From: Cezary Kaliszyk Date: Fri, 30 Aug 2013 09:32:28 +0000 (+0200) Subject: Update from HH X-Git-Url: http://colo12-c703.uibk.ac.at/git/?a=commitdiff_plain;p=Multivariate%20Analysis%2F.git Update from HH --- 083b3d93c9462bb3079943fbbeac235b1841e69b diff --git a/Multivariate/canal.ml b/Multivariate/canal.ml new file mode 100644 index 0000000..f09184f --- /dev/null +++ b/Multivariate/canal.ml @@ -0,0 +1,3207 @@ +(* ========================================================================= *) +(* Complex analysis. *) +(* *) +(* (c) Copyright, John Harrison 1998-2008 *) +(* (c) Copyright, Marco Maggesi, Graziano Gentili and Gianni Ciolli, 2008. *) +(* (c) Copyright, Valentina Bruno 2010 *) +(* ========================================================================= *) + +needs "Library/floor.ml";; +needs "Library/iter.ml";; +needs "Multivariate/complexes.ml";; + +prioritize_complex();; + +(* ------------------------------------------------------------------------- *) +(* Some toplogical facts formulated for the complex numbers. *) +(* ------------------------------------------------------------------------- *) + +let CLOSED_HALFSPACE_RE_GE = prove + (`!b. closed {z | Re(z) >= b}`, + GEN_TAC THEN MP_TAC(ISPECL [`Cx(&1)`; `b:real`] CLOSED_HALFSPACE_GE) THEN + MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN + REWRITE_TAC[EXTENSION; dot; SUM_2; DIMINDEX_2; GSYM RE_DEF; GSYM IM_DEF] THEN + REWRITE_TAC[RE_CX; IM_CX; IN_ELIM_THM] THEN REAL_ARITH_TAC);; + +let CLOSED_HALFSPACE_RE_LE = prove + (`!b. closed {z | Re(z) <= b}`, + GEN_TAC THEN MP_TAC(ISPECL [`Cx(&1)`; `b:real`] CLOSED_HALFSPACE_LE) THEN + MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN + REWRITE_TAC[EXTENSION; dot; SUM_2; DIMINDEX_2; GSYM RE_DEF; GSYM IM_DEF] THEN + REWRITE_TAC[RE_CX; IM_CX; IN_ELIM_THM] THEN REAL_ARITH_TAC);; + +let CLOSED_HALFSPACE_RE_EQ = prove + (`!b. closed {z | Re(z) = b}`, + GEN_TAC THEN REWRITE_TAC[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 + SIMP_TAC[CLOSED_INTER; CLOSED_HALFSPACE_RE_GE; CLOSED_HALFSPACE_RE_LE]);; + +let OPEN_HALFSPACE_RE_GT = prove + (`!b. open {z | Re(z) > b}`, + REWRITE_TAC[OPEN_CLOSED; CLOSED_HALFSPACE_RE_LE; + REAL_ARITH `x > y <=> ~(x <= y)`; + SET_RULE `UNIV DIFF {x | ~p x} = {x | p x}`]);; + +let OPEN_HALFSPACE_RE_LT = prove + (`!b. open {z | Re(z) < b}`, + REWRITE_TAC[OPEN_CLOSED; CLOSED_HALFSPACE_RE_GE; + REAL_ARITH `x < y <=> ~(x >= y)`; + SET_RULE `UNIV DIFF {x | ~p x} = {x | p x}`]);; + +let CLOSED_HALFSPACE_IM_GE = prove + (`!b. closed {z | Im(z) >= b}`, + GEN_TAC THEN MP_TAC(ISPECL [`ii`; `b:real`] CLOSED_HALFSPACE_GE) THEN + MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN + REWRITE_TAC[EXTENSION; dot; SUM_2; DIMINDEX_2; GSYM RE_DEF; GSYM IM_DEF] THEN + REWRITE_TAC[ii; RE_CX; IM_CX; RE; IM; IN_ELIM_THM] THEN REAL_ARITH_TAC);; + +let CLOSED_HALFSPACE_IM_LE = prove + (`!b. closed {z | Im(z) <= b}`, + GEN_TAC THEN MP_TAC(ISPECL [`ii`; `b:real`] CLOSED_HALFSPACE_LE) THEN + MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN + REWRITE_TAC[EXTENSION; dot; SUM_2; DIMINDEX_2; GSYM RE_DEF; GSYM IM_DEF] THEN + REWRITE_TAC[ii; RE_CX; IM_CX; RE; IM; IN_ELIM_THM] THEN REAL_ARITH_TAC);; + +let CLOSED_HALFSPACE_IM_EQ = prove + (`!b. closed {z | Im(z) = b}`, + GEN_TAC THEN REWRITE_TAC[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 + SIMP_TAC[CLOSED_INTER; CLOSED_HALFSPACE_IM_GE; CLOSED_HALFSPACE_IM_LE]);; + +let OPEN_HALFSPACE_IM_GT = prove + (`!b. open {z | Im(z) > b}`, + REWRITE_TAC[OPEN_CLOSED; CLOSED_HALFSPACE_IM_LE; + REAL_ARITH `x > y <=> ~(x <= y)`; + SET_RULE `UNIV DIFF {x | ~p x} = {x | p x}`]);; + +let OPEN_HALFSPACE_IM_LT = prove + (`!b. open {z | Im(z) < b}`, + REWRITE_TAC[OPEN_CLOSED; CLOSED_HALFSPACE_IM_GE; + REAL_ARITH `x < y <=> ~(x >= y)`; + SET_RULE `UNIV DIFF {x | ~p x} = {x | p x}`]);; + +let CONVEX_HALFSPACE_RE_GE = prove + (`!b. convex {z | Re(z) >= b}`, + GEN_TAC THEN MP_TAC(ISPECL [`Cx(&1)`; `b:real`] CONVEX_HALFSPACE_GE) THEN + MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN + REWRITE_TAC[EXTENSION; dot; SUM_2; DIMINDEX_2; GSYM RE_DEF; GSYM IM_DEF] THEN + REWRITE_TAC[ii; RE_CX; IM_CX; RE; IM; IN_ELIM_THM] THEN REAL_ARITH_TAC);; + +let CONVEX_HALFSPACE_RE_GT = prove + (`!b. convex {z | Re(z) > b}`, + GEN_TAC THEN MP_TAC(ISPECL [`Cx(&1)`; `b:real`] CONVEX_HALFSPACE_GT) THEN + MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN + REWRITE_TAC[EXTENSION; dot; SUM_2; DIMINDEX_2; GSYM RE_DEF; GSYM IM_DEF] THEN + REWRITE_TAC[ii; RE_CX; IM_CX; RE; IM; IN_ELIM_THM] THEN REAL_ARITH_TAC);; + +let CONVEX_HALFSPACE_RE_LE = prove + (`!b. convex {z | Re(z) <= b}`, + GEN_TAC THEN MP_TAC(ISPECL [`Cx(&1)`; `b:real`] CONVEX_HALFSPACE_LE) THEN + MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN + REWRITE_TAC[EXTENSION; dot; SUM_2; DIMINDEX_2; GSYM RE_DEF; GSYM IM_DEF] THEN + REWRITE_TAC[ii; RE_CX; IM_CX; RE; IM; IN_ELIM_THM] THEN REAL_ARITH_TAC);; + +let CONVEX_HALFSPACE_RE_LT = prove + (`!b. convex {z | Re(z) < b}`, + GEN_TAC THEN MP_TAC(ISPECL [`Cx(&1)`; `b:real`] CONVEX_HALFSPACE_LT) THEN + MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN + REWRITE_TAC[EXTENSION; dot; SUM_2; DIMINDEX_2; GSYM RE_DEF; GSYM IM_DEF] THEN + REWRITE_TAC[ii; RE_CX; IM_CX; RE; IM; IN_ELIM_THM] THEN REAL_ARITH_TAC);; + +let CONVEX_HALFSPACE_IM_GE = prove + (`!b. convex {z | Im(z) >= b}`, + GEN_TAC THEN MP_TAC(ISPECL [`ii`; `b:real`] CONVEX_HALFSPACE_GE) THEN + MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN + REWRITE_TAC[EXTENSION; dot; SUM_2; DIMINDEX_2; GSYM RE_DEF; GSYM IM_DEF] THEN + REWRITE_TAC[ii; RE_CX; IM_CX; RE; IM; IN_ELIM_THM] THEN REAL_ARITH_TAC);; + +let CONVEX_HALFSPACE_IM_GT = prove + (`!b. convex {z | Im(z) > b}`, + GEN_TAC THEN MP_TAC(ISPECL [`ii`; `b:real`] CONVEX_HALFSPACE_GT) THEN + MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN + REWRITE_TAC[EXTENSION; dot; SUM_2; DIMINDEX_2; GSYM RE_DEF; GSYM IM_DEF] THEN + REWRITE_TAC[ii; RE_CX; IM_CX; RE; IM; IN_ELIM_THM] THEN REAL_ARITH_TAC);; + +let CONVEX_HALFSPACE_IM_LE = prove + (`!b. convex {z | Im(z) <= b}`, + GEN_TAC THEN MP_TAC(ISPECL [`ii`; `b:real`] CONVEX_HALFSPACE_LE) THEN + MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN + REWRITE_TAC[EXTENSION; dot; SUM_2; DIMINDEX_2; GSYM RE_DEF; GSYM IM_DEF] THEN + REWRITE_TAC[ii; RE_CX; IM_CX; RE; IM; IN_ELIM_THM] THEN REAL_ARITH_TAC);; + +let CONVEX_HALFSPACE_IM_LT = prove + (`!b. convex {z | Im(z) < b}`, + GEN_TAC THEN MP_TAC(ISPECL [`ii`; `b:real`] CONVEX_HALFSPACE_LT) THEN + MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN + REWRITE_TAC[EXTENSION; dot; SUM_2; DIMINDEX_2; GSYM RE_DEF; GSYM IM_DEF] THEN + REWRITE_TAC[ii; RE_CX; IM_CX; RE; IM; IN_ELIM_THM] THEN REAL_ARITH_TAC);; + +let COMPLEX_IN_BALL_0 = prove + (`!v r. v IN ball(Cx(&0),r) <=> norm v < r`, + REWRITE_TAC [GSYM COMPLEX_VEC_0; IN_BALL_0]);; + +let COMPLEX_IN_CBALL_0 = prove + (`!v r. v IN cball(Cx(&0),r) <=> norm v <= r`, + REWRITE_TAC [GSYM COMPLEX_VEC_0; IN_CBALL_0]);; + +let COMPLEX_IN_SPHERE_0 = prove + (`!v r. v IN sphere(Cx(&0),r) <=> norm v = r`, + REWRITE_TAC [GSYM COMPLEX_VEC_0; IN_SPHERE_0]);; + +let IN_BALL_RE = prove + (`!x z e. x IN ball(z,e) ==> abs(Re(x) - Re(z)) < e`, + REPEAT GEN_TAC THEN REWRITE_TAC[IN_BALL; dist] THEN + MP_TAC(SPEC `z - x:complex` COMPLEX_NORM_GE_RE_IM) THEN + REWRITE_TAC[RE_SUB] THEN REAL_ARITH_TAC);; + +let IN_BALL_IM = prove + (`!x z e. x IN ball(z,e) ==> abs(Im(x) - Im(z)) < e`, + REPEAT GEN_TAC THEN REWRITE_TAC[IN_BALL; dist] THEN + MP_TAC(SPEC `z - x:complex` COMPLEX_NORM_GE_RE_IM) THEN + REWRITE_TAC[IM_SUB] THEN REAL_ARITH_TAC);; + +let IN_CBALL_RE = prove + (`!x z e. x IN cball(z,e) ==> abs(Re(x) - Re(z)) <= e`, + REPEAT GEN_TAC THEN REWRITE_TAC[IN_CBALL; dist] THEN + MP_TAC(SPEC `z - x:complex` COMPLEX_NORM_GE_RE_IM) THEN + REWRITE_TAC[RE_SUB] THEN REAL_ARITH_TAC);; + +let IN_CBALL_IM = prove + (`!x z e. x IN cball(z,e) ==> abs(Im(x) - Im(z)) <= e`, + REPEAT GEN_TAC THEN REWRITE_TAC[IN_CBALL; dist] THEN + MP_TAC(SPEC `z - x:complex` COMPLEX_NORM_GE_RE_IM) THEN + REWRITE_TAC[IM_SUB] THEN REAL_ARITH_TAC);; + +let CLOSED_REAL_SET = prove + (`closed {z | real z}`, + REWRITE_TAC[CLOSED_HALFSPACE_IM_EQ; real]);; + +let CLOSED_REAL = prove + (`closed real`, + GEN_REWRITE_TAC RAND_CONV [SET_RULE `s = {x | s x}`] THEN + REWRITE_TAC[CLOSED_REAL_SET]);; + +(* ------------------------------------------------------------------------- *) +(* Complex-specific uniform limit composition theorems. *) +(* ------------------------------------------------------------------------- *) + +let UNIFORM_LIM_COMPLEX_MUL = prove + (`!net:(A)net P f g l m b1 b2. + eventually (\x. !n. P n ==> norm(l n) <= b1) net /\ + eventually (\x. !n. P n ==> norm(m n) <= b2) net /\ + (!e. &0 < e + ==> eventually (\x. !n:B. P n ==> norm(f n x - l n) < e) net) /\ + (!e. &0 < e + ==> eventually (\x. !n. P n ==> norm(g n x - m n) < e) net) + ==> !e. &0 < e + ==> eventually + (\x. !n. P n + ==> norm(f n x * g n x - l n * m n) < e) + net`, + REPEAT GEN_TAC THEN + DISCH_THEN(MP_TAC o CONJ BILINEAR_COMPLEX_MUL) THEN + REWRITE_TAC[UNIFORM_LIM_BILINEAR]);; + +let UNIFORM_LIM_COMPLEX_INV = prove + (`!net:(A)net P f l b. + (!e. &0 < e + ==> eventually (\x. !n:B. P n ==> norm(f n x - l n) < e) net) /\ + &0 < b /\ eventually (\x. !n. P n ==> b <= norm(l n)) net + ==> !e. &0 < e + ==> eventually + (\x. !n. P n ==> norm(inv(f n x) - inv(l n)) < e) net`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC EVENTUALLY_MONO THEN + EXISTS_TAC + `\x. !n. P n ==> b <= norm(l n) /\ + b / &2 <= norm((f:B->A->complex) n x) /\ + norm(f n x - l n) < e * b pow 2 / &2` THEN + REWRITE_TAC[TAUT `(p ==> q /\ r) <=> (p ==> q) /\ (p ==> r)`] THEN + REWRITE_TAC[FORALL_AND_THM] THEN CONJ_TAC THENL + [X_GEN_TAC `x:A` THEN STRIP_TAC THEN X_GEN_TAC `n:B` THEN DISCH_TAC THEN + REPEAT(FIRST_X_ASSUM(MP_TAC o SPEC `n:B`) THEN ASM_REWRITE_TAC[]) THEN + REPEAT DISCH_TAC THEN + SUBGOAL_THEN `~((f:B->A->complex) n x = Cx(&0)) /\ ~(l n = Cx(&0))` + STRIP_ASSUME_TAC THENL + [CONJ_TAC THEN DISCH_THEN SUBST_ALL_TAC THEN + RULE_ASSUM_TAC(REWRITE_RULE[COMPLEX_NORM_CX]) THEN ASM_REAL_ARITH_TAC; + ALL_TAC] THEN + ASM_SIMP_TAC[COMPLEX_FIELD + `~(x = Cx(&0)) /\ ~(y = Cx(&0)) + ==> inv x - inv y = (y - x) / (x * y)`] THEN + ASM_SIMP_TAC[COMPLEX_NORM_DIV; REAL_LT_LDIV_EQ; COMPLEX_NORM_NZ; + COMPLEX_ENTIRE] THEN + ONCE_REWRITE_TAC[NORM_SUB] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + REAL_LTE_TRANS)) THEN + ASM_SIMP_TAC[REAL_LE_LMUL_EQ; REAL_ARITH `b pow 2 / &2 = b / &2 * b`] THEN + REWRITE_TAC[COMPLEX_NORM_MUL] THEN MATCH_MP_TAC REAL_LE_MUL2 THEN + ASM_REAL_ARITH_TAC; + ASM_REWRITE_TAC[EVENTUALLY_AND] THEN CONJ_TAC THENL + [FIRST_X_ASSUM(MP_TAC o SPEC `b / &2`) THEN + ASM_REWRITE_TAC[REAL_HALF] THEN + FIRST_X_ASSUM(fun th -> MP_TAC th THEN REWRITE_TAC[IMP_IMP] THEN + GEN_REWRITE_TAC LAND_CONV [GSYM EVENTUALLY_AND]) THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] EVENTUALLY_MONO) THEN + REWRITE_TAC[] THEN + ASM_MESON_TAC[NORM_ARITH + `b <= norm l /\ norm(f - l) < b / &2 ==> b / &2 <= norm f`]; + FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_SIMP_TAC[REAL_HALF; REAL_POW_LT; REAL_LT_MUL]]]);; + +let UNIFORM_LIM_COMPLEX_DIV = prove + (`!net:(A)net P f g l m b1 b2. + eventually (\x. !n. P n ==> norm(l n) <= b1) net /\ + &0 < b2 /\ eventually (\x. !n. P n ==> b2 <= norm(m n)) net /\ + (!e. &0 < e + ==> eventually (\x. !n:B. P n ==> norm(f n x - l n) < e) net) /\ + (!e. &0 < e + ==> eventually (\x. !n. P n ==> norm(g n x - m n) < e) net) + ==> !e. &0 < e + ==> eventually + (\x. !n. P n + ==> norm(f n x / g n x - l n / m n) < e) + net`, + REPEAT GEN_TAC THEN DISCH_TAC THEN + REWRITE_TAC[complex_div] THEN MATCH_MP_TAC UNIFORM_LIM_COMPLEX_MUL THEN + MAP_EVERY EXISTS_TAC [`b1:real`; `inv(b2):real`] THEN + ASM_REWRITE_TAC[] THEN CONJ_TAC THENL + [FIRST_X_ASSUM(CONJUNCTS_THEN2 ASSUME_TAC + (MP_TAC o CONJUNCT1) o CONJUNCT2) THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] EVENTUALLY_MONO) THEN + GEN_TAC THEN REWRITE_TAC[] THEN MATCH_MP_TAC MONO_FORALL THEN + REPEAT STRIP_TAC THEN REWRITE_TAC[COMPLEX_NORM_INV] THEN + MATCH_MP_TAC REAL_LE_INV2 THEN ASM_SIMP_TAC[]; + MATCH_MP_TAC UNIFORM_LIM_COMPLEX_INV THEN + EXISTS_TAC `b2:real` THEN ASM_REWRITE_TAC[]]);; + +(* ------------------------------------------------------------------------- *) +(* The usual non-uniform versions. *) +(* ------------------------------------------------------------------------- *) + +let LIM_COMPLEX_MUL = prove + (`!net:(A)net f g l m. + (f --> l) net /\ (g --> m) net ==> ((\x. f x * g x) --> l * m) net`, + SIMP_TAC[LIM_BILINEAR; BILINEAR_COMPLEX_MUL]);; + +let LIM_COMPLEX_INV = prove + (`!net:(A)net f g l m. + (f --> l) net /\ ~(l = Cx(&0)) ==> ((\x. inv(f x)) --> inv(l)) net`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL + [`net:(A)net`; `\x:one. T`; + `\n:one. (f:A->complex)`; + `\n:one. (l:complex)`; + `norm(l:complex)`] UNIFORM_LIM_COMPLEX_INV) THEN + ASM_REWRITE_TAC[REAL_LE_REFL; EVENTUALLY_TRUE] THEN + ASM_REWRITE_TAC[GSYM dist; GSYM tendsto; COMPLEX_NORM_NZ]);; + +let LIM_COMPLEX_DIV = prove + (`!net:(A)net f g l m. + (f --> l) net /\ (g --> m) net /\ ~(m = Cx(&0)) + ==> ((\x. f x / g x) --> l / m) net`, + REPEAT STRIP_TAC THEN REWRITE_TAC[complex_div] THEN + MATCH_MP_TAC LIM_COMPLEX_MUL THEN ASM_SIMP_TAC[LIM_COMPLEX_INV]);; + +let LIM_COMPLEX_POW = prove + (`!net:(A)net f l n. + (f --> l) net ==> ((\x. f(x) pow n) --> l pow n) net`, + REWRITE_TAC[RIGHT_FORALL_IMP_THM] THEN REPEAT GEN_TAC THEN DISCH_TAC THEN + INDUCT_TAC THEN ASM_SIMP_TAC[LIM_COMPLEX_MUL; complex_pow; LIM_CONST]);; + +let LIM_COMPLEX_LMUL = prove + (`!f l c. (f --> l) net ==> ((\x. c * f x) --> c * l) net`, + SIMP_TAC[LIM_COMPLEX_MUL; LIM_CONST]);; + +let LIM_COMPLEX_RMUL = prove + (`!f l c. (f --> l) net ==> ((\x. f x * c) --> l * c) net`, + SIMP_TAC[LIM_COMPLEX_MUL; LIM_CONST]);; + +(* ------------------------------------------------------------------------- *) +(* Special cases of null limits. *) +(* ------------------------------------------------------------------------- *) + +let LIM_NULL_COMPLEX_NEG = prove + (`!net f. (f --> Cx(&0)) net ==> ((\x. --(f x)) --> Cx(&0)) net`, + REPEAT GEN_TAC THEN DISCH_THEN(MP_TAC o MATCH_MP LIM_NEG) THEN + REWRITE_TAC[COMPLEX_NEG_0]);; + +let LIM_NULL_COMPLEX_ADD = prove + (`!net f g. (f --> Cx(&0)) net /\ (g --> Cx(&0)) net + ==> ((\x. f x + g x) --> Cx(&0)) net`, + REPEAT GEN_TAC THEN + DISCH_THEN(MP_TAC o MATCH_MP LIM_ADD) THEN + REWRITE_TAC[COMPLEX_ADD_LID]);; + +let LIM_NULL_COMPLEX_SUB = prove + (`!net f g. (f --> Cx(&0)) net /\ (g --> Cx(&0)) net + ==> ((\x. f x - g x) --> Cx(&0)) net`, + REPEAT GEN_TAC THEN + DISCH_THEN(MP_TAC o MATCH_MP LIM_SUB) THEN + REWRITE_TAC[COMPLEX_SUB_REFL]);; + +let LIM_NULL_COMPLEX_MUL = prove + (`!net f g. (f --> Cx(&0)) net /\ (g --> Cx(&0)) net + ==> ((\x. f x * g x) --> Cx(&0)) net`, + REPEAT GEN_TAC THEN + DISCH_THEN(MP_TAC o MATCH_MP LIM_COMPLEX_MUL) THEN + REWRITE_TAC[COMPLEX_MUL_LZERO]);; + +let LIM_NULL_COMPLEX_LMUL = prove + (`!net f c. (f --> Cx(&0)) net ==> ((\x. c * f x) --> Cx(&0)) net`, + REPEAT STRIP_TAC THEN SUBST1_TAC(COMPLEX_RING `Cx(&0) = c * Cx(&0)`) THEN + ASM_SIMP_TAC[LIM_COMPLEX_LMUL]);; + +let LIM_NULL_COMPLEX_RMUL = prove + (`!net f c. (f --> Cx(&0)) net ==> ((\x. f x * c) --> Cx(&0)) net`, + REPEAT STRIP_TAC THEN SUBST1_TAC(COMPLEX_RING `Cx(&0) = Cx(&0) * c`) THEN + ASM_SIMP_TAC[LIM_COMPLEX_RMUL]);; + +let LIM_NULL_COMPLEX_POW = prove + (`!net f n. (f --> Cx(&0)) net /\ ~(n = 0) + ==> ((\x. (f x) pow n) --> Cx(&0)) net`, + REPEAT STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `n:num` o MATCH_MP LIM_COMPLEX_POW) THEN + ASM_REWRITE_TAC[COMPLEX_POW_ZERO]);; + +let LIM_NULL_COMPLEX_BOUND = prove + (`!f g. eventually (\n. norm (f n) <= norm (g n)) net /\ (g --> Cx(&0)) net + ==> (f --> Cx(&0)) net`, + REWRITE_TAC[GSYM COMPLEX_VEC_0; LIM_TRANSFORM_BOUND]);; + +let SUMS_COMPLEX_0 = prove + (`!f s. (!n. n IN s ==> f n = Cx(&0)) ==> (f sums Cx(&0)) s`, + REWRITE_TAC[GSYM COMPLEX_VEC_0; SUMS_0]);; + +let LIM_NULL_COMPLEX_RMUL_BOUNDED = prove + (`!f g. (f --> Cx(&0)) net /\ + eventually (\a. f a = Cx(&0) \/ norm(g a) <= B) net + ==> ((\z. f(z) * g(z)) --> Cx(&0)) net`, + REWRITE_TAC[GSYM COMPLEX_VEC_0] THEN + ONCE_REWRITE_TAC[LIM_NULL_NORM] THEN + REWRITE_TAC[LIFT_CMUL; COMPLEX_NORM_MUL] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC LIM_NULL_VMUL_BOUNDED THEN + EXISTS_TAC `B:real` THEN + ASM_REWRITE_TAC[o_DEF; NORM_LIFT; REAL_ABS_NORM; NORM_EQ_0]);; + +let LIM_NULL_COMPLEX_LMUL_BOUNDED = prove + (`!f g. eventually (\a. norm(f a) <= B \/ g a = Cx(&0)) net /\ + (g --> Cx(&0)) net + ==> ((\z. f(z) * g(z)) --> Cx(&0)) net`, + ONCE_REWRITE_TAC[DISJ_SYM; COMPLEX_MUL_SYM] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC LIM_NULL_COMPLEX_RMUL_BOUNDED THEN ASM_REWRITE_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* Bound results for real and imaginary components of limits. *) +(* ------------------------------------------------------------------------- *) + +let LIM_RE_UBOUND = prove + (`!net:(A)net f l b. + ~(trivial_limit net) /\ (f --> l) net /\ + eventually (\x. Re(f x) <= b) net + ==> Re(l) <= b`, + REWRITE_TAC[RE_DEF] THEN REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`net:(A)net`; `f:A->complex`; `l:complex`; `b:real`; `1`] + LIM_COMPONENT_UBOUND) THEN + ASM_REWRITE_TAC[DIMINDEX_2; ARITH]);; + +let LIM_RE_LBOUND = prove + (`!net:(A)net f l b. + ~(trivial_limit net) /\ (f --> l) net /\ + eventually (\x. b <= Re(f x)) net + ==> b <= Re(l)`, + REWRITE_TAC[RE_DEF] THEN REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`net:(A)net`; `f:A->complex`; `l:complex`; `b:real`; `1`] + LIM_COMPONENT_LBOUND) THEN + ASM_REWRITE_TAC[DIMINDEX_2; ARITH]);; + +let LIM_IM_UBOUND = prove + (`!net:(A)net f l b. + ~(trivial_limit net) /\ (f --> l) net /\ + eventually (\x. Im(f x) <= b) net + ==> Im(l) <= b`, + REWRITE_TAC[IM_DEF] THEN REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`net:(A)net`; `f:A->complex`; `l:complex`; `b:real`; `2`] + LIM_COMPONENT_UBOUND) THEN + ASM_REWRITE_TAC[DIMINDEX_2; ARITH]);; + +let LIM_IM_LBOUND = prove + (`!net:(A)net f l b. + ~(trivial_limit net) /\ (f --> l) net /\ + eventually (\x. b <= Im(f x)) net + ==> b <= Im(l)`, + REWRITE_TAC[IM_DEF] THEN REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`net:(A)net`; `f:A->complex`; `l:complex`; `b:real`; `2`] + LIM_COMPONENT_LBOUND) THEN + ASM_REWRITE_TAC[DIMINDEX_2; ARITH]);; + +(* ------------------------------------------------------------------------- *) +(* Left and right multiplication of series. *) +(* ------------------------------------------------------------------------- *) + +let SERIES_COMPLEX_LMUL = prove + (`!f l c s. (f sums l) s ==> ((\x. c * f x) sums c * l) s`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC SERIES_LINEAR THEN + ASM_REWRITE_TAC[] THEN GEN_REWRITE_TAC RAND_CONV [GSYM ETA_AX] THEN + REWRITE_TAC[LINEAR_COMPLEX_MUL]);; + +let SERIES_COMPLEX_RMUL = prove + (`!f l c s. (f sums l) s ==> ((\x. f x * c) sums l * c) s`, + ONCE_REWRITE_TAC[COMPLEX_MUL_SYM] THEN REWRITE_TAC[SERIES_COMPLEX_LMUL]);; + +let SERIES_COMPLEX_DIV = prove + (`!f l c s. (f sums l) s ==> ((\x. f x / c) sums (l / c)) s`, + REWRITE_TAC[complex_div; SERIES_COMPLEX_RMUL]);; + +let SUMMABLE_COMPLEX_LMUL = prove + (`!f c s. summable s f ==> summable s (\x. c * f x)`, + REWRITE_TAC[summable] THEN MESON_TAC[SERIES_COMPLEX_LMUL]);; + +let SUMMABLE_COMPLEX_RMUL = prove + (`!f c s. summable s f ==> summable s (\x. f x * c)`, + REWRITE_TAC[summable] THEN MESON_TAC[SERIES_COMPLEX_RMUL]);; + +let SUMMABLE_COMPLEX_DIV = prove + (`!f c s. summable s f ==> summable s (\x. f x / c)`, + REWRITE_TAC[summable] THEN MESON_TAC[SERIES_COMPLEX_DIV]);; + +(* ------------------------------------------------------------------------- *) +(* Complex-specific continuity closures. *) +(* ------------------------------------------------------------------------- *) + +let CONTINUOUS_COMPLEX_MUL = prove + (`!net f g. + f continuous net /\ g continuous net ==> (\x. f(x) * g(x)) continuous net`, + SIMP_TAC[continuous; LIM_COMPLEX_MUL]);; + +let CONTINUOUS_COMPLEX_INV = prove + (`!net f. + f continuous net /\ ~(f(netlimit net) = Cx(&0)) + ==> (\x. inv(f x)) continuous net`, + SIMP_TAC[continuous; LIM_COMPLEX_INV]);; + +let CONTINUOUS_COMPLEX_DIV = prove + (`!net f g. + f continuous net /\ g continuous net /\ ~(g(netlimit net) = Cx(&0)) + ==> (\x. f(x) / g(x)) continuous net`, + SIMP_TAC[continuous; LIM_COMPLEX_DIV]);; + +let CONTINUOUS_COMPLEX_POW = prove + (`!net f n. f continuous net ==> (\x. f(x) pow n) continuous net`, + SIMP_TAC[continuous; LIM_COMPLEX_POW]);; + +(* ------------------------------------------------------------------------- *) +(* Write away the netlimit, which is otherwise a bit tedious. *) +(* ------------------------------------------------------------------------- *) + +let CONTINUOUS_COMPLEX_INV_WITHIN = prove + (`!f s a. + f continuous (at a within s) /\ ~(f a = Cx(&0)) + ==> (\x. inv(f x)) continuous (at a within s)`, + MESON_TAC[CONTINUOUS_COMPLEX_INV; CONTINUOUS_TRIVIAL_LIMIT; + NETLIMIT_WITHIN]);; + +let CONTINUOUS_COMPLEX_INV_AT = prove + (`!f a. + f continuous (at a) /\ ~(f a = Cx(&0)) + ==> (\x. inv(f x)) continuous (at a)`, + SIMP_TAC[CONTINUOUS_COMPLEX_INV; NETLIMIT_AT]);; + +let CONTINUOUS_COMPLEX_DIV_WITHIN = prove + (`!f g s a. + f continuous (at a within s) /\ g continuous (at a within s) /\ + ~(g a = Cx(&0)) + ==> (\x. f x / g x) continuous (at a within s)`, + MESON_TAC[CONTINUOUS_COMPLEX_DIV; CONTINUOUS_TRIVIAL_LIMIT; + NETLIMIT_WITHIN]);; + +let CONTINUOUS_COMPLEX_DIV_AT = prove + (`!f g a. + f continuous at a /\ g continuous at a /\ ~(g a = Cx(&0)) + ==> (\x. f x / g x) continuous at a`, + SIMP_TAC[CONTINUOUS_COMPLEX_DIV; NETLIMIT_AT]);; + +(* ------------------------------------------------------------------------- *) +(* Also prove "on" variants as needed. *) +(* ------------------------------------------------------------------------- *) + +let CONTINUOUS_ON_COMPLEX_MUL = prove + (`!f g s. f continuous_on s /\ g continuous_on s + ==> (\x. f(x) * g(x)) continuous_on s`, + REWRITE_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN] THEN + SIMP_TAC[CONTINUOUS_COMPLEX_MUL]);; + +let CONTINUOUS_ON_COMPLEX_LMUL = prove + (`!f:real^N->complex s. f continuous_on s ==> (\x. c * f(x)) continuous_on s`, + REWRITE_TAC[CONTINUOUS_ON] THEN SIMP_TAC[LIM_COMPLEX_MUL; LIM_CONST]);; + +let CONTINUOUS_ON_COMPLEX_RMUL = prove + (`!f:real^N->complex s. f continuous_on s ==> (\x. f(x) * c) continuous_on s`, + REWRITE_TAC[CONTINUOUS_ON] THEN SIMP_TAC[LIM_COMPLEX_MUL; LIM_CONST]);; + +let CONTINUOUS_ON_COMPLEX_INV = prove + (`!f:real^N->complex. + f continuous_on s /\ + (!x. x IN s ==> ~(f x = Cx(&0))) + ==> (\x. inv(f x)) continuous_on s`, + SIMP_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN; + CONTINUOUS_COMPLEX_INV_WITHIN]);; + +let CONTINUOUS_ON_COMPLEX_DIV = prove + (`!f g s. f continuous_on s /\ g continuous_on s /\ + (!x. x IN s ==> ~(g x = Cx(&0))) + ==> (\x. f(x) / g(x)) continuous_on s`, + REWRITE_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN] THEN + SIMP_TAC[CONTINUOUS_COMPLEX_DIV_WITHIN]);; + +let CONTINUOUS_ON_COMPLEX_POW = prove + (`!f n s. f continuous_on s ==> (\x. f(x) pow n) continuous_on s`, + SIMP_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN; CONTINUOUS_COMPLEX_POW]);; + +(* ------------------------------------------------------------------------- *) +(* And also uniform versions. *) +(* ------------------------------------------------------------------------- *) + +let UNIFORMLY_CONTINUOUS_ON_COMPLEX_MUL = prove + (`!f g s:real^N->bool. + f uniformly_continuous_on s /\ g uniformly_continuous_on s /\ + bounded(IMAGE f s) /\ bounded(IMAGE g s) + ==> (\x. f(x) * g(x)) uniformly_continuous_on s`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL + [`f:real^N->complex`; `g:real^N->complex`; + `( * ):complex->complex->complex`; `s:real^N->bool`] + BILINEAR_UNIFORMLY_CONTINUOUS_ON_COMPOSE) THEN + ASM_REWRITE_TAC[BILINEAR_COMPLEX_MUL]);; + +let UNIFORMLY_CONTINUOUS_ON_COMPLEX_LMUL = prove + (`!f c s:real^N->bool. + f uniformly_continuous_on s ==> (\x. c * f x) uniformly_continuous_on s`, + REPEAT GEN_TAC THEN + DISCH_THEN(MP_TAC o ISPEC `\x:complex. c * x` o MATCH_MP + (REWRITE_RULE[IMP_CONJ] UNIFORMLY_CONTINUOUS_ON_COMPOSE)) THEN + ASM_SIMP_TAC[o_DEF; LINEAR_COMPLEX_MUL; LINEAR_UNIFORMLY_CONTINUOUS_ON]);; + +let UNIFORMLY_CONTINUOUS_ON_COMPLEX_RMUL = prove + (`!f c s:real^N->bool. + f uniformly_continuous_on s ==> (\x. f x * c) uniformly_continuous_on s`, + ONCE_REWRITE_TAC[COMPLEX_MUL_SYM] THEN + REWRITE_TAC[UNIFORMLY_CONTINUOUS_ON_COMPLEX_LMUL]);; + +(* ------------------------------------------------------------------------- *) +(* Continuity prover (not just for complex numbers but with more for them). *) +(* ------------------------------------------------------------------------- *) + +let CONTINUOUS_TAC = + let ETA_THM = prove + (`f continuous net <=> (\x. f x) continuous net`, + REWRITE_TAC[ETA_AX]) in + let ETA_TWEAK = + GEN_REWRITE_RULE (LAND_CONV o ONCE_DEPTH_CONV) [ETA_THM] o SPEC_ALL in + let tac_base = + MATCH_ACCEPT_TAC CONTINUOUS_CONST ORELSE + MATCH_ACCEPT_TAC CONTINUOUS_AT_ID ORELSE + MATCH_ACCEPT_TAC CONTINUOUS_WITHIN_ID + and tac_1 = + MATCH_MP_TAC(ETA_TWEAK CONTINUOUS_CMUL) ORELSE + MATCH_MP_TAC(ETA_TWEAK CONTINUOUS_NEG) ORELSE + MATCH_MP_TAC(ETA_TWEAK CONTINUOUS_COMPLEX_POW) + and tac_2 = + MATCH_MP_TAC(ETA_TWEAK CONTINUOUS_ADD) ORELSE + MATCH_MP_TAC(ETA_TWEAK CONTINUOUS_SUB) ORELSE + MATCH_MP_TAC(ETA_TWEAK CONTINUOUS_COMPLEX_MUL) + and tac_1' = MATCH_MP_TAC (ETA_TWEAK CONTINUOUS_COMPLEX_INV) + and tac_2' = MATCH_MP_TAC (ETA_TWEAK CONTINUOUS_COMPLEX_DIV) in + let rec CONTINUOUS_TAC gl = + (tac_base ORELSE + (tac_1 THEN CONTINUOUS_TAC) ORELSE + (tac_2 THEN CONJ_TAC THEN CONTINUOUS_TAC) ORELSE + (tac_1' THEN CONJ_TAC THENL + [CONTINUOUS_TAC; REWRITE_TAC[NETLIMIT_AT; NETLIMIT_WITHIN]]) ORELSE + (tac_2' THEN REPEAT CONJ_TAC THENL + [CONTINUOUS_TAC; CONTINUOUS_TAC; + REWRITE_TAC[NETLIMIT_AT; NETLIMIT_WITHIN]]) ORELSE + ALL_TAC) gl in + CONTINUOUS_TAC;; + +(* ------------------------------------------------------------------------- *) +(* Hence a limit calculator *) +(* ------------------------------------------------------------------------- *) + +let LIM_CONTINUOUS = prove + (`!net f l. f continuous net /\ f(netlimit net) = l ==> (f --> l) net`, + MESON_TAC[continuous]);; + +let LIM_TAC = + MATCH_MP_TAC LIM_CONTINUOUS THEN CONJ_TAC THENL + [CONTINUOUS_TAC; REWRITE_TAC[NETLIMIT_AT; NETLIMIT_WITHIN]];; + +(* ------------------------------------------------------------------------- *) +(* Continuity of the norm. *) +(* ------------------------------------------------------------------------- *) + +let CONTINUOUS_AT_CX_NORM = prove + (`!z:real^N. (\z. Cx(norm z)) continuous at z`, + REWRITE_TAC[continuous_at; dist; GSYM CX_SUB; COMPLEX_NORM_CX] THEN + MESON_TAC[NORM_ARITH `norm(a - b:real^N) < d ==> abs(norm a - norm b) < d`]);; + +let CONTINUOUS_WITHIN_CX_NORM = prove + (`!z:real^N s. (\z. Cx(norm z)) continuous (at z within s)`, + SIMP_TAC[CONTINUOUS_AT_CX_NORM; CONTINUOUS_AT_WITHIN]);; + +let CONTINUOUS_ON_CX_NORM = prove + (`!s. (\z. Cx(norm z)) continuous_on s`, + SIMP_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN; CONTINUOUS_WITHIN_CX_NORM]);; + +let CONTINUOUS_AT_CX_DOT = prove + (`!c z:real^N. (\z. Cx(c dot z)) continuous at z`, + REPEAT GEN_TAC THEN MATCH_MP_TAC LINEAR_CONTINUOUS_AT THEN + REWRITE_TAC[linear; DOT_RADD; DOT_RMUL; CX_ADD; COMPLEX_CMUL; CX_MUL]);; + +let CONTINUOUS_WITHIN_CX_DOT = prove + (`!c z:real^N s. (\z. Cx(c dot z)) continuous (at z within s)`, + SIMP_TAC[CONTINUOUS_AT_CX_DOT; CONTINUOUS_AT_WITHIN]);; + +let CONTINUOUS_ON_CX_DOT = prove + (`!s c:real^N. (\z. Cx(c dot z)) continuous_on s`, + SIMP_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN; CONTINUOUS_WITHIN_CX_DOT]);; + +(* ------------------------------------------------------------------------- *) +(* Continuity switching range between complex and real^1 *) +(* ------------------------------------------------------------------------- *) + +let CONTINUOUS_CX_DROP = prove + (`!net f. f continuous net ==> (\x. Cx(drop(f x))) continuous net`, + REWRITE_TAC[continuous; tendsto] THEN + REWRITE_TAC[dist; GSYM CX_SUB; COMPLEX_NORM_CX; GSYM DROP_SUB] THEN + REWRITE_TAC[GSYM ABS_DROP]);; + +let CONTINUOUS_ON_CX_DROP = prove + (`!f s. f continuous_on s ==> (\x. Cx(drop(f x))) continuous_on s`, + SIMP_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN; CONTINUOUS_CX_DROP]);; + +let CONTINUOUS_CX_LIFT = prove + (`!f. (\x. Cx(f x)) continuous net <=> (\x. lift(f x)) continuous net`, + REWRITE_TAC[continuous; LIM; dist; GSYM CX_SUB; GSYM LIFT_SUB] THEN + REWRITE_TAC[COMPLEX_NORM_CX; NORM_LIFT]);; + +let CONTINUOUS_ON_CX_LIFT = prove + (`!f s. (\x. Cx(f x)) continuous_on s <=> (\x. lift(f x)) continuous_on s`, + REWRITE_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN; CONTINUOUS_CX_LIFT]);; + +(* ------------------------------------------------------------------------- *) +(* Linearity and continuity of the components. *) +(* ------------------------------------------------------------------------- *) + +let LINEAR_CX_RE = prove + (`linear(Cx o Re)`, + SIMP_TAC[linear; o_THM; COMPLEX_CMUL; RE_ADD; RE_MUL_CX; CX_MUL; CX_ADD]);; + +let CONTINUOUS_AT_CX_RE = prove + (`!z. (Cx o Re) continuous at z`, + SIMP_TAC[LINEAR_CONTINUOUS_AT; LINEAR_CX_RE]);; + +let CONTINUOUS_ON_CX_RE = prove + (`!s. (Cx o Re) continuous_on s`, + SIMP_TAC[LINEAR_CONTINUOUS_ON; LINEAR_CX_RE]);; + +let LINEAR_CX_IM = prove + (`linear(Cx o Im)`, + SIMP_TAC[linear; o_THM; COMPLEX_CMUL; IM_ADD; IM_MUL_CX; CX_MUL; CX_ADD]);; + +let CONTINUOUS_AT_CX_IM = prove + (`!z. (Cx o Im) continuous at z`, + SIMP_TAC[LINEAR_CONTINUOUS_AT; LINEAR_CX_IM]);; + +let CONTINUOUS_ON_CX_IM = prove + (`!s. (Cx o Im) continuous_on s`, + SIMP_TAC[LINEAR_CONTINUOUS_ON; LINEAR_CX_IM]);; + +(* ------------------------------------------------------------------------- *) +(* Complex differentiability. *) +(* ------------------------------------------------------------------------- *) + +parse_as_infix ("has_complex_derivative",(12,"right"));; +parse_as_infix ("complex_differentiable",(12,"right"));; +parse_as_infix ("holomorphic_on",(12,"right"));; + +let has_complex_derivative = new_definition + `(f has_complex_derivative f') net <=> (f has_derivative (\x. f' * x)) net`;; + +let complex_differentiable = new_definition + `f complex_differentiable net <=> ?f'. (f has_complex_derivative f') net`;; + +let complex_derivative = new_definition + `complex_derivative f x = @f'. (f has_complex_derivative f') (at x)`;; + +let higher_complex_derivative = define + `higher_complex_derivative 0 f = f /\ + (!n. higher_complex_derivative (SUC n) f = + complex_derivative (higher_complex_derivative n f))`;; + +let holomorphic_on = new_definition + `f holomorphic_on s <=> + !x. x IN s ==> ?f'. (f has_complex_derivative f') (at x within s)`;; + +let HOLOMORPHIC_ON_DIFFERENTIABLE = prove + (`!f s. f holomorphic_on s <=> + !x. x IN s ==> f complex_differentiable (at x within s)`, + REWRITE_TAC[holomorphic_on; complex_differentiable]);; + +let HOLOMORPHIC_ON_OPEN = prove + (`!f s. open s + ==> (f holomorphic_on s <=> + !x. x IN s ==> ?f'. (f has_complex_derivative f') (at x))`, + REWRITE_TAC[holomorphic_on; has_complex_derivative] THEN + REWRITE_TAC[has_derivative_at; has_derivative_within] THEN + SIMP_TAC[LIM_WITHIN_OPEN]);; + +let HOLOMORPHIC_ON_IMP_DIFFERENTIABLE_WITHIN = prove + (`!f s x. f holomorphic_on s /\ x IN s + ==> f complex_differentiable (at x within s)`, + MESON_TAC[HOLOMORPHIC_ON_DIFFERENTIABLE]);; + +let HOLOMORPHIC_ON_IMP_DIFFERENTIABLE_AT = prove + (`!f s x. f holomorphic_on s /\ open s /\ x IN s + ==> f complex_differentiable (at x)`, + MESON_TAC[HOLOMORPHIC_ON_OPEN; complex_differentiable]);; + +let HAS_COMPLEX_DERIVATIVE_IMP_CONTINUOUS_AT = prove + (`!f f' x. (f has_complex_derivative f') (at x) ==> f continuous at x`, + REWRITE_TAC[has_complex_derivative] THEN + MESON_TAC[differentiable; DIFFERENTIABLE_IMP_CONTINUOUS_AT]);; + +let HAS_COMPLEX_DERIVATIVE_IMP_CONTINUOUS_WITHIN = prove + (`!f f' x s. (f has_complex_derivative f') (at x within s) + ==> f continuous (at x within s)`, + REWRITE_TAC[has_complex_derivative] THEN + MESON_TAC[differentiable; DIFFERENTIABLE_IMP_CONTINUOUS_WITHIN]);; + +let COMPLEX_DIFFERENTIABLE_IMP_CONTINUOUS_AT = prove + (`!f x. f complex_differentiable at x ==> f continuous at x`, + MESON_TAC[HAS_COMPLEX_DERIVATIVE_IMP_CONTINUOUS_AT; complex_differentiable]);; + +let HOLOMORPHIC_ON_IMP_CONTINUOUS_ON = prove + (`!f s. f holomorphic_on s ==> f continuous_on s`, + REWRITE_TAC[holomorphic_on; CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN] THEN + REWRITE_TAC[has_complex_derivative] THEN + MESON_TAC[DIFFERENTIABLE_IMP_CONTINUOUS_WITHIN; differentiable]);; + +let HOLOMORPHIC_ON_SUBSET = prove + (`!f s t. f holomorphic_on s /\ t SUBSET s ==> f holomorphic_on t`, + REWRITE_TAC[holomorphic_on; has_complex_derivative] THEN + MESON_TAC[SUBSET; HAS_DERIVATIVE_WITHIN_SUBSET]);; + +let HAS_COMPLEX_DERIVATIVE_WITHIN_SUBSET = prove + (`!f s t x. (f has_complex_derivative f') (at x within s) /\ t SUBSET s + ==> (f has_complex_derivative f') (at x within t)`, + REWRITE_TAC[has_complex_derivative; HAS_DERIVATIVE_WITHIN_SUBSET]);; + +let COMPLEX_DIFFERENTIABLE_WITHIN_SUBSET = prove + (`!f s t. f complex_differentiable (at x within s) /\ t SUBSET s + ==> f complex_differentiable (at x within t)`, + REWRITE_TAC[complex_differentiable] THEN + MESON_TAC[HAS_COMPLEX_DERIVATIVE_WITHIN_SUBSET]);; + +let HAS_COMPLEX_DERIVATIVE_AT_WITHIN = prove + (`!f f' x s. (f has_complex_derivative f') (at x) + ==> (f has_complex_derivative f') (at x within s)`, + REWRITE_TAC[has_complex_derivative; HAS_DERIVATIVE_AT_WITHIN]);; + +let HAS_COMPLEX_DERIVATIVE_WITHIN_OPEN = prove + (`!f f' a s. + a IN s /\ open s + ==> ((f has_complex_derivative f') (at a within s) <=> + (f has_complex_derivative f') (at a))`, + REWRITE_TAC[has_complex_derivative; HAS_DERIVATIVE_WITHIN_OPEN]);; + +let COMPLEX_DIFFERENTIABLE_AT_WITHIN = prove + (`!f s z. f complex_differentiable (at z) + ==> f complex_differentiable (at z within s)`, + REWRITE_TAC[complex_differentiable] THEN + MESON_TAC[HAS_COMPLEX_DERIVATIVE_AT_WITHIN]);; + +let HAS_COMPLEX_DERIVATIVE_TRANSFORM_WITHIN = prove + (`!f f' g x s d. + &0 < d /\ x IN s /\ + (!x'. x' IN s /\ dist (x',x) < d ==> f x' = g x') /\ + (f has_complex_derivative f') (at x within s) + ==> (g has_complex_derivative f') (at x within s)`, + REWRITE_TAC[has_complex_derivative] THEN + MESON_TAC[HAS_DERIVATIVE_TRANSFORM_WITHIN]);; + +let HAS_COMPLEX_DERIVATIVE_TRANSFORM_WITHIN_OPEN = prove + (`!f g f' s z. open s /\ z IN s /\ (!w. w IN s ==> f w = g w) /\ + (f has_complex_derivative f') (at z) + ==> (g has_complex_derivative f') (at z)`, + REWRITE_TAC [has_complex_derivative] THEN + ASM_MESON_TAC [HAS_DERIVATIVE_TRANSFORM_WITHIN_OPEN]);; + +let HAS_COMPLEX_DERIVATIVE_TRANSFORM_AT = prove + (`!f f' g x d. + &0 < d /\ (!x'. dist (x',x) < d ==> f x' = g x') /\ + (f has_complex_derivative f') (at x) + ==> (g has_complex_derivative f') (at x)`, + ONCE_REWRITE_TAC[GSYM WITHIN_UNIV] THEN + MESON_TAC[HAS_COMPLEX_DERIVATIVE_TRANSFORM_WITHIN; IN_UNIV]);; + +let HAS_COMPLEX_DERIVATIVE_ZERO_CONSTANT = prove + (`!f s. + convex s /\ + (!x. x IN s ==> (f has_complex_derivative Cx(&0)) (at x within s)) + ==> ?c. !x. x IN s ==> f(x) = c`, + REWRITE_TAC[has_complex_derivative; COMPLEX_MUL_LZERO] THEN + REWRITE_TAC[GSYM COMPLEX_VEC_0; HAS_DERIVATIVE_ZERO_CONSTANT]);; + +let HAS_COMPLEX_DERIVATIVE_ZERO_UNIQUE = prove + (`!f s c a. + convex s /\ a IN s /\ f a = c /\ + (!x. x IN s ==> (f has_complex_derivative Cx(&0)) (at x within s)) + ==> !x. x IN s ==> f(x) = c`, + REWRITE_TAC[has_complex_derivative; COMPLEX_MUL_LZERO] THEN + REWRITE_TAC[GSYM COMPLEX_VEC_0; HAS_DERIVATIVE_ZERO_UNIQUE]);; + +let HAS_COMPLEX_DERIVATIVE_ZERO_CONNECTED_CONSTANT = prove + (`!f s. + open s /\ connected s /\ + (!x. x IN s ==> (f has_complex_derivative Cx(&0)) (at x)) + ==> ?c. !x. x IN s ==> f(x) = c`, + REWRITE_TAC[has_complex_derivative; COMPLEX_MUL_LZERO] THEN + REWRITE_TAC[GSYM COMPLEX_VEC_0; HAS_DERIVATIVE_ZERO_CONNECTED_CONSTANT]);; + +let HAS_COMPLEX_DERIVATIVE_ZERO_CONNECTED_UNIQUE = prove + (`!f s c a. + open s /\ connected s /\ a IN s /\ f a = c /\ + (!x. x IN s ==> (f has_complex_derivative Cx(&0)) (at x)) + ==> !x. x IN s ==> f(x) = c`, + REWRITE_TAC[has_complex_derivative; COMPLEX_MUL_LZERO] THEN + REWRITE_TAC[GSYM COMPLEX_VEC_0; HAS_DERIVATIVE_ZERO_CONNECTED_UNIQUE]);; + +let COMPLEX_DIFF_CHAIN_WITHIN = prove + (`!f g f' g' x s. + (f has_complex_derivative f') (at x within s) /\ + (g has_complex_derivative g') (at (f x) within (IMAGE f s)) + ==> ((g o f) has_complex_derivative (g' * f'))(at x within s)`, + REPEAT GEN_TAC THEN REWRITE_TAC[has_complex_derivative] THEN + DISCH_THEN(MP_TAC o MATCH_MP DIFF_CHAIN_WITHIN) THEN + REWRITE_TAC[o_DEF; COMPLEX_MUL_ASSOC]);; + +let COMPLEX_DIFF_CHAIN_AT = prove + (`!f g f' g' x. + (f has_complex_derivative f') (at x) /\ + (g has_complex_derivative g') (at (f x)) + ==> ((g o f) has_complex_derivative (g' * f')) (at x)`, + ONCE_REWRITE_TAC[GSYM WITHIN_UNIV] THEN + ASM_MESON_TAC[COMPLEX_DIFF_CHAIN_WITHIN; SUBSET_UNIV; + HAS_COMPLEX_DERIVATIVE_WITHIN_SUBSET]);; + +let HAS_COMPLEX_DERIVATIVE_CHAIN = prove + (`!P f g. + (!x. P x ==> (g has_complex_derivative g'(x)) (at x)) + ==> (!x s. (f has_complex_derivative f') (at x within s) /\ P(f x) + ==> ((\x. g(f x)) has_complex_derivative f' * g'(f x)) + (at x within s)) /\ + (!x. (f has_complex_derivative f') (at x) /\ P(f x) + ==> ((\x. g(f x)) has_complex_derivative f' * g'(f x)) + (at x))`, + REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM o_DEF] THEN + ONCE_REWRITE_TAC[COMPLEX_MUL_SYM] THEN + ASM_MESON_TAC[COMPLEX_DIFF_CHAIN_WITHIN; COMPLEX_DIFF_CHAIN_AT; + HAS_COMPLEX_DERIVATIVE_AT_WITHIN]);; + +let HAS_COMPLEX_DERIVATIVE_CHAIN_UNIV = prove + (`!f g. (!x. (g has_complex_derivative g'(x)) (at x)) + ==> (!x s. (f has_complex_derivative f') (at x within s) + ==> ((\x. g(f x)) has_complex_derivative f' * g'(f x)) + (at x within s)) /\ + (!x. (f has_complex_derivative f') (at x) + ==> ((\x. g(f x)) has_complex_derivative f' * g'(f x)) + (at x))`, + MP_TAC(SPEC `\x:complex. T` HAS_COMPLEX_DERIVATIVE_CHAIN) THEN SIMP_TAC[]);; + +let COMPLEX_DERIVATIVE_UNIQUE_AT = prove + (`!f z f' f''. + (f has_complex_derivative f') (at z) /\ + (f has_complex_derivative f'') (at z) + ==> f' = f''`, + REPEAT GEN_TAC THEN REWRITE_TAC[has_complex_derivative] THEN + DISCH_THEN(MP_TAC o MATCH_MP FRECHET_DERIVATIVE_UNIQUE_AT) THEN + DISCH_THEN(MP_TAC o C AP_THM `Cx(&1)`) THEN + REWRITE_TAC[COMPLEX_MUL_RID]);; + +let HIGHER_COMPLEX_DERIVATIVE_1 = prove + (`!f z. higher_complex_derivative 1 f z = complex_derivative f z`, + REWRITE_TAC[num_CONV `1`; higher_complex_derivative]);; + +(* ------------------------------------------------------------------------- *) +(* A more direct characterization. *) +(* ------------------------------------------------------------------------- *) + +let HAS_COMPLEX_DERIVATIVE_WITHIN = prove + (`!f s a. (f has_complex_derivative f') (at a within s) <=> + ((\x. (f(x) - f(a)) / (x - a)) --> f') (at a within s)`, + REWRITE_TAC[has_complex_derivative; has_derivative_within] THEN + REPEAT GEN_TAC THEN REWRITE_TAC[LINEAR_COMPLEX_MUL] THEN + GEN_REWRITE_TAC RAND_CONV [LIM_NULL] THEN + REWRITE_TAC[LIM_WITHIN; dist; VECTOR_SUB_RZERO; NORM_MUL] THEN + REWRITE_TAC[NORM_POS_LT; VECTOR_SUB_EQ] THEN SIMP_TAC[COMPLEX_FIELD + `~(x:complex = a) ==> y / (x - a) - z = inv(x - a) * (y - z * (x - a))`] THEN + REWRITE_TAC[REAL_ABS_INV; COMPLEX_NORM_MUL; REAL_ABS_NORM; + COMPLEX_NORM_INV; VECTOR_ARITH `a:complex - (b + c) = a - b - c`]);; + +let HAS_COMPLEX_DERIVATIVE_AT = prove + (`!f a. (f has_complex_derivative f') (at a) <=> + ((\x. (f(x) - f(a)) / (x - a)) --> f') (at a)`, + ONCE_REWRITE_TAC[GSYM WITHIN_UNIV] THEN + REWRITE_TAC[HAS_COMPLEX_DERIVATIVE_WITHIN]);; + +(* ------------------------------------------------------------------------- *) +(* Arithmetical combining theorems. *) +(* ------------------------------------------------------------------------- *) + +let HAS_DERIVATIVE_COMPLEX_CMUL = prove + (`!net c. ((\x. c * x) has_derivative (\x. c * x)) net`, + REPEAT GEN_TAC THEN MATCH_MP_TAC HAS_DERIVATIVE_LINEAR THEN + REWRITE_TAC[LINEAR_COMPLEX_MUL]);; + +let HAS_COMPLEX_DERIVATIVE_LINEAR = prove + (`!net c. ((\x. c * x) has_complex_derivative c) net`, + REPEAT GEN_TAC THEN REWRITE_TAC[has_complex_derivative] THEN + MATCH_MP_TAC HAS_DERIVATIVE_LINEAR THEN + REWRITE_TAC[linear; COMPLEX_CMUL] THEN CONV_TAC COMPLEX_RING);; + +let HAS_COMPLEX_DERIVATIVE_LMUL_WITHIN = prove + (`!f f' c x s. + (f has_complex_derivative f') (at x within s) + ==> ((\x. c * f(x)) has_complex_derivative (c * f')) (at x within s)`, + REPEAT GEN_TAC THEN + MP_TAC(ISPECL [`at ((f:complex->complex) x) within (IMAGE f s)`; `c:complex`] + HAS_COMPLEX_DERIVATIVE_LINEAR) THEN + ONCE_REWRITE_TAC[TAUT `a ==> b ==> c <=> b /\ a ==> c`] THEN + DISCH_THEN(MP_TAC o MATCH_MP COMPLEX_DIFF_CHAIN_WITHIN) THEN + REWRITE_TAC[o_DEF]);; + +let HAS_COMPLEX_DERIVATIVE_LMUL_AT = prove + (`!f f' c x. + (f has_complex_derivative f') (at x) + ==> ((\x. c * f(x)) has_complex_derivative (c * f')) (at x)`, + ONCE_REWRITE_TAC[GSYM WITHIN_UNIV] THEN + REWRITE_TAC[HAS_COMPLEX_DERIVATIVE_LMUL_WITHIN]);; + +let HAS_COMPLEX_DERIVATIVE_RMUL_WITHIN = prove + (`!f f' c x s. + (f has_complex_derivative f') (at x within s) + ==> ((\x. f(x) * c) has_complex_derivative (f' * c)) (at x within s)`, + ONCE_REWRITE_TAC[COMPLEX_MUL_SYM] THEN + REWRITE_TAC[HAS_COMPLEX_DERIVATIVE_LMUL_WITHIN]);; + +let HAS_COMPLEX_DERIVATIVE_RMUL_AT = prove + (`!f f' c x. + (f has_complex_derivative f') (at x) + ==> ((\x. f(x) * c) has_complex_derivative (f' * c)) (at x)`, + ONCE_REWRITE_TAC[COMPLEX_MUL_SYM] THEN + REWRITE_TAC[HAS_COMPLEX_DERIVATIVE_LMUL_AT]);; + +let HAS_COMPLEX_DERIVATIVE_CDIV_WITHIN = prove + (`!f f' c x s. + (f has_complex_derivative f') (at x within s) + ==> ((\x. f(x) / c) has_complex_derivative (f' / c)) (at x within s)`, + SIMP_TAC[complex_div; HAS_COMPLEX_DERIVATIVE_RMUL_WITHIN]);; + +let HAS_COMPLEX_DERIVATIVE_CDIV_AT = prove + (`!f f' c x s. + (f has_complex_derivative f') (at x) + ==> ((\x. f(x) / c) has_complex_derivative (f' / c)) (at x)`, + SIMP_TAC[complex_div; HAS_COMPLEX_DERIVATIVE_RMUL_AT]);; + +let HAS_COMPLEX_DERIVATIVE_ID = prove + (`!net. ((\x. x) has_complex_derivative Cx(&1)) net`, + REWRITE_TAC[has_complex_derivative; HAS_DERIVATIVE_ID; COMPLEX_MUL_LID]);; + +let HAS_COMPLEX_DERIVATIVE_CONST = prove + (`!c net. ((\x. c) has_complex_derivative Cx(&0)) net`, + REWRITE_TAC[has_complex_derivative; COMPLEX_MUL_LZERO] THEN + REWRITE_TAC[GSYM COMPLEX_VEC_0; HAS_DERIVATIVE_CONST]);; + +let HAS_COMPLEX_DERIVATIVE_NEG = prove + (`!f f' net. (f has_complex_derivative f') net + ==> ((\x. --(f(x))) has_complex_derivative (--f')) net`, + SIMP_TAC[has_complex_derivative; COMPLEX_MUL_LNEG; HAS_DERIVATIVE_NEG]);; + +let HAS_COMPLEX_DERIVATIVE_ADD = prove + (`!f f' g g' net. + (f has_complex_derivative f') net /\ (g has_complex_derivative g') net + ==> ((\x. f(x) + g(x)) has_complex_derivative (f' + g')) net`, + SIMP_TAC[has_complex_derivative; COMPLEX_ADD_RDISTRIB; HAS_DERIVATIVE_ADD]);; + +let HAS_COMPLEX_DERIVATIVE_SUB = prove + (`!f f' g g' net. + (f has_complex_derivative f') net /\ (g has_complex_derivative g') net + ==> ((\x. f(x) - g(x)) has_complex_derivative (f' - g')) net`, + SIMP_TAC[has_complex_derivative; COMPLEX_SUB_RDISTRIB; HAS_DERIVATIVE_SUB]);; + +let HAS_COMPLEX_DERIVATIVE_MUL_WITHIN = prove + (`!f f' g g' x s. + (f has_complex_derivative f') (at x within s) /\ + (g has_complex_derivative g') (at x within s) + ==> ((\x. f(x) * g(x)) has_complex_derivative + (f(x) * g' + f' * g(x))) (at x within s)`, + REPEAT GEN_TAC THEN SIMP_TAC[has_complex_derivative] THEN + DISCH_THEN(MP_TAC o C CONJ BILINEAR_COMPLEX_MUL) THEN + REWRITE_TAC[GSYM CONJ_ASSOC] THEN + DISCH_THEN(MP_TAC o MATCH_MP HAS_DERIVATIVE_BILINEAR_WITHIN) THEN + MATCH_MP_TAC EQ_IMP THEN + AP_THM_TAC THEN AP_TERM_TAC THEN REWRITE_TAC[FUN_EQ_THM] THEN + CONV_TAC COMPLEX_RING);; + +let HAS_COMPLEX_DERIVATIVE_MUL_AT = prove + (`!f f' g g' x. + (f has_complex_derivative f') (at x) /\ + (g has_complex_derivative g') (at x) + ==> ((\x. f(x) * g(x)) has_complex_derivative + (f(x) * g' + f' * g(x))) (at x)`, + ONCE_REWRITE_TAC[GSYM WITHIN_UNIV] THEN + REWRITE_TAC[HAS_COMPLEX_DERIVATIVE_MUL_WITHIN]);; + +let HAS_COMPLEX_DERIVATIVE_POW_WITHIN = prove + (`!f f' x s n. (f has_complex_derivative f') (at x within s) + ==> ((\x. f(x) pow n) has_complex_derivative + (Cx(&n) * f(x) pow (n - 1) * f')) (at x within s)`, + REWRITE_TAC[RIGHT_FORALL_IMP_THM] THEN REPEAT GEN_TAC THEN DISCH_TAC THEN + INDUCT_TAC THEN REWRITE_TAC[complex_pow] THEN + REWRITE_TAC[HAS_COMPLEX_DERIVATIVE_CONST; COMPLEX_MUL_LZERO] THEN + POP_ASSUM_LIST(MP_TAC o end_itlist CONJ) THEN + DISCH_THEN(MP_TAC o MATCH_MP HAS_COMPLEX_DERIVATIVE_MUL_WITHIN) THEN + REWRITE_TAC[SUC_SUB1] THEN MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN + BINOP_TAC THEN REWRITE_TAC[COMPLEX_MUL_AC; GSYM REAL_OF_NUM_SUC] THEN + SPEC_TAC(`n:num`,`n:num`) THEN REWRITE_TAC[CX_ADD] THEN INDUCT_TAC THEN + CONV_TAC NUM_REDUCE_CONV THEN REWRITE_TAC[SUC_SUB1; complex_pow] THEN + CONV_TAC COMPLEX_FIELD);; + +let HAS_COMPLEX_DERIVATIVE_POW_AT = prove + (`!f f' x n. (f has_complex_derivative f') (at x) + ==> ((\x. f(x) pow n) has_complex_derivative + (Cx(&n) * f(x) pow (n - 1) * f')) (at x)`, + ONCE_REWRITE_TAC[GSYM WITHIN_UNIV] THEN + REWRITE_TAC[HAS_COMPLEX_DERIVATIVE_POW_WITHIN]);; + +let HAS_COMPLEX_DERIVATIVE_INV_BASIC = prove + (`!x. ~(x = Cx(&0)) + ==> ((inv) has_complex_derivative (--inv(x pow 2))) (at x)`, + REPEAT STRIP_TAC THEN + REWRITE_TAC[has_complex_derivative; has_derivative_at] THEN + REWRITE_TAC[LINEAR_COMPLEX_MUL; COMPLEX_VEC_0] THEN + MATCH_MP_TAC LIM_TRANSFORM_AWAY_AT THEN + MAP_EVERY EXISTS_TAC + [`\y. inv(norm(y - x)) % inv(x pow 2 * y) * (y - x) pow 2`; `Cx(&0)`] THEN + ASM_REWRITE_TAC[COMPLEX_CMUL] THEN CONJ_TAC THENL + [POP_ASSUM MP_TAC THEN CONV_TAC COMPLEX_FIELD; ALL_TAC] THEN + SUBGOAL_THEN `((\y. inv(x pow 2 * y) * (y - x)) --> Cx(&0)) (at x)` + MP_TAC THENL + [LIM_TAC THEN POP_ASSUM MP_TAC THEN CONV_TAC COMPLEX_FIELD; ALL_TAC] THEN + MATCH_MP_TAC EQ_IMP THEN REWRITE_TAC[LIM_AT] THEN + REWRITE_TAC[dist; COMPLEX_SUB_RZERO] THEN + REWRITE_TAC[COMPLEX_NORM_MUL; COMPLEX_NORM_INV; COMPLEX_NORM_POW] THEN + REWRITE_TAC[COMPLEX_NORM_CX; REAL_ABS_INV; REAL_ABS_NORM] THEN + REPLICATE_TAC 2 (AP_TERM_TAC THEN ABS_TAC THEN AP_TERM_TAC) THEN + AP_TERM_TAC THEN ABS_TAC THEN + MATCH_MP_TAC(MESON[] + `(p ==> x = y) ==> ((p ==> x < e) <=> (p ==> y < e))`) THEN + MAP_EVERY ABBREV_TAC + [`n = norm(x' - x:complex)`; + `m = inv (norm(x:complex) pow 2 * norm(x':complex))`] THEN + CONV_TAC REAL_FIELD);; + +let HAS_COMPLEX_DERIVATIVE_INV_WITHIN = prove + (`!f f' x s. (f has_complex_derivative f') (at x within s) /\ + ~(f x = Cx(&0)) + ==> ((\x. inv(f(x))) has_complex_derivative (--f' / f(x) pow 2)) + (at x within s)`, + REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[GSYM o_DEF] THEN + ASM_SIMP_TAC[COMPLEX_FIELD + `~(g = Cx(&0)) ==> --f / g pow 2 = --inv(g pow 2) * f`] THEN + MATCH_MP_TAC COMPLEX_DIFF_CHAIN_WITHIN THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC HAS_COMPLEX_DERIVATIVE_AT_WITHIN THEN + ASM_SIMP_TAC[HAS_COMPLEX_DERIVATIVE_INV_BASIC]);; + +let HAS_COMPLEX_DERIVATIVE_INV_AT = prove + (`!f f' x. (f has_complex_derivative f') (at x) /\ + ~(f x = Cx(&0)) + ==> ((\x. inv(f(x))) has_complex_derivative (--f' / f(x) pow 2)) + (at x)`, + ONCE_REWRITE_TAC[GSYM WITHIN_UNIV] THEN + REWRITE_TAC[HAS_COMPLEX_DERIVATIVE_INV_WITHIN]);; + +let HAS_COMPLEX_DERIVATIVE_DIV_WITHIN = prove + (`!f f' g g' x s. + (f has_complex_derivative f') (at x within s) /\ + (g has_complex_derivative g') (at x within s) /\ + ~(g(x) = Cx(&0)) + ==> ((\x. f(x) / g(x)) has_complex_derivative + (f' * g(x) - f(x) * g') / g(x) pow 2) (at x within s)`, + REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + DISCH_THEN(fun th -> ASSUME_TAC(CONJUNCT2 th) THEN MP_TAC th) THEN + DISCH_THEN(MP_TAC o MATCH_MP HAS_COMPLEX_DERIVATIVE_INV_WITHIN) THEN + UNDISCH_TAC `(f has_complex_derivative f') (at x within s)` THEN + REWRITE_TAC[IMP_IMP] THEN + DISCH_THEN(MP_TAC o MATCH_MP HAS_COMPLEX_DERIVATIVE_MUL_WITHIN) THEN + REWRITE_TAC[GSYM complex_div] THEN MATCH_MP_TAC EQ_IMP THEN + AP_THM_TAC THEN AP_TERM_TAC THEN + POP_ASSUM MP_TAC THEN CONV_TAC COMPLEX_FIELD);; + +let HAS_COMPLEX_DERIVATIVE_DIV_AT = prove + (`!f f' g g' x. + (f has_complex_derivative f') (at x) /\ + (g has_complex_derivative g') (at x) /\ + ~(g(x) = Cx(&0)) + ==> ((\x. f(x) / g(x)) has_complex_derivative + (f' * g(x) - f(x) * g') / g(x) pow 2) (at x)`, + ONCE_REWRITE_TAC[GSYM WITHIN_UNIV] THEN + REWRITE_TAC[HAS_COMPLEX_DERIVATIVE_DIV_WITHIN]);; + +let HAS_COMPLEX_DERIVATIVE_VSUM = prove + (`!f net s. + FINITE s /\ (!a. a IN s ==> (f a has_complex_derivative f' a) net) + ==> ((\x. vsum s (\a. f a x)) has_complex_derivative (vsum s f')) + net`, + SIMP_TAC[GSYM VSUM_COMPLEX_RMUL; has_complex_derivative] THEN + REPEAT GEN_TAC THEN DISCH_THEN(MP_TAC o MATCH_MP HAS_DERIVATIVE_VSUM) THEN + REWRITE_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* Same thing just for complex differentiability. *) +(* ------------------------------------------------------------------------- *) + +let COMPLEX_DIFFERENTIABLE_LINEAR = prove + (`(\z. c * z) complex_differentiable p`, + REWRITE_TAC [complex_differentiable] THEN + MESON_TAC [HAS_COMPLEX_DERIVATIVE_LINEAR]);; + +let COMPLEX_DIFFERENTIABLE_CONST = prove + (`!c net. (\z. c) complex_differentiable net`, + REWRITE_TAC[complex_differentiable] THEN + MESON_TAC[HAS_COMPLEX_DERIVATIVE_CONST]);; + +let COMPLEX_DIFFERENTIABLE_ID = prove + (`!net. (\z. z) complex_differentiable net`, + REWRITE_TAC[complex_differentiable] THEN + MESON_TAC[HAS_COMPLEX_DERIVATIVE_ID]);; + +let COMPLEX_DIFFERENTIABLE_NEG = prove + (`!f net. + f complex_differentiable net + ==> (\z. --(f z)) complex_differentiable net`, + REWRITE_TAC[complex_differentiable] THEN + MESON_TAC[HAS_COMPLEX_DERIVATIVE_NEG]);; + +let COMPLEX_DIFFERENTIABLE_ADD = prove + (`!f g net. + f complex_differentiable net /\ + g complex_differentiable net + ==> (\z. f z + g z) complex_differentiable net`, + REWRITE_TAC[complex_differentiable] THEN + MESON_TAC[HAS_COMPLEX_DERIVATIVE_ADD]);; + +let COMPLEX_DIFFERENTIABLE_SUB = prove + (`!f g net. + f complex_differentiable net /\ + g complex_differentiable net + ==> (\z. f z - g z) complex_differentiable net`, + REWRITE_TAC[complex_differentiable] THEN + MESON_TAC[HAS_COMPLEX_DERIVATIVE_SUB]);; + +let COMPLEX_DIFFERENTIABLE_INV_WITHIN = prove + (`!f z s. + f complex_differentiable (at z within s) /\ ~(f z = Cx(&0)) + ==> (\z. inv(f z)) complex_differentiable (at z within s)`, + REWRITE_TAC[complex_differentiable] THEN + MESON_TAC[HAS_COMPLEX_DERIVATIVE_INV_WITHIN]);; + +let COMPLEX_DIFFERENTIABLE_MUL_WITHIN = prove + (`!f g z s. + f complex_differentiable (at z within s) /\ + g complex_differentiable (at z within s) + ==> (\z. f z * g z) complex_differentiable (at z within s)`, + REWRITE_TAC[complex_differentiable] THEN + MESON_TAC[HAS_COMPLEX_DERIVATIVE_MUL_WITHIN]);; + +let COMPLEX_DIFFERENTIABLE_DIV_WITHIN = prove + (`!f g z s. + f complex_differentiable (at z within s) /\ + g complex_differentiable (at z within s) /\ + ~(g z = Cx(&0)) + ==> (\z. f z / g z) complex_differentiable (at z within s)`, + REWRITE_TAC[complex_differentiable] THEN + MESON_TAC[HAS_COMPLEX_DERIVATIVE_DIV_WITHIN]);; + +let COMPLEX_DIFFERENTIABLE_POW_WITHIN = prove + (`!f n z s. + f complex_differentiable (at z within s) + ==> (\z. f z pow n) complex_differentiable (at z within s)`, + REWRITE_TAC[complex_differentiable] THEN + MESON_TAC[HAS_COMPLEX_DERIVATIVE_POW_WITHIN]);; + +let COMPLEX_DIFFERENTIABLE_TRANSFORM_WITHIN = prove + (`!f g x s d. + &0 < d /\ + x IN s /\ + (!x'. x' IN s /\ dist (x',x) < d ==> f x' = g x') /\ + f complex_differentiable (at x within s) + ==> g complex_differentiable (at x within s)`, + REWRITE_TAC[complex_differentiable] THEN + MESON_TAC[HAS_COMPLEX_DERIVATIVE_TRANSFORM_WITHIN]);; + +let HOLOMORPHIC_TRANSFORM = prove + (`!f g s. (!x. x IN s ==> f x = g x) /\ f holomorphic_on s + ==> g holomorphic_on s`, + REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + REWRITE_TAC[holomorphic_on; GSYM complex_differentiable] THEN + MATCH_MP_TAC MONO_FORALL THEN GEN_TAC THEN + DISCH_THEN(fun th -> DISCH_TAC THEN MP_TAC th) THEN + ASM_REWRITE_TAC[] THEN DISCH_TAC THEN + MATCH_MP_TAC COMPLEX_DIFFERENTIABLE_TRANSFORM_WITHIN THEN + MAP_EVERY EXISTS_TAC [`f:complex->complex`; `&1`] THEN + ASM_SIMP_TAC[REAL_LT_01]);; + +let HOLOMORPHIC_EQ = prove + (`!f g s. (!x. x IN s ==> f x = g x) + ==> (f holomorphic_on s <=> g holomorphic_on s)`, + MESON_TAC[HOLOMORPHIC_TRANSFORM]);; + +let COMPLEX_DIFFERENTIABLE_INV_AT = prove + (`!f z. + f complex_differentiable at z /\ ~(f z = Cx(&0)) + ==> (\z. inv(f z)) complex_differentiable at z`, + REWRITE_TAC[complex_differentiable] THEN + MESON_TAC[HAS_COMPLEX_DERIVATIVE_INV_AT]);; + +let COMPLEX_DIFFERENTIABLE_MUL_AT = prove + (`!f g z. + f complex_differentiable at z /\ + g complex_differentiable at z + ==> (\z. f z * g z) complex_differentiable at z`, + REWRITE_TAC[complex_differentiable] THEN + MESON_TAC[HAS_COMPLEX_DERIVATIVE_MUL_AT]);; + +let COMPLEX_DIFFERENTIABLE_DIV_AT = prove + (`!f g z. + f complex_differentiable at z /\ + g complex_differentiable at z /\ + ~(g z = Cx(&0)) + ==> (\z. f z / g z) complex_differentiable at z`, + REWRITE_TAC[complex_differentiable] THEN + MESON_TAC[HAS_COMPLEX_DERIVATIVE_DIV_AT]);; + +let COMPLEX_DIFFERENTIABLE_POW_AT = prove + (`!f n z. + f complex_differentiable at z + ==> (\z. f z pow n) complex_differentiable at z`, + REWRITE_TAC[complex_differentiable] THEN + MESON_TAC[HAS_COMPLEX_DERIVATIVE_POW_AT]);; + +let COMPLEX_DIFFERENTIABLE_TRANSFORM_AT = prove + (`!f g x d. + &0 < d /\ + (!x'. dist (x',x) < d ==> f x' = g x') /\ + f complex_differentiable at x + ==> g complex_differentiable at x`, + REWRITE_TAC[complex_differentiable] THEN + MESON_TAC[HAS_COMPLEX_DERIVATIVE_TRANSFORM_AT]);; + +let COMPLEX_DIFFERENTIABLE_COMPOSE_WITHIN = prove + (`!f g x s. + f complex_differentiable (at x within s) /\ + g complex_differentiable (at (f x) within IMAGE f s) + ==> (g o f) complex_differentiable (at x within s)`, + REWRITE_TAC[complex_differentiable] THEN + MESON_TAC[COMPLEX_DIFF_CHAIN_WITHIN]);; + +let COMPLEX_DIFFERENTIABLE_COMPOSE_AT = prove + (`!f g x s. + f complex_differentiable (at x) /\ + g complex_differentiable (at (f x)) + ==> (g o f) complex_differentiable (at x)`, + REWRITE_TAC[complex_differentiable] THEN + MESON_TAC[COMPLEX_DIFF_CHAIN_AT]);; + +let COMPLEX_DIFFERENTIABLE_WITHIN_OPEN = prove + (`!f a s. + a IN s /\ open s + ==> (f complex_differentiable at a within s <=> + f complex_differentiable at a)`, + SIMP_TAC[complex_differentiable; HAS_COMPLEX_DERIVATIVE_WITHIN_OPEN]);; + +(* ------------------------------------------------------------------------- *) +(* Same again for being holomorphic on a set. *) +(* ------------------------------------------------------------------------- *) + +let HOLOMORPHIC_ON_LINEAR = prove + (`!s c. (\w. c * w) holomorphic_on s`, + REWRITE_TAC [holomorphic_on] THEN + MESON_TAC [HAS_COMPLEX_DERIVATIVE_LINEAR]);; + +let HOLOMORPHIC_ON_CONST = prove + (`!c s. (\z. c) holomorphic_on s`, + REWRITE_TAC[HOLOMORPHIC_ON_DIFFERENTIABLE; COMPLEX_DIFFERENTIABLE_CONST]);; + +let HOLOMORPHIC_ON_ID = prove + (`!s. (\z. z) holomorphic_on s`, + REWRITE_TAC[HOLOMORPHIC_ON_DIFFERENTIABLE; COMPLEX_DIFFERENTIABLE_ID]);; + +let HOLOMORPHIC_ON_COMPOSE = prove + (`!f g s. f holomorphic_on s /\ g holomorphic_on (IMAGE f s) + ==> (g o f) holomorphic_on s`, + SIMP_TAC[holomorphic_on; GSYM complex_differentiable; FORALL_IN_IMAGE] THEN + MESON_TAC[COMPLEX_DIFFERENTIABLE_COMPOSE_WITHIN]);; + +let HOLOMORPHIC_ON_NEG = prove + (`!f s. f holomorphic_on s ==> (\z. --(f z)) holomorphic_on s`, + SIMP_TAC[HOLOMORPHIC_ON_DIFFERENTIABLE; COMPLEX_DIFFERENTIABLE_NEG]);; + +let HOLOMORPHIC_ON_ADD = prove + (`!f g s. + f holomorphic_on s /\ g holomorphic_on s + ==> (\z. f z + g z) holomorphic_on s`, + SIMP_TAC[HOLOMORPHIC_ON_DIFFERENTIABLE; COMPLEX_DIFFERENTIABLE_ADD]);; + +let HOLOMORPHIC_ON_SUB = prove + (`!f g s. + f holomorphic_on s /\ g holomorphic_on s + ==> (\z. f z - g z) holomorphic_on s`, + SIMP_TAC[HOLOMORPHIC_ON_DIFFERENTIABLE; COMPLEX_DIFFERENTIABLE_SUB]);; + +let HOLOMORPHIC_ON_MUL = prove + (`!f g s. + f holomorphic_on s /\ g holomorphic_on s + ==> (\z. f z * g z) holomorphic_on s`, + SIMP_TAC[HOLOMORPHIC_ON_DIFFERENTIABLE; COMPLEX_DIFFERENTIABLE_MUL_WITHIN]);; + +let HOLOMORPHIC_ON_INV = prove + (`!f s. f holomorphic_on s /\ (!z. z IN s ==> ~(f z = Cx(&0))) + ==> (\z. inv(f z)) holomorphic_on s`, + SIMP_TAC[HOLOMORPHIC_ON_DIFFERENTIABLE; COMPLEX_DIFFERENTIABLE_INV_WITHIN]);; + +let HOLOMORPHIC_ON_DIV = prove + (`!f g s. + f holomorphic_on s /\ g holomorphic_on s /\ + (!z. z IN s ==> ~(g z = Cx(&0))) + ==> (\z. f z / g z) holomorphic_on s`, + SIMP_TAC[HOLOMORPHIC_ON_DIFFERENTIABLE; COMPLEX_DIFFERENTIABLE_DIV_WITHIN]);; + +let HOLOMORPHIC_ON_POW = prove + (`!f s n. f holomorphic_on s ==> (\z. (f z) pow n) holomorphic_on s`, + SIMP_TAC[HOLOMORPHIC_ON_DIFFERENTIABLE; COMPLEX_DIFFERENTIABLE_POW_WITHIN]);; + +let HOLOMORPHIC_ON_VSUM = prove + (`!f s k. FINITE k /\ (!a. a IN k ==> (f a) holomorphic_on s) + ==> (\x. vsum k (\a. f a x)) holomorphic_on s`, + GEN_TAC THEN GEN_TAC THEN REWRITE_TAC[IMP_CONJ] THEN + MATCH_MP_TAC FINITE_INDUCT_STRONG THEN SIMP_TAC[VSUM_CLAUSES] THEN + SIMP_TAC[HOLOMORPHIC_ON_CONST; IN_INSERT; NOT_IN_EMPTY] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC HOLOMORPHIC_ON_ADD THEN + ASM_SIMP_TAC[ETA_AX]);; + +let HOLOMORPHIC_ON_COMPOSE_GEN = prove + (`!f g s t. f holomorphic_on s /\ g holomorphic_on t /\ + (!z. z IN s ==> f z IN t) + ==> g o f holomorphic_on s`, + REWRITE_TAC [holomorphic_on] THEN REPEAT STRIP_TAC THEN + SUBGOAL_THEN `IMAGE (f:complex->complex) s SUBSET t` MP_TAC THENL + [ASM SET_TAC []; ASM_MESON_TAC [HAS_COMPLEX_DERIVATIVE_WITHIN_SUBSET; + COMPLEX_DIFF_CHAIN_WITHIN]]);; + +(* ------------------------------------------------------------------------- *) +(* Same again for the actual derivative function. *) +(* ------------------------------------------------------------------------- *) + +let HAS_COMPLEX_DERIVATIVE_DERIVATIVE = prove + (`!f f' x. (f has_complex_derivative f') (at x) + ==> complex_derivative f x = f'`, + REWRITE_TAC[complex_derivative] THEN + MESON_TAC[COMPLEX_DERIVATIVE_UNIQUE_AT]);; + +let HAS_COMPLEX_DERIVATIVE_DIFFERENTIABLE = prove + (`!f x. (f has_complex_derivative (complex_derivative f x)) (at x) <=> + f complex_differentiable at x`, + REWRITE_TAC[complex_differentiable; complex_derivative] THEN MESON_TAC[]);; + +let COMPLEX_DIFFERENTIABLE_COMPOSE = prove + (`!f g z. f complex_differentiable at z /\ g complex_differentiable at (f z) + ==> (g o f) complex_differentiable at z`, + REWRITE_TAC [complex_differentiable] THEN + MESON_TAC [COMPLEX_DIFF_CHAIN_AT]);; + +let COMPLEX_DERIVATIVE_CHAIN = prove + (`!f g z. f complex_differentiable at z /\ g complex_differentiable at (f z) + ==> complex_derivative (g o f) z = + complex_derivative g (f z) * complex_derivative f z`, + MESON_TAC [HAS_COMPLEX_DERIVATIVE_DERIVATIVE; COMPLEX_DIFF_CHAIN_AT; + HAS_COMPLEX_DERIVATIVE_DIFFERENTIABLE]);; + +let COMPLEX_DERIVATIVE_LINEAR = prove + (`!c. complex_derivative (\w. c * w) = \z. c`, + REWRITE_TAC [FUN_EQ_THM] THEN REPEAT GEN_TAC THEN + MATCH_MP_TAC HAS_COMPLEX_DERIVATIVE_DERIVATIVE THEN + REWRITE_TAC [HAS_COMPLEX_DERIVATIVE_LINEAR]);; + +let COMPLEX_DERIVATIVE_ID = prove + (`complex_derivative (\w.w) = \z. Cx(&1)`, + REWRITE_TAC [FUN_EQ_THM] THEN + MESON_TAC [HAS_COMPLEX_DERIVATIVE_DERIVATIVE; HAS_COMPLEX_DERIVATIVE_ID]);; + +let COMPLEX_DERIVATIVE_CONST = prove + (`!c. complex_derivative (\w.c) = \z. Cx(&0)`, + REWRITE_TAC [FUN_EQ_THM] THEN + MESON_TAC [HAS_COMPLEX_DERIVATIVE_DERIVATIVE; + HAS_COMPLEX_DERIVATIVE_CONST]);; + +let COMPLEX_DERIVATIVE_ADD = prove + (`!f g z. f complex_differentiable at z /\ g complex_differentiable at z + ==> complex_derivative (\w. f w + g w) z = + complex_derivative f z + complex_derivative g z`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_COMPLEX_DERIVATIVE_DERIVATIVE THEN + ASM_SIMP_TAC [HAS_COMPLEX_DERIVATIVE_ADD; + HAS_COMPLEX_DERIVATIVE_DIFFERENTIABLE]);; + +let COMPLEX_DERIVATIVE_SUB = prove + (`!f g z. f complex_differentiable at z /\ g complex_differentiable at z + ==> complex_derivative (\w. f w - g w) z = + complex_derivative f z - complex_derivative g z`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_COMPLEX_DERIVATIVE_DERIVATIVE THEN + ASM_SIMP_TAC [HAS_COMPLEX_DERIVATIVE_SUB; + HAS_COMPLEX_DERIVATIVE_DIFFERENTIABLE]);; + +let COMPLEX_DERIVATIVE_MUL = prove + (`!f g z. f complex_differentiable at z /\ g complex_differentiable at z + ==> complex_derivative (\w. f w * g w) z = + f z * complex_derivative g z + complex_derivative f z * g z`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_COMPLEX_DERIVATIVE_DERIVATIVE THEN + ASM_SIMP_TAC [HAS_COMPLEX_DERIVATIVE_MUL_AT; + HAS_COMPLEX_DERIVATIVE_DIFFERENTIABLE]);; + +let COMPLEX_DERIVATIVE_LMUL = prove + (`!f c z. f complex_differentiable at z + ==> complex_derivative (\w. c * f w) z = + c * complex_derivative f z`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_COMPLEX_DERIVATIVE_DERIVATIVE THEN + ASM_SIMP_TAC [HAS_COMPLEX_DERIVATIVE_LMUL_AT; + HAS_COMPLEX_DERIVATIVE_DIFFERENTIABLE]);; + +let COMPLEX_DERIVATIVE_RMUL = prove + (`!f c z. f complex_differentiable at z + ==> complex_derivative (\w. f w * c) z = + complex_derivative f z * c`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_COMPLEX_DERIVATIVE_DERIVATIVE THEN + ASM_SIMP_TAC [HAS_COMPLEX_DERIVATIVE_RMUL_AT; + HAS_COMPLEX_DERIVATIVE_DIFFERENTIABLE]);; + +let COMPLEX_DERIVATIVE_TRANSFORM_WITHIN_OPEN = prove + (`!f g s z. open s /\ f holomorphic_on s /\ g holomorphic_on s /\ z IN s /\ + (!w. w IN s ==> f w = g w) + ==> complex_derivative f z = complex_derivative g z`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC COMPLEX_DERIVATIVE_UNIQUE_AT THEN + ASM_MESON_TAC[HAS_COMPLEX_DERIVATIVE_TRANSFORM_WITHIN_OPEN; + HOLOMORPHIC_ON_IMP_DIFFERENTIABLE_AT; + HAS_COMPLEX_DERIVATIVE_DIFFERENTIABLE]);; + +let COMPLEX_DERIVATIVE_COMPOSE_LINEAR = prove + (`!f c z. f complex_differentiable at (c * z) + ==> complex_derivative (\w. f (c * w)) z = + c * complex_derivative f (c * z)`, + SIMP_TAC + [COMPLEX_MUL_SYM; REWRITE_RULE [o_DEF; COMPLEX_DIFFERENTIABLE_ID; + COMPLEX_DIFFERENTIABLE_LINEAR; + COMPLEX_DERIVATIVE_LINEAR] + (SPECL [`\w:complex. c * w`] COMPLEX_DERIVATIVE_CHAIN)]);; + +(* ------------------------------------------------------------------------- *) +(* Caratheodory characterization. *) +(* ------------------------------------------------------------------------- *) + +let HAS_COMPLEX_DERIVATIVE_CARATHEODORY_AT = prove + (`!f f' z. + (f has_complex_derivative f') (at z) <=> + ?g. (!w. f(w) - f(z) = g(w) * (w - z)) /\ + g continuous at z /\ g(z) = f'`, + REPEAT GEN_TAC THEN + REWRITE_TAC[COMPLEX_RING `w' - z':complex = a <=> w' = z' + a`] THEN + SIMP_TAC[GSYM FUN_EQ_THM; HAS_COMPLEX_DERIVATIVE_AT; CONTINUOUS_AT] THEN + EQ_TAC THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THENL + [EXISTS_TAC `\w. if w = z then f':complex else (f(w) - f(z)) / (w - z)` THEN + ASM_SIMP_TAC[FUN_EQ_THM; COND_RAND; COND_RATOR; COMPLEX_SUB_REFL] THEN + CONV_TAC COMPLEX_FIELD; + FIRST_X_ASSUM SUBST_ALL_TAC THEN FIRST_X_ASSUM SUBST1_TAC THEN + ASM_SIMP_TAC[COMPLEX_RING `(z + a) - (z + b * (w - w)):complex = a`] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ_ALT] + LIM_TRANSFORM)) THEN + SIMP_TAC[LIM_CONST; COMPLEX_VEC_0; COMPLEX_FIELD + `~(w = z) ==> x - (x * (w - z)) / (w - z) = Cx(&0)`]]);; + +let HAS_COMPLEX_DERIVATIVE_CARATHEODORY_WITHIN = prove + (`!f f' z s. + (f has_complex_derivative f') (at z within s) <=> + ?g. (!w. f(w) - f(z) = g(w) * (w - z)) /\ + g continuous (at z within s) /\ g(z) = f'`, + REPEAT GEN_TAC THEN + REWRITE_TAC[COMPLEX_RING `w' - z':complex = a <=> w' = z' + a`] THEN + SIMP_TAC[GSYM FUN_EQ_THM; HAS_COMPLEX_DERIVATIVE_WITHIN; + CONTINUOUS_WITHIN] THEN + EQ_TAC THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THENL + [EXISTS_TAC `\w. if w = z then f':complex else (f(w) - f(z)) / (w - z)` THEN + ASM_SIMP_TAC[FUN_EQ_THM; COND_RAND; COND_RATOR; COMPLEX_SUB_REFL] THEN + CONV_TAC COMPLEX_FIELD; + FIRST_X_ASSUM SUBST_ALL_TAC THEN FIRST_X_ASSUM SUBST1_TAC THEN + ASM_SIMP_TAC[COMPLEX_RING `(z + a) - (z + b * (w - w)):complex = a`] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ_ALT] + LIM_TRANSFORM)) THEN + SIMP_TAC[LIM_CONST; COMPLEX_VEC_0; COMPLEX_FIELD + `~(w = z) ==> x - (x * (w - z)) / (w - z) = Cx(&0)`]]);; + +let COMPLEX_DIFFERENTIABLE_CARATHEODORY_AT = prove + (`!f z. f complex_differentiable at z <=> + ?g. (!w. f(w) - f(z) = g(w) * (w - z)) /\ g continuous at z`, + SIMP_TAC[complex_differentiable; HAS_COMPLEX_DERIVATIVE_CARATHEODORY_AT] THEN + MESON_TAC[]);; + +let COMPLEX_DIFFERENTIABLE_CARATHEODORY_WITHIN = prove + (`!f z s. + f complex_differentiable (at z within s) <=> + ?g. (!w. f(w) - f(z) = g(w) * (w - z)) /\ g continuous (at z within s)`, + SIMP_TAC[complex_differentiable; + HAS_COMPLEX_DERIVATIVE_CARATHEODORY_WITHIN] THEN + MESON_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* A slightly stronger, more traditional notion of analyticity on a set. *) +(* ------------------------------------------------------------------------- *) + +parse_as_infix ("analytic_on",(12,"right"));; + +let analytic_on = new_definition + `f analytic_on s <=> + !x. x IN s ==> ?e. &0 < e /\ f holomorphic_on ball(x,e)`;; + +let ANALYTIC_IMP_HOLOMORPHIC = prove + (`!f s. f analytic_on s ==> f holomorphic_on s`, + REWRITE_TAC[analytic_on; holomorphic_on] THEN + SIMP_TAC[HAS_COMPLEX_DERIVATIVE_WITHIN_OPEN; OPEN_BALL] THEN + MESON_TAC[HAS_COMPLEX_DERIVATIVE_AT_WITHIN; CENTRE_IN_BALL]);; + +let ANALYTIC_ON_OPEN = prove + (`!f s. open s ==> (f analytic_on s <=> f holomorphic_on s)`, + REPEAT STRIP_TAC THEN EQ_TAC THEN REWRITE_TAC[ANALYTIC_IMP_HOLOMORPHIC] THEN + REWRITE_TAC[analytic_on; holomorphic_on] THEN + ASM_SIMP_TAC[HAS_COMPLEX_DERIVATIVE_WITHIN_OPEN; OPEN_BALL] THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [OPEN_CONTAINS_BALL]) THEN + REWRITE_TAC[SUBSET] THEN MESON_TAC[CENTRE_IN_BALL]);; + +let ANALYTIC_ON_IMP_DIFFERENTIABLE_AT = prove + (`!f s x. f analytic_on s /\ x IN s ==> f complex_differentiable (at x)`, + SIMP_TAC[analytic_on; HOLOMORPHIC_ON_OPEN; OPEN_BALL; + complex_differentiable] THEN + MESON_TAC[CENTRE_IN_BALL]);; + +let ANALYTIC_ON_SUBSET = prove + (`!f s t. f analytic_on s /\ t SUBSET s ==> f analytic_on t`, + REWRITE_TAC[analytic_on; SUBSET] THEN MESON_TAC[]);; + +let ANALYTIC_ON_UNION = prove + (`!f s t. f analytic_on (s UNION t) <=> f analytic_on s /\ f analytic_on t`, + REWRITE_TAC [analytic_on; IN_UNION] THEN MESON_TAC[]);; + +let ANALYTIC_ON_UNIONS = prove + (`!f s. f analytic_on (UNIONS s) <=> (!t. t IN s ==> f analytic_on t)`, + REWRITE_TAC [analytic_on; IN_UNIONS] THEN MESON_TAC[]);; + +let ANALYTIC_ON_HOLOMORPHIC = prove + (`!f s. f analytic_on s <=> ?t. open t /\ s SUBSET t /\ f holomorphic_on t`, + REPEAT GEN_TAC THEN MATCH_MP_TAC EQ_TRANS THEN + EXISTS_TAC `?t. open t /\ s SUBSET t /\ f analytic_on t` THEN CONJ_TAC THENL + [EQ_TAC THENL + [DISCH_TAC THEN EXISTS_TAC `UNIONS {u | open u /\ f analytic_on u}` THEN + SIMP_TAC [IN_ELIM_THM; OPEN_UNIONS; ANALYTIC_ON_UNIONS] THEN + REWRITE_TAC [SUBSET; IN_UNIONS; IN_ELIM_THM] THEN + ASM_MESON_TAC [analytic_on; ANALYTIC_ON_OPEN; OPEN_BALL; CENTRE_IN_BALL]; + MESON_TAC [ANALYTIC_ON_SUBSET]]; + MESON_TAC [ANALYTIC_ON_OPEN]]);; + +let ANALYTIC_ON_LINEAR = prove + (`!s c. (\w. c * w) analytic_on s`, + REPEAT GEN_TAC THEN + REWRITE_TAC [ANALYTIC_ON_HOLOMORPHIC; HOLOMORPHIC_ON_LINEAR] THEN + EXISTS_TAC `(:complex)` THEN REWRITE_TAC [OPEN_UNIV; SUBSET_UNIV]);; + +let ANALYTIC_ON_CONST = prove + (`!c s. (\z. c) analytic_on s`, + REWRITE_TAC[analytic_on; HOLOMORPHIC_ON_CONST] THEN MESON_TAC[REAL_LT_01]);; + +let ANALYTIC_ON_ID = prove + (`!s. (\z. z) analytic_on s`, + REWRITE_TAC[analytic_on; HOLOMORPHIC_ON_ID] THEN MESON_TAC[REAL_LT_01]);; + +let ANALYTIC_ON_COMPOSE = prove + (`!f g s. f analytic_on s /\ g analytic_on (IMAGE f s) + ==> (g o f) analytic_on s`, + REWRITE_TAC[analytic_on; FORALL_IN_IMAGE] THEN REPEAT GEN_TAC THEN + DISCH_THEN(CONJUNCTS_THEN2 (LABEL_TAC "f") (LABEL_TAC "g")) THEN + X_GEN_TAC `z:complex` THEN DISCH_TAC THEN + REMOVE_THEN "f" (MP_TAC o SPEC `z:complex`) THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC) THEN + FIRST_ASSUM(MP_TAC o MATCH_MP HOLOMORPHIC_ON_IMP_CONTINUOUS_ON) THEN + SIMP_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_AT; OPEN_BALL] THEN + DISCH_THEN(MP_TAC o SPEC `z:complex`) THEN + ASM_REWRITE_TAC[CENTRE_IN_BALL; CONTINUOUS_AT_BALL] THEN + FIRST_X_ASSUM(MP_TAC o SPEC `z:complex`) THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `e:real` STRIP_ASSUME_TAC) THEN + DISCH_THEN(MP_TAC o SPEC `e:real`) THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `k:real` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `min (d:real) k` THEN ASM_REWRITE_TAC[REAL_LT_MIN] THEN + MATCH_MP_TAC HOLOMORPHIC_ON_COMPOSE THEN + CONJ_TAC THEN MATCH_MP_TAC HOLOMORPHIC_ON_SUBSET THENL + [EXISTS_TAC `ball(z:complex,d)`; + EXISTS_TAC `ball((f:complex->complex) z,e)`] THEN + ASM_REWRITE_TAC[BALL_MIN_INTER; INTER_SUBSET] THEN ASM SET_TAC[]);; + +let ANALYTIC_ON_COMPOSE_GEN = prove + (`!f g s t. f analytic_on s /\ g analytic_on t /\ (!z. z IN s ==> f z IN t) + ==> g o f analytic_on s`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC ANALYTIC_ON_COMPOSE THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC ANALYTIC_ON_SUBSET THEN ASM SET_TAC[]);; + +let ANALYTIC_ON_NEG = prove + (`!f s. f analytic_on s ==> (\z. --(f z)) analytic_on s`, + SIMP_TAC[analytic_on] THEN MESON_TAC[HOLOMORPHIC_ON_NEG]);; + +let ANALYTIC_ON_ADD = prove + (`!f g s. + f analytic_on s /\ g analytic_on s ==> (\z. f z + g z) analytic_on s`, + REPEAT GEN_TAC THEN REWRITE_TAC[analytic_on] THEN + REWRITE_TAC[AND_FORALL_THM] THEN MATCH_MP_TAC MONO_FORALL THEN + GEN_TAC THEN DISCH_THEN(fun th -> DISCH_TAC THEN MP_TAC th) THEN + ASM_REWRITE_TAC[] THEN DISCH_THEN(CONJUNCTS_THEN2 + (X_CHOOSE_TAC `d:real`) (X_CHOOSE_TAC `e:real`)) THEN + EXISTS_TAC `min (d:real) e` THEN + ASM_REWRITE_TAC[REAL_LT_MIN; BALL_MIN_INTER; IN_INTER] THEN + MATCH_MP_TAC HOLOMORPHIC_ON_ADD THEN + ASM_MESON_TAC[HOLOMORPHIC_ON_SUBSET; INTER_SUBSET]);; + +let ANALYTIC_ON_SUB = prove + (`!f g s. + f analytic_on s /\ g analytic_on s ==> (\z. f z - g z) analytic_on s`, + SIMP_TAC[complex_sub; ANALYTIC_ON_ADD; ANALYTIC_ON_NEG]);; + +let ANALYTIC_ON_MUL = prove + (`!f g s. + f analytic_on s /\ g analytic_on s ==> (\z. f z * g z) analytic_on s`, + REPEAT GEN_TAC THEN REWRITE_TAC[analytic_on] THEN + REWRITE_TAC[AND_FORALL_THM] THEN MATCH_MP_TAC MONO_FORALL THEN + GEN_TAC THEN DISCH_THEN(fun th -> DISCH_TAC THEN MP_TAC th) THEN + ASM_REWRITE_TAC[] THEN DISCH_THEN(CONJUNCTS_THEN2 + (X_CHOOSE_TAC `d:real`) (X_CHOOSE_TAC `e:real`)) THEN + EXISTS_TAC `min (d:real) e` THEN + ASM_REWRITE_TAC[REAL_LT_MIN; BALL_MIN_INTER; IN_INTER] THEN + MATCH_MP_TAC HOLOMORPHIC_ON_MUL THEN + ASM_MESON_TAC[HOLOMORPHIC_ON_SUBSET; INTER_SUBSET]);; + +let ANALYTIC_ON_INV = prove + (`!f s. f analytic_on s /\ (!z. z IN s ==> ~(f z = Cx(&0))) + ==> (\z. inv(f z)) analytic_on s`, + REPEAT STRIP_TAC THEN REWRITE_TAC[analytic_on] THEN + X_GEN_TAC `z:complex` THEN DISCH_TAC THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [analytic_on]) THEN + DISCH_THEN(MP_TAC o SPEC `z:complex`) THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN `?e. &0 < e /\ !y:complex. dist(z,y) < e ==> ~(f y = Cx(&0))` + MP_TAC THENL + [MATCH_MP_TAC CONTINUOUS_ON_OPEN_AVOID THEN + EXISTS_TAC `ball(z:complex,d)` THEN + ASM_SIMP_TAC[HOLOMORPHIC_ON_IMP_CONTINUOUS_ON; CENTRE_IN_BALL; OPEN_BALL]; + REWRITE_TAC[GSYM IN_BALL] THEN + DISCH_THEN(X_CHOOSE_THEN `e:real` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `min (d:real) e` THEN ASM_REWRITE_TAC[REAL_LT_MIN] THEN + MATCH_MP_TAC HOLOMORPHIC_ON_INV THEN + ASM_SIMP_TAC[BALL_MIN_INTER; IN_INTER] THEN + ASM_MESON_TAC[HOLOMORPHIC_ON_SUBSET; INTER_SUBSET]]);; + +let ANALYTIC_ON_DIV = prove + (`!f g s. + f analytic_on s /\ g analytic_on s /\ + (!z. z IN s ==> ~(g z = Cx(&0))) + ==> (\z. f z / g z) analytic_on s`, + SIMP_TAC[complex_div; ANALYTIC_ON_MUL; ANALYTIC_ON_INV]);; + +let ANALYTIC_ON_POW = prove + (`!f s n. f analytic_on s ==> (\z. (f z) pow n) analytic_on s`, + REWRITE_TAC[RIGHT_FORALL_IMP_THM] THEN REPEAT GEN_TAC THEN + DISCH_TAC THEN INDUCT_TAC THEN REWRITE_TAC[complex_pow] THEN + ASM_SIMP_TAC[ANALYTIC_ON_CONST; ANALYTIC_ON_MUL]);; + +let ANALYTIC_ON_VSUM = prove + (`!f s k. FINITE k /\ (!a. a IN k ==> (f a) analytic_on s) + ==> (\x. vsum k (\a. f a x)) analytic_on s`, + GEN_TAC THEN GEN_TAC THEN REWRITE_TAC[IMP_CONJ] THEN + MATCH_MP_TAC FINITE_INDUCT_STRONG THEN SIMP_TAC[VSUM_CLAUSES] THEN + SIMP_TAC[ANALYTIC_ON_CONST; IN_INSERT; NOT_IN_EMPTY] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC ANALYTIC_ON_ADD THEN + ASM_SIMP_TAC[ETA_AX]);; + +(* ------------------------------------------------------------------------- *) +(* The case of analyticity at a point. *) +(* ------------------------------------------------------------------------- *) + +let ANALYTIC_AT_BALL = prove + (`!f z. f analytic_on {z} <=> ?e. &0 ?s. open s /\ z IN s /\ f holomorphic_on s`, + REWRITE_TAC [ANALYTIC_ON_HOLOMORPHIC; SING_SUBSET]);; + +let ANALYTIC_ON_ANALYTIC_AT = prove + (`!f s. f analytic_on s <=> !z. z IN s ==> f analytic_on {z}`, + REWRITE_TAC [ANALYTIC_AT_BALL; analytic_on]);; + +let ANALYTIC_AT_TWO = prove + (`!f g z. f analytic_on {z} /\ g analytic_on {z} <=> + ?s. open s /\ z IN s /\ f holomorphic_on s /\ g holomorphic_on s`, + REWRITE_TAC [ANALYTIC_AT] THEN + MESON_TAC [HOLOMORPHIC_ON_SUBSET; OPEN_INTER; INTER_SUBSET; IN_INTER]);; + +let ANALYTIC_AT_ADD = prove + (`!f g z. f analytic_on {z} /\ g analytic_on {z} + ==> (\w. f w + g w) analytic_on {z}`, + REWRITE_TAC [ANALYTIC_AT_TWO] THEN REWRITE_TAC [ANALYTIC_AT] THEN + MESON_TAC [HOLOMORPHIC_ON_ADD]);; + +let ANALYTIC_AT_SUB = prove + (`!f g z. f analytic_on {z} /\ g analytic_on {z} + ==> (\w. f w - g w) analytic_on {z}`, + REWRITE_TAC [ANALYTIC_AT_TWO] THEN REWRITE_TAC [ANALYTIC_AT] THEN + MESON_TAC [HOLOMORPHIC_ON_SUB]);; + +let ANALYTIC_AT_MUL = prove + (`!f g z. f analytic_on {z} /\ g analytic_on {z} + + ==> (\w. f w * g w) analytic_on {z}`, + REWRITE_TAC [ANALYTIC_AT_TWO] THEN REWRITE_TAC [ANALYTIC_AT] THEN + MESON_TAC [HOLOMORPHIC_ON_MUL]);; + +let ANALYTIC_AT_POW = prove + (`!f n z. f analytic_on {z} + ==> (\w. f w pow n) analytic_on {z}`, + REWRITE_TAC [ANALYTIC_AT] THEN MESON_TAC [HOLOMORPHIC_ON_POW]);; + +(* ------------------------------------------------------------------------- *) +(* Combining theorems for derivative with analytic_at {z} hypotheses. *) +(* ------------------------------------------------------------------------- *) + +let COMPLEX_DERIVATIVE_ADD_AT = prove + (`!f g z. f analytic_on {z} /\ g analytic_on {z} + ==> complex_derivative (\w. f w + g w) z = + complex_derivative f z + complex_derivative g z`, + REWRITE_TAC [ANALYTIC_AT_TWO] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC COMPLEX_DERIVATIVE_ADD THEN + ASM_MESON_TAC [HOLOMORPHIC_ON_IMP_DIFFERENTIABLE_AT]);; + +let COMPLEX_DERIVATIVE_SUB_AT = prove + (`!f g z. f analytic_on {z} /\ g analytic_on {z} + ==> complex_derivative (\w. f w - g w) z = + complex_derivative f z - complex_derivative g z`, + REWRITE_TAC [ANALYTIC_AT_TWO] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC COMPLEX_DERIVATIVE_SUB THEN + ASM_MESON_TAC [HOLOMORPHIC_ON_IMP_DIFFERENTIABLE_AT]);; + +let COMPLEX_DERIVATIVE_MUL_AT = prove + (`!f g z. f analytic_on {z} /\ g analytic_on {z} + ==> complex_derivative (\w. f w * g w) z = + f z * complex_derivative g z + complex_derivative f z * g z`, + REWRITE_TAC [ANALYTIC_AT_TWO] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC COMPLEX_DERIVATIVE_MUL THEN + ASM_MESON_TAC [HOLOMORPHIC_ON_IMP_DIFFERENTIABLE_AT]);; + +let COMPLEX_DERIVATIVE_LMUL_AT = prove + (`!f c z. f analytic_on {z} + ==> complex_derivative (\w. c * f w) z = c * complex_derivative f z`, + REWRITE_TAC [ANALYTIC_AT] THEN + MESON_TAC [HOLOMORPHIC_ON_IMP_DIFFERENTIABLE_AT; COMPLEX_DERIVATIVE_LMUL]);; + +let COMPLEX_DERIVATIVE_RMUL_AT = prove + (`!f c z. f analytic_on {z} + ==> complex_derivative (\w. f w * c) z = complex_derivative f z * c`, + REWRITE_TAC [ANALYTIC_AT] THEN + MESON_TAC [HOLOMORPHIC_ON_IMP_DIFFERENTIABLE_AT; COMPLEX_DERIVATIVE_RMUL]);; + +(* ------------------------------------------------------------------------- *) +(* A composition lemma for functions of mixed type. *) +(* ------------------------------------------------------------------------- *) + +let HAS_VECTOR_DERIVATIVE_REAL_COMPLEX = prove + (`(f has_complex_derivative f') (at(Cx(drop a))) + ==> ((\x. f(Cx(drop x))) has_vector_derivative f') (at a)`, + REWRITE_TAC[has_complex_derivative; has_vector_derivative] THEN + REWRITE_TAC[COMPLEX_CMUL] THEN MP_TAC(ISPECL + [`\x. Cx(drop x)`; `f:complex->complex`; + `\x. Cx(drop x)`; `\x:complex. f' * x`; `a:real^1`] DIFF_CHAIN_AT) THEN + REWRITE_TAC[o_DEF; COMPLEX_MUL_SYM; IMP_CONJ] THEN + DISCH_THEN MATCH_MP_TAC THEN MATCH_MP_TAC HAS_DERIVATIVE_LINEAR THEN + REWRITE_TAC[linear; DROP_ADD; DROP_CMUL; CX_ADD; CX_MUL; COMPLEX_CMUL]);; + +(* ------------------------------------------------------------------------- *) +(* Complex differentiation of sequences and series. *) +(* ------------------------------------------------------------------------- *) + +let HAS_COMPLEX_DERIVATIVE_SEQUENCE = prove + (`!s f f' g'. + convex s /\ + (!n x. x IN s + ==> (f n has_complex_derivative f' n x) (at x within s)) /\ + (!e. &0 < e + ==> ?N. !n x. n >= N /\ x IN s ==> norm (f' n x - g' x) <= e) /\ + (?x l. x IN s /\ ((\n. f n x) --> l) sequentially) + ==> ?g. !x. x IN s + ==> ((\n. f n x) --> g x) sequentially /\ + (g has_complex_derivative g' x) (at x within s)`, + REWRITE_TAC[has_complex_derivative] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC HAS_DERIVATIVE_SEQUENCE THEN + EXISTS_TAC `\n x h:complex. (f':num->complex->complex) n x * h` THEN + ASM_SIMP_TAC[] THEN CONJ_TAC THENL [ALL_TAC; ASM_MESON_TAC[]] THEN + REWRITE_TAC[GSYM COMPLEX_SUB_RDISTRIB; COMPLEX_NORM_MUL] THEN + ASM_MESON_TAC[REAL_LE_RMUL; NORM_POS_LE]);; + +let HAS_COMPLEX_DERIVATIVE_SERIES = prove + (`!s f f' g' k. + convex s /\ + (!n x. x IN s + ==> (f n has_complex_derivative f' n x) (at x within s)) /\ + (!e. &0 < e + ==> ?N. !n x. n >= N /\ x IN s + ==> norm(vsum (k INTER (0..n)) (\i. f' i x) - g' x) + <= e) /\ + (?x l. x IN s /\ ((\n. f n x) sums l) k) + ==> ?g. !x. x IN s + ==> ((\n. f n x) sums g x) k /\ + (g has_complex_derivative g' x) (at x within s)`, + REWRITE_TAC[has_complex_derivative] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC HAS_DERIVATIVE_SERIES THEN + EXISTS_TAC `\n x h:complex. (f':num->complex->complex) n x * h` THEN + ASM_SIMP_TAC[] THEN CONJ_TAC THENL [ALL_TAC; ASM_MESON_TAC[]] THEN + SIMP_TAC[GSYM COMPLEX_SUB_RDISTRIB; VSUM_COMPLEX_RMUL; FINITE_NUMSEG; + FINITE_INTER; COMPLEX_NORM_MUL] THEN + ASM_MESON_TAC[REAL_LE_RMUL; NORM_POS_LE]);; + +(* ------------------------------------------------------------------------- *) +(* Bound theorem. *) +(* ------------------------------------------------------------------------- *) + +let COMPLEX_DIFFERENTIABLE_BOUND = prove + (`!f f' s B. + convex s /\ + (!x. x IN s ==> (f has_complex_derivative f'(x)) (at x within s) /\ + norm(f' x) <= B) + ==> !x y. x IN s /\ y IN s ==> norm(f x - f y) <= B * norm(x - y)`, + REPEAT GEN_TAC THEN REWRITE_TAC[has_complex_derivative] THEN + STRIP_TAC THEN MATCH_MP_TAC DIFFERENTIABLE_BOUND THEN + EXISTS_TAC `\x:complex h. f' x * h` THEN ASM_SIMP_TAC[] THEN + REPEAT STRIP_TAC THEN + MP_TAC(ISPEC `\h. (f':complex->complex) x * h` ONORM) THEN + REWRITE_TAC[LINEAR_COMPLEX_MUL] THEN + DISCH_THEN(MATCH_MP_TAC o CONJUNCT2) THEN + GEN_TAC THEN REWRITE_TAC[COMPLEX_NORM_MUL] THEN + ASM_MESON_TAC[REAL_LE_RMUL; NORM_POS_LE]);; + +(* ------------------------------------------------------------------------- *) +(* Inverse function theorem for complex derivatives. *) +(* ------------------------------------------------------------------------- *) + +let HAS_COMPLEX_DERIVATIVE_INVERSE_BASIC = prove + (`!f g f' t y. + (f has_complex_derivative f') (at (g y)) /\ + ~(f' = Cx(&0)) /\ + g continuous at y /\ + open t /\ + y IN t /\ + (!z. z IN t ==> f (g z) = z) + ==> (g has_complex_derivative inv(f')) (at y)`, + REWRITE_TAC[has_complex_derivative] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC HAS_DERIVATIVE_INVERSE_BASIC THEN + MAP_EVERY EXISTS_TAC + [`f:complex->complex`; `\x:complex. f' * x`; `t:complex->bool`] THEN + ASM_REWRITE_TAC[LINEAR_COMPLEX_MUL; FUN_EQ_THM; o_THM; I_THM] THEN + UNDISCH_TAC `~(f' = Cx(&0))` THEN CONV_TAC COMPLEX_FIELD);; + +let HAS_COMPLEX_DERIVATIVE_INVERSE_STRONG = prove + (`!f g f' s x. + open s /\ + x IN s /\ + f continuous_on s /\ + (!x. x IN s ==> g (f x) = x) /\ + (f has_complex_derivative f') (at x) /\ + ~(f' = Cx(&0)) + ==> (g has_complex_derivative inv(f')) (at (f x))`, + REWRITE_TAC[has_complex_derivative] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC HAS_DERIVATIVE_INVERSE_STRONG THEN + MAP_EVERY EXISTS_TAC [`\x:complex. f' * x`; `s:complex->bool`] THEN + ASM_REWRITE_TAC[] THEN ASM_SIMP_TAC[FUN_EQ_THM; o_THM; I_THM] THEN + UNDISCH_TAC `~(f' = Cx(&0))` THEN CONV_TAC COMPLEX_FIELD);; + +let HAS_COMPLEX_DERIVATIVE_INVERSE_STRONG_X = prove + (`!f g f' s y. + open s /\ (g y) IN s /\ f continuous_on s /\ + (!x. x IN s ==> (g(f(x)) = x)) /\ + (f has_complex_derivative f') (at (g y)) /\ ~(f' = Cx(&0)) /\ + f(g y) = y + ==> (g has_complex_derivative inv(f')) (at y)`, + REWRITE_TAC[has_complex_derivative] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC HAS_DERIVATIVE_INVERSE_STRONG_X THEN MAP_EVERY EXISTS_TAC + [`f:complex->complex`; `\x:complex. f' * x`; `s:complex->bool`] THEN + ASM_REWRITE_TAC[] THEN ASM_SIMP_TAC[FUN_EQ_THM; o_THM; I_THM] THEN + UNDISCH_TAC `~(f' = Cx(&0))` THEN CONV_TAC COMPLEX_FIELD);; + +(* ------------------------------------------------------------------------- *) +(* Cauchy-Riemann condition and relation to conformal. *) +(* ------------------------------------------------------------------------- *) + +let COMPLEX_BASIS = prove + (`basis 1 = Cx(&1) /\ basis 2 = ii`, + SIMP_TAC[CART_EQ; FORALL_2; BASIS_COMPONENT; DIMINDEX_2; ARITH] THEN + REWRITE_TAC[GSYM RE_DEF; GSYM IM_DEF; RE_CX; IM_CX] THEN + REWRITE_TAC[ii] THEN SIMPLE_COMPLEX_ARITH_TAC);; + +let COMPLEX_DIFFERENTIABLE_IMP_DIFFERENTIABLE = prove + (`!net f. f complex_differentiable net ==> f differentiable net`, + SIMP_TAC[complex_differentiable; differentiable; has_complex_derivative] THEN + MESON_TAC[]);; + +let CAUCHY_RIEMANN = prove + (`!f z. f complex_differentiable at z <=> + f differentiable at z /\ + (jacobian f (at z))$1$1 = (jacobian f (at z))$2$2 /\ + (jacobian f (at z))$1$2 = --((jacobian f (at z))$2$1)`, + REPEAT GEN_TAC THEN REWRITE_TAC[complex_differentiable] THEN EQ_TAC THENL + [REWRITE_TAC[has_complex_derivative] THEN + DISCH_THEN(X_CHOOSE_THEN `f':complex` ASSUME_TAC) THEN + CONJ_TAC THENL [ASM_MESON_TAC[differentiable]; ALL_TAC] THEN + REWRITE_TAC[jacobian] THEN + FIRST_ASSUM(SUBST1_TAC o SYM o MATCH_MP FRECHET_DERIVATIVE_AT) THEN + SIMP_TAC[matrix; LAMBDA_BETA; DIMINDEX_2; ARITH] THEN + REWRITE_TAC[COMPLEX_BASIS; GSYM RE_DEF; GSYM IM_DEF; ii] THEN + SIMPLE_COMPLEX_ARITH_TAC; + STRIP_TAC THEN EXISTS_TAC + `complex(jacobian (f:complex->complex) (at z)$1$1, + jacobian f (at z)$2$1)` THEN + REWRITE_TAC[has_complex_derivative] THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [JACOBIAN_WORKS]) THEN + MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_TERM_TAC THEN + ASM_SIMP_TAC[CART_EQ; matrix_vector_mul; DIMINDEX_2; SUM_2; ARITH; + FORALL_2; FUN_EQ_THM; LAMBDA_BETA] THEN + REWRITE_TAC[GSYM RE_DEF; GSYM IM_DEF; IM; RE; complex_mul] THEN + REAL_ARITH_TAC]);; + +let COMPLEX_DERIVATIVE_JACOBIAN = prove + (`!f z. + f complex_differentiable (at z) + ==> complex_derivative f z = + complex(jacobian f (at z)$1$1,jacobian f (at z)$2$1)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC COMPLEX_DERIVATIVE_UNIQUE_AT THEN + MAP_EVERY EXISTS_TAC [`f:complex->complex`; `z:complex`] THEN + ASM_REWRITE_TAC[HAS_COMPLEX_DERIVATIVE_DIFFERENTIABLE] THEN + REWRITE_TAC[has_complex_derivative] THEN + FIRST_ASSUM(STRIP_ASSUME_TAC o GEN_REWRITE_RULE I [CAUCHY_RIEMANN]) THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [JACOBIAN_WORKS]) THEN + MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_TERM_TAC THEN + ASM_SIMP_TAC[CART_EQ; matrix_vector_mul; DIMINDEX_2; SUM_2; ARITH; + FORALL_2; FUN_EQ_THM; LAMBDA_BETA] THEN + REWRITE_TAC[GSYM RE_DEF; GSYM IM_DEF; IM; RE; complex_mul] THEN + REAL_ARITH_TAC);; + +let COMPLEX_DIFFERENTIABLE_EQ_CONFORMAL = prove + (`!f z. + f complex_differentiable at z /\ ~(complex_derivative f z = Cx(&0)) <=> + f differentiable at z /\ + ?a. ~(a = &0) /\ rotation_matrix (a %% jacobian f (at z))`, + REPEAT GEN_TAC THEN EQ_TAC THENL + [DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + ASM_SIMP_TAC[COMPLEX_DIFFERENTIABLE_IMP_DIFFERENTIABLE; + COMPLEX_DERIVATIVE_JACOBIAN] THEN + REWRITE_TAC[GSYM COMPLEX_VEC_0; GSYM DOT_EQ_0] THEN + REWRITE_TAC[DOT_2; GSYM RE_DEF; GSYM IM_DEF; RE; IM; GSYM REAL_POW_2] THEN + REWRITE_TAC[RE_DEF; IM_DEF; ROTATION_MATRIX_2] THEN + RULE_ASSUM_TAC(REWRITE_RULE[CAUCHY_RIEMANN]) THEN + ASM_REWRITE_TAC[MATRIX_CMUL_COMPONENT] THEN DISCH_TAC THEN + REWRITE_TAC[REAL_MUL_RNEG; GSYM REAL_ADD_LDISTRIB; + REAL_ARITH `(a * x:real) pow 2 = a pow 2 * x pow 2`] THEN + EXISTS_TAC + `inv(sqrt(jacobian (f:complex->complex) (at z)$2$2 pow 2 + + jacobian f (at z)$2$1 pow 2))` THEN + MATCH_MP_TAC(REAL_FIELD + `x pow 2 = y /\ ~(y = &0) + ==> ~(inv x = &0) /\ inv(x) pow 2 * y = &1`) THEN + ASM_SIMP_TAC[SQRT_POW_2; REAL_LE_ADD; REAL_LE_POW_2]; + REWRITE_TAC[ROTATION_MATRIX_2; MATRIX_CMUL_COMPONENT] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + DISCH_THEN(X_CHOOSE_THEN `a:real` (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + ASM_REWRITE_TAC[GSYM REAL_MUL_RNEG; REAL_EQ_MUL_LCANCEL] THEN + STRIP_TAC THEN MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN + CONJ_TAC THENL [ASM_REWRITE_TAC[CAUCHY_RIEMANN]; DISCH_TAC] THEN + ASM_SIMP_TAC[COMPLEX_DERIVATIVE_JACOBIAN] THEN + REWRITE_TAC[GSYM COMPLEX_VEC_0; GSYM DOT_EQ_0] THEN + REWRITE_TAC[DOT_2; GSYM RE_DEF; GSYM IM_DEF; RE; IM; GSYM REAL_POW_2] THEN + FIRST_X_ASSUM(MP_TAC o MATCH_MP + (REAL_RING `(a * x) pow 2 + (a * y) pow 2 = &1 + ==> ~(x pow 2 + y pow 2 = &0)`)) THEN + ASM_REWRITE_TAC[RE_DEF; IM_DEF]]);; + +(* ------------------------------------------------------------------------- *) +(* Differentiation conversion. *) +(* ------------------------------------------------------------------------- *) + +let complex_differentiation_theorems = ref [];; + +let add_complex_differentiation_theorems = + let ETA_THM = prove + (`(f has_complex_derivative f') net <=> + ((\x. f x) has_complex_derivative f') net`, + REWRITE_TAC[ETA_AX]) in + let ETA_TWEAK = + PURE_REWRITE_RULE [IMP_CONJ] o + GEN_REWRITE_RULE (LAND_CONV o ONCE_DEPTH_CONV) [ETA_THM] o + SPEC_ALL in + fun l -> complex_differentiation_theorems := + !complex_differentiation_theorems @ map ETA_TWEAK l;; + +add_complex_differentiation_theorems + [HAS_COMPLEX_DERIVATIVE_LMUL_WITHIN; HAS_COMPLEX_DERIVATIVE_LMUL_AT; + HAS_COMPLEX_DERIVATIVE_RMUL_WITHIN; HAS_COMPLEX_DERIVATIVE_RMUL_AT; + HAS_COMPLEX_DERIVATIVE_CDIV_WITHIN; HAS_COMPLEX_DERIVATIVE_CDIV_AT; + HAS_COMPLEX_DERIVATIVE_ID; + HAS_COMPLEX_DERIVATIVE_CONST; + HAS_COMPLEX_DERIVATIVE_NEG; + HAS_COMPLEX_DERIVATIVE_ADD; + HAS_COMPLEX_DERIVATIVE_SUB; + HAS_COMPLEX_DERIVATIVE_MUL_WITHIN; HAS_COMPLEX_DERIVATIVE_MUL_AT; + HAS_COMPLEX_DERIVATIVE_DIV_WITHIN; HAS_COMPLEX_DERIVATIVE_DIV_AT; + HAS_COMPLEX_DERIVATIVE_POW_WITHIN; HAS_COMPLEX_DERIVATIVE_POW_AT; + HAS_COMPLEX_DERIVATIVE_INV_WITHIN; HAS_COMPLEX_DERIVATIVE_INV_AT];; + +let rec COMPLEX_DIFF_CONV = + let partfn tm = let l,r = dest_comb tm in mk_pair(lhand l,r) + and is_deriv = can (term_match [] `(f has_complex_derivative f') net`) in + let rec COMPLEX_DIFF_CONV tm = + try tryfind (fun th -> PART_MATCH partfn th (partfn tm)) + (!complex_differentiation_theorems) + with Failure _ -> + let ith = tryfind (fun th -> + PART_MATCH (partfn o repeat (snd o dest_imp)) th (partfn tm)) + (!complex_differentiation_theorems) in + COMPLEX_DIFF_ELIM ith + and COMPLEX_DIFF_ELIM th = + let tm = concl th in + if not(is_imp tm) then th else + let t = lhand tm in + if not(is_deriv t) then UNDISCH th + else COMPLEX_DIFF_ELIM (MATCH_MP th (COMPLEX_DIFF_CONV t)) in + COMPLEX_DIFF_CONV;; + +(* ------------------------------------------------------------------------- *) +(* Hence a tactic. *) +(* ------------------------------------------------------------------------- *) + +let COMPLEX_DIFF_TAC = + let pth = MESON[] + `(f has_complex_derivative f') net + ==> f' = g' + ==> (f has_complex_derivative g') net` in + W(fun (asl,w) -> let th = MATCH_MP pth (COMPLEX_DIFF_CONV w) in + MATCH_MP_TAC(repeat (GEN_REWRITE_RULE I [IMP_IMP]) (DISCH_ALL th)));; + +let COMPLEX_DIFFERENTIABLE_TAC = + let DISCH_FIRST th = DISCH (hd(hyp th)) th in + GEN_REWRITE_TAC I [complex_differentiable] THEN + W(fun (asl,w) -> + let th = COMPLEX_DIFF_CONV(snd(dest_exists w)) in + let f' = rand(rator(concl th)) in + EXISTS_TAC f' THEN + (if hyp th = [] then MATCH_ACCEPT_TAC th else + let th' = repeat (GEN_REWRITE_RULE I [IMP_IMP] o DISCH_FIRST) + (DISCH_FIRST th) in + MATCH_MP_TAC th'));; + +(* ------------------------------------------------------------------------- *) +(* A kind of complex Taylor theorem. *) +(* ------------------------------------------------------------------------- *) + +let COMPLEX_TAYLOR = prove + (`!f n s B. + convex s /\ + (!i x. x IN s /\ i <= n + ==> ((f i) has_complex_derivative f (i + 1) x) (at x within s)) /\ + (!x. x IN s ==> norm(f (n + 1) x) <= B) + ==> !w z. w IN s /\ z IN s + ==> norm(f 0 z - + vsum (0..n) (\i. f i w * (z - w) pow i / Cx(&(FACT i)))) + <= B * norm(z - w) pow (n + 1) / &(FACT n)`, + let lemma = prove + (`!f:num->real^N. + vsum (0..n) f = f 0 - f (n + 1) + vsum (0..n) (\i. f (i + 1))`, + REWRITE_TAC[GSYM(REWRITE_CONV[o_DEF] `(f:num->real^N) o (\i. i + 1)`)] THEN + ASM_SIMP_TAC[GSYM VSUM_IMAGE; EQ_ADD_RCANCEL; FINITE_NUMSEG] THEN + REWRITE_TAC[GSYM NUMSEG_OFFSET_IMAGE] THEN + SIMP_TAC[VSUM_CLAUSES_LEFT; LE_0] THEN + REWRITE_TAC[VSUM_CLAUSES_NUMSEG; GSYM ADD1] THEN + REWRITE_TAC[ARITH; ARITH_RULE `1 <= SUC n`] THEN VECTOR_ARITH_TAC) in + REPEAT STRIP_TAC THEN MP_TAC(SPECL + [`(\w. vsum (0..n) (\i. f i w * (z - w) pow i / Cx(&(FACT i))))`; + `\w. (f:num->complex->complex) (n + 1) w * + (z - w) pow n / Cx(&(FACT n))`; `segment[w:complex,z]`; + `B * norm(z - w:complex) pow n / &(FACT n)`] + COMPLEX_DIFFERENTIABLE_BOUND) THEN + ANTS_TAC THENL + [ASM_REWRITE_TAC[CONVEX_SEGMENT] THEN X_GEN_TAC `u:complex` THEN + DISCH_TAC THEN SUBGOAL_THEN `(u:complex) IN s` ASSUME_TAC THENL + [ASM_MESON_TAC[CONVEX_CONTAINS_SEGMENT; SUBSET]; ALL_TAC] THEN + CONJ_TAC THENL + [ALL_TAC; + REWRITE_TAC[COMPLEX_NORM_MUL; COMPLEX_NORM_DIV; COMPLEX_NORM_CX; + COMPLEX_NORM_POW; REAL_ABS_NUM] THEN + MATCH_MP_TAC REAL_LE_MUL2 THEN + ASM_SIMP_TAC[REAL_LE_DIV; NORM_POS_LE; REAL_POS; REAL_POW_LE] THEN + ASM_SIMP_TAC[REAL_LE_DIV2_EQ; REAL_OF_NUM_LT; FACT_LT] THEN + MATCH_MP_TAC REAL_POW_LE2 THEN REWRITE_TAC[NORM_POS_LE] THEN + ASM_MESON_TAC[SEGMENT_BOUND; NORM_SUB]] THEN + MATCH_MP_TAC HAS_COMPLEX_DERIVATIVE_WITHIN_SUBSET THEN + EXISTS_TAC `s:complex->bool` THEN CONJ_TAC THENL + [ALL_TAC; ASM_MESON_TAC[CONVEX_CONTAINS_SEGMENT]] THEN + SUBGOAL_THEN + `((\u. vsum (0..n) (\i. f i u * (z - u) pow i / Cx (&(FACT i)))) + has_complex_derivative + vsum (0..n) (\i. f i u * (-- Cx(&i) * (z - u) pow (i - 1)) / + Cx(&(FACT i)) + + f (i + 1) u * (z - u) pow i / Cx (&(FACT i)))) + (at u within s)` + MP_TAC THENL + [MATCH_MP_TAC HAS_COMPLEX_DERIVATIVE_VSUM THEN + REWRITE_TAC[FINITE_NUMSEG; IN_NUMSEG] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC HAS_COMPLEX_DERIVATIVE_MUL_WITHIN THEN + ASM_SIMP_TAC[ETA_AX] THEN W(MP_TAC o COMPLEX_DIFF_CONV o snd) THEN + MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_TERM_TAC THEN + REWRITE_TAC[complex_div] THEN CONV_TAC COMPLEX_RING; + ALL_TAC] THEN + ASM_SIMP_TAC[] THEN MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN + AP_TERM_TAC THEN REWRITE_TAC[VSUM_ADD_NUMSEG] THEN + GEN_REWRITE_TAC (LAND_CONV o LAND_CONV) [lemma] THEN + REWRITE_TAC[GSYM VSUM_ADD_NUMSEG; GSYM COMPLEX_ADD_ASSOC] THEN + REWRITE_TAC[ADD_SUB] THEN REWRITE_TAC[GSYM ADD1; FACT] THEN + REWRITE_TAC[GSYM REAL_OF_NUM_SUC; GSYM REAL_OF_NUM_MUL; CX_MUL] THEN + REWRITE_TAC[complex_div; COMPLEX_INV_MUL; GSYM COMPLEX_MUL_ASSOC] THEN + REWRITE_TAC[COMPLEX_RING + `--a * b * inv a * c:complex = --(a * inv a) * b * c`] THEN + SIMP_TAC[COMPLEX_MUL_RINV; CX_INJ; REAL_ARITH `~(&n + &1 = &0)`] THEN + REWRITE_TAC[COMPLEX_MUL_LNEG; COMPLEX_MUL_RNEG; COMPLEX_MUL_LID] THEN + REWRITE_TAC[COMPLEX_ADD_LINV; GSYM COMPLEX_VEC_0; VSUM_0] THEN + REWRITE_TAC[COMPLEX_VEC_0; COMPLEX_ADD_RID] THEN + REWRITE_TAC[COMPLEX_MUL_LZERO; COMPLEX_MUL_RZERO; COMPLEX_NEG_0] THEN + CONV_TAC COMPLEX_RING; + ALL_TAC] THEN + DISCH_THEN(MP_TAC o SPECL [`z:complex`; `w:complex`]) THEN ANTS_TAC THEN + ASM_REWRITE_TAC[ENDS_IN_SEGMENT] THEN MATCH_MP_TAC EQ_IMP THEN + BINOP_TAC THENL + [ALL_TAC; + REWRITE_TAC[REAL_POW_ADD; real_div; REAL_POW_1] THEN REAL_ARITH_TAC] THEN + AP_TERM_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN + SIMP_TAC[VSUM_CLAUSES_LEFT; LE_0; complex_pow; FACT; COMPLEX_DIV_1] THEN + REWRITE_TAC[SIMPLE_COMPLEX_ARITH `x * Cx(&1) + y = x <=> y = Cx(&0)`] THEN + REWRITE_TAC[GSYM COMPLEX_VEC_0] THEN MATCH_MP_TAC VSUM_EQ_0 THEN + INDUCT_TAC THEN + ASM_REWRITE_TAC[complex_pow; complex_div; COMPLEX_MUL_LZERO; + COMPLEX_MUL_RZERO; COMPLEX_SUB_REFL; COMPLEX_VEC_0] THEN + REWRITE_TAC[IN_NUMSEG] THEN ARITH_TAC);; + +(* ------------------------------------------------------------------------- *) +(* The simplest special case. *) +(* ------------------------------------------------------------------------- *) + +let COMPLEX_MVT = prove + (`!f f' s B. + convex s /\ + (!z. z IN s ==> (f has_complex_derivative f' z) (at z within s)) /\ + (!z. z IN s ==> norm (f' z) <= B) + ==> !w z. w IN s /\ z IN s ==> norm (f z - f w) <= B * norm (z - w)`, + REPEAT STRIP_TAC THEN + MP_TAC(SPECL [`(\n. if n = 0 then f else f'):num->complex->complex`; + `0`; `s:complex->bool`; `B:real`] COMPLEX_TAYLOR) THEN + SIMP_TAC[NUMSEG_SING; VSUM_SING; LE; ARITH] THEN + REWRITE_TAC[complex_pow; REAL_POW_1; FACT; REAL_DIV_1] THEN + ASM_SIMP_TAC[COMPLEX_DIV_1; COMPLEX_MUL_RID]);; + +(* ------------------------------------------------------------------------- *) +(* Something more like the traditional MVT for real components. *) +(* Could, perhaps should, sharpen this to derivatives inside the segment. *) +(* ------------------------------------------------------------------------- *) + +let COMPLEX_MVT_LINE = prove + (`!f f' w z. + (!u. u IN segment[w,z] + ==> (f has_complex_derivative f'(u)) (at u)) + ==> ?u. u IN segment[w,z] /\ Re(f z) - Re(f w) = Re(f'(u) * (z - w))`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL + [`(lift o Re) o (f:complex->complex) o + (\t. (&1 - drop t) % w + drop t % z)`; + `\u. (lift o Re) o + (\h. (f':complex->complex)((&1 - drop u) % w + drop u % z) * h) o + (\t. drop t % (z - w))`; + `vec 0:real^1`; `vec 1:real^1`] + MVT_VERY_SIMPLE) THEN + ANTS_TAC THENL + [REWRITE_TAC[DROP_VEC; REAL_POS] THEN + X_GEN_TAC `t:real^1` THEN STRIP_TAC THEN + MATCH_MP_TAC HAS_DERIVATIVE_AT_WITHIN THEN + MATCH_MP_TAC DIFF_CHAIN_AT THEN CONJ_TAC THENL + [ALL_TAC; + MATCH_MP_TAC HAS_DERIVATIVE_LINEAR THEN + REWRITE_TAC[linear; LIFT_ADD; RE_ADD; LIFT_CMUL; RE_CMUL; o_DEF]] THEN + MATCH_MP_TAC DIFF_CHAIN_AT THEN CONJ_TAC THENL + [REWRITE_TAC[VECTOR_ARITH `(&1 - t) % w + t % z = w + t % (z - w)`] THEN + GEN_REWRITE_TAC (RATOR_CONV o RAND_CONV o ABS_CONV) + [GSYM VECTOR_ADD_LID] THEN + MATCH_MP_TAC HAS_DERIVATIVE_ADD THEN + REWRITE_TAC[HAS_DERIVATIVE_CONST] THEN + MATCH_MP_TAC HAS_DERIVATIVE_LINEAR THEN + REWRITE_TAC[linear; DROP_ADD; DROP_CMUL] THEN + CONJ_TAC THEN VECTOR_ARITH_TAC; + ALL_TAC] THEN + REWRITE_TAC[GSYM has_complex_derivative] THEN + FIRST_X_ASSUM MATCH_MP_TAC; + REWRITE_TAC[o_THM; GSYM LIFT_SUB; LIFT_EQ; DROP_VEC; VECTOR_SUB_RZERO] THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN + REWRITE_TAC[VECTOR_MUL_LID; VECTOR_MUL_LZERO] THEN + REWRITE_TAC[VECTOR_ADD_LID; VECTOR_ADD_RID] THEN + DISCH_THEN(X_CHOOSE_THEN `t:real^1` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `(&1 - drop t) % w + drop t % z:complex`] THEN + ASM_REWRITE_TAC[segment; IN_ELIM_THM] THEN + EXISTS_TAC `drop t` THEN ASM_REWRITE_TAC[] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_INTERVAL_1]) THEN + REWRITE_TAC[DROP_VEC]);; + +let COMPLEX_TAYLOR_MVT = prove + (`!f w z n. + (!i x. x IN segment[w,z] /\ i <= n + ==> ((f i) has_complex_derivative f (i + 1) x) (at x)) + ==> ?u. u IN segment[w,z] /\ + Re(f 0 z) = + Re(vsum (0..n) (\i. f i w * (z - w) pow i / Cx(&(FACT i))) + + (f (n + 1) u * (z - u) pow n / Cx (&(FACT n))) * (z - w))`, + let lemma = prove + (`!f:num->real^N. + vsum (0..n) f = f 0 - f (n + 1) + vsum (0..n) (\i. f (i + 1))`, + REWRITE_TAC[GSYM(REWRITE_CONV[o_DEF] `(f:num->real^N) o (\i. i + 1)`)] THEN + ASM_SIMP_TAC[GSYM VSUM_IMAGE; EQ_ADD_RCANCEL; FINITE_NUMSEG] THEN + REWRITE_TAC[GSYM NUMSEG_OFFSET_IMAGE] THEN + SIMP_TAC[VSUM_CLAUSES_LEFT; LE_0] THEN + REWRITE_TAC[VSUM_CLAUSES_NUMSEG; GSYM ADD1] THEN + REWRITE_TAC[ARITH; ARITH_RULE `1 <= SUC n`] THEN VECTOR_ARITH_TAC) in + REPEAT STRIP_TAC THEN MP_TAC(SPECL + [`(\w. vsum (0..n) (\i. f i w * (z - w) pow i / Cx(&(FACT i))))`; + `\w. (f:num->complex->complex) (n + 1) w * + (z - w) pow n / Cx(&(FACT n))`; + `w:complex`; `z:complex`] + COMPLEX_MVT_LINE) THEN + ANTS_TAC THENL + [ASM_REWRITE_TAC[CONVEX_SEGMENT] THEN X_GEN_TAC `u:complex` THEN + DISCH_TAC THEN + SUBGOAL_THEN + `((\u. vsum (0..n) (\i. f i u * (z - u) pow i / Cx (&(FACT i)))) + has_complex_derivative + vsum (0..n) (\i. f i u * (-- Cx(&i) * (z - u) pow (i - 1)) / + Cx(&(FACT i)) + + f (i + 1) u * (z - u) pow i / Cx (&(FACT i)))) + (at u)` + MP_TAC THENL + [MATCH_MP_TAC HAS_COMPLEX_DERIVATIVE_VSUM THEN + REWRITE_TAC[FINITE_NUMSEG; IN_NUMSEG] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC HAS_COMPLEX_DERIVATIVE_MUL_AT THEN + ASM_SIMP_TAC[ETA_AX] THEN W(MP_TAC o COMPLEX_DIFF_CONV o snd) THEN + MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_TERM_TAC THEN + REWRITE_TAC[complex_div] THEN CONV_TAC COMPLEX_RING; + ALL_TAC] THEN + ASM_SIMP_TAC[] THEN MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN + AP_TERM_TAC THEN REWRITE_TAC[VSUM_ADD_NUMSEG] THEN + GEN_REWRITE_TAC (LAND_CONV o LAND_CONV) [lemma] THEN + REWRITE_TAC[GSYM VSUM_ADD_NUMSEG; GSYM COMPLEX_ADD_ASSOC] THEN + REWRITE_TAC[ADD_SUB] THEN REWRITE_TAC[GSYM ADD1; FACT] THEN + REWRITE_TAC[GSYM REAL_OF_NUM_SUC; GSYM REAL_OF_NUM_MUL; CX_MUL] THEN + REWRITE_TAC[complex_div; COMPLEX_INV_MUL; GSYM COMPLEX_MUL_ASSOC] THEN + REWRITE_TAC[COMPLEX_RING + `--a * b * inv a * c:complex = --(a * inv a) * b * c`] THEN + SIMP_TAC[COMPLEX_MUL_RINV; CX_INJ; REAL_ARITH `~(&n + &1 = &0)`] THEN + REWRITE_TAC[COMPLEX_MUL_LNEG; COMPLEX_MUL_RNEG; COMPLEX_MUL_LID] THEN + REWRITE_TAC[COMPLEX_ADD_LINV; GSYM COMPLEX_VEC_0; VSUM_0] THEN + REWRITE_TAC[COMPLEX_VEC_0; COMPLEX_ADD_RID] THEN + REWRITE_TAC[COMPLEX_MUL_LZERO; COMPLEX_MUL_RZERO; COMPLEX_NEG_0] THEN + CONV_TAC COMPLEX_RING; + ALL_TAC] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `u:complex` THEN + MATCH_MP_TAC MONO_AND THEN REWRITE_TAC[RE_ADD] THEN + REWRITE_TAC[ONCE_REWRITE_RULE[REAL_ADD_SYM] REAL_EQ_SUB_RADD] THEN + DISCH_THEN(SUBST1_TAC o SYM) THEN + SIMP_TAC[VSUM_CLAUSES_LEFT; LE_0; complex_pow; FACT; COMPLEX_DIV_1] THEN + REWRITE_TAC[COMPLEX_MUL_RID; RE_ADD] THEN + MATCH_MP_TAC(REAL_ARITH `Re x = &0 ==> y = y + Re x`) THEN + SIMP_TAC[RE_VSUM; FINITE_NUMSEG] THEN + MATCH_MP_TAC SUM_EQ_0_NUMSEG THEN + INDUCT_TAC THEN REWRITE_TAC[ARITH] THEN + REWRITE_TAC[COMPLEX_SUB_REFL; complex_pow; complex_div] THEN + REWRITE_TAC[COMPLEX_MUL_LZERO; COMPLEX_MUL_RZERO; RE_CX]);; + +(* ------------------------------------------------------------------------- *) +(* Further useful properties of complex conjugation. *) +(* ------------------------------------------------------------------------- *) + +let LIM_CNJ = prove + (`!net f l. ((\x. cnj(f x)) --> cnj l) net <=> (f --> l) net`, + REWRITE_TAC[LIM; dist; GSYM CNJ_SUB; COMPLEX_NORM_CNJ]);; + +let SUMS_CNJ = prove + (`!net f l. ((\x. cnj(f x)) sums cnj l) net <=> (f sums l) net`, + SIMP_TAC[sums; LIM_CNJ; GSYM CNJ_VSUM; FINITE_INTER_NUMSEG]);; + +let CONTINUOUS_WITHIN_CNJ = prove + (`!s z. cnj continuous (at z within s)`, + SIMP_TAC[LINEAR_CONTINUOUS_WITHIN; LINEAR_CNJ]);; + +let CONTINUOUS_AT_CNJ = prove + (`!z. cnj continuous (at z)`, + SIMP_TAC[LINEAR_CONTINUOUS_AT; LINEAR_CNJ]);; + +let CONTINUOUS_ON_CNJ = prove + (`!s. cnj continuous_on s`, + SIMP_TAC[LINEAR_CONTINUOUS_ON; LINEAR_CNJ]);; + +(* ------------------------------------------------------------------------- *) +(* Some limit theorems about real part of real series etc. *) +(* ------------------------------------------------------------------------- *) + +let REAL_LIM = prove + (`!net:(A)net f l. + (f --> l) net /\ ~(trivial_limit net) /\ + (?b. (?a. netord net a b) /\ !a. netord net a b ==> real(f a)) + ==> real l`, + REWRITE_TAC[IM_DEF; real] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC LIM_COMPONENT_EQ THEN + REWRITE_TAC[eventually; DIMINDEX_2; ARITH] THEN ASM_MESON_TAC[]);; + +let REAL_LIM_SEQUENTIALLY = prove + (`!f l. (f --> l) sequentially /\ (?N. !n. n >= N ==> real(f n)) + ==> real l`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC(ISPEC `sequentially` REAL_LIM) THEN + REWRITE_TAC[SEQUENTIALLY; TRIVIAL_LIMIT_SEQUENTIALLY] THEN + ASM_MESON_TAC[GE_REFL]);; + +let REAL_SERIES = prove + (`!f l s. (f sums l) s /\ (!n. real(f n)) ==> real l`, + REWRITE_TAC[sums] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC REAL_LIM_SEQUENTIALLY THEN + EXISTS_TAC `\n. vsum(s INTER (0..n)) f :complex` THEN + ASM_SIMP_TAC[REAL_VSUM; FINITE_INTER; FINITE_NUMSEG]);; + +(* ------------------------------------------------------------------------- *) +(* Often convenient to use comparison with real limit of complex type. *) +(* ------------------------------------------------------------------------- *) + +let LIM_NULL_COMPARISON_COMPLEX = prove + (`!net:(A)net f g. + eventually (\x. norm(f x) <= norm(g x)) net /\ + (g --> Cx(&0)) net + ==> (f --> Cx(&0)) net`, + REWRITE_TAC[GSYM COMPLEX_VEC_0] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC(ISPEC `net:(A)net` LIM_NULL_COMPARISON) THEN + EXISTS_TAC `norm o (g:A->complex)` THEN + ASM_REWRITE_TAC[o_THM; GSYM LIM_NULL_NORM]);; + +let LIM_NULL_COMPARISON_COMPLEX_RE = prove + (`!net:(A)net f g. + eventually (\x. norm(f x) <= Re(g x)) net /\ + (g --> Cx(&0)) net + ==> (f --> Cx(&0)) net`, + REPEAT STRIP_TAC THEN + MATCH_MP_TAC(ISPEC `net:(A)net` LIM_NULL_COMPARISON_COMPLEX) THEN + EXISTS_TAC `g:A->complex` THEN ASM_REWRITE_TAC[] THEN + FIRST_ASSUM(MATCH_MP_TAC o MATCH_MP + (REWRITE_RULE[IMP_CONJ_ALT] EVENTUALLY_MONO)) THEN + REWRITE_TAC[] THEN + MESON_TAC[COMPLEX_NORM_GE_RE_IM; REAL_ABS_LE; REAL_LE_TRANS]);; + +let SERIES_COMPARISON_COMPLEX = prove + (`!f:num->real^N g s. + summable s g /\ + (!n. n IN s ==> real(g n) /\ &0 <= Re(g n)) /\ + (?N. !n. n >= N /\ n IN s ==> norm(f n) <= norm(g n)) + ==> summable s f`, + REPEAT GEN_TAC THEN REWRITE_TAC[summable] THEN + DISCH_THEN(REPEAT_TCL CONJUNCTS_THEN ASSUME_TAC) THEN + MATCH_MP_TAC SERIES_COMPARISON THEN + EXISTS_TAC `\n. norm((g:num->complex) n)` THEN ASM_REWRITE_TAC[] THEN + FIRST_X_ASSUM(X_CHOOSE_THEN `l:complex` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `lift(Re l)` THEN MATCH_MP_TAC SUMS_EQ THEN + EXISTS_TAC `\i:num. lift(Re(g i))` THEN + ASM_SIMP_TAC[REAL_NORM_POS; o_DEF] THEN + REWRITE_TAC[RE_DEF] THEN MATCH_MP_TAC SERIES_COMPONENT THEN + ASM_REWRITE_TAC[DIMINDEX_2; ARITH]);; + +let SERIES_COMPARISON_UNIFORM_COMPLEX = prove + (`!f:A->num->real^N g P s. + summable s g /\ + (!n. n IN s ==> real(g n) /\ &0 <= Re(g n)) /\ + (?N. !n x. N <= n /\ n IN s /\ P x ==> norm(f x n) <= norm(g n)) + ==> ?l. !e. &0 < e + ==> ?N. !n x. N <= n /\ P x + ==> dist(vsum(s INTER (0..n)) (f x),l x) < + e`, + REPEAT GEN_TAC THEN REWRITE_TAC[summable] THEN + DISCH_THEN(REPEAT_TCL CONJUNCTS_THEN ASSUME_TAC) THEN + MATCH_MP_TAC SERIES_COMPARISON_UNIFORM THEN + EXISTS_TAC `\n. norm((g:num->complex) n)` THEN ASM_REWRITE_TAC[] THEN + FIRST_X_ASSUM(X_CHOOSE_THEN `l:complex` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `lift(Re l)` THEN MATCH_MP_TAC SUMS_EQ THEN + EXISTS_TAC `\i:num. lift(Re(g i))` THEN + ASM_SIMP_TAC[REAL_NORM_POS; o_DEF] THEN + REWRITE_TAC[RE_DEF] THEN MATCH_MP_TAC SERIES_COMPONENT THEN + ASM_REWRITE_TAC[DIMINDEX_2; ARITH]);; + +let SUMMABLE_SUBSET_COMPLEX = prove + (`!x s t. (!n. n IN s ==> real(x n) /\ &0 <= Re(x n)) /\ + summable s x /\ t SUBSET s + ==> summable t x`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC SUMMABLE_SUBSET THEN + EXISTS_TAC `s:num->bool` THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC SERIES_COMPARISON_COMPLEX THEN + EXISTS_TAC `x:num->complex` THEN ASM_REWRITE_TAC[] THEN + MESON_TAC[REAL_LE_REFL; NORM_0; NORM_POS_LE]);; + +let SERIES_ABSCONV_IMP_CONV = prove + (`!x:num->real^N k. summable k (\n. Cx(norm(x n))) ==> summable k x`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC SERIES_COMPARISON_COMPLEX THEN + EXISTS_TAC `\n:num. Cx(norm(x n:real^N))` THEN + ASM_REWRITE_TAC[REAL_CX; RE_CX; NORM_POS_LE; COMPLEX_NORM_CX] THEN + REWRITE_TAC[REAL_ABS_NORM; REAL_LE_REFL]);; + +(* ------------------------------------------------------------------------- *) +(* Complex-valued geometric series. *) +(* ------------------------------------------------------------------------- *) + +let SUMS_GP = prove + (`!n z. norm(z) < &1 + ==> ((\k. z pow k) sums (z pow n / (Cx(&1) - z))) (from n)`, + REPEAT STRIP_TAC THEN REWRITE_TAC[SERIES_FROM; VSUM_GP] THEN + ASM_CASES_TAC `z = Cx(&1)` THENL + [ASM_MESON_TAC[COMPLEX_NORM_NUM; REAL_LT_REFL]; ALL_TAC] THEN + MATCH_MP_TAC LIM_TRANSFORM_EVENTUALLY THEN + EXISTS_TAC `\m. (z pow n - z pow SUC m) / (Cx (&1) - z)` THEN CONJ_TAC THENL + [ASM_REWRITE_TAC[EVENTUALLY_SEQUENTIALLY] THEN + EXISTS_TAC `n:num` THEN SIMP_TAC[GSYM NOT_LE]; + MATCH_MP_TAC LIM_COMPLEX_DIV THEN + ASM_REWRITE_TAC[COMPLEX_SUB_0; LIM_CONST] THEN + GEN_REWRITE_TAC (RATOR_CONV o RAND_CONV) [GSYM COMPLEX_SUB_RZERO] THEN + MATCH_MP_TAC LIM_SUB THEN REWRITE_TAC[LIM_CONST] THEN + REWRITE_TAC[LIM_SEQUENTIALLY; GSYM COMPLEX_VEC_0] THEN + REWRITE_TAC[NORM_ARITH `dist(x,vec 0) = norm x`] THEN + X_GEN_TAC `e:real` THEN DISCH_TAC THEN + MP_TAC(SPECL [`norm(z:complex)`; `e:real`] REAL_ARCH_POW_INV) THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC MONO_EXISTS THEN + X_GEN_TAC `n:num` THEN DISCH_TAC THEN X_GEN_TAC `m:num` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH + `x < e ==> y <= x ==> y < e`)) THEN + REWRITE_TAC[COMPLEX_NORM_POW] THEN MATCH_MP_TAC REAL_POW_MONO_INV THEN + ASM_SIMP_TAC[NORM_POS_LE; REAL_LT_IMP_LE] THEN + UNDISCH_TAC `n:num <= m` THEN ARITH_TAC]);; + +let SUMMABLE_GP = prove + (`!z k. norm(z) < &1 ==> summable k (\n. z pow n)`, + REPEAT STRIP_TAC THEN + MATCH_MP_TAC SUMMABLE_SUBSET THEN EXISTS_TAC `(:num)` THEN + REWRITE_TAC[SUBSET_UNIV] THEN + MATCH_MP_TAC SERIES_COMPARISON_COMPLEX THEN + EXISTS_TAC `\n. Cx(norm(z:complex) pow n)` THEN + REWRITE_TAC[REAL_CX; RE_CX; COMPLEX_NORM_CX] THEN + SIMP_TAC[REAL_POW_LE; NORM_POS_LE] THEN CONJ_TAC THENL + [REWRITE_TAC[summable; GSYM FROM_0; CX_POW] THEN + EXISTS_TAC `Cx(norm z) pow 0 / (Cx(&1) - Cx(norm(z:complex)))` THEN + MATCH_MP_TAC SUMS_GP THEN + ASM_REWRITE_TAC[COMPLEX_NORM_CX; REAL_ABS_NORM]; + EXISTS_TAC `0` THEN REPEAT STRIP_TAC THEN + COND_CASES_TAC THEN + ASM_SIMP_TAC[REAL_ABS_POW; REAL_ABS_NORM; REAL_LE_REFL; NORM_POS_LE; + COMPLEX_NORM_POW; NORM_0; REAL_ABS_POS; REAL_POW_LE]]);; + +(* ------------------------------------------------------------------------- *) +(* Complex version (the usual one) of Dirichlet convergence test. *) +(* ------------------------------------------------------------------------- *) + +let SERIES_DIRICHLET_COMPLEX_GEN = prove + (`!f g N k m p l. + bounded {vsum (m..n) f | n IN (:num)} /\ + summable (from p) (\n. Cx(norm(g(n + 1) - g(n)))) /\ + ((\n. vsum(1..n) f * g(n + 1)) --> l) sequentially + ==> summable (from k) (\n. f(n) * g(n))`, + REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[COMPLEX_MUL_SYM] THEN + MATCH_MP_TAC SERIES_DIRICHLET_BILINEAR THEN + MAP_EVERY EXISTS_TAC [`m:num`; `p:num`; `l:complex`] THEN + ASM_REWRITE_TAC[BILINEAR_COMPLEX_MUL] THEN + ONCE_REWRITE_TAC[COMPLEX_MUL_SYM] THEN ASM_REWRITE_TAC[] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [summable]) THEN + REWRITE_TAC[summable; SERIES_CAUCHY] THEN + SIMP_TAC[GSYM(REWRITE_RULE[o_DEF] LIFT_SUM); FINITE_NUMSEG; FINITE_INTER; + VSUM_CX; NORM_LIFT; COMPLEX_NORM_CX]);; + +let SERIES_DIRICHLET_COMPLEX = prove + (`!f g N k m. + bounded {vsum (m..n) f | n IN (:num)} /\ + (!n. real(g n)) /\ + (!n. N <= n ==> Re(g(n + 1)) <= Re(g n)) /\ + (g --> Cx(&0)) sequentially + ==> summable (from k) (\n. f(n) * g(n))`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`f:num->complex`; `\n:num. Re(g n)`; `N:num`; `k:num`; + `m:num`] SERIES_DIRICHLET) THEN + ASM_REWRITE_TAC[] THEN ANTS_TAC THENL + [FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [LIM_SEQUENTIALLY]) THEN + REWRITE_TAC[LIM_SEQUENTIALLY; o_THM; dist; VECTOR_SUB_RZERO] THEN + REWRITE_TAC[COMPLEX_SUB_RZERO; NORM_LIFT] THEN + MESON_TAC[COMPLEX_NORM_GE_RE_IM; REAL_LET_TRANS]; + MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN + REWRITE_TAC[COMPLEX_CMUL; FUN_EQ_THM] THEN + ASM_MESON_TAC[REAL; COMPLEX_MUL_SYM]]);; + +(* ------------------------------------------------------------------------- *) +(* Versions with explicit bounds are sometimes useful. *) +(* ------------------------------------------------------------------------- *) + +let SERIES_DIRICHLET_COMPLEX_VERY_EXPLICIT = prove + (`!f g B p. + &0 < B /\ 1 <= p /\ + (!m n. p <= m ==> norm(vsum(m..n) f) <= B) /\ + (!n. p <= n ==> real(g n) /\ &0 <= Re(g n)) /\ + (!n. p <= n ==> Re(g(n + 1)) <= Re(g n)) + ==> !m n. p <= m + ==> norm(vsum(m..n) (\k. f k * g k)) <= &2 * B * norm(g m)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC + `norm(vsum(m..n) (\k. (vsum(p..k) f - vsum(p..(k-1)) f) * g k))` THEN + CONJ_TAC THENL + [MATCH_MP_TAC REAL_EQ_IMP_LE THEN AP_TERM_TAC THEN + MATCH_MP_TAC VSUM_EQ_NUMSEG THEN X_GEN_TAC `k:num` THEN STRIP_TAC THEN + REWRITE_TAC[] THEN AP_THM_TAC THEN AP_TERM_TAC THEN + SUBGOAL_THEN `p:num <= k` + (fun th -> SIMP_TAC[GSYM(MATCH_MP NUMSEG_RREC th)]) + THENL [ASM_ARITH_TAC; ALL_TAC] THEN + SIMP_TAC[VSUM_CLAUSES; FINITE_NUMSEG; IN_NUMSEG] THEN + COND_CASES_TAC THENL [ASM_ARITH_TAC; VECTOR_ARITH_TAC]; + ALL_TAC] THEN + ONCE_REWRITE_TAC[COMPLEX_MUL_SYM] THEN + REWRITE_TAC[MATCH_MP BILINEAR_VSUM_PARTIAL_PRE BILINEAR_COMPLEX_MUL] THEN + COND_CASES_TAC THEN + ASM_SIMP_TAC[NORM_0; REAL_LE_MUL; REAL_POS; REAL_LT_IMP_LE; NORM_POS_LE] THEN + MATCH_MP_TAC(NORM_ARITH + `norm(c) <= e - norm(a) - norm(b) ==> norm(a - b - c) <= e`) THEN + MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `sum (m..n) (\k. norm(g(k + 1) - g(k)) * B)` THEN CONJ_TAC THENL + [MATCH_MP_TAC VSUM_NORM_LE THEN REWRITE_TAC[IN_NUMSEG; FINITE_NUMSEG] THEN + X_GEN_TAC `k:num` THEN STRIP_TAC THEN REWRITE_TAC[COMPLEX_NORM_MUL] THEN + MATCH_MP_TAC REAL_LE_MUL2 THEN + ASM_SIMP_TAC[REAL_LE_REFL; LE_REFL; NORM_POS_LE]; + ALL_TAC] THEN + MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `sum(m..n) (\k. Re(g(k)) - Re(g(k + 1))) * B` THEN CONJ_TAC THENL + [ASM_SIMP_TAC[SUM_RMUL; REAL_LE_RMUL_EQ] THEN + MATCH_MP_TAC REAL_EQ_IMP_LE THEN MATCH_MP_TAC SUM_EQ_NUMSEG THEN + X_GEN_TAC `i:num` THEN STRIP_TAC THEN + SUBGOAL_THEN `p <= i /\ p <= i + 1` ASSUME_TAC THENL + [ASM_ARITH_TAC; ALL_TAC] THEN + ASM_SIMP_TAC[REAL_NORM; REAL_SUB; RE_SUB] THEN + ASM_SIMP_TAC[REAL_ARITH `abs(x - y) = y - x <=> x <= y`]; + ALL_TAC] THEN + ASM_REWRITE_TAC[SUM_DIFFS; COMPLEX_NORM_MUL] THEN + MATCH_MP_TAC(REAL_ARITH + `w * n1 <= w * B /\ z * n2 <= z * B /\ &0 <= B * (&2 * y - (x + w + z)) + ==> x * B <= &2 * B * y - w * n1 - z * n2`) THEN + REPEAT(CONJ_TAC THENL + [MATCH_MP_TAC REAL_LE_LMUL THEN + ASM_SIMP_TAC[NORM_POS_LE; LE_REFL]; ALL_TAC]) THEN + MATCH_MP_TAC REAL_LE_MUL THEN ASM_SIMP_TAC[REAL_LT_IMP_LE] THEN + SUBGOAL_THEN + `p <= m /\ p <= m + 1 /\ p <= n /\ p <= n + 1` + STRIP_ASSUME_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN + ASM_SIMP_TAC[REAL_NORM; real_abs] THEN REAL_ARITH_TAC);; + +let SERIES_DIRICHLET_COMPLEX_EXPLICIT = prove + (`!f g p q. + 1 <= p /\ + bounded {vsum (q..n) f | n IN (:num)} /\ + (!n. p <= n ==> real(g n) /\ &0 <= Re(g n)) /\ + (!n. p <= n ==> Re(g(n + 1)) <= Re(g n)) + ==> ?B. &0 < B /\ + !m n. p <= m + ==> norm(vsum(m..n) (\k. f k * g k)) + <= B * norm(g m)`, + REWRITE_TAC[FORALL_AND_THM] THEN REPEAT STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o MATCH_MP BOUNDED_PARTIAL_SUMS) THEN + SIMP_TAC[BOUNDED_POS; IN_ELIM_THM; IN_UNIV; LEFT_IMP_EXISTS_THM] THEN + REWRITE_TAC[MESON[] `(!x a b. x = f a b ==> p a b) <=> (!a b. p a b)`] THEN + X_GEN_TAC `B:real` THEN STRIP_TAC THEN EXISTS_TAC `&2 * B` THEN + ASM_SIMP_TAC[GSYM REAL_MUL_ASSOC; REAL_LT_MUL; REAL_OF_NUM_LT; ARITH] THEN + MATCH_MP_TAC SERIES_DIRICHLET_COMPLEX_VERY_EXPLICIT THEN + ASM_SIMP_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* Relations among convergence and absolute convergence for power series. *) +(* ------------------------------------------------------------------------- *) + +let ABEL_LEMMA = prove + (`!a M r r0. + &0 <= r /\ r < r0 /\ + (!n. n IN k ==> norm(a n) * r0 pow n <= M) + ==> summable k (\n. Cx(norm(a(n)) * r pow n))`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN `&0 < r0` ASSUME_TAC THENL + [ASM_REAL_ARITH_TAC; ALL_TAC] THEN + ASM_CASES_TAC `k:num->bool = {}` THEN ASM_REWRITE_TAC[SUMMABLE_TRIVIAL] THEN + SUBGOAL_THEN `&0 <= M` ASSUME_TAC THENL + [FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN + DISCH_THEN(X_CHOOSE_TAC `i:num`) THEN + FIRST_X_ASSUM(MP_TAC o SPEC `i:num`) THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC(REAL_ARITH `&0 <= x ==> x <= y ==> &0 <= y`) THEN + MATCH_MP_TAC REAL_LE_MUL THEN + ASM_SIMP_TAC[NORM_POS_LE; REAL_POW_LE; REAL_LT_IMP_LE]; + ALL_TAC] THEN + MATCH_MP_TAC SERIES_COMPARISON_COMPLEX THEN + EXISTS_TAC `\n. Cx(M * (r / r0) pow n)` THEN REPEAT CONJ_TAC THENL + [REWRITE_TAC[CX_MUL; CX_POW] THEN MATCH_MP_TAC SUMMABLE_COMPLEX_LMUL THEN + MATCH_MP_TAC SUMMABLE_GP THEN REWRITE_TAC[COMPLEX_NORM_CX] THEN + ASM_SIMP_TAC[REAL_ABS_DIV; real_abs; REAL_LT_IMP_LE] THEN + ASM_SIMP_TAC[REAL_LT_LDIV_EQ; REAL_MUL_LID]; + REWRITE_TAC[REAL_CX; RE_CX] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_LE_MUL THEN ASM_REWRITE_TAC[] THEN + ASM_SIMP_TAC[REAL_LE_DIV; REAL_POW_LE; REAL_LT_IMP_LE]; + EXISTS_TAC `0` THEN REWRITE_TAC[COMPLEX_NORM_CX] THEN REPEAT STRIP_TAC THEN + REWRITE_TAC[REAL_ABS_MUL; REAL_ABS_POW; REAL_ABS_NORM; REAL_ABS_DIV] THEN + ASM_SIMP_TAC[real_abs; REAL_LT_IMP_LE; REAL_POW_DIV] THEN + REWRITE_TAC[real_div; REAL_MUL_ASSOC] THEN + ASM_SIMP_TAC[GSYM real_div; REAL_LE_RDIV_EQ; REAL_POW_LT] THEN + ONCE_REWRITE_TAC[REAL_ARITH `(a * b) * c:real = (a * c) * b`] THEN + ASM_SIMP_TAC[REAL_LE_RMUL; REAL_POW_LE; REAL_LT_IMP_LE]]);; + +let POWER_SERIES_CONV_IMP_ABSCONV = prove + (`!a k w z. + summable k (\n. a(n) * z pow n) /\ norm(w) < norm(z) + ==> summable k (\n. Cx(norm(a(n) * w pow n)))`, + REPEAT STRIP_TAC THEN + REWRITE_TAC[COMPLEX_NORM_MUL; COMPLEX_NORM_POW] THEN + MATCH_MP_TAC ABEL_LEMMA THEN + FIRST_ASSUM(MP_TAC o MATCH_MP SUMMABLE_IMP_BOUNDED) THEN + REWRITE_TAC[BOUNDED_POS; FORALL_IN_IMAGE] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `B:real` THEN STRIP_TAC THEN + EXISTS_TAC `norm(z:complex)` THEN REWRITE_TAC[NORM_POS_LE] THEN + ASM_REWRITE_TAC[GSYM COMPLEX_NORM_POW; GSYM COMPLEX_NORM_MUL]);; + +let POWER_SERIES_CONV_IMP_ABSCONV_WEAK = prove + (`!a k w z. + summable k (\n. a(n) * z pow n) /\ norm(w) < norm(z) + ==> summable k (\n. Cx(norm(a(n))) * w pow n)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC SERIES_COMPARISON_COMPLEX THEN + EXISTS_TAC `\n. Cx(norm(a(n) * w pow n))` THEN CONJ_TAC THENL + [MATCH_MP_TAC POWER_SERIES_CONV_IMP_ABSCONV THEN + EXISTS_TAC `z:complex` THEN ASM_REWRITE_TAC[]; + ALL_TAC] THEN + REWRITE_TAC[REAL_CX; RE_CX; NORM_POS_LE] THEN + REWRITE_TAC[COMPLEX_NORM_MUL; COMPLEX_NORM_CX; REAL_ABS_NORM; + REAL_ABS_MUL; REAL_LE_REFL]);; + +(* ------------------------------------------------------------------------- *) +(* Comparing sums and "integrals" via complex antiderivatives. *) +(* ------------------------------------------------------------------------- *) + +let SUM_INTEGRAL_UBOUND_INCREASING = prove + (`!f g m n. + m <= n /\ + (!x. x IN segment[Cx(&m),Cx(&n + &1)] + ==> (g has_complex_derivative f(x)) (at x)) /\ + (!x y. &m <= x /\ x <= y /\ y <= &n + &1 ==> Re(f(Cx x)) <= Re(f(Cx y))) + ==> sum(m..n) (\k. Re(f(Cx(&k)))) <= Re(g(Cx(&n + &1)) - g(Cx(&m)))`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `--sum(m..n) (\k. Re(g(Cx(&k))) - Re(g(Cx(&(k + 1)))))` THEN + CONJ_TAC THENL + [ALL_TAC; + ASM_REWRITE_TAC[SUM_DIFFS; RE_SUB; REAL_NEG_SUB; REAL_OF_NUM_ADD] THEN + REWRITE_TAC[REAL_LE_REFL]] THEN + REWRITE_TAC[GSYM SUM_NEG] THEN MATCH_MP_TAC SUM_LE_NUMSEG THEN + REWRITE_TAC[REAL_NEG_SUB] THEN X_GEN_TAC `r:num` THEN STRIP_TAC THEN + MP_TAC(ISPECL [`g:complex->complex`; `f:complex->complex`; + `Cx(&r)`; `Cx(&r + &1)`] COMPLEX_MVT_LINE) THEN + ANTS_TAC THENL + [X_GEN_TAC `u:complex` THEN STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + UNDISCH_TAC `u IN segment[Cx(&r),Cx(&r + &1)]` THEN + REWRITE_TAC[SEGMENT_CONVEX_HULL] THEN + SPEC_TAC(`u:complex`,`u:complex`) THEN REWRITE_TAC[GSYM SUBSET] THEN + MATCH_MP_TAC HULL_MINIMAL THEN REWRITE_TAC[CONVEX_CONVEX_HULL] THEN + REWRITE_TAC[SUBSET; IN_INSERT; NOT_IN_EMPTY; GSYM SEGMENT_CONVEX_HULL] THEN + REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[IN_SEGMENT_CX] THEN + REWRITE_TAC[REAL_OF_NUM_ADD; REAL_OF_NUM_LE] THEN + ASM_ARITH_TAC; + REWRITE_TAC[GSYM REAL_OF_NUM_ADD] THEN DISCH_THEN(X_CHOOSE_THEN `u:complex` + (CONJUNCTS_THEN2 ASSUME_TAC SUBST1_TAC)) THEN + REWRITE_TAC[CX_ADD; COMPLEX_RING `y * ((x + Cx(&1)) - x) = y`] THEN + SUBGOAL_THEN `?y. u = Cx y` (CHOOSE_THEN SUBST_ALL_TAC) THENL + [ASM_MESON_TAC[REAL_SEGMENT; REAL_CX; REAL]; ALL_TAC] THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_SEGMENT_CX]) THEN + REPEAT(FIRST_X_ASSUM + (MP_TAC o GEN_REWRITE_RULE I [GSYM REAL_OF_NUM_LE])) THEN + REAL_ARITH_TAC]);; + +let SUM_INTEGRAL_UBOUND_DECREASING = prove + (`!f g m n. + m <= n /\ + (!x. x IN segment[Cx(&m - &1),Cx(&n)] + ==> (g has_complex_derivative f(x)) (at x)) /\ + (!x y. &m - &1 <= x /\ x <= y /\ y <= &n ==> Re(f(Cx y)) <= Re(f(Cx x))) + ==> sum(m..n) (\k. Re(f(Cx(&k)))) <= Re(g(Cx(&n)) - g(Cx(&m - &1)))`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC + `--sum(m..n) (\k. Re(g(Cx(&(k) - &1))) - Re(g(Cx(&(k+1) - &1))))` THEN + CONJ_TAC THENL + [ALL_TAC; + ASM_REWRITE_TAC[SUM_DIFFS; REAL_NEG_SUB] THEN + REWRITE_TAC[GSYM REAL_OF_NUM_ADD; GSYM REAL_OF_NUM_SUB] THEN + REWRITE_TAC[RE_SUB; REAL_ARITH `(x + &1) - &1 = x`; REAL_LE_REFL]] THEN + REWRITE_TAC[GSYM SUM_NEG] THEN MATCH_MP_TAC SUM_LE_NUMSEG THEN + REWRITE_TAC[REAL_NEG_SUB] THEN X_GEN_TAC `r:num` THEN STRIP_TAC THEN + REWRITE_TAC[GSYM REAL_OF_NUM_ADD; REAL_ARITH `(x + &1) - &1 = x`] THEN + MP_TAC(ISPECL [`g:complex->complex`; `f:complex->complex`; + `Cx(&r - &1)`; `Cx(&r)`] COMPLEX_MVT_LINE) THEN + ANTS_TAC THENL + [X_GEN_TAC `u:complex` THEN STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + UNDISCH_TAC `u IN segment[Cx(&r - &1),Cx(&r)]` THEN + REWRITE_TAC[SEGMENT_CONVEX_HULL] THEN + SPEC_TAC(`u:complex`,`u:complex`) THEN REWRITE_TAC[GSYM SUBSET] THEN + MATCH_MP_TAC HULL_MINIMAL THEN REWRITE_TAC[CONVEX_CONVEX_HULL] THEN + REWRITE_TAC[SUBSET; IN_INSERT; NOT_IN_EMPTY; GSYM SEGMENT_CONVEX_HULL] THEN + REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[IN_SEGMENT_CX] THEN + REPEAT(POP_ASSUM MP_TAC) THEN + REWRITE_TAC[GSYM REAL_OF_NUM_LE] THEN REAL_ARITH_TAC; + REWRITE_TAC[GSYM REAL_OF_NUM_ADD] THEN DISCH_THEN(X_CHOOSE_THEN `u:complex` + (CONJUNCTS_THEN2 ASSUME_TAC SUBST1_TAC)) THEN + REWRITE_TAC[CX_SUB; COMPLEX_RING `y * (x - (x - Cx(&1))) = y`] THEN + SUBGOAL_THEN `?y. u = Cx y` (CHOOSE_THEN SUBST_ALL_TAC) THENL + [ASM_MESON_TAC[REAL_SEGMENT; REAL_CX; REAL]; ALL_TAC] THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_SEGMENT_CX]) THEN + REPEAT(FIRST_X_ASSUM + (MP_TAC o GEN_REWRITE_RULE I [GSYM REAL_OF_NUM_LE])) THEN + REAL_ARITH_TAC]);; + +let SUM_INTEGRAL_LBOUND_INCREASING = prove + (`!f g m n. + m <= n /\ + (!x. x IN segment[Cx(&m - &1),Cx(&n)] + ==> (g has_complex_derivative f(x)) (at x)) /\ + (!x y. &m - &1 <= x /\ x <= y /\ y <= &n ==> Re(f(Cx x)) <= Re(f(Cx y))) + ==> Re(g(Cx(&n)) - g(Cx(&m - &1))) <= sum(m..n) (\k. Re(f(Cx(&k))))`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`\z. --((f:complex->complex) z)`; + `\z. --((g:complex->complex) z)`; + `m:num`; `n:num`] SUM_INTEGRAL_UBOUND_DECREASING) THEN + REWRITE_TAC[RE_NEG; RE_SUB; SUM_NEG; REAL_LE_NEG2; + REAL_ARITH `--x - --y:real = --(x - y)`] THEN + ASM_SIMP_TAC[HAS_COMPLEX_DERIVATIVE_NEG]);; + +let SUM_INTEGRAL_LBOUND_DECREASING = prove + (`!f g m n. + m <= n /\ + (!x. x IN segment[Cx(&m),Cx(&n + &1)] + ==> (g has_complex_derivative f(x)) (at x)) /\ + (!x y. &m <= x /\ x <= y /\ y <= &n + &1 ==> Re(f(Cx y)) <= Re(f(Cx x))) + ==> Re(g(Cx(&n + &1)) - g(Cx(&m))) <= sum(m..n) (\k. Re(f(Cx(&k))))`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`\z. --((f:complex->complex) z)`; + `\z. --((g:complex->complex) z)`; + `m:num`; `n:num`] SUM_INTEGRAL_UBOUND_INCREASING) THEN + REWRITE_TAC[RE_NEG; RE_SUB; SUM_NEG; REAL_LE_NEG2; + REAL_ARITH `--x - --y:real = --(x - y)`] THEN + ASM_SIMP_TAC[HAS_COMPLEX_DERIVATIVE_NEG]);; + +let SUM_INTEGRAL_BOUNDS_INCREASING = prove + (`!f g m n. + m <= n /\ + (!x. x IN segment[Cx(&m - &1),Cx (&n + &1)] + ==> (g has_complex_derivative f x) (at x)) /\ + (!x y. + &m - &1 <= x /\ x <= y /\ y <= &n + &1 + ==> Re(f(Cx x)) <= Re(f(Cx y))) + ==> Re(g(Cx(&n)) - g(Cx(&m - &1))) <= sum(m..n) (\k. Re(f(Cx(&k)))) /\ + sum (m..n) (\k. Re(f(Cx(&k)))) <= Re(g(Cx(&n + &1)) - g(Cx(&m)))`, + REPEAT STRIP_TAC THENL + [MATCH_MP_TAC SUM_INTEGRAL_LBOUND_INCREASING; + MATCH_MP_TAC SUM_INTEGRAL_UBOUND_INCREASING] THEN + REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN + RULE_ASSUM_TAC(REWRITE_RULE[IN_SEGMENT_CX_GEN; GSYM REAL_OF_NUM_LE]) THEN + REWRITE_TAC[IN_SEGMENT_CX_GEN] THEN ASM_REAL_ARITH_TAC);; + +let SUM_INTEGRAL_BOUNDS_DECREASING = prove + (`!f g m n. + m <= n /\ + (!x. x IN segment[Cx(&m - &1),Cx(&n + &1)] + ==> (g has_complex_derivative f(x)) (at x)) /\ + (!x y. &m - &1 <= x /\ x <= y /\ y <= &n + &1 + ==> Re(f(Cx y)) <= Re(f(Cx x))) + ==> Re(g(Cx(&n + &1)) - g(Cx(&m))) <= sum(m..n) (\k. Re(f(Cx(&k)))) /\ + sum(m..n) (\k. Re(f(Cx(&k)))) <= Re(g(Cx(&n)) - g(Cx(&m - &1)))`, + REPEAT STRIP_TAC THENL + [MATCH_MP_TAC SUM_INTEGRAL_LBOUND_DECREASING; + MATCH_MP_TAC SUM_INTEGRAL_UBOUND_DECREASING] THEN + REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN + RULE_ASSUM_TAC(REWRITE_RULE[IN_SEGMENT_CX_GEN; GSYM REAL_OF_NUM_LE]) THEN + REWRITE_TAC[IN_SEGMENT_CX_GEN] THEN ASM_REAL_ARITH_TAC);; + +(* ------------------------------------------------------------------------- *) +(* Relating different kinds of complex limits. *) +(* ------------------------------------------------------------------------- *) + +let LIM_INFINITY_SEQUENTIALLY_COMPLEX = prove + (`!f l. (f --> l) at_infinity ==> ((\n. f(Cx(&n))) --> l) sequentially`, + REPEAT GEN_TAC THEN REWRITE_TAC[LIM_AT_INFINITY; LIM_SEQUENTIALLY] THEN + DISCH_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 `B:real`) THEN + MP_TAC(ISPEC `B:real` REAL_ARCH_SIMPLE) THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `N:num` THEN + REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + REWRITE_TAC[COMPLEX_NORM_CX] THEN + REPEAT(POP_ASSUM MP_TAC) THEN + REWRITE_TAC[GSYM REAL_OF_NUM_LE] THEN REAL_ARITH_TAC);; + +let LIM_ZERO_INFINITY_COMPLEX = prove + (`!f l. ((\x. f(Cx(&1) / x)) --> l) (at (Cx(&0))) ==> (f --> l) at_infinity`, + REPEAT GEN_TAC THEN REWRITE_TAC[LIM_AT; LIM_AT_INFINITY] THEN + DISCH_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 + REWRITE_TAC[dist; COMPLEX_SUB_RZERO; real_ge] THEN + DISCH_THEN(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `&2 / d` THEN X_GEN_TAC `z:complex` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `inv(z):complex`) THEN + REWRITE_TAC[complex_div; COMPLEX_MUL_LINV; COMPLEX_INV_INV] THEN + REWRITE_TAC[COMPLEX_MUL_LID] THEN DISCH_THEN MATCH_MP_TAC THEN + ASM_REWRITE_TAC[COMPLEX_NORM_INV; REAL_LT_INV_EQ] THEN CONJ_TAC THENL + [UNDISCH_TAC `&2 / d <= norm(z:complex)` THEN + ASM_CASES_TAC `z = Cx(&0)` THEN ASM_REWRITE_TAC[COMPLEX_NORM_NZ] THEN + REWRITE_TAC[COMPLEX_NORM_0; REAL_NOT_LE] THEN + ASM_SIMP_TAC[REAL_LT_DIV; REAL_OF_NUM_LT; ARITH]; + GEN_REWRITE_TAC RAND_CONV [GSYM REAL_INV_INV] THEN + MATCH_MP_TAC REAL_LT_INV2 THEN ASM_REWRITE_TAC[REAL_LT_INV_EQ] THEN + MATCH_MP_TAC REAL_LTE_TRANS THEN EXISTS_TAC `&2 / d` THEN + ASM_REWRITE_TAC[] THEN REWRITE_TAC[real_div] THEN + ASM_REWRITE_TAC[REAL_LT_INV_EQ; REAL_ARITH `x < &2 * x <=> &0 < x`]]);; + +(* ------------------------------------------------------------------------- *) +(* Transforming complex limits to real ones. *) +(* ------------------------------------------------------------------------- *) + +let LIM_COMPLEX_REAL = prove + (`!f g l m. + eventually (\n. Re(g n) = f n) sequentially /\ + Re m = l /\ + (g --> m) sequentially + ==> !e. &0 < e ==> ?N. !n. N <= n ==> abs(f n - l) < e`, + REPEAT GEN_TAC THEN + REWRITE_TAC[EVENTUALLY_SEQUENTIALLY; LIM_SEQUENTIALLY] THEN + DISCH_THEN(CONJUNCTS_THEN2 (X_CHOOSE_TAC `N1:num`) + (CONJUNCTS_THEN2 (SUBST1_TAC o SYM) ASSUME_TAC)) THEN + X_GEN_TAC `e:real` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `e:real`) THEN ASM_REWRITE_TAC[dist] THEN + DISCH_THEN(X_CHOOSE_TAC `N0:num`) THEN EXISTS_TAC `N0 + N1:num` THEN + X_GEN_TAC `n:num` THEN DISCH_THEN(STRIP_ASSUME_TAC o MATCH_MP (ARITH_RULE + `N0 + N1:num <= n ==> N0 <= n /\ N1 <= n`)) THEN + UNDISCH_THEN `!n. N0 <= n ==> norm ((g:num->complex) n - m) < e` + (MP_TAC o SPEC `n:num`) THEN + FIRST_X_ASSUM(MP_TAC o SPEC `n:num`) THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(SUBST1_TAC o SYM) THEN REWRITE_TAC[GSYM RE_SUB] THEN + MATCH_MP_TAC(REAL_ARITH `x <= y ==> y < e ==> x < e`) THEN + REWRITE_TAC[COMPLEX_NORM_GE_RE_IM]);; + +let LIM_COMPLEX_REAL_0 = prove + (`!f g. eventually (\n. Re(g n) = f n) sequentially /\ + (g --> Cx(&0)) sequentially + ==> !e. &0 < e ==> ?N. !n. N <= n ==> abs(f n) < e`, + MP_TAC LIM_COMPLEX_REAL THEN + REPLICATE_TAC 2 (MATCH_MP_TAC MONO_FORALL THEN GEN_TAC) THEN + DISCH_THEN(MP_TAC o SPECL [`&0`; `Cx(&0)`]) THEN + REWRITE_TAC[RE_CX; REAL_SUB_RZERO]);; + +(* ------------------------------------------------------------------------- *) +(* Uniform convergence of power series in a "Stolz angle". *) +(* ------------------------------------------------------------------------- *) + +let POWER_SERIES_UNIFORM_CONVERGENCE_STOLZ_1 = prove + (`!M a s e. + summable s a /\ &0 < M /\ &0 < e + ==> eventually + (\n. !z. norm(Cx(&1) - z) <= M * (&1 - norm z) + ==> norm(vsum (s INTER (0..n)) (\i. a i * z pow i) - + infsum s (\i. a i * z pow i)) < e) + sequentially`, + let lemma = prove + (`!M w z. &0 < M /\ norm(w - z) <= M * (norm w - norm z) /\ ~(z = w) + ==> norm(z) < norm(w)`, + REPEAT STRIP_TAC THEN REWRITE_TAC[REAL_LT_LE] THEN CONJ_TAC THENL + [ASM_MESON_TAC[REAL_LE_MUL_EQ; REAL_SUB_LE; NORM_POS_LE; REAL_LE_TRANS]; + DISCH_THEN SUBST_ALL_TAC THEN + ASM_MESON_TAC[REAL_SUB_REFL; REAL_MUL_RZERO;NORM_LE_0; VECTOR_SUB_EQ]]) + and lemma1 = prove + (`!m n. m < n + ==> vsum (m..n) (\i. a i * z pow i) = + (Cx(&1) - z) * vsum(m..n-1) (\i. vsum (m..i) a * z pow i) + + vsum(m..n) a * z pow n`, + GEN_TAC THEN INDUCT_TAC THEN REWRITE_TAC[NOT_SUC; SUC_SUB1] THEN + SIMP_TAC[VSUM_CLAUSES_NUMSEG; LT; LT_IMP_LE] THEN STRIP_TAC THENL + [ASM_REWRITE_TAC[VSUM_SING_NUMSEG; complex_pow] THEN CONV_TAC COMPLEX_RING; + ASM_SIMP_TAC[] THEN UNDISCH_TAC `m:num < n` THEN + POP_ASSUM(K ALL_TAC)] THEN + SPEC_TAC(`n:num`,`n:num`) THEN + INDUCT_TAC THEN REWRITE_TAC[CONJUNCT1 LT] THEN POP_ASSUM(K ALL_TAC) THEN + SIMP_TAC[SUC_SUB1; VSUM_CLAUSES_NUMSEG; LT_IMP_LE] THEN + ASM_REWRITE_TAC[VSUM_SING_NUMSEG; complex_pow] THEN + CONV_TAC COMPLEX_RING) in + SUBGOAL_THEN + `!M a e. + summable (:num) a /\ &0 < M /\ &0 < e + ==> eventually + (\n. !z. norm(Cx(&1) - z) <= M * (&1 - norm z) + ==> norm(vsum (0..n) (\i. a i * z pow i) - + infsum (:num) (\i. a i * z pow i)) < e) + sequentially` + ASSUME_TAC THENL + [ALL_TAC; + REPEAT STRIP_TAC THEN FIRST_ASSUM(MP_TAC o ISPECL + [`M:real`; `\i:num. if i IN s then a i else Cx(&0)`; `e:real`]) THEN + REWRITE_TAC[COND_RAND; COND_RATOR; COMPLEX_MUL_LZERO] THEN + ASM_REWRITE_TAC[GSYM COMPLEX_VEC_0; GSYM VSUM_RESTRICT_SET; + INFSUM_RESTRICT; SUMMABLE_RESTRICT] THEN + REWRITE_TAC[SET_RULE `{i | i IN t /\ i IN s} = s INTER t`]] THEN + REPEAT STRIP_TAC THEN + ONCE_REWRITE_TAC[MESON[] + `(!z. P z) <=> P (Cx(&1)) /\ (!z. ~(z = Cx(&1)) ==> P z)`] THEN + REWRITE_TAC[EVENTUALLY_AND] THEN CONJ_TAC THENL + [REWRITE_TAC[COMPLEX_NORM_CX; REAL_ABS_NUM; COMPLEX_SUB_REFL; + REAL_SUB_REFL; REAL_MUL_RZERO; REAL_LE_REFL] THEN + UNDISCH_TAC `&0 < e` THEN SPEC_TAC(`e:real`,`e:real`) THEN + REWRITE_TAC[GSYM tendsto; COMPLEX_POW_ONE; COMPLEX_MUL_RID; GSYM dist; + ETA_AX] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM SUMS_INFSUM]) THEN + REWRITE_TAC[sums; INTER_UNIV]; + ALL_TAC] THEN + REWRITE_TAC[IMP_IMP; EVENTUALLY_SEQUENTIALLY] THEN + REWRITE_TAC[RIGHT_IMP_FORALL_THM; IMP_IMP; GSYM dist] THEN + UNDISCH_TAC `&0 < e` THEN SPEC_TAC(`e:real`,`e:real`) THEN + MATCH_MP_TAC UNIFORMLY_CAUCHY_IMP_UNIFORMLY_CONVERGENT THEN + REWRITE_TAC[GSYM LIM_SEQUENTIALLY] THEN CONJ_TAC THENL + [X_GEN_TAC `e:real` THEN DISCH_TAC THEN + REWRITE_TAC[MESON[] `(!m n z. P m /\ P n /\ Q z ==> R m n z) <=> + (!z. Q z ==> !m n. P m /\ P n ==> R m n z)`] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM SUMS_INFSUM]) THEN + REWRITE_TAC[sums] THEN + DISCH_THEN(MP_TAC o MATCH_MP CONVERGENT_IMP_CAUCHY) THEN + REWRITE_TAC[cauchy; GSYM dist] THEN + DISCH_THEN(MP_TAC o SPEC `min (e / &2) (e / &2 / M)`) THEN + ASM_SIMP_TAC[REAL_LT_MIN; REAL_LT_DIV; REAL_HALF; GE; INTER_UNIV] THEN + REWRITE_TAC[GSYM REAL_LT_MIN] THEN + ONCE_REWRITE_TAC[SEQUENCE_CAUCHY_WLOG] THEN + SUBGOAL_THEN + `!f:num->complex m n. m <= n + ==> dist(vsum (0..m) f,vsum (0..n) f) = norm(vsum (m+1..n) f)` + (fun th -> SIMP_TAC[th]) + THENL + [REPEAT STRIP_TAC THEN + MATCH_MP_TAC(NORM_ARITH `a + c = b ==> dist(a,b) = norm c`) THEN + MATCH_MP_TAC VSUM_COMBINE_R THEN ASM_ARITH_TAC; + ALL_TAC] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `N:num` THEN + REWRITE_TAC[REAL_LT_MIN] THEN STRIP_TAC THEN + X_GEN_TAC `z:complex` THEN REWRITE_TAC[dist] THEN STRIP_TAC THEN + SUBGOAL_THEN `norm(z:complex) < &1` ASSUME_TAC THENL + [UNDISCH_TAC `~(z = Cx(&1))` THEN + ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN + REWRITE_TAC[NORM_POS_LT; VECTOR_SUB_EQ] THEN DISCH_TAC THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (NORM_ARITH + `norm(a - b) <= M ==> &0 <= --M ==> b = a`)) THEN + REWRITE_TAC[GSYM REAL_MUL_RNEG; REAL_NEG_SUB] THEN + MATCH_MP_TAC REAL_LE_MUL THEN ASM_REAL_ARITH_TAC; + ALL_TAC] THEN + MAP_EVERY X_GEN_TAC [`m:num`; `n:num`] THEN STRIP_TAC THEN + ASM_CASES_TAC `m + 1 < n` THENL + [ASM_SIMP_TAC[lemma1] THEN + MATCH_MP_TAC(NORM_ARITH + `norm(a) < e / &2 /\ norm(b) < e / &2 ==> norm(a + b) < e`) THEN + REWRITE_TAC[COMPLEX_NORM_MUL; COMPLEX_NORM_POW] THEN CONJ_TAC THENL + [MATCH_MP_TAC REAL_LET_TRANS THEN + EXISTS_TAC `(M * (&1 - norm(z:complex))) * + sum (m+1..n-1) (\i. e / &2 / M * norm(z) pow i)` THEN + CONJ_TAC THENL + [MATCH_MP_TAC REAL_LE_MUL2 THEN ASM_REWRITE_TAC[NORM_POS_LE] THEN + MATCH_MP_TAC VSUM_NORM_LE THEN + REWRITE_TAC[FINITE_NUMSEG; IN_NUMSEG] THEN + X_GEN_TAC `p:num` THEN STRIP_TAC THEN + ASM_SIMP_TAC[COMPLEX_NORM_MUL; COMPLEX_NORM_POW] THEN + MATCH_MP_TAC REAL_LE_RMUL THEN + SIMP_TAC[REAL_POW_LE; NORM_POS_LE] THEN + MATCH_MP_TAC(REAL_ARITH + `x < e / &2 /\ x < e / &2 / M ==> x <= e / &2 / M`) THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_ARITH_TAC; + REWRITE_TAC[SUM_LMUL] THEN + REWRITE_TAC[REAL_ARITH + `(M * z1) * e / &2 / M * s < e / &2 <=> + e * (M / M) * s * z1 < e * &1`] THEN + ASM_SIMP_TAC[REAL_LT_LMUL_EQ] THEN + ASM_SIMP_TAC[REAL_DIV_REFL; REAL_LT_IMP_NZ; REAL_MUL_LID] THEN + ASM_SIMP_TAC[GSYM REAL_LT_RDIV_EQ; REAL_SUB_LT] THEN + REWRITE_TAC[SUM_GP] THEN + COND_CASES_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN + COND_CASES_TAC THENL + [UNDISCH_TAC `norm(Cx(&1) - z) <= M * (&1 - norm z)` THEN + ASM_REWRITE_TAC[REAL_SUB_REFL; REAL_MUL_RZERO] THEN + ASM_REWRITE_TAC[NORM_ARITH `norm(x - y:complex) <= &0 <=> x = y`]; + ALL_TAC] THEN + ASM_SIMP_TAC[REAL_LT_DIV2_EQ; REAL_SUB_LT] THEN + MATCH_MP_TAC(REAL_ARITH + `&0 <= y /\ x < &1 ==> x - y < &1`) THEN + ASM_SIMP_TAC[REAL_POW_LE; NORM_POS_LE] THEN + MATCH_MP_TAC REAL_POW_1_LT THEN + ASM_REWRITE_TAC[NORM_POS_LE] THEN ARITH_TAC]; + GEN_REWRITE_TAC RAND_CONV [GSYM REAL_MUL_RID] THEN + MATCH_MP_TAC REAL_LT_MUL2 THEN SIMP_TAC[NORM_POS_LE; REAL_POW_LE] THEN + CONJ_TAC THENL + [MATCH_MP_TAC(REAL_ARITH + `x < e / &2 /\ x < e / &2 / M ==> x < e / &2`) THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_ARITH_TAC; + MATCH_MP_TAC REAL_POW_1_LT THEN + ASM_REWRITE_TAC[NORM_POS_LE] THEN ASM_ARITH_TAC]]; + ASM_CASES_TAC `(m+1)..n = {}` THENL + [ASM_REWRITE_TAC[VSUM_CLAUSES; NORM_0]; ALL_TAC] THEN + RULE_ASSUM_TAC(REWRITE_RULE[NUMSEG_EMPTY]) THEN + SUBGOAL_THEN `m + 1 = n` SUBST1_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN + REWRITE_TAC[VSUM_SING_NUMSEG] THEN + REWRITE_TAC[COMPLEX_NORM_MUL; COMPLEX_NORM_POW] THEN + GEN_REWRITE_TAC RAND_CONV [GSYM REAL_MUL_RID] THEN + MATCH_MP_TAC REAL_LT_MUL2 THEN SIMP_TAC[NORM_POS_LE; REAL_POW_LE] THEN + CONJ_TAC THENL + [FIRST_X_ASSUM(MP_TAC o SPECL [`m:num`; `n:num`]) THEN + SUBGOAL_THEN `m + 1 = n` SUBST1_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN + ANTS_TAC THENL [ASM_ARITH_TAC; REWRITE_TAC[VSUM_SING_NUMSEG]] THEN + ASM_REAL_ARITH_TAC; + MATCH_MP_TAC REAL_POW_1_LT THEN + ASM_REWRITE_TAC[NORM_POS_LE] THEN ASM_ARITH_TAC]]; + X_GEN_TAC `z:complex` THEN REWRITE_TAC[dist] THEN STRIP_TAC THEN + MP_TAC(ISPECL [`M:real`; `Cx(&1)`; `z:complex`] lemma) THEN + ASM_REWRITE_TAC[COMPLEX_NORM_CX; REAL_ABS_NUM] THEN DISCH_TAC THEN + SUBGOAL_THEN `summable (:num) (\i. a i * z pow i)` MP_TAC THENL + [MATCH_MP_TAC SERIES_ABSCONV_IMP_CONV THEN + REWRITE_TAC[] THEN MATCH_MP_TAC POWER_SERIES_CONV_IMP_ABSCONV THEN + EXISTS_TAC `Cx(&1)` THEN + REWRITE_TAC[COMPLEX_POW_ONE; COMPLEX_NORM_CX] THEN + ASM_REWRITE_TAC[REAL_ABS_NUM; COMPLEX_MUL_RID; ETA_AX]; + REWRITE_TAC[GSYM SUMS_INFSUM] THEN + REWRITE_TAC[sums; INTER_UNIV]]]);; + +let POWER_SERIES_UNIFORM_CONVERGENCE_STOLZ = prove + (`!M a w s e. + summable s (\i. a i * w pow i) /\ &0 < M /\ &0 < e + ==> eventually + (\n. !z. norm(w - z) <= M * (norm w - norm z) + ==> norm(vsum (s INTER (0..n)) (\i. a i * z pow i) - + infsum s (\i. a i * z pow i)) < e) + sequentially`, + REPEAT GEN_TAC THEN DISCH_TAC THEN ASM_CASES_TAC `w = Cx(&0)` THENL + [ASM_REWRITE_TAC[COMPLEX_SUB_LZERO; REAL_SUB_LZERO; COMPLEX_NORM_0] THEN + REWRITE_TAC[NORM_NEG; REAL_ARITH + `n <= M * --n <=> &0 <= --n * (&1 + M)`] THEN + ASM_SIMP_TAC[REAL_LE_MUL_EQ; REAL_ARITH `&0 < M ==> &0 < &1 + M`] THEN + REWRITE_TAC[NORM_ARITH `&0 <= --norm z <=> z = vec 0`] THEN + REWRITE_TAC[EVENTUALLY_SEQUENTIALLY; FORALL_UNWIND_THM2] THEN + EXISTS_TAC `1` THEN X_GEN_TAC `n:num` THEN DISCH_TAC THEN + REWRITE_TAC[COMPLEX_VEC_0; COMPLEX_POW_ZERO] THEN + REWRITE_TAC[COND_RATOR; COND_RAND; COMPLEX_MUL_RZERO; COMPLEX_MUL_RID] THEN + MATCH_MP_TAC(NORM_ARITH `x = y /\ &0 < e ==> norm(y - x) < e`) THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC INFSUM_UNIQUE THEN + REWRITE_TAC[sums] THEN MATCH_MP_TAC LIM_EVENTUALLY THEN + REWRITE_TAC[EVENTUALLY_SEQUENTIALLY] THEN EXISTS_TAC `1` THEN + X_GEN_TAC `m:num` THEN DISCH_TAC THEN + SIMP_TAC[GSYM COMPLEX_VEC_0; VSUM_DELTA] THEN + REWRITE_TAC[IN_INTER; LE_0; IN_NUMSEG]; + FIRST_ASSUM(MP_TAC o MATCH_MP POWER_SERIES_UNIFORM_CONVERGENCE_STOLZ_1) THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] EVENTUALLY_MONO) THEN + X_GEN_TAC `n:num` THEN REWRITE_TAC[] THEN DISCH_TAC THEN + X_GEN_TAC `z:complex` THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `z / w:complex`) THEN + ASM_SIMP_TAC[GSYM COMPLEX_MUL_ASSOC; GSYM COMPLEX_POW_MUL] THEN + ASM_SIMP_TAC[COMPLEX_DIV_LMUL] THEN DISCH_THEN MATCH_MP_TAC THEN + MATCH_MP_TAC REAL_LE_RCANCEL_IMP THEN EXISTS_TAC `norm(w:complex)` THEN + ASM_REWRITE_TAC[COMPLEX_NORM_NZ; GSYM COMPLEX_NORM_MUL] THEN + ASM_SIMP_TAC[COMPLEX_FIELD + `~(w = Cx(&0)) ==> (Cx(&1) - z / w) * w = w - z`] THEN + REWRITE_TAC[GSYM REAL_MUL_ASSOC; REAL_SUB_RDISTRIB] THEN + REWRITE_TAC[GSYM COMPLEX_NORM_MUL; REAL_MUL_LID] THEN + ASM_SIMP_TAC[COMPLEX_DIV_RMUL]]);; + +(* ------------------------------------------------------------------------- *) +(* Hence continuity and the Abel limit theorem. *) +(* ------------------------------------------------------------------------- *) + +let ABEL_POWER_SERIES_CONTINUOUS = prove + (`!M s a. + summable s a /\ &0 < M + ==> (\z. infsum s (\i. a i * z pow i)) continuous_on + {z | norm(Cx(&1) - z) <= M * (&1 - norm z)}`, + REPEAT STRIP_TAC THEN + MATCH_MP_TAC(ISPEC `sequentially` CONTINUOUS_UNIFORM_LIMIT) THEN + EXISTS_TAC `\n z. vsum (s INTER (0..n)) (\i. a i * z pow i)` THEN + ASM_SIMP_TAC[POWER_SERIES_UNIFORM_CONVERGENCE_STOLZ_1; IN_ELIM_THM; + TRIVIAL_LIMIT_SEQUENTIALLY] THEN + MATCH_MP_TAC ALWAYS_EVENTUALLY THEN X_GEN_TAC `n:num` THEN + REWRITE_TAC[] THEN MATCH_MP_TAC CONTINUOUS_ON_VSUM THEN + SIMP_TAC[CONTINUOUS_ON_COMPLEX_MUL; CONTINUOUS_ON_COMPLEX_POW; + CONTINUOUS_ON_ID; CONTINUOUS_ON_CONST; FINITE_INTER; + FINITE_NUMSEG]);; + +let ABEL_LIMIT_THEOREM = prove + (`!M s a. + summable s a /\ &0 < M + ==> (!z. norm(z) < &1 ==> summable s (\i. a i * z pow i)) /\ + ((\z. infsum s (\i. a i * z pow i)) --> infsum s a) + (at (Cx(&1)) within {z | norm(Cx(&1) - z) <= M * (&1 - norm z)})`, + GEN_TAC THEN ASM_CASES_TAC `&0 < M` THEN ASM_REWRITE_TAC[] THEN + SUBGOAL_THEN + `!a. summable (:num) a + ==> (!z. norm(z) < &1 ==> summable (:num) (\i. a i * z pow i)) /\ + ((\z. infsum (:num) (\i. a i * z pow i)) + --> infsum (:num) a) + (at (Cx(&1)) within {z | norm(Cx(&1) - z) <= M * (&1 - norm z)})` + ASSUME_TAC THENL + [ALL_TAC; + REPEAT GEN_TAC THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC + `(\n. if n IN s then a n else vec 0):num->complex`) THEN + REWRITE_TAC[COND_RAND; COND_RATOR; COMPLEX_VEC_0; COMPLEX_MUL_LZERO] THEN + REWRITE_TAC[GSYM COMPLEX_VEC_0] THEN + ASM_REWRITE_TAC[SUMMABLE_RESTRICT; INFSUM_RESTRICT]] THEN + GEN_TAC THEN STRIP_TAC THEN CONJ_TAC THENL + [X_GEN_TAC `z:complex` THEN DISCH_TAC THEN + MATCH_MP_TAC SERIES_ABSCONV_IMP_CONV THEN + REWRITE_TAC[] THEN MATCH_MP_TAC POWER_SERIES_CONV_IMP_ABSCONV THEN + EXISTS_TAC `Cx(&1)` THEN REWRITE_TAC[COMPLEX_POW_ONE; COMPLEX_NORM_CX] THEN + ASM_REWRITE_TAC[REAL_ABS_NUM; COMPLEX_MUL_RID; ETA_AX]; + MP_TAC(ISPECL [`M:real`; `(:num)`; `a:num->complex`] + ABEL_POWER_SERIES_CONTINUOUS) THEN + ASM_REWRITE_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN] THEN + DISCH_THEN(MP_TAC o SPEC `Cx(&1)`) THEN + REWRITE_TAC[IN_ELIM_THM; CONTINUOUS_WITHIN] THEN + REWRITE_TAC[COMPLEX_SUB_REFL; COMPLEX_NORM_CX; COMPLEX_POW_ONE; + COMPLEX_MUL_RID; ETA_AX; REAL_ABS_NUM; REAL_SUB_REFL; + REAL_LE_REFL; REAL_MUL_RZERO]]);; diff --git a/Multivariate/cauchy.ml b/Multivariate/cauchy.ml new file mode 100644 index 0000000..81be303 --- /dev/null +++ b/Multivariate/cauchy.ml @@ -0,0 +1,16641 @@ +(* ========================================================================= *) +(* Complex path integrals and Cauchy's theorem. *) +(* *) +(* (c) Copyright, John Harrison 1998-2008 *) +(* (c) Copyright, Gianni Ciolli, Graziano Gentili, Marco Maggesi 2008-2009. *) +(* (c) Copyright, Valentina Bruno 2010 *) +(* ========================================================================= *) + +needs "Library/binomial.ml";; +needs "Library/iter.ml";; +needs "Multivariate/realanalysis.ml";; + +prioritize_complex();; + +(* ------------------------------------------------------------------------- *) +(* A couple of extra tactics used in some proofs below. *) +(* ------------------------------------------------------------------------- *) + +let ASSERT_TAC tm = + SUBGOAL_THEN tm STRIP_ASSUME_TAC;; + +let EQ_TRANS_TAC tm = + MATCH_MP_TAC EQ_TRANS THEN EXISTS_TAC tm THEN CONJ_TAC;; + +(* ------------------------------------------------------------------------- *) +(* Piecewise differentiability on a 1-D interval. The definition doesn't *) +(* tie it to real^1 but it's not obviously that useful elsewhere. *) +(* ------------------------------------------------------------------------- *) + +parse_as_infix("piecewise_differentiable_on",(12,"right"));; + +let piecewise_differentiable_on = new_definition + `f piecewise_differentiable_on i <=> + f continuous_on i /\ + (?s. FINITE s /\ !x. x IN (i DIFF s) ==> f differentiable at x)`;; + +let PIECEWISE_DIFFERENTIABLE_ON_IMP_CONTINUOUS_ON = prove + (`!f s. f piecewise_differentiable_on s ==> f continuous_on s`, + SIMP_TAC[piecewise_differentiable_on]);; + +let PIECEWISE_DIFFERENTIABLE_ON_SUBSET = prove + (`!f s t. + f piecewise_differentiable_on s /\ t SUBSET s + ==> f piecewise_differentiable_on t`, + REWRITE_TAC[piecewise_differentiable_on] THEN + MESON_TAC[SUBSET; IN_DIFF; CONTINUOUS_ON_SUBSET]);; + +let DIFFERENTIABLE_ON_IMP_PIECEWISE_DIFFERENTIABLE = prove + (`!f:real^1->real^N a b. + f differentiable_on interval[a,b] + ==> f piecewise_differentiable_on interval[a,b]`, + SIMP_TAC[piecewise_differentiable_on; + DIFFERENTIABLE_IMP_CONTINUOUS_ON] THEN + REPEAT STRIP_TAC THEN EXISTS_TAC `{a,b}:real^1->bool` THEN + ASM_REWRITE_TAC[FINITE_INSERT; FINITE_RULES] THEN + REWRITE_TAC[GSYM OPEN_CLOSED_INTERVAL_1] THEN + SIMP_TAC[GSYM DIFFERENTIABLE_ON_EQ_DIFFERENTIABLE_AT; OPEN_INTERVAL] THEN + MATCH_MP_TAC DIFFERENTIABLE_ON_SUBSET THEN + EXISTS_TAC `interval[a:real^1,b]` THEN + ASM_REWRITE_TAC[INTERVAL_OPEN_SUBSET_CLOSED]);; + +let DIFFERENTIABLE_IMP_PIECEWISE_DIFFERENTIABLE = prove + (`!f s. (!x. x IN s ==> f differentiable (at x)) + ==> f piecewise_differentiable_on s`, + SIMP_TAC[piecewise_differentiable_on; DIFFERENTIABLE_IMP_CONTINUOUS_AT; + CONTINUOUS_AT_IMP_CONTINUOUS_ON; IN_DIFF] THEN + MESON_TAC[FINITE_RULES]);; + +let PIECEWISE_DIFFERENTIABLE_COMPOSE = prove + (`!f:real^M->real^N g:real^N->real^P s. + f piecewise_differentiable_on s /\ + g piecewise_differentiable_on (IMAGE f s) /\ + (!b. FINITE {x | x IN s /\ f(x) = b}) + ==> (g o f) piecewise_differentiable_on s`, + REPEAT GEN_TAC THEN + SIMP_TAC[piecewise_differentiable_on; CONTINUOUS_ON_COMPOSE] THEN + DISCH_THEN(CONJUNCTS_THEN2 + (CONJUNCTS_THEN2 ASSUME_TAC (X_CHOOSE_THEN `ks:real^M->bool` + STRIP_ASSUME_TAC)) + (CONJUNCTS_THEN2 + (CONJUNCTS_THEN2 ASSUME_TAC (X_CHOOSE_THEN `kt:real^N->bool` + STRIP_ASSUME_TAC)) + ASSUME_TAC)) THEN + EXISTS_TAC + `ks UNION + UNIONS(IMAGE (\b. {x | x IN s /\ (f:real^M->real^N) x = b}) kt)` THEN + ASM_SIMP_TAC[FINITE_UNION; FINITE_UNIONS; FINITE_IMAGE] THEN + REWRITE_TAC[UNIONS_IMAGE; FORALL_IN_IMAGE; IN_DIFF; IN_UNION] THEN + ASM_REWRITE_TAC[IN_ELIM_THM; DE_MORGAN_THM] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC DIFFERENTIABLE_CHAIN_AT THEN + CONJ_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM SET_TAC[]);; + +let PIECEWISE_DIFFERENTIABLE_AFFINE = prove + (`!f:real^M->real^N s m c. + f piecewise_differentiable_on (IMAGE (\x. m % x + c) s) + ==> (f o (\x. m % x + c)) piecewise_differentiable_on s`, + REPEAT STRIP_TAC THEN ASM_CASES_TAC `m = &0` THENL + [ASM_REWRITE_TAC[o_DEF; VECTOR_MUL_LZERO] THEN + MATCH_MP_TAC DIFFERENTIABLE_IMP_PIECEWISE_DIFFERENTIABLE THEN + SIMP_TAC[DIFFERENTIABLE_CONST]; + MATCH_MP_TAC PIECEWISE_DIFFERENTIABLE_COMPOSE THEN + ASM_REWRITE_TAC[] THEN CONJ_TAC THENL + [MATCH_MP_TAC DIFFERENTIABLE_IMP_PIECEWISE_DIFFERENTIABLE THEN + SIMP_TAC[DIFFERENTIABLE_ADD; DIFFERENTIABLE_CMUL; DIFFERENTIABLE_CONST; + DIFFERENTIABLE_ID]; + X_GEN_TAC `b:real^M` THEN ASM_SIMP_TAC[VECTOR_AFFINITY_EQ] THEN + MATCH_MP_TAC FINITE_SUBSET THEN + EXISTS_TAC `{inv m % b + --(inv m % c):real^M}` THEN + SIMP_TAC[FINITE_RULES] THEN SET_TAC[]]]);; + +let PIECEWISE_DIFFERENTIABLE_CASES = prove + (`!f g:real^1->real^N a b c. + drop a <= drop c /\ drop c <= drop b /\ f c = g c /\ + f piecewise_differentiable_on interval[a,c] /\ + g piecewise_differentiable_on interval[c,b] + ==> (\x. if drop x <= drop c then f(x) else g(x)) + piecewise_differentiable_on interval[a,b]`, + REPEAT GEN_TAC THEN + REPLICATE_TAC 3 (DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + REWRITE_TAC[piecewise_differentiable_on] THEN + DISCH_THEN(CONJUNCTS_THEN2 + (CONJUNCTS_THEN2 ASSUME_TAC (X_CHOOSE_THEN `s:real^1->bool` + STRIP_ASSUME_TAC)) + (CONJUNCTS_THEN2 ASSUME_TAC (X_CHOOSE_THEN `t:real^1->bool` + STRIP_ASSUME_TAC))) THEN + CONJ_TAC THENL + [SUBGOAL_THEN `interval[a:real^1,b] = interval[a,c] UNION interval[c,b]` + SUBST1_TAC THENL + [REWRITE_TAC[EXTENSION; IN_UNION; IN_INTERVAL_1] THEN + ASM_REAL_ARITH_TAC; + ALL_TAC] THEN + MATCH_MP_TAC CONTINUOUS_ON_CASES THEN + ASM_REWRITE_TAC[CLOSED_INTERVAL; IN_INTERVAL_1] THEN + ASM_MESON_TAC[REAL_LE_ANTISYM; DROP_EQ]; + ALL_TAC] THEN + EXISTS_TAC `(c:real^1) INSERT s UNION t` THEN + ASM_REWRITE_TAC[FINITE_INSERT; FINITE_UNION] THEN + REWRITE_TAC[DE_MORGAN_THM; IN_DIFF; IN_INTERVAL_1; IN_INSERT; IN_UNION] THEN + X_GEN_TAC `x:real^1` THEN STRIP_TAC THEN + DISJ_CASES_TAC(REAL_ARITH `drop x <= drop c \/ drop c <= drop x`) THEN + MATCH_MP_TAC DIFFERENTIABLE_TRANSFORM_AT THENL + [EXISTS_TAC `f:real^1->real^N`; EXISTS_TAC `g:real^1->real^N`] THEN + EXISTS_TAC `dist(x:real^1,c)` THEN ASM_REWRITE_TAC[GSYM DIST_NZ] THEN + (CONJ_TAC THENL + [GEN_TAC THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[dist; NORM_REAL; GSYM drop; DROP_SUB] THEN + ASM_REAL_ARITH_TAC; + FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_REWRITE_TAC[IN_INTERVAL_1; IN_DIFF]]));; + +let PIECEWISE_DIFFERENTIABLE_NEG = prove + (`!f:real^M->real^N s. + f piecewise_differentiable_on s + ==> (\x. --(f x)) piecewise_differentiable_on s`, + REPEAT GEN_TAC THEN REWRITE_TAC[piecewise_differentiable_on] THEN + MATCH_MP_TAC MONO_AND THEN SIMP_TAC[CONTINUOUS_ON_NEG] THEN + MATCH_MP_TAC MONO_EXISTS THEN SIMP_TAC[DIFFERENTIABLE_NEG]);; + +let PIECEWISE_DIFFERENTIABLE_ADD = prove + (`!f g:real^M->real^N s. + f piecewise_differentiable_on s /\ + g piecewise_differentiable_on s + ==> (\x. f x + g x) piecewise_differentiable_on s`, + REPEAT GEN_TAC THEN REWRITE_TAC[piecewise_differentiable_on] THEN + DISCH_THEN(REPEAT_TCL CONJUNCTS_THEN ASSUME_TAC) THEN + ASM_SIMP_TAC[CONTINUOUS_ON_ADD] THEN + FIRST_X_ASSUM(X_CHOOSE_THEN `t:real^M->bool` STRIP_ASSUME_TAC) THEN + FIRST_X_ASSUM(X_CHOOSE_THEN `u:real^M->bool` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `t UNION u :real^M->bool` THEN + ASM_SIMP_TAC[FINITE_UNION; DIFFERENTIABLE_ADD; IN_INTER; + SET_RULE `s DIFF (t UNION u) = (s DIFF t) INTER (s DIFF u)`]);; + +let PIECEWISE_DIFFERENTIABLE_SUB = prove + (`!f g:real^M->real^N s. + f piecewise_differentiable_on s /\ + g piecewise_differentiable_on s + ==> (\x. f x - g x) piecewise_differentiable_on s`, + SIMP_TAC[VECTOR_SUB; PIECEWISE_DIFFERENTIABLE_ADD; + PIECEWISE_DIFFERENTIABLE_NEG]);; + +(* ------------------------------------------------------------------------- *) +(* Valid paths, and their start and finish. *) +(* ------------------------------------------------------------------------- *) + +let valid_path = new_definition + `valid_path (f:real^1->complex) <=> + f piecewise_differentiable_on interval[vec 0,vec 1]`;; + +let closed_path = new_definition + `closed_path g <=> pathstart g = pathfinish g`;; + +let VALID_PATH_COMPOSE = prove + (`!f g. valid_path g /\ f differentiable_on (path_image g) + ==> valid_path (f o g)`, + REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN + REWRITE_TAC[valid_path; piecewise_differentiable_on] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC + (X_CHOOSE_THEN `s:real^1->bool` STRIP_ASSUME_TAC)) THEN + ASM_SIMP_TAC[CONTINUOUS_ON_COMPOSE; DIFFERENTIABLE_IMP_CONTINUOUS_ON] THEN + CONJ_TAC THENL + [MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN + ASM_MESON_TAC[DIFFERENTIABLE_IMP_CONTINUOUS_ON; path_image]; + EXISTS_TAC `{vec 0:real^1,vec 1} UNION s` THEN + ASM_REWRITE_TAC[FINITE_UNION; FINITE_INSERT; FINITE_EMPTY] THEN + REWRITE_TAC[SET_RULE `s DIFF (t UNION u) = (s DIFF t) DIFF u`] THEN + REWRITE_TAC[GSYM OPEN_CLOSED_INTERVAL_1] THEN + X_GEN_TAC `t:real^1` THEN STRIP_TAC THEN + SUBGOAL_THEN + `((f:complex->complex) o (g:real^1->complex)) + differentiable (at t within (interval(vec 0,vec 1) DIFF s))` + MP_TAC THENL + [MATCH_MP_TAC DIFFERENTIABLE_CHAIN_WITHIN THEN CONJ_TAC THENL + [MATCH_MP_TAC DIFFERENTIABLE_AT_WITHIN THEN + FIRST_X_ASSUM MATCH_MP_TAC; + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [differentiable_on]) THEN + DISCH_THEN(MP_TAC o SPEC `(g:real^1->complex) t`) THEN + ANTS_TAC THENL + [REWRITE_TAC[path_image; IN_IMAGE] THEN EXISTS_TAC `t:real^1`; + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] + DIFFERENTIABLE_WITHIN_SUBSET) THEN + REWRITE_TAC[path_image] THEN MATCH_MP_TAC IMAGE_SUBSET]] THEN + MP_TAC(ISPECL [`vec 0:real^1`; `vec 1:real^1`] + INTERVAL_OPEN_SUBSET_CLOSED) THEN ASM SET_TAC[]; + ASM_SIMP_TAC[DIFFERENTIABLE_WITHIN_OPEN; OPEN_DIFF; OPEN_INTERVAL; + FINITE_IMP_CLOSED]]]);; + +(* ------------------------------------------------------------------------- *) +(* In particular, all results for paths apply. *) +(* ------------------------------------------------------------------------- *) + +let VALID_PATH_IMP_PATH = prove + (`!g. valid_path g ==> path g`, + SIMP_TAC[valid_path; path; piecewise_differentiable_on]);; + +let CONNECTED_VALID_PATH_IMAGE = prove + (`!g. valid_path g ==> connected(path_image g)`, + MESON_TAC[CONNECTED_PATH_IMAGE; VALID_PATH_IMP_PATH]);; + +let COMPACT_VALID_PATH_IMAGE = prove + (`!g. valid_path g ==> compact(path_image g)`, + MESON_TAC[COMPACT_PATH_IMAGE; VALID_PATH_IMP_PATH]);; + +let BOUNDED_VALID_PATH_IMAGE = prove + (`!g. valid_path g ==> bounded(path_image g)`, + MESON_TAC[BOUNDED_PATH_IMAGE; VALID_PATH_IMP_PATH]);; + +let CLOSED_VALID_PATH_IMAGE = prove + (`!g. valid_path g ==> closed(path_image g)`, + MESON_TAC[CLOSED_PATH_IMAGE; VALID_PATH_IMP_PATH]);; + +(* ------------------------------------------------------------------------- *) +(* Theorems about rectifiable valid paths. *) +(* ------------------------------------------------------------------------- *) + +let RECTIFIABLE_VALID_PATH = prove + (`!g. valid_path g + ==> (rectifiable_path g <=> + (\t. vector_derivative g (at t)) absolutely_integrable_on + interval [vec 0,vec 1])`, + REWRITE_TAC[valid_path; piecewise_differentiable_on; GSYM path] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC RECTIFIABLE_PATH_DIFFERENTIABLE THEN + ASM_MESON_TAC[FINITE_IMP_COUNTABLE]);; + +let PATH_LENGTH_VALID_PATH = prove + (`!g. valid_path g /\ rectifiable_path g + ==> path_length g = + drop(integral (interval[vec 0,vec 1]) + (\t. lift(norm(vector_derivative g (at t)))))`, + REWRITE_TAC[valid_path; piecewise_differentiable_on; GSYM path] THEN + + REPEAT STRIP_TAC THEN MATCH_MP_TAC PATH_LENGTH_DIFFERENTIABLE THEN + ASM_MESON_TAC[FINITE_IMP_COUNTABLE]);; + +(* ------------------------------------------------------------------------- *) +(* Negligibility of valid_path image *) +(* ------------------------------------------------------------------------- *) + +let NEGLIGIBLE_VALID_PATH_IMAGE = prove + (`!g. valid_path g ==> negligible(path_image g)`, + REWRITE_TAC[piecewise_differentiable_on; piecewise_differentiable_on; + valid_path; path_image] THEN + GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + DISCH_THEN(X_CHOOSE_THEN `k:real^1->bool` STRIP_ASSUME_TAC) THEN + MATCH_MP_TAC NEGLIGIBLE_SUBSET THEN + EXISTS_TAC `IMAGE (g:real^1->real^2) + (k UNION (interval [vec 0,vec 1] DIFF k))` THEN + CONJ_TAC THENL [REWRITE_TAC[IMAGE_UNION]; SET_TAC[]] THEN + ASM_SIMP_TAC[NEGLIGIBLE_UNION_EQ; NEGLIGIBLE_FINITE; FINITE_IMAGE] THEN + MATCH_MP_TAC NEGLIGIBLE_DIFFERENTIABLE_IMAGE_LOWDIM THEN + REWRITE_TAC[DIMINDEX_1; DIMINDEX_2; ARITH] THEN + ASM_SIMP_TAC[DIFFERENTIABLE_AT_IMP_DIFFERENTIABLE_ON]);; + +(* ------------------------------------------------------------------------- *) +(* Integrals along a path (= piecewise differentiable function on [0,1]). *) +(* ------------------------------------------------------------------------- *) + +parse_as_infix("has_path_integral",(12,"right"));; +parse_as_infix("path_integrable_on",(12,"right"));; + +let has_path_integral = define + `(f has_path_integral i) (g) <=> + ((\x. f(g(x)) * vector_derivative g (at x within interval[vec 0,vec 1])) + has_integral i) + (interval[vec 0,vec 1])`;; + +let path_integral = new_definition + `path_integral g f = @i. (f has_path_integral i) (g)`;; + +let path_integrable_on = new_definition + `f path_integrable_on g <=> ?i. (f has_path_integral i) g`;; + +let PATH_INTEGRAL_UNIQUE = prove + (`!f g i. (f has_path_integral i) (g) ==> path_integral(g) f = i`, + REWRITE_TAC[path_integral; has_path_integral; GSYM integral] THEN + MESON_TAC[INTEGRAL_UNIQUE]);; + +let HAS_PATH_INTEGRAL_INTEGRAL = prove + (`!f i. f path_integrable_on i + ==> (f has_path_integral (path_integral i f)) i`, + REWRITE_TAC[path_integral; path_integrable_on] THEN + MESON_TAC[PATH_INTEGRAL_UNIQUE]);; + +let HAS_PATH_INTEGRAL_UNIQUE = prove + (`!f i j g. (f has_path_integral i) g /\ + (f has_path_integral j) g + ==> i = j`, + REWRITE_TAC[has_path_integral] THEN MESON_TAC[HAS_INTEGRAL_UNIQUE]);; + +let HAS_PATH_INTEGRAL_INTEGRABLE = prove + (`!f g i. (f has_path_integral i) g ==> f path_integrable_on g`, + REWRITE_TAC[path_integrable_on] THEN MESON_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* Show that we can forget about the localized derivative. *) +(* ------------------------------------------------------------------------- *) + +let VECTOR_DERIVATIVE_WITHIN_INTERIOR = prove + (`!a b x. + x IN interior(interval[a,b]) + ==> vector_derivative f (at x within interval[a,b]) = + vector_derivative f (at x)`, + SIMP_TAC[vector_derivative; has_vector_derivative; has_derivative; + LIM_WITHIN_INTERIOR; NETLIMIT_WITHIN_INTERIOR; NETLIMIT_AT]);; + +let HAS_INTEGRAL_LOCALIZED_VECTOR_DERIVATIVE = prove + (`((\x. f' (g x) * vector_derivative g (at x within interval [a,b])) + has_integral i) (interval [a,b]) <=> + ((\x. f' (g x) * vector_derivative g (at x)) + has_integral i) (interval [a,b])`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_INTEGRAL_SPIKE_EQ THEN + EXISTS_TAC `{a:real^1,b}` THEN + REWRITE_TAC[NEGLIGIBLE_INSERT; NEGLIGIBLE_EMPTY] THEN + SUBGOAL_THEN `interval[a:real^1,b] DIFF {a,b} = interior(interval[a,b])` + (fun th -> SIMP_TAC[th; VECTOR_DERIVATIVE_WITHIN_INTERIOR]) THEN + REWRITE_TAC[INTERIOR_CLOSED_INTERVAL] THEN + REWRITE_TAC[EXTENSION; IN_DIFF; IN_INTERVAL; IN_INSERT; NOT_IN_EMPTY] THEN + REWRITE_TAC[DIMINDEX_1; FORALL_1; GSYM drop; GSYM DROP_EQ] THEN + REAL_ARITH_TAC);; + +let HAS_PATH_INTEGRAL = prove + (`(f has_path_integral i) g <=> + ((\x. f (g x) * vector_derivative g (at x)) has_integral i) + (interval[vec 0,vec 1])`, + SIMP_TAC[HAS_INTEGRAL_LOCALIZED_VECTOR_DERIVATIVE; has_path_integral]);; + +let PATH_INTEGRABLE_ON = prove + (`f path_integrable_on g <=> + (\t. f(g t) * vector_derivative g (at t)) + integrable_on interval[vec 0,vec 1]`, + REWRITE_TAC[path_integrable_on; HAS_PATH_INTEGRAL; GSYM integrable_on]);; + +(* ------------------------------------------------------------------------- *) +(* Reversing a path. *) +(* ------------------------------------------------------------------------- *) + +let VALID_PATH_REVERSEPATH = prove + (`!g. valid_path(reversepath g) <=> valid_path g`, + SUBGOAL_THEN `!g. valid_path g ==> valid_path(reversepath g)` + (fun th -> MESON_TAC[th; REVERSEPATH_REVERSEPATH]) THEN GEN_TAC THEN + SIMP_TAC[valid_path; piecewise_differentiable_on; GSYM path; + PATH_REVERSEPATH] THEN + DISCH_THEN(CONJUNCTS_THEN2 (K ALL_TAC) MP_TAC) THEN + REWRITE_TAC[IN_DIFF] THEN + DISCH_THEN(X_CHOOSE_THEN `s:real^1->bool` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `IMAGE (\x:real^1. vec 1 - x) s` THEN + ASM_SIMP_TAC[FINITE_IMAGE; reversepath] THEN + REPEAT STRIP_TAC THEN GEN_REWRITE_TAC LAND_CONV [GSYM o_DEF] THEN + MATCH_MP_TAC DIFFERENTIABLE_CHAIN_AT THEN + SIMP_TAC[DIFFERENTIABLE_SUB; DIFFERENTIABLE_CONST; DIFFERENTIABLE_ID] THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN CONJ_TAC THENL + [UNDISCH_TAC `(x:real^1) IN interval[vec 0,vec 1]` THEN + REWRITE_TAC[IN_INTERVAL_1; DROP_SUB; DROP_VEC] THEN REAL_ARITH_TAC; + DISCH_THEN(MP_TAC o ISPEC `\x:real^1. vec 1 - x` o + MATCH_MP FUN_IN_IMAGE) THEN + UNDISCH_TAC `~((x:real^1) IN IMAGE (\x. vec 1 - x) s)` THEN + REWRITE_TAC[VECTOR_ARITH `vec 1 - (vec 1 - x):real^1 = x`]]);; + +let HAS_PATH_INTEGRAL_REVERSEPATH = prove + (`!f g i. valid_path g /\ (f has_path_integral i) g + ==> (f has_path_integral (--i)) (reversepath g)`, + REPEAT GEN_TAC THEN REWRITE_TAC[HAS_PATH_INTEGRAL] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + DISCH_THEN(MP_TAC o C CONJ (REAL_ARITH `~(-- &1 = &0)`)) THEN + DISCH_THEN(MP_TAC o MATCH_MP HAS_INTEGRAL_AFFINITY) THEN + DISCH_THEN(MP_TAC o SPEC `vec 1:real^1`) THEN + REWRITE_TAC[IMAGE_AFFINITY_INTERVAL; INTERVAL_EQ_EMPTY_1; DROP_VEC] THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN + REWRITE_TAC[VECTOR_ARITH `x + --x:real^1 = vec 0`] THEN + REWRITE_TAC[VECTOR_MUL_RZERO; VECTOR_ADD_LID; VECTOR_MUL_LNEG] THEN + REWRITE_TAC[VECTOR_MUL_LID; VECTOR_NEG_NEG; REAL_POW_ONE] THEN + REWRITE_TAC[reversepath; VECTOR_ARITH `-- x + a:real^N = a - x`] THEN + REWRITE_TAC[REAL_INV_1; VECTOR_MUL_LID] THEN + DISCH_THEN(MP_TAC o MATCH_MP HAS_INTEGRAL_NEG) THEN + REWRITE_TAC[VECTOR_SUB_RZERO] THEN + MATCH_MP_TAC(REWRITE_RULE [TAUT `a /\ b /\ c ==> d <=> a /\ b ==> c ==> d`] + HAS_INTEGRAL_SPIKE_FINITE) THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [valid_path]) THEN + REWRITE_TAC[piecewise_differentiable_on] THEN + DISCH_THEN(X_CHOOSE_THEN `s:real^1->bool` STRIP_ASSUME_TAC o CONJUNCT2) THEN + EXISTS_TAC `IMAGE (\x:real^1. vec 1 - x) s` THEN + ASM_SIMP_TAC[FINITE_IMAGE] THEN X_GEN_TAC `x:real^1` THEN STRIP_TAC THEN + ASM_REWRITE_TAC[GSYM COMPLEX_MUL_RNEG] THEN + AP_TERM_TAC THEN MATCH_MP_TAC VECTOR_DERIVATIVE_AT THEN + GEN_REWRITE_TAC (RATOR_CONV o LAND_CONV) [GSYM o_DEF] THEN + ONCE_REWRITE_TAC[VECTOR_ARITH `--x = --(&1) % x`] THEN + REWRITE_TAC[GSYM DROP_VEC; GSYM DROP_NEG] THEN + MATCH_MP_TAC VECTOR_DIFF_CHAIN_AT THEN REWRITE_TAC[] THEN + ONCE_REWRITE_TAC[VECTOR_ARITH `--x:real^N = vec 0 - x`] THEN + SIMP_TAC[HAS_VECTOR_DERIVATIVE_SUB; HAS_VECTOR_DERIVATIVE_CONST; + HAS_VECTOR_DERIVATIVE_ID] THEN + REWRITE_TAC[GSYM VECTOR_DERIVATIVE_WORKS] THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_DIFF]) THEN + REWRITE_TAC[IN_DIFF] THEN MATCH_MP_TAC MONO_AND THEN + REWRITE_TAC[CONTRAPOS_THM; IN_DIFF; IN_INTERVAL_1; DROP_SUB; DROP_VEC] THEN + CONJ_TAC THENL [REAL_ARITH_TAC; ALL_TAC] THEN REWRITE_TAC[IN_IMAGE] THEN + MESON_TAC[VECTOR_ARITH `vec 1 - (vec 1 - x):real^1 = x`]);; + +let PATH_INTEGRABLE_REVERSEPATH = prove + (`!f g. valid_path g /\ f path_integrable_on g + ==> f path_integrable_on (reversepath g)`, + REWRITE_TAC[path_integrable_on] THEN + MESON_TAC[HAS_PATH_INTEGRAL_REVERSEPATH]);; + +let PATH_INTEGRABLE_REVERSEPATH_EQ = prove + (`!f g. valid_path g + ==> (f path_integrable_on (reversepath g) <=> + f path_integrable_on g)`, + MESON_TAC[PATH_INTEGRABLE_REVERSEPATH; VALID_PATH_REVERSEPATH; + REVERSEPATH_REVERSEPATH]);; + +let PATH_INTEGRAL_REVERSEPATH = prove + (`!f g. valid_path g /\ f path_integrable_on g + ==> path_integral (reversepath g) f = --(path_integral g f)`, + MESON_TAC[PATH_INTEGRAL_UNIQUE; HAS_PATH_INTEGRAL_REVERSEPATH; + HAS_PATH_INTEGRAL_INTEGRAL]);; + +(* ------------------------------------------------------------------------- *) +(* Joining two paths together. *) +(* ------------------------------------------------------------------------- *) + +let VALID_PATH_JOIN_EQ = prove + (`!g1 g2. + pathfinish g1 = pathstart g2 + ==> (valid_path(g1 ++ g2) <=> valid_path g1 /\ valid_path g2)`, + REWRITE_TAC[valid_path; piecewise_differentiable_on; GSYM path] THEN + ASM_SIMP_TAC[PATH_JOIN] THEN REPEAT STRIP_TAC THEN + ASM_CASES_TAC `path(g1:real^1->complex)` THEN ASM_REWRITE_TAC[] THEN + ASM_CASES_TAC `path(g2:real^1->complex)` THEN ASM_REWRITE_TAC[] THEN + EQ_TAC THENL + [DISCH_THEN(X_CHOOSE_THEN `s:real^1->bool` STRIP_ASSUME_TAC) THEN + CONJ_TAC THENL + [EXISTS_TAC `(vec 0) INSERT (vec 1) INSERT + {x:real^1 | ((&1 / &2) % x) IN s}` THEN + CONJ_TAC THENL + [REWRITE_TAC[FINITE_INSERT] THEN MATCH_MP_TAC FINITE_IMAGE_INJ THEN + ASM_REWRITE_TAC[] THEN VECTOR_ARITH_TAC; + ALL_TAC] THEN + X_GEN_TAC `x:real^1` THEN + FIRST_X_ASSUM(MP_TAC o SPEC `(&1 / &2) % x:real^1`) THEN + REWRITE_TAC[IN_DIFF; IN_ELIM_THM; IN_INTERVAL_1; DROP_CMUL; DROP_VEC; + IN_INSERT; DE_MORGAN_THM; GSYM DROP_EQ; NOT_EXISTS_THM] THEN + DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN ANTS_TAC THENL + [ASM_REWRITE_TAC[] THEN ASM_REAL_ARITH_TAC; + ALL_TAC] THEN + DISCH_TAC THEN + SUBGOAL_THEN + `(g1:real^1->complex) = (\x. g1 (&2 % x)) o (\x. &1 / &2 % x)` + SUBST1_TAC THENL + [REWRITE_TAC[FUN_EQ_THM; o_THM] THEN GEN_TAC THEN AP_TERM_TAC THEN + VECTOR_ARITH_TAC; + ALL_TAC] THEN + MATCH_MP_TAC DIFFERENTIABLE_CHAIN_AT THEN + SIMP_TAC[DIFFERENTIABLE_CMUL; DIFFERENTIABLE_ID] THEN + MATCH_MP_TAC DIFFERENTIABLE_TRANSFORM_AT THEN + EXISTS_TAC `(g1 ++ g2):real^1->complex` THEN + EXISTS_TAC `dist(&1 / &2 % x:real^1,lift(&1 / &2))` THEN + ASM_REWRITE_TAC[dist; NORM_REAL; GSYM drop; DROP_SUB; DROP_CMUL; + LIFT_DROP] THEN + REWRITE_TAC[joinpaths] THEN + REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + ASM_REAL_ARITH_TAC; + + EXISTS_TAC `(vec 0) INSERT (vec 1) INSERT + {x:real^1 | ((&1 / &2) % (x + vec 1)) IN s}` THEN + CONJ_TAC THENL + [REWRITE_TAC[FINITE_INSERT] THEN MATCH_MP_TAC FINITE_IMAGE_INJ THEN + ASM_REWRITE_TAC[] THEN VECTOR_ARITH_TAC; + ALL_TAC] THEN + X_GEN_TAC `x:real^1` THEN + FIRST_X_ASSUM(MP_TAC o SPEC `(&1 / &2) % (x + vec 1):real^1`) THEN + REWRITE_TAC[IN_DIFF; IN_ELIM_THM; IN_INTERVAL_1; DROP_CMUL; DROP_VEC; + DROP_ADD; IN_INSERT; DE_MORGAN_THM; GSYM DROP_EQ; NOT_EXISTS_THM] THEN + DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN ANTS_TAC THENL + [ASM_REWRITE_TAC[] THEN ASM_REAL_ARITH_TAC; + ALL_TAC] THEN + DISCH_TAC THEN + SUBGOAL_THEN + `(g2:real^1->complex) = + (\x. g2 (&2 % x - vec 1)) o (\x. &1 / &2 % (x + vec 1))` + SUBST1_TAC THENL + [REWRITE_TAC[FUN_EQ_THM; o_THM] THEN GEN_TAC THEN AP_TERM_TAC THEN + VECTOR_ARITH_TAC; + ALL_TAC] THEN + MATCH_MP_TAC DIFFERENTIABLE_CHAIN_AT THEN + SIMP_TAC[DIFFERENTIABLE_CMUL; DIFFERENTIABLE_ADD; + DIFFERENTIABLE_CONST; DIFFERENTIABLE_ID] THEN + MATCH_MP_TAC DIFFERENTIABLE_TRANSFORM_AT THEN + EXISTS_TAC `(g1 ++ g2):real^1->complex` THEN + EXISTS_TAC `dist(&1 / &2 % (x + vec 1):real^1,lift(&1 / &2))` THEN + ASM_REWRITE_TAC[dist; NORM_REAL; GSYM drop; DROP_SUB; DROP_CMUL; + DROP_ADD; DROP_VEC; LIFT_DROP] THEN + REWRITE_TAC[joinpaths] THEN + REPEAT STRIP_TAC THEN REPEAT(COND_CASES_TAC THEN ASM_REWRITE_TAC[]) THEN + ASM_REAL_ARITH_TAC]; + ALL_TAC] THEN + DISCH_THEN(CONJUNCTS_THEN2 + (X_CHOOSE_THEN `s1:real^1->bool` STRIP_ASSUME_TAC) + (X_CHOOSE_THEN `s2:real^1->bool` STRIP_ASSUME_TAC)) THEN + EXISTS_TAC `(&1 / &2 % vec 1:real^1) INSERT + {x:real^1 | (&2 % x) IN s1} UNION + {x:real^1 | (&2 % x - vec 1) IN s2}` THEN + CONJ_TAC THENL + [REWRITE_TAC[FINITE_INSERT; FINITE_UNION] THEN + CONJ_TAC THEN MATCH_MP_TAC FINITE_IMAGE_INJ THEN + ASM_REWRITE_TAC[] THEN VECTOR_ARITH_TAC; + ALL_TAC] THEN + X_GEN_TAC `x:real^1` THEN + REWRITE_TAC[IN_INTERVAL_1; IN_DIFF; DROP_VEC; IN_INSERT; IN_ELIM_THM; + DE_MORGAN_THM; IN_UNION; GSYM DROP_EQ; DROP_CMUL] THEN + STRIP_TAC THEN + REWRITE_TAC[joinpaths] THEN ASM_CASES_TAC `drop x <= &1 / &2` THENL + [MATCH_MP_TAC DIFFERENTIABLE_TRANSFORM_AT THEN + EXISTS_TAC `\x. (g1:real^1->complex)(&2 % x)` THEN + EXISTS_TAC `abs(&1 / &2 - drop x)` THEN + REWRITE_TAC[dist; NORM_REAL; GSYM drop; DROP_SUB; DROP_CMUL; + DROP_ADD; DROP_VEC; LIFT_DROP] THEN + CONJ_TAC THENL + [ASM_REAL_ARITH_TAC; ALL_TAC] THEN + CONJ_TAC THENL + [GEN_TAC THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN + ASM_REAL_ARITH_TAC; + ALL_TAC]; + MATCH_MP_TAC DIFFERENTIABLE_TRANSFORM_AT THEN + EXISTS_TAC `\x. (g2:real^1->complex)(&2 % x - vec 1)` THEN + EXISTS_TAC `abs(&1 / &2 - drop x)` THEN + REWRITE_TAC[dist; NORM_REAL; GSYM drop; DROP_SUB; DROP_CMUL; + DROP_ADD; DROP_VEC; LIFT_DROP] THEN + CONJ_TAC THENL + [ASM_REAL_ARITH_TAC; ALL_TAC] THEN + CONJ_TAC THENL + [GEN_TAC THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN + ASM_REAL_ARITH_TAC; + ALL_TAC]] THEN + GEN_REWRITE_TAC LAND_CONV [GSYM o_DEF] THEN + MATCH_MP_TAC DIFFERENTIABLE_CHAIN_AT THEN + SIMP_TAC[DIFFERENTIABLE_CMUL; DIFFERENTIABLE_SUB; DIFFERENTIABLE_CONST; + DIFFERENTIABLE_ID] THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_REWRITE_TAC[IN_INTERVAL_1; DROP_SUB; IN_DIFF; DROP_VEC; DROP_CMUL] THEN + ASM_REAL_ARITH_TAC);; + +let VALID_PATH_JOIN = prove + (`!g1 g2. + valid_path g1 /\ valid_path g2 /\ pathfinish g1 = pathstart g2 + ==> valid_path(g1 ++ g2)`, + MESON_TAC[VALID_PATH_JOIN_EQ]);; + +let HAS_PATH_INTEGRAL_JOIN = prove + (`!f g1 g2 i1 i2. + (f has_path_integral i1) g1 /\ + (f has_path_integral i2) g2 /\ + valid_path g1 /\ valid_path g2 + ==> (f has_path_integral (i1 + i2)) (g1 ++ g2)`, + REPEAT GEN_TAC THEN REWRITE_TAC[HAS_PATH_INTEGRAL; CONJ_ASSOC] THEN + REPLICATE_TAC 2 (DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC)) THEN + DISCH_THEN(CONJUNCTS_THEN + (MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] HAS_INTEGRAL_AFFINITY))) THEN + DISCH_THEN(ASSUME_TAC o SPECL [`&2`; `--(vec 1):real^1`]) THEN + DISCH_THEN(MP_TAC o SPECL [`&2`; `vec 0:real^1`]) THEN POP_ASSUM MP_TAC THEN + REWRITE_TAC[DIMINDEX_1] THEN CONV_TAC REAL_RAT_REDUCE_CONV THEN + REWRITE_TAC[IMAGE_AFFINITY_INTERVAL] THEN + REWRITE_TAC[INTERVAL_EQ_EMPTY_1; DROP_VEC] THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN + REWRITE_TAC[VECTOR_MUL_RNEG; VECTOR_NEG_NEG; VECTOR_MUL_RZERO; + VECTOR_ADD_LID; VECTOR_NEG_0; VECTOR_ADD_RID; + VECTOR_ARITH `&1 / &2 % x + &1 / &2 % x = x:real^N`] THEN + REWRITE_TAC[DROP_CMUL; DROP_ADD; DROP_NEG; DROP_VEC; VECTOR_MUL_ASSOC] THEN + REWRITE_TAC[VECTOR_ARITH `x % (a + b) + y % b = x % a + (x + y) % b`; + VECTOR_ARITH `x % a + y % (a + b) = (x + y) % a + y % b`] THEN + REWRITE_TAC[REAL_ARITH `(&1 - (&2 * x + --(&1))) * inv(&2) = &1 - x`; + REAL_ARITH `&1 - x + &2 * x + --(&1) = x`; + REAL_ARITH `&1 - &2 * x + (&2 * x) * inv(&2) = &1 - x`; + REAL_ARITH `(&2 * x) * inv(&2) = x`] THEN + REWRITE_TAC[VECTOR_ARITH `b - inv(&2) % (a + b) = inv(&2) % (b - a)`; + VECTOR_ARITH `inv(&2) % (a + b) - a = inv(&2) % (b - a)`] THEN + REPEAT(DISCH_THEN(MP_TAC o SPEC `&2` o MATCH_MP HAS_INTEGRAL_CMUL) THEN + REWRITE_TAC[COMPLEX_CMUL; SIMPLE_COMPLEX_ARITH + `Cx(&2) * Cx(&1 / &2) * j = j /\ + Cx(&2) * (a * Cx(inv(&2)) * b) = a * b`] THEN DISCH_TAC) THEN + MATCH_MP_TAC HAS_INTEGRAL_COMBINE THEN + EXISTS_TAC `&1 / &2 % vec 1:real^1` THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[DROP_CMUL; DROP_VEC] THEN CONV_TAC REAL_RAT_REDUCE_CONV THEN + CONJ_TAC THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE + [TAUT `a1 /\ a2 /\ b ==> c <=> b ==> a1 /\ a2 ==> c`] + HAS_INTEGRAL_SPIKE_FINITE)) THENL + [MP_TAC(REWRITE_RULE[valid_path] (ASSUME `valid_path g1`)); + MP_TAC(REWRITE_RULE[valid_path] (ASSUME `valid_path g2`))] THEN + REWRITE_TAC[piecewise_differentiable_on] THEN + DISCH_THEN(MP_TAC o CONJUNCT2) THEN + DISCH_THEN(X_CHOOSE_THEN `s:real^1->bool` STRIP_ASSUME_TAC) THENL + [EXISTS_TAC `((&1 / &2) % vec 1) INSERT {x:real^1 | (&2 % x) IN s}`; + EXISTS_TAC `((&1 / &2) % vec 1) INSERT + {x:real^1 | (&2 % x - vec 1) IN s}`] THEN + (CONJ_TAC THENL + [REWRITE_TAC[FINITE_INSERT] THEN MATCH_MP_TAC FINITE_IMAGE_INJ THEN + ASM_REWRITE_TAC[] THEN VECTOR_ARITH_TAC; + ALL_TAC]) THEN + ASM_SIMP_TAC[FINITE_IMAGE; FINITE_INSERT; IN_DIFF; IN_INSERT; DE_MORGAN_THM; + joinpaths; IN_INTERVAL_1; DROP_VEC; DROP_CMUL; GSYM DROP_EQ] THEN + SIMP_TAC[REAL_LT_IMP_LE; REAL_MUL_RID; IN_ELIM_THM; + REAL_ARITH `&1 / &2 <= x /\ ~(x = &1 / &2) ==> ~(x <= &1 / &2)`] THEN + REWRITE_TAC[LIFT_CMUL; LIFT_SUB; LIFT_DROP; LIFT_NUM; GSYM VECTOR_SUB] THEN + X_GEN_TAC `x:real^1` THEN STRIP_TAC THEN + MATCH_MP_TAC(COMPLEX_RING `x = Cx(&2) * y ==> g * x = Cx(&2) * g * y`) THEN + MATCH_MP_TAC VECTOR_DERIVATIVE_AT THEN + MATCH_MP_TAC HAS_VECTOR_DERIVATIVE_TRANSFORM_AT THENL + [EXISTS_TAC `(\x. g1(&2 % x)):real^1->complex`; + EXISTS_TAC `(\x. g2(&2 % x - vec 1)):real^1->complex`] THEN + EXISTS_TAC `abs(drop x - &1 / &2)` THEN + REWRITE_TAC[DIST_REAL; GSYM drop; GSYM REAL_ABS_NZ] THEN + ASM_SIMP_TAC[REAL_LT_IMP_NE; REAL_SUB_0] THEN + (CONJ_TAC THENL + [GEN_TAC THEN COND_CASES_TAC THEN REWRITE_TAC[] THEN + ASM_REAL_ARITH_TAC; + ALL_TAC]) THEN + GEN_REWRITE_TAC (RATOR_CONV o LAND_CONV) [GSYM o_DEF] THEN + REWRITE_TAC[GSYM COMPLEX_CMUL] THEN + SUBST1_TAC(SYM(SPEC `2` DROP_VEC)) THEN + MATCH_MP_TAC VECTOR_DIFF_CHAIN_AT THEN + (CONJ_TAC THENL + [TRY(GEN_REWRITE_TAC LAND_CONV [GSYM VECTOR_SUB_RZERO] THEN + MATCH_MP_TAC HAS_VECTOR_DERIVATIVE_SUB THEN + REWRITE_TAC[HAS_VECTOR_DERIVATIVE_CONST]) THEN + REWRITE_TAC[has_vector_derivative] THEN + MATCH_MP_TAC(MESON[HAS_DERIVATIVE_LINEAR] + `f = g /\ linear f ==> (f has_derivative g) net`) THEN + REWRITE_TAC[linear; FUN_EQ_THM; DROP_VEC] THEN + REWRITE_TAC[GSYM DROP_EQ; DROP_ADD; DROP_CMUL; DROP_VEC] THEN + REAL_ARITH_TAC; + REWRITE_TAC[GSYM VECTOR_DERIVATIVE_WORKS] THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_SIMP_TAC[IN_DIFF; IN_INTERVAL_1; DROP_SUB; DROP_CMUL; DROP_VEC] THEN + ASM_REAL_ARITH_TAC]));; + +let PATH_INTEGRABLE_JOIN = prove + (`!f g1 g2. + valid_path g1 /\ valid_path g2 + ==> (f path_integrable_on (g1 ++ g2) <=> + f path_integrable_on g1 /\ f path_integrable_on g2)`, + REPEAT STRIP_TAC THEN EQ_TAC THENL + [ALL_TAC; + REWRITE_TAC[path_integrable_on] THEN + ASM_MESON_TAC[HAS_PATH_INTEGRAL_JOIN]] THEN + RULE_ASSUM_TAC(REWRITE_RULE[valid_path]) THEN + REWRITE_TAC[PATH_INTEGRABLE_ON; joinpaths] THEN REPEAT STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o MATCH_MP + (REWRITE_RULE[IMP_CONJ] INTEGRABLE_ON_SUBINTERVAL)) + THENL + [DISCH_THEN(MP_TAC o SPECL [`lift(&0)`; `lift(&1 / &2)`]); + DISCH_THEN(MP_TAC o SPECL [`lift(&1 / &2)`; `lift(&1)`])] THEN + REWRITE_TAC[SUBSET_INTERVAL_1; DROP_VEC; LIFT_DROP] THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN + DISCH_THEN(MP_TAC o MATCH_MP + (REWRITE_RULE[IMP_CONJ] INTEGRABLE_AFFINITY)) + THENL + [DISCH_THEN(MP_TAC o SPECL [`&1 / &2`; `vec 0:real^1`]); + DISCH_THEN(MP_TAC o SPECL [`&1 / &2`; `lift(&1 / &2)`])] THEN + REWRITE_TAC[] THEN CONV_TAC REAL_RAT_REDUCE_CONV THEN + REWRITE_TAC[IMAGE_AFFINITY_INTERVAL; INTERVAL_EQ_EMPTY_1] THEN + REWRITE_TAC[LIFT_DROP; LIFT_NUM; VECTOR_MUL_RZERO; VECTOR_NEG_0; + GSYM LIFT_CMUL; VECTOR_ADD_RID; VECTOR_MUL_RNEG] THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN REWRITE_TAC[LIFT_NUM] THEN + REWRITE_TAC[VECTOR_ARITH `vec 2 + --vec 1:real^1 = vec 1`; + VECTOR_ARITH `vec 1 + --vec 1:real^1 = vec 0`] THEN + DISCH_THEN(MP_TAC o SPEC `&1 / &2` o MATCH_MP INTEGRABLE_CMUL) THEN + REWRITE_TAC[] THEN MATCH_MP_TAC INTEGRABLE_SPIKE_FINITE THEN + REWRITE_TAC[IN_DIFF; IN_INTERVAL_1; DROP_VEC; DROP_CMUL; DROP_ADD; + LIFT_DROP; COMPLEX_CMUL] THEN + REWRITE_TAC[COMPLEX_RING `a * b = Cx(&1 / &2) * x * y <=> + x * y = a * Cx(&2) * b`] + THENL + [UNDISCH_TAC `(g1:real^1->complex) piecewise_differentiable_on + interval[vec 0,vec 1]`; + UNDISCH_TAC `(g2:real^1->complex) piecewise_differentiable_on + interval[vec 0,vec 1]`] THEN + REWRITE_TAC[piecewise_differentiable_on] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + DISCH_THEN(X_CHOOSE_THEN `s:real^1->bool` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `(vec 0:real^1) INSERT (vec 1) INSERT s` THEN + ASM_REWRITE_TAC[FINITE_INSERT; IN_INSERT; DE_MORGAN_THM] THEN + REWRITE_TAC[GSYM DROP_EQ; DROP_VEC] THEN X_GEN_TAC `t:real^1` THEN + STRIP_TAC THEN BINOP_TAC THENL + [AP_TERM_TAC THEN + ASM_SIMP_TAC[REAL_ARITH `x <= &1 ==> &1 / &2 * x <= &1 / &2`] THEN + AP_TERM_TAC THEN VECTOR_ARITH_TAC; + ALL_TAC; + AP_TERM_TAC THEN ASM_SIMP_TAC[REAL_ARITH + `&0 <= t /\ ~(t = &0) ==> ~(&1 / &2 * t + &1 / &2 <= &1 / &2)`] THEN + AP_TERM_TAC THEN + REWRITE_TAC[GSYM DROP_EQ; DROP_CMUL; DROP_ADD; DROP_SUB; LIFT_DROP] THEN + REWRITE_TAC[DROP_VEC] THEN REAL_ARITH_TAC; + ALL_TAC] THEN + MATCH_MP_TAC VECTOR_DERIVATIVE_AT THEN + MATCH_MP_TAC HAS_VECTOR_DERIVATIVE_TRANSFORM_AT THENL + [EXISTS_TAC `(\x. g1(&2 % x)):real^1->complex` THEN + EXISTS_TAC `abs(drop t - &1) / &2` THEN + ASM_SIMP_TAC[REAL_ARITH `&0 < abs x / &2 <=> ~(x = &0)`; REAL_SUB_0] THEN + REWRITE_TAC[DIST_REAL; GSYM drop; DROP_CMUL] THEN + CONJ_TAC THENL + [ASM_MESON_TAC[REAL_ARITH + `t <= &1 /\ ~(t = &1) /\ abs(x - &1 / &2 * t) < abs(t - &1) / &2 + ==> x <= &1 / &2`]; + ALL_TAC]; + EXISTS_TAC `(\x. g2(&2 % x - vec 1)):real^1->complex` THEN + EXISTS_TAC `abs(drop t) / &2` THEN + ASM_SIMP_TAC[REAL_ARITH `&0 < abs x / &2 <=> ~(x = &0)`; REAL_SUB_0] THEN + REWRITE_TAC[DIST_REAL; GSYM drop; DROP_CMUL; DROP_ADD; LIFT_DROP] THEN + CONJ_TAC THENL + [ASM_MESON_TAC[REAL_ARITH + `&0 <= t /\ abs(x - (&1 / &2 * t + &1 / &2)) < abs(t) / &2 + ==> ~(x <= &1 / &2)`]; + ALL_TAC]] THEN + GEN_REWRITE_TAC (RATOR_CONV o LAND_CONV) [GSYM o_DEF] THEN + REWRITE_TAC[GSYM COMPLEX_CMUL] THEN + SUBST1_TAC(SYM(SPEC `2` DROP_VEC)) THEN + MATCH_MP_TAC VECTOR_DIFF_CHAIN_AT THEN + (CONJ_TAC THENL + [TRY(GEN_REWRITE_TAC LAND_CONV [GSYM VECTOR_SUB_RZERO] THEN + MATCH_MP_TAC HAS_VECTOR_DERIVATIVE_SUB THEN + REWRITE_TAC[HAS_VECTOR_DERIVATIVE_CONST]) THEN + REWRITE_TAC[has_vector_derivative] THEN + MATCH_MP_TAC(MESON[HAS_DERIVATIVE_LINEAR] + `f = g /\ linear f ==> (f has_derivative g) net`) THEN + REWRITE_TAC[linear; FUN_EQ_THM; DROP_VEC] THEN + REWRITE_TAC[GSYM DROP_EQ; DROP_ADD; DROP_CMUL; DROP_VEC] THEN + REAL_ARITH_TAC; + MATCH_MP_TAC(MESON[VECTOR_DERIVATIVE_WORKS] + `f differentiable (at t) /\ t' = t + ==> (f has_vector_derivative + (vector_derivative f (at t))) (at t')`) THEN + CONJ_TAC THENL + [FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_REWRITE_TAC[IN_DIFF; IN_INTERVAL_1; DROP_VEC]; + ALL_TAC] THEN + REWRITE_TAC[GSYM DROP_EQ; DROP_CMUL; DROP_ADD; DROP_SUB; LIFT_DROP; + DROP_VEC] THEN + REAL_ARITH_TAC]));; + +let PATH_INTEGRAL_JOIN = prove + (`!f g1 g2:real^1->complex. + valid_path g1 /\ valid_path g2 /\ + f path_integrable_on g1 /\ f path_integrable_on g2 + ==> path_integral (g1 ++ g2) f = + path_integral g1 f + path_integral g2 f`, + MESON_TAC[PATH_INTEGRAL_UNIQUE; HAS_PATH_INTEGRAL_INTEGRAL; + HAS_PATH_INTEGRAL_JOIN]);; + +(* ------------------------------------------------------------------------- *) +(* Reparametrizing to shift the starting point of a (closed) path. *) +(* ------------------------------------------------------------------------- *) + +let VALID_PATH_SHIFTPATH = prove + (`!g a. valid_path g /\ pathfinish g = pathstart g /\ + a IN interval[vec 0,vec 1] + ==> valid_path(shiftpath a g)`, + REWRITE_TAC[valid_path; shiftpath; DROP_ADD; GSYM DROP_VEC] THEN + REWRITE_TAC[REAL_ARITH `a + x <= y <=> x <= y - a`; GSYM DROP_SUB] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC PIECEWISE_DIFFERENTIABLE_CASES THEN + REPLICATE_TAC 2 (CONJ_TAC THENL + [FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_INTERVAL_1]) THEN + REWRITE_TAC[DROP_SUB; DROP_VEC] THEN REAL_ARITH_TAC; + ALL_TAC]) THEN + RULE_ASSUM_TAC(REWRITE_RULE[pathstart; pathfinish]) THEN + ASM_REWRITE_TAC[VECTOR_ARITH `a + vec 1 - a - vec 1:real^1 = vec 0`; + VECTOR_ARITH `a + vec 1 - a:real^1 = vec 1`] THEN + CONJ_TAC THENL + [ONCE_REWRITE_TAC[VECTOR_ARITH `a + x:real^1 = &1 % x + a`]; + ONCE_REWRITE_TAC[VECTOR_ARITH + `a + x - vec 1:real^1 = &1 % x + (a - vec 1)`]] THEN + GEN_REWRITE_TAC LAND_CONV [GSYM o_DEF] THEN + MATCH_MP_TAC PIECEWISE_DIFFERENTIABLE_AFFINE THEN + MATCH_MP_TAC PIECEWISE_DIFFERENTIABLE_ON_SUBSET THEN + EXISTS_TAC `interval[vec 0:real^1,vec 1]` THEN ASM_REWRITE_TAC[] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_INTERVAL_1]) THEN + REWRITE_TAC[IMAGE_AFFINITY_INTERVAL; REAL_POS; INTERVAL_EQ_EMPTY_1; + IN_INTERVAL_1; DROP_SUB; DROP_VEC] THEN + ONCE_REWRITE_TAC[COND_RAND] THEN ONCE_REWRITE_TAC[COND_RATOR] THEN + REWRITE_TAC[EMPTY_SUBSET; SUBSET_INTERVAL_1; DROP_ADD; DROP_CMUL; + DROP_SUB; DROP_VEC] THEN + REAL_ARITH_TAC);; + +let HAS_PATH_INTEGRAL_SHIFTPATH = prove + (`!f g i a. + (f has_path_integral i) g /\ valid_path g /\ + a IN interval[vec 0,vec 1] + ==> (f has_path_integral i) (shiftpath a g)`, + REWRITE_TAC[HAS_PATH_INTEGRAL; IN_INTERVAL_1; DROP_VEC] THEN + REPEAT STRIP_TAC THEN + SUBGOAL_THEN + `i = integral (interval[a,vec 1]) + (\x. f ((g:real^1->real^2) x) * vector_derivative g (at x)) + + integral (interval[vec 0,a]) + (\x. f (g x) * vector_derivative g (at x))` + SUBST1_TAC THENL + [MATCH_MP_TAC(INST_TYPE [`:1`,`:M`; `:2`,`:N`] HAS_INTEGRAL_UNIQUE) THEN + MAP_EVERY EXISTS_TAC + [`\x. f ((g:real^1->real^2) x) * vector_derivative g (at x)`; + `interval[vec 0:real^1,vec 1]`] THEN + ONCE_REWRITE_TAC[COMPLEX_ADD_SYM] THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC HAS_INTEGRAL_COMBINE THEN EXISTS_TAC `a:real^1` THEN + ASM_REWRITE_TAC[DROP_VEC] THEN + CONJ_TAC THEN MATCH_MP_TAC INTEGRABLE_INTEGRAL THEN + MATCH_MP_TAC INTEGRABLE_SUBINTERVAL THEN + MAP_EVERY EXISTS_TAC [`vec 0:real^1`; `vec 1:real^1`] THEN + (CONJ_TAC THENL [ASM_MESON_TAC[integrable_on]; ALL_TAC]) THEN + REWRITE_TAC[DROP_SUB; DROP_VEC; SUBSET_INTERVAL_1] THEN + ASM_REAL_ARITH_TAC; + ALL_TAC] THEN + MATCH_MP_TAC HAS_INTEGRAL_COMBINE THEN EXISTS_TAC `vec 1 - a:real^1` THEN + ASM_REWRITE_TAC[DROP_SUB; DROP_VEC; REAL_SUB_LE; + REAL_ARITH `&1 - x <= &1 <=> &0 <= x`] THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [valid_path]) THEN + REWRITE_TAC[piecewise_differentiable_on] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + DISCH_THEN(X_CHOOSE_THEN `s:real^1->bool` STRIP_ASSUME_TAC) THEN + REWRITE_TAC[shiftpath] THEN CONJ_TAC THEN + MATCH_MP_TAC HAS_INTEGRAL_SPIKE_FINITE THENL + [EXISTS_TAC `\x. f(g(a + x)) * vector_derivative g (at(a + x))` THEN + EXISTS_TAC `(vec 1 - a) INSERT IMAGE (\x:real^1. x - a) s` THEN + ASM_SIMP_TAC[FINITE_IMAGE; FINITE_INSERT] THEN CONJ_TAC THENL + [X_GEN_TAC `x:real^1` THEN + REWRITE_TAC[IN_DIFF; IN_INTERVAL_1; IN_INSERT; IN_IMAGE; UNWIND_THM2; + DROP_SUB; DROP_ADD; DROP_VEC; DE_MORGAN_THM; + VECTOR_ARITH `x:real^1 = y - a <=> y = a + x`] THEN + REWRITE_TAC[GSYM DROP_EQ; DROP_ADD; DROP_VEC] THEN STRIP_TAC THEN + ASM_SIMP_TAC[REAL_ARITH `x <= &1 - a ==> a + x <= &1`] THEN + AP_TERM_TAC THEN MATCH_MP_TAC VECTOR_DERIVATIVE_AT THEN + MATCH_MP_TAC HAS_VECTOR_DERIVATIVE_TRANSFORM_AT THEN + MAP_EVERY EXISTS_TAC + [`\x. (g:real^1->complex)(a + x)`; `dist(vec 1 - a:real^1,x)`] THEN + SIMP_TAC[CONJ_ASSOC; dist; NORM_REAL; GSYM drop; DROP_VEC; DROP_SUB] THEN + CONJ_TAC THENL + [REPEAT STRIP_TAC THEN REPEAT COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN + ASM_REAL_ARITH_TAC; + ALL_TAC] THEN + GEN_REWRITE_TAC (RATOR_CONV o LAND_CONV) [GSYM o_DEF] THEN + GEN_REWRITE_TAC LAND_CONV [GSYM VECTOR_MUL_LID] THEN + REWRITE_TAC[GSYM DROP_VEC] THEN MATCH_MP_TAC VECTOR_DIFF_CHAIN_AT THEN + SUBST1_TAC(VECTOR_ARITH `vec 1:real^1 = vec 0 + vec 1`) THEN + SIMP_TAC[HAS_VECTOR_DERIVATIVE_ADD; HAS_VECTOR_DERIVATIVE_CONST; + HAS_VECTOR_DERIVATIVE_ID] THEN + REWRITE_TAC[GSYM VECTOR_DERIVATIVE_WORKS] THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_REWRITE_TAC[IN_DIFF; IN_INTERVAL_1; DROP_VEC; DROP_ADD] THEN + ASM_REAL_ARITH_TAC; + ALL_TAC] THEN + SUBGOAL_THEN `(\x. f (g x) * vector_derivative g (at x)) integrable_on + (interval [a,vec 1])` + MP_TAC THENL + [MATCH_MP_TAC INTEGRABLE_SUBINTERVAL THEN + MAP_EVERY EXISTS_TAC [`vec 0:real^1`; `vec 1:real^1`] THEN + CONJ_TAC THENL [ASM_MESON_TAC[integrable_on]; ALL_TAC] THEN + ASM_REWRITE_TAC[DROP_SUB; DROP_VEC; SUBSET_INTERVAL_1; REAL_LE_REFL]; + ALL_TAC] THEN + DISCH_THEN(MP_TAC o C CONJ (REAL_ARITH `~(&1 = &0)`) o MATCH_MP + INTEGRABLE_INTEGRAL) THEN + DISCH_THEN(MP_TAC o SPEC `a:real^1` o MATCH_MP HAS_INTEGRAL_AFFINITY) THEN + REWRITE_TAC[IMAGE_AFFINITY_INTERVAL] THEN + REWRITE_TAC[VECTOR_ARITH `&1 % x + a:real^1 = a + x`] THEN + REWRITE_TAC[REAL_INV_1; REAL_POS; REAL_ABS_NUM; REAL_POW_ONE] THEN + ASM_REWRITE_TAC[INTERVAL_EQ_EMPTY_1; DROP_VEC; GSYM REAL_NOT_LE] THEN + REWRITE_TAC[VECTOR_MUL_LID; GSYM VECTOR_SUB; VECTOR_SUB_REFL]; + EXISTS_TAC `\x. f(g(a + x - vec 1)) * + vector_derivative g (at(a + x - vec 1))` THEN + EXISTS_TAC `(vec 1 - a) INSERT IMAGE (\x:real^1. x - a + vec 1) s` THEN + ASM_SIMP_TAC[FINITE_IMAGE; FINITE_INSERT] THEN CONJ_TAC THENL + [X_GEN_TAC `x:real^1` THEN + REWRITE_TAC[IN_DIFF; IN_INTERVAL_1; IN_INSERT; IN_IMAGE; UNWIND_THM2; + DROP_SUB; DROP_ADD; DROP_VEC; DE_MORGAN_THM; + VECTOR_ARITH `x:real^1 = y - a + z <=> y = a + (x - z)`] THEN + REWRITE_TAC[GSYM DROP_EQ; DROP_ADD; DROP_VEC; DROP_SUB] THEN + STRIP_TAC THEN + ASM_SIMP_TAC[REAL_ARITH + `&1 - a <= x /\ ~(x = &1 - a) ==> ~(a + x <= &1)`] THEN + AP_TERM_TAC THEN MATCH_MP_TAC VECTOR_DERIVATIVE_AT THEN + MATCH_MP_TAC HAS_VECTOR_DERIVATIVE_TRANSFORM_AT THEN + MAP_EVERY EXISTS_TAC + [`\x. (g:real^1->complex)(a + x - vec 1)`; + `dist(vec 1 - a:real^1,x)`] THEN + SIMP_TAC[CONJ_ASSOC; dist; NORM_REAL; GSYM drop; DROP_VEC; DROP_SUB] THEN + CONJ_TAC THENL + [REPEAT STRIP_TAC THEN REPEAT COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN + ASM_REAL_ARITH_TAC; + ALL_TAC] THEN + GEN_REWRITE_TAC (RATOR_CONV o LAND_CONV) [GSYM o_DEF] THEN + GEN_REWRITE_TAC LAND_CONV [GSYM VECTOR_MUL_LID] THEN + REWRITE_TAC[GSYM DROP_VEC] THEN MATCH_MP_TAC VECTOR_DIFF_CHAIN_AT THEN + CONJ_TAC THENL + [GEN_REWRITE_TAC LAND_CONV [GSYM VECTOR_ADD_LID] THEN + ONCE_REWRITE_TAC[VECTOR_ARITH + `a + x - vec 1:real^1 = (a - vec 1) + x`] THEN + SIMP_TAC[HAS_VECTOR_DERIVATIVE_ADD; HAS_VECTOR_DERIVATIVE_CONST; + HAS_VECTOR_DERIVATIVE_ID]; + ALL_TAC] THEN + REWRITE_TAC[GSYM VECTOR_DERIVATIVE_WORKS] THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_SIMP_TAC[IN_DIFF; DROP_SUB; IN_INTERVAL_1; DROP_VEC; DROP_ADD] THEN + ASM_REAL_ARITH_TAC; + ALL_TAC] THEN + SUBGOAL_THEN `(\x. f (g x) * vector_derivative g (at x)) integrable_on + (interval [vec 0,a])` + MP_TAC THENL + [MATCH_MP_TAC INTEGRABLE_SUBINTERVAL THEN + MAP_EVERY EXISTS_TAC [`vec 0:real^1`; `vec 1:real^1`] THEN + CONJ_TAC THENL [ASM_MESON_TAC[integrable_on]; ALL_TAC] THEN + ASM_REWRITE_TAC[DROP_SUB; DROP_VEC; SUBSET_INTERVAL_1; REAL_LE_REFL]; + ALL_TAC] THEN + DISCH_THEN(MP_TAC o C CONJ (REAL_ARITH `~(&1 = &0)`) o MATCH_MP + INTEGRABLE_INTEGRAL) THEN + DISCH_THEN(MP_TAC o SPEC `a - vec 1:real^1` o + MATCH_MP HAS_INTEGRAL_AFFINITY) THEN + REWRITE_TAC[IMAGE_AFFINITY_INTERVAL] THEN + REWRITE_TAC[VECTOR_ARITH `&1 % x + a - vec 1:real^1 = a + x - vec 1`] THEN + REWRITE_TAC[REAL_INV_1; REAL_POS; REAL_ABS_NUM; REAL_POW_ONE] THEN + ASM_REWRITE_TAC[INTERVAL_EQ_EMPTY_1; DROP_VEC; GSYM REAL_NOT_LE] THEN + REWRITE_TAC[VECTOR_MUL_LID; + VECTOR_ARITH `vec 0 + --(a - vec 1):real^1 = vec 1 - a`; + VECTOR_ARITH `a + --(a - vec 1):real^1 = vec 1`]]);; + +let HAS_PATH_INTEGRAL_SHIFTPATH_EQ = prove + (`!f g i a. + valid_path g /\ pathfinish g = pathstart g /\ + a IN interval[vec 0,vec 1] + ==> ((f has_path_integral i) (shiftpath a g) <=> + (f has_path_integral i) g)`, + REPEAT STRIP_TAC THEN EQ_TAC THEN STRIP_TAC THEN + ASM_SIMP_TAC[HAS_PATH_INTEGRAL_SHIFTPATH] THEN + SUBGOAL_THEN + `(f has_path_integral i) (shiftpath (vec 1 - a) (shiftpath a g))` + MP_TAC THENL + [MATCH_MP_TAC HAS_PATH_INTEGRAL_SHIFTPATH THEN + ASM_SIMP_TAC[VALID_PATH_SHIFTPATH] THEN REPEAT(POP_ASSUM MP_TAC) THEN + REWRITE_TAC[IN_INTERVAL_1; DROP_VEC; DROP_SUB] THEN REAL_ARITH_TAC; + ALL_TAC] THEN + REWRITE_TAC[HAS_PATH_INTEGRAL] THEN MATCH_MP_TAC EQ_IMP THEN + MATCH_MP_TAC HAS_INTEGRAL_SPIKE_FINITE_EQ THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [valid_path]) THEN + REWRITE_TAC[piecewise_differentiable_on] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + DISCH_THEN(X_CHOOSE_THEN `s:real^1->bool` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `(s:real^1->bool) UNION {vec 0,vec 1}` THEN + ASM_SIMP_TAC[FINITE_UNION; FINITE_RULES] THEN + REWRITE_TAC[SET_RULE `s DIFF (t UNION u) = (s DIFF u) DIFF t`] THEN + REWRITE_TAC[GSYM OPEN_CLOSED_INTERVAL_1] THEN X_GEN_TAC `x:real^1` THEN + STRIP_TAC THEN BINOP_TAC THEN CONV_TAC SYM_CONV THENL + [AP_TERM_TAC THEN MATCH_MP_TAC SHIFTPATH_SHIFTPATH THEN ASM_SIMP_TAC[] THEN + ASM_MESON_TAC[INTERVAL_OPEN_SUBSET_CLOSED; SUBSET; IN_DIFF]; + ALL_TAC] THEN + MATCH_MP_TAC VECTOR_DERIVATIVE_AT THEN + MATCH_MP_TAC HAS_VECTOR_DERIVATIVE_TRANSFORM_WITHIN_OPEN THEN + MAP_EVERY EXISTS_TAC + [`g:real^1->real^2`; `interval(vec 0,vec 1) DIFF s:real^1->bool`] THEN + ASM_SIMP_TAC[GSYM VECTOR_DERIVATIVE_WORKS; OPEN_DIFF; FINITE_IMP_CLOSED; + OPEN_INTERVAL] THEN + REPEAT STRIP_TAC THENL + [CONV_TAC SYM_CONV THEN MATCH_MP_TAC SHIFTPATH_SHIFTPATH; + FIRST_X_ASSUM MATCH_MP_TAC] THEN + ASM_MESON_TAC[INTERVAL_OPEN_SUBSET_CLOSED; SUBSET; IN_DIFF]);; + +let PATH_INTEGRAL_SHIFTPATH = prove + (`!f g a. valid_path g /\ pathfinish g = pathstart g /\ + a IN interval[vec 0,vec 1] + ==> path_integral (shiftpath a g) f = path_integral g f`, + SIMP_TAC[path_integral; HAS_PATH_INTEGRAL_SHIFTPATH_EQ]);; + +(* ------------------------------------------------------------------------- *) +(* More about straight-line paths. *) +(* ------------------------------------------------------------------------- *) + +let HAS_VECTOR_DERIVATIVE_LINEPATH_WITHIN = prove + (`!a b:complex x s. + (linepath(a,b) has_vector_derivative (b - a)) (at x within s)`, + REPEAT GEN_TAC THEN REWRITE_TAC[linepath; has_vector_derivative] THEN + ONCE_REWRITE_TAC[VECTOR_ARITH `u % (b - a) = vec 0 + u % (b - a)`] THEN + REWRITE_TAC[VECTOR_ARITH `(&1 - u) % a + u % b = a + u % (b - a)`] THEN + MATCH_MP_TAC HAS_DERIVATIVE_ADD THEN REWRITE_TAC[HAS_DERIVATIVE_CONST] THEN + MATCH_MP_TAC HAS_DERIVATIVE_VMUL_DROP THEN REWRITE_TAC[HAS_DERIVATIVE_ID]);; + +let HAS_VECTOR_DERIVATIVE_LINEPATH_AT = prove + (`!a b:complex x. + (linepath(a,b) has_vector_derivative (b - a)) (at x)`, + MESON_TAC[WITHIN_UNIV; HAS_VECTOR_DERIVATIVE_LINEPATH_WITHIN]);; + +let VALID_PATH_LINEPATH = prove + (`!a b. valid_path(linepath(a,b))`, + REPEAT GEN_TAC THEN REWRITE_TAC[valid_path] THEN + MATCH_MP_TAC DIFFERENTIABLE_ON_IMP_PIECEWISE_DIFFERENTIABLE THEN + REWRITE_TAC[differentiable_on; differentiable] THEN + MESON_TAC[HAS_VECTOR_DERIVATIVE_LINEPATH_WITHIN; has_vector_derivative]);; + +let VECTOR_DERIVATIVE_LINEPATH_WITHIN = prove + (`!a b x. x IN interval[vec 0,vec 1] + ==> vector_derivative (linepath(a,b)) + (at x within interval[vec 0,vec 1]) = b - a`, + REPEAT STRIP_TAC THEN + MATCH_MP_TAC VECTOR_DERIVATIVE_WITHIN_CLOSED_INTERVAL THEN + ASM_REWRITE_TAC[HAS_VECTOR_DERIVATIVE_LINEPATH_WITHIN] THEN + REWRITE_TAC[DROP_VEC; REAL_LT_01]);; + +let VECTOR_DERIVATIVE_LINEPATH_AT = prove + (`!a b x. vector_derivative (linepath(a,b)) (at x) = b - a`, + REPEAT STRIP_TAC THEN + MATCH_MP_TAC VECTOR_DERIVATIVE_AT THEN + ASM_REWRITE_TAC[HAS_VECTOR_DERIVATIVE_LINEPATH_AT]);; + +let HAS_PATH_INTEGRAL_LINEPATH = prove + (`!f i a b. (f has_path_integral i) (linepath(a,b)) <=> + ((\x. f(linepath(a,b) x) * (b - a)) has_integral i) + (interval[vec 0,vec 1])`, + REPEAT GEN_TAC THEN REWRITE_TAC[has_path_integral] THEN + MATCH_MP_TAC HAS_INTEGRAL_EQ_EQ THEN + SIMP_TAC[VECTOR_DERIVATIVE_LINEPATH_WITHIN]);; + +let LINEPATH_IN_PATH = prove + (`!x. x IN interval[vec 0,vec 1] ==> linepath(a,b) x IN segment[a,b]`, + REWRITE_TAC[segment; linepath; IN_ELIM_THM; IN_INTERVAL_1; DROP_VEC] THEN + MESON_TAC[]);; + +let RE_LINEPATH_CX = prove + (`!a b x. Re(linepath(Cx a,Cx b) x) = (&1 - drop x) * a + drop x * b`, + REWRITE_TAC[linepath; RE_ADD; COMPLEX_CMUL; RE_MUL_CX; RE_CX]);; + +let IM_LINEPATH_CX = prove + (`!a b x. Im(linepath(Cx a,Cx b) x) = &0`, + REWRITE_TAC[linepath; IM_ADD; COMPLEX_CMUL; IM_MUL_CX; IM_CX] THEN + REAL_ARITH_TAC);; + +let LINEPATH_CX = prove + (`!a b x. linepath(Cx a,Cx b) x = Cx((&1 - drop x) * a + drop x * b)`, + REWRITE_TAC[COMPLEX_EQ; RE_LINEPATH_CX; IM_LINEPATH_CX; RE_CX; IM_CX]);; + +let HAS_PATH_INTEGRAL_TRIVIAL = prove + (`!f a. (f has_path_integral (Cx(&0))) (linepath(a,a))`, + REWRITE_TAC[HAS_PATH_INTEGRAL_LINEPATH; COMPLEX_SUB_REFL; + COMPLEX_MUL_RZERO] THEN + REWRITE_TAC[GSYM COMPLEX_VEC_0; HAS_INTEGRAL_0]);; + +let PATH_INTEGRAL_TRIVIAL = prove + (`!f a. path_integral (linepath(a,a)) f = Cx(&0)`, + MESON_TAC[HAS_PATH_INTEGRAL_TRIVIAL; PATH_INTEGRAL_UNIQUE]);; + +(* ------------------------------------------------------------------------- *) +(* Relation to subpath construction. *) +(* ------------------------------------------------------------------------- *) + +let VALID_PATH_SUBPATH = prove + (`!g u v. valid_path g /\ + u IN interval[vec 0,vec 1] /\ v IN interval[vec 0,vec 1] + ==> valid_path(subpath u v g)`, + SIMP_TAC[valid_path; PATH_SUBPATH] THEN + REPEAT STRIP_TAC THEN REWRITE_TAC[subpath] THEN + ASM_CASES_TAC `v:real^1 = u` THENL + [MATCH_MP_TAC DIFFERENTIABLE_ON_IMP_PIECEWISE_DIFFERENTIABLE THEN + ASM_REWRITE_TAC[VECTOR_SUB_REFL; VECTOR_MUL_LZERO; DROP_VEC] THEN + REWRITE_TAC[DIFFERENTIABLE_ON_CONST]; + MATCH_MP_TAC(REWRITE_RULE[o_DEF] PIECEWISE_DIFFERENTIABLE_COMPOSE) THEN + REPEAT CONJ_TAC THENL + [MATCH_MP_TAC DIFFERENTIABLE_ON_IMP_PIECEWISE_DIFFERENTIABLE THEN + MATCH_MP_TAC DIFFERENTIABLE_AT_IMP_DIFFERENTIABLE_ON THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC DIFFERENTIABLE_ADD THEN + REWRITE_TAC[DIFFERENTIABLE_CONST] THEN + MATCH_MP_TAC DIFFERENTIABLE_CMUL THEN REWRITE_TAC[DIFFERENTIABLE_ID]; + MATCH_MP_TAC PIECEWISE_DIFFERENTIABLE_ON_SUBSET THEN + EXISTS_TAC `interval[vec 0:real^1,vec 1]` THEN ASM_REWRITE_TAC[] THEN + ONCE_REWRITE_TAC[VECTOR_ADD_SYM] THEN + REWRITE_TAC[IMAGE_AFFINITY_INTERVAL] THEN + REPEAT(COND_CASES_TAC THEN REWRITE_TAC[EMPTY_SUBSET]) THEN + REPEAT(FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_INTERVAL_1])) THEN + SIMP_TAC[SUBSET_INTERVAL_1; DROP_ADD; DROP_CMUL; DROP_SUB; DROP_VEC] THEN + REAL_ARITH_TAC; + REWRITE_TAC[GSYM DROP_EQ; DROP_CMUL; DROP_ADD; DROP_SUB] THEN + ASM_SIMP_TAC[DROP_EQ; REAL_FIELD `~(u:real = v) ==> + (u + (v - u) * x = b <=> x = (b - u) / (v - u))`] THEN + X_GEN_TAC `b:real^1` THEN MATCH_MP_TAC FINITE_SUBSET THEN + EXISTS_TAC `{lift((drop b - drop u) / (drop v - drop u))}` THEN + REWRITE_TAC[FINITE_INSERT; FINITE_EMPTY; SUBSET; IN_ELIM_THM] THEN + SIMP_TAC[GSYM LIFT_EQ; LIFT_DROP; IN_SING]]]);; + +let HAS_PATH_INTEGRAL_SUBPATH_REFL = prove + (`!f g u. (f has_path_integral (Cx(&0))) (subpath u u g)`, + REWRITE_TAC[HAS_PATH_INTEGRAL; subpath; VECTOR_SUB_REFL] THEN + REWRITE_TAC[DROP_VEC; VECTOR_MUL_LZERO; VECTOR_DERIVATIVE_CONST_AT] THEN + REWRITE_TAC[COMPLEX_VEC_0; COMPLEX_MUL_RZERO] THEN + REWRITE_TAC[GSYM COMPLEX_VEC_0; HAS_INTEGRAL_0]);; + +let PATH_INTEGRABLE_SUBPATH_REFL = prove + (`!f g u. f path_integrable_on (subpath u u g)`, + REWRITE_TAC[path_integrable_on] THEN + MESON_TAC[HAS_PATH_INTEGRAL_SUBPATH_REFL]);; + +let PATH_INTEGRAL_SUBPATH_REFL = prove + (`!f g u. path_integral (subpath u u g) f = Cx(&0)`, + MESON_TAC[PATH_INTEGRAL_UNIQUE; HAS_PATH_INTEGRAL_SUBPATH_REFL]);; + +let HAS_PATH_INTEGRAL_SUBPATH = prove + (`!f g u v. + valid_path g /\ f path_integrable_on g /\ + u IN interval[vec 0,vec 1] /\ v IN interval[vec 0,vec 1] /\ + drop u <= drop v + ==> (f has_path_integral + integral (interval[u,v]) + (\x. f(g x) * vector_derivative g (at x))) + (subpath u v g)`, + REWRITE_TAC[path_integrable_on; HAS_PATH_INTEGRAL; subpath] THEN + REWRITE_TAC[GSYM integrable_on] THEN REPEAT STRIP_TAC THEN + ASM_CASES_TAC `v:real^1 = u` THENL + [ASM_REWRITE_TAC[INTEGRAL_REFL; VECTOR_SUB_REFL; DROP_VEC] THEN + REWRITE_TAC[VECTOR_MUL_LZERO; VECTOR_DERIVATIVE_CONST_AT] THEN + REWRITE_TAC[COMPLEX_VEC_0; COMPLEX_MUL_RZERO] THEN + REWRITE_TAC[GSYM COMPLEX_VEC_0; HAS_INTEGRAL_0]; + SUBGOAL_THEN `drop u < drop v` ASSUME_TAC THENL + [ASM_REWRITE_TAC[REAL_LT_LE; DROP_EQ]; ALL_TAC]] THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`u:real^1`; `v:real^1`] o + MATCH_MP(REWRITE_RULE[IMP_CONJ] INTEGRABLE_ON_SUBINTERVAL)) THEN + ANTS_TAC THENL + [ASM_MESON_TAC[SUBSET_INTERVAL_1; IN_INTERVAL_1; REAL_LT_IMP_LE]; + REWRITE_TAC[HAS_INTEGRAL_INTEGRAL]] THEN + DISCH_THEN(MP_TAC o SPECL [`drop(v - u)`; `u:real^1`] o + MATCH_MP(REWRITE_RULE[IMP_CONJ] HAS_INTEGRAL_AFFINITY)) THEN + ASM_SIMP_TAC[DROP_SUB; REAL_ARITH `u < v ==> ~(v - u = &0)`] THEN + REWRITE_TAC[IMAGE_AFFINITY_INTERVAL; INTERVAL_EQ_EMPTY_1; DROP_SUB] THEN + ASM_SIMP_TAC[REAL_LE_INV_EQ; REAL_ARITH `u < v ==> ~(v < u) /\ &0 <= v - u`; + VECTOR_ARITH `a % u + --(a % v):real^N = a % (u - v)`] THEN + REWRITE_TAC[VECTOR_SUB_REFL; VECTOR_MUL_RZERO] THEN + SUBGOAL_THEN `inv(drop v - drop u) % (v - u) = vec 1` SUBST1_TAC THENL + [REWRITE_TAC[GSYM DROP_EQ; DROP_VEC; DROP_CMUL; DROP_SUB] THEN + UNDISCH_TAC `drop u < drop v` THEN CONV_TAC REAL_FIELD; + ALL_TAC] THEN + DISCH_THEN(MP_TAC o SPEC `drop(v - u)` o MATCH_MP HAS_INTEGRAL_CMUL) THEN + ASM_SIMP_TAC[real_abs; REAL_LT_IMP_LE; REAL_SUB_LE] THEN + REWRITE_TAC[DIMINDEX_1; REAL_POW_1; VECTOR_MUL_ASSOC; DROP_SUB] THEN + ASM_SIMP_TAC[REAL_FIELD `u < v ==> (v - u) * inv(v - u) = &1`] THEN + REWRITE_TAC[VECTOR_MUL_LID] THEN + MATCH_MP_TAC(REWRITE_RULE[TAUT `a /\ b /\ c ==> d <=> a /\ b ==> c ==> d`] + HAS_INTEGRAL_SPIKE_FINITE) THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [valid_path]) THEN + REWRITE_TAC[piecewise_differentiable_on; IN_DIFF] THEN + DISCH_THEN(X_CHOOSE_THEN `k:real^1->bool` STRIP_ASSUME_TAC o CONJUNCT2) THEN + EXISTS_TAC `{t | ((drop v - drop u) % t + u) IN k}` THEN CONJ_TAC THENL + [MATCH_MP_TAC FINITE_IMAGE_INJ THEN + ASM_REWRITE_TAC[GSYM DROP_EQ; DROP_CMUL; DROP_SUB; DROP_ADD] THEN + UNDISCH_TAC `drop u < drop v` THEN CONV_TAC REAL_FIELD; + ALL_TAC] THEN + ASM_REWRITE_TAC[IN_DIFF; IN_ELIM_THM] THEN + X_GEN_TAC `t:real^1` THEN STRIP_TAC THEN REWRITE_TAC[COMPLEX_CMUL] THEN + ONCE_REWRITE_TAC[COMPLEX_RING `a * b * c:complex = b * a * c`] THEN + REWRITE_TAC[VECTOR_ARITH `x + a % y:real^N = a % y + x`] THEN + AP_TERM_TAC THEN REWRITE_TAC[GSYM COMPLEX_CMUL; GSYM DROP_SUB] THEN + MATCH_MP_TAC HAS_VECTOR_DERIVATIVE_UNIQUE_AT THEN + MATCH_MP_TAC(REWRITE_RULE[o_DEF] VECTOR_DIFF_CHAIN_AT) THEN + REWRITE_TAC[DROP_SUB] THEN CONJ_TAC THENL + [SUBST1_TAC(VECTOR_ARITH `v - u:real^1 = (v - u) + vec 0`) THEN + MATCH_MP_TAC HAS_VECTOR_DERIVATIVE_ADD THEN + REWRITE_TAC[HAS_VECTOR_DERIVATIVE_CONST] THEN + SUBST1_TAC(MESON[LIFT_DROP; LIFT_EQ_CMUL] + `v - u = drop(v - u) % vec 1`) THEN REWRITE_TAC[GSYM DROP_SUB] THEN + MATCH_MP_TAC HAS_VECTOR_DERIVATIVE_CMUL THEN + REWRITE_TAC[HAS_VECTOR_DERIVATIVE_ID]; + REWRITE_TAC[GSYM VECTOR_DERIVATIVE_WORKS] THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[IN_INTERVAL_1] THEN + REPEAT(FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_INTERVAL_1])) THEN + REWRITE_TAC[DROP_ADD; DROP_SUB; DROP_CMUL; DROP_VEC] THEN + REPEAT STRIP_TAC THENL + [MATCH_MP_TAC REAL_LE_ADD THEN CONJ_TAC THEN + TRY(MATCH_MP_TAC REAL_LE_MUL) THEN ASM_REAL_ARITH_TAC; + MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `(drop v - drop u) * &1 + drop u` THEN + ASM_SIMP_TAC[REAL_LE_RADD; REAL_LE_LMUL; + REAL_SUB_LE; REAL_LT_IMP_LE] THEN + ASM_REAL_ARITH_TAC]]);; + +let PATH_INTEGRABLE_SUBPATH = prove + (`!f g u v. + valid_path g /\ f path_integrable_on g /\ + u IN interval[vec 0,vec 1] /\ v IN interval[vec 0,vec 1] + ==> f path_integrable_on (subpath u v g)`, + REPEAT STRIP_TAC THEN DISJ_CASES_TAC(REAL_ARITH + `drop u <= drop v \/ drop v <= drop u`) + THENL + [ASM_MESON_TAC[path_integrable_on; HAS_PATH_INTEGRAL_SUBPATH]; + ONCE_REWRITE_TAC[GSYM REVERSEPATH_SUBPATH] THEN + MATCH_MP_TAC PATH_INTEGRABLE_REVERSEPATH THEN + ASM_SIMP_TAC[VALID_PATH_SUBPATH] THEN + ASM_MESON_TAC[path_integrable_on; HAS_PATH_INTEGRAL_SUBPATH]]);; + +let HAS_INTEGRAL_PATH_INTEGRAL_SUBPATH = prove + (`!f g u v. + valid_path g /\ f path_integrable_on g /\ + u IN interval[vec 0,vec 1] /\ v IN interval[vec 0,vec 1] /\ + drop u <= drop v + ==> (((\x. f(g x) * vector_derivative g (at x))) has_integral + path_integral (subpath u v g) f) + (interval[u,v])`, + REPEAT STRIP_TAC THEN + REWRITE_TAC[HAS_INTEGRAL_INTEGRABLE_INTEGRAL] THEN CONJ_TAC THENL + [MATCH_MP_TAC INTEGRABLE_ON_SUBINTERVAL THEN + EXISTS_TAC `interval[vec 0:real^1,vec 1]` THEN + ASM_REWRITE_TAC[GSYM PATH_INTEGRABLE_ON; SUBSET_INTERVAL_1] THEN + ASM_MESON_TAC[IN_INTERVAL_1]; + CONV_TAC SYM_CONV THEN MATCH_MP_TAC PATH_INTEGRAL_UNIQUE THEN + ASM_SIMP_TAC[HAS_PATH_INTEGRAL_SUBPATH]]);; + +let PATH_INTEGRAL_SUBPATH_INTEGRAL = prove + (`!f g u v. + valid_path g /\ f path_integrable_on g /\ + u IN interval[vec 0,vec 1] /\ v IN interval[vec 0,vec 1] /\ + drop u <= drop v + ==> path_integral (subpath u v g) f = + integral (interval[u,v]) + (\x. f(g x) * vector_derivative g (at x))`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC PATH_INTEGRAL_UNIQUE THEN + ASM_SIMP_TAC[HAS_PATH_INTEGRAL_SUBPATH]);; + +let PATH_INTEGRAL_SUBPATH_COMBINE = prove + (`!f g u v w. + valid_path g /\ f path_integrable_on g /\ + u IN interval[vec 0,vec 1] /\ + v IN interval[vec 0,vec 1] /\ + w IN interval[vec 0,vec 1] + ==> path_integral (subpath u v g) f + path_integral (subpath v w g) f = + path_integral (subpath u w g) f`, + REPLICATE_TAC 3 GEN_TAC THEN + SUBGOAL_THEN + `!u v w. + drop u <= drop v /\ drop v <= drop w + ==> valid_path g /\ f path_integrable_on g /\ + u IN interval[vec 0,vec 1] /\ + v IN interval[vec 0,vec 1] /\ + w IN interval[vec 0,vec 1] + ==> path_integral (subpath u v g) f + + path_integral (subpath v w g) f = + path_integral (subpath u w g) f` + ASSUME_TAC THENL + [ALL_TAC; + REPEAT STRIP_TAC THEN REPEAT_TCL DISJ_CASES_THEN ASSUME_TAC + (REAL_ARITH `drop u <= drop v /\ drop v <= drop w \/ + drop u <= drop w /\ drop w <= drop v \/ + drop v <= drop u /\ drop u <= drop w \/ + drop v <= drop w /\ drop w <= drop u \/ + drop w <= drop u /\ drop u <= drop v \/ + drop w <= drop v /\ drop v <= drop u`) THEN + FIRST_ASSUM(ANTE_RES_THEN MP_TAC) THEN ASM_REWRITE_TAC[] THEN + REPEAT_TCL CONJUNCTS_THEN SUBST1_TAC (MESON[REVERSEPATH_SUBPATH] + `subpath v u (g:real^1->complex) = reversepath(subpath u v g) /\ + subpath w u g = reversepath(subpath u w g) /\ + subpath w v g = reversepath(subpath v w g)`) THEN + ASM_SIMP_TAC[PATH_INTEGRAL_REVERSEPATH; PATH_INTEGRABLE_SUBPATH; + VALID_PATH_REVERSEPATH; VALID_PATH_SUBPATH] THEN + CONV_TAC COMPLEX_RING] THEN + REPEAT GEN_TAC THEN STRIP_TAC THEN + SUBGOAL_THEN `drop u <= drop w` ASSUME_TAC THENL + [ASM_REAL_ARITH_TAC; STRIP_TAC] THEN + ASM_SIMP_TAC[PATH_INTEGRAL_SUBPATH_INTEGRAL] THEN + MATCH_MP_TAC INTEGRAL_COMBINE THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC INTEGRABLE_ON_SUBINTERVAL THEN + EXISTS_TAC `interval[vec 0:real^1,vec 1]` THEN + ASM_REWRITE_TAC[GSYM PATH_INTEGRABLE_ON; SUBSET_INTERVAL_1] THEN + ASM_MESON_TAC[IN_INTERVAL_1]);; + +let PATH_INTEGRAL_INTEGRAL = prove + (`!f g. path_integral g f = + integral (interval [vec 0,vec 1]) + (\x. f (g x) * vector_derivative g (at x))`, + REWRITE_TAC[path_integral; integral; HAS_PATH_INTEGRAL]);; + +(* ------------------------------------------------------------------------- *) +(* Easier to reason about segments via convex hulls. *) +(* ------------------------------------------------------------------------- *) + +let SEGMENTS_SUBSET_CONVEX_HULL = prove + (`!a b c. segment[a,b] SUBSET (convex hull {a,b,c}) /\ + segment[a,c] SUBSET (convex hull {a,b,c}) /\ + segment[b,c] SUBSET (convex hull {a,b,c}) /\ + segment[b,a] SUBSET (convex hull {a,b,c}) /\ + segment[c,a] SUBSET (convex hull {a,b,c}) /\ + segment[c,b] SUBSET (convex hull {a,b,c})`, + REPEAT STRIP_TAC THEN REWRITE_TAC[SEGMENT_CONVEX_HULL] THEN + MATCH_MP_TAC HULL_MONO THEN SET_TAC[]);; + +let MIDPOINTS_IN_CONVEX_HULL = prove + (`!x:real^N s. x IN convex hull s /\ y IN convex hull s + ==> midpoint(x,y) IN convex hull s`, + REPEAT STRIP_TAC THEN REWRITE_TAC[midpoint; VECTOR_ARITH + `inv(&2) % (x + y):real^N = (&1 - inv(&2)) % x + inv(&2) % y`] THEN + MATCH_MP_TAC IN_CONVEX_SET THEN + ASM_REWRITE_TAC[CONVEX_CONVEX_HULL] THEN REAL_ARITH_TAC);; + +let POINTS_IN_CONVEX_HULL = prove + (`!x s. x IN s ==> x IN convex hull s`, + MESON_TAC[SUBSET; HULL_SUBSET]);; + +let CONVEX_HULL_SUBSET = prove + (`(!x. x IN s ==> x IN convex hull t) + ==> (convex hull s) SUBSET (convex hull t)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC HULL_MINIMAL THEN + ASM_REWRITE_TAC[CONVEX_CONVEX_HULL; SUBSET]);; + +let NOT_IN_INTERIOR_CONVEX_HULL_3 = prove + (`!a b c:complex. ~(a IN interior(convex hull {a,b,c})) /\ + ~(b IN interior(convex hull {a,b,c})) /\ + ~(c IN interior(convex hull {a,b,c}))`, + REPEAT GEN_TAC THEN REPEAT CONJ_TAC THEN + MATCH_MP_TAC NOT_IN_INTERIOR_CONVEX_HULL THEN + ASM_SIMP_TAC[CARD_CLAUSES; FINITE_INSERT; FINITE_EMPTY; IN_INSERT] THEN + REWRITE_TAC[DIMINDEX_2] THEN ARITH_TAC);; + +(* ------------------------------------------------------------------------- *) +(* Cauchy's theorem where there's a primitive. *) +(* ------------------------------------------------------------------------- *) + +let PATH_INTEGRAL_PRIMITIVE_LEMMA = prove + (`!f f' g a b s. + ~(interval[a,b] = {}) /\ + (!x. x IN s ==> (f has_complex_derivative f'(x)) (at x within s)) /\ + g piecewise_differentiable_on interval[a,b] /\ + (!x. x IN interval[a,b] ==> g(x) IN s) + ==> ((\x. f'(g x) * vector_derivative g (at x within interval[a,b])) + has_integral (f(g b) - f(g a))) (interval[a,b])`, + REPEAT GEN_TAC THEN REWRITE_TAC[valid_path; piecewise_differentiable_on] THEN + REWRITE_TAC[INTERVAL_EQ_EMPTY_1; REAL_NOT_LT] THEN + DISCH_THEN(REPEAT_TCL CONJUNCTS_THEN ASSUME_TAC) THEN + FIRST_X_ASSUM(X_CHOOSE_THEN `k:real^1->bool` STRIP_ASSUME_TAC) THEN + MATCH_MP_TAC FUNDAMENTAL_THEOREM_OF_CALCULUS_INTERIOR_STRONG THEN + EXISTS_TAC `k:real^1->bool` THEN ASM_REWRITE_TAC[DROP_VEC; REAL_POS] THEN + ASM_SIMP_TAC[FINITE_IMP_COUNTABLE; GSYM o_DEF] THEN CONJ_TAC THENL + [MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC CONTINUOUS_ON_SUBSET THEN EXISTS_TAC `s:complex->bool` THEN + ASM_REWRITE_TAC[SUBSET; FORALL_IN_IMAGE] THEN + MATCH_MP_TAC HOLOMORPHIC_ON_IMP_CONTINUOUS_ON THEN + ASM_MESON_TAC[holomorphic_on]; + ALL_TAC] THEN + X_GEN_TAC `x:real^1` THEN + REPEAT STRIP_TAC THEN REWRITE_TAC[has_vector_derivative; COMPLEX_CMUL] THEN + SUBGOAL_THEN `(f has_complex_derivative f'(g x)) + (at (g x) within (IMAGE g (interval[a:real^1,b])))` + MP_TAC THENL + [MATCH_MP_TAC HAS_COMPLEX_DERIVATIVE_WITHIN_SUBSET THEN + EXISTS_TAC `s:complex->bool` THEN + ASM_REWRITE_TAC[SUBSET; FORALL_IN_IMAGE] THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_MESON_TAC[INTERVAL_OPEN_SUBSET_CLOSED; SUBSET; IN_DIFF]; + ALL_TAC] THEN + SUBGOAL_THEN + `(g:real^1->complex) differentiable (at x within interval[a,b])` + MP_TAC THENL + [MATCH_MP_TAC DIFFERENTIABLE_AT_WITHIN THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_MESON_TAC[INTERVAL_OPEN_SUBSET_CLOSED; SUBSET; IN_DIFF]; + ALL_TAC] THEN + GEN_REWRITE_TAC LAND_CONV [VECTOR_DERIVATIVE_WORKS] THEN + REWRITE_TAC[has_vector_derivative; IMP_IMP; has_complex_derivative] THEN + DISCH_THEN(MP_TAC o MATCH_MP DIFF_CHAIN_WITHIN) THEN + DISCH_THEN(MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + HAS_DERIVATIVE_WITHIN_SUBSET)) THEN + DISCH_THEN(MP_TAC o SPEC `interval(a:real^1,b)`) THEN + RULE_ASSUM_TAC(REWRITE_RULE[IN_DIFF]) THEN + ASM_SIMP_TAC[INTERVAL_OPEN_SUBSET_CLOSED; OPEN_INTERVAL; + HAS_DERIVATIVE_WITHIN_OPEN] THEN + REWRITE_TAC[o_DEF; COMPLEX_CMUL] THEN REWRITE_TAC[COMPLEX_MUL_AC]);; + +let PATH_INTEGRAL_PRIMITIVE = prove + (`!f f' g s. + (!x. x IN s ==> (f has_complex_derivative f'(x)) (at x within s)) /\ + valid_path g /\ (path_image g) SUBSET s + ==> (f' has_path_integral (f(pathfinish g) - f(pathstart g))) (g)`, + REWRITE_TAC[valid_path; path_image; pathfinish; pathstart] THEN + REWRITE_TAC[has_path_integral] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC PATH_INTEGRAL_PRIMITIVE_LEMMA THEN + ASM_REWRITE_TAC[INTERVAL_EQ_EMPTY_1; DROP_VEC; REAL_POS; REAL_NOT_LT] THEN + RULE_ASSUM_TAC(REWRITE_RULE[SUBSET; FORALL_IN_IMAGE]) THEN + ASM_MESON_TAC[]);; + +let CAUCHY_THEOREM_PRIMITIVE = prove + (`!f f' g s. + (!x. x IN s ==> (f has_complex_derivative f'(x)) (at x within s)) /\ + valid_path g /\ (path_image g) SUBSET s /\ + pathfinish g = pathstart g + ==> (f' has_path_integral Cx(&0)) (g)`, + MESON_TAC[PATH_INTEGRAL_PRIMITIVE; COMPLEX_SUB_REFL]);; + +(* ------------------------------------------------------------------------- *) +(* Existence of path integral for continuous function. *) +(* ------------------------------------------------------------------------- *) + +let PATH_INTEGRABLE_CONTINUOUS_LINEPATH = prove + (`!f a b. f continuous_on segment[a,b] + ==> f path_integrable_on (linepath(a,b))`, + REPEAT GEN_TAC THEN REWRITE_TAC[path_integrable_on; has_path_integral] THEN + DISCH_THEN(REPEAT_TCL CONJUNCTS_THEN ASSUME_TAC) THEN + REWRITE_TAC[GSYM integrable_on] THEN MATCH_MP_TAC INTEGRABLE_CONTINUOUS THEN + MATCH_MP_TAC CONTINUOUS_ON_EQ THEN + EXISTS_TAC `\x. f(linepath(a,b) x) * (b - a)` THEN + SIMP_TAC[VECTOR_DERIVATIVE_LINEPATH_WITHIN] THEN + ONCE_REWRITE_TAC[COMPLEX_MUL_SYM] THEN + MATCH_MP_TAC CONTINUOUS_ON_COMPLEX_LMUL THEN + GEN_REWRITE_TAC LAND_CONV [GSYM o_DEF] THEN + MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN + ASM_REWRITE_TAC[GSYM path_image; ETA_AX; PATH_IMAGE_LINEPATH] THEN + REWRITE_TAC[CONTINUOUS_ON_LINEPATH]);; + +(* ------------------------------------------------------------------------- *) +(* A complex-specific theorem for integrals. *) +(* ------------------------------------------------------------------------- *) + +let HAS_INTEGRAL_COMPLEX_CMUL = prove + (`!f y i c. (f has_integral y) i ==> ((\x. c * f(x)) has_integral (c * y)) i`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC + (REWRITE_RULE[o_DEF] HAS_INTEGRAL_LINEAR) THEN + ASM_REWRITE_TAC[linear; COMPLEX_CMUL] THEN CONV_TAC COMPLEX_RING);; + +(* ------------------------------------------------------------------------- *) +(* Arithmetical combining theorems. *) +(* ------------------------------------------------------------------------- *) + +let HAS_PATH_INTEGRAL_CONST_LINEPATH = prove + (`!a b c. ((\x. c) has_path_integral (c * (b - a))) (linepath(a,b))`, + REPEAT GEN_TAC THEN REWRITE_TAC[HAS_PATH_INTEGRAL_LINEPATH] THEN + MP_TAC(ISPECL [`vec 0:real^1`; `vec 1:real^1`; `c * (b - a):complex`] + HAS_INTEGRAL_CONST) THEN + REWRITE_TAC[CONTENT_UNIT; VECTOR_MUL_LID]);; + +let HAS_PATH_INTEGRAL_NEG = prove + (`!f i g. (f has_path_integral i) g + ==> ((\x. --(f x)) has_path_integral (--i)) g`, + REWRITE_TAC[has_path_integral; COMPLEX_MUL_LNEG; HAS_INTEGRAL_NEG]);; + +let HAS_PATH_INTEGRAL_ADD = prove + (`!f1 i1 f2 i2 g. + (f1 has_path_integral i1) g /\ (f2 has_path_integral i2) g + ==> ((\x. f1(x) + f2(x)) has_path_integral (i1 + i2)) g`, + REWRITE_TAC[has_path_integral; COMPLEX_ADD_RDISTRIB] THEN + SIMP_TAC[HAS_INTEGRAL_ADD]);; + +let HAS_PATH_INTEGRAL_SUB = prove + (`!f1 i1 f2 i2 g. + (f1 has_path_integral i1) g /\ (f2 has_path_integral i2) g + ==> ((\x. f1(x) - f2(x)) has_path_integral (i1 - i2)) g`, + REWRITE_TAC[has_path_integral; COMPLEX_SUB_RDISTRIB] THEN + SIMP_TAC[HAS_INTEGRAL_SUB]);; + +let HAS_PATH_INTEGRAL_COMPLEX_LMUL = prove + (`!f g i c. (f has_path_integral i) g + ==> ((\x. c * f x) has_path_integral (c * i)) g`, + REWRITE_TAC[has_path_integral; HAS_INTEGRAL_COMPLEX_CMUL; + GSYM COMPLEX_MUL_ASSOC]);; + +let HAS_PATH_INTEGRAL_COMPLEX_RMUL = prove + (`!f g i c. (f has_path_integral i) g + ==> ((\x. f x * c) has_path_integral (i * c)) g`, + ONCE_REWRITE_TAC[COMPLEX_MUL_SYM] THEN + REWRITE_TAC[HAS_PATH_INTEGRAL_COMPLEX_LMUL]);; + +let HAS_PATH_INTEGRAL_COMPLEX_DIV = prove + (`!f g i c. (f has_path_integral i) g + ==> ((\x. f x / c) has_path_integral (i / c)) g`, + REWRITE_TAC[complex_div; HAS_PATH_INTEGRAL_COMPLEX_RMUL]);; + +let HAS_PATH_INTEGRAL_EQ = prove + (`!f g p y. + (!x. x IN path_image p ==> f x = g x) /\ + (f has_path_integral y) p + ==> (g has_path_integral y) p`, + REPEAT GEN_TAC THEN + REWRITE_TAC[path_image; IN_IMAGE; has_path_integral; IMP_CONJ] THEN + DISCH_TAC THEN MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] HAS_INTEGRAL_EQ) THEN + ASM_SIMP_TAC[] THEN ASM_MESON_TAC[]);; + +let HAS_PATH_INTEGRAL_BOUND_LINEPATH = prove + (`!f i a b B. + (f has_path_integral i) (linepath(a,b)) /\ + &0 <= B /\ (!x. x IN segment[a,b] ==> norm(f x) <= B) + ==> norm(i) <= B * norm(b - a)`, + REPEAT GEN_TAC THEN REWRITE_TAC[has_path_integral] THEN STRIP_TAC THEN + GEN_REWRITE_TAC RAND_CONV [GSYM REAL_MUL_RID] THEN + REWRITE_TAC[GSYM CONTENT_UNIT_1] THEN MATCH_MP_TAC HAS_INTEGRAL_BOUND THEN + EXISTS_TAC `\x. f (linepath (a,b) x) * + vector_derivative (linepath (a,b)) + (at x within interval [vec 0,vec 1])` THEN + ASM_SIMP_TAC[REAL_LE_MUL; NORM_POS_LE; + VECTOR_DERIVATIVE_LINEPATH_WITHIN] THEN + REPEAT STRIP_TAC THEN REWRITE_TAC[COMPLEX_NORM_MUL] THEN + MATCH_MP_TAC REAL_LE_RMUL THEN REWRITE_TAC[NORM_POS_LE] THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN + REWRITE_TAC[GSYM PATH_IMAGE_LINEPATH; path_image] THEN + ASM SET_TAC[]);; + +let HAS_PATH_INTEGRAL_BOUND_LINEPATH_STRONG = prove + (`!f i a b B k. + FINITE k /\ + (f has_path_integral i) (linepath(a,b)) /\ + &0 <= B /\ (!x. x IN segment[a,b] DIFF k ==> norm(f x) <= B) + ==> norm(i) <= B * norm(b - a)`, + REPEAT GEN_TAC THEN ASM_CASES_TAC `b:complex = a` THENL + [ASM_REWRITE_TAC[VECTOR_SUB_REFL; NORM_0; REAL_MUL_RZERO] THEN + STRIP_TAC THEN SUBGOAL_THEN `i = Cx(&0)` + (fun th -> REWRITE_TAC[th; COMPLEX_NORM_0; REAL_LE_REFL]) THEN + MATCH_MP_TAC HAS_PATH_INTEGRAL_UNIQUE THEN + ASM_MESON_TAC[HAS_PATH_INTEGRAL_TRIVIAL]; + STRIP_TAC THEN MATCH_MP_TAC HAS_PATH_INTEGRAL_BOUND_LINEPATH THEN + EXISTS_TAC `\x. if x IN k then Cx(&0) else (f:complex->complex) x` THEN + ASM_REWRITE_TAC[] THEN CONJ_TAC THENL + [ALL_TAC; ASM SET_TAC[COMPLEX_NORM_0]] THEN + UNDISCH_TAC `(f has_path_integral i) (linepath (a,b))` THEN + MATCH_MP_TAC EQ_IMP THEN REWRITE_TAC[has_path_integral] THEN + MATCH_MP_TAC HAS_INTEGRAL_SPIKE_EQ THEN + EXISTS_TAC `{t | t IN interval[vec 0,vec 1] /\ + linepath(a:complex,b) t IN k}` THEN + CONJ_TAC THENL [MATCH_MP_TAC NEGLIGIBLE_FINITE; SET_TAC[]] THEN + MATCH_MP_TAC FINITE_FINITE_PREIMAGE_GENERAL THEN ASM_REWRITE_TAC[] THEN + X_GEN_TAC `c:complex` THEN DISCH_TAC THEN + MATCH_MP_TAC(MESON[FINITE_SING; FINITE_SUBSET] + `(?a. s SUBSET {a}) ==> FINITE s`) THEN + MATCH_MP_TAC(SET_RULE + `(!a b. a IN s /\ b IN s ==> a = b) ==> (?a. s SUBSET {a})`) THEN + MAP_EVERY X_GEN_TAC [`s:real^1`; `t:real^1`] THEN + REWRITE_TAC[IN_ELIM_THM] THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SYM) THEN FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN + REWRITE_TAC[linepath; VECTOR_ARITH + `(&1 - s) % a + s % b:real^N = (&1 - t) % a + t % b <=> + (s - t) % (b - a) = vec 0`] THEN + ASM_REWRITE_TAC[VECTOR_MUL_EQ_0; VECTOR_SUB_EQ; REAL_SUB_0] THEN + REWRITE_TAC[DROP_EQ]]);; + +let HAS_PATH_INTEGRAL_0 = prove + (`!g. ((\x. Cx(&0)) has_path_integral Cx(&0)) g`, + REWRITE_TAC[has_path_integral; COMPLEX_MUL_LZERO] THEN + REWRITE_TAC[GSYM COMPLEX_VEC_0; HAS_INTEGRAL_0]);; + +let HAS_PATH_INTEGRAL_IS_0 = prove + (`!f g. (!z. z IN path_image g ==> f(z) = Cx(&0)) + ==> (f has_path_integral Cx(&0)) g`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_PATH_INTEGRAL_EQ THEN + EXISTS_TAC `\z:complex. Cx(&0)` THEN + ASM_REWRITE_TAC[HAS_PATH_INTEGRAL_0] THEN ASM_MESON_TAC[]);; + +let HAS_PATH_INTEGRAL_VSUM = prove + (`!f p s. FINITE s /\ (!a. a IN s ==> (f a has_path_integral i a) p) + ==> ((\x. vsum s (\a. f a x)) has_path_integral vsum s i) p`, + GEN_TAC THEN GEN_TAC THEN REWRITE_TAC[IMP_CONJ] THEN + MATCH_MP_TAC FINITE_INDUCT_STRONG THEN + SIMP_TAC[VSUM_CLAUSES; HAS_PATH_INTEGRAL_0; COMPLEX_VEC_0; IN_INSERT] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_PATH_INTEGRAL_ADD THEN + ASM_REWRITE_TAC[ETA_AX] THEN CONJ_TAC THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_SIMP_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* Same thing non-relationally. *) +(* ------------------------------------------------------------------------- *) + +let PATH_INTEGRAL_CONST_LINEPATH = prove + (`!a b c. path_integral (linepath(a,b)) (\x. c) = c * (b - a)`, + REPEAT GEN_TAC THEN MATCH_MP_TAC PATH_INTEGRAL_UNIQUE THEN + REWRITE_TAC[HAS_PATH_INTEGRAL_CONST_LINEPATH]);; + +let PATH_INTEGRAL_NEG = prove + (`!f g. f path_integrable_on g + ==> path_integral g (\x. --(f x)) = --(path_integral g f)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC PATH_INTEGRAL_UNIQUE THEN + MATCH_MP_TAC HAS_PATH_INTEGRAL_NEG THEN + ASM_SIMP_TAC[HAS_PATH_INTEGRAL_INTEGRAL]);; + +let PATH_INTEGRAL_ADD = prove + (`!f1 f2 g. + f1 path_integrable_on g /\ f2 path_integrable_on g + ==> path_integral g (\x. f1(x) + f2(x)) = + path_integral g f1 + path_integral g f2`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC PATH_INTEGRAL_UNIQUE THEN + MATCH_MP_TAC HAS_PATH_INTEGRAL_ADD THEN + ASM_SIMP_TAC[HAS_PATH_INTEGRAL_INTEGRAL]);; + +let PATH_INTEGRAL_SUB = prove + (`!f1 f2 g. + f1 path_integrable_on g /\ f2 path_integrable_on g + ==> path_integral g (\x. f1(x) - f2(x)) = + path_integral g f1 - path_integral g f2`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC PATH_INTEGRAL_UNIQUE THEN + MATCH_MP_TAC HAS_PATH_INTEGRAL_SUB THEN + ASM_SIMP_TAC[HAS_PATH_INTEGRAL_INTEGRAL]);; + +let PATH_INTEGRAL_COMPLEX_LMUL = prove + (`!f g c. f path_integrable_on g + ==> path_integral g (\x. c * f x) = c * path_integral g f`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC PATH_INTEGRAL_UNIQUE THEN + MATCH_MP_TAC HAS_PATH_INTEGRAL_COMPLEX_LMUL THEN + ASM_SIMP_TAC[HAS_PATH_INTEGRAL_INTEGRAL]);; + +let PATH_INTEGRAL_COMPLEX_RMUL = prove + (`!f g c. f path_integrable_on g + ==> path_integral g (\x. f x * c) = path_integral g f * c`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC PATH_INTEGRAL_UNIQUE THEN + MATCH_MP_TAC HAS_PATH_INTEGRAL_COMPLEX_RMUL THEN + ASM_SIMP_TAC[HAS_PATH_INTEGRAL_INTEGRAL]);; + +let PATH_INTEGRAL_COMPLEX_DIV = prove + (`!f g c. f path_integrable_on g + ==> path_integral g (\x. f x / c) = path_integral g f / c`, + REWRITE_TAC[complex_div; PATH_INTEGRAL_COMPLEX_RMUL]);; + +let PATH_INTEGRAL_EQ = prove + (`!f g p. + (!x. x IN path_image p ==> f x = g x) + ==> path_integral p f = path_integral p g`, + REPEAT STRIP_TAC THEN REWRITE_TAC[path_integral] THEN + AP_TERM_TAC THEN REWRITE_TAC[FUN_EQ_THM] THEN + ASM_MESON_TAC[HAS_PATH_INTEGRAL_EQ]);; + +let PATH_INTEGRAL_EQ_0 = prove + (`!f g. (!z. z IN path_image g ==> f(z) = Cx(&0)) + ==> path_integral g f = Cx(&0)`, + MESON_TAC[HAS_PATH_INTEGRAL_IS_0; PATH_INTEGRAL_UNIQUE]);; + +let PATH_INTEGRAL_BOUND_LINEPATH = prove + (`!f a b. + f path_integrable_on (linepath(a,b)) /\ + &0 <= B /\ (!x. x IN segment[a,b] ==> norm(f x) <= B) + ==> norm(path_integral (linepath(a,b)) f) <= B * norm(b - a)`, + REPEAT STRIP_TAC THEN + MATCH_MP_TAC HAS_PATH_INTEGRAL_BOUND_LINEPATH THEN + EXISTS_TAC `f:complex->complex` THEN + ASM_SIMP_TAC[HAS_PATH_INTEGRAL_INTEGRAL]);; + +let PATH_INTEGRAL_0 = prove + (`!g. path_integral g (\x. Cx(&0)) = Cx(&0)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC PATH_INTEGRAL_UNIQUE THEN + REWRITE_TAC[HAS_PATH_INTEGRAL_0]);; + +let PATH_INTEGRAL_VSUM = prove + (`!f p s. FINITE s /\ (!a. a IN s ==> (f a) path_integrable_on p) + ==> path_integral p (\x. vsum s (\a. f a x)) = + vsum s (\a. path_integral p (f a))`, + REPEAT STRIP_TAC THEN + MATCH_MP_TAC PATH_INTEGRAL_UNIQUE THEN + MATCH_MP_TAC HAS_PATH_INTEGRAL_VSUM THEN + ASM_SIMP_TAC[HAS_PATH_INTEGRAL_INTEGRAL]);; + +let PATH_INTEGRABLE_EQ = prove + (`!f g p. (!x. x IN path_image p ==> f x = g x) /\ f path_integrable_on p + ==> g path_integrable_on p`, + REWRITE_TAC[path_integrable_on] THEN MESON_TAC[HAS_PATH_INTEGRAL_EQ]);; + +(* ------------------------------------------------------------------------- *) +(* Arithmetic theorems for path integrability. *) +(* ------------------------------------------------------------------------- *) + +let PATH_INTEGRABLE_NEG = prove + (`!f g. f path_integrable_on g + ==> (\x. --(f x)) path_integrable_on g`, + REWRITE_TAC[path_integrable_on] THEN MESON_TAC[HAS_PATH_INTEGRAL_NEG]);; + +let PATH_INTEGRABLE_ADD = prove + (`!f1 f2 g. + f1 path_integrable_on g /\ f2 path_integrable_on g + ==> (\x. f1(x) + f2(x)) path_integrable_on g`, + REWRITE_TAC[path_integrable_on] THEN MESON_TAC[HAS_PATH_INTEGRAL_ADD]);; + +let PATH_INTEGRABLE_SUB = prove + (`!f1 f2 g. + f1 path_integrable_on g /\ f2 path_integrable_on g + ==> (\x. f1(x) - f2(x)) path_integrable_on g`, + REWRITE_TAC[path_integrable_on] THEN MESON_TAC[HAS_PATH_INTEGRAL_SUB]);; + +let PATH_INTEGRABLE_COMPLEX_LMUL = prove + (`!f g c. f path_integrable_on g + ==> (\x. c * f x) path_integrable_on g`, + REWRITE_TAC[path_integrable_on] THEN + MESON_TAC[HAS_PATH_INTEGRAL_COMPLEX_LMUL]);; + +let PATH_INTEGRABLE_COMPLEX_RMUL = prove + (`!f g c. f path_integrable_on g + ==> (\x. f x * c) path_integrable_on g`, + ONCE_REWRITE_TAC[COMPLEX_MUL_SYM] THEN + REWRITE_TAC[PATH_INTEGRABLE_COMPLEX_LMUL]);; + +let PATH_INTEGRABLE_COMPLEX_DIV = prove + (`!f g c. f path_integrable_on g + ==> (\x. f x / c) path_integrable_on g`, + REWRITE_TAC[path_integrable_on] THEN + MESON_TAC[HAS_PATH_INTEGRAL_COMPLEX_DIV]);; + +let PATH_INTEGRABLE_VSUM = prove + (`!f g s. FINITE s /\ (!a. a IN s ==> f a path_integrable_on g) + ==> (\x. vsum s (\a. f a x)) path_integrable_on g`, + REWRITE_TAC[path_integrable_on] THEN + MESON_TAC[HAS_PATH_INTEGRAL_VSUM]);; + +(* ------------------------------------------------------------------------- *) +(* Considering a path integral "backwards". *) +(* ------------------------------------------------------------------------- *) + +let HAS_PATH_INTEGRAL_REVERSE_LINEPATH = prove + (`!f a b i. + (f has_path_integral i) (linepath(a,b)) + ==> (f has_path_integral (--i)) (linepath(b,a))`, + MESON_TAC[REVERSEPATH_LINEPATH; VALID_PATH_LINEPATH; + HAS_PATH_INTEGRAL_REVERSEPATH]);; + +let PATH_INTEGRAL_REVERSE_LINEPATH = prove + (`!f a b. + f continuous_on (segment[a,b]) + ==> path_integral(linepath(a,b)) f = + --(path_integral(linepath(b,a)) f)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC PATH_INTEGRAL_UNIQUE THEN + MATCH_MP_TAC HAS_PATH_INTEGRAL_REVERSE_LINEPATH THEN + MATCH_MP_TAC HAS_PATH_INTEGRAL_INTEGRAL THEN + MATCH_MP_TAC PATH_INTEGRABLE_CONTINUOUS_LINEPATH THEN + ASM_MESON_TAC[SEGMENT_SYM]);; + +(* ------------------------------------------------------------------------- *) +(* Splitting a path integral in a flat way. *) +(* ------------------------------------------------------------------------- *) + +let HAS_PATH_INTEGRAL_SPLIT = prove + (`!f a b c i j k. + &0 <= k /\ k <= &1 /\ c - a = k % (b - a) /\ + (f has_path_integral i) (linepath(a,c)) /\ + (f has_path_integral j) (linepath(c,b)) + ==> (f has_path_integral (i + j)) (linepath(a,b))`, + REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + ASM_CASES_TAC `k = &0` THENL + [ASM_REWRITE_TAC[VECTOR_MUL_LZERO; VECTOR_SUB_EQ] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN ASM_REWRITE_TAC[] THEN + ASM_MESON_TAC[HAS_PATH_INTEGRAL_TRIVIAL; PATH_INTEGRAL_UNIQUE; + COMPLEX_ADD_LID]; + ALL_TAC] THEN + ASM_CASES_TAC `k = &1` THEN ASM_REWRITE_TAC[VECTOR_MUL_LID] THENL + [REWRITE_TAC[VECTOR_ARITH `c - a = b - a <=> c = b:real^N`] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN ASM_REWRITE_TAC[] THEN + ASM_MESON_TAC[HAS_PATH_INTEGRAL_TRIVIAL; PATH_INTEGRAL_UNIQUE; + COMPLEX_ADD_RID]; + ALL_TAC] THEN + REWRITE_TAC[HAS_PATH_INTEGRAL_LINEPATH] THEN + REWRITE_TAC[linepath] THEN REPEAT GEN_TAC THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + DISCH_THEN(CONJUNCTS_THEN + (MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] HAS_INTEGRAL_AFFINITY))) THEN + DISCH_THEN(ASSUME_TAC o SPECL + [`inv(&1 - k):real`; `--(k / (&1 - k)) % vec 1:real^1`]) THEN + DISCH_THEN(MP_TAC o SPECL [`inv(k):real`; `vec 0:real^1`]) THEN + POP_ASSUM MP_TAC THEN ASM_REWRITE_TAC[REAL_INV_EQ_0; REAL_SUB_0] THEN + REWRITE_TAC[REAL_INV_INV; DIMINDEX_1; REAL_POW_1; REAL_ABS_INV] THEN + REWRITE_TAC[IMAGE_AFFINITY_INTERVAL] THEN + REWRITE_TAC[INTERVAL_EQ_EMPTY_1; DROP_VEC] THEN + ASM_REWRITE_TAC[REAL_SUB_LE; REAL_ARITH `~(&1 < &0)`] THEN + REWRITE_TAC[VECTOR_MUL_RZERO; VECTOR_NEG_0; VECTOR_ADD_RID] THEN + REWRITE_TAC[VECTOR_MUL_ASSOC; VECTOR_MUL_LNEG] THEN + ASM_SIMP_TAC[REAL_FIELD + `~(k = &1) ==> (&1 - k) * --(k / (&1 - k)) = --k`] THEN + REWRITE_TAC[VECTOR_ADD_LID; VECTOR_MUL_LNEG; VECTOR_NEG_NEG; + VECTOR_ARITH `(&1 - k) % x + k % x:real^1 = x`] THEN + REWRITE_TAC[DROP_ADD; DROP_CMUL; DROP_NEG; DROP_VEC; REAL_MUL_RID] THEN + FIRST_X_ASSUM(SUBST1_TAC o MATCH_MP (VECTOR_ARITH + `c - a = x ==> c = x + a`)) THEN + REWRITE_TAC[VECTOR_ARITH `b - (k % (b - a) + a) = (&1 - k) % (b - a)`] THEN + SUBGOAL_THEN + `!x. (&1 - (inv (&1 - k) * drop x + --(k / (&1 - k)))) % (k % (b - a) + a) + + (inv (&1 - k) * drop x + --(k / (&1 - k))) % b = + (&1 - drop x) % a + drop x % b` + (fun th -> REWRITE_TAC[th]) THENL + [REWRITE_TAC[VECTOR_ARITH + `x % (k % (b - a) + a) + y % b = + (x * (&1 - k)) % a + (y + x * k) % b`] THEN + GEN_TAC THEN BINOP_TAC THEN BINOP_TAC THEN REWRITE_TAC[] THEN + REPEAT(POP_ASSUM MP_TAC) THEN CONV_TAC REAL_FIELD; + ALL_TAC] THEN + SUBGOAL_THEN + `!x. (&1 - inv k * drop x) % a + (inv k * drop x) % (k % (b - a) + a) = + (&1 - drop x) % a + drop x % b` + (fun th -> REWRITE_TAC[th]) THENL + [REWRITE_TAC[VECTOR_ARITH + `x % a + y % (k % (b - a) + a) = + (x + y * (&1 - k)) % a + (y * k) % b`] THEN + GEN_TAC THEN BINOP_TAC THEN BINOP_TAC THEN REWRITE_TAC[] THEN + REPEAT(POP_ASSUM MP_TAC) THEN CONV_TAC REAL_FIELD; + ALL_TAC] THEN + DISCH_TAC THEN + DISCH_THEN(MP_TAC o SPEC `inv(k:real)` o MATCH_MP HAS_INTEGRAL_CMUL) THEN + FIRST_ASSUM(MP_TAC o SPEC `inv(&1 - k)` o MATCH_MP HAS_INTEGRAL_CMUL) THEN + ASM_SIMP_TAC[REAL_ARITH `&0 <= k ==> abs k = k`; + REAL_ARITH `k <= &1 ==> abs(&1 - k) = &1 - k`] THEN + ASM_SIMP_TAC[VECTOR_MUL_ASSOC; REAL_MUL_LINV; REAL_SUB_0] THEN + REWRITE_TAC[IMP_IMP; VECTOR_MUL_LID] THEN + REWRITE_TAC[COMPLEX_CMUL] THEN + ONCE_REWRITE_TAC[COMPLEX_RING + `Cx(inv a) * b * Cx(a) * c = (Cx(inv a) * Cx a) * b * c`] THEN + ASM_SIMP_TAC[GSYM CX_MUL; REAL_MUL_LINV; REAL_SUB_0; COMPLEX_MUL_LID] THEN + STRIP_TAC THEN + MATCH_MP_TAC HAS_INTEGRAL_COMBINE THEN EXISTS_TAC `k % vec 1:real^1` THEN + ASM_REWRITE_TAC[DROP_CMUL; DROP_VEC; REAL_MUL_RID]);; + +let PATH_INTEGRAL_SPLIT = prove + (`!f a b c k. + &0 <= k /\ k <= &1 /\ c - a = k % (b - a) /\ + f continuous_on (segment[a,b]) + ==> path_integral(linepath(a,b)) f = + path_integral(linepath(a,c)) f + + path_integral(linepath(c,b)) f`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC PATH_INTEGRAL_UNIQUE THEN + MATCH_MP_TAC HAS_PATH_INTEGRAL_SPLIT THEN + MAP_EVERY EXISTS_TAC [`c:complex`; `k:real`] THEN ASM_REWRITE_TAC[] THEN + CONJ_TAC THEN MATCH_MP_TAC HAS_PATH_INTEGRAL_INTEGRAL THEN + MATCH_MP_TAC PATH_INTEGRABLE_CONTINUOUS_LINEPATH THEN + MATCH_MP_TAC CONTINUOUS_ON_SUBSET THEN + EXISTS_TAC `segment[a:complex,b]` THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[SEGMENT_CONVEX_HULL] THEN MATCH_MP_TAC CONVEX_HULL_SUBSET THEN + REWRITE_TAC[IN_INSERT; NOT_IN_EMPTY] THEN REPEAT STRIP_TAC THEN + ASM_SIMP_TAC[POINTS_IN_CONVEX_HULL; IN_INSERT] THEN + FIRST_ASSUM(SUBST1_TAC o MATCH_MP (VECTOR_ARITH + `c - a = k % (b - a) ==> c = (&1 - k) % a + k % b`)) THEN + MATCH_MP_TAC IN_CONVEX_SET THEN + ASM_SIMP_TAC[CONVEX_CONVEX_HULL; POINTS_IN_CONVEX_HULL; IN_INSERT]);; + +let PATH_INTEGRAL_SPLIT_LINEPATH = prove + (`!f a b c. + f continuous_on segment[a,b] /\ c IN segment[a,b] + ==> path_integral(linepath (a,b)) f = + path_integral(linepath (a,c)) f + + path_integral(linepath (c,b)) f`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC PATH_INTEGRAL_SPLIT THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_SEGMENT]) THEN + MATCH_MP_TAC MONO_EXISTS THEN REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + VECTOR_ARITH_TAC);; + +(* ------------------------------------------------------------------------- *) +(* The special case of midpoints used in the main quadrisection. *) +(* ------------------------------------------------------------------------- *) + +let HAS_PATH_INTEGRAL_MIDPOINT = prove + (`!f a b i j. + (f has_path_integral i) (linepath(a,midpoint(a,b))) /\ + (f has_path_integral j) (linepath(midpoint(a,b),b)) + ==> (f has_path_integral (i + j)) (linepath(a,b))`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_PATH_INTEGRAL_SPLIT THEN + MAP_EVERY EXISTS_TAC [`midpoint(a:complex,b)`; `&1 / &2`] THEN + ASM_REWRITE_TAC[] THEN CONV_TAC REAL_RAT_REDUCE_CONV THEN + REWRITE_TAC[midpoint] THEN VECTOR_ARITH_TAC);; + +let PATH_INTEGRAL_MIDPOINT = prove + (`!f a b. + f continuous_on (segment[a,b]) + ==> path_integral(linepath(a,b)) f = + path_integral(linepath(a,midpoint(a,b))) f + + path_integral(linepath(midpoint(a,b),b)) f`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC PATH_INTEGRAL_SPLIT THEN + EXISTS_TAC `&1 / &2` THEN + ASM_REWRITE_TAC[] THEN CONV_TAC REAL_RAT_REDUCE_CONV THEN + REWRITE_TAC[midpoint] THEN VECTOR_ARITH_TAC);; + +(* ------------------------------------------------------------------------- *) +(* A couple of special case lemmas that are useful below. *) +(* ------------------------------------------------------------------------- *) + +let TRIANGLE_LINEAR_HAS_CHAIN_INTEGRAL = prove + (`!a b c m d. ((\x. m * x + d) has_path_integral Cx(&0)) + (linepath(a,b) ++ linepath(b,c) ++ linepath(c,a))`, + REPEAT GEN_TAC THEN MATCH_MP_TAC CAUCHY_THEOREM_PRIMITIVE THEN + MAP_EVERY EXISTS_TAC [`\x. m / Cx(&2) * x pow 2 + d * x`; `(:complex)`] THEN + SIMP_TAC[PATHSTART_JOIN; PATHFINISH_JOIN; PATHSTART_LINEPATH; SUBSET_UNIV; + PATHFINISH_LINEPATH; VALID_PATH_JOIN; VALID_PATH_LINEPATH] THEN + REPEAT STRIP_TAC THEN COMPLEX_DIFF_TAC THEN CONV_TAC NUM_REDUCE_CONV THEN + CONV_TAC COMPLEX_RING);; + +let HAS_CHAIN_INTEGRAL_CHAIN_INTEGRAL = prove + (`!f i a b c d. + (f has_path_integral i) + (linepath(a,b) ++ linepath(b,c) ++ linepath(c,d)) + ==> path_integral (linepath(a,b)) f + + path_integral (linepath(b,c)) f + + path_integral (linepath(c,d)) f = i`, + REPEAT STRIP_TAC THEN + FIRST_ASSUM(SUBST1_TAC o SYM o MATCH_MP PATH_INTEGRAL_UNIQUE) THEN + FIRST_X_ASSUM(MP_TAC o MATCH_MP HAS_PATH_INTEGRAL_INTEGRABLE) THEN + SIMP_TAC[PATH_INTEGRABLE_JOIN; VALID_PATH_LINEPATH; VALID_PATH_JOIN; + PATHSTART_JOIN; PATHFINISH_JOIN; PATHSTART_LINEPATH; + PATHFINISH_LINEPATH] THEN + STRIP_TAC THEN CONV_TAC SYM_CONV THEN MATCH_MP_TAC PATH_INTEGRAL_UNIQUE THEN + REPEAT(MATCH_MP_TAC HAS_PATH_INTEGRAL_JOIN THEN + SIMP_TAC[VALID_PATH_LINEPATH; VALID_PATH_JOIN; + PATHSTART_JOIN; PATHFINISH_JOIN; PATHSTART_LINEPATH; + PATHFINISH_LINEPATH] THEN + CONJ_TAC) THEN + MATCH_MP_TAC HAS_PATH_INTEGRAL_INTEGRAL THEN ASM_REWRITE_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* Reversing the order in a double path integral. The condition is *) +(* stronger than needed but it's often true in typical situations. *) +(* ------------------------------------------------------------------------- *) + +let PATH_INTEGRAL_SWAP = prove + (`!f g h. + (\y. f (fstcart y) (sndcart y)) continuous_on + (path_image g PCROSS path_image h) /\ + valid_path g /\ valid_path h /\ + (\t. vector_derivative g (at t)) continuous_on interval[vec 0,vec 1] /\ + (\t. vector_derivative h (at t)) continuous_on interval[vec 0,vec 1] + ==> path_integral g (\w. path_integral h (f w)) = + path_integral h (\z. path_integral g (\w. f w z))`, + REWRITE_TAC[PCROSS] THEN REPEAT STRIP_TAC THEN + ONCE_REWRITE_TAC[PATH_INTEGRAL_INTEGRAL] THEN MATCH_MP_TAC EQ_TRANS THEN + EXISTS_TAC + `integral (interval[vec 0,vec 1]) + (\x. path_integral h + (\y. f (g x) y * vector_derivative g (at x)))` THEN + CONJ_TAC THENL + [MATCH_MP_TAC INTEGRAL_EQ THEN X_GEN_TAC `x:real^1` THEN + DISCH_TAC THEN REWRITE_TAC[] THEN + CONV_TAC SYM_CONV THEN MATCH_MP_TAC PATH_INTEGRAL_COMPLEX_RMUL THEN + REWRITE_TAC[PATH_INTEGRABLE_ON] THEN + MATCH_MP_TAC INTEGRABLE_CONTINUOUS THEN + MATCH_MP_TAC CONTINUOUS_ON_COMPLEX_MUL THEN ASM_REWRITE_TAC[] THEN + SUBGOAL_THEN + `(\t:real^1. (f:complex->complex->complex) (g x) (h t)) = + (\y. f (fstcart y) (sndcart y)) o + (\t. pastecart (g(x:real^1)) (h t))` + SUBST1_TAC THENL + [REWRITE_TAC[o_DEF; FSTCART_PASTECART; SNDCART_PASTECART]; + ALL_TAC] THEN + MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN CONJ_TAC THENL + [MATCH_MP_TAC CONTINUOUS_ON_PASTECART THEN + ASM_SIMP_TAC[CONTINUOUS_ON_CONST; GSYM path; VALID_PATH_IMP_PATH]; + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET)) THEN + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; IN_ELIM_PASTECART_THM] THEN + ASM_SIMP_TAC[path_image; FUN_IN_IMAGE]]; + ALL_TAC] THEN + MATCH_MP_TAC EQ_TRANS THEN EXISTS_TAC + `integral (interval[vec 0,vec 1]) + (\y. path_integral g + (\x. f x (h y) * vector_derivative h (at y)))` THEN + CONJ_TAC THENL + [ALL_TAC; + MATCH_MP_TAC INTEGRAL_EQ THEN X_GEN_TAC `y:real^1` THEN + DISCH_TAC THEN REWRITE_TAC[] THEN + MATCH_MP_TAC PATH_INTEGRAL_COMPLEX_RMUL THEN + REWRITE_TAC[PATH_INTEGRABLE_ON] THEN + MATCH_MP_TAC INTEGRABLE_CONTINUOUS THEN + MATCH_MP_TAC CONTINUOUS_ON_COMPLEX_MUL THEN ASM_REWRITE_TAC[] THEN + SUBGOAL_THEN + `(\t:real^1. (f:complex->complex->complex) (g t) (h y)) = + (\z. f (fstcart z) (sndcart z)) o + (\t. pastecart (g t) (h(y:real^1)))` + SUBST1_TAC THENL + [REWRITE_TAC[o_DEF; FSTCART_PASTECART; SNDCART_PASTECART]; + ALL_TAC] THEN + MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN CONJ_TAC THENL + [MATCH_MP_TAC CONTINUOUS_ON_PASTECART THEN + ASM_SIMP_TAC[CONTINUOUS_ON_CONST; GSYM path; VALID_PATH_IMP_PATH]; + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET)) THEN + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; IN_ELIM_PASTECART_THM] THEN + ASM_SIMP_TAC[path_image; FUN_IN_IMAGE]]] THEN + REWRITE_TAC[PATH_INTEGRAL_INTEGRAL] THEN + W(MP_TAC o PART_MATCH (lhand o rand) + INTEGRAL_SWAP_CONTINUOUS o lhs o snd) THEN + REWRITE_TAC[] THEN ANTS_TAC THENL + [ALL_TAC; + DISCH_THEN(fun th -> GEN_REWRITE_TAC LAND_CONV [th]) THEN + REPEAT(MATCH_MP_TAC INTEGRAL_EQ THEN + REWRITE_TAC[] THEN REPEAT STRIP_TAC) THEN + REWRITE_TAC[COMPLEX_MUL_AC]] THEN + REPEAT(MATCH_MP_TAC CONTINUOUS_ON_COMPLEX_MUL THEN CONJ_TAC) THENL + [ALL_TAC; + SUBGOAL_THEN + `(\z:real^(1,1)finite_sum. vector_derivative g (at (fstcart z))) = + (\t. vector_derivative (g:real^1->complex) (at t)) o fstcart` + SUBST1_TAC THENL [REWRITE_TAC[o_DEF]; ALL_TAC] THEN + MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN + SIMP_TAC[LINEAR_CONTINUOUS_ON; LINEAR_FSTCART] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET)) THEN + SIMP_TAC[SUBSET; FORALL_IN_IMAGE; IN_ELIM_PASTECART_THM; PCROSS; + FORALL_PASTECART; GSYM PCROSS_INTERVAL; FSTCART_PASTECART]; + SUBGOAL_THEN + `(\z:real^(1,1)finite_sum. vector_derivative h (at (sndcart z))) = + (\t. vector_derivative (h:real^1->complex) (at t)) o sndcart` + SUBST1_TAC THENL [REWRITE_TAC[o_DEF]; ALL_TAC] THEN + MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN + SIMP_TAC[LINEAR_CONTINUOUS_ON; LINEAR_SNDCART] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET)) THEN + SIMP_TAC[SUBSET; FORALL_IN_IMAGE; IN_ELIM_PASTECART_THM; PCROSS; + FORALL_PASTECART; GSYM PCROSS_INTERVAL; SNDCART_PASTECART]] THEN + SUBGOAL_THEN + `(\z. f (g (fstcart z)) (h (sndcart z))) = + (\y. (f:complex->complex->complex) (fstcart y) (sndcart y)) o + (\p. pastecart (g(fstcart p:real^1)) (h(sndcart p:real^1)))` + SUBST1_TAC THENL + [REWRITE_TAC[o_DEF; FSTCART_PASTECART; SNDCART_PASTECART]; ALL_TAC] THEN + MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN CONJ_TAC THENL + [MATCH_MP_TAC CONTINUOUS_ON_PASTECART THEN + CONJ_TAC THEN GEN_REWRITE_TAC LAND_CONV [GSYM o_DEF] THEN + MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN + SIMP_TAC[LINEAR_CONTINUOUS_ON; LINEAR_FSTCART; LINEAR_SNDCART] THEN + REWRITE_TAC[GSYM PCROSS_INTERVAL; PCROSS; GSYM SIMPLE_IMAGE] THEN + REWRITE_TAC[FSTCART_PASTECART; SNDCART_PASTECART; + SET_RULE `{f x | x IN {g a b | P a /\ Q b}} = + {f(g a b) | P a /\ Q b}`] THEN + REPEAT(FIRST_X_ASSUM(ASSUME_TAC o REWRITE_RULE[path] o + MATCH_MP VALID_PATH_IMP_PATH)) THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET)) THEN + SIMP_TAC[SUBSET; FORALL_IN_GSPEC]; + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET)) THEN + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; IN_ELIM_PASTECART_THM; + FORALL_PASTECART; GSYM PCROSS_INTERVAL; PCROSS; + path_image; FSTCART_PASTECART; SNDCART_PASTECART] THEN + SIMP_TAC[FUN_IN_IMAGE]]);; + +(* ------------------------------------------------------------------------- *) +(* The key quadrisection step. *) +(* ------------------------------------------------------------------------- *) + +let NORM_SUM_LEMMA = prove + (`norm(a + b + c + d:complex) >= e + ==> norm(a) >= e / &4 \/ + norm(b) >= e / &4 \/ + norm(c) >= e / &4 \/ + norm(d) >= e / &4`, + NORM_ARITH_TAC);; + +let CAUCHY_THEOREM_QUADRISECTION = prove + (`!f a b c e K. + f continuous_on (convex hull {a,b,c}) /\ + dist (a,b) <= K /\ + dist (b,c) <= K /\ + dist (c,a) <= K /\ + norm(path_integral(linepath(a,b)) f + + path_integral(linepath(b,c)) f + + path_integral(linepath(c,a)) f) >= e * K pow 2 + ==> ?a' b' c'. a' IN convex hull {a,b,c} /\ + b' IN convex hull {a,b,c} /\ + c' IN convex hull {a,b,c} /\ + dist(a',b') <= K / &2 /\ + dist(b',c') <= K / &2 /\ + dist(c',a') <= K / &2 /\ + norm(path_integral(linepath(a',b')) f + + path_integral(linepath(b',c')) f + + path_integral(linepath(c',a')) f) + >= e * (K / &2) pow 2`, + REPEAT STRIP_TAC THEN MAP_EVERY ABBREV_TAC + [`a':complex = midpoint(b,c)`; + `b':complex = midpoint(c,a)`; + `c':complex = midpoint(a,b)`] THEN + SUBGOAL_THEN + `path_integral(linepath(a,b)) f + + path_integral(linepath(b,c)) f + + path_integral(linepath(c,a)) f = + (path_integral(linepath(a,c')) f + + path_integral(linepath(c',b')) f + + path_integral(linepath(b',a)) f) + + (path_integral(linepath(a',c')) f + + path_integral(linepath(c',b)) f + + path_integral(linepath(b,a')) f) + + (path_integral(linepath(a',c)) f + + path_integral(linepath(c,b')) f + + path_integral(linepath(b',a')) f) + + (path_integral(linepath(a',b')) f + + path_integral(linepath(b',c')) f + + path_integral(linepath(c',a')) f)` + SUBST_ALL_TAC THENL + [MP_TAC(SPEC `f:complex->complex` PATH_INTEGRAL_MIDPOINT) THEN DISCH_THEN + (fun th -> MP_TAC(SPECL [`a:complex`; `b:complex`] th) THEN + MP_TAC(SPECL [`b:complex`; `c:complex`] th) THEN + MP_TAC(SPECL [`c:complex`; `a:complex`] th)) THEN + MP_TAC(SPEC `f:complex->complex` PATH_INTEGRAL_REVERSE_LINEPATH) THEN DISCH_THEN + (fun th -> MP_TAC(SPECL [`a':complex`; `b':complex`] th) THEN + MP_TAC(SPECL [`b':complex`; `c':complex`] th) THEN + MP_TAC(SPECL [`c':complex`; `a':complex`] th)) THEN + ASM_REWRITE_TAC[] THEN + REPEAT(MATCH_MP_TAC(TAUT + `((a /\ c ==> b /\ d) ==> e) ==> (a ==> b) ==> (c ==> d) ==> e`)) THEN + ANTS_TAC THENL [ALL_TAC; CONV_TAC COMPLEX_RING] THEN + REWRITE_TAC[SEGMENT_CONVEX_HULL] THEN + REPEAT CONJ_TAC THEN MATCH_MP_TAC CONTINUOUS_ON_SUBSET THEN + EXISTS_TAC `convex hull {a:complex,b,c}` THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC CONVEX_HULL_SUBSET THEN + SIMP_TAC[IN_INSERT; NOT_IN_EMPTY; + TAUT `(a \/ b ==> c) <=> (a ==> c) /\ (b ==> c)`] THEN + MAP_EVERY EXPAND_TAC ["a'"; "b'"; "c'"] THEN + SIMP_TAC[MIDPOINTS_IN_CONVEX_HULL; POINTS_IN_CONVEX_HULL; IN_INSERT]; + ALL_TAC] THEN + REWRITE_TAC[REAL_ARITH `e * (K / &2) pow 2 = (e * K pow 2) / &4`] THEN + FIRST_X_ASSUM(MP_TAC o MATCH_MP NORM_SUM_LEMMA) THEN STRIP_TAC THENL + [MAP_EVERY EXISTS_TAC [`a:complex`; `c':complex`; `b':complex`]; + MAP_EVERY EXISTS_TAC [`a':complex`; `c':complex`; `b:complex`]; + MAP_EVERY EXISTS_TAC [`a':complex`; `c:complex`; `b':complex`]; + MAP_EVERY EXISTS_TAC [`a':complex`; `b':complex`; `c':complex`]] THEN + ASM_REWRITE_TAC[] THEN + MAP_EVERY EXPAND_TAC ["a'"; "b'"; "c'"] THEN + SIMP_TAC[MIDPOINTS_IN_CONVEX_HULL; POINTS_IN_CONVEX_HULL; IN_INSERT] THEN + REWRITE_TAC[midpoint; dist; GSYM VECTOR_SUB_LDISTRIB; + VECTOR_ARITH `a - inv(&2) % (a + b) = inv(&2) % (a - b)`; + VECTOR_ARITH `inv(&2) % (c + a) - a = inv(&2) % (c - a)`; + VECTOR_ARITH `(a + b) - (c + a) = b - c`; + VECTOR_ARITH `(b + c) - (c + a) = b - a`] THEN + SIMP_TAC[NORM_MUL; REAL_ARITH `abs(inv(&2)) * x <= k / &2 <=> x <= k`] THEN + ASM_REWRITE_TAC[GSYM dist] THEN ASM_MESON_TAC[DIST_SYM]);; + +(* ------------------------------------------------------------------------- *) +(* Yet at small enough scales this cannot be the case. *) +(* ------------------------------------------------------------------------- *) + +let TRIANGLE_POINTS_CLOSER = prove + (`!a b c x y:real^N. + x IN convex hull {a,b,c} /\ + y IN convex hull {a,b,c} + ==> norm(x - y) <= norm(a - b) \/ + norm(x - y) <= norm(b - c) \/ + norm(x - y) <= norm(c - a)`, + REPEAT STRIP_TAC THEN MP_TAC(ISPEC `{a:real^N,b,c}` SIMPLEX_EXTREMAL_LE) THEN + REWRITE_TAC[FINITE_INSERT; FINITE_RULES; NOT_INSERT_EMPTY] THEN + REWRITE_TAC[IN_INSERT; NOT_IN_EMPTY] THEN + REPEAT STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`x:real^N`; `y:real^N`]) THEN + ASM_REWRITE_TAC[VECTOR_SUB_REFL; NORM_0] THEN + ASM_MESON_TAC[NORM_POS_LE; REAL_LE_TRANS; NORM_SUB]);; + +let HOLOMORPHIC_POINT_SMALL_TRIANGLE = prove + (`!f s x e. + x IN s /\ f continuous_on s /\ + f complex_differentiable (at x within s) /\ + &0 < e + ==> ?k. &0 < k /\ + !a b c. dist(a,b) <= k /\ dist(b,c) <= k /\ dist(c,a) <= k /\ + x IN convex hull {a,b,c} /\ convex hull {a,b,c} SUBSET s + ==> norm(path_integral(linepath(a,b)) f + + path_integral(linepath(b,c)) f + + path_integral(linepath(c,a)) f) + <= e * (dist(a,b) + dist(b,c) + dist(c,a)) pow 2`, + REPEAT STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [complex_differentiable]) THEN + DISCH_THEN(X_CHOOSE_THEN `f':complex` MP_TAC) THEN + GEN_REWRITE_TAC LAND_CONV [has_complex_derivative] THEN + REWRITE_TAC[HAS_DERIVATIVE_WITHIN_ALT] THEN + DISCH_THEN(MP_TAC o SPEC `e:real` o CONJUNCT2) THEN + ASM_SIMP_TAC[REAL_LT_DIV; REAL_OF_NUM_LT; ARITH] THEN + GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) + [TAUT `a /\ b ==> c <=> b ==> a ==> c`] THEN + REWRITE_TAC[APPROACHABLE_LT_LE] THEN + ONCE_REWRITE_TAC[TAUT `b ==> a ==> c <=> a /\ b ==> c`] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `d:real` THEN STRIP_TAC THEN + ASM_REWRITE_TAC[dist] THEN + MAP_EVERY X_GEN_TAC [`a:complex`; `b:complex`; `c:complex`] THEN + STRIP_TAC THEN + SUBGOAL_THEN + `path_integral (linepath(a,b)) f + + path_integral (linepath(b,c)) f + + path_integral (linepath(c,a)) f = + path_integral (linepath(a,b)) (\y. f y - f x - f' * (y - x)) + + path_integral (linepath(b,c)) (\y. f y - f x - f' * (y - x)) + + path_integral (linepath(c,a)) (\y. f y - f x - f' * (y - x))` + SUBST1_TAC THENL + [SUBGOAL_THEN + `path_integral (linepath(a,b)) (\y. f y - f x - f' * (y - x)) = + path_integral (linepath(a,b)) f - + path_integral (linepath(a,b)) (\y. f x + f' * (y - x)) /\ + path_integral (linepath(b,c)) (\y. f y - f x - f' * (y - x)) = + path_integral (linepath(b,c)) f - + path_integral (linepath(b,c)) (\y. f x + f' * (y - x)) /\ + path_integral (linepath(c,a)) (\y. f y - f x - f' * (y - x)) = + path_integral (linepath(c,a)) f - + path_integral (linepath(c,a)) (\y. f x + f' * (y - x))` + (REPEAT_TCL CONJUNCTS_THEN SUBST1_TAC) THENL + [REWRITE_TAC[SIMPLE_COMPLEX_ARITH `a - b - c = a - (b + c)`] THEN + REPEAT CONJ_TAC THEN MATCH_MP_TAC PATH_INTEGRAL_UNIQUE THEN + MATCH_MP_TAC HAS_PATH_INTEGRAL_SUB THEN + CONJ_TAC THEN MATCH_MP_TAC HAS_PATH_INTEGRAL_INTEGRAL THEN + MATCH_MP_TAC PATH_INTEGRABLE_CONTINUOUS_LINEPATH THEN + MATCH_MP_TAC CONTINUOUS_ON_SUBSET THEN + EXISTS_TAC `s:complex->bool` THEN + ASM_SIMP_TAC[CONTINUOUS_ON_ID; CONTINUOUS_ON_ADD; CONTINUOUS_ON_CONST; + CONTINUOUS_ON_COMPLEX_MUL; CONTINUOUS_ON_SUB] THEN + MATCH_MP_TAC SUBSET_TRANS THEN + EXISTS_TAC `convex hull {a:complex,b,c}` THEN + ASM_REWRITE_TAC[SEGMENT_CONVEX_HULL] THEN + MATCH_MP_TAC CONVEX_HULL_SUBSET THEN + REWRITE_TAC[IN_INSERT; NOT_IN_EMPTY] THEN REPEAT STRIP_TAC THEN + ASM_SIMP_TAC[MIDPOINTS_IN_CONVEX_HULL; POINTS_IN_CONVEX_HULL; IN_INSERT]; + ALL_TAC] THEN + REWRITE_TAC[COMPLEX_RING + `x + y + z = (x - x') + (y - y') + (z - z') <=> + x' + y' + z' = Cx(&0)`] THEN + MP_TAC(ISPECL [`a:complex`; `b:complex`; `c:complex`; + `f':complex`; `f x - f' * x`] + TRIANGLE_LINEAR_HAS_CHAIN_INTEGRAL) THEN + REWRITE_TAC[COMPLEX_RING + `f' * x' + f x - f' * x = f x + f' * (x' - x)`] THEN + DISCH_THEN(MP_TAC o MATCH_MP HAS_CHAIN_INTEGRAL_CHAIN_INTEGRAL) THEN + REWRITE_TAC[]; + ALL_TAC] THEN + ONCE_REWRITE_TAC[NORM_SUB] THEN MATCH_MP_TAC(REAL_ARITH + `&0 <= x * y /\ &0 <= x * z /\ &0 <= y * z /\ + a <= (e * (x + y + z)) * x + + (e * (x + y + z)) * y + + (e * (x + y + z)) * z + ==> a <= e * (x + y + z) pow 2`) THEN + SIMP_TAC[REAL_LE_MUL; NORM_POS_LE] THEN + REPEAT(MATCH_MP_TAC NORM_TRIANGLE_LE THEN + MATCH_MP_TAC REAL_LE_ADD2 THEN CONJ_TAC) THEN + (MATCH_MP_TAC HAS_PATH_INTEGRAL_BOUND_LINEPATH THEN + EXISTS_TAC `\y:complex. f y - f x - f' * (y - x)` THEN + ASM_SIMP_TAC[REAL_LE_MUL; REAL_LE_ADD; REAL_LT_IMP_LE; NORM_POS_LE] THEN + CONJ_TAC THENL + [MATCH_MP_TAC HAS_PATH_INTEGRAL_INTEGRAL THEN + MATCH_MP_TAC PATH_INTEGRABLE_CONTINUOUS_LINEPATH THEN + MATCH_MP_TAC CONTINUOUS_ON_SUBSET THEN EXISTS_TAC `s:complex->bool` THEN + ASM_SIMP_TAC[CONTINUOUS_ON_SUB; ETA_AX; CONTINUOUS_ON_COMPLEX_MUL; + CONTINUOUS_ON_CONST; CONTINUOUS_ON_ID] THEN + MATCH_MP_TAC SUBSET_TRANS THEN + EXISTS_TAC `convex hull {a:complex,b,c}` THEN + ASM_REWRITE_TAC[SEGMENT_CONVEX_HULL] THEN + MATCH_MP_TAC CONVEX_HULL_SUBSET THEN + REWRITE_TAC[IN_INSERT; NOT_IN_EMPTY] THEN REPEAT STRIP_TAC THEN + ASM_SIMP_TAC[MIDPOINTS_IN_CONVEX_HULL; POINTS_IN_CONVEX_HULL; IN_INSERT]; + ALL_TAC] THEN + X_GEN_TAC `y:complex` THEN STRIP_TAC THEN + MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `e * norm(y - x:complex)` THEN CONJ_TAC THENL + [FIRST_X_ASSUM MATCH_MP_TAC THEN CONJ_TAC THENL + [MATCH_MP_TAC(SET_RULE `!t. y IN t /\ t SUBSET s ==> y IN s`) THEN + EXISTS_TAC `convex hull {a:complex,b,c}` THEN ASM_REWRITE_TAC[]; + MATCH_MP_TAC(REAL_ARITH + `!n1 n2 n3. n1 <= d /\ n2 <= d /\ n3 <= d /\ + (n <= n1 \/ n <= n2 \/ n <= n3) + ==> n <= d`) THEN + MAP_EVERY EXISTS_TAC + [`norm(a - b:complex)`; `norm(b - c:complex)`; + `norm(c - a:complex)`] THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC TRIANGLE_POINTS_CLOSER]; + ASM_SIMP_TAC[REAL_LE_LMUL_EQ] THEN + ONCE_REWRITE_TAC[NORM_SUB] THEN + MATCH_MP_TAC(REAL_ARITH + `(x <= a \/ x <= b \/ x <= c) /\ (&0 <= a /\ &0 <= b /\ &0 <= c) + ==> x <= a + b + c`) THEN + REWRITE_TAC[NORM_POS_LE] THEN MATCH_MP_TAC TRIANGLE_POINTS_CLOSER THEN + ASM_REWRITE_TAC[]] THEN + REPEAT CONJ_TAC THEN + FIRST_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE + `x IN s ==> s SUBSET t ==> x IN t`)) THEN + REWRITE_TAC[SEGMENT_CONVEX_HULL] THEN MATCH_MP_TAC CONVEX_HULL_SUBSET THEN + REWRITE_TAC[IN_INSERT; NOT_IN_EMPTY] THEN REPEAT STRIP_TAC THEN + ASM_SIMP_TAC[MIDPOINTS_IN_CONVEX_HULL; POINTS_IN_CONVEX_HULL; + IN_INSERT]));; + +(* ------------------------------------------------------------------------- *) +(* Hence the most basic theorem for a triangle. *) +(* ------------------------------------------------------------------------- *) + +let CAUCHY_THEOREM_TRIANGLE = prove + (`!f a b c. + f holomorphic_on (convex hull {a,b,c}) + ==> (f has_path_integral Cx(&0)) + (linepath(a,b) ++ linepath(b,c) ++ linepath(c,a))`, + let lemma1 = prove + (`!P Q abc. + P abc 0 /\ + (!abc:A n. P abc n ==> ?abc'. P abc' (SUC n) /\ Q abc' abc) + ==> ?ABC. ABC 0 = abc /\ !n. P (ABC n) n /\ Q (ABC(SUC n)) (ABC n)`, + REPEAT STRIP_TAC THEN + (MP_TAC o prove_recursive_functions_exist num_RECURSION) + `ABC 0 = abc:A /\ + !n. ABC(SUC n) = @abc. P abc (SUC n) /\ Q abc (ABC n)` THEN + MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC THEN + STRIP_TAC THEN CONJ_TAC THENL [ASM_REWRITE_TAC[]; ALL_TAC] THEN + REWRITE_TAC[FORALL_AND_THM] THEN + MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN CONJ_TAC THENL + [INDUCT_TAC THEN ASM_REWRITE_TAC[] THEN ASM_MESON_TAC[]; ALL_TAC] THEN + DISCH_TAC THEN ASM_REWRITE_TAC[] THEN ASM_MESON_TAC[]) in + let lemma3 = prove + (`!P Q a:A b:A c:A. + P a b c 0 /\ + (!a b c n. P a b c n + ==> ?a' b' c'. P a' b' c' (SUC n) /\ Q a' b' c' a b c) + ==> ?A B C. A 0 = a /\ B 0 = b /\ C 0 = c /\ + !n. P (A n) (B n) (C n) n /\ + Q (A(SUC n)) (B(SUC n)) (C(SUC n)) (A n) (B n) (C n)`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL + [`\(a,b,c). (P:A->A->A->num->bool) a b c`; + `\(a,b,c) (a',b',c'). (Q:A->A->A->A->A->A->bool) a b c a' b' c'`; + `(a:A,b:A,c:A)`] + lemma1) THEN + REWRITE_TAC[FORALL_PAIR_THM; EXISTS_PAIR_THM] THEN + ANTS_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN + DISCH_THEN(X_CHOOSE_THEN `ABC:num->A#A#A` STRIP_ASSUME_TAC) THEN + MAP_EVERY EXISTS_TAC + [`(\(a,b,c). a) o (ABC:num->A#A#A)`; + `(\(a,b,c). b) o (ABC:num->A#A#A)`; + `(\(a,b,c). c) o (ABC:num->A#A#A)`] THEN + REWRITE_TAC[o_THM] THEN + REPEAT(CONJ_TAC THENL [ASM_REWRITE_TAC[]; ALL_TAC]) THEN + X_GEN_TAC `n:num` THEN + FIRST_X_ASSUM(MP_TAC o SPEC `n:num`) THEN + SPEC_TAC(`(ABC:num->A#A#A) (SUC n)`,`y:A#A#A`) THEN + SPEC_TAC(`(ABC:num->A#A#A) n`,`x:A#A#A`) THEN + REWRITE_TAC[FORALL_PAIR_THM]) in + REPEAT STRIP_TAC THEN + STRIP_ASSUME_TAC(ISPECL [`a:complex`; `b:complex`; `c:complex`] + SEGMENTS_SUBSET_CONVEX_HULL) THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP HOLOMORPHIC_ON_IMP_CONTINUOUS_ON) THEN + SUBGOAL_THEN + `f path_integrable_on (linepath(a,b) ++ linepath(b,c) ++ linepath(c,a))` + MP_TAC THENL + [SIMP_TAC[PATH_INTEGRABLE_JOIN; VALID_PATH_JOIN; VALID_PATH_LINEPATH; + PATHSTART_JOIN; PATHFINISH_JOIN; PATHSTART_LINEPATH; + PATHFINISH_LINEPATH] THEN + ASM_MESON_TAC[PATH_INTEGRABLE_CONTINUOUS_LINEPATH; CONTINUOUS_ON_SUBSET]; + ALL_TAC] THEN + SIMP_TAC[path_integrable_on] THEN DISCH_THEN(X_CHOOSE_TAC `y:complex`) THEN + ASM_CASES_TAC `y = Cx(&0)` THENL [ASM_MESON_TAC[]; ALL_TAC] THEN + ABBREV_TAC + `K = &1 + max (dist(a:complex,b)) (max (dist(b,c)) (dist(c,a)))` THEN + SUBGOAL_THEN `&0 < K` ASSUME_TAC THENL + [EXPAND_TAC "K" THEN MATCH_MP_TAC(REAL_ARITH `&0 <= x ==> &0 < &1 + x`) THEN + REWRITE_TAC[REAL_LE_MAX; DIST_POS_LE]; + ALL_TAC] THEN + ABBREV_TAC `e = norm(y:complex) / K pow 2` THEN + SUBGOAL_THEN `&0 < e` ASSUME_TAC THENL + [EXPAND_TAC "e" THEN + ASM_SIMP_TAC[REAL_LT_DIV; REAL_POW_LT; COMPLEX_NORM_NZ]; + ALL_TAC] THEN + SUBGOAL_THEN + `?A B C. A 0 = a /\ B 0 = b /\ C 0 = c /\ + !n. (convex hull {A n,B n,C n} SUBSET convex hull {a,b,c} /\ + dist(A n,B n) <= K / &2 pow n /\ + dist(B n,C n) <= K / &2 pow n /\ + dist(C n,A n) <= K / &2 pow n /\ + norm(path_integral(linepath (A n,B n)) f + + path_integral(linepath (B n,C n)) f + + path_integral(linepath (C n,A n)) f) >= + e * (K / &2 pow n) pow 2) /\ + convex hull {A(SUC n),B(SUC n),C(SUC n)} SUBSET + convex hull {A n,B n,C n}` + MP_TAC THENL + [MATCH_MP_TAC lemma3 THEN CONJ_TAC THENL + [ASM_REWRITE_TAC[real_pow; REAL_DIV_1; CONJ_ASSOC; SUBSET_REFL] THEN + CONJ_TAC THENL [EXPAND_TAC "K" THEN REAL_ARITH_TAC; ALL_TAC] THEN + EXPAND_TAC "e" THEN + ASM_SIMP_TAC[REAL_DIV_RMUL; REAL_LT_IMP_NZ; REAL_POW_LT] THEN + MATCH_MP_TAC(REAL_ARITH `x = y ==> x >= y`) THEN AP_TERM_TAC THEN + FIRST_ASSUM(SUBST1_TAC o SYM o + MATCH_MP HAS_CHAIN_INTEGRAL_CHAIN_INTEGRAL) THEN + REWRITE_TAC[]; + ALL_TAC] THEN + MAP_EVERY X_GEN_TAC + [`a':complex`; `b':complex`; `c':complex`; `n:num`] THEN + REPEAT STRIP_TAC THEN + MP_TAC(SPECL [`f:complex->complex`; `a':complex`; `b':complex`; + `c':complex`; `e:real`; `K / &2 pow n`] + CAUCHY_THEOREM_QUADRISECTION) THEN + ASM_REWRITE_TAC[] THEN + ANTS_TAC THENL [ASM_MESON_TAC[CONTINUOUS_ON_SUBSET]; ALL_TAC] THEN + REPEAT(MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC) THEN STRIP_TAC THEN + ASM_REWRITE_TAC[real_pow; REAL_FIELD `x / (&2 * y) = x / y / &2`] THEN + MATCH_MP_TAC(SET_RULE + `s SUBSET t /\ t SUBSET u ==> s SUBSET u /\ s SUBSET t`) THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC CONVEX_HULL_SUBSET THEN + ASM SET_TAC[]; + ALL_TAC] THEN + REWRITE_TAC[FORALL_AND_THM] THEN STRIP_TAC THEN + SUBGOAL_THEN + `?x:complex. !n:num. x IN convex hull {A n,B n,C n}` + STRIP_ASSUME_TAC THENL + [MATCH_MP_TAC BOUNDED_CLOSED_NEST THEN REPEAT CONJ_TAC THENL + [GEN_TAC THEN MATCH_MP_TAC COMPACT_IMP_CLOSED; + REWRITE_TAC[CONVEX_HULL_EQ_EMPTY; NOT_INSERT_EMPTY]; + MATCH_MP_TAC TRANSITIVE_STEPWISE_LE THEN ASM_REWRITE_TAC[] THEN + MESON_TAC[SUBSET_REFL; SUBSET_TRANS]; + MATCH_MP_TAC COMPACT_IMP_BOUNDED] THEN + MATCH_MP_TAC FINITE_IMP_COMPACT_CONVEX_HULL THEN + REWRITE_TAC[FINITE_INSERT; FINITE_RULES]; + ALL_TAC] THEN + MP_TAC(ISPECL [`f:complex->complex`; `convex hull {a:complex,b,c}`; + `x:complex`; `e / &10`] HOLOMORPHIC_POINT_SMALL_TRIANGLE) THEN + ANTS_TAC THENL + [ASM_SIMP_TAC[HOLOMORPHIC_ON_IMP_CONTINUOUS_ON; complex_differentiable] THEN + ASM_SIMP_TAC[REAL_LT_DIV; REAL_OF_NUM_LT; ARITH] THEN + ASM_MESON_TAC[holomorphic_on; SUBSET]; + ALL_TAC] THEN + DISCH_THEN(X_CHOOSE_THEN `k:real` STRIP_ASSUME_TAC) THEN + MP_TAC(SPEC `K:real / k` REAL_ARCH_POW2) THEN + ASM_SIMP_TAC[REAL_LT_LDIV_EQ] THEN + ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN + SIMP_TAC[GSYM REAL_LT_LDIV_EQ; REAL_POW_LT; REAL_OF_NUM_LT; ARITH] THEN + DISCH_THEN(X_CHOOSE_TAC `n:num`) THEN FIRST_X_ASSUM(MP_TAC o SPECL + [`(A:num->complex) n`; `(B:num->complex) n`; `(C:num->complex) n`]) THEN + ASM_REWRITE_TAC[] THEN ANTS_TAC THENL + [ASM_MESON_TAC[REAL_LE_TRANS; REAL_LT_IMP_LE]; ALL_TAC] THEN + ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN DISCH_THEN(K ALL_TAC) THEN + REWRITE_TAC[REAL_NOT_LE] THEN + MATCH_MP_TAC REAL_LTE_TRANS THEN + EXISTS_TAC `e * (K / &2 pow n) pow 2` THEN + CONJ_TAC THENL [ALL_TAC; ASM_REWRITE_TAC[GSYM real_ge]] THEN + ASM_SIMP_TAC[real_div; GSYM REAL_MUL_ASSOC; REAL_LT_LMUL_EQ] THEN + MATCH_MP_TAC(REAL_ARITH + `&0 < x /\ y <= &9 * x ==> inv(&10) * y < x`) THEN + ASM_SIMP_TAC[REAL_POW_LT; REAL_LT_MUL; REAL_LT_INV_EQ; + REAL_OF_NUM_LT; ARITH] THEN + REWRITE_TAC[REAL_ARITH `&9 * x pow 2 = (&3 * x) pow 2`] THEN + MATCH_MP_TAC REAL_POW_LE2 THEN + SIMP_TAC[REAL_LE_ADD; DIST_POS_LE; GSYM real_div] THEN + MATCH_MP_TAC(REAL_ARITH + `x <= a /\ y <= a /\ z <= a ==> x + y + z <= &3 * a`) THEN + ASM_REWRITE_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* Version needing function holomorphic in interior only. *) +(* ------------------------------------------------------------------------- *) + +let CAUCHY_THEOREM_FLAT_LEMMA = prove + (`!f a b c k. + f continuous_on convex hull {a,b,c} /\ c - a = k % (b - a) /\ &0 <= k + ==> path_integral (linepath(a,b)) f + + path_integral (linepath(b,c)) f + + path_integral (linepath(c,a)) f = Cx(&0)`, + REPEAT STRIP_TAC THEN + STRIP_ASSUME_TAC(ISPECL [`a:complex`; `b:complex`; `c:complex`] + SEGMENTS_SUBSET_CONVEX_HULL) THEN + ASM_CASES_TAC `k <= &1` THENL + [MP_TAC(SPECL [`f:complex->complex`; `a:complex`; `b:complex`; `c:complex`; + `k:real`] PATH_INTEGRAL_SPLIT) THEN + ASM_REWRITE_TAC[] THEN + ANTS_TAC THENL [ASM_MESON_TAC[CONTINUOUS_ON_SUBSET]; ALL_TAC] THEN + DISCH_THEN SUBST1_TAC THEN MATCH_MP_TAC(COMPLEX_RING + `x = --b /\ y = --a ==> (x + y) + (a + b) = Cx(&0)`) THEN + CONJ_TAC THEN MATCH_MP_TAC PATH_INTEGRAL_REVERSE_LINEPATH THEN + ASM_MESON_TAC[CONTINUOUS_ON_SUBSET]; + MP_TAC(SPECL [`f:complex->complex`; `a:complex`; `c:complex`; `b:complex`; + `inv k:real`] PATH_INTEGRAL_SPLIT) THEN + ASM_SIMP_TAC[VECTOR_MUL_ASSOC; REAL_LE_INV_EQ; REAL_MUL_LINV; REAL_INV_LE_1; + VECTOR_MUL_LID; REAL_ARITH `~(k <= &1) ==> ~(k = &0) /\ &1 <= k`] THEN + ANTS_TAC THENL [ASM_MESON_TAC[CONTINUOUS_ON_SUBSET]; ALL_TAC] THEN + MATCH_MP_TAC(COMPLEX_RING + `ac = --ca ==> ac = ab + bc ==> ab + bc + ca = Cx(&0)`) THEN + MATCH_MP_TAC PATH_INTEGRAL_REVERSE_LINEPATH THEN + ASM_MESON_TAC[CONTINUOUS_ON_SUBSET]]);; + +let CAUCHY_THEOREM_FLAT = prove + (`!f a b c k. + f continuous_on convex hull {a,b,c} /\ c - a = k % (b - a) + ==> path_integral (linepath(a,b)) f + + path_integral (linepath(b,c)) f + + path_integral (linepath(c,a)) f = Cx(&0)`, + REPEAT STRIP_TAC THEN ASM_CASES_TAC `&0 <= k` THENL + [ASM_MESON_TAC[CAUCHY_THEOREM_FLAT_LEMMA]; ALL_TAC] THEN + STRIP_ASSUME_TAC(ISPECL [`a:complex`; `b:complex`; `c:complex`] + SEGMENTS_SUBSET_CONVEX_HULL) THEN + MP_TAC(ISPECL [`f:complex->complex`; `b:complex`; `a:complex`; `c:complex`; + `&1 - k`] CAUCHY_THEOREM_FLAT_LEMMA) THEN + ANTS_TAC THENL + [ASM_MESON_TAC[INSERT_AC; REAL_ARITH `~(&0 <= k) ==> &0 <= &1 - k`; + VECTOR_ARITH `b - a = k % (c - a) ==> (b - c) = (&1 - k) % (a - c)`]; + ALL_TAC] THEN + MATCH_MP_TAC(COMPLEX_RING + `ab = --ba /\ ac = --ca /\ bc = --cb + ==> ba + ac + cb = Cx(&0) ==> ab + bc + ca = Cx(&0)`) THEN + REPEAT CONJ_TAC THEN MATCH_MP_TAC PATH_INTEGRAL_REVERSE_LINEPATH THEN + ASM_MESON_TAC[CONTINUOUS_ON_SUBSET]);; + +let CAUCHY_THEOREM_TRIANGLE_INTERIOR = prove + (`!f a b c. + f continuous_on (convex hull {a,b,c}) /\ + f holomorphic_on interior (convex hull {a,b,c}) + ==> (f has_path_integral Cx(&0)) + (linepath(a,b) ++ linepath(b,c) ++ linepath(c,a))`, + REPEAT STRIP_TAC THEN + STRIP_ASSUME_TAC(ISPECL [`a:complex`; `b:complex`; `c:complex`] + SEGMENTS_SUBSET_CONVEX_HULL) THEN + SUBGOAL_THEN + `?B. &0 < B /\ + !y. y IN IMAGE (f:complex->complex) (convex hull {a,b,c}) + ==> norm(y) <= B` + MP_TAC THENL + [REWRITE_TAC[GSYM BOUNDED_POS] THEN MATCH_MP_TAC COMPACT_IMP_BOUNDED THEN + MATCH_MP_TAC COMPACT_CONTINUOUS_IMAGE THEN + ASM_SIMP_TAC[FINITE_IMP_COMPACT_CONVEX_HULL; FINITE_INSERT; FINITE_RULES]; + REWRITE_TAC[FORALL_IN_IMAGE] THEN STRIP_TAC] THEN + SUBGOAL_THEN + `?C. &0 < C /\ !x:complex. x IN convex hull {a,b,c} ==> norm(x) <= C` + MP_TAC THENL + [REWRITE_TAC[GSYM BOUNDED_POS] THEN + MATCH_MP_TAC COMPACT_IMP_BOUNDED THEN + ASM_SIMP_TAC[FINITE_IMP_COMPACT_CONVEX_HULL; FINITE_INSERT; FINITE_RULES]; + STRIP_TAC] THEN + SUBGOAL_THEN + `(f:complex->complex) uniformly_continuous_on (convex hull {a,b,c})` + MP_TAC THENL + [MATCH_MP_TAC COMPACT_UNIFORMLY_CONTINUOUS THEN + ASM_SIMP_TAC[FINITE_IMP_COMPACT_CONVEX_HULL; FINITE_RULES; FINITE_INSERT]; + ALL_TAC] THEN + REWRITE_TAC[uniformly_continuous_on] THEN DISCH_TAC THEN + SUBGOAL_THEN + `f path_integrable_on + (linepath (a,b) ++ linepath(b,c) ++ linepath(c,a))` + MP_TAC THENL + [SIMP_TAC[PATH_INTEGRABLE_JOIN; VALID_PATH_JOIN; VALID_PATH_LINEPATH; + PATHSTART_JOIN; PATHFINISH_JOIN; PATHSTART_LINEPATH; + PATHFINISH_LINEPATH] THEN + ASM_MESON_TAC[PATH_INTEGRABLE_CONTINUOUS_LINEPATH; CONTINUOUS_ON_SUBSET]; + ALL_TAC] THEN + SIMP_TAC[path_integrable_on] THEN DISCH_THEN(X_CHOOSE_TAC `y:complex`) THEN + ASM_CASES_TAC `y = Cx(&0)` THENL [ASM_MESON_TAC[]; ALL_TAC] THEN + UNDISCH_TAC `~(y = Cx(&0))` THEN ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN + DISCH_THEN(K ALL_TAC) THEN REWRITE_TAC[] THEN + FIRST_ASSUM(ASSUME_TAC o SYM o MATCH_MP + HAS_CHAIN_INTEGRAL_CHAIN_INTEGRAL) THEN + ASM_REWRITE_TAC[] THEN + ASM_CASES_TAC `c:complex = a` THENL + [MATCH_MP_TAC CAUCHY_THEOREM_FLAT THEN + EXISTS_TAC `&0` THEN ASM_REWRITE_TAC[VECTOR_MUL_LZERO; VECTOR_SUB_EQ]; + ALL_TAC] THEN + ASM_CASES_TAC `b:complex = c` THENL + [ONCE_REWRITE_TAC[COMPLEX_RING `a + b + c:complex = c + a + b`] THEN + MATCH_MP_TAC CAUCHY_THEOREM_FLAT THEN + EXISTS_TAC `&0` THEN ASM_REWRITE_TAC[VECTOR_MUL_LZERO; VECTOR_SUB_EQ] THEN + ASM_MESON_TAC[INSERT_AC]; + ALL_TAC] THEN + ASM_CASES_TAC `a:complex = b` THENL + [ONCE_REWRITE_TAC[COMPLEX_RING `a + b + c:complex = b + c + a`] THEN + MATCH_MP_TAC CAUCHY_THEOREM_FLAT THEN + EXISTS_TAC `&0` THEN ASM_REWRITE_TAC[VECTOR_MUL_LZERO; VECTOR_SUB_EQ] THEN + ASM_MESON_TAC[INSERT_AC]; + ALL_TAC] THEN + ASM_CASES_TAC `interior(convex hull {a:complex,b,c}) = {}` THENL + [MATCH_MP_TAC CAUCHY_THEOREM_FLAT THEN + SUBGOAL_THEN `{a:complex,b,c} HAS_SIZE (dimindex(:2) + 1)` + MP_TAC THENL + [ASM_SIMP_TAC[HAS_SIZE; CARD_CLAUSES; FINITE_INSERT; FINITE_EMPTY] THEN + ASM_REWRITE_TAC[DIMINDEX_2; ARITH; IN_INSERT; NOT_IN_EMPTY]; + ALL_TAC] THEN + DISCH_THEN(MP_TAC o MATCH_MP INTERIOR_CONVEX_HULL_EQ_EMPTY) THEN + ASM_REWRITE_TAC[] THEN DISCH_TAC THEN + SUBGOAL_THEN `collinear{a:complex,b,c}` MP_TAC THENL + [ASM_REWRITE_TAC[COLLINEAR_3_EQ_AFFINE_DEPENDENT]; ALL_TAC] THEN + ONCE_REWRITE_TAC[SET_RULE `{a,b,c} = {b,a,c}`] THEN + ONCE_REWRITE_TAC[COLLINEAR_3] THEN + ASM_REWRITE_TAC[COLLINEAR_LEMMA; VECTOR_SUB_EQ]; + ALL_TAC] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN + DISCH_THEN(X_CHOOSE_TAC `d:complex`) THEN FIRST_X_ASSUM(MP_TAC o SYM) THEN + DISCH_TAC THEN + ASM_REWRITE_TAC[] THEN ASM_CASES_TAC `y = Cx(&0)` THEN ASM_REWRITE_TAC[] THEN + FIRST_X_ASSUM(MP_TAC o SPEC `norm(y:complex) / &24 / C`) THEN + SUBGOAL_THEN `&0 < norm(y:complex) / &24 / C` ASSUME_TAC THENL + [ASM_SIMP_TAC[REAL_LT_DIV; REAL_OF_NUM_LT; ARITH; NORM_POS_LE; REAL_LTE_ADD; + COMPLEX_NORM_NZ; COMPLEX_SUB_0]; + ASM_REWRITE_TAC[dist]] THEN + DISCH_THEN(X_CHOOSE_THEN `d1:real` STRIP_ASSUME_TAC) THEN ABBREV_TAC + `e = min (&1) + (min (d1 / (&4 * C)) + ((norm(y:complex) / &24 / C) / B))` THEN + SUBGOAL_THEN `&0 < e` ASSUME_TAC THENL + [EXPAND_TAC "e" THEN + ASM_SIMP_TAC[REAL_HALF; REAL_LT_MIN; REAL_LT_DIV; COMPLEX_NORM_NZ; + REAL_LT_MUL; REAL_OF_NUM_LT; ARITH]; + ALL_TAC] THEN + ABBREV_TAC `shrink = \x:complex. x - e % (x - d)` THEN + SUBGOAL_THEN `shrink (a:complex) IN interior(convex hull {a,b,c}) /\ + shrink b IN interior(convex hull {a,b,c}) /\ + shrink c IN interior(convex hull {a,b,c})` + STRIP_ASSUME_TAC THENL + [REPEAT CONJ_TAC THEN EXPAND_TAC "shrink" THEN + MATCH_MP_TAC IN_INTERIOR_CONVEX_SHRINK THEN + ASM_REWRITE_TAC[CONVEX_CONVEX_HULL] THEN + (CONJ_TAC THENL [ALL_TAC; EXPAND_TAC "e" THEN REAL_ARITH_TAC]) THEN + MATCH_MP_TAC(REWRITE_RULE[SUBSET] HULL_SUBSET) THEN + REWRITE_TAC[IN_INSERT]; + ALL_TAC] THEN + SUBGOAL_THEN + `norm((path_integral(linepath(shrink a,shrink b)) f - + path_integral(linepath(a,b)) f) + + (path_integral(linepath(shrink b,shrink c)) f - + path_integral(linepath(b,c)) f) + + (path_integral(linepath(shrink c,shrink a)) f - + path_integral(linepath(c,a)) f)) <= norm(y:complex) / &2` + MP_TAC THENL + [ALL_TAC; + ASM_REWRITE_TAC[COMPLEX_RING + `(ab' - ab) + (bc' - bc) + (ca' - ca) = + (ab' + bc' + ca') - (ab + bc + ca)`] THEN + SUBGOAL_THEN + `(f has_path_integral (Cx(&0))) + (linepath (shrink a,shrink b) ++ + linepath (shrink b,shrink c) ++ + linepath (shrink c,shrink (a:complex)))` + MP_TAC THENL + [MATCH_MP_TAC CAUCHY_THEOREM_TRIANGLE THEN + MATCH_MP_TAC HOLOMORPHIC_ON_SUBSET THEN + EXISTS_TAC `interior(convex hull {a:complex,b,c})` THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC HULL_MINIMAL THEN + SIMP_TAC[CONVEX_INTERIOR; CONVEX_CONVEX_HULL] THEN + ASM SET_TAC[]; + ALL_TAC] THEN + DISCH_THEN(MP_TAC o MATCH_MP HAS_CHAIN_INTEGRAL_CHAIN_INTEGRAL) THEN + SIMP_TAC[] THEN DISCH_THEN(K ALL_TAC) THEN + REWRITE_TAC[COMPLEX_SUB_LZERO; NORM_NEG] THEN + MATCH_MP_TAC(REAL_ARITH `&0 <= y /\ ~(y = &0) ==> ~(y <= y / &2)`) THEN + ASM_REWRITE_TAC[COMPLEX_NORM_ZERO; NORM_POS_LE]] THEN + SUBGOAL_THEN + `!x y. x IN convex hull {a,b,c} /\ y IN convex hull {a,b,c} + ==> norm(x - y) <= &2 * C` + ASSUME_TAC THENL + [REPEAT STRIP_TAC THEN REWRITE_TAC[REAL_MUL_2; VECTOR_SUB] THEN + MATCH_MP_TAC NORM_TRIANGLE_LE THEN REWRITE_TAC[NORM_NEG] THEN + MATCH_MP_TAC REAL_LE_ADD2 THEN ASM_SIMP_TAC[]; + ALL_TAC] THEN + REWRITE_TAC[REAL_ARITH `x / &2 = x / &6 + x / &6 + x / &6`] THEN + REPEAT(MATCH_MP_TAC NORM_TRIANGLE_LE THEN + MATCH_MP_TAC REAL_LE_ADD2 THEN CONJ_TAC) THEN + GEN_REWRITE_TAC RAND_CONV [GSYM REAL_MUL_RID] THEN + GEN_REWRITE_TAC (RAND_CONV o RAND_CONV) [GSYM CONTENT_UNIT_1] THEN + MATCH_MP_TAC HAS_INTEGRAL_BOUND THENL + [EXISTS_TAC `\x. f(linepath(shrink a,shrink b) x) * + (shrink b - shrink a) - + f(linepath(a,b) x) * (b - a)`; + EXISTS_TAC `\x. f(linepath(shrink b,shrink c) x) * + (shrink c - shrink b) - + f(linepath(b,c) x) * (c - b)`; + EXISTS_TAC `\x. f(linepath(shrink c,shrink a) x) * + (shrink a - shrink c) - + f(linepath(c,a) x) * (a - c)`] THEN + ASM_SIMP_TAC[COMPLEX_NORM_NZ; REAL_ARITH `&0 < x ==> &0 <= x / &6`] THEN + (CONJ_TAC THENL + [MATCH_MP_TAC HAS_INTEGRAL_SUB THEN + REWRITE_TAC[GSYM HAS_PATH_INTEGRAL_LINEPATH] THEN + CONJ_TAC THEN MATCH_MP_TAC HAS_PATH_INTEGRAL_INTEGRAL THEN + MATCH_MP_TAC PATH_INTEGRABLE_CONTINUOUS_LINEPATH THEN + MATCH_MP_TAC CONTINUOUS_ON_SUBSET THEN + EXISTS_TAC `convex hull {a:complex,b,c}` THEN + ASM_REWRITE_TAC[SEGMENT_CONVEX_HULL] THEN + MATCH_MP_TAC HULL_MINIMAL THEN + REWRITE_TAC[CONVEX_CONVEX_HULL; SUBSET; IN_INSERT; NOT_IN_EMPTY] THEN + ASM_MESON_TAC[SUBSET; INTERIOR_SUBSET]; + ALL_TAC] THEN + REPEAT STRIP_TAC THEN + ONCE_REWRITE_TAC[COMPLEX_RING + `f' * x' - f * x = f' * (x' - x) + x * (f' - f):complex`] THEN + MATCH_MP_TAC NORM_TRIANGLE_LE THEN REWRITE_TAC[COMPLEX_NORM_MUL] THEN + MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `B * (norm(y:complex) / &24 / C / B) * &2 * C + + (&2 * C) * (norm y / &24 / C)` THEN + CONJ_TAC THENL + [ALL_TAC; + MATCH_MP_TAC REAL_EQ_IMP_LE THEN + MAP_EVERY UNDISCH_TAC [`&0 < B`; `&0 < C`] THEN CONV_TAC REAL_FIELD] THEN + MATCH_MP_TAC REAL_LE_ADD2 THEN CONJ_TAC THEN + MATCH_MP_TAC REAL_LE_MUL2 THEN REWRITE_TAC[NORM_POS_LE] THENL + [CONJ_TAC THENL + [FIRST_X_ASSUM MATCH_MP_TAC THEN + W(fun (asl,w) -> + MP_TAC(PART_MATCH (lhand o rand) LINEPATH_IN_PATH (lhand w))) THEN + ASM_REWRITE_TAC[] THEN + W(fun (asl,w) -> SPEC_TAC(lhand(rand w),`x:complex`)) THEN + REWRITE_TAC[GSYM SUBSET; SEGMENT_CONVEX_HULL] THEN + MATCH_MP_TAC HULL_MINIMAL THEN + REWRITE_TAC[CONVEX_CONVEX_HULL; SUBSET; IN_INSERT; NOT_IN_EMPTY] THEN + ASM_MESON_TAC[SUBSET; INTERIOR_SUBSET]; + ALL_TAC] THEN + EXPAND_TAC "shrink" THEN + REWRITE_TAC[VECTOR_ARITH `(b - e % (b - d)) - (a - e % (a - d)) - + (b - a) = e % (a - b)`] THEN + REWRITE_TAC[NORM_MUL] THEN MATCH_MP_TAC REAL_LE_MUL2 THEN + ASM_SIMP_TAC[NORM_POS_LE; REAL_ARITH `&0 < x ==> abs x = x`; + REAL_ABS_POS] THEN + CONJ_TAC THENL [EXPAND_TAC "e" THEN REAL_ARITH_TAC; ALL_TAC] THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN CONJ_TAC THEN + MATCH_MP_TAC(REWRITE_RULE[SUBSET] HULL_SUBSET) THEN + REWRITE_TAC[IN_INSERT]; + ALL_TAC] THEN + CONJ_TAC THENL + [FIRST_X_ASSUM MATCH_MP_TAC THEN CONJ_TAC THEN + MATCH_MP_TAC(REWRITE_RULE[SUBSET] HULL_SUBSET) THEN + REWRITE_TAC[IN_INSERT]; + ALL_TAC] THEN + MATCH_MP_TAC REAL_LT_IMP_LE THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + CONJ_TAC THENL + [W(fun (asl,w) -> + MP_TAC(PART_MATCH (lhand o rand) LINEPATH_IN_PATH (lhand w))) THEN + ASM_MESON_TAC[SUBSET]; + ALL_TAC] THEN + CONJ_TAC THENL + [W(fun (asl,w) -> + MP_TAC(PART_MATCH (lhand o rand) LINEPATH_IN_PATH (lhand w))) THEN + ASM_REWRITE_TAC[] THEN + W(fun (asl,w) -> SPEC_TAC(lhand(rand w),`x:complex`)) THEN + REWRITE_TAC[GSYM SUBSET; SEGMENT_CONVEX_HULL] THEN + MATCH_MP_TAC HULL_MINIMAL THEN + REWRITE_TAC[CONVEX_CONVEX_HULL; SUBSET; IN_INSERT; NOT_IN_EMPTY] THEN + ASM_MESON_TAC[SUBSET; INTERIOR_SUBSET]; + ALL_TAC] THEN + REWRITE_TAC[linepath] THEN REWRITE_TAC[VECTOR_ARITH + `((&1 - x) % a' + x % b') - ((&1 - x) % a + x % b) = + (&1 - x) % (a' - a) + x % (b' - b)`] THEN + EXPAND_TAC "shrink" THEN REWRITE_TAC[VECTOR_ARITH `a - b - a = --b`] THEN + MATCH_MP_TAC NORM_TRIANGLE_LT THEN REWRITE_TAC[NORM_MUL; NORM_NEG] THEN + MATCH_MP_TAC REAL_CONVEX_BOUND_LT THEN ONCE_REWRITE_TAC[TAUT + `a /\ b /\ c /\ d /\ e <=> (c /\ d /\ e) /\ a /\ b`] THEN + CONJ_TAC THENL + [FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_INTERVAL_1]) THEN + REWRITE_TAC[DROP_VEC] THEN REAL_ARITH_TAC; + ALL_TAC] THEN + CONJ_TAC THEN + MATCH_MP_TAC REAL_LET_TRANS THEN + EXISTS_TAC `e * &2 * C` THEN + ASM_SIMP_TAC[REAL_LE_LMUL_EQ; REAL_ARITH `&0 < x ==> abs x = x`] THEN + (CONJ_TAC THENL + [FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_MESON_TAC[SUBSET; INTERIOR_SUBSET; HULL_SUBSET; IN_INSERT]; + ALL_TAC]) THEN + ASM_SIMP_TAC[GSYM REAL_LT_RDIV_EQ; REAL_LT_MUL; REAL_OF_NUM_LT; ARITH] THEN + EXPAND_TAC "e" THEN REWRITE_TAC[REAL_MIN_LT] THEN + DISJ2_TAC THEN DISJ1_TAC THEN + REWRITE_TAC[REAL_FIELD `d / (a * b) = inv(a:real) * d / b`] THEN + REWRITE_TAC[REAL_ARITH `inv(&4) * x < inv(&2) * x <=> &0 < x`] THEN + ASM_SIMP_TAC[REAL_LT_DIV]));; + +(* ------------------------------------------------------------------------- *) +(* Version allowing finite number of exceptional points. *) +(* ------------------------------------------------------------------------- *) + +let CAUCHY_THEOREM_TRIANGLE_COFINITE = prove + (`!f s a b c. + f continuous_on (convex hull {a,b,c}) /\ + FINITE s /\ + (!x. x IN interior(convex hull {a,b,c}) DIFF s + ==> f complex_differentiable (at x)) + ==> (f has_path_integral Cx(&0)) + (linepath (a,b) ++ linepath(b,c) ++ linepath(c,a))`, + GEN_TAC THEN GEN_TAC THEN WF_INDUCT_TAC `CARD(s:complex->bool)` THEN + REPEAT STRIP_TAC THEN ASM_CASES_TAC `s:complex->bool = {}` THENL + [MATCH_MP_TAC CAUCHY_THEOREM_TRIANGLE_INTERIOR THEN + ASM_REWRITE_TAC[holomorphic_on] THEN X_GEN_TAC `z:complex` THEN + DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC `z:complex`) THEN + ASM_REWRITE_TAC[complex_differentiable; IN_DIFF; NOT_IN_EMPTY] THEN + MESON_TAC[HAS_COMPLEX_DERIVATIVE_AT_WITHIN]; + ALL_TAC] THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN + DISCH_THEN(X_CHOOSE_TAC `d:complex`) THEN + FIRST_X_ASSUM(MP_TAC o SPEC `s DELETE (d:complex)`) THEN + ASM_SIMP_TAC[CARD_DELETE; CARD_EQ_0; + ARITH_RULE `n - 1 < n <=> ~(n = 0)`] THEN + ASM_CASES_TAC `(d:complex) IN convex hull {a,b,c}` THENL + [ALL_TAC; + DISCH_THEN MATCH_MP_TAC THEN + ASM_REWRITE_TAC[FINITE_DELETE; IN_DIFF; IN_DELETE] THEN + REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_REWRITE_TAC[IN_DIFF] THEN ASM_MESON_TAC[INTERIOR_SUBSET; SUBSET]] THEN + DISCH_TAC THEN SUBGOAL_THEN + `(f has_path_integral Cx(&0)) + (linepath(a,b) ++ linepath(b,d) ++ linepath(d,a)) /\ + (f has_path_integral Cx(&0)) + (linepath(b,c) ++ linepath(c,d) ++ linepath(d,b)) /\ + (f has_path_integral Cx(&0)) + (linepath(c,a) ++ linepath(a,d) ++ linepath(d,c))` + MP_TAC THENL + [RULE_ASSUM_TAC(REWRITE_RULE[IMP_IMP; RIGHT_IMP_FORALL_THM]) THEN + REPEAT CONJ_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_REWRITE_TAC[FINITE_DELETE] THEN + (CONJ_TAC THENL + [MATCH_MP_TAC CONTINUOUS_ON_SUBSET THEN + EXISTS_TAC `convex hull {a:complex,b,c}` THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC CONVEX_HULL_SUBSET THEN + REWRITE_TAC[IN_INSERT; NOT_IN_EMPTY] THEN + REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC(REWRITE_RULE[SUBSET] HULL_SUBSET) THEN + REWRITE_TAC[IN_INSERT]; + ALL_TAC]) THEN + ASM_REWRITE_TAC[FINITE_DELETE; IN_DIFF; IN_DELETE] THEN + REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [DE_MORGAN_THM]) THEN + (ASM_CASES_TAC `x:complex = d` THEN ASM_REWRITE_TAC[] THENL + [ASM_MESON_TAC[NOT_IN_INTERIOR_CONVEX_HULL_3]; ALL_TAC]) THEN + DISCH_TAC THEN ASM_REWRITE_TAC[IN_DIFF] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE + `x IN interior s + ==> interior s SUBSET interior t ==> x IN interior t`)) THEN + MATCH_MP_TAC SUBSET_INTERIOR THEN + MATCH_MP_TAC CONVEX_HULL_SUBSET THEN + SIMP_TAC[IN_INSERT; NOT_IN_EMPTY] THEN + REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC(REWRITE_RULE[SUBSET] HULL_SUBSET) THEN REWRITE_TAC[IN_INSERT]; + ALL_TAC] THEN + SUBGOAL_THEN + `f path_integrable_on + (linepath (a,b) ++ linepath(b,c) ++ linepath(c,a))` + MP_TAC THENL + [SIMP_TAC[PATH_INTEGRABLE_JOIN; VALID_PATH_JOIN; VALID_PATH_LINEPATH; + PATHSTART_JOIN; PATHFINISH_JOIN; PATHSTART_LINEPATH; + PATHFINISH_LINEPATH] THEN + STRIP_ASSUME_TAC(ISPECL [`a:complex`; `b:complex`; `c:complex`] + SEGMENTS_SUBSET_CONVEX_HULL) THEN + ASM_MESON_TAC[PATH_INTEGRABLE_CONTINUOUS_LINEPATH; CONTINUOUS_ON_SUBSET]; + ALL_TAC] THEN + REWRITE_TAC[path_integrable_on; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `y:complex` THEN + DISCH_THEN(fun th -> ASSUME_TAC th THEN MP_TAC th) THEN + REWRITE_TAC[IMP_IMP] THEN + DISCH_THEN(REPEAT_TCL CONJUNCTS_THEN + (MP_TAC o MATCH_MP HAS_CHAIN_INTEGRAL_CHAIN_INTEGRAL)) THEN + ASM_CASES_TAC `y = Cx(&0)` THEN ASM_REWRITE_TAC[] THENL + [ASM_MESON_TAC[]; UNDISCH_TAC `~(y = Cx(&0))`] THEN + REWRITE_TAC[] THEN + SUBGOAL_THEN `(f:complex->complex) continuous_on segment[a,d] /\ + f continuous_on segment[b,d] /\ + f continuous_on segment[c,d]` + MP_TAC THENL + [ALL_TAC; + DISCH_THEN(REPEAT_TCL CONJUNCTS_THEN (MP_TAC o MATCH_MP + PATH_INTEGRAL_REVERSE_LINEPATH)) THEN + CONV_TAC COMPLEX_RING] THEN + REPEAT CONJ_TAC THEN MATCH_MP_TAC CONTINUOUS_ON_SUBSET THEN + EXISTS_TAC `convex hull {a:complex,b,c}` THEN + ASM_REWRITE_TAC[SEGMENT_CONVEX_HULL] THEN + MATCH_MP_TAC CONVEX_HULL_SUBSET THEN + SIMP_TAC[IN_INSERT; NOT_IN_EMPTY] THEN + REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC(REWRITE_RULE[SUBSET] HULL_SUBSET) THEN REWRITE_TAC[IN_INSERT]);; + +(* ------------------------------------------------------------------------- *) +(* Existence of a primitive. *) +(* ------------------------------------------------------------------------- *) + +let STARLIKE_CONVEX_SUBSET = prove + (`!s a b c:real^N. + a IN s /\ segment[b,c] SUBSET s /\ + (!x. x IN s ==> segment[a,x] SUBSET s) + ==> convex hull {a,b,c} SUBSET s`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`{b:real^N,c}`; `a:real^N`] CONVEX_HULL_INSERT) THEN + REWRITE_TAC[NOT_INSERT_EMPTY] THEN DISCH_THEN SUBST1_TAC THEN + REWRITE_TAC[SUBSET; IN_ELIM_THM; LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`x:real^N`; `u:real`; `v:real`; `d:real^N`] THEN + STRIP_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC `d:real^N`) THEN ANTS_TAC THENL + [ASM_MESON_TAC[SUBSET; SEGMENT_CONVEX_HULL]; + ASM_REWRITE_TAC[SUBSET] THEN DISCH_THEN MATCH_MP_TAC THEN + REWRITE_TAC[SEGMENT_CONVEX_HULL; CONVEX_HULL_2; IN_ELIM_THM] THEN + ASM_MESON_TAC[]]);; + +let TRIANGLE_PATH_INTEGRALS_STARLIKE_PRIMITIVE = prove + (`!f s a. + a IN s /\ open s /\ f continuous_on s /\ + (!z. z IN s ==> segment[a,z] SUBSET s) /\ + (!b c. segment[b,c] SUBSET s + ==> path_integral (linepath(a,b)) f + + path_integral (linepath(b,c)) f + + path_integral (linepath(c,a)) f = Cx(&0)) + ==> ?g. !z. z IN s ==> (g has_complex_derivative f(z)) (at z)`, + REPEAT STRIP_TAC THEN + EXISTS_TAC `\x. path_integral (linepath(a,x)) f` THEN + X_GEN_TAC `x:complex` THEN STRIP_TAC THEN + REWRITE_TAC[has_complex_derivative] THEN + REWRITE_TAC[has_derivative_at; LINEAR_COMPLEX_MUL] THEN + MATCH_MP_TAC LIM_TRANSFORM THEN + EXISTS_TAC `\y. inv(norm(y - x)) % (path_integral(linepath(x,y)) f - + f x * (y - x))` THEN + REWRITE_TAC[VECTOR_ARITH + `i % (x - a) - i % (y - (z + a)) = i % (x + z - y)`] THEN + CONJ_TAC THENL + [MATCH_MP_TAC LIM_EVENTUALLY THEN REWRITE_TAC[EVENTUALLY_AT] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [OPEN_CONTAINS_BALL]) THEN + DISCH_THEN(MP_TAC o SPEC `x:complex`) THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `e:real` THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + X_GEN_TAC `y:complex` THEN REWRITE_TAC[dist] THEN STRIP_TAC THEN + REWRITE_TAC[VECTOR_MUL_EQ_0] THEN DISJ2_TAC THEN + MP_TAC(SPECL [`f:complex->complex`; `a:complex`; `y:complex`] + PATH_INTEGRAL_REVERSE_LINEPATH) THEN + ANTS_TAC THENL + [MATCH_MP_TAC CONTINUOUS_ON_SUBSET THEN + EXISTS_TAC `s:complex->bool` THEN ASM_REWRITE_TAC[] THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN + FIRST_X_ASSUM(MATCH_MP_TAC o GEN_REWRITE_RULE I [SUBSET]) THEN + ASM_REWRITE_TAC[IN_BALL; ONCE_REWRITE_RULE[NORM_SUB] dist]; + REWRITE_TAC[COMPLEX_VEC_0] THEN MATCH_MP_TAC(COMPLEX_RING + `ax + xy + ya = Cx(&0) ==> ay = --ya ==> xy + ax - ay = Cx(&0)`) THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN FIRST_X_ASSUM(MATCH_MP_TAC o + MATCH_MP (REWRITE_RULE[IMP_CONJ_ALT] SUBSET_TRANS)) THEN + REWRITE_TAC[SEGMENT_CONVEX_HULL] THEN + MATCH_MP_TAC HULL_MINIMAL THEN REWRITE_TAC[CONVEX_BALL] THEN + REWRITE_TAC[SUBSET; IN_BALL; IN_INSERT; NOT_IN_EMPTY] THEN + REPEAT STRIP_TAC THEN + ASM_REWRITE_TAC[dist; NORM_0; VECTOR_SUB_REFL] THEN + ASM_MESON_TAC[NORM_SUB]]; + REWRITE_TAC[LIM_AT] THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN + SUBGOAL_THEN `(f:complex->complex) continuous at x` MP_TAC THENL + [MATCH_MP_TAC CONTINUOUS_ON_INTERIOR THEN ASM_MESON_TAC[INTERIOR_OPEN]; + ALL_TAC] THEN + REWRITE_TAC[continuous_at; dist; VECTOR_SUB_RZERO] THEN + DISCH_THEN(MP_TAC o SPEC `e / &2`) THEN ASM_REWRITE_TAC[REAL_HALF] THEN + DISCH_THEN(X_CHOOSE_THEN `d1:real` STRIP_ASSUME_TAC) THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [OPEN_CONTAINS_BALL]) THEN + DISCH_THEN(MP_TAC o SPEC `x:complex`) THEN + ASM_REWRITE_TAC[SUBSET; IN_BALL; dist] THEN + DISCH_THEN(X_CHOOSE_THEN `d2:real` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `min d1 d2` THEN ASM_REWRITE_TAC[REAL_LT_MIN] THEN + X_GEN_TAC `y:complex` THEN STRIP_TAC THEN + SUBGOAL_THEN `f path_integrable_on linepath(x,y)` MP_TAC THENL + [MATCH_MP_TAC PATH_INTEGRABLE_CONTINUOUS_LINEPATH THEN + MATCH_MP_TAC CONTINUOUS_ON_SUBSET THEN EXISTS_TAC `s:complex->bool` THEN + ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC SUBSET_TRANS THEN EXISTS_TAC `ball(x:complex,d2)` THEN + CONJ_TAC THENL + [REWRITE_TAC[SEGMENT_CONVEX_HULL] THEN + MATCH_MP_TAC HULL_MINIMAL THEN REWRITE_TAC[CONVEX_BALL] THEN + REWRITE_TAC[SUBSET; IN_BALL; IN_INSERT; NOT_IN_EMPTY] THEN + REPEAT STRIP_TAC THEN + ASM_REWRITE_TAC[dist; NORM_0; VECTOR_SUB_REFL] THEN + ASM_MESON_TAC[NORM_SUB]; + ASM_REWRITE_TAC[SUBSET; IN_BALL; dist]]; + ALL_TAC] THEN + REWRITE_TAC[path_integrable_on; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `z:complex` THEN + MP_TAC(SPECL [`x:complex`; `y:complex`; `(f:complex->complex) x`] + HAS_PATH_INTEGRAL_CONST_LINEPATH) THEN + REWRITE_TAC[IMP_IMP] THEN + DISCH_THEN(fun th -> ASSUME_TAC(CONJUNCT2 th) THEN MP_TAC th) THEN + FIRST_ASSUM(SUBST1_TAC o MATCH_MP PATH_INTEGRAL_UNIQUE) THEN + DISCH_THEN(MP_TAC o MATCH_MP HAS_PATH_INTEGRAL_SUB) THEN + DISCH_THEN(MP_TAC o MATCH_MP HAS_PATH_INTEGRAL_NEG) THEN + REWRITE_TAC[COMPLEX_NEG_SUB] THEN STRIP_TAC THEN + MATCH_MP_TAC(REAL_ARITH `x <= e / &2 /\ &0 < e ==> x < e`) THEN + ASM_REWRITE_TAC[NORM_MUL; REAL_ABS_INV; REAL_ABS_NORM] THEN + ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN REWRITE_TAC[GSYM real_div] THEN + ASM_SIMP_TAC[REAL_LE_LDIV_EQ] THEN + MATCH_MP_TAC HAS_PATH_INTEGRAL_BOUND_LINEPATH THEN + EXISTS_TAC `\w. (f:complex->complex) w - f x` THEN + ASM_SIMP_TAC[REAL_ARITH `&0 < e ==> &0 <= e / &2`] THEN + X_GEN_TAC `w:complex` THEN STRIP_TAC THEN MATCH_MP_TAC REAL_LT_IMP_LE THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_MESON_TAC[REAL_LET_TRANS; SEGMENT_BOUND]]);; + +let HOLOMORPHIC_STARLIKE_PRIMITIVE = prove + (`!f s k. open s /\ starlike s /\ FINITE k /\ f continuous_on s /\ + (!x. x IN s DIFF k ==> f complex_differentiable at x) + ==> ?g. !x. x IN s ==> (g has_complex_derivative f(x)) (at x)`, + REPEAT STRIP_TAC THEN + FIRST_X_ASSUM(X_CHOOSE_THEN `a:complex` STRIP_ASSUME_TAC o + GEN_REWRITE_RULE I [starlike]) THEN + MATCH_MP_TAC TRIANGLE_PATH_INTEGRALS_STARLIKE_PRIMITIVE THEN + EXISTS_TAC `a:complex` THEN ASM_REWRITE_TAC[] THEN + MAP_EVERY X_GEN_TAC [`x:complex`; `y:complex`] THEN STRIP_TAC THEN + MATCH_MP_TAC HAS_CHAIN_INTEGRAL_CHAIN_INTEGRAL THEN + MATCH_MP_TAC CAUCHY_THEOREM_TRIANGLE_COFINITE THEN + EXISTS_TAC `k:complex->bool` THEN ASM_REWRITE_TAC[] THEN + SUBGOAL_THEN `convex hull {a:complex,x,y} SUBSET s` ASSUME_TAC THENL + [MATCH_MP_TAC STARLIKE_CONVEX_SUBSET THEN ASM_REWRITE_TAC[]; ALL_TAC] THEN + CONJ_TAC THENL [ASM_MESON_TAC[CONTINUOUS_ON_SUBSET]; ALL_TAC] THEN + REWRITE_TAC[IN_DIFF] THEN REPEAT STRIP_TAC THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[IN_DIFF] THEN + ASM_MESON_TAC[SUBSET; INTERIOR_SUBSET]);; + +(* ------------------------------------------------------------------------- *) +(* Cauchy's theorem for an open starlike set. *) +(* ------------------------------------------------------------------------- *) + +let CAUCHY_THEOREM_STARLIKE = prove + (`!f s k g. open s /\ starlike s /\ FINITE k /\ f continuous_on s /\ + (!x. x IN s DIFF k ==> f complex_differentiable at x) /\ + valid_path g /\ (path_image g) SUBSET s /\ + pathfinish g = pathstart g + ==> (f has_path_integral Cx(&0)) (g)`, + MESON_TAC[HOLOMORPHIC_STARLIKE_PRIMITIVE; CAUCHY_THEOREM_PRIMITIVE; + HAS_COMPLEX_DERIVATIVE_AT_WITHIN]);; + +let CAUCHY_THEOREM_STARLIKE_SIMPLE = prove + (`!f s g. open s /\ starlike s /\ f holomorphic_on s /\ + valid_path g /\ (path_image g) SUBSET s /\ + pathfinish g = pathstart g + ==> (f has_path_integral Cx(&0)) (g)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC CAUCHY_THEOREM_STARLIKE THEN + MAP_EVERY EXISTS_TAC [`s:complex->bool`; `{}:complex->bool`] THEN + ASM_SIMP_TAC[HOLOMORPHIC_ON_IMP_CONTINUOUS_ON; FINITE_RULES] THEN + REWRITE_TAC[IN_DIFF; NOT_IN_EMPTY; complex_differentiable] THEN + ASM_MESON_TAC[HAS_COMPLEX_DERIVATIVE_WITHIN_OPEN; holomorphic_on]);; + +(* ------------------------------------------------------------------------- *) +(* For a convex set we can avoid assuming openness and boundary analyticity. *) +(* ------------------------------------------------------------------------- *) + +let TRIANGLE_PATH_INTEGRALS_CONVEX_PRIMITIVE = prove + (`!f s a. + a IN s /\ convex s /\ f continuous_on s /\ + (!b c. b IN s /\ c IN s + ==> path_integral (linepath(a,b)) f + + path_integral (linepath(b,c)) f + + path_integral (linepath(c,a)) f = Cx(&0)) + ==> ?g. !z. z IN s ==> (g has_complex_derivative f(z)) (at z within s)`, + REPEAT STRIP_TAC THEN + EXISTS_TAC `\x. path_integral (linepath(a,x)) f` THEN + X_GEN_TAC `x:complex` THEN STRIP_TAC THEN + REWRITE_TAC[has_complex_derivative] THEN + REWRITE_TAC[has_derivative_within; LINEAR_COMPLEX_MUL] THEN + MATCH_MP_TAC LIM_TRANSFORM THEN + EXISTS_TAC `\y. inv(norm(y - x)) % (path_integral(linepath(x,y)) f - + f x * (y - x))` THEN + REWRITE_TAC[VECTOR_ARITH + `i % (x - a) - i % (y - (z + a)) = i % (x + z - y)`] THEN + CONJ_TAC THENL + [MATCH_MP_TAC LIM_EVENTUALLY THEN REWRITE_TAC[EVENTUALLY_WITHIN] THEN + EXISTS_TAC `&1` THEN REWRITE_TAC[REAL_LT_01] THEN + X_GEN_TAC `y:complex` THEN STRIP_TAC THEN + REWRITE_TAC[VECTOR_MUL_EQ_0] THEN DISJ2_TAC THEN + MP_TAC(SPECL [`f:complex->complex`; `a:complex`; `y:complex`] + PATH_INTEGRAL_REVERSE_LINEPATH) THEN + ANTS_TAC THENL + [MATCH_MP_TAC CONTINUOUS_ON_SUBSET THEN + EXISTS_TAC `s:complex->bool` THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[SEGMENT_CONVEX_HULL] THEN + MATCH_MP_TAC HULL_MINIMAL THEN ASM SET_TAC[]; + REWRITE_TAC[COMPLEX_VEC_0] THEN MATCH_MP_TAC(COMPLEX_RING + `ax + xy + ya = Cx(&0) ==> ay = --ya ==> xy + ax - ay = Cx(&0)`) THEN + ASM_SIMP_TAC[]]; + REWRITE_TAC[LIM_WITHIN] THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN + SUBGOAL_THEN + `(f:complex->complex) continuous (at x within s)` MP_TAC THENL + [ASM_MESON_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN]; ALL_TAC] THEN + REWRITE_TAC[continuous_within; dist; VECTOR_SUB_RZERO] THEN + DISCH_THEN(MP_TAC o SPEC `e / &2`) THEN ASM_REWRITE_TAC[REAL_HALF] THEN + DISCH_THEN(X_CHOOSE_THEN `d1:real` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `d1:real` THEN ASM_REWRITE_TAC[] THEN + X_GEN_TAC `y:complex` THEN STRIP_TAC THEN + SUBGOAL_THEN `f path_integrable_on linepath(x,y)` MP_TAC THENL + [MATCH_MP_TAC PATH_INTEGRABLE_CONTINUOUS_LINEPATH THEN + MATCH_MP_TAC CONTINUOUS_ON_SUBSET THEN EXISTS_TAC `s:complex->bool` THEN + ASM_REWRITE_TAC[] THEN REWRITE_TAC[SEGMENT_CONVEX_HULL] THEN + MATCH_MP_TAC HULL_MINIMAL THEN ASM SET_TAC[]; + ALL_TAC] THEN + REWRITE_TAC[path_integrable_on; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `z:complex` THEN + MP_TAC(SPECL [`x:complex`; `y:complex`; `(f:complex->complex) x`] + HAS_PATH_INTEGRAL_CONST_LINEPATH) THEN + REWRITE_TAC[IMP_IMP] THEN + DISCH_THEN(fun th -> ASSUME_TAC(CONJUNCT2 th) THEN MP_TAC th) THEN + FIRST_ASSUM(SUBST1_TAC o MATCH_MP PATH_INTEGRAL_UNIQUE) THEN + DISCH_THEN(MP_TAC o MATCH_MP HAS_PATH_INTEGRAL_SUB) THEN + DISCH_THEN(MP_TAC o MATCH_MP HAS_PATH_INTEGRAL_NEG) THEN + REWRITE_TAC[COMPLEX_NEG_SUB] THEN STRIP_TAC THEN + MATCH_MP_TAC(REAL_ARITH `x <= e / &2 /\ &0 < e ==> x < e`) THEN + ASM_REWRITE_TAC[NORM_MUL; REAL_ABS_INV; REAL_ABS_NORM] THEN + ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN REWRITE_TAC[GSYM real_div] THEN + ASM_SIMP_TAC[REAL_LE_LDIV_EQ] THEN + MATCH_MP_TAC HAS_PATH_INTEGRAL_BOUND_LINEPATH THEN + EXISTS_TAC `\w. (f:complex->complex) w - f x` THEN + ASM_SIMP_TAC[REAL_ARITH `&0 < e ==> &0 <= e / &2`] THEN + X_GEN_TAC `w:complex` THEN STRIP_TAC THEN MATCH_MP_TAC REAL_LT_IMP_LE THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN CONJ_TAC THENL + [FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE + `w IN t ==> t SUBSET s ==> w IN s`)) THEN + REWRITE_TAC[SEGMENT_CONVEX_HULL] THEN + MATCH_MP_TAC HULL_MINIMAL THEN ASM SET_TAC[]; + ASM_MESON_TAC[REAL_LET_TRANS; SEGMENT_BOUND]]]);; + +let PATHINTEGRAL_CONVEX_PRIMITIVE = prove + (`!f s. convex s /\ f continuous_on s /\ + (!a b c. a IN s /\ b IN s /\ c IN s + ==> (f has_path_integral Cx(&0)) + (linepath (a,b) ++ linepath(b,c) ++ linepath(c,a))) + ==> ?g. !x. x IN s + ==> (g has_complex_derivative f(x)) (at x within s)`, + REPEAT STRIP_TAC THEN + ASM_CASES_TAC `s:complex->bool = {}` THEN ASM_REWRITE_TAC[NOT_IN_EMPTY] THEN + FIRST_X_ASSUM(X_CHOOSE_THEN `a:complex` STRIP_ASSUME_TAC o + GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN + MATCH_MP_TAC TRIANGLE_PATH_INTEGRALS_CONVEX_PRIMITIVE THEN + EXISTS_TAC `a:complex` THEN ASM_REWRITE_TAC[] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_CHAIN_INTEGRAL_CHAIN_INTEGRAL THEN + ASM_SIMP_TAC[]);; + +let HOLOMORPHIC_CONVEX_PRIMITIVE = prove + (`!f s k. convex s /\ FINITE k /\ f continuous_on s /\ + (!x. x IN interior(s) DIFF k ==> f complex_differentiable at x) + ==> ?g. !x. x IN s + ==> (g has_complex_derivative f(x)) (at x within s)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC PATHINTEGRAL_CONVEX_PRIMITIVE THEN + ASM_REWRITE_TAC[] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC CAUCHY_THEOREM_TRIANGLE_COFINITE THEN + EXISTS_TAC `k:complex->bool` THEN ASM_REWRITE_TAC[] THEN CONJ_TAC THENL + [MATCH_MP_TAC CONTINUOUS_ON_SUBSET THEN EXISTS_TAC `s:complex->bool` THEN + ASM_REWRITE_TAC[]; + X_GEN_TAC `w:complex` THEN + DISCH_THEN(fun th -> FIRST_X_ASSUM MATCH_MP_TAC THEN MP_TAC th) THEN + SPEC_TAC(`w:complex`,`w:complex`) THEN ASM_REWRITE_TAC[GSYM SUBSET] THEN + MATCH_MP_TAC(SET_RULE `s SUBSET t ==> (s DIFF k) SUBSET (t DIFF k)`) THEN + MATCH_MP_TAC SUBSET_INTERIOR] THEN + MATCH_MP_TAC HULL_MINIMAL THEN ASM_REWRITE_TAC[] THEN ASM SET_TAC[]);; + +let CAUCHY_THEOREM_CONVEX = prove + (`!f s k g. convex s /\ FINITE k /\ f continuous_on s /\ + (!x. x IN interior(s) DIFF k ==> f complex_differentiable at x) /\ + valid_path g /\ (path_image g) SUBSET s /\ + pathfinish g = pathstart g + ==> (f has_path_integral Cx(&0)) (g)`, + MESON_TAC[HOLOMORPHIC_CONVEX_PRIMITIVE; CAUCHY_THEOREM_PRIMITIVE]);; + +let CAUCHY_THEOREM_CONVEX_SIMPLE = prove + (`!f s g. convex s /\ f holomorphic_on s /\ + valid_path g /\ (path_image g) SUBSET s /\ + pathfinish g = pathstart g + ==> (f has_path_integral Cx(&0)) (g)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC CAUCHY_THEOREM_CONVEX THEN + MAP_EVERY EXISTS_TAC [`s:complex->bool`; `{}:complex->bool`] THEN + ASM_SIMP_TAC[HOLOMORPHIC_ON_IMP_CONTINUOUS_ON; FINITE_RULES] THEN + REWRITE_TAC[IN_DIFF; NOT_IN_EMPTY; complex_differentiable] THEN + SUBGOAL_THEN `f holomorphic_on (interior s)` MP_TAC THENL + [ASM_MESON_TAC[HOLOMORPHIC_ON_SUBSET; INTERIOR_SUBSET]; ALL_TAC] THEN + MESON_TAC[holomorphic_on; HAS_COMPLEX_DERIVATIVE_WITHIN_OPEN; + OPEN_INTERIOR]);; + +(* ------------------------------------------------------------------------- *) +(* In particular for a disc. *) +(* ------------------------------------------------------------------------- *) + +let CAUCHY_THEOREM_DISC = prove + (`!f g k a e. + FINITE k /\ f continuous_on cball(a,e) /\ + (!x. x IN ball(a,e) DIFF k ==> f complex_differentiable at x) /\ + valid_path g /\ (path_image g) SUBSET cball(a,e) /\ + pathfinish g = pathstart g + ==> (f has_path_integral Cx(&0)) (g)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC CAUCHY_THEOREM_CONVEX THEN + MAP_EVERY EXISTS_TAC [`cball(a:complex,e)`; `k:complex->bool`] THEN + ASM_REWRITE_TAC[INTERIOR_CBALL; CONVEX_CBALL]);; + +let CAUCHY_THEOREM_DISC_SIMPLE = prove + (`!f g a e. + f holomorphic_on ball(a,e) /\ + valid_path g /\ (path_image g) SUBSET ball(a,e) /\ + pathfinish g = pathstart g + ==> (f has_path_integral Cx(&0)) (g)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC CAUCHY_THEOREM_CONVEX_SIMPLE THEN + EXISTS_TAC `ball(a:complex,e)` THEN ASM_REWRITE_TAC[CONVEX_BALL; OPEN_BALL]);; + +(* ------------------------------------------------------------------------- *) +(* Generalize integrability to local primitives. *) +(* ------------------------------------------------------------------------- *) + +let PATH_INTEGRAL_LOCAL_PRIMITIVE_LEMMA = prove + (`!f f' g s a b. + (!x. x IN s ==> (f has_complex_derivative f' x) (at x within s)) /\ + g piecewise_differentiable_on interval[a,b] /\ + (!x. x IN interval[a,b] ==> g(x) IN s) + ==> (\x. f' (g x) * vector_derivative g (at x within interval[a,b])) + integrable_on interval[a,b]`, + REPEAT STRIP_TAC THEN + ASM_CASES_TAC `interval[a:real^1,b] = {}` THENL + [ASM_REWRITE_TAC[INTEGRABLE_ON_EMPTY]; + REWRITE_TAC[integrable_on] THEN + EXISTS_TAC `(f:complex->complex) (g(b:real^1)) - f(g a)` THEN + MATCH_MP_TAC PATH_INTEGRAL_PRIMITIVE_LEMMA THEN + ASM_MESON_TAC[]]);; + +let PATH_INTEGRAL_LOCAL_PRIMITIVE_ANY = prove + (`!f g s a b. + (!x. x IN s + ==> ?d h. &0 < d /\ + !y. norm(y - x) < d + ==> (h has_complex_derivative f(y)) (at y within s)) /\ + g piecewise_differentiable_on interval[a,b] /\ + (!x. x IN interval[a,b] ==> g(x) IN s) + ==> (\x. f(g x) * vector_derivative g (at x)) integrable_on interval[a,b]`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC INTEGRABLE_ON_LITTLE_SUBINTERVALS THEN + X_GEN_TAC `x:real^1` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `(g:real^1->complex) x`) THEN + ASM_SIMP_TAC[LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`d:real`; `h:complex->complex`] THEN STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o MATCH_MP + PIECEWISE_DIFFERENTIABLE_ON_IMP_CONTINUOUS_ON) THEN + REWRITE_TAC[continuous_on] THEN DISCH_THEN(MP_TAC o SPEC `x:real^1`) THEN + ASM_REWRITE_TAC[] THEN DISCH_THEN(MP_TAC o SPEC `d:real`) THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `e:real` THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN + SIMP_TAC[integrable_on; GSYM HAS_INTEGRAL_LOCALIZED_VECTOR_DERIVATIVE] THEN + REWRITE_TAC[GSYM integrable_on] THEN + MATCH_MP_TAC PATH_INTEGRAL_LOCAL_PRIMITIVE_LEMMA THEN + MAP_EVERY EXISTS_TAC + [`h:complex->complex`; `IMAGE (g:real^1->complex) (interval[u,v])`] THEN + REWRITE_TAC[FORALL_IN_IMAGE] THEN REPEAT STRIP_TAC THENL + [MATCH_MP_TAC HAS_COMPLEX_DERIVATIVE_WITHIN_SUBSET THEN + EXISTS_TAC `s:complex->bool` THEN + CONJ_TAC THENL [FIRST_X_ASSUM MATCH_MP_TAC; ASM SET_TAC[]] THEN + REWRITE_TAC[GSYM dist] THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_MESON_TAC[SUBSET; IN_BALL; DIST_SYM]; + ASM_MESON_TAC[PIECEWISE_DIFFERENTIABLE_ON_SUBSET]; + ASM SET_TAC[]]);; + +let PATH_INTEGRAL_LOCAL_PRIMITIVE = prove + (`!f g s. + (!x. x IN s + ==> ?d h. &0 < d /\ + !y. norm(y - x) < d + ==> (h has_complex_derivative f(y)) (at y within s)) /\ + valid_path g /\ (path_image g) SUBSET s + ==> f path_integrable_on g`, + REWRITE_TAC[valid_path; path_image; SUBSET; FORALL_IN_IMAGE] THEN + REWRITE_TAC[path_integrable_on; has_path_integral] THEN + REWRITE_TAC[HAS_INTEGRAL_LOCALIZED_VECTOR_DERIVATIVE] THEN + REWRITE_TAC[GSYM integrable_on; PATH_INTEGRAL_LOCAL_PRIMITIVE_ANY]);; + +(* ------------------------------------------------------------------------- *) +(* In particular if a function is holomorphic. *) +(* ------------------------------------------------------------------------- *) + +let PATH_INTEGRABLE_HOLOMORPHIC = prove + (`!f g s k. + open s /\ FINITE k /\ + f continuous_on s /\ + (!x. x IN s DIFF k ==> f complex_differentiable at x) /\ + valid_path g /\ path_image g SUBSET s + ==> f path_integrable_on g`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC PATH_INTEGRAL_LOCAL_PRIMITIVE THEN + EXISTS_TAC `s:complex->bool` THEN ASM_REWRITE_TAC[] THEN + X_GEN_TAC `z:complex` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [OPEN_CONTAINS_BALL]) THEN + DISCH_THEN(MP_TAC o SPEC `z:complex`) THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `d:real` THEN STRIP_TAC THEN + MP_TAC(ISPECL [`f:complex->complex`; `ball(z:complex,d)`; + `k:complex->bool`] HOLOMORPHIC_CONVEX_PRIMITIVE) THEN + ANTS_TAC THENL + [ASM_REWRITE_TAC[CONVEX_BALL; DIFF_EMPTY] THEN CONJ_TAC THENL + [ASM_MESON_TAC[CONTINUOUS_ON_SUBSET]; ALL_TAC] THEN + GEN_TAC THEN DISCH_THEN(fun th -> + FIRST_X_ASSUM MATCH_MP_TAC THEN MP_TAC th) THEN + SIMP_TAC[IN_DIFF] THEN ASM_MESON_TAC[INTERIOR_SUBSET; SUBSET]; + MATCH_MP_TAC MONO_EXISTS THEN + SIMP_TAC[HAS_COMPLEX_DERIVATIVE_WITHIN_OPEN; OPEN_BALL] THEN + ONCE_REWRITE_TAC[NORM_SUB] THEN REWRITE_TAC[IN_BALL; dist] THEN + ASM_MESON_TAC[HAS_COMPLEX_DERIVATIVE_AT_WITHIN]]);; + +let PATH_INTEGRABLE_HOLOMORPHIC_SIMPLE = prove + (`!f g s. open s /\ f holomorphic_on s /\ valid_path g /\ path_image g SUBSET s + ==> f path_integrable_on g`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC PATH_INTEGRABLE_HOLOMORPHIC THEN + MAP_EVERY EXISTS_TAC [`s:complex->bool`; `{}:complex->bool`] THEN + ASM_SIMP_TAC[HOLOMORPHIC_ON_IMP_CONTINUOUS_ON; FINITE_RULES; DIFF_EMPTY] THEN + ASM_MESON_TAC[HOLOMORPHIC_ON_OPEN; complex_differentiable]);; + +(* ------------------------------------------------------------------------- *) +(* Key fact that path integral is the same for a "nearby" path. This is the *) +(* main lemma for the homotopy form of Cauchy's theorem and is also useful *) +(* if we want "without loss of generality" to assume some niceness of our *) +(* path (e.g. smoothness). It can also be used to define the integrals of *) +(* analytic functions over arbitrary continuous paths. This is just done for *) +(* winding numbers now; I'm not sure if it's worth going further with that. *) +(* ------------------------------------------------------------------------- *) + +let PATH_INTEGRAL_NEARBY_ENDS,PATH_INTEGRAL_NEARBY_LOOP = (CONJ_PAIR o prove) + (`(!s p. + open s /\ path p /\ path_image p SUBSET s + ==> ?d. &0 < d /\ + !g h. valid_path g /\ valid_path h /\ + (!t. t IN interval[vec 0,vec 1] + ==> norm(g t - p t) < d /\ norm(h t - p t) < d) /\ + pathstart h = pathstart g /\ pathfinish h = pathfinish g + ==> path_image g SUBSET s /\ + path_image h SUBSET s /\ + !f. f holomorphic_on s + ==> path_integral h f = path_integral g f) /\ + (!s p. + open s /\ path p /\ path_image p SUBSET s + ==> ?d. &0 < d /\ + !g h. valid_path g /\ valid_path h /\ + (!t. t IN interval[vec 0,vec 1] + ==> norm(g t - p t) < d /\ norm(h t - p t) < d) /\ + pathfinish g = pathstart g /\ pathfinish h = pathstart h + ==> path_image g SUBSET s /\ + path_image h SUBSET s /\ + !f. f holomorphic_on s + ==> path_integral h f = path_integral g f)`, + REWRITE_TAC[AND_FORALL_THM] THEN REPEAT GEN_TAC THEN + MAP_EVERY (fun t -> ASM_CASES_TAC t THEN ASM_REWRITE_TAC[]) + [`open(s:complex->bool)`; + `path(p:real^1->complex)`; + `path_image(p:real^1->complex) SUBSET s`] THEN + REWRITE_TAC[RIGHT_IMP_EXISTS_THM] THEN + MATCH_MP_TAC(MESON[] `(?x. P x /\ Q x) ==> (?x. P x) /\ (?x. Q x)`) THEN + SUBGOAL_THEN + `!z. z IN path_image p ==> ?e. &0 < e /\ ball(z:complex,e) SUBSET s` + MP_TAC THENL + [ASM_MESON_TAC[OPEN_CONTAINS_BALL; SUBSET]; ALL_TAC] THEN + GEN_REWRITE_TAC (LAND_CONV o TOP_DEPTH_CONV) + [RIGHT_IMP_EXISTS_THM; RIGHT_AND_EXISTS_THM; SKOLEM_THM] THEN + REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN X_GEN_TAC `ee:complex->real` THEN + DISCH_THEN(LABEL_TAC "*") THEN + FIRST_ASSUM(MP_TAC o MATCH_MP COMPACT_IMP_HEINE_BOREL o + MATCH_MP COMPACT_PATH_IMAGE) THEN + DISCH_THEN(MP_TAC o SPEC + `IMAGE (\z:complex. ball(z,ee z / &3)) (path_image p)`) THEN + ANTS_TAC THENL + [REWRITE_TAC[FORALL_IN_IMAGE; OPEN_BALL; SUBSET] THEN + X_GEN_TAC `z:complex` THEN DISCH_TAC THEN + REWRITE_TAC[UNIONS_IMAGE; IN_ELIM_THM] THEN EXISTS_TAC `z:complex` THEN + ASM_SIMP_TAC[CENTRE_IN_BALL; REAL_ARITH `&0 < e / &3 <=> &0 < e`]; + ALL_TAC] THEN + REWRITE_TAC[path_image; GSYM IMAGE_o] THEN REWRITE_TAC[GSYM path_image] THEN + ONCE_REWRITE_TAC[TAUT `a /\ b /\ c <=> b /\ a /\ c`] THEN + REWRITE_TAC[CONJ_ASSOC; FINITE_SUBSET_IMAGE] THEN + REWRITE_TAC[LEFT_AND_EXISTS_THM; MESON[] + `(?f s. (P s /\ f = g s) /\ Q f) <=> ?s. P s /\ Q(g s)`] THEN + REWRITE_TAC[UNIONS_IMAGE; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `k:real^1->bool` THEN + DISCH_THEN(CONJUNCTS_THEN2 STRIP_ASSUME_TAC MP_TAC) THEN + GEN_REWRITE_TAC LAND_CONV [SUBSET] THEN REWRITE_TAC[IN_ELIM_THM; o_THM] THEN + ASM_CASES_TAC `k:real^1->bool = {}` THENL + [ASM_REWRITE_TAC[NOT_IN_EMPTY; GSYM NOT_EXISTS_THM; MEMBER_NOT_EMPTY] THEN + REWRITE_TAC[PATH_IMAGE_NONEMPTY]; + DISCH_THEN(LABEL_TAC "+")] THEN + SUBGOAL_THEN + `!i:real^1. i IN k ==> &0 < ee((p i):complex)` + ASSUME_TAC THENL + [ASM_MESON_TAC[SUBSET; path_image; IN_IMAGE]; ALL_TAC] THEN + ABBREV_TAC `e = inf(IMAGE ((ee:complex->real) o (p:real^1->complex)) k)` THEN + MP_TAC(ISPEC `IMAGE ((ee:complex->real) o (p:real^1->complex)) k` + INF_FINITE) THEN + MP_TAC(ISPECL [`IMAGE ((ee:complex->real) o (p:real^1->complex)) k`; `&0`] + REAL_LT_INF_FINITE) THEN + ASM_SIMP_TAC[FINITE_IMAGE; IMAGE_EQ_EMPTY; FORALL_IN_IMAGE] THEN + ASM_REWRITE_TAC[o_THM] THEN DISCH_TAC THEN + DISCH_THEN(ASSUME_TAC o CONJUNCT2) THEN + EXISTS_TAC `e / &3` THEN + MP_TAC(ISPECL [`p:real^1->complex`; `interval[vec 0:real^1,vec 1]`] + COMPACT_UNIFORMLY_CONTINUOUS) THEN REWRITE_TAC[COMPACT_INTERVAL] THEN + ANTS_TAC THENL [ASM_MESON_TAC[path]; ALL_TAC] THEN + REWRITE_TAC[uniformly_continuous_on] THEN + DISCH_THEN(MP_TAC o SPEC `e / &3`) THEN + ASM_REWRITE_TAC[REAL_ARITH `&0 < e / &3 <=> &0 < e`] THEN + DISCH_THEN(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC) THEN + REWRITE_TAC[RIGHT_IMP_FORALL_THM; AND_FORALL_THM] THEN + MAP_EVERY X_GEN_TAC [`g:real^1->complex`; `h:real^1->complex`] THEN + MAP_EVERY (fun t -> ASM_CASES_TAC t THEN ASM_REWRITE_TAC[]) + [`!t. t IN interval[vec 0,vec 1] + ==> norm((g:real^1->complex) t - p t) < e / &3 /\ + norm((h:real^1->complex) t - p t) < e / &3`; + `valid_path(g:real^1->complex)`; `valid_path(h:real^1->complex)`] THEN + MATCH_MP_TAC(TAUT + `q /\ (p1 \/ p2 ==> q ==> r) ==> (p1 ==> q /\ r) /\ (p2 ==> q /\ r)`) THEN + CONJ_TAC THENL + [CONJ_TAC THEN REWRITE_TAC[path_image; SUBSET; FORALL_IN_IMAGE] THEN + X_GEN_TAC `t:real^1` THEN DISCH_TAC THEN + REMOVE_THEN "+" (MP_TAC o SPEC `(p:real^1->complex) t`) THEN + ASM_SIMP_TAC[path_image; FUN_IN_IMAGE; IN_BALL] THEN + DISCH_THEN(X_CHOOSE_THEN `u:real^1` STRIP_ASSUME_TAC) THENL + [SUBGOAL_THEN `(g:real^1->complex) t IN ball(p(u:real^1),ee(p u))` + MP_TAC THENL [ALL_TAC; ASM_MESON_TAC[path_image; IN_IMAGE; SUBSET]]; + SUBGOAL_THEN `(h:real^1->complex) t IN ball(p(u:real^1),ee(p u))` + MP_TAC THENL [ALL_TAC; ASM_MESON_TAC[path_image; IN_IMAGE; SUBSET]]] THEN + REWRITE_TAC[IN_BALL] THEN FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP + (NORM_ARITH `dist(gu,gt) < eu / &3 + ==> norm(ht - gt) < e / &3 /\ e <= eu + ==> dist(gu,ht) < eu`)) THEN + ASM_SIMP_TAC[]; + DISCH_TAC THEN STRIP_TAC THEN + X_GEN_TAC `f:complex->complex` THEN DISCH_TAC] THEN + SUBGOAL_THEN + `?ff. !z. z IN path_image p + ==> &0 < ee z /\ ball(z,ee z) SUBSET s /\ + !w. w IN ball(z,ee z) + ==> (ff z has_complex_derivative f w) (at w)` + MP_TAC THENL + [REWRITE_TAC[GSYM SKOLEM_THM; RIGHT_EXISTS_IMP_THM; + RIGHT_EXISTS_AND_THM] THEN + X_GEN_TAC `z:complex` THEN DISCH_TAC THEN + REMOVE_THEN "*" (MP_TAC o SPEC `z:complex`) THEN + ASM_REWRITE_TAC[] THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + MP_TAC(ISPECL [`f:complex->complex`; `ball(z:complex,ee z)`; + `{}:complex->bool`] HOLOMORPHIC_CONVEX_PRIMITIVE) THEN + SIMP_TAC[HAS_COMPLEX_DERIVATIVE_WITHIN_OPEN; OPEN_BALL] THEN + DISCH_THEN MATCH_MP_TAC THEN REWRITE_TAC[CONVEX_BALL; FINITE_EMPTY] THEN + SIMP_TAC[DIFF_EMPTY; INTERIOR_OPEN; OPEN_BALL] THEN + SUBGOAL_THEN `f holomorphic_on ball(z,ee z)` MP_TAC THENL + [MATCH_MP_TAC HOLOMORPHIC_ON_SUBSET THEN EXISTS_TAC `s:complex->bool` THEN + ASM_REWRITE_TAC[]; + SIMP_TAC[HOLOMORPHIC_ON_IMP_CONTINUOUS_ON] THEN + SIMP_TAC[holomorphic_on; HAS_COMPLEX_DERIVATIVE_WITHIN_OPEN; OPEN_BALL; + complex_differentiable]]; + REMOVE_THEN "*" (K ALL_TAC) THEN + DISCH_THEN(CHOOSE_THEN (LABEL_TAC "*"))] THEN + MP_TAC(ISPEC `d:real` REAL_ARCH_INV) THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `N:num` STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN + `!n. n <= N + ==> path_integral(subpath (vec 0) (&n / &N % vec 1) h) f - + path_integral(subpath (vec 0) (&n / &N % vec 1) g) f = + path_integral(linepath (g(&n / &N % vec 1),h(&n / &N % vec 1))) f - + path_integral(linepath (g(vec 0),h(vec 0))) f` + (MP_TAC o SPEC `N:num`) THENL + [ALL_TAC; + ASM_SIMP_TAC[LE_REFL; REAL_DIV_REFL; REAL_OF_NUM_EQ; VECTOR_MUL_LID] THEN + FIRST_X_ASSUM(DISJ_CASES_THEN MP_TAC) THEN + REWRITE_TAC[pathstart; pathfinish] THEN STRIP_TAC THEN + ASM_REWRITE_TAC[SUBPATH_TRIVIAL; PATH_INTEGRAL_TRIVIAL] THEN + CONV_TAC COMPLEX_RING] THEN + INDUCT_TAC THENL + [REWRITE_TAC[real_div; REAL_MUL_LZERO; VECTOR_MUL_LZERO] THEN + FIRST_X_ASSUM(DISJ_CASES_THEN MP_TAC) THEN + REWRITE_TAC[pathstart; pathfinish] THEN REPEAT STRIP_TAC THEN + ASM_REWRITE_TAC[PATH_INTEGRAL_TRIVIAL; PATH_INTEGRAL_SUBPATH_REFL] THEN + REWRITE_TAC[COMPLEX_SUB_REFL]; + DISCH_TAC THEN FIRST_X_ASSUM(K ALL_TAC o check (is_disj o concl))] THEN + REMOVE_THEN "+" (MP_TAC o SPEC `(p:real^1->complex)(&n / &N % vec 1)`) THEN + REWRITE_TAC[IN_BALL] THEN ANTS_TAC THENL + [REWRITE_TAC[path_image] THEN MATCH_MP_TAC FUN_IN_IMAGE THEN + REWRITE_TAC[IN_INTERVAL_1; DROP_CMUL; DROP_VEC; REAL_MUL_RID] THEN + ASM_SIMP_TAC[REAL_LE_RDIV_EQ; REAL_LE_LDIV_EQ; REAL_OF_NUM_LT; LE_1] THEN + REWRITE_TAC[REAL_OF_NUM_MUL; REAL_OF_NUM_LE] THEN ASM_ARITH_TAC; + DISCH_THEN(X_CHOOSE_THEN `t:real^1` STRIP_ASSUME_TAC)] THEN + MP_TAC(ISPECL + [`(ff:complex->complex->complex) (p(t:real^1))`; `f:complex->complex`; + `subpath (&n / &N % vec 1) (&(SUC n) / &N % vec 1) (g:real^1->complex) ++ + linepath(g (&(SUC n) / &N % vec 1),h(&(SUC n) / &N % vec 1)) ++ + subpath (&(SUC n) / &N % vec 1) (&n / &N % vec 1) h ++ + linepath(h (&n / &N % vec 1),g (&n / &N % vec 1))`; + `ball((p:real^1->complex) t,ee(p t))`] CAUCHY_THEOREM_PRIMITIVE) THEN + ASM_SIMP_TAC[VALID_PATH_JOIN_EQ; PATHSTART_JOIN; PATHFINISH_JOIN; + PATHSTART_SUBPATH; PATHFINISH_SUBPATH; PATH_IMAGE_JOIN; PATHSTART_LINEPATH; + PATHFINISH_LINEPATH; VALID_PATH_LINEPATH; UNION_SUBSET] THEN + ONCE_REWRITE_TAC[IMP_CONJ] THEN ANTS_TAC THENL + [X_GEN_TAC `z:complex` THEN DISCH_TAC THEN + REMOVE_THEN "*" (MP_TAC o SPEC `(p:real^1->complex) t`) THEN ANTS_TAC THENL + [ASM_MESON_TAC[path_image; IN_IMAGE; SUBSET]; + ASM_SIMP_TAC[HAS_COMPLEX_DERIVATIVE_AT_WITHIN; CENTRE_IN_BALL]]; + ALL_TAC] THEN + MATCH_MP_TAC(TAUT `p /\ q /\ (p ==> r ==> s) ==> (p /\ q ==> r) ==> s`) THEN + CONJ_TAC THENL + [CONJ_TAC THEN MATCH_MP_TAC VALID_PATH_SUBPATH THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[IN_INTERVAL_1; DROP_CMUL; DROP_VEC; REAL_MUL_RID] THEN + ASM_SIMP_TAC[REAL_LE_RDIV_EQ; REAL_LE_LDIV_EQ; REAL_OF_NUM_LT; LE_1] THEN + REWRITE_TAC[REAL_OF_NUM_MUL; REAL_OF_NUM_LE] THEN ASM_ARITH_TAC; + ALL_TAC] THEN + CONJ_TAC THENL + [SUBGOAL_THEN `drop(&n / &N % vec 1) <= drop(&(SUC n) / &N % vec 1)` + ASSUME_TAC THENL + [ASM_SIMP_TAC[DROP_CMUL; DROP_VEC; REAL_MUL_RID; REAL_LE_DIV2_EQ; + REAL_OF_NUM_LT; LE_1; REAL_OF_NUM_LE] THEN + ARITH_TAC; + ASM_SIMP_TAC[PATH_IMAGE_SUBPATH; PATH_IMAGE_LINEPATH] THEN + ONCE_REWRITE_TAC[GSYM REVERSEPATH_SUBPATH] THEN + ASM_SIMP_TAC[PATH_IMAGE_SUBPATH; PATH_IMAGE_REVERSEPATH]] THEN + MATCH_MP_TAC(TAUT + `(p /\ r) /\ (p /\ r ==> q /\ s) ==> p /\ q /\ r /\ s`) THEN + CONJ_TAC THENL + [REWRITE_TAC[SUBSET; FORALL_IN_IMAGE] THEN + REWRITE_TAC[AND_FORALL_THM; TAUT + `(p ==> q) /\ (p ==> r) <=> p ==> q /\ r`] THEN + X_GEN_TAC `u:real^1` THEN REWRITE_TAC[IN_INTERVAL_1] THEN + REWRITE_TAC[DROP_CMUL; DROP_VEC; REAL_MUL_RID] THEN STRIP_TAC THEN + REWRITE_TAC[IN_BALL] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (NORM_ARITH + `!e pu. dist(pt,pn) < ee / &3 + ==> dist(pn,pu) < e / &3 /\ e <= ee /\ + norm(gu - pu) < e / &3 /\ norm(hu - pu) < e / &3 + ==> dist(pt,gu) < ee /\ dist(pt,hu) < ee`)) THEN + MAP_EVERY EXISTS_TAC [`e:real`; `(p:real^1->complex) u`] THEN + ASM_SIMP_TAC[] THEN + SUBGOAL_THEN `(u:real^1) IN interval[vec 0,vec 1]` ASSUME_TAC THENL + [REWRITE_TAC[IN_INTERVAL_1; DROP_VEC] THEN CONJ_TAC THENL + [FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ_ALT] + REAL_LE_TRANS)) THEN ASM_SIMP_TAC[REAL_LE_DIV; REAL_POS]; + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + REAL_LE_TRANS)) THEN + ASM_SIMP_TAC[REAL_LE_LDIV_EQ; REAL_OF_NUM_LT; LE_1] THEN + ASM_REWRITE_TAC[REAL_MUL_LID; REAL_OF_NUM_LE]]; + ASM_SIMP_TAC[] THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_REWRITE_TAC[] THEN + REWRITE_TAC[DIST_REAL; GSYM drop; IN_INTERVAL_1; + DROP_VEC; DROP_CMUL; REAL_MUL_RID] THEN + ASM_SIMP_TAC[REAL_LE_LDIV_EQ; REAL_POS; REAL_LE_DIV; + REAL_OF_NUM_LT; LE_1; REAL_MUL_LID; REAL_OF_NUM_LE; + ARITH_RULE `SUC n <= N ==> n <= N`] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH + `u <= s ==> n <= u /\ s - n < d ==> abs(n - u) < d`)) THEN + ASM_REWRITE_TAC[] THEN + REWRITE_TAC[real_div; GSYM REAL_SUB_RDISTRIB] THEN + SIMP_TAC[REAL_OF_NUM_SUB; ARITH_RULE `n <= SUC n`] THEN + ASM_REWRITE_TAC[ARITH_RULE `SUC n - n = 1`; REAL_MUL_LID]]; + GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [SUBSET] THEN + REWRITE_TAC[FORALL_IN_IMAGE] THEN STRIP_TAC THEN + REWRITE_TAC[SEGMENT_CONVEX_HULL] THEN CONJ_TAC THEN + MATCH_MP_TAC HULL_MINIMAL THEN REWRITE_TAC[CONVEX_BALL] THEN + REWRITE_TAC[INSERT_SUBSET; EMPTY_SUBSET] THEN + CONJ_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + REWRITE_TAC[ENDS_IN_INTERVAL; INTERVAL_EQ_EMPTY_1; REAL_NOT_LT] THEN + REWRITE_TAC[DROP_VEC; DROP_CMUL; REAL_MUL_RID] THEN + ASM_SIMP_TAC[REAL_LE_DIV2_EQ; REAL_POS; REAL_LE_DIV; + REAL_OF_NUM_LT; LE_1; REAL_MUL_LID; REAL_OF_NUM_LE] THEN + ARITH_TAC]; + STRIP_TAC THEN DISCH_THEN(fun th -> + MP_TAC(MATCH_MP PATH_INTEGRAL_UNIQUE th) THEN + MP_TAC(MATCH_MP HAS_PATH_INTEGRAL_INTEGRABLE th)) THEN + ASM_SIMP_TAC[PATH_INTEGRABLE_JOIN; VALID_PATH_JOIN_EQ; VALID_PATH_LINEPATH; + PATHSTART_SUBPATH; PATHFINISH_SUBPATH; PATHSTART_JOIN; PATHFINISH_JOIN; + PATHSTART_LINEPATH; PATHFINISH_LINEPATH; VALID_PATH_LINEPATH; + PATH_INTEGRAL_JOIN] THEN + STRIP_TAC THEN FIRST_X_ASSUM(MP_TAC o check(is_imp o concl)) THEN + ASM_SIMP_TAC[ARITH_RULE `SUC n <= N ==> n <= N`] THEN + MATCH_MP_TAC(COMPLEX_RING + `hn - he = hn' /\ gn + gd = gn' /\ hgn = --ghn + ==> hn - gn = ghn - gh0 + ==> gd + ghn' + he + hgn = Cx(&0) + ==> hn' - gn' = ghn' - gh0`) THEN + REPEAT CONJ_TAC THENL + [ASM_SIMP_TAC[complex_sub; GSYM PATH_INTEGRAL_REVERSEPATH] THEN + REWRITE_TAC[REVERSEPATH_SUBPATH] THEN + MATCH_MP_TAC PATH_INTEGRAL_SUBPATH_COMBINE; + MATCH_MP_TAC PATH_INTEGRAL_SUBPATH_COMBINE; + GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) + [GSYM REVERSEPATH_LINEPATH] THEN + MATCH_MP_TAC PATH_INTEGRAL_REVERSEPATH] THEN + ASM_REWRITE_TAC[VALID_PATH_LINEPATH] THEN + ASM_REWRITE_TAC[IN_INTERVAL_1; DROP_CMUL; DROP_VEC; REAL_MUL_RID] THEN + ASM_SIMP_TAC[REAL_LE_DIV; REAL_POS; REAL_LE_LDIV_EQ; REAL_OF_NUM_LT; LE_1; + REAL_MUL_LID; REAL_OF_NUM_LE] THEN + ASM_SIMP_TAC[ARITH_RULE `SUC n <= N ==> n <= N`] THEN + TRY(MATCH_MP_TAC PATH_INTEGRABLE_HOLOMORPHIC_SIMPLE THEN + EXISTS_TAC `s:complex->bool` THEN ASM_REWRITE_TAC[] THEN NO_TAC) THEN + ASM_MESON_TAC[PATH_INTEGRABLE_REVERSEPATH; VALID_PATH_LINEPATH; + REVERSEPATH_LINEPATH]]);; + +(* ------------------------------------------------------------------------- *) +(* Hence we can treat even non-rectifiable paths as having a "length" *) +(* for bounds on analytic functions in open sets. *) +(* ------------------------------------------------------------------------- *) + +let VALID_PATH_VECTOR_POLYNOMIAL_FUNCTION = prove + (`!p:real^1->complex. + vector_polynomial_function p ==> valid_path p`, + REPEAT STRIP_TAC THEN REWRITE_TAC[valid_path] THEN + MATCH_MP_TAC DIFFERENTIABLE_ON_IMP_PIECEWISE_DIFFERENTIABLE THEN + MATCH_MP_TAC DIFFERENTIABLE_AT_IMP_DIFFERENTIABLE_ON THEN + REWRITE_TAC[VECTOR_DERIVATIVE_WORKS] THEN + REPEAT STRIP_TAC THEN REWRITE_TAC[vector_derivative] THEN + CONV_TAC SELECT_CONV THEN + ASM_MESON_TAC[HAS_VECTOR_DERIVATIVE_VECTOR_POLYNOMIAL_FUNCTION]);; + +let PATH_INTEGRAL_BOUND_EXISTS = prove + (`!s g. open s /\ valid_path g /\ path_image g SUBSET s + ==> ?L. &0 < L /\ + !f B. f holomorphic_on s /\ (!z. z IN s ==> norm(f z) <= B) + ==> norm(path_integral g f) <= L * B`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`s:complex->bool`; `g:real^1->complex`] + PATH_INTEGRAL_NEARBY_ENDS) THEN + ASM_SIMP_TAC[VALID_PATH_IMP_PATH] THEN + DISCH_THEN(X_CHOOSE_THEN `d:real` (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + DISCH_THEN(MP_TAC o SPEC `g:real^1->complex`) THEN + ASM_REWRITE_TAC[VECTOR_SUB_REFL; NORM_0] THEN + DISCH_THEN(STRIP_ASSUME_TAC o GSYM) THEN + MP_TAC(ISPECL [`g:real^1->complex`; `d:real`] + PATH_APPROX_VECTOR_POLYNOMIAL_FUNCTION) THEN + ASM_SIMP_TAC[VALID_PATH_IMP_PATH] THEN + DISCH_THEN(X_CHOOSE_THEN `p:real^1->complex` STRIP_ASSUME_TAC) THEN + FIRST_X_ASSUM(MP_TAC o SPEC `p:real^1->complex`) THEN + ASM_SIMP_TAC[VALID_PATH_VECTOR_POLYNOMIAL_FUNCTION] THEN STRIP_TAC THEN + FIRST_ASSUM(X_CHOOSE_THEN `p':real^1->complex` STRIP_ASSUME_TAC o + MATCH_MP HAS_VECTOR_DERIVATIVE_VECTOR_POLYNOMIAL_FUNCTION) THEN + SUBGOAL_THEN `bounded(IMAGE (p':real^1->complex) (interval[vec 0,vec 1]))` + MP_TAC THENL + [MATCH_MP_TAC COMPACT_IMP_BOUNDED THEN + MATCH_MP_TAC COMPACT_CONTINUOUS_IMAGE THEN + REWRITE_TAC[COMPACT_INTERVAL] THEN + ASM_MESON_TAC[CONTINUOUS_VECTOR_POLYNOMIAL_FUNCTION; + CONTINUOUS_AT_IMP_CONTINUOUS_ON]; + REWRITE_TAC[BOUNDED_POS; FORALL_IN_IMAGE]] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `L:real` THEN STRIP_TAC THEN + ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN + SUBGOAL_THEN `f path_integrable_on p /\ valid_path p` STRIP_ASSUME_TAC THENL + [ASM_MESON_TAC[PATH_INTEGRABLE_HOLOMORPHIC_SIMPLE; + VALID_PATH_VECTOR_POLYNOMIAL_FUNCTION]; + ALL_TAC] THEN + MP_TAC(ISPECL [`f:complex->complex`; `p:real^1->complex`] + PATH_INTEGRAL_INTEGRAL) THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN SUBST1_TAC THEN MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC + `drop(integral (interval[vec 0,vec 1]) (\x:real^1. lift(L * B)))` THEN + CONJ_TAC THENL + [MATCH_MP_TAC INTEGRAL_NORM_BOUND_INTEGRAL THEN + ASM_REWRITE_TAC[INTEGRABLE_CONST; GSYM PATH_INTEGRABLE_ON] THEN + X_GEN_TAC `t:real^1` THEN DISCH_TAC THEN + ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN + REWRITE_TAC[LIFT_DROP; COMPLEX_NORM_MUL] THEN + MATCH_MP_TAC REAL_LE_MUL2 THEN REWRITE_TAC[NORM_POS_LE] THEN + CONJ_TAC THENL + [FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_MESON_TAC[path_image; SUBSET; IN_IMAGE]; + ASM_MESON_TAC[HAS_VECTOR_DERIVATIVE_UNIQUE_AT]]; + REWRITE_TAC[INTEGRAL_CONST; CONTENT_UNIT_1; VECTOR_MUL_LID] THEN + REWRITE_TAC[LIFT_DROP; REAL_LE_REFL]]);; + +(* ------------------------------------------------------------------------- *) +(* Winding number. *) +(* ------------------------------------------------------------------------- *) + +let winding_number = new_definition + `winding_number(g,z) = + @n. !e. &0 < e + ==> ?p. valid_path p /\ ~(z IN path_image p) /\ + pathstart p = pathstart g /\ + pathfinish p = pathfinish g /\ + (!t. t IN interval[vec 0,vec 1] ==> norm(g t - p t) < e) /\ + path_integral p (\w. Cx(&1) / (w - z)) = + Cx(&2) * Cx(pi) * ii * n`;; + +let CX_2PII_NZ = prove + (`~(Cx(&2) * Cx(pi) * ii = Cx(&0))`, + SIMP_TAC[COMPLEX_ENTIRE; CX_PI_NZ; II_NZ; CX_INJ; REAL_OF_NUM_EQ; ARITH]);; + +let PATH_INTEGRABLE_INVERSEDIFF = prove + (`!g z. valid_path g /\ ~(z IN path_image g) + ==> (\w. Cx(&1) / (w - z)) path_integrable_on g`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC PATH_INTEGRABLE_HOLOMORPHIC_SIMPLE THEN + EXISTS_TAC `(:complex) DELETE z` THEN + ASM_SIMP_TAC[OPEN_DELETE; OPEN_UNIV; HOLOMORPHIC_ON_OPEN; SET_RULE + `s SUBSET (UNIV DELETE x) <=> ~(x IN s)`] THEN + X_GEN_TAC `w:complex` THEN REWRITE_TAC[IN_UNIV; IN_DELETE] THEN + STRIP_TAC THEN + W(MP_TAC o DISCH_ALL o COMPLEX_DIFF_CONV o snd o dest_exists o snd) THEN + ASM_REWRITE_TAC[COMPLEX_SUB_0] THEN MESON_TAC[]);; + +let WINDING_NUMBER = prove + (`!g z e. + path g /\ ~(z IN path_image g) /\ &0 < e + ==> ?p. valid_path p /\ ~(z IN path_image p) /\ + pathstart p = pathstart g /\ + pathfinish p = pathfinish g /\ + (!t. t IN interval[vec 0,vec 1] ==> norm(g t - p t) < e) /\ + path_integral p (\w. Cx(&1) / (w - z)) = + Cx(&2) * Cx(pi) * ii * winding_number(g,z)`, + REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN + GEN_TAC THEN DISCH_TAC THEN GEN_TAC THEN DISCH_TAC THEN + REWRITE_TAC[winding_number] THEN CONV_TAC SELECT_CONV THEN + MP_TAC(ISPECL [`(:complex) DELETE z`; `g:real^1->complex`] + PATH_INTEGRAL_NEARBY_ENDS) THEN + ASM_SIMP_TAC[OPEN_DELETE; OPEN_UNIV] THEN + ANTS_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + DISCH_THEN(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC) THEN + MP_TAC(ISPECL [`g:real^1->complex`; `d / &2`] + PATH_APPROX_VECTOR_POLYNOMIAL_FUNCTION) THEN + ASM_REWRITE_TAC[REAL_HALF] THEN + DISCH_THEN(X_CHOOSE_THEN `h:real^1->complex` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `Cx (&1) / (Cx (&2) * Cx pi * ii) * + path_integral h (\w. Cx (&1) / (w - z))` THEN + X_GEN_TAC `e:real` THEN DISCH_TAC THEN + MP_TAC(ISPECL [`g:real^1->complex`; `min d e / &2`] + PATH_APPROX_VECTOR_POLYNOMIAL_FUNCTION) THEN + ASM_REWRITE_TAC[REAL_HALF; REAL_LT_MIN] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `p:real^1->complex` THEN + STRIP_TAC THEN + ASM_SIMP_TAC[VALID_PATH_VECTOR_POLYNOMIAL_FUNCTION; CX_2PII_NZ; COMPLEX_FIELD + `~(a * b * c = Cx(&0)) + ==> a * b * c * Cx(&1) / (a * b * c) * z = z`] THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`h:real^1->complex`; `p:real^1->complex`]) THEN + ANTS_TAC THENL + [ASM_SIMP_TAC[VALID_PATH_VECTOR_POLYNOMIAL_FUNCTION] THEN + ASM_MESON_TAC[NORM_ARITH + `norm(h - g) < d / &2 /\ norm(p - g) < min d e / &2 + ==> norm(h - g) < d /\ norm(p - g) < d`]; + ALL_TAC] THEN + REWRITE_TAC[SET_RULE `t SUBSET UNIV DELETE x <=> ~(x IN t)`] THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN CONJ_TAC THENL + [ASM_MESON_TAC[NORM_SUB; REAL_ARITH `&0 < e /\ x < min d e / &2 ==> x < e`]; + ALL_TAC] THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_SIMP_TAC[OPEN_DELETE; OPEN_UNIV; HOLOMORPHIC_ON_OPEN] THEN + REWRITE_TAC[IN_DELETE; IN_UNIV; GSYM complex_differentiable] THEN + REPEAT STRIP_TAC THEN COMPLEX_DIFFERENTIABLE_TAC THEN + ASM_REWRITE_TAC[COMPLEX_SUB_0]);; + +let WINDING_NUMBER_UNIQUE = prove + (`!g z e n. + path g /\ ~(z IN path_image g) /\ + (!e. &0 < e + ==> ?p. valid_path p /\ ~(z IN path_image p) /\ + pathstart p = pathstart g /\ + pathfinish p = pathfinish g /\ + (!t. t IN interval[vec 0,vec 1] + ==> norm(g t - p t) < e) /\ + path_integral p (\w. Cx(&1) / (w - z)) = + Cx(&2) * Cx(pi) * ii * n) + ==> winding_number(g,z) = n`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`(:complex) DELETE z`; `g:real^1->complex`] + PATH_INTEGRAL_NEARBY_ENDS) THEN + ASM_SIMP_TAC[OPEN_DELETE; OPEN_UNIV] THEN + ANTS_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + DISCH_THEN(X_CHOOSE_THEN `e:real` STRIP_ASSUME_TAC) THEN + FIRST_X_ASSUM(MP_TAC o SPEC `e:real`) THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `p:real^1->complex` STRIP_ASSUME_TAC) THEN + MP_TAC(ISPECL [`g:real^1->complex`; `z:complex`] WINDING_NUMBER) THEN + DISCH_THEN(MP_TAC o SPEC `e:real`) THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `q:real^1->complex` STRIP_ASSUME_TAC) THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`p:real^1->complex`; `q:real^1->complex`]) THEN + ASM_REWRITE_TAC[] THEN ONCE_REWRITE_TAC[NORM_SUB] THEN ASM_SIMP_TAC[] THEN + STRIP_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC `\w. Cx(&1) / (w - z)`) THEN + ANTS_TAC THENL + [ASM_SIMP_TAC[OPEN_DELETE; OPEN_UNIV; HOLOMORPHIC_ON_OPEN] THEN + REWRITE_TAC[IN_DELETE; IN_UNIV; GSYM complex_differentiable] THEN + REPEAT STRIP_TAC THEN COMPLEX_DIFFERENTIABLE_TAC THEN + ASM_REWRITE_TAC[COMPLEX_SUB_0]; + ASM_REWRITE_TAC[] THEN MP_TAC CX_2PII_NZ THEN + CONV_TAC COMPLEX_RING]);; + +let WINDING_NUMBER_UNIQUE_LOOP = prove + (`!g z e n. + path g /\ ~(z IN path_image g) /\ pathfinish g = pathstart g /\ + (!e. &0 < e + ==> ?p. valid_path p /\ ~(z IN path_image p) /\ + pathfinish p = pathstart p /\ + (!t. t IN interval[vec 0,vec 1] + ==> norm(g t - p t) < e) /\ + path_integral p (\w. Cx(&1) / (w - z)) = + Cx(&2) * Cx(pi) * ii * n) + ==> winding_number(g,z) = n`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`(:complex) DELETE z`; `g:real^1->complex`] + PATH_INTEGRAL_NEARBY_LOOP) THEN + ASM_SIMP_TAC[OPEN_DELETE; OPEN_UNIV] THEN + ANTS_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + DISCH_THEN(X_CHOOSE_THEN `e:real` STRIP_ASSUME_TAC) THEN + FIRST_X_ASSUM(MP_TAC o SPEC `e:real`) THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `p:real^1->complex` STRIP_ASSUME_TAC) THEN + MP_TAC(ISPECL [`g:real^1->complex`; `z:complex`] WINDING_NUMBER) THEN + DISCH_THEN(MP_TAC o SPEC `e:real`) THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `q:real^1->complex` STRIP_ASSUME_TAC) THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`p:real^1->complex`; `q:real^1->complex`]) THEN + ASM_REWRITE_TAC[] THEN ONCE_REWRITE_TAC[NORM_SUB] THEN ASM_SIMP_TAC[] THEN + STRIP_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC `\w. Cx(&1) / (w - z)`) THEN + ANTS_TAC THENL + [ASM_SIMP_TAC[OPEN_DELETE; OPEN_UNIV; HOLOMORPHIC_ON_OPEN] THEN + REWRITE_TAC[IN_DELETE; IN_UNIV; GSYM complex_differentiable] THEN + REPEAT STRIP_TAC THEN COMPLEX_DIFFERENTIABLE_TAC THEN + ASM_REWRITE_TAC[COMPLEX_SUB_0]; + ASM_REWRITE_TAC[] THEN MP_TAC CX_2PII_NZ THEN + CONV_TAC COMPLEX_RING]);; + +let WINDING_NUMBER_VALID_PATH = prove + (`!g z. valid_path g /\ ~(z IN path_image g) + ==> winding_number(g,z) = + Cx(&1) / (Cx(&2) * Cx(pi) * ii) * + path_integral g (\w. Cx(&1) / (w - z))`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC WINDING_NUMBER_UNIQUE THEN + ASM_SIMP_TAC[VALID_PATH_IMP_PATH] THEN + X_GEN_TAC `e:real` THEN DISCH_TAC THEN + EXISTS_TAC `g:real^1->complex` THEN + ASM_REWRITE_TAC[VECTOR_SUB_REFL; NORM_0] THEN + MP_TAC CX_2PII_NZ THEN CONV_TAC COMPLEX_FIELD);; + +let HAS_PATH_INTEGRAL_WINDING_NUMBER = prove + (`!g z. valid_path g /\ ~(z IN path_image g) + ==> ((\w. Cx(&1) / (w - z)) has_path_integral + (Cx(&2) * Cx(pi) * ii * winding_number(g,z))) g`, + REPEAT STRIP_TAC THEN ASM_SIMP_TAC[WINDING_NUMBER_VALID_PATH] THEN + ASM_SIMP_TAC[CX_2PII_NZ; COMPLEX_FIELD + `~(a * b * c = Cx(&0)) + ==> a * b * c * Cx(&1) / (a * b * c) * z = z`] THEN + MATCH_MP_TAC HAS_PATH_INTEGRAL_INTEGRAL THEN + ASM_SIMP_TAC[PATH_INTEGRABLE_INVERSEDIFF]);; + +let WINDING_NUMBER_TRIVIAL = prove + (`!a z. ~(z = a) ==> winding_number(linepath(a,a),z) = Cx(&0)`, + SIMP_TAC[VALID_PATH_LINEPATH; PATH_INTEGRAL_TRIVIAL; COMPLEX_MUL_RZERO; + WINDING_NUMBER_VALID_PATH; PATH_IMAGE_LINEPATH; SEGMENT_REFL; + IN_SING]);; + +let WINDING_NUMBER_JOIN = prove + (`!g1 g2 z. + path g1 /\ path g2 /\ pathfinish g1 = pathstart g2 /\ + ~(z IN path_image g1) /\ ~(z IN path_image g2) + ==> winding_number(g1 ++ g2,z) = + winding_number(g1,z) + winding_number(g2,z)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC WINDING_NUMBER_UNIQUE THEN + ASM_SIMP_TAC[PATH_JOIN; PATH_IMAGE_JOIN; IN_UNION] THEN + X_GEN_TAC `e:real` THEN DISCH_TAC THEN + MP_TAC(ISPECL [`g2:real^1->complex`; `z:complex`; `e:real`] + WINDING_NUMBER) THEN + MP_TAC(ISPECL [`g1:real^1->complex`; `z:complex`; `e:real`] + WINDING_NUMBER) THEN + ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `p1:real^1->complex` THEN STRIP_TAC THEN + X_GEN_TAC `p2:real^1->complex` THEN STRIP_TAC THEN + EXISTS_TAC `p1 ++ p2:real^1->complex` THEN + ASM_SIMP_TAC[VALID_PATH_JOIN; PATHSTART_JOIN; PATHFINISH_JOIN] THEN + ASM_SIMP_TAC[PATH_IMAGE_JOIN; IN_UNION] THEN CONJ_TAC THENL + [REWRITE_TAC[joinpaths; IN_INTERVAL_1; DROP_VEC] THEN REPEAT STRIP_TAC THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_REWRITE_TAC[IN_INTERVAL_1; DROP_VEC; DROP_CMUL; DROP_SUB] THEN + ASM_REAL_ARITH_TAC; + W(MP_TAC o PART_MATCH (lhs o rand) PATH_INTEGRAL_JOIN o lhand o snd) THEN + ASM_REWRITE_TAC[COMPLEX_ADD_LDISTRIB] THEN + DISCH_THEN MATCH_MP_TAC THEN + CONJ_TAC THEN MATCH_MP_TAC PATH_INTEGRABLE_INVERSEDIFF THEN + ASM_REWRITE_TAC[]]);; + +let WINDING_NUMBER_REVERSEPATH = prove + (`!g z. path g /\ ~(z IN path_image g) + ==> winding_number(reversepath g,z) = --(winding_number(g,z))`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC WINDING_NUMBER_UNIQUE THEN + ASM_SIMP_TAC[PATH_REVERSEPATH; PATH_IMAGE_REVERSEPATH] THEN + X_GEN_TAC `e:real` THEN DISCH_TAC THEN + MP_TAC(ISPECL [`g:real^1->complex`; `z:complex`; `e:real`] + WINDING_NUMBER) THEN + ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `p:real^1->complex` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `reversepath p:real^1->complex` THEN + ASM_SIMP_TAC[VALID_PATH_REVERSEPATH; PATH_IMAGE_REVERSEPATH; + PATHSTART_REVERSEPATH; PATHFINISH_REVERSEPATH; + PATH_INTEGRAL_REVERSEPATH; PATH_INTEGRABLE_INVERSEDIFF] THEN + REWRITE_TAC[COMPLEX_MUL_RNEG; reversepath; IN_INTERVAL_1; DROP_VEC] THEN + REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + REWRITE_TAC[IN_INTERVAL_1; DROP_VEC; DROP_SUB] THEN ASM_REAL_ARITH_TAC);; + +let WINDING_NUMBER_SHIFTPATH = prove + (`!g a z. path g /\ pathfinish g = pathstart g /\ ~(z IN path_image g) /\ + a IN interval[vec 0,vec 1] + ==> winding_number(shiftpath a g,z) = winding_number(g,z)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC WINDING_NUMBER_UNIQUE_LOOP THEN + ASM_SIMP_TAC[PATH_SHIFTPATH; PATH_IMAGE_SHIFTPATH] THEN CONJ_TAC THENL + [RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1; DROP_VEC]) THEN + ASM_SIMP_TAC[PATHSTART_SHIFTPATH; PATHFINISH_SHIFTPATH]; + ALL_TAC] THEN + X_GEN_TAC `e:real` THEN DISCH_TAC THEN + MP_TAC(ISPECL [`g:real^1->complex`; `z:complex`; `e:real`] + WINDING_NUMBER) THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `p:real^1->complex` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `shiftpath a p:real^1->complex` THEN + ASM_SIMP_TAC[VALID_PATH_SHIFTPATH; PATH_IMAGE_SHIFTPATH; + PATH_INTEGRAL_SHIFTPATH; PATH_INTEGRABLE_INVERSEDIFF] THEN + RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1; DROP_VEC]) THEN + ASM_SIMP_TAC[PATHSTART_SHIFTPATH; PATHFINISH_SHIFTPATH] THEN + SIMP_TAC[COMPLEX_MUL_RNEG; shiftpath; IN_INTERVAL_1; DROP_ADD; DROP_VEC] THEN + REPEAT STRIP_TAC THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN + REWRITE_TAC[IN_INTERVAL_1; DROP_VEC; DROP_SUB; DROP_ADD] THEN + ASM_REAL_ARITH_TAC);; + +let WINDING_NUMBER_SPLIT_LINEPATH = prove + (`!a b c z. + c IN segment[a,b] /\ ~(z IN segment[a,b]) + ==> winding_number(linepath(a,b),z) = + winding_number(linepath(a,c),z) + + winding_number(linepath(c,b),z)`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN `~((z:complex) IN segment[a,c]) /\ ~(z IN segment[c,b])` + STRIP_ASSUME_TAC THENL + [CONJ_TAC THEN FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE + `~(z IN s) ==> t SUBSET s ==> ~(z IN t)`)) THEN + ASM_REWRITE_TAC[SUBSET_SEGMENT; ENDS_IN_SEGMENT]; + ASM_SIMP_TAC[WINDING_NUMBER_VALID_PATH; PATH_IMAGE_LINEPATH; + VALID_PATH_LINEPATH] THEN + REWRITE_TAC[GSYM COMPLEX_ADD_LDISTRIB] THEN AP_TERM_TAC THEN + MATCH_MP_TAC PATH_INTEGRAL_SPLIT_LINEPATH THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC CONTINUOUS_ON_COMPLEX_DIV THEN + SIMP_TAC[CONTINUOUS_ON_CONST; CONTINUOUS_ON_SUB; CONTINUOUS_ON_ID] THEN + ASM_MESON_TAC[COMPLEX_SUB_0]]);; + +let WINDING_NUMBER_EQUAL = prove + (`!p q z. (!t. t IN interval[vec 0,vec 1] ==> p t = q t) + ==> winding_number(p,z) = winding_number(q,z)`, + REPEAT STRIP_TAC THEN SIMP_TAC[winding_number; PATH_INTEGRAL_INTEGRAL] THEN + AP_TERM_TAC THEN GEN_REWRITE_TAC I [FUN_EQ_THM] THEN + X_GEN_TAC `W:complex` THEN REWRITE_TAC[] THEN + AP_TERM_TAC THEN GEN_REWRITE_TAC I [FUN_EQ_THM] THEN + X_GEN_TAC `e:real` THEN REWRITE_TAC[] THEN + ASM_CASES_TAC `&0 < e` THEN ASM_REWRITE_TAC[] THEN + AP_TERM_TAC THEN GEN_REWRITE_TAC I [FUN_EQ_THM] THEN + X_GEN_TAC `g:real^1->complex` THEN + ASM_SIMP_TAC[pathstart; pathfinish; ENDS_IN_UNIT_INTERVAL]);; + +let WINDING_NUMBER_OFFSET = prove + (`!p z. winding_number(p,z) = winding_number((\w. p w - z),Cx(&0))`, + REPEAT GEN_TAC THEN REWRITE_TAC[winding_number; PATH_INTEGRAL_INTEGRAL] THEN + AP_TERM_TAC THEN GEN_REWRITE_TAC I [FUN_EQ_THM] THEN + X_GEN_TAC `W:complex` THEN REWRITE_TAC[] THEN + AP_TERM_TAC THEN GEN_REWRITE_TAC I [FUN_EQ_THM] THEN + X_GEN_TAC `e:real` THEN REWRITE_TAC[] THEN + ASM_CASES_TAC `&0 < e` THEN + ASM_REWRITE_TAC[path_image; valid_path; pathstart; pathfinish] THEN + EQ_TAC THEN + DISCH_THEN(X_CHOOSE_THEN `g:real^1->complex` STRIP_ASSUME_TAC) THENL + [EXISTS_TAC `\t. (g:real^1->complex) t - z`; + EXISTS_TAC `\t. (g:real^1->complex) t + z`] THEN + ASM_REWRITE_TAC[COMPLEX_RING `(p - z) - (g - z):complex = p - g`; + COMPLEX_RING `p - (g + z):complex = p - z - g`; + COMPLEX_RING `(p - z) + z:complex = p`; + COMPLEX_SUB_RZERO] THEN + RULE_ASSUM_TAC(REWRITE_RULE[IN_IMAGE]) THEN + ASM_SIMP_TAC[PIECEWISE_DIFFERENTIABLE_ADD; PIECEWISE_DIFFERENTIABLE_SUB; + DIFFERENTIABLE_ON_IMP_PIECEWISE_DIFFERENTIABLE; + DIFFERENTIABLE_ON_CONST; IN_IMAGE] THEN + ASM_REWRITE_TAC[COMPLEX_RING `Cx(&0) = w - z <=> z = w`; + COMPLEX_RING `z = w + z <=> Cx(&0) = w`] THEN + FIRST_X_ASSUM(fun th -> GEN_REWRITE_TAC RAND_CONV [SYM th]) THEN + MATCH_MP_TAC INTEGRAL_EQ THEN X_GEN_TAC `t:real^1` THEN STRIP_TAC THEN + REWRITE_TAC[COMPLEX_RING `(w + z) - z = w - Cx(&0)`] THEN AP_TERM_TAC THEN + REWRITE_TAC[vector_derivative; has_vector_derivative; HAS_DERIVATIVE_AT; + COMPLEX_RING `(x - z) - (w - z):complex = x - w`; + COMPLEX_RING `(x + z) - (w + z):complex = x - w`]);; + +(* ------------------------------------------------------------------------- *) +(* A combined theorem deducing several things piecewise. *) +(* ------------------------------------------------------------------------- *) + +let WINDING_NUMBER_JOIN_POS_COMBINED = prove + (`!g1 g2 z. + (valid_path g1 /\ + ~(z IN path_image g1) /\ + &0 < Re(winding_number(g1,z))) /\ + (valid_path g2 /\ + ~(z IN path_image g2) /\ + &0 < Re(winding_number(g2,z))) /\ + pathfinish g1 = pathstart g2 + ==> valid_path(g1 ++ g2) /\ + ~(z IN path_image(g1 ++ g2)) /\ + &0 < Re(winding_number(g1 ++ g2,z))`, + REPEAT GEN_TAC THEN STRIP_TAC THEN ASM_SIMP_TAC[VALID_PATH_JOIN] THEN + ASM_SIMP_TAC[PATH_IMAGE_JOIN; VALID_PATH_IMP_PATH; IN_UNION] THEN + ASM_SIMP_TAC[WINDING_NUMBER_JOIN; VALID_PATH_IMP_PATH; RE_ADD] THEN + ASM_REAL_ARITH_TAC);; + +(* ------------------------------------------------------------------------- *) +(* Useful sufficient conditions for the winding number to be positive etc. *) +(* ------------------------------------------------------------------------- *) + +let RE_WINDING_NUMBER = prove + (`!g z. valid_path g /\ ~(z IN path_image g) + ==> Re(winding_number(g,z)) = + Im(path_integral g (\w. Cx(&1) / (w - z))) / (&2 * pi)`, + SIMP_TAC[WINDING_NUMBER_VALID_PATH; complex_div; COMPLEX_MUL_LID] THEN + REPEAT STRIP_TAC THEN REWRITE_TAC[COMPLEX_MUL_ASSOC; GSYM CX_MUL] THEN + REWRITE_TAC[COMPLEX_INV_MUL; GSYM CX_INV; COMPLEX_INV_II] THEN + REWRITE_TAC[COMPLEX_MUL_LNEG; COMPLEX_MUL_RNEG; RE_NEG] THEN + REWRITE_TAC[GSYM COMPLEX_MUL_ASSOC; RE_MUL_CX; RE_MUL_II] THEN + MP_TAC PI_POS THEN CONV_TAC REAL_FIELD);; + +let WINDING_NUMBER_POS_LE = prove + (`!g z. valid_path g /\ ~(z IN path_image g) /\ + (!x. x IN interval(vec 0,vec 1) + ==> &0 <= Im(vector_derivative g (at x) * cnj(g x - z))) + ==> &0 <= Re(winding_number(g,z))`, + REPEAT STRIP_TAC THEN ASM_SIMP_TAC[RE_WINDING_NUMBER] THEN + MATCH_MP_TAC REAL_LE_DIV THEN + SIMP_TAC[REAL_LE_MUL; REAL_POS; PI_POS; REAL_LT_IMP_LE; IM_DEF] THEN + MATCH_MP_TAC(INST_TYPE [`:1`,`:M`; `:2`,`:N`] + HAS_INTEGRAL_COMPONENT_POS) THEN + MAP_EVERY EXISTS_TAC + [`\x:real^1. if x IN interval(vec 0,vec 1) + then Cx(&1) / (g x - z) * vector_derivative g (at x) + else Cx(&0)`; + `interval[vec 0:real^1,vec 1]`] THEN + REWRITE_TAC[ARITH; DIMINDEX_2] THEN CONJ_TAC THENL + [MATCH_MP_TAC HAS_INTEGRAL_SPIKE_INTERIOR THEN + EXISTS_TAC `\x:real^1. Cx(&1) / (g x - z) * vector_derivative g (at x)` THEN + ASM_SIMP_TAC[] THEN REWRITE_TAC[GSYM HAS_PATH_INTEGRAL] THEN + MATCH_MP_TAC HAS_PATH_INTEGRAL_INTEGRAL THEN + ASM_SIMP_TAC[PATH_INTEGRABLE_INVERSEDIFF]; + ALL_TAC] THEN + X_GEN_TAC `x:real^1` THEN DISCH_TAC THEN COND_CASES_TAC THEN + ASM_REWRITE_TAC[GSYM IM_DEF; IM_CX; REAL_LE_REFL] THEN + FIRST_X_ASSUM(MP_TAC o SPEC `x:real^1`) THEN + ASM_REWRITE_TAC[complex_div; COMPLEX_MUL_LID] THEN + REWRITE_TAC[complex_inv; complex_inv; complex_mul; RE; IM; cnj] THEN + REWRITE_TAC[real_div; REAL_RING + `(a * x) * b + (--c * x) * d:real = x * (a * b - c * d)`] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_LE_MUL THEN + SIMP_TAC[REAL_POW_2; REAL_LE_INV_EQ; REAL_LE_ADD; REAL_LE_SQUARE] THEN + ASM_REAL_ARITH_TAC);; + +let WINDING_NUMBER_POS_LT_LEMMA = prove + (`!g z e. valid_path g /\ ~(z IN path_image g) /\ &0 < e /\ + (!x. x IN interval(vec 0,vec 1) + ==> e <= Im(vector_derivative g (at x) / (g x - z))) + ==> &0 < Re(winding_number(g,z))`, + REPEAT STRIP_TAC THEN ASM_SIMP_TAC[RE_WINDING_NUMBER] THEN + MATCH_MP_TAC REAL_LT_DIV THEN + SIMP_TAC[REAL_LT_MUL; REAL_OF_NUM_LT; ARITH; PI_POS] THEN + MATCH_MP_TAC REAL_LTE_TRANS THEN EXISTS_TAC `Im(ii * Cx e)` THEN + CONJ_TAC THENL + [ASM_REWRITE_TAC[COMPLEX_MUL_LNEG; IM_MUL_II; IM_NEG; RE_CX]; ALL_TAC] THEN + REWRITE_TAC[IM_DEF] THEN + MATCH_MP_TAC(ISPECL [`\x:real^1. ii * Cx e`; + `\x:real^1. if x IN interval(vec 0,vec 1) + then Cx(&1) / (g x - z) * vector_derivative g (at x) + else ii * Cx e`; + `interval[vec 0:real^1,vec 1]`; `ii * Cx e`; + `path_integral g (\w. Cx(&1) / (w - z))`; `2`] + HAS_INTEGRAL_COMPONENT_LE) THEN + REWRITE_TAC[DIMINDEX_2; ARITH] THEN REPEAT CONJ_TAC THENL + [GEN_REWRITE_TAC LAND_CONV [GSYM VECTOR_MUL_LID] THEN + ONCE_REWRITE_TAC[GSYM CONTENT_UNIT_1] THEN + REWRITE_TAC[HAS_INTEGRAL_CONST]; + MATCH_MP_TAC HAS_INTEGRAL_SPIKE_INTERIOR THEN + EXISTS_TAC `\x:real^1. Cx(&1) / (g x - z) * vector_derivative g (at x)` THEN + ASM_SIMP_TAC[] THEN REWRITE_TAC[GSYM HAS_PATH_INTEGRAL] THEN + MATCH_MP_TAC HAS_PATH_INTEGRAL_INTEGRAL THEN + ASM_SIMP_TAC[PATH_INTEGRABLE_INVERSEDIFF]; + X_GEN_TAC `x:real^1` THEN DISCH_TAC THEN COND_CASES_TAC THEN + ASM_REWRITE_TAC[GSYM IM_DEF; IM_CX; REAL_LE_REFL] THEN + REWRITE_TAC[IM_MUL_II; RE_CX] THEN + FIRST_X_ASSUM(MP_TAC o SPEC `x:real^1`) THEN + ASM_REWRITE_TAC[complex_div; COMPLEX_MUL_LID; COMPLEX_MUL_SYM]]);; + +let WINDING_NUMBER_POS_LT = prove + (`!g z e. valid_path g /\ ~(z IN path_image g) /\ &0 < e /\ + (!x. x IN interval(vec 0,vec 1) + ==> e <= Im(vector_derivative g (at x) * cnj(g x - z))) + ==> &0 < Re(winding_number(g,z))`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN `bounded (IMAGE (\w. w - z) (path_image g))` MP_TAC THENL + [REWRITE_TAC[path_image; GSYM IMAGE_o] THEN + MATCH_MP_TAC COMPACT_IMP_BOUNDED THEN + MATCH_MP_TAC COMPACT_CONTINUOUS_IMAGE THEN + REWRITE_TAC[COMPACT_INTERVAL] THEN + MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN + SIMP_TAC[CONTINUOUS_ON_SUB; CONTINUOUS_ON_CONST; CONTINUOUS_ON_ID] THEN + MATCH_MP_TAC PIECEWISE_DIFFERENTIABLE_ON_IMP_CONTINUOUS_ON THEN + ASM_REWRITE_TAC[GSYM valid_path]; + ALL_TAC] THEN + REWRITE_TAC[BOUNDED_POS; FORALL_IN_IMAGE] THEN + DISCH_THEN(X_CHOOSE_THEN `B:real` STRIP_ASSUME_TAC) THEN + MATCH_MP_TAC WINDING_NUMBER_POS_LT_LEMMA THEN + EXISTS_TAC `e:real / B pow 2` THEN + ASM_SIMP_TAC[REAL_LT_DIV; REAL_POW_LT] THEN + X_GEN_TAC `x:real^1` THEN DISCH_TAC THEN + ONCE_REWRITE_TAC[COMPLEX_DIV_CNJ] THEN + REWRITE_TAC[real_div; complex_div; GSYM CX_INV; GSYM CX_POW] THEN + REWRITE_TAC[IM_MUL_CX] THEN MATCH_MP_TAC REAL_LE_MUL2 THEN + ASM_SIMP_TAC[REAL_LT_IMP_LE; REAL_LE_INV_EQ; REAL_POW_LE] THEN + MATCH_MP_TAC REAL_LE_INV2 THEN CONJ_TAC THENL + [MATCH_MP_TAC REAL_POW_LT THEN REWRITE_TAC[NORM_POS_LT; VECTOR_SUB_EQ] THEN + UNDISCH_TAC `~((z:complex) IN path_image g)`; + MATCH_MP_TAC REAL_POW_LE2 THEN REWRITE_TAC[NORM_POS_LE] THEN + FIRST_X_ASSUM MATCH_MP_TAC] THEN + REWRITE_TAC[path_image; IN_IMAGE] THEN + ASM_MESON_TAC[SUBSET; INTERVAL_OPEN_SUBSET_CLOSED]);; + +(* ------------------------------------------------------------------------- *) +(* The winding number is an integer (proof from Ahlfors's book). *) +(* ------------------------------------------------------------------------- *) + +let WINDING_NUMBER_AHLFORS_LEMMA = prove + (`!g a b. + g piecewise_differentiable_on interval [a,b] /\ + drop a <= drop b /\ (!x. x IN interval [a,b] ==> ~(g x = z)) + ==> (\x. vector_derivative g (at x within interval[a,b]) / (g(x) - z)) + integrable_on interval[a,b] /\ + cexp(--(integral (interval[a,b]) + (\x. vector_derivative g (at x within interval[a,b]) / + (g(x) - z)))) * + (g(b) - z) = g(a) - z`, + let lemma = prove + (`!f g g' s x z. + (g has_vector_derivative g') (at x within s) /\ + (f has_vector_derivative (g' / (g x - z))) (at x within s) /\ + ~(g x = z) + ==> ((\x. cexp(--f x) * (g x - z)) has_vector_derivative Cx(&0)) + (at x within s)`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN + `cexp(--f x) * (g' - Cx(&0)) + + (cexp(--f x) * --(g' / ((g:real^1->complex) x - z))) * (g x - z) = Cx(&0)` + (SUBST1_TAC o SYM) + THENL + [FIRST_X_ASSUM(MP_TAC o check (is_neg o concl)) THEN + CONV_TAC COMPLEX_FIELD; + ALL_TAC] THEN + MATCH_MP_TAC(ISPEC `( * ):complex->complex->complex` + HAS_VECTOR_DERIVATIVE_BILINEAR_WITHIN) THEN + REWRITE_TAC[BILINEAR_COMPLEX_MUL; GSYM COMPLEX_VEC_0] THEN + ASM_SIMP_TAC[HAS_VECTOR_DERIVATIVE_SUB; ETA_AX; + HAS_VECTOR_DERIVATIVE_CONST] THEN + GEN_REWRITE_TAC (RATOR_CONV o LAND_CONV) [GSYM o_DEF] THEN + REWRITE_TAC[has_vector_derivative] THEN + SUBGOAL_THEN `!x y. (\z. drop z % (x * y :complex)) = + (\w. x * w) o (\z. drop z % y)` + (fun th -> REWRITE_TAC[th]) + THENL + [REWRITE_TAC[FUN_EQ_THM; o_THM; COMPLEX_CMUL] THEN + SIMPLE_COMPLEX_ARITH_TAC; + ALL_TAC] THEN + MATCH_MP_TAC DIFF_CHAIN_WITHIN THEN + REWRITE_TAC[GSYM has_complex_derivative; GSYM has_vector_derivative] THEN + SIMP_TAC[HAS_COMPLEX_DERIVATIVE_CEXP; HAS_COMPLEX_DERIVATIVE_AT_WITHIN] THEN + ASM_SIMP_TAC[HAS_VECTOR_DERIVATIVE_NEG]) in + REPEAT GEN_TAC THEN STRIP_TAC THEN + SUBGOAL_THEN + `!w. ~(w = z) + ==> ?h. !y. norm(y - w) < norm(w - z) + ==> (h has_complex_derivative inv(y - z)) (at y)` + (LABEL_TAC "P") + THENL + [REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`\w:complex. inv(w - z)`; + `ball(w:complex,norm(w - z))`; + `{}:complex->bool`] + HOLOMORPHIC_CONVEX_PRIMITIVE) THEN + SIMP_TAC[HAS_COMPLEX_DERIVATIVE_WITHIN_OPEN; OPEN_BALL; INTERIOR_OPEN] THEN + REWRITE_TAC[CONVEX_BALL; FINITE_RULES; DIFF_EMPTY] THEN ANTS_TAC THENL + [SUBGOAL_THEN `(\w. inv(w - z)) holomorphic_on ball(w:complex,norm(w - z))` + (fun th -> + MESON_TAC[HOLOMORPHIC_ON_OPEN; HOLOMORPHIC_ON_IMP_CONTINUOUS_ON; + OPEN_BALL; complex_differentiable; th]) THEN + SIMP_TAC[HOLOMORPHIC_ON_OPEN; OPEN_BALL; IN_BALL] THEN + X_GEN_TAC `u:complex` THEN DISCH_TAC THEN + EXISTS_TAC `--Cx(&1) / (u - z) pow 2` THEN COMPLEX_DIFF_TAC THEN + REWRITE_TAC[COMPLEX_SUB_RZERO; COMPLEX_SUB_0] THEN + ASM_MESON_TAC[REAL_LT_REFL; dist]; + ALL_TAC] THEN + REWRITE_TAC[IN_BALL; dist] THEN MESON_TAC[NORM_SUB]; + ALL_TAC] THEN + SUBGOAL_THEN + `!t. t IN interval[a,b] + ==> (\x. vector_derivative g (at x within interval[a,b]) / (g(x) - z)) + integrable_on interval[a,t] /\ + cexp(--(integral (interval[a,t]) + (\x. vector_derivative g (at x within interval[a,b]) / + (g(x) - z)))) * + (g(t) - z) = g(a) - z` + (fun th -> MATCH_MP_TAC th THEN + ASM_REWRITE_TAC[IN_INTERVAL_1; REAL_LE_REFL]) THEN + REWRITE_TAC[TAUT `a ==> b /\ c <=> (a ==> b) /\ (a ==> c)`] THEN + REWRITE_TAC[FORALL_AND_THM] THEN + MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN CONJ_TAC THENL + [REPEAT STRIP_TAC THEN MATCH_MP_TAC INTEGRABLE_SUBINTERVAL THEN + MAP_EVERY EXISTS_TAC [`a:real^1`; `b:real^1`] THEN + ASM_REWRITE_TAC[SUBSET_INTERVAL_1; REAL_LE_REFL] THEN + CONJ_TAC THENL [ALL_TAC; ASM_MESON_TAC[IN_INTERVAL_1]] THEN + REWRITE_TAC[integrable_on; complex_div] THEN + ONCE_REWRITE_TAC[COMPLEX_MUL_SYM] THEN + REWRITE_TAC[HAS_INTEGRAL_LOCALIZED_VECTOR_DERIVATIVE] THEN + REWRITE_TAC[GSYM integrable_on] THEN + MATCH_MP_TAC PATH_INTEGRAL_LOCAL_PRIMITIVE_ANY THEN + EXISTS_TAC `(:complex) DELETE z` THEN + ASM_SIMP_TAC[IN_DELETE; IN_UNIV; + DIFFERENTIABLE_ON_IMP_PIECEWISE_DIFFERENTIABLE] THEN + X_GEN_TAC `w:complex` THEN DISCH_TAC THEN + EXISTS_TAC `norm(w - z:complex)` THEN + ASM_REWRITE_TAC[COMPLEX_NORM_NZ; COMPLEX_SUB_0] THEN + ASM_MESON_TAC[HAS_COMPLEX_DERIVATIVE_AT_WITHIN]; + ALL_TAC] THEN + DISCH_TAC THEN MATCH_MP_TAC HAS_DERIVATIVE_ZERO_UNIQUE_STRONG_INTERVAL THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [piecewise_differentiable_on]) THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + MATCH_MP_TAC MONO_EXISTS THEN SIMP_TAC[IN_DIFF; FINITE_IMP_COUNTABLE] THEN + X_GEN_TAC `k:real^1->bool` THEN STRIP_TAC THEN + ASM_SIMP_TAC[CONVEX_INTERVAL; INTEGRAL_REFL] THEN + REWRITE_TAC[COMPLEX_VEC_0; COMPLEX_NEG_0; CEXP_0; COMPLEX_MUL_LID] THEN + CONJ_TAC THENL + [MATCH_MP_TAC CONTINUOUS_ON_COMPLEX_MUL THEN + ASM_SIMP_TAC[CONTINUOUS_ON_SUB; CONTINUOUS_ON_CONST; ETA_AX; + PIECEWISE_DIFFERENTIABLE_ON_IMP_CONTINUOUS_ON] THEN + GEN_REWRITE_TAC LAND_CONV [GSYM o_DEF] THEN + MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN + REWRITE_TAC[CONTINUOUS_ON_CEXP] THEN + MATCH_MP_TAC CONTINUOUS_ON_NEG THEN + MATCH_MP_TAC INDEFINITE_INTEGRAL_CONTINUOUS_RIGHT THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_REWRITE_TAC[IN_INTERVAL_1; REAL_LE_REFL]; + ALL_TAC] THEN + X_GEN_TAC `t:real^1` THEN DISCH_TAC THEN + MP_TAC(ISPECL [`\w:complex. inv(w - z)`; + `ball((g:real^1->complex) t,dist(g t,z))`; + `{}:complex->bool`] + HOLOMORPHIC_CONVEX_PRIMITIVE) THEN + SIMP_TAC[HAS_COMPLEX_DERIVATIVE_WITHIN_OPEN; OPEN_BALL; INTERIOR_OPEN] THEN + REWRITE_TAC[CONVEX_BALL; FINITE_RULES; DIFF_EMPTY] THEN ANTS_TAC THENL + [SUBGOAL_THEN `(\w. inv(w - z)) holomorphic_on ball(g(t:real^1),dist(g t,z))` + (fun th -> + MESON_TAC[HOLOMORPHIC_ON_OPEN; HOLOMORPHIC_ON_IMP_CONTINUOUS_ON; + OPEN_BALL; complex_differentiable; th]) THEN + SIMP_TAC[HOLOMORPHIC_ON_OPEN; OPEN_BALL; IN_BALL] THEN + X_GEN_TAC `w:complex` THEN DISCH_TAC THEN + EXISTS_TAC `--Cx(&1) / (w - z) pow 2` THEN COMPLEX_DIFF_TAC THEN + REWRITE_TAC[COMPLEX_SUB_RZERO; COMPLEX_SUB_0] THEN + ASM_MESON_TAC[REAL_LT_REFL]; + ALL_TAC] THEN + REWRITE_TAC[IN_BALL; dist] THEN + DISCH_THEN(X_CHOOSE_TAC `h:complex->complex`) THEN + SUBGOAL_THEN `(\h. Cx(&0)) = (\h. drop h % Cx(&0))` SUBST1_TAC THENL + [REWRITE_TAC[FUN_EQ_THM; GSYM COMPLEX_VEC_0; VECTOR_MUL_RZERO]; + ALL_TAC] THEN + REWRITE_TAC[GSYM has_vector_derivative] THEN MATCH_MP_TAC lemma THEN + EXISTS_TAC `vector_derivative g (at t within interval[a,b]):complex` THEN + REPEAT CONJ_TAC THENL + [REWRITE_TAC[GSYM VECTOR_DERIVATIVE_WORKS] THEN + ASM_MESON_TAC[DIFFERENTIABLE_AT_WITHIN]; + ALL_TAC; + ASM_MESON_TAC[]] THEN + REWRITE_TAC[has_vector_derivative] THEN + MATCH_MP_TAC HAS_DERIVATIVE_TRANSFORM_WITHIN THEN + ASM_REWRITE_TAC[GSYM has_vector_derivative] THEN + EXISTS_TAC `\u. integral (interval [a,t]) + (\x. vector_derivative g (at x within interval [a,b]) / + ((g:real^1->complex) x - z)) + (h(g(u)) - h(g(t)))` THEN + REWRITE_TAC[LEFT_EXISTS_AND_THM; CONJ_ASSOC] THEN + REWRITE_TAC[GSYM CONJ_ASSOC] THEN CONJ_TAC THENL + [ALL_TAC; + ONCE_REWRITE_TAC[COMPLEX_RING `a + (b - c) = b + (a - c):complex`] THEN + GEN_REWRITE_TAC LAND_CONV [GSYM VECTOR_ADD_RID] THEN + MATCH_MP_TAC HAS_VECTOR_DERIVATIVE_ADD THEN + REWRITE_TAC[HAS_VECTOR_DERIVATIVE_CONST] THEN + REWRITE_TAC[has_vector_derivative] THEN + SUBGOAL_THEN `!x y. (\h. drop h % x / y) = + (\x. inv(y) * x) o (\h. drop h % x)` + (fun th -> REWRITE_TAC[th]) + THENL + [REWRITE_TAC[FUN_EQ_THM; o_THM; COMPLEX_CMUL] THEN + SIMPLE_COMPLEX_ARITH_TAC; + ALL_TAC] THEN + GEN_REWRITE_TAC (RATOR_CONV o LAND_CONV) [GSYM o_DEF] THEN + MATCH_MP_TAC DIFF_CHAIN_WITHIN THEN + REWRITE_TAC[GSYM has_complex_derivative; GSYM has_vector_derivative] THEN + REWRITE_TAC[GSYM VECTOR_DERIVATIVE_WORKS] THEN + CONJ_TAC THENL [ASM_MESON_TAC[DIFFERENTIABLE_AT_WITHIN]; ALL_TAC] THEN + MATCH_MP_TAC HAS_COMPLEX_DERIVATIVE_AT_WITHIN THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN + REWRITE_TAC[COMPLEX_SUB_REFL; COMPLEX_NORM_0; COMPLEX_NORM_NZ] THEN + ASM_SIMP_TAC[COMPLEX_SUB_0]] THEN + SUBGOAL_THEN + `?d. &0 < d /\ + !y:real^1. y IN interval[a,b] /\ dist(y,t) < d + ==> dist(g y:complex,g t) < norm(g t - z) /\ ~(y IN k)` + MP_TAC THENL + [SUBGOAL_THEN `(g:real^1->complex) continuous (at t within interval[a,b])` + MP_TAC THENL + [ASM_MESON_TAC[PIECEWISE_DIFFERENTIABLE_ON_IMP_CONTINUOUS_ON; + CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN]; + ALL_TAC] THEN + REWRITE_TAC[continuous_within] THEN + DISCH_THEN(MP_TAC o SPEC `norm((g:real^1->complex) t - z)`) THEN + ASM_SIMP_TAC[COMPLEX_NORM_NZ; COMPLEX_SUB_0] THEN + DISCH_THEN(X_CHOOSE_THEN `d1:real` STRIP_ASSUME_TAC) THEN + FIRST_X_ASSUM(X_CHOOSE_THEN `d2:real` STRIP_ASSUME_TAC o + SPEC `t:real^1` o MATCH_MP FINITE_SET_AVOID) THEN + EXISTS_TAC `min d1 d2` THEN ASM_SIMP_TAC[REAL_LT_MIN] THEN + ASM_MESON_TAC[DIST_SYM; REAL_NOT_LE]; + ALL_TAC] THEN + REWRITE_TAC[TAUT `a ==> b /\ c <=> (a ==> b) /\ (a ==> c)`] THEN + REWRITE_TAC[FORALL_AND_THM] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `d:real` THEN STRIP_TAC THEN + ASM_REWRITE_TAC[] THEN X_GEN_TAC `u:real^1` THEN REWRITE_TAC[dist] THEN + STRIP_TAC THEN + DISJ_CASES_TAC(REAL_ARITH `drop t <= drop u \/ drop u <= drop t`) THENL + [SUBGOAL_THEN + `integral (interval [a,u]) + (\x. vector_derivative g (at x within interval [a,b]) / (g x - z)) = + integral (interval [a,t]) + (\x. vector_derivative g (at x within interval [a,b]) / (g x - z)) + + integral (interval [t,u]) + (\x. vector_derivative g (at x within interval [a,b]) / (g x - z))` + SUBST1_TAC THENL + [CONV_TAC SYM_CONV THEN MATCH_MP_TAC INTEGRAL_COMBINE THEN + ASM_MESON_TAC[IN_INTERVAL_1]; + ALL_TAC] THEN + SIMP_TAC[COMPLEX_RING `a + x = a + y <=> y:complex = x`]; + SUBGOAL_THEN + `integral (interval [a,t]) + (\x. vector_derivative g (at x within interval [a,b]) / (g x - z)) = + integral (interval [a,u]) + (\x. vector_derivative g (at x within interval [a,b]) / (g x - z)) + + integral (interval [u,t]) + (\x. vector_derivative g (at x within interval [a,b]) / (g x - z))` + SUBST1_TAC THENL + [CONV_TAC SYM_CONV THEN MATCH_MP_TAC INTEGRAL_COMBINE THEN + ASM_MESON_TAC[IN_INTERVAL_1]; + ALL_TAC] THEN + SIMP_TAC[COMPLEX_RING `(a + x) + (w - z) = a <=> x:complex = z - w`]] THEN + (MATCH_MP_TAC INTEGRAL_UNIQUE THEN + MATCH_MP_TAC FUNDAMENTAL_THEOREM_OF_CALCULUS THEN + ASM_REWRITE_TAC[GSYM o_DEF] THEN X_GEN_TAC `x:real^1` THEN + REPEAT STRIP_TAC THEN REWRITE_TAC[has_vector_derivative; COMPLEX_CMUL] THEN + SUBGOAL_THEN `!x y. (\h. Cx(drop h) * x / y) = + (\x. inv(y) * x) o (\h. drop h % x)` + (fun th -> REWRITE_TAC[th]) + THENL + [REWRITE_TAC[FUN_EQ_THM; o_THM; COMPLEX_CMUL] THEN + SIMPLE_COMPLEX_ARITH_TAC; + ALL_TAC] THEN + MATCH_MP_TAC DIFF_CHAIN_WITHIN THEN + REWRITE_TAC[GSYM has_complex_derivative; GSYM has_vector_derivative] THEN + CONJ_TAC THENL + [MATCH_MP_TAC HAS_VECTOR_DERIVATIVE_WITHIN_SUBSET THEN + EXISTS_TAC `interval[a:real^1,b]` THEN + REWRITE_TAC[GSYM VECTOR_DERIVATIVE_WORKS] THEN CONJ_TAC THENL + [MATCH_MP_TAC DIFFERENTIABLE_AT_WITHIN THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN CONJ_TAC THENL + [ALL_TAC; FIRST_X_ASSUM MATCH_MP_TAC]; + ALL_TAC] THEN + REPEAT(FIRST_X_ASSUM(MP_TAC o + check (fun t -> not(is_forall (concl t))))) THEN + REWRITE_TAC[dist; NORM_REAL; GSYM drop; DROP_SUB] THEN + REWRITE_TAC[SUBSET_INTERVAL_1; IN_INTERVAL_1; REAL_LE_REFL] THEN + REAL_ARITH_TAC; + ALL_TAC] THEN + MATCH_MP_TAC HAS_COMPLEX_DERIVATIVE_AT_WITHIN THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN GEN_REWRITE_TAC LAND_CONV [GSYM dist] THEN + ONCE_REWRITE_TAC[DIST_SYM] THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + CONJ_TAC THENL [ASM_MESON_TAC[IN_INTERVAL_1; REAL_LE_TRANS]; ALL_TAC] THEN + REPEAT(FIRST_X_ASSUM(MP_TAC o + check (fun t -> not(is_forall (concl t))))) THEN + REWRITE_TAC[dist; NORM_REAL; GSYM drop; DROP_SUB] THEN + REWRITE_TAC[SUBSET_INTERVAL_1; IN_INTERVAL_1; REAL_LE_REFL] THEN + REAL_ARITH_TAC));; + +let WINDING_NUMBER_AHLFORS = prove + (`!g z a b. + g piecewise_differentiable_on interval [a,b] /\ + drop a <= drop b /\ (!x. x IN interval [a,b] ==> ~(g x = z)) + ==> (\x. vector_derivative g (at x) / (g(x) - z)) + integrable_on interval[a,b] /\ + cexp(--(integral (interval[a,b]) + (\x. vector_derivative g (at x) / (g(x) - z)))) * + (g(b) - z) = g(a) - z`, + REPEAT GEN_TAC THEN STRIP_TAC THEN + REWRITE_TAC[integrable_on; integral] THEN + REWRITE_TAC[ONCE_REWRITE_RULE[COMPLEX_MUL_SYM] complex_div] THEN + REWRITE_TAC[GSYM HAS_INTEGRAL_LOCALIZED_VECTOR_DERIVATIVE] THEN + ONCE_REWRITE_TAC[ONCE_REWRITE_RULE[COMPLEX_MUL_SYM](GSYM complex_div)] THEN + REWRITE_TAC[GSYM integral; GSYM integrable_on] THEN + MATCH_MP_TAC WINDING_NUMBER_AHLFORS_LEMMA THEN ASM_REWRITE_TAC[]);; + +let WINDING_NUMBER_AHLFORS_FULL = prove + (`!p z. path p /\ ~(z IN path_image p) + ==> pathfinish p - z = + cexp(Cx(&2) * Cx pi * ii * winding_number(p,z)) * + (pathstart p - z)`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`p:real^1->complex`; `z:complex`; `&1`] WINDING_NUMBER) THEN + ASM_REWRITE_TAC[REAL_LT_01; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `g:real^1->complex` THEN STRIP_TAC THEN + REPEAT(FIRST_X_ASSUM(SUBST_ALL_TAC o SYM)) THEN + RULE_ASSUM_TAC(REWRITE_RULE[valid_path; path_image; IN_IMAGE; + NOT_EXISTS_THM]) THEN + MP_TAC(ISPECL + [`g:real^1->complex`; `z:complex`; `vec 0:real^1`; `vec 1:real^1`] + WINDING_NUMBER_AHLFORS) THEN + ASM_SIMP_TAC[DROP_VEC; REAL_POS; pathstart; pathfinish] THEN ANTS_TAC THENL + [ASM_MESON_TAC[]; DISCH_THEN(SUBST1_TAC o SYM o CONJUNCT2)] THEN + REWRITE_TAC[GSYM CEXP_ADD; COMPLEX_MUL_ASSOC; PATH_INTEGRAL_INTEGRAL] THEN + REWRITE_TAC[SIMPLE_COMPLEX_ARITH `Cx(&1) / z * w = w / z`] THEN + REWRITE_TAC[GSYM complex_sub; COMPLEX_SUB_REFL; CEXP_0; COMPLEX_MUL_LID]);; + +(* ------------------------------------------------------------------------- *) +(* State in terms of complex integers. Note the useful equality version. *) +(* ------------------------------------------------------------------------- *) + +let complex_integer = new_definition + `complex_integer z <=> integer(Re z) /\ Im z = &0`;; + +let COMPLEX_INTEGER = prove + (`complex_integer z <=> ?n. integer n /\ z = Cx n`, + REWRITE_TAC[COMPLEX_EQ; RE_CX; IM_CX; complex_integer] THEN MESON_TAC[]);; + +let INTEGER_WINDING_NUMBER_EQ = prove + (`!g z. path g /\ ~(z IN path_image g) + ==> (complex_integer(winding_number(g,z)) <=> + pathfinish g = pathstart g)`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPEC `(:complex) DIFF path_image g` OPEN_CONTAINS_BALL) THEN + ASM_SIMP_TAC[GSYM closed; CLOSED_PATH_IMAGE; VALID_PATH_IMP_PATH] THEN + DISCH_THEN(MP_TAC o SPEC `z:complex`) THEN + ASM_REWRITE_TAC[IN_DIFF; IN_UNIV; SUBSET; IN_BALL] THEN + DISCH_THEN(X_CHOOSE_THEN `e:real` STRIP_ASSUME_TAC) THEN + MP_TAC(ISPECL [`g:real^1->complex`; `z:complex`; `e:real`] + WINDING_NUMBER) THEN + ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `p:real^1->complex` STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN + `complex_integer(winding_number(p,z)) <=> + pathfinish p = pathstart p` + MP_TAC THENL + [UNDISCH_THEN + `path_integral p (\w. Cx (&1) / (w - z)) = + Cx (&2) * Cx pi * ii * winding_number (g,z)` (K ALL_TAC) THEN + ASM_SIMP_TAC[WINDING_NUMBER_VALID_PATH]; + ASM_SIMP_TAC[WINDING_NUMBER_VALID_PATH; CX_2PII_NZ; COMPLEX_FIELD + `~(a * b * c = Cx(&0)) + ==> Cx(&1) / (a * b * c) * a * b * c * z = z`]] THEN + UNDISCH_THEN `pathstart p:complex = pathstart g` (SUBST_ALL_TAC o SYM) THEN + UNDISCH_THEN `pathfinish p:complex = pathfinish g` (SUBST_ALL_TAC o SYM) THEN + RULE_ASSUM_TAC(REWRITE_RULE[valid_path; path_image]) THEN + REWRITE_TAC[pathfinish; pathstart] THEN + MATCH_MP_TAC EQ_TRANS THEN + EXISTS_TAC `cexp(path_integral p (\w. Cx(&1) / (w - z))) = Cx(&1)` THEN + CONJ_TAC THENL + [REWRITE_TAC[CEXP_EQ_1; complex_integer] THEN + REWRITE_TAC[complex_div; COMPLEX_MUL_LID; COMPLEX_INV_MUL] THEN + SIMP_TAC[GSYM CX_INV; GSYM CX_MUL; COMPLEX_MUL_ASSOC; COMPLEX_INV_II] THEN + REWRITE_TAC[RE_MUL_CX; IM_MUL_CX; GSYM COMPLEX_MUL_ASSOC] THEN + REWRITE_TAC[COMPLEX_MUL_LNEG; RE_MUL_II; IM_MUL_II; RE_NEG; IM_NEG] THEN + REWRITE_TAC[REAL_NEGNEG; REAL_ENTIRE; REAL_INV_EQ_0; REAL_NEG_EQ_0] THEN + SIMP_TAC[REAL_OF_NUM_EQ; ARITH; REAL_LT_IMP_NZ; PI_POS] THEN + SIMP_TAC[PI_POS; REAL_FIELD + `&0 < p ==> (x = &2 * n * p <=> (inv(&2) * inv(p)) * x = n)`] THEN + MESON_TAC[]; + MP_TAC(ISPECL [`p:real^1->complex`; `z:complex`; + `vec 0:real^1`; `vec 1:real^1`] + WINDING_NUMBER_AHLFORS) THEN + ASM_REWRITE_TAC[DROP_VEC; REAL_POS] THEN + ANTS_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + DISCH_THEN(MP_TAC o CONJUNCT2) THEN + REWRITE_TAC[ONCE_REWRITE_RULE[COMPLEX_MUL_SYM] complex_div] THEN + REWRITE_TAC[integral; GSYM HAS_INTEGRAL_LOCALIZED_VECTOR_DERIVATIVE] THEN + REWRITE_TAC[GSYM has_path_integral; GSYM path_integral] THEN + REWRITE_TAC[CEXP_NEG; COMPLEX_MUL_RID] THEN + MATCH_MP_TAC(COMPLEX_FIELD + `~(i = Cx(&0)) /\ ~(g0 = z) + ==> (inv i * (g1 - z) = g0 - z ==> (i = Cx(&1) <=> g1 = g0))`) THEN + REWRITE_TAC[CEXP_NZ] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE RAND_CONV [IN_IMAGE]) THEN + REWRITE_TAC[IN_INTERVAL_1; DROP_VEC] THEN MESON_TAC[REAL_POS; DROP_VEC]]);; + +let INTEGER_WINDING_NUMBER = prove + (`!g z. path g /\ pathfinish g = pathstart g /\ ~(z IN path_image g) + ==> complex_integer(winding_number(g,z))`, + MESON_TAC[INTEGER_WINDING_NUMBER_EQ]);; + +(* ------------------------------------------------------------------------- *) +(* For |WN| >= 1 the path must contain points in every direction. *) +(* We can thus bound the WN of a path that doesn't meet some "cut". *) +(* ------------------------------------------------------------------------- *) + +let WINDING_NUMBER_POS_MEETS = prove + (`!g z. valid_path g /\ ~(z IN path_image g) /\ + Re(winding_number(g,z)) >= &1 + ==> !w. ~(w = z) + ==> ?a. &0 < a /\ z + (Cx a * (w - z)) IN path_image g`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN + `!t. t IN interval[vec 0,vec 1] ==> ~((g:real^1->complex) t = z)` + ASSUME_TAC THENL + [UNDISCH_TAC `~((z:complex) IN path_image g)` THEN + REWRITE_TAC[path_image; IN_IMAGE] THEN MESON_TAC[]; + ALL_TAC] THEN + ABBREV_TAC `r:complex = (w - z) / (pathstart g - z)` THEN + STRIP_ASSUME_TAC(GSYM(SPEC `r:complex` ARG)) THEN + SUBGOAL_THEN + `?t. t IN interval[vec 0,vec 1] /\ + Im(integral (interval[vec 0,t]) + (\x. vector_derivative g (at x) / (g x - z))) = Arg r` + STRIP_ASSUME_TAC THENL + [REWRITE_TAC[IM_DEF] THEN MATCH_MP_TAC IVT_INCREASING_COMPONENT_ON_1 THEN + ASM_SIMP_TAC[DIMINDEX_2; DROP_VEC; ARITH; INTEGRAL_REFL; REAL_POS; + VEC_COMPONENT] THEN + CONJ_TAC THENL + [MATCH_MP_TAC INDEFINITE_INTEGRAL_CONTINUOUS_RIGHT THEN + REWRITE_TAC[ONCE_REWRITE_RULE[COMPLEX_MUL_SYM] complex_div] THEN + REWRITE_TAC[GSYM PATH_INTEGRABLE_ON] THEN + REWRITE_TAC[SIMPLE_COMPLEX_ARITH `inv z = Cx(&1) / z`] THEN + MATCH_MP_TAC PATH_INTEGRABLE_INVERSEDIFF THEN ASM_REWRITE_TAC[]; + ALL_TAC] THEN + MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC `&2 * pi` THEN + ASM_SIMP_TAC[REAL_LT_IMP_LE] THEN + UNDISCH_TAC `Re(winding_number (g,z)) >= &1` THEN + ASM_SIMP_TAC[WINDING_NUMBER_VALID_PATH; GSYM IM_DEF] THEN + REWRITE_TAC[path_integral; HAS_PATH_INTEGRAL; GSYM integral] THEN + SUBST1_TAC(COMPLEX_FIELD `ii = --inv ii`) THEN + REWRITE_TAC[complex_div; COMPLEX_INV_MUL; COMPLEX_INV_NEG] THEN + REWRITE_TAC[GSYM CX_INV; GSYM CX_MUL; COMPLEX_MUL_ASSOC] THEN + REWRITE_TAC[RE_MUL_CX; RE; COMPLEX_MUL_RNEG; RE_NEG; COMPLEX_MUL_LNEG; + COMPLEX_INV_INV; GSYM COMPLEX_MUL_ASSOC; RE_MUL_II] THEN + REWRITE_TAC[REAL_MUL_RNEG; REAL_NEGNEG] THEN + SIMP_TAC[REAL_ARITH `((&1 * inv(&2)) * p) * x >= &1 <=> &2 <= x * p`] THEN + SIMP_TAC[GSYM real_div; REAL_LE_RDIV_EQ; PI_POS] THEN + REWRITE_TAC[COMPLEX_MUL_LID; COMPLEX_MUL_AC]; + ALL_TAC] THEN + MP_TAC(ISPECL + [`g:real^1->complex`; `z:complex`; `vec 0:real^1`; `t:real^1`] + WINDING_NUMBER_AHLFORS) THEN + ANTS_TAC THENL + [REPEAT CONJ_TAC THENL + [MATCH_MP_TAC PIECEWISE_DIFFERENTIABLE_ON_SUBSET THEN + EXISTS_TAC `interval[vec 0:real^1,vec 1]` THEN + RULE_ASSUM_TAC(REWRITE_RULE[valid_path]) THEN ASM_REWRITE_TAC[]; + ALL_TAC; + GEN_TAC THEN + DISCH_THEN(fun th -> FIRST_ASSUM MATCH_MP_TAC THEN MP_TAC th)] THEN + UNDISCH_TAC `(t:real^1) IN interval[vec 0,vec 1]` THEN + REWRITE_TAC[SUBSET; IN_INTERVAL_1; DROP_VEC] THEN REAL_ARITH_TAC; + ALL_TAC] THEN + DISCH_THEN(MP_TAC o CONJUNCT2) THEN REWRITE_TAC[CEXP_NEG] THEN + ABBREV_TAC `i = integral (interval [vec 0,t]) + (\x. vector_derivative g (at x) / (g x - z))` THEN + SUBST1_TAC(SPEC `i:complex` COMPLEX_EXPAND) THEN + ASM_REWRITE_TAC[CEXP_ADD; COMPLEX_INV_MUL; GSYM CX_EXP] THEN + UNDISCH_TAC `Cx(norm r) * cexp(ii * Cx(Arg r)) = r` THEN + REWRITE_TAC[IMP_IMP] THEN DISCH_THEN(MP_TAC o MATCH_MP (COMPLEX_FIELD + `x * e = r /\ (y * inv e) * w = z + ==> ~(e = Cx(&0)) ==> x * y * w = r * z`)) THEN + REWRITE_TAC[CEXP_NZ] THEN + EXPAND_TAC "r" THEN + GEN_REWRITE_TAC (LAND_CONV o RAND_CONV o ONCE_DEPTH_CONV) [pathstart] THEN + SUBGOAL_THEN `~((g:real^1->complex)(vec 0) = z)` ASSUME_TAC THENL + [FIRST_ASSUM MATCH_MP_TAC THEN SIMP_TAC[IN_INTERVAL_1; DROP_VEC; REAL_POS]; + ALL_TAC] THEN + ASM_SIMP_TAC[COMPLEX_DIV_RMUL; COMPLEX_SUB_0; GSYM CX_INV; GSYM CX_MUL; + COMPLEX_MUL_ASSOC; GSYM real_div] THEN + DISCH_TAC THEN + EXISTS_TAC `exp(Re i) / norm(r:complex)` THEN + SUBGOAL_THEN `~(r = Cx(&0))` ASSUME_TAC THENL + [EXPAND_TAC "r" THEN MATCH_MP_TAC(COMPLEX_FIELD + `~(x = Cx(&0)) /\ ~(y = Cx(&0)) ==> ~(x / y = Cx(&0))`) THEN + ASM_REWRITE_TAC[COMPLEX_SUB_0; pathstart]; + ALL_TAC] THEN + ASM_SIMP_TAC[REAL_LT_DIV; REAL_EXP_POS_LT; COMPLEX_NORM_NZ] THEN + REWRITE_TAC[path_image; IN_IMAGE] THEN + EXISTS_TAC `t:real^1` THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC(COMPLEX_FIELD + `inv i * (gt - z) = wz /\ ~(i = Cx(&0)) ==> z + i * wz = gt`) THEN + ASM_REWRITE_TAC[GSYM CX_INV; REAL_INV_DIV; CX_INJ] THEN + MATCH_MP_TAC(REAL_FIELD `~(x = &0) /\ ~(y = &0) ==> ~(x / y = &0)`) THEN + ASM_REWRITE_TAC[REAL_EXP_NZ; COMPLEX_NORM_ZERO]);; + +let WINDING_NUMBER_BIG_MEETS = prove + (`!g z. valid_path g /\ ~(z IN path_image g) /\ + abs(Re(winding_number(g,z))) >= &1 + ==> !w. ~(w = z) + ==> ?a. &0 < a /\ z + (Cx a * (w - z)) IN path_image g`, + REPEAT GEN_TAC THEN REWRITE_TAC[real_abs] THEN COND_CASES_TAC THEN + ASM_SIMP_TAC[WINDING_NUMBER_POS_MEETS] THEN + REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + ASM_SIMP_TAC[GSYM RE_NEG; VALID_PATH_IMP_PATH; + GSYM WINDING_NUMBER_REVERSEPATH] THEN + DISCH_TAC THEN ONCE_REWRITE_TAC[GSYM PATH_IMAGE_REVERSEPATH] THEN + MATCH_MP_TAC WINDING_NUMBER_POS_MEETS THEN + ASM_SIMP_TAC[PATH_IMAGE_REVERSEPATH; VALID_PATH_REVERSEPATH]);; + +let WINDING_NUMBER_LT_1 = prove + (`!g w z. valid_path g /\ ~(z IN path_image g) /\ ~(w = z) /\ + (!a. &0 < a ==> ~(z + (Cx a * (w - z)) IN path_image g)) + ==> Re(winding_number(g,z)) < &1`, + REPEAT STRIP_TAC THEN + REWRITE_TAC[GSYM REAL_NOT_LE; GSYM real_ge] THEN + ASM_MESON_TAC[WINDING_NUMBER_POS_MEETS]);; + +(* ------------------------------------------------------------------------- *) +(* One way of proving that WN=1 for a loop. *) +(* ------------------------------------------------------------------------- *) + +let WINDING_NUMBER_EQ_1 = prove + (`!g z. valid_path g /\ ~(z IN path_image g) /\ pathfinish g = pathstart g /\ + &0 < Re(winding_number(g,z)) /\ Re(winding_number(g,z)) < &2 + ==> winding_number(g,z) = Cx(&1)`, + REPEAT GEN_TAC THEN + REPLICATE_TAC 3 (DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + SUBGOAL_THEN `complex_integer(winding_number(g,z))` MP_TAC THENL + [ASM_SIMP_TAC[INTEGER_WINDING_NUMBER; VALID_PATH_IMP_PATH]; ALL_TAC] THEN + SIMP_TAC[complex_integer; COMPLEX_EQ; RE_CX; IM_CX] THEN + SIMP_TAC[REAL_LT_INTEGERS; INTEGER_CLOSED] THEN REAL_ARITH_TAC);; + +(* ------------------------------------------------------------------------- *) +(* Continuity of winding number and invariance on connected sets. *) +(* ------------------------------------------------------------------------- *) + +let CONTINUOUS_AT_WINDING_NUMBER = prove + (`!g z. path g /\ ~(z IN path_image g) + ==> (\w. winding_number(g,w)) continuous (at z)`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPEC `(:complex) DIFF path_image g` OPEN_CONTAINS_CBALL) THEN + ASM_SIMP_TAC[GSYM closed; CLOSED_PATH_IMAGE] THEN + DISCH_THEN(MP_TAC o SPEC `z:complex`) THEN + ASM_REWRITE_TAC[IN_DIFF; IN_UNIV; SUBSET; IN_CBALL] THEN + DISCH_THEN(X_CHOOSE_THEN `e:real` STRIP_ASSUME_TAC) THEN + MP_TAC(ISPECL [`(:complex) DIFF cball(z,e / &2)`; `g:real^1->complex`] + PATH_INTEGRAL_NEARBY_ENDS) THEN + ASM_SIMP_TAC[OPEN_DIFF; OPEN_UNIV; CLOSED_CBALL] THEN ANTS_TAC THENL + [REWRITE_TAC[SUBSET; IN_DIFF; IN_CBALL; SUBSET; IN_UNIV] THEN + GEN_TAC THEN ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN + REWRITE_TAC[] THEN DISCH_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_REAL_ARITH_TAC; + ALL_TAC] THEN + DISCH_THEN(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC) THEN + MP_TAC(ISPECL [`g:real^1->complex`; `z:complex`; `min d e / &2`] + WINDING_NUMBER) THEN + ASM_REWRITE_TAC[REAL_HALF; REAL_LT_MIN] THEN + DISCH_THEN(X_CHOOSE_THEN `p:real^1->complex` STRIP_ASSUME_TAC) THEN + MATCH_MP_TAC CONTINUOUS_TRANSFORM_AT THEN + MAP_EVERY EXISTS_TAC [`\w. winding_number(p,w)`; `min d e / &2`] THEN + ASM_REWRITE_TAC[REAL_HALF; REAL_LT_MIN] THEN CONJ_TAC THENL + [X_GEN_TAC `w:complex` THEN DISCH_TAC THEN + MATCH_MP_TAC WINDING_NUMBER_UNIQUE THEN + ASM_SIMP_TAC[VALID_PATH_IMP_PATH] THEN + MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN CONJ_TAC THENL + [REWRITE_TAC[path_image; IN_IMAGE] THEN + DISCH_THEN(X_CHOOSE_THEN `t:real^1` STRIP_ASSUME_TAC) THEN + FIRST_X_ASSUM(MP_TAC o SPEC `(g:real^1->complex) t`) THEN + FIRST_X_ASSUM(MP_TAC o SPEC `t:real^1`) THEN + ASM_SIMP_TAC[path_image; FUN_IN_IMAGE] THEN + UNDISCH_TAC `dist (w:complex,z) < min d e / &2` THEN + ASM_REWRITE_TAC[] THEN CONV_TAC NORM_ARITH; + DISCH_TAC THEN X_GEN_TAC `k:real` THEN DISCH_TAC THEN + MP_TAC(ISPECL [`g:real^1->complex`; `w:complex`; `min k (min d e) / &2`] + WINDING_NUMBER) THEN + ASM_REWRITE_TAC[REAL_HALF; REAL_LT_MIN] THEN ANTS_TAC THENL + [FIRST_X_ASSUM MATCH_MP_TAC THEN ONCE_REWRITE_TAC[DIST_SYM] THEN + ASM_REAL_ARITH_TAC; + ALL_TAC] THEN + DISCH_THEN(X_CHOOSE_THEN `q:real^1->complex` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `p:real^1->complex` THEN ASM_REWRITE_TAC[] THEN + ASM_REWRITE_TAC[VECTOR_SUB_REFL; NORM_0] THEN + FIRST_X_ASSUM(fun th -> GEN_REWRITE_TAC RAND_CONV [SYM th]) THEN + CONV_TAC SYM_CONV THEN FIRST_X_ASSUM(MP_TAC o SPECL + [`p:real^1->complex`; `q:real^1->complex`]) THEN + ASM_REWRITE_TAC[] THEN ANTS_TAC THENL + [X_GEN_TAC `t:real^1` THEN DISCH_TAC THEN + REPEAT(FIRST_X_ASSUM(MP_TAC o SPEC `t:real^1`)) THEN + ASM_REWRITE_TAC[] THEN CONV_TAC NORM_ARITH; + DISCH_THEN(MATCH_MP_TAC o last o CONJUNCTS)] THEN + MATCH_MP_TAC HOLOMORPHIC_ON_DIV THEN + SIMP_TAC[HOLOMORPHIC_ON_SUB; HOLOMORPHIC_ON_ID; HOLOMORPHIC_ON_CONST; + IN_DELETE; IN_UNIV; COMPLEX_SUB_0] THEN + ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN SIMP_TAC[IN_DIFF] THEN + REWRITE_TAC[IN_UNIV; IN_CBALL] THEN + ONCE_REWRITE_TAC[DIST_SYM] THEN ASM_REAL_ARITH_TAC]; + UNDISCH_TAC `~((z:complex) IN path_image p)` THEN + UNDISCH_TAC `valid_path(p:real^1->complex)` THEN + POP_ASSUM_LIST(K ALL_TAC) THEN SPEC_TAC(`z:complex`,`z:complex`) THEN + SPEC_TAC(`p:real^1->complex`,`g:real^1->complex`)] THEN + REPEAT STRIP_TAC THEN + MP_TAC(ISPEC `(:complex) DIFF path_image g` OPEN_CONTAINS_BALL) THEN + ASM_SIMP_TAC[GSYM closed; CLOSED_PATH_IMAGE; VALID_PATH_IMP_PATH] THEN + DISCH_THEN(MP_TAC o SPEC `z:complex`) THEN + ASM_REWRITE_TAC[IN_DIFF; IN_UNIV; SUBSET; IN_BALL] THEN + DISCH_THEN(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC) THEN + MP_TAC(ISPECL [`(:complex) DIFF cball(z, &3 / &4 * d)`; `g:real^1->complex`] + PATH_INTEGRAL_BOUND_EXISTS) THEN + ASM_REWRITE_TAC[GSYM closed; CLOSED_CBALL; SUBSET; IN_DIFF; + IN_CBALL; IN_UNIV; REAL_NOT_LE] THEN + ANTS_TAC THENL + [ASM_MESON_TAC[REAL_ARITH `&0 < d /\ ~(&3 / &4 * d < x) ==> x < d`]; + ALL_TAC] THEN + DISCH_THEN(X_CHOOSE_THEN `L:real` STRIP_ASSUME_TAC) THEN + REWRITE_TAC[continuous_at] THEN X_GEN_TAC `e:real` THEN STRIP_TAC THEN + EXISTS_TAC `min (d / &4) (e / &2 * d pow 2 / L / &4)` THEN + ASM_SIMP_TAC[REAL_LT_MIN; REAL_POW_LT; REAL_LT_DIV; REAL_LT_MUL; REAL_HALF; + REAL_ARITH `&0 < x / &4 <=> &0 < x`] THEN + X_GEN_TAC `w:complex` THEN STRIP_TAC THEN + SUBGOAL_THEN `~((w:complex) IN path_image g)` ASSUME_TAC THENL + [FIRST_X_ASSUM MATCH_MP_TAC THEN ONCE_REWRITE_TAC[DIST_SYM] THEN + ASM_REAL_ARITH_TAC; + ALL_TAC] THEN + ASM_SIMP_TAC[dist; WINDING_NUMBER_VALID_PATH; GSYM COMPLEX_SUB_LDISTRIB] THEN + REWRITE_TAC[COMPLEX_NORM_MUL; COMPLEX_NORM_DIV; COMPLEX_NORM_CX] THEN + REWRITE_TAC[REAL_ABS_NUM; COMPLEX_NORM_II; REAL_ABS_PI] THEN + REWRITE_TAC[real_div; REAL_MUL_LID; REAL_MUL_RID] THEN + MATCH_MP_TAC(REAL_ARITH + `inv p * x <= &1 * x /\ x < e ==> inv p * x < e`) THEN + CONJ_TAC THENL + [MATCH_MP_TAC REAL_LE_RMUL THEN REWRITE_TAC[NORM_POS_LE] THEN + MATCH_MP_TAC REAL_INV_LE_1 THEN MP_TAC PI_APPROX_32 THEN REAL_ARITH_TAC; + ALL_TAC] THEN + MATCH_MP_TAC(REAL_ARITH `!d. &0 < e /\ d = e / &2 /\ x <= d ==> x < e`) THEN + EXISTS_TAC `L * (e / &2 * d pow 2 / L / &4) * inv(d / &2) pow 2` THEN + ASM_REWRITE_TAC[] THEN CONJ_TAC THENL + [MAP_EVERY UNDISCH_TAC [`&0 < d`; `&0 < L`] THEN CONV_TAC REAL_FIELD; + ALL_TAC] THEN + SUBGOAL_THEN + `path_integral g (\x. Cx(&1) / (x - w)) - + path_integral g (\x. Cx(&1) / (x - z)) = + path_integral g (\x. Cx(&1) / (x - w) - Cx(&1) / (x - z))` + SUBST1_TAC THENL + [CONV_TAC SYM_CONV THEN MATCH_MP_TAC PATH_INTEGRAL_SUB THEN + CONJ_TAC THEN MATCH_MP_TAC PATH_INTEGRABLE_INVERSEDIFF THEN + ASM_REWRITE_TAC[] THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + ONCE_REWRITE_TAC[DIST_SYM] THEN ASM_REAL_ARITH_TAC; + ALL_TAC] THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN + SIMP_TAC[HOLOMORPHIC_ON_OPEN; GSYM closed; CLOSED_CBALL] THEN + REWRITE_TAC[IN_UNIV; IN_DIFF; IN_CBALL; REAL_NOT_LE; AND_FORALL_THM] THEN + X_GEN_TAC `x:complex` THEN + REWRITE_TAC[TAUT `(a ==> b) /\ (a ==> c) <=> a ==> b /\ c`] THEN + DISCH_TAC THEN REWRITE_TAC[GSYM complex_differentiable] THEN + SUBGOAL_THEN `~(x:complex = w) /\ ~(x = z)` STRIP_ASSUME_TAC THENL + [CONJ_TAC THEN DISCH_THEN SUBST_ALL_TAC THEN + REPEAT(FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM REAL_NOT_LE])) THEN + CONV_TAC NORM_ARITH; + ALL_TAC] THEN + CONJ_TAC THENL + [MATCH_MP_TAC COMPLEX_DIFFERENTIABLE_SUB THEN + CONJ_TAC THEN MATCH_MP_TAC COMPLEX_DIFFERENTIABLE_DIV_AT THEN + ASM_SIMP_TAC[COMPLEX_SUB_0; COMPLEX_DIFFERENTIABLE_SUB; + COMPLEX_DIFFERENTIABLE_ID; COMPLEX_DIFFERENTIABLE_CONST]; + ALL_TAC] THEN + ASM_SIMP_TAC[COMPLEX_FIELD + `~(x = w) /\ ~(x = z) + ==> Cx(&1) / (x - w) - Cx(&1) / (x - z) = + (w - z) * inv((x - w) * (x - z))`] THEN + REWRITE_TAC[COMPLEX_NORM_MUL] THEN MATCH_MP_TAC REAL_LE_MUL2 THEN + ASM_SIMP_TAC[NORM_POS_LE; GSYM dist; REAL_LT_IMP_LE] THEN + REWRITE_TAC[COMPLEX_NORM_INV; REAL_POW_INV] THEN + MATCH_MP_TAC REAL_LE_INV2 THEN + ASM_SIMP_TAC[REAL_POW_2; REAL_LT_MUL; REAL_HALF; COMPLEX_NORM_MUL] THEN + MATCH_MP_TAC REAL_LE_MUL2 THEN ASM_SIMP_TAC[REAL_HALF; REAL_LT_IMP_LE] THEN + REPEAT(FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM REAL_NOT_LE])) THEN + CONV_TAC NORM_ARITH);; + +let CONTINUOUS_ON_WINDING_NUMBER = prove + (`!g. path g + ==> (\w. winding_number(g,w)) continuous_on + ((:complex) DIFF path_image g)`, + SIMP_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_AT; GSYM closed; + OPEN_UNIV; CLOSED_PATH_IMAGE; VALID_PATH_IMP_PATH] THEN + SIMP_TAC[IN_DIFF; IN_UNIV; CONTINUOUS_AT_WINDING_NUMBER]);; + +let WINDING_NUMBER_CONSTANT = prove + (`!s g. path g /\ pathfinish g = pathstart g /\ + connected s /\ s INTER path_image g = {} + ==> ?k. !z. z IN s ==> winding_number(g,z) = k`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC CONTINUOUS_DISCRETE_RANGE_CONSTANT THEN + ASM_REWRITE_TAC[] THEN CONJ_TAC THENL + [MATCH_MP_TAC CONTINUOUS_ON_SUBSET THEN + EXISTS_TAC `(:complex) DIFF path_image g` THEN + ASM_SIMP_TAC[CONTINUOUS_ON_WINDING_NUMBER] THEN ASM SET_TAC[]; + ALL_TAC] THEN + X_GEN_TAC `z:complex` THEN DISCH_TAC THEN + EXISTS_TAC `&1` THEN REWRITE_TAC[REAL_LT_01] THEN + X_GEN_TAC `w:complex` THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + SUBGOAL_THEN + `complex_integer(winding_number(g,w)) /\ + complex_integer(winding_number(g,z))` + MP_TAC THENL + [CONJ_TAC THEN MATCH_MP_TAC INTEGER_WINDING_NUMBER THEN + ASM_REWRITE_TAC[] THEN ASM SET_TAC[]; + REWRITE_TAC[COMPLEX_INTEGER] THEN STRIP_TAC THEN ASM_REWRITE_TAC[]] THEN + REWRITE_TAC[GSYM CX_SUB; CX_INJ; COMPLEX_NORM_CX] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_ABS_INTEGER_LEMMA THEN + ASM_SIMP_TAC[REAL_SUB_0; INTEGER_CLOSED]);; + +let WINDING_NUMBER_EQ = prove + (`!g s w z. + path g /\ pathfinish g = pathstart g /\ + w IN s /\ z IN s /\ connected s /\ s INTER path_image g = {} + ==> winding_number(g,w) = winding_number(g,z)`, + MESON_TAC[WINDING_NUMBER_CONSTANT]);; + +let OPEN_WINDING_NUMBER_LEVELSETS = prove + (`!g k. path g /\ pathfinish g = pathstart g + ==> open {z | ~(z IN path_image g) /\ winding_number(g,z) = k}`, + REPEAT STRIP_TAC THEN REWRITE_TAC[open_def; IN_ELIM_THM] THEN + X_GEN_TAC `z:complex` THEN STRIP_TAC THEN + MP_TAC(ISPEC `(:complex) DIFF path_image g` OPEN_CONTAINS_BALL) THEN + ASM_SIMP_TAC[GSYM closed; CLOSED_PATH_IMAGE; VALID_PATH_IMP_PATH] THEN + DISCH_THEN(MP_TAC o SPEC `z:complex`) THEN + ASM_REWRITE_TAC[IN_DIFF; IN_UNIV; SUBSET; IN_BALL] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `e:real` THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN X_GEN_TAC `w:complex` THEN + REPEAT STRIP_TAC THENL [ASM_MESON_TAC[DIST_SYM]; ALL_TAC] THEN + MP_TAC(ISPECL [`ball(z:complex,e)`; `g:real^1->complex`] + WINDING_NUMBER_CONSTANT) THEN + ASM_SIMP_TAC[CONNECTED_BALL; EXTENSION; IN_INTER; NOT_IN_EMPTY; IN_BALL] THEN + ASM_MESON_TAC[DIST_REFL; DIST_SYM]);; + +(* ------------------------------------------------------------------------- *) +(* Winding number is zero "outside" a curve, in various senses. *) +(* ------------------------------------------------------------------------- *) + +let WINDING_NUMBER_ZERO_IN_OUTSIDE = prove + (`!g z. path g /\ pathfinish g = pathstart g /\ z IN outside(path_image g) + ==> winding_number(g,z) = Cx(&0)`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`path_image(g:real^1->complex)`; `Cx(&0)`] + BOUNDED_SUBSET_BALL) THEN ASM_SIMP_TAC[BOUNDED_PATH_IMAGE] THEN + DISCH_THEN(X_CHOOSE_THEN `B:real` STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN `?w. ~(w IN ball(Cx(&0),B + &1))` STRIP_ASSUME_TAC THENL + [MATCH_MP_TAC(SET_RULE `~(s = UNIV) ==> ?z. ~(z IN s)`) THEN + MESON_TAC[BOUNDED_BALL; NOT_BOUNDED_UNIV]; + ALL_TAC] THEN + MP_TAC(ISPECL [`Cx(&0)`; `B:real`; `B + &1`] SUBSET_BALL) THEN + REWRITE_TAC[REAL_ARITH `B <= B + &1`] THEN DISCH_TAC THEN + MP_TAC(ISPECL [`path_image(g:real^1->complex)`; `ball(Cx(&0),B + &1)`] + OUTSIDE_SUBSET_CONVEX) THEN + ASM_REWRITE_TAC[CONVEX_BALL] THEN + ANTS_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + REWRITE_TAC[SUBSET; IN_UNIV; IN_DIFF] THEN DISCH_TAC THEN + MATCH_MP_TAC EQ_TRANS THEN EXISTS_TAC `winding_number(g,w)` THEN + CONJ_TAC THENL + [MP_TAC(ISPECL [`outside(path_image(g:real^1->complex))`; + `g:real^1->complex`] WINDING_NUMBER_CONSTANT) THEN + ASM_SIMP_TAC[OUTSIDE_NO_OVERLAP; CONNECTED_OUTSIDE; + DIMINDEX_2; LE_REFL; BOUNDED_PATH_IMAGE] THEN + ASM SET_TAC[]; + MATCH_MP_TAC WINDING_NUMBER_UNIQUE THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN CONJ_TAC THENL + [ASM SET_TAC[]; DISCH_TAC THEN X_GEN_TAC `e:real` THEN DISCH_TAC] THEN + MP_TAC(ISPECL [`g:real^1->complex`; `min e (&1)`] + PATH_APPROX_VECTOR_POLYNOMIAL_FUNCTION) THEN + ASM_REWRITE_TAC[REAL_LT_MIN; REAL_LT_01] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `p:real^1->complex` THEN + STRIP_TAC THEN ONCE_REWRITE_TAC[NORM_SUB] THEN + ASM_SIMP_TAC[VALID_PATH_VECTOR_POLYNOMIAL_FUNCTION] THEN CONJ_TAC THENL + [UNDISCH_TAC `~(w IN ball (Cx (&0),B + &1))` THEN + REWRITE_TAC[CONTRAPOS_THM; path_image; IN_BALL] THEN + SPEC_TAC(`w:complex`,`x:complex`) THEN REWRITE_TAC[FORALL_IN_IMAGE]; + REWRITE_TAC[COMPLEX_MUL_RZERO] THEN + MATCH_MP_TAC PATH_INTEGRAL_UNIQUE THEN + MATCH_MP_TAC CAUCHY_THEOREM_CONVEX_SIMPLE THEN + EXISTS_TAC `ball(Cx(&0),B + &1)` THEN + ASM_SIMP_TAC[CONVEX_BALL; VALID_PATH_VECTOR_POLYNOMIAL_FUNCTION] THEN + CONJ_TAC THENL + [MATCH_MP_TAC HOLOMORPHIC_ON_DIV THEN + SIMP_TAC[HOLOMORPHIC_ON_SUB; HOLOMORPHIC_ON_ID; HOLOMORPHIC_ON_CONST; + COMPLEX_SUB_0] THEN + ASM_MESON_TAC[]; + REWRITE_TAC[path_image; SUBSET; FORALL_IN_IMAGE; IN_BALL]]] THEN + X_GEN_TAC `t:real^1` THEN DISCH_TAC THEN + REWRITE_TAC[dist; COMPLEX_SUB_LZERO; NORM_NEG] THEN + MATCH_MP_TAC(NORM_ARITH + `!g:real^1->complex. norm(p t - g t) < &1 /\ norm(g t) <= B + ==> norm(p t) < B + &1`) THEN + EXISTS_TAC `g:real^1->complex` THEN + UNDISCH_TAC `path_image g SUBSET ball (Cx (&0),B)` THEN + ASM_SIMP_TAC[SUBSET; IN_BALL; path_image; FORALL_IN_IMAGE] THEN + ASM_SIMP_TAC[dist; COMPLEX_SUB_LZERO; NORM_NEG; REAL_LT_IMP_LE]]);; + +let WINDING_NUMBER_ZERO_OUTSIDE = prove + (`!g s z. path g /\ convex s /\ pathfinish g = pathstart g /\ + ~(z IN s) /\ path_image g SUBSET s + ==> winding_number(g,z) = Cx(&0)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC WINDING_NUMBER_ZERO_IN_OUTSIDE THEN + ASM_REWRITE_TAC[] THEN + MP_TAC(ISPECL [`path_image(g:real^1->complex)`; `s:complex->bool`] + OUTSIDE_SUBSET_CONVEX) THEN + ASM SET_TAC[]);; + +let WINDING_NUMBER_ZERO_ATINFINITY = prove + (`!g. path g /\ pathfinish g = pathstart g + ==> ?B. !z. B <= norm(z) ==> winding_number(g,z) = Cx(&0)`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN `bounded (path_image g :complex->bool)` MP_TAC THENL + [ASM_SIMP_TAC[BOUNDED_PATH_IMAGE]; ALL_TAC] THEN + REWRITE_TAC[bounded] THEN DISCH_THEN(X_CHOOSE_TAC `B:real`) THEN + EXISTS_TAC `B + &1` THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC WINDING_NUMBER_ZERO_OUTSIDE THEN + EXISTS_TAC `cball(Cx(&0),B)` THEN ASM_REWRITE_TAC[CONVEX_CBALL] THEN + REWRITE_TAC[SUBSET; IN_CBALL; dist; COMPLEX_SUB_LZERO; NORM_NEG] THEN + ASM_MESON_TAC[REAL_ARITH `~(B + &1 <= z /\ z <= B)`]);; + +let WINDING_NUMBER_ZERO_POINT = prove + (`!g s. path g /\ pathfinish g = pathstart g /\ + open s /\ path_image g SUBSET s + ==> ?z. z IN s /\ winding_number(g,z) = Cx(&0)`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`path_image g:complex->bool`; `s:complex->bool`] + OUTSIDE_COMPACT_IN_OPEN) THEN + ASM_SIMP_TAC[COMPACT_PATH_IMAGE] THEN ANTS_TAC THENL + [ASM_MESON_TAC[SUBSET_EMPTY; PATH_IMAGE_NONEMPTY]; ALL_TAC] THEN + REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN MATCH_MP_TAC MONO_EXISTS THEN + GEN_TAC THEN REWRITE_TAC[IN_INTER] THEN + ASM_SIMP_TAC[WINDING_NUMBER_ZERO_IN_OUTSIDE]);; + +(* ------------------------------------------------------------------------- *) +(* If a path winds round a set, it winds rounds its inside. *) +(* ------------------------------------------------------------------------- *) + +let WINDING_NUMBER_AROUND_INSIDE = prove + (`!g s z. + path g /\ pathfinish g = pathstart g /\ + closed s /\ connected s /\ s INTER path_image g = {} /\ + z IN s /\ ~(winding_number(g,z) = Cx(&0)) + ==> !w. w IN s UNION inside(s) + ==> winding_number(g,w) = winding_number(g,z)`, + MAP_EVERY X_GEN_TAC + [`g:real^1->complex`; `s:complex->bool`; `z0:complex`] THEN STRIP_TAC THEN + SUBGOAL_THEN `!z. z IN s ==> winding_number(g,z) = winding_number(g,z0)` + ASSUME_TAC THENL [ASM_MESON_TAC[WINDING_NUMBER_EQ]; ALL_TAC] THEN + ABBREV_TAC `k = winding_number (g,z0)` THEN + SUBGOAL_THEN `(s:complex->bool) SUBSET inside(path_image g)` ASSUME_TAC THENL + [REWRITE_TAC[SUBSET; INSIDE_OUTSIDE; IN_DIFF; IN_UNIV; IN_UNION] THEN + X_GEN_TAC `z:complex` THEN REPEAT STRIP_TAC THENL + [ASM SET_TAC[]; ASM_MESON_TAC[WINDING_NUMBER_ZERO_IN_OUTSIDE]]; + ALL_TAC] THEN + X_GEN_TAC `z:complex` THEN REWRITE_TAC[IN_UNION] THEN + STRIP_TAC THEN ASM_SIMP_TAC[] THEN + MP_TAC(ISPECL [`s:complex->bool`; + `path_image g:complex->bool`] + INSIDE_INSIDE_COMPACT_CONNECTED) THEN + ASM_SIMP_TAC[COMPACT_PATH_IMAGE; CONNECTED_PATH_IMAGE] THEN STRIP_TAC THEN + EXPAND_TAC "k" THEN MATCH_MP_TAC WINDING_NUMBER_EQ THEN + EXISTS_TAC `s UNION inside s :complex->bool` THEN + ASM_SIMP_TAC[CONNECTED_WITH_INSIDE; IN_UNION] THEN + MP_TAC(ISPEC `path_image g :complex->bool` INSIDE_NO_OVERLAP) THEN + ASM SET_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* Bounding a WN by 1/2 for a path and point in opposite halfspaces. *) +(* ------------------------------------------------------------------------- *) + +let WINDING_NUMBER_SUBPATH_CONTINUOUS = prove + (`!g z. valid_path g /\ ~(z IN path_image g) + ==> (\a. winding_number(subpath (vec 0) a g,z)) continuous_on + interval[vec 0,vec 1]`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC CONTINUOUS_ON_EQ THEN EXISTS_TAC + `\a. Cx(&1) / (Cx(&2) * Cx pi * ii) * + integral (interval[vec 0,a]) + (\t. Cx(&1) / (g t - z) * vector_derivative g (at t))` THEN + CONJ_TAC THENL + [X_GEN_TAC `a:real^1` THEN DISCH_TAC THEN REWRITE_TAC[] THEN + MATCH_MP_TAC EQ_TRANS THEN EXISTS_TAC + `Cx(&1) / (Cx(&2) * Cx pi * ii) * + path_integral (subpath (vec 0) a g) (\w. Cx (&1) / (w - z))` THEN + CONJ_TAC THENL + [AP_TERM_TAC THEN CONV_TAC SYM_CONV THEN + MATCH_MP_TAC PATH_INTEGRAL_SUBPATH_INTEGRAL THEN + ASM_SIMP_TAC[ENDS_IN_UNIT_INTERVAL; PATH_INTEGRABLE_INVERSEDIFF] THEN + ASM_MESON_TAC[IN_INTERVAL_1]; + REPEAT STRIP_TAC THEN REWRITE_TAC[] THEN CONV_TAC SYM_CONV THEN + MATCH_MP_TAC WINDING_NUMBER_VALID_PATH THEN + ASM_MESON_TAC[VALID_PATH_SUBPATH; SUBSET; VALID_PATH_IMP_PATH; + ENDS_IN_UNIT_INTERVAL; PATH_IMAGE_SUBPATH_SUBSET]]; + MATCH_MP_TAC CONTINUOUS_ON_COMPLEX_LMUL THEN + MATCH_MP_TAC INDEFINITE_INTEGRAL_CONTINUOUS_RIGHT THEN + REWRITE_TAC[GSYM PATH_INTEGRABLE_ON] THEN + ASM_SIMP_TAC[PATH_INTEGRABLE_INVERSEDIFF]]);; + +let WINDING_NUMBER_IVT_POS = prove + (`!g z w. + valid_path g /\ ~(z IN path_image g) /\ + &0 <= w /\ w <= Re(winding_number(g,z)) + ==> ?t. t IN interval[vec 0,vec 1] /\ + Re(winding_number(subpath (vec 0) t g,z)) = w`, + REPEAT STRIP_TAC THEN REWRITE_TAC[RE_DEF] THEN + MATCH_MP_TAC IVT_INCREASING_COMPONENT_ON_1 THEN + ASM_SIMP_TAC[WINDING_NUMBER_SUBPATH_CONTINUOUS] THEN + ASM_REWRITE_TAC[SUBPATH_TRIVIAL; GSYM RE_DEF; DIMINDEX_2; ARITH] THEN + REWRITE_TAC[DROP_VEC; REAL_POS; SUBPATH_REFL] THEN + MP_TAC(ISPECL [`(g:real^1->complex) (vec 0)`; `z:complex`] + WINDING_NUMBER_TRIVIAL) THEN + ASM_MESON_TAC[pathstart; PATHSTART_IN_PATH_IMAGE; RE_CX]);; + +let WINDING_NUMBER_IVT_NEG = prove + (`!g z w. + valid_path g /\ ~(z IN path_image g) /\ + Re(winding_number(g,z)) <= w /\ w <= &0 + ==> ?t. t IN interval[vec 0,vec 1] /\ + Re(winding_number(subpath (vec 0) t g,z)) = w`, + REPEAT STRIP_TAC THEN REWRITE_TAC[RE_DEF] THEN + MATCH_MP_TAC IVT_DECREASING_COMPONENT_ON_1 THEN + ASM_SIMP_TAC[WINDING_NUMBER_SUBPATH_CONTINUOUS] THEN + ASM_REWRITE_TAC[SUBPATH_TRIVIAL; GSYM RE_DEF; DIMINDEX_2; ARITH] THEN + REWRITE_TAC[DROP_VEC; REAL_POS; SUBPATH_REFL] THEN + MP_TAC(ISPECL [`(g:real^1->complex) (vec 0)`; `z:complex`] + WINDING_NUMBER_TRIVIAL) THEN + ASM_MESON_TAC[pathstart; PATHSTART_IN_PATH_IMAGE; RE_CX]);; + +let WINDING_NUMBER_IVT_ABS = prove + (`!g z w. + valid_path g /\ ~(z IN path_image g) /\ + &0 <= w /\ w <= abs(Re(winding_number(g,z))) + ==> ?t. t IN interval[vec 0,vec 1] /\ + abs(Re(winding_number(subpath (vec 0) t g,z))) = w`, + REPEAT GEN_TAC THEN ASM_CASES_TAC `&0 <= Re(winding_number(g,z))` THEN + ASM_REWRITE_TAC[real_abs] THEN REWRITE_TAC[GSYM real_abs] THEN + REPEAT STRIP_TAC THENL + [MP_TAC(ISPECL [`g:real^1->complex`; `z:complex`; `w:real`] + WINDING_NUMBER_IVT_POS); + MP_TAC(ISPECL [`g:real^1->complex`; `z:complex`; `--w:real`] + WINDING_NUMBER_IVT_NEG)] THEN + (ANTS_TAC THENL [ASM_REWRITE_TAC[] THEN ASM_REAL_ARITH_TAC; ALL_TAC]) THEN + MATCH_MP_TAC MONO_EXISTS THEN SIMP_TAC[] THEN ASM_REAL_ARITH_TAC);; + +let WINDING_NUMBER_LT_HALF = prove + (`!g z a b. + valid_path g /\ a dot z <= b /\ path_image g SUBSET {w | a dot w > b} + ==> abs(Re(winding_number(g,z))) < &1 / &2`, + let lemma = prove + (`!g z a b. + valid_path g /\ ~(z IN path_image g) /\ + a dot z <= b /\ path_image g SUBSET {w | a dot w > b} + ==> Re(winding_number(g,z)) < &1 / &2`, + REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM REAL_NOT_LE] THEN STRIP_TAC THEN + MP_TAC(ISPECL [`g:real^1->complex`; `z:complex`; `&1 / &2`] + WINDING_NUMBER_IVT_POS) THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN ASM_REWRITE_TAC[NOT_EXISTS_THM] THEN + X_GEN_TAC `t:real^1` THEN STRIP_TAC THEN + MP_TAC(ISPECL [`subpath (vec 0) t (g:real^1->complex)`; `z:complex`] + WINDING_NUMBER_AHLFORS_FULL) THEN + ASM_SIMP_TAC[VALID_PATH_SUBPATH; VALID_PATH_IMP_PATH; + ENDS_IN_UNIT_INTERVAL; NOT_IMP] THEN + CONJ_TAC THENL + [FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE + `~(z IN t) ==> s SUBSET t ==> ~(z IN s)`)) THEN + ASM_SIMP_TAC[PATH_IMAGE_SUBPATH_SUBSET; ENDS_IN_UNIT_INTERVAL; + VALID_PATH_IMP_PATH]; + ASM_REWRITE_TAC[EULER; RE_MUL_CX; RE_MUL_II; IM_MUL_CX; IM_MUL_II] THEN + REWRITE_TAC[REAL_ARITH `&2 * pi * &1 / &2 = pi`; SIN_PI; COS_PI] THEN + REWRITE_TAC[COMPLEX_MUL_RZERO; COMPLEX_ADD_RID] THEN + REWRITE_TAC[PATHSTART_SUBPATH; PATHFINISH_SUBPATH] THEN + REWRITE_TAC[COMPLEX_MUL_ASSOC; GSYM CX_MUL] THEN + REWRITE_TAC[REAL_MUL_RNEG; REAL_MUL_RID; GSYM COMPLEX_CMUL] THEN + DISCH_TAC THEN + SUBGOAL_THEN `&0 < a dot ((g:real^1->complex) t - z) /\ + &0 < a dot (g(vec 0) - z)` + MP_TAC THENL + [REWRITE_TAC[DOT_RSUB; REAL_SUB_LT] THEN CONJ_TAC THEN + MATCH_MP_TAC REAL_LET_TRANS THEN EXISTS_TAC `b:real` THEN + ASM_REWRITE_TAC[GSYM real_gt] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE + `g SUBSET {z | a dot z > b} ==> t IN g ==> a dot t > b`)) THEN + REWRITE_TAC[path_image] THEN MATCH_MP_TAC FUN_IN_IMAGE THEN + ASM_REWRITE_TAC[ENDS_IN_UNIT_INTERVAL]; + ASM_REWRITE_TAC[DOT_RMUL] THEN + DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN + ASM_SIMP_TAC[REAL_LT_MUL_EQ] THEN + MATCH_MP_TAC(REAL_ARITH `&0 < x ==> ~(&0 < -- x)`) THEN + REWRITE_TAC[REAL_EXP_POS_LT]]]) in + REPEAT STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [SUBSET]) THEN + DISCH_THEN(MP_TAC o SPEC `z:complex`) THEN + ASM_REWRITE_TAC[IN_ELIM_THM; REAL_ARITH `a:real > b <=> ~(a <= b)`] THEN + DISCH_TAC THEN MATCH_MP_TAC(REAL_ARITH `x < a /\ --x < a ==> abs x < a`) THEN + CONJ_TAC THENL [ASM_MESON_TAC[lemma]; ALL_TAC] THEN + MP_TAC(ISPECL [`reversepath g:real^1->complex`; `z:complex`; + `a:complex`; `b:real`] lemma) THEN + ASM_SIMP_TAC[VALID_PATH_REVERSEPATH; PATH_IMAGE_REVERSEPATH; + WINDING_NUMBER_REVERSEPATH; VALID_PATH_IMP_PATH; RE_NEG] THEN + REAL_ARITH_TAC);; + +let WINDING_NUMBER_LE_HALF = prove + (`!g z a b. + valid_path g /\ ~(z IN path_image g) /\ + ~(a = vec 0) /\ a dot z <= b /\ path_image g SUBSET {w | a dot w >= b} + ==> abs(Re(winding_number(g,z))) <= &1 / &2`, + REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM REAL_NOT_LT] THEN DISCH_TAC THEN + MP_TAC(ISPECL [`g:real^1->complex`; `z:complex`] + CONTINUOUS_AT_WINDING_NUMBER) THEN + ASM_SIMP_TAC[VALID_PATH_IMP_PATH; continuous_at] THEN + DISCH_THEN(MP_TAC o SPEC `abs(Re(winding_number(g,z))) - &1 / &2`) THEN + ASM_REWRITE_TAC[REAL_SUB_LT] THEN + DISCH_THEN(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC) THEN + FIRST_X_ASSUM(MP_TAC o SPEC `z - d / &2 / norm(a) % a:complex`) THEN + REWRITE_TAC[NORM_ARITH `dist(z - d:complex,z) = norm d`] THEN + ASM_SIMP_TAC[NORM_MUL; REAL_ABS_DIV; REAL_ABS_NORM; REAL_DIV_RMUL; + NORM_EQ_0; NOT_IMP] THEN + CONJ_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN + MATCH_MP_TAC(NORM_ARITH + `abs(Re w' - Re w) <= norm(w' - w) /\ abs(Re w') < &1 / &2 + ==> ~(dist(w',w) < abs(Re w) - &1 / &2)`) THEN + REWRITE_TAC[GSYM RE_SUB] THEN CONJ_TAC THENL + [SIMP_TAC[COMPONENT_LE_NORM; RE_DEF; DIMINDEX_2; ARITH]; ALL_TAC] THEN + MATCH_MP_TAC WINDING_NUMBER_LT_HALF THEN EXISTS_TAC `a:complex` THEN + EXISTS_TAC `b - d / &3 * norm(a:complex)` THEN + ASM_REWRITE_TAC[] THEN CONJ_TAC THENL + [REWRITE_TAC[DOT_RSUB; DOT_RMUL; GSYM NORM_POW_2] THEN + ASM_SIMP_TAC[NORM_EQ_0; REAL_FIELD + `~(a = &0) ==> x / a * a pow 2 = x * a`] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH + `a:real <= b ==> d <= e ==> a - e <= b - d`)) THEN + MATCH_MP_TAC REAL_LE_RMUL THEN REWRITE_TAC[NORM_POS_LE] THEN + ASM_REAL_ARITH_TAC; + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + SUBSET_TRANS)) THEN + REWRITE_TAC[SUBSET; IN_ELIM_THM] THEN MATCH_MP_TAC(REAL_ARITH + `&0 < e ==> !x. a dot x >= b ==> a dot x > b - e`) THEN + MATCH_MP_TAC REAL_LT_MUL THEN ASM_SIMP_TAC[NORM_POS_LT] THEN + ASM_REAL_ARITH_TAC]);; + +let WINDING_NUMBER_LT_HALF_LINEPATH = prove + (`!a b z. + ~(z IN segment[a,b]) + ==> abs(Re(winding_number(linepath(a,b),z))) < &1 / &2`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC WINDING_NUMBER_LT_HALF THEN + MP_TAC(ISPECL [`segment[a:complex,b]`; `z:complex`] + SEPARATING_HYPERPLANE_CLOSED_POINT) THEN + ASM_REWRITE_TAC[CONVEX_SEGMENT; CLOSED_SEGMENT] THEN + REPEAT(MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC) THEN + SIMP_TAC[VALID_PATH_LINEPATH; PATH_IMAGE_LINEPATH; SUBSET; IN_ELIM_THM; + REAL_LT_IMP_LE]);; + +(* ------------------------------------------------------------------------- *) +(* Positivity of WN for a linepath. *) +(* ------------------------------------------------------------------------- *) + +let WINDING_NUMBER_LINEPATH_POS_LT = prove + (`!a b z. &0 < Im((b - a) * cnj(b - z)) + ==> &0 < Re(winding_number(linepath(a,b),z))`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC WINDING_NUMBER_POS_LT THEN + EXISTS_TAC `Im((b - a) * cnj(b - z))` THEN + ASM_REWRITE_TAC[VALID_PATH_LINEPATH; VECTOR_DERIVATIVE_LINEPATH_AT] THEN + CONJ_TAC THENL + [POP_ASSUM MP_TAC THEN ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN + SPEC_TAC(`z:complex`,`z:complex`) THEN + REWRITE_TAC[path_image; FORALL_IN_IMAGE; linepath] THEN + REWRITE_TAC[VECTOR_ARITH + `b - ((&1 - x) % a + x % b) = (&1 - x) % (b - a)`] THEN + REWRITE_TAC[COMPLEX_CMUL; CNJ_MUL; CNJ_CX] THEN + REWRITE_TAC[COMPLEX_RING `a * Cx x * cnj a = Cx x * a * cnj a`] THEN + SIMP_TAC[COMPLEX_MUL_CNJ; GSYM CX_POW; GSYM CX_MUL; IM_CX; REAL_LT_REFL]; + ALL_TAC] THEN + SUBGOAL_THEN + `segment[a,b] SUBSET + {y | Im((b - a) * cnj(b - z)) <= Im((b - a) * cnj(y - z))}` + MP_TAC THENL + [REWRITE_TAC[SEGMENT_CONVEX_HULL] THEN MATCH_MP_TAC HULL_MINIMAL THEN + CONJ_TAC THENL + [REWRITE_TAC[SET_RULE `{a,b} SUBSET {y | P y} <=> P a /\ P b`] THEN + POP_ASSUM MP_TAC THEN + REWRITE_TAC[cnj; complex_mul; RE; IM; RE_SUB; IM_SUB] THEN + REAL_ARITH_TAC; + ALL_TAC] THEN + REWRITE_TAC[COMPLEX_SUB_LDISTRIB; IM_SUB; CNJ_SUB; REAL_LE_SUB_LADD] THEN + REWRITE_TAC[CONVEX_ALT; cnj; complex_mul; RE; IM; RE_SUB; IM_SUB] THEN + REWRITE_TAC[IN_ELIM_THM; IM_ADD; RE_ADD; IM_CMUL; RE_CMUL] THEN + REWRITE_TAC[REAL_NEG_ADD; REAL_NEG_RMUL] THEN + ONCE_REWRITE_TAC[REAL_ARITH + `e <= ab * ((&1 - u) * x + u * y) + ab' * ((&1 - u) * x' + u * y') <=> + (&1 - u) * e + u * e <= + (&1 - u) * (ab * x + ab' * x') + u * (ab * y + ab' * y')`] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_LE_ADD2 THEN + CONJ_TAC THEN MATCH_MP_TAC REAL_LE_LMUL THEN ASM_REWRITE_TAC[] THEN + ASM_REAL_ARITH_TAC; + REWRITE_TAC[GSYM PATH_IMAGE_LINEPATH] THEN + REWRITE_TAC[SUBSET; path_image; FORALL_IN_IMAGE; IN_ELIM_THM] THEN + ASM_MESON_TAC[SUBSET; INTERVAL_OPEN_SUBSET_CLOSED]]);; + +(* ------------------------------------------------------------------------- *) +(* Winding number for a triangle. *) +(* ------------------------------------------------------------------------- *) + +let WINDING_NUMBER_TRIANGLE = prove + (`!a b c z. + z IN interior(convex hull {a,b,c}) + ==> winding_number(linepath(a,b) ++ linepath(b,c) ++ linepath(c,a),z) = + if &0 < Im((b - a) * cnj (b - z)) then Cx(&1) else --Cx(&1)`, + let lemma1 = prove + (`!a b c. vec 0 IN interior(convex hull {a,b,c}) + ==> ~(Im(a / b) <= &0 /\ &0 <= Im(b / c))`, + REPEAT GEN_TAC THEN + ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN SIMP_TAC[] THEN + GEN_REWRITE_TAC (LAND_CONV o RAND_CONV o ONCE_DEPTH_CONV) + [GSYM COMPLEX_INV_DIV] THEN + REWRITE_TAC[IM_COMPLEX_INV_GE_0] THEN + GEOM_BASIS_MULTIPLE_TAC 1 `b:complex` THEN + REWRITE_TAC[COMPLEX_CMUL; COMPLEX_BASIS; GSYM CX_MUL; REAL_MUL_RID] THEN + X_GEN_TAC `x:real` THEN GEN_REWRITE_TAC LAND_CONV [REAL_LE_LT] THEN + REWRITE_TAC[IM_DIV_CX] THEN ASM_CASES_TAC `x = &0` THEN + ASM_REWRITE_TAC[NOT_IN_INTERIOR_CONVEX_HULL_3; COMPLEX_VEC_0] THEN + DISCH_TAC THEN REPEAT GEN_TAC THEN + ASM_SIMP_TAC[REAL_LE_LDIV_EQ; REAL_MUL_LZERO] THEN STRIP_TAC THEN + MATCH_MP_TAC(SET_RULE + `!s. ~(x IN s) /\ t SUBSET s ==> ~(x IN t)`) THEN + EXISTS_TAC `interior {z | Im z <= &0}` THEN CONJ_TAC THENL + [REWRITE_TAC[IM_DEF; INTERIOR_HALFSPACE_COMPONENT_LE] THEN + REWRITE_TAC[GSYM COMPLEX_VEC_0; IN_ELIM_THM; VEC_COMPONENT] THEN + REAL_ARITH_TAC; + MATCH_MP_TAC SUBSET_INTERIOR THEN MATCH_MP_TAC HULL_MINIMAL THEN + REWRITE_TAC[CONVEX_HALFSPACE_IM_LE] THEN + ASM_REWRITE_TAC[INSERT_SUBSET; EMPTY_SUBSET; IN_ELIM_THM] THEN + REWRITE_TAC[IM_CX; REAL_LE_REFL]]) in + let lemma2 = prove + (`z IN interior(convex hull {a,b,c}) + ==> &0 < Im((b - a) * cnj (b - z)) /\ + &0 < Im((c - b) * cnj (c - z)) /\ + &0 < Im((a - c) * cnj (a - z)) \/ + Im((b - a) * cnj (b - z)) < &0 /\ + &0 < Im((b - c) * cnj (b - z)) /\ + &0 < Im((a - b) * cnj (a - z)) /\ + &0 < Im((c - a) * cnj (c - z))`, + GEOM_ORIGIN_TAC `z:complex` THEN + REWRITE_TAC[VECTOR_SUB_RZERO; COMPLEX_SUB_RDISTRIB] THEN + REWRITE_TAC[COMPLEX_MUL_CNJ; IM_SUB; GSYM CX_POW; IM_CX] THEN + REWRITE_TAC[REAL_ARITH `&0 < &0 - x <=> x < &0`; + REAL_ARITH `&0 - x < &0 <=> &0 < x`] THEN + REWRITE_TAC[GSYM IM_COMPLEX_DIV_GT_0; GSYM IM_COMPLEX_DIV_LT_0] THEN + REPEAT STRIP_TAC THEN + GEN_REWRITE_TAC (RAND_CONV o ONCE_DEPTH_CONV) [GSYM COMPLEX_INV_DIV] THEN + REWRITE_TAC[IM_COMPLEX_INV_LT_0; IM_COMPLEX_INV_GT_0] THEN + GEN_REWRITE_TAC (RAND_CONV o LAND_CONV o LAND_CONV o RAND_CONV) + [GSYM COMPLEX_INV_DIV] THEN + REWRITE_TAC[IM_COMPLEX_INV_LT_0] THEN + MP_TAC(ISPECL [`a:complex`; `b:complex`; `c:complex`] lemma1) THEN + MP_TAC(ISPECL [`b:complex`; `c:complex`; `a:complex`] lemma1) THEN + MP_TAC(ISPECL [`c:complex`; `a:complex`; `b:complex`] lemma1) THEN + POP_ASSUM MP_TAC THEN SIMP_TAC[INSERT_AC] THEN REAL_ARITH_TAC) in + let lemma3 = prove + (`!a b c z. + z IN interior(convex hull {a,b,c}) /\ + &0 < Im((b - a) * cnj (b - z)) /\ + &0 < Im((c - b) * cnj (c - z)) /\ + &0 < Im((a - c) * cnj (a - z)) + ==> winding_number + (linepath(a,b) ++ linepath(b,c) ++ linepath(c,a),z) = Cx(&1)`, + REPEAT STRIP_TAC THEN + MATCH_MP_TAC WINDING_NUMBER_EQ_1 THEN + REWRITE_TAC[PATHSTART_JOIN; PATHFINISH_JOIN; CONJ_ASSOC; + PATHSTART_LINEPATH; PATHFINISH_LINEPATH] THEN + CONJ_TAC THENL + [REWRITE_TAC[GSYM CONJ_ASSOC] THEN + REPEAT(MATCH_MP_TAC WINDING_NUMBER_JOIN_POS_COMBINED THEN + REWRITE_TAC[PATHSTART_JOIN; PATHFINISH_JOIN; + PATHSTART_LINEPATH; PATHFINISH_LINEPATH] THEN + CONJ_TAC) THEN + ASM_SIMP_TAC[WINDING_NUMBER_LINEPATH_POS_LT; VALID_PATH_LINEPATH] THEN + RULE_ASSUM_TAC(REWRITE_RULE + [INTERIOR_OF_TRIANGLE; IN_DIFF; IN_UNION; DE_MORGAN_THM]) THEN + ASM_REWRITE_TAC[PATH_IMAGE_LINEPATH]; + RULE_ASSUM_TAC(REWRITE_RULE + [INTERIOR_OF_TRIANGLE; IN_DIFF; IN_UNION; DE_MORGAN_THM]) THEN + ASM_SIMP_TAC[WINDING_NUMBER_JOIN; PATH_IMAGE_JOIN; PATH_JOIN; IN_UNION; + PATH_LINEPATH; PATHSTART_JOIN; PATHFINISH_JOIN; RE_ADD; + PATHSTART_LINEPATH; PATHFINISH_LINEPATH; PATH_IMAGE_LINEPATH] THEN + MATCH_MP_TAC(REAL_ARITH + `abs a < &1 / &2 /\ abs b < &1 / &2 /\ abs c < &1 / &2 + ==> a + b + c < &2`) THEN + REPEAT CONJ_TAC THEN MATCH_MP_TAC WINDING_NUMBER_LT_HALF_LINEPATH THEN + ASM_REWRITE_TAC[]]) in + REPEAT STRIP_TAC THEN + FIRST_ASSUM(STRIP_ASSUME_TAC o MATCH_MP lemma2) THEN + ASM_SIMP_TAC[lemma3; COMPLEX_NORM_CX; REAL_ABS_NUM] THEN + SUBGOAL_THEN + `winding_number + (linepath(c,b) ++ linepath(b,a) ++ linepath(a,c),z) = Cx(&1)` + MP_TAC THENL + [MATCH_MP_TAC lemma3 THEN ASM_REWRITE_TAC[] THEN ASM_MESON_TAC[INSERT_AC]; + COND_CASES_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC]] THEN + DISCH_THEN(SUBST1_TAC o SYM) THEN CONV_TAC SYM_CONV THEN + REWRITE_TAC[COMPLEX_NORM_CX; REAL_ABS_NUM] THEN + RULE_ASSUM_TAC(REWRITE_RULE + [INTERIOR_OF_TRIANGLE; IN_DIFF; IN_UNION; DE_MORGAN_THM]) THEN + FIRST_ASSUM(ASSUME_TAC o ONCE_REWRITE_RULE[SEGMENT_SYM] o CONJUNCT2) THEN + ASM_SIMP_TAC[WINDING_NUMBER_JOIN; PATH_IMAGE_JOIN; PATH_JOIN; IN_UNION; + PATH_LINEPATH; PATHSTART_JOIN; PATHFINISH_JOIN; RE_ADD; + PATHSTART_LINEPATH; PATHFINISH_LINEPATH; PATH_IMAGE_LINEPATH] THEN + ASM_SIMP_TAC[COMPLEX_NEG_ADD; GSYM WINDING_NUMBER_REVERSEPATH; + PATH_IMAGE_LINEPATH; PATH_LINEPATH; REVERSEPATH_LINEPATH] THEN + CONV_TAC COMPLEX_RING);; + +(* ------------------------------------------------------------------------- *) +(* Cauchy's integral formula, again for a convex enclosing set. *) +(* ------------------------------------------------------------------------- *) + +let CAUCHY_INTEGRAL_FORMULA_WEAK = prove + (`!f s k g z. + convex s /\ FINITE k /\ f continuous_on s /\ + (!x. x IN interior(s) DIFF k ==> f complex_differentiable at x) /\ + z IN interior(s) DIFF k /\ + valid_path g /\ (path_image g) SUBSET (s DELETE z) /\ + pathfinish g = pathstart g + ==> ((\w. f(w) / (w - z)) has_path_integral + (Cx(&2) * Cx(pi) * ii * winding_number(g,z) * f(z))) g`, + REWRITE_TAC[IN_DIFF] THEN REPEAT STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o SPEC `z:complex`) THEN ANTS_TAC THENL + [ASM_REWRITE_TAC[]; ALL_TAC] THEN + REWRITE_TAC[complex_differentiable; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `f':complex` THEN DISCH_TAC THEN MP_TAC(SPECL + [`\w:complex. if w = z then f' else (f w - f z) / (w - z)`; + `s:complex->bool`; + `(z:complex) INSERT k`; + `g:real^1->complex`] CAUCHY_THEOREM_CONVEX) THEN + REWRITE_TAC[IN_DIFF; IN_INSERT; DE_MORGAN_THM] THEN ANTS_TAC THENL + [ASM_REWRITE_TAC[FINITE_INSERT] THEN REPEAT CONJ_TAC THENL + [ALL_TAC; + X_GEN_TAC `w:complex` THEN DISCH_TAC THEN + MATCH_MP_TAC COMPLEX_DIFFERENTIABLE_TRANSFORM_AT THEN + EXISTS_TAC `\w:complex. (f w - f z) / (w - z)` THEN + EXISTS_TAC `dist(w:complex,z)` THEN ASM_SIMP_TAC[DIST_POS_LT] THEN + CONJ_TAC THENL [MESON_TAC[DIST_SYM; REAL_LT_REFL]; ALL_TAC] THEN + MATCH_MP_TAC COMPLEX_DIFFERENTIABLE_DIV_AT THEN + ASM_REWRITE_TAC[COMPLEX_SUB_0] THEN CONJ_TAC THEN + MATCH_MP_TAC COMPLEX_DIFFERENTIABLE_SUB THEN + ASM_SIMP_TAC[ETA_AX; COMPLEX_DIFFERENTIABLE_CONST; + COMPLEX_DIFFERENTIABLE_ID]; + ASM SET_TAC[]] THEN + REWRITE_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN] THEN + X_GEN_TAC `w:complex` THEN DISCH_TAC THEN + ASM_CASES_TAC `w:complex = z` THENL + [ALL_TAC; + MATCH_MP_TAC CONTINUOUS_TRANSFORM_WITHIN THEN + EXISTS_TAC `\w:complex. (f w - f z) / (w - z)` THEN + EXISTS_TAC `dist(w:complex,z)` THEN ASM_SIMP_TAC[DIST_POS_LT] THEN + CONJ_TAC THENL [MESON_TAC[DIST_SYM; REAL_LT_REFL]; ALL_TAC] THEN + MATCH_MP_TAC CONTINUOUS_COMPLEX_DIV_WITHIN THEN + RULE_ASSUM_TAC(REWRITE_RULE[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN]) THEN + ASM_SIMP_TAC[CONTINUOUS_CONST; CONTINUOUS_SUB; CONTINUOUS_WITHIN_ID; + ETA_AX; COMPLEX_SUB_0]] THEN + FIRST_X_ASSUM SUBST_ALL_TAC THEN REWRITE_TAC[CONTINUOUS_WITHIN] THEN + MATCH_MP_TAC LIM_TRANSFORM_AWAY_WITHIN THEN + EXISTS_TAC `\w:complex. (f w - f z) / (w - z)` THEN SIMP_TAC[] THEN + EXISTS_TAC `z + Cx(&1)` THEN + CONJ_TAC THENL [CONV_TAC COMPLEX_RING; ALL_TAC] THEN + REWRITE_TAC[GSYM HAS_COMPLEX_DERIVATIVE_WITHIN] THEN + ASM_SIMP_TAC[HAS_COMPLEX_DERIVATIVE_AT_WITHIN]; + ALL_TAC] THEN + MP_TAC(SPECL [`g:real^1->complex`; `z:complex`] + HAS_PATH_INTEGRAL_WINDING_NUMBER) THEN + ANTS_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + DISCH_THEN(MP_TAC o SPEC `(f:complex->complex) z` o MATCH_MP + HAS_PATH_INTEGRAL_COMPLEX_LMUL) THEN REWRITE_TAC[IMP_IMP] THEN + DISCH_THEN(MP_TAC o MATCH_MP HAS_PATH_INTEGRAL_ADD) THEN + REWRITE_TAC[COMPLEX_RING + `f * Cx(&2) * a * b * c + Cx(&0) = Cx(&2) * a * b * c * f`] THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] HAS_PATH_INTEGRAL_EQ) THEN + X_GEN_TAC `w:complex` THEN DISCH_TAC THEN + SUBGOAL_THEN `~(w:complex = z)` MP_TAC THENL + [ASM SET_TAC[]; ALL_TAC] THEN + ASM_REWRITE_TAC[] THEN CONV_TAC COMPLEX_FIELD);; + +let CAUCHY_INTEGRAL_FORMULA_CONVEX_SIMPLE = prove + (`!f s g z. + convex s /\ f holomorphic_on s /\ + z IN interior(s) /\ + valid_path g /\ (path_image g) SUBSET (s DELETE z) /\ + pathfinish g = pathstart g + ==> ((\w. f(w) / (w - z)) has_path_integral + (Cx(&2) * Cx(pi) * ii * winding_number(g,z) * f(z))) g`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC CAUCHY_INTEGRAL_FORMULA_WEAK THEN + MAP_EVERY EXISTS_TAC [`s:complex->bool`; `{}:complex->bool`] THEN + ASM_REWRITE_TAC[DIFF_EMPTY; FINITE_RULES] THEN + SIMP_TAC[OPEN_INTERIOR; complex_differentiable; GSYM HOLOMORPHIC_ON_OPEN] THEN + ASM_MESON_TAC[HOLOMORPHIC_ON_IMP_CONTINUOUS_ON; + HOLOMORPHIC_ON_SUBSET; INTERIOR_SUBSET]);; + +(* ------------------------------------------------------------------------- *) +(* Homotopy forms of Cauchy's theorem. The first two proofs are almost the *) +(* same and could potentially be unified with a little more work. *) +(* ------------------------------------------------------------------------- *) + +let CAUCHY_THEOREM_HOMOTOPIC_PATHS = prove + (`!f g h s. + open s /\ f holomorphic_on s /\ + valid_path g /\ valid_path h /\ homotopic_paths s g h + ==> path_integral g f = path_integral h f`, + REPEAT STRIP_TAC THEN + FIRST_ASSUM(ASSUME_TAC o SYM o MATCH_MP HOMOTOPIC_PATHS_IMP_PATHSTART) THEN + FIRST_ASSUM(ASSUME_TAC o SYM o MATCH_MP HOMOTOPIC_PATHS_IMP_PATHFINISH) THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [homotopic_paths]) THEN + REWRITE_TAC[homotopic_with; LEFT_IMP_EXISTS_THM; PCROSS] THEN + X_GEN_TAC `k:real^(1,1)finite_sum->complex` THEN STRIP_TAC THEN + SUBGOAL_THEN + `!t. t IN interval[vec 0:real^1,vec 1] + ==> ?e. &0 < e /\ + !t1 t2. t1 IN interval[vec 0:real^1,vec 1] /\ + t2 IN interval[vec 0,vec 1] /\ + norm(t1 - t) < e /\ norm(t2 - t) < e + ==> ?d. &0 < d /\ + !g1 g2. valid_path g1 /\ valid_path g2 /\ + (!u. u IN interval[vec 0,vec 1] + ==> norm(g1 u - k(pastecart t1 u)) < d /\ + norm(g2 u - k(pastecart t2 u)) < d) /\ + pathstart g1 = pathstart g /\ + pathfinish g1 = pathfinish g /\ + pathstart g2 = pathstart g /\ + pathfinish g2 = pathfinish g + ==> path_image g1 SUBSET s /\ + path_image g2 SUBSET s /\ + path_integral g2 f = path_integral g1 f` + MP_TAC THENL + [X_GEN_TAC `t:real^1` THEN STRIP_TAC THEN + MP_TAC(ISPECL + [`s:complex->bool`; `\u. (k:real^(1,1)finite_sum->complex)(pastecart t u)`] + PATH_INTEGRAL_NEARBY_ENDS) THEN + REWRITE_TAC[] THEN ANTS_TAC THENL + [ASM_REWRITE_TAC[] THEN ONCE_REWRITE_TAC[GSYM o_DEF] THEN + REWRITE_TAC[path_image; path; IMAGE_o] THEN CONJ_TAC THENL + [ALL_TAC; ASM SET_TAC[]] THEN + MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN + SIMP_TAC[CONTINUOUS_ON_PASTECART; CONTINUOUS_ON_ID; + CONTINUOUS_ON_CONST] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET)) THEN ASM SET_TAC[]; + DISCH_THEN(X_CHOOSE_THEN `e:real` STRIP_ASSUME_TAC)] THEN + FIRST_ASSUM(MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + COMPACT_UNIFORMLY_CONTINUOUS)) THEN + SIMP_TAC[REWRITE_RULE[PCROSS] COMPACT_PCROSS; COMPACT_INTERVAL] THEN + REWRITE_TAC[uniformly_continuous_on] THEN + DISCH_THEN(MP_TAC o SPEC `e / &4`) THEN + ASM_REWRITE_TAC[REAL_ARITH `&0 < e / &4 <=> &0 < e`] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `d:real` THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN + REWRITE_TAC[FORALL_IN_GSPEC] THEN + REWRITE_TAC[RIGHT_IMP_FORALL_THM; IMP_IMP; GSYM CONJ_ASSOC] THEN + DISCH_THEN(MP_TAC o MATCH_MP (MESON[] + `(!t x t' x'. P t x t' x') ==> (!t t' u. P t u t' u)`)) THEN + REWRITE_TAC[dist; NORM_PASTECART; PASTECART_SUB] THEN + REWRITE_TAC[VECTOR_SUB_REFL; NORM_0] THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN + REWRITE_TAC[TAUT `a /\ b /\ c /\ b /\ d <=> a /\ c /\ b /\ d`] THEN + SIMP_TAC[REAL_ADD_RID; POW_2_SQRT; NORM_POS_LE] THEN DISCH_TAC THEN + ASM_REWRITE_TAC[] THEN + MAP_EVERY X_GEN_TAC [`t1:real^1`; `t2:real^1`] THEN + STRIP_TAC THEN EXISTS_TAC `e / &4` THEN + ASM_REWRITE_TAC[REAL_ARITH `&0 < e / &4 <=> &0 < e`] THEN + MAP_EVERY X_GEN_TAC [`g1:real^1->complex`; `g2:real^1->complex`] THEN + STRIP_TAC THEN FIRST_X_ASSUM + (MP_TAC o SPECL [`g1:real^1->complex`; `g2:real^1->complex`]) THEN + ASM_REWRITE_TAC[] THEN ANTS_TAC THENL [ALL_TAC; ASM_MESON_TAC[]] THEN + X_GEN_TAC `u:real^1` THEN STRIP_TAC THEN + ASM_MESON_TAC[NORM_ARITH + `norm(g1 - k1) < e / &4 /\ norm(g2 - k2) < e / &4 /\ + norm(k1 - kt) < e / &4 /\ norm(k2 - kt) < e / &4 + ==> norm(g1 - kt) < e /\ norm(g2 - kt) < e`]; + GEN_REWRITE_TAC (LAND_CONV o BINDER_CONV) [RIGHT_IMP_EXISTS_THM] THEN + REWRITE_TAC[ SKOLEM_THM; LEFT_IMP_EXISTS_THM]] THEN + X_GEN_TAC `ee:real^1->real` THEN DISCH_THEN(LABEL_TAC "*") THEN + MP_TAC(ISPEC `interval[vec 0:real^1,vec 1]` COMPACT_IMP_HEINE_BOREL) THEN + REWRITE_TAC[COMPACT_INTERVAL] THEN + DISCH_THEN(MP_TAC o SPEC + `IMAGE (\t:real^1. ball(t,ee t / &3)) (interval[vec 0,vec 1])`) THEN + ANTS_TAC THENL + [REWRITE_TAC[FORALL_IN_IMAGE; OPEN_BALL; SUBSET] THEN + X_GEN_TAC `t:real^1` THEN DISCH_TAC THEN + REWRITE_TAC[UNIONS_IMAGE; IN_ELIM_THM] THEN EXISTS_TAC `t:real^1` THEN + ASM_SIMP_TAC[CENTRE_IN_BALL; REAL_ARITH `&0 < e / &3 <=> &0 < e`]; + ALL_TAC] THEN + ONCE_REWRITE_TAC[TAUT `a /\ b /\ c <=> b /\ a /\ c`] THEN + REWRITE_TAC[CONJ_ASSOC; FINITE_SUBSET_IMAGE] THEN + REWRITE_TAC[LEFT_AND_EXISTS_THM; MESON[] + `(?f s. (P s /\ f = g s) /\ Q f) <=> ?s. P s /\ Q(g s)`] THEN + REWRITE_TAC[UNIONS_IMAGE; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `k:real^1->bool` THEN + DISCH_THEN(CONJUNCTS_THEN2 STRIP_ASSUME_TAC MP_TAC) THEN + GEN_REWRITE_TAC LAND_CONV [SUBSET] THEN REWRITE_TAC[IN_ELIM_THM] THEN + ASM_CASES_TAC `k:real^1->bool = {}` THENL + [ASM_REWRITE_TAC[NOT_IN_EMPTY; GSYM NOT_EXISTS_THM; MEMBER_NOT_EMPTY] THEN + REWRITE_TAC[INTERVAL_EQ_EMPTY_1; DROP_VEC] THEN REAL_ARITH_TAC; + DISCH_THEN(LABEL_TAC "+")] THEN + SUBGOAL_THEN `!i:real^1. i IN k ==> &0 < ee(i)` + ASSUME_TAC THENL [ASM_MESON_TAC[SUBSET]; ALL_TAC] THEN + ABBREV_TAC `e = inf(IMAGE (ee:real^1->real) k)` THEN + MP_TAC(ISPEC `IMAGE (ee:real^1->real) k` INF_FINITE) THEN + MP_TAC(ISPECL [`IMAGE (ee:real^1->real) k`; `&0`] + REAL_LT_INF_FINITE) THEN + ASM_SIMP_TAC[FINITE_IMAGE; IMAGE_EQ_EMPTY; FORALL_IN_IMAGE] THEN + DISCH_TAC THEN DISCH_THEN(ASSUME_TAC o CONJUNCT2) THEN + MP_TAC(ISPEC `e / &3` REAL_ARCH_INV) THEN + ASM_REWRITE_TAC[REAL_ARITH `&0 < e / &3 <=> &0 < e`] THEN + DISCH_THEN(X_CHOOSE_THEN `N:num` STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN + `!n. n <= N + ==> ?d. &0 < d /\ + !j. valid_path j /\ + (!u. u IN interval [vec 0,vec 1] + ==> norm(j u - k(pastecart (lift(&n / &N)) u)) < d) /\ + pathstart j = pathstart g /\ + pathfinish j = pathfinish g + ==> path_image j SUBSET s /\ + path_integral j f = path_integral g f` + (MP_TAC o SPEC `N:num`) THENL + [ALL_TAC; + REWRITE_TAC[LE_REFL; LEFT_IMP_EXISTS_THM] THEN + GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + DISCH_THEN(MP_TAC o SPEC `h:real^1->complex`) THEN + ASM_SIMP_TAC[REAL_DIV_REFL; REAL_OF_NUM_EQ; LIFT_NUM] THEN + ASM_REWRITE_TAC[VECTOR_SUB_REFL; NORM_0] THEN MESON_TAC[]] THEN + INDUCT_TAC THENL + [REMOVE_THEN "*" (MP_TAC o SPEC `vec 0:real^1`) THEN + ASM_REWRITE_TAC[real_div; REAL_MUL_LZERO; LE_0; LIFT_NUM] THEN + REWRITE_TAC[IN_INTERVAL_1; DROP_VEC; REAL_POS; REAL_LE_REFL] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + REPEAT(DISCH_THEN(MP_TAC o SPEC `vec 0:real^1`) THEN + REWRITE_TAC[IN_INTERVAL_1; DROP_VEC; REAL_POS; REAL_LE_REFL]) THEN + ASM_REWRITE_TAC[VECTOR_SUB_REFL; NORM_0] THEN + MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC THEN STRIP_TAC THEN + ASM_REWRITE_TAC[] THEN X_GEN_TAC `j:real^1->complex` THEN + STRIP_TAC THEN FIRST_X_ASSUM(MP_TAC o SPECL + [`g:real^1->complex`; `j:real^1->complex`]) THEN + ASM_REWRITE_TAC[VECTOR_SUB_REFL; NORM_0] THEN MESON_TAC[]; + DISCH_TAC] THEN + SUBGOAL_THEN `lift(&n / &N) IN interval[vec 0,vec 1] /\ + lift(&(SUC n) / &N) IN interval[vec 0,vec 1]` + STRIP_ASSUME_TAC THENL + [REWRITE_TAC[IN_INTERVAL_1; DROP_VEC; LIFT_DROP] THEN + ASM_SIMP_TAC[REAL_LE_RDIV_EQ; REAL_LE_LDIV_EQ; REAL_OF_NUM_LT; LE_1] THEN + REWRITE_TAC[REAL_MUL_LZERO; REAL_MUL_LID; REAL_OF_NUM_LE] THEN + ASM_ARITH_TAC; + ALL_TAC] THEN + REMOVE_THEN "+" (MP_TAC o SPEC `lift(&n / &N)`) THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `t:real^1` STRIP_ASSUME_TAC) THEN + FIRST_X_ASSUM(MP_TAC o check (is_imp o concl)) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN + DISCH_THEN(X_CHOOSE_THEN `d1:real` + (CONJUNCTS_THEN2 ASSUME_TAC (LABEL_TAC "1"))) THEN + REMOVE_THEN "*" (MP_TAC o SPEC `t:real^1`) THEN + ANTS_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + DISCH_THEN(MP_TAC o SPECL [`lift(&n / &N)`; `lift(&(SUC n) / &N)`]) THEN + ASM_REWRITE_TAC[] THEN ANTS_TAC THENL + [FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_BALL]) THEN + MATCH_MP_TAC(NORM_ARITH + `!e. norm(n' - n:real^N) < e / &3 /\ e <= ee + ==> dist(t,n) < ee / &3 ==> norm(n - t) < ee /\ norm(n' - t) < ee`) THEN + EXISTS_TAC `e:real` THEN + REWRITE_TAC[NORM_REAL; GSYM drop; DROP_SUB; LIFT_DROP] THEN + REWRITE_TAC[real_div; GSYM REAL_SUB_RDISTRIB] THEN + SIMP_TAC[REAL_OF_NUM_SUB; ARITH_RULE `n <= SUC n`] THEN + REWRITE_TAC[ARITH_RULE `SUC n - n = 1`; REAL_MUL_LID] THEN + REWRITE_TAC[REAL_ABS_INV; REAL_ABS_NUM] THEN + ASM_SIMP_TAC[GSYM real_div]; + ALL_TAC] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `d2:real` THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + X_GEN_TAC `j:real^1->complex` THEN STRIP_TAC THEN + MP_TAC(ISPECL + [`\u:real^1. (k(pastecart (lift (&n / &N)) u):complex)`; + `min d1 d2`] PATH_APPROX_VECTOR_POLYNOMIAL_FUNCTION) THEN + ASM_SIMP_TAC[REAL_LT_MIN; REAL_ARITH `&0 < e / &4 <=> &0 < e`] THEN + ANTS_TAC THENL + [REWRITE_TAC[path] THEN GEN_REWRITE_TAC LAND_CONV [GSYM o_DEF] THEN + MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN + SIMP_TAC[CONTINUOUS_ON_PASTECART; CONTINUOUS_ON_ID; + CONTINUOUS_ON_CONST] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET)) THEN + ASM SET_TAC[]; + DISCH_THEN(X_CHOOSE_THEN `p:real^1->complex` STRIP_ASSUME_TAC)] THEN + REMOVE_THEN "1" (MP_TAC o SPEC `p:real^1->complex`) THEN + ASM_SIMP_TAC[VALID_PATH_VECTOR_POLYNOMIAL_FUNCTION] THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`p:real^1->complex`; `j:real^1->complex`]) THEN + ASM_SIMP_TAC[VALID_PATH_VECTOR_POLYNOMIAL_FUNCTION]);; + +let CAUCHY_THEOREM_HOMOTOPIC_LOOPS = prove + (`!f g h s. + open s /\ f holomorphic_on s /\ + valid_path g /\ valid_path h /\ homotopic_loops s g h + ==> path_integral g f = path_integral h f`, + REPEAT STRIP_TAC THEN + FIRST_ASSUM(STRIP_ASSUME_TAC o MATCH_MP HOMOTOPIC_LOOPS_IMP_LOOP) THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [homotopic_loops]) THEN + REWRITE_TAC[homotopic_with; PCROSS; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `k:real^(1,1)finite_sum->complex` THEN STRIP_TAC THEN + SUBGOAL_THEN + `!t. t IN interval[vec 0:real^1,vec 1] + ==> ?e. &0 < e /\ + !t1 t2. t1 IN interval[vec 0:real^1,vec 1] /\ + t2 IN interval[vec 0,vec 1] /\ + norm(t1 - t) < e /\ norm(t2 - t) < e + ==> ?d. &0 < d /\ + !g1 g2. valid_path g1 /\ valid_path g2 /\ + (!u. u IN interval[vec 0,vec 1] + ==> norm(g1 u - k(pastecart t1 u)) < d /\ + norm(g2 u - k(pastecart t2 u)) < d) /\ + pathfinish g1 = pathstart g1 /\ + pathfinish g2 = pathstart g2 + ==> path_image g1 SUBSET s /\ + path_image g2 SUBSET s /\ + path_integral g2 f = path_integral g1 f` + MP_TAC THENL + [X_GEN_TAC `t:real^1` THEN STRIP_TAC THEN + MP_TAC(ISPECL + [`s:complex->bool`; `\u. (k:real^(1,1)finite_sum->complex)(pastecart t u)`] + PATH_INTEGRAL_NEARBY_LOOP) THEN + REWRITE_TAC[] THEN ANTS_TAC THENL + [ASM_REWRITE_TAC[] THEN ONCE_REWRITE_TAC[GSYM o_DEF] THEN + REWRITE_TAC[path_image; path; IMAGE_o] THEN CONJ_TAC THENL + [ALL_TAC; ASM SET_TAC[]] THEN + MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN + SIMP_TAC[CONTINUOUS_ON_PASTECART; CONTINUOUS_ON_ID; + CONTINUOUS_ON_CONST] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET)) THEN ASM SET_TAC[]; + DISCH_THEN(X_CHOOSE_THEN `e:real` STRIP_ASSUME_TAC)] THEN + FIRST_ASSUM(MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + COMPACT_UNIFORMLY_CONTINUOUS)) THEN + SIMP_TAC[REWRITE_RULE[PCROSS] COMPACT_PCROSS; COMPACT_INTERVAL] THEN + REWRITE_TAC[uniformly_continuous_on] THEN + DISCH_THEN(MP_TAC o SPEC `e / &4`) THEN + ASM_REWRITE_TAC[REAL_ARITH `&0 < e / &4 <=> &0 < e`] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `d:real` THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN + REWRITE_TAC[FORALL_IN_GSPEC] THEN + REWRITE_TAC[RIGHT_IMP_FORALL_THM; IMP_IMP; GSYM CONJ_ASSOC] THEN + DISCH_THEN(MP_TAC o MATCH_MP (MESON[] + `(!t x t' x'. P t x t' x') ==> (!t t' u. P t u t' u)`)) THEN + REWRITE_TAC[dist; NORM_PASTECART; PASTECART_SUB] THEN + REWRITE_TAC[VECTOR_SUB_REFL; NORM_0] THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN + REWRITE_TAC[TAUT `a /\ b /\ c /\ b /\ d <=> a /\ c /\ b /\ d`] THEN + SIMP_TAC[REAL_ADD_RID; POW_2_SQRT; NORM_POS_LE] THEN DISCH_TAC THEN + ASM_REWRITE_TAC[] THEN + MAP_EVERY X_GEN_TAC [`t1:real^1`; `t2:real^1`] THEN + STRIP_TAC THEN EXISTS_TAC `e / &4` THEN + ASM_REWRITE_TAC[REAL_ARITH `&0 < e / &4 <=> &0 < e`] THEN + MAP_EVERY X_GEN_TAC [`g1:real^1->complex`; `g2:real^1->complex`] THEN + STRIP_TAC THEN FIRST_X_ASSUM + (MP_TAC o SPECL [`g1:real^1->complex`; `g2:real^1->complex`]) THEN + ASM_REWRITE_TAC[] THEN ANTS_TAC THENL [ALL_TAC; ASM_MESON_TAC[]] THEN + X_GEN_TAC `u:real^1` THEN STRIP_TAC THEN + ASM_MESON_TAC[NORM_ARITH + `norm(g1 - k1) < e / &4 /\ norm(g2 - k2) < e / &4 /\ + norm(k1 - kt) < e / &4 /\ norm(k2 - kt) < e / &4 + ==> norm(g1 - kt) < e /\ norm(g2 - kt) < e`]; + GEN_REWRITE_TAC (LAND_CONV o BINDER_CONV) [RIGHT_IMP_EXISTS_THM] THEN + REWRITE_TAC[ SKOLEM_THM; LEFT_IMP_EXISTS_THM]] THEN + X_GEN_TAC `ee:real^1->real` THEN DISCH_THEN(LABEL_TAC "*") THEN + MP_TAC(ISPEC `interval[vec 0:real^1,vec 1]` COMPACT_IMP_HEINE_BOREL) THEN + REWRITE_TAC[COMPACT_INTERVAL] THEN + DISCH_THEN(MP_TAC o SPEC + `IMAGE (\t:real^1. ball(t,ee t / &3)) (interval[vec 0,vec 1])`) THEN + ANTS_TAC THENL + [REWRITE_TAC[FORALL_IN_IMAGE; OPEN_BALL; SUBSET] THEN + X_GEN_TAC `t:real^1` THEN DISCH_TAC THEN + REWRITE_TAC[UNIONS_IMAGE; IN_ELIM_THM] THEN EXISTS_TAC `t:real^1` THEN + ASM_SIMP_TAC[CENTRE_IN_BALL; REAL_ARITH `&0 < e / &3 <=> &0 < e`]; + ALL_TAC] THEN + ONCE_REWRITE_TAC[TAUT `a /\ b /\ c <=> b /\ a /\ c`] THEN + REWRITE_TAC[CONJ_ASSOC; FINITE_SUBSET_IMAGE] THEN + REWRITE_TAC[LEFT_AND_EXISTS_THM; MESON[] + `(?f s. (P s /\ f = g s) /\ Q f) <=> ?s. P s /\ Q(g s)`] THEN + REWRITE_TAC[UNIONS_IMAGE; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `k:real^1->bool` THEN + DISCH_THEN(CONJUNCTS_THEN2 STRIP_ASSUME_TAC MP_TAC) THEN + GEN_REWRITE_TAC LAND_CONV [SUBSET] THEN REWRITE_TAC[IN_ELIM_THM] THEN + ASM_CASES_TAC `k:real^1->bool = {}` THENL + [ASM_REWRITE_TAC[NOT_IN_EMPTY; GSYM NOT_EXISTS_THM; MEMBER_NOT_EMPTY] THEN + REWRITE_TAC[INTERVAL_EQ_EMPTY_1; DROP_VEC] THEN REAL_ARITH_TAC; + DISCH_THEN(LABEL_TAC "+")] THEN + SUBGOAL_THEN `!i:real^1. i IN k ==> &0 < ee(i)` + ASSUME_TAC THENL [ASM_MESON_TAC[SUBSET]; ALL_TAC] THEN + ABBREV_TAC `e = inf(IMAGE (ee:real^1->real) k)` THEN + MP_TAC(ISPEC `IMAGE (ee:real^1->real) k` INF_FINITE) THEN + MP_TAC(ISPECL [`IMAGE (ee:real^1->real) k`; `&0`] + REAL_LT_INF_FINITE) THEN + ASM_SIMP_TAC[FINITE_IMAGE; IMAGE_EQ_EMPTY; FORALL_IN_IMAGE] THEN + DISCH_TAC THEN DISCH_THEN(ASSUME_TAC o CONJUNCT2) THEN + MP_TAC(ISPEC `e / &3` REAL_ARCH_INV) THEN + ASM_REWRITE_TAC[REAL_ARITH `&0 < e / &3 <=> &0 < e`] THEN + DISCH_THEN(X_CHOOSE_THEN `N:num` STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN + `!n. n <= N + ==> ?d. &0 < d /\ + !j. valid_path j /\ + (!u. u IN interval [vec 0,vec 1] + ==> norm(j u - k(pastecart (lift(&n / &N)) u)) < d) /\ + pathfinish j = pathstart j + ==> path_image j SUBSET s /\ + path_integral j f = path_integral g f` + (MP_TAC o SPEC `N:num`) THENL + [ALL_TAC; + REWRITE_TAC[LE_REFL; LEFT_IMP_EXISTS_THM] THEN + GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + DISCH_THEN(MP_TAC o SPEC `h:real^1->complex`) THEN + ASM_SIMP_TAC[REAL_DIV_REFL; REAL_OF_NUM_EQ; LIFT_NUM] THEN + ASM_REWRITE_TAC[VECTOR_SUB_REFL; NORM_0] THEN MESON_TAC[]] THEN + INDUCT_TAC THENL + [REMOVE_THEN "*" (MP_TAC o SPEC `vec 0:real^1`) THEN + ASM_REWRITE_TAC[real_div; REAL_MUL_LZERO; LE_0; LIFT_NUM] THEN + REWRITE_TAC[IN_INTERVAL_1; DROP_VEC; REAL_POS; REAL_LE_REFL] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + REPEAT(DISCH_THEN(MP_TAC o SPEC `vec 0:real^1`) THEN + REWRITE_TAC[IN_INTERVAL_1; DROP_VEC; REAL_POS; REAL_LE_REFL]) THEN + ASM_REWRITE_TAC[VECTOR_SUB_REFL; NORM_0] THEN + MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC THEN STRIP_TAC THEN + ASM_REWRITE_TAC[] THEN X_GEN_TAC `j:real^1->complex` THEN + STRIP_TAC THEN FIRST_X_ASSUM(MP_TAC o SPECL + [`g:real^1->complex`; `j:real^1->complex`]) THEN + ASM_REWRITE_TAC[VECTOR_SUB_REFL; NORM_0] THEN MESON_TAC[]; + DISCH_TAC] THEN + SUBGOAL_THEN `lift(&n / &N) IN interval[vec 0,vec 1] /\ + lift(&(SUC n) / &N) IN interval[vec 0,vec 1]` + STRIP_ASSUME_TAC THENL + [REWRITE_TAC[IN_INTERVAL_1; DROP_VEC; LIFT_DROP] THEN + ASM_SIMP_TAC[REAL_LE_RDIV_EQ; REAL_LE_LDIV_EQ; REAL_OF_NUM_LT; LE_1] THEN + REWRITE_TAC[REAL_MUL_LZERO; REAL_MUL_LID; REAL_OF_NUM_LE] THEN + ASM_ARITH_TAC; + ALL_TAC] THEN + REMOVE_THEN "+" (MP_TAC o SPEC `lift(&n / &N)`) THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `t:real^1` STRIP_ASSUME_TAC) THEN + FIRST_X_ASSUM(MP_TAC o check (is_imp o concl)) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN + DISCH_THEN(X_CHOOSE_THEN `d1:real` + (CONJUNCTS_THEN2 ASSUME_TAC (LABEL_TAC "1"))) THEN + REMOVE_THEN "*" (MP_TAC o SPEC `t:real^1`) THEN + ANTS_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + DISCH_THEN(MP_TAC o SPECL [`lift(&n / &N)`; `lift(&(SUC n) / &N)`]) THEN + ASM_REWRITE_TAC[] THEN ANTS_TAC THENL + [FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_BALL]) THEN + MATCH_MP_TAC(NORM_ARITH + `!e. norm(n' - n:real^N) < e / &3 /\ e <= ee + ==> dist(t,n) < ee / &3 ==> norm(n - t) < ee /\ norm(n' - t) < ee`) THEN + EXISTS_TAC `e:real` THEN + REWRITE_TAC[NORM_REAL; GSYM drop; DROP_SUB; LIFT_DROP] THEN + REWRITE_TAC[real_div; GSYM REAL_SUB_RDISTRIB] THEN + SIMP_TAC[REAL_OF_NUM_SUB; ARITH_RULE `n <= SUC n`] THEN + REWRITE_TAC[ARITH_RULE `SUC n - n = 1`; REAL_MUL_LID] THEN + REWRITE_TAC[REAL_ABS_INV; REAL_ABS_NUM] THEN + ASM_SIMP_TAC[GSYM real_div]; + ALL_TAC] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `d2:real` THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + X_GEN_TAC `j:real^1->complex` THEN STRIP_TAC THEN + MP_TAC(ISPECL + [`\u:real^1. (k(pastecart (lift (&n / &N)) u):complex)`; + `min d1 d2`] PATH_APPROX_VECTOR_POLYNOMIAL_FUNCTION) THEN + ASM_SIMP_TAC[REAL_LT_MIN; REAL_ARITH `&0 < e / &4 <=> &0 < e`] THEN + ANTS_TAC THENL + [REWRITE_TAC[path] THEN GEN_REWRITE_TAC LAND_CONV [GSYM o_DEF] THEN + MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN + SIMP_TAC[CONTINUOUS_ON_PASTECART; CONTINUOUS_ON_ID; + CONTINUOUS_ON_CONST] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET)) THEN + ASM SET_TAC[]; + DISCH_THEN(X_CHOOSE_THEN `p:real^1->complex` STRIP_ASSUME_TAC)] THEN + REMOVE_THEN "1" (MP_TAC o SPEC `p:real^1->complex`) THEN + ASM_SIMP_TAC[VALID_PATH_VECTOR_POLYNOMIAL_FUNCTION] THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`p:real^1->complex`; `j:real^1->complex`]) THEN + ASM_SIMP_TAC[VALID_PATH_VECTOR_POLYNOMIAL_FUNCTION]);; + +let CAUCHY_THEOREM_NULL_HOMOTOPIC = prove + (`!f g s a. + open s /\ f holomorphic_on s /\ a IN s /\ valid_path g /\ + homotopic_loops s g (linepath(a,a)) + ==> (f has_path_integral Cx(&0)) g`, + REPEAT STRIP_TAC THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP HOMOTOPIC_LOOPS_IMP_SUBSET) THEN + MATCH_MP_TAC + (MESON[HAS_PATH_INTEGRAL_INTEGRAL; path_integrable_on; PATH_INTEGRAL_UNIQUE] + `!p. f path_integrable_on g /\ (f has_path_integral y) p /\ + path_integral g f = path_integral p f + ==> (f has_path_integral y) g`) THEN + EXISTS_TAC `linepath(a:complex,a)` THEN REPEAT CONJ_TAC THENL + [ASM_MESON_TAC[PATH_INTEGRABLE_HOLOMORPHIC_SIMPLE]; + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [OPEN_CONTAINS_BALL]) THEN + DISCH_THEN(MP_TAC o SPEC `a:complex`) THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `e:real` STRIP_ASSUME_TAC) THEN + MATCH_MP_TAC CAUCHY_THEOREM_CONVEX_SIMPLE THEN + EXISTS_TAC `ball(a:complex,e)` THEN + ASM_REWRITE_TAC[VALID_PATH_LINEPATH; CONVEX_BALL; PATH_IMAGE_LINEPATH; + PATHSTART_LINEPATH; PATHFINISH_LINEPATH] THEN + ASM_REWRITE_TAC[SEGMENT_REFL; SING_SUBSET; IN_BALL; CENTRE_IN_BALL] THEN + ASM_MESON_TAC[HOLOMORPHIC_ON_SUBSET]; + MATCH_MP_TAC CAUCHY_THEOREM_HOMOTOPIC_LOOPS THEN + EXISTS_TAC `s:complex->bool` THEN ASM_REWRITE_TAC[VALID_PATH_LINEPATH]]);; + +let CAUCHY_THEOREM_SIMPLY_CONNECTED = prove + (`!f g s. open s /\ simply_connected s /\ f holomorphic_on s /\ + valid_path g /\ path_image g SUBSET s /\ pathfinish g = pathstart g + ==> (f has_path_integral Cx(&0)) g`, + REWRITE_TAC[SIMPLY_CONNECTED_EQ_CONTRACTIBLE_PATH] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC CAUCHY_THEOREM_NULL_HOMOTOPIC THEN + MAP_EVERY EXISTS_TAC [`s:complex->bool`; `pathstart g :complex`] THEN + ASM_REWRITE_TAC[] THEN CONJ_TAC THENL + [ASM_MESON_TAC[PATHSTART_IN_PATH_IMAGE; SUBSET]; + MATCH_MP_TAC HOMOTOPIC_PATHS_IMP_HOMOTOPIC_LOOPS THEN + ASM_SIMP_TAC[PATHFINISH_LINEPATH; VALID_PATH_IMP_PATH]]);; + +(* ------------------------------------------------------------------------- *) +(* More winding number properties, including the fact that it's +-1 inside *) +(* a simple closed curve. *) +(* ------------------------------------------------------------------------- *) + +let WINDING_NUMBER_HOMOTOPIC_PATHS = prove + (`!g h z. homotopic_paths ((:complex) DELETE z) g h + ==> winding_number(g,z) = winding_number(h,z)`, + REPEAT STRIP_TAC THEN + FIRST_ASSUM(STRIP_ASSUME_TAC o MATCH_MP HOMOTOPIC_PATHS_IMP_PATH) THEN + FIRST_ASSUM(MP_TAC o MATCH_MP HOMOTOPIC_PATHS_IMP_SUBSET) THEN + REWRITE_TAC[SET_RULE `s SUBSET UNIV DELETE z <=> ~(z IN s)`] THEN + STRIP_TAC THEN + MP_TAC(ISPECL [`g:real^1->complex`; `(:complex) DELETE z`] + HOMOTOPIC_NEARBY_PATHS) THEN + ASM_SIMP_TAC[OPEN_DELETE; OPEN_UNIV; SET_RULE + `s SUBSET UNIV DELETE z <=> ~(z IN s)`] THEN + DISCH_THEN(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC) THEN + MP_TAC(ISPECL [`g:real^1->complex`; `z:complex`; `d:real`] + WINDING_NUMBER) THEN ASM_SIMP_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `p:real^1->complex` STRIP_ASSUME_TAC) THEN + MP_TAC(ISPECL [`h:real^1->complex`; `(:complex) DELETE z`] + HOMOTOPIC_NEARBY_PATHS) THEN + ASM_SIMP_TAC[OPEN_DELETE; OPEN_UNIV; SET_RULE + `s SUBSET UNIV DELETE z <=> ~(z IN s)`] THEN + DISCH_THEN(X_CHOOSE_THEN `e:real` STRIP_ASSUME_TAC) THEN + MP_TAC(ISPECL [`h:real^1->complex`; `z:complex`; `e:real`] + WINDING_NUMBER) THEN ASM_SIMP_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `q:real^1->complex` STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN + `path_integral p (\w. Cx(&1) / (w - z)) = + path_integral q (\w. Cx(&1) / (w - z))` + MP_TAC THENL + [MATCH_MP_TAC CAUCHY_THEOREM_HOMOTOPIC_PATHS THEN + EXISTS_TAC `(:complex) DELETE z` THEN + ASM_SIMP_TAC[OPEN_DELETE; OPEN_UNIV] THEN CONJ_TAC THENL + [MATCH_MP_TAC HOLOMORPHIC_ON_DIV THEN + SIMP_TAC[HOLOMORPHIC_ON_CONST; HOLOMORPHIC_ON_ID; + HOLOMORPHIC_ON_SUB; IN_DELETE; COMPLEX_SUB_0]; + ALL_TAC] THEN + MATCH_MP_TAC HOMOTOPIC_PATHS_TRANS THEN + EXISTS_TAC `g:real^1->complex` THEN CONJ_TAC THENL + [ONCE_REWRITE_TAC[HOMOTOPIC_PATHS_SYM] THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_MESON_TAC[NORM_SUB; VALID_PATH_IMP_PATH]; + MATCH_MP_TAC HOMOTOPIC_PATHS_TRANS THEN + EXISTS_TAC `h:real^1->complex` THEN ASM_REWRITE_TAC[] THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_MESON_TAC[NORM_SUB; VALID_PATH_IMP_PATH]]; + ASM_REWRITE_TAC[] THEN MP_TAC CX_2PII_NZ THEN CONV_TAC COMPLEX_RING]);; + +let WINDING_NUMBER_HOMOTOPIC_LOOPS = prove + (`!g h z. homotopic_loops ((:complex) DELETE z) g h + ==> winding_number(g,z) = winding_number(h,z)`, + REPEAT STRIP_TAC THEN + FIRST_ASSUM(STRIP_ASSUME_TAC o MATCH_MP HOMOTOPIC_LOOPS_IMP_PATH) THEN + FIRST_ASSUM(STRIP_ASSUME_TAC o MATCH_MP HOMOTOPIC_LOOPS_IMP_LOOP) THEN + FIRST_ASSUM(MP_TAC o MATCH_MP HOMOTOPIC_LOOPS_IMP_SUBSET) THEN + REWRITE_TAC[SET_RULE `s SUBSET UNIV DELETE z <=> ~(z IN s)`] THEN + STRIP_TAC THEN + MP_TAC(ISPECL [`g:real^1->complex`; `(:complex) DELETE z`] + HOMOTOPIC_NEARBY_LOOPS) THEN + ASM_SIMP_TAC[OPEN_DELETE; OPEN_UNIV; SET_RULE + `s SUBSET UNIV DELETE z <=> ~(z IN s)`] THEN + DISCH_THEN(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC) THEN + MP_TAC(ISPECL [`g:real^1->complex`; `z:complex`; `d:real`] + WINDING_NUMBER) THEN ASM_SIMP_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `p:real^1->complex` STRIP_ASSUME_TAC) THEN + MP_TAC(ISPECL [`h:real^1->complex`; `(:complex) DELETE z`] + HOMOTOPIC_NEARBY_LOOPS) THEN + ASM_SIMP_TAC[OPEN_DELETE; OPEN_UNIV; SET_RULE + `s SUBSET UNIV DELETE z <=> ~(z IN s)`] THEN + DISCH_THEN(X_CHOOSE_THEN `e:real` STRIP_ASSUME_TAC) THEN + MP_TAC(ISPECL [`h:real^1->complex`; `z:complex`; `e:real`] + WINDING_NUMBER) THEN ASM_SIMP_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `q:real^1->complex` STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN + `path_integral p (\w. Cx(&1) / (w - z)) = + path_integral q (\w. Cx(&1) / (w - z))` + MP_TAC THENL + [MATCH_MP_TAC CAUCHY_THEOREM_HOMOTOPIC_LOOPS THEN + EXISTS_TAC `(:complex) DELETE z` THEN + ASM_SIMP_TAC[OPEN_DELETE; OPEN_UNIV] THEN CONJ_TAC THENL + [MATCH_MP_TAC HOLOMORPHIC_ON_DIV THEN + SIMP_TAC[HOLOMORPHIC_ON_CONST; HOLOMORPHIC_ON_ID; + HOLOMORPHIC_ON_SUB; IN_DELETE; COMPLEX_SUB_0]; + ALL_TAC] THEN + MATCH_MP_TAC HOMOTOPIC_LOOPS_TRANS THEN + EXISTS_TAC `g:real^1->complex` THEN CONJ_TAC THENL + [ONCE_REWRITE_TAC[HOMOTOPIC_LOOPS_SYM] THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_MESON_TAC[NORM_SUB; VALID_PATH_IMP_PATH]; + MATCH_MP_TAC HOMOTOPIC_LOOPS_TRANS THEN + EXISTS_TAC `h:real^1->complex` THEN ASM_REWRITE_TAC[] THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_MESON_TAC[NORM_SUB; VALID_PATH_IMP_PATH]]; + ASM_REWRITE_TAC[] THEN MP_TAC CX_2PII_NZ THEN CONV_TAC COMPLEX_RING]);; + +let WINDING_NUMBER_PATHS_LINEAR_EQ = prove + (`!g h z. + path g /\ path h /\ + pathstart h = pathstart g /\ + pathfinish h = pathfinish g /\ + (!t. t IN interval[vec 0,vec 1] ==> ~(z IN segment[g t,h t])) + ==> winding_number(h,z) = winding_number(g,z)`, + REPEAT STRIP_TAC THEN CONV_TAC SYM_CONV THEN + MATCH_MP_TAC WINDING_NUMBER_HOMOTOPIC_PATHS THEN + MATCH_MP_TAC HOMOTOPIC_PATHS_LINEAR THEN ASM SET_TAC[]);; + +let WINDING_NUMBER_LOOPS_LINEAR_EQ = prove + (`!g h z. + path g /\ path h /\ + pathfinish g = pathstart g /\ + pathfinish h = pathstart h /\ + (!t. t IN interval[vec 0,vec 1] ==> ~(z IN segment[g t,h t])) + ==> winding_number(h,z) = winding_number(g,z)`, + REPEAT STRIP_TAC THEN CONV_TAC SYM_CONV THEN + MATCH_MP_TAC WINDING_NUMBER_HOMOTOPIC_LOOPS THEN + MATCH_MP_TAC HOMOTOPIC_LOOPS_LINEAR THEN ASM SET_TAC[]);; + +let WINDING_NUMBER_NEARBY_PATHS_EQ = prove + (`!g h z. + path g /\ path h /\ + pathstart h = pathstart g /\ + pathfinish h = pathfinish g /\ + (!t. t IN interval[vec 0,vec 1] ==> norm(h t - g t) < norm(g t - z)) + ==> winding_number(h,z) = winding_number(g,z)`, + REPEAT STRIP_TAC THEN CONV_TAC SYM_CONV THEN + MATCH_MP_TAC WINDING_NUMBER_HOMOTOPIC_PATHS THEN + MATCH_MP_TAC HOMOTOPIC_PATHS_NEARBY_EXPLICIT THEN ASM SET_TAC[]);; + +let WINDING_NUMBER_NEARBY_LOOPS_EQ = prove + (`!g h z. + path g /\ path h /\ + pathfinish g = pathstart g /\ + pathfinish h = pathstart h /\ + (!t. t IN interval[vec 0,vec 1] ==> norm(h t - g t) < norm(g t - z)) + ==> winding_number(h,z) = winding_number(g,z)`, + REPEAT STRIP_TAC THEN CONV_TAC SYM_CONV THEN + MATCH_MP_TAC WINDING_NUMBER_HOMOTOPIC_LOOPS THEN + MATCH_MP_TAC HOMOTOPIC_LOOPS_NEARBY_EXPLICIT THEN ASM SET_TAC[]);; + +let WINDING_NUMBER_SUBPATH_COMBINE = prove + (`!g u v w z. + path g /\ ~(z IN path_image g) /\ + u IN interval [vec 0,vec 1] /\ + v IN interval [vec 0,vec 1] /\ + w IN interval [vec 0,vec 1] + ==> winding_number(subpath u v g,z) + + winding_number(subpath v w g,z) = + winding_number(subpath u w g,z)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC EQ_TRANS THEN + EXISTS_TAC `winding_number(subpath u v g ++ subpath v w g,z)` THEN + CONJ_TAC THENL + [CONV_TAC SYM_CONV THEN MATCH_MP_TAC WINDING_NUMBER_JOIN THEN + ASM_SIMP_TAC[PATH_SUBPATH; PATHSTART_SUBPATH; PATHFINISH_SUBPATH] THEN + ASM_MESON_TAC[SUBSET; PATH_IMAGE_SUBPATH_SUBSET]; + MATCH_MP_TAC WINDING_NUMBER_HOMOTOPIC_PATHS THEN + MATCH_MP_TAC HOMOTOPIC_JOIN_SUBPATHS THEN + ASM_REWRITE_TAC[] THEN ASM SET_TAC[]]);; + +let WINDING_NUMBER_STRONG = prove + (`!g z e. + path g /\ ~(z IN path_image g) /\ &0 < e + ==> ?p. vector_polynomial_function p /\ valid_path p /\ + ~(z IN path_image p) /\ + pathstart p = pathstart g /\ + pathfinish p = pathfinish g /\ + (!t. t IN interval[vec 0,vec 1] ==> norm(g t - p t) < e) /\ + path_integral p (\w. Cx(&1) / (w - z)) = + Cx(&2) * Cx(pi) * ii * winding_number(g,z)`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN + `?d. &0 < d /\ + !t. t IN interval[vec 0,vec 1] ==> d <= norm((g:real^1->complex) t - z)` + STRIP_ASSUME_TAC THENL + [EXISTS_TAC `setdist({z:complex},path_image g)` THEN + REWRITE_TAC[SETDIST_POS_LE; REAL_ARITH + `&0 < x <=> &0 <= x /\ ~(x = &0)`] THEN + ASM_SIMP_TAC[SETDIST_EQ_0_CLOSED_COMPACT; CLOSED_SING; COMPACT_PATH_IMAGE; + PATH_IMAGE_NONEMPTY] THEN + CONJ_TAC THENL [ASM SET_TAC[]; REPEAT STRIP_TAC] THEN + REWRITE_TAC[ONCE_REWRITE_RULE[DIST_SYM] (GSYM dist)] THEN + MATCH_MP_TAC SETDIST_LE_DIST THEN REWRITE_TAC[path_image] THEN + ASM SET_TAC[]; + MP_TAC(ISPECL [`g:real^1->complex`; `min d e`] + PATH_APPROX_VECTOR_POLYNOMIAL_FUNCTION) THEN + ASM_REWRITE_TAC[REAL_LT_MIN] THEN MATCH_MP_TAC MONO_EXISTS THEN + X_GEN_TAC `p:real^1->complex` THEN STRIP_TAC THEN + ONCE_REWRITE_TAC[NORM_SUB] THEN + ASM_SIMP_TAC[VALID_PATH_VECTOR_POLYNOMIAL_FUNCTION] THEN + MATCH_MP_TAC(TAUT `p /\ (p ==> q) ==> p /\ q`) THEN CONJ_TAC THENL + [REWRITE_TAC[path_image; IN_IMAGE] THEN + ASM_MESON_TAC[NORM_SUB; REAL_NOT_LT]; + DISCH_TAC THEN MATCH_MP_TAC(COMPLEX_FIELD + `!w'. ~(a * b * c = Cx(&0)) /\ w' = w /\ w' = Cx(&1) / (a * b * c) * i + ==> i = a * b * c * w`) THEN + EXISTS_TAC `winding_number(p,z)` THEN + REWRITE_TAC[CX_2PII_NZ] THEN CONJ_TAC THENL + [MATCH_MP_TAC WINDING_NUMBER_NEARBY_PATHS_EQ; ALL_TAC] THEN + ASM_SIMP_TAC[WINDING_NUMBER_VALID_PATH; VALID_PATH_IMP_PATH; + VALID_PATH_VECTOR_POLYNOMIAL_FUNCTION] THEN + ASM_MESON_TAC[REAL_LTE_TRANS; NORM_SUB]]]);; + +let WINDING_NUMBER_FROM_INNERPATH = prove + (`!c1 c2 c a b z:complex d. + ~(a = b) /\ + simple_path c1 /\ pathstart c1 = a /\ pathfinish c1 = b /\ + simple_path c2 /\ pathstart c2 = a /\ pathfinish c2 = b /\ + simple_path c /\ pathstart c = a /\ pathfinish c = b /\ + path_image c1 INTER path_image c2 = {a,b} /\ + path_image c1 INTER path_image c = {a,b} /\ + path_image c2 INTER path_image c = {a,b} /\ + ~(path_image c INTER inside(path_image c1 UNION path_image c2) = {}) /\ + z IN inside(path_image c1 UNION path_image c) /\ + winding_number(c1 ++ reversepath c,z) = d /\ ~(d = Cx(&0)) + ==> z IN inside(path_image c1 UNION path_image c2) /\ + winding_number(c1 ++ reversepath c2,z) = d`, + REPEAT GEN_TAC THEN STRIP_TAC THEN + MP_TAC(ISPECL [`c1:real^1->complex`; `c2:real^1->complex`; + `c:real^1->complex`; `a:complex`; `b:complex`] + SPLIT_INSIDE_SIMPLE_CLOSED_CURVE) THEN + ASM_REWRITE_TAC[] THEN STRIP_TAC THEN + CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + UNDISCH_TAC `winding_number(c1 ++ reversepath c,z) = d` THEN + MP_TAC(ISPECL + [`c ++ reversepath(c2:real^1->complex)`; `z:complex`] + WINDING_NUMBER_ZERO_IN_OUTSIDE) THEN + SUBGOAL_THEN + `~((z:complex) IN path_image c) /\ + ~(z IN path_image c1) /\ + ~(z IN path_image c2)` + STRIP_ASSUME_TAC THENL + [MP_TAC(ISPEC `(path_image c1 UNION path_image c):complex->bool` + INSIDE_NO_OVERLAP) THEN + MP_TAC(ISPEC `(path_image c1 UNION path_image c2):complex->bool` + INSIDE_NO_OVERLAP) THEN + ASM SET_TAC[]; + ASM_SIMP_TAC[PATHSTART_JOIN; PATHFINISH_JOIN; PATH_IMAGE_JOIN; + PATHSTART_REVERSEPATH; PATHFINISH_REVERSEPATH; PATH_IMAGE_REVERSEPATH; + PATH_JOIN; PATH_REVERSEPATH; SIMPLE_PATH_IMP_PATH; + WINDING_NUMBER_JOIN; WINDING_NUMBER_REVERSEPATH] THEN + ANTS_TAC THENL + [ASM_REWRITE_TAC[OUTSIDE_INSIDE; IN_DIFF; IN_UNION; IN_UNIV] THEN + ONCE_REWRITE_TAC[UNION_COMM] THEN ASM SET_TAC[]; + CONV_TAC COMPLEX_RING]]);; + +let SIMPLE_CLOSED_PATH_WINDING_NUMBER_INSIDE = prove + (`!g. simple_path g + ==> (!z. z IN inside(path_image g) ==> winding_number(g,z) = Cx(&1)) \/ + (!z. z IN inside(path_image g) ==> winding_number(g,z) = --Cx(&1))`, + let lemma1 = prove + (`!p a e. + &0 < e /\ + simple_path(p ++ linepath(a - e % basis 1,a + e % basis 1)) /\ + pathstart p = a + e % basis 1 /\ pathfinish p = a - e % basis 1 /\ + ball(a,e) INTER path_image p = {} + ==> ?z. z IN inside(path_image + (p ++ linepath(a - e % basis 1,a + e % basis 1))) /\ + norm(winding_number + (p ++ linepath(a - e % basis 1,a + e % basis 1),z)) = &1`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL + [`p:real^1->complex`; `linepath(a - e % basis 1,a + e % basis 1)`] + SIMPLE_PATH_JOIN_LOOP_EQ) THEN + ASM_REWRITE_TAC[PATHFINISH_LINEPATH; PATHSTART_LINEPATH] THEN + STRIP_TAC THEN + SUBGOAL_THEN + `(a:complex) IN frontier(inside + (path_image(p ++ linepath(a - e % basis 1,a + e % basis 1))))` + MP_TAC THENL + [FIRST_ASSUM + (MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] JORDAN_INSIDE_OUTSIDE)) THEN + ASM_REWRITE_TAC[PATHSTART_JOIN; PATHFINISH_JOIN; + PATHFINISH_LINEPATH] THEN + STRIP_TAC THEN ASM_SIMP_TAC[PATH_IMAGE_JOIN; PATHSTART_LINEPATH] THEN + REWRITE_TAC[IN_UNION; PATH_IMAGE_LINEPATH] THEN DISJ2_TAC THEN + REWRITE_TAC[IN_SEGMENT] THEN EXISTS_TAC `&1 / &2` THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN VECTOR_ARITH_TAC; + ALL_TAC] THEN + REWRITE_TAC[FRONTIER_STRADDLE] THEN + DISCH_THEN(MP_TAC o SPEC `e:real`) THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `c:complex` STRIP_ASSUME_TAC o CONJUNCT1) THEN + MP_TAC(ISPEC + `path_image (p ++ linepath(a - e % basis 1:complex,a + e % basis 1))` + INSIDE_NO_OVERLAP) THEN + REWRITE_TAC[EXTENSION] THEN DISCH_THEN(MP_TAC o SPEC `c:complex`) THEN + ASM_REWRITE_TAC[IN_INTER; NOT_IN_EMPTY] THEN + ASM_SIMP_TAC[PATH_IMAGE_JOIN; PATHSTART_LINEPATH; PATH_IMAGE_LINEPATH] THEN + REWRITE_TAC[IN_UNION; DE_MORGAN_THM] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [SEGMENT_AS_BALL] THEN + ASM_REWRITE_TAC[IN_INTER; + VECTOR_ARITH `inv(&2) % ((a - e) + (a + e)):complex = a`; + VECTOR_ARITH `(a + e) - (a - e):complex = &2 % e`] THEN + ASM_SIMP_TAC[NORM_MUL; NORM_BASIS; DIMINDEX_2; ARITH] THEN + ASM_SIMP_TAC[REAL_ARITH `&0 < e ==> (abs(&2) * abs e * &1) / &2 = e`] THEN + ASM_SIMP_TAC[IN_CBALL; REAL_LT_IMP_LE] THEN STRIP_TAC THEN + SUBGOAL_THEN + `~collinear{a - e % basis 1,c:complex,a + e % basis 1}` + ASSUME_TAC THENL + [MP_TAC(ISPECL + [`a - e % basis 1:complex`; `a + e % basis 1:complex`; `c:complex`] + COLLINEAR_3_AFFINE_HULL) THEN + ASM_SIMP_TAC[VECTOR_ARITH `a - x:complex = a + x <=> x = vec 0`; + BASIS_NONZERO; DIMINDEX_2; ARITH; VECTOR_MUL_EQ_0; + REAL_LT_IMP_NZ] THEN + REWRITE_TAC[INSERT_AC]; + ALL_TAC] THEN + SUBGOAL_THEN + `~(interior(convex hull {a - e % basis 1,c:complex,a + e % basis 1}) = {})` + MP_TAC THENL + [ASM_SIMP_TAC[INTERIOR_CONVEX_HULL_3_MINIMAL] THEN + REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; IN_ELIM_THM] THEN + REPEAT(ONCE_REWRITE_TAC[SWAP_EXISTS_THM] THEN EXISTS_TAC `&1 / &3`) THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN MESON_TAC[]; + ALL_TAC] THEN + REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `z:complex` THEN DISCH_TAC THEN + FIRST_ASSUM(MP_TAC o AP_TERM `norm:complex->real` o + MATCH_MP WINDING_NUMBER_TRIANGLE) THEN + REWRITE_TAC[] THEN ONCE_REWRITE_TAC[COND_RAND] THEN + REWRITE_TAC[NORM_NEG; COND_ID; COMPLEX_NORM_CX; REAL_ABS_NUM] THEN + DISCH_TAC THEN + MP_TAC(ISPECL + [`linepath(a + e % basis 1:complex,a - e % basis 1)`; + `p:real^1->complex`; + `linepath(a + e % basis 1:complex,c) ++ linepath(c,a - e % basis 1)`; + `a + e % basis 1:complex`; `a - e % basis 1:complex`; + `z:complex`; + `winding_number + (linepath(a - e % basis 1,c) ++ + linepath(c,a + e % basis 1) ++ + linepath(a + e % basis 1,a - e % basis 1), + z)`] WINDING_NUMBER_FROM_INNERPATH) THEN + ASM_SIMP_TAC[SIMPLE_PATH_LINEPATH; PATHSTART_JOIN; PATHFINISH_JOIN; + VECTOR_ARITH `a + x:complex = a - x <=> x = vec 0`; + BASIS_NONZERO; DIMINDEX_2; ARITH; VECTOR_MUL_EQ_0; + REAL_LT_IMP_NZ; PATHSTART_LINEPATH; PATHFINISH_LINEPATH; + ARC_IMP_SIMPLE_PATH; PATH_IMAGE_JOIN; PATH_IMAGE_LINEPATH] THEN + ANTS_TAC THENL + [ALL_TAC; + MATCH_MP_TAC(TAUT + `(p ==> p') /\ (p /\ q ==> q') ==> p /\ q ==> p' /\ q'`) THEN + CONJ_TAC THENL [MESON_TAC[UNION_COMM; SEGMENT_SYM]; ALL_TAC] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC (SUBST_ALL_TAC o SYM)) THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (NORM_ARITH + `norm(z:complex) = &1 ==> u = --z ==> norm u = &1`)) THEN + GEN_REWRITE_TAC (RAND_CONV o ONCE_DEPTH_CONV) + [GSYM REVERSEPATH_LINEPATH] THEN + ASM_SIMP_TAC[GSYM REVERSEPATH_JOINPATHS; PATHSTART_LINEPATH] THEN + ONCE_REWRITE_TAC[COMPLEX_RING `a:complex = --b <=> b = --a`] THEN + MATCH_MP_TAC WINDING_NUMBER_REVERSEPATH THEN + ASM_SIMP_TAC[PATH_JOIN; PATHSTART_LINEPATH; PATH_IMAGE_JOIN; + PATH_LINEPATH; ARC_IMP_PATH; PATH_IMAGE_LINEPATH] THEN + ONCE_REWRITE_TAC[SEGMENT_SYM] THEN ONCE_REWRITE_TAC[UNION_COMM] THEN + ASM_MESON_TAC[INSIDE_NO_OVERLAP; IN_INTER; NOT_IN_EMPTY]] THEN + REPEAT CONJ_TAC THENL + [MATCH_MP_TAC ARC_IMP_SIMPLE_PATH THEN MATCH_MP_TAC ARC_JOIN THEN + REWRITE_TAC[ARC_LINEPATH_EQ; PATHSTART_LINEPATH; + PATHFINISH_LINEPATH] THEN + REPEAT(CONJ_TAC THENL + [DISCH_THEN SUBST_ALL_TAC THEN + RULE_ASSUM_TAC(REWRITE_RULE[INSERT_AC; COLLINEAR_2]) THEN + FIRST_X_ASSUM CONTR_TAC; + ALL_TAC]) THEN + REWRITE_TAC[PATH_IMAGE_LINEPATH] THEN + MATCH_MP_TAC(SET_RULE `s = t ==> s SUBSET t`) THEN + MATCH_MP_TAC INTER_SEGMENT THEN ASM_MESON_TAC[INSERT_AC]; + REWRITE_TAC[SEGMENT_CLOSED_OPEN] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE + `b INTER p = {} + ==> s SUBSET b /\ k SUBSET p + ==> (s UNION k) INTER p = k`)) THEN + CONJ_TAC THENL + [REWRITE_TAC[SUBSET; IN_SEGMENT; IN_BALL] THEN + REWRITE_TAC[VECTOR_ARITH + `(&1 - u) % (a + e) + u % (a - e):complex = + a + (&1 - &2 * u) % e`] THEN + REPEAT STRIP_TAC THEN + ASM_REWRITE_TAC[NORM_ARITH `dist(a:complex,a + e) = norm e`] THEN + SIMP_TAC[NORM_MUL; NORM_BASIS; DIMINDEX_2; ARITH] THEN + MATCH_MP_TAC(REAL_ARITH + `x * e < &1 * e /\ &0 < e ==> x * abs e * &1 < e`) THEN + ASM_SIMP_TAC[REAL_LT_RMUL_EQ] THEN ASM_REAL_ARITH_TAC; + REWRITE_TAC[INSERT_SUBSET; EMPTY_SUBSET] THEN + ASM_MESON_TAC[PATHSTART_IN_PATH_IMAGE; PATHFINISH_IN_PATH_IMAGE]]; + MATCH_MP_TAC(SET_RULE + `s INTER t1 = {a} /\ s INTER t2 = {b} + ==> s INTER (t1 UNION t2) = {a,b}`) THEN + CONJ_TAC THENL + [GEN_REWRITE_TAC (LAND_CONV o LAND_CONV) [SEGMENT_SYM]; + GEN_REWRITE_TAC (LAND_CONV o RAND_CONV) [SEGMENT_SYM]] THEN + MATCH_MP_TAC INTER_SEGMENT THEN DISJ2_TAC THEN + ASM_MESON_TAC[INSERT_AC]; + MATCH_MP_TAC(SET_RULE + `s INTER t1 = {a} /\ s INTER t2 = {b} + ==> s INTER (t1 UNION t2) = {a,b}`) THEN + CONJ_TAC THENL [ONCE_REWRITE_TAC[SEGMENT_SYM]; ALL_TAC] THEN + REWRITE_TAC[SEGMENT_CLOSED_OPEN] THEN + MATCH_MP_TAC(SET_RULE + `b IN p /\ ~(c IN p) /\ p INTER s = {} + ==> p INTER (s UNION {c,b}) = {b}`) THEN + (CONJ_TAC THENL + [ASM_MESON_TAC[PATHSTART_IN_PATH_IMAGE; PATHFINISH_IN_PATH_IMAGE]; + ASM_REWRITE_TAC[]]) THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE + `b INTER p = {} ==> s SUBSET b ==> p INTER s = {}`)) THEN + REWRITE_TAC[GSYM INTERIOR_CBALL] THEN + MATCH_MP_TAC IN_INTERIOR_CLOSURE_CONVEX_SEGMENT THEN + ASM_REWRITE_TAC[CONVEX_CBALL; INTERIOR_CBALL; IN_BALL] THEN + MATCH_MP_TAC(REWRITE_RULE[SUBSET] CLOSURE_SUBSET) THEN + REWRITE_TAC[IN_CBALL; + NORM_ARITH `dist(a:complex,a - e) = norm e`; + NORM_ARITH `dist(a:complex,a + e) = norm e`] THEN + ASM_SIMP_TAC[NORM_MUL; NORM_BASIS; DIMINDEX_2; ARITH] THEN + ASM_REAL_ARITH_TAC; + REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN EXISTS_TAC `c:complex` THEN + REWRITE_TAC[IN_INTER; ENDS_IN_SEGMENT; IN_UNION] THEN + FIRST_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE + `c IN s ==> s = t ==> c IN t`)) THEN + ASM_SIMP_TAC[PATH_IMAGE_JOIN; PATHSTART_LINEPATH] THEN + REWRITE_TAC[UNION_COMM; PATH_IMAGE_LINEPATH; SEGMENT_SYM]; + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE RAND_CONV [GSYM + INSIDE_OF_TRIANGLE]) THEN + REWRITE_TAC[UNION_ACI; SEGMENT_SYM]; + ASM_SIMP_TAC[REVERSEPATH_JOINPATHS; PATHSTART_JOIN; PATHFINISH_JOIN; + PATHSTART_LINEPATH; PATHFINISH_LINEPATH; REVERSEPATH_LINEPATH] THEN + RULE_ASSUM_TAC(REWRITE_RULE + [INTERIOR_OF_TRIANGLE; IN_DIFF; IN_UNION; DE_MORGAN_THM]) THEN + ASM_SIMP_TAC[WINDING_NUMBER_JOIN; PATH_JOIN; PATH_LINEPATH; + PATH_IMAGE_JOIN; IN_UNION; PATHSTART_JOIN; PATHFINISH_JOIN; + PATHSTART_LINEPATH; PATHFINISH_LINEPATH; PATH_IMAGE_LINEPATH] THEN + CONV_TAC COMPLEX_RING; + DISCH_THEN SUBST_ALL_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE LAND_CONV [COMPLEX_NORM_CX]) THEN + REAL_ARITH_TAC]) in + let lemma2 = prove + (`!p a d e. + &0 < d /\ &0 < e /\ + simple_path(p ++ linepath(a - d % basis 1,a + e % basis 1)) /\ + pathstart p = a + e % basis 1 /\ pathfinish p = a - d % basis 1 + ==> ?z. z IN inside(path_image + (p ++ linepath(a - d % basis 1,a + e % basis 1))) /\ + norm(winding_number + (p ++ linepath(a - d % basis 1,a + e % basis 1),z)) = &1`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL + [`p:real^1->complex`; `linepath(a - d % basis 1,a + e % basis 1)`] + SIMPLE_PATH_JOIN_LOOP_EQ) THEN + ASM_REWRITE_TAC[PATHFINISH_LINEPATH; PATHSTART_LINEPATH] THEN + REWRITE_TAC[ARC_LINEPATH_EQ; PATH_IMAGE_LINEPATH] THEN STRIP_TAC THEN + SUBGOAL_THEN `~((a:complex) IN path_image p)` ASSUME_TAC THENL + [FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE + `p INTER s SUBSET {d,e} + ==> a IN s /\ ~(d = a) /\ ~(e = a) ==> ~(a IN p)`)) THEN + REWRITE_TAC[GSYM BETWEEN_IN_SEGMENT; between] THEN + REWRITE_TAC[NORM_ARITH `dist(a - d:complex,a + e) = norm(d + e)`; + NORM_ARITH `dist(a - d:complex,a) + dist(a,a + e) = norm(d) + norm(e)`; + VECTOR_ARITH `a + e:complex = a <=> e = vec 0`; + VECTOR_ARITH `a - d:complex = a <=> d = vec 0`] THEN + SIMP_TAC[GSYM VECTOR_ADD_RDISTRIB; NORM_MUL; VECTOR_MUL_EQ_0] THEN + ASM_SIMP_TAC[BASIS_NONZERO; NORM_BASIS; DIMINDEX_2; ARITH] THEN + ASM_REAL_ARITH_TAC; + ALL_TAC] THEN + MP_TAC(ISPEC `(:complex) DIFF path_image p` OPEN_CONTAINS_BALL) THEN + ASM_SIMP_TAC[GSYM closed; CLOSED_ARC_IMAGE; IN_UNIV; IN_DIFF] THEN + DISCH_THEN(MP_TAC o SPEC `a:complex`) THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[SET_RULE `s SUBSET UNIV DIFF t <=> s INTER t = {}`] THEN + DISCH_THEN(X_CHOOSE_THEN `k:real` STRIP_ASSUME_TAC) THEN + ABBREV_TAC `kde:real = min k (min d e) / &2` THEN + SUBGOAL_THEN `&0 < kde /\ kde < k /\ kde < d /\ kde < e` + STRIP_ASSUME_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN + MP_TAC(ISPECL + [`linepath(a + kde % basis 1,a + e % basis 1) ++ p ++ + linepath(a - d % basis 1,a - kde % basis 1)`; + `a:complex`; `kde:real`] lemma1) THEN + ASM_SIMP_TAC[PATHSTART_JOIN; PATHFINISH_JOIN; PATH_IMAGE_JOIN; + PATHSTART_LINEPATH; PATHFINISH_LINEPATH; PATH_IMAGE_LINEPATH; + SIMPLE_PATH_JOIN_LOOP_EQ] THEN + ANTS_TAC THENL + [REPEAT CONJ_TAC THENL + [MATCH_MP_TAC ARC_JOIN THEN + ASM_SIMP_TAC[ARC_JOIN_EQ; PATHSTART_LINEPATH; PATHFINISH_LINEPATH; + PATHSTART_JOIN; PATHFINISH_JOIN; PATH_IMAGE_LINEPATH; + ARC_LINEPATH_EQ; PATH_IMAGE_JOIN] THEN + REWRITE_TAC[VECTOR_ARITH `a + e:complex = a + d <=> e - d = vec 0`; + VECTOR_ARITH `a - d:complex = a - e <=> e - d = vec 0`] THEN + REWRITE_TAC[GSYM VECTOR_SUB_RDISTRIB; VECTOR_MUL_EQ_0; REAL_SUB_0] THEN + ASM_SIMP_TAC[BASIS_NONZERO; NORM_BASIS; DIMINDEX_2; ARITH] THEN + ASM_SIMP_TAC[REAL_LT_IMP_NE] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE + `p INTER de SUBSET {e,d} + ==> dk SUBSET de /\ ke SUBSET de /\ ~(e IN dk) /\ ~(d IN ke) /\ + ke INTER dk = {} + ==> p INTER dk SUBSET {d} /\ ke INTER (p UNION dk) SUBSET {e}`)) THEN + REWRITE_TAC[SUBSET_SEGMENT; ENDS_IN_SEGMENT] THEN + REWRITE_TAC[GSYM BETWEEN_IN_SEGMENT; between] THEN + REWRITE_TAC[NORM_ARITH `dist(a - d:complex,a + e) = norm(d + e) /\ + dist(a + d,a - e) = norm(d + e) /\ + dist(a - d,a - e) = norm(d - e) /\ + dist(a + d,a + e) = norm(d - e)`] THEN + REWRITE_TAC[GSYM VECTOR_ADD_RDISTRIB; GSYM VECTOR_SUB_RDISTRIB] THEN + ASM_SIMP_TAC[NORM_MUL; NORM_BASIS; DIMINDEX_2; ARITH] THEN + REPEAT(CONJ_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC]) THEN + REWRITE_TAC[EXTENSION; IN_ELIM_THM; IN_INTER; NOT_IN_EMPTY] THEN + MATCH_MP_TAC(MESON[REAL_LT_ANTISYM] + `!a:complex. (!x. x IN t ==> x$1 < a$1) /\ (!x. x IN s ==> a$1 < x$1) + ==> !x. ~(x IN s /\ x IN t)`) THEN + EXISTS_TAC `a:complex` THEN + SIMP_TAC[IN_SEGMENT; LEFT_IMP_EXISTS_THM] THEN + SIMP_TAC[VECTOR_SUB_COMPONENT; VECTOR_ADD_COMPONENT; + VECTOR_MUL_COMPONENT; BASIS_COMPONENT; DIMINDEX_2; ARITH] THEN + REWRITE_TAC[REAL_ARITH + `(a < (&1 - u) * (a + x) + u * (a + y) <=> + &0 < (&1 - u) * x + u * y) /\ + ((&1 - u) * (a - x) + u * (a - y) < a <=> + &0 < (&1 - u) * x + u * y)`] THEN + REPEAT STRIP_TAC THEN REWRITE_TAC[REAL_MUL_RID] THEN + REWRITE_TAC[REAL_ARITH `&0 < (&1 - u) * x + u * y <=> + (&1 - u) * --x + u * --y < &0`] THEN + MATCH_MP_TAC REAL_CONVEX_BOUND_LT THEN ASM_REAL_ARITH_TAC; + REWRITE_TAC[ARC_LINEPATH_EQ; VECTOR_MUL_EQ_0; + VECTOR_ARITH `a - k:complex = a + k <=> k = vec 0`] THEN + ASM_SIMP_TAC[REAL_LT_IMP_NZ; BASIS_NONZERO; DIMINDEX_2; ARITH]; + MATCH_MP_TAC(SET_RULE + `kk INTER p = {} /\ kk INTER ke = {kp} /\ dk INTER kk = {kn} + ==> (ke UNION p UNION dk) INTER kk SUBSET {kp,kn}`) THEN + CONJ_TAC THENL + [FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE + `b INTER p = {} ==> s SUBSET b ==> s INTER p = {}`)) THEN + SIMP_TAC[SUBSET; IN_SEGMENT; IN_BALL; LEFT_IMP_EXISTS_THM] THEN + REWRITE_TAC[VECTOR_ARITH + `(&1 - u) % (a - d) + u % (a + d):complex = a - (&1 - &2 * u) % d`; + NORM_ARITH `dist(a:complex,a - d) = norm d`] THEN + REPEAT STRIP_TAC THEN + SIMP_TAC[NORM_MUL; NORM_BASIS; DIMINDEX_2; ARITH] THEN + MATCH_MP_TAC(REAL_ARITH + `&0 < kd /\ a * kd <= &1 * kd /\ kd < k + ==> a * abs kd * &1 < k`) THEN + ASM_SIMP_TAC[REAL_LE_RMUL_EQ] THEN ASM_REAL_ARITH_TAC; + CONJ_TAC THEN MATCH_MP_TAC INTER_SEGMENT THEN DISJ1_TAC THEN + REWRITE_TAC[GSYM BETWEEN_IN_SEGMENT; between] THEN + REWRITE_TAC[NORM_ARITH `dist(a - d:complex,a + e) = norm(d + e) /\ + dist(a + d,a - e) = norm(d + e) /\ + dist(a - d,a - e) = norm(d - e) /\ + dist(a + d,a + e) = norm(d - e)`] THEN + REWRITE_TAC[GSYM VECTOR_ADD_RDISTRIB; GSYM VECTOR_SUB_RDISTRIB] THEN + ASM_SIMP_TAC[NORM_MUL; NORM_BASIS; DIMINDEX_2; ARITH] THEN + ASM_REAL_ARITH_TAC]; + REWRITE_TAC[UNION_OVER_INTER; EMPTY_UNION] THEN + ONCE_REWRITE_TAC[TAUT `a /\ b /\ c <=> b /\ a /\ c`] THEN CONJ_TAC THENL + [FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE + `b INTER p = {} ==> c SUBSET b ==> c INTER p = {}`)) THEN + MATCH_MP_TAC SUBSET_BALL THEN ASM_SIMP_TAC[REAL_LT_IMP_LE]; + ALL_TAC] THEN + REWRITE_TAC[SET_RULE `s INTER t = {} <=> + !x. x IN t ==> ~(x IN s)`] THEN + SIMP_TAC[IN_SEGMENT; LEFT_IMP_EXISTS_THM; IN_BALL] THEN + REWRITE_TAC[VECTOR_ARITH + `(&1 - u) % (a - d) + u % (a - e):complex = + a - ((&1 - u) % d + u % e) /\ + (&1 - u) % (a + d) + u % (a + e):complex = + a + ((&1 - u) % d + u % e)`; + NORM_ARITH + `dist(a:complex,a + d) = norm d /\ dist(a,a - e) = norm e`] THEN + REWRITE_TAC[VECTOR_MUL_ASSOC; GSYM VECTOR_ADD_RDISTRIB] THEN + SIMP_TAC[NORM_MUL; NORM_BASIS; DIMINDEX_2; ARITH] THEN + REWRITE_TAC[REAL_NOT_LT; REAL_MUL_RID] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC(REAL_ARITH `x <= y ==> x <= abs y`) THEN + REWRITE_TAC[REAL_ARITH + `(k <= (&1 - u) * k + u * e <=> &0 <= u * (e - k)) /\ + (k <= (&1 - u) * d + u * k <=> &0 <= (&1 - u) * (d - k))`] THEN + MATCH_MP_TAC REAL_LE_MUL THEN ASM_REAL_ARITH_TAC]; + ALL_TAC] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `z:complex` THEN + MATCH_MP_TAC(TAUT + `(p <=> p') /\ (p /\ p' ==> (q <=> q')) ==> p /\ q ==> p' /\ q'`) THEN + CONJ_TAC THENL + [AP_TERM_TAC THEN AP_TERM_TAC THEN + ONCE_REWRITE_TAC[SET_RULE + `(c UNION p UNION a) UNION b = p UNION (a UNION b UNION c)`] THEN + AP_TERM_TAC THEN + W(MP_TAC o PART_MATCH (lhand o rand) UNION_SEGMENT o + rand o lhand o snd) THEN + REWRITE_TAC[GSYM BETWEEN_IN_SEGMENT; between; + NORM_ARITH `dist(a - d:complex,a + e) = norm(d + e)`; + NORM_ARITH `dist(a + d:complex,a + e) = norm(d - e)`] THEN + ASM_SIMP_TAC[GSYM VECTOR_ADD_RDISTRIB; GSYM VECTOR_SUB_RDISTRIB; + NORM_MUL; NORM_BASIS; DIMINDEX_2; ARITH] THEN + ANTS_TAC THENL [ASM_REAL_ARITH_TAC; DISCH_THEN SUBST1_TAC] THEN + MATCH_MP_TAC UNION_SEGMENT THEN + REWRITE_TAC[GSYM BETWEEN_IN_SEGMENT; between; + NORM_ARITH `dist(a - d:complex,a + e) = norm(d + e)`; + NORM_ARITH `dist(a - d:complex,a - e) = norm(d - e)`] THEN + ASM_SIMP_TAC[GSYM VECTOR_ADD_RDISTRIB; GSYM VECTOR_SUB_RDISTRIB; + NORM_MUL; NORM_BASIS; DIMINDEX_2; ARITH] THEN + ASM_REAL_ARITH_TAC; + ALL_TAC] THEN + DISCH_THEN(CONJUNCTS_THEN (MP_TAC o MATCH_MP + (MESON[INSIDE_NO_OVERLAP; IN_INTER; NOT_IN_EMPTY] + `z IN inside s ==> ~(z IN s)`))) THEN + REWRITE_TAC[IN_UNION; DE_MORGAN_THM] THEN REPEAT STRIP_TAC THEN + AP_THM_TAC THEN AP_TERM_TAC THEN AP_TERM_TAC THEN + ASM_SIMP_TAC[WINDING_NUMBER_JOIN; PATH_JOIN; ARC_IMP_PATH; PATH_LINEPATH; + PATH_IMAGE_JOIN; IN_UNION; PATH_IMAGE_LINEPATH; PATHSTART_JOIN; + PATHFINISH_JOIN; PATHSTART_LINEPATH; PATHFINISH_LINEPATH] THEN + MATCH_MP_TAC(COMPLEX_RING + `d + k + e:complex = z ==> (e + p + d) + k = p + z`) THEN + MATCH_MP_TAC EQ_TRANS THEN + EXISTS_TAC + `winding_number(linepath (a - d % basis 1:complex,a - kde % basis 1),z) + + winding_number(linepath (a - kde % basis 1,a + e % basis 1),z)` THEN + CONJ_TAC THENL [AP_TERM_TAC; ALL_TAC] THEN CONV_TAC SYM_CONV THEN + MATCH_MP_TAC WINDING_NUMBER_SPLIT_LINEPATH THEN + ASM_REWRITE_TAC[] THENL + [CONJ_TAC THENL + [ALL_TAC; + SUBGOAL_THEN + `~(z IN segment[a - kde % basis 1:complex,a + kde % basis 1]) /\ + ~(z IN segment[a + kde % basis 1,a + e % basis 1])` + MP_TAC THENL [ASM_REWRITE_TAC[]; ALL_TAC] THEN + MATCH_MP_TAC(SET_RULE + `s UNION t = u ==> ~(z IN s) /\ ~(z IN t) ==> ~(z IN u)`) THEN + MATCH_MP_TAC UNION_SEGMENT]; + ALL_TAC] THEN + REWRITE_TAC[GSYM BETWEEN_IN_SEGMENT; between] THEN + REWRITE_TAC[NORM_ARITH `dist(a - d:complex,a + e) = norm(d + e)`; + NORM_ARITH `dist(a - d:complex,a - e) = norm(d - e)`; + NORM_ARITH `dist(a + d:complex,a + e) = norm(d - e)`] THEN + ASM_SIMP_TAC[GSYM VECTOR_ADD_RDISTRIB; GSYM VECTOR_SUB_RDISTRIB; NORM_MUL; + NORM_BASIS; DIMINDEX_2; ARITH] THEN + ASM_REAL_ARITH_TAC) in + let lemma3 = prove + (`!p:real^1->complex. + simple_path p /\ pathfinish p = pathstart p + ==> ?z. z IN inside(path_image p) /\ norm(winding_number(p,z)) = &1`, + GEN_TAC THEN STRIP_TAC THEN + MP_TAC(ISPEC `p:real^1->complex` JORDAN_INSIDE_OUTSIDE) THEN + ASM_REWRITE_TAC[] THEN STRIP_TAC THEN + UNDISCH_TAC `~(inside(path_image p):complex->bool = {})` THEN + REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN + DISCH_THEN(X_CHOOSE_TAC `a:complex`) THEN + MP_TAC(ISPECL [`inside(path_image p):complex->bool`; + `a:complex`; `basis 1:complex`] + RAY_TO_FRONTIER) THEN + MP_TAC(ISPECL [`inside(path_image p):complex->bool`; + `a:complex`; `--basis 1:complex`] + RAY_TO_FRONTIER) THEN + ASM_SIMP_TAC[INTERIOR_OPEN; VECTOR_NEG_EQ_0; BASIS_NONZERO; + DIMINDEX_2; ARITH] THEN + REWRITE_TAC[VECTOR_ARITH `a + d % --b:complex = a - d % b`] THEN + DISCH_THEN(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC) THEN + DISCH_THEN(X_CHOOSE_THEN `e:real` STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN + `?t. t IN interval[vec 0,vec 1] /\ + (p:real^1->complex) t = a - d % basis 1` + STRIP_ASSUME_TAC THENL + [RULE_ASSUM_TAC(REWRITE_RULE[path_image; IN_IMAGE]) THEN + ASM_MESON_TAC[]; + ALL_TAC] THEN + SUBGOAL_THEN + `?q. simple_path q /\ + pathstart q:complex = a - d % basis 1 /\ + pathfinish q = a - d % basis 1 /\ + path_image q = path_image p /\ + (!z. z IN inside(path_image p) + ==> winding_number(q,z) = winding_number(p,z))` + MP_TAC THENL + [EXISTS_TAC `shiftpath t (p:real^1->complex)` THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_INTERVAL_1]) THEN + ASM_SIMP_TAC[PATHSTART_SHIFTPATH; PATHFINISH_SHIFTPATH; DROP_VEC; + SIMPLE_PATH_SHIFTPATH; PATH_IMAGE_SHIFTPATH] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC WINDING_NUMBER_SHIFTPATH THEN + ASM_SIMP_TAC[SIMPLE_PATH_IMP_PATH] THEN + ASM_MESON_TAC[INSIDE_NO_OVERLAP; IN_INTER; NOT_IN_EMPTY]; + DISCH_THEN(X_CHOOSE_THEN `q:real^1->complex` MP_TAC) THEN + REPLICATE_TAC 3 (DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + REWRITE_TAC[IMP_CONJ] THEN DISCH_THEN(SUBST_ALL_TAC o SYM) THEN + SUBGOAL_THEN + `?z. z IN inside(path_image q) /\ norm(winding_number(q,z)) = &1` + (fun th -> MESON_TAC[th]) THEN + POP_ASSUM_LIST(MP_TAC o end_itlist CONJ o rev o + filter (fun tm -> not(free_in `t:real^1` (concl tm) or + free_in `p:real^1->complex` (concl tm)))) THEN + STRIP_TAC] THEN + SUBGOAL_THEN + `?t. t IN interval[vec 0,vec 1] /\ + (q:real^1->complex) t = a + e % basis 1` + STRIP_ASSUME_TAC THENL + [RULE_ASSUM_TAC(REWRITE_RULE[path_image; IN_IMAGE]) THEN + ASM_MESON_TAC[]; + ALL_TAC] THEN + SUBGOAL_THEN `~(a - d % basis 1:complex = a + e % basis 1)` + ASSUME_TAC THENL + [REWRITE_TAC[VECTOR_ARITH + `a - d % l:complex = a + e % l <=> (e + d) % l = vec 0`] THEN + SIMP_TAC[VECTOR_MUL_EQ_0; BASIS_NONZERO; DIMINDEX_2; ARITH] THEN + ASM_REAL_ARITH_TAC; + ALL_TAC] THEN + SUBGOAL_THEN + `path_image q INTER segment[a - d % basis 1,a + e % basis 1] = + {a - d % basis 1:complex,a + e % basis 1}` + ASSUME_TAC THENL + [REWRITE_TAC[SEGMENT_CLOSED_OPEN] THEN + MATCH_MP_TAC(SET_RULE + `a IN p /\ b IN p /\ p INTER s = {} + ==> p INTER (s UNION {a,b}) = {a,b}`) THEN + CONJ_TAC THENL [ASM_MESON_TAC[PATHSTART_IN_PATH_IMAGE]; ALL_TAC] THEN + CONJ_TAC THENL [ASM_MESON_TAC[path_image; IN_IMAGE]; ALL_TAC] THEN + ASM_SIMP_TAC[PATH_IMAGE_SUBPATH_SUBSET; SIMPLE_PATH_IMP_PATH; + ENDS_IN_UNIT_INTERVAL] THEN + REWRITE_TAC[SET_RULE `s INTER t = {} <=> !x. x IN t ==> ~(x IN s)`] THEN + REWRITE_TAC[IN_SEGMENT; VECTOR_ARITH + `(&1 - u) % (a - d % l) + u % (a + e % l):complex = + a + (u * e - (&1 - u) * d) % l`] THEN + X_GEN_TAC `y:complex` THEN + DISCH_THEN(X_CHOOSE_THEN `k:real` STRIP_ASSUME_TAC o CONJUNCT2) THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC(MESON + [INSIDE_NO_OVERLAP; IN_INTER; NOT_IN_EMPTY] + `x IN inside s ==> ~(x IN s)`) THEN + ASM_CASES_TAC `&0 <= k * e - (&1 - k) * d` THENL + [ALL_TAC; + ONCE_REWRITE_TAC[VECTOR_ARITH + `a + (s - t) % l:complex = a - (t - s) % l`]] THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_SIMP_TAC[REAL_ARITH `~(&0 <= a - b) ==> &0 <= b - a`] THEN + REWRITE_TAC[REAL_ARITH `k * e - (&1 - k) * d < e <=> + &0 < (&1 - k) * (d + e)`] THEN + REWRITE_TAC[REAL_ARITH `(&1 - k) * d - k * e < d <=> + &0 < k * (d + e)`] THEN + MATCH_MP_TAC REAL_LT_MUL THEN ASM_REAL_ARITH_TAC; + ALL_TAC] THEN + MP_TAC(ISPECL + [`subpath t (vec 0) (q:real^1->complex)`; + `a:complex`; `d:real`; `e:real`] lemma2) THEN + ASM_SIMP_TAC[PATHSTART_SUBPATH; PATHFINISH_SUBPATH; + PATH_IMAGE_JOIN; PATHSTART_LINEPATH] THEN + ANTS_TAC THENL + [CONJ_TAC THENL [ALL_TAC; ASM_MESON_TAC[pathstart]] THEN + MATCH_MP_TAC SIMPLE_PATH_JOIN_LOOP THEN + ASM_REWRITE_TAC[PATHSTART_SUBPATH; PATHFINISH_SUBPATH; + PATHSTART_LINEPATH; PATHFINISH_LINEPATH] THEN + ASM_REWRITE_TAC[ARC_LINEPATH_EQ] THEN REPEAT CONJ_TAC THENL + [MATCH_MP_TAC ARC_SIMPLE_PATH_SUBPATH THEN + RULE_ASSUM_TAC(REWRITE_RULE[pathstart]) THEN + ASM_REWRITE_TAC[ENDS_IN_UNIT_INTERVAL]; + RULE_ASSUM_TAC(REWRITE_RULE[pathstart]) THEN ASM_REWRITE_TAC[]; + REWRITE_TAC[PATH_IMAGE_LINEPATH] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE + `p INTER s = {a,b} ==> p' SUBSET p ==> p' INTER s SUBSET {b,a}`)) THEN + ASM_SIMP_TAC[PATH_IMAGE_SUBPATH_SUBSET; SIMPLE_PATH_IMP_PATH; + ENDS_IN_UNIT_INTERVAL]]; + DISCH_THEN(X_CHOOSE_THEN `z:complex` STRIP_ASSUME_TAC)] THEN + MP_TAC(ISPECL + [`subpath (vec 0) t (q:real^1->complex)`; + `subpath (vec 1) t (q:real^1->complex)`; + `linepath(a - d % basis 1:complex,a + e % basis 1)`; + `a - d % basis 1:complex`; `a + e % basis 1:complex`; + `z:complex`; + `--winding_number + (subpath t (vec 0) q ++ + linepath (a - d % basis 1,a + e % basis 1),z)`] + WINDING_NUMBER_FROM_INNERPATH) THEN + ASM_REWRITE_TAC[PATHSTART_SUBPATH; PATHFINISH_SUBPATH; + PATHSTART_LINEPATH; PATHFINISH_LINEPATH] THEN + REWRITE_TAC[REVERSEPATH_SUBPATH; REVERSEPATH_LINEPATH] THEN + SUBGOAL_THEN + `path_image (subpath (vec 0) t q) UNION + path_image (subpath (vec 1) t q) :complex->bool = + path_image q` + SUBST1_TAC THENL + [FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_INTERVAL_1]) THEN + SIMP_TAC[DROP_VEC; PATH_IMAGE_SUBPATH] THEN + ONCE_REWRITE_TAC[GSYM PATH_IMAGE_REVERSEPATH] THEN + REWRITE_TAC[REVERSEPATH_SUBPATH] THEN + SIMP_TAC[DROP_VEC; PATH_IMAGE_SUBPATH] THEN STRIP_TAC THEN + REWRITE_TAC[GSYM IMAGE_UNION; PATH_IMAGE_REVERSEPATH] THEN + SUBGOAL_THEN `interval[vec 0:real^1,t] UNION interval[t,vec 1] = + interval[vec 0,vec 1]` + (fun th -> ASM_REWRITE_TAC[th; GSYM path_image]) THEN + REWRITE_TAC[EXTENSION; IN_UNION; IN_INTERVAL_1; DROP_VEC] THEN + ASM_REAL_ARITH_TAC; + ALL_TAC] THEN + ANTS_TAC THENL + [RULE_ASSUM_TAC(REWRITE_RULE[pathstart; pathfinish]) THEN + REPLICATE_TAC 2 (ASM_REWRITE_TAC[] THEN CONJ_TAC THENL + [MATCH_MP_TAC SIMPLE_PATH_SUBPATH THEN + ASM_REWRITE_TAC[ENDS_IN_UNIT_INTERVAL] THEN ASM_MESON_TAC[]; + ALL_TAC]) THEN + ASM_REWRITE_TAC[SIMPLE_PATH_LINEPATH_EQ; PATH_IMAGE_LINEPATH] THEN + REPEAT CONJ_TAC THENL + [FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_INTERVAL_1]) THEN + SIMP_TAC[DROP_VEC; PATH_IMAGE_SUBPATH] THEN + ONCE_REWRITE_TAC[GSYM PATH_IMAGE_REVERSEPATH] THEN + REWRITE_TAC[REVERSEPATH_SUBPATH] THEN + SIMP_TAC[DROP_VEC; PATH_IMAGE_SUBPATH] THEN STRIP_TAC THEN + MATCH_MP_TAC(SET_RULE + `a IN s /\ a IN t /\ b IN s /\ b IN t /\ + (!x. x IN s ==> !y. y IN t ==> x = y ==> x = a \/ x = b) + ==> s INTER t = {a,b}`) THEN + REPEAT CONJ_TAC THENL + [REWRITE_TAC[IN_IMAGE] THEN EXISTS_TAC `vec 0:real^1` THEN + ASM_REWRITE_TAC[ENDS_IN_INTERVAL; INTERVAL_EQ_EMPTY_1; DROP_VEC] THEN + ASM_REAL_ARITH_TAC; + REWRITE_TAC[IN_IMAGE] THEN EXISTS_TAC `vec 1:real^1` THEN + ASM_REWRITE_TAC[ENDS_IN_INTERVAL; INTERVAL_EQ_EMPTY_1; DROP_VEC] THEN + ASM_REAL_ARITH_TAC; + REWRITE_TAC[IN_IMAGE] THEN EXISTS_TAC `t:real^1` THEN + ASM_REWRITE_TAC[ENDS_IN_INTERVAL; INTERVAL_EQ_EMPTY_1; DROP_VEC] THEN + ASM_REAL_ARITH_TAC; + REWRITE_TAC[IN_IMAGE] THEN EXISTS_TAC `t:real^1` THEN + ASM_REWRITE_TAC[ENDS_IN_INTERVAL; INTERVAL_EQ_EMPTY_1; DROP_VEC] THEN + ASM_REAL_ARITH_TAC; + ALL_TAC] THEN + REWRITE_TAC[FORALL_IN_IMAGE; IN_INTERVAL_1; DROP_VEC] THEN + X_GEN_TAC `s:real^1` THEN STRIP_TAC THEN + X_GEN_TAC `u:real^1` THEN STRIP_TAC THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [simple_path]) THEN + DISCH_THEN(MP_TAC o SPECL [`s:real^1`; `u:real^1`] o CONJUNCT2) THEN + ASM_REWRITE_TAC[IN_INTERVAL_1; DROP_VEC] THEN + ANTS_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN + DISCH_THEN(REPEAT_TCL DISJ_CASES_THEN + (REPEAT_TCL CONJUNCTS_THEN SUBST_ALL_TAC)) THEN + ASM_REWRITE_TAC[] THEN SUBGOAL_THEN `drop u = drop t` MP_TAC THENL + [ASM_REAL_ARITH_TAC; ASM_MESON_TAC[DROP_EQ]]; + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE + `p INTER s = {a,b} + ==> a IN q /\ b IN q /\ q SUBSET p ==> q INTER s = {a,b}`)) THEN + ASM_SIMP_TAC[PATH_IMAGE_SUBPATH_SUBSET; SIMPLE_PATH_IMP_PATH; + ENDS_IN_UNIT_INTERVAL] THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_INTERVAL_1]) THEN + SIMP_TAC[DROP_VEC; PATH_IMAGE_SUBPATH] THEN STRIP_TAC THEN + REWRITE_TAC[IN_IMAGE] THEN CONJ_TAC THENL + [EXISTS_TAC `vec 0:real^1`; EXISTS_TAC `t:real^1`] THEN + ASM_REWRITE_TAC[ENDS_IN_INTERVAL; INTERVAL_EQ_EMPTY_1; DROP_VEC] THEN + ASM_REAL_ARITH_TAC; + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE + `p INTER s = {a,b} + ==> a IN q /\ b IN q /\ q SUBSET p ==> q INTER s = {a,b}`)) THEN + ASM_SIMP_TAC[PATH_IMAGE_SUBPATH_SUBSET; SIMPLE_PATH_IMP_PATH; + ENDS_IN_UNIT_INTERVAL] THEN + ONCE_REWRITE_TAC[GSYM PATH_IMAGE_REVERSEPATH] THEN + REWRITE_TAC[REVERSEPATH_SUBPATH] THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_INTERVAL_1]) THEN + SIMP_TAC[DROP_VEC; PATH_IMAGE_SUBPATH] THEN STRIP_TAC THEN + REWRITE_TAC[IN_IMAGE] THEN CONJ_TAC THENL + [EXISTS_TAC `vec 1:real^1`; EXISTS_TAC `t:real^1`] THEN + ASM_REWRITE_TAC[ENDS_IN_INTERVAL; INTERVAL_EQ_EMPTY_1; DROP_VEC] THEN + ASM_REAL_ARITH_TAC; + REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; IN_INTER] THEN + EXISTS_TAC `a:complex` THEN + ASM_REWRITE_TAC[GSYM BETWEEN_IN_SEGMENT; between] THEN + REWRITE_TAC[NORM_ARITH `dist(a - d:complex,a + e) = norm(d + e)`; + NORM_ARITH `dist(a - d:complex,a) = norm(d)`; + NORM_ARITH `dist(a:complex,a + e) = norm e`] THEN + ASM_SIMP_TAC[GSYM VECTOR_ADD_RDISTRIB; NORM_MUL; + NORM_BASIS; DIMINDEX_2; ARITH] THEN + ASM_REAL_ARITH_TAC; + ONCE_REWRITE_TAC[GSYM PATH_IMAGE_REVERSEPATH] THEN + RULE_ASSUM_TAC(REWRITE_RULE[PATH_IMAGE_LINEPATH]) THEN + ASM_REWRITE_TAC[REVERSEPATH_SUBPATH]; + W(MP_TAC o PART_MATCH (rand o rand) WINDING_NUMBER_REVERSEPATH o + rand o snd) THEN + ANTS_TAC THENL + [ASM_SIMP_TAC[PATH_JOIN_EQ; PATH_IMAGE_JOIN; PATH_LINEPATH; + SIMPLE_PATH_IMP_PATH; PATHSTART_LINEPATH; PATHFINISH_SUBPATH; + PATH_SUBPATH; ENDS_IN_UNIT_INTERVAL] THEN + ASM_MESON_TAC[INSIDE_NO_OVERLAP; IN_INTER; NOT_IN_EMPTY]; + DISCH_THEN(SUBST1_TAC o SYM) THEN + ASM_SIMP_TAC[REVERSEPATH_JOINPATHS; REVERSEPATH_LINEPATH; + REVERSEPATH_SUBPATH; PATHFINISH_SUBPATH; + PATHSTART_LINEPATH] THEN + MATCH_MP_TAC(MESON[COMPLEX_ADD_SYM] + `winding_number(g ++ h,z) = + winding_number(g,z) + winding_number(h,z) /\ + winding_number(h ++ g,z) = + winding_number(h,z) + winding_number(g,z) + ==> winding_number(g ++ h,z) =winding_number(h ++ g,z)`) THEN + CONJ_TAC THEN MATCH_MP_TAC WINDING_NUMBER_JOIN THEN + ASM_SIMP_TAC[PATH_LINEPATH; PATH_SUBPATH; PATH_SUBPATH; + SIMPLE_PATH_IMP_PATH; ENDS_IN_UNIT_INTERVAL; + PATHSTART_LINEPATH; PATHFINISH_LINEPATH; + PATHSTART_SUBPATH; PATHFINISH_SUBPATH] + THENL [ALL_TAC; ONCE_REWRITE_TAC[CONJ_SYM]] THEN + REWRITE_TAC[SET_RULE + `~(z IN s) /\ ~(z IN t) <=> ~(z IN s UNION t)`] THEN + ONCE_REWRITE_TAC[GSYM PATH_IMAGE_REVERSEPATH] THEN + REWRITE_TAC[REVERSEPATH_LINEPATH; REVERSEPATH_SUBPATH] THEN + ASM_MESON_TAC[INSIDE_NO_OVERLAP; IN_INTER; NOT_IN_EMPTY]]; + REWRITE_TAC[COMPLEX_NEG_EQ_0] THEN DISCH_THEN SUBST_ALL_TAC THEN + RULE_ASSUM_TAC(REWRITE_RULE + [COMPLEX_NORM_CX; REAL_OF_NUM_EQ; REAL_ABS_NUM; ARITH]) THEN + FIRST_X_ASSUM CONTR_TAC]; + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + ONCE_REWRITE_TAC[COMPLEX_RING `a:complex = --b <=> --a = b`] THEN + DISCH_THEN(SUBST_ALL_TAC o SYM) THEN + RULE_ASSUM_TAC(REWRITE_RULE[NORM_NEG])] THEN + EXISTS_TAC `z:complex` THEN ASM_REWRITE_TAC[] THEN + SUBGOAL_THEN + `winding_number(subpath (vec 0) t q ++ subpath t (vec 1) q,z) = + winding_number(subpath (vec 0) (vec 1) q,z)` + (fun th -> ASM_MESON_TAC[th; SUBPATH_TRIVIAL]) THEN + MATCH_MP_TAC EQ_TRANS THEN + EXISTS_TAC `winding_number(subpath (vec 0) t q,z) + + winding_number(subpath t (vec 1) q,z)` THEN + CONJ_TAC THENL + [MATCH_MP_TAC WINDING_NUMBER_JOIN THEN + ASM_SIMP_TAC[PATH_SUBPATH; ENDS_IN_UNIT_INTERVAL; SIMPLE_PATH_IMP_PATH; + PATHSTART_SUBPATH; PATHFINISH_SUBPATH] THEN + SUBGOAL_THEN `~((z:complex) IN path_image q)` MP_TAC THENL + [ASM_MESON_TAC[INSIDE_NO_OVERLAP; IN_INTER; NOT_IN_EMPTY]; + MATCH_MP_TAC(SET_RULE + `s1 SUBSET s /\ s2 SUBSET s + ==> ~(z IN s) ==> ~(z IN s1) /\ ~(z IN s2)`) THEN + ASM_SIMP_TAC[PATH_IMAGE_SUBPATH_SUBSET; ENDS_IN_UNIT_INTERVAL; + SIMPLE_PATH_IMP_PATH]]; + MATCH_MP_TAC WINDING_NUMBER_SUBPATH_COMBINE THEN + ASM_REWRITE_TAC[ENDS_IN_INTERVAL; GSYM IN_INTERVAL_1] THEN + ASM_SIMP_TAC[UNIT_INTERVAL_NONEMPTY; SIMPLE_PATH_IMP_PATH] THEN + ASM_MESON_TAC[INSIDE_NO_OVERLAP; IN_INTER; NOT_IN_EMPTY]]) in + GEN_TAC THEN DISCH_TAC THEN + ASM_CASES_TAC `pathfinish g:complex = pathstart g` THENL + [ALL_TAC; ASM_MESON_TAC[INSIDE_SIMPLE_CURVE_IMP_CLOSED]] THEN + MATCH_MP_TAC(MESON[] + `(?k. !z. z IN s ==> f z = k) /\ + (?z. z IN s /\ (f z = a \/ f z = b)) + ==> (!z. z IN s ==> f z = a) \/ (!z. z IN s ==> f z = b)`) THEN + CONJ_TAC THENL + [MATCH_MP_TAC WINDING_NUMBER_CONSTANT THEN + ASM_SIMP_TAC[INSIDE_NO_OVERLAP; SIMPLE_PATH_IMP_PATH] THEN + ASM_SIMP_TAC[JORDAN_INSIDE_OUTSIDE]; + MP_TAC(SPEC `g:real^1->complex` lemma3) THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `z:complex` THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN ASM_REWRITE_TAC[] THEN + MP_TAC(ISPECL [`g:real^1->complex`; `z:complex`] + INTEGER_WINDING_NUMBER) THEN + ANTS_TAC THENL + [ASM_SIMP_TAC[SIMPLE_PATH_IMP_PATH] THEN + ASM_MESON_TAC[INSIDE_NO_OVERLAP; IN_INTER; NOT_IN_EMPTY]; + SIMP_TAC[complex_integer; COMPLEX_EQ; IM_NEG; IM_CX] THEN + SIMP_TAC[GSYM real; REAL_NORM; RE_NEG; RE_CX] THEN REAL_ARITH_TAC]]);; + +let SIMPLE_CLOSED_PATH_ABS_WINDING_NUMBER_INSIDE = prove + (`!g z. simple_path g /\ z IN inside(path_image g) + ==> abs(Re(winding_number(g,z))) = &1`, + REPEAT STRIP_TAC THEN FIRST_ASSUM(DISJ_CASES_TAC o MATCH_MP + SIMPLE_CLOSED_PATH_WINDING_NUMBER_INSIDE) THEN + ASM_SIMP_TAC[RE_NEG; RE_CX; REAL_ABS_NUM; REAL_ABS_NEG]);; + +let SIMPLE_CLOSED_PATH_NORM_WINDING_NUMBER_INSIDE = prove + (`!g z. simple_path g /\ z IN inside(path_image g) + ==> norm(winding_number(g,z)) = &1`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN `pathfinish g:complex = pathstart g` ASSUME_TAC THENL + [ASM_MESON_TAC[INSIDE_SIMPLE_CURVE_IMP_CLOSED]; ALL_TAC] THEN + MP_TAC(ISPECL [`g:real^1->complex`; `z:complex`] + INTEGER_WINDING_NUMBER) THEN + ANTS_TAC THENL + [ASM_SIMP_TAC[SIMPLE_PATH_IMP_PATH] THEN + ASM_MESON_TAC[INSIDE_NO_OVERLAP; IN_INTER; NOT_IN_EMPTY]; + ASM_SIMP_TAC[complex_integer; GSYM real; REAL_NORM; + SIMPLE_CLOSED_PATH_ABS_WINDING_NUMBER_INSIDE]]);; + +let SIMPLE_CLOSED_PATH_WINDING_NUMBER_CASES = prove + (`!g z. simple_path g /\ pathfinish g = pathstart g /\ ~(z IN path_image g) + ==> winding_number(g,z) IN {--Cx(&1),Cx(&0),Cx(&1)}`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPEC `path_image g:complex->bool` INSIDE_UNION_OUTSIDE) THEN + REWRITE_TAC[EXTENSION; IN_DIFF; IN_UNIV; IN_UNION] THEN + DISCH_THEN(MP_TAC o SPEC `z:complex`) THEN + ASM_REWRITE_TAC[IN_INSERT; NOT_IN_EMPTY] THEN STRIP_TAC THEN + ASM_SIMP_TAC[WINDING_NUMBER_ZERO_IN_OUTSIDE; SIMPLE_PATH_IMP_PATH] THEN + ASM_MESON_TAC[SIMPLE_CLOSED_PATH_WINDING_NUMBER_INSIDE]);; + +let SIMPLE_CLOSED_PATH_WINDING_NUMBER_POS = prove + (`!g z. simple_path g /\ pathfinish g = pathstart g /\ ~(z IN path_image g) /\ + &0 < Re(winding_number(g,z)) + ==> winding_number(g,z) = Cx(&1)`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`g:real^1->complex`; `z:complex`] + SIMPLE_CLOSED_PATH_WINDING_NUMBER_CASES) THEN + ASM_REWRITE_TAC[IN_INSERT; NOT_IN_EMPTY] THEN + STRIP_TAC THEN UNDISCH_TAC `&0 < Re(winding_number(g,z))` THEN + ASM_REWRITE_TAC[RE_NEG; RE_CX] THEN REAL_ARITH_TAC);; + +let SIMPLY_CONNECTED_IMP_WINDING_NUMBER_ZERO = prove + (`!s g z. simply_connected s /\ + path g /\ path_image g SUBSET s /\ + pathfinish g = pathstart g /\ ~(z IN s) + ==> winding_number(g,z) = Cx(&0)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC EQ_TRANS THEN + EXISTS_TAC `winding_number(linepath(pathstart g,pathstart g),z)` THEN + CONJ_TAC THENL + [MATCH_MP_TAC WINDING_NUMBER_HOMOTOPIC_PATHS THEN + MATCH_MP_TAC HOMOTOPIC_LOOPS_IMP_HOMOTOPIC_PATHS_NULL THEN + EXISTS_TAC `pathstart(g:real^1->complex)` THEN + MATCH_MP_TAC HOMOTOPIC_LOOPS_SUBSET THEN + EXISTS_TAC `s:complex->bool` THEN + CONJ_TAC THENL [ALL_TAC; ASM SET_TAC[]] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o GEN_REWRITE_RULE I [simply_connected]) THEN + ASM_REWRITE_TAC[PATH_LINEPATH; PATHSTART_LINEPATH; + PATHFINISH_LINEPATH; PATH_IMAGE_LINEPATH; SEGMENT_REFL; + INSERT_SUBSET; EMPTY_SUBSET]; + MATCH_MP_TAC WINDING_NUMBER_TRIVIAL] THEN + MP_TAC(ISPEC `g:real^1->complex` PATHSTART_IN_PATH_IMAGE) THEN + ASM SET_TAC[]);; + +let NO_BOUNDED_CONNECTED_COMPONENT_IMP_WINDING_NUMBER_ZERO = prove + (`!s. ~(?z. ~(z IN s) /\ bounded(connected_component ((:complex) DIFF s) z)) + ==> !g z. path g /\ path_image g SUBSET s /\ + pathfinish g = pathstart g /\ ~(z IN s) + ==> winding_number(g,z) = Cx(&0)`, + REWRITE_TAC[NOT_EXISTS_THM] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC WINDING_NUMBER_ZERO_IN_OUTSIDE THEN + ASM_REWRITE_TAC[outside; IN_ELIM_THM] THEN + CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + FIRST_X_ASSUM(MP_TAC o SPEC `z:complex`) THEN + ASM_REWRITE_TAC[CONTRAPOS_THM] THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] BOUNDED_SUBSET) THEN + MATCH_MP_TAC CONNECTED_COMPONENT_MONO THEN ASM SET_TAC[]);; + +let NO_BOUNDED_PATH_COMPONENT_IMP_WINDING_NUMBER_ZERO = prove + (`!s. ~(?z. ~(z IN s) /\ bounded(path_component ((:complex) DIFF s) z)) + ==> !g z. path g /\ path_image g SUBSET s /\ + pathfinish g = pathstart g /\ ~(z IN s) + ==> winding_number(g,z) = Cx(&0)`, + GEN_TAC THEN DISCH_TAC THEN + MATCH_MP_TAC NO_BOUNDED_CONNECTED_COMPONENT_IMP_WINDING_NUMBER_ZERO THEN + ASM_MESON_TAC[PATH_COMPONENT_SUBSET_CONNECTED_COMPONENT; BOUNDED_SUBSET]);; + +(* ------------------------------------------------------------------------- *) +(* Partial circle path. *) +(* ------------------------------------------------------------------------- *) + +let partcirclepath = new_definition + `partcirclepath(z,r,s,t) = + \x. z + Cx(r) * cexp(ii * linepath(Cx(s),Cx(t)) x)`;; + +let PATHSTART_PARTCIRCLEPATH = prove + (`!r z s t. pathstart(partcirclepath(z,r,s,t)) = + z + Cx(r) * cexp(ii * Cx(s))`, + REWRITE_TAC[pathstart; partcirclepath; + REWRITE_RULE[pathstart] PATHSTART_LINEPATH]);; + +let PATHFINISH_PARTCIRCLEPATH = prove + (`!r z s t. pathfinish(partcirclepath(z,r,s,t)) = + z + Cx(r) * cexp(ii * Cx(t))`, + REWRITE_TAC[pathfinish; partcirclepath; + REWRITE_RULE[pathfinish] PATHFINISH_LINEPATH]);; + +let HAS_VECTOR_DERIVATIVE_PARTCIRCLEPATH = prove + (`!z r s t x. + ((partcirclepath(z,r,s,t)) has_vector_derivative + (ii * Cx(r) * (Cx t - Cx s) * cexp(ii * linepath(Cx(s),Cx(t)) x))) + (at x)`, + REWRITE_TAC[partcirclepath; linepath; COMPLEX_CMUL; CX_SUB] THEN + REPEAT GEN_TAC THEN MATCH_MP_TAC HAS_VECTOR_DERIVATIVE_REAL_COMPLEX THEN + COMPLEX_DIFF_TAC THEN CONV_TAC COMPLEX_RING);; + +let VECTOR_DERIVATIVE_PARTCIRCLEPATH = prove + (`!z r s t x. + vector_derivative (partcirclepath(z,r,s,t)) (at x) = + ii * Cx(r) * (Cx t - Cx s) * cexp(ii * linepath(Cx(s),Cx(t)) x)`, + REPEAT GEN_TAC THEN MATCH_MP_TAC VECTOR_DERIVATIVE_AT THEN + REWRITE_TAC[HAS_VECTOR_DERIVATIVE_PARTCIRCLEPATH]);; + +let VALID_PATH_PARTCIRCLEPATH = prove + (`!z r s t. valid_path(partcirclepath(z,r,s,t))`, + REPEAT GEN_TAC THEN REWRITE_TAC[valid_path] THEN + MATCH_MP_TAC DIFFERENTIABLE_ON_IMP_PIECEWISE_DIFFERENTIABLE THEN + REWRITE_TAC[differentiable_on] THEN X_GEN_TAC `x:real^1` THEN STRIP_TAC THEN + MATCH_MP_TAC DIFFERENTIABLE_AT_WITHIN THEN + REWRITE_TAC[VECTOR_DERIVATIVE_WORKS; VECTOR_DERIVATIVE_PARTCIRCLEPATH; + HAS_VECTOR_DERIVATIVE_PARTCIRCLEPATH]);; + +let PATH_PARTCIRCLEPATH = prove + (`!z r s t. path(partcirclepath(z,r,s,t))`, + SIMP_TAC[VALID_PATH_PARTCIRCLEPATH; VALID_PATH_IMP_PATH]);; + +let PATH_IMAGE_PARTCIRCLEPATH = prove + (`!z r s t. + &0 <= r /\ s <= t + ==> path_image(partcirclepath(z,r,s,t)) = + {z + Cx(r) * cexp(ii * Cx x) | s <= x /\ x <= t}`, + REPEAT STRIP_TAC THEN REWRITE_TAC[path_image; partcirclepath] THEN + REWRITE_TAC[EXTENSION; TAUT `(a <=> b) <=> (a ==> b) /\ (b ==> a)`] THEN + REWRITE_TAC[FORALL_AND_THM; FORALL_IN_IMAGE; IN_ELIM_THM] THEN + CONJ_TAC THENL + [X_GEN_TAC `x:real^1` THEN REWRITE_TAC[IN_INTERVAL_1; DROP_VEC] THEN + DISCH_TAC THEN EXISTS_TAC `(&1 - drop x) * s + drop x * t` THEN + REWRITE_TAC[linepath; CX_ADD; CX_SUB; COMPLEX_CMUL; CX_MUL] THEN + REWRITE_TAC[REAL_ARITH `s <= (&1 - x) * s + x * t <=> &0 <= x * (t - s)`; + REAL_ARITH `(&1 - x) * s + x * t <= t <=> &0 <= (&1 - x) * (t - s)`] THEN + ASM_SIMP_TAC[REAL_LE_MUL; REAL_SUB_LE]; + ALL_TAC] THEN + X_GEN_TAC `w:complex` THEN + DISCH_THEN(X_CHOOSE_THEN `x:real` STRIP_ASSUME_TAC) THEN + ASM_REWRITE_TAC[IN_IMAGE] THEN ASM_CASES_TAC `s:real < t` THENL + [EXISTS_TAC `lift((x - s) / (t - s))` THEN + ASM_SIMP_TAC[IN_INTERVAL_1; REAL_LE_LDIV_EQ; REAL_LE_RDIV_EQ; REAL_SUB_LT; + LIFT_DROP; DROP_VEC; linepath; REAL_MUL_LZERO; REAL_MUL_LID; + REAL_SUB_LE; REAL_ARITH `x - s:real <= t - s <=> x <= t`] THEN + AP_TERM_TAC THEN AP_TERM_TAC THEN AP_TERM_TAC THEN AP_TERM_TAC THEN + REWRITE_TAC[COMPLEX_CMUL; CX_SUB; CX_DIV] THEN + SUBGOAL_THEN `~(Cx(s) = Cx(t))` MP_TAC THENL + [ASM_SIMP_TAC[CX_INJ; REAL_LT_IMP_NE]; CONV_TAC COMPLEX_FIELD]; + UNDISCH_TAC `s:real <= t` THEN ASM_REWRITE_TAC[REAL_LE_LT] THEN + DISCH_THEN SUBST_ALL_TAC THEN EXISTS_TAC `vec 0:real^1` THEN + SIMP_TAC[IN_INTERVAL_1; DROP_VEC; linepath; VECTOR_MUL_LZERO; + REAL_SUB_RZERO; VECTOR_MUL_LID; VECTOR_ADD_RID; REAL_POS] THEN + AP_TERM_TAC THEN AP_TERM_TAC THEN AP_TERM_TAC THEN AP_TERM_TAC THEN + REWRITE_TAC[CX_INJ] THEN ASM_REAL_ARITH_TAC]);; + +let PATH_IMAGE_PARTCIRCLEPATH_SUBSET = prove + (`!z r s t. + &0 <= r /\ s <= t + ==> path_image(partcirclepath(z,r,s,t)) SUBSET sphere(z,r)`, + SIMP_TAC[PATH_IMAGE_PARTCIRCLEPATH] THEN + SIMP_TAC[SUBSET; IN_ELIM_THM; IN_SPHERE; LEFT_IMP_EXISTS_THM] THEN + REWRITE_TAC[NORM_ARITH `dist(z,z + a) = norm a`] THEN + REWRITE_TAC[COMPLEX_NORM_MUL; NORM_CEXP; COMPLEX_NORM_CX; + RE_MUL_II; IM_CX; REAL_NEG_0; REAL_EXP_0] THEN + REAL_ARITH_TAC);; + +let IN_PATH_IMAGE_PARTCIRCLEPATH = prove + (`!z r s t w. + &0 <= r /\ s <= t /\ w IN path_image(partcirclepath(z,r,s,t)) + ==> norm(w - z) = r`, + MP_TAC PATH_IMAGE_PARTCIRCLEPATH_SUBSET THEN + REPEAT(MATCH_MP_TAC MONO_FORALL THEN GEN_TAC) THEN + REWRITE_TAC[SUBSET; IN_SPHERE; dist; NORM_SUB] THEN SET_TAC[]);; + +let HAS_PATH_INTEGRAL_BOUND_PARTCIRCLEPATH_STRONG = prove + (`!f i z r s t B k. + FINITE k /\ + (f has_path_integral i) (partcirclepath(z,r,s,t)) /\ + &0 <= B /\ &0 < r /\ s <= t /\ + (!x. x IN path_image(partcirclepath(z,r,s,t)) DIFF k + ==> norm(f x) <= B) + ==> norm(i) <= B * r * (t - s)`, + let lemma1 = prove + (`!b w. FINITE {z | norm(z) <= b /\ cexp(z) = w}`, + REPEAT GEN_TAC THEN ASM_CASES_TAC `w = Cx(&0)` THEN + ASM_REWRITE_TAC[CEXP_NZ; SET_RULE `{x | F} = {}`; FINITE_RULES] THEN + FIRST_ASSUM(SUBST1_TAC o SYM o MATCH_MP CEXP_CLOG) THEN + REWRITE_TAC[CEXP_EQ] THEN + REWRITE_TAC[SET_RULE + `{z | P z /\ ?n. Q n /\ z = f n} = IMAGE f {n | Q n /\ P(f n)}`] THEN + MATCH_MP_TAC FINITE_IMAGE THEN + MATCH_MP_TAC FINITE_SUBSET THEN + EXISTS_TAC `{n | integer n /\ + norm(Cx (&2 * n * pi) * ii) <= b + norm(clog w)}` THEN + CONJ_TAC THENL + [ALL_TAC; SIMP_TAC[SUBSET; IN_ELIM_THM] THEN NORM_ARITH_TAC] THEN + REWRITE_TAC[COMPLEX_NORM_MUL; COMPLEX_NORM_CX; COMPLEX_NORM_II] THEN + REWRITE_TAC[REAL_MUL_RID; REAL_ABS_MUL; REAL_ABS_NUM; REAL_ABS_PI] THEN + ASM_SIMP_TAC[REAL_MUL_ASSOC; GSYM REAL_LE_RDIV_EQ; PI_POS] THEN + REWRITE_TAC[REAL_ARITH `&2 * x <= a <=> x <= a / &2`] THEN + REWRITE_TAC[GSYM REAL_BOUNDS_LE; FINITE_INTSEG]) in + let lemma2 = prove + (`!a b. ~(a = Cx(&0)) ==> FINITE {z | norm(z) <= b /\ cexp(a * z) = w}`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC FINITE_SUBSET THEN + EXISTS_TAC + `IMAGE (\z. z / a) {z | norm(z) <= b * norm(a) /\ cexp(z) = w}` THEN + SIMP_TAC[lemma1; FINITE_IMAGE] THEN ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN + REWRITE_TAC[SUBSET; IN_IMAGE; IN_ELIM_THM] THEN + ASM_SIMP_TAC[COMPLEX_FIELD `~(a = Cx(&0)) ==> (x = y / a <=> a * x = y)`; + UNWIND_THM1; COMPLEX_NORM_MUL; REAL_LE_LMUL; NORM_POS_LE]) in + REPEAT GEN_TAC THEN REWRITE_TAC[HAS_PATH_INTEGRAL] THEN STRIP_TAC THEN + MP_TAC(ASSUME `s <= t`) THEN GEN_REWRITE_TAC LAND_CONV [REAL_LE_LT] THEN + STRIP_TAC THENL + [ALL_TAC; + FIRST_X_ASSUM SUBST_ALL_TAC THEN + REPEAT(POP_ASSUM MP_TAC) THEN + REWRITE_TAC[VECTOR_DERIVATIVE_PARTCIRCLEPATH] THEN + REWRITE_TAC[COMPLEX_SUB_REFL; COMPLEX_MUL_LZERO; COMPLEX_MUL_RZERO] THEN + SIMP_TAC[GSYM COMPLEX_VEC_0; HAS_INTEGRAL_0_EQ; NORM_0] THEN + REAL_ARITH_TAC] THEN + GEN_REWRITE_TAC RAND_CONV [GSYM REAL_MUL_RID] THEN + REWRITE_TAC[GSYM CONTENT_UNIT_1] THEN MATCH_MP_TAC HAS_INTEGRAL_BOUND THEN + EXISTS_TAC `\x. if (partcirclepath(z,r,s,t) x) IN k then Cx(&0) + else f(partcirclepath(z,r,s,t) x) * + vector_derivative (partcirclepath(z,r,s,t)) (at x)` THEN + ASM_SIMP_TAC[] THEN CONJ_TAC THENL + [ASM_MESON_TAC[REAL_LE_MUL; REAL_POS; REAL_LT_IMP_LE; REAL_SUB_LE]; + ALL_TAC] THEN + CONJ_TAC THENL + [MATCH_MP_TAC HAS_INTEGRAL_SPIKE THEN + EXISTS_TAC `\x. f(partcirclepath(z,r,s,t) x) * + vector_derivative (partcirclepath(z,r,s,t)) (at x)` THEN + EXISTS_TAC `{x | x IN interval[vec 0,vec 1] /\ + (partcirclepath(z,r,s,t) x) IN k}` THEN + ASM_SIMP_TAC[IN_DIFF; IN_ELIM_THM; IMP_CONJ] THEN + MATCH_MP_TAC NEGLIGIBLE_FINITE THEN + MATCH_MP_TAC FINITE_FINITE_PREIMAGE_GENERAL THEN ASM_REWRITE_TAC[] THEN + X_GEN_TAC `y:complex` THEN DISCH_TAC THEN + REWRITE_TAC[partcirclepath] THEN + ASM_SIMP_TAC[CX_INJ; REAL_LT_IMP_NZ; COMPLEX_FIELD + `~(r = Cx(&0)) ==> (z + r * e = y <=> e = (y - z) / r)`] THEN + REWRITE_TAC[linepath; COMPLEX_CMUL] THEN + REWRITE_TAC[GSYM CX_MUL; GSYM CX_ADD] THEN + REWRITE_TAC[REAL_ARITH `(&1 - t) * x + t * y = x + t * (y - x)`] THEN + REWRITE_TAC[CX_ADD; COMPLEX_ADD_LDISTRIB; CEXP_ADD] THEN + SIMP_TAC[CEXP_NZ; COMPLEX_FIELD + `~(e = Cx(&0)) ==> (e * x = y <=> x = y / e)`] THEN + ABBREV_TAC `w = (y - z) / Cx r / cexp(ii * Cx s)` THEN + REWRITE_TAC[CX_MUL; COMPLEX_RING + `ii * Cx x * Cx(t - s) = (ii * Cx(t - s)) * Cx x`] THEN + MATCH_MP_TAC FINITE_SUBSET THEN + EXISTS_TAC + `{x | Cx(drop x) IN + {z | norm(z) <= &1 /\ cexp((ii * Cx(t - s)) * z) = w}}` THEN + CONJ_TAC THENL + [MATCH_MP_TAC FINITE_IMAGE_INJ THEN REWRITE_TAC[CX_INJ; DROP_EQ] THEN + MATCH_MP_TAC lemma2 THEN + REWRITE_TAC[COMPLEX_RING `ii * x = Cx(&0) <=> x = Cx(&0)`] THEN + ASM_SIMP_TAC[CX_INJ; REAL_SUB_0; REAL_LT_IMP_NE]; + SIMP_TAC[SUBSET; IN_ELIM_THM; IN_INTERVAL_1; DROP_VEC] THEN + SIMP_TAC[COMPLEX_NORM_CX] THEN REAL_ARITH_TAC]; + ALL_TAC] THEN + X_GEN_TAC `x:real^1` THEN DISCH_TAC THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[COMPLEX_NORM_0] THEN + ASM_SIMP_TAC[REAL_LE_MUL; REAL_LT_IMP_LE; REAL_SUB_LE] THEN + REWRITE_TAC[VECTOR_DERIVATIVE_PARTCIRCLEPATH] THEN + REWRITE_TAC[COMPLEX_NORM_MUL; COMPLEX_NORM_CX; COMPLEX_NORM_II] THEN + REWRITE_TAC[REAL_ABS_NUM; REAL_MUL_LID] THEN + REWRITE_TAC[NORM_CEXP; RE_MUL_II; IM_LINEPATH_CX] THEN + REWRITE_TAC[REAL_EXP_0; REAL_NEG_0; REAL_MUL_RID] THEN + MATCH_MP_TAC REAL_LE_MUL2 THEN REWRITE_TAC[NORM_POS_LE] THEN CONJ_TAC THENL + [FIRST_X_ASSUM MATCH_MP_TAC THEN + REWRITE_TAC[path_image] THEN ASM SET_TAC[]; + ALL_TAC] THEN + SIMP_TAC[REAL_LE_MUL; NORM_POS_LE; REAL_ABS_POS] THEN + MATCH_MP_TAC REAL_LE_MUL2 THEN + ASM_SIMP_TAC[NORM_POS_LE; GSYM CX_SUB; COMPLEX_NORM_CX] THEN + ASM_REAL_ARITH_TAC);; + +let HAS_PATH_INTEGRAL_BOUND_PARTCIRCLEPATH = prove + (`!f i z r s t B. + (f has_path_integral i) (partcirclepath(z,r,s,t)) /\ + &0 <= B /\ &0 < r /\ s <= t /\ + (!x. x IN path_image(partcirclepath(z,r,s,t)) + ==> norm(f x) <= B) + ==> norm(i) <= B * r * (t - s)`, + REPEAT STRIP_TAC THEN + MATCH_MP_TAC HAS_PATH_INTEGRAL_BOUND_PARTCIRCLEPATH_STRONG THEN + MAP_EVERY EXISTS_TAC + [`f:complex->complex`; `z:complex`; `{}:complex->bool`] THEN + ASM_REWRITE_TAC[FINITE_RULES; IN_DIFF; NOT_IN_EMPTY]);; + +let PATH_INTEGRABLE_CONTINUOUS_PARTCIRCLEPATH = prove + (`!f z r s t. f continuous_on path_image(partcirclepath(z,r,s,t)) + ==> f path_integrable_on (partcirclepath(z,r,s,t))`, + REPEAT GEN_TAC THEN REWRITE_TAC[path_integrable_on; HAS_PATH_INTEGRAL] THEN + REWRITE_TAC[VECTOR_DERIVATIVE_PARTCIRCLEPATH; GSYM integrable_on] THEN + DISCH_TAC THEN MATCH_MP_TAC INTEGRABLE_CONTINUOUS THEN + MATCH_MP_TAC CONTINUOUS_ON_COMPLEX_MUL THEN CONJ_TAC THENL + [ONCE_REWRITE_TAC[GSYM o_DEF] THEN + MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN + ASM_REWRITE_TAC[GSYM path_image; ETA_AX] THEN + MATCH_MP_TAC PIECEWISE_DIFFERENTIABLE_ON_IMP_CONTINUOUS_ON THEN + ASM_REWRITE_TAC[GSYM valid_path; VALID_PATH_PARTCIRCLEPATH]; + ALL_TAC] THEN + REWRITE_TAC[linepath] THEN + REPEAT(MATCH_MP_TAC CONTINUOUS_ON_COMPLEX_MUL THEN + REWRITE_TAC[CONTINUOUS_ON_CONST]) THEN + ONCE_REWRITE_TAC[GSYM o_DEF] THEN + MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN + REWRITE_TAC[CONTINUOUS_ON_CEXP] THEN + REPEAT(MATCH_MP_TAC CONTINUOUS_ON_COMPLEX_MUL THEN + REWRITE_TAC[CONTINUOUS_ON_CONST]) THEN + REWRITE_TAC[VECTOR_ARITH `(&1 - x) % s + x % t = s + x % (t - s)`] THEN + MATCH_MP_TAC CONTINUOUS_ON_ADD THEN REWRITE_TAC[CONTINUOUS_ON_CONST] THEN + MATCH_MP_TAC LINEAR_CONTINUOUS_ON THEN + REWRITE_TAC[linear; DROP_ADD; DROP_CMUL; CX_ADD; COMPLEX_CMUL; CX_MUL; + CX_SUB] THEN + CONV_TAC COMPLEX_RING);; + +let WINDING_NUMBER_PARTCIRCLEPATH_POS_LT = prove + (`!r z s t w. + s < t /\ norm(w - z) < r + ==> &0 < Re(winding_number(partcirclepath(z,r,s,t),w))`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC WINDING_NUMBER_POS_LT THEN + EXISTS_TAC `r * (t - s) * (r - norm(w - z:complex))` THEN + FIRST_ASSUM(MP_TAC o MATCH_MP (REAL_ARITH + `n < r ==> &0 <= n ==> &0 < r`)) THEN + REWRITE_TAC[NORM_POS_LE] THEN DISCH_TAC THEN + ASM_SIMP_TAC[REAL_LT_MUL; REAL_SUB_LT; VALID_PATH_PARTCIRCLEPATH] THEN + ASM_REWRITE_TAC[VALID_PATH_PARTCIRCLEPATH] THEN CONJ_TAC THENL + [ASM_MESON_TAC[IN_PATH_IMAGE_PARTCIRCLEPATH; REAL_LT_IMP_LE; REAL_LT_REFL]; + ALL_TAC] THEN + X_GEN_TAC `x:real^1` THEN DISCH_TAC THEN + REWRITE_TAC[VECTOR_DERIVATIVE_PARTCIRCLEPATH] THEN + REWRITE_TAC[partcirclepath] THEN + REWRITE_TAC[GSYM COMPLEX_MUL_ASSOC; IM_MUL_II; RE_MUL_CX; GSYM CX_SUB] THEN + REWRITE_TAC[CNJ_ADD; CNJ_SUB; CNJ_MUL; CNJ_CX] THEN + REWRITE_TAC[COMPLEX_RING + `c * ((z + r * c') - w):complex = r * c * c' - c * (w - z)`] THEN + REWRITE_TAC[COMPLEX_MUL_CNJ; NORM_CEXP; RE_MUL_II] THEN + REWRITE_TAC[IM_LINEPATH_CX; REAL_NEG_0; REAL_EXP_0; COMPLEX_MUL_RID; + COMPLEX_POW_2] THEN + ASM_SIMP_TAC[REAL_LE_LMUL_EQ; REAL_SUB_LT; RE_SUB; RE_CX] THEN + MATCH_MP_TAC(REAL_ARITH + `norm(x) <= norm(y) /\ abs(Re(x)) <= norm(x) + ==> r - norm(y) <= r - Re x`) THEN + REWRITE_TAC[COMPLEX_NORM_GE_RE_IM] THEN + REWRITE_TAC[COMPLEX_NORM_MUL; NORM_CEXP; RE_MUL_II; IM_LINEPATH_CX] THEN + REWRITE_TAC[REAL_EXP_0; REAL_NEG_0; REAL_MUL_LID; GSYM CNJ_SUB] THEN + REWRITE_TAC[COMPLEX_NORM_CNJ; REAL_LE_REFL]);; + +let SIMPLE_PATH_PARTCIRCLEPATH = prove + (`!z r s t. simple_path(partcirclepath(z,r,s,t)) <=> + ~(r = &0) /\ ~(s = t) /\ abs(s - t) <= &2 * pi`, + let lemma = prove + (`(!x y. (&0 <= x /\ x <= &1) /\ (&0 <= y /\ y <= &1) ==> P(abs(x - y))) <=> + (!x. &0 <= x /\ x <= &1 ==> P x)`, + MESON_TAC[REAL_ARITH `(&0 <= x /\ x <= &1) /\ (&0 <= y /\ y <= &1) + ==> &0 <= abs(x - y) /\ abs(x - y) <= &1`; + REAL_ARITH `&0 <= &0 /\ &0 <= &1`; + REAL_ARITH `(&0 <= x ==> abs(x - &0) = x)`]) in + REPEAT GEN_TAC THEN REWRITE_TAC[simple_path; PATH_PARTCIRCLEPATH] THEN + REWRITE_TAC[partcirclepath] THEN + SIMP_TAC[COMPLEX_RING `z + r * x = z + r * y <=> r * (x - y) = Cx(&0)`] THEN + REWRITE_TAC[COMPLEX_ENTIRE; CX_INJ] THEN + ASM_CASES_TAC `r = &0` THEN ASM_REWRITE_TAC[] THENL + [DISCH_THEN(MP_TAC o SPECL [`lift(&1 / &3)`; `lift(&1 / &2)`]) THEN + REWRITE_TAC[IN_INTERVAL_1; LIFT_DROP; GSYM LIFT_NUM; LIFT_EQ] THEN + CONV_TAC REAL_RAT_REDUCE_CONV; + ALL_TAC] THEN + ASM_CASES_TAC `s:real = t` THEN ASM_REWRITE_TAC[] THENL + [DISCH_THEN(MP_TAC o SPECL [`lift(&1 / &3)`; `lift(&1 / &2)`]) THEN + REWRITE_TAC[linepath; VECTOR_ARITH `(&1 - t) % x + t % x = x`] THEN + REWRITE_TAC[IN_INTERVAL_1; LIFT_DROP; GSYM LIFT_NUM; LIFT_EQ] THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN REWRITE_TAC[COMPLEX_SUB_0]; + ALL_TAC] THEN + REWRITE_TAC[COMPLEX_SUB_0; CEXP_EQ] THEN + REWRITE_TAC[COMPLEX_RING + `ii * x = ii * y + z * ii <=> ii * (x - (y + z)) = Cx(&0)`] THEN + REWRITE_TAC[COMPLEX_ENTIRE; II_NZ; LINEPATH_CX] THEN + REWRITE_TAC[GSYM CX_SUB; GSYM CX_ADD; CX_INJ] THEN + REWRITE_TAC[REAL_ARITH + `((&1 - x) * s + x * t) - (((&1 - y) * s + y * t) + z) = &0 <=> + (x - y) * (t - s) = z`] THEN + REWRITE_TAC[GSYM DROP_EQ; DROP_VEC; IN_INTERVAL_1] THEN + SIMP_TAC[REAL_ARITH + `&0 <= x /\ x <= &1 /\ &0 <= y /\ y <= &1 + ==> (x = y \/ x = &0 /\ y = &1 \/ x = &1 /\ y = &0 <=> + abs(x - y) = &0 \/ abs(x - y) = &1)`] THEN + SIMP_TAC[PI_POS; REAL_FIELD + `&0 < pi ==> (x = &2 * n * pi <=> n = x / (&2 * pi))`] THEN + REWRITE_TAC[ONCE_REWRITE_RULE[CONJ_SYM] UNWIND_THM2] THEN + ONCE_REWRITE_TAC[GSYM INTEGER_ABS] THEN + REWRITE_TAC[GSYM FORALL_DROP; REAL_ABS_MUL; REAL_ABS_DIV] THEN + REWRITE_TAC[REAL_ABS_NUM; REAL_ABS_PI] THEN + ONCE_REWRITE_TAC[TAUT `a /\ b /\ c ==> d <=> a /\ b ==> c ==> d`] THEN + REWRITE_TAC[lemma] THEN EQ_TAC THENL + [DISCH_THEN(MP_TAC o SPEC `(&2 * pi) / abs(t - s)`) THEN + ASM_SIMP_TAC[REAL_ABS_SUB; REAL_FIELD + `~(s = t) ==> x / abs(s - t) * abs(s - t) = x`] THEN + ASM_SIMP_TAC[PI_POS; INTEGER_CLOSED; REAL_FIELD + `&0 < pi ==> (&2 * pi) / (&2 * pi) = &1`] THEN + ASM_SIMP_TAC[REAL_EQ_LDIV_EQ; REAL_LE_LDIV_EQ; REAL_LE_RDIV_EQ; + GSYM REAL_ABS_NZ; REAL_SUB_0] THEN + MP_TAC PI_POS THEN REAL_ARITH_TAC; + DISCH_TAC THEN X_GEN_TAC `x:real` THEN REPEAT STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o MATCH_MP (ONCE_REWRITE_RULE[IMP_CONJ] + REAL_ABS_INTEGER_LEMMA)) THEN + SIMP_TAC[REAL_ABS_DIV; REAL_ABS_MUL; REAL_ABS_ABS; REAL_ABS_NUM; + REAL_ABS_PI] THEN + SIMP_TAC[REAL_EQ_LDIV_EQ; REAL_LE_RDIV_EQ; PI_POS; REAL_LT_MUL; + REAL_OF_NUM_LT; ARITH] THEN + ASM_CASES_TAC `x = &0` THEN ASM_REWRITE_TAC[REAL_MUL_LZERO] THEN + ASM_REWRITE_TAC[REAL_ENTIRE; REAL_MUL_LID; + REAL_ARITH `abs(t - s) = &0 <=> s = t`] THEN + DISCH_THEN(MP_TAC o MATCH_MP (REAL_ARITH + `p <= x * abs(s - t) + ==> abs(s - t) <= p ==> &1 * abs(s - t) <= x * abs(s - t)`)) THEN + ONCE_REWRITE_TAC[REAL_ABS_SUB] THEN ASM_REWRITE_TAC[] THEN + ASM_SIMP_TAC[REAL_LE_RMUL_EQ; GSYM REAL_ABS_NZ; REAL_SUB_0] THEN + ASM_REAL_ARITH_TAC]);; + +let ARC_PARTCIRCLEPATH = prove + (`!z r s t. ~(r = &0) /\ ~(s = t) /\ abs(s - t) < &2 * pi + ==> arc(partcirclepath(z,r,s,t))`, + REPEAT STRIP_TAC THEN REWRITE_TAC[arc; PATH_PARTCIRCLEPATH] THEN + REWRITE_TAC[partcirclepath] THEN + SIMP_TAC[COMPLEX_RING `z + r * x = z + r * y <=> r * (x - y) = Cx(&0)`] THEN + ASM_REWRITE_TAC[COMPLEX_ENTIRE; CX_INJ] THEN + REWRITE_TAC[COMPLEX_SUB_0; CEXP_EQ] THEN + REWRITE_TAC[COMPLEX_RING + `ii * x = ii * y + z * ii <=> ii * (x - (y + z)) = Cx(&0)`] THEN + REWRITE_TAC[COMPLEX_ENTIRE; II_NZ; LINEPATH_CX] THEN + REWRITE_TAC[GSYM CX_SUB; GSYM CX_ADD; CX_INJ] THEN + REWRITE_TAC[REAL_ARITH + `((&1 - x) * s + x * t) - (((&1 - y) * s + y * t) + z) = &0 <=> + (x - y) * (t - s) = z`] THEN + REPEAT GEN_TAC THEN DISCH_THEN(REPEAT_TCL CONJUNCTS_THEN ASSUME_TAC) THEN + FIRST_X_ASSUM(X_CHOOSE_THEN `n:real` MP_TAC) THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + ASM_CASES_TAC `n = &0` THEN + ASM_REWRITE_TAC[REAL_MUL_LZERO; REAL_MUL_RZERO; REAL_ENTIRE; REAL_SUB_0; + DROP_EQ] THEN + MP_TAC(SPEC `n:real` REAL_ABS_INTEGER_LEMMA) THEN + ASM_REWRITE_TAC[] THEN DISCH_TAC THEN + ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN DISCH_THEN(K ALL_TAC) THEN + MATCH_MP_TAC(REAL_ARITH `abs x < abs y ==> ~(x = y)`) THEN + REWRITE_TAC[REAL_ABS_MUL; REAL_ABS_NUM; REAL_ABS_PI] THEN + MATCH_MP_TAC REAL_LTE_TRANS THEN EXISTS_TAC `&1 * &2 * pi` THEN + CONJ_TAC THENL + [ALL_TAC; + ONCE_REWRITE_TAC[REAL_ARITH `&2 * n * pi = n * &2 * pi`] THEN + MATCH_MP_TAC REAL_LE_RMUL THEN ASM_REWRITE_TAC[] THEN + MP_TAC PI_POS THEN REAL_ARITH_TAC] THEN + MATCH_MP_TAC REAL_LET_TRANS THEN EXISTS_TAC `&1 * abs(t - s)` THEN + CONJ_TAC THENL + [ALL_TAC; + ASM_REWRITE_TAC[REAL_MUL_LID] THEN ASM_MESON_TAC[REAL_ABS_SUB]] THEN + MATCH_MP_TAC REAL_LE_RMUL THEN REWRITE_TAC[REAL_ABS_POS] THEN + REPEAT(FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_INTERVAL_1])) THEN + REWRITE_TAC[DROP_VEC] THEN REAL_ARITH_TAC);; + +(* ------------------------------------------------------------------------- *) +(* Special case of one complete circle. *) +(* ------------------------------------------------------------------------- *) + +let circlepath = new_definition + `circlepath(z,r) = partcirclepath(z,r,&0,&2 * pi)`;; + +let CIRCLEPATH = prove + (`circlepath(z,r) = \x. z + Cx(r) * cexp(Cx(&2) * Cx pi * ii * Cx(drop x))`, + REWRITE_TAC[circlepath; partcirclepath; linepath; COMPLEX_CMUL] THEN + REWRITE_TAC[COMPLEX_MUL_RZERO; COMPLEX_ADD_LID] THEN + REWRITE_TAC[CX_MUL; COMPLEX_MUL_AC]);; + +let PATHSTART_CIRCLEPATH = prove + (`!r z. pathstart(circlepath(z,r)) = z + Cx(r)`, + REWRITE_TAC[circlepath; PATHSTART_PARTCIRCLEPATH] THEN + REWRITE_TAC[COMPLEX_MUL_RZERO; CEXP_0; COMPLEX_MUL_RID]);; + +let PATHFINISH_CIRCLEPATH = prove + (`!r z. pathfinish(circlepath(z,r)) = z + Cx(r)`, + REWRITE_TAC[circlepath; PATHFINISH_PARTCIRCLEPATH] THEN + REWRITE_TAC[CEXP_EULER; GSYM CX_COS; GSYM CX_SIN] THEN + REWRITE_TAC[SIN_NPI; COS_NPI; REAL_POW_NEG; ARITH; REAL_POW_ONE] THEN + CONV_TAC COMPLEX_RING);; + +let HAS_VECTOR_DERIVATIVE_CIRCLEPATH = prove + (`((circlepath (z,r)) has_vector_derivative + (Cx(&2) * Cx(pi) * ii * Cx(r) * cexp(Cx(&2) * Cx pi * ii * Cx(drop x)))) + (at x)`, + REWRITE_TAC[CIRCLEPATH] THEN + MATCH_MP_TAC HAS_VECTOR_DERIVATIVE_REAL_COMPLEX THEN + COMPLEX_DIFF_TAC THEN CONV_TAC COMPLEX_RING);; + +let VECTOR_DERIVATIVE_CIRCLEPATH = prove + (`vector_derivative (circlepath (z,r)) (at x) = + Cx(&2) * Cx(pi) * ii * Cx(r) * cexp(Cx(&2) * Cx pi * ii * Cx(drop x))`, + MATCH_MP_TAC VECTOR_DERIVATIVE_AT THEN + REWRITE_TAC[HAS_VECTOR_DERIVATIVE_CIRCLEPATH]);; + +let VALID_PATH_CIRCLEPATH = prove + (`!z r. valid_path (circlepath(z,r))`, + REWRITE_TAC[circlepath; VALID_PATH_PARTCIRCLEPATH]);; + +let PATH_IMAGE_CIRCLEPATH = prove + (`!z r. &0 <= r ==> path_image (circlepath(z,r)) = sphere(z,r)`, + REPEAT STRIP_TAC THEN REWRITE_TAC[CIRCLEPATH; path_image] THEN + REWRITE_TAC[sphere; NORM_ARITH `dist(w,z) = norm(z - w)`] THEN + MATCH_MP_TAC SUBSET_ANTISYM THEN REWRITE_TAC[SUBSET; FORALL_IN_IMAGE] THEN + REWRITE_TAC[IN_ELIM_THM; COMPLEX_RING `(z + r) - z = r:complex`] THEN + REWRITE_TAC[COMPLEX_NORM_MUL; NORM_CEXP] THEN CONJ_TAC THENL + [ONCE_REWRITE_TAC[COMPLEX_RING + `Cx(&2) * p * i * z = (Cx(&2) * p * z) * i`] THEN + REWRITE_TAC[RE_MUL_II; GSYM CX_MUL; IM_CX] THEN + REWRITE_TAC[REAL_EXP_NEG; REAL_EXP_0; REAL_MUL_RID; COMPLEX_NORM_CX] THEN + POP_ASSUM MP_TAC THEN REAL_ARITH_TAC; + ALL_TAC] THEN + X_GEN_TAC `x:complex` THEN DISCH_TAC THEN ABBREV_TAC `w:complex = x - z` THEN + FIRST_X_ASSUM(SUBST1_TAC o MATCH_MP (COMPLEX_RING + `x - z = w:complex ==> x = z + w`)) THEN + REWRITE_TAC[IN_IMAGE; COMPLEX_RING `z + a = z + b:complex <=> a = b`] THEN + ASM_CASES_TAC `w = Cx(&0)` THENL + [UNDISCH_THEN `norm(w:complex) = r` (MP_TAC o SYM) THEN + ASM_REWRITE_TAC[COMPLEX_NORM_0; REAL_ABS_ZERO] THEN + DISCH_THEN SUBST1_TAC THEN REWRITE_TAC[COMPLEX_MUL_LZERO] THEN + REWRITE_TAC[MEMBER_NOT_EMPTY; INTERVAL_EQ_EMPTY_1; DROP_VEC] THEN + REWRITE_TAC[REAL_NOT_LT; REAL_POS]; + ALL_TAC] THEN + MP_TAC(SPECL [`Re(w / Cx(norm w))`; `Im(w / Cx(norm w))`] + SINCOS_TOTAL_2PI) THEN + REWRITE_TAC[GSYM COMPLEX_SQNORM] THEN + REWRITE_TAC[COMPLEX_NORM_DIV; COMPLEX_NORM_CX; REAL_ABS_NORM] THEN + ASM_SIMP_TAC[REAL_DIV_REFL; REAL_POW_ONE; COMPLEX_NORM_ZERO] THEN + DISCH_THEN(X_CHOOSE_THEN `t:real` (STRIP_ASSUME_TAC o GSYM)) THEN + EXISTS_TAC `lift(t / (&2 * pi))` THEN + ONCE_REWRITE_TAC[COMPLEX_RING + `Cx(&2) * p * i * z = i * (Cx(&2) * p * z)`] THEN + REWRITE_TAC[CEXP_EULER; LIFT_DROP; CX_DIV; CX_MUL] THEN + ASM_SIMP_TAC[CX_PI_NZ; COMPLEX_FIELD + `~(p = Cx(&0)) ==> Cx(&2) * p * t / (Cx(&2) * p) = t`] THEN + ASM_REWRITE_TAC[GSYM CX_COS; GSYM CX_SIN] THEN CONJ_TAC THENL + [REWRITE_TAC[complex_div; GSYM CX_INV] THEN + REWRITE_TAC[SIMPLE_COMPLEX_ARITH `Re(w * Cx x) = Re(w) * x`; + SIMPLE_COMPLEX_ARITH `Im(w * Cx x) = Im(w) * x`] THEN + REWRITE_TAC[COMPLEX_ADD_LDISTRIB; GSYM CX_MUL] THEN + SUBGOAL_THEN `!z:real. r * z * inv r = z` MP_TAC THENL + [SUBGOAL_THEN `~(r = &0)` MP_TAC THENL [ALL_TAC; CONV_TAC REAL_FIELD] THEN + ASM_MESON_TAC[COMPLEX_NORM_ZERO]; + ONCE_REWRITE_TAC[COMPLEX_RING `t * ii * s = ii * t * s`] THEN + SIMP_TAC[GSYM CX_MUL; GSYM COMPLEX_EXPAND]]; + REWRITE_TAC[IN_INTERVAL_1; DROP_VEC; LIFT_DROP] THEN + ASM_SIMP_TAC[REAL_LE_LDIV_EQ; REAL_LE_RDIV_EQ; REAL_LT_MUL; + PI_POS; REAL_OF_NUM_LT; ARITH] THEN + ASM_REAL_ARITH_TAC]);; + +let HAS_PATH_INTEGRAL_BOUND_CIRCLEPATH_STRONG = prove + (`!f i z r B k. + FINITE k /\ + (f has_path_integral i) (circlepath(z,r)) /\ + &0 <= B /\ &0 < r /\ + (!x. norm(x - z) = r /\ ~(x IN k) ==> norm(f x) <= B) + ==> norm(i) <= B * (&2 * pi * r)`, + REWRITE_TAC[circlepath] THEN REPEAT STRIP_TAC THEN + SUBST1_TAC(REAL_ARITH `B * (&2 * pi * r) = B * r * (&2 * pi - &0)`) THEN + MATCH_MP_TAC HAS_PATH_INTEGRAL_BOUND_PARTCIRCLEPATH_STRONG THEN + MAP_EVERY EXISTS_TAC + [`f:complex->complex`; `z:complex`; `k:complex->bool`] THEN + ASM_SIMP_TAC[REAL_LE_MUL; REAL_POS; REAL_LT_IMP_LE; PI_POS; IN_DIFF] THEN + ASM_SIMP_TAC[PATH_IMAGE_CIRCLEPATH; GSYM circlepath; REAL_LT_IMP_LE] THEN + ASM_REWRITE_TAC[IN_SPHERE; NORM_ARITH `dist(w,z) = norm(z - w)`]);; + +let HAS_PATH_INTEGRAL_BOUND_CIRCLEPATH = prove + (`!f i z r B. + (f has_path_integral i) (circlepath(z,r)) /\ + &0 <= B /\ &0 < r /\ (!x. norm(x - z) = r ==> norm(f x) <= B) + ==> norm(i) <= B * (&2 * pi * r)`, + REWRITE_TAC[circlepath] THEN REPEAT STRIP_TAC THEN + SUBST1_TAC(REAL_ARITH `B * (&2 * pi * r) = B * r * (&2 * pi - &0)`) THEN + MATCH_MP_TAC HAS_PATH_INTEGRAL_BOUND_PARTCIRCLEPATH THEN + MAP_EVERY EXISTS_TAC [`f:complex->complex`; `z:complex`] THEN + ASM_SIMP_TAC[REAL_LE_MUL; REAL_POS; REAL_LT_IMP_LE; PI_POS] THEN + ASM_SIMP_TAC[PATH_IMAGE_CIRCLEPATH; GSYM circlepath; REAL_LT_IMP_LE] THEN + ASM_REWRITE_TAC[IN_SPHERE; NORM_ARITH `dist(w,z) = norm(z - w)`]);; + +let PATH_INTEGRABLE_CONTINUOUS_CIRCLEPATH = prove + (`!f z r. f continuous_on path_image(circlepath(z,r)) + ==> f path_integrable_on (circlepath(z,r))`, + SIMP_TAC[PATH_INTEGRABLE_CONTINUOUS_PARTCIRCLEPATH; circlepath]);; + +let SIMPLE_PATH_CIRCLEPATH = prove + (`!z r. simple_path(circlepath(z,r)) <=> ~(r = &0)`, + REWRITE_TAC[circlepath; SIMPLE_PATH_PARTCIRCLEPATH] THEN + MP_TAC PI_POS THEN REAL_ARITH_TAC);; + +let WINDING_NUMBER_CIRCLEPATH = prove + (`!z r w. norm(w - z) < r ==> winding_number(circlepath(z,r),w) = Cx(&1)`, + REPEAT STRIP_TAC THEN + MATCH_MP_TAC SIMPLE_CLOSED_PATH_WINDING_NUMBER_POS THEN + REWRITE_TAC[SIMPLE_PATH_CIRCLEPATH; + PATHSTART_CIRCLEPATH; PATHFINISH_CIRCLEPATH; CONJ_ASSOC] THEN + CONJ_TAC THENL + [FIRST_X_ASSUM(MP_TAC o MATCH_MP (REAL_ARITH + `n < r ==> (&0 <= n ==> &0 <= r /\ &0 < r) /\ n < r`)) THEN + SIMP_TAC[NORM_POS_LE; PATH_IMAGE_CIRCLEPATH; IN_ELIM_THM] THEN + ASM_REWRITE_TAC[IN_SPHERE; NORM_ARITH `dist(w,z) = norm(z - w)`] THEN + REAL_ARITH_TAC; + REWRITE_TAC[circlepath] THEN + MATCH_MP_TAC WINDING_NUMBER_PARTCIRCLEPATH_POS_LT THEN + ASM_SIMP_TAC[REAL_LT_MUL; PI_POS; REAL_OF_NUM_LT; ARITH]]);; + +(* ------------------------------------------------------------------------- *) +(* Hence the Cauchy formula for points inside a circle. *) +(* ------------------------------------------------------------------------- *) + +let CAUCHY_INTEGRAL_CIRCLEPATH = prove + (`!f z r w. + f continuous_on cball(z,r) /\ + f holomorphic_on ball(z,r) /\ + w IN ball(z,r) + ==> ((\u. f(u) / (u - w)) has_path_integral + (Cx(&2) * Cx(pi) * ii * f(w))) (circlepath(z,r))`, + REPEAT STRIP_TAC THEN + MP_TAC(SPECL [`f:complex->complex`; `cball(z:complex,r)`; + `{}:complex->bool`; `circlepath(z,r)`; `w:complex`] + CAUCHY_INTEGRAL_FORMULA_WEAK) THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_BALL]) THEN + ONCE_REWRITE_TAC[DIST_SYM] THEN REWRITE_TAC[dist] THEN DISCH_TAC THEN + ASM_SIMP_TAC[WINDING_NUMBER_CIRCLEPATH; COMPLEX_MUL_LID] THEN + DISCH_THEN MATCH_MP_TAC THEN + ASM_REWRITE_TAC[VALID_PATH_CIRCLEPATH; PATHSTART_CIRCLEPATH; FINITE_RULES; + PATHFINISH_CIRCLEPATH; CONVEX_CBALL; INTERIOR_CBALL; DIFF_EMPTY] THEN + REWRITE_TAC[complex_differentiable] THEN + CONJ_TAC THENL [ASM_MESON_TAC[HOLOMORPHIC_ON_OPEN; OPEN_BALL]; ALL_TAC] THEN + FIRST_ASSUM(MP_TAC o MATCH_MP (REAL_ARITH + `n < r ==> &0 <= n ==> &0 <= r`)) THEN + SIMP_TAC[NORM_POS_LE; PATH_IMAGE_CIRCLEPATH] THEN + REWRITE_TAC[SET_RULE `s SUBSET c DELETE q <=> s SUBSET c /\ ~(q IN s)`] THEN + REWRITE_TAC[SPHERE_SUBSET_CBALL; IN_SPHERE] THEN + UNDISCH_TAC `norm(w - z:complex) < r` THEN CONV_TAC NORM_ARITH);; + +let CAUCHY_INTEGRAL_CIRCLEPATH_SIMPLE = prove + (`!f z r w. + f holomorphic_on cball(z,r) /\ w IN ball(z,r) + ==> ((\u. f(u) / (u - w)) has_path_integral + (Cx(&2) * Cx(pi) * ii * f(w))) (circlepath(z,r))`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC CAUCHY_INTEGRAL_CIRCLEPATH THEN + ASM_SIMP_TAC[HOLOMORPHIC_ON_IMP_CONTINUOUS_ON] THEN + ASM_MESON_TAC[BALL_SUBSET_CBALL; HOLOMORPHIC_ON_SUBSET]);; + +(* ------------------------------------------------------------------------- *) +(* Uniform convergence of path integral when the derivative of the path is *) +(* bounded, and in particular for the special case of a circle. *) +(* ------------------------------------------------------------------------- *) + +let PATH_INTEGRAL_UNIFORM_LIMIT = prove + (`!net f B g l. + ~(trivial_limit net) /\ valid_path g /\ + (!t. t IN interval[vec 0,vec 1] + ==> norm(vector_derivative g (at t)) <= B) /\ + eventually (\n:A. (f n) path_integrable_on g) net /\ + (!e. &0 < e + ==> eventually (\n. !x. x IN path_image g + ==> norm(f n x - l x) < e) net) + ==> l path_integrable_on g /\ + ((\n. path_integral g (f n)) --> path_integral g l) net`, + REPEAT GEN_TAC THEN STRIP_TAC THEN + MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN CONJ_TAC THENL + [REWRITE_TAC[path_integrable_on; HAS_PATH_INTEGRAL; GSYM integrable_on] THEN + MATCH_MP_TAC INTEGRABLE_UNIFORM_LIMIT THEN + X_GEN_TAC `e:real` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `e / (abs B + &1)`) THEN + ASM_SIMP_TAC[REAL_LT_DIV; REAL_ARITH `&0 < abs B + &1`] THEN + UNDISCH_TAC `eventually (\n:A. (f n) path_integrable_on g) net` THEN + REWRITE_TAC[IMP_IMP; GSYM EVENTUALLY_AND] THEN + DISCH_THEN(MP_TAC o MATCH_MP EVENTUALLY_HAPPENS) THEN + ASM_REWRITE_TAC[path_image; path_integrable_on; FORALL_IN_IMAGE] THEN + REWRITE_TAC[HAS_PATH_INTEGRAL; GSYM integrable_on] THEN + DISCH_THEN(X_CHOOSE_THEN `a:A` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `\x. f (a:A) (g x) * vector_derivative g (at x)` THEN + ASM_REWRITE_TAC[GSYM COMPLEX_SUB_RDISTRIB] THEN + X_GEN_TAC `t:real^1` THEN DISCH_TAC THEN + MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `e / (abs B + &1) * B` THEN CONJ_TAC THENL + [REWRITE_TAC[COMPLEX_NORM_MUL] THEN MATCH_MP_TAC REAL_LE_MUL2 THEN + ASM_SIMP_TAC[NORM_POS_LE] THEN ONCE_REWRITE_TAC[NORM_SUB] THEN + ASM_SIMP_TAC[REAL_LT_IMP_LE]; + REWRITE_TAC[REAL_ARITH `e / x * B <= e <=> &0 <= e * (&1 - B / x)`] THEN + MATCH_MP_TAC REAL_LE_MUL THEN + ASM_SIMP_TAC[REAL_LT_IMP_LE; REAL_SUB_LE; REAL_LE_LDIV_EQ; + REAL_ARITH `&0 < abs B + &1`] THEN + REAL_ARITH_TAC]; + ALL_TAC] THEN + DISCH_TAC THEN ONCE_REWRITE_TAC[LIM_NULL] THEN REWRITE_TAC[tendsto] THEN + X_GEN_TAC `e:real` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `e / &2 / (abs B + &1)`) THEN + ASM_SIMP_TAC[REAL_LT_DIV; REAL_ARITH `&0 < abs B + &1`; REAL_HALF] THEN + UNDISCH_TAC `eventually (\n:A. (f n) path_integrable_on g) net` THEN + REWRITE_TAC[IMP_IMP; GSYM EVENTUALLY_AND] THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] EVENTUALLY_MONO) THEN + X_GEN_TAC `a:A` THEN REWRITE_TAC[] THEN STRIP_TAC THEN + ASM_SIMP_TAC[PATH_INTEGRAL_INTEGRAL; DIST_0; GSYM INTEGRAL_SUB; + GSYM PATH_INTEGRABLE_ON; ETA_AX] THEN + MATCH_MP_TAC REAL_LET_TRANS THEN + EXISTS_TAC + `drop(integral (interval[vec 0,vec 1]) (\x:real^1. lift(e / &2)))` THEN + CONJ_TAC THENL + [MATCH_MP_TAC INTEGRAL_NORM_BOUND_INTEGRAL THEN + ASM_SIMP_TAC[INTEGRABLE_SUB; GSYM PATH_INTEGRABLE_ON; ETA_AX] THEN + REWRITE_TAC[INTEGRABLE_CONST; GSYM COMPLEX_SUB_RDISTRIB; LIFT_DROP] THEN + X_GEN_TAC `t:real^1` THEN DISCH_TAC THEN MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `e / &2 / (abs B + &1) * B` THEN CONJ_TAC THENL + [REWRITE_TAC[COMPLEX_NORM_MUL] THEN MATCH_MP_TAC REAL_LE_MUL2 THEN + ASM_SIMP_TAC[NORM_POS_LE] THEN MATCH_MP_TAC REAL_LT_IMP_LE THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN + REWRITE_TAC[IN_IMAGE; path_image] THEN ASM_MESON_TAC[]; + REWRITE_TAC[REAL_ARITH `e / x * B <= e <=> &0 <= e * (&1 - B / x)`] THEN + MATCH_MP_TAC REAL_LE_MUL THEN + ASM_SIMP_TAC[REAL_LT_IMP_LE; REAL_SUB_LE; REAL_LE_LDIV_EQ; + REAL_ARITH `&0 < abs B + &1`] THEN + ASM_REAL_ARITH_TAC]; + REWRITE_TAC[INTEGRAL_CONST; CONTENT_UNIT_1; VECTOR_MUL_LID; LIFT_DROP] THEN + ASM_REAL_ARITH_TAC]);; + +let PATH_INTEGRAL_UNIFORM_LIMIT_CIRCLEPATH = prove + (`!net f l z r. + &0 < r /\ ~(trivial_limit net) /\ + eventually (\n:A. (f n) path_integrable_on circlepath(z,r)) net /\ + (!e. &0 < e + ==> eventually (\n. !x. x IN path_image (circlepath(z,r)) + ==> norm(f n x - l x) < e) net) + ==> l path_integrable_on circlepath(z,r) /\ + ((\n. path_integral (circlepath(z,r)) (f n)) + --> path_integral (circlepath(z,r)) l) net`, + REPEAT GEN_TAC THEN STRIP_TAC THEN + MATCH_MP_TAC PATH_INTEGRAL_UNIFORM_LIMIT THEN EXISTS_TAC `&2 * pi * r` THEN + ASM_SIMP_TAC[PI_POS; REAL_LT_MUL; REAL_OF_NUM_LT; ARITH] THEN + REWRITE_TAC[VALID_PATH_CIRCLEPATH; VECTOR_DERIVATIVE_CIRCLEPATH] THEN + REWRITE_TAC[COMPLEX_NORM_MUL; COMPLEX_NORM_CX; COMPLEX_NORM_II] THEN + REWRITE_TAC[REAL_ABS_NUM; REAL_ABS_PI; REAL_MUL_LID] THEN + REWRITE_TAC[NORM_CEXP; RE_MUL_CX; RE_MUL_II; IM_CX] THEN + REWRITE_TAC[REAL_NEG_0; REAL_MUL_RZERO; REAL_EXP_0; REAL_MUL_RID] THEN + ASM_SIMP_TAC[real_abs; REAL_LE_REFL; REAL_LT_IMP_LE]);; + +(* ------------------------------------------------------------------------- *) +(* General stepping result for derivative formulas. *) +(* ------------------------------------------------------------------------- *) + +let CAUCHY_NEXT_DERIVATIVE = prove + (`!f' f g s k B. + ~(k = 0) /\ + open s /\ valid_path g /\ + (!t. t IN interval[vec 0,vec 1] + ==> norm(vector_derivative g (at t)) <= B) /\ + f' continuous_on path_image g /\ + (!w. w IN s DIFF path_image g + ==> ((\u. f'(u) / (u - w) pow k) has_path_integral f w) g) + ==> !w. w IN s DIFF path_image g + ==> (\u. f'(u) / (u - w) pow (k + 1)) path_integrable_on g /\ + (f has_complex_derivative + (Cx(&k) * path_integral g (\u. f'(u) / (u - w) pow (k + 1)))) + (at w)`, + REPEAT GEN_TAC THEN STRIP_TAC THEN X_GEN_TAC `w:complex` THEN + REWRITE_TAC[IN_DIFF] THEN STRIP_TAC THEN + MP_TAC(ISPEC `s DIFF path_image(g:real^1->complex)` + OPEN_CONTAINS_BALL) THEN + ASM_SIMP_TAC[OPEN_DIFF; CLOSED_PATH_IMAGE; VALID_PATH_IMP_PATH] THEN + DISCH_THEN(MP_TAC o SPEC `w:complex`) THEN + ASM_REWRITE_TAC[IN_DIFF] THEN + DISCH_THEN(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC) THEN + MP_TAC(ISPECL + [`at(w:complex)`; + `\u x:complex. f'(x) * (inv(x - u) pow k - inv(x - w) pow k) / + (u - w) / Cx(&k)`; + `B:real`; `g:real^1->complex`; + `\u. f'(u) / (u - w) pow (k + 1)`] + PATH_INTEGRAL_UNIFORM_LIMIT) THEN + REWRITE_TAC[] THEN ANTS_TAC THENL + [ALL_TAC; + MATCH_MP_TAC MONO_AND THEN REWRITE_TAC[] THEN + DISCH_THEN(MP_TAC o SPEC `Cx(&k)` o MATCH_MP LIM_COMPLEX_LMUL) THEN + REWRITE_TAC[HAS_COMPLEX_DERIVATIVE_AT] THEN + MATCH_MP_TAC(REWRITE_RULE[TAUT `a /\ b /\ c ==> d <=> a /\ b ==> c ==> d`] + LIM_TRANSFORM_AT) THEN + EXISTS_TAC `d:real` THEN ASM_REWRITE_TAC[] THEN X_GEN_TAC `u:complex` THEN + REWRITE_TAC[dist] THEN STRIP_TAC THEN + SUBGOAL_THEN `~(u:complex = w)` ASSUME_TAC THENL + [ASM_MESON_TAC[COMPLEX_SUB_0; COMPLEX_NORM_0; REAL_LT_REFL]; ALL_TAC] THEN + ASM_SIMP_TAC[CX_INJ; REAL_OF_NUM_EQ; COMPLEX_FIELD + `~(y = Cx(&0)) ==> (y * x = z <=> x = z / y)`] THEN + ASM_SIMP_TAC[COMPLEX_SUB_0; CX_INJ; REAL_OF_NUM_EQ; COMPLEX_SUB_LDISTRIB; + COMPLEX_FIELD `~(c = Cx(&0)) ==> (a - b) / c = a / c - b / c`] THEN + MATCH_MP_TAC PATH_INTEGRAL_UNIQUE THEN + MATCH_MP_TAC HAS_PATH_INTEGRAL_SUB THEN + REWRITE_TAC[complex_div; COMPLEX_MUL_ASSOC] THEN + REWRITE_TAC[GSYM complex_div] THEN + CONJ_TAC THEN REPEAT(MATCH_MP_TAC HAS_PATH_INTEGRAL_COMPLEX_DIV) THEN + REWRITE_TAC[GSYM complex_div; COMPLEX_POW_INV] THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o GEN_REWRITE_RULE I [SUBSET]) THEN + ASM_REWRITE_TAC[IN_BALL; dist; VECTOR_SUB_REFL; NORM_0] THEN + ASM_MESON_TAC[NORM_SUB]] THEN + ASM_REWRITE_TAC[TRIVIAL_LIMIT_AT] THEN CONJ_TAC THENL + [REWRITE_TAC[EVENTUALLY_AT] THEN EXISTS_TAC `d:real` THEN + ASM_REWRITE_TAC[] THEN X_GEN_TAC `u:complex` THEN + REWRITE_TAC[dist] THEN STRIP_TAC THEN + REWRITE_TAC[complex_div; COMPLEX_MUL_ASSOC] THEN + REPEAT(MATCH_MP_TAC PATH_INTEGRABLE_COMPLEX_RMUL) THEN + REWRITE_TAC[COMPLEX_SUB_LDISTRIB; COMPLEX_POW_INV; GSYM complex_div] THEN + MATCH_MP_TAC PATH_INTEGRABLE_SUB THEN + REWRITE_TAC[path_integrable_on] THEN CONJ_TAC THENL + [EXISTS_TAC `(f:complex->complex) u`; + EXISTS_TAC `(f:complex->complex) w`] THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o GEN_REWRITE_RULE I [SUBSET]) THEN + REWRITE_TAC[IN_BALL; dist; VECTOR_SUB_REFL; NORM_0] THEN + ASM_MESON_TAC[NORM_SUB]; + ALL_TAC] THEN + SUBGOAL_THEN + `!e. &0 < e + ==> eventually + (\n. !x. x IN path_image g + ==> norm + ((inv (x - n) pow k - inv (x - w) pow k) / + (n - w) / Cx(&k) - inv(x - w) pow (k + 1)) < + e) + (at w)` + ASSUME_TAC THENL + [ALL_TAC; + X_GEN_TAC `e:real` THEN DISCH_TAC THEN + SUBGOAL_THEN `bounded(IMAGE (f':complex->complex) (path_image g))` + MP_TAC THENL + [MATCH_MP_TAC COMPACT_IMP_BOUNDED THEN + MATCH_MP_TAC COMPACT_CONTINUOUS_IMAGE THEN + ASM_SIMP_TAC[COMPACT_VALID_PATH_IMAGE]; + ALL_TAC] THEN + REWRITE_TAC[BOUNDED_POS; FORALL_IN_IMAGE] THEN + DISCH_THEN(X_CHOOSE_THEN `C:real` STRIP_ASSUME_TAC) THEN + FIRST_X_ASSUM(MP_TAC o SPEC `e / C:real`) THEN + ASM_SIMP_TAC[REAL_LT_DIV] THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] EVENTUALLY_MONO) THEN + X_GEN_TAC `u:complex` THEN REWRITE_TAC[] THEN + MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `x:complex` THEN + DISCH_THEN(fun th -> DISCH_TAC THEN MP_TAC th) THEN + ASM_REWRITE_TAC[complex_div; GSYM COMPLEX_MUL_ASSOC] THEN + REWRITE_TAC[GSYM COMPLEX_SUB_LDISTRIB; COMPLEX_NORM_MUL] THEN + ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN ASM_SIMP_TAC[REAL_LT_RDIV_EQ] THEN + MATCH_MP_TAC(REAL_ARITH `a <= b ==> b < x ==> a < x`) THEN + REWRITE_TAC[COMPLEX_POW_INV] THEN MATCH_MP_TAC REAL_LE_LMUL THEN + ASM_SIMP_TAC[NORM_POS_LE; REAL_LT_IMP_LE]] THEN + X_GEN_TAC `e:real` THEN DISCH_TAC THEN REWRITE_TAC[EVENTUALLY_AT] THEN + EXISTS_TAC `min (d / &2) ((e * (d / &2) pow (k + 2)) / (&k + &1))` THEN + ASM_SIMP_TAC[REAL_LT_MIN; REAL_HALF; REAL_POW_LT; REAL_LT_MUL; dist; + REAL_LT_DIV; REAL_ARITH `&0 < &k + &1`] THEN + X_GEN_TAC `u:complex` THEN STRIP_TAC THEN + X_GEN_TAC `x:complex` THEN DISCH_TAC THEN + MP_TAC(ISPECL [`\n w. if n = 0 then inv(x - w) pow k + else if n = 1 then Cx(&k) / (x - w) pow (k + 1) + else (Cx(&k) * Cx(&k + &1)) / (x - w) pow (k + 2)`; + `1`; `ball(w:complex,d / &2)`; + `(&k * (&k + &1)) / (d / &2) pow (k + 2)`] + COMPLEX_TAYLOR) THEN + REWRITE_TAC[] THEN ANTS_TAC THENL + [REWRITE_TAC[CONVEX_BALL; ADD_EQ_0; ARITH] THEN CONJ_TAC THENL + [ALL_TAC; + X_GEN_TAC `v:complex` THEN REWRITE_TAC[IN_BALL; dist] THEN DISCH_TAC THEN + REWRITE_TAC[COMPLEX_NORM_MUL; COMPLEX_NORM_DIV; COMPLEX_NORM_CX]THEN + REWRITE_TAC[real_div; GSYM REAL_POW_INV; GSYM REAL_MUL_ASSOC] THEN + REWRITE_TAC[REAL_ABS_NUM; REAL_ARITH `abs(&k + &1) = &k + &1`] THEN + REPEAT(MATCH_MP_TAC REAL_LE_LMUL THEN + CONJ_TAC THENL [REAL_ARITH_TAC; ALL_TAC]) THEN + REWRITE_TAC[REAL_POW_INV] THEN MATCH_MP_TAC REAL_LE_INV2 THEN + ASM_SIMP_TAC[GSYM real_div; REAL_POW_LT; REAL_HALF] THEN + REWRITE_TAC[COMPLEX_NORM_POW] THEN MATCH_MP_TAC REAL_POW_LE2 THEN + ASM_SIMP_TAC[REAL_ARITH `&0 < d ==> &0 <= d / &2`] THEN + UNDISCH_TAC `ball(w:complex,d) SUBSET s DIFF path_image g` THEN + REWRITE_TAC[SUBSET] THEN DISCH_THEN(MP_TAC o SPEC `x:complex`) THEN + ASM_REWRITE_TAC[IN_DIFF; IN_BALL] THEN + UNDISCH_TAC `norm(w - v:complex) < d / &2` THEN + CONV_TAC NORM_ARITH] THEN + GEN_TAC THEN X_GEN_TAC `y:complex` THEN + REWRITE_TAC[IN_BALL; dist] THEN STRIP_TAC THEN + SUBGOAL_THEN `~(y:complex = x)` ASSUME_TAC THENL + [DISCH_THEN SUBST_ALL_TAC THEN + UNDISCH_TAC `ball(w:complex,d) SUBSET s DIFF path_image g` THEN + REWRITE_TAC[SUBSET] THEN DISCH_THEN(MP_TAC o SPEC `x:complex`) THEN + ASM_REWRITE_TAC[IN_DIFF; IN_BALL; dist] THEN ASM_REAL_ARITH_TAC; + ALL_TAC] THEN + FIRST_X_ASSUM(DISJ_CASES_THEN SUBST_ALL_TAC o MATCH_MP + (ARITH_RULE `i <= 1 ==> i = 0 \/ i = 1`)) THEN + REWRITE_TAC[ARITH] THEN + MATCH_MP_TAC HAS_COMPLEX_DERIVATIVE_AT_WITHIN THEN + COMPLEX_DIFF_TAC THEN + REWRITE_TAC[COMPLEX_POW_EQ_0; COMPLEX_INV_EQ_0; CONJ_ASSOC; + COMPLEX_MUL_LZERO; COMPLEX_SUB_0; ADD_EQ_0; ARITH] THEN + REWRITE_TAC[COMPLEX_SUB_LZERO; COMPLEX_NEG_NEG; complex_div] THEN + REWRITE_TAC[COMPLEX_MUL_LID; GSYM COMPLEX_MUL_ASSOC; + GSYM COMPLEX_POW_INV; GSYM COMPLEX_INV_MUL; GSYM COMPLEX_POW_ADD] THEN + ASM_SIMP_TAC[ARITH_RULE `~(k = 0) ==> k - 1 + 2 = k + 1`] THEN + REWRITE_TAC[COMPLEX_INV_INV; ADD_SUB; COMPLEX_MUL_RNEG; + COMPLEX_NEG_NEG; COMPLEX_MUL_RID; COMPLEX_POW_POW] THEN + REWRITE_TAC[GSYM COMPLEX_MUL_ASSOC; GSYM REAL_OF_NUM_ADD] THEN + AP_TERM_TAC THEN AP_TERM_TAC THEN REWRITE_TAC[COMPLEX_POW_INV] THEN + ASM_SIMP_TAC[COMPLEX_POW_EQ_0; COMPLEX_INV_EQ_0; COMPLEX_SUB_0; + COMPLEX_FIELD `~(x = Cx(&0)) /\ ~(y = Cx(&0)) + ==> (z * inv x = inv y <=> y * z = x)`] THEN + REWRITE_TAC[GSYM COMPLEX_POW_ADD] THEN AP_TERM_TAC THEN ARITH_TAC; + ALL_TAC] THEN + DISCH_THEN(MP_TAC o SPECL [`w:complex`; `u:complex`]) THEN + ASM_REWRITE_TAC[CENTRE_IN_BALL; REAL_HALF; NUMSEG_CONV `0..1`] THEN + ASM_SIMP_TAC[IN_BALL; dist; VSUM_CLAUSES; FINITE_RULES] THEN + ANTS_TAC THENL [ASM_MESON_TAC[NORM_SUB]; ALL_TAC] THEN + REWRITE_TAC[IN_INSERT; NOT_IN_EMPTY; ARITH] THEN + REWRITE_TAC[complex_pow; VECTOR_ADD_RID; ARITH; FACT] THEN + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[COMPLEX_DIV_1; COMPLEX_MUL_RID; COMPLEX_POW_1] THEN + SUBGOAL_THEN `~(u:complex = w)` ASSUME_TAC THENL + [ASM_MESON_TAC[COMPLEX_SUB_REFL; COMPLEX_NORM_0; REAL_LT_REFL]; + ALL_TAC] THEN + SUBGOAL_THEN `~(x:complex = w)` ASSUME_TAC THENL + [ASM_MESON_TAC[]; ALL_TAC] THEN + ASM_SIMP_TAC[COMPLEX_SUB_0; COMPLEX_POW_EQ_0; CX_INJ; REAL_OF_NUM_EQ; + COMPLEX_FIELD + `~(d = Cx(&0)) /\ ~(c = Cx(&0)) /\ ~(e = Cx(&0)) + ==> a - (b + c / d * e) = ((a - b) / e / c - inv d) * c * e`] THEN + REWRITE_TAC[COMPLEX_NORM_MUL; COMPLEX_NORM_CX; REAL_DIV_1] THEN + REWRITE_TAC[REAL_ABS_NUM; GSYM COMPLEX_POW_INV] THEN DISCH_TAC THEN + MATCH_MP_TAC REAL_LT_RCANCEL_IMP THEN + EXISTS_TAC `&k * norm(u - w:complex)` THEN + ASM_SIMP_TAC[REAL_LT_MUL; REAL_OF_NUM_LT; LT_NZ] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH + `n <= x ==> x < y ==> n < y`)) THEN + REWRITE_TAC[REAL_POW_2; REAL_MUL_ASSOC] THEN + ASM_SIMP_TAC[REAL_POW_2; REAL_MUL_ASSOC; REAL_LT_RMUL_EQ] THEN + GEN_REWRITE_TAC RAND_CONV [REAL_MUL_SYM] THEN + REWRITE_TAC[real_div; GSYM REAL_MUL_ASSOC] THEN + MATCH_MP_TAC REAL_LT_LMUL THEN ASM_REWRITE_TAC[REAL_OF_NUM_LT; LT_NZ] THEN + ONCE_REWRITE_TAC[REAL_ARITH `a * b * c:real = (c * a) * b`] THEN + ASM_SIMP_TAC[GSYM real_div; REAL_LT_LDIV_EQ; REAL_HALF; REAL_POW_LT] THEN + ASM_SIMP_TAC[GSYM REAL_LT_RDIV_EQ; REAL_ARITH `&0 < &k + &1`]);; + +let CAUCHY_NEXT_DERIVATIVE_CIRCLEPATH = prove + (`!f g z r k. + ~(k = 0) /\ + (f continuous_on path_image(circlepath(z,r))) /\ + (!w. w IN ball(z,r) + ==> ((\u. f(u) / (u - w) pow k) has_path_integral g w) + (circlepath(z,r))) + ==> !w. w IN ball(z,r) + ==> (\u. f(u) / (u - w) pow (k + 1)) path_integrable_on + (circlepath(z,r)) /\ + (g has_complex_derivative + (Cx(&k) * path_integral(circlepath(z,r)) + (\u. f(u) / (u - w) pow (k + 1)))) + (at w)`, + REPEAT GEN_TAC THEN STRIP_TAC THEN ASM_CASES_TAC `&0 <= r` THENL + [ALL_TAC; + GEN_TAC THEN REWRITE_TAC[IN_BALL] THEN + MATCH_MP_TAC(TAUT `~p ==> p ==> q`) THEN + UNDISCH_TAC `~(&0 <= r)` THEN CONV_TAC NORM_ARITH] THEN + MP_TAC(ISPECL + [`f:complex->complex`; `g:complex->complex`; `circlepath(z,r)`; + `ball(z:complex,r)`; `k:num`; `&2 * pi * r`] CAUCHY_NEXT_DERIVATIVE) THEN + ASM_REWRITE_TAC[OPEN_BALL; VALID_PATH_CIRCLEPATH] THEN + SUBGOAL_THEN `ball(z,r) DIFF path_image(circlepath (z,r)) = ball(z,r)` + SUBST1_TAC THENL + [REWRITE_TAC[SET_RULE `s DIFF t = s <=> !x. x IN t ==> ~(x IN s)`] THEN + ASM_SIMP_TAC[PATH_IMAGE_CIRCLEPATH; IN_SPHERE; IN_BALL; REAL_LT_REFL]; + DISCH_THEN MATCH_MP_TAC THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[VECTOR_DERIVATIVE_CIRCLEPATH] THEN + REWRITE_TAC[COMPLEX_NORM_MUL; COMPLEX_NORM_CX; COMPLEX_NORM_II] THEN + REWRITE_TAC[REAL_ABS_NUM; REAL_ABS_PI; REAL_MUL_LID] THEN + REWRITE_TAC[NORM_CEXP; RE_MUL_CX; RE_MUL_II; IM_CX] THEN + REWRITE_TAC[REAL_NEG_0; REAL_MUL_RZERO; REAL_EXP_0; REAL_MUL_RID] THEN + ASM_SIMP_TAC[real_abs; REAL_LE_REFL]]);; + +(* ------------------------------------------------------------------------- *) +(* In particular, the first derivative formula. *) +(* ------------------------------------------------------------------------- *) + +let CAUCHY_DERIVATIVE_INTEGRAL_CIRCLEPATH = prove + (`!f z r w. + f continuous_on cball(z,r) /\ + f holomorphic_on ball(z,r) /\ + w IN ball(z,r) + ==> (\u. f(u) / (u - w) pow 2) path_integrable_on circlepath(z,r) /\ + (f has_complex_derivative + (Cx(&1) / (Cx(&2) * Cx(pi) * ii) * + path_integral(circlepath(z,r)) (\u. f(u) / (u - w) pow 2))) + (at w)`, + REPEAT GEN_TAC THEN STRIP_TAC THEN + MP_TAC(SPECL [`f:complex->complex`; `\x:complex. Cx(&2) * Cx(pi) * ii * f x`; + `z:complex`; `r:real`; `1`] + CAUCHY_NEXT_DERIVATIVE_CIRCLEPATH) THEN + ASM_SIMP_TAC[COMPLEX_POW_1; ARITH; CAUCHY_INTEGRAL_CIRCLEPATH] THEN + ANTS_TAC THENL + [MATCH_MP_TAC CONTINUOUS_ON_SUBSET THEN EXISTS_TAC `cball(z:complex,r)` THEN + ASM_REWRITE_TAC[] THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_BALL]) THEN + DISCH_THEN(MP_TAC o MATCH_MP (REAL_ARITH + `n < r ==> &0 <= n ==> &0 <= r`)) THEN + SIMP_TAC[DIST_POS_LE; PATH_IMAGE_CIRCLEPATH; SPHERE_SUBSET_CBALL]; + ALL_TAC] THEN + DISCH_THEN(MP_TAC o SPEC `w:complex`) THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC MONO_AND THEN REWRITE_TAC[COMPLEX_MUL_LID] THEN + DISCH_THEN(MP_TAC o SPEC `Cx(&1) / (Cx(&2) * Cx pi * ii)` o + MATCH_MP HAS_COMPLEX_DERIVATIVE_LMUL_AT) THEN + MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN + REWRITE_TAC[FUN_EQ_THM] THEN MP_TAC CX_2PII_NZ THEN CONV_TAC COMPLEX_FIELD);; + +(* ------------------------------------------------------------------------- *) +(* Existence of all higher derivatives. *) +(* ------------------------------------------------------------------------- *) + +let HOLOMORPHIC_DERIVATIVE = prove + (`!f f' s. open s /\ (!z. z IN s ==> (f has_complex_derivative f'(z)) (at z)) + ==> f' holomorphic_on s`, + REPEAT STRIP_TAC THEN ASM_SIMP_TAC[HOLOMORPHIC_ON_OPEN] THEN + X_GEN_TAC `z:complex` THEN DISCH_TAC THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [OPEN_CONTAINS_CBALL]) THEN + DISCH_THEN(MP_TAC o SPEC `z:complex`) THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `r:real` STRIP_ASSUME_TAC) THEN + MP_TAC(SPECL [`\x. Cx(&1) / (Cx(&2) * Cx pi * ii) * f(x:complex)`; + `f':complex->complex`; `z:complex`; `r:real`; `2`] + CAUCHY_NEXT_DERIVATIVE_CIRCLEPATH) THEN + ANTS_TAC THENL [ALL_TAC; ASM_MESON_TAC[CENTRE_IN_BALL]] THEN + SUBGOAL_THEN `f holomorphic_on cball(z,r)` ASSUME_TAC THENL + [ASM_REWRITE_TAC[holomorphic_on] THEN + ASM_MESON_TAC[SUBSET; HAS_COMPLEX_DERIVATIVE_AT_WITHIN]; + ALL_TAC] THEN + REWRITE_TAC[ARITH] THEN CONJ_TAC THENL + [MATCH_MP_TAC CONTINUOUS_ON_COMPLEX_LMUL THEN + MATCH_MP_TAC CONTINUOUS_ON_SUBSET THEN EXISTS_TAC `cball(z:complex,r)` THEN + ASM_SIMP_TAC[HOLOMORPHIC_ON_IMP_CONTINUOUS_ON] THEN + ASM_SIMP_TAC[PATH_IMAGE_CIRCLEPATH; REAL_LT_IMP_LE; SPHERE_SUBSET_CBALL]; + ALL_TAC] THEN + X_GEN_TAC `w:complex` THEN DISCH_TAC THEN + MP_TAC(SPECL [`f:complex->complex`; `z:complex`; `r:real`; `w:complex`] + CAUCHY_DERIVATIVE_INTEGRAL_CIRCLEPATH) THEN + ANTS_TAC THENL + [ASM_MESON_TAC[HOLOMORPHIC_ON_IMP_CONTINUOUS_ON; HOLOMORPHIC_ON_SUBSET; + BALL_SUBSET_CBALL]; + ALL_TAC] THEN + STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o MATCH_MP HAS_PATH_INTEGRAL_INTEGRAL) THEN + DISCH_THEN(MP_TAC o SPEC `Cx(&1) / (Cx(&2) * Cx pi * ii)` o + MATCH_MP HAS_PATH_INTEGRAL_COMPLEX_LMUL) THEN + REWRITE_TAC[complex_div; GSYM COMPLEX_MUL_ASSOC] THEN + MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_TERM_TAC THEN + REWRITE_TAC[COMPLEX_MUL_ASSOC; GSYM complex_div] THEN + MATCH_MP_TAC COMPLEX_DERIVATIVE_UNIQUE_AT THEN + MAP_EVERY EXISTS_TAC [`f:complex->complex`; `w:complex`] THEN + ASM_REWRITE_TAC[GSYM COMPLEX_MUL_ASSOC] THEN + ASM_MESON_TAC[SUBSET; BALL_SUBSET_CBALL]);; + +let HOLOMORPHIC_COMPLEX_DERIVATIVE = prove + (`!f s. open s /\ f holomorphic_on s + ==> (complex_derivative f) holomorphic_on s`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC HOLOMORPHIC_DERIVATIVE THEN + EXISTS_TAC `f:complex->complex` THEN ASM_REWRITE_TAC[] THEN + ASM_MESON_TAC[HAS_COMPLEX_DERIVATIVE_DERIVATIVE; HOLOMORPHIC_ON_OPEN]);; + +let ANALYTIC_COMPLEX_DERIVATIVE = prove + (`!f s. f analytic_on s ==> (complex_derivative f) analytic_on s`, + REPEAT GEN_TAC THEN REWRITE_TAC[analytic_on] THEN DISCH_TAC THEN + X_GEN_TAC `z:complex` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `z:complex`) THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC MONO_EXISTS THEN + SIMP_TAC[HOLOMORPHIC_COMPLEX_DERIVATIVE; OPEN_BALL]);; + +let HOLOMORPHIC_HIGHER_COMPLEX_DERIVATIVE = prove + (`!f s n. open s /\ f holomorphic_on s + ==> (higher_complex_derivative n f) holomorphic_on s`, + REWRITE_TAC[RIGHT_FORALL_IMP_THM] THEN REPEAT GEN_TAC THEN STRIP_TAC THEN + INDUCT_TAC THEN + ASM_SIMP_TAC[HOLOMORPHIC_COMPLEX_DERIVATIVE; higher_complex_derivative]);; + +let ANALYTIC_HIGHER_COMPLEX_DERIVATIVE = prove + (`!f s n. f analytic_on s ==> (higher_complex_derivative n f) analytic_on s`, + REPEAT GEN_TAC THEN REWRITE_TAC[analytic_on] THEN DISCH_TAC THEN + X_GEN_TAC `z:complex` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `z:complex`) THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC MONO_EXISTS THEN + ASM_SIMP_TAC[HOLOMORPHIC_HIGHER_COMPLEX_DERIVATIVE; OPEN_BALL]);; + +let HAS_COMPLEX_DERIVATIVE_HIGHER_COMPLEX_DERIVATIVE = prove + (`!f s x n. open s /\ f holomorphic_on s /\ x IN s + ==> ((higher_complex_derivative n f) has_complex_derivative + (higher_complex_derivative (SUC n) f x)) (at x)`, + REPEAT STRIP_TAC THEN REWRITE_TAC[higher_complex_derivative] THEN + REWRITE_TAC[HAS_COMPLEX_DERIVATIVE_DIFFERENTIABLE] THEN + MATCH_MP_TAC HOLOMORPHIC_ON_IMP_DIFFERENTIABLE_AT THEN + EXISTS_TAC `s:complex->bool` THEN + ASM_SIMP_TAC[HOLOMORPHIC_HIGHER_COMPLEX_DERIVATIVE]);; + +(* ------------------------------------------------------------------------- *) +(* Morera's theorem. *) +(* ------------------------------------------------------------------------- *) + +let MORERA_LOCAL_TRIANGLE_GEN = prove + (`!f s. + (!z. z IN s + ==> ?e a. &0 < e /\ z IN ball(a,e) /\ f continuous_on ball(a,e) /\ + !b c. segment[b,c] SUBSET ball(a,e) + ==> path_integral (linepath(a,b)) f + + path_integral (linepath(b,c)) f + + path_integral (linepath(c,a)) f = Cx(&0)) + ==> f analytic_on s`, + REPEAT STRIP_TAC THEN REWRITE_TAC[analytic_on] THEN + X_GEN_TAC `z:complex` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `z:complex`) THEN + ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`e:real`; `a:complex`] THEN STRIP_TAC THEN + EXISTS_TAC `e - dist(a:complex,z)` THEN CONJ_TAC THENL + [FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_BALL]) THEN NORM_ARITH_TAC; + ALL_TAC] THEN + MATCH_MP_TAC HOLOMORPHIC_ON_SUBSET THEN EXISTS_TAC `ball(a:complex,e)` THEN + CONJ_TAC THENL + [MATCH_MP_TAC HOLOMORPHIC_DERIVATIVE THEN REWRITE_TAC[OPEN_BALL] THEN + MATCH_MP_TAC TRIANGLE_PATH_INTEGRALS_STARLIKE_PRIMITIVE THEN + EXISTS_TAC `a:complex` THEN ASM_REWRITE_TAC[CENTRE_IN_BALL; OPEN_BALL] THEN + REPEAT STRIP_TAC THEN REWRITE_TAC[SEGMENT_CONVEX_HULL] THEN + MATCH_MP_TAC HULL_MINIMAL THEN REWRITE_TAC[CONVEX_BALL] THEN + ASM_REWRITE_TAC[INSERT_SUBSET; EMPTY_SUBSET; CENTRE_IN_BALL]; + REWRITE_TAC[SUBSET; IN_BALL] THEN NORM_ARITH_TAC]);; + +let MORERA_LOCAL_TRIANGLE = prove + (`!f s. (!z. z IN s + ==> ?t. open t /\ z IN t /\ f continuous_on t /\ + !a b c. convex hull {a,b,c} SUBSET t + ==> path_integral (linepath(a,b)) f + + path_integral (linepath(b,c)) f + + path_integral (linepath(c,a)) f = Cx(&0)) + ==> f analytic_on s`, + REPEAT GEN_TAC THEN DISCH_TAC THEN + MATCH_MP_TAC MORERA_LOCAL_TRIANGLE_GEN THEN + X_GEN_TAC `z:complex` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `z:complex`) THEN + ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `t:complex->bool` THEN STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [OPEN_CONTAINS_BALL]) THEN + DISCH_THEN(MP_TAC o SPEC `z:complex`) THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `e:real` THEN STRIP_TAC THEN + EXISTS_TAC `z:complex` THEN ASM_REWRITE_TAC[CENTRE_IN_BALL] THEN + CONJ_TAC THENL [ASM_MESON_TAC[CONTINUOUS_ON_SUBSET]; ALL_TAC] THEN + MAP_EVERY X_GEN_TAC [`x:complex`; `w:complex`] THEN DISCH_TAC THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[] THEN FIRST_X_ASSUM + (MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ_ALT] SUBSET_TRANS)) THEN + MATCH_MP_TAC HULL_MINIMAL THEN REWRITE_TAC[CONVEX_BALL] THEN + ASM_REWRITE_TAC[INSERT_SUBSET; EMPTY_SUBSET; CENTRE_IN_BALL] THEN + MP_TAC(ISPECL [`x:complex`; `w:complex`] ENDS_IN_SEGMENT) THEN + ASM SET_TAC[]);; + +let MORERA_TRIANGLE = prove + (`!f s. open s /\ f continuous_on s /\ + (!a b c. convex hull {a,b,c} SUBSET s + ==> path_integral (linepath(a,b)) f + + path_integral (linepath(b,c)) f + + path_integral (linepath(c,a)) f = Cx(&0)) + ==> f analytic_on s`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC MORERA_LOCAL_TRIANGLE THEN + X_GEN_TAC `z:complex` THEN DISCH_TAC THEN EXISTS_TAC `s:complex->bool` THEN + ASM_REWRITE_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* Combining theorems for higher derivatives including Leibniz rule. *) +(* ------------------------------------------------------------------------- *) + +let HIGHER_COMPLEX_DERIVATIVE_EQ_ITER = prove + (`!n. higher_complex_derivative n = ITER n complex_derivative`, + INDUCT_TAC THEN + ASM_REWRITE_TAC [FUN_EQ_THM; ITER; higher_complex_derivative]);; + +let HIGHER_COMPLEX_DERIVATIVE_HIGHER_COMPLEX_DERIVATIVE = prove + (`!f m n. higher_complex_derivative m (higher_complex_derivative n f) = + higher_complex_derivative (m + n) f`, + REWRITE_TAC[HIGHER_COMPLEX_DERIVATIVE_EQ_ITER; ITER_ADD]);; + +let higher_complex_derivative_alt = prove + (`(!f. higher_complex_derivative 0 f = f) /\ + (!f z n. higher_complex_derivative (SUC n) f = + higher_complex_derivative n (complex_derivative f))`, + REWRITE_TAC [HIGHER_COMPLEX_DERIVATIVE_EQ_ITER; ITER_ALT]);; + +let HIGHER_COMPLEX_DERIVATIVE_LINEAR = prove + (`!c n. higher_complex_derivative n (\w. c * w) = + \z. if n = 0 then c * z else if n = 1 then c else (Cx(&0))`, + GEN_TAC THEN INDUCT_TAC THEN + ASM_REWRITE_TAC [higher_complex_derivative; NOT_SUC; SUC_INJ; ONE] THEN + STRUCT_CASES_TAC (SPEC `n:num` num_CASES) THEN + REWRITE_TAC [NOT_SUC; SUC_INJ; + COMPLEX_DERIVATIVE_LINEAR; COMPLEX_DERIVATIVE_CONST]);; + +let HIGHER_COMPLEX_DERIVATIVE_CONST = prove + (`!i c. higher_complex_derivative i (\w.c) = \w. if i=0 then c else Cx(&0)`, + INDUCT_TAC THEN ASM_REWRITE_TAC [higher_complex_derivative_alt; NOT_SUC; + COMPLEX_DERIVATIVE_CONST; FUN_EQ_THM] THEN + MESON_TAC[]);; + +let HIGHER_COMPLEX_DERIVATIVE_ID = prove + (`!z i. higher_complex_derivative i (\w.w) z = + if i = 0 then z else if i = 1 then Cx(&1) else Cx(&0)`, + GEN_TAC THEN INDUCT_TAC THEN + ASM_REWRITE_TAC [higher_complex_derivative_alt; NOT_SUC; ONE; SUC_INJ] THEN + REWRITE_TAC[COMPLEX_DERIVATIVE_ID; HIGHER_COMPLEX_DERIVATIVE_CONST; ONE]);; + +let HAS_COMPLEX_DERIVATIVE_ITER_1 = prove + (`!f n z. f z = z /\ (f has_complex_derivative Cx(&1)) (at z) + ==> (ITER n f has_complex_derivative Cx(&1)) (at z)`, + GEN_TAC THEN INDUCT_TAC THEN REPEAT STRIP_TAC THEN + REWRITE_TAC [ITER_POINTLESS; I_DEF; HAS_COMPLEX_DERIVATIVE_ID] THEN + SUBGOAL_THEN `Cx(&1) = Cx(&1) * Cx(&1)` SUBST1_TAC THENL + [REWRITE_TAC [COMPLEX_MUL_LID]; + ASM_SIMP_TAC [ITER_FIXPOINT; COMPLEX_DIFF_CHAIN_AT]]);; + +let HIGHER_COMPLEX_DERIVATIVE_NEG = prove + (`!f s n z. + open s /\ f holomorphic_on s /\ z IN s + ==> higher_complex_derivative n (\w. --(f w)) z = + --(higher_complex_derivative n f z)`, + REWRITE_TAC [IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN REPEAT GEN_TAC THEN + REPEAT DISCH_TAC THEN INDUCT_TAC THEN + REWRITE_TAC [higher_complex_derivative] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC HAS_COMPLEX_DERIVATIVE_DERIVATIVE THEN + MATCH_MP_TAC HAS_COMPLEX_DERIVATIVE_TRANSFORM_WITHIN_OPEN THEN + EXISTS_TAC `(\w. --(higher_complex_derivative n f w))` THEN + EXISTS_TAC `s:complex->bool` THEN ASM_SIMP_TAC [] THEN + MATCH_MP_TAC HAS_COMPLEX_DERIVATIVE_NEG THEN + REWRITE_TAC [ETA_AX; GSYM higher_complex_derivative] THEN + ASM_MESON_TAC [HAS_COMPLEX_DERIVATIVE_HIGHER_COMPLEX_DERIVATIVE]);; + +let HIGHER_COMPLEX_DERIVATIVE_ADD = prove + (`!f g s n z. + open s /\ f holomorphic_on s /\ g holomorphic_on s /\ z IN s ==> + higher_complex_derivative n (\w. f w + g w) z = + higher_complex_derivative n f z + higher_complex_derivative n g z`, + REWRITE_TAC [IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN REPEAT GEN_TAC THEN + REPEAT DISCH_TAC THEN INDUCT_TAC THEN + REWRITE_TAC [higher_complex_derivative] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC HAS_COMPLEX_DERIVATIVE_DERIVATIVE THEN + MATCH_MP_TAC HAS_COMPLEX_DERIVATIVE_TRANSFORM_WITHIN_OPEN THEN + EXISTS_TAC `(\w. higher_complex_derivative n f w + + higher_complex_derivative n g w)` THEN + EXISTS_TAC `s:complex->bool` THEN ASM_SIMP_TAC [] THEN + MATCH_MP_TAC HAS_COMPLEX_DERIVATIVE_ADD THEN + REWRITE_TAC [ETA_AX; GSYM higher_complex_derivative] THEN + ASM_MESON_TAC [HAS_COMPLEX_DERIVATIVE_HIGHER_COMPLEX_DERIVATIVE]);; + +let HIGHER_COMPLEX_DERIVATIVE_SUB = prove + (`!f g s n z. + open s /\ f holomorphic_on s /\ g holomorphic_on s /\ z IN s ==> + higher_complex_derivative n (\w. f w - g w) z = + higher_complex_derivative n f z - higher_complex_derivative n g z`, + REWRITE_TAC [IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN REPEAT GEN_TAC THEN + REPEAT DISCH_TAC THEN INDUCT_TAC THEN + REWRITE_TAC [higher_complex_derivative] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC HAS_COMPLEX_DERIVATIVE_DERIVATIVE THEN + MATCH_MP_TAC HAS_COMPLEX_DERIVATIVE_TRANSFORM_WITHIN_OPEN THEN + EXISTS_TAC `(\w. higher_complex_derivative n f w - + higher_complex_derivative n g w)` THEN + EXISTS_TAC `s:complex->bool` THEN ASM_SIMP_TAC [] THEN + MATCH_MP_TAC HAS_COMPLEX_DERIVATIVE_SUB THEN + REWRITE_TAC [ETA_AX; GSYM higher_complex_derivative] THEN + ASM_MESON_TAC [HAS_COMPLEX_DERIVATIVE_HIGHER_COMPLEX_DERIVATIVE]);; + +let HIGHER_COMPLEX_DERIVATIVE_MUL = prove + (`!f g s n z. + open s /\ f holomorphic_on s /\ g holomorphic_on s /\ z IN s + ==> higher_complex_derivative n (\w. f w * g w) z = + vsum (0..n) (\i. Cx(&(binom(n,i))) * + higher_complex_derivative i f z * + higher_complex_derivative (n-i) g z)`, + REWRITE_TAC [IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN REPEAT GEN_TAC THEN + REPEAT DISCH_TAC THEN INDUCT_TAC THEN + REPEAT STRIP_TAC THEN REWRITE_TAC [NUMSEG_SING; VSUM_SING; SUB] THEN + REWRITE_TAC [higher_complex_derivative; binom; COMPLEX_MUL_LID] THEN + MATCH_MP_TAC HAS_COMPLEX_DERIVATIVE_DERIVATIVE THEN + MATCH_MP_TAC HAS_COMPLEX_DERIVATIVE_TRANSFORM_WITHIN_OPEN THEN + EXISTS_TAC `\w. vsum (0..n) + (\i. Cx (&(binom (n,i))) * + higher_complex_derivative i f w * + higher_complex_derivative (n-i) g w)` THEN + EXISTS_TAC `s:complex->bool` THEN ASM_SIMP_TAC [] THEN + SUBGOAL_THEN `vsum (0..SUC n) (\i. Cx (&(binom (SUC n,i))) * + higher_complex_derivative i f z * + higher_complex_derivative (SUC n-i) g z) = + vsum (0..n) (\i. Cx (&(binom (n,i))) * + (higher_complex_derivative i f z * + higher_complex_derivative (SUC n-i) g z + + higher_complex_derivative (SUC i) f z * + higher_complex_derivative (n-i) g z))` + SUBST1_TAC THENL + [SUBGOAL_THEN + `!i. binom(SUC n,i) = binom(n,i) + if i=0 then 0 else binom(n,PRE i)` + (fun th -> REWRITE_TAC[th; GSYM REAL_OF_NUM_ADD; CX_ADD]) THENL + [INDUCT_TAC THEN REWRITE_TAC[binom; NOT_SUC; PRE; ADD_SYM; ADD_0]; + REWRITE_TAC [COMPLEX_ADD_LDISTRIB; COMPLEX_ADD_RDISTRIB]] THEN + SIMP_TAC [VSUM_ADD; FINITE_NUMSEG] THEN BINOP_TAC THENL + [REWRITE_TAC [VSUM_CLAUSES_NUMSEG; LE_0] THEN + SUBGOAL_THEN `binom(n,SUC n)=0` SUBST1_TAC THENL + [REWRITE_TAC [BINOM_EQ_0] THEN ARITH_TAC; CONV_TAC COMPLEX_RING]; + SIMP_TAC [VSUM_CLAUSES_LEFT; SPEC `SUC n` LE_0] THEN + REWRITE_TAC [COMPLEX_MUL_LZERO; COMPLEX_ADD_LID; GSYM ADD1; + VSUM_SUC; o_DEF; SUB_SUC; NOT_SUC; PRE]]; + MATCH_MP_TAC HAS_COMPLEX_DERIVATIVE_VSUM THEN + REWRITE_TAC [FINITE_NUMSEG; IN_NUMSEG] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC HAS_COMPLEX_DERIVATIVE_LMUL_AT THEN + MATCH_MP_TAC HAS_COMPLEX_DERIVATIVE_MUL_AT THEN + ASM_SIMP_TAC [ETA_AX; ARITH_RULE `i <= n ==> SUC n - i = SUC (n-i)`] THEN + ASM_MESON_TAC [HAS_COMPLEX_DERIVATIVE_HIGHER_COMPLEX_DERIVATIVE]]);; + +let HIGHER_COMPLEX_DERIVATIVE_TRANSFORM_WITHIN_OPEN = prove + (`!f g s i z. + open s /\ f holomorphic_on s /\ g holomorphic_on s /\ + (!w. w IN s ==> f w = g w) /\ z IN s + ==> higher_complex_derivative i f z = higher_complex_derivative i g z`, + REWRITE_TAC [IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN REPEAT GEN_TAC THEN + REPEAT DISCH_TAC THEN INDUCT_TAC THEN REPEAT STRIP_TAC THEN + ASM_SIMP_TAC [higher_complex_derivative] THEN + MATCH_MP_TAC COMPLEX_DERIVATIVE_TRANSFORM_WITHIN_OPEN THEN + ASM_MESON_TAC [HOLOMORPHIC_HIGHER_COMPLEX_DERIVATIVE]);; + +let HIGHER_COMPLEX_DERIVATIVE_COMPOSE_LINEAR = prove + (`!f u s t n z. + f holomorphic_on t /\ open s /\ open t /\ + (!w. w IN s ==> u * w IN t) /\ z IN s + ==> higher_complex_derivative n (\w. f (u * w)) z = + u pow n * higher_complex_derivative n f (u * z)`, + REWRITE_TAC [RIGHT_FORALL_IMP_THM; IMP_CONJ] THEN + REPEAT GEN_TAC THEN REPEAT DISCH_TAC THEN INDUCT_TAC THEN + REWRITE_TAC [higher_complex_derivative; complex_pow; COMPLEX_MUL_LID] THEN + REPEAT STRIP_TAC THEN EQ_TRANS_TAC + `complex_derivative + (\z. u pow n * higher_complex_derivative n f (u * z)) z` THENL + [MATCH_MP_TAC COMPLEX_DERIVATIVE_TRANSFORM_WITHIN_OPEN THEN + EXISTS_TAC `s:complex->bool` THEN ASM_REWRITE_TAC[] THEN CONJ_TAC THENL + [MATCH_MP_TAC HOLOMORPHIC_HIGHER_COMPLEX_DERIVATIVE THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC + (REWRITE_RULE [o_DEF] + (SPECL [`\z:complex. u * z`; `f:complex->complex`] + HOLOMORPHIC_ON_COMPOSE_GEN)) THEN + EXISTS_TAC `t:complex->bool` THEN ASM_REWRITE_TAC[] THEN MATCH_MP_TAC + (REWRITE_RULE [o_DEF] + (SPECL [`\w:complex. u:complex`; `\w:complex. w`] + HOLOMORPHIC_ON_MUL)) THEN + REWRITE_TAC [HOLOMORPHIC_ON_CONST; HOLOMORPHIC_ON_ID]; + MATCH_MP_TAC HOLOMORPHIC_ON_MUL THEN + SIMP_TAC [HOLOMORPHIC_ON_POW; HOLOMORPHIC_ON_CONST] THEN MATCH_MP_TAC + (REWRITE_RULE [o_DEF] + (SPECL [`\w. u * w`; `higher_complex_derivative f n`] + HOLOMORPHIC_ON_COMPOSE_GEN)) THEN + EXISTS_TAC `t:complex->bool` THEN ASM_REWRITE_TAC[] THEN CONJ_TAC THENL + [MATCH_MP_TAC + (REWRITE_RULE [o_DEF] + (SPECL [`\w:complex. u:complex`; `\w:complex. w`] + HOLOMORPHIC_ON_MUL)) THEN + REWRITE_TAC [HOLOMORPHIC_ON_CONST; HOLOMORPHIC_ON_ID]; + ASM_SIMP_TAC [HOLOMORPHIC_HIGHER_COMPLEX_DERIVATIVE]]]; + EQ_TRANS_TAC + `u pow n * complex_derivative + (\z. higher_complex_derivative n f (u * z)) z` THENL + [MATCH_MP_TAC COMPLEX_DERIVATIVE_LMUL THEN + MATCH_MP_TAC ANALYTIC_ON_IMP_DIFFERENTIABLE_AT THEN + EXISTS_TAC `s:complex->bool` THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC (REWRITE_RULE [o_DEF] ANALYTIC_ON_COMPOSE_GEN) THEN + EXISTS_TAC `t:complex->bool` THEN + ASM_SIMP_TAC [ANALYTIC_ON_LINEAR; ANALYTIC_HIGHER_COMPLEX_DERIVATIVE; + ANALYTIC_ON_OPEN]; + ABBREV_TAC `a = u:complex pow n` THEN + REWRITE_TAC [COMPLEX_MUL_AC; COMPLEX_EQ_MUL_LCANCEL] THEN + ASM_CASES_TAC `a = Cx(&0)` THEN ASM_REWRITE_TAC[] THEN + GEN_REWRITE_TAC RAND_CONV [COMPLEX_MUL_SYM] THEN MATCH_MP_TAC + (REWRITE_RULE [o_DEF; COMPLEX_DIFFERENTIABLE_LINEAR; + COMPLEX_DERIVATIVE_LINEAR] + (SPECL [`\w. u * w`;`higher_complex_derivative n f`] + COMPLEX_DERIVATIVE_CHAIN)) THEN + ASM_MESON_TAC [HOLOMORPHIC_ON_IMP_DIFFERENTIABLE_AT; + HOLOMORPHIC_HIGHER_COMPLEX_DERIVATIVE]]]);; + +let HIGHER_COMPLEX_DERIVATIVE_ADD_AT = prove + (`!f g n z. + f analytic_on {z} /\ g analytic_on {z} + ==> higher_complex_derivative n (\w. f w + g w) z = + higher_complex_derivative n f z + + higher_complex_derivative n g z`, + REWRITE_TAC [ANALYTIC_AT_TWO] THEN + MESON_TAC [HIGHER_COMPLEX_DERIVATIVE_ADD]);; + +let HIGHER_COMPLEX_DERIVATIVE_SUB_AT = prove + (`!f g n z. + f analytic_on {z} /\ g analytic_on {z} + ==> higher_complex_derivative n (\w. f w - g w) z = + higher_complex_derivative n f z - + higher_complex_derivative n g z`, + REWRITE_TAC [ANALYTIC_AT_TWO] THEN + MESON_TAC [HIGHER_COMPLEX_DERIVATIVE_SUB]);; + +let HIGHER_COMPLEX_DERIVATIVE_NEG_AT = prove + (`!f n z. + f analytic_on {z} + ==> higher_complex_derivative n (\w. --(f w)) z = + --(higher_complex_derivative n f z)`, + REWRITE_TAC [ANALYTIC_AT] THEN + MESON_TAC [HIGHER_COMPLEX_DERIVATIVE_NEG]);; + +let HIGHER_COMPLEX_DERIVATIVE_MUL_AT = prove + (`!f g n z. + f analytic_on {z} /\ g analytic_on {z} + ==> higher_complex_derivative n (\w. f w * g w) z = + vsum (0..n) (\i. Cx(&(binom(n,i))) * + higher_complex_derivative i f z * + higher_complex_derivative (n-i) g z)`, + REWRITE_TAC [ANALYTIC_AT_TWO] THEN + MESON_TAC [HIGHER_COMPLEX_DERIVATIVE_MUL]);; + +(* ------------------------------------------------------------------------- *) +(* Nonexistence of isolated singularities and a stronger integral formula. *) +(* ------------------------------------------------------------------------- *) + +let NO_ISOLATED_SINGULARITY = prove + (`!f s k. open s /\ FINITE k /\ + f continuous_on s /\ f holomorphic_on (s DIFF k) + ==> f holomorphic_on s`, + REPEAT GEN_TAC THEN + SIMP_TAC[HOLOMORPHIC_ON_OPEN; OPEN_DIFF; FINITE_IMP_CLOSED; IMP_CONJ] THEN + REWRITE_TAC[GSYM complex_differentiable] THEN REPEAT DISCH_TAC THEN + X_GEN_TAC `z:complex` THEN DISCH_TAC THEN + ASM_CASES_TAC `(z:complex) IN k` THEN ASM_SIMP_TAC[IN_DIFF] THEN + MP_TAC(ISPECL [`z:complex`; `k:complex->bool`] FINITE_SET_AVOID) THEN + ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN X_GEN_TAC `d:real` THEN + STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [OPEN_CONTAINS_BALL]) THEN + DISCH_THEN(MP_TAC o SPEC `z:complex`) THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `e:real` STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN `f holomorphic_on ball(z,min d e)` MP_TAC THENL + [ALL_TAC; + ASM_SIMP_TAC[HOLOMORPHIC_ON_OPEN; OPEN_BALL; CENTRE_IN_BALL; REAL_LT_MIN; + complex_differentiable]] THEN + SUBGOAL_THEN + `?g. !w. w IN ball(z,min d e) + ==> (g has_complex_derivative f w) (at w within ball(z,min d e))` + MP_TAC THENL + [ALL_TAC; + SIMP_TAC[HAS_COMPLEX_DERIVATIVE_WITHIN_OPEN; OPEN_BALL] THEN + MESON_TAC[HOLOMORPHIC_DERIVATIVE; OPEN_BALL]] THEN + MATCH_MP_TAC PATHINTEGRAL_CONVEX_PRIMITIVE THEN + REWRITE_TAC[CONVEX_BALL] THEN CONJ_TAC THENL + [MATCH_MP_TAC CONTINUOUS_ON_SUBSET THEN EXISTS_TAC `s:complex->bool` THEN + ASM_REWRITE_TAC[] THEN FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP + (SET_RULE `b SUBSET s ==> c SUBSET b ==> c SUBSET s`)) THEN + REWRITE_TAC[SUBSET; IN_BALL] THEN REAL_ARITH_TAC; + ALL_TAC] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC CAUCHY_THEOREM_TRIANGLE_COFINITE THEN + EXISTS_TAC `k:complex->bool` THEN ASM_REWRITE_TAC[] THEN CONJ_TAC THENL + [MATCH_MP_TAC CONTINUOUS_ON_SUBSET THEN EXISTS_TAC `s:complex->bool` THEN + ASM_REWRITE_TAC[]; + X_GEN_TAC `w:complex` THEN + DISCH_THEN(fun th -> FIRST_X_ASSUM MATCH_MP_TAC THEN MP_TAC th) THEN + SPEC_TAC(`w:complex`,`w:complex`) THEN ASM_REWRITE_TAC[GSYM SUBSET] THEN + MATCH_MP_TAC(SET_RULE `s SUBSET t ==> (s DIFF k) SUBSET (t DIFF k)`) THEN + MATCH_MP_TAC(SET_RULE + `interior s SUBSET s /\ s SUBSET t ==> interior s SUBSET t`) THEN + REWRITE_TAC[INTERIOR_SUBSET]] THEN + (MATCH_MP_TAC SUBSET_TRANS THEN EXISTS_TAC `ball(z:complex,e)` THEN + ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC SUBSET_TRANS THEN EXISTS_TAC `ball(z:complex,min d e)` THEN + CONJ_TAC THENL + [MATCH_MP_TAC HULL_MINIMAL THEN REWRITE_TAC[CONVEX_BALL] THEN + ASM SET_TAC[]; + REWRITE_TAC[SUBSET; IN_BALL] THEN REAL_ARITH_TAC]));; + +let CAUCHY_INTEGRAL_FORMULA_CONVEX = prove + (`!f s k g z. + convex s /\ FINITE k /\ f continuous_on s /\ + (!x. x IN interior(s) DIFF k ==> f complex_differentiable at x) /\ + z IN interior(s) /\ + valid_path g /\ (path_image g) SUBSET (s DELETE z) /\ + pathfinish g = pathstart g + ==> ((\w. f(w) / (w - z)) has_path_integral + (Cx(&2) * Cx(pi) * ii * winding_number(g,z) * f(z))) g`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC CAUCHY_INTEGRAL_FORMULA_WEAK THEN + MAP_EVERY EXISTS_TAC [`s:complex->bool`; `{}:complex->bool`] THEN + ASM_REWRITE_TAC[DIFF_EMPTY; FINITE_RULES] THEN + SIMP_TAC[GSYM HOLOMORPHIC_ON_OPEN; complex_differentiable; OPEN_INTERIOR] THEN + MATCH_MP_TAC NO_ISOLATED_SINGULARITY THEN + EXISTS_TAC `k:complex->bool` THEN + ASM_REWRITE_TAC[OPEN_INTERIOR] THEN CONJ_TAC THENL + [MATCH_MP_TAC CONTINUOUS_ON_SUBSET THEN EXISTS_TAC `s:complex->bool` THEN + ASM_REWRITE_TAC[INTERIOR_SUBSET]; + ASM_SIMP_TAC[HOLOMORPHIC_ON_OPEN; OPEN_DIFF; FINITE_IMP_CLOSED; + OPEN_INTERIOR; GSYM complex_differentiable]]);; + +(* ------------------------------------------------------------------------- *) +(* Formula for higher derivatives. *) +(* ------------------------------------------------------------------------- *) + +let CAUCHY_HAS_PATH_INTEGRAL_HIGHER_DERIVATIVE_CIRCLEPATH = prove + (`!f z r k w. + f continuous_on cball(z,r) /\ + f holomorphic_on ball(z,r) /\ + w IN ball(z,r) + ==> ((\u. f(u) / (u - w) pow (k + 1)) + has_path_integral + ((Cx(&2) * Cx(pi) * ii) / Cx(&(FACT k)) * + higher_complex_derivative k f w)) + (circlepath(z,r))`, + REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN + REPEAT GEN_TAC THEN DISCH_TAC THEN DISCH_TAC THEN + ASM_CASES_TAC `&0 < r` THENL + [ALL_TAC; + REWRITE_TAC[IN_BALL] THEN + ASM_MESON_TAC[NORM_ARITH `~(&0 < r) ==> ~(dist(a,b) < r)`]] THEN + INDUCT_TAC THEN REWRITE_TAC[higher_complex_derivative] THENL + [REWRITE_TAC[ARITH; COMPLEX_POW_1; FACT; COMPLEX_DIV_1] THEN + ASM_SIMP_TAC[GSYM COMPLEX_MUL_ASSOC; CAUCHY_INTEGRAL_CIRCLEPATH]; + ALL_TAC] THEN + MP_TAC(SPECL + [`f:complex->complex`; + `\x. (Cx(&2) * Cx(pi) * ii) / Cx(&(FACT k)) * + higher_complex_derivative k f x`; + `z:complex`; `r:real`; `k + 1`] CAUCHY_NEXT_DERIVATIVE_CIRCLEPATH) THEN + ASM_REWRITE_TAC[ADD1; ARITH_RULE `(k + 1) + 1 = k + 2`] THEN ANTS_TAC THENL + [REWRITE_TAC[ADD_EQ_0; ARITH_EQ] THEN + MATCH_MP_TAC CONTINUOUS_ON_SUBSET THEN + EXISTS_TAC `cball(z:complex,r)` THEN ASM_REWRITE_TAC[] THEN + ASM_SIMP_TAC[PATH_IMAGE_CIRCLEPATH; REAL_LT_IMP_LE; SPHERE_SUBSET_CBALL]; + ALL_TAC] THEN + DISCH_THEN(fun th -> + X_GEN_TAC `w:complex` THEN DISCH_TAC THEN MP_TAC(SPEC `w:complex` th)) THEN + ASM_REWRITE_TAC[] THEN DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN + REWRITE_TAC[path_integrable_on; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `y:complex` THEN + DISCH_THEN(fun th -> ASSUME_TAC th THEN MP_TAC th) THEN + MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_TERM_TAC THEN + MATCH_MP_TAC(COMPLEX_FIELD + `~(a = Cx(&0)) /\ ~(b = Cx(&0)) /\ x = b / a * y ==> y = a / b * x`) THEN + REWRITE_TAC[CX_2PII_NZ; CX_INJ; REAL_OF_NUM_EQ; FACT_NZ] THEN + MATCH_MP_TAC HAS_COMPLEX_DERIVATIVE_DERIVATIVE THEN + FIRST_ASSUM(MP_TAC o MATCH_MP HAS_COMPLEX_DERIVATIVE_LMUL_AT) THEN + DISCH_THEN(MP_TAC o SPEC `Cx(&(FACT k)) / (Cx(&2) * Cx pi * ii)`) THEN + REWRITE_TAC[] THEN MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN BINOP_TAC THENL + [REWRITE_TAC[FUN_EQ_THM] THEN GEN_TAC THEN + MATCH_MP_TAC(COMPLEX_FIELD + `~(a = Cx(&0)) /\ ~(b = Cx(&0)) ==> (a / b) * (b / a) * x = x`) THEN + REWRITE_TAC[CX_2PII_NZ; CX_INJ; REAL_OF_NUM_EQ; FACT_NZ]; + REWRITE_TAC[FACT; GSYM REAL_OF_NUM_MUL; GSYM ADD1; CX_MUL] THEN + MATCH_MP_TAC(COMPLEX_FIELD + `z:complex = y /\ ~(d = Cx(&0)) + ==> k / d * k1 * z = (k1 * k) / d * y`) THEN + REWRITE_TAC[CX_2PII_NZ] THEN MATCH_MP_TAC PATH_INTEGRAL_UNIQUE THEN + ASM_REWRITE_TAC[]]);; + +let CAUCHY_HIGHER_DERIVATIVE_INTEGRAL_CIRCLEPATH = prove + (`!f z r k w. + f continuous_on cball(z,r) /\ + f holomorphic_on ball(z,r) /\ + w IN ball(z,r) + ==> (\u. f(u) / (u - w) pow (k + 1)) + path_integrable_on circlepath(z,r) /\ + higher_complex_derivative k f w = + Cx(&(FACT k)) / (Cx(&2) * Cx(pi) * ii) * + path_integral(circlepath(z,r)) (\u. f(u) / (u - w) pow (k + 1))`, + REPEAT GEN_TAC THEN DISCH_TAC THEN + FIRST_ASSUM(STRIP_ASSUME_TAC o MATCH_MP + CAUCHY_HAS_PATH_INTEGRAL_HIGHER_DERIVATIVE_CIRCLEPATH) THEN + CONJ_TAC THENL [ASM_MESON_TAC[path_integrable_on]; ALL_TAC] THEN + MATCH_MP_TAC(COMPLEX_FIELD + `~(a = Cx(&0)) /\ ~(b = Cx(&0)) /\ x = b / a * y ==> y = a / b * x`) THEN + REWRITE_TAC[CX_2PII_NZ; CX_INJ; REAL_OF_NUM_EQ; FACT_NZ] THEN + MATCH_MP_TAC PATH_INTEGRAL_UNIQUE THEN ASM_REWRITE_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* A holomorphic function is analytic, i.e. has local power series. *) +(* ------------------------------------------------------------------------- *) + +let HOLOMORPHIC_POWER_SERIES = prove + (`!f z w r. + f holomorphic_on ball(z,r) /\ w IN ball(z,r) + ==> ((\n. higher_complex_derivative n f z / Cx(&(FACT n)) * (w - z) pow n) + sums f(w)) (from 0)`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN + `?r. &0 < r /\ f holomorphic_on cball(z,r) /\ w IN ball(z,r)` + MP_TAC THENL + [EXISTS_TAC `(r + dist(w:complex,z)) / &2` THEN REPEAT CONJ_TAC THENL + [ALL_TAC; + MATCH_MP_TAC HOLOMORPHIC_ON_SUBSET THEN + EXISTS_TAC `ball(z:complex,r)` THEN ASM_REWRITE_TAC[SUBSET]; + ALL_TAC] THEN + UNDISCH_TAC `(w:complex) IN ball(z,r)` THEN + REWRITE_TAC[IN_BALL; IN_CBALL] THEN NORM_ARITH_TAC; + ALL_TAC] THEN + POP_ASSUM_LIST(K ALL_TAC) THEN + DISCH_THEN(X_CHOOSE_THEN `r:real` STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN `f holomorphic_on ball(z,r) /\ f continuous_on cball(z,r)` + STRIP_ASSUME_TAC THENL + [ASM_SIMP_TAC[HOLOMORPHIC_ON_IMP_CONTINUOUS_ON] THEN + MATCH_MP_TAC HOLOMORPHIC_ON_SUBSET THEN ASM_MESON_TAC[BALL_SUBSET_CBALL]; + ALL_TAC] THEN + SUBGOAL_THEN + `((\k. path_integral (circlepath(z,r)) (\u. f u / (u - z) pow (k + 1)) * + (w - z) pow k) + sums path_integral (circlepath(z,r)) (\u. f u / (u - w))) (from 0)` + MP_TAC THENL + [ALL_TAC; + DISCH_THEN(MP_TAC o SPEC `inv(Cx(&2) * Cx(pi) * ii)` o + MATCH_MP SERIES_COMPLEX_LMUL) THEN + MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN BINOP_TAC THENL + [REWRITE_TAC[FUN_EQ_THM] THEN X_GEN_TAC `k:num` THEN + MP_TAC(SPECL [`f:complex->complex`; `z:complex`; `r:real`; `k:num`; + `z:complex`] CAUCHY_HAS_PATH_INTEGRAL_HIGHER_DERIVATIVE_CIRCLEPATH) THEN + ASM_REWRITE_TAC[CENTRE_IN_BALL] THEN + DISCH_THEN(SUBST1_TAC o MATCH_MP PATH_INTEGRAL_UNIQUE) THEN + MATCH_MP_TAC(COMPLEX_FIELD + `~(pit = Cx(&0)) /\ ~(fact = Cx(&0)) + ==> inv(pit) * ((pit / fact) * d) * wz = d / fact * wz`) THEN + REWRITE_TAC[CX_2PII_NZ; CX_INJ; REAL_OF_NUM_EQ; FACT_NZ]; + MP_TAC(SPECL [`f:complex->complex`; `z:complex`; `r:real`; `w:complex`] + CAUCHY_INTEGRAL_CIRCLEPATH_SIMPLE) THEN + ASM_REWRITE_TAC[] THEN + DISCH_THEN(SUBST1_TAC o MATCH_MP PATH_INTEGRAL_UNIQUE) THEN + MATCH_MP_TAC(COMPLEX_FIELD + `~(x * y * z = Cx(&0)) ==> inv(x * y * z) * x * y * z * w = w`) THEN + REWRITE_TAC[CX_2PII_NZ]]] THEN + REWRITE_TAC[sums; FROM_0; INTER_UNIV] THEN + MATCH_MP_TAC LIM_TRANSFORM_EVENTUALLY THEN + EXISTS_TAC `\n. path_integral (circlepath(z,r)) + (\u. vsum (0..n) + (\k. f u * (w - z) pow k / (u - z) pow (k + 1)))` THEN + CONJ_TAC THENL + [MATCH_MP_TAC ALWAYS_EVENTUALLY THEN + X_GEN_TAC `k:num` THEN REWRITE_TAC[] THEN + W(MP_TAC o PART_MATCH (lhs o rand) PATH_INTEGRAL_VSUM o lhand o snd) THEN + ANTS_TAC THENL + [REWRITE_TAC[FINITE_NUMSEG] THEN X_GEN_TAC `m:num` THEN DISCH_TAC THEN + ONCE_REWRITE_TAC[SIMPLE_COMPLEX_ARITH + `a * b / c:complex = b * a / c`] THEN + MATCH_MP_TAC PATH_INTEGRABLE_COMPLEX_LMUL THEN + ASM_SIMP_TAC[CAUCHY_HIGHER_DERIVATIVE_INTEGRAL_CIRCLEPATH; + CENTRE_IN_BALL]; + ALL_TAC] THEN + DISCH_THEN SUBST1_TAC THEN MATCH_MP_TAC VSUM_EQ THEN + X_GEN_TAC `m:num` THEN DISCH_TAC THEN REWRITE_TAC[] THEN + ONCE_REWRITE_TAC[SIMPLE_COMPLEX_ARITH `a * b / c:complex = a / c * b`] THEN + MATCH_MP_TAC PATH_INTEGRAL_COMPLEX_RMUL THEN + ASM_SIMP_TAC[CAUCHY_HIGHER_DERIVATIVE_INTEGRAL_CIRCLEPATH; CENTRE_IN_BALL]; + ALL_TAC] THEN + MATCH_MP_TAC(CONJUNCT2 + (REWRITE_RULE[FORALL_AND_THM; TAUT `a ==> b /\ c <=> (a ==> b) /\ (a ==> c)`] + PATH_INTEGRAL_UNIFORM_LIMIT_CIRCLEPATH)) THEN + ASM_REWRITE_TAC[TRIVIAL_LIMIT_SEQUENTIALLY] THEN CONJ_TAC THENL + [MATCH_MP_TAC ALWAYS_EVENTUALLY THEN + X_GEN_TAC `k:num` THEN REWRITE_TAC[] THEN + MATCH_MP_TAC PATH_INTEGRABLE_VSUM THEN + REWRITE_TAC[FINITE_NUMSEG] THEN X_GEN_TAC `m:num` THEN DISCH_TAC THEN + ONCE_REWRITE_TAC[SIMPLE_COMPLEX_ARITH `a * b / c:complex = b * a / c`] THEN + MATCH_MP_TAC PATH_INTEGRABLE_COMPLEX_LMUL THEN + ASM_SIMP_TAC[CAUCHY_HIGHER_DERIVATIVE_INTEGRAL_CIRCLEPATH; CENTRE_IN_BALL]; + ALL_TAC] THEN + X_GEN_TAC `e:real` THEN STRIP_TAC THEN + ASM_SIMP_TAC[PATH_IMAGE_CIRCLEPATH; REAL_LT_IMP_LE; IN_ELIM_THM] THEN + SIMP_TAC[VSUM_COMPLEX_LMUL; FINITE_NUMSEG; complex_div] THEN + REWRITE_TAC[GSYM COMPLEX_SUB_LDISTRIB; COMPLEX_NORM_MUL] THEN + REWRITE_TAC[COMPLEX_POW_ADD; COMPLEX_INV_MUL; COMPLEX_POW_1] THEN + SIMP_TAC[COMPLEX_MUL_ASSOC; VSUM_COMPLEX_RMUL; FINITE_NUMSEG] THEN + REWRITE_TAC[GSYM complex_div; GSYM COMPLEX_POW_DIV] THEN + REWRITE_TAC[VSUM_GP; CONJUNCT1 LT; CONJUNCT1 complex_pow] THEN + REWRITE_TAC[EVENTUALLY_SEQUENTIALLY] THEN + SUBGOAL_THEN + `?B. &0 < B /\ + !u:complex. u IN cball(z,r) ==> norm(f u:complex) <= B` + STRIP_ASSUME_TAC THENL + [MP_TAC(ISPEC `IMAGE (f:complex->complex) (cball(z,r))` + COMPACT_IMP_BOUNDED) THEN + ASM_SIMP_TAC[COMPACT_CONTINUOUS_IMAGE; COMPACT_CBALL] THEN + REWRITE_TAC[BOUNDED_POS; FORALL_IN_IMAGE]; + ALL_TAC] THEN + SUBGOAL_THEN `?k. &0 < k /\ k <= r /\ norm(w - z) <= r - k /\ + !u. norm(u - z) = r ==> k <= norm(u - w)` + STRIP_ASSUME_TAC THENL + [EXISTS_TAC `r - dist(z:complex,w)` THEN + REPEAT(POP_ASSUM MP_TAC) THEN REWRITE_TAC[IN_BALL] THEN + NORM_ARITH_TAC; + ALL_TAC] THEN + REWRITE_TAC[IN_SPHERE; NORM_ARITH `dist(z,x) = r <=> norm(x - z) = r`] THEN + MP_TAC(SPECL [`(r - k) / r:real`; `e / B * k:real`] REAL_ARCH_POW_INV) THEN + ASM_SIMP_TAC[REAL_LT_LDIV_EQ; REAL_LT_DIV; REAL_HALF; REAL_LT_MUL] THEN + ASM_REWRITE_TAC[REAL_ARITH `r - k < &1 * r <=> &0 < k`] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `N:num` THEN DISCH_TAC THEN + X_GEN_TAC `n:num` THEN DISCH_TAC THEN + X_GEN_TAC `u:complex` THEN DISCH_TAC THEN + SUBGOAL_THEN `~(u:complex = z) /\ ~(u = w)` STRIP_ASSUME_TAC THENL + [FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_BALL]) THEN + MAP_EVERY UNDISCH_TAC [`&0 < r`; `norm(u - z:complex) = r`] THEN + NORM_ARITH_TAC; + ALL_TAC] THEN + ASM_SIMP_TAC[COMPLEX_FIELD + `~(u = z) /\ ~(u = w) ==> ~((w - z) / (u - z) = Cx(&1))`] THEN + ASM_SIMP_TAC[COMPLEX_FIELD + `~(u = z) /\ ~(u = w) + ==> x / (Cx(&1) - (w - z) / (u - z)) / (u - z) = x / (u - w)`] THEN + ASM_SIMP_TAC[COMPLEX_FIELD + `~(u = w) + ==> (Cx(&1) - e) / (u - w) - inv(u - w) = --(e / (u - w))`] THEN + REWRITE_TAC[COMPLEX_NORM_DIV; NORM_NEG; COMPLEX_NORM_POW] THEN + MATCH_MP_TAC REAL_LET_TRANS THEN + EXISTS_TAC `B * ((r - k) / r) pow N / k:real` THEN CONJ_TAC THENL + [ALL_TAC; + ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN + ASM_SIMP_TAC[GSYM REAL_LT_RDIV_EQ; REAL_LT_LDIV_EQ]] THEN + MATCH_MP_TAC REAL_LE_MUL2 THEN ASM_SIMP_TAC[NORM_POS_LE] THEN + REPEAT CONJ_TAC THENL + [FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[IN_CBALL] THEN + ONCE_REWRITE_TAC[DIST_SYM] THEN ASM_REWRITE_TAC[dist; REAL_LE_REFL]; + MATCH_MP_TAC REAL_LE_DIV THEN REWRITE_TAC[NORM_POS_LE] THEN + MATCH_MP_TAC REAL_POW_LE THEN MATCH_MP_TAC REAL_LE_DIV THEN + ASM_SIMP_TAC[REAL_LT_IMP_LE; NORM_POS_LE]; + ALL_TAC] THEN + REWRITE_TAC[real_div] THEN MATCH_MP_TAC REAL_LE_MUL2 THEN + REWRITE_TAC[GSYM real_div] THEN REPEAT CONJ_TAC THENL + [MATCH_MP_TAC REAL_POW_LE THEN MATCH_MP_TAC REAL_LE_DIV THEN + ASM_SIMP_TAC[REAL_LT_IMP_LE; NORM_POS_LE]; + ALL_TAC; + REWRITE_TAC[REAL_LE_INV_EQ; NORM_POS_LE]; + MATCH_MP_TAC REAL_LE_INV2 THEN ASM_SIMP_TAC[]] THEN + MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `((r - k) / r:real) pow (SUC n)` THEN CONJ_TAC THENL + [MATCH_MP_TAC REAL_POW_LE2 THEN + ASM_SIMP_TAC[REAL_LE_DIV2_EQ; REAL_LE_DIV; NORM_POS_LE; REAL_LT_IMP_LE]; + MATCH_MP_TAC REAL_POW_MONO_INV THEN + ASM_SIMP_TAC[REAL_LE_RDIV_EQ; REAL_LE_LDIV_EQ] THEN + ASM_SIMP_TAC[ARITH_RULE `N <= n ==> N <= SUC n`] THEN + ASM_REAL_ARITH_TAC]);; + +(* ------------------------------------------------------------------------- *) +(* Liouville's theorem. *) +(* ------------------------------------------------------------------------- *) + +let LIOUVILLE_THEOREM = prove + (`!f. f holomorphic_on (:complex) /\ bounded (IMAGE f (:complex)) + ==> ?c. !z. f(z) = c`, + GEN_TAC THEN + SIMP_TAC[HOLOMORPHIC_ON_OPEN; OPEN_UNIV; BOUNDED_POS; IN_UNIV; + FORALL_IN_IMAGE; SKOLEM_THM] THEN + DISCH_THEN(CONJUNCTS_THEN2 (X_CHOOSE_TAC `f':complex->complex`) + (X_CHOOSE_THEN `B:real` STRIP_ASSUME_TAC)) THEN + SUBGOAL_THEN `!w. w IN (:complex) ==> f w:complex = f z` + (fun th -> MESON_TAC[th; IN_UNIV]) THEN + MATCH_MP_TAC HAS_COMPLEX_DERIVATIVE_ZERO_UNIQUE THEN + EXISTS_TAC `z:complex` THEN + REWRITE_TAC[IN_UNIV; CONVEX_UNIV; WITHIN_UNIV] THEN + X_GEN_TAC `w:complex` THEN + SUBGOAL_THEN `(f':complex->complex) w = Cx(&0)` + (fun th -> ASM_MESON_TAC[th]) THEN + REWRITE_TAC[GSYM COMPLEX_NORM_ZERO] THEN + MATCH_MP_TAC(REAL_ARITH `&0 <= x /\ ~(&0 < x) ==> x = &0`) THEN + REWRITE_TAC[NORM_POS_LE] THEN DISCH_TAC THEN + SUBGOAL_THEN `?R. &0 < R /\ B / R < norm((f':complex->complex) w)` + STRIP_ASSUME_TAC THENL + [EXISTS_TAC `&2 * B / norm((f':complex->complex) w)` THEN + ASM_SIMP_TAC[REAL_LT_DIV; REAL_LT_MUL; REAL_OF_NUM_LT; ARITH] THEN + REWRITE_TAC[real_div; REAL_INV_MUL; REAL_INV_INV; GSYM REAL_MUL_ASSOC] THEN + ASM_SIMP_TAC[REAL_FIELD + `&0 < B ==> B * inv(&2) * inv(B) * c = c / &2`] THEN + ASM_REAL_ARITH_TAC; + ALL_TAC] THEN + MP_TAC(SPECL [`f:complex->complex`; `w:complex`; + `R:real`; `w:complex`] + CAUCHY_DERIVATIVE_INTEGRAL_CIRCLEPATH) THEN + ANTS_TAC THENL + [ASM_SIMP_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN; HOLOMORPHIC_ON_OPEN; + OPEN_BALL; CENTRE_IN_BALL; REAL_LT_DIV; REAL_HALF] THEN + ASM_MESON_TAC[HAS_COMPLEX_DERIVATIVE_IMP_CONTINUOUS_AT; + CONTINUOUS_AT_WITHIN]; + ALL_TAC] THEN + STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o MATCH_MP HAS_PATH_INTEGRAL_INTEGRAL) THEN + DISCH_THEN(MP_TAC o SPEC `B:real / R pow 2` o MATCH_MP + (ONCE_REWRITE_RULE[IMP_CONJ] HAS_PATH_INTEGRAL_BOUND_CIRCLEPATH)) THEN + ASM_SIMP_TAC[REAL_LT_DIV; REAL_LT_IMP_LE; REAL_POW_LT] THEN + ASM_SIMP_TAC[COMPLEX_NORM_DIV; COMPLEX_NORM_POW; REAL_LE_DIV2_EQ; + REAL_POW_LT; REAL_NOT_LE] THEN + MATCH_MP_TAC REAL_LT_LCANCEL_IMP THEN + EXISTS_TAC `norm(Cx(&1) / (Cx (&2) * Cx pi * ii))` THEN + REWRITE_TAC[GSYM COMPLEX_NORM_MUL] THEN + SUBGOAL_THEN + `Cx(&1) / (Cx(&2) * Cx pi * ii) * + path_integral (circlepath (w,R)) (\u. f u / (u - w) pow 2) = + f' w` + SUBST1_TAC THENL [ASM_MESON_TAC[COMPLEX_DERIVATIVE_UNIQUE_AT]; ALL_TAC] THEN + REWRITE_TAC[COMPLEX_NORM_NZ] THEN + ASM_SIMP_TAC[CX_2PII_NZ; + COMPLEX_FIELD `~(y = Cx(&0)) ==> ~(Cx(&1) / y = Cx(&0))`] THEN + REWRITE_TAC[COMPLEX_NORM_DIV; COMPLEX_NORM_MUL; COMPLEX_NORM_CX] THEN + REWRITE_TAC[REAL_ABS_NUM; REAL_ABS_PI; COMPLEX_NORM_II] THEN + ASM_SIMP_TAC[PI_POS; REAL_FIELD + `&0 < R /\ &0 < pi + ==> &1 / (&2 * pi * &1) * B / R pow 2 * &2 * pi * R = B / R`]);; + +(* ------------------------------------------------------------------------- *) +(* These weaker versions don't even need the derivative formula. *) +(* ------------------------------------------------------------------------- *) + +let LIOUVILLE_WEAK = prove + (`!f. f holomorphic_on (:complex) /\ (f --> Cx(&0)) at_infinity + ==> !z. f(z) = Cx(&0)`, + REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[TAUT `p = ~ ~ p`] THEN + PURE_REWRITE_TAC[GSYM COMPLEX_NORM_NZ] THEN DISCH_TAC THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [LIM_AT_INFINITY]) THEN + DISCH_THEN(MP_TAC o SPEC `norm((f:complex->complex) z) / &2`) THEN + ASM_REWRITE_TAC[dist; REAL_HALF; COMPLEX_SUB_RZERO] THEN + DISCH_THEN(X_CHOOSE_THEN `B:real` STRIP_ASSUME_TAC) THEN + MP_TAC(SPECL [`f:complex->complex`; `z:complex`; + `&1 + abs B + norm(z:complex)`; `z:complex`] + CAUCHY_INTEGRAL_CIRCLEPATH) THEN + ASM_SIMP_TAC[CONVEX_UNIV; INTERIOR_OPEN; OPEN_UNIV; IN_UNIV] THEN + ABBREV_TAC `R = &1 + abs B + norm(z:complex)` THEN + SUBGOAL_THEN `&0 < R` ASSUME_TAC THENL + [ASM_MESON_TAC[NORM_POS_LE; REAL_ABS_POS; REAL_ARITH + `&0 <= x /\ &0 <= y ==> &0 < &1 + x + y`]; ALL_TAC] THEN + ASM_REWRITE_TAC[CENTRE_IN_BALL; NOT_IMP; CONJ_ASSOC] THEN CONJ_TAC THENL + [ASM_MESON_TAC[HOLOMORPHIC_ON_IMP_CONTINUOUS_ON; HOLOMORPHIC_ON_SUBSET; + SUBSET_UNIV]; + ALL_TAC] THEN + DISCH_THEN(MP_TAC o MATCH_MP + (ONCE_REWRITE_RULE[IMP_CONJ] HAS_PATH_INTEGRAL_BOUND_CIRCLEPATH)) THEN + DISCH_THEN(MP_TAC o SPEC `norm((f:complex->complex) z) / &2 / R`) THEN + ASM_SIMP_TAC[REAL_LE_DIV; NORM_POS_LE; REAL_POS; REAL_LT_IMP_LE] THEN + ASM_SIMP_TAC[REAL_FIELD `&0 < R ==> x / R * &2 * pi * R = &2 * pi * x`] THEN + REWRITE_TAC[NOT_IMP; REAL_NOT_LE] THEN CONJ_TAC THENL + [REPEAT STRIP_TAC THEN ASM_SIMP_TAC[COMPLEX_NORM_DIV; REAL_LE_DIV2_EQ] THEN + MATCH_MP_TAC REAL_LT_IMP_LE THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + UNDISCH_TAC `norm(x - z:complex) = R` THEN EXPAND_TAC "R" THEN + MATCH_MP_TAC(REAL_ARITH + `d <= x + z ==> d = &1 + abs b + z ==> x >= b`) THEN + REWRITE_TAC[VECTOR_SUB] THEN MESON_TAC[NORM_TRIANGLE; NORM_NEG]; + REWRITE_TAC[COMPLEX_NORM_MUL; COMPLEX_NORM_CX; REAL_ABS_NUM; REAL_ABS_PI; + COMPLEX_NORM_II] THEN + SIMP_TAC[REAL_LT_LMUL_EQ; REAL_OF_NUM_LT; ARITH; PI_POS; REAL_MUL_LID] THEN + SUBGOAL_THEN `?w:complex. norm w = abs B` MP_TAC THENL + [MESON_TAC[VECTOR_CHOOSE_SIZE; REAL_ABS_POS]; ALL_TAC] THEN + ASM_MESON_TAC[NORM_POS_LE; REAL_ARITH + `abs B >= B /\ (&0 <= x /\ x < z / &2 ==> z / &2 < z)`]]);; + +let LIOUVILLE_WEAK_INVERSE = prove + (`!f. f holomorphic_on (:complex) /\ + (!B. eventually (\x. norm(f x) >= B) at_infinity) + ==> ?z. f(z) = Cx(&0)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC(TAUT `(~p ==> F) ==> p`) THEN + PURE_REWRITE_TAC[NOT_EXISTS_THM] THEN DISCH_TAC THEN + MP_TAC(SPEC `\x:complex. Cx(&1) / (f(x))` LIOUVILLE_WEAK) THEN + ASM_SIMP_TAC[COMPLEX_FIELD `~(y = Cx(&0)) ==> ~(Cx(&1) / y = Cx(&0))`] THEN + CONJ_TAC THENL + [REWRITE_TAC[holomorphic_on; complex_div; COMPLEX_MUL_LID; IN_UNIV] THEN + GEN_TAC THEN REWRITE_TAC[GSYM complex_differentiable; WITHIN_UNIV] THEN + MATCH_MP_TAC COMPLEX_DIFFERENTIABLE_INV_AT THEN ASM_REWRITE_TAC[] THEN + ASM_MESON_TAC[OPEN_UNIV; HOLOMORPHIC_ON_OPEN; IN_UNIV; + complex_differentiable]; + REWRITE_TAC[tendsto] THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `&2/ e`) THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] EVENTUALLY_MONO) THEN + REWRITE_TAC[dist; COMPLEX_SUB_RZERO; real_ge; COMPLEX_NORM_DIV; + COMPLEX_NORM_CX; REAL_ABS_POS] THEN + ASM_SIMP_TAC[REAL_LT_LDIV_EQ; REAL_LE_LDIV_EQ; COMPLEX_NORM_NZ] THEN + REAL_ARITH_TAC]);; + +(* ------------------------------------------------------------------------- *) +(* In particular we get the Fundamental Theorem of Algebra. *) +(* ------------------------------------------------------------------------- *) + +let FTA = prove + (`!a n. a(0) = Cx(&0) \/ ~(!k. k IN 1..n ==> a(k) = Cx(&0)) + ==> ?z. vsum(0..n) (\i. a(i) * z pow i) = Cx(&0)`, + REPEAT STRIP_TAC THENL + [EXISTS_TAC `Cx(&0)` THEN + SIMP_TAC[VSUM_CLAUSES_LEFT; LE_0] THEN + ASM_SIMP_TAC[ADD_CLAUSES; COMPLEX_POW_ZERO; LE_1; COMPLEX_ADD_LID; + COMPLEX_MUL_RZERO; COMPLEX_MUL_LZERO] THEN + REWRITE_TAC[GSYM COMPLEX_VEC_0; VSUM_0]; + MATCH_MP_TAC LIOUVILLE_WEAK_INVERSE THEN CONJ_TAC THENL + [MATCH_MP_TAC HOLOMORPHIC_ON_VSUM THEN + SIMP_TAC[FINITE_NUMSEG; HOLOMORPHIC_ON_POW; HOLOMORPHIC_ON_MUL; + HOLOMORPHIC_ON_CONST; HOLOMORPHIC_ON_ID]; + ASM_MESON_TAC[COMPLEX_POLYFUN_EXTREMAL]]]);; + +(* ------------------------------------------------------------------------- *) +(* Weierstrass convergence theorem. *) +(* ------------------------------------------------------------------------- *) + +let HOLOMORPHIC_UNIFORM_LIMIT = prove + (`!net:(A net) f g z r. + ~(trivial_limit net) /\ + eventually + (\n. (f n) continuous_on cball(z,r) /\ + (f n) holomorphic_on ball(z,r)) + net /\ + (!e. &0 < e + ==> eventually (\n. !x. x IN cball(z,r) ==> norm(f n x - g x) < e) + net) + ==> g continuous_on cball(z,r) /\ g holomorphic_on ball(z,r)`, + REPEAT GEN_TAC THEN STRIP_TAC THEN + DISJ_CASES_TAC(REAL_ARITH `r <= &0 \/ &0 < r`) THENL + [ASM_SIMP_TAC[BALL_EMPTY; holomorphic_on; NOT_IN_EMPTY] THEN + FIRST_X_ASSUM(DISJ_CASES_TAC o MATCH_MP (REAL_ARITH + `r <= &0 ==> r < &0 \/ r = &0`)) THEN + ASM_SIMP_TAC[continuous_on; CBALL_EMPTY; CBALL_SING; NOT_IN_EMPTY] THEN + SIMP_TAC[IN_SING; DIST_REFL] THEN MESON_TAC[REAL_LT_01]; + ALL_TAC] THEN + MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN CONJ_TAC THENL + [MATCH_MP_TAC CONTINUOUS_UNIFORM_LIMIT THEN + MAP_EVERY EXISTS_TAC [`net:A net`; `f:A->complex->complex`] THEN + RULE_ASSUM_TAC(REWRITE_RULE[EVENTUALLY_AND]) THEN + ASM_REWRITE_TAC[]; + ALL_TAC] THEN + DISCH_TAC THEN + MP_TAC(ISPECL + [`\x. Cx(&1) / (Cx(&2) * Cx pi * ii) * g(x:complex)`; + `g:complex->complex`; `z:complex`; `r:real`; `1`] + CAUCHY_NEXT_DERIVATIVE_CIRCLEPATH) THEN + SIMP_TAC[HOLOMORPHIC_ON_OPEN; OPEN_BALL] THEN + ANTS_TAC THENL [ALL_TAC; ASM_MESON_TAC[]] THEN + REWRITE_TAC[ARITH] THEN CONJ_TAC THENL + [MATCH_MP_TAC CONTINUOUS_ON_COMPLEX_MUL THEN + REWRITE_TAC[CONTINUOUS_ON_CONST] THEN + MATCH_MP_TAC CONTINUOUS_ON_SUBSET THEN + ASM_SIMP_TAC[PATH_IMAGE_CIRCLEPATH; REAL_LT_IMP_LE] THEN + EXISTS_TAC `cball(z:complex,r)` THEN ASM_REWRITE_TAC[ETA_AX] THEN + SIMP_TAC[SPHERE_SUBSET_CBALL]; + ALL_TAC] THEN + X_GEN_TAC `w:complex` THEN DISCH_TAC THEN REWRITE_TAC[COMPLEX_POW_1] THEN + REWRITE_TAC[complex_div; GSYM COMPLEX_MUL_ASSOC] THEN + REWRITE_TAC[GSYM complex_div] THEN REWRITE_TAC[COMPLEX_MUL_ASSOC] THEN + REWRITE_TAC[GSYM complex_div] THEN REWRITE_TAC[GSYM COMPLEX_MUL_ASSOC] THEN + SUBGOAL_THEN + `(\u. g u / (u - w)) path_integrable_on circlepath(z,r) /\ + ((\n:A. path_integral(circlepath(z,r)) + (\u. f n u / (u - w))) --> + path_integral(circlepath(z,r)) (\u. g u / (u - w))) net` + MP_TAC THENL + [MATCH_MP_TAC PATH_INTEGRAL_UNIFORM_LIMIT_CIRCLEPATH THEN + ASM_REWRITE_TAC[] THEN CONJ_TAC THENL + [FIRST_X_ASSUM(fun th -> MP_TAC th THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] EVENTUALLY_MONO)) THEN + X_GEN_TAC `a:A` THEN REWRITE_TAC[] THEN STRIP_TAC THEN + MATCH_MP_TAC PATH_INTEGRABLE_CONTINUOUS_CIRCLEPATH THEN + ASM_SIMP_TAC[PATH_IMAGE_CIRCLEPATH; REAL_LT_IMP_LE] THEN + REWRITE_TAC[sphere; NORM_ARITH `dist(z,w) = norm(w - z)`] THEN + MATCH_MP_TAC CONTINUOUS_ON_COMPLEX_DIV THEN CONJ_TAC THENL + [MATCH_MP_TAC CONTINUOUS_ON_SUBSET THEN + EXISTS_TAC `cball(z:complex,r)` THEN ASM_REWRITE_TAC[ETA_AX] THEN + SIMP_TAC[SUBSET; IN_CBALL; IN_ELIM_THM; NORM_SUB; dist; REAL_LE_REFL]; + ALL_TAC] THEN + ASM_SIMP_TAC[CONTINUOUS_ON_COMPLEX_POW; CONTINUOUS_ON_SUB; + CONTINUOUS_ON_CONST; CONTINUOUS_ON_ID] THEN + REWRITE_TAC[COMPLEX_POW_EQ_0; ARITH; IN_ELIM_THM] THEN + GEN_TAC THEN ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN + SIMP_TAC[COMPLEX_SUB_0] THEN DISCH_THEN SUBST_ALL_TAC THEN + ASM_MESON_TAC[IN_BALL; dist; REAL_LT_REFL; DIST_SYM]; + ALL_TAC] THEN + X_GEN_TAC `e:real` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `e * abs(r - norm(w - z:complex))`) THEN + SUBGOAL_THEN `&0 < e * abs(r - norm(w - z:complex))` ASSUME_TAC THENL + [MATCH_MP_TAC REAL_LT_MUL THEN ASM_REWRITE_TAC[GSYM REAL_ABS_NZ] THEN + SIMP_TAC[REAL_SUB_0] THEN + ASM_MESON_TAC[IN_BALL; dist; REAL_LT_REFL; DIST_SYM]; + ALL_TAC] THEN + ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] EVENTUALLY_MONO) THEN + X_GEN_TAC `a:A` THEN REWRITE_TAC[] THEN + MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `x:complex` THEN + ASM_SIMP_TAC[PATH_IMAGE_CIRCLEPATH; REAL_LT_IMP_LE] THEN + REWRITE_TAC[sphere; NORM_ARITH `dist(z,w) = norm(w - z)`] THEN + REWRITE_TAC[IN_ELIM_THM] THEN + DISCH_THEN(fun th -> DISCH_TAC THEN MP_TAC th) THEN + ASM_REWRITE_TAC[IN_CBALL] THEN ONCE_REWRITE_TAC[DIST_SYM] THEN + ASM_REWRITE_TAC[dist; REAL_LE_REFL] THEN + SUBGOAL_THEN `~(x:complex = w)` ASSUME_TAC THENL + [DISCH_THEN SUBST_ALL_TAC THEN + ASM_MESON_TAC[IN_BALL; dist; NORM_SUB; REAL_LT_REFL]; + ALL_TAC] THEN + ASM_SIMP_TAC[COMPLEX_FIELD + `~(x = w) ==> a / (x - w) - b / (x - w) = + (a - b:complex) / (x - w)`] THEN + ASM_SIMP_TAC[COMPLEX_NORM_DIV; REAL_LT_LDIV_EQ; COMPLEX_NORM_NZ; + COMPLEX_POW_EQ_0; COMPLEX_SUB_0] THEN + MATCH_MP_TAC(REAL_ARITH `a <= b ==> x < a ==> x < b`) THEN + ASM_SIMP_TAC[REAL_LE_LMUL_EQ; REAL_LT_IMP_LE; COMPLEX_NORM_POW] THEN + MATCH_MP_TAC(REAL_ARITH `w < r /\ r <= x + w ==> abs(r - w) <= x`) THEN + CONJ_TAC THENL [ASM_MESON_TAC[IN_BALL; dist; NORM_SUB]; ALL_TAC] THEN + FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN + REWRITE_TAC[GSYM dist] THEN MESON_TAC[DIST_TRIANGLE]; + ALL_TAC] THEN + STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o MATCH_MP HAS_PATH_INTEGRAL_INTEGRAL) THEN + DISCH_THEN(MP_TAC o SPEC `Cx(&1) / (Cx(&2) * Cx pi * ii)` o + MATCH_MP HAS_PATH_INTEGRAL_COMPLEX_LMUL) THEN + MATCH_MP_TAC EQ_IMP THEN REWRITE_TAC[] THEN AP_THM_TAC THEN AP_TERM_TAC THEN + MATCH_MP_TAC LIM_UNIQUE THEN + MAP_EVERY EXISTS_TAC [`net:A net`; `\n. (f:A->complex->complex) n w`] THEN + ASM_REWRITE_TAC[] THEN CONJ_TAC THENL + [ALL_TAC; + REWRITE_TAC[tendsto; dist] THEN X_GEN_TAC `e:real` THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `e:real`) THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] EVENTUALLY_MONO) THEN + REWRITE_TAC[] THEN ASM_MESON_TAC[SUBSET; BALL_SUBSET_CBALL]] THEN + SUBGOAL_THEN + `((\n:A. Cx(&2) * Cx pi * ii * f n w) + --> path_integral (circlepath (z,r)) (\u. g u / (u - w))) net` + MP_TAC THENL + [MATCH_MP_TAC LIM_TRANSFORM_EVENTUALLY THEN EXISTS_TAC + `\n:A. path_integral (circlepath (z,r)) (\u. f n u / (u - w))` THEN + ASM_REWRITE_TAC[] THEN + FIRST_X_ASSUM(fun th -> MP_TAC th THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] EVENTUALLY_MONO)) THEN + X_GEN_TAC `a:A` THEN REWRITE_TAC[] THEN STRIP_TAC THEN + MATCH_MP_TAC PATH_INTEGRAL_UNIQUE THEN + MATCH_MP_TAC CAUCHY_INTEGRAL_CIRCLEPATH THEN + ASM_REWRITE_TAC[ETA_AX]; + ALL_TAC] THEN + DISCH_THEN(MP_TAC o SPEC `Cx(&1) / (Cx(&2) * Cx pi * ii)` o + MATCH_MP LIM_COMPLEX_LMUL) THEN + SIMP_TAC[CX_2PII_NZ; COMPLEX_FIELD + `~(x * y * z = Cx(&0)) ==> Cx(&1) / (x * y * z) * x * y * z * w = w`]);; + +(* ------------------------------------------------------------------------- *) +(* Version showing that the limit is the limit of the derivatives. *) +(* ------------------------------------------------------------------------- *) + +let HAS_COMPLEX_DERIVATIVE_UNIFORM_LIMIT = prove + (`!net:(A net) f f' g z r. + &0 < r /\ ~(trivial_limit net) /\ + eventually + (\n. (f n) continuous_on cball(z,r) /\ + (!w. w IN ball(z,r) + ==> ((f n) has_complex_derivative (f' n w)) (at w))) + net /\ + (!e. &0 < e + ==> eventually (\n. !x. x IN cball(z,r) ==> norm(f n x - g x) < e) + net) + ==> g continuous_on cball(z,r) /\ + ?g'. !w. w IN ball(z,r) + ==> (g has_complex_derivative (g' w)) (at w) /\ + ((\n. f' n w) --> g' w) net`, + REPEAT GEN_TAC THEN STRIP_TAC THEN + MP_TAC(SPECL [`net:(A)net`; `f:A->complex->complex`; + `g:complex->complex`; `z:complex`; `r:real`] + HOLOMORPHIC_UNIFORM_LIMIT) THEN + ANTS_TAC THENL + [ASM_REWRITE_TAC[] THEN FIRST_X_ASSUM(fun th -> + MP_TAC th THEN MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] + EVENTUALLY_MONO)) THEN + SIMP_TAC[HOLOMORPHIC_ON_OPEN; OPEN_BALL] THEN MESON_TAC[]; + ALL_TAC] THEN + SIMP_TAC[HOLOMORPHIC_ON_OPEN; OPEN_BALL] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC + (MP_TAC o REWRITE_RULE[RIGHT_IMP_EXISTS_THM])) THEN + REWRITE_TAC[SKOLEM_THM] THEN MATCH_MP_TAC MONO_EXISTS THEN + X_GEN_TAC `g':complex->complex` THEN STRIP_TAC THEN + ASM_SIMP_TAC[] THEN X_GEN_TAC `w:complex` THEN DISCH_TAC THEN + ONCE_REWRITE_TAC[LIM_NULL] THEN MATCH_MP_TAC LIM_TRANSFORM_EVENTUALLY THEN + EXISTS_TAC + `\n. Cx(&1) / (Cx(&2) * Cx pi * ii) * + (path_integral(circlepath(z,r)) (\x. f (n:A) x / (x - w) pow 2) - + path_integral(circlepath(z,r)) (\x. g x / (x - w) pow 2))` THEN + REWRITE_TAC[] THEN CONJ_TAC THENL + [FIRST_X_ASSUM(fun th -> + MP_TAC th THEN MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] + EVENTUALLY_MONO)) THEN + X_GEN_TAC `a:A` THEN REWRITE_TAC[] THEN STRIP_TAC THEN + REWRITE_TAC[COMPLEX_SUB_LDISTRIB] THEN BINOP_TAC THEN + MATCH_MP_TAC COMPLEX_DERIVATIVE_UNIQUE_AT THENL + [EXISTS_TAC `(f:A->complex->complex) a`; + EXISTS_TAC `g:complex->complex`] THEN + EXISTS_TAC `w:complex` THEN ASM_SIMP_TAC[] THEN + W(fun (asl,w) -> MP_TAC(PART_MATCH (rand o rand) + CAUCHY_DERIVATIVE_INTEGRAL_CIRCLEPATH w)) THEN + ASM_SIMP_TAC[HOLOMORPHIC_ON_OPEN; OPEN_BALL] THEN + ANTS_TAC THEN SIMP_TAC[] THEN ASM_MESON_TAC[]; + ALL_TAC] THEN + REWRITE_TAC[COMPLEX_VEC_0] THEN + SUBST1_TAC(SYM(SPEC `Cx(&1) / (Cx(&2) * Cx pi * ii)` COMPLEX_MUL_RZERO)) THEN + MATCH_MP_TAC LIM_COMPLEX_MUL THEN REWRITE_TAC[LIM_CONST] THEN + REWRITE_TAC[GSYM COMPLEX_VEC_0] THEN REWRITE_TAC[GSYM LIM_NULL] THEN + W(fun (asl,w) -> MP_TAC(PART_MATCH (rand o rand) + PATH_INTEGRAL_UNIFORM_LIMIT_CIRCLEPATH w)) THEN + ANTS_TAC THEN ASM_SIMP_TAC[] THEN CONJ_TAC THENL + [FIRST_X_ASSUM(fun th -> MP_TAC th THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] EVENTUALLY_MONO)) THEN + X_GEN_TAC `a:A` THEN REWRITE_TAC[] THEN STRIP_TAC THEN + MATCH_MP_TAC PATH_INTEGRABLE_CONTINUOUS_CIRCLEPATH THEN + ASM_SIMP_TAC[PATH_IMAGE_CIRCLEPATH; REAL_LT_IMP_LE] THEN + REWRITE_TAC[sphere; NORM_ARITH `dist(z,w) = norm(w - z)`] THEN + MATCH_MP_TAC CONTINUOUS_ON_COMPLEX_DIV THEN CONJ_TAC THENL + [MATCH_MP_TAC CONTINUOUS_ON_SUBSET THEN + EXISTS_TAC `cball(z:complex,r)` THEN ASM_REWRITE_TAC[ETA_AX] THEN + SIMP_TAC[SUBSET; IN_CBALL; IN_ELIM_THM; NORM_SUB; dist; REAL_LE_REFL]; + ALL_TAC] THEN + ASM_SIMP_TAC[CONTINUOUS_ON_COMPLEX_POW; CONTINUOUS_ON_SUB; + CONTINUOUS_ON_CONST; CONTINUOUS_ON_ID] THEN + REWRITE_TAC[COMPLEX_POW_EQ_0; ARITH; IN_ELIM_THM] THEN + GEN_TAC THEN ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN + SIMP_TAC[COMPLEX_SUB_0] THEN DISCH_THEN SUBST_ALL_TAC THEN + ASM_MESON_TAC[IN_BALL; dist; REAL_LT_REFL; DIST_SYM]; + ALL_TAC] THEN + X_GEN_TAC `e:real` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `e * abs(r - norm(w - z:complex)) pow 2`) THEN + SUBGOAL_THEN `&0 < e * abs(r - norm(w - z:complex)) pow 2` ASSUME_TAC THENL + [MATCH_MP_TAC REAL_LT_MUL THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC REAL_POW_LT THEN REWRITE_TAC[GSYM REAL_ABS_NZ] THEN + SIMP_TAC[REAL_SUB_0] THEN + ASM_MESON_TAC[IN_BALL; dist; REAL_LT_REFL; DIST_SYM]; + ALL_TAC] THEN + ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] EVENTUALLY_MONO) THEN + X_GEN_TAC `a:A` THEN REWRITE_TAC[] THEN + MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `x:complex` THEN + ASM_SIMP_TAC[PATH_IMAGE_CIRCLEPATH; REAL_LT_IMP_LE] THEN + REWRITE_TAC[sphere; NORM_ARITH `dist(z,w) = norm(w - z)`] THEN + REWRITE_TAC[IN_ELIM_THM] THEN + DISCH_THEN(fun th -> DISCH_TAC THEN MP_TAC th) THEN + ASM_REWRITE_TAC[IN_CBALL] THEN ONCE_REWRITE_TAC[DIST_SYM] THEN + ASM_REWRITE_TAC[dist; REAL_LE_REFL] THEN + SUBGOAL_THEN `~(x:complex = w)` ASSUME_TAC THENL + [DISCH_THEN SUBST_ALL_TAC THEN + ASM_MESON_TAC[IN_BALL; dist; NORM_SUB; REAL_LT_REFL]; + ALL_TAC] THEN + ASM_SIMP_TAC[COMPLEX_FIELD + `~(x = w) ==> a / (x - w) pow 2 - b / (x - w) pow 2 = + (a - b:complex) / (x - w) pow 2`] THEN + ASM_SIMP_TAC[COMPLEX_NORM_DIV; REAL_LT_LDIV_EQ; COMPLEX_NORM_NZ; + COMPLEX_POW_EQ_0; COMPLEX_SUB_0] THEN + MATCH_MP_TAC(REAL_ARITH `a <= b ==> x < a ==> x < b`) THEN + ASM_SIMP_TAC[REAL_LE_LMUL_EQ; REAL_LT_IMP_LE; COMPLEX_NORM_POW] THEN + MATCH_MP_TAC REAL_POW_LE2 THEN REWRITE_TAC[REAL_ABS_POS] THEN + MATCH_MP_TAC(REAL_ARITH `w < r /\ r <= x + w ==> abs(r - w) <= x`) THEN + CONJ_TAC THENL [ASM_MESON_TAC[IN_BALL; dist; NORM_SUB]; ALL_TAC] THEN + FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN + REWRITE_TAC[GSYM dist] THEN MESON_TAC[DIST_TRIANGLE]);; + +(* ------------------------------------------------------------------------- *) +(* Some more simple/convenient versions for applications. *) +(* ------------------------------------------------------------------------- *) + +let HOLOMORPHIC_UNIFORM_SEQUENCE = prove + (`!f g s. + open s /\ + (!n. (f n) holomorphic_on s) /\ + (!x. x IN s + ==> ?d. &0 < d /\ cball(x,d) SUBSET s /\ + !e. &0 < e + ==> eventually (\n. !y. y IN cball(x,d) + ==> norm(f n y - g y) < e) + sequentially) + ==> g holomorphic_on s`, + REPEAT STRIP_TAC THEN ASM_SIMP_TAC[HOLOMORPHIC_ON_OPEN] THEN + X_GEN_TAC `z:complex` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `z:complex`) THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `r:real` STRIP_ASSUME_TAC) THEN + MP_TAC(ISPECL [`sequentially`; `f:num->complex->complex`; + `g:complex->complex`; `z:complex`; `r:real`] + HOLOMORPHIC_UNIFORM_LIMIT) THEN + ASM_REWRITE_TAC[TRIVIAL_LIMIT_SEQUENTIALLY] THEN ANTS_TAC THENL + [MATCH_MP_TAC ALWAYS_EVENTUALLY THEN + ASM_MESON_TAC[HOLOMORPHIC_ON_IMP_CONTINUOUS_ON; HOLOMORPHIC_ON_SUBSET; + BALL_SUBSET_CBALL]; + SIMP_TAC[HOLOMORPHIC_ON_OPEN; OPEN_BALL] THEN + ASM_MESON_TAC[CENTRE_IN_BALL]]);; + +let HAS_COMPLEX_DERIVATIVE_UNIFORM_SEQUENCE = prove + (`!f f' g s. + open s /\ + (!n x. x IN s ==> ((f n) has_complex_derivative f' n x) (at x)) /\ + (!x. x IN s + ==> ?d. &0 < d /\ cball(x,d) SUBSET s /\ + !e. &0 < e + ==> eventually (\n. !y. y IN cball(x,d) + ==> norm(f n y - g y) < e) + sequentially) + ==> ?g'. !x. x IN s ==> (g has_complex_derivative g'(x)) (at x) /\ + ((\n. f' n x) --> g'(x)) sequentially`, + REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM SKOLEM_THM; RIGHT_EXISTS_IMP_THM] THEN + X_GEN_TAC `z:complex` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `z:complex`) THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `r:real` STRIP_ASSUME_TAC) THEN + MP_TAC(ISPECL [`sequentially`; `f:num->complex->complex`; + `f':num->complex->complex`; + `g:complex->complex`; `z:complex`; `r:real`] + HAS_COMPLEX_DERIVATIVE_UNIFORM_LIMIT) THEN + ASM_REWRITE_TAC[TRIVIAL_LIMIT_SEQUENTIALLY] THEN ANTS_TAC THENL + [ALL_TAC; ASM_MESON_TAC[CENTRE_IN_BALL]] THEN + MATCH_MP_TAC ALWAYS_EVENTUALLY THEN X_GEN_TAC `n:num` THEN + REWRITE_TAC[] THEN CONJ_TAC THENL + [MATCH_MP_TAC CONTINUOUS_AT_IMP_CONTINUOUS_ON THEN + ASM_MESON_TAC[HAS_COMPLEX_DERIVATIVE_IMP_CONTINUOUS_AT; SUBSET]; + ASM_MESON_TAC[BALL_SUBSET_CBALL; SUBSET]]);; + +(* ------------------------------------------------------------------------- *) +(* A one-stop shop for an analytic function defined by a series. *) +(* ------------------------------------------------------------------------- *) + +let SERIES_AND_DERIVATIVE_COMPARISON = prove + (`!f f' s k h. + open s /\ + (!n x. n IN k /\ x IN s ==> (f n has_complex_derivative f' n x) (at x)) /\ + (?l. (lift o h sums l) k) /\ + (?N. !n x. N <= n /\ n IN k /\ x IN s ==> norm(f n x) <= h n) + ==> ?g g'. !x. x IN s + ==> ((\n. f n x) sums g x) k /\ + ((\n. f' n x) sums g' x) k /\ + (g has_complex_derivative g' x) (at x)`, + REPEAT GEN_TAC THEN + REPLICATE_TAC 2 (DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + DISCH_THEN(MP_TAC o MATCH_MP SERIES_COMPARISON_UNIFORM) THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `g:complex->complex` THEN + REWRITE_TAC[] THEN DISCH_TAC THEN + REWRITE_TAC[TAUT `a ==> b /\ c /\ d <=> (a ==> b) /\ (a ==> d /\ c)`] THEN + REWRITE_TAC[FORALL_AND_THM; RIGHT_EXISTS_AND_THM] THEN CONJ_TAC THENL + [REWRITE_TAC[sums; LIM_SEQUENTIALLY] THEN ASM_MESON_TAC[]; ALL_TAC] THEN + REWRITE_TAC[sums] THEN + MATCH_MP_TAC HAS_COMPLEX_DERIVATIVE_UNIFORM_SEQUENCE THEN + EXISTS_TAC `\n x. vsum + (k INTER (0..n)) (\n. (f:num->complex->complex) n x)` THEN + ASM_SIMP_TAC[HAS_COMPLEX_DERIVATIVE_VSUM; FINITE_INTER_NUMSEG; IN_INTER] THEN + X_GEN_TAC `z:complex` THEN DISCH_TAC THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [OPEN_CONTAINS_CBALL]) THEN + DISCH_THEN(MP_TAC o SPEC `z:complex`) THEN ASM_REWRITE_TAC[GSYM dist] THEN + MATCH_MP_TAC MONO_EXISTS THEN SIMP_TAC[EVENTUALLY_SEQUENTIALLY] THEN + ASM_MESON_TAC[SUBSET]);; + +(* ------------------------------------------------------------------------- *) +(* A version where we only have local uniform/comparative convergence. *) +(* ------------------------------------------------------------------------- *) + +let SERIES_AND_DERIVATIVE_COMPARISON_LOCAL = prove + (`!f f' s k. + open s /\ + (!n x. n IN k /\ x IN s ==> (f n has_complex_derivative f' n x) (at x)) /\ + (!x. x IN s + ==> ?d h N. &0 < d /\ (?l. (lift o h sums l) k) /\ + !n y. N <= n /\ n IN k /\ y IN ball(x,d) + ==> norm(f n y) <= h n) + ==> ?g g'. !x. x IN s + ==> ((\n. f n x) sums g x) k /\ + ((\n. f' n x) sums g' x) k /\ + (g has_complex_derivative g' x) (at x)`, + REPEAT STRIP_TAC THEN + EXISTS_TAC `\x. infsum k (\n. (f:num->complex->complex) n x)` THEN + REWRITE_TAC[GSYM SKOLEM_THM; RIGHT_EXISTS_IMP_THM] THEN + X_GEN_TAC `z:complex` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `z:complex`) THEN + ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`d:real`; `h:num->real`; `N:num`] THEN + DISCH_THEN(REPEAT_TCL CONJUNCTS_THEN ASSUME_TAC) THEN + MP_TAC(ISPECL [`f:num->complex->complex`; `f':num->complex->complex`; + `ball(z:complex,d) INTER s`; `k:num->bool`; `h:num->real`] + SERIES_AND_DERIVATIVE_COMPARISON) THEN + ASM_SIMP_TAC[OPEN_INTER; OPEN_BALL; IN_INTER] THEN + ANTS_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN + DISCH_THEN(X_CHOOSE_THEN `g:complex->complex` MP_TAC) THEN + ONCE_REWRITE_TAC[TAUT `a ==> b /\ c <=> (a ==> b) /\ (a ==> c)`] THEN + REWRITE_TAC[FORALL_AND_THM; RIGHT_EXISTS_AND_THM] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + REWRITE_TAC[GSYM SKOLEM_THM; RIGHT_AND_EXISTS_THM] THEN + DISCH_THEN(MP_TAC o SPEC `z:complex`) THEN + MATCH_MP_TAC MONO_EXISTS THEN ASM_SIMP_TAC[CENTRE_IN_BALL] THEN + X_GEN_TAC `g':complex` THEN REPEAT STRIP_TAC THENL + [ASM_MESON_TAC[SUMS_INFSUM; CENTRE_IN_BALL; summable]; ALL_TAC] THEN + MATCH_MP_TAC HAS_COMPLEX_DERIVATIVE_TRANSFORM_AT THEN + EXISTS_TAC `g:complex->complex` THEN + MP_TAC(ISPEC `ball(z:complex,d) INTER s` OPEN_CONTAINS_BALL) THEN + ASM_SIMP_TAC[OPEN_INTER; OPEN_BALL] THEN + DISCH_THEN(MP_TAC o SPEC `z:complex`) THEN + ASM_REWRITE_TAC[IN_INTER; CENTRE_IN_BALL] THEN MATCH_MP_TAC MONO_EXISTS THEN + REWRITE_TAC[SUBSET; IN_BALL; IN_INTER] THEN + ASM_MESON_TAC[INFSUM_UNIQUE; SUBSET; IN_BALL; DIST_SYM]);; + +(* ------------------------------------------------------------------------- *) +(* Sometimes convenient to compare with a complex series of +ve reals. *) +(* ------------------------------------------------------------------------- *) + +let SERIES_AND_DERIVATIVE_COMPARISON_COMPLEX = prove + (`!f f' s k. + open s /\ + (!n x. n IN k /\ x IN s ==> (f n has_complex_derivative f' n x) (at x)) /\ + (!x. x IN s + ==> ?d h N. &0 < d /\ summable k h /\ + (!n. n IN k ==> real(h n) /\ &0 <= Re(h n)) /\ + (!n y. N <= n /\ n IN k /\ y IN ball(x,d) + ==> norm(f n y) <= norm(h n))) + ==> ?g g'. !x. x IN s + ==> ((\n. f n x) sums g x) k /\ + ((\n. f' n x) sums g' x) k /\ + (g has_complex_derivative g' x) (at x)`, + REPEAT STRIP_TAC THEN + MATCH_MP_TAC SERIES_AND_DERIVATIVE_COMPARISON_LOCAL THEN + ASM_REWRITE_TAC[] THEN X_GEN_TAC `z:complex` THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `z:complex`) THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC MONO_EXISTS THEN + X_GEN_TAC `d:real` THEN ONCE_REWRITE_TAC[SWAP_EXISTS_THM] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `N:num` THEN + DISCH_THEN(X_CHOOSE_THEN `h:num->complex` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `\n. norm((h:num->complex) n)` THEN ASM_REWRITE_TAC[] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [summable]) THEN + DISCH_THEN(X_CHOOSE_THEN `l:complex` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `lift(Re l)` THEN MATCH_MP_TAC SUMS_EQ THEN + EXISTS_TAC `\i:num. lift(Re(h i))` THEN + ASM_SIMP_TAC[REAL_NORM_POS; o_DEF] THEN + REWRITE_TAC[RE_DEF] THEN MATCH_MP_TAC SERIES_COMPONENT THEN + ASM_REWRITE_TAC[DIMINDEX_2; ARITH]);; + +let SERIES_DIFFERENTIABLE_COMPARISON_COMPLEX = prove + (`!f s k. + open s /\ + (!n x. n IN k /\ x IN s ==> (f n) complex_differentiable (at x)) /\ + (!x. x IN s + ==> ?d h N. &0 < d /\ summable k h /\ + (!n. n IN k ==> real(h n) /\ &0 <= Re(h n)) /\ + (!n y. N <= n /\ n IN k /\ y IN ball(x,d) + ==> norm(f n y) <= norm(h n))) + ==> ?g. !x. x IN s + ==> ((\n. f n x) sums g x) k /\ + g complex_differentiable (at x)`, + REPEAT GEN_TAC THEN + REWRITE_TAC[complex_differentiable; RIGHT_AND_EXISTS_THM] THEN + GEN_REWRITE_TAC (PAT_CONV `\x. a /\ x /\ b ==> x` o ONCE_DEPTH_CONV) + [RIGHT_IMP_EXISTS_THM] THEN + REWRITE_TAC[SKOLEM_THM] THEN + REWRITE_TAC[RIGHT_AND_EXISTS_THM; LEFT_AND_EXISTS_THM] THEN + DISCH_THEN(CHOOSE_THEN (MP_TAC o MATCH_MP + SERIES_AND_DERIVATIVE_COMPARISON_COMPLEX)) THEN + MESON_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* In particular, a power series is analytic inside circle of convergence. *) +(* ------------------------------------------------------------------------- *) + +let POWER_SERIES_AND_DERIVATIVE_0 = prove + (`!k a r. summable k (\n. a(n) * Cx(r) pow n) + ==> ?g g'. + !z. norm(z) < r + ==> ((\n. a(n) * z pow n) sums g(z)) k /\ + ((\n. Cx(&n) * a(n) * z pow (n - 1)) sums g'(z)) k /\ + (g has_complex_derivative g' z) (at z)`, + REPEAT STRIP_TAC THEN + ASM_CASES_TAC `&0 < r` THEN + ASM_SIMP_TAC[NORM_ARITH `~(&0 < r) ==> ~(norm z < r)`] THEN + SUBGOAL_THEN `!z. norm(z) < r <=> z IN ball(Cx(&0),r)` + (fun th -> REWRITE_TAC[th]) + THENL + [REWRITE_TAC[IN_BALL; dist; COMPLEX_SUB_LZERO; NORM_NEG]; ALL_TAC] THEN + MATCH_MP_TAC SERIES_AND_DERIVATIVE_COMPARISON_COMPLEX THEN + REWRITE_TAC[OPEN_BALL; IN_BALL; dist; COMPLEX_SUB_LZERO; NORM_NEG] THEN + CONJ_TAC THENL + [REPEAT STRIP_TAC THEN COMPLEX_DIFF_TAC THEN CONV_TAC COMPLEX_RING; + ALL_TAC] THEN + X_GEN_TAC `z:complex` THEN DISCH_TAC THEN + MAP_EVERY EXISTS_TAC + [`(r - norm(z:complex)) / &2`; + `\n. Cx(norm(a(n):complex) * ((r + norm(z:complex)) / &2) pow n)`; + `0`] THEN + ASM_REWRITE_TAC[REAL_SUB_LT; REAL_HALF; REAL_CX; RE_CX] THEN + REPEAT CONJ_TAC THENL + [REWRITE_TAC[CX_MUL; CX_POW] THEN + MATCH_MP_TAC POWER_SERIES_CONV_IMP_ABSCONV_WEAK THEN + EXISTS_TAC `Cx r` THEN ASM_REWRITE_TAC[] THEN REWRITE_TAC[COMPLEX_NORM_CX]; + REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_LE_MUL THEN + REWRITE_TAC[NORM_POS_LE] THEN MATCH_MP_TAC REAL_POW_LE; + REPEAT STRIP_TAC THEN REWRITE_TAC[COMPLEX_NORM_CX; COMPLEX_NORM_MUL] THEN + REWRITE_TAC[REAL_ABS_MUL; REAL_ABS_NORM] THEN + MATCH_MP_TAC REAL_LE_LMUL THEN REWRITE_TAC[NORM_POS_LE] THEN + REWRITE_TAC[COMPLEX_NORM_POW; REAL_ABS_POW] THEN + MATCH_MP_TAC REAL_POW_LE2] THEN + ASM_NORM_ARITH_TAC);; + +let POWER_SERIES_AND_DERIVATIVE = prove + (`!k a r w. + summable k (\n. a(n) * Cx(r) pow n) + ==> ?g g'. + !z. z IN ball(w,r) + ==> ((\n. a(n) * (z - w) pow n) sums g(z)) k /\ + ((\n. Cx(&n) * a(n) * (z - w) pow (n - 1)) sums g'(z)) k /\ + (g has_complex_derivative g' z) (at z)`, + REPEAT STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o MATCH_MP POWER_SERIES_AND_DERIVATIVE_0) THEN + REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`g:complex->complex`; `g':complex->complex`] THEN + DISCH_TAC THEN + EXISTS_TAC `(\z. g(z - w)):complex->complex` THEN + EXISTS_TAC `(\z. g'(z - w)):complex->complex` THEN + REWRITE_TAC[IN_BALL; dist] THEN X_GEN_TAC `z:complex` THEN + DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC `z - w:complex`) THEN + ANTS_TAC THENL [ASM_MESON_TAC[NORM_SUB]; ALL_TAC] THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + GEN_REWRITE_TAC (RATOR_CONV o LAND_CONV) [GSYM o_DEF] THEN + GEN_REWRITE_TAC (RATOR_CONV o RAND_CONV) [GSYM COMPLEX_MUL_RID] THEN + MATCH_MP_TAC COMPLEX_DIFF_CHAIN_AT THEN ASM_REWRITE_TAC[] THEN + COMPLEX_DIFF_TAC THEN REWRITE_TAC[COMPLEX_SUB_RZERO]);; + +let POWER_SERIES_HOLOMORPHIC = prove + (`!a k f z r. (!w. w IN ball(z,r) ==> ((\n. a(n) * (w - z) pow n) sums f w) k) + ==> f holomorphic_on ball(z,r)`, + REPEAT STRIP_TAC THEN SIMP_TAC[HOLOMORPHIC_ON_OPEN; OPEN_BALL] THEN + X_GEN_TAC `w:complex` THEN REWRITE_TAC[IN_BALL; dist] THEN DISCH_TAC THEN + MP_TAC(ISPECL [`k:num->bool`; `a:num->complex`; + `(norm(z - w:complex) + r) / &2`; `z:complex`] + POWER_SERIES_AND_DERIVATIVE) THEN + ANTS_TAC THENL + [FIRST_X_ASSUM(MP_TAC o SPEC `z + Cx((norm(z - w) + r) / &2)`) THEN + REWRITE_TAC[IN_BALL; dist; COMPLEX_RING `(z + w) - z:complex = w`; + NORM_ARITH `norm(z - (z + w)) = norm w`; summable] THEN + ANTS_TAC THENL [REWRITE_TAC[COMPLEX_NORM_CX]; MESON_TAC[]] THEN + POP_ASSUM MP_TAC THEN NORM_ARITH_TAC; + ALL_TAC] THEN + DISCH_THEN(X_CHOOSE_THEN `g:complex->complex` MP_TAC) THEN + DISCH_THEN(X_CHOOSE_THEN `g':complex->complex` (LABEL_TAC "*")) THEN + EXISTS_TAC `(g':complex->complex) w` THEN + MATCH_MP_TAC HAS_COMPLEX_DERIVATIVE_TRANSFORM_AT THEN + MAP_EVERY EXISTS_TAC + [`g:complex->complex`; `(r - norm(z - w:complex)) / &2`] THEN + REPEAT CONJ_TAC THENL + [UNDISCH_TAC `norm(z - w:complex) < r` THEN NORM_ARITH_TAC; + ALL_TAC; + REMOVE_THEN "*" (MP_TAC o SPEC `w:complex`) THEN ANTS_TAC THENL + [ALL_TAC; SIMP_TAC[]] THEN REWRITE_TAC[IN_BALL] THEN + UNDISCH_TAC `norm(z - w:complex) < r` THEN NORM_ARITH_TAC] THEN + X_GEN_TAC `u:complex` THEN REWRITE_TAC[dist] THEN DISCH_TAC THEN + MATCH_MP_TAC SERIES_UNIQUE THEN + EXISTS_TAC `(\n. a(n) * (u - z) pow n):num->complex` THEN + EXISTS_TAC `k:num->bool` THEN CONJ_TAC THENL + [REMOVE_THEN "*" (MP_TAC o SPEC `u:complex`) THEN + ANTS_TAC THENL [ALL_TAC; SIMP_TAC[]]; + FIRST_X_ASSUM MATCH_MP_TAC] THEN + REWRITE_TAC[IN_BALL] THEN ASM_NORM_ARITH_TAC);; + +let HOLOMORPHIC_IFF_POWER_SERIES = prove + (`!f z r. f holomorphic_on ball(z,r) <=> + !w. w IN ball(z,r) + ==> ((\n. higher_complex_derivative n f z / Cx(&(FACT n)) * + (w - z) pow n) sums + f w) + (from 0)`, + REPEAT GEN_TAC THEN EQ_TAC THEN REPEAT STRIP_TAC THENL + [ASM_MESON_TAC[HOLOMORPHIC_POWER_SERIES]; ALL_TAC] THEN + MATCH_MP_TAC POWER_SERIES_HOLOMORPHIC THEN + MAP_EVERY EXISTS_TAC + [`\n. higher_complex_derivative n f z / Cx(&(FACT n))`; + `from 0`] THEN + ASM_REWRITE_TAC[]);; + +let POWER_SERIES_ANALYTIC = prove + (`!a k f z r. (!w. w IN ball(z,r) ==> ((\n. a(n) * (w - z) pow n) sums f w) k) + ==> f analytic_on ball(z,r)`, + SIMP_TAC[ANALYTIC_ON_OPEN; OPEN_BALL] THEN + REWRITE_TAC[POWER_SERIES_HOLOMORPHIC]);; + +let ANALYTIC_IFF_POWER_SERIES = prove + (`!f z r. f analytic_on ball(z,r) <=> + !w. w IN ball(z,r) + ==> ((\n. higher_complex_derivative n f z / Cx(&(FACT n)) * + (w - z) pow n) sums + f w) + (from 0)`, + SIMP_TAC[ANALYTIC_ON_OPEN; OPEN_BALL] THEN + REWRITE_TAC[HOLOMORPHIC_IFF_POWER_SERIES]);; + +(* ------------------------------------------------------------------------- *) +(* Equality between holomorphic functions, on open ball then connected set. *) +(* ------------------------------------------------------------------------- *) + +let HOLOMORPHIC_FUN_EQ_ON_BALL = prove + (`!f g z r w. + f holomorphic_on ball(z,r) /\ g holomorphic_on ball(z,r) /\ + w IN ball(z,r) /\ + (!n. higher_complex_derivative n f z = higher_complex_derivative n g z) + ==> f w = g w`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC SERIES_UNIQUE THEN + EXISTS_TAC `(\n. higher_complex_derivative n f z / + Cx (&(FACT n)) * (w - z) pow n)` THEN + EXISTS_TAC `(from 0)` THEN CONJ_TAC THENL [ALL_TAC; ASM_REWRITE_TAC []] THEN + ASM_MESON_TAC [HOLOMORPHIC_POWER_SERIES]);; + +let HOLOMORPHIC_FUN_EQ_0_ON_BALL = prove + (`!f z r w. + w IN ball(z,r) /\ f holomorphic_on ball(z,r) /\ + (!n. higher_complex_derivative n f z = Cx(&0)) + ==> f w = Cx(&0)`, + REPEAT STRIP_TAC THEN + SUBST1_TAC (GSYM (BETA_CONV `(\z:complex. Cx(&0)) w`)) THEN + MATCH_MP_TAC HOLOMORPHIC_FUN_EQ_ON_BALL THEN + REWRITE_TAC [HOLOMORPHIC_ON_CONST; HIGHER_COMPLEX_DERIVATIVE_CONST] THEN + ASM_MESON_TAC []);; + +let HOLOMORPHIC_FUN_EQ_0_ON_CONNECTED = prove + (`!f s z. + open s /\ connected s /\ f holomorphic_on s /\ + z IN s /\ (!n. higher_complex_derivative n f z = Cx(&0)) + ==> !w. w IN s ==> f w = Cx(&0)`, + REPEAT GEN_TAC THEN REWRITE_TAC[CONNECTED_CLOPEN] THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC + `{w | w IN s /\ !n. higher_complex_derivative n f w = Cx(&0)}`) THEN + ANTS_TAC THENL [ALL_TAC; ASM SET_TAC[higher_complex_derivative]] THEN + CONJ_TAC THENL + [MATCH_MP_TAC OPEN_SUBSET THEN CONJ_TAC THENL [SET_TAC[]; ALL_TAC] THEN + UNDISCH_TAC `open(s:complex->bool)` THEN + REWRITE_TAC[OPEN_CONTAINS_BALL; IN_ELIM_THM] THEN + MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `w:complex` THEN + DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `e:real` THEN + REWRITE_TAC[SUBSET; IN_ELIM_THM] THEN STRIP_TAC THEN ASM_SIMP_TAC[] THEN + X_GEN_TAC `u:complex` THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC HOLOMORPHIC_FUN_EQ_0_ON_BALL THEN + MAP_EVERY EXISTS_TAC [`w:complex`; `e:real`] THEN + ASM_REWRITE_TAC[] THEN CONJ_TAC THENL + [MATCH_MP_TAC HOLOMORPHIC_HIGHER_COMPLEX_DERIVATIVE THEN + ASM_MESON_TAC[HOLOMORPHIC_ON_SUBSET; OPEN_BALL; SUBSET]; + ASM_REWRITE_TAC[HIGHER_COMPLEX_DERIVATIVE_HIGHER_COMPLEX_DERIVATIVE]]; + SUBGOAL_THEN + `closed_in (subtopology euclidean s) + (INTERS (IMAGE + (\n. {w | w IN s /\ higher_complex_derivative n f w = Cx(&0)}) + (:num)))` + MP_TAC THENL + [MATCH_MP_TAC CLOSED_IN_INTERS THEN + REWRITE_TAC[IMAGE_EQ_EMPTY; UNIV_NOT_EMPTY] THEN + REWRITE_TAC[FORALL_IN_IMAGE; IN_UNIV] THEN X_GEN_TAC `n:num` THEN + MATCH_MP_TAC CONTINUOUS_CLOSED_IN_PREIMAGE_CONSTANT THEN + MATCH_MP_TAC HOLOMORPHIC_ON_IMP_CONTINUOUS_ON THEN SIMP_TAC[ETA_AX] THEN + MATCH_MP_TAC HOLOMORPHIC_HIGHER_COMPLEX_DERIVATIVE THEN + ASM_REWRITE_TAC[]; + MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN + SIMP_TAC[INTERS; IN_IMAGE; IN_UNIV; LEFT_IMP_EXISTS_THM; IN_ELIM_THM] THEN + ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN + REWRITE_TAC[LEFT_FORALL_IMP_THM; EXISTS_REFL] THEN SET_TAC[]]]);; + +let HOLOMORPHIC_FUN_EQ_ON_CONNECTED = prove + (`!f g z s w. + open s /\ connected s /\ f holomorphic_on s /\ g holomorphic_on s /\ + w IN s /\ z IN s /\ + (!n. higher_complex_derivative n f z = higher_complex_derivative n g z) + ==> f w = g w`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`\z. (f:complex->complex) z - g z`; `s:complex->bool`; + `z:complex`] HOLOMORPHIC_FUN_EQ_0_ON_CONNECTED) THEN + ASM_REWRITE_TAC[RIGHT_IMP_FORALL_THM; HOLOMORPHIC_ON_SUB] THEN + DISCH_THEN(MP_TAC o SPEC `w:complex`) THEN + ASM_REWRITE_TAC[COMPLEX_SUB_0] THEN DISCH_THEN MATCH_MP_TAC THEN + ASM_SIMP_TAC[HOLOMORPHIC_ON_SUB] THEN + MP_TAC(ISPECL [`f:complex->complex`; `g:complex->complex`; `s:complex->bool`] + HIGHER_COMPLEX_DERIVATIVE_SUB) THEN + ASM_SIMP_TAC[COMPLEX_SUB_0]);; + +let HOLOMORPHIC_FUN_EQ_CONST_ON_CONNECTED = prove + (`!f s z. + open s /\ + connected s /\ + f holomorphic_on s /\ + z IN s /\ + (!n. 0 < n ==> higher_complex_derivative n f z = Cx (&0)) + ==> !w. w IN s ==> f w = f z`, + REPEAT STRIP_TAC THEN MP_TAC(ISPECL + [`\w. (f:complex->complex) w - f z`; `s:complex->bool`; `z:complex`] + HOLOMORPHIC_FUN_EQ_0_ON_CONNECTED) THEN + ASM_REWRITE_TAC[COMPLEX_SUB_0; RIGHT_IMP_FORALL_THM; IMP_IMP] THEN + DISCH_THEN MATCH_MP_TAC THEN + ASM_SIMP_TAC[HOLOMORPHIC_ON_SUB; HOLOMORPHIC_ON_CONST] THEN + X_GEN_TAC `n:num` THEN ASM_CASES_TAC `n = 0` THEN + ASM_REWRITE_TAC[higher_complex_derivative; COMPLEX_SUB_REFL] THEN + MP_TAC(ISPECL + [`f:complex->complex`; `(\w. f(z:complex)):complex->complex`; + `s:complex->bool`; `n:num`; `z:complex`] + HIGHER_COMPLEX_DERIVATIVE_SUB) THEN + ASM_REWRITE_TAC[HOLOMORPHIC_ON_CONST] THEN DISCH_THEN SUBST1_TAC THEN + ASM_SIMP_TAC[LE_1; HIGHER_COMPLEX_DERIVATIVE_CONST; COMPLEX_SUB_REFL]);; + +(* ------------------------------------------------------------------------- *) +(* Some basic lemmas about poles/singularities. *) +(* ------------------------------------------------------------------------- *) + +let POLE_LEMMA = prove + (`!f s a. + f holomorphic_on s /\ a IN interior(s) + ==> (\z. if z = a then complex_derivative f a + else (f(z) - f(a)) / (z - a)) holomorphic_on s`, + REPEAT STRIP_TAC THEN SUBGOAL_THEN `(a:complex) IN s` ASSUME_TAC THENL + [ASM_MESON_TAC[INTERIOR_SUBSET; SUBSET]; ALL_TAC] THEN + SUBGOAL_THEN + `!z. z IN s /\ ~(z = a) + ==> (\z. if z = a then complex_derivative f a + else (f(z) - f(a)) / (z - a)) + complex_differentiable (at z within s)` + ASSUME_TAC THENL + [REPEAT STRIP_TAC THEN + MATCH_MP_TAC COMPLEX_DIFFERENTIABLE_TRANSFORM_WITHIN THEN + EXISTS_TAC `\z:complex. (f(z) - f(a)) / (z - a)` THEN + EXISTS_TAC `dist(a:complex,z)` THEN ASM_SIMP_TAC[DIST_POS_LT] THEN + CONJ_TAC THENL + [X_GEN_TAC `w:complex` THEN COND_CASES_TAC THEN + ASM_REWRITE_TAC[REAL_LT_REFL] THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `w:complex`) THEN ASM_REWRITE_TAC[] THEN + REPEAT(POP_ASSUM MP_TAC) THEN CONV_TAC COMPLEX_FIELD; + MATCH_MP_TAC COMPLEX_DIFFERENTIABLE_DIV_WITHIN THEN + ASM_REWRITE_TAC[COMPLEX_SUB_0] THEN CONJ_TAC THEN + MATCH_MP_TAC COMPLEX_DIFFERENTIABLE_SUB THEN + REWRITE_TAC[COMPLEX_DIFFERENTIABLE_CONST; COMPLEX_DIFFERENTIABLE_ID] THEN + ASM_MESON_TAC[holomorphic_on; complex_differentiable]]; + ALL_TAC] THEN + REWRITE_TAC[holomorphic_on; GSYM complex_differentiable] THEN + X_GEN_TAC `z:complex` THEN DISCH_TAC THEN + ASM_CASES_TAC `z:complex = a` THENL [ALL_TAC; ASM_SIMP_TAC[]] THEN + FIRST_X_ASSUM SUBST_ALL_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_INTERIOR]) THEN + DISCH_THEN(X_CHOOSE_THEN `e:real` STRIP_ASSUME_TAC) THEN + MATCH_MP_TAC COMPLEX_DIFFERENTIABLE_AT_WITHIN THEN + SUBGOAL_THEN + `(\z. if z = a then complex_derivative f a else (f z - f a) / (z - a)) + holomorphic_on ball(a,e)` + MP_TAC THENL + [ALL_TAC; + ASM_SIMP_TAC[HOLOMORPHIC_ON_OPEN; OPEN_BALL; GSYM complex_differentiable; + CENTRE_IN_BALL; COMPLEX_DIFFERENTIABLE_AT_WITHIN]] THEN + MATCH_MP_TAC NO_ISOLATED_SINGULARITY THEN + EXISTS_TAC `{a:complex}` THEN SIMP_TAC[OPEN_BALL; FINITE_RULES] THEN + MATCH_MP_TAC(TAUT `b /\ (b ==> a) ==> a /\ b`) THEN CONJ_TAC THENL + [MATCH_MP_TAC HOLOMORPHIC_ON_SUBSET THEN + EXISTS_TAC `s DELETE (a:complex)` THEN + ASM_SIMP_TAC[SET_RULE `b SUBSET s ==> b DIFF {a} SUBSET s DELETE a`] THEN + ASM_SIMP_TAC[holomorphic_on; GSYM complex_differentiable; IN_DELETE] THEN + REPEAT STRIP_TAC THEN + MATCH_MP_TAC COMPLEX_DIFFERENTIABLE_WITHIN_SUBSET THEN + EXISTS_TAC `s:complex->bool` THEN ASM_SIMP_TAC[] THEN SET_TAC[]; + ALL_TAC] THEN + SIMP_TAC[HOLOMORPHIC_ON_OPEN; CONTINUOUS_ON_EQ_CONTINUOUS_AT; + OPEN_DIFF; FINITE_IMP_CLOSED; OPEN_BALL; FINITE_INSERT; + FINITE_RULES; GSYM complex_differentiable] THEN + REWRITE_TAC[IN_DIFF; IN_BALL; IN_SING] THEN + MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `w:complex` THEN + ASM_CASES_TAC `w:complex = a` THENL + [ALL_TAC; ASM_SIMP_TAC[COMPLEX_DIFFERENTIABLE_IMP_CONTINUOUS_AT]] THEN + FIRST_X_ASSUM SUBST_ALL_TAC THEN REWRITE_TAC[] THEN + SUBGOAL_THEN `f holomorphic_on ball(a,e)` MP_TAC THENL + [ASM_MESON_TAC[HOLOMORPHIC_ON_SUBSET]; ALL_TAC] THEN + ASM_SIMP_TAC[HOLOMORPHIC_ON_OPEN; OPEN_BALL] THEN + REWRITE_TAC[GSYM complex_differentiable; IN_BALL] THEN + DISCH_THEN(MP_TAC o SPEC `a:complex`) THEN + ASM_REWRITE_TAC[GSYM HAS_COMPLEX_DERIVATIVE_DIFFERENTIABLE] THEN + MATCH_MP_TAC MONO_IMP THEN REWRITE_TAC[] THEN + REWRITE_TAC[HAS_COMPLEX_DERIVATIVE_AT; CONTINUOUS_AT] THEN + MATCH_MP_TAC(REWRITE_RULE[TAUT `a /\ b /\ c ==> d <=> a /\ b ==> c ==> d`] + LIM_TRANSFORM_AT) THEN + EXISTS_TAC `&1` THEN REWRITE_TAC[GSYM DIST_NZ; REAL_LT_01] THEN + X_GEN_TAC `u:complex` THEN STRIP_TAC THEN ASM_REWRITE_TAC[]);; + +let POLE_LEMMA_OPEN = prove + (`!f s a. + open s /\ f holomorphic_on s + ==> (\z. if z = a + then complex_derivative f a + else (f z - f a) / (z - a)) holomorphic_on s`, + REPEAT STRIP_TAC THEN ASM_CASES_TAC `(a:complex) IN s` THENL + [MATCH_MP_TAC POLE_LEMMA THEN ASM_SIMP_TAC[INTERIOR_OPEN]; + ALL_TAC] THEN + REWRITE_TAC[holomorphic_on; GSYM complex_differentiable] THEN + X_GEN_TAC `z:complex` THEN DISCH_TAC THEN + MATCH_MP_TAC COMPLEX_DIFFERENTIABLE_TRANSFORM_WITHIN THEN + MAP_EVERY EXISTS_TAC [`\z:complex. (f(z) - f(a)) / (z - a)`; `&1`] THEN + ASM_REWRITE_TAC[REAL_LT_01] THEN + CONJ_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN + MATCH_MP_TAC COMPLEX_DIFFERENTIABLE_DIV_WITHIN THEN + ASM_REWRITE_TAC[COMPLEX_SUB_0; CONJ_ASSOC] THEN + CONJ_TAC THENL [CONJ_TAC; ASM_MESON_TAC[]] THEN + MATCH_MP_TAC COMPLEX_DIFFERENTIABLE_SUB THEN + REWRITE_TAC[COMPLEX_DIFFERENTIABLE_CONST; COMPLEX_DIFFERENTIABLE_ID] THEN + ASM_MESON_TAC[holomorphic_on; complex_differentiable]);; + +let POLE_THEOREM = prove + (`!f g s a. + g holomorphic_on s /\ a IN interior(s) /\ + (!z. z IN s /\ ~(z = a) ==> g(z) = (z - a) * f(z)) + ==> (\z. if z = a then complex_derivative g a + else f(z) - g(a) / (z - a)) holomorphic_on s`, + REPEAT GEN_TAC THEN REWRITE_TAC[CONJ_ASSOC] THEN + DISCH_THEN(CONJUNCTS_THEN ASSUME_TAC) THEN + FIRST_ASSUM(MP_TAC o MATCH_MP POLE_LEMMA) THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] HOLOMORPHIC_TRANSFORM) THEN + X_GEN_TAC `z:complex` THEN DISCH_TAC THEN REWRITE_TAC[] THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN + FIRST_X_ASSUM(MP_TAC o SPEC `z:complex` o last o CONJUNCTS) THEN + ASM_REWRITE_TAC[] THEN REPEAT(POP_ASSUM MP_TAC) THEN + CONV_TAC COMPLEX_FIELD);; + +let POLE_THEOREM_OPEN = prove + (`!f g s a. + open s /\ g holomorphic_on s /\ + (!z. z IN s /\ ~(z = a) ==> g(z) = (z - a) * f(z)) + ==> (\z. if z = a then complex_derivative g a + else f(z) - g(a) / (z - a)) holomorphic_on s`, + REPEAT GEN_TAC THEN REWRITE_TAC[CONJ_ASSOC] THEN + DISCH_THEN(CONJUNCTS_THEN ASSUME_TAC) THEN + FIRST_ASSUM(MP_TAC o SPEC `a:complex` o MATCH_MP POLE_LEMMA_OPEN) THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] HOLOMORPHIC_TRANSFORM) THEN + X_GEN_TAC `z:complex` THEN DISCH_TAC THEN REWRITE_TAC[] THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN + FIRST_X_ASSUM(MP_TAC o SPEC `z:complex` o last o CONJUNCTS) THEN + ASM_REWRITE_TAC[] THEN REPEAT(POP_ASSUM MP_TAC) THEN + CONV_TAC COMPLEX_FIELD);; + +let POLE_THEOREM_0 = prove + (`!f g s a. + g holomorphic_on s /\ a IN interior(s) /\ + (!z. z IN s /\ ~(z = a) ==> g(z) = (z - a) * f(z)) /\ + f a = complex_derivative g a /\ g(a) = Cx(&0) + ==> f holomorphic_on s`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN + `(\z. if z = a then complex_derivative g a + else f(z) - g(a) / (z - a)) holomorphic_on s` + MP_TAC THENL [ASM_SIMP_TAC[POLE_THEOREM]; ALL_TAC] THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] HOLOMORPHIC_TRANSFORM) THEN + X_GEN_TAC `z:complex` THEN DISCH_TAC THEN REWRITE_TAC[] THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[complex_div] THEN + CONV_TAC COMPLEX_RING);; + +let POLE_THEOREM_OPEN_0 = prove + (`!f g s a. + open s /\ g holomorphic_on s /\ + (!z. z IN s /\ ~(z = a) ==> g(z) = (z - a) * f(z)) /\ + f a = complex_derivative g a /\ g(a) = Cx(&0) + ==> f holomorphic_on s`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN + `(\z. if z = a then complex_derivative g a + else f(z) - g(a) / (z - a)) holomorphic_on s` + MP_TAC THENL [ASM_SIMP_TAC[POLE_THEOREM_OPEN]; ALL_TAC] THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] HOLOMORPHIC_TRANSFORM) THEN + X_GEN_TAC `z:complex` THEN DISCH_TAC THEN REWRITE_TAC[] THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[complex_div] THEN + CONV_TAC COMPLEX_RING);; + +let POLE_THEOREM_ANALYTIC = prove + (`!f g s a. + g analytic_on s /\ + (!z. z IN s + ==> ?d. &0 < d /\ + !w. w IN ball(z,d) /\ ~(w = a) ==> g(w) = (w - a) * f(w)) + ==> (\z. if z = a then complex_derivative g a + else f(z) - g(a) / (z - a)) analytic_on s`, + REPEAT GEN_TAC THEN REWRITE_TAC[analytic_on] THEN + DISCH_THEN(CONJUNCTS_THEN2 (LABEL_TAC "A") (LABEL_TAC "B")) THEN + X_GEN_TAC `z:complex` THEN DISCH_TAC THEN + REMOVE_THEN "A" (MP_TAC o SPEC `z:complex`) THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `e:real` STRIP_ASSUME_TAC) THEN + FIRST_X_ASSUM(MP_TAC o SPEC `z:complex`) THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `min (d:real) e` THEN ASM_REWRITE_TAC[REAL_LT_MIN] THEN + MATCH_MP_TAC POLE_THEOREM_OPEN THEN + ASM_SIMP_TAC[BALL_MIN_INTER; OPEN_BALL; IN_INTER] THEN + ASM_MESON_TAC[HOLOMORPHIC_ON_SUBSET; INTER_SUBSET]);; + +let POLE_THEOREM_ANALYTIC_0 = prove + (`!f g s a. + g analytic_on s /\ + (!z. z IN s + ==> ?d. &0 < d /\ + !w. w IN ball(z,d) /\ ~(w = a) + ==> g(w) = (w - a) * f(w)) /\ + f a = complex_derivative g a /\ g(a) = Cx(&0) + ==> f analytic_on s`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN + `(\z. if z = a then complex_derivative g a + else f(z) - g(a) / (z - a)) analytic_on s` + MP_TAC THENL [ASM_SIMP_TAC[POLE_THEOREM_ANALYTIC]; ALL_TAC] THEN + MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_TERM_TAC THEN + REWRITE_TAC[FUN_EQ_THM] THEN GEN_TAC THEN COND_CASES_TAC THEN + ASM_REWRITE_TAC[complex_div] THEN CONV_TAC COMPLEX_RING);; + +let POLE_THEOREM_ANALYTIC_OPEN_SUPERSET = prove + (`!f g s a t. + s SUBSET t /\ open t /\ g analytic_on s /\ + (!z. z IN t /\ ~(z = a) ==> g(z) = (z - a) * f(z)) + ==> (\z. if z = a then complex_derivative g a + else f(z) - g(a) / (z - a)) analytic_on s`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC POLE_THEOREM_ANALYTIC THEN + ASM_MESON_TAC[OPEN_CONTAINS_BALL; SUBSET]);; + +let POLE_THEOREM_ANALYTIC_OPEN_SUPERSET_0 = prove + (`!f g s a t. + s SUBSET t /\ open t /\ g analytic_on s /\ + (!z. z IN t /\ ~(z = a) ==> g(z) = (z - a) * f(z)) /\ + f a = complex_derivative g a /\ g(a) = Cx(&0) + ==> f analytic_on s`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN + `(\z. if z = a then complex_derivative g a + else f(z) - g(a) / (z - a)) analytic_on s` + MP_TAC THENL + [MATCH_MP_TAC POLE_THEOREM_ANALYTIC_OPEN_SUPERSET THEN ASM_MESON_TAC[]; + ALL_TAC] THEN + MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_TERM_TAC THEN + REWRITE_TAC[FUN_EQ_THM] THEN GEN_TAC THEN COND_CASES_TAC THEN + ASM_REWRITE_TAC[complex_div] THEN CONV_TAC COMPLEX_RING);; + +let HOLOMORPHIC_ON_EXTEND_LIM,HOLOMORPHIC_ON_EXTEND_BOUNDED = + (CONJ_PAIR o prove) + (`(!f a s. + f holomorphic_on (s DELETE a) /\ a IN interior s + ==> ((?g. g holomorphic_on s /\ (!z. z IN s DELETE a ==> g z = f z)) <=> + ((\z. (z - a) * f(z)) --> Cx(&0)) (at a))) /\ + (!f a s. + f holomorphic_on (s DELETE a) /\ a IN interior s + ==> ((?g. g holomorphic_on s /\ (!z. z IN s DELETE a ==> g z = f z)) <=> + (?B. eventually (\z. norm(f z) <= B) (at a))))`, + REWRITE_TAC[AND_FORALL_THM] THEN + REWRITE_TAC[TAUT `(p ==> q) /\ (p ==> r) <=> (p ==> q /\ r)`] THEN + REPEAT GEN_TAC THEN STRIP_TAC THEN MATCH_MP_TAC(TAUT + `(p ==> r) /\ (r ==> q) /\ (q ==> p) ==> (p <=> q) /\ (p <=> r)`) THEN + REPEAT CONJ_TAC THENL + [REWRITE_TAC[IN_DELETE] THEN DISCH_THEN(X_CHOOSE_THEN `g:complex->complex` + (CONJUNCTS_THEN2 + (MP_TAC o MATCH_MP HOLOMORPHIC_ON_IMP_CONTINUOUS_ON) ASSUME_TAC)) THEN + DISCH_THEN(MP_TAC o SPEC `interior s:complex->bool` o + MATCH_MP(REWRITE_RULE[IMP_CONJ] CONTINUOUS_ON_SUBSET)) THEN + REWRITE_TAC[INTERIOR_SUBSET; CONTINUOUS_ON] THEN + DISCH_THEN(MP_TAC o SPEC `a:complex`) THEN + ASM_SIMP_TAC[LIM_WITHIN_OPEN; OPEN_INTERIOR; tendsto] THEN + DISCH_THEN(MP_TAC o SPEC `&1`) THEN REWRITE_TAC[REAL_LT_01] THEN + DISCH_THEN(fun th -> EXISTS_TAC `norm((g:complex->complex) a) + &1` THEN + MP_TAC th) THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] EVENTUALLY_MP) THEN + FIRST_ASSUM(fun th -> + REWRITE_TAC[GSYM(MATCH_MP EVENTUALLY_WITHIN_INTERIOR th)]) THEN + ASM_SIMP_TAC[EVENTUALLY_WITHIN; GSYM DIST_NZ] THEN + EXISTS_TAC `&1` THEN CONV_TAC NORM_ARITH; + DISCH_THEN(X_CHOOSE_THEN `B:real` STRIP_ASSUME_TAC) THEN + MATCH_MP_TAC LIM_NULL_COMPLEX_RMUL_BOUNDED THEN + SUBST1_TAC(COMPLEX_RING `Cx(&0) = a - a`) THEN + SIMP_TAC[LIM_AT_ID; LIM_CONST; LIM_SUB] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (ONCE_REWRITE_RULE[IMP_CONJ_ALT] + EVENTUALLY_MONO)) THEN + SIMP_TAC[]; + DISCH_TAC THEN ABBREV_TAC `h = \z. (z - a) pow 2 * f z` THEN + SUBGOAL_THEN `(h has_complex_derivative Cx(&0)) (at a)` ASSUME_TAC THENL + [EXPAND_TAC "h" THEN REWRITE_TAC[HAS_COMPLEX_DERIVATIVE_AT] THEN + MATCH_MP_TAC LIM_TRANSFORM_AT THEN + MAP_EVERY EXISTS_TAC [`\z:complex. (z - a) * f z`; `&1`] THEN + ASM_SIMP_TAC[REAL_LT_01; GSYM DIST_NZ] THEN CONV_TAC COMPLEX_FIELD; + ALL_TAC] THEN + SUBGOAL_THEN `h holomorphic_on s` ASSUME_TAC THENL + [REWRITE_TAC[holomorphic_on; GSYM complex_differentiable] THEN + X_GEN_TAC `z:complex` THEN DISCH_TAC THEN + ASM_CASES_TAC `z:complex = a` THENL + [ASM_MESON_TAC[complex_differentiable; COMPLEX_DIFFERENTIABLE_AT_WITHIN]; + ALL_TAC] THEN + EXPAND_TAC "h" THEN MATCH_MP_TAC COMPLEX_DIFFERENTIABLE_MUL_WITHIN THEN + CONJ_TAC THENL [COMPLEX_DIFFERENTIABLE_TAC; ALL_TAC] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [holomorphic_on]) THEN + DISCH_THEN(MP_TAC o SPEC `z:complex`) THEN + ASM_REWRITE_TAC[IN_DELETE; complex_differentiable] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `b:complex` THEN + REWRITE_TAC[HAS_COMPLEX_DERIVATIVE_WITHIN] THEN + MATCH_MP_TAC EQ_IMP THEN MATCH_MP_TAC LIM_TRANSFORM_WITHIN_SET THEN + REWRITE_TAC[EVENTUALLY_AT] THEN EXISTS_TAC `dist(a:complex,z)` THEN + ASM_REWRITE_TAC[IN_DELETE; NORM_ARITH `&0 < dist(a,b) <=> ~(a = b)`] THEN + MESON_TAC[REAL_LT_REFL]; + MP_TAC(SPECL [`h:complex->complex`; `s:complex->bool`; `a:complex`] + POLE_LEMMA) THEN ASM_REWRITE_TAC[] THEN + ABBREV_TAC + `g = \z. if z = a then complex_derivative h a + else (h z - h a) / (z - a)` THEN + DISCH_TAC THEN + EXISTS_TAC + `\z. if z = a then complex_derivative g a + else (g z - g a) / (z - a)` THEN + ASM_SIMP_TAC[POLE_LEMMA; IN_DELETE] THEN EXPAND_TAC "g" THEN + FIRST_ASSUM(fun th -> + REWRITE_TAC[MATCH_MP HAS_COMPLEX_DERIVATIVE_DERIVATIVE th]) THEN + SIMP_TAC[COMPLEX_SUB_RZERO] THEN + EXPAND_TAC "h" THEN SIMP_TAC[] THEN CONV_TAC COMPLEX_FIELD]]);; + +(* ------------------------------------------------------------------------- *) +(* General, homology form of Cauchy's theorem. Proof is based on Dixon's, *) +(* as presented in Lang's "Complex Analysis" book. *) +(* ------------------------------------------------------------------------- *) + +let CAUCHY_INTEGRAL_FORMULA_GLOBAL = prove + (`!f s g z. + open s /\ f holomorphic_on s /\ z IN s /\ + valid_path g /\ pathfinish g = pathstart g /\ + path_image g SUBSET s DELETE z /\ + (!w. ~(w IN s) ==> winding_number(g,w) = Cx(&0)) + ==> ((\w. f(w) / (w - z)) has_path_integral + (Cx(&2) * Cx(pi) * ii * winding_number(g,z) * f(z))) g`, + MATCH_MP_TAC(MESON[] + `((!f s g. vector_polynomial_function g ==> P f s g) ==> !f s g. P f s g) /\ + (!f s g. vector_polynomial_function g ==> P f s g) + ==> !f s g. P f s g`) THEN + CONJ_TAC THENL + [REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`s DELETE (z:complex)`; `g:real^1->complex`] + PATH_INTEGRAL_NEARBY_ENDS) THEN + ASM_SIMP_TAC[VALID_PATH_IMP_PATH; OPEN_DELETE] THEN + DISCH_THEN(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC) THEN + MP_TAC(ISPECL [`g:real^1->complex`; `d:real`] + PATH_APPROX_VECTOR_POLYNOMIAL_FUNCTION) THEN + ASM_SIMP_TAC[VALID_PATH_IMP_PATH] THEN + DISCH_THEN(X_CHOOSE_THEN `p:real^1->complex` STRIP_ASSUME_TAC) THEN + FIRST_X_ASSUM(MP_TAC o SPECL + [`g:real^1->complex`; `p:real^1->complex`]) THEN + ASM_SIMP_TAC[VECTOR_SUB_REFL; NORM_0; + VALID_PATH_VECTOR_POLYNOMIAL_FUNCTION] THEN + STRIP_TAC THEN FIRST_X_ASSUM(MP_TAC o SPECL + [`f:complex->complex`; `s:complex->bool`; `p:real^1->complex`]) THEN + ASM_REWRITE_TAC[] THEN DISCH_THEN(MP_TAC o SPEC `z:complex`) THEN + SUBGOAL_THEN + `winding_number(p,z) = winding_number(g,z) /\ + !w. ~(w IN s) ==> winding_number(p,w) = winding_number(g,w)` + (fun th -> SIMP_TAC[th]) + THENL + [FIRST_X_ASSUM(K ALL_TAC o SPEC `z:complex`) THEN + REPEAT(FIRST_X_ASSUM(STRIP_ASSUME_TAC o MATCH_MP (SET_RULE + `g SUBSET s DELETE z + ==> ~(z IN g) /\ (!y. ~(y IN s) ==> ~(y IN g))`))) THEN + ASM_SIMP_TAC[WINDING_NUMBER_VALID_PATH; + VALID_PATH_VECTOR_POLYNOMIAL_FUNCTION] THEN + REPEAT STRIP_TAC THEN AP_TERM_TAC THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN + REWRITE_TAC[complex_div; COMPLEX_MUL_LID] THEN + MATCH_MP_TAC HOLOMORPHIC_ON_INV THEN + SIMP_TAC[HOLOMORPHIC_ON_SUB; HOLOMORPHIC_ON_ID; HOLOMORPHIC_ON_CONST; + IN_DELETE; COMPLEX_SUB_0] THEN ASM SET_TAC[]; + ALL_TAC] THEN + ASM_SIMP_TAC[VALID_PATH_VECTOR_POLYNOMIAL_FUNCTION] THEN + MATCH_MP_TAC(MESON[HAS_PATH_INTEGRAL_INTEGRAL; path_integrable_on; + PATH_INTEGRAL_UNIQUE] + `f path_integrable_on g /\ path_integral p f = path_integral g f + ==> (f has_path_integral y) p ==> (f has_path_integral y) g`) THEN + CONJ_TAC THENL + [MATCH_MP_TAC PATH_INTEGRABLE_HOLOMORPHIC_SIMPLE THEN + EXISTS_TAC `s DELETE (z:complex)` THEN ASM_SIMP_TAC[OPEN_DELETE]; + FIRST_X_ASSUM MATCH_MP_TAC] THEN + MATCH_MP_TAC HOLOMORPHIC_ON_DIV THEN + SIMP_TAC[HOLOMORPHIC_ON_SUB; HOLOMORPHIC_ON_ID; HOLOMORPHIC_ON_CONST; + IN_DELETE; COMPLEX_SUB_0] THEN + ASM_MESON_TAC[HOLOMORPHIC_ON_SUBSET; DELETE_SUBSET]; + ALL_TAC] THEN + MAP_EVERY X_GEN_TAC + [`f:complex->complex`; `u:complex->bool`; `g:real^1->complex`] THEN + DISCH_TAC THEN X_GEN_TAC `z:complex` THEN STRIP_TAC THEN + FIRST_ASSUM(X_CHOOSE_THEN `g':real^1->complex` STRIP_ASSUME_TAC o + MATCH_MP HAS_VECTOR_DERIVATIVE_VECTOR_POLYNOMIAL_FUNCTION) THEN + SUBGOAL_THEN + `bounded(IMAGE (g':real^1->complex) (interval[vec 0,vec 1]))` + MP_TAC THENL + [MATCH_MP_TAC COMPACT_IMP_BOUNDED THEN + MATCH_MP_TAC COMPACT_CONTINUOUS_IMAGE THEN + REWRITE_TAC[COMPACT_INTERVAL] THEN + ASM_MESON_TAC[CONTINUOUS_VECTOR_POLYNOMIAL_FUNCTION; + CONTINUOUS_AT_IMP_CONTINUOUS_ON]; + REWRITE_TAC[BOUNDED_POS; FORALL_IN_IMAGE] THEN + DISCH_THEN(X_CHOOSE_THEN `B:real` STRIP_ASSUME_TAC)] THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP VALID_PATH_IMP_PATH) THEN + MAP_EVERY ABBREV_TAC + [`d = \z w. if w = z then complex_derivative f z + else (f(w) - f(z)) / (w - z)`; + `v = {w | ~(w IN path_image g) /\ winding_number(g,w) = Cx(&0)}`] THEN + SUBGOAL_THEN `open(v:complex->bool)` ASSUME_TAC THENL + [EXPAND_TAC "v" THEN MATCH_MP_TAC OPEN_WINDING_NUMBER_LEVELSETS THEN + ASM_REWRITE_TAC[]; + ALL_TAC] THEN + SUBGOAL_THEN `u UNION v = (:complex)` ASSUME_TAC THENL + [ASM SET_TAC[]; ALL_TAC] THEN + SUBGOAL_THEN `!y:complex. y IN u ==> (d y) holomorphic_on u` ASSUME_TAC THENL + [X_GEN_TAC `y:complex` THEN STRIP_TAC THEN EXPAND_TAC "d" THEN + MATCH_MP_TAC NO_ISOLATED_SINGULARITY THEN EXISTS_TAC `{y:complex}` THEN + ASM_REWRITE_TAC[FINITE_SING] THEN CONJ_TAC THENL + [ASM_SIMP_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_AT] THEN + X_GEN_TAC `w:complex` THEN DISCH_TAC THEN + ASM_CASES_TAC `w:complex = y` THENL + [UNDISCH_THEN `w:complex = y` SUBST_ALL_TAC THEN + REWRITE_TAC[CONTINUOUS_AT] THEN + MATCH_MP_TAC LIM_TRANSFORM_AWAY_AT THEN + EXISTS_TAC `\w:complex. (f w - f y) / (w - y)` THEN SIMP_TAC[] THEN + EXISTS_TAC `y + Cx(&1)` THEN + CONJ_TAC THENL [CONV_TAC COMPLEX_RING; ALL_TAC] THEN + REWRITE_TAC[GSYM HAS_COMPLEX_DERIVATIVE_AT] THEN + REWRITE_TAC[HAS_COMPLEX_DERIVATIVE_DIFFERENTIABLE] THEN + ASM_MESON_TAC[HOLOMORPHIC_ON_IMP_DIFFERENTIABLE_AT]; + MATCH_MP_TAC COMPLEX_DIFFERENTIABLE_IMP_CONTINUOUS_AT]; + ASM_SIMP_TAC[HOLOMORPHIC_ON_OPEN; OPEN_DELETE; IN_DELETE; + SET_RULE `s DIFF {x} = s DELETE x`; GSYM complex_differentiable] THEN + X_GEN_TAC `w:complex` THEN STRIP_TAC] THEN + MATCH_MP_TAC COMPLEX_DIFFERENTIABLE_TRANSFORM_AT THEN + EXISTS_TAC `\w:complex. (f w - f y) / (w - y)` THEN + EXISTS_TAC `dist(w:complex,y)` THEN ASM_SIMP_TAC[DIST_POS_LT] THEN + (CONJ_TAC THENL [MESON_TAC[DIST_SYM; REAL_LT_REFL]; ALL_TAC]) THEN + MATCH_MP_TAC COMPLEX_DIFFERENTIABLE_DIV_AT THEN + ASM_REWRITE_TAC[COMPLEX_SUB_0] THEN CONJ_TAC THEN + MATCH_MP_TAC COMPLEX_DIFFERENTIABLE_SUB THEN + ASM_SIMP_TAC[ETA_AX; COMPLEX_DIFFERENTIABLE_CONST; + COMPLEX_DIFFERENTIABLE_ID] THEN + ASM_MESON_TAC[HOLOMORPHIC_ON_IMP_DIFFERENTIABLE_AT]; + ALL_TAC] THEN + SUBGOAL_THEN + `!y. ~(y IN path_image g) + ==> (\x. (f x - f y) / (x - y)) path_integrable_on g` + ASSUME_TAC THENL + [X_GEN_TAC `y:complex` THEN DISCH_TAC THEN + MATCH_MP_TAC PATH_INTEGRABLE_HOLOMORPHIC_SIMPLE THEN + EXISTS_TAC `u DELETE (y:complex)` THEN ASM_SIMP_TAC[OPEN_DELETE] THEN + CONJ_TAC THENL [ALL_TAC; ASM SET_TAC[]] THEN + MATCH_MP_TAC HOLOMORPHIC_ON_DIV THEN + SIMP_TAC[IN_DELETE; COMPLEX_SUB_0] THEN + CONJ_TAC THEN MATCH_MP_TAC HOLOMORPHIC_ON_SUB THEN + ASM_REWRITE_TAC[HOLOMORPHIC_ON_CONST; HOLOMORPHIC_ON_ID] THEN + MATCH_MP_TAC HOLOMORPHIC_ON_SUBSET THEN + EXISTS_TAC `u:complex->bool` THEN ASM_REWRITE_TAC[DELETE_SUBSET]; + ALL_TAC] THEN + SUBGOAL_THEN + `!y:complex. d y path_integrable_on g` + ASSUME_TAC THENL + [X_GEN_TAC `y:complex` THEN + ASM_CASES_TAC `(y:complex) IN path_image g` THENL + [MATCH_MP_TAC PATH_INTEGRABLE_HOLOMORPHIC_SIMPLE THEN + EXISTS_TAC `u:complex->bool` THEN ASM_SIMP_TAC[] THEN ASM SET_TAC[]; + MATCH_MP_TAC PATH_INTEGRABLE_EQ THEN + EXISTS_TAC `\x:complex. (f x - f y) / (x - y)` THEN + ASM_SIMP_TAC[] THEN EXPAND_TAC "d" THEN ASM_MESON_TAC[]]; + ALL_TAC] THEN + SUBGOAL_THEN + `?h. (!z. z IN u ==> ((d z) has_path_integral h(z)) g) /\ + (!z. z IN v ==> ((\w. f(w) / (w - z)) has_path_integral h(z)) g)` + (CHOOSE_THEN (CONJUNCTS_THEN2 (LABEL_TAC "u") (LABEL_TAC "v"))) + THENL + [EXISTS_TAC `\z. if z IN u then path_integral g (d z) + else path_integral g (\w. f(w) / (w - z))` THEN + SIMP_TAC[] THEN CONJ_TAC THEN X_GEN_TAC `w:complex` THEN DISCH_TAC THENL + [ASM_MESON_TAC[HAS_PATH_INTEGRAL_INTEGRAL]; ALL_TAC] THEN + ASM_CASES_TAC `(w:complex) IN u` THEN ASM_REWRITE_TAC[] THENL + [ALL_TAC; + MATCH_MP_TAC HAS_PATH_INTEGRAL_INTEGRAL THEN + MATCH_MP_TAC PATH_INTEGRABLE_HOLOMORPHIC_SIMPLE THEN + EXISTS_TAC `u:complex->bool` THEN ASM_SIMP_TAC[] THEN CONJ_TAC THENL + [MATCH_MP_TAC HOLOMORPHIC_ON_DIV THEN + ASM_SIMP_TAC[COMPLEX_SUB_0; HOLOMORPHIC_ON_SUB; HOLOMORPHIC_ON_CONST; + HOLOMORPHIC_ON_ID] THEN + ASM_MESON_TAC[]; + ASM SET_TAC[]]] THEN + MATCH_MP_TAC HAS_PATH_INTEGRAL_EQ THEN + EXISTS_TAC `\x:complex. (f x - f w) / (x - w) + f(w) / (x - w)` THEN + CONJ_TAC THENL + [X_GEN_TAC `x:complex` THEN DISCH_TAC THEN REWRITE_TAC[] THEN + SIMPLE_COMPLEX_ARITH_TAC; + ALL_TAC] THEN + GEN_REWRITE_TAC LAND_CONV [GSYM COMPLEX_ADD_RID] THEN + MATCH_MP_TAC HAS_PATH_INTEGRAL_ADD THEN + UNDISCH_TAC `(w:complex) IN v` THEN EXPAND_TAC "v" THEN + REWRITE_TAC[IN_ELIM_THM] THEN REPEAT STRIP_TAC THENL + [MATCH_MP_TAC(MESON[PATH_INTEGRAL_UNIQUE; HAS_PATH_INTEGRAL_INTEGRAL; + path_integrable_on; PATH_INTEGRAL_EQ; PATH_INTEGRABLE_EQ] + `g path_integrable_on p /\ + (!x. x IN path_image p ==> f x = g x) + ==> (f has_path_integral path_integral p g) p`) THEN + ASM_REWRITE_TAC[] THEN EXPAND_TAC "d" THEN ASM_MESON_TAC[]; + SUBGOAL_THEN + `Cx(&0) = (f w) * Cx(&2) * Cx pi * ii * winding_number(g,w)` + SUBST1_TAC THENL [ASM_REWRITE_TAC[COMPLEX_MUL_RZERO]; ALL_TAC] THEN + ONCE_REWRITE_TAC[SIMPLE_COMPLEX_ARITH `x / y = x * Cx(&1) / y`] THEN + MATCH_MP_TAC HAS_PATH_INTEGRAL_COMPLEX_LMUL THEN + MATCH_MP_TAC HAS_PATH_INTEGRAL_WINDING_NUMBER THEN + ASM_REWRITE_TAC[]]; + ALL_TAC] THEN + SUBGOAL_THEN `!z. (h:complex->complex) z = Cx(&0)` ASSUME_TAC THENL + [ALL_TAC; + REMOVE_THEN "u" (MP_TAC o SPEC `z:complex`) THEN ASM_REWRITE_TAC[] THEN + EXPAND_TAC "d" THEN REWRITE_TAC[] THEN + DISCH_THEN(MP_TAC o SPEC `\w. (f w - f z) / (w - z)` o + MATCH_MP (REWRITE_RULE[IMP_CONJ_ALT] HAS_PATH_INTEGRAL_EQ)) THEN + REWRITE_TAC[] THEN ANTS_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + MP_TAC(SPECL [`g:real^1->complex`; `z:complex`] + HAS_PATH_INTEGRAL_WINDING_NUMBER) THEN ASM_REWRITE_TAC[] THEN + ANTS_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + DISCH_THEN(MP_TAC o MATCH_MP HAS_PATH_INTEGRAL_COMPLEX_RMUL) THEN + DISCH_THEN(MP_TAC o SPEC `(f:complex->complex) z`) THEN + REWRITE_TAC[IMP_IMP] THEN + DISCH_THEN(MP_TAC o MATCH_MP HAS_PATH_INTEGRAL_ADD) THEN + REWRITE_TAC[complex_div; COMPLEX_ADD_RID; COMPLEX_RING + `(Cx(&1) * i) * fz + (fx - fz) * i = fx * i`] THEN + REWRITE_TAC[GSYM COMPLEX_MUL_ASSOC]] THEN + UNDISCH_THEN `(z:complex) IN u` (K ALL_TAC) THEN + FIRST_X_ASSUM(ASSUME_TAC o MATCH_MP (SET_RULE + `p SUBSET u DELETE z ==> p SUBSET u`)) THEN + POP_ASSUM_LIST(MP_TAC o end_itlist CONJ o rev) THEN STRIP_TAC THEN + MATCH_MP_TAC LIOUVILLE_WEAK THEN + MATCH_MP_TAC(TAUT `b /\ (b ==> a) ==> a /\ b`) THEN CONJ_TAC THENL + [SUBGOAL_THEN + `?t:complex->bool. + compact t /\ path_image g SUBSET interior t /\ t SUBSET u` + STRIP_ASSUME_TAC THENL + [SUBGOAL_THEN + `?dd. &0 < dd /\ + {y + k | y IN path_image g /\ k IN ball(vec 0,dd)} SUBSET u` + STRIP_ASSUME_TAC THENL + [ASM_CASES_TAC `u = (:complex)` THENL + [EXISTS_TAC `&1` THEN ASM_REWRITE_TAC[REAL_LT_01; SUBSET_UNIV]; + ALL_TAC] THEN + MP_TAC(ISPECL [`path_image g:complex->bool`; `(:complex) DIFF u`] + SEPARATE_COMPACT_CLOSED) THEN + ASM_SIMP_TAC[COMPACT_PATH_IMAGE; GSYM OPEN_CLOSED] THEN + ANTS_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + DISCH_THEN(X_CHOOSE_THEN `dd:real` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `dd / &2` THEN ASM_REWRITE_TAC[REAL_HALF] THEN + REWRITE_TAC[SUBSET; FORALL_IN_GSPEC] THEN + MAP_EVERY X_GEN_TAC [`y:complex`; `k:complex`] THEN + MATCH_MP_TAC(TAUT `(a /\ ~c ==> ~b) ==> a /\ b ==> c`) THEN + STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`y:complex`; `y + k:complex`]) THEN + ASM_REWRITE_TAC[IN_DIFF; IN_UNIV; IN_BALL] THEN CONV_TAC NORM_ARITH; + ALL_TAC] THEN + EXISTS_TAC `{y + k:complex | + y IN path_image g /\ k IN cball(vec 0,dd / &2)}` THEN + ASM_SIMP_TAC[COMPACT_SUMS; COMPACT_PATH_IMAGE; COMPACT_CBALL] THEN + CONJ_TAC THENL + [REWRITE_TAC[SUBSET; IN_INTERIOR; IN_ELIM_THM] THEN + X_GEN_TAC `y:complex` THEN DISCH_TAC THEN + EXISTS_TAC `dd / &2` THEN ASM_REWRITE_TAC[REAL_HALF] THEN + X_GEN_TAC `x:complex` THEN REWRITE_TAC[IN_BALL] THEN DISCH_TAC THEN + MAP_EVERY EXISTS_TAC [`y:complex`; `x - y:complex`] THEN + ASM_REWRITE_TAC[IN_CBALL] THEN + UNDISCH_TAC `dist(y:complex,x) < dd / &2` THEN CONV_TAC NORM_ARITH; + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE + `{x + y:real^N | x IN s /\ y IN t} SUBSET u + ==> t' SUBSET t ==> {x + y | x IN s /\ y IN t'} SUBSET u`)) THEN + REWRITE_TAC[SUBSET; IN_BALL; IN_CBALL] THEN + UNDISCH_TAC `&0 < dd` THEN CONV_TAC NORM_ARITH]; + ALL_TAC] THEN + MP_TAC(ISPECL [`interior t:complex->bool`; `g:real^1->complex`] + PATH_INTEGRAL_BOUND_EXISTS) THEN + ASM_REWRITE_TAC[OPEN_INTERIOR] THEN + DISCH_THEN(X_CHOOSE_THEN `L:real` STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN `bounded(IMAGE (f:complex->complex) t)` MP_TAC THENL + [MATCH_MP_TAC COMPACT_IMP_BOUNDED THEN + MATCH_MP_TAC COMPACT_CONTINUOUS_IMAGE THEN + ASM_MESON_TAC[HOLOMORPHIC_ON_IMP_CONTINUOUS_ON; CONTINUOUS_ON_SUBSET]; + REWRITE_TAC[BOUNDED_POS; FORALL_IN_IMAGE] THEN + DISCH_THEN(X_CHOOSE_THEN `D:real` STRIP_ASSUME_TAC)] THEN + FIRST_ASSUM(MP_TAC o MATCH_MP COMPACT_IMP_BOUNDED) THEN + REWRITE_TAC[BOUNDED_POS] THEN + DISCH_THEN(X_CHOOSE_THEN `C:real` STRIP_ASSUME_TAC) THEN + REWRITE_TAC[LIM_AT_INFINITY] THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN + EXISTS_TAC `(D * L) / (e / &2) + C:real` THEN REWRITE_TAC[real_ge] THEN + X_GEN_TAC `y:complex` THEN DISCH_TAC THEN + REWRITE_TAC[dist; COMPLEX_SUB_RZERO] THEN + SUBGOAL_THEN `h y = path_integral g (\w. f w / (w - y))` SUBST1_TAC THENL + [CONV_TAC SYM_CONV THEN MATCH_MP_TAC PATH_INTEGRAL_UNIQUE THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN EXPAND_TAC "v" THEN + REWRITE_TAC[IN_ELIM_THM] THEN CONJ_TAC THENL + [DISCH_TAC THEN + UNDISCH_TAC `(D * L) / (e / &2) + C <= norm(y:complex)` THEN + MATCH_MP_TAC(REAL_ARITH `&0 < d /\ x <= c ==> d + c <= x ==> F`) THEN + ASM_SIMP_TAC[REAL_LT_MUL; REAL_LT_DIV; REAL_HALF] THEN + ASM_MESON_TAC[INTERIOR_SUBSET; SUBSET]; + MATCH_MP_TAC WINDING_NUMBER_ZERO_OUTSIDE THEN + EXISTS_TAC `cball(Cx(&0),C)` THEN + ASM_REWRITE_TAC[CONVEX_CBALL; SUBSET; IN_CBALL; dist; + COMPLEX_SUB_LZERO; NORM_NEG] THEN + CONJ_TAC THENL [ALL_TAC; ASM_MESON_TAC[INTERIOR_SUBSET; SUBSET]] THEN + UNDISCH_TAC `(D * L) / (e / &2) + C <= norm(y:complex)` THEN + MATCH_MP_TAC(REAL_ARITH `&0 < d ==> d + c <= x ==> ~(x <= c)`) THEN + ASM_SIMP_TAC[REAL_LT_MUL; REAL_LT_DIV; REAL_HALF]]; + ALL_TAC] THEN + MATCH_MP_TAC REAL_LET_TRANS THEN EXISTS_TAC `L * (e / &2 / L)` THEN + CONJ_TAC THENL + [ALL_TAC; + ASM_SIMP_TAC[REAL_DIV_LMUL; REAL_LT_IMP_NZ; REAL_HALF] THEN + ASM_REAL_ARITH_TAC] THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN REWRITE_TAC[] THEN CONJ_TAC THENL + [MATCH_MP_TAC HOLOMORPHIC_ON_DIV THEN CONJ_TAC THENL + [ASM_MESON_TAC[HOLOMORPHIC_ON_SUBSET; SUBSET_TRANS; INTERIOR_SUBSET]; + SIMP_TAC[HOLOMORPHIC_ON_SUB; HOLOMORPHIC_ON_ID; + HOLOMORPHIC_ON_CONST; COMPLEX_SUB_0]] THEN + X_GEN_TAC `w:complex` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (NORM_ARITH + `d + c <= norm y ==> &0 < d /\ norm w <= c ==> ~(w = y)`)) THEN + ASM_SIMP_TAC[REAL_LT_MUL; REAL_LT_DIV; REAL_HALF] THEN + ASM_MESON_TAC[SUBSET; INTERIOR_SUBSET]; + ALL_TAC] THEN + X_GEN_TAC `w:complex` THEN DISCH_TAC THEN SIMP_TAC[COMPLEX_NORM_DIV] THEN + SUBGOAL_THEN `&0 < norm(w - y)` ASSUME_TAC THENL + [FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (NORM_ARITH + `d + c <= norm y ==> &0 < d /\ norm w <= c ==> &0 < norm(w - y)`)) THEN + ASM_SIMP_TAC[REAL_LT_MUL; REAL_LT_DIV; REAL_HALF] THEN + ASM_MESON_TAC[SUBSET; INTERIOR_SUBSET]; + ASM_SIMP_TAC[REAL_LE_LDIV_EQ]] THEN + MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC `D:real` THEN CONJ_TAC THENL + [ASM_MESON_TAC[SUBSET; INTERIOR_SUBSET]; ALL_TAC] THEN + REWRITE_TAC[REAL_ARITH `e / &2 / L * x = (x * (e / &2)) / L`] THEN + ASM_SIMP_TAC[REAL_LE_RDIV_EQ; GSYM REAL_LE_LDIV_EQ; REAL_HALF] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (NORM_ARITH + `d + c <= norm y ==> norm w <= c ==> d <= norm(w - y)`)) THEN + ASM_MESON_TAC[SUBSET; INTERIOR_SUBSET]; + DISCH_TAC] THEN + SUBGOAL_THEN + `(\y. (d:complex->complex->complex) (fstcart y) (sndcart y)) continuous_on + {pastecart x z | x IN u /\ z IN u}` + ASSUME_TAC THENL + [REWRITE_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN] THEN EXPAND_TAC "d" THEN + REWRITE_TAC[FORALL_IN_GSPEC; continuous_within; IMP_CONJ] THEN + MAP_EVERY X_GEN_TAC [`x:complex`; `z:complex`] THEN REPEAT DISCH_TAC THEN + X_GEN_TAC `e:real` THEN DISCH_TAC THEN + REWRITE_TAC[FSTCART_PASTECART; SNDCART_PASTECART; FORALL_PASTECART] THEN + REWRITE_TAC[dist; IMP_IMP; GSYM CONJ_ASSOC; PASTECART_SUB] THEN + ASM_CASES_TAC `z:complex = x` THEN ASM_REWRITE_TAC[] THENL + [UNDISCH_THEN `z:complex = x` (SUBST_ALL_TAC o SYM); + SUBGOAL_THEN + `(\y. (f(sndcart y) - f(fstcart y)) / (sndcart y - fstcart y)) + continuous at (pastecart x z)` + MP_TAC THENL + [MATCH_MP_TAC CONTINUOUS_COMPLEX_DIV_AT THEN + ASM_SIMP_TAC[FSTCART_PASTECART; SNDCART_PASTECART; COMPLEX_SUB_0] THEN + CONJ_TAC THEN MATCH_MP_TAC CONTINUOUS_SUB THEN + SIMP_TAC[LINEAR_CONTINUOUS_AT; LINEAR_FSTCART; LINEAR_SNDCART] THEN + CONJ_TAC THEN GEN_REWRITE_TAC LAND_CONV [GSYM o_DEF] THEN + MATCH_MP_TAC CONTINUOUS_AT_COMPOSE THEN + SIMP_TAC[LINEAR_CONTINUOUS_AT; LINEAR_FSTCART; LINEAR_SNDCART] THEN + REWRITE_TAC[FSTCART_PASTECART; SNDCART_PASTECART] THEN + ASM_MESON_TAC[HOLOMORPHIC_ON_IMP_CONTINUOUS_ON; + CONTINUOUS_ON_EQ_CONTINUOUS_AT]; + ALL_TAC] THEN + REWRITE_TAC[continuous_at; dist; FORALL_PASTECART] THEN + REWRITE_TAC[FSTCART_PASTECART; SNDCART_PASTECART; PASTECART_SUB] THEN + DISCH_THEN(MP_TAC o SPEC `e:real`) THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `k1:real` STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN + `open({pastecart x z | x IN u /\ z IN u} DIFF + {y | y IN UNIV /\ fstcart y - sndcart y = Cx(&0)})` + MP_TAC THENL + [MATCH_MP_TAC OPEN_DIFF THEN + ASM_SIMP_TAC[REWRITE_RULE[PCROSS] OPEN_PCROSS] THEN + MATCH_MP_TAC CONTINUOUS_CLOSED_PREIMAGE_CONSTANT THEN + REWRITE_TAC[CLOSED_UNIV] THEN MATCH_MP_TAC CONTINUOUS_ON_SUB THEN + SIMP_TAC[LINEAR_CONTINUOUS_ON; LINEAR_FSTCART; LINEAR_SNDCART]; + SIMP_TAC[OPEN_CONTAINS_BALL; IN_DIFF; IMP_CONJ; FORALL_IN_GSPEC] THEN + DISCH_THEN(MP_TAC o SPECL [`x:complex`; `z:complex`]) THEN + ASM_REWRITE_TAC[IN_ELIM_THM; IN_UNIV; COMPLEX_SUB_0] THEN + ASM_REWRITE_TAC[SUBSET; IN_BALL; FORALL_PASTECART; IN_DIFF; + IN_ELIM_PASTECART_THM; FSTCART_PASTECART; SNDCART_PASTECART] THEN + REWRITE_TAC[IN_ELIM_THM; IMP_IMP; GSYM CONJ_ASSOC] THEN + REWRITE_TAC[ONCE_REWRITE_RULE[NORM_SUB] dist; PASTECART_SUB; + FSTCART_PASTECART; SNDCART_PASTECART] THEN + DISCH_THEN(X_CHOOSE_THEN `k2:real` STRIP_ASSUME_TAC)] THEN + EXISTS_TAC `min k1 k2:real` THEN + ASM_SIMP_TAC[REAL_LT_MIN; COMPLEX_NORM_NZ; COMPLEX_SUB_0]] THEN + SUBGOAL_THEN `(complex_derivative f) continuous at z` MP_TAC THENL + [MATCH_MP_TAC CONTINUOUS_ON_INTERIOR THEN + EXISTS_TAC `u:complex->bool` THEN ASM_SIMP_TAC[INTERIOR_OPEN] THEN + MATCH_MP_TAC HOLOMORPHIC_ON_IMP_CONTINUOUS_ON THEN + MATCH_MP_TAC HOLOMORPHIC_COMPLEX_DERIVATIVE THEN + ASM_REWRITE_TAC[]; + REWRITE_TAC[continuous_at] THEN DISCH_THEN(MP_TAC o SPEC `e / &2`) THEN + ASM_REWRITE_TAC[dist; REAL_HALF]] THEN + DISCH_THEN(X_CHOOSE_THEN `k1:real` STRIP_ASSUME_TAC) THEN + MP_TAC(ISPEC `u:complex->bool` OPEN_CONTAINS_BALL) THEN + ASM_REWRITE_TAC[] THEN DISCH_THEN(MP_TAC o SPEC `z:complex`) THEN + ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `k2:real` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `min k1 k2:real` THEN ASM_REWRITE_TAC[REAL_LT_MIN] THEN + MAP_EVERY X_GEN_TAC [`x':complex`; `z':complex`] THEN STRIP_TAC THEN + MATCH_MP_TAC(REAL_ARITH `&0 < e /\ x <= e / &2 ==> x < e`) THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[] THENL + [ASM_MESON_TAC[NORM_LE_PASTECART; REAL_LET_TRANS; REAL_LT_IMP_LE]; + ALL_TAC] THEN + SUBGOAL_THEN `e / &2 = e / &2 / norm(z' - x') * norm(z' - x':complex)` + SUBST1_TAC THENL + [ASM_SIMP_TAC[REAL_DIV_RMUL; NORM_EQ_0; VECTOR_SUB_EQ]; ALL_TAC] THEN + MATCH_MP_TAC HAS_PATH_INTEGRAL_BOUND_LINEPATH THEN + EXISTS_TAC `\u. (complex_derivative f u - complex_derivative f z) / + (z' - x')` THEN + ASM_SIMP_TAC[REAL_LE_DIV; NORM_POS_LE; REAL_LT_IMP_LE; REAL_HALF] THEN + CONJ_TAC THENL + [ASM_SIMP_TAC[COMPLEX_FIELD + `~(z:complex = x) + ==> a / (z - x) - b = (a - b * (z - x)) / (z - x)`] THEN + MATCH_MP_TAC HAS_PATH_INTEGRAL_COMPLEX_DIV THEN + MATCH_MP_TAC HAS_PATH_INTEGRAL_SUB THEN + REWRITE_TAC[HAS_PATH_INTEGRAL_CONST_LINEPATH] THEN + MP_TAC(ISPECL [`f:complex->complex`; `complex_derivative f`; + `linepath(x':complex,z')`; `u:complex->bool`] + PATH_INTEGRAL_PRIMITIVE) THEN + REWRITE_TAC[ETA_AX; PATHSTART_LINEPATH; PATHFINISH_LINEPATH] THEN + DISCH_THEN MATCH_MP_TAC THEN + REWRITE_TAC[VALID_PATH_LINEPATH] THEN CONJ_TAC THENL + [ASM_MESON_TAC[HAS_COMPLEX_DERIVATIVE_DIFFERENTIABLE; + GSYM HOLOMORPHIC_ON_DIFFERENTIABLE; + HAS_COMPLEX_DERIVATIVE_AT_WITHIN; HOLOMORPHIC_ON_OPEN; + complex_differentiable]; + MATCH_MP_TAC SUBSET_TRANS THEN EXISTS_TAC `ball(z:complex,k2)`]; + X_GEN_TAC `w:complex` THEN DISCH_TAC THEN + REWRITE_TAC[COMPLEX_NORM_DIV; real_div] THEN + MATCH_MP_TAC REAL_LE_RMUL THEN + REWRITE_TAC[REAL_LE_INV_EQ; NORM_POS_LE] THEN + MATCH_MP_TAC(REAL_ARITH `x < e / &2 ==> x <= e * inv(&2)`) THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN + REWRITE_TAC[REWRITE_RULE[ONCE_REWRITE_RULE[NORM_SUB] dist] + (GSYM IN_BALL)] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE + `w IN s ==> s SUBSET t ==> w IN t`))] THEN + ASM_REWRITE_TAC[PATH_IMAGE_LINEPATH; SEGMENT_CONVEX_HULL] THEN + MATCH_MP_TAC HULL_MINIMAL THEN REWRITE_TAC[CONVEX_BALL] THEN + REWRITE_TAC[INSERT_SUBSET; EMPTY_SUBSET; IN_BALL; dist] THEN + ONCE_REWRITE_TAC[NORM_SUB] THEN + ASM_MESON_TAC[NORM_LE_PASTECART; REAL_LET_TRANS]; + ALL_TAC] THEN + SIMP_TAC[HOLOMORPHIC_ON_OPEN; OPEN_UNIV; IN_UNIV; + GSYM complex_differentiable] THEN + X_GEN_TAC `z0:complex` THEN ASM_CASES_TAC `(z0:complex) IN v` THENL + [MP_TAC(ISPECL + [`f:complex->complex`; `h:complex->complex`; `g:real^1->complex`; + `v:complex->bool`; `1`; `B:real`] + CAUCHY_NEXT_DERIVATIVE) THEN + ASM_SIMP_TAC[IN_DIFF; ARITH_EQ; COMPLEX_POW_1] THEN ANTS_TAC THENL + [CONJ_TAC THENL + [ASM_MESON_TAC[HAS_VECTOR_DERIVATIVE_UNIQUE_AT]; ALL_TAC] THEN + MATCH_MP_TAC HOLOMORPHIC_ON_IMP_CONTINUOUS_ON THEN + MATCH_MP_TAC HOLOMORPHIC_ON_SUBSET THEN + EXISTS_TAC `u:complex->bool` THEN ASM SET_TAC[]; + DISCH_THEN(MP_TAC o SPEC `z0:complex`) THEN + UNDISCH_TAC `(z0:complex) IN v` THEN EXPAND_TAC "v" THEN + SIMP_TAC[IN_ELIM_THM; complex_differentiable] THEN MESON_TAC[]]; + ALL_TAC] THEN + SUBGOAL_THEN `(z0:complex) IN u` ASSUME_TAC THENL + [ASM SET_TAC[]; ALL_TAC] THEN + MP_TAC(ISPEC `u:complex->bool` OPEN_CONTAINS_BALL) THEN + ASM_REWRITE_TAC[] THEN DISCH_THEN(MP_TAC o SPEC `z0:complex`) THEN + ASM_SIMP_TAC[] THEN DISCH_THEN(X_CHOOSE_THEN `e:real` STRIP_ASSUME_TAC) THEN + MATCH_MP_TAC HOLOMORPHIC_ON_IMP_DIFFERENTIABLE_AT THEN + EXISTS_TAC `ball(z0:complex,e)` THEN + ASM_REWRITE_TAC[OPEN_BALL; CENTRE_IN_BALL] THEN + MATCH_MP_TAC ANALYTIC_IMP_HOLOMORPHIC THEN MATCH_MP_TAC MORERA_TRIANGLE THEN + REWRITE_TAC[OPEN_BALL] THEN + SUBGOAL_THEN `(h:complex->complex) continuous_on u` ASSUME_TAC THENL + [REWRITE_TAC[CONTINUOUS_ON_SEQUENTIALLY] THEN + MAP_EVERY X_GEN_TAC [`a:num->complex`; `x:complex`] THEN STRIP_TAC THEN + MP_TAC(ISPECL + [`sequentially`; `\n:num x. (d:complex->complex->complex) (a n) x`; + `B:real`; `g:real^1->complex`; `(d:complex->complex->complex) x`] + PATH_INTEGRAL_UNIFORM_LIMIT) THEN + ASM_REWRITE_TAC[TRIVIAL_LIMIT_SEQUENTIALLY; ETA_AX; EVENTUALLY_TRUE] THEN + ANTS_TAC THENL + [ALL_TAC; + MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN BINOP_TAC THEN + REWRITE_TAC[FUN_EQ_THM; o_THM] THEN REPEAT GEN_TAC THEN + MATCH_MP_TAC PATH_INTEGRAL_UNIQUE THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[]] THEN + CONJ_TAC THENL + [ASM_MESON_TAC[HAS_VECTOR_DERIVATIVE_UNIQUE_AT]; ALL_TAC] THEN + X_GEN_TAC `ee:real` THEN DISCH_TAC THEN + MP_TAC(ISPEC `u:complex->bool` OPEN_CONTAINS_CBALL) THEN + ASM_REWRITE_TAC[] THEN DISCH_THEN(MP_TAC o SPEC `x:complex`) THEN + ASM_SIMP_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `dd:real` STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN + `(\y. (d:complex->complex->complex) (fstcart y) (sndcart y)) + uniformly_continuous_on + {pastecart w z | w IN cball(x,dd) /\ z IN path_image g}` + MP_TAC THENL + [MATCH_MP_TAC COMPACT_UNIFORMLY_CONTINUOUS THEN + ASM_SIMP_TAC[REWRITE_RULE[PCROSS] COMPACT_PCROSS; COMPACT_CBALL; + COMPACT_VALID_PATH_IMAGE] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET)) THEN + REWRITE_TAC[SUBSET; FORALL_IN_GSPEC; IN_ELIM_PASTECART_THM] THEN + ASM SET_TAC[]; + ALL_TAC] THEN + REWRITE_TAC[uniformly_continuous_on] THEN + DISCH_THEN(MP_TAC o SPEC `ee:real`) THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `kk:real` + (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + DISCH_THEN(MP_TAC o GENL [`w:complex`; `z:complex`] o + SPECL [`pastecart (x:complex) (z:complex)`; + `pastecart (w:complex) (z:complex)`]) THEN + SIMP_TAC[IN_ELIM_PASTECART_THM; FSTCART_PASTECART; SNDCART_PASTECART] THEN + ASM_SIMP_TAC[CENTRE_IN_CBALL; REAL_LT_IMP_LE; dist; PASTECART_SUB] THEN + REWRITE_TAC[VECTOR_SUB_REFL; NORM_0; NORM_PASTECART] THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN + REWRITE_TAC[TAUT `b /\ (a /\ b) /\ c ==> d <=> a /\ b /\ c ==> d`] THEN + SIMP_TAC[REAL_ADD_RID; POW_2_SQRT; NORM_POS_LE] THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [LIM_SEQUENTIALLY]) THEN + DISCH_THEN(MP_TAC o SPEC `min dd kk:real`) THEN + ASM_REWRITE_TAC[EVENTUALLY_SEQUENTIALLY; REAL_LT_MIN] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `N:num` THEN + REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_SIMP_TAC[ONCE_REWRITE_RULE[DIST_SYM] IN_CBALL; GSYM dist; + REAL_LT_IMP_LE]; + ALL_TAC] THEN + CONJ_TAC THENL [ASM_MESON_TAC[CONTINUOUS_ON_SUBSET]; ALL_TAC] THEN + + SUBGOAL_THEN + `!w. w IN u ==> (\z. d z w) holomorphic_on u` + ASSUME_TAC THENL + [EXPAND_TAC "d" THEN X_GEN_TAC `y:complex` THEN STRIP_TAC THEN + MATCH_MP_TAC NO_ISOLATED_SINGULARITY THEN EXISTS_TAC `{y:complex}` THEN + ASM_REWRITE_TAC[FINITE_SING] THEN CONJ_TAC THENL + [SUBGOAL_THEN + `((\y. (d:complex->complex->complex) (fstcart y) (sndcart y)) o + (\z. pastecart y z)) + continuous_on u` + MP_TAC THENL + [MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN + SIMP_TAC[CONTINUOUS_ON_PASTECART; CONTINUOUS_ON_ID; + CONTINUOUS_ON_CONST] 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; IN_ELIM_PASTECART_THM]; + EXPAND_TAC "d" THEN + REWRITE_TAC[o_DEF; FSTCART_PASTECART; SNDCART_PASTECART] THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] CONTINUOUS_ON_EQ) THEN + GEN_TAC THEN REWRITE_TAC[] THEN COND_CASES_TAC THEN + ASM_REWRITE_TAC[] THEN + DISCH_TAC THEN REWRITE_TAC[complex_div] THEN MATCH_MP_TAC(COMPLEX_RING + `x':complex = --x /\ y' = --y ==> x * y = x' * y'`) THEN + REWRITE_TAC[GSYM COMPLEX_INV_NEG; COMPLEX_NEG_SUB]]; + ASM_SIMP_TAC[HOLOMORPHIC_ON_OPEN; OPEN_DELETE; IN_DELETE; + SET_RULE `s DIFF {x} = s DELETE x`; GSYM complex_differentiable] THEN + X_GEN_TAC `w:complex` THEN STRIP_TAC THEN + MATCH_MP_TAC COMPLEX_DIFFERENTIABLE_TRANSFORM_AT THEN + EXISTS_TAC `\w:complex. (f y - f w) / (y - w)` THEN + EXISTS_TAC `dist(w:complex,y)` THEN ASM_SIMP_TAC[DIST_POS_LT] THEN + (CONJ_TAC THENL [MESON_TAC[DIST_SYM; REAL_LT_REFL]; ALL_TAC]) THEN + MATCH_MP_TAC COMPLEX_DIFFERENTIABLE_DIV_AT THEN + ASM_REWRITE_TAC[COMPLEX_SUB_0] THEN CONJ_TAC THEN + MATCH_MP_TAC COMPLEX_DIFFERENTIABLE_SUB THEN + ASM_SIMP_TAC[ETA_AX; COMPLEX_DIFFERENTIABLE_CONST; + COMPLEX_DIFFERENTIABLE_ID] THEN + ASM_MESON_TAC[HOLOMORPHIC_ON_IMP_DIFFERENTIABLE_AT]]; + ALL_TAC] THEN + SUBGOAL_THEN + `!w a b:complex. w IN u /\ segment[a,b] SUBSET u + ==> (\z. d z w) path_integrable_on (linepath(a,b))` + ASSUME_TAC THENL + [REPEAT STRIP_TAC THEN + MATCH_MP_TAC PATH_INTEGRABLE_CONTINUOUS_LINEPATH THEN + ASM_MESON_TAC[CONTINUOUS_ON_SUBSET; HOLOMORPHIC_ON_IMP_CONTINUOUS_ON]; + ALL_TAC] THEN + SUBGOAL_THEN + `!a b:complex. + segment[a,b] SUBSET u + ==> (\w. path_integral (linepath(a,b)) (\z. d z w)) + continuous_on u` + ASSUME_TAC THENL + [REPEAT STRIP_TAC THEN ASM_CASES_TAC `a:complex = b` THENL + [ASM_SIMP_TAC[PATH_INTEGRAL_TRIVIAL; CONTINUOUS_ON_CONST]; ALL_TAC] THEN + REWRITE_TAC[continuous_on] THEN X_GEN_TAC `w:complex` THEN DISCH_TAC THEN + X_GEN_TAC `ee:real` THEN DISCH_TAC THEN + ASM_SIMP_TAC[dist; GSYM PATH_INTEGRAL_SUB] THEN + MP_TAC(ISPEC `u:complex->bool` OPEN_CONTAINS_CBALL) THEN + ASM_REWRITE_TAC[] THEN DISCH_THEN(MP_TAC o SPEC `w:complex`) THEN + ASM_SIMP_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `dd:real` STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN + `(\y. (d:complex->complex->complex) (fstcart y) (sndcart y)) + uniformly_continuous_on + {pastecart z t | z IN segment[a,b] /\ t IN cball(w,dd)}` + MP_TAC THENL + [MATCH_MP_TAC COMPACT_UNIFORMLY_CONTINUOUS THEN + ASM_SIMP_TAC[REWRITE_RULE[PCROSS] COMPACT_PCROSS; + COMPACT_CBALL; COMPACT_SEGMENT] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET)) THEN + REWRITE_TAC[SUBSET; FORALL_IN_GSPEC; IN_ELIM_PASTECART_THM] THEN + ASM SET_TAC[]; + ALL_TAC] THEN + REWRITE_TAC[uniformly_continuous_on] THEN + DISCH_THEN(MP_TAC o SPEC `ee / &2 / norm(b - a:complex)`) THEN + ASM_SIMP_TAC[REAL_HALF; REAL_LT_DIV; COMPLEX_NORM_NZ; COMPLEX_SUB_0] THEN + DISCH_THEN(X_CHOOSE_THEN `kk:real` + (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + DISCH_THEN(MP_TAC o GENL [`z:complex`; `r:complex`] o + SPECL [`pastecart (r:complex) (z:complex)`; + `pastecart (r:complex) (w:complex)`]) THEN + SIMP_TAC[IN_ELIM_PASTECART_THM; FSTCART_PASTECART; SNDCART_PASTECART] THEN + ASM_SIMP_TAC[CENTRE_IN_CBALL; REAL_LT_IMP_LE; dist; PASTECART_SUB] THEN + REWRITE_TAC[VECTOR_SUB_REFL; NORM_0; NORM_PASTECART] THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN + REWRITE_TAC[TAUT `(a /\ b) /\ a /\ c ==> d <=> a /\ b /\ c ==> d`] THEN + SIMP_TAC[REAL_ADD_LID; POW_2_SQRT; NORM_POS_LE] THEN DISCH_TAC THEN + EXISTS_TAC `min dd kk:real` THEN ASM_REWRITE_TAC[REAL_LT_MIN] THEN + X_GEN_TAC `x:complex` THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC(REAL_ARITH `&0 < e /\ x <= e / &2 ==> x < e`) THEN + ASM_REWRITE_TAC[] THEN + SUBGOAL_THEN `ee / &2 = ee / &2 / norm(b - a) * norm(b - a:complex)` + SUBST1_TAC THENL + [ASM_SIMP_TAC[REAL_DIV_RMUL; NORM_EQ_0; VECTOR_SUB_EQ]; ALL_TAC] THEN + MATCH_MP_TAC HAS_PATH_INTEGRAL_BOUND_LINEPATH THEN + EXISTS_TAC `\r. (d:complex->complex->complex) r x - d r w` THEN + ASM_SIMP_TAC[REAL_LE_DIV; NORM_POS_LE; REAL_LT_IMP_LE; REAL_HALF] THEN + CONJ_TAC THENL + [MATCH_MP_TAC HAS_PATH_INTEGRAL_INTEGRAL THEN + MATCH_MP_TAC PATH_INTEGRABLE_SUB THEN ASM_SIMP_TAC[]; + REPEAT STRIP_TAC THEN GEN_REWRITE_TAC LAND_CONV [NORM_SUB] THEN + MATCH_MP_TAC REAL_LT_IMP_LE THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_REWRITE_TAC[IN_CBALL; dist] THEN + ASM_MESON_TAC[NORM_SUB; REAL_LT_IMP_LE]]; + ALL_TAC] THEN + SUBGOAL_THEN + `!a b. segment[a,b] SUBSET u + ==> (\w. path_integral (linepath (a,b)) (\z. d z w)) + path_integrable_on g` + ASSUME_TAC THENL + [REPEAT STRIP_TAC THEN REWRITE_TAC[PATH_INTEGRABLE_ON] THEN + MATCH_MP_TAC INTEGRABLE_CONTINUOUS THEN + MATCH_MP_TAC CONTINUOUS_ON_COMPLEX_MUL THEN CONJ_TAC THENL + [SUBGOAL_THEN + `((\w. path_integral (linepath(a,b)) (\z. d z w)) o (g:real^1->complex)) + continuous_on interval[vec 0,vec 1]` + MP_TAC THENL + [MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN + ASM_SIMP_TAC[GSYM path; VALID_PATH_IMP_PATH] THEN + MATCH_MP_TAC CONTINUOUS_ON_SUBSET THEN + EXISTS_TAC `u:complex->bool` THEN ASM_SIMP_TAC[GSYM path_image]; + REWRITE_TAC[o_DEF]]; + FIRST_ASSUM(fun th -> REWRITE_TAC + [MATCH_MP HAS_VECTOR_DERIVATIVE_UNIQUE_AT (SPEC_ALL th)]) THEN + ASM_SIMP_TAC[ETA_AX; GSYM path; VALID_PATH_IMP_PATH; + VALID_PATH_VECTOR_POLYNOMIAL_FUNCTION]]; + ALL_TAC] THEN + SUBGOAL_THEN + `!a b. segment[a,b] SUBSET u + ==> path_integral (linepath(a,b)) h = + path_integral g (\w. path_integral (linepath (a,b)) (\z. d z w))` + ASSUME_TAC THENL + [ALL_TAC; + MAP_EVERY X_GEN_TAC [`a:complex`; `b:complex`; `c:complex`] THEN + DISCH_TAC THEN + SUBGOAL_THEN + `segment[a:complex,b] SUBSET u /\ + segment[b,c] SUBSET u /\ segment[c,a] SUBSET u` + STRIP_ASSUME_TAC THENL + [ASM_MESON_TAC[SEGMENTS_SUBSET_CONVEX_HULL; SUBSET_TRANS]; ALL_TAC] THEN + ASM_SIMP_TAC[] THEN + ASM_SIMP_TAC[GSYM PATH_INTEGRAL_ADD; PATH_INTEGRABLE_ADD] THEN + MATCH_MP_TAC PATH_INTEGRAL_EQ_0 THEN + X_GEN_TAC `w:complex` THEN REWRITE_TAC[] THEN DISCH_TAC THEN + SUBGOAL_THEN `(w:complex) IN u` ASSUME_TAC THENL + [ASM SET_TAC[]; ALL_TAC] THEN + ASM_SIMP_TAC[GSYM PATH_INTEGRAL_JOIN; VALID_PATH_LINEPATH; + VALID_PATH_JOIN; PATHSTART_JOIN; + PATH_INTEGRABLE_JOIN; PATHSTART_LINEPATH; PATHFINISH_LINEPATH] THEN + MATCH_MP_TAC PATH_INTEGRAL_UNIQUE THEN + MATCH_MP_TAC CAUCHY_THEOREM_TRIANGLE THEN + MATCH_MP_TAC HOLOMORPHIC_ON_SUBSET THEN EXISTS_TAC `u:complex->bool` THEN + ASM_SIMP_TAC[] THEN ASM SET_TAC[]] THEN + MAP_EVERY X_GEN_TAC [`a:complex`; `b:complex`] THEN DISCH_TAC THEN + MATCH_MP_TAC EQ_TRANS THEN + EXISTS_TAC `path_integral (linepath(a,b)) (\z. path_integral g (d z))` THEN + CONJ_TAC THENL + [MATCH_MP_TAC PATH_INTEGRAL_EQ THEN + REWRITE_TAC[PATH_IMAGE_LINEPATH] THEN + REPEAT STRIP_TAC THEN CONV_TAC SYM_CONV THEN + MATCH_MP_TAC PATH_INTEGRAL_UNIQUE THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_MESON_TAC[SUBSET]; + MATCH_MP_TAC(REWRITE_RULE[PCROSS] PATH_INTEGRAL_SWAP) THEN + REWRITE_TAC[VALID_PATH_LINEPATH; VECTOR_DERIVATIVE_LINEPATH_AT; + CONTINUOUS_ON_CONST] THEN + FIRST_ASSUM(fun th -> REWRITE_TAC + [MATCH_MP HAS_VECTOR_DERIVATIVE_UNIQUE_AT (SPEC_ALL th)]) THEN + ASM_SIMP_TAC[ETA_AX; CONTINUOUS_VECTOR_POLYNOMIAL_FUNCTION; + CONTINUOUS_AT_IMP_CONTINUOUS_ON] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET)) THEN + REWRITE_TAC[SUBSET; FORALL_IN_GSPEC; IN_ELIM_PASTECART_THM] THEN + REWRITE_TAC[PATH_IMAGE_LINEPATH] THEN ASM SET_TAC[]]);; + +let CAUCHY_THEOREM_GLOBAL = prove + (`!f s g. + open s /\ f holomorphic_on s /\ + valid_path g /\ pathfinish g = pathstart g /\ path_image g SUBSET s /\ + (!z. ~(z IN s) ==> winding_number(g,z) = Cx(&0)) + ==> (f has_path_integral Cx(&0)) g`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN `?z:complex. z IN s /\ ~(z IN path_image g)` + STRIP_ASSUME_TAC THENL + [MATCH_MP_TAC(SET_RULE + `t SUBSET s /\ ~(t = s) ==> ?z. z IN s /\ ~(z IN t)`) THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC(MESON + [CLOPEN; COMPACT_EQ_BOUNDED_CLOSED; NOT_BOUNDED_UNIV] + `open s /\ compact t /\ ~(t = {}) ==> ~(t = s)`) THEN + ASM_SIMP_TAC[COMPACT_PATH_IMAGE; PATH_IMAGE_NONEMPTY; VALID_PATH_IMP_PATH]; + MP_TAC(ISPECL [`\w:complex. (w - z) * f(w)`; `s:complex->bool`; + `g:real^1->complex`; `z:complex`] + CAUCHY_INTEGRAL_FORMULA_GLOBAL) THEN + ASM_SIMP_TAC[COMPLEX_SUB_REFL; COMPLEX_MUL_LZERO; COMPLEX_MUL_RZERO; + HOLOMORPHIC_ON_MUL; HOLOMORPHIC_ON_SUB; + HOLOMORPHIC_ON_ID; HOLOMORPHIC_ON_CONST] THEN + ANTS_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] HAS_PATH_INTEGRAL_EQ) THEN + X_GEN_TAC `w:complex` THEN ASM_CASES_TAC `w:complex = z` THEN + ASM_SIMP_TAC[COMPLEX_FIELD + `~(w:complex = z) ==> ((w - z) * f) / (w - z) = f`]]);; + +let CAUCHY_THEOREM_GLOBAL_OUTSIDE = prove + (`!f s g. + open s /\ f holomorphic_on s /\ + valid_path g /\ pathfinish g = pathstart g /\ + (!z. ~(z IN s) ==> z IN outside(path_image g)) + ==> (f has_path_integral Cx(&0)) g`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC CAUCHY_THEOREM_GLOBAL THEN + EXISTS_TAC `s:complex->bool` THEN + ASM_SIMP_TAC[WINDING_NUMBER_ZERO_IN_OUTSIDE; VALID_PATH_IMP_PATH] THEN + MP_TAC(ISPEC `path_image(g:real^1->complex)` OUTSIDE_NO_OVERLAP) THEN + ASM SET_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* First Cartan Theorem. *) +(* ------------------------------------------------------------------------- *) + +let HIGHER_COMPLEX_DERIVATIVE_COMP_LEMMA = prove + (`!f g z s t n i. + open s /\ f holomorphic_on s /\ z IN s /\ + open t /\ g holomorphic_on t /\ (!w. w IN s ==> f w IN t) /\ + complex_derivative f z = Cx(&1) /\ + (!i. 1 < i /\ i <= n ==> higher_complex_derivative i f z = Cx(&0)) /\ + i <= n + ==> higher_complex_derivative i (g o f) z = + higher_complex_derivative i g (f z)`, + REPEAT GEN_TAC THEN + SUBGOAL_THEN + `open s /\ f holomorphic_on s /\ z IN s /\ open t /\ + (!w. w IN s ==> f w IN t) /\ + complex_derivative f z = Cx(&1) /\ + (!i. 1 < i /\ i <= n ==> higher_complex_derivative i f z = Cx(&0)) + ==> !i g. g holomorphic_on t /\ i <= n + ==> higher_complex_derivative i (g o f) z = + higher_complex_derivative i g (f z)` + (fun th -> MESON_TAC [th]) THEN + STRIP_TAC THEN + INDUCT_TAC THEN + REWRITE_TAC [LE_SUC_LT; higher_complex_derivative_alt; o_THM] THEN + REPEAT STRIP_TAC THEN + EQ_TRANS_TAC `higher_complex_derivative i + (\w. complex_derivative g (f w) * complex_derivative f w) z` THENL + [MATCH_MP_TAC HIGHER_COMPLEX_DERIVATIVE_TRANSFORM_WITHIN_OPEN THEN + EXISTS_TAC `s:complex->bool` THEN + ASM_REWRITE_TAC [] THEN + REPEAT CONJ_TAC THENL + [MATCH_MP_TAC HOLOMORPHIC_COMPLEX_DERIVATIVE THEN + ASM_REWRITE_TAC [] THEN + MATCH_MP_TAC HOLOMORPHIC_ON_COMPOSE_GEN THEN + EXISTS_TAC `t:complex->bool` THEN + ASM_SIMP_TAC []; + MATCH_MP_TAC HOLOMORPHIC_ON_MUL THEN + CONJ_TAC THENL + [REWRITE_TAC [GSYM o_DEF] THEN + MATCH_MP_TAC HOLOMORPHIC_ON_COMPOSE_GEN THEN + EXISTS_TAC `t:complex->bool` THEN + ASM_REWRITE_TAC [] THEN + MATCH_MP_TAC HOLOMORPHIC_COMPLEX_DERIVATIVE THEN + ASM_REWRITE_TAC []; + ASM_REWRITE_TAC [ETA_AX] THEN + MATCH_MP_TAC HOLOMORPHIC_COMPLEX_DERIVATIVE THEN + ASM_REWRITE_TAC []]; + REPEAT STRIP_TAC THEN + MATCH_MP_TAC COMPLEX_DERIVATIVE_CHAIN THEN + ASM_MESON_TAC [HOLOMORPHIC_ON_IMP_DIFFERENTIABLE_AT]]; + EQ_TRANS_TAC + `vsum (0..i) + (\j. Cx (&(binom (i,j))) * + higher_complex_derivative j (\w. complex_derivative g (f w)) z * + higher_complex_derivative (i - j) (complex_derivative f) z)` THENL + [MATCH_MP_TAC HIGHER_COMPLEX_DERIVATIVE_MUL THEN + EXISTS_TAC `s:complex->bool` THEN + ASM_REWRITE_TAC [] THEN + ASM_SIMP_TAC [HOLOMORPHIC_COMPLEX_DERIVATIVE] THEN + REWRITE_TAC [GSYM o_DEF] THEN + MATCH_MP_TAC HOLOMORPHIC_ON_COMPOSE_GEN THEN + EXISTS_TAC `t:complex->bool` THEN + ASM_REWRITE_TAC [] THEN + ASM_SIMP_TAC [HOLOMORPHIC_COMPLEX_DERIVATIVE]; + REWRITE_TAC [GSYM higher_complex_derivative_alt] THEN + EQ_TRANS_TAC + `vsum (i..i) + (\j. Cx (&(binom (i,j))) * + higher_complex_derivative j + (\w. complex_derivative g (f w)) z * + higher_complex_derivative (SUC (i - j)) f z)` THENL + [MATCH_MP_TAC VSUM_SUPERSET THEN + REWRITE_TAC[SUBSET_NUMSEG; LT_REFL; LE_0; + LE_REFL; IN_NUMSEG_0; NUMSEG_SING; IN_SING] THEN + X_GEN_TAC `j:num` THEN + REWRITE_TAC [ARITH_RULE `j:num <= i /\ ~(j = i) <=> j < i`] THEN + DISCH_TAC THEN + ASSERT_TAC `1 < SUC (i - j) /\ SUC (i - j) <= n` THENL + [ASM_SIMP_TAC [ARITH_RULE + `i < n /\ j < i ==> 1 < SUC (i - j) /\ SUC (i - j) <= n`] THEN + MATCH_MP_TAC (ARITH_RULE `i < n /\ j < i ==> 1 < SUC (i - j)`) THEN + ASM_REWRITE_TAC []; + ASM_SIMP_TAC [COMPLEX_MUL_RZERO; COMPLEX_VEC_0]]; + REWRITE_TAC [NUMSEG_SING; VSUM_SING; BINOM_REFL; SUB_REFL] THEN + ASM_REWRITE_TAC [COMPLEX_MUL_LID; COMPLEX_MUL_RID; + higher_complex_derivative] THEN + ASM_REWRITE_TAC [GSYM o_DEF] THEN + REWRITE_TAC [GSYM higher_complex_derivative; + higher_complex_derivative_alt] THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_SIMP_TAC [ARITH_RULE `i:num < n ==> i <= n`] THEN + MATCH_MP_TAC HOLOMORPHIC_COMPLEX_DERIVATIVE THEN + ASM_REWRITE_TAC []]]]);; + +let HIGHER_COMPLEX_DERIVATIVE_COMP_ITER_LEMMA = prove + (`!f s z n m i. + open s /\ f holomorphic_on s /\ (!w. w IN s ==> f w IN s) /\ + z IN s /\ f z = z /\ complex_derivative f z = Cx (&1) /\ + (!i. 1 < i /\ i <= n ==> higher_complex_derivative i f z = Cx (&0)) /\ + i <= n + ==> higher_complex_derivative i (ITER m f) z = + higher_complex_derivative i f z`, + GEN_TAC THEN GEN_TAC THEN GEN_TAC THEN GEN_TAC THEN + REWRITE_TAC [RIGHT_FORALL_IMP_THM; IMP_CONJ] THEN + REWRITE_TAC [IMP_IMP] THEN + STRIP_TAC THEN + ASSERT_TAC `!m. ITER m f z = z:complex` THENL + [INDUCT_TAC THEN ASM_REWRITE_TAC [ITER]; ALL_TAC] THEN + ASSERT_TAC `!m (w:complex). w IN s ==> ITER m f w IN s` THENL + [INDUCT_TAC THEN ASM_SIMP_TAC [ITER]; ALL_TAC] THEN + ASSERT_TAC `!m. ITER m f holomorphic_on s` THENL + [INDUCT_TAC THEN REWRITE_TAC [ITER_POINTLESS] THENL + [ASM_SIMP_TAC [I_DEF; HOLOMORPHIC_ON_ID]; + MATCH_MP_TAC HOLOMORPHIC_ON_COMPOSE_GEN THEN + EXISTS_TAC `s:complex ->bool` THEN + ASM_REWRITE_TAC []]; + ALL_TAC] THEN + INDUCT_TAC THENL + [REWRITE_TAC [ITER_POINTLESS; I_DEF; HIGHER_COMPLEX_DERIVATIVE_ID] THEN + REPEAT STRIP_TAC THEN COND_CASES_TAC THENL + [ASM_REWRITE_TAC [higher_complex_derivative]; ALL_TAC] THEN + REPEAT STRIP_TAC THEN COND_CASES_TAC THENL + [ASM_REWRITE_TAC [higher_complex_derivative; ONE]; ALL_TAC] THEN + MATCH_MP_TAC EQ_SYM THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_SIMP_TAC [ARITH_RULE `~(i = 0) /\ ~(i = 1) ==> 1 < i`]; + GEN_TAC THEN DISCH_TAC THEN + REWRITE_TAC [ITER_ALT_POINTLESS] THEN + EQ_TRANS_TAC `higher_complex_derivative i (ITER m f) (f z)` THENL + [MATCH_MP_TAC HIGHER_COMPLEX_DERIVATIVE_COMP_LEMMA THEN + EXISTS_TAC `s:complex ->bool` THEN + EXISTS_TAC `s:complex ->bool` THEN + EXISTS_TAC `n:num` THEN + ASM_REWRITE_TAC []; + ASM_REWRITE_TAC [] THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_REWRITE_TAC []]]);; + +let HIGHER_COMPLEX_DERIVATIVE_ITER_TOP_LEMMA = prove + (`!f s z n m. + open s /\ f holomorphic_on s /\ (!w. w IN s ==> f w IN s) /\ + z IN s /\ f z = z /\ complex_derivative f z = Cx (&1) /\ + (!i. 1 < i /\ i < n ==> higher_complex_derivative i f z = Cx (&0)) /\ + 1 < n + ==> higher_complex_derivative n (ITER m f) z = + Cx(&m) * higher_complex_derivative n f z`, + GEN_TAC THEN GEN_TAC THEN GEN_TAC THEN + INDUCT_TAC THEN REWRITE_TAC [LT_SUC_LE] THEN REWRITE_TAC [LT] THEN + REWRITE_TAC [RIGHT_FORALL_IMP_THM] THEN + STRIP_TAC THEN + ASSERT_TAC `!m. ITER m f z = z:complex` THENL + [INDUCT_TAC THEN ASM_REWRITE_TAC [ITER]; ALL_TAC] THEN + ASSERT_TAC `!m (w:complex). w IN s ==> ITER m f w IN s` THENL + [INDUCT_TAC THEN ASM_SIMP_TAC [ITER]; ALL_TAC] THEN + ASSERT_TAC `!m. ITER m f holomorphic_on s` THENL + [INDUCT_TAC THEN REWRITE_TAC [ITER_POINTLESS] THEN + ASM_SIMP_TAC [I_DEF; HOLOMORPHIC_ON_ID] THEN + MATCH_MP_TAC HOLOMORPHIC_ON_COMPOSE_GEN THEN + EXISTS_TAC `s:complex ->bool` THEN + ASM_REWRITE_TAC []; + ALL_TAC] THEN + ASSERT_TAC `!w. w IN s ==> f complex_differentiable at w` THENL + [ASM_MESON_TAC [HOLOMORPHIC_ON_IMP_DIFFERENTIABLE_AT]; ALL_TAC] THEN + ASSERT_TAC `!m w. w IN s ==> ITER m f complex_differentiable at w` THENL + [ASM_MESON_TAC [HOLOMORPHIC_ON_IMP_DIFFERENTIABLE_AT]; ALL_TAC] THEN + ASSERT_TAC `!m. complex_derivative (ITER m f) z = Cx(&1)` THENL + [INDUCT_TAC THEN ASM_REWRITE_TAC [ITER_POINTLESS] THENL + [REWRITE_TAC [I_DEF; COMPLEX_DERIVATIVE_ID]; ALL_TAC] THEN + ASM_SIMP_TAC [COMPLEX_DERIVATIVE_CHAIN; + HOLOMORPHIC_ON_IMP_DIFFERENTIABLE_AT] THEN + REWRITE_TAC [COMPLEX_MUL_LID]; + ALL_TAC] THEN + INDUCT_TAC THEN + REWRITE_TAC [higher_complex_derivative_alt; ITER_POINTLESS] THENL + [ASM_REWRITE_TAC [COMPLEX_MUL_LZERO; I_DEF; COMPLEX_DERIVATIVE_ID; + HIGHER_COMPLEX_DERIVATIVE_CONST; + ARITH_RULE `n = 0 <=> ~(1 <= n)`]; + ALL_TAC] THEN + EQ_TRANS_TAC `higher_complex_derivative n + (\w. complex_derivative f (ITER m f w) * + complex_derivative (ITER m f) w) z` THENL + [MATCH_MP_TAC HIGHER_COMPLEX_DERIVATIVE_TRANSFORM_WITHIN_OPEN THEN + EXISTS_TAC `s:complex->bool` THEN + ASM_REWRITE_TAC[] THEN CONJ_TAC THENL + [REWRITE_TAC [o_DEF] THEN + MATCH_MP_TAC HOLOMORPHIC_COMPLEX_DERIVATIVE THEN + ASM_REWRITE_TAC [] THEN + ONCE_REWRITE_TAC [GSYM o_DEF] THEN + MATCH_MP_TAC HOLOMORPHIC_ON_COMPOSE_GEN THEN + EXISTS_TAC `s:complex->bool` THEN + ASM_REWRITE_TAC [ETA_AX]; + ALL_TAC] THEN + CONJ_TAC THENL + [MATCH_MP_TAC HOLOMORPHIC_ON_MUL THEN CONJ_TAC THENL + [ONCE_REWRITE_TAC [GSYM o_DEF] THEN + MATCH_MP_TAC HOLOMORPHIC_ON_COMPOSE_GEN THEN + EXISTS_TAC `s:complex->bool` THEN + ASM_REWRITE_TAC[ETA_AX] THEN + MATCH_MP_TAC HOLOMORPHIC_COMPLEX_DERIVATIVE THEN + ASM_REWRITE_TAC[]; + ONCE_REWRITE_TAC [GSYM o_DEF] THEN + MATCH_MP_TAC HOLOMORPHIC_ON_COMPOSE_GEN THEN + EXISTS_TAC `s:complex->bool` THEN + ASM_REWRITE_TAC[HOLOMORPHIC_ON_ID] THEN + MATCH_MP_TAC HOLOMORPHIC_COMPLEX_DERIVATIVE THEN + ASM_REWRITE_TAC[]]; + GEN_TAC THEN DISCH_TAC THEN + MATCH_MP_TAC COMPLEX_DERIVATIVE_CHAIN THEN + CONJ_TAC THENL + [MATCH_MP_TAC HOLOMORPHIC_ON_IMP_DIFFERENTIABLE_AT THEN + ASM_MESON_TAC []; + MATCH_MP_TAC HOLOMORPHIC_ON_IMP_DIFFERENTIABLE_AT THEN + ASM_MESON_TAC []]]; + ALL_TAC] THEN + EQ_TRANS_TAC + `vsum (0..n) + (\i. Cx (&(binom (n,i))) * + higher_complex_derivative i + (\w. complex_derivative f (ITER m f w)) z * + higher_complex_derivative (n - i) + (complex_derivative (ITER m f)) z)` THENL + [MATCH_MP_TAC HIGHER_COMPLEX_DERIVATIVE_MUL THEN + EXISTS_TAC `s:complex->bool` THEN + ASM_REWRITE_TAC[] THEN CONJ_TAC THENL + [ONCE_REWRITE_TAC [GSYM o_DEF] THEN + MATCH_MP_TAC HOLOMORPHIC_ON_COMPOSE_GEN THEN + EXISTS_TAC `s:complex->bool` THEN + ASM_REWRITE_TAC[ETA_AX] THEN + MATCH_MP_TAC HOLOMORPHIC_COMPLEX_DERIVATIVE THEN + ASM_REWRITE_TAC[]; + MATCH_MP_TAC HOLOMORPHIC_COMPLEX_DERIVATIVE THEN + ASM_REWRITE_TAC[]]; + ALL_TAC] THEN + EQ_TRANS_TAC + `vsum {0,n} + (\i. Cx (&(binom (n,i))) * + higher_complex_derivative i + (\w. complex_derivative f (ITER m f w)) z * + higher_complex_derivative (n - i) + (complex_derivative (ITER m f)) z)` THENL + [MATCH_MP_TAC VSUM_SUPERSET THEN + REWRITE_TAC [INSERT_SUBSET; EMPTY_SUBSET; IN_NUMSEG_0; LE_0; LE_REFL; + IN_INSERT; NOT_IN_EMPTY; DE_MORGAN_THM] THEN + X_GEN_TAC `i:num` THEN + STRIP_TAC THEN + REWRITE_TAC [GSYM higher_complex_derivative_alt] THEN + ASSERT_TAC `1 < SUC (n-i) /\ SUC (n-i) <= n` THENL + [ASM_SIMP_TAC [ARITH_RULE `i <= n /\ ~(i=0) /\ ~(i=n) + ==> 1 < SUC (n-i) /\ SUC (n-i) <= n`]; + ALL_TAC] THEN + ASM_SIMP_TAC [] THEN + SUBGOAL_THEN + `higher_complex_derivative (SUC (n - i)) (ITER m f) z = Cx(&0)` + SUBST1_TAC THENL + [EQ_TRANS_TAC `higher_complex_derivative (SUC (n - i)) f z` THENL + [MATCH_MP_TAC HIGHER_COMPLEX_DERIVATIVE_COMP_ITER_LEMMA THEN + EXISTS_TAC `s:complex->bool` THEN + ASM_REWRITE_TAC [] THEN + EXISTS_TAC `n:num` THEN + ASM_REWRITE_TAC []; + FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_REWRITE_TAC []]; + ASM_REWRITE_TAC [COMPLEX_MUL_RZERO; COMPLEX_VEC_0]]; + ALL_TAC] THEN + SIMP_TAC [VSUM_CLAUSES; FINITE_RULES; IN_INSERT; NOT_IN_EMPTY] THEN + REWRITE_TAC [binom; BINOM_REFL; COMPLEX_MUL_LID; + SUB_REFL; SUB; higher_complex_derivative] THEN + ASM_CASES_TAC `n = 0` THEN ASM_REWRITE_TAC [] THENL + [REWRITE_TAC [higher_complex_derivative] THEN + POP_ASSUM SUBST_ALL_TAC THEN + RULE_ASSUM_TAC (REWRITE_RULE [higher_complex_derivative]) THEN + ASM_REWRITE_TAC [COMPLEX_MUL_RID; COMPLEX_MUL_LID; + COMPLEX_VEC_0; COMPLEX_ADD_RID] THEN + ASM_MESON_TAC [ARITH_RULE `~(1 <= 0)`]; + ALL_TAC] THEN + ASM_REWRITE_TAC [COMPLEX_MUL_LID; COMPLEX_VEC_0; COMPLEX_ADD_RID] THEN + ASM_REWRITE_TAC [COMPLEX_MUL_RID] THEN + ASM_REWRITE_TAC [GSYM higher_complex_derivative_alt] THEN + SUBGOAL_THEN + `(\w. complex_derivative f (ITER m f w)) = complex_derivative f o ITER m f` + SUBST1_TAC + THENL [REWRITE_TAC [FUN_EQ_THM; o_THM]; ALL_TAC] THEN + SUBGOAL_THEN + `higher_complex_derivative n (complex_derivative f o ITER m f) z = + higher_complex_derivative n (complex_derivative f) (ITER m f z)` + SUBST1_TAC THENL + [MATCH_MP_TAC HIGHER_COMPLEX_DERIVATIVE_COMP_LEMMA THEN + EXISTS_TAC `s:complex->bool` THEN + EXISTS_TAC `s:complex->bool` THEN + EXISTS_TAC `n:num` THEN + ASM_REWRITE_TAC[] THEN + ASM_SIMP_TAC[HOLOMORPHIC_COMPLEX_DERIVATIVE; LE_REFL] THEN + REPEAT STRIP_TAC THEN + EQ_TRANS_TAC `higher_complex_derivative i f z` THENL + [MATCH_MP_TAC HIGHER_COMPLEX_DERIVATIVE_COMP_ITER_LEMMA THEN + EXISTS_TAC `s:complex->bool` THEN + EXISTS_TAC `n:num` THEN + ASM_REWRITE_TAC[]; + ASM_SIMP_TAC[]]; + ALL_TAC] THEN + ASSERT_TAC `Cx (&(SUC m)) = Cx (&m) + Cx (&1)` THENL + [REWRITE_TAC [GSYM CX_ADD; REAL_OF_NUM_ADD; ONE; ADD_SUC; ADD_0]; + ASM_REWRITE_TAC[COMPLEX_POLY_CLAUSES; + GSYM higher_complex_derivative_alt]]);; + +let CAUCHY_HIGHER_COMPLEX_DERIVATIVE_BOUND = prove + (`!f z y r B0 n. + &0 < r /\ 0 < n /\ + f holomorphic_on ball(z,r) /\ + f continuous_on cball(z,r) /\ + (!w. w IN ball(z,r) ==> f w IN ball(y,B0)) + ==> norm (higher_complex_derivative n f z) <= &(FACT n) * B0 / r pow n`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN `higher_complex_derivative n f z = + higher_complex_derivative n (\w. f w - y) z` + SUBST1_TAC THENL + [EQ_TRANS_TAC `higher_complex_derivative n (\w. f w) z - + higher_complex_derivative n (\w. y) z` THENL + [ASM_SIMP_TAC + [HIGHER_COMPLEX_DERIVATIVE_CONST; ARITH_RULE `0 ~(n=0)`] THEN + REWRITE_TAC [COMPLEX_SUB_RZERO; ETA_AX]; + MATCH_MP_TAC EQ_SYM THEN + REWRITE_TAC [ETA_AX] THEN + MATCH_MP_TAC HIGHER_COMPLEX_DERIVATIVE_SUB THEN + EXISTS_TAC `ball(z:complex,r)` THEN + ASM_SIMP_TAC [OPEN_BALL; HOLOMORPHIC_ON_CONST; CENTRE_IN_BALL]]; + ALL_TAC] THEN + SUBGOAL_THEN + `norm ((Cx (&2) * Cx pi * ii) / Cx (&(FACT n)) + * higher_complex_derivative n (\w. f w - y) z) + <= (B0 / r pow (n + 1)) * &2 * pi * r` + MP_TAC THENL + [MATCH_MP_TAC HAS_PATH_INTEGRAL_BOUND_CIRCLEPATH THEN + EXISTS_TAC `(\u. (f u - y) / (u - z) pow (n + 1))` THEN + EXISTS_TAC `z:complex` THEN STRIP_TAC THENL + [MATCH_MP_TAC CAUCHY_HAS_PATH_INTEGRAL_HIGHER_DERIVATIVE_CIRCLEPATH THEN + ASM_SIMP_TAC[CENTRE_IN_BALL] THEN CONJ_TAC THENL + [MATCH_MP_TAC CONTINUOUS_ON_SUB THEN + ASM_REWRITE_TAC [CONTINUOUS_ON_CONST]; + MATCH_MP_TAC HOLOMORPHIC_ON_SUB THEN + ASM_REWRITE_TAC [HOLOMORPHIC_ON_CONST]]; + ALL_TAC] THEN + ASM_SIMP_TAC[] THEN STRIP_TAC THENL + [MATCH_MP_TAC REAL_LE_DIV THEN STRIP_TAC THENL + [MATCH_MP_TAC REAL_LT_IMP_LE THEN + MATCH_MP_TAC + (prove(`(?x. &0 <= x /\ x < B0) ==> &0 < B0`, REAL_ARITH_TAC)) THEN + EXISTS_TAC `norm ((\u. (f:complex->complex) u - y) z)` THEN + SIMP_TAC[NORM_POS_LE] THEN + SUBGOAL_THEN + `!w:complex. f w IN ball(y,B0) ==> norm (f w - y) < B0` + MATCH_MP_TAC THENL + [ASM_MESON_TAC [dist; DIST_SYM; IN_BALL; CENTRE_IN_BALL]; + ALL_TAC] THEN + FIRST_ASSUM MATCH_MP_TAC THEN + ASM_SIMP_TAC[CENTRE_IN_BALL]; + MATCH_MP_TAC(SPECL [`r:real`;`n + 1`] REAL_POW_LE) THEN + ASM_SIMP_TAC[REAL_LT_IMP_LE]]; + REPEAT STRIP_TAC THEN + ASM_REWRITE_TAC[COMPLEX_NORM_DIV;COMPLEX_NORM_POW] THEN + ASM_SIMP_TAC [REAL_LE_DIV2_EQ; REAL_POW_LT] THEN + ONCE_REWRITE_TAC[MESON[] `!(f:complex->complex). + (f x - y) = (\w. f w - y) x`] THEN + MATCH_MP_TAC CONTINUOUS_ON_CLOSURE_NORM_LE THEN + EXISTS_TAC `ball(z:complex,r)` THEN + ASM_SIMP_TAC[CLOSURE_BALL] THEN + REPEAT STRIP_TAC THENL + [MATCH_MP_TAC CONTINUOUS_ON_SUB THEN + ASM_SIMP_TAC[CONTINUOUS_ON_CONST]; + SUBGOAL_THEN + `!w:complex. f w IN ball(y,B0) ==> norm (f w - y) <= B0` + MATCH_MP_TAC THENL + [REWRITE_TAC[GSYM dist;IN_BALL;DIST_SYM;REAL_LT_IMP_LE]; + ASM_MESON_TAC [dist; DIST_SYM; IN_BALL; CENTRE_IN_BALL]]; + ASM_REWRITE_TAC[cball;IN_ELIM_THM;dist;DIST_SYM] THEN + ASM_SIMP_TAC[REAL_EQ_IMP_LE]]]; + ALL_TAC] THEN + REWRITE_TAC [COMPLEX_NORM_MUL; COMPLEX_NORM_DIV; COMPLEX_NORM_II; + COMPLEX_NORM_CX; REAL_ABS_NUM; REAL_ABS_PI; + REAL_MUL_RID] THEN + STRIP_TAC THEN + ABBREV_TAC `a = (&2 * pi) / &(FACT n)` THEN + SUBGOAL_THEN `&0 < a` ASSUME_TAC THENL + [EXPAND_TAC "a" THEN + SIMP_TAC[REAL_LT_DIV; REAL_LT_MUL; REAL_OF_NUM_LT; FACT_LT; ARITH; PI_POS]; + ALL_TAC] THEN + SUBGOAL_THEN + `B0 / r pow (n + 1) * &2 * pi * r = a * (&(FACT n) * B0 / r pow n)` + SUBST_ALL_TAC THENL + [EXPAND_TAC "a" THEN + REWRITE_TAC [GSYM ADD1; real_pow] THEN + SUBGOAL_THEN `~(&(FACT n) = &0) /\ &0 < r` MP_TAC THENL + [ASM_REWRITE_TAC[FACT_NZ; REAL_OF_NUM_EQ]; + CONV_TAC REAL_FIELD]; + ASM_MESON_TAC [REAL_LE_LCANCEL_IMP]]);; + +let FIRST_CARTAN_THM_DIM_1 = prove + (`!f s z w. + open s /\ connected s /\ bounded s /\ + (!w. w IN s ==> f w IN s) /\ f holomorphic_on s /\ + z IN s /\ f z = z /\ + complex_derivative f z = Cx (&1) /\ w IN s + ==> f w = w`, + REWRITE_TAC [RIGHT_FORALL_IMP_THM; IMP_CONJ] THEN REPEAT GEN_TAC THEN + REPEAT DISCH_TAC THEN REPEAT STRIP_TAC THEN EQ_TRANS_TAC `I w:complex` THENL + [MATCH_MP_TAC HOLOMORPHIC_FUN_EQ_ON_CONNECTED; + REWRITE_TAC [I_THM]] THEN + EXISTS_TAC `z:complex` THEN EXISTS_TAC `s:complex->bool` THEN + ASM_REWRITE_TAC [I_DEF; HOLOMORPHIC_ON_ID] THEN + GEN_TAC THEN STRIP_ASSUME_TAC (ARITH_RULE `n = 0 \/ n = 1 \/ 1 < n`) THENL + [ASM_REWRITE_TAC [higher_complex_derivative]; + ASM_REWRITE_TAC [ONE; higher_complex_derivative; COMPLEX_DERIVATIVE_ID]; + ASM_REWRITE_TAC [HIGHER_COMPLEX_DERIVATIVE_ID]] THEN + ASM_SIMP_TAC [ARITH_RULE `1 < n ==> ~(n=0) /\ ~(n=1)`] THEN + POP_ASSUM MP_TAC THEN SPEC_TAC (`n:num`,`n:num`) THEN + MATCH_MP_TAC num_WF THEN REPEAT STRIP_TAC THEN + REWRITE_TAC [GSYM COMPLEX_NORM_ZERO] THEN + MATCH_MP_TAC REAL_ARCH_RDIV_EQ_0 THEN REWRITE_TAC [NORM_POS_LE] THEN + ASSERT_TAC `?c. s SUBSET ball(z:complex,c)` THENL + [ASSERT_TAC `?c. !w:complex. w IN s ==> norm w <= c` THENL + [ASM_REWRITE_TAC[GSYM bounded]; + EXISTS_TAC `&2 * c + &1` THEN REWRITE_TAC [SUBSET] THEN GEN_TAC THEN + DISCH_TAC THEN + SUBGOAL_THEN `norm (x:complex) <= c /\ norm (z:complex) <= c` MP_TAC THENL + [ASM_MESON_TAC[]; REWRITE_TAC [IN_BALL] THEN NORM_ARITH_TAC]]; + ALL_TAC] THEN + ASSERT_TAC `?r. &0 < r /\ cball(z:complex,r) SUBSET s` THENL + [ASM_MESON_TAC [OPEN_CONTAINS_CBALL]; + EXISTS_TAC `&(FACT n) * c / r pow n`] THEN + ASSERT_TAC `&0 < c` THENL + [SUBGOAL_THEN `~(ball(z:complex,c) = {})` MP_TAC THENL + [ASM SET_TAC[]; ASM_REWRITE_TAC [BALL_EQ_EMPTY; REAL_NOT_LE]]; + ALL_TAC] THEN + ASSERT_TAC `ball(z:complex,r) SUBSET s` THENL + [ASM_MESON_TAC [SUBSET_TRANS; BALL_SUBSET_CBALL]; ALL_TAC] THEN + CONJ_TAC THENL + [MATCH_MP_TAC REAL_LE_MUL THEN CONJ_TAC THENL + [MATCH_MP_TAC REAL_LT_IMP_LE THEN MATCH_MP_TAC REAL_LTE_TRANS THEN + EXISTS_TAC `&1` THEN REWRITE_TAC [REAL_LT_01; FACT_LE; REAL_OF_NUM_LE]; + MATCH_MP_TAC REAL_LE_DIV THEN ASM_SIMP_TAC [REAL_LT_IMP_LE; REAL_POW_LE]]; + ALL_TAC] THEN + REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC [GSYM COMPLEX_NORM_NUM] THEN + REWRITE_TAC [GSYM COMPLEX_NORM_MUL] THEN SUBGOAL_THEN + `Cx(&m) * higher_complex_derivative n f z = + higher_complex_derivative n (ITER m f) z` + SUBST1_TAC THENL + [MATCH_MP_TAC (GSYM HIGHER_COMPLEX_DERIVATIVE_ITER_TOP_LEMMA) THEN + EXISTS_TAC `s:complex->bool` THEN ASM_SIMP_TAC []; + ALL_TAC] THEN + REWRITE_TAC [COMPLEX_NORM_CX; REAL_ABS_NUM; REAL_POS] THEN + MATCH_MP_TAC CAUCHY_HIGHER_COMPLEX_DERIVATIVE_BOUND THEN + EXISTS_TAC `z:complex` THEN ASM_SIMP_TAC [ARITH_RULE `1 0 < n`] THEN + ASSERT_TAC `!m w. w:complex IN s ==> ITER m f w IN s` THENL + [INDUCT_TAC THEN ASM_SIMP_TAC [ITER]; + ASSERT_TAC `!m. ITER m f holomorphic_on s` THENL + [INDUCT_TAC THEN REWRITE_TAC [ITER_POINTLESS] THENL + [ASM_SIMP_TAC [I_DEF; HOLOMORPHIC_ON_ID]; + MATCH_MP_TAC HOLOMORPHIC_ON_COMPOSE_GEN THEN + EXISTS_TAC `s:complex->bool` THEN ASM_REWRITE_TAC []]; + ASSERT_TAC `ITER m f holomorphic_on ball(z,r)` THENL + [MATCH_MP_TAC HOLOMORPHIC_ON_SUBSET THEN ASM SET_TAC []; + ASM_REWRITE_TAC[]] THEN + CONJ_TAC THENL + [ASM_MESON_TAC [CONTINUOUS_ON_SUBSET; HOLOMORPHIC_ON_IMP_CONTINUOUS_ON]; + ASM SET_TAC []]]]);; + +(* ------------------------------------------------------------------------- *) +(* Second Cartan Theorem. *) +(* ------------------------------------------------------------------------- *) + +let SECOND_CARTAN_THM_DIM_1 = prove + (`!g f r. + &0 < r /\ + g holomorphic_on ball(Cx(&0),r) /\ + (!z. z IN ball(Cx(&0),r) ==> g z IN ball(Cx(&0),r)) /\ + g(Cx(&0)) = Cx(&0) /\ + f holomorphic_on ball(Cx(&0),r) /\ + (!z. z IN ball(Cx(&0),r) ==> f z IN ball(Cx(&0),r)) /\ + f (Cx(&0)) = Cx(&0) /\ + (!z. z IN ball(Cx(&0),r) ==> g (f z) = z) /\ + (!z. z IN ball(Cx(&0),r) ==> f (g z) = z) + ==> ?t. !z. z IN ball(Cx(&0),r) ==> g z = cexp (ii * Cx t) * z`, + let COMPLEX_DERIVATIVE_LEFT_INVERSE = prove + (`!s t f g w. + open s /\ open t /\ + (!z. z IN s ==> f z IN t) /\ f holomorphic_on s /\ + (!z. z IN t ==> g z IN s) /\ g holomorphic_on t /\ + (!z. z IN s ==> g (f z) = z) /\ w IN s + ==> complex_derivative f w * complex_derivative g (f w) = Cx(&1)`, + REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC [COMPLEX_MUL_SYM] THEN + SUBGOAL_THEN `complex_derivative g (f w) * complex_derivative f w = + complex_derivative (g o f) w ` SUBST1_TAC THENL + [ASM_MESON_TAC [HOLOMORPHIC_ON_IMP_DIFFERENTIABLE_AT; + COMPLEX_DERIVATIVE_CHAIN]; + EQ_TRANS_TAC `complex_derivative (\u. u) w` THENL + [MATCH_MP_TAC COMPLEX_DERIVATIVE_TRANSFORM_WITHIN_OPEN THEN + EXISTS_TAC `s:complex->bool` THEN + ASM_SIMP_TAC[HOLOMORPHIC_ON_ID;o_THM] THEN + ASM_MESON_TAC [HOLOMORPHIC_ON_COMPOSE_GEN]; + ASM_SIMP_TAC[COMPLEX_DERIVATIVE_ID]]]) in + let LEMMA_1 = prove + (`!s f. + open s /\ connected s /\ f holomorphic_on s /\ Cx(&0) IN s /\ + (!u z. norm u = &1 /\ z IN s ==> u * z IN s) /\ + (!u z. norm u = &1 /\ z IN s ==> f (u * z) = u * f z) + ==> ?c. !z. z IN s ==> f z = c * z`, + REPEAT STRIP_TAC THEN ABBREV_TAC `c = complex_derivative f (Cx(&0))` THEN + EXISTS_TAC `c : complex` THEN + SUBGOAL_THEN `f(Cx(&0)) = Cx(&0)` ASSUME_TAC THENL + [FIRST_X_ASSUM (MP_TAC o SPECL [`--Cx(&1)`;`Cx(&0)`]) THEN + ASM_REWRITE_TAC [NORM_NEG; COMPLEX_NORM_NUM; COMPLEX_MUL_RZERO] THEN + CONV_TAC COMPLEX_RING; ALL_TAC] THEN + SUBGOAL_THEN + `!n u z. + norm u = &1 /\ z IN s ==> + u pow n * higher_complex_derivative n f (u * z) = + u * higher_complex_derivative n f z` + ASSUME_TAC THENL + [REPEAT STRIP_TAC THEN + EQ_TRANS_TAC `higher_complex_derivative n (\w. f (u * w)) z` THENL + [MATCH_MP_TAC EQ_SYM THEN + MATCH_MP_TAC HIGHER_COMPLEX_DERIVATIVE_COMPOSE_LINEAR THEN + EXISTS_TAC `s:complex->bool` THEN EXISTS_TAC `s:complex->bool` THEN + ASM_SIMP_TAC[]; ALL_TAC] THEN + EQ_TRANS_TAC `higher_complex_derivative n (\w. u * f w) z` THENL + [MATCH_MP_TAC HIGHER_COMPLEX_DERIVATIVE_TRANSFORM_WITHIN_OPEN THEN + EXISTS_TAC `s:complex->bool` THEN ASM_SIMP_TAC[] THEN CONJ_TAC THENL + [MATCH_MP_TAC + (REWRITE_RULE [o_DEF] + (SPECL [`\w:complex. u*w`; `f:complex->complex`] + HOLOMORPHIC_ON_COMPOSE_GEN)) THEN + EXISTS_TAC `s:complex->bool` THEN + ASM_SIMP_TAC [HOLOMORPHIC_ON_LINEAR]; + MATCH_MP_TAC + (REWRITE_RULE [o_DEF] + (SPECL [`f:complex->complex`; `\w:complex. u*w`] + HOLOMORPHIC_ON_COMPOSE_GEN)) THEN + EXISTS_TAC `(:complex)` THEN + ASM_REWRITE_TAC [HOLOMORPHIC_ON_LINEAR; IN_UNIV]]; + POP_ASSUM MP_TAC THEN SPEC_TAC (`z:complex`,`z:complex`) THEN + SPEC_TAC (`n:num`,`n:num`) THEN INDUCT_TAC THEN + REWRITE_TAC [higher_complex_derivative] THEN GEN_TAC THEN + DISCH_TAC THEN EQ_TRANS_TAC + `complex_derivative (\w. u * higher_complex_derivative n f w) z` + THENL + [MATCH_MP_TAC COMPLEX_DERIVATIVE_TRANSFORM_WITHIN_OPEN THEN + EXISTS_TAC `s:complex->bool` THEN ASM_REWRITE_TAC[] THEN CONJ_TAC THENL + [MATCH_MP_TAC HOLOMORPHIC_HIGHER_COMPLEX_DERIVATIVE THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC HOLOMORPHIC_ON_MUL THEN + ASM_REWRITE_TAC [HOLOMORPHIC_ON_CONST]; + MATCH_MP_TAC HOLOMORPHIC_ON_MUL THEN + ASM_REWRITE_TAC [HOLOMORPHIC_ON_CONST; ETA_AX] THEN + MATCH_MP_TAC HOLOMORPHIC_HIGHER_COMPLEX_DERIVATIVE THEN + ASM_REWRITE_TAC[]]; + MATCH_MP_TAC COMPLEX_DERIVATIVE_LMUL THEN + MATCH_MP_TAC HOLOMORPHIC_ON_IMP_DIFFERENTIABLE_AT THEN + ASM_MESON_TAC [HOLOMORPHIC_HIGHER_COMPLEX_DERIVATIVE]]]; + SUBGOAL_THEN + `!n. 2 <= n ==> higher_complex_derivative n f (Cx(&0)) = Cx(&0)` + ASSUME_TAC THENL + [GEN_TAC THEN DISCH_TAC THEN SUBGOAL_THEN + `!n z. 2 <= n /\ + (!u. norm u = &1 ==> u pow n * z = u * z) ==> z = Cx(&0)` + MATCH_MP_TAC THENL + [REPEAT STRIP_TAC THEN MATCH_MP_TAC + (COMPLEX_RING + `!u. ~(u pow n' = u) /\ u pow n' * z = u * z ==> z = Cx(&0)`) THEN + SUBGOAL_THEN `2 <= n' ==> ?u. norm u = &1 /\ ~(u pow n' = u)` + (fun th -> ASM_MESON_TAC [th]) THEN + STRUCT_CASES_TAC (SPEC `n':num` num_CASES) THEN + REWRITE_TAC + [ARITH_LE; ARITH_RULE `2 <= SUC n'' <=> 1 <= n''`; complex_pow] THEN + DISCH_TAC THEN MP_TAC (SPEC `n'':num` COMPLEX_NOT_ROOT_UNITY) THEN + ASM_REWRITE_TAC [] THEN STRIP_TAC THEN EXISTS_TAC `u:complex` THEN + ASM_REWRITE_TAC [] THEN POP_ASSUM MP_TAC THEN + REWRITE_TAC [CONTRAPOS_THM] THEN + SUBGOAL_THEN `~(u = Cx(&0))` MP_TAC THENL + [ASM_REWRITE_TAC [GSYM COMPLEX_NORM_ZERO; REAL_OF_NUM_EQ; ARITH_EQ]; + CONV_TAC COMPLEX_FIELD]; + EXISTS_TAC `n:num` THEN ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN + FIRST_X_ASSUM (MP_TAC o SPECL [`n:num`;`u:complex`;`Cx(&0)`]) THEN + ASM_REWRITE_TAC[COMPLEX_MUL_RZERO]]; + REPEAT STRIP_TAC THEN MATCH_MP_TAC + (REWRITE_RULE [] + (SPECL [`f:complex->complex`; `\z. c*z`; `Cx(&0)`; + `s:complex->bool`] + HOLOMORPHIC_FUN_EQ_ON_CONNECTED)) THEN + ASM_REWRITE_TAC [COMPLEX_MUL_RZERO; HOLOMORPHIC_ON_LINEAR; + HIGHER_COMPLEX_DERIVATIVE_LINEAR] THEN + GEN_TAC THEN FIRST_X_ASSUM (MP_TAC o SPEC `n:num`) THEN + STRUCT_CASES_TAC (ARITH_RULE `n = 0 \/ n = 1 \/ 2 <= n`) THEN + ASM_SIMP_TAC [higher_complex_derivative; ARITH_EQ; ARITH_LE; ONE] THEN + ASM_SIMP_TAC [ARITH_RULE `2 <= n ==> ~(n=0)`] THEN + ASM_SIMP_TAC [ARITH_RULE `2 <= n ==> ~(n=SUC 0)`]]]) in + let LEMMA_2 = prove + (`!r c. &0 < r /\ &0 <= c /\ + (!x. &0 <= x /\ x < r ==> c * x < r) + ==> c <= &1`, + REPEAT STRIP_TAC THEN REWRITE_TAC [GSYM REAL_NOT_LT] THEN STRIP_TAC THEN + FIRST_X_ASSUM (MP_TAC o SPEC `r * (c + &1) / (&2 * c)`) THEN + REWRITE_TAC [MESON [] `((a ==> b) ==> F) <=> (a /\ ~b)`] THEN + CONJ_TAC THENL + [CONJ_TAC THENL + [MATCH_MP_TAC REAL_LE_MUL THEN CONJ_TAC THENL + [ASM_REAL_ARITH_TAC; MATCH_MP_TAC REAL_LE_DIV THEN ASM_REAL_ARITH_TAC]; + ALL_TAC] THEN + MATCH_MP_TAC REAL_LTE_TRANS THEN EXISTS_TAC `r * &1` THEN + CONJ_TAC THENL [ALL_TAC; REWRITE_TAC [REAL_MUL_RID; REAL_LE_REFL]] THEN + MATCH_MP_TAC REAL_LT_LMUL THEN ASM_REWRITE_TAC[] THEN + SUBGOAL_THEN `&0 < &2 * c` ASSUME_TAC THENL + [ASM_REAL_ARITH_TAC; + ASM_SIMP_TAC [REAL_LT_LDIV_EQ] THEN ASM_REAL_ARITH_TAC]; + REWRITE_TAC [REAL_NOT_LT] THEN + ONCE_REWRITE_TAC [REAL_RING `!a b c:real. a * b * c = b * a * c`] THEN + MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC `r * &1` THEN CONJ_TAC THENL + [REWRITE_TAC [REAL_MUL_RID; REAL_LE_REFL]; ALL_TAC] THEN + MATCH_MP_TAC REAL_LE_LMUL THEN CONJ_TAC THENL + [ASM_REAL_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `&0 < &2 * c` ASSUME_TAC THENL + [ASM_REAL_ARITH_TAC; ALL_TAC] THEN + ASM_SIMP_TAC [REAL_ARITH `&0 < c ==> a * b / c = (a * b) / c`] THEN + SUBGOAL_THEN `(c * (c + &1)) / (&2 * c) = (c + &1) / &2` + SUBST1_TAC THENL + [ASM_SIMP_TAC [RAT_LEMMA5; REAL_ARITH `&0 < &2`] THEN + ASM_REAL_ARITH_TAC; + ASM_REAL_ARITH_TAC]]) in + REPEAT STRIP_TAC THEN SUBGOAL_THEN + `!u z. norm u = &1 /\ z IN ball(Cx(&0),r) ==> u * g z = g (u * z)` + ASSUME_TAC THENL + [REPEAT STRIP_TAC THEN SUBGOAL_THEN `~(u = Cx(&0))` ASSUME_TAC THENL + [ASM_REWRITE_TAC[GSYM COMPLEX_NORM_NZ] THEN REAL_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `!w. w IN ball(Cx(&0),r) ==> f (u * g w) / u = w` + ASSUME_TAC THENL + [REPEAT STRIP_TAC THEN MATCH_MP_TAC FIRST_CARTAN_THM_DIM_1 THEN + EXISTS_TAC `ball(Cx(&0),r)` THEN EXISTS_TAC `Cx(&0)` THEN + ASM_REWRITE_TAC [OPEN_BALL;CONNECTED_BALL;BOUNDED_BALL; + COMPLEX_MUL_RZERO; CENTRE_IN_BALL] THEN + ASSERT_TAC `!z. norm (u * z) = norm z` THENL + [ASM_REWRITE_TAC [COMPLEX_NORM_MUL; REAL_MUL_LID]; ALL_TAC] THEN + ASSERT_TAC `!z. z IN ball(Cx(&0),r) ==> u * z IN ball(Cx(&0),r)` THENL + [ASM_REWRITE_TAC [COMPLEX_IN_BALL_0]; ALL_TAC] THEN + ASSERT_TAC `!z. z IN ball(Cx(&0),r) ==> z / u IN ball(Cx(&0),r)` THENL + [ASM_REWRITE_TAC [COMPLEX_IN_BALL_0; COMPLEX_NORM_DIV; REAL_DIV_1]; + ALL_TAC] THEN + CONJ_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN CONJ_TAC THENL + [MATCH_MP_TAC HOLOMORPHIC_ON_DIV THEN CONJ_TAC THENL + [ALL_TAC; ASM_REWRITE_TAC[HOLOMORPHIC_ON_CONST]] THEN + SUBGOAL_THEN `(\w:complex. f (u * g w) : complex) = f o (\w. u * g w)` + SUBST1_TAC THENL + [REWRITE_TAC [o_DEF]; MATCH_MP_TAC HOLOMORPHIC_ON_COMPOSE_GEN] THEN + EXISTS_TAC `ball(Cx(&0),r)` THEN ASM_REWRITE_TAC[] THEN CONJ_TAC THENL + [MATCH_MP_TAC HOLOMORPHIC_ON_MUL THEN + ASM_REWRITE_TAC[HOLOMORPHIC_ON_CONST]; + ASM_SIMP_TAC[]]; + ALL_TAC] THEN + CONJ_TAC THENL + [REWRITE_TAC [complex_div; COMPLEX_MUL_LZERO]; ALL_TAC] THEN + SUBGOAL_THEN `Cx(&1) = u / u` SUBST1_TAC THENL + [ASM_SIMP_TAC [COMPLEX_DIV_REFL]; ALL_TAC] THEN + MATCH_MP_TAC HAS_COMPLEX_DERIVATIVE_DERIVATIVE THEN + MATCH_MP_TAC HAS_COMPLEX_DERIVATIVE_CDIV_AT THEN + SUBGOAL_THEN `(\w:complex. f (u * g w) : complex) = f o (\w. u * g w)` + SUBST1_TAC THENL [REWRITE_TAC [o_DEF]; ALL_TAC] THEN + SUBGOAL_THEN + `((\w. f (u * g w)) has_complex_derivative + complex_derivative f (u * g(Cx(&0))) * + (u * complex_derivative g (Cx(&0)))) + (at (Cx (&0)))` MP_TAC THENL + [MATCH_MP_TAC (REWRITE_RULE [o_DEF] + (SPECL [`\w:complex. u * g(w):complex`; `f:complex->complex`] + COMPLEX_DIFF_CHAIN_AT)) THEN CONJ_TAC THENL + [MATCH_MP_TAC HAS_COMPLEX_DERIVATIVE_LMUL_AT THEN + REWRITE_TAC [HAS_COMPLEX_DERIVATIVE_DIFFERENTIABLE] THEN + MATCH_MP_TAC HOLOMORPHIC_ON_IMP_DIFFERENTIABLE_AT THEN + EXISTS_TAC `ball(Cx(&0),r)` THEN + ASM_REWRITE_TAC[OPEN_BALL; CENTRE_IN_BALL]; + REWRITE_TAC [HAS_COMPLEX_DERIVATIVE_DIFFERENTIABLE] THEN + MATCH_MP_TAC HOLOMORPHIC_ON_IMP_DIFFERENTIABLE_AT THEN + EXISTS_TAC `ball(Cx(&0),r)` THEN + ASM_REWRITE_TAC[OPEN_BALL; CENTRE_IN_BALL; COMPLEX_MUL_RZERO]]; + SUBGOAL_THEN + `complex_derivative f (u * g (Cx (&0))) * + (u * complex_derivative g (Cx (&0))) = u` + SUBST1_TAC THENL + [ALL_TAC; REWRITE_TAC[o_DEF]] THEN + ABBREV_TAC `g' = complex_derivative g (Cx(&0))` THEN + ABBREV_TAC `f' = complex_derivative f (Cx(&0))` THEN + SUBGOAL_THEN `f' * g' = Cx(&1)` ASSUME_TAC THENL + [EXPAND_TAC "g'" THEN EXPAND_TAC "f'" THEN + SUBGOAL_THEN `complex_derivative g (Cx(&0)) = + complex_derivative g (f (Cx(&0)))` SUBST1_TAC THENL + [ASM_REWRITE_TAC []; + MATCH_MP_TAC COMPLEX_DERIVATIVE_LEFT_INVERSE THEN + EXISTS_TAC `ball(Cx(&0),r)` THEN EXISTS_TAC `ball(Cx(&0),r)` THEN + ASM_REWRITE_TAC [OPEN_BALL; CENTRE_IN_BALL]]; + ASM_REWRITE_TAC [COMPLEX_MUL_RZERO] THEN + POP_ASSUM MP_TAC THEN CONV_TAC COMPLEX_RING]]; + SUBGOAL_THEN `f(u*g(z)) = f (g (u * z)) : complex` MP_TAC THENL + [MATCH_MP_TAC EQ_TRANS THEN EXISTS_TAC `u * z:complex` THEN CONJ_TAC THENL + [SUBGOAL_THEN `!x y:complex. x / u = y ==> x = u * y` MATCH_MP_TAC THENL + [REWRITE_TAC [complex_div] THEN GEN_TAC THEN GEN_TAC THEN + DISCH_THEN (SUBST1_TAC o GSYM) THEN + SUBGOAL_THEN `x = (inv u * u) * x` MP_TAC THENL + [ASM_SIMP_TAC [COMPLEX_MUL_LINV; COMPLEX_MUL_LID]; + REWRITE_TAC [COMPLEX_MUL_AC]]; + POP_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC []]; + MATCH_MP_TAC EQ_SYM THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_REWRITE_TAC [COMPLEX_IN_BALL_0; COMPLEX_NORM_MUL; REAL_MUL_LID] THEN + ASM_REWRITE_TAC [GSYM COMPLEX_IN_BALL_0]]; + DISCH_TAC THEN SUBGOAL_THEN + `g (f (u * g z)) = g (f (g (u * z : complex))) : complex` MP_TAC THENL + [POP_ASSUM SUBST1_TAC THEN REWRITE_TAC []; + SUBGOAL_THEN `u * g z IN ball (Cx(&0),r) /\ u * z IN ball(Cx(&0),r)` + MP_TAC THENL + [ASM_REWRITE_TAC [COMPLEX_IN_BALL_0; COMPLEX_NORM_MUL; REAL_MUL_LID] THEN + REWRITE_TAC [GSYM COMPLEX_IN_BALL_0] THEN ASM_SIMP_TAC[]; + ASM_SIMP_TAC[]]]]]; + SUBGOAL_THEN `?c. !z. z IN ball(Cx(&0),r) ==> g z = c * z` + STRIP_ASSUME_TAC THENL + [MATCH_MP_TAC LEMMA_1 THEN + ASM_SIMP_TAC [OPEN_BALL; CONNECTED_BALL; CENTRE_IN_BALL] THEN + SIMP_TAC [COMPLEX_IN_BALL_0; COMPLEX_NORM_MUL; REAL_MUL_LID]; + ALL_TAC] THEN + SUBGOAL_THEN `norm (c:complex) = &1` ASSUME_TAC THENL + [ALL_TAC; ASM_MESON_TAC [COMPLEX_NORM_EQ_1_CEXP]] THEN + SUBGOAL_THEN `~(norm (c:complex) = &0)` ASSUME_TAC THENL + [REWRITE_TAC [COMPLEX_NORM_ZERO] THEN STRIP_TAC THEN + SUBGOAL_THEN `Cx(&0) = Cx(r / &2)` MP_TAC THENL + [ALL_TAC; REWRITE_TAC [CX_INJ] THEN ASM_REAL_ARITH_TAC] THEN + SUBGOAL_THEN `Cx(r / &2) IN ball(Cx(&0),r)` ASSUME_TAC THENL + [REWRITE_TAC [COMPLEX_IN_BALL_0; CX_DIV; COMPLEX_NORM_DIV; + COMPLEX_NORM_NUM] THEN + REWRITE_TAC [COMPLEX_NORM_CX] THEN ASM_REAL_ARITH_TAC; + EQ_TRANS_TAC `g (f (Cx(r / &2)):complex):complex` THENL + [EQ_TRANS_TAC `c * (f (Cx(r / &2)):complex)` THENL + [ASM_REWRITE_TAC [COMPLEX_MUL_LZERO]; ASM_MESON_TAC[]]; + ASM_MESON_TAC[]]]; + ALL_TAC] THEN SUBGOAL_THEN `&0 < norm (c:complex)` ASSUME_TAC THENL + [POP_ASSUM MP_TAC THEN CONV_TAC NORM_ARITH; ALL_TAC] THEN + REWRITE_TAC [GSYM REAL_LE_ANTISYM] THEN CONJ_TAC THENL + [MATCH_MP_TAC LEMMA_2 THEN EXISTS_TAC `r : real` THEN + ASM_REWRITE_TAC [NORM_POS_LE] THEN GEN_TAC THEN STRIP_TAC THEN + ABBREV_TAC `p = Cx x` THEN + SUBGOAL_THEN `x = norm (p:complex)` SUBST_ALL_TAC THENL + [EXPAND_TAC "p" THEN REWRITE_TAC [COMPLEX_NORM_CX] THEN + ASM_REAL_ARITH_TAC; + REWRITE_TAC [GSYM COMPLEX_NORM_MUL] THEN + SUBGOAL_THEN `c * p = g p` SUBST1_TAC THENL + [ALL_TAC; ASM_MESON_TAC [COMPLEX_IN_BALL_0]] THEN + FIRST_X_ASSUM (MATCH_MP_TAC o GSYM) THEN + ASM_MESON_TAC [COMPLEX_IN_BALL_0]]; + ALL_TAC] THEN + SUBST1_TAC (GSYM (SPEC `norm (c:complex)` REAL_INV_INV)) THEN + MATCH_MP_TAC REAL_INV_1_LE THEN CONJ_TAC THENL + [ASM_MESON_TAC [REAL_LT_INV]; ALL_TAC] THEN + MATCH_MP_TAC LEMMA_2 THEN EXISTS_TAC `r:real` THEN ASM_REWRITE_TAC [] THEN + CONJ_TAC THENL + [MATCH_MP_TAC REAL_LE_INV THEN ASM_REAL_ARITH_TAC; ALL_TAC] THEN + GEN_TAC THEN STRIP_TAC THEN + SUBGOAL_THEN `x = norm (g (f (Cx x):complex):complex)` SUBST1_TAC THENL + [SUBGOAL_THEN `g (f (Cx x):complex) = Cx x` SUBST1_TAC THENL + [FIRST_X_ASSUM MATCH_MP_TAC THEN + REWRITE_TAC [COMPLEX_IN_BALL_0; COMPLEX_NORM_CX] THEN + ASM_REAL_ARITH_TAC; + REWRITE_TAC [COMPLEX_NORM_CX] THEN ASM_REAL_ARITH_TAC]; + SUBGOAL_THEN `g (f (Cx x):complex) = c * f (Cx x) : complex` + SUBST1_TAC THENL + [FIRST_X_ASSUM MATCH_MP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + REWRITE_TAC [COMPLEX_IN_BALL_0; COMPLEX_NORM_CX] THEN + ASM_REAL_ARITH_TAC; + REWRITE_TAC [COMPLEX_NORM_MUL; REAL_MUL_ASSOC] THEN + ASM_SIMP_TAC [REAL_MUL_LINV; REAL_MUL_LID; GSYM COMPLEX_IN_BALL_0] THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN + REWRITE_TAC [COMPLEX_IN_BALL_0; COMPLEX_NORM_CX] THEN + ASM_REAL_ARITH_TAC]]]);; + +(* ------------------------------------------------------------------------- *) +(* Cauchy's inequality. *) +(* ------------------------------------------------------------------------- *) + +let CAUCHY_INEQUALITY = prove + (`!f z r (B:real) n. + f continuous_on cball(z,r) /\ + f holomorphic_on ball(z,r) /\ &0 < r /\ + (!x:complex. norm(z-x) = r ==> norm(f x) <= B) + ==> norm (higher_complex_derivative n f z) <= &(FACT n) * B / r pow n`, + REPEAT STRIP_TAC THEN SUBGOAL_THEN `&0 <= B` ASSUME_TAC THENL + [SUBGOAL_THEN `?x:complex. norm (z-x) = r` STRIP_ASSUME_TAC THENL [ + EXISTS_TAC `z + Cx r` THEN ASM_SIMP_TAC[COMPLEX_ADD_SUB2;NORM_NEG; + COMPLEX_NORM_CX;REAL_ABS_REFL;REAL_LT_IMP_LE];ALL_TAC] THEN + ASM_MESON_TAC [NORM_POS_LE;REAL_LE_TRANS]; + SUBGOAL_THEN `norm ((Cx(&2) * Cx pi * ii) / Cx(&(FACT n)) + * higher_complex_derivative n f z) + <= (B / r pow (n + 1)) * &2 * pi * r` MP_TAC THENL[ + MATCH_MP_TAC HAS_PATH_INTEGRAL_BOUND_CIRCLEPATH THEN + EXISTS_TAC `\u. (f:complex->complex) u / (u - z) pow (n + 1)` THEN + EXISTS_TAC `z:complex` THEN CONJ_TAC THENL [MATCH_MP_TAC + CAUCHY_HAS_PATH_INTEGRAL_HIGHER_DERIVATIVE_CIRCLEPATH THEN + ASM_SIMP_TAC [CENTRE_IN_BALL]; ALL_TAC] THEN CONJ_TAC THENL + [MATCH_MP_TAC REAL_LE_DIV THEN ASM_SIMP_TAC + [REAL_POW_LE;REAL_LT_IMP_LE];ALL_TAC]THEN ASM_REWRITE_TAC [] + THEN GEN_TAC THEN DISCH_TAC THEN + ASM_REWRITE_TAC [COMPLEX_NORM_DIV;COMPLEX_NORM_POW] THEN MATCH_MP_TAC + REAL_LE_TRANS THEN EXISTS_TAC `B:real / r pow (n+1)` THEN + ASM_SIMP_TAC[ REAL_LE_DIV2_EQ; REAL_POW_LT;NORM_SUB;REAL_LE_REFL]; + REWRITE_TAC[COMPLEX_NORM_DIV;COMPLEX_NORM_MUL; COMPLEX_NORM_II; + COMPLEX_NORM_CX; REAL_ABS_NUM; REAL_ABS_PI; REAL_MUL_RID;REAL_ABS_NUM] + THEN SUBGOAL_THEN `B / r pow (n + 1) * &2 * pi * r = + (&2 * pi) / &(FACT n) * (((&(FACT n) * B) * r/ r pow (n+1)))` + SUBST1_TAC THENL [SUBGOAL_THEN `~(&(FACT n) = &0)` MP_TAC THENL + [REWRITE_TAC [FACT_NZ;REAL_OF_NUM_EQ];ALL_TAC] + THEN CONV_TAC REAL_FIELD;SUBGOAL_THEN `&0 < (&2 * pi) / &(FACT n)` ASSUME_TAC + THENL[MATCH_MP_TAC REAL_LT_DIV THEN SIMP_TAC[FACT_LT;REAL_OF_NUM_LT] THEN + MP_TAC PI_POS THEN REAL_ARITH_TAC;SUBGOAL_THEN `(&(FACT n) * B) * r / r pow + (n + 1) = &(FACT n) * B / r pow n` SUBST1_TAC THENL + [REWRITE_TAC[GSYM ADD1; real_pow] THEN MP_TAC (ASSUME `&0 < r`) THEN + CONV_TAC REAL_FIELD; ASM_MESON_TAC [REAL_LE_LCANCEL_IMP]]]]]]);; + +(* ------------------------------------------------------------------------- *) +(* A holomorphic function f has only isolated zeros unless f is 0. *) +(* ------------------------------------------------------------------------- *) + +let ISOLATED_ZEROS = prove + (`!f a z w. + open a /\ connected a /\ f holomorphic_on a /\ z IN a /\ f z = Cx(&0) /\ + w IN a /\ ~(f w = Cx(&0)) + ==> (?r. &0 < r /\ ball(z,r) SUBSET a /\ + (!w. w IN ball(z,r) /\ ~(w=z) ==> ~(f w = Cx(&0))))`, + REPEAT STRIP_TAC THEN ASSERT_TAC `?k. + ~(higher_complex_derivative k f z = Cx(&0)) /\ + (!n. n < k ==> higher_complex_derivative n f z = Cx(&0))` THENL + [EXISTS_TAC `minimal n. (~(higher_complex_derivative n f z = Cx(&0)))` + THEN SUBGOAL_THEN `?k'. ~(higher_complex_derivative k' f z = Cx(&0))` + (fun th-> ASM_MESON_TAC[th;MINIMAL]) THEN REWRITE_TAC[GSYM NOT_FORALL_THM] + THEN STRIP_TAC THEN ASM_MESON_TAC[HOLOMORPHIC_FUN_EQ_0_ON_CONNECTED]; + ALL_TAC] THEN SUBGOAL_THEN `~(k = 0)`ASSUME_TAC THENL + [STRIP_TAC THEN MP_TAC(ASSUME `~(higher_complex_derivative k f z = Cx(&0))`) + THEN ASM_MESON_TAC[higher_complex_derivative]; + STRIP_ASSUME_TAC (MESON [OPEN_CONTAINS_BALL;ASSUME `open (a:complex->bool)`; + ASSUME `z:complex IN a`] `?s. &0 < s /\ ball (z:complex,s) SUBSET a`) + THEN ASSUME_TAC (MESON [HOLOMORPHIC_POWER_SERIES; + ASSUME `f holomorphic_on a`;ASSUME `ball (z:complex,s) + SUBSET a`;HOLOMORPHIC_ON_SUBSET] `!w:complex. w IN ball(z,s) ==> + ((\n. higher_complex_derivative n f z / Cx(&(FACT n))*(w -z) pow n) sums f w) + (from 0)`) THEN ASSERT_TAC `?g:complex->complex. !x:complex. + x IN ball(z,s) ==> + (((\n. higher_complex_derivative n f z / Cx(&(FACT n)) * + (x - z) pow (n-k))) sums g x) (from k)` THENL + [EXISTS_TAC `\x:complex. lim sequentially + (\m. vsum (k..m) (\n. higher_complex_derivative n f z / Cx(&(FACT n)) * + (x - z) pow (n-k)))` THEN GEN_TAC THEN DISCH_TAC THEN + SUBGOAL_THEN `!m. k..m = (0..m) INTER from k` ASSUME_TAC THENL + [REWRITE_TAC[EXTENSION; IN_FROM; IN_INTER; IN_ELIM_THM; IN_NUMSEG] THEN + ARITH_TAC;ASM_REWRITE_TAC[] THEN REWRITE_TAC + [SET_RULE `!m. (0..m) INTER from k = from k INTER (0..m)`;SUMS_LIM]] THEN + ASM_CASES_TAC `x:complex = z` THENL + [ASM_REWRITE_TAC[COMPLEX_SUB_REFL;summable] THEN + EXISTS_TAC `higher_complex_derivative k f z / Cx(&(FACT k))` THEN + MATCH_MP_TAC SUMS_EQ THEN EXISTS_TAC `\n. if n = k then + higher_complex_derivative k f z / Cx(&(FACT k)) else Cx(&0)` + THEN CONJ_TAC THENL [REWRITE_TAC [IN_FROM] THEN GEN_TAC THEN DISCH_TAC + THEN COND_CASES_TAC THENL + [ASM_REWRITE_TAC[COMPLEX_POW_ZERO;SUB_REFL;COMPLEX_MUL_RID]; + ASM_SIMP_TAC[COMPLEX_POW_ZERO; ARITH_RULE `k <= x' /\ ~(x' = k) ==> + ~(x' - k = 0)`;COMPLEX_MUL_RZERO]]; MATCH_MP_TAC SERIES_VSUM THEN + EXISTS_TAC `{k:num}` THEN SIMP_TAC [FINITE_SING;from;IN_SING; + COMPLEX_VEC_0;VSUM_SING] THEN SET_TAC[LE_REFL]]; + MATCH_MP_TAC SUMMABLE_EQ THEN EXISTS_TAC + `\n. higher_complex_derivative n f z / Cx(&(FACT n)) * + (x - z) pow n / (x-z) pow k` THEN CONJ_TAC THENL [REWRITE_TAC [IN_FROM] + THEN GEN_TAC THEN DISCH_TAC THEN SUBGOAL_THEN `(x:complex - z) pow (x' - k) + = (x - z) pow x' / (x - z) pow k` (fun th-> + REWRITE_TAC[th;COMPLEX_EQ_MUL_LCANCEL]) THEN MATCH_MP_TAC + COMPLEX_DIV_POW THEN ASM_SIMP_TAC [COMPLEX_SUB_0]; + SUBGOAL_THEN `(\n. higher_complex_derivative n f z / Cx(&(FACT n)) * + (x - z) pow n / (x - z) pow k) = (\n. (higher_complex_derivative n f z / + Cx(&(FACT n)) *(x - z) pow n) / (x - z) pow k) ` SUBST1_TAC + THENL [REWRITE_TAC [FUN_EQ_THM] THEN GEN_TAC THEN CONV_TAC COMPLEX_FIELD; + MATCH_MP_TAC SUMMABLE_COMPLEX_DIV THEN MATCH_MP_TAC SUMMABLE_FROM_ELSEWHERE + THEN EXISTS_TAC `0` THEN ASM_MESON_TAC[summable]]]];ALL_TAC] THEN + ASSERT_TAC `~(g (z:complex) = Cx(&0)) /\ + (!x. x IN ball(z,s) ==> f x = (x - z) pow k * g(x))` THENL + [CONJ_TAC THENL [MATCH_MP_TAC + (COMPLEX_FIELD `!x y:complex. x = y /\ ~(y= Cx(&0)) ==> ~(x=Cx(&0))`) THEN + EXISTS_TAC `higher_complex_derivative k f z / Cx(&(FACT k))` THEN + CONJ_TAC THENL [ONCE_REWRITE_TAC [GSYM COMPLEX_SUB_0] THEN + MATCH_MP_TAC SERIES_UNIQUE THEN EXISTS_TAC + `(\n. higher_complex_derivative n f z / Cx(&(FACT n)) * + Cx(&0) pow (n-k))` THEN EXISTS_TAC `from (k +1)` THEN + CONJ_TAC THENL [SUBST1_TAC (MESON [VSUM_SING_NUMSEG] + `higher_complex_derivative k f z / Cx(&(FACT k)) = + vsum (k..k) (\n. higher_complex_derivative n f z / Cx(&(FACT n))) `) + THEN SUBGOAL_THEN `vsum (k..k) (\n. higher_complex_derivative n f z + / Cx(&(FACT n))) = vsum (k..((k+1)-1)) (\n. higher_complex_derivative n f z + / Cx(&(FACT n)) * Cx(&0) pow (n - k))` SUBST1_TAC THENL [ + REWRITE_TAC[VSUM_SING_NUMSEG; COMPLEX_POW_ZERO;SUB_REFL;COMPLEX_MUL_RID; + ARITH_RULE `((k:num) + 1) -1 = k`]; + MATCH_MP_TAC SUMS_OFFSET THEN ASM_REWRITE_TAC[ARITH_RULE `k:num < k+1`] + THEN POP_ASSUM (MP_TAC o SPEC `z:complex`) THEN + ASM_REWRITE_TAC[CENTRE_IN_BALL;COMPLEX_SUB_REFL]];MATCH_MP_TAC + SUMS_COMPLEX_0 THEN GEN_TAC THEN SIMP_TAC [IN_FROM;COMPLEX_POW_ZERO; + ARITH_RULE `k + 1 <= n <=> ~(n-k= 0)`;COMPLEX_MUL_RZERO]]; + MATCH_MP_TAC (COMPLEX_FIELD `!x y. ~(x = Cx(&0)) /\ ~(y = Cx(&0)) + ==> ~(x / y = Cx(&0))`) THEN ASM_REWRITE_TAC[GSYM COMPLEX_NORM_ZERO] THEN + SUBST1_TAC (MESON [COMPLEX_NORM_CX] + `norm (Cx(&(FACT k))) = abs ((&(FACT k)))`) THEN + SIMP_TAC [REAL_ABS_ZERO;FACT_LT;REAL_OF_NUM_LT;REAL_LT_IMP_NZ]]; ALL_TAC] + THEN GEN_TAC THEN DISCH_TAC THEN MATCH_MP_TAC SERIES_UNIQUE THEN + EXISTS_TAC `(\n. higher_complex_derivative n f z / Cx(&(FACT n)) * + (x - z) pow n)`THEN EXISTS_TAC `(from 0)` THEN + CONJ_TAC THENL [FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[]; + ASM_CASES_TAC `x:complex = z` THENL [ + ASM_REWRITE_TAC[COMPLEX_SUB_REFL] THEN MATCH_MP_TAC SUMS_EQ THEN + EXISTS_TAC `\n:num. Cx(&0)` THEN CONJ_TAC THENL + [REWRITE_TAC[IN_FROM;COMPLEX_POW_ZERO] THEN X_GEN_TAC `n:num` THEN + DISCH_TAC THEN COND_CASES_TAC THENL [ + ASM_REWRITE_TAC[higher_complex_derivative] THEN CONV_TAC COMPLEX_FIELD; + REWRITE_TAC[COMPLEX_MUL_RZERO]]; + ASM_REWRITE_TAC[COMPLEX_POW_ZERO;COMPLEX_MUL_LZERO] THEN + ASM_REWRITE_TAC[SERIES_0;GSYM COMPLEX_VEC_0]];ALL_TAC] THEN + MATCH_MP_TAC SUMS_EQ THEN EXISTS_TAC `\n.(x-z) pow k * + higher_complex_derivative n f z / Cx(&(FACT n)) *(x - z) pow (n - k)` + THEN CONJ_TAC THENL [REWRITE_TAC[IN_FROM] THEN X_GEN_TAC `n:num` + THEN DISCH_TAC THEN ASM_CASES_TAC `n:num < k` THENL [ASM_SIMP_TAC[] + THEN CONV_TAC COMPLEX_FIELD; + SUBGOAL_THEN `(x:complex-z) pow (n-k) = (x-z) pow n / (x-z) pow k` + SUBST1_TAC THENL [MATCH_MP_TAC COMPLEX_DIV_POW THEN + ASM_SIMP_TAC[COMPLEX_SUB_0; ARITH_RULE `~(n:num < k) ==> k <= n`]; + SUBST1_TAC (COMPLEX_FIELD `(x - z) pow k * + higher_complex_derivative n f z / Cx(&(FACT n)) * + (x - z) pow n / (x - z) pow k = + higher_complex_derivative n f z / Cx(&(FACT n)) * (x-z) pow k * + (x - z) pow n / (x - z) pow k`) THEN MESON_TAC [ASSUME `~(x:complex = z)`; + COMPLEX_DIV_LMUL;COMPLEX_SUB_0;COMPLEX_POW_EQ_0]]]; + MATCH_MP_TAC SERIES_COMPLEX_LMUL THEN SUBST1_TAC + (MESON [COMPLEX_ADD_RID] `(g:complex->complex) x = g x + Cx(&0)`) THEN + SUBGOAL_THEN `Cx(&0) = vsum (0.. (k-1)) + (\n. higher_complex_derivative n f z / Cx(&(FACT n)) * (x - z) pow (n - k))` + SUBST1_TAC THENL [ONCE_REWRITE_TAC[EQ_SYM_EQ] THEN + REWRITE_TAC [GSYM COMPLEX_VEC_0] THEN MATCH_MP_TAC VSUM_EQ_0 THEN + REWRITE_TAC [IN_NUMSEG] THEN X_GEN_TAC `n:num` THEN DISCH_TAC THEN + ASM_SIMP_TAC[ARITH_RULE ` ~(k = 0) /\ n <= k - 1 ==> n < k`] THEN + REWRITE_TAC[COMPLEX_VEC_0] THEN CONV_TAC COMPLEX_FIELD; + MATCH_MP_TAC SUMS_OFFSET_REV THEN + ASM_SIMP_TAC[ARITH_RULE `0 <= k /\ ~(k = 0) ==> 0 < k`;LE_0]]]];ALL_TAC] THEN + ASSERT_TAC `?r. &0 < r /\ (!x:complex. dist (z,x) < r ==> + ~((g:complex->complex) x = Cx(&0)))` THENL [ + MATCH_MP_TAC CONTINUOUS_ON_OPEN_AVOID THEN + EXISTS_TAC `ball(z:complex, s)` THEN + ASM_REWRITE_TAC[OPEN_BALL;CENTRE_IN_BALL] + THEN MATCH_MP_TAC HOLOMORPHIC_ON_IMP_CONTINUOUS_ON THEN + MATCH_MP_TAC ANALYTIC_IMP_HOLOMORPHIC THEN MATCH_MP_TAC POWER_SERIES_ANALYTIC + THEN EXISTS_TAC `\n. higher_complex_derivative (n+k) f z / Cx(&(FACT (n+k)))` + THEN EXISTS_TAC `from 0` THEN REWRITE_TAC[] THEN GEN_TAC THEN DISCH_TAC + THEN REWRITE_TAC[SERIES_FROM] THEN MATCH_MP_TAC LIM_TRANSFORM THEN + EXISTS_TAC `(\n.vsum (k..(k+n)) + (\n. higher_complex_derivative n f z / Cx(&(FACT n)) *(w' - z) pow (n-k)))` + THEN CONJ_TAC THENL [SIMP_TAC [VSUM_OFFSET_0;ARITH_RULE + `!k n :num.(k + n) - k = n`; ARITH_RULE `!k n:num. k <= k + n`;ADD_ASSOC; + ARITH_RULE `!k n :num.(n + k) - k = n`] THEN + SUBGOAL_THEN `(\x. vsum (0..x) (\i. higher_complex_derivative (i + k) + f z / Cx(&(FACT (i + k))) * (w' - z) pow i) + - vsum (0..x) (\n. higher_complex_derivative (n + k) f z + / Cx(&(FACT (n + k))) * (w' - z) pow n)) = (\x. Cx(&0))` + (fun th-> SIMP_TAC[th;COMPLEX_VEC_0;LIM_CONST]) THEN + REWRITE_TAC[FUN_EQ_THM] THEN GEN_TAC THEN REWRITE_TAC[COMPLEX_SUB_0]; + SUBGOAL_THEN `(\n. vsum (k..k + n) + (\n. higher_complex_derivative n f z / Cx(&(FACT n)) *(w' - z) pow (n - k))) + = (\n. vsum (k..n+k)(\n. higher_complex_derivative n f z / Cx(&(FACT n)) * + (w' - z) pow (n - k)))` SUBST1_TAC THENL [ + REWRITE_TAC[FUN_EQ_THM] THEN GEN_TAC THEN REWRITE_TAC[ADD_SYM]; + MP_TAC (ISPECL [`(\n. vsum (k..n) + (\n. higher_complex_derivative n f z / Cx(&(FACT n)) * + (w' - z) pow (n - k)))`;`(g:complex->complex) w'`;`k:num`] + SEQ_OFFSET) THEN ONCE_REWRITE_TAC[GSYM SERIES_FROM] THEN ASM_SIMP_TAC[]]]; + ALL_TAC] THEN EXISTS_TAC `min r s` THEN CONJ_TAC THENL + [MP_TAC (CONJ (ASSUME `&0 < r`) (ASSUME `&0 < s`)) THEN REAL_ARITH_TAC; + CONJ_TAC THENL [REWRITE_TAC[real_min] THEN COND_CASES_TAC + THENL [MATCH_MP_TAC SUBSET_TRANS THEN EXISTS_TAC `ball(z:complex,s)` + THEN ASM_REWRITE_TAC[ball] THEN SET_TAC[ASSUME `r:real <= s`;REAL_LTE_TRANS]; + ASM_REWRITE_TAC[]];GEN_TAC THEN STRIP_TAC THEN + SUBGOAL_THEN `(f:complex->complex) w' = + (w' - z) pow k * (g:complex->complex) w'` SUBST1_TAC + THENL [FIRST_ASSUM MATCH_MP_TAC THEN + MP_TAC (ASSUME `w':complex IN ball (z,min r s)`) THEN REWRITE_TAC [real_min] + THEN COND_CASES_TAC THENL [ASM_MESON_TAC[IN_BALL;REAL_LTE_TRANS]; + REWRITE_TAC[]];SIMP_TAC [COMPLEX_ENTIRE;DE_MORGAN_THM] THEN + CONJ_TAC THENL [REWRITE_TAC[COMPLEX_POW_EQ_0;DE_MORGAN_THM] + THEN DISJ1_TAC THEN ASM_REWRITE_TAC [COMPLEX_SUB_0]; + FIRST_X_ASSUM MATCH_MP_TAC THEN MP_TAC (ASSUME `w':complex IN + ball (z,min r s)`) THEN REWRITE_TAC [real_min] THEN COND_CASES_TAC + THENL [REWRITE_TAC[IN_BALL]; + ASM_MESON_TAC[REAL_NOT_LE;IN_BALL;REAL_LT_TRANS]]]]]]]);; + +(* ------------------------------------------------------------------------- *) +(* Analytic continuation. *) +(* ------------------------------------------------------------------------- *) + +let ANALYTIC_CONTINUATION = prove + (`!f a u z. + open a /\ connected a /\ f holomorphic_on a /\ u SUBSET a /\ z IN a /\ + z limit_point_of u /\ (!w. w IN u ==> f w = Cx(&0)) + ==> (!w. w IN a ==> f w = Cx(&0))`, + REPEAT GEN_TAC THEN STRIP_TAC THEN + REWRITE_TAC[TAUT ` (p ==> q) <=> ~( p /\ (~ q))`;GSYM NOT_EXISTS_THM] + THEN STRIP_TAC THEN SUBGOAL_THEN `(f:complex->complex) z = Cx(&0)` + ASSUME_TAC THENL [STRIP_ASSUME_TAC(MESON [OPEN_CONTAINS_CBALL; + ASSUME `open (a:complex->bool)`; ASSUME `z:complex IN a`] + `?e. &0 < e /\ cball (z:complex,e) SUBSET a`) THEN ABBREV_TAC + `s = cball(z:complex,e) INTER (u:complex->bool)` THEN + ASSERT_TAC `f:complex->complex continuous_on closure s /\ + (!x:complex. x IN s ==> f x = Cx(&0)) /\ + z:complex IN closure s` + THENL [CONJ_TAC THENL [MATCH_MP_TAC CONTINUOUS_ON_SUBSET THEN + EXISTS_TAC `a:complex->bool` THEN + ASM_SIMP_TAC[HOLOMORPHIC_ON_IMP_CONTINUOUS_ON] THEN MATCH_MP_TAC + SUBSET_TRANS THEN EXISTS_TAC `cball(z:complex,e)` THEN + ASM_MESON_TAC[CLOSED_CBALL;INTER_SUBSET;CLOSURE_MINIMAL]; + CONJ_TAC THENL [ASM_MESON_TAC[INTER_SUBSET;SUBSET]; + ASM_SIMP_TAC[closure;IN_UNION] THEN DISJ2_TAC THEN SUBGOAL_THEN + `z:complex limit_point_of s` (fun thm-> SET_TAC[thm]) THEN + REWRITE_TAC [LIMPT_APPROACHABLE] THEN GEN_TAC THEN DISCH_TAC THEN + ASSERT_TAC `?x:complex. x IN u /\ ~(x = z) /\ dist (x , z) < min e' e` + THENL [MP_TAC (ISPECL [`z:complex`;`u:complex->bool`] LIMPT_APPROACHABLE) + THEN ASM_SIMP_TAC[REAL_LT_MIN];EXISTS_TAC `x:complex` THEN ASM_REWRITE_TAC[] + THEN CONJ_TAC THENL + [REWRITE_TAC [GSYM (ASSUME `cball (z:complex,e) INTER u = s`);IN_INTER; + ASSUME `x:complex IN u`;IN_CBALL] THEN ASM_MESON_TAC[REAL_LT_IMP_LE; + REAL_LT_MIN;DIST_SYM]; ASM_MESON_TAC [REAL_LT_MIN]]]]]; + ASM_MESON_TAC [CONTINUOUS_CONSTANT_ON_CLOSURE]]; + MP_TAC(SPECL [`f:complex->complex`;`a:complex->bool`;`z:complex`;`w:complex`] + ISOLATED_ZEROS) THEN ASM_REWRITE_TAC[] THEN STRIP_TAC THEN + SUBGOAL_THEN `?x:complex. x IN ball(z,r) /\ x IN u /\ ~(x=z) /\ + (f:complex->complex) x = Cx(&0)`(fun thm->ASM_MESON_TAC[thm]) THEN + MP_TAC (ISPECL [`z:complex`;`u:complex->bool`] LIMPT_APPROACHABLE) THEN + ASM_REWRITE_TAC [] THEN DISCH_TAC THEN POP_ASSUM (MP_TAC o SPEC `r:real`) + THEN ASM_REWRITE_TAC [] THEN STRIP_TAC THEN EXISTS_TAC `x':complex` + THEN ASM_MESON_TAC[IN_BALL;DIST_SYM]]);; + +(* ------------------------------------------------------------------------- *) +(* Open mapping theorem. *) +(* ------------------------------------------------------------------------- *) + +let OPEN_MAPPING_THM = prove + (`!a f. + open a /\ connected a /\ f holomorphic_on a /\ + ~(?c:complex. !z:complex. z IN a ==> f z = c) + ==> (!u. open u /\ u SUBSET a ==> open(IMAGE f u))`, + let LEMMA_ZERO = prove + (`!f z r. f continuous_on cball(z,r) /\ f holomorphic_on ball(z,r) /\ + &0 < r /\ (!w. norm(z-w) =r ==> norm(f z) < norm(f w)) + ==> (?w. w IN ball(z,r) /\ f w = Cx(&0))`, + REPEAT STRIP_TAC THEN SUBGOAL_THEN ` ((!x:complex. x IN ball(z,r) ==> + ~((f:complex->complex) x = Cx(&0))) ==> F ) ==> ( ?w:complex. w IN ball(z,r) + /\ f w = Cx(&0))` MATCH_MP_TAC THENL [MESON_TAC[]; + STRIP_TAC THEN SUBGOAL_THEN `&0 < norm ((f:complex->complex) z)` ASSUME_TAC + THENL [ASM_SIMP_TAC[COMPLEX_NORM_NZ; CENTRE_IN_BALL; SPEC `z:complex` + (ASSUME`!x:complex. x IN ball(z,r) ==> ~((f:complex->complex) x = Cx(&0))`)]; + ALL_TAC] THEN SUBGOAL_THEN + `(!x:complex. x IN cball(z,r) ==> ~((f:complex->complex) x = Cx(&0)))` + ASSUME_TAC THENL [GEN_TAC THEN REWRITE_TAC [IN_CBALL;dist] + THEN REWRITE_TAC[REAL_ARITH `a <= b <=> a < b \/ a = b`] THEN + REWRITE_TAC [TAUT `((p \/ q) ==> r ) <=> ((p ==> r ) /\ (q ==> r))`] THEN + CONJ_TAC THENL [ASM_MESON_TAC[IN_BALL;dist]; + DISCH_TAC THEN REWRITE_TAC[GSYM COMPLEX_NORM_ZERO] THEN MATCH_MP_TAC + REAL_LT_IMP_NZ THEN MATCH_MP_TAC REAL_LT_TRANS THEN EXISTS_TAC + `norm ((f:complex->complex) z)` THEN + ASM_SIMP_TAC [SPEC `z':complex` (ASSUME `!w:complex. norm (w - z) = r + ==> norm ((f:complex->complex) z) < norm (f w)`)]]; + ALL_TAC] THEN SUBGOAL_THEN `~(frontier(cball(z:complex,r))={})` ASSUME_TAC + THENL [REWRITE_TAC[FRONTIER_CBALL;sphere;dist] THEN SUBGOAL_THEN `?x:complex. + norm(z-x) = r` (fun th-> SET_TAC [MEMBER_NOT_EMPTY;th]) THEN EXISTS_TAC + `z + Cx r` THEN ASM_SIMP_TAC[COMPLEX_ADD_SUB2;NORM_NEG;COMPLEX_NORM_CX; + REAL_ABS_REFL;REAL_LT_IMP_LE];ALL_TAC] THEN + ABBREV_TAC `g = \z. inv ((f:complex->complex) z)` THEN ASSERT_TAC + `(g:complex->complex) continuous_on cball(z,r) /\ g holomorphic_on ball(z,r)` + THENL [CONJ_TAC THENL [EXPAND_TAC "g" THEN + REWRITE_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN] THEN GEN_TAC THEN DISCH_TAC + THEN MATCH_MP_TAC CONTINUOUS_COMPLEX_INV_WITHIN THEN ASM_MESON_TAC + [CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN];EXPAND_TAC "g" THEN MATCH_MP_TAC + HOLOMORPHIC_ON_INV THEN ASM_REWRITE_TAC[]];ALL_TAC] THEN + SUBGOAL_THEN `?w:complex. w IN frontier(cball(z,r)) /\ + (!x:complex. x IN frontier(cball(z,r)) ==> + norm ((f:complex->complex) w) <= norm (f x))` + STRIP_ASSUME_TAC THENL [MATCH_MP_TAC CONTINUOUS_ATTAINS_INF + THEN ASM_SIMP_TAC[COMPACT_FRONTIER;COMPACT_CBALL;CBALL_EQ_EMPTY; + REAL_ARITH `!r:real. &0 < r ==> ~(r < &0)` ] THEN + SUBGOAL_THEN `lift o (\x. norm ((f:complex->complex) x)) = + (lift o norm) o (\x. f x) ` SUBST1_TAC THENL + [REWRITE_TAC[o_DEF]; MATCH_MP_TAC CONTINUOUS_ON_COMPOSE + THEN CONJ_TAC THENL [MATCH_MP_TAC CONTINUOUS_ON_SUBSET THEN EXISTS_TAC + `cball(z:complex,r)` THEN ASM_REWRITE_TAC[ETA_AX] THEN + ASM_SIMP_TAC[SUBSET_TRANS;CLOSED_CBALL;FRONTIER_SUBSET_CLOSED]; + ASM_MESON_TAC [CONTINUOUS_ON_LIFT_NORM; HOLOMORPHIC_ON_SUBSET; + HOLOMORPHIC_ON_IMP_CONTINUOUS_ON;SUBSET_TRANS;CLOSED_CBALL; + FRONTIER_SUBSET_CLOSED]]];ALL_TAC] THEN + SUBGOAL_THEN `?w:complex. norm (z-w) = r /\ + norm ((f:complex->complex) w) <= norm (f z)` + (fun thm -> ASM_MESON_TAC[thm;REAL_NOT_LE]) + THEN EXISTS_TAC `w:complex` THEN CONJ_TAC + THENL [MP_TAC (ASSUME `w:complex IN frontier (cball (z,r))`) THEN + REWRITE_TAC[FRONTIER_CBALL;sphere;dist] THEN SET_TAC[];ALL_TAC] THEN + SUBGOAL_THEN `&0 < norm ((f:complex->complex) w)` ASSUME_TAC THENL + [REWRITE_TAC[NORM_POS_LT;COMPLEX_VEC_0] THEN MATCH_MP_TAC (ASSUME `!x. + x:complex IN cball (z,r) ==> ~(f x = Cx(&0))`) THEN MATCH_MP_TAC + (SET_RULE `!x:complex u s. x IN u /\ u SUBSET s ==> x IN s `) THEN + EXISTS_TAC `frontier(cball(z:complex,r))` THEN + ASM_SIMP_TAC[CLOSED_CBALL;FRONTIER_SUBSET_CLOSED];ALL_TAC] THEN + SUBGOAL_THEN `inv (norm ((f:complex-> complex) w)) = &1/ (norm (f w))` + ASSUME_TAC THENL [MATCH_MP_TAC REAL_MUL_RINV_UNIQ THEN MATCH_MP_TAC + REAL_DIV_LMUL THEN ASM_REWRITE_TAC[COMPLEX_NORM_ZERO;GSYM COMPLEX_NORM_NZ]; + ASSERT_TAC `?x:complex. x IN frontier(cball(z,r)) /\ (!y. y IN + frontier(cball(z,r)) ==> norm ((g:complex->complex) y) <= norm (g x))` + THENL [MATCH_MP_TAC CONTINUOUS_ATTAINS_SUP THEN + ASM_SIMP_TAC[COMPACT_FRONTIER; + COMPACT_CBALL;CBALL_EQ_EMPTY; REAL_ARITH `!r:real. &0 < r ==> ~(r < &0)`] + THEN SUBGOAL_THEN `lift o (\x. norm ((g:complex->complex) x)) = + (lift o norm) o (\x. g x) ` SUBST1_TAC + THENL [REWRITE_TAC[o_DEF]; MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN + CONJ_TAC THENL [MATCH_MP_TAC CONTINUOUS_ON_SUBSET THEN + EXISTS_TAC `cball(z:complex,r)` THEN ASM_REWRITE_TAC[ETA_AX] + THEN ASM_SIMP_TAC[SUBSET_TRANS;CLOSED_CBALL; + FRONTIER_SUBSET_CLOSED]; ASM_MESON_TAC [CONTINUOUS_ON_LIFT_NORM; + HOLOMORPHIC_ON_SUBSET; HOLOMORPHIC_ON_IMP_CONTINUOUS_ON;SUBSET_TRANS; + CLOSED_CBALL; FRONTIER_SUBSET_CLOSED]]];ALL_TAC] THEN SUBGOAL_THEN + `&0 < norm ((f:complex->complex) x)` ASSUME_TAC THENL + [REWRITE_TAC[NORM_POS_LT;COMPLEX_VEC_0] THEN MATCH_MP_TAC + (ASSUME `!x. x:complex IN cball (z,r) ==> ~(f x = Cx(&0))`) + THEN MATCH_MP_TAC (SET_RULE `!x:complex u s. x IN u /\ u SUBSET s + ==> x IN s `) THEN EXISTS_TAC `frontier(cball(z:complex,r))` + THEN ASM_SIMP_TAC[CLOSED_CBALL;FRONTIER_SUBSET_CLOSED]; + ABBREV_TAC `B = norm ((g:complex->complex) x)` + THEN SUBGOAL_THEN `norm (higher_complex_derivative 0 g z) <= + (&(FACT 0)) * B / (r pow 0) ` + MP_TAC THENL[MATCH_MP_TAC CAUCHY_INEQUALITY THEN + ASM_REWRITE_TAC[] THEN MP_TAC + (ASSUME `!y:complex. y IN frontier (cball (z,r)) ==> + norm ((g:complex ->complex) y) <= B`) + THEN SIMP_TAC [FRONTIER_CBALL;sphere;dist] THEN SET_TAC[]; + REWRITE_TAC [higher_complex_derivative;FACT;real_pow; + REAL_MUL_LID;REAL_DIV_1] THEN DISCH_TAC THEN SUBGOAL_THEN + `inv (norm ((f:complex->complex) z)) <= + inv (norm (f w)) ==> norm (f w) <= norm (f z)` MATCH_MP_TAC + THENL [SUBGOAL_THEN `inv (norm ((f:complex-> complex) z)) = + &1/ (norm (f z))` SUBST1_TAC + THENL [MATCH_MP_TAC REAL_MUL_RINV_UNIQ THEN MATCH_MP_TAC REAL_DIV_LMUL THEN + ASM_SIMP_TAC[REAL_ARITH `&0 < norm ((f:complex->complex) z) ==> + ~(norm (f z) = &0) `]; ASM_REWRITE_TAC[] THEN DISCH_TAC THEN SUBST1_TAC + (REAL_ARITH `norm ((f:complex->complex) w)= &1 * norm (f w)`) THEN + SUBST1_TAC(REAL_ARITH `norm ((f:complex->complex) z)= + &1 * norm (f z)`) THEN POP_ASSUM + MP_TAC THEN MATCH_MP_TAC (TAUT `(p <=> q ) ==> ( p ==> q)`) + THEN MATCH_MP_TAC RAT_LEMMA4 THEN ASM_REWRITE_TAC[]]; + REWRITE_TAC[GSYM COMPLEX_NORM_INV] THEN + SUBGOAL_THEN `inv ((f:complex->complex) z) = g z /\ inv (f w) = g w` + (fun thm -> REWRITE_TAC[thm]) + THENL [ASM_MESON_TAC[];MATCH_MP_TAC (REAL_ARITH + `!x y z:real. x <= y /\ y = z ==> x <= z`) THEN EXISTS_TAC `B:real` THEN + ASM_REWRITE_TAC[GSYM REAL_LE_ANTISYM] THEN CONJ_TAC THENL [EXPAND_TAC "B" + THEN REWRITE_TAC[SYM (ASSUME`(\z. inv ((f:complex->complex) z)) = + g`);COMPLEX_NORM_INV] THEN SUBGOAL_THEN `inv (norm ((f:complex->complex) x)) + = &1 / norm (f x)` (fun thm -> REWRITE_TAC[thm]) THENL [MATCH_MP_TAC + REAL_MUL_RINV_UNIQ THEN MATCH_MP_TAC REAL_DIV_LMUL THEN + ASM_SIMP_TAC[REAL_LT_IMP_NZ]; ASM_REWRITE_TAC[] THEN + MP_TAC (SPEC `x:complex`(ASSUME`!x:complex. x IN frontier (cball (z,r)) + ==> norm ((f:complex->complex) w) <= norm (f x)`)) + THEN REWRITE_TAC [ASSUME`x:complex IN frontier + (cball (z,r))`] THEN SUBST1_TAC + (REAL_ARITH `norm ((f:complex->complex) w)= &1* norm (f w)`) THEN + SUBST1_TAC (REAL_ARITH `norm ((f:complex->complex) x)= &1 * norm (f x)`) + THEN DISCH_TAC THEN REWRITE_TAC[REAL_MUL_LID] THEN POP_ASSUM + MP_TAC THEN MATCH_MP_TAC (TAUT `(q <=> p ) ==> ( p ==> q)`) THEN MATCH_MP_TAC + (RAT_LEMMA4) THEN ASM_REWRITE_TAC[]];ASM_MESON_TAC[]]]]]]]]) in + REPEAT STRIP_TAC THEN ASSUME_TAC (MESON [HOLOMORPHIC_ON_SUBSET; + ASSUME `(u:complex->bool) SUBSET a`;ASSUME `f holomorphic_on a`] + `f holomorphic_on u`) THEN ASM_CASES_TAC `(u:complex->bool)={}` THENL [ + ASM_MESON_TAC[SUBSET_EMPTY;IMAGE_EQ_EMPTY;OPEN_EMPTY];ALL_TAC] THEN + SUBGOAL_THEN `!f u. ~(u={}) /\ open u /\ connected u /\ + f holomorphic_on u /\ + ~(?c:complex. !z:complex. z IN u ==> f z=c) ==> + open (IMAGE f u)` ASSUME_TAC + THENL [REPEAT STRIP_TAC THEN REWRITE_TAC[OPEN_CONTAINS_BALL;IN_IMAGE] + THEN GEN_TAC THEN STRIP_TAC THEN + ASSERT_TAC `(\z:complex.(f':complex->complex)z - f' x') holomorphic_on + (u':complex->bool) /\ (\z:complex. f' z - f' x')x' = Cx(&0)` THENL [ + ASM_SIMP_TAC[HOLOMORPHIC_ON_CONST;HOLOMORPHIC_ON_SUB; + BETA_THM;COMPLEX_SUB_REFL];ALL_TAC] THEN + ASSERT_TAC `?s:real. &0 < s /\ ball(x',s) SUBSET u' /\ + (!z:complex. z IN ball(x',s) /\ ~(z = x') ==> + ~((\z:complex.(f':complex->complex)z - f' x') z = Cx(&0)))` THENL [ + MATCH_MP_TAC ISOLATED_ZEROS THEN ASM_REWRITE_TAC[] THEN + ASM_MESON_TAC[COMPLEX_SUB_0]; + ASSERT_TAC `?r. &0 < r /\ cball(x':complex,r) SUBSET ball(x',s)` THENL[ + EXISTS_TAC `s:real / &2` THEN ASM_SIMP_TAC [REAL_ARITH `&0 < s + ==> &0 < s/ &2`;SUBSET;IN_CBALL;IN_BALL] THEN MP_TAC (ASSUME `&0 < s`) + THEN REAL_ARITH_TAC;ALL_TAC] THEN + ASSERT_TAC `cball(x',r) SUBSET u' /\ + (!z:complex. z IN cball(x',r) /\ + ~(z=x')==> ~((\z:complex.(f':complex->complex)z - f' x') z = Cx(&0)))` + THENL [CONJ_TAC THENL [ASM_MESON_TAC[SUBSET_TRANS]; + MESON_TAC[ASSUME `!z:complex. z IN ball (x',s) /\ ~(z = x') + ==> ~((\z. (f':complex->complex) z - f' x') z = Cx(&0))`; + ASSUME `cball (x':complex,r) SUBSET ball (x',s)`;SUBSET]];ALL_TAC] + THEN SUBGOAL_THEN `frontier (cball (x':complex,r)) SUBSET u'` ASSUME_TAC + THENL [MATCH_MP_TAC SUBSET_TRANS THEN EXISTS_TAC `cball(x':complex,r)` + THEN ASM_MESON_TAC[CLOSED_CBALL;FRONTIER_SUBSET_CLOSED];ALL_TAC] THEN + ASSERT_TAC `?w. w IN frontier(cball(x':complex,r)) /\ + (!z. z IN frontier(cball(x',r)) ==> + norm ((f':complex->complex)w - f' x') <= norm(f' z - f' x'))` + THENL [MATCH_MP_TAC CONTINUOUS_ATTAINS_INF THEN + ASM_SIMP_TAC[COMPACT_FRONTIER;COMPACT_CBALL;CBALL_EQ_EMPTY; + REAL_ARITH `!r:real. &0 < r ==> ~(r < &0)` ] THEN + CONJ_TAC THENL [REWRITE_TAC[REWRITE_RULE[sphere] FRONTIER_CBALL;dist] THEN + SUBGOAL_THEN `?x:complex. norm(x'-x) = r` (fun th-> SET_TAC + [MEMBER_NOT_EMPTY;th]) THEN EXISTS_TAC `x' + Cx r` THEN + ASM_SIMP_TAC[COMPLEX_ADD_SUB2;NORM_NEG;COMPLEX_NORM_CX; + REAL_ABS_REFL;REAL_LT_IMP_LE]; + SUBGOAL_THEN `lift o (\z. norm ((f':complex->complex) z - f' x')) = + (lift o norm) o (\z. f' z - f' x') ` SUBST1_TAC THENL [ + REWRITE_TAC[o_DEF]; MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN + ASM_MESON_TAC [CONTINUOUS_ON_LIFT_NORM; HOLOMORPHIC_ON_SUBSET; + HOLOMORPHIC_ON_IMP_CONTINUOUS_ON]]];ALL_TAC] THEN + ABBREV_TAC `e = (norm ((f':complex->complex) w - f' x'))*(&1/ &3)` + THEN SUBGOAL_THEN `&0complex) w - f' x' = + (\w. f' w - f' x')w `) THEN FIRST_ASSUM MATCH_MP_TAC THEN + CONJ_TAC THENL[MESON_TAC[ASSUME `w:complex IN frontier (cball (x',r))`; + FRONTIER_SUBSET_CLOSED; CLOSED_CBALL;SET_RULE `!x:complex s t. x IN s /\ + s SUBSET t ==> x IN t` ];ONCE_REWRITE_TAC[GSYM COMPLEX_SUB_0] THEN + REWRITE_TAC[GSYM COMPLEX_NORM_ZERO] THEN MATCH_MP_TAC REAL_LT_IMP_NZ + THEN MATCH_MP_TAC (REAL_ARITH `&0 < r /\ r = norm (w:complex - x') ==> + &0 < norm (w - x')`) THEN ASM_REWRITE_TAC[] THEN + MP_TAC (ASSUME `w:complex IN frontier (cball (x',r))`) THEN + SIMP_TAC[FRONTIER_CBALL; sphere; dist; IN_ELIM_THM; NORM_SUB]]; + ALL_TAC] + THEN EXISTS_TAC `e:real` THEN REWRITE_TAC[ASSUME `&0complex) x = Cx(&0)) ==> + ?x. x'' - f' x = Cx(&0) /\ x IN u'` MATCH_MP_TAC THENL [ + STRIP_TAC THEN EXISTS_TAC `x''':complex` THEN + ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC (SET_RULE `!x:complex u s. x IN u /\ u SUBSET s ==> x IN s`) + THEN EXISTS_TAC `ball(x':complex,r)` THEN ASM_REWRITE_TAC[] + THEN ASM_MESON_TAC[BALL_SUBSET_CBALL;SUBSET_TRANS]; + MATCH_MP_TAC LEMMA_ZERO THEN CONJ_TAC THENL + [MATCH_MP_TAC HOLOMORPHIC_ON_IMP_CONTINUOUS_ON THEN + MATCH_MP_TAC HOLOMORPHIC_ON_SUB THEN ASM_MESON_TAC + [HOLOMORPHIC_ON_CONST; HOLOMORPHIC_ON_SUBSET]; + CONJ_TAC THENL [MATCH_MP_TAC HOLOMORPHIC_ON_SUB THEN ASM_MESON_TAC[ + HOLOMORPHIC_ON_CONST;HOLOMORPHIC_ON_SUBSET;BALL_SUBSET_CBALL]; + ASM_REWRITE_TAC[] THEN X_GEN_TAC `w':complex` THEN DISCH_TAC THEN + MATCH_MP_TAC REAL_LTE_TRANS THEN + EXISTS_TAC `e:real` THEN CONJ_TAC THENL + [MESON_TAC [NORM_SUB;dist;IN_BALL; ASSUME`x'':complex IN ball (x,e)`; + ASSUME `x:complex = (f':complex->complex) x'`]; + MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC `&2*e` THEN + ASM_SIMP_TAC[REAL_ARITH `&0 e <= &2 * e`;NORM_SUB] THEN + SUBST1_TAC (COMPLEX_RING `(f':complex->complex) w' - x'' = + f' w' -x + x - x''`) THEN + MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `norm ((f':complex->complex) w' - x) - norm (x-x'')` THEN + CONJ_TAC THENL [SUBST1_TAC (REAL_ARITH `&2 * e = &3 *e - e`) THEN + MATCH_MP_TAC (REAL_ARITH `!x y z w:real. x<=y /\ z x-w <= y-z`) + THEN CONJ_TAC THENL [EXPAND_TAC "e" THEN + ASM_REWRITE_TAC[REAL_ARITH `&3 * norm ((f':complex->complex) w - f' x') * + &1 / &3 = norm (f' w - f' x')`] THEN FIRST_ASSUM MATCH_MP_TAC THEN + POP_ASSUM MP_TAC THEN + REWRITE_TAC[FRONTIER_CBALL; sphere; NORM_SUB; IN_ELIM_THM; dist]; + UNDISCH_TAC `x'':complex IN ball (x,e)` THEN + REWRITE_TAC [IN_BALL;dist;ASSUME`x:complex = (f':complex->complex) x'`]]; + MATCH_MP_TAC (REAL_ARITH `!x y z:real. x<=y+z ==> x-z<=y`) THEN + REWRITE_TAC[COMPLEX_NORM_TRIANGLE_SUB]]]]]]];ALL_TAC] THEN + ASM_CASES_TAC `connected (u:complex->bool)` THENL [ + SUBGOAL_THEN `~(?c:complex. !z:complex. z IN u ==> f z=c)` + (fun th-> ASM_MESON_TAC [th]) THEN + ONCE_REWRITE_TAC[GSYM COMPLEX_SUB_0] + THEN STRIP_TAC THEN ABBREV_TAC `w:complex= CHOICE u` THEN + ASSUME_TAC (MESON [CHOICE_DEF;GSYM (ASSUME `CHOICE u = w:complex`); + ASSUME `~(u:complex->bool = {})`] `w:complex IN u`) THEN + ASSERT_TAC `w:complex limit_point_of u` THENL + [MATCH_MP_TAC INTERIOR_LIMIT_POINT THEN ASM_SIMP_TAC [INTERIOR_OPEN]; + SUBGOAL_THEN `(\z. (f:complex->complex) z - c) holomorphic_on a` ASSUME_TAC + THENL [ASM_SIMP_TAC [HOLOMORPHIC_ON_SUB; HOLOMORPHIC_ON_CONST]; + ASSUME_TAC (MESON [ASSUME `w:complex IN u`;ASSUME `u:complex->bool SUBSET a`; + SET_RULE `w:complex IN u /\ u SUBSET a ==> w IN a`] `w:complex IN a`) THEN + MP_TAC(SPECL [`\z:complex.(f:complex->complex)z - c`; + `a:complex->bool`; `u:complex->bool`; `w:complex`] + ANALYTIC_CONTINUATION) THEN + ASM_REWRITE_TAC [] THEN MP_TAC (ASSUME `~(?c:complex. !z. z IN a ==> + (f:complex->complex) z = c)`) THEN ONCE_REWRITE_TAC [GSYM COMPLEX_SUB_0; + GSYM COMPLEX_SUB_RZERO] THEN ONCE_REWRITE_TAC [COMPLEX_SUB_RZERO] THEN + MESON_TAC[]]];ALL_TAC] THEN SUBST1_TAC (MESON [UNIONS_COMPONENTS] + `u:complex->bool = UNIONS ( components u)`) THEN + REWRITE_TAC [IMAGE_UNIONS] THEN MATCH_MP_TAC OPEN_UNIONS THEN + REWRITE_TAC[IN_IMAGE] THEN GEN_TAC THEN STRIP_TAC THEN + FIRST_X_ASSUM SUBST1_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + STRIP_ASSUME_TAC(MESON [IN_COMPONENTS; + ASSUME `(x:complex->bool) IN components u`] + `?w:complex. w IN u /\ x = connected_component u w`) THEN + ASM_SIMP_TAC[CONNECTED_COMPONENT_EQ_EMPTY;OPEN_CONNECTED_COMPONENT; + CONNECTED_CONNECTED_COMPONENT] THEN CONJ_TAC THENL + [ASM_MESON_TAC [CONNECTED_COMPONENT_SUBSET; + HOLOMORPHIC_ON_SUBSET]; ONCE_REWRITE_TAC[GSYM COMPLEX_SUB_0] THEN + STRIP_TAC THEN ABBREV_TAC `y = CHOICE (x:complex->bool)` THEN + SUBGOAL_THEN `y:complex IN x` ASSUME_TAC THENL + [EXPAND_TAC "y" THEN MATCH_MP_TAC CHOICE_DEF THEN + ASM_MESON_TAC [CONNECTED_COMPONENT_EQ_EMPTY]; + ASSUME_TAC (MESON [OPEN_COMPONENTS;ASSUME `open (u:complex->bool)`; + ASSUME` x:complex->bool IN components u`] `open (x:complex->bool)`) THEN + ASSERT_TAC `y:complex limit_point_of x` THENL [ + MATCH_MP_TAC INTERIOR_LIMIT_POINT THEN ASSUME_TAC + (MESON [OPEN_COMPONENTS;ASSUME `open (u:complex->bool)`; + ASSUME` x:complex->bool IN components u`] `open (x:complex->bool)`) THEN + SIMP_TAC [INTERIOR_OPEN;ASSUME `open (x:complex->bool)`; + ASSUME `y:complex IN x`]; SUBGOAL_THEN `(\z. (f:complex->complex) z - c) + holomorphic_on a` ASSUME_TAC THENL [ + ASM_SIMP_TAC [HOLOMORPHIC_ON_SUB; HOLOMORPHIC_ON_CONST]; + SUBGOAL_THEN `x:complex->bool SUBSET a` ASSUME_TAC THENL [ + MATCH_MP_TAC SUBSET_TRANS THEN EXISTS_TAC `u:complex->bool` THEN + ASM_REWRITE_TAC[CONNECTED_COMPONENT_SUBSET]; + SUBGOAL_THEN `y:complex IN a` ASSUME_TAC THENL [ + MATCH_MP_TAC (SET_RULE `y:complex IN x /\ x SUBSET a ==> y IN a`) + THEN ASM_REWRITE_TAC[]; MP_TAC(SPECL [`\z:complex.(f:complex->complex)z - c`; + `a:complex->bool`; `x:complex->bool`; `y:complex`] ANALYTIC_CONTINUATION) + THEN ASM_REWRITE_TAC [] THEN MP_TAC (ASSUME `~(?c:complex. !z. z IN a ==> + (f:complex->complex) z = c)`) THEN + ONCE_REWRITE_TAC [GSYM COMPLEX_SUB_0;GSYM COMPLEX_SUB_RZERO] THEN + ONCE_REWRITE_TAC [COMPLEX_SUB_RZERO] THEN MESON_TAC[]]]]]]]);; + +(* ------------------------------------------------------------------------- *) +(* Maximum modulus principle. *) +(* ------------------------------------------------------------------------- *) + +let MAXIMUM_MODULUS_PRINCIPLE = prove + (`!f a u w. + open a /\ connected a /\ f holomorphic_on a /\ + open u /\ u SUBSET a /\ w IN u /\ + (!z. z IN u ==> norm(f z) <= norm(f w)) + ==> (?c. !z. z IN a ==> f z = c)`, + REPEAT STRIP_TAC THEN SUBGOAL_THEN + `~(open (IMAGE (f:complex->complex) u))` + (fun th -> ASM_MESON_TAC[th; OPEN_MAPPING_THM]) THEN + REWRITE_TAC[OPEN_CONTAINS_BALL;NOT_FORALL_THM] THEN + EXISTS_TAC `(f:complex->complex) w` THEN + MATCH_MP_TAC (TAUT `!p q. (p /\ ~ q) ==> ~(p ==> q)`) THEN CONJ_TAC THENL + [ASM_MESON_TAC[IN_IMAGE]; ALL_TAC] THEN + REWRITE_TAC[NOT_EXISTS_THM;DE_MORGAN_THM;SUBSET] THEN + GEN_TAC THEN ASM_CASES_TAC `~(&0 < e)` THENL + [ASM_REWRITE_TAC[]; ALL_TAC] THEN POP_ASSUM MP_TAC THEN REWRITE_TAC[] THEN + DISCH_TAC THEN DISJ2_TAC THEN REWRITE_TAC[NOT_FORALL_THM] THEN + EXISTS_TAC `if &0 < Re((f:complex->complex) w) + then f w + Cx(e / &2) + else f w - Cx(e/ &2) ` THEN + ABBREV_TAC `x = if &0complex) w) + then f w + Cx(e / &2) + else f w - Cx(e / &2)` THEN + MATCH_MP_TAC (TAUT `!p q. (p /\ ~ q) ==> ~(p ==> q)`) THEN CONJ_TAC THENL + [REWRITE_TAC[IN_BALL;dist] THEN + MATCH_MP_TAC (REAL_ARITH `!x y z:real. x = y /\ y < z ==> x < z `) THEN + EXISTS_TAC `e / &2` THEN EXPAND_TAC "x" THEN COND_CASES_TAC THENL + [ASM_SIMP_TAC [NORM_NEG;COMPLEX_ADD_SUB2;REAL_ARITH `&0 < e ==> e / &2 &0 <= e / &2`]; + ASM_SIMP_TAC [COMPLEX_SUB_SUB2; REAL_ARITH `&0 < e ==> e / &2 &0 <= e / &2`]]; ALL_TAC] THEN + REWRITE_TAC[IN_IMAGE; NOT_EXISTS_THM; DE_MORGAN_THM] THEN + GEN_TAC THEN ASM_CASES_TAC `~(x':complex IN u)` THENL + [ASM_REWRITE_TAC[]; ALL_TAC] THEN DISJ1_TAC THEN POP_ASSUM MP_TAC THEN + REWRITE_TAC[] THEN DISCH_TAC THEN + MATCH_MP_TAC (NORM_ARITH `!x y:complex. ~(norm x=norm y) ==> ~(x=y)`) THEN + REWRITE_TAC[REAL_NOT_EQ] THEN DISJ2_TAC THEN + MATCH_MP_TAC REAL_LET_TRANS THEN + EXISTS_TAC `norm ((f:complex->complex) w)` THEN ASM_SIMP_TAC[] THEN + EXPAND_TAC "x" THEN COND_CASES_TAC THEN + REWRITE_TAC [complex_norm;RE_ADD;IM_ADD; IM_CX;RE_CX;REAL_ADD_RID] THENL + [MATCH_MP_TAC SQRT_MONO_LT THEN CONJ_TAC THENL + [SIMP_TAC[REAL_ARITH `!x:real. x pow 2 = x*x`; + REAL_LE_SQUARE;REAL_LE_ADD]; ALL_TAC] THEN + MATCH_MP_TAC (REAL_ARITH `!x:real y z. x < y ==> x + z < y + z`) THEN + REWRITE_TAC[GSYM REAL_LT_SQUARE_ABS] THEN + ASM_SIMP_TAC [REAL_ARITH `!x y. &0 < x /\ &0 < y + ==> abs (x+y) = abs x + abs y`; + REAL_ARITH `!x:real. &0 < x ==> &0 < x / &2`] THEN + ASM_REAL_ARITH_TAC; ALL_TAC] THEN + REWRITE_TAC [complex_norm;RE_SUB;IM_SUB; IM_CX;RE_CX;REAL_SUB_RZERO] THEN + MATCH_MP_TAC SQRT_MONO_LT THEN CONJ_TAC THENL + [SIMP_TAC[REAL_LE_SQUARE; REAL_LE_ADD; + REAL_ARITH `!x:real. x pow 2 = x*x`]; ALL_TAC] THEN + MATCH_MP_TAC (REAL_ARITH `!x:real y z. x < y ==> x + z < y + z`) THEN + REWRITE_TAC[GSYM REAL_LT_SQUARE_ABS] THEN POP_ASSUM MP_TAC THEN + REWRITE_TAC[REAL_NOT_LT] THEN DISCH_TAC THEN + ASM_SIMP_TAC [REAL_ARITH `!x y. x <= &0 /\ &0 < y + ==> abs (x - y) = abs x + abs y`; + REAL_ARITH `!x. &0 < x ==> &0 < x/ &2`] THEN + ASM_REAL_ARITH_TAC);; + +(* ------------------------------------------------------------------------- *) +(* Factoring out a zero according to its order. *) +(* ------------------------------------------------------------------------- *) + +let HOLOMORPHIC_FACTOR_ORDER_OF_ZERO = prove + (`!f s n. + open s /\ z IN s /\ f holomorphic_on s /\ + 0 < n /\ ~(higher_complex_derivative n f z = Cx(&0)) /\ + (!m. 0 < m /\ m < n ==> higher_complex_derivative m f z = Cx(&0)) + ==> ?g r. &0 < r /\ + g holomorphic_on ball(z,r) /\ + (!w. w IN ball(z,r) ==> f(w) - f(z) = (w - z) pow n * g(w)) /\ + (!w. w IN ball(z,r) ==> ~(g w = Cx(&0)))`, + REPEAT STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [OPEN_CONTAINS_BALL]) THEN + DISCH_THEN(MP_TAC o SPEC `z:complex`) THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `r:real` STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN + `!w. w IN ball(z,r) + ==> ((\m. higher_complex_derivative m f z / Cx(&(FACT m)) * + (w - z) pow m) sums f(w) - f(z)) (from n)` + ASSUME_TAC THENL + [GEN_TAC THEN DISCH_TAC THEN + MP_TAC(ISPECL [`f:complex->complex`; `z:complex`; `w:complex`; `r:real`] + HOLOMORPHIC_POWER_SERIES) THEN ASM_REWRITE_TAC[] THEN + ANTS_TAC THENL [ASM_MESON_TAC[HOLOMORPHIC_ON_SUBSET]; ALL_TAC] THEN + DISCH_THEN(MP_TAC o SPEC `1` o + MATCH_MP (REWRITE_RULE[IMP_CONJ] SUMS_OFFSET)) THEN + CONV_TAC NUM_REDUCE_CONV THEN REWRITE_TAC[VSUM_SING_NUMSEG] THEN + REWRITE_TAC[FACT; higher_complex_derivative; COMPLEX_DIV_1] THEN + REWRITE_TAC[complex_pow; COMPLEX_MUL_RID] THEN + ASM_CASES_TAC `n = 1` THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(MP_TAC o SPEC `n:num` o + MATCH_MP (REWRITE_RULE[IMP_CONJ] SUMS_OFFSET)) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; MATCH_MP_TAC EQ_IMP] THEN + AP_THM_TAC THEN AP_TERM_TAC THEN MATCH_MP_TAC(COMPLEX_RING + `p = Cx(&0) ==> w - z - p = w - z`) THEN + REWRITE_TAC[GSYM COMPLEX_VEC_0] THEN MATCH_MP_TAC VSUM_EQ_0 THEN + REWRITE_TAC[IN_NUMSEG; COMPLEX_VEC_0] THEN REPEAT STRIP_TAC THEN + REWRITE_TAC[COMPLEX_ENTIRE; complex_div] THEN REPEAT DISJ1_TAC THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_ARITH_TAC; + ALL_TAC] THEN + ABBREV_TAC + `g = \w. infsum (from 0) + (\m. higher_complex_derivative (m + n) f z / + Cx(&(FACT(m + n))) * (w - z) pow m)` THEN + SUBGOAL_THEN + `!w. w IN ball(z,r) + ==> ((\m. higher_complex_derivative (m + n) f z / + Cx(&(FACT(m + n))) * (w - z) pow m) + sums g(w)) (from 0)` + (LABEL_TAC "*") THENL + [REPEAT STRIP_TAC THEN EXPAND_TAC "g" THEN REWRITE_TAC[SUMS_INFSUM] THEN + ASM_CASES_TAC `w:complex = z` THENL + [MATCH_MP_TAC SUMMABLE_FROM_ELSEWHERE THEN EXISTS_TAC `1` THEN + MATCH_MP_TAC SUMMABLE_EQ THEN EXISTS_TAC `\n:num. Cx(&0)` THEN + REWRITE_TAC[SUMMABLE_0; GSYM COMPLEX_VEC_0] THEN + ASM_SIMP_TAC[IN_FROM; COMPLEX_VEC_0; COMPLEX_SUB_REFL; + COMPLEX_POW_ZERO; LE_1; COMPLEX_MUL_RZERO]; + SUBGOAL_THEN + `!x:complex m. x * (w - z) pow m = + (x * (w - z) pow (m + n)) / (w - z) pow n` + (fun th -> ONCE_REWRITE_TAC[th]) + THENL + [REPEAT GEN_TAC THEN + SIMP_TAC[complex_div; GSYM COMPLEX_MUL_ASSOC; COMPLEX_POW_ADD] THEN + ASM_SIMP_TAC[COMPLEX_MUL_RINV; COMPLEX_POW_EQ_0; COMPLEX_SUB_0] THEN + REWRITE_TAC[COMPLEX_MUL_RID]; + MATCH_MP_TAC SUMMABLE_COMPLEX_DIV THEN + MP_TAC(GEN `a:num->complex` + (ISPECL [`n:num`; `a:num->complex`] SUMMABLE_REINDEX)) THEN + DISCH_THEN(fun th -> REWRITE_TAC[th]) THEN + REWRITE_TAC[summable; ADD_CLAUSES] THEN ASM_MESON_TAC[]]]; + ALL_TAC] THEN + SUBGOAL_THEN `g holomorphic_on ball(z,r)` ASSUME_TAC THENL + [MATCH_MP_TAC POWER_SERIES_HOLOMORPHIC THEN + EXISTS_TAC `\m. higher_complex_derivative (m + n) f z / + Cx(&(FACT (m + n)))` THEN + EXISTS_TAC `from 0` THEN ASM_SIMP_TAC[]; + ALL_TAC] THEN + SUBGOAL_THEN + `!w. w IN ball(z,r) ==> f w - f z = (w - z) pow n * g(w)` + ASSUME_TAC THENL + [REPEAT STRIP_TAC THEN MATCH_MP_TAC SERIES_UNIQUE THEN + EXISTS_TAC `\m. higher_complex_derivative m f z / Cx(&(FACT m)) * + (w - z) pow m` THEN + EXISTS_TAC `from n` THEN ASM_SIMP_TAC[] THEN + GEN_REWRITE_TAC (RAND_CONV o RAND_CONV) [ARITH_RULE `n = 0 + n`] THEN + REWRITE_TAC[GSYM SUMS_REINDEX] THEN REWRITE_TAC[COMPLEX_POW_ADD] THEN + ONCE_REWRITE_TAC[COMPLEX_RING `a * b * c:complex = c * a * b`] THEN + MATCH_MP_TAC SERIES_COMPLEX_LMUL THEN ASM_SIMP_TAC[]; + ALL_TAC] THEN + EXISTS_TAC `g:complex->complex` THEN + SUBGOAL_THEN `(g:complex->complex) continuous_on ball(z,r)` MP_TAC THENL + [ASM_SIMP_TAC[HOLOMORPHIC_ON_IMP_CONTINUOUS_ON]; ALL_TAC] THEN + REWRITE_TAC[continuous_on] THEN + DISCH_THEN(MP_TAC o SPEC `z:complex`) THEN + ASM_REWRITE_TAC[CENTRE_IN_BALL] THEN DISCH_THEN(MP_TAC o SPEC + `norm((g:complex->complex) z)`) THEN + ANTS_TAC THENL + [REMOVE_THEN "*" (MP_TAC o SPEC `z:complex`) THEN + ASM_REWRITE_TAC[CENTRE_IN_BALL] THEN + DISCH_THEN(MP_TAC o SPEC `1` o + MATCH_MP (REWRITE_RULE[IMP_CONJ] SUMS_OFFSET)) THEN + CONV_TAC NUM_REDUCE_CONV THEN REWRITE_TAC[VSUM_SING_NUMSEG] THEN + DISCH_THEN(MP_TAC o SPEC `Cx(&0)` o + MATCH_MP(REWRITE_RULE[IMP_CONJ] SERIES_UNIQUE)) THEN + REWRITE_TAC[complex_pow; ADD_CLAUSES; COMPLEX_MUL_RID] THEN ANTS_TAC THENL + [REWRITE_TAC[GSYM COMPLEX_VEC_0] THEN MATCH_MP_TAC SUMS_0 THEN + SIMP_TAC[IN_FROM; LE_1; COMPLEX_SUB_REFL; COMPLEX_POW_ZERO] THEN + REWRITE_TAC[COMPLEX_VEC_0; COMPLEX_MUL_RZERO]; + SIMP_TAC[COMPLEX_SUB_0; NORM_POS_LT] THEN DISCH_THEN(K ALL_TAC) THEN + ASM_REWRITE_TAC[COMPLEX_VEC_0; complex_div; COMPLEX_ENTIRE] THEN + REWRITE_TAC[COMPLEX_INV_EQ_0; CX_INJ; REAL_OF_NUM_EQ; FACT_NZ]]; + ALL_TAC] THEN + DISCH_THEN(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `min d r:real` THEN ASM_REWRITE_TAC[REAL_LT_MIN] THEN + SUBGOAL_THEN `ball(z,min d r) SUBSET ball(z:complex,r)` ASSUME_TAC THENL + [SIMP_TAC[SUBSET_BALL; REAL_ARITH `min d r <= r`]; ALL_TAC] THEN + CONJ_TAC THENL [ASM_MESON_TAC[HOLOMORPHIC_ON_SUBSET]; ALL_TAC] THEN + CONJ_TAC THENL [ASM_MESON_TAC[SUBSET]; ALL_TAC] THEN + REWRITE_TAC[IN_BALL; REAL_LT_MIN; GSYM COMPLEX_VEC_0] THEN + RULE_ASSUM_TAC(REWRITE_RULE[IN_BALL]) THEN + ASM_MESON_TAC[DIST_SYM; NORM_ARITH `dist(x,y) < norm y ==> ~(x = vec 0)`]);; + +let HOLOMORPHIC_FACTOR_ORDER_OF_ZERO_STRONG = prove + (`!f s n z. + open s /\ z IN s /\ f holomorphic_on s /\ + 0 < n /\ ~(higher_complex_derivative n f z = Cx(&0)) /\ + (!m. 0 < m /\ m < n ==> higher_complex_derivative m f z = Cx(&0)) + ==> ?g r. &0 < r /\ + g holomorphic_on ball(z,r) /\ + (!w. w IN ball(z,r) + ==> f(w) - f(z) = ((w - z) * g w) pow n) /\ + (!w. w IN ball(z,r) ==> ~(g w = Cx(&0)))`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`f:complex->complex`; `s:complex->bool`; `n:num`] + HOLOMORPHIC_FACTOR_ORDER_OF_ZERO) THEN + ASM_REWRITE_TAC[] THEN + ONCE_REWRITE_TAC[SWAP_EXISTS_THM] THEN MATCH_MP_TAC MONO_EXISTS THEN + X_GEN_TAC `r:real` THEN + DISCH_THEN(X_CHOOSE_THEN `g:complex->complex` STRIP_ASSUME_TAC) THEN + MP_TAC(ISPECL + [`\z. complex_derivative g z / g z`; `ball(z:complex,r)`; + `{}:complex->bool`] HOLOMORPHIC_CONVEX_PRIMITIVE) THEN + REWRITE_TAC[CONVEX_BALL; FINITE_RULES; DIFF_EMPTY] THEN ANTS_TAC THENL + [SIMP_TAC[GSYM HOLOMORPHIC_ON_OPEN; OPEN_BALL; + INTERIOR_OPEN; complex_differentiable] THEN + MATCH_MP_TAC(TAUT `q /\ (q ==> p) ==> p /\ q`) THEN + REWRITE_TAC[HOLOMORPHIC_ON_IMP_CONTINUOUS_ON] THEN + ASM_SIMP_TAC[HOLOMORPHIC_COMPLEX_DERIVATIVE; OPEN_BALL; + HOLOMORPHIC_ON_DIV; ETA_AX]; + SIMP_TAC[OPEN_BALL; HAS_COMPLEX_DERIVATIVE_WITHIN_OPEN] THEN + DISCH_THEN(X_CHOOSE_THEN `h:complex->complex` STRIP_ASSUME_TAC)] THEN + MP_TAC(ISPECL [`\z:complex. cexp(h z) / g z`; `ball(z:complex,r)`] + HAS_COMPLEX_DERIVATIVE_ZERO_CONNECTED_CONSTANT) THEN + REWRITE_TAC[OPEN_BALL; CONNECTED_BALL] THEN ANTS_TAC THENL + [X_GEN_TAC `w:complex` THEN DISCH_TAC THEN + SUBGOAL_THEN + `Cx(&0) = ((complex_derivative g w / g w * cexp (h w)) * g w - + cexp (h w) * complex_derivative g w) / g w pow 2` + SUBST1_TAC THENL + [ASM_SIMP_TAC[COMPLEX_FIELD + `~(z = Cx(&0)) ==> (d / z * e) * z = e * d`] THEN + SIMPLE_COMPLEX_ARITH_TAC; + MATCH_MP_TAC HAS_COMPLEX_DERIVATIVE_DIV_AT THEN + ASM_SIMP_TAC[] THEN CONJ_TAC THENL + [GEN_REWRITE_TAC (RATOR_CONV o LAND_CONV) [GSYM o_DEF] THEN + ONCE_REWRITE_TAC[COMPLEX_MUL_SYM] THEN + MATCH_MP_TAC COMPLEX_DIFF_CHAIN_AT THEN + ASM_SIMP_TAC[HAS_COMPLEX_DERIVATIVE_CEXP]; + ASM_MESON_TAC[HOLOMORPHIC_ON_OPEN; complex_differentiable; + OPEN_BALL; HAS_COMPLEX_DERIVATIVE_DIFFERENTIABLE]]]; + DISCH_THEN(X_CHOOSE_THEN `c:complex` MP_TAC) THEN + ASM_CASES_TAC `c = Cx(&0)` THENL + [ASM_SIMP_TAC[CEXP_NZ; COMPLEX_FIELD + `~(x = Cx(&0)) /\ ~(y = Cx(&0)) ==> ~(x / y = Cx(&0))`] THEN + ASM_MESON_TAC[]; + ASM_SIMP_TAC[COMPLEX_FIELD + `~(y = Cx(&0)) /\ ~(z = Cx(&0)) + ==> (x / y = z <=> y = inv(z) * x)`] THEN + DISCH_TAC THEN EXISTS_TAC + `\z:complex. cexp((clog(inv c) + h z) / Cx(&n))` THEN + REWRITE_TAC[CEXP_NZ; GSYM CEXP_N; COMPLEX_POW_MUL] THEN + ASM_SIMP_TAC[COMPLEX_DIV_LMUL; CX_INJ; REAL_OF_NUM_EQ; LE_1] THEN + ASM_SIMP_TAC[CEXP_ADD; CEXP_CLOG; COMPLEX_INV_EQ_0] THEN + GEN_REWRITE_TAC LAND_CONV [GSYM o_DEF] THEN + MATCH_MP_TAC HOLOMORPHIC_ON_COMPOSE THEN + REWRITE_TAC[HOLOMORPHIC_ON_CEXP] THEN + MATCH_MP_TAC HOLOMORPHIC_ON_DIV THEN + ASM_SIMP_TAC[HOLOMORPHIC_ON_CONST; CX_INJ; REAL_OF_NUM_EQ; LE_1] THEN + MATCH_MP_TAC HOLOMORPHIC_ON_ADD THEN + REWRITE_TAC[HOLOMORPHIC_ON_CONST] THEN + ASM_MESON_TAC[HOLOMORPHIC_ON_OPEN; OPEN_BALL]]]);; + +let HOLOMORPHIC_FACTOR_ZERO_NONCONSTANT = prove + (`!f s z. + open s /\ connected s /\ z IN s /\ + f holomorphic_on s /\ f(z) = Cx(&0) /\ ~(?c. !w. w IN s ==> f w = c) + ==> ?g r n. + 0 < n /\ &0 < r /\ ball(z,r) SUBSET s /\ + g holomorphic_on ball(z,r) /\ + (!w. w IN ball(z,r) ==> f w = (w - z) pow n * g w) /\ + (!w. w IN ball(z,r) ==> ~(g w = Cx (&0)))`, + REPEAT STRIP_TAC THEN + ASM_CASES_TAC `!n. 0 < n ==> higher_complex_derivative n f z = Cx(&0)` THENL + [MP_TAC(ISPECL + [`f:complex->complex`; `s:complex->bool`; `z:complex`] + HOLOMORPHIC_FUN_EQ_CONST_ON_CONNECTED) THEN + ASM_REWRITE_TAC[] THEN ASM_MESON_TAC[]; + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [OPEN_CONTAINS_BALL]) THEN + DISCH_THEN(MP_TAC o SPEC `z:complex`) THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `r0:real` STRIP_ASSUME_TAC) THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [NOT_FORALL_THM]) THEN + GEN_REWRITE_TAC LAND_CONV [num_WOP] THEN + REWRITE_TAC[NOT_IMP; GSYM IMP_CONJ_ALT] THEN + DISCH_THEN(X_CHOOSE_THEN `n:num` STRIP_ASSUME_TAC) THEN + MP_TAC(ISPECL [`f:complex->complex`; `s:complex->bool`; `n:num`] + HOLOMORPHIC_FACTOR_ORDER_OF_ZERO) THEN + ASM_REWRITE_TAC[COMPLEX_SUB_RZERO] THEN MATCH_MP_TAC MONO_EXISTS THEN + X_GEN_TAC `g:complex->complex` THEN + DISCH_THEN(X_CHOOSE_THEN `r1:real` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `min r0 r1:real` THEN EXISTS_TAC `n:num` THEN + ASM_SIMP_TAC[BALL_MIN_INTER; IN_INTER; REAL_LT_MIN] THEN CONJ_TAC THENL + [ASM SET_TAC[]; + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + HOLOMORPHIC_ON_SUBSET)) THEN + ASM SET_TAC[]]]);; + +(* ------------------------------------------------------------------------- *) +(* Relating invertibility and nonvanishing of derivative. *) +(* ------------------------------------------------------------------------- *) + +let HAS_COMPLEX_DERIVATIVE_LOCALLY_INJECTIVE = prove + (`!f s z. + f holomorphic_on s /\ open s /\ z IN s /\ + ~(complex_derivative f z = Cx(&0)) + ==> ?t. z IN t /\ + open t /\ + (!x x'. x IN t /\ x' IN t /\ f x' = f x ==> x' = x)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_DERIVATIVE_LOCALLY_INJECTIVE THEN + EXISTS_TAC `\z h. complex_derivative f z * h` THEN + ONCE_REWRITE_TAC[SWAP_EXISTS_THM] THEN EXISTS_TAC `s:complex->bool` THEN + ASM_REWRITE_TAC[GSYM has_complex_derivative] THEN + REWRITE_TAC[CONJ_ASSOC; LEFT_EXISTS_AND_THM] THEN + ASM_REWRITE_TAC[HAS_COMPLEX_DERIVATIVE_DIFFERENTIABLE] THEN + REPEAT CONJ_TAC THENL + [MATCH_MP_TAC LINEAR_INJECTIVE_LEFT_INVERSE THEN + ASM_SIMP_TAC[LINEAR_COMPLEX_MUL; COMPLEX_EQ_MUL_LCANCEL]; + ASM_MESON_TAC[HOLOMORPHIC_ON_IMP_DIFFERENTIABLE_AT]; + X_GEN_TAC `e:real` THEN DISCH_TAC THEN + SUBGOAL_THEN `(complex_derivative f) continuous_on s` MP_TAC THENL + [MATCH_MP_TAC HOLOMORPHIC_ON_IMP_CONTINUOUS_ON THEN + ASM_SIMP_TAC[HOLOMORPHIC_COMPLEX_DERIVATIVE]; + ALL_TAC] THEN + ONCE_REWRITE_TAC[DIST_SYM] THEN REWRITE_TAC[continuous_on] THEN + DISCH_THEN(MP_TAC o SPEC `z:complex`) THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(MP_TAC o SPEC `e / &2`) THEN + ASM_REWRITE_TAC[dist; REAL_HALF] THEN + DISCH_THEN(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC) THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [OPEN_CONTAINS_BALL]) THEN + DISCH_THEN(MP_TAC o SPEC `z:complex`) THEN + ASM_REWRITE_TAC[SUBSET; IN_BALL; ONCE_REWRITE_RULE[DIST_SYM] dist] THEN + DISCH_THEN(X_CHOOSE_THEN `r:real` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `min d r:real` THEN ASM_REWRITE_TAC[REAL_LT_MIN] THEN + X_GEN_TAC `w:complex` THEN DISCH_TAC THEN + MATCH_MP_TAC(REAL_ARITH `&0 < e /\ x <= e / &2 ==> x < e`) THEN + ASM_REWRITE_TAC[GSYM COMPLEX_SUB_RDISTRIB] THEN MATCH_MP_TAC + (CONJUNCT2(MATCH_MP ONORM (SPEC_ALL LINEAR_COMPLEX_MUL))) THEN + GEN_TAC THEN REWRITE_TAC[COMPLEX_NORM_MUL] THEN + MATCH_MP_TAC REAL_LE_RMUL THEN + ASM_SIMP_TAC[REAL_LT_IMP_LE; NORM_POS_LE]]);; + +let HAS_COMPLEX_DERIVATIVE_LOCALLY_INVERTIBLE = prove + (`!f s z. + f holomorphic_on s /\ open s /\ z IN s /\ + ~(complex_derivative f z = Cx(&0)) + ==> ?t g. z IN t /\ open t /\ open(IMAGE f t) /\ t SUBSET s /\ + (!w. w IN t ==> g(f w) = w) /\ + (!y. y IN (IMAGE f t) ==> f(g y) = y)`, + REPEAT GEN_TAC THEN DISCH_TAC THEN + FIRST_ASSUM(MP_TAC o MATCH_MP HAS_COMPLEX_DERIVATIVE_LOCALLY_INJECTIVE) THEN + DISCH_THEN(X_CHOOSE_THEN `t:complex->bool` MP_TAC) THEN + REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [EQ_SYM_EQ] THEN + REWRITE_TAC[INJECTIVE_ON_LEFT_INVERSE] THEN + DISCH_THEN(X_CHOOSE_TAC `g:complex->complex`) THEN + EXISTS_TAC `s INTER t:complex->bool` THEN + EXISTS_TAC `g:complex->complex` THEN + ASM_SIMP_TAC[OPEN_INTER; IN_INTER; INTER_SUBSET; FORALL_IN_IMAGE] THEN + MATCH_MP_TAC INVARIANCE_OF_DOMAIN THEN + ASM_SIMP_TAC[OPEN_INTER; IN_INTER] THEN + ASM_MESON_TAC[HOLOMORPHIC_ON_IMP_CONTINUOUS_ON; + HOLOMORPHIC_ON_SUBSET; INTER_SUBSET]);; + +let HOLOMORPHIC_INJECTIVE_IMP_REGULAR = prove + (`!f s. + f holomorphic_on s /\ open s /\ + (!w z. w IN s /\ z IN s /\ f w = f z ==> w = z) + ==> !z. z IN s ==> ~(complex_derivative f z = Cx(&0))`, + REPEAT STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [OPEN_CONTAINS_BALL]) THEN + DISCH_THEN(MP_TAC o SPEC `z:complex`) THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `r:real` STRIP_ASSUME_TAC) THEN + ASM_CASES_TAC `!n. 0 < n ==> higher_complex_derivative n f z = Cx(&0)` THENL + [MP_TAC(ISPECL + [`f:complex->complex`; `ball(z:complex,r)`; `z:complex`] + HOLOMORPHIC_FUN_EQ_CONST_ON_CONNECTED) THEN + ASM_SIMP_TAC[OPEN_BALL; CONNECTED_BALL; CENTRE_IN_BALL; NOT_IMP] THEN + CONJ_TAC THENL [ASM_MESON_TAC[HOLOMORPHIC_ON_SUBSET]; ALL_TAC] THEN + DISCH_THEN(MP_TAC o SPEC `z + Cx(r / &2)`) THEN + REWRITE_TAC[IN_BALL; NORM_ARITH `dist(z,z + r) = norm r`] THEN + REWRITE_TAC[COMPLEX_NORM_CX; NOT_IMP] THEN + CONJ_TAC THENL [ASM_REAL_ARITH_TAC; DISCH_TAC] THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`z:complex`; `z + Cx(r / &2)`]) THEN + ASM_REWRITE_TAC[COMPLEX_RING `z = z + a <=> a = Cx(&0)`] THEN + REWRITE_TAC[NOT_IMP; CX_INJ] THEN + CONJ_TAC THENL [ALL_TAC; ASM_REAL_ARITH_TAC] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o GEN_REWRITE_RULE I [SUBSET]) THEN + REWRITE_TAC[IN_BALL; NORM_ARITH `dist(z,z + r) = norm r`] THEN + REWRITE_TAC[COMPLEX_NORM_CX] THEN ASM_REAL_ARITH_TAC; + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [NOT_FORALL_THM])] THEN + GEN_REWRITE_TAC LAND_CONV [num_WOP] THEN + REWRITE_TAC[NOT_IMP; GSYM IMP_CONJ_ALT] THEN + DISCH_THEN(X_CHOOSE_THEN `n:num` STRIP_ASSUME_TAC) THEN + MP_TAC(ISPECL [`f:complex->complex`; `s:complex->bool`; `n:num`; `z:complex`] + HOLOMORPHIC_FACTOR_ORDER_OF_ZERO_STRONG) THEN + ASM_REWRITE_TAC[NOT_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`g:complex->complex`; `k:real`] THEN STRIP_TAC THEN + ASM_CASES_TAC `n = 1` THENL + [ASM_MESON_TAC[HIGHER_COMPLEX_DERIVATIVE_1]; ALL_TAC] THEN + MP_TAC(ISPECL[`\w:complex. (w - z) * g(w)`; `ball(z:complex,min r k)`; + `z:complex`] HAS_COMPLEX_DERIVATIVE_LOCALLY_INVERTIBLE) THEN + ASM_REWRITE_TAC[OPEN_BALL; CENTRE_IN_BALL; NOT_IMP; REAL_LT_MIN] THEN + CONJ_TAC THENL + [SUBGOAL_THEN + `!w. w IN ball(z,min r k) + ==> ((\w. (w - z) * g w) has_complex_derivative + ((w - z) * complex_derivative g w + (Cx(&1) - Cx(&0)) * g w)) + (at w)` + (LABEL_TAC "*") + THENL + [REPEAT STRIP_TAC THEN + SUBGOAL_THEN `w IN ball(z:complex,k)` ASSUME_TAC THENL + [ASM_MESON_TAC[SUBSET; SUBSET_BALL; REAL_ARITH `min r k <= k`]; + ALL_TAC] THEN + MATCH_MP_TAC HAS_COMPLEX_DERIVATIVE_MUL_AT THEN + SIMP_TAC[HAS_COMPLEX_DERIVATIVE_ID; HAS_COMPLEX_DERIVATIVE_SUB; + HAS_COMPLEX_DERIVATIVE_CONST; HAS_COMPLEX_DERIVATIVE_DIFFERENTIABLE] THEN + ASM_MESON_TAC[HOLOMORPHIC_ON_IMP_DIFFERENTIABLE_AT; OPEN_BALL]; + SIMP_TAC[HOLOMORPHIC_ON_OPEN; OPEN_BALL] THEN + CONJ_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN + REMOVE_THEN "*" (MP_TAC o SPEC `z:complex`) THEN + ASM_REWRITE_TAC[CENTRE_IN_BALL; REAL_LT_MIN] THEN + DISCH_THEN(SUBST1_TAC o MATCH_MP HAS_COMPLEX_DERIVATIVE_DERIVATIVE) THEN + REWRITE_TAC[COMPLEX_SUB_REFL; COMPLEX_MUL_LZERO; COMPLEX_ADD_LID; + COMPLEX_SUB_RZERO; COMPLEX_MUL_LID] THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[CENTRE_IN_BALL]]; + REWRITE_TAC[NOT_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`t:complex->bool`; `h:complex->complex`] THEN + ABBREV_TAC `u = IMAGE (\w:complex. (w - z) * g w) t` THEN STRIP_TAC THEN + MP_TAC(ISPEC `u:complex->bool` OPEN_CONTAINS_CBALL) THEN + ASM_REWRITE_TAC[] THEN DISCH_THEN(MP_TAC o SPEC `Cx(&0)`) THEN + ANTS_TAC THENL + [EXPAND_TAC "u" THEN REWRITE_TAC[IN_IMAGE] THEN + EXISTS_TAC `z:complex` THEN ASM_REWRITE_TAC[] THEN + CONV_TAC COMPLEX_RING; + ALL_TAC] THEN + REWRITE_TAC[NOT_EXISTS_THM; SUBSET; IN_CBALL; dist; + COMPLEX_SUB_LZERO; NORM_NEG] THEN + X_GEN_TAC `e:real` THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + DISCH_THEN(fun th -> + MP_TAC(ISPEC `Cx(e) * cexp(Cx(&2) * Cx pi * ii * Cx(&0 / &n))` th) THEN + MP_TAC(ISPEC `Cx(e) * cexp(Cx(&2) * Cx pi * ii * Cx(&1 / &n))` th)) THEN + REWRITE_TAC[COMPLEX_NORM_MUL; NORM_CEXP; RE_MUL_CX; RE_MUL_II] THEN + REWRITE_TAC[IM_CX; REAL_NEG_0; REAL_MUL_RZERO; REAL_EXP_0] THEN + REWRITE_TAC[COMPLEX_NORM_CX; REAL_MUL_RID] THEN + SIMP_TAC[REAL_ARITH `&0 < e ==> abs e <= e`; ASSUME `&0 < e`] THEN + EXPAND_TAC "u" THEN REWRITE_TAC[IN_IMAGE] THEN + DISCH_THEN(X_CHOOSE_THEN `y1:complex` (STRIP_ASSUME_TAC o GSYM)) THEN + DISCH_THEN(X_CHOOSE_THEN `y0:complex` (STRIP_ASSUME_TAC o GSYM)) THEN + UNDISCH_THEN `!w. w IN ball (z,k) ==> f w - f z = ((w - z) * g w) pow n` + (fun th -> MP_TAC(SPEC `y1:complex` th) THEN + MP_TAC(SPEC `y0:complex` th)) THEN + MATCH_MP_TAC(TAUT `(p1 /\ p2) /\ ~(q1 /\ q2) + ==> (p1 ==> q1) ==> (p2 ==> q2) ==> F`) THEN + CONJ_TAC THENL + [ASM_MESON_TAC[SUBSET; SUBSET_BALL; REAL_ARITH `min r k <= k`]; + MATCH_MP_TAC(MESON[] `x' = y' /\ ~(x = y) ==> ~(x = x' /\ y = y')`)] THEN + CONJ_TAC THENL + [RULE_ASSUM_TAC(REWRITE_RULE[INJECTIVE_ON_LEFT_INVERSE]) THEN + ASM_SIMP_TAC[] THEN REWRITE_TAC[COMPLEX_POW_MUL] THEN + ASM_SIMP_TAC[COMPLEX_ROOT_UNITY; LE_1]; + REWRITE_TAC[COMPLEX_RING `x - a:complex = y - a <=> x = y`] THEN + DISCH_TAC THEN UNDISCH_THEN + `!w z. w IN s /\ z IN s /\ (f:complex->complex) w = f z ==> w = z` + (MP_TAC o SPECL [`y0:complex`; `y1:complex`]) THEN + ASM_REWRITE_TAC[NOT_IMP] THEN CONJ_TAC THENL + [ASM_MESON_TAC[SUBSET; SUBSET_BALL; REAL_ARITH `min r k <= r`]; + DISCH_THEN SUBST_ALL_TAC] THEN + MP_TAC(ISPECL [`n:num`; `0`; `1`] COMPLEX_ROOT_UNITY_EQ) THEN + ASM_SIMP_TAC[LE_1] THEN MATCH_MP_TAC(TAUT `a /\ ~b ==> ~(a <=> b)`) THEN + CONJ_TAC THENL + [FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (COMPLEX_RING + `z = e * y ==> z = e * x /\ ~(e = Cx(&0)) ==> x = y`)) THEN + ASM_SIMP_TAC[CX_INJ; REAL_LT_IMP_NZ]; + REWRITE_TAC[num_congruent; int_congruent] THEN + DISCH_THEN(X_CHOOSE_THEN `d:int` + (MP_TAC o AP_TERM `abs:int->int` o SYM)) THEN + REWRITE_TAC[INT_ABS_NUM; INT_SUB_LZERO; INT_ABS_NEG] THEN + ASM_REWRITE_TAC[INT_ABS_MUL_1; INT_OF_NUM_EQ; INT_ABS_NUM]]]]);; + +(* ------------------------------------------------------------------------- *) +(* Hence a nice clean inverse function theorem. *) +(* ------------------------------------------------------------------------- *) + +let HOLOMORPHIC_ON_INVERSE = prove + (`!f s. f holomorphic_on s /\ open s /\ + (!w z. w IN s /\ z IN s /\ f w = f z ==> w = z) + ==> open(IMAGE f s) /\ + ?g. g holomorphic_on (IMAGE f s) /\ + (!z. z IN s + ==> complex_derivative f z * complex_derivative g (f z) = + Cx(&1)) /\ + (!z. z IN s ==> g(f z) = z) /\ + (!y. y IN (IMAGE f s) ==> f(g y) = y)`, + REPEAT GEN_TAC THEN STRIP_TAC THEN + MATCH_MP_TAC(TAUT `p /\ (p ==> q) ==> p /\ q`) THEN CONJ_TAC THENL + [MATCH_MP_TAC INVARIANCE_OF_DOMAIN THEN + ASM_MESON_TAC[HOLOMORPHIC_ON_IMP_CONTINUOUS_ON]; + DISCH_TAC] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [INJECTIVE_ON_LEFT_INVERSE]) THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `g:complex->complex` THEN + STRIP_TAC THEN ASM_SIMP_TAC[FORALL_IN_IMAGE] THEN + ASM_SIMP_TAC[HOLOMORPHIC_ON_OPEN; FORALL_IN_IMAGE] THEN + REWRITE_TAC[AND_FORALL_THM] THEN X_GEN_TAC `z:complex` THEN + ASM_CASES_TAC `(z:complex) IN s` THEN ASM_REWRITE_TAC[] THEN + MP_TAC(ISPECL + [`f:complex->complex`; `g:complex->complex`; + `complex_derivative f z`; `s:complex->bool`; + `z:complex`] HAS_COMPLEX_DERIVATIVE_INVERSE_STRONG) THEN + ASM_SIMP_TAC[HOLOMORPHIC_ON_IMP_CONTINUOUS_ON; IMP_CONJ] THEN + ANTS_TAC THENL + [ASM_MESON_TAC[HAS_COMPLEX_DERIVATIVE_DIFFERENTIABLE; HOLOMORPHIC_ON_OPEN; + complex_differentiable]; + ALL_TAC] THEN + MP_TAC(ISPECL [`f:complex->complex`; `s:complex->bool`] + HOLOMORPHIC_INJECTIVE_IMP_REGULAR) THEN + ANTS_TAC THENL [ASM_MESON_TAC[]; DISCH_THEN(MP_TAC o SPEC `z:complex`)] THEN + ASM_REWRITE_TAC[] THEN DISCH_TAC THEN ASM_REWRITE_TAC[] THEN + ASM_SIMP_TAC[COMPLEX_FIELD + `~(z = Cx(&0)) ==> (z * w = Cx(&1) <=> w = inv z)`] THEN + MESON_TAC[HAS_COMPLEX_DERIVATIVE_DERIVATIVE]);; + +(* ------------------------------------------------------------------------- *) +(* Holomorphism of covering maps and lifts. *) +(* ------------------------------------------------------------------------- *) + +let COVERING_SPACE_LIFT_IS_HOLOMORPHIC = prove + (`!p c s f g u. + covering_space (c,p) s /\ open c /\ p holomorphic_on c /\ + f holomorphic_on u /\ IMAGE f u SUBSET s /\ IMAGE g u SUBSET c /\ + g continuous_on u /\ (!x. x IN u ==> p(g x) = f x) + ==> g holomorphic_on u`, + REPEAT STRIP_TAC THEN + REWRITE_TAC[holomorphic_on; GSYM complex_differentiable] THEN + X_GEN_TAC `z:complex` THEN DISCH_TAC THEN + FIRST_ASSUM(MP_TAC o SPEC `(f:complex->complex) z` o last o CONJUNCTS o + GEN_REWRITE_RULE I [covering_space]) THEN + ANTS_TAC THENL [ASM SET_TAC[]; ASM_SIMP_TAC[OPEN_IN_OPEN_EQ]] THEN + DISCH_THEN(X_CHOOSE_THEN `t:complex->bool` MP_TAC) THEN + REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + DISCH_THEN(X_CHOOSE_THEN `vv:(complex->bool)->bool` STRIP_ASSUME_TAC) THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [EXTENSION]) THEN + DISCH_THEN(MP_TAC o snd o EQ_IMP_RULE o SPEC `(g:complex->complex) z`) THEN + ANTS_TAC THENL [ASM SET_TAC[]; REWRITE_TAC[IN_UNIONS]] THEN + DISCH_THEN(X_CHOOSE_THEN `v:complex->bool` STRIP_ASSUME_TAC) THEN + MP_TAC(ISPECL [`p:complex->complex`; `v:complex->bool`] + HOLOMORPHIC_ON_INVERSE) THEN + ANTS_TAC THENL + [CONJ_TAC THENL [ASM_MESON_TAC[HOLOMORPHIC_ON_SUBSET]; ALL_TAC] THEN + RULE_ASSUM_TAC(REWRITE_RULE[homeomorphism]) THEN ASM SET_TAC[]; + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + DISCH_THEN(X_CHOOSE_THEN `p':complex->complex` STRIP_ASSUME_TAC)] THEN + MATCH_MP_TAC COMPLEX_DIFFERENTIABLE_TRANSFORM_WITHIN THEN + EXISTS_TAC `(p':complex->complex) o (f:complex->complex)` THEN + MP_TAC(ISPECL + [`g:complex->complex`; `u:complex->bool`; `c:complex->bool`; + `v:complex->bool`] CONTINUOUS_OPEN_IN_PREIMAGE_GEN) THEN + ASM_SIMP_TAC[OPEN_IN_OPEN_EQ] THEN REWRITE_TAC[open_in] THEN + DISCH_THEN(MP_TAC o SPEC `z:complex` o CONJUNCT2) THEN + ANTS_TAC THENL [ASM SET_TAC[]; REWRITE_TAC[o_THM; IN_ELIM_THM]] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `e:real` THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + MATCH_MP_TAC COMPLEX_DIFFERENTIABLE_COMPOSE_WITHIN THEN CONJ_TAC THENL + [MATCH_MP_TAC HOLOMORPHIC_ON_IMP_DIFFERENTIABLE_WITHIN THEN + ASM_MESON_TAC[HOLOMORPHIC_ON_SUBSET]; + MATCH_MP_TAC COMPLEX_DIFFERENTIABLE_AT_WITHIN THEN + MATCH_MP_TAC HOLOMORPHIC_ON_IMP_DIFFERENTIABLE_AT THEN + EXISTS_TAC `IMAGE (p:complex->complex) v` THEN + ASM_REWRITE_TAC[] THEN ASM SET_TAC[]]);; + +let COVERING_SPACE_LIFT_HOLOMORPHIC = prove + (`!p c s f u. + covering_space (c,p) s /\ p holomorphic_on c /\ open c /\ + simply_connected u /\ locally path_connected u /\ + f holomorphic_on u /\ IMAGE f u SUBSET s + ==> ?g. g holomorphic_on u /\ IMAGE g u SUBSET c /\ + !y. y IN u ==> p(g y) = f y`, + REPEAT STRIP_TAC THEN MP_TAC(ISPECL + [`p:complex->complex`; `c:complex->bool`; `s:complex->bool`; + `f:complex->complex`; `u:complex->bool`] COVERING_SPACE_LIFT) THEN + ASM_SIMP_TAC[HOLOMORPHIC_ON_IMP_CONTINUOUS_ON] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `g:complex->complex` THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + FIRST_ASSUM(MATCH_MP_TAC o MATCH_MP (ONCE_REWRITE_RULE[IMP_CONJ] + COVERING_SPACE_LIFT_IS_HOLOMORPHIC)) THEN + EXISTS_TAC `f:complex->complex` THEN ASM_REWRITE_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* The Schwarz lemma. *) +(* ------------------------------------------------------------------------- *) + +let SCHWARZ_LEMMA = prove + (`!f. f holomorphic_on ball(Cx(&0),&1) /\ + (!z:complex. norm z < &1 ==> norm (f z) < &1) /\ + f(Cx(&0)) = Cx(&0) + ==> (!z. norm z < &1 ==> norm(f z) <= norm z) /\ + norm(complex_derivative f(Cx(&0))) <= &1 /\ + ((?z. norm z < &1 /\ ~(z= Cx(&0)) /\ norm(f z) = norm z) \/ + norm(complex_derivative f (Cx(&0))) = &1 + ==> ?c. (!z. norm z < &1 ==> f z = c*z) /\ norm c = &1)`, + let LEMMA1 = prove + (`!f a. open a /\ connected a /\ bounded a /\ ~(a = {}) /\ + f holomorphic_on a /\ f continuous_on (closure a) + ==> (?w. w IN (frontier a) /\ + (!z. z IN (closure a) ==> norm (f z) <= norm (f w)))`, + REPEAT STRIP_TAC THEN ASSERT_TAC + `?x. x IN closure a /\ + (!z. z IN closure a ==> + norm((f:complex->complex) z) <= norm(f x))` THENL + [MATCH_MP_TAC CONTINUOUS_ATTAINS_SUP THEN + ASM_SIMP_TAC [COMPACT_CLOSURE;CLOSURE_EQ_EMPTY] THEN + SUBGOAL_THEN `lift o (\x. norm((f:complex->complex) x)) = + (lift o norm) o (\x. f x) ` SUBST1_TAC THENL + [REWRITE_TAC[o_DEF]; MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN + ASM_REWRITE_TAC [CONTINUOUS_ON_LIFT_NORM;ETA_AX]]; ALL_TAC] THEN + ASM_CASES_TAC `x:complex IN frontier a` THENL + [EXISTS_TAC `x:complex` THEN ASM_REWRITE_TAC[]; ALL_TAC] THEN + SUBGOAL_THEN `x:complex IN interior a` MP_TAC THENL + [POP_ASSUM MP_TAC THEN REWRITE_TAC[frontier;DIFF] THEN + SET_TAC[ASSUME `x:complex IN closure a`]; ALL_TAC] THEN + ASM_SIMP_TAC[INTERIOR_OPEN] THEN DISCH_TAC THEN + SUBGOAL_THEN `?c. !z. z IN a ==> (f:complex->complex) z = c` + STRIP_ASSUME_TAC THENL + [MATCH_MP_TAC MAXIMUM_MODULUS_PRINCIPLE THEN + EXISTS_TAC `a:complex->bool` THEN + EXISTS_TAC `x:complex` THEN ASM_REWRITE_TAC[SUBSET_REFL] THEN GEN_TAC THEN + DISCH_TAC THEN FIRST_ASSUM MATCH_MP_TAC THEN REWRITE_TAC[closure;UNION] THEN + SET_TAC[ASSUME `z:complex IN a`]; ALL_TAC] THEN + SUBGOAL_THEN `CHOICE(frontier(a:complex->bool)) IN frontier a` + ASSUME_TAC THENL + [MATCH_MP_TAC CHOICE_DEF THEN MATCH_MP_TAC FRONTIER_NOT_EMPTY THEN + CONJ_TAC THENL [ASM SET_TAC[]; ASM_MESON_TAC[NOT_BOUNDED_UNIV]]; + ALL_TAC] THEN + EXISTS_TAC `CHOICE(frontier(a:complex->bool))` THEN ASM_REWRITE_TAC[] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_EQ_IMP_LE THEN + SUBGOAL_THEN `!z. z IN closure a ==> (f:complex->complex) z = c` + ASSUME_TAC THENL + [MP_TAC (ISPECL [`f:complex->complex`; `closure (a:complex->bool)`; + `{c:complex}`] CONTINUOUS_CLOSED_PREIMAGE) THEN + ASM_REWRITE_TAC [CLOSED_CLOSURE; CLOSED_SING] THEN + ABBREV_TAC `s = {x | x IN closure(a:complex->bool) /\ + (f:complex->complex) x IN {c}}` THEN DISCH_TAC THEN + SUBGOAL_THEN `closure a SUBSET (s:complex->bool)` ASSUME_TAC THENL + [MATCH_MP_TAC CLOSURE_MINIMAL THEN CONJ_TAC THENL + [REWRITE_TAC[SUBSET] THEN EXPAND_TAC "s" THEN + ASSUME_TAC (MESON [CLOSURE_SUBSET;GSYM SUBSET] + `!x:complex. x IN a ==> x IN closure a`) THEN + SET_TAC [ASSUME `!x:complex. x IN a ==> x IN closure a`; + ASSUME `!z:complex. z IN a ==> f z = c:complex`]; + ASM_REWRITE_TAC[]]; + POP_ASSUM MP_TAC THEN EXPAND_TAC "s" THEN SET_TAC[]]; + EQ_TRANS_TAC `norm(c:complex)` THENL + [ASM_SIMP_TAC[]; ONCE_REWRITE_TAC [EQ_SYM_EQ] THEN + MATCH_MP_TAC (NORM_ARITH `!x y:complex. x = y ==> norm x = norm y`) THEN + FIRST_ASSUM MATCH_MP_TAC THEN ASM_MESON_TAC[frontier;IN_DIFF]]]) + in + let LEMMA2 = prove + (`!(f:complex->complex) r w s. + &0 < r /\ f holomorphic_on ball(Cx(&0),r) /\ + &0 < s /\ ball(w,s) SUBSET ball(Cx(&0),r) /\ + (!z. norm (w-z) < s ==> norm(f z) <= norm(f w)) + ==> (?c. !z. norm z < r ==> f z = c)`, + REPEAT STRIP_TAC THEN + MP_TAC (SPECL[`f:complex->complex`;`ball (Cx(&0),r)`; `ball (w:complex,s)`; + `w:complex`] MAXIMUM_MODULUS_PRINCIPLE) THEN + ASM_REWRITE_TAC[OPEN_BALL; CONNECTED_BALL; IN_BALL;DIST_REFL] THEN + ASM_REWRITE_TAC[dist;COMPLEX_SUB_LZERO;NORM_NEG]) + in + let LEMMA3 = prove + (`!r:real f. f holomorphic_on (ball(Cx(&0),r)) /\ f (Cx(&0))=Cx(&0) + ==> (?h. h holomorphic_on (ball(Cx(&0),r)) /\ + ((!z. norm z < r ==> f z=z*(h z)) /\ + (complex_derivative f (Cx(&0)))= h (Cx(&0))))`, + REPEAT STRIP_TAC THEN ABBREV_TAC `h = \z. if z = Cx(&0) then + complex_derivative f (Cx(&0)) else f z/z` THEN EXISTS_TAC + `h:complex->complex` THEN ASSERT_TAC `(!z:complex. norm z < r ==> + (f:complex->complex) z = z * h z) /\ complex_derivative f (Cx(&0)) + = h (Cx(&0))` THENL [CONJ_TAC THENL + [GEN_TAC THEN DISCH_TAC THEN EXPAND_TAC "h" THEN + COND_CASES_TAC THENL [ASM_REWRITE_TAC[COMPLEX_MUL_LZERO]; + POP_ASSUM MP_TAC THEN CONV_TAC COMPLEX_FIELD]; + EXPAND_TAC "h" THEN ASM_REWRITE_TAC[]];ALL_TAC] THEN ASM_REWRITE_TAC[] + THEN MATCH_MP_TAC POLE_THEOREM_OPEN_0 THEN EXISTS_TAC `(f:complex->complex)` + THEN EXISTS_TAC `Cx(&0)` THEN + ASM_SIMP_TAC[OPEN_BALL;IN_BALL;COMPLEX_SUB_RZERO; + dist;COMPLEX_SUB_LZERO;NORM_NEG]) + in + GEN_TAC THEN STRIP_TAC THEN + MP_TAC (SPECL [`&1`;`f:complex->complex`] LEMMA3) THEN ASM_REWRITE_TAC[] THEN + STRIP_TAC THEN SUBGOAL_THEN + `!z. norm z < &1 ==> norm ((h:complex->complex) z) <= &1` + ASSUME_TAC THENL + [GEN_TAC THEN DISCH_TAC THEN MATCH_MP_TAC + (prove + (`!x y:real. (!a. y x x <= y`, + REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM REAL_NOT_LT] THEN + ONCE_REWRITE_TAC[REAL_LT_BETWEEN] THEN REWRITE_TAC[NOT_EXISTS_THM; + DE_MORGAN_THM] THEN X_GEN_TAC `z:real` THEN + POP_ASSUM (MP_TAC o SPEC `z:real`) THEN REAL_ARITH_TAC)) THEN + X_GEN_TAC `a:real` THEN + DISCH_TAC THEN SUBGOAL_THEN + `?r. norm (z:complex) < r /\ inv r < a /\ r < &1` MP_TAC THENL + [SUBGOAL_THEN `max (inv a) (norm(z:complex)) < &1` MP_TAC THENL + [ASM_SIMP_TAC[REAL_MAX_LT; REAL_INV_LT_1]; + GEN_REWRITE_TAC LAND_CONV [REAL_LT_BETWEEN] THEN + DISCH_THEN (X_CHOOSE_TAC `r:real`) THEN EXISTS_TAC `r:real` THEN + POP_ASSUM MP_TAC THEN ASM_REWRITE_TAC[REAL_MAX_LT] THEN STRIP_TAC THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC REAL_LT_LINV THEN + ASM_REWRITE_TAC[] THEN ASM_REAL_ARITH_TAC]; ALL_TAC] THEN + STRIP_TAC THEN + SUBGOAL_THEN `&0 < r` ASSUME_TAC THENL + [ASM_MESON_TAC[REAL_LET_TRANS; NORM_POS_LE]; ALL_TAC] THEN + SUBGOAL_THEN `inv (r:real) = &1/r` ASSUME_TAC THENL + [MATCH_MP_TAC REAL_MUL_RINV_UNIQ THEN MATCH_MP_TAC REAL_DIV_LMUL THEN + ASM_SIMP_TAC[REAL_LT_IMP_NZ]; ALL_TAC] THEN + SUBGOAL_THEN `?w. norm w = r /\ (!z. norm z < r + ==> norm((h:complex->complex) z) <= norm(h w))` + STRIP_ASSUME_TAC THENL + [MATCH_MP_TAC(prove (`!f r. &0 < r /\ f holomorphic_on ball(Cx(&0),r) /\ + f continuous_on cball(Cx(&0),r) + ==> (?w. norm w = r /\ (!z. norm z < r ==> norm(f z) <= norm(f w)))`, + REPEAT GEN_TAC THEN STRIP_TAC THEN + MP_TAC(SPECL[`f:complex->complex`; `ball(Cx(&0),r)`] LEMMA1) THEN + ASM_REWRITE_TAC[OPEN_BALL; CONNECTED_BALL; BOUNDED_BALL; BALL_EQ_EMPTY; + REAL_ARITH `!r:real. ~(r <= &0) <=> &0 < r`] THEN + ASM_SIMP_TAC[CLOSURE_BALL] THEN STRIP_TAC THEN EXISTS_TAC `w:complex` THEN + CONJ_TAC THENL + [UNDISCH_TAC `w:complex IN frontier(ball(Cx(&0),r))` THEN + ASM_SIMP_TAC[FRONTIER_BALL;sphere;dist;COMPLEX_SUB_LZERO;NORM_NEG] THEN + SET_TAC[]; + POP_ASSUM MP_TAC THEN + REWRITE_TAC[IN_CBALL;dist;COMPLEX_SUB_LZERO;NORM_NEG] THEN + MESON_TAC [REAL_LT_IMP_LE]])) THEN ASM_REWRITE_TAC[] THEN + CONJ_TAC THENL [MATCH_MP_TAC HOLOMORPHIC_ON_SUBSET + THEN EXISTS_TAC `ball(Cx(&0),&1)` THEN + ASM_SIMP_TAC [SUBSET_BALL;REAL_LT_IMP_LE]; + MATCH_MP_TAC HOLOMORPHIC_ON_IMP_CONTINUOUS_ON THEN + MATCH_MP_TAC HOLOMORPHIC_ON_SUBSET THEN EXISTS_TAC `ball(Cx(&0),&1)` THEN + ASM_REWRITE_TAC[SUBSET; IN_CBALL; IN_BALL] THEN + ASM_MESON_TAC[REAL_LET_TRANS]]; ALL_TAC] THEN + MATCH_MP_TAC REAL_LET_TRANS THEN + EXISTS_TAC `norm(h(w:complex):complex)` THEN CONJ_TAC THENL + [ASM_SIMP_TAC[]; ALL_TAC] THEN + SUBGOAL_THEN `h w:complex = f w / w` SUBST1_TAC THENL + [ASM_SIMP_TAC[] THEN + MP_TAC (MESON [GSYM COMPLEX_NORM_ZERO;REAL_NOT_EQ; + ASSUME `norm(w:complex) =r`; + ASSUME `&0 < r`] `~(w=Cx(&0))`) THEN + CONV_TAC(COMPLEX_FIELD); + ASM_REWRITE_TAC[COMPLEX_NORM_DIV] THEN MATCH_MP_TAC REAL_LT_TRANS THEN + EXISTS_TAC `&1/(r:real)` THEN ASM_SIMP_TAC [REAL_LT_DIV2_EQ] THEN + MATCH_MP_TAC REAL_LET_TRANS THEN EXISTS_TAC `inv (r:real)` THEN + ASM_REWRITE_TAC[REAL_LE_REFL]]; ALL_TAC] THEN + CONJ_TAC THENL + [GEN_TAC THEN DISCH_TAC THEN ASM_CASES_TAC `z = Cx(&0)` THENL + [ASM_SIMP_TAC[COMPLEX_MUL_LZERO;REAL_LE_REFL]; + SUBST1_TAC (REAL_ARITH `norm (z:complex) = norm z * &1`) THEN + ASM_SIMP_TAC[COMPLEX_NORM_MUL] THEN MATCH_MP_TAC REAL_LE_LMUL THEN + ASM_SIMP_TAC[NORM_POS_LE]]; ALL_TAC] THEN CONJ_TAC THENL + [ASM_MESON_TAC [COMPLEX_NORM_ZERO;REAL_LT_01]; ALL_TAC] THEN + REWRITE_TAC[TAUT `((p \/ q) ==> r) <=> ((p ==> r) /\ (q ==> r))`] THEN + CONJ_TAC THENL [STRIP_TAC THEN SUBGOAL_THEN + `norm ((h:complex->complex) z) = &1` ASSUME_TAC THENL + [SUBGOAL_THEN `(h:complex->complex) z = f z/z` SUBST1_TAC THENL + [UNDISCH_THEN `!z:complex. norm z < &1 ==> f z = z * h z` + (MP_TAC o SPEC `z:complex`) THEN ASM_REWRITE_TAC[] THEN + UNDISCH_TAC `~(z = Cx(&0))` THEN CONV_TAC(COMPLEX_FIELD); + ASM_SIMP_TAC[COMPLEX_NORM_ZERO;REAL_DIV_REFL;COMPLEX_NORM_DIV]]; + SUBGOAL_THEN `?c. (!z. norm z < &1 ==> (h:complex->complex) z = c)` + STRIP_ASSUME_TAC THENL [MATCH_MP_TAC LEMMA2 + THEN EXISTS_TAC `z:complex` THEN EXISTS_TAC `&1 - norm(z:complex)` + THEN ASM_REWRITE_TAC[REAL_LT_01] THEN CONJ_TAC THENL + [ASM_MESON_TAC[REAL_SUB_LT]; CONJ_TAC THENL + [REWRITE_TAC[SUBSET;IN_BALL] THEN GEN_TAC THEN DISCH_TAC THEN + MATCH_MP_TAC REAL_LET_TRANS THEN + EXISTS_TAC `dist(Cx(&0), z) + dist(z,x)` THEN + REWRITE_TAC[DIST_TRIANGLE] THEN POP_ASSUM MP_TAC THEN + REWRITE_TAC[dist;COMPLEX_SUB_LZERO;NORM_NEG] THEN REAL_ARITH_TAC; + GEN_TAC THEN DISCH_TAC THEN FIRST_ASSUM MATCH_MP_TAC THEN + MATCH_MP_TAC REAL_LET_TRANS THEN + EXISTS_TAC `norm(z:complex) + norm(z' - z)` THEN + REWRITE_TAC[NORM_TRIANGLE_SUB] THEN REWRITE_TAC[NORM_SUB] THEN + POP_ASSUM MP_TAC THEN REWRITE_TAC[NORM_SUB] THEN REAL_ARITH_TAC]]; + EXISTS_TAC `c:complex` THEN CONJ_TAC THENL + [ASM_SIMP_TAC[COMPLEX_MUL_SYM]; + POP_ASSUM (MP_TAC o SPEC `z:complex`) THEN ASM_MESON_TAC[]]]]; + ASM_REWRITE_TAC[] THEN DISCH_TAC THEN + SUBGOAL_THEN `?c. (!z. norm z < &1 ==> (h:complex->complex) z = c)` + STRIP_ASSUME_TAC THENL[MATCH_MP_TAC LEMMA2 THEN EXISTS_TAC `Cx(&0)` + THEN EXISTS_TAC `&1` THEN ASM_REWRITE_TAC[REAL_ARITH `&0 < &1`; + SUBSET_REFL; COMPLEX_SUB_LZERO; NORM_NEG]; + EXISTS_TAC `c:complex` THEN CONJ_TAC THENL + [ASM_SIMP_TAC[COMPLEX_MUL_SYM];POP_ASSUM (MP_TAC o SPEC `Cx(&0)`) THEN + ASM_MESON_TAC[COMPLEX_NORM_0; REAL_LT_01]]]]);; + +(* ------------------------------------------------------------------------- *) +(* The Schwarz reflection principle. *) +(* ------------------------------------------------------------------------- *) + +let HOLOMORPHIC_ON_PASTE_ACROSS_LINE = prove + (`!f s a k. + open s /\ ~(a = vec 0) /\ + f holomorphic_on {z | z IN s /\ k < a dot z} /\ + f holomorphic_on {z | z IN s /\ a dot z < k} /\ + f continuous_on s + ==> f holomorphic_on s`, + let lemma0 = prove + (`!d a b:real^N k. + d dot a <= k /\ k <= d dot b + ==> ?c. c IN segment[a,b] /\ d dot c = k /\ + (!z. z IN segment[a,c] ==> d dot z <= k) /\ + (!z. z IN segment[c,b] ==> k <= d dot z)`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`segment[a:real^N,b]`; `a:real^N`; `b:real^N`; + `d:real^N`; `k:real`] CONNECTED_IVT_HYPERPLANE) THEN + ASM_REWRITE_TAC[CONNECTED_SEGMENT; ENDS_IN_SEGMENT] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `c:real^N` THEN STRIP_TAC THEN + ASM_REWRITE_TAC[SET_RULE + `(!z. z IN s ==> P z) <=> s SUBSET {x | P x}`] THEN + REWRITE_TAC[SEGMENT_CONVEX_HULL] THEN CONJ_TAC THEN + MATCH_MP_TAC HULL_MINIMAL THEN + REWRITE_TAC[CONVEX_HALFSPACE_LE; REWRITE_RULE[real_ge] CONVEX_HALFSPACE_GE; + SUBSET; FORALL_IN_INSERT; NOT_IN_EMPTY] THEN + ASM_REWRITE_TAC[IN_ELIM_THM; REAL_LE_REFL]) in + let lemma1 = prove + (`!f s d k a b c. + convex s /\ open s /\ a IN s /\ b IN s /\ c IN s /\ ~(d = vec 0) /\ + d dot a <= k /\ d dot b <= k /\ d dot c <= k /\ + f holomorphic_on {z | z IN s /\ d dot z < k} /\ + f holomorphic_on {z | z IN s /\ k < d dot z} /\ + f continuous_on s + ==> path_integral (linepath (a,b)) f + + path_integral (linepath (b,c)) f + + path_integral (linepath (c,a)) f = Cx(&0)`, + REPEAT STRIP_TAC THEN + MP_TAC(SPECL [`f:complex->complex`; `a:complex`; `b:complex`; `c:complex`] + CAUCHY_THEOREM_TRIANGLE_INTERIOR) THEN + ANTS_TAC THENL + [CONJ_TAC THENL + [MATCH_MP_TAC CONTINUOUS_ON_SUBSET THEN + EXISTS_TAC `s:complex->bool` THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC HULL_MINIMAL THEN ASM SET_TAC[]; + MATCH_MP_TAC HOLOMORPHIC_ON_SUBSET THEN + EXISTS_TAC `{z:complex | z IN s /\ d dot z < k}` THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC SUBSET_TRANS THEN + EXISTS_TAC `interior(s INTER {x:complex | d dot x <= k})` THEN + CONJ_TAC THENL + [MATCH_MP_TAC SUBSET_INTERIOR THEN MATCH_MP_TAC HULL_MINIMAL THEN + ASM_SIMP_TAC[CONVEX_INTER; CONVEX_HALFSPACE_LE] THEN ASM SET_TAC[]; + ASM_SIMP_TAC[INTERIOR_INTER; INTERIOR_HALFSPACE_LE; + INTERIOR_OPEN] THEN + SET_TAC[]]]; + REWRITE_TAC[HAS_CHAIN_INTEGRAL_CHAIN_INTEGRAL]]) in + let lemma2 = prove + (`!f s d k a b c. + convex s /\ open s /\ a IN s /\ b IN s /\ c IN s /\ ~(d = vec 0) /\ + d dot a <= k /\ d dot b <= k /\ + f holomorphic_on {z | z IN s /\ d dot z < k} /\ + f holomorphic_on {z | z IN s /\ k < d dot z} /\ + f continuous_on s + ==> path_integral (linepath (a,b)) f + + path_integral (linepath (b,c)) f + + path_integral (linepath (c,a)) f = Cx(&0)`, + REPEAT STRIP_TAC THEN ASM_CASES_TAC `(d:complex) dot c <= k` THENL + [MATCH_MP_TAC lemma1 THEN ASM_MESON_TAC[]; ALL_TAC] THEN + RULE_ASSUM_TAC(REWRITE_RULE[REAL_NOT_LE]) THEN + MP_TAC(ISPECL [`d:complex`; `b:complex`; `c:complex`; `k:real`] + lemma0) THEN + MP_TAC(ISPECL [`d:complex`; `a:complex`; `c:complex`; `k:real`] + lemma0) THEN + ASM_SIMP_TAC[REAL_LT_IMP_LE] THEN + DISCH_THEN(X_CHOOSE_THEN `a':complex` STRIP_ASSUME_TAC) THEN + DISCH_THEN(X_CHOOSE_THEN `b':complex` STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN `(a':complex) IN s /\ b' IN s` STRIP_ASSUME_TAC THENL + [ASM_MESON_TAC[CONVEX_CONTAINS_SEGMENT; SEGMENT_SYM; SUBSET]; + ALL_TAC] THEN + MP_TAC(SPECL + [`f:complex->complex`; `c:complex`; `a:complex`; `a':complex`] + PATH_INTEGRAL_SPLIT_LINEPATH) THEN + MP_TAC(SPECL + [`f:complex->complex`; `b:complex`; `c:complex`; `b':complex`] + PATH_INTEGRAL_SPLIT_LINEPATH) THEN + ASM_REWRITE_TAC[] THEN REPEAT(ANTS_TAC THENL + [ASM_MESON_TAC[CONVEX_CONTAINS_SEGMENT; SEGMENT_SYM; + CONTINUOUS_ON_SUBSET]; + ONCE_REWRITE_TAC[TAUT `p ==> q ==> r <=> q ==> p ==> r`]]) THEN + MP_TAC(ISPECL [`f:complex->complex`; `linepath(a':complex,b')`] + PATH_INTEGRAL_REVERSEPATH) THEN + REWRITE_TAC[REVERSEPATH_LINEPATH; VALID_PATH_LINEPATH] THEN ANTS_TAC THENL + [MATCH_MP_TAC PATH_INTEGRABLE_CONTINUOUS_LINEPATH THEN + ASM_MESON_TAC[CONVEX_CONTAINS_SEGMENT; CONTINUOUS_ON_SUBSET]; + ALL_TAC] THEN + MP_TAC(ISPECL [`f:complex->complex`; `s INTER {x:complex | d dot x <= k}`; + `{}:complex->bool`; + `linepath(a:complex,b) ++ linepath(b,b') ++ + linepath(b',a') ++ linepath(a',a)`] + CAUCHY_THEOREM_CONVEX) THEN + MP_TAC(ISPECL [`f:complex->complex`; `s INTER {x:complex | k <= d dot x}`; + `{}:complex->bool`; + `linepath(b':complex,c) ++ linepath(c,a') ++ + linepath(a',b')`] + CAUCHY_THEOREM_CONVEX) THEN + MATCH_MP_TAC(TAUT + `(q /\ q' ==> r) /\ (p /\ p') ==> (p ==> q) ==> (p' ==> q') ==> r`) THEN + CONJ_TAC THENL + [DISCH_THEN(CONJUNCTS_THEN + (fun th -> MP_TAC(MATCH_MP PATH_INTEGRAL_UNIQUE th) THEN + MP_TAC(MATCH_MP HAS_PATH_INTEGRAL_INTEGRABLE th))); + ASM_SIMP_TAC[DIFF_EMPTY; INTERIOR_INTER; INTERIOR_HALFSPACE_LE; + REWRITE_RULE[real_ge] INTERIOR_HALFSPACE_GE] THEN + ASM_SIMP_TAC[CONVEX_INTER; CONVEX_HALFSPACE_LE; FINITE_EMPTY; + REWRITE_RULE[real_ge] CONVEX_HALFSPACE_GE]] THEN + SIMP_TAC[PATH_INTEGRABLE_JOIN; VALID_PATH_JOIN_EQ; + PATHSTART_JOIN; PATHFINISH_JOIN; PATH_IMAGE_JOIN; + VALID_PATH_LINEPATH; PATHSTART_LINEPATH; PATHFINISH_LINEPATH; + PATH_INTEGRAL_JOIN] + THENL [CONV_TAC COMPLEX_RING; ALL_TAC] THEN + REWRITE_TAC[PATH_IMAGE_LINEPATH; UNION_SUBSET; SUBSET_INTER] THEN + ASM_SIMP_TAC[fst(EQ_IMP_RULE(SPEC_ALL CONVEX_CONTAINS_SEGMENT_EQ)); + CONVEX_HALFSPACE_LE; REWRITE_RULE[real_ge] CONVEX_HALFSPACE_GE; + IN_ELIM_THM; REAL_LT_IMP_LE; REAL_LE_REFL] THEN + ASM_SIMP_TAC[complex_differentiable; GSYM HOLOMORPHIC_ON_OPEN; + OPEN_INTER; INTERIOR_OPEN; OPEN_HALFSPACE_LT; + OPEN_HALFSPACE_GT] THEN + RULE_ASSUM_TAC(REWRITE_RULE[SET_RULE + `{x | x IN s /\ P x} = s INTER {x | P x}`]) THEN + ASM_REWRITE_TAC[real_gt] THEN + ASM_MESON_TAC[INTER_SUBSET; CONTINUOUS_ON_SUBSET]) in + let lemma3 = prove + (`!f s d k a b c. + convex s /\ open s /\ a IN s /\ b IN s /\ c IN s /\ ~(d = vec 0) /\ + d dot a <= k /\ + f holomorphic_on {z | z IN s /\ d dot z < k} /\ + f holomorphic_on {z | z IN s /\ k < d dot z} /\ + f continuous_on s + ==> path_integral (linepath (a,b)) f + + path_integral (linepath (b,c)) f + + path_integral (linepath (c,a)) f = Cx(&0)`, + REPEAT STRIP_TAC THEN ASM_CASES_TAC `(d:complex) dot b <= k` THENL + [MATCH_MP_TAC lemma2 THEN ASM_MESON_TAC[]; ALL_TAC] THEN + ASM_CASES_TAC `(d:complex) dot c <= k` THENL + [ONCE_REWRITE_TAC[COMPLEX_RING `a + b + c:complex = c + a + b`] THEN + MATCH_MP_TAC(GEN_ALL lemma2) THEN ASM_MESON_TAC[]; + ALL_TAC] THEN + ONCE_REWRITE_TAC[COMPLEX_RING `a + b + c:complex = b + c + a`] THEN + MATCH_MP_TAC(GEN_ALL lemma2) THEN + MAP_EVERY EXISTS_TAC + [`s:complex->bool`; `--d:real^2`; `--k:real`] THEN + ASM_REWRITE_TAC[DOT_LNEG; REAL_LE_NEG2; REAL_LT_NEG2; VECTOR_NEG_EQ_0] THEN + ASM_REAL_ARITH_TAC) in + let lemma4 = prove + (`!f s d k a b c. + convex s /\ open s /\ a IN s /\ b IN s /\ c IN s /\ ~(d = vec 0) /\ + f holomorphic_on {z | z IN s /\ d dot z < k} /\ + f holomorphic_on {z | z IN s /\ k < d dot z} /\ + f continuous_on s + ==> path_integral (linepath (a,b)) f + + path_integral (linepath (b,c)) f + + path_integral (linepath (c,a)) f = Cx(&0)`, + REPEAT STRIP_TAC THEN ASM_CASES_TAC `(d:complex) dot a <= k` THENL + [MATCH_MP_TAC lemma3 THEN ASM_MESON_TAC[]; ALL_TAC] THEN + MATCH_MP_TAC lemma3 THEN + MAP_EVERY EXISTS_TAC + [`s:complex->bool`; `--d:real^2`; `--k:real`] THEN + ASM_REWRITE_TAC[DOT_LNEG; REAL_LE_NEG2; REAL_LT_NEG2; VECTOR_NEG_EQ_0] THEN + ASM_REAL_ARITH_TAC) in + REPEAT STRIP_TAC THEN MATCH_MP_TAC ANALYTIC_IMP_HOLOMORPHIC THEN + MATCH_MP_TAC MORERA_LOCAL_TRIANGLE THEN + X_GEN_TAC `p:complex` THEN DISCH_TAC THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [OPEN_CONTAINS_BALL]) THEN + DISCH_THEN(MP_TAC o SPEC `p:complex`) THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `e:real` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `ball(p:complex,e)` THEN + ASM_REWRITE_TAC[OPEN_BALL; CENTRE_IN_BALL] THEN + CONJ_TAC THENL [ASM_MESON_TAC[CONTINUOUS_ON_SUBSET]; ALL_TAC] THEN + MAP_EVERY X_GEN_TAC [`u:complex`; `v:complex`; `w:complex`] THEN + SIMP_TAC[SUBSET_HULL; CONVEX_BALL; INSERT_SUBSET; EMPTY_SUBSET] THEN + STRIP_TAC THEN MATCH_MP_TAC lemma4 THEN + MAP_EVERY EXISTS_TAC [`ball(p:complex,e)`; `a:complex`; `k:real`] THEN + ASM_REWRITE_TAC[CONVEX_BALL; OPEN_BALL] THEN REPEAT CONJ_TAC THENL + [MATCH_MP_TAC HOLOMORPHIC_ON_SUBSET THEN + EXISTS_TAC `{z:complex | z IN s /\ a dot z < k}`; + MATCH_MP_TAC HOLOMORPHIC_ON_SUBSET THEN + EXISTS_TAC `{z:complex | z IN s /\ k < a dot z}`; + MATCH_MP_TAC CONTINUOUS_ON_SUBSET THEN + EXISTS_TAC `s:complex->bool`] THEN + ASM_REWRITE_TAC[] THEN ASM SET_TAC[]);; + +let SCHWARZ_REFLECTION = prove + (`!f s. open s /\ (!z. z IN s ==> cnj z IN s) /\ + f holomorphic_on {z | z IN s /\ &0 < Im z} /\ + f continuous_on {z | z IN s /\ &0 <= Im z} /\ + (!z. z IN s /\ real z ==> real(f z)) + ==> (\z. if &0 <= Im z then f(z) else cnj(f(cnj z))) + holomorphic_on s`, + REPEAT STRIP_TAC THEN + MATCH_MP_TAC HOLOMORPHIC_ON_PASTE_ACROSS_LINE THEN + MAP_EVERY EXISTS_TAC [`basis 2:complex`; `&0`] THEN + ASM_SIMP_TAC[BASIS_NONZERO; DOT_BASIS; DIMINDEX_2; ARITH] THEN + REWRITE_TAC[GSYM IM_DEF] THEN REPEAT CONJ_TAC THENL + [UNDISCH_TAC `f holomorphic_on {z | z IN s /\ &0 < Im z}` THEN + MATCH_MP_TAC EQ_IMP THEN MATCH_MP_TAC HOLOMORPHIC_EQ THEN + SIMP_TAC[IN_ELIM_THM; REAL_LT_IMP_LE]; + SUBGOAL_THEN + `(cnj o f o cnj) holomorphic_on {z | z IN s /\ Im z < &0}` + MP_TAC THENL + [ALL_TAC; + MATCH_MP_TAC EQ_IMP THEN MATCH_MP_TAC HOLOMORPHIC_EQ THEN + SIMP_TAC[IN_ELIM_THM; GSYM REAL_NOT_LE; o_THM]] THEN + UNDISCH_TAC `f holomorphic_on {z | z IN s /\ &0 < Im z}` THEN + REWRITE_TAC[holomorphic_on; IN_ELIM_THM] THEN DISCH_TAC THEN + X_GEN_TAC `z:complex` THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `cnj z`) THEN + ASM_SIMP_TAC[IM_CNJ; REAL_ARITH `&0 < --x <=> x < &0`] THEN + DISCH_THEN(X_CHOOSE_THEN `w:complex` + (fun th -> EXISTS_TAC `cnj w` THEN MP_TAC th)) THEN + REWRITE_TAC[HAS_COMPLEX_DERIVATIVE_WITHIN; LIM_WITHIN] THEN + GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [GSYM FORALL_CNJ] THEN + REWRITE_TAC[IN_ELIM_THM; dist; GSYM CNJ_SUB; o_THM] THEN + GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [GSYM COMPLEX_NORM_CNJ] THEN + REWRITE_TAC[CNJ_SUB; CNJ_DIV; CNJ_CNJ] 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 REPEAT STRIP_TAC THEN + ASM_REWRITE_TAC[] THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_SIMP_TAC[IM_CNJ] THEN ASM_REAL_ARITH_TAC; + SUBGOAL_THEN + `s = {z | z IN s /\ &0 <= Im z} UNION + {z | z IN s /\ Im z <= &0}` + (fun th -> SUBST1_TAC th THEN ASSUME_TAC(SYM th)) + THENL [SET_TAC[REAL_LE_TOTAL]; ALL_TAC] THEN + MATCH_MP_TAC CONTINUOUS_ON_CASES_LOCAL THEN + ASM_REWRITE_TAC[IN_ELIM_THM] THEN + REWRITE_TAC[SET_RULE `{z | z IN s /\ P z} = s INTER {z | P z}`] THEN + SIMP_TAC[CLOSED_IN_CLOSED_INTER; CLOSED_HALFSPACE_IM_LE; + REWRITE_RULE[real_ge] CLOSED_HALFSPACE_IM_GE] THEN + CONJ_TAC THENL + [REPLICATE_TAC 2 + (MATCH_MP_TAC(REWRITE_RULE[o_DEF] CONTINUOUS_ON_COMPOSE) THEN + REWRITE_TAC[CONTINUOUS_ON_CNJ]) 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; IN_ELIM_THM; IN_INTER; IM_CNJ] THEN + REAL_ARITH_TAC; + X_GEN_TAC `z:complex` THEN DISCH_TAC THEN + SUBGOAL_THEN `real z` ASSUME_TAC THENL + [REWRITE_TAC[real] THEN ASM_REAL_ARITH_TAC; ALL_TAC] THEN + RULE_ASSUM_TAC(REWRITE_RULE[REAL_CNJ]) THEN ASM_MESON_TAC[]]]);; + +(* ------------------------------------------------------------------------- *) +(* Bloch's theorem. *) +(* ------------------------------------------------------------------------- *) + +let BLOCH_LEMMA = prove + (`!f a r. + &0 < r /\ f holomorphic_on cball(a,r) /\ + (!z. z IN ball(a,r) + ==> norm(complex_derivative f z) <= &2 * norm(complex_derivative f a)) + ==> ball(f(a),(&3 - &2 * sqrt(&2)) * r * norm(complex_derivative f a)) + SUBSET IMAGE f (ball(a,r))`, + SUBGOAL_THEN + `!f r. + &0 < r /\ f holomorphic_on cball(Cx(&0),r) /\ f(Cx(&0)) = Cx(&0) /\ + (!z. z IN ball(Cx(&0),r) + ==> norm(complex_derivative f z) + <= &2 * norm(complex_derivative f (Cx(&0)))) + ==> ball(Cx(&0), + (&3 - &2 * sqrt(&2)) * + r * norm(complex_derivative f (Cx(&0)))) + SUBSET IMAGE f (ball(Cx(&0),r))` + ASSUME_TAC THENL + [ALL_TAC; + REPEAT STRIP_TAC THEN FIRST_X_ASSUM(MP_TAC o SPECL + [`\z. (f:complex->complex)(a + z) - f(a)`; `r:real`]) THEN + ASM_REWRITE_TAC[COMPLEX_ADD_RID; COMPLEX_SUB_REFL] THEN + SUBGOAL_THEN + `!z. z IN ball(Cx(&0),r) + ==> complex_derivative (\w. f (a + w) - f a) z = + complex_derivative f (a + z)` + (fun th -> ASM_SIMP_TAC[CENTRE_IN_BALL; COMPLEX_ADD_RID; th]) + THENL + [REWRITE_TAC[COMPLEX_IN_BALL_0] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC HAS_COMPLEX_DERIVATIVE_DERIVATIVE THEN + ONCE_REWRITE_TAC [COMPLEX_RING + `complex_derivative f z = + complex_derivative f z * (Cx(&0) + Cx(&1)) - Cx(&0)`] THEN + MATCH_MP_TAC HAS_COMPLEX_DERIVATIVE_SUB THEN + REWRITE_TAC[HAS_COMPLEX_DERIVATIVE_CONST] THEN + GEN_REWRITE_TAC (RATOR_CONV o LAND_CONV) [GSYM o_DEF] THEN + MATCH_MP_TAC COMPLEX_DIFF_CHAIN_AT THEN + SIMP_TAC[HAS_COMPLEX_DERIVATIVE_ADD; HAS_COMPLEX_DERIVATIVE_CONST; + HAS_COMPLEX_DERIVATIVE_ID; HAS_COMPLEX_DERIVATIVE_DIFFERENTIABLE] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [holomorphic_on]) THEN + DISCH_THEN(MP_TAC o SPEC `a + z:complex`) THEN + ASM_SIMP_TAC[IN_CBALL; NORM_ARITH `norm z < r ==> dist(a,a+z) <= r`] THEN + REWRITE_TAC[GSYM complex_differentiable] THEN + DISCH_THEN(MP_TAC o SPEC `ball(a:complex,r)` o + MATCH_MP (REWRITE_RULE[IMP_CONJ] + COMPLEX_DIFFERENTIABLE_WITHIN_SUBSET)) THEN + ASM_REWRITE_TAC[BALL_SUBSET_CBALL] THEN MATCH_MP_TAC EQ_IMP THEN + MATCH_MP_TAC COMPLEX_DIFFERENTIABLE_WITHIN_OPEN THEN + ASM_REWRITE_TAC[IN_BALL; OPEN_BALL; NORM_ARITH `dist(a,a + z) = norm z`]; + ANTS_TAC THENL + [CONJ_TAC THENL + [MATCH_MP_TAC HOLOMORPHIC_ON_SUB THEN + REWRITE_TAC[HOLOMORPHIC_ON_CONST] THEN + GEN_REWRITE_TAC LAND_CONV [GSYM o_DEF] THEN + MATCH_MP_TAC HOLOMORPHIC_ON_COMPOSE_GEN THEN + EXISTS_TAC `cball(a:complex,r)` THEN + ASM_SIMP_TAC[HOLOMORPHIC_ON_ADD; HOLOMORPHIC_ON_ID; + HOLOMORPHIC_ON_CONST; COMPLEX_IN_CBALL_0] THEN + REWRITE_TAC[IN_CBALL] THEN NORM_ARITH_TAC; + X_GEN_TAC `z:complex` THEN REWRITE_TAC[COMPLEX_IN_BALL_0] THEN + STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_REWRITE_TAC[IN_BALL; NORM_ARITH `dist(a,a + z) = norm z`]]; + REWRITE_TAC[SUBSET; COMPLEX_IN_BALL_0; IN_IMAGE] THEN + REWRITE_TAC[IN_BALL; ONCE_REWRITE_RULE[DIST_SYM] dist] THEN + DISCH_THEN(fun th -> + X_GEN_TAC `z:complex` THEN DISCH_TAC THEN + MP_TAC(SPEC `z - (f:complex->complex) a` th)) THEN + ASM_REWRITE_TAC[COMPLEX_RING `z - a:complex = w - a <=> z = w`] THEN + DISCH_THEN(X_CHOOSE_TAC `x:complex`) THEN + EXISTS_TAC `a + x:complex` THEN + ASM_REWRITE_TAC[COMPLEX_ADD_SUB]]]] THEN + REPEAT GEN_TAC THEN + SUBGOAL_THEN `&0 < &3 - &2 * sqrt(&2)` ASSUME_TAC THENL + [REWRITE_TAC[REAL_ARITH `&0 < a - &2 * b <=> b < a / &2`] THEN + MATCH_MP_TAC REAL_LT_LSQRT THEN REAL_ARITH_TAC; + ALL_TAC] THEN + ASM_CASES_TAC `&0 < r` THEN ASM_REWRITE_TAC[] THEN STRIP_TAC THEN + ASM_CASES_TAC `complex_derivative f (Cx(&0)) = Cx(&0)` THEN + ASM_SIMP_TAC[COMPLEX_NORM_0; REAL_MUL_RZERO; BALL_TRIVIAL; EMPTY_SUBSET] THEN + ABBREV_TAC `C = &2 * norm(complex_derivative f (Cx(&0)))` THEN + SUBGOAL_THEN `&0 < C` ASSUME_TAC THENL + [ASM_MESON_TAC[COMPLEX_NORM_NZ; REAL_ARITH `&0 < &2 * x <=> &0 < x`]; + ALL_TAC] THEN + SUBGOAL_THEN + `!z. z IN ball(Cx(&0),r) + ==> norm(complex_derivative f z - complex_derivative f (Cx(&0))) + <= norm(z) / (r - norm(z)) * C` + (LABEL_TAC "+") THENL + [REPEAT STRIP_TAC THEN + SUBGOAL_THEN + `!R. norm z < R /\ R < r + ==> norm(complex_derivative f z - complex_derivative f (Cx(&0))) + <= norm(z) / (R - norm(z)) * C` + MP_TAC THENL + [REPEAT STRIP_TAC THEN + MP_TAC(ISPECL + [`complex_derivative f`; + `cball(Cx(&0),R)`; + `circlepath(Cx(&0),R)`] + CAUCHY_INTEGRAL_FORMULA_CONVEX_SIMPLE) THEN + REWRITE_TAC[CONVEX_CBALL; VALID_PATH_CIRCLEPATH; INTERIOR_CBALL; + PATHSTART_CIRCLEPATH; PATHFINISH_CIRCLEPATH] THEN + SUBGOAL_THEN `&0 < R` ASSUME_TAC THENL + [ASM_MESON_TAC[REAL_LET_TRANS; NORM_POS_LE]; ALL_TAC] THEN + ASM_SIMP_TAC[PATH_IMAGE_CIRCLEPATH; REAL_LT_IMP_LE] THEN + REWRITE_TAC[sphere; NORM_ARITH `dist(z,w) = norm(w - z)`] THEN + REWRITE_TAC[SUBSET; FORALL_IN_GSPEC; IN_CBALL; IN_BALL; IN_DELETE] THEN + SIMP_TAC[WINDING_NUMBER_CIRCLEPATH; COMPLEX_SUB_RZERO; COMPLEX_SUB_LZERO; + dist; NORM_NEG; REAL_LE_REFL; MESON[REAL_LT_REFL] + `norm z < R /\ (!w. norm w = R ==> ~(w = z)) <=> norm z < R`] THEN + REWRITE_TAC[RIGHT_FORALL_IMP_THM; IMP_CONJ] THEN ANTS_TAC THENL + [MATCH_MP_TAC HOLOMORPHIC_ON_SUBSET THEN + EXISTS_TAC `ball(Cx(&0),r)` THEN CONJ_TAC THENL + [MATCH_MP_TAC HOLOMORPHIC_COMPLEX_DERIVATIVE THEN + REWRITE_TAC[OPEN_BALL] THEN + MATCH_MP_TAC HOLOMORPHIC_ON_SUBSET THEN + EXISTS_TAC `cball(Cx(&0),r)` THEN ASM_REWRITE_TAC[BALL_SUBSET_CBALL]; + ASM_REWRITE_TAC[SUBSET_BALLS; DIST_REFL; REAL_ADD_LID]]; + REWRITE_TAC[COMPLEX_MUL_LID]] THEN + DISCH_THEN(fun th -> + MP_TAC (CONJ (SPEC `z:complex` th) (SPEC `Cx(&0)` th))) THEN + ASM_REWRITE_TAC[COMPLEX_NORM_0; COMPLEX_SUB_RZERO] THEN + DISCH_THEN(MP_TAC o MATCH_MP HAS_PATH_INTEGRAL_SUB) THEN + DISCH_THEN(MP_TAC o SPEC `C * norm(z) / (R * (R - norm(z:complex)))` o + MATCH_MP (ONCE_REWRITE_RULE[IMP_CONJ] + HAS_PATH_INTEGRAL_BOUND_CIRCLEPATH)) THEN + ASM_REWRITE_TAC[GSYM COMPLEX_SUB_LDISTRIB] THEN + REWRITE_TAC[COMPLEX_NORM_MUL; COMPLEX_NORM_CX; COMPLEX_NORM_II] THEN + REWRITE_TAC[REAL_ABS_NUM; REAL_MUL_LID; REAL_ABS_PI] THEN + ASM_SIMP_TAC[REAL_FIELD + `&0 < R /\ z < R + ==> (C * z / (R * (R - z))) * &2 * pi * R = + &2 * pi * z / (R - z) * C`] THEN + ASM_SIMP_TAC[REAL_LE_LMUL_EQ; REAL_ARITH `&0 < &2`; PI_POS] THEN + DISCH_THEN MATCH_MP_TAC THEN + ASM_SIMP_TAC[REAL_LE_MUL_EQ; REAL_LE_DIV; REAL_LE_MUL; REAL_SUB_LE; + REAL_LT_IMP_LE; NORM_POS_LE; COMPLEX_SUB_RZERO] THEN + X_GEN_TAC `x:complex` THEN DISCH_TAC THEN + SUBGOAL_THEN `~(x = Cx(&0)) /\ ~(x = z)` STRIP_ASSUME_TAC THENL + [ASM_MESON_TAC[REAL_LT_REFL; COMPLEX_NORM_0]; ALL_TAC] THEN + ASM_SIMP_TAC[COMPLEX_FIELD + `~(x = Cx(&0)) /\ ~(x = z) + ==> d / (x - z) - d / x = d * z / (x * (x - z))`] THEN + REWRITE_TAC[COMPLEX_NORM_MUL] THEN MATCH_MP_TAC REAL_LE_MUL2 THEN + ASM_SIMP_TAC[NORM_POS_LE; REAL_LT_IMP_LE; IN_BALL; dist; NORM_NEG; + COMPLEX_SUB_LZERO] THEN + REWRITE_TAC[COMPLEX_NORM_DIV; real_div] THEN + MATCH_MP_TAC REAL_LE_LMUL THEN REWRITE_TAC[NORM_POS_LE] THEN + MATCH_MP_TAC REAL_LE_INV2 THEN + ASM_SIMP_TAC[REAL_LT_MUL; REAL_SUB_LT; COMPLEX_NORM_MUL] THEN + ASM_SIMP_TAC[REAL_LE_LMUL_EQ] THEN + UNDISCH_TAC `norm(x:complex) = R` THEN CONV_TAC NORM_ARITH; + DISCH_TAC THEN MP_TAC(ISPECL + [`\x. lift(norm(z:complex) / (drop x - norm z) * C)`; + `interval(lift((norm(z:complex) + r) / &2),lift r)`; `lift r`; + `norm(complex_derivative f z - complex_derivative f (Cx (&0)))`; + `1`] CONTINUOUS_ON_CLOSURE_COMPONENT_GE) THEN + REWRITE_TAC[GSYM drop; LIFT_DROP; CLOSURE_INTERVAL] THEN + DISCH_THEN MATCH_MP_TAC THEN REWRITE_TAC[INTERVAL_EQ_EMPTY_1] THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_BALL]) THEN + REWRITE_TAC[dist; COMPLEX_SUB_LZERO; NORM_NEG] THEN DISCH_TAC THEN + ASM_SIMP_TAC[ENDS_IN_INTERVAL; INTERVAL_EQ_EMPTY_1; LIFT_DROP; REAL_ARITH + `z < r ==> ~(r <= (z + r) / &2) /\ ~(r < (z + r) / &2)`] THEN + REWRITE_TAC[FORALL_LIFT; LIFT_DROP; IN_INTERVAL_1] THEN + CONJ_TAC THENL + [ALL_TAC; + ASM_MESON_TAC[REAL_ARITH `(z + r) / &2 < R /\ R < r ==> z < R`]] THEN + REWRITE_TAC[LIFT_CMUL; real_div] THEN + MATCH_MP_TAC CONTINUOUS_ON_MUL THEN + REWRITE_TAC[CONTINUOUS_ON_CONST; o_DEF; LIFT_CMUL] THEN + MATCH_MP_TAC CONTINUOUS_ON_MUL THEN + REWRITE_TAC[CONTINUOUS_ON_CONST; o_DEF; LIFT_CMUL] THEN + MATCH_MP_TAC(REWRITE_RULE[o_DEF] CONTINUOUS_ON_INV) THEN + SIMP_TAC[LIFT_SUB; CONTINUOUS_ON_SUB; CONTINUOUS_ON_CONST; LIFT_DROP; + CONTINUOUS_ON_LIFT_NORM_COMPOSE; CONTINUOUS_ON_ID] THEN + REWRITE_TAC[IN_INTERVAL_1; DROP_CMUL; LIFT_DROP] THEN + ASM_REAL_ARITH_TAC]; + ALL_TAC] THEN + SUBGOAL_THEN + `!z. z IN ball(Cx(&0),r) + ==> (norm(z) - norm(z) pow 2 / (r - norm(z))) * + norm(complex_derivative f (Cx(&0))) + <= norm(f z)` + (LABEL_TAC "*") THENL + [REPEAT STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_BALL]) THEN + REWRITE_TAC[dist; COMPLEX_SUB_LZERO; NORM_NEG] THEN DISCH_TAC THEN + MP_TAC(ISPECL[`\z. f(z) - complex_derivative f (Cx(&0)) * z`; + `\z. complex_derivative f z - complex_derivative f (Cx(&0))`; + `linepath(Cx(&0),z)`; `ball(Cx(&0),r)`] + PATH_INTEGRAL_PRIMITIVE) THEN + REWRITE_TAC[PATHSTART_LINEPATH; PATHFINISH_LINEPATH] THEN ANTS_TAC THENL + [REWRITE_TAC[VALID_PATH_LINEPATH; PATH_IMAGE_LINEPATH] THEN + ONCE_REWRITE_TAC[COMPLEX_RING + `a - complex_derivative f b = a - complex_derivative f b * Cx(&1)`] THEN + CONJ_TAC THENL + [X_GEN_TAC `x:complex` THEN STRIP_TAC THEN + MATCH_MP_TAC HAS_COMPLEX_DERIVATIVE_SUB THEN + SIMP_TAC[HAS_COMPLEX_DERIVATIVE_LMUL_WITHIN; + HAS_COMPLEX_DERIVATIVE_ID] THEN + MATCH_MP_TAC HAS_COMPLEX_DERIVATIVE_AT_WITHIN THEN + REWRITE_TAC[HAS_COMPLEX_DERIVATIVE_DIFFERENTIABLE] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [holomorphic_on]) THEN + DISCH_THEN(MP_TAC o SPEC `x:complex`) THEN + ASM_SIMP_TAC[REWRITE_RULE[SUBSET] BALL_SUBSET_CBALL] THEN + REWRITE_TAC[GSYM complex_differentiable] THEN + DISCH_THEN(MP_TAC o SPEC `ball(Cx(&0),r)` o + MATCH_MP (REWRITE_RULE[IMP_CONJ] + COMPLEX_DIFFERENTIABLE_WITHIN_SUBSET)) THEN + ASM_SIMP_TAC[COMPLEX_DIFFERENTIABLE_WITHIN_OPEN; OPEN_BALL] THEN + REWRITE_TAC[BALL_SUBSET_CBALL]; + MATCH_MP_TAC(REWRITE_RULE[CONVEX_CONTAINS_SEGMENT] CONVEX_BALL) THEN + ASM_REWRITE_TAC[CENTRE_IN_BALL]]; + ALL_TAC] THEN + SIMP_TAC[HAS_INTEGRAL_INTEGRABLE_INTEGRAL; HAS_PATH_INTEGRAL_LINEPATH] THEN + REWRITE_TAC[COMPLEX_SUB_RZERO; COMPLEX_MUL_RZERO] THEN + REWRITE_TAC[linepath; COMPLEX_CMUL; COMPLEX_MUL_RZERO; LIFT_DROP] THEN + REWRITE_TAC[COMPLEX_ADD_LID; FORALL_LIFT; IN_INTERVAL_1; LIFT_DROP] THEN + STRIP_TAC THEN FIRST_ASSUM(MP_TAC o + SPEC `\t. lift(norm(z:complex) pow 2 * drop t / (r - norm(z)) * C)` o + MATCH_MP (REWRITE_RULE[IMP_CONJ] INTEGRAL_NORM_BOUND_INTEGRAL)) THEN + REWRITE_TAC[linepath; COMPLEX_CMUL; COMPLEX_MUL_RZERO; LIFT_DROP] THEN + REWRITE_TAC[COMPLEX_ADD_LID; FORALL_LIFT; IN_INTERVAL_1; LIFT_DROP] THEN + REWRITE_TAC[REAL_ARITH `a * b / c * d:real = (a / c * d) * b`] THEN + REWRITE_TAC[LIFT_CMUL; LIFT_DROP; DROP_VEC] THEN + MP_TAC(ISPECL + [`\x. inv(&2) * x pow 2`; `\x:real. x`; `&0`; `&1`] + REAL_FUNDAMENTAL_THEOREM_OF_CALCULUS) THEN + REWRITE_TAC[REAL_POS] THEN ANTS_TAC THENL + [REPEAT STRIP_TAC THEN REAL_DIFF_TAC THEN CONV_TAC NUM_REDUCE_CONV THEN + REAL_ARITH_TAC; + REWRITE_TAC[has_real_integral; o_DEF; IMAGE_LIFT_REAL_INTERVAL] THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN REWRITE_TAC[LIFT_DROP; LIFT_NUM] THEN + DISCH_THEN(MP_TAC o SPEC `norm(z:complex) pow 2 / (r - norm z) * C` o + MATCH_MP HAS_INTEGRAL_CMUL) THEN + REWRITE_TAC[HAS_INTEGRAL_INTEGRABLE_INTEGRAL] THEN + STRIP_TAC THEN ASM_REWRITE_TAC[]] THEN + ANTS_TAC THENL + [X_GEN_TAC `t:real` THEN STRIP_TAC THEN + REWRITE_TAC[REAL_ARITH + `(z pow 2 / y * c) * t:real = (z / y * t * c) * z`] THEN + REWRITE_TAC[COMPLEX_NORM_MUL] THEN MATCH_MP_TAC REAL_LE_RMUL THEN + REWRITE_TAC[NORM_POS_LE] THEN + REMOVE_THEN "+" (MP_TAC o SPEC `Cx(t) * z`) THEN + REWRITE_TAC[IN_BALL; dist; COMPLEX_SUB_LZERO; NORM_NEG] THEN + SUBGOAL_THEN `norm(Cx t * z) <= norm z` ASSUME_TAC THENL + [GEN_REWRITE_TAC RAND_CONV [GSYM REAL_MUL_LID] THEN + REWRITE_TAC[COMPLEX_NORM_MUL] THEN MATCH_MP_TAC REAL_LE_RMUL THEN + REWRITE_TAC[NORM_POS_LE; COMPLEX_NORM_CX] THEN ASM_REAL_ARITH_TAC; + ALL_TAC] THEN + ANTS_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] REAL_LE_TRANS) THEN + ASM_SIMP_TAC[REAL_LE_RMUL_EQ; REAL_MUL_ASSOC; real_div] THEN + ASM_REWRITE_TAC[COMPLEX_NORM_MUL; COMPLEX_NORM_CX; real_abs] THEN + GEN_REWRITE_TAC LAND_CONV + [REAL_ARITH `(t * z) * w:real = (z * w) * t`] THEN + MATCH_MP_TAC REAL_LE_RMUL THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC REAL_LE_MUL2 THEN + REWRITE_TAC[NORM_POS_LE; REAL_LE_INV_EQ; REAL_SUB_LE] THEN + REWRITE_TAC[REAL_LE_REFL] THEN CONJ_TAC THENL + [ALL_TAC; MATCH_MP_TAC REAL_LE_INV2] THEN + ASM_REWRITE_TAC[REAL_SUB_LT] THEN FIRST_X_ASSUM(MP_TAC o + GEN_REWRITE_RULE LAND_CONV [COMPLEX_NORM_MUL]) THEN + REWRITE_TAC[COMPLEX_NORM_CX] THEN ASM_REAL_ARITH_TAC; + REWRITE_TAC[COMPLEX_SUB_RZERO]] THEN + MATCH_MP_TAC(NORM_ARITH + `abc <= norm d - e ==> norm(f - d) <= e ==> abc <= norm f`) THEN + REWRITE_TAC[REAL_SUB_RDISTRIB; + ONCE_REWRITE_RULE[COMPLEX_MUL_SYM] COMPLEX_NORM_MUL] THEN + MATCH_MP_TAC(REAL_ARITH `y <= x ==> a - x <= a - y`) THEN + REWRITE_TAC[DROP_CMUL; GSYM REAL_MUL_ASSOC; LIFT_DROP] THEN + MATCH_MP_TAC REAL_LE_LMUL THEN + ASM_SIMP_TAC[REAL_LE_DIV; REAL_SUB_LE; REAL_LT_IMP_LE; REAL_LE_POW_2] THEN + EXPAND_TAC "C" THEN REAL_ARITH_TAC; + ALL_TAC] THEN + MATCH_MP_TAC SUBSET_TRANS THEN + EXISTS_TAC `IMAGE (f:complex->complex) + (ball(Cx(&0),(&1 - sqrt(&2) / &2) * r))` THEN + SUBGOAL_THEN `&0 < &1 - sqrt(&2) / &2 /\ &1 - sqrt(&2) / &2 < &1` + STRIP_ASSUME_TAC THENL + [REWRITE_TAC[REAL_ARITH + `&0 < &1 - s / &2 /\ &1 - s / &2 < &1 <=> &0 < s /\ s < &2`] THEN + CONJ_TAC THENL + [MATCH_MP_TAC REAL_LT_RSQRT; MATCH_MP_TAC REAL_LT_LSQRT] THEN + REAL_ARITH_TAC; + ALL_TAC] THEN + CONJ_TAC THENL + [ALL_TAC; + MATCH_MP_TAC IMAGE_SUBSET THEN MATCH_MP_TAC SUBSET_BALL THEN + REWRITE_TAC[REAL_ARITH `x * r <= r <=> &0 <= r * (&1 - x)`] THEN + MATCH_MP_TAC REAL_LE_MUL THEN ASM_REAL_ARITH_TAC] THEN + FIRST_ASSUM(fun th -> + GEN_REWRITE_TAC (LAND_CONV o RAND_CONV o LAND_CONV) [SYM th]) THEN + MATCH_MP_TAC BALL_SUBSET_OPEN_MAP_IMAGE THEN + ASM_SIMP_TAC[REAL_LT_MUL; BOUNDED_BALL; CLOSURE_BALL; CENTRE_IN_BALL] THEN + REPEAT CONJ_TAC THENL + [MATCH_MP_TAC CONTINUOUS_ON_SUBSET THEN + EXISTS_TAC `cball(Cx(&0),r)` THEN + ASM_SIMP_TAC[HOLOMORPHIC_ON_IMP_CONTINUOUS_ON] THEN + MATCH_MP_TAC SUBSET_CBALL THEN + REWRITE_TAC[REAL_ARITH `x * r <= r <=> &0 <= r * (&1 - x)`] THEN + MATCH_MP_TAC REAL_LE_MUL THEN ASM_REAL_ARITH_TAC; + MATCH_MP_TAC(REWRITE_RULE[RIGHT_IMP_FORALL_THM; IMP_IMP] + OPEN_MAPPING_THM) THEN + EXISTS_TAC `ball(Cx(&0),r)` THEN + ASM_SIMP_TAC[OPEN_BALL; CONNECTED_BALL; INTERIOR_OPEN; SUBSET_REFL] THEN + REPEAT CONJ_TAC THENL + [ASM_MESON_TAC[HOLOMORPHIC_ON_SUBSET; BALL_SUBSET_CBALL]; + ALL_TAC; + MATCH_MP_TAC SUBSET_BALL THEN + REWRITE_TAC[REAL_ARITH `x * r <= r <=> &0 <= r * (&1 - x)`] THEN + MATCH_MP_TAC REAL_LE_MUL THEN ASM_REAL_ARITH_TAC] THEN + DISCH_THEN(X_CHOOSE_TAC `y:complex`) THEN + MP_TAC(ISPECL + [`f:complex->complex`; `(\x. y):complex->complex`; + `ball(Cx(&0),r)`; `Cx(&0)`] + COMPLEX_DERIVATIVE_TRANSFORM_WITHIN_OPEN) THEN + ASM_REWRITE_TAC[OPEN_BALL; HOLOMORPHIC_ON_CONST; COMPLEX_DERIVATIVE_CONST; + CENTRE_IN_BALL] THEN + ASM_MESON_TAC[HOLOMORPHIC_ON_SUBSET; BALL_SUBSET_CBALL]; + REPEAT(MATCH_MP_TAC REAL_LT_MUL THEN CONJ_TAC) THEN + ASM_REWRITE_TAC[REAL_ARITH `&0 < &3 - &2 * s <=> s < &3 / &2`] THEN + ASM_REAL_ARITH_TAC; + ALL_TAC] THEN + ASM_SIMP_TAC[FRONTIER_BALL; sphere; REAL_LT_MUL; dist; IN_ELIM_THM] THEN + X_GEN_TAC `z:complex` THEN REWRITE_TAC[COMPLEX_SUB_LZERO; NORM_NEG] THEN + DISCH_TAC THEN REMOVE_THEN "*" (MP_TAC o SPEC `z:complex`) THEN + ASM_REWRITE_TAC[IN_BALL; dist; COMPLEX_SUB_LZERO; COMPLEX_SUB_RZERO] THEN + ASM_REWRITE_TAC[NORM_NEG] THEN ANTS_TAC THENL + [REWRITE_TAC[REAL_ARITH `x * r < r <=> &0 < r * (&1 - x)`] THEN + MATCH_MP_TAC REAL_LT_MUL THEN ASM_REAL_ARITH_TAC; + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] REAL_LE_TRANS)] THEN + REWRITE_TAC[REAL_MUL_ASSOC] THEN MATCH_MP_TAC REAL_LE_RMUL THEN + REWRITE_TAC[NORM_POS_LE; REAL_ARITH `r - (&1 - s) * r = s * r`] THEN + REWRITE_TAC[real_div; REAL_INV_MUL; REAL_INV_INV] THEN + ASM_SIMP_TAC[REAL_LE_RMUL_EQ; REAL_FIELD + `&0 < r + ==> a * r - (b * r) pow 2 * x * inv r = (a - b pow 2 * x) * r`] THEN + MATCH_MP_TAC REAL_EQ_IMP_LE THEN + MP_TAC(SPEC `&2` SQRT_WORKS) THEN CONV_TAC REAL_FIELD);; + +let BLOCH_UNIT = prove + (`!f a. f holomorphic_on ball(a,&1) /\ + complex_derivative f a = Cx(&1) + ==> ?b r. &1 / &12 < r /\ ball(b,r) SUBSET IMAGE f (ball(a,&1))`, + REPEAT STRIP_TAC THEN ABBREV_TAC `r = &249 / &256` THEN + SUBGOAL_THEN `&0 < r` ASSUME_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN + ABBREV_TAC `g = \z. complex_derivative f z * Cx(r - norm(z - a))` THEN + MP_TAC(ISPECL [`IMAGE (g:complex->complex) (cball(a,r))`; `Cx(&0)`] + DISTANCE_ATTAINS_SUP) THEN + ANTS_TAC THENL + [ASM_REWRITE_TAC[IMAGE_EQ_EMPTY; CBALL_EQ_EMPTY] THEN + CONJ_TAC THENL [ALL_TAC; ASM_REAL_ARITH_TAC] THEN + MATCH_MP_TAC COMPACT_CONTINUOUS_IMAGE THEN REWRITE_TAC[COMPACT_CBALL] THEN + MATCH_MP_TAC CONTINUOUS_ON_SUBSET THEN EXISTS_TAC `ball(a:complex,&1)` THEN + REWRITE_TAC[SUBSET_BALLS; DIST_REFL] THEN + CONJ_TAC THENL [ALL_TAC; ASM_REAL_ARITH_TAC] THEN EXPAND_TAC "g" THEN + MATCH_MP_TAC CONTINUOUS_ON_COMPLEX_MUL THEN CONJ_TAC THENL + [MATCH_MP_TAC HOLOMORPHIC_ON_IMP_CONTINUOUS_ON THEN + ASM_SIMP_TAC[HOLOMORPHIC_COMPLEX_DERIVATIVE; ETA_AX; OPEN_BALL]; + REWRITE_TAC[CONTINUOUS_ON_CX_LIFT; LIFT_SUB] THEN + MATCH_MP_TAC CONTINUOUS_ON_SUB THEN REWRITE_TAC[CONTINUOUS_ON_CONST] THEN + MATCH_MP_TAC CONTINUOUS_ON_LIFT_NORM_COMPOSE THEN + SIMP_TAC[CONTINUOUS_ON_SUB; CONTINUOUS_ON_ID; CONTINUOUS_ON_CONST]]; + REWRITE_TAC[EXISTS_IN_IMAGE; FORALL_IN_IMAGE; IN_CBALL] THEN + REWRITE_TAC[NORM_ARITH `dist(a,b) = norm(b - a)`] THEN + REWRITE_TAC[COMPLEX_SUB_RZERO] THEN + DISCH_THEN(X_CHOOSE_THEN `p:complex` STRIP_ASSUME_TAC)] THEN + SUBGOAL_THEN `norm(p - a:complex) < r` ASSUME_TAC THENL + [ASM_REWRITE_TAC[REAL_LT_LE] THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `a:complex`) THEN + ASM_SIMP_TAC[COMPLEX_SUB_REFL; COMPLEX_NORM_0; REAL_LT_IMP_LE] THEN + EXPAND_TAC "g" THEN REWRITE_TAC[COMPLEX_NORM_MUL] THEN + ASM_REWRITE_TAC[REAL_SUB_REFL; COMPLEX_SUB_RZERO; COMPLEX_NORM_CX] THEN + REWRITE_TAC[COMPLEX_SUB_REFL; COMPLEX_NORM_0] THEN ASM_REAL_ARITH_TAC; + ALL_TAC] THEN + ABBREV_TAC `t = (r - norm(p - a:complex)) / &2` THEN + SUBGOAL_THEN `&0 < t` ASSUME_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN + EXISTS_TAC `(f:complex->complex) p` THEN + EXISTS_TAC `(&3 - &2 * sqrt (&2)) * t * norm (complex_derivative f p)` THEN + MP_TAC(ISPECL [`f:complex->complex`; `p:complex`; `t:real`] + BLOCH_LEMMA) THEN + ASM_REWRITE_TAC[] THEN ANTS_TAC THENL + [CONJ_TAC THENL + [FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + HOLOMORPHIC_ON_SUBSET)) THEN + REWRITE_TAC[SUBSET_BALLS; dist; COMPLEX_SUB_RZERO] THEN + ASM_REAL_ARITH_TAC; + X_GEN_TAC `z:complex` THEN REWRITE_TAC[IN_BALL] THEN DISCH_TAC THEN + SUBGOAL_THEN `norm(z - a:complex) < r` ASSUME_TAC THENL + [REPEAT(POP_ASSUM MP_TAC) THEN NORM_ARITH_TAC; ALL_TAC] THEN + FIRST_X_ASSUM(MP_TAC o SPEC `z:complex`) THEN + ASM_SIMP_TAC[REAL_LT_IMP_LE] THEN EXPAND_TAC "g" THEN + REWRITE_TAC[COMPLEX_NORM_MUL] THEN + ASM_SIMP_TAC[COMPLEX_NORM_CX; GSYM REAL_LE_RDIV_EQ; + REAL_ARITH `z < r ==> &0 < abs(r - z)`] THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] REAL_LE_TRANS) THEN + GEN_REWRITE_TAC RAND_CONV [REAL_MUL_SYM] THEN + REWRITE_TAC[real_div; GSYM REAL_MUL_ASSOC] THEN + MATCH_MP_TAC REAL_LE_LMUL THEN REWRITE_TAC[NORM_POS_LE] THEN + ASM_SIMP_TAC[GSYM real_div; REAL_LE_LDIV_EQ; REAL_ARITH + `z < r ==> &0 < abs(r - z)`] THEN + REPEAT(POP_ASSUM MP_TAC) THEN NORM_ARITH_TAC]; + DISCH_TAC THEN CONJ_TAC THENL + [FIRST_X_ASSUM(MP_TAC o SPEC `a:complex`) THEN + ASM_SIMP_TAC[COMPLEX_SUB_REFL; COMPLEX_NORM_0; REAL_LT_IMP_LE] THEN + EXPAND_TAC "g" THEN REWRITE_TAC[COMPLEX_NORM_MUL] THEN + ASM_REWRITE_TAC[COMPLEX_NORM_CX; REAL_ABS_NUM; REAL_MUL_LID] THEN + ASM_SIMP_TAC[REAL_SUB_RZERO; real_abs; REAL_SUB_LE; REAL_LT_IMP_LE; + COMPLEX_SUB_REFL; COMPLEX_NORM_0] THEN + EXPAND_TAC "t" THEN + REWRITE_TAC[REAL_ARITH + `a < b * c / &2 * d <=> a < (d * c) * (b / &2)`] THEN + SUBGOAL_THEN `sqrt (&2) < &2113 / &1494` ASSUME_TAC THENL + [MATCH_MP_TAC REAL_LT_LSQRT THEN CONV_TAC REAL_RAT_REDUCE_CONV; + ALL_TAC] THEN + SUBGOAL_THEN `&0 < &3 - &2 * sqrt(&2)` ASSUME_TAC THENL + [ASM_REAL_ARITH_TAC; ALL_TAC] THEN + ASM_SIMP_TAC[GSYM REAL_LT_LDIV_EQ; REAL_HALF] THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] REAL_LTE_TRANS) THEN + ASM_SIMP_TAC[REAL_LT_LDIV_EQ; REAL_HALF] THEN + EXPAND_TAC "r" THEN ASM_REAL_ARITH_TAC; + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + SUBSET_TRANS)) THEN + MATCH_MP_TAC IMAGE_SUBSET THEN + REWRITE_TAC[SUBSET_BALLS; dist; COMPLEX_SUB_RZERO] THEN + REPEAT(POP_ASSUM MP_TAC) THEN NORM_ARITH_TAC]]);; + +let BLOCH = prove + (`!f a r r'. + &0 < r /\ f holomorphic_on ball(a,r) /\ + r' <= r * norm(complex_derivative f a) / &12 + ==> ?b. ball(b,r') SUBSET IMAGE f (ball(a,r))`, + REPEAT GEN_TAC THEN + ASM_CASES_TAC `complex_derivative f a = Cx(&0)` THENL + [ASM_SIMP_TAC[COMPLEX_NORM_0; real_div; REAL_MUL_RZERO; REAL_MUL_LZERO; + BALL_EMPTY; EMPTY_SUBSET]; + ALL_TAC] THEN + ABBREV_TAC `C = complex_derivative f a` THEN + SUBGOAL_THEN `&0 < norm(C:complex)` ASSUME_TAC THENL + [ASM_MESON_TAC[COMPLEX_NORM_NZ]; STRIP_TAC] THEN + MP_TAC(ISPECL + [`\z. (f:complex->complex)(a + Cx r * z) / (C * Cx r)`; `Cx(&0)`] + BLOCH_UNIT) THEN + SUBGOAL_THEN + `!z. z IN ball(Cx(&0),&1) + ==> ((\z. f (a + Cx r * z) / (C * Cx r)) has_complex_derivative + (complex_derivative f (a + Cx r * z) / C)) (at z)` + ASSUME_TAC THENL + [REWRITE_TAC[COMPLEX_IN_BALL_0] THEN REPEAT STRIP_TAC THEN + SUBGOAL_THEN + `complex_derivative f (a + Cx r * z) / C = + (complex_derivative f (a + Cx r * z) * Cx r) / (C * Cx r)` + SUBST1_TAC THENL + [ASM_SIMP_TAC[CX_INJ; REAL_LT_IMP_NZ; COMPLEX_FIELD + `~(r = Cx(&0)) /\ ~(c = Cx(&0)) ==> (d * r) / (c * r) = d / c`]; + ALL_TAC] THEN + MATCH_MP_TAC HAS_COMPLEX_DERIVATIVE_CDIV_AT THEN + GEN_REWRITE_TAC (RATOR_CONV o LAND_CONV) [GSYM o_DEF] THEN + MATCH_MP_TAC COMPLEX_DIFF_CHAIN_AT THEN CONJ_TAC THENL + [COMPLEX_DIFF_TAC THEN CONV_TAC COMPLEX_RING; ALL_TAC] THEN + REWRITE_TAC[HAS_COMPLEX_DERIVATIVE_DIFFERENTIABLE] THEN + FIRST_ASSUM(MATCH_MP_TAC o + MATCH_MP (ONCE_REWRITE_RULE[IMP_CONJ] + HOLOMORPHIC_ON_IMP_DIFFERENTIABLE_AT)) THEN + REWRITE_TAC[OPEN_BALL; IN_BALL; NORM_ARITH `dist(a,a + b) = norm b`] THEN + REWRITE_TAC[COMPLEX_NORM_MUL; COMPLEX_NORM_CX] THEN + ASM_SIMP_TAC[REAL_ARITH `&0 < r ==> (abs r * z < r <=> &0 < r * (&1 - z))`; + REAL_LT_MUL; REAL_SUB_LT]; + ALL_TAC] THEN + ANTS_TAC THENL + [SIMP_TAC[HOLOMORPHIC_ON_OPEN; OPEN_BALL] THEN + CONJ_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN + FIRST_X_ASSUM(MP_TAC o SPEC `Cx(&0)`) THEN + ASM_REWRITE_TAC[CENTRE_IN_BALL; REAL_LT_01] THEN + DISCH_THEN(SUBST1_TAC o MATCH_MP HAS_COMPLEX_DERIVATIVE_DERIVATIVE) THEN + ASM_SIMP_TAC[COMPLEX_MUL_RZERO; COMPLEX_ADD_RID; COMPLEX_DIV_REFL]; + ALL_TAC] THEN + REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`b:complex`; `t:real`] THEN STRIP_TAC THEN + EXISTS_TAC `(C * Cx r) * b` THEN + FIRST_ASSUM(MP_TAC o ISPEC `\z. (C * Cx r) * z` o MATCH_MP IMAGE_SUBSET) THEN + REWRITE_TAC[GSYM IMAGE_o; o_DEF] THEN + ASM_SIMP_TAC[COMPLEX_DIV_LMUL; COMPLEX_ENTIRE; CX_INJ; REAL_LT_IMP_NZ] THEN + GEN_REWRITE_TAC (LAND_CONV o RAND_CONV o LAND_CONV) [GSYM o_DEF] THEN + REWRITE_TAC[IMAGE_o] THEN MATCH_MP_TAC(SET_RULE + `v SUBSET s /\ t SUBSET w + ==> s SUBSET IMAGE f t ==> v SUBSET IMAGE f w`) THEN + CONJ_TAC THENL + [REWRITE_TAC[SUBSET; IN_IMAGE; IN_BALL; dist] THEN + X_GEN_TAC `x:complex` THEN DISCH_TAC THEN + EXISTS_TAC `x / (C * Cx r)` THEN + ASM_SIMP_TAC[COMPLEX_DIV_LMUL; COMPLEX_ENTIRE; CX_INJ; REAL_LT_IMP_NZ] THEN + MATCH_MP_TAC REAL_LT_LCANCEL_IMP THEN EXISTS_TAC `norm(C * Cx r)` THEN + ASM_SIMP_TAC[COMPLEX_NORM_NZ; COMPLEX_ENTIRE; CX_INJ; REAL_LT_IMP_NZ] THEN + REWRITE_TAC[GSYM COMPLEX_NORM_MUL; COMPLEX_SUB_LDISTRIB] THEN + ASM_SIMP_TAC[COMPLEX_DIV_LMUL; COMPLEX_ENTIRE; CX_INJ; REAL_LT_IMP_NZ] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + REAL_LTE_TRANS)) THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + REAL_LE_TRANS)) THEN + REWRITE_TAC[COMPLEX_NORM_MUL; COMPLEX_NORM_CX] THEN + ASM_SIMP_TAC[REAL_ARITH `&0 < r ==> a * abs r = r * a`] THEN + ASM_REWRITE_TAC[real_div; GSYM REAL_MUL_ASSOC] THEN + ASM_SIMP_TAC[REAL_LE_LMUL_EQ; COMPLEX_NORM_NZ] THEN ASM_REAL_ARITH_TAC; + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; COMPLEX_IN_BALL_0] THEN + REWRITE_TAC[OPEN_BALL; IN_BALL; NORM_ARITH `dist(a,a + b) = norm b`] THEN + REWRITE_TAC[COMPLEX_NORM_MUL; COMPLEX_NORM_CX] THEN + ASM_SIMP_TAC[REAL_ARITH `&0 < r ==> (abs r * z < r <=> &0 < r * (&1 - z))`; + REAL_LT_MUL; REAL_SUB_LT]]);; + +let BLOCH_COROLLARY = prove + (`!f s a t r. + f holomorphic_on s /\ a IN s /\ + (!z. z IN frontier s ==> t <= dist(a,z)) /\ + r <= t * norm(complex_derivative f a) / &12 + ==> ?b. ball(b,r) SUBSET IMAGE f s`, + REPEAT STRIP_TAC THEN FIRST_ASSUM(DISJ_CASES_THEN MP_TAC o + MATCH_MP (REAL_ARITH `r <= t ==> r <= &0 \/ &0 < t`)) THEN + SIMP_TAC[BALL_EMPTY; EMPTY_SUBSET] THEN + ASM_CASES_TAC `complex_derivative f a = Cx(&0)` THEN + ASM_REWRITE_TAC[COMPLEX_NORM_0] THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN + ASM_SIMP_TAC[REAL_LT_MUL_EQ; REAL_ARITH `&0 < x / &12 <=> &0 < x`; + COMPLEX_NORM_NZ] THEN + DISCH_TAC THEN + SUBGOAL_THEN `ball(a:complex,t) SUBSET s` ASSUME_TAC THENL + [MP_TAC(ISPECL [`ball(a:complex,t)`; `s:complex->bool`] + CONNECTED_INTER_FRONTIER) THEN + REWRITE_TAC[CONNECTED_BALL; SET_RULE `s DIFF t = {} <=> s SUBSET t`] THEN + MATCH_MP_TAC(TAUT `~p /\ r ==> (~p /\ ~q ==> ~r) ==> q`) THEN + CONJ_TAC THENL + [REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN EXISTS_TAC `a:complex` THEN + + ASM_REWRITE_TAC[IN_INTER; CENTRE_IN_BALL]; + REWRITE_TAC[EXTENSION; NOT_IN_EMPTY; IN_INTER; IN_BALL] THEN + ASM_MESON_TAC[REAL_NOT_LE]]; + ALL_TAC] THEN + MP_TAC(ISPECL + [`f:complex->complex`; `a:complex`; `t:real`; `r:real`] BLOCH) THEN + ASM_REWRITE_TAC[] THEN + ANTS_TAC THENL [ASM_MESON_TAC[HOLOMORPHIC_ON_SUBSET]; ALL_TAC] THEN + MATCH_MP_TAC MONO_EXISTS THEN ASM SET_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* Schottky's theorem. *) +(* ------------------------------------------------------------------------- *) + +let SCHOTTKY = prove + (`!f r. f holomorphic_on cball(Cx(&0),&1) /\ norm(f(Cx(&0))) <= r /\ + (!z. z IN cball(Cx(&0),&1) ==> ~(f z = Cx(&0) \/ f z = Cx(&1))) + ==> !t z. &0 < t /\ t < &1 /\ norm(z) <= t + ==> norm(f z) + <= exp(pi * exp(pi * + (&2 + &2 * r + &12 * t / (&1 - t))))`, + let lemma0 = prove + (`!f s a. + f holomorphic_on s /\ + contractible s /\ + a IN s /\ + (!z. z IN s ==> ~(f z = Cx (&1)) /\ ~(f z = --Cx (&1))) + ==> (?g. g holomorphic_on s /\ + norm(g a) <= &1 + norm(f a) / &3 /\ + (!z. z IN s ==> f z = ccos(Cx pi * g z)))`, + REPEAT GEN_TAC THEN + DISCH_THEN(X_CHOOSE_THEN `g:complex->complex` STRIP_ASSUME_TAC o MATCH_MP + CONTRACTIBLE_IMP_HOLOMORPHIC_ACS_BOUNDED) THEN + EXISTS_TAC `\z:complex. g z / Cx pi` THEN + ASM_SIMP_TAC[COMPLEX_DIV_LMUL; CX_INJ; PI_NZ; COMPLEX_NORM_DIV; + HOLOMORPHIC_ON_DIV; HOLOMORPHIC_ON_CONST; REAL_LE_LDIV_EQ; + COMPLEX_NORM_CX; REAL_ABS_PI; PI_POS] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH + `x <= pi + a ==> a * &3 <= n * pi ==> x <= (&1 + n / &3) * pi`)) THEN + MATCH_MP_TAC REAL_LE_LMUL THEN REWRITE_TAC[NORM_POS_LE] THEN + MP_TAC PI_APPROX_32 THEN REAL_ARITH_TAC) in + let lemma1 = prove + (`!n. 0 < n ==> &0 < &n + sqrt(&n pow 2 - &1)`, + MESON_TAC[REAL_LTE_ADD; REAL_OF_NUM_LT; SQRT_POS_LE; REAL_POW_LE_1; + REAL_SUB_LE; REAL_OF_NUM_LE; LE_1]) in + let lemma2 = prove + (`!x. &0 <= x + ==> ?n. 0 < n /\ + abs(x - log(&n + sqrt(&n pow 2 - &1)) / pi) < &1 / &2`, + REPEAT STRIP_TAC THEN MP_TAC(SPEC + `\n. 0 < n /\ log(&n + sqrt(&n pow 2 - &1)) / pi <= x` num_MAX) THEN + SIMP_TAC[] THEN + MATCH_MP_TAC(TAUT `p /\ (q ==> r) ==> (p <=> q) ==> r`) THEN + REPEAT CONJ_TAC THENL + [EXISTS_TAC `1` THEN CONV_TAC REAL_RAT_REDUCE_CONV THEN + ASM_REWRITE_TAC[ARITH; SQRT_0; REAL_ADD_RID; LOG_1] THEN + REWRITE_TAC[real_div; REAL_MUL_LZERO] THEN ASM_REAL_ARITH_TAC; + MP_TAC(ISPEC `exp(x * pi)` REAL_ARCH_SIMPLE) THEN + MATCH_MP_TAC MONO_EXISTS THEN + X_GEN_TAC `n:num` THEN DISCH_TAC THEN X_GEN_TAC `m:num` THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + SIMP_TAC[REAL_LE_LDIV_EQ; PI_POS] THEN + GEN_REWRITE_TAC LAND_CONV [GSYM REAL_EXP_MONO_LE] THEN + ASM_SIMP_TAC[lemma1; EXP_LOG] THEN + REWRITE_TAC[GSYM REAL_OF_NUM_LE] THEN MATCH_MP_TAC(REAL_ARITH + `e <= n /\ &0 <= x ==> m + x <= e ==> m <= n`) THEN + ASM_SIMP_TAC[SQRT_POS_LE; REAL_POW_LE_1; REAL_SUB_LE; + REAL_OF_NUM_LE; LE_1]; + DISCH_THEN(X_CHOOSE_THEN `n:num` + (CONJUNCTS_THEN2 (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) + (MP_TAC o SPEC `n + 1`))) THEN + REWRITE_TAC[ARITH_RULE `~(n + 1 <= n) /\ 0 < n + 1`] THEN + REWRITE_TAC[REAL_NOT_LE; IMP_IMP] THEN + DISCH_THEN(MP_TAC o MATCH_MP (REAL_ARITH + `x < b /\ a <= x ==> b - a < &1 + ==> abs(x - a) < &1 / &2 \/ abs(x - b) < &1 / &2`)) THEN + ANTS_TAC THENL [ALL_TAC; ASM_MESON_TAC[ARITH_RULE `0 < n + 1`]] THEN + REWRITE_TAC[REAL_ARITH `x / pi - y / pi = (x - y) / pi`] THEN + SIMP_TAC[PI_POS; REAL_LT_LDIV_EQ; REAL_MUL_LID] THEN + MATCH_MP_TAC REAL_LET_TRANS THEN EXISTS_TAC `&3` THEN + CONJ_TAC THENL [ALL_TAC; MP_TAC PI_APPROX_32 THEN REAL_ARITH_TAC] THEN + ASM_SIMP_TAC[lemma1; GSYM LOG_DIV; ARITH_RULE `0 < n + 1`] THEN + FIRST_ASSUM(DISJ_CASES_TAC o MATCH_MP (ARITH_RULE + `0 < n ==> n = 1 \/ 2 <= n`)) + THENL + [ASM_REWRITE_TAC[] THEN CONV_TAC NUM_REDUCE_CONV THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN + REWRITE_TAC[SQRT_0; REAL_ADD_RID; REAL_DIV_1] THEN + ONCE_REWRITE_TAC[GSYM REAL_EXP_MONO_LE] THEN + SIMP_TAC[EXP_LOG; REAL_LTE_ADD; SQRT_POS_LE; REAL_POS; REAL_OF_NUM_LT; + ARITH] THEN + MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC `&1 + &3` THEN + SIMP_TAC[REAL_EXP_LE_X; REAL_POS] THEN + REWRITE_TAC[REAL_ARITH `&2 + s <= a <=> s <= a - &2`] THEN + MATCH_MP_TAC REAL_LE_LSQRT THEN CONV_TAC REAL_RAT_REDUCE_CONV; + MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC `log(&2)` THEN + CONJ_TAC THENL + [MATCH_MP_TAC LOG_MONO_LE_IMP THEN + ASM_SIMP_TAC[lemma1; ARITH_RULE `0 < n + 1`; REAL_LT_DIV; + REAL_LE_LDIV_EQ] THEN + REWRITE_TAC[GSYM REAL_OF_NUM_ADD] THEN MATCH_MP_TAC(REAL_ARITH + `&1 <= n /\ s <= &2 * t ==> (n + &1) + s <= &2 * (n + t)`) THEN + ASM_SIMP_TAC[REAL_OF_NUM_LE; LE_1] THEN + MATCH_MP_TAC REAL_LE_LSQRT THEN + ASM_SIMP_TAC[REAL_SUB_LE; REAL_POW_LE_1; REAL_ARITH `&1 <= &n + &1`; + REAL_ARITH `&0 <= &2 * x <=> &0 <= x`; REAL_POW_MUL; SQRT_POW_2; + REAL_LE_MUL; REAL_POS; SQRT_POS_LE; REAL_OF_NUM_LE; LE_1] THEN + MATCH_MP_TAC(REAL_ARITH + `&2 <= n /\ &2 * n <= n * n + ==> (n + &1) pow 2 - &1 <= &2 pow 2 * (n pow 2 - &1)`) THEN + ASM_SIMP_TAC[REAL_LE_RMUL; REAL_OF_NUM_LE; LE_0]; + ONCE_REWRITE_TAC[GSYM REAL_EXP_MONO_LE] THEN + SIMP_TAC[EXP_LOG; REAL_OF_NUM_LT; ARITH] THEN + MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC `&1 + &3` THEN + SIMP_TAC[REAL_EXP_LE_X; REAL_POS] THEN REAL_ARITH_TAC]]]) in + let lemma3 = prove + (`!z. + z IN + ({complex(m,log(&n + sqrt(&n pow 2 - &1)) / pi) | integer m /\ 0 < n} + UNION + {complex(m,--log(&n + sqrt(&n pow 2 - &1)) / pi) | integer m /\ 0 < n}) + ==> ccos(Cx(pi) * ccos(Cx pi * z)) = Cx(&1) \/ + ccos(Cx(pi) * ccos(Cx pi * z)) = --Cx(&1)`, + REWRITE_TAC[COMPLEX_RING + `x = Cx(&1) \/ x = --Cx(&1) <=> Cx(&1) - x pow 2 = Cx(&0)`] THEN + REWRITE_TAC[COMPLEX_POW_EQ_0; ARITH_EQ; CSIN_EQ_0; + REWRITE_RULE[COMPLEX_RING + `s pow 2 + c pow 2 = Cx(&1) <=> + Cx(&1) - c pow 2 = s pow 2`] CSIN_CIRCLE] THEN + ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN REWRITE_TAC[CX_MUL] THEN + REWRITE_TAC[COMPLEX_EQ_MUL_LCANCEL; CX_INJ; PI_NZ] THEN + REWRITE_TAC[IN_UNION; TAUT `p \/ q ==> r <=> (p ==> r) /\ (q ==> r)`] THEN + REWRITE_TAC[FORALL_AND_THM; FORALL_IN_GSPEC] THEN + REWRITE_TAC[complex_mul; RE; IM; RE_CX; IM_CX; REAL_MUL_LZERO] THEN + ASM_SIMP_TAC[REAL_DIV_LMUL; PI_NZ; REAL_ADD_RID; REAL_SUB_RZERO] THEN + ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN + REWRITE_TAC[ccos; COMPLEX_MUL_LNEG; CEXP_NEG] THEN CONJ_TAC THENL + [ASM_SIMP_TAC[CEXP_NZ; COMPLEX_FIELD + `~(e = Cx(&0)) + ==> ((e + inv e) / Cx(&2) = n <=> + inv e pow 2 - Cx(&2) * n * inv e + Cx(&1) = Cx(&0))`]; + ASM_SIMP_TAC[CEXP_NZ; COMPLEX_FIELD + `~(e = Cx(&0)) + ==> ((e + inv e) / Cx(&2) = n <=> + e pow 2 - Cx(&2) * n * e + Cx(&1) = Cx(&0))`]] THEN + SIMP_TAC[COMPLEX_TRAD; COMPLEX_RING + `ii * (a + ii * b) = --b + ii * a`] THEN + REWRITE_TAC[GSYM COMPLEX_TRAD; GSYM CX_NEG; CEXP_COMPLEX] THEN + SIMP_TAC[REAL_EXP_NEG; EXP_LOG; lemma1] THEN + SIMP_TAC[SIN_INTEGER_PI; REAL_INV_INV] THEN + REWRITE_TAC[COMPLEX_TRAD; COMPLEX_MUL_RZERO; COMPLEX_ADD_RID] THEN + REWRITE_TAC[GSYM CX_POW; GSYM CX_MUL; GSYM CX_ADD; GSYM CX_ADD; + GSYM CX_SUB; GSYM CX_INV; CX_INJ] THEN + REWRITE_TAC[REAL_INV_MUL; REAL_INV_INV; REAL_POW_MUL] THEN + ONCE_REWRITE_TAC[GSYM COS_ABS] THEN REWRITE_TAC[REAL_ABS_MUL] THEN + MAP_EVERY X_GEN_TAC [`i:real`; `n:num`] THEN REWRITE_TAC[integer] THEN + DISCH_THEN(CONJUNCTS_THEN2 + (X_CHOOSE_THEN `m:num` SUBST_ALL_TAC) ASSUME_TAC) THEN + REWRITE_TAC[GSYM integer] THEN REWRITE_TAC[real_abs; PI_POS_LE] THEN + REWRITE_TAC[COS_NPI; REAL_POW_INV; REAL_POW_POW] THEN + REWRITE_TAC[REAL_POW_NEG; EVEN_MULT; ARITH; REAL_POW_ONE] THEN + (ASM_CASES_TAC `EVEN m` THEN + ASM_REWRITE_TAC[REAL_INV_NEG; REAL_INV_1; REAL_MUL_RID] THEN + REWRITE_TAC[REAL_ARITH `a - &2 * n * x * --(&1) = a - &2 * --n * x`] THENL + [EXISTS_TAC `&n:real`; EXISTS_TAC `--(&n):real`] THEN + REWRITE_TAC[REAL_NEG_NEG; REAL_RING + `(n + s) pow 2 - &2 * n * (n + s) + &1 = &0 <=> + s pow 2 = n pow 2 - &1`] THEN + SIMP_TAC[INTEGER_CLOSED] THEN MATCH_MP_TAC SQRT_POW_2 THEN + ASM_SIMP_TAC[REAL_SUB_LE; REAL_POW_LE_1; REAL_OF_NUM_LE; LE_1])) in + REPEAT GEN_TAC THEN STRIP_TAC THEN + MP_TAC(ISPECL + [`\z:complex. Cx(&2) * f z - Cx(&1)`; `cball(Cx(&0),&1)`; `Cx(&0)`] + lemma0) THEN + ASM_SIMP_TAC[HOLOMORPHIC_ON_SUB; HOLOMORPHIC_ON_MUL; + HOLOMORPHIC_ON_CONST; CENTRE_IN_CBALL; REAL_POS; + COMPLEX_RING `Cx(&2) * z - Cx(&1) = Cx(&1) <=> z = Cx(&1)`; + COMPLEX_RING `Cx(&2) * z - Cx(&1) = --Cx(&1) <=> z = Cx(&0)`; + CONVEX_IMP_CONTRACTIBLE; CONVEX_CBALL] THEN + ANTS_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN + DISCH_THEN(X_CHOOSE_THEN `h:complex->complex` STRIP_ASSUME_TAC) THEN + MP_TAC(ISPECL + [`h:complex->complex`; `cball(Cx(&0),&1)`; `Cx(&0)`] + lemma0) THEN + ASM_SIMP_TAC[CENTRE_IN_CBALL; REAL_POS; CONVEX_IMP_CONTRACTIBLE; + CONVEX_CBALL] THEN + ANTS_TAC THENL + [X_GEN_TAC `z:complex` THEN REPEAT STRIP_TAC THEN + REPEAT(FIRST_X_ASSUM(MP_TAC o SPEC `z:complex`)) THEN + ASM_REWRITE_TAC[COMPLEX_MUL_RID; COMPLEX_MUL_RNEG; CCOS_NEG; + GSYM CX_COS; COS_PI; CX_NEG] THEN + CONV_TAC COMPLEX_RING; + DISCH_THEN(X_CHOOSE_THEN `g:complex->complex` STRIP_ASSUME_TAC)] THEN + MAP_EVERY UNDISCH_TAC + [`!z. z IN cball (Cx (&0),&1) + ==> Cx(&2) * f z - Cx(&1) = ccos(Cx pi * h z)`; + `!z. z IN cball(Cx(&0),&1) ==> h z = ccos(Cx pi * g z)`] THEN + SIMP_TAC[] THEN DISCH_THEN(K ALL_TAC) THEN DISCH_TAC THEN + SUBGOAL_THEN + `norm(g(Cx(&0)):complex) <= &2 + norm(f(Cx(&0)):complex)` + ASSUME_TAC THENL + [FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + REAL_LE_TRANS)) THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH + `h <= p ==> p / &3 <= &1 + f ==> &1 + h / &3 <= &2 + f`)) THEN + MP_TAC(ISPEC `&1` COMPLEX_NORM_CX) THEN + REWRITE_TAC[GSYM COMPLEX_CMUL] THEN CONV_TAC NORM_ARITH; + MAP_EVERY (C UNDISCH_THEN (K ALL_TAC)) + [`h holomorphic_on cball(Cx (&0),&1)`; + `norm(g(Cx(&0)):complex) <= &1 + norm(h(Cx(&0)):complex) / &3`; + `norm(h(Cx(&0)):complex) <= + &1 + norm(Cx(&2) * f(Cx(&0)) - Cx(&1)) / &3`]] THEN + MAP_EVERY X_GEN_TAC [`t:real`; `z:complex`] THEN STRIP_TAC THEN + SUBGOAL_THEN `z IN ball(Cx(&0),&1)` ASSUME_TAC THENL + [REWRITE_TAC[COMPLEX_IN_BALL_0] THEN ASM_REAL_ARITH_TAC; + FIRST_ASSUM(ASSUME_TAC o MATCH_MP + (REWRITE_RULE[SUBSET] BALL_SUBSET_CBALL))] THEN + SUBGOAL_THEN + `norm(g(z) - g(Cx(&0))) <= &12 * t / (&1 - t)` + ASSUME_TAC THENL + [FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [holomorphic_on]) THEN + REWRITE_TAC[RIGHT_IMP_EXISTS_THM; SKOLEM_THM] THEN + DISCH_THEN(X_CHOOSE_TAC `g':complex->complex`) THEN + MP_TAC(ISPECL [`g:complex->complex`; `g':complex->complex`; + `linepath(Cx(&0),z)`; `cball(Cx(&0),&1)`] + PATH_INTEGRAL_PRIMITIVE) THEN + ASM_REWRITE_TAC[VALID_PATH_LINEPATH; PATH_IMAGE_LINEPATH; + PATHSTART_LINEPATH; PATHFINISH_LINEPATH] THEN + ASM_SIMP_TAC[CONVEX_CONTAINS_SEGMENT_IMP; CONVEX_CBALL] THEN + REWRITE_TAC[CENTRE_IN_CBALL; REAL_POS] THEN + DISCH_THEN(MP_TAC o SPEC `&12 / (&1 - t)` o MATCH_MP + (ONCE_REWRITE_RULE[IMP_CONJ] HAS_PATH_INTEGRAL_BOUND_LINEPATH)) THEN + ANTS_TAC THENL + [ASM_SIMP_TAC[REAL_LE_DIV; REAL_POS; REAL_SUB_LT; REAL_LT_IMP_LE] THEN + X_GEN_TAC `w:complex` THEN DISCH_TAC THEN + MP_TAC(ISPECL [`Cx(&0)`; `z:complex`; `w:complex`] SEGMENT_BOUND) THEN + ASM_REWRITE_TAC[COMPLEX_SUB_RZERO] THEN STRIP_TAC THEN + MP_TAC(ISPECL + [`g:complex->complex`; `cball(Cx(&0),&1)`; `w:complex`; + `&1 - t`; `&1`] BLOCH_COROLLARY) THEN + ASM_REWRITE_TAC[FRONTIER_CBALL; COMPLEX_IN_CBALL_0; + COMPLEX_IN_SPHERE_0] THEN + MATCH_MP_TAC(TAUT + `p /\ q /\ ~s /\ (~r ==> t) ==> (p /\ q /\ r ==> s) ==> t`) THEN + REWRITE_TAC[REAL_NOT_LE] THEN REPEAT CONJ_TAC THENL + [ASM_REAL_ARITH_TAC; + MAP_EVERY UNDISCH_TAC + [`norm(w:complex) <= norm(z:complex)`; `norm(z:complex) <= t`] THEN + CONV_TAC NORM_ARITH; + MATCH_MP_TAC(SET_RULE + `!t u. (!b. (?w. w IN t /\ w IN ball(b,&1)) \/ + (?w. w IN u /\ w IN ball(b,&1))) /\ + (!x. x IN d ==> ~(g x IN t UNION u)) + ==> ~(?b. ball(b,&1) SUBSET IMAGE g d)`) THEN + MAP_EVERY EXISTS_TAC + [`{ complex(m,log(&n + sqrt(&n pow 2 - &1)) / pi) | + integer m /\ 0 < n}`; + `{ complex(m,--log(&n + sqrt(&n pow 2 - &1)) / pi) | + integer m /\ 0 < n}`] THEN + REWRITE_TAC[EXISTS_IN_GSPEC] THEN CONJ_TAC THENL + [X_GEN_TAC `b:complex` THEN REWRITE_TAC[OR_EXISTS_THM] THEN + MP_TAC(ISPEC `Re b` INTEGER_ROUND) THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `m:real` THEN + STRIP_TAC THEN ASM_REWRITE_TAC[IN_BALL] THEN + DISJ_CASES_TAC(REAL_ARITH `&0 <= Im b \/ &0 <= --(Im b)`) THENL + [MP_TAC(SPEC `Im b` lemma2); MP_TAC(SPEC `--(Im b)` lemma2)] THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC MONO_EXISTS THEN + X_GEN_TAC `n:num` THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THENL + [DISJ1_TAC; DISJ2_TAC] THEN + REWRITE_TAC[dist] THEN + W(MP_TAC o PART_MATCH lhand COMPLEX_NORM_LE_RE_IM o lhand o snd) THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] REAL_LET_TRANS) THEN + MATCH_MP_TAC(REAL_ARITH + `x <= &1 / &2 /\ y < &1 / &2 ==> x + y < &1`) THEN + ASM_REWRITE_TAC[RE_SUB; IM_SUB; RE; IM] THEN ASM_REAL_ARITH_TAC; + X_GEN_TAC `v:complex` THEN DISCH_TAC THEN + DISCH_THEN(DISJ_CASES_TAC o MATCH_MP lemma3) THEN + REPEAT(FIRST_X_ASSUM(MP_TAC o SPEC `v:complex`)) THEN + ASM_REWRITE_TAC[] THEN CONV_TAC COMPLEX_RING]; + REWRITE_TAC[REAL_ARITH `a * c / &12 < &1 <=> c * a < &12`] THEN + ASM_SIMP_TAC[GSYM REAL_LT_RDIV_EQ; REAL_SUB_LT] THEN MATCH_MP_TAC + (NORM_ARITH `x = y ==> norm(x) < d ==> norm(y) <= d`) THEN + MATCH_MP_TAC COMPLEX_DERIVATIVE_UNIQUE_AT THEN + MAP_EVERY EXISTS_TAC [`g:complex->complex`; `w:complex`] THEN + REWRITE_TAC[HAS_COMPLEX_DERIVATIVE_DIFFERENTIABLE] THEN + MATCH_MP_TAC(TAUT `(q ==> p) /\ q ==> p /\ q`) THEN + CONJ_TAC THENL [MESON_TAC[complex_differentiable]; ALL_TAC] THEN + MATCH_MP_TAC(MESON[] + `!s. (g has_complex_derivative g') (at x within s) /\ + ((g has_complex_derivative g') (at x within s) <=> + (g has_complex_derivative g') (at x)) + ==> (g has_complex_derivative g') (at x)`) THEN + EXISTS_TAC `cball(Cx(&0),&1)` THEN CONJ_TAC THENL + [FIRST_X_ASSUM MATCH_MP_TAC THEN + REWRITE_TAC[COMPLEX_IN_CBALL_0] THEN ASM_REAL_ARITH_TAC; + REWRITE_TAC[HAS_COMPLEX_DERIVATIVE_WITHIN; + HAS_COMPLEX_DERIVATIVE_AT] THEN + MATCH_MP_TAC LIM_WITHIN_INTERIOR THEN + REWRITE_TAC[INTERIOR_CBALL; COMPLEX_IN_BALL_0] THEN + ASM_REAL_ARITH_TAC]]; + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] REAL_LE_TRANS) THEN + ONCE_REWRITE_TAC[REAL_ARITH `&12 * t / s = &12 / s * t`] THEN + MATCH_MP_TAC REAL_LE_LMUL THEN + ASM_SIMP_TAC[REAL_LE_DIV; REAL_POS; REAL_SUB_LT; REAL_LT_IMP_LE] THEN + ASM_REWRITE_TAC[COMPLEX_SUB_RZERO]]; + GEN_REWRITE_TAC (LAND_CONV o RAND_CONV) + [COMPLEX_RING `y = (Cx(&1) + (Cx(&2) * y - Cx (&1))) / Cx(&2)`] THEN + ASM_SIMP_TAC[COMPLEX_NORM_DIV; COMPLEX_NORM_CX; REAL_ABS_NUM] THEN + ONCE_REWRITE_TAC[REAL_ARITH `x / &2 <= y <=> x <= &2 * y`] THEN + W(MP_TAC o PART_MATCH lhand NORM_CCOS_PLUS1_LE o lhand o snd) THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] REAL_LE_TRANS) THEN + MATCH_MP_TAC REAL_LE_LMUL THEN + REWRITE_TAC[REAL_POS; REAL_EXP_MONO_LE; COMPLEX_NORM_MUL] THEN + REWRITE_TAC[COMPLEX_NORM_CX; REAL_ABS_PI] THEN + MATCH_MP_TAC REAL_LE_LMUL THEN REWRITE_TAC[PI_POS_LE] THEN + W(MP_TAC o PART_MATCH lhand NORM_CCOS_LE o lhand o snd) THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] REAL_LE_TRANS) THEN + REWRITE_TAC[REAL_EXP_MONO_LE; COMPLEX_NORM_MUL] THEN + REWRITE_TAC[COMPLEX_NORM_CX; REAL_ABS_PI] THEN + MATCH_MP_TAC REAL_LE_LMUL THEN REWRITE_TAC[PI_POS_LE] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (NORM_ARITH + `norm(z - w) <= c ==> norm w <= a + b ==> norm z <= a + b + c`)) THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + REAL_LE_TRANS)) THEN + UNDISCH_TAC `norm(f(Cx(&0)):complex) <= r` THEN + CONV_TAC NORM_ARITH]);; + +(* ------------------------------------------------------------------------- *) +(* The Little Picard Theorem. *) +(* ------------------------------------------------------------------------- *) + +let LANDAU_PICARD = prove + (`?R. (!z. &0 < R z) /\ + !f. f holomorphic_on cball(Cx(&0),R(f(Cx(&0)))) /\ + (!z. z IN cball(Cx(&0),R(f(Cx(&0)))) + ==> ~(f(z) = Cx(&0)) /\ ~(f(z) = Cx(&1))) + ==> norm(complex_derivative f (Cx(&0))) < &1`, + ABBREV_TAC + `R = \z:complex. &3 * exp(pi * exp(pi * (&2 + &2 * norm(z) + &12)))` THEN + EXISTS_TAC `R:complex->real` THEN + MATCH_MP_TAC(TAUT `p /\ (p ==> q) ==> p /\ q`) THEN CONJ_TAC THENL + [EXPAND_TAC "R" THEN + REWRITE_TAC[REAL_EXP_POS_LT; REAL_ARITH `&0 < &3 * x <=> &0 < x`]; + DISCH_TAC] THEN + REPEAT STRIP_TAC THEN + ABBREV_TAC `r = (R:complex->real)(f(Cx(&0)))` THEN + SUBGOAL_THEN `&0 < r` ASSUME_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN + ABBREV_TAC `g = \z. (f:complex->complex)(Cx r * z)` THEN + SUBGOAL_THEN + `!z. z IN cball(Cx(&0),&1) ==> (Cx r * z) IN cball(Cx(&0),r)` + ASSUME_TAC THENL + [REWRITE_TAC[COMPLEX_IN_CBALL_0; COMPLEX_NORM_MUL; COMPLEX_NORM_CX] THEN + ASM_SIMP_TAC[REAL_LE_LMUL_EQ; REAL_ARITH + `&0 < r ==> (abs r * z <= r <=> r * z <= r * &1)`]; + ALL_TAC] THEN + SUBGOAL_THEN `g holomorphic_on cball(Cx(&0),&1)` ASSUME_TAC THENL + [EXPAND_TAC "g" THEN GEN_REWRITE_TAC LAND_CONV [GSYM o_DEF] THEN + MATCH_MP_TAC HOLOMORPHIC_ON_COMPOSE THEN + SIMP_TAC[HOLOMORPHIC_ON_MUL; HOLOMORPHIC_ON_ID; HOLOMORPHIC_ON_CONST] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + HOLOMORPHIC_ON_SUBSET)) THEN + ASM_REWRITE_TAC[SUBSET; FORALL_IN_IMAGE]; + ALL_TAC] THEN + MP_TAC(ISPECL [`g:complex->complex`; `norm(f(Cx(&0)):complex)`] + SCHOTTKY) THEN + ASM_REWRITE_TAC[] THEN ANTS_TAC THENL + [EXPAND_TAC "g" THEN REWRITE_TAC[COMPLEX_MUL_RZERO; REAL_LE_REFL] THEN + GEN_TAC THEN DISCH_TAC THEN REWRITE_TAC[DE_MORGAN_THM] THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_SIMP_TAC[]; + ALL_TAC] THEN + DISCH_THEN(MP_TAC o SPEC `&1 / &2`) THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN + MP_TAC(ASSUME `(R:complex->real)(f(Cx(&0))) = r`) THEN + EXPAND_TAC "R" THEN + SIMP_TAC[REAL_ARITH `&3 * x = r <=> x = r / &3`] THEN + DISCH_THEN SUBST1_TAC THEN DISCH_THEN(LABEL_TAC "*") THEN + MP_TAC(ISPECL + [`g:complex->complex`; `Cx(&0)`; `&1 / &2`; `r / &3`; `1`] + CAUCHY_INEQUALITY) THEN + CONV_TAC NUM_REDUCE_CONV THEN CONV_TAC REAL_RAT_REDUCE_CONV THEN + REWRITE_TAC[HIGHER_COMPLEX_DERIVATIVE_1] THEN + ASM_SIMP_TAC[COMPLEX_SUB_LZERO; NORM_NEG; REAL_EQ_IMP_LE] THEN + ANTS_TAC THENL + [CONJ_TAC THENL + [MATCH_MP_TAC HOLOMORPHIC_ON_IMP_CONTINUOUS_ON; ALL_TAC] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + HOLOMORPHIC_ON_SUBSET)) THEN + REWRITE_TAC[SUBSET_BALLS; DIST_REFL] THEN CONV_TAC REAL_RAT_REDUCE_CONV; + ALL_TAC] THEN + SUBGOAL_THEN + `complex_derivative g (Cx(&0)) = Cx r * complex_derivative f (Cx(&0))` + SUBST1_TAC THENL + [MATCH_MP_TAC HAS_COMPLEX_DERIVATIVE_DERIVATIVE THEN EXPAND_TAC "g" THEN + REWRITE_TAC[] THEN ONCE_REWRITE_TAC[COMPLEX_MUL_SYM] THEN + ONCE_REWRITE_TAC[GSYM o_DEF] THEN MATCH_MP_TAC COMPLEX_DIFF_CHAIN_AT THEN + CONJ_TAC THENL + [COMPLEX_DIFF_TAC THEN REWRITE_TAC[COMPLEX_MUL_LID]; ALL_TAC] THEN + REWRITE_TAC[COMPLEX_MUL_LZERO; HAS_COMPLEX_DERIVATIVE_DIFFERENTIABLE] THEN + MATCH_MP_TAC HOLOMORPHIC_ON_IMP_DIFFERENTIABLE_AT THEN + EXISTS_TAC `ball(Cx(&0),r)` THEN + ASM_REWRITE_TAC[OPEN_BALL; CENTRE_IN_BALL] THEN + ASM_MESON_TAC[BALL_SUBSET_CBALL; HOLOMORPHIC_ON_SUBSET]; + REWRITE_TAC[COMPLEX_NORM_MUL; COMPLEX_NORM_CX] THEN + ASM_SIMP_TAC[REAL_LE_LMUL_EQ; REAL_ARITH + `&0 < r ==> (abs r * z <= &1 * r / &3 / (&1 / &2) <=> + r * z <= r * &2 / &3)`] THEN + REAL_ARITH_TAC]);; + +let LITTLE_PICARD = prove + (`!f a b. + f holomorphic_on (:complex) /\ + ~(a = b) /\ IMAGE f (:complex) INTER {a,b} = {} + ==> ?c. f = \x. c`, + let lemma = prove + (`!f. f holomorphic_on (:complex) /\ + (!z. ~(f z = Cx(&0)) /\ ~(f z = Cx(&1))) + ==> ?c. f = \x. c`, + X_CHOOSE_THEN `R:complex->real` MP_TAC LANDAU_PICARD THEN + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`f:complex->complex`; `(:complex)`] + HAS_COMPLEX_DERIVATIVE_ZERO_CONNECTED_CONSTANT) THEN + REWRITE_TAC[IN_UNIV; FUN_EQ_THM; CONNECTED_UNIV; OPEN_UNIV] THEN + DISCH_THEN MATCH_MP_TAC THEN X_GEN_TAC `w:complex` THEN + ASM_CASES_TAC `complex_derivative f w = Cx(&0)` THENL + [FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN + REWRITE_TAC[HAS_COMPLEX_DERIVATIVE_DIFFERENTIABLE] THEN + ASM_MESON_TAC[HOLOMORPHIC_ON_IMP_DIFFERENTIABLE_AT; OPEN_UNIV; IN_UNIV]; + MATCH_MP_TAC(TAUT `F ==> p`)] THEN + FIRST_X_ASSUM(MP_TAC o SPEC + `\z. (f:complex->complex)(w + z / complex_derivative f w)`) THEN + ASM_REWRITE_TAC[NOT_IMP] THEN CONJ_TAC THENL + [GEN_REWRITE_TAC LAND_CONV [GSYM o_DEF] THEN + MATCH_MP_TAC HOLOMORPHIC_ON_COMPOSE THEN CONJ_TAC THENL + [ALL_TAC; ASM_MESON_TAC[HOLOMORPHIC_ON_SUBSET; SUBSET_UNIV]] THEN + REWRITE_TAC[HOLOMORPHIC_ON_DIFFERENTIABLE] THEN + REPEAT STRIP_TAC THEN COMPLEX_DIFFERENTIABLE_TAC; + SUBGOAL_THEN + `complex_derivative (\z. f (w + z / complex_derivative f w)) (Cx(&0)) = + complex_derivative f w * inv(complex_derivative f w)` + SUBST1_TAC THENL + [ALL_TAC; + ASM_SIMP_TAC[COMPLEX_MUL_RINV; COMPLEX_NORM_CX; REAL_ABS_NUM; + REAL_LT_REFL]] THEN + ONCE_REWRITE_TAC[GSYM o_DEF] THEN + MATCH_MP_TAC HAS_COMPLEX_DERIVATIVE_DERIVATIVE THEN + MATCH_MP_TAC COMPLEX_DIFF_CHAIN_AT THEN CONJ_TAC THENL + [COMPLEX_DIFF_TAC THEN + REWRITE_TAC[COMPLEX_ADD_LID; COMPLEX_MUL_LID; complex_div]; + REWRITE_TAC[complex_div; COMPLEX_MUL_LZERO; COMPLEX_ADD_RID] THEN + REWRITE_TAC[HAS_COMPLEX_DERIVATIVE_DIFFERENTIABLE] THEN + ASM_MESON_TAC[HOLOMORPHIC_ON_IMP_DIFFERENTIABLE_AT; OPEN_UNIV; + IN_UNIV]]]) in + REPEAT STRIP_TAC THEN + MP_TAC(SPEC `\x:complex. Cx(&1) / (b - a) * (f x - b) + Cx(&1)` lemma) THEN + ASM_SIMP_TAC[HOLOMORPHIC_ON_ADD; HOLOMORPHIC_ON_MUL; HOLOMORPHIC_ON_SUB; + HOLOMORPHIC_ON_CONST] THEN + ASM_SIMP_TAC[FUN_EQ_THM; COMPLEX_FIELD + `~(a = b) + ==> (Cx(&1) / (b - a) * (f - b) + Cx(&1) = c <=> + f = b + (b - a) / Cx(&1) * (c - Cx(&1)))`] THEN + ANTS_TAC THENL [ALL_TAC; MESON_TAC[]] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I + [SET_RULE `IMAGE f UNIV INTER t = {} <=> !x. ~(f x IN t)`]) THEN + MATCH_MP_TAC MONO_FORALL THEN + REWRITE_TAC[CONTRAPOS_THM; IN_INSERT; NOT_IN_EMPTY] THEN + CONV_TAC COMPLEX_RING);; + +(* ------------------------------------------------------------------------- *) +(* A couple of little applications of Little Picard. *) +(* ------------------------------------------------------------------------- *) + +let HOLOMORPHIC_PERIODIC_FIXPOINT = prove + (`!f p. f holomorphic_on (:complex) /\ ~(p = Cx(&0)) /\ (!z. f(z + p) = f(z)) + ==> ?x. f(x) = x`, + REWRITE_TAC[MESON[] `(?x. P x) <=> ~(!x. ~P x)`] THEN REPEAT STRIP_TAC THEN + MP_TAC(ISPECL + [`\z:complex. f(z) - z`; `Cx(&0)`; `p:complex`] LITTLE_PICARD) THEN + ASM_SIMP_TAC[HOLOMORPHIC_ON_SUB; HOLOMORPHIC_ON_ID; NOT_IMP] THEN + REWRITE_TAC[SET_RULE `IMAGE f UNIV INTER {a,b} = {} <=> + !x. ~(f x = a) /\ ~(f x = b)`] THEN + CONJ_TAC THENL + [REWRITE_TAC[COMPLEX_RING `a - b:complex = c <=> a = b + c`; + COMPLEX_ADD_RID] THEN + ASM_MESON_TAC[]; + REWRITE_TAC[NOT_EXISTS_THM; FUN_EQ_THM] THEN GEN_TAC THEN + DISCH_THEN(fun th -> + MP_TAC(SPEC `p + p:complex` th) THEN + MP_TAC(SPEC `p:complex` th)) THEN + ASM_REWRITE_TAC[] THEN + UNDISCH_TAC `~(p = Cx(&0))` THEN CONV_TAC COMPLEX_RING]);; + +let HOLOMORPHIC_INVOLUTION_POINT = prove + (`!f. f holomorphic_on (:complex) /\ ~(?a. f = \x. a + x) ==> ?x. f(f x) = x`, + REWRITE_TAC[MESON[] `(?x. P x) <=> ~(!x. ~P x)`] THEN REPEAT STRIP_TAC THEN + SUBGOAL_THEN `!z:complex. ~(f z = z)` ASSUME_TAC THENL + [ASM_MESON_TAC[]; ALL_TAC] THEN + MP_TAC(ISPECL [`\x. (f(f x) - x) / (f x - x)`; `Cx(&0)`; `Cx(&1)`] + LITTLE_PICARD) THEN + REWRITE_TAC[NOT_IMP; CX_INJ; REAL_OF_NUM_EQ; ARITH_EQ] THEN + REWRITE_TAC[SET_RULE `IMAGE f UNIV INTER {a,b} = {} <=> + !x. ~(f x = a) /\ ~(f x = b)`] THEN + ASM_SIMP_TAC[FUN_EQ_THM; COMPLEX_FIELD + `~(a:complex = b) ==> (x / (a - b) = c <=> x = c * (a - b))`] THEN + REPEAT CONJ_TAC THENL + [MATCH_MP_TAC HOLOMORPHIC_ON_DIV THEN + ASM_SIMP_TAC[COMPLEX_SUB_0] THEN CONJ_TAC THEN + MATCH_MP_TAC HOLOMORPHIC_ON_SUB THEN + ASM_REWRITE_TAC[HOLOMORPHIC_ON_ID] THEN + GEN_REWRITE_TAC LAND_CONV [GSYM o_DEF] THEN + MATCH_MP_TAC HOLOMORPHIC_ON_COMPOSE THEN + ASM_MESON_TAC[HOLOMORPHIC_ON_SUBSET; SUBSET_UNIV]; + ASM_REWRITE_TAC[COMPLEX_MUL_LZERO; COMPLEX_MUL_LID; COMPLEX_SUB_0] THEN + REWRITE_TAC[COMPLEX_RING `x - a:complex = y - a <=> x = y`] THEN + ASM_MESON_TAC[]; + DISCH_THEN(X_CHOOSE_THEN `c:complex` MP_TAC)] THEN + ASM_CASES_TAC `c = Cx(&0)` THEN + ASM_REWRITE_TAC[COMPLEX_MUL_LZERO; COMPLEX_SUB_0] THEN + ASM_CASES_TAC `c = Cx(&1)` THEN + ASM_REWRITE_TAC[COMPLEX_RING `ffx - x = Cx(&1) * (fx - x) <=> ffx = fx`] THEN + REWRITE_TAC[COMPLEX_RING + `ffx - x = c * (fx - x) <=> (ffx - c * fx) = x * (Cx(&1) - c)`] THEN + DISCH_TAC THEN + MP_TAC(SPECL + [`complex_derivative f o f`; `Cx(&0)`; `c:complex`] LITTLE_PICARD) THEN + REWRITE_TAC[SET_RULE `IMAGE f UNIV INTER {a,b} = {} <=> + !x. ~(f x = a) /\ ~(f x = b)`] THEN + ASM_REWRITE_TAC[o_THM; NOT_IMP] THEN REPEAT CONJ_TAC THENL + [MATCH_MP_TAC HOLOMORPHIC_ON_COMPOSE THEN + ASM_MESON_TAC[HOLOMORPHIC_COMPLEX_DERIVATIVE; OPEN_UNIV; SUBSET_UNIV; + HOLOMORPHIC_ON_SUBSET]; + MP_TAC(MATCH_MP MONO_FORALL (GEN `z:complex` (SPECL + [`\x:complex. f(f x) - c * f x`; `z:complex`; + `complex_derivative f z * (complex_derivative f (f z) - c)`; + `Cx(&1) * (Cx(&1) - c)`] COMPLEX_DERIVATIVE_UNIQUE_AT))) THEN + ANTS_TAC THENL + [REPEAT STRIP_TAC THENL + [REWRITE_TAC[COMPLEX_RING `a * (b - c):complex = b * a - c * a`] THEN + MATCH_MP_TAC HAS_COMPLEX_DERIVATIVE_SUB THEN CONJ_TAC THENL + [ONCE_REWRITE_TAC[GSYM o_DEF] THEN MATCH_MP_TAC COMPLEX_DIFF_CHAIN_AT; + MATCH_MP_TAC HAS_COMPLEX_DERIVATIVE_LMUL_AT] THEN + REWRITE_TAC[HAS_COMPLEX_DERIVATIVE_DIFFERENTIABLE] THEN + ASM_MESON_TAC[HOLOMORPHIC_ON_IMP_DIFFERENTIABLE_AT; IN_UNIV; OPEN_UNIV]; + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC HAS_COMPLEX_DERIVATIVE_RMUL_AT THEN + REWRITE_TAC[HAS_COMPLEX_DERIVATIVE_ID]]; + DISCH_THEN(fun th -> X_GEN_TAC `z:complex` THEN REPEAT STRIP_TAC THEN + MP_TAC th) + THENL [DISCH_THEN(MP_TAC o SPEC `(f:complex->complex) z`); + DISCH_THEN(MP_TAC o SPEC `z:complex`)] THEN + ASM_REWRITE_TAC[] THEN + UNDISCH_TAC `~(c = Cx(&1))` THEN CONV_TAC COMPLEX_RING]; + REWRITE_TAC[FUN_EQ_THM; o_THM] THEN + DISCH_THEN(X_CHOOSE_TAC `k:complex`) THEN + SUBGOAL_THEN `open(IMAGE (f:complex->complex) (:complex))` + ASSUME_TAC THENL + [MATCH_MP_TAC(REWRITE_RULE[RIGHT_IMP_FORALL_THM; IMP_IMP] + OPEN_MAPPING_THM) THEN + EXISTS_TAC `(:complex)` THEN + ASM_REWRITE_TAC[OPEN_UNIV; CONNECTED_UNIV; SUBSET_UNIV; IN_UNIV] THEN + ASM_MESON_TAC[]; + ALL_TAC] THEN + MP_TAC(ISPECL + [`\z. complex_derivative f z - k`; `(:complex)`; + `IMAGE (f:complex->complex) (:complex)`; `(f:complex->complex) z`] + ANALYTIC_CONTINUATION) THEN + REWRITE_TAC[OPEN_UNIV; CONNECTED_UNIV; SUBSET_UNIV; IN_UNIV] THEN + ASM_REWRITE_TAC[FORALL_IN_IMAGE; COMPLEX_SUB_0; NOT_IMP] THEN + REPEAT CONJ_TAC THENL + [MATCH_MP_TAC HOLOMORPHIC_ON_SUB THEN REWRITE_TAC[ETA_AX] THEN + ASM_MESON_TAC[HOLOMORPHIC_COMPLEX_DERIVATIVE; OPEN_UNIV; SUBSET_UNIV; + HOLOMORPHIC_ON_SUBSET; HOLOMORPHIC_ON_CONST]; + MATCH_MP_TAC LIMPT_OF_OPEN THEN ASM_REWRITE_TAC[] THEN SET_TAC[]; + DISCH_TAC] THEN + MP_TAC(ISPECL + [`\x:complex. f x - k * x`; `(:complex)`] + HAS_COMPLEX_DERIVATIVE_ZERO_CONNECTED_CONSTANT) THEN + REWRITE_TAC[OPEN_UNIV; CONNECTED_UNIV; IN_UNIV; NOT_IMP] THEN + CONJ_TAC THENL + [X_GEN_TAC `z:complex` THEN + SUBST1_TAC(COMPLEX_RING `Cx(&0) = k - k * Cx(&1)`) THEN + MATCH_MP_TAC HAS_COMPLEX_DERIVATIVE_SUB THEN CONJ_TAC THENL + [ASM_MESON_TAC[HAS_COMPLEX_DERIVATIVE_DIFFERENTIABLE; + HOLOMORPHIC_ON_OPEN; OPEN_UNIV; IN_UNIV; + complex_differentiable]; + COMPLEX_DIFF_TAC THEN CONV_TAC COMPLEX_RING]; + DISCH_THEN(X_CHOOSE_THEN `l:complex` MP_TAC) THEN + REWRITE_TAC[COMPLEX_RING `a - b:complex = c <=> a = b + c`] THEN + DISCH_THEN(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th; FUN_EQ_THM])) THEN + ASM_CASES_TAC `k = Cx(&1)` THENL + [UNDISCH_TAC `!a:complex. ~(!x. k * x + l = a + x)` THEN + ASM_REWRITE_TAC[COMPLEX_MUL_LID] THEN MESON_TAC[COMPLEX_ADD_SYM]; + UNDISCH_TAC `!z:complex. ~(k * z + l = z)` THEN + ASM_SIMP_TAC[COMPLEX_FIELD + `~(k = Cx(&1)) ==> (k * z + l = z <=> z = l / (Cx(&1) - k))`] THEN + MESON_TAC[]]]]);; + +(* ------------------------------------------------------------------------- *) +(* Montel's theorem: a sequence of holomorphic functions uniformly bounded *) +(* on compact subsets of an open set S has a subsequence that converges to a *) +(* holomorphic function, and converges *uniformly* on compact subsets of S. *) +(* ------------------------------------------------------------------------- *) + +let MONTEL = prove + (`!(f:num->complex->complex) p s. + open s /\ (!h. h IN p ==> h holomorphic_on s) /\ + (!k. compact k /\ k SUBSET s + ==> ?b. !h z. h IN p /\ z IN k ==> norm(h z) <= b) /\ + (!n. (f n) IN p) + ==> ?g r. g holomorphic_on s /\ + (!m n:num. m < n ==> r m < r n) /\ + (!x. x IN s ==> ((\n. f (r n) x) --> g(x)) sequentially) /\ + (!k e. compact k /\ k SUBSET s /\ &0 < e + ==> ?N. !n x. n >= N /\ x IN k + ==> norm(f (r n) x - g x) < e)`, + REPEAT GEN_TAC THEN + REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + SPEC_TAC(`f:num->complex->complex`,`f:num->complex->complex`) THEN + REWRITE_TAC[LIM_SEQUENTIALLY] THEN + REWRITE_TAC[RIGHT_IMP_FORALL_THM; IMP_IMP; GSYM GE; dist] THEN + FIRST_ASSUM(MP_TAC o MATCH_MP OPEN_UNION_COMPACT_SUBSETS) THEN + DISCH_THEN(X_CHOOSE_THEN `k:num->complex->bool` + (fun th -> FIRST_X_ASSUM(MP_TAC o GEN `i:num `o + SPEC `(k:num->complex->bool) i`) THEN + STRIP_ASSUME_TAC th)) THEN + ASM_REWRITE_TAC[SKOLEM_THM; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `B:num->real` THEN DISCH_TAC THEN + SUBGOAL_THEN + `!(f:num->complex->complex) (i:num). + (!n. f n IN p) + ==> ?r g. (!m n:num. m < n ==> r m < r n) /\ + (!e. &0 < e ==> ?N. !n x. n >= N /\ x IN k i + ==> norm((f o r) n x - g x) < e)` + MP_TAC THENL + [REPEAT STRIP_TAC THEN REWRITE_TAC[o_THM] THEN + MP_TAC(ISPECL [`f:num->complex->complex`; `(k:num->complex->bool) i`; + `(B:num->real) i`] ARZELA_ASCOLI) THEN + ANTS_TAC THENL [ASM_SIMP_TAC[]; MESON_TAC[]] THEN + MAP_EVERY X_GEN_TAC [`z:complex`; `e:real`] THEN STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [OPEN_CONTAINS_CBALL]) THEN + DISCH_THEN(MP_TAC o SPEC `z:complex`) THEN + ANTS_TAC THENL [ASM SET_TAC[]; REWRITE_TAC[SUBSET; IN_CBALL]] THEN + DISCH_THEN(X_CHOOSE_THEN `r:real` STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN + `?M. &0 < M /\ + !n w. dist(z,w) <= &2 / &3 * r + ==> norm((f:num->complex->complex) n w) <= M` + STRIP_ASSUME_TAC THENL + [FIRST_X_ASSUM(MP_TAC o SPEC `cball(z:complex,&2 / &3 * r)`) THEN + ASM_SIMP_TAC[SUBSET; IN_CBALL; COMPACT_CBALL; + NORM_ARITH `dist(a,b) <= &2 / &3 * r ==> dist(a,b) <= r`] THEN + DISCH_THEN(X_CHOOSE_THEN `N:num` (MP_TAC o SPEC `N:num`)) THEN + REWRITE_TAC[GE; LE_REFL] THEN DISCH_TAC THEN + EXISTS_TAC `abs(B(N:num)) + &1` THEN + REWRITE_TAC[REAL_ARITH `&0 < abs x + &1`] THEN + ASM_MESON_TAC[SUBSET; REAL_ARITH `x <= b ==> x <= abs b + &1`]; + ALL_TAC] THEN + EXISTS_TAC `min (r / &3) ((e * r) / (&6 * M))` THEN + ASM_SIMP_TAC[REAL_LT_MIN; REAL_LT_DIV; + REAL_LT_MUL; REAL_OF_NUM_LT; ARITH] THEN + MAP_EVERY X_GEN_TAC [`n:num`; `y:complex`] THEN STRIP_TAC THEN + MP_TAC + (ISPECL [`(f:num->complex->complex) n`; `cball(z:complex,&2 / &3 * r)`; + `circlepath(z:complex,&2 / &3 * r)`] + CAUCHY_INTEGRAL_FORMULA_CONVEX_SIMPLE) THEN + REWRITE_TAC[CONVEX_CBALL; VALID_PATH_CIRCLEPATH] THEN + REWRITE_TAC[PATHSTART_CIRCLEPATH; PATHFINISH_CIRCLEPATH] THEN + SIMP_TAC[INTERIOR_CBALL; IN_BALL; WINDING_NUMBER_CIRCLEPATH; + NORM_ARITH `dist(z,w) = norm(w - z)`] THEN + ASM_SIMP_TAC[PATH_IMAGE_CIRCLEPATH; + REAL_ARITH `&0 < r ==> &0 <= &2 / &3 * r`] THEN + REWRITE_TAC[sphere; NORM_ARITH `dist(z,w) = norm(w - z)`] THEN + SIMP_TAC[SUBSET; IN_CBALL; IN_DELETE; IN_ELIM_THM; REAL_LE_REFL; + NORM_ARITH `dist(z,w) = norm(w - z)`] THEN + ONCE_REWRITE_TAC[TAUT `p ==> ~q <=> q ==> ~p`] THEN + SIMP_TAC[FORALL_UNWIND_THM2; IMP_CONJ; REAL_LT_IMP_NE] THEN + REWRITE_TAC[RIGHT_FORALL_IMP_THM; COMPLEX_MUL_LID] THEN ANTS_TAC THENL + [MATCH_MP_TAC HOLOMORPHIC_ON_SUBSET THEN + EXISTS_TAC `s:complex->bool` THEN ASM_SIMP_TAC[SUBSET; IN_CBALL] THEN + ASM_SIMP_TAC[NORM_ARITH `dist(a,b) <= &2 / &3 * r ==> dist(a,b) <= r`]; + ALL_TAC] THEN + DISCH_THEN(fun th -> + MP_TAC(SPEC `y:complex` th) THEN MP_TAC(SPEC `z:complex` th)) THEN + ASM_SIMP_TAC[VECTOR_SUB_REFL; NORM_0; REAL_LT_MUL; REAL_LT_DIV; + REAL_OF_NUM_LT; ARITH; NORM_ARITH + `norm(z - y) < r / &3 ==> norm(y - z) < &2 / &3 * r`] THEN + REWRITE_TAC[IMP_IMP] THEN + DISCH_THEN(MP_TAC o MATCH_MP HAS_PATH_INTEGRAL_SUB) THEN + DISCH_THEN(MP_TAC o MATCH_MP (ONCE_REWRITE_RULE[IMP_CONJ] + HAS_PATH_INTEGRAL_BOUND_CIRCLEPATH)) THEN + REWRITE_TAC[GSYM COMPLEX_SUB_LDISTRIB; COMPLEX_NORM_MUL] THEN + REWRITE_TAC[COMPLEX_NORM_II; COMPLEX_NORM_CX; REAL_ABS_PI; + REAL_ABS_NUM; REAL_MUL_LID] THEN + DISCH_THEN(MP_TAC o SPEC `e / r:real`) THEN + ASM_SIMP_TAC[REAL_FIELD + `&0 < r ==> e / r * &2 * pi * c * r = &2 * pi * e * c`] THEN + SIMP_TAC[REAL_LE_LMUL_EQ; REAL_OF_NUM_LT; ARITH; PI_POS] THEN + ANTS_TAC THENL [ALL_TAC; ASM_REAL_ARITH_TAC] THEN + ASM_SIMP_TAC[REAL_LT_IMP_LE; REAL_LT_DIV; REAL_OF_NUM_LT; ARITH; + REAL_LT_MUL] THEN + X_GEN_TAC `w:complex` THEN STRIP_TAC THEN + SUBGOAL_THEN `~(w:complex = z) /\ ~(w = y)` STRIP_ASSUME_TAC THENL + [CONJ_TAC THEN DISCH_THEN SUBST_ALL_TAC THEN + RULE_ASSUM_TAC(REWRITE_RULE[NORM_0; VECTOR_SUB_REFL]) THEN + RULE_ASSUM_TAC(REWRITE_RULE[NORM_SUB]) THEN ASM_REAL_ARITH_TAC; + ALL_TAC] THEN + ASM_SIMP_TAC[COMPLEX_FIELD + `~(w:complex = z) /\ ~(w = y) + ==> (a / (w - z) - a / (w - y) = + (a * (z - y)) / ((w - z) * (w - y)))`] THEN + REWRITE_TAC[COMPLEX_NORM_MUL; COMPLEX_NORM_DIV] THEN + ASM_SIMP_TAC[REAL_LE_LDIV_EQ; REAL_LT_MUL; NORM_POS_LT; VECTOR_SUB_EQ; + REAL_FIELD `&0 < r ==> e / r * (&2 / &3 * r) * x = &2 / &3 * e * x`] THEN + MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `M * (e * r) / (&6 * M)` THEN CONJ_TAC THENL + [MATCH_MP_TAC REAL_LE_MUL2 THEN + ASM_SIMP_TAC[REAL_LT_IMP_LE; NORM_POS_LE] THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_REWRITE_TAC[NORM_ARITH `dist(x,y) = norm(y - x)`; REAL_LE_REFL]; + ASM_SIMP_TAC[REAL_FIELD `&0 < M ==> M * e / (&6 * M) = e / &6`] THEN + MATCH_MP_TAC(REAL_ARITH + `&0 < x /\ x <= y * &3 ==> x / &6 <= &2 / &3 * y`) THEN + ASM_SIMP_TAC[REAL_LT_MUL; GSYM REAL_MUL_ASSOC; REAL_LE_LMUL_EQ] THEN + MAP_EVERY UNDISCH_TAC + [`norm(w - z:complex) = &2 / &3 * r`; + `norm(z - y:complex) < r / &3`] THEN + CONV_TAC NORM_ARITH]; + ALL_TAC] THEN + REWRITE_TAC[RIGHT_EXISTS_AND_THM] THEN + DISCH_THEN(fun th -> X_GEN_TAC `f:num->complex->complex` THEN + DISCH_TAC THEN MP_TAC th) THEN + DISCH_THEN(MP_TAC o GENL [`i:num`; `r:num->num`] o + SPECL [`(f:num->complex->complex) o (r:num->num)`; `i:num`]) THEN + GEN_REWRITE_TAC + (LAND_CONV o funpow 2 BINDER_CONV o LAND_CONV o ONCE_DEPTH_CONV) + [o_THM] THEN ASM_REWRITE_TAC[GSYM o_ASSOC] THEN + DISCH_THEN(MP_TAC o MATCH_MP (ONCE_REWRITE_RULE[IMP_CONJ] + SUBSEQUENCE_DIAGONALIZATION_LEMMA)) THEN + ANTS_TAC THENL + [SIMP_TAC[o_THM; GE] THEN REPEAT GEN_TAC THEN + DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `g:complex->complex` THEN + MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `e:real` THEN + MATCH_MP_TAC MONO_IMP THEN REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_TAC `M:num`) THEN + EXISTS_TAC `MAX M N` THEN + REWRITE_TAC[ARITH_RULE `MAX m n <= x <=> m <= x /\ n <= x`] THEN + ASM_MESON_TAC[LE_TRANS]; + ALL_TAC] THEN + DISCH_THEN(MP_TAC o SPEC `I:num->num`) THEN + REWRITE_TAC[I_O_ID; RIGHT_AND_EXISTS_THM] THEN + ONCE_REWRITE_TAC[SWAP_EXISTS_THM] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `r:num->num` THEN + REWRITE_TAC[o_THM] THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + SUBGOAL_THEN + `!x. x IN s + ==> ?l. !e. &0 < e + ==> ?N:num. !n. n >= N + ==> norm((f:num->complex->complex) (r n) x - l) + < e` + MP_TAC THENL + [X_GEN_TAC `z:complex` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `{z:complex}`) THEN + ASM_REWRITE_TAC[COMPACT_SING; SING_SUBSET] THEN + DISCH_THEN(X_CHOOSE_THEN `N:num` STRIP_ASSUME_TAC) THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [SKOLEM_THM]) THEN + DISCH_THEN(X_CHOOSE_THEN `G:num->complex->complex` MP_TAC) THEN + DISCH_THEN(LABEL_TAC "*" o SPEC `N:num`) THEN + EXISTS_TAC `(G:num->complex->complex) N z` THEN + X_GEN_TAC `e:real` THEN DISCH_TAC THEN + REMOVE_THEN "*" (MP_TAC o SPEC `e:real`) THEN + ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `M:num` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `MAX M N` THEN + REWRITE_TAC[ARITH_RULE `a >= MAX m n <=> a >= m /\ a >= n`] THEN + ASM_MESON_TAC[GE_REFL]; + ALL_TAC] THEN + GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [RIGHT_IMP_EXISTS_THM] THEN + REWRITE_TAC[SKOLEM_THM; RIGHT_IMP_FORALL_THM; IMP_IMP] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `g:complex->complex` THEN + DISCH_TAC THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC(TAUT `b /\ (b ==> a) ==> a /\ b`) THEN CONJ_TAC THENL + [MAP_EVERY X_GEN_TAC [`t:complex->bool`; `e:real`] THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `t:complex->bool`) THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_TAC `N:num`) THEN + FIRST_X_ASSUM(X_CHOOSE_THEN `h:complex->complex` (LABEL_TAC "*") o + SPEC `N:num`) THEN + SUBGOAL_THEN + `!w. w IN t ==> g w = (h:complex->complex) w` + (fun th -> ASM_MESON_TAC[GE_REFL; SUBSET; th]) THEN + X_GEN_TAC `w:complex` THEN DISCH_TAC THEN + MATCH_MP_TAC(ISPEC `sequentially` LIM_UNIQUE) THEN + EXISTS_TAC `\n:num. (f:num->complex->complex)(r n) w` THEN + ASM_REWRITE_TAC[TRIVIAL_LIMIT_SEQUENTIALLY; LIM_SEQUENTIALLY] THEN + REWRITE_TAC[GSYM GE; dist; o_THM] THEN + ASM_MESON_TAC[SUBSET; GE_REFL]; + DISCH_THEN(LABEL_TAC "*")] THEN + MATCH_MP_TAC HOLOMORPHIC_UNIFORM_SEQUENCE THEN + EXISTS_TAC `(f:num->complex->complex) o (r:num->num)` THEN + ASM_SIMP_TAC[o_THM] THEN X_GEN_TAC `z:complex` THEN DISCH_TAC THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [OPEN_CONTAINS_CBALL]) THEN + DISCH_THEN(MP_TAC o SPEC `z:complex`) THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `d:real` THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN + REWRITE_TAC[EVENTUALLY_SEQUENTIALLY] THEN ASM_MESON_TAC[COMPACT_CBALL; GE]);; + +(* ------------------------------------------------------------------------- *) +(* Moebius functions are biholomorphisms of the unit disc. *) +(* ------------------------------------------------------------------------- *) + +let moebius_function = new_definition + `!t w z. moebius_function t w z = + cexp (ii * Cx t) * (z - w) / (Cx(&1) - cnj w * z)`;; + +let MOEBIUS_FUNCTION_SIMPLE = prove + (`!w z. moebius_function (&0) w z = (z - w) / (Cx(&1) - cnj w * z)`, + REWRITE_TAC[moebius_function; COMPLEX_MUL_RZERO; CEXP_0; COMPLEX_MUL_LID]);; + +let MOEBIUS_FUNCTION_EQ_ZERO = prove + (`!t w. moebius_function t w w = Cx(&0)`, + REWRITE_TAC [moebius_function] THEN CONV_TAC COMPLEX_FIELD);; + +let MOEBIUS_FUNCTION_OF_ZERO = prove + (`!t w. moebius_function t w (Cx(&0)) = -- cexp (ii * Cx t) * w`, + REWRITE_TAC [moebius_function] THEN CONV_TAC COMPLEX_FIELD);; + +let MOEBIUS_FUNCTION_NORM_LT_1 = prove + (`!t w z. norm w < &1 /\ norm z < &1 + ==> norm (moebius_function t w z) < &1`, + REPEAT STRIP_TAC THEN SUBGOAL_THEN + `!a. &0 <= a /\ &0 < &1 - a pow 2 ==> a < &1` MATCH_MP_TAC THENL + [GEN_TAC THEN ASM_CASES_TAC `&0 <= a` THEN + ASM_REWRITE_TAC [REAL_FIELD `&1 - a pow 2 = (&1 - a) * (&1 + a)`; + REAL_MUL_POS_LT] THEN + REAL_ARITH_TAC; + ALL_TAC] THEN + REWRITE_TAC [NORM_POS_LE] THEN + SUBGOAL_THEN `~(Cx (&1) - cnj w * z = Cx (&0))` ASSUME_TAC THENL + [REWRITE_TAC [COMPLEX_SUB_0] THEN + SUBGOAL_THEN `~(norm (Cx(&1)) = norm (cnj w * z))` + (fun th -> MESON_TAC [th]) THEN + REWRITE_TAC [COMPLEX_NORM_NUM; COMPLEX_NORM_MUL; COMPLEX_NORM_CNJ] THEN + MATCH_MP_TAC (REAL_ARITH `a * b < &1 ==> ~(&1 = a * b)`) THEN + STRIP_ASSUME_TAC (NORM_ARITH `norm (z:complex) = &0 \/ &0 < norm z`) THENL + [ASM_REWRITE_TAC [REAL_MUL_RZERO; REAL_LT_01]; + MATCH_MP_TAC REAL_LT_TRANS THEN EXISTS_TAC `&1 * norm (z:complex)` THEN + ASM_SIMP_TAC[REAL_LT_RMUL; REAL_MUL_LID]]; + ALL_TAC] THEN + SUBGOAL_THEN + `&1 - norm (moebius_function t w z) pow 2 = + ((&1 - norm w pow 2) / (norm (Cx(&1) - cnj w * z) pow 2)) * + (&1 - norm z pow 2)` + SUBST1_TAC THENL + [REWRITE_TAC [moebius_function; + GSYM CX_INJ; CX_SUB; CX_MUL; CX_DIV; CX_POW; CNJ_SUB; CNJ_CX; + CNJ_MUL; CNJ_DIV; CNJ_CNJ; COMPLEX_NORM_POW_2] THEN + SUBGOAL_THEN + `cnj (cexp (ii * Cx t)) * (cexp (ii * Cx t)) = Cx(&1) /\ + ~(Cx(&1) - cnj w * z = Cx(&0)) /\ ~(Cx(&1) - w * cnj z = Cx(&0))` + MP_TAC THENL [ALL_TAC; CONV_TAC COMPLEX_FIELD] THEN + REWRITE_TAC [CNJ_CEXP; CNJ_MUL; CNJ_II; CNJ_CX; + COMPLEX_MUL_LNEG; CEXP_NEG_LMUL] THEN ASM_REWRITE_TAC [] THEN + SUBGOAL_THEN `~(cnj (Cx (&1) - cnj w * z) = Cx (&0))` MP_TAC THENL + [ASM_REWRITE_TAC [CNJ_EQ_0]; + REWRITE_TAC [CNJ_SUB; CNJ_CX; CNJ_MUL; CNJ_CNJ]]; + SUBGOAL_THEN `!u:complex. norm u < &1 ==> &0 < &1 - norm u pow 2` + ASSUME_TAC THENL + [REWRITE_TAC [REAL_FIELD `!a. &1 - a pow 2 = (&1 - a) * (&1 + a)`] THEN + ASM_SIMP_TAC [REAL_LT_MUL; REAL_SUB_LT; REAL_LTE_ADD; REAL_LT_01; + NORM_POS_LE]; + SUBGOAL_THEN `&0 < norm (Cx (&1) - cnj w * z) pow 2` + (fun th -> ASM_MESON_TAC [th; REAL_LT_MUL; REAL_LT_DIV]) THEN + ASM_REWRITE_TAC [REAL_RING `!a:real. a pow 2 = a * a`; + REAL_LT_SQUARE; COMPLEX_NORM_ZERO]]]);; + +let MOEBIUS_FUNCTION_HOLOMORPHIC = prove + (`!t w. norm w < &1 ==> moebius_function t w holomorphic_on ball(Cx(&0),&1)`, + let LEMMA_1 = prove + (`!a b:complex. norm a < &1 /\ norm b < &1 ==> ~(Cx(&1) - a * b = Cx(&0))`, + GEN_TAC THEN GEN_TAC THEN STRIP_TAC THEN REWRITE_TAC [COMPLEX_SUB_0] THEN + SUBGOAL_THEN `~(norm (Cx(&1)) = norm (a * b))` + (fun th -> MESON_TAC[th]) THEN + REWRITE_TAC [COMPLEX_NORM_NUM; COMPLEX_NORM_MUL] THEN + MATCH_MP_TAC (REAL_ARITH `!x y. y < x ==> ~(x = y)`) THEN + ASM_CASES_TAC `b = Cx(&0)` THEN + ASM_REWRITE_TAC [COMPLEX_NORM_NUM; REAL_MUL_RZERO; REAL_LT_01] THEN + MATCH_MP_TAC REAL_LT_TRANS THEN EXISTS_TAC `&1 * norm (b:complex)` THEN + CONJ_TAC THENL + [MATCH_MP_TAC REAL_LT_RMUL THEN ASM_REWRITE_TAC [COMPLEX_NORM_NZ]; + ASM_REWRITE_TAC [REAL_MUL_LID]]) in + REPEAT STRIP_TAC THEN + SUBST1_TAC (GSYM (ISPEC `moebius_function t w` ETA_AX)) THEN + REWRITE_TAC [moebius_function] THEN + MATCH_MP_TAC HOLOMORPHIC_ON_MUL THEN CONJ_TAC THENL + [MATCH_MP_TAC (REWRITE_RULE [o_DEF] HOLOMORPHIC_ON_COMPOSE_GEN) THEN + EXISTS_TAC `(:complex)` THEN REWRITE_TAC [HOLOMORPHIC_ON_CEXP; IN_UNIV] THEN + SIMP_TAC [HOLOMORPHIC_ON_MUL; HOLOMORPHIC_ON_CONST]; + MATCH_MP_TAC HOLOMORPHIC_ON_DIV THEN + SIMP_TAC[HOLOMORPHIC_ON_SUB; HOLOMORPHIC_ON_CONST; + HOLOMORPHIC_ON_ID; HOLOMORPHIC_ON_MUL] THEN + ASM_SIMP_TAC[COMPLEX_IN_BALL_0; LEMMA_1; COMPLEX_NORM_CNJ]]);; + +let MOEBIUS_FUNCTION_COMPOSE = prove + (`!w1 w2 z. + -- w1 = w2 /\ norm w1 < &1 /\ norm z < &1 + ==> moebius_function (&0) w1 (moebius_function (&0) w2 z) = z`, + let LEMMA_1 = prove + (`!a b:complex. norm a < &1 /\ norm b < &1 + ==> ~(Cx(&1) - a * b = Cx(&0))`, + GEN_TAC THEN GEN_TAC THEN STRIP_TAC THEN REWRITE_TAC [COMPLEX_SUB_0] THEN + SUBGOAL_THEN `~(norm (Cx(&1)) = norm (a * b))` + (fun th -> MESON_TAC[th]) THEN + REWRITE_TAC [COMPLEX_NORM_NUM; COMPLEX_NORM_MUL] THEN + MATCH_MP_TAC (REAL_ARITH `!x y. y < x ==> ~(x = y)`) THEN + ASM_CASES_TAC `b = Cx(&0)` THEN + ASM_REWRITE_TAC [COMPLEX_NORM_NUM; REAL_MUL_RZERO; REAL_LT_01] THEN + MATCH_MP_TAC REAL_LT_TRANS THEN EXISTS_TAC `&1 * norm (b:complex)` THEN + CONJ_TAC THENL + [MATCH_MP_TAC REAL_LT_RMUL THEN ASM_REWRITE_TAC [COMPLEX_NORM_NZ]; + ASM_REWRITE_TAC [REAL_MUL_LID]]) in + let LEMMA_1_ALT = prove + (`!a b:complex. norm a < &1 /\ norm b < &1 + ==> ~(Cx(&1) + a * b = Cx(&0))`, + REPEAT GEN_TAC THEN STRIP_TAC THEN + SUBST1_TAC (COMPLEX_RING `a : complex = -- (-- a)`) THEN + ABBREV_TAC `u : complex= -- a` THEN + REWRITE_TAC [COMPLEX_MUL_LNEG; GSYM complex_sub] THEN + MATCH_MP_TAC LEMMA_1 THEN EXPAND_TAC "u" THEN + ASM_REWRITE_TAC[NORM_NEG]) in + REPEAT STRIP_TAC THEN + SUBGOAL_THEN `norm (w2:complex) < &1` ASSUME_TAC THENL + [EXPAND_TAC "w2" THEN ASM_REWRITE_TAC [NORM_NEG]; ALL_TAC] THEN + REWRITE_TAC [moebius_function; COMPLEX_MUL_RZERO; + CEXP_0; COMPLEX_MUL_LID] THEN + MATCH_MP_TAC (COMPLEX_FIELD + `!a b c. ~(b = Cx(&0)) /\ a = b * c ==> a / b = c`) THEN + CONJ_TAC THENL + [ALL_TAC; MP_TAC (SPECL [`cnj w2`;`z:complex`] LEMMA_1) THEN + ASM_REWRITE_TAC [COMPLEX_NORM_CNJ] THEN EXPAND_TAC "w2" THEN + REWRITE_TAC [CNJ_NEG] THEN CONV_TAC COMPLEX_FIELD] THEN + MATCH_MP_TAC (COMPLEX_FIELD + `!a b c d. ~(d = Cx(&0)) /\ ~(d * a - b * c = Cx(&0)) + ==> ~(a - b * c / d = Cx(&0))`) THEN + ASM_SIMP_TAC [LEMMA_1; COMPLEX_NORM_CNJ] THEN + ASM_REWRITE_TAC [COMPLEX_MUL_RID] THEN + SUBGOAL_THEN + `Cx(&1) - cnj w2 * z - cnj w1 * (z - w2) = + Cx(&1) + cnj w1 * w2` SUBST1_TAC THENL + [EXPAND_TAC "w2" THEN REWRITE_TAC [CNJ_NEG] THEN CONV_TAC COMPLEX_RING; + ASM_SIMP_TAC [LEMMA_1_ALT; COMPLEX_NORM_CNJ]]);; + +let BALL_BIHOLOMORPHISM_EXISTS = prove + (`!a. a IN ball(Cx(&0),&1) + ==> ?f g. f(a) = Cx(&0) /\ + f holomorphic_on ball (Cx(&0),&1) /\ + (!z. z IN ball (Cx(&0),&1) ==> f z IN ball (Cx(&0),&1)) /\ + g holomorphic_on ball (Cx(&0),&1) /\ + (!z. z IN ball (Cx(&0),&1) ==> g z IN ball (Cx(&0),&1)) /\ + (!z. z IN ball (Cx(&0),&1) ==> f (g z) = z) /\ + (!z. z IN ball (Cx(&0),&1) ==> g (f z) = z)`, + REWRITE_TAC[COMPLEX_IN_BALL_0] THEN REPEAT STRIP_TAC THEN + EXISTS_TAC `moebius_function (&0) a` THEN + EXISTS_TAC `moebius_function (&0) (--a)` THEN + ASM_SIMP_TAC[COMPLEX_IN_BALL_0; MOEBIUS_FUNCTION_COMPOSE; COMPLEX_NEG_NEG; + NORM_NEG] THEN + ASM_SIMP_TAC[MOEBIUS_FUNCTION_NORM_LT_1; NORM_NEG; + MOEBIUS_FUNCTION_HOLOMORPHIC; MOEBIUS_FUNCTION_EQ_ZERO]);; + +let BALL_BIHOLOMORPHISM_MOEBIUS_FUNCTION = prove + (`!f g. + f holomorphic_on ball (Cx(&0),&1) /\ + (!z. z IN ball (Cx(&0),&1) ==> f z IN ball (Cx(&0),&1)) /\ + g holomorphic_on ball (Cx(&0),&1) /\ + (!z. z IN ball (Cx(&0),&1) ==> g z IN ball (Cx(&0),&1)) /\ + (!z. z IN ball (Cx(&0),&1) ==> f (g z) = z) /\ + (!z. z IN ball (Cx(&0),&1) ==> g (f z) = z) + ==> ?t w. w IN ball (Cx(&0),&1) /\ + (!z. z IN ball (Cx(&0),&1) ==> f z = moebius_function t w z)`, + let LEMMA_1 = prove + (`!a b:complex. norm a < &1 /\ norm b < &1 + ==> ~(Cx(&1) - a * b = Cx(&0))`, + GEN_TAC THEN GEN_TAC THEN STRIP_TAC THEN REWRITE_TAC [COMPLEX_SUB_0] THEN + SUBGOAL_THEN `~(norm (Cx(&1)) = norm (a * b))` + (fun th -> MESON_TAC[th]) THEN + REWRITE_TAC [COMPLEX_NORM_NUM; COMPLEX_NORM_MUL] THEN + MATCH_MP_TAC (REAL_ARITH `!x y. y < x ==> ~(x = y)`) THEN + ASM_CASES_TAC `b = Cx(&0)` THEN + ASM_REWRITE_TAC [COMPLEX_NORM_NUM; REAL_MUL_RZERO; REAL_LT_01] THEN + MATCH_MP_TAC REAL_LT_TRANS THEN EXISTS_TAC `&1 * norm (b:complex)` THEN + CONJ_TAC THENL + [MATCH_MP_TAC REAL_LT_RMUL THEN ASM_REWRITE_TAC [COMPLEX_NORM_NZ]; + ASM_REWRITE_TAC [REAL_MUL_LID]]) in + let LEMMA_2 = prove + (`!t w s z. norm w < &1 /\ norm z < &1 + ==> moebius_function t w (cexp (ii * Cx s) * z) = + moebius_function (t + s) (cexp (-- (ii * Cx s)) * w) z`, + REPEAT STRIP_TAC THEN + REWRITE_TAC[moebius_function; CX_ADD; COMPLEX_ADD_LDISTRIB; CEXP_ADD; + GSYM COMPLEX_MUL_ASSOC; COMPLEX_EQ_MUL_LCANCEL; CEXP_NZ; + CNJ_MUL] THEN + MATCH_MP_TAC (COMPLEX_FIELD + `!a b c d e. ~(b = Cx(&0)) /\ ~(e = Cx(&0)) /\ e * a = b * c * d + ==> a / b = c * d / e`) THEN CONJ_TAC THENL + [MATCH_MP_TAC LEMMA_1 THEN + ASM_REWRITE_TAC [COMPLEX_NORM_CNJ; COMPLEX_NORM_MUL; NORM_CEXP_II; + REAL_MUL_LID]; + ALL_TAC] THEN + CONJ_TAC THENL + [REWRITE_TAC [COMPLEX_MUL_ASSOC] THEN MATCH_MP_TAC LEMMA_1 THEN + ASM_REWRITE_TAC [COMPLEX_NORM_MUL; COMPLEX_NORM_CNJ; COMPLEX_NEG_RMUL; + GSYM CX_NEG; NORM_CEXP_II; REAL_MUL_LID]; + REWRITE_TAC [CNJ_CEXP; CNJ_NEG; CNJ_MUL; CNJ_II; CNJ_CX; + COMPLEX_MUL_LNEG; COMPLEX_NEG_NEG; CEXP_NEG] THEN + ABBREV_TAC `a = cexp (ii * Cx s)` THEN + SUBGOAL_THEN `inv a * a = Cx(&1)` MP_TAC THENL + [ALL_TAC; CONV_TAC COMPLEX_RING] THEN + MATCH_MP_TAC COMPLEX_MUL_LINV THEN EXPAND_TAC "a" THEN + REWRITE_TAC [CEXP_NZ]]) in + REWRITE_TAC [COMPLEX_IN_BALL_0] THEN REPEAT STRIP_TAC THEN + ABBREV_TAC `w:complex = f (Cx(&0))` THEN + SUBGOAL_THEN `norm(w:complex) < &1` ASSUME_TAC THENL + [ASM_MESON_TAC [COMPLEX_NORM_NUM; REAL_LT_01]; ALL_TAC] THEN + SUBGOAL_THEN + `?t. !z. z IN ball (Cx(&0),&1) + ==> moebius_function (&0) w (f z) = cexp (ii * Cx t) * z` + STRIP_ASSUME_TAC THENL + [ALL_TAC; + EXISTS_TAC `t:real` THEN EXISTS_TAC `-- (cexp(-- (ii * Cx t)) * w)` THEN + ASM_REWRITE_TAC [NORM_NEG; COMPLEX_NORM_MUL; COMPLEX_NEG_RMUL; + GSYM CX_NEG; NORM_CEXP_II; REAL_MUL_LID] THEN + GEN_TAC THEN DISCH_TAC THEN EQ_TRANS_TAC + `moebius_function (&0) (--w) + (moebius_function (&0) w (f (z:complex)))` THENL + [MATCH_MP_TAC EQ_SYM THEN MATCH_MP_TAC MOEBIUS_FUNCTION_COMPOSE THEN + ASM_SIMP_TAC [COMPLEX_NEG_NEG; NORM_NEG]; + ASM_SIMP_TAC[COMPLEX_IN_BALL_0] THEN ASM_SIMP_TAC[LEMMA_2; NORM_NEG] THEN + REWRITE_TAC [REAL_ADD_LID; CX_NEG; COMPLEX_MUL_RNEG]]] THEN + MATCH_MP_TAC SECOND_CARTAN_THM_DIM_1 THEN EXISTS_TAC + `\z. g (moebius_function (&0) (--w) z) : complex` THEN + REWRITE_TAC [COMPLEX_IN_BALL_0] THEN REWRITE_TAC [REAL_LT_01] THEN + CONJ_TAC THENL + [MATCH_MP_TAC (REWRITE_RULE [o_DEF] HOLOMORPHIC_ON_COMPOSE_GEN) THEN + EXISTS_TAC `ball(Cx(&0),&1)` THEN + ASM_SIMP_TAC [ETA_AX; MOEBIUS_FUNCTION_HOLOMORPHIC; COMPLEX_IN_BALL_0]; + ALL_TAC] THEN CONJ_TAC THENL [ASM_SIMP_TAC [MOEBIUS_FUNCTION_NORM_LT_1]; + ALL_TAC] THEN + CONJ_TAC THENL [ASM_REWRITE_TAC [MOEBIUS_FUNCTION_EQ_ZERO]; ALL_TAC] THEN + CONJ_TAC THENL + [MATCH_MP_TAC (REWRITE_RULE [o_DEF] HOLOMORPHIC_ON_COMPOSE_GEN) THEN + EXISTS_TAC `ball(Cx(&0),&1)` THEN + ASM_SIMP_TAC [COMPLEX_IN_BALL_0; MOEBIUS_FUNCTION_NORM_LT_1; + NORM_NEG] THEN + ASM_SIMP_TAC [ETA_AX; MOEBIUS_FUNCTION_HOLOMORPHIC; NORM_NEG]; + ALL_TAC] THEN CONJ_TAC THENL + [ASM_SIMP_TAC [MOEBIUS_FUNCTION_NORM_LT_1; NORM_NEG]; ALL_TAC] THEN + CONJ_TAC THENL + [ASM_REWRITE_TAC [MOEBIUS_FUNCTION_OF_ZERO; COMPLEX_MUL_RZERO; CEXP_0; + GSYM COMPLEX_NEG_LMUL; COMPLEX_MUL_LID; + COMPLEX_NEG_NEG] THEN + ASM_MESON_TAC [COMPLEX_NORM_0; REAL_LT_01]; + ALL_TAC] THEN CONJ_TAC THENL + [ALL_TAC; + ASM_SIMP_TAC [REWRITE_RULE [COMPLEX_NEG_NEG; NORM_NEG] + (SPECL [`--w:complex`;`w:complex`] MOEBIUS_FUNCTION_COMPOSE)]] THEN + REPEAT STRIP_TAC THEN SUBGOAL_THEN + `f (g (moebius_function (&0) (--w) z) : complex) = + (moebius_function (&0) (--w) z)` + SUBST1_TAC THENL + [FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_SIMP_TAC [MOEBIUS_FUNCTION_NORM_LT_1; NORM_NEG]; + MATCH_MP_TAC MOEBIUS_FUNCTION_COMPOSE THEN ASM_REWRITE_TAC []]);; + +(* ------------------------------------------------------------------------- *) +(* Some simple but useful cases of Hurwitz's theorem. *) +(* ------------------------------------------------------------------------- *) + +let HURWITZ_NO_ZEROS = prove + (`!f:num->complex->complex g s. + open s /\ connected s /\ + (!n. (f n) holomorphic_on s) /\ g holomorphic_on s /\ + (!k e. compact k /\ k SUBSET s /\ &0 < e + ==> ?N. !n x. n >= N /\ x IN k ==> norm(f n x - g x) < e) /\ + ~(?c. !z. z IN s ==> g z = c) /\ + (!n z. z IN s ==> ~(f n z = Cx(&0))) + ==> (!z. z IN s ==> ~(g z = Cx(&0)))`, + REPEAT GEN_TAC THEN STRIP_TAC THEN X_GEN_TAC `z0:complex` THEN + REPEAT DISCH_TAC THEN + MP_TAC(ISPECL [`g:complex->complex`; `s:complex->bool`; `z0:complex`] + HOLOMORPHIC_FACTOR_ZERO_NONCONSTANT) THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[NOT_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`h:complex->complex`; `r:real`; `m:num`] THEN + STRIP_TAC THEN + MP_TAC(ISPECL + [`sequentially`; `\n:num z. complex_derivative (f n) z / f n z`; + `\z. complex_derivative g z / g z`; `z0:complex`; `r / &2`] + PATH_INTEGRAL_UNIFORM_LIMIT_CIRCLEPATH) THEN + ASM_REWRITE_TAC[REAL_HALF; TRIVIAL_LIMIT_SEQUENTIALLY; NOT_IMP] THEN + SUBGOAL_THEN + `!n:num. ((\z. complex_derivative (f n) z / f n z) + has_path_integral (Cx(&0))) (circlepath(z0,r / &2))` + ASSUME_TAC THENL + [X_GEN_TAC `n:num` THEN MATCH_MP_TAC CAUCHY_THEOREM_DISC_SIMPLE THEN + MAP_EVERY EXISTS_TAC [`z0:complex`; `r:real`] THEN + ASM_SIMP_TAC[VALID_PATH_CIRCLEPATH; PATHSTART_CIRCLEPATH; + PATHFINISH_CIRCLEPATH; PATH_IMAGE_CIRCLEPATH; + REAL_HALF; REAL_LT_IMP_LE] THEN + REWRITE_TAC[sphere; NORM_ARITH `dist(z,w) = norm(w - z)`] THEN + REWRITE_TAC[SUBSET; IN_BALL; ONCE_REWRITE_RULE[DIST_SYM] dist] THEN + ASM_SIMP_TAC[IN_ELIM_THM; REAL_ARITH `&0 < r ==> r / &2 < r`] THEN + MATCH_MP_TAC HOLOMORPHIC_ON_DIV THEN REPEAT CONJ_TAC THENL + [REWRITE_TAC[ETA_AX] THEN MATCH_MP_TAC HOLOMORPHIC_COMPLEX_DERIVATIVE THEN + REWRITE_TAC[OPEN_BALL]; + REWRITE_TAC[ETA_AX]; + ASM_MESON_TAC[SUBSET]] THEN + ASM_MESON_TAC[HOLOMORPHIC_ON_SUBSET]; + ALL_TAC] THEN + REPEAT CONJ_TAC THENL + [MATCH_MP_TAC ALWAYS_EVENTUALLY THEN + REWRITE_TAC[path_integrable_on] THEN ASM_MESON_TAC[]; + MATCH_MP_TAC UNIFORM_LIM_COMPLEX_DIV THEN + REWRITE_TAC[LEFT_EXISTS_AND_THM; CONJ_ASSOC] THEN + REWRITE_TAC[RIGHT_EXISTS_AND_THM; GSYM CONJ_ASSOC] THEN + REWRITE_TAC[LEFT_EXISTS_AND_THM] THEN + + ASM_SIMP_TAC[PATH_IMAGE_CIRCLEPATH; REAL_HALF; REAL_LT_IMP_LE] THEN + REWRITE_TAC[sphere; NORM_ARITH `dist(z,w) = norm(w - z)`] THEN + REWRITE_TAC[IN_ELIM_THM] THEN REPEAT CONJ_TAC THENL + [MP_TAC(ISPEC `IMAGE (complex_derivative g) {w | norm(w - z0) = r / &2}` + COMPACT_IMP_BOUNDED) THEN + ANTS_TAC THENL + [MATCH_MP_TAC COMPACT_CONTINUOUS_IMAGE THEN + REWRITE_TAC[o_DEF; + REWRITE_RULE[sphere; NORM_ARITH `dist(w:real^N,z) = norm(z - w)`] + COMPACT_SPHERE] THEN + MATCH_MP_TAC HOLOMORPHIC_ON_IMP_CONTINUOUS_ON THEN + MATCH_MP_TAC HOLOMORPHIC_ON_SUBSET THEN + EXISTS_TAC `s:complex->bool` THEN + ASM_SIMP_TAC[HOLOMORPHIC_COMPLEX_DERIVATIVE] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ_ALT] + SUBSET_TRANS)) THEN + REWRITE_TAC[SUBSET; IN_BALL; IN_ELIM_THM] THEN + UNDISCH_TAC `&0 < r` THEN CONV_TAC NORM_ARITH; + REWRITE_TAC[bounded; FORALL_IN_IMAGE; IN_ELIM_THM] THEN + MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC THEN DISCH_TAC THEN + MATCH_MP_TAC ALWAYS_EVENTUALLY THEN ASM_SIMP_TAC[]]; + MP_TAC(ISPEC `IMAGE (norm o (g:complex->complex)) + {w | norm(w - z0) = r / &2}` + COMPACT_ATTAINS_INF) THEN + REWRITE_TAC[EXISTS_IN_IMAGE; FORALL_IN_IMAGE; IMAGE_EQ_EMPTY] THEN + REWRITE_TAC[GSYM IMAGE_o; FORALL_IN_GSPEC; EXISTS_IN_GSPEC; o_THM] THEN + ANTS_TAC THENL + [CONJ_TAC THENL + [MATCH_MP_TAC COMPACT_CONTINUOUS_IMAGE THEN + REWRITE_TAC[o_DEF; + REWRITE_RULE[sphere; NORM_ARITH `dist(w:real^N,z) = norm(z - w)`] + COMPACT_SPHERE] THEN + MATCH_MP_TAC CONTINUOUS_ON_LIFT_NORM_COMPOSE THEN + MATCH_MP_TAC HOLOMORPHIC_ON_IMP_CONTINUOUS_ON THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + HOLOMORPHIC_ON_SUBSET)) THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ_ALT] + SUBSET_TRANS)) THEN + REWRITE_TAC[SUBSET; IN_BALL; IN_ELIM_THM] THEN + UNDISCH_TAC `&0 < r` THEN CONV_TAC NORM_ARITH; + REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; IN_ELIM_THM] THEN + EXISTS_TAC `z0 + Cx(r / &2)` THEN + REWRITE_TAC[VECTOR_ARITH `(a + b) - a:real^N = b`] THEN + REWRITE_TAC[COMPLEX_NORM_CX] THEN ASM_REAL_ARITH_TAC]; + DISCH_THEN(X_CHOOSE_THEN `ww:complex` MP_TAC) THEN + STRIP_TAC THEN EXISTS_TAC `norm((g:complex->complex) ww)` THEN + ASM_SIMP_TAC[ALWAYS_EVENTUALLY; COMPLEX_NORM_NZ] THEN + DISCH_THEN(ASSUME_TAC o REWRITE_RULE[COMPLEX_NORM_ZERO]) THEN + UNDISCH_TAC `!w. w IN ball(z0,r) ==> g w = (w - z0) pow m * h w` THEN + DISCH_THEN(MP_TAC o SPEC `ww:complex`) THEN + CONV_TAC(ONCE_DEPTH_CONV SYM_CONV) THEN + ASM_SIMP_TAC[COMPLEX_ENTIRE; COMPLEX_POW_EQ_0] THEN + REWRITE_TAC[IN_BALL; GSYM COMPLEX_NORM_ZERO] THEN + ASM_REWRITE_TAC[ONCE_REWRITE_RULE[DIST_SYM] dist] THEN + ASM_REAL_ARITH_TAC]; + X_GEN_TAC `e:real` THEN DISCH_TAC THEN + FIRST_ASSUM(MP_TAC o SPECL + [`cball(z0:complex,&3 * r / &4)`; `r / &4 * e / &2`]) THEN + REWRITE_TAC[COMPACT_CBALL] THEN ANTS_TAC THENL + [ASM_SIMP_TAC[REAL_LT_MUL; REAL_LT_DIV; REAL_OF_NUM_LT; ARITH] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ_ALT] + SUBSET_TRANS)) THEN + REWRITE_TAC[SUBSET; IN_BALL; IN_CBALL; IN_ELIM_THM] THEN + UNDISCH_TAC `&0 < r` THEN CONV_TAC NORM_ARITH; + REWRITE_TAC[GE; EVENTUALLY_SEQUENTIALLY; IN_CBALL; dist] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `N:num` THEN + MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `n:num` THEN + DISCH_THEN(fun th -> DISCH_TAC THEN MP_TAC th) THEN + ASM_REWRITE_TAC[] THEN DISCH_TAC] THEN + X_GEN_TAC `w:complex` THEN DISCH_TAC THEN + MP_TAC(ISPECL + [`\z. (f:num->complex->complex) n z - g z`; + `w:complex`; `Cx(&0)`; `r / &4`; `r / &4 * e / &2`; `1`] + CAUCHY_HIGHER_COMPLEX_DERIVATIVE_BOUND) THEN + REWRITE_TAC[HIGHER_COMPLEX_DERIVATIVE_1; COMPLEX_IN_BALL_0] THEN + ANTS_TAC THENL + [CONJ_TAC THENL [ASM_REAL_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV] THEN + REPEAT CONJ_TAC THENL + [ALL_TAC; + MATCH_MP_TAC HOLOMORPHIC_ON_IMP_CONTINUOUS_ON; + X_GEN_TAC `y:complex` THEN REWRITE_TAC[IN_BALL] THEN + DISCH_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + MAP_EVERY UNDISCH_TAC + [`norm(w - z0:complex) = r / &2`; `dist(w:complex,y) < r / &4`] THEN + CONV_TAC NORM_ARITH] THEN + (MATCH_MP_TAC HOLOMORPHIC_ON_SUB THEN + CONJ_TAC THEN MATCH_MP_TAC HOLOMORPHIC_ON_SUBSET THEN + EXISTS_TAC `s:complex->bool` THEN ASM_REWRITE_TAC[ETA_AX] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ_ALT] + SUBSET_TRANS)) THEN + REWRITE_TAC[SUBSET; IN_BALL; IN_CBALL; IN_ELIM_THM] THEN + UNDISCH_TAC `norm(w - z0:complex) = r / &2` THEN + UNDISCH_TAC `&0 < r` THEN CONV_TAC NORM_ARITH); + CONV_TAC NUM_REDUCE_CONV THEN + ASM_SIMP_TAC[REAL_FIELD + `&0 < r /\ &0 < e + ==> &1 * (r / &4 * e / &2) / (r / &4) pow 1 = e / &2`] THEN + MATCH_MP_TAC(NORM_ARITH + `x = y /\ &0 < e ==> norm(x) <= e / &2 ==> norm(y) < e`) THEN + ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC COMPLEX_DERIVATIVE_SUB THEN CONJ_TAC THEN + MATCH_MP_TAC HOLOMORPHIC_ON_IMP_DIFFERENTIABLE_AT THEN + EXISTS_TAC `s:complex->bool` THEN ASM_REWRITE_TAC[] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o GEN_REWRITE_RULE I [SUBSET]) THEN + ASM_REWRITE_TAC[IN_BALL; ONCE_REWRITE_RULE[DIST_SYM] dist] THEN + ASM_REAL_ARITH_TAC]; + X_GEN_TAC `e:real` THEN DISCH_TAC THEN + REWRITE_TAC[EVENTUALLY_SEQUENTIALLY] THEN + FIRST_X_ASSUM(MP_TAC o SPECL + [`{w:complex | norm(w - z0) = r / &2}`; `e:real`]) THEN + ASM_REWRITE_TAC[GE; IN_ELIM_THM; + REWRITE_RULE[sphere; NORM_ARITH `dist(w:real^N,z) = norm(z - w)`] + COMPACT_SPHERE] THEN + ANTS_TAC THENL [ALL_TAC; MESON_TAC[]] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ_ALT] + SUBSET_TRANS)) THEN + REWRITE_TAC[SUBSET; IN_BALL; IN_ELIM_THM] THEN + UNDISCH_TAC `&0 < r` THEN CONV_TAC NORM_ARITH]; + FIRST_ASSUM(ASSUME_TAC o GEN `n:num` o MATCH_MP PATH_INTEGRAL_UNIQUE o + SPEC `n:num`) THEN + DISCH_THEN(MP_TAC o CONJUNCT2) THEN + ASM_REWRITE_TAC[LIM_CONST_EQ; TRIVIAL_LIMIT_SEQUENTIALLY] THEN + MATCH_MP_TAC(COMPLEX_RING + `!q r. p = q /\ q = r /\ ~(r = Cx(&0)) ==> ~(Cx(&0) = p)`) THEN + MAP_EVERY EXISTS_TAC + [`path_integral (circlepath(z0,r / &2)) + (\z. Cx(&m) / (z - z0) + + complex_derivative h z / h z)`; + `Cx(&2) * Cx pi * ii * Cx(&m)`] THEN + REPEAT CONJ_TAC THENL + [MATCH_MP_TAC PATH_INTEGRAL_EQ THEN X_GEN_TAC `w:complex` THEN + ASM_SIMP_TAC[PATH_IMAGE_CIRCLEPATH; IN_ELIM_THM; REAL_HALF; + REAL_LT_IMP_LE; sphere; NORM_ARITH `dist(z,w) = norm(w - z)`] THEN + ASM_CASES_TAC `w:complex = z0` THEN + ASM_REWRITE_TAC[VECTOR_SUB_REFL; NORM_0] THENL + [ASM_REAL_ARITH_TAC; DISCH_TAC] THEN + SUBGOAL_THEN `w IN ball(z0:complex,r)` ASSUME_TAC THENL + [REWRITE_TAC[IN_BALL] THEN + MAP_EVERY UNDISCH_TAC [`norm (w - z0) = r / &2`; `&0 < r`] THEN + CONV_TAC NORM_ARITH; + ALL_TAC] THEN + ASM_SIMP_TAC[] THEN + ASM_SIMP_TAC[COMPLEX_ENTIRE; COMPLEX_POW_EQ_0; COMPLEX_SUB_0; + COMPLEX_FIELD `~(y = Cx(&0)) ==> (x / y = w <=> x = y * w)`] THEN + ASM_SIMP_TAC[COMPLEX_FIELD + `~(h = Cx(&0)) ==> (m * h) * (x + y / h) = m * y + m * h * x`] THEN + MATCH_MP_TAC HAS_COMPLEX_DERIVATIVE_DERIVATIVE THEN + MATCH_MP_TAC HAS_COMPLEX_DERIVATIVE_TRANSFORM_WITHIN_OPEN THEN + EXISTS_TAC `\w:complex. (w - z0) pow m * h w` THEN + EXISTS_TAC `ball(z0:complex,r)` THEN ASM_SIMP_TAC[OPEN_BALL] THEN + SUBGOAL_THEN + `(w - z0) pow m * h w * Cx(&m) / (w - z0) = + (Cx(&m) * (w - z0) pow (m - 1)) * h w` + SUBST1_TAC THENL + [MATCH_MP_TAC(COMPLEX_FIELD + `w * mm = z /\ ~(w = Cx(&0)) + ==> z * h * m / w = (m * mm) * h`) THEN + ASM_REWRITE_TAC[COMPLEX_SUB_0; GSYM(CONJUNCT2 complex_pow)] THEN + AP_TERM_TAC THEN ASM_ARITH_TAC; + MATCH_MP_TAC HAS_COMPLEX_DERIVATIVE_MUL_AT THEN CONJ_TAC THENL + [COMPLEX_DIFF_TAC THEN CONV_TAC COMPLEX_RING; + REWRITE_TAC[HAS_COMPLEX_DERIVATIVE_DIFFERENTIABLE] THEN + ASM_MESON_TAC[HOLOMORPHIC_ON_IMP_DIFFERENTIABLE_AT; OPEN_BALL]]]; + GEN_REWRITE_TAC RAND_CONV [GSYM COMPLEX_ADD_RID] THEN + MATCH_MP_TAC PATH_INTEGRAL_UNIQUE THEN + MATCH_MP_TAC HAS_PATH_INTEGRAL_ADD THEN CONJ_TAC THENL + [MATCH_MP_TAC CAUCHY_INTEGRAL_CIRCLEPATH_SIMPLE THEN + ASM_REWRITE_TAC[CENTRE_IN_BALL; REAL_HALF; HOLOMORPHIC_ON_CONST]; + MATCH_MP_TAC CAUCHY_THEOREM_DISC_SIMPLE THEN + MAP_EVERY EXISTS_TAC [`z0:complex`; `r:real`] THEN + ASM_SIMP_TAC[VALID_PATH_CIRCLEPATH; PATHSTART_CIRCLEPATH; + PATHFINISH_CIRCLEPATH; PATH_IMAGE_CIRCLEPATH; + REAL_HALF; REAL_LT_IMP_LE] THEN + REWRITE_TAC[sphere; NORM_ARITH `dist(z,w) = norm(w - z)`] THEN + REWRITE_TAC[SUBSET; IN_BALL; ONCE_REWRITE_RULE[DIST_SYM] dist] THEN + ASM_SIMP_TAC[IN_ELIM_THM; REAL_ARITH `&0 < r ==> r / &2 < r`] THEN + MATCH_MP_TAC HOLOMORPHIC_ON_DIV THEN ASM_REWRITE_TAC[ETA_AX] THEN + MATCH_MP_TAC HOLOMORPHIC_COMPLEX_DERIVATIVE THEN + ASM_REWRITE_TAC[OPEN_BALL]]; + REWRITE_TAC[COMPLEX_ENTIRE; CX_INJ; PI_NZ; II_NZ; REAL_OF_NUM_EQ] THEN + ASM_SIMP_TAC[LE_1; ARITH_EQ] THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_REWRITE_TAC[CENTRE_IN_BALL]]]);; + +let HURWITZ_INJECTIVE = prove + (`!f:num->complex->complex g s. + open s /\ connected s /\ + (!n. (f n) holomorphic_on s) /\ g holomorphic_on s /\ + (!k e. compact k /\ k SUBSET s /\ &0 < e + ==> ?N. !n x. n >= N /\ x IN k ==> norm(f n x - g x) < e) /\ + ~(?c. !z. z IN s ==> g z = c) /\ + (!n w z. w IN s /\ z IN s /\ f n w = f n z ==> w = z) + ==> (!w z. w IN s /\ z IN s /\ g w = g z ==> w = z)`, + REPEAT GEN_TAC THEN STRIP_TAC THEN + MAP_EVERY X_GEN_TAC [`z1:complex`; `z2:complex`] THEN + REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN REPEAT DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [NOT_EXISTS_THM]) THEN + DISCH_THEN(MP_TAC o SPEC `(g:complex->complex) z2`) THEN + REWRITE_TAC[] THEN X_GEN_TAC `z0:complex` THEN + ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN REPEAT DISCH_TAC THEN + RULE_ASSUM_TAC(REWRITE_RULE[MESON[] + `(!x y. x IN s /\ y IN s /\ g x = g y ==> x = y) <=> + (!x y. x IN s /\ y IN s ==> (g x = g y <=> x = y))`]) THEN + MP_TAC(ISPECL + [`\z. (g:complex->complex) z - g z1`; `s:complex->bool`; + `z2:complex`; `z0:complex`] + ISOLATED_ZEROS) THEN + ASM_SIMP_TAC[COMPLEX_SUB_0; HOLOMORPHIC_ON_SUB; HOLOMORPHIC_ON_ID; + HOLOMORPHIC_ON_CONST] THEN + DISCH_THEN(X_CHOOSE_THEN `r:real` STRIP_ASSUME_TAC) THEN + MP_TAC(ISPECL + [`\n z. (f:num->complex->complex) n z - f n z1`; + `\z. (g:complex->complex) z - g z1`; `s DELETE (z1:complex)`] + HURWITZ_NO_ZEROS) THEN + REWRITE_TAC[NOT_IMP; COMPLEX_SUB_0] THEN REPEAT CONJ_TAC THENL + [ASM_SIMP_TAC[OPEN_DELETE]; + ASM_SIMP_TAC[CONNECTED_OPEN_DELETE; DIMINDEX_2; LE_REFL]; + GEN_TAC THEN MATCH_MP_TAC HOLOMORPHIC_ON_SUBSET THEN + EXISTS_TAC `s:complex->bool` THEN + ASM_SIMP_TAC[HOLOMORPHIC_ON_SUB; ETA_AX; HOLOMORPHIC_ON_CONST] THEN + SET_TAC[]; + MATCH_MP_TAC HOLOMORPHIC_ON_SUBSET THEN + EXISTS_TAC `s:complex->bool` THEN + ASM_SIMP_TAC[HOLOMORPHIC_ON_SUB; ETA_AX; HOLOMORPHIC_ON_CONST] THEN + SET_TAC[]; + MAP_EVERY X_GEN_TAC [`k:complex->bool`; `e:real`] THEN STRIP_TAC THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP (SET_RULE + `k SUBSET s DELETE z ==> k SUBSET s`)) THEN + FIRST_X_ASSUM(fun th -> + MP_TAC(SPECL [`k:complex->bool`; `e / &2`] th) THEN + MP_TAC(SPECL [`{z1:complex}`; `e / &2`] th)) THEN + ASM_REWRITE_TAC[COMPACT_SING; SING_SUBSET; REAL_HALF] THEN + SIMP_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; IN_SING; FORALL_UNWIND_THM2] THEN + REWRITE_TAC[IMP_IMP; RIGHT_IMP_FORALL_THM] THEN DISCH_THEN(CONJUNCTS_THEN2 + (X_CHOOSE_TAC `N1:num`) (X_CHOOSE_TAC `N2:num`)) THEN + EXISTS_TAC `MAX N1 N2` THEN REPEAT STRIP_TAC THEN + UNDISCH_THEN `(g:complex->complex) z1 = g z2` (SUBST1_TAC o SYM) THEN + MATCH_MP_TAC(NORM_ARITH + `norm(x1 - x2) < e / &2 /\ norm(y1 - y2) < e / &2 + ==> norm(x1 - y1 - (x2 - y2)) < e`) THEN + ASM_MESON_TAC[ARITH_RULE `x >= MAX m n <=> x >= m /\ x >= n`]; + REWRITE_TAC[IN_DELETE; COMPLEX_EQ_SUB_RADD] THEN DISCH_THEN(CHOOSE_THEN + (fun th -> MAP_EVERY (MP_TAC o C SPEC th) + [`z0:complex`; `z1:complex`; `z2:complex`])) THEN + ASM_MESON_TAC[]; + REWRITE_TAC[IN_DELETE] THEN ASM_MESON_TAC[]; + REWRITE_TAC[IN_DELETE] THEN ASM_MESON_TAC[]]);; + +(* ------------------------------------------------------------------------- *) +(* A big chain of equivalents of simple connectedness for an open set. *) +(* ------------------------------------------------------------------------- *) + +let [SIMPLY_CONNECTED_EQ_WINDING_NUMBER_ZERO; + SIMPLY_CONNECTED_EQ_PATH_INTEGRAL_ZERO; + SIMPLY_CONNECTED_EQ_GLOBAL_PRIMITIVE; + SIMPLY_CONNECTED_EQ_HOLOMORPHIC_LOG; + SIMPLY_CONNECTED_EQ_HOLOMORPHIC_SQRT; + SIMPLY_CONNECTED_EQ_INJECTIVE_HOLOMORPHIC_SQRT; + SIMPLY_CONNECTED_EQ_BIHOLOMORPHIC_TO_DISC; + SIMPLY_CONNECTED_EQ_HOMEOMORPHIC_TO_DISC] = + (CONJUNCTS o prove) + (`(!s. open s + ==> (simply_connected s <=> + connected s /\ + !g z. path g /\ path_image g SUBSET s /\ + pathfinish g = pathstart g /\ ~(z IN s) + ==> winding_number(g,z) = Cx(&0))) /\ + (!s. open s + ==> (simply_connected s <=> + connected s /\ + !g f. valid_path g /\ path_image g SUBSET s /\ + pathfinish g = pathstart g /\ f holomorphic_on s + ==> (f has_path_integral Cx(&0)) g)) /\ + (!s. open s + ==> (simply_connected s <=> + connected s /\ + !f. f holomorphic_on s + ==> ?h. !z. z IN s + ==> (h has_complex_derivative f(z)) (at z))) /\ + (!s. open s + ==> (simply_connected s <=> + connected s /\ + !f. f holomorphic_on s /\ (!z. z IN s ==> ~(f z = Cx(&0))) + ==> ?g. g holomorphic_on s /\ + !z. z IN s ==> f z = cexp(g z))) /\ + (!s. open s + ==> (simply_connected s <=> + connected s /\ + !f. f holomorphic_on s /\ (!z. z IN s ==> ~(f z = Cx(&0))) + ==> ?g. g holomorphic_on s /\ + !z. z IN s ==> f z = g z pow 2)) /\ + (!s. open s + ==> (simply_connected s <=> + connected s /\ + !f. f holomorphic_on s /\ (!z. z IN s ==> ~(f z = Cx(&0))) /\ + (!x y. x IN s /\ y IN s /\ f x = f y ==> x = y) + ==> ?g. g holomorphic_on s /\ + !z. z IN s ==> f z = g z pow 2)) /\ + (!s. open s + ==> (simply_connected s <=> + s = {} \/ s = (:complex) \/ + ?f g. f holomorphic_on s /\ g holomorphic_on ball(Cx(&0),&1) /\ + (!z. z IN s ==> f(z) IN ball(Cx(&0),&1) /\ g(f z) = z) /\ + (!z. z IN ball(Cx(&0),&1) ==> g(z) IN s /\ f(g z) = z))) /\ + (!s. open s + ==> (simply_connected(s:complex->bool) <=> + s = {} \/ s homeomorphic ball(Cx(&0),&1)))`, + REWRITE_TAC[AND_FORALL_THM; TAUT + `(p ==> q) /\ (p ==> r) <=> p ==> q /\ r`] THEN + X_GEN_TAC `s:complex->bool` THEN DISCH_TAC THEN MATCH_MP_TAC(TAUT + `(p0 ==> p1) /\ (p1 ==> p2) /\ (p2 ==> p3) /\ (p3 ==> p4) /\ + (p4 ==> p5) /\ (p5 ==> p6) /\ (p6 ==> p7) /\ (p7 ==> p8) /\ (p8 ==> p0) + ==> (p0 <=> p1) /\ (p0 <=> p2) /\ + (p0 <=> p3) /\ (p0 <=> p4) /\ + (p0 <=> p5) /\ (p0 <=> p6) /\ (p0 <=> p7) /\ (p0 <=> p8)`) THEN + REPEAT CONJ_TAC THENL + [SIMP_TAC[SIMPLY_CONNECTED_IMP_CONNECTED] THEN + MESON_TAC[SIMPLY_CONNECTED_IMP_WINDING_NUMBER_ZERO]; + + REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC CAUCHY_THEOREM_GLOBAL THEN + EXISTS_TAC `s:complex->bool` THEN ASM_REWRITE_TAC[] THEN + REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_SIMP_TAC[VALID_PATH_IMP_PATH]; + + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN X_GEN_TAC `f:complex->complex` THEN + ASM_CASES_TAC `s:complex->bool = {}` THENL + [ASM_REWRITE_TAC[NOT_IN_EMPTY] THEN ASM_MESON_TAC[]; DISCH_TAC] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN + DISCH_THEN(X_CHOOSE_TAC `a:complex`) THEN EXISTS_TAC + `\z. path_integral + (@g. vector_polynomial_function g /\ path_image g SUBSET s /\ + pathstart g = a /\ pathfinish g = z) + f` THEN + X_GEN_TAC `x:complex` THEN DISCH_TAC THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [OPEN_CONTAINS_CBALL]) THEN + DISCH_THEN(MP_TAC o SPEC `x:complex`) THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC) THEN + REWRITE_TAC[has_complex_derivative] THEN + REWRITE_TAC[has_derivative_at; LINEAR_COMPLEX_MUL] THEN + MATCH_MP_TAC LIM_TRANSFORM THEN + EXISTS_TAC `\y. inv(norm(y - x)) % (path_integral(linepath(x,y)) f - + f x * (y - x))` THEN + REWRITE_TAC[VECTOR_ARITH + `i % (x - a) - i % (y - (z + a)) = i % (x + z - y)`] THEN + CONJ_TAC THENL + [MATCH_MP_TAC LIM_EVENTUALLY THEN REWRITE_TAC[EVENTUALLY_AT] THEN + EXISTS_TAC `d:real` THEN ASM_REWRITE_TAC[] THEN + X_GEN_TAC `y:complex` THEN STRIP_TAC THEN + REWRITE_TAC[VECTOR_MUL_EQ_0] THEN DISJ2_TAC THEN MP_TAC(ISPEC + `s:complex->bool` CONNECTED_OPEN_VECTOR_POLYNOMIAL_CONNECTED) THEN + ASM_REWRITE_TAC[] THEN + DISCH_THEN(MP_TAC o SPEC `a:complex`) THEN ASM_REWRITE_TAC[] THEN + SUBGOAL_THEN `(y:complex) IN s` ASSUME_TAC THENL + [ASM_MESON_TAC[SUBSET; IN_CBALL; REAL_LT_IMP_LE; DIST_SYM]; + ALL_TAC] THEN + DISCH_THEN(fun th -> + MP_TAC(SPEC `y:complex` th) THEN MP_TAC(SPEC `x:complex` th)) THEN + ASM_REWRITE_TAC[] THEN MAP_EVERY ABBREV_TAC + [`g1 = @g. vector_polynomial_function g /\ path_image g SUBSET s /\ + pathstart g = (a:complex) /\ pathfinish g = x`; + `g2 = @g. vector_polynomial_function g /\ path_image g SUBSET s /\ + pathstart g = (a:complex) /\ pathfinish g = y`] THEN + DISCH_THEN(MP_TAC o SELECT_RULE) THEN ASM_REWRITE_TAC[] THEN + STRIP_TAC THEN DISCH_THEN(MP_TAC o SELECT_RULE) THEN + ASM_REWRITE_TAC[] THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPECL + [`g1 ++ linepath (x:complex,y) ++ reversepath g2`; + `f:complex->complex`]) THEN + ASM_REWRITE_TAC[PATHSTART_JOIN; PATHFINISH_JOIN; PATHFINISH_REVERSEPATH; + PATHSTART_LINEPATH; PATHFINISH_LINEPATH] THEN + SUBGOAL_THEN `segment[x:complex,y] SUBSET s` ASSUME_TAC THENL + [MATCH_MP_TAC SUBSET_TRANS THEN EXISTS_TAC `cball(x:complex,d)` THEN + ASM_REWRITE_TAC[SEGMENT_CONVEX_HULL] THEN + MATCH_MP_TAC HULL_MINIMAL THEN REWRITE_TAC[CONVEX_CBALL] THEN + REWRITE_TAC[INSERT_SUBSET; EMPTY_SUBSET] THEN + ASM_SIMP_TAC[IN_CBALL; DIST_REFL] THEN + ASM_MESON_TAC[REAL_LT_IMP_LE; DIST_SYM]; + ALL_TAC] THEN + SUBGOAL_THEN + `f path_integrable_on g1 /\ f path_integrable_on g2 /\ + f path_integrable_on linepath(x,y)` + STRIP_ASSUME_TAC THENL + [REPEAT CONJ_TAC THEN + MATCH_MP_TAC PATH_INTEGRABLE_HOLOMORPHIC_SIMPLE THEN + EXISTS_TAC `s:complex->bool` THEN + ASM_SIMP_TAC[VALID_PATH_VECTOR_POLYNOMIAL_FUNCTION] THEN + ASM_REWRITE_TAC[VALID_PATH_LINEPATH; PATH_IMAGE_LINEPATH]; + ALL_TAC] THEN + ANTS_TAC THENL + [ALL_TAC; DISCH_THEN(MP_TAC o MATCH_MP PATH_INTEGRAL_UNIQUE)] THEN + ASM_SIMP_TAC[VALID_PATH_JOIN_EQ; PATHSTART_JOIN; PATHFINISH_JOIN; + PATHFINISH_REVERSEPATH; PATHSTART_LINEPATH; + PATHFINISH_LINEPATH; VALID_PATH_VECTOR_POLYNOMIAL_FUNCTION; + PATH_IMAGE_JOIN; PATH_IMAGE_LINEPATH; + PATH_IMAGE_REVERSEPATH; PATHSTART_REVERSEPATH; + VALID_PATH_LINEPATH; VALID_PATH_REVERSEPATH; UNION_SUBSET; + PATH_INTEGRAL_JOIN; PATH_INTEGRABLE_JOIN; + PATH_INTEGRABLE_REVERSEPATH; PATH_INTEGRAL_REVERSEPATH] THEN + REWRITE_TAC[COMPLEX_VEC_0] THEN CONV_TAC COMPLEX_RING; + REWRITE_TAC[LIM_AT] THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN + SUBGOAL_THEN `(f:complex->complex) continuous at x` MP_TAC THENL + [ASM_MESON_TAC[HOLOMORPHIC_ON_IMP_CONTINUOUS_ON; + CONTINUOUS_ON_EQ_CONTINUOUS_AT]; + ALL_TAC] THEN + REWRITE_TAC[continuous_at; dist; VECTOR_SUB_RZERO] THEN + DISCH_THEN(MP_TAC o SPEC `e / &2`) THEN ASM_REWRITE_TAC[REAL_HALF] THEN + DISCH_THEN(X_CHOOSE_THEN `d1:real` STRIP_ASSUME_TAC) THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [OPEN_CONTAINS_BALL]) THEN + DISCH_THEN(MP_TAC o SPEC `x:complex`) THEN + ASM_REWRITE_TAC[SUBSET; IN_BALL; dist] THEN + DISCH_THEN(X_CHOOSE_THEN `d2:real` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `min d1 d2` THEN ASM_REWRITE_TAC[REAL_LT_MIN] THEN + X_GEN_TAC `y:complex` THEN STRIP_TAC THEN + SUBGOAL_THEN `f path_integrable_on linepath(x,y)` MP_TAC THENL + [MATCH_MP_TAC PATH_INTEGRABLE_CONTINUOUS_LINEPATH THEN + MATCH_MP_TAC CONTINUOUS_ON_SUBSET THEN + EXISTS_TAC `s:complex->bool` THEN CONJ_TAC THENL + [ASM_MESON_TAC[HOLOMORPHIC_ON_IMP_CONTINUOUS_ON; + CONTINUOUS_ON_EQ_CONTINUOUS_AT]; + MATCH_MP_TAC SUBSET_TRANS THEN + EXISTS_TAC `ball(x:complex,d2)` THEN CONJ_TAC THENL + [REWRITE_TAC[SEGMENT_CONVEX_HULL] THEN + MATCH_MP_TAC HULL_MINIMAL THEN REWRITE_TAC[CONVEX_BALL] THEN + REWRITE_TAC[SUBSET; IN_BALL; IN_INSERT; NOT_IN_EMPTY; dist] THEN + REPEAT STRIP_TAC THEN + ASM_REWRITE_TAC[dist; NORM_0; VECTOR_SUB_REFL] THEN + ASM_MESON_TAC[NORM_SUB]; + ASM_REWRITE_TAC[SUBSET; dist; IN_BALL]]]; + ALL_TAC] THEN + REWRITE_TAC[path_integrable_on; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `z:complex` THEN + MP_TAC(SPECL [`x:complex`; `y:complex`; `(f:complex->complex) x`] + HAS_PATH_INTEGRAL_CONST_LINEPATH) THEN + REWRITE_TAC[IMP_IMP] THEN + DISCH_THEN(fun th -> ASSUME_TAC(CONJUNCT2 th) THEN MP_TAC th) THEN + FIRST_ASSUM(SUBST1_TAC o MATCH_MP PATH_INTEGRAL_UNIQUE) THEN + DISCH_THEN(MP_TAC o MATCH_MP HAS_PATH_INTEGRAL_SUB) THEN + DISCH_THEN(MP_TAC o MATCH_MP HAS_PATH_INTEGRAL_NEG) THEN + REWRITE_TAC[COMPLEX_NEG_SUB] THEN STRIP_TAC THEN + MATCH_MP_TAC(REAL_ARITH `x <= e / &2 /\ &0 < e ==> x < e`) THEN + ASM_REWRITE_TAC[NORM_MUL; REAL_ABS_INV; REAL_ABS_NORM] THEN + ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN REWRITE_TAC[GSYM real_div] THEN + ASM_SIMP_TAC[REAL_LE_LDIV_EQ] THEN + MATCH_MP_TAC HAS_PATH_INTEGRAL_BOUND_LINEPATH THEN + EXISTS_TAC `\w. (f:complex->complex) w - f x` THEN + ASM_SIMP_TAC[REAL_ARITH `&0 < e ==> &0 <= e / &2`] THEN + X_GEN_TAC `w:complex` THEN STRIP_TAC THEN + MATCH_MP_TAC REAL_LT_IMP_LE THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_MESON_TAC[REAL_LET_TRANS; SEGMENT_BOUND]]; + + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN X_GEN_TAC `f:complex->complex` THEN + ASM_CASES_TAC `s:complex->bool = {}` THENL + [ASM_REWRITE_TAC[NOT_IN_EMPTY] THEN ASM_MESON_TAC[]; STRIP_TAC] THEN + FIRST_X_ASSUM(MP_TAC o SPEC `\z. complex_derivative f z / f z`) THEN + ASM_SIMP_TAC[HOLOMORPHIC_COMPLEX_DERIVATIVE; + HOLOMORPHIC_ON_DIV; ETA_AX] THEN + DISCH_THEN(X_CHOOSE_THEN `g:complex->complex` STRIP_ASSUME_TAC) THEN + MP_TAC(ISPECL [`\z:complex. cexp(g z) / f z`; `s:complex->bool`] + HAS_COMPLEX_DERIVATIVE_ZERO_CONNECTED_CONSTANT) THEN + ASM_REWRITE_TAC[] THEN ANTS_TAC THENL + [X_GEN_TAC `z:complex` THEN DISCH_TAC THEN + SUBGOAL_THEN + `Cx(&0) = ((complex_derivative f z / f z * cexp (g z)) * f z - + cexp (g z) * complex_derivative f z) / f z pow 2` + SUBST1_TAC THENL + [ASM_SIMP_TAC[COMPLEX_FIELD + `~(z = Cx(&0)) ==> (d / z * e) * z = e * d`] THEN + SIMPLE_COMPLEX_ARITH_TAC; + MATCH_MP_TAC HAS_COMPLEX_DERIVATIVE_DIV_AT THEN + ASM_SIMP_TAC[] THEN CONJ_TAC THENL + [GEN_REWRITE_TAC (RATOR_CONV o LAND_CONV) [GSYM o_DEF] THEN + ONCE_REWRITE_TAC[COMPLEX_MUL_SYM] THEN + MATCH_MP_TAC COMPLEX_DIFF_CHAIN_AT THEN + ASM_SIMP_TAC[HAS_COMPLEX_DERIVATIVE_CEXP]; + ASM_MESON_TAC[HOLOMORPHIC_ON_OPEN; complex_differentiable; + HAS_COMPLEX_DERIVATIVE_DIFFERENTIABLE]]]; + DISCH_THEN(X_CHOOSE_THEN `c:complex` MP_TAC) THEN + ASM_CASES_TAC `c = Cx(&0)` THENL + [ASM_SIMP_TAC[CEXP_NZ; COMPLEX_FIELD + `~(x = Cx(&0)) /\ ~(y = Cx(&0)) ==> ~(x / y = Cx(&0))`] THEN + ASM_MESON_TAC[]; + ASM_SIMP_TAC[COMPLEX_FIELD + `~(y = Cx(&0)) /\ ~(z = Cx(&0)) + ==> (x / y = z <=> y = inv(z) * x)`] THEN + DISCH_TAC THEN EXISTS_TAC `\z:complex. clog(inv c) + g z` THEN + ASM_SIMP_TAC[CEXP_CLOG; CEXP_ADD; COMPLEX_INV_EQ_0] THEN + MATCH_MP_TAC HOLOMORPHIC_ON_ADD THEN + REWRITE_TAC[HOLOMORPHIC_ON_CONST] THEN + ASM_MESON_TAC[HOLOMORPHIC_ON_OPEN]]]; + + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + X_GEN_TAC `f:complex->complex` THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `f:complex->complex`) THEN + ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `g:complex->complex` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `\z:complex. cexp(g z / Cx(&2))` THEN + ASM_SIMP_TAC[GSYM CEXP_N; COMPLEX_RING `Cx(&2) * z / Cx(&2) = z`] THEN + GEN_REWRITE_TAC LAND_CONV [GSYM o_DEF] THEN + MATCH_MP_TAC HOLOMORPHIC_ON_COMPOSE THEN + REWRITE_TAC[HOLOMORPHIC_ON_CEXP] THEN + MATCH_MP_TAC HOLOMORPHIC_ON_DIV THEN + ASM_SIMP_TAC[HOLOMORPHIC_ON_CONST] THEN + CONV_TAC COMPLEX_RING; + + MATCH_MP_TAC MONO_AND THEN REWRITE_TAC[] THEN + MATCH_MP_TAC MONO_FORALL THEN MESON_TAC[]; + + POP_ASSUM MP_TAC THEN SPEC_TAC(`s:complex->bool`,`s:complex->bool`) THEN + REWRITE_TAC[IMP_IMP; GSYM CONJ_ASSOC; FORALL_AND_THM] THEN + SUBGOAL_THEN + `!s:complex->bool. + open s /\ connected s /\ Cx(&0) IN s /\ s SUBSET ball(Cx(&0),&1) /\ + (!f. f holomorphic_on s /\ (!z. z IN s ==> ~(f z = Cx(&0))) /\ + (!x y. x IN s /\ y IN s /\ f x = f y ==> x = y) + ==> ?g. g holomorphic_on s /\ (!z. z IN s ==> f z = g z pow 2)) + ==> ?f g. f holomorphic_on s /\ + g holomorphic_on ball(Cx(&0),&1) /\ + (!z. z IN s ==> f z IN ball(Cx(&0),&1) /\ g(f z) = z) /\ + (!z. z IN ball(Cx(&0),&1) ==> g z IN s /\ f(g z) = z)` + ASSUME_TAC THENL + [ALL_TAC; + REPEAT STRIP_TAC THEN + ASM_CASES_TAC `s:complex->bool = {}` THEN ASM_REWRITE_TAC[] THEN + ASM_CASES_TAC `s = (:complex)` THEN ASM_REWRITE_TAC[] THEN + SUBGOAL_THEN `?a b:complex. a IN s /\ ~(b IN s)` STRIP_ASSUME_TAC THENL + [ASM SET_TAC[]; ALL_TAC] THEN + SUBGOAL_THEN + `?f. f holomorphic_on s /\ + f(a) = Cx(&0) /\ + IMAGE f s SUBSET ball(Cx(&0),&1) /\ + (!w z. w IN s /\ z IN s /\ f w = f z ==> w = z)` + MP_TAC THENL + [FIRST_X_ASSUM(K ALL_TAC o SPEC `(:complex)`) THEN + FIRST_X_ASSUM(MP_TAC o SPEC `\z:complex. z - b`) THEN ANTS_TAC THENL + [SIMP_TAC[HOLOMORPHIC_ON_SUB; HOLOMORPHIC_ON_CONST; HOLOMORPHIC_ON_ID; + COMPLEX_RING `x - b:complex = y - b <=> x = y`] THEN + ASM_MESON_TAC[COMPLEX_SUB_0]; + ALL_TAC] THEN + REWRITE_TAC[COMPLEX_EQ_SUB_RADD] THEN + DISCH_THEN(X_CHOOSE_THEN `g:complex->complex` STRIP_ASSUME_TAC) THEN + MP_TAC(ISPECL [`s:complex->bool`; `g:complex->complex`] + OPEN_MAPPING_THM) THEN ASM_REWRITE_TAC[] THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [OPEN_CONTAINS_BALL]) THEN + DISCH_THEN(MP_TAC o SPEC `a:complex`) THEN ASM_REWRITE_TAC[SUBSET] THEN + DISCH_THEN(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC) THEN ANTS_TAC THENL + [SUBGOAL_THEN `a IN ball(a,d) /\ (a + Cx(d / &2)) IN ball(a,d) /\ + ~(a + Cx(d / &2) = a)` + MP_TAC THENL [ALL_TAC; ASM_MESON_TAC[]] THEN + ASM_REWRITE_TAC[CENTRE_IN_BALL; + COMPLEX_EQ_ADD_LCANCEL_0; CX_INJ] THEN + REWRITE_TAC[IN_BALL; NORM_ARITH `dist(a,a + d) = norm d`] THEN + REWRITE_TAC[COMPLEX_NORM_CX] THEN ASM_REAL_ARITH_TAC; + ALL_TAC] THEN + DISCH_THEN(MP_TAC o SPEC `ball(a:complex,d)`) THEN + ASM_REWRITE_TAC[OPEN_BALL] THEN REWRITE_TAC[OPEN_CONTAINS_BALL] THEN + DISCH_THEN(MP_TAC o SPEC `(g:complex->complex) a`) THEN + ASM_SIMP_TAC[FUN_IN_IMAGE; CENTRE_IN_BALL] THEN + DISCH_THEN(X_CHOOSE_THEN `r:real` STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN `!z:complex. z IN s ==> ~(g(z) IN ball(--(g a),r))` + MP_TAC THENL + [REWRITE_TAC[IN_BALL] THEN X_GEN_TAC `z:complex` THEN + REPEAT DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [SUBSET]) THEN + DISCH_THEN(MP_TAC o SPEC `--((g:complex->complex) z)`) THEN + ASM_REWRITE_TAC[IN_BALL; NORM_ARITH `dist(w,--z) = dist(--w,z)`] THEN + REWRITE_TAC[IN_IMAGE; NOT_EXISTS_THM] THEN X_GEN_TAC `w:complex` THEN + ASM_CASES_TAC `w:complex = z` THENL + [ASM_REWRITE_TAC[COMPLEX_RING `--z = z <=> z = Cx(&0)`] THEN + ASM_MESON_TAC[COMPLEX_RING `Cx(&0) pow 2 + b = b`]; + ASM_MESON_TAC[COMPLEX_RING `(--z:complex) pow 2 = z pow 2`]]; + REWRITE_TAC[IN_BALL; NORM_ARITH `dist(--a,b) = norm(b + a)`] THEN + ASM_CASES_TAC `!z:complex. z IN s ==> ~(g z + g a = Cx(&0))` THENL + [REWRITE_TAC[REAL_NOT_LT] THEN DISCH_TAC; + ASM_MESON_TAC[COMPLEX_NORM_0]] THEN + EXISTS_TAC `\z:complex. + Cx(r / &3) / (g z + g a) - Cx(r / &3) / (g a + g a)` THEN + REWRITE_TAC[COMPLEX_SUB_REFL] THEN CONJ_TAC THENL + [MATCH_MP_TAC HOLOMORPHIC_ON_SUB THEN + REWRITE_TAC[HOLOMORPHIC_ON_CONST] THEN + MATCH_MP_TAC HOLOMORPHIC_ON_DIV THEN + ASM_SIMP_TAC[HOLOMORPHIC_ON_ADD; HOLOMORPHIC_ON_CONST; ETA_AX]; + ASM_SIMP_TAC[IMP_CONJ; CX_INJ; REAL_LT_IMP_NZ; + REAL_ARITH `&0 < r ==> ~(r / &3 = &0)`; + COMPLEX_FIELD + `~(a = Cx(&0)) /\ ~(x + k = Cx(&0)) /\ ~(y + k = Cx(&0)) + ==> (a / (x + k) - c = a / (y + k) - c <=> x = y)`] THEN + CONJ_TAC THENL [REWRITE_TAC[dist]; ASM_MESON_TAC[]] THEN + REWRITE_TAC[FORALL_IN_IMAGE; COMPLEX_SUB_LZERO; NORM_NEG] THEN + X_GEN_TAC `z:complex` THEN DISCH_TAC THEN + MATCH_MP_TAC(NORM_ARITH + `norm(x) <= &1 / &3 /\ norm(y) <= &1 / &3 + ==> norm(x - y) < &1`) THEN + REWRITE_TAC[COMPLEX_NORM_DIV; COMPLEX_NORM_CX; REAL_ABS_DIV] THEN + ASM_SIMP_TAC[real_abs; REAL_LT_IMP_LE; REAL_POS] THEN + REWRITE_TAC[REAL_ARITH + `r / &3 / x <= &1 / &3 <=> r / x <= &1`] THEN + ASM_SIMP_TAC[REAL_LE_LDIV_EQ; NORM_POS_LT; COMPLEX_NORM_NZ] THEN + ASM_SIMP_TAC[REAL_MUL_LID]]]; + REWRITE_TAC[MESON[] + `(!x y. P x /\ P y /\ f x = f y ==> x = y) <=> + (!x y. P x /\ P y ==> (f x = f y <=> x = y))`] THEN + DISCH_THEN(X_CHOOSE_THEN `h:complex->complex` STRIP_ASSUME_TAC) THEN + MP_TAC(ISPECL [`h:complex->complex`; `s:complex->bool`] + HOLOMORPHIC_ON_INVERSE) THEN + ANTS_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC + (X_CHOOSE_THEN `k:complex->complex` STRIP_ASSUME_TAC)) THEN + FIRST_X_ASSUM(MP_TAC o SPEC `IMAGE (h:complex->complex) s`) THEN + ANTS_TAC THENL + [ASM_REWRITE_TAC[] THEN REPEAT CONJ_TAC THENL + [MATCH_MP_TAC CONNECTED_CONTINUOUS_IMAGE THEN + ASM_SIMP_TAC[HOLOMORPHIC_ON_IMP_CONTINUOUS_ON]; + ASM SET_TAC[]; + REWRITE_TAC[FORALL_IN_IMAGE]] THEN + X_GEN_TAC `f:complex->complex` THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC + `(f:complex->complex) o (h:complex->complex)`) THEN + ANTS_TAC THENL + [CONJ_TAC THENL + [ASM_MESON_TAC[HOLOMORPHIC_ON_COMPOSE]; ALL_TAC] THEN + ASM_REWRITE_TAC[o_THM] THEN ASM SET_TAC[]; + ALL_TAC] THEN + REWRITE_TAC[o_THM] THEN + DISCH_THEN(X_CHOOSE_THEN `g:complex->complex` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `(g:complex->complex) o (k:complex->complex)` THEN + ASM_SIMP_TAC[o_THM] THEN MATCH_MP_TAC HOLOMORPHIC_ON_COMPOSE THEN + ASM_REWRITE_TAC[] THEN FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP + (REWRITE_RULE[IMP_CONJ] HOLOMORPHIC_ON_SUBSET)) THEN ASM SET_TAC[]; + ALL_TAC] THEN + REWRITE_TAC[FORALL_IN_IMAGE] THEN + DISCH_THEN(X_CHOOSE_THEN `f:complex->complex` + (X_CHOOSE_THEN `g:complex->complex` STRIP_ASSUME_TAC)) THEN + EXISTS_TAC `(f:complex->complex) o (h:complex->complex)` THEN + EXISTS_TAC `(k:complex->complex) o (g:complex->complex)` THEN + ASM_SIMP_TAC[o_THM; HOLOMORPHIC_ON_COMPOSE] THEN CONJ_TAC THENL + [MATCH_MP_TAC HOLOMORPHIC_ON_COMPOSE; ASM SET_TAC[]] THEN + ASM_REWRITE_TAC[] THEN FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP + (REWRITE_RULE[IMP_CONJ] HOLOMORPHIC_ON_SUBSET)) THEN + ASM SET_TAC[]]] THEN + X_GEN_TAC `s:complex->bool` THEN STRIP_TAC THEN + ABBREV_TAC + `ff = { h | h holomorphic_on s /\ + IMAGE h s SUBSET ball(Cx(&0),&1) /\ + h(Cx(&0)) = Cx(&0) /\ + (!x y. x IN s /\ y IN s ==> (h x = h y <=> x = y))}` THEN + SUBGOAL_THEN `(\z:complex. z) IN ff` MP_TAC THENL + [EXPAND_TAC "ff" THEN REWRITE_TAC[IN_ELIM_THM; IMAGE_ID] THEN + ASM_REWRITE_TAC[HOLOMORPHIC_ON_ID]; + ASM_CASES_TAC `ff:(complex->complex)->bool = {}` THEN + ASM_REWRITE_TAC[NOT_IN_EMPTY] THEN DISCH_TAC] THEN + SUBGOAL_THEN `!h. h IN ff ==> h holomorphic_on s` ASSUME_TAC THENL + [EXPAND_TAC "ff" THEN SIMP_TAC[IN_ELIM_THM]; ALL_TAC] THEN + SUBGOAL_THEN + `?f:complex->complex. + f IN ff /\ + (!h. h IN ff + ==> norm(complex_derivative h (Cx(&0))) + <= norm(complex_derivative f (Cx(&0))))` + MP_TAC THENL + [MP_TAC(ISPEC + `{ norm(complex_derivative h (Cx(&0))) | h IN ff}` SUP) THEN + ANTS_TAC THENL + [ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN + ASM_REWRITE_TAC[IMAGE_EQ_EMPTY; FORALL_IN_IMAGE] THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [OPEN_CONTAINS_BALL]) THEN + DISCH_THEN(MP_TAC o SPEC `Cx(&0)`) THEN + ASM_REWRITE_TAC[SUBSET; IN_BALL; COMPLEX_SUB_LZERO; + dist; NORM_NEG] THEN + DISCH_THEN(X_CHOOSE_THEN `r:real` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `inv(r):real` THEN X_GEN_TAC `f:complex->complex` THEN + EXPAND_TAC "ff" THEN + REWRITE_TAC[IN_ELIM_THM; FORALL_IN_IMAGE; SUBSET] THEN + ASM_REWRITE_TAC[SUBSET; IN_BALL; COMPLEX_SUB_LZERO; + dist; NORM_NEG] THEN + STRIP_TAC THEN + MP_TAC(ISPEC `\z. (f:complex->complex) (Cx(r) * z)` + SCHWARZ_LEMMA) THEN + ASM_REWRITE_TAC[COMPLEX_MUL_RZERO] THEN + SUBGOAL_THEN + `!z. z IN ball(Cx(&0),&1) + ==> ((\z. f (Cx r * z)) has_complex_derivative + complex_derivative f (Cx(r) * z) * Cx(r)) (at z)` + (LABEL_TAC "*") + THENL + [REPEAT STRIP_TAC THEN MATCH_MP_TAC + (REWRITE_RULE[o_DEF] COMPLEX_DIFF_CHAIN_AT) THEN + CONJ_TAC THENL + [COMPLEX_DIFF_TAC THEN REWRITE_TAC[COMPLEX_MUL_RID]; + REWRITE_TAC[HAS_COMPLEX_DERIVATIVE_DIFFERENTIABLE]] THEN + MATCH_MP_TAC HOLOMORPHIC_ON_IMP_DIFFERENTIABLE_AT THEN + EXISTS_TAC `s:complex->bool` THEN ASM_REWRITE_TAC[] THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN + REWRITE_TAC[COMPLEX_NORM_MUL; COMPLEX_NORM_CX] THEN + ASM_SIMP_TAC[real_abs; REAL_LT_IMP_LE] THEN + GEN_REWRITE_TAC RAND_CONV [GSYM REAL_MUL_RID] THEN + ASM_SIMP_TAC[GSYM COMPLEX_IN_BALL_0; REAL_LT_LMUL_EQ]; + ALL_TAC] THEN + ANTS_TAC THENL + [CONJ_TAC THENL + [REWRITE_TAC[holomorphic_on] THEN + ASM_MESON_TAC[HAS_COMPLEX_DERIVATIVE_AT_WITHIN]; + REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN + REWRITE_TAC[COMPLEX_NORM_MUL; COMPLEX_NORM_CX] THEN + ASM_SIMP_TAC[real_abs; REAL_LT_IMP_LE] THEN + GEN_REWRITE_TAC RAND_CONV [GSYM REAL_MUL_RID] THEN + ASM_SIMP_TAC[GSYM COMPLEX_IN_BALL_0; REAL_LT_LMUL_EQ]]; + REMOVE_THEN "*" (MP_TAC o SPEC `Cx(&0)`) THEN + REWRITE_TAC[CENTRE_IN_BALL; REAL_LT_01] THEN + DISCH_THEN(SUBST1_TAC o + MATCH_MP HAS_COMPLEX_DERIVATIVE_DERIVATIVE) THEN + DISCH_THEN(MP_TAC o CONJUNCT1 o CONJUNCT2) THEN + REWRITE_TAC[COMPLEX_MUL_RZERO; COMPLEX_NORM_MUL] THEN + ASM_SIMP_TAC[COMPLEX_NORM_CX; real_abs; REAL_LT_IMP_LE] THEN + ASM_SIMP_TAC[GSYM REAL_LE_RDIV_EQ; real_div; REAL_MUL_LID]]; + ALL_TAC] THEN + ABBREV_TAC + `l = sup { norm(complex_derivative h (Cx(&0))) | h IN ff}` THEN + REWRITE_TAC[FORALL_IN_GSPEC] THEN DISCH_TAC THEN + SUBGOAL_THEN + `?f. (!n. (f n) IN ff) /\ + ((\n. Cx(norm(complex_derivative (f n) (Cx(&0))))) --> Cx(l)) + sequentially` + STRIP_ASSUME_TAC THENL + [SUBGOAL_THEN + `!n. ?f. f IN ff /\ + abs(norm(complex_derivative f (Cx (&0))) - l) < inv(&n + &1)` + MP_TAC THENL + [X_GEN_TAC `n:num` THEN + FIRST_ASSUM(MP_TAC o SPEC `l - inv(&n + &1)` o CONJUNCT2) THEN + REWRITE_TAC[REAL_ARITH `l <= l - i <=> ~(&0 < i)`; REAL_LT_INV_EQ; + REAL_ARITH `&0 < &n + &1`; NOT_FORALL_THM; NOT_IMP] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `f:complex->complex` THEN + ASM_CASES_TAC `(f:complex->complex) IN ff` THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC(REAL_ARITH + `n <= l ==> ~(n <= l - e) ==> abs(n - l) < e`) THEN + ASM_SIMP_TAC[]; + REWRITE_TAC[SKOLEM_THM; FORALL_AND_THM] THEN + MATCH_MP_TAC MONO_EXISTS THEN + X_GEN_TAC `f:num->complex->complex` THEN + STRIP_TAC THEN ASM_REWRITE_TAC[LIM_SEQUENTIALLY] THEN + X_GEN_TAC `e:real` THEN + DISCH_THEN(MP_TAC o GEN_REWRITE_RULE I [REAL_ARCH_INV]) THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `N:num` THEN STRIP_TAC THEN + X_GEN_TAC `m:num` THEN DISCH_TAC THEN REWRITE_TAC[dist] THEN + MATCH_MP_TAC REAL_LT_TRANS THEN EXISTS_TAC `inv(&m + &1)` THEN + ASM_REWRITE_TAC[COMPLEX_NORM_CX; GSYM CX_SUB] THEN + MATCH_MP_TAC REAL_LT_TRANS THEN EXISTS_TAC `inv(&N)` THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC REAL_LT_INV2 THEN + ASM_REWRITE_TAC[REAL_OF_NUM_LT; REAL_OF_NUM_ADD] THEN ASM_ARITH_TAC]; + ALL_TAC] THEN + MP_TAC(ISPECL [`f:num->complex->complex`; `ff:(complex->complex)->bool`; + `s:complex->bool`] MONTEL) THEN + ASM_REWRITE_TAC[] THEN ANTS_TAC THENL + [EXPAND_TAC "ff" THEN SIMP_TAC[IN_ELIM_THM] THEN + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; IN_BALL; COMPLEX_SUB_LZERO; + dist; NORM_NEG] THEN + MESON_TAC[REAL_LT_IMP_LE]; + ALL_TAC] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `g:complex->complex` THEN + DISCH_THEN(X_CHOOSE_THEN `r:num->num` STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN + `g complex_differentiable (at(Cx(&0))) /\ + norm(complex_derivative g (Cx(&0))) = l` + STRIP_ASSUME_TAC THENL + [MP_TAC(ISPECL [`(f:num->complex->complex) o (r:num->num)`; + `(\n:num z. complex_derivative (f n) z) o (r:num->num)`; + `g:complex->complex`; `s:complex->bool`] + HAS_COMPLEX_DERIVATIVE_UNIFORM_SEQUENCE) THEN + ASM_REWRITE_TAC[o_THM] THEN ANTS_TAC THENL + [CONJ_TAC THENL + [REWRITE_TAC[HAS_COMPLEX_DERIVATIVE_DIFFERENTIABLE] THEN + REPEAT STRIP_TAC THEN + MATCH_MP_TAC HOLOMORPHIC_ON_IMP_DIFFERENTIABLE_AT THEN + EXISTS_TAC `s:complex->bool` THEN ASM_SIMP_TAC[]; + ALL_TAC] THEN + X_GEN_TAC `z:complex` THEN DISCH_TAC THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [OPEN_CONTAINS_CBALL]) THEN + DISCH_THEN(MP_TAC o SPEC `z:complex`) THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `d:real` THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN X_GEN_TAC `e:real` THEN + DISCH_TAC THEN REWRITE_TAC[EVENTUALLY_SEQUENTIALLY] THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`cball(z:complex,d)`; `e:real`]) THEN + ASM_REWRITE_TAC[COMPACT_CBALL; GE] THEN + MATCH_MP_TAC MONO_EXISTS THEN SIMP_TAC[]; + DISCH_THEN(X_CHOOSE_THEN `g':complex->complex` MP_TAC) THEN + DISCH_THEN(MP_TAC o SPEC `Cx(&0)`) THEN + ASM_REWRITE_TAC[IMP_CONJ_ALT] THEN + DISCH_THEN(MP_TAC o ISPEC `\z:complex. Cx(norm z)` o MATCH_MP + (REWRITE_RULE[IMP_CONJ_ALT] LIM_CONTINUOUS_FUNCTION)) THEN + REWRITE_TAC[CONTINUOUS_AT_CX_NORM] THEN DISCH_TAC THEN DISCH_TAC THEN + CONJ_TAC THENL [ASM_MESON_TAC[complex_differentiable]; ALL_TAC] THEN + GEN_REWRITE_TAC I [GSYM CX_INJ] THEN + FIRST_ASSUM(SUBST1_TAC o + MATCH_MP HAS_COMPLEX_DERIVATIVE_DERIVATIVE) THEN + MATCH_MP_TAC(ISPEC `sequentially` LIM_UNIQUE) THEN EXISTS_TAC + `\n. Cx(norm(complex_derivative(f((r:num->num) n)) (Cx (&0))))` THEN + ASM_REWRITE_TAC[TRIVIAL_LIMIT_SEQUENTIALLY] THEN MP_TAC(ISPECL + [`\n:num. Cx(norm(complex_derivative (f n) (Cx (&0))))`; + `r:num->num`; `Cx l`] LIM_SUBSEQUENCE) THEN + ASM_REWRITE_TAC[o_DEF]]; + ALL_TAC] THEN + ASM_SIMP_TAC[] THEN + SUBGOAL_THEN `~(?c. !z. z IN s ==> (g:complex->complex) z = c)` + ASSUME_TAC THENL + [DISCH_THEN(X_CHOOSE_TAC `c:complex`) THEN + SUBGOAL_THEN `complex_derivative g (Cx(&0)) = Cx(&0)` MP_TAC THENL + [MATCH_MP_TAC HAS_COMPLEX_DERIVATIVE_DERIVATIVE THEN + MATCH_MP_TAC HAS_COMPLEX_DERIVATIVE_TRANSFORM_WITHIN_OPEN THEN + MAP_EVERY EXISTS_TAC + [`(\z. c):complex->complex`; `s:complex->bool`] THEN + ASM_REWRITE_TAC[HAS_COMPLEX_DERIVATIVE_CONST] THEN ASM_MESON_TAC[]; + DISCH_THEN(MP_TAC o AP_TERM `norm:complex->real`) THEN + ASM_REWRITE_TAC[COMPLEX_NORM_CX; REAL_ABS_NUM] THEN + DISCH_THEN SUBST_ALL_TAC THEN + FIRST_ASSUM(MP_TAC o SPEC `\z:complex. z` o CONJUNCT1) THEN + ANTS_TAC THENL [ASM_REWRITE_TAC[]; ALL_TAC] THEN + REWRITE_TAC[COMPLEX_DERIVATIVE_ID; COMPLEX_NORM_CX] THEN + REAL_ARITH_TAC]; + ALL_TAC] THEN + EXPAND_TAC "ff" THEN REWRITE_TAC[IN_ELIM_THM] THEN ASM_REWRITE_TAC[] THEN + REPEAT CONJ_TAC THENL + [REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; COMPLEX_IN_BALL_0] THEN + SUBGOAL_THEN `!z. z IN s ==> norm((g:complex->complex) z) <= &1` + ASSUME_TAC THENL + [X_GEN_TAC `z:complex` THEN DISCH_TAC THEN + MATCH_MP_TAC(ISPEC `sequentially` LIM_NORM_UBOUND) THEN + EXISTS_TAC `\n:num. (f:num->complex->complex) (r n) z` THEN + ASM_SIMP_TAC[TRIVIAL_LIMIT_SEQUENTIALLY] THEN + MATCH_MP_TAC ALWAYS_EVENTUALLY THEN X_GEN_TAC `n:num` THEN + SUBGOAL_THEN + `(f:num->complex->complex) (r(n:num)) IN ff` + MP_TAC THENL [ASM_REWRITE_TAC[]; ALL_TAC] THEN + EXPAND_TAC "ff" THEN REWRITE_TAC[IN_ELIM_THM] THEN + ASM_SIMP_TAC[SUBSET; FORALL_IN_IMAGE; COMPLEX_IN_BALL_0; + REAL_LT_IMP_LE]; + X_GEN_TAC `z:complex` THEN DISCH_TAC THEN + ASM_SIMP_TAC[REAL_LT_LE] THEN DISCH_TAC THEN MP_TAC(ISPECL + [`g:complex->complex`; `s:complex->bool`; `s:complex->bool`; + `z:complex`] MAXIMUM_MODULUS_PRINCIPLE) THEN + ASM_REWRITE_TAC[SUBSET_REFL]]; + MATCH_MP_TAC(ISPEC `sequentially` LIM_UNIQUE) THEN + EXISTS_TAC `\n:num. (f:num->complex->complex) (r n) (Cx(&0))` THEN + ASM_SIMP_TAC[TRIVIAL_LIMIT_SEQUENTIALLY] THEN + MATCH_MP_TAC LIM_EVENTUALLY THEN MATCH_MP_TAC ALWAYS_EVENTUALLY THEN + X_GEN_TAC `n:num` THEN + SUBGOAL_THEN `(f:num->complex->complex) (r(n:num)) IN ff` + MP_TAC THENL [ASM_REWRITE_TAC[]; ALL_TAC] THEN + EXPAND_TAC "ff" THEN SIMP_TAC[IN_ELIM_THM]; + MATCH_MP_TAC(REWRITE_RULE + [MESON[] `(!x y. P x /\ P y /\ f x = f y ==> x = y) <=> + (!x y. P x /\ P y ==> (f x = f y <=> x = y))`] + HURWITZ_INJECTIVE) THEN + EXISTS_TAC `(f:num->complex->complex) o (r:num->num)` THEN + ASM_SIMP_TAC[o_THM] THEN X_GEN_TAC `n:num` THEN + SUBGOAL_THEN `(f:num->complex->complex) (r(n:num)) IN ff` + MP_TAC THENL [ASM_REWRITE_TAC[]; ALL_TAC] THEN + EXPAND_TAC "ff" THEN SIMP_TAC[IN_ELIM_THM]]; + ALL_TAC] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `f:complex->complex` THEN + STRIP_TAC THEN + MP_TAC(SPECL [`f:complex->complex`; `s:complex->bool`] + HOLOMORPHIC_ON_INVERSE) THEN + ANTS_TAC THENL + [UNDISCH_TAC `(f:complex->complex) IN ff` THEN EXPAND_TAC "ff" THEN + REWRITE_TAC[IN_ELIM_THM] THEN ASM_MESON_TAC[]; + DISCH_THEN(MP_TAC o CONJUNCT2)] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `g:complex->complex` THEN + ASM_CASES_TAC `IMAGE (f:complex->complex) s = ball(Cx(&0),&1)` THENL + [ASM_SIMP_TAC[] THEN ASM SET_TAC[]; ALL_TAC] THEN + STRIP_TAC THEN + UNDISCH_TAC `~(IMAGE (f:complex->complex) s = ball(Cx(&0),&1))` THEN + MATCH_MP_TAC(TAUT `p ==> ~p ==> q`) THEN + MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL + [UNDISCH_TAC `(f:complex->complex) IN ff` THEN EXPAND_TAC "ff" THEN + REWRITE_TAC[IN_ELIM_THM] THEN ASM_MESON_TAC[]; + ALL_TAC] THEN + REWRITE_TAC[SUBSET; COMPLEX_IN_BALL_0] THEN + X_GEN_TAC `a:complex` THEN DISCH_TAC THEN + REWRITE_TAC[IN_IMAGE; MESON[] + `(?x. a = f x /\ x IN s) <=> ~(!x. x IN s ==> ~(f x = a))`] THEN + DISCH_TAC THEN + MP_TAC(ISPEC `a:complex` BALL_BIHOLOMORPHISM_EXISTS) THEN + ASM_REWRITE_TAC[COMPLEX_IN_BALL_0; NOT_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`t:complex->complex`; `t':complex->complex`] THEN + STRIP_TAC THEN + SUBGOAL_THEN + `!z. z IN s ==> norm((f:complex->complex) z) < &1` + ASSUME_TAC THENL + [UNDISCH_TAC `(f:complex->complex) IN ff` THEN EXPAND_TAC "ff" THEN + SIMP_TAC[IN_ELIM_THM; SUBSET; FORALL_IN_IMAGE; COMPLEX_IN_BALL_0]; + ALL_TAC] THEN + SUBGOAL_THEN + `?sq. sq holomorphic_on (IMAGE (t o f) s) /\ + !z. z IN s + ==> sq((t:complex->complex) ((f:complex->complex) z)) pow 2 = + t(f z)` + STRIP_ASSUME_TAC THENL + [UNDISCH_TAC + `!f. f holomorphic_on s /\ (!z. z IN s ==> ~(f z = Cx (&0))) /\ + (!x y. x IN s /\ y IN s /\ f x = f y ==> x = y) + ==> ?g. g holomorphic_on s /\ + (!z. z IN s ==> f z = g z pow 2)` THEN + DISCH_THEN(MP_TAC o SPEC + `(t:complex->complex) o (f:complex->complex)`) THEN + ASM_REWRITE_TAC[FORALL_IN_IMAGE; o_THM] THEN ANTS_TAC THENL + [REPEAT CONJ_TAC THENL + [MATCH_MP_TAC HOLOMORPHIC_ON_COMPOSE THEN ASM_SIMP_TAC[] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP + (REWRITE_RULE[IMP_CONJ] HOLOMORPHIC_ON_SUBSET)) THEN + UNDISCH_TAC `(f:complex->complex) IN ff` THEN EXPAND_TAC "ff" THEN + REWRITE_TAC[IN_ELIM_THM] THEN ASM_MESON_TAC[]; + UNDISCH_TAC `(f:complex->complex) IN ff` THEN EXPAND_TAC "ff" THEN + REWRITE_TAC[IN_ELIM_THM; SUBSET; FORALL_IN_IMAGE] THEN + RULE_ASSUM_TAC(REWRITE_RULE[SUBSET; COMPLEX_IN_BALL_0]) THEN + REWRITE_TAC[COMPLEX_IN_BALL_0] THEN STRIP_TAC THEN + GEN_TAC THEN DISCH_TAC THEN + DISCH_THEN(MP_TAC o AP_TERM `t':complex->complex`) THEN + ASM_SIMP_TAC[] THEN ASM_MESON_TAC[]; + UNDISCH_TAC `(f:complex->complex) IN ff` THEN EXPAND_TAC "ff" THEN + REWRITE_TAC[IN_ELIM_THM] THEN + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; COMPLEX_IN_BALL_0] THEN + REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + REPEAT(MATCH_MP_TAC MONO_FORALL THEN GEN_TAC) THEN ASM_MESON_TAC[]]; + DISCH_THEN(X_CHOOSE_THEN `q:complex->complex` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `(q:complex->complex) o (g:complex->complex) o + (t':complex->complex)` THEN + ASM_REWRITE_TAC[o_THM] THEN CONJ_TAC THENL + [MATCH_MP_TAC HOLOMORPHIC_ON_COMPOSE THEN CONJ_TAC THENL + [MATCH_MP_TAC HOLOMORPHIC_ON_COMPOSE THEN CONJ_TAC; + ALL_TAC] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP + (REWRITE_RULE[IMP_CONJ] HOLOMORPHIC_ON_SUBSET)) THEN + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; COMPLEX_IN_BALL_0; o_THM] THENL + [ASM_MESON_TAC[]; ASM SET_TAC[]; ASM_MESON_TAC[]]; + X_GEN_TAC `z:complex` THEN DISCH_TAC THEN + MATCH_MP_TAC EQ_TRANS THEN + EXISTS_TAC `(q:complex->complex) z pow 2` THEN + CONJ_TAC THENL [ALL_TAC; ASM_MESON_TAC[]] THEN + AP_THM_TAC THEN AP_TERM_TAC THEN AP_TERM_TAC THEN + UNDISCH_TAC `(f:complex->complex) IN ff` THEN EXPAND_TAC "ff" THEN + REWRITE_TAC[IN_ELIM_THM; SUBSET; FORALL_IN_IMAGE] THEN + REWRITE_TAC[COMPLEX_IN_BALL_0] THEN ASM_MESON_TAC[]]]; + ALL_TAC] THEN + SUBGOAL_THEN + `!z. z IN s + ==> norm((sq:complex->complex) + ((t:complex->complex)((f:complex->complex) z))) < &1` + ASSUME_TAC THENL + [REPEAT STRIP_TAC THEN + GEN_REWRITE_TAC LAND_CONV [GSYM REAL_ABS_NORM] THEN + REWRITE_TAC[GSYM ABS_SQUARE_LT_1; GSYM COMPLEX_NORM_POW] THEN + ASM_SIMP_TAC[]; + ALL_TAC] THEN + MP_TAC(ISPEC + `(sq:complex->complex) + ((t:complex->complex)((f:complex->complex) (Cx(&0))))` + BALL_BIHOLOMORPHISM_EXISTS) THEN + ASM_SIMP_TAC[COMPLEX_IN_BALL_0; NOT_IMP; NOT_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`r:complex->complex`; `r':complex->complex`] THEN + STRIP_TAC THEN UNDISCH_TAC + `!h. h IN ff + ==> norm(complex_derivative h (Cx (&0))) <= + norm(complex_derivative f (Cx (&0)))` THEN + DISCH_THEN(fun th -> MP_TAC(SPEC + `(r:complex->complex) o (sq:complex->complex) o + (t:complex->complex) o (f:complex->complex)` th) THEN + MP_TAC(SPEC `\z:complex. z` th)) THEN + ASM_REWRITE_TAC[COMPLEX_DERIVATIVE_ID; COMPLEX_NORM_CX; REAL_ABS_NUM] THEN + DISCH_TAC THEN REWRITE_TAC[NOT_IMP; REAL_NOT_LE] THEN + EXPAND_TAC "ff" THEN REWRITE_TAC[IN_ELIM_THM] THEN + MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN REPEAT CONJ_TAC THENL + [REPEAT(MATCH_MP_TAC HOLOMORPHIC_ON_COMPOSE THEN CONJ_TAC) THEN + ASM_SIMP_TAC[] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP + (REWRITE_RULE[IMP_CONJ] HOLOMORPHIC_ON_SUBSET)) THEN + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; o_THM; COMPLEX_IN_BALL_0] THEN + ASM_SIMP_TAC[]; + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; o_THM; COMPLEX_IN_BALL_0] THEN + ASM_SIMP_TAC[]; + ASM_SIMP_TAC[o_THM]; + MAP_EVERY X_GEN_TAC [`w:complex`; `z:complex`] THEN STRIP_TAC THEN + EQ_TAC THEN SIMP_TAC[] THEN + DISCH_THEN(MP_TAC o AP_TERM `r':complex->complex`) THEN + ASM_SIMP_TAC[o_THM] THEN + DISCH_THEN(MP_TAC o AP_TERM `\z:complex. z pow 2`) THEN + ASM_SIMP_TAC[] THEN + DISCH_THEN(MP_TAC o AP_TERM `t':complex->complex`) THEN + ASM_SIMP_TAC[] THEN ASM_MESON_TAC[]; + STRIP_TAC] THEN + MP_TAC(ISPEC + `(t':complex->complex) o (\z. z pow 2) o (r':complex->complex)` + SCHWARZ_LEMMA) THEN + REWRITE_TAC[] THEN ANTS_TAC THENL + [REPEAT CONJ_TAC THENL + [REPEAT(MATCH_MP_TAC HOLOMORPHIC_ON_COMPOSE THEN CONJ_TAC) THEN + SIMP_TAC[HOLOMORPHIC_ON_POW; HOLOMORPHIC_ON_ID] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP + (REWRITE_RULE[IMP_CONJ] HOLOMORPHIC_ON_SUBSET)) THEN + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; o_THM; COMPLEX_IN_BALL_0] THEN + ASM_SIMP_TAC[COMPLEX_NORM_POW; ABS_SQUARE_LT_1; REAL_ABS_NORM]; + ASM_SIMP_TAC[COMPLEX_NORM_POW; ABS_SQUARE_LT_1; REAL_ABS_NORM; o_THM]; + UNDISCH_THEN `(r:complex->complex) ((sq:complex->complex) + ((t:complex->complex) (f(Cx(&0))))) = Cx (&0)` + (fun th -> GEN_REWRITE_TAC (LAND_CONV o RAND_CONV) [SYM th]) THEN + ASM_SIMP_TAC[o_THM] THEN + UNDISCH_TAC `(f:complex->complex) IN ff` THEN EXPAND_TAC "ff" THEN + SIMP_TAC[IN_ELIM_THM]]; + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN MATCH_MP_TAC + (TAUT `~r /\ (p /\ ~q ==> s) ==> p /\ (q' \/ q ==> r) ==> s`) THEN + CONJ_TAC THENL + [REWRITE_TAC[NOT_EXISTS_THM] THEN X_GEN_TAC `c:complex` THEN + ASM_CASES_TAC `c = Cx(&0)` THEN + ASM_SIMP_TAC[COMPLEX_NORM_CX; REAL_ABS_NUM; REAL_OF_NUM_EQ; ARITH] THEN + DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN + DISCH_THEN(fun th -> + MP_TAC(ISPEC `(r:complex->complex) (--(Cx(&1) / Cx(&2)))` th) THEN + MP_TAC(ISPEC `(r:complex->complex) (Cx(&1) / Cx(&2))` th)) THEN + MATCH_MP_TAC(TAUT `(p1 /\ p2) /\ (q1 /\ q2 ==> r) + ==> (p1 ==> q1) ==> (p2 ==> q2) ==> r`) THEN + CONJ_TAC THENL + [CONJ_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + REWRITE_TAC[COMPLEX_NORM_DIV; COMPLEX_NORM_CX; NORM_NEG] THEN + REAL_ARITH_TAC; + ALL_TAC] THEN + MATCH_MP_TAC(MESON[] + `~(b1 = b2) /\ a1 = a2 ==> (a1 = b1 /\ a2 = b2 ==> F)`) THEN + CONJ_TAC THENL + [ASM_REWRITE_TAC[COMPLEX_EQ_MUL_LCANCEL] THEN + DISCH_THEN(MP_TAC o AP_TERM `r':complex->complex`) THEN + FIRST_ASSUM(fun th -> + W(MP_TAC o PART_MATCH (lhand o rand) th o + lhand o lhand o snd)) THEN + REWRITE_TAC[COMPLEX_NORM_DIV; COMPLEX_NORM_CX; NORM_NEG] THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN DISCH_THEN SUBST1_TAC THEN + MATCH_MP_TAC(COMPLEX_RING + `x = --(Cx(&1) / Cx(&2)) ==> ~(Cx(&1) / Cx(&2) = x)`) THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN + REWRITE_TAC[COMPLEX_NORM_DIV; COMPLEX_NORM_CX; NORM_NEG] THEN + CONV_TAC REAL_RAT_REDUCE_CONV; + REWRITE_TAC[o_DEF] THEN AP_TERM_TAC THEN + MATCH_MP_TAC(COMPLEX_RING + `x = Cx(&1) / Cx(&2) /\ y = --(Cx(&1) / Cx(&2)) + ==> x pow 2 = y pow 2`) THEN + CONJ_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + REWRITE_TAC[COMPLEX_NORM_DIV; COMPLEX_NORM_CX; NORM_NEG] THEN + CONV_TAC REAL_RAT_REDUCE_CONV]; + REWRITE_TAC[GSYM REAL_LT_LE] THEN DISCH_TAC THEN + UNDISCH_TAC `&1 <= norm (complex_derivative f (Cx (&0)))` THEN + SUBGOAL_THEN + `complex_derivative f (Cx (&0)) = + complex_derivative (t' o (\z:complex. z pow 2) o r') (Cx(&0)) * + complex_derivative + (r o (sq:complex->complex) o (t:complex->complex) o f) (Cx(&0))` + (fun th -> REWRITE_TAC[th; COMPLEX_NORM_MUL]) + THENL + [ALL_TAC; + REWRITE_TAC[REAL_ARITH `a * b < b <=> &0 < (&1 - a) * b`] THEN + DISCH_THEN(MP_TAC o MATCH_MP + (REAL_ARITH `&1 <= x ==> ~(x = &0)`)) THEN + SIMP_TAC[REAL_ENTIRE; NORM_EQ_0; GSYM NORM_POS_LT; DE_MORGAN_THM] THEN + ASM_SIMP_TAC[REAL_LT_MUL_EQ] THEN ASM_REAL_ARITH_TAC] THEN + MATCH_MP_TAC HAS_COMPLEX_DERIVATIVE_DERIVATIVE THEN + MATCH_MP_TAC HAS_COMPLEX_DERIVATIVE_TRANSFORM_WITHIN_OPEN THEN + EXISTS_TAC `((t':complex->complex) o + (\z:complex. z pow 2) o (r':complex->complex)) o + ((r:complex->complex) o (sq:complex->complex) o + (t:complex->complex) o (f:complex->complex))` THEN + EXISTS_TAC `s:complex->bool` THEN ASM_REWRITE_TAC[] THEN CONJ_TAC THENL + [ASM_SIMP_TAC[o_THM]; ALL_TAC] THEN + MATCH_MP_TAC COMPLEX_DIFF_CHAIN_AT THEN + ASM_REWRITE_TAC[HAS_COMPLEX_DERIVATIVE_DIFFERENTIABLE] THEN + CONJ_TAC THEN MATCH_MP_TAC HOLOMORPHIC_ON_IMP_DIFFERENTIABLE_AT THENL + [EXISTS_TAC `s:complex->bool` THEN ASM_REWRITE_TAC[]; + EXISTS_TAC `ball(Cx(&0),&1)` THEN + ASM_REWRITE_TAC[OPEN_BALL; CENTRE_IN_BALL; REAL_LT_01] THEN + REPEAT(MATCH_MP_TAC HOLOMORPHIC_ON_COMPOSE THEN CONJ_TAC) THEN + SIMP_TAC[HOLOMORPHIC_ON_POW; HOLOMORPHIC_ON_ID] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP + (REWRITE_RULE[IMP_CONJ] HOLOMORPHIC_ON_SUBSET)) THEN + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; o_THM; COMPLEX_IN_BALL_0] THEN + ASM_SIMP_TAC[COMPLEX_NORM_POW; ABS_SQUARE_LT_1; REAL_ABS_NORM]]]]; + ASM_CASES_TAC `s:complex->bool = {}` THEN ASM_REWRITE_TAC[] THEN + ASM_CASES_TAC `s = (:complex)` THEN ASM_REWRITE_TAC[] THENL + [ONCE_REWRITE_TAC[HOMEOMORPHIC_SYM] THEN + MATCH_MP_TAC HOMEOMORPHIC_BALL_UNIV THEN REWRITE_TAC[REAL_LT_01]; + REWRITE_TAC[HOMEOMORPHIC_MINIMAL] THEN + REPEAT(MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC) THEN + MESON_TAC[HOLOMORPHIC_ON_IMP_CONTINUOUS_ON]]; + STRIP_TAC THEN ASM_REWRITE_TAC[SIMPLY_CONNECTED_EMPTY] THEN + FIRST_ASSUM(MP_TAC o MATCH_MP HOMEOMORPHIC_SIMPLY_CONNECTED_EQ) THEN + SIMP_TAC[CONVEX_IMP_SIMPLY_CONNECTED; CONVEX_BALL]]);; + +let CONTRACTIBLE_EQ_SIMPLY_CONNECTED_2D = prove + (`!s:real^2->bool. open s ==> (contractible s <=> simply_connected s)`, + REPEAT STRIP_TAC THEN EQ_TAC THEN + REWRITE_TAC[CONTRACTIBLE_IMP_SIMPLY_CONNECTED] THEN + ASM_SIMP_TAC[SIMPLY_CONNECTED_EQ_HOMEOMORPHIC_TO_DISC] THEN + STRIP_TAC THEN ASM_REWRITE_TAC[CONTRACTIBLE_EMPTY] THEN + ASM_MESON_TAC[HOMEOMORPHIC_CONTRACTIBLE_EQ; CONVEX_IMP_CONTRACTIBLE; + CONVEX_BALL]);; + +(* ------------------------------------------------------------------------- *) +(* A further chain of equivalents about components of the complement of a *) +(* simply connected set (following 1.35 in Burckel's book). *) +(* ------------------------------------------------------------------------- *) + +let [SIMPLY_CONNECTED_EQ_FRONTIER_PROPERTIES; + SIMPLY_CONNECTED_EQ_UNBOUNDED_COMPLEMENT_COMPONENTS; + SIMPLY_CONNECTED_EQ_EMPTY_INSIDE] = (CONJUNCTS o prove) + (`(!s:complex->bool. + open s + ==> (simply_connected s <=> + connected s /\ + if bounded s then connected(frontier s) + else !c. c IN components(frontier s) ==> ~bounded c)) /\ + (!s. open s + ==> (simply_connected s <=> + connected s /\ + !c. c IN components ((:complex) DIFF s) ==> ~bounded c)) /\ + (!s:complex->bool. + open s ==> (simply_connected s <=> connected s /\ inside s = {}))`, + REWRITE_TAC[AND_FORALL_THM] THEN X_GEN_TAC `s:complex->bool` THEN + ASM_CASES_TAC `open(s:complex->bool)` THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC(TAUT + `(q3 ==> p) /\ (q2 ==> q3) /\ (q1 ==> q2) /\ (p ==> q1) + ==> (p <=> q1) /\ (p <=> q2) /\ (p <=> q3)`) THEN + REPEAT CONJ_TAC THENL + [REWRITE_TAC[INSIDE_OUTSIDE] THEN + REWRITE_TAC[SET_RULE `UNIV DIFF (s UNION t) = {} <=> + !x. ~(x IN s) ==> x IN t`] THEN + STRIP_TAC THEN ASM_SIMP_TAC[SIMPLY_CONNECTED_EQ_WINDING_NUMBER_ZERO] THEN + GEN_TAC THEN X_GEN_TAC `z:complex` THEN STRIP_TAC THEN + MATCH_MP_TAC WINDING_NUMBER_ZERO_IN_OUTSIDE THEN ASM_REWRITE_TAC[] THEN + FIRST_ASSUM(MP_TAC o MATCH_MP OUTSIDE_MONO) THEN ASM SET_TAC[]; + REWRITE_TAC[components; FORALL_IN_GSPEC; inside] THEN SET_TAC[]; + ASM_CASES_TAC `connected(s:complex->bool)` THEN ASM_REWRITE_TAC[] THEN + COND_CASES_TAC THENL + [DISCH_TAC THEN + REWRITE_TAC[components; FORALL_IN_GSPEC; IN_DIFF; IN_UNIV] THEN + ASM_CASES_TAC `s:complex->bool = {}` THEN + ASM_SIMP_TAC[DIFF_EMPTY; CONNECTED_COMPONENT_EQ_SELF; + CONNECTED_UNIV; IN_UNIV; NOT_BOUNDED_UNIV] THEN + ASM_CASES_TAC `s = (:complex)` THENL + [ASM_MESON_TAC[NOT_BOUNDED_UNIV]; ALL_TAC] THEN + X_GEN_TAC `w:complex` THEN DISCH_TAC THEN + FIRST_ASSUM(MP_TAC o MATCH_MP OUTSIDE_BOUNDED_NONEMPTY) THEN + REWRITE_TAC[outside; GSYM MEMBER_NOT_EMPTY; IN_ELIM_THM] THEN + DISCH_THEN(X_CHOOSE_THEN `z:complex` STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN + `connected_component ((:complex) DIFF s) w = + connected_component ((:complex) DIFF s) z` + (fun th -> ASM_REWRITE_TAC[th]) THEN + MATCH_MP_TAC JOINABLE_CONNECTED_COMPONENT_EQ THEN + EXISTS_TAC `frontier s :complex->bool` THEN ASM_REWRITE_TAC[] THEN + CONJ_TAC THENL + [REWRITE_TAC[frontier] THEN MATCH_MP_TAC(SET_RULE + `i = s ==> s' DIFF i SUBSET UNIV DIFF s`) THEN + ASM_REWRITE_TAC[INTERIOR_EQ]; + ALL_TAC] THEN + ONCE_REWRITE_TAC[GSYM FRONTIER_COMPLEMENT] THEN CONJ_TAC THEN + MATCH_MP_TAC(SET_RULE + `frontier c SUBSET c /\ frontier c SUBSET f /\ ~(frontier c = {}) + ==> ~(c INTER f = {})`) THEN + REWRITE_TAC[FRONTIER_OF_CONNECTED_COMPONENT_SUBSET] THEN + ASM_REWRITE_TAC[FRONTIER_EQ_EMPTY; CONNECTED_COMPONENT_EQ_EMPTY; + IN_DIFF; IN_UNIV; CONNECTED_COMPONENT_EQ_UNIV; + SET_RULE `UNIV DIFF s = UNIV <=> s = {}`] THEN + REWRITE_TAC[frontier] THEN MATCH_MP_TAC(SET_RULE + `c = s ==> c DIFF i SUBSET s`) THEN + ASM_REWRITE_TAC[CLOSURE_EQ] THEN + MATCH_MP_TAC CLOSED_CONNECTED_COMPONENT THEN + ASM_REWRITE_TAC[GSYM OPEN_CLOSED]; + DISCH_TAC THEN REWRITE_TAC[components; FORALL_IN_GSPEC] THEN + X_GEN_TAC `w:complex` THEN REWRITE_TAC[IN_DIFF; IN_UNIV] THEN + DISCH_TAC THEN + SUBGOAL_THEN + `?z:complex. z IN frontier s /\ + z IN connected_component ((:real^2) DIFF s) w` + STRIP_ASSUME_TAC THENL + [ONCE_REWRITE_TAC[GSYM FRONTIER_COMPLEMENT] THEN + MATCH_MP_TAC(SET_RULE + `frontier c SUBSET c /\ frontier c SUBSET f /\ ~(frontier c = {}) + ==> ?z. z IN f /\ z IN c`) THEN + ASM_REWRITE_TAC[FRONTIER_OF_CONNECTED_COMPONENT_SUBSET] THEN + CONJ_TAC THENL + [REWRITE_TAC[frontier] THEN MATCH_MP_TAC(SET_RULE + `c = s ==> c DIFF i SUBSET s`) THEN + ASM_REWRITE_TAC[CLOSURE_EQ] THEN + MATCH_MP_TAC CLOSED_CONNECTED_COMPONENT THEN + ASM_REWRITE_TAC[GSYM OPEN_CLOSED]; + ASM_REWRITE_TAC[FRONTIER_EQ_EMPTY; CONNECTED_COMPONENT_EQ_EMPTY; + CONNECTED_COMPONENT_EQ_UNIV; IN_DIFF; IN_UNIV] THEN + REWRITE_TAC[SET_RULE `UNIV DIFF s = UNIV <=> s = {}`] THEN + ASM_MESON_TAC[BOUNDED_EMPTY]]; + FIRST_X_ASSUM(MP_TAC o SPEC + `connected_component (frontier s) (z:complex)`) THEN + REWRITE_TAC[components; IN_ELIM_THM] THEN + ANTS_TAC THENL [ASM SET_TAC[]; REWRITE_TAC[CONTRAPOS_THM]] THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] BOUNDED_SUBSET) THEN + SUBGOAL_THEN + `connected_component ((:complex) DIFF s) w = + connected_component ((:complex) DIFF s) z` + SUBST1_TAC THENL + [ASM_MESON_TAC[CONNECTED_COMPONENT_EQ]; + MATCH_MP_TAC CONNECTED_COMPONENT_MAXIMAL THEN + ASM_REWRITE_TAC[IN; CONNECTED_COMPONENT_REFL_EQ] THEN + REWRITE_TAC[CONNECTED_CONNECTED_COMPONENT] THEN + MATCH_MP_TAC SUBSET_TRANS THEN + EXISTS_TAC `frontier s :complex->bool` THEN + REWRITE_TAC[CONNECTED_COMPONENT_SUBSET] THEN + REWRITE_TAC[frontier] THEN MATCH_MP_TAC(SET_RULE + `i = s ==> s' DIFF i SUBSET UNIV DIFF s`) THEN + ASM_REWRITE_TAC[INTERIOR_EQ]]]]; + ALL_TAC] THEN + DISCH_THEN(fun th -> + ASSUME_TAC(MATCH_MP SIMPLY_CONNECTED_IMP_CONNECTED th) THEN MP_TAC th) THEN + ASM_SIMP_TAC[SIMPLY_CONNECTED_EQ_HOMEOMORPHIC_TO_DISC] THEN STRIP_TAC THEN + ASM_REWRITE_TAC[BOUNDED_EMPTY; FRONTIER_EMPTY; CONNECTED_EMPTY] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [homeomorphic]) THEN + REWRITE_TAC[LEFT_IMP_EXISTS_THM; homeomorphism] THEN + MAP_EVERY X_GEN_TAC [`g:real^2->real^2`; `f:real^2->real^2`] THEN + STRIP_TAC THEN MAP_EVERY ABBREV_TAC + [`D = \n. ball(vec 0:real^2,&1 - inv(&n + &2))`; + `A = \n. {z:real^2 | &1 - inv(&n + &2) < norm z /\ norm z < &1}`; + `X = \n:num. closure(IMAGE (f:real^2->real^2) (A n))`] THEN + SUBGOAL_THEN + `frontier s = INTERS {X n:real^2->bool | n IN (:num)}` + SUBST1_TAC THENL + [ASM_SIMP_TAC[frontier; INTERIOR_OPEN; INTERS_GSPEC; IN_UNIV] THEN + MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL + [REWRITE_TAC[SUBSET; IN_DIFF] THEN X_GEN_TAC `x:real^2` THEN + STRIP_TAC THEN REWRITE_TAC[IN_ELIM_THM] THEN X_GEN_TAC `n:num` THEN + UNDISCH_TAC `(x:real^2) IN closure s` THEN + SUBGOAL_THEN + `s = IMAGE (f:real^2->real^2) (closure (D(n:num))) UNION IMAGE f (A n)` + SUBST1_TAC THENL + [EXPAND_TAC "s" THEN MATCH_MP_TAC(SET_RULE + `t UNION u = s /\ (!x y. x IN s /\ y IN s /\ f x = f y ==> x = y) + ==> IMAGE f s = IMAGE f t UNION IMAGE f u`) THEN + CONJ_TAC THENL [ALL_TAC; ASM_MESON_TAC[]] THEN + MAP_EVERY EXPAND_TAC ["A"; "D"] THEN + SIMP_TAC[CLOSURE_BALL; REAL_SUB_LT; REAL_INV_LT_1; + REAL_ARITH `&1 < &n + &2`] THEN + REWRITE_TAC[EXTENSION; IN_UNION; COMPLEX_IN_BALL_0; IN_CBALL_0; + IN_ELIM_THM] THEN GEN_TAC THEN + MATCH_MP_TAC(REAL_ARITH + `&0 < e /\ e <= &1 + ==> (x <= &1 - e \/ &1 - e < x /\ x < &1 <=> x < &1)`) THEN + SIMP_TAC[REAL_LT_INV_EQ; REAL_INV_LE_1; REAL_ARITH `&1 <= &n + &2`; + REAL_ARITH `&0 < &n + &2`]; + EXPAND_TAC "X" THEN REWRITE_TAC[CLOSURE_UNION] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE + `~(x IN s) ==> t SUBSET s ==> x IN t UNION u ==> x IN u`)) THEN + EXPAND_TAC "D" THEN + SIMP_TAC[CLOSURE_BALL; REAL_SUB_LT; REAL_INV_LT_1; + REAL_ARITH `&1 < &n + &2`; COMPACT_CBALL] THEN + MATCH_MP_TAC(SET_RULE + `closure s = s /\ s SUBSET t ==> closure s SUBSET t`) THEN + CONJ_TAC THENL + [MATCH_MP_TAC CLOSURE_CLOSED THEN MATCH_MP_TAC COMPACT_IMP_CLOSED THEN + MATCH_MP_TAC COMPACT_CONTINUOUS_IMAGE THEN + REWRITE_TAC[COMPACT_CBALL] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP(REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET)); + EXPAND_TAC "s" THEN MATCH_MP_TAC IMAGE_SUBSET] THEN + REWRITE_TAC[SUBSET; COMPLEX_IN_BALL_0; IN_CBALL_0] THEN GEN_TAC THEN + MATCH_MP_TAC(REAL_ARITH `&0 < x ==> a <= &1 - x ==> a < &1`) THEN + REWRITE_TAC[REAL_LT_INV_EQ] THEN REAL_ARITH_TAC]; + MATCH_MP_TAC(SET_RULE + `s SUBSET t /\ s INTER u = {} ==> s SUBSET t DIFF u`) THEN + CONJ_TAC THENL + [EXPAND_TAC "X" THEN REWRITE_TAC[SUBSET; IN_ELIM_THM] THEN + X_GEN_TAC `x:real^2` THEN DISCH_THEN(MP_TAC o SPEC `0`) THEN + SPEC_TAC(`x:real^2`,`x:real^2`) THEN REWRITE_TAC[GSYM SUBSET] THEN + MATCH_MP_TAC SUBSET_CLOSURE THEN EXPAND_TAC "s" THEN + MATCH_MP_TAC IMAGE_SUBSET THEN EXPAND_TAC "A" THEN + REWRITE_TAC[SUBSET; IN_ELIM_THM; COMPLEX_IN_BALL_0] THEN + REAL_ARITH_TAC; + REWRITE_TAC[EXTENSION; IN_INTER; IN_ELIM_THM; NOT_IN_EMPTY] THEN + MAP_EVERY EXPAND_TAC ["s"; "X"] THEN + REWRITE_TAC[TAUT `~(a /\ b) <=> b ==> ~a`; FORALL_IN_IMAGE] THEN + X_GEN_TAC `x:real^2` THEN REWRITE_TAC[COMPLEX_IN_BALL_0] THEN + DISCH_TAC THEN MP_TAC(SPEC `&1 - norm(x:real^2)` REAL_ARCH_INV) THEN + ASM_REWRITE_TAC[REAL_SUB_LT; NOT_FORALL_THM] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `n:num` THEN STRIP_TAC THEN + MATCH_MP_TAC(SET_RULE + `!s. y IN s /\ (s INTER t = {}) ==> ~(y IN t)`) THEN + EXISTS_TAC `IMAGE (f:real^2->real^2) (D(n:num))` THEN CONJ_TAC THENL + [MATCH_MP_TAC FUN_IN_IMAGE THEN EXPAND_TAC "D" THEN + REWRITE_TAC[IN_BALL_0] THEN FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP + (REAL_ARITH `n < &1 - x ==> m < n ==> x < &1 - m`)) THEN + MATCH_MP_TAC REAL_LT_INV2 THEN + ASM_SIMP_TAC[REAL_OF_NUM_LT; LE_1] THEN REAL_ARITH_TAC; + SUBGOAL_THEN `open(IMAGE (f:real^2->real^2) (D(n:num)))` MP_TAC THENL + [MATCH_MP_TAC INVARIANCE_OF_DOMAIN THEN + SUBGOAL_THEN `(D:num->real^2->bool) n SUBSET ball(Cx(&0),&1)` + ASSUME_TAC THENL + [EXPAND_TAC "D" THEN REWRITE_TAC[GSYM COMPLEX_VEC_0] THEN + MATCH_MP_TAC SUBSET_BALL THEN + REWRITE_TAC[REAL_ARITH `&1 - x <= &1 <=> &0 <= x`] THEN + REWRITE_TAC[REAL_LE_INV_EQ] THEN REAL_ARITH_TAC; + REPEAT CONJ_TAC THENL + [ASM_MESON_TAC[CONTINUOUS_ON_SUBSET]; + EXPAND_TAC "D" THEN REWRITE_TAC[OPEN_BALL]; + ASM SET_TAC[]]]; + SIMP_TAC[OPEN_INTER_CLOSURE_EQ_EMPTY] THEN DISCH_TAC THEN + MATCH_MP_TAC(SET_RULE + `!u. (!x y. x IN u /\ y IN u /\ f x = f y ==> x = y) /\ + s UNION t SUBSET u /\ s INTER t = {} + ==> IMAGE f s INTER IMAGE f t = {}`) THEN + EXISTS_TAC `ball(Cx(&0),&1)` THEN + CONJ_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN + MAP_EVERY EXPAND_TAC ["D"; "A"] THEN + REWRITE_TAC[COMPLEX_IN_BALL_0; IN_BALL_0; SUBSET; NOT_IN_EMPTY; + IN_UNION; IN_ELIM_THM; IN_INTER; EXTENSION] THEN + CONJ_TAC THENL [GEN_TAC; REAL_ARITH_TAC] THEN + MATCH_MP_TAC(REAL_ARITH + `&0 < e ==> x < &1 - e \/ &1 - e < x /\ x < &1 ==> x < &1`) THEN + REWRITE_TAC[REAL_LT_INV_EQ] THEN REAL_ARITH_TAC]]]]; + ALL_TAC] THEN + SUBGOAL_THEN `!n. closed((X:num->complex->bool) n)` ASSUME_TAC THENL + [EXPAND_TAC "X" THEN REWRITE_TAC[CLOSED_CLOSURE]; ALL_TAC] THEN + SUBGOAL_THEN `!n. connected((X:num->complex->bool) n)` ASSUME_TAC THENL + [X_GEN_TAC `n:num` THEN EXPAND_TAC "X" THEN + MATCH_MP_TAC CONNECTED_CLOSURE THEN + MATCH_MP_TAC CONNECTED_CONTINUOUS_IMAGE THEN + EXPAND_TAC "A" THEN CONJ_TAC THENL + [FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP(REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET)) THEN + SIMP_TAC[SUBSET; COMPLEX_IN_BALL_0; IN_ELIM_THM]; + ONCE_REWRITE_TAC[NORM_ARITH `norm z = norm(z - vec 0)`] THEN + SIMP_TAC[CONNECTED_ANNULUS; DIMINDEX_2; LE_REFL]]; + ALL_TAC] THEN + SUBGOAL_THEN + `!n. ((X:num->complex->bool) n) SUBSET closure s` + ASSUME_TAC THENL + [GEN_TAC THEN EXPAND_TAC "X" THEN REWRITE_TAC[] THEN + MATCH_MP_TAC SUBSET_CLOSURE THEN EXPAND_TAC "s" THEN + MATCH_MP_TAC IMAGE_SUBSET THEN EXPAND_TAC "A" THEN + SIMP_TAC[SUBSET; COMPLEX_IN_BALL_0; IN_ELIM_THM]; + ALL_TAC] THEN + SUBGOAL_THEN `!m n. m <= n ==> (X:num->complex->bool) n SUBSET X m` + ASSUME_TAC THENL + [MAP_EVERY X_GEN_TAC [`m:num`; `n:num`] THEN STRIP_TAC THEN + EXPAND_TAC "X" THEN MATCH_MP_TAC SUBSET_CLOSURE THEN + MATCH_MP_TAC IMAGE_SUBSET THEN EXPAND_TAC "A" THEN + REWRITE_TAC[SUBSET; IN_ELIM_THM] THEN GEN_TAC THEN + MATCH_MP_TAC(REAL_ARITH + `n <= m ==> &1 - n < x /\ x < &1 ==> &1 - m < x /\ x < &1`) THEN + MATCH_MP_TAC REAL_LE_INV2 THEN + ASM_REWRITE_TAC[REAL_LE_RADD; REAL_OF_NUM_LE] THEN REAL_ARITH_TAC; + ALL_TAC] THEN + COND_CASES_TAC THENL + [MATCH_MP_TAC CONNECTED_NEST THEN + ASM_REWRITE_TAC[COMPACT_EQ_BOUNDED_CLOSED] THEN + ASM_MESON_TAC[BOUNDED_SUBSET; BOUNDED_CLOSURE]; + ALL_TAC] THEN + SUBGOAL_THEN `!n. ~(bounded((X:num->complex->bool) n))` ASSUME_TAC THENL + [X_GEN_TAC `n:num` THEN DISCH_TAC THEN + UNDISCH_TAC `~bounded(s:complex->bool)` THEN EXPAND_TAC "s" THEN + REWRITE_TAC[] THEN MATCH_MP_TAC BOUNDED_SUBSET THEN EXISTS_TAC + `IMAGE (f:complex->complex) + (cball(Cx(&0),&1 - inv(&n + &2)) UNION A n)` THEN + CONJ_TAC THENL + [REWRITE_TAC[IMAGE_UNION; BOUNDED_UNION] THEN CONJ_TAC THENL + [MATCH_MP_TAC COMPACT_IMP_BOUNDED THEN + MATCH_MP_TAC COMPACT_CONTINUOUS_IMAGE THEN SIMP_TAC[COMPACT_CBALL] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP(REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET)) THEN + SIMP_TAC[SUBSET; COMPLEX_IN_CBALL_0; COMPLEX_IN_BALL_0] THEN + GEN_TAC THEN MATCH_MP_TAC(REAL_ARITH + `&0 < e ==> x <= &1 - e ==> x < &1`) THEN + ASM_REWRITE_TAC[REAL_LT_INV_EQ] THEN REAL_ARITH_TAC; + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP(REWRITE_RULE[IMP_CONJ] + BOUNDED_SUBSET)) THEN EXPAND_TAC "X" THEN + REWRITE_TAC[CLOSURE_SUBSET]]; + MATCH_MP_TAC IMAGE_SUBSET THEN EXPAND_TAC "A" THEN + REWRITE_TAC[SUBSET; IN_UNION; COMPLEX_IN_BALL_0; COMPLEX_IN_CBALL_0; + IN_ELIM_THM] THEN REAL_ARITH_TAC]; + ALL_TAC] THEN + X_GEN_TAC `c:complex->bool` THEN REPEAT DISCH_TAC THEN + SUBGOAL_THEN `closed(INTERS {X n:complex->bool | n IN (:num)})` + ASSUME_TAC THENL + [ASM_SIMP_TAC[CLOSED_INTERS; FORALL_IN_GSPEC]; ALL_TAC] THEN + SUBGOAL_THEN `closed(c:complex->bool)` ASSUME_TAC THENL + [ASM_MESON_TAC[CLOSED_COMPONENTS]; ALL_TAC] THEN + SUBGOAL_THEN `compact(c:complex->bool)` ASSUME_TAC THENL + [ASM_REWRITE_TAC[COMPACT_EQ_BOUNDED_CLOSED]; ALL_TAC] THEN + SUBGOAL_THEN + `?k:complex->bool. + c SUBSET k /\ compact k /\ + k SUBSET INTERS {X n | n IN (:num)} /\ + closed(INTERS {X n | n IN (:num)} DIFF k)` + STRIP_ASSUME_TAC THENL + [MP_TAC(ISPECL[`INTERS {X n:complex->bool | n IN (:num)}`;`c:complex->bool`] + SURA_BURA_CLOSED) THEN + ASM_REWRITE_TAC[OPEN_IN_CLOSED_IN_EQ; TOPSPACE_EUCLIDEAN_SUBTOPOLOGY] THEN + MATCH_MP_TAC(MESON[] + `~(c = i {}) /\ (~(f = {}) ==> P) + ==> c = i f ==> P`) THEN + CONJ_TAC THENL + [REWRITE_TAC[INTERS_0] THEN ASM_MESON_TAC[NOT_BOUNDED_UNIV]; + REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN MATCH_MP_TAC MONO_EXISTS THEN + X_GEN_TAC `k:complex->bool` THEN REWRITE_TAC[IN_ELIM_THM] THEN + ASM_MESON_TAC[CLOSED_IN_CLOSED_TRANS]]; + ALL_TAC] THEN + MP_TAC(ISPECL [`k:complex->bool`; + `INTERS {X n:complex->bool | n IN (:num)} DIFF k`] + SEPARATION_NORMAL_COMPACT) THEN + ASM_SIMP_TAC[NOT_EXISTS_THM; SET_RULE `k INTER (s DIFF k) = {}`] THEN + MAP_EVERY X_GEN_TAC [`v:complex->bool`; `v':complex->bool`] THEN + STRIP_TAC THEN + SUBGOAL_THEN `v INTER (INTERS {X n:complex->bool | n IN (:num)} DIFF k) = {}` + ASSUME_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + MP_TAC(ISPECL + [`closure(v) DIFF v:complex->bool`; + `{X n INTER closure(v:complex->bool) | n IN (:num)}`] + COMPACT_IMP_FIP) THEN + ASM_SIMP_TAC[COMPACT_DIFF; FORALL_IN_GSPEC; CLOSED_INTER; CLOSED_CLOSURE; + NOT_IMP] THEN + CONJ_TAC THENL + [ALL_TAC; + SUBGOAL_THEN + `INTERS {X n INTER closure v :complex->bool | n IN (:num)} = + INTERS {X n | n IN (:num)} INTER closure v` + SUBST1_TAC THENL + [REWRITE_TAC[INTERS_GSPEC; EXTENSION; IN_ELIM_THM; IN_INTER; IN_UNIV] THEN + MESON_TAC[]; + MP_TAC(ISPECL [`v':complex->bool`; `v:complex->bool`] + OPEN_INTER_CLOSURE_EQ_EMPTY) THEN + ASM_REWRITE_TAC[] THEN ASM SET_TAC[]]] THEN + ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN + REWRITE_TAC[FINITE_SUBSET_IMAGE; SUBSET_UNIV; LEFT_IMP_EXISTS_THM] THEN + ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN + REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_UNWIND_THM2] THEN + X_GEN_TAC `i:num->bool` THEN STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o SPEC `\n:num. n` o MATCH_MP UPPER_BOUND_FINITE_SET) THEN + REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN X_GEN_TAC `n:num` THEN DISCH_TAC THEN + ASM_CASES_TAC `i:num->bool = {}` THENL + [ASM_REWRITE_TAC[IMAGE_CLAUSES; INTERS_0; INTER_UNIV] THEN + MP_TAC(ISPEC `v:complex->bool` FRONTIER_EQ_EMPTY) THEN + ASM_SIMP_TAC[frontier; INTERIOR_OPEN] THEN DISCH_THEN SUBST1_TAC THEN + DISCH_THEN(DISJ_CASES_THEN SUBST_ALL_TAC) THENL + [FIRST_ASSUM(MP_TAC o MATCH_MP IN_COMPONENTS_NONEMPTY) THEN + ASM SET_TAC[]; + ASM_MESON_TAC[CLOSURE_UNIV; COMPACT_IMP_BOUNDED; NOT_BOUNDED_UNIV]]; + ALL_TAC] THEN + SUBGOAL_THEN `?n:num. n IN i /\ !m. m IN i ==> m <= n` + (X_CHOOSE_TAC `p:num`) THENL + [MAP_EVERY UNDISCH_TAC [`~(i:num->bool = {})`; `FINITE(i:num->bool)`] THEN + POP_ASSUM_LIST(K ALL_TAC) THEN SPEC_TAC(`i:num->bool`,`i:num->bool`) THEN + MATCH_MP_TAC FINITE_INDUCT_STRONG THEN + REWRITE_TAC[EXISTS_IN_INSERT; FORALL_IN_INSERT; NOT_INSERT_EMPTY] THEN + MAP_EVERY X_GEN_TAC [`n:num`; `i:num->bool`] THEN + ASM_CASES_TAC `i:num->bool = {}` THEN + ASM_REWRITE_TAC[LE_REFL; NOT_IN_EMPTY] THEN + DISCH_THEN(X_CHOOSE_THEN `p:num` STRIP_ASSUME_TAC o CONJUNCT1) THEN + DISJ_CASES_TAC(ARITH_RULE `n:num <= p \/ p <= n`) THEN + ASM_MESON_TAC[LE_TRANS]; + ALL_TAC] THEN + SUBGOAL_THEN + `INTERS (IMAGE (\n:num. X n INTER closure v) i):complex->bool = + X p INTER closure v` + SUBST1_TAC THENL + [REWRITE_TAC[EXTENSION; INTERS_IMAGE; IN_ELIM_THM; IN_INTER] THEN + ASM SET_TAC[]; + ALL_TAC] THEN + DISCH_THEN(ASSUME_TAC o MATCH_MP (SET_RULE + `(c DIFF v) INTER (x INTER c) = {} ==> x INTER c SUBSET v`)) THEN + SUBGOAL_THEN `connected((X:num->complex->bool) p)` MP_TAC THENL + [ASM_MESON_TAC[]; ALL_TAC] THEN + REWRITE_TAC[CONNECTED_CLOPEN] THEN + DISCH_THEN(MP_TAC o SPEC `(X:num->complex->bool) p INTER closure v`) THEN + REWRITE_TAC[NOT_IMP; DE_MORGAN_THM] THEN REPEAT CONJ_TAC THENL + [SUBGOAL_THEN `(X:num->complex->bool) p INTER closure v = X p INTER v` + SUBST1_TAC THENL + [MP_TAC(ISPEC `v:complex->bool` CLOSURE_SUBSET) THEN ASM SET_TAC[]; + MATCH_MP_TAC OPEN_IN_OPEN_INTER THEN ASM_REWRITE_TAC[]]; + MATCH_MP_TAC CLOSED_IN_CLOSED_INTER THEN REWRITE_TAC[CLOSED_CLOSURE]; + MATCH_MP_TAC(SET_RULE `!k. k SUBSET s /\ ~(k = {}) ==> ~(s = {})`) THEN + EXISTS_TAC `k:complex->bool` THEN CONJ_TAC THENL + [MP_TAC(ISPEC `v:complex->bool` CLOSURE_SUBSET) THEN ASM SET_TAC[]; + FIRST_ASSUM(MP_TAC o MATCH_MP IN_COMPONENTS_NONEMPTY) THEN + ASM SET_TAC[]]; + DISCH_THEN(MP_TAC o AP_TERM `bounded:(complex->bool)->bool`) THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC BOUNDED_SUBSET THEN + EXISTS_TAC `closure v:complex->bool` THEN + ASM_SIMP_TAC[COMPACT_IMP_BOUNDED] THEN SET_TAC[]]);; + +(* ------------------------------------------------------------------------- *) +(* Yet another set of equivalences based on *continuous* logs and sqrts. *) +(* ------------------------------------------------------------------------- *) + +let SIMPLY_CONNECTED_EQ_CONTINUOUS_LOG,SIMPLY_CONNECTED_EQ_CONTINUOUS_SQRT = + (CONJ_PAIR o prove) + (`(!s. open s + ==> (simply_connected s <=> + connected s /\ + !f. f continuous_on s /\ (!z:complex. z IN s ==> ~(f z = Cx(&0))) + ==> ?g. g continuous_on s /\ + !z. z IN s ==> f z = cexp(g z))) /\ + (!s. open s + ==> (simply_connected s <=> + connected s /\ + !f. f continuous_on s /\ (!z:complex. z IN s ==> ~(f z = Cx(&0))) + ==> ?g. g continuous_on s /\ + !z. z IN s ==> f z = g z pow 2))`, + REWRITE_TAC[AND_FORALL_THM] THEN X_GEN_TAC `s:complex->bool` THEN + ASM_CASES_TAC `open(s:complex->bool)` THEN ASM_REWRITE_TAC[] THEN + ASM_CASES_TAC `connected(s:complex->bool)` THEN ASM_REWRITE_TAC[] THENL + [ALL_TAC; ASM_MESON_TAC[SIMPLY_CONNECTED_IMP_CONNECTED]] THEN + MATCH_MP_TAC(TAUT + `(p ==> q) /\ (q ==> r) /\ (r ==> p) ==> (p <=> q) /\ (p <=> r)`) THEN + REPEAT CONJ_TAC THENL + [ASM_SIMP_TAC[SIMPLY_CONNECTED_EQ_HOMEOMORPHIC_TO_DISC] THEN + STRIP_TAC THEN ASM_REWRITE_TAC[CONTINUOUS_ON_EMPTY; NOT_IN_EMPTY] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [homeomorphic]) THEN + REWRITE_TAC[homeomorphism; LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`k:complex->complex`; `h:complex->complex`] THEN + STRIP_TAC THEN X_GEN_TAC `f:complex->complex` THEN STRIP_TAC THEN + MP_TAC(ISPECL + [`(f:complex->complex) o (h:complex->complex)`; `Cx(&0)`; `&1`] + CONTINUOUS_LOGARITHM_ON_BALL) THEN + ASM_REWRITE_TAC[o_THM] THEN ANTS_TAC THENL + [CONJ_TAC THENL [ALL_TAC; ASM SET_TAC[]] THEN + MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN + ASM_MESON_TAC[CONTINUOUS_ON_SUBSET]; + DISCH_THEN(X_CHOOSE_THEN `g:complex->complex` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `(g:complex->complex) o (k:complex->complex)` THEN + REWRITE_TAC[o_THM] THEN CONJ_TAC THENL [ALL_TAC; ASM SET_TAC[]] THEN + MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN + ASM_MESON_TAC[CONTINUOUS_ON_SUBSET]]; + DISCH_TAC THEN X_GEN_TAC `f:complex->complex` THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `f:complex->complex`) THEN ASM_SIMP_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `g:complex->complex` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `\z:complex. cexp(g z / Cx(&2))` THEN + ASM_SIMP_TAC[GSYM CEXP_N; COMPLEX_RING `Cx(&2) * z / Cx(&2) = z`] THEN + GEN_REWRITE_TAC LAND_CONV [GSYM o_DEF] THEN + MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN + REWRITE_TAC[CONTINUOUS_ON_CEXP] THEN + MATCH_MP_TAC CONTINUOUS_ON_COMPLEX_DIV THEN + ASM_SIMP_TAC[CONTINUOUS_ON_CONST] THEN + CONV_TAC COMPLEX_RING; + DISCH_TAC THEN ASM_SIMP_TAC[SIMPLY_CONNECTED_EQ_HOLOMORPHIC_SQRT] THEN + X_GEN_TAC `f:complex->complex` THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `f:complex->complex`) THEN + ASM_SIMP_TAC[HOLOMORPHIC_ON_IMP_CONTINUOUS_ON] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `g:complex->complex` THEN + STRIP_TAC THEN ASM_SIMP_TAC[HOLOMORPHIC_ON_OPEN] THEN + X_GEN_TAC `z:complex` THEN DISCH_TAC THEN + SUBGOAL_THEN `~((g:complex->complex) z = Cx(&0))` ASSUME_TAC THENL + [ASM_MESON_TAC[COMPLEX_RING `Cx(&0) pow 2 = Cx(&0)`]; ALL_TAC] THEN + EXISTS_TAC `complex_derivative f z / (Cx(&2) * g z)` THEN + REWRITE_TAC[HAS_COMPLEX_DERIVATIVE_AT] THEN + MATCH_MP_TAC LIM_TRANSFORM_WITHIN_OPEN THEN + EXISTS_TAC `\x:complex. (f(x) - f(z)) / (x - z) / (g(x) + g(z))` THEN + SUBGOAL_THEN + `?d. &0 < d /\ + !w:complex. w IN s /\ w IN ball(z,d) ==> ~(g w + g z = Cx(&0))` + STRIP_ASSUME_TAC THENL + [FIRST_ASSUM(MP_TAC o SPEC `z:complex` o + GEN_REWRITE_RULE I [continuous_on]) THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(MP_TAC o SPEC `norm((g:complex->complex) z)`) THEN + ASM_REWRITE_TAC[COMPLEX_NORM_NZ] THEN MATCH_MP_TAC MONO_EXISTS THEN + ONCE_REWRITE_TAC[DIST_SYM] THEN + REWRITE_TAC[IN_BALL; GSYM COMPLEX_VEC_0] THEN + MESON_TAC[NORM_ARITH `dist(z,x) < norm z ==> ~(x + z = vec 0)`]; + ALL_TAC] THEN + EXISTS_TAC `ball(z:complex,d) INTER s` THEN + ASM_REWRITE_TAC[IN_INTER; CENTRE_IN_BALL] THEN REPEAT CONJ_TAC THENL + [ASM_SIMP_TAC[OPEN_INTER; OPEN_BALL]; + ASM_SIMP_TAC[] THEN REPEAT STRIP_TAC THEN MATCH_MP_TAC(COMPLEX_FIELD + `~(x = z) /\ ~(gx + gz = Cx(&0)) + ==> (gx pow 2 - gz pow 2) / (x - z) / (gx + gz) = + (gx - gz) / (x - z)`) THEN + ASM_SIMP_TAC[]; + MATCH_MP_TAC LIM_COMPLEX_DIV THEN + ASM_REWRITE_TAC[COMPLEX_ENTIRE; GSYM HAS_COMPLEX_DERIVATIVE_AT] THEN + REWRITE_TAC[HAS_COMPLEX_DERIVATIVE_DIFFERENTIABLE; CX_INJ] THEN + REWRITE_TAC[COMPLEX_MUL_2; REAL_OF_NUM_EQ; ARITH_EQ] THEN CONJ_TAC THENL + [ASM_MESON_TAC[HOLOMORPHIC_ON_IMP_DIFFERENTIABLE_AT]; ALL_TAC] THEN + MATCH_MP_TAC LIM_ADD THEN REWRITE_TAC[LIM_CONST; GSYM CONTINUOUS_AT] THEN + ASM_MESON_TAC[HOLOMORPHIC_ON_IMP_CONTINUOUS_ON; + CONTINUOUS_ON_INTERIOR; INTERIOR_OPEN]]]);; + +(* ------------------------------------------------------------------------- *) +(* A per-function version for continuous logs, a kind of monodromy. *) +(* ------------------------------------------------------------------------- *) + +let WINDING_NUMBER_COMPOSE_CEXP = prove + (`!p. path p + ==> winding_number(cexp o p,Cx(&0)) = + Cx(&1) / (Cx(&2) * Cx pi * ii) * (pathfinish p - pathstart p)`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN + `?e. &0 < e /\ + !t:real^1. t IN interval[vec 0,vec 1] ==> e <= norm(cexp(p t))` + STRIP_ASSUME_TAC THENL + [EXISTS_TAC `setdist({Cx(&0)},path_image (cexp o p))` THEN + REWRITE_TAC[SETDIST_POS_LE; REAL_ARITH + `&0 < x <=> &0 <= x /\ ~(x = &0)`] THEN + ASM_SIMP_TAC[PATH_CONTINUOUS_IMAGE; CONTINUOUS_ON_CEXP; CLOSED_SING; + SETDIST_EQ_0_CLOSED_COMPACT; COMPACT_PATH_IMAGE; PATH_IMAGE_NONEMPTY] THEN + REWRITE_TAC[NOT_INSERT_EMPTY; path_image; IMAGE_o] THEN CONJ_TAC THENL + [MP_TAC CEXP_NZ THEN SET_TAC[]; REPEAT STRIP_TAC] THEN + ONCE_REWRITE_TAC[GSYM NORM_NEG] THEN + REWRITE_TAC[COMPLEX_RING `--x = Cx(&0) - x`] THEN + REWRITE_TAC[GSYM dist] THEN MATCH_MP_TAC SETDIST_LE_DIST THEN + ASM SET_TAC[]; + ALL_TAC] THEN + MP_TAC(ISPECL [`path_image(p:real^1->complex)`; `Cx(&0)`] + BOUNDED_SUBSET_CBALL) THEN + ASM_SIMP_TAC[BOUNDED_PATH_IMAGE; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `B:real` THEN REWRITE_TAC[SUBSET; COMPLEX_IN_CBALL_0] THEN + STRIP_TAC THEN + MP_TAC(ISPECL [`cexp`; `cball(Cx(&0),B + &1)`] + COMPACT_UNIFORMLY_CONTINUOUS) THEN + REWRITE_TAC[CONTINUOUS_ON_CEXP; COMPACT_CBALL] THEN + REWRITE_TAC[uniformly_continuous_on] THEN + DISCH_THEN(MP_TAC o SPEC `e:real`) THEN + ASM_REWRITE_TAC[COMPLEX_IN_CBALL_0] THEN + DISCH_THEN(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC) THEN + MP_TAC(ISPECL [`p:real^1->complex`; `min (&1) d`] + PATH_APPROX_VECTOR_POLYNOMIAL_FUNCTION) THEN + ASM_REWRITE_TAC[REAL_LT_MIN; REAL_LT_01; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `g:real^1->complex` THEN STRIP_TAC THEN MATCH_MP_TAC EQ_TRANS THEN + EXISTS_TAC `winding_number(cexp o g,Cx(&0))` THEN CONJ_TAC THENL + [CONV_TAC SYM_CONV THEN MATCH_MP_TAC WINDING_NUMBER_NEARBY_PATHS_EQ THEN + ASM_SIMP_TAC[PATH_CONTINUOUS_IMAGE; CONTINUOUS_ON_CEXP; + PATH_VECTOR_POLYNOMIAL_FUNCTION] THEN + ASM_REWRITE_TAC[PATHSTART_COMPOSE; PATHFINISH_COMPOSE] THEN + REPEAT STRIP_TAC THEN REWRITE_TAC[COMPLEX_SUB_RZERO; o_THM] THEN + REWRITE_TAC[GSYM dist] THEN MATCH_MP_TAC REAL_LTE_TRANS THEN + EXISTS_TAC `e:real` THEN ASM_SIMP_TAC[] THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_SIMP_TAC[dist] THEN + MATCH_MP_TAC(NORM_ARITH + `norm(g - p) < &1 /\ norm(p) <= B + ==> norm(p) <= B + &1 /\ norm(g) <= B + &1`) THEN + ASM_SIMP_TAC[] THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + REWRITE_TAC[path_image] THEN ASM SET_TAC[]; + W(MP_TAC o + PART_MATCH (lhs o rand) WINDING_NUMBER_VALID_PATH o lhs o snd) THEN + REWRITE_TAC[PATH_INTEGRAL_INTEGRAL; COMPLEX_SUB_RZERO] THEN ANTS_TAC THENL + [REWRITE_TAC[path_image; IN_IMAGE; o_THM; CEXP_NZ] THEN + REWRITE_TAC[valid_path] THEN + MATCH_MP_TAC DIFFERENTIABLE_ON_IMP_PIECEWISE_DIFFERENTIABLE THEN + MATCH_MP_TAC DIFFERENTIABLE_ON_COMPOSE THEN + REWRITE_TAC[differentiable_on] THEN REPEAT STRIP_TAC THENL + [MATCH_MP_TAC DIFFERENTIABLE_AT_WITHIN THEN + REWRITE_TAC[differentiable] THEN + ASM_MESON_TAC[has_vector_derivative; + HAS_VECTOR_DERIVATIVE_VECTOR_POLYNOMIAL_FUNCTION]; + GEN_REWRITE_TAC LAND_CONV [GSYM ETA_AX] THEN + MATCH_MP_TAC COMPLEX_DIFFERENTIABLE_IMP_DIFFERENTIABLE THEN + COMPLEX_DIFFERENTIABLE_TAC]; + DISCH_THEN SUBST1_TAC THEN AP_TERM_TAC THEN MATCH_MP_TAC EQ_TRANS THEN + EXISTS_TAC `integral (interval [vec 0,vec 1]) + (\x. vector_derivative (g:real^1->complex) (at x))` THEN + CONJ_TAC THENL + [MATCH_MP_TAC INTEGRAL_EQ THEN X_GEN_TAC `t:real^1` THEN DISCH_TAC THEN + REWRITE_TAC[o_THM] THEN MATCH_MP_TAC(COMPLEX_FIELD + `~(e = Cx(&0)) /\ v' = e * v ==> Cx(&1) / e * v' = v`) THEN + REWRITE_TAC[CEXP_NZ] THEN + MATCH_MP_TAC HAS_VECTOR_DERIVATIVE_UNIQUE_AT THEN + MP_TAC(ISPECL [`g:real^1->complex`; `cexp`; + `\h. drop h % vector_derivative (g:real^1->complex) (at t)`; + `\w. cexp(g(t:real^1)) * w`; `t:real^1`] + DIFF_CHAIN_AT) THEN + REWRITE_TAC[GSYM has_vector_derivative; GSYM has_complex_derivative; + GSYM VECTOR_DERIVATIVE_WORKS; + HAS_COMPLEX_DERIVATIVE_CEXP; differentiable] THEN + ANTS_TAC THENL + [ASM_MESON_TAC[HAS_VECTOR_DERIVATIVE_VECTOR_POLYNOMIAL_FUNCTION; + has_vector_derivative]; + REWRITE_TAC[has_vector_derivative; o_DEF] THEN + MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_TERM_TAC THEN + REWRITE_TAC[FUN_EQ_THM; COMPLEX_CMUL] THEN + CONV_TAC COMPLEX_RING]; + MP_TAC(ISPECL [`g:real^1->complex`; + `\x. vector_derivative (g:real^1->complex) (at x)`; + `vec 0:real^1`; `vec 1:real^1`] + FUNDAMENTAL_THEOREM_OF_CALCULUS) THEN + ASM_REWRITE_TAC[DROP_VEC; REAL_POS] THEN ANTS_TAC THENL + [REPEAT STRIP_TAC THEN + MATCH_MP_TAC HAS_VECTOR_DERIVATIVE_AT_WITHIN THEN + REWRITE_TAC[GSYM VECTOR_DERIVATIVE_WORKS] THEN + REWRITE_TAC[differentiable] THEN + ASM_MESON_TAC[has_vector_derivative; + HAS_VECTOR_DERIVATIVE_VECTOR_POLYNOMIAL_FUNCTION]; + DISCH_THEN(SUBST1_TAC o MATCH_MP INTEGRAL_UNIQUE) THEN + RULE_ASSUM_TAC(REWRITE_RULE[pathstart; pathfinish]) THEN + ASM_REWRITE_TAC[pathstart; pathfinish]]]]]);; + +let MONODROMY_CONTINUOUS_LOG = prove + (`!f:complex->complex s. + open s /\ f continuous_on s /\ + (!z. z IN s ==> ~(f z = Cx(&0))) + ==> ((!p. path p /\ path_image p SUBSET s /\ + pathfinish p = pathstart p + ==> winding_number(f o p,Cx(&0)) = Cx(&0)) <=> + (?g. g continuous_on s /\ !z. z IN s ==> f(z) = cexp(g z)))`, + let lemma = prove + (`!f g s p. + f continuous_on s /\ g continuous_on s /\ + (!z:complex. z IN s ==> f(z) = cexp(g z)) /\ + path p /\ path_image p SUBSET s + ==> winding_number(f o p,Cx(&0)) = + Cx(&1) / (Cx(&2) * Cx pi * ii) * + (pathfinish(g o p) - pathstart(g o p))`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC EQ_TRANS THEN + EXISTS_TAC `winding_number(cexp o g o (p:real^1->complex),Cx(&0))` THEN + CONJ_TAC THENL + [MATCH_MP_TAC WINDING_NUMBER_NEARBY_PATHS_EQ THEN + REPEAT CONJ_TAC THENL + [MATCH_MP_TAC PATH_CONTINUOUS_IMAGE THEN + REWRITE_TAC[CONTINUOUS_ON_CEXP] THEN + MATCH_MP_TAC PATH_CONTINUOUS_IMAGE THEN + ASM_MESON_TAC[CONTINUOUS_ON_SUBSET]; + MATCH_MP_TAC PATH_CONTINUOUS_IMAGE THEN + ASM_MESON_TAC[CONTINUOUS_ON_SUBSET]; + REWRITE_TAC[PATHSTART_COMPOSE] THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_MESON_TAC[SUBSET; PATHSTART_IN_PATH_IMAGE]; + REWRITE_TAC[PATHFINISH_COMPOSE] THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_MESON_TAC[SUBSET; PATHFINISH_IN_PATH_IMAGE]; + GEN_TAC THEN DISCH_TAC THEN REWRITE_TAC[o_THM; COMPLEX_SUB_RZERO] THEN + MATCH_MP_TAC(NORM_ARITH + `x = y /\ ~(z = vec 0) ==> norm(x - y) < norm z`) THEN + REWRITE_TAC[COMPLEX_VEC_0; CEXP_NZ] THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_MESON_TAC[SUBSET; path_image; IN_IMAGE]]; + MATCH_MP_TAC WINDING_NUMBER_COMPOSE_CEXP THEN + ASM_REWRITE_TAC[PATHSTART_COMPOSE; PATHFINISH_COMPOSE] THEN + MATCH_MP_TAC PATH_CONTINUOUS_IMAGE THEN + ASM_MESON_TAC[CONTINUOUS_ON_SUBSET]]) in + REPEAT STRIP_TAC THEN EQ_TAC THENL + [ALL_TAC; + DISCH_THEN(X_CHOOSE_THEN `g:complex->complex` STRIP_ASSUME_TAC) THEN + X_GEN_TAC `p:real^1->complex` THEN STRIP_TAC THEN + MP_TAC(ISPECL [`f:complex->complex`; `g:complex->complex`; + `s:complex->bool`; `p:real^1->complex`] + lemma) THEN + ASM_REWRITE_TAC[PATHSTART_COMPOSE; PATHFINISH_COMPOSE] THEN + REWRITE_TAC[COMPLEX_SUB_REFL; COMPLEX_MUL_RZERO]] THEN + DISCH_TAC THEN + EXISTS_TAC `\z. let c = connected_component s (z:complex) in + let z0 = (@) c in + let p = @p. path p /\ path_image p SUBSET c /\ + pathstart p = z0 /\ pathfinish p = z in + Cx(&2) * Cx(pi) * ii * winding_number(f o p,Cx(&0)) + + clog(f z0)` THEN + + CONJ_TAC THENL + [ALL_TAC; + X_GEN_TAC `z:complex` THEN DISCH_TAC THEN REWRITE_TAC[] THEN + REPEAT LET_TAC THEN + SUBGOAL_THEN `(z:complex) IN c` ASSUME_TAC THENL + [ASM_MESON_TAC[CONNECTED_COMPONENT_REFL; IN]; ALL_TAC] THEN + SUBGOAL_THEN `(z0:complex) IN c` ASSUME_TAC THENL + [EXPAND_TAC "z0" THEN REWRITE_TAC[IN] THEN MATCH_MP_TAC SELECT_AX THEN + ASM_MESON_TAC[IN]; + ALL_TAC] THEN + SUBGOAL_THEN `(c:complex->bool) SUBSET s` ASSUME_TAC THENL + [ASM_MESON_TAC[CONNECTED_COMPONENT_SUBSET]; ALL_TAC] THEN + SUBGOAL_THEN `connected(c:complex->bool)` ASSUME_TAC THENL + [ASM_MESON_TAC[CONNECTED_CONNECTED_COMPONENT]; ALL_TAC] THEN + SUBGOAL_THEN `open(c:complex->bool)` ASSUME_TAC THENL + [ASM_MESON_TAC[OPEN_CONNECTED_COMPONENT]; ALL_TAC] THEN + SUBGOAL_THEN `path_connected(c:complex->bool)` ASSUME_TAC THENL + [ASM_MESON_TAC[CONNECTED_OPEN_PATH_CONNECTED]; ALL_TAC] THEN + SUBGOAL_THEN + `path p /\ path_image p SUBSET c /\ + pathstart p = z0 /\ pathfinish p = (z:complex)` + STRIP_ASSUME_TAC THENL + [EXPAND_TAC "p" THEN CONV_TAC SELECT_CONV THEN + FIRST_X_ASSUM(MATCH_MP_TAC o REWRITE_RULE[path_connected]) THEN + ASM_REWRITE_TAC[]; + ALL_TAC] THEN + MP_TAC(ISPECL [`(f:complex->complex) o (p:real^1->complex)`; `Cx(&0)`] + WINDING_NUMBER_AHLFORS_FULL) THEN + REWRITE_TAC[CEXP_ADD] THEN ANTS_TAC THENL + [CONJ_TAC THENL + [MATCH_MP_TAC PATH_CONTINUOUS_IMAGE THEN + ASM_MESON_TAC[CONTINUOUS_ON_SUBSET]; + REWRITE_TAC[path_image; IMAGE_o] THEN + REWRITE_TAC[GSYM path_image] THEN ASM SET_TAC[]]; + ASM_REWRITE_TAC[PATHSTART_COMPOSE; PATHFINISH_COMPOSE] THEN + REWRITE_TAC[COMPLEX_SUB_RZERO] THEN DISCH_THEN SUBST1_TAC THEN + AP_TERM_TAC THEN CONV_TAC SYM_CONV THEN MATCH_MP_TAC CEXP_CLOG THEN + ASM SET_TAC[]]] THEN + MATCH_MP_TAC CONTINUOUS_ON_COMPONENTS THEN + ASM_REWRITE_TAC[] THEN X_GEN_TAC `c:complex->bool` THEN DISCH_TAC THEN + ABBREV_TAC `z0:complex = (@) c` THEN + MATCH_MP_TAC CONTINUOUS_ON_EQ THEN + ABBREV_TAC + `g = \z. let p = @p. path p /\ path_image p SUBSET c /\ + pathstart p = z0 /\ pathfinish p = z in + Cx(&2) * Cx(pi) * ii * winding_number(f o p,Cx(&0)) + + clog(f(z0:complex))` THEN + EXISTS_TAC `g:complex->complex` THEN REWRITE_TAC[] THEN CONJ_TAC THENL + [X_GEN_TAC `z:complex` THEN DISCH_TAC THEN EXPAND_TAC "g" THEN + CONV_TAC(TOP_DEPTH_CONV let_CONV) THEN EXPAND_TAC "z0" THEN + SUBGOAL_THEN `connected_component s (z:complex) = c` + (fun th -> REWRITE_TAC[th]) THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_COMPONENTS]) THEN + ASM_MESON_TAC[CONNECTED_COMPONENT_EQ]; + ALL_TAC] THEN + SUBGOAL_THEN `(z0:complex) IN c` ASSUME_TAC THENL + [EXPAND_TAC "z0" THEN REWRITE_TAC[IN] THEN MATCH_MP_TAC SELECT_AX THEN + FIRST_ASSUM(MP_TAC o MATCH_MP IN_COMPONENTS_NONEMPTY) THEN SET_TAC[]; + ALL_TAC] THEN + SUBGOAL_THEN `(c:complex->bool) SUBSET s` ASSUME_TAC THENL + [ASM_MESON_TAC[IN_COMPONENTS_SUBSET]; ALL_TAC] THEN + SUBGOAL_THEN `connected(c:complex->bool)` ASSUME_TAC THENL + [ASM_MESON_TAC[IN_COMPONENTS_CONNECTED]; ALL_TAC] THEN + SUBGOAL_THEN `open(c:complex->bool)` ASSUME_TAC THENL + [ASM_MESON_TAC[OPEN_COMPONENTS]; ALL_TAC] THEN + SUBGOAL_THEN `path_connected(c:complex->bool)` ASSUME_TAC THENL + [ASM_MESON_TAC[CONNECTED_OPEN_PATH_CONNECTED]; ALL_TAC] THEN + SUBGOAL_THEN + `!x. x IN c + ==> ?p. path (p:real^1->complex) /\ path_image p SUBSET c /\ + pathstart p = z0 /\ pathfinish p = x /\ + g(x) = Cx(&2) * Cx pi * ii * winding_number(f o p,Cx(&0)) + + clog (f z0)` + (LABEL_TAC "*") + THENL + [X_GEN_TAC `z:complex` THEN DISCH_TAC THEN EXPAND_TAC "g" THEN + ABBREV_TAC `p = @p. path p /\ path_image p SUBSET c /\ + pathstart p = z0 /\ pathfinish p = (z:complex)` THEN + EXISTS_TAC `p:real^1->complex` THEN + CONV_TAC(TOP_DEPTH_CONV let_CONV) THEN REWRITE_TAC[] THEN + EXPAND_TAC "p" THEN CONV_TAC SELECT_CONV THEN + FIRST_X_ASSUM(MATCH_MP_TAC o GEN_REWRITE_RULE I [path_connected]) THEN + ASM_REWRITE_TAC[]; + ALL_TAC] THEN + ASM_SIMP_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_AT] THEN + X_GEN_TAC `z:complex` THEN DISCH_TAC THEN + FIRST_ASSUM(MP_TAC o SPEC `z:complex` o GEN_REWRITE_RULE I + [OPEN_CONTAINS_BALL]) THEN + ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN X_GEN_TAC `e:real` THEN + STRIP_TAC THEN + MP_TAC(SPEC `ball(z:complex,e)` SIMPLY_CONNECTED_EQ_CONTINUOUS_LOG) THEN + SIMP_TAC[OPEN_BALL; CONVEX_BALL; CONVEX_IMP_SIMPLY_CONNECTED] THEN + DISCH_THEN(MP_TAC o SPEC `f:complex->complex` o CONJUNCT2) THEN + ANTS_TAC THENL + [ASM_MESON_TAC[CONTINUOUS_ON_SUBSET; SUBSET]; + DISCH_THEN(X_CHOOSE_THEN `l:complex->complex` STRIP_ASSUME_TAC)] THEN + REWRITE_TAC[CONTINUOUS_AT] THEN ONCE_REWRITE_TAC[LIM_NULL] THEN + MATCH_MP_TAC LIM_TRANSFORM_AT THEN + ONCE_REWRITE_TAC[DIST_SYM] THEN EXISTS_TAC + `\w. Cx (&2) * Cx pi * ii * + winding_number((f:complex->complex) o linepath(z,w),Cx(&0))` THEN + EXISTS_TAC `e:real` THEN ASM_REWRITE_TAC[] THEN CONJ_TAC THENL + [X_GEN_TAC `w:complex` THEN STRIP_TAC THEN REMOVE_THEN "*" + (fun th -> MP_TAC(SPEC `w:complex` th) THEN + MP_TAC(SPEC `z:complex` th)) THEN + ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `p:real^1->complex` THEN STRIP_TAC THEN + ANTS_TAC THENL [ASM_MESON_TAC[SUBSET; IN_BALL; DIST_SYM]; ALL_TAC] THEN + DISCH_THEN(X_CHOOSE_THEN `q:real^1->complex` STRIP_ASSUME_TAC) THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC(COMPLEX_RING + `(z + x) - y = Cx(&0) + ==> a * b * c * x = (a * b * c * y + l) - (a * b * c * z + l)`) THEN + FIRST_X_ASSUM(MP_TAC o SPEC + `p ++ linepath(z:complex,w) ++ reversepath q`) THEN + ASM_SIMP_TAC[PATHSTART_JOIN; PATHFINISH_JOIN; + PATHSTART_REVERSEPATH; PATHFINISH_REVERSEPATH; + PATH_JOIN_EQ; PATH_LINEPATH; PATH_REVERSEPATH; + PATHSTART_LINEPATH; PATHFINISH_LINEPATH; PATH_IMAGE_JOIN] THEN + ASM_REWRITE_TAC[UNION_SUBSET; PATH_IMAGE_REVERSEPATH] THEN ANTS_TAC THENL + [REPEAT STRIP_TAC THEN + MATCH_MP_TAC SUBSET_TRANS THEN EXISTS_TAC `c:complex->bool` THEN + ASM_REWRITE_TAC[PATH_IMAGE_LINEPATH] THEN + MATCH_MP_TAC SUBSET_TRANS THEN EXISTS_TAC `ball(z:complex,e)` THEN + ASM_REWRITE_TAC[SEGMENT_CONVEX_HULL] THEN MATCH_MP_TAC HULL_MINIMAL THEN + ASM_REWRITE_TAC[INSERT_SUBSET; CENTRE_IN_BALL; EMPTY_SUBSET] THEN + ASM_REWRITE_TAC[IN_BALL; CONVEX_BALL]; + DISCH_THEN(fun th -> GEN_REWRITE_TAC RAND_CONV [GSYM th]) THEN + REWRITE_TAC[PATH_COMPOSE_JOIN; PATH_COMPOSE_REVERSEPATH] THEN + W(MP_TAC o PART_MATCH (lhand o rand) WINDING_NUMBER_JOIN o + rand o snd) THEN + ANTS_TAC THENL + [ALL_TAC; + DISCH_THEN SUBST1_TAC THEN + REWRITE_TAC[VECTOR_SUB; GSYM VECTOR_ADD_ASSOC] THEN + AP_TERM_TAC THEN + W(MP_TAC o PART_MATCH (lhand o rand) WINDING_NUMBER_JOIN o + rand o snd) THEN + ANTS_TAC THENL + [ALL_TAC; + DISCH_THEN SUBST1_TAC THEN AP_TERM_TAC THEN + MATCH_MP_TAC(GSYM WINDING_NUMBER_REVERSEPATH)]] THEN + ASM_SIMP_TAC[PATHSTART_REVERSEPATH; PATHFINISH_REVERSEPATH; + PATHSTART_COMPOSE; PATHFINISH_COMPOSE; PATH_IMAGE_REVERSEPATH; + PATHSTART_JOIN; PATHFINISH_JOIN; PATH_REVERSEPATH; + PATHSTART_LINEPATH; PATHFINISH_LINEPATH; PATH_JOIN; + PATH_IMAGE_JOIN; IN_UNION; DE_MORGAN_THM] THEN + REWRITE_TAC[PATH_IMAGE_COMPOSE; SET_RULE + `~(z IN IMAGE f s) <=> !x. x IN s ==> ~(f x = z)`] THEN + REPEAT CONJ_TAC THEN + ((MATCH_MP_TAC PATH_CONTINUOUS_IMAGE) + ORELSE + (X_GEN_TAC `x:complex` THEN DISCH_TAC THEN + FIRST_X_ASSUM MATCH_MP_TAC)) THEN + ASM_REWRITE_TAC[PATH_LINEPATH] THEN + TRY(FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET)) THEN + REWRITE_TAC[SUBSET] THEN X_GEN_TAC `x:complex` THEN STRIP_TAC) THEN + FIRST_X_ASSUM(MATCH_MP_TAC o GEN_REWRITE_RULE I [SUBSET]) THEN + TRY(FIRST_X_ASSUM(fun th -> + MATCH_MP_TAC(GEN_REWRITE_RULE I [SUBSET] th) THEN + FIRST_X_ASSUM ACCEPT_TAC)) THEN + UNDISCH_TAC `(x:complex) IN path_image(linepath(z,w))` THEN + SPEC_TAC(`x:complex`,`x:complex`) THEN + REWRITE_TAC[GSYM SUBSET; PATH_IMAGE_LINEPATH; SEGMENT_CONVEX_HULL] THEN + MATCH_MP_TAC SUBSET_TRANS THEN EXISTS_TAC `ball(z:complex,e)` THEN + ASM_REWRITE_TAC[SEGMENT_CONVEX_HULL] THEN MATCH_MP_TAC HULL_MINIMAL THEN + ASM_REWRITE_TAC[INSERT_SUBSET; CENTRE_IN_BALL; EMPTY_SUBSET] THEN + ASM_REWRITE_TAC[IN_BALL; CONVEX_BALL]]; + MATCH_MP_TAC LIM_TRANSFORM THEN + EXISTS_TAC `\w. Cx(&2) * Cx pi * ii * + Cx(&1) / (Cx(&2) * Cx pi * ii) * + (pathfinish(l o linepath(z:complex,w)) - + pathstart (l o linepath(z,w)))` THEN + REWRITE_TAC[] THEN CONJ_TAC THENL + [MATCH_MP_TAC LIM_EVENTUALLY THEN REWRITE_TAC[EVENTUALLY_AT] THEN + EXISTS_TAC `e:real` THEN ONCE_REWRITE_TAC[DIST_SYM] THEN + ASM_REWRITE_TAC[] THEN X_GEN_TAC `w:complex` THEN STRIP_TAC THEN + REWRITE_TAC[VECTOR_ARITH `x - y = vec 0 <=> y = x`] THEN + REPLICATE_TAC 3 AP_TERM_TAC THEN MATCH_MP_TAC lemma THEN + EXISTS_TAC `ball(z:complex,e)` THEN ASM_REWRITE_TAC[PATH_LINEPATH] THEN + CONJ_TAC THENL[ASM_MESON_TAC[CONTINUOUS_ON_SUBSET; SUBSET]; ALL_TAC] THEN + REWRITE_TAC[PATH_IMAGE_LINEPATH; SEGMENT_CONVEX_HULL] THEN + MATCH_MP_TAC HULL_MINIMAL THEN REWRITE_TAC[CONVEX_BALL] THEN + ASM_REWRITE_TAC[INSERT_SUBSET; CENTRE_IN_BALL; EMPTY_SUBSET] THEN + ASM_REWRITE_TAC[IN_BALL]; + REWRITE_TAC[COMPLEX_VEC_0] THEN + REPEAT(MATCH_MP_TAC LIM_NULL_COMPLEX_LMUL) THEN + REWRITE_TAC[PATHSTART_COMPOSE; PATHSTART_LINEPATH; + PATHFINISH_COMPOSE; PATHFINISH_LINEPATH] THEN + REWRITE_TAC[GSYM COMPLEX_VEC_0; GSYM LIM_NULL; GSYM CONTINUOUS_AT] THEN + ASM_MESON_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_AT; OPEN_BALL; + CENTRE_IN_BALL]]]);; + +(* ------------------------------------------------------------------------- *) +(* The winding number defines a continuous logarithm for the path itself. *) +(* ------------------------------------------------------------------------- *) + +let WINDING_NUMBER_AS_CONTINUOUS_LOGARITHM = prove + (`!p z. + path p /\ ~(z IN path_image p) + ==> ?q. path q /\ + pathfinish q - pathstart q = + Cx(&2) * Cx pi * ii * winding_number(p,z) /\ + !t. t IN interval[vec 0,vec 1] ==> p(t) = z + cexp(q t)`, + REPEAT STRIP_TAC THEN EXISTS_TAC + `\t:real^1. Cx(&2) * Cx pi * ii * winding_number(subpath (vec 0) t p,z) + + clog(pathstart p - z)` THEN + REPEAT CONJ_TAC THENL + [REWRITE_TAC[path] THEN MATCH_MP_TAC CONTINUOUS_ON_ADD THEN + REWRITE_TAC[CONTINUOUS_ON_CONST] THEN + REPEAT(MATCH_MP_TAC CONTINUOUS_ON_COMPLEX_MUL THEN + REWRITE_TAC[CONTINUOUS_ON_CONST]) THEN + REWRITE_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN] THEN + X_GEN_TAC `t:real^1` THEN DISCH_TAC THEN + SUBGOAL_THEN `~((p:real^1->complex) t = z)` ASSUME_TAC THENL + [ASM_MESON_TAC[path_image; IN_IMAGE]; ALL_TAC] THEN + MP_TAC(SPEC `ball((p:real^1->complex) t,norm(p t - z))` + SIMPLY_CONNECTED_EQ_CONTINUOUS_LOG) THEN + SIMP_TAC[OPEN_BALL; CONVEX_BALL; CONVEX_IMP_SIMPLY_CONNECTED] THEN + DISCH_THEN(MP_TAC o SPEC `\w:complex. w - z` o CONJUNCT2) THEN + SIMP_TAC[CONTINUOUS_ON_SUB; CONTINUOUS_ON_ID; CONTINUOUS_ON_CONST] THEN + REWRITE_TAC[COMPLEX_SUB_0] THEN ANTS_TAC THENL + [GEN_TAC THEN ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN + SIMP_TAC[IN_BALL; dist; REAL_LT_REFL]; + DISCH_THEN(X_CHOOSE_THEN `l:complex->complex` STRIP_ASSUME_TAC)] THEN + ONCE_REWRITE_TAC[WINDING_NUMBER_OFFSET] THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [path]) THEN + GEN_REWRITE_TAC LAND_CONV [continuous_on] THEN + DISCH_THEN(MP_TAC o SPEC `t:real^1`) THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(MP_TAC o SPEC `norm((p:real^1->complex) t - z)`) THEN + ASM_REWRITE_TAC[NORM_POS_LT; VECTOR_SUB_EQ] THEN + ONCE_REWRITE_TAC[DIST_SYM] THEN REWRITE_TAC[GSYM IN_BALL] THEN + DISCH_THEN(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC) THEN + REWRITE_TAC[CONTINUOUS_WITHIN] THEN ONCE_REWRITE_TAC[LIM_NULL] THEN + MATCH_MP_TAC LIM_TRANSFORM_WITHIN THEN EXISTS_TAC + `\u. Cx(&1) / (Cx(&2) * Cx pi * ii) * + (pathfinish((l:complex->complex) o subpath t u p) - + pathstart(l o subpath t u p))` THEN + EXISTS_TAC `d:real` THEN ASM_REWRITE_TAC[] THEN CONJ_TAC THENL + [X_GEN_TAC `u:real^1` THEN STRIP_TAC THEN + SUBGOAL_THEN + `path_image(subpath t u p) SUBSET ball(p t:complex,norm (p t - z))` + ASSUME_TAC THENL + [REWRITE_TAC[PATH_IMAGE_SUBPATH_GEN] THEN + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE] THEN + SUBGOAL_THEN + `segment[t,u] SUBSET interval[vec 0,vec 1] /\ + segment[t,u] SUBSET ball(t:real^1,d)` + MP_TAC THENL [ALL_TAC; ASM SET_TAC[]] THEN + CONJ_TAC THEN REWRITE_TAC[SEGMENT_CONVEX_HULL] THEN + MATCH_MP_TAC HULL_MINIMAL THEN + REWRITE_TAC[CONVEX_BALL; CONVEX_INTERVAL] THEN + ASM_REWRITE_TAC[INSERT_SUBSET; EMPTY_SUBSET; CENTRE_IN_BALL] THEN + ASM_REWRITE_TAC[ONCE_REWRITE_RULE[DIST_SYM] IN_BALL]; + ALL_TAC] THEN + W(MP_TAC o PART_MATCH (rand o rand) WINDING_NUMBER_COMPOSE_CEXP o + lhand o snd) THEN + ANTS_TAC THENL + [MATCH_MP_TAC PATH_CONTINUOUS_IMAGE THEN ASM_SIMP_TAC[PATH_SUBPATH] THEN + ASM_MESON_TAC[CONTINUOUS_ON_SUBSET]; + DISCH_THEN(SUBST1_TAC o SYM)] THEN + MATCH_MP_TAC EQ_TRANS THEN + EXISTS_TAC `winding_number((\w. subpath t u p w - z),Cx(&0))` THEN + CONJ_TAC THENL + [MATCH_MP_TAC WINDING_NUMBER_EQUAL THEN + REWRITE_TAC[o_THM; GSYM path_image; SET_RULE + `(!x. x IN s ==> cexp(l(subpath t u p x)) = subpath t u p x - z) <=> + (!y. y IN IMAGE (subpath t u p) s ==> cexp(l y) = y - z)`] THEN + ASM SET_TAC[]; + ONCE_REWRITE_TAC[GSYM WINDING_NUMBER_OFFSET] THEN + REWRITE_TAC[ETA_AX] THEN + MP_TAC(ISPECL [`p:real^1->complex`; `vec 0:real^1`; `t:real^1`; + `u:real^1`; `z:complex`] + WINDING_NUMBER_SUBPATH_COMBINE) THEN + ASM_REWRITE_TAC[ENDS_IN_UNIT_INTERVAL] THEN + CONV_TAC COMPLEX_RING]; + REWRITE_TAC[COMPLEX_VEC_0] THEN MATCH_MP_TAC LIM_NULL_COMPLEX_LMUL THEN + REWRITE_TAC[PATHSTART_COMPOSE; PATHSTART_SUBPATH; + PATHFINISH_COMPOSE; PATHFINISH_SUBPATH] THEN + REWRITE_TAC[GSYM COMPLEX_VEC_0; GSYM LIM_NULL] THEN + REWRITE_TAC[GSYM CONTINUOUS_WITHIN] THEN + GEN_REWRITE_TAC LAND_CONV [GSYM o_DEF] THEN + MATCH_MP_TAC CONTINUOUS_WITHIN_COMPOSE THEN CONJ_TAC THENL + [ASM_MESON_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN; path]; + MATCH_MP_TAC CONTINUOUS_AT_WITHIN THEN + UNDISCH_TAC `(l:complex->complex) continuous_on + ball(p(t:real^1),norm(p t - z))` THEN + SIMP_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_AT; OPEN_BALL] THEN + DISCH_THEN MATCH_MP_TAC THEN REWRITE_TAC[CENTRE_IN_BALL] THEN + ASM_REWRITE_TAC[VECTOR_SUB_EQ; NORM_POS_LT]]]; + REWRITE_TAC[pathstart; pathfinish; SUBPATH_REFL; SUBPATH_TRIVIAL] THEN + MATCH_MP_TAC(COMPLEX_FIELD + `w' = Cx(&0) + ==> (a * b * c * w + l) - (a * b * c * w' + l) = a * b * c * w`) THEN + MATCH_MP_TAC WINDING_NUMBER_TRIVIAL THEN + MP_TAC(ISPEC `p:real^1->complex` PATHSTART_IN_PATH_IMAGE) THEN + REWRITE_TAC[pathstart] THEN ASM_MESON_TAC[]; + X_GEN_TAC `t:real^1` THEN DISCH_TAC THEN + MP_TAC(ISPECL [`subpath (vec 0) t (p:real^1->complex)`; `z:complex`] + WINDING_NUMBER_AHLFORS_FULL) THEN + REWRITE_TAC[PATHSTART_SUBPATH; PATHFINISH_SUBPATH] THEN + ASM_SIMP_TAC[ENDS_IN_UNIT_INTERVAL; PATH_SUBPATH; CEXP_ADD; + REWRITE_RULE[SET_RULE `s SUBSET t <=> !x. ~(x IN t) ==> ~(x IN s)`] + PATH_IMAGE_SUBPATH_SUBSET] THEN + MATCH_MP_TAC(COMPLEX_RING + `t:complex = s ==> p - z = e * s ==> p = z + e * t`) THEN + REWRITE_TAC[pathstart] THEN MATCH_MP_TAC CEXP_CLOG THEN + REWRITE_TAC[COMPLEX_SUB_0] THEN + ASM_MESON_TAC[pathstart; PATHSTART_IN_PATH_IMAGE]]);; + +(* ------------------------------------------------------------------------- *) +(* Winding number equality is the same as path/loop homotopy in C - {0}. *) +(* ------------------------------------------------------------------------- *) + +let WINDING_NUMBER_HOMOTOPIC_LOOPS_NULL_EQ = prove + (`!p z. path p /\ ~(z IN path_image p) + ==> (winding_number(p,z) = Cx(&0) <=> + ?a. homotopic_loops ((:complex) DELETE z) p (\t. a))`, + REPEAT STRIP_TAC THEN EQ_TAC THEN STRIP_TAC THENL + [REPEAT STRIP_TAC THEN + MP_TAC(SPECL [`p:real^1->complex`; `z:complex`] + WINDING_NUMBER_AS_CONTINUOUS_LOGARITHM) THEN + ASM_REWRITE_TAC[COMPLEX_MUL_RZERO; COMPLEX_ADD_LID; COMPLEX_SUB_0] THEN + DISCH_THEN(X_CHOOSE_THEN `q:real^1->complex` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `z + Cx(&1)` THEN + MP_TAC(ISPECL [`\r:real^1->complex. pathfinish r = pathstart r`; + `q:real^1->complex`; `\t:real^1. Cx(&0)`; + `\w. z + cexp w`; + `interval[vec 0:real^1,vec 1]`; `(:complex)`; + `(:complex) DELETE z`] + HOMOTOPIC_WITH_COMPOSE_CONTINUOUS_LEFT) THEN + ASM_SIMP_TAC[CONTINUOUS_ON_CEXP; CONTINUOUS_ON_ADD; CONTINUOUS_ON_CONST; + CEXP_0; homotopic_loops; o_DEF] THEN + ANTS_TAC THENL + [REWRITE_TAC[CEXP_NZ; COMPLEX_EQ_ADD_LCANCEL_0; SET_RULE + `IMAGE f UNIV SUBSET UNIV DELETE z <=> !x. ~(f x = z)`] THEN + MATCH_MP_TAC HOMOTOPIC_WITH_MONO THEN + EXISTS_TAC `\r:real^1->complex. pathfinish r = pathstart r` THEN + CONJ_TAC THENL + [REWRITE_TAC[GSYM homotopic_loops] THEN + MATCH_MP_TAC HOMOTOPIC_LOOPS_LINEAR THEN + ASM_REWRITE_TAC[SUBSET_UNIV] THEN + REWRITE_TAC[path; pathstart; pathfinish; CONTINUOUS_ON_CONST]; + SIMP_TAC[pathstart; pathfinish]]; + MATCH_MP_TAC(ONCE_REWRITE_RULE[IMP_CONJ_ALT] HOMOTOPIC_WITH_EQ) THEN + ASM_SIMP_TAC[o_THM; pathstart; pathfinish; ENDS_IN_UNIT_INTERVAL]]; + FIRST_ASSUM(MP_TAC o MATCH_MP WINDING_NUMBER_HOMOTOPIC_LOOPS) THEN + ASM_REWRITE_TAC[GSYM LINEPATH_REFL] THEN + DISCH_THEN SUBST1_TAC THEN MATCH_MP_TAC WINDING_NUMBER_TRIVIAL THEN + FIRST_ASSUM(MP_TAC o MATCH_MP HOMOTOPIC_LOOPS_IMP_SUBSET) THEN + REWRITE_TAC[GSYM LINEPATH_REFL; PATH_IMAGE_LINEPATH; SEGMENT_REFL] THEN + SET_TAC[]]);; + +let WINDING_NUMBER_HOMOTOPIC_PATHS_NULL_EXPLICIT_EQ = prove + (`!p z. path p /\ ~(z IN path_image p) + ==> (winding_number(p,z) = Cx(&0) <=> + homotopic_paths ((:complex) DELETE z) + p (linepath(pathstart p,pathstart p)))`, + REPEAT STRIP_TAC THEN EQ_TAC THENL + [ASM_SIMP_TAC[WINDING_NUMBER_HOMOTOPIC_LOOPS_NULL_EQ] THEN + REWRITE_TAC[GSYM LINEPATH_REFL; HOMOTOPIC_LOOPS_IMP_HOMOTOPIC_PATHS_NULL; + LEFT_IMP_EXISTS_THM]; + STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o MATCH_MP WINDING_NUMBER_HOMOTOPIC_PATHS) THEN + ASM_REWRITE_TAC[GSYM LINEPATH_REFL] THEN + DISCH_THEN SUBST1_TAC THEN MATCH_MP_TAC WINDING_NUMBER_TRIVIAL THEN + ASM_MESON_TAC[PATHSTART_IN_PATH_IMAGE]]);; + +let WINDING_NUMBER_HOMOTOPIC_PATHS_NULL_EQ = prove + (`!p z. path p /\ ~(z IN path_image p) + ==> (winding_number(p,z) = Cx(&0) <=> + ?a. homotopic_paths ((:complex) DELETE z) p (\t. a))`, + REPEAT STRIP_TAC THEN EQ_TAC THENL + [ASM_SIMP_TAC[WINDING_NUMBER_HOMOTOPIC_PATHS_NULL_EXPLICIT_EQ] THEN + REWRITE_TAC[GSYM LINEPATH_REFL] THEN MESON_TAC[]; + STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o MATCH_MP WINDING_NUMBER_HOMOTOPIC_PATHS) THEN + ASM_REWRITE_TAC[GSYM LINEPATH_REFL] THEN + DISCH_THEN SUBST1_TAC THEN MATCH_MP_TAC WINDING_NUMBER_TRIVIAL THEN + FIRST_ASSUM(MP_TAC o MATCH_MP HOMOTOPIC_PATHS_IMP_SUBSET) THEN + REWRITE_TAC[GSYM LINEPATH_REFL; PATH_IMAGE_LINEPATH; SEGMENT_REFL] THEN + SET_TAC[]]);; + +let WINDING_NUMBER_HOMOTOPIC_PATHS_EQ = prove + (`!p q z. + path p /\ ~(z IN path_image p) /\ + path q /\ ~(z IN path_image q) /\ + pathstart q = pathstart p /\ pathfinish q = pathfinish p + ==> (winding_number(p,z) = winding_number(q,z) <=> + homotopic_paths ((:complex) DELETE z) p q)`, + REPEAT STRIP_TAC THEN EQ_TAC THEN + REWRITE_TAC[WINDING_NUMBER_HOMOTOPIC_PATHS] THEN DISCH_TAC THEN + MP_TAC(ISPECL [`p ++ reversepath q:real^1->complex`; `z:complex`] + WINDING_NUMBER_HOMOTOPIC_PATHS_NULL_EQ) THEN + ASM_SIMP_TAC[PATH_JOIN; PATH_REVERSEPATH; PATH_IMAGE_JOIN; IN_UNION; + PATHSTART_REVERSEPATH; PATHFINISH_REVERSEPATH; + PATH_IMAGE_REVERSEPATH; WINDING_NUMBER_JOIN; + WINDING_NUMBER_REVERSEPATH; COMPLEX_ADD_RINV] THEN + REWRITE_TAC[GSYM LINEPATH_REFL] THEN STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o MATCH_MP + (REWRITE_RULE[IMP_CONJ] HOMOTOPIC_PATHS_IMP_HOMOTOPIC_LOOPS)) THEN + FIRST_ASSUM(MP_TAC o MATCH_MP HOMOTOPIC_PATHS_IMP_PATHSTART) THEN + ASM_REWRITE_TAC[PATHSTART_JOIN; PATHFINISH_JOIN; + PATHSTART_REVERSEPATH; PATHFINISH_REVERSEPATH; + PATHSTART_LINEPATH; PATHFINISH_LINEPATH] THEN + DISCH_TAC THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(MP_TAC o MATCH_MP + (REWRITE_RULE[IMP_CONJ] HOMOTOPIC_PATHS_LOOP_PARTS)) THEN + ASM_REWRITE_TAC[]);; + +let WINDING_NUMBER_HOMOTOPIC_LOOPS_EQ = prove + (`!p q z. + path p /\ pathfinish p = pathstart p /\ ~(z IN path_image p) /\ + path q /\ pathfinish q = pathstart q /\ ~(z IN path_image q) + ==> (winding_number(p,z) = winding_number(q,z) <=> + homotopic_loops ((:complex) DELETE z) p q)`, + REPEAT STRIP_TAC THEN EQ_TAC THEN + REWRITE_TAC[WINDING_NUMBER_HOMOTOPIC_LOOPS] THEN DISCH_TAC THEN + SUBGOAL_THEN `~(pathstart p:complex = z) /\ ~(pathstart q = z)` + STRIP_ASSUME_TAC THENL + [ASM_MESON_TAC[PATHSTART_IN_PATH_IMAGE; PATHFINISH_IN_PATH_IMAGE]; + ALL_TAC] THEN + MP_TAC(ISPECL [`(:complex)`; `z:complex`] + PATH_CONNECTED_OPEN_DELETE) THEN + REWRITE_TAC[OPEN_UNIV; CONNECTED_UNIV; DIMINDEX_2; LE_REFL] THEN + REWRITE_TAC[path_connected] THEN DISCH_THEN(MP_TAC o SPECL + [`pathstart p:complex`; `pathstart q:complex`]) THEN + ASM_REWRITE_TAC[IN_UNIV; IN_DELETE; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `r:real^1->complex` THEN + REWRITE_TAC[SET_RULE `s SUBSET UNIV DELETE z <=> ~(z IN s)`] THEN + STRIP_TAC THEN SUBGOAL_THEN `~(pathstart r:complex = z)` + STRIP_ASSUME_TAC THENL + [ASM_MESON_TAC[PATHSTART_IN_PATH_IMAGE; PATHFINISH_IN_PATH_IMAGE]; + ALL_TAC] THEN + MATCH_MP_TAC HOMOTOPIC_LOOPS_TRANS THEN + EXISTS_TAC `r ++ q ++ reversepath r:real^1->complex` THEN + ASM_SIMP_TAC[HOMOTOPIC_LOOPS_CONJUGATE; SET_RULE + `s SUBSET UNIV DELETE z <=> ~(z IN s)`] THEN + MATCH_MP_TAC HOMOTOPIC_PATHS_IMP_HOMOTOPIC_LOOPS THEN + ASM_REWRITE_TAC[PATHFINISH_JOIN; PATHFINISH_REVERSEPATH] THEN + W(MP_TAC o PART_MATCH (rand o rand) WINDING_NUMBER_HOMOTOPIC_PATHS_EQ o + snd) THEN + ASM_SIMP_TAC[PATH_JOIN; PATH_REVERSEPATH; PATHSTART_JOIN; PATHFINISH_JOIN; + PATHSTART_REVERSEPATH; PATHFINISH_REVERSEPATH; + PATH_IMAGE_JOIN; IN_UNION; PATH_IMAGE_REVERSEPATH; + WINDING_NUMBER_JOIN; WINDING_NUMBER_REVERSEPATH] THEN + DISCH_THEN(SUBST1_TAC o SYM) THEN SIMPLE_COMPLEX_ARITH_TAC);; + +(* ------------------------------------------------------------------------- *) +(* A few simple corollaries from the various equivalences. *) +(* ------------------------------------------------------------------------- *) + +let SIMPLY_CONNECTED_INSIDE_SIMPLE_PATH = prove + (`!p:real^1->real^2. + simple_path p ==> simply_connected(inside(path_image p))`, + REPEAT STRIP_TAC THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP SIMPLE_PATH_IMP_PATH) THEN + ASM_SIMP_TAC[SIMPLY_CONNECTED_EQ_EMPTY_INSIDE; + OPEN_INSIDE; CLOSED_PATH_IMAGE; INSIDE_INSIDE_EQ_EMPTY; + CONNECTED_PATH_IMAGE] THEN + ASM_CASES_TAC `pathstart(p):real^2 = pathfinish p` THEN + ASM_SIMP_TAC[JORDAN_INSIDE_OUTSIDE; INSIDE_ARC_EMPTY; ARC_SIMPLE_PATH] THEN + REWRITE_TAC[CONNECTED_EMPTY]);; + +let SIMPLY_CONNECTED_INTER = prove + (`!s t:real^2->bool. + open s /\ open t /\ simply_connected s /\ simply_connected t /\ + connected (s INTER t) + ==> simply_connected (s INTER t)`, + REPEAT GEN_TAC THEN REWRITE_TAC[IMP_CONJ] THEN + SIMP_TAC[SIMPLY_CONNECTED_EQ_WINDING_NUMBER_ZERO; OPEN_INTER] THEN + REWRITE_TAC[SUBSET; IN_INTER] THEN MESON_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* Pick out the Riemann Mapping Theorem from the earlier chain. *) +(* ------------------------------------------------------------------------- *) + +let RIEMANN_MAPPING_THEOREM = prove + (`!s. open s /\ simply_connected s <=> + s = {} \/ + s = (:real^2) \/ + ?f g. f holomorphic_on s /\ + g holomorphic_on ball(Cx(&0),&1) /\ + (!z. z IN s ==> f z IN ball(Cx(&0),&1) /\ g(f z) = z) /\ + (!z. z IN ball(Cx(&0),&1) ==> g z IN s /\ f(g z) = z)`, + GEN_TAC THEN MATCH_MP_TAC(TAUT + `(a ==> (b <=> c)) /\ (c ==> a) ==> (a /\ b <=> c)`) THEN + REWRITE_TAC[SIMPLY_CONNECTED_EQ_BIHOLOMORPHIC_TO_DISC] THEN STRIP_TAC THEN + ASM_REWRITE_TAC[OPEN_EMPTY; OPEN_UNIV] THEN + SUBGOAL_THEN `s = IMAGE (g:complex->complex) (ball(Cx(&0),&1))` + SUBST1_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + MATCH_MP_TAC INVARIANCE_OF_DOMAIN THEN + ASM_SIMP_TAC[OPEN_BALL; HOLOMORPHIC_ON_IMP_CONTINUOUS_ON] THEN + ASM_MESON_TAC[]);; diff --git a/Multivariate/clifford.ml b/Multivariate/clifford.ml new file mode 100644 index 0000000..f8a6969 --- /dev/null +++ b/Multivariate/clifford.ml @@ -0,0 +1,979 @@ +(* ========================================================================= *) +(* Geometric algebra. *) +(* *) +(* (c) Copyright, John Harrison 1998-2008 *) +(* ========================================================================= *) + +needs "Multivariate/vectors.ml";; +needs "Library/binary.ml";; + +prioritize_real();; + +(* ------------------------------------------------------------------------- *) +(* Some basic lemmas, mostly set theory. *) +(* ------------------------------------------------------------------------- *) + +let CARD_UNION_LEMMA = prove + (`FINITE s /\ FINITE t /\ FINITE u /\ FINITE v /\ + s INTER t = {} /\ u INTER v = {} /\ s UNION t = u UNION v + ==> CARD(s) + CARD(t) = CARD(u) + CARD(v)`, + MESON_TAC[CARD_UNION]);; + +let CARD_DIFF_INTER = prove + (`!s t. FINITE s ==> CARD s = CARD(s DIFF t) + CARD(s INTER t)`, + REPEAT STRIP_TAC THEN CONV_TAC SYM_CONV THEN MATCH_MP_TAC CARD_UNION_EQ THEN + ASM_REWRITE_TAC[] THEN SET_TAC[]);; + +let CARD_ADD_SYMDIFF_INTER = prove + (`!s t:A->bool. + FINITE s /\ FINITE t + ==> CARD s + CARD t = + CARD((s DIFF t) UNION (t DIFF s)) + 2 * CARD(s INTER t)`, + REPEAT STRIP_TAC THEN + SUBST1_TAC(SPEC `t:A->bool`(MATCH_MP CARD_DIFF_INTER + (ASSUME `FINITE(s:A->bool)`))) THEN + SUBST1_TAC(SPEC `s:A->bool`(MATCH_MP CARD_DIFF_INTER + (ASSUME `FINITE(t:A->bool)`))) THEN + REWRITE_TAC[INTER_ACI] THEN + MATCH_MP_TAC(ARITH_RULE `c = a + b ==> (a + x) + (b + x) = c + 2 * x`) THEN + MATCH_MP_TAC CARD_UNION THEN ASM_SIMP_TAC[FINITE_DIFF] THEN SET_TAC[]);; + +let SYMDIFF_PARITY_LEMMA = prove + (`!s t u. FINITE s /\ FINITE t /\ (s DIFF t) UNION (t DIFF s) = u + ==> EVEN(CARD u) = (EVEN(CARD s) <=> EVEN(CARD t))`, + ONCE_REWRITE_TAC[GSYM EVEN_ADD] THEN + SIMP_TAC[CARD_ADD_SYMDIFF_INTER] THEN + REWRITE_TAC[EVEN_ADD; EVEN_MULT; ARITH]);; + +let FINITE_CART_SUBSET_LEMMA = prove + (`!P m n. FINITE {i,j | i IN 1..m /\ j IN 1..n /\ P i j}`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC FINITE_SUBSET THEN + EXISTS_TAC `{i,j | i IN 1..m /\ j IN 1..n}` THEN + SIMP_TAC[SUBSET; FINITE_PRODUCT; FINITE_NUMSEG] THEN + SIMP_TAC[FORALL_PAIR_THM; IN_ELIM_PAIR_THM]);; + +(* ------------------------------------------------------------------------- *) +(* Index type for "multivectors" (k-vectors for all k <= N). *) +(* ------------------------------------------------------------------------- *) + +let multivector_tybij_th = prove + (`?s. s SUBSET (1..dimindex(:N))`, + MESON_TAC[EMPTY_SUBSET]);; + +let multivector_tybij = + new_type_definition "multivector" ("mk_multivector","dest_multivector") + multivector_tybij_th;; + +let MULTIVECTOR_IMAGE = prove + (`(:(N)multivector) = IMAGE mk_multivector {s | s SUBSET 1..dimindex(:N)}`, + REWRITE_TAC[EXTENSION; IN_UNIV; IN_IMAGE; IN_ELIM_THM] THEN + MESON_TAC[multivector_tybij]);; + +let HAS_SIZE_MULTIVECTOR = prove + (`(:(N)multivector) HAS_SIZE (2 EXP dimindex(:N))`, + REWRITE_TAC[MULTIVECTOR_IMAGE] THEN MATCH_MP_TAC HAS_SIZE_IMAGE_INJ THEN + SIMP_TAC[HAS_SIZE_POWERSET; HAS_SIZE_NUMSEG_1; IN_ELIM_THM] THEN + MESON_TAC[multivector_tybij]);; + +let FINITE_MULTIVECTOR = prove + (`FINITE(:(N)multivector)`, + MESON_TAC[HAS_SIZE; HAS_SIZE_MULTIVECTOR]);; + +let DIMINDEX_MULTIVECTOR = prove + (`dimindex(:(N)multivector) = 2 EXP dimindex(:N)`, + MESON_TAC[DIMINDEX_UNIQUE; HAS_SIZE_MULTIVECTOR]);; + +let DEST_MK_MULTIVECTOR = prove + (`!s. s SUBSET 1..dimindex(:N) + ==> dest_multivector(mk_multivector s :(N)multivector) = s`, + REPEAT STRIP_TAC THEN GEN_REWRITE_TAC I [GSYM multivector_tybij] THEN + ASM_REWRITE_TAC[]);; + +let FORALL_MULTIVECTOR = prove + (`(!s. s SUBSET 1..dimindex(:N) ==> P(mk_multivector s)) <=> + (!m:(N)multivector. P m)`, + EQ_TAC THENL [ALL_TAC; SIMP_TAC[]] THEN DISCH_TAC THEN GEN_TAC THEN + MP_TAC(ISPEC `m:(N)multivector` + (REWRITE_RULE[EXTENSION] MULTIVECTOR_IMAGE)) THEN + REWRITE_TAC[IN_UNIV; IN_IMAGE; EXISTS_PAIR_THM; IN_ELIM_THM] THEN + ASM_MESON_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* The bijections we use for indexing. *) +(* *) +(* Note that we need a *single* bijection over the entire space that also *) +(* works for the various subsets. Hence the tedious explicit construction. *) +(* ------------------------------------------------------------------------- *) + +let setcode = new_definition + `setcode s = 1 + binarysum (IMAGE PRE s)`;; + +let codeset = new_definition + `codeset n = IMAGE SUC (bitset(n - 1))`;; + +let CODESET_SETCODE_BIJECTIONS = prove + (`(!i. i IN 1..(2 EXP n) + ==> codeset i SUBSET 1..n /\ setcode(codeset i) = i) /\ + (!s. s SUBSET (1..n) + ==> (setcode s) IN 1..(2 EXP n) /\ codeset(setcode s) = s)`, + REWRITE_TAC[codeset; setcode; ADD_SUB2; GSYM IMAGE_o; o_DEF; PRE] THEN + REWRITE_TAC[SET_RULE `IMAGE (\x. x) s = s`] THEN CONJ_TAC THEN GEN_TAC THENL + [REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; IN_NUMSEG] THEN + SIMP_TAC[ARITH_RULE `1 <= i ==> (1 + b = i <=> b = i - 1)`] THEN + REWRITE_TAC[ARITH_RULE `1 <= SUC n /\ SUC n <= k <=> n < k`] THEN + DISCH_THEN(MP_TAC o MATCH_MP + (ARITH_RULE `1 <= i /\ i <= t ==> i - 1 < t`)) THEN + MESON_TAC[BITSET_BOUND; BINARYSUM_BITSET]; + ALL_TAC] THEN + DISCH_TAC THEN + FIRST_ASSUM(MP_TAC o ISPEC `PRE` o MATCH_MP IMAGE_SUBSET) THEN + REWRITE_TAC[IN_NUMSEG; SUBSET] THEN DISCH_TAC THEN CONJ_TAC THENL + [MATCH_MP_TAC(ARITH_RULE `x < n ==> 1 <= 1 + x /\ 1 + x <= n`) THEN + MATCH_MP_TAC BINARYSUM_BOUND THEN X_GEN_TAC `i:num` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `i:num`) THEN + ASM_REWRITE_TAC[IN_IMAGE; IN_NUMSEG] THEN ARITH_TAC; + ALL_TAC] THEN + MATCH_MP_TAC EQ_TRANS THEN EXISTS_TAC `IMAGE SUC (IMAGE PRE s)` THEN + CONJ_TAC THENL + [ASM_MESON_TAC[FINITE_IMAGE; FINITE_SUBSET; FINITE_NUMSEG; BITSET_BINARYSUM]; + ALL_TAC] THEN + UNDISCH_TAC `s SUBSET 1..n` THEN + REWRITE_TAC[SUBSET; EXTENSION; IN_IMAGE; IN_NUMSEG] THEN + MESON_TAC[ARITH_RULE `1 <= n ==> SUC(PRE n) = n`]);; + +let FORALL_SETCODE = prove + (`(!s. s SUBSET (1..n) ==> P(setcode s)) <=> (!i. i IN 1..(2 EXP n) ==> P i)`, + MESON_TAC[CODESET_SETCODE_BIJECTIONS; SUBSET]);; + +let SETCODE_BOUNDS = prove + (`!s n. s SUBSET 1..n ==> setcode s IN (1..(2 EXP n))`, + MESON_TAC[CODESET_SETCODE_BIJECTIONS]);; + +(* ------------------------------------------------------------------------- *) +(* Indexing directly via subsets. *) +(* ------------------------------------------------------------------------- *) + +parse_as_infix("$$",(25,"left"));; + +let sindex = new_definition + `(x:real^(N)multivector)$$s = x$(setcode s)`;; + +parse_as_binder "lambdas";; + +let lambdas = new_definition + `(lambdas) (g:(num->bool)->real) = + (lambda i. g(codeset i)):real^(N)multivector`;; + +(* ------------------------------------------------------------------------- *) +(* Crucial properties. *) +(* ------------------------------------------------------------------------- *) + +let MULTIVECTOR_EQ = prove + (`!x y:real^(N)multivector. + x = y <=> !s. s SUBSET 1..dimindex(:N) ==> x$$s = y$$s`, + SIMP_TAC[CART_EQ; sindex; FORALL_SETCODE; GSYM IN_NUMSEG; + DIMINDEX_MULTIVECTOR]);; + +let MULTIVECTOR_BETA = prove + (`!s. s SUBSET 1..dimindex(:N) + ==> ((lambdas) g :real^(N)multivector)$$s = g s`, + SIMP_TAC[sindex; lambdas; LAMBDA_BETA; SETCODE_BOUNDS; + DIMINDEX_MULTIVECTOR; GSYM IN_NUMSEG] THEN + MESON_TAC[CODESET_SETCODE_BIJECTIONS]);; + +let MULTIVECTOR_UNIQUE = prove + (`!m:real^(N)multivector g. + (!s. s SUBSET 1..dimindex(:N) ==> m$$s = g s) + ==> (lambdas) g = m`, + SIMP_TAC[MULTIVECTOR_EQ; MULTIVECTOR_BETA] THEN MESON_TAC[]);; + +let MULTIVECTOR_ETA = prove + (`(lambdas s. m$$s) = m`, + SIMP_TAC[MULTIVECTOR_EQ; MULTIVECTOR_BETA]);; + +(* ------------------------------------------------------------------------- *) +(* Also componentwise operations; they all work in this style. *) +(* ------------------------------------------------------------------------- *) + +let MULTIVECTOR_ADD_COMPONENT = prove + (`!x y:real^(N)multivector s. + s SUBSET (1..dimindex(:N)) ==> (x + y)$$s = x$$s + y$$s`, + SIMP_TAC[sindex; SETCODE_BOUNDS; DIMINDEX_MULTIVECTOR; + GSYM IN_NUMSEG; VECTOR_ADD_COMPONENT]);; + +let MULTIVECTOR_MUL_COMPONENT = prove + (`!c x:real^(N)multivector s. + s SUBSET (1..dimindex(:N)) ==> (c % x)$$s = c * x$$s`, + SIMP_TAC[sindex; SETCODE_BOUNDS; DIMINDEX_MULTIVECTOR; + GSYM IN_NUMSEG; VECTOR_MUL_COMPONENT]);; + +let MULTIVECTOR_VEC_COMPONENT = prove + (`!k s. s SUBSET (1..dimindex(:N)) ==> (vec k :real^(N)multivector)$$s = &k`, + SIMP_TAC[sindex; SETCODE_BOUNDS; DIMINDEX_MULTIVECTOR; + GSYM IN_NUMSEG; VEC_COMPONENT]);; + +let MULTIVECTOR_VSUM_COMPONENT = prove + (`!f:A->real^(N)multivector t s. + s SUBSET (1..dimindex(:N)) + ==> (vsum t f)$$s = sum t (\x. (f x)$$s)`, + SIMP_TAC[vsum; sindex; LAMBDA_BETA; SETCODE_BOUNDS; GSYM IN_NUMSEG; + DIMINDEX_MULTIVECTOR]);; + +let MULTIVECTOR_VSUM = prove + (`!t f. vsum t f = lambdas s. sum t (\x. (f x)$$s)`, + SIMP_TAC[MULTIVECTOR_EQ; MULTIVECTOR_BETA; MULTIVECTOR_VSUM_COMPONENT]);; + +(* ------------------------------------------------------------------------- *) +(* Basis vectors indexed by subsets of 1..N. *) +(* ------------------------------------------------------------------------- *) + +let mbasis = new_definition + `mbasis i = lambdas s. if i = s then &1 else &0`;; + +let MBASIS_COMPONENT = prove + (`!s t. s SUBSET (1..dimindex(:N)) + ==> (mbasis t :real^(N)multivector)$$s = if s = t then &1 else &0`, + SIMP_TAC[mbasis; IN_ELIM_THM; MULTIVECTOR_BETA] THEN MESON_TAC[]);; + +let MBASIS_EQ_0 = prove + (`!s. (mbasis s :real^(N)multivector = vec 0) <=> + ~(s SUBSET 1..dimindex(:N))`, + SIMP_TAC[MULTIVECTOR_EQ; MBASIS_COMPONENT; MULTIVECTOR_VEC_COMPONENT] THEN + MESON_TAC[REAL_ARITH `~(&1 = &0)`]);; + +let MBASIS_NONZERO = prove + (`!s. s SUBSET 1..dimindex(:N) ==> ~(mbasis s :real^(N)multivector = vec 0)`, + REWRITE_TAC[MBASIS_EQ_0]);; + +let MBASIS_EXPANSION = prove + (`!x:real^(N)multivector. + vsum {s | s SUBSET 1..dimindex(:N)} (\s. x$$s % mbasis s) = x`, + SIMP_TAC[MULTIVECTOR_EQ; MULTIVECTOR_VSUM_COMPONENT; + MULTIVECTOR_MUL_COMPONENT; MBASIS_COMPONENT] THEN + REPEAT STRIP_TAC THEN + GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [EQ_SYM_EQ] THEN + ASM_SIMP_TAC[REAL_ARITH `x * (if p then &1 else &0) = if p then x else &0`; + SUM_DELTA; IN_ELIM_THM]);; + +let SPAN_MBASIS = prove + (`span {mbasis s :real^(N)multivector | s SUBSET 1..dimindex(:N)} = UNIV`, + REWRITE_TAC[EXTENSION; IN_UNIV] THEN X_GEN_TAC `x:real^(N)multivector` THEN + GEN_REWRITE_TAC LAND_CONV [GSYM MBASIS_EXPANSION] THEN + MATCH_MP_TAC SPAN_VSUM THEN + SIMP_TAC[FINITE_NUMSEG; FINITE_POWERSET; IN_ELIM_THM] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC SPAN_MUL THEN + MATCH_MP_TAC SPAN_SUPERSET THEN REWRITE_TAC[IN_ELIM_THM] THEN + ASM_MESON_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* Linear and bilinear functions are determined by their effect on basis. *) +(* ------------------------------------------------------------------------- *) + +let LINEAR_EQ_MBASIS = prove + (`!f:real^(M)multivector->real^N g b s. + linear f /\ linear g /\ + (!s. s SUBSET 1..dimindex(:M) ==> f(mbasis s) = g(mbasis s)) + ==> f = g`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN `!x. x IN UNIV ==> (f:real^(M)multivector->real^N) x = g x` + (fun th -> MP_TAC th THEN REWRITE_TAC[FUN_EQ_THM; IN_UNIV]) THEN + MATCH_MP_TAC LINEAR_EQ THEN + EXISTS_TAC `{mbasis s :real^(M)multivector | s SUBSET 1..dimindex(:M)}` THEN + ASM_REWRITE_TAC[SPAN_MBASIS; SUBSET_REFL; IN_ELIM_THM] THEN + ASM_MESON_TAC[]);; + +let BILINEAR_EQ_MBASIS = prove + (`!f:real^(M)multivector->real^(N)multivector->real^P g b s. + bilinear f /\ bilinear g /\ + (!s t. s SUBSET 1..dimindex(:M) /\ t SUBSET 1..dimindex(:N) + ==> f (mbasis s) (mbasis t) = g (mbasis s) (mbasis t)) + ==> f = g`, + REPEAT STRIP_TAC THEN SUBGOAL_THEN + `!x y. x IN UNIV /\ y IN UNIV + ==> (f:real^(M)multivector->real^(N)multivector->real^P) x y = g x y` + (fun th -> MP_TAC th THEN REWRITE_TAC[FUN_EQ_THM; IN_UNIV]) THEN + MATCH_MP_TAC BILINEAR_EQ THEN + EXISTS_TAC `{mbasis s :real^(M)multivector | s SUBSET 1..dimindex(:M)}` THEN + EXISTS_TAC `{mbasis t :real^(N)multivector | t SUBSET 1..dimindex(:N)}` THEN + ASM_REWRITE_TAC[SPAN_MBASIS; SUBSET_REFL; IN_ELIM_THM] THEN + ASM_MESON_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* A way of proving linear properties by extension from basis. *) +(* ------------------------------------------------------------------------- *) + +let LINEAR_PROPERTY = prove + (`!P. P(vec 0) /\ (!x y. P x /\ P y ==> P(x + y)) + ==> !f s. FINITE s /\ (!i. i IN s ==> P(f i)) ==> P(vsum s f)`, + GEN_TAC THEN STRIP_TAC THEN GEN_TAC THEN ONCE_REWRITE_TAC[IMP_CONJ] THEN + MATCH_MP_TAC FINITE_INDUCT_STRONG THEN + ASM_SIMP_TAC[VSUM_CLAUSES; IN_INSERT]);; + +let MBASIS_EXTENSION = prove + (`!P. (!s. s SUBSET 1..dimindex(:N) ==> P(mbasis s)) /\ + (!c x. P x ==> P(c % x)) /\ (!x y. P x /\ P y ==> P(x + y)) + ==> !x:real^(N)multivector. P x`, + REPEAT STRIP_TAC THEN GEN_REWRITE_TAC RAND_CONV [GSYM MBASIS_EXPANSION] THEN + MATCH_MP_TAC(SIMP_RULE[RIGHT_IMP_FORALL_THM; IMP_IMP] LINEAR_PROPERTY) THEN + ASM_SIMP_TAC[FINITE_POWERSET; FINITE_NUMSEG; IN_ELIM_THM] THEN + ASM_MESON_TAC[EMPTY_SUBSET; VECTOR_MUL_LZERO]);; + +(* ------------------------------------------------------------------------- *) +(* Injection from regular vectors. *) +(* ------------------------------------------------------------------------- *) + +let multivec = new_definition + `(multivec:real^N->real^(N)multivector) x = + vsum(1..dimindex(:N)) (\i. x$i % mbasis{i})`;; + +(* ------------------------------------------------------------------------- *) +(* Subspace of k-vectors. *) +(* ------------------------------------------------------------------------- *) + +parse_as_infix("multivector",(12,"right"));; + +let multivector = new_definition + `k multivector (p:real^(N)multivector) <=> + !s. s SUBSET (1..dimindex(:N)) /\ ~(p$$s = &0) ==> s HAS_SIZE k`;; + +(* ------------------------------------------------------------------------- *) +(* k-grade part of a multivector. *) +(* ------------------------------------------------------------------------- *) + +parse_as_infix("grade",(22,"right"));; + +let grade = new_definition + `k grade (p:real^(N)multivector) = + (lambdas s. if s HAS_SIZE k then p$$s else &0):real^(N)multivector`;; + +let MULTIVECTOR_GRADE = prove + (`!k x. k multivector (k grade x)`, + SIMP_TAC[multivector; grade; MULTIVECTOR_BETA; IMP_CONJ] THEN + MESON_TAC[]);; + +let GRADE_ADD = prove + (`!x y k. k grade (x + y) = (k grade x) + (k grade y)`, + SIMP_TAC[grade; MULTIVECTOR_EQ; MULTIVECTOR_ADD_COMPONENT; + MULTIVECTOR_BETA; COND_COMPONENT] THEN + REAL_ARITH_TAC);; + +let GRADE_CMUL = prove + (`!c x k. k grade (c % x) = c % (k grade x)`, + SIMP_TAC[grade; MULTIVECTOR_EQ; MULTIVECTOR_MUL_COMPONENT; + MULTIVECTOR_BETA; COND_COMPONENT] THEN + REAL_ARITH_TAC);; + +(* ------------------------------------------------------------------------- *) +(* General product construct. *) +(* ------------------------------------------------------------------------- *) + +let Product_DEF = new_definition + `(Product mult op + :real^(N)multivector->real^(N)multivector->real^(N)multivector) x y = + vsum {s | s SUBSET 1..dimindex(:N)} + (\s. vsum {s | s SUBSET 1..dimindex(:N)} + (\t. (x$$s * y$$t * mult s t) % mbasis (op s t)))`;; + +(* ------------------------------------------------------------------------- *) +(* This is always bilinear. *) +(* ------------------------------------------------------------------------- *) + +let BILINEAR_PRODUCT = prove + (`!mult op. bilinear(Product mult op)`, + REWRITE_TAC[bilinear; linear; Product_DEF] THEN + SIMP_TAC[GSYM VSUM_LMUL; MULTIVECTOR_MUL_COMPONENT] THEN + REWRITE_TAC[VECTOR_MUL_ASSOC; REAL_MUL_AC] THEN + REPEAT STRIP_TAC THEN REWRITE_TAC[Product_DEF] THEN + SIMP_TAC[GSYM VSUM_ADD; FINITE_POWERSET; FINITE_NUMSEG] THEN + REPEAT(MATCH_MP_TAC VSUM_EQ THEN REWRITE_TAC[IN_ELIM_THM] THEN + REPEAT STRIP_TAC) THEN + ASM_SIMP_TAC[MULTIVECTOR_ADD_COMPONENT] THEN VECTOR_ARITH_TAC);; + +let PRODUCT_LADD = (MATCH_MP BILINEAR_LADD o SPEC_ALL) BILINEAR_PRODUCT;; +let PRODUCT_RADD = (MATCH_MP BILINEAR_RADD o SPEC_ALL) BILINEAR_PRODUCT;; +let PRODUCT_LMUL = (MATCH_MP BILINEAR_LMUL o SPEC_ALL) BILINEAR_PRODUCT;; +let PRODUCT_RMUL = (MATCH_MP BILINEAR_RMUL o SPEC_ALL) BILINEAR_PRODUCT;; +let PRODUCT_LNEG = (MATCH_MP BILINEAR_LNEG o SPEC_ALL) BILINEAR_PRODUCT;; +let PRODUCT_RNEG = (MATCH_MP BILINEAR_RNEG o SPEC_ALL) BILINEAR_PRODUCT;; +let PRODUCT_LZERO = (MATCH_MP BILINEAR_LZERO o SPEC_ALL) BILINEAR_PRODUCT;; +let PRODUCT_RZERO = (MATCH_MP BILINEAR_RZERO o SPEC_ALL) BILINEAR_PRODUCT;; + +(* ------------------------------------------------------------------------- *) +(* Under suitable conditions, it's also associative. *) +(* ------------------------------------------------------------------------- *) + +let PRODUCT_ASSOCIATIVE = prove + (`!op mult. (!s t. s SUBSET 1..dimindex(:N) /\ t SUBSET 1..dimindex(:N) + ==> (op s t) SUBSET 1..dimindex(:N)) /\ + (!s t u. op s (op t u) = op (op s t) u) /\ + (!s t u. mult t u * mult s (op t u) = mult s t * mult (op s t) u) + ==> !x y z:real^(N)multivector. + Product mult op x (Product mult op y z) = + Product mult op (Product mult op x y) z`, + let SUM_SWAP_POWERSET = + SIMP_RULE[FINITE_POWERSET; FINITE_NUMSEG] + (repeat(SPEC `{s | s SUBSET 1..dimindex(:N)}`) + (ISPEC `f:(num->bool)->(num->bool)->real` SUM_SWAP)) in + let SWAP_TAC cnv n = + GEN_REWRITE_TAC (cnv o funpow n BINDER_CONV) [SUM_SWAP_POWERSET] THEN + REWRITE_TAC[] in + let SWAPS_TAC cnv ns x = + MAP_EVERY (SWAP_TAC cnv) ns THEN MATCH_MP_TAC SUM_EQ THEN X_GEN_TAC x THEN + REWRITE_TAC[IN_ELIM_THM] THEN STRIP_TAC in + REWRITE_TAC[Product_DEF] THEN REPEAT STRIP_TAC THEN + SIMP_TAC[MULTIVECTOR_EQ; MULTIVECTOR_VSUM_COMPONENT; MBASIS_COMPONENT; + MULTIVECTOR_MUL_COMPONENT] THEN + SIMP_TAC[GSYM SUM_LMUL; GSYM SUM_RMUL] THEN + X_GEN_TAC `r:num->bool` THEN STRIP_TAC THEN + SWAPS_TAC RAND_CONV [1;0] `s:num->bool` THEN + SWAP_TAC LAND_CONV 0 THEN SWAPS_TAC RAND_CONV [1;0] `t:num->bool` THEN + SWAP_TAC RAND_CONV 0 THEN SWAPS_TAC LAND_CONV [0] `u:num->bool` THEN + REWRITE_TAC[GSYM REAL_MUL_ASSOC; + REAL_ARITH `(if p then a else &0) * b = if p then a * b else &0`; + REAL_ARITH `a * (if p then b else &0) = if p then a * b else &0`] THEN + SIMP_TAC[SUM_DELTA] THEN ASM_SIMP_TAC[IN_ELIM_THM] THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[REAL_MUL_LID; REAL_MUL_RID] THEN + ASM_REWRITE_TAC[] THEN REWRITE_TAC[REAL_MUL_AC]);; + +(* ------------------------------------------------------------------------- *) +(* Geometric product. *) +(* ------------------------------------------------------------------------- *) + +overload_interface + ("*", + `geom_mul:real^(N)multivector->real^(N)multivector->real^(N)multivector`);; + +let geom_mul = new_definition + `(x:real^(N)multivector) * y = + Product (\s t. --(&1) pow CARD {i,j | i IN 1..dimindex(:N) /\ + j IN 1..dimindex(:N) /\ + i IN s /\ j IN t /\ i > j}) + (\s t. (s DIFF t) UNION (t DIFF s)) + x y`;; + +let BILINEAR_GEOM = prove + (`bilinear(geom_mul)`, + REWRITE_TAC[REWRITE_RULE[GSYM FUN_EQ_THM; ETA_AX] geom_mul] THEN + MATCH_ACCEPT_TAC BILINEAR_PRODUCT);; + +let GEOM_LADD = (MATCH_MP BILINEAR_LADD o SPEC_ALL) BILINEAR_GEOM;; +let GEOM_RADD = (MATCH_MP BILINEAR_RADD o SPEC_ALL) BILINEAR_GEOM;; +let GEOM_LMUL = (MATCH_MP BILINEAR_LMUL o SPEC_ALL) BILINEAR_GEOM;; +let GEOM_RMUL = (MATCH_MP BILINEAR_RMUL o SPEC_ALL) BILINEAR_GEOM;; +let GEOM_LNEG = (MATCH_MP BILINEAR_LNEG o SPEC_ALL) BILINEAR_GEOM;; +let GEOM_RNEG = (MATCH_MP BILINEAR_RNEG o SPEC_ALL) BILINEAR_GEOM;; +let GEOM_LZERO = (MATCH_MP BILINEAR_LZERO o SPEC_ALL) BILINEAR_GEOM;; +let GEOM_RZERO = (MATCH_MP BILINEAR_RZERO o SPEC_ALL) BILINEAR_GEOM;; + +let GEOM_ASSOC = prove + (`!x y z:real^(N)multivector. x * (y * z) = (x * y) * z`, + REWRITE_TAC[geom_mul] THEN MATCH_MP_TAC PRODUCT_ASSOCIATIVE THEN + REPEAT(CONJ_TAC THENL [SET_TAC[]; ALL_TAC]) THEN + REPEAT GEN_TAC THEN REWRITE_TAC[GSYM REAL_POW_ADD] THEN + REWRITE_TAC[REAL_POW_NEG; REAL_POW_ONE] THEN + AP_THM_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN + REWRITE_TAC[EVEN_ADD] THEN + W(fun (_,w) -> let tu = funpow 2 lhand w in + let su = vsubst[`s:num->bool`,`t:num->bool`] tu in + let st = vsubst[`t:num->bool`,`u:num->bool`] su in + MATCH_MP_TAC EQ_TRANS THEN + EXISTS_TAC(end_itlist (curry mk_eq) [st; su; tu])) THEN + CONJ_TAC THENL + [MATCH_MP_TAC(TAUT `(x <=> y <=> z) ==> ((a <=> x) <=> (y <=> z <=> a))`); + AP_TERM_TAC THEN CONV_TAC SYM_CONV] THEN + MATCH_MP_TAC SYMDIFF_PARITY_LEMMA THEN + REWRITE_TAC[FINITE_CART_SUBSET_LEMMA] THEN + REWRITE_TAC[EXTENSION; FORALL_PAIR_THM; IN_ELIM_PAIR_THM; + IN_UNION; IN_DIFF] THEN + CONV_TAC TAUT);; + +(* ------------------------------------------------------------------------- *) +(* Outer product. *) +(* ------------------------------------------------------------------------- *) + +parse_as_infix("outer",(20,"right"));; + +let outer = new_definition + `!x y:real^(N)multivector. + x outer y = + Product (\s t. if ~(s INTER t = {}) then &0 + else --(&1) pow CARD {i,j | i IN 1..dimindex(:N) /\ + j IN 1..dimindex(:N) /\ + i IN s /\ j IN t /\ i > j}) + (\s t. (s DIFF t) UNION (t DIFF s)) + x y`;; + +let OUTER = prove + (`!x y:real^(N)multivector. + x outer y = + Product (\s t. if ~(s INTER t = {}) then &0 + else --(&1) pow CARD {i,j | i IN 1..dimindex(:N) /\ + j IN 1..dimindex(:N) /\ + i IN s /\ j IN t /\ i > j}) + (UNION) + x y`, + REPEAT GEN_TAC THEN REWRITE_TAC[outer; Product_DEF] THEN + REPEAT(AP_TERM_TAC THEN ABS_TAC) THEN + ASM_CASES_TAC `s INTER t :num->bool = {}` THEN + ASM_REWRITE_TAC[REAL_MUL_RZERO; VECTOR_MUL_LZERO] THEN + ASM_SIMP_TAC[SET_RULE + `(s INTER t = {}) ==> (s DIFF t) UNION (t DIFF s) = s UNION t`]);; + +let BILINEAR_OUTER = prove + (`bilinear(outer)`, + REWRITE_TAC[REWRITE_RULE[GSYM FUN_EQ_THM; ETA_AX] outer] THEN + MATCH_ACCEPT_TAC BILINEAR_PRODUCT);; + +let OUTER_LADD = (MATCH_MP BILINEAR_LADD o SPEC_ALL) BILINEAR_OUTER;; +let OUTER_RADD = (MATCH_MP BILINEAR_RADD o SPEC_ALL) BILINEAR_OUTER;; +let OUTER_LMUL = (MATCH_MP BILINEAR_LMUL o SPEC_ALL) BILINEAR_OUTER;; +let OUTER_RMUL = (MATCH_MP BILINEAR_RMUL o SPEC_ALL) BILINEAR_OUTER;; +let OUTER_LNEG = (MATCH_MP BILINEAR_LNEG o SPEC_ALL) BILINEAR_OUTER;; +let OUTER_RNEG = (MATCH_MP BILINEAR_RNEG o SPEC_ALL) BILINEAR_OUTER;; +let OUTER_LZERO = (MATCH_MP BILINEAR_LZERO o SPEC_ALL) BILINEAR_OUTER;; +let OUTER_RZERO = (MATCH_MP BILINEAR_RZERO o SPEC_ALL) BILINEAR_OUTER;; + +let OUTER_ASSOC = prove + (`!x y z:real^(N)multivector. x outer (y outer z) = (x outer y) outer z`, + REWRITE_TAC[OUTER] THEN MATCH_MP_TAC PRODUCT_ASSOCIATIVE THEN + SIMP_TAC[UNION_SUBSET; UNION_ASSOC; + SET_RULE `s INTER (t UNION u) = (s INTER t) UNION (s INTER u)`; + SET_RULE `(t UNION u) INTER s = (t INTER s) UNION (u INTER s)`] THEN + REWRITE_TAC[EMPTY_UNION] THEN REPEAT GEN_TAC THEN + MAP_EVERY ASM_CASES_TAC + [`s INTER t :num->bool = {}`; + `s INTER u :num->bool = {}`; + `t INTER u :num->bool = {}`] THEN + ASM_REWRITE_TAC[REAL_MUL_LZERO; REAL_MUL_RZERO] THEN + REWRITE_TAC[GSYM REAL_POW_ADD] THEN AP_TERM_TAC THEN + MATCH_MP_TAC CARD_UNION_LEMMA THEN REWRITE_TAC[FINITE_CART_SUBSET_LEMMA] THEN + SIMP_TAC[EXTENSION; FORALL_PAIR_THM; NOT_IN_EMPTY; IN_UNION; IN_INTER] THEN + REWRITE_TAC[IN_ELIM_PAIR_THM] THEN ASM SET_TAC []);; + +(* ------------------------------------------------------------------------- *) +(* Inner product. *) +(* ------------------------------------------------------------------------- *) + +parse_as_infix("inner",(20,"right"));; + +let inner = new_definition + `!x y:real^(N)multivector. + x inner y = + Product (\s t. if s = {} \/ t = {} \/ + ~((s DIFF t) = {} /\ ~(t DIFF s = {})) + then &0 + else --(&1) pow CARD {i,j | i IN 1..dimindex(:N) /\ + j IN 1..dimindex(:N) /\ + i IN s /\ j IN t /\ i > j}) + (\s t. (s DIFF t) UNION (t DIFF s)) + x y`;; + +let BILINEAR_INNER = prove + (`bilinear(inner)`, + REWRITE_TAC[REWRITE_RULE[GSYM FUN_EQ_THM; ETA_AX] inner] THEN + MATCH_ACCEPT_TAC BILINEAR_PRODUCT);; + +let INNER_LADD = (MATCH_MP BILINEAR_LADD o SPEC_ALL) BILINEAR_INNER;; +let INNER_RADD = (MATCH_MP BILINEAR_RADD o SPEC_ALL) BILINEAR_INNER;; +let INNER_LMUL = (MATCH_MP BILINEAR_LMUL o SPEC_ALL) BILINEAR_INNER;; +let INNER_RMUL = (MATCH_MP BILINEAR_RMUL o SPEC_ALL) BILINEAR_INNER;; +let INNER_LNEG = (MATCH_MP BILINEAR_LNEG o SPEC_ALL) BILINEAR_INNER;; +let INNER_RNEG = (MATCH_MP BILINEAR_RNEG o SPEC_ALL) BILINEAR_INNER;; +let INNER_LZERO = (MATCH_MP BILINEAR_LZERO o SPEC_ALL) BILINEAR_INNER;; +let INNER_RZERO = (MATCH_MP BILINEAR_RZERO o SPEC_ALL) BILINEAR_INNER;; + +(* ------------------------------------------------------------------------- *) +(* Actions of products on basis and singleton basis. *) +(* ------------------------------------------------------------------------- *) + +let PRODUCT_MBASIS = prove + (`!s t. Product mult op (mbasis s) (mbasis t) :real^(N)multivector = + if s SUBSET 1..dimindex(:N) /\ t SUBSET 1..dimindex(:N) + then mult s t % mbasis(op s t) + else vec 0`, + REPEAT GEN_TAC THEN REWRITE_TAC[Product_DEF] THEN + SIMP_TAC[MULTIVECTOR_MUL_COMPONENT; MBASIS_COMPONENT] THEN + REWRITE_TAC[REAL_ARITH + `(if p then &1 else &0) * (if q then &1 else &0) * x = + if q then if p then x else &0 else &0`] THEN + REPEAT + (GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [COND_RAND] THEN + GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [COND_RATOR] THEN + SIMP_TAC[VECTOR_MUL_LZERO; COND_ID; VSUM_DELTA; IN_ELIM_THM; VSUM_0] THEN + ASM_CASES_TAC `t SUBSET 1..dimindex(:N)` THEN ASM_REWRITE_TAC[]));; + +let PRODUCT_MBASIS_SING = prove + (`!i j. Product mult op (mbasis{i}) (mbasis{j}) :real^(N)multivector = + if i IN 1..dimindex(:N) /\ j IN 1..dimindex(:N) + then mult {i} {j} % mbasis(op {i} {j}) + else vec 0`, + REWRITE_TAC[PRODUCT_MBASIS; SET_RULE `{x} SUBSET s <=> x IN s`]);; + +let GEOM_MBASIS = prove + (`!s t. mbasis s * mbasis t :real^(N)multivector = + if s SUBSET 1..dimindex(:N) /\ t SUBSET 1..dimindex(:N) + then --(&1) pow CARD {i,j | i IN s /\ j IN t /\ i > j} % + mbasis((s DIFF t) UNION (t DIFF s)) + else vec 0`, + REPEAT GEN_TAC THEN REWRITE_TAC[geom_mul; PRODUCT_MBASIS] THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN + AP_THM_TAC THEN AP_TERM_TAC THEN AP_TERM_TAC THEN AP_TERM_TAC THEN + REWRITE_TAC[EXTENSION; IN_ELIM_PAIR_THM; FORALL_PAIR_THM] THEN + ASM_MESON_TAC[SUBSET]);; + +let GEOM_MBASIS_SING = prove + (`!i j. mbasis{i} * mbasis{j} :real^(N)multivector = + if i IN 1..dimindex(:N) /\ j IN 1..dimindex(:N) + then if i = j then mbasis{} + else if i < j then mbasis{i,j} + else --(mbasis{i,j}) + else vec 0`, + REPEAT GEN_TAC THEN REWRITE_TAC[geom_mul; PRODUCT_MBASIS_SING] THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[IN_SING] THEN + SUBGOAL_THEN + `{i',j' | i' IN 1 .. dimindex (:N) /\ + j' IN 1 .. dimindex (:N) /\ + i' = i /\ + j' = j /\ + i' > j'} = + if i > j then {(i,j)} else {}` + SUBST1_TAC THENL + [REWRITE_TAC[EXTENSION; FORALL_PAIR_THM; IN_ELIM_PAIR_THM; IN_SING] THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[IN_SING; NOT_IN_EMPTY; PAIR_EQ] THEN + ASM_MESON_TAC[LT_REFL]; + ALL_TAC] THEN + ASM_CASES_TAC `i:num = j` THEN ASM_REWRITE_TAC[GT; LT_REFL] THENL + [REWRITE_TAC[CARD_CLAUSES; real_pow; VECTOR_MUL_LID] THEN + AP_TERM_TAC THEN SET_TAC[]; + ALL_TAC] THEN + ASM_SIMP_TAC[SET_RULE + `~(i = j) ==> ({i} DIFF {j}) UNION ({j} DIFF {i}) = {i,j}`] THEN + FIRST_ASSUM(SUBST1_TAC o MATCH_MP (ARITH_RULE + `~(i:num = j) ==> (j < i <=> ~(i < j))`)) THEN + ASM_CASES_TAC `i:num < j` THEN + ASM_SIMP_TAC[CARD_CLAUSES; real_pow; VECTOR_MUL_LID; FINITE_RULES; + NOT_IN_EMPTY] THEN + VECTOR_ARITH_TAC);; + +let OUTER_MBASIS = prove + (`!s t. (mbasis s) outer (mbasis t) :real^(N)multivector = + if s SUBSET 1..dimindex(:N) /\ t SUBSET 1..dimindex(:N) /\ + s INTER t = {} + then --(&1) pow CARD {i,j | i IN s /\ j IN t /\ i > j} % + mbasis(s UNION t) + else vec 0`, + REPEAT GEN_TAC THEN REWRITE_TAC[OUTER; PRODUCT_MBASIS] THEN + ASM_CASES_TAC `(s:num->bool) INTER t = {}` THEN + ASM_REWRITE_TAC[VECTOR_MUL_LZERO; COND_ID] THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN + AP_THM_TAC THEN AP_TERM_TAC THEN AP_TERM_TAC THEN AP_TERM_TAC THEN + REWRITE_TAC[EXTENSION; IN_ELIM_PAIR_THM; FORALL_PAIR_THM] THEN + ASM_MESON_TAC[SUBSET]);; + +let OUTER_MBASIS_SING = prove + (`!i j. mbasis{i} outer mbasis{j} :real^(N)multivector = + if i IN 1..dimindex(:N) /\ j IN 1..dimindex(:N) /\ ~(i = j) + then if i < j then mbasis{i,j} else --(mbasis{i,j}) + else vec 0`, + REPEAT GEN_TAC THEN REWRITE_TAC[OUTER; PRODUCT_MBASIS_SING] THEN + REWRITE_TAC[SET_RULE `{i} INTER {j} = {} <=> ~(i = j)`] THEN + ASM_CASES_TAC `i:num = j` THEN + ASM_REWRITE_TAC[VECTOR_MUL_LZERO; COND_ID] THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[IN_SING] THEN + SUBGOAL_THEN + `{i',j' | i' IN 1 .. dimindex (:N) /\ + j' IN 1 .. dimindex (:N) /\ + i' = i /\ + j' = j /\ + i' > j'} = + if i > j then {(i,j)} else {}` + SUBST1_TAC THENL + [REWRITE_TAC[EXTENSION; FORALL_PAIR_THM; IN_ELIM_PAIR_THM; IN_SING] THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[IN_SING; NOT_IN_EMPTY; PAIR_EQ] THEN + ASM_MESON_TAC[LT_REFL]; + ALL_TAC] THEN + ASM_SIMP_TAC[GT; SET_RULE `{i} UNION {j} = {i,j}`] THEN + FIRST_ASSUM(SUBST1_TAC o MATCH_MP (ARITH_RULE + `~(i:num = j) ==> (j < i <=> ~(i < j))`)) THEN + ASM_CASES_TAC `i:num < j` THEN + ASM_SIMP_TAC[CARD_CLAUSES; real_pow; VECTOR_MUL_LID; FINITE_RULES; + NOT_IN_EMPTY] THEN + VECTOR_ARITH_TAC);; + +(* ------------------------------------------------------------------------- *) +(* Some simple consequences. *) +(* ------------------------------------------------------------------------- *) + +let OUTER_MBASIS_SKEWSYM = prove + (`!i j. mbasis{i} outer mbasis{j} = --(mbasis{j} outer mbasis{i})`, + REPEAT GEN_TAC THEN REWRITE_TAC[OUTER_MBASIS_SING] THEN + ASM_CASES_TAC `i:num = j` THEN ASM_REWRITE_TAC[VECTOR_NEG_0] THEN + FIRST_ASSUM(DISJ_CASES_TAC o MATCH_MP (ARITH_RULE + `~(i:num = j) ==> i < j /\ ~(j < i) \/ j < i /\ ~(i < j)`)) THEN + ASM_REWRITE_TAC[CONJ_ACI] THEN COND_CASES_TAC THEN + ASM_REWRITE_TAC[VECTOR_NEG_NEG; VECTOR_NEG_0] THEN + REPEAT AP_TERM_TAC THEN SET_TAC[]);; + +let OUTER_MBASIS_REFL = prove + (`!i. mbasis{i} outer mbasis{i} = vec 0`, + GEN_TAC THEN MATCH_MP_TAC(VECTOR_ARITH + `!x:real^N. x = --x ==> x = vec 0`) THEN + MATCH_ACCEPT_TAC OUTER_MBASIS_SKEWSYM);; + +let OUTER_MBASIS_LSCALAR = prove + (`!x. mbasis{} outer x = x`, + MATCH_MP_TAC MBASIS_EXTENSION THEN SIMP_TAC[OUTER_RMUL; OUTER_RADD] THEN + SIMP_TAC[OUTER_MBASIS; EMPTY_SUBSET; INTER_EMPTY; UNION_EMPTY] THEN + REWRITE_TAC[SET_RULE `{i,j | i IN {} /\ j IN s /\ i:num > j} = {}`] THEN + REWRITE_TAC[CARD_CLAUSES; real_pow; VECTOR_MUL_LID]);; + +let OUTER_MBASIS_RSCALAR = prove + (`!x. x outer mbasis{} = x`, + MATCH_MP_TAC MBASIS_EXTENSION THEN SIMP_TAC[OUTER_LMUL; OUTER_LADD] THEN + SIMP_TAC[OUTER_MBASIS; EMPTY_SUBSET; INTER_EMPTY; UNION_EMPTY] THEN + REWRITE_TAC[SET_RULE `{i,j | i IN s /\ j IN {} /\ i:num > j} = {}`] THEN + REWRITE_TAC[CARD_CLAUSES; real_pow; VECTOR_MUL_LID]);; + +let MBASIS_SPLIT = prove + (`!a s. (!x. x IN s ==> a < x) + ==> mbasis (a INSERT s) = mbasis{a} outer mbasis s`, + REPEAT STRIP_TAC THEN REWRITE_TAC[OUTER_MBASIS] THEN + SUBGOAL_THEN `{a:num} INTER s = {}` SUBST1_TAC THENL + [ASM SET_TAC [LT_REFL]; ALL_TAC] THEN + SIMP_TAC[SET_RULE`{a} SUBSET t /\ s SUBSET t <=> (a INSERT s) SUBSET t`] THEN + COND_CASES_TAC THENL [ALL_TAC; ASM_MESON_TAC[MBASIS_EQ_0]] THEN + REWRITE_TAC[SET_RULE `{a} UNION s = a INSERT s`] THEN + SUBGOAL_THEN `{(i:num),(j:num) | i IN {a} /\ j IN s /\ i > j} = {}` + (fun th -> SIMP_TAC[th; CARD_CLAUSES; real_pow; VECTOR_MUL_LID]) THEN + REWRITE_TAC[EXTENSION; FORALL_PAIR_THM; IN_ELIM_PAIR_THM; IN_SING; + NOT_IN_EMPTY] THEN + ASM_MESON_TAC[ARITH_RULE `~(n < m /\ n:num > m)`]);; + +(* ------------------------------------------------------------------------- *) +(* Just for generality, normalize a set enumeration. *) +(* ------------------------------------------------------------------------- *) + +let SETENUM_NORM_CONV = + let conv = + GEN_REWRITE_CONV I [EXTENSION] THENC + GEN_REWRITE_CONV TOP_SWEEP_CONV [IN_SING; IN_INSERT] THENC + BINDER_CONV(EQT_INTRO o DISJ_ACI_RULE) THENC + GEN_REWRITE_CONV I [FORALL_SIMP] in + fun tm -> + let nums = dest_setenum tm in + let nums' = map mk_numeral (sort ( a < x) <=> T) /\ + ((!x:num. x IN (y INSERT s) ==> a < x) <=> + a < y /\ (!x. x IN s ==> a < x))` in + let SET_CHECK_CONV = + GEN_REWRITE_CONV TOP_SWEEP_CONV [setlemma] THENC NUM_REDUCE_CONV + and INST_SPLIT = PART_MATCH (lhs o rand) MBASIS_SPLIT + and INST_MERGE = PART_MATCH (lhs o rand) (GSYM MBASIS_SPLIT) in + let rec conv tm = + if length(dest_setenum(rand tm)) <= 1 then REFL tm else + let th = MP_CONV SET_CHECK_CONV (INST_SPLIT tm) in + let th' = RAND_CONV conv (rand(concl th)) in + TRANS th th' in + (fun tm -> + try let op,se = dest_comb tm in + if fst(dest_const op) = "mbasis" & forall is_numeral (dest_setenum se) + then (RAND_CONV SETENUM_NORM_CONV THENC conv) tm + else fail() + with Failure _ -> failwith "MBASIS_SPLIT_CONV"), + (fun tm -> try MP_CONV SET_CHECK_CONV (INST_MERGE tm) + with Failure _ -> failwith "MBASIS_MERGE_CONV");; + +(* ------------------------------------------------------------------------- *) +(* Convergent (if slow) rewrite set to bubble into position. *) +(* ------------------------------------------------------------------------- *) + +let OUTER_ACI = prove + (`(!x y z. (x outer y) outer z = x outer (y outer z)) /\ + (!i j. i > j + ==> mbasis{i} outer mbasis{j} = + --(&1) % (mbasis{j} outer mbasis{i})) /\ + (!i j x. i > j + ==> mbasis{i} outer mbasis{j} outer x = + --(&1) % (mbasis{j} outer mbasis{i} outer x)) /\ + (!i. mbasis{i} outer mbasis{i} = vec 0) /\ + (!i x. mbasis{i} outer mbasis{i} outer x = vec 0) /\ + (!x. mbasis{} outer x = x) /\ + (!x. x outer mbasis{} = x)`, + REWRITE_TAC[OUTER_ASSOC; OUTER_LZERO; OUTER_RZERO; OUTER_LADD; + OUTER_RADD; OUTER_LMUL; OUTER_RMUL; OUTER_LZERO; OUTER_RZERO] THEN + REWRITE_TAC[OUTER_MBASIS_REFL; OUTER_LZERO] THEN + REWRITE_TAC[OUTER_MBASIS_LSCALAR; OUTER_MBASIS_RSCALAR] THEN + SIMP_TAC[GSYM VECTOR_NEG_MINUS1; VECTOR_ARITH `x - y:real^N = x + --y`] THEN + MESON_TAC[OUTER_MBASIS_SKEWSYM; OUTER_LNEG]);; + +(* ------------------------------------------------------------------------- *) +(* Group the final "c1 % mbasis s1 + ... + cn % mbasis sn". *) +(* ------------------------------------------------------------------------- *) + +let MBASIS_GROUP_CONV tm = + let tms = striplist(dest_binary "vector_add") tm in + if length tms = 1 then LAND_CONV REAL_POLY_CONV tm else + let vadd_tm = rator(rator tm) in + let mk_vadd = mk_binop vadd_tm in + let mbs = map (snd o dest_binary "%") tms in + let tmbs = zip mbs tms and mset = setify mbs in + let grps = map (fun x -> map snd (filter (fun (x',_) -> x' = x) tmbs)) + mset in + let tm' = end_itlist mk_vadd (map (end_itlist mk_vadd) grps) in + let th1 = AC VECTOR_ADD_AC (mk_eq(tm,tm')) + and th2 = + (GEN_REWRITE_CONV DEPTH_CONV [GSYM VECTOR_ADD_RDISTRIB] THENC + DEPTH_BINOP_CONV vadd_tm (LAND_CONV REAL_POLY_CONV)) tm' in + TRANS th1 th2;; + +(* ------------------------------------------------------------------------- *) +(* Overall conversion. *) +(* ------------------------------------------------------------------------- *) + +let OUTER_CANON_CONV = + ONCE_DEPTH_CONV MBASIS_SPLIT_CONV THENC + GEN_REWRITE_CONV TOP_DEPTH_CONV + [VECTOR_SUB; VECTOR_NEG_MINUS1; + OUTER_LADD; OUTER_RADD; OUTER_LMUL; OUTER_RMUL; OUTER_LZERO; OUTER_RZERO; + VECTOR_ADD_LDISTRIB; VECTOR_ADD_RDISTRIB; VECTOR_MUL_ASSOC; + VECTOR_MUL_LZERO; VECTOR_MUL_RZERO] THENC + REAL_RAT_REDUCE_CONV THENC + PURE_SIMP_CONV[OUTER_ACI; ARITH_GT; ARITH_GE; OUTER_LMUL; OUTER_RMUL; + OUTER_LZERO; OUTER_RZERO] THENC + PURE_REWRITE_CONV[VECTOR_MUL_LZERO; VECTOR_MUL_RZERO; + VECTOR_ADD_LID; VECTOR_ADD_RID; VECTOR_MUL_ASSOC] THENC + GEN_REWRITE_CONV I [GSYM VECTOR_MUL_LID] THENC + PURE_REWRITE_CONV + [VECTOR_ADD_LDISTRIB; VECTOR_ADD_RDISTRIB; VECTOR_MUL_ASSOC] THENC + REAL_RAT_REDUCE_CONV THENC PURE_REWRITE_CONV[GSYM VECTOR_ADD_ASSOC] THENC + DEPTH_CONV MBASIS_MERGE_CONV THENC + MBASIS_GROUP_CONV THENC + GEN_REWRITE_CONV DEPTH_CONV [GSYM VECTOR_ADD_RDISTRIB] THENC + REAL_RAT_REDUCE_CONV;; + +(* ------------------------------------------------------------------------- *) +(* Iterated operation in order. *) +(* I guess this ought to be added to the core... *) +(* ------------------------------------------------------------------------- *) + +let seqiterate_EXISTS = prove + (`!op f. ?h. + !s. h s = if INFINITE s \/ s = {} then neutral op else + let i = minimal x. x IN s in + if s = {i} then f(i) else op (f i) (h (s DELETE i))`, + REPEAT GEN_TAC THEN REWRITE_TAC[INFINITE] THEN + MATCH_MP_TAC(MATCH_MP WF_REC (ISPEC `CARD:(num->bool)->num` WF_MEASURE)) THEN + REPEAT STRIP_TAC THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN + LET_TAC THEN CONV_TAC(ONCE_DEPTH_CONV let_CONV) THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN AP_TERM_TAC THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN REWRITE_TAC[MEASURE] THEN + RULE_ASSUM_TAC(REWRITE_RULE[DE_MORGAN_THM]) THEN + SUBGOAL_THEN `?i:num. i IN s` MP_TAC THENL + [ASM_MESON_TAC[MEMBER_NOT_EMPTY]; ALL_TAC] THEN + GEN_REWRITE_TAC LAND_CONV [MINIMAL] THEN + ASM_SIMP_TAC[CARD_DELETE; CARD_EQ_0; ARITH_RULE `n - 1 < n <=> ~(n = 0)`]);; + +let EXISTS_SWAP = prove + (`!P. (?f. P f) <=> (?f:A->B->C. P (\b a. f a b))`, + GEN_TAC THEN EQ_TAC THEN DISCH_THEN CHOOSE_TAC THENL + [EXISTS_TAC `\a b. (f:B->A->C) b a` THEN ASM_REWRITE_TAC[ETA_AX]; + ASM_MESON_TAC[]]);; + +let seqiterate = new_specification ["seqiterate"] + (REWRITE_RULE[SKOLEM_THM] + (ONCE_REWRITE_RULE[EXISTS_SWAP] + (ONCE_REWRITE_RULE[SKOLEM_THM] seqiterate_EXISTS)));; + +let MINIMAL_IN_INSERT = prove + (`!s i. (!j. j IN s ==> i < j) ==> (minimal j. j IN (i INSERT s)) = i`, + REPEAT STRIP_TAC THEN REWRITE_TAC[minimal] THEN + MATCH_MP_TAC SELECT_UNIQUE THEN + REWRITE_TAC[IN_INSERT] THEN ASM_MESON_TAC[LT_ANTISYM]);; + +let SEQITERATE_CLAUSES = prove + (`(!op f. seqiterate op {} f = neutral op) /\ + (!op f i. seqiterate op {i} f = f(i)) /\ + (!op f i s. FINITE s /\ ~(s = {}) /\ (!j. j IN s ==> i < j) + ==> seqiterate op (i INSERT s) f = + op (f i) (seqiterate op s f))`, + REPEAT STRIP_TAC THEN GEN_REWRITE_TAC LAND_CONV [seqiterate] THEN + ASM_SIMP_TAC[NOT_INSERT_EMPTY; INFINITE; FINITE_INSERT; FINITE_RULES] THEN + ASM_SIMP_TAC[MINIMAL_IN_INSERT; NOT_IN_EMPTY; LET_DEF; LET_END_DEF] THEN + SUBGOAL_THEN `~((i:num) IN s)` ASSUME_TAC THENL + [ASM_MESON_TAC[LT_REFL]; ALL_TAC] THEN + ASM_SIMP_TAC[DELETE_INSERT; SET_RULE + `~(i IN s) /\ ~(s = {}) ==> (s DELETE i = s) /\ ~(i INSERT s = {i})`]);; + +(* ------------------------------------------------------------------------- *) +(* In the "common" case this agrees with ordinary iteration. *) +(* ------------------------------------------------------------------------- *) + +let SEQITERATE_ITERATE = prove + (`!op f s. monoidal op /\ FINITE s ==> seqiterate op s f = iterate op s f`, + REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN + GEN_TAC THEN DISCH_TAC THEN GEN_TAC THEN + MATCH_MP_TAC FINITE_INDUCT_DELETE THEN + ASM_SIMP_TAC[SEQITERATE_CLAUSES; ITERATE_CLAUSES] THEN + GEN_TAC THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN + GEN_REWRITE_TAC LAND_CONV [num_WOP] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `i:num` THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN DISCH_TAC THEN + FIRST_X_ASSUM(SUBST1_TAC o MATCH_MP (SET_RULE + `i IN s ==> s = i INSERT (s DELETE i)`)) THEN + ASM_SIMP_TAC[ITERATE_CLAUSES; FINITE_DELETE; IN_DELETE] THEN + ASM_CASES_TAC `s DELETE (i:num) = {}` THEN + ASM_SIMP_TAC[SEQITERATE_CLAUSES; ITERATE_CLAUSES] THENL + [ASM_MESON_TAC[monoidal]; FIRST_X_ASSUM(SUBST1_TAC o SYM)] THEN + MATCH_MP_TAC(last(CONJUNCTS SEQITERATE_CLAUSES)) THEN + ASM_REWRITE_TAC[FINITE_DELETE; IN_DELETE] THEN + ASM_MESON_TAC[LT_ANTISYM; LT_CASES]);; + +(* ------------------------------------------------------------------------- *) +(* Outermorphism extension. *) +(* ------------------------------------------------------------------------- *) + +let outermorphism = new_definition + `outermorphism(f:real^N->real^P) (x:real^(N)multivector) = + vsum {s | s SUBSET 1..dimindex(:N)} + (\s. x$$s % seqiterate(outer) s (multivec o f o basis))`;; + +let NEUTRAL_OUTER = prove + (`neutral(outer) = mbasis{}`, + REWRITE_TAC[neutral] THEN MATCH_MP_TAC SELECT_UNIQUE THEN + MESON_TAC[OUTER_MBASIS_LSCALAR; OUTER_MBASIS_RSCALAR]);; + +let OUTERMORPHISM_MBASIS = prove + (`!f:real^M->real^N s t. + s SUBSET 1..dimindex(:M) + ==> outermorphism f (mbasis s) = + seqiterate(outer) s (multivec o f o basis)`, + REWRITE_TAC[outermorphism] THEN SIMP_TAC[MBASIS_COMPONENT] THEN + ONCE_REWRITE_TAC[COND_RAND] THEN ONCE_REWRITE_TAC[COND_RATOR] THEN + SIMP_TAC[VECTOR_MUL_LZERO; VSUM_DELTA; IN_ELIM_THM; VECTOR_MUL_LID]);; + +let OUTERMORPHISM_MBASIS_EMPTY = prove + (`!f. outermorphism f (mbasis {}) = mbasis {}`, + SIMP_TAC[OUTERMORPHISM_MBASIS; EMPTY_SUBSET; SEQITERATE_CLAUSES] THEN + REWRITE_TAC[NEUTRAL_OUTER]);; + +(* ------------------------------------------------------------------------- *) +(* Reversion operation. *) +(* ------------------------------------------------------------------------- *) + +let reversion = new_definition + `(reversion:real^(N)multivector->real^(N)multivector) x = + lambdas s. --(&1) pow ((CARD(s) * (CARD(s) - 1)) DIV 2) * x$$s`;; diff --git a/Multivariate/complex_database.ml b/Multivariate/complex_database.ml new file mode 100644 index 0000000..6f3b7a3 --- /dev/null +++ b/Multivariate/complex_database.ml @@ -0,0 +1,11152 @@ +needs "help.ml";; + +theorems := +[ +"ABEL_LEMMA",ABEL_LEMMA; +"ABEL_LIMIT_THEOREM",ABEL_LIMIT_THEOREM; +"ABEL_POWER_SERIES_CONTINUOUS",ABEL_POWER_SERIES_CONTINUOUS; +"ABSOLUTELY_INTEGRABLE_0",ABSOLUTELY_INTEGRABLE_0; +"ABSOLUTELY_INTEGRABLE_ABS",ABSOLUTELY_INTEGRABLE_ABS; +"ABSOLUTELY_INTEGRABLE_ABSOLUTELY_INTEGRABLE_BOUND",ABSOLUTELY_INTEGRABLE_ABSOLUTELY_INTEGRABLE_BOUND; +"ABSOLUTELY_INTEGRABLE_ABSOLUTELY_INTEGRABLE_COMPONENT_LBOUND",ABSOLUTELY_INTEGRABLE_ABSOLUTELY_INTEGRABLE_COMPONENT_LBOUND; +"ABSOLUTELY_INTEGRABLE_ABSOLUTELY_INTEGRABLE_COMPONENT_UBOUND",ABSOLUTELY_INTEGRABLE_ABSOLUTELY_INTEGRABLE_COMPONENT_UBOUND; +"ABSOLUTELY_INTEGRABLE_ABSOLUTELY_INTEGRABLE_DROP_LBOUND",ABSOLUTELY_INTEGRABLE_ABSOLUTELY_INTEGRABLE_DROP_LBOUND; +"ABSOLUTELY_INTEGRABLE_ABSOLUTELY_INTEGRABLE_DROP_UBOUND",ABSOLUTELY_INTEGRABLE_ABSOLUTELY_INTEGRABLE_DROP_UBOUND; +"ABSOLUTELY_INTEGRABLE_ABS_1",ABSOLUTELY_INTEGRABLE_ABS_1; +"ABSOLUTELY_INTEGRABLE_ABS_EQ",ABSOLUTELY_INTEGRABLE_ABS_EQ; +"ABSOLUTELY_INTEGRABLE_ADD",ABSOLUTELY_INTEGRABLE_ADD; +"ABSOLUTELY_INTEGRABLE_APPROXIMATE_CONTINUOUS",ABSOLUTELY_INTEGRABLE_APPROXIMATE_CONTINUOUS; +"ABSOLUTELY_INTEGRABLE_BOUNDED_SETVARIATION",ABSOLUTELY_INTEGRABLE_BOUNDED_SETVARIATION; +"ABSOLUTELY_INTEGRABLE_BOUNDED_SETVARIATION_EQ",ABSOLUTELY_INTEGRABLE_BOUNDED_SETVARIATION_EQ; +"ABSOLUTELY_INTEGRABLE_BOUNDED_SETVARIATION_UNIV_EQ",ABSOLUTELY_INTEGRABLE_BOUNDED_SETVARIATION_UNIV_EQ; +"ABSOLUTELY_INTEGRABLE_CMUL",ABSOLUTELY_INTEGRABLE_CMUL; +"ABSOLUTELY_INTEGRABLE_COMPONENTWISE",ABSOLUTELY_INTEGRABLE_COMPONENTWISE; +"ABSOLUTELY_INTEGRABLE_CONST",ABSOLUTELY_INTEGRABLE_CONST; +"ABSOLUTELY_INTEGRABLE_CONTINUOUS",ABSOLUTELY_INTEGRABLE_CONTINUOUS; +"ABSOLUTELY_INTEGRABLE_IMP_INTEGRABLE",ABSOLUTELY_INTEGRABLE_IMP_INTEGRABLE; +"ABSOLUTELY_INTEGRABLE_INF_1",ABSOLUTELY_INTEGRABLE_INF_1; +"ABSOLUTELY_INTEGRABLE_INTEGRABLE_BOUND",ABSOLUTELY_INTEGRABLE_INTEGRABLE_BOUND; +"ABSOLUTELY_INTEGRABLE_LE",ABSOLUTELY_INTEGRABLE_LE; +"ABSOLUTELY_INTEGRABLE_LEBESGUE_POINTS",ABSOLUTELY_INTEGRABLE_LEBESGUE_POINTS; +"ABSOLUTELY_INTEGRABLE_LINEAR",ABSOLUTELY_INTEGRABLE_LINEAR; +"ABSOLUTELY_INTEGRABLE_MAX",ABSOLUTELY_INTEGRABLE_MAX; +"ABSOLUTELY_INTEGRABLE_MAX_1",ABSOLUTELY_INTEGRABLE_MAX_1; +"ABSOLUTELY_INTEGRABLE_MEASURABLE",ABSOLUTELY_INTEGRABLE_MEASURABLE; +"ABSOLUTELY_INTEGRABLE_MIN",ABSOLUTELY_INTEGRABLE_MIN; +"ABSOLUTELY_INTEGRABLE_MIN_1",ABSOLUTELY_INTEGRABLE_MIN_1; +"ABSOLUTELY_INTEGRABLE_NEG",ABSOLUTELY_INTEGRABLE_NEG; +"ABSOLUTELY_INTEGRABLE_NORM",ABSOLUTELY_INTEGRABLE_NORM; +"ABSOLUTELY_INTEGRABLE_ON_CONST",ABSOLUTELY_INTEGRABLE_ON_CONST; +"ABSOLUTELY_INTEGRABLE_ON_SUBINTERVAL",ABSOLUTELY_INTEGRABLE_ON_SUBINTERVAL; +"ABSOLUTELY_INTEGRABLE_RESTRICT_UNIV",ABSOLUTELY_INTEGRABLE_RESTRICT_UNIV; +"ABSOLUTELY_INTEGRABLE_SET_VARIATION",ABSOLUTELY_INTEGRABLE_SET_VARIATION; +"ABSOLUTELY_INTEGRABLE_SUB",ABSOLUTELY_INTEGRABLE_SUB; +"ABSOLUTELY_INTEGRABLE_SUP_1",ABSOLUTELY_INTEGRABLE_SUP_1; +"ABSOLUTELY_INTEGRABLE_VSUM",ABSOLUTELY_INTEGRABLE_VSUM; +"ABSOLUTELY_REAL_INTEGRABLE_0",ABSOLUTELY_REAL_INTEGRABLE_0; +"ABSOLUTELY_REAL_INTEGRABLE_ABS",ABSOLUTELY_REAL_INTEGRABLE_ABS; +"ABSOLUTELY_REAL_INTEGRABLE_ABSOLUTELY_REAL_INTEGRABLE_BOUND",ABSOLUTELY_REAL_INTEGRABLE_ABSOLUTELY_REAL_INTEGRABLE_BOUND; +"ABSOLUTELY_REAL_INTEGRABLE_ABSOLUTELY_REAL_INTEGRABLE_LBOUND",ABSOLUTELY_REAL_INTEGRABLE_ABSOLUTELY_REAL_INTEGRABLE_LBOUND; +"ABSOLUTELY_REAL_INTEGRABLE_ABSOLUTELY_REAL_INTEGRABLE_UBOUND",ABSOLUTELY_REAL_INTEGRABLE_ABSOLUTELY_REAL_INTEGRABLE_UBOUND; +"ABSOLUTELY_REAL_INTEGRABLE_ADD",ABSOLUTELY_REAL_INTEGRABLE_ADD; +"ABSOLUTELY_REAL_INTEGRABLE_BOUNDED_MEASURABLE_PRODUCT",ABSOLUTELY_REAL_INTEGRABLE_BOUNDED_MEASURABLE_PRODUCT; +"ABSOLUTELY_REAL_INTEGRABLE_CONST",ABSOLUTELY_REAL_INTEGRABLE_CONST; +"ABSOLUTELY_REAL_INTEGRABLE_CONTINUOUS",ABSOLUTELY_REAL_INTEGRABLE_CONTINUOUS; +"ABSOLUTELY_REAL_INTEGRABLE_DECREASING",ABSOLUTELY_REAL_INTEGRABLE_DECREASING; +"ABSOLUTELY_REAL_INTEGRABLE_DECREASING_PRODUCT",ABSOLUTELY_REAL_INTEGRABLE_DECREASING_PRODUCT; +"ABSOLUTELY_REAL_INTEGRABLE_IMP_INTEGRABLE",ABSOLUTELY_REAL_INTEGRABLE_IMP_INTEGRABLE; +"ABSOLUTELY_REAL_INTEGRABLE_INCREASING",ABSOLUTELY_REAL_INTEGRABLE_INCREASING; +"ABSOLUTELY_REAL_INTEGRABLE_INCREASING_PRODUCT",ABSOLUTELY_REAL_INTEGRABLE_INCREASING_PRODUCT; +"ABSOLUTELY_REAL_INTEGRABLE_INF",ABSOLUTELY_REAL_INTEGRABLE_INF; +"ABSOLUTELY_REAL_INTEGRABLE_INTEGRABLE_BOUND",ABSOLUTELY_REAL_INTEGRABLE_INTEGRABLE_BOUND; +"ABSOLUTELY_REAL_INTEGRABLE_LE",ABSOLUTELY_REAL_INTEGRABLE_LE; +"ABSOLUTELY_REAL_INTEGRABLE_LINEAR",ABSOLUTELY_REAL_INTEGRABLE_LINEAR; +"ABSOLUTELY_REAL_INTEGRABLE_LMUL",ABSOLUTELY_REAL_INTEGRABLE_LMUL; +"ABSOLUTELY_REAL_INTEGRABLE_MAX",ABSOLUTELY_REAL_INTEGRABLE_MAX; +"ABSOLUTELY_REAL_INTEGRABLE_MIN",ABSOLUTELY_REAL_INTEGRABLE_MIN; +"ABSOLUTELY_REAL_INTEGRABLE_NEG",ABSOLUTELY_REAL_INTEGRABLE_NEG; +"ABSOLUTELY_REAL_INTEGRABLE_ON",ABSOLUTELY_REAL_INTEGRABLE_ON; +"ABSOLUTELY_REAL_INTEGRABLE_ON_SUBINTERVAL",ABSOLUTELY_REAL_INTEGRABLE_ON_SUBINTERVAL; +"ABSOLUTELY_REAL_INTEGRABLE_REAL_MEASURABLE",ABSOLUTELY_REAL_INTEGRABLE_REAL_MEASURABLE; +"ABSOLUTELY_REAL_INTEGRABLE_RESTRICT_UNIV",ABSOLUTELY_REAL_INTEGRABLE_RESTRICT_UNIV; +"ABSOLUTELY_REAL_INTEGRABLE_RMUL",ABSOLUTELY_REAL_INTEGRABLE_RMUL; +"ABSOLUTELY_REAL_INTEGRABLE_SUB",ABSOLUTELY_REAL_INTEGRABLE_SUB; +"ABSOLUTELY_REAL_INTEGRABLE_SUM",ABSOLUTELY_REAL_INTEGRABLE_SUM; +"ABSOLUTELY_REAL_INTEGRABLE_SUP",ABSOLUTELY_REAL_INTEGRABLE_SUP; +"ABSOLUTE_RETRACTION_CONVEX_CLOSED",ABSOLUTE_RETRACTION_CONVEX_CLOSED; +"ABSOLUTE_RETRACTION_CONVEX_CLOSED_RELATIVE",ABSOLUTE_RETRACTION_CONVEX_CLOSED_RELATIVE; +"ABSOLUTE_RETRACT_CONTRACTIBLE_ANR",ABSOLUTE_RETRACT_CONTRACTIBLE_ANR; +"ABSOLUTE_RETRACT_CONVEX_CLOSED",ABSOLUTE_RETRACT_CONVEX_CLOSED; +"ABSOLUTE_RETRACT_HOMEOMORPHIC_CONVEX_COMPACT",ABSOLUTE_RETRACT_HOMEOMORPHIC_CONVEX_COMPACT; +"ABSOLUTE_RETRACT_IMP_AR",ABSOLUTE_RETRACT_IMP_AR; +"ABSOLUTE_RETRACT_IMP_AR_GEN",ABSOLUTE_RETRACT_IMP_AR_GEN; +"ABSOLUTE_RETRACT_PATH_IMAGE_ARC",ABSOLUTE_RETRACT_PATH_IMAGE_ARC; +"ABSORPTION",ABSORPTION; +"ABS_DROP",ABS_DROP; +"ABS_SIMP",ABS_SIMP; +"ABS_SQUARE_EQ_1",ABS_SQUARE_EQ_1; +"ABS_SQUARE_LE_1",ABS_SQUARE_LE_1; +"ABS_SQUARE_LT_1",ABS_SQUARE_LT_1; +"ACS_0",ACS_0; +"ACS_1",ACS_1; +"ACS_ASN",ACS_ASN; +"ACS_ASN_SQRT_NEG",ACS_ASN_SQRT_NEG; +"ACS_ASN_SQRT_POS",ACS_ASN_SQRT_POS; +"ACS_ATN",ACS_ATN; +"ACS_BOUNDS",ACS_BOUNDS; +"ACS_BOUNDS_LT",ACS_BOUNDS_LT; +"ACS_COS",ACS_COS; +"ACS_INJ",ACS_INJ; +"ACS_MONO_LE",ACS_MONO_LE; +"ACS_MONO_LE_EQ",ACS_MONO_LE_EQ; +"ACS_MONO_LT",ACS_MONO_LT; +"ACS_MONO_LT_EQ",ACS_MONO_LT_EQ; +"ACS_NEG",ACS_NEG; +"ACS_NEG_1",ACS_NEG_1; +"ADD",ADD; +"ADD1",ADD1; +"ADDITIVE_CONTENT_DIVISION",ADDITIVE_CONTENT_DIVISION; +"ADDITIVE_CONTENT_TAGGED_DIVISION",ADDITIVE_CONTENT_TAGGED_DIVISION; +"ADDITIVE_TAGGED_DIVISION_1",ADDITIVE_TAGGED_DIVISION_1; +"ADD_0",ADD_0; +"ADD_AC",ADD_AC; +"ADD_ASSOC",ADD_ASSOC; +"ADD_CLAUSES",ADD_CLAUSES; +"ADD_EQ_0",ADD_EQ_0; +"ADD_SUB",ADD_SUB; +"ADD_SUB2",ADD_SUB2; +"ADD_SUBR",ADD_SUBR; +"ADD_SUBR2",ADD_SUBR2; +"ADD_SUC",ADD_SUC; +"ADD_SYM",ADD_SYM; +"ADJOINT_ADJOINT",ADJOINT_ADJOINT; +"ADJOINT_CLAUSES",ADJOINT_CLAUSES; +"ADJOINT_COMPOSE",ADJOINT_COMPOSE; +"ADJOINT_INJECTIVE",ADJOINT_INJECTIVE; +"ADJOINT_INJECTIVE_INJECTIVE",ADJOINT_INJECTIVE_INJECTIVE; +"ADJOINT_INJECTIVE_INJECTIVE_0",ADJOINT_INJECTIVE_INJECTIVE_0; +"ADJOINT_LINEAR",ADJOINT_LINEAR; +"ADJOINT_MATRIX",ADJOINT_MATRIX; +"ADJOINT_SURJECTIVE",ADJOINT_SURJECTIVE; +"ADJOINT_UNIQUE",ADJOINT_UNIQUE; +"ADJOINT_WORKS",ADJOINT_WORKS; +"ADMISSIBLE_BASE",ADMISSIBLE_BASE; +"ADMISSIBLE_COMB",ADMISSIBLE_COMB; +"ADMISSIBLE_COND",ADMISSIBLE_COND; +"ADMISSIBLE_CONST",ADMISSIBLE_CONST; +"ADMISSIBLE_GUARDED_PATTERN",ADMISSIBLE_GUARDED_PATTERN; +"ADMISSIBLE_IMP_SUPERADMISSIBLE",ADMISSIBLE_IMP_SUPERADMISSIBLE; +"ADMISSIBLE_LAMBDA",ADMISSIBLE_LAMBDA; +"ADMISSIBLE_MAP",ADMISSIBLE_MAP; +"ADMISSIBLE_MATCH",ADMISSIBLE_MATCH; +"ADMISSIBLE_MATCH_SEQPATTERN",ADMISSIBLE_MATCH_SEQPATTERN; +"ADMISSIBLE_NEST",ADMISSIBLE_NEST; +"ADMISSIBLE_NSUM",ADMISSIBLE_NSUM; +"ADMISSIBLE_RAND",ADMISSIBLE_RAND; +"ADMISSIBLE_SEQPATTERN",ADMISSIBLE_SEQPATTERN; +"ADMISSIBLE_SUM",ADMISSIBLE_SUM; +"ADMISSIBLE_UNGUARDED_PATTERN",ADMISSIBLE_UNGUARDED_PATTERN; +"AFFINE",AFFINE; +"AFFINE_AFFINE_HULL",AFFINE_AFFINE_HULL; +"AFFINE_AFFINITY",AFFINE_AFFINITY; +"AFFINE_ALT",AFFINE_ALT; +"AFFINE_BASIS_EXISTS",AFFINE_BASIS_EXISTS; +"AFFINE_BOUNDED_EQ_LOWDIM",AFFINE_BOUNDED_EQ_LOWDIM; +"AFFINE_BOUNDED_EQ_TRIVIAL",AFFINE_BOUNDED_EQ_TRIVIAL; +"AFFINE_DEPENDENT_BIGGERSET",AFFINE_DEPENDENT_BIGGERSET; +"AFFINE_DEPENDENT_BIGGERSET_GENERAL",AFFINE_DEPENDENT_BIGGERSET_GENERAL; +"AFFINE_DEPENDENT_CHOOSE",AFFINE_DEPENDENT_CHOOSE; +"AFFINE_DEPENDENT_EXPLICIT",AFFINE_DEPENDENT_EXPLICIT; +"AFFINE_DEPENDENT_EXPLICIT_FINITE",AFFINE_DEPENDENT_EXPLICIT_FINITE; +"AFFINE_DEPENDENT_IMP_COLLINEAR_3",AFFINE_DEPENDENT_IMP_COLLINEAR_3; +"AFFINE_DEPENDENT_IMP_DEPENDENT",AFFINE_DEPENDENT_IMP_DEPENDENT; +"AFFINE_DEPENDENT_LINEAR_IMAGE",AFFINE_DEPENDENT_LINEAR_IMAGE; +"AFFINE_DEPENDENT_LINEAR_IMAGE_EQ",AFFINE_DEPENDENT_LINEAR_IMAGE_EQ; +"AFFINE_DEPENDENT_MONO",AFFINE_DEPENDENT_MONO; +"AFFINE_DEPENDENT_TRANSLATION",AFFINE_DEPENDENT_TRANSLATION; +"AFFINE_DEPENDENT_TRANSLATION_EQ",AFFINE_DEPENDENT_TRANSLATION_EQ; +"AFFINE_DIFFERENCES",AFFINE_DIFFERENCES; +"AFFINE_DIFFS_SUBSPACE",AFFINE_DIFFS_SUBSPACE; +"AFFINE_EMPTY",AFFINE_EMPTY; +"AFFINE_EQ_SUBSPACE",AFFINE_EQ_SUBSPACE; +"AFFINE_EXPLICIT",AFFINE_EXPLICIT; +"AFFINE_HULLS_EQ",AFFINE_HULLS_EQ; +"AFFINE_HULL_2",AFFINE_HULL_2; +"AFFINE_HULL_2_ALT",AFFINE_HULL_2_ALT; +"AFFINE_HULL_3",AFFINE_HULL_3; +"AFFINE_HULL_3_IMP_COLLINEAR",AFFINE_HULL_3_IMP_COLLINEAR; +"AFFINE_HULL_AFFINE_INTER_NONEMPTY_INTERIOR",AFFINE_HULL_AFFINE_INTER_NONEMPTY_INTERIOR; +"AFFINE_HULL_AFFINE_INTER_OPEN",AFFINE_HULL_AFFINE_INTER_OPEN; +"AFFINE_HULL_AFFINE_INTER_OPEN_IN",AFFINE_HULL_AFFINE_INTER_OPEN_IN; +"AFFINE_HULL_CLOSURE",AFFINE_HULL_CLOSURE; +"AFFINE_HULL_CONVEX_HULL",AFFINE_HULL_CONVEX_HULL; +"AFFINE_HULL_CONVEX_INTER_NONEMPTY_INTERIOR",AFFINE_HULL_CONVEX_INTER_NONEMPTY_INTERIOR; +"AFFINE_HULL_CONVEX_INTER_OPEN",AFFINE_HULL_CONVEX_INTER_OPEN; +"AFFINE_HULL_CONVEX_INTER_OPEN_IN",AFFINE_HULL_CONVEX_INTER_OPEN_IN; +"AFFINE_HULL_EMPTY",AFFINE_HULL_EMPTY; +"AFFINE_HULL_EQ",AFFINE_HULL_EQ; +"AFFINE_HULL_EQ_EMPTY",AFFINE_HULL_EQ_EMPTY; +"AFFINE_HULL_EQ_SING",AFFINE_HULL_EQ_SING; +"AFFINE_HULL_EQ_SPAN",AFFINE_HULL_EQ_SPAN; +"AFFINE_HULL_EQ_SPAN_EQ",AFFINE_HULL_EQ_SPAN_EQ; +"AFFINE_HULL_EXPLICIT",AFFINE_HULL_EXPLICIT; +"AFFINE_HULL_EXPLICIT_ALT",AFFINE_HULL_EXPLICIT_ALT; +"AFFINE_HULL_EXPLICIT_UNIQUE",AFFINE_HULL_EXPLICIT_UNIQUE; +"AFFINE_HULL_FACE_OF_DISJOINT_RELATIVE_INTERIOR",AFFINE_HULL_FACE_OF_DISJOINT_RELATIVE_INTERIOR; +"AFFINE_HULL_FINITE",AFFINE_HULL_FINITE; +"AFFINE_HULL_FINITE_INTERSECTION_HYPERPLANES",AFFINE_HULL_FINITE_INTERSECTION_HYPERPLANES; +"AFFINE_HULL_FINITE_STEP",AFFINE_HULL_FINITE_STEP; +"AFFINE_HULL_FINITE_STEP_GEN",AFFINE_HULL_FINITE_STEP_GEN; +"AFFINE_HULL_HALFSPACE_GE",AFFINE_HULL_HALFSPACE_GE; +"AFFINE_HULL_HALFSPACE_GT",AFFINE_HULL_HALFSPACE_GT; +"AFFINE_HULL_HALFSPACE_LE",AFFINE_HULL_HALFSPACE_LE; +"AFFINE_HULL_HALFSPACE_LT",AFFINE_HULL_HALFSPACE_LT; +"AFFINE_HULL_INDEXED",AFFINE_HULL_INDEXED; +"AFFINE_HULL_INSERT_SPAN",AFFINE_HULL_INSERT_SPAN; +"AFFINE_HULL_INSERT_SUBSET_SPAN",AFFINE_HULL_INSERT_SUBSET_SPAN; +"AFFINE_HULL_INTER",AFFINE_HULL_INTER; +"AFFINE_HULL_INTERS",AFFINE_HULL_INTERS; +"AFFINE_HULL_LINEAR_IMAGE",AFFINE_HULL_LINEAR_IMAGE; +"AFFINE_HULL_NONEMPTY_INTERIOR",AFFINE_HULL_NONEMPTY_INTERIOR; +"AFFINE_HULL_OPEN",AFFINE_HULL_OPEN; +"AFFINE_HULL_OPEN_IN",AFFINE_HULL_OPEN_IN; +"AFFINE_HULL_PCROSS",AFFINE_HULL_PCROSS; +"AFFINE_HULL_RELATIVE_INTERIOR",AFFINE_HULL_RELATIVE_INTERIOR; +"AFFINE_HULL_SEGMENT",AFFINE_HULL_SEGMENT; +"AFFINE_HULL_SING",AFFINE_HULL_SING; +"AFFINE_HULL_SPAN",AFFINE_HULL_SPAN; +"AFFINE_HULL_SUBSET_SPAN",AFFINE_HULL_SUBSET_SPAN; +"AFFINE_HULL_TRANSLATION",AFFINE_HULL_TRANSLATION; +"AFFINE_HULL_UNIV",AFFINE_HULL_UNIV; +"AFFINE_HYPERPLANE",AFFINE_HYPERPLANE; +"AFFINE_HYPERPLANE_SUMS_EQ_UNIV",AFFINE_HYPERPLANE_SUMS_EQ_UNIV; +"AFFINE_IMP_CONVEX",AFFINE_IMP_CONVEX; +"AFFINE_IMP_POLYHEDRON",AFFINE_IMP_POLYHEDRON; +"AFFINE_IMP_SUBSPACE",AFFINE_IMP_SUBSPACE; +"AFFINE_INDEPENDENT_1",AFFINE_INDEPENDENT_1; +"AFFINE_INDEPENDENT_2",AFFINE_INDEPENDENT_2; +"AFFINE_INDEPENDENT_CARD_DIM_DIFFS",AFFINE_INDEPENDENT_CARD_DIM_DIFFS; +"AFFINE_INDEPENDENT_CARD_LE",AFFINE_INDEPENDENT_CARD_LE; +"AFFINE_INDEPENDENT_CONVEX_AFFINE_HULL",AFFINE_INDEPENDENT_CONVEX_AFFINE_HULL; +"AFFINE_INDEPENDENT_DELETE",AFFINE_INDEPENDENT_DELETE; +"AFFINE_INDEPENDENT_EMPTY",AFFINE_INDEPENDENT_EMPTY; +"AFFINE_INDEPENDENT_IFF_CARD",AFFINE_INDEPENDENT_IFF_CARD; +"AFFINE_INDEPENDENT_IMP_FINITE",AFFINE_INDEPENDENT_IMP_FINITE; +"AFFINE_INDEPENDENT_INSERT",AFFINE_INDEPENDENT_INSERT; +"AFFINE_INDEPENDENT_SPAN_EQ",AFFINE_INDEPENDENT_SPAN_EQ; +"AFFINE_INDEPENDENT_SPAN_GT",AFFINE_INDEPENDENT_SPAN_GT; +"AFFINE_INDEPENDENT_STDBASIS",AFFINE_INDEPENDENT_STDBASIS; +"AFFINE_INDEPENDENT_SUBSET",AFFINE_INDEPENDENT_SUBSET; +"AFFINE_INDEXED",AFFINE_INDEXED; +"AFFINE_INTER",AFFINE_INTER; +"AFFINE_INTERS",AFFINE_INTERS; +"AFFINE_LINEAR_IMAGE",AFFINE_LINEAR_IMAGE; +"AFFINE_LINEAR_IMAGE_EQ",AFFINE_LINEAR_IMAGE_EQ; +"AFFINE_NEGATIONS",AFFINE_NEGATIONS; +"AFFINE_PARALLEL_SLICE",AFFINE_PARALLEL_SLICE; +"AFFINE_PCROSS",AFFINE_PCROSS; +"AFFINE_PCROSS_EQ",AFFINE_PCROSS_EQ; +"AFFINE_SCALING",AFFINE_SCALING; +"AFFINE_SCALING_EQ",AFFINE_SCALING_EQ; +"AFFINE_SING",AFFINE_SING; +"AFFINE_SPAN",AFFINE_SPAN; +"AFFINE_STANDARD_HYPERPLANE",AFFINE_STANDARD_HYPERPLANE; +"AFFINE_SUMS",AFFINE_SUMS; +"AFFINE_TRANSLATION",AFFINE_TRANSLATION; +"AFFINE_TRANSLATION_EQ",AFFINE_TRANSLATION_EQ; +"AFFINE_TRANSLATION_SUBSPACE",AFFINE_TRANSLATION_SUBSPACE; +"AFFINE_TRANSLATION_SUBSPACE_EXPLICIT",AFFINE_TRANSLATION_SUBSPACE_EXPLICIT; +"AFFINE_TRANSLATION_UNIQUE_SUBSPACE",AFFINE_TRANSLATION_UNIQUE_SUBSPACE; +"AFFINE_UNIV",AFFINE_UNIV; +"AFFINE_VSUM",AFFINE_VSUM; +"AFFINITY_INVERSES",AFFINITY_INVERSES; +"AFF_DIM",AFF_DIM; +"AFF_DIM_2",AFF_DIM_2; +"AFF_DIM_AFFINE_HULL",AFF_DIM_AFFINE_HULL; +"AFF_DIM_AFFINE_INDEPENDENT",AFF_DIM_AFFINE_INDEPENDENT; +"AFF_DIM_AFFINE_INTER_HYPERPLANE",AFF_DIM_AFFINE_INTER_HYPERPLANE; +"AFF_DIM_BALL",AFF_DIM_BALL; +"AFF_DIM_CBALL",AFF_DIM_CBALL; +"AFF_DIM_CLOSURE",AFF_DIM_CLOSURE; +"AFF_DIM_CONVEX_HULL",AFF_DIM_CONVEX_HULL; +"AFF_DIM_CONVEX_INTER_NONEMPTY_INTERIOR",AFF_DIM_CONVEX_INTER_NONEMPTY_INTERIOR; +"AFF_DIM_CONVEX_INTER_OPEN",AFF_DIM_CONVEX_INTER_OPEN; +"AFF_DIM_DIM_0",AFF_DIM_DIM_0; +"AFF_DIM_DIM_AFFINE_DIFFS",AFF_DIM_DIM_AFFINE_DIFFS; +"AFF_DIM_DIM_SUBSPACE",AFF_DIM_DIM_SUBSPACE; +"AFF_DIM_EMPTY",AFF_DIM_EMPTY; +"AFF_DIM_EQ_0",AFF_DIM_EQ_0; +"AFF_DIM_EQ_AFFINE_HULL",AFF_DIM_EQ_AFFINE_HULL; +"AFF_DIM_EQ_FULL",AFF_DIM_EQ_FULL; +"AFF_DIM_EQ_HYPERPLANE",AFF_DIM_EQ_HYPERPLANE; +"AFF_DIM_EQ_MINUS1",AFF_DIM_EQ_MINUS1; +"AFF_DIM_GE",AFF_DIM_GE; +"AFF_DIM_HALFSPACE_GE",AFF_DIM_HALFSPACE_GE; +"AFF_DIM_HALFSPACE_GT",AFF_DIM_HALFSPACE_GT; +"AFF_DIM_HALFSPACE_LE",AFF_DIM_HALFSPACE_LE; +"AFF_DIM_HALFSPACE_LT",AFF_DIM_HALFSPACE_LT; +"AFF_DIM_HYPERPLANE",AFF_DIM_HYPERPLANE; +"AFF_DIM_INJECTIVE_LINEAR_IMAGE",AFF_DIM_INJECTIVE_LINEAR_IMAGE; +"AFF_DIM_INSERT",AFF_DIM_INSERT; +"AFF_DIM_INTERVAL",AFF_DIM_INTERVAL; +"AFF_DIM_LE_CARD",AFF_DIM_LE_CARD; +"AFF_DIM_LE_DIM",AFF_DIM_LE_DIM; +"AFF_DIM_LE_UNIV",AFF_DIM_LE_UNIV; +"AFF_DIM_LINEAR_IMAGE_LE",AFF_DIM_LINEAR_IMAGE_LE; +"AFF_DIM_LT_FULL",AFF_DIM_LT_FULL; +"AFF_DIM_NONEMPTY_INTERIOR",AFF_DIM_NONEMPTY_INTERIOR; +"AFF_DIM_NONEMPTY_INTERIOR_EQ",AFF_DIM_NONEMPTY_INTERIOR_EQ; +"AFF_DIM_OPEN",AFF_DIM_OPEN; +"AFF_DIM_OPEN_IN",AFF_DIM_OPEN_IN; +"AFF_DIM_POS_LE",AFF_DIM_POS_LE; +"AFF_DIM_PSUBSET",AFF_DIM_PSUBSET; +"AFF_DIM_SIMPLEX",AFF_DIM_SIMPLEX; +"AFF_DIM_SING",AFF_DIM_SING; +"AFF_DIM_SUBSET",AFF_DIM_SUBSET; +"AFF_DIM_SUMS_INTER",AFF_DIM_SUMS_INTER; +"AFF_DIM_TRANSLATION_EQ",AFF_DIM_TRANSLATION_EQ; +"AFF_DIM_UNIQUE",AFF_DIM_UNIQUE; +"AFF_DIM_UNIV",AFF_DIM_UNIV; +"AFF_LOWDIM_SUBSET_HYPERPLANE",AFF_LOWDIM_SUBSET_HYPERPLANE; +"ALL",ALL; +"ALL2",ALL2; +"ALL2_ALL",ALL2_ALL; +"ALL2_AND_RIGHT",ALL2_AND_RIGHT; +"ALL2_DEF",ALL2_DEF; +"ALL2_MAP",ALL2_MAP; +"ALL2_MAP2",ALL2_MAP2; +"ALL_APPEND",ALL_APPEND; +"ALL_EL",ALL_EL; +"ALL_FILTER",ALL_FILTER; +"ALL_IMP",ALL_IMP; +"ALL_MAP",ALL_MAP; +"ALL_MEM",ALL_MEM; +"ALL_MP",ALL_MP; +"ALL_T",ALL_T; +"ALWAYS_EVENTUALLY",ALWAYS_EVENTUALLY; +"ANALYTIC_AT",ANALYTIC_AT; +"ANALYTIC_AT_ADD",ANALYTIC_AT_ADD; +"ANALYTIC_AT_BALL",ANALYTIC_AT_BALL; +"ANALYTIC_AT_MUL",ANALYTIC_AT_MUL; +"ANALYTIC_AT_POW",ANALYTIC_AT_POW; +"ANALYTIC_AT_SUB",ANALYTIC_AT_SUB; +"ANALYTIC_AT_TWO",ANALYTIC_AT_TWO; +"ANALYTIC_COMPLEX_DERIVATIVE",ANALYTIC_COMPLEX_DERIVATIVE; +"ANALYTIC_CONTINUATION",ANALYTIC_CONTINUATION; +"ANALYTIC_HIGHER_COMPLEX_DERIVATIVE",ANALYTIC_HIGHER_COMPLEX_DERIVATIVE; +"ANALYTIC_IFF_POWER_SERIES",ANALYTIC_IFF_POWER_SERIES; +"ANALYTIC_IMP_HOLOMORPHIC",ANALYTIC_IMP_HOLOMORPHIC; +"ANALYTIC_ON_ADD",ANALYTIC_ON_ADD; +"ANALYTIC_ON_ANALYTIC_AT",ANALYTIC_ON_ANALYTIC_AT; +"ANALYTIC_ON_COMPOSE",ANALYTIC_ON_COMPOSE; +"ANALYTIC_ON_COMPOSE_GEN",ANALYTIC_ON_COMPOSE_GEN; +"ANALYTIC_ON_CONST",ANALYTIC_ON_CONST; +"ANALYTIC_ON_DIV",ANALYTIC_ON_DIV; +"ANALYTIC_ON_HOLOMORPHIC",ANALYTIC_ON_HOLOMORPHIC; +"ANALYTIC_ON_ID",ANALYTIC_ON_ID; +"ANALYTIC_ON_IMP_DIFFERENTIABLE_AT",ANALYTIC_ON_IMP_DIFFERENTIABLE_AT; +"ANALYTIC_ON_INV",ANALYTIC_ON_INV; +"ANALYTIC_ON_LINEAR",ANALYTIC_ON_LINEAR; +"ANALYTIC_ON_MUL",ANALYTIC_ON_MUL; +"ANALYTIC_ON_NEG",ANALYTIC_ON_NEG; +"ANALYTIC_ON_OPEN",ANALYTIC_ON_OPEN; +"ANALYTIC_ON_POW",ANALYTIC_ON_POW; +"ANALYTIC_ON_SUB",ANALYTIC_ON_SUB; +"ANALYTIC_ON_SUBSET",ANALYTIC_ON_SUBSET; +"ANALYTIC_ON_UNION",ANALYTIC_ON_UNION; +"ANALYTIC_ON_UNIONS",ANALYTIC_ON_UNIONS; +"ANALYTIC_ON_VSUM",ANALYTIC_ON_VSUM; +"AND_ALL",AND_ALL; +"AND_ALL2",AND_ALL2; +"AND_CLAUSES",AND_CLAUSES; +"AND_DEF",AND_DEF; +"AND_FORALL_THM",AND_FORALL_THM; +"ANR_PATH_IMAGE_SIMPLE_PATH",ANR_PATH_IMAGE_SIMPLE_PATH; +"ANR_RELATIVE_FRONTIER_CONVEX",ANR_RELATIVE_FRONTIER_CONVEX; +"ANTIDERIVATIVE_CONTINUOUS",ANTIDERIVATIVE_CONTINUOUS; +"ANTIDERIVATIVE_INTEGRAL_CONTINUOUS",ANTIDERIVATIVE_INTEGRAL_CONTINUOUS; +"ANY_CLOSEST_POINT_AFFINE_ORTHOGONAL",ANY_CLOSEST_POINT_AFFINE_ORTHOGONAL; +"ANY_CLOSEST_POINT_DOT",ANY_CLOSEST_POINT_DOT; +"ANY_CLOSEST_POINT_UNIQUE",ANY_CLOSEST_POINT_UNIQUE; +"APPEND",APPEND; +"APPEND_ASSOC",APPEND_ASSOC; +"APPEND_BUTLAST_LAST",APPEND_BUTLAST_LAST; +"APPEND_EQ_NIL",APPEND_EQ_NIL; +"APPEND_NIL",APPEND_NIL; +"APPEND_SING",APPEND_SING; +"APPROACHABLE_LT_LE",APPROACHABLE_LT_LE; +"APPROXIMABLE_ON_DIVISION",APPROXIMABLE_ON_DIVISION; +"ARC_ASSOC",ARC_ASSOC; +"ARC_CONNECTED_TRANS",ARC_CONNECTED_TRANS; +"ARC_DISTINCT_ENDS",ARC_DISTINCT_ENDS; +"ARC_IMP_PATH",ARC_IMP_PATH; +"ARC_IMP_SIMPLE_PATH",ARC_IMP_SIMPLE_PATH; +"ARC_JOIN",ARC_JOIN; +"ARC_JOIN_EQ",ARC_JOIN_EQ; +"ARC_JOIN_EQ_ALT",ARC_JOIN_EQ_ALT; +"ARC_LINEAR_IMAGE_EQ",ARC_LINEAR_IMAGE_EQ; +"ARC_LINEPATH",ARC_LINEPATH; +"ARC_LINEPATH_EQ",ARC_LINEPATH_EQ; +"ARC_PARTCIRCLEPATH",ARC_PARTCIRCLEPATH; +"ARC_REVERSEPATH",ARC_REVERSEPATH; +"ARC_SIMPLE_PATH",ARC_SIMPLE_PATH; +"ARC_SIMPLE_PATH_SUBPATH",ARC_SIMPLE_PATH_SUBPATH; +"ARC_SIMPLE_PATH_SUBPATH_INTERIOR",ARC_SIMPLE_PATH_SUBPATH_INTERIOR; +"ARC_SUBPATH_ARC",ARC_SUBPATH_ARC; +"ARC_SUBPATH_EQ",ARC_SUBPATH_EQ; +"ARC_TRANSLATION_EQ",ARC_TRANSLATION_EQ; +"ARG",ARG; +"ARG_0",ARG_0; +"ARG_ATAN_UPPERHALF",ARG_ATAN_UPPERHALF; +"ARG_CEXP",ARG_CEXP; +"ARG_CLOG",ARG_CLOG; +"ARG_CNJ",ARG_CNJ; +"ARG_DIV_CX",ARG_DIV_CX; +"ARG_EQ",ARG_EQ; +"ARG_EQ_0",ARG_EQ_0; +"ARG_EQ_0_PI",ARG_EQ_0_PI; +"ARG_EQ_PI",ARG_EQ_PI; +"ARG_INV",ARG_INV; +"ARG_INV_EQ_0",ARG_INV_EQ_0; +"ARG_LE_DIV_SUM",ARG_LE_DIV_SUM; +"ARG_LE_DIV_SUM_EQ",ARG_LE_DIV_SUM_EQ; +"ARG_LE_PI",ARG_LE_PI; +"ARG_LT_NZ",ARG_LT_NZ; +"ARG_LT_PI",ARG_LT_PI; +"ARG_MUL",ARG_MUL; +"ARG_MUL_CX",ARG_MUL_CX; +"ARG_NUM",ARG_NUM; +"ARG_REAL",ARG_REAL; +"ARG_ROTATE2D",ARG_ROTATE2D; +"ARG_ROTATE2D_UNIQUE",ARG_ROTATE2D_UNIQUE; +"ARG_ROTATE2D_UNIQUE_2PI",ARG_ROTATE2D_UNIQUE_2PI; +"ARG_UNIQUE",ARG_UNIQUE; +"ARITH",ARITH; +"ARITH_ADD",ARITH_ADD; +"ARITH_EQ",ARITH_EQ; +"ARITH_EVEN",ARITH_EVEN; +"ARITH_EXP",ARITH_EXP; +"ARITH_GE",ARITH_GE; +"ARITH_GT",ARITH_GT; +"ARITH_LE",ARITH_LE; +"ARITH_LT",ARITH_LT; +"ARITH_MULT",ARITH_MULT; +"ARITH_ODD",ARITH_ODD; +"ARITH_PRE",ARITH_PRE; +"ARITH_SUB",ARITH_SUB; +"ARITH_SUC",ARITH_SUC; +"ARITH_ZERO",ARITH_ZERO; +"ARZELA_ASCOLI",ARZELA_ASCOLI; +"ASN_0",ASN_0; +"ASN_1",ASN_1; +"ASN_ACS",ASN_ACS; +"ASN_ACS_SQRT_NEG",ASN_ACS_SQRT_NEG; +"ASN_ACS_SQRT_POS",ASN_ACS_SQRT_POS; +"ASN_ATN",ASN_ATN; +"ASN_BOUNDS",ASN_BOUNDS; +"ASN_BOUNDS_LT",ASN_BOUNDS_LT; +"ASN_MONO_LE",ASN_MONO_LE; +"ASN_MONO_LE_EQ",ASN_MONO_LE_EQ; +"ASN_MONO_LT",ASN_MONO_LT; +"ASN_MONO_LT_EQ",ASN_MONO_LT_EQ; +"ASN_NEG",ASN_NEG; +"ASN_NEG_1",ASN_NEG_1; +"ASN_PLUS_ACS",ASN_PLUS_ACS; +"ASN_SIN",ASN_SIN; +"ASSOC",ASSOC; +"AT",AT; +"ATN_0",ATN_0; +"ATN_1",ATN_1; +"ATN_ABS_LE_X",ATN_ABS_LE_X; +"ATN_BOUND",ATN_BOUND; +"ATN_BOUNDS",ATN_BOUNDS; +"ATN_INJ",ATN_INJ; +"ATN_LE_PI4",ATN_LE_PI4; +"ATN_LE_X",ATN_LE_X; +"ATN_LT_PI4",ATN_LT_PI4; +"ATN_LT_PI4_NEG",ATN_LT_PI4_NEG; +"ATN_LT_PI4_POS",ATN_LT_PI4_POS; +"ATN_MONO_LE_EQ",ATN_MONO_LE_EQ; +"ATN_MONO_LT",ATN_MONO_LT; +"ATN_MONO_LT_EQ",ATN_MONO_LT_EQ; +"ATN_NEG",ATN_NEG; +"ATN_POS_LE",ATN_POS_LE; +"ATN_POS_LT",ATN_POS_LT; +"ATN_TAN",ATN_TAN; +"ATREAL",ATREAL; +"AT_INFINITY",AT_INFINITY; +"AT_NEGINFINITY",AT_NEGINFINITY; +"AT_POSINFINITY",AT_POSINFINITY; +"AUSTIN_LEMMA",AUSTIN_LEMMA; +"Arg_DEF",Arg_DEF; +"BABY_SARD",BABY_SARD; +"BALL_1",BALL_1; +"BALL_BIHOLOMORPHISM_EXISTS",BALL_BIHOLOMORPHISM_EXISTS; +"BALL_BIHOLOMORPHISM_MOEBIUS_FUNCTION",BALL_BIHOLOMORPHISM_MOEBIUS_FUNCTION; +"BALL_EMPTY",BALL_EMPTY; +"BALL_EQ_EMPTY",BALL_EQ_EMPTY; +"BALL_INTERVAL",BALL_INTERVAL; +"BALL_INTERVAL_0",BALL_INTERVAL_0; +"BALL_LINEAR_IMAGE",BALL_LINEAR_IMAGE; +"BALL_MAX_UNION",BALL_MAX_UNION; +"BALL_MIN_INTER",BALL_MIN_INTER; +"BALL_SCALING",BALL_SCALING; +"BALL_SUBSET_CBALL",BALL_SUBSET_CBALL; +"BALL_SUBSET_OPEN_MAP_IMAGE",BALL_SUBSET_OPEN_MAP_IMAGE; +"BALL_TRANSLATION",BALL_TRANSLATION; +"BALL_TRIVIAL",BALL_TRIVIAL; +"BALL_UNION_SPHERE",BALL_UNION_SPHERE; +"BANACH_FIX",BANACH_FIX; +"BASIS_CARD_EQ_DIM",BASIS_CARD_EQ_DIM; +"BASIS_COMPONENT",BASIS_COMPONENT; +"BASIS_COORDINATES_CONTINUOUS",BASIS_COORDINATES_CONTINUOUS; +"BASIS_COORDINATES_LIPSCHITZ",BASIS_COORDINATES_LIPSCHITZ; +"BASIS_EQ_0",BASIS_EQ_0; +"BASIS_EXISTS",BASIS_EXISTS; +"BASIS_EXISTS_FINITE",BASIS_EXISTS_FINITE; +"BASIS_EXPANSION",BASIS_EXPANSION; +"BASIS_EXPANSION_UNIQUE",BASIS_EXPANSION_UNIQUE; +"BASIS_HAS_SIZE_DIM",BASIS_HAS_SIZE_DIM; +"BASIS_HAS_SIZE_UNIV",BASIS_HAS_SIZE_UNIV; +"BASIS_INJ",BASIS_INJ; +"BASIS_INJ_EQ",BASIS_INJ_EQ; +"BASIS_NE",BASIS_NE; +"BASIS_NONZERO",BASIS_NONZERO; +"BASIS_ORTHOGONAL",BASIS_ORTHOGONAL; +"BASIS_SUBSPACE_EXISTS",BASIS_SUBSPACE_EXISTS; +"BEPPO_LEVI_DECREASING",BEPPO_LEVI_DECREASING; +"BEPPO_LEVI_INCREASING",BEPPO_LEVI_INCREASING; +"BEPPO_LEVI_MONOTONE_CONVERGENCE_DECREASING",BEPPO_LEVI_MONOTONE_CONVERGENCE_DECREASING; +"BEPPO_LEVI_MONOTONE_CONVERGENCE_INCREASING",BEPPO_LEVI_MONOTONE_CONVERGENCE_INCREASING; +"BERNSTEIN_LEMMA",BERNSTEIN_LEMMA; +"BERNSTEIN_POS",BERNSTEIN_POS; +"BERNSTEIN_WEIERSTRASS",BERNSTEIN_WEIERSTRASS; +"BESSEL_INEQUALITY",BESSEL_INEQUALITY; +"BETA_THM",BETA_THM; +"BETWEEN_ANTISYM",BETWEEN_ANTISYM; +"BETWEEN_COLLINEAR_DIST_EQ",BETWEEN_COLLINEAR_DIST_EQ; +"BETWEEN_DIST_LE",BETWEEN_DIST_LE; +"BETWEEN_DIST_LT",BETWEEN_DIST_LT; +"BETWEEN_DOT",BETWEEN_DOT; +"BETWEEN_EXISTS_EXTENSION",BETWEEN_EXISTS_EXTENSION; +"BETWEEN_IMP_COLLINEAR",BETWEEN_IMP_COLLINEAR; +"BETWEEN_IN_CONVEX_HULL",BETWEEN_IN_CONVEX_HULL; +"BETWEEN_IN_SEGMENT",BETWEEN_IN_SEGMENT; +"BETWEEN_LINEAR_IMAGE_EQ",BETWEEN_LINEAR_IMAGE_EQ; +"BETWEEN_MIDPOINT",BETWEEN_MIDPOINT; +"BETWEEN_NORM",BETWEEN_NORM; +"BETWEEN_NORM_LE",BETWEEN_NORM_LE; +"BETWEEN_NORM_LT",BETWEEN_NORM_LT; +"BETWEEN_REFL",BETWEEN_REFL; +"BETWEEN_REFL_EQ",BETWEEN_REFL_EQ; +"BETWEEN_SYM",BETWEEN_SYM; +"BETWEEN_TRANS",BETWEEN_TRANS; +"BETWEEN_TRANSLATION",BETWEEN_TRANSLATION; +"BETWEEN_TRANS_2",BETWEEN_TRANS_2; +"BIJ",BIJ; +"BIJECTIONS_CARD_EQ",BIJECTIONS_CARD_EQ; +"BIJECTIONS_HAS_SIZE",BIJECTIONS_HAS_SIZE; +"BIJECTIONS_HAS_SIZE_EQ",BIJECTIONS_HAS_SIZE_EQ; +"BIJECTIVE_INJECTIVE_SURJECTIVE",BIJECTIVE_INJECTIVE_SURJECTIVE; +"BIJECTIVE_INVERSES",BIJECTIVE_INVERSES; +"BIJECTIVE_LEFT_RIGHT_INVERSE",BIJECTIVE_LEFT_RIGHT_INVERSE; +"BIJECTIVE_ON_LEFT_RIGHT_INVERSE",BIJECTIVE_ON_LEFT_RIGHT_INVERSE; +"BILINEAR_BOUNDED",BILINEAR_BOUNDED; +"BILINEAR_BOUNDED_POS",BILINEAR_BOUNDED_POS; +"BILINEAR_COMPLEX_MUL",BILINEAR_COMPLEX_MUL; +"BILINEAR_CONTINUOUS_COMPOSE",BILINEAR_CONTINUOUS_COMPOSE; +"BILINEAR_CONTINUOUS_ON_COMPOSE",BILINEAR_CONTINUOUS_ON_COMPOSE; +"BILINEAR_DIFFERENTIABLE_AT_COMPOSE",BILINEAR_DIFFERENTIABLE_AT_COMPOSE; +"BILINEAR_DIFFERENTIABLE_ON_COMPOSE",BILINEAR_DIFFERENTIABLE_ON_COMPOSE; +"BILINEAR_DIFFERENTIABLE_WITHIN_COMPOSE",BILINEAR_DIFFERENTIABLE_WITHIN_COMPOSE; +"BILINEAR_DOT",BILINEAR_DOT; +"BILINEAR_DROP_MUL",BILINEAR_DROP_MUL; +"BILINEAR_EQ",BILINEAR_EQ; +"BILINEAR_EQ_MBASIS",BILINEAR_EQ_MBASIS; +"BILINEAR_EQ_STDBASIS",BILINEAR_EQ_STDBASIS; +"BILINEAR_GEOM",BILINEAR_GEOM; +"BILINEAR_INNER",BILINEAR_INNER; +"BILINEAR_LADD",BILINEAR_LADD; +"BILINEAR_LMUL",BILINEAR_LMUL; +"BILINEAR_LNEG",BILINEAR_LNEG; +"BILINEAR_LSUB",BILINEAR_LSUB; +"BILINEAR_LZERO",BILINEAR_LZERO; +"BILINEAR_OUTER",BILINEAR_OUTER; +"BILINEAR_PRODUCT",BILINEAR_PRODUCT; +"BILINEAR_RADD",BILINEAR_RADD; +"BILINEAR_RMUL",BILINEAR_RMUL; +"BILINEAR_RNEG",BILINEAR_RNEG; +"BILINEAR_RSUB",BILINEAR_RSUB; +"BILINEAR_RZERO",BILINEAR_RZERO; +"BILINEAR_UNIFORMLY_CONTINUOUS_ON_COMPOSE",BILINEAR_UNIFORMLY_CONTINUOUS_ON_COMPOSE; +"BILINEAR_VSUM",BILINEAR_VSUM; +"BILINEAR_VSUM_PARTIAL_PRE",BILINEAR_VSUM_PARTIAL_PRE; +"BILINEAR_VSUM_PARTIAL_SUC",BILINEAR_VSUM_PARTIAL_SUC; +"BINARYSUM_BITSET",BINARYSUM_BITSET; +"BINARYSUM_BOUND",BINARYSUM_BOUND; +"BINARYSUM_BOUND_EQ",BINARYSUM_BOUND_EQ; +"BINARYSUM_BOUND_LEMMA",BINARYSUM_BOUND_LEMMA; +"BINARYSUM_DIV",BINARYSUM_DIV; +"BINARYSUM_DIV_DIVISIBLE",BINARYSUM_DIV_DIVISIBLE; +"BINARY_INDUCT",BINARY_INDUCT; +"BINOM",BINOM; +"BINOMIAL_THEOREM",BINOMIAL_THEOREM; +"BINOM_1",BINOM_1; +"BINOM_BOTH_STEP",BINOM_BOTH_STEP; +"BINOM_BOTH_STEP_DOWN",BINOM_BOTH_STEP_DOWN; +"BINOM_BOTH_STEP_REAL",BINOM_BOTH_STEP_REAL; +"BINOM_BOTTOM_STEP",BINOM_BOTTOM_STEP; +"BINOM_BOTTOM_STEP_REAL",BINOM_BOTTOM_STEP_REAL; +"BINOM_EQ_0",BINOM_EQ_0; +"BINOM_FACT",BINOM_FACT; +"BINOM_LT",BINOM_LT; +"BINOM_PENULT",BINOM_PENULT; +"BINOM_REFL",BINOM_REFL; +"BINOM_TOP_STEP",BINOM_TOP_STEP; +"BINOM_TOP_STEP_REAL",BINOM_TOP_STEP_REAL; +"BIT0",BIT0; +"BIT0_DEF",BIT0_DEF; +"BIT0_THM",BIT0_THM; +"BIT1",BIT1; +"BIT1_DEF",BIT1_DEF; +"BIT1_THM",BIT1_THM; +"BITSET_0",BITSET_0; +"BITSET_BINARYSUM",BITSET_BINARYSUM; +"BITSET_BOUND",BITSET_BOUND; +"BITSET_BOUND_EQ",BITSET_BOUND_EQ; +"BITSET_BOUND_LEMMA",BITSET_BOUND_LEMMA; +"BITSET_BOUND_WEAK",BITSET_BOUND_WEAK; +"BITSET_EQ",BITSET_EQ; +"BITSET_EQ_EMPTY",BITSET_EQ_EMPTY; +"BITSET_STEP",BITSET_STEP; +"BLOCH",BLOCH; +"BLOCH_COROLLARY",BLOCH_COROLLARY; +"BLOCH_LEMMA",BLOCH_LEMMA; +"BLOCH_UNIT",BLOCH_UNIT; +"BOLZANO_WEIERSTRASS",BOLZANO_WEIERSTRASS; +"BOLZANO_WEIERSTRASS_CONTRAPOS",BOLZANO_WEIERSTRASS_CONTRAPOS; +"BOLZANO_WEIERSTRASS_IMP_BOUNDED",BOLZANO_WEIERSTRASS_IMP_BOUNDED; +"BOLZANO_WEIERSTRASS_IMP_CLOSED",BOLZANO_WEIERSTRASS_IMP_CLOSED; +"BOOL_CASES_AX",BOOL_CASES_AX; +"BORSUK_HOMOTOPY_EXTENSION",BORSUK_HOMOTOPY_EXTENSION; +"BORSUK_MAPS_HOMOTOPIC_IN_CONNECTED_COMPONENT_EQ",BORSUK_MAPS_HOMOTOPIC_IN_CONNECTED_COMPONENT_EQ; +"BORSUK_MAPS_HOMOTOPIC_IN_PATH_COMPONENT",BORSUK_MAPS_HOMOTOPIC_IN_PATH_COMPONENT; +"BORSUK_MAP_ESSENTIAL_BOUNDED_COMPONENT",BORSUK_MAP_ESSENTIAL_BOUNDED_COMPONENT; +"BORSUK_MAP_INTO_SPHERE",BORSUK_MAP_INTO_SPHERE; +"BORSUK_SEPARATION_THEOREM",BORSUK_SEPARATION_THEOREM; +"BORSUK_SEPARATION_THEOREM_GEN",BORSUK_SEPARATION_THEOREM_GEN; +"BOTTOM",BOTTOM; +"BOUNDED_ARC_IMAGE",BOUNDED_ARC_IMAGE; +"BOUNDED_BALL",BOUNDED_BALL; +"BOUNDED_CBALL",BOUNDED_CBALL; +"BOUNDED_CLOSED_CHAIN",BOUNDED_CLOSED_CHAIN; +"BOUNDED_CLOSED_IMP_COMPACT",BOUNDED_CLOSED_IMP_COMPACT; +"BOUNDED_CLOSED_INTERVAL",BOUNDED_CLOSED_INTERVAL; +"BOUNDED_CLOSED_NEST",BOUNDED_CLOSED_NEST; +"BOUNDED_CLOSURE",BOUNDED_CLOSURE; +"BOUNDED_CLOSURE_EQ",BOUNDED_CLOSURE_EQ; +"BOUNDED_COMPONENTWISE",BOUNDED_COMPONENTWISE; +"BOUNDED_CONVEX_HULL",BOUNDED_CONVEX_HULL; +"BOUNDED_CONVEX_HULL_EQ",BOUNDED_CONVEX_HULL_EQ; +"BOUNDED_DECREASING_CONVERGENT",BOUNDED_DECREASING_CONVERGENT; +"BOUNDED_DIFF",BOUNDED_DIFF; +"BOUNDED_DIFFS",BOUNDED_DIFFS; +"BOUNDED_EMPTY",BOUNDED_EMPTY; +"BOUNDED_EQUIINTEGRAL_OVER_THIN_TAGGED_PARTIAL_DIVISION",BOUNDED_EQUIINTEGRAL_OVER_THIN_TAGGED_PARTIAL_DIVISION; +"BOUNDED_FINITE",BOUNDED_FINITE; +"BOUNDED_FRONTIER",BOUNDED_FRONTIER; +"BOUNDED_FUNCTIONS_BIJECTIONS_1",BOUNDED_FUNCTIONS_BIJECTIONS_1; +"BOUNDED_FUNCTIONS_BIJECTIONS_2",BOUNDED_FUNCTIONS_BIJECTIONS_2; +"BOUNDED_HALFSPACE_GE",BOUNDED_HALFSPACE_GE; +"BOUNDED_HALFSPACE_GT",BOUNDED_HALFSPACE_GT; +"BOUNDED_HALFSPACE_LE",BOUNDED_HALFSPACE_LE; +"BOUNDED_HALFSPACE_LT",BOUNDED_HALFSPACE_LT; +"BOUNDED_HAS_INF",BOUNDED_HAS_INF; +"BOUNDED_HAS_SUP",BOUNDED_HAS_SUP; +"BOUNDED_HYPERPLANE_EQ_TRIVIAL",BOUNDED_HYPERPLANE_EQ_TRIVIAL; +"BOUNDED_INCREASING_CONVERGENT",BOUNDED_INCREASING_CONVERGENT; +"BOUNDED_INSERT",BOUNDED_INSERT; +"BOUNDED_INSIDE",BOUNDED_INSIDE; +"BOUNDED_INTER",BOUNDED_INTER; +"BOUNDED_INTERIOR",BOUNDED_INTERIOR; +"BOUNDED_INTERS",BOUNDED_INTERS; +"BOUNDED_INTERVAL",BOUNDED_INTERVAL; +"BOUNDED_LIFT",BOUNDED_LIFT; +"BOUNDED_LINEAR_IMAGE",BOUNDED_LINEAR_IMAGE; +"BOUNDED_LINEAR_IMAGE_EQ",BOUNDED_LINEAR_IMAGE_EQ; +"BOUNDED_NEGATIONS",BOUNDED_NEGATIONS; +"BOUNDED_PARTIAL_REAL_SUMS",BOUNDED_PARTIAL_REAL_SUMS; +"BOUNDED_PARTIAL_SUMS",BOUNDED_PARTIAL_SUMS; +"BOUNDED_PATH_IMAGE",BOUNDED_PATH_IMAGE; +"BOUNDED_PCROSS",BOUNDED_PCROSS; +"BOUNDED_PCROSS_EQ",BOUNDED_PCROSS_EQ; +"BOUNDED_POS",BOUNDED_POS; +"BOUNDED_POS_LT",BOUNDED_POS_LT; +"BOUNDED_RECTIFIABLE_PATH_IMAGE",BOUNDED_RECTIFIABLE_PATH_IMAGE; +"BOUNDED_RELATIVE_FRONTIER",BOUNDED_RELATIVE_FRONTIER; +"BOUNDED_SCALING",BOUNDED_SCALING; +"BOUNDED_SEGMENT",BOUNDED_SEGMENT; +"BOUNDED_SETVARIATION_ABSOLUTELY_INTEGRABLE",BOUNDED_SETVARIATION_ABSOLUTELY_INTEGRABLE; +"BOUNDED_SETVARIATION_ABSOLUTELY_INTEGRABLE_INTERVAL",BOUNDED_SETVARIATION_ABSOLUTELY_INTEGRABLE_INTERVAL; +"BOUNDED_SIMPLE_PATH_IMAGE",BOUNDED_SIMPLE_PATH_IMAGE; +"BOUNDED_SING",BOUNDED_SING; +"BOUNDED_SLICE",BOUNDED_SLICE; +"BOUNDED_SPHERE",BOUNDED_SPHERE; +"BOUNDED_SUBSET",BOUNDED_SUBSET; +"BOUNDED_SUBSET_BALL",BOUNDED_SUBSET_BALL; +"BOUNDED_SUBSET_CBALL",BOUNDED_SUBSET_CBALL; +"BOUNDED_SUBSET_CLOSED_INTERVAL",BOUNDED_SUBSET_CLOSED_INTERVAL; +"BOUNDED_SUBSET_CLOSED_INTERVAL_SYMMETRIC",BOUNDED_SUBSET_CLOSED_INTERVAL_SYMMETRIC; +"BOUNDED_SUBSET_OPEN_INTERVAL",BOUNDED_SUBSET_OPEN_INTERVAL; +"BOUNDED_SUBSET_OPEN_INTERVAL_SYMMETRIC",BOUNDED_SUBSET_OPEN_INTERVAL_SYMMETRIC; +"BOUNDED_SUMS",BOUNDED_SUMS; +"BOUNDED_SUMS_IMAGE",BOUNDED_SUMS_IMAGE; +"BOUNDED_SUMS_IMAGES",BOUNDED_SUMS_IMAGES; +"BOUNDED_TRANSLATION",BOUNDED_TRANSLATION; +"BOUNDED_TRANSLATION_EQ",BOUNDED_TRANSLATION_EQ; +"BOUNDED_UNIFORMLY_CONTINUOUS_IMAGE",BOUNDED_UNIFORMLY_CONTINUOUS_IMAGE; +"BOUNDED_UNION",BOUNDED_UNION; +"BOUNDED_UNIONS",BOUNDED_UNIONS; +"BOUNDED_UNIQUE_OUTSIDE",BOUNDED_UNIQUE_OUTSIDE; +"BOUNDED_VALID_PATH_IMAGE",BOUNDED_VALID_PATH_IMAGE; +"BOUNDS_DIVIDED",BOUNDS_DIVIDED; +"BOUNDS_IGNORE",BOUNDS_IGNORE; +"BOUNDS_LINEAR",BOUNDS_LINEAR; +"BOUNDS_LINEAR_0",BOUNDS_LINEAR_0; +"BOUNDS_NOTZERO",BOUNDS_NOTZERO; +"BROUWER",BROUWER; +"BROUWER_BALL",BROUWER_BALL; +"BROUWER_COMPACTNESS_LEMMA",BROUWER_COMPACTNESS_LEMMA; +"BROUWER_CONTRACTIBLE_ANR",BROUWER_CONTRACTIBLE_ANR; +"BROUWER_CUBE",BROUWER_CUBE; +"BROUWER_INESSENTIAL_ANR",BROUWER_INESSENTIAL_ANR; +"BROUWER_REDUCTION_THEOREM",BROUWER_REDUCTION_THEOREM; +"BROUWER_REDUCTION_THEOREM_GEN",BROUWER_REDUCTION_THEOREM_GEN; +"BROUWER_SURJECTIVE",BROUWER_SURJECTIVE; +"BROUWER_SURJECTIVE_CBALL",BROUWER_SURJECTIVE_CBALL; +"BROUWER_WEAK",BROUWER_WEAK; +"BUTLAST",BUTLAST; +"CACS_0",CACS_0; +"CACS_1",CACS_1; +"CACS_BODY_LEMMA",CACS_BODY_LEMMA; +"CACS_BOUNDS",CACS_BOUNDS; +"CACS_CASN_SQRT_POS",CACS_CASN_SQRT_POS; +"CACS_CCOS",CACS_CCOS; +"CACS_NEG_1",CACS_NEG_1; +"CACS_RANGE_LEMMA",CACS_RANGE_LEMMA; +"CACS_UNIQUE",CACS_UNIQUE; +"CANTOR_THM",CANTOR_THM; +"CANTOR_THM_UNIV",CANTOR_THM_UNIV; +"CARATHEODORY",CARATHEODORY; +"CARATHEODORY_AFF_DIM",CARATHEODORY_AFF_DIM; +"CARD",CARD; +"CARD_ADD2_ABSORB_LE",CARD_ADD2_ABSORB_LE; +"CARD_ADD2_ABSORB_LT",CARD_ADD2_ABSORB_LT; +"CARD_ADD_ABSORB",CARD_ADD_ABSORB; +"CARD_ADD_ABSORB_LE",CARD_ADD_ABSORB_LE; +"CARD_ADD_ASSOC",CARD_ADD_ASSOC; +"CARD_ADD_C",CARD_ADD_C; +"CARD_ADD_CONG",CARD_ADD_CONG; +"CARD_ADD_FINITE",CARD_ADD_FINITE; +"CARD_ADD_FINITE_EQ",CARD_ADD_FINITE_EQ; +"CARD_ADD_LE_MUL_INFINITE",CARD_ADD_LE_MUL_INFINITE; +"CARD_ADD_SYM",CARD_ADD_SYM; +"CARD_ADD_SYMDIFF_INTER",CARD_ADD_SYMDIFF_INTER; +"CARD_BOOL",CARD_BOOL; +"CARD_CART_UNIV",CARD_CART_UNIV; +"CARD_CLAUSES",CARD_CLAUSES; +"CARD_COMPLEX_ROOTS_UNITY",CARD_COMPLEX_ROOTS_UNITY; +"CARD_COUNTABLE_CONG",CARD_COUNTABLE_CONG; +"CARD_CROSS",CARD_CROSS; +"CARD_DELETE",CARD_DELETE; +"CARD_DIFF",CARD_DIFF; +"CARD_DIFF_INTER",CARD_DIFF_INTER; +"CARD_DISJOINT_UNION",CARD_DISJOINT_UNION; +"CARD_EQ_0",CARD_EQ_0; +"CARD_EQ_ARC_IMAGE",CARD_EQ_ARC_IMAGE; +"CARD_EQ_BALL",CARD_EQ_BALL; +"CARD_EQ_BIJECTION",CARD_EQ_BIJECTION; +"CARD_EQ_BIJECTIONS",CARD_EQ_BIJECTIONS; +"CARD_EQ_CARD",CARD_EQ_CARD; +"CARD_EQ_CARD_IMP",CARD_EQ_CARD_IMP; +"CARD_EQ_CART",CARD_EQ_CART; +"CARD_EQ_CBALL",CARD_EQ_CBALL; +"CARD_EQ_CLOSED",CARD_EQ_CLOSED; +"CARD_EQ_CLOSED_SETS",CARD_EQ_CLOSED_SETS; +"CARD_EQ_COMPACT_SETS",CARD_EQ_COMPACT_SETS; +"CARD_EQ_CONDENSATION_POINTS",CARD_EQ_CONDENSATION_POINTS; +"CARD_EQ_CONDENSATION_POINTS_IN_SET",CARD_EQ_CONDENSATION_POINTS_IN_SET; +"CARD_EQ_CONG",CARD_EQ_CONG; +"CARD_EQ_CONNECTED",CARD_EQ_CONNECTED; +"CARD_EQ_CONVEX",CARD_EQ_CONVEX; +"CARD_EQ_COUNTABLE",CARD_EQ_COUNTABLE; +"CARD_EQ_COUNTABLE_SUBSETS_REAL",CARD_EQ_COUNTABLE_SUBSETS_REAL; +"CARD_EQ_COVERING_MAP_FIBRES",CARD_EQ_COVERING_MAP_FIBRES; +"CARD_EQ_DIM",CARD_EQ_DIM; +"CARD_EQ_EMPTY",CARD_EQ_EMPTY; +"CARD_EQ_EUCLIDEAN",CARD_EQ_EUCLIDEAN; +"CARD_EQ_FINITE",CARD_EQ_FINITE; +"CARD_EQ_FINITE_SUBSETS",CARD_EQ_FINITE_SUBSETS; +"CARD_EQ_IMAGE",CARD_EQ_IMAGE; +"CARD_EQ_IMP_LE",CARD_EQ_IMP_LE; +"CARD_EQ_INTEGER",CARD_EQ_INTEGER; +"CARD_EQ_INTERVAL",CARD_EQ_INTERVAL; +"CARD_EQ_LIST",CARD_EQ_LIST; +"CARD_EQ_LIST_GEN",CARD_EQ_LIST_GEN; +"CARD_EQ_NONEMPTY_INTERIOR",CARD_EQ_NONEMPTY_INTERIOR; +"CARD_EQ_NSUM",CARD_EQ_NSUM; +"CARD_EQ_OPEN",CARD_EQ_OPEN; +"CARD_EQ_OPEN_IN",CARD_EQ_OPEN_IN; +"CARD_EQ_OPEN_IN_AFFINE",CARD_EQ_OPEN_IN_AFFINE; +"CARD_EQ_OPEN_SETS",CARD_EQ_OPEN_SETS; +"CARD_EQ_PATH_CONNECTED",CARD_EQ_PATH_CONNECTED; +"CARD_EQ_PCROSS",CARD_EQ_PCROSS; +"CARD_EQ_RATIONAL",CARD_EQ_RATIONAL; +"CARD_EQ_REAL",CARD_EQ_REAL; +"CARD_EQ_REAL_IMP_UNCOUNTABLE",CARD_EQ_REAL_IMP_UNCOUNTABLE; +"CARD_EQ_REAL_SEQUENCES",CARD_EQ_REAL_SEQUENCES; +"CARD_EQ_REFL",CARD_EQ_REFL; +"CARD_EQ_SEGMENT",CARD_EQ_SEGMENT; +"CARD_EQ_SIMPLE_PATH_IMAGE",CARD_EQ_SIMPLE_PATH_IMAGE; +"CARD_EQ_SPHERE",CARD_EQ_SPHERE; +"CARD_EQ_SUM",CARD_EQ_SUM; +"CARD_EQ_SYM",CARD_EQ_SYM; +"CARD_EQ_TRANS",CARD_EQ_TRANS; +"CARD_FACES_OF_SIMPLEX",CARD_FACES_OF_SIMPLEX; +"CARD_FINITE_CONG",CARD_FINITE_CONG; +"CARD_FINITE_IMAGE",CARD_FINITE_IMAGE; +"CARD_FUNSPACE",CARD_FUNSPACE; +"CARD_FUNSPACE_CONG",CARD_FUNSPACE_CONG; +"CARD_FUNSPACE_CURRY",CARD_FUNSPACE_CURRY; +"CARD_FUNSPACE_LE",CARD_FUNSPACE_LE; +"CARD_FUNSPACE_UNIV",CARD_FUNSPACE_UNIV; +"CARD_GE_DIM_INDEPENDENT",CARD_GE_DIM_INDEPENDENT; +"CARD_HAS_SIZE_CONG",CARD_HAS_SIZE_CONG; +"CARD_IMAGE_EQ_INJ",CARD_IMAGE_EQ_INJ; +"CARD_IMAGE_INJ",CARD_IMAGE_INJ; +"CARD_IMAGE_INJ_EQ",CARD_IMAGE_INJ_EQ; +"CARD_IMAGE_LE",CARD_IMAGE_LE; +"CARD_INFINITE_CONG",CARD_INFINITE_CONG; +"CARD_INTSEG_INT",CARD_INTSEG_INT; +"CARD_LDISTRIB",CARD_LDISTRIB; +"CARD_LET_TOTAL",CARD_LET_TOTAL; +"CARD_LET_TRANS",CARD_LET_TRANS; +"CARD_LE_ADD",CARD_LE_ADD; +"CARD_LE_ADDL",CARD_LE_ADDL; +"CARD_LE_ADDR",CARD_LE_ADDR; +"CARD_LE_ANTISYM",CARD_LE_ANTISYM; +"CARD_LE_CARD",CARD_LE_CARD; +"CARD_LE_CARD_IMP",CARD_LE_CARD_IMP; +"CARD_LE_CONG",CARD_LE_CONG; +"CARD_LE_COUNTABLE",CARD_LE_COUNTABLE; +"CARD_LE_COUNTABLE_SUBSETS",CARD_LE_COUNTABLE_SUBSETS; +"CARD_LE_DIM_SPANNING",CARD_LE_DIM_SPANNING; +"CARD_LE_EMPTY",CARD_LE_EMPTY; +"CARD_LE_EQ_SUBSET",CARD_LE_EQ_SUBSET; +"CARD_LE_FINITE",CARD_LE_FINITE; +"CARD_LE_FINITE_SUBSETS",CARD_LE_FINITE_SUBSETS; +"CARD_LE_IMAGE",CARD_LE_IMAGE; +"CARD_LE_IMAGE_GEN",CARD_LE_IMAGE_GEN; +"CARD_LE_INFINITE",CARD_LE_INFINITE; +"CARD_LE_INJ",CARD_LE_INJ; +"CARD_LE_LIST",CARD_LE_LIST; +"CARD_LE_LT",CARD_LE_LT; +"CARD_LE_MUL",CARD_LE_MUL; +"CARD_LE_POWERSET",CARD_LE_POWERSET; +"CARD_LE_REFL",CARD_LE_REFL; +"CARD_LE_RELATIONAL",CARD_LE_RELATIONAL; +"CARD_LE_SQUARE",CARD_LE_SQUARE; +"CARD_LE_SUBPOWERSET",CARD_LE_SUBPOWERSET; +"CARD_LE_SUBSET",CARD_LE_SUBSET; +"CARD_LE_TOTAL",CARD_LE_TOTAL; +"CARD_LE_TRANS",CARD_LE_TRANS; +"CARD_LE_UNIV",CARD_LE_UNIV; +"CARD_LTE_TOTAL",CARD_LTE_TOTAL; +"CARD_LTE_TRANS",CARD_LTE_TRANS; +"CARD_LT_ADD",CARD_LT_ADD; +"CARD_LT_CARD",CARD_LT_CARD; +"CARD_LT_CONG",CARD_LT_CONG; +"CARD_LT_FINITE_INFINITE",CARD_LT_FINITE_INFINITE; +"CARD_LT_IMP_DISCONNECTED",CARD_LT_IMP_DISCONNECTED; +"CARD_LT_IMP_LE",CARD_LT_IMP_LE; +"CARD_LT_LE",CARD_LT_LE; +"CARD_LT_REFL",CARD_LT_REFL; +"CARD_LT_TOTAL",CARD_LT_TOTAL; +"CARD_LT_TRANS",CARD_LT_TRANS; +"CARD_MUL2_ABSORB_LE",CARD_MUL2_ABSORB_LE; +"CARD_MUL_ABSORB",CARD_MUL_ABSORB; +"CARD_MUL_ABSORB_LE",CARD_MUL_ABSORB_LE; +"CARD_MUL_ASSOC",CARD_MUL_ASSOC; +"CARD_MUL_CONG",CARD_MUL_CONG; +"CARD_MUL_FINITE",CARD_MUL_FINITE; +"CARD_MUL_LT_INFINITE",CARD_MUL_LT_INFINITE; +"CARD_MUL_LT_LEMMA",CARD_MUL_LT_LEMMA; +"CARD_MUL_SYM",CARD_MUL_SYM; +"CARD_NOT_LE",CARD_NOT_LE; +"CARD_NOT_LT",CARD_NOT_LT; +"CARD_NUMSEG",CARD_NUMSEG; +"CARD_NUMSEG_1",CARD_NUMSEG_1; +"CARD_NUMSEG_LE",CARD_NUMSEG_LE; +"CARD_NUMSEG_LEMMA",CARD_NUMSEG_LEMMA; +"CARD_NUMSEG_LT",CARD_NUMSEG_LT; +"CARD_PERMUTATIONS",CARD_PERMUTATIONS; +"CARD_POWERSET",CARD_POWERSET; +"CARD_PRODUCT",CARD_PRODUCT; +"CARD_PSUBSET",CARD_PSUBSET; +"CARD_RDISTRIB",CARD_RDISTRIB; +"CARD_SET_OF_LIST_LE",CARD_SET_OF_LIST_LE; +"CARD_SING",CARD_SING; +"CARD_SQUARE_INFINITE",CARD_SQUARE_INFINITE; +"CARD_SQUARE_NUM",CARD_SQUARE_NUM; +"CARD_STDBASIS",CARD_STDBASIS; +"CARD_SUBSET",CARD_SUBSET; +"CARD_SUBSET_EQ",CARD_SUBSET_EQ; +"CARD_SUBSET_IMAGE",CARD_SUBSET_IMAGE; +"CARD_SUBSET_LE",CARD_SUBSET_LE; +"CARD_UNION",CARD_UNION; +"CARD_UNIONS",CARD_UNIONS; +"CARD_UNIONS_LE",CARD_UNIONS_LE; +"CARD_UNION_EQ",CARD_UNION_EQ; +"CARD_UNION_GEN",CARD_UNION_GEN; +"CARD_UNION_LE",CARD_UNION_LE; +"CARD_UNION_LEMMA",CARD_UNION_LEMMA; +"CARD_UNION_OVERLAP",CARD_UNION_OVERLAP; +"CARD_UNION_OVERLAP_EQ",CARD_UNION_OVERLAP_EQ; +"CART_EQ",CART_EQ; +"CART_EQ_FULL",CART_EQ_FULL; +"CASEWISE",CASEWISE; +"CASEWISE_CASES",CASEWISE_CASES; +"CASEWISE_DEF",CASEWISE_DEF; +"CASEWISE_WORKS",CASEWISE_WORKS; +"CASN_0",CASN_0; +"CASN_1",CASN_1; +"CASN_BODY_LEMMA",CASN_BODY_LEMMA; +"CASN_BOUNDS",CASN_BOUNDS; +"CASN_CACS_SQRT_POS",CASN_CACS_SQRT_POS; +"CASN_CSIN",CASN_CSIN; +"CASN_NEG_1",CASN_NEG_1; +"CASN_RANGE_LEMMA",CASN_RANGE_LEMMA; +"CASN_UNIQUE",CASN_UNIQUE; +"CATN_CTAN",CATN_CTAN; +"CAUCHY",CAUCHY; +"CAUCHY_CONTINUOUS_EXTENDS_TO_CLOSURE",CAUCHY_CONTINUOUS_EXTENDS_TO_CLOSURE; +"CAUCHY_CONTINUOUS_IMP_CONTINUOUS",CAUCHY_CONTINUOUS_IMP_CONTINUOUS; +"CAUCHY_CONTINUOUS_UNIQUENESS_LEMMA",CAUCHY_CONTINUOUS_UNIQUENESS_LEMMA; +"CAUCHY_DERIVATIVE_INTEGRAL_CIRCLEPATH",CAUCHY_DERIVATIVE_INTEGRAL_CIRCLEPATH; +"CAUCHY_HAS_PATH_INTEGRAL_HIGHER_DERIVATIVE_CIRCLEPATH",CAUCHY_HAS_PATH_INTEGRAL_HIGHER_DERIVATIVE_CIRCLEPATH; +"CAUCHY_HIGHER_COMPLEX_DERIVATIVE_BOUND",CAUCHY_HIGHER_COMPLEX_DERIVATIVE_BOUND; +"CAUCHY_HIGHER_DERIVATIVE_INTEGRAL_CIRCLEPATH",CAUCHY_HIGHER_DERIVATIVE_INTEGRAL_CIRCLEPATH; +"CAUCHY_IMP_BOUNDED",CAUCHY_IMP_BOUNDED; +"CAUCHY_INEQUALITY",CAUCHY_INEQUALITY; +"CAUCHY_INTEGRAL_CIRCLEPATH",CAUCHY_INTEGRAL_CIRCLEPATH; +"CAUCHY_INTEGRAL_CIRCLEPATH_SIMPLE",CAUCHY_INTEGRAL_CIRCLEPATH_SIMPLE; +"CAUCHY_INTEGRAL_FORMULA_CONVEX",CAUCHY_INTEGRAL_FORMULA_CONVEX; +"CAUCHY_INTEGRAL_FORMULA_CONVEX_SIMPLE",CAUCHY_INTEGRAL_FORMULA_CONVEX_SIMPLE; +"CAUCHY_INTEGRAL_FORMULA_GLOBAL",CAUCHY_INTEGRAL_FORMULA_GLOBAL; +"CAUCHY_INTEGRAL_FORMULA_WEAK",CAUCHY_INTEGRAL_FORMULA_WEAK; +"CAUCHY_ISOMETRIC",CAUCHY_ISOMETRIC; +"CAUCHY_NEXT_DERIVATIVE",CAUCHY_NEXT_DERIVATIVE; +"CAUCHY_NEXT_DERIVATIVE_CIRCLEPATH",CAUCHY_NEXT_DERIVATIVE_CIRCLEPATH; +"CAUCHY_RIEMANN",CAUCHY_RIEMANN; +"CAUCHY_THEOREM_CONVEX",CAUCHY_THEOREM_CONVEX; +"CAUCHY_THEOREM_CONVEX_SIMPLE",CAUCHY_THEOREM_CONVEX_SIMPLE; +"CAUCHY_THEOREM_DISC",CAUCHY_THEOREM_DISC; +"CAUCHY_THEOREM_DISC_SIMPLE",CAUCHY_THEOREM_DISC_SIMPLE; +"CAUCHY_THEOREM_FLAT",CAUCHY_THEOREM_FLAT; +"CAUCHY_THEOREM_FLAT_LEMMA",CAUCHY_THEOREM_FLAT_LEMMA; +"CAUCHY_THEOREM_GLOBAL",CAUCHY_THEOREM_GLOBAL; +"CAUCHY_THEOREM_GLOBAL_OUTSIDE",CAUCHY_THEOREM_GLOBAL_OUTSIDE; +"CAUCHY_THEOREM_HOMOTOPIC_LOOPS",CAUCHY_THEOREM_HOMOTOPIC_LOOPS; +"CAUCHY_THEOREM_HOMOTOPIC_PATHS",CAUCHY_THEOREM_HOMOTOPIC_PATHS; +"CAUCHY_THEOREM_NULL_HOMOTOPIC",CAUCHY_THEOREM_NULL_HOMOTOPIC; +"CAUCHY_THEOREM_PRIMITIVE",CAUCHY_THEOREM_PRIMITIVE; +"CAUCHY_THEOREM_QUADRISECTION",CAUCHY_THEOREM_QUADRISECTION; +"CAUCHY_THEOREM_SIMPLY_CONNECTED",CAUCHY_THEOREM_SIMPLY_CONNECTED; +"CAUCHY_THEOREM_STARLIKE",CAUCHY_THEOREM_STARLIKE; +"CAUCHY_THEOREM_STARLIKE_SIMPLE",CAUCHY_THEOREM_STARLIKE_SIMPLE; +"CAUCHY_THEOREM_TRIANGLE",CAUCHY_THEOREM_TRIANGLE; +"CAUCHY_THEOREM_TRIANGLE_COFINITE",CAUCHY_THEOREM_TRIANGLE_COFINITE; +"CAUCHY_THEOREM_TRIANGLE_INTERIOR",CAUCHY_THEOREM_TRIANGLE_INTERIOR; +"CBALL_DIFF_BALL",CBALL_DIFF_BALL; +"CBALL_DIFF_SPHERE",CBALL_DIFF_SPHERE; +"CBALL_EMPTY",CBALL_EMPTY; +"CBALL_EQ_EMPTY",CBALL_EQ_EMPTY; +"CBALL_EQ_SING",CBALL_EQ_SING; +"CBALL_INTERVAL",CBALL_INTERVAL; +"CBALL_INTERVAL_0",CBALL_INTERVAL_0; +"CBALL_LINEAR_IMAGE",CBALL_LINEAR_IMAGE; +"CBALL_SCALING",CBALL_SCALING; +"CBALL_SING",CBALL_SING; +"CBALL_TRANSLATION",CBALL_TRANSLATION; +"CBALL_TRIVIAL",CBALL_TRIVIAL; +"CCOS_0",CCOS_0; +"CCOS_ADD",CCOS_ADD; +"CCOS_CACS",CCOS_CACS; +"CCOS_CASN",CCOS_CASN; +"CCOS_CASN_NZ",CCOS_CASN_NZ; +"CCOS_CSIN_CSQRT",CCOS_CSIN_CSQRT; +"CCOS_DOUBLE",CCOS_DOUBLE; +"CCOS_DOUBLE_CCOS",CCOS_DOUBLE_CCOS; +"CCOS_DOUBLE_CSIN",CCOS_DOUBLE_CSIN; +"CCOS_EQ",CCOS_EQ; +"CCOS_EQ_0",CCOS_EQ_0; +"CCOS_EQ_1",CCOS_EQ_1; +"CCOS_EQ_MINUS1",CCOS_EQ_MINUS1; +"CCOS_NEG",CCOS_NEG; +"CCOS_SUB",CCOS_SUB; +"CELL_COMPLEX_SUBDIVISION_EXISTS",CELL_COMPLEX_SUBDIVISION_EXISTS; +"CENTRE_IN_BALL",CENTRE_IN_BALL; +"CENTRE_IN_CBALL",CENTRE_IN_CBALL; +"CEXP_0",CEXP_0; +"CEXP_ADD",CEXP_ADD; +"CEXP_ADD_MUL",CEXP_ADD_MUL; +"CEXP_BOUND_BLEMMA",CEXP_BOUND_BLEMMA; +"CEXP_BOUND_HALF",CEXP_BOUND_HALF; +"CEXP_BOUND_LEMMA",CEXP_BOUND_LEMMA; +"CEXP_CLOG",CEXP_CLOG; +"CEXP_COMPLEX",CEXP_COMPLEX; +"CEXP_CONVERGES",CEXP_CONVERGES; +"CEXP_CONVERGES_UNIFORMLY",CEXP_CONVERGES_UNIFORMLY; +"CEXP_CONVERGES_UNIFORMLY_CAUCHY",CEXP_CONVERGES_UNIFORMLY_CAUCHY; +"CEXP_CONVERGES_UNIQUE",CEXP_CONVERGES_UNIQUE; +"CEXP_EQ",CEXP_EQ; +"CEXP_EQ_1",CEXP_EQ_1; +"CEXP_EULER",CEXP_EULER; +"CEXP_II_NE_1",CEXP_II_NE_1; +"CEXP_INTEGER_2PI",CEXP_INTEGER_2PI; +"CEXP_N",CEXP_N; +"CEXP_NEG",CEXP_NEG; +"CEXP_NEG_LMUL",CEXP_NEG_LMUL; +"CEXP_NEG_RMUL",CEXP_NEG_RMUL; +"CEXP_NZ",CEXP_NZ; +"CEXP_SUB",CEXP_SUB; +"CEXP_VSUM",CEXP_VSUM; +"CHAIN_SUBSET",CHAIN_SUBSET; +"CHARACTERISTIC_POLYNOMIAL",CHARACTERISTIC_POLYNOMIAL; +"CHOICE",CHOICE; +"CHOICE_DEF",CHOICE_DEF; +"CHOOSE_AFFINE_SUBSET",CHOOSE_AFFINE_SUBSET; +"CHOOSE_POLYTOPE",CHOOSE_POLYTOPE; +"CHOOSE_SIMPLEX",CHOOSE_SIMPLEX; +"CHOOSE_SUBSET",CHOOSE_SUBSET; +"CHOOSE_SUBSET_BETWEEN",CHOOSE_SUBSET_BETWEEN; +"CHOOSE_SUBSET_STRONG",CHOOSE_SUBSET_STRONG; +"CHOOSE_SUBSPACE_OF_SUBSPACE",CHOOSE_SUBSPACE_OF_SUBSPACE; +"CIRCLEPATH",CIRCLEPATH; +"CIRCLE_SINCOS",CIRCLE_SINCOS; +"CLOG_1",CLOG_1; +"CLOG_CEXP",CLOG_CEXP; +"CLOG_EQ",CLOG_EQ; +"CLOG_II",CLOG_II; +"CLOG_INV",CLOG_INV; +"CLOG_MUL",CLOG_MUL; +"CLOG_MUL_II",CLOG_MUL_II; +"CLOG_MUL_SIMPLE",CLOG_MUL_SIMPLE; +"CLOG_MUL_UNWINDING",CLOG_MUL_UNWINDING; +"CLOG_NEG",CLOG_NEG; +"CLOG_NEG_1",CLOG_NEG_1; +"CLOG_NEG_II",CLOG_NEG_II; +"CLOG_UNIQUE",CLOG_UNIQUE; +"CLOG_WORKS",CLOG_WORKS; +"CLOPEN",CLOPEN; +"CLOSED_AFFINE",CLOSED_AFFINE; +"CLOSED_AFFINE_HULL",CLOSED_AFFINE_HULL; +"CLOSED_APPROACHABLE",CLOSED_APPROACHABLE; +"CLOSED_ARC_IMAGE",CLOSED_ARC_IMAGE; +"CLOSED_ARG_LE",CLOSED_ARG_LE; +"CLOSED_AS_FRONTIER",CLOSED_AS_FRONTIER; +"CLOSED_AS_FRONTIER_OF_SUBSET",CLOSED_AS_FRONTIER_OF_SUBSET; +"CLOSED_BOUNDEDPREIM_CONTINUOUS_IMAGE",CLOSED_BOUNDEDPREIM_CONTINUOUS_IMAGE; +"CLOSED_CBALL",CLOSED_CBALL; +"CLOSED_CLOSED_IN_TRANS",CLOSED_CLOSED_IN_TRANS; +"CLOSED_CLOSURE",CLOSED_CLOSURE; +"CLOSED_COMPACT_DIFFERENCES",CLOSED_COMPACT_DIFFERENCES; +"CLOSED_COMPACT_PROJECTION",CLOSED_COMPACT_PROJECTION; +"CLOSED_COMPACT_SUMS",CLOSED_COMPACT_SUMS; +"CLOSED_COMPONENTS",CLOSED_COMPONENTS; +"CLOSED_CONDENSATION_POINTS",CLOSED_CONDENSATION_POINTS; +"CLOSED_CONNECTED_COMPONENT",CLOSED_CONNECTED_COMPONENT; +"CLOSED_CONTAINS_SEQUENTIAL_LIMIT",CLOSED_CONTAINS_SEQUENTIAL_LIMIT; +"CLOSED_CONVEX_CONE_HULL",CLOSED_CONVEX_CONE_HULL; +"CLOSED_DIFF",CLOSED_DIFF; +"CLOSED_DIFF_OPEN_INTERVAL_1",CLOSED_DIFF_OPEN_INTERVAL_1; +"CLOSED_EMPTY",CLOSED_EMPTY; +"CLOSED_FIP",CLOSED_FIP; +"CLOSED_FORALL",CLOSED_FORALL; +"CLOSED_FORALL_IN",CLOSED_FORALL_IN; +"CLOSED_HALFSPACE_COMPONENT_GE",CLOSED_HALFSPACE_COMPONENT_GE; +"CLOSED_HALFSPACE_COMPONENT_LE",CLOSED_HALFSPACE_COMPONENT_LE; +"CLOSED_HALFSPACE_GE",CLOSED_HALFSPACE_GE; +"CLOSED_HALFSPACE_IM_EQ",CLOSED_HALFSPACE_IM_EQ; +"CLOSED_HALFSPACE_IM_GE",CLOSED_HALFSPACE_IM_GE; +"CLOSED_HALFSPACE_IM_LE",CLOSED_HALFSPACE_IM_LE; +"CLOSED_HALFSPACE_LE",CLOSED_HALFSPACE_LE; +"CLOSED_HALFSPACE_RE_EQ",CLOSED_HALFSPACE_RE_EQ; +"CLOSED_HALFSPACE_RE_GE",CLOSED_HALFSPACE_RE_GE; +"CLOSED_HALFSPACE_RE_LE",CLOSED_HALFSPACE_RE_LE; +"CLOSED_HYPERPLANE",CLOSED_HYPERPLANE; +"CLOSED_IMP_LOCALLY_COMPACT",CLOSED_IMP_LOCALLY_COMPACT; +"CLOSED_IN",CLOSED_IN; +"CLOSED_INJECTIVE_IMAGE_SUBSET_SUBSPACE",CLOSED_INJECTIVE_IMAGE_SUBSET_SUBSPACE; +"CLOSED_INJECTIVE_IMAGE_SUBSPACE",CLOSED_INJECTIVE_IMAGE_SUBSPACE; +"CLOSED_INJECTIVE_LINEAR_IMAGE",CLOSED_INJECTIVE_LINEAR_IMAGE; +"CLOSED_INJECTIVE_LINEAR_IMAGE_EQ",CLOSED_INJECTIVE_LINEAR_IMAGE_EQ; +"CLOSED_INSERT",CLOSED_INSERT; +"CLOSED_INTER",CLOSED_INTER; +"CLOSED_INTERS",CLOSED_INTERS; +"CLOSED_INTERS_COMPACT",CLOSED_INTERS_COMPACT; +"CLOSED_INTERVAL",CLOSED_INTERVAL; +"CLOSED_INTERVAL_AS_CONVEX_HULL",CLOSED_INTERVAL_AS_CONVEX_HULL; +"CLOSED_INTERVAL_DROPOUT",CLOSED_INTERVAL_DROPOUT; +"CLOSED_INTERVAL_EQ",CLOSED_INTERVAL_EQ; +"CLOSED_INTERVAL_IMAGE_UNIT_INTERVAL",CLOSED_INTERVAL_IMAGE_UNIT_INTERVAL; +"CLOSED_INTERVAL_LEFT",CLOSED_INTERVAL_LEFT; +"CLOSED_INTERVAL_RIGHT",CLOSED_INTERVAL_RIGHT; +"CLOSED_INTER_COMPACT",CLOSED_INTER_COMPACT; +"CLOSED_IN_CLOSED",CLOSED_IN_CLOSED; +"CLOSED_IN_CLOSED_EQ",CLOSED_IN_CLOSED_EQ; +"CLOSED_IN_CLOSED_INTER",CLOSED_IN_CLOSED_INTER; +"CLOSED_IN_CLOSED_TRANS",CLOSED_IN_CLOSED_TRANS; +"CLOSED_IN_COMPACT",CLOSED_IN_COMPACT; +"CLOSED_IN_COMPACT_PROJECTION",CLOSED_IN_COMPACT_PROJECTION; +"CLOSED_IN_CONNECTED_COMPONENT",CLOSED_IN_CONNECTED_COMPONENT; +"CLOSED_IN_DIFF",CLOSED_IN_DIFF; +"CLOSED_IN_EMPTY",CLOSED_IN_EMPTY; +"CLOSED_IN_IMP_SUBSET",CLOSED_IN_IMP_SUBSET; +"CLOSED_IN_INJECTIVE_LINEAR_IMAGE",CLOSED_IN_INJECTIVE_LINEAR_IMAGE; +"CLOSED_IN_INTER",CLOSED_IN_INTER; +"CLOSED_IN_INTERS",CLOSED_IN_INTERS; +"CLOSED_IN_INTER_CLOSED",CLOSED_IN_INTER_CLOSED; +"CLOSED_IN_LIMPT",CLOSED_IN_LIMPT; +"CLOSED_IN_PATH_COMPONENT_LOCALLY_PATH_CONNECTED",CLOSED_IN_PATH_COMPONENT_LOCALLY_PATH_CONNECTED; +"CLOSED_IN_REFL",CLOSED_IN_REFL; +"CLOSED_IN_RETRACT",CLOSED_IN_RETRACT; +"CLOSED_IN_SING",CLOSED_IN_SING; +"CLOSED_IN_SUBSET",CLOSED_IN_SUBSET; +"CLOSED_IN_SUBSET_TRANS",CLOSED_IN_SUBSET_TRANS; +"CLOSED_IN_SUBTOPOLOGY",CLOSED_IN_SUBTOPOLOGY; +"CLOSED_IN_SUBTOPOLOGY_EMPTY",CLOSED_IN_SUBTOPOLOGY_EMPTY; +"CLOSED_IN_SUBTOPOLOGY_REFL",CLOSED_IN_SUBTOPOLOGY_REFL; +"CLOSED_IN_SUBTOPOLOGY_UNION",CLOSED_IN_SUBTOPOLOGY_UNION; +"CLOSED_IN_TOPSPACE",CLOSED_IN_TOPSPACE; +"CLOSED_IN_TRANS",CLOSED_IN_TRANS; +"CLOSED_IN_TRANSLATION_EQ",CLOSED_IN_TRANSLATION_EQ; +"CLOSED_IN_UNION",CLOSED_IN_UNION; +"CLOSED_IN_UNIONS",CLOSED_IN_UNIONS; +"CLOSED_IN_UNION_COMPLEMENT_COMPONENT",CLOSED_IN_UNION_COMPLEMENT_COMPONENT; +"CLOSED_LIFT",CLOSED_LIFT; +"CLOSED_LIMPT",CLOSED_LIMPT; +"CLOSED_LIMPTS",CLOSED_LIMPTS; +"CLOSED_MAP_FROM_COMPOSITION_INJECTIVE",CLOSED_MAP_FROM_COMPOSITION_INJECTIVE; +"CLOSED_MAP_FROM_COMPOSITION_SURJECTIVE",CLOSED_MAP_FROM_COMPOSITION_SURJECTIVE; +"CLOSED_MAP_IMP_OPEN_MAP",CLOSED_MAP_IMP_OPEN_MAP; +"CLOSED_MAP_IMP_QUOTIENT_MAP",CLOSED_MAP_IMP_QUOTIENT_MAP; +"CLOSED_NEGATIONS",CLOSED_NEGATIONS; +"CLOSED_OPEN_INTERVAL_1",CLOSED_OPEN_INTERVAL_1; +"CLOSED_PATH_IMAGE",CLOSED_PATH_IMAGE; +"CLOSED_PCROSS",CLOSED_PCROSS; +"CLOSED_PCROSS_EQ",CLOSED_PCROSS_EQ; +"CLOSED_POSITIVE_ORTHANT",CLOSED_POSITIVE_ORTHANT; +"CLOSED_REAL",CLOSED_REAL; +"CLOSED_REAL_SET",CLOSED_REAL_SET; +"CLOSED_RELATIVE_BOUNDARY",CLOSED_RELATIVE_BOUNDARY; +"CLOSED_RELATIVE_FRONTIER",CLOSED_RELATIVE_FRONTIER; +"CLOSED_SCALING",CLOSED_SCALING; +"CLOSED_SEGMENT",CLOSED_SEGMENT; +"CLOSED_SEGMENT_LINEAR_IMAGE",CLOSED_SEGMENT_LINEAR_IMAGE; +"CLOSED_SEQUENTIAL_LIMITS",CLOSED_SEQUENTIAL_LIMITS; +"CLOSED_SHIFTPATH",CLOSED_SHIFTPATH; +"CLOSED_SIMPLE_PATH_IMAGE",CLOSED_SIMPLE_PATH_IMAGE; +"CLOSED_SING",CLOSED_SING; +"CLOSED_SLICE",CLOSED_SLICE; +"CLOSED_SPAN",CLOSED_SPAN; +"CLOSED_SPHERE",CLOSED_SPHERE; +"CLOSED_STANDARD_HYPERPLANE",CLOSED_STANDARD_HYPERPLANE; +"CLOSED_SUBSET",CLOSED_SUBSET; +"CLOSED_SUBSET_EQ",CLOSED_SUBSET_EQ; +"CLOSED_SUBSPACE",CLOSED_SUBSPACE; +"CLOSED_SUBSTANDARD",CLOSED_SUBSTANDARD; +"CLOSED_TRANSLATION",CLOSED_TRANSLATION; +"CLOSED_TRANSLATION_EQ",CLOSED_TRANSLATION_EQ; +"CLOSED_UNION",CLOSED_UNION; +"CLOSED_UNIONS",CLOSED_UNIONS; +"CLOSED_UNION_COMPACT_SUBSETS",CLOSED_UNION_COMPACT_SUBSETS; +"CLOSED_UNION_COMPLEMENT_COMPONENT",CLOSED_UNION_COMPLEMENT_COMPONENT; +"CLOSED_UNIV",CLOSED_UNIV; +"CLOSED_VALID_PATH_IMAGE",CLOSED_VALID_PATH_IMAGE; +"CLOSER_POINTS_LEMMA",CLOSER_POINTS_LEMMA; +"CLOSER_POINT_LEMMA",CLOSER_POINT_LEMMA; +"CLOSEST_POINT_AFFINE_ORTHOGONAL",CLOSEST_POINT_AFFINE_ORTHOGONAL; +"CLOSEST_POINT_AFFINE_ORTHOGONAL_EQ",CLOSEST_POINT_AFFINE_ORTHOGONAL_EQ; +"CLOSEST_POINT_DOT",CLOSEST_POINT_DOT; +"CLOSEST_POINT_EXISTS",CLOSEST_POINT_EXISTS; +"CLOSEST_POINT_IN_FRONTIER",CLOSEST_POINT_IN_FRONTIER; +"CLOSEST_POINT_IN_INTERIOR",CLOSEST_POINT_IN_INTERIOR; +"CLOSEST_POINT_IN_RELATIVE_FRONTIER",CLOSEST_POINT_IN_RELATIVE_FRONTIER; +"CLOSEST_POINT_IN_RELATIVE_INTERIOR",CLOSEST_POINT_IN_RELATIVE_INTERIOR; +"CLOSEST_POINT_IN_SET",CLOSEST_POINT_IN_SET; +"CLOSEST_POINT_LE",CLOSEST_POINT_LE; +"CLOSEST_POINT_LIPSCHITZ",CLOSEST_POINT_LIPSCHITZ; +"CLOSEST_POINT_LT",CLOSEST_POINT_LT; +"CLOSEST_POINT_REFL",CLOSEST_POINT_REFL; +"CLOSEST_POINT_SELF",CLOSEST_POINT_SELF; +"CLOSEST_POINT_UNIQUE",CLOSEST_POINT_UNIQUE; +"CLOSURE_APPROACHABLE",CLOSURE_APPROACHABLE; +"CLOSURE_BALL",CLOSURE_BALL; +"CLOSURE_BOUNDED_LINEAR_IMAGE",CLOSURE_BOUNDED_LINEAR_IMAGE; +"CLOSURE_CLOSED",CLOSURE_CLOSED; +"CLOSURE_CLOSURE",CLOSURE_CLOSURE; +"CLOSURE_COCOUNTABLE_COORDINATES",CLOSURE_COCOUNTABLE_COORDINATES; +"CLOSURE_COMPLEMENT",CLOSURE_COMPLEMENT; +"CLOSURE_CONVEX_HULL",CLOSURE_CONVEX_HULL; +"CLOSURE_CONVEX_INTER_AFFINE",CLOSURE_CONVEX_INTER_AFFINE; +"CLOSURE_CONVEX_INTER_SUPERSET",CLOSURE_CONVEX_INTER_SUPERSET; +"CLOSURE_COSMALL_COORDINATES",CLOSURE_COSMALL_COORDINATES; +"CLOSURE_DYADIC_RATIONALS",CLOSURE_DYADIC_RATIONALS; +"CLOSURE_DYADIC_RATIONALS_IN_CONVEX_SET",CLOSURE_DYADIC_RATIONALS_IN_CONVEX_SET; +"CLOSURE_DYADIC_RATIONALS_IN_OPEN_SET",CLOSURE_DYADIC_RATIONALS_IN_OPEN_SET; +"CLOSURE_EMPTY",CLOSURE_EMPTY; +"CLOSURE_EQ",CLOSURE_EQ; +"CLOSURE_EQ_EMPTY",CLOSURE_EQ_EMPTY; +"CLOSURE_HALFSPACE_COMPONENT_GT",CLOSURE_HALFSPACE_COMPONENT_GT; +"CLOSURE_HALFSPACE_COMPONENT_LT",CLOSURE_HALFSPACE_COMPONENT_LT; +"CLOSURE_HALFSPACE_GT",CLOSURE_HALFSPACE_GT; +"CLOSURE_HALFSPACE_LT",CLOSURE_HALFSPACE_LT; +"CLOSURE_HULL",CLOSURE_HULL; +"CLOSURE_IMAGE_CLOSURE",CLOSURE_IMAGE_CLOSURE; +"CLOSURE_INJECTIVE_LINEAR_IMAGE",CLOSURE_INJECTIVE_LINEAR_IMAGE; +"CLOSURE_INSIDE_SUBSET",CLOSURE_INSIDE_SUBSET; +"CLOSURE_INTERIOR",CLOSURE_INTERIOR; +"CLOSURE_INTERIOR_IDEMP",CLOSURE_INTERIOR_IDEMP; +"CLOSURE_INTERS_CONVEX",CLOSURE_INTERS_CONVEX; +"CLOSURE_INTERS_CONVEX_OPEN",CLOSURE_INTERS_CONVEX_OPEN; +"CLOSURE_INTERS_SUBSET",CLOSURE_INTERS_SUBSET; +"CLOSURE_INTERVAL",CLOSURE_INTERVAL; +"CLOSURE_INTER_CONVEX",CLOSURE_INTER_CONVEX; +"CLOSURE_INTER_CONVEX_OPEN",CLOSURE_INTER_CONVEX_OPEN; +"CLOSURE_INTER_SUBSET",CLOSURE_INTER_SUBSET; +"CLOSURE_IRRATIONAL_COORDINATES",CLOSURE_IRRATIONAL_COORDINATES; +"CLOSURE_LINEAR_IMAGE_SUBSET",CLOSURE_LINEAR_IMAGE_SUBSET; +"CLOSURE_MINIMAL",CLOSURE_MINIMAL; +"CLOSURE_MINIMAL_EQ",CLOSURE_MINIMAL_EQ; +"CLOSURE_NEGATIONS",CLOSURE_NEGATIONS; +"CLOSURE_OPEN_INTERVAL",CLOSURE_OPEN_INTERVAL; +"CLOSURE_OPEN_INTER_SUPERSET",CLOSURE_OPEN_INTER_SUPERSET; +"CLOSURE_OUTSIDE_SUBSET",CLOSURE_OUTSIDE_SUBSET; +"CLOSURE_PCROSS",CLOSURE_PCROSS; +"CLOSURE_RATIONALS_IN_CONVEX_SET",CLOSURE_RATIONALS_IN_CONVEX_SET; +"CLOSURE_RATIONALS_IN_OPEN_SET",CLOSURE_RATIONALS_IN_OPEN_SET; +"CLOSURE_RATIONAL_COORDINATES",CLOSURE_RATIONAL_COORDINATES; +"CLOSURE_SEGMENT",CLOSURE_SEGMENT; +"CLOSURE_SEQUENTIAL",CLOSURE_SEQUENTIAL; +"CLOSURE_SING",CLOSURE_SING; +"CLOSURE_SUBSET",CLOSURE_SUBSET; +"CLOSURE_SUBSET_AFFINE_HULL",CLOSURE_SUBSET_AFFINE_HULL; +"CLOSURE_SUBSET_EQ",CLOSURE_SUBSET_EQ; +"CLOSURE_SURJECTIVE_LINEAR_IMAGE",CLOSURE_SURJECTIVE_LINEAR_IMAGE; +"CLOSURE_TRANSLATION",CLOSURE_TRANSLATION; +"CLOSURE_UNION",CLOSURE_UNION; +"CLOSURE_UNIONS",CLOSURE_UNIONS; +"CLOSURE_UNION_FRONTIER",CLOSURE_UNION_FRONTIER; +"CLOSURE_UNIQUE",CLOSURE_UNIQUE; +"CLOSURE_UNIV",CLOSURE_UNIV; +"CNJ_ADD",CNJ_ADD; +"CNJ_CCOS",CNJ_CCOS; +"CNJ_CEXP",CNJ_CEXP; +"CNJ_CLOG",CNJ_CLOG; +"CNJ_CNJ",CNJ_CNJ; +"CNJ_CSIN",CNJ_CSIN; +"CNJ_CSQRT",CNJ_CSQRT; +"CNJ_CTAN",CNJ_CTAN; +"CNJ_CX",CNJ_CX; +"CNJ_DIV",CNJ_DIV; +"CNJ_EQ_0",CNJ_EQ_0; +"CNJ_EQ_CX",CNJ_EQ_CX; +"CNJ_II",CNJ_II; +"CNJ_INJ",CNJ_INJ; +"CNJ_INV",CNJ_INV; +"CNJ_MUL",CNJ_MUL; +"CNJ_NEG",CNJ_NEG; +"CNJ_POW",CNJ_POW; +"CNJ_SUB",CNJ_SUB; +"CNJ_VSUM",CNJ_VSUM; +"COBOUNDED_HAS_BOUNDED_COMPONENT",COBOUNDED_HAS_BOUNDED_COMPONENT; +"COBOUNDED_IMP_UNBOUNDED",COBOUNDED_IMP_UNBOUNDED; +"COBOUNDED_INTER_UNBOUNDED",COBOUNDED_INTER_UNBOUNDED; +"COBOUNDED_OUTSIDE",COBOUNDED_OUTSIDE; +"COBOUNDED_UNBOUNDED_COMPONENT",COBOUNDED_UNBOUNDED_COMPONENT; +"COBOUNDED_UNBOUNDED_COMPONENTS",COBOUNDED_UNBOUNDED_COMPONENTS; +"COBOUNDED_UNIQUE_UNBOUNDED_COMPONENT",COBOUNDED_UNIQUE_UNBOUNDED_COMPONENT; +"COBOUNDED_UNIQUE_UNBOUNDED_COMPONENTS",COBOUNDED_UNIQUE_UNBOUNDED_COMPONENTS; +"COCOUNTABLE_APPROXIMATION",COCOUNTABLE_APPROXIMATION; +"CODESET_SETCODE_BIJECTIONS",CODESET_SETCODE_BIJECTIONS; +"COFACTOR_0",COFACTOR_0; +"COFACTOR_CMUL",COFACTOR_CMUL; +"COFACTOR_COFACTOR",COFACTOR_COFACTOR; +"COFACTOR_COLUMN",COFACTOR_COLUMN; +"COFACTOR_I",COFACTOR_I; +"COFACTOR_MATRIX_INV",COFACTOR_MATRIX_INV; +"COFACTOR_MATRIX_MUL",COFACTOR_MATRIX_MUL; +"COFACTOR_ROW",COFACTOR_ROW; +"COFACTOR_TRANSP",COFACTOR_TRANSP; +"COHOMOTOPICALLY_TRIVIAL_RETRACTION_GEN",COHOMOTOPICALLY_TRIVIAL_RETRACTION_GEN; +"COHOMOTOPICALLY_TRIVIAL_RETRACTION_NULL_GEN",COHOMOTOPICALLY_TRIVIAL_RETRACTION_NULL_GEN; +"COLLINEAR_1",COLLINEAR_1; +"COLLINEAR_2",COLLINEAR_2; +"COLLINEAR_3",COLLINEAR_3; +"COLLINEAR_3_2D",COLLINEAR_3_2D; +"COLLINEAR_3_AFFINE_HULL",COLLINEAR_3_AFFINE_HULL; +"COLLINEAR_3_DOT_MULTIPLES",COLLINEAR_3_DOT_MULTIPLES; +"COLLINEAR_3_EQ_AFFINE_DEPENDENT",COLLINEAR_3_EQ_AFFINE_DEPENDENT; +"COLLINEAR_3_EXPAND",COLLINEAR_3_EXPAND; +"COLLINEAR_3_IN_AFFINE_HULL",COLLINEAR_3_IN_AFFINE_HULL; +"COLLINEAR_3_TRANS",COLLINEAR_3_TRANS; +"COLLINEAR_4_3",COLLINEAR_4_3; +"COLLINEAR_AFFINE_HULL",COLLINEAR_AFFINE_HULL; +"COLLINEAR_AFFINE_HULL_COLLINEAR",COLLINEAR_AFFINE_HULL_COLLINEAR; +"COLLINEAR_AFF_DIM",COLLINEAR_AFF_DIM; +"COLLINEAR_BETWEEN_CASES",COLLINEAR_BETWEEN_CASES; +"COLLINEAR_CONVEX_HULL_COLLINEAR",COLLINEAR_CONVEX_HULL_COLLINEAR; +"COLLINEAR_DIST_BETWEEN",COLLINEAR_DIST_BETWEEN; +"COLLINEAR_DIST_IN_CLOSED_SEGMENT",COLLINEAR_DIST_IN_CLOSED_SEGMENT; +"COLLINEAR_DIST_IN_OPEN_SEGMENT",COLLINEAR_DIST_IN_OPEN_SEGMENT; +"COLLINEAR_EMPTY",COLLINEAR_EMPTY; +"COLLINEAR_EXTREME_POINTS",COLLINEAR_EXTREME_POINTS; +"COLLINEAR_IMP_COPLANAR",COLLINEAR_IMP_COPLANAR; +"COLLINEAR_LEMMA",COLLINEAR_LEMMA; +"COLLINEAR_LEMMA_ALT",COLLINEAR_LEMMA_ALT; +"COLLINEAR_LINEAR_IMAGE",COLLINEAR_LINEAR_IMAGE; +"COLLINEAR_LINEAR_IMAGE_EQ",COLLINEAR_LINEAR_IMAGE_EQ; +"COLLINEAR_MIDPOINT",COLLINEAR_MIDPOINT; +"COLLINEAR_SEGMENT",COLLINEAR_SEGMENT; +"COLLINEAR_SING",COLLINEAR_SING; +"COLLINEAR_SMALL",COLLINEAR_SMALL; +"COLLINEAR_SUBSET",COLLINEAR_SUBSET; +"COLLINEAR_TRANSLATION",COLLINEAR_TRANSLATION; +"COLLINEAR_TRANSLATION_EQ",COLLINEAR_TRANSLATION_EQ; +"COLLINEAR_TRIPLES",COLLINEAR_TRIPLES; +"COLUMNS_IMAGE_BASIS",COLUMNS_IMAGE_BASIS; +"COLUMNS_TRANSP",COLUMNS_TRANSP; +"COLUMN_TRANSP",COLUMN_TRANSP; +"COMMA_DEF",COMMA_DEF; +"COMPACT_AFFINITY",COMPACT_AFFINITY; +"COMPACT_ARC_IMAGE",COMPACT_ARC_IMAGE; +"COMPACT_ATTAINS_INF",COMPACT_ATTAINS_INF; +"COMPACT_ATTAINS_SUP",COMPACT_ATTAINS_SUP; +"COMPACT_CBALL",COMPACT_CBALL; +"COMPACT_CHAIN",COMPACT_CHAIN; +"COMPACT_CLOSED_DIFFERENCES",COMPACT_CLOSED_DIFFERENCES; +"COMPACT_CLOSED_SUMS",COMPACT_CLOSED_SUMS; +"COMPACT_CLOSURE",COMPACT_CLOSURE; +"COMPACT_CONTINUOUS_IMAGE",COMPACT_CONTINUOUS_IMAGE; +"COMPACT_CONTINUOUS_IMAGE_EQ",COMPACT_CONTINUOUS_IMAGE_EQ; +"COMPACT_CONVEX_COLLINEAR_SEGMENT",COMPACT_CONVEX_COLLINEAR_SEGMENT; +"COMPACT_CONVEX_COMBINATIONS",COMPACT_CONVEX_COMBINATIONS; +"COMPACT_CONVEX_HULL",COMPACT_CONVEX_HULL; +"COMPACT_DIFF",COMPACT_DIFF; +"COMPACT_DIFFERENCES",COMPACT_DIFFERENCES; +"COMPACT_EMPTY",COMPACT_EMPTY; +"COMPACT_EQ_BOLZANO_WEIERSTRASS",COMPACT_EQ_BOLZANO_WEIERSTRASS; +"COMPACT_EQ_BOUNDED_CLOSED",COMPACT_EQ_BOUNDED_CLOSED; +"COMPACT_EQ_HEINE_BOREL",COMPACT_EQ_HEINE_BOREL; +"COMPACT_EQ_HEINE_BOREL_SUBTOPOLOGY",COMPACT_EQ_HEINE_BOREL_SUBTOPOLOGY; +"COMPACT_FIP",COMPACT_FIP; +"COMPACT_FRONTIER",COMPACT_FRONTIER; +"COMPACT_FRONTIER_BOUNDED",COMPACT_FRONTIER_BOUNDED; +"COMPACT_FRONTIER_LINE_LEMMA",COMPACT_FRONTIER_LINE_LEMMA; +"COMPACT_IMP_BOUNDED",COMPACT_IMP_BOUNDED; +"COMPACT_IMP_CLOSED",COMPACT_IMP_CLOSED; +"COMPACT_IMP_COMPLETE",COMPACT_IMP_COMPLETE; +"COMPACT_IMP_FIP",COMPACT_IMP_FIP; +"COMPACT_IMP_HEINE_BOREL",COMPACT_IMP_HEINE_BOREL; +"COMPACT_IMP_TOTALLY_BOUNDED",COMPACT_IMP_TOTALLY_BOUNDED; +"COMPACT_INSERT",COMPACT_INSERT; +"COMPACT_INTER",COMPACT_INTER; +"COMPACT_INTERS",COMPACT_INTERS; +"COMPACT_INTERVAL",COMPACT_INTERVAL; +"COMPACT_INTERVAL_EQ",COMPACT_INTERVAL_EQ; +"COMPACT_INTER_CLOSED",COMPACT_INTER_CLOSED; +"COMPACT_LEMMA",COMPACT_LEMMA; +"COMPACT_LINEAR_IMAGE",COMPACT_LINEAR_IMAGE; +"COMPACT_LINEAR_IMAGE_EQ",COMPACT_LINEAR_IMAGE_EQ; +"COMPACT_NEGATIONS",COMPACT_NEGATIONS; +"COMPACT_NEST",COMPACT_NEST; +"COMPACT_OPEN",COMPACT_OPEN; +"COMPACT_PATH_IMAGE",COMPACT_PATH_IMAGE; +"COMPACT_PCROSS",COMPACT_PCROSS; +"COMPACT_PCROSS_EQ",COMPACT_PCROSS_EQ; +"COMPACT_REAL_LEMMA",COMPACT_REAL_LEMMA; +"COMPACT_RELATIVE_BOUNDARY",COMPACT_RELATIVE_BOUNDARY; +"COMPACT_RELATIVE_FRONTIER",COMPACT_RELATIVE_FRONTIER; +"COMPACT_RELATIVE_FRONTIER_BOUNDED",COMPACT_RELATIVE_FRONTIER_BOUNDED; +"COMPACT_SCALING",COMPACT_SCALING; +"COMPACT_SEGMENT",COMPACT_SEGMENT; +"COMPACT_SEQUENCE_WITH_LIMIT",COMPACT_SEQUENCE_WITH_LIMIT; +"COMPACT_SIMPLEX",COMPACT_SIMPLEX; +"COMPACT_SIMPLE_PATH_IMAGE",COMPACT_SIMPLE_PATH_IMAGE; +"COMPACT_SING",COMPACT_SING; +"COMPACT_SLICE",COMPACT_SLICE; +"COMPACT_SPHERE",COMPACT_SPHERE; +"COMPACT_SUBSET_FRONTIER_RETRACTION",COMPACT_SUBSET_FRONTIER_RETRACTION; +"COMPACT_SUMS",COMPACT_SUMS; +"COMPACT_SUP_MAXDISTANCE",COMPACT_SUP_MAXDISTANCE; +"COMPACT_TRANSLATION",COMPACT_TRANSLATION; +"COMPACT_TRANSLATION_EQ",COMPACT_TRANSLATION_EQ; +"COMPACT_UNIFORMLY_CONTINUOUS",COMPACT_UNIFORMLY_CONTINUOUS; +"COMPACT_UNIFORMLY_EQUICONTINUOUS",COMPACT_UNIFORMLY_EQUICONTINUOUS; +"COMPACT_UNION",COMPACT_UNION; +"COMPACT_UNIONS",COMPACT_UNIONS; +"COMPACT_VALID_PATH_IMAGE",COMPACT_VALID_PATH_IMAGE; +"COMPLETE_EQ_CLOSED",COMPLETE_EQ_CLOSED; +"COMPLETE_FACE_TOP",COMPLETE_FACE_TOP; +"COMPLETE_INJECTIVE_LINEAR_IMAGE",COMPLETE_INJECTIVE_LINEAR_IMAGE; +"COMPLETE_INJECTIVE_LINEAR_IMAGE_EQ",COMPLETE_INJECTIVE_LINEAR_IMAGE_EQ; +"COMPLETE_ISOMETRIC_IMAGE",COMPLETE_ISOMETRIC_IMAGE; +"COMPLETE_SUBSPACE",COMPLETE_SUBSPACE; +"COMPLETE_TRANSLATION_EQ",COMPLETE_TRANSLATION_EQ; +"COMPLETE_UNIV",COMPLETE_UNIV; +"COMPLEX",COMPLEX; +"COMPLEX_ADD2_SUB2",COMPLEX_ADD2_SUB2; +"COMPLEX_ADD_AC",COMPLEX_ADD_AC; +"COMPLEX_ADD_ASSOC",COMPLEX_ADD_ASSOC; +"COMPLEX_ADD_CCOS",COMPLEX_ADD_CCOS; +"COMPLEX_ADD_CNJ",COMPLEX_ADD_CNJ; +"COMPLEX_ADD_CSIN",COMPLEX_ADD_CSIN; +"COMPLEX_ADD_CTAN",COMPLEX_ADD_CTAN; +"COMPLEX_ADD_LDISTRIB",COMPLEX_ADD_LDISTRIB; +"COMPLEX_ADD_LID",COMPLEX_ADD_LID; +"COMPLEX_ADD_LINV",COMPLEX_ADD_LINV; +"COMPLEX_ADD_RDISTRIB",COMPLEX_ADD_RDISTRIB; +"COMPLEX_ADD_RID",COMPLEX_ADD_RID; +"COMPLEX_ADD_RINV",COMPLEX_ADD_RINV; +"COMPLEX_ADD_SUB",COMPLEX_ADD_SUB; +"COMPLEX_ADD_SUB2",COMPLEX_ADD_SUB2; +"COMPLEX_ADD_SYM",COMPLEX_ADD_SYM; +"COMPLEX_BASIS",COMPLEX_BASIS; +"COMPLEX_CMUL",COMPLEX_CMUL; +"COMPLEX_DERIVATIVE_ADD",COMPLEX_DERIVATIVE_ADD; +"COMPLEX_DERIVATIVE_ADD_AT",COMPLEX_DERIVATIVE_ADD_AT; +"COMPLEX_DERIVATIVE_CHAIN",COMPLEX_DERIVATIVE_CHAIN; +"COMPLEX_DERIVATIVE_COMPOSE_LINEAR",COMPLEX_DERIVATIVE_COMPOSE_LINEAR; +"COMPLEX_DERIVATIVE_CONST",COMPLEX_DERIVATIVE_CONST; +"COMPLEX_DERIVATIVE_ID",COMPLEX_DERIVATIVE_ID; +"COMPLEX_DERIVATIVE_JACOBIAN",COMPLEX_DERIVATIVE_JACOBIAN; +"COMPLEX_DERIVATIVE_LINEAR",COMPLEX_DERIVATIVE_LINEAR; +"COMPLEX_DERIVATIVE_LMUL",COMPLEX_DERIVATIVE_LMUL; +"COMPLEX_DERIVATIVE_LMUL_AT",COMPLEX_DERIVATIVE_LMUL_AT; +"COMPLEX_DERIVATIVE_MUL",COMPLEX_DERIVATIVE_MUL; +"COMPLEX_DERIVATIVE_MUL_AT",COMPLEX_DERIVATIVE_MUL_AT; +"COMPLEX_DERIVATIVE_RMUL",COMPLEX_DERIVATIVE_RMUL; +"COMPLEX_DERIVATIVE_RMUL_AT",COMPLEX_DERIVATIVE_RMUL_AT; +"COMPLEX_DERIVATIVE_SUB",COMPLEX_DERIVATIVE_SUB; +"COMPLEX_DERIVATIVE_SUB_AT",COMPLEX_DERIVATIVE_SUB_AT; +"COMPLEX_DERIVATIVE_TRANSFORM_WITHIN_OPEN",COMPLEX_DERIVATIVE_TRANSFORM_WITHIN_OPEN; +"COMPLEX_DERIVATIVE_UNIQUE_AT",COMPLEX_DERIVATIVE_UNIQUE_AT; +"COMPLEX_DIFFERENTIABLE_ADD",COMPLEX_DIFFERENTIABLE_ADD; +"COMPLEX_DIFFERENTIABLE_AT_CACS",COMPLEX_DIFFERENTIABLE_AT_CACS; +"COMPLEX_DIFFERENTIABLE_AT_CASN",COMPLEX_DIFFERENTIABLE_AT_CASN; +"COMPLEX_DIFFERENTIABLE_AT_CATN",COMPLEX_DIFFERENTIABLE_AT_CATN; +"COMPLEX_DIFFERENTIABLE_AT_CCOS",COMPLEX_DIFFERENTIABLE_AT_CCOS; +"COMPLEX_DIFFERENTIABLE_AT_CEXP",COMPLEX_DIFFERENTIABLE_AT_CEXP; +"COMPLEX_DIFFERENTIABLE_AT_CLOG",COMPLEX_DIFFERENTIABLE_AT_CLOG; +"COMPLEX_DIFFERENTIABLE_AT_CSIN",COMPLEX_DIFFERENTIABLE_AT_CSIN; +"COMPLEX_DIFFERENTIABLE_AT_CSQRT",COMPLEX_DIFFERENTIABLE_AT_CSQRT; +"COMPLEX_DIFFERENTIABLE_AT_CTAN",COMPLEX_DIFFERENTIABLE_AT_CTAN; +"COMPLEX_DIFFERENTIABLE_AT_WITHIN",COMPLEX_DIFFERENTIABLE_AT_WITHIN; +"COMPLEX_DIFFERENTIABLE_BOUND",COMPLEX_DIFFERENTIABLE_BOUND; +"COMPLEX_DIFFERENTIABLE_CARATHEODORY_AT",COMPLEX_DIFFERENTIABLE_CARATHEODORY_AT; +"COMPLEX_DIFFERENTIABLE_CARATHEODORY_WITHIN",COMPLEX_DIFFERENTIABLE_CARATHEODORY_WITHIN; +"COMPLEX_DIFFERENTIABLE_COMPOSE",COMPLEX_DIFFERENTIABLE_COMPOSE; +"COMPLEX_DIFFERENTIABLE_COMPOSE_AT",COMPLEX_DIFFERENTIABLE_COMPOSE_AT; +"COMPLEX_DIFFERENTIABLE_COMPOSE_WITHIN",COMPLEX_DIFFERENTIABLE_COMPOSE_WITHIN; +"COMPLEX_DIFFERENTIABLE_CONST",COMPLEX_DIFFERENTIABLE_CONST; +"COMPLEX_DIFFERENTIABLE_CPOW_RIGHT",COMPLEX_DIFFERENTIABLE_CPOW_RIGHT; +"COMPLEX_DIFFERENTIABLE_DIV_AT",COMPLEX_DIFFERENTIABLE_DIV_AT; +"COMPLEX_DIFFERENTIABLE_DIV_WITHIN",COMPLEX_DIFFERENTIABLE_DIV_WITHIN; +"COMPLEX_DIFFERENTIABLE_EQ_CONFORMAL",COMPLEX_DIFFERENTIABLE_EQ_CONFORMAL; +"COMPLEX_DIFFERENTIABLE_ID",COMPLEX_DIFFERENTIABLE_ID; +"COMPLEX_DIFFERENTIABLE_IMP_CONTINUOUS_AT",COMPLEX_DIFFERENTIABLE_IMP_CONTINUOUS_AT; +"COMPLEX_DIFFERENTIABLE_IMP_DIFFERENTIABLE",COMPLEX_DIFFERENTIABLE_IMP_DIFFERENTIABLE; +"COMPLEX_DIFFERENTIABLE_INV_AT",COMPLEX_DIFFERENTIABLE_INV_AT; +"COMPLEX_DIFFERENTIABLE_INV_WITHIN",COMPLEX_DIFFERENTIABLE_INV_WITHIN; +"COMPLEX_DIFFERENTIABLE_LINEAR",COMPLEX_DIFFERENTIABLE_LINEAR; +"COMPLEX_DIFFERENTIABLE_MUL_AT",COMPLEX_DIFFERENTIABLE_MUL_AT; +"COMPLEX_DIFFERENTIABLE_MUL_WITHIN",COMPLEX_DIFFERENTIABLE_MUL_WITHIN; +"COMPLEX_DIFFERENTIABLE_NEG",COMPLEX_DIFFERENTIABLE_NEG; +"COMPLEX_DIFFERENTIABLE_POW_AT",COMPLEX_DIFFERENTIABLE_POW_AT; +"COMPLEX_DIFFERENTIABLE_POW_WITHIN",COMPLEX_DIFFERENTIABLE_POW_WITHIN; +"COMPLEX_DIFFERENTIABLE_SUB",COMPLEX_DIFFERENTIABLE_SUB; +"COMPLEX_DIFFERENTIABLE_TRANSFORM_AT",COMPLEX_DIFFERENTIABLE_TRANSFORM_AT; +"COMPLEX_DIFFERENTIABLE_TRANSFORM_WITHIN",COMPLEX_DIFFERENTIABLE_TRANSFORM_WITHIN; +"COMPLEX_DIFFERENTIABLE_WITHIN_CACS",COMPLEX_DIFFERENTIABLE_WITHIN_CACS; +"COMPLEX_DIFFERENTIABLE_WITHIN_CASN",COMPLEX_DIFFERENTIABLE_WITHIN_CASN; +"COMPLEX_DIFFERENTIABLE_WITHIN_CATN",COMPLEX_DIFFERENTIABLE_WITHIN_CATN; +"COMPLEX_DIFFERENTIABLE_WITHIN_CCOS",COMPLEX_DIFFERENTIABLE_WITHIN_CCOS; +"COMPLEX_DIFFERENTIABLE_WITHIN_CEXP",COMPLEX_DIFFERENTIABLE_WITHIN_CEXP; +"COMPLEX_DIFFERENTIABLE_WITHIN_CLOG",COMPLEX_DIFFERENTIABLE_WITHIN_CLOG; +"COMPLEX_DIFFERENTIABLE_WITHIN_CSIN",COMPLEX_DIFFERENTIABLE_WITHIN_CSIN; +"COMPLEX_DIFFERENTIABLE_WITHIN_CSQRT",COMPLEX_DIFFERENTIABLE_WITHIN_CSQRT; +"COMPLEX_DIFFERENTIABLE_WITHIN_CTAN",COMPLEX_DIFFERENTIABLE_WITHIN_CTAN; +"COMPLEX_DIFFERENTIABLE_WITHIN_OPEN",COMPLEX_DIFFERENTIABLE_WITHIN_OPEN; +"COMPLEX_DIFFERENTIABLE_WITHIN_SUBSET",COMPLEX_DIFFERENTIABLE_WITHIN_SUBSET; +"COMPLEX_DIFFSQ",COMPLEX_DIFFSQ; +"COMPLEX_DIFF_CHAIN_AT",COMPLEX_DIFF_CHAIN_AT; +"COMPLEX_DIFF_CHAIN_WITHIN",COMPLEX_DIFF_CHAIN_WITHIN; +"COMPLEX_DIV_1",COMPLEX_DIV_1; +"COMPLEX_DIV_CNJ",COMPLEX_DIV_CNJ; +"COMPLEX_DIV_EQ_0",COMPLEX_DIV_EQ_0; +"COMPLEX_DIV_LMUL",COMPLEX_DIV_LMUL; +"COMPLEX_DIV_POW",COMPLEX_DIV_POW; +"COMPLEX_DIV_REFL",COMPLEX_DIV_REFL; +"COMPLEX_DIV_RMUL",COMPLEX_DIV_RMUL; +"COMPLEX_DIV_ROTATION",COMPLEX_DIV_ROTATION; +"COMPLEX_ENTIRE",COMPLEX_ENTIRE; +"COMPLEX_EQ",COMPLEX_EQ; +"COMPLEX_EQ_0",COMPLEX_EQ_0; +"COMPLEX_EQ_ADD_LCANCEL",COMPLEX_EQ_ADD_LCANCEL; +"COMPLEX_EQ_ADD_LCANCEL_0",COMPLEX_EQ_ADD_LCANCEL_0; +"COMPLEX_EQ_ADD_RCANCEL",COMPLEX_EQ_ADD_RCANCEL; +"COMPLEX_EQ_ADD_RCANCEL_0",COMPLEX_EQ_ADD_RCANCEL_0; +"COMPLEX_EQ_CEXP",COMPLEX_EQ_CEXP; +"COMPLEX_EQ_MUL_LCANCEL",COMPLEX_EQ_MUL_LCANCEL; +"COMPLEX_EQ_MUL_RCANCEL",COMPLEX_EQ_MUL_RCANCEL; +"COMPLEX_EQ_NEG2",COMPLEX_EQ_NEG2; +"COMPLEX_EQ_SUB_LADD",COMPLEX_EQ_SUB_LADD; +"COMPLEX_EQ_SUB_RADD",COMPLEX_EQ_SUB_RADD; +"COMPLEX_EXPAND",COMPLEX_EXPAND; +"COMPLEX_INTEGER",COMPLEX_INTEGER; +"COMPLEX_INV_0",COMPLEX_INV_0; +"COMPLEX_INV_1",COMPLEX_INV_1; +"COMPLEX_INV_CNJ",COMPLEX_INV_CNJ; +"COMPLEX_INV_DIV",COMPLEX_INV_DIV; +"COMPLEX_INV_EQ_0",COMPLEX_INV_EQ_0; +"COMPLEX_INV_EQ_1",COMPLEX_INV_EQ_1; +"COMPLEX_INV_II",COMPLEX_INV_II; +"COMPLEX_INV_INV",COMPLEX_INV_INV; +"COMPLEX_INV_MUL",COMPLEX_INV_MUL; +"COMPLEX_INV_NEG",COMPLEX_INV_NEG; +"COMPLEX_IN_BALL_0",COMPLEX_IN_BALL_0; +"COMPLEX_IN_CBALL_0",COMPLEX_IN_CBALL_0; +"COMPLEX_IN_SPHERE_0",COMPLEX_IN_SPHERE_0; +"COMPLEX_L1_LE_NORM",COMPLEX_L1_LE_NORM; +"COMPLEX_LNEG_UNIQ",COMPLEX_LNEG_UNIQ; +"COMPLEX_MUL_2",COMPLEX_MUL_2; +"COMPLEX_MUL_AC",COMPLEX_MUL_AC; +"COMPLEX_MUL_ASSOC",COMPLEX_MUL_ASSOC; +"COMPLEX_MUL_CCOS_CCOS",COMPLEX_MUL_CCOS_CCOS; +"COMPLEX_MUL_CCOS_CSIN",COMPLEX_MUL_CCOS_CSIN; +"COMPLEX_MUL_CNJ",COMPLEX_MUL_CNJ; +"COMPLEX_MUL_CSIN_CCOS",COMPLEX_MUL_CSIN_CCOS; +"COMPLEX_MUL_CSIN_CSIN",COMPLEX_MUL_CSIN_CSIN; +"COMPLEX_MUL_LID",COMPLEX_MUL_LID; +"COMPLEX_MUL_LINV",COMPLEX_MUL_LINV; +"COMPLEX_MUL_LNEG",COMPLEX_MUL_LNEG; +"COMPLEX_MUL_LZERO",COMPLEX_MUL_LZERO; +"COMPLEX_MUL_RID",COMPLEX_MUL_RID; +"COMPLEX_MUL_RINV",COMPLEX_MUL_RINV; +"COMPLEX_MUL_RNEG",COMPLEX_MUL_RNEG; +"COMPLEX_MUL_RZERO",COMPLEX_MUL_RZERO; +"COMPLEX_MUL_SYM",COMPLEX_MUL_SYM; +"COMPLEX_MVT",COMPLEX_MVT; +"COMPLEX_MVT_LINE",COMPLEX_MVT_LINE; +"COMPLEX_NEG_0",COMPLEX_NEG_0; +"COMPLEX_NEG_ADD",COMPLEX_NEG_ADD; +"COMPLEX_NEG_EQ",COMPLEX_NEG_EQ; +"COMPLEX_NEG_EQ_0",COMPLEX_NEG_EQ_0; +"COMPLEX_NEG_INV",COMPLEX_NEG_INV; +"COMPLEX_NEG_LMUL",COMPLEX_NEG_LMUL; +"COMPLEX_NEG_MINUS1",COMPLEX_NEG_MINUS1; +"COMPLEX_NEG_MUL2",COMPLEX_NEG_MUL2; +"COMPLEX_NEG_NEG",COMPLEX_NEG_NEG; +"COMPLEX_NEG_RMUL",COMPLEX_NEG_RMUL; +"COMPLEX_NEG_SUB",COMPLEX_NEG_SUB; +"COMPLEX_NORM_0",COMPLEX_NORM_0; +"COMPLEX_NORM_ABS_NORM",COMPLEX_NORM_ABS_NORM; +"COMPLEX_NORM_CNJ",COMPLEX_NORM_CNJ; +"COMPLEX_NORM_CX",COMPLEX_NORM_CX; +"COMPLEX_NORM_DIV",COMPLEX_NORM_DIV; +"COMPLEX_NORM_EQ_1_CEXP",COMPLEX_NORM_EQ_1_CEXP; +"COMPLEX_NORM_GE_RE_IM",COMPLEX_NORM_GE_RE_IM; +"COMPLEX_NORM_II",COMPLEX_NORM_II; +"COMPLEX_NORM_INV",COMPLEX_NORM_INV; +"COMPLEX_NORM_LE_RE_IM",COMPLEX_NORM_LE_RE_IM; +"COMPLEX_NORM_MUL",COMPLEX_NORM_MUL; +"COMPLEX_NORM_NUM",COMPLEX_NORM_NUM; +"COMPLEX_NORM_NZ",COMPLEX_NORM_NZ; +"COMPLEX_NORM_POW",COMPLEX_NORM_POW; +"COMPLEX_NORM_POW_2",COMPLEX_NORM_POW_2; +"COMPLEX_NORM_TRIANGLE_SUB",COMPLEX_NORM_TRIANGLE_SUB; +"COMPLEX_NORM_VSUM_BOUND",COMPLEX_NORM_VSUM_BOUND; +"COMPLEX_NORM_VSUM_BOUND_SUBSET",COMPLEX_NORM_VSUM_BOUND_SUBSET; +"COMPLEX_NORM_VSUM_SUM_RE",COMPLEX_NORM_VSUM_SUM_RE; +"COMPLEX_NORM_ZERO",COMPLEX_NORM_ZERO; +"COMPLEX_NOT_ROOT_UNITY",COMPLEX_NOT_ROOT_UNITY; +"COMPLEX_POLYFUN_EQ_0",COMPLEX_POLYFUN_EQ_0; +"COMPLEX_POLYFUN_EQ_CONST",COMPLEX_POLYFUN_EQ_CONST; +"COMPLEX_POLYFUN_EXTREMAL",COMPLEX_POLYFUN_EXTREMAL; +"COMPLEX_POLYFUN_EXTREMAL_LEMMA",COMPLEX_POLYFUN_EXTREMAL_LEMMA; +"COMPLEX_POLYFUN_FINITE_ROOTS",COMPLEX_POLYFUN_FINITE_ROOTS; +"COMPLEX_POLYFUN_LINEAR_FACTOR",COMPLEX_POLYFUN_LINEAR_FACTOR; +"COMPLEX_POLYFUN_LINEAR_FACTOR_ROOT",COMPLEX_POLYFUN_LINEAR_FACTOR_ROOT; +"COMPLEX_POLYFUN_ROOTBOUND",COMPLEX_POLYFUN_ROOTBOUND; +"COMPLEX_POLY_CLAUSES",COMPLEX_POLY_CLAUSES; +"COMPLEX_POLY_NEG_CLAUSES",COMPLEX_POLY_NEG_CLAUSES; +"COMPLEX_POW_1",COMPLEX_POW_1; +"COMPLEX_POW_2",COMPLEX_POW_2; +"COMPLEX_POW_ADD",COMPLEX_POW_ADD; +"COMPLEX_POW_DIV",COMPLEX_POW_DIV; +"COMPLEX_POW_EQ_0",COMPLEX_POW_EQ_0; +"COMPLEX_POW_EQ_1",COMPLEX_POW_EQ_1; +"COMPLEX_POW_II_2",COMPLEX_POW_II_2; +"COMPLEX_POW_INV",COMPLEX_POW_INV; +"COMPLEX_POW_MUL",COMPLEX_POW_MUL; +"COMPLEX_POW_NEG",COMPLEX_POW_NEG; +"COMPLEX_POW_ONE",COMPLEX_POW_ONE; +"COMPLEX_POW_POW",COMPLEX_POW_POW; +"COMPLEX_POW_ZERO",COMPLEX_POW_ZERO; +"COMPLEX_RNEG_UNIQ",COMPLEX_RNEG_UNIQ; +"COMPLEX_ROOTS_UNITY",COMPLEX_ROOTS_UNITY; +"COMPLEX_ROOT_POLYFUN",COMPLEX_ROOT_POLYFUN; +"COMPLEX_ROOT_UNITY",COMPLEX_ROOT_UNITY; +"COMPLEX_ROOT_UNITY_EQ",COMPLEX_ROOT_UNITY_EQ; +"COMPLEX_ROOT_UNITY_EQ_1",COMPLEX_ROOT_UNITY_EQ_1; +"COMPLEX_SQNORM",COMPLEX_SQNORM; +"COMPLEX_STONE_WEIERSTRASS",COMPLEX_STONE_WEIERSTRASS; +"COMPLEX_STONE_WEIERSTRASS_ALT",COMPLEX_STONE_WEIERSTRASS_ALT; +"COMPLEX_SUB_0",COMPLEX_SUB_0; +"COMPLEX_SUB_ADD",COMPLEX_SUB_ADD; +"COMPLEX_SUB_ADD2",COMPLEX_SUB_ADD2; +"COMPLEX_SUB_CCOS",COMPLEX_SUB_CCOS; +"COMPLEX_SUB_CSIN",COMPLEX_SUB_CSIN; +"COMPLEX_SUB_CTAN",COMPLEX_SUB_CTAN; +"COMPLEX_SUB_LDISTRIB",COMPLEX_SUB_LDISTRIB; +"COMPLEX_SUB_LNEG",COMPLEX_SUB_LNEG; +"COMPLEX_SUB_LZERO",COMPLEX_SUB_LZERO; +"COMPLEX_SUB_NEG2",COMPLEX_SUB_NEG2; +"COMPLEX_SUB_POLYFUN",COMPLEX_SUB_POLYFUN; +"COMPLEX_SUB_POLYFUN_ALT",COMPLEX_SUB_POLYFUN_ALT; +"COMPLEX_SUB_POW",COMPLEX_SUB_POW; +"COMPLEX_SUB_POW_L1",COMPLEX_SUB_POW_L1; +"COMPLEX_SUB_POW_R1",COMPLEX_SUB_POW_R1; +"COMPLEX_SUB_RDISTRIB",COMPLEX_SUB_RDISTRIB; +"COMPLEX_SUB_REFL",COMPLEX_SUB_REFL; +"COMPLEX_SUB_RNEG",COMPLEX_SUB_RNEG; +"COMPLEX_SUB_RZERO",COMPLEX_SUB_RZERO; +"COMPLEX_SUB_SUB",COMPLEX_SUB_SUB; +"COMPLEX_SUB_SUB2",COMPLEX_SUB_SUB2; +"COMPLEX_SUB_TRIANGLE",COMPLEX_SUB_TRIANGLE; +"COMPLEX_TAYLOR",COMPLEX_TAYLOR; +"COMPLEX_TAYLOR_MVT",COMPLEX_TAYLOR_MVT; +"COMPLEX_TRAD",COMPLEX_TRAD; +"COMPLEX_UNIMODULAR_POLAR",COMPLEX_UNIMODULAR_POLAR; +"COMPLEX_VEC_0",COMPLEX_VEC_0; +"COMPONENT",COMPONENT; +"COMPONENTS_EQ",COMPONENTS_EQ; +"COMPONENTS_EQ_EMPTY",COMPONENTS_EQ_EMPTY; +"COMPONENTS_EQ_SING",COMPONENTS_EQ_SING; +"COMPONENTS_EQ_SING_EXISTS",COMPONENTS_EQ_SING_EXISTS; +"COMPONENTS_LINEAR_IMAGE",COMPONENTS_LINEAR_IMAGE; +"COMPONENTS_MAXIMAL",COMPONENTS_MAXIMAL; +"COMPONENTS_NONOVERLAP",COMPONENTS_NONOVERLAP; +"COMPONENTS_OPEN_UNIQUE",COMPONENTS_OPEN_UNIQUE; +"COMPONENTS_TRANSLATION",COMPONENTS_TRANSLATION; +"COMPONENTS_UNIQUE",COMPONENTS_UNIQUE; +"COMPONENTS_UNIQUE_EQ",COMPONENTS_UNIQUE_EQ; +"COMPONENT_COMPLEMENT_CONNECTED",COMPONENT_COMPLEMENT_CONNECTED; +"COMPONENT_LE_INFNORM",COMPONENT_LE_INFNORM; +"COMPONENT_LE_NORM",COMPONENT_LE_NORM; +"CONDENSATION_POINTS_EQ_EMPTY",CONDENSATION_POINTS_EQ_EMPTY; +"CONDENSATION_POINT_IMP_LIMPT",CONDENSATION_POINT_IMP_LIMPT; +"CONDENSATION_POINT_INFINITE_BALL",CONDENSATION_POINT_INFINITE_BALL; +"CONDENSATION_POINT_INFINITE_CBALL",CONDENSATION_POINT_INFINITE_CBALL; +"COND_ABS",COND_ABS; +"COND_CLAUSES",COND_CLAUSES; +"COND_COMPONENT",COND_COMPONENT; +"COND_DEF",COND_DEF; +"COND_ELIM_THM",COND_ELIM_THM; +"COND_EXPAND",COND_EXPAND; +"COND_ID",COND_ID; +"COND_RAND",COND_RAND; +"COND_RATOR",COND_RATOR; +"CONGRUENT_IMAGE_STD_SIMPLEX",CONGRUENT_IMAGE_STD_SIMPLEX; +"CONIC_CONIC_HULL",CONIC_CONIC_HULL; +"CONIC_CONTAINS_0",CONIC_CONTAINS_0; +"CONIC_CONVEX_CONE_HULL",CONIC_CONVEX_CONE_HULL; +"CONIC_EMPTY",CONIC_EMPTY; +"CONIC_HALFSPACE_GE",CONIC_HALFSPACE_GE; +"CONIC_HALFSPACE_LE",CONIC_HALFSPACE_LE; +"CONIC_HULL_EMPTY",CONIC_HULL_EMPTY; +"CONIC_HULL_EQ",CONIC_HULL_EQ; +"CONIC_HULL_EQ_EMPTY",CONIC_HULL_EQ_EMPTY; +"CONIC_HULL_EXPLICIT",CONIC_HULL_EXPLICIT; +"CONIC_HULL_LINEAR_IMAGE",CONIC_HULL_LINEAR_IMAGE; +"CONIC_HULL_SUBSET_CONVEX_CONE_HULL",CONIC_HULL_SUBSET_CONVEX_CONE_HULL; +"CONIC_INTERS",CONIC_INTERS; +"CONIC_LINEAR_IMAGE",CONIC_LINEAR_IMAGE; +"CONIC_LINEAR_IMAGE_EQ",CONIC_LINEAR_IMAGE_EQ; +"CONIC_NEGATIONS",CONIC_NEGATIONS; +"CONIC_PCROSS",CONIC_PCROSS; +"CONIC_PCROSS_EQ",CONIC_PCROSS_EQ; +"CONIC_POSITIVE_ORTHANT",CONIC_POSITIVE_ORTHANT; +"CONIC_SPAN",CONIC_SPAN; +"CONIC_SUMS",CONIC_SUMS; +"CONIC_UNIV",CONIC_UNIV; +"CONJ_ACI",CONJ_ACI; +"CONJ_ASSOC",CONJ_ASSOC; +"CONJ_SYM",CONJ_SYM; +"CONNECTED_ANNULUS",CONNECTED_ANNULUS; +"CONNECTED_ARC_COMPLEMENT",CONNECTED_ARC_COMPLEMENT; +"CONNECTED_ARC_IMAGE",CONNECTED_ARC_IMAGE; +"CONNECTED_BALL",CONNECTED_BALL; +"CONNECTED_CARD_EQ_IFF_NONTRIVIAL",CONNECTED_CARD_EQ_IFF_NONTRIVIAL; +"CONNECTED_CBALL",CONNECTED_CBALL; +"CONNECTED_CHAIN",CONNECTED_CHAIN; +"CONNECTED_CHAIN_GEN",CONNECTED_CHAIN_GEN; +"CONNECTED_CLOPEN",CONNECTED_CLOPEN; +"CONNECTED_CLOSED",CONNECTED_CLOSED; +"CONNECTED_CLOSED_IN",CONNECTED_CLOSED_IN; +"CONNECTED_CLOSED_IN_EQ",CONNECTED_CLOSED_IN_EQ; +"CONNECTED_CLOSED_SET",CONNECTED_CLOSED_SET; +"CONNECTED_CLOSURE",CONNECTED_CLOSURE; +"CONNECTED_COMPACT_INTERVAL_1",CONNECTED_COMPACT_INTERVAL_1; +"CONNECTED_COMPLEMENT_ABSOLUTE_RETRACT",CONNECTED_COMPLEMENT_ABSOLUTE_RETRACT; +"CONNECTED_COMPLEMENT_BOUNDED_CONVEX",CONNECTED_COMPLEMENT_BOUNDED_CONVEX; +"CONNECTED_COMPLEMENT_HOMEOMORPHIC_CONVEX_COMPACT",CONNECTED_COMPLEMENT_HOMEOMORPHIC_CONVEX_COMPACT; +"CONNECTED_COMPONENT_1",CONNECTED_COMPONENT_1; +"CONNECTED_COMPONENT_1_GEN",CONNECTED_COMPONENT_1_GEN; +"CONNECTED_COMPONENT_DISJOINT",CONNECTED_COMPONENT_DISJOINT; +"CONNECTED_COMPONENT_EMPTY",CONNECTED_COMPONENT_EMPTY; +"CONNECTED_COMPONENT_EQ",CONNECTED_COMPONENT_EQ; +"CONNECTED_COMPONENT_EQUIVALENCE_RELATION",CONNECTED_COMPONENT_EQUIVALENCE_RELATION; +"CONNECTED_COMPONENT_EQ_EMPTY",CONNECTED_COMPONENT_EQ_EMPTY; +"CONNECTED_COMPONENT_EQ_EQ",CONNECTED_COMPONENT_EQ_EQ; +"CONNECTED_COMPONENT_EQ_SELF",CONNECTED_COMPONENT_EQ_SELF; +"CONNECTED_COMPONENT_EQ_UNIV",CONNECTED_COMPONENT_EQ_UNIV; +"CONNECTED_COMPONENT_IDEMP",CONNECTED_COMPONENT_IDEMP; +"CONNECTED_COMPONENT_IN",CONNECTED_COMPONENT_IN; +"CONNECTED_COMPONENT_LINEAR_IMAGE",CONNECTED_COMPONENT_LINEAR_IMAGE; +"CONNECTED_COMPONENT_MAXIMAL",CONNECTED_COMPONENT_MAXIMAL; +"CONNECTED_COMPONENT_MONO",CONNECTED_COMPONENT_MONO; +"CONNECTED_COMPONENT_NONOVERLAP",CONNECTED_COMPONENT_NONOVERLAP; +"CONNECTED_COMPONENT_OF_SUBSET",CONNECTED_COMPONENT_OF_SUBSET; +"CONNECTED_COMPONENT_OVERLAP",CONNECTED_COMPONENT_OVERLAP; +"CONNECTED_COMPONENT_REFL",CONNECTED_COMPONENT_REFL; +"CONNECTED_COMPONENT_REFL_EQ",CONNECTED_COMPONENT_REFL_EQ; +"CONNECTED_COMPONENT_SET",CONNECTED_COMPONENT_SET; +"CONNECTED_COMPONENT_SUBSET",CONNECTED_COMPONENT_SUBSET; +"CONNECTED_COMPONENT_SYM",CONNECTED_COMPONENT_SYM; +"CONNECTED_COMPONENT_SYM_EQ",CONNECTED_COMPONENT_SYM_EQ; +"CONNECTED_COMPONENT_TRANS",CONNECTED_COMPONENT_TRANS; +"CONNECTED_COMPONENT_TRANSLATION",CONNECTED_COMPONENT_TRANSLATION; +"CONNECTED_COMPONENT_UNIONS",CONNECTED_COMPONENT_UNIONS; +"CONNECTED_COMPONENT_UNIQUE",CONNECTED_COMPONENT_UNIQUE; +"CONNECTED_COMPONENT_UNIV",CONNECTED_COMPONENT_UNIV; +"CONNECTED_CONNECTED_COMPONENT",CONNECTED_CONNECTED_COMPONENT; +"CONNECTED_CONNECTED_COMPONENT_SET",CONNECTED_CONNECTED_COMPONENT_SET; +"CONNECTED_CONTINUOUS_IMAGE",CONNECTED_CONTINUOUS_IMAGE; +"CONNECTED_CONVEX_1",CONNECTED_CONVEX_1; +"CONNECTED_CONVEX_1_GEN",CONNECTED_CONVEX_1_GEN; +"CONNECTED_DIFF_BALL",CONNECTED_DIFF_BALL; +"CONNECTED_DIFF_OPEN_FROM_CLOSED",CONNECTED_DIFF_OPEN_FROM_CLOSED; +"CONNECTED_DISJOINT_UNIONS_OPEN_UNIQUE",CONNECTED_DISJOINT_UNIONS_OPEN_UNIQUE; +"CONNECTED_EMPTY",CONNECTED_EMPTY; +"CONNECTED_EQUIVALENCE_RELATION",CONNECTED_EQUIVALENCE_RELATION; +"CONNECTED_EQUIVALENCE_RELATION_GEN",CONNECTED_EQUIVALENCE_RELATION_GEN; +"CONNECTED_EQ_CONNECTED_COMPONENTS_EQ",CONNECTED_EQ_CONNECTED_COMPONENTS_EQ; +"CONNECTED_EQ_CONNECTED_COMPONENT_EQ",CONNECTED_EQ_CONNECTED_COMPONENT_EQ; +"CONNECTED_FINITE_IFF_COUNTABLE",CONNECTED_FINITE_IFF_COUNTABLE; +"CONNECTED_FINITE_IFF_SING",CONNECTED_FINITE_IFF_SING; +"CONNECTED_IFF_CONNECTED_COMPONENT",CONNECTED_IFF_CONNECTED_COMPONENT; +"CONNECTED_IMP_PERFECT",CONNECTED_IMP_PERFECT; +"CONNECTED_IMP_PERFECT_AFF_DIM",CONNECTED_IMP_PERFECT_AFF_DIM; +"CONNECTED_INDUCTION",CONNECTED_INDUCTION; +"CONNECTED_INDUCTION_SIMPLE",CONNECTED_INDUCTION_SIMPLE; +"CONNECTED_INFINITE_IFF_CARD_EQ",CONNECTED_INFINITE_IFF_CARD_EQ; +"CONNECTED_INTERMEDIATE_CLOSURE",CONNECTED_INTERMEDIATE_CLOSURE; +"CONNECTED_INTERVAL",CONNECTED_INTERVAL; +"CONNECTED_INTER_FRONTIER",CONNECTED_INTER_FRONTIER; +"CONNECTED_INTER_RELATIVE_FRONTIER",CONNECTED_INTER_RELATIVE_FRONTIER; +"CONNECTED_IVT_COMPONENT",CONNECTED_IVT_COMPONENT; +"CONNECTED_IVT_HYPERPLANE",CONNECTED_IVT_HYPERPLANE; +"CONNECTED_LINEAR_IMAGE",CONNECTED_LINEAR_IMAGE; +"CONNECTED_LINEAR_IMAGE_EQ",CONNECTED_LINEAR_IMAGE_EQ; +"CONNECTED_NEGATIONS",CONNECTED_NEGATIONS; +"CONNECTED_NEST",CONNECTED_NEST; +"CONNECTED_NEST_GEN",CONNECTED_NEST_GEN; +"CONNECTED_OPEN_ARC_CONNECTED",CONNECTED_OPEN_ARC_CONNECTED; +"CONNECTED_OPEN_DELETE",CONNECTED_OPEN_DELETE; +"CONNECTED_OPEN_DIFF_CARD_LT",CONNECTED_OPEN_DIFF_CARD_LT; +"CONNECTED_OPEN_DIFF_CBALL",CONNECTED_OPEN_DIFF_CBALL; +"CONNECTED_OPEN_DIFF_COUNTABLE",CONNECTED_OPEN_DIFF_COUNTABLE; +"CONNECTED_OPEN_IN",CONNECTED_OPEN_IN; +"CONNECTED_OPEN_IN_DIFF_CARD_LT",CONNECTED_OPEN_IN_DIFF_CARD_LT; +"CONNECTED_OPEN_IN_EQ",CONNECTED_OPEN_IN_EQ; +"CONNECTED_OPEN_PATH_CONNECTED",CONNECTED_OPEN_PATH_CONNECTED; +"CONNECTED_OPEN_SET",CONNECTED_OPEN_SET; +"CONNECTED_OPEN_VECTOR_POLYNOMIAL_CONNECTED",CONNECTED_OPEN_VECTOR_POLYNOMIAL_CONNECTED; +"CONNECTED_OUTSIDE",CONNECTED_OUTSIDE; +"CONNECTED_PATH_IMAGE",CONNECTED_PATH_IMAGE; +"CONNECTED_PCROSS",CONNECTED_PCROSS; +"CONNECTED_PCROSS_EQ",CONNECTED_PCROSS_EQ; +"CONNECTED_PUNCTURED_BALL",CONNECTED_PUNCTURED_BALL; +"CONNECTED_PUNCTURED_UNIVERSE",CONNECTED_PUNCTURED_UNIVERSE; +"CONNECTED_REAL_LEMMA",CONNECTED_REAL_LEMMA; +"CONNECTED_SCALING",CONNECTED_SCALING; +"CONNECTED_SEGMENT",CONNECTED_SEGMENT; +"CONNECTED_SEMIOPEN_SEGMENT",CONNECTED_SEMIOPEN_SEGMENT; +"CONNECTED_SIMPLE_PATH_ENDLESS",CONNECTED_SIMPLE_PATH_ENDLESS; +"CONNECTED_SIMPLE_PATH_IMAGE",CONNECTED_SIMPLE_PATH_IMAGE; +"CONNECTED_SING",CONNECTED_SING; +"CONNECTED_SPHERE",CONNECTED_SPHERE; +"CONNECTED_SPHERE_EQ",CONNECTED_SPHERE_EQ; +"CONNECTED_SUMS",CONNECTED_SUMS; +"CONNECTED_TRANSLATION",CONNECTED_TRANSLATION; +"CONNECTED_TRANSLATION_EQ",CONNECTED_TRANSLATION_EQ; +"CONNECTED_UNION",CONNECTED_UNION; +"CONNECTED_UNIONS",CONNECTED_UNIONS; +"CONNECTED_UNION_CLOPEN_IN_COMPLEMENT",CONNECTED_UNION_CLOPEN_IN_COMPLEMENT; +"CONNECTED_UNION_STRONG",CONNECTED_UNION_STRONG; +"CONNECTED_UNIV",CONNECTED_UNIV; +"CONNECTED_VALID_PATH_IMAGE",CONNECTED_VALID_PATH_IMAGE; +"CONNECTED_WITH_INSIDE",CONNECTED_WITH_INSIDE; +"CONNECTED_WITH_OUTSIDE",CONNECTED_WITH_OUTSIDE; +"CONSTR",CONSTR; +"CONSTR_BOT",CONSTR_BOT; +"CONSTR_IND",CONSTR_IND; +"CONSTR_INJ",CONSTR_INJ; +"CONSTR_REC",CONSTR_REC; +"CONS_11",CONS_11; +"CONS_HD_TL",CONS_HD_TL; +"CONTENT_0_SUBSET",CONTENT_0_SUBSET; +"CONTENT_0_SUBSET_GEN",CONTENT_0_SUBSET_GEN; +"CONTENT_1",CONTENT_1; +"CONTENT_CLOSED_INTERVAL",CONTENT_CLOSED_INTERVAL; +"CONTENT_CLOSED_INTERVAL_CASES",CONTENT_CLOSED_INTERVAL_CASES; +"CONTENT_DOUBLESPLIT",CONTENT_DOUBLESPLIT; +"CONTENT_EMPTY",CONTENT_EMPTY; +"CONTENT_EQ_0",CONTENT_EQ_0; +"CONTENT_EQ_0_1",CONTENT_EQ_0_1; +"CONTENT_EQ_0_GEN",CONTENT_EQ_0_GEN; +"CONTENT_EQ_0_INTERIOR",CONTENT_EQ_0_INTERIOR; +"CONTENT_IMAGE_AFFINITY_INTERVAL",CONTENT_IMAGE_AFFINITY_INTERVAL; +"CONTENT_IMAGE_STRETCH_INTERVAL",CONTENT_IMAGE_STRETCH_INTERVAL; +"CONTENT_LT_NZ",CONTENT_LT_NZ; +"CONTENT_PASTECART",CONTENT_PASTECART; +"CONTENT_POS_LE",CONTENT_POS_LE; +"CONTENT_POS_LT",CONTENT_POS_LT; +"CONTENT_POS_LT_1",CONTENT_POS_LT_1; +"CONTENT_POS_LT_EQ",CONTENT_POS_LT_EQ; +"CONTENT_SPLIT",CONTENT_SPLIT; +"CONTENT_SUBSET",CONTENT_SUBSET; +"CONTENT_UNIT",CONTENT_UNIT; +"CONTENT_UNIT_1",CONTENT_UNIT_1; +"CONTINUOUS_ABS",CONTINUOUS_ABS; +"CONTINUOUS_ADD",CONTINUOUS_ADD; +"CONTINUOUS_ADDITIVE_IMP_LINEAR",CONTINUOUS_ADDITIVE_IMP_LINEAR; +"CONTINUOUS_AGREE_ON_CLOSURE",CONTINUOUS_AGREE_ON_CLOSURE; +"CONTINUOUS_AT",CONTINUOUS_AT; +"CONTINUOUS_ATREAL",CONTINUOUS_ATREAL; +"CONTINUOUS_ATREAL_COMPOSE",CONTINUOUS_ATREAL_COMPOSE; +"CONTINUOUS_ATREAL_SQRT_COMPOSE",CONTINUOUS_ATREAL_SQRT_COMPOSE; +"CONTINUOUS_ATREAL_WITHINREAL",CONTINUOUS_ATREAL_WITHINREAL; +"CONTINUOUS_ATTAINS_INF",CONTINUOUS_ATTAINS_INF; +"CONTINUOUS_ATTAINS_SUP",CONTINUOUS_ATTAINS_SUP; +"CONTINUOUS_AT_ARG",CONTINUOUS_AT_ARG; +"CONTINUOUS_AT_AVOID",CONTINUOUS_AT_AVOID; +"CONTINUOUS_AT_BALL",CONTINUOUS_AT_BALL; +"CONTINUOUS_AT_CACS",CONTINUOUS_AT_CACS; +"CONTINUOUS_AT_CASN",CONTINUOUS_AT_CASN; +"CONTINUOUS_AT_CATN",CONTINUOUS_AT_CATN; +"CONTINUOUS_AT_CCOS",CONTINUOUS_AT_CCOS; +"CONTINUOUS_AT_CEXP",CONTINUOUS_AT_CEXP; +"CONTINUOUS_AT_CLOG",CONTINUOUS_AT_CLOG; +"CONTINUOUS_AT_CLOSEST_POINT",CONTINUOUS_AT_CLOSEST_POINT; +"CONTINUOUS_AT_CNJ",CONTINUOUS_AT_CNJ; +"CONTINUOUS_AT_COMPOSE",CONTINUOUS_AT_COMPOSE; +"CONTINUOUS_AT_COMPOSE_EQ",CONTINUOUS_AT_COMPOSE_EQ; +"CONTINUOUS_AT_CSIN",CONTINUOUS_AT_CSIN; +"CONTINUOUS_AT_CSQRT",CONTINUOUS_AT_CSQRT; +"CONTINUOUS_AT_CTAN",CONTINUOUS_AT_CTAN; +"CONTINUOUS_AT_CX_DOT",CONTINUOUS_AT_CX_DOT; +"CONTINUOUS_AT_CX_IM",CONTINUOUS_AT_CX_IM; +"CONTINUOUS_AT_CX_NORM",CONTINUOUS_AT_CX_NORM; +"CONTINUOUS_AT_CX_RE",CONTINUOUS_AT_CX_RE; +"CONTINUOUS_AT_DIST_CLOSEST_POINT",CONTINUOUS_AT_DIST_CLOSEST_POINT; +"CONTINUOUS_AT_ID",CONTINUOUS_AT_ID; +"CONTINUOUS_AT_IMP_CONTINUOUS_ON",CONTINUOUS_AT_IMP_CONTINUOUS_ON; +"CONTINUOUS_AT_INV",CONTINUOUS_AT_INV; +"CONTINUOUS_AT_LIFT_COMPONENT",CONTINUOUS_AT_LIFT_COMPONENT; +"CONTINUOUS_AT_LIFT_DIST",CONTINUOUS_AT_LIFT_DIST; +"CONTINUOUS_AT_LIFT_DOT",CONTINUOUS_AT_LIFT_DOT; +"CONTINUOUS_AT_LIFT_INFNORM",CONTINUOUS_AT_LIFT_INFNORM; +"CONTINUOUS_AT_LIFT_NORM",CONTINUOUS_AT_LIFT_NORM; +"CONTINUOUS_AT_LIFT_RANGE",CONTINUOUS_AT_LIFT_RANGE; +"CONTINUOUS_AT_LIFT_SETDIST",CONTINUOUS_AT_LIFT_SETDIST; +"CONTINUOUS_AT_LINEAR_IMAGE",CONTINUOUS_AT_LINEAR_IMAGE; +"CONTINUOUS_AT_OPEN",CONTINUOUS_AT_OPEN; +"CONTINUOUS_AT_SEQUENTIALLY",CONTINUOUS_AT_SEQUENTIALLY; +"CONTINUOUS_AT_SQRT",CONTINUOUS_AT_SQRT; +"CONTINUOUS_AT_SQRT_COMPOSE",CONTINUOUS_AT_SQRT_COMPOSE; +"CONTINUOUS_AT_TRANSLATION",CONTINUOUS_AT_TRANSLATION; +"CONTINUOUS_AT_WINDING_NUMBER",CONTINUOUS_AT_WINDING_NUMBER; +"CONTINUOUS_AT_WITHIN",CONTINUOUS_AT_WITHIN; +"CONTINUOUS_AT_WITHIN_INV",CONTINUOUS_AT_WITHIN_INV; +"CONTINUOUS_CARD_LT_RANGE_CONSTANT",CONTINUOUS_CARD_LT_RANGE_CONSTANT; +"CONTINUOUS_CARD_LT_RANGE_CONSTANT_EQ",CONTINUOUS_CARD_LT_RANGE_CONSTANT_EQ; +"CONTINUOUS_CLOSED_IMP_CAUCHY_CONTINUOUS",CONTINUOUS_CLOSED_IMP_CAUCHY_CONTINUOUS; +"CONTINUOUS_CLOSED_IN_PREIMAGE",CONTINUOUS_CLOSED_IN_PREIMAGE; +"CONTINUOUS_CLOSED_IN_PREIMAGE_CONSTANT",CONTINUOUS_CLOSED_IN_PREIMAGE_CONSTANT; +"CONTINUOUS_CLOSED_IN_PREIMAGE_EQ",CONTINUOUS_CLOSED_IN_PREIMAGE_EQ; +"CONTINUOUS_CLOSED_IN_PREIMAGE_GEN",CONTINUOUS_CLOSED_IN_PREIMAGE_GEN; +"CONTINUOUS_CLOSED_PREIMAGE",CONTINUOUS_CLOSED_PREIMAGE; +"CONTINUOUS_CLOSED_PREIMAGE_CONSTANT",CONTINUOUS_CLOSED_PREIMAGE_CONSTANT; +"CONTINUOUS_CLOSED_PREIMAGE_UNIV",CONTINUOUS_CLOSED_PREIMAGE_UNIV; +"CONTINUOUS_CMUL",CONTINUOUS_CMUL; +"CONTINUOUS_COMPLEX_DIV",CONTINUOUS_COMPLEX_DIV; +"CONTINUOUS_COMPLEX_DIV_AT",CONTINUOUS_COMPLEX_DIV_AT; +"CONTINUOUS_COMPLEX_DIV_WITHIN",CONTINUOUS_COMPLEX_DIV_WITHIN; +"CONTINUOUS_COMPLEX_INV",CONTINUOUS_COMPLEX_INV; +"CONTINUOUS_COMPLEX_INV_AT",CONTINUOUS_COMPLEX_INV_AT; +"CONTINUOUS_COMPLEX_INV_WITHIN",CONTINUOUS_COMPLEX_INV_WITHIN; +"CONTINUOUS_COMPLEX_MUL",CONTINUOUS_COMPLEX_MUL; +"CONTINUOUS_COMPLEX_POW",CONTINUOUS_COMPLEX_POW; +"CONTINUOUS_COMPONENTWISE",CONTINUOUS_COMPONENTWISE; +"CONTINUOUS_COMPONENTWISE_LIFT",CONTINUOUS_COMPONENTWISE_LIFT; +"CONTINUOUS_CONST",CONTINUOUS_CONST; +"CONTINUOUS_CONSTANT_ON_CLOSURE",CONTINUOUS_CONSTANT_ON_CLOSURE; +"CONTINUOUS_CONTINUOUS_ATREAL",CONTINUOUS_CONTINUOUS_ATREAL; +"CONTINUOUS_CONTINUOUS_WITHINREAL",CONTINUOUS_CONTINUOUS_WITHINREAL; +"CONTINUOUS_COUNTABLE_RANGE_CONSTANT",CONTINUOUS_COUNTABLE_RANGE_CONSTANT; +"CONTINUOUS_COUNTABLE_RANGE_CONSTANT_EQ",CONTINUOUS_COUNTABLE_RANGE_CONSTANT_EQ; +"CONTINUOUS_CX_ATREAL",CONTINUOUS_CX_ATREAL; +"CONTINUOUS_CX_DROP",CONTINUOUS_CX_DROP; +"CONTINUOUS_CX_LIFT",CONTINUOUS_CX_LIFT; +"CONTINUOUS_CX_WITHINREAL",CONTINUOUS_CX_WITHINREAL; +"CONTINUOUS_DISCONNECTED_RANGE_CONSTANT",CONTINUOUS_DISCONNECTED_RANGE_CONSTANT; +"CONTINUOUS_DISCONNECTED_RANGE_CONSTANT_EQ",CONTINUOUS_DISCONNECTED_RANGE_CONSTANT_EQ; +"CONTINUOUS_DISCRETE_RANGE_CONSTANT",CONTINUOUS_DISCRETE_RANGE_CONSTANT; +"CONTINUOUS_DISCRETE_RANGE_CONSTANT_EQ",CONTINUOUS_DISCRETE_RANGE_CONSTANT_EQ; +"CONTINUOUS_FINITE_RANGE_CONSTANT",CONTINUOUS_FINITE_RANGE_CONSTANT; +"CONTINUOUS_FINITE_RANGE_CONSTANT_EQ",CONTINUOUS_FINITE_RANGE_CONSTANT_EQ; +"CONTINUOUS_GE_ON_CLOSURE",CONTINUOUS_GE_ON_CLOSURE; +"CONTINUOUS_IMAGE_SUBSET_INTERIOR",CONTINUOUS_IMAGE_SUBSET_INTERIOR; +"CONTINUOUS_IMAGE_SUBSET_RELATIVE_INTERIOR",CONTINUOUS_IMAGE_SUBSET_RELATIVE_INTERIOR; +"CONTINUOUS_IMP_CLOSED_MAP",CONTINUOUS_IMP_CLOSED_MAP; +"CONTINUOUS_IMP_MEASURABLE_ON",CONTINUOUS_IMP_MEASURABLE_ON; +"CONTINUOUS_IMP_MEASURABLE_ON_CLOSED_SUBSET",CONTINUOUS_IMP_MEASURABLE_ON_CLOSED_SUBSET; +"CONTINUOUS_IMP_MEASURABLE_ON_LEBESGUE_MEASURABLE_SUBSET",CONTINUOUS_IMP_MEASURABLE_ON_LEBESGUE_MEASURABLE_SUBSET; +"CONTINUOUS_IMP_REAL_MEASURABLE_ON",CONTINUOUS_IMP_REAL_MEASURABLE_ON; +"CONTINUOUS_INJECTIVE_IFF_MONOTONIC",CONTINUOUS_INJECTIVE_IFF_MONOTONIC; +"CONTINUOUS_INJECTIVE_IMAGE_OPEN_SEGMENT_1",CONTINUOUS_INJECTIVE_IMAGE_OPEN_SEGMENT_1; +"CONTINUOUS_INJECTIVE_IMAGE_SEGMENT_1",CONTINUOUS_INJECTIVE_IMAGE_SEGMENT_1; +"CONTINUOUS_INJECTIVE_IMAGE_SUBSPACE_DIM_LE",CONTINUOUS_INJECTIVE_IMAGE_SUBSPACE_DIM_LE; +"CONTINUOUS_INTERVAL_BIJ",CONTINUOUS_INTERVAL_BIJ; +"CONTINUOUS_INV",CONTINUOUS_INV; +"CONTINUOUS_IVT_LOCAL_EXTREMUM",CONTINUOUS_IVT_LOCAL_EXTREMUM; +"CONTINUOUS_LEFT_INVERSE_IMP_QUOTIENT_MAP",CONTINUOUS_LEFT_INVERSE_IMP_QUOTIENT_MAP; +"CONTINUOUS_LEVELSET_OPEN",CONTINUOUS_LEVELSET_OPEN; +"CONTINUOUS_LEVELSET_OPEN_IN",CONTINUOUS_LEVELSET_OPEN_IN; +"CONTINUOUS_LEVELSET_OPEN_IN_CASES",CONTINUOUS_LEVELSET_OPEN_IN_CASES; +"CONTINUOUS_LE_ON_CLOSURE",CONTINUOUS_LE_ON_CLOSURE; +"CONTINUOUS_LIFT_COMPONENT_COMPOSE",CONTINUOUS_LIFT_COMPONENT_COMPOSE; +"CONTINUOUS_LIFT_DET",CONTINUOUS_LIFT_DET; +"CONTINUOUS_LIFT_DOT2",CONTINUOUS_LIFT_DOT2; +"CONTINUOUS_LIFT_NORM_COMPOSE",CONTINUOUS_LIFT_NORM_COMPOSE; +"CONTINUOUS_LIFT_POW",CONTINUOUS_LIFT_POW; +"CONTINUOUS_LIFT_PRODUCT",CONTINUOUS_LIFT_PRODUCT; +"CONTINUOUS_LINEPATH_AT",CONTINUOUS_LINEPATH_AT; +"CONTINUOUS_LOGARITHM_ON_BALL",CONTINUOUS_LOGARITHM_ON_BALL; +"CONTINUOUS_LOGARITHM_ON_CBALL",CONTINUOUS_LOGARITHM_ON_CBALL; +"CONTINUOUS_LOGARITHM_ON_CONTRACTIBLE",CONTINUOUS_LOGARITHM_ON_CONTRACTIBLE; +"CONTINUOUS_LOGARITHM_ON_SIMPLY_CONNECTED",CONTINUOUS_LOGARITHM_ON_SIMPLY_CONNECTED; +"CONTINUOUS_MAX",CONTINUOUS_MAX; +"CONTINUOUS_MIDPOINT_CONVEX",CONTINUOUS_MIDPOINT_CONVEX; +"CONTINUOUS_MIN",CONTINUOUS_MIN; +"CONTINUOUS_MUL",CONTINUOUS_MUL; +"CONTINUOUS_NEG",CONTINUOUS_NEG; +"CONTINUOUS_ON",CONTINUOUS_ON; +"CONTINUOUS_ON_ABS",CONTINUOUS_ON_ABS; +"CONTINUOUS_ON_ADD",CONTINUOUS_ON_ADD; +"CONTINUOUS_ON_AVOID",CONTINUOUS_ON_AVOID; +"CONTINUOUS_ON_BORSUK_MAP",CONTINUOUS_ON_BORSUK_MAP; +"CONTINUOUS_ON_CACS",CONTINUOUS_ON_CACS; +"CONTINUOUS_ON_CACS_REAL",CONTINUOUS_ON_CACS_REAL; +"CONTINUOUS_ON_CASES",CONTINUOUS_ON_CASES; +"CONTINUOUS_ON_CASES_1",CONTINUOUS_ON_CASES_1; +"CONTINUOUS_ON_CASES_LE",CONTINUOUS_ON_CASES_LE; +"CONTINUOUS_ON_CASES_LOCAL",CONTINUOUS_ON_CASES_LOCAL; +"CONTINUOUS_ON_CASES_LOCAL_OPEN",CONTINUOUS_ON_CASES_LOCAL_OPEN; +"CONTINUOUS_ON_CASES_OPEN",CONTINUOUS_ON_CASES_OPEN; +"CONTINUOUS_ON_CASN",CONTINUOUS_ON_CASN; +"CONTINUOUS_ON_CASN_REAL",CONTINUOUS_ON_CASN_REAL; +"CONTINUOUS_ON_CATN",CONTINUOUS_ON_CATN; +"CONTINUOUS_ON_CCOS",CONTINUOUS_ON_CCOS; +"CONTINUOUS_ON_CEXP",CONTINUOUS_ON_CEXP; +"CONTINUOUS_ON_CLOG",CONTINUOUS_ON_CLOG; +"CONTINUOUS_ON_CLOSED",CONTINUOUS_ON_CLOSED; +"CONTINUOUS_ON_CLOSED_GEN",CONTINUOUS_ON_CLOSED_GEN; +"CONTINUOUS_ON_CLOSEST_POINT",CONTINUOUS_ON_CLOSEST_POINT; +"CONTINUOUS_ON_CLOSURE",CONTINUOUS_ON_CLOSURE; +"CONTINUOUS_ON_CLOSURE_COMPONENT_GE",CONTINUOUS_ON_CLOSURE_COMPONENT_GE; +"CONTINUOUS_ON_CLOSURE_COMPONENT_LE",CONTINUOUS_ON_CLOSURE_COMPONENT_LE; +"CONTINUOUS_ON_CLOSURE_NORM_LE",CONTINUOUS_ON_CLOSURE_NORM_LE; +"CONTINUOUS_ON_CLOSURE_SEQUENTIALLY",CONTINUOUS_ON_CLOSURE_SEQUENTIALLY; +"CONTINUOUS_ON_CMUL",CONTINUOUS_ON_CMUL; +"CONTINUOUS_ON_CNJ",CONTINUOUS_ON_CNJ; +"CONTINUOUS_ON_COMPACT_SURFACE_PROJECTION",CONTINUOUS_ON_COMPACT_SURFACE_PROJECTION; +"CONTINUOUS_ON_COMPLEX_DIV",CONTINUOUS_ON_COMPLEX_DIV; +"CONTINUOUS_ON_COMPLEX_INV",CONTINUOUS_ON_COMPLEX_INV; +"CONTINUOUS_ON_COMPLEX_LMUL",CONTINUOUS_ON_COMPLEX_LMUL; +"CONTINUOUS_ON_COMPLEX_MUL",CONTINUOUS_ON_COMPLEX_MUL; +"CONTINUOUS_ON_COMPLEX_POW",CONTINUOUS_ON_COMPLEX_POW; +"CONTINUOUS_ON_COMPLEX_RMUL",CONTINUOUS_ON_COMPLEX_RMUL; +"CONTINUOUS_ON_COMPONENTS",CONTINUOUS_ON_COMPONENTS; +"CONTINUOUS_ON_COMPONENTS_CLOSED",CONTINUOUS_ON_COMPONENTS_CLOSED; +"CONTINUOUS_ON_COMPONENTS_CLOSED_GEN",CONTINUOUS_ON_COMPONENTS_CLOSED_GEN; +"CONTINUOUS_ON_COMPONENTS_EQ",CONTINUOUS_ON_COMPONENTS_EQ; +"CONTINUOUS_ON_COMPONENTS_GEN",CONTINUOUS_ON_COMPONENTS_GEN; +"CONTINUOUS_ON_COMPONENTWISE_LIFT",CONTINUOUS_ON_COMPONENTWISE_LIFT; +"CONTINUOUS_ON_COMPOSE",CONTINUOUS_ON_COMPOSE; +"CONTINUOUS_ON_COMPOSE_ARG",CONTINUOUS_ON_COMPOSE_ARG; +"CONTINUOUS_ON_CONST",CONTINUOUS_ON_CONST; +"CONTINUOUS_ON_CONST_DYADIC_RATIONALS",CONTINUOUS_ON_CONST_DYADIC_RATIONALS; +"CONTINUOUS_ON_CSIN",CONTINUOUS_ON_CSIN; +"CONTINUOUS_ON_CSQRT",CONTINUOUS_ON_CSQRT; +"CONTINUOUS_ON_CTAN",CONTINUOUS_ON_CTAN; +"CONTINUOUS_ON_CX_DOT",CONTINUOUS_ON_CX_DOT; +"CONTINUOUS_ON_CX_DROP",CONTINUOUS_ON_CX_DROP; +"CONTINUOUS_ON_CX_IM",CONTINUOUS_ON_CX_IM; +"CONTINUOUS_ON_CX_LIFT",CONTINUOUS_ON_CX_LIFT; +"CONTINUOUS_ON_CX_NORM",CONTINUOUS_ON_CX_NORM; +"CONTINUOUS_ON_CX_RE",CONTINUOUS_ON_CX_RE; +"CONTINUOUS_ON_DIST_CLOSEST_POINT",CONTINUOUS_ON_DIST_CLOSEST_POINT; +"CONTINUOUS_ON_EMPTY",CONTINUOUS_ON_EMPTY; +"CONTINUOUS_ON_EQ",CONTINUOUS_ON_EQ; +"CONTINUOUS_ON_EQ_CONTINUOUS_AT",CONTINUOUS_ON_EQ_CONTINUOUS_AT; +"CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN",CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN; +"CONTINUOUS_ON_FINITE",CONTINUOUS_ON_FINITE; +"CONTINUOUS_ON_ID",CONTINUOUS_ON_ID; +"CONTINUOUS_ON_IMP_CLOSED_IN",CONTINUOUS_ON_IMP_CLOSED_IN; +"CONTINUOUS_ON_IMP_OPEN_IN",CONTINUOUS_ON_IMP_OPEN_IN; +"CONTINUOUS_ON_INTERIOR",CONTINUOUS_ON_INTERIOR; +"CONTINUOUS_ON_INTERVAL_BIJ",CONTINUOUS_ON_INTERVAL_BIJ; +"CONTINUOUS_ON_INV",CONTINUOUS_ON_INV; +"CONTINUOUS_ON_INVERSE",CONTINUOUS_ON_INVERSE; +"CONTINUOUS_ON_INVERSE_CLOSED_MAP",CONTINUOUS_ON_INVERSE_CLOSED_MAP; +"CONTINUOUS_ON_INVERSE_INTO_1D",CONTINUOUS_ON_INVERSE_INTO_1D; +"CONTINUOUS_ON_INVERSE_OPEN",CONTINUOUS_ON_INVERSE_OPEN; +"CONTINUOUS_ON_INVERSE_OPEN_MAP",CONTINUOUS_ON_INVERSE_OPEN_MAP; +"CONTINUOUS_ON_LIFT_COMPONENT",CONTINUOUS_ON_LIFT_COMPONENT; +"CONTINUOUS_ON_LIFT_COMPONENT_COMPOSE",CONTINUOUS_ON_LIFT_COMPONENT_COMPOSE; +"CONTINUOUS_ON_LIFT_DET",CONTINUOUS_ON_LIFT_DET; +"CONTINUOUS_ON_LIFT_DIST",CONTINUOUS_ON_LIFT_DIST; +"CONTINUOUS_ON_LIFT_DOT",CONTINUOUS_ON_LIFT_DOT; +"CONTINUOUS_ON_LIFT_DOT2",CONTINUOUS_ON_LIFT_DOT2; +"CONTINUOUS_ON_LIFT_NORM",CONTINUOUS_ON_LIFT_NORM; +"CONTINUOUS_ON_LIFT_NORM_COMPOSE",CONTINUOUS_ON_LIFT_NORM_COMPOSE; +"CONTINUOUS_ON_LIFT_POW",CONTINUOUS_ON_LIFT_POW; +"CONTINUOUS_ON_LIFT_PRODUCT",CONTINUOUS_ON_LIFT_PRODUCT; +"CONTINUOUS_ON_LIFT_RANGE",CONTINUOUS_ON_LIFT_RANGE; +"CONTINUOUS_ON_LIFT_SETDIST",CONTINUOUS_ON_LIFT_SETDIST; +"CONTINUOUS_ON_LIFT_SQRT",CONTINUOUS_ON_LIFT_SQRT; +"CONTINUOUS_ON_LIFT_SQRT_COMPOSE",CONTINUOUS_ON_LIFT_SQRT_COMPOSE; +"CONTINUOUS_ON_LINEPATH",CONTINUOUS_ON_LINEPATH; +"CONTINUOUS_ON_MAX",CONTINUOUS_ON_MAX; +"CONTINUOUS_ON_MIN",CONTINUOUS_ON_MIN; +"CONTINUOUS_ON_MUL",CONTINUOUS_ON_MUL; +"CONTINUOUS_ON_NEG",CONTINUOUS_ON_NEG; +"CONTINUOUS_ON_NO_LIMPT",CONTINUOUS_ON_NO_LIMPT; +"CONTINUOUS_ON_OPEN",CONTINUOUS_ON_OPEN; +"CONTINUOUS_ON_OPEN_AVOID",CONTINUOUS_ON_OPEN_AVOID; +"CONTINUOUS_ON_OPEN_GEN",CONTINUOUS_ON_OPEN_GEN; +"CONTINUOUS_ON_PASTECART",CONTINUOUS_ON_PASTECART; +"CONTINUOUS_ON_SEQUENTIALLY",CONTINUOUS_ON_SEQUENTIALLY; +"CONTINUOUS_ON_SING",CONTINUOUS_ON_SING; +"CONTINUOUS_ON_SUB",CONTINUOUS_ON_SUB; +"CONTINUOUS_ON_SUBSET",CONTINUOUS_ON_SUBSET; +"CONTINUOUS_ON_UNION",CONTINUOUS_ON_UNION; +"CONTINUOUS_ON_UNION_LOCAL",CONTINUOUS_ON_UNION_LOCAL; +"CONTINUOUS_ON_UNION_LOCAL_OPEN",CONTINUOUS_ON_UNION_LOCAL_OPEN; +"CONTINUOUS_ON_UNION_OPEN",CONTINUOUS_ON_UNION_OPEN; +"CONTINUOUS_ON_UPPERHALF_ARG",CONTINUOUS_ON_UPPERHALF_ARG; +"CONTINUOUS_ON_VECTOR_POLYNOMIAL_FUNCTION",CONTINUOUS_ON_VECTOR_POLYNOMIAL_FUNCTION; +"CONTINUOUS_ON_VMUL",CONTINUOUS_ON_VMUL; +"CONTINUOUS_ON_VSUM",CONTINUOUS_ON_VSUM; +"CONTINUOUS_ON_WINDING_NUMBER",CONTINUOUS_ON_WINDING_NUMBER; +"CONTINUOUS_OPEN_IN_PREIMAGE",CONTINUOUS_OPEN_IN_PREIMAGE; +"CONTINUOUS_OPEN_IN_PREIMAGE_EQ",CONTINUOUS_OPEN_IN_PREIMAGE_EQ; +"CONTINUOUS_OPEN_IN_PREIMAGE_GEN",CONTINUOUS_OPEN_IN_PREIMAGE_GEN; +"CONTINUOUS_OPEN_PREIMAGE",CONTINUOUS_OPEN_PREIMAGE; +"CONTINUOUS_OPEN_PREIMAGE_UNIV",CONTINUOUS_OPEN_PREIMAGE_UNIV; +"CONTINUOUS_PASTECART",CONTINUOUS_PASTECART; +"CONTINUOUS_REAL_CONTINUOUS_ATREAL_COMPOSE",CONTINUOUS_REAL_CONTINUOUS_ATREAL_COMPOSE; +"CONTINUOUS_REAL_CONTINUOUS_AT_COMPOSE",CONTINUOUS_REAL_CONTINUOUS_AT_COMPOSE; +"CONTINUOUS_REAL_CONTINUOUS_WITHINREAL_COMPOSE",CONTINUOUS_REAL_CONTINUOUS_WITHINREAL_COMPOSE; +"CONTINUOUS_REAL_CONTINUOUS_WITHIN_COMPOSE",CONTINUOUS_REAL_CONTINUOUS_WITHIN_COMPOSE; +"CONTINUOUS_RIGHT_INVERSE_IMP_QUOTIENT_MAP",CONTINUOUS_RIGHT_INVERSE_IMP_QUOTIENT_MAP; +"CONTINUOUS_SQRT_ON_CONTRACTIBLE",CONTINUOUS_SQRT_ON_CONTRACTIBLE; +"CONTINUOUS_SQRT_ON_SIMPLY_CONNECTED",CONTINUOUS_SQRT_ON_SIMPLY_CONNECTED; +"CONTINUOUS_SUB",CONTINUOUS_SUB; +"CONTINUOUS_TRANSFORM_AT",CONTINUOUS_TRANSFORM_AT; +"CONTINUOUS_TRANSFORM_WITHIN",CONTINUOUS_TRANSFORM_WITHIN; +"CONTINUOUS_TRIVIAL_LIMIT",CONTINUOUS_TRIVIAL_LIMIT; +"CONTINUOUS_UNIFORM_LIMIT",CONTINUOUS_UNIFORM_LIMIT; +"CONTINUOUS_VECTOR_POLYNOMIAL_FUNCTION",CONTINUOUS_VECTOR_POLYNOMIAL_FUNCTION; +"CONTINUOUS_VMUL",CONTINUOUS_VMUL; +"CONTINUOUS_VSUM",CONTINUOUS_VSUM; +"CONTINUOUS_WITHIN",CONTINUOUS_WITHIN; +"CONTINUOUS_WITHINREAL",CONTINUOUS_WITHINREAL; +"CONTINUOUS_WITHINREAL_COMPOSE",CONTINUOUS_WITHINREAL_COMPOSE; +"CONTINUOUS_WITHINREAL_SQRT_COMPOSE",CONTINUOUS_WITHINREAL_SQRT_COMPOSE; +"CONTINUOUS_WITHINREAL_SUBSET",CONTINUOUS_WITHINREAL_SUBSET; +"CONTINUOUS_WITHIN_AVOID",CONTINUOUS_WITHIN_AVOID; +"CONTINUOUS_WITHIN_BALL",CONTINUOUS_WITHIN_BALL; +"CONTINUOUS_WITHIN_CACS",CONTINUOUS_WITHIN_CACS; +"CONTINUOUS_WITHIN_CACS_REAL",CONTINUOUS_WITHIN_CACS_REAL; +"CONTINUOUS_WITHIN_CASN",CONTINUOUS_WITHIN_CASN; +"CONTINUOUS_WITHIN_CASN_REAL",CONTINUOUS_WITHIN_CASN_REAL; +"CONTINUOUS_WITHIN_CATN",CONTINUOUS_WITHIN_CATN; +"CONTINUOUS_WITHIN_CCOS",CONTINUOUS_WITHIN_CCOS; +"CONTINUOUS_WITHIN_CEXP",CONTINUOUS_WITHIN_CEXP; +"CONTINUOUS_WITHIN_CLOG",CONTINUOUS_WITHIN_CLOG; +"CONTINUOUS_WITHIN_CLOSED_NONTRIVIAL",CONTINUOUS_WITHIN_CLOSED_NONTRIVIAL; +"CONTINUOUS_WITHIN_CNJ",CONTINUOUS_WITHIN_CNJ; +"CONTINUOUS_WITHIN_COMPOSE",CONTINUOUS_WITHIN_COMPOSE; +"CONTINUOUS_WITHIN_CSIN",CONTINUOUS_WITHIN_CSIN; +"CONTINUOUS_WITHIN_CSQRT",CONTINUOUS_WITHIN_CSQRT; +"CONTINUOUS_WITHIN_CSQRT_POSREAL",CONTINUOUS_WITHIN_CSQRT_POSREAL; +"CONTINUOUS_WITHIN_CTAN",CONTINUOUS_WITHIN_CTAN; +"CONTINUOUS_WITHIN_CX_DOT",CONTINUOUS_WITHIN_CX_DOT; +"CONTINUOUS_WITHIN_CX_NORM",CONTINUOUS_WITHIN_CX_NORM; +"CONTINUOUS_WITHIN_ID",CONTINUOUS_WITHIN_ID; +"CONTINUOUS_WITHIN_LIFT_SQRT",CONTINUOUS_WITHIN_LIFT_SQRT; +"CONTINUOUS_WITHIN_OPEN",CONTINUOUS_WITHIN_OPEN; +"CONTINUOUS_WITHIN_SEQUENTIALLY",CONTINUOUS_WITHIN_SEQUENTIALLY; +"CONTINUOUS_WITHIN_SQRT_COMPOSE",CONTINUOUS_WITHIN_SQRT_COMPOSE; +"CONTINUOUS_WITHIN_SUBSET",CONTINUOUS_WITHIN_SUBSET; +"CONTINUOUS_WITHIN_UPPERHALF_ARG",CONTINUOUS_WITHIN_UPPERHALF_ARG; +"CONTRACTIBLE_CONVEX_TWEAK_BOUNDARY_POINTS",CONTRACTIBLE_CONVEX_TWEAK_BOUNDARY_POINTS; +"CONTRACTIBLE_EMPTY",CONTRACTIBLE_EMPTY; +"CONTRACTIBLE_EQ_SIMPLY_CONNECTED_2D",CONTRACTIBLE_EQ_SIMPLY_CONNECTED_2D; +"CONTRACTIBLE_IMP_CONNECTED",CONTRACTIBLE_IMP_CONNECTED; +"CONTRACTIBLE_IMP_HOLOMORPHIC_ACS",CONTRACTIBLE_IMP_HOLOMORPHIC_ACS; +"CONTRACTIBLE_IMP_HOLOMORPHIC_ACS_BOUNDED",CONTRACTIBLE_IMP_HOLOMORPHIC_ACS_BOUNDED; +"CONTRACTIBLE_IMP_HOLOMORPHIC_LOG",CONTRACTIBLE_IMP_HOLOMORPHIC_LOG; +"CONTRACTIBLE_IMP_HOLOMORPHIC_SQRT",CONTRACTIBLE_IMP_HOLOMORPHIC_SQRT; +"CONTRACTIBLE_IMP_PATH_CONNECTED",CONTRACTIBLE_IMP_PATH_CONNECTED; +"CONTRACTIBLE_IMP_SIMPLY_CONNECTED",CONTRACTIBLE_IMP_SIMPLY_CONNECTED; +"CONTRACTIBLE_IMP_UNICOHERENT",CONTRACTIBLE_IMP_UNICOHERENT; +"CONTRACTIBLE_INJECTIVE_LINEAR_IMAGE",CONTRACTIBLE_INJECTIVE_LINEAR_IMAGE; +"CONTRACTIBLE_PCROSS",CONTRACTIBLE_PCROSS; +"CONTRACTIBLE_PCROSS_EQ",CONTRACTIBLE_PCROSS_EQ; +"CONTRACTIBLE_PUNCTURED_SPHERE",CONTRACTIBLE_PUNCTURED_SPHERE; +"CONTRACTIBLE_SING",CONTRACTIBLE_SING; +"CONTRACTIBLE_SPHERE",CONTRACTIBLE_SPHERE; +"CONTRACTIBLE_TRANSLATION",CONTRACTIBLE_TRANSLATION; +"CONTRACTIBLE_UNIV",CONTRACTIBLE_UNIV; +"CONTRACTION_IMP_CONTINUOUS_ON",CONTRACTION_IMP_CONTINUOUS_ON; +"CONTRAPOS_THM",CONTRAPOS_THM; +"CONVERGENT_BOUNDED_INCREASING",CONVERGENT_BOUNDED_INCREASING; +"CONVERGENT_BOUNDED_MONOTONE",CONVERGENT_BOUNDED_MONOTONE; +"CONVERGENT_EQ_CAUCHY",CONVERGENT_EQ_CAUCHY; +"CONVERGENT_IMP_BOUNDED",CONVERGENT_IMP_BOUNDED; +"CONVERGENT_IMP_CAUCHY",CONVERGENT_IMP_CAUCHY; +"CONVEX",CONVEX; +"CONVEX_ADD",CONVEX_ADD; +"CONVEX_AFFINITY",CONVEX_AFFINITY; +"CONVEX_ALT",CONVEX_ALT; +"CONVEX_AND_AFFINE_INTER_OPEN",CONVEX_AND_AFFINE_INTER_OPEN; +"CONVEX_BALL",CONVEX_BALL; +"CONVEX_BOUNDS_LEMMA",CONVEX_BOUNDS_LEMMA; +"CONVEX_CBALL",CONVEX_CBALL; +"CONVEX_CLOSED_CONTAINS_SAME_RAY",CONVEX_CLOSED_CONTAINS_SAME_RAY; +"CONVEX_CLOSURE",CONVEX_CLOSURE; +"CONVEX_CLOSURE_INTERIOR",CONVEX_CLOSURE_INTERIOR; +"CONVEX_CLOSURE_RELATIVE_INTERIOR",CONVEX_CLOSURE_RELATIVE_INTERIOR; +"CONVEX_CMUL",CONVEX_CMUL; +"CONVEX_CONE",CONVEX_CONE; +"CONVEX_CONE_CONTAINS_0",CONVEX_CONE_CONTAINS_0; +"CONVEX_CONE_CONVEX_CONE_HULL",CONVEX_CONE_CONVEX_CONE_HULL; +"CONVEX_CONE_HALFSPACE_GE",CONVEX_CONE_HALFSPACE_GE; +"CONVEX_CONE_HALFSPACE_LE",CONVEX_CONE_HALFSPACE_LE; +"CONVEX_CONE_HULL_ADD",CONVEX_CONE_HULL_ADD; +"CONVEX_CONE_HULL_CONTAINS_0",CONVEX_CONE_HULL_CONTAINS_0; +"CONVEX_CONE_HULL_CONVEX_HULL",CONVEX_CONE_HULL_CONVEX_HULL; +"CONVEX_CONE_HULL_CONVEX_HULL_NONEMPTY",CONVEX_CONE_HULL_CONVEX_HULL_NONEMPTY; +"CONVEX_CONE_HULL_EMPTY",CONVEX_CONE_HULL_EMPTY; +"CONVEX_CONE_HULL_LINEAR_IMAGE",CONVEX_CONE_HULL_LINEAR_IMAGE; +"CONVEX_CONE_HULL_MUL",CONVEX_CONE_HULL_MUL; +"CONVEX_CONE_HULL_NONEMPTY",CONVEX_CONE_HULL_NONEMPTY; +"CONVEX_CONE_HULL_SEPARATE",CONVEX_CONE_HULL_SEPARATE; +"CONVEX_CONE_HULL_SEPARATE_NONEMPTY",CONVEX_CONE_HULL_SEPARATE_NONEMPTY; +"CONVEX_CONE_HULL_UNION",CONVEX_CONE_HULL_UNION; +"CONVEX_CONE_INTERS",CONVEX_CONE_INTERS; +"CONVEX_CONE_LINEAR_IMAGE",CONVEX_CONE_LINEAR_IMAGE; +"CONVEX_CONE_LINEAR_IMAGE_EQ",CONVEX_CONE_LINEAR_IMAGE_EQ; +"CONVEX_CONE_NEGATIONS",CONVEX_CONE_NEGATIONS; +"CONVEX_CONE_PCROSS",CONVEX_CONE_PCROSS; +"CONVEX_CONE_PCROSS_EQ",CONVEX_CONE_PCROSS_EQ; +"CONVEX_CONE_SING",CONVEX_CONE_SING; +"CONVEX_CONE_SPAN",CONVEX_CONE_SPAN; +"CONVEX_CONE_SUMS",CONVEX_CONE_SUMS; +"CONVEX_CONIC_HULL",CONVEX_CONIC_HULL; +"CONVEX_CONNECTED",CONVEX_CONNECTED; +"CONVEX_CONNECTED_1",CONVEX_CONNECTED_1; +"CONVEX_CONNECTED_1_GEN",CONVEX_CONNECTED_1_GEN; +"CONVEX_CONTAINS_SEGMENT",CONVEX_CONTAINS_SEGMENT; +"CONVEX_CONTAINS_SEGMENT_EQ",CONVEX_CONTAINS_SEGMENT_EQ; +"CONVEX_CONTAINS_SEGMENT_IMP",CONVEX_CONTAINS_SEGMENT_IMP; +"CONVEX_CONVEX_CONE_HULL",CONVEX_CONVEX_CONE_HULL; +"CONVEX_CONVEX_HULL",CONVEX_CONVEX_HULL; +"CONVEX_DIFFERENCES",CONVEX_DIFFERENCES; +"CONVEX_DISTANCE",CONVEX_DISTANCE; +"CONVEX_EMPTY",CONVEX_EMPTY; +"CONVEX_EPIGRAPH",CONVEX_EPIGRAPH; +"CONVEX_EPIGRAPH_CONVEX",CONVEX_EPIGRAPH_CONVEX; +"CONVEX_EXPLICIT",CONVEX_EXPLICIT; +"CONVEX_FINITE",CONVEX_FINITE; +"CONVEX_HALFSPACE_COMPONENT_GE",CONVEX_HALFSPACE_COMPONENT_GE; +"CONVEX_HALFSPACE_COMPONENT_GT",CONVEX_HALFSPACE_COMPONENT_GT; +"CONVEX_HALFSPACE_COMPONENT_LE",CONVEX_HALFSPACE_COMPONENT_LE; +"CONVEX_HALFSPACE_COMPONENT_LT",CONVEX_HALFSPACE_COMPONENT_LT; +"CONVEX_HALFSPACE_GE",CONVEX_HALFSPACE_GE; +"CONVEX_HALFSPACE_GT",CONVEX_HALFSPACE_GT; +"CONVEX_HALFSPACE_IM_GE",CONVEX_HALFSPACE_IM_GE; +"CONVEX_HALFSPACE_IM_GT",CONVEX_HALFSPACE_IM_GT; +"CONVEX_HALFSPACE_IM_LE",CONVEX_HALFSPACE_IM_LE; +"CONVEX_HALFSPACE_IM_LT",CONVEX_HALFSPACE_IM_LT; +"CONVEX_HALFSPACE_INTERSECTION",CONVEX_HALFSPACE_INTERSECTION; +"CONVEX_HALFSPACE_LE",CONVEX_HALFSPACE_LE; +"CONVEX_HALFSPACE_LT",CONVEX_HALFSPACE_LT; +"CONVEX_HALFSPACE_RE_GE",CONVEX_HALFSPACE_RE_GE; +"CONVEX_HALFSPACE_RE_GT",CONVEX_HALFSPACE_RE_GT; +"CONVEX_HALFSPACE_RE_LE",CONVEX_HALFSPACE_RE_LE; +"CONVEX_HALFSPACE_RE_LT",CONVEX_HALFSPACE_RE_LT; +"CONVEX_HULLS_EQ",CONVEX_HULLS_EQ; +"CONVEX_HULL_2",CONVEX_HULL_2; +"CONVEX_HULL_2_ALT",CONVEX_HULL_2_ALT; +"CONVEX_HULL_3",CONVEX_HULL_3; +"CONVEX_HULL_3_ALT",CONVEX_HULL_3_ALT; +"CONVEX_HULL_AFFINITY",CONVEX_HULL_AFFINITY; +"CONVEX_HULL_CARATHEODORY",CONVEX_HULL_CARATHEODORY; +"CONVEX_HULL_CARATHEODORY_AFF_DIM",CONVEX_HULL_CARATHEODORY_AFF_DIM; +"CONVEX_HULL_EMPTY",CONVEX_HULL_EMPTY; +"CONVEX_HULL_EQ",CONVEX_HULL_EQ; +"CONVEX_HULL_EQ_EMPTY",CONVEX_HULL_EQ_EMPTY; +"CONVEX_HULL_EQ_SING",CONVEX_HULL_EQ_SING; +"CONVEX_HULL_EXCHANGE_INTER",CONVEX_HULL_EXCHANGE_INTER; +"CONVEX_HULL_EXCHANGE_UNION",CONVEX_HULL_EXCHANGE_UNION; +"CONVEX_HULL_EXPLICIT",CONVEX_HULL_EXPLICIT; +"CONVEX_HULL_FINITE",CONVEX_HULL_FINITE; +"CONVEX_HULL_FINITE_STEP",CONVEX_HULL_FINITE_STEP; +"CONVEX_HULL_INDEXED",CONVEX_HULL_INDEXED; +"CONVEX_HULL_INSERT",CONVEX_HULL_INSERT; +"CONVEX_HULL_INSERT_ALT",CONVEX_HULL_INSERT_ALT; +"CONVEX_HULL_INTER",CONVEX_HULL_INTER; +"CONVEX_HULL_INTERS",CONVEX_HULL_INTERS; +"CONVEX_HULL_LINEAR_IMAGE",CONVEX_HULL_LINEAR_IMAGE; +"CONVEX_HULL_PCROSS",CONVEX_HULL_PCROSS; +"CONVEX_HULL_SCALING",CONVEX_HULL_SCALING; +"CONVEX_HULL_SING",CONVEX_HULL_SING; +"CONVEX_HULL_SUBSET",CONVEX_HULL_SUBSET; +"CONVEX_HULL_SUBSET_AFFINE_HULL",CONVEX_HULL_SUBSET_AFFINE_HULL; +"CONVEX_HULL_SUBSET_CONVEX_CONE_HULL",CONVEX_HULL_SUBSET_CONVEX_CONE_HULL; +"CONVEX_HULL_SUBSET_SPAN",CONVEX_HULL_SUBSET_SPAN; +"CONVEX_HULL_SUMS",CONVEX_HULL_SUMS; +"CONVEX_HULL_TRANSLATION",CONVEX_HULL_TRANSLATION; +"CONVEX_HULL_UNION_EXPLICIT",CONVEX_HULL_UNION_EXPLICIT; +"CONVEX_HULL_UNION_NONEMPTY_EXPLICIT",CONVEX_HULL_UNION_NONEMPTY_EXPLICIT; +"CONVEX_HULL_UNION_UNIONS",CONVEX_HULL_UNION_UNIONS; +"CONVEX_HULL_UNIV",CONVEX_HULL_UNIV; +"CONVEX_HYPERPLANE",CONVEX_HYPERPLANE; +"CONVEX_IMP_CONTRACTIBLE",CONVEX_IMP_CONTRACTIBLE; +"CONVEX_IMP_LOCALLY_CONNECTED",CONVEX_IMP_LOCALLY_CONNECTED; +"CONVEX_IMP_LOCALLY_PATH_CONNECTED",CONVEX_IMP_LOCALLY_PATH_CONNECTED; +"CONVEX_IMP_PATH_CONNECTED",CONVEX_IMP_PATH_CONNECTED; +"CONVEX_IMP_SIMPLY_CONNECTED",CONVEX_IMP_SIMPLY_CONNECTED; +"CONVEX_IMP_STARLIKE",CONVEX_IMP_STARLIKE; +"CONVEX_IMP_UNICOHERENT",CONVEX_IMP_UNICOHERENT; +"CONVEX_INDEXED",CONVEX_INDEXED; +"CONVEX_INTER",CONVEX_INTER; +"CONVEX_INTERIOR",CONVEX_INTERIOR; +"CONVEX_INTERIOR_CLOSURE",CONVEX_INTERIOR_CLOSURE; +"CONVEX_INTERS",CONVEX_INTERS; +"CONVEX_INTERVAL",CONVEX_INTERVAL; +"CONVEX_LINEAR_IMAGE",CONVEX_LINEAR_IMAGE; +"CONVEX_LINEAR_IMAGE_EQ",CONVEX_LINEAR_IMAGE_EQ; +"CONVEX_LINEAR_PREIMAGE",CONVEX_LINEAR_PREIMAGE; +"CONVEX_LOCAL_GLOBAL_MINIMUM",CONVEX_LOCAL_GLOBAL_MINIMUM; +"CONVEX_LOWER",CONVEX_LOWER; +"CONVEX_LOWER_SEGMENT",CONVEX_LOWER_SEGMENT; +"CONVEX_MAX",CONVEX_MAX; +"CONVEX_NEGATIONS",CONVEX_NEGATIONS; +"CONVEX_NORM",CONVEX_NORM; +"CONVEX_ON_BOUNDED_CONTINUOUS",CONVEX_ON_BOUNDED_CONTINUOUS; +"CONVEX_ON_COMPOSE_LINEAR",CONVEX_ON_COMPOSE_LINEAR; +"CONVEX_ON_CONTINUOUS",CONVEX_ON_CONTINUOUS; +"CONVEX_ON_CONVEX_HULL_BOUND",CONVEX_ON_CONVEX_HULL_BOUND; +"CONVEX_ON_DERIVATIVES",CONVEX_ON_DERIVATIVES; +"CONVEX_ON_DERIVATIVES_IMP",CONVEX_ON_DERIVATIVES_IMP; +"CONVEX_ON_DERIVATIVE_SECANT",CONVEX_ON_DERIVATIVE_SECANT; +"CONVEX_ON_DERIVATIVE_SECANT_IMP",CONVEX_ON_DERIVATIVE_SECANT_IMP; +"CONVEX_ON_EPIGRAPH_SLICE_LE",CONVEX_ON_EPIGRAPH_SLICE_LE; +"CONVEX_ON_EPIGRAPH_SLICE_LT",CONVEX_ON_EPIGRAPH_SLICE_LT; +"CONVEX_ON_JENSEN",CONVEX_ON_JENSEN; +"CONVEX_ON_LEFT_SECANT",CONVEX_ON_LEFT_SECANT; +"CONVEX_ON_LEFT_SECANT_MUL",CONVEX_ON_LEFT_SECANT_MUL; +"CONVEX_ON_RIGHT_SECANT",CONVEX_ON_RIGHT_SECANT; +"CONVEX_ON_RIGHT_SECANT_MUL",CONVEX_ON_RIGHT_SECANT_MUL; +"CONVEX_ON_SECANT_DERIVATIVE",CONVEX_ON_SECANT_DERIVATIVE; +"CONVEX_ON_SECANT_DERIVATIVE_IMP",CONVEX_ON_SECANT_DERIVATIVE_IMP; +"CONVEX_ON_SUBSET",CONVEX_ON_SUBSET; +"CONVEX_ON_TRANSLATION",CONVEX_ON_TRANSLATION; +"CONVEX_PCROSS",CONVEX_PCROSS; +"CONVEX_PCROSS_EQ",CONVEX_PCROSS_EQ; +"CONVEX_POSITIVE_ORTHANT",CONVEX_POSITIVE_ORTHANT; +"CONVEX_REAL",CONVEX_REAL; +"CONVEX_RELATIVE_INTERIOR",CONVEX_RELATIVE_INTERIOR; +"CONVEX_RELATIVE_INTERIOR_CLOSURE",CONVEX_RELATIVE_INTERIOR_CLOSURE; +"CONVEX_SAME_RELATIVE_INTERIOR_CLOSURE",CONVEX_SAME_RELATIVE_INTERIOR_CLOSURE; +"CONVEX_SAME_RELATIVE_INTERIOR_CLOSURE_STRADDLE",CONVEX_SAME_RELATIVE_INTERIOR_CLOSURE_STRADDLE; +"CONVEX_SCALING",CONVEX_SCALING; +"CONVEX_SCALING_EQ",CONVEX_SCALING_EQ; +"CONVEX_SEGMENT",CONVEX_SEGMENT; +"CONVEX_SEMIOPEN_SEGMENT",CONVEX_SEMIOPEN_SEGMENT; +"CONVEX_SIMPLEX",CONVEX_SIMPLEX; +"CONVEX_SING",CONVEX_SING; +"CONVEX_SLICE",CONVEX_SLICE; +"CONVEX_SPAN",CONVEX_SPAN; +"CONVEX_STANDARD_HYPERPLANE",CONVEX_STANDARD_HYPERPLANE; +"CONVEX_SUMS",CONVEX_SUMS; +"CONVEX_TRANSLATION",CONVEX_TRANSLATION; +"CONVEX_TRANSLATION_EQ",CONVEX_TRANSLATION_EQ; +"CONVEX_UNIV",CONVEX_UNIV; +"CONVEX_VSUM",CONVEX_VSUM; +"CONVEX_VSUM_STRONG",CONVEX_VSUM_STRONG; +"COPLANAR_2",COPLANAR_2; +"COPLANAR_3",COPLANAR_3; +"COPLANAR_AFFINE_HULL_COPLANAR",COPLANAR_AFFINE_HULL_COPLANAR; +"COPLANAR_EMPTY",COPLANAR_EMPTY; +"COPLANAR_LINEAR_IMAGE",COPLANAR_LINEAR_IMAGE; +"COPLANAR_LINEAR_IMAGE_EQ",COPLANAR_LINEAR_IMAGE_EQ; +"COPLANAR_SING",COPLANAR_SING; +"COPLANAR_SMALL",COPLANAR_SMALL; +"COPLANAR_SUBSET",COPLANAR_SUBSET; +"COPLANAR_TRANSLATION",COPLANAR_TRANSLATION; +"COPLANAR_TRANSLATION_EQ",COPLANAR_TRANSLATION_EQ; +"COSMALL_APPROXIMATION",COSMALL_APPROXIMATION; +"COS_0",COS_0; +"COS_ABS",COS_ABS; +"COS_ACS",COS_ACS; +"COS_ADD",COS_ADD; +"COS_ASN",COS_ASN; +"COS_ASN_NZ",COS_ASN_NZ; +"COS_ATN",COS_ATN; +"COS_ATN_NZ",COS_ATN_NZ; +"COS_BOUND",COS_BOUND; +"COS_BOUNDS",COS_BOUNDS; +"COS_DOUBLE",COS_DOUBLE; +"COS_DOUBLE_BOUND",COS_DOUBLE_BOUND; +"COS_DOUBLE_COS",COS_DOUBLE_COS; +"COS_DOUBLE_SIN",COS_DOUBLE_SIN; +"COS_EQ",COS_EQ; +"COS_EQ_0",COS_EQ_0; +"COS_EQ_1",COS_EQ_1; +"COS_EQ_MINUS1",COS_EQ_MINUS1; +"COS_GOESNEGATIVE",COS_GOESNEGATIVE; +"COS_GOESNEGATIVE_LEMMA",COS_GOESNEGATIVE_LEMMA; +"COS_HASZERO",COS_HASZERO; +"COS_INJ_PI",COS_INJ_PI; +"COS_INTEGER_2PI",COS_INTEGER_2PI; +"COS_MONO_LE",COS_MONO_LE; +"COS_MONO_LE_EQ",COS_MONO_LE_EQ; +"COS_MONO_LT",COS_MONO_LT; +"COS_MONO_LT_EQ",COS_MONO_LT_EQ; +"COS_NEG",COS_NEG; +"COS_NONTRIVIAL",COS_NONTRIVIAL; +"COS_NPI",COS_NPI; +"COS_ONE_2PI",COS_ONE_2PI; +"COS_PERIODIC",COS_PERIODIC; +"COS_PERIODIC_PI",COS_PERIODIC_PI; +"COS_PI",COS_PI; +"COS_PI2",COS_PI2; +"COS_PI6",COS_PI6; +"COS_POS_PI",COS_POS_PI; +"COS_POS_PI2",COS_POS_PI2; +"COS_POS_PI_LE",COS_POS_PI_LE; +"COS_SIN",COS_SIN; +"COS_SUB",COS_SUB; +"COS_TAN",COS_TAN; +"COS_TREBLE_COS",COS_TREBLE_COS; +"COS_ZERO",COS_ZERO; +"COS_ZERO_PI",COS_ZERO_PI; +"COUNTABLE",COUNTABLE; +"COUNTABLE_ALT",COUNTABLE_ALT; +"COUNTABLE_AS_IMAGE",COUNTABLE_AS_IMAGE; +"COUNTABLE_AS_IMAGE_SUBSET",COUNTABLE_AS_IMAGE_SUBSET; +"COUNTABLE_AS_IMAGE_SUBSET_EQ",COUNTABLE_AS_IMAGE_SUBSET_EQ; +"COUNTABLE_AS_INJECTIVE_IMAGE",COUNTABLE_AS_INJECTIVE_IMAGE; +"COUNTABLE_CARD_MUL",COUNTABLE_CARD_MUL; +"COUNTABLE_CARD_MUL_EQ",COUNTABLE_CARD_MUL_EQ; +"COUNTABLE_CART",COUNTABLE_CART; +"COUNTABLE_CASES",COUNTABLE_CASES; +"COUNTABLE_COMPONENTS",COUNTABLE_COMPONENTS; +"COUNTABLE_CROSS",COUNTABLE_CROSS; +"COUNTABLE_DELETE",COUNTABLE_DELETE; +"COUNTABLE_DIFF_FINITE",COUNTABLE_DIFF_FINITE; +"COUNTABLE_DISJOINT_OPEN_SUBSETS",COUNTABLE_DISJOINT_OPEN_SUBSETS; +"COUNTABLE_ELEMENTARY_DIVISION",COUNTABLE_ELEMENTARY_DIVISION; +"COUNTABLE_EMPTY",COUNTABLE_EMPTY; +"COUNTABLE_EMPTY_INTERIOR",COUNTABLE_EMPTY_INTERIOR; +"COUNTABLE_FINITE_SUBSETS",COUNTABLE_FINITE_SUBSETS; +"COUNTABLE_IMAGE",COUNTABLE_IMAGE; +"COUNTABLE_IMAGE_INJ",COUNTABLE_IMAGE_INJ; +"COUNTABLE_IMAGE_INJ_EQ",COUNTABLE_IMAGE_INJ_EQ; +"COUNTABLE_IMAGE_INJ_GENERAL",COUNTABLE_IMAGE_INJ_GENERAL; +"COUNTABLE_IMP_CARD_LT_REAL",COUNTABLE_IMP_CARD_LT_REAL; +"COUNTABLE_IMP_DISCONNECTED",COUNTABLE_IMP_DISCONNECTED; +"COUNTABLE_INSERT",COUNTABLE_INSERT; +"COUNTABLE_INTEGER",COUNTABLE_INTEGER; +"COUNTABLE_INTEGER_COORDINATES",COUNTABLE_INTEGER_COORDINATES; +"COUNTABLE_INTER",COUNTABLE_INTER; +"COUNTABLE_LIST",COUNTABLE_LIST; +"COUNTABLE_LIST_GEN",COUNTABLE_LIST_GEN; +"COUNTABLE_NON_CONDENSATION_POINTS",COUNTABLE_NON_CONDENSATION_POINTS; +"COUNTABLE_OPEN_INTERVAL",COUNTABLE_OPEN_INTERVAL; +"COUNTABLE_PCROSS",COUNTABLE_PCROSS; +"COUNTABLE_PCROSS_EQ",COUNTABLE_PCROSS_EQ; +"COUNTABLE_PRODUCT_DEPENDENT",COUNTABLE_PRODUCT_DEPENDENT; +"COUNTABLE_RATIONAL",COUNTABLE_RATIONAL; +"COUNTABLE_RATIONAL_COORDINATES",COUNTABLE_RATIONAL_COORDINATES; +"COUNTABLE_RESTRICT",COUNTABLE_RESTRICT; +"COUNTABLE_SING",COUNTABLE_SING; +"COUNTABLE_SUBSET",COUNTABLE_SUBSET; +"COUNTABLE_SUBSET_IMAGE",COUNTABLE_SUBSET_IMAGE; +"COUNTABLE_UNION",COUNTABLE_UNION; +"COUNTABLE_UNIONS",COUNTABLE_UNIONS; +"COUNTABLE_UNION_IMP",COUNTABLE_UNION_IMP; +"COVERING_LEMMA",COVERING_LEMMA; +"COVERING_SPACE_CEXP_PUNCTURED_PLANE",COVERING_SPACE_CEXP_PUNCTURED_PLANE; +"COVERING_SPACE_CLOSED_MAP",COVERING_SPACE_CLOSED_MAP; +"COVERING_SPACE_COMPACT",COVERING_SPACE_COMPACT; +"COVERING_SPACE_COUNTABLE_SHEETS",COVERING_SPACE_COUNTABLE_SHEETS; +"COVERING_SPACE_FIBRE_NO_LIMPT",COVERING_SPACE_FIBRE_NO_LIMPT; +"COVERING_SPACE_FINITE_EQ_COMPACT_FIBRE",COVERING_SPACE_FINITE_EQ_COMPACT_FIBRE; +"COVERING_SPACE_FINITE_SHEETS",COVERING_SPACE_FINITE_SHEETS; +"COVERING_SPACE_FINITE_SHEETS_EQ_CLOSED_MAP",COVERING_SPACE_FINITE_SHEETS_EQ_CLOSED_MAP; +"COVERING_SPACE_FINITE_SHEETS_EQ_CLOSED_MAP_STRONG",COVERING_SPACE_FINITE_SHEETS_EQ_CLOSED_MAP_STRONG; +"COVERING_SPACE_FINITE_SHEETS_EQ_PROPER_MAP",COVERING_SPACE_FINITE_SHEETS_EQ_PROPER_MAP; +"COVERING_SPACE_HOMEOMORPHISM",COVERING_SPACE_HOMEOMORPHISM; +"COVERING_SPACE_IMP_CONTINUOUS",COVERING_SPACE_IMP_CONTINUOUS; +"COVERING_SPACE_IMP_SURJECTIVE",COVERING_SPACE_IMP_SURJECTIVE; +"COVERING_SPACE_INESSENTIAL_LOOP_LIFT_IS_LOOP",COVERING_SPACE_INESSENTIAL_LOOP_LIFT_IS_LOOP; +"COVERING_SPACE_INJECTIVE",COVERING_SPACE_INJECTIVE; +"COVERING_SPACE_LIFT",COVERING_SPACE_LIFT; +"COVERING_SPACE_LIFT_GENERAL",COVERING_SPACE_LIFT_GENERAL; +"COVERING_SPACE_LIFT_HOLOMORPHIC",COVERING_SPACE_LIFT_HOLOMORPHIC; +"COVERING_SPACE_LIFT_HOMOTOPIC_FUNCTION",COVERING_SPACE_LIFT_HOMOTOPIC_FUNCTION; +"COVERING_SPACE_LIFT_HOMOTOPIC_PATH",COVERING_SPACE_LIFT_HOMOTOPIC_PATH; +"COVERING_SPACE_LIFT_HOMOTOPIC_PATHS",COVERING_SPACE_LIFT_HOMOTOPIC_PATHS; +"COVERING_SPACE_LIFT_HOMOTOPY",COVERING_SPACE_LIFT_HOMOTOPY; +"COVERING_SPACE_LIFT_HOMOTOPY_ALT",COVERING_SPACE_LIFT_HOMOTOPY_ALT; +"COVERING_SPACE_LIFT_INESSENTIAL_FUNCTION",COVERING_SPACE_LIFT_INESSENTIAL_FUNCTION; +"COVERING_SPACE_LIFT_IS_HOLOMORPHIC",COVERING_SPACE_LIFT_IS_HOLOMORPHIC; +"COVERING_SPACE_LIFT_PATH",COVERING_SPACE_LIFT_PATH; +"COVERING_SPACE_LIFT_PATH_STRONG",COVERING_SPACE_LIFT_PATH_STRONG; +"COVERING_SPACE_LIFT_STRONG",COVERING_SPACE_LIFT_STRONG; +"COVERING_SPACE_LIFT_STRONGER",COVERING_SPACE_LIFT_STRONGER; +"COVERING_SPACE_LIFT_UNIQUE",COVERING_SPACE_LIFT_UNIQUE; +"COVERING_SPACE_LIFT_UNIQUE_GEN",COVERING_SPACE_LIFT_UNIQUE_GEN; +"COVERING_SPACE_LIFT_UNIQUE_IDENTITY",COVERING_SPACE_LIFT_UNIQUE_IDENTITY; +"COVERING_SPACE_LOCALLY",COVERING_SPACE_LOCALLY; +"COVERING_SPACE_LOCALLY_CONNECTED",COVERING_SPACE_LOCALLY_CONNECTED; +"COVERING_SPACE_LOCALLY_PATH_CONNECTED",COVERING_SPACE_LOCALLY_PATH_CONNECTED; +"COVERING_SPACE_LOCAL_HOMEOMORPHISM",COVERING_SPACE_LOCAL_HOMEOMORPHISM; +"COVERING_SPACE_LOCAL_HOMEOMORPHISM_ALT",COVERING_SPACE_LOCAL_HOMEOMORPHISM_ALT; +"COVERING_SPACE_MONODROMY",COVERING_SPACE_MONODROMY; +"COVERING_SPACE_OPEN_MAP",COVERING_SPACE_OPEN_MAP; +"COVERING_SPACE_POW_PUNCTURED_PLANE",COVERING_SPACE_POW_PUNCTURED_PLANE; +"COVERING_SPACE_QUOTIENT_MAP",COVERING_SPACE_QUOTIENT_MAP; +"COVERING_SPACE_SIMPLY_CONNECTED_LOOP_LIFT_IS_LOOP",COVERING_SPACE_SIMPLY_CONNECTED_LOOP_LIFT_IS_LOOP; +"COVERING_SPACE_SQUARE_PUNCTURED_PLANE",COVERING_SPACE_SQUARE_PUNCTURED_PLANE; +"CPOW_0",CPOW_0; +"CPOW_1",CPOW_1; +"CPOW_ADD",CPOW_ADD; +"CPOW_EQ_0",CPOW_EQ_0; +"CPOW_MUL_REAL",CPOW_MUL_REAL; +"CPOW_N",CPOW_N; +"CPOW_NEG",CPOW_NEG; +"CPOW_REAL_REAL",CPOW_REAL_REAL; +"CPOW_SUB",CPOW_SUB; +"CPRODUCT_1",CPRODUCT_1; +"CPRODUCT_CLAUSES",CPRODUCT_CLAUSES; +"CPRODUCT_EQ",CPRODUCT_EQ; +"CPRODUCT_EQ_0",CPRODUCT_EQ_0; +"CPRODUCT_EQ_1",CPRODUCT_EQ_1; +"CPRODUCT_INV",CPRODUCT_INV; +"CPRODUCT_MUL",CPRODUCT_MUL; +"CPRODUCT_POW",CPRODUCT_POW; +"CRAMER",CRAMER; +"CRAMER_LEMMA",CRAMER_LEMMA; +"CRAMER_LEMMA_TRANSP",CRAMER_LEMMA_TRANSP; +"CRAMER_MATRIX_LEFT",CRAMER_MATRIX_LEFT; +"CRAMER_MATRIX_LEFT_INVERSE",CRAMER_MATRIX_LEFT_INVERSE; +"CRAMER_MATRIX_RIGHT",CRAMER_MATRIX_RIGHT; +"CRAMER_MATRIX_RIGHT_INVERSE",CRAMER_MATRIX_RIGHT_INVERSE; +"CROSS",CROSS; +"CROSS_EQ_EMPTY",CROSS_EQ_EMPTY; +"CSIN_0",CSIN_0; +"CSIN_ADD",CSIN_ADD; +"CSIN_CACS",CSIN_CACS; +"CSIN_CACS_NZ",CSIN_CACS_NZ; +"CSIN_CASN",CSIN_CASN; +"CSIN_CCOS_CSQRT",CSIN_CCOS_CSQRT; +"CSIN_CIRCLE",CSIN_CIRCLE; +"CSIN_DOUBLE",CSIN_DOUBLE; +"CSIN_EQ",CSIN_EQ; +"CSIN_EQ_0",CSIN_EQ_0; +"CSIN_EQ_1",CSIN_EQ_1; +"CSIN_EQ_MINUS1",CSIN_EQ_MINUS1; +"CSIN_NEG",CSIN_NEG; +"CSIN_SUB",CSIN_SUB; +"CSQRT",CSQRT; +"CSQRT_0",CSQRT_0; +"CSQRT_1",CSQRT_1; +"CSQRT_CEXP_CLOG",CSQRT_CEXP_CLOG; +"CSQRT_CX",CSQRT_CX; +"CSQRT_EQ_0",CSQRT_EQ_0; +"CSQRT_PRINCIPAL",CSQRT_PRINCIPAL; +"CSQRT_UNIQUE",CSQRT_UNIQUE; +"CTAN_0",CTAN_0; +"CTAN_ADD",CTAN_ADD; +"CTAN_CATN",CTAN_CATN; +"CTAN_DOUBLE",CTAN_DOUBLE; +"CTAN_NEG",CTAN_NEG; +"CTAN_SUB",CTAN_SUB; +"CURRY_DEF",CURRY_DEF; +"CX_2PII_NZ",CX_2PII_NZ; +"CX_ABS",CX_ABS; +"CX_ACS",CX_ACS; +"CX_ADD",CX_ADD; +"CX_ASN",CX_ASN; +"CX_ATN",CX_ATN; +"CX_COS",CX_COS; +"CX_COSH",CX_COSH; +"CX_DEF",CX_DEF; +"CX_DIV",CX_DIV; +"CX_EXP",CX_EXP; +"CX_IM_CNJ",CX_IM_CNJ; +"CX_INJ",CX_INJ; +"CX_INV",CX_INV; +"CX_LOG",CX_LOG; +"CX_MUL",CX_MUL; +"CX_NEG",CX_NEG; +"CX_PI_NZ",CX_PI_NZ; +"CX_POW",CX_POW; +"CX_RE_CNJ",CX_RE_CNJ; +"CX_SIN",CX_SIN; +"CX_SINH",CX_SINH; +"CX_SQRT",CX_SQRT; +"CX_SUB",CX_SUB; +"CX_TAN",CX_TAN; +"DECIMAL",DECIMAL; +"DECOMPOSITION",DECOMPOSITION; +"DECREASING_BOUNDED_VARIATION",DECREASING_BOUNDED_VARIATION; +"DECREASING_CLOSED_NEST",DECREASING_CLOSED_NEST; +"DECREASING_CLOSED_NEST_SING",DECREASING_CLOSED_NEST_SING; +"DECREASING_LEFT_LIMIT",DECREASING_LEFT_LIMIT; +"DECREASING_LEFT_LIMIT_1",DECREASING_LEFT_LIMIT_1; +"DECREASING_RIGHT_LIMIT",DECREASING_RIGHT_LIMIT; +"DECREASING_RIGHT_LIMIT_1",DECREASING_RIGHT_LIMIT_1; +"DECREASING_VECTOR_VARIATION",DECREASING_VECTOR_VARIATION; +"DELETE",DELETE; +"DELETE_COMM",DELETE_COMM; +"DELETE_DELETE",DELETE_DELETE; +"DELETE_INSERT",DELETE_INSERT; +"DELETE_INTER",DELETE_INTER; +"DELETE_NON_ELEMENT",DELETE_NON_ELEMENT; +"DELETE_SUBSET",DELETE_SUBSET; +"DEMOIVRE",DEMOIVRE; +"DENSE_ACCESSIBLE_FRONTIER_POINTS",DENSE_ACCESSIBLE_FRONTIER_POINTS; +"DENSE_ACCESSIBLE_FRONTIER_POINTS_CONNECTED",DENSE_ACCESSIBLE_FRONTIER_POINTS_CONNECTED; +"DENSE_ACCESSIBLE_FRONTIER_POINT_PAIRS",DENSE_ACCESSIBLE_FRONTIER_POINT_PAIRS; +"DEPENDENT_2",DEPENDENT_2; +"DEPENDENT_3",DEPENDENT_3; +"DEPENDENT_AFFINE_DEPENDENT_CASES",DEPENDENT_AFFINE_DEPENDENT_CASES; +"DEPENDENT_BIGGERSET",DEPENDENT_BIGGERSET; +"DEPENDENT_BIGGERSET_GENERAL",DEPENDENT_BIGGERSET_GENERAL; +"DEPENDENT_EXPLICIT",DEPENDENT_EXPLICIT; +"DEPENDENT_FINITE",DEPENDENT_FINITE; +"DEPENDENT_IMP_AFFINE_DEPENDENT",DEPENDENT_IMP_AFFINE_DEPENDENT; +"DEPENDENT_LINEAR_IMAGE",DEPENDENT_LINEAR_IMAGE; +"DEPENDENT_LINEAR_IMAGE_EQ",DEPENDENT_LINEAR_IMAGE_EQ; +"DEPENDENT_MONO",DEPENDENT_MONO; +"DEPENDENT_SING",DEPENDENT_SING; +"DEST_MK_MULTIVECTOR",DEST_MK_MULTIVECTOR; +"DEST_REC_INJ",DEST_REC_INJ; +"DET_0",DET_0; +"DET_1",DET_1; +"DET_2",DET_2; +"DET_3",DET_3; +"DET_4",DET_4; +"DET_CMUL",DET_CMUL; +"DET_COFACTOR",DET_COFACTOR; +"DET_COFACTOR_EXPANSION",DET_COFACTOR_EXPANSION; +"DET_DEPENDENT_COLUMNS",DET_DEPENDENT_COLUMNS; +"DET_DEPENDENT_ROWS",DET_DEPENDENT_ROWS; +"DET_DIAGONAL",DET_DIAGONAL; +"DET_EQ_0",DET_EQ_0; +"DET_EQ_0_RANK",DET_EQ_0_RANK; +"DET_I",DET_I; +"DET_IDENTICAL_COLUMNS",DET_IDENTICAL_COLUMNS; +"DET_IDENTICAL_ROWS",DET_IDENTICAL_ROWS; +"DET_LINEAR_ROWS_VSUM",DET_LINEAR_ROWS_VSUM; +"DET_LINEAR_ROWS_VSUM_LEMMA",DET_LINEAR_ROWS_VSUM_LEMMA; +"DET_LINEAR_ROW_VSUM",DET_LINEAR_ROW_VSUM; +"DET_LOWERTRIANGULAR",DET_LOWERTRIANGULAR; +"DET_MATRIX_EQ_0",DET_MATRIX_EQ_0; +"DET_MATRIX_EQ_0_LEFT",DET_MATRIX_EQ_0_LEFT; +"DET_MATRIX_EQ_0_RIGHT",DET_MATRIX_EQ_0_RIGHT; +"DET_MATRIX_REFLECT_ALONG",DET_MATRIX_REFLECT_ALONG; +"DET_MATRIX_ROTATE2D",DET_MATRIX_ROTATE2D; +"DET_MUL",DET_MUL; +"DET_NEG",DET_NEG; +"DET_ORTHOGONAL_MATRIX",DET_ORTHOGONAL_MATRIX; +"DET_PERMUTE_COLUMNS",DET_PERMUTE_COLUMNS; +"DET_PERMUTE_ROWS",DET_PERMUTE_ROWS; +"DET_ROWS_MUL",DET_ROWS_MUL; +"DET_ROW_ADD",DET_ROW_ADD; +"DET_ROW_MUL",DET_ROW_MUL; +"DET_ROW_OPERATION",DET_ROW_OPERATION; +"DET_ROW_SPAN",DET_ROW_SPAN; +"DET_TRANSP",DET_TRANSP; +"DET_UPPERTRIANGULAR",DET_UPPERTRIANGULAR; +"DET_ZERO_COLUMN",DET_ZERO_COLUMN; +"DET_ZERO_ROW",DET_ZERO_ROW; +"DE_MORGAN_THM",DE_MORGAN_THM; +"DIAMETER_ATTAINED_FRONTIER",DIAMETER_ATTAINED_FRONTIER; +"DIAMETER_ATTAINED_RELATIVE_FRONTIER",DIAMETER_ATTAINED_RELATIVE_FRONTIER; +"DIAMETER_BALL",DIAMETER_BALL; +"DIAMETER_BOUNDED",DIAMETER_BOUNDED; +"DIAMETER_BOUNDED_BOUND",DIAMETER_BOUNDED_BOUND; +"DIAMETER_BOUNDED_BOUND_LT",DIAMETER_BOUNDED_BOUND_LT; +"DIAMETER_CBALL",DIAMETER_CBALL; +"DIAMETER_CLOSURE",DIAMETER_CLOSURE; +"DIAMETER_COMPACT_ATTAINED",DIAMETER_COMPACT_ATTAINED; +"DIAMETER_CONVEX_HULL",DIAMETER_CONVEX_HULL; +"DIAMETER_EMPTY",DIAMETER_EMPTY; +"DIAMETER_EQ_0",DIAMETER_EQ_0; +"DIAMETER_FRONTIER",DIAMETER_FRONTIER; +"DIAMETER_INTERVAL",DIAMETER_INTERVAL; +"DIAMETER_LE",DIAMETER_LE; +"DIAMETER_LINEAR_IMAGE",DIAMETER_LINEAR_IMAGE; +"DIAMETER_POS_LE",DIAMETER_POS_LE; +"DIAMETER_RELATIVE_FRONTIER",DIAMETER_RELATIVE_FRONTIER; +"DIAMETER_SIMPLEX",DIAMETER_SIMPLEX; +"DIAMETER_SING",DIAMETER_SING; +"DIAMETER_SPHERE",DIAMETER_SPHERE; +"DIAMETER_SUBSET",DIAMETER_SUBSET; +"DIAMETER_SUBSET_CBALL",DIAMETER_SUBSET_CBALL; +"DIAMETER_SUBSET_CBALL_NONEMPTY",DIAMETER_SUBSET_CBALL_NONEMPTY; +"DIAMETER_TRANSLATION",DIAMETER_TRANSLATION; +"DIFF",DIFF; +"DIFFERENTIABLE_ADD",DIFFERENTIABLE_ADD; +"DIFFERENTIABLE_AT_IMP_DIFFERENTIABLE_ON",DIFFERENTIABLE_AT_IMP_DIFFERENTIABLE_ON; +"DIFFERENTIABLE_AT_LIFT_DOT2",DIFFERENTIABLE_AT_LIFT_DOT2; +"DIFFERENTIABLE_AT_WITHIN",DIFFERENTIABLE_AT_WITHIN; +"DIFFERENTIABLE_BOUND",DIFFERENTIABLE_BOUND; +"DIFFERENTIABLE_CHAIN_AT",DIFFERENTIABLE_CHAIN_AT; +"DIFFERENTIABLE_CHAIN_WITHIN",DIFFERENTIABLE_CHAIN_WITHIN; +"DIFFERENTIABLE_CMUL",DIFFERENTIABLE_CMUL; +"DIFFERENTIABLE_COMPONENTWISE_AT",DIFFERENTIABLE_COMPONENTWISE_AT; +"DIFFERENTIABLE_COMPONENTWISE_WITHIN",DIFFERENTIABLE_COMPONENTWISE_WITHIN; +"DIFFERENTIABLE_CONST",DIFFERENTIABLE_CONST; +"DIFFERENTIABLE_ID",DIFFERENTIABLE_ID; +"DIFFERENTIABLE_IMP_CONTINUOUS_AT",DIFFERENTIABLE_IMP_CONTINUOUS_AT; +"DIFFERENTIABLE_IMP_CONTINUOUS_ON",DIFFERENTIABLE_IMP_CONTINUOUS_ON; +"DIFFERENTIABLE_IMP_CONTINUOUS_WITHIN",DIFFERENTIABLE_IMP_CONTINUOUS_WITHIN; +"DIFFERENTIABLE_IMP_PIECEWISE_DIFFERENTIABLE",DIFFERENTIABLE_IMP_PIECEWISE_DIFFERENTIABLE; +"DIFFERENTIABLE_LIFT_COMPONENT",DIFFERENTIABLE_LIFT_COMPONENT; +"DIFFERENTIABLE_LINEAR",DIFFERENTIABLE_LINEAR; +"DIFFERENTIABLE_MUL_AT",DIFFERENTIABLE_MUL_AT; +"DIFFERENTIABLE_MUL_WITHIN",DIFFERENTIABLE_MUL_WITHIN; +"DIFFERENTIABLE_NEG",DIFFERENTIABLE_NEG; +"DIFFERENTIABLE_NORM_AT",DIFFERENTIABLE_NORM_AT; +"DIFFERENTIABLE_ON_ADD",DIFFERENTIABLE_ON_ADD; +"DIFFERENTIABLE_ON_COMPOSE",DIFFERENTIABLE_ON_COMPOSE; +"DIFFERENTIABLE_ON_CONST",DIFFERENTIABLE_ON_CONST; +"DIFFERENTIABLE_ON_EMPTY",DIFFERENTIABLE_ON_EMPTY; +"DIFFERENTIABLE_ON_EQ_DIFFERENTIABLE_AT",DIFFERENTIABLE_ON_EQ_DIFFERENTIABLE_AT; +"DIFFERENTIABLE_ON_ID",DIFFERENTIABLE_ON_ID; +"DIFFERENTIABLE_ON_IMP_PIECEWISE_DIFFERENTIABLE",DIFFERENTIABLE_ON_IMP_PIECEWISE_DIFFERENTIABLE; +"DIFFERENTIABLE_ON_LIFT_DOT2",DIFFERENTIABLE_ON_LIFT_DOT2; +"DIFFERENTIABLE_ON_LINEAR",DIFFERENTIABLE_ON_LINEAR; +"DIFFERENTIABLE_ON_MUL",DIFFERENTIABLE_ON_MUL; +"DIFFERENTIABLE_ON_NEG",DIFFERENTIABLE_ON_NEG; +"DIFFERENTIABLE_ON_NORM",DIFFERENTIABLE_ON_NORM; +"DIFFERENTIABLE_ON_REAL_POLYNOMIAL_FUNCTION",DIFFERENTIABLE_ON_REAL_POLYNOMIAL_FUNCTION; +"DIFFERENTIABLE_ON_SQNORM",DIFFERENTIABLE_ON_SQNORM; +"DIFFERENTIABLE_ON_SUB",DIFFERENTIABLE_ON_SUB; +"DIFFERENTIABLE_ON_SUBSET",DIFFERENTIABLE_ON_SUBSET; +"DIFFERENTIABLE_ON_VECTOR_POLYNOMIAL_FUNCTION",DIFFERENTIABLE_ON_VECTOR_POLYNOMIAL_FUNCTION; +"DIFFERENTIABLE_REAL_POLYNOMIAL_FUNCTION_AT",DIFFERENTIABLE_REAL_POLYNOMIAL_FUNCTION_AT; +"DIFFERENTIABLE_SQNORM_AT",DIFFERENTIABLE_SQNORM_AT; +"DIFFERENTIABLE_SUB",DIFFERENTIABLE_SUB; +"DIFFERENTIABLE_TRANSFORM_AT",DIFFERENTIABLE_TRANSFORM_AT; +"DIFFERENTIABLE_TRANSFORM_WITHIN",DIFFERENTIABLE_TRANSFORM_WITHIN; +"DIFFERENTIABLE_VECTOR_POLYNOMIAL_FUNCTION",DIFFERENTIABLE_VECTOR_POLYNOMIAL_FUNCTION; +"DIFFERENTIABLE_VSUM",DIFFERENTIABLE_VSUM; +"DIFFERENTIABLE_VSUM_NUMSEG",DIFFERENTIABLE_VSUM_NUMSEG; +"DIFFERENTIABLE_WITHIN_LIFT_DOT2",DIFFERENTIABLE_WITHIN_LIFT_DOT2; +"DIFFERENTIABLE_WITHIN_OPEN",DIFFERENTIABLE_WITHIN_OPEN; +"DIFFERENTIABLE_WITHIN_SUBSET",DIFFERENTIABLE_WITHIN_SUBSET; +"DIFFERENTIAL_COMPONENT_NEG_AT_MAXIMUM",DIFFERENTIAL_COMPONENT_NEG_AT_MAXIMUM; +"DIFFERENTIAL_COMPONENT_POS_AT_MINIMUM",DIFFERENTIAL_COMPONENT_POS_AT_MINIMUM; +"DIFFERENTIAL_COMPONENT_ZERO_AT_MAXMIN",DIFFERENTIAL_COMPONENT_ZERO_AT_MAXMIN; +"DIFFERENTIAL_ZERO_MAXMIN",DIFFERENTIAL_ZERO_MAXMIN; +"DIFFERENTIAL_ZERO_MAXMIN_COMPONENT",DIFFERENTIAL_ZERO_MAXMIN_COMPONENT; +"DIFFERENT_NORM_3_COLLINEAR_POINTS",DIFFERENT_NORM_3_COLLINEAR_POINTS; +"DIFFS_AFFINE_HULL_SPAN",DIFFS_AFFINE_HULL_SPAN; +"DIFF_CHAIN_AT",DIFF_CHAIN_AT; +"DIFF_CHAIN_WITHIN",DIFF_CHAIN_WITHIN; +"DIFF_DIFF",DIFF_DIFF; +"DIFF_EMPTY",DIFF_EMPTY; +"DIFF_EQ_EMPTY",DIFF_EQ_EMPTY; +"DIFF_INSERT",DIFF_INSERT; +"DIFF_INTERS",DIFF_INTERS; +"DIFF_UNIONS",DIFF_UNIONS; +"DIFF_UNIONS_NONEMPTY",DIFF_UNIONS_NONEMPTY; +"DIFF_UNIV",DIFF_UNIV; +"DIMINDEX_1",DIMINDEX_1; +"DIMINDEX_2",DIMINDEX_2; +"DIMINDEX_3",DIMINDEX_3; +"DIMINDEX_4",DIMINDEX_4; +"DIMINDEX_FINITE_IMAGE",DIMINDEX_FINITE_IMAGE; +"DIMINDEX_FINITE_SUM",DIMINDEX_FINITE_SUM; +"DIMINDEX_GE_1",DIMINDEX_GE_1; +"DIMINDEX_HAS_SIZE_FINITE_SUM",DIMINDEX_HAS_SIZE_FINITE_SUM; +"DIMINDEX_MULTIVECTOR",DIMINDEX_MULTIVECTOR; +"DIMINDEX_NONZERO",DIMINDEX_NONZERO; +"DIMINDEX_UNIQUE",DIMINDEX_UNIQUE; +"DIMINDEX_UNIV",DIMINDEX_UNIV; +"DIM_CLOSURE",DIM_CLOSURE; +"DIM_EMPTY",DIM_EMPTY; +"DIM_EQ_0",DIM_EQ_0; +"DIM_EQ_CARD",DIM_EQ_CARD; +"DIM_EQ_FULL",DIM_EQ_FULL; +"DIM_EQ_HYPERPLANE",DIM_EQ_HYPERPLANE; +"DIM_EQ_SPAN",DIM_EQ_SPAN; +"DIM_HYPERPLANE",DIM_HYPERPLANE; +"DIM_IMAGE_KERNEL",DIM_IMAGE_KERNEL; +"DIM_IMAGE_KERNEL_GEN",DIM_IMAGE_KERNEL_GEN; +"DIM_INJECTIVE_LINEAR_IMAGE",DIM_INJECTIVE_LINEAR_IMAGE; +"DIM_INSERT",DIM_INSERT; +"DIM_INSERT_0",DIM_INSERT_0; +"DIM_KERNEL_COMPOSE",DIM_KERNEL_COMPOSE; +"DIM_LE_CARD",DIM_LE_CARD; +"DIM_LINEAR_IMAGE_LE",DIM_LINEAR_IMAGE_LE; +"DIM_OPEN",DIM_OPEN; +"DIM_OPEN_IN",DIM_OPEN_IN; +"DIM_ORTHOGONAL_SUM",DIM_ORTHOGONAL_SUM; +"DIM_PCROSS",DIM_PCROSS; +"DIM_PCROSS_STRONG",DIM_PCROSS_STRONG; +"DIM_PSUBSET",DIM_PSUBSET; +"DIM_ROWS_LE_DIM_COLUMNS",DIM_ROWS_LE_DIM_COLUMNS; +"DIM_SING",DIM_SING; +"DIM_SPAN",DIM_SPAN; +"DIM_SPECIAL_HYPERPLANE",DIM_SPECIAL_HYPERPLANE; +"DIM_SPECIAL_SUBSPACE",DIM_SPECIAL_SUBSPACE; +"DIM_SUBSET",DIM_SUBSET; +"DIM_SUBSET_UNIV",DIM_SUBSET_UNIV; +"DIM_SUBSPACE_ORTHOGONAL_TO_VECTORS",DIM_SUBSPACE_ORTHOGONAL_TO_VECTORS; +"DIM_SUBSTANDARD",DIM_SUBSTANDARD; +"DIM_SUMS_INTER",DIM_SUMS_INTER; +"DIM_UNIQUE",DIM_UNIQUE; +"DIM_UNIV",DIM_UNIV; +"DINI",DINI; +"DISCRETE_BOUNDED_IMP_FINITE",DISCRETE_BOUNDED_IMP_FINITE; +"DISCRETE_IMP_CLOSED",DISCRETE_IMP_CLOSED; +"DISCRETE_IMP_COUNTABLE",DISCRETE_IMP_COUNTABLE; +"DISJOINT",DISJOINT; +"DISJOINT_AFFINE_HULL",DISJOINT_AFFINE_HULL; +"DISJOINT_DELETE_SYM",DISJOINT_DELETE_SYM; +"DISJOINT_EMPTY",DISJOINT_EMPTY; +"DISJOINT_EMPTY_REFL",DISJOINT_EMPTY_REFL; +"DISJOINT_INSERT",DISJOINT_INSERT; +"DISJOINT_INTERVAL",DISJOINT_INTERVAL; +"DISJOINT_INTERVAL_1",DISJOINT_INTERVAL_1; +"DISJOINT_NUMSEG",DISJOINT_NUMSEG; +"DISJOINT_SYM",DISJOINT_SYM; +"DISJOINT_UNION",DISJOINT_UNION; +"DISJ_ACI",DISJ_ACI; +"DISJ_ASSOC",DISJ_ASSOC; +"DISJ_SYM",DISJ_SYM; +"DISTANCE_ATTAINS_INF",DISTANCE_ATTAINS_INF; +"DISTANCE_ATTAINS_SUP",DISTANCE_ATTAINS_SUP; +"DIST_0",DIST_0; +"DIST_ADD2",DIST_ADD2; +"DIST_ADD2_REV",DIST_ADD2_REV; +"DIST_ADDBOUND",DIST_ADDBOUND; +"DIST_CEXP_II_1",DIST_CEXP_II_1; +"DIST_CLOSEST_POINT_LIPSCHITZ",DIST_CLOSEST_POINT_LIPSCHITZ; +"DIST_ELIM_THM",DIST_ELIM_THM; +"DIST_EQ",DIST_EQ; +"DIST_EQ_0",DIST_EQ_0; +"DIST_FSTCART",DIST_FSTCART; +"DIST_INCREASES_ONLINE",DIST_INCREASES_ONLINE; +"DIST_IN_CLOSED_SEGMENT",DIST_IN_CLOSED_SEGMENT; +"DIST_IN_OPEN_SEGMENT",DIST_IN_OPEN_SEGMENT; +"DIST_LADD",DIST_LADD; +"DIST_LADD_0",DIST_LADD_0; +"DIST_LE_0",DIST_LE_0; +"DIST_LE_CASES",DIST_LE_CASES; +"DIST_LIFT",DIST_LIFT; +"DIST_LMUL",DIST_LMUL; +"DIST_LZERO",DIST_LZERO; +"DIST_MIDPOINT",DIST_MIDPOINT; +"DIST_MUL",DIST_MUL; +"DIST_NZ",DIST_NZ; +"DIST_PASTECART_CANCEL",DIST_PASTECART_CANCEL; +"DIST_POS_LE",DIST_POS_LE; +"DIST_POS_LT",DIST_POS_LT; +"DIST_RADD",DIST_RADD; +"DIST_RADD_0",DIST_RADD_0; +"DIST_REAL",DIST_REAL; +"DIST_REFL",DIST_REFL; +"DIST_RMUL",DIST_RMUL; +"DIST_RZERO",DIST_RZERO; +"DIST_SNDCART",DIST_SNDCART; +"DIST_SYM",DIST_SYM; +"DIST_TRIANGLE",DIST_TRIANGLE; +"DIST_TRIANGLES_LE",DIST_TRIANGLES_LE; +"DIST_TRIANGLE_ADD",DIST_TRIANGLE_ADD; +"DIST_TRIANGLE_ADD_HALF",DIST_TRIANGLE_ADD_HALF; +"DIST_TRIANGLE_ALT",DIST_TRIANGLE_ALT; +"DIST_TRIANGLE_EQ",DIST_TRIANGLE_EQ; +"DIST_TRIANGLE_HALF_L",DIST_TRIANGLE_HALF_L; +"DIST_TRIANGLE_HALF_R",DIST_TRIANGLE_HALF_R; +"DIST_TRIANGLE_LE",DIST_TRIANGLE_LE; +"DIST_TRIANGLE_LT",DIST_TRIANGLE_LT; +"DIVISION",DIVISION; +"DIVISION_0",DIVISION_0; +"DIVISION_COMMON_POINT_BOUND",DIVISION_COMMON_POINT_BOUND; +"DIVISION_CONTAINS",DIVISION_CONTAINS; +"DIVISION_DISJOINT_UNION",DIVISION_DISJOINT_UNION; +"DIVISION_DOUBLESPLIT",DIVISION_DOUBLESPLIT; +"DIVISION_INTER",DIVISION_INTER; +"DIVISION_INTER_1",DIVISION_INTER_1; +"DIVISION_OF",DIVISION_OF; +"DIVISION_OF_AFFINITY",DIVISION_OF_AFFINITY; +"DIVISION_OF_CLOSED",DIVISION_OF_CLOSED; +"DIVISION_OF_CONTENT_0",DIVISION_OF_CONTENT_0; +"DIVISION_OF_FINITE",DIVISION_OF_FINITE; +"DIVISION_OF_NONTRIVIAL",DIVISION_OF_NONTRIVIAL; +"DIVISION_OF_REFLECT",DIVISION_OF_REFLECT; +"DIVISION_OF_SELF",DIVISION_OF_SELF; +"DIVISION_OF_SING",DIVISION_OF_SING; +"DIVISION_OF_SUBSET",DIVISION_OF_SUBSET; +"DIVISION_OF_TAGGED_DIVISION",DIVISION_OF_TAGGED_DIVISION; +"DIVISION_OF_TRANSLATION",DIVISION_OF_TRANSLATION; +"DIVISION_OF_TRIVIAL",DIVISION_OF_TRIVIAL; +"DIVISION_OF_UNIONS",DIVISION_OF_UNIONS; +"DIVISION_OF_UNION_SELF",DIVISION_OF_UNION_SELF; +"DIVISION_POINTS_FINITE",DIVISION_POINTS_FINITE; +"DIVISION_POINTS_PSUBSET",DIVISION_POINTS_PSUBSET; +"DIVISION_POINTS_SUBSET",DIVISION_POINTS_SUBSET; +"DIVISION_SIMP",DIVISION_SIMP; +"DIVISION_SPLIT",DIVISION_SPLIT; +"DIVISION_SPLIT_LEFT_INJ",DIVISION_SPLIT_LEFT_INJ; +"DIVISION_SPLIT_RIGHT_INJ",DIVISION_SPLIT_RIGHT_INJ; +"DIVISION_UNION_INTERVALS_EXISTS",DIVISION_UNION_INTERVALS_EXISTS; +"DIVMOD_ELIM_THM",DIVMOD_ELIM_THM; +"DIVMOD_ELIM_THM'",DIVMOD_ELIM_THM'; +"DIVMOD_EXIST",DIVMOD_EXIST; +"DIVMOD_EXIST_0",DIVMOD_EXIST_0; +"DIVMOD_UNIQ",DIVMOD_UNIQ; +"DIVMOD_UNIQ_LEMMA",DIVMOD_UNIQ_LEMMA; +"DIV_0",DIV_0; +"DIV_1",DIV_1; +"DIV_ADD_MOD",DIV_ADD_MOD; +"DIV_DIV",DIV_DIV; +"DIV_EQ_0",DIV_EQ_0; +"DIV_EQ_EXCLUSION",DIV_EQ_EXCLUSION; +"DIV_LE",DIV_LE; +"DIV_LE_EXCLUSION",DIV_LE_EXCLUSION; +"DIV_LT",DIV_LT; +"DIV_MOD",DIV_MOD; +"DIV_MONO",DIV_MONO; +"DIV_MONO2",DIV_MONO2; +"DIV_MONO_LT",DIV_MONO_LT; +"DIV_MULT",DIV_MULT; +"DIV_MULT2",DIV_MULT2; +"DIV_MULT_ADD",DIV_MULT_ADD; +"DIV_MUL_LE",DIV_MUL_LE; +"DIV_REFL",DIV_REFL; +"DIV_UNIQ",DIV_UNIQ; +"DOMINATED_CONVERGENCE",DOMINATED_CONVERGENCE; +"DOMINATED_CONVERGENCE_ABSOLUTELY_INTEGRABLE",DOMINATED_CONVERGENCE_ABSOLUTELY_INTEGRABLE; +"DOMINATED_CONVERGENCE_INTEGRABLE",DOMINATED_CONVERGENCE_INTEGRABLE; +"DOT_1",DOT_1; +"DOT_2",DOT_2; +"DOT_3",DOT_3; +"DOT_4",DOT_4; +"DOT_BASIS",DOT_BASIS; +"DOT_BASIS_BASIS",DOT_BASIS_BASIS; +"DOT_BASIS_BASIS_UNEQUAL",DOT_BASIS_BASIS_UNEQUAL; +"DOT_CAUCHY_SCHWARZ_EQUAL",DOT_CAUCHY_SCHWARZ_EQUAL; +"DOT_DROPOUT",DOT_DROPOUT; +"DOT_EQ_0",DOT_EQ_0; +"DOT_LADD",DOT_LADD; +"DOT_LMUL",DOT_LMUL; +"DOT_LMUL_MATRIX",DOT_LMUL_MATRIX; +"DOT_LNEG",DOT_LNEG; +"DOT_LSUB",DOT_LSUB; +"DOT_LSUM",DOT_LSUM; +"DOT_LZERO",DOT_LZERO; +"DOT_MATRIX_PRODUCT",DOT_MATRIX_PRODUCT; +"DOT_MATRIX_VECTOR_MUL",DOT_MATRIX_VECTOR_MUL; +"DOT_NORM",DOT_NORM; +"DOT_NORM_NEG",DOT_NORM_NEG; +"DOT_NORM_SUB",DOT_NORM_SUB; +"DOT_PASTECART",DOT_PASTECART; +"DOT_POS_LE",DOT_POS_LE; +"DOT_POS_LT",DOT_POS_LT; +"DOT_PUSHIN",DOT_PUSHIN; +"DOT_RADD",DOT_RADD; +"DOT_RMUL",DOT_RMUL; +"DOT_RNEG",DOT_RNEG; +"DOT_ROWVECTOR_COLUMNVECTOR",DOT_ROWVECTOR_COLUMNVECTOR; +"DOT_RSUB",DOT_RSUB; +"DOT_RSUM",DOT_RSUM; +"DOT_RZERO",DOT_RZERO; +"DOT_SQUARE_NORM",DOT_SQUARE_NORM; +"DOT_SYM",DOT_SYM; +"DROPOUT_0",DROPOUT_0; +"DROPOUT_ADD",DROPOUT_ADD; +"DROPOUT_EQ",DROPOUT_EQ; +"DROPOUT_GALOIS",DROPOUT_GALOIS; +"DROPOUT_MUL",DROPOUT_MUL; +"DROPOUT_PUSHIN",DROPOUT_PUSHIN; +"DROPOUT_SUB",DROPOUT_SUB; +"DROP_ADD",DROP_ADD; +"DROP_CMUL",DROP_CMUL; +"DROP_DIFFERENTIAL_NEG_AT_MAXIMUM",DROP_DIFFERENTIAL_NEG_AT_MAXIMUM; +"DROP_DIFFERENTIAL_POS_AT_MINIMUM",DROP_DIFFERENTIAL_POS_AT_MINIMUM; +"DROP_EQ",DROP_EQ; +"DROP_EQ_0",DROP_EQ_0; +"DROP_INDICATOR",DROP_INDICATOR; +"DROP_INDICATOR_ABS_LE_1",DROP_INDICATOR_ABS_LE_1; +"DROP_INDICATOR_LE_1",DROP_INDICATOR_LE_1; +"DROP_INDICATOR_POS_LE",DROP_INDICATOR_POS_LE; +"DROP_IN_IMAGE_DROP",DROP_IN_IMAGE_DROP; +"DROP_LAMBDA",DROP_LAMBDA; +"DROP_NEG",DROP_NEG; +"DROP_SUB",DROP_SUB; +"DROP_VEC",DROP_VEC; +"DROP_VSUM",DROP_VSUM; +"DROP_WLOG_LE",DROP_WLOG_LE; +"DSUM_BOUND",DSUM_BOUND; +"EDELSTEIN_FIX",EDELSTEIN_FIX; +"EDGE_OF_IMP_SUBSET",EDGE_OF_IMP_SUBSET; +"EDGE_OF_LINEAR_IMAGE",EDGE_OF_LINEAR_IMAGE; +"EDGE_OF_TRANSLATION_EQ",EDGE_OF_TRANSLATION_EQ; +"EL",EL; +"ELEMENTARY_BOUNDED",ELEMENTARY_BOUNDED; +"ELEMENTARY_COMPACT",ELEMENTARY_COMPACT; +"ELEMENTARY_EMPTY",ELEMENTARY_EMPTY; +"ELEMENTARY_INTER",ELEMENTARY_INTER; +"ELEMENTARY_INTERS",ELEMENTARY_INTERS; +"ELEMENTARY_INTERVAL",ELEMENTARY_INTERVAL; +"ELEMENTARY_SUBSET_INTERVAL",ELEMENTARY_SUBSET_INTERVAL; +"ELEMENTARY_UNION",ELEMENTARY_UNION; +"ELEMENTARY_UNIONS_INTERVALS",ELEMENTARY_UNIONS_INTERVALS; +"ELEMENTARY_UNION_INTERVAL",ELEMENTARY_UNION_INTERVAL; +"ELEMENTARY_UNION_INTERVAL_STRONG",ELEMENTARY_UNION_INTERVAL_STRONG; +"EL_APPEND",EL_APPEND; +"EL_CONS",EL_CONS; +"EL_MAP",EL_MAP; +"EL_TL",EL_TL; +"EMPTY",EMPTY; +"EMPTY_AS_INTERVAL",EMPTY_AS_INTERVAL; +"EMPTY_AS_REAL_INTERVAL",EMPTY_AS_REAL_INTERVAL; +"EMPTY_DELETE",EMPTY_DELETE; +"EMPTY_DIFF",EMPTY_DIFF; +"EMPTY_DIVISION_OF",EMPTY_DIVISION_OF; +"EMPTY_EXPOSED_FACE_OF",EMPTY_EXPOSED_FACE_OF; +"EMPTY_FACE_OF",EMPTY_FACE_OF; +"EMPTY_GSPEC",EMPTY_GSPEC; +"EMPTY_INTERIOR_AFFINE_HULL",EMPTY_INTERIOR_AFFINE_HULL; +"EMPTY_INTERIOR_CONVEX_HULL",EMPTY_INTERIOR_CONVEX_HULL; +"EMPTY_INTERIOR_FINITE",EMPTY_INTERIOR_FINITE; +"EMPTY_INTERIOR_LOWDIM",EMPTY_INTERIOR_LOWDIM; +"EMPTY_INTERIOR_SUBSET_HYPERPLANE",EMPTY_INTERIOR_SUBSET_HYPERPLANE; +"EMPTY_NOT_UNIV",EMPTY_NOT_UNIV; +"EMPTY_SUBSET",EMPTY_SUBSET; +"EMPTY_UNION",EMPTY_UNION; +"EMPTY_UNIONS",EMPTY_UNIONS; +"ENDPOINTS_SHIFTPATH",ENDPOINTS_SHIFTPATH; +"ENDS_IN_INTERVAL",ENDS_IN_INTERVAL; +"ENDS_IN_REAL_INTERVAL",ENDS_IN_REAL_INTERVAL; +"ENDS_IN_SEGMENT",ENDS_IN_SEGMENT; +"ENDS_IN_UNIT_INTERVAL",ENDS_IN_UNIT_INTERVAL; +"ENDS_NOT_IN_SEGMENT",ENDS_NOT_IN_SEGMENT; +"EPSILON_DELTA_MINIMAL",EPSILON_DELTA_MINIMAL; +"EQUIINTEGRABLE_ADD",EQUIINTEGRABLE_ADD; +"EQUIINTEGRABLE_CLOSED_INTERVAL_RESTRICTIONS",EQUIINTEGRABLE_CLOSED_INTERVAL_RESTRICTIONS; +"EQUIINTEGRABLE_CMUL",EQUIINTEGRABLE_CMUL; +"EQUIINTEGRABLE_DIVISION",EQUIINTEGRABLE_DIVISION; +"EQUIINTEGRABLE_EQ",EQUIINTEGRABLE_EQ; +"EQUIINTEGRABLE_HALFSPACE_RESTRICTIONS_GE",EQUIINTEGRABLE_HALFSPACE_RESTRICTIONS_GE; +"EQUIINTEGRABLE_HALFSPACE_RESTRICTIONS_GT",EQUIINTEGRABLE_HALFSPACE_RESTRICTIONS_GT; +"EQUIINTEGRABLE_HALFSPACE_RESTRICTIONS_LE",EQUIINTEGRABLE_HALFSPACE_RESTRICTIONS_LE; +"EQUIINTEGRABLE_HALFSPACE_RESTRICTIONS_LT",EQUIINTEGRABLE_HALFSPACE_RESTRICTIONS_LT; +"EQUIINTEGRABLE_LIMIT",EQUIINTEGRABLE_LIMIT; +"EQUIINTEGRABLE_NEG",EQUIINTEGRABLE_NEG; +"EQUIINTEGRABLE_ON_NULL",EQUIINTEGRABLE_ON_NULL; +"EQUIINTEGRABLE_ON_SING",EQUIINTEGRABLE_ON_SING; +"EQUIINTEGRABLE_ON_SPLIT",EQUIINTEGRABLE_ON_SPLIT; +"EQUIINTEGRABLE_OPEN_INTERVAL_RESTRICTIONS",EQUIINTEGRABLE_OPEN_INTERVAL_RESTRICTIONS; +"EQUIINTEGRABLE_REFLECT",EQUIINTEGRABLE_REFLECT; +"EQUIINTEGRABLE_SUB",EQUIINTEGRABLE_SUB; +"EQUIINTEGRABLE_SUBSET",EQUIINTEGRABLE_SUBSET; +"EQUIINTEGRABLE_SUM",EQUIINTEGRABLE_SUM; +"EQUIINTEGRABLE_UNIFORM_LIMIT",EQUIINTEGRABLE_UNIFORM_LIMIT; +"EQUIINTEGRABLE_UNION",EQUIINTEGRABLE_UNION; +"EQ_ADD_LCANCEL",EQ_ADD_LCANCEL; +"EQ_ADD_LCANCEL_0",EQ_ADD_LCANCEL_0; +"EQ_ADD_RCANCEL",EQ_ADD_RCANCEL; +"EQ_ADD_RCANCEL_0",EQ_ADD_RCANCEL_0; +"EQ_BALLS",EQ_BALLS; +"EQ_C",EQ_C; +"EQ_CLAUSES",EQ_CLAUSES; +"EQ_C_BIJECTIONS",EQ_C_BIJECTIONS; +"EQ_EXP",EQ_EXP; +"EQ_EXT",EQ_EXT; +"EQ_IMP",EQ_IMP; +"EQ_IMP_LE",EQ_IMP_LE; +"EQ_INTERVAL",EQ_INTERVAL; +"EQ_INTERVAL_1",EQ_INTERVAL_1; +"EQ_MULT_LCANCEL",EQ_MULT_LCANCEL; +"EQ_MULT_RCANCEL",EQ_MULT_RCANCEL; +"EQ_REFL",EQ_REFL; +"EQ_SPAN_INSERT_EQ",EQ_SPAN_INSERT_EQ; +"EQ_SYM",EQ_SYM; +"EQ_SYM_EQ",EQ_SYM_EQ; +"EQ_TRANS",EQ_TRANS; +"EQ_UNIV",EQ_UNIV; +"ETA_AX",ETA_AX; +"EUCLIDEAN_SPACE_INFINITE",EUCLIDEAN_SPACE_INFINITE; +"EULER",EULER; +"EULER_ROTATION_THEOREM",EULER_ROTATION_THEOREM; +"EULER_ROTOINVERSION_THEOREM",EULER_ROTOINVERSION_THEOREM; +"EVEN",EVEN; +"EVENPERM_COMPOSE",EVENPERM_COMPOSE; +"EVENPERM_I",EVENPERM_I; +"EVENPERM_INVERSE",EVENPERM_INVERSE; +"EVENPERM_SWAP",EVENPERM_SWAP; +"EVENPERM_UNIQUE",EVENPERM_UNIQUE; +"EVENTUALLY_AND",EVENTUALLY_AND; +"EVENTUALLY_AT",EVENTUALLY_AT; +"EVENTUALLY_ATREAL",EVENTUALLY_ATREAL; +"EVENTUALLY_AT_INFINITY",EVENTUALLY_AT_INFINITY; +"EVENTUALLY_AT_NEGINFINITY",EVENTUALLY_AT_NEGINFINITY; +"EVENTUALLY_AT_POSINFINITY",EVENTUALLY_AT_POSINFINITY; +"EVENTUALLY_FALSE",EVENTUALLY_FALSE; +"EVENTUALLY_FORALL",EVENTUALLY_FORALL; +"EVENTUALLY_HAPPENS",EVENTUALLY_HAPPENS; +"EVENTUALLY_MONO",EVENTUALLY_MONO; +"EVENTUALLY_MP",EVENTUALLY_MP; +"EVENTUALLY_SEQUENTIALLY",EVENTUALLY_SEQUENTIALLY; +"EVENTUALLY_TRUE",EVENTUALLY_TRUE; +"EVENTUALLY_WITHIN",EVENTUALLY_WITHIN; +"EVENTUALLY_WITHINREAL",EVENTUALLY_WITHINREAL; +"EVENTUALLY_WITHINREAL_LE",EVENTUALLY_WITHINREAL_LE; +"EVENTUALLY_WITHIN_INTERIOR",EVENTUALLY_WITHIN_INTERIOR; +"EVENTUALLY_WITHIN_LE",EVENTUALLY_WITHIN_LE; +"EVEN_ADD",EVEN_ADD; +"EVEN_AND_ODD",EVEN_AND_ODD; +"EVEN_DOUBLE",EVEN_DOUBLE; +"EVEN_EXISTS",EVEN_EXISTS; +"EVEN_EXISTS_LEMMA",EVEN_EXISTS_LEMMA; +"EVEN_EXP",EVEN_EXP; +"EVEN_MOD",EVEN_MOD; +"EVEN_MULT",EVEN_MULT; +"EVEN_NSUM",EVEN_NSUM; +"EVEN_ODD_DECOMPOSITION",EVEN_ODD_DECOMPOSITION; +"EVEN_OR_ODD",EVEN_OR_ODD; +"EVEN_SUB",EVEN_SUB; +"EX",EX; +"EXCHANGE_LEMMA",EXCHANGE_LEMMA; +"EXCLUDED_MIDDLE",EXCLUDED_MIDDLE; +"EXISTS_ARC_PSUBSET_SIMPLE_PATH",EXISTS_ARC_PSUBSET_SIMPLE_PATH; +"EXISTS_BOOL_THM",EXISTS_BOOL_THM; +"EXISTS_CNJ",EXISTS_CNJ; +"EXISTS_COMPLEX",EXISTS_COMPLEX; +"EXISTS_COMPLEX'",EXISTS_COMPLEX'; +"EXISTS_COMPLEX_ROOT",EXISTS_COMPLEX_ROOT; +"EXISTS_COUNTABLE_SUBSET_IMAGE",EXISTS_COUNTABLE_SUBSET_IMAGE; +"EXISTS_CURRY",EXISTS_CURRY; +"EXISTS_DEF",EXISTS_DEF; +"EXISTS_DIFF",EXISTS_DIFF; +"EXISTS_DOUBLE_ARC",EXISTS_DOUBLE_ARC; +"EXISTS_DROP",EXISTS_DROP; +"EXISTS_DROP_FUN",EXISTS_DROP_FUN; +"EXISTS_DROP_IMAGE",EXISTS_DROP_IMAGE; +"EXISTS_EX",EXISTS_EX; +"EXISTS_FINITE_SUBSET_IMAGE",EXISTS_FINITE_SUBSET_IMAGE; +"EXISTS_IN_CLAUSES",EXISTS_IN_CLAUSES; +"EXISTS_IN_GSPEC",EXISTS_IN_GSPEC; +"EXISTS_IN_IMAGE",EXISTS_IN_IMAGE; +"EXISTS_IN_INSERT",EXISTS_IN_INSERT; +"EXISTS_IN_PCROSS",EXISTS_IN_PCROSS; +"EXISTS_IN_UNIONS",EXISTS_IN_UNIONS; +"EXISTS_LIFT",EXISTS_LIFT; +"EXISTS_LIFT_FUN",EXISTS_LIFT_FUN; +"EXISTS_LIFT_IMAGE",EXISTS_LIFT_IMAGE; +"EXISTS_NOT_THM",EXISTS_NOT_THM; +"EXISTS_ONE_REP",EXISTS_ONE_REP; +"EXISTS_OPTION",EXISTS_OPTION; +"EXISTS_OR_THM",EXISTS_OR_THM; +"EXISTS_PAIRED_THM",EXISTS_PAIRED_THM; +"EXISTS_PAIR_THM",EXISTS_PAIR_THM; +"EXISTS_PASTECART",EXISTS_PASTECART; +"EXISTS_PATH_SUBPATH_TO_FRONTIER",EXISTS_PATH_SUBPATH_TO_FRONTIER; +"EXISTS_PATH_SUBPATH_TO_FRONTIER_CLOSED",EXISTS_PATH_SUBPATH_TO_FRONTIER_CLOSED; +"EXISTS_REAL",EXISTS_REAL; +"EXISTS_REFL",EXISTS_REFL; +"EXISTS_SIMP",EXISTS_SIMP; +"EXISTS_SUBARC_OF_ARC_NOENDS",EXISTS_SUBARC_OF_ARC_NOENDS; +"EXISTS_SUBPATH_OF_ARC_NOENDS",EXISTS_SUBPATH_OF_ARC_NOENDS; +"EXISTS_SUBPATH_OF_PATH",EXISTS_SUBPATH_OF_PATH; +"EXISTS_SUBSET_IMAGE",EXISTS_SUBSET_IMAGE; +"EXISTS_SUBSET_UNION",EXISTS_SUBSET_UNION; +"EXISTS_SUM_THM",EXISTS_SUM_THM; +"EXISTS_SWAP",EXISTS_SWAP; +"EXISTS_THM",EXISTS_THM; +"EXISTS_TRIPLED_THM",EXISTS_TRIPLED_THM; +"EXISTS_UNCURRY",EXISTS_UNCURRY; +"EXISTS_UNIQUE",EXISTS_UNIQUE; +"EXISTS_UNIQUE_ALT",EXISTS_UNIQUE_ALT; +"EXISTS_UNIQUE_DEF",EXISTS_UNIQUE_DEF; +"EXISTS_UNIQUE_REFL",EXISTS_UNIQUE_REFL; +"EXISTS_UNIQUE_THM",EXISTS_UNIQUE_THM; +"EXISTS_VECTOR_1",EXISTS_VECTOR_1; +"EXISTS_VECTOR_2",EXISTS_VECTOR_2; +"EXISTS_VECTOR_3",EXISTS_VECTOR_3; +"EXISTS_VECTOR_4",EXISTS_VECTOR_4; +"EXP",EXP; +"EXPAND_CLOSED_OPEN_INTERVAL",EXPAND_CLOSED_OPEN_INTERVAL; +"EXPLICIT_SUBSET_INTERIOR_CONVEX_HULL",EXPLICIT_SUBSET_INTERIOR_CONVEX_HULL; +"EXPLICIT_SUBSET_INTERIOR_CONVEX_HULL_MINIMAL",EXPLICIT_SUBSET_INTERIOR_CONVEX_HULL_MINIMAL; +"EXPLICIT_SUBSET_RELATIVE_INTERIOR_CONVEX_HULL",EXPLICIT_SUBSET_RELATIVE_INTERIOR_CONVEX_HULL; +"EXPLICIT_SUBSET_RELATIVE_INTERIOR_CONVEX_HULL_MINIMAL",EXPLICIT_SUBSET_RELATIVE_INTERIOR_CONVEX_HULL_MINIMAL; +"EXPOSED_FACE_OF",EXPOSED_FACE_OF; +"EXPOSED_FACE_OF_INTER",EXPOSED_FACE_OF_INTER; +"EXPOSED_FACE_OF_INTERS",EXPOSED_FACE_OF_INTERS; +"EXPOSED_FACE_OF_INTER_SUPPORTING_HYPERPLANE_GE",EXPOSED_FACE_OF_INTER_SUPPORTING_HYPERPLANE_GE; +"EXPOSED_FACE_OF_INTER_SUPPORTING_HYPERPLANE_LE",EXPOSED_FACE_OF_INTER_SUPPORTING_HYPERPLANE_LE; +"EXPOSED_FACE_OF_LINEAR_IMAGE",EXPOSED_FACE_OF_LINEAR_IMAGE; +"EXPOSED_FACE_OF_PARALLEL",EXPOSED_FACE_OF_PARALLEL; +"EXPOSED_FACE_OF_POLYHEDRON",EXPOSED_FACE_OF_POLYHEDRON; +"EXPOSED_FACE_OF_REFL",EXPOSED_FACE_OF_REFL; +"EXPOSED_FACE_OF_REFL_EQ",EXPOSED_FACE_OF_REFL_EQ; +"EXPOSED_FACE_OF_SUMS",EXPOSED_FACE_OF_SUMS; +"EXPOSED_FACE_OF_TRANSLATION_EQ",EXPOSED_FACE_OF_TRANSLATION_EQ; +"EXPOSED_POINT_OF_FURTHEST_POINT",EXPOSED_POINT_OF_FURTHEST_POINT; +"EXPOSED_POINT_OF_INTER_SUPPORTING_HYPERPLANE_GE",EXPOSED_POINT_OF_INTER_SUPPORTING_HYPERPLANE_GE; +"EXPOSED_POINT_OF_INTER_SUPPORTING_HYPERPLANE_LE",EXPOSED_POINT_OF_INTER_SUPPORTING_HYPERPLANE_LE; +"EXP_1",EXP_1; +"EXP_2",EXP_2; +"EXP_ADD",EXP_ADD; +"EXP_EQ_0",EXP_EQ_0; +"EXP_EQ_1",EXP_EQ_1; +"EXP_LOG",EXP_LOG; +"EXP_LT_0",EXP_LT_0; +"EXP_MONO_EQ",EXP_MONO_EQ; +"EXP_MONO_LE",EXP_MONO_LE; +"EXP_MONO_LE_IMP",EXP_MONO_LE_IMP; +"EXP_MONO_LT",EXP_MONO_LT; +"EXP_MONO_LT_IMP",EXP_MONO_LT_IMP; +"EXP_MULT",EXP_MULT; +"EXP_ONE",EXP_ONE; +"EXP_ZERO",EXP_ZERO; +"EXTEND_FL",EXTEND_FL; +"EXTEND_INSEG",EXTEND_INSEG; +"EXTEND_LINSEG",EXTEND_LINSEG; +"EXTEND_MAP_AFFINE_TO_SPHERE_COFINITE",EXTEND_MAP_AFFINE_TO_SPHERE_COFINITE; +"EXTEND_MAP_AFFINE_TO_SPHERE_COFINITE_GEN",EXTEND_MAP_AFFINE_TO_SPHERE_COFINITE_GEN; +"EXTEND_MAP_AFFINE_TO_SPHERE_COFINITE_SIMPLE",EXTEND_MAP_AFFINE_TO_SPHERE_COFINITE_SIMPLE; +"EXTEND_MAP_CELL_COMPLEX_TO_SPHERE",EXTEND_MAP_CELL_COMPLEX_TO_SPHERE; +"EXTEND_MAP_CELL_COMPLEX_TO_SPHERE_COFINITE",EXTEND_MAP_CELL_COMPLEX_TO_SPHERE_COFINITE; +"EXTEND_MAP_SPHERE_TO_SPHERE",EXTEND_MAP_SPHERE_TO_SPHERE; +"EXTEND_MAP_SPHERE_TO_SPHERE_COFINITE",EXTEND_MAP_SPHERE_TO_SPHERE_COFINITE; +"EXTEND_MAP_SPHERE_TO_SPHERE_COFINITE_GEN",EXTEND_MAP_SPHERE_TO_SPHERE_COFINITE_GEN; +"EXTEND_MAP_SPHERE_TO_SPHERE_GEN",EXTEND_MAP_SPHERE_TO_SPHERE_GEN; +"EXTEND_MAP_UNIV_TO_SPHERE_COFINITE",EXTEND_MAP_UNIV_TO_SPHERE_COFINITE; +"EXTEND_MAP_UNIV_TO_SPHERE_NO_BOUNDED_COMPONENT",EXTEND_MAP_UNIV_TO_SPHERE_NO_BOUNDED_COMPONENT; +"EXTEND_TO_AFFINE_BASIS",EXTEND_TO_AFFINE_BASIS; +"EXTENSION",EXTENSION; +"EXTREME_POINTS_OF_CONVEX_HULL",EXTREME_POINTS_OF_CONVEX_HULL; +"EXTREME_POINTS_OF_CONVEX_HULL_EQ",EXTREME_POINTS_OF_CONVEX_HULL_EQ; +"EXTREME_POINTS_OF_LINEAR_IMAGE",EXTREME_POINTS_OF_LINEAR_IMAGE; +"EXTREME_POINTS_OF_TRANSLATION",EXTREME_POINTS_OF_TRANSLATION; +"EXTREME_POINT_EXISTS_CONVEX",EXTREME_POINT_EXISTS_CONVEX; +"EXTREME_POINT_NOT_IN_INTERIOR",EXTREME_POINT_NOT_IN_INTERIOR; +"EXTREME_POINT_NOT_IN_RELATIVE_INTERIOR",EXTREME_POINT_NOT_IN_RELATIVE_INTERIOR; +"EXTREME_POINT_OF_CONIC",EXTREME_POINT_OF_CONIC; +"EXTREME_POINT_OF_CONVEX_HULL",EXTREME_POINT_OF_CONVEX_HULL; +"EXTREME_POINT_OF_CONVEX_HULL_2",EXTREME_POINT_OF_CONVEX_HULL_2; +"EXTREME_POINT_OF_CONVEX_HULL_AFFINE_INDEPENDENT",EXTREME_POINT_OF_CONVEX_HULL_AFFINE_INDEPENDENT; +"EXTREME_POINT_OF_CONVEX_HULL_CONVEX_INDEPENDENT",EXTREME_POINT_OF_CONVEX_HULL_CONVEX_INDEPENDENT; +"EXTREME_POINT_OF_CONVEX_HULL_EQ",EXTREME_POINT_OF_CONVEX_HULL_EQ; +"EXTREME_POINT_OF_CONVEX_HULL_INSERT",EXTREME_POINT_OF_CONVEX_HULL_INSERT; +"EXTREME_POINT_OF_CONVEX_HULL_INSERT_EQ",EXTREME_POINT_OF_CONVEX_HULL_INSERT_EQ; +"EXTREME_POINT_OF_EMPTY",EXTREME_POINT_OF_EMPTY; +"EXTREME_POINT_OF_FACE",EXTREME_POINT_OF_FACE; +"EXTREME_POINT_OF_INTER",EXTREME_POINT_OF_INTER; +"EXTREME_POINT_OF_INTER_SUPPORTING_HYPERPLANE_GE",EXTREME_POINT_OF_INTER_SUPPORTING_HYPERPLANE_GE; +"EXTREME_POINT_OF_INTER_SUPPORTING_HYPERPLANE_LE",EXTREME_POINT_OF_INTER_SUPPORTING_HYPERPLANE_LE; +"EXTREME_POINT_OF_LINEAR_IMAGE",EXTREME_POINT_OF_LINEAR_IMAGE; +"EXTREME_POINT_OF_MIDPOINT",EXTREME_POINT_OF_MIDPOINT; +"EXTREME_POINT_OF_SEGMENT",EXTREME_POINT_OF_SEGMENT; +"EXTREME_POINT_OF_SING",EXTREME_POINT_OF_SING; +"EXTREME_POINT_OF_STILLCONVEX",EXTREME_POINT_OF_STILLCONVEX; +"EXTREME_POINT_OF_TRANSLATION_EQ",EXTREME_POINT_OF_TRANSLATION_EQ; +"EX_IMP",EX_IMP; +"EX_MAP",EX_MAP; +"EX_MEM",EX_MEM; +"E_APPROX_32",E_APPROX_32; +"FACES_OF_LINEAR_IMAGE",FACES_OF_LINEAR_IMAGE; +"FACES_OF_SIMPLEX",FACES_OF_SIMPLEX; +"FACES_OF_TRANSLATION",FACES_OF_TRANSLATION; +"FACETS_OF_POLYHEDRON_EXPLICIT_DISTINCT",FACETS_OF_POLYHEDRON_EXPLICIT_DISTINCT; +"FACET_OF_CONVEX_HULL_AFFINE_INDEPENDENT",FACET_OF_CONVEX_HULL_AFFINE_INDEPENDENT; +"FACET_OF_CONVEX_HULL_AFFINE_INDEPENDENT_ALT",FACET_OF_CONVEX_HULL_AFFINE_INDEPENDENT_ALT; +"FACET_OF_EMPTY",FACET_OF_EMPTY; +"FACET_OF_HALFSPACE_GE",FACET_OF_HALFSPACE_GE; +"FACET_OF_HALFSPACE_LE",FACET_OF_HALFSPACE_LE; +"FACET_OF_IMP_FACE_OF",FACET_OF_IMP_FACE_OF; +"FACET_OF_IMP_PROPER",FACET_OF_IMP_PROPER; +"FACET_OF_IMP_SUBSET",FACET_OF_IMP_SUBSET; +"FACET_OF_LINEAR_IMAGE",FACET_OF_LINEAR_IMAGE; +"FACET_OF_POLYHEDRON",FACET_OF_POLYHEDRON; +"FACET_OF_POLYHEDRON_EXPLICIT",FACET_OF_POLYHEDRON_EXPLICIT; +"FACET_OF_REFL",FACET_OF_REFL; +"FACET_OF_TRANSLATION_EQ",FACET_OF_TRANSLATION_EQ; +"FACE_OF_AFFINE_EQ",FACE_OF_AFFINE_EQ; +"FACE_OF_AFFINE_TRIVIAL",FACE_OF_AFFINE_TRIVIAL; +"FACE_OF_AFF_DIM_LT",FACE_OF_AFF_DIM_LT; +"FACE_OF_CONIC",FACE_OF_CONIC; +"FACE_OF_CONVEX_HULLS",FACE_OF_CONVEX_HULLS; +"FACE_OF_CONVEX_HULL_AFFINE_INDEPENDENT",FACE_OF_CONVEX_HULL_AFFINE_INDEPENDENT; +"FACE_OF_CONVEX_HULL_INSERT",FACE_OF_CONVEX_HULL_INSERT; +"FACE_OF_CONVEX_HULL_INSERT_EQ",FACE_OF_CONVEX_HULL_INSERT_EQ; +"FACE_OF_CONVEX_HULL_SUBSET",FACE_OF_CONVEX_HULL_SUBSET; +"FACE_OF_DISJOINT_INTERIOR",FACE_OF_DISJOINT_INTERIOR; +"FACE_OF_DISJOINT_RELATIVE_INTERIOR",FACE_OF_DISJOINT_RELATIVE_INTERIOR; +"FACE_OF_EMPTY",FACE_OF_EMPTY; +"FACE_OF_EQ",FACE_OF_EQ; +"FACE_OF_FACE",FACE_OF_FACE; +"FACE_OF_HALFSPACE_GE",FACE_OF_HALFSPACE_GE; +"FACE_OF_HALFSPACE_LE",FACE_OF_HALFSPACE_LE; +"FACE_OF_IMP_CLOSED",FACE_OF_IMP_CLOSED; +"FACE_OF_IMP_COMPACT",FACE_OF_IMP_COMPACT; +"FACE_OF_IMP_CONVEX",FACE_OF_IMP_CONVEX; +"FACE_OF_IMP_SUBSET",FACE_OF_IMP_SUBSET; +"FACE_OF_INTER",FACE_OF_INTER; +"FACE_OF_INTERS",FACE_OF_INTERS; +"FACE_OF_INTER_INTER",FACE_OF_INTER_INTER; +"FACE_OF_INTER_SUBFACE",FACE_OF_INTER_SUBFACE; +"FACE_OF_INTER_SUPPORTING_HYPERPLANE_GE",FACE_OF_INTER_SUPPORTING_HYPERPLANE_GE; +"FACE_OF_INTER_SUPPORTING_HYPERPLANE_GE_STRONG",FACE_OF_INTER_SUPPORTING_HYPERPLANE_GE_STRONG; +"FACE_OF_INTER_SUPPORTING_HYPERPLANE_LE",FACE_OF_INTER_SUPPORTING_HYPERPLANE_LE; +"FACE_OF_INTER_SUPPORTING_HYPERPLANE_LE_STRONG",FACE_OF_INTER_SUPPORTING_HYPERPLANE_LE_STRONG; +"FACE_OF_LINEAR_IMAGE",FACE_OF_LINEAR_IMAGE; +"FACE_OF_PCROSS",FACE_OF_PCROSS; +"FACE_OF_PCROSS_DECOMP",FACE_OF_PCROSS_DECOMP; +"FACE_OF_PCROSS_EQ",FACE_OF_PCROSS_EQ; +"FACE_OF_POLYHEDRON",FACE_OF_POLYHEDRON; +"FACE_OF_POLYHEDRON_EXPLICIT",FACE_OF_POLYHEDRON_EXPLICIT; +"FACE_OF_POLYHEDRON_POLYHEDRON",FACE_OF_POLYHEDRON_POLYHEDRON; +"FACE_OF_POLYHEDRON_SUBSET_EXPLICIT",FACE_OF_POLYHEDRON_SUBSET_EXPLICIT; +"FACE_OF_POLYHEDRON_SUBSET_FACET",FACE_OF_POLYHEDRON_SUBSET_FACET; +"FACE_OF_POLYTOPE_POLYTOPE",FACE_OF_POLYTOPE_POLYTOPE; +"FACE_OF_REFL",FACE_OF_REFL; +"FACE_OF_REFL_EQ",FACE_OF_REFL_EQ; +"FACE_OF_SIMPLEX_SUBSET",FACE_OF_SIMPLEX_SUBSET; +"FACE_OF_SING",FACE_OF_SING; +"FACE_OF_SLICE",FACE_OF_SLICE; +"FACE_OF_STILLCONVEX",FACE_OF_STILLCONVEX; +"FACE_OF_SUBSET",FACE_OF_SUBSET; +"FACE_OF_SUBSET_RELATIVE_BOUNDARY",FACE_OF_SUBSET_RELATIVE_BOUNDARY; +"FACE_OF_SUBSET_RELATIVE_FRONTIER",FACE_OF_SUBSET_RELATIVE_FRONTIER; +"FACE_OF_TRANS",FACE_OF_TRANS; +"FACE_OF_TRANSLATION_EQ",FACE_OF_TRANSLATION_EQ; +"FACT",FACT; +"FACT_LE",FACT_LE; +"FACT_LT",FACT_LT; +"FACT_MONO",FACT_MONO; +"FACT_NZ",FACT_NZ; +"FARKAS_LEMMA",FARKAS_LEMMA; +"FARKAS_LEMMA_ALT",FARKAS_LEMMA_ALT; +"FASHODA",FASHODA; +"FASHODA_INTERLACE",FASHODA_INTERLACE; +"FASHODA_UNIT",FASHODA_UNIT; +"FASHODA_UNIT_PATH",FASHODA_UNIT_PATH; +"FCONS",FCONS; +"FCONS_UNDO",FCONS_UNDO; +"FILTER",FILTER; +"FILTER_APPEND",FILTER_APPEND; +"FILTER_MAP",FILTER_MAP; +"FINE_DIVISION_EXISTS",FINE_DIVISION_EXISTS; +"FINE_INTER",FINE_INTER; +"FINE_INTERS",FINE_INTERS; +"FINE_SUBSET",FINE_SUBSET; +"FINE_UNION",FINE_UNION; +"FINE_UNIONS",FINE_UNIONS; +"FINITELY_GENERATED_CONIC_POLYHEDRON",FINITELY_GENERATED_CONIC_POLYHEDRON; +"FINITE_BALL",FINITE_BALL; +"FINITE_BITSET",FINITE_BITSET; +"FINITE_BOOL",FINITE_BOOL; +"FINITE_BOUNDED_FUNCTIONS",FINITE_BOUNDED_FUNCTIONS; +"FINITE_CARD_COMPLEX_ROOTS_UNITY",FINITE_CARD_COMPLEX_ROOTS_UNITY; +"FINITE_CARD_COMPLEX_ROOTS_UNITY_EXPLICIT",FINITE_CARD_COMPLEX_ROOTS_UNITY_EXPLICIT; +"FINITE_CARD_LT",FINITE_CARD_LT; +"FINITE_CART",FINITE_CART; +"FINITE_CART_SUBSET_LEMMA",FINITE_CART_SUBSET_LEMMA; +"FINITE_CART_UNIV",FINITE_CART_UNIV; +"FINITE_CASES",FINITE_CASES; +"FINITE_CBALL",FINITE_CBALL; +"FINITE_COLUMNS",FINITE_COLUMNS; +"FINITE_COMPLEX_ROOTS_UNITY",FINITE_COMPLEX_ROOTS_UNITY; +"FINITE_COMPONENTS",FINITE_COMPONENTS; +"FINITE_CROSS",FINITE_CROSS; +"FINITE_DELETE",FINITE_DELETE; +"FINITE_DELETE_IMP",FINITE_DELETE_IMP; +"FINITE_DIFF",FINITE_DIFF; +"FINITE_EMPTY",FINITE_EMPTY; +"FINITE_EMPTY_INTERIOR",FINITE_EMPTY_INTERIOR; +"FINITE_FACES_OF_SIMPLEX",FINITE_FACES_OF_SIMPLEX; +"FINITE_FINITE_IMAGE",FINITE_FINITE_IMAGE; +"FINITE_FINITE_PREIMAGE",FINITE_FINITE_PREIMAGE; +"FINITE_FINITE_PREIMAGE_GENERAL",FINITE_FINITE_PREIMAGE_GENERAL; +"FINITE_FINITE_UNIONS",FINITE_FINITE_UNIONS; +"FINITE_FUNSPACE",FINITE_FUNSPACE; +"FINITE_FUNSPACE_UNIV",FINITE_FUNSPACE_UNIV; +"FINITE_HAS_SIZE",FINITE_HAS_SIZE; +"FINITE_IMAGE",FINITE_IMAGE; +"FINITE_IMAGE_EXPAND",FINITE_IMAGE_EXPAND; +"FINITE_IMAGE_IMAGE",FINITE_IMAGE_IMAGE; +"FINITE_IMAGE_INJ",FINITE_IMAGE_INJ; +"FINITE_IMAGE_INJ_EQ",FINITE_IMAGE_INJ_EQ; +"FINITE_IMAGE_INJ_GENERAL",FINITE_IMAGE_INJ_GENERAL; +"FINITE_IMP_BOUNDED",FINITE_IMP_BOUNDED; +"FINITE_IMP_BOUNDED_CONVEX_HULL",FINITE_IMP_BOUNDED_CONVEX_HULL; +"FINITE_IMP_CLOSED",FINITE_IMP_CLOSED; +"FINITE_IMP_CLOSED_IN",FINITE_IMP_CLOSED_IN; +"FINITE_IMP_COMPACT",FINITE_IMP_COMPACT; +"FINITE_IMP_COMPACT_CONVEX_HULL",FINITE_IMP_COMPACT_CONVEX_HULL; +"FINITE_IMP_COUNTABLE",FINITE_IMP_COUNTABLE; +"FINITE_IMP_NOT_OPEN",FINITE_IMP_NOT_OPEN; +"FINITE_INDEX_INJ",FINITE_INDEX_INJ; +"FINITE_INDEX_INRANGE",FINITE_INDEX_INRANGE; +"FINITE_INDEX_INRANGE_2",FINITE_INDEX_INRANGE_2; +"FINITE_INDEX_NUMBERS",FINITE_INDEX_NUMBERS; +"FINITE_INDEX_NUMSEG",FINITE_INDEX_NUMSEG; +"FINITE_INDEX_NUMSEG_SPECIAL",FINITE_INDEX_NUMSEG_SPECIAL; +"FINITE_INDEX_WORKS",FINITE_INDEX_WORKS; +"FINITE_INDUCT",FINITE_INDUCT; +"FINITE_INDUCT_DELETE",FINITE_INDUCT_DELETE; +"FINITE_INDUCT_STRONG",FINITE_INDUCT_STRONG; +"FINITE_INSERT",FINITE_INSERT; +"FINITE_INTER",FINITE_INTER; +"FINITE_INTERVAL_1",FINITE_INTERVAL_1; +"FINITE_INTER_COLLINEAR_OPEN_SEGMENTS",FINITE_INTER_COLLINEAR_OPEN_SEGMENTS; +"FINITE_INTER_NUMSEG",FINITE_INTER_NUMSEG; +"FINITE_INTSEG",FINITE_INTSEG; +"FINITE_MULTIVECTOR",FINITE_MULTIVECTOR; +"FINITE_NUMSEG",FINITE_NUMSEG; +"FINITE_NUMSEG_LE",FINITE_NUMSEG_LE; +"FINITE_NUMSEG_LT",FINITE_NUMSEG_LT; +"FINITE_PCROSS",FINITE_PCROSS; +"FINITE_PCROSS_EQ",FINITE_PCROSS_EQ; +"FINITE_PERMUTATIONS",FINITE_PERMUTATIONS; +"FINITE_POLYHEDRON_EXPOSED_FACES",FINITE_POLYHEDRON_EXPOSED_FACES; +"FINITE_POLYHEDRON_EXTREME_POINTS",FINITE_POLYHEDRON_EXTREME_POINTS; +"FINITE_POLYHEDRON_FACES",FINITE_POLYHEDRON_FACES; +"FINITE_POLYHEDRON_FACETS",FINITE_POLYHEDRON_FACETS; +"FINITE_POLYTOPE_FACES",FINITE_POLYTOPE_FACES; +"FINITE_POLYTOPE_FACETS",FINITE_POLYTOPE_FACETS; +"FINITE_POWERSET",FINITE_POWERSET; +"FINITE_PRODUCT",FINITE_PRODUCT; +"FINITE_PRODUCT_DEPENDENT",FINITE_PRODUCT_DEPENDENT; +"FINITE_REAL_INTERVAL",FINITE_REAL_INTERVAL; +"FINITE_RECURSION",FINITE_RECURSION; +"FINITE_RECURSION_DELETE",FINITE_RECURSION_DELETE; +"FINITE_RESTRICT",FINITE_RESTRICT; +"FINITE_ROWS",FINITE_ROWS; +"FINITE_RULES",FINITE_RULES; +"FINITE_SEGMENT",FINITE_SEGMENT; +"FINITE_SET_AVOID",FINITE_SET_AVOID; +"FINITE_SET_OF_LIST",FINITE_SET_OF_LIST; +"FINITE_SIMPLICES",FINITE_SIMPLICES; +"FINITE_SING",FINITE_SING; +"FINITE_SPHERE",FINITE_SPHERE; +"FINITE_SPHERE_1",FINITE_SPHERE_1; +"FINITE_STDBASIS",FINITE_STDBASIS; +"FINITE_SUBSET",FINITE_SUBSET; +"FINITE_SUBSET_IMAGE",FINITE_SUBSET_IMAGE; +"FINITE_SUBSET_IMAGE_IMP",FINITE_SUBSET_IMAGE_IMP; +"FINITE_SUM_IMAGE",FINITE_SUM_IMAGE; +"FINITE_SUPPORT",FINITE_SUPPORT; +"FINITE_SUPPORT_DELTA",FINITE_SUPPORT_DELTA; +"FINITE_TRANSITIVITY_CHAIN",FINITE_TRANSITIVITY_CHAIN; +"FINITE_UNION",FINITE_UNION; +"FINITE_UNIONS",FINITE_UNIONS; +"FINITE_UNION_IMP",FINITE_UNION_IMP; +"FINREC",FINREC; +"FINREC_1_LEMMA",FINREC_1_LEMMA; +"FINREC_EXISTS_LEMMA",FINREC_EXISTS_LEMMA; +"FINREC_FUN",FINREC_FUN; +"FINREC_FUN_LEMMA",FINREC_FUN_LEMMA; +"FINREC_SUC_LEMMA",FINREC_SUC_LEMMA; +"FINREC_UNIQUE_LEMMA",FINREC_UNIQUE_LEMMA; +"FIRST_CARTAN_THM_DIM_1",FIRST_CARTAN_THM_DIM_1; +"FIXED_POINT_INESSENTIAL_SPHERE_MAP",FIXED_POINT_INESSENTIAL_SPHERE_MAP; +"FIXING_SWAPSEQ_DECREASE",FIXING_SWAPSEQ_DECREASE; +"FLATTEN_LEMMA",FLATTEN_LEMMA; +"FLOOR",FLOOR; +"FLOOR_DIV_DIV",FLOOR_DIV_DIV; +"FLOOR_DOUBLE",FLOOR_DOUBLE; +"FLOOR_EQ_0",FLOOR_EQ_0; +"FLOOR_FRAC",FLOOR_FRAC; +"FLOOR_MONO",FLOOR_MONO; +"FLOOR_NUM",FLOOR_NUM; +"FLOOR_POS",FLOOR_POS; +"FLOOR_POS_LE",FLOOR_POS_LE; +"FLOOR_UNIQUE",FLOOR_UNIQUE; +"FL_RESTRICT",FL_RESTRICT; +"FL_RESTRICTED_SUBSET",FL_RESTRICTED_SUBSET; +"FL_SUC",FL_SUC; +"FNIL",FNIL; +"FORALL_1",FORALL_1; +"FORALL_2",FORALL_2; +"FORALL_3",FORALL_3; +"FORALL_4",FORALL_4; +"FORALL_ALL",FORALL_ALL; +"FORALL_AND_THM",FORALL_AND_THM; +"FORALL_BOOL_THM",FORALL_BOOL_THM; +"FORALL_CNJ",FORALL_CNJ; +"FORALL_COMPLEX",FORALL_COMPLEX; +"FORALL_COUNTABLE_AS_IMAGE",FORALL_COUNTABLE_AS_IMAGE; +"FORALL_COUNTABLE_SUBSET_IMAGE",FORALL_COUNTABLE_SUBSET_IMAGE; +"FORALL_CURRY",FORALL_CURRY; +"FORALL_DEF",FORALL_DEF; +"FORALL_DIMINDEX_1",FORALL_DIMINDEX_1; +"FORALL_DOT_EQ_0",FORALL_DOT_EQ_0; +"FORALL_DROP",FORALL_DROP; +"FORALL_DROP_FUN",FORALL_DROP_FUN; +"FORALL_DROP_IMAGE",FORALL_DROP_IMAGE; +"FORALL_EVENTUALLY",FORALL_EVENTUALLY; +"FORALL_FINITE_INDEX",FORALL_FINITE_INDEX; +"FORALL_FINITE_SUBSET_IMAGE",FORALL_FINITE_SUBSET_IMAGE; +"FORALL_INTEGER",FORALL_INTEGER; +"FORALL_IN_CLAUSES",FORALL_IN_CLAUSES; +"FORALL_IN_CLOSURE",FORALL_IN_CLOSURE; +"FORALL_IN_DIVISION",FORALL_IN_DIVISION; +"FORALL_IN_DIVISION_NONEMPTY",FORALL_IN_DIVISION_NONEMPTY; +"FORALL_IN_GSPEC",FORALL_IN_GSPEC; +"FORALL_IN_IMAGE",FORALL_IN_IMAGE; +"FORALL_IN_INSERT",FORALL_IN_INSERT; +"FORALL_IN_PCROSS",FORALL_IN_PCROSS; +"FORALL_IN_UNIONS",FORALL_IN_UNIONS; +"FORALL_LIFT",FORALL_LIFT; +"FORALL_LIFT_FUN",FORALL_LIFT_FUN; +"FORALL_LIFT_IMAGE",FORALL_LIFT_IMAGE; +"FORALL_MULTIVECTOR",FORALL_MULTIVECTOR; +"FORALL_NOT_THM",FORALL_NOT_THM; +"FORALL_OF_DROP",FORALL_OF_DROP; +"FORALL_OF_PASTECART",FORALL_OF_PASTECART; +"FORALL_OPTION",FORALL_OPTION; +"FORALL_PAIRED_THM",FORALL_PAIRED_THM; +"FORALL_PAIR_THM",FORALL_PAIR_THM; +"FORALL_PASTECART",FORALL_PASTECART; +"FORALL_POS_MONO",FORALL_POS_MONO; +"FORALL_POS_MONO_1",FORALL_POS_MONO_1; +"FORALL_REAL",FORALL_REAL; +"FORALL_REAL_ONE",FORALL_REAL_ONE; +"FORALL_SETCODE",FORALL_SETCODE; +"FORALL_SIMP",FORALL_SIMP; +"FORALL_SUBSET_IMAGE",FORALL_SUBSET_IMAGE; +"FORALL_SUBSET_UNION",FORALL_SUBSET_UNION; +"FORALL_SUC",FORALL_SUC; +"FORALL_SUM_THM",FORALL_SUM_THM; +"FORALL_TRIPLED_THM",FORALL_TRIPLED_THM; +"FORALL_UNCURRY",FORALL_UNCURRY; +"FORALL_UNWIND_THM1",FORALL_UNWIND_THM1; +"FORALL_UNWIND_THM2",FORALL_UNWIND_THM2; +"FORALL_VECTOR_1",FORALL_VECTOR_1; +"FORALL_VECTOR_2",FORALL_VECTOR_2; +"FORALL_VECTOR_3",FORALL_VECTOR_3; +"FORALL_VECTOR_4",FORALL_VECTOR_4; +"FRAC_FLOOR",FRAC_FLOOR; +"FRAC_NUM",FRAC_NUM; +"FRAC_UNIQUE",FRAC_UNIQUE; +"FRECHET_DERIVATIVE_AT",FRECHET_DERIVATIVE_AT; +"FRECHET_DERIVATIVE_CONST_AT",FRECHET_DERIVATIVE_CONST_AT; +"FRECHET_DERIVATIVE_UNIQUE_AT",FRECHET_DERIVATIVE_UNIQUE_AT; +"FRECHET_DERIVATIVE_UNIQUE_WITHIN",FRECHET_DERIVATIVE_UNIQUE_WITHIN; +"FRECHET_DERIVATIVE_UNIQUE_WITHIN_CLOSED_INTERVAL",FRECHET_DERIVATIVE_UNIQUE_WITHIN_CLOSED_INTERVAL; +"FRECHET_DERIVATIVE_UNIQUE_WITHIN_OPEN_INTERVAL",FRECHET_DERIVATIVE_UNIQUE_WITHIN_OPEN_INTERVAL; +"FRECHET_DERIVATIVE_WITHIN_CLOSED_INTERVAL",FRECHET_DERIVATIVE_WITHIN_CLOSED_INTERVAL; +"FRECHET_DERIVATIVE_WORKS",FRECHET_DERIVATIVE_WORKS; +"FROM_0",FROM_0; +"FROM_INTER_NUMSEG",FROM_INTER_NUMSEG; +"FROM_INTER_NUMSEG_GEN",FROM_INTER_NUMSEG_GEN; +"FRONTIER_BALL",FRONTIER_BALL; +"FRONTIER_BIJECTIVE_LINEAR_IMAGE",FRONTIER_BIJECTIVE_LINEAR_IMAGE; +"FRONTIER_CBALL",FRONTIER_CBALL; +"FRONTIER_CLOSED",FRONTIER_CLOSED; +"FRONTIER_CLOSED_INTERVAL",FRONTIER_CLOSED_INTERVAL; +"FRONTIER_CLOSURES",FRONTIER_CLOSURES; +"FRONTIER_CLOSURE_CONVEX",FRONTIER_CLOSURE_CONVEX; +"FRONTIER_COMPLEMENT",FRONTIER_COMPLEMENT; +"FRONTIER_CONVEX_HULL_CASES",FRONTIER_CONVEX_HULL_CASES; +"FRONTIER_CONVEX_HULL_EXPLICIT",FRONTIER_CONVEX_HULL_EXPLICIT; +"FRONTIER_DISJOINT_EQ",FRONTIER_DISJOINT_EQ; +"FRONTIER_EMPTY",FRONTIER_EMPTY; +"FRONTIER_EQ_EMPTY",FRONTIER_EQ_EMPTY; +"FRONTIER_FRONTIER_FRONTIER",FRONTIER_FRONTIER_FRONTIER; +"FRONTIER_FRONTIER_SUBSET",FRONTIER_FRONTIER_SUBSET; +"FRONTIER_HALFSPACE_GE",FRONTIER_HALFSPACE_GE; +"FRONTIER_HALFSPACE_GT",FRONTIER_HALFSPACE_GT; +"FRONTIER_HALFSPACE_LE",FRONTIER_HALFSPACE_LE; +"FRONTIER_HALFSPACE_LT",FRONTIER_HALFSPACE_LT; +"FRONTIER_INJECTIVE_LINEAR_IMAGE",FRONTIER_INJECTIVE_LINEAR_IMAGE; +"FRONTIER_INSIDE_SUBSET",FRONTIER_INSIDE_SUBSET; +"FRONTIER_INTERIORS",FRONTIER_INTERIORS; +"FRONTIER_INTER_SUBSET",FRONTIER_INTER_SUBSET; +"FRONTIER_MINIMAL_SEPARATING_CLOSED",FRONTIER_MINIMAL_SEPARATING_CLOSED; +"FRONTIER_NOT_EMPTY",FRONTIER_NOT_EMPTY; +"FRONTIER_OF_COMPONENTS_CLOSED_COMPLEMENT",FRONTIER_OF_COMPONENTS_CLOSED_COMPLEMENT; +"FRONTIER_OF_COMPONENTS_SUBSET",FRONTIER_OF_COMPONENTS_SUBSET; +"FRONTIER_OF_CONNECTED_COMPONENT_SUBSET",FRONTIER_OF_CONNECTED_COMPONENT_SUBSET; +"FRONTIER_OF_CONVEX_HULL",FRONTIER_OF_CONVEX_HULL; +"FRONTIER_OF_TRIANGLE",FRONTIER_OF_TRIANGLE; +"FRONTIER_OPEN_INTERVAL",FRONTIER_OPEN_INTERVAL; +"FRONTIER_OUTSIDE_SUBSET",FRONTIER_OUTSIDE_SUBSET; +"FRONTIER_RETRACT_OF_PUNCTURED_UNIVERSE",FRONTIER_RETRACT_OF_PUNCTURED_UNIVERSE; +"FRONTIER_SING",FRONTIER_SING; +"FRONTIER_STRADDLE",FRONTIER_STRADDLE; +"FRONTIER_SUBSET_CLOSED",FRONTIER_SUBSET_CLOSED; +"FRONTIER_SUBSET_COMPACT",FRONTIER_SUBSET_COMPACT; +"FRONTIER_SUBSET_EQ",FRONTIER_SUBSET_EQ; +"FRONTIER_SUBSET_RETRACTION",FRONTIER_SUBSET_RETRACTION; +"FRONTIER_SURJECTIVE_LINEAR_IMAGE",FRONTIER_SURJECTIVE_LINEAR_IMAGE; +"FRONTIER_TRANSLATION",FRONTIER_TRANSLATION; +"FRONTIER_UNION",FRONTIER_UNION; +"FRONTIER_UNIONS_SUBSET_CLOSURE",FRONTIER_UNIONS_SUBSET_CLOSURE; +"FRONTIER_UNION_SUBSET",FRONTIER_UNION_SUBSET; +"FRONTIER_UNIV",FRONTIER_UNIV; +"FST",FST; +"FSTCART_ADD",FSTCART_ADD; +"FSTCART_CMUL",FSTCART_CMUL; +"FSTCART_NEG",FSTCART_NEG; +"FSTCART_PASTECART",FSTCART_PASTECART; +"FSTCART_SUB",FSTCART_SUB; +"FSTCART_VEC",FSTCART_VEC; +"FSTCART_VSUM",FSTCART_VSUM; +"FST_DEF",FST_DEF; +"FTA",FTA; +"FUBINI_CLOSED_INTERVAL",FUBINI_CLOSED_INTERVAL; +"FUBINI_SIMPLE",FUBINI_SIMPLE; +"FUBINI_SIMPLE_ALT",FUBINI_SIMPLE_ALT; +"FUBINI_SIMPLE_COMPACT",FUBINI_SIMPLE_COMPACT; +"FUBINI_SIMPLE_COMPACT_STRONG",FUBINI_SIMPLE_COMPACT_STRONG; +"FUBINI_SIMPLE_CONVEX",FUBINI_SIMPLE_CONVEX; +"FUBINI_SIMPLE_CONVEX_STRONG",FUBINI_SIMPLE_CONVEX_STRONG; +"FUBINI_SIMPLE_LEMMA",FUBINI_SIMPLE_LEMMA; +"FUBINI_SIMPLE_OPEN",FUBINI_SIMPLE_OPEN; +"FUBINI_SIMPLE_OPEN_STRONG",FUBINI_SIMPLE_OPEN_STRONG; +"FULL_RANK_INJECTIVE",FULL_RANK_INJECTIVE; +"FULL_RANK_SURJECTIVE",FULL_RANK_SURJECTIVE; +"FUNCTION_CONVERGENT_SUBSEQUENCE",FUNCTION_CONVERGENT_SUBSEQUENCE; +"FUNCTION_FACTORS_LEFT",FUNCTION_FACTORS_LEFT; +"FUNCTION_FACTORS_LEFT_GEN",FUNCTION_FACTORS_LEFT_GEN; +"FUNCTION_FACTORS_RIGHT",FUNCTION_FACTORS_RIGHT; +"FUNCTION_FACTORS_RIGHT_GEN",FUNCTION_FACTORS_RIGHT_GEN; +"FUNDAMENTAL_THEOREM_OF_CALCULUS",FUNDAMENTAL_THEOREM_OF_CALCULUS; +"FUNDAMENTAL_THEOREM_OF_CALCULUS_INTERIOR",FUNDAMENTAL_THEOREM_OF_CALCULUS_INTERIOR; +"FUNDAMENTAL_THEOREM_OF_CALCULUS_INTERIOR_STRONG",FUNDAMENTAL_THEOREM_OF_CALCULUS_INTERIOR_STRONG; +"FUNDAMENTAL_THEOREM_OF_CALCULUS_STRONG",FUNDAMENTAL_THEOREM_OF_CALCULUS_STRONG; +"FUN_EQ_THM",FUN_EQ_THM; +"FUN_IN_IMAGE",FUN_IN_IMAGE; +"F_DEF",F_DEF; +"GABS_DEF",GABS_DEF; +"GAUGE_BALL",GAUGE_BALL; +"GAUGE_BALL_DEPENDENT",GAUGE_BALL_DEPENDENT; +"GAUGE_EXISTENCE_LEMMA",GAUGE_EXISTENCE_LEMMA; +"GAUGE_INTER",GAUGE_INTER; +"GAUGE_INTERS",GAUGE_INTERS; +"GAUGE_MODIFY",GAUGE_MODIFY; +"GAUGE_TRIVIAL",GAUGE_TRIVIAL; +"GE",GE; +"GENERAL_CONNECTED_OPEN",GENERAL_CONNECTED_OPEN; +"GEOM_ASSOC",GEOM_ASSOC; +"GEOM_LADD",GEOM_LADD; +"GEOM_LMUL",GEOM_LMUL; +"GEOM_LNEG",GEOM_LNEG; +"GEOM_LZERO",GEOM_LZERO; +"GEOM_MBASIS",GEOM_MBASIS; +"GEOM_MBASIS_SING",GEOM_MBASIS_SING; +"GEOM_RADD",GEOM_RADD; +"GEOM_RMUL",GEOM_RMUL; +"GEOM_RNEG",GEOM_RNEG; +"GEOM_RZERO",GEOM_RZERO; +"GEQ_DEF",GEQ_DEF; +"GE_C",GE_C; +"GE_REFL",GE_REFL; +"GRADE_ADD",GRADE_ADD; +"GRADE_CMUL",GRADE_CMUL; +"GRAM_SCHMIDT_STEP",GRAM_SCHMIDT_STEP; +"GRASSMANN_PLUCKER_2",GRASSMANN_PLUCKER_2; +"GRASSMANN_PLUCKER_3",GRASSMANN_PLUCKER_3; +"GRASSMANN_PLUCKER_4",GRASSMANN_PLUCKER_4; +"GSPEC",GSPEC; +"GT",GT; +"HALFSPACE_EQ_EMPTY_GE",HALFSPACE_EQ_EMPTY_GE; +"HALFSPACE_EQ_EMPTY_GT",HALFSPACE_EQ_EMPTY_GT; +"HALFSPACE_EQ_EMPTY_LE",HALFSPACE_EQ_EMPTY_LE; +"HALFSPACE_EQ_EMPTY_LT",HALFSPACE_EQ_EMPTY_LT; +"HAS_ANTIDERIVATIVE_LIMIT",HAS_ANTIDERIVATIVE_LIMIT; +"HAS_ANTIDERIVATIVE_SEQUENCE",HAS_ANTIDERIVATIVE_SEQUENCE; +"HAS_BOUNDED_REAL_VARIATION_AFFINITY2_EQ",HAS_BOUNDED_REAL_VARIATION_AFFINITY2_EQ; +"HAS_BOUNDED_REAL_VARIATION_AFFINITY_EQ",HAS_BOUNDED_REAL_VARIATION_AFFINITY_EQ; +"HAS_BOUNDED_REAL_VARIATION_COUNTABLE_DISCONTINUITIES",HAS_BOUNDED_REAL_VARIATION_COUNTABLE_DISCONTINUITIES; +"HAS_BOUNDED_REAL_VARIATION_DARBOUX",HAS_BOUNDED_REAL_VARIATION_DARBOUX; +"HAS_BOUNDED_REAL_VARIATION_DARBOUX_STRICT",HAS_BOUNDED_REAL_VARIATION_DARBOUX_STRICT; +"HAS_BOUNDED_REAL_VARIATION_DARBOUX_STRONG",HAS_BOUNDED_REAL_VARIATION_DARBOUX_STRONG; +"HAS_BOUNDED_REAL_VARIATION_LEFT_LIMIT",HAS_BOUNDED_REAL_VARIATION_LEFT_LIMIT; +"HAS_BOUNDED_REAL_VARIATION_ON_ABS",HAS_BOUNDED_REAL_VARIATION_ON_ABS; +"HAS_BOUNDED_REAL_VARIATION_ON_ADD",HAS_BOUNDED_REAL_VARIATION_ON_ADD; +"HAS_BOUNDED_REAL_VARIATION_ON_COMBINE",HAS_BOUNDED_REAL_VARIATION_ON_COMBINE; +"HAS_BOUNDED_REAL_VARIATION_ON_EMPTY",HAS_BOUNDED_REAL_VARIATION_ON_EMPTY; +"HAS_BOUNDED_REAL_VARIATION_ON_EQ",HAS_BOUNDED_REAL_VARIATION_ON_EQ; +"HAS_BOUNDED_REAL_VARIATION_ON_IMP_BOUNDED_ON_INTERVAL",HAS_BOUNDED_REAL_VARIATION_ON_IMP_BOUNDED_ON_INTERVAL; +"HAS_BOUNDED_REAL_VARIATION_ON_LMUL",HAS_BOUNDED_REAL_VARIATION_ON_LMUL; +"HAS_BOUNDED_REAL_VARIATION_ON_MAX",HAS_BOUNDED_REAL_VARIATION_ON_MAX; +"HAS_BOUNDED_REAL_VARIATION_ON_MIN",HAS_BOUNDED_REAL_VARIATION_ON_MIN; +"HAS_BOUNDED_REAL_VARIATION_ON_MUL",HAS_BOUNDED_REAL_VARIATION_ON_MUL; +"HAS_BOUNDED_REAL_VARIATION_ON_NEG",HAS_BOUNDED_REAL_VARIATION_ON_NEG; +"HAS_BOUNDED_REAL_VARIATION_ON_NULL",HAS_BOUNDED_REAL_VARIATION_ON_NULL; +"HAS_BOUNDED_REAL_VARIATION_ON_RMUL",HAS_BOUNDED_REAL_VARIATION_ON_RMUL; +"HAS_BOUNDED_REAL_VARIATION_ON_SUB",HAS_BOUNDED_REAL_VARIATION_ON_SUB; +"HAS_BOUNDED_REAL_VARIATION_ON_SUBSET",HAS_BOUNDED_REAL_VARIATION_ON_SUBSET; +"HAS_BOUNDED_REAL_VARIATION_REFLECT2_EQ",HAS_BOUNDED_REAL_VARIATION_REFLECT2_EQ; +"HAS_BOUNDED_REAL_VARIATION_REFLECT_EQ",HAS_BOUNDED_REAL_VARIATION_REFLECT_EQ; +"HAS_BOUNDED_REAL_VARIATION_REFLECT_EQ_INTERVAL",HAS_BOUNDED_REAL_VARIATION_REFLECT_EQ_INTERVAL; +"HAS_BOUNDED_REAL_VARIATION_RIGHT_LIMIT",HAS_BOUNDED_REAL_VARIATION_RIGHT_LIMIT; +"HAS_BOUNDED_REAL_VARIATION_TRANSLATION",HAS_BOUNDED_REAL_VARIATION_TRANSLATION; +"HAS_BOUNDED_REAL_VARIATION_TRANSLATION2_EQ",HAS_BOUNDED_REAL_VARIATION_TRANSLATION2_EQ; +"HAS_BOUNDED_REAL_VARIATION_TRANSLATION_EQ",HAS_BOUNDED_REAL_VARIATION_TRANSLATION_EQ; +"HAS_BOUNDED_REAL_VARIATION_TRANSLATION_EQ_INTERVAL",HAS_BOUNDED_REAL_VARIATION_TRANSLATION_EQ_INTERVAL; +"HAS_BOUNDED_SETVARIATION_ON",HAS_BOUNDED_SETVARIATION_ON; +"HAS_BOUNDED_SETVARIATION_ON_0",HAS_BOUNDED_SETVARIATION_ON_0; +"HAS_BOUNDED_SETVARIATION_ON_ADD",HAS_BOUNDED_SETVARIATION_ON_ADD; +"HAS_BOUNDED_SETVARIATION_ON_CMUL",HAS_BOUNDED_SETVARIATION_ON_CMUL; +"HAS_BOUNDED_SETVARIATION_ON_COMPONENTWISE",HAS_BOUNDED_SETVARIATION_ON_COMPONENTWISE; +"HAS_BOUNDED_SETVARIATION_ON_COMPOSE_LINEAR",HAS_BOUNDED_SETVARIATION_ON_COMPOSE_LINEAR; +"HAS_BOUNDED_SETVARIATION_ON_DIVISION",HAS_BOUNDED_SETVARIATION_ON_DIVISION; +"HAS_BOUNDED_SETVARIATION_ON_ELEMENTARY",HAS_BOUNDED_SETVARIATION_ON_ELEMENTARY; +"HAS_BOUNDED_SETVARIATION_ON_EQ",HAS_BOUNDED_SETVARIATION_ON_EQ; +"HAS_BOUNDED_SETVARIATION_ON_IMP_BOUNDED_ON_SUBINTERVALS",HAS_BOUNDED_SETVARIATION_ON_IMP_BOUNDED_ON_SUBINTERVALS; +"HAS_BOUNDED_SETVARIATION_ON_INTERVAL",HAS_BOUNDED_SETVARIATION_ON_INTERVAL; +"HAS_BOUNDED_SETVARIATION_ON_NEG",HAS_BOUNDED_SETVARIATION_ON_NEG; +"HAS_BOUNDED_SETVARIATION_ON_NORM",HAS_BOUNDED_SETVARIATION_ON_NORM; +"HAS_BOUNDED_SETVARIATION_ON_NULL",HAS_BOUNDED_SETVARIATION_ON_NULL; +"HAS_BOUNDED_SETVARIATION_ON_SUB",HAS_BOUNDED_SETVARIATION_ON_SUB; +"HAS_BOUNDED_SETVARIATION_ON_SUBSET",HAS_BOUNDED_SETVARIATION_ON_SUBSET; +"HAS_BOUNDED_SETVARIATION_ON_UNIV",HAS_BOUNDED_SETVARIATION_ON_UNIV; +"HAS_BOUNDED_SETVARIATION_REFLECT2_EQ",HAS_BOUNDED_SETVARIATION_REFLECT2_EQ; +"HAS_BOUNDED_SETVARIATION_TRANSLATION",HAS_BOUNDED_SETVARIATION_TRANSLATION; +"HAS_BOUNDED_SETVARIATION_TRANSLATION2_EQ",HAS_BOUNDED_SETVARIATION_TRANSLATION2_EQ; +"HAS_BOUNDED_SETVARIATION_WORKS",HAS_BOUNDED_SETVARIATION_WORKS; +"HAS_BOUNDED_SETVARIATION_WORKS_ON_ELEMENTARY",HAS_BOUNDED_SETVARIATION_WORKS_ON_ELEMENTARY; +"HAS_BOUNDED_SETVARIATION_WORKS_ON_INTERVAL",HAS_BOUNDED_SETVARIATION_WORKS_ON_INTERVAL; +"HAS_BOUNDED_VARIATION_ABSOLUTELY_INTEGRABLE_DERIVATIVE",HAS_BOUNDED_VARIATION_ABSOLUTELY_INTEGRABLE_DERIVATIVE; +"HAS_BOUNDED_VARIATION_AFFINITY2_EQ",HAS_BOUNDED_VARIATION_AFFINITY2_EQ; +"HAS_BOUNDED_VARIATION_AFFINITY_EQ",HAS_BOUNDED_VARIATION_AFFINITY_EQ; +"HAS_BOUNDED_VARIATION_COMPOSE_DECREASING",HAS_BOUNDED_VARIATION_COMPOSE_DECREASING; +"HAS_BOUNDED_VARIATION_COMPOSE_INCREASING",HAS_BOUNDED_VARIATION_COMPOSE_INCREASING; +"HAS_BOUNDED_VARIATION_COUNTABLE_DISCONTINUITIES",HAS_BOUNDED_VARIATION_COUNTABLE_DISCONTINUITIES; +"HAS_BOUNDED_VARIATION_DARBOUX",HAS_BOUNDED_VARIATION_DARBOUX; +"HAS_BOUNDED_VARIATION_DARBOUX_STRICT",HAS_BOUNDED_VARIATION_DARBOUX_STRICT; +"HAS_BOUNDED_VARIATION_DARBOUX_STRONG",HAS_BOUNDED_VARIATION_DARBOUX_STRONG; +"HAS_BOUNDED_VARIATION_INTEGRABLE_NORM_DERIVATIVE",HAS_BOUNDED_VARIATION_INTEGRABLE_NORM_DERIVATIVE; +"HAS_BOUNDED_VARIATION_ON_ADD",HAS_BOUNDED_VARIATION_ON_ADD; +"HAS_BOUNDED_VARIATION_ON_CMUL",HAS_BOUNDED_VARIATION_ON_CMUL; +"HAS_BOUNDED_VARIATION_ON_COMBINE",HAS_BOUNDED_VARIATION_ON_COMBINE; +"HAS_BOUNDED_VARIATION_ON_COMPONENTWISE",HAS_BOUNDED_VARIATION_ON_COMPONENTWISE; +"HAS_BOUNDED_VARIATION_ON_COMPOSE_LINEAR",HAS_BOUNDED_VARIATION_ON_COMPOSE_LINEAR; +"HAS_BOUNDED_VARIATION_ON_CONST",HAS_BOUNDED_VARIATION_ON_CONST; +"HAS_BOUNDED_VARIATION_ON_DIVISION",HAS_BOUNDED_VARIATION_ON_DIVISION; +"HAS_BOUNDED_VARIATION_ON_EMPTY",HAS_BOUNDED_VARIATION_ON_EMPTY; +"HAS_BOUNDED_VARIATION_ON_EQ",HAS_BOUNDED_VARIATION_ON_EQ; +"HAS_BOUNDED_VARIATION_ON_ID",HAS_BOUNDED_VARIATION_ON_ID; +"HAS_BOUNDED_VARIATION_ON_IMP_BOUNDED_ON_INTERVAL",HAS_BOUNDED_VARIATION_ON_IMP_BOUNDED_ON_INTERVAL; +"HAS_BOUNDED_VARIATION_ON_IMP_BOUNDED_ON_SUBINTERVALS",HAS_BOUNDED_VARIATION_ON_IMP_BOUNDED_ON_SUBINTERVALS; +"HAS_BOUNDED_VARIATION_ON_LINEAR_IMAGE",HAS_BOUNDED_VARIATION_ON_LINEAR_IMAGE; +"HAS_BOUNDED_VARIATION_ON_MAX",HAS_BOUNDED_VARIATION_ON_MAX; +"HAS_BOUNDED_VARIATION_ON_MIN",HAS_BOUNDED_VARIATION_ON_MIN; +"HAS_BOUNDED_VARIATION_ON_MUL",HAS_BOUNDED_VARIATION_ON_MUL; +"HAS_BOUNDED_VARIATION_ON_NEG",HAS_BOUNDED_VARIATION_ON_NEG; +"HAS_BOUNDED_VARIATION_ON_NORM",HAS_BOUNDED_VARIATION_ON_NORM; +"HAS_BOUNDED_VARIATION_ON_NULL",HAS_BOUNDED_VARIATION_ON_NULL; +"HAS_BOUNDED_VARIATION_ON_REFLECT",HAS_BOUNDED_VARIATION_ON_REFLECT; +"HAS_BOUNDED_VARIATION_ON_REFLECT_INTERVAL",HAS_BOUNDED_VARIATION_ON_REFLECT_INTERVAL; +"HAS_BOUNDED_VARIATION_ON_SUB",HAS_BOUNDED_VARIATION_ON_SUB; +"HAS_BOUNDED_VARIATION_ON_SUBSET",HAS_BOUNDED_VARIATION_ON_SUBSET; +"HAS_BOUNDED_VARIATION_REFLECT2_EQ",HAS_BOUNDED_VARIATION_REFLECT2_EQ; +"HAS_BOUNDED_VARIATION_REFLECT_EQ",HAS_BOUNDED_VARIATION_REFLECT_EQ; +"HAS_BOUNDED_VARIATION_REFLECT_EQ_INTERVAL",HAS_BOUNDED_VARIATION_REFLECT_EQ_INTERVAL; +"HAS_BOUNDED_VARIATION_TRANSLATION",HAS_BOUNDED_VARIATION_TRANSLATION; +"HAS_BOUNDED_VARIATION_TRANSLATION2_EQ",HAS_BOUNDED_VARIATION_TRANSLATION2_EQ; +"HAS_BOUNDED_VARIATION_TRANSLATION_EQ",HAS_BOUNDED_VARIATION_TRANSLATION_EQ; +"HAS_BOUNDED_VARIATION_TRANSLATION_EQ_INTERVAL",HAS_BOUNDED_VARIATION_TRANSLATION_EQ_INTERVAL; +"HAS_BOUNDED_VECTOR_VARIATION_LEFT_LIMIT",HAS_BOUNDED_VECTOR_VARIATION_LEFT_LIMIT; +"HAS_BOUNDED_VECTOR_VARIATION_RIGHT_LIMIT",HAS_BOUNDED_VECTOR_VARIATION_RIGHT_LIMIT; +"HAS_CHAIN_INTEGRAL_CHAIN_INTEGRAL",HAS_CHAIN_INTEGRAL_CHAIN_INTEGRAL; +"HAS_COMPLEX_DERIVATIVE_ADD",HAS_COMPLEX_DERIVATIVE_ADD; +"HAS_COMPLEX_DERIVATIVE_AT",HAS_COMPLEX_DERIVATIVE_AT; +"HAS_COMPLEX_DERIVATIVE_AT_WITHIN",HAS_COMPLEX_DERIVATIVE_AT_WITHIN; +"HAS_COMPLEX_DERIVATIVE_CACS",HAS_COMPLEX_DERIVATIVE_CACS; +"HAS_COMPLEX_DERIVATIVE_CARATHEODORY_AT",HAS_COMPLEX_DERIVATIVE_CARATHEODORY_AT; +"HAS_COMPLEX_DERIVATIVE_CARATHEODORY_WITHIN",HAS_COMPLEX_DERIVATIVE_CARATHEODORY_WITHIN; +"HAS_COMPLEX_DERIVATIVE_CASN",HAS_COMPLEX_DERIVATIVE_CASN; +"HAS_COMPLEX_DERIVATIVE_CATN",HAS_COMPLEX_DERIVATIVE_CATN; +"HAS_COMPLEX_DERIVATIVE_CCOS",HAS_COMPLEX_DERIVATIVE_CCOS; +"HAS_COMPLEX_DERIVATIVE_CDIV_AT",HAS_COMPLEX_DERIVATIVE_CDIV_AT; +"HAS_COMPLEX_DERIVATIVE_CDIV_WITHIN",HAS_COMPLEX_DERIVATIVE_CDIV_WITHIN; +"HAS_COMPLEX_DERIVATIVE_CEXP",HAS_COMPLEX_DERIVATIVE_CEXP; +"HAS_COMPLEX_DERIVATIVE_CHAIN",HAS_COMPLEX_DERIVATIVE_CHAIN; +"HAS_COMPLEX_DERIVATIVE_CHAIN_UNIV",HAS_COMPLEX_DERIVATIVE_CHAIN_UNIV; +"HAS_COMPLEX_DERIVATIVE_CLOG",HAS_COMPLEX_DERIVATIVE_CLOG; +"HAS_COMPLEX_DERIVATIVE_CONST",HAS_COMPLEX_DERIVATIVE_CONST; +"HAS_COMPLEX_DERIVATIVE_CPOW",HAS_COMPLEX_DERIVATIVE_CPOW; +"HAS_COMPLEX_DERIVATIVE_CPOW_RIGHT",HAS_COMPLEX_DERIVATIVE_CPOW_RIGHT; +"HAS_COMPLEX_DERIVATIVE_CSIN",HAS_COMPLEX_DERIVATIVE_CSIN; +"HAS_COMPLEX_DERIVATIVE_CSQRT",HAS_COMPLEX_DERIVATIVE_CSQRT; +"HAS_COMPLEX_DERIVATIVE_CTAN",HAS_COMPLEX_DERIVATIVE_CTAN; +"HAS_COMPLEX_DERIVATIVE_DERIVATIVE",HAS_COMPLEX_DERIVATIVE_DERIVATIVE; +"HAS_COMPLEX_DERIVATIVE_DIFFERENTIABLE",HAS_COMPLEX_DERIVATIVE_DIFFERENTIABLE; +"HAS_COMPLEX_DERIVATIVE_DIV_AT",HAS_COMPLEX_DERIVATIVE_DIV_AT; +"HAS_COMPLEX_DERIVATIVE_DIV_WITHIN",HAS_COMPLEX_DERIVATIVE_DIV_WITHIN; +"HAS_COMPLEX_DERIVATIVE_HIGHER_COMPLEX_DERIVATIVE",HAS_COMPLEX_DERIVATIVE_HIGHER_COMPLEX_DERIVATIVE; +"HAS_COMPLEX_DERIVATIVE_ID",HAS_COMPLEX_DERIVATIVE_ID; +"HAS_COMPLEX_DERIVATIVE_IMP_CONTINUOUS_AT",HAS_COMPLEX_DERIVATIVE_IMP_CONTINUOUS_AT; +"HAS_COMPLEX_DERIVATIVE_IMP_CONTINUOUS_WITHIN",HAS_COMPLEX_DERIVATIVE_IMP_CONTINUOUS_WITHIN; +"HAS_COMPLEX_DERIVATIVE_INVERSE_BASIC",HAS_COMPLEX_DERIVATIVE_INVERSE_BASIC; +"HAS_COMPLEX_DERIVATIVE_INVERSE_STRONG",HAS_COMPLEX_DERIVATIVE_INVERSE_STRONG; +"HAS_COMPLEX_DERIVATIVE_INVERSE_STRONG_X",HAS_COMPLEX_DERIVATIVE_INVERSE_STRONG_X; +"HAS_COMPLEX_DERIVATIVE_INV_AT",HAS_COMPLEX_DERIVATIVE_INV_AT; +"HAS_COMPLEX_DERIVATIVE_INV_BASIC",HAS_COMPLEX_DERIVATIVE_INV_BASIC; +"HAS_COMPLEX_DERIVATIVE_INV_WITHIN",HAS_COMPLEX_DERIVATIVE_INV_WITHIN; +"HAS_COMPLEX_DERIVATIVE_ITER_1",HAS_COMPLEX_DERIVATIVE_ITER_1; +"HAS_COMPLEX_DERIVATIVE_LINEAR",HAS_COMPLEX_DERIVATIVE_LINEAR; +"HAS_COMPLEX_DERIVATIVE_LMUL_AT",HAS_COMPLEX_DERIVATIVE_LMUL_AT; +"HAS_COMPLEX_DERIVATIVE_LMUL_WITHIN",HAS_COMPLEX_DERIVATIVE_LMUL_WITHIN; +"HAS_COMPLEX_DERIVATIVE_LOCALLY_INJECTIVE",HAS_COMPLEX_DERIVATIVE_LOCALLY_INJECTIVE; +"HAS_COMPLEX_DERIVATIVE_LOCALLY_INVERTIBLE",HAS_COMPLEX_DERIVATIVE_LOCALLY_INVERTIBLE; +"HAS_COMPLEX_DERIVATIVE_MUL_AT",HAS_COMPLEX_DERIVATIVE_MUL_AT; +"HAS_COMPLEX_DERIVATIVE_MUL_WITHIN",HAS_COMPLEX_DERIVATIVE_MUL_WITHIN; +"HAS_COMPLEX_DERIVATIVE_NEG",HAS_COMPLEX_DERIVATIVE_NEG; +"HAS_COMPLEX_DERIVATIVE_POW_AT",HAS_COMPLEX_DERIVATIVE_POW_AT; +"HAS_COMPLEX_DERIVATIVE_POW_WITHIN",HAS_COMPLEX_DERIVATIVE_POW_WITHIN; +"HAS_COMPLEX_DERIVATIVE_RMUL_AT",HAS_COMPLEX_DERIVATIVE_RMUL_AT; +"HAS_COMPLEX_DERIVATIVE_RMUL_WITHIN",HAS_COMPLEX_DERIVATIVE_RMUL_WITHIN; +"HAS_COMPLEX_DERIVATIVE_SEQUENCE",HAS_COMPLEX_DERIVATIVE_SEQUENCE; +"HAS_COMPLEX_DERIVATIVE_SERIES",HAS_COMPLEX_DERIVATIVE_SERIES; +"HAS_COMPLEX_DERIVATIVE_SUB",HAS_COMPLEX_DERIVATIVE_SUB; +"HAS_COMPLEX_DERIVATIVE_TRANSFORM_AT",HAS_COMPLEX_DERIVATIVE_TRANSFORM_AT; +"HAS_COMPLEX_DERIVATIVE_TRANSFORM_WITHIN",HAS_COMPLEX_DERIVATIVE_TRANSFORM_WITHIN; +"HAS_COMPLEX_DERIVATIVE_TRANSFORM_WITHIN_OPEN",HAS_COMPLEX_DERIVATIVE_TRANSFORM_WITHIN_OPEN; +"HAS_COMPLEX_DERIVATIVE_UNIFORM_LIMIT",HAS_COMPLEX_DERIVATIVE_UNIFORM_LIMIT; +"HAS_COMPLEX_DERIVATIVE_UNIFORM_SEQUENCE",HAS_COMPLEX_DERIVATIVE_UNIFORM_SEQUENCE; +"HAS_COMPLEX_DERIVATIVE_VSUM",HAS_COMPLEX_DERIVATIVE_VSUM; +"HAS_COMPLEX_DERIVATIVE_WITHIN",HAS_COMPLEX_DERIVATIVE_WITHIN; +"HAS_COMPLEX_DERIVATIVE_WITHIN_OPEN",HAS_COMPLEX_DERIVATIVE_WITHIN_OPEN; +"HAS_COMPLEX_DERIVATIVE_WITHIN_SUBSET",HAS_COMPLEX_DERIVATIVE_WITHIN_SUBSET; +"HAS_COMPLEX_DERIVATIVE_ZERO_CONNECTED_CONSTANT",HAS_COMPLEX_DERIVATIVE_ZERO_CONNECTED_CONSTANT; +"HAS_COMPLEX_DERIVATIVE_ZERO_CONNECTED_UNIQUE",HAS_COMPLEX_DERIVATIVE_ZERO_CONNECTED_UNIQUE; +"HAS_COMPLEX_DERIVATIVE_ZERO_CONSTANT",HAS_COMPLEX_DERIVATIVE_ZERO_CONSTANT; +"HAS_COMPLEX_DERIVATIVE_ZERO_UNIQUE",HAS_COMPLEX_DERIVATIVE_ZERO_UNIQUE; +"HAS_COMPLEX_REAL_DERIVATIVE_AT",HAS_COMPLEX_REAL_DERIVATIVE_AT; +"HAS_COMPLEX_REAL_DERIVATIVE_AT_GEN",HAS_COMPLEX_REAL_DERIVATIVE_AT_GEN; +"HAS_COMPLEX_REAL_DERIVATIVE_WITHIN",HAS_COMPLEX_REAL_DERIVATIVE_WITHIN; +"HAS_COMPLEX_REAL_DERIVATIVE_WITHIN_GEN",HAS_COMPLEX_REAL_DERIVATIVE_WITHIN_GEN; +"HAS_DERIVATIVE_ADD",HAS_DERIVATIVE_ADD; +"HAS_DERIVATIVE_AT",HAS_DERIVATIVE_AT; +"HAS_DERIVATIVE_AT_ALT",HAS_DERIVATIVE_AT_ALT; +"HAS_DERIVATIVE_AT_WITHIN",HAS_DERIVATIVE_AT_WITHIN; +"HAS_DERIVATIVE_BILINEAR_AT",HAS_DERIVATIVE_BILINEAR_AT; +"HAS_DERIVATIVE_BILINEAR_WITHIN",HAS_DERIVATIVE_BILINEAR_WITHIN; +"HAS_DERIVATIVE_CMUL",HAS_DERIVATIVE_CMUL; +"HAS_DERIVATIVE_CMUL_EQ",HAS_DERIVATIVE_CMUL_EQ; +"HAS_DERIVATIVE_COMPLEX_CMUL",HAS_DERIVATIVE_COMPLEX_CMUL; +"HAS_DERIVATIVE_COMPONENTWISE_AT",HAS_DERIVATIVE_COMPONENTWISE_AT; +"HAS_DERIVATIVE_COMPONENTWISE_WITHIN",HAS_DERIVATIVE_COMPONENTWISE_WITHIN; +"HAS_DERIVATIVE_CONST",HAS_DERIVATIVE_CONST; +"HAS_DERIVATIVE_ID",HAS_DERIVATIVE_ID; +"HAS_DERIVATIVE_IMP_DIFFERENTIABLE",HAS_DERIVATIVE_IMP_DIFFERENTIABLE; +"HAS_DERIVATIVE_INVERSE",HAS_DERIVATIVE_INVERSE; +"HAS_DERIVATIVE_INVERSE_BASIC",HAS_DERIVATIVE_INVERSE_BASIC; +"HAS_DERIVATIVE_INVERSE_BASIC_X",HAS_DERIVATIVE_INVERSE_BASIC_X; +"HAS_DERIVATIVE_INVERSE_DIEUDONNE",HAS_DERIVATIVE_INVERSE_DIEUDONNE; +"HAS_DERIVATIVE_INVERSE_ON",HAS_DERIVATIVE_INVERSE_ON; +"HAS_DERIVATIVE_INVERSE_STRONG",HAS_DERIVATIVE_INVERSE_STRONG; +"HAS_DERIVATIVE_INVERSE_STRONG_X",HAS_DERIVATIVE_INVERSE_STRONG_X; +"HAS_DERIVATIVE_LIFT_COMPONENT",HAS_DERIVATIVE_LIFT_COMPONENT; +"HAS_DERIVATIVE_LIFT_DOT",HAS_DERIVATIVE_LIFT_DOT; +"HAS_DERIVATIVE_LINEAR",HAS_DERIVATIVE_LINEAR; +"HAS_DERIVATIVE_LOCALLY_INJECTIVE",HAS_DERIVATIVE_LOCALLY_INJECTIVE; +"HAS_DERIVATIVE_MUL_AT",HAS_DERIVATIVE_MUL_AT; +"HAS_DERIVATIVE_MUL_WITHIN",HAS_DERIVATIVE_MUL_WITHIN; +"HAS_DERIVATIVE_NEG",HAS_DERIVATIVE_NEG; +"HAS_DERIVATIVE_NEG_EQ",HAS_DERIVATIVE_NEG_EQ; +"HAS_DERIVATIVE_SEQUENCE",HAS_DERIVATIVE_SEQUENCE; +"HAS_DERIVATIVE_SEQUENCE_LIPSCHITZ",HAS_DERIVATIVE_SEQUENCE_LIPSCHITZ; +"HAS_DERIVATIVE_SERIES",HAS_DERIVATIVE_SERIES; +"HAS_DERIVATIVE_SQNORM_AT",HAS_DERIVATIVE_SQNORM_AT; +"HAS_DERIVATIVE_SUB",HAS_DERIVATIVE_SUB; +"HAS_DERIVATIVE_TRANSFORM_AT",HAS_DERIVATIVE_TRANSFORM_AT; +"HAS_DERIVATIVE_TRANSFORM_WITHIN",HAS_DERIVATIVE_TRANSFORM_WITHIN; +"HAS_DERIVATIVE_TRANSFORM_WITHIN_OPEN",HAS_DERIVATIVE_TRANSFORM_WITHIN_OPEN; +"HAS_DERIVATIVE_VMUL_COMPONENT",HAS_DERIVATIVE_VMUL_COMPONENT; +"HAS_DERIVATIVE_VMUL_DROP",HAS_DERIVATIVE_VMUL_DROP; +"HAS_DERIVATIVE_VSUM",HAS_DERIVATIVE_VSUM; +"HAS_DERIVATIVE_VSUM_NUMSEG",HAS_DERIVATIVE_VSUM_NUMSEG; +"HAS_DERIVATIVE_WITHIN",HAS_DERIVATIVE_WITHIN; +"HAS_DERIVATIVE_WITHIN_ALT",HAS_DERIVATIVE_WITHIN_ALT; +"HAS_DERIVATIVE_WITHIN_OPEN",HAS_DERIVATIVE_WITHIN_OPEN; +"HAS_DERIVATIVE_WITHIN_SUBSET",HAS_DERIVATIVE_WITHIN_SUBSET; +"HAS_DERIVATIVE_ZERO_CONNECTED_CONSTANT",HAS_DERIVATIVE_ZERO_CONNECTED_CONSTANT; +"HAS_DERIVATIVE_ZERO_CONNECTED_UNIQUE",HAS_DERIVATIVE_ZERO_CONNECTED_UNIQUE; +"HAS_DERIVATIVE_ZERO_CONSTANT",HAS_DERIVATIVE_ZERO_CONSTANT; +"HAS_DERIVATIVE_ZERO_UNIQUE",HAS_DERIVATIVE_ZERO_UNIQUE; +"HAS_DERIVATIVE_ZERO_UNIQUE_STRONG_CONNECTED",HAS_DERIVATIVE_ZERO_UNIQUE_STRONG_CONNECTED; +"HAS_DERIVATIVE_ZERO_UNIQUE_STRONG_CONVEX",HAS_DERIVATIVE_ZERO_UNIQUE_STRONG_CONVEX; +"HAS_DERIVATIVE_ZERO_UNIQUE_STRONG_INTERVAL",HAS_DERIVATIVE_ZERO_UNIQUE_STRONG_INTERVAL; +"HAS_FRECHET_DERIVATIVE_UNIQUE_AT",HAS_FRECHET_DERIVATIVE_UNIQUE_AT; +"HAS_INTEGRAL",HAS_INTEGRAL; +"HAS_INTEGRAL_0",HAS_INTEGRAL_0; +"HAS_INTEGRAL_0_EQ",HAS_INTEGRAL_0_EQ; +"HAS_INTEGRAL_ADD",HAS_INTEGRAL_ADD; +"HAS_INTEGRAL_AFFINITY",HAS_INTEGRAL_AFFINITY; +"HAS_INTEGRAL_ALT",HAS_INTEGRAL_ALT; +"HAS_INTEGRAL_BOUND",HAS_INTEGRAL_BOUND; +"HAS_INTEGRAL_CLOSURE",HAS_INTEGRAL_CLOSURE; +"HAS_INTEGRAL_CMUL",HAS_INTEGRAL_CMUL; +"HAS_INTEGRAL_COMBINE",HAS_INTEGRAL_COMBINE; +"HAS_INTEGRAL_COMBINE_DIVISION",HAS_INTEGRAL_COMBINE_DIVISION; +"HAS_INTEGRAL_COMBINE_DIVISION_TOPDOWN",HAS_INTEGRAL_COMBINE_DIVISION_TOPDOWN; +"HAS_INTEGRAL_COMBINE_TAGGED_DIVISION",HAS_INTEGRAL_COMBINE_TAGGED_DIVISION; +"HAS_INTEGRAL_COMBINE_TAGGED_DIVISION_TOPDOWN",HAS_INTEGRAL_COMBINE_TAGGED_DIVISION_TOPDOWN; +"HAS_INTEGRAL_COMPLEX_CMUL",HAS_INTEGRAL_COMPLEX_CMUL; +"HAS_INTEGRAL_COMPONENTWISE",HAS_INTEGRAL_COMPONENTWISE; +"HAS_INTEGRAL_COMPONENT_LBOUND",HAS_INTEGRAL_COMPONENT_LBOUND; +"HAS_INTEGRAL_COMPONENT_LE",HAS_INTEGRAL_COMPONENT_LE; +"HAS_INTEGRAL_COMPONENT_NEG",HAS_INTEGRAL_COMPONENT_NEG; +"HAS_INTEGRAL_COMPONENT_POS",HAS_INTEGRAL_COMPONENT_POS; +"HAS_INTEGRAL_COMPONENT_UBOUND",HAS_INTEGRAL_COMPONENT_UBOUND; +"HAS_INTEGRAL_CONST",HAS_INTEGRAL_CONST; +"HAS_INTEGRAL_DIFF",HAS_INTEGRAL_DIFF; +"HAS_INTEGRAL_DROP_LE",HAS_INTEGRAL_DROP_LE; +"HAS_INTEGRAL_DROP_NEG",HAS_INTEGRAL_DROP_NEG; +"HAS_INTEGRAL_DROP_POS",HAS_INTEGRAL_DROP_POS; +"HAS_INTEGRAL_EMPTY",HAS_INTEGRAL_EMPTY; +"HAS_INTEGRAL_EMPTY_EQ",HAS_INTEGRAL_EMPTY_EQ; +"HAS_INTEGRAL_EQ",HAS_INTEGRAL_EQ; +"HAS_INTEGRAL_EQ_EQ",HAS_INTEGRAL_EQ_EQ; +"HAS_INTEGRAL_FACTOR_CONTENT",HAS_INTEGRAL_FACTOR_CONTENT; +"HAS_INTEGRAL_INTEGRABLE",HAS_INTEGRAL_INTEGRABLE; +"HAS_INTEGRAL_INTEGRABLE_INTEGRAL",HAS_INTEGRAL_INTEGRABLE_INTEGRAL; +"HAS_INTEGRAL_INTEGRAL",HAS_INTEGRAL_INTEGRAL; +"HAS_INTEGRAL_INTERIOR",HAS_INTEGRAL_INTERIOR; +"HAS_INTEGRAL_IS_0",HAS_INTEGRAL_IS_0; +"HAS_INTEGRAL_LINEAR",HAS_INTEGRAL_LINEAR; +"HAS_INTEGRAL_LOCALIZED_VECTOR_DERIVATIVE",HAS_INTEGRAL_LOCALIZED_VECTOR_DERIVATIVE; +"HAS_INTEGRAL_NEG",HAS_INTEGRAL_NEG; +"HAS_INTEGRAL_NEGLIGIBLE",HAS_INTEGRAL_NEGLIGIBLE; +"HAS_INTEGRAL_NEGLIGIBLE_EQ",HAS_INTEGRAL_NEGLIGIBLE_EQ; +"HAS_INTEGRAL_NORM_BOUND_INTEGRAL_COMPONENT",HAS_INTEGRAL_NORM_BOUND_INTEGRAL_COMPONENT; +"HAS_INTEGRAL_NULL",HAS_INTEGRAL_NULL; +"HAS_INTEGRAL_NULL_EQ",HAS_INTEGRAL_NULL_EQ; +"HAS_INTEGRAL_ON_SUPERSET",HAS_INTEGRAL_ON_SUPERSET; +"HAS_INTEGRAL_OPEN_INTERVAL",HAS_INTEGRAL_OPEN_INTERVAL; +"HAS_INTEGRAL_PATH_INTEGRAL_SUBPATH",HAS_INTEGRAL_PATH_INTEGRAL_SUBPATH; +"HAS_INTEGRAL_REFL",HAS_INTEGRAL_REFL; +"HAS_INTEGRAL_REFLECT",HAS_INTEGRAL_REFLECT; +"HAS_INTEGRAL_REFLECT_LEMMA",HAS_INTEGRAL_REFLECT_LEMMA; +"HAS_INTEGRAL_RESTRICT",HAS_INTEGRAL_RESTRICT; +"HAS_INTEGRAL_RESTRICT_CLOSED_SUBINTERVAL",HAS_INTEGRAL_RESTRICT_CLOSED_SUBINTERVAL; +"HAS_INTEGRAL_RESTRICT_CLOSED_SUBINTERVALS_EQ",HAS_INTEGRAL_RESTRICT_CLOSED_SUBINTERVALS_EQ; +"HAS_INTEGRAL_RESTRICT_INTER",HAS_INTEGRAL_RESTRICT_INTER; +"HAS_INTEGRAL_RESTRICT_OPEN_SUBINTERVAL",HAS_INTEGRAL_RESTRICT_OPEN_SUBINTERVAL; +"HAS_INTEGRAL_RESTRICT_UNIV",HAS_INTEGRAL_RESTRICT_UNIV; +"HAS_INTEGRAL_SEPARATE_SIDES",HAS_INTEGRAL_SEPARATE_SIDES; +"HAS_INTEGRAL_SPIKE",HAS_INTEGRAL_SPIKE; +"HAS_INTEGRAL_SPIKE_EQ",HAS_INTEGRAL_SPIKE_EQ; +"HAS_INTEGRAL_SPIKE_FINITE",HAS_INTEGRAL_SPIKE_FINITE; +"HAS_INTEGRAL_SPIKE_FINITE_EQ",HAS_INTEGRAL_SPIKE_FINITE_EQ; +"HAS_INTEGRAL_SPIKE_INTERIOR",HAS_INTEGRAL_SPIKE_INTERIOR; +"HAS_INTEGRAL_SPIKE_INTERIOR_EQ",HAS_INTEGRAL_SPIKE_INTERIOR_EQ; +"HAS_INTEGRAL_SPIKE_SET",HAS_INTEGRAL_SPIKE_SET; +"HAS_INTEGRAL_SPIKE_SET_EQ",HAS_INTEGRAL_SPIKE_SET_EQ; +"HAS_INTEGRAL_SPLIT",HAS_INTEGRAL_SPLIT; +"HAS_INTEGRAL_STRADDLE_NULL",HAS_INTEGRAL_STRADDLE_NULL; +"HAS_INTEGRAL_STRETCH",HAS_INTEGRAL_STRETCH; +"HAS_INTEGRAL_SUB",HAS_INTEGRAL_SUB; +"HAS_INTEGRAL_SUBSET_COMPONENT_LE",HAS_INTEGRAL_SUBSET_COMPONENT_LE; +"HAS_INTEGRAL_SUBSET_DROP_LE",HAS_INTEGRAL_SUBSET_DROP_LE; +"HAS_INTEGRAL_TWIDDLE",HAS_INTEGRAL_TWIDDLE; +"HAS_INTEGRAL_UNION",HAS_INTEGRAL_UNION; +"HAS_INTEGRAL_UNIONS",HAS_INTEGRAL_UNIONS; +"HAS_INTEGRAL_UNIQUE",HAS_INTEGRAL_UNIQUE; +"HAS_INTEGRAL_VSUM",HAS_INTEGRAL_VSUM; +"HAS_MEASURE",HAS_MEASURE; +"HAS_MEASURE_0",HAS_MEASURE_0; +"HAS_MEASURE_AFFINITY",HAS_MEASURE_AFFINITY; +"HAS_MEASURE_ALMOST",HAS_MEASURE_ALMOST; +"HAS_MEASURE_ALMOST_EQ",HAS_MEASURE_ALMOST_EQ; +"HAS_MEASURE_COUNTABLE_NEGLIGIBLE_UNIONS",HAS_MEASURE_COUNTABLE_NEGLIGIBLE_UNIONS; +"HAS_MEASURE_COUNTABLE_NEGLIGIBLE_UNIONS_BOUNDED",HAS_MEASURE_COUNTABLE_NEGLIGIBLE_UNIONS_BOUNDED; +"HAS_MEASURE_DIFF_NEGLIGIBLE",HAS_MEASURE_DIFF_NEGLIGIBLE; +"HAS_MEASURE_DIFF_NEGLIGIBLE_EQ",HAS_MEASURE_DIFF_NEGLIGIBLE_EQ; +"HAS_MEASURE_DIFF_SUBSET",HAS_MEASURE_DIFF_SUBSET; +"HAS_MEASURE_DISJOINT_UNION",HAS_MEASURE_DISJOINT_UNION; +"HAS_MEASURE_DISJOINT_UNIONS",HAS_MEASURE_DISJOINT_UNIONS; +"HAS_MEASURE_DISJOINT_UNIONS_IMAGE",HAS_MEASURE_DISJOINT_UNIONS_IMAGE; +"HAS_MEASURE_DISJOINT_UNIONS_IMAGE_STRONG",HAS_MEASURE_DISJOINT_UNIONS_IMAGE_STRONG; +"HAS_MEASURE_ELEMENTARY",HAS_MEASURE_ELEMENTARY; +"HAS_MEASURE_EMPTY",HAS_MEASURE_EMPTY; +"HAS_MEASURE_IMAGE_STD_SIMPLEX",HAS_MEASURE_IMAGE_STD_SIMPLEX; +"HAS_MEASURE_IMP_MEASURABLE",HAS_MEASURE_IMP_MEASURABLE; +"HAS_MEASURE_INNER_OUTER",HAS_MEASURE_INNER_OUTER; +"HAS_MEASURE_INNER_OUTER_LE",HAS_MEASURE_INNER_OUTER_LE; +"HAS_MEASURE_INTERVAL",HAS_MEASURE_INTERVAL; +"HAS_MEASURE_LIMIT",HAS_MEASURE_LIMIT; +"HAS_MEASURE_LINEAR_IMAGE",HAS_MEASURE_LINEAR_IMAGE; +"HAS_MEASURE_LINEAR_IMAGE_ALT",HAS_MEASURE_LINEAR_IMAGE_ALT; +"HAS_MEASURE_LINEAR_IMAGE_SAME",HAS_MEASURE_LINEAR_IMAGE_SAME; +"HAS_MEASURE_LINEAR_SUFFICIENT",HAS_MEASURE_LINEAR_SUFFICIENT; +"HAS_MEASURE_MEASURABLE_MEASURE",HAS_MEASURE_MEASURABLE_MEASURE; +"HAS_MEASURE_MEASURE",HAS_MEASURE_MEASURE; +"HAS_MEASURE_NEGLIGIBLE_SYMDIFF",HAS_MEASURE_NEGLIGIBLE_SYMDIFF; +"HAS_MEASURE_NEGLIGIBLE_UNION",HAS_MEASURE_NEGLIGIBLE_UNION; +"HAS_MEASURE_NEGLIGIBLE_UNIONS",HAS_MEASURE_NEGLIGIBLE_UNIONS; +"HAS_MEASURE_NEGLIGIBLE_UNIONS_IMAGE",HAS_MEASURE_NEGLIGIBLE_UNIONS_IMAGE; +"HAS_MEASURE_NEGLIGIBLE_UNIONS_IMAGE_STRONG",HAS_MEASURE_NEGLIGIBLE_UNIONS_IMAGE_STRONG; +"HAS_MEASURE_NESTED_INTERS",HAS_MEASURE_NESTED_INTERS; +"HAS_MEASURE_NESTED_UNIONS",HAS_MEASURE_NESTED_UNIONS; +"HAS_MEASURE_ORTHOGONAL_IMAGE",HAS_MEASURE_ORTHOGONAL_IMAGE; +"HAS_MEASURE_ORTHOGONAL_IMAGE_EQ",HAS_MEASURE_ORTHOGONAL_IMAGE_EQ; +"HAS_MEASURE_POS_LE",HAS_MEASURE_POS_LE; +"HAS_MEASURE_SCALING",HAS_MEASURE_SCALING; +"HAS_MEASURE_SCALING_EQ",HAS_MEASURE_SCALING_EQ; +"HAS_MEASURE_SHEAR_INTERVAL",HAS_MEASURE_SHEAR_INTERVAL; +"HAS_MEASURE_SIMPLEX",HAS_MEASURE_SIMPLEX; +"HAS_MEASURE_SIMPLEX_0",HAS_MEASURE_SIMPLEX_0; +"HAS_MEASURE_STD_SIMPLEX",HAS_MEASURE_STD_SIMPLEX; +"HAS_MEASURE_STRETCH",HAS_MEASURE_STRETCH; +"HAS_MEASURE_SUBSET",HAS_MEASURE_SUBSET; +"HAS_MEASURE_TETRAHEDRON",HAS_MEASURE_TETRAHEDRON; +"HAS_MEASURE_TRANSLATION",HAS_MEASURE_TRANSLATION; +"HAS_MEASURE_TRANSLATION_EQ",HAS_MEASURE_TRANSLATION_EQ; +"HAS_MEASURE_TRIANGLE",HAS_MEASURE_TRIANGLE; +"HAS_MEASURE_UNION_NEGLIGIBLE",HAS_MEASURE_UNION_NEGLIGIBLE; +"HAS_MEASURE_UNION_NEGLIGIBLE_EQ",HAS_MEASURE_UNION_NEGLIGIBLE_EQ; +"HAS_MEASURE_UNIQUE",HAS_MEASURE_UNIQUE; +"HAS_PATH_INTEGRAL",HAS_PATH_INTEGRAL; +"HAS_PATH_INTEGRAL_0",HAS_PATH_INTEGRAL_0; +"HAS_PATH_INTEGRAL_ADD",HAS_PATH_INTEGRAL_ADD; +"HAS_PATH_INTEGRAL_BOUND_CIRCLEPATH",HAS_PATH_INTEGRAL_BOUND_CIRCLEPATH; +"HAS_PATH_INTEGRAL_BOUND_CIRCLEPATH_STRONG",HAS_PATH_INTEGRAL_BOUND_CIRCLEPATH_STRONG; +"HAS_PATH_INTEGRAL_BOUND_LINEPATH",HAS_PATH_INTEGRAL_BOUND_LINEPATH; +"HAS_PATH_INTEGRAL_BOUND_LINEPATH_STRONG",HAS_PATH_INTEGRAL_BOUND_LINEPATH_STRONG; +"HAS_PATH_INTEGRAL_BOUND_PARTCIRCLEPATH",HAS_PATH_INTEGRAL_BOUND_PARTCIRCLEPATH; +"HAS_PATH_INTEGRAL_BOUND_PARTCIRCLEPATH_STRONG",HAS_PATH_INTEGRAL_BOUND_PARTCIRCLEPATH_STRONG; +"HAS_PATH_INTEGRAL_COMPLEX_DIV",HAS_PATH_INTEGRAL_COMPLEX_DIV; +"HAS_PATH_INTEGRAL_COMPLEX_LMUL",HAS_PATH_INTEGRAL_COMPLEX_LMUL; +"HAS_PATH_INTEGRAL_COMPLEX_RMUL",HAS_PATH_INTEGRAL_COMPLEX_RMUL; +"HAS_PATH_INTEGRAL_CONST_LINEPATH",HAS_PATH_INTEGRAL_CONST_LINEPATH; +"HAS_PATH_INTEGRAL_EQ",HAS_PATH_INTEGRAL_EQ; +"HAS_PATH_INTEGRAL_INTEGRABLE",HAS_PATH_INTEGRAL_INTEGRABLE; +"HAS_PATH_INTEGRAL_INTEGRAL",HAS_PATH_INTEGRAL_INTEGRAL; +"HAS_PATH_INTEGRAL_IS_0",HAS_PATH_INTEGRAL_IS_0; +"HAS_PATH_INTEGRAL_JOIN",HAS_PATH_INTEGRAL_JOIN; +"HAS_PATH_INTEGRAL_LINEPATH",HAS_PATH_INTEGRAL_LINEPATH; +"HAS_PATH_INTEGRAL_MIDPOINT",HAS_PATH_INTEGRAL_MIDPOINT; +"HAS_PATH_INTEGRAL_NEG",HAS_PATH_INTEGRAL_NEG; +"HAS_PATH_INTEGRAL_REVERSEPATH",HAS_PATH_INTEGRAL_REVERSEPATH; +"HAS_PATH_INTEGRAL_REVERSE_LINEPATH",HAS_PATH_INTEGRAL_REVERSE_LINEPATH; +"HAS_PATH_INTEGRAL_SHIFTPATH",HAS_PATH_INTEGRAL_SHIFTPATH; +"HAS_PATH_INTEGRAL_SHIFTPATH_EQ",HAS_PATH_INTEGRAL_SHIFTPATH_EQ; +"HAS_PATH_INTEGRAL_SPLIT",HAS_PATH_INTEGRAL_SPLIT; +"HAS_PATH_INTEGRAL_SUB",HAS_PATH_INTEGRAL_SUB; +"HAS_PATH_INTEGRAL_SUBPATH",HAS_PATH_INTEGRAL_SUBPATH; +"HAS_PATH_INTEGRAL_SUBPATH_REFL",HAS_PATH_INTEGRAL_SUBPATH_REFL; +"HAS_PATH_INTEGRAL_TRIVIAL",HAS_PATH_INTEGRAL_TRIVIAL; +"HAS_PATH_INTEGRAL_UNIQUE",HAS_PATH_INTEGRAL_UNIQUE; +"HAS_PATH_INTEGRAL_VSUM",HAS_PATH_INTEGRAL_VSUM; +"HAS_PATH_INTEGRAL_WINDING_NUMBER",HAS_PATH_INTEGRAL_WINDING_NUMBER; +"HAS_REAL_COMPLEX_DERIVATIVE_AT",HAS_REAL_COMPLEX_DERIVATIVE_AT; +"HAS_REAL_COMPLEX_DERIVATIVE_WITHIN",HAS_REAL_COMPLEX_DERIVATIVE_WITHIN; +"HAS_REAL_DERIVATIVE_ACS",HAS_REAL_DERIVATIVE_ACS; +"HAS_REAL_DERIVATIVE_ACS_SIN",HAS_REAL_DERIVATIVE_ACS_SIN; +"HAS_REAL_DERIVATIVE_ADD",HAS_REAL_DERIVATIVE_ADD; +"HAS_REAL_DERIVATIVE_ASN",HAS_REAL_DERIVATIVE_ASN; +"HAS_REAL_DERIVATIVE_ASN_COS",HAS_REAL_DERIVATIVE_ASN_COS; +"HAS_REAL_DERIVATIVE_ATN",HAS_REAL_DERIVATIVE_ATN; +"HAS_REAL_DERIVATIVE_ATREAL",HAS_REAL_DERIVATIVE_ATREAL; +"HAS_REAL_DERIVATIVE_ATREAL_WITHIN",HAS_REAL_DERIVATIVE_ATREAL_WITHIN; +"HAS_REAL_DERIVATIVE_CARATHEODORY_ATREAL",HAS_REAL_DERIVATIVE_CARATHEODORY_ATREAL; +"HAS_REAL_DERIVATIVE_CARATHEODORY_WITHINREAL",HAS_REAL_DERIVATIVE_CARATHEODORY_WITHINREAL; +"HAS_REAL_DERIVATIVE_CDIV_ATREAL",HAS_REAL_DERIVATIVE_CDIV_ATREAL; +"HAS_REAL_DERIVATIVE_CDIV_WITHIN",HAS_REAL_DERIVATIVE_CDIV_WITHIN; +"HAS_REAL_DERIVATIVE_CHAIN",HAS_REAL_DERIVATIVE_CHAIN; +"HAS_REAL_DERIVATIVE_CHAIN_UNIV",HAS_REAL_DERIVATIVE_CHAIN_UNIV; +"HAS_REAL_DERIVATIVE_CONST",HAS_REAL_DERIVATIVE_CONST; +"HAS_REAL_DERIVATIVE_COS",HAS_REAL_DERIVATIVE_COS; +"HAS_REAL_DERIVATIVE_DERIVATIVE",HAS_REAL_DERIVATIVE_DERIVATIVE; +"HAS_REAL_DERIVATIVE_DIFFERENTIABLE",HAS_REAL_DERIVATIVE_DIFFERENTIABLE; +"HAS_REAL_DERIVATIVE_DIV_ATREAL",HAS_REAL_DERIVATIVE_DIV_ATREAL; +"HAS_REAL_DERIVATIVE_DIV_WITHIN",HAS_REAL_DERIVATIVE_DIV_WITHIN; +"HAS_REAL_DERIVATIVE_EXP",HAS_REAL_DERIVATIVE_EXP; +"HAS_REAL_DERIVATIVE_ID",HAS_REAL_DERIVATIVE_ID; +"HAS_REAL_DERIVATIVE_IMP_CONTINUOUS_ATREAL",HAS_REAL_DERIVATIVE_IMP_CONTINUOUS_ATREAL; +"HAS_REAL_DERIVATIVE_IMP_CONTINUOUS_WITHINREAL",HAS_REAL_DERIVATIVE_IMP_CONTINUOUS_WITHINREAL; +"HAS_REAL_DERIVATIVE_INCREASING",HAS_REAL_DERIVATIVE_INCREASING; +"HAS_REAL_DERIVATIVE_INCREASING_IMP",HAS_REAL_DERIVATIVE_INCREASING_IMP; +"HAS_REAL_DERIVATIVE_INDEFINITE_INTEGRAL",HAS_REAL_DERIVATIVE_INDEFINITE_INTEGRAL; +"HAS_REAL_DERIVATIVE_INVERSE_BASIC",HAS_REAL_DERIVATIVE_INVERSE_BASIC; +"HAS_REAL_DERIVATIVE_INVERSE_STRONG",HAS_REAL_DERIVATIVE_INVERSE_STRONG; +"HAS_REAL_DERIVATIVE_INVERSE_STRONG_X",HAS_REAL_DERIVATIVE_INVERSE_STRONG_X; +"HAS_REAL_DERIVATIVE_INV_ATREAL",HAS_REAL_DERIVATIVE_INV_ATREAL; +"HAS_REAL_DERIVATIVE_INV_BASIC",HAS_REAL_DERIVATIVE_INV_BASIC; +"HAS_REAL_DERIVATIVE_INV_WITHIN",HAS_REAL_DERIVATIVE_INV_WITHIN; +"HAS_REAL_DERIVATIVE_LMUL_ATREAL",HAS_REAL_DERIVATIVE_LMUL_ATREAL; +"HAS_REAL_DERIVATIVE_LMUL_WITHIN",HAS_REAL_DERIVATIVE_LMUL_WITHIN; +"HAS_REAL_DERIVATIVE_LOG",HAS_REAL_DERIVATIVE_LOG; +"HAS_REAL_DERIVATIVE_MUL_ATREAL",HAS_REAL_DERIVATIVE_MUL_ATREAL; +"HAS_REAL_DERIVATIVE_MUL_WITHIN",HAS_REAL_DERIVATIVE_MUL_WITHIN; +"HAS_REAL_DERIVATIVE_NEG",HAS_REAL_DERIVATIVE_NEG; +"HAS_REAL_DERIVATIVE_POW_ATREAL",HAS_REAL_DERIVATIVE_POW_ATREAL; +"HAS_REAL_DERIVATIVE_POW_WITHIN",HAS_REAL_DERIVATIVE_POW_WITHIN; +"HAS_REAL_DERIVATIVE_RMUL_ATREAL",HAS_REAL_DERIVATIVE_RMUL_ATREAL; +"HAS_REAL_DERIVATIVE_RMUL_WITHIN",HAS_REAL_DERIVATIVE_RMUL_WITHIN; +"HAS_REAL_DERIVATIVE_RPOW",HAS_REAL_DERIVATIVE_RPOW; +"HAS_REAL_DERIVATIVE_SEQUENCE",HAS_REAL_DERIVATIVE_SEQUENCE; +"HAS_REAL_DERIVATIVE_SERIES",HAS_REAL_DERIVATIVE_SERIES; +"HAS_REAL_DERIVATIVE_SIN",HAS_REAL_DERIVATIVE_SIN; +"HAS_REAL_DERIVATIVE_SQRT",HAS_REAL_DERIVATIVE_SQRT; +"HAS_REAL_DERIVATIVE_SUB",HAS_REAL_DERIVATIVE_SUB; +"HAS_REAL_DERIVATIVE_SUM",HAS_REAL_DERIVATIVE_SUM; +"HAS_REAL_DERIVATIVE_TAN",HAS_REAL_DERIVATIVE_TAN; +"HAS_REAL_DERIVATIVE_TRANSFORM_ATREAL",HAS_REAL_DERIVATIVE_TRANSFORM_ATREAL; +"HAS_REAL_DERIVATIVE_TRANSFORM_WITHIN",HAS_REAL_DERIVATIVE_TRANSFORM_WITHIN; +"HAS_REAL_DERIVATIVE_WITHINREAL",HAS_REAL_DERIVATIVE_WITHINREAL; +"HAS_REAL_DERIVATIVE_WITHIN_REAL_OPEN",HAS_REAL_DERIVATIVE_WITHIN_REAL_OPEN; +"HAS_REAL_DERIVATIVE_WITHIN_SUBSET",HAS_REAL_DERIVATIVE_WITHIN_SUBSET; +"HAS_REAL_DERIVATIVE_ZERO_CONSTANT",HAS_REAL_DERIVATIVE_ZERO_CONSTANT; +"HAS_REAL_DERIVATIVE_ZERO_UNIQUE",HAS_REAL_DERIVATIVE_ZERO_UNIQUE; +"HAS_REAL_DERIVATIVE_ZERO_UNIQUE_STRONG_CONVEX",HAS_REAL_DERIVATIVE_ZERO_UNIQUE_STRONG_CONVEX; +"HAS_REAL_DERIVATIVE_ZERO_UNIQUE_STRONG_INTERVAL",HAS_REAL_DERIVATIVE_ZERO_UNIQUE_STRONG_INTERVAL; +"HAS_REAL_FRECHET_DERIVATIVE_AT",HAS_REAL_FRECHET_DERIVATIVE_AT; +"HAS_REAL_FRECHET_DERIVATIVE_WITHIN",HAS_REAL_FRECHET_DERIVATIVE_WITHIN; +"HAS_REAL_INTEGRAL",HAS_REAL_INTEGRAL; +"HAS_REAL_INTEGRAL_0",HAS_REAL_INTEGRAL_0; +"HAS_REAL_INTEGRAL_0_EQ",HAS_REAL_INTEGRAL_0_EQ; +"HAS_REAL_INTEGRAL_ADD",HAS_REAL_INTEGRAL_ADD; +"HAS_REAL_INTEGRAL_AFFINITY",HAS_REAL_INTEGRAL_AFFINITY; +"HAS_REAL_INTEGRAL_BOUND",HAS_REAL_INTEGRAL_BOUND; +"HAS_REAL_INTEGRAL_COMBINE",HAS_REAL_INTEGRAL_COMBINE; +"HAS_REAL_INTEGRAL_CONST",HAS_REAL_INTEGRAL_CONST; +"HAS_REAL_INTEGRAL_EMPTY",HAS_REAL_INTEGRAL_EMPTY; +"HAS_REAL_INTEGRAL_EMPTY_EQ",HAS_REAL_INTEGRAL_EMPTY_EQ; +"HAS_REAL_INTEGRAL_EQ",HAS_REAL_INTEGRAL_EQ; +"HAS_REAL_INTEGRAL_EQ_EQ",HAS_REAL_INTEGRAL_EQ_EQ; +"HAS_REAL_INTEGRAL_INTEGRABLE",HAS_REAL_INTEGRAL_INTEGRABLE; +"HAS_REAL_INTEGRAL_INTEGRABLE_INTEGRAL",HAS_REAL_INTEGRAL_INTEGRABLE_INTEGRAL; +"HAS_REAL_INTEGRAL_INTEGRAL",HAS_REAL_INTEGRAL_INTEGRAL; +"HAS_REAL_INTEGRAL_ISNEG",HAS_REAL_INTEGRAL_ISNEG; +"HAS_REAL_INTEGRAL_IS_0",HAS_REAL_INTEGRAL_IS_0; +"HAS_REAL_INTEGRAL_LBOUND",HAS_REAL_INTEGRAL_LBOUND; +"HAS_REAL_INTEGRAL_LE",HAS_REAL_INTEGRAL_LE; +"HAS_REAL_INTEGRAL_LINEAR",HAS_REAL_INTEGRAL_LINEAR; +"HAS_REAL_INTEGRAL_LMUL",HAS_REAL_INTEGRAL_LMUL; +"HAS_REAL_INTEGRAL_NEG",HAS_REAL_INTEGRAL_NEG; +"HAS_REAL_INTEGRAL_NEGLIGIBLE",HAS_REAL_INTEGRAL_NEGLIGIBLE; +"HAS_REAL_INTEGRAL_NEGLIGIBLE_EQ",HAS_REAL_INTEGRAL_NEGLIGIBLE_EQ; +"HAS_REAL_INTEGRAL_NULL",HAS_REAL_INTEGRAL_NULL; +"HAS_REAL_INTEGRAL_NULL_EQ",HAS_REAL_INTEGRAL_NULL_EQ; +"HAS_REAL_INTEGRAL_ON_SUPERSET",HAS_REAL_INTEGRAL_ON_SUPERSET; +"HAS_REAL_INTEGRAL_OPEN_INTERVAL",HAS_REAL_INTEGRAL_OPEN_INTERVAL; +"HAS_REAL_INTEGRAL_POS",HAS_REAL_INTEGRAL_POS; +"HAS_REAL_INTEGRAL_REFL",HAS_REAL_INTEGRAL_REFL; +"HAS_REAL_INTEGRAL_REFLECT",HAS_REAL_INTEGRAL_REFLECT; +"HAS_REAL_INTEGRAL_REFLECT_LEMMA",HAS_REAL_INTEGRAL_REFLECT_LEMMA; +"HAS_REAL_INTEGRAL_RESTRICT",HAS_REAL_INTEGRAL_RESTRICT; +"HAS_REAL_INTEGRAL_RESTRICT_INTER",HAS_REAL_INTEGRAL_RESTRICT_INTER; +"HAS_REAL_INTEGRAL_RESTRICT_UNIV",HAS_REAL_INTEGRAL_RESTRICT_UNIV; +"HAS_REAL_INTEGRAL_RMUL",HAS_REAL_INTEGRAL_RMUL; +"HAS_REAL_INTEGRAL_SPIKE",HAS_REAL_INTEGRAL_SPIKE; +"HAS_REAL_INTEGRAL_SPIKE_EQ",HAS_REAL_INTEGRAL_SPIKE_EQ; +"HAS_REAL_INTEGRAL_SPIKE_FINITE",HAS_REAL_INTEGRAL_SPIKE_FINITE; +"HAS_REAL_INTEGRAL_SPIKE_FINITE_EQ",HAS_REAL_INTEGRAL_SPIKE_FINITE_EQ; +"HAS_REAL_INTEGRAL_SPIKE_INTERIOR",HAS_REAL_INTEGRAL_SPIKE_INTERIOR; +"HAS_REAL_INTEGRAL_SPIKE_INTERIOR_EQ",HAS_REAL_INTEGRAL_SPIKE_INTERIOR_EQ; +"HAS_REAL_INTEGRAL_SPIKE_SET",HAS_REAL_INTEGRAL_SPIKE_SET; +"HAS_REAL_INTEGRAL_SPIKE_SET_EQ",HAS_REAL_INTEGRAL_SPIKE_SET_EQ; +"HAS_REAL_INTEGRAL_STRADDLE_NULL",HAS_REAL_INTEGRAL_STRADDLE_NULL; +"HAS_REAL_INTEGRAL_STRETCH",HAS_REAL_INTEGRAL_STRETCH; +"HAS_REAL_INTEGRAL_SUB",HAS_REAL_INTEGRAL_SUB; +"HAS_REAL_INTEGRAL_SUBSET_LE",HAS_REAL_INTEGRAL_SUBSET_LE; +"HAS_REAL_INTEGRAL_SUM",HAS_REAL_INTEGRAL_SUM; +"HAS_REAL_INTEGRAL_UBOUND",HAS_REAL_INTEGRAL_UBOUND; +"HAS_REAL_INTEGRAL_UNION",HAS_REAL_INTEGRAL_UNION; +"HAS_REAL_INTEGRAL_UNIONS",HAS_REAL_INTEGRAL_UNIONS; +"HAS_REAL_INTEGRAL_UNIQUE",HAS_REAL_INTEGRAL_UNIQUE; +"HAS_REAL_MEASURE",HAS_REAL_MEASURE; +"HAS_REAL_MEASURE_0",HAS_REAL_MEASURE_0; +"HAS_REAL_MEASURE_AFFINITY",HAS_REAL_MEASURE_AFFINITY; +"HAS_REAL_MEASURE_ALMOST",HAS_REAL_MEASURE_ALMOST; +"HAS_REAL_MEASURE_ALMOST_EQ",HAS_REAL_MEASURE_ALMOST_EQ; +"HAS_REAL_MEASURE_COUNTABLE_REAL_NEGLIGIBLE_UNIONS",HAS_REAL_MEASURE_COUNTABLE_REAL_NEGLIGIBLE_UNIONS; +"HAS_REAL_MEASURE_COUNTABLE_REAL_NEGLIGIBLE_UNIONS_BOUNDED",HAS_REAL_MEASURE_COUNTABLE_REAL_NEGLIGIBLE_UNIONS_BOUNDED; +"HAS_REAL_MEASURE_DIFF_REAL_NEGLIGIBLE",HAS_REAL_MEASURE_DIFF_REAL_NEGLIGIBLE; +"HAS_REAL_MEASURE_DIFF_REAL_NEGLIGIBLE_EQ",HAS_REAL_MEASURE_DIFF_REAL_NEGLIGIBLE_EQ; +"HAS_REAL_MEASURE_DIFF_SUBSET",HAS_REAL_MEASURE_DIFF_SUBSET; +"HAS_REAL_MEASURE_DISJOINT_UNION",HAS_REAL_MEASURE_DISJOINT_UNION; +"HAS_REAL_MEASURE_DISJOINT_UNIONS",HAS_REAL_MEASURE_DISJOINT_UNIONS; +"HAS_REAL_MEASURE_DISJOINT_UNIONS_IMAGE",HAS_REAL_MEASURE_DISJOINT_UNIONS_IMAGE; +"HAS_REAL_MEASURE_DISJOINT_UNIONS_IMAGE_STRONG",HAS_REAL_MEASURE_DISJOINT_UNIONS_IMAGE_STRONG; +"HAS_REAL_MEASURE_EMPTY",HAS_REAL_MEASURE_EMPTY; +"HAS_REAL_MEASURE_HAS_MEASURE",HAS_REAL_MEASURE_HAS_MEASURE; +"HAS_REAL_MEASURE_IMP_REAL_MEASURABLE",HAS_REAL_MEASURE_IMP_REAL_MEASURABLE; +"HAS_REAL_MEASURE_INNER_OUTER",HAS_REAL_MEASURE_INNER_OUTER; +"HAS_REAL_MEASURE_INNER_OUTER_LE",HAS_REAL_MEASURE_INNER_OUTER_LE; +"HAS_REAL_MEASURE_MEASURE",HAS_REAL_MEASURE_MEASURE; +"HAS_REAL_MEASURE_NESTED_UNIONS",HAS_REAL_MEASURE_NESTED_UNIONS; +"HAS_REAL_MEASURE_POS_LE",HAS_REAL_MEASURE_POS_LE; +"HAS_REAL_MEASURE_REAL_INTERVAL",HAS_REAL_MEASURE_REAL_INTERVAL; +"HAS_REAL_MEASURE_REAL_MEASURABLE_REAL_MEASURE",HAS_REAL_MEASURE_REAL_MEASURABLE_REAL_MEASURE; +"HAS_REAL_MEASURE_REAL_NEGLIGIBLE_SYMDIFF",HAS_REAL_MEASURE_REAL_NEGLIGIBLE_SYMDIFF; +"HAS_REAL_MEASURE_REAL_NEGLIGIBLE_UNION",HAS_REAL_MEASURE_REAL_NEGLIGIBLE_UNION; +"HAS_REAL_MEASURE_REAL_NEGLIGIBLE_UNIONS",HAS_REAL_MEASURE_REAL_NEGLIGIBLE_UNIONS; +"HAS_REAL_MEASURE_REAL_NEGLIGIBLE_UNIONS_IMAGE",HAS_REAL_MEASURE_REAL_NEGLIGIBLE_UNIONS_IMAGE; +"HAS_REAL_MEASURE_REAL_NEGLIGIBLE_UNIONS_IMAGE_STRONG",HAS_REAL_MEASURE_REAL_NEGLIGIBLE_UNIONS_IMAGE_STRONG; +"HAS_REAL_MEASURE_SCALING",HAS_REAL_MEASURE_SCALING; +"HAS_REAL_MEASURE_SCALING_EQ",HAS_REAL_MEASURE_SCALING_EQ; +"HAS_REAL_MEASURE_SUBSET",HAS_REAL_MEASURE_SUBSET; +"HAS_REAL_MEASURE_TRANSLATION",HAS_REAL_MEASURE_TRANSLATION; +"HAS_REAL_MEASURE_TRANSLATION_EQ",HAS_REAL_MEASURE_TRANSLATION_EQ; +"HAS_REAL_MEASURE_UNION_REAL_NEGLIGIBLE",HAS_REAL_MEASURE_UNION_REAL_NEGLIGIBLE; +"HAS_REAL_MEASURE_UNION_REAL_NEGLIGIBLE_EQ",HAS_REAL_MEASURE_UNION_REAL_NEGLIGIBLE_EQ; +"HAS_REAL_MEASURE_UNIQUE",HAS_REAL_MEASURE_UNIQUE; +"HAS_REAL_VECTOR_DERIVATIVE_AT",HAS_REAL_VECTOR_DERIVATIVE_AT; +"HAS_REAL_VECTOR_DERIVATIVE_WITHIN",HAS_REAL_VECTOR_DERIVATIVE_WITHIN; +"HAS_SIZE",HAS_SIZE; +"HAS_SIZE_0",HAS_SIZE_0; +"HAS_SIZE_1",HAS_SIZE_1; +"HAS_SIZE_1_EXISTS",HAS_SIZE_1_EXISTS; +"HAS_SIZE_2",HAS_SIZE_2; +"HAS_SIZE_2_EXISTS",HAS_SIZE_2_EXISTS; +"HAS_SIZE_3",HAS_SIZE_3; +"HAS_SIZE_4",HAS_SIZE_4; +"HAS_SIZE_BOOL",HAS_SIZE_BOOL; +"HAS_SIZE_CARD",HAS_SIZE_CARD; +"HAS_SIZE_CART_UNIV",HAS_SIZE_CART_UNIV; +"HAS_SIZE_CLAUSES",HAS_SIZE_CLAUSES; +"HAS_SIZE_COMPLEX_ROOTS_UNITY",HAS_SIZE_COMPLEX_ROOTS_UNITY; +"HAS_SIZE_CROSS",HAS_SIZE_CROSS; +"HAS_SIZE_DIFF",HAS_SIZE_DIFF; +"HAS_SIZE_FACES_OF_SIMPLEX",HAS_SIZE_FACES_OF_SIMPLEX; +"HAS_SIZE_FINITE_IMAGE",HAS_SIZE_FINITE_IMAGE; +"HAS_SIZE_FUNSPACE",HAS_SIZE_FUNSPACE; +"HAS_SIZE_FUNSPACE_UNIV",HAS_SIZE_FUNSPACE_UNIV; +"HAS_SIZE_IMAGE_INJ",HAS_SIZE_IMAGE_INJ; +"HAS_SIZE_IMAGE_INJ_EQ",HAS_SIZE_IMAGE_INJ_EQ; +"HAS_SIZE_INDEX",HAS_SIZE_INDEX; +"HAS_SIZE_INTSEG_INT",HAS_SIZE_INTSEG_INT; +"HAS_SIZE_INTSEG_NUM",HAS_SIZE_INTSEG_NUM; +"HAS_SIZE_MULTIVECTOR",HAS_SIZE_MULTIVECTOR; +"HAS_SIZE_NUMSEG",HAS_SIZE_NUMSEG; +"HAS_SIZE_NUMSEG_1",HAS_SIZE_NUMSEG_1; +"HAS_SIZE_NUMSEG_LE",HAS_SIZE_NUMSEG_LE; +"HAS_SIZE_NUMSEG_LT",HAS_SIZE_NUMSEG_LT; +"HAS_SIZE_PCROSS",HAS_SIZE_PCROSS; +"HAS_SIZE_PERMUTATIONS",HAS_SIZE_PERMUTATIONS; +"HAS_SIZE_POWERSET",HAS_SIZE_POWERSET; +"HAS_SIZE_PRODUCT",HAS_SIZE_PRODUCT; +"HAS_SIZE_PRODUCT_DEPENDENT",HAS_SIZE_PRODUCT_DEPENDENT; +"HAS_SIZE_SET_OF_LIST",HAS_SIZE_SET_OF_LIST; +"HAS_SIZE_STDBASIS",HAS_SIZE_STDBASIS; +"HAS_SIZE_SUC",HAS_SIZE_SUC; +"HAS_SIZE_UNION",HAS_SIZE_UNION; +"HAS_SIZE_UNIONS",HAS_SIZE_UNIONS; +"HAS_VECTOR_DERIVATIVE_ADD",HAS_VECTOR_DERIVATIVE_ADD; +"HAS_VECTOR_DERIVATIVE_AT_WITHIN",HAS_VECTOR_DERIVATIVE_AT_WITHIN; +"HAS_VECTOR_DERIVATIVE_BILINEAR_AT",HAS_VECTOR_DERIVATIVE_BILINEAR_AT; +"HAS_VECTOR_DERIVATIVE_BILINEAR_WITHIN",HAS_VECTOR_DERIVATIVE_BILINEAR_WITHIN; +"HAS_VECTOR_DERIVATIVE_CIRCLEPATH",HAS_VECTOR_DERIVATIVE_CIRCLEPATH; +"HAS_VECTOR_DERIVATIVE_CMUL",HAS_VECTOR_DERIVATIVE_CMUL; +"HAS_VECTOR_DERIVATIVE_CMUL_EQ",HAS_VECTOR_DERIVATIVE_CMUL_EQ; +"HAS_VECTOR_DERIVATIVE_CONST",HAS_VECTOR_DERIVATIVE_CONST; +"HAS_VECTOR_DERIVATIVE_ID",HAS_VECTOR_DERIVATIVE_ID; +"HAS_VECTOR_DERIVATIVE_INDEFINITE_INTEGRAL",HAS_VECTOR_DERIVATIVE_INDEFINITE_INTEGRAL; +"HAS_VECTOR_DERIVATIVE_LINEPATH_AT",HAS_VECTOR_DERIVATIVE_LINEPATH_AT; +"HAS_VECTOR_DERIVATIVE_LINEPATH_WITHIN",HAS_VECTOR_DERIVATIVE_LINEPATH_WITHIN; +"HAS_VECTOR_DERIVATIVE_NEG",HAS_VECTOR_DERIVATIVE_NEG; +"HAS_VECTOR_DERIVATIVE_NEG_EQ",HAS_VECTOR_DERIVATIVE_NEG_EQ; +"HAS_VECTOR_DERIVATIVE_PARTCIRCLEPATH",HAS_VECTOR_DERIVATIVE_PARTCIRCLEPATH; +"HAS_VECTOR_DERIVATIVE_REAL_COMPLEX",HAS_VECTOR_DERIVATIVE_REAL_COMPLEX; +"HAS_VECTOR_DERIVATIVE_SUB",HAS_VECTOR_DERIVATIVE_SUB; +"HAS_VECTOR_DERIVATIVE_TRANSFORM_AT",HAS_VECTOR_DERIVATIVE_TRANSFORM_AT; +"HAS_VECTOR_DERIVATIVE_TRANSFORM_WITHIN",HAS_VECTOR_DERIVATIVE_TRANSFORM_WITHIN; +"HAS_VECTOR_DERIVATIVE_TRANSFORM_WITHIN_OPEN",HAS_VECTOR_DERIVATIVE_TRANSFORM_WITHIN_OPEN; +"HAS_VECTOR_DERIVATIVE_UNIQUE_AT",HAS_VECTOR_DERIVATIVE_UNIQUE_AT; +"HAS_VECTOR_DERIVATIVE_VECTOR_POLYNOMIAL_FUNCTION",HAS_VECTOR_DERIVATIVE_VECTOR_POLYNOMIAL_FUNCTION; +"HAS_VECTOR_DERIVATIVE_WITHIN_SUBSET",HAS_VECTOR_DERIVATIVE_WITHIN_SUBSET; +"HD",HD; +"HD_APPEND",HD_APPEND; +"HEINE_BOREL_IMP_BOLZANO_WEIERSTRASS",HEINE_BOREL_IMP_BOLZANO_WEIERSTRASS; +"HEINE_BOREL_LEMMA",HEINE_BOREL_LEMMA; +"HELLY",HELLY; +"HELLY_ALT",HELLY_ALT; +"HELLY_CLOSED",HELLY_CLOSED; +"HELLY_CLOSED_ALT",HELLY_CLOSED_ALT; +"HELLY_COMPACT",HELLY_COMPACT; +"HELLY_COMPACT_ALT",HELLY_COMPACT_ALT; +"HELLY_INDUCT",HELLY_INDUCT; +"HENSTOCK_LEMMA",HENSTOCK_LEMMA; +"HENSTOCK_LEMMA_PART1",HENSTOCK_LEMMA_PART1; +"HENSTOCK_LEMMA_PART2",HENSTOCK_LEMMA_PART2; +"HIGHER_COMPLEX_DERIVATIVE_1",HIGHER_COMPLEX_DERIVATIVE_1; +"HIGHER_COMPLEX_DERIVATIVE_ADD",HIGHER_COMPLEX_DERIVATIVE_ADD; +"HIGHER_COMPLEX_DERIVATIVE_ADD_AT",HIGHER_COMPLEX_DERIVATIVE_ADD_AT; +"HIGHER_COMPLEX_DERIVATIVE_COMPOSE_LINEAR",HIGHER_COMPLEX_DERIVATIVE_COMPOSE_LINEAR; +"HIGHER_COMPLEX_DERIVATIVE_COMP_ITER_LEMMA",HIGHER_COMPLEX_DERIVATIVE_COMP_ITER_LEMMA; +"HIGHER_COMPLEX_DERIVATIVE_COMP_LEMMA",HIGHER_COMPLEX_DERIVATIVE_COMP_LEMMA; +"HIGHER_COMPLEX_DERIVATIVE_CONST",HIGHER_COMPLEX_DERIVATIVE_CONST; +"HIGHER_COMPLEX_DERIVATIVE_EQ_ITER",HIGHER_COMPLEX_DERIVATIVE_EQ_ITER; +"HIGHER_COMPLEX_DERIVATIVE_HIGHER_COMPLEX_DERIVATIVE",HIGHER_COMPLEX_DERIVATIVE_HIGHER_COMPLEX_DERIVATIVE; +"HIGHER_COMPLEX_DERIVATIVE_ID",HIGHER_COMPLEX_DERIVATIVE_ID; +"HIGHER_COMPLEX_DERIVATIVE_ITER_TOP_LEMMA",HIGHER_COMPLEX_DERIVATIVE_ITER_TOP_LEMMA; +"HIGHER_COMPLEX_DERIVATIVE_LINEAR",HIGHER_COMPLEX_DERIVATIVE_LINEAR; +"HIGHER_COMPLEX_DERIVATIVE_MUL",HIGHER_COMPLEX_DERIVATIVE_MUL; +"HIGHER_COMPLEX_DERIVATIVE_MUL_AT",HIGHER_COMPLEX_DERIVATIVE_MUL_AT; +"HIGHER_COMPLEX_DERIVATIVE_NEG",HIGHER_COMPLEX_DERIVATIVE_NEG; +"HIGHER_COMPLEX_DERIVATIVE_NEG_AT",HIGHER_COMPLEX_DERIVATIVE_NEG_AT; +"HIGHER_COMPLEX_DERIVATIVE_SUB",HIGHER_COMPLEX_DERIVATIVE_SUB; +"HIGHER_COMPLEX_DERIVATIVE_SUB_AT",HIGHER_COMPLEX_DERIVATIVE_SUB_AT; +"HIGHER_COMPLEX_DERIVATIVE_TRANSFORM_WITHIN_OPEN",HIGHER_COMPLEX_DERIVATIVE_TRANSFORM_WITHIN_OPEN; +"HOLOMORPHIC_COMPLEX_DERIVATIVE",HOLOMORPHIC_COMPLEX_DERIVATIVE; +"HOLOMORPHIC_CONVEX_PRIMITIVE",HOLOMORPHIC_CONVEX_PRIMITIVE; +"HOLOMORPHIC_DERIVATIVE",HOLOMORPHIC_DERIVATIVE; +"HOLOMORPHIC_EQ",HOLOMORPHIC_EQ; +"HOLOMORPHIC_FACTOR_ORDER_OF_ZERO",HOLOMORPHIC_FACTOR_ORDER_OF_ZERO; +"HOLOMORPHIC_FACTOR_ORDER_OF_ZERO_STRONG",HOLOMORPHIC_FACTOR_ORDER_OF_ZERO_STRONG; +"HOLOMORPHIC_FACTOR_ZERO_NONCONSTANT",HOLOMORPHIC_FACTOR_ZERO_NONCONSTANT; +"HOLOMORPHIC_FUN_EQ_0_ON_BALL",HOLOMORPHIC_FUN_EQ_0_ON_BALL; +"HOLOMORPHIC_FUN_EQ_0_ON_CONNECTED",HOLOMORPHIC_FUN_EQ_0_ON_CONNECTED; +"HOLOMORPHIC_FUN_EQ_CONST_ON_CONNECTED",HOLOMORPHIC_FUN_EQ_CONST_ON_CONNECTED; +"HOLOMORPHIC_FUN_EQ_ON_BALL",HOLOMORPHIC_FUN_EQ_ON_BALL; +"HOLOMORPHIC_FUN_EQ_ON_CONNECTED",HOLOMORPHIC_FUN_EQ_ON_CONNECTED; +"HOLOMORPHIC_HIGHER_COMPLEX_DERIVATIVE",HOLOMORPHIC_HIGHER_COMPLEX_DERIVATIVE; +"HOLOMORPHIC_IFF_POWER_SERIES",HOLOMORPHIC_IFF_POWER_SERIES; +"HOLOMORPHIC_INJECTIVE_IMP_REGULAR",HOLOMORPHIC_INJECTIVE_IMP_REGULAR; +"HOLOMORPHIC_INVOLUTION_POINT",HOLOMORPHIC_INVOLUTION_POINT; +"HOLOMORPHIC_ON_ADD",HOLOMORPHIC_ON_ADD; +"HOLOMORPHIC_ON_CACS",HOLOMORPHIC_ON_CACS; +"HOLOMORPHIC_ON_CASN",HOLOMORPHIC_ON_CASN; +"HOLOMORPHIC_ON_CATN",HOLOMORPHIC_ON_CATN; +"HOLOMORPHIC_ON_CCOS",HOLOMORPHIC_ON_CCOS; +"HOLOMORPHIC_ON_CEXP",HOLOMORPHIC_ON_CEXP; +"HOLOMORPHIC_ON_CLOG",HOLOMORPHIC_ON_CLOG; +"HOLOMORPHIC_ON_COMPOSE",HOLOMORPHIC_ON_COMPOSE; +"HOLOMORPHIC_ON_COMPOSE_GEN",HOLOMORPHIC_ON_COMPOSE_GEN; +"HOLOMORPHIC_ON_CONST",HOLOMORPHIC_ON_CONST; +"HOLOMORPHIC_ON_CPOW_RIGHT",HOLOMORPHIC_ON_CPOW_RIGHT; +"HOLOMORPHIC_ON_CSIN",HOLOMORPHIC_ON_CSIN; +"HOLOMORPHIC_ON_CSQRT",HOLOMORPHIC_ON_CSQRT; +"HOLOMORPHIC_ON_CTAN",HOLOMORPHIC_ON_CTAN; +"HOLOMORPHIC_ON_DIFFERENTIABLE",HOLOMORPHIC_ON_DIFFERENTIABLE; +"HOLOMORPHIC_ON_DIV",HOLOMORPHIC_ON_DIV; +"HOLOMORPHIC_ON_EXTEND_BOUNDED",HOLOMORPHIC_ON_EXTEND_BOUNDED; +"HOLOMORPHIC_ON_EXTEND_LIM",HOLOMORPHIC_ON_EXTEND_LIM; +"HOLOMORPHIC_ON_ID",HOLOMORPHIC_ON_ID; +"HOLOMORPHIC_ON_IMP_CONTINUOUS_ON",HOLOMORPHIC_ON_IMP_CONTINUOUS_ON; +"HOLOMORPHIC_ON_IMP_DIFFERENTIABLE_AT",HOLOMORPHIC_ON_IMP_DIFFERENTIABLE_AT; +"HOLOMORPHIC_ON_IMP_DIFFERENTIABLE_WITHIN",HOLOMORPHIC_ON_IMP_DIFFERENTIABLE_WITHIN; +"HOLOMORPHIC_ON_INV",HOLOMORPHIC_ON_INV; +"HOLOMORPHIC_ON_INVERSE",HOLOMORPHIC_ON_INVERSE; +"HOLOMORPHIC_ON_LINEAR",HOLOMORPHIC_ON_LINEAR; +"HOLOMORPHIC_ON_MUL",HOLOMORPHIC_ON_MUL; +"HOLOMORPHIC_ON_NEG",HOLOMORPHIC_ON_NEG; +"HOLOMORPHIC_ON_OPEN",HOLOMORPHIC_ON_OPEN; +"HOLOMORPHIC_ON_PASTE_ACROSS_LINE",HOLOMORPHIC_ON_PASTE_ACROSS_LINE; +"HOLOMORPHIC_ON_POW",HOLOMORPHIC_ON_POW; +"HOLOMORPHIC_ON_SUB",HOLOMORPHIC_ON_SUB; +"HOLOMORPHIC_ON_SUBSET",HOLOMORPHIC_ON_SUBSET; +"HOLOMORPHIC_ON_VSUM",HOLOMORPHIC_ON_VSUM; +"HOLOMORPHIC_PERIODIC_FIXPOINT",HOLOMORPHIC_PERIODIC_FIXPOINT; +"HOLOMORPHIC_POINT_SMALL_TRIANGLE",HOLOMORPHIC_POINT_SMALL_TRIANGLE; +"HOLOMORPHIC_POWER_SERIES",HOLOMORPHIC_POWER_SERIES; +"HOLOMORPHIC_STARLIKE_PRIMITIVE",HOLOMORPHIC_STARLIKE_PRIMITIVE; +"HOLOMORPHIC_TRANSFORM",HOLOMORPHIC_TRANSFORM; +"HOLOMORPHIC_UNIFORM_LIMIT",HOLOMORPHIC_UNIFORM_LIMIT; +"HOLOMORPHIC_UNIFORM_SEQUENCE",HOLOMORPHIC_UNIFORM_SEQUENCE; +"HOMEOMORPHIC_AFFINE_SETS",HOMEOMORPHIC_AFFINE_SETS; +"HOMEOMORPHIC_AFFINE_SETS_EQ",HOMEOMORPHIC_AFFINE_SETS_EQ; +"HOMEOMORPHIC_AFFINITY",HOMEOMORPHIC_AFFINITY; +"HOMEOMORPHIC_ANRNESS",HOMEOMORPHIC_ANRNESS; +"HOMEOMORPHIC_ARC_IMAGES",HOMEOMORPHIC_ARC_IMAGES; +"HOMEOMORPHIC_ARC_IMAGE_INTERVAL",HOMEOMORPHIC_ARC_IMAGE_INTERVAL; +"HOMEOMORPHIC_ARC_IMAGE_SEGMENT",HOMEOMORPHIC_ARC_IMAGE_SEGMENT; +"HOMEOMORPHIC_BALLS",HOMEOMORPHIC_BALLS; +"HOMEOMORPHIC_BALLS_EQ",HOMEOMORPHIC_BALLS_EQ; +"HOMEOMORPHIC_BALL_UNIV",HOMEOMORPHIC_BALL_UNIV; +"HOMEOMORPHIC_CBALLS",HOMEOMORPHIC_CBALLS; +"HOMEOMORPHIC_CBALLS_EQ",HOMEOMORPHIC_CBALLS_EQ; +"HOMEOMORPHIC_CLOSED_INTERVALS",HOMEOMORPHIC_CLOSED_INTERVALS; +"HOMEOMORPHIC_COMPACT",HOMEOMORPHIC_COMPACT; +"HOMEOMORPHIC_COMPACTNESS",HOMEOMORPHIC_COMPACTNESS; +"HOMEOMORPHIC_COMPACT_ARNESS",HOMEOMORPHIC_COMPACT_ARNESS; +"HOMEOMORPHIC_CONNECTEDNESS",HOMEOMORPHIC_CONNECTEDNESS; +"HOMEOMORPHIC_CONTRACTIBLE",HOMEOMORPHIC_CONTRACTIBLE; +"HOMEOMORPHIC_CONTRACTIBLE_EQ",HOMEOMORPHIC_CONTRACTIBLE_EQ; +"HOMEOMORPHIC_CONVEX_COMPACT",HOMEOMORPHIC_CONVEX_COMPACT; +"HOMEOMORPHIC_CONVEX_COMPACT_CBALL",HOMEOMORPHIC_CONVEX_COMPACT_CBALL; +"HOMEOMORPHIC_CONVEX_COMPACT_SETS",HOMEOMORPHIC_CONVEX_COMPACT_SETS; +"HOMEOMORPHIC_CONVEX_COMPACT_SETS_EQ",HOMEOMORPHIC_CONVEX_COMPACT_SETS_EQ; +"HOMEOMORPHIC_CONVEX_SETS",HOMEOMORPHIC_CONVEX_SETS; +"HOMEOMORPHIC_EMPTY",HOMEOMORPHIC_EMPTY; +"HOMEOMORPHIC_FINITE",HOMEOMORPHIC_FINITE; +"HOMEOMORPHIC_FINITE_STRONG",HOMEOMORPHIC_FINITE_STRONG; +"HOMEOMORPHIC_FIXPOINT_PROPERTY",HOMEOMORPHIC_FIXPOINT_PROPERTY; +"HOMEOMORPHIC_FRONTIERS",HOMEOMORPHIC_FRONTIERS; +"HOMEOMORPHIC_FRONTIERS_SAME_DIMENSION",HOMEOMORPHIC_FRONTIERS_SAME_DIMENSION; +"HOMEOMORPHIC_HYPERPLANES",HOMEOMORPHIC_HYPERPLANES; +"HOMEOMORPHIC_HYPERPLANES_EQ",HOMEOMORPHIC_HYPERPLANES_EQ; +"HOMEOMORPHIC_HYPERPLANE_STANDARD_HYPERPLANE",HOMEOMORPHIC_HYPERPLANE_STANDARD_HYPERPLANE; +"HOMEOMORPHIC_HYPERPLANE_UNIV",HOMEOMORPHIC_HYPERPLANE_UNIV; +"HOMEOMORPHIC_IMP_CARD_EQ",HOMEOMORPHIC_IMP_CARD_EQ; +"HOMEOMORPHIC_IMP_HOMOTOPY_EQUIVALENT",HOMEOMORPHIC_IMP_HOMOTOPY_EQUIVALENT; +"HOMEOMORPHIC_INJECTIVE_LINEAR_IMAGE_LEFT_EQ",HOMEOMORPHIC_INJECTIVE_LINEAR_IMAGE_LEFT_EQ; +"HOMEOMORPHIC_INJECTIVE_LINEAR_IMAGE_RIGHT_EQ",HOMEOMORPHIC_INJECTIVE_LINEAR_IMAGE_RIGHT_EQ; +"HOMEOMORPHIC_INJECTIVE_LINEAR_IMAGE_SELF",HOMEOMORPHIC_INJECTIVE_LINEAR_IMAGE_SELF; +"HOMEOMORPHIC_INTERIORS",HOMEOMORPHIC_INTERIORS; +"HOMEOMORPHIC_INTERIORS_SAME_DIMENSION",HOMEOMORPHIC_INTERIORS_SAME_DIMENSION; +"HOMEOMORPHIC_INTERVALS_EQ",HOMEOMORPHIC_INTERVALS_EQ; +"HOMEOMORPHIC_LOCALLY",HOMEOMORPHIC_LOCALLY; +"HOMEOMORPHIC_LOCAL_COMPACTNESS",HOMEOMORPHIC_LOCAL_COMPACTNESS; +"HOMEOMORPHIC_LOCAL_CONNECTEDNESS",HOMEOMORPHIC_LOCAL_CONNECTEDNESS; +"HOMEOMORPHIC_LOCAL_PATH_CONNECTEDNESS",HOMEOMORPHIC_LOCAL_PATH_CONNECTEDNESS; +"HOMEOMORPHIC_MINIMAL",HOMEOMORPHIC_MINIMAL; +"HOMEOMORPHIC_MONOTONE_IMAGE_INTERVAL",HOMEOMORPHIC_MONOTONE_IMAGE_INTERVAL; +"HOMEOMORPHIC_ONE_POINT_COMPACTIFICATIONS",HOMEOMORPHIC_ONE_POINT_COMPACTIFICATIONS; +"HOMEOMORPHIC_OPEN_INTERVALS",HOMEOMORPHIC_OPEN_INTERVALS; +"HOMEOMORPHIC_OPEN_INTERVALS_1",HOMEOMORPHIC_OPEN_INTERVALS_1; +"HOMEOMORPHIC_OPEN_INTERVAL_UNIV",HOMEOMORPHIC_OPEN_INTERVAL_UNIV; +"HOMEOMORPHIC_OPEN_INTERVAL_UNIV_1",HOMEOMORPHIC_OPEN_INTERVAL_UNIV_1; +"HOMEOMORPHIC_PATH_CONNECTEDNESS",HOMEOMORPHIC_PATH_CONNECTEDNESS; +"HOMEOMORPHIC_PCROSS",HOMEOMORPHIC_PCROSS; +"HOMEOMORPHIC_PCROSS_ASSOC",HOMEOMORPHIC_PCROSS_ASSOC; +"HOMEOMORPHIC_PCROSS_SING",HOMEOMORPHIC_PCROSS_SING; +"HOMEOMORPHIC_PCROSS_SYM",HOMEOMORPHIC_PCROSS_SYM; +"HOMEOMORPHIC_PUNCTURED_AFFINE_SPHERE_AFFINE",HOMEOMORPHIC_PUNCTURED_AFFINE_SPHERE_AFFINE; +"HOMEOMORPHIC_PUNCTURED_SPHERE_AFFINE",HOMEOMORPHIC_PUNCTURED_SPHERE_AFFINE; +"HOMEOMORPHIC_PUNCTURED_SPHERE_AFFINE_GEN",HOMEOMORPHIC_PUNCTURED_SPHERE_AFFINE_GEN; +"HOMEOMORPHIC_PUNCTURED_SPHERE_HYPERPLANE",HOMEOMORPHIC_PUNCTURED_SPHERE_HYPERPLANE; +"HOMEOMORPHIC_PUNCTURED_SPHERE_UNIV",HOMEOMORPHIC_PUNCTURED_SPHERE_UNIV; +"HOMEOMORPHIC_REFL",HOMEOMORPHIC_REFL; +"HOMEOMORPHIC_RELATIVE_BOUNDARIES",HOMEOMORPHIC_RELATIVE_BOUNDARIES; +"HOMEOMORPHIC_RELATIVE_BOUNDARIES_SAME_DIMENSION",HOMEOMORPHIC_RELATIVE_BOUNDARIES_SAME_DIMENSION; +"HOMEOMORPHIC_RELATIVE_FRONTIERS_CONVEX_BOUNDED_SETS",HOMEOMORPHIC_RELATIVE_FRONTIERS_CONVEX_BOUNDED_SETS; +"HOMEOMORPHIC_RELATIVE_INTERIORS",HOMEOMORPHIC_RELATIVE_INTERIORS; +"HOMEOMORPHIC_RELATIVE_INTERIORS_SAME_DIMENSION",HOMEOMORPHIC_RELATIVE_INTERIORS_SAME_DIMENSION; +"HOMEOMORPHIC_SCALING",HOMEOMORPHIC_SCALING; +"HOMEOMORPHIC_SCALING_LEFT",HOMEOMORPHIC_SCALING_LEFT; +"HOMEOMORPHIC_SCALING_RIGHT",HOMEOMORPHIC_SCALING_RIGHT; +"HOMEOMORPHIC_SIMPLE_PATH_IMAGES",HOMEOMORPHIC_SIMPLE_PATH_IMAGES; +"HOMEOMORPHIC_SIMPLE_PATH_IMAGE_CIRCLE",HOMEOMORPHIC_SIMPLE_PATH_IMAGE_CIRCLE; +"HOMEOMORPHIC_SIMPLY_CONNECTED",HOMEOMORPHIC_SIMPLY_CONNECTED; +"HOMEOMORPHIC_SIMPLY_CONNECTED_EQ",HOMEOMORPHIC_SIMPLY_CONNECTED_EQ; +"HOMEOMORPHIC_SING",HOMEOMORPHIC_SING; +"HOMEOMORPHIC_SPHERES",HOMEOMORPHIC_SPHERES; +"HOMEOMORPHIC_SPHERES_EQ",HOMEOMORPHIC_SPHERES_EQ; +"HOMEOMORPHIC_STANDARD_HYPERPLANE_HYPERPLANE",HOMEOMORPHIC_STANDARD_HYPERPLANE_HYPERPLANE; +"HOMEOMORPHIC_SUBSPACES",HOMEOMORPHIC_SUBSPACES; +"HOMEOMORPHIC_SUBSPACES_EQ",HOMEOMORPHIC_SUBSPACES_EQ; +"HOMEOMORPHIC_SYM",HOMEOMORPHIC_SYM; +"HOMEOMORPHIC_TRANS",HOMEOMORPHIC_TRANS; +"HOMEOMORPHIC_TRANSLATION",HOMEOMORPHIC_TRANSLATION; +"HOMEOMORPHIC_TRANSLATION_LEFT_EQ",HOMEOMORPHIC_TRANSLATION_LEFT_EQ; +"HOMEOMORPHIC_TRANSLATION_RIGHT_EQ",HOMEOMORPHIC_TRANSLATION_RIGHT_EQ; +"HOMEOMORPHIC_TRANSLATION_SELF",HOMEOMORPHIC_TRANSLATION_SELF; +"HOMEOMORPHIC_UNIV_UNIV",HOMEOMORPHIC_UNIV_UNIV; +"HOMEOMORPHISM",HOMEOMORPHISM; +"HOMEOMORPHISM_ARC",HOMEOMORPHISM_ARC; +"HOMEOMORPHISM_COMPACT",HOMEOMORPHISM_COMPACT; +"HOMEOMORPHISM_COMPOSE",HOMEOMORPHISM_COMPOSE; +"HOMEOMORPHISM_FROM_COMPOSITION_INJECTIVE",HOMEOMORPHISM_FROM_COMPOSITION_INJECTIVE; +"HOMEOMORPHISM_FROM_COMPOSITION_SURJECTIVE",HOMEOMORPHISM_FROM_COMPOSITION_SURJECTIVE; +"HOMEOMORPHISM_GROUPING_POINTS_EXISTS",HOMEOMORPHISM_GROUPING_POINTS_EXISTS; +"HOMEOMORPHISM_GROUPING_POINTS_EXISTS_GEN",HOMEOMORPHISM_GROUPING_POINTS_EXISTS_GEN; +"HOMEOMORPHISM_I",HOMEOMORPHISM_I; +"HOMEOMORPHISM_ID",HOMEOMORPHISM_ID; +"HOMEOMORPHISM_IMP_CLOSED_MAP",HOMEOMORPHISM_IMP_CLOSED_MAP; +"HOMEOMORPHISM_IMP_COVERING_SPACE",HOMEOMORPHISM_IMP_COVERING_SPACE; +"HOMEOMORPHISM_IMP_OPEN_MAP",HOMEOMORPHISM_IMP_OPEN_MAP; +"HOMEOMORPHISM_IMP_QUOTIENT_MAP",HOMEOMORPHISM_IMP_QUOTIENT_MAP; +"HOMEOMORPHISM_INJECTIVE_CLOSED_MAP",HOMEOMORPHISM_INJECTIVE_CLOSED_MAP; +"HOMEOMORPHISM_INJECTIVE_CLOSED_MAP_EQ",HOMEOMORPHISM_INJECTIVE_CLOSED_MAP_EQ; +"HOMEOMORPHISM_INJECTIVE_OPEN_MAP",HOMEOMORPHISM_INJECTIVE_OPEN_MAP; +"HOMEOMORPHISM_INJECTIVE_OPEN_MAP_EQ",HOMEOMORPHISM_INJECTIVE_OPEN_MAP_EQ; +"HOMEOMORPHISM_LOCALLY",HOMEOMORPHISM_LOCALLY; +"HOMEOMORPHISM_MOVING_POINTS_EXISTS",HOMEOMORPHISM_MOVING_POINTS_EXISTS; +"HOMEOMORPHISM_MOVING_POINTS_EXISTS_GEN",HOMEOMORPHISM_MOVING_POINTS_EXISTS_GEN; +"HOMEOMORPHISM_MOVING_POINT_EXISTS",HOMEOMORPHISM_MOVING_POINT_EXISTS; +"HOMEOMORPHISM_OF_SUBSETS",HOMEOMORPHISM_OF_SUBSETS; +"HOMEOMORPHISM_SYM",HOMEOMORPHISM_SYM; +"HOMOGENEOUS_LINEAR_EQUATIONS_DET",HOMOGENEOUS_LINEAR_EQUATIONS_DET; +"HOMOTOPICALLY_TRIVIAL_RETRACTION_GEN",HOMOTOPICALLY_TRIVIAL_RETRACTION_GEN; +"HOMOTOPICALLY_TRIVIAL_RETRACTION_NULL_GEN",HOMOTOPICALLY_TRIVIAL_RETRACTION_NULL_GEN; +"HOMOTOPIC_BORSUK_MAPS_IN_BOUNDED_COMPONENT",HOMOTOPIC_BORSUK_MAPS_IN_BOUNDED_COMPONENT; +"HOMOTOPIC_CIRCLEMAPS_DIV",HOMOTOPIC_CIRCLEMAPS_DIV; +"HOMOTOPIC_CIRCLEMAPS_DIV_1",HOMOTOPIC_CIRCLEMAPS_DIV_1; +"HOMOTOPIC_CIRCLEMAPS_IMP_HOMOTOPIC_LOOPS",HOMOTOPIC_CIRCLEMAPS_IMP_HOMOTOPIC_LOOPS; +"HOMOTOPIC_COMPOSE_CONTINUOUS_LEFT",HOMOTOPIC_COMPOSE_CONTINUOUS_LEFT; +"HOMOTOPIC_COMPOSE_CONTINUOUS_RIGHT",HOMOTOPIC_COMPOSE_CONTINUOUS_RIGHT; +"HOMOTOPIC_CONSTANT_MAPS",HOMOTOPIC_CONSTANT_MAPS; +"HOMOTOPIC_FROM_CONTRACTIBLE",HOMOTOPIC_FROM_CONTRACTIBLE; +"HOMOTOPIC_INTO_CONTRACTIBLE",HOMOTOPIC_INTO_CONTRACTIBLE; +"HOMOTOPIC_JOIN_LEMMA",HOMOTOPIC_JOIN_LEMMA; +"HOMOTOPIC_JOIN_SUBPATHS",HOMOTOPIC_JOIN_SUBPATHS; +"HOMOTOPIC_LOOPS",HOMOTOPIC_LOOPS; +"HOMOTOPIC_LOOPS_ADD_SYM",HOMOTOPIC_LOOPS_ADD_SYM; +"HOMOTOPIC_LOOPS_CONJUGATE",HOMOTOPIC_LOOPS_CONJUGATE; +"HOMOTOPIC_LOOPS_CONTINUOUS_IMAGE",HOMOTOPIC_LOOPS_CONTINUOUS_IMAGE; +"HOMOTOPIC_LOOPS_EQ",HOMOTOPIC_LOOPS_EQ; +"HOMOTOPIC_LOOPS_IMP_HOMOTOPIC_CIRCLEMAPS",HOMOTOPIC_LOOPS_IMP_HOMOTOPIC_CIRCLEMAPS; +"HOMOTOPIC_LOOPS_IMP_HOMOTOPIC_PATHS_NULL",HOMOTOPIC_LOOPS_IMP_HOMOTOPIC_PATHS_NULL; +"HOMOTOPIC_LOOPS_IMP_LOOP",HOMOTOPIC_LOOPS_IMP_LOOP; +"HOMOTOPIC_LOOPS_IMP_PATH",HOMOTOPIC_LOOPS_IMP_PATH; +"HOMOTOPIC_LOOPS_IMP_PATH_COMPONENT_VALUE",HOMOTOPIC_LOOPS_IMP_PATH_COMPONENT_VALUE; +"HOMOTOPIC_LOOPS_IMP_SUBSET",HOMOTOPIC_LOOPS_IMP_SUBSET; +"HOMOTOPIC_LOOPS_LINEAR",HOMOTOPIC_LOOPS_LINEAR; +"HOMOTOPIC_LOOPS_NEARBY_EXPLICIT",HOMOTOPIC_LOOPS_NEARBY_EXPLICIT; +"HOMOTOPIC_LOOPS_REFL",HOMOTOPIC_LOOPS_REFL; +"HOMOTOPIC_LOOPS_SHIFTPATH",HOMOTOPIC_LOOPS_SHIFTPATH; +"HOMOTOPIC_LOOPS_SHIFTPATH_SELF",HOMOTOPIC_LOOPS_SHIFTPATH_SELF; +"HOMOTOPIC_LOOPS_SUBSET",HOMOTOPIC_LOOPS_SUBSET; +"HOMOTOPIC_LOOPS_SYM",HOMOTOPIC_LOOPS_SYM; +"HOMOTOPIC_LOOPS_TRANS",HOMOTOPIC_LOOPS_TRANS; +"HOMOTOPIC_NEARBY_LOOPS",HOMOTOPIC_NEARBY_LOOPS; +"HOMOTOPIC_NEARBY_PATHS",HOMOTOPIC_NEARBY_PATHS; +"HOMOTOPIC_NON_ANTIPODAL_SPHEREMAPS",HOMOTOPIC_NON_ANTIPODAL_SPHEREMAPS; +"HOMOTOPIC_NON_MIDPOINT_SPHEREMAPS",HOMOTOPIC_NON_MIDPOINT_SPHEREMAPS; +"HOMOTOPIC_ORTHOGONAL_TRANSFORMATIONS",HOMOTOPIC_ORTHOGONAL_TRANSFORMATIONS; +"HOMOTOPIC_PATHS",HOMOTOPIC_PATHS; +"HOMOTOPIC_PATHS_ASSOC",HOMOTOPIC_PATHS_ASSOC; +"HOMOTOPIC_PATHS_CONTINUOUS_IMAGE",HOMOTOPIC_PATHS_CONTINUOUS_IMAGE; +"HOMOTOPIC_PATHS_EQ",HOMOTOPIC_PATHS_EQ; +"HOMOTOPIC_PATHS_IMP_HOMOTOPIC_LOOPS",HOMOTOPIC_PATHS_IMP_HOMOTOPIC_LOOPS; +"HOMOTOPIC_PATHS_IMP_PATH",HOMOTOPIC_PATHS_IMP_PATH; +"HOMOTOPIC_PATHS_IMP_PATHFINISH",HOMOTOPIC_PATHS_IMP_PATHFINISH; +"HOMOTOPIC_PATHS_IMP_PATHSTART",HOMOTOPIC_PATHS_IMP_PATHSTART; +"HOMOTOPIC_PATHS_IMP_SUBSET",HOMOTOPIC_PATHS_IMP_SUBSET; +"HOMOTOPIC_PATHS_JOIN",HOMOTOPIC_PATHS_JOIN; +"HOMOTOPIC_PATHS_LID",HOMOTOPIC_PATHS_LID; +"HOMOTOPIC_PATHS_LINEAR",HOMOTOPIC_PATHS_LINEAR; +"HOMOTOPIC_PATHS_LINV",HOMOTOPIC_PATHS_LINV; +"HOMOTOPIC_PATHS_LOOP_PARTS",HOMOTOPIC_PATHS_LOOP_PARTS; +"HOMOTOPIC_PATHS_NEARBY_EXPLICIT",HOMOTOPIC_PATHS_NEARBY_EXPLICIT; +"HOMOTOPIC_PATHS_REFL",HOMOTOPIC_PATHS_REFL; +"HOMOTOPIC_PATHS_REPARAMETRIZE",HOMOTOPIC_PATHS_REPARAMETRIZE; +"HOMOTOPIC_PATHS_REVERSEPATH",HOMOTOPIC_PATHS_REVERSEPATH; +"HOMOTOPIC_PATHS_RID",HOMOTOPIC_PATHS_RID; +"HOMOTOPIC_PATHS_RINV",HOMOTOPIC_PATHS_RINV; +"HOMOTOPIC_PATHS_SUBSET",HOMOTOPIC_PATHS_SUBSET; +"HOMOTOPIC_PATHS_SYM",HOMOTOPIC_PATHS_SYM; +"HOMOTOPIC_PATHS_TRANS",HOMOTOPIC_PATHS_TRANS; +"HOMOTOPIC_POINTS_EQ_PATH_COMPONENT",HOMOTOPIC_POINTS_EQ_PATH_COMPONENT; +"HOMOTOPIC_SPECIAL_ORTHOGONAL_TRANSFORMATIONS",HOMOTOPIC_SPECIAL_ORTHOGONAL_TRANSFORMATIONS; +"HOMOTOPIC_THROUGH_CONTRACTIBLE",HOMOTOPIC_THROUGH_CONTRACTIBLE; +"HOMOTOPIC_TRIVIALITY",HOMOTOPIC_TRIVIALITY; +"HOMOTOPIC_WITH",HOMOTOPIC_WITH; +"HOMOTOPIC_WITH_COMPOSE_CONTINUOUS_LEFT",HOMOTOPIC_WITH_COMPOSE_CONTINUOUS_LEFT; +"HOMOTOPIC_WITH_COMPOSE_CONTINUOUS_RIGHT",HOMOTOPIC_WITH_COMPOSE_CONTINUOUS_RIGHT; +"HOMOTOPIC_WITH_EQ",HOMOTOPIC_WITH_EQ; +"HOMOTOPIC_WITH_EQUAL",HOMOTOPIC_WITH_EQUAL; +"HOMOTOPIC_WITH_IMP_CONTINUOUS",HOMOTOPIC_WITH_IMP_CONTINUOUS; +"HOMOTOPIC_WITH_IMP_PROPERTY",HOMOTOPIC_WITH_IMP_PROPERTY; +"HOMOTOPIC_WITH_IMP_SUBSET",HOMOTOPIC_WITH_IMP_SUBSET; +"HOMOTOPIC_WITH_LINEAR",HOMOTOPIC_WITH_LINEAR; +"HOMOTOPIC_WITH_MONO",HOMOTOPIC_WITH_MONO; +"HOMOTOPIC_WITH_PCROSS",HOMOTOPIC_WITH_PCROSS; +"HOMOTOPIC_WITH_REFL",HOMOTOPIC_WITH_REFL; +"HOMOTOPIC_WITH_SUBSET_LEFT",HOMOTOPIC_WITH_SUBSET_LEFT; +"HOMOTOPIC_WITH_SUBSET_RIGHT",HOMOTOPIC_WITH_SUBSET_RIGHT; +"HOMOTOPIC_WITH_SYM",HOMOTOPIC_WITH_SYM; +"HOMOTOPIC_WITH_TRANS",HOMOTOPIC_WITH_TRANS; +"HOMOTOPY_EQUIVALENT",HOMOTOPY_EQUIVALENT; +"HOMOTOPY_EQUIVALENT_COHOMOTOPIC_TRIVIALITY",HOMOTOPY_EQUIVALENT_COHOMOTOPIC_TRIVIALITY; +"HOMOTOPY_EQUIVALENT_COHOMOTOPIC_TRIVIALITY_NULL",HOMOTOPY_EQUIVALENT_COHOMOTOPIC_TRIVIALITY_NULL; +"HOMOTOPY_EQUIVALENT_CONNECTEDNESS",HOMOTOPY_EQUIVALENT_CONNECTEDNESS; +"HOMOTOPY_EQUIVALENT_CONTRACTIBILITY",HOMOTOPY_EQUIVALENT_CONTRACTIBILITY; +"HOMOTOPY_EQUIVALENT_CONTRACTIBLE_SETS",HOMOTOPY_EQUIVALENT_CONTRACTIBLE_SETS; +"HOMOTOPY_EQUIVALENT_EMPTY",HOMOTOPY_EQUIVALENT_EMPTY; +"HOMOTOPY_EQUIVALENT_HOMOTOPIC_TRIVIALITY",HOMOTOPY_EQUIVALENT_HOMOTOPIC_TRIVIALITY; +"HOMOTOPY_EQUIVALENT_HOMOTOPIC_TRIVIALITY_NULL",HOMOTOPY_EQUIVALENT_HOMOTOPIC_TRIVIALITY_NULL; +"HOMOTOPY_EQUIVALENT_INJECTIVE_LINEAR_IMAGE_LEFT_EQ",HOMOTOPY_EQUIVALENT_INJECTIVE_LINEAR_IMAGE_LEFT_EQ; +"HOMOTOPY_EQUIVALENT_INJECTIVE_LINEAR_IMAGE_RIGHT_EQ",HOMOTOPY_EQUIVALENT_INJECTIVE_LINEAR_IMAGE_RIGHT_EQ; +"HOMOTOPY_EQUIVALENT_INJECTIVE_LINEAR_IMAGE_SELF",HOMOTOPY_EQUIVALENT_INJECTIVE_LINEAR_IMAGE_SELF; +"HOMOTOPY_EQUIVALENT_PATH_CONNECTEDNESS",HOMOTOPY_EQUIVALENT_PATH_CONNECTEDNESS; +"HOMOTOPY_EQUIVALENT_REFL",HOMOTOPY_EQUIVALENT_REFL; +"HOMOTOPY_EQUIVALENT_SEPARATION",HOMOTOPY_EQUIVALENT_SEPARATION; +"HOMOTOPY_EQUIVALENT_SIMPLE_CONNECTEDNESS",HOMOTOPY_EQUIVALENT_SIMPLE_CONNECTEDNESS; +"HOMOTOPY_EQUIVALENT_SING",HOMOTOPY_EQUIVALENT_SING; +"HOMOTOPY_EQUIVALENT_SPHERES_EQ",HOMOTOPY_EQUIVALENT_SPHERES_EQ; +"HOMOTOPY_EQUIVALENT_SYM",HOMOTOPY_EQUIVALENT_SYM; +"HOMOTOPY_EQUIVALENT_TRANS",HOMOTOPY_EQUIVALENT_TRANS; +"HOMOTOPY_EQUIVALENT_TRANSLATION_LEFT_EQ",HOMOTOPY_EQUIVALENT_TRANSLATION_LEFT_EQ; +"HOMOTOPY_EQUIVALENT_TRANSLATION_RIGHT_EQ",HOMOTOPY_EQUIVALENT_TRANSLATION_RIGHT_EQ; +"HOMOTOPY_EQUIVALENT_TRANSLATION_SELF",HOMOTOPY_EQUIVALENT_TRANSLATION_SELF; +"HOMOTOPY_INVARIANT_CONNECTEDNESS",HOMOTOPY_INVARIANT_CONNECTEDNESS; +"HOMOTOPY_INVARIANT_PATH_CONNECTEDNESS",HOMOTOPY_INVARIANT_PATH_CONNECTEDNESS; +"HP",HP; +"HREAL_ADD_AC",HREAL_ADD_AC; +"HREAL_ADD_ASSOC",HREAL_ADD_ASSOC; +"HREAL_ADD_LCANCEL",HREAL_ADD_LCANCEL; +"HREAL_ADD_LDISTRIB",HREAL_ADD_LDISTRIB; +"HREAL_ADD_LID",HREAL_ADD_LID; +"HREAL_ADD_RDISTRIB",HREAL_ADD_RDISTRIB; +"HREAL_ADD_RID",HREAL_ADD_RID; +"HREAL_ADD_SYM",HREAL_ADD_SYM; +"HREAL_ARCH",HREAL_ARCH; +"HREAL_COMPLETE",HREAL_COMPLETE; +"HREAL_EQ_ADD_LCANCEL",HREAL_EQ_ADD_LCANCEL; +"HREAL_EQ_ADD_RCANCEL",HREAL_EQ_ADD_RCANCEL; +"HREAL_INV_0",HREAL_INV_0; +"HREAL_LE_ADD",HREAL_LE_ADD; +"HREAL_LE_ADD2",HREAL_LE_ADD2; +"HREAL_LE_ADD_LCANCEL",HREAL_LE_ADD_LCANCEL; +"HREAL_LE_ADD_RCANCEL",HREAL_LE_ADD_RCANCEL; +"HREAL_LE_ANTISYM",HREAL_LE_ANTISYM; +"HREAL_LE_EXISTS",HREAL_LE_EXISTS; +"HREAL_LE_EXISTS_DEF",HREAL_LE_EXISTS_DEF; +"HREAL_LE_MUL_RCANCEL_IMP",HREAL_LE_MUL_RCANCEL_IMP; +"HREAL_LE_REFL",HREAL_LE_REFL; +"HREAL_LE_TOTAL",HREAL_LE_TOTAL; +"HREAL_LE_TRANS",HREAL_LE_TRANS; +"HREAL_MUL_ASSOC",HREAL_MUL_ASSOC; +"HREAL_MUL_LID",HREAL_MUL_LID; +"HREAL_MUL_LINV",HREAL_MUL_LINV; +"HREAL_MUL_LZERO",HREAL_MUL_LZERO; +"HREAL_MUL_RZERO",HREAL_MUL_RZERO; +"HREAL_MUL_SYM",HREAL_MUL_SYM; +"HREAL_OF_NUM_ADD",HREAL_OF_NUM_ADD; +"HREAL_OF_NUM_EQ",HREAL_OF_NUM_EQ; +"HREAL_OF_NUM_LE",HREAL_OF_NUM_LE; +"HREAL_OF_NUM_MUL",HREAL_OF_NUM_MUL; +"HULLS_EQ",HULLS_EQ; +"HULL_ANTIMONO",HULL_ANTIMONO; +"HULL_EQ",HULL_EQ; +"HULL_HULL",HULL_HULL; +"HULL_IMAGE",HULL_IMAGE; +"HULL_IMAGE_GALOIS",HULL_IMAGE_GALOIS; +"HULL_IMAGE_SUBSET",HULL_IMAGE_SUBSET; +"HULL_INC",HULL_INC; +"HULL_INDUCT",HULL_INDUCT; +"HULL_MINIMAL",HULL_MINIMAL; +"HULL_MONO",HULL_MONO; +"HULL_P",HULL_P; +"HULL_P_AND_Q",HULL_P_AND_Q; +"HULL_REDUNDANT",HULL_REDUNDANT; +"HULL_REDUNDANT_EQ",HULL_REDUNDANT_EQ; +"HULL_SUBSET",HULL_SUBSET; +"HULL_UNION",HULL_UNION; +"HULL_UNION_LEFT",HULL_UNION_LEFT; +"HULL_UNION_RIGHT",HULL_UNION_RIGHT; +"HULL_UNION_SUBSET",HULL_UNION_SUBSET; +"HULL_UNIQUE",HULL_UNIQUE; +"HURWITZ_INJECTIVE",HURWITZ_INJECTIVE; +"HURWITZ_NO_ZEROS",HURWITZ_NO_ZEROS; +"HYPERPLANE_EQ_EMPTY",HYPERPLANE_EQ_EMPTY; +"HYPERPLANE_EQ_UNIV",HYPERPLANE_EQ_UNIV; +"HYPERPLANE_FACET_OF_HALFSPACE_GE",HYPERPLANE_FACET_OF_HALFSPACE_GE; +"HYPERPLANE_FACET_OF_HALFSPACE_LE",HYPERPLANE_FACET_OF_HALFSPACE_LE; +"HYPERPLANE_FACE_OF_HALFSPACE_GE",HYPERPLANE_FACE_OF_HALFSPACE_GE; +"HYPERPLANE_FACE_OF_HALFSPACE_LE",HYPERPLANE_FACE_OF_HALFSPACE_LE; +"IDEMPOTENT_IMP_RETRACTION",IDEMPOTENT_IMP_RETRACTION; +"II_NZ",II_NZ; +"IM",IM; +"IMAGE",IMAGE; +"IMAGE_AFFINITY_INTERVAL",IMAGE_AFFINITY_INTERVAL; +"IMAGE_AFFINITY_REAL_INTERVAL",IMAGE_AFFINITY_REAL_INTERVAL; +"IMAGE_CLAUSES",IMAGE_CLAUSES; +"IMAGE_CLOSURE_SUBSET",IMAGE_CLOSURE_SUBSET; +"IMAGE_COMPOSE_PERMUTATIONS_L",IMAGE_COMPOSE_PERMUTATIONS_L; +"IMAGE_COMPOSE_PERMUTATIONS_R",IMAGE_COMPOSE_PERMUTATIONS_R; +"IMAGE_CONST",IMAGE_CONST; +"IMAGE_CX",IMAGE_CX; +"IMAGE_DELETE_INJ",IMAGE_DELETE_INJ; +"IMAGE_DIFF_INJ",IMAGE_DIFF_INJ; +"IMAGE_DROPOUT_CLOSED_INTERVAL",IMAGE_DROPOUT_CLOSED_INTERVAL; +"IMAGE_DROP_INTERVAL",IMAGE_DROP_INTERVAL; +"IMAGE_DROP_UNIV",IMAGE_DROP_UNIV; +"IMAGE_EQ_EMPTY",IMAGE_EQ_EMPTY; +"IMAGE_FSTCART_PCROSS",IMAGE_FSTCART_PCROSS; +"IMAGE_I",IMAGE_I; +"IMAGE_ID",IMAGE_ID; +"IMAGE_IMP_INJECTIVE",IMAGE_IMP_INJECTIVE; +"IMAGE_IMP_INJECTIVE_GEN",IMAGE_IMP_INJECTIVE_GEN; +"IMAGE_INJECTIVE_IMAGE_OF_SUBSET",IMAGE_INJECTIVE_IMAGE_OF_SUBSET; +"IMAGE_INTER_INJ",IMAGE_INTER_INJ; +"IMAGE_INVERSE_PERMUTATIONS",IMAGE_INVERSE_PERMUTATIONS; +"IMAGE_LEMMA_0",IMAGE_LEMMA_0; +"IMAGE_LEMMA_1",IMAGE_LEMMA_1; +"IMAGE_LEMMA_2",IMAGE_LEMMA_2; +"IMAGE_LIFT_DROP",IMAGE_LIFT_DROP; +"IMAGE_LIFT_REAL_INTERVAL",IMAGE_LIFT_REAL_INTERVAL; +"IMAGE_LIFT_REAL_SEGMENT",IMAGE_LIFT_REAL_SEGMENT; +"IMAGE_LIFT_UNIV",IMAGE_LIFT_UNIV; +"IMAGE_SNDCART_PCROSS",IMAGE_SNDCART_PCROSS; +"IMAGE_STRETCH_INTERVAL",IMAGE_STRETCH_INTERVAL; +"IMAGE_STRETCH_REAL_INTERVAL",IMAGE_STRETCH_REAL_INTERVAL; +"IMAGE_SUBSET",IMAGE_SUBSET; +"IMAGE_UNION",IMAGE_UNION; +"IMAGE_UNIONS",IMAGE_UNIONS; +"IMAGE_o",IMAGE_o; +"IMP_CLAUSES",IMP_CLAUSES; +"IMP_CONJ",IMP_CONJ; +"IMP_CONJ_ALT",IMP_CONJ_ALT; +"IMP_DEF",IMP_DEF; +"IMP_IMP",IMP_IMP; +"IM_ADD",IM_ADD; +"IM_CCOS",IM_CCOS; +"IM_CEXP",IM_CEXP; +"IM_CLOG_EQ_0",IM_CLOG_EQ_0; +"IM_CLOG_EQ_PI",IM_CLOG_EQ_PI; +"IM_CLOG_POS_LE",IM_CLOG_POS_LE; +"IM_CLOG_POS_LT",IM_CLOG_POS_LT; +"IM_CLOG_POS_LT_IMP",IM_CLOG_POS_LT_IMP; +"IM_CMUL",IM_CMUL; +"IM_CNJ",IM_CNJ; +"IM_COMPLEX_DIV_EQ_0",IM_COMPLEX_DIV_EQ_0; +"IM_COMPLEX_DIV_GE_0",IM_COMPLEX_DIV_GE_0; +"IM_COMPLEX_DIV_GT_0",IM_COMPLEX_DIV_GT_0; +"IM_COMPLEX_DIV_LEMMA",IM_COMPLEX_DIV_LEMMA; +"IM_COMPLEX_DIV_LE_0",IM_COMPLEX_DIV_LE_0; +"IM_COMPLEX_DIV_LT_0",IM_COMPLEX_DIV_LT_0; +"IM_COMPLEX_INV_EQ_0",IM_COMPLEX_INV_EQ_0; +"IM_COMPLEX_INV_GE_0",IM_COMPLEX_INV_GE_0; +"IM_COMPLEX_INV_GT_0",IM_COMPLEX_INV_GT_0; +"IM_COMPLEX_INV_LE_0",IM_COMPLEX_INV_LE_0; +"IM_COMPLEX_INV_LT_0",IM_COMPLEX_INV_LT_0; +"IM_CSIN",IM_CSIN; +"IM_CX",IM_CX; +"IM_DEF",IM_DEF; +"IM_DIV_CX",IM_DIV_CX; +"IM_II",IM_II; +"IM_LINEPATH_CX",IM_LINEPATH_CX; +"IM_MUL_CX",IM_MUL_CX; +"IM_MUL_II",IM_MUL_II; +"IM_NEG",IM_NEG; +"IM_POW_2",IM_POW_2; +"IM_SUB",IM_SUB; +"IM_VSUM",IM_VSUM; +"IN",IN; +"INCREASING_BOUNDED_REAL_VARIATION",INCREASING_BOUNDED_REAL_VARIATION; +"INCREASING_BOUNDED_VARIATION",INCREASING_BOUNDED_VARIATION; +"INCREASING_LEFT_LIMIT",INCREASING_LEFT_LIMIT; +"INCREASING_LEFT_LIMIT_1",INCREASING_LEFT_LIMIT_1; +"INCREASING_REAL_VARIATION",INCREASING_REAL_VARIATION; +"INCREASING_RIGHT_LIMIT",INCREASING_RIGHT_LIMIT; +"INCREASING_RIGHT_LIMIT_1",INCREASING_RIGHT_LIMIT_1; +"INCREASING_VECTOR_VARIATION",INCREASING_VECTOR_VARIATION; +"INDEFINITE_INTEGRAL_CONTINUOUS",INDEFINITE_INTEGRAL_CONTINUOUS; +"INDEFINITE_INTEGRAL_CONTINUOUS_LEFT",INDEFINITE_INTEGRAL_CONTINUOUS_LEFT; +"INDEFINITE_INTEGRAL_CONTINUOUS_RIGHT",INDEFINITE_INTEGRAL_CONTINUOUS_RIGHT; +"INDEFINITE_INTEGRAL_UNIFORMLY_CONTINUOUS",INDEFINITE_INTEGRAL_UNIFORMLY_CONTINUOUS; +"INDEFINITE_INTEGRAL_UNIFORMLY_CONTINUOUS_EXPLICIT",INDEFINITE_INTEGRAL_UNIFORMLY_CONTINUOUS_EXPLICIT; +"INDEPENDENT_2",INDEPENDENT_2; +"INDEPENDENT_3",INDEPENDENT_3; +"INDEPENDENT_BOUND",INDEPENDENT_BOUND; +"INDEPENDENT_BOUND_GENERAL",INDEPENDENT_BOUND_GENERAL; +"INDEPENDENT_CARD_LE_DIM",INDEPENDENT_CARD_LE_DIM; +"INDEPENDENT_EMPTY",INDEPENDENT_EMPTY; +"INDEPENDENT_EXPLICIT",INDEPENDENT_EXPLICIT; +"INDEPENDENT_IMP_AFFINE_DEPENDENT_0",INDEPENDENT_IMP_AFFINE_DEPENDENT_0; +"INDEPENDENT_IMP_FINITE",INDEPENDENT_IMP_FINITE; +"INDEPENDENT_INJECTIVE_IMAGE",INDEPENDENT_INJECTIVE_IMAGE; +"INDEPENDENT_INJECTIVE_IMAGE_GEN",INDEPENDENT_INJECTIVE_IMAGE_GEN; +"INDEPENDENT_INSERT",INDEPENDENT_INSERT; +"INDEPENDENT_LINEAR_IMAGE_EQ",INDEPENDENT_LINEAR_IMAGE_EQ; +"INDEPENDENT_MONO",INDEPENDENT_MONO; +"INDEPENDENT_NONZERO",INDEPENDENT_NONZERO; +"INDEPENDENT_SING",INDEPENDENT_SING; +"INDEPENDENT_SPAN_BOUND",INDEPENDENT_SPAN_BOUND; +"INDEPENDENT_STDBASIS",INDEPENDENT_STDBASIS; +"INDUCT_LINEAR_ELEMENTARY",INDUCT_LINEAR_ELEMENTARY; +"INDUCT_MATRIX_ELEMENTARY",INDUCT_MATRIX_ELEMENTARY; +"INDUCT_MATRIX_ELEMENTARY_ALT",INDUCT_MATRIX_ELEMENTARY_ALT; +"INDUCT_MATRIX_ROW_OPERATIONS",INDUCT_MATRIX_ROW_OPERATIONS; +"IND_SUC_0",IND_SUC_0; +"IND_SUC_0_EXISTS",IND_SUC_0_EXISTS; +"IND_SUC_INJ",IND_SUC_INJ; +"IND_SUC_SPEC",IND_SUC_SPEC; +"INESSENTIAL_EQ_CONTINUOUS_LOGARITHM",INESSENTIAL_EQ_CONTINUOUS_LOGARITHM; +"INESSENTIAL_EQ_CONTINUOUS_LOGARITHM_CIRCLE",INESSENTIAL_EQ_CONTINUOUS_LOGARITHM_CIRCLE; +"INESSENTIAL_EQ_EXTENSIBLE",INESSENTIAL_EQ_EXTENSIBLE; +"INESSENTIAL_IMP_CONTINUOUS_LOGARITHM_CIRCLE",INESSENTIAL_IMP_CONTINUOUS_LOGARITHM_CIRCLE; +"INESSENTIAL_IMP_UNICOHERENT",INESSENTIAL_IMP_UNICOHERENT; +"INESSENTIAL_SPHEREMAP_2",INESSENTIAL_SPHEREMAP_2; +"INESSENTIAL_SPHEREMAP_LOWDIM",INESSENTIAL_SPHEREMAP_LOWDIM; +"INESSENTIAL_SPHEREMAP_LOWDIM_GEN",INESSENTIAL_SPHEREMAP_LOWDIM_GEN; +"INF",INF; +"INFINITE",INFINITE; +"INFINITE_ARC_IMAGE",INFINITE_ARC_IMAGE; +"INFINITE_CARD_LE",INFINITE_CARD_LE; +"INFINITE_DIFF_FINITE",INFINITE_DIFF_FINITE; +"INFINITE_ENUMERATE",INFINITE_ENUMERATE; +"INFINITE_FROM",INFINITE_FROM; +"INFINITE_IMAGE_INJ",INFINITE_IMAGE_INJ; +"INFINITE_INTEGER",INFINITE_INTEGER; +"INFINITE_NONEMPTY",INFINITE_NONEMPTY; +"INFINITE_OPEN_IN",INFINITE_OPEN_IN; +"INFINITE_RATIONAL",INFINITE_RATIONAL; +"INFINITE_SIMPLE_PATH_IMAGE",INFINITE_SIMPLE_PATH_IMAGE; +"INFINITE_SUPERSET",INFINITE_SUPERSET; +"INFINITY_AX",INFINITY_AX; +"INFNORM_0",INFNORM_0; +"INFNORM_2",INFNORM_2; +"INFNORM_EQ_0",INFNORM_EQ_0; +"INFNORM_EQ_1_2",INFNORM_EQ_1_2; +"INFNORM_EQ_1_IMP",INFNORM_EQ_1_IMP; +"INFNORM_LE_NORM",INFNORM_LE_NORM; +"INFNORM_MUL",INFNORM_MUL; +"INFNORM_MUL_LEMMA",INFNORM_MUL_LEMMA; +"INFNORM_NEG",INFNORM_NEG; +"INFNORM_POS_LE",INFNORM_POS_LE; +"INFNORM_POS_LT",INFNORM_POS_LT; +"INFNORM_SET_IMAGE",INFNORM_SET_IMAGE; +"INFNORM_SET_LEMMA",INFNORM_SET_LEMMA; +"INFNORM_SUB",INFNORM_SUB; +"INFNORM_TRIANGLE",INFNORM_TRIANGLE; +"INFSUM_0",INFSUM_0; +"INFSUM_ADD",INFSUM_ADD; +"INFSUM_CMUL",INFSUM_CMUL; +"INFSUM_EQ",INFSUM_EQ; +"INFSUM_LINEAR",INFSUM_LINEAR; +"INFSUM_NEG",INFSUM_NEG; +"INFSUM_RESTRICT",INFSUM_RESTRICT; +"INFSUM_SUB",INFSUM_SUB; +"INFSUM_UNIQUE",INFSUM_UNIQUE; +"INF_EQ",INF_EQ; +"INF_FINITE",INF_FINITE; +"INF_FINITE_LEMMA",INF_FINITE_LEMMA; +"INF_INSERT",INF_INSERT; +"INF_INSERT_FINITE",INF_INSERT_FINITE; +"INF_SING",INF_SING; +"INF_UNIQUE_FINITE",INF_UNIQUE_FINITE; +"INJ",INJ; +"INJA",INJA; +"INJA_INJ",INJA_INJ; +"INJECTIVE_ALT",INJECTIVE_ALT; +"INJECTIVE_EQ_1D_OPEN_MAP_UNIV",INJECTIVE_EQ_1D_OPEN_MAP_UNIV; +"INJECTIVE_IMAGE",INJECTIVE_IMAGE; +"INJECTIVE_IMP_ISOMETRIC",INJECTIVE_IMP_ISOMETRIC; +"INJECTIVE_INTO_1D_EQ_HOMEOMORPHISM",INJECTIVE_INTO_1D_EQ_HOMEOMORPHISM; +"INJECTIVE_INTO_1D_IMP_OPEN_MAP",INJECTIVE_INTO_1D_IMP_OPEN_MAP; +"INJECTIVE_INTO_1D_IMP_OPEN_MAP_UNIV",INJECTIVE_INTO_1D_IMP_OPEN_MAP_UNIV; +"INJECTIVE_INVERSE",INJECTIVE_INVERSE; +"INJECTIVE_INVERSE_o",INJECTIVE_INVERSE_o; +"INJECTIVE_LEFT_INVERSE",INJECTIVE_LEFT_INVERSE; +"INJECTIVE_LEFT_INVERSE_NONEMPTY",INJECTIVE_LEFT_INVERSE_NONEMPTY; +"INJECTIVE_MAP",INJECTIVE_MAP; +"INJECTIVE_MAP_OPEN_IFF_CLOSED",INJECTIVE_MAP_OPEN_IFF_CLOSED; +"INJECTIVE_ON_ALT",INJECTIVE_ON_ALT; +"INJECTIVE_ON_IMAGE",INJECTIVE_ON_IMAGE; +"INJECTIVE_ON_LEFT_INVERSE",INJECTIVE_ON_LEFT_INVERSE; +"INJECTIVE_SCALING",INJECTIVE_SCALING; +"INJF",INJF; +"INJF_INJ",INJF_INJ; +"INJN",INJN; +"INJN_INJ",INJN_INJ; +"INJP",INJP; +"INJP_INJ",INJP_INJ; +"INJ_INVERSE2",INJ_INVERSE2; +"INNER_LADD",INNER_LADD; +"INNER_LMUL",INNER_LMUL; +"INNER_LNEG",INNER_LNEG; +"INNER_LZERO",INNER_LZERO; +"INNER_RADD",INNER_RADD; +"INNER_RMUL",INNER_RMUL; +"INNER_RNEG",INNER_RNEG; +"INNER_RZERO",INNER_RZERO; +"INSEG_LINSEG",INSEG_LINSEG; +"INSEG_PROPER_SUBSET",INSEG_PROPER_SUBSET; +"INSEG_PROPER_SUBSET_FL",INSEG_PROPER_SUBSET_FL; +"INSEG_SUBSET",INSEG_SUBSET; +"INSEG_SUBSET_FL",INSEG_SUBSET_FL; +"INSEG_WOSET",INSEG_WOSET; +"INSERT",INSERT; +"INSERT_AC",INSERT_AC; +"INSERT_COMM",INSERT_COMM; +"INSERT_DEF",INSERT_DEF; +"INSERT_DELETE",INSERT_DELETE; +"INSERT_DIFF",INSERT_DIFF; +"INSERT_INSERT",INSERT_INSERT; +"INSERT_INTER",INSERT_INTER; +"INSERT_SUBSET",INSERT_SUBSET; +"INSERT_UNION",INSERT_UNION; +"INSERT_UNION_EQ",INSERT_UNION_EQ; +"INSERT_UNIV",INSERT_UNIV; +"INSIDE_ARC_EMPTY",INSIDE_ARC_EMPTY; +"INSIDE_BOUNDED_COMPLEMENT_CONNECTED_EMPTY",INSIDE_BOUNDED_COMPLEMENT_CONNECTED_EMPTY; +"INSIDE_COMPLEMENT_UNBOUNDED_CONNECTED_EMPTY",INSIDE_COMPLEMENT_UNBOUNDED_CONNECTED_EMPTY; +"INSIDE_CONNECTED_COMPONENT_LE",INSIDE_CONNECTED_COMPONENT_LE; +"INSIDE_CONNECTED_COMPONENT_LT",INSIDE_CONNECTED_COMPONENT_LT; +"INSIDE_CONVEX",INSIDE_CONVEX; +"INSIDE_EMPTY",INSIDE_EMPTY; +"INSIDE_EQ_OUTSIDE",INSIDE_EQ_OUTSIDE; +"INSIDE_FRONTIER_EQ_INTERIOR",INSIDE_FRONTIER_EQ_INTERIOR; +"INSIDE_INSIDE",INSIDE_INSIDE; +"INSIDE_INSIDE_COMPACT_CONNECTED",INSIDE_INSIDE_COMPACT_CONNECTED; +"INSIDE_INSIDE_EQ_EMPTY",INSIDE_INSIDE_EQ_EMPTY; +"INSIDE_INSIDE_SUBSET",INSIDE_INSIDE_SUBSET; +"INSIDE_INTER_OUTSIDE",INSIDE_INTER_OUTSIDE; +"INSIDE_IN_COMPONENTS",INSIDE_IN_COMPONENTS; +"INSIDE_LINEAR_IMAGE",INSIDE_LINEAR_IMAGE; +"INSIDE_MONO",INSIDE_MONO; +"INSIDE_NO_OVERLAP",INSIDE_NO_OVERLAP; +"INSIDE_OF_TRIANGLE",INSIDE_OF_TRIANGLE; +"INSIDE_OUTSIDE",INSIDE_OUTSIDE; +"INSIDE_OUTSIDE_INTERSECT_CONNECTED",INSIDE_OUTSIDE_INTERSECT_CONNECTED; +"INSIDE_OUTSIDE_UNIQUE",INSIDE_OUTSIDE_UNIQUE; +"INSIDE_SAME_COMPONENT",INSIDE_SAME_COMPONENT; +"INSIDE_SIMPLE_CURVE_IMP_CLOSED",INSIDE_SIMPLE_CURVE_IMP_CLOSED; +"INSIDE_SUBSET",INSIDE_SUBSET; +"INSIDE_TRANSLATION",INSIDE_TRANSLATION; +"INSIDE_UNION_OUTSIDE",INSIDE_UNION_OUTSIDE; +"INSIDE_UNIQUE",INSIDE_UNIQUE; +"INTEGER_ABS",INTEGER_ABS; +"INTEGER_ABS_MUL_EQ_1",INTEGER_ABS_MUL_EQ_1; +"INTEGER_ADD",INTEGER_ADD; +"INTEGER_ADD_EQ",INTEGER_ADD_EQ; +"INTEGER_CASES",INTEGER_CASES; +"INTEGER_CLOSED",INTEGER_CLOSED; +"INTEGER_DET",INTEGER_DET; +"INTEGER_EXISTS_BETWEEN",INTEGER_EXISTS_BETWEEN; +"INTEGER_EXISTS_BETWEEN_ABS",INTEGER_EXISTS_BETWEEN_ABS; +"INTEGER_EXISTS_BETWEEN_ABS_LT",INTEGER_EXISTS_BETWEEN_ABS_LT; +"INTEGER_EXISTS_BETWEEN_ALT",INTEGER_EXISTS_BETWEEN_ALT; +"INTEGER_EXISTS_BETWEEN_LT",INTEGER_EXISTS_BETWEEN_LT; +"INTEGER_MUL",INTEGER_MUL; +"INTEGER_NEG",INTEGER_NEG; +"INTEGER_POS",INTEGER_POS; +"INTEGER_POW",INTEGER_POW; +"INTEGER_PRODUCT",INTEGER_PRODUCT; +"INTEGER_ROUND",INTEGER_ROUND; +"INTEGER_SIGN",INTEGER_SIGN; +"INTEGER_SUB",INTEGER_SUB; +"INTEGER_SUB_EQ",INTEGER_SUB_EQ; +"INTEGER_SUM",INTEGER_SUM; +"INTEGER_WINDING_NUMBER",INTEGER_WINDING_NUMBER; +"INTEGER_WINDING_NUMBER_EQ",INTEGER_WINDING_NUMBER_EQ; +"INTEGRABLE_0",INTEGRABLE_0; +"INTEGRABLE_ADD",INTEGRABLE_ADD; +"INTEGRABLE_AFFINITY",INTEGRABLE_AFFINITY; +"INTEGRABLE_ALT",INTEGRABLE_ALT; +"INTEGRABLE_ALT_SUBSET",INTEGRABLE_ALT_SUBSET; +"INTEGRABLE_CAUCHY",INTEGRABLE_CAUCHY; +"INTEGRABLE_CCONTINUOUS_EXPLICIT",INTEGRABLE_CCONTINUOUS_EXPLICIT; +"INTEGRABLE_CCONTINUOUS_EXPLICIT_SYMMETRIC",INTEGRABLE_CCONTINUOUS_EXPLICIT_SYMMETRIC; +"INTEGRABLE_CMUL",INTEGRABLE_CMUL; +"INTEGRABLE_COMBINE",INTEGRABLE_COMBINE; +"INTEGRABLE_COMBINE_DIVISION",INTEGRABLE_COMBINE_DIVISION; +"INTEGRABLE_COMPONENTWISE",INTEGRABLE_COMPONENTWISE; +"INTEGRABLE_CONST",INTEGRABLE_CONST; +"INTEGRABLE_CONTINUOUS",INTEGRABLE_CONTINUOUS; +"INTEGRABLE_DECREASING",INTEGRABLE_DECREASING; +"INTEGRABLE_DECREASING_1",INTEGRABLE_DECREASING_1; +"INTEGRABLE_DECREASING_PRODUCT",INTEGRABLE_DECREASING_PRODUCT; +"INTEGRABLE_DECREASING_PRODUCT_UNIV",INTEGRABLE_DECREASING_PRODUCT_UNIV; +"INTEGRABLE_EQ",INTEGRABLE_EQ; +"INTEGRABLE_IMP_MEASURABLE",INTEGRABLE_IMP_MEASURABLE; +"INTEGRABLE_IMP_REAL_MEASURABLE",INTEGRABLE_IMP_REAL_MEASURABLE; +"INTEGRABLE_INCREASING",INTEGRABLE_INCREASING; +"INTEGRABLE_INCREASING_1",INTEGRABLE_INCREASING_1; +"INTEGRABLE_INCREASING_PRODUCT",INTEGRABLE_INCREASING_PRODUCT; +"INTEGRABLE_INCREASING_PRODUCT_UNIV",INTEGRABLE_INCREASING_PRODUCT_UNIV; +"INTEGRABLE_INTEGRAL",INTEGRABLE_INTEGRAL; +"INTEGRABLE_LINEAR",INTEGRABLE_LINEAR; +"INTEGRABLE_MIN_CONST_1",INTEGRABLE_MIN_CONST_1; +"INTEGRABLE_NEG",INTEGRABLE_NEG; +"INTEGRABLE_ON_ALL_INTERVALS_INTEGRABLE_BOUND",INTEGRABLE_ON_ALL_INTERVALS_INTEGRABLE_BOUND; +"INTEGRABLE_ON_CONST",INTEGRABLE_ON_CONST; +"INTEGRABLE_ON_EMPTY",INTEGRABLE_ON_EMPTY; +"INTEGRABLE_ON_LITTLE_SUBINTERVALS",INTEGRABLE_ON_LITTLE_SUBINTERVALS; +"INTEGRABLE_ON_NULL",INTEGRABLE_ON_NULL; +"INTEGRABLE_ON_OPEN_INTERVAL",INTEGRABLE_ON_OPEN_INTERVAL; +"INTEGRABLE_ON_REFL",INTEGRABLE_ON_REFL; +"INTEGRABLE_ON_SUBDIVISION",INTEGRABLE_ON_SUBDIVISION; +"INTEGRABLE_ON_SUBINTERVAL",INTEGRABLE_ON_SUBINTERVAL; +"INTEGRABLE_ON_SUPERSET",INTEGRABLE_ON_SUPERSET; +"INTEGRABLE_REFLECT",INTEGRABLE_REFLECT; +"INTEGRABLE_RESTRICT",INTEGRABLE_RESTRICT; +"INTEGRABLE_RESTRICT_INTER",INTEGRABLE_RESTRICT_INTER; +"INTEGRABLE_RESTRICT_UNIV",INTEGRABLE_RESTRICT_UNIV; +"INTEGRABLE_SPIKE",INTEGRABLE_SPIKE; +"INTEGRABLE_SPIKE_FINITE",INTEGRABLE_SPIKE_FINITE; +"INTEGRABLE_SPIKE_INTERIOR",INTEGRABLE_SPIKE_INTERIOR; +"INTEGRABLE_SPIKE_SET",INTEGRABLE_SPIKE_SET; +"INTEGRABLE_SPIKE_SET_EQ",INTEGRABLE_SPIKE_SET_EQ; +"INTEGRABLE_SPLIT",INTEGRABLE_SPLIT; +"INTEGRABLE_STRADDLE",INTEGRABLE_STRADDLE; +"INTEGRABLE_STRADDLE_INTERVAL",INTEGRABLE_STRADDLE_INTERVAL; +"INTEGRABLE_STRETCH",INTEGRABLE_STRETCH; +"INTEGRABLE_SUB",INTEGRABLE_SUB; +"INTEGRABLE_SUBINTERVAL",INTEGRABLE_SUBINTERVAL; +"INTEGRABLE_SUBINTERVALS_IMP_MEASURABLE",INTEGRABLE_SUBINTERVALS_IMP_MEASURABLE; +"INTEGRABLE_SUBINTERVALS_IMP_REAL_MEASURABLE",INTEGRABLE_SUBINTERVALS_IMP_REAL_MEASURABLE; +"INTEGRABLE_UNIFORM_LIMIT",INTEGRABLE_UNIFORM_LIMIT; +"INTEGRABLE_VSUM",INTEGRABLE_VSUM; +"INTEGRAL_0",INTEGRAL_0; +"INTEGRAL_ADD",INTEGRAL_ADD; +"INTEGRAL_CMUL",INTEGRAL_CMUL; +"INTEGRAL_COMBINE",INTEGRAL_COMBINE; +"INTEGRAL_COMBINE_DIVISION_BOTTOMUP",INTEGRAL_COMBINE_DIVISION_BOTTOMUP; +"INTEGRAL_COMBINE_DIVISION_TOPDOWN",INTEGRAL_COMBINE_DIVISION_TOPDOWN; +"INTEGRAL_COMBINE_TAGGED_DIVISION_BOTTOMUP",INTEGRAL_COMBINE_TAGGED_DIVISION_BOTTOMUP; +"INTEGRAL_COMBINE_TAGGED_DIVISION_TOPDOWN",INTEGRAL_COMBINE_TAGGED_DIVISION_TOPDOWN; +"INTEGRAL_COMPONENT",INTEGRAL_COMPONENT; +"INTEGRAL_COMPONENT_LBOUND",INTEGRAL_COMPONENT_LBOUND; +"INTEGRAL_COMPONENT_LE",INTEGRAL_COMPONENT_LE; +"INTEGRAL_COMPONENT_POS",INTEGRAL_COMPONENT_POS; +"INTEGRAL_COMPONENT_UBOUND",INTEGRAL_COMPONENT_UBOUND; +"INTEGRAL_CONST",INTEGRAL_CONST; +"INTEGRAL_DIFF",INTEGRAL_DIFF; +"INTEGRAL_DROP_LE",INTEGRAL_DROP_LE; +"INTEGRAL_DROP_LE_MEASURABLE",INTEGRAL_DROP_LE_MEASURABLE; +"INTEGRAL_DROP_POS",INTEGRAL_DROP_POS; +"INTEGRAL_EMPTY",INTEGRAL_EMPTY; +"INTEGRAL_EQ",INTEGRAL_EQ; +"INTEGRAL_EQ_0",INTEGRAL_EQ_0; +"INTEGRAL_EQ_HAS_INTEGRAL",INTEGRAL_EQ_HAS_INTEGRAL; +"INTEGRAL_HAS_VECTOR_DERIVATIVE",INTEGRAL_HAS_VECTOR_DERIVATIVE; +"INTEGRAL_INTERVALS_DIFF_INCLUSION_EXCLUSION",INTEGRAL_INTERVALS_DIFF_INCLUSION_EXCLUSION; +"INTEGRAL_INTERVALS_INCLUSION_EXCLUSION",INTEGRAL_INTERVALS_INCLUSION_EXCLUSION; +"INTEGRAL_INTERVALS_INCLUSION_EXCLUSION_LEFT",INTEGRAL_INTERVALS_INCLUSION_EXCLUSION_LEFT; +"INTEGRAL_INTERVALS_INCLUSION_EXCLUSION_RIGHT",INTEGRAL_INTERVALS_INCLUSION_EXCLUSION_RIGHT; +"INTEGRAL_LINEAR",INTEGRAL_LINEAR; +"INTEGRAL_MEASURE",INTEGRAL_MEASURE; +"INTEGRAL_MEASURE_UNIV",INTEGRAL_MEASURE_UNIV; +"INTEGRAL_NEG",INTEGRAL_NEG; +"INTEGRAL_NORM_BOUND_INTEGRAL",INTEGRAL_NORM_BOUND_INTEGRAL; +"INTEGRAL_NORM_BOUND_INTEGRAL_COMPONENT",INTEGRAL_NORM_BOUND_INTEGRAL_COMPONENT; +"INTEGRAL_NULL",INTEGRAL_NULL; +"INTEGRAL_OPEN_INTERVAL",INTEGRAL_OPEN_INTERVAL; +"INTEGRAL_PASTECART_CONST",INTEGRAL_PASTECART_CONST; +"INTEGRAL_PASTECART_CONTINUOUS",INTEGRAL_PASTECART_CONTINUOUS; +"INTEGRAL_REFL",INTEGRAL_REFL; +"INTEGRAL_REFLECT",INTEGRAL_REFLECT; +"INTEGRAL_RESTRICT",INTEGRAL_RESTRICT; +"INTEGRAL_RESTRICT_INTER",INTEGRAL_RESTRICT_INTER; +"INTEGRAL_RESTRICT_UNIV",INTEGRAL_RESTRICT_UNIV; +"INTEGRAL_SPIKE",INTEGRAL_SPIKE; +"INTEGRAL_SPIKE_SET",INTEGRAL_SPIKE_SET; +"INTEGRAL_SPLIT",INTEGRAL_SPLIT; +"INTEGRAL_SPLIT_SIGNED",INTEGRAL_SPLIT_SIGNED; +"INTEGRAL_SUB",INTEGRAL_SUB; +"INTEGRAL_SUBSET_COMPONENT_LE",INTEGRAL_SUBSET_COMPONENT_LE; +"INTEGRAL_SUBSET_DROP_LE",INTEGRAL_SUBSET_DROP_LE; +"INTEGRAL_SWAP_CONTINUOUS",INTEGRAL_SWAP_CONTINUOUS; +"INTEGRAL_UNION",INTEGRAL_UNION; +"INTEGRAL_UNIQUE",INTEGRAL_UNIQUE; +"INTEGRAL_VSUM",INTEGRAL_VSUM; +"INTER",INTER; +"INTERIOR_BIJECTIVE_LINEAR_IMAGE",INTERIOR_BIJECTIVE_LINEAR_IMAGE; +"INTERIOR_CBALL",INTERIOR_CBALL; +"INTERIOR_CLOSED_EQ_EMPTY_AS_FRONTIER",INTERIOR_CLOSED_EQ_EMPTY_AS_FRONTIER; +"INTERIOR_CLOSED_INTERVAL",INTERIOR_CLOSED_INTERVAL; +"INTERIOR_CLOSED_UNION_EMPTY_INTERIOR",INTERIOR_CLOSED_UNION_EMPTY_INTERIOR; +"INTERIOR_CLOSURE",INTERIOR_CLOSURE; +"INTERIOR_CLOSURE_IDEMP",INTERIOR_CLOSURE_IDEMP; +"INTERIOR_COMPLEMENT",INTERIOR_COMPLEMENT; +"INTERIOR_CONVEX_HULL_3",INTERIOR_CONVEX_HULL_3; +"INTERIOR_CONVEX_HULL_3_MINIMAL",INTERIOR_CONVEX_HULL_3_MINIMAL; +"INTERIOR_CONVEX_HULL_EQ_EMPTY",INTERIOR_CONVEX_HULL_EQ_EMPTY; +"INTERIOR_CONVEX_HULL_EXPLICIT",INTERIOR_CONVEX_HULL_EXPLICIT; +"INTERIOR_CONVEX_HULL_EXPLICIT_MINIMAL",INTERIOR_CONVEX_HULL_EXPLICIT_MINIMAL; +"INTERIOR_DIFF",INTERIOR_DIFF; +"INTERIOR_EMPTY",INTERIOR_EMPTY; +"INTERIOR_EQ",INTERIOR_EQ; +"INTERIOR_EQ_EMPTY",INTERIOR_EQ_EMPTY; +"INTERIOR_EQ_EMPTY_ALT",INTERIOR_EQ_EMPTY_ALT; +"INTERIOR_FINITE_INTERS",INTERIOR_FINITE_INTERS; +"INTERIOR_FRONTIER",INTERIOR_FRONTIER; +"INTERIOR_FRONTIER_EMPTY",INTERIOR_FRONTIER_EMPTY; +"INTERIOR_HALFSPACE_COMPONENT_GE",INTERIOR_HALFSPACE_COMPONENT_GE; +"INTERIOR_HALFSPACE_COMPONENT_LE",INTERIOR_HALFSPACE_COMPONENT_LE; +"INTERIOR_HALFSPACE_GE",INTERIOR_HALFSPACE_GE; +"INTERIOR_HALFSPACE_LE",INTERIOR_HALFSPACE_LE; +"INTERIOR_HYPERPLANE",INTERIOR_HYPERPLANE; +"INTERIOR_IMAGE_SUBSET",INTERIOR_IMAGE_SUBSET; +"INTERIOR_INJECTIVE_LINEAR_IMAGE",INTERIOR_INJECTIVE_LINEAR_IMAGE; +"INTERIOR_INSIDE_FRONTIER",INTERIOR_INSIDE_FRONTIER; +"INTERIOR_INTER",INTERIOR_INTER; +"INTERIOR_INTERIOR",INTERIOR_INTERIOR; +"INTERIOR_INTERS_SUBSET",INTERIOR_INTERS_SUBSET; +"INTERIOR_INTERVAL",INTERIOR_INTERVAL; +"INTERIOR_LIMIT_POINT",INTERIOR_LIMIT_POINT; +"INTERIOR_MAXIMAL",INTERIOR_MAXIMAL; +"INTERIOR_MAXIMAL_EQ",INTERIOR_MAXIMAL_EQ; +"INTERIOR_NEGATIONS",INTERIOR_NEGATIONS; +"INTERIOR_OF_TRIANGLE",INTERIOR_OF_TRIANGLE; +"INTERIOR_OPEN",INTERIOR_OPEN; +"INTERIOR_PCROSS",INTERIOR_PCROSS; +"INTERIOR_SEGMENT",INTERIOR_SEGMENT; +"INTERIOR_SIMPLEX_NONEMPTY",INTERIOR_SIMPLEX_NONEMPTY; +"INTERIOR_SING",INTERIOR_SING; +"INTERIOR_STANDARD_HYPERPLANE",INTERIOR_STANDARD_HYPERPLANE; +"INTERIOR_STD_SIMPLEX",INTERIOR_STD_SIMPLEX; +"INTERIOR_SUBSET",INTERIOR_SUBSET; +"INTERIOR_SUBSET_RELATIVE_INTERIOR",INTERIOR_SUBSET_RELATIVE_INTERIOR; +"INTERIOR_SUBSET_UNION_INTERVALS",INTERIOR_SUBSET_UNION_INTERVALS; +"INTERIOR_SURJECTIVE_LINEAR_IMAGE",INTERIOR_SURJECTIVE_LINEAR_IMAGE; +"INTERIOR_TRANSLATION",INTERIOR_TRANSLATION; +"INTERIOR_UNIONS_OPEN_SUBSETS",INTERIOR_UNIONS_OPEN_SUBSETS; +"INTERIOR_UNION_EQ_EMPTY",INTERIOR_UNION_EQ_EMPTY; +"INTERIOR_UNIQUE",INTERIOR_UNIQUE; +"INTERIOR_UNIV",INTERIOR_UNIV; +"INTERS",INTERS; +"INTERS_0",INTERS_0; +"INTERS_1",INTERS_1; +"INTERS_2",INTERS_2; +"INTERS_FACES_FINITE_ALTBOUND",INTERS_FACES_FINITE_ALTBOUND; +"INTERS_FACES_FINITE_BOUND",INTERS_FACES_FINITE_BOUND; +"INTERS_GSPEC",INTERS_GSPEC; +"INTERS_IMAGE",INTERS_IMAGE; +"INTERS_INSERT",INTERS_INSERT; +"INTERS_OVER_UNIONS",INTERS_OVER_UNIONS; +"INTERS_UNION",INTERS_UNION; +"INTERS_UNIONS",INTERS_UNIONS; +"INTERVAL_BIJ_AFFINE",INTERVAL_BIJ_AFFINE; +"INTERVAL_BIJ_BIJ",INTERVAL_BIJ_BIJ; +"INTERVAL_BISECTION",INTERVAL_BISECTION; +"INTERVAL_BISECTION_STEP",INTERVAL_BISECTION_STEP; +"INTERVAL_BOUNDS_EMPTY_1",INTERVAL_BOUNDS_EMPTY_1; +"INTERVAL_BOUNDS_NULL_1",INTERVAL_BOUNDS_NULL_1; +"INTERVAL_CASES_1",INTERVAL_CASES_1; +"INTERVAL_CONTAINS_COMPACT_NEIGHBOURHOOD",INTERVAL_CONTAINS_COMPACT_NEIGHBOURHOOD; +"INTERVAL_DOUBLESPLIT",INTERVAL_DOUBLESPLIT; +"INTERVAL_EQ_EMPTY",INTERVAL_EQ_EMPTY; +"INTERVAL_EQ_EMPTY_1",INTERVAL_EQ_EMPTY_1; +"INTERVAL_IMAGE_AFFINITY_INTERVAL",INTERVAL_IMAGE_AFFINITY_INTERVAL; +"INTERVAL_IMAGE_STRETCH_INTERVAL",INTERVAL_IMAGE_STRETCH_INTERVAL; +"INTERVAL_INTER_HYPERPLANE",INTERVAL_INTER_HYPERPLANE; +"INTERVAL_LOWERBOUND",INTERVAL_LOWERBOUND; +"INTERVAL_LOWERBOUND_1",INTERVAL_LOWERBOUND_1; +"INTERVAL_NE_EMPTY",INTERVAL_NE_EMPTY; +"INTERVAL_NE_EMPTY_1",INTERVAL_NE_EMPTY_1; +"INTERVAL_OPEN_SUBSET_CLOSED",INTERVAL_OPEN_SUBSET_CLOSED; +"INTERVAL_REAL_INTERVAL",INTERVAL_REAL_INTERVAL; +"INTERVAL_SING",INTERVAL_SING; +"INTERVAL_SPLIT",INTERVAL_SPLIT; +"INTERVAL_SUBDIVISION",INTERVAL_SUBDIVISION; +"INTERVAL_SUBSET_IS_INTERVAL",INTERVAL_SUBSET_IS_INTERVAL; +"INTERVAL_TRANSLATION",INTERVAL_TRANSLATION; +"INTERVAL_UPPERBOUND",INTERVAL_UPPERBOUND; +"INTERVAL_UPPERBOUND_1",INTERVAL_UPPERBOUND_1; +"INTER_ACI",INTER_ACI; +"INTER_ASSOC",INTER_ASSOC; +"INTER_COMM",INTER_COMM; +"INTER_EMPTY",INTER_EMPTY; +"INTER_IDEMPOT",INTER_IDEMPOT; +"INTER_INTERIOR_UNIONS_INTERVALS",INTER_INTERIOR_UNIONS_INTERVALS; +"INTER_INTERVAL",INTER_INTERVAL; +"INTER_INTERVAL_1",INTER_INTERVAL_1; +"INTER_INTERVAL_MIXED_EQ_EMPTY",INTER_INTERVAL_MIXED_EQ_EMPTY; +"INTER_OVER_UNION",INTER_OVER_UNION; +"INTER_SEGMENT",INTER_SEGMENT; +"INTER_SUBSET",INTER_SUBSET; +"INTER_UNIONS",INTER_UNIONS; +"INTER_UNIV",INTER_UNIV; +"INT_ABS",INT_ABS; +"INT_ABS_0",INT_ABS_0; +"INT_ABS_1",INT_ABS_1; +"INT_ABS_ABS",INT_ABS_ABS; +"INT_ABS_BETWEEN",INT_ABS_BETWEEN; +"INT_ABS_BETWEEN1",INT_ABS_BETWEEN1; +"INT_ABS_BETWEEN2",INT_ABS_BETWEEN2; +"INT_ABS_BOUND",INT_ABS_BOUND; +"INT_ABS_CASES",INT_ABS_CASES; +"INT_ABS_CIRCLE",INT_ABS_CIRCLE; +"INT_ABS_LE",INT_ABS_LE; +"INT_ABS_MUL",INT_ABS_MUL; +"INT_ABS_MUL_1",INT_ABS_MUL_1; +"INT_ABS_NEG",INT_ABS_NEG; +"INT_ABS_NUM",INT_ABS_NUM; +"INT_ABS_NZ",INT_ABS_NZ; +"INT_ABS_POS",INT_ABS_POS; +"INT_ABS_POW",INT_ABS_POW; +"INT_ABS_REFL",INT_ABS_REFL; +"INT_ABS_SGN",INT_ABS_SGN; +"INT_ABS_SIGN",INT_ABS_SIGN; +"INT_ABS_SIGN2",INT_ABS_SIGN2; +"INT_ABS_STILLNZ",INT_ABS_STILLNZ; +"INT_ABS_SUB",INT_ABS_SUB; +"INT_ABS_SUB_ABS",INT_ABS_SUB_ABS; +"INT_ABS_TRIANGLE",INT_ABS_TRIANGLE; +"INT_ABS_ZERO",INT_ABS_ZERO; +"INT_ADD2_SUB2",INT_ADD2_SUB2; +"INT_ADD_AC",INT_ADD_AC; +"INT_ADD_ASSOC",INT_ADD_ASSOC; +"INT_ADD_LDISTRIB",INT_ADD_LDISTRIB; +"INT_ADD_LID",INT_ADD_LID; +"INT_ADD_LINV",INT_ADD_LINV; +"INT_ADD_RDISTRIB",INT_ADD_RDISTRIB; +"INT_ADD_RID",INT_ADD_RID; +"INT_ADD_RINV",INT_ADD_RINV; +"INT_ADD_SUB",INT_ADD_SUB; +"INT_ADD_SUB2",INT_ADD_SUB2; +"INT_ADD_SYM",INT_ADD_SYM; +"INT_ARCH",INT_ARCH; +"INT_BOUNDS_LE",INT_BOUNDS_LE; +"INT_BOUNDS_LT",INT_BOUNDS_LT; +"INT_DIFFSQ",INT_DIFFSQ; +"INT_DIVISION",INT_DIVISION; +"INT_DIVISION_0",INT_DIVISION_0; +"INT_DIVMOD_EXIST_0",INT_DIVMOD_EXIST_0; +"INT_DIVMOD_UNIQ",INT_DIVMOD_UNIQ; +"INT_ENTIRE",INT_ENTIRE; +"INT_EQ_ADD_LCANCEL",INT_EQ_ADD_LCANCEL; +"INT_EQ_ADD_LCANCEL_0",INT_EQ_ADD_LCANCEL_0; +"INT_EQ_ADD_RCANCEL",INT_EQ_ADD_RCANCEL; +"INT_EQ_ADD_RCANCEL_0",INT_EQ_ADD_RCANCEL_0; +"INT_EQ_IMP_LE",INT_EQ_IMP_LE; +"INT_EQ_MUL_LCANCEL",INT_EQ_MUL_LCANCEL; +"INT_EQ_MUL_RCANCEL",INT_EQ_MUL_RCANCEL; +"INT_EQ_NEG2",INT_EQ_NEG2; +"INT_EQ_SQUARE_ABS",INT_EQ_SQUARE_ABS; +"INT_EQ_SUB_LADD",INT_EQ_SUB_LADD; +"INT_EQ_SUB_RADD",INT_EQ_SUB_RADD; +"INT_EXISTS_ABS",INT_EXISTS_ABS; +"INT_EXISTS_POS",INT_EXISTS_POS; +"INT_FORALL_ABS",INT_FORALL_ABS; +"INT_FORALL_POS",INT_FORALL_POS; +"INT_GCD_EXISTS",INT_GCD_EXISTS; +"INT_GCD_EXISTS_POS",INT_GCD_EXISTS_POS; +"INT_GE",INT_GE; +"INT_GT",INT_GT; +"INT_GT_DISCRETE",INT_GT_DISCRETE; +"INT_IMAGE",INT_IMAGE; +"INT_LET_ADD",INT_LET_ADD; +"INT_LET_ADD2",INT_LET_ADD2; +"INT_LET_ANTISYM",INT_LET_ANTISYM; +"INT_LET_TOTAL",INT_LET_TOTAL; +"INT_LET_TRANS",INT_LET_TRANS; +"INT_LE_01",INT_LE_01; +"INT_LE_ADD",INT_LE_ADD; +"INT_LE_ADD2",INT_LE_ADD2; +"INT_LE_ADDL",INT_LE_ADDL; +"INT_LE_ADDR",INT_LE_ADDR; +"INT_LE_ANTISYM",INT_LE_ANTISYM; +"INT_LE_DOUBLE",INT_LE_DOUBLE; +"INT_LE_LADD",INT_LE_LADD; +"INT_LE_LADD_IMP",INT_LE_LADD_IMP; +"INT_LE_LMUL",INT_LE_LMUL; +"INT_LE_LNEG",INT_LE_LNEG; +"INT_LE_LT",INT_LE_LT; +"INT_LE_MAX",INT_LE_MAX; +"INT_LE_MIN",INT_LE_MIN; +"INT_LE_MUL",INT_LE_MUL; +"INT_LE_MUL_EQ",INT_LE_MUL_EQ; +"INT_LE_NEG",INT_LE_NEG; +"INT_LE_NEG2",INT_LE_NEG2; +"INT_LE_NEGL",INT_LE_NEGL; +"INT_LE_NEGR",INT_LE_NEGR; +"INT_LE_NEGTOTAL",INT_LE_NEGTOTAL; +"INT_LE_POW2",INT_LE_POW2; +"INT_LE_RADD",INT_LE_RADD; +"INT_LE_REFL",INT_LE_REFL; +"INT_LE_RMUL",INT_LE_RMUL; +"INT_LE_RNEG",INT_LE_RNEG; +"INT_LE_SQUARE",INT_LE_SQUARE; +"INT_LE_SQUARE_ABS",INT_LE_SQUARE_ABS; +"INT_LE_SUB_LADD",INT_LE_SUB_LADD; +"INT_LE_SUB_RADD",INT_LE_SUB_RADD; +"INT_LE_TOTAL",INT_LE_TOTAL; +"INT_LE_TRANS",INT_LE_TRANS; +"INT_LNEG_UNIQ",INT_LNEG_UNIQ; +"INT_LT",INT_LT; +"INT_LTE_ADD",INT_LTE_ADD; +"INT_LTE_ADD2",INT_LTE_ADD2; +"INT_LTE_ANTISYM",INT_LTE_ANTISYM; +"INT_LTE_TOTAL",INT_LTE_TOTAL; +"INT_LTE_TRANS",INT_LTE_TRANS; +"INT_LT_01",INT_LT_01; +"INT_LT_ADD",INT_LT_ADD; +"INT_LT_ADD1",INT_LT_ADD1; +"INT_LT_ADD2",INT_LT_ADD2; +"INT_LT_ADDL",INT_LT_ADDL; +"INT_LT_ADDNEG",INT_LT_ADDNEG; +"INT_LT_ADDNEG2",INT_LT_ADDNEG2; +"INT_LT_ADDR",INT_LT_ADDR; +"INT_LT_ADD_SUB",INT_LT_ADD_SUB; +"INT_LT_ANTISYM",INT_LT_ANTISYM; +"INT_LT_DISCRETE",INT_LT_DISCRETE; +"INT_LT_GT",INT_LT_GT; +"INT_LT_IMP_LE",INT_LT_IMP_LE; +"INT_LT_IMP_NE",INT_LT_IMP_NE; +"INT_LT_LADD",INT_LT_LADD; +"INT_LT_LE",INT_LT_LE; +"INT_LT_LMUL_EQ",INT_LT_LMUL_EQ; +"INT_LT_MAX",INT_LT_MAX; +"INT_LT_MIN",INT_LT_MIN; +"INT_LT_MUL",INT_LT_MUL; +"INT_LT_MUL_EQ",INT_LT_MUL_EQ; +"INT_LT_NEG",INT_LT_NEG; +"INT_LT_NEG2",INT_LT_NEG2; +"INT_LT_NEGTOTAL",INT_LT_NEGTOTAL; +"INT_LT_POW2",INT_LT_POW2; +"INT_LT_RADD",INT_LT_RADD; +"INT_LT_REFL",INT_LT_REFL; +"INT_LT_RMUL_EQ",INT_LT_RMUL_EQ; +"INT_LT_SQUARE_ABS",INT_LT_SQUARE_ABS; +"INT_LT_SUB_LADD",INT_LT_SUB_LADD; +"INT_LT_SUB_RADD",INT_LT_SUB_RADD; +"INT_LT_TOTAL",INT_LT_TOTAL; +"INT_LT_TRANS",INT_LT_TRANS; +"INT_MAX",INT_MAX; +"INT_MAX_ACI",INT_MAX_ACI; +"INT_MAX_ASSOC",INT_MAX_ASSOC; +"INT_MAX_LE",INT_MAX_LE; +"INT_MAX_LT",INT_MAX_LT; +"INT_MAX_MAX",INT_MAX_MAX; +"INT_MAX_MIN",INT_MAX_MIN; +"INT_MAX_SYM",INT_MAX_SYM; +"INT_MIN",INT_MIN; +"INT_MIN_ACI",INT_MIN_ACI; +"INT_MIN_ASSOC",INT_MIN_ASSOC; +"INT_MIN_LE",INT_MIN_LE; +"INT_MIN_LT",INT_MIN_LT; +"INT_MIN_MAX",INT_MIN_MAX; +"INT_MIN_MIN",INT_MIN_MIN; +"INT_MIN_SYM",INT_MIN_SYM; +"INT_MUL_AC",INT_MUL_AC; +"INT_MUL_ASSOC",INT_MUL_ASSOC; +"INT_MUL_LID",INT_MUL_LID; +"INT_MUL_LNEG",INT_MUL_LNEG; +"INT_MUL_LZERO",INT_MUL_LZERO; +"INT_MUL_POS_LE",INT_MUL_POS_LE; +"INT_MUL_POS_LT",INT_MUL_POS_LT; +"INT_MUL_RID",INT_MUL_RID; +"INT_MUL_RNEG",INT_MUL_RNEG; +"INT_MUL_RZERO",INT_MUL_RZERO; +"INT_MUL_SYM",INT_MUL_SYM; +"INT_NEGNEG",INT_NEGNEG; +"INT_NEG_0",INT_NEG_0; +"INT_NEG_ADD",INT_NEG_ADD; +"INT_NEG_EQ",INT_NEG_EQ; +"INT_NEG_EQ_0",INT_NEG_EQ_0; +"INT_NEG_GE0",INT_NEG_GE0; +"INT_NEG_GT0",INT_NEG_GT0; +"INT_NEG_LE0",INT_NEG_LE0; +"INT_NEG_LMUL",INT_NEG_LMUL; +"INT_NEG_LT0",INT_NEG_LT0; +"INT_NEG_MINUS1",INT_NEG_MINUS1; +"INT_NEG_MUL2",INT_NEG_MUL2; +"INT_NEG_NEG",INT_NEG_NEG; +"INT_NEG_RMUL",INT_NEG_RMUL; +"INT_NEG_SUB",INT_NEG_SUB; +"INT_NOT_EQ",INT_NOT_EQ; +"INT_NOT_LE",INT_NOT_LE; +"INT_NOT_LT",INT_NOT_LT; +"INT_OF_NUM_ADD",INT_OF_NUM_ADD; +"INT_OF_NUM_EQ",INT_OF_NUM_EQ; +"INT_OF_NUM_EXISTS",INT_OF_NUM_EXISTS; +"INT_OF_NUM_GE",INT_OF_NUM_GE; +"INT_OF_NUM_GT",INT_OF_NUM_GT; +"INT_OF_NUM_LE",INT_OF_NUM_LE; +"INT_OF_NUM_LT",INT_OF_NUM_LT; +"INT_OF_NUM_MAX",INT_OF_NUM_MAX; +"INT_OF_NUM_MIN",INT_OF_NUM_MIN; +"INT_OF_NUM_MUL",INT_OF_NUM_MUL; +"INT_OF_NUM_OF_INT",INT_OF_NUM_OF_INT; +"INT_OF_NUM_POW",INT_OF_NUM_POW; +"INT_OF_NUM_SUB",INT_OF_NUM_SUB; +"INT_OF_NUM_SUC",INT_OF_NUM_SUC; +"INT_OF_REAL_OF_INT",INT_OF_REAL_OF_INT; +"INT_POS",INT_POS; +"INT_POS_NZ",INT_POS_NZ; +"INT_POW",INT_POW; +"INT_POW2_ABS",INT_POW2_ABS; +"INT_POW_1",INT_POW_1; +"INT_POW_1_LE",INT_POW_1_LE; +"INT_POW_1_LT",INT_POW_1_LT; +"INT_POW_2",INT_POW_2; +"INT_POW_ADD",INT_POW_ADD; +"INT_POW_EQ",INT_POW_EQ; +"INT_POW_EQ_0",INT_POW_EQ_0; +"INT_POW_EQ_ABS",INT_POW_EQ_ABS; +"INT_POW_LE",INT_POW_LE; +"INT_POW_LE2",INT_POW_LE2; +"INT_POW_LE2_ODD",INT_POW_LE2_ODD; +"INT_POW_LE2_REV",INT_POW_LE2_REV; +"INT_POW_LE_1",INT_POW_LE_1; +"INT_POW_LT",INT_POW_LT; +"INT_POW_LT2",INT_POW_LT2; +"INT_POW_LT2_REV",INT_POW_LT2_REV; +"INT_POW_LT_1",INT_POW_LT_1; +"INT_POW_MONO",INT_POW_MONO; +"INT_POW_MONO_LT",INT_POW_MONO_LT; +"INT_POW_MUL",INT_POW_MUL; +"INT_POW_NEG",INT_POW_NEG; +"INT_POW_NZ",INT_POW_NZ; +"INT_POW_ONE",INT_POW_ONE; +"INT_POW_POW",INT_POW_POW; +"INT_POW_ZERO",INT_POW_ZERO; +"INT_RNEG_UNIQ",INT_RNEG_UNIQ; +"INT_SGN",INT_SGN; +"INT_SGN_0",INT_SGN_0; +"INT_SGN_ABS",INT_SGN_ABS; +"INT_SGN_CASES",INT_SGN_CASES; +"INT_SGN_EQ",INT_SGN_EQ; +"INT_SGN_INEQS",INT_SGN_INEQS; +"INT_SGN_MUL",INT_SGN_MUL; +"INT_SGN_NEG",INT_SGN_NEG; +"INT_SOS_EQ_0",INT_SOS_EQ_0; +"INT_SUB",INT_SUB; +"INT_SUB_0",INT_SUB_0; +"INT_SUB_ABS",INT_SUB_ABS; +"INT_SUB_ADD",INT_SUB_ADD; +"INT_SUB_ADD2",INT_SUB_ADD2; +"INT_SUB_LDISTRIB",INT_SUB_LDISTRIB; +"INT_SUB_LE",INT_SUB_LE; +"INT_SUB_LNEG",INT_SUB_LNEG; +"INT_SUB_LT",INT_SUB_LT; +"INT_SUB_LZERO",INT_SUB_LZERO; +"INT_SUB_NEG2",INT_SUB_NEG2; +"INT_SUB_RDISTRIB",INT_SUB_RDISTRIB; +"INT_SUB_REFL",INT_SUB_REFL; +"INT_SUB_RNEG",INT_SUB_RNEG; +"INT_SUB_RZERO",INT_SUB_RZERO; +"INT_SUB_SUB",INT_SUB_SUB; +"INT_SUB_SUB2",INT_SUB_SUB2; +"INT_SUB_TRIANGLE",INT_SUB_TRIANGLE; +"INT_WOP",INT_WOP; +"INVARIANCE_OF_DIMENSION",INVARIANCE_OF_DIMENSION; +"INVARIANCE_OF_DIMENSION_AFFINE_SETS",INVARIANCE_OF_DIMENSION_AFFINE_SETS; +"INVARIANCE_OF_DIMENSION_CONVEX_DOMAIN",INVARIANCE_OF_DIMENSION_CONVEX_DOMAIN; +"INVARIANCE_OF_DIMENSION_SUBSPACES",INVARIANCE_OF_DIMENSION_SUBSPACES; +"INVARIANCE_OF_DOMAIN",INVARIANCE_OF_DOMAIN; +"INVARIANCE_OF_DOMAIN_AFFINE_SETS",INVARIANCE_OF_DOMAIN_AFFINE_SETS; +"INVARIANCE_OF_DOMAIN_GEN",INVARIANCE_OF_DOMAIN_GEN; +"INVARIANCE_OF_DOMAIN_HOMEOMORPHIC",INVARIANCE_OF_DOMAIN_HOMEOMORPHIC; +"INVARIANCE_OF_DOMAIN_HOMEOMORPHISM",INVARIANCE_OF_DOMAIN_HOMEOMORPHISM; +"INVARIANCE_OF_DOMAIN_SPHERE_AFFINE_SET",INVARIANCE_OF_DOMAIN_SPHERE_AFFINE_SET; +"INVARIANCE_OF_DOMAIN_SPHERE_AFFINE_SET_GEN",INVARIANCE_OF_DOMAIN_SPHERE_AFFINE_SET_GEN; +"INVARIANCE_OF_DOMAIN_SUBSPACES",INVARIANCE_OF_DOMAIN_SUBSPACES; +"INVERSE_I",INVERSE_I; +"INVERSE_SWAP",INVERSE_SWAP; +"INVERSE_UNIQUE_o",INVERSE_UNIQUE_o; +"INVERTIBLE_COFACTOR",INVERTIBLE_COFACTOR; +"INVERTIBLE_DET_NZ",INVERTIBLE_DET_NZ; +"INVERTIBLE_FIXPOINT_PROPERTY",INVERTIBLE_FIXPOINT_PROPERTY; +"INVERTIBLE_IMP_SQUARE_MATRIX",INVERTIBLE_IMP_SQUARE_MATRIX; +"INVERTIBLE_LEFT_INVERSE",INVERTIBLE_LEFT_INVERSE; +"INVERTIBLE_MATRIX_MUL",INVERTIBLE_MATRIX_MUL; +"INVERTIBLE_NEG",INVERTIBLE_NEG; +"INVERTIBLE_RIGHT_INVERSE",INVERTIBLE_RIGHT_INVERSE; +"INVERTIBLE_TRANSP",INVERTIBLE_TRANSP; +"IN_AFFINE_ADD_MUL",IN_AFFINE_ADD_MUL; +"IN_AFFINE_ADD_MUL_DIFF",IN_AFFINE_ADD_MUL_DIFF; +"IN_AFFINE_HULL_LINEAR_IMAGE",IN_AFFINE_HULL_LINEAR_IMAGE; +"IN_AFFINE_MUL_DIFF_ADD",IN_AFFINE_MUL_DIFF_ADD; +"IN_AFFINE_SUB_MUL_DIFF",IN_AFFINE_SUB_MUL_DIFF; +"IN_BALL",IN_BALL; +"IN_BALL_0",IN_BALL_0; +"IN_BALL_IM",IN_BALL_IM; +"IN_BALL_RE",IN_BALL_RE; +"IN_CARD_ADD",IN_CARD_ADD; +"IN_CARD_MUL",IN_CARD_MUL; +"IN_CBALL",IN_CBALL; +"IN_CBALL_0",IN_CBALL_0; +"IN_CBALL_IM",IN_CBALL_IM; +"IN_CBALL_RE",IN_CBALL_RE; +"IN_CLOSURE_CONNECTED_COMPONENT",IN_CLOSURE_CONNECTED_COMPONENT; +"IN_CLOSURE_DELETE",IN_CLOSURE_DELETE; +"IN_COMPONENTS",IN_COMPONENTS; +"IN_COMPONENTS_CONNECTED",IN_COMPONENTS_CONNECTED; +"IN_COMPONENTS_MAXIMAL",IN_COMPONENTS_MAXIMAL; +"IN_COMPONENTS_NONEMPTY",IN_COMPONENTS_NONEMPTY; +"IN_COMPONENTS_SELF",IN_COMPONENTS_SELF; +"IN_COMPONENTS_SUBSET",IN_COMPONENTS_SUBSET; +"IN_CONVEX_HULL_EXCHANGE",IN_CONVEX_HULL_EXCHANGE; +"IN_CONVEX_HULL_EXCHANGE_UNIQUE",IN_CONVEX_HULL_EXCHANGE_UNIQUE; +"IN_CONVEX_HULL_LINEAR_IMAGE",IN_CONVEX_HULL_LINEAR_IMAGE; +"IN_CONVEX_SET",IN_CONVEX_SET; +"IN_CROSS",IN_CROSS; +"IN_DELETE",IN_DELETE; +"IN_DELETE_EQ",IN_DELETE_EQ; +"IN_DIFF",IN_DIFF; +"IN_DIMINDEX_SWAP",IN_DIMINDEX_SWAP; +"IN_DIRECTION",IN_DIRECTION; +"IN_DISJOINT",IN_DISJOINT; +"IN_ELIM_PAIR_THM",IN_ELIM_PAIR_THM; +"IN_ELIM_PASTECART_THM",IN_ELIM_PASTECART_THM; +"IN_ELIM_THM",IN_ELIM_THM; +"IN_EPIGRAPH",IN_EPIGRAPH; +"IN_FROM",IN_FROM; +"IN_FRONTIER_CONVEX_HULL",IN_FRONTIER_CONVEX_HULL; +"IN_IMAGE",IN_IMAGE; +"IN_IMAGE_DROPOUT",IN_IMAGE_DROPOUT; +"IN_IMAGE_LIFT_DROP",IN_IMAGE_LIFT_DROP; +"IN_INSERT",IN_INSERT; +"IN_INTER",IN_INTER; +"IN_INTERIOR",IN_INTERIOR; +"IN_INTERIOR_CBALL",IN_INTERIOR_CBALL; +"IN_INTERIOR_CLOSURE_CONVEX_SEGMENT",IN_INTERIOR_CLOSURE_CONVEX_SEGMENT; +"IN_INTERIOR_CLOSURE_CONVEX_SHRINK",IN_INTERIOR_CLOSURE_CONVEX_SHRINK; +"IN_INTERIOR_CONVEX_SHRINK",IN_INTERIOR_CONVEX_SHRINK; +"IN_INTERIOR_LINEAR_IMAGE",IN_INTERIOR_LINEAR_IMAGE; +"IN_INTERS",IN_INTERS; +"IN_INTERVAL",IN_INTERVAL; +"IN_INTERVAL_1",IN_INTERVAL_1; +"IN_INTERVAL_INTERVAL_BIJ",IN_INTERVAL_INTERVAL_BIJ; +"IN_INTERVAL_REFLECT",IN_INTERVAL_REFLECT; +"IN_NUMSEG",IN_NUMSEG; +"IN_NUMSEG_0",IN_NUMSEG_0; +"IN_OPEN_SEGMENT",IN_OPEN_SEGMENT; +"IN_OPEN_SEGMENT_ALT",IN_OPEN_SEGMENT_ALT; +"IN_PATH_IMAGE_PARTCIRCLEPATH",IN_PATH_IMAGE_PARTCIRCLEPATH; +"IN_REAL_INTERVAL",IN_REAL_INTERVAL; +"IN_REAL_INTERVAL_REFLECT",IN_REAL_INTERVAL_REFLECT; +"IN_RELATIVE_INTERIOR",IN_RELATIVE_INTERIOR; +"IN_RELATIVE_INTERIOR_CBALL",IN_RELATIVE_INTERIOR_CBALL; +"IN_RELATIVE_INTERIOR_CLOSURE_CONVEX_SEGMENT",IN_RELATIVE_INTERIOR_CLOSURE_CONVEX_SEGMENT; +"IN_RELATIVE_INTERIOR_CLOSURE_CONVEX_SHRINK",IN_RELATIVE_INTERIOR_CLOSURE_CONVEX_SHRINK; +"IN_RELATIVE_INTERIOR_CONVEX_SHRINK",IN_RELATIVE_INTERIOR_CONVEX_SHRINK; +"IN_REST",IN_REST; +"IN_SEGMENT",IN_SEGMENT; +"IN_SEGMENT_COMPONENT",IN_SEGMENT_COMPONENT; +"IN_SEGMENT_CX",IN_SEGMENT_CX; +"IN_SEGMENT_CX_GEN",IN_SEGMENT_CX_GEN; +"IN_SET_OF_LIST",IN_SET_OF_LIST; +"IN_SING",IN_SING; +"IN_SLICE",IN_SLICE; +"IN_SPAN_DELETE",IN_SPAN_DELETE; +"IN_SPAN_IMAGE_BASIS",IN_SPAN_IMAGE_BASIS; +"IN_SPAN_INSERT",IN_SPAN_INSERT; +"IN_SPHERE",IN_SPHERE; +"IN_SPHERE_0",IN_SPHERE_0; +"IN_SUPPORT",IN_SUPPORT; +"IN_UNION",IN_UNION; +"IN_UNIONS",IN_UNIONS; +"IN_UNIV",IN_UNIV; +"IRRATIONAL_APPROXIMATION",IRRATIONAL_APPROXIMATION; +"ISO",ISO; +"ISOLATED_ZEROS",ISOLATED_ZEROS; +"ISOMETRIES_SUBSPACES",ISOMETRIES_SUBSPACES; +"ISOMETRY_IMP_AFFINITY",ISOMETRY_IMP_AFFINITY; +"ISOMETRY_LINEAR",ISOMETRY_LINEAR; +"ISOMETRY_ON_IMP_CONTINUOUS_ON",ISOMETRY_ON_IMP_CONTINUOUS_ON; +"ISOMETRY_SPHERE_EXTEND",ISOMETRY_SPHERE_EXTEND; +"ISOMETRY_SUBSET_SUBSPACE",ISOMETRY_SUBSET_SUBSPACE; +"ISOMETRY_SUBSPACES",ISOMETRY_SUBSPACES; +"ISOMETRY_UNIV_SUBSPACE",ISOMETRY_UNIV_SUBSPACE; +"ISOMETRY_UNIV_SUPERSET_SUBSPACE",ISOMETRY_UNIV_SUPERSET_SUBSPACE; +"ISOMETRY_UNIV_UNIV",ISOMETRY_UNIV_UNIV; +"ISOMORPHISMS_UNIV_UNIV",ISOMORPHISMS_UNIV_UNIV; +"ISOMORPHISM_EXPAND",ISOMORPHISM_EXPAND; +"ISO_FUN",ISO_FUN; +"ISO_REFL",ISO_REFL; +"ISO_USAGE",ISO_USAGE; +"ISTOPLOGY_SUBTOPOLOGY",ISTOPLOGY_SUBTOPOLOGY; +"ISTOPOLOGY_OPEN_IN",ISTOPOLOGY_OPEN_IN; +"IS_AFFINE_HULL",IS_AFFINE_HULL; +"IS_CONVEX_HULL",IS_CONVEX_HULL; +"IS_HULL",IS_HULL; +"IS_INTERVAL_1",IS_INTERVAL_1; +"IS_INTERVAL_1_CASES",IS_INTERVAL_1_CASES; +"IS_INTERVAL_COMPACT",IS_INTERVAL_COMPACT; +"IS_INTERVAL_CONNECTED",IS_INTERVAL_CONNECTED; +"IS_INTERVAL_CONNECTED_1",IS_INTERVAL_CONNECTED_1; +"IS_INTERVAL_CONTRACTIBLE_1",IS_INTERVAL_CONTRACTIBLE_1; +"IS_INTERVAL_CONVEX",IS_INTERVAL_CONVEX; +"IS_INTERVAL_CONVEX_1",IS_INTERVAL_CONVEX_1; +"IS_INTERVAL_EMPTY",IS_INTERVAL_EMPTY; +"IS_INTERVAL_IMP_LOCALLY_COMPACT",IS_INTERVAL_IMP_LOCALLY_COMPACT; +"IS_INTERVAL_INTER",IS_INTERVAL_INTER; +"IS_INTERVAL_INTERVAL",IS_INTERVAL_INTERVAL; +"IS_INTERVAL_PATH_CONNECTED",IS_INTERVAL_PATH_CONNECTED; +"IS_INTERVAL_PATH_CONNECTED_1",IS_INTERVAL_PATH_CONNECTED_1; +"IS_INTERVAL_PCROSS",IS_INTERVAL_PCROSS; +"IS_INTERVAL_PCROSS_EQ",IS_INTERVAL_PCROSS_EQ; +"IS_INTERVAL_POINTWISE",IS_INTERVAL_POINTWISE; +"IS_INTERVAL_SCALING",IS_INTERVAL_SCALING; +"IS_INTERVAL_SCALING_EQ",IS_INTERVAL_SCALING_EQ; +"IS_INTERVAL_SIMPLY_CONNECTED_1",IS_INTERVAL_SIMPLY_CONNECTED_1; +"IS_INTERVAL_SING",IS_INTERVAL_SING; +"IS_INTERVAL_SUMS",IS_INTERVAL_SUMS; +"IS_INTERVAL_TRANSLATION",IS_INTERVAL_TRANSLATION; +"IS_INTERVAL_TRANSLATION_EQ",IS_INTERVAL_TRANSLATION_EQ; +"IS_INTERVAL_UNIV",IS_INTERVAL_UNIV; +"IS_REALINTERVAL_CONNECTED",IS_REALINTERVAL_CONNECTED; +"IS_REALINTERVAL_CONTINUOUS_IMAGE",IS_REALINTERVAL_CONTINUOUS_IMAGE; +"IS_REALINTERVAL_CONVEX",IS_REALINTERVAL_CONVEX; +"IS_REALINTERVAL_CONVEX_COMPLEX",IS_REALINTERVAL_CONVEX_COMPLEX; +"IS_REALINTERVAL_EMPTY",IS_REALINTERVAL_EMPTY; +"IS_REALINTERVAL_INTERVAL",IS_REALINTERVAL_INTERVAL; +"IS_REALINTERVAL_IS_INTERVAL",IS_REALINTERVAL_IS_INTERVAL; +"IS_REALINTERVAL_UNION",IS_REALINTERVAL_UNION; +"IS_REALINTERVAL_UNIV",IS_REALINTERVAL_UNIV; +"IS_REAL_INTERVAL_CASES",IS_REAL_INTERVAL_CASES; +"ITER",ITER; +"ITERATE_AND",ITERATE_AND; +"ITERATE_BIJECTION",ITERATE_BIJECTION; +"ITERATE_CASES",ITERATE_CASES; +"ITERATE_CLAUSES",ITERATE_CLAUSES; +"ITERATE_CLAUSES_GEN",ITERATE_CLAUSES_GEN; +"ITERATE_CLAUSES_NUMSEG",ITERATE_CLAUSES_NUMSEG; +"ITERATE_CLOSED",ITERATE_CLOSED; +"ITERATE_DELETE",ITERATE_DELETE; +"ITERATE_DELTA",ITERATE_DELTA; +"ITERATE_DIFF",ITERATE_DIFF; +"ITERATE_DIFF_GEN",ITERATE_DIFF_GEN; +"ITERATE_EQ",ITERATE_EQ; +"ITERATE_EQ_GENERAL",ITERATE_EQ_GENERAL; +"ITERATE_EQ_GENERAL_INVERSES",ITERATE_EQ_GENERAL_INVERSES; +"ITERATE_EQ_NEUTRAL",ITERATE_EQ_NEUTRAL; +"ITERATE_EXPAND_CASES",ITERATE_EXPAND_CASES; +"ITERATE_IMAGE",ITERATE_IMAGE; +"ITERATE_IMAGE_NONZERO",ITERATE_IMAGE_NONZERO; +"ITERATE_INCL_EXCL",ITERATE_INCL_EXCL; +"ITERATE_INJECTION",ITERATE_INJECTION; +"ITERATE_ITERATE_PRODUCT",ITERATE_ITERATE_PRODUCT; +"ITERATE_NONZERO_IMAGE_LEMMA",ITERATE_NONZERO_IMAGE_LEMMA; +"ITERATE_OP",ITERATE_OP; +"ITERATE_OP_GEN",ITERATE_OP_GEN; +"ITERATE_PAIR",ITERATE_PAIR; +"ITERATE_PERMUTE",ITERATE_PERMUTE; +"ITERATE_RELATED",ITERATE_RELATED; +"ITERATE_SING",ITERATE_SING; +"ITERATE_SOME",ITERATE_SOME; +"ITERATE_SUPERSET",ITERATE_SUPERSET; +"ITERATE_SUPPORT",ITERATE_SUPPORT; +"ITERATE_UNION",ITERATE_UNION; +"ITERATE_UNION_GEN",ITERATE_UNION_GEN; +"ITERATE_UNION_NONZERO",ITERATE_UNION_NONZERO; +"ITER_1",ITER_1; +"ITER_ADD",ITER_ADD; +"ITER_ALT",ITER_ALT; +"ITER_ALT_POINTLESS",ITER_ALT_POINTLESS; +"ITER_FIXPOINT",ITER_FIXPOINT; +"ITER_MUL",ITER_MUL; +"ITER_POINTLESS",ITER_POINTLESS; +"ITLIST",ITLIST; +"ITLIST2",ITLIST2; +"ITLIST2_DEF",ITLIST2_DEF; +"ITLIST_APPEND",ITLIST_APPEND; +"ITLIST_EXTRA",ITLIST_EXTRA; +"ITSET",ITSET; +"ITSET_EQ",ITSET_EQ; +"IVT_DECREASING_COMPONENT_1",IVT_DECREASING_COMPONENT_1; +"IVT_DECREASING_COMPONENT_ON_1",IVT_DECREASING_COMPONENT_ON_1; +"IVT_DECREASING_IM",IVT_DECREASING_IM; +"IVT_DECREASING_RE",IVT_DECREASING_RE; +"IVT_INCREASING_COMPONENT_1",IVT_INCREASING_COMPONENT_1; +"IVT_INCREASING_COMPONENT_ON_1",IVT_INCREASING_COMPONENT_ON_1; +"IVT_INCREASING_IM",IVT_INCREASING_IM; +"IVT_INCREASING_RE",IVT_INCREASING_RE; +"I_DEF",I_DEF; +"I_O_ID",I_O_ID; +"I_THM",I_THM; +"JACOBIAN_WORKS",JACOBIAN_WORKS; +"JANISZEWSKI",JANISZEWSKI; +"JANISZEWSKI_GEN",JANISZEWSKI_GEN; +"JOINABLE_COMPONENTS_EQ",JOINABLE_COMPONENTS_EQ; +"JOINABLE_CONNECTED_COMPONENT_EQ",JOINABLE_CONNECTED_COMPONENT_EQ; +"JOINPATHS",JOINPATHS; +"JOINPATHS_LINEAR_IMAGE",JOINPATHS_LINEAR_IMAGE; +"JOINPATHS_TRANSLATION",JOINPATHS_TRANSLATION; +"JOIN_PATHS_EQ",JOIN_PATHS_EQ; +"JOIN_SUBPATHS_MIDDLE",JOIN_SUBPATHS_MIDDLE; +"JORDAN_BROUWER_ACCESSIBILITY",JORDAN_BROUWER_ACCESSIBILITY; +"JORDAN_BROUWER_FRONTIER",JORDAN_BROUWER_FRONTIER; +"JORDAN_BROUWER_NONSEPARATION",JORDAN_BROUWER_NONSEPARATION; +"JORDAN_BROUWER_SEPARATION",JORDAN_BROUWER_SEPARATION; +"JORDAN_CURVE_THEOREM",JORDAN_CURVE_THEOREM; +"JORDAN_DISCONNECTED",JORDAN_DISCONNECTED; +"JORDAN_INSIDE_OUTSIDE",JORDAN_INSIDE_OUTSIDE; +"JUNG",JUNG; +"KIRCHBERGER",KIRCHBERGER; +"KL",KL; +"KLE_ADJACENT",KLE_ADJACENT; +"KLE_ANTISYM",KLE_ANTISYM; +"KLE_BETWEEN_L",KLE_BETWEEN_L; +"KLE_BETWEEN_R",KLE_BETWEEN_R; +"KLE_IMP_POINTWISE",KLE_IMP_POINTWISE; +"KLE_MAXIMAL",KLE_MAXIMAL; +"KLE_MINIMAL",KLE_MINIMAL; +"KLE_RANGE_COMBINE",KLE_RANGE_COMBINE; +"KLE_RANGE_COMBINE_L",KLE_RANGE_COMBINE_L; +"KLE_RANGE_COMBINE_R",KLE_RANGE_COMBINE_R; +"KLE_RANGE_INDUCT",KLE_RANGE_INDUCT; +"KLE_REFL",KLE_REFL; +"KLE_STRICT",KLE_STRICT; +"KLE_STRICT_SET",KLE_STRICT_SET; +"KLE_SUC",KLE_SUC; +"KLE_TRANS",KLE_TRANS; +"KLE_TRANS_1",KLE_TRANS_1; +"KLE_TRANS_2",KLE_TRANS_2; +"KL_POSET_LEMMA",KL_POSET_LEMMA; +"KREIN_MILMAN",KREIN_MILMAN; +"KREIN_MILMAN_FRONTIER",KREIN_MILMAN_FRONTIER; +"KREIN_MILMAN_MINKOWSKI",KREIN_MILMAN_MINKOWSKI; +"KREIN_MILMAN_POLYTOPE",KREIN_MILMAN_POLYTOPE; +"KREIN_MILMAN_RELATIVE_FRONTIER",KREIN_MILMAN_RELATIVE_FRONTIER; +"KSIMPLEX_0",KSIMPLEX_0; +"KSIMPLEX_EXTREMA",KSIMPLEX_EXTREMA; +"KSIMPLEX_EXTREMA_STRONG",KSIMPLEX_EXTREMA_STRONG; +"KSIMPLEX_FIX_PLANE",KSIMPLEX_FIX_PLANE; +"KSIMPLEX_FIX_PLANE_0",KSIMPLEX_FIX_PLANE_0; +"KSIMPLEX_FIX_PLANE_P",KSIMPLEX_FIX_PLANE_P; +"KSIMPLEX_PREDECESSOR",KSIMPLEX_PREDECESSOR; +"KSIMPLEX_REPLACE_0",KSIMPLEX_REPLACE_0; +"KSIMPLEX_REPLACE_1",KSIMPLEX_REPLACE_1; +"KSIMPLEX_REPLACE_2",KSIMPLEX_REPLACE_2; +"KSIMPLEX_SUCCESSOR",KSIMPLEX_SUCCESSOR; +"KUHN_COMBINATORIAL",KUHN_COMBINATORIAL; +"KUHN_COMPLETE_LEMMA",KUHN_COMPLETE_LEMMA; +"KUHN_COUNTING_LEMMA",KUHN_COUNTING_LEMMA; +"KUHN_INDUCTION",KUHN_INDUCTION; +"KUHN_LABELLING_LEMMA",KUHN_LABELLING_LEMMA; +"KUHN_LEMMA",KUHN_LEMMA; +"KUHN_SIMPLEX_LEMMA",KUHN_SIMPLEX_LEMMA; +"L1_LE_NORM",L1_LE_NORM; +"LAMBDA_ADD_GALOIS",LAMBDA_ADD_GALOIS; +"LAMBDA_BETA",LAMBDA_BETA; +"LAMBDA_BETA_PERM",LAMBDA_BETA_PERM; +"LAMBDA_ETA",LAMBDA_ETA; +"LAMBDA_PAIR",LAMBDA_PAIR; +"LAMBDA_PAIR_THM",LAMBDA_PAIR_THM; +"LAMBDA_SKOLEM",LAMBDA_SKOLEM; +"LAMBDA_SWAP_GALOIS",LAMBDA_SWAP_GALOIS; +"LAMBDA_UNIQUE",LAMBDA_UNIQUE; +"LANDAU_PICARD",LANDAU_PICARD; +"LAST",LAST; +"LAST_APPEND",LAST_APPEND; +"LAST_CLAUSES",LAST_CLAUSES; +"LAST_EL",LAST_EL; +"LE",LE; +"LEBESGUE_COVERING_LEMMA",LEBESGUE_COVERING_LEMMA; +"LEBESGUE_DENSITY_THEOREM",LEBESGUE_DENSITY_THEOREM; +"LEBESGUE_MEASURABLE_CLOSED",LEBESGUE_MEASURABLE_CLOSED; +"LEBESGUE_MEASURABLE_COMPACT",LEBESGUE_MEASURABLE_COMPACT; +"LEBESGUE_MEASURABLE_COMPL",LEBESGUE_MEASURABLE_COMPL; +"LEBESGUE_MEASURABLE_CONTINUOUS_IMAGE",LEBESGUE_MEASURABLE_CONTINUOUS_IMAGE; +"LEBESGUE_MEASURABLE_CONVEX",LEBESGUE_MEASURABLE_CONVEX; +"LEBESGUE_MEASURABLE_COUNTABLE_INTERS",LEBESGUE_MEASURABLE_COUNTABLE_INTERS; +"LEBESGUE_MEASURABLE_COUNTABLE_INTERS_EXPLICIT",LEBESGUE_MEASURABLE_COUNTABLE_INTERS_EXPLICIT; +"LEBESGUE_MEASURABLE_COUNTABLE_UNIONS",LEBESGUE_MEASURABLE_COUNTABLE_UNIONS; +"LEBESGUE_MEASURABLE_COUNTABLE_UNIONS_EXPLICIT",LEBESGUE_MEASURABLE_COUNTABLE_UNIONS_EXPLICIT; +"LEBESGUE_MEASURABLE_DIFF",LEBESGUE_MEASURABLE_DIFF; +"LEBESGUE_MEASURABLE_DIFFERENTIABLE_IMAGE",LEBESGUE_MEASURABLE_DIFFERENTIABLE_IMAGE; +"LEBESGUE_MEASURABLE_EMPTY",LEBESGUE_MEASURABLE_EMPTY; +"LEBESGUE_MEASURABLE_IFF_MEASURABLE",LEBESGUE_MEASURABLE_IFF_MEASURABLE; +"LEBESGUE_MEASURABLE_INNER_CLOSED",LEBESGUE_MEASURABLE_INNER_CLOSED; +"LEBESGUE_MEASURABLE_INTER",LEBESGUE_MEASURABLE_INTER; +"LEBESGUE_MEASURABLE_INTERS",LEBESGUE_MEASURABLE_INTERS; +"LEBESGUE_MEASURABLE_INTERVAL",LEBESGUE_MEASURABLE_INTERVAL; +"LEBESGUE_MEASURABLE_JORDAN",LEBESGUE_MEASURABLE_JORDAN; +"LEBESGUE_MEASURABLE_LEBESGUE_MEASURABLE_PREIMAGE_CLOSED",LEBESGUE_MEASURABLE_LEBESGUE_MEASURABLE_PREIMAGE_CLOSED; +"LEBESGUE_MEASURABLE_LEBESGUE_MEASURABLE_PREIMAGE_OPEN",LEBESGUE_MEASURABLE_LEBESGUE_MEASURABLE_PREIMAGE_OPEN; +"LEBESGUE_MEASURABLE_LINEAR_IMAGE_EQ",LEBESGUE_MEASURABLE_LINEAR_IMAGE_EQ; +"LEBESGUE_MEASURABLE_ON_SUBINTERVALS",LEBESGUE_MEASURABLE_ON_SUBINTERVALS; +"LEBESGUE_MEASURABLE_OPEN",LEBESGUE_MEASURABLE_OPEN; +"LEBESGUE_MEASURABLE_OUTER_OPEN",LEBESGUE_MEASURABLE_OUTER_OPEN; +"LEBESGUE_MEASURABLE_PREIMAGE_CLOSED",LEBESGUE_MEASURABLE_PREIMAGE_CLOSED; +"LEBESGUE_MEASURABLE_PREIMAGE_OPEN",LEBESGUE_MEASURABLE_PREIMAGE_OPEN; +"LEBESGUE_MEASURABLE_REGULAR_INNER",LEBESGUE_MEASURABLE_REGULAR_INNER; +"LEBESGUE_MEASURABLE_REGULAR_OUTER",LEBESGUE_MEASURABLE_REGULAR_OUTER; +"LEBESGUE_MEASURABLE_TRANSLATION",LEBESGUE_MEASURABLE_TRANSLATION; +"LEBESGUE_MEASURABLE_UNION",LEBESGUE_MEASURABLE_UNION; +"LEBESGUE_MEASURABLE_UNIONS",LEBESGUE_MEASURABLE_UNIONS; +"LEBESGUE_MEASURABLE_UNIV",LEBESGUE_MEASURABLE_UNIV; +"LEFT_ADD_DISTRIB",LEFT_ADD_DISTRIB; +"LEFT_AND_EXISTS_THM",LEFT_AND_EXISTS_THM; +"LEFT_AND_FORALL_THM",LEFT_AND_FORALL_THM; +"LEFT_EXISTS_AND_THM",LEFT_EXISTS_AND_THM; +"LEFT_EXISTS_IMP_THM",LEFT_EXISTS_IMP_THM; +"LEFT_FORALL_IMP_THM",LEFT_FORALL_IMP_THM; +"LEFT_FORALL_OR_THM",LEFT_FORALL_OR_THM; +"LEFT_IMP_EXISTS_THM",LEFT_IMP_EXISTS_THM; +"LEFT_IMP_FORALL_THM",LEFT_IMP_FORALL_THM; +"LEFT_INVERSE_LINEAR",LEFT_INVERSE_LINEAR; +"LEFT_INVERTIBLE_TRANSP",LEFT_INVERTIBLE_TRANSP; +"LEFT_OR_DISTRIB",LEFT_OR_DISTRIB; +"LEFT_OR_EXISTS_THM",LEFT_OR_EXISTS_THM; +"LEFT_OR_FORALL_THM",LEFT_OR_FORALL_THM; +"LEFT_RIGHT_INVERSE_EQ",LEFT_RIGHT_INVERSE_EQ; +"LEFT_RIGHT_INVERSE_LINEAR",LEFT_RIGHT_INVERSE_LINEAR; +"LEFT_SUB_DISTRIB",LEFT_SUB_DISTRIB; +"LEMMA",LEMMA; +"LENGTH",LENGTH; +"LENGTH_APPEND",LENGTH_APPEND; +"LENGTH_EQ_CONS",LENGTH_EQ_CONS; +"LENGTH_EQ_NIL",LENGTH_EQ_NIL; +"LENGTH_LIST_OF_SET",LENGTH_LIST_OF_SET; +"LENGTH_MAP",LENGTH_MAP; +"LENGTH_MAP2",LENGTH_MAP2; +"LENGTH_REPLICATE",LENGTH_REPLICATE; +"LENGTH_TL",LENGTH_TL; +"LET_ADD2",LET_ADD2; +"LET_ANTISYM",LET_ANTISYM; +"LET_CASES",LET_CASES; +"LET_DEF",LET_DEF; +"LET_END_DEF",LET_END_DEF; +"LET_TRANS",LET_TRANS; +"LE_0",LE_0; +"LE_1",LE_1; +"LE_ADD",LE_ADD; +"LE_ADD2",LE_ADD2; +"LE_ADDR",LE_ADDR; +"LE_ADD_LCANCEL",LE_ADD_LCANCEL; +"LE_ADD_RCANCEL",LE_ADD_RCANCEL; +"LE_ANTISYM",LE_ANTISYM; +"LE_C",LE_C; +"LE_CASES",LE_CASES; +"LE_EXISTS",LE_EXISTS; +"LE_EXP",LE_EXP; +"LE_LDIV",LE_LDIV; +"LE_LDIV_EQ",LE_LDIV_EQ; +"LE_LT",LE_LT; +"LE_MULT2",LE_MULT2; +"LE_MULT_LCANCEL",LE_MULT_LCANCEL; +"LE_MULT_RCANCEL",LE_MULT_RCANCEL; +"LE_RDIV_EQ",LE_RDIV_EQ; +"LE_REFL",LE_REFL; +"LE_SQUARE_REFL",LE_SQUARE_REFL; +"LE_SUC",LE_SUC; +"LE_SUC_LT",LE_SUC_LT; +"LE_TRANS",LE_TRANS; +"LHOSPITAL",LHOSPITAL; +"LIFT_ADD",LIFT_ADD; +"LIFT_CMUL",LIFT_CMUL; +"LIFT_COMPONENT",LIFT_COMPONENT; +"LIFT_DROP",LIFT_DROP; +"LIFT_EQ",LIFT_EQ; +"LIFT_EQ_CMUL",LIFT_EQ_CMUL; +"LIFT_INTEGRAL_COMPONENT",LIFT_INTEGRAL_COMPONENT; +"LIFT_IN_IMAGE_LIFT",LIFT_IN_IMAGE_LIFT; +"LIFT_NEG",LIFT_NEG; +"LIFT_NUM",LIFT_NUM; +"LIFT_SUB",LIFT_SUB; +"LIFT_SUM",LIFT_SUM; +"LIM",LIM; +"LIMIT_POINT_FINITE",LIMIT_POINT_FINITE; +"LIMIT_POINT_OF_SPHERE",LIMIT_POINT_OF_SPHERE; +"LIMIT_POINT_UNION",LIMIT_POINT_UNION; +"LIMPT_APPROACHABLE",LIMPT_APPROACHABLE; +"LIMPT_APPROACHABLE_LE",LIMPT_APPROACHABLE_LE; +"LIMPT_APPROACHABLE_LIFT",LIMPT_APPROACHABLE_LIFT; +"LIMPT_BALL",LIMPT_BALL; +"LIMPT_EMPTY",LIMPT_EMPTY; +"LIMPT_INFINITE_BALL",LIMPT_INFINITE_BALL; +"LIMPT_INFINITE_CBALL",LIMPT_INFINITE_CBALL; +"LIMPT_INFINITE_OPEN",LIMPT_INFINITE_OPEN; +"LIMPT_INJECTIVE_LINEAR_IMAGE_EQ",LIMPT_INJECTIVE_LINEAR_IMAGE_EQ; +"LIMPT_INSERT",LIMPT_INSERT; +"LIMPT_OF_CLOSURE",LIMPT_OF_CLOSURE; +"LIMPT_OF_CONDENSATION_POINTS",LIMPT_OF_CONDENSATION_POINTS; +"LIMPT_OF_CONVEX",LIMPT_OF_CONVEX; +"LIMPT_OF_LIMPTS",LIMPT_OF_LIMPTS; +"LIMPT_OF_OPEN",LIMPT_OF_OPEN; +"LIMPT_OF_OPEN_IN",LIMPT_OF_OPEN_IN; +"LIMPT_OF_SEQUENCE_SUBSEQUENCE",LIMPT_OF_SEQUENCE_SUBSEQUENCE; +"LIMPT_OF_UNIV",LIMPT_OF_UNIV; +"LIMPT_PCROSS",LIMPT_PCROSS; +"LIMPT_SEQUENTIAL",LIMPT_SEQUENTIAL; +"LIMPT_SEQUENTIAL_INJ",LIMPT_SEQUENTIAL_INJ; +"LIMPT_SING",LIMPT_SING; +"LIMPT_SUBSET",LIMPT_SUBSET; +"LIMPT_TRANSLATION_EQ",LIMPT_TRANSLATION_EQ; +"LIMPT_UNIV",LIMPT_UNIV; +"LIM_1_OVER_LOG",LIM_1_OVER_LOG; +"LIM_1_OVER_N",LIM_1_OVER_N; +"LIM_1_OVER_POWER",LIM_1_OVER_POWER; +"LIM_ABS",LIM_ABS; +"LIM_ADD",LIM_ADD; +"LIM_AT",LIM_AT; +"LIM_ATREAL",LIM_ATREAL; +"LIM_ATREAL_AT",LIM_ATREAL_AT; +"LIM_ATREAL_ATCOMPLEX",LIM_ATREAL_ATCOMPLEX; +"LIM_ATREAL_WITHINREAL",LIM_ATREAL_WITHINREAL; +"LIM_AT_ID",LIM_AT_ID; +"LIM_AT_INFINITY",LIM_AT_INFINITY; +"LIM_AT_NEGINFINITY",LIM_AT_NEGINFINITY; +"LIM_AT_POSINFINITY",LIM_AT_POSINFINITY; +"LIM_AT_WITHIN",LIM_AT_WITHIN; +"LIM_AT_ZERO",LIM_AT_ZERO; +"LIM_BILINEAR",LIM_BILINEAR; +"LIM_CASES_COFINITE_SEQUENTIALLY",LIM_CASES_COFINITE_SEQUENTIALLY; +"LIM_CASES_FINITE_SEQUENTIALLY",LIM_CASES_FINITE_SEQUENTIALLY; +"LIM_CASES_SEQUENTIALLY",LIM_CASES_SEQUENTIALLY; +"LIM_CEXP_MINUS_1",LIM_CEXP_MINUS_1; +"LIM_CMUL",LIM_CMUL; +"LIM_CMUL_EQ",LIM_CMUL_EQ; +"LIM_CNJ",LIM_CNJ; +"LIM_COMPLEX_DIV",LIM_COMPLEX_DIV; +"LIM_COMPLEX_INV",LIM_COMPLEX_INV; +"LIM_COMPLEX_LMUL",LIM_COMPLEX_LMUL; +"LIM_COMPLEX_MUL",LIM_COMPLEX_MUL; +"LIM_COMPLEX_POW",LIM_COMPLEX_POW; +"LIM_COMPLEX_REAL",LIM_COMPLEX_REAL; +"LIM_COMPLEX_REAL_0",LIM_COMPLEX_REAL_0; +"LIM_COMPLEX_RMUL",LIM_COMPLEX_RMUL; +"LIM_COMPONENT",LIM_COMPONENT; +"LIM_COMPONENTWISE",LIM_COMPONENTWISE; +"LIM_COMPONENTWISE_LIFT",LIM_COMPONENTWISE_LIFT; +"LIM_COMPONENT_EQ",LIM_COMPONENT_EQ; +"LIM_COMPONENT_LBOUND",LIM_COMPONENT_LBOUND; +"LIM_COMPONENT_LE",LIM_COMPONENT_LE; +"LIM_COMPONENT_UBOUND",LIM_COMPONENT_UBOUND; +"LIM_COMPOSE_AT",LIM_COMPOSE_AT; +"LIM_COMPOSE_WITHIN",LIM_COMPOSE_WITHIN; +"LIM_CONG_AT",LIM_CONG_AT; +"LIM_CONG_ATREAL",LIM_CONG_ATREAL; +"LIM_CONG_WITHIN",LIM_CONG_WITHIN; +"LIM_CONG_WITHINREAL",LIM_CONG_WITHINREAL; +"LIM_CONST",LIM_CONST; +"LIM_CONST_EQ",LIM_CONST_EQ; +"LIM_CONTINUOUS",LIM_CONTINUOUS; +"LIM_CONTINUOUS_FUNCTION",LIM_CONTINUOUS_FUNCTION; +"LIM_DROP_LBOUND",LIM_DROP_LBOUND; +"LIM_DROP_LE",LIM_DROP_LE; +"LIM_DROP_UBOUND",LIM_DROP_UBOUND; +"LIM_EVENTUALLY",LIM_EVENTUALLY; +"LIM_IM_LBOUND",LIM_IM_LBOUND; +"LIM_IM_UBOUND",LIM_IM_UBOUND; +"LIM_INFINITY_SEQUENTIALLY_COMPLEX",LIM_INFINITY_SEQUENTIALLY_COMPLEX; +"LIM_INV",LIM_INV; +"LIM_INV_N",LIM_INV_N; +"LIM_IN_CLOSED_SET",LIM_IN_CLOSED_SET; +"LIM_LIFT_DOT",LIM_LIFT_DOT; +"LIM_LINEAR",LIM_LINEAR; +"LIM_LOG_OVER_N",LIM_LOG_OVER_N; +"LIM_LOG_OVER_POWER",LIM_LOG_OVER_POWER; +"LIM_MAX",LIM_MAX; +"LIM_MIN",LIM_MIN; +"LIM_MUL",LIM_MUL; +"LIM_MUL_NORM_WITHIN",LIM_MUL_NORM_WITHIN; +"LIM_NEG",LIM_NEG; +"LIM_NEG_EQ",LIM_NEG_EQ; +"LIM_NORM",LIM_NORM; +"LIM_NORM_LBOUND",LIM_NORM_LBOUND; +"LIM_NORM_UBOUND",LIM_NORM_UBOUND; +"LIM_NULL",LIM_NULL; +"LIM_NULL_CMUL_BOUNDED",LIM_NULL_CMUL_BOUNDED; +"LIM_NULL_CMUL_EQ",LIM_NULL_CMUL_EQ; +"LIM_NULL_COMPARISON",LIM_NULL_COMPARISON; +"LIM_NULL_COMPARISON_COMPLEX",LIM_NULL_COMPARISON_COMPLEX; +"LIM_NULL_COMPARISON_COMPLEX_RE",LIM_NULL_COMPARISON_COMPLEX_RE; +"LIM_NULL_COMPLEX_ADD",LIM_NULL_COMPLEX_ADD; +"LIM_NULL_COMPLEX_BOUND",LIM_NULL_COMPLEX_BOUND; +"LIM_NULL_COMPLEX_LMUL",LIM_NULL_COMPLEX_LMUL; +"LIM_NULL_COMPLEX_LMUL_BOUNDED",LIM_NULL_COMPLEX_LMUL_BOUNDED; +"LIM_NULL_COMPLEX_MUL",LIM_NULL_COMPLEX_MUL; +"LIM_NULL_COMPLEX_NEG",LIM_NULL_COMPLEX_NEG; +"LIM_NULL_COMPLEX_POW",LIM_NULL_COMPLEX_POW; +"LIM_NULL_COMPLEX_POW_EQ",LIM_NULL_COMPLEX_POW_EQ; +"LIM_NULL_COMPLEX_RMUL",LIM_NULL_COMPLEX_RMUL; +"LIM_NULL_COMPLEX_RMUL_BOUNDED",LIM_NULL_COMPLEX_RMUL_BOUNDED; +"LIM_NULL_COMPLEX_SUB",LIM_NULL_COMPLEX_SUB; +"LIM_NULL_NORM",LIM_NULL_NORM; +"LIM_NULL_VMUL_BOUNDED",LIM_NULL_VMUL_BOUNDED; +"LIM_N_OVER_POWN",LIM_N_OVER_POWN; +"LIM_N_TIMES_POWN",LIM_N_TIMES_POWN; +"LIM_PASTECART",LIM_PASTECART; +"LIM_PASTECART_EQ",LIM_PASTECART_EQ; +"LIM_POSINFINITY_SEQUENTIALLY",LIM_POSINFINITY_SEQUENTIALLY; +"LIM_POWN",LIM_POWN; +"LIM_REAL_CONTINUOUS_FUNCTION",LIM_REAL_CONTINUOUS_FUNCTION; +"LIM_RE_LBOUND",LIM_RE_LBOUND; +"LIM_RE_UBOUND",LIM_RE_UBOUND; +"LIM_SEQUENTIALLY",LIM_SEQUENTIALLY; +"LIM_SUB",LIM_SUB; +"LIM_SUBSEQUENCE",LIM_SUBSEQUENCE; +"LIM_TRANSFORM",LIM_TRANSFORM; +"LIM_TRANSFORM_AT",LIM_TRANSFORM_AT; +"LIM_TRANSFORM_AWAY_AT",LIM_TRANSFORM_AWAY_AT; +"LIM_TRANSFORM_AWAY_WITHIN",LIM_TRANSFORM_AWAY_WITHIN; +"LIM_TRANSFORM_BOUND",LIM_TRANSFORM_BOUND; +"LIM_TRANSFORM_EQ",LIM_TRANSFORM_EQ; +"LIM_TRANSFORM_EVENTUALLY",LIM_TRANSFORM_EVENTUALLY; +"LIM_TRANSFORM_WITHIN",LIM_TRANSFORM_WITHIN; +"LIM_TRANSFORM_WITHINREAL_SET",LIM_TRANSFORM_WITHINREAL_SET; +"LIM_TRANSFORM_WITHIN_OPEN",LIM_TRANSFORM_WITHIN_OPEN; +"LIM_TRANSFORM_WITHIN_SET",LIM_TRANSFORM_WITHIN_SET; +"LIM_UNION",LIM_UNION; +"LIM_UNION_UNIV",LIM_UNION_UNIV; +"LIM_UNIQUE",LIM_UNIQUE; +"LIM_VMUL",LIM_VMUL; +"LIM_VSUM",LIM_VSUM; +"LIM_WITHIN",LIM_WITHIN; +"LIM_WITHINREAL",LIM_WITHINREAL; +"LIM_WITHINREAL_LE",LIM_WITHINREAL_LE; +"LIM_WITHINREAL_SUBSET",LIM_WITHINREAL_SUBSET; +"LIM_WITHINREAL_WITHIN",LIM_WITHINREAL_WITHIN; +"LIM_WITHINREAL_WITHINCOMPLEX",LIM_WITHINREAL_WITHINCOMPLEX; +"LIM_WITHIN_CLOSED_TRIVIAL",LIM_WITHIN_CLOSED_TRIVIAL; +"LIM_WITHIN_EMPTY",LIM_WITHIN_EMPTY; +"LIM_WITHIN_ID",LIM_WITHIN_ID; +"LIM_WITHIN_INTERIOR",LIM_WITHIN_INTERIOR; +"LIM_WITHIN_LE",LIM_WITHIN_LE; +"LIM_WITHIN_OPEN",LIM_WITHIN_OPEN; +"LIM_WITHIN_REAL_OPEN",LIM_WITHIN_REAL_OPEN; +"LIM_WITHIN_SUBSET",LIM_WITHIN_SUBSET; +"LIM_WITHIN_UNION",LIM_WITHIN_UNION; +"LIM_ZERO_INFINITY_COMPLEX",LIM_ZERO_INFINITY_COMPLEX; +"LIM_ZERO_NEGINFINITY",LIM_ZERO_NEGINFINITY; +"LIM_ZERO_POSINFINITY",LIM_ZERO_POSINFINITY; +"LINDELOF",LINDELOF; +"LINDELOF_OPEN_IN",LINDELOF_OPEN_IN; +"LINEAR_0",LINEAR_0; +"LINEAR_1",LINEAR_1; +"LINEAR_ADD",LINEAR_ADD; +"LINEAR_BIJECTIVE_DIMINDEX_EQ",LINEAR_BIJECTIVE_DIMINDEX_EQ; +"LINEAR_BIJECTIVE_LEFT_RIGHT_INVERSE",LINEAR_BIJECTIVE_LEFT_RIGHT_INVERSE; +"LINEAR_BOUNDED",LINEAR_BOUNDED; +"LINEAR_BOUNDED_POS",LINEAR_BOUNDED_POS; +"LINEAR_CMUL",LINEAR_CMUL; +"LINEAR_CNJ",LINEAR_CNJ; +"LINEAR_COMPLEX_MUL",LINEAR_COMPLEX_MUL; +"LINEAR_COMPONENTWISE",LINEAR_COMPONENTWISE; +"LINEAR_COMPONENTWISE_EXPANSION",LINEAR_COMPONENTWISE_EXPANSION; +"LINEAR_COMPOSE",LINEAR_COMPOSE; +"LINEAR_COMPOSE_ADD",LINEAR_COMPOSE_ADD; +"LINEAR_COMPOSE_CMUL",LINEAR_COMPOSE_CMUL; +"LINEAR_COMPOSE_NEG",LINEAR_COMPOSE_NEG; +"LINEAR_COMPOSE_SUB",LINEAR_COMPOSE_SUB; +"LINEAR_COMPOSE_VSUM",LINEAR_COMPOSE_VSUM; +"LINEAR_CONTINUOUS_AT",LINEAR_CONTINUOUS_AT; +"LINEAR_CONTINUOUS_COMPOSE",LINEAR_CONTINUOUS_COMPOSE; +"LINEAR_CONTINUOUS_ON",LINEAR_CONTINUOUS_ON; +"LINEAR_CONTINUOUS_ON_COMPOSE",LINEAR_CONTINUOUS_ON_COMPOSE; +"LINEAR_CONTINUOUS_WITHIN",LINEAR_CONTINUOUS_WITHIN; +"LINEAR_CX_IM",LINEAR_CX_IM; +"LINEAR_CX_RE",LINEAR_CX_RE; +"LINEAR_DROPOUT",LINEAR_DROPOUT; +"LINEAR_EQ",LINEAR_EQ; +"LINEAR_EQ_0",LINEAR_EQ_0; +"LINEAR_EQ_0_SPAN",LINEAR_EQ_0_SPAN; +"LINEAR_EQ_MATRIX",LINEAR_EQ_MATRIX; +"LINEAR_EQ_MBASIS",LINEAR_EQ_MBASIS; +"LINEAR_EQ_STDBASIS",LINEAR_EQ_STDBASIS; +"LINEAR_FRECHET_DERIVATIVE",LINEAR_FRECHET_DERIVATIVE; +"LINEAR_FROM_REALS",LINEAR_FROM_REALS; +"LINEAR_FSTCART",LINEAR_FSTCART; +"LINEAR_I",LINEAR_I; +"LINEAR_ID",LINEAR_ID; +"LINEAR_IMAGE_SUBSET_INTERIOR",LINEAR_IMAGE_SUBSET_INTERIOR; +"LINEAR_INDEPENDENT_EXTEND",LINEAR_INDEPENDENT_EXTEND; +"LINEAR_INDEPENDENT_EXTEND_LEMMA",LINEAR_INDEPENDENT_EXTEND_LEMMA; +"LINEAR_INDEP_IMAGE_LEMMA",LINEAR_INDEP_IMAGE_LEMMA; +"LINEAR_INJECTIVE_0",LINEAR_INJECTIVE_0; +"LINEAR_INJECTIVE_0_SUBSPACE",LINEAR_INJECTIVE_0_SUBSPACE; +"LINEAR_INJECTIVE_BOUNDED_BELOW_POS",LINEAR_INJECTIVE_BOUNDED_BELOW_POS; +"LINEAR_INJECTIVE_DIMINDEX_LE",LINEAR_INJECTIVE_DIMINDEX_LE; +"LINEAR_INJECTIVE_IMP_SURJECTIVE",LINEAR_INJECTIVE_IMP_SURJECTIVE; +"LINEAR_INJECTIVE_ISOMORPHISM",LINEAR_INJECTIVE_ISOMORPHISM; +"LINEAR_INJECTIVE_LEFT_INVERSE",LINEAR_INJECTIVE_LEFT_INVERSE; +"LINEAR_INTERIOR_IMAGE_SUBSET",LINEAR_INTERIOR_IMAGE_SUBSET; +"LINEAR_INVERSE_LEFT",LINEAR_INVERSE_LEFT; +"LINEAR_INVERTIBLE_BOUNDED_BELOW",LINEAR_INVERTIBLE_BOUNDED_BELOW; +"LINEAR_INVERTIBLE_BOUNDED_BELOW_POS",LINEAR_INVERTIBLE_BOUNDED_BELOW_POS; +"LINEAR_LIFT_COMPONENT",LINEAR_LIFT_COMPONENT; +"LINEAR_LIFT_DOT",LINEAR_LIFT_DOT; +"LINEAR_LIM_0",LINEAR_LIM_0; +"LINEAR_MATRIX_EXISTS",LINEAR_MATRIX_EXISTS; +"LINEAR_NEG",LINEAR_NEG; +"LINEAR_NEGATION",LINEAR_NEGATION; +"LINEAR_OPEN_MAPPING",LINEAR_OPEN_MAPPING; +"LINEAR_PASTECART",LINEAR_PASTECART; +"LINEAR_PROPERTY",LINEAR_PROPERTY; +"LINEAR_REFLECT_ALONG",LINEAR_REFLECT_ALONG; +"LINEAR_ROTATE2D",LINEAR_ROTATE2D; +"LINEAR_SCALING",LINEAR_SCALING; +"LINEAR_SINGULAR_IMAGE_HYPERPLANE",LINEAR_SINGULAR_IMAGE_HYPERPLANE; +"LINEAR_SINGULAR_INTO_HYPERPLANE",LINEAR_SINGULAR_INTO_HYPERPLANE; +"LINEAR_SNDCART",LINEAR_SNDCART; +"LINEAR_SUB",LINEAR_SUB; +"LINEAR_SUBSPACE_GRAPH",LINEAR_SUBSPACE_GRAPH; +"LINEAR_SURJECTIVE_DIMINDEX_LE",LINEAR_SURJECTIVE_DIMINDEX_LE; +"LINEAR_SURJECTIVE_IFF_INJECTIVE",LINEAR_SURJECTIVE_IFF_INJECTIVE; +"LINEAR_SURJECTIVE_IMP_INJECTIVE",LINEAR_SURJECTIVE_IMP_INJECTIVE; +"LINEAR_SURJECTIVE_ISOMORPHISM",LINEAR_SURJECTIVE_ISOMORPHISM; +"LINEAR_SURJECTIVE_RIGHT_INVERSE",LINEAR_SURJECTIVE_RIGHT_INVERSE; +"LINEAR_TO_REALS",LINEAR_TO_REALS; +"LINEAR_UNIFORMLY_CONTINUOUS_ON",LINEAR_UNIFORMLY_CONTINUOUS_ON; +"LINEAR_VMUL_COMPONENT",LINEAR_VMUL_COMPONENT; +"LINEAR_VMUL_DROP",LINEAR_VMUL_DROP; +"LINEAR_VSUM",LINEAR_VSUM; +"LINEAR_VSUM_MUL",LINEAR_VSUM_MUL; +"LINEAR_ZERO",LINEAR_ZERO; +"LINEPATH_CX",LINEPATH_CX; +"LINEPATH_IN_PATH",LINEPATH_IN_PATH; +"LINEPATH_LINEAR_IMAGE",LINEPATH_LINEAR_IMAGE; +"LINEPATH_REFL",LINEPATH_REFL; +"LINEPATH_TRANSLATION",LINEPATH_TRANSLATION; +"LINSEG_FL",LINSEG_FL; +"LINSEG_INSEG",LINSEG_INSEG; +"LINSEG_WOSET",LINSEG_WOSET; +"LIOUVILLE_THEOREM",LIOUVILLE_THEOREM; +"LIOUVILLE_WEAK",LIOUVILLE_WEAK; +"LIOUVILLE_WEAK_INVERSE",LIOUVILLE_WEAK_INVERSE; +"LIPSCHITZ_REAL_POLYNOMIAL_FUNCTION",LIPSCHITZ_REAL_POLYNOMIAL_FUNCTION; +"LIPSCHITZ_VECTOR_POLYNOMIAL_FUNCTION",LIPSCHITZ_VECTOR_POLYNOMIAL_FUNCTION; +"LIST_OF_SET_PROPERTIES",LIST_OF_SET_PROPERTIES; +"LITTLE_PICARD",LITTLE_PICARD; +"LOCALLY_CLOSED",LOCALLY_CLOSED; +"LOCALLY_COMPACT",LOCALLY_COMPACT; +"LOCALLY_COMPACT_CLOSED_IN",LOCALLY_COMPACT_CLOSED_IN; +"LOCALLY_COMPACT_CLOSED_IN_OPEN",LOCALLY_COMPACT_CLOSED_IN_OPEN; +"LOCALLY_COMPACT_HOMEOMORPHIC_CLOSED",LOCALLY_COMPACT_HOMEOMORPHIC_CLOSED; +"LOCALLY_COMPACT_HOMEOMORPHISM_PROJECTION_CLOSED",LOCALLY_COMPACT_HOMEOMORPHISM_PROJECTION_CLOSED; +"LOCALLY_COMPACT_INTER",LOCALLY_COMPACT_INTER; +"LOCALLY_COMPACT_LINEAR_IMAGE_EQ",LOCALLY_COMPACT_LINEAR_IMAGE_EQ; +"LOCALLY_COMPACT_OPEN_IN",LOCALLY_COMPACT_OPEN_IN; +"LOCALLY_COMPACT_OPEN_INTER_CLOSURE",LOCALLY_COMPACT_OPEN_INTER_CLOSURE; +"LOCALLY_COMPACT_TRANSLATION_EQ",LOCALLY_COMPACT_TRANSLATION_EQ; +"LOCALLY_COMPACT_UNIV",LOCALLY_COMPACT_UNIV; +"LOCALLY_CONNECTED",LOCALLY_CONNECTED; +"LOCALLY_CONNECTED_COMPONENTS",LOCALLY_CONNECTED_COMPONENTS; +"LOCALLY_CONNECTED_CONNECTED_COMPONENT",LOCALLY_CONNECTED_CONNECTED_COMPONENT; +"LOCALLY_CONNECTED_CONTINUOUS_IMAGE_COMPACT",LOCALLY_CONNECTED_CONTINUOUS_IMAGE_COMPACT; +"LOCALLY_CONNECTED_IM_KLEINEN",LOCALLY_CONNECTED_IM_KLEINEN; +"LOCALLY_CONNECTED_LEFT_INVERTIBLE_IMAGE",LOCALLY_CONNECTED_LEFT_INVERTIBLE_IMAGE; +"LOCALLY_CONNECTED_LINEAR_IMAGE_EQ",LOCALLY_CONNECTED_LINEAR_IMAGE_EQ; +"LOCALLY_CONNECTED_OPEN_COMPONENT",LOCALLY_CONNECTED_OPEN_COMPONENT; +"LOCALLY_CONNECTED_OPEN_CONNECTED_COMPONENT",LOCALLY_CONNECTED_OPEN_CONNECTED_COMPONENT; +"LOCALLY_CONNECTED_PATH_IMAGE",LOCALLY_CONNECTED_PATH_IMAGE; +"LOCALLY_CONNECTED_PCROSS",LOCALLY_CONNECTED_PCROSS; +"LOCALLY_CONNECTED_PCROSS_EQ",LOCALLY_CONNECTED_PCROSS_EQ; +"LOCALLY_CONNECTED_QUOTIENT_IMAGE",LOCALLY_CONNECTED_QUOTIENT_IMAGE; +"LOCALLY_CONNECTED_RIGHT_INVERTIBLE_IMAGE",LOCALLY_CONNECTED_RIGHT_INVERTIBLE_IMAGE; +"LOCALLY_CONNECTED_SPHERE",LOCALLY_CONNECTED_SPHERE; +"LOCALLY_CONNECTED_SPHERE_GEN",LOCALLY_CONNECTED_SPHERE_GEN; +"LOCALLY_CONNECTED_TRANSLATION_EQ",LOCALLY_CONNECTED_TRANSLATION_EQ; +"LOCALLY_CONNECTED_UNIV",LOCALLY_CONNECTED_UNIV; +"LOCALLY_DIFF_CLOSED",LOCALLY_DIFF_CLOSED; +"LOCALLY_EMPTY",LOCALLY_EMPTY; +"LOCALLY_INJECTIVE_LINEAR_IMAGE",LOCALLY_INJECTIVE_LINEAR_IMAGE; +"LOCALLY_INTER",LOCALLY_INTER; +"LOCALLY_MONO",LOCALLY_MONO; +"LOCALLY_OPEN_MAP_IMAGE",LOCALLY_OPEN_MAP_IMAGE; +"LOCALLY_OPEN_SUBSET",LOCALLY_OPEN_SUBSET; +"LOCALLY_PATH_CONNECTED",LOCALLY_PATH_CONNECTED; +"LOCALLY_PATH_CONNECTED_COMPONENTS",LOCALLY_PATH_CONNECTED_COMPONENTS; +"LOCALLY_PATH_CONNECTED_CONNECTED_COMPONENT",LOCALLY_PATH_CONNECTED_CONNECTED_COMPONENT; +"LOCALLY_PATH_CONNECTED_CONTINUOUS_IMAGE_COMPACT",LOCALLY_PATH_CONNECTED_CONTINUOUS_IMAGE_COMPACT; +"LOCALLY_PATH_CONNECTED_IMP_LOCALLY_CONNECTED",LOCALLY_PATH_CONNECTED_IMP_LOCALLY_CONNECTED; +"LOCALLY_PATH_CONNECTED_IM_KLEINEN",LOCALLY_PATH_CONNECTED_IM_KLEINEN; +"LOCALLY_PATH_CONNECTED_LEFT_INVERTIBLE_IMAGE",LOCALLY_PATH_CONNECTED_LEFT_INVERTIBLE_IMAGE; +"LOCALLY_PATH_CONNECTED_LINEAR_IMAGE_EQ",LOCALLY_PATH_CONNECTED_LINEAR_IMAGE_EQ; +"LOCALLY_PATH_CONNECTED_OPEN_PATH_COMPONENT",LOCALLY_PATH_CONNECTED_OPEN_PATH_COMPONENT; +"LOCALLY_PATH_CONNECTED_PATH_COMPONENT",LOCALLY_PATH_CONNECTED_PATH_COMPONENT; +"LOCALLY_PATH_CONNECTED_PATH_IMAGE",LOCALLY_PATH_CONNECTED_PATH_IMAGE; +"LOCALLY_PATH_CONNECTED_PCROSS",LOCALLY_PATH_CONNECTED_PCROSS; +"LOCALLY_PATH_CONNECTED_PCROSS_EQ",LOCALLY_PATH_CONNECTED_PCROSS_EQ; +"LOCALLY_PATH_CONNECTED_QUOTIENT_IMAGE",LOCALLY_PATH_CONNECTED_QUOTIENT_IMAGE; +"LOCALLY_PATH_CONNECTED_RIGHT_INVERTIBLE_IMAGE",LOCALLY_PATH_CONNECTED_RIGHT_INVERTIBLE_IMAGE; +"LOCALLY_PATH_CONNECTED_SPHERE",LOCALLY_PATH_CONNECTED_SPHERE; +"LOCALLY_PATH_CONNECTED_SPHERE_GEN",LOCALLY_PATH_CONNECTED_SPHERE_GEN; +"LOCALLY_PATH_CONNECTED_TRANSLATION_EQ",LOCALLY_PATH_CONNECTED_TRANSLATION_EQ; +"LOCALLY_PATH_CONNECTED_UNIV",LOCALLY_PATH_CONNECTED_UNIV; +"LOCALLY_PCROSS",LOCALLY_PCROSS; +"LOCALLY_SING",LOCALLY_SING; +"LOCALLY_TRANSLATION",LOCALLY_TRANSLATION; +"LOG_1",LOG_1; +"LOG_DIV",LOG_DIV; +"LOG_EXP",LOG_EXP; +"LOG_INJ",LOG_INJ; +"LOG_INV",LOG_INV; +"LOG_LE",LOG_LE; +"LOG_LT_X",LOG_LT_X; +"LOG_MONO_LE",LOG_MONO_LE; +"LOG_MONO_LE_IMP",LOG_MONO_LE_IMP; +"LOG_MONO_LT",LOG_MONO_LT; +"LOG_MONO_LT_IMP",LOG_MONO_LT_IMP; +"LOG_MUL",LOG_MUL; +"LOG_POS",LOG_POS; +"LOG_POS_LT",LOG_POS_LT; +"LOG_POW",LOG_POW; +"LOG_ROOT",LOG_ROOT; +"LOWDIM_EQ_HYPERPLANE",LOWDIM_EQ_HYPERPLANE; +"LOWDIM_EXPAND_BASIS",LOWDIM_EXPAND_BASIS; +"LOWDIM_EXPAND_DIMENSION",LOWDIM_EXPAND_DIMENSION; +"LOWDIM_SUBSET_HYPERPLANE",LOWDIM_SUBSET_HYPERPLANE; +"LOWER_BOUND_FINITE_SET",LOWER_BOUND_FINITE_SET; +"LOWER_BOUND_FINITE_SET_REAL",LOWER_BOUND_FINITE_SET_REAL; +"LT",LT; +"LTE_ADD2",LTE_ADD2; +"LTE_ANTISYM",LTE_ANTISYM; +"LTE_CASES",LTE_CASES; +"LTE_TRANS",LTE_TRANS; +"LT_0",LT_0; +"LT_ADD",LT_ADD; +"LT_ADD2",LT_ADD2; +"LT_ADDR",LT_ADDR; +"LT_ADD_LCANCEL",LT_ADD_LCANCEL; +"LT_ADD_RCANCEL",LT_ADD_RCANCEL; +"LT_ANTISYM",LT_ANTISYM; +"LT_CASES",LT_CASES; +"LT_EXISTS",LT_EXISTS; +"LT_EXP",LT_EXP; +"LT_IMP_LE",LT_IMP_LE; +"LT_LE",LT_LE; +"LT_LMULT",LT_LMULT; +"LT_MULT",LT_MULT; +"LT_MULT2",LT_MULT2; +"LT_MULT_LCANCEL",LT_MULT_LCANCEL; +"LT_MULT_RCANCEL",LT_MULT_RCANCEL; +"LT_NZ",LT_NZ; +"LT_POW2_REFL",LT_POW2_REFL; +"LT_REFL",LT_REFL; +"LT_SUC",LT_SUC; +"LT_SUC_LE",LT_SUC_LE; +"LT_TRANS",LT_TRANS; +"LUZIN",LUZIN; +"LUZIN_EQ",LUZIN_EQ; +"LUZIN_EQ_ALT",LUZIN_EQ_ALT; +"MAP",MAP; +"MAP2",MAP2; +"MAP2_DEF",MAP2_DEF; +"MAP_APPEND",MAP_APPEND; +"MAP_EQ",MAP_EQ; +"MAP_EQ_ALL2",MAP_EQ_ALL2; +"MAP_EQ_DEGEN",MAP_EQ_DEGEN; +"MAP_EQ_NIL",MAP_EQ_NIL; +"MAP_FST_ZIP",MAP_FST_ZIP; +"MAP_I",MAP_I; +"MAP_ID",MAP_ID; +"MAP_REVERSE",MAP_REVERSE; +"MAP_SND_ZIP",MAP_SND_ZIP; +"MAP_o",MAP_o; +"MATCH_SEQPATTERN",MATCH_SEQPATTERN; +"MATRIX_ADD_AC",MATRIX_ADD_AC; +"MATRIX_ADD_ASSOC",MATRIX_ADD_ASSOC; +"MATRIX_ADD_COMPONENT",MATRIX_ADD_COMPONENT; +"MATRIX_ADD_LDISTRIB",MATRIX_ADD_LDISTRIB; +"MATRIX_ADD_LID",MATRIX_ADD_LID; +"MATRIX_ADD_LNEG",MATRIX_ADD_LNEG; +"MATRIX_ADD_RDISTRIB",MATRIX_ADD_RDISTRIB; +"MATRIX_ADD_RID",MATRIX_ADD_RID; +"MATRIX_ADD_RNEG",MATRIX_ADD_RNEG; +"MATRIX_ADD_SYM",MATRIX_ADD_SYM; +"MATRIX_ADJOINT",MATRIX_ADJOINT; +"MATRIX_CMUL_ADD_LDISTRIB",MATRIX_CMUL_ADD_LDISTRIB; +"MATRIX_CMUL_ADD_RDISTRIB",MATRIX_CMUL_ADD_RDISTRIB; +"MATRIX_CMUL_ASSOC",MATRIX_CMUL_ASSOC; +"MATRIX_CMUL_COMPONENT",MATRIX_CMUL_COMPONENT; +"MATRIX_CMUL_LID",MATRIX_CMUL_LID; +"MATRIX_CMUL_LZERO",MATRIX_CMUL_LZERO; +"MATRIX_CMUL_RZERO",MATRIX_CMUL_RZERO; +"MATRIX_CMUL_SUB_LDISTRIB",MATRIX_CMUL_SUB_LDISTRIB; +"MATRIX_CMUL_SUB_RDISTRIB",MATRIX_CMUL_SUB_RDISTRIB; +"MATRIX_COMPOSE",MATRIX_COMPOSE; +"MATRIX_EQ",MATRIX_EQ; +"MATRIX_EQUAL_COLUMNS",MATRIX_EQUAL_COLUMNS; +"MATRIX_EQUAL_ROWS",MATRIX_EQUAL_ROWS; +"MATRIX_FULL_LINEAR_EQUATIONS",MATRIX_FULL_LINEAR_EQUATIONS; +"MATRIX_I",MATRIX_I; +"MATRIX_ID",MATRIX_ID; +"MATRIX_INV",MATRIX_INV; +"MATRIX_INVERTIBLE",MATRIX_INVERTIBLE; +"MATRIX_INV_COFACTOR",MATRIX_INV_COFACTOR; +"MATRIX_INV_I",MATRIX_INV_I; +"MATRIX_INV_MUL",MATRIX_INV_MUL; +"MATRIX_INV_UNIQUE",MATRIX_INV_UNIQUE; +"MATRIX_INV_UNIQUE_LEFT",MATRIX_INV_UNIQUE_LEFT; +"MATRIX_INV_UNIQUE_RIGHT",MATRIX_INV_UNIQUE_RIGHT; +"MATRIX_LEFT_INVERSE_COFACTOR",MATRIX_LEFT_INVERSE_COFACTOR; +"MATRIX_LEFT_INVERTIBLE",MATRIX_LEFT_INVERTIBLE; +"MATRIX_LEFT_INVERTIBLE_INDEPENDENT_COLUMNS",MATRIX_LEFT_INVERTIBLE_INDEPENDENT_COLUMNS; +"MATRIX_LEFT_INVERTIBLE_INJECTIVE",MATRIX_LEFT_INVERTIBLE_INJECTIVE; +"MATRIX_LEFT_INVERTIBLE_KER",MATRIX_LEFT_INVERTIBLE_KER; +"MATRIX_LEFT_INVERTIBLE_SPAN_ROWS",MATRIX_LEFT_INVERTIBLE_SPAN_ROWS; +"MATRIX_LEFT_RIGHT_INVERSE",MATRIX_LEFT_RIGHT_INVERSE; +"MATRIX_MUL_ASSOC",MATRIX_MUL_ASSOC; +"MATRIX_MUL_COMPONENT",MATRIX_MUL_COMPONENT; +"MATRIX_MUL_DOT",MATRIX_MUL_DOT; +"MATRIX_MUL_LEFT_COFACTOR",MATRIX_MUL_LEFT_COFACTOR; +"MATRIX_MUL_LID",MATRIX_MUL_LID; +"MATRIX_MUL_LINV",MATRIX_MUL_LINV; +"MATRIX_MUL_LMUL",MATRIX_MUL_LMUL; +"MATRIX_MUL_LNEG",MATRIX_MUL_LNEG; +"MATRIX_MUL_LTRANSP_DOT_COLUMN",MATRIX_MUL_LTRANSP_DOT_COLUMN; +"MATRIX_MUL_LZERO",MATRIX_MUL_LZERO; +"MATRIX_MUL_RID",MATRIX_MUL_RID; +"MATRIX_MUL_RIGHT_COFACTOR",MATRIX_MUL_RIGHT_COFACTOR; +"MATRIX_MUL_RINV",MATRIX_MUL_RINV; +"MATRIX_MUL_RMUL",MATRIX_MUL_RMUL; +"MATRIX_MUL_RNEG",MATRIX_MUL_RNEG; +"MATRIX_MUL_RTRANSP_DOT_ROW",MATRIX_MUL_RTRANSP_DOT_ROW; +"MATRIX_MUL_RZERO",MATRIX_MUL_RZERO; +"MATRIX_MUL_VSUM",MATRIX_MUL_VSUM; +"MATRIX_MUL_VSUM_ALT",MATRIX_MUL_VSUM_ALT; +"MATRIX_NEG_0",MATRIX_NEG_0; +"MATRIX_NEG_ADD",MATRIX_NEG_ADD; +"MATRIX_NEG_COMPONENT",MATRIX_NEG_COMPONENT; +"MATRIX_NEG_EQ_0",MATRIX_NEG_EQ_0; +"MATRIX_NEG_MINUS1",MATRIX_NEG_MINUS1; +"MATRIX_NEG_NEG",MATRIX_NEG_NEG; +"MATRIX_NEG_SUB",MATRIX_NEG_SUB; +"MATRIX_NONFULL_LINEAR_EQUATIONS",MATRIX_NONFULL_LINEAR_EQUATIONS; +"MATRIX_NONFULL_LINEAR_EQUATIONS_EQ",MATRIX_NONFULL_LINEAR_EQUATIONS_EQ; +"MATRIX_OF_MATRIX_VECTOR_MUL",MATRIX_OF_MATRIX_VECTOR_MUL; +"MATRIX_REFLECT_ALONG_BASIS",MATRIX_REFLECT_ALONG_BASIS; +"MATRIX_RIGHT_INVERSE_COFACTOR",MATRIX_RIGHT_INVERSE_COFACTOR; +"MATRIX_RIGHT_INVERTIBLE",MATRIX_RIGHT_INVERTIBLE; +"MATRIX_RIGHT_INVERTIBLE_INDEPENDENT_ROWS",MATRIX_RIGHT_INVERTIBLE_INDEPENDENT_ROWS; +"MATRIX_RIGHT_INVERTIBLE_SPAN_COLUMNS",MATRIX_RIGHT_INVERTIBLE_SPAN_COLUMNS; +"MATRIX_RIGHT_INVERTIBLE_SURJECTIVE",MATRIX_RIGHT_INVERTIBLE_SURJECTIVE; +"MATRIX_ROTATE2D",MATRIX_ROTATE2D; +"MATRIX_SELF_ADJOINT",MATRIX_SELF_ADJOINT; +"MATRIX_SUB",MATRIX_SUB; +"MATRIX_SUB_COMPONENT",MATRIX_SUB_COMPONENT; +"MATRIX_SUB_LDISTRIB",MATRIX_SUB_LDISTRIB; +"MATRIX_SUB_LZERO",MATRIX_SUB_LZERO; +"MATRIX_SUB_RDISTRIB",MATRIX_SUB_RDISTRIB; +"MATRIX_SUB_REFL",MATRIX_SUB_REFL; +"MATRIX_SUB_RZERO",MATRIX_SUB_RZERO; +"MATRIX_TRANSP_MUL",MATRIX_TRANSP_MUL; +"MATRIX_TRIVIAL_LINEAR_EQUATIONS",MATRIX_TRIVIAL_LINEAR_EQUATIONS; +"MATRIX_VECTOR_COLUMN",MATRIX_VECTOR_COLUMN; +"MATRIX_VECTOR_MUL",MATRIX_VECTOR_MUL; +"MATRIX_VECTOR_MUL_ADD_LDISTRIB",MATRIX_VECTOR_MUL_ADD_LDISTRIB; +"MATRIX_VECTOR_MUL_ADD_RDISTRIB",MATRIX_VECTOR_MUL_ADD_RDISTRIB; +"MATRIX_VECTOR_MUL_ASSOC",MATRIX_VECTOR_MUL_ASSOC; +"MATRIX_VECTOR_MUL_BASIS",MATRIX_VECTOR_MUL_BASIS; +"MATRIX_VECTOR_MUL_COMPONENT",MATRIX_VECTOR_MUL_COMPONENT; +"MATRIX_VECTOR_MUL_INJECTIVE_ON_ROWSPACE",MATRIX_VECTOR_MUL_INJECTIVE_ON_ROWSPACE; +"MATRIX_VECTOR_MUL_IN_COLUMNSPACE",MATRIX_VECTOR_MUL_IN_COLUMNSPACE; +"MATRIX_VECTOR_MUL_LID",MATRIX_VECTOR_MUL_LID; +"MATRIX_VECTOR_MUL_LINEAR",MATRIX_VECTOR_MUL_LINEAR; +"MATRIX_VECTOR_MUL_LZERO",MATRIX_VECTOR_MUL_LZERO; +"MATRIX_VECTOR_MUL_RMUL",MATRIX_VECTOR_MUL_RMUL; +"MATRIX_VECTOR_MUL_RZERO",MATRIX_VECTOR_MUL_RZERO; +"MATRIX_VECTOR_MUL_SUB_LDISTRIB",MATRIX_VECTOR_MUL_SUB_LDISTRIB; +"MATRIX_VECTOR_MUL_SUB_RDISTRIB",MATRIX_VECTOR_MUL_SUB_RDISTRIB; +"MATRIX_VECTOR_MUL_TRANSP",MATRIX_VECTOR_MUL_TRANSP; +"MATRIX_WLOG_INVERTIBLE",MATRIX_WLOG_INVERTIBLE; +"MATRIX_WORKS",MATRIX_WORKS; +"MAT_0_COMPONENT",MAT_0_COMPONENT; +"MAT_COMPONENT",MAT_COMPONENT; +"MAX",MAX; +"MAXIMAL_AFFINE_INDEPENDENT_SUBSET",MAXIMAL_AFFINE_INDEPENDENT_SUBSET; +"MAXIMAL_AFFINE_INDEPENDENT_SUBSET_AFFINE",MAXIMAL_AFFINE_INDEPENDENT_SUBSET_AFFINE; +"MAXIMAL_INDEPENDENT_SUBSET",MAXIMAL_INDEPENDENT_SUBSET; +"MAXIMAL_INDEPENDENT_SUBSET_EXTEND",MAXIMAL_INDEPENDENT_SUBSET_EXTEND; +"MAXIMUM_MODULUS_PRINCIPLE",MAXIMUM_MODULUS_PRINCIPLE; +"MBASIS_COMPONENT",MBASIS_COMPONENT; +"MBASIS_EQ_0",MBASIS_EQ_0; +"MBASIS_EXPANSION",MBASIS_EXPANSION; +"MBASIS_EXTENSION",MBASIS_EXTENSION; +"MBASIS_NONZERO",MBASIS_NONZERO; +"MBASIS_SPLIT",MBASIS_SPLIT; +"MEASURABLE",MEASURABLE; +"MEASURABLE_ADDITIVE_IMP_LINEAR",MEASURABLE_ADDITIVE_IMP_LINEAR; +"MEASURABLE_ALMOST",MEASURABLE_ALMOST; +"MEASURABLE_BALL",MEASURABLE_BALL; +"MEASURABLE_BOUNDED_BY_INTEGRABLE_IMP_ABSOLUTELY_INTEGRABLE",MEASURABLE_BOUNDED_BY_INTEGRABLE_IMP_ABSOLUTELY_INTEGRABLE; +"MEASURABLE_BOUNDED_BY_INTEGRABLE_IMP_INTEGRABLE",MEASURABLE_BOUNDED_BY_INTEGRABLE_IMP_INTEGRABLE; +"MEASURABLE_CBALL",MEASURABLE_CBALL; +"MEASURABLE_CLOSURE",MEASURABLE_CLOSURE; +"MEASURABLE_COMPACT",MEASURABLE_COMPACT; +"MEASURABLE_CONVEX",MEASURABLE_CONVEX; +"MEASURABLE_CONVEX_HULL",MEASURABLE_CONVEX_HULL; +"MEASURABLE_COUNTABLE_INTERS",MEASURABLE_COUNTABLE_INTERS; +"MEASURABLE_COUNTABLE_INTERS_GEN",MEASURABLE_COUNTABLE_INTERS_GEN; +"MEASURABLE_COUNTABLE_UNIONS",MEASURABLE_COUNTABLE_UNIONS; +"MEASURABLE_COUNTABLE_UNIONS_BOUNDED",MEASURABLE_COUNTABLE_UNIONS_BOUNDED; +"MEASURABLE_COUNTABLE_UNIONS_STRONG",MEASURABLE_COUNTABLE_UNIONS_STRONG; +"MEASURABLE_DIFF",MEASURABLE_DIFF; +"MEASURABLE_ELEMENTARY",MEASURABLE_ELEMENTARY; +"MEASURABLE_EMPTY",MEASURABLE_EMPTY; +"MEASURABLE_FRONTIER",MEASURABLE_FRONTIER; +"MEASURABLE_IMP_LEBESGUE_MEASURABLE",MEASURABLE_IMP_LEBESGUE_MEASURABLE; +"MEASURABLE_INNER_COMPACT",MEASURABLE_INNER_COMPACT; +"MEASURABLE_INNER_OUTER",MEASURABLE_INNER_OUTER; +"MEASURABLE_INSERT",MEASURABLE_INSERT; +"MEASURABLE_INSIDE",MEASURABLE_INSIDE; +"MEASURABLE_INTEGRABLE",MEASURABLE_INTEGRABLE; +"MEASURABLE_INTER",MEASURABLE_INTER; +"MEASURABLE_INTERIOR",MEASURABLE_INTERIOR; +"MEASURABLE_INTERVAL",MEASURABLE_INTERVAL; +"MEASURABLE_INTER_HALFSPACE_GE",MEASURABLE_INTER_HALFSPACE_GE; +"MEASURABLE_INTER_HALFSPACE_LE",MEASURABLE_INTER_HALFSPACE_LE; +"MEASURABLE_INTER_INTERVAL",MEASURABLE_INTER_INTERVAL; +"MEASURABLE_JORDAN",MEASURABLE_JORDAN; +"MEASURABLE_LEGESGUE_MEASURABLE_INTER_MEASURABLE",MEASURABLE_LEGESGUE_MEASURABLE_INTER_MEASURABLE; +"MEASURABLE_LEGESGUE_MEASURABLE_SUBSET",MEASURABLE_LEGESGUE_MEASURABLE_SUBSET; +"MEASURABLE_LINEAR_IMAGE",MEASURABLE_LINEAR_IMAGE; +"MEASURABLE_LINEAR_IMAGE_EQ",MEASURABLE_LINEAR_IMAGE_EQ; +"MEASURABLE_LINEAR_IMAGE_INTERVAL",MEASURABLE_LINEAR_IMAGE_INTERVAL; +"MEASURABLE_MEASURABLE_DIFF_LEGESGUE_MEASURABLE",MEASURABLE_MEASURABLE_DIFF_LEGESGUE_MEASURABLE; +"MEASURABLE_MEASURABLE_INTER_LEGESGUE_MEASURABLE",MEASURABLE_MEASURABLE_INTER_LEGESGUE_MEASURABLE; +"MEASURABLE_MEASURABLE_PREIMAGE_CLOSED",MEASURABLE_MEASURABLE_PREIMAGE_CLOSED; +"MEASURABLE_MEASURABLE_PREIMAGE_OPEN",MEASURABLE_MEASURABLE_PREIMAGE_OPEN; +"MEASURABLE_MEASURE_EQ_0",MEASURABLE_MEASURE_EQ_0; +"MEASURABLE_MEASURE_POS_LT",MEASURABLE_MEASURE_POS_LT; +"MEASURABLE_NEGLIGIBLE_SYMDIFF",MEASURABLE_NEGLIGIBLE_SYMDIFF; +"MEASURABLE_NEGLIGIBLE_SYMDIFF_EQ",MEASURABLE_NEGLIGIBLE_SYMDIFF_EQ; +"MEASURABLE_NESTED_UNIONS",MEASURABLE_NESTED_UNIONS; +"MEASURABLE_NONNEGLIGIBLE_IMP_LARGE",MEASURABLE_NONNEGLIGIBLE_IMP_LARGE; +"MEASURABLE_ON_0",MEASURABLE_ON_0; +"MEASURABLE_ON_ADD",MEASURABLE_ON_ADD; +"MEASURABLE_ON_CASES",MEASURABLE_ON_CASES; +"MEASURABLE_ON_CMUL",MEASURABLE_ON_CMUL; +"MEASURABLE_ON_COMBINE",MEASURABLE_ON_COMBINE; +"MEASURABLE_ON_COMPLEX_DIV",MEASURABLE_ON_COMPLEX_DIV; +"MEASURABLE_ON_COMPLEX_INV",MEASURABLE_ON_COMPLEX_INV; +"MEASURABLE_ON_COMPLEX_MUL",MEASURABLE_ON_COMPLEX_MUL; +"MEASURABLE_ON_COMPONENTWISE",MEASURABLE_ON_COMPONENTWISE; +"MEASURABLE_ON_COMPOSE_CONTINUOUS",MEASURABLE_ON_COMPOSE_CONTINUOUS; +"MEASURABLE_ON_COMPOSE_CONTINUOUS_0",MEASURABLE_ON_COMPOSE_CONTINUOUS_0; +"MEASURABLE_ON_COMPOSE_CONTINUOUS_CLOSED_SET",MEASURABLE_ON_COMPOSE_CONTINUOUS_CLOSED_SET; +"MEASURABLE_ON_COMPOSE_CONTINUOUS_CLOSED_SET_0",MEASURABLE_ON_COMPOSE_CONTINUOUS_CLOSED_SET_0; +"MEASURABLE_ON_COMPOSE_CONTINUOUS_OPEN_INTERVAL",MEASURABLE_ON_COMPOSE_CONTINUOUS_OPEN_INTERVAL; +"MEASURABLE_ON_CONST",MEASURABLE_ON_CONST; +"MEASURABLE_ON_COUNTABLE_UNIONS",MEASURABLE_ON_COUNTABLE_UNIONS; +"MEASURABLE_ON_DIFF",MEASURABLE_ON_DIFF; +"MEASURABLE_ON_DROP_MUL",MEASURABLE_ON_DROP_MUL; +"MEASURABLE_ON_EMPTY",MEASURABLE_ON_EMPTY; +"MEASURABLE_ON_INTER",MEASURABLE_ON_INTER; +"MEASURABLE_ON_LEBESGUE_MEASURABLE_PREIMAGE_CLOSED",MEASURABLE_ON_LEBESGUE_MEASURABLE_PREIMAGE_CLOSED; +"MEASURABLE_ON_LEBESGUE_MEASURABLE_PREIMAGE_CLOSED_EQ",MEASURABLE_ON_LEBESGUE_MEASURABLE_PREIMAGE_CLOSED_EQ; +"MEASURABLE_ON_LEBESGUE_MEASURABLE_PREIMAGE_CLOSED_INTERVAL",MEASURABLE_ON_LEBESGUE_MEASURABLE_PREIMAGE_CLOSED_INTERVAL; +"MEASURABLE_ON_LEBESGUE_MEASURABLE_PREIMAGE_OPEN",MEASURABLE_ON_LEBESGUE_MEASURABLE_PREIMAGE_OPEN; +"MEASURABLE_ON_LEBESGUE_MEASURABLE_PREIMAGE_OPEN_EQ",MEASURABLE_ON_LEBESGUE_MEASURABLE_PREIMAGE_OPEN_EQ; +"MEASURABLE_ON_LEBESGUE_MEASURABLE_PREIMAGE_OPEN_HALFSPACE_COMPONENT_GE",MEASURABLE_ON_LEBESGUE_MEASURABLE_PREIMAGE_OPEN_HALFSPACE_COMPONENT_GE; +"MEASURABLE_ON_LEBESGUE_MEASURABLE_PREIMAGE_OPEN_HALFSPACE_COMPONENT_GT",MEASURABLE_ON_LEBESGUE_MEASURABLE_PREIMAGE_OPEN_HALFSPACE_COMPONENT_GT; +"MEASURABLE_ON_LEBESGUE_MEASURABLE_PREIMAGE_OPEN_HALFSPACE_COMPONENT_LE",MEASURABLE_ON_LEBESGUE_MEASURABLE_PREIMAGE_OPEN_HALFSPACE_COMPONENT_LE; +"MEASURABLE_ON_LEBESGUE_MEASURABLE_PREIMAGE_OPEN_HALFSPACE_COMPONENT_LT",MEASURABLE_ON_LEBESGUE_MEASURABLE_PREIMAGE_OPEN_HALFSPACE_COMPONENT_LT; +"MEASURABLE_ON_LEBESGUE_MEASURABLE_PREIMAGE_OPEN_INTERVAL",MEASURABLE_ON_LEBESGUE_MEASURABLE_PREIMAGE_OPEN_INTERVAL; +"MEASURABLE_ON_LEBESGUE_MEASURABLE_SUBSET",MEASURABLE_ON_LEBESGUE_MEASURABLE_SUBSET; +"MEASURABLE_ON_LIFT_MUL",MEASURABLE_ON_LIFT_MUL; +"MEASURABLE_ON_LIMIT",MEASURABLE_ON_LIMIT; +"MEASURABLE_ON_LINEAR_IMAGE_EQ",MEASURABLE_ON_LINEAR_IMAGE_EQ; +"MEASURABLE_ON_MAX",MEASURABLE_ON_MAX; +"MEASURABLE_ON_MEASURABLE_PREIMAGE_CLOSED",MEASURABLE_ON_MEASURABLE_PREIMAGE_CLOSED; +"MEASURABLE_ON_MEASURABLE_PREIMAGE_CLOSED_EQ",MEASURABLE_ON_MEASURABLE_PREIMAGE_CLOSED_EQ; +"MEASURABLE_ON_MEASURABLE_PREIMAGE_CLOSED_INTERVAL",MEASURABLE_ON_MEASURABLE_PREIMAGE_CLOSED_INTERVAL; +"MEASURABLE_ON_MEASURABLE_PREIMAGE_OPEN",MEASURABLE_ON_MEASURABLE_PREIMAGE_OPEN; +"MEASURABLE_ON_MEASURABLE_PREIMAGE_OPEN_EQ",MEASURABLE_ON_MEASURABLE_PREIMAGE_OPEN_EQ; +"MEASURABLE_ON_MEASURABLE_PREIMAGE_OPEN_HALFSPACE_COMPONENT_GE",MEASURABLE_ON_MEASURABLE_PREIMAGE_OPEN_HALFSPACE_COMPONENT_GE; +"MEASURABLE_ON_MEASURABLE_PREIMAGE_OPEN_HALFSPACE_COMPONENT_GT",MEASURABLE_ON_MEASURABLE_PREIMAGE_OPEN_HALFSPACE_COMPONENT_GT; +"MEASURABLE_ON_MEASURABLE_PREIMAGE_OPEN_HALFSPACE_COMPONENT_LE",MEASURABLE_ON_MEASURABLE_PREIMAGE_OPEN_HALFSPACE_COMPONENT_LE; +"MEASURABLE_ON_MEASURABLE_PREIMAGE_OPEN_HALFSPACE_COMPONENT_LT",MEASURABLE_ON_MEASURABLE_PREIMAGE_OPEN_HALFSPACE_COMPONENT_LT; +"MEASURABLE_ON_MEASURABLE_PREIMAGE_OPEN_INTERVAL",MEASURABLE_ON_MEASURABLE_PREIMAGE_OPEN_INTERVAL; +"MEASURABLE_ON_MEASURABLE_SUBSET",MEASURABLE_ON_MEASURABLE_SUBSET; +"MEASURABLE_ON_MIN",MEASURABLE_ON_MIN; +"MEASURABLE_ON_NEG",MEASURABLE_ON_NEG; +"MEASURABLE_ON_NEG_EQ",MEASURABLE_ON_NEG_EQ; +"MEASURABLE_ON_NORM",MEASURABLE_ON_NORM; +"MEASURABLE_ON_PASTECART",MEASURABLE_ON_PASTECART; +"MEASURABLE_ON_PREIMAGE_CLOSED",MEASURABLE_ON_PREIMAGE_CLOSED; +"MEASURABLE_ON_PREIMAGE_CLOSED_INTERVAL",MEASURABLE_ON_PREIMAGE_CLOSED_INTERVAL; +"MEASURABLE_ON_PREIMAGE_OPEN",MEASURABLE_ON_PREIMAGE_OPEN; +"MEASURABLE_ON_PREIMAGE_OPEN_HALFSPACE_COMPONENT_GE",MEASURABLE_ON_PREIMAGE_OPEN_HALFSPACE_COMPONENT_GE; +"MEASURABLE_ON_PREIMAGE_OPEN_HALFSPACE_COMPONENT_GT",MEASURABLE_ON_PREIMAGE_OPEN_HALFSPACE_COMPONENT_GT; +"MEASURABLE_ON_PREIMAGE_OPEN_HALFSPACE_COMPONENT_LE",MEASURABLE_ON_PREIMAGE_OPEN_HALFSPACE_COMPONENT_LE; +"MEASURABLE_ON_PREIMAGE_OPEN_HALFSPACE_COMPONENT_LT",MEASURABLE_ON_PREIMAGE_OPEN_HALFSPACE_COMPONENT_LT; +"MEASURABLE_ON_PREIMAGE_OPEN_INTERVAL",MEASURABLE_ON_PREIMAGE_OPEN_INTERVAL; +"MEASURABLE_ON_RESTRICT",MEASURABLE_ON_RESTRICT; +"MEASURABLE_ON_SIMPLE_FUNCTION_LIMIT",MEASURABLE_ON_SIMPLE_FUNCTION_LIMIT; +"MEASURABLE_ON_SPIKE",MEASURABLE_ON_SPIKE; +"MEASURABLE_ON_SPIKE_SET",MEASURABLE_ON_SPIKE_SET; +"MEASURABLE_ON_SUB",MEASURABLE_ON_SUB; +"MEASURABLE_ON_TRANSLATION",MEASURABLE_ON_TRANSLATION; +"MEASURABLE_ON_TRANSLATION_EQ",MEASURABLE_ON_TRANSLATION_EQ; +"MEASURABLE_ON_UNION",MEASURABLE_ON_UNION; +"MEASURABLE_ON_UNIONS",MEASURABLE_ON_UNIONS; +"MEASURABLE_ON_UNIV",MEASURABLE_ON_UNIV; +"MEASURABLE_ON_VECTOR_DERIVATIVE",MEASURABLE_ON_VECTOR_DERIVATIVE; +"MEASURABLE_ON_VSUM",MEASURABLE_ON_VSUM; +"MEASURABLE_OPEN",MEASURABLE_OPEN; +"MEASURABLE_OUTER_CLOSED_INTERVALS",MEASURABLE_OUTER_CLOSED_INTERVALS; +"MEASURABLE_OUTER_INTERVALS_BOUNDED",MEASURABLE_OUTER_INTERVALS_BOUNDED; +"MEASURABLE_OUTER_INTERVALS_BOUNDED_EXPLICIT_SPECIAL",MEASURABLE_OUTER_INTERVALS_BOUNDED_EXPLICIT_SPECIAL; +"MEASURABLE_OUTER_OPEN",MEASURABLE_OUTER_OPEN; +"MEASURABLE_OUTER_OPEN_INTERVALS",MEASURABLE_OUTER_OPEN_INTERVALS; +"MEASURABLE_SCALING",MEASURABLE_SCALING; +"MEASURABLE_SCALING_EQ",MEASURABLE_SCALING_EQ; +"MEASURABLE_SIMPLEX",MEASURABLE_SIMPLEX; +"MEASURABLE_SMALL_IMP_NEGLIGIBLE",MEASURABLE_SMALL_IMP_NEGLIGIBLE; +"MEASURABLE_TETRAHEDRON",MEASURABLE_TETRAHEDRON; +"MEASURABLE_TRANSLATION",MEASURABLE_TRANSLATION; +"MEASURABLE_TRANSLATION_EQ",MEASURABLE_TRANSLATION_EQ; +"MEASURABLE_TRIANGLE",MEASURABLE_TRIANGLE; +"MEASURABLE_UNION",MEASURABLE_UNION; +"MEASURABLE_UNIONS",MEASURABLE_UNIONS; +"MEASURE",MEASURE; +"MEASURE_BALL_BOUND",MEASURE_BALL_BOUND; +"MEASURE_BALL_POS",MEASURE_BALL_POS; +"MEASURE_CBALL_BOUND",MEASURE_CBALL_BOUND; +"MEASURE_CBALL_POS",MEASURE_CBALL_POS; +"MEASURE_CLOSURE",MEASURE_CLOSURE; +"MEASURE_COUNTABLE_UNIONS_APPROACHABLE",MEASURE_COUNTABLE_UNIONS_APPROACHABLE; +"MEASURE_COUNTABLE_UNIONS_LE",MEASURE_COUNTABLE_UNIONS_LE; +"MEASURE_COUNTABLE_UNIONS_LE_GEN",MEASURE_COUNTABLE_UNIONS_LE_GEN; +"MEASURE_COUNTABLE_UNIONS_LE_STRONG",MEASURE_COUNTABLE_UNIONS_LE_STRONG; +"MEASURE_COUNTABLE_UNIONS_LE_STRONG_GEN",MEASURE_COUNTABLE_UNIONS_LE_STRONG_GEN; +"MEASURE_DIFF_SUBSET",MEASURE_DIFF_SUBSET; +"MEASURE_DISJOINT_UNION",MEASURE_DISJOINT_UNION; +"MEASURE_DISJOINT_UNIONS",MEASURE_DISJOINT_UNIONS; +"MEASURE_DISJOINT_UNIONS_IMAGE",MEASURE_DISJOINT_UNIONS_IMAGE; +"MEASURE_DISJOINT_UNIONS_IMAGE_STRONG",MEASURE_DISJOINT_UNIONS_IMAGE_STRONG; +"MEASURE_DISJOINT_UNION_EQ",MEASURE_DISJOINT_UNION_EQ; +"MEASURE_ELEMENTARY",MEASURE_ELEMENTARY; +"MEASURE_EMPTY",MEASURE_EMPTY; +"MEASURE_EQ_0",MEASURE_EQ_0; +"MEASURE_FRONTIER",MEASURE_FRONTIER; +"MEASURE_INSERT",MEASURE_INSERT; +"MEASURE_INTEGRAL",MEASURE_INTEGRAL; +"MEASURE_INTEGRAL_UNIV",MEASURE_INTEGRAL_UNIV; +"MEASURE_INTERIOR",MEASURE_INTERIOR; +"MEASURE_INTERVAL",MEASURE_INTERVAL; +"MEASURE_INTERVAL_1",MEASURE_INTERVAL_1; +"MEASURE_INTERVAL_1_ALT",MEASURE_INTERVAL_1_ALT; +"MEASURE_INTERVAL_2",MEASURE_INTERVAL_2; +"MEASURE_INTERVAL_2_ALT",MEASURE_INTERVAL_2_ALT; +"MEASURE_INTERVAL_3",MEASURE_INTERVAL_3; +"MEASURE_INTERVAL_3_ALT",MEASURE_INTERVAL_3_ALT; +"MEASURE_INTERVAL_4",MEASURE_INTERVAL_4; +"MEASURE_INTERVAL_4_ALT",MEASURE_INTERVAL_4_ALT; +"MEASURE_LE",MEASURE_LE; +"MEASURE_LIMIT",MEASURE_LIMIT; +"MEASURE_LINEAR_IMAGE",MEASURE_LINEAR_IMAGE; +"MEASURE_LINEAR_IMAGE_SAME",MEASURE_LINEAR_IMAGE_SAME; +"MEASURE_NEGLIGIBLE_SYMDIFF",MEASURE_NEGLIGIBLE_SYMDIFF; +"MEASURE_NEGLIGIBLE_UNION",MEASURE_NEGLIGIBLE_UNION; +"MEASURE_NEGLIGIBLE_UNIONS",MEASURE_NEGLIGIBLE_UNIONS; +"MEASURE_NEGLIGIBLE_UNIONS_IMAGE",MEASURE_NEGLIGIBLE_UNIONS_IMAGE; +"MEASURE_NEGLIGIBLE_UNIONS_IMAGE_STRONG",MEASURE_NEGLIGIBLE_UNIONS_IMAGE_STRONG; +"MEASURE_NEGLIGIBLE_UNION_EQ",MEASURE_NEGLIGIBLE_UNION_EQ; +"MEASURE_OPEN_POS_LT",MEASURE_OPEN_POS_LT; +"MEASURE_ORTHOGONAL_IMAGE_EQ",MEASURE_ORTHOGONAL_IMAGE_EQ; +"MEASURE_POS_LE",MEASURE_POS_LE; +"MEASURE_SCALING",MEASURE_SCALING; +"MEASURE_SIMPLEX",MEASURE_SIMPLEX; +"MEASURE_SUBSET",MEASURE_SUBSET; +"MEASURE_TETRAHEDRON",MEASURE_TETRAHEDRON; +"MEASURE_TRANSLATION",MEASURE_TRANSLATION; +"MEASURE_TRIANGLE",MEASURE_TRIANGLE; +"MEASURE_UNION",MEASURE_UNION; +"MEASURE_UNIONS_LE",MEASURE_UNIONS_LE; +"MEASURE_UNIONS_LE_IMAGE",MEASURE_UNIONS_LE_IMAGE; +"MEASURE_UNION_LE",MEASURE_UNION_LE; +"MEASURE_UNIQUE",MEASURE_UNIQUE; +"MEM",MEM; +"MEMBER_NOT_EMPTY",MEMBER_NOT_EMPTY; +"MEM_APPEND",MEM_APPEND; +"MEM_APPEND_DECOMPOSE",MEM_APPEND_DECOMPOSE; +"MEM_APPEND_DECOMPOSE_LEFT",MEM_APPEND_DECOMPOSE_LEFT; +"MEM_ASSOC",MEM_ASSOC; +"MEM_EL",MEM_EL; +"MEM_EXISTS_EL",MEM_EXISTS_EL; +"MEM_FILTER",MEM_FILTER; +"MEM_LINEAR_IMAGE",MEM_LINEAR_IMAGE; +"MEM_LIST_OF_SET",MEM_LIST_OF_SET; +"MEM_MAP",MEM_MAP; +"MEM_TRANSLATION",MEM_TRANSLATION; +"MIDPOINTS_IN_CONVEX_HULL",MIDPOINTS_IN_CONVEX_HULL; +"MIDPOINT_BETWEEN",MIDPOINT_BETWEEN; +"MIDPOINT_COLLINEAR",MIDPOINT_COLLINEAR; +"MIDPOINT_CONVEX_DYADIC_RATIONALS",MIDPOINT_CONVEX_DYADIC_RATIONALS; +"MIDPOINT_EQ_ENDPOINT",MIDPOINT_EQ_ENDPOINT; +"MIDPOINT_IN_SEGMENT",MIDPOINT_IN_SEGMENT; +"MIDPOINT_LINEAR_IMAGE",MIDPOINT_LINEAR_IMAGE; +"MIDPOINT_REFL",MIDPOINT_REFL; +"MIDPOINT_SYM",MIDPOINT_SYM; +"MIN",MIN; +"MINIMAL",MINIMAL; +"MINIMAL_IN_INSERT",MINIMAL_IN_INSERT; +"MK_REC_INJ",MK_REC_INJ; +"MOD_0",MOD_0; +"MOD_1",MOD_1; +"MOD_ADD_MOD",MOD_ADD_MOD; +"MOD_EQ",MOD_EQ; +"MOD_EQ_0",MOD_EQ_0; +"MOD_EXISTS",MOD_EXISTS; +"MOD_EXP_MOD",MOD_EXP_MOD; +"MOD_LE",MOD_LE; +"MOD_LT",MOD_LT; +"MOD_MOD",MOD_MOD; +"MOD_MOD_EXP_MIN",MOD_MOD_EXP_MIN; +"MOD_MOD_REFL",MOD_MOD_REFL; +"MOD_MULT",MOD_MULT; +"MOD_MULT2",MOD_MULT2; +"MOD_MULT_ADD",MOD_MULT_ADD; +"MOD_MULT_LMOD",MOD_MULT_LMOD; +"MOD_MULT_MOD2",MOD_MULT_MOD2; +"MOD_MULT_RMOD",MOD_MULT_RMOD; +"MOD_NSUM_MOD",MOD_NSUM_MOD; +"MOD_NSUM_MOD_NUMSEG",MOD_NSUM_MOD_NUMSEG; +"MOD_UNIQ",MOD_UNIQ; +"MOEBIUS_FUNCTION_COMPOSE",MOEBIUS_FUNCTION_COMPOSE; +"MOEBIUS_FUNCTION_EQ_ZERO",MOEBIUS_FUNCTION_EQ_ZERO; +"MOEBIUS_FUNCTION_HOLOMORPHIC",MOEBIUS_FUNCTION_HOLOMORPHIC; +"MOEBIUS_FUNCTION_NORM_LT_1",MOEBIUS_FUNCTION_NORM_LT_1; +"MOEBIUS_FUNCTION_OF_ZERO",MOEBIUS_FUNCTION_OF_ZERO; +"MOEBIUS_FUNCTION_SIMPLE",MOEBIUS_FUNCTION_SIMPLE; +"MONODROMY_CONTINUOUS_LOG",MONODROMY_CONTINUOUS_LOG; +"MONOIDAL_AC",MONOIDAL_AC; +"MONOIDAL_ADD",MONOIDAL_ADD; +"MONOIDAL_AND",MONOIDAL_AND; +"MONOIDAL_COMPLEX_MUL",MONOIDAL_COMPLEX_MUL; +"MONOIDAL_LIFTED",MONOIDAL_LIFTED; +"MONOIDAL_MUL",MONOIDAL_MUL; +"MONOIDAL_REAL_ADD",MONOIDAL_REAL_ADD; +"MONOIDAL_REAL_MUL",MONOIDAL_REAL_MUL; +"MONOIDAL_VECTOR_ADD",MONOIDAL_VECTOR_ADD; +"MONOTONE_BIGGER",MONOTONE_BIGGER; +"MONOTONE_CONVERGENCE_DECREASING",MONOTONE_CONVERGENCE_DECREASING; +"MONOTONE_CONVERGENCE_INCREASING",MONOTONE_CONVERGENCE_INCREASING; +"MONOTONE_CONVERGENCE_INTERVAL",MONOTONE_CONVERGENCE_INTERVAL; +"MONOTONE_SUBSEQUENCE",MONOTONE_SUBSEQUENCE; +"MONO_ALL",MONO_ALL; +"MONO_ALL2",MONO_ALL2; +"MONO_AND",MONO_AND; +"MONO_COND",MONO_COND; +"MONO_EXISTS",MONO_EXISTS; +"MONO_FORALL",MONO_FORALL; +"MONO_IMP",MONO_IMP; +"MONO_NOT",MONO_NOT; +"MONO_OR",MONO_OR; +"MONTEL",MONTEL; +"MORERA_LOCAL_TRIANGLE",MORERA_LOCAL_TRIANGLE; +"MORERA_LOCAL_TRIANGLE_GEN",MORERA_LOCAL_TRIANGLE_GEN; +"MORERA_TRIANGLE",MORERA_TRIANGLE; +"MULT",MULT; +"MULTIVECTOR_ADD_COMPONENT",MULTIVECTOR_ADD_COMPONENT; +"MULTIVECTOR_BETA",MULTIVECTOR_BETA; +"MULTIVECTOR_EQ",MULTIVECTOR_EQ; +"MULTIVECTOR_ETA",MULTIVECTOR_ETA; +"MULTIVECTOR_GRADE",MULTIVECTOR_GRADE; +"MULTIVECTOR_IMAGE",MULTIVECTOR_IMAGE; +"MULTIVECTOR_MUL_COMPONENT",MULTIVECTOR_MUL_COMPONENT; +"MULTIVECTOR_UNIQUE",MULTIVECTOR_UNIQUE; +"MULTIVECTOR_VEC_COMPONENT",MULTIVECTOR_VEC_COMPONENT; +"MULTIVECTOR_VSUM",MULTIVECTOR_VSUM; +"MULTIVECTOR_VSUM_COMPONENT",MULTIVECTOR_VSUM_COMPONENT; +"MULT_0",MULT_0; +"MULT_2",MULT_2; +"MULT_AC",MULT_AC; +"MULT_ASSOC",MULT_ASSOC; +"MULT_CLAUSES",MULT_CLAUSES; +"MULT_DIV_LE",MULT_DIV_LE; +"MULT_EQ_0",MULT_EQ_0; +"MULT_EQ_1",MULT_EQ_1; +"MULT_EXP",MULT_EXP; +"MULT_SUC",MULT_SUC; +"MULT_SYM",MULT_SYM; +"MUL_C_UNIV",MUL_C_UNIV; +"MVT",MVT; +"MVT_GENERAL",MVT_GENERAL; +"MVT_SIMPLE",MVT_SIMPLE; +"MVT_VERY_SIMPLE",MVT_VERY_SIMPLE; +"NADD_ADD",NADD_ADD; +"NADD_ADDITIVE",NADD_ADDITIVE; +"NADD_ADD_ASSOC",NADD_ADD_ASSOC; +"NADD_ADD_LCANCEL",NADD_ADD_LCANCEL; +"NADD_ADD_LID",NADD_ADD_LID; +"NADD_ADD_SYM",NADD_ADD_SYM; +"NADD_ADD_WELLDEF",NADD_ADD_WELLDEF; +"NADD_ALTMUL",NADD_ALTMUL; +"NADD_ARCH",NADD_ARCH; +"NADD_ARCH_LEMMA",NADD_ARCH_LEMMA; +"NADD_ARCH_MULT",NADD_ARCH_MULT; +"NADD_ARCH_ZERO",NADD_ARCH_ZERO; +"NADD_BOUND",NADD_BOUND; +"NADD_CAUCHY",NADD_CAUCHY; +"NADD_COMPLETE",NADD_COMPLETE; +"NADD_DIST",NADD_DIST; +"NADD_DIST_LEMMA",NADD_DIST_LEMMA; +"NADD_EQ_IMP_LE",NADD_EQ_IMP_LE; +"NADD_EQ_REFL",NADD_EQ_REFL; +"NADD_EQ_SYM",NADD_EQ_SYM; +"NADD_EQ_TRANS",NADD_EQ_TRANS; +"NADD_INV",NADD_INV; +"NADD_INV_0",NADD_INV_0; +"NADD_INV_WELLDEF",NADD_INV_WELLDEF; +"NADD_LBOUND",NADD_LBOUND; +"NADD_LDISTRIB",NADD_LDISTRIB; +"NADD_LE_0",NADD_LE_0; +"NADD_LE_ADD",NADD_LE_ADD; +"NADD_LE_ANTISYM",NADD_LE_ANTISYM; +"NADD_LE_EXISTS",NADD_LE_EXISTS; +"NADD_LE_LADD",NADD_LE_LADD; +"NADD_LE_LMUL",NADD_LE_LMUL; +"NADD_LE_RADD",NADD_LE_RADD; +"NADD_LE_REFL",NADD_LE_REFL; +"NADD_LE_RMUL",NADD_LE_RMUL; +"NADD_LE_TOTAL",NADD_LE_TOTAL; +"NADD_LE_TOTAL_LEMMA",NADD_LE_TOTAL_LEMMA; +"NADD_LE_TRANS",NADD_LE_TRANS; +"NADD_LE_WELLDEF",NADD_LE_WELLDEF; +"NADD_LE_WELLDEF_LEMMA",NADD_LE_WELLDEF_LEMMA; +"NADD_MUL",NADD_MUL; +"NADD_MULTIPLICATIVE",NADD_MULTIPLICATIVE; +"NADD_MUL_ASSOC",NADD_MUL_ASSOC; +"NADD_MUL_LID",NADD_MUL_LID; +"NADD_MUL_LINV",NADD_MUL_LINV; +"NADD_MUL_LINV_LEMMA0",NADD_MUL_LINV_LEMMA0; +"NADD_MUL_LINV_LEMMA1",NADD_MUL_LINV_LEMMA1; +"NADD_MUL_LINV_LEMMA2",NADD_MUL_LINV_LEMMA2; +"NADD_MUL_LINV_LEMMA3",NADD_MUL_LINV_LEMMA3; +"NADD_MUL_LINV_LEMMA4",NADD_MUL_LINV_LEMMA4; +"NADD_MUL_LINV_LEMMA5",NADD_MUL_LINV_LEMMA5; +"NADD_MUL_LINV_LEMMA6",NADD_MUL_LINV_LEMMA6; +"NADD_MUL_LINV_LEMMA7",NADD_MUL_LINV_LEMMA7; +"NADD_MUL_LINV_LEMMA7a",NADD_MUL_LINV_LEMMA7a; +"NADD_MUL_LINV_LEMMA8",NADD_MUL_LINV_LEMMA8; +"NADD_MUL_SYM",NADD_MUL_SYM; +"NADD_MUL_WELLDEF",NADD_MUL_WELLDEF; +"NADD_MUL_WELLDEF_LEMMA",NADD_MUL_WELLDEF_LEMMA; +"NADD_NONZERO",NADD_NONZERO; +"NADD_OF_NUM",NADD_OF_NUM; +"NADD_OF_NUM_ADD",NADD_OF_NUM_ADD; +"NADD_OF_NUM_EQ",NADD_OF_NUM_EQ; +"NADD_OF_NUM_LE",NADD_OF_NUM_LE; +"NADD_OF_NUM_MUL",NADD_OF_NUM_MUL; +"NADD_OF_NUM_WELLDEF",NADD_OF_NUM_WELLDEF; +"NADD_RDISTRIB",NADD_RDISTRIB; +"NADD_SUC",NADD_SUC; +"NADD_UBOUND",NADD_UBOUND; +"NEARBY_INVERTIBLE_MATRIX",NEARBY_INVERTIBLE_MATRIX; +"NEGATIONS_BALL",NEGATIONS_BALL; +"NEGATIONS_CBALL",NEGATIONS_CBALL; +"NEGATIONS_SPHERE",NEGATIONS_SPHERE; +"NEGLIGIBLE",NEGLIGIBLE; +"NEGLIGIBLE_AFFINE_HULL",NEGLIGIBLE_AFFINE_HULL; +"NEGLIGIBLE_AFFINE_HULL_1",NEGLIGIBLE_AFFINE_HULL_1; +"NEGLIGIBLE_AFFINE_HULL_2",NEGLIGIBLE_AFFINE_HULL_2; +"NEGLIGIBLE_AFFINE_HULL_3",NEGLIGIBLE_AFFINE_HULL_3; +"NEGLIGIBLE_CONVEX_FRONTIER",NEGLIGIBLE_CONVEX_FRONTIER; +"NEGLIGIBLE_CONVEX_HULL",NEGLIGIBLE_CONVEX_HULL; +"NEGLIGIBLE_CONVEX_HULL_1",NEGLIGIBLE_CONVEX_HULL_1; +"NEGLIGIBLE_CONVEX_HULL_2",NEGLIGIBLE_CONVEX_HULL_2; +"NEGLIGIBLE_CONVEX_HULL_3",NEGLIGIBLE_CONVEX_HULL_3; +"NEGLIGIBLE_COUNTABLE",NEGLIGIBLE_COUNTABLE; +"NEGLIGIBLE_COUNTABLE_UNIONS",NEGLIGIBLE_COUNTABLE_UNIONS; +"NEGLIGIBLE_COUNTABLE_UNIONS_GEN",NEGLIGIBLE_COUNTABLE_UNIONS_GEN; +"NEGLIGIBLE_DELETE",NEGLIGIBLE_DELETE; +"NEGLIGIBLE_DIFF",NEGLIGIBLE_DIFF; +"NEGLIGIBLE_DIFFERENTIABLE_IMAGE_LOWDIM",NEGLIGIBLE_DIFFERENTIABLE_IMAGE_LOWDIM; +"NEGLIGIBLE_DIFFERENTIABLE_IMAGE_NEGLIGIBLE",NEGLIGIBLE_DIFFERENTIABLE_IMAGE_NEGLIGIBLE; +"NEGLIGIBLE_EMPTY",NEGLIGIBLE_EMPTY; +"NEGLIGIBLE_EQ_MEASURE_0",NEGLIGIBLE_EQ_MEASURE_0; +"NEGLIGIBLE_FINITE",NEGLIGIBLE_FINITE; +"NEGLIGIBLE_FRONTIER_INTERVAL",NEGLIGIBLE_FRONTIER_INTERVAL; +"NEGLIGIBLE_HYPERPLANE",NEGLIGIBLE_HYPERPLANE; +"NEGLIGIBLE_IFF_LEBESGUE_MEASURABLE_SUBSETS",NEGLIGIBLE_IFF_LEBESGUE_MEASURABLE_SUBSETS; +"NEGLIGIBLE_IFF_MEASURABLE_SUBSETS",NEGLIGIBLE_IFF_MEASURABLE_SUBSETS; +"NEGLIGIBLE_IMAGE_BOUNDED_VARIATION_INTERVAL",NEGLIGIBLE_IMAGE_BOUNDED_VARIATION_INTERVAL; +"NEGLIGIBLE_IMP_LEBESGUE_MEASURABLE",NEGLIGIBLE_IMP_LEBESGUE_MEASURABLE; +"NEGLIGIBLE_IMP_MEASURABLE",NEGLIGIBLE_IMP_MEASURABLE; +"NEGLIGIBLE_INSERT",NEGLIGIBLE_INSERT; +"NEGLIGIBLE_INTER",NEGLIGIBLE_INTER; +"NEGLIGIBLE_INTERVAL",NEGLIGIBLE_INTERVAL; +"NEGLIGIBLE_LINEAR_IMAGE",NEGLIGIBLE_LINEAR_IMAGE; +"NEGLIGIBLE_LINEAR_IMAGE_EQ",NEGLIGIBLE_LINEAR_IMAGE_EQ; +"NEGLIGIBLE_LINEAR_SINGULAR_IMAGE",NEGLIGIBLE_LINEAR_SINGULAR_IMAGE; +"NEGLIGIBLE_LIPSCHITZ_IMAGE_UNIV",NEGLIGIBLE_LIPSCHITZ_IMAGE_UNIV; +"NEGLIGIBLE_LOCALLY_LIPSCHITZ_IMAGE",NEGLIGIBLE_LOCALLY_LIPSCHITZ_IMAGE; +"NEGLIGIBLE_LOWDIM",NEGLIGIBLE_LOWDIM; +"NEGLIGIBLE_ON_INTERVALS",NEGLIGIBLE_ON_INTERVALS; +"NEGLIGIBLE_ON_UNIV",NEGLIGIBLE_ON_UNIV; +"NEGLIGIBLE_OUTER",NEGLIGIBLE_OUTER; +"NEGLIGIBLE_OUTER_LE",NEGLIGIBLE_OUTER_LE; +"NEGLIGIBLE_RECTIFIABLE_PATH_IMAGE",NEGLIGIBLE_RECTIFIABLE_PATH_IMAGE; +"NEGLIGIBLE_SING",NEGLIGIBLE_SING; +"NEGLIGIBLE_SPHERE",NEGLIGIBLE_SPHERE; +"NEGLIGIBLE_STANDARD_HYPERPLANE",NEGLIGIBLE_STANDARD_HYPERPLANE; +"NEGLIGIBLE_SUBSET",NEGLIGIBLE_SUBSET; +"NEGLIGIBLE_SYMDIFF_EQ",NEGLIGIBLE_SYMDIFF_EQ; +"NEGLIGIBLE_TRANSLATION",NEGLIGIBLE_TRANSLATION; +"NEGLIGIBLE_TRANSLATION_EQ",NEGLIGIBLE_TRANSLATION_EQ; +"NEGLIGIBLE_TRANSLATION_REV",NEGLIGIBLE_TRANSLATION_REV; +"NEGLIGIBLE_UNION",NEGLIGIBLE_UNION; +"NEGLIGIBLE_UNIONS",NEGLIGIBLE_UNIONS; +"NEGLIGIBLE_UNION_EQ",NEGLIGIBLE_UNION_EQ; +"NEGLIGIBLE_VALID_PATH_IMAGE",NEGLIGIBLE_VALID_PATH_IMAGE; +"NEIGHBOURHOOD_EXTENSION_INTO_ANR",NEIGHBOURHOOD_EXTENSION_INTO_ANR; +"NEIGHBOURHOOD_EXTENSION_INTO_ANR_LOCAL",NEIGHBOURHOOD_EXTENSION_INTO_ANR_LOCAL; +"NEIGHBOURHOOD_RETRACT_IMP_ANR",NEIGHBOURHOOD_RETRACT_IMP_ANR; +"NEIGHBOURHOOD_RETRACT_IMP_ANR_UNIV",NEIGHBOURHOOD_RETRACT_IMP_ANR_UNIV; +"NET",NET; +"NETLIMIT_AT",NETLIMIT_AT; +"NETLIMIT_ATREAL",NETLIMIT_ATREAL; +"NETLIMIT_WITHIN",NETLIMIT_WITHIN; +"NETLIMIT_WITHINREAL",NETLIMIT_WITHINREAL; +"NETLIMIT_WITHIN_INTERIOR",NETLIMIT_WITHIN_INTERIOR; +"NET_DILEMMA",NET_DILEMMA; +"NEUTRAL_ADD",NEUTRAL_ADD; +"NEUTRAL_AND",NEUTRAL_AND; +"NEUTRAL_COMPLEX_MUL",NEUTRAL_COMPLEX_MUL; +"NEUTRAL_LIFTED",NEUTRAL_LIFTED; +"NEUTRAL_MUL",NEUTRAL_MUL; +"NEUTRAL_OUTER",NEUTRAL_OUTER; +"NEUTRAL_REAL_ADD",NEUTRAL_REAL_ADD; +"NEUTRAL_REAL_MUL",NEUTRAL_REAL_MUL; +"NEUTRAL_VECTOR_ADD",NEUTRAL_VECTOR_ADD; +"NONEMPTY_SIMPLE_PATH_ENDLESS",NONEMPTY_SIMPLE_PATH_ENDLESS; +"NONNEGATIVE_ABSOLUTELY_INTEGRABLE",NONNEGATIVE_ABSOLUTELY_INTEGRABLE; +"NONNEGATIVE_ABSOLUTELY_REAL_INTEGRABLE",NONNEGATIVE_ABSOLUTELY_REAL_INTEGRABLE; +"NONTRIVIAL_LIMIT_WITHIN",NONTRIVIAL_LIMIT_WITHIN; +"NON_EXTENSIBLE_BORSUK_MAP",NON_EXTENSIBLE_BORSUK_MAP; +"NORM_0",NORM_0; +"NORM_1",NORM_1; +"NORM_1_POS",NORM_1_POS; +"NORM_ADD_PYTHAGOREAN",NORM_ADD_PYTHAGOREAN; +"NORM_BASIS",NORM_BASIS; +"NORM_BASIS_1",NORM_BASIS_1; +"NORM_BOUND_COMPONENT_LE",NORM_BOUND_COMPONENT_LE; +"NORM_BOUND_COMPONENT_LT",NORM_BOUND_COMPONENT_LT; +"NORM_BOUND_GENERALIZE",NORM_BOUND_GENERALIZE; +"NORM_CAUCHY_SCHWARZ",NORM_CAUCHY_SCHWARZ; +"NORM_CAUCHY_SCHWARZ_ABS",NORM_CAUCHY_SCHWARZ_ABS; +"NORM_CAUCHY_SCHWARZ_ABS_EQ",NORM_CAUCHY_SCHWARZ_ABS_EQ; +"NORM_CAUCHY_SCHWARZ_DIV",NORM_CAUCHY_SCHWARZ_DIV; +"NORM_CAUCHY_SCHWARZ_EQ",NORM_CAUCHY_SCHWARZ_EQ; +"NORM_CAUCHY_SCHWARZ_EQUAL",NORM_CAUCHY_SCHWARZ_EQUAL; +"NORM_CCOS_LE",NORM_CCOS_LE; +"NORM_CCOS_PLUS1_LE",NORM_CCOS_PLUS1_LE; +"NORM_CCOS_POW_2",NORM_CCOS_POW_2; +"NORM_CEXP",NORM_CEXP; +"NORM_CEXP_II",NORM_CEXP_II; +"NORM_CEXP_IMAGINARY",NORM_CEXP_IMAGINARY; +"NORM_COSSIN",NORM_COSSIN; +"NORM_CPOW_REAL",NORM_CPOW_REAL; +"NORM_CPOW_REAL_MONO",NORM_CPOW_REAL_MONO; +"NORM_CPRODUCT",NORM_CPRODUCT; +"NORM_CROSS_MULTIPLY",NORM_CROSS_MULTIPLY; +"NORM_CSIN_POW_2",NORM_CSIN_POW_2; +"NORM_EQ",NORM_EQ; +"NORM_EQ_0",NORM_EQ_0; +"NORM_EQ_0_DOT",NORM_EQ_0_DOT; +"NORM_EQ_0_IMP",NORM_EQ_0_IMP; +"NORM_EQ_1",NORM_EQ_1; +"NORM_EQ_SQUARE",NORM_EQ_SQUARE; +"NORM_FSTCART",NORM_FSTCART; +"NORM_GE_SQUARE",NORM_GE_SQUARE; +"NORM_GT_SQUARE",NORM_GT_SQUARE; +"NORM_INCREASES_ONLINE",NORM_INCREASES_ONLINE; +"NORM_LE",NORM_LE; +"NORM_LE_0",NORM_LE_0; +"NORM_LE_COMPONENTWISE",NORM_LE_COMPONENTWISE; +"NORM_LE_INFNORM",NORM_LE_INFNORM; +"NORM_LE_L1",NORM_LE_L1; +"NORM_LE_PASTECART",NORM_LE_PASTECART; +"NORM_LE_SQUARE",NORM_LE_SQUARE; +"NORM_LIFT",NORM_LIFT; +"NORM_LT",NORM_LT; +"NORM_LT_SQUARE",NORM_LT_SQUARE; +"NORM_LT_SQUARE_ALT",NORM_LT_SQUARE_ALT; +"NORM_MUL",NORM_MUL; +"NORM_NEG",NORM_NEG; +"NORM_PASTECART",NORM_PASTECART; +"NORM_PASTECART_0",NORM_PASTECART_0; +"NORM_PASTECART_LE",NORM_PASTECART_LE; +"NORM_POS_LE",NORM_POS_LE; +"NORM_POS_LT",NORM_POS_LT; +"NORM_POW_2",NORM_POW_2; +"NORM_REAL",NORM_REAL; +"NORM_ROTATE2D",NORM_ROTATE2D; +"NORM_SEGMENT_LOWERBOUND",NORM_SEGMENT_LOWERBOUND; +"NORM_SEGMENT_ORTHOGONAL_LOWERBOUND",NORM_SEGMENT_ORTHOGONAL_LOWERBOUND; +"NORM_SNDCART",NORM_SNDCART; +"NORM_SUB",NORM_SUB; +"NORM_SUM_LEMMA",NORM_SUM_LEMMA; +"NORM_TRIANGLE",NORM_TRIANGLE; +"NORM_TRIANGLE_EQ",NORM_TRIANGLE_EQ; +"NORM_TRIANGLE_LE",NORM_TRIANGLE_LE; +"NORM_TRIANGLE_LT",NORM_TRIANGLE_LT; +"NORM_TRIANGLE_SUB",NORM_TRIANGLE_SUB; +"NORM_VSUM_PYTHAGOREAN",NORM_VSUM_PYTHAGOREAN; +"NORM_VSUM_TRIVIAL_LEMMA",NORM_VSUM_TRIVIAL_LEMMA; +"NOT_ABSOLUTE_RETRACT_COBOUNDED",NOT_ABSOLUTE_RETRACT_COBOUNDED; +"NOT_ALL",NOT_ALL; +"NOT_BOUNDED_UNIV",NOT_BOUNDED_UNIV; +"NOT_CLAUSES",NOT_CLAUSES; +"NOT_CLAUSES_WEAK",NOT_CLAUSES_WEAK; +"NOT_CONS_NIL",NOT_CONS_NIL; +"NOT_DEF",NOT_DEF; +"NOT_EMPTY_INSERT",NOT_EMPTY_INSERT; +"NOT_EQUAL_SETS",NOT_EQUAL_SETS; +"NOT_EVEN",NOT_EVEN; +"NOT_EVENTUALLY",NOT_EVENTUALLY; +"NOT_EX",NOT_EX; +"NOT_EXISTS_THM",NOT_EXISTS_THM; +"NOT_FORALL_THM",NOT_FORALL_THM; +"NOT_IMP",NOT_IMP; +"NOT_INSERT_EMPTY",NOT_INSERT_EMPTY; +"NOT_INTERVAL_UNIV",NOT_INTERVAL_UNIV; +"NOT_IN_EMPTY",NOT_IN_EMPTY; +"NOT_IN_INTERIOR_CONVEX_HULL",NOT_IN_INTERIOR_CONVEX_HULL; +"NOT_IN_INTERIOR_CONVEX_HULL_3",NOT_IN_INTERIOR_CONVEX_HULL_3; +"NOT_IN_PATH_IMAGE_JOIN",NOT_IN_PATH_IMAGE_JOIN; +"NOT_LE",NOT_LE; +"NOT_LT",NOT_LT; +"NOT_NEGLIGIBLE_UNIV",NOT_NEGLIGIBLE_UNIV; +"NOT_ODD",NOT_ODD; +"NOT_ON_PATH_BALL",NOT_ON_PATH_BALL; +"NOT_ON_PATH_CBALL",NOT_ON_PATH_CBALL; +"NOT_OUTSIDE_CONNECTED_COMPONENT_LE",NOT_OUTSIDE_CONNECTED_COMPONENT_LE; +"NOT_OUTSIDE_CONNECTED_COMPONENT_LT",NOT_OUTSIDE_CONNECTED_COMPONENT_LT; +"NOT_PSUBSET_EMPTY",NOT_PSUBSET_EMPTY; +"NOT_SIMPLY_CONNECTED_CIRCLE",NOT_SIMPLY_CONNECTED_CIRCLE; +"NOT_SUC",NOT_SUC; +"NOT_UNIV_PSUBSET",NOT_UNIV_PSUBSET; +"NOWHERE_DENSE",NOWHERE_DENSE; +"NOWHERE_DENSE_UNION",NOWHERE_DENSE_UNION; +"NO_BOUNDED_CONNECTED_COMPONENT_IMP_WINDING_NUMBER_ZERO",NO_BOUNDED_CONNECTED_COMPONENT_IMP_WINDING_NUMBER_ZERO; +"NO_BOUNDED_PATH_COMPONENT_IMP_WINDING_NUMBER_ZERO",NO_BOUNDED_PATH_COMPONENT_IMP_WINDING_NUMBER_ZERO; +"NO_EMBEDDING_SPHERE_LOWDIM",NO_EMBEDDING_SPHERE_LOWDIM; +"NO_ISOLATED_SINGULARITY",NO_ISOLATED_SINGULARITY; +"NO_LIMIT_POINT_IMP_CLOSED",NO_LIMIT_POINT_IMP_CLOSED; +"NO_RETRACTION_CBALL",NO_RETRACTION_CBALL; +"NO_RETRACTION_FRONTIER_BOUNDED",NO_RETRACTION_FRONTIER_BOUNDED; +"NSUM_0",NSUM_0; +"NSUM_ADD",NSUM_ADD; +"NSUM_ADD_GEN",NSUM_ADD_GEN; +"NSUM_ADD_NUMSEG",NSUM_ADD_NUMSEG; +"NSUM_ADD_SPLIT",NSUM_ADD_SPLIT; +"NSUM_BIJECTION",NSUM_BIJECTION; +"NSUM_BOUND",NSUM_BOUND; +"NSUM_BOUND_GEN",NSUM_BOUND_GEN; +"NSUM_BOUND_LT",NSUM_BOUND_LT; +"NSUM_BOUND_LT_ALL",NSUM_BOUND_LT_ALL; +"NSUM_BOUND_LT_GEN",NSUM_BOUND_LT_GEN; +"NSUM_CASES",NSUM_CASES; +"NSUM_CLAUSES",NSUM_CLAUSES; +"NSUM_CLAUSES_LEFT",NSUM_CLAUSES_LEFT; +"NSUM_CLAUSES_NUMSEG",NSUM_CLAUSES_NUMSEG; +"NSUM_CLAUSES_RIGHT",NSUM_CLAUSES_RIGHT; +"NSUM_CLOSED",NSUM_CLOSED; +"NSUM_CONST",NSUM_CONST; +"NSUM_CONST_NUMSEG",NSUM_CONST_NUMSEG; +"NSUM_DELETE",NSUM_DELETE; +"NSUM_DELTA",NSUM_DELTA; +"NSUM_DIFF",NSUM_DIFF; +"NSUM_EQ",NSUM_EQ; +"NSUM_EQ_0",NSUM_EQ_0; +"NSUM_EQ_0_IFF",NSUM_EQ_0_IFF; +"NSUM_EQ_0_IFF_NUMSEG",NSUM_EQ_0_IFF_NUMSEG; +"NSUM_EQ_0_NUMSEG",NSUM_EQ_0_NUMSEG; +"NSUM_EQ_GENERAL",NSUM_EQ_GENERAL; +"NSUM_EQ_GENERAL_INVERSES",NSUM_EQ_GENERAL_INVERSES; +"NSUM_EQ_NUMSEG",NSUM_EQ_NUMSEG; +"NSUM_EQ_SUPERSET",NSUM_EQ_SUPERSET; +"NSUM_GROUP",NSUM_GROUP; +"NSUM_IMAGE",NSUM_IMAGE; +"NSUM_IMAGE_GEN",NSUM_IMAGE_GEN; +"NSUM_IMAGE_NONZERO",NSUM_IMAGE_NONZERO; +"NSUM_INCL_EXCL",NSUM_INCL_EXCL; +"NSUM_INJECTION",NSUM_INJECTION; +"NSUM_LE",NSUM_LE; +"NSUM_LE_NUMSEG",NSUM_LE_NUMSEG; +"NSUM_LMUL",NSUM_LMUL; +"NSUM_LT",NSUM_LT; +"NSUM_LT_ALL",NSUM_LT_ALL; +"NSUM_MULTICOUNT",NSUM_MULTICOUNT; +"NSUM_MULTICOUNT_GEN",NSUM_MULTICOUNT_GEN; +"NSUM_NSUM_PRODUCT",NSUM_NSUM_PRODUCT; +"NSUM_NSUM_RESTRICT",NSUM_NSUM_RESTRICT; +"NSUM_OFFSET",NSUM_OFFSET; +"NSUM_OFFSET_0",NSUM_OFFSET_0; +"NSUM_PAIR",NSUM_PAIR; +"NSUM_PERMUTE",NSUM_PERMUTE; +"NSUM_PERMUTE_NUMSEG",NSUM_PERMUTE_NUMSEG; +"NSUM_POS_BOUND",NSUM_POS_BOUND; +"NSUM_POS_LT",NSUM_POS_LT; +"NSUM_RESTRICT",NSUM_RESTRICT; +"NSUM_RESTRICT_SET",NSUM_RESTRICT_SET; +"NSUM_RMUL",NSUM_RMUL; +"NSUM_SING",NSUM_SING; +"NSUM_SING_NUMSEG",NSUM_SING_NUMSEG; +"NSUM_SUBSET",NSUM_SUBSET; +"NSUM_SUBSET_SIMPLE",NSUM_SUBSET_SIMPLE; +"NSUM_SUPERSET",NSUM_SUPERSET; +"NSUM_SUPPORT",NSUM_SUPPORT; +"NSUM_SWAP",NSUM_SWAP; +"NSUM_SWAP_NUMSEG",NSUM_SWAP_NUMSEG; +"NSUM_TRIV_NUMSEG",NSUM_TRIV_NUMSEG; +"NSUM_UNION",NSUM_UNION; +"NSUM_UNIONS_NONZERO",NSUM_UNIONS_NONZERO; +"NSUM_UNION_EQ",NSUM_UNION_EQ; +"NSUM_UNION_LZERO",NSUM_UNION_LZERO; +"NSUM_UNION_NONZERO",NSUM_UNION_NONZERO; +"NSUM_UNION_RZERO",NSUM_UNION_RZERO; +"NULL",NULL; +"NULLHOMOTOPIC_FROM_CONTRACTIBLE",NULLHOMOTOPIC_FROM_CONTRACTIBLE; +"NULLHOMOTOPIC_FROM_SPHERE_EXTENSION",NULLHOMOTOPIC_FROM_SPHERE_EXTENSION; +"NULLHOMOTOPIC_INTO_ANR_EXTENSION",NULLHOMOTOPIC_INTO_ANR_EXTENSION; +"NULLHOMOTOPIC_INTO_CONTRACTIBLE",NULLHOMOTOPIC_INTO_CONTRACTIBLE; +"NULLHOMOTOPIC_INTO_RELATIVE_FRONTIER_EXTENSION",NULLHOMOTOPIC_INTO_RELATIVE_FRONTIER_EXTENSION; +"NULLHOMOTOPIC_INTO_SPHERE_EXTENSION",NULLHOMOTOPIC_INTO_SPHERE_EXTENSION; +"NULLHOMOTOPIC_ORTHOGONAL_TRANSFORMATION",NULLHOMOTOPIC_ORTHOGONAL_TRANSFORMATION; +"NULLHOMOTOPIC_THROUGH_CONTRACTIBLE",NULLHOMOTOPIC_THROUGH_CONTRACTIBLE; +"NULLSPACE_INTER_ROWSPACE",NULLSPACE_INTER_ROWSPACE; +"NUMERAL",NUMERAL; +"NUMPAIR",NUMPAIR; +"NUMPAIR_DEST",NUMPAIR_DEST; +"NUMPAIR_INJ",NUMPAIR_INJ; +"NUMPAIR_INJ_LEMMA",NUMPAIR_INJ_LEMMA; +"NUMSEG_ADD_SPLIT",NUMSEG_ADD_SPLIT; +"NUMSEG_CLAUSES",NUMSEG_CLAUSES; +"NUMSEG_COMBINE_L",NUMSEG_COMBINE_L; +"NUMSEG_COMBINE_R",NUMSEG_COMBINE_R; +"NUMSEG_DIMINDEX_NONEMPTY",NUMSEG_DIMINDEX_NONEMPTY; +"NUMSEG_EMPTY",NUMSEG_EMPTY; +"NUMSEG_LE",NUMSEG_LE; +"NUMSEG_LREC",NUMSEG_LREC; +"NUMSEG_LT",NUMSEG_LT; +"NUMSEG_OFFSET_IMAGE",NUMSEG_OFFSET_IMAGE; +"NUMSEG_REC",NUMSEG_REC; +"NUMSEG_RREC",NUMSEG_RREC; +"NUMSEG_SING",NUMSEG_SING; +"NUMSUM",NUMSUM; +"NUMSUM_DEST",NUMSUM_DEST; +"NUMSUM_INJ",NUMSUM_INJ; +"NUM_COUNTABLE",NUM_COUNTABLE; +"NUM_GCD",NUM_GCD; +"NUM_OF_INT",NUM_OF_INT; +"NUM_OF_INT_OF_NUM",NUM_OF_INT_OF_NUM; +"NUM_REP_CASES",NUM_REP_CASES; +"NUM_REP_INDUCT",NUM_REP_INDUCT; +"NUM_REP_RULES",NUM_REP_RULES; +"ODD",ODD; +"ODD_ADD",ODD_ADD; +"ODD_DOUBLE",ODD_DOUBLE; +"ODD_EXISTS",ODD_EXISTS; +"ODD_EXP",ODD_EXP; +"ODD_MOD",ODD_MOD; +"ODD_MULT",ODD_MULT; +"ODD_SUB",ODD_SUB; +"OEP",OEP; +"OLDNET",OLDNET; +"ONE",ONE; +"ONE_ONE",ONE_ONE; +"ONORM",ONORM; +"ONORM_COMPOSE",ONORM_COMPOSE; +"ONORM_CONST",ONORM_CONST; +"ONORM_EQ_0",ONORM_EQ_0; +"ONORM_I",ONORM_I; +"ONORM_ID",ONORM_ID; +"ONORM_NEG",ONORM_NEG; +"ONORM_NEG_LEMMA",ONORM_NEG_LEMMA; +"ONORM_POS_LE",ONORM_POS_LE; +"ONORM_POS_LT",ONORM_POS_LT; +"ONORM_TRIANGLE",ONORM_TRIANGLE; +"ONORM_TRIANGLE_LE",ONORM_TRIANGLE_LE; +"ONORM_TRIANGLE_LT",ONORM_TRIANGLE_LT; +"ONTO",ONTO; +"OPEN_AFFINITY",OPEN_AFFINITY; +"OPEN_ARG_GT",OPEN_ARG_GT; +"OPEN_ARG_LTT",OPEN_ARG_LTT; +"OPEN_BALL",OPEN_BALL; +"OPEN_BIJECTIVE_LINEAR_IMAGE_EQ",OPEN_BIJECTIVE_LINEAR_IMAGE_EQ; +"OPEN_CLOSED",OPEN_CLOSED; +"OPEN_CLOSED_INTERVAL_1",OPEN_CLOSED_INTERVAL_1; +"OPEN_CLOSED_INTERVAL_CONVEX",OPEN_CLOSED_INTERVAL_CONVEX; +"OPEN_COMPONENTS",OPEN_COMPONENTS; +"OPEN_CONNECTED_COMPONENT",OPEN_CONNECTED_COMPONENT; +"OPEN_CONTAINS_BALL",OPEN_CONTAINS_BALL; +"OPEN_CONTAINS_BALL_EQ",OPEN_CONTAINS_BALL_EQ; +"OPEN_CONTAINS_CBALL",OPEN_CONTAINS_CBALL; +"OPEN_CONTAINS_CBALL_EQ",OPEN_CONTAINS_CBALL_EQ; +"OPEN_CONTAINS_INTERVAL",OPEN_CONTAINS_INTERVAL; +"OPEN_CONTAINS_OPEN_INTERVAL",OPEN_CONTAINS_OPEN_INTERVAL; +"OPEN_CONVEX_HULL",OPEN_CONVEX_HULL; +"OPEN_COUNTABLE_UNION_CLOSED_INTERVALS",OPEN_COUNTABLE_UNION_CLOSED_INTERVALS; +"OPEN_COUNTABLE_UNION_OPEN_INTERVALS",OPEN_COUNTABLE_UNION_OPEN_INTERVALS; +"OPEN_DELETE",OPEN_DELETE; +"OPEN_DIFF",OPEN_DIFF; +"OPEN_EMPTY",OPEN_EMPTY; +"OPEN_EXISTS",OPEN_EXISTS; +"OPEN_EXISTS_IN",OPEN_EXISTS_IN; +"OPEN_GENERAL_COMPONENT",OPEN_GENERAL_COMPONENT; +"OPEN_HALFSPACE_COMPONENT_GT",OPEN_HALFSPACE_COMPONENT_GT; +"OPEN_HALFSPACE_COMPONENT_LT",OPEN_HALFSPACE_COMPONENT_LT; +"OPEN_HALFSPACE_GT",OPEN_HALFSPACE_GT; +"OPEN_HALFSPACE_IM_GT",OPEN_HALFSPACE_IM_GT; +"OPEN_HALFSPACE_IM_LT",OPEN_HALFSPACE_IM_LT; +"OPEN_HALFSPACE_LT",OPEN_HALFSPACE_LT; +"OPEN_HALFSPACE_RE_GT",OPEN_HALFSPACE_RE_GT; +"OPEN_HALFSPACE_RE_LT",OPEN_HALFSPACE_RE_LT; +"OPEN_IMP_INFINITE",OPEN_IMP_INFINITE; +"OPEN_IMP_LOCALLY_COMPACT",OPEN_IMP_LOCALLY_COMPACT; +"OPEN_IMP_LOCALLY_CONNECTED",OPEN_IMP_LOCALLY_CONNECTED; +"OPEN_IMP_LOCALLY_PATH_CONNECTED",OPEN_IMP_LOCALLY_PATH_CONNECTED; +"OPEN_IN",OPEN_IN; +"OPEN_INSIDE",OPEN_INSIDE; +"OPEN_INTER",OPEN_INTER; +"OPEN_INTERIOR",OPEN_INTERIOR; +"OPEN_INTERS",OPEN_INTERS; +"OPEN_INTERVAL",OPEN_INTERVAL; +"OPEN_INTERVAL_EQ",OPEN_INTERVAL_EQ; +"OPEN_INTERVAL_LEMMA",OPEN_INTERVAL_LEMMA; +"OPEN_INTERVAL_MIDPOINT",OPEN_INTERVAL_MIDPOINT; +"OPEN_INTER_CLOSURE_EQ_EMPTY",OPEN_INTER_CLOSURE_EQ_EMPTY; +"OPEN_INTER_CLOSURE_SUBSET",OPEN_INTER_CLOSURE_SUBSET; +"OPEN_IN_CLAUSES",OPEN_IN_CLAUSES; +"OPEN_IN_CLOSED_IN",OPEN_IN_CLOSED_IN; +"OPEN_IN_CLOSED_IN_EQ",OPEN_IN_CLOSED_IN_EQ; +"OPEN_IN_COMPONENTS_LOCALLY_CONNECTED",OPEN_IN_COMPONENTS_LOCALLY_CONNECTED; +"OPEN_IN_CONNECTED_COMPONENT",OPEN_IN_CONNECTED_COMPONENT; +"OPEN_IN_CONNECTED_COMPONENTS",OPEN_IN_CONNECTED_COMPONENTS; +"OPEN_IN_CONNECTED_COMPONENT_LOCALLY_CONNECTED",OPEN_IN_CONNECTED_COMPONENT_LOCALLY_CONNECTED; +"OPEN_IN_CONTAINS_BALL",OPEN_IN_CONTAINS_BALL; +"OPEN_IN_CONTAINS_CBALL",OPEN_IN_CONTAINS_CBALL; +"OPEN_IN_DELETE",OPEN_IN_DELETE; +"OPEN_IN_DIFF",OPEN_IN_DIFF; +"OPEN_IN_EMPTY",OPEN_IN_EMPTY; +"OPEN_IN_IMP_SUBSET",OPEN_IN_IMP_SUBSET; +"OPEN_IN_INJECTIVE_LINEAR_IMAGE",OPEN_IN_INJECTIVE_LINEAR_IMAGE; +"OPEN_IN_INTER",OPEN_IN_INTER; +"OPEN_IN_INTERS",OPEN_IN_INTERS; +"OPEN_IN_INTER_OPEN",OPEN_IN_INTER_OPEN; +"OPEN_IN_OPEN",OPEN_IN_OPEN; +"OPEN_IN_OPEN_EQ",OPEN_IN_OPEN_EQ; +"OPEN_IN_OPEN_INTER",OPEN_IN_OPEN_INTER; +"OPEN_IN_OPEN_TRANS",OPEN_IN_OPEN_TRANS; +"OPEN_IN_PATH_COMPONENT_LOCALLY_PATH_CONNECTED",OPEN_IN_PATH_COMPONENT_LOCALLY_PATH_CONNECTED; +"OPEN_IN_PCROSS",OPEN_IN_PCROSS; +"OPEN_IN_PCROSS_EQ",OPEN_IN_PCROSS_EQ; +"OPEN_IN_REFL",OPEN_IN_REFL; +"OPEN_IN_RELATIVE_INTERIOR",OPEN_IN_RELATIVE_INTERIOR; +"OPEN_IN_SING",OPEN_IN_SING; +"OPEN_IN_SUBOPEN",OPEN_IN_SUBOPEN; +"OPEN_IN_SUBSET",OPEN_IN_SUBSET; +"OPEN_IN_SUBSET_RELATIVE_INTERIOR",OPEN_IN_SUBSET_RELATIVE_INTERIOR; +"OPEN_IN_SUBSET_TRANS",OPEN_IN_SUBSET_TRANS; +"OPEN_IN_SUBTOPOLOGY",OPEN_IN_SUBTOPOLOGY; +"OPEN_IN_SUBTOPOLOGY_EMPTY",OPEN_IN_SUBTOPOLOGY_EMPTY; +"OPEN_IN_SUBTOPOLOGY_INTER_SUBSET",OPEN_IN_SUBTOPOLOGY_INTER_SUBSET; +"OPEN_IN_SUBTOPOLOGY_REFL",OPEN_IN_SUBTOPOLOGY_REFL; +"OPEN_IN_SUBTOPOLOGY_UNION",OPEN_IN_SUBTOPOLOGY_UNION; +"OPEN_IN_TOPSPACE",OPEN_IN_TOPSPACE; +"OPEN_IN_TRANS",OPEN_IN_TRANS; +"OPEN_IN_TRANSLATION_EQ",OPEN_IN_TRANSLATION_EQ; +"OPEN_IN_UNION",OPEN_IN_UNION; +"OPEN_IN_UNIONS",OPEN_IN_UNIONS; +"OPEN_LIFT",OPEN_LIFT; +"OPEN_MAPPING_THM",OPEN_MAPPING_THM; +"OPEN_MAP_FROM_COMPOSITION_INJECTIVE",OPEN_MAP_FROM_COMPOSITION_INJECTIVE; +"OPEN_MAP_FROM_COMPOSITION_SURJECTIVE",OPEN_MAP_FROM_COMPOSITION_SURJECTIVE; +"OPEN_MAP_IMP_CLOSED_MAP",OPEN_MAP_IMP_CLOSED_MAP; +"OPEN_MAP_IMP_QUOTIENT_MAP",OPEN_MAP_IMP_QUOTIENT_MAP; +"OPEN_MEASURABLE_INNER_DIVISION",OPEN_MEASURABLE_INNER_DIVISION; +"OPEN_NEGATIONS",OPEN_NEGATIONS; +"OPEN_NON_GENERAL_COMPONENT",OPEN_NON_GENERAL_COMPONENT; +"OPEN_NON_PATH_COMPONENT",OPEN_NON_PATH_COMPONENT; +"OPEN_NOT_NEGLIGIBLE",OPEN_NOT_NEGLIGIBLE; +"OPEN_OPEN_IN_TRANS",OPEN_OPEN_IN_TRANS; +"OPEN_OPEN_LEFT_PROJECTION",OPEN_OPEN_LEFT_PROJECTION; +"OPEN_OPEN_RIGHT_PROJECTION",OPEN_OPEN_RIGHT_PROJECTION; +"OPEN_OUTSIDE",OPEN_OUTSIDE; +"OPEN_PATH_COMPONENT",OPEN_PATH_COMPONENT; +"OPEN_PATH_CONNECTED_COMPONENT",OPEN_PATH_CONNECTED_COMPONENT; +"OPEN_PCROSS",OPEN_PCROSS; +"OPEN_PCROSS_EQ",OPEN_PCROSS_EQ; +"OPEN_POSITIVE_MULTIPLES",OPEN_POSITIVE_MULTIPLES; +"OPEN_SCALING",OPEN_SCALING; +"OPEN_SEGMENT_1",OPEN_SEGMENT_1; +"OPEN_SEGMENT_ALT",OPEN_SEGMENT_ALT; +"OPEN_SEGMENT_LINEAR_IMAGE",OPEN_SEGMENT_LINEAR_IMAGE; +"OPEN_SET_COCOUNTABLE_COORDINATES",OPEN_SET_COCOUNTABLE_COORDINATES; +"OPEN_SET_COSMALL_COORDINATES",OPEN_SET_COSMALL_COORDINATES; +"OPEN_SET_IRRATIONAL_COORDINATES",OPEN_SET_IRRATIONAL_COORDINATES; +"OPEN_SET_RATIONAL_COORDINATES",OPEN_SET_RATIONAL_COORDINATES; +"OPEN_SLICE",OPEN_SLICE; +"OPEN_SUBOPEN",OPEN_SUBOPEN; +"OPEN_SUBSET",OPEN_SUBSET; +"OPEN_SUBSET_INTERIOR",OPEN_SUBSET_INTERIOR; +"OPEN_SUMS",OPEN_SUMS; +"OPEN_SURJECTIVE_LINEAR_IMAGE",OPEN_SURJECTIVE_LINEAR_IMAGE; +"OPEN_TRANSLATION",OPEN_TRANSLATION; +"OPEN_TRANSLATION_EQ",OPEN_TRANSLATION_EQ; +"OPEN_UNION",OPEN_UNION; +"OPEN_UNIONS",OPEN_UNIONS; +"OPEN_UNION_COMPACT_SUBSETS",OPEN_UNION_COMPACT_SUBSETS; +"OPEN_UNIV",OPEN_UNIV; +"OPEN_WINDING_NUMBER_LEVELSETS",OPEN_WINDING_NUMBER_LEVELSETS; +"OPERATIVE_1_LE",OPERATIVE_1_LE; +"OPERATIVE_1_LT",OPERATIVE_1_LT; +"OPERATIVE_APPROXIMABLE",OPERATIVE_APPROXIMABLE; +"OPERATIVE_CONTENT",OPERATIVE_CONTENT; +"OPERATIVE_DIVISION",OPERATIVE_DIVISION; +"OPERATIVE_DIVISION_AND",OPERATIVE_DIVISION_AND; +"OPERATIVE_EMPTY",OPERATIVE_EMPTY; +"OPERATIVE_FUNCTION_ENDPOINT_DIFF",OPERATIVE_FUNCTION_ENDPOINT_DIFF; +"OPERATIVE_INTEGRABLE",OPERATIVE_INTEGRABLE; +"OPERATIVE_INTEGRAL",OPERATIVE_INTEGRAL; +"OPERATIVE_LIFTED_SETVARIATION",OPERATIVE_LIFTED_SETVARIATION; +"OPERATIVE_LIFTED_VECTOR_VARIATION",OPERATIVE_LIFTED_VECTOR_VARIATION; +"OPERATIVE_REAL_FUNCTION_ENDPOINT_DIFF",OPERATIVE_REAL_FUNCTION_ENDPOINT_DIFF; +"OPERATIVE_TAGGED_DIVISION",OPERATIVE_TAGGED_DIVISION; +"OPERATIVE_TRIVIAL",OPERATIVE_TRIVIAL; +"ORDINAL_CHAINED",ORDINAL_CHAINED; +"ORDINAL_CHAINED_LEMMA",ORDINAL_CHAINED_LEMMA; +"ORDINAL_SUC",ORDINAL_SUC; +"ORDINAL_UNION",ORDINAL_UNION; +"ORDINAL_UNION_LEMMA",ORDINAL_UNION_LEMMA; +"ORDINAL_UP",ORDINAL_UP; +"ORTHGOONAL_TRANSFORMATION_REFLECT_ALONG",ORTHGOONAL_TRANSFORMATION_REFLECT_ALONG; +"ORTHOGONAL_0",ORTHOGONAL_0; +"ORTHOGONAL_ANY_CLOSEST_POINT",ORTHOGONAL_ANY_CLOSEST_POINT; +"ORTHOGONAL_BASIS",ORTHOGONAL_BASIS; +"ORTHOGONAL_BASIS_BASIS",ORTHOGONAL_BASIS_BASIS; +"ORTHOGONAL_BASIS_EXISTS",ORTHOGONAL_BASIS_EXISTS; +"ORTHOGONAL_BASIS_SUBSPACE",ORTHOGONAL_BASIS_SUBSPACE; +"ORTHOGONAL_CLAUSES",ORTHOGONAL_CLAUSES; +"ORTHOGONAL_EXTENSION",ORTHOGONAL_EXTENSION; +"ORTHOGONAL_EXTENSION_STRONG",ORTHOGONAL_EXTENSION_STRONG; +"ORTHOGONAL_LINEAR_IMAGE_EQ",ORTHOGONAL_LINEAR_IMAGE_EQ; +"ORTHOGONAL_LNEG",ORTHOGONAL_LNEG; +"ORTHOGONAL_LVSUM",ORTHOGONAL_LVSUM; +"ORTHOGONAL_MATRIX",ORTHOGONAL_MATRIX; +"ORTHOGONAL_MATRIX_2",ORTHOGONAL_MATRIX_2; +"ORTHOGONAL_MATRIX_2_ALT",ORTHOGONAL_MATRIX_2_ALT; +"ORTHOGONAL_MATRIX_ALT",ORTHOGONAL_MATRIX_ALT; +"ORTHOGONAL_MATRIX_EXISTS_BASIS",ORTHOGONAL_MATRIX_EXISTS_BASIS; +"ORTHOGONAL_MATRIX_ID",ORTHOGONAL_MATRIX_ID; +"ORTHOGONAL_MATRIX_INV",ORTHOGONAL_MATRIX_INV; +"ORTHOGONAL_MATRIX_MATRIX",ORTHOGONAL_MATRIX_MATRIX; +"ORTHOGONAL_MATRIX_MUL",ORTHOGONAL_MATRIX_MUL; +"ORTHOGONAL_MATRIX_ORTHOGONAL_EIGENVECTORS",ORTHOGONAL_MATRIX_ORTHOGONAL_EIGENVECTORS; +"ORTHOGONAL_MATRIX_ORTHONORMAL_COLUMNS",ORTHOGONAL_MATRIX_ORTHONORMAL_COLUMNS; +"ORTHOGONAL_MATRIX_ORTHONORMAL_COLUMNS_INDEXED",ORTHOGONAL_MATRIX_ORTHONORMAL_COLUMNS_INDEXED; +"ORTHOGONAL_MATRIX_ORTHONORMAL_COLUMNS_PAIRWISE",ORTHOGONAL_MATRIX_ORTHONORMAL_COLUMNS_PAIRWISE; +"ORTHOGONAL_MATRIX_ORTHONORMAL_COLUMNS_SPAN",ORTHOGONAL_MATRIX_ORTHONORMAL_COLUMNS_SPAN; +"ORTHOGONAL_MATRIX_ORTHONORMAL_ROWS",ORTHOGONAL_MATRIX_ORTHONORMAL_ROWS; +"ORTHOGONAL_MATRIX_ORTHONORMAL_ROWS_INDEXED",ORTHOGONAL_MATRIX_ORTHONORMAL_ROWS_INDEXED; +"ORTHOGONAL_MATRIX_ORTHONORMAL_ROWS_PAIRWISE",ORTHOGONAL_MATRIX_ORTHONORMAL_ROWS_PAIRWISE; +"ORTHOGONAL_MATRIX_ORTHONORMAL_ROWS_SPAN",ORTHOGONAL_MATRIX_ORTHONORMAL_ROWS_SPAN; +"ORTHOGONAL_MATRIX_TRANSFORMATION",ORTHOGONAL_MATRIX_TRANSFORMATION; +"ORTHOGONAL_MATRIX_TRANSP",ORTHOGONAL_MATRIX_TRANSP; +"ORTHOGONAL_MUL",ORTHOGONAL_MUL; +"ORTHOGONAL_NULLSPACE_ROWSPACE",ORTHOGONAL_NULLSPACE_ROWSPACE; +"ORTHOGONAL_REFL",ORTHOGONAL_REFL; +"ORTHOGONAL_RNEG",ORTHOGONAL_RNEG; +"ORTHOGONAL_ROTATION_OR_ROTOINVERSION",ORTHOGONAL_ROTATION_OR_ROTOINVERSION; +"ORTHOGONAL_RVSUM",ORTHOGONAL_RVSUM; +"ORTHOGONAL_SPANNINGSET_SUBSPACE",ORTHOGONAL_SPANNINGSET_SUBSPACE; +"ORTHOGONAL_SUBSPACE_DECOMP",ORTHOGONAL_SUBSPACE_DECOMP; +"ORTHOGONAL_SUBSPACE_DECOMP_EXISTS",ORTHOGONAL_SUBSPACE_DECOMP_EXISTS; +"ORTHOGONAL_SUBSPACE_DECOMP_UNIQUE",ORTHOGONAL_SUBSPACE_DECOMP_UNIQUE; +"ORTHOGONAL_SYM",ORTHOGONAL_SYM; +"ORTHOGONAL_TO_ORTHOGONAL_2D",ORTHOGONAL_TO_ORTHOGONAL_2D; +"ORTHOGONAL_TO_SPAN",ORTHOGONAL_TO_SPAN; +"ORTHOGONAL_TO_SPANS_EQ",ORTHOGONAL_TO_SPANS_EQ; +"ORTHOGONAL_TO_SPAN_EQ",ORTHOGONAL_TO_SPAN_EQ; +"ORTHOGONAL_TO_SUBSPACE_EXISTS",ORTHOGONAL_TO_SUBSPACE_EXISTS; +"ORTHOGONAL_TO_SUBSPACE_EXISTS_GEN",ORTHOGONAL_TO_SUBSPACE_EXISTS_GEN; +"ORTHOGONAL_TO_VECTOR_EXISTS",ORTHOGONAL_TO_VECTOR_EXISTS; +"ORTHOGONAL_TRANSFORMATION",ORTHOGONAL_TRANSFORMATION; +"ORTHOGONAL_TRANSFORMATION_BETWEEN_ORTHOGONAL_SETS",ORTHOGONAL_TRANSFORMATION_BETWEEN_ORTHOGONAL_SETS; +"ORTHOGONAL_TRANSFORMATION_COMPOSE",ORTHOGONAL_TRANSFORMATION_COMPOSE; +"ORTHOGONAL_TRANSFORMATION_EXISTS",ORTHOGONAL_TRANSFORMATION_EXISTS; +"ORTHOGONAL_TRANSFORMATION_EXISTS_1",ORTHOGONAL_TRANSFORMATION_EXISTS_1; +"ORTHOGONAL_TRANSFORMATION_GENERATED_BY_REFLECTIONS",ORTHOGONAL_TRANSFORMATION_GENERATED_BY_REFLECTIONS; +"ORTHOGONAL_TRANSFORMATION_I",ORTHOGONAL_TRANSFORMATION_I; +"ORTHOGONAL_TRANSFORMATION_ID",ORTHOGONAL_TRANSFORMATION_ID; +"ORTHOGONAL_TRANSFORMATION_INJECTIVE",ORTHOGONAL_TRANSFORMATION_INJECTIVE; +"ORTHOGONAL_TRANSFORMATION_INTO_SUBSPACE",ORTHOGONAL_TRANSFORMATION_INTO_SUBSPACE; +"ORTHOGONAL_TRANSFORMATION_INVERSE",ORTHOGONAL_TRANSFORMATION_INVERSE; +"ORTHOGONAL_TRANSFORMATION_INVERSE_o",ORTHOGONAL_TRANSFORMATION_INVERSE_o; +"ORTHOGONAL_TRANSFORMATION_ISOMETRY",ORTHOGONAL_TRANSFORMATION_ISOMETRY; +"ORTHOGONAL_TRANSFORMATION_LINEAR",ORTHOGONAL_TRANSFORMATION_LINEAR; +"ORTHOGONAL_TRANSFORMATION_LOWDIM_HORIZONTAL",ORTHOGONAL_TRANSFORMATION_LOWDIM_HORIZONTAL; +"ORTHOGONAL_TRANSFORMATION_MATRIX",ORTHOGONAL_TRANSFORMATION_MATRIX; +"ORTHOGONAL_TRANSFORMATION_ONTO_SUBSPACE",ORTHOGONAL_TRANSFORMATION_ONTO_SUBSPACE; +"ORTHOGONAL_TRANSFORMATION_ORTHOGONAL_EIGENVECTORS",ORTHOGONAL_TRANSFORMATION_ORTHOGONAL_EIGENVECTORS; +"ORTHOGONAL_TRANSFORMATION_ROTATE2D",ORTHOGONAL_TRANSFORMATION_ROTATE2D; +"ORTHOGONAL_TRANSFORMATION_SURJECTIVE",ORTHOGONAL_TRANSFORMATION_SURJECTIVE; +"ORTHONORMAL_BASIS_EXPAND",ORTHONORMAL_BASIS_EXPAND; +"ORTHONORMAL_BASIS_SUBSPACE",ORTHONORMAL_BASIS_SUBSPACE; +"ORTHONORMAL_EXTENSION",ORTHONORMAL_EXTENSION; +"OR_CLAUSES",OR_CLAUSES; +"OR_DEF",OR_DEF; +"OR_EXISTS_THM",OR_EXISTS_THM; +"OSTROWSKI_THEOREM",OSTROWSKI_THEOREM; +"OUTER",OUTER; +"OUTERMORPHISM_MBASIS",OUTERMORPHISM_MBASIS; +"OUTERMORPHISM_MBASIS_EMPTY",OUTERMORPHISM_MBASIS_EMPTY; +"OUTER_ACI",OUTER_ACI; +"OUTER_ASSOC",OUTER_ASSOC; +"OUTER_LADD",OUTER_LADD; +"OUTER_LMUL",OUTER_LMUL; +"OUTER_LNEG",OUTER_LNEG; +"OUTER_LZERO",OUTER_LZERO; +"OUTER_MBASIS",OUTER_MBASIS; +"OUTER_MBASIS_LSCALAR",OUTER_MBASIS_LSCALAR; +"OUTER_MBASIS_REFL",OUTER_MBASIS_REFL; +"OUTER_MBASIS_RSCALAR",OUTER_MBASIS_RSCALAR; +"OUTER_MBASIS_SING",OUTER_MBASIS_SING; +"OUTER_MBASIS_SKEWSYM",OUTER_MBASIS_SKEWSYM; +"OUTER_RADD",OUTER_RADD; +"OUTER_RMUL",OUTER_RMUL; +"OUTER_RNEG",OUTER_RNEG; +"OUTER_RZERO",OUTER_RZERO; +"OUTL",OUTL; +"OUTR",OUTR; +"OUTSIDE",OUTSIDE; +"OUTSIDE_BOUNDED_NONEMPTY",OUTSIDE_BOUNDED_NONEMPTY; +"OUTSIDE_COMPACT_IN_OPEN",OUTSIDE_COMPACT_IN_OPEN; +"OUTSIDE_CONNECTED_COMPONENT_LE",OUTSIDE_CONNECTED_COMPONENT_LE; +"OUTSIDE_CONNECTED_COMPONENT_LT",OUTSIDE_CONNECTED_COMPONENT_LT; +"OUTSIDE_CONVEX",OUTSIDE_CONVEX; +"OUTSIDE_EMPTY",OUTSIDE_EMPTY; +"OUTSIDE_FRONTIER_EQ_COMPLEMENT_CLOSURE",OUTSIDE_FRONTIER_EQ_COMPLEMENT_CLOSURE; +"OUTSIDE_FRONTIER_MISSES_CLOSURE",OUTSIDE_FRONTIER_MISSES_CLOSURE; +"OUTSIDE_INSIDE",OUTSIDE_INSIDE; +"OUTSIDE_IN_COMPONENTS",OUTSIDE_IN_COMPONENTS; +"OUTSIDE_LINEAR_IMAGE",OUTSIDE_LINEAR_IMAGE; +"OUTSIDE_MONO",OUTSIDE_MONO; +"OUTSIDE_NO_OVERLAP",OUTSIDE_NO_OVERLAP; +"OUTSIDE_SAME_COMPONENT",OUTSIDE_SAME_COMPONENT; +"OUTSIDE_SUBSET_CONVEX",OUTSIDE_SUBSET_CONVEX; +"OUTSIDE_TRANSLATION",OUTSIDE_TRANSLATION; +"OUTSIDE_UNION_OUTSIDE_UNION",OUTSIDE_UNION_OUTSIDE_UNION; +"PAIR",PAIR; +"PAIRED_ETA_THM",PAIRED_ETA_THM; +"PAIRED_EXT",PAIRED_EXT; +"PAIRWISE",PAIRWISE; +"PAIRWISE_DISJOINT_COMPONENTS",PAIRWISE_DISJOINT_COMPONENTS; +"PAIRWISE_EMPTY",PAIRWISE_EMPTY; +"PAIRWISE_IMAGE",PAIRWISE_IMAGE; +"PAIRWISE_INSERT",PAIRWISE_INSERT; +"PAIRWISE_MONO",PAIRWISE_MONO; +"PAIRWISE_ORTHOGONAL_IMP_FINITE",PAIRWISE_ORTHOGONAL_IMP_FINITE; +"PAIRWISE_ORTHOGONAL_INDEPENDENT",PAIRWISE_ORTHOGONAL_INDEPENDENT; +"PAIRWISE_SING",PAIRWISE_SING; +"PAIR_EQ",PAIR_EQ; +"PAIR_EXISTS_THM",PAIR_EXISTS_THM; +"PAIR_SURJECTIVE",PAIR_SURJECTIVE; +"PARTIAL_DIVISION_EXTEND",PARTIAL_DIVISION_EXTEND; +"PARTIAL_DIVISION_EXTEND_1",PARTIAL_DIVISION_EXTEND_1; +"PARTIAL_DIVISION_EXTEND_INTERVAL",PARTIAL_DIVISION_EXTEND_INTERVAL; +"PARTIAL_DIVISION_OF_TAGGED_DIVISION",PARTIAL_DIVISION_OF_TAGGED_DIVISION; +"PARTIAL_SUMS_COMPONENT_LE_INFSUM",PARTIAL_SUMS_COMPONENT_LE_INFSUM; +"PARTIAL_SUMS_DROP_LE_INFSUM",PARTIAL_SUMS_DROP_LE_INFSUM; +"PASSOC_DEF",PASSOC_DEF; +"PASTECART_ADD",PASTECART_ADD; +"PASTECART_AS_ORTHOGONAL_SUM",PASTECART_AS_ORTHOGONAL_SUM; +"PASTECART_CMUL",PASTECART_CMUL; +"PASTECART_EQ",PASTECART_EQ; +"PASTECART_EQ_VEC",PASTECART_EQ_VEC; +"PASTECART_FST_SND",PASTECART_FST_SND; +"PASTECART_INJ",PASTECART_INJ; +"PASTECART_IN_INTERIOR_SUBTOPOLOGY",PASTECART_IN_INTERIOR_SUBTOPOLOGY; +"PASTECART_IN_PCROSS",PASTECART_IN_PCROSS; +"PASTECART_NEG",PASTECART_NEG; +"PASTECART_SUB",PASTECART_SUB; +"PASTECART_VEC",PASTECART_VEC; +"PASTECART_VSUM",PASTECART_VSUM; +"PASTING_LEMMA",PASTING_LEMMA; +"PASTING_LEMMA_CLOSED",PASTING_LEMMA_CLOSED; +"PASTING_LEMMA_EXISTS",PASTING_LEMMA_EXISTS; +"PASTING_LEMMA_EXISTS_CLOSED",PASTING_LEMMA_EXISTS_CLOSED; +"PATHFINISH_CIRCLEPATH",PATHFINISH_CIRCLEPATH; +"PATHFINISH_COMPOSE",PATHFINISH_COMPOSE; +"PATHFINISH_IN_PATH_IMAGE",PATHFINISH_IN_PATH_IMAGE; +"PATHFINISH_JOIN",PATHFINISH_JOIN; +"PATHFINISH_LINEAR_IMAGE",PATHFINISH_LINEAR_IMAGE; +"PATHFINISH_LINEPATH",PATHFINISH_LINEPATH; +"PATHFINISH_PARTCIRCLEPATH",PATHFINISH_PARTCIRCLEPATH; +"PATHFINISH_REVERSEPATH",PATHFINISH_REVERSEPATH; +"PATHFINISH_SHIFTPATH",PATHFINISH_SHIFTPATH; +"PATHFINISH_SUBPATH",PATHFINISH_SUBPATH; +"PATHFINISH_TRANSLATION",PATHFINISH_TRANSLATION; +"PATHINTEGRAL_CONVEX_PRIMITIVE",PATHINTEGRAL_CONVEX_PRIMITIVE; +"PATHSTART_CIRCLEPATH",PATHSTART_CIRCLEPATH; +"PATHSTART_COMPOSE",PATHSTART_COMPOSE; +"PATHSTART_IN_PATH_IMAGE",PATHSTART_IN_PATH_IMAGE; +"PATHSTART_JOIN",PATHSTART_JOIN; +"PATHSTART_LINEAR_IMAGE_EQ",PATHSTART_LINEAR_IMAGE_EQ; +"PATHSTART_LINEPATH",PATHSTART_LINEPATH; +"PATHSTART_PARTCIRCLEPATH",PATHSTART_PARTCIRCLEPATH; +"PATHSTART_REVERSEPATH",PATHSTART_REVERSEPATH; +"PATHSTART_SHIFTPATH",PATHSTART_SHIFTPATH; +"PATHSTART_SUBPATH",PATHSTART_SUBPATH; +"PATHSTART_TRANSLATION",PATHSTART_TRANSLATION; +"PATH_APPROX_VECTOR_POLYNOMIAL_FUNCTION",PATH_APPROX_VECTOR_POLYNOMIAL_FUNCTION; +"PATH_ASSOC",PATH_ASSOC; +"PATH_COMPONENT",PATH_COMPONENT; +"PATH_COMPONENT_DISJOINT",PATH_COMPONENT_DISJOINT; +"PATH_COMPONENT_EMPTY",PATH_COMPONENT_EMPTY; +"PATH_COMPONENT_EQ",PATH_COMPONENT_EQ; +"PATH_COMPONENT_EQ_CONNECTED_COMPONENT",PATH_COMPONENT_EQ_CONNECTED_COMPONENT; +"PATH_COMPONENT_EQ_EMPTY",PATH_COMPONENT_EQ_EMPTY; +"PATH_COMPONENT_EQ_EQ",PATH_COMPONENT_EQ_EQ; +"PATH_COMPONENT_IMP_HOMOTOPIC_POINTS",PATH_COMPONENT_IMP_HOMOTOPIC_POINTS; +"PATH_COMPONENT_IN",PATH_COMPONENT_IN; +"PATH_COMPONENT_LINEAR_IMAGE",PATH_COMPONENT_LINEAR_IMAGE; +"PATH_COMPONENT_MAXIMAL",PATH_COMPONENT_MAXIMAL; +"PATH_COMPONENT_MONO",PATH_COMPONENT_MONO; +"PATH_COMPONENT_OF_SUBSET",PATH_COMPONENT_OF_SUBSET; +"PATH_COMPONENT_PATH_COMPONENT",PATH_COMPONENT_PATH_COMPONENT; +"PATH_COMPONENT_PATH_IMAGE_PATHSTART",PATH_COMPONENT_PATH_IMAGE_PATHSTART; +"PATH_COMPONENT_REFL",PATH_COMPONENT_REFL; +"PATH_COMPONENT_REFL_EQ",PATH_COMPONENT_REFL_EQ; +"PATH_COMPONENT_SET",PATH_COMPONENT_SET; +"PATH_COMPONENT_SUBSET",PATH_COMPONENT_SUBSET; +"PATH_COMPONENT_SUBSET_CONNECTED_COMPONENT",PATH_COMPONENT_SUBSET_CONNECTED_COMPONENT; +"PATH_COMPONENT_SYM",PATH_COMPONENT_SYM; +"PATH_COMPONENT_SYM_EQ",PATH_COMPONENT_SYM_EQ; +"PATH_COMPONENT_TRANS",PATH_COMPONENT_TRANS; +"PATH_COMPONENT_TRANSLATION",PATH_COMPONENT_TRANSLATION; +"PATH_COMPONENT_UNIV",PATH_COMPONENT_UNIV; +"PATH_COMPOSE_JOIN",PATH_COMPOSE_JOIN; +"PATH_COMPOSE_REVERSEPATH",PATH_COMPOSE_REVERSEPATH; +"PATH_CONNECTED_ANNULUS",PATH_CONNECTED_ANNULUS; +"PATH_CONNECTED_ARCWISE",PATH_CONNECTED_ARCWISE; +"PATH_CONNECTED_ARC_COMPLEMENT",PATH_CONNECTED_ARC_COMPLEMENT; +"PATH_CONNECTED_COMPLEMENT_ABSOLUTE_RETRACT",PATH_CONNECTED_COMPLEMENT_ABSOLUTE_RETRACT; +"PATH_CONNECTED_COMPLEMENT_BOUNDED_CONVEX",PATH_CONNECTED_COMPLEMENT_BOUNDED_CONVEX; +"PATH_CONNECTED_COMPLEMENT_CARD_LT",PATH_CONNECTED_COMPLEMENT_CARD_LT; +"PATH_CONNECTED_COMPLEMENT_HOMEOMORPHIC_CONVEX_COMPACT",PATH_CONNECTED_COMPLEMENT_HOMEOMORPHIC_CONVEX_COMPACT; +"PATH_CONNECTED_COMPONENT_SET",PATH_CONNECTED_COMPONENT_SET; +"PATH_CONNECTED_CONTINUOUS_IMAGE",PATH_CONNECTED_CONTINUOUS_IMAGE; +"PATH_CONNECTED_CONVEX_DIFF_CARD_LT",PATH_CONNECTED_CONVEX_DIFF_CARD_LT; +"PATH_CONNECTED_DIFF_BALL",PATH_CONNECTED_DIFF_BALL; +"PATH_CONNECTED_EMPTY",PATH_CONNECTED_EMPTY; +"PATH_CONNECTED_EQ_CONNECTED",PATH_CONNECTED_EQ_CONNECTED; +"PATH_CONNECTED_EQ_CONNECTED_LPC",PATH_CONNECTED_EQ_CONNECTED_LPC; +"PATH_CONNECTED_EQ_HOMOTOPIC_POINTS",PATH_CONNECTED_EQ_HOMOTOPIC_POINTS; +"PATH_CONNECTED_IFF_PATH_COMPONENT",PATH_CONNECTED_IFF_PATH_COMPONENT; +"PATH_CONNECTED_IMP_CONNECTED",PATH_CONNECTED_IMP_CONNECTED; +"PATH_CONNECTED_INTERVAL",PATH_CONNECTED_INTERVAL; +"PATH_CONNECTED_LINEAR_IMAGE",PATH_CONNECTED_LINEAR_IMAGE; +"PATH_CONNECTED_LINEAR_IMAGE_EQ",PATH_CONNECTED_LINEAR_IMAGE_EQ; +"PATH_CONNECTED_LINEPATH",PATH_CONNECTED_LINEPATH; +"PATH_CONNECTED_NEGATIONS",PATH_CONNECTED_NEGATIONS; +"PATH_CONNECTED_OPEN_DELETE",PATH_CONNECTED_OPEN_DELETE; +"PATH_CONNECTED_OPEN_DIFF_CARD_LT",PATH_CONNECTED_OPEN_DIFF_CARD_LT; +"PATH_CONNECTED_OPEN_DIFF_COUNTABLE",PATH_CONNECTED_OPEN_DIFF_COUNTABLE; +"PATH_CONNECTED_OPEN_IN_DIFF_CARD_LT",PATH_CONNECTED_OPEN_IN_DIFF_CARD_LT; +"PATH_CONNECTED_PATH_COMPONENT",PATH_CONNECTED_PATH_COMPONENT; +"PATH_CONNECTED_PATH_IMAGE",PATH_CONNECTED_PATH_IMAGE; +"PATH_CONNECTED_PCROSS",PATH_CONNECTED_PCROSS; +"PATH_CONNECTED_PCROSS_EQ",PATH_CONNECTED_PCROSS_EQ; +"PATH_CONNECTED_PUNCTURED_BALL",PATH_CONNECTED_PUNCTURED_BALL; +"PATH_CONNECTED_PUNCTURED_UNIVERSE",PATH_CONNECTED_PUNCTURED_UNIVERSE; +"PATH_CONNECTED_SCALING",PATH_CONNECTED_SCALING; +"PATH_CONNECTED_SEGMENT",PATH_CONNECTED_SEGMENT; +"PATH_CONNECTED_SEMIOPEN_SEGMENT",PATH_CONNECTED_SEMIOPEN_SEGMENT; +"PATH_CONNECTED_SING",PATH_CONNECTED_SING; +"PATH_CONNECTED_SPHERE",PATH_CONNECTED_SPHERE; +"PATH_CONNECTED_SPHERE_EQ",PATH_CONNECTED_SPHERE_EQ; +"PATH_CONNECTED_SUMS",PATH_CONNECTED_SUMS; +"PATH_CONNECTED_TRANSLATION",PATH_CONNECTED_TRANSLATION; +"PATH_CONNECTED_TRANSLATION_EQ",PATH_CONNECTED_TRANSLATION_EQ; +"PATH_CONNECTED_UNION",PATH_CONNECTED_UNION; +"PATH_CONNECTED_UNIV",PATH_CONNECTED_UNIV; +"PATH_CONTAINS_ARC",PATH_CONTAINS_ARC; +"PATH_CONTINUOUS_IMAGE",PATH_CONTINUOUS_IMAGE; +"PATH_EQ",PATH_EQ; +"PATH_IMAGE_CIRCLEPATH",PATH_IMAGE_CIRCLEPATH; +"PATH_IMAGE_COMPOSE",PATH_IMAGE_COMPOSE; +"PATH_IMAGE_JOIN",PATH_IMAGE_JOIN; +"PATH_IMAGE_JOIN_SUBSET",PATH_IMAGE_JOIN_SUBSET; +"PATH_IMAGE_LINEAR_IMAGE",PATH_IMAGE_LINEAR_IMAGE; +"PATH_IMAGE_LINEPATH",PATH_IMAGE_LINEPATH; +"PATH_IMAGE_NONEMPTY",PATH_IMAGE_NONEMPTY; +"PATH_IMAGE_PARTCIRCLEPATH",PATH_IMAGE_PARTCIRCLEPATH; +"PATH_IMAGE_PARTCIRCLEPATH_SUBSET",PATH_IMAGE_PARTCIRCLEPATH_SUBSET; +"PATH_IMAGE_REVERSEPATH",PATH_IMAGE_REVERSEPATH; +"PATH_IMAGE_SHIFTPATH",PATH_IMAGE_SHIFTPATH; +"PATH_IMAGE_SUBPATH",PATH_IMAGE_SUBPATH; +"PATH_IMAGE_SUBPATH_GEN",PATH_IMAGE_SUBPATH_GEN; +"PATH_IMAGE_SUBPATH_SUBSET",PATH_IMAGE_SUBPATH_SUBSET; +"PATH_IMAGE_SYM",PATH_IMAGE_SYM; +"PATH_IMAGE_TRANSLATION",PATH_IMAGE_TRANSLATION; +"PATH_INTEGRABLE_ADD",PATH_INTEGRABLE_ADD; +"PATH_INTEGRABLE_COMPLEX_DIV",PATH_INTEGRABLE_COMPLEX_DIV; +"PATH_INTEGRABLE_COMPLEX_LMUL",PATH_INTEGRABLE_COMPLEX_LMUL; +"PATH_INTEGRABLE_COMPLEX_RMUL",PATH_INTEGRABLE_COMPLEX_RMUL; +"PATH_INTEGRABLE_CONTINUOUS_CIRCLEPATH",PATH_INTEGRABLE_CONTINUOUS_CIRCLEPATH; +"PATH_INTEGRABLE_CONTINUOUS_LINEPATH",PATH_INTEGRABLE_CONTINUOUS_LINEPATH; +"PATH_INTEGRABLE_CONTINUOUS_PARTCIRCLEPATH",PATH_INTEGRABLE_CONTINUOUS_PARTCIRCLEPATH; +"PATH_INTEGRABLE_EQ",PATH_INTEGRABLE_EQ; +"PATH_INTEGRABLE_HOLOMORPHIC",PATH_INTEGRABLE_HOLOMORPHIC; +"PATH_INTEGRABLE_HOLOMORPHIC_SIMPLE",PATH_INTEGRABLE_HOLOMORPHIC_SIMPLE; +"PATH_INTEGRABLE_INVERSEDIFF",PATH_INTEGRABLE_INVERSEDIFF; +"PATH_INTEGRABLE_JOIN",PATH_INTEGRABLE_JOIN; +"PATH_INTEGRABLE_NEG",PATH_INTEGRABLE_NEG; +"PATH_INTEGRABLE_ON",PATH_INTEGRABLE_ON; +"PATH_INTEGRABLE_REVERSEPATH",PATH_INTEGRABLE_REVERSEPATH; +"PATH_INTEGRABLE_REVERSEPATH_EQ",PATH_INTEGRABLE_REVERSEPATH_EQ; +"PATH_INTEGRABLE_SUB",PATH_INTEGRABLE_SUB; +"PATH_INTEGRABLE_SUBPATH",PATH_INTEGRABLE_SUBPATH; +"PATH_INTEGRABLE_SUBPATH_REFL",PATH_INTEGRABLE_SUBPATH_REFL; +"PATH_INTEGRABLE_VSUM",PATH_INTEGRABLE_VSUM; +"PATH_INTEGRAL_0",PATH_INTEGRAL_0; +"PATH_INTEGRAL_ADD",PATH_INTEGRAL_ADD; +"PATH_INTEGRAL_BOUND_EXISTS",PATH_INTEGRAL_BOUND_EXISTS; +"PATH_INTEGRAL_BOUND_LINEPATH",PATH_INTEGRAL_BOUND_LINEPATH; +"PATH_INTEGRAL_COMPLEX_DIV",PATH_INTEGRAL_COMPLEX_DIV; +"PATH_INTEGRAL_COMPLEX_LMUL",PATH_INTEGRAL_COMPLEX_LMUL; +"PATH_INTEGRAL_COMPLEX_RMUL",PATH_INTEGRAL_COMPLEX_RMUL; +"PATH_INTEGRAL_CONST_LINEPATH",PATH_INTEGRAL_CONST_LINEPATH; +"PATH_INTEGRAL_EQ",PATH_INTEGRAL_EQ; +"PATH_INTEGRAL_EQ_0",PATH_INTEGRAL_EQ_0; +"PATH_INTEGRAL_INTEGRAL",PATH_INTEGRAL_INTEGRAL; +"PATH_INTEGRAL_JOIN",PATH_INTEGRAL_JOIN; +"PATH_INTEGRAL_LOCAL_PRIMITIVE",PATH_INTEGRAL_LOCAL_PRIMITIVE; +"PATH_INTEGRAL_LOCAL_PRIMITIVE_ANY",PATH_INTEGRAL_LOCAL_PRIMITIVE_ANY; +"PATH_INTEGRAL_LOCAL_PRIMITIVE_LEMMA",PATH_INTEGRAL_LOCAL_PRIMITIVE_LEMMA; +"PATH_INTEGRAL_MIDPOINT",PATH_INTEGRAL_MIDPOINT; +"PATH_INTEGRAL_NEARBY_ENDS",PATH_INTEGRAL_NEARBY_ENDS; +"PATH_INTEGRAL_NEARBY_LOOP",PATH_INTEGRAL_NEARBY_LOOP; +"PATH_INTEGRAL_NEG",PATH_INTEGRAL_NEG; +"PATH_INTEGRAL_PRIMITIVE",PATH_INTEGRAL_PRIMITIVE; +"PATH_INTEGRAL_PRIMITIVE_LEMMA",PATH_INTEGRAL_PRIMITIVE_LEMMA; +"PATH_INTEGRAL_REVERSEPATH",PATH_INTEGRAL_REVERSEPATH; +"PATH_INTEGRAL_REVERSE_LINEPATH",PATH_INTEGRAL_REVERSE_LINEPATH; +"PATH_INTEGRAL_SHIFTPATH",PATH_INTEGRAL_SHIFTPATH; +"PATH_INTEGRAL_SPLIT",PATH_INTEGRAL_SPLIT; +"PATH_INTEGRAL_SPLIT_LINEPATH",PATH_INTEGRAL_SPLIT_LINEPATH; +"PATH_INTEGRAL_SUB",PATH_INTEGRAL_SUB; +"PATH_INTEGRAL_SUBPATH_COMBINE",PATH_INTEGRAL_SUBPATH_COMBINE; +"PATH_INTEGRAL_SUBPATH_INTEGRAL",PATH_INTEGRAL_SUBPATH_INTEGRAL; +"PATH_INTEGRAL_SUBPATH_REFL",PATH_INTEGRAL_SUBPATH_REFL; +"PATH_INTEGRAL_SWAP",PATH_INTEGRAL_SWAP; +"PATH_INTEGRAL_TRIVIAL",PATH_INTEGRAL_TRIVIAL; +"PATH_INTEGRAL_UNIFORM_LIMIT",PATH_INTEGRAL_UNIFORM_LIMIT; +"PATH_INTEGRAL_UNIFORM_LIMIT_CIRCLEPATH",PATH_INTEGRAL_UNIFORM_LIMIT_CIRCLEPATH; +"PATH_INTEGRAL_UNIQUE",PATH_INTEGRAL_UNIQUE; +"PATH_INTEGRAL_VSUM",PATH_INTEGRAL_VSUM; +"PATH_JOIN",PATH_JOIN; +"PATH_JOIN_EQ",PATH_JOIN_EQ; +"PATH_JOIN_IMP",PATH_JOIN_IMP; +"PATH_JOIN_PATH_ENDS",PATH_JOIN_PATH_ENDS; +"PATH_LENGTH_DIFFERENTIABLE",PATH_LENGTH_DIFFERENTIABLE; +"PATH_LENGTH_JOIN",PATH_LENGTH_JOIN; +"PATH_LENGTH_REVERSEPATH",PATH_LENGTH_REVERSEPATH; +"PATH_LENGTH_VALID_PATH",PATH_LENGTH_VALID_PATH; +"PATH_LINEAR_IMAGE_EQ",PATH_LINEAR_IMAGE_EQ; +"PATH_LINEPATH",PATH_LINEPATH; +"PATH_PARTCIRCLEPATH",PATH_PARTCIRCLEPATH; +"PATH_REVERSEPATH",PATH_REVERSEPATH; +"PATH_SHIFTPATH",PATH_SHIFTPATH; +"PATH_SUBPATH",PATH_SUBPATH; +"PATH_SYM",PATH_SYM; +"PATH_TRANSLATION_EQ",PATH_TRANSLATION_EQ; +"PATH_VECTOR_POLYNOMIAL_FUNCTION",PATH_VECTOR_POLYNOMIAL_FUNCTION; +"PCROSS",PCROSS; +"PCROSS_AS_ORTHOGONAL_SUM",PCROSS_AS_ORTHOGONAL_SUM; +"PCROSS_EMPTY",PCROSS_EMPTY; +"PCROSS_EQ",PCROSS_EQ; +"PCROSS_EQ_EMPTY",PCROSS_EQ_EMPTY; +"PCROSS_INTER",PCROSS_INTER; +"PCROSS_INTERVAL",PCROSS_INTERVAL; +"PCROSS_MONO",PCROSS_MONO; +"PCROSS_UNION",PCROSS_UNION; +"PCROSS_UNIONS",PCROSS_UNIONS; +"PCROSS_UNIONS_UNIONS",PCROSS_UNIONS_UNIONS; +"PERMUTATION",PERMUTATION; +"PERMUTATION_BIJECTIVE",PERMUTATION_BIJECTIVE; +"PERMUTATION_COMPOSE",PERMUTATION_COMPOSE; +"PERMUTATION_COMPOSE_EQ",PERMUTATION_COMPOSE_EQ; +"PERMUTATION_COMPOSE_SWAP",PERMUTATION_COMPOSE_SWAP; +"PERMUTATION_FINITE_SUPPORT",PERMUTATION_FINITE_SUPPORT; +"PERMUTATION_I",PERMUTATION_I; +"PERMUTATION_INVERSE",PERMUTATION_INVERSE; +"PERMUTATION_INVERSE_COMPOSE",PERMUTATION_INVERSE_COMPOSE; +"PERMUTATION_INVERSE_WORKS",PERMUTATION_INVERSE_WORKS; +"PERMUTATION_LEMMA",PERMUTATION_LEMMA; +"PERMUTATION_PERMUTES",PERMUTATION_PERMUTES; +"PERMUTATION_SWAP",PERMUTATION_SWAP; +"PERMUTES_COMPOSE",PERMUTES_COMPOSE; +"PERMUTES_EMPTY",PERMUTES_EMPTY; +"PERMUTES_FINITE_INJECTIVE",PERMUTES_FINITE_INJECTIVE; +"PERMUTES_FINITE_SURJECTIVE",PERMUTES_FINITE_SURJECTIVE; +"PERMUTES_I",PERMUTES_I; +"PERMUTES_IMAGE",PERMUTES_IMAGE; +"PERMUTES_INDUCT",PERMUTES_INDUCT; +"PERMUTES_INJECTIVE",PERMUTES_INJECTIVE; +"PERMUTES_INSERT",PERMUTES_INSERT; +"PERMUTES_INSERT_LEMMA",PERMUTES_INSERT_LEMMA; +"PERMUTES_INVERSE",PERMUTES_INVERSE; +"PERMUTES_INVERSES",PERMUTES_INVERSES; +"PERMUTES_INVERSES_o",PERMUTES_INVERSES_o; +"PERMUTES_INVERSE_EQ",PERMUTES_INVERSE_EQ; +"PERMUTES_INVERSE_INVERSE",PERMUTES_INVERSE_INVERSE; +"PERMUTES_IN_IMAGE",PERMUTES_IN_IMAGE; +"PERMUTES_IN_NUMSEG",PERMUTES_IN_NUMSEG; +"PERMUTES_NUMSET_GE",PERMUTES_NUMSET_GE; +"PERMUTES_NUMSET_LE",PERMUTES_NUMSET_LE; +"PERMUTES_SING",PERMUTES_SING; +"PERMUTES_SUBSET",PERMUTES_SUBSET; +"PERMUTES_SUPERSET",PERMUTES_SUPERSET; +"PERMUTES_SURJECTIVE",PERMUTES_SURJECTIVE; +"PERMUTES_SWAP",PERMUTES_SWAP; +"PERMUTES_UNIV",PERMUTES_UNIV; +"PI2_BOUNDS",PI2_BOUNDS; +"PIECEWISE_DIFFERENTIABLE_ADD",PIECEWISE_DIFFERENTIABLE_ADD; +"PIECEWISE_DIFFERENTIABLE_AFFINE",PIECEWISE_DIFFERENTIABLE_AFFINE; +"PIECEWISE_DIFFERENTIABLE_CASES",PIECEWISE_DIFFERENTIABLE_CASES; +"PIECEWISE_DIFFERENTIABLE_COMPOSE",PIECEWISE_DIFFERENTIABLE_COMPOSE; +"PIECEWISE_DIFFERENTIABLE_NEG",PIECEWISE_DIFFERENTIABLE_NEG; +"PIECEWISE_DIFFERENTIABLE_ON_IMP_CONTINUOUS_ON",PIECEWISE_DIFFERENTIABLE_ON_IMP_CONTINUOUS_ON; +"PIECEWISE_DIFFERENTIABLE_ON_SUBSET",PIECEWISE_DIFFERENTIABLE_ON_SUBSET; +"PIECEWISE_DIFFERENTIABLE_SUB",PIECEWISE_DIFFERENTIABLE_SUB; +"PI_APPROX_32",PI_APPROX_32; +"PI_NZ",PI_NZ; +"PI_POS",PI_POS; +"PI_POS_LE",PI_POS_LE; +"PI_WORKS",PI_WORKS; +"POINTS_IN_CONVEX_HULL",POINTS_IN_CONVEX_HULL; +"POINTWISE_ANTISYM",POINTWISE_ANTISYM; +"POINTWISE_MAXIMAL",POINTWISE_MAXIMAL; +"POINTWISE_MINIMAL",POINTWISE_MINIMAL; +"POLE_LEMMA",POLE_LEMMA; +"POLE_LEMMA_OPEN",POLE_LEMMA_OPEN; +"POLE_THEOREM",POLE_THEOREM; +"POLE_THEOREM_0",POLE_THEOREM_0; +"POLE_THEOREM_ANALYTIC",POLE_THEOREM_ANALYTIC; +"POLE_THEOREM_ANALYTIC_0",POLE_THEOREM_ANALYTIC_0; +"POLE_THEOREM_ANALYTIC_OPEN_SUPERSET",POLE_THEOREM_ANALYTIC_OPEN_SUPERSET; +"POLE_THEOREM_ANALYTIC_OPEN_SUPERSET_0",POLE_THEOREM_ANALYTIC_OPEN_SUPERSET_0; +"POLE_THEOREM_OPEN",POLE_THEOREM_OPEN; +"POLE_THEOREM_OPEN_0",POLE_THEOREM_OPEN_0; +"POLYHEDRON_AFFINE_HULL",POLYHEDRON_AFFINE_HULL; +"POLYHEDRON_AS_CONE_PLUS_CONV",POLYHEDRON_AS_CONE_PLUS_CONV; +"POLYHEDRON_CONVEX_CONE_HULL",POLYHEDRON_CONVEX_CONE_HULL; +"POLYHEDRON_CONVEX_HULL",POLYHEDRON_CONVEX_HULL; +"POLYHEDRON_EMPTY",POLYHEDRON_EMPTY; +"POLYHEDRON_EQ_FINITE_EXPOSED_FACES",POLYHEDRON_EQ_FINITE_EXPOSED_FACES; +"POLYHEDRON_EQ_FINITE_FACES",POLYHEDRON_EQ_FINITE_FACES; +"POLYHEDRON_HALFSPACE_GE",POLYHEDRON_HALFSPACE_GE; +"POLYHEDRON_HALFSPACE_LE",POLYHEDRON_HALFSPACE_LE; +"POLYHEDRON_HYPERPLANE",POLYHEDRON_HYPERPLANE; +"POLYHEDRON_IMP_CLOSED",POLYHEDRON_IMP_CLOSED; +"POLYHEDRON_IMP_CONVEX",POLYHEDRON_IMP_CONVEX; +"POLYHEDRON_INTER",POLYHEDRON_INTER; +"POLYHEDRON_INTERS",POLYHEDRON_INTERS; +"POLYHEDRON_INTERVAL",POLYHEDRON_INTERVAL; +"POLYHEDRON_INTER_AFFINE",POLYHEDRON_INTER_AFFINE; +"POLYHEDRON_INTER_AFFINE_MINIMAL",POLYHEDRON_INTER_AFFINE_MINIMAL; +"POLYHEDRON_INTER_AFFINE_PARALLEL",POLYHEDRON_INTER_AFFINE_PARALLEL; +"POLYHEDRON_INTER_AFFINE_PARALLEL_MINIMAL",POLYHEDRON_INTER_AFFINE_PARALLEL_MINIMAL; +"POLYHEDRON_INTER_POLYTOPE",POLYHEDRON_INTER_POLYTOPE; +"POLYHEDRON_LINEAR_IMAGE",POLYHEDRON_LINEAR_IMAGE; +"POLYHEDRON_LINEAR_IMAGE_EQ",POLYHEDRON_LINEAR_IMAGE_EQ; +"POLYHEDRON_NEGATIONS",POLYHEDRON_NEGATIONS; +"POLYHEDRON_POLYTOPE_SUMS",POLYHEDRON_POLYTOPE_SUMS; +"POLYHEDRON_POSITIVE_ORTHANT",POLYHEDRON_POSITIVE_ORTHANT; +"POLYHEDRON_RIDGE_TWO_FACETS",POLYHEDRON_RIDGE_TWO_FACETS; +"POLYHEDRON_SUMS",POLYHEDRON_SUMS; +"POLYHEDRON_TRANSLATION_EQ",POLYHEDRON_TRANSLATION_EQ; +"POLYHEDRON_UNIV",POLYHEDRON_UNIV; +"POLYTOPE_CONVEX_HULL",POLYTOPE_CONVEX_HULL; +"POLYTOPE_EMPTY",POLYTOPE_EMPTY; +"POLYTOPE_EQ_BOUNDED_POLYHEDRON",POLYTOPE_EQ_BOUNDED_POLYHEDRON; +"POLYTOPE_FACET_EXISTS",POLYTOPE_FACET_EXISTS; +"POLYTOPE_FACET_LOWER_BOUND",POLYTOPE_FACET_LOWER_BOUND; +"POLYTOPE_IMP_BOUNDED",POLYTOPE_IMP_BOUNDED; +"POLYTOPE_IMP_CLOSED",POLYTOPE_IMP_CLOSED; +"POLYTOPE_IMP_COMPACT",POLYTOPE_IMP_COMPACT; +"POLYTOPE_IMP_CONVEX",POLYTOPE_IMP_CONVEX; +"POLYTOPE_IMP_POLYHEDRON",POLYTOPE_IMP_POLYHEDRON; +"POLYTOPE_INTER",POLYTOPE_INTER; +"POLYTOPE_INTERVAL",POLYTOPE_INTERVAL; +"POLYTOPE_INTER_POLYHEDRON",POLYTOPE_INTER_POLYHEDRON; +"POLYTOPE_LINEAR_IMAGE",POLYTOPE_LINEAR_IMAGE; +"POLYTOPE_LINEAR_IMAGE_EQ",POLYTOPE_LINEAR_IMAGE_EQ; +"POLYTOPE_NEGATIONS",POLYTOPE_NEGATIONS; +"POLYTOPE_PCROSS",POLYTOPE_PCROSS; +"POLYTOPE_PCROSS_EQ",POLYTOPE_PCROSS_EQ; +"POLYTOPE_SCALING",POLYTOPE_SCALING; +"POLYTOPE_SCALING_EQ",POLYTOPE_SCALING_EQ; +"POLYTOPE_SING",POLYTOPE_SING; +"POLYTOPE_SUMS",POLYTOPE_SUMS; +"POLYTOPE_TRANSLATION_EQ",POLYTOPE_TRANSLATION_EQ; +"POLYTOPE_UNION_CONVEX_HULL_FACETS",POLYTOPE_UNION_CONVEX_HULL_FACETS; +"POLYTOPE_VERTEX_LOWER_BOUND",POLYTOPE_VERTEX_LOWER_BOUND; +"POSET_ANTISYM",POSET_ANTISYM; +"POSET_FLEQ",POSET_FLEQ; +"POSET_REFL",POSET_REFL; +"POSET_RESTRICTED_SUBSET",POSET_RESTRICTED_SUBSET; +"POSET_TRANS",POSET_TRANS; +"POWERSET_CLAUSES",POWERSET_CLAUSES; +"POWER_REAL_SERIES_CONV_IMP_ABSCONV_WEAK",POWER_REAL_SERIES_CONV_IMP_ABSCONV_WEAK; +"POWER_SERIES_ANALYTIC",POWER_SERIES_ANALYTIC; +"POWER_SERIES_AND_DERIVATIVE",POWER_SERIES_AND_DERIVATIVE; +"POWER_SERIES_AND_DERIVATIVE_0",POWER_SERIES_AND_DERIVATIVE_0; +"POWER_SERIES_CONV_IMP_ABSCONV",POWER_SERIES_CONV_IMP_ABSCONV; +"POWER_SERIES_CONV_IMP_ABSCONV_WEAK",POWER_SERIES_CONV_IMP_ABSCONV_WEAK; +"POWER_SERIES_HOLOMORPHIC",POWER_SERIES_HOLOMORPHIC; +"POWER_SERIES_UNIFORM_CONVERGENCE_STOLZ",POWER_SERIES_UNIFORM_CONVERGENCE_STOLZ; +"POWER_SERIES_UNIFORM_CONVERGENCE_STOLZ_1",POWER_SERIES_UNIFORM_CONVERGENCE_STOLZ_1; +"POW_2_CSQRT",POW_2_CSQRT; +"POW_2_SQRT",POW_2_SQRT; +"POW_2_SQRT_ABS",POW_2_SQRT_ABS; +"PRE",PRE; +"PRESERVES_LEBESGUE_MEASURABLE_IMP_PRESERVES_NEGLIGIBLE",PRESERVES_LEBESGUE_MEASURABLE_IMP_PRESERVES_NEGLIGIBLE; +"PRESERVES_NORM_INJECTIVE",PRESERVES_NORM_INJECTIVE; +"PRESERVES_NORM_PRESERVES_DOT",PRESERVES_NORM_PRESERVES_DOT; +"PRE_ELIM_THM",PRE_ELIM_THM; +"PRE_ELIM_THM'",PRE_ELIM_THM'; +"PRODUCT_1",PRODUCT_1; +"PRODUCT_2",PRODUCT_2; +"PRODUCT_3",PRODUCT_3; +"PRODUCT_4",PRODUCT_4; +"PRODUCT_ABS",PRODUCT_ABS; +"PRODUCT_ADD_SPLIT",PRODUCT_ADD_SPLIT; +"PRODUCT_ASSOCIATIVE",PRODUCT_ASSOCIATIVE; +"PRODUCT_CLAUSES",PRODUCT_CLAUSES; +"PRODUCT_CLAUSES_LEFT",PRODUCT_CLAUSES_LEFT; +"PRODUCT_CLAUSES_NUMSEG",PRODUCT_CLAUSES_NUMSEG; +"PRODUCT_CLAUSES_RIGHT",PRODUCT_CLAUSES_RIGHT; +"PRODUCT_CLOSED",PRODUCT_CLOSED; +"PRODUCT_CONST",PRODUCT_CONST; +"PRODUCT_CONST_NUMSEG",PRODUCT_CONST_NUMSEG; +"PRODUCT_CONST_NUMSEG_1",PRODUCT_CONST_NUMSEG_1; +"PRODUCT_DIV",PRODUCT_DIV; +"PRODUCT_DIV_NUMSEG",PRODUCT_DIV_NUMSEG; +"PRODUCT_EQ",PRODUCT_EQ; +"PRODUCT_EQ_0",PRODUCT_EQ_0; +"PRODUCT_EQ_0_NUMSEG",PRODUCT_EQ_0_NUMSEG; +"PRODUCT_EQ_1",PRODUCT_EQ_1; +"PRODUCT_EQ_1_NUMSEG",PRODUCT_EQ_1_NUMSEG; +"PRODUCT_EQ_NUMSEG",PRODUCT_EQ_NUMSEG; +"PRODUCT_IMAGE",PRODUCT_IMAGE; +"PRODUCT_INV",PRODUCT_INV; +"PRODUCT_LADD",PRODUCT_LADD; +"PRODUCT_LE",PRODUCT_LE; +"PRODUCT_LE_1",PRODUCT_LE_1; +"PRODUCT_LE_NUMSEG",PRODUCT_LE_NUMSEG; +"PRODUCT_LMUL",PRODUCT_LMUL; +"PRODUCT_LNEG",PRODUCT_LNEG; +"PRODUCT_LZERO",PRODUCT_LZERO; +"PRODUCT_MBASIS",PRODUCT_MBASIS; +"PRODUCT_MBASIS_SING",PRODUCT_MBASIS_SING; +"PRODUCT_MUL",PRODUCT_MUL; +"PRODUCT_MUL_NUMSEG",PRODUCT_MUL_NUMSEG; +"PRODUCT_NEG",PRODUCT_NEG; +"PRODUCT_NEG_NUMSEG",PRODUCT_NEG_NUMSEG; +"PRODUCT_NEG_NUMSEG_1",PRODUCT_NEG_NUMSEG_1; +"PRODUCT_OFFSET",PRODUCT_OFFSET; +"PRODUCT_ONE",PRODUCT_ONE; +"PRODUCT_PERMUTE",PRODUCT_PERMUTE; +"PRODUCT_PERMUTE_NUMSEG",PRODUCT_PERMUTE_NUMSEG; +"PRODUCT_POS_LE",PRODUCT_POS_LE; +"PRODUCT_POS_LE_NUMSEG",PRODUCT_POS_LE_NUMSEG; +"PRODUCT_POS_LT",PRODUCT_POS_LT; +"PRODUCT_POS_LT_NUMSEG",PRODUCT_POS_LT_NUMSEG; +"PRODUCT_RADD",PRODUCT_RADD; +"PRODUCT_RMUL",PRODUCT_RMUL; +"PRODUCT_RNEG",PRODUCT_RNEG; +"PRODUCT_RZERO",PRODUCT_RZERO; +"PRODUCT_SING",PRODUCT_SING; +"PRODUCT_SING_NUMSEG",PRODUCT_SING_NUMSEG; +"PRODUCT_UNION",PRODUCT_UNION; +"PROPERTY_EMPTY_INTERVAL",PROPERTY_EMPTY_INTERVAL; +"PROPER_MAP",PROPER_MAP; +"PROPER_MAP_FROM_COMPACT",PROPER_MAP_FROM_COMPACT; +"PSUBSET",PSUBSET; +"PSUBSET_ALT",PSUBSET_ALT; +"PSUBSET_INSERT_SUBSET",PSUBSET_INSERT_SUBSET; +"PSUBSET_IRREFL",PSUBSET_IRREFL; +"PSUBSET_MEMBER",PSUBSET_MEMBER; +"PSUBSET_SUBSET_TRANS",PSUBSET_SUBSET_TRANS; +"PSUBSET_TRANS",PSUBSET_TRANS; +"PSUBSET_UNIV",PSUBSET_UNIV; +"PUSHIN_DROPOUT",PUSHIN_DROPOUT; +"P_HULL",P_HULL; +"Product_DEF",Product_DEF; +"QUANTIFY_SURJECTION_HIGHER_THM",QUANTIFY_SURJECTION_HIGHER_THM; +"QUANTIFY_SURJECTION_THM",QUANTIFY_SURJECTION_THM; +"QUOTIENT_MAP_OPEN_CLOSED",QUOTIENT_MAP_OPEN_CLOSED; +"RADON",RADON; +"RADON_EX_LEMMA",RADON_EX_LEMMA; +"RADON_PARTITION",RADON_PARTITION; +"RADON_S_LEMMA",RADON_S_LEMMA; +"RADON_V_LEMMA",RADON_V_LEMMA; +"RANK_0",RANK_0; +"RANK_BOUND",RANK_BOUND; +"RANK_DIM_IM",RANK_DIM_IM; +"RANK_EQ_0",RANK_EQ_0; +"RANK_GRAM",RANK_GRAM; +"RANK_I",RANK_I; +"RANK_MUL_LE_LEFT",RANK_MUL_LE_LEFT; +"RANK_MUL_LE_RIGHT",RANK_MUL_LE_RIGHT; +"RANK_NULLSPACE",RANK_NULLSPACE; +"RANK_ROW",RANK_ROW; +"RANK_SYLVESTER",RANK_SYLVESTER; +"RANK_TRANSP",RANK_TRANSP; +"RANK_TRIANGLE",RANK_TRIANGLE; +"RATIONAL_ABS",RATIONAL_ABS; +"RATIONAL_ADD",RATIONAL_ADD; +"RATIONAL_ALT",RATIONAL_ALT; +"RATIONAL_APPROXIMATION",RATIONAL_APPROXIMATION; +"RATIONAL_APPROXIMATION_STRADDLE",RATIONAL_APPROXIMATION_STRADDLE; +"RATIONAL_BETWEEN",RATIONAL_BETWEEN; +"RATIONAL_CLOSED",RATIONAL_CLOSED; +"RATIONAL_DIV",RATIONAL_DIV; +"RATIONAL_INTEGER",RATIONAL_INTEGER; +"RATIONAL_INV",RATIONAL_INV; +"RATIONAL_INV_EQ",RATIONAL_INV_EQ; +"RATIONAL_MUL",RATIONAL_MUL; +"RATIONAL_NEG",RATIONAL_NEG; +"RATIONAL_NEG_EQ",RATIONAL_NEG_EQ; +"RATIONAL_NUM",RATIONAL_NUM; +"RATIONAL_POW",RATIONAL_POW; +"RATIONAL_SUB",RATIONAL_SUB; +"RAT_LEMMA1",RAT_LEMMA1; +"RAT_LEMMA2",RAT_LEMMA2; +"RAT_LEMMA3",RAT_LEMMA3; +"RAT_LEMMA4",RAT_LEMMA4; +"RAT_LEMMA5",RAT_LEMMA5; +"RAY_TO_FRONTIER",RAY_TO_FRONTIER; +"RAY_TO_RELATIVE_FRONTIER",RAY_TO_RELATIVE_FRONTIER; +"RE",RE; +"REAL",REAL; +"REALLIM",REALLIM; +"REALLIM_1_OVER_LOG",REALLIM_1_OVER_LOG; +"REALLIM_1_OVER_N",REALLIM_1_OVER_N; +"REALLIM_ABS",REALLIM_ABS; +"REALLIM_ADD",REALLIM_ADD; +"REALLIM_AT",REALLIM_AT; +"REALLIM_ATREAL",REALLIM_ATREAL; +"REALLIM_ATREAL_AT",REALLIM_ATREAL_AT; +"REALLIM_ATREAL_ID",REALLIM_ATREAL_ID; +"REALLIM_ATREAL_WITHINREAL",REALLIM_ATREAL_WITHINREAL; +"REALLIM_AT_INFINITY",REALLIM_AT_INFINITY; +"REALLIM_AT_NEGINFINITY",REALLIM_AT_NEGINFINITY; +"REALLIM_AT_POSINFINITY",REALLIM_AT_POSINFINITY; +"REALLIM_COMPLEX",REALLIM_COMPLEX; +"REALLIM_CONG_AT",REALLIM_CONG_AT; +"REALLIM_CONG_ATREAL",REALLIM_CONG_ATREAL; +"REALLIM_CONG_WITHIN",REALLIM_CONG_WITHIN; +"REALLIM_CONG_WITHINREAL",REALLIM_CONG_WITHINREAL; +"REALLIM_CONST",REALLIM_CONST; +"REALLIM_CONST_EQ",REALLIM_CONST_EQ; +"REALLIM_CONTINUOUS_FUNCTION",REALLIM_CONTINUOUS_FUNCTION; +"REALLIM_DIV",REALLIM_DIV; +"REALLIM_EVENTUALLY",REALLIM_EVENTUALLY; +"REALLIM_IM",REALLIM_IM; +"REALLIM_INV",REALLIM_INV; +"REALLIM_LBOUND",REALLIM_LBOUND; +"REALLIM_LE",REALLIM_LE; +"REALLIM_LMUL",REALLIM_LMUL; +"REALLIM_LMUL_EQ",REALLIM_LMUL_EQ; +"REALLIM_LOG_OVER_N",REALLIM_LOG_OVER_N; +"REALLIM_MAX",REALLIM_MAX; +"REALLIM_MIN",REALLIM_MIN; +"REALLIM_MUL",REALLIM_MUL; +"REALLIM_NEG",REALLIM_NEG; +"REALLIM_NEG_EQ",REALLIM_NEG_EQ; +"REALLIM_NULL",REALLIM_NULL; +"REALLIM_NULL_ABS",REALLIM_NULL_ABS; +"REALLIM_NULL_ADD",REALLIM_NULL_ADD; +"REALLIM_NULL_COMPARISON",REALLIM_NULL_COMPARISON; +"REALLIM_NULL_LMUL",REALLIM_NULL_LMUL; +"REALLIM_NULL_LMUL_EQ",REALLIM_NULL_LMUL_EQ; +"REALLIM_NULL_POW",REALLIM_NULL_POW; +"REALLIM_NULL_POW_EQ",REALLIM_NULL_POW_EQ; +"REALLIM_NULL_RMUL",REALLIM_NULL_RMUL; +"REALLIM_NULL_RMUL_EQ",REALLIM_NULL_RMUL_EQ; +"REALLIM_POSINFINITY_SEQUENTIALLY",REALLIM_POSINFINITY_SEQUENTIALLY; +"REALLIM_POW",REALLIM_POW; +"REALLIM_POWN",REALLIM_POWN; +"REALLIM_RE",REALLIM_RE; +"REALLIM_REAL_CONTINUOUS_FUNCTION",REALLIM_REAL_CONTINUOUS_FUNCTION; +"REALLIM_RMUL",REALLIM_RMUL; +"REALLIM_RMUL_EQ",REALLIM_RMUL_EQ; +"REALLIM_RPOW",REALLIM_RPOW; +"REALLIM_SEQUENTIALLY",REALLIM_SEQUENTIALLY; +"REALLIM_SUB",REALLIM_SUB; +"REALLIM_SUM",REALLIM_SUM; +"REALLIM_TRANSFORM",REALLIM_TRANSFORM; +"REALLIM_TRANSFORM_BOUND",REALLIM_TRANSFORM_BOUND; +"REALLIM_TRANSFORM_EQ",REALLIM_TRANSFORM_EQ; +"REALLIM_TRANSFORM_EVENTUALLY",REALLIM_TRANSFORM_EVENTUALLY; +"REALLIM_TRANSFORM_STRADDLE",REALLIM_TRANSFORM_STRADDLE; +"REALLIM_TRANSFORM_WITHINREAL_SET",REALLIM_TRANSFORM_WITHINREAL_SET; +"REALLIM_TRANSFORM_WITHIN_SET",REALLIM_TRANSFORM_WITHIN_SET; +"REALLIM_UBOUND",REALLIM_UBOUND; +"REALLIM_UNIQUE",REALLIM_UNIQUE; +"REALLIM_WITHIN",REALLIM_WITHIN; +"REALLIM_WITHINREAL",REALLIM_WITHINREAL; +"REALLIM_WITHINREAL_ID",REALLIM_WITHINREAL_ID; +"REALLIM_WITHINREAL_LE",REALLIM_WITHINREAL_LE; +"REALLIM_WITHINREAL_SUBSET",REALLIM_WITHINREAL_SUBSET; +"REALLIM_WITHINREAL_WITHIN",REALLIM_WITHINREAL_WITHIN; +"REALLIM_WITHIN_LE",REALLIM_WITHIN_LE; +"REALLIM_WITHIN_OPEN",REALLIM_WITHIN_OPEN; +"REALLIM_WITHIN_REAL_OPEN",REALLIM_WITHIN_REAL_OPEN; +"REALLIM_WITHIN_SUBSET",REALLIM_WITHIN_SUBSET; +"REALLIM_ZERO_NEGINFINITY",REALLIM_ZERO_NEGINFINITY; +"REALLIM_ZERO_POSINFINITY",REALLIM_ZERO_POSINFINITY; +"REAL_ABEL_LEMMA",REAL_ABEL_LEMMA; +"REAL_ABEL_LIMIT_THEOREM",REAL_ABEL_LIMIT_THEOREM; +"REAL_ABS_0",REAL_ABS_0; +"REAL_ABS_1",REAL_ABS_1; +"REAL_ABS_ABS",REAL_ABS_ABS; +"REAL_ABS_BETWEEN",REAL_ABS_BETWEEN; +"REAL_ABS_BETWEEN1",REAL_ABS_BETWEEN1; +"REAL_ABS_BETWEEN2",REAL_ABS_BETWEEN2; +"REAL_ABS_BOUND",REAL_ABS_BOUND; +"REAL_ABS_BOUNDS",REAL_ABS_BOUNDS; +"REAL_ABS_CASES",REAL_ABS_CASES; +"REAL_ABS_CIRCLE",REAL_ABS_CIRCLE; +"REAL_ABS_DIV",REAL_ABS_DIV; +"REAL_ABS_EXP",REAL_ABS_EXP; +"REAL_ABS_INFNORM",REAL_ABS_INFNORM; +"REAL_ABS_INF_LE",REAL_ABS_INF_LE; +"REAL_ABS_INTEGER_LEMMA",REAL_ABS_INTEGER_LEMMA; +"REAL_ABS_INV",REAL_ABS_INV; +"REAL_ABS_LE",REAL_ABS_LE; +"REAL_ABS_MUL",REAL_ABS_MUL; +"REAL_ABS_NEG",REAL_ABS_NEG; +"REAL_ABS_NORM",REAL_ABS_NORM; +"REAL_ABS_NUM",REAL_ABS_NUM; +"REAL_ABS_NZ",REAL_ABS_NZ; +"REAL_ABS_PI",REAL_ABS_PI; +"REAL_ABS_POS",REAL_ABS_POS; +"REAL_ABS_POW",REAL_ABS_POW; +"REAL_ABS_REFL",REAL_ABS_REFL; +"REAL_ABS_RPOW",REAL_ABS_RPOW; +"REAL_ABS_SGN",REAL_ABS_SGN; +"REAL_ABS_SIGN",REAL_ABS_SIGN; +"REAL_ABS_SIGN2",REAL_ABS_SIGN2; +"REAL_ABS_STILLNZ",REAL_ABS_STILLNZ; +"REAL_ABS_SUB",REAL_ABS_SUB; +"REAL_ABS_SUB_ABS",REAL_ABS_SUB_ABS; +"REAL_ABS_SUB_INFNORM",REAL_ABS_SUB_INFNORM; +"REAL_ABS_SUB_NORM",REAL_ABS_SUB_NORM; +"REAL_ABS_SUP_LE",REAL_ABS_SUP_LE; +"REAL_ABS_TRIANGLE",REAL_ABS_TRIANGLE; +"REAL_ABS_TRIANGLE_LE",REAL_ABS_TRIANGLE_LE; +"REAL_ABS_TRIANGLE_LT",REAL_ABS_TRIANGLE_LT; +"REAL_ABS_ZERO",REAL_ABS_ZERO; +"REAL_ACS",REAL_ACS; +"REAL_ADD",REAL_ADD; +"REAL_ADD2_SUB2",REAL_ADD2_SUB2; +"REAL_ADD_AC",REAL_ADD_AC; +"REAL_ADD_ARG",REAL_ADD_ARG; +"REAL_ADD_ASSOC",REAL_ADD_ASSOC; +"REAL_ADD_COS",REAL_ADD_COS; +"REAL_ADD_LDISTRIB",REAL_ADD_LDISTRIB; +"REAL_ADD_LID",REAL_ADD_LID; +"REAL_ADD_LINV",REAL_ADD_LINV; +"REAL_ADD_RDISTRIB",REAL_ADD_RDISTRIB; +"REAL_ADD_RID",REAL_ADD_RID; +"REAL_ADD_RINV",REAL_ADD_RINV; +"REAL_ADD_SIN",REAL_ADD_SIN; +"REAL_ADD_SUB",REAL_ADD_SUB; +"REAL_ADD_SUB2",REAL_ADD_SUB2; +"REAL_ADD_SYM",REAL_ADD_SYM; +"REAL_ADD_TAN",REAL_ADD_TAN; +"REAL_AFFINITY_EQ",REAL_AFFINITY_EQ; +"REAL_AFFINITY_LE",REAL_AFFINITY_LE; +"REAL_AFFINITY_LT",REAL_AFFINITY_LT; +"REAL_ANTIDERIVATIVE_CONTINUOUS",REAL_ANTIDERIVATIVE_CONTINUOUS; +"REAL_ANTIDERIVATIVE_INTEGRAL_CONTINUOUS",REAL_ANTIDERIVATIVE_INTEGRAL_CONTINUOUS; +"REAL_ARCH",REAL_ARCH; +"REAL_ARCH_INV",REAL_ARCH_INV; +"REAL_ARCH_LT",REAL_ARCH_LT; +"REAL_ARCH_POW",REAL_ARCH_POW; +"REAL_ARCH_POW2",REAL_ARCH_POW2; +"REAL_ARCH_POW_INV",REAL_ARCH_POW_INV; +"REAL_ARCH_RDIV_EQ_0",REAL_ARCH_RDIV_EQ_0; +"REAL_ARCH_SIMPLE",REAL_ARCH_SIMPLE; +"REAL_ASN",REAL_ASN; +"REAL_BEPPO_LEVI_DECREASING",REAL_BEPPO_LEVI_DECREASING; +"REAL_BEPPO_LEVI_INCREASING",REAL_BEPPO_LEVI_INCREASING; +"REAL_BEPPO_LEVI_MONOTONE_CONVERGENCE_DECREASING",REAL_BEPPO_LEVI_MONOTONE_CONVERGENCE_DECREASING; +"REAL_BEPPO_LEVI_MONOTONE_CONVERGENCE_INCREASING",REAL_BEPPO_LEVI_MONOTONE_CONVERGENCE_INCREASING; +"REAL_BINOMIAL_THEOREM",REAL_BINOMIAL_THEOREM; +"REAL_BOUNDED",REAL_BOUNDED; +"REAL_BOUNDED_POS",REAL_BOUNDED_POS; +"REAL_BOUNDED_POS_LT",REAL_BOUNDED_POS_LT; +"REAL_BOUNDED_REAL_INTERVAL",REAL_BOUNDED_REAL_INTERVAL; +"REAL_BOUNDED_SUBSET",REAL_BOUNDED_SUBSET; +"REAL_BOUNDED_UNION",REAL_BOUNDED_UNION; +"REAL_BOUNDS_LE",REAL_BOUNDS_LE; +"REAL_BOUNDS_LT",REAL_BOUNDS_LT; +"REAL_CARD_INTSEG_INT",REAL_CARD_INTSEG_INT; +"REAL_CLOSED",REAL_CLOSED; +"REAL_CLOSED_DIFF",REAL_CLOSED_DIFF; +"REAL_CLOSED_EMPTY",REAL_CLOSED_EMPTY; +"REAL_CLOSED_HALFSPACE_GE",REAL_CLOSED_HALFSPACE_GE; +"REAL_CLOSED_HALFSPACE_LE",REAL_CLOSED_HALFSPACE_LE; +"REAL_CLOSED_IN",REAL_CLOSED_IN; +"REAL_CLOSED_INTER",REAL_CLOSED_INTER; +"REAL_CLOSED_INTERS",REAL_CLOSED_INTERS; +"REAL_CLOSED_OPEN_INTERVAL",REAL_CLOSED_OPEN_INTERVAL; +"REAL_CLOSED_REAL_INTERVAL",REAL_CLOSED_REAL_INTERVAL; +"REAL_CLOSED_UNION",REAL_CLOSED_UNION; +"REAL_CLOSED_UNIONS",REAL_CLOSED_UNIONS; +"REAL_CLOSED_UNIV",REAL_CLOSED_UNIV; +"REAL_CNJ",REAL_CNJ; +"REAL_COMPACT_ATTAINS_INF",REAL_COMPACT_ATTAINS_INF; +"REAL_COMPACT_ATTAINS_SUP",REAL_COMPACT_ATTAINS_SUP; +"REAL_COMPACT_CONTINUOUS_IMAGE",REAL_COMPACT_CONTINUOUS_IMAGE; +"REAL_COMPACT_EQ_BOUNDED_CLOSED",REAL_COMPACT_EQ_BOUNDED_CLOSED; +"REAL_COMPACT_IMP_BOUNDED",REAL_COMPACT_IMP_BOUNDED; +"REAL_COMPACT_IMP_CLOSED",REAL_COMPACT_IMP_CLOSED; +"REAL_COMPACT_INTERVAL",REAL_COMPACT_INTERVAL; +"REAL_COMPACT_UNIFORMLY_CONTINUOUS",REAL_COMPACT_UNIFORMLY_CONTINUOUS; +"REAL_COMPACT_UNION",REAL_COMPACT_UNION; +"REAL_COMPLETE",REAL_COMPLETE; +"REAL_COMPLETE_SOMEPOS",REAL_COMPLETE_SOMEPOS; +"REAL_COMPLEX_CONTINUOUS_ATREAL",REAL_COMPLEX_CONTINUOUS_ATREAL; +"REAL_COMPLEX_CONTINUOUS_WITHINREAL",REAL_COMPLEX_CONTINUOUS_WITHINREAL; +"REAL_COMPLEX_MEASURABLE_ON",REAL_COMPLEX_MEASURABLE_ON; +"REAL_CONTINUOUS_ABS",REAL_CONTINUOUS_ABS; +"REAL_CONTINUOUS_ADD",REAL_CONTINUOUS_ADD; +"REAL_CONTINUOUS_ADDITIVE_EXTEND",REAL_CONTINUOUS_ADDITIVE_EXTEND; +"REAL_CONTINUOUS_ADDITIVE_IMP_LINEAR",REAL_CONTINUOUS_ADDITIVE_IMP_LINEAR; +"REAL_CONTINUOUS_ADDITIVE_IMP_LINEAR_INTERVAL",REAL_CONTINUOUS_ADDITIVE_IMP_LINEAR_INTERVAL; +"REAL_CONTINUOUS_AT",REAL_CONTINUOUS_AT; +"REAL_CONTINUOUS_ATREAL",REAL_CONTINUOUS_ATREAL; +"REAL_CONTINUOUS_ATREAL_COMPOSE",REAL_CONTINUOUS_ATREAL_COMPOSE; +"REAL_CONTINUOUS_ATREAL_SQRT_COMPOSE",REAL_CONTINUOUS_ATREAL_SQRT_COMPOSE; +"REAL_CONTINUOUS_ATREAL_WITHINREAL",REAL_CONTINUOUS_ATREAL_WITHINREAL; +"REAL_CONTINUOUS_ATTAINS_INF",REAL_CONTINUOUS_ATTAINS_INF; +"REAL_CONTINUOUS_ATTAINS_SUP",REAL_CONTINUOUS_ATTAINS_SUP; +"REAL_CONTINUOUS_AT_ACS",REAL_CONTINUOUS_AT_ACS; +"REAL_CONTINUOUS_AT_ARG",REAL_CONTINUOUS_AT_ARG; +"REAL_CONTINUOUS_AT_ASN",REAL_CONTINUOUS_AT_ASN; +"REAL_CONTINUOUS_AT_ATN",REAL_CONTINUOUS_AT_ATN; +"REAL_CONTINUOUS_AT_COMPONENT",REAL_CONTINUOUS_AT_COMPONENT; +"REAL_CONTINUOUS_AT_COMPOSE",REAL_CONTINUOUS_AT_COMPOSE; +"REAL_CONTINUOUS_AT_COS",REAL_CONTINUOUS_AT_COS; +"REAL_CONTINUOUS_AT_EXP",REAL_CONTINUOUS_AT_EXP; +"REAL_CONTINUOUS_AT_ID",REAL_CONTINUOUS_AT_ID; +"REAL_CONTINUOUS_AT_LINEAR_IMAGE",REAL_CONTINUOUS_AT_LINEAR_IMAGE; +"REAL_CONTINUOUS_AT_LOG",REAL_CONTINUOUS_AT_LOG; +"REAL_CONTINUOUS_AT_RPOW",REAL_CONTINUOUS_AT_RPOW; +"REAL_CONTINUOUS_AT_SIN",REAL_CONTINUOUS_AT_SIN; +"REAL_CONTINUOUS_AT_SQRT",REAL_CONTINUOUS_AT_SQRT; +"REAL_CONTINUOUS_AT_SQRT_COMPOSE",REAL_CONTINUOUS_AT_SQRT_COMPOSE; +"REAL_CONTINUOUS_AT_TAN",REAL_CONTINUOUS_AT_TAN; +"REAL_CONTINUOUS_AT_TRANSLATION",REAL_CONTINUOUS_AT_TRANSLATION; +"REAL_CONTINUOUS_AT_WITHIN",REAL_CONTINUOUS_AT_WITHIN; +"REAL_CONTINUOUS_COMPLEX_COMPONENTS_AT",REAL_CONTINUOUS_COMPLEX_COMPONENTS_AT; +"REAL_CONTINUOUS_COMPLEX_COMPONENTS_WITHIN",REAL_CONTINUOUS_COMPLEX_COMPONENTS_WITHIN; +"REAL_CONTINUOUS_CONST",REAL_CONTINUOUS_CONST; +"REAL_CONTINUOUS_CONTINUOUS",REAL_CONTINUOUS_CONTINUOUS; +"REAL_CONTINUOUS_CONTINUOUS1",REAL_CONTINUOUS_CONTINUOUS1; +"REAL_CONTINUOUS_CONTINUOUS_ATREAL",REAL_CONTINUOUS_CONTINUOUS_ATREAL; +"REAL_CONTINUOUS_CONTINUOUS_ATREAL_COMPOSE",REAL_CONTINUOUS_CONTINUOUS_ATREAL_COMPOSE; +"REAL_CONTINUOUS_CONTINUOUS_AT_COMPOSE",REAL_CONTINUOUS_CONTINUOUS_AT_COMPOSE; +"REAL_CONTINUOUS_CONTINUOUS_WITHINREAL",REAL_CONTINUOUS_CONTINUOUS_WITHINREAL; +"REAL_CONTINUOUS_CONTINUOUS_WITHINREAL_COMPOSE",REAL_CONTINUOUS_CONTINUOUS_WITHINREAL_COMPOSE; +"REAL_CONTINUOUS_CONTINUOUS_WITHIN_COMPOSE",REAL_CONTINUOUS_CONTINUOUS_WITHIN_COMPOSE; +"REAL_CONTINUOUS_DIST_AT",REAL_CONTINUOUS_DIST_AT; +"REAL_CONTINUOUS_DIST_WITHIN",REAL_CONTINUOUS_DIST_WITHIN; +"REAL_CONTINUOUS_DIV",REAL_CONTINUOUS_DIV; +"REAL_CONTINUOUS_DIV_AT",REAL_CONTINUOUS_DIV_AT; +"REAL_CONTINUOUS_DIV_ATREAL",REAL_CONTINUOUS_DIV_ATREAL; +"REAL_CONTINUOUS_DIV_WITHIN",REAL_CONTINUOUS_DIV_WITHIN; +"REAL_CONTINUOUS_DIV_WITHINREAL",REAL_CONTINUOUS_DIV_WITHINREAL; +"REAL_CONTINUOUS_FLOOR",REAL_CONTINUOUS_FLOOR; +"REAL_CONTINUOUS_FRAC",REAL_CONTINUOUS_FRAC; +"REAL_CONTINUOUS_IMP_REAL_MEASURABLE_ON_CLOSED_SUBSET",REAL_CONTINUOUS_IMP_REAL_MEASURABLE_ON_CLOSED_SUBSET; +"REAL_CONTINUOUS_INJECTIVE_IFF_MONOTONIC",REAL_CONTINUOUS_INJECTIVE_IFF_MONOTONIC; +"REAL_CONTINUOUS_INV",REAL_CONTINUOUS_INV; +"REAL_CONTINUOUS_INV_AT",REAL_CONTINUOUS_INV_AT; +"REAL_CONTINUOUS_INV_ATREAL",REAL_CONTINUOUS_INV_ATREAL; +"REAL_CONTINUOUS_INV_WITHIN",REAL_CONTINUOUS_INV_WITHIN; +"REAL_CONTINUOUS_INV_WITHINREAL",REAL_CONTINUOUS_INV_WITHINREAL; +"REAL_CONTINUOUS_LMUL",REAL_CONTINUOUS_LMUL; +"REAL_CONTINUOUS_MAX",REAL_CONTINUOUS_MAX; +"REAL_CONTINUOUS_MEASURE_IN_HALFSPACE_LE",REAL_CONTINUOUS_MEASURE_IN_HALFSPACE_LE; +"REAL_CONTINUOUS_MIN",REAL_CONTINUOUS_MIN; +"REAL_CONTINUOUS_MUL",REAL_CONTINUOUS_MUL; +"REAL_CONTINUOUS_NEG",REAL_CONTINUOUS_NEG; +"REAL_CONTINUOUS_NORM_AT",REAL_CONTINUOUS_NORM_AT; +"REAL_CONTINUOUS_NORM_WITHIN",REAL_CONTINUOUS_NORM_WITHIN; +"REAL_CONTINUOUS_ON",REAL_CONTINUOUS_ON; +"REAL_CONTINUOUS_ON_ACS",REAL_CONTINUOUS_ON_ACS; +"REAL_CONTINUOUS_ON_ADD",REAL_CONTINUOUS_ON_ADD; +"REAL_CONTINUOUS_ON_ASN",REAL_CONTINUOUS_ON_ASN; +"REAL_CONTINUOUS_ON_ATN",REAL_CONTINUOUS_ON_ATN; +"REAL_CONTINUOUS_ON_CASES",REAL_CONTINUOUS_ON_CASES; +"REAL_CONTINUOUS_ON_CASES_OPEN",REAL_CONTINUOUS_ON_CASES_OPEN; +"REAL_CONTINUOUS_ON_COMPOSE",REAL_CONTINUOUS_ON_COMPOSE; +"REAL_CONTINUOUS_ON_COMPOSE_FRAC",REAL_CONTINUOUS_ON_COMPOSE_FRAC; +"REAL_CONTINUOUS_ON_CONST",REAL_CONTINUOUS_ON_CONST; +"REAL_CONTINUOUS_ON_CONST_DYADIC_RATIONALS",REAL_CONTINUOUS_ON_CONST_DYADIC_RATIONALS; +"REAL_CONTINUOUS_ON_COS",REAL_CONTINUOUS_ON_COS; +"REAL_CONTINUOUS_ON_EQ",REAL_CONTINUOUS_ON_EQ; +"REAL_CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN",REAL_CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN; +"REAL_CONTINUOUS_ON_EQ_REAL_CONTINUOUS_AT",REAL_CONTINUOUS_ON_EQ_REAL_CONTINUOUS_AT; +"REAL_CONTINUOUS_ON_EXP",REAL_CONTINUOUS_ON_EXP; +"REAL_CONTINUOUS_ON_ID",REAL_CONTINUOUS_ON_ID; +"REAL_CONTINUOUS_ON_INVERSE",REAL_CONTINUOUS_ON_INVERSE; +"REAL_CONTINUOUS_ON_INVERSE_ALT",REAL_CONTINUOUS_ON_INVERSE_ALT; +"REAL_CONTINUOUS_ON_LMUL",REAL_CONTINUOUS_ON_LMUL; +"REAL_CONTINUOUS_ON_LOG",REAL_CONTINUOUS_ON_LOG; +"REAL_CONTINUOUS_ON_MUL",REAL_CONTINUOUS_ON_MUL; +"REAL_CONTINUOUS_ON_NEG",REAL_CONTINUOUS_ON_NEG; +"REAL_CONTINUOUS_ON_POW",REAL_CONTINUOUS_ON_POW; +"REAL_CONTINUOUS_ON_RMUL",REAL_CONTINUOUS_ON_RMUL; +"REAL_CONTINUOUS_ON_RPOW",REAL_CONTINUOUS_ON_RPOW; +"REAL_CONTINUOUS_ON_SIN",REAL_CONTINUOUS_ON_SIN; +"REAL_CONTINUOUS_ON_SQRT",REAL_CONTINUOUS_ON_SQRT; +"REAL_CONTINUOUS_ON_SUB",REAL_CONTINUOUS_ON_SUB; +"REAL_CONTINUOUS_ON_SUBSET",REAL_CONTINUOUS_ON_SUBSET; +"REAL_CONTINUOUS_ON_SUM",REAL_CONTINUOUS_ON_SUM; +"REAL_CONTINUOUS_ON_TAN",REAL_CONTINUOUS_ON_TAN; +"REAL_CONTINUOUS_ON_UNION",REAL_CONTINUOUS_ON_UNION; +"REAL_CONTINUOUS_ON_UNION_OPEN",REAL_CONTINUOUS_ON_UNION_OPEN; +"REAL_CONTINUOUS_POW",REAL_CONTINUOUS_POW; +"REAL_CONTINUOUS_REAL_CONTINUOUS_ATREAL",REAL_CONTINUOUS_REAL_CONTINUOUS_ATREAL; +"REAL_CONTINUOUS_REAL_CONTINUOUS_WITHINREAL",REAL_CONTINUOUS_REAL_CONTINUOUS_WITHINREAL; +"REAL_CONTINUOUS_REAL_POLYMONIAL_FUNCTION",REAL_CONTINUOUS_REAL_POLYMONIAL_FUNCTION; +"REAL_CONTINUOUS_RMUL",REAL_CONTINUOUS_RMUL; +"REAL_CONTINUOUS_SUB",REAL_CONTINUOUS_SUB; +"REAL_CONTINUOUS_TRIVIAL_LIMIT",REAL_CONTINUOUS_TRIVIAL_LIMIT; +"REAL_CONTINUOUS_WITHIN",REAL_CONTINUOUS_WITHIN; +"REAL_CONTINUOUS_WITHINREAL",REAL_CONTINUOUS_WITHINREAL; +"REAL_CONTINUOUS_WITHINREAL_COMPOSE",REAL_CONTINUOUS_WITHINREAL_COMPOSE; +"REAL_CONTINUOUS_WITHINREAL_SQRT_COMPOSE",REAL_CONTINUOUS_WITHINREAL_SQRT_COMPOSE; +"REAL_CONTINUOUS_WITHINREAL_SUBSET",REAL_CONTINUOUS_WITHINREAL_SUBSET; +"REAL_CONTINUOUS_WITHIN_ACS",REAL_CONTINUOUS_WITHIN_ACS; +"REAL_CONTINUOUS_WITHIN_ACS_STRONG",REAL_CONTINUOUS_WITHIN_ACS_STRONG; +"REAL_CONTINUOUS_WITHIN_ASN",REAL_CONTINUOUS_WITHIN_ASN; +"REAL_CONTINUOUS_WITHIN_ASN_STRONG",REAL_CONTINUOUS_WITHIN_ASN_STRONG; +"REAL_CONTINUOUS_WITHIN_ATN",REAL_CONTINUOUS_WITHIN_ATN; +"REAL_CONTINUOUS_WITHIN_COMPOSE",REAL_CONTINUOUS_WITHIN_COMPOSE; +"REAL_CONTINUOUS_WITHIN_COS",REAL_CONTINUOUS_WITHIN_COS; +"REAL_CONTINUOUS_WITHIN_EXP",REAL_CONTINUOUS_WITHIN_EXP; +"REAL_CONTINUOUS_WITHIN_ID",REAL_CONTINUOUS_WITHIN_ID; +"REAL_CONTINUOUS_WITHIN_LOG",REAL_CONTINUOUS_WITHIN_LOG; +"REAL_CONTINUOUS_WITHIN_RPOW",REAL_CONTINUOUS_WITHIN_RPOW; +"REAL_CONTINUOUS_WITHIN_SIN",REAL_CONTINUOUS_WITHIN_SIN; +"REAL_CONTINUOUS_WITHIN_SQRT",REAL_CONTINUOUS_WITHIN_SQRT; +"REAL_CONTINUOUS_WITHIN_SQRT_COMPOSE",REAL_CONTINUOUS_WITHIN_SQRT_COMPOSE; +"REAL_CONTINUOUS_WITHIN_SQRT_STRONG",REAL_CONTINUOUS_WITHIN_SQRT_STRONG; +"REAL_CONTINUOUS_WITHIN_SUBSET",REAL_CONTINUOUS_WITHIN_SUBSET; +"REAL_CONTINUOUS_WITHIN_TAN",REAL_CONTINUOUS_WITHIN_TAN; +"REAL_CONVERGENT_IMP_BOUNDED",REAL_CONVERGENT_IMP_BOUNDED; +"REAL_CONVEX_ADD",REAL_CONVEX_ADD; +"REAL_CONVEX_BOUND2_LT",REAL_CONVEX_BOUND2_LT; +"REAL_CONVEX_BOUND_LE",REAL_CONVEX_BOUND_LE; +"REAL_CONVEX_BOUND_LT",REAL_CONVEX_BOUND_LT; +"REAL_CONVEX_DISTANCE",REAL_CONVEX_DISTANCE; +"REAL_CONVEX_LMUL",REAL_CONVEX_LMUL; +"REAL_CONVEX_LOCAL_GLOBAL_MINIMUM",REAL_CONVEX_LOCAL_GLOBAL_MINIMUM; +"REAL_CONVEX_LOWER",REAL_CONVEX_LOWER; +"REAL_CONVEX_ON",REAL_CONVEX_ON; +"REAL_CONVEX_ON_ASYM",REAL_CONVEX_ON_ASYM; +"REAL_CONVEX_ON_CONTINUOUS",REAL_CONVEX_ON_CONTINUOUS; +"REAL_CONVEX_ON_DERIVATIVES",REAL_CONVEX_ON_DERIVATIVES; +"REAL_CONVEX_ON_DERIVATIVES_IMP",REAL_CONVEX_ON_DERIVATIVES_IMP; +"REAL_CONVEX_ON_DERIVATIVE_INCREASING",REAL_CONVEX_ON_DERIVATIVE_INCREASING; +"REAL_CONVEX_ON_DERIVATIVE_INCREASING_IMP",REAL_CONVEX_ON_DERIVATIVE_INCREASING_IMP; +"REAL_CONVEX_ON_DERIVATIVE_SECANT",REAL_CONVEX_ON_DERIVATIVE_SECANT; +"REAL_CONVEX_ON_DERIVATIVE_SECANT_IMP",REAL_CONVEX_ON_DERIVATIVE_SECANT_IMP; +"REAL_CONVEX_ON_EXP",REAL_CONVEX_ON_EXP; +"REAL_CONVEX_ON_JENSEN",REAL_CONVEX_ON_JENSEN; +"REAL_CONVEX_ON_LEFT_SECANT",REAL_CONVEX_ON_LEFT_SECANT; +"REAL_CONVEX_ON_LEFT_SECANT_MUL",REAL_CONVEX_ON_LEFT_SECANT_MUL; +"REAL_CONVEX_ON_RIGHT_SEQUENT",REAL_CONVEX_ON_RIGHT_SEQUENT; +"REAL_CONVEX_ON_RIGHT_SEQUENT_MUL",REAL_CONVEX_ON_RIGHT_SEQUENT_MUL; +"REAL_CONVEX_ON_RPOW",REAL_CONVEX_ON_RPOW; +"REAL_CONVEX_ON_SECANT_DERIVATIVE",REAL_CONVEX_ON_SECANT_DERIVATIVE; +"REAL_CONVEX_ON_SECANT_DERIVATIVE_IMP",REAL_CONVEX_ON_SECANT_DERIVATIVE_IMP; +"REAL_CONVEX_ON_SECOND_DERIVATIVE",REAL_CONVEX_ON_SECOND_DERIVATIVE; +"REAL_CONVEX_ON_SUBSET",REAL_CONVEX_ON_SUBSET; +"REAL_CONVEX_RMUL",REAL_CONVEX_RMUL; +"REAL_COS",REAL_COS; +"REAL_CX",REAL_CX; +"REAL_DERIVATIVE_IVT_DECREASING",REAL_DERIVATIVE_IVT_DECREASING; +"REAL_DERIVATIVE_IVT_INCREASING",REAL_DERIVATIVE_IVT_INCREASING; +"REAL_DERIVATIVE_NEG_LEFT_MAXIMUM",REAL_DERIVATIVE_NEG_LEFT_MAXIMUM; +"REAL_DERIVATIVE_NEG_RIGHT_MINIMUM",REAL_DERIVATIVE_NEG_RIGHT_MINIMUM; +"REAL_DERIVATIVE_POS_LEFT_MINIMUM",REAL_DERIVATIVE_POS_LEFT_MINIMUM; +"REAL_DERIVATIVE_POS_RIGHT_MAXIMUM",REAL_DERIVATIVE_POS_RIGHT_MAXIMUM; +"REAL_DERIVATIVE_UNIQUE_ATREAL",REAL_DERIVATIVE_UNIQUE_ATREAL; +"REAL_DERIVATIVE_ZERO_MAXMIN",REAL_DERIVATIVE_ZERO_MAXMIN; +"REAL_DIFFERENTIABLE_ADD",REAL_DIFFERENTIABLE_ADD; +"REAL_DIFFERENTIABLE_AT",REAL_DIFFERENTIABLE_AT; +"REAL_DIFFERENTIABLE_ATREAL_WITHIN",REAL_DIFFERENTIABLE_ATREAL_WITHIN; +"REAL_DIFFERENTIABLE_AT_ACS",REAL_DIFFERENTIABLE_AT_ACS; +"REAL_DIFFERENTIABLE_AT_ASN",REAL_DIFFERENTIABLE_AT_ASN; +"REAL_DIFFERENTIABLE_AT_ATN",REAL_DIFFERENTIABLE_AT_ATN; +"REAL_DIFFERENTIABLE_AT_COS",REAL_DIFFERENTIABLE_AT_COS; +"REAL_DIFFERENTIABLE_AT_EXP",REAL_DIFFERENTIABLE_AT_EXP; +"REAL_DIFFERENTIABLE_AT_LOG",REAL_DIFFERENTIABLE_AT_LOG; +"REAL_DIFFERENTIABLE_AT_RPOW",REAL_DIFFERENTIABLE_AT_RPOW; +"REAL_DIFFERENTIABLE_AT_SIN",REAL_DIFFERENTIABLE_AT_SIN; +"REAL_DIFFERENTIABLE_AT_SQRT",REAL_DIFFERENTIABLE_AT_SQRT; +"REAL_DIFFERENTIABLE_AT_TAN",REAL_DIFFERENTIABLE_AT_TAN; +"REAL_DIFFERENTIABLE_BOUND",REAL_DIFFERENTIABLE_BOUND; +"REAL_DIFFERENTIABLE_CARATHEODORY_ATREAL",REAL_DIFFERENTIABLE_CARATHEODORY_ATREAL; +"REAL_DIFFERENTIABLE_CARATHEODORY_WITHINREAL",REAL_DIFFERENTIABLE_CARATHEODORY_WITHINREAL; +"REAL_DIFFERENTIABLE_COMPOSE_ATREAL",REAL_DIFFERENTIABLE_COMPOSE_ATREAL; +"REAL_DIFFERENTIABLE_COMPOSE_WITHIN",REAL_DIFFERENTIABLE_COMPOSE_WITHIN; +"REAL_DIFFERENTIABLE_CONST",REAL_DIFFERENTIABLE_CONST; +"REAL_DIFFERENTIABLE_DIV_ATREAL",REAL_DIFFERENTIABLE_DIV_ATREAL; +"REAL_DIFFERENTIABLE_DIV_WITHIN",REAL_DIFFERENTIABLE_DIV_WITHIN; +"REAL_DIFFERENTIABLE_EQ",REAL_DIFFERENTIABLE_EQ; +"REAL_DIFFERENTIABLE_ID",REAL_DIFFERENTIABLE_ID; +"REAL_DIFFERENTIABLE_IMP_CONTINUOUS_ATREAL",REAL_DIFFERENTIABLE_IMP_CONTINUOUS_ATREAL; +"REAL_DIFFERENTIABLE_IMP_CONTINUOUS_WITHINREAL",REAL_DIFFERENTIABLE_IMP_CONTINUOUS_WITHINREAL; +"REAL_DIFFERENTIABLE_INV_ATREAL",REAL_DIFFERENTIABLE_INV_ATREAL; +"REAL_DIFFERENTIABLE_INV_WITHIN",REAL_DIFFERENTIABLE_INV_WITHIN; +"REAL_DIFFERENTIABLE_MUL_ATREAL",REAL_DIFFERENTIABLE_MUL_ATREAL; +"REAL_DIFFERENTIABLE_MUL_WITHIN",REAL_DIFFERENTIABLE_MUL_WITHIN; +"REAL_DIFFERENTIABLE_NEG",REAL_DIFFERENTIABLE_NEG; +"REAL_DIFFERENTIABLE_ON_ADD",REAL_DIFFERENTIABLE_ON_ADD; +"REAL_DIFFERENTIABLE_ON_COMPOSE",REAL_DIFFERENTIABLE_ON_COMPOSE; +"REAL_DIFFERENTIABLE_ON_CONST",REAL_DIFFERENTIABLE_ON_CONST; +"REAL_DIFFERENTIABLE_ON_DIFFERENTIABLE",REAL_DIFFERENTIABLE_ON_DIFFERENTIABLE; +"REAL_DIFFERENTIABLE_ON_DIV",REAL_DIFFERENTIABLE_ON_DIV; +"REAL_DIFFERENTIABLE_ON_ID",REAL_DIFFERENTIABLE_ON_ID; +"REAL_DIFFERENTIABLE_ON_IMP_DIFFERENTIABLE_ATREAL",REAL_DIFFERENTIABLE_ON_IMP_DIFFERENTIABLE_ATREAL; +"REAL_DIFFERENTIABLE_ON_IMP_DIFFERENTIABLE_WITHIN",REAL_DIFFERENTIABLE_ON_IMP_DIFFERENTIABLE_WITHIN; +"REAL_DIFFERENTIABLE_ON_IMP_REAL_CONTINUOUS_ON",REAL_DIFFERENTIABLE_ON_IMP_REAL_CONTINUOUS_ON; +"REAL_DIFFERENTIABLE_ON_INV",REAL_DIFFERENTIABLE_ON_INV; +"REAL_DIFFERENTIABLE_ON_MUL",REAL_DIFFERENTIABLE_ON_MUL; +"REAL_DIFFERENTIABLE_ON_NEG",REAL_DIFFERENTIABLE_ON_NEG; +"REAL_DIFFERENTIABLE_ON_POW",REAL_DIFFERENTIABLE_ON_POW; +"REAL_DIFFERENTIABLE_ON_REAL_OPEN",REAL_DIFFERENTIABLE_ON_REAL_OPEN; +"REAL_DIFFERENTIABLE_ON_SUB",REAL_DIFFERENTIABLE_ON_SUB; +"REAL_DIFFERENTIABLE_ON_SUBSET",REAL_DIFFERENTIABLE_ON_SUBSET; +"REAL_DIFFERENTIABLE_ON_SUM",REAL_DIFFERENTIABLE_ON_SUM; +"REAL_DIFFERENTIABLE_POW_ATREAL",REAL_DIFFERENTIABLE_POW_ATREAL; +"REAL_DIFFERENTIABLE_POW_WITHIN",REAL_DIFFERENTIABLE_POW_WITHIN; +"REAL_DIFFERENTIABLE_SUB",REAL_DIFFERENTIABLE_SUB; +"REAL_DIFFERENTIABLE_TRANSFORM",REAL_DIFFERENTIABLE_TRANSFORM; +"REAL_DIFFERENTIABLE_TRANSFORM_ATREAL",REAL_DIFFERENTIABLE_TRANSFORM_ATREAL; +"REAL_DIFFERENTIABLE_TRANSFORM_WITHIN",REAL_DIFFERENTIABLE_TRANSFORM_WITHIN; +"REAL_DIFFERENTIABLE_WITHIN",REAL_DIFFERENTIABLE_WITHIN; +"REAL_DIFFERENTIABLE_WITHIN_ACS",REAL_DIFFERENTIABLE_WITHIN_ACS; +"REAL_DIFFERENTIABLE_WITHIN_ASN",REAL_DIFFERENTIABLE_WITHIN_ASN; +"REAL_DIFFERENTIABLE_WITHIN_ATN",REAL_DIFFERENTIABLE_WITHIN_ATN; +"REAL_DIFFERENTIABLE_WITHIN_COS",REAL_DIFFERENTIABLE_WITHIN_COS; +"REAL_DIFFERENTIABLE_WITHIN_EXP",REAL_DIFFERENTIABLE_WITHIN_EXP; +"REAL_DIFFERENTIABLE_WITHIN_LOG",REAL_DIFFERENTIABLE_WITHIN_LOG; +"REAL_DIFFERENTIABLE_WITHIN_SIN",REAL_DIFFERENTIABLE_WITHIN_SIN; +"REAL_DIFFERENTIABLE_WITHIN_SQRT",REAL_DIFFERENTIABLE_WITHIN_SQRT; +"REAL_DIFFERENTIABLE_WITHIN_SUBSET",REAL_DIFFERENTIABLE_WITHIN_SUBSET; +"REAL_DIFFERENTIABLE_WITHIN_TAN",REAL_DIFFERENTIABLE_WITHIN_TAN; +"REAL_DIFFSQ",REAL_DIFFSQ; +"REAL_DIFF_CHAIN_ATREAL",REAL_DIFF_CHAIN_ATREAL; +"REAL_DIFF_CHAIN_WITHIN",REAL_DIFF_CHAIN_WITHIN; +"REAL_DINI",REAL_DINI; +"REAL_DIV",REAL_DIV; +"REAL_DIV_1",REAL_DIV_1; +"REAL_DIV_EQ_0",REAL_DIV_EQ_0; +"REAL_DIV_LMUL",REAL_DIV_LMUL; +"REAL_DIV_POW2",REAL_DIV_POW2; +"REAL_DIV_POW2_ALT",REAL_DIV_POW2_ALT; +"REAL_DIV_REFL",REAL_DIV_REFL; +"REAL_DIV_RMUL",REAL_DIV_RMUL; +"REAL_DIV_SQRT",REAL_DIV_SQRT; +"REAL_DOMINATED_CONVERGENCE",REAL_DOMINATED_CONVERGENCE; +"REAL_DOWN",REAL_DOWN; +"REAL_DOWN2",REAL_DOWN2; +"REAL_ENTIRE",REAL_ENTIRE; +"REAL_EQ_ADD_LCANCEL",REAL_EQ_ADD_LCANCEL; +"REAL_EQ_ADD_LCANCEL_0",REAL_EQ_ADD_LCANCEL_0; +"REAL_EQ_ADD_RCANCEL",REAL_EQ_ADD_RCANCEL; +"REAL_EQ_ADD_RCANCEL_0",REAL_EQ_ADD_RCANCEL_0; +"REAL_EQ_AFFINITY",REAL_EQ_AFFINITY; +"REAL_EQ_IMP_LE",REAL_EQ_IMP_LE; +"REAL_EQ_INTEGERS",REAL_EQ_INTEGERS; +"REAL_EQ_INTEGERS_IMP",REAL_EQ_INTEGERS_IMP; +"REAL_EQ_INV2",REAL_EQ_INV2; +"REAL_EQ_LCANCEL_IMP",REAL_EQ_LCANCEL_IMP; +"REAL_EQ_LDIV_EQ",REAL_EQ_LDIV_EQ; +"REAL_EQ_MUL_LCANCEL",REAL_EQ_MUL_LCANCEL; +"REAL_EQ_MUL_RCANCEL",REAL_EQ_MUL_RCANCEL; +"REAL_EQ_NEG2",REAL_EQ_NEG2; +"REAL_EQ_RCANCEL_IMP",REAL_EQ_RCANCEL_IMP; +"REAL_EQ_RDIV_EQ",REAL_EQ_RDIV_EQ; +"REAL_EQ_SQUARE_ABS",REAL_EQ_SQUARE_ABS; +"REAL_EQ_SUB_LADD",REAL_EQ_SUB_LADD; +"REAL_EQ_SUB_RADD",REAL_EQ_SUB_RADD; +"REAL_EXISTS",REAL_EXISTS; +"REAL_EXP",REAL_EXP; +"REAL_EXP_0",REAL_EXP_0; +"REAL_EXP_ADD",REAL_EXP_ADD; +"REAL_EXP_ADD_MUL",REAL_EXP_ADD_MUL; +"REAL_EXP_BOUND_LEMMA",REAL_EXP_BOUND_LEMMA; +"REAL_EXP_EQ_1",REAL_EXP_EQ_1; +"REAL_EXP_INJ",REAL_EXP_INJ; +"REAL_EXP_LE_X",REAL_EXP_LE_X; +"REAL_EXP_LOG",REAL_EXP_LOG; +"REAL_EXP_LT_1",REAL_EXP_LT_1; +"REAL_EXP_MONO_IMP",REAL_EXP_MONO_IMP; +"REAL_EXP_MONO_LE",REAL_EXP_MONO_LE; +"REAL_EXP_MONO_LT",REAL_EXP_MONO_LT; +"REAL_EXP_N",REAL_EXP_N; +"REAL_EXP_NEG",REAL_EXP_NEG; +"REAL_EXP_NEG_MUL",REAL_EXP_NEG_MUL; +"REAL_EXP_NEG_MUL2",REAL_EXP_NEG_MUL2; +"REAL_EXP_NZ",REAL_EXP_NZ; +"REAL_EXP_POS_LE",REAL_EXP_POS_LE; +"REAL_EXP_POS_LT",REAL_EXP_POS_LT; +"REAL_EXP_SUB",REAL_EXP_SUB; +"REAL_EXP_SUM",REAL_EXP_SUM; +"REAL_FLOOR_ADD",REAL_FLOOR_ADD; +"REAL_FLOOR_EQ",REAL_FLOOR_EQ; +"REAL_FLOOR_LE",REAL_FLOOR_LE; +"REAL_FLOOR_LT",REAL_FLOOR_LT; +"REAL_FLOOR_REFL",REAL_FLOOR_REFL; +"REAL_FRAC_ADD",REAL_FRAC_ADD; +"REAL_FRAC_EQ",REAL_FRAC_EQ; +"REAL_FRAC_EQ_0",REAL_FRAC_EQ_0; +"REAL_FRAC_POS_LT",REAL_FRAC_POS_LT; +"REAL_FRAC_ZERO",REAL_FRAC_ZERO; +"REAL_FUNDAMENTAL_THEOREM_OF_CALCULUS",REAL_FUNDAMENTAL_THEOREM_OF_CALCULUS; +"REAL_FUNDAMENTAL_THEOREM_OF_CALCULUS_INTERIOR",REAL_FUNDAMENTAL_THEOREM_OF_CALCULUS_INTERIOR; +"REAL_FUNDAMENTAL_THEOREM_OF_CALCULUS_INTERIOR_STRONG",REAL_FUNDAMENTAL_THEOREM_OF_CALCULUS_INTERIOR_STRONG; +"REAL_FUNDAMENTAL_THEOREM_OF_CALCULUS_STRONG",REAL_FUNDAMENTAL_THEOREM_OF_CALCULUS_STRONG; +"REAL_HALF",REAL_HALF; +"REAL_HREAL_LEMMA1",REAL_HREAL_LEMMA1; +"REAL_HREAL_LEMMA2",REAL_HREAL_LEMMA2; +"REAL_IMP_CNJ",REAL_IMP_CNJ; +"REAL_INDEFINITE_INTEGRAL_CONTINUOUS_LEFT",REAL_INDEFINITE_INTEGRAL_CONTINUOUS_LEFT; +"REAL_INDEFINITE_INTEGRAL_CONTINUOUS_RIGHT",REAL_INDEFINITE_INTEGRAL_CONTINUOUS_RIGHT; +"REAL_INFSUM",REAL_INFSUM; +"REAL_INFSUM_0",REAL_INFSUM_0; +"REAL_INFSUM_ADD",REAL_INFSUM_ADD; +"REAL_INFSUM_COMPLEX",REAL_INFSUM_COMPLEX; +"REAL_INFSUM_EQ",REAL_INFSUM_EQ; +"REAL_INFSUM_LMUL",REAL_INFSUM_LMUL; +"REAL_INFSUM_NEG",REAL_INFSUM_NEG; +"REAL_INFSUM_RESTRICT",REAL_INFSUM_RESTRICT; +"REAL_INFSUM_RMUL",REAL_INFSUM_RMUL; +"REAL_INFSUM_SUB",REAL_INFSUM_SUB; +"REAL_INFSUM_UNIQUE",REAL_INFSUM_UNIQUE; +"REAL_INF_ASCLOSE",REAL_INF_ASCLOSE; +"REAL_INF_BOUNDS",REAL_INF_BOUNDS; +"REAL_INF_LE_FINITE",REAL_INF_LE_FINITE; +"REAL_INF_LT_FINITE",REAL_INF_LT_FINITE; +"REAL_INF_UNIQUE",REAL_INF_UNIQUE; +"REAL_INTEGRABLE_0",REAL_INTEGRABLE_0; +"REAL_INTEGRABLE_ADD",REAL_INTEGRABLE_ADD; +"REAL_INTEGRABLE_AFFINITY",REAL_INTEGRABLE_AFFINITY; +"REAL_INTEGRABLE_COMBINE",REAL_INTEGRABLE_COMBINE; +"REAL_INTEGRABLE_CONST",REAL_INTEGRABLE_CONST; +"REAL_INTEGRABLE_CONTINUOUS",REAL_INTEGRABLE_CONTINUOUS; +"REAL_INTEGRABLE_DECREASING",REAL_INTEGRABLE_DECREASING; +"REAL_INTEGRABLE_DECREASING_PRODUCT",REAL_INTEGRABLE_DECREASING_PRODUCT; +"REAL_INTEGRABLE_DECREASING_PRODUCT_UNIV",REAL_INTEGRABLE_DECREASING_PRODUCT_UNIV; +"REAL_INTEGRABLE_EQ",REAL_INTEGRABLE_EQ; +"REAL_INTEGRABLE_INCREASING",REAL_INTEGRABLE_INCREASING; +"REAL_INTEGRABLE_INCREASING_PRODUCT",REAL_INTEGRABLE_INCREASING_PRODUCT; +"REAL_INTEGRABLE_INCREASING_PRODUCT_UNIV",REAL_INTEGRABLE_INCREASING_PRODUCT_UNIV; +"REAL_INTEGRABLE_INTEGRAL",REAL_INTEGRABLE_INTEGRAL; +"REAL_INTEGRABLE_LINEAR",REAL_INTEGRABLE_LINEAR; +"REAL_INTEGRABLE_LMUL",REAL_INTEGRABLE_LMUL; +"REAL_INTEGRABLE_NEG",REAL_INTEGRABLE_NEG; +"REAL_INTEGRABLE_ON",REAL_INTEGRABLE_ON; +"REAL_INTEGRABLE_ON_EMPTY",REAL_INTEGRABLE_ON_EMPTY; +"REAL_INTEGRABLE_ON_LITTLE_SUBINTERVALS",REAL_INTEGRABLE_ON_LITTLE_SUBINTERVALS; +"REAL_INTEGRABLE_ON_NULL",REAL_INTEGRABLE_ON_NULL; +"REAL_INTEGRABLE_ON_OPEN_INTERVAL",REAL_INTEGRABLE_ON_OPEN_INTERVAL; +"REAL_INTEGRABLE_ON_REFL",REAL_INTEGRABLE_ON_REFL; +"REAL_INTEGRABLE_ON_SUBINTERVAL",REAL_INTEGRABLE_ON_SUBINTERVAL; +"REAL_INTEGRABLE_ON_SUPERSET",REAL_INTEGRABLE_ON_SUPERSET; +"REAL_INTEGRABLE_REFLECT",REAL_INTEGRABLE_REFLECT; +"REAL_INTEGRABLE_RESTRICT_INTER",REAL_INTEGRABLE_RESTRICT_INTER; +"REAL_INTEGRABLE_RESTRICT_UNIV",REAL_INTEGRABLE_RESTRICT_UNIV; +"REAL_INTEGRABLE_RMUL",REAL_INTEGRABLE_RMUL; +"REAL_INTEGRABLE_SPIKE",REAL_INTEGRABLE_SPIKE; +"REAL_INTEGRABLE_SPIKE_FINITE",REAL_INTEGRABLE_SPIKE_FINITE; +"REAL_INTEGRABLE_SPIKE_INTERIOR",REAL_INTEGRABLE_SPIKE_INTERIOR; +"REAL_INTEGRABLE_SPIKE_SET",REAL_INTEGRABLE_SPIKE_SET; +"REAL_INTEGRABLE_SPIKE_SET_EQ",REAL_INTEGRABLE_SPIKE_SET_EQ; +"REAL_INTEGRABLE_STRADDLE",REAL_INTEGRABLE_STRADDLE; +"REAL_INTEGRABLE_STRETCH",REAL_INTEGRABLE_STRETCH; +"REAL_INTEGRABLE_SUB",REAL_INTEGRABLE_SUB; +"REAL_INTEGRABLE_SUBINTERVAL",REAL_INTEGRABLE_SUBINTERVAL; +"REAL_INTEGRABLE_SUM",REAL_INTEGRABLE_SUM; +"REAL_INTEGRABLE_UNIFORM_LIMIT",REAL_INTEGRABLE_UNIFORM_LIMIT; +"REAL_INTEGRAL",REAL_INTEGRAL; +"REAL_INTEGRAL_0",REAL_INTEGRAL_0; +"REAL_INTEGRAL_ABS_BOUND_INTEGRAL",REAL_INTEGRAL_ABS_BOUND_INTEGRAL; +"REAL_INTEGRAL_ADD",REAL_INTEGRAL_ADD; +"REAL_INTEGRAL_COMBINE",REAL_INTEGRAL_COMBINE; +"REAL_INTEGRAL_CONST",REAL_INTEGRAL_CONST; +"REAL_INTEGRAL_EMPTY",REAL_INTEGRAL_EMPTY; +"REAL_INTEGRAL_EQ",REAL_INTEGRAL_EQ; +"REAL_INTEGRAL_EQ_0",REAL_INTEGRAL_EQ_0; +"REAL_INTEGRAL_EQ_HAS_INTEGRAL",REAL_INTEGRAL_EQ_HAS_INTEGRAL; +"REAL_INTEGRAL_HAS_REAL_DERIVATIVE",REAL_INTEGRAL_HAS_REAL_DERIVATIVE; +"REAL_INTEGRAL_LBOUND",REAL_INTEGRAL_LBOUND; +"REAL_INTEGRAL_LE",REAL_INTEGRAL_LE; +"REAL_INTEGRAL_LINEAR",REAL_INTEGRAL_LINEAR; +"REAL_INTEGRAL_LMUL",REAL_INTEGRAL_LMUL; +"REAL_INTEGRAL_NEG",REAL_INTEGRAL_NEG; +"REAL_INTEGRAL_NULL",REAL_INTEGRAL_NULL; +"REAL_INTEGRAL_OPEN_INTERVAL",REAL_INTEGRAL_OPEN_INTERVAL; +"REAL_INTEGRAL_POS",REAL_INTEGRAL_POS; +"REAL_INTEGRAL_REAL_MEASURE",REAL_INTEGRAL_REAL_MEASURE; +"REAL_INTEGRAL_REAL_MEASURE_UNIV",REAL_INTEGRAL_REAL_MEASURE_UNIV; +"REAL_INTEGRAL_REFL",REAL_INTEGRAL_REFL; +"REAL_INTEGRAL_REFLECT",REAL_INTEGRAL_REFLECT; +"REAL_INTEGRAL_RESTRICT",REAL_INTEGRAL_RESTRICT; +"REAL_INTEGRAL_RESTRICT_INTER",REAL_INTEGRAL_RESTRICT_INTER; +"REAL_INTEGRAL_RESTRICT_UNIV",REAL_INTEGRAL_RESTRICT_UNIV; +"REAL_INTEGRAL_RMUL",REAL_INTEGRAL_RMUL; +"REAL_INTEGRAL_SPIKE",REAL_INTEGRAL_SPIKE; +"REAL_INTEGRAL_SPIKE_SET",REAL_INTEGRAL_SPIKE_SET; +"REAL_INTEGRAL_SUB",REAL_INTEGRAL_SUB; +"REAL_INTEGRAL_SUBSET_LE",REAL_INTEGRAL_SUBSET_LE; +"REAL_INTEGRAL_SUM",REAL_INTEGRAL_SUM; +"REAL_INTEGRAL_UBOUND",REAL_INTEGRAL_UBOUND; +"REAL_INTEGRAL_UNIQUE",REAL_INTEGRAL_UNIQUE; +"REAL_INTERVAL_EQ_EMPTY",REAL_INTERVAL_EQ_EMPTY; +"REAL_INTERVAL_INTERVAL",REAL_INTERVAL_INTERVAL; +"REAL_INTERVAL_NE_EMPTY",REAL_INTERVAL_NE_EMPTY; +"REAL_INTERVAL_OPEN_SUBSET_CLOSED",REAL_INTERVAL_OPEN_SUBSET_CLOSED; +"REAL_INTERVAL_SING",REAL_INTERVAL_SING; +"REAL_INTERVAL_TRANSLATION",REAL_INTERVAL_TRANSLATION; +"REAL_INV",REAL_INV; +"REAL_INV_0",REAL_INV_0; +"REAL_INV_1",REAL_INV_1; +"REAL_INV_1_LE",REAL_INV_1_LE; +"REAL_INV_1_LT",REAL_INV_1_LT; +"REAL_INV_DIV",REAL_INV_DIV; +"REAL_INV_EQ",REAL_INV_EQ; +"REAL_INV_EQ_0",REAL_INV_EQ_0; +"REAL_INV_EQ_1",REAL_INV_EQ_1; +"REAL_INV_INV",REAL_INV_INV; +"REAL_INV_LE_1",REAL_INV_LE_1; +"REAL_INV_LT_1",REAL_INV_LT_1; +"REAL_INV_MUL",REAL_INV_MUL; +"REAL_INV_NEG",REAL_INV_NEG; +"REAL_INV_POW",REAL_INV_POW; +"REAL_INV_RPOW",REAL_INV_RPOW; +"REAL_IVT_DECREASING",REAL_IVT_DECREASING; +"REAL_IVT_INCREASING",REAL_IVT_INCREASING; +"REAL_LEBESGUE_MEASURABLE",REAL_LEBESGUE_MEASURABLE; +"REAL_LEBESGUE_MEASURABLE_CLOSED",REAL_LEBESGUE_MEASURABLE_CLOSED; +"REAL_LEBESGUE_MEASURABLE_COMPACT",REAL_LEBESGUE_MEASURABLE_COMPACT; +"REAL_LEBESGUE_MEASURABLE_COMPL",REAL_LEBESGUE_MEASURABLE_COMPL; +"REAL_LEBESGUE_MEASURABLE_COUNTABLE_INTERS",REAL_LEBESGUE_MEASURABLE_COUNTABLE_INTERS; +"REAL_LEBESGUE_MEASURABLE_COUNTABLE_INTERS_EXPLICIT",REAL_LEBESGUE_MEASURABLE_COUNTABLE_INTERS_EXPLICIT; +"REAL_LEBESGUE_MEASURABLE_COUNTABLE_UNIONS",REAL_LEBESGUE_MEASURABLE_COUNTABLE_UNIONS; +"REAL_LEBESGUE_MEASURABLE_COUNTABLE_UNIONS_EXPLICIT",REAL_LEBESGUE_MEASURABLE_COUNTABLE_UNIONS_EXPLICIT; +"REAL_LEBESGUE_MEASURABLE_DIFF",REAL_LEBESGUE_MEASURABLE_DIFF; +"REAL_LEBESGUE_MEASURABLE_EMPTY",REAL_LEBESGUE_MEASURABLE_EMPTY; +"REAL_LEBESGUE_MEASURABLE_IFF_MEASURABLE",REAL_LEBESGUE_MEASURABLE_IFF_MEASURABLE; +"REAL_LEBESGUE_MEASURABLE_INTER",REAL_LEBESGUE_MEASURABLE_INTER; +"REAL_LEBESGUE_MEASURABLE_INTERS",REAL_LEBESGUE_MEASURABLE_INTERS; +"REAL_LEBESGUE_MEASURABLE_INTERVAL",REAL_LEBESGUE_MEASURABLE_INTERVAL; +"REAL_LEBESGUE_MEASURABLE_ON_SUBINTERVALS",REAL_LEBESGUE_MEASURABLE_ON_SUBINTERVALS; +"REAL_LEBESGUE_MEASURABLE_OPEN",REAL_LEBESGUE_MEASURABLE_OPEN; +"REAL_LEBESGUE_MEASURABLE_PREIMAGE_CLOSED",REAL_LEBESGUE_MEASURABLE_PREIMAGE_CLOSED; +"REAL_LEBESGUE_MEASURABLE_PREIMAGE_OPEN",REAL_LEBESGUE_MEASURABLE_PREIMAGE_OPEN; +"REAL_LEBESGUE_MEASURABLE_UNION",REAL_LEBESGUE_MEASURABLE_UNION; +"REAL_LEBESGUE_MEASURABLE_UNIONS",REAL_LEBESGUE_MEASURABLE_UNIONS; +"REAL_LEBESGUE_MEASURABLE_UNIV",REAL_LEBESGUE_MEASURABLE_UNIV; +"REAL_LET_ADD",REAL_LET_ADD; +"REAL_LET_ADD2",REAL_LET_ADD2; +"REAL_LET_ANTISYM",REAL_LET_ANTISYM; +"REAL_LET_TOTAL",REAL_LET_TOTAL; +"REAL_LET_TRANS",REAL_LET_TRANS; +"REAL_LE_01",REAL_LE_01; +"REAL_LE_ABS_SINH",REAL_LE_ABS_SINH; +"REAL_LE_ADD",REAL_LE_ADD; +"REAL_LE_ADD2",REAL_LE_ADD2; +"REAL_LE_ADDL",REAL_LE_ADDL; +"REAL_LE_ADDR",REAL_LE_ADDR; +"REAL_LE_AFFINITY",REAL_LE_AFFINITY; +"REAL_LE_ANTISYM",REAL_LE_ANTISYM; +"REAL_LE_BETWEEN",REAL_LE_BETWEEN; +"REAL_LE_CASES_INTEGERS",REAL_LE_CASES_INTEGERS; +"REAL_LE_DIV",REAL_LE_DIV; +"REAL_LE_DIV2_EQ",REAL_LE_DIV2_EQ; +"REAL_LE_DOUBLE",REAL_LE_DOUBLE; +"REAL_LE_FLOOR",REAL_LE_FLOOR; +"REAL_LE_INF",REAL_LE_INF; +"REAL_LE_INF_FINITE",REAL_LE_INF_FINITE; +"REAL_LE_INF_SUBSET",REAL_LE_INF_SUBSET; +"REAL_LE_INTEGERS",REAL_LE_INTEGERS; +"REAL_LE_INV",REAL_LE_INV; +"REAL_LE_INV2",REAL_LE_INV2; +"REAL_LE_INV_EQ",REAL_LE_INV_EQ; +"REAL_LE_LADD",REAL_LE_LADD; +"REAL_LE_LADD_IMP",REAL_LE_LADD_IMP; +"REAL_LE_LCANCEL_IMP",REAL_LE_LCANCEL_IMP; +"REAL_LE_LDIV_EQ",REAL_LE_LDIV_EQ; +"REAL_LE_LINV",REAL_LE_LINV; +"REAL_LE_LMUL",REAL_LE_LMUL; +"REAL_LE_LMUL_EQ",REAL_LE_LMUL_EQ; +"REAL_LE_LNEG",REAL_LE_LNEG; +"REAL_LE_LSQRT",REAL_LE_LSQRT; +"REAL_LE_LT",REAL_LE_LT; +"REAL_LE_MAX",REAL_LE_MAX; +"REAL_LE_MIN",REAL_LE_MIN; +"REAL_LE_MUL",REAL_LE_MUL; +"REAL_LE_MUL2",REAL_LE_MUL2; +"REAL_LE_MUL_EQ",REAL_LE_MUL_EQ; +"REAL_LE_NEG",REAL_LE_NEG; +"REAL_LE_NEG2",REAL_LE_NEG2; +"REAL_LE_NEGL",REAL_LE_NEGL; +"REAL_LE_NEGR",REAL_LE_NEGR; +"REAL_LE_NEGTOTAL",REAL_LE_NEGTOTAL; +"REAL_LE_POW2",REAL_LE_POW2; +"REAL_LE_POW_2",REAL_LE_POW_2; +"REAL_LE_RADD",REAL_LE_RADD; +"REAL_LE_RCANCEL_IMP",REAL_LE_RCANCEL_IMP; +"REAL_LE_RDIV_EQ",REAL_LE_RDIV_EQ; +"REAL_LE_REFL",REAL_LE_REFL; +"REAL_LE_REVERSE_INTEGERS",REAL_LE_REVERSE_INTEGERS; +"REAL_LE_RINV",REAL_LE_RINV; +"REAL_LE_RMUL",REAL_LE_RMUL; +"REAL_LE_RMUL_EQ",REAL_LE_RMUL_EQ; +"REAL_LE_RNEG",REAL_LE_RNEG; +"REAL_LE_ROOT",REAL_LE_ROOT; +"REAL_LE_RSQRT",REAL_LE_RSQRT; +"REAL_LE_SETDIST",REAL_LE_SETDIST; +"REAL_LE_SETDIST_EQ",REAL_LE_SETDIST_EQ; +"REAL_LE_SQUARE",REAL_LE_SQUARE; +"REAL_LE_SQUARE_ABS",REAL_LE_SQUARE_ABS; +"REAL_LE_SUB_LADD",REAL_LE_SUB_LADD; +"REAL_LE_SUB_RADD",REAL_LE_SUB_RADD; +"REAL_LE_SUP_FINITE",REAL_LE_SUP_FINITE; +"REAL_LE_TOTAL",REAL_LE_TOTAL; +"REAL_LE_TRANS",REAL_LE_TRANS; +"REAL_LE_X_SINH",REAL_LE_X_SINH; +"REAL_LIM",REAL_LIM; +"REAL_LIM_SEQUENTIALLY",REAL_LIM_SEQUENTIALLY; +"REAL_LNEG_UNIQ",REAL_LNEG_UNIQ; +"REAL_LSQRT_LE",REAL_LSQRT_LE; +"REAL_LTE_ADD",REAL_LTE_ADD; +"REAL_LTE_ADD2",REAL_LTE_ADD2; +"REAL_LTE_ANTISYM",REAL_LTE_ANTISYM; +"REAL_LTE_TOTAL",REAL_LTE_TOTAL; +"REAL_LTE_TRANS",REAL_LTE_TRANS; +"REAL_LT_01",REAL_LT_01; +"REAL_LT_ADD",REAL_LT_ADD; +"REAL_LT_ADD1",REAL_LT_ADD1; +"REAL_LT_ADD2",REAL_LT_ADD2; +"REAL_LT_ADDL",REAL_LT_ADDL; +"REAL_LT_ADDNEG",REAL_LT_ADDNEG; +"REAL_LT_ADDNEG2",REAL_LT_ADDNEG2; +"REAL_LT_ADDR",REAL_LT_ADDR; +"REAL_LT_ADD_SUB",REAL_LT_ADD_SUB; +"REAL_LT_AFFINITY",REAL_LT_AFFINITY; +"REAL_LT_ANTISYM",REAL_LT_ANTISYM; +"REAL_LT_BETWEEN",REAL_LT_BETWEEN; +"REAL_LT_DIV",REAL_LT_DIV; +"REAL_LT_DIV2_EQ",REAL_LT_DIV2_EQ; +"REAL_LT_GT",REAL_LT_GT; +"REAL_LT_IMP_LE",REAL_LT_IMP_LE; +"REAL_LT_IMP_NE",REAL_LT_IMP_NE; +"REAL_LT_IMP_NZ",REAL_LT_IMP_NZ; +"REAL_LT_INF_FINITE",REAL_LT_INF_FINITE; +"REAL_LT_INTEGERS",REAL_LT_INTEGERS; +"REAL_LT_INV",REAL_LT_INV; +"REAL_LT_INV2",REAL_LT_INV2; +"REAL_LT_INV_EQ",REAL_LT_INV_EQ; +"REAL_LT_LADD",REAL_LT_LADD; +"REAL_LT_LADD_IMP",REAL_LT_LADD_IMP; +"REAL_LT_LCANCEL_IMP",REAL_LT_LCANCEL_IMP; +"REAL_LT_LDIV_EQ",REAL_LT_LDIV_EQ; +"REAL_LT_LE",REAL_LT_LE; +"REAL_LT_LINV",REAL_LT_LINV; +"REAL_LT_LMUL",REAL_LT_LMUL; +"REAL_LT_LMUL_EQ",REAL_LT_LMUL_EQ; +"REAL_LT_LNEG",REAL_LT_LNEG; +"REAL_LT_LSQRT",REAL_LT_LSQRT; +"REAL_LT_MAX",REAL_LT_MAX; +"REAL_LT_MIN",REAL_LT_MIN; +"REAL_LT_MUL",REAL_LT_MUL; +"REAL_LT_MUL2",REAL_LT_MUL2; +"REAL_LT_MUL_EQ",REAL_LT_MUL_EQ; +"REAL_LT_NEG",REAL_LT_NEG; +"REAL_LT_NEG2",REAL_LT_NEG2; +"REAL_LT_NEGTOTAL",REAL_LT_NEGTOTAL; +"REAL_LT_POW2",REAL_LT_POW2; +"REAL_LT_RADD",REAL_LT_RADD; +"REAL_LT_RCANCEL_IMP",REAL_LT_RCANCEL_IMP; +"REAL_LT_RDIV_EQ",REAL_LT_RDIV_EQ; +"REAL_LT_REFL",REAL_LT_REFL; +"REAL_LT_RINV",REAL_LT_RINV; +"REAL_LT_RMUL",REAL_LT_RMUL; +"REAL_LT_RMUL_EQ",REAL_LT_RMUL_EQ; +"REAL_LT_RNEG",REAL_LT_RNEG; +"REAL_LT_RSQRT",REAL_LT_RSQRT; +"REAL_LT_SQUARE",REAL_LT_SQUARE; +"REAL_LT_SQUARE_ABS",REAL_LT_SQUARE_ABS; +"REAL_LT_SUB_LADD",REAL_LT_SUB_LADD; +"REAL_LT_SUB_RADD",REAL_LT_SUB_RADD; +"REAL_LT_SUP_FINITE",REAL_LT_SUP_FINITE; +"REAL_LT_TOTAL",REAL_LT_TOTAL; +"REAL_LT_TRANS",REAL_LT_TRANS; +"REAL_MAX_ACI",REAL_MAX_ACI; +"REAL_MAX_ASSOC",REAL_MAX_ASSOC; +"REAL_MAX_LE",REAL_MAX_LE; +"REAL_MAX_LT",REAL_MAX_LT; +"REAL_MAX_MAX",REAL_MAX_MAX; +"REAL_MAX_MIN",REAL_MAX_MIN; +"REAL_MAX_SUP",REAL_MAX_SUP; +"REAL_MAX_SYM",REAL_MAX_SYM; +"REAL_MEASURABLE",REAL_MEASURABLE; +"REAL_MEASURABLE_ALMOST",REAL_MEASURABLE_ALMOST; +"REAL_MEASURABLE_BOUNDED_BY_INTEGRABLE_IMP_ABSOLUTELY_INTEGRABLE",REAL_MEASURABLE_BOUNDED_BY_INTEGRABLE_IMP_ABSOLUTELY_INTEGRABLE; +"REAL_MEASURABLE_BOUNDED_BY_INTEGRABLE_IMP_INTEGRABLE",REAL_MEASURABLE_BOUNDED_BY_INTEGRABLE_IMP_INTEGRABLE; +"REAL_MEASURABLE_COMPACT",REAL_MEASURABLE_COMPACT; +"REAL_MEASURABLE_COUNTABLE_INTERS",REAL_MEASURABLE_COUNTABLE_INTERS; +"REAL_MEASURABLE_COUNTABLE_UNIONS",REAL_MEASURABLE_COUNTABLE_UNIONS; +"REAL_MEASURABLE_COUNTABLE_UNIONS_BOUNDED",REAL_MEASURABLE_COUNTABLE_UNIONS_BOUNDED; +"REAL_MEASURABLE_COUNTABLE_UNIONS_STRONG",REAL_MEASURABLE_COUNTABLE_UNIONS_STRONG; +"REAL_MEASURABLE_DIFF",REAL_MEASURABLE_DIFF; +"REAL_MEASURABLE_EMPTY",REAL_MEASURABLE_EMPTY; +"REAL_MEASURABLE_IMP_REAL_LEBESGUE_MEASURABLE",REAL_MEASURABLE_IMP_REAL_LEBESGUE_MEASURABLE; +"REAL_MEASURABLE_INNER_OUTER",REAL_MEASURABLE_INNER_OUTER; +"REAL_MEASURABLE_INTER",REAL_MEASURABLE_INTER; +"REAL_MEASURABLE_MEASURABLE",REAL_MEASURABLE_MEASURABLE; +"REAL_MEASURABLE_NESTED_UNIONS",REAL_MEASURABLE_NESTED_UNIONS; +"REAL_MEASURABLE_ON_0",REAL_MEASURABLE_ON_0; +"REAL_MEASURABLE_ON_ABS",REAL_MEASURABLE_ON_ABS; +"REAL_MEASURABLE_ON_ADD",REAL_MEASURABLE_ON_ADD; +"REAL_MEASURABLE_ON_CASES",REAL_MEASURABLE_ON_CASES; +"REAL_MEASURABLE_ON_COMPOSE_CONTINUOUS",REAL_MEASURABLE_ON_COMPOSE_CONTINUOUS; +"REAL_MEASURABLE_ON_COMPOSE_CONTINUOUS_0",REAL_MEASURABLE_ON_COMPOSE_CONTINUOUS_0; +"REAL_MEASURABLE_ON_COMPOSE_CONTINUOUS_CLOSED_SET",REAL_MEASURABLE_ON_COMPOSE_CONTINUOUS_CLOSED_SET; +"REAL_MEASURABLE_ON_COMPOSE_CONTINUOUS_CLOSED_SET_0",REAL_MEASURABLE_ON_COMPOSE_CONTINUOUS_CLOSED_SET_0; +"REAL_MEASURABLE_ON_COMPOSE_CONTINUOUS_OPEN_INTERVAL",REAL_MEASURABLE_ON_COMPOSE_CONTINUOUS_OPEN_INTERVAL; +"REAL_MEASURABLE_ON_CONST",REAL_MEASURABLE_ON_CONST; +"REAL_MEASURABLE_ON_DECREASING",REAL_MEASURABLE_ON_DECREASING; +"REAL_MEASURABLE_ON_DECREASING_UNIV",REAL_MEASURABLE_ON_DECREASING_UNIV; +"REAL_MEASURABLE_ON_DIV",REAL_MEASURABLE_ON_DIV; +"REAL_MEASURABLE_ON_INCREASING",REAL_MEASURABLE_ON_INCREASING; +"REAL_MEASURABLE_ON_INCREASING_UNIV",REAL_MEASURABLE_ON_INCREASING_UNIV; +"REAL_MEASURABLE_ON_INV",REAL_MEASURABLE_ON_INV; +"REAL_MEASURABLE_ON_LEBESGUE_MEASURABLE_SUBSET",REAL_MEASURABLE_ON_LEBESGUE_MEASURABLE_SUBSET; +"REAL_MEASURABLE_ON_LIMIT",REAL_MEASURABLE_ON_LIMIT; +"REAL_MEASURABLE_ON_LMUL",REAL_MEASURABLE_ON_LMUL; +"REAL_MEASURABLE_ON_MAX",REAL_MEASURABLE_ON_MAX; +"REAL_MEASURABLE_ON_MEASURABLE_SUBSET",REAL_MEASURABLE_ON_MEASURABLE_SUBSET; +"REAL_MEASURABLE_ON_MIN",REAL_MEASURABLE_ON_MIN; +"REAL_MEASURABLE_ON_MUL",REAL_MEASURABLE_ON_MUL; +"REAL_MEASURABLE_ON_NEG",REAL_MEASURABLE_ON_NEG; +"REAL_MEASURABLE_ON_NEG_EQ",REAL_MEASURABLE_ON_NEG_EQ; +"REAL_MEASURABLE_ON_PREIMAGE_CLOSED",REAL_MEASURABLE_ON_PREIMAGE_CLOSED; +"REAL_MEASURABLE_ON_PREIMAGE_CLOSED_INTERVAL",REAL_MEASURABLE_ON_PREIMAGE_CLOSED_INTERVAL; +"REAL_MEASURABLE_ON_PREIMAGE_OPEN",REAL_MEASURABLE_ON_PREIMAGE_OPEN; +"REAL_MEASURABLE_ON_PREIMAGE_OPEN_HALFSPACE_GE",REAL_MEASURABLE_ON_PREIMAGE_OPEN_HALFSPACE_GE; +"REAL_MEASURABLE_ON_PREIMAGE_OPEN_HALFSPACE_GT",REAL_MEASURABLE_ON_PREIMAGE_OPEN_HALFSPACE_GT; +"REAL_MEASURABLE_ON_PREIMAGE_OPEN_HALFSPACE_LE",REAL_MEASURABLE_ON_PREIMAGE_OPEN_HALFSPACE_LE; +"REAL_MEASURABLE_ON_PREIMAGE_OPEN_HALFSPACE_LT",REAL_MEASURABLE_ON_PREIMAGE_OPEN_HALFSPACE_LT; +"REAL_MEASURABLE_ON_PREIMAGE_OPEN_INTERVAL",REAL_MEASURABLE_ON_PREIMAGE_OPEN_INTERVAL; +"REAL_MEASURABLE_ON_RESTRICT",REAL_MEASURABLE_ON_RESTRICT; +"REAL_MEASURABLE_ON_RMUL",REAL_MEASURABLE_ON_RMUL; +"REAL_MEASURABLE_ON_SIMPLE_FUNCTION_LIMIT",REAL_MEASURABLE_ON_SIMPLE_FUNCTION_LIMIT; +"REAL_MEASURABLE_ON_SPIKE_SET",REAL_MEASURABLE_ON_SPIKE_SET; +"REAL_MEASURABLE_ON_SUB",REAL_MEASURABLE_ON_SUB; +"REAL_MEASURABLE_ON_UNIV",REAL_MEASURABLE_ON_UNIV; +"REAL_MEASURABLE_OPEN",REAL_MEASURABLE_OPEN; +"REAL_MEASURABLE_REAL_INTEGRABLE",REAL_MEASURABLE_REAL_INTEGRABLE; +"REAL_MEASURABLE_REAL_INTERVAL",REAL_MEASURABLE_REAL_INTERVAL; +"REAL_MEASURABLE_REAL_MEASURE_EQ_0",REAL_MEASURABLE_REAL_MEASURE_EQ_0; +"REAL_MEASURABLE_REAL_MEASURE_POS_LT",REAL_MEASURABLE_REAL_MEASURE_POS_LT; +"REAL_MEASURABLE_REAL_NEGLIGIBLE_SYMDIFF",REAL_MEASURABLE_REAL_NEGLIGIBLE_SYMDIFF; +"REAL_MEASURABLE_SCALING",REAL_MEASURABLE_SCALING; +"REAL_MEASURABLE_SCALING_EQ",REAL_MEASURABLE_SCALING_EQ; +"REAL_MEASURABLE_TRANSLATION",REAL_MEASURABLE_TRANSLATION; +"REAL_MEASURABLE_UNION",REAL_MEASURABLE_UNION; +"REAL_MEASURABLE_UNIONS",REAL_MEASURABLE_UNIONS; +"REAL_MEASURE_DIFF_SUBSET",REAL_MEASURE_DIFF_SUBSET; +"REAL_MEASURE_DISJOINT_UNION",REAL_MEASURE_DISJOINT_UNION; +"REAL_MEASURE_DISJOINT_UNIONS",REAL_MEASURE_DISJOINT_UNIONS; +"REAL_MEASURE_DISJOINT_UNIONS_IMAGE",REAL_MEASURE_DISJOINT_UNIONS_IMAGE; +"REAL_MEASURE_DISJOINT_UNIONS_IMAGE_STRONG",REAL_MEASURE_DISJOINT_UNIONS_IMAGE_STRONG; +"REAL_MEASURE_EMPTY",REAL_MEASURE_EMPTY; +"REAL_MEASURE_EQ_0",REAL_MEASURE_EQ_0; +"REAL_MEASURE_MEASURE",REAL_MEASURE_MEASURE; +"REAL_MEASURE_POS_LE",REAL_MEASURE_POS_LE; +"REAL_MEASURE_REAL_INTEGRAL",REAL_MEASURE_REAL_INTEGRAL; +"REAL_MEASURE_REAL_INTEGRAL_UNIV",REAL_MEASURE_REAL_INTEGRAL_UNIV; +"REAL_MEASURE_REAL_INTERVAL",REAL_MEASURE_REAL_INTERVAL; +"REAL_MEASURE_REAL_NEGLIGIBLE_SYMDIFF",REAL_MEASURE_REAL_NEGLIGIBLE_SYMDIFF; +"REAL_MEASURE_REAL_NEGLIGIBLE_UNION",REAL_MEASURE_REAL_NEGLIGIBLE_UNION; +"REAL_MEASURE_REAL_NEGLIGIBLE_UNIONS",REAL_MEASURE_REAL_NEGLIGIBLE_UNIONS; +"REAL_MEASURE_REAL_NEGLIGIBLE_UNIONS_IMAGE",REAL_MEASURE_REAL_NEGLIGIBLE_UNIONS_IMAGE; +"REAL_MEASURE_REAL_NEGLIGIBLE_UNIONS_IMAGE_STRONG",REAL_MEASURE_REAL_NEGLIGIBLE_UNIONS_IMAGE_STRONG; +"REAL_MEASURE_SCALING",REAL_MEASURE_SCALING; +"REAL_MEASURE_SUBSET",REAL_MEASURE_SUBSET; +"REAL_MEASURE_TRANSLATION",REAL_MEASURE_TRANSLATION; +"REAL_MEASURE_UNION",REAL_MEASURE_UNION; +"REAL_MEASURE_UNIONS_LE",REAL_MEASURE_UNIONS_LE; +"REAL_MEASURE_UNIONS_LE_IMAGE",REAL_MEASURE_UNIONS_LE_IMAGE; +"REAL_MEASURE_UNION_LE",REAL_MEASURE_UNION_LE; +"REAL_MEASURE_UNIQUE",REAL_MEASURE_UNIQUE; +"REAL_MIN_ACI",REAL_MIN_ACI; +"REAL_MIN_ASSOC",REAL_MIN_ASSOC; +"REAL_MIN_INF",REAL_MIN_INF; +"REAL_MIN_LE",REAL_MIN_LE; +"REAL_MIN_LT",REAL_MIN_LT; +"REAL_MIN_MAX",REAL_MIN_MAX; +"REAL_MIN_MIN",REAL_MIN_MIN; +"REAL_MIN_SYM",REAL_MIN_SYM; +"REAL_MONOTONE_CONVERGENCE_DECREASING",REAL_MONOTONE_CONVERGENCE_DECREASING; +"REAL_MONOTONE_CONVERGENCE_INCREASING",REAL_MONOTONE_CONVERGENCE_INCREASING; +"REAL_MONOTONE_CONVERGENCE_INCREASING_AE",REAL_MONOTONE_CONVERGENCE_INCREASING_AE; +"REAL_MUL",REAL_MUL; +"REAL_MUL_2",REAL_MUL_2; +"REAL_MUL_AC",REAL_MUL_AC; +"REAL_MUL_ASSOC",REAL_MUL_ASSOC; +"REAL_MUL_COS_COS",REAL_MUL_COS_COS; +"REAL_MUL_COS_SIN",REAL_MUL_COS_SIN; +"REAL_MUL_CX",REAL_MUL_CX; +"REAL_MUL_LID",REAL_MUL_LID; +"REAL_MUL_LINV",REAL_MUL_LINV; +"REAL_MUL_LINV_UNIQ",REAL_MUL_LINV_UNIQ; +"REAL_MUL_LNEG",REAL_MUL_LNEG; +"REAL_MUL_LZERO",REAL_MUL_LZERO; +"REAL_MUL_POS_LE",REAL_MUL_POS_LE; +"REAL_MUL_POS_LT",REAL_MUL_POS_LT; +"REAL_MUL_RID",REAL_MUL_RID; +"REAL_MUL_RINV",REAL_MUL_RINV; +"REAL_MUL_RINV_UNIQ",REAL_MUL_RINV_UNIQ; +"REAL_MUL_RNEG",REAL_MUL_RNEG; +"REAL_MUL_RZERO",REAL_MUL_RZERO; +"REAL_MUL_SIN_COS",REAL_MUL_SIN_COS; +"REAL_MUL_SIN_SIN",REAL_MUL_SIN_SIN; +"REAL_MUL_SUM",REAL_MUL_SUM; +"REAL_MUL_SUM_NUMSEG",REAL_MUL_SUM_NUMSEG; +"REAL_MUL_SYM",REAL_MUL_SYM; +"REAL_MVT",REAL_MVT; +"REAL_MVT_CAUCHY",REAL_MVT_CAUCHY; +"REAL_MVT_SIMPLE",REAL_MVT_SIMPLE; +"REAL_MVT_VERY_SIMPLE",REAL_MVT_VERY_SIMPLE; +"REAL_NEG",REAL_NEG; +"REAL_NEGLIGIBLE_COUNTABLE",REAL_NEGLIGIBLE_COUNTABLE; +"REAL_NEGLIGIBLE_COUNTABLE_UNIONS",REAL_NEGLIGIBLE_COUNTABLE_UNIONS; +"REAL_NEGLIGIBLE_DIFF",REAL_NEGLIGIBLE_DIFF; +"REAL_NEGLIGIBLE_EMPTY",REAL_NEGLIGIBLE_EMPTY; +"REAL_NEGLIGIBLE_FINITE",REAL_NEGLIGIBLE_FINITE; +"REAL_NEGLIGIBLE_FRONTIER_INTERVAL",REAL_NEGLIGIBLE_FRONTIER_INTERVAL; +"REAL_NEGLIGIBLE_INSERT",REAL_NEGLIGIBLE_INSERT; +"REAL_NEGLIGIBLE_INTER",REAL_NEGLIGIBLE_INTER; +"REAL_NEGLIGIBLE_ON_INTERVALS",REAL_NEGLIGIBLE_ON_INTERVALS; +"REAL_NEGLIGIBLE_OUTER",REAL_NEGLIGIBLE_OUTER; +"REAL_NEGLIGIBLE_OUTER_LE",REAL_NEGLIGIBLE_OUTER_LE; +"REAL_NEGLIGIBLE_REAL_INTERVAL",REAL_NEGLIGIBLE_REAL_INTERVAL; +"REAL_NEGLIGIBLE_SING",REAL_NEGLIGIBLE_SING; +"REAL_NEGLIGIBLE_SUBSET",REAL_NEGLIGIBLE_SUBSET; +"REAL_NEGLIGIBLE_TRANSLATION",REAL_NEGLIGIBLE_TRANSLATION; +"REAL_NEGLIGIBLE_TRANSLATION_EQ",REAL_NEGLIGIBLE_TRANSLATION_EQ; +"REAL_NEGLIGIBLE_TRANSLATION_REV",REAL_NEGLIGIBLE_TRANSLATION_REV; +"REAL_NEGLIGIBLE_UNION",REAL_NEGLIGIBLE_UNION; +"REAL_NEGLIGIBLE_UNIONS",REAL_NEGLIGIBLE_UNIONS; +"REAL_NEGLIGIBLE_UNION_EQ",REAL_NEGLIGIBLE_UNION_EQ; +"REAL_NEGNEG",REAL_NEGNEG; +"REAL_NEG_0",REAL_NEG_0; +"REAL_NEG_ADD",REAL_NEG_ADD; +"REAL_NEG_EQ",REAL_NEG_EQ; +"REAL_NEG_EQ_0",REAL_NEG_EQ_0; +"REAL_NEG_GE0",REAL_NEG_GE0; +"REAL_NEG_GT0",REAL_NEG_GT0; +"REAL_NEG_LE0",REAL_NEG_LE0; +"REAL_NEG_LMUL",REAL_NEG_LMUL; +"REAL_NEG_LT0",REAL_NEG_LT0; +"REAL_NEG_MINUS1",REAL_NEG_MINUS1; +"REAL_NEG_MUL2",REAL_NEG_MUL2; +"REAL_NEG_NEG",REAL_NEG_NEG; +"REAL_NEG_RMUL",REAL_NEG_RMUL; +"REAL_NEG_SUB",REAL_NEG_SUB; +"REAL_NORM",REAL_NORM; +"REAL_NORM_POS",REAL_NORM_POS; +"REAL_NOT_EQ",REAL_NOT_EQ; +"REAL_NOT_LE",REAL_NOT_LE; +"REAL_NOT_LT",REAL_NOT_LT; +"REAL_OF_INT_OF_REAL",REAL_OF_INT_OF_REAL; +"REAL_OF_NUM_ADD",REAL_OF_NUM_ADD; +"REAL_OF_NUM_BINOM",REAL_OF_NUM_BINOM; +"REAL_OF_NUM_EQ",REAL_OF_NUM_EQ; +"REAL_OF_NUM_GE",REAL_OF_NUM_GE; +"REAL_OF_NUM_GT",REAL_OF_NUM_GT; +"REAL_OF_NUM_LE",REAL_OF_NUM_LE; +"REAL_OF_NUM_LT",REAL_OF_NUM_LT; +"REAL_OF_NUM_MAX",REAL_OF_NUM_MAX; +"REAL_OF_NUM_MIN",REAL_OF_NUM_MIN; +"REAL_OF_NUM_MUL",REAL_OF_NUM_MUL; +"REAL_OF_NUM_POW",REAL_OF_NUM_POW; +"REAL_OF_NUM_SUB",REAL_OF_NUM_SUB; +"REAL_OF_NUM_SUC",REAL_OF_NUM_SUC; +"REAL_OF_NUM_SUM",REAL_OF_NUM_SUM; +"REAL_OF_NUM_SUM_NUMSEG",REAL_OF_NUM_SUM_NUMSEG; +"REAL_OPEN",REAL_OPEN; +"REAL_OPEN_CLOSED_INTERVAL",REAL_OPEN_CLOSED_INTERVAL; +"REAL_OPEN_DIFF",REAL_OPEN_DIFF; +"REAL_OPEN_EMPTY",REAL_OPEN_EMPTY; +"REAL_OPEN_EXISTS_RATIONAL",REAL_OPEN_EXISTS_RATIONAL; +"REAL_OPEN_HALFSPACE_GT",REAL_OPEN_HALFSPACE_GT; +"REAL_OPEN_HALFSPACE_LT",REAL_OPEN_HALFSPACE_LT; +"REAL_OPEN_IN",REAL_OPEN_IN; +"REAL_OPEN_INTER",REAL_OPEN_INTER; +"REAL_OPEN_INTERS",REAL_OPEN_INTERS; +"REAL_OPEN_RATIONAL",REAL_OPEN_RATIONAL; +"REAL_OPEN_REAL_CLOSED",REAL_OPEN_REAL_CLOSED; +"REAL_OPEN_REAL_INTERVAL",REAL_OPEN_REAL_INTERVAL; +"REAL_OPEN_SET_EXISTS_RATIONAL",REAL_OPEN_SET_EXISTS_RATIONAL; +"REAL_OPEN_SET_RATIONAL",REAL_OPEN_SET_RATIONAL; +"REAL_OPEN_SUBREAL_OPEN",REAL_OPEN_SUBREAL_OPEN; +"REAL_OPEN_UNION",REAL_OPEN_UNION; +"REAL_OPEN_UNIONS",REAL_OPEN_UNIONS; +"REAL_OPEN_UNIV",REAL_OPEN_UNIV; +"REAL_PARTIAL_SUMS_LE_INFSUM",REAL_PARTIAL_SUMS_LE_INFSUM; +"REAL_POLYFUN_EQ_0",REAL_POLYFUN_EQ_0; +"REAL_POLYFUN_EQ_CONST",REAL_POLYFUN_EQ_CONST; +"REAL_POLYFUN_FINITE_ROOTS",REAL_POLYFUN_FINITE_ROOTS; +"REAL_POLYFUN_ROOTBOUND",REAL_POLYFUN_ROOTBOUND; +"REAL_POLY_CLAUSES",REAL_POLY_CLAUSES; +"REAL_POLY_NEG_CLAUSES",REAL_POLY_NEG_CLAUSES; +"REAL_POS",REAL_POS; +"REAL_POS_NZ",REAL_POS_NZ; +"REAL_POW",REAL_POW; +"REAL_POW2_ABS",REAL_POW2_ABS; +"REAL_POWER_SERIES_CONV_IMP_ABSCONV",REAL_POWER_SERIES_CONV_IMP_ABSCONV; +"REAL_POW_1",REAL_POW_1; +"REAL_POW_1_LE",REAL_POW_1_LE; +"REAL_POW_1_LT",REAL_POW_1_LT; +"REAL_POW_2",REAL_POW_2; +"REAL_POW_ADD",REAL_POW_ADD; +"REAL_POW_DIV",REAL_POW_DIV; +"REAL_POW_EQ",REAL_POW_EQ; +"REAL_POW_EQ_0",REAL_POW_EQ_0; +"REAL_POW_EQ_1",REAL_POW_EQ_1; +"REAL_POW_EQ_1_IMP",REAL_POW_EQ_1_IMP; +"REAL_POW_EQ_ABS",REAL_POW_EQ_ABS; +"REAL_POW_EQ_EQ",REAL_POW_EQ_EQ; +"REAL_POW_EQ_ODD",REAL_POW_EQ_ODD; +"REAL_POW_EQ_ODD_EQ",REAL_POW_EQ_ODD_EQ; +"REAL_POW_INV",REAL_POW_INV; +"REAL_POW_LBOUND",REAL_POW_LBOUND; +"REAL_POW_LE",REAL_POW_LE; +"REAL_POW_LE2",REAL_POW_LE2; +"REAL_POW_LE2_ODD",REAL_POW_LE2_ODD; +"REAL_POW_LE2_ODD_EQ",REAL_POW_LE2_ODD_EQ; +"REAL_POW_LE2_REV",REAL_POW_LE2_REV; +"REAL_POW_LE_1",REAL_POW_LE_1; +"REAL_POW_LT",REAL_POW_LT; +"REAL_POW_LT2",REAL_POW_LT2; +"REAL_POW_LT2_ODD",REAL_POW_LT2_ODD; +"REAL_POW_LT2_ODD_EQ",REAL_POW_LT2_ODD_EQ; +"REAL_POW_LT2_REV",REAL_POW_LT2_REV; +"REAL_POW_LT_1",REAL_POW_LT_1; +"REAL_POW_MONO",REAL_POW_MONO; +"REAL_POW_MONO_INV",REAL_POW_MONO_INV; +"REAL_POW_MONO_LT",REAL_POW_MONO_LT; +"REAL_POW_MUL",REAL_POW_MUL; +"REAL_POW_NEG",REAL_POW_NEG; +"REAL_POW_NZ",REAL_POW_NZ; +"REAL_POW_ONE",REAL_POW_ONE; +"REAL_POW_POW",REAL_POW_POW; +"REAL_POW_ROOT",REAL_POW_ROOT; +"REAL_POW_SUB",REAL_POW_SUB; +"REAL_POW_ZERO",REAL_POW_ZERO; +"REAL_RNEG_UNIQ",REAL_RNEG_UNIQ; +"REAL_ROLLE",REAL_ROLLE; +"REAL_ROLLE_SIMPLE",REAL_ROLLE_SIMPLE; +"REAL_ROOT_DIV",REAL_ROOT_DIV; +"REAL_ROOT_INV",REAL_ROOT_INV; +"REAL_ROOT_LE",REAL_ROOT_LE; +"REAL_ROOT_MUL",REAL_ROOT_MUL; +"REAL_ROOT_POW",REAL_ROOT_POW; +"REAL_ROOT_RPOW",REAL_ROOT_RPOW; +"REAL_RSQRT_LE",REAL_RSQRT_LE; +"REAL_SECOND_MEAN_VALUE_THEOREM",REAL_SECOND_MEAN_VALUE_THEOREM; +"REAL_SECOND_MEAN_VALUE_THEOREM_BONNET",REAL_SECOND_MEAN_VALUE_THEOREM_BONNET; +"REAL_SECOND_MEAN_VALUE_THEOREM_BONNET_FULL",REAL_SECOND_MEAN_VALUE_THEOREM_BONNET_FULL; +"REAL_SECOND_MEAN_VALUE_THEOREM_FULL",REAL_SECOND_MEAN_VALUE_THEOREM_FULL; +"REAL_SECOND_MEAN_VALUE_THEOREM_GEN",REAL_SECOND_MEAN_VALUE_THEOREM_GEN; +"REAL_SECOND_MEAN_VALUE_THEOREM_GEN_FULL",REAL_SECOND_MEAN_VALUE_THEOREM_GEN_FULL; +"REAL_SEGMENT",REAL_SEGMENT; +"REAL_SEGMENT_INTERVAL",REAL_SEGMENT_INTERVAL; +"REAL_SEGMENT_SEGMENT",REAL_SEGMENT_SEGMENT; +"REAL_SEQ_OFFSET",REAL_SEQ_OFFSET; +"REAL_SEQ_OFFSET_REV",REAL_SEQ_OFFSET_REV; +"REAL_SERIES",REAL_SERIES; +"REAL_SERIES_0",REAL_SERIES_0; +"REAL_SERIES_ABSCONV_IMP_CONV",REAL_SERIES_ABSCONV_IMP_CONV; +"REAL_SERIES_ADD",REAL_SERIES_ADD; +"REAL_SERIES_CAUCHY",REAL_SERIES_CAUCHY; +"REAL_SERIES_CAUCHY_UNIFORM",REAL_SERIES_CAUCHY_UNIFORM; +"REAL_SERIES_COMPARISON",REAL_SERIES_COMPARISON; +"REAL_SERIES_COMPARISON_UNIFORM",REAL_SERIES_COMPARISON_UNIFORM; +"REAL_SERIES_DIFFS",REAL_SERIES_DIFFS; +"REAL_SERIES_DIRICHLET",REAL_SERIES_DIRICHLET; +"REAL_SERIES_FINITE",REAL_SERIES_FINITE; +"REAL_SERIES_FINITE_SUPPORT",REAL_SERIES_FINITE_SUPPORT; +"REAL_SERIES_FROM",REAL_SERIES_FROM; +"REAL_SERIES_GOESTOZERO",REAL_SERIES_GOESTOZERO; +"REAL_SERIES_LMUL",REAL_SERIES_LMUL; +"REAL_SERIES_NEG",REAL_SERIES_NEG; +"REAL_SERIES_RATIO",REAL_SERIES_RATIO; +"REAL_SERIES_RESTRICT",REAL_SERIES_RESTRICT; +"REAL_SERIES_RMUL",REAL_SERIES_RMUL; +"REAL_SERIES_SUB",REAL_SERIES_SUB; +"REAL_SERIES_SUBSET",REAL_SERIES_SUBSET; +"REAL_SERIES_SUM",REAL_SERIES_SUM; +"REAL_SERIES_TRIVIAL",REAL_SERIES_TRIVIAL; +"REAL_SERIES_UNIQUE",REAL_SERIES_UNIQUE; +"REAL_SGN",REAL_SGN; +"REAL_SGN_0",REAL_SGN_0; +"REAL_SGN_ABS",REAL_SGN_ABS; +"REAL_SGN_CASES",REAL_SGN_CASES; +"REAL_SGN_DIV",REAL_SGN_DIV; +"REAL_SGN_EQ",REAL_SGN_EQ; +"REAL_SGN_IM_COMPLEX_DIV",REAL_SGN_IM_COMPLEX_DIV; +"REAL_SGN_INEQS",REAL_SGN_INEQS; +"REAL_SGN_INV",REAL_SGN_INV; +"REAL_SGN_MUL",REAL_SGN_MUL; +"REAL_SGN_NEG",REAL_SGN_NEG; +"REAL_SGN_RE_COMPLEX_DIV",REAL_SGN_RE_COMPLEX_DIV; +"REAL_SIN",REAL_SIN; +"REAL_SOS_EQ_0",REAL_SOS_EQ_0; +"REAL_STEINHAUS",REAL_STEINHAUS; +"REAL_STONE_WEIERSTRASS",REAL_STONE_WEIERSTRASS; +"REAL_STONE_WEIERSTRASS_ALT",REAL_STONE_WEIERSTRASS_ALT; +"REAL_SUB",REAL_SUB; +"REAL_SUB_0",REAL_SUB_0; +"REAL_SUB_ABS",REAL_SUB_ABS; +"REAL_SUB_ADD",REAL_SUB_ADD; +"REAL_SUB_ADD2",REAL_SUB_ADD2; +"REAL_SUB_ARG",REAL_SUB_ARG; +"REAL_SUB_COS",REAL_SUB_COS; +"REAL_SUB_INV",REAL_SUB_INV; +"REAL_SUB_LDISTRIB",REAL_SUB_LDISTRIB; +"REAL_SUB_LE",REAL_SUB_LE; +"REAL_SUB_LNEG",REAL_SUB_LNEG; +"REAL_SUB_LT",REAL_SUB_LT; +"REAL_SUB_LZERO",REAL_SUB_LZERO; +"REAL_SUB_NEG2",REAL_SUB_NEG2; +"REAL_SUB_POLYFUN",REAL_SUB_POLYFUN; +"REAL_SUB_POLYFUN_ALT",REAL_SUB_POLYFUN_ALT; +"REAL_SUB_POW",REAL_SUB_POW; +"REAL_SUB_POW_L1",REAL_SUB_POW_L1; +"REAL_SUB_POW_R1",REAL_SUB_POW_R1; +"REAL_SUB_RDISTRIB",REAL_SUB_RDISTRIB; +"REAL_SUB_REFL",REAL_SUB_REFL; +"REAL_SUB_RNEG",REAL_SUB_RNEG; +"REAL_SUB_RZERO",REAL_SUB_RZERO; +"REAL_SUB_SIN",REAL_SUB_SIN; +"REAL_SUB_SUB",REAL_SUB_SUB; +"REAL_SUB_SUB2",REAL_SUB_SUB2; +"REAL_SUB_TAN",REAL_SUB_TAN; +"REAL_SUB_TRIANGLE",REAL_SUB_TRIANGLE; +"REAL_SUMMABLE",REAL_SUMMABLE; +"REAL_SUMMABLE_0",REAL_SUMMABLE_0; +"REAL_SUMMABLE_ADD",REAL_SUMMABLE_ADD; +"REAL_SUMMABLE_COMPARISON",REAL_SUMMABLE_COMPARISON; +"REAL_SUMMABLE_COMPLEX",REAL_SUMMABLE_COMPLEX; +"REAL_SUMMABLE_EQ",REAL_SUMMABLE_EQ; +"REAL_SUMMABLE_EQ_COFINITE",REAL_SUMMABLE_EQ_COFINITE; +"REAL_SUMMABLE_EQ_EVENTUALLY",REAL_SUMMABLE_EQ_EVENTUALLY; +"REAL_SUMMABLE_FROM_ELSEWHERE",REAL_SUMMABLE_FROM_ELSEWHERE; +"REAL_SUMMABLE_GP",REAL_SUMMABLE_GP; +"REAL_SUMMABLE_IFF",REAL_SUMMABLE_IFF; +"REAL_SUMMABLE_IFF_COFINITE",REAL_SUMMABLE_IFF_COFINITE; +"REAL_SUMMABLE_IFF_EVENTUALLY",REAL_SUMMABLE_IFF_EVENTUALLY; +"REAL_SUMMABLE_IMP_BOUNDED",REAL_SUMMABLE_IMP_BOUNDED; +"REAL_SUMMABLE_IMP_REAL_SUMS_BOUNDED",REAL_SUMMABLE_IMP_REAL_SUMS_BOUNDED; +"REAL_SUMMABLE_IMP_TOZERO",REAL_SUMMABLE_IMP_TOZERO; +"REAL_SUMMABLE_LMUL",REAL_SUMMABLE_LMUL; +"REAL_SUMMABLE_NEG",REAL_SUMMABLE_NEG; +"REAL_SUMMABLE_RESTRICT",REAL_SUMMABLE_RESTRICT; +"REAL_SUMMABLE_RMUL",REAL_SUMMABLE_RMUL; +"REAL_SUMMABLE_SUB",REAL_SUMMABLE_SUB; +"REAL_SUMMABLE_SUBSET",REAL_SUMMABLE_SUBSET; +"REAL_SUMMABLE_TRIVIAL",REAL_SUMMABLE_TRIVIAL; +"REAL_SUMS",REAL_SUMS; +"REAL_SUMS_COMPLEX",REAL_SUMS_COMPLEX; +"REAL_SUMS_EQ",REAL_SUMS_EQ; +"REAL_SUMS_FINITE_DIFF",REAL_SUMS_FINITE_DIFF; +"REAL_SUMS_FINITE_UNION",REAL_SUMS_FINITE_UNION; +"REAL_SUMS_GP",REAL_SUMS_GP; +"REAL_SUMS_IFF",REAL_SUMS_IFF; +"REAL_SUMS_IM",REAL_SUMS_IM; +"REAL_SUMS_INFSUM",REAL_SUMS_INFSUM; +"REAL_SUMS_LE2",REAL_SUMS_LE2; +"REAL_SUMS_OFFSET",REAL_SUMS_OFFSET; +"REAL_SUMS_OFFSET_REV",REAL_SUMS_OFFSET_REV; +"REAL_SUMS_RE",REAL_SUMS_RE; +"REAL_SUMS_REINDEX",REAL_SUMS_REINDEX; +"REAL_SUMS_SUMMABLE",REAL_SUMS_SUMMABLE; +"REAL_SUM_INTEGRAL_BOUNDS_DECREASING",REAL_SUM_INTEGRAL_BOUNDS_DECREASING; +"REAL_SUM_INTEGRAL_BOUNDS_INCREASING",REAL_SUM_INTEGRAL_BOUNDS_INCREASING; +"REAL_SUM_INTEGRAL_LBOUND_DECREASING",REAL_SUM_INTEGRAL_LBOUND_DECREASING; +"REAL_SUM_INTEGRAL_LBOUND_INCREASING",REAL_SUM_INTEGRAL_LBOUND_INCREASING; +"REAL_SUM_INTEGRAL_UBOUND_DECREASING",REAL_SUM_INTEGRAL_UBOUND_DECREASING; +"REAL_SUM_INTEGRAL_UBOUND_INCREASING",REAL_SUM_INTEGRAL_UBOUND_INCREASING; +"REAL_SUP_ASCLOSE",REAL_SUP_ASCLOSE; +"REAL_SUP_BOUNDS",REAL_SUP_BOUNDS; +"REAL_SUP_EQ_INF",REAL_SUP_EQ_INF; +"REAL_SUP_LE",REAL_SUP_LE; +"REAL_SUP_LE_FINITE",REAL_SUP_LE_FINITE; +"REAL_SUP_LE_SUBSET",REAL_SUP_LE_SUBSET; +"REAL_SUP_LT_FINITE",REAL_SUP_LT_FINITE; +"REAL_SUP_UNIQUE",REAL_SUP_UNIQUE; +"REAL_TAN",REAL_TAN; +"REAL_TAYLOR",REAL_TAYLOR; +"REAL_TAYLOR_MVT_NEG",REAL_TAYLOR_MVT_NEG; +"REAL_TAYLOR_MVT_POS",REAL_TAYLOR_MVT_POS; +"REAL_TENDSTO",REAL_TENDSTO; +"REAL_TIETZE_PERIODIC_INTERVAL",REAL_TIETZE_PERIODIC_INTERVAL; +"REAL_TRUNCATE",REAL_TRUNCATE; +"REAL_TRUNCATE_POS",REAL_TRUNCATE_POS; +"REAL_UNIFORMLY_CONTINUOUS_IMP_REAL_CONTINUOUS",REAL_UNIFORMLY_CONTINUOUS_IMP_REAL_CONTINUOUS; +"REAL_UNIFORMLY_CONTINUOUS_ON",REAL_UNIFORMLY_CONTINUOUS_ON; +"REAL_UNIFORMLY_CONTINUOUS_ON_ADD",REAL_UNIFORMLY_CONTINUOUS_ON_ADD; +"REAL_UNIFORMLY_CONTINUOUS_ON_COMPOSE",REAL_UNIFORMLY_CONTINUOUS_ON_COMPOSE; +"REAL_UNIFORMLY_CONTINUOUS_ON_CONST",REAL_UNIFORMLY_CONTINUOUS_ON_CONST; +"REAL_UNIFORMLY_CONTINUOUS_ON_ID",REAL_UNIFORMLY_CONTINUOUS_ON_ID; +"REAL_UNIFORMLY_CONTINUOUS_ON_LMUL",REAL_UNIFORMLY_CONTINUOUS_ON_LMUL; +"REAL_UNIFORMLY_CONTINUOUS_ON_NEG",REAL_UNIFORMLY_CONTINUOUS_ON_NEG; +"REAL_UNIFORMLY_CONTINUOUS_ON_RMUL",REAL_UNIFORMLY_CONTINUOUS_ON_RMUL; +"REAL_UNIFORMLY_CONTINUOUS_ON_SEQUENTIALLY",REAL_UNIFORMLY_CONTINUOUS_ON_SEQUENTIALLY; +"REAL_UNIFORMLY_CONTINUOUS_ON_SUB",REAL_UNIFORMLY_CONTINUOUS_ON_SUB; +"REAL_UNIFORMLY_CONTINUOUS_ON_SUBSET",REAL_UNIFORMLY_CONTINUOUS_ON_SUBSET; +"REAL_UNIFORMLY_CONTINUOUS_ON_SUM",REAL_UNIFORMLY_CONTINUOUS_ON_SUM; +"REAL_VARIATION_AFFINITY",REAL_VARIATION_AFFINITY; +"REAL_VARIATION_AFFINITY2",REAL_VARIATION_AFFINITY2; +"REAL_VARIATION_COMBINE",REAL_VARIATION_COMBINE; +"REAL_VARIATION_CONTINUOUS",REAL_VARIATION_CONTINUOUS; +"REAL_VARIATION_CONTINUOUS_LEFT",REAL_VARIATION_CONTINUOUS_LEFT; +"REAL_VARIATION_CONTINUOUS_RIGHT",REAL_VARIATION_CONTINUOUS_RIGHT; +"REAL_VARIATION_GE_ABS_FUNCTION",REAL_VARIATION_GE_ABS_FUNCTION; +"REAL_VARIATION_GE_FUNCTION",REAL_VARIATION_GE_FUNCTION; +"REAL_VARIATION_MINUS_FUNCTION_MONOTONE",REAL_VARIATION_MINUS_FUNCTION_MONOTONE; +"REAL_VARIATION_MONOTONE",REAL_VARIATION_MONOTONE; +"REAL_VARIATION_NEG",REAL_VARIATION_NEG; +"REAL_VARIATION_POS_LE",REAL_VARIATION_POS_LE; +"REAL_VARIATION_REFLECT",REAL_VARIATION_REFLECT; +"REAL_VARIATION_REFLECT2",REAL_VARIATION_REFLECT2; +"REAL_VARIATION_REFLECT_INTERVAL",REAL_VARIATION_REFLECT_INTERVAL; +"REAL_VARIATION_TRANSLATION",REAL_VARIATION_TRANSLATION; +"REAL_VARIATION_TRANSLATION2",REAL_VARIATION_TRANSLATION2; +"REAL_VARIATION_TRANSLATION_INTERVAL",REAL_VARIATION_TRANSLATION_INTERVAL; +"REAL_VARIATION_TRIANGLE",REAL_VARIATION_TRIANGLE; +"REAL_VSUM",REAL_VSUM; +"REAL_WLOG_LE",REAL_WLOG_LE; +"REAL_WLOG_LT",REAL_WLOG_LT; +"RECTIFIABLE_PATH_DIFFERENTIABLE",RECTIFIABLE_PATH_DIFFERENTIABLE; +"RECTIFIABLE_PATH_IMP_PATH",RECTIFIABLE_PATH_IMP_PATH; +"RECTIFIABLE_PATH_JOIN",RECTIFIABLE_PATH_JOIN; +"RECTIFIABLE_PATH_JOIN_EQ",RECTIFIABLE_PATH_JOIN_EQ; +"RECTIFIABLE_PATH_JOIN_IMP",RECTIFIABLE_PATH_JOIN_IMP; +"RECTIFIABLE_PATH_LINEPATH",RECTIFIABLE_PATH_LINEPATH; +"RECTIFIABLE_PATH_REVERSEPATH",RECTIFIABLE_PATH_REVERSEPATH; +"RECTIFIABLE_PATH_SUBPATH",RECTIFIABLE_PATH_SUBPATH; +"RECTIFIABLE_VALID_PATH",RECTIFIABLE_VALID_PATH; +"RECURSION_CASEWISE",RECURSION_CASEWISE; +"RECURSION_CASEWISE_PAIRWISE",RECURSION_CASEWISE_PAIRWISE; +"RECURSION_SUPERADMISSIBLE",RECURSION_SUPERADMISSIBLE; +"REDUCED_LABELLING",REDUCED_LABELLING; +"REDUCED_LABELLING_0",REDUCED_LABELLING_0; +"REDUCED_LABELLING_1",REDUCED_LABELLING_1; +"REDUCED_LABELLING_SUC",REDUCED_LABELLING_SUC; +"REDUCED_LABELLING_UNIQUE",REDUCED_LABELLING_UNIQUE; +"REDUCE_LABELLING_0",REDUCE_LABELLING_0; +"REFLECT_ALONG_0",REFLECT_ALONG_0; +"REFLECT_ALONG_1D",REFLECT_ALONG_1D; +"REFLECT_ALONG_ADD",REFLECT_ALONG_ADD; +"REFLECT_ALONG_BASIS",REFLECT_ALONG_BASIS; +"REFLECT_ALONG_EQ_0",REFLECT_ALONG_EQ_0; +"REFLECT_ALONG_EQ_SELF",REFLECT_ALONG_EQ_SELF; +"REFLECT_ALONG_INVOLUTION",REFLECT_ALONG_INVOLUTION; +"REFLECT_ALONG_LINEAR_IMAGE",REFLECT_ALONG_LINEAR_IMAGE; +"REFLECT_ALONG_MUL",REFLECT_ALONG_MUL; +"REFLECT_ALONG_REFL",REFLECT_ALONG_REFL; +"REFLECT_ALONG_SCALE",REFLECT_ALONG_SCALE; +"REFLECT_ALONG_ZERO",REFLECT_ALONG_ZERO; +"REFLECT_INTERVAL",REFLECT_INTERVAL; +"REFLECT_REAL_INTERVAL",REFLECT_REAL_INTERVAL; +"REFL_CLAUSE",REFL_CLAUSE; +"RELATIVE_BOUNDARY_OF_CONVEX_HULL",RELATIVE_BOUNDARY_OF_CONVEX_HULL; +"RELATIVE_BOUNDARY_OF_POLYHEDRON",RELATIVE_BOUNDARY_OF_POLYHEDRON; +"RELATIVE_BOUNDARY_OF_TRIANGLE",RELATIVE_BOUNDARY_OF_TRIANGLE; +"RELATIVE_BOUNDARY_RETRACT_OF_PUNCTURED_AFFINE_HULL",RELATIVE_BOUNDARY_RETRACT_OF_PUNCTURED_AFFINE_HULL; +"RELATIVE_FRONTIER_BALL",RELATIVE_FRONTIER_BALL; +"RELATIVE_FRONTIER_CBALL",RELATIVE_FRONTIER_CBALL; +"RELATIVE_FRONTIER_CLOSURE",RELATIVE_FRONTIER_CLOSURE; +"RELATIVE_FRONTIER_CONVEX_HULL_CASES",RELATIVE_FRONTIER_CONVEX_HULL_CASES; +"RELATIVE_FRONTIER_CONVEX_HULL_EXPLICIT",RELATIVE_FRONTIER_CONVEX_HULL_EXPLICIT; +"RELATIVE_FRONTIER_CONVEX_INTER_AFFINE",RELATIVE_FRONTIER_CONVEX_INTER_AFFINE; +"RELATIVE_FRONTIER_EMPTY",RELATIVE_FRONTIER_EMPTY; +"RELATIVE_FRONTIER_EQ_EMPTY",RELATIVE_FRONTIER_EQ_EMPTY; +"RELATIVE_FRONTIER_FRONTIER",RELATIVE_FRONTIER_FRONTIER; +"RELATIVE_FRONTIER_INJECTIVE_LINEAR_IMAGE",RELATIVE_FRONTIER_INJECTIVE_LINEAR_IMAGE; +"RELATIVE_FRONTIER_NONEMPTY_INTERIOR",RELATIVE_FRONTIER_NONEMPTY_INTERIOR; +"RELATIVE_FRONTIER_NOT_SING",RELATIVE_FRONTIER_NOT_SING; +"RELATIVE_FRONTIER_OF_CONVEX_HULL",RELATIVE_FRONTIER_OF_CONVEX_HULL; +"RELATIVE_FRONTIER_OF_POLYHEDRON",RELATIVE_FRONTIER_OF_POLYHEDRON; +"RELATIVE_FRONTIER_OF_POLYHEDRON_ALT",RELATIVE_FRONTIER_OF_POLYHEDRON_ALT; +"RELATIVE_FRONTIER_OF_TRIANGLE",RELATIVE_FRONTIER_OF_TRIANGLE; +"RELATIVE_FRONTIER_RETRACT_OF_PUNCTURED_AFFINE_HULL",RELATIVE_FRONTIER_RETRACT_OF_PUNCTURED_AFFINE_HULL; +"RELATIVE_FRONTIER_SING",RELATIVE_FRONTIER_SING; +"RELATIVE_FRONTIER_TRANSLATION",RELATIVE_FRONTIER_TRANSLATION; +"RELATIVE_INTERIOR",RELATIVE_INTERIOR; +"RELATIVE_INTERIOR_AFFINE",RELATIVE_INTERIOR_AFFINE; +"RELATIVE_INTERIOR_CONVEX_CONTAINS_SAME_RAY",RELATIVE_INTERIOR_CONVEX_CONTAINS_SAME_RAY; +"RELATIVE_INTERIOR_CONVEX_HULL_EXPLICIT",RELATIVE_INTERIOR_CONVEX_HULL_EXPLICIT; +"RELATIVE_INTERIOR_CONVEX_INTER_AFFINE",RELATIVE_INTERIOR_CONVEX_INTER_AFFINE; +"RELATIVE_INTERIOR_CONVEX_PROLONG",RELATIVE_INTERIOR_CONVEX_PROLONG; +"RELATIVE_INTERIOR_EMPTY",RELATIVE_INTERIOR_EMPTY; +"RELATIVE_INTERIOR_EQ",RELATIVE_INTERIOR_EQ; +"RELATIVE_INTERIOR_EQ_CLOSURE",RELATIVE_INTERIOR_EQ_CLOSURE; +"RELATIVE_INTERIOR_EQ_EMPTY",RELATIVE_INTERIOR_EQ_EMPTY; +"RELATIVE_INTERIOR_INJECTIVE_LINEAR_IMAGE",RELATIVE_INTERIOR_INJECTIVE_LINEAR_IMAGE; +"RELATIVE_INTERIOR_INTERIOR",RELATIVE_INTERIOR_INTERIOR; +"RELATIVE_INTERIOR_LINEAR_IMAGE_CONVEX",RELATIVE_INTERIOR_LINEAR_IMAGE_CONVEX; +"RELATIVE_INTERIOR_MAXIMAL",RELATIVE_INTERIOR_MAXIMAL; +"RELATIVE_INTERIOR_NONEMPTY_INTERIOR",RELATIVE_INTERIOR_NONEMPTY_INTERIOR; +"RELATIVE_INTERIOR_OF_POLYHEDRON",RELATIVE_INTERIOR_OF_POLYHEDRON; +"RELATIVE_INTERIOR_OPEN",RELATIVE_INTERIOR_OPEN; +"RELATIVE_INTERIOR_OPEN_IN",RELATIVE_INTERIOR_OPEN_IN; +"RELATIVE_INTERIOR_PCROSS",RELATIVE_INTERIOR_PCROSS; +"RELATIVE_INTERIOR_POLYHEDRON_EXPLICIT",RELATIVE_INTERIOR_POLYHEDRON_EXPLICIT; +"RELATIVE_INTERIOR_PROLONG",RELATIVE_INTERIOR_PROLONG; +"RELATIVE_INTERIOR_SEGMENT",RELATIVE_INTERIOR_SEGMENT; +"RELATIVE_INTERIOR_SING",RELATIVE_INTERIOR_SING; +"RELATIVE_INTERIOR_SUBSET",RELATIVE_INTERIOR_SUBSET; +"RELATIVE_INTERIOR_TRANSLATION",RELATIVE_INTERIOR_TRANSLATION; +"RELATIVE_INTERIOR_UNBOUNDED_CONVEX_CONTAINS_RAY",RELATIVE_INTERIOR_UNBOUNDED_CONVEX_CONTAINS_RAY; +"RELATIVE_INTERIOR_UNBOUNDED_CONVEX_CONTAINS_RAYS",RELATIVE_INTERIOR_UNBOUNDED_CONVEX_CONTAINS_RAYS; +"RELATIVE_INTERIOR_UNIQUE",RELATIVE_INTERIOR_UNIQUE; +"RELATIVE_INTERIOR_UNIV",RELATIVE_INTERIOR_UNIV; +"REPLICATE",REPLICATE; +"REP_ABS_PAIR",REP_ABS_PAIR; +"REST",REST; +"RETRACTION",RETRACTION; +"RETRACTION_ARC",RETRACTION_ARC; +"RETRACTION_IDEMPOTENT",RETRACTION_IDEMPOTENT; +"RETRACTION_IMP_QUOTIENT_MAP",RETRACTION_IMP_QUOTIENT_MAP; +"RETRACTION_REFL",RETRACTION_REFL; +"RETRACTION_SUBSET",RETRACTION_SUBSET; +"RETRACTION_o",RETRACTION_o; +"RETRACT_FIXPOINT_PROPERTY",RETRACT_FIXPOINT_PROPERTY; +"RETRACT_OF_CLOSED",RETRACT_OF_CLOSED; +"RETRACT_OF_COHOMOTOPICALLY_TRIVIAL",RETRACT_OF_COHOMOTOPICALLY_TRIVIAL; +"RETRACT_OF_COHOMOTOPICALLY_TRIVIAL_NULL",RETRACT_OF_COHOMOTOPICALLY_TRIVIAL_NULL; +"RETRACT_OF_COMPACT",RETRACT_OF_COMPACT; +"RETRACT_OF_CONNECTED",RETRACT_OF_CONNECTED; +"RETRACT_OF_CONTRACTIBLE",RETRACT_OF_CONTRACTIBLE; +"RETRACT_OF_EMPTY",RETRACT_OF_EMPTY; +"RETRACT_OF_HOMOTOPICALLY_TRIVIAL",RETRACT_OF_HOMOTOPICALLY_TRIVIAL; +"RETRACT_OF_HOMOTOPICALLY_TRIVIAL_NULL",RETRACT_OF_HOMOTOPICALLY_TRIVIAL_NULL; +"RETRACT_OF_IMP_EXTENSIBLE",RETRACT_OF_IMP_EXTENSIBLE; +"RETRACT_OF_IMP_SUBSET",RETRACT_OF_IMP_SUBSET; +"RETRACT_OF_INJECTIVE_LINEAR_IMAGE",RETRACT_OF_INJECTIVE_LINEAR_IMAGE; +"RETRACT_OF_LINEAR_IMAGE_EQ",RETRACT_OF_LINEAR_IMAGE_EQ; +"RETRACT_OF_LOCALLY_COMPACT",RETRACT_OF_LOCALLY_COMPACT; +"RETRACT_OF_LOCALLY_CONNECTED",RETRACT_OF_LOCALLY_CONNECTED; +"RETRACT_OF_LOCALLY_PATH_CONNECTED",RETRACT_OF_LOCALLY_PATH_CONNECTED; +"RETRACT_OF_PATH_CONNECTED",RETRACT_OF_PATH_CONNECTED; +"RETRACT_OF_PCROSS",RETRACT_OF_PCROSS; +"RETRACT_OF_REFL",RETRACT_OF_REFL; +"RETRACT_OF_SIMPLY_CONNECTED",RETRACT_OF_SIMPLY_CONNECTED; +"RETRACT_OF_SING",RETRACT_OF_SING; +"RETRACT_OF_SUBSET",RETRACT_OF_SUBSET; +"RETRACT_OF_TRANS",RETRACT_OF_TRANS; +"RETRACT_OF_TRANSLATION",RETRACT_OF_TRANSLATION; +"RETRACT_OF_TRANSLATION_EQ",RETRACT_OF_TRANSLATION_EQ; +"REVERSE",REVERSE; +"REVERSEPATH_JOINPATHS",REVERSEPATH_JOINPATHS; +"REVERSEPATH_LINEAR_IMAGE",REVERSEPATH_LINEAR_IMAGE; +"REVERSEPATH_LINEPATH",REVERSEPATH_LINEPATH; +"REVERSEPATH_REVERSEPATH",REVERSEPATH_REVERSEPATH; +"REVERSEPATH_SUBPATH",REVERSEPATH_SUBPATH; +"REVERSEPATH_TRANSLATION",REVERSEPATH_TRANSLATION; +"REVERSE_APPEND",REVERSE_APPEND; +"REVERSE_REVERSE",REVERSE_REVERSE; +"RE_ADD",RE_ADD; +"RE_CACS",RE_CACS; +"RE_CACS_BOUND",RE_CACS_BOUND; +"RE_CACS_BOUNDS",RE_CACS_BOUNDS; +"RE_CASN",RE_CASN; +"RE_CASN_BOUND",RE_CASN_BOUND; +"RE_CASN_BOUNDS",RE_CASN_BOUNDS; +"RE_CATN_BOUNDS",RE_CATN_BOUNDS; +"RE_CCOS",RE_CCOS; +"RE_CEXP",RE_CEXP; +"RE_CLOG",RE_CLOG; +"RE_CLOG_POS_LE",RE_CLOG_POS_LE; +"RE_CLOG_POS_LT",RE_CLOG_POS_LT; +"RE_CLOG_POS_LT_IMP",RE_CLOG_POS_LT_IMP; +"RE_CMUL",RE_CMUL; +"RE_CNJ",RE_CNJ; +"RE_COMPLEX_DIV_EQ_0",RE_COMPLEX_DIV_EQ_0; +"RE_COMPLEX_DIV_GE_0",RE_COMPLEX_DIV_GE_0; +"RE_COMPLEX_DIV_GT_0",RE_COMPLEX_DIV_GT_0; +"RE_COMPLEX_DIV_LEMMA",RE_COMPLEX_DIV_LEMMA; +"RE_COMPLEX_DIV_LE_0",RE_COMPLEX_DIV_LE_0; +"RE_COMPLEX_DIV_LT_0",RE_COMPLEX_DIV_LT_0; +"RE_CSIN",RE_CSIN; +"RE_CSQRT",RE_CSQRT; +"RE_CX",RE_CX; +"RE_DEF",RE_DEF; +"RE_DIV_CX",RE_DIV_CX; +"RE_II",RE_II; +"RE_LINEPATH_CX",RE_LINEPATH_CX; +"RE_MUL_CX",RE_MUL_CX; +"RE_MUL_II",RE_MUL_II; +"RE_NEG",RE_NEG; +"RE_POS_SEGMENT",RE_POS_SEGMENT; +"RE_POW_2",RE_POW_2; +"RE_SUB",RE_SUB; +"RE_VSUM",RE_VSUM; +"RE_WINDING_NUMBER",RE_WINDING_NUMBER; +"RIEMANN_MAPPING_THEOREM",RIEMANN_MAPPING_THEOREM; +"RIGHT_ADD_DISTRIB",RIGHT_ADD_DISTRIB; +"RIGHT_AND_EXISTS_THM",RIGHT_AND_EXISTS_THM; +"RIGHT_AND_FORALL_THM",RIGHT_AND_FORALL_THM; +"RIGHT_EXISTS_AND_THM",RIGHT_EXISTS_AND_THM; +"RIGHT_EXISTS_IMP_THM",RIGHT_EXISTS_IMP_THM; +"RIGHT_FORALL_IMP_THM",RIGHT_FORALL_IMP_THM; +"RIGHT_FORALL_OR_THM",RIGHT_FORALL_OR_THM; +"RIGHT_IMP_EXISTS_THM",RIGHT_IMP_EXISTS_THM; +"RIGHT_IMP_FORALL_THM",RIGHT_IMP_FORALL_THM; +"RIGHT_INVERSE_LINEAR",RIGHT_INVERSE_LINEAR; +"RIGHT_INVERTIBLE_TRANSP",RIGHT_INVERTIBLE_TRANSP; +"RIGHT_OR_DISTRIB",RIGHT_OR_DISTRIB; +"RIGHT_OR_EXISTS_THM",RIGHT_OR_EXISTS_THM; +"RIGHT_OR_FORALL_THM",RIGHT_OR_FORALL_THM; +"RIGHT_SUB_DISTRIB",RIGHT_SUB_DISTRIB; +"RIGID_TRANSFORMATION_BETWEEN_2",RIGID_TRANSFORMATION_BETWEEN_2; +"RIGID_TRANSFORMATION_BETWEEN_3",RIGID_TRANSFORMATION_BETWEEN_3; +"RIGID_TRANSFORMATION_BETWEEN_CONGRUENT_SETS",RIGID_TRANSFORMATION_BETWEEN_CONGRUENT_SETS; +"RIGID_TRANSFORMATION_BETWEEN_CONGRUENT_SETS_STRONG",RIGID_TRANSFORMATION_BETWEEN_CONGRUENT_SETS_STRONG; +"ROLLE",ROLLE; +"ROOT_0",ROOT_0; +"ROOT_1",ROOT_1; +"ROOT_2",ROOT_2; +"ROOT_EXP_LOG",ROOT_EXP_LOG; +"ROOT_INJ",ROOT_INJ; +"ROOT_MONO_LE",ROOT_MONO_LE; +"ROOT_MONO_LE_EQ",ROOT_MONO_LE_EQ; +"ROOT_MONO_LT",ROOT_MONO_LT; +"ROOT_MONO_LT_EQ",ROOT_MONO_LT_EQ; +"ROOT_POS_LE",ROOT_POS_LE; +"ROOT_POS_LT",ROOT_POS_LT; +"ROOT_UNIQUE",ROOT_UNIQUE; +"ROOT_WORKS",ROOT_WORKS; +"ROTATE2D_0",ROTATE2D_0; +"ROTATE2D_2PI",ROTATE2D_2PI; +"ROTATE2D_ADD",ROTATE2D_ADD; +"ROTATE2D_ADD_VECTORS",ROTATE2D_ADD_VECTORS; +"ROTATE2D_COMPLEX",ROTATE2D_COMPLEX; +"ROTATE2D_EQ",ROTATE2D_EQ; +"ROTATE2D_EQ_0",ROTATE2D_EQ_0; +"ROTATE2D_NPI",ROTATE2D_NPI; +"ROTATE2D_PI",ROTATE2D_PI; +"ROTATE2D_PI2",ROTATE2D_PI2; +"ROTATE2D_POLAR",ROTATE2D_POLAR; +"ROTATE2D_SUB",ROTATE2D_SUB; +"ROTATE2D_SUB_ARG",ROTATE2D_SUB_ARG; +"ROTATE2D_ZERO",ROTATE2D_ZERO; +"ROTATION_EXISTS",ROTATION_EXISTS; +"ROTATION_EXISTS_1",ROTATION_EXISTS_1; +"ROTATION_LOWDIM_HORIZONTAL",ROTATION_LOWDIM_HORIZONTAL; +"ROTATION_MATRIX_2",ROTATION_MATRIX_2; +"ROTATION_MATRIX_EXISTS_BASIS",ROTATION_MATRIX_EXISTS_BASIS; +"ROTATION_MATRIX_ROTATE2D",ROTATION_MATRIX_ROTATE2D; +"ROTATION_MATRIX_ROTATE2D_EQ",ROTATION_MATRIX_ROTATE2D_EQ; +"ROTATION_RIGHTWARD_LINE",ROTATION_RIGHTWARD_LINE; +"ROTATION_ROTATE2D",ROTATION_ROTATE2D; +"ROTATION_ROTATE2D_EXISTS",ROTATION_ROTATE2D_EXISTS; +"ROTATION_ROTATE2D_EXISTS_GEN",ROTATION_ROTATE2D_EXISTS_GEN; +"ROTATION_ROTATE2D_EXISTS_ORTHOGONAL",ROTATION_ROTATE2D_EXISTS_ORTHOGONAL; +"ROTATION_ROTATE2D_EXISTS_ORTHOGONAL_ORIENTED",ROTATION_ROTATE2D_EXISTS_ORTHOGONAL_ORIENTED; +"ROTHE",ROTHE; +"ROTOINVERSION_MATRIX_REFLECT_ALONG",ROTOINVERSION_MATRIX_REFLECT_ALONG; +"ROWS_TRANSP",ROWS_TRANSP; +"ROW_TRANSP",ROW_TRANSP; +"RPOW_1_LE",RPOW_1_LE; +"RPOW_ADD",RPOW_ADD; +"RPOW_ADD_ALT",RPOW_ADD_ALT; +"RPOW_EQ_0",RPOW_EQ_0; +"RPOW_INV",RPOW_INV; +"RPOW_LE2",RPOW_LE2; +"RPOW_LNEG",RPOW_LNEG; +"RPOW_LT2",RPOW_LT2; +"RPOW_MONO",RPOW_MONO; +"RPOW_MONO_INV",RPOW_MONO_INV; +"RPOW_MUL",RPOW_MUL; +"RPOW_NEG",RPOW_NEG; +"RPOW_ONE",RPOW_ONE; +"RPOW_POS_LE",RPOW_POS_LE; +"RPOW_POS_LT",RPOW_POS_LT; +"RPOW_POW",RPOW_POW; +"RPOW_RPOW",RPOW_RPOW; +"RPOW_SQRT",RPOW_SQRT; +"RPOW_ZERO",RPOW_ZERO; +"RSUM_BOUND",RSUM_BOUND; +"RSUM_COMPONENT_LE",RSUM_COMPONENT_LE; +"RSUM_DIFF_BOUND",RSUM_DIFF_BOUND; +"SAME_DISTANCES_TO_AFFINE_HULL",SAME_DISTANCES_TO_AFFINE_HULL; +"SCALING_LINEAR",SCALING_LINEAR; +"SCHAUDER",SCHAUDER; +"SCHAUDER_PROJECTION",SCHAUDER_PROJECTION; +"SCHAUDER_UNIV",SCHAUDER_UNIV; +"SCHOTTKY",SCHOTTKY; +"SCHWARZ_LEMMA",SCHWARZ_LEMMA; +"SCHWARZ_REFLECTION",SCHWARZ_REFLECTION; +"SECOND_CARTAN_THM_DIM_1",SECOND_CARTAN_THM_DIM_1; +"SECOND_MEAN_VALUE_THEOREM",SECOND_MEAN_VALUE_THEOREM; +"SECOND_MEAN_VALUE_THEOREM_BONNET",SECOND_MEAN_VALUE_THEOREM_BONNET; +"SECOND_MEAN_VALUE_THEOREM_BONNET_FULL",SECOND_MEAN_VALUE_THEOREM_BONNET_FULL; +"SECOND_MEAN_VALUE_THEOREM_FULL",SECOND_MEAN_VALUE_THEOREM_FULL; +"SECOND_MEAN_VALUE_THEOREM_GEN",SECOND_MEAN_VALUE_THEOREM_GEN; +"SECOND_MEAN_VALUE_THEOREM_GEN_FULL",SECOND_MEAN_VALUE_THEOREM_GEN_FULL; +"SEGMENTS_SUBSET_CONVEX_HULL",SEGMENTS_SUBSET_CONVEX_HULL; +"SEGMENT_1",SEGMENT_1; +"SEGMENT_AS_BALL",SEGMENT_AS_BALL; +"SEGMENT_BOUND",SEGMENT_BOUND; +"SEGMENT_CLOSED_OPEN",SEGMENT_CLOSED_OPEN; +"SEGMENT_CONVEX_HULL",SEGMENT_CONVEX_HULL; +"SEGMENT_EDGE_OF",SEGMENT_EDGE_OF; +"SEGMENT_EQ",SEGMENT_EQ; +"SEGMENT_EQ_EMPTY",SEGMENT_EQ_EMPTY; +"SEGMENT_EQ_SING",SEGMENT_EQ_SING; +"SEGMENT_FACE_OF",SEGMENT_FACE_OF; +"SEGMENT_FURTHEST_LE",SEGMENT_FURTHEST_LE; +"SEGMENT_HORIZONTAL",SEGMENT_HORIZONTAL; +"SEGMENT_IMAGE_INTERVAL",SEGMENT_IMAGE_INTERVAL; +"SEGMENT_OPEN_SUBSET_CLOSED",SEGMENT_OPEN_SUBSET_CLOSED; +"SEGMENT_REAL_SEGMENT",SEGMENT_REAL_SEGMENT; +"SEGMENT_REFL",SEGMENT_REFL; +"SEGMENT_SCALAR_MULTIPLE",SEGMENT_SCALAR_MULTIPLE; +"SEGMENT_SYM",SEGMENT_SYM; +"SEGMENT_TO_CLOSEST_POINT",SEGMENT_TO_CLOSEST_POINT; +"SEGMENT_TO_POINT_EXISTS",SEGMENT_TO_POINT_EXISTS; +"SEGMENT_TRANSLATION",SEGMENT_TRANSLATION; +"SEGMENT_VERTICAL",SEGMENT_VERTICAL; +"SELECT_AX",SELECT_AX; +"SELECT_REFL",SELECT_REFL; +"SELECT_UNIQUE",SELECT_UNIQUE; +"SELF_ADJOINT_COMPOSE",SELF_ADJOINT_COMPOSE; +"SELF_ADJOINT_HAS_EIGENVECTOR",SELF_ADJOINT_HAS_EIGENVECTOR; +"SELF_ADJOINT_HAS_EIGENVECTOR_BASIS",SELF_ADJOINT_HAS_EIGENVECTOR_BASIS; +"SELF_ADJOINT_HAS_EIGENVECTOR_BASIS_OF_SUBSPACE",SELF_ADJOINT_HAS_EIGENVECTOR_BASIS_OF_SUBSPACE; +"SELF_ADJOINT_HAS_EIGENVECTOR_IN_SUBSPACE",SELF_ADJOINT_HAS_EIGENVECTOR_IN_SUBSPACE; +"SELF_ADJOINT_ORTHOGONAL_EIGENVECTORS",SELF_ADJOINT_ORTHOGONAL_EIGENVECTORS; +"SEPARABLE",SEPARABLE; +"SEPARATE_CLOSED_COMPACT",SEPARATE_CLOSED_COMPACT; +"SEPARATE_CLOSED_CONES",SEPARATE_CLOSED_CONES; +"SEPARATE_COMPACT_CLOSED",SEPARATE_COMPACT_CLOSED; +"SEPARATE_POINT_CLOSED",SEPARATE_POINT_CLOSED; +"SEPARATING_HYPERPLANE_CLOSED_0",SEPARATING_HYPERPLANE_CLOSED_0; +"SEPARATING_HYPERPLANE_CLOSED_0_INSET",SEPARATING_HYPERPLANE_CLOSED_0_INSET; +"SEPARATING_HYPERPLANE_CLOSED_COMPACT",SEPARATING_HYPERPLANE_CLOSED_COMPACT; +"SEPARATING_HYPERPLANE_CLOSED_POINT",SEPARATING_HYPERPLANE_CLOSED_POINT; +"SEPARATING_HYPERPLANE_CLOSED_POINT_INSET",SEPARATING_HYPERPLANE_CLOSED_POINT_INSET; +"SEPARATING_HYPERPLANE_COMPACT_CLOSED",SEPARATING_HYPERPLANE_COMPACT_CLOSED; +"SEPARATING_HYPERPLANE_COMPACT_CLOSED_NONZERO",SEPARATING_HYPERPLANE_COMPACT_CLOSED_NONZERO; +"SEPARATING_HYPERPLANE_COMPACT_COMPACT",SEPARATING_HYPERPLANE_COMPACT_COMPACT; +"SEPARATING_HYPERPLANE_POLYHEDRA",SEPARATING_HYPERPLANE_POLYHEDRA; +"SEPARATING_HYPERPLANE_RELATIVE_INTERIORS",SEPARATING_HYPERPLANE_RELATIVE_INTERIORS; +"SEPARATING_HYPERPLANE_SETS",SEPARATING_HYPERPLANE_SETS; +"SEPARATING_HYPERPLANE_SET_0",SEPARATING_HYPERPLANE_SET_0; +"SEPARATING_HYPERPLANE_SET_0_INSPAN",SEPARATING_HYPERPLANE_SET_0_INSPAN; +"SEPARATING_HYPERPLANE_SET_POINT_INAFF",SEPARATING_HYPERPLANE_SET_POINT_INAFF; +"SEPARATION_CLOSURES",SEPARATION_CLOSURES; +"SEPARATION_HAUSDORFF",SEPARATION_HAUSDORFF; +"SEPARATION_NORMAL",SEPARATION_NORMAL; +"SEPARATION_NORMAL_COMPACT",SEPARATION_NORMAL_COMPACT; +"SEPARATION_T0",SEPARATION_T0; +"SEPARATION_T1",SEPARATION_T1; +"SEPARATION_T2",SEPARATION_T2; +"SEQITERATE_CLAUSES",SEQITERATE_CLAUSES; +"SEQITERATE_ITERATE",SEQITERATE_ITERATE; +"SEQUENCE_CAUCHY_WLOG",SEQUENCE_CAUCHY_WLOG; +"SEQUENCE_INFINITE_LEMMA",SEQUENCE_INFINITE_LEMMA; +"SEQUENCE_UNIQUE_LIMPT",SEQUENCE_UNIQUE_LIMPT; +"SEQUENTIALLY",SEQUENTIALLY; +"SEQ_HARMONIC",SEQ_HARMONIC; +"SEQ_MONO_LEMMA",SEQ_MONO_LEMMA; +"SEQ_OFFSET",SEQ_OFFSET; +"SEQ_OFFSET_NEG",SEQ_OFFSET_NEG; +"SEQ_OFFSET_REV",SEQ_OFFSET_REV; +"SERIES_0",SERIES_0; +"SERIES_ABSCONV_IMP_CONV",SERIES_ABSCONV_IMP_CONV; +"SERIES_ADD",SERIES_ADD; +"SERIES_AND_DERIVATIVE_COMPARISON",SERIES_AND_DERIVATIVE_COMPARISON; +"SERIES_AND_DERIVATIVE_COMPARISON_COMPLEX",SERIES_AND_DERIVATIVE_COMPARISON_COMPLEX; +"SERIES_AND_DERIVATIVE_COMPARISON_LOCAL",SERIES_AND_DERIVATIVE_COMPARISON_LOCAL; +"SERIES_CAUCHY",SERIES_CAUCHY; +"SERIES_CAUCHY_UNIFORM",SERIES_CAUCHY_UNIFORM; +"SERIES_CMUL",SERIES_CMUL; +"SERIES_COMPARISON",SERIES_COMPARISON; +"SERIES_COMPARISON_COMPLEX",SERIES_COMPARISON_COMPLEX; +"SERIES_COMPARISON_UNIFORM",SERIES_COMPARISON_UNIFORM; +"SERIES_COMPARISON_UNIFORM_COMPLEX",SERIES_COMPARISON_UNIFORM_COMPLEX; +"SERIES_COMPLEX_DIV",SERIES_COMPLEX_DIV; +"SERIES_COMPLEX_LMUL",SERIES_COMPLEX_LMUL; +"SERIES_COMPLEX_RMUL",SERIES_COMPLEX_RMUL; +"SERIES_COMPONENT",SERIES_COMPONENT; +"SERIES_DIFFERENTIABLE_COMPARISON_COMPLEX",SERIES_DIFFERENTIABLE_COMPARISON_COMPLEX; +"SERIES_DIFFS",SERIES_DIFFS; +"SERIES_DIRICHLET",SERIES_DIRICHLET; +"SERIES_DIRICHLET_BILINEAR",SERIES_DIRICHLET_BILINEAR; +"SERIES_DIRICHLET_COMPLEX",SERIES_DIRICHLET_COMPLEX; +"SERIES_DIRICHLET_COMPLEX_EXPLICIT",SERIES_DIRICHLET_COMPLEX_EXPLICIT; +"SERIES_DIRICHLET_COMPLEX_GEN",SERIES_DIRICHLET_COMPLEX_GEN; +"SERIES_DIRICHLET_COMPLEX_VERY_EXPLICIT",SERIES_DIRICHLET_COMPLEX_VERY_EXPLICIT; +"SERIES_FINITE",SERIES_FINITE; +"SERIES_FINITE_SUPPORT",SERIES_FINITE_SUPPORT; +"SERIES_FROM",SERIES_FROM; +"SERIES_GOESTOZERO",SERIES_GOESTOZERO; +"SERIES_INJECTIVE_IMAGE",SERIES_INJECTIVE_IMAGE; +"SERIES_INJECTIVE_IMAGE_STRONG",SERIES_INJECTIVE_IMAGE_STRONG; +"SERIES_LIFT_ABSCONV_IMP_CONV",SERIES_LIFT_ABSCONV_IMP_CONV; +"SERIES_LINEAR",SERIES_LINEAR; +"SERIES_NEG",SERIES_NEG; +"SERIES_RATIO",SERIES_RATIO; +"SERIES_REARRANGE",SERIES_REARRANGE; +"SERIES_REARRANGE_EQ",SERIES_REARRANGE_EQ; +"SERIES_RESTRICT",SERIES_RESTRICT; +"SERIES_SUB",SERIES_SUB; +"SERIES_SUBSET",SERIES_SUBSET; +"SERIES_TRIVIAL",SERIES_TRIVIAL; +"SERIES_UNIQUE",SERIES_UNIQUE; +"SERIES_VSUM",SERIES_VSUM; +"SETCODE_BOUNDS",SETCODE_BOUNDS; +"SETDIST_CLOSED_COMPACT",SETDIST_CLOSED_COMPACT; +"SETDIST_CLOSEST_POINT",SETDIST_CLOSEST_POINT; +"SETDIST_CLOSURE",SETDIST_CLOSURE; +"SETDIST_COMPACT_CLOSED",SETDIST_COMPACT_CLOSED; +"SETDIST_DIFFERENCES",SETDIST_DIFFERENCES; +"SETDIST_EMPTY",SETDIST_EMPTY; +"SETDIST_EQ_0_BOUNDED",SETDIST_EQ_0_BOUNDED; +"SETDIST_EQ_0_CLOSED_COMPACT",SETDIST_EQ_0_CLOSED_COMPACT; +"SETDIST_EQ_0_COMPACT_CLOSED",SETDIST_EQ_0_COMPACT_CLOSED; +"SETDIST_EQ_0_SING",SETDIST_EQ_0_SING; +"SETDIST_LE_DIST",SETDIST_LE_DIST; +"SETDIST_LINEAR_IMAGE",SETDIST_LINEAR_IMAGE; +"SETDIST_LIPSCHITZ",SETDIST_LIPSCHITZ; +"SETDIST_POS_LE",SETDIST_POS_LE; +"SETDIST_REFL",SETDIST_REFL; +"SETDIST_SINGS",SETDIST_SINGS; +"SETDIST_SUBSET_LEFT",SETDIST_SUBSET_LEFT; +"SETDIST_SUBSET_RIGHT",SETDIST_SUBSET_RIGHT; +"SETDIST_SYM",SETDIST_SYM; +"SETDIST_TRANSLATION",SETDIST_TRANSLATION; +"SETDIST_TRIANGLE",SETDIST_TRIANGLE; +"SETDIST_UNIQUE",SETDIST_UNIQUE; +"SETSPEC",SETSPEC; +"SETVARIATION_EQUAL_LEMMA",SETVARIATION_EQUAL_LEMMA; +"SET_CASES",SET_CASES; +"SET_OF_LIST_APPEND",SET_OF_LIST_APPEND; +"SET_OF_LIST_EQ_EMPTY",SET_OF_LIST_EQ_EMPTY; +"SET_OF_LIST_MAP",SET_OF_LIST_MAP; +"SET_OF_LIST_OF_SET",SET_OF_LIST_OF_SET; +"SET_PAIR_THM",SET_PAIR_THM; +"SET_PROVE_CASES",SET_PROVE_CASES; +"SET_RECURSION_LEMMA",SET_RECURSION_LEMMA; +"SET_VARIATION",SET_VARIATION; +"SET_VARIATION_0",SET_VARIATION_0; +"SET_VARIATION_ELEMENTARY_LEMMA",SET_VARIATION_ELEMENTARY_LEMMA; +"SET_VARIATION_EQ",SET_VARIATION_EQ; +"SET_VARIATION_GE_FUNCTION",SET_VARIATION_GE_FUNCTION; +"SET_VARIATION_LBOUND",SET_VARIATION_LBOUND; +"SET_VARIATION_LBOUND_ON_INTERVAL",SET_VARIATION_LBOUND_ON_INTERVAL; +"SET_VARIATION_MONOTONE",SET_VARIATION_MONOTONE; +"SET_VARIATION_ON_DIVISION",SET_VARIATION_ON_DIVISION; +"SET_VARIATION_ON_ELEMENTARY",SET_VARIATION_ON_ELEMENTARY; +"SET_VARIATION_ON_INTERVAL",SET_VARIATION_ON_INTERVAL; +"SET_VARIATION_ON_NULL",SET_VARIATION_ON_NULL; +"SET_VARIATION_POS_LE",SET_VARIATION_POS_LE; +"SET_VARIATION_REFLECT2",SET_VARIATION_REFLECT2; +"SET_VARIATION_TRANSLATION2",SET_VARIATION_TRANSLATION2; +"SET_VARIATION_TRIANGLE",SET_VARIATION_TRIANGLE; +"SET_VARIATION_UBOUND",SET_VARIATION_UBOUND; +"SET_VARIATION_UBOUND_ON_INTERVAL",SET_VARIATION_UBOUND_ON_INTERVAL; +"SET_VARIATION_WORKS_ON_INTERVAL",SET_VARIATION_WORKS_ON_INTERVAL; +"SHIFTPATH_LINEAR_IMAGE",SHIFTPATH_LINEAR_IMAGE; +"SHIFTPATH_SHIFTPATH",SHIFTPATH_SHIFTPATH; +"SHIFTPATH_TRANSLATION",SHIFTPATH_TRANSLATION; +"SHIFTPATH_TRIVIAL",SHIFTPATH_TRIVIAL; +"SIGMA_COMPACT",SIGMA_COMPACT; +"SIGN_COMPOSE",SIGN_COMPOSE; +"SIGN_I",SIGN_I; +"SIGN_IDEMPOTENT",SIGN_IDEMPOTENT; +"SIGN_INVERSE",SIGN_INVERSE; +"SIGN_NZ",SIGN_NZ; +"SIGN_SWAP",SIGN_SWAP; +"SIMPLEX",SIMPLEX; +"SIMPLEX_DIM_GE",SIMPLEX_DIM_GE; +"SIMPLEX_EMPTY",SIMPLEX_EMPTY; +"SIMPLEX_EXPLICIT",SIMPLEX_EXPLICIT; +"SIMPLEX_EXTREMAL_LE",SIMPLEX_EXTREMAL_LE; +"SIMPLEX_EXTREMAL_LE_EXISTS",SIMPLEX_EXTREMAL_LE_EXISTS; +"SIMPLEX_EXTREME_POINTS",SIMPLEX_EXTREME_POINTS; +"SIMPLEX_FACE_OF_SIMPLEX",SIMPLEX_FACE_OF_SIMPLEX; +"SIMPLEX_FURTHEST_LE",SIMPLEX_FURTHEST_LE; +"SIMPLEX_FURTHEST_LE_EXISTS",SIMPLEX_FURTHEST_LE_EXISTS; +"SIMPLEX_FURTHEST_LT",SIMPLEX_FURTHEST_LT; +"SIMPLEX_IMP_POLYTOPE",SIMPLEX_IMP_POLYTOPE; +"SIMPLEX_MINUS_1",SIMPLEX_MINUS_1; +"SIMPLEX_TOP_FACE",SIMPLEX_TOP_FACE; +"SIMPLE_CLOSED_PATH_ABS_WINDING_NUMBER_INSIDE",SIMPLE_CLOSED_PATH_ABS_WINDING_NUMBER_INSIDE; +"SIMPLE_CLOSED_PATH_NORM_WINDING_NUMBER_INSIDE",SIMPLE_CLOSED_PATH_NORM_WINDING_NUMBER_INSIDE; +"SIMPLE_CLOSED_PATH_WINDING_NUMBER_CASES",SIMPLE_CLOSED_PATH_WINDING_NUMBER_CASES; +"SIMPLE_CLOSED_PATH_WINDING_NUMBER_INSIDE",SIMPLE_CLOSED_PATH_WINDING_NUMBER_INSIDE; +"SIMPLE_CLOSED_PATH_WINDING_NUMBER_POS",SIMPLE_CLOSED_PATH_WINDING_NUMBER_POS; +"SIMPLE_IMAGE",SIMPLE_IMAGE; +"SIMPLE_IMAGE_GEN",SIMPLE_IMAGE_GEN; +"SIMPLE_PATH_ASSOC",SIMPLE_PATH_ASSOC; +"SIMPLE_PATH_CASES",SIMPLE_PATH_CASES; +"SIMPLE_PATH_CIRCLEPATH",SIMPLE_PATH_CIRCLEPATH; +"SIMPLE_PATH_ENDLESS",SIMPLE_PATH_ENDLESS; +"SIMPLE_PATH_EQ_ARC",SIMPLE_PATH_EQ_ARC; +"SIMPLE_PATH_IMP_ARC",SIMPLE_PATH_IMP_ARC; +"SIMPLE_PATH_IMP_PATH",SIMPLE_PATH_IMP_PATH; +"SIMPLE_PATH_JOIN_IMP",SIMPLE_PATH_JOIN_IMP; +"SIMPLE_PATH_JOIN_LOOP",SIMPLE_PATH_JOIN_LOOP; +"SIMPLE_PATH_JOIN_LOOP_EQ",SIMPLE_PATH_JOIN_LOOP_EQ; +"SIMPLE_PATH_LINEAR_IMAGE_EQ",SIMPLE_PATH_LINEAR_IMAGE_EQ; +"SIMPLE_PATH_LINEPATH",SIMPLE_PATH_LINEPATH; +"SIMPLE_PATH_LINEPATH_EQ",SIMPLE_PATH_LINEPATH_EQ; +"SIMPLE_PATH_PARTCIRCLEPATH",SIMPLE_PATH_PARTCIRCLEPATH; +"SIMPLE_PATH_REVERSEPATH",SIMPLE_PATH_REVERSEPATH; +"SIMPLE_PATH_SHIFTPATH",SIMPLE_PATH_SHIFTPATH; +"SIMPLE_PATH_SUBPATH",SIMPLE_PATH_SUBPATH; +"SIMPLE_PATH_SUBPATH_EQ",SIMPLE_PATH_SUBPATH_EQ; +"SIMPLE_PATH_SYM",SIMPLE_PATH_SYM; +"SIMPLE_PATH_TRANSLATION_EQ",SIMPLE_PATH_TRANSLATION_EQ; +"SIMPLICIAL_COMPLEX_IMP_TRIANGULATION",SIMPLICIAL_COMPLEX_IMP_TRIANGULATION; +"SIMPLY_CONNECTED_EMPTY",SIMPLY_CONNECTED_EMPTY; +"SIMPLY_CONNECTED_EQ_BIHOLOMORPHIC_TO_DISC",SIMPLY_CONNECTED_EQ_BIHOLOMORPHIC_TO_DISC; +"SIMPLY_CONNECTED_EQ_CONTINUOUS_LOG",SIMPLY_CONNECTED_EQ_CONTINUOUS_LOG; +"SIMPLY_CONNECTED_EQ_CONTINUOUS_SQRT",SIMPLY_CONNECTED_EQ_CONTINUOUS_SQRT; +"SIMPLY_CONNECTED_EQ_CONTRACTIBLE_CIRCLEMAP",SIMPLY_CONNECTED_EQ_CONTRACTIBLE_CIRCLEMAP; +"SIMPLY_CONNECTED_EQ_CONTRACTIBLE_LOOP_ALL",SIMPLY_CONNECTED_EQ_CONTRACTIBLE_LOOP_ALL; +"SIMPLY_CONNECTED_EQ_CONTRACTIBLE_LOOP_ANY",SIMPLY_CONNECTED_EQ_CONTRACTIBLE_LOOP_ANY; +"SIMPLY_CONNECTED_EQ_CONTRACTIBLE_LOOP_SOME",SIMPLY_CONNECTED_EQ_CONTRACTIBLE_LOOP_SOME; +"SIMPLY_CONNECTED_EQ_CONTRACTIBLE_PATH",SIMPLY_CONNECTED_EQ_CONTRACTIBLE_PATH; +"SIMPLY_CONNECTED_EQ_EMPTY_INSIDE",SIMPLY_CONNECTED_EQ_EMPTY_INSIDE; +"SIMPLY_CONNECTED_EQ_FRONTIER_PROPERTIES",SIMPLY_CONNECTED_EQ_FRONTIER_PROPERTIES; +"SIMPLY_CONNECTED_EQ_GLOBAL_PRIMITIVE",SIMPLY_CONNECTED_EQ_GLOBAL_PRIMITIVE; +"SIMPLY_CONNECTED_EQ_HOLOMORPHIC_LOG",SIMPLY_CONNECTED_EQ_HOLOMORPHIC_LOG; +"SIMPLY_CONNECTED_EQ_HOLOMORPHIC_SQRT",SIMPLY_CONNECTED_EQ_HOLOMORPHIC_SQRT; +"SIMPLY_CONNECTED_EQ_HOMEOMORPHIC_TO_DISC",SIMPLY_CONNECTED_EQ_HOMEOMORPHIC_TO_DISC; +"SIMPLY_CONNECTED_EQ_HOMOTOPIC_CIRCLEMAPS",SIMPLY_CONNECTED_EQ_HOMOTOPIC_CIRCLEMAPS; +"SIMPLY_CONNECTED_EQ_HOMOTOPIC_PATHS",SIMPLY_CONNECTED_EQ_HOMOTOPIC_PATHS; +"SIMPLY_CONNECTED_EQ_INJECTIVE_HOLOMORPHIC_SQRT",SIMPLY_CONNECTED_EQ_INJECTIVE_HOLOMORPHIC_SQRT; +"SIMPLY_CONNECTED_EQ_PATH_INTEGRAL_ZERO",SIMPLY_CONNECTED_EQ_PATH_INTEGRAL_ZERO; +"SIMPLY_CONNECTED_EQ_UNBOUNDED_COMPLEMENT_COMPONENTS",SIMPLY_CONNECTED_EQ_UNBOUNDED_COMPLEMENT_COMPONENTS; +"SIMPLY_CONNECTED_EQ_WINDING_NUMBER_ZERO",SIMPLY_CONNECTED_EQ_WINDING_NUMBER_ZERO; +"SIMPLY_CONNECTED_IMP_CONNECTED",SIMPLY_CONNECTED_IMP_CONNECTED; +"SIMPLY_CONNECTED_IMP_HOLOMORPHIC_LOG",SIMPLY_CONNECTED_IMP_HOLOMORPHIC_LOG; +"SIMPLY_CONNECTED_IMP_HOLOMORPHIC_SQRT",SIMPLY_CONNECTED_IMP_HOLOMORPHIC_SQRT; +"SIMPLY_CONNECTED_IMP_PATH_CONNECTED",SIMPLY_CONNECTED_IMP_PATH_CONNECTED; +"SIMPLY_CONNECTED_IMP_WINDING_NUMBER_ZERO",SIMPLY_CONNECTED_IMP_WINDING_NUMBER_ZERO; +"SIMPLY_CONNECTED_INJECTIVE_LINEAR_IMAGE",SIMPLY_CONNECTED_INJECTIVE_LINEAR_IMAGE; +"SIMPLY_CONNECTED_INSIDE_SIMPLE_PATH",SIMPLY_CONNECTED_INSIDE_SIMPLE_PATH; +"SIMPLY_CONNECTED_INTER",SIMPLY_CONNECTED_INTER; +"SIMPLY_CONNECTED_PCROSS",SIMPLY_CONNECTED_PCROSS; +"SIMPLY_CONNECTED_PCROSS_EQ",SIMPLY_CONNECTED_PCROSS_EQ; +"SIMPLY_CONNECTED_RETRACTION_GEN",SIMPLY_CONNECTED_RETRACTION_GEN; +"SIMPLY_CONNECTED_SPHERE",SIMPLY_CONNECTED_SPHERE; +"SIMPLY_CONNECTED_SPHERE_EQ",SIMPLY_CONNECTED_SPHERE_EQ; +"SIMPLY_CONNECTED_TRANSLATION",SIMPLY_CONNECTED_TRANSLATION; +"SIMPLY_CONNECTED_UNION",SIMPLY_CONNECTED_UNION; +"SINCOS_PRINCIPAL_VALUE",SINCOS_PRINCIPAL_VALUE; +"SINCOS_TOTAL_2PI",SINCOS_TOTAL_2PI; +"SINCOS_TOTAL_PI",SINCOS_TOTAL_PI; +"SINCOS_TOTAL_PI2",SINCOS_TOTAL_PI2; +"SING",SING; +"SING_GSPEC",SING_GSPEC; +"SING_SUBSET",SING_SUBSET; +"SIN_0",SIN_0; +"SIN_ACS",SIN_ACS; +"SIN_ACS_NZ",SIN_ACS_NZ; +"SIN_ADD",SIN_ADD; +"SIN_ASN",SIN_ASN; +"SIN_ATN",SIN_ATN; +"SIN_BOUND",SIN_BOUND; +"SIN_BOUNDS",SIN_BOUNDS; +"SIN_CIRCLE",SIN_CIRCLE; +"SIN_COS",SIN_COS; +"SIN_COS_EQ",SIN_COS_EQ; +"SIN_COS_INJ",SIN_COS_INJ; +"SIN_COS_SQRT",SIN_COS_SQRT; +"SIN_DOUBLE",SIN_DOUBLE; +"SIN_EQ",SIN_EQ; +"SIN_EQ_0",SIN_EQ_0; +"SIN_EQ_0_PI",SIN_EQ_0_PI; +"SIN_EQ_1",SIN_EQ_1; +"SIN_EQ_MINUS1",SIN_EQ_MINUS1; +"SIN_HASZERO",SIN_HASZERO; +"SIN_HASZERO_MINIMAL",SIN_HASZERO_MINIMAL; +"SIN_INJ_PI",SIN_INJ_PI; +"SIN_INTEGER_2PI",SIN_INTEGER_2PI; +"SIN_INTEGER_PI",SIN_INTEGER_PI; +"SIN_MONO_LE",SIN_MONO_LE; +"SIN_MONO_LE_EQ",SIN_MONO_LE_EQ; +"SIN_MONO_LT",SIN_MONO_LT; +"SIN_MONO_LT_EQ",SIN_MONO_LT_EQ; +"SIN_NEARZERO",SIN_NEARZERO; +"SIN_NEG",SIN_NEG; +"SIN_NONTRIVIAL",SIN_NONTRIVIAL; +"SIN_NPI",SIN_NPI; +"SIN_PERIODIC",SIN_PERIODIC; +"SIN_PERIODIC_PI",SIN_PERIODIC_PI; +"SIN_PI",SIN_PI; +"SIN_PI2",SIN_PI2; +"SIN_PI6",SIN_PI6; +"SIN_PI6_STRADDLE",SIN_PI6_STRADDLE; +"SIN_PIMUL_EQ_0",SIN_PIMUL_EQ_0; +"SIN_POS_PI",SIN_POS_PI; +"SIN_POS_PI2",SIN_POS_PI2; +"SIN_POS_PI_LE",SIN_POS_PI_LE; +"SIN_POS_PI_REV",SIN_POS_PI_REV; +"SIN_SUB",SIN_SUB; +"SIN_TAN",SIN_TAN; +"SIN_TOTAL_POS",SIN_TOTAL_POS; +"SIN_ZERO",SIN_ZERO; +"SIN_ZERO_PI",SIN_ZERO_PI; +"SKOLEM_THM",SKOLEM_THM; +"SLICE_BALL",SLICE_BALL; +"SLICE_CBALL",SLICE_CBALL; +"SLICE_DIFF",SLICE_DIFF; +"SLICE_EMPTY",SLICE_EMPTY; +"SLICE_INTER",SLICE_INTER; +"SLICE_INTERVAL",SLICE_INTERVAL; +"SLICE_SUBSET",SLICE_SUBSET; +"SLICE_UNION",SLICE_UNION; +"SLICE_UNIONS",SLICE_UNIONS; +"SLICE_UNIV",SLICE_UNIV; +"SND",SND; +"SNDCART_ADD",SNDCART_ADD; +"SNDCART_CMUL",SNDCART_CMUL; +"SNDCART_NEG",SNDCART_NEG; +"SNDCART_PASTECART",SNDCART_PASTECART; +"SNDCART_SUB",SNDCART_SUB; +"SNDCART_VEC",SNDCART_VEC; +"SNDCART_VSUM",SNDCART_VSUM; +"SND_DEF",SND_DEF; +"SPANNING_SUBSET_INDEPENDENT",SPANNING_SUBSET_INDEPENDENT; +"SPANNING_SURJECTIVE_IMAGE",SPANNING_SURJECTIVE_IMAGE; +"SPANS_IMAGE",SPANS_IMAGE; +"SPAN_0",SPAN_0; +"SPAN_2",SPAN_2; +"SPAN_3",SPAN_3; +"SPAN_ADD",SPAN_ADD; +"SPAN_ADD_EQ",SPAN_ADD_EQ; +"SPAN_BREAKDOWN",SPAN_BREAKDOWN; +"SPAN_BREAKDOWN_EQ",SPAN_BREAKDOWN_EQ; +"SPAN_CARD_GE_DIM",SPAN_CARD_GE_DIM; +"SPAN_CLAUSES",SPAN_CLAUSES; +"SPAN_CONVEX_CONE_ALLSIGNS",SPAN_CONVEX_CONE_ALLSIGNS; +"SPAN_DELETE_0",SPAN_DELETE_0; +"SPAN_EMPTY",SPAN_EMPTY; +"SPAN_EQ",SPAN_EQ; +"SPAN_EQ_DIM",SPAN_EQ_DIM; +"SPAN_EQ_INSERT",SPAN_EQ_INSERT; +"SPAN_EQ_SELF",SPAN_EQ_SELF; +"SPAN_EXPLICIT",SPAN_EXPLICIT; +"SPAN_FINITE",SPAN_FINITE; +"SPAN_IMAGE_SCALE",SPAN_IMAGE_SCALE; +"SPAN_INC",SPAN_INC; +"SPAN_INDUCT",SPAN_INDUCT; +"SPAN_INDUCT_ALT",SPAN_INDUCT_ALT; +"SPAN_INSERT_0",SPAN_INSERT_0; +"SPAN_LINEAR_IMAGE",SPAN_LINEAR_IMAGE; +"SPAN_MBASIS",SPAN_MBASIS; +"SPAN_MONO",SPAN_MONO; +"SPAN_MUL",SPAN_MUL; +"SPAN_MUL_EQ",SPAN_MUL_EQ; +"SPAN_NEG",SPAN_NEG; +"SPAN_NEG_EQ",SPAN_NEG_EQ; +"SPAN_NOT_UNIV_ORTHOGONAL",SPAN_NOT_UNIV_ORTHOGONAL; +"SPAN_NOT_UNIV_SUBSET_HYPERPLANE",SPAN_NOT_UNIV_SUBSET_HYPERPLANE; +"SPAN_OF_SUBSPACE",SPAN_OF_SUBSPACE; +"SPAN_OPEN",SPAN_OPEN; +"SPAN_PCROSS",SPAN_PCROSS; +"SPAN_PCROSS_SUBSET",SPAN_PCROSS_SUBSET; +"SPAN_SING",SPAN_SING; +"SPAN_SPAN",SPAN_SPAN; +"SPAN_STDBASIS",SPAN_STDBASIS; +"SPAN_SUB",SPAN_SUB; +"SPAN_SUBSET_SUBSPACE",SPAN_SUBSET_SUBSPACE; +"SPAN_SUBSPACE",SPAN_SUBSPACE; +"SPAN_SUMS",SPAN_SUMS; +"SPAN_SUPERSET",SPAN_SUPERSET; +"SPAN_TRANS",SPAN_TRANS; +"SPAN_UNION",SPAN_UNION; +"SPAN_UNION_SUBSET",SPAN_UNION_SUBSET; +"SPAN_UNIV",SPAN_UNIV; +"SPAN_VSUM",SPAN_VSUM; +"SPECIAL_HYPERPLANE_SPAN",SPECIAL_HYPERPLANE_SPAN; +"SPHERE_1",SPHERE_1; +"SPHERE_EMPTY",SPHERE_EMPTY; +"SPHERE_EQ_EMPTY",SPHERE_EQ_EMPTY; +"SPHERE_EQ_SING",SPHERE_EQ_SING; +"SPHERE_LINEAR_IMAGE",SPHERE_LINEAR_IMAGE; +"SPHERE_RETRACT_OF_PUNCTURED_UNIVERSE",SPHERE_RETRACT_OF_PUNCTURED_UNIVERSE; +"SPHERE_RETRACT_OF_PUNCTURED_UNIVERSE_GEN",SPHERE_RETRACT_OF_PUNCTURED_UNIVERSE_GEN; +"SPHERE_SING",SPHERE_SING; +"SPHERE_SUBSET_CBALL",SPHERE_SUBSET_CBALL; +"SPHERE_TRANSLATION",SPHERE_TRANSLATION; +"SPHERE_UNION_BALL",SPHERE_UNION_BALL; +"SPLIT_INSIDE_SIMPLE_CLOSED_CURVE",SPLIT_INSIDE_SIMPLE_CLOSED_CURVE; +"SQNORM_PASTECART",SQNORM_PASTECART; +"SQRT_0",SQRT_0; +"SQRT_1",SQRT_1; +"SQRT_DIV",SQRT_DIV; +"SQRT_EQ_0",SQRT_EQ_0; +"SQRT_EVEN_POW2",SQRT_EVEN_POW2; +"SQRT_INJ",SQRT_INJ; +"SQRT_INV",SQRT_INV; +"SQRT_LT_0",SQRT_LT_0; +"SQRT_MONO_LE",SQRT_MONO_LE; +"SQRT_MONO_LE_EQ",SQRT_MONO_LE_EQ; +"SQRT_MONO_LT",SQRT_MONO_LT; +"SQRT_MONO_LT_EQ",SQRT_MONO_LT_EQ; +"SQRT_MUL",SQRT_MUL; +"SQRT_POS_LE",SQRT_POS_LE; +"SQRT_POS_LT",SQRT_POS_LT; +"SQRT_POW2",SQRT_POW2; +"SQRT_POW_2",SQRT_POW_2; +"SQRT_UNIQUE",SQRT_UNIQUE; +"SQRT_WORKS",SQRT_WORKS; +"SQUARE_BOUND_LEMMA",SQUARE_BOUND_LEMMA; +"SQUARE_CONTINUOUS",SQUARE_CONTINUOUS; +"STARLIKE_CLOSURE",STARLIKE_CLOSURE; +"STARLIKE_COMPACT_PROJECTIVE",STARLIKE_COMPACT_PROJECTIVE; +"STARLIKE_CONVEX_SUBSET",STARLIKE_CONVEX_SUBSET; +"STARLIKE_CONVEX_TWEAK_BOUNDARY_POINTS",STARLIKE_CONVEX_TWEAK_BOUNDARY_POINTS; +"STARLIKE_IMP_CONNECTED",STARLIKE_IMP_CONNECTED; +"STARLIKE_IMP_CONTRACTIBLE",STARLIKE_IMP_CONTRACTIBLE; +"STARLIKE_IMP_CONTRACTIBLE_GEN",STARLIKE_IMP_CONTRACTIBLE_GEN; +"STARLIKE_IMP_PATH_CONNECTED",STARLIKE_IMP_PATH_CONNECTED; +"STARLIKE_IMP_SIMPLY_CONNECTED",STARLIKE_IMP_SIMPLY_CONNECTED; +"STARLIKE_LINEAR_IMAGE",STARLIKE_LINEAR_IMAGE; +"STARLIKE_LINEAR_IMAGE_EQ",STARLIKE_LINEAR_IMAGE_EQ; +"STARLIKE_NEGLIGIBLE",STARLIKE_NEGLIGIBLE; +"STARLIKE_NEGLIGIBLE_BOUNDED_MEASURABLE",STARLIKE_NEGLIGIBLE_BOUNDED_MEASURABLE; +"STARLIKE_NEGLIGIBLE_LEMMA",STARLIKE_NEGLIGIBLE_LEMMA; +"STARLIKE_NEGLIGIBLE_STRONG",STARLIKE_NEGLIGIBLE_STRONG; +"STARLIKE_PCROSS",STARLIKE_PCROSS; +"STARLIKE_PCROSS_EQ",STARLIKE_PCROSS_EQ; +"STARLIKE_TRANSLATION_EQ",STARLIKE_TRANSLATION_EQ; +"STARLIKE_UNIV",STARLIKE_UNIV; +"STD_SIMPLEX",STD_SIMPLEX; +"STEINHAUS",STEINHAUS; +"STEINHAUS_LEBESGUE",STEINHAUS_LEBESGUE; +"STEINHAUS_TRIVIAL",STEINHAUS_TRIVIAL; +"STONE_WEIERSTRASS",STONE_WEIERSTRASS; +"STONE_WEIERSTRASS_ALT",STONE_WEIERSTRASS_ALT; +"STONE_WEIERSTRASS_REAL_POLYNOMIAL_FUNCTION",STONE_WEIERSTRASS_REAL_POLYNOMIAL_FUNCTION; +"STONE_WEIERSTRASS_VECTOR_POLYNOMIAL_FUNCTION",STONE_WEIERSTRASS_VECTOR_POLYNOMIAL_FUNCTION; +"STONE_WEIERSTRASS_VECTOR_POLYNOMIAL_FUNCTION_AFFINE",STONE_WEIERSTRASS_VECTOR_POLYNOMIAL_FUNCTION_AFFINE; +"STONE_WEIERSTRASS_VECTOR_POLYNOMIAL_FUNCTION_SUBSPACE",STONE_WEIERSTRASS_VECTOR_POLYNOMIAL_FUNCTION_SUBSPACE; +"STRETCH_GALOIS",STRETCH_GALOIS; +"SUB",SUB; +"SUBADDITIVE_CONTENT_DIVISION",SUBADDITIVE_CONTENT_DIVISION; +"SUBPATH_LINEAR_IMAGE",SUBPATH_LINEAR_IMAGE; +"SUBPATH_REFL",SUBPATH_REFL; +"SUBPATH_REVERSEPATH",SUBPATH_REVERSEPATH; +"SUBPATH_SCALING_LEMMA",SUBPATH_SCALING_LEMMA; +"SUBPATH_TO_FRONTIER",SUBPATH_TO_FRONTIER; +"SUBPATH_TO_FRONTIER_EXPLICIT",SUBPATH_TO_FRONTIER_EXPLICIT; +"SUBPATH_TO_FRONTIER_STRONG",SUBPATH_TO_FRONTIER_STRONG; +"SUBPATH_TRANSLATION",SUBPATH_TRANSLATION; +"SUBPATH_TRIVIAL",SUBPATH_TRIVIAL; +"SUBSEQUENCE_DIAGONALIZATION_LEMMA",SUBSEQUENCE_DIAGONALIZATION_LEMMA; +"SUBSET",SUBSET; +"SUBSET_ANTISYM",SUBSET_ANTISYM; +"SUBSET_ANTISYM_EQ",SUBSET_ANTISYM_EQ; +"SUBSET_BALL",SUBSET_BALL; +"SUBSET_BALLS",SUBSET_BALLS; +"SUBSET_CARD_EQ",SUBSET_CARD_EQ; +"SUBSET_CBALL",SUBSET_CBALL; +"SUBSET_CLOSURE",SUBSET_CLOSURE; +"SUBSET_CONTINUOUS_IMAGE_SEGMENT_1",SUBSET_CONTINUOUS_IMAGE_SEGMENT_1; +"SUBSET_DELETE",SUBSET_DELETE; +"SUBSET_DIFF",SUBSET_DIFF; +"SUBSET_DROP_IMAGE",SUBSET_DROP_IMAGE; +"SUBSET_EMPTY",SUBSET_EMPTY; +"SUBSET_FACE_OF_SIMPLEX",SUBSET_FACE_OF_SIMPLEX; +"SUBSET_HULL",SUBSET_HULL; +"SUBSET_HYPERPLANES",SUBSET_HYPERPLANES; +"SUBSET_IMAGE",SUBSET_IMAGE; +"SUBSET_INSERT",SUBSET_INSERT; +"SUBSET_INSERT_DELETE",SUBSET_INSERT_DELETE; +"SUBSET_INTER",SUBSET_INTER; +"SUBSET_INTERIOR",SUBSET_INTERIOR; +"SUBSET_INTERS",SUBSET_INTERS; +"SUBSET_INTERVAL",SUBSET_INTERVAL; +"SUBSET_INTERVAL_1",SUBSET_INTERVAL_1; +"SUBSET_INTERVAL_IMP",SUBSET_INTERVAL_IMP; +"SUBSET_INTER_ABSORPTION",SUBSET_INTER_ABSORPTION; +"SUBSET_LE_DIM",SUBSET_LE_DIM; +"SUBSET_LIFT_IMAGE",SUBSET_LIFT_IMAGE; +"SUBSET_NUMSEG",SUBSET_NUMSEG; +"SUBSET_OF_FACE_OF",SUBSET_OF_FACE_OF; +"SUBSET_PATH_IMAGE_JOIN",SUBSET_PATH_IMAGE_JOIN; +"SUBSET_PCROSS",SUBSET_PCROSS; +"SUBSET_PRED",SUBSET_PRED; +"SUBSET_PSUBSET_TRANS",SUBSET_PSUBSET_TRANS; +"SUBSET_REAL_INTERVAL",SUBSET_REAL_INTERVAL; +"SUBSET_REFL",SUBSET_REFL; +"SUBSET_RELATIVE_INTERIOR",SUBSET_RELATIVE_INTERIOR; +"SUBSET_RESTRICT",SUBSET_RESTRICT; +"SUBSET_SECOND_COUNTABLE",SUBSET_SECOND_COUNTABLE; +"SUBSET_SEGMENT",SUBSET_SEGMENT; +"SUBSET_SEGMENT_OPEN_CLOSED",SUBSET_SEGMENT_OPEN_CLOSED; +"SUBSET_TRANS",SUBSET_TRANS; +"SUBSET_UNION",SUBSET_UNION; +"SUBSET_UNIONS",SUBSET_UNIONS; +"SUBSET_UNION_ABSORPTION",SUBSET_UNION_ABSORPTION; +"SUBSET_UNIV",SUBSET_UNIV; +"SUBSPACE_0",SUBSPACE_0; +"SUBSPACE_ADD",SUBSPACE_ADD; +"SUBSPACE_BOUNDED_EQ_TRIVIAL",SUBSPACE_BOUNDED_EQ_TRIVIAL; +"SUBSPACE_CONVEX_CONE_SYMMETRIC",SUBSPACE_CONVEX_CONE_SYMMETRIC; +"SUBSPACE_HYPERPLANE",SUBSPACE_HYPERPLANE; +"SUBSPACE_IMP_AFFINE",SUBSPACE_IMP_AFFINE; +"SUBSPACE_IMP_CONIC",SUBSPACE_IMP_CONIC; +"SUBSPACE_IMP_CONVEX",SUBSPACE_IMP_CONVEX; +"SUBSPACE_IMP_CONVEX_CONE",SUBSPACE_IMP_CONVEX_CONE; +"SUBSPACE_IMP_NONEMPTY",SUBSPACE_IMP_NONEMPTY; +"SUBSPACE_INTER",SUBSPACE_INTER; +"SUBSPACE_INTERS",SUBSPACE_INTERS; +"SUBSPACE_ISOMORPHISM",SUBSPACE_ISOMORPHISM; +"SUBSPACE_KERNEL",SUBSPACE_KERNEL; +"SUBSPACE_LINEAR_FIXED_POINTS",SUBSPACE_LINEAR_FIXED_POINTS; +"SUBSPACE_LINEAR_IMAGE",SUBSPACE_LINEAR_IMAGE; +"SUBSPACE_LINEAR_IMAGE_EQ",SUBSPACE_LINEAR_IMAGE_EQ; +"SUBSPACE_LINEAR_PREIMAGE",SUBSPACE_LINEAR_PREIMAGE; +"SUBSPACE_MUL",SUBSPACE_MUL; +"SUBSPACE_NEG",SUBSPACE_NEG; +"SUBSPACE_ORTHOGONAL_TO_VECTOR",SUBSPACE_ORTHOGONAL_TO_VECTOR; +"SUBSPACE_ORTHOGONAL_TO_VECTORS",SUBSPACE_ORTHOGONAL_TO_VECTORS; +"SUBSPACE_PCROSS",SUBSPACE_PCROSS; +"SUBSPACE_PCROSS_EQ",SUBSPACE_PCROSS_EQ; +"SUBSPACE_SPAN",SUBSPACE_SPAN; +"SUBSPACE_SPECIAL_HYPERPLANE",SUBSPACE_SPECIAL_HYPERPLANE; +"SUBSPACE_SUB",SUBSPACE_SUB; +"SUBSPACE_SUBSTANDARD",SUBSPACE_SUBSTANDARD; +"SUBSPACE_SUMS",SUBSPACE_SUMS; +"SUBSPACE_TRANSLATION_SELF",SUBSPACE_TRANSLATION_SELF; +"SUBSPACE_TRANSLATION_SELF_EQ",SUBSPACE_TRANSLATION_SELF_EQ; +"SUBSPACE_TRIVIAL",SUBSPACE_TRIVIAL; +"SUBSPACE_UNION_CHAIN",SUBSPACE_UNION_CHAIN; +"SUBSPACE_UNIV",SUBSPACE_UNIV; +"SUBSPACE_VSUM",SUBSPACE_VSUM; +"SUBTOPOLOGY_SUPERSET",SUBTOPOLOGY_SUPERSET; +"SUBTOPOLOGY_TOPSPACE",SUBTOPOLOGY_TOPSPACE; +"SUBTOPOLOGY_UNIV",SUBTOPOLOGY_UNIV; +"SUB_0",SUB_0; +"SUB_ADD",SUB_ADD; +"SUB_ADD_LCANCEL",SUB_ADD_LCANCEL; +"SUB_ADD_RCANCEL",SUB_ADD_RCANCEL; +"SUB_ELIM_THM",SUB_ELIM_THM; +"SUB_ELIM_THM'",SUB_ELIM_THM'; +"SUB_EQ_0",SUB_EQ_0; +"SUB_PRESUC",SUB_PRESUC; +"SUB_REFL",SUB_REFL; +"SUB_SUC",SUB_SUC; +"SUC_DEF",SUC_DEF; +"SUC_INJ",SUC_INJ; +"SUC_SUB1",SUC_SUB1; +"SUMMABLE_0",SUMMABLE_0; +"SUMMABLE_ADD",SUMMABLE_ADD; +"SUMMABLE_BILINEAR_PARTIAL_PRE",SUMMABLE_BILINEAR_PARTIAL_PRE; +"SUMMABLE_CAUCHY",SUMMABLE_CAUCHY; +"SUMMABLE_CMUL",SUMMABLE_CMUL; +"SUMMABLE_COMPARISON",SUMMABLE_COMPARISON; +"SUMMABLE_COMPLEX_DIV",SUMMABLE_COMPLEX_DIV; +"SUMMABLE_COMPLEX_LMUL",SUMMABLE_COMPLEX_LMUL; +"SUMMABLE_COMPLEX_RMUL",SUMMABLE_COMPLEX_RMUL; +"SUMMABLE_COMPONENT",SUMMABLE_COMPONENT; +"SUMMABLE_EQ",SUMMABLE_EQ; +"SUMMABLE_EQ_COFINITE",SUMMABLE_EQ_COFINITE; +"SUMMABLE_EQ_EVENTUALLY",SUMMABLE_EQ_EVENTUALLY; +"SUMMABLE_FROM_ELSEWHERE",SUMMABLE_FROM_ELSEWHERE; +"SUMMABLE_GP",SUMMABLE_GP; +"SUMMABLE_IFF",SUMMABLE_IFF; +"SUMMABLE_IFF_COFINITE",SUMMABLE_IFF_COFINITE; +"SUMMABLE_IFF_EVENTUALLY",SUMMABLE_IFF_EVENTUALLY; +"SUMMABLE_IMP_BOUNDED",SUMMABLE_IMP_BOUNDED; +"SUMMABLE_IMP_SUMS_BOUNDED",SUMMABLE_IMP_SUMS_BOUNDED; +"SUMMABLE_IMP_TOZERO",SUMMABLE_IMP_TOZERO; +"SUMMABLE_LINEAR",SUMMABLE_LINEAR; +"SUMMABLE_NEG",SUMMABLE_NEG; +"SUMMABLE_REARRANGE",SUMMABLE_REARRANGE; +"SUMMABLE_REINDEX",SUMMABLE_REINDEX; +"SUMMABLE_RESTRICT",SUMMABLE_RESTRICT; +"SUMMABLE_SUB",SUMMABLE_SUB; +"SUMMABLE_SUBSET",SUMMABLE_SUBSET; +"SUMMABLE_SUBSET_ABSCONV",SUMMABLE_SUBSET_ABSCONV; +"SUMMABLE_SUBSET_COMPLEX",SUMMABLE_SUBSET_COMPLEX; +"SUMMABLE_TRIVIAL",SUMMABLE_TRIVIAL; +"SUMS_0",SUMS_0; +"SUMS_CNJ",SUMS_CNJ; +"SUMS_COMPLEX_0",SUMS_COMPLEX_0; +"SUMS_EQ",SUMS_EQ; +"SUMS_FINITE_DIFF",SUMS_FINITE_DIFF; +"SUMS_FINITE_UNION",SUMS_FINITE_UNION; +"SUMS_GP",SUMS_GP; +"SUMS_IFF",SUMS_IFF; +"SUMS_INFSUM",SUMS_INFSUM; +"SUMS_INTERVALS",SUMS_INTERVALS; +"SUMS_LIM",SUMS_LIM; +"SUMS_OFFSET",SUMS_OFFSET; +"SUMS_OFFSET_REV",SUMS_OFFSET_REV; +"SUMS_REINDEX",SUMS_REINDEX; +"SUMS_SUMMABLE",SUMS_SUMMABLE; +"SUM_0",SUM_0; +"SUM_1",SUM_1; +"SUM_2",SUM_2; +"SUM_3",SUM_3; +"SUM_4",SUM_4; +"SUM_ABS",SUM_ABS; +"SUM_ABS_BOUND",SUM_ABS_BOUND; +"SUM_ABS_LE",SUM_ABS_LE; +"SUM_ABS_NUMSEG",SUM_ABS_NUMSEG; +"SUM_ADD",SUM_ADD; +"SUM_ADD_GEN",SUM_ADD_GEN; +"SUM_ADD_NUMSEG",SUM_ADD_NUMSEG; +"SUM_ADD_SPLIT",SUM_ADD_SPLIT; +"SUM_BERNSTEIN",SUM_BERNSTEIN; +"SUM_BIJECTION",SUM_BIJECTION; +"SUM_BOUND",SUM_BOUND; +"SUM_BOUND_GEN",SUM_BOUND_GEN; +"SUM_BOUND_LT",SUM_BOUND_LT; +"SUM_BOUND_LT_ALL",SUM_BOUND_LT_ALL; +"SUM_BOUND_LT_GEN",SUM_BOUND_LT_GEN; +"SUM_CASES",SUM_CASES; +"SUM_CASES_1",SUM_CASES_1; +"SUM_CLAUSES",SUM_CLAUSES; +"SUM_CLAUSES_LEFT",SUM_CLAUSES_LEFT; +"SUM_CLAUSES_NUMSEG",SUM_CLAUSES_NUMSEG; +"SUM_CLAUSES_RIGHT",SUM_CLAUSES_RIGHT; +"SUM_CLOSED",SUM_CLOSED; +"SUM_COMBINE_L",SUM_COMBINE_L; +"SUM_COMBINE_R",SUM_COMBINE_R; +"SUM_CONST",SUM_CONST; +"SUM_CONST_NUMSEG",SUM_CONST_NUMSEG; +"SUM_CONTENT_AREA_OVER_THIN_DIVISION",SUM_CONTENT_AREA_OVER_THIN_DIVISION; +"SUM_DELETE",SUM_DELETE; +"SUM_DELETE_CASES",SUM_DELETE_CASES; +"SUM_DELTA",SUM_DELTA; +"SUM_DIFF",SUM_DIFF; +"SUM_DIFFS",SUM_DIFFS; +"SUM_DIFFS_ALT",SUM_DIFFS_ALT; +"SUM_EQ",SUM_EQ; +"SUM_EQ_0",SUM_EQ_0; +"SUM_EQ_0_NUMSEG",SUM_EQ_0_NUMSEG; +"SUM_EQ_GENERAL",SUM_EQ_GENERAL; +"SUM_EQ_GENERAL_INVERSES",SUM_EQ_GENERAL_INVERSES; +"SUM_EQ_NUMSEG",SUM_EQ_NUMSEG; +"SUM_EQ_SUPERSET",SUM_EQ_SUPERSET; +"SUM_GP",SUM_GP; +"SUM_GP_BASIC",SUM_GP_BASIC; +"SUM_GP_MULTIPLIED",SUM_GP_MULTIPLIED; +"SUM_GP_OFFSET",SUM_GP_OFFSET; +"SUM_GROUP",SUM_GROUP; +"SUM_IMAGE",SUM_IMAGE; +"SUM_IMAGE_GEN",SUM_IMAGE_GEN; +"SUM_IMAGE_LE",SUM_IMAGE_LE; +"SUM_IMAGE_NONZERO",SUM_IMAGE_NONZERO; +"SUM_INCL_EXCL",SUM_INCL_EXCL; +"SUM_INJECTION",SUM_INJECTION; +"SUM_INTEGRAL_BOUNDS_DECREASING",SUM_INTEGRAL_BOUNDS_DECREASING; +"SUM_INTEGRAL_BOUNDS_INCREASING",SUM_INTEGRAL_BOUNDS_INCREASING; +"SUM_INTEGRAL_LBOUND_DECREASING",SUM_INTEGRAL_LBOUND_DECREASING; +"SUM_INTEGRAL_LBOUND_INCREASING",SUM_INTEGRAL_LBOUND_INCREASING; +"SUM_INTEGRAL_UBOUND_DECREASING",SUM_INTEGRAL_UBOUND_DECREASING; +"SUM_INTEGRAL_UBOUND_INCREASING",SUM_INTEGRAL_UBOUND_INCREASING; +"SUM_LE",SUM_LE; +"SUM_LE_INCLUDED",SUM_LE_INCLUDED; +"SUM_LE_NUMSEG",SUM_LE_NUMSEG; +"SUM_LMUL",SUM_LMUL; +"SUM_LT",SUM_LT; +"SUM_LT_ALL",SUM_LT_ALL; +"SUM_MULTICOUNT",SUM_MULTICOUNT; +"SUM_MULTICOUNT_GEN",SUM_MULTICOUNT_GEN; +"SUM_NEG",SUM_NEG; +"SUM_OFFSET",SUM_OFFSET; +"SUM_OFFSET_0",SUM_OFFSET_0; +"SUM_OVER_PERMUTATIONS_INSERT",SUM_OVER_PERMUTATIONS_INSERT; +"SUM_OVER_PERMUTATIONS_NUMSEG",SUM_OVER_PERMUTATIONS_NUMSEG; +"SUM_OVER_TAGGED_DIVISION_LEMMA",SUM_OVER_TAGGED_DIVISION_LEMMA; +"SUM_OVER_TAGGED_PARTIAL_DIVISION_LEMMA",SUM_OVER_TAGGED_PARTIAL_DIVISION_LEMMA; +"SUM_PAIR",SUM_PAIR; +"SUM_PARTIAL_PRE",SUM_PARTIAL_PRE; +"SUM_PARTIAL_SUC",SUM_PARTIAL_SUC; +"SUM_PERMUTATIONS_COMPOSE_L",SUM_PERMUTATIONS_COMPOSE_L; +"SUM_PERMUTATIONS_COMPOSE_R",SUM_PERMUTATIONS_COMPOSE_R; +"SUM_PERMUTATIONS_INVERSE",SUM_PERMUTATIONS_INVERSE; +"SUM_PERMUTE",SUM_PERMUTE; +"SUM_PERMUTE_NUMSEG",SUM_PERMUTE_NUMSEG; +"SUM_POS_BOUND",SUM_POS_BOUND; +"SUM_POS_EQ_0",SUM_POS_EQ_0; +"SUM_POS_EQ_0_NUMSEG",SUM_POS_EQ_0_NUMSEG; +"SUM_POS_LE",SUM_POS_LE; +"SUM_POS_LE_NUMSEG",SUM_POS_LE_NUMSEG; +"SUM_POS_LT",SUM_POS_LT; +"SUM_RESTRICT",SUM_RESTRICT; +"SUM_RESTRICT_SET",SUM_RESTRICT_SET; +"SUM_RMUL",SUM_RMUL; +"SUM_SING",SUM_SING; +"SUM_SING_NUMSEG",SUM_SING_NUMSEG; +"SUM_SUB",SUM_SUB; +"SUM_SUBSET",SUM_SUBSET; +"SUM_SUBSET_SIMPLE",SUM_SUBSET_SIMPLE; +"SUM_SUB_NUMSEG",SUM_SUB_NUMSEG; +"SUM_SUM_PRODUCT",SUM_SUM_PRODUCT; +"SUM_SUM_RESTRICT",SUM_SUM_RESTRICT; +"SUM_SUPERSET",SUM_SUPERSET; +"SUM_SUPPORT",SUM_SUPPORT; +"SUM_SWAP",SUM_SWAP; +"SUM_SWAP_NUMSEG",SUM_SWAP_NUMSEG; +"SUM_TRIV_NUMSEG",SUM_TRIV_NUMSEG; +"SUM_UNION",SUM_UNION; +"SUM_UNIONS_NONZERO",SUM_UNIONS_NONZERO; +"SUM_UNION_EQ",SUM_UNION_EQ; +"SUM_UNION_LZERO",SUM_UNION_LZERO; +"SUM_UNION_NONZERO",SUM_UNION_NONZERO; +"SUM_UNION_RZERO",SUM_UNION_RZERO; +"SUM_VSUM",SUM_VSUM; +"SUM_ZERO_EXISTS",SUM_ZERO_EXISTS; +"SUP",SUP; +"SUPERADMISSIBLE_COND",SUPERADMISSIBLE_COND; +"SUPERADMISSIBLE_CONST",SUPERADMISSIBLE_CONST; +"SUPERADMISSIBLE_MATCH_GUARDED_PATTERN",SUPERADMISSIBLE_MATCH_GUARDED_PATTERN; +"SUPERADMISSIBLE_MATCH_SEQPATTERN",SUPERADMISSIBLE_MATCH_SEQPATTERN; +"SUPERADMISSIBLE_MATCH_UNGUARDED_PATTERN",SUPERADMISSIBLE_MATCH_UNGUARDED_PATTERN; +"SUPERADMISSIBLE_T",SUPERADMISSIBLE_T; +"SUPERADMISSIBLE_TAIL",SUPERADMISSIBLE_TAIL; +"SUPPORTING_HYPERPLANE_CLOSED_POINT",SUPPORTING_HYPERPLANE_CLOSED_POINT; +"SUPPORTING_HYPERPLANE_COMPACT_POINT_INF",SUPPORTING_HYPERPLANE_COMPACT_POINT_INF; +"SUPPORTING_HYPERPLANE_COMPACT_POINT_SUP",SUPPORTING_HYPERPLANE_COMPACT_POINT_SUP; +"SUPPORTING_HYPERPLANE_RELATIVE_BOUNDARY",SUPPORTING_HYPERPLANE_RELATIVE_BOUNDARY; +"SUPPORTING_HYPERPLANE_RELATIVE_FRONTIER",SUPPORTING_HYPERPLANE_RELATIVE_FRONTIER; +"SUPPORT_CLAUSES",SUPPORT_CLAUSES; +"SUPPORT_DELTA",SUPPORT_DELTA; +"SUPPORT_EMPTY",SUPPORT_EMPTY; +"SUPPORT_SUBSET",SUPPORT_SUBSET; +"SUPPORT_SUPPORT",SUPPORT_SUPPORT; +"SUP_EQ",SUP_EQ; +"SUP_FINITE",SUP_FINITE; +"SUP_FINITE_LEMMA",SUP_FINITE_LEMMA; +"SUP_INSERT",SUP_INSERT; +"SUP_INSERT_FINITE",SUP_INSERT_FINITE; +"SUP_SING",SUP_SING; +"SUP_UNIQUE_FINITE",SUP_UNIQUE_FINITE; +"SURA_BURA_CLOSED",SURA_BURA_CLOSED; +"SURA_BURA_COMPACT",SURA_BURA_COMPACT; +"SURJ",SURJ; +"SURJECTIVE_EXISTS_THM",SURJECTIVE_EXISTS_THM; +"SURJECTIVE_FORALL_THM",SURJECTIVE_FORALL_THM; +"SURJECTIVE_IFF_INJECTIVE",SURJECTIVE_IFF_INJECTIVE; +"SURJECTIVE_IFF_INJECTIVE_GEN",SURJECTIVE_IFF_INJECTIVE_GEN; +"SURJECTIVE_IMAGE",SURJECTIVE_IMAGE; +"SURJECTIVE_IMAGE_EQ",SURJECTIVE_IMAGE_EQ; +"SURJECTIVE_IMAGE_THM",SURJECTIVE_IMAGE_THM; +"SURJECTIVE_INVERSE",SURJECTIVE_INVERSE; +"SURJECTIVE_INVERSE_o",SURJECTIVE_INVERSE_o; +"SURJECTIVE_MAP",SURJECTIVE_MAP; +"SURJECTIVE_ON_IMAGE",SURJECTIVE_ON_IMAGE; +"SURJECTIVE_ON_RIGHT_INVERSE",SURJECTIVE_ON_RIGHT_INVERSE; +"SURJECTIVE_RIGHT_INVERSE",SURJECTIVE_RIGHT_INVERSE; +"SURJECTIVE_SCALING",SURJECTIVE_SCALING; +"SUSSMANN_OPEN_MAPPING",SUSSMANN_OPEN_MAPPING; +"SWAPSEQ_COMPOSE",SWAPSEQ_COMPOSE; +"SWAPSEQ_ENDSWAP",SWAPSEQ_ENDSWAP; +"SWAPSEQ_EVEN_EVEN",SWAPSEQ_EVEN_EVEN; +"SWAPSEQ_I",SWAPSEQ_I; +"SWAPSEQ_IDENTITY_EVEN",SWAPSEQ_IDENTITY_EVEN; +"SWAPSEQ_INVERSE",SWAPSEQ_INVERSE; +"SWAPSEQ_INVERSE_EXISTS",SWAPSEQ_INVERSE_EXISTS; +"SWAPSEQ_SWAP",SWAPSEQ_SWAP; +"SWAP_COMMON",SWAP_COMMON; +"SWAP_COMMON'",SWAP_COMMON'; +"SWAP_EXISTS_THM",SWAP_EXISTS_THM; +"SWAP_FORALL_THM",SWAP_FORALL_THM; +"SWAP_GALOIS",SWAP_GALOIS; +"SWAP_GENERAL",SWAP_GENERAL; +"SWAP_IDEMPOTENT",SWAP_IDEMPOTENT; +"SWAP_INDEPENDENT",SWAP_INDEPENDENT; +"SWAP_REFL",SWAP_REFL; +"SWAP_SYM",SWAP_SYM; +"SYLVESTER_DETERMINANT_IDENTITY",SYLVESTER_DETERMINANT_IDENTITY; +"SYMDIFF_PARITY_LEMMA",SYMDIFF_PARITY_LEMMA; +"SYMMETRIC_CLOSURE",SYMMETRIC_CLOSURE; +"SYMMETRIC_INTERIOR",SYMMETRIC_INTERIOR; +"SYMMETRIC_LINEAR_IMAGE",SYMMETRIC_LINEAR_IMAGE; +"SYMMETRIC_MATRIX",SYMMETRIC_MATRIX; +"SYMMETRIC_MATRIX_DIAGONALIZABLE_EXPLICIT",SYMMETRIC_MATRIX_DIAGONALIZABLE_EXPLICIT; +"SYMMETRIC_MATRIX_EQ_DIAGONALIZABLE",SYMMETRIC_MATRIX_EQ_DIAGONALIZABLE; +"SYMMETRIC_MATRIX_IMP_DIAGONALIZABLE",SYMMETRIC_MATRIX_IMP_DIAGONALIZABLE; +"SYMMETRIC_MATRIX_MUL",SYMMETRIC_MATRIX_MUL; +"SYMMETRIC_MATRIX_ORTHOGONAL_EIGENVECTORS",SYMMETRIC_MATRIX_ORTHOGONAL_EIGENVECTORS; +"SYMMETRIX_MATRIX_CONJUGATE",SYMMETRIX_MATRIX_CONJUGATE; +"SYMMETRY_LEMMA",SYMMETRY_LEMMA; +"TAGGED_DIVISION_FINER",TAGGED_DIVISION_FINER; +"TAGGED_DIVISION_OF",TAGGED_DIVISION_OF; +"TAGGED_DIVISION_OF_ALT",TAGGED_DIVISION_OF_ALT; +"TAGGED_DIVISION_OF_ANOTHER",TAGGED_DIVISION_OF_ANOTHER; +"TAGGED_DIVISION_OF_EMPTY",TAGGED_DIVISION_OF_EMPTY; +"TAGGED_DIVISION_OF_FINITE",TAGGED_DIVISION_OF_FINITE; +"TAGGED_DIVISION_OF_NONTRIVIAL",TAGGED_DIVISION_OF_NONTRIVIAL; +"TAGGED_DIVISION_OF_SELF",TAGGED_DIVISION_OF_SELF; +"TAGGED_DIVISION_OF_TRIVIAL",TAGGED_DIVISION_OF_TRIVIAL; +"TAGGED_DIVISION_OF_UNION_SELF",TAGGED_DIVISION_OF_UNION_SELF; +"TAGGED_DIVISION_SPLIT_LEFT_INJ",TAGGED_DIVISION_SPLIT_LEFT_INJ; +"TAGGED_DIVISION_SPLIT_RIGHT_INJ",TAGGED_DIVISION_SPLIT_RIGHT_INJ; +"TAGGED_DIVISION_UNION",TAGGED_DIVISION_UNION; +"TAGGED_DIVISION_UNIONS",TAGGED_DIVISION_UNIONS; +"TAGGED_DIVISION_UNIONS_EXISTS",TAGGED_DIVISION_UNIONS_EXISTS; +"TAGGED_DIVISION_UNION_IMAGE_SND",TAGGED_DIVISION_UNION_IMAGE_SND; +"TAGGED_DIVISION_UNION_INTERVAL",TAGGED_DIVISION_UNION_INTERVAL; +"TAGGED_PARTIAL_DIVISION_COMMON_POINT_BOUND",TAGGED_PARTIAL_DIVISION_COMMON_POINT_BOUND; +"TAGGED_PARTIAL_DIVISION_COMMON_TAGS",TAGGED_PARTIAL_DIVISION_COMMON_TAGS; +"TAGGED_PARTIAL_DIVISION_OF_SUBSET",TAGGED_PARTIAL_DIVISION_OF_SUBSET; +"TAGGED_PARTIAL_DIVISION_OF_TRIVIAL",TAGGED_PARTIAL_DIVISION_OF_TRIVIAL; +"TAGGED_PARTIAL_DIVISION_OF_UNION_SELF",TAGGED_PARTIAL_DIVISION_OF_UNION_SELF; +"TAGGED_PARTIAL_DIVISION_SUBSET",TAGGED_PARTIAL_DIVISION_SUBSET; +"TAG_IN_INTERVAL",TAG_IN_INTERVAL; +"TAN_0",TAN_0; +"TAN_ABS_GE_X",TAN_ABS_GE_X; +"TAN_ADD",TAN_ADD; +"TAN_ATN",TAN_ATN; +"TAN_BOUND_PI2",TAN_BOUND_PI2; +"TAN_COT",TAN_COT; +"TAN_DOUBLE",TAN_DOUBLE; +"TAN_MONO_LE",TAN_MONO_LE; +"TAN_MONO_LE_EQ",TAN_MONO_LE_EQ; +"TAN_MONO_LT",TAN_MONO_LT; +"TAN_MONO_LT_EQ",TAN_MONO_LT_EQ; +"TAN_NEG",TAN_NEG; +"TAN_NPI",TAN_NPI; +"TAN_PERIODIC_NPI",TAN_PERIODIC_NPI; +"TAN_PERIODIC_PI",TAN_PERIODIC_PI; +"TAN_PI",TAN_PI; +"TAN_PI4",TAN_PI4; +"TAN_POS_PI2",TAN_POS_PI2; +"TAN_POS_PI2_LE",TAN_POS_PI2_LE; +"TAN_SEC",TAN_SEC; +"TAN_SUB",TAN_SUB; +"TAN_TOTAL",TAN_TOTAL; +"TAN_TOTAL_LEMMA",TAN_TOTAL_LEMMA; +"TAN_TOTAL_POS",TAN_TOTAL_POS; +"TARSKI_SET",TARSKI_SET; +"TAYLOR_CCOS",TAYLOR_CCOS; +"TAYLOR_CCOS_RAW",TAYLOR_CCOS_RAW; +"TAYLOR_CEXP",TAYLOR_CEXP; +"TAYLOR_CSIN",TAYLOR_CSIN; +"TAYLOR_CSIN_RAW",TAYLOR_CSIN_RAW; +"TENDSTO_LIM",TENDSTO_LIM; +"TENDSTO_REAL",TENDSTO_REAL; +"TIETZE",TIETZE; +"TIETZE_CLOSED_INTERVAL",TIETZE_CLOSED_INTERVAL; +"TIETZE_CLOSED_INTERVAL_1",TIETZE_CLOSED_INTERVAL_1; +"TIETZE_OPEN_INTERVAL",TIETZE_OPEN_INTERVAL; +"TIETZE_OPEN_INTERVAL_1",TIETZE_OPEN_INTERVAL_1; +"TIETZE_STEP",TIETZE_STEP; +"TIETZE_UNBOUNDED",TIETZE_UNBOUNDED; +"TIETZE_UNBOUNDED_1",TIETZE_UNBOUNDED_1; +"TL",TL; +"TOPOLOGICAL_SORT",TOPOLOGICAL_SORT; +"TOPOLOGY_EQ",TOPOLOGY_EQ; +"TOPSPACE_EUCLIDEAN",TOPSPACE_EUCLIDEAN; +"TOPSPACE_EUCLIDEANREAL",TOPSPACE_EUCLIDEANREAL; +"TOPSPACE_EUCLIDEANREAL_SUBTOPOLOGY",TOPSPACE_EUCLIDEANREAL_SUBTOPOLOGY; +"TOPSPACE_EUCLIDEAN_SUBTOPOLOGY",TOPSPACE_EUCLIDEAN_SUBTOPOLOGY; +"TOPSPACE_SUBTOPOLOGY",TOPSPACE_SUBTOPOLOGY; +"TRACE_0",TRACE_0; +"TRACE_ADD",TRACE_ADD; +"TRACE_CONJUGATE",TRACE_CONJUGATE; +"TRACE_I",TRACE_I; +"TRACE_MUL_SYM",TRACE_MUL_SYM; +"TRACE_SUB",TRACE_SUB; +"TRACE_TRANSP",TRACE_TRANSP; +"TRANSITIVE_STEPWISE_LE",TRANSITIVE_STEPWISE_LE; +"TRANSITIVE_STEPWISE_LE_EQ",TRANSITIVE_STEPWISE_LE_EQ; +"TRANSITIVE_STEPWISE_LT",TRANSITIVE_STEPWISE_LT; +"TRANSITIVE_STEPWISE_LT_EQ",TRANSITIVE_STEPWISE_LT_EQ; +"TRANSLATION_DIFF",TRANSLATION_DIFF; +"TRANSLATION_EQ_IMP",TRANSLATION_EQ_IMP; +"TRANSLATION_GALOIS",TRANSLATION_GALOIS; +"TRANSLATION_UNIV",TRANSLATION_UNIV; +"TRANSP_COLUMNVECTOR",TRANSP_COLUMNVECTOR; +"TRANSP_COMPONENT",TRANSP_COMPONENT; +"TRANSP_DIAGONAL_MATRIX",TRANSP_DIAGONAL_MATRIX; +"TRANSP_EQ",TRANSP_EQ; +"TRANSP_MAT",TRANSP_MAT; +"TRANSP_MATRIX_ADD",TRANSP_MATRIX_ADD; +"TRANSP_MATRIX_CMUL",TRANSP_MATRIX_CMUL; +"TRANSP_MATRIX_NEG",TRANSP_MATRIX_NEG; +"TRANSP_MATRIX_SUB",TRANSP_MATRIX_SUB; +"TRANSP_ROWVECTOR",TRANSP_ROWVECTOR; +"TRANSP_TRANSP",TRANSP_TRANSP; +"TREAL_ADD_ASSOC",TREAL_ADD_ASSOC; +"TREAL_ADD_LDISTRIB",TREAL_ADD_LDISTRIB; +"TREAL_ADD_LID",TREAL_ADD_LID; +"TREAL_ADD_LINV",TREAL_ADD_LINV; +"TREAL_ADD_SYM",TREAL_ADD_SYM; +"TREAL_ADD_SYM_EQ",TREAL_ADD_SYM_EQ; +"TREAL_ADD_WELLDEF",TREAL_ADD_WELLDEF; +"TREAL_ADD_WELLDEFR",TREAL_ADD_WELLDEFR; +"TREAL_EQ_AP",TREAL_EQ_AP; +"TREAL_EQ_IMP_LE",TREAL_EQ_IMP_LE; +"TREAL_EQ_REFL",TREAL_EQ_REFL; +"TREAL_EQ_SYM",TREAL_EQ_SYM; +"TREAL_EQ_TRANS",TREAL_EQ_TRANS; +"TREAL_INV_0",TREAL_INV_0; +"TREAL_INV_WELLDEF",TREAL_INV_WELLDEF; +"TREAL_LE_ANTISYM",TREAL_LE_ANTISYM; +"TREAL_LE_LADD_IMP",TREAL_LE_LADD_IMP; +"TREAL_LE_MUL",TREAL_LE_MUL; +"TREAL_LE_REFL",TREAL_LE_REFL; +"TREAL_LE_TOTAL",TREAL_LE_TOTAL; +"TREAL_LE_TRANS",TREAL_LE_TRANS; +"TREAL_LE_WELLDEF",TREAL_LE_WELLDEF; +"TREAL_MUL_ASSOC",TREAL_MUL_ASSOC; +"TREAL_MUL_LID",TREAL_MUL_LID; +"TREAL_MUL_LINV",TREAL_MUL_LINV; +"TREAL_MUL_SYM",TREAL_MUL_SYM; +"TREAL_MUL_SYM_EQ",TREAL_MUL_SYM_EQ; +"TREAL_MUL_WELLDEF",TREAL_MUL_WELLDEF; +"TREAL_MUL_WELLDEFR",TREAL_MUL_WELLDEFR; +"TREAL_NEG_WELLDEF",TREAL_NEG_WELLDEF; +"TREAL_OF_NUM_ADD",TREAL_OF_NUM_ADD; +"TREAL_OF_NUM_EQ",TREAL_OF_NUM_EQ; +"TREAL_OF_NUM_LE",TREAL_OF_NUM_LE; +"TREAL_OF_NUM_MUL",TREAL_OF_NUM_MUL; +"TREAL_OF_NUM_WELLDEF",TREAL_OF_NUM_WELLDEF; +"TRIANGLE_LEMMA",TRIANGLE_LEMMA; +"TRIANGLE_LINEAR_HAS_CHAIN_INTEGRAL",TRIANGLE_LINEAR_HAS_CHAIN_INTEGRAL; +"TRIANGLE_PATH_INTEGRALS_CONVEX_PRIMITIVE",TRIANGLE_PATH_INTEGRALS_CONVEX_PRIMITIVE; +"TRIANGLE_PATH_INTEGRALS_STARLIKE_PRIMITIVE",TRIANGLE_PATH_INTEGRALS_STARLIKE_PRIMITIVE; +"TRIANGLE_POINTS_CLOSER",TRIANGLE_POINTS_CLOSER; +"TRIANGULATION_INTER_SIMPLEX",TRIANGULATION_INTER_SIMPLEX; +"TRIANGULATION_SIMPLICIAL_COMPLEX",TRIANGULATION_SIMPLICIAL_COMPLEX; +"TRIANGULATION_UNION",TRIANGULATION_UNION; +"TRIVIAL_LIMIT_AT",TRIVIAL_LIMIT_AT; +"TRIVIAL_LIMIT_ATREAL",TRIVIAL_LIMIT_ATREAL; +"TRIVIAL_LIMIT_AT_INFINITY",TRIVIAL_LIMIT_AT_INFINITY; +"TRIVIAL_LIMIT_AT_NEGINFINITY",TRIVIAL_LIMIT_AT_NEGINFINITY; +"TRIVIAL_LIMIT_AT_POSINFINITY",TRIVIAL_LIMIT_AT_POSINFINITY; +"TRIVIAL_LIMIT_SEQUENTIALLY",TRIVIAL_LIMIT_SEQUENTIALLY; +"TRIVIAL_LIMIT_WITHIN",TRIVIAL_LIMIT_WITHIN; +"TRIVIAL_LIMIT_WITHINREAL_WITHIN",TRIVIAL_LIMIT_WITHINREAL_WITHIN; +"TRIVIAL_LIMIT_WITHINREAL_WITHINCOMPLEX",TRIVIAL_LIMIT_WITHINREAL_WITHINCOMPLEX; +"TRIVIAL_LIMIT_WITHIN_CONVEX",TRIVIAL_LIMIT_WITHIN_CONVEX; +"TRIVIAL_LIMIT_WITHIN_REALINTERVAL",TRIVIAL_LIMIT_WITHIN_REALINTERVAL; +"TRIV_AND_EXISTS_THM",TRIV_AND_EXISTS_THM; +"TRIV_EXISTS_AND_THM",TRIV_EXISTS_AND_THM; +"TRIV_EXISTS_IMP_THM",TRIV_EXISTS_IMP_THM; +"TRIV_FORALL_IMP_THM",TRIV_FORALL_IMP_THM; +"TRIV_FORALL_OR_THM",TRIV_FORALL_OR_THM; +"TRIV_OR_FORALL_THM",TRIV_OR_FORALL_THM; +"TRUTH",TRUTH; +"TUBE_LEMMA",TUBE_LEMMA; +"TWO",TWO; +"T_DEF",T_DEF; +"UNBOUNDED_COMPONENTS_COMPLEMENT_ABSOLUTE_RETRACT",UNBOUNDED_COMPONENTS_COMPLEMENT_ABSOLUTE_RETRACT; +"UNBOUNDED_CONVEX_CLOSED_CONTAINS_RAY",UNBOUNDED_CONVEX_CLOSED_CONTAINS_RAY; +"UNBOUNDED_CONVEX_CLOSED_CONTAINS_RAYS",UNBOUNDED_CONVEX_CLOSED_CONTAINS_RAYS; +"UNBOUNDED_HALFSPACE_COMPONENT_GE",UNBOUNDED_HALFSPACE_COMPONENT_GE; +"UNBOUNDED_HALFSPACE_COMPONENT_GT",UNBOUNDED_HALFSPACE_COMPONENT_GT; +"UNBOUNDED_HALFSPACE_COMPONENT_LE",UNBOUNDED_HALFSPACE_COMPONENT_LE; +"UNBOUNDED_HALFSPACE_COMPONENT_LT",UNBOUNDED_HALFSPACE_COMPONENT_LT; +"UNBOUNDED_INTER_COBOUNDED",UNBOUNDED_INTER_COBOUNDED; +"UNBOUNDED_OUTSIDE",UNBOUNDED_OUTSIDE; +"UNCOUNTABLE_CONNECTED",UNCOUNTABLE_CONNECTED; +"UNCOUNTABLE_CONTAINS_LIMIT_POINT",UNCOUNTABLE_CONTAINS_LIMIT_POINT; +"UNCOUNTABLE_CONVEX",UNCOUNTABLE_CONVEX; +"UNCOUNTABLE_EUCLIDEAN",UNCOUNTABLE_EUCLIDEAN; +"UNCOUNTABLE_HAS_CONDENSATION_POINT",UNCOUNTABLE_HAS_CONDENSATION_POINT; +"UNCOUNTABLE_INTERVAL",UNCOUNTABLE_INTERVAL; +"UNCOUNTABLE_NONEMPTY_INTERIOR",UNCOUNTABLE_NONEMPTY_INTERIOR; +"UNCOUNTABLE_OPEN",UNCOUNTABLE_OPEN; +"UNCOUNTABLE_PATH_CONNECTED",UNCOUNTABLE_PATH_CONNECTED; +"UNCOUNTABLE_REAL",UNCOUNTABLE_REAL; +"UNCOUNTABLE_SEGMENT",UNCOUNTABLE_SEGMENT; +"UNCURRY_DEF",UNCURRY_DEF; +"UNICOHERENT_UNIV",UNICOHERENT_UNIV; +"UNIFORMLY_CAUCHY_IMP_UNIFORMLY_CONVERGENT",UNIFORMLY_CAUCHY_IMP_UNIFORMLY_CONVERGENT; +"UNIFORMLY_CONTINUOUS_EXTENDS_TO_CLOSURE",UNIFORMLY_CONTINUOUS_EXTENDS_TO_CLOSURE; +"UNIFORMLY_CONTINUOUS_HOMEOMORPHISM_UNIV_TRIVIAL",UNIFORMLY_CONTINUOUS_HOMEOMORPHISM_UNIV_TRIVIAL; +"UNIFORMLY_CONTINUOUS_IMP_CAUCHY_CONTINUOUS",UNIFORMLY_CONTINUOUS_IMP_CAUCHY_CONTINUOUS; +"UNIFORMLY_CONTINUOUS_IMP_CONTINUOUS",UNIFORMLY_CONTINUOUS_IMP_CONTINUOUS; +"UNIFORMLY_CONTINUOUS_ON_ADD",UNIFORMLY_CONTINUOUS_ON_ADD; +"UNIFORMLY_CONTINUOUS_ON_CLOSURE",UNIFORMLY_CONTINUOUS_ON_CLOSURE; +"UNIFORMLY_CONTINUOUS_ON_CMUL",UNIFORMLY_CONTINUOUS_ON_CMUL; +"UNIFORMLY_CONTINUOUS_ON_COMPLEX_LMUL",UNIFORMLY_CONTINUOUS_ON_COMPLEX_LMUL; +"UNIFORMLY_CONTINUOUS_ON_COMPLEX_MUL",UNIFORMLY_CONTINUOUS_ON_COMPLEX_MUL; +"UNIFORMLY_CONTINUOUS_ON_COMPLEX_RMUL",UNIFORMLY_CONTINUOUS_ON_COMPLEX_RMUL; +"UNIFORMLY_CONTINUOUS_ON_COMPOSE",UNIFORMLY_CONTINUOUS_ON_COMPOSE; +"UNIFORMLY_CONTINUOUS_ON_CONST",UNIFORMLY_CONTINUOUS_ON_CONST; +"UNIFORMLY_CONTINUOUS_ON_DIST_CLOSEST_POINT",UNIFORMLY_CONTINUOUS_ON_DIST_CLOSEST_POINT; +"UNIFORMLY_CONTINUOUS_ON_EQ",UNIFORMLY_CONTINUOUS_ON_EQ; +"UNIFORMLY_CONTINUOUS_ON_ID",UNIFORMLY_CONTINUOUS_ON_ID; +"UNIFORMLY_CONTINUOUS_ON_LIFT_SETDIST",UNIFORMLY_CONTINUOUS_ON_LIFT_SETDIST; +"UNIFORMLY_CONTINUOUS_ON_MUL",UNIFORMLY_CONTINUOUS_ON_MUL; +"UNIFORMLY_CONTINUOUS_ON_NEG",UNIFORMLY_CONTINUOUS_ON_NEG; +"UNIFORMLY_CONTINUOUS_ON_SEQUENTIALLY",UNIFORMLY_CONTINUOUS_ON_SEQUENTIALLY; +"UNIFORMLY_CONTINUOUS_ON_SUB",UNIFORMLY_CONTINUOUS_ON_SUB; +"UNIFORMLY_CONTINUOUS_ON_SUBSET",UNIFORMLY_CONTINUOUS_ON_SUBSET; +"UNIFORMLY_CONTINUOUS_ON_VMUL",UNIFORMLY_CONTINUOUS_ON_VMUL; +"UNIFORMLY_CONTINUOUS_ON_VSUM",UNIFORMLY_CONTINUOUS_ON_VSUM; +"UNIFORMLY_CONVERGENT_EQ_CAUCHY",UNIFORMLY_CONVERGENT_EQ_CAUCHY; +"UNIFORM_LIM_ADD",UNIFORM_LIM_ADD; +"UNIFORM_LIM_BILINEAR",UNIFORM_LIM_BILINEAR; +"UNIFORM_LIM_COMPLEX_DIV",UNIFORM_LIM_COMPLEX_DIV; +"UNIFORM_LIM_COMPLEX_INV",UNIFORM_LIM_COMPLEX_INV; +"UNIFORM_LIM_COMPLEX_MUL",UNIFORM_LIM_COMPLEX_MUL; +"UNIFORM_LIM_SUB",UNIFORM_LIM_SUB; +"UNION",UNION; +"UNIONS",UNIONS; +"UNIONS_0",UNIONS_0; +"UNIONS_1",UNIONS_1; +"UNIONS_2",UNIONS_2; +"UNIONS_COMPONENTS",UNIONS_COMPONENTS; +"UNIONS_CONNECTED_COMPONENT",UNIONS_CONNECTED_COMPONENT; +"UNIONS_DIFF",UNIONS_DIFF; +"UNIONS_GSPEC",UNIONS_GSPEC; +"UNIONS_IMAGE",UNIONS_IMAGE; +"UNIONS_INSERT",UNIONS_INSERT; +"UNIONS_INTERS",UNIONS_INTERS; +"UNIONS_MAXIMAL_SETS",UNIONS_MAXIMAL_SETS; +"UNIONS_MONO",UNIONS_MONO; +"UNIONS_MONO_IMAGE",UNIONS_MONO_IMAGE; +"UNIONS_PATH_COMPONENT",UNIONS_PATH_COMPONENT; +"UNIONS_PRED",UNIONS_PRED; +"UNIONS_SUBSET",UNIONS_SUBSET; +"UNIONS_UNION",UNIONS_UNION; +"UNION_ACI",UNION_ACI; +"UNION_ASSOC",UNION_ASSOC; +"UNION_COMM",UNION_COMM; +"UNION_EMPTY",UNION_EMPTY; +"UNION_FL",UNION_FL; +"UNION_IDEMPOT",UNION_IDEMPOT; +"UNION_INSEG",UNION_INSEG; +"UNION_INTERIOR_SUBSET",UNION_INTERIOR_SUBSET; +"UNION_LE_ADD_C",UNION_LE_ADD_C; +"UNION_OVER_INTER",UNION_OVER_INTER; +"UNION_SEGMENT",UNION_SEGMENT; +"UNION_SUBSET",UNION_SUBSET; +"UNION_UNIV",UNION_UNIV; +"UNION_WITH_INSIDE",UNION_WITH_INSIDE; +"UNION_WITH_OUTSIDE",UNION_WITH_OUTSIDE; +"UNIQUE_SKOLEM_ALT",UNIQUE_SKOLEM_ALT; +"UNIQUE_SKOLEM_THM",UNIQUE_SKOLEM_THM; +"UNIT_INTERVAL_CONVEX_HULL",UNIT_INTERVAL_CONVEX_HULL; +"UNIT_INTERVAL_NONEMPTY",UNIT_INTERVAL_NONEMPTY; +"UNIV",UNIV; +"UNIV_GSPEC",UNIV_GSPEC; +"UNIV_NOT_EMPTY",UNIV_NOT_EMPTY; +"UNIV_PCROSS_UNIV",UNIV_PCROSS_UNIV; +"UNIV_SECOND_COUNTABLE",UNIV_SECOND_COUNTABLE; +"UNIV_SECOND_COUNTABLE_SEQUENCE",UNIV_SECOND_COUNTABLE_SEQUENCE; +"UNIV_SUBSET",UNIV_SUBSET; +"UNWINDING_2PI",UNWINDING_2PI; +"UNWIND_THM1",UNWIND_THM1; +"UNWIND_THM2",UNWIND_THM2; +"UPPER_BOUND_FINITE_SET",UPPER_BOUND_FINITE_SET; +"UPPER_BOUND_FINITE_SET_REAL",UPPER_BOUND_FINITE_SET_REAL; +"URYSOHN",URYSOHN; +"URYSOHN_LOCAL",URYSOHN_LOCAL; +"URYSOHN_LOCAL_STRONG",URYSOHN_LOCAL_STRONG; +"URYSOHN_STRONG",URYSOHN_STRONG; +"VALID_PATH_CIRCLEPATH",VALID_PATH_CIRCLEPATH; +"VALID_PATH_COMPOSE",VALID_PATH_COMPOSE; +"VALID_PATH_IMP_PATH",VALID_PATH_IMP_PATH; +"VALID_PATH_JOIN",VALID_PATH_JOIN; +"VALID_PATH_JOIN_EQ",VALID_PATH_JOIN_EQ; +"VALID_PATH_LINEPATH",VALID_PATH_LINEPATH; +"VALID_PATH_PARTCIRCLEPATH",VALID_PATH_PARTCIRCLEPATH; +"VALID_PATH_REVERSEPATH",VALID_PATH_REVERSEPATH; +"VALID_PATH_SHIFTPATH",VALID_PATH_SHIFTPATH; +"VALID_PATH_SUBPATH",VALID_PATH_SUBPATH; +"VALID_PATH_VECTOR_POLYNOMIAL_FUNCTION",VALID_PATH_VECTOR_POLYNOMIAL_FUNCTION; +"VARIATION_EQUAL_LEMMA",VARIATION_EQUAL_LEMMA; +"VECTOR_1",VECTOR_1; +"VECTOR_2",VECTOR_2; +"VECTOR_3",VECTOR_3; +"VECTOR_4",VECTOR_4; +"VECTOR_ADD_AC",VECTOR_ADD_AC; +"VECTOR_ADD_ASSOC",VECTOR_ADD_ASSOC; +"VECTOR_ADD_COMPONENT",VECTOR_ADD_COMPONENT; +"VECTOR_ADD_LDISTRIB",VECTOR_ADD_LDISTRIB; +"VECTOR_ADD_LID",VECTOR_ADD_LID; +"VECTOR_ADD_LINV",VECTOR_ADD_LINV; +"VECTOR_ADD_RDISTRIB",VECTOR_ADD_RDISTRIB; +"VECTOR_ADD_RID",VECTOR_ADD_RID; +"VECTOR_ADD_RINV",VECTOR_ADD_RINV; +"VECTOR_ADD_SUB",VECTOR_ADD_SUB; +"VECTOR_ADD_SYM",VECTOR_ADD_SYM; +"VECTOR_AFFINITY_EQ",VECTOR_AFFINITY_EQ; +"VECTOR_CHOOSE_DIST",VECTOR_CHOOSE_DIST; +"VECTOR_CHOOSE_SIZE",VECTOR_CHOOSE_SIZE; +"VECTOR_COMPONENTWISE",VECTOR_COMPONENTWISE; +"VECTOR_DERIVATIVE_AT",VECTOR_DERIVATIVE_AT; +"VECTOR_DERIVATIVE_CIRCLEPATH",VECTOR_DERIVATIVE_CIRCLEPATH; +"VECTOR_DERIVATIVE_CONST_AT",VECTOR_DERIVATIVE_CONST_AT; +"VECTOR_DERIVATIVE_LINEPATH_AT",VECTOR_DERIVATIVE_LINEPATH_AT; +"VECTOR_DERIVATIVE_LINEPATH_WITHIN",VECTOR_DERIVATIVE_LINEPATH_WITHIN; +"VECTOR_DERIVATIVE_PARTCIRCLEPATH",VECTOR_DERIVATIVE_PARTCIRCLEPATH; +"VECTOR_DERIVATIVE_UNIQUE_AT",VECTOR_DERIVATIVE_UNIQUE_AT; +"VECTOR_DERIVATIVE_UNIQUE_WITHIN_CLOSED_INTERVAL",VECTOR_DERIVATIVE_UNIQUE_WITHIN_CLOSED_INTERVAL; +"VECTOR_DERIVATIVE_WITHIN_CLOSED_INTERVAL",VECTOR_DERIVATIVE_WITHIN_CLOSED_INTERVAL; +"VECTOR_DERIVATIVE_WITHIN_INTERIOR",VECTOR_DERIVATIVE_WITHIN_INTERIOR; +"VECTOR_DERIVATIVE_WORKS",VECTOR_DERIVATIVE_WORKS; +"VECTOR_DIFF_CHAIN_AT",VECTOR_DIFF_CHAIN_AT; +"VECTOR_DIFF_CHAIN_WITHIN",VECTOR_DIFF_CHAIN_WITHIN; +"VECTOR_EQ",VECTOR_EQ; +"VECTOR_EQ_ADDR",VECTOR_EQ_ADDR; +"VECTOR_EQ_AFFINITY",VECTOR_EQ_AFFINITY; +"VECTOR_EQ_DOT_SPAN",VECTOR_EQ_DOT_SPAN; +"VECTOR_EQ_LDOT",VECTOR_EQ_LDOT; +"VECTOR_EQ_NEG2",VECTOR_EQ_NEG2; +"VECTOR_EQ_RDOT",VECTOR_EQ_RDOT; +"VECTOR_EXPAND_1",VECTOR_EXPAND_1; +"VECTOR_EXPAND_2",VECTOR_EXPAND_2; +"VECTOR_EXPAND_3",VECTOR_EXPAND_3; +"VECTOR_EXPAND_4",VECTOR_EXPAND_4; +"VECTOR_IN_ORTHOGONAL_BASIS",VECTOR_IN_ORTHOGONAL_BASIS; +"VECTOR_IN_ORTHOGONAL_SPANNINGSET",VECTOR_IN_ORTHOGONAL_SPANNINGSET; +"VECTOR_IN_ORTHONORMAL_BASIS",VECTOR_IN_ORTHONORMAL_BASIS; +"VECTOR_MATRIX_MUL_TRANSP",VECTOR_MATRIX_MUL_TRANSP; +"VECTOR_MUL_ASSOC",VECTOR_MUL_ASSOC; +"VECTOR_MUL_COMPONENT",VECTOR_MUL_COMPONENT; +"VECTOR_MUL_EQ_0",VECTOR_MUL_EQ_0; +"VECTOR_MUL_LCANCEL",VECTOR_MUL_LCANCEL; +"VECTOR_MUL_LCANCEL_IMP",VECTOR_MUL_LCANCEL_IMP; +"VECTOR_MUL_LID",VECTOR_MUL_LID; +"VECTOR_MUL_LNEG",VECTOR_MUL_LNEG; +"VECTOR_MUL_LZERO",VECTOR_MUL_LZERO; +"VECTOR_MUL_RCANCEL",VECTOR_MUL_RCANCEL; +"VECTOR_MUL_RCANCEL_IMP",VECTOR_MUL_RCANCEL_IMP; +"VECTOR_MUL_RNEG",VECTOR_MUL_RNEG; +"VECTOR_MUL_RZERO",VECTOR_MUL_RZERO; +"VECTOR_NEG_0",VECTOR_NEG_0; +"VECTOR_NEG_COMPONENT",VECTOR_NEG_COMPONENT; +"VECTOR_NEG_EQ_0",VECTOR_NEG_EQ_0; +"VECTOR_NEG_MINUS1",VECTOR_NEG_MINUS1; +"VECTOR_NEG_NEG",VECTOR_NEG_NEG; +"VECTOR_NEG_SUB",VECTOR_NEG_SUB; +"VECTOR_ONE",VECTOR_ONE; +"VECTOR_POLYNOMIAL_FUNCTION_ADD",VECTOR_POLYNOMIAL_FUNCTION_ADD; +"VECTOR_POLYNOMIAL_FUNCTION_CMUL",VECTOR_POLYNOMIAL_FUNCTION_CMUL; +"VECTOR_POLYNOMIAL_FUNCTION_COMPONENT",VECTOR_POLYNOMIAL_FUNCTION_COMPONENT; +"VECTOR_POLYNOMIAL_FUNCTION_CONST",VECTOR_POLYNOMIAL_FUNCTION_CONST; +"VECTOR_POLYNOMIAL_FUNCTION_ID",VECTOR_POLYNOMIAL_FUNCTION_ID; +"VECTOR_POLYNOMIAL_FUNCTION_MUL",VECTOR_POLYNOMIAL_FUNCTION_MUL; +"VECTOR_POLYNOMIAL_FUNCTION_NEG",VECTOR_POLYNOMIAL_FUNCTION_NEG; +"VECTOR_POLYNOMIAL_FUNCTION_SUB",VECTOR_POLYNOMIAL_FUNCTION_SUB; +"VECTOR_POLYNOMIAL_FUNCTION_VSUM",VECTOR_POLYNOMIAL_FUNCTION_VSUM; +"VECTOR_SUB",VECTOR_SUB; +"VECTOR_SUB_ADD",VECTOR_SUB_ADD; +"VECTOR_SUB_ADD2",VECTOR_SUB_ADD2; +"VECTOR_SUB_COMPONENT",VECTOR_SUB_COMPONENT; +"VECTOR_SUB_EQ",VECTOR_SUB_EQ; +"VECTOR_SUB_LDISTRIB",VECTOR_SUB_LDISTRIB; +"VECTOR_SUB_LZERO",VECTOR_SUB_LZERO; +"VECTOR_SUB_PROJECT_ORTHOGONAL",VECTOR_SUB_PROJECT_ORTHOGONAL; +"VECTOR_SUB_RADD",VECTOR_SUB_RADD; +"VECTOR_SUB_RDISTRIB",VECTOR_SUB_RDISTRIB; +"VECTOR_SUB_REFL",VECTOR_SUB_REFL; +"VECTOR_SUB_RZERO",VECTOR_SUB_RZERO; +"VECTOR_VARIATION_AFFINITY",VECTOR_VARIATION_AFFINITY; +"VECTOR_VARIATION_AFFINITY2",VECTOR_VARIATION_AFFINITY2; +"VECTOR_VARIATION_COMBINE",VECTOR_VARIATION_COMBINE; +"VECTOR_VARIATION_CONST",VECTOR_VARIATION_CONST; +"VECTOR_VARIATION_CONST_EQ",VECTOR_VARIATION_CONST_EQ; +"VECTOR_VARIATION_CONTINUOUS",VECTOR_VARIATION_CONTINUOUS; +"VECTOR_VARIATION_CONTINUOUS_LEFT",VECTOR_VARIATION_CONTINUOUS_LEFT; +"VECTOR_VARIATION_CONTINUOUS_RIGHT",VECTOR_VARIATION_CONTINUOUS_RIGHT; +"VECTOR_VARIATION_EQ",VECTOR_VARIATION_EQ; +"VECTOR_VARIATION_GE_DROP_FUNCTION",VECTOR_VARIATION_GE_DROP_FUNCTION; +"VECTOR_VARIATION_GE_NORM_FUNCTION",VECTOR_VARIATION_GE_NORM_FUNCTION; +"VECTOR_VARIATION_INTEGRAL_NORM_DERIVATIVE",VECTOR_VARIATION_INTEGRAL_NORM_DERIVATIVE; +"VECTOR_VARIATION_MINUS_FUNCTION_MONOTONE",VECTOR_VARIATION_MINUS_FUNCTION_MONOTONE; +"VECTOR_VARIATION_MONOTONE",VECTOR_VARIATION_MONOTONE; +"VECTOR_VARIATION_NEG",VECTOR_VARIATION_NEG; +"VECTOR_VARIATION_ON_DIVISION",VECTOR_VARIATION_ON_DIVISION; +"VECTOR_VARIATION_ON_NULL",VECTOR_VARIATION_ON_NULL; +"VECTOR_VARIATION_POS_LE",VECTOR_VARIATION_POS_LE; +"VECTOR_VARIATION_REFLECT",VECTOR_VARIATION_REFLECT; +"VECTOR_VARIATION_REFLECT2",VECTOR_VARIATION_REFLECT2; +"VECTOR_VARIATION_REFLECT_INTERVAL",VECTOR_VARIATION_REFLECT_INTERVAL; +"VECTOR_VARIATION_TRANSLATION",VECTOR_VARIATION_TRANSLATION; +"VECTOR_VARIATION_TRANSLATION2",VECTOR_VARIATION_TRANSLATION2; +"VECTOR_VARIATION_TRANSLATION_INTERVAL",VECTOR_VARIATION_TRANSLATION_INTERVAL; +"VECTOR_VARIATION_TRIANGLE",VECTOR_VARIATION_TRIANGLE; +"VEC_COMPONENT",VEC_COMPONENT; +"VEC_EQ",VEC_EQ; +"VSUM",VSUM; +"VSUM_0",VSUM_0; +"VSUM_1",VSUM_1; +"VSUM_2",VSUM_2; +"VSUM_3",VSUM_3; +"VSUM_4",VSUM_4; +"VSUM_ADD",VSUM_ADD; +"VSUM_ADD_GEN",VSUM_ADD_GEN; +"VSUM_ADD_NUMSEG",VSUM_ADD_NUMSEG; +"VSUM_ADD_SPLIT",VSUM_ADD_SPLIT; +"VSUM_BIJECTION",VSUM_BIJECTION; +"VSUM_CASES",VSUM_CASES; +"VSUM_CASES_1",VSUM_CASES_1; +"VSUM_CLAUSES",VSUM_CLAUSES; +"VSUM_CLAUSES_LEFT",VSUM_CLAUSES_LEFT; +"VSUM_CLAUSES_NUMSEG",VSUM_CLAUSES_NUMSEG; +"VSUM_CLAUSES_RIGHT",VSUM_CLAUSES_RIGHT; +"VSUM_CMUL_NUMSEG",VSUM_CMUL_NUMSEG; +"VSUM_COMBINE_L",VSUM_COMBINE_L; +"VSUM_COMBINE_R",VSUM_COMBINE_R; +"VSUM_COMPLEX_LMUL",VSUM_COMPLEX_LMUL; +"VSUM_COMPLEX_RMUL",VSUM_COMPLEX_RMUL; +"VSUM_COMPONENT",VSUM_COMPONENT; +"VSUM_CONST",VSUM_CONST; +"VSUM_CONST_NUMSEG",VSUM_CONST_NUMSEG; +"VSUM_CONTENT_NULL",VSUM_CONTENT_NULL; +"VSUM_CX",VSUM_CX; +"VSUM_CX_NUMSEG",VSUM_CX_NUMSEG; +"VSUM_DELETE",VSUM_DELETE; +"VSUM_DELETE_CASES",VSUM_DELETE_CASES; +"VSUM_DELTA",VSUM_DELTA; +"VSUM_DIFF",VSUM_DIFF; +"VSUM_DIFFS",VSUM_DIFFS; +"VSUM_DIFFS_ALT",VSUM_DIFFS_ALT; +"VSUM_DIFF_LEMMA",VSUM_DIFF_LEMMA; +"VSUM_EQ",VSUM_EQ; +"VSUM_EQ_0",VSUM_EQ_0; +"VSUM_EQ_GENERAL",VSUM_EQ_GENERAL; +"VSUM_EQ_GENERAL_INVERSES",VSUM_EQ_GENERAL_INVERSES; +"VSUM_EQ_NUMSEG",VSUM_EQ_NUMSEG; +"VSUM_EQ_SUPERSET",VSUM_EQ_SUPERSET; +"VSUM_GP",VSUM_GP; +"VSUM_GP_BASIC",VSUM_GP_BASIC; +"VSUM_GP_MULTIPLIED",VSUM_GP_MULTIPLIED; +"VSUM_GP_OFFSET",VSUM_GP_OFFSET; +"VSUM_GROUP",VSUM_GROUP; +"VSUM_IMAGE",VSUM_IMAGE; +"VSUM_IMAGE_GEN",VSUM_IMAGE_GEN; +"VSUM_IMAGE_NONZERO",VSUM_IMAGE_NONZERO; +"VSUM_INCL_EXCL",VSUM_INCL_EXCL; +"VSUM_INJECTION",VSUM_INJECTION; +"VSUM_LMUL",VSUM_LMUL; +"VSUM_NEG",VSUM_NEG; +"VSUM_NONZERO_IMAGE_LEMMA",VSUM_NONZERO_IMAGE_LEMMA; +"VSUM_NORM",VSUM_NORM; +"VSUM_NORM_ALLSUBSETS_BOUND",VSUM_NORM_ALLSUBSETS_BOUND; +"VSUM_NORM_BOUND",VSUM_NORM_BOUND; +"VSUM_NORM_LE",VSUM_NORM_LE; +"VSUM_NORM_TRIANGLE",VSUM_NORM_TRIANGLE; +"VSUM_OFFSET",VSUM_OFFSET; +"VSUM_OFFSET_0",VSUM_OFFSET_0; +"VSUM_OVER_TAGGED_DIVISION_LEMMA",VSUM_OVER_TAGGED_DIVISION_LEMMA; +"VSUM_OVER_TAGGED_PARTIAL_DIVISION_LEMMA",VSUM_OVER_TAGGED_PARTIAL_DIVISION_LEMMA; +"VSUM_PAIR",VSUM_PAIR; +"VSUM_PAIR_0",VSUM_PAIR_0; +"VSUM_PARTIAL_PRE",VSUM_PARTIAL_PRE; +"VSUM_PARTIAL_SUC",VSUM_PARTIAL_SUC; +"VSUM_REAL",VSUM_REAL; +"VSUM_RESTRICT",VSUM_RESTRICT; +"VSUM_RESTRICT_SET",VSUM_RESTRICT_SET; +"VSUM_RMUL",VSUM_RMUL; +"VSUM_SING",VSUM_SING; +"VSUM_SING_NUMSEG",VSUM_SING_NUMSEG; +"VSUM_SUB",VSUM_SUB; +"VSUM_SUB_NUMSEG",VSUM_SUB_NUMSEG; +"VSUM_SUC",VSUM_SUC; +"VSUM_SUPERSET",VSUM_SUPERSET; +"VSUM_SWAP",VSUM_SWAP; +"VSUM_SWAP_NUMSEG",VSUM_SWAP_NUMSEG; +"VSUM_TRIV_NUMSEG",VSUM_TRIV_NUMSEG; +"VSUM_UNION",VSUM_UNION; +"VSUM_UNIONS_NONZERO",VSUM_UNIONS_NONZERO; +"VSUM_UNION_LZERO",VSUM_UNION_LZERO; +"VSUM_UNION_NONZERO",VSUM_UNION_NONZERO; +"VSUM_UNION_RZERO",VSUM_UNION_RZERO; +"VSUM_VMUL",VSUM_VMUL; +"VSUM_VSUM_PRODUCT",VSUM_VSUM_PRODUCT; +"WF",WF; +"WF_DCHAIN",WF_DCHAIN; +"WF_EQ",WF_EQ; +"WF_EREC",WF_EREC; +"WF_FALSE",WF_FALSE; +"WF_FINITE",WF_FINITE; +"WF_IND",WF_IND; +"WF_INT_MEASURE",WF_INT_MEASURE; +"WF_INT_MEASURE_2",WF_INT_MEASURE_2; +"WF_LEX",WF_LEX; +"WF_LEX_DEPENDENT",WF_LEX_DEPENDENT; +"WF_MEASURE",WF_MEASURE; +"WF_MEASURE_GEN",WF_MEASURE_GEN; +"WF_POINTWISE",WF_POINTWISE; +"WF_REC",WF_REC; +"WF_REC_CASES",WF_REC_CASES; +"WF_REC_CASES'",WF_REC_CASES'; +"WF_REC_INVARIANT",WF_REC_INVARIANT; +"WF_REC_TAIL",WF_REC_TAIL; +"WF_REC_TAIL_GENERAL",WF_REC_TAIL_GENERAL; +"WF_REC_TAIL_GENERAL'",WF_REC_TAIL_GENERAL'; +"WF_REC_WF",WF_REC_WF; +"WF_REC_num",WF_REC_num; +"WF_REFL",WF_REFL; +"WF_SUBSET",WF_SUBSET; +"WF_UREC",WF_UREC; +"WF_UREC_WF",WF_UREC_WF; +"WF_num",WF_num; +"WINDING_NUMBER",WINDING_NUMBER; +"WINDING_NUMBER_AHLFORS",WINDING_NUMBER_AHLFORS; +"WINDING_NUMBER_AHLFORS_FULL",WINDING_NUMBER_AHLFORS_FULL; +"WINDING_NUMBER_AHLFORS_LEMMA",WINDING_NUMBER_AHLFORS_LEMMA; +"WINDING_NUMBER_AROUND_INSIDE",WINDING_NUMBER_AROUND_INSIDE; +"WINDING_NUMBER_AS_CONTINUOUS_LOGARITHM",WINDING_NUMBER_AS_CONTINUOUS_LOGARITHM; +"WINDING_NUMBER_BIG_MEETS",WINDING_NUMBER_BIG_MEETS; +"WINDING_NUMBER_CIRCLEPATH",WINDING_NUMBER_CIRCLEPATH; +"WINDING_NUMBER_COMPOSE_CEXP",WINDING_NUMBER_COMPOSE_CEXP; +"WINDING_NUMBER_CONSTANT",WINDING_NUMBER_CONSTANT; +"WINDING_NUMBER_EQ",WINDING_NUMBER_EQ; +"WINDING_NUMBER_EQUAL",WINDING_NUMBER_EQUAL; +"WINDING_NUMBER_EQ_1",WINDING_NUMBER_EQ_1; +"WINDING_NUMBER_FROM_INNERPATH",WINDING_NUMBER_FROM_INNERPATH; +"WINDING_NUMBER_HOMOTOPIC_LOOPS",WINDING_NUMBER_HOMOTOPIC_LOOPS; +"WINDING_NUMBER_HOMOTOPIC_LOOPS_EQ",WINDING_NUMBER_HOMOTOPIC_LOOPS_EQ; +"WINDING_NUMBER_HOMOTOPIC_LOOPS_NULL_EQ",WINDING_NUMBER_HOMOTOPIC_LOOPS_NULL_EQ; +"WINDING_NUMBER_HOMOTOPIC_PATHS",WINDING_NUMBER_HOMOTOPIC_PATHS; +"WINDING_NUMBER_HOMOTOPIC_PATHS_EQ",WINDING_NUMBER_HOMOTOPIC_PATHS_EQ; +"WINDING_NUMBER_HOMOTOPIC_PATHS_NULL_EQ",WINDING_NUMBER_HOMOTOPIC_PATHS_NULL_EQ; +"WINDING_NUMBER_HOMOTOPIC_PATHS_NULL_EXPLICIT_EQ",WINDING_NUMBER_HOMOTOPIC_PATHS_NULL_EXPLICIT_EQ; +"WINDING_NUMBER_IVT_ABS",WINDING_NUMBER_IVT_ABS; +"WINDING_NUMBER_IVT_NEG",WINDING_NUMBER_IVT_NEG; +"WINDING_NUMBER_IVT_POS",WINDING_NUMBER_IVT_POS; +"WINDING_NUMBER_JOIN",WINDING_NUMBER_JOIN; +"WINDING_NUMBER_JOIN_POS_COMBINED",WINDING_NUMBER_JOIN_POS_COMBINED; +"WINDING_NUMBER_LE_HALF",WINDING_NUMBER_LE_HALF; +"WINDING_NUMBER_LINEPATH_POS_LT",WINDING_NUMBER_LINEPATH_POS_LT; +"WINDING_NUMBER_LOOPS_LINEAR_EQ",WINDING_NUMBER_LOOPS_LINEAR_EQ; +"WINDING_NUMBER_LT_1",WINDING_NUMBER_LT_1; +"WINDING_NUMBER_LT_HALF",WINDING_NUMBER_LT_HALF; +"WINDING_NUMBER_LT_HALF_LINEPATH",WINDING_NUMBER_LT_HALF_LINEPATH; +"WINDING_NUMBER_NEARBY_LOOPS_EQ",WINDING_NUMBER_NEARBY_LOOPS_EQ; +"WINDING_NUMBER_NEARBY_PATHS_EQ",WINDING_NUMBER_NEARBY_PATHS_EQ; +"WINDING_NUMBER_OFFSET",WINDING_NUMBER_OFFSET; +"WINDING_NUMBER_PARTCIRCLEPATH_POS_LT",WINDING_NUMBER_PARTCIRCLEPATH_POS_LT; +"WINDING_NUMBER_PATHS_LINEAR_EQ",WINDING_NUMBER_PATHS_LINEAR_EQ; +"WINDING_NUMBER_POS_LE",WINDING_NUMBER_POS_LE; +"WINDING_NUMBER_POS_LT",WINDING_NUMBER_POS_LT; +"WINDING_NUMBER_POS_LT_LEMMA",WINDING_NUMBER_POS_LT_LEMMA; +"WINDING_NUMBER_POS_MEETS",WINDING_NUMBER_POS_MEETS; +"WINDING_NUMBER_REVERSEPATH",WINDING_NUMBER_REVERSEPATH; +"WINDING_NUMBER_SHIFTPATH",WINDING_NUMBER_SHIFTPATH; +"WINDING_NUMBER_SPLIT_LINEPATH",WINDING_NUMBER_SPLIT_LINEPATH; +"WINDING_NUMBER_STRONG",WINDING_NUMBER_STRONG; +"WINDING_NUMBER_SUBPATH_COMBINE",WINDING_NUMBER_SUBPATH_COMBINE; +"WINDING_NUMBER_SUBPATH_CONTINUOUS",WINDING_NUMBER_SUBPATH_CONTINUOUS; +"WINDING_NUMBER_TRIANGLE",WINDING_NUMBER_TRIANGLE; +"WINDING_NUMBER_TRIVIAL",WINDING_NUMBER_TRIVIAL; +"WINDING_NUMBER_UNIQUE",WINDING_NUMBER_UNIQUE; +"WINDING_NUMBER_UNIQUE_LOOP",WINDING_NUMBER_UNIQUE_LOOP; +"WINDING_NUMBER_VALID_PATH",WINDING_NUMBER_VALID_PATH; +"WINDING_NUMBER_ZERO_ATINFINITY",WINDING_NUMBER_ZERO_ATINFINITY; +"WINDING_NUMBER_ZERO_IN_OUTSIDE",WINDING_NUMBER_ZERO_IN_OUTSIDE; +"WINDING_NUMBER_ZERO_OUTSIDE",WINDING_NUMBER_ZERO_OUTSIDE; +"WINDING_NUMBER_ZERO_POINT",WINDING_NUMBER_ZERO_POINT; +"WITHIN",WITHIN; +"WITHINREAL_UNIV",WITHINREAL_UNIV; +"WITHIN_UNIV",WITHIN_UNIV; +"WITHIN_WITHIN",WITHIN_WITHIN; +"WLOG_LE",WLOG_LE; +"WLOG_LINEAR_INJECTIVE_IMAGE",WLOG_LINEAR_INJECTIVE_IMAGE; +"WLOG_LINEAR_INJECTIVE_IMAGE_2",WLOG_LINEAR_INJECTIVE_IMAGE_2; +"WLOG_LINEAR_INJECTIVE_IMAGE_2_ALT",WLOG_LINEAR_INJECTIVE_IMAGE_2_ALT; +"WLOG_LINEAR_INJECTIVE_IMAGE_ALT",WLOG_LINEAR_INJECTIVE_IMAGE_ALT; +"WLOG_LT",WLOG_LT; +"WO",WO; +"WOSET",WOSET; +"WOSET_ANTISYM",WOSET_ANTISYM; +"WOSET_FLEQ",WOSET_FLEQ; +"WOSET_POSET",WOSET_POSET; +"WOSET_REFL",WOSET_REFL; +"WOSET_TOTAL",WOSET_TOTAL; +"WOSET_TOTAL_LE",WOSET_TOTAL_LE; +"WOSET_TOTAL_LT",WOSET_TOTAL_LT; +"WOSET_TRANS",WOSET_TRANS; +"WOSET_TRANS_LE",WOSET_TRANS_LE; +"WOSET_TRANS_LESS",WOSET_TRANS_LESS; +"WOSET_WELL",WOSET_WELL; +"WOSET_WELL_CONTRAPOS",WOSET_WELL_CONTRAPOS; +"ZBOT",ZBOT; +"ZCONSTR",ZCONSTR; +"ZCONSTR_ZBOT",ZCONSTR_ZBOT; +"ZERO_DEF",ZERO_DEF; +"ZIP",ZIP; +"ZIP_DEF",ZIP_DEF; +"ZL",ZL; +"ZL_SUBSETS",ZL_SUBSETS; +"ZL_SUBSETS_UNIONS",ZL_SUBSETS_UNIONS; +"ZL_SUBSETS_UNIONS_NONEMPTY",ZL_SUBSETS_UNIONS_NONEMPTY; +"ZRECSPACE_CASES",ZRECSPACE_CASES; +"ZRECSPACE_INDUCT",ZRECSPACE_INDUCT; +"ZRECSPACE_RULES",ZRECSPACE_RULES; +"_FALSITY_",_FALSITY_; +"_FUNCTION",_FUNCTION; +"_GUARDED_PATTERN",_GUARDED_PATTERN; +"_MATCH",_MATCH; +"_SEQPATTERN",_SEQPATTERN; +"_UNGUARDED_PATTERN",_UNGUARDED_PATTERN; +"absolutely_integrable_on",absolutely_integrable_on; +"absolutely_real_integrable_on",absolutely_real_integrable_on; +"acs",acs; +"add_c",add_c; +"adjoint",adjoint; +"admissible",admissible; +"aff_dim",aff_dim; +"affine",affine; +"affine_dependent",affine_dependent; +"analytic_on",analytic_on; +"arc",arc; +"asn",asn; +"at",at; +"at_infinity",at_infinity; +"at_neginfinity",at_neginfinity; +"at_posinfinity",at_posinfinity; +"atn",atn; +"atreal",atreal; +"ball",ball; +"basis",basis; +"bernstein",bernstein; +"between",between; +"bilinear",bilinear; +"binarysum",binarysum; +"binom",binom; +"bitset",bitset; +"bool_INDUCT",bool_INDUCT; +"bool_RECURSION",bool_RECURSION; +"bounded",bounded; +"cacs",cacs; +"cart_tybij",cart_tybij; +"casn",casn; +"catn",catn; +"cauchy",cauchy; +"cball",cball; +"ccos",ccos; +"cexp",cexp; +"chain",chain; +"char_INDUCT",char_INDUCT; +"char_RECURSION",char_RECURSION; +"circlepath",circlepath; +"clog",clog; +"closed",closed; +"closed_in",closed_in; +"closed_interval",closed_interval; +"closed_path",closed_path; +"closed_real_interval",closed_real_interval; +"closed_real_segment",closed_real_segment; +"closed_segment",closed_segment; +"closest_point",closest_point; +"closure",closure; +"cnj",cnj; +"codeset",codeset; +"cofactor",cofactor; +"collinear",collinear; +"column",column; +"columns",columns; +"columnvector",columnvector; +"compact",compact; +"complete",complete; +"complex",complex; +"complex_add",complex_add; +"complex_derivative",complex_derivative; +"complex_differentiable",complex_differentiable; +"complex_div",complex_div; +"complex_integer",complex_integer; +"complex_inv",complex_inv; +"complex_mul",complex_mul; +"complex_neg",complex_neg; +"complex_norm",complex_norm; +"complex_pow",complex_pow; +"complex_sub",complex_sub; +"components",components; +"condensation_point_of",condensation_point_of; +"cong",cong; +"conic",conic; +"connected",connected; +"connected_component",connected_component; +"content",content; +"continuous",continuous; +"continuous_at",continuous_at; +"continuous_atreal",continuous_atreal; +"continuous_on",continuous_on; +"continuous_within",continuous_within; +"continuous_withinreal",continuous_withinreal; +"contractible",contractible; +"convex",convex; +"convex_cone",convex_cone; +"convex_on",convex_on; +"coplanar",coplanar; +"cos",cos; +"covering_space",covering_space; +"cpow",cpow; +"cproduct",cproduct; +"csin",csin; +"csqrt",csqrt; +"ctan",ctan; +"dependent",dependent; +"dest_int_rep",dest_int_rep; +"det",det; +"diagonal_matrix",diagonal_matrix; +"diameter",diameter; +"differentiable",differentiable; +"differentiable_on",differentiable_on; +"dim",dim; +"dimindex",dimindex; +"dist",dist; +"division_of",division_of; +"division_points",division_points; +"dot",dot; +"drop",drop; +"dropout",dropout; +"edge_of",edge_of; +"epigraph",epigraph; +"eq_c",eq_c; +"equiintegrable_on",equiintegrable_on; +"euclidean",euclidean; +"euclideanreal",euclideanreal; +"evenperm",evenperm; +"eventually",eventually; +"exp",exp; +"exposed_face_of",exposed_face_of; +"extreme_point_of",extreme_point_of; +"face_of",face_of; +"facet_of",facet_of; +"fine",fine; +"finite_image_tybij",finite_image_tybij; +"finite_index",finite_index; +"finite_sum_tybij",finite_sum_tybij; +"fl",fl; +"frechet_derivative",frechet_derivative; +"from",from; +"frontier",frontier; +"fstcart",fstcart; +"gauge",gauge; +"ge_c",ge_c; +"geom_mul",geom_mul; +"grade",grade; +"gt_c",gt_c; +"has_bounded_real_variation_on",has_bounded_real_variation_on; +"has_bounded_setvariation_on",has_bounded_setvariation_on; +"has_bounded_variation_on",has_bounded_variation_on; +"has_complex_derivative",has_complex_derivative; +"has_derivative",has_derivative; +"has_derivative_at",has_derivative_at; +"has_derivative_within",has_derivative_within; +"has_integral",has_integral; +"has_integral_alt",has_integral_alt; +"has_integral_compact_interval",has_integral_compact_interval; +"has_integral_def",has_integral_def; +"has_measure",has_measure; +"has_path_integral",has_path_integral; +"has_real_derivative",has_real_derivative; +"has_real_integral",has_real_integral; +"has_real_measure",has_real_measure; +"has_vector_derivative",has_vector_derivative; +"higher_complex_derivative",higher_complex_derivative; +"higher_complex_derivative_alt",higher_complex_derivative_alt; +"higher_real_derivative",higher_real_derivative; +"holomorphic_on",holomorphic_on; +"homeomorphic",homeomorphic; +"homeomorphism",homeomorphism; +"homotopic_loops",homotopic_loops; +"homotopic_paths",homotopic_paths; +"homotopic_with",homotopic_with; +"homotopy_equivalent",homotopy_equivalent; +"hreal_add",hreal_add; +"hreal_add_th",hreal_add_th; +"hreal_inv",hreal_inv; +"hreal_inv_th",hreal_inv_th; +"hreal_le",hreal_le; +"hreal_le_th",hreal_le_th; +"hreal_mul",hreal_mul; +"hreal_mul_th",hreal_mul_th; +"hreal_of_num",hreal_of_num; +"hreal_of_num_th",hreal_of_num_th; +"hull",hull; +"ii",ii; +"in_direction",in_direction; +"independent",independent; +"indicator",indicator; +"inf",inf; +"infnorm",infnorm; +"infsum",infsum; +"inner",inner; +"inseg",inseg; +"inside",inside; +"int_abs",int_abs; +"int_abs_th",int_abs_th; +"int_abstr",int_abstr; +"int_add",int_add; +"int_add_th",int_add_th; +"int_congruent",int_congruent; +"int_coprime",int_coprime; +"int_divides",int_divides; +"int_eq",int_eq; +"int_gcd",int_gcd; +"int_ge",int_ge; +"int_gt",int_gt; +"int_le",int_le; +"int_lt",int_lt; +"int_max",int_max; +"int_max_th",int_max_th; +"int_min",int_min; +"int_min_th",int_min_th; +"int_mod",int_mod; +"int_mul",int_mul; +"int_mul_th",int_mul_th; +"int_neg",int_neg; +"int_neg_th",int_neg_th; +"int_of_num",int_of_num; +"int_of_num_th",int_of_num_th; +"int_pow",int_pow; +"int_pow_th",int_pow_th; +"int_rep",int_rep; +"int_sgn",int_sgn; +"int_sgn_th",int_sgn_th; +"int_sub",int_sub; +"int_sub_th",int_sub_th; +"int_tybij",int_tybij; +"integer",integer; +"integrable_on",integrable_on; +"integral",integral; +"interior",interior; +"interval",interval; +"interval_bij",interval_bij; +"interval_lowerbound",interval_lowerbound; +"interval_upperbound",interval_upperbound; +"inverse",inverse; +"invertible",invertible; +"is_int",is_int; +"is_interval",is_interval; +"is_nadd",is_nadd; +"is_nadd_0",is_nadd_0; +"is_realinterval",is_realinterval; +"istopology",istopology; +"iterate",iterate; +"jacobian",jacobian; +"joinpaths",joinpaths; +"kle",kle; +"ksimplex",ksimplex; +"lambda",lambda; +"lambdas",lambdas; +"le_c",le_c; +"lebesgue_measurable",lebesgue_measurable; +"lemma",lemma; +"less",less; +"lift",lift; +"lifted",lifted; +"lim",lim; +"limit_point_of",limit_point_of; +"linear",linear; +"linepath",linepath; +"linseg",linseg; +"list_CASES",list_CASES; +"list_INDUCT",list_INDUCT; +"list_RECURSION",list_RECURSION; +"list_of_set",list_of_set; +"locally",locally; +"log_def",log_def; +"lt_c",lt_c; +"mat",mat; +"matrix",matrix; +"matrix_add",matrix_add; +"matrix_cmul",matrix_cmul; +"matrix_inv",matrix_inv; +"matrix_mul",matrix_mul; +"matrix_neg",matrix_neg; +"matrix_sub",matrix_sub; +"matrix_vector_mul",matrix_vector_mul; +"mbasis",mbasis; +"measurable",measurable; +"measurable_on",measurable_on; +"measure",measure; +"midpoint",midpoint; +"minimal",minimal; +"mk_pair_def",mk_pair_def; +"moebius_function",moebius_function; +"monoidal",monoidal; +"mul_c",mul_c; +"multivec",multivec; +"multivector",multivector; +"multivector_tybij",multivector_tybij; +"multivector_tybij_th",multivector_tybij_th; +"nadd_abs",nadd_abs; +"nadd_add",nadd_add; +"nadd_eq",nadd_eq; +"nadd_inv",nadd_inv; +"nadd_le",nadd_le; +"nadd_mul",nadd_mul; +"nadd_of_num",nadd_of_num; +"nadd_rep",nadd_rep; +"nadd_rinv",nadd_rinv; +"negligible",negligible; +"net_tybij",net_tybij; +"netlimit",netlimit; +"neutral",neutral; +"nsum",nsum; +"num_Axiom",num_Axiom; +"num_CASES",num_CASES; +"num_FINITE",num_FINITE; +"num_FINITE_AVOID",num_FINITE_AVOID; +"num_INDUCTION",num_INDUCTION; +"num_INFINITE",num_INFINITE; +"num_MAX",num_MAX; +"num_RECURSION",num_RECURSION; +"num_RECURSION_STD",num_RECURSION_STD; +"num_WF",num_WF; +"num_WOP",num_WOP; +"num_congruent",num_congruent; +"num_coprime",num_coprime; +"num_divides",num_divides; +"num_gcd",num_gcd; +"num_mod",num_mod; +"num_of_int",num_of_int; +"numseg",numseg; +"o_ASSOC",o_ASSOC; +"o_DEF",o_DEF; +"o_THM",o_THM; +"one",one; +"one_Axiom",one_Axiom; +"one_DEF",one_DEF; +"one_INDUCT",one_INDUCT; +"one_RECURSION",one_RECURSION; +"one_axiom",one_axiom; +"one_tydef",one_tydef; +"onorm",onorm; +"open_def",open_def; +"open_in",open_in; +"open_interval",open_interval; +"open_real_interval",open_real_interval; +"open_real_segment",open_real_segment; +"open_segment",open_segment; +"operative",operative; +"option_INDUCT",option_INDUCT; +"option_RECURSION",option_RECURSION; +"ordinal",ordinal; +"orthogonal",orthogonal; +"orthogonal_matrix",orthogonal_matrix; +"orthogonal_transformation",orthogonal_transformation; +"outer",outer; +"outermorphism",outermorphism; +"outside",outside; +"pair_INDUCT",pair_INDUCT; +"pair_RECURSION",pair_RECURSION; +"pairwise",pairwise; +"partcirclepath",partcirclepath; +"pastecart",pastecart; +"path",path; +"path_component",path_component; +"path_connected",path_connected; +"path_image",path_image; +"path_integrable_on",path_integrable_on; +"path_integral",path_integral; +"path_length",path_length; +"pathfinish",pathfinish; +"pathstart",pathstart; +"permutation",permutation; +"permutes",permutes; +"pi",pi; +"piecewise_differentiable_on",piecewise_differentiable_on; +"polyhedron",polyhedron; +"polytope",polytope; +"poset",poset; +"prod_tybij",prod_tybij; +"product",product; +"pushin",pushin; +"rank",rank; +"rational",rational; +"real",real; +"real_INFINITE",real_INFINITE; +"real_abs",real_abs; +"real_add",real_add; +"real_add_th",real_add_th; +"real_bounded",real_bounded; +"real_closed",real_closed; +"real_compact",real_compact; +"real_continuous",real_continuous; +"real_continuous_at",real_continuous_at; +"real_continuous_atreal",real_continuous_atreal; +"real_continuous_on",real_continuous_on; +"real_continuous_within",real_continuous_within; +"real_continuous_withinreal",real_continuous_withinreal; +"real_convex_on",real_convex_on; +"real_derivative",real_derivative; +"real_differentiable",real_differentiable; +"real_differentiable_on",real_differentiable_on; +"real_div",real_div; +"real_ge",real_ge; +"real_gt",real_gt; +"real_infsum",real_infsum; +"real_integrable_on",real_integrable_on; +"real_integral",real_integral; +"real_interval",real_interval; +"real_inv",real_inv; +"real_inv_th",real_inv_th; +"real_le",real_le; +"real_le_th",real_le_th; +"real_lebesgue_measurable",real_lebesgue_measurable; +"real_lt",real_lt; +"real_max",real_max; +"real_measurable",real_measurable; +"real_measurable_on",real_measurable_on; +"real_measure",real_measure; +"real_min",real_min; +"real_mod",real_mod; +"real_mul",real_mul; +"real_mul_th",real_mul_th; +"real_neg",real_neg; +"real_neg_th",real_neg_th; +"real_negligible",real_negligible; +"real_of_num",real_of_num; +"real_of_num_th",real_of_num_th; +"real_open",real_open; +"real_polynomial_function_CASES",real_polynomial_function_CASES; +"real_polynomial_function_INDUCT",real_polynomial_function_INDUCT; +"real_polynomial_function_RULES",real_polynomial_function_RULES; +"real_pow",real_pow; +"real_segment",real_segment; +"real_sgn",real_sgn; +"real_sub",real_sub; +"real_summable",real_summable; +"real_sums",real_sums; +"real_uniformly_continuous_on",real_uniformly_continuous_on; +"real_variation",real_variation; +"reallim",reallim; +"rectifiable_path",rectifiable_path; +"reduced",reduced; +"reflect_along",reflect_along; +"relative_frontier",relative_frontier; +"relative_interior",relative_interior; +"retract_of",retract_of; +"retraction",retraction; +"reversepath",reversepath; +"reversion",reversion; +"root",root; +"rotate2d",rotate2d; +"rotation_matrix",rotation_matrix; +"rotoinversion_matrix",rotoinversion_matrix; +"row",row; +"rows",rows; +"rowvector",rowvector; +"rpow",rpow; +"segment",segment; +"seqiterate",seqiterate; +"seqiterate_EXISTS",seqiterate_EXISTS; +"sequentially",sequentially; +"set_of_list",set_of_list; +"set_variation",set_variation; +"setcode",setcode; +"setdist",setdist; +"shiftpath",shiftpath; +"sign",sign; +"simple_path",simple_path; +"simplex",simplex; +"simplicial_complex",simplicial_complex; +"simply_connected",simply_connected; +"sin",sin; +"sindex",sindex; +"slice",slice; +"sndcart",sndcart; +"span",span; +"sphere",sphere; +"sqrt",sqrt; +"starlike",starlike; +"string_INFINITE",string_INFINITE; +"subpath",subpath; +"subspace",subspace; +"subtopology",subtopology; +"sum",sum; +"sum_CASES",sum_CASES; +"sum_DISTINCT",sum_DISTINCT; +"sum_INDUCT",sum_INDUCT; +"sum_INJECTIVE",sum_INJECTIVE; +"sum_RECURSION",sum_RECURSION; +"summable",summable; +"sums",sums; +"sup",sup; +"superadmissible",superadmissible; +"support",support; +"swap",swap; +"swapseq_CASES",swapseq_CASES; +"swapseq_INDUCT",swapseq_INDUCT; +"swapseq_RULES",swapseq_RULES; +"tagged_division_of",tagged_division_of; +"tagged_partial_division_of",tagged_partial_division_of; +"tailadmissible",tailadmissible; +"tan",tan; +"tan_def",tan_def; +"tendsto",tendsto; +"tendsto_real",tendsto_real; +"topology_tybij",topology_tybij; +"topology_tybij_th",topology_tybij_th; +"topspace",topspace; +"toset",toset; +"trace",trace; +"transp",transp; +"treal_add",treal_add; +"treal_eq",treal_eq; +"treal_inv",treal_inv; +"treal_le",treal_le; +"treal_mul",treal_mul; +"treal_neg",treal_neg; +"treal_of_num",treal_of_num; +"triangulation",triangulation; +"trivial_limit",trivial_limit; +"uniformly_continuous_on",uniformly_continuous_on; +"unwinding",unwinding; +"valid_path",valid_path; +"vec",vec; +"vector",vector; +"vector_add",vector_add; +"vector_derivative",vector_derivative; +"vector_matrix_mul",vector_matrix_mul; +"vector_mul",vector_mul; +"vector_neg",vector_neg; +"vector_norm",vector_norm; +"vector_polynomial_function",vector_polynomial_function; +"vector_sub",vector_sub; +"vector_variation",vector_variation; +"vsum",vsum; +"winding_number",winding_number; +"within",within; +"woset",woset +];; diff --git a/Multivariate/complexes.ml b/Multivariate/complexes.ml new file mode 100644 index 0000000..615b0df --- /dev/null +++ b/Multivariate/complexes.ml @@ -0,0 +1,1944 @@ +(* ========================================================================= *) +(* The type "real^2" regarded as the complex numbers. *) +(* *) +(* (c) Copyright, John Harrison 1998-2008 *) +(* (c) Copyright, Valentina Bruno 2010 *) +(* ========================================================================= *) + +needs "Multivariate/integration.ml";; + +new_type_abbrev("complex",`:real^2`);; + +let prioritize_complex() = + overload_interface("--",`vector_neg:complex->complex`); + overload_interface("+",`vector_add:complex->complex->complex`); + overload_interface("-",`vector_sub:complex->complex->complex`); + overload_interface("*",`complex_mul:complex->complex->complex`); + overload_interface("/",`complex_div:complex->complex->complex`); + overload_interface("pow",`complex_pow:complex->num->complex`); + overload_interface("inv",`complex_inv:complex->complex`);; + +prioritize_complex();; + +(* ------------------------------------------------------------------------- *) +(* Real and imaginary parts of a number. *) +(* ------------------------------------------------------------------------- *) + +let RE_DEF = new_definition + `Re(z:complex) = z$1`;; + +let IM_DEF = new_definition + `Im(z:complex) = z$2`;; + +(* ------------------------------------------------------------------------- *) +(* Real injection and imaginary unit. *) +(* ------------------------------------------------------------------------- *) + +let complex = new_definition + `complex(x,y) = vector[x;y]:complex`;; + +let CX_DEF = new_definition + `Cx(a) = complex(a,&0)`;; + +let ii = new_definition + `ii = complex(&0,&1)`;; + +(* ------------------------------------------------------------------------- *) +(* Complex multiplication. *) +(* ------------------------------------------------------------------------- *) + +let complex_mul = new_definition + `w * z = complex(Re(w) * Re(z) - Im(w) * Im(z), + Re(w) * Im(z) + Im(w) * Re(z))`;; + +let complex_inv = new_definition + `inv(z) = complex(Re(z) / (Re(z) pow 2 + Im(z) pow 2), + --(Im(z)) / (Re(z) pow 2 + Im(z) pow 2))`;; + +let complex_div = new_definition + `w / z = w * inv(z)`;; + +let complex_pow = define + `(x pow 0 = Cx(&1)) /\ + (!n. x pow (SUC n) = x * x pow n)`;; + +(* ------------------------------------------------------------------------- *) +(* Various handy rewrites. *) +(* ------------------------------------------------------------------------- *) + +let RE = prove + (`(Re(complex(x,y)) = x)`, + REWRITE_TAC[RE_DEF; complex; VECTOR_2]);; + +let IM = prove + (`Im(complex(x,y)) = y`, + REWRITE_TAC[IM_DEF; complex; VECTOR_2]);; + +let COMPLEX_EQ = prove + (`!w z. (w = z) <=> (Re(w) = Re(z)) /\ (Im(w) = Im(z))`, + SIMP_TAC[CART_EQ; FORALL_2; DIMINDEX_2; RE_DEF; IM_DEF]);; + +let COMPLEX = prove + (`!z. complex(Re(z),Im(z)) = z`, + REWRITE_TAC[COMPLEX_EQ; RE; IM]);; + +let COMPLEX_EQ_0 = prove + (`z = Cx(&0) <=> Re(z) pow 2 + Im(z) pow 2 = &0`, + REWRITE_TAC[COMPLEX_EQ; CX_DEF; RE; IM] THEN + EQ_TAC THEN SIMP_TAC[] THEN CONV_TAC REAL_RAT_REDUCE_CONV THEN + DISCH_THEN(MP_TAC o MATCH_MP (REAL_ARITH + `!x y:real. x + y = &0 ==> &0 <= x /\ &0 <= y ==> x = &0 /\ y = &0`)) THEN + REWRITE_TAC[REAL_POW_2; REAL_LE_SQUARE; REAL_ENTIRE]);; + +let FORALL_COMPLEX = prove + (`(!z. P z) <=> (!x y. P(complex(x,y)))`, + MESON_TAC[COMPLEX]);; + +let EXISTS_COMPLEX = prove + (`(?z. P z) <=> (?x y. P(complex(x,y)))`, + MESON_TAC[COMPLEX]);; + +(* ------------------------------------------------------------------------- *) +(* Pseudo-definitions of other general vector concepts over R^2. *) +(* ------------------------------------------------------------------------- *) + +let complex_neg = prove + (`--z = complex(--(Re(z)),--(Im(z)))`, + REWRITE_TAC[COMPLEX_EQ; RE; IM] THEN REWRITE_TAC[RE_DEF; IM_DEF] THEN + SIMP_TAC[VECTOR_NEG_COMPONENT; DIMINDEX_2; ARITH]);; + +let complex_add = prove + (`w + z = complex(Re(w) + Re(z),Im(w) + Im(z))`, + REWRITE_TAC[COMPLEX_EQ; RE; IM] THEN REWRITE_TAC[RE_DEF; IM_DEF] THEN + SIMP_TAC[VECTOR_ADD_COMPONENT; DIMINDEX_2; ARITH]);; + +let complex_sub = VECTOR_ARITH `(w:complex) - z = w + --z`;; + +let complex_norm = prove + (`norm(z) = sqrt(Re(z) pow 2 + Im(z) pow 2)`, + REWRITE_TAC[vector_norm; dot; RE_DEF; IM_DEF; SUM_2; DIMINDEX_2] THEN + AP_TERM_TAC THEN REAL_ARITH_TAC);; + +let COMPLEX_SQNORM = prove + (`norm(z) pow 2 = Re(z) pow 2 + Im(z) pow 2`, + REWRITE_TAC[NORM_POW_2; dot; RE_DEF; IM_DEF; SUM_2; DIMINDEX_2] THEN + REAL_ARITH_TAC);; + +(* ------------------------------------------------------------------------- *) +(* Crude tactic to automate very simple algebraic equivalences. *) +(* ------------------------------------------------------------------------- *) + +let SIMPLE_COMPLEX_ARITH_TAC = + REWRITE_TAC[COMPLEX_EQ; RE; IM; CX_DEF; + complex_add; complex_neg; complex_sub; complex_mul; + complex_inv; complex_div] THEN + CONV_TAC REAL_FIELD;; + +let SIMPLE_COMPLEX_ARITH tm = prove(tm,SIMPLE_COMPLEX_ARITH_TAC);; + +(* ------------------------------------------------------------------------- *) +(* Basic algebraic properties that can be proved automatically by this. *) +(* ------------------------------------------------------------------------- *) + +let COMPLEX_ADD_SYM = prove + (`!x y. x + y = y + x`, + SIMPLE_COMPLEX_ARITH_TAC);; + +let COMPLEX_ADD_ASSOC = prove + (`!x y z. x + y + z = (x + y) + z`, + SIMPLE_COMPLEX_ARITH_TAC);; + +let COMPLEX_ADD_LID = prove + (`!x. Cx(&0) + x = x`, + SIMPLE_COMPLEX_ARITH_TAC);; + +let COMPLEX_ADD_LINV = prove + (`!x. --x + x = Cx(&0)`, + SIMPLE_COMPLEX_ARITH_TAC);; + +let COMPLEX_MUL_SYM = prove + (`!x y. x * y = y * x`, + SIMPLE_COMPLEX_ARITH_TAC);; + +let COMPLEX_MUL_ASSOC = prove + (`!x y z. x * y * z = (x * y) * z`, + SIMPLE_COMPLEX_ARITH_TAC);; + +let COMPLEX_MUL_LID = prove + (`!x. Cx(&1) * x = x`, + SIMPLE_COMPLEX_ARITH_TAC);; + +let COMPLEX_ADD_LDISTRIB = prove + (`!x y z. x * (y + z) = x * y + x * z`, + SIMPLE_COMPLEX_ARITH_TAC);; + +let COMPLEX_ADD_AC = prove + (`(m + n = n + m) /\ ((m + n) + p = m + n + p) /\ (m + n + p = n + m + p)`, + SIMPLE_COMPLEX_ARITH_TAC);; + +let COMPLEX_MUL_AC = prove + (`(m * n = n * m) /\ ((m * n) * p = m * n * p) /\ (m * n * p = n * m * p)`, + SIMPLE_COMPLEX_ARITH_TAC);; + +let COMPLEX_ADD_RID = prove + (`!x. x + Cx(&0) = x`, + SIMPLE_COMPLEX_ARITH_TAC);; + +let COMPLEX_MUL_RID = prove + (`!x. x * Cx(&1) = x`, + SIMPLE_COMPLEX_ARITH_TAC);; + +let COMPLEX_ADD_RINV = prove + (`!x. x + --x = Cx(&0)`, + SIMPLE_COMPLEX_ARITH_TAC);; + +let COMPLEX_ADD_RDISTRIB = prove + (`!x y z. (x + y) * z = x * z + y * z`, + SIMPLE_COMPLEX_ARITH_TAC);; + +let COMPLEX_EQ_ADD_LCANCEL = prove + (`!x y z. (x + y = x + z) <=> (y = z)`, + SIMPLE_COMPLEX_ARITH_TAC);; + +let COMPLEX_EQ_ADD_RCANCEL = prove + (`!x y z. (x + z = y + z) <=> (x = y)`, + SIMPLE_COMPLEX_ARITH_TAC);; + +let COMPLEX_MUL_RZERO = prove + (`!x. x * Cx(&0) = Cx(&0)`, + SIMPLE_COMPLEX_ARITH_TAC);; + +let COMPLEX_MUL_LZERO = prove + (`!x. Cx(&0) * x = Cx(&0)`, + SIMPLE_COMPLEX_ARITH_TAC);; + +let COMPLEX_NEG_NEG = prove + (`!x. --(--x) = x`, + SIMPLE_COMPLEX_ARITH_TAC);; + +let COMPLEX_MUL_RNEG = prove + (`!x y. x * --y = --(x * y)`, + SIMPLE_COMPLEX_ARITH_TAC);; + +let COMPLEX_MUL_LNEG = prove + (`!x y. --x * y = --(x * y)`, + SIMPLE_COMPLEX_ARITH_TAC);; + +let COMPLEX_NEG_ADD = prove + (`!x y. --(x + y) = --x + --y`, + SIMPLE_COMPLEX_ARITH_TAC);; + +let COMPLEX_NEG_0 = prove + (`--Cx(&0) = Cx(&0)`, + SIMPLE_COMPLEX_ARITH_TAC);; + +let COMPLEX_EQ_ADD_LCANCEL_0 = prove + (`!x y. (x + y = x) <=> (y = Cx(&0))`, + SIMPLE_COMPLEX_ARITH_TAC);; + +let COMPLEX_EQ_ADD_RCANCEL_0 = prove + (`!x y. (x + y = y) <=> (x = Cx(&0))`, + SIMPLE_COMPLEX_ARITH_TAC);; + +let COMPLEX_LNEG_UNIQ = prove + (`!x y. (x + y = Cx(&0)) <=> (x = --y)`, + SIMPLE_COMPLEX_ARITH_TAC);; + +let COMPLEX_RNEG_UNIQ = prove + (`!x y. (x + y = Cx(&0)) <=> (y = --x)`, + SIMPLE_COMPLEX_ARITH_TAC);; + +let COMPLEX_NEG_LMUL = prove + (`!x y. --(x * y) = --x * y`, + SIMPLE_COMPLEX_ARITH_TAC);; + +let COMPLEX_NEG_RMUL = prove + (`!x y. --(x * y) = x * --y`, + SIMPLE_COMPLEX_ARITH_TAC);; + +let COMPLEX_NEG_MUL2 = prove + (`!x y. --x * --y = x * y`, + SIMPLE_COMPLEX_ARITH_TAC);; + +let COMPLEX_SUB_ADD = prove + (`!x y. x - y + y = x`, + SIMPLE_COMPLEX_ARITH_TAC);; + +let COMPLEX_SUB_ADD2 = prove + (`!x y. y + x - y = x`, + SIMPLE_COMPLEX_ARITH_TAC);; + +let COMPLEX_SUB_REFL = prove + (`!x. x - x = Cx(&0)`, + SIMPLE_COMPLEX_ARITH_TAC);; + +let COMPLEX_SUB_0 = prove + (`!x y. (x - y = Cx(&0)) <=> (x = y)`, + SIMPLE_COMPLEX_ARITH_TAC);; + +let COMPLEX_NEG_EQ_0 = prove + (`!x. (--x = Cx(&0)) <=> (x = Cx(&0))`, + SIMPLE_COMPLEX_ARITH_TAC);; + +let COMPLEX_NEG_SUB = prove + (`!x y. --(x - y) = y - x`, + SIMPLE_COMPLEX_ARITH_TAC);; + +let COMPLEX_ADD_SUB = prove + (`!x y. (x + y) - x = y`, + SIMPLE_COMPLEX_ARITH_TAC);; + +let COMPLEX_NEG_EQ = prove + (`!x y. (--x = y) <=> (x = --y)`, + SIMPLE_COMPLEX_ARITH_TAC);; + +let COMPLEX_NEG_MINUS1 = prove + (`!x. --x = --Cx(&1) * x`, + SIMPLE_COMPLEX_ARITH_TAC);; + +let COMPLEX_SUB_SUB = prove + (`!x y. x - y - x = --y`, + SIMPLE_COMPLEX_ARITH_TAC);; + +let COMPLEX_ADD2_SUB2 = prove + (`!a b c d. (a + b) - (c + d) = a - c + b - d`, + SIMPLE_COMPLEX_ARITH_TAC);; + +let COMPLEX_SUB_LZERO = prove + (`!x. Cx(&0) - x = --x`, + SIMPLE_COMPLEX_ARITH_TAC);; + +let COMPLEX_SUB_RZERO = prove + (`!x. x - Cx(&0) = x`, + SIMPLE_COMPLEX_ARITH_TAC);; + +let COMPLEX_SUB_LNEG = prove + (`!x y. --x - y = --(x + y)`, + SIMPLE_COMPLEX_ARITH_TAC);; + +let COMPLEX_SUB_RNEG = prove + (`!x y. x - --y = x + y`, + SIMPLE_COMPLEX_ARITH_TAC);; + +let COMPLEX_SUB_NEG2 = prove + (`!x y. --x - --y = y - x`, + SIMPLE_COMPLEX_ARITH_TAC);; + +let COMPLEX_SUB_TRIANGLE = prove + (`!a b c. a - b + b - c = a - c`, + SIMPLE_COMPLEX_ARITH_TAC);; + +let COMPLEX_EQ_SUB_LADD = prove + (`!x y z. (x = y - z) <=> (x + z = y)`, + SIMPLE_COMPLEX_ARITH_TAC);; + +let COMPLEX_EQ_SUB_RADD = prove + (`!x y z. (x - y = z) <=> (x = z + y)`, + SIMPLE_COMPLEX_ARITH_TAC);; + +let COMPLEX_SUB_SUB2 = prove + (`!x y. x - (x - y) = y`, + SIMPLE_COMPLEX_ARITH_TAC);; + +let COMPLEX_ADD_SUB2 = prove + (`!x y. x - (x + y) = --y`, + SIMPLE_COMPLEX_ARITH_TAC);; + +let COMPLEX_DIFFSQ = prove + (`!x y. (x + y) * (x - y) = x * x - y * y`, + SIMPLE_COMPLEX_ARITH_TAC);; + +let COMPLEX_EQ_NEG2 = prove + (`!x y. (--x = --y) <=> (x = y)`, + SIMPLE_COMPLEX_ARITH_TAC);; + +let COMPLEX_SUB_LDISTRIB = prove + (`!x y z. x * (y - z) = x * y - x * z`, + SIMPLE_COMPLEX_ARITH_TAC);; + +let COMPLEX_SUB_RDISTRIB = prove + (`!x y z. (x - y) * z = x * z - y * z`, + SIMPLE_COMPLEX_ARITH_TAC);; + +let COMPLEX_MUL_2 = prove + (`!x. Cx(&2) * x = x + x`, + SIMPLE_COMPLEX_ARITH_TAC);; + +(* ------------------------------------------------------------------------- *) +(* Sometimes here we need to tweak non-zeroness assertions. *) +(* ------------------------------------------------------------------------- *) + +let II_NZ = prove + (`~(ii = Cx(&0))`, + REWRITE_TAC[ii] THEN SIMPLE_COMPLEX_ARITH_TAC);; + +let COMPLEX_MUL_LINV = prove + (`!z. ~(z = Cx(&0)) ==> (inv(z) * z = Cx(&1))`, + REWRITE_TAC[COMPLEX_EQ_0] THEN SIMPLE_COMPLEX_ARITH_TAC);; + +let COMPLEX_ENTIRE = prove + (`!x y. (x * y = Cx(&0)) <=> (x = Cx(&0)) \/ (y = Cx(&0))`, + REWRITE_TAC[COMPLEX_EQ_0] THEN SIMPLE_COMPLEX_ARITH_TAC);; + +let COMPLEX_MUL_RINV = prove + (`!z. ~(z = Cx(&0)) ==> (z * inv(z) = Cx(&1))`, + REWRITE_TAC[COMPLEX_EQ_0] THEN SIMPLE_COMPLEX_ARITH_TAC);; + +let COMPLEX_DIV_REFL = prove + (`!x. ~(x = Cx(&0)) ==> (x / x = Cx(&1))`, + REWRITE_TAC[COMPLEX_EQ_0] THEN SIMPLE_COMPLEX_ARITH_TAC);; + +(* ------------------------------------------------------------------------- *) +(* Homomorphic embedding properties for Cx mapping. *) +(* ------------------------------------------------------------------------- *) + +let CX_INJ = prove + (`!x y. (Cx(x) = Cx(y)) <=> (x = y)`, + REWRITE_TAC[CX_DEF; COMPLEX_EQ; RE; IM]);; + +let CX_NEG = prove + (`!x. Cx(--x) = --(Cx(x))`, + REWRITE_TAC[CX_DEF; complex_neg; RE; IM; REAL_NEG_0]);; + +let CX_ADD = prove + (`!x y. Cx(x + y) = Cx(x) + Cx(y)`, + REWRITE_TAC[CX_DEF; complex_add; RE; IM; REAL_ADD_LID]);; + +let CX_SUB = prove + (`!x y. Cx(x - y) = Cx(x) - Cx(y)`, + REWRITE_TAC[complex_sub; real_sub; CX_ADD; CX_NEG]);; + +let CX_INV = prove + (`!x. Cx(inv x) = inv(Cx x)`, + GEN_TAC THEN REWRITE_TAC[CX_DEF; complex_inv; RE; IM; COMPLEX_EQ] THEN + ASM_CASES_TAC `x = &0` THEN ASM_REWRITE_TAC[] THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN + POP_ASSUM MP_TAC THEN CONV_TAC REAL_FIELD);; + +let CX_MUL = prove + (`!x y. Cx(x * y) = Cx(x) * Cx(y)`, + REWRITE_TAC[CX_DEF; complex_mul; RE; IM; REAL_MUL_LZERO; REAL_MUL_RZERO] THEN + REWRITE_TAC[REAL_SUB_RZERO; REAL_ADD_RID]);; + +let CX_POW = prove + (`!x n. Cx(x pow n) = Cx(x) pow n`, + GEN_TAC THEN INDUCT_TAC THEN + ASM_REWRITE_TAC[complex_pow; real_pow; CX_MUL]);; + +let CX_DIV = prove + (`!x y. Cx(x / y) = Cx(x) / Cx(y)`, + REWRITE_TAC[complex_div; real_div; CX_MUL; CX_INV]);; + +let CX_ABS = prove + (`!x. Cx(abs x) = Cx(norm(Cx(x)))`, + REWRITE_TAC[CX_DEF; complex_norm; COMPLEX_EQ; RE; IM] THEN + REWRITE_TAC[REAL_POW_2; REAL_MUL_LZERO; REAL_ADD_RID] THEN + REWRITE_TAC[GSYM REAL_POW_2; POW_2_SQRT_ABS]);; + +let COMPLEX_NORM_CX = prove + (`!x. norm(Cx(x)) = abs(x)`, + REWRITE_TAC[GSYM CX_INJ; CX_ABS]);; + +(* ------------------------------------------------------------------------- *) +(* Some "linear" things hold for Re and Im too. *) +(* ------------------------------------------------------------------------- *) + +let RE_CX = prove + (`!x. Re(Cx x) = x`, + REWRITE_TAC[RE; CX_DEF]);; + +let RE_NEG = prove + (`!x. Re(--x) = --Re(x)`, + REWRITE_TAC[complex_neg; RE]);; + +let RE_ADD = prove + (`!x y. Re(x + y) = Re(x) + Re(y)`, + REWRITE_TAC[complex_add; RE]);; + +let RE_SUB = prove + (`!x y. Re(x - y) = Re(x) - Re(y)`, + REWRITE_TAC[complex_sub; real_sub; RE_ADD; RE_NEG]);; + +let IM_CX = prove + (`!x. Im(Cx x) = &0`, + REWRITE_TAC[IM; CX_DEF]);; + +let IM_NEG = prove + (`!x. Im(--x) = --Im(x)`, + REWRITE_TAC[complex_neg; IM]);; + +let IM_ADD = prove + (`!x y. Im(x + y) = Im(x) + Im(y)`, + REWRITE_TAC[complex_add; IM]);; + +let IM_SUB = prove + (`!x y. Im(x - y) = Im(x) - Im(y)`, + REWRITE_TAC[complex_sub; real_sub; IM_ADD; IM_NEG]);; + +(* ------------------------------------------------------------------------- *) +(* An "expansion" theorem into the traditional notation. *) +(* ------------------------------------------------------------------------- *) + +let COMPLEX_EXPAND = prove + (`!z. z = Cx(Re z) + ii * Cx(Im z)`, + REWRITE_TAC[ii] THEN SIMPLE_COMPLEX_ARITH_TAC);; + +let COMPLEX_TRAD = prove + (`!x y. complex(x,y) = Cx(x) + ii * Cx(y)`, + REWRITE_TAC[ii] THEN SIMPLE_COMPLEX_ARITH_TAC);; + +(* ------------------------------------------------------------------------- *) +(* Real and complex parts of ii and multiples. *) +(* ------------------------------------------------------------------------- *) + +let RE_II = prove + (`Re ii = &0`, + REWRITE_TAC[ii] THEN SIMPLE_COMPLEX_ARITH_TAC);; + +let IM_II = prove + (`Im ii = &1`, + REWRITE_TAC[ii] THEN SIMPLE_COMPLEX_ARITH_TAC);; + +let RE_MUL_II = prove + (`!z. Re(z * ii) = --(Im z) /\ Re(ii * z) = --(Im z)`, + REWRITE_TAC[ii] THEN SIMPLE_COMPLEX_ARITH_TAC);; + +let IM_MUL_II = prove + (`!z. Im(z * ii) = Re z /\ Im(ii * z) = Re z`, + REWRITE_TAC[ii] THEN SIMPLE_COMPLEX_ARITH_TAC);; + +let COMPLEX_NORM_II = prove + (`norm ii = &1`, + REWRITE_TAC[complex_norm; RE_II; IM_II] THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN REWRITE_TAC[SQRT_1]);; + +(* ------------------------------------------------------------------------- *) +(* Limited "multiplicative" theorems for Re and Im. *) +(* ------------------------------------------------------------------------- *) + +let RE_CMUL = prove + (`!a z. Re(a % z) = a * Re z`, + SIMP_TAC[RE_DEF; VECTOR_MUL_COMPONENT; DIMINDEX_2; ARITH]);; + +let IM_CMUL = prove + (`!a z. Im(a % z) = a * Im z`, + SIMP_TAC[IM_DEF; VECTOR_MUL_COMPONENT; DIMINDEX_2; ARITH]);; + +let RE_MUL_CX = prove + (`!x z. Re(Cx(x) * z) = x * Re z /\ + Re(z * Cx(x)) = Re z * x`, + SIMPLE_COMPLEX_ARITH_TAC);; + +let IM_MUL_CX = prove + (`!x z. Im(Cx(x) * z) = x * Im z /\ + Im(z * Cx(x)) = Im z * x`, + SIMPLE_COMPLEX_ARITH_TAC);; + +let RE_DIV_CX = prove + (`!z x. Re(z / Cx(x)) = Re(z) / x`, + REWRITE_TAC[complex_div; real_div; GSYM CX_INV; RE_MUL_CX]);; + +let IM_DIV_CX = prove + (`!z x. Im(z / Cx(x)) = Im(z) / x`, + REWRITE_TAC[complex_div; real_div; GSYM CX_INV; IM_MUL_CX]);; + +(* ------------------------------------------------------------------------- *) +(* Syntax constructors etc. for complex constants. *) +(* ------------------------------------------------------------------------- *) + +let is_complex_const = + let cx_tm = `Cx` in + fun tm -> + is_comb tm & + let l,r = dest_comb tm in l = cx_tm & is_ratconst r;; + +let dest_complex_const = + let cx_tm = `Cx` in + fun tm -> + let l,r = dest_comb tm in + if l = cx_tm then rat_of_term r + else failwith "dest_complex_const";; + +let mk_complex_const = + let cx_tm = `Cx` in + fun r -> + mk_comb(cx_tm,term_of_rat r);; + +(* ------------------------------------------------------------------------- *) +(* Conversions for arithmetic on complex constants. *) +(* ------------------------------------------------------------------------- *) + +let COMPLEX_RAT_EQ_CONV = + GEN_REWRITE_CONV I [CX_INJ] THENC REAL_RAT_EQ_CONV;; + +let COMPLEX_RAT_MUL_CONV = + GEN_REWRITE_CONV I [GSYM CX_MUL] THENC RAND_CONV REAL_RAT_MUL_CONV;; + +let COMPLEX_RAT_ADD_CONV = + GEN_REWRITE_CONV I [GSYM CX_ADD] THENC RAND_CONV REAL_RAT_ADD_CONV;; + +let COMPLEX_RAT_POW_CONV = + let x_tm = `x:real` + and n_tm = `n:num` in + let pth = SYM(SPECL [x_tm; n_tm] CX_POW) in + fun tm -> + let lop,r = dest_comb tm in + let op,bod = dest_comb lop in + let th1 = INST [rand bod,x_tm; r,n_tm] pth in + let tm1,tm2 = dest_comb(concl th1) in + if rand tm1 <> tm then failwith "COMPLEX_RAT_POW_CONV" else + let tm3,tm4 = dest_comb tm2 in + TRANS th1 (AP_TERM tm3 (REAL_RAT_REDUCE_CONV tm4));; + +(* ------------------------------------------------------------------------- *) +(* Complex polynomial normalizer. *) +(* ------------------------------------------------------------------------- *) + +let COMPLEX_POLY_CLAUSES = prove + (`(!x y z. x + (y + z) = (x + y) + z) /\ + (!x y. x + y = y + x) /\ + (!x. Cx(&0) + x = x) /\ + (!x y z. x * (y * z) = (x * y) * z) /\ + (!x y. x * y = y * x) /\ + (!x. Cx(&1) * x = x) /\ + (!x. Cx(&0) * x = Cx(&0)) /\ + (!x y z. x * (y + z) = x * y + x * z) /\ + (!x. x pow 0 = Cx(&1)) /\ + (!x n. x pow (SUC n) = x * x pow n)`, + REWRITE_TAC[complex_pow] THEN SIMPLE_COMPLEX_ARITH_TAC) +and COMPLEX_POLY_NEG_CLAUSES = prove + (`(!x. --x = Cx(-- &1) * x) /\ + (!x y. x - y = x + Cx(-- &1) * y)`, + SIMPLE_COMPLEX_ARITH_TAC);; + +let COMPLEX_POLY_NEG_CONV,COMPLEX_POLY_ADD_CONV,COMPLEX_POLY_SUB_CONV, + COMPLEX_POLY_MUL_CONV,COMPLEX_POLY_POW_CONV,COMPLEX_POLY_CONV = + SEMIRING_NORMALIZERS_CONV COMPLEX_POLY_CLAUSES COMPLEX_POLY_NEG_CLAUSES + (is_complex_const, + COMPLEX_RAT_ADD_CONV,COMPLEX_RAT_MUL_CONV,COMPLEX_RAT_POW_CONV) + (<);; + +(* ------------------------------------------------------------------------- *) +(* Extend it to handle "inv" and division, by constants after normalization. *) +(* ------------------------------------------------------------------------- *) + +let COMPLEX_RAT_INV_CONV = + REWR_CONV(GSYM CX_INV) THENC RAND_CONV REAL_RAT_INV_CONV;; + +let COMPLEX_POLY_CONV = + let neg_tm = `(--):complex->complex` + and inv_tm = `inv:complex->complex` + and add_tm = `(+):complex->complex->complex` + and sub_tm = `(-):complex->complex->complex` + and mul_tm = `(*):complex->complex->complex` + and div_tm = `(/):complex->complex->complex` + and pow_tm = `(pow):complex->num->complex` + and div_conv = REWR_CONV complex_div in + let rec COMPLEX_POLY_CONV tm = + if not(is_comb tm) or is_ratconst tm then REFL tm else + let lop,r = dest_comb tm in + if lop = neg_tm then + let th1 = AP_TERM lop (COMPLEX_POLY_CONV r) in + TRANS th1 (COMPLEX_POLY_NEG_CONV (rand(concl th1))) + else if lop = inv_tm then + let th1 = AP_TERM lop (COMPLEX_POLY_CONV r) in + TRANS th1 (TRY_CONV COMPLEX_RAT_INV_CONV (rand(concl th1))) + else if not(is_comb lop) then REFL tm else + let op,l = dest_comb lop in + if op = pow_tm then + let th1 = AP_THM (AP_TERM op (COMPLEX_POLY_CONV l)) r in + TRANS th1 (TRY_CONV COMPLEX_POLY_POW_CONV (rand(concl th1))) + else if op = add_tm or op = mul_tm or op = sub_tm then + let th1 = MK_COMB(AP_TERM op (COMPLEX_POLY_CONV l), + COMPLEX_POLY_CONV r) in + let fn = if op = add_tm then COMPLEX_POLY_ADD_CONV + else if op = mul_tm then COMPLEX_POLY_MUL_CONV + else COMPLEX_POLY_SUB_CONV in + TRANS th1 (fn (rand(concl th1))) + else if op = div_tm then + let th1 = div_conv tm in + TRANS th1 (COMPLEX_POLY_CONV (rand(concl th1))) + else REFL tm in + COMPLEX_POLY_CONV;; + +(* ------------------------------------------------------------------------- *) +(* Complex number version of usual ring procedure. *) +(* ------------------------------------------------------------------------- *) + +let COMPLEX_RING,complex_ideal_cofactors = + let COMPLEX_INTEGRAL = prove + (`(!x. Cx(&0) * x = Cx(&0)) /\ + (!x y z. (x + y = x + z) <=> (y = z)) /\ + (!w x y z. (w * y + x * z = w * z + x * y) <=> (w = x) \/ (y = z))`, + REWRITE_TAC[COMPLEX_ENTIRE; SIMPLE_COMPLEX_ARITH + `(w * y + x * z = w * z + x * y) <=> + (w - x) * (y - z) = Cx(&0)`] THEN + SIMPLE_COMPLEX_ARITH_TAC) + and COMPLEX_RABINOWITSCH = prove + (`!x y:complex. ~(x = y) <=> ?z. (x - y) * z = Cx(&1)`, + REPEAT GEN_TAC THEN + GEN_REWRITE_TAC (LAND_CONV o RAND_CONV) [GSYM COMPLEX_SUB_0] THEN + MESON_TAC[COMPLEX_MUL_RINV; COMPLEX_MUL_LZERO; + SIMPLE_COMPLEX_ARITH `~(Cx(&1) = Cx(&0))`]) + and COMPLEX_IIII = prove + (`ii * ii + Cx(&1) = Cx(&0)`, + REWRITE_TAC[ii; CX_DEF; complex_mul; complex_add; RE; IM] THEN + AP_TERM_TAC THEN BINOP_TAC THEN REAL_ARITH_TAC) in + let ring,ideal = + RING_AND_IDEAL_CONV + (dest_complex_const,mk_complex_const,COMPLEX_RAT_EQ_CONV, + `(--):complex->complex`,`(+):complex->complex->complex`, + `(-):complex->complex->complex`,`(inv):complex->complex`, + `(*):complex->complex->complex`,`(/):complex->complex->complex`, + `(pow):complex->num->complex`, + COMPLEX_INTEGRAL,COMPLEX_RABINOWITSCH,COMPLEX_POLY_CONV) + and ii_tm = `ii` and iiii_tm = concl COMPLEX_IIII in + (fun tm -> if free_in ii_tm tm then + MP (ring (mk_imp(iiii_tm,tm))) COMPLEX_IIII + else ring tm), + ideal;; + +(* ------------------------------------------------------------------------- *) +(* Most basic properties of inverses. *) +(* ------------------------------------------------------------------------- *) + +let COMPLEX_INV_0 = prove + (`inv(Cx(&0)) = Cx(&0)`, + SIMPLE_COMPLEX_ARITH_TAC);; + +let COMPLEX_INV_1 = prove + (`inv(Cx(&1)) = Cx(&1)`, + SIMPLE_COMPLEX_ARITH_TAC);; + +let COMPLEX_INV_MUL = prove + (`!w z. inv(w * z) = inv(w) * inv(z)`, + REPEAT GEN_TAC THEN + MAP_EVERY ASM_CASES_TAC [`w = Cx(&0)`; `z = Cx(&0)`] THEN + ASM_REWRITE_TAC[COMPLEX_INV_0; COMPLEX_MUL_LZERO; COMPLEX_MUL_RZERO] THEN + REPEAT(POP_ASSUM MP_TAC) THEN + REWRITE_TAC[complex_mul; complex_inv; RE; IM; COMPLEX_EQ; CX_DEF] THEN + REWRITE_TAC[GSYM REAL_SOS_EQ_0] THEN CONV_TAC REAL_FIELD);; + +let COMPLEX_POW_INV = prove + (`!x n. (inv x) pow n = inv(x pow n)`, + GEN_TAC THEN INDUCT_TAC THEN + ASM_REWRITE_TAC[complex_pow; COMPLEX_INV_1; COMPLEX_INV_MUL]);; + +let COMPLEX_INV_INV = prove + (`!x:complex. inv(inv x) = x`, + GEN_TAC THEN ASM_CASES_TAC `x = Cx(&0)` THEN + ASM_REWRITE_TAC[COMPLEX_INV_0] THEN + POP_ASSUM MP_TAC THEN + MAP_EVERY (fun t -> MP_TAC(SPEC t COMPLEX_MUL_RINV)) + [`x:complex`; `inv(x):complex`] THEN + CONV_TAC COMPLEX_RING);; + +let COMPLEX_INV_DIV = prove + (`!w z:complex. inv(w / z) = z / w`, + REWRITE_TAC[complex_div; COMPLEX_INV_MUL; COMPLEX_INV_INV] THEN + REWRITE_TAC[COMPLEX_MUL_AC]);; + +(* ------------------------------------------------------------------------- *) +(* And also field procedure. *) +(* ------------------------------------------------------------------------- *) + +let COMPLEX_EQ_MUL_LCANCEL = prove + (`!x y z. (x * y = x * z) <=> (x = Cx(&0)) \/ (y = z)`, + CONV_TAC COMPLEX_RING);; + +let COMPLEX_EQ_MUL_RCANCEL = prove + (`!x y z. (x * z = y * z) <=> (x = y) \/ (z = Cx(&0))`, + CONV_TAC COMPLEX_RING);; + +let COMPLEX_FIELD = + let prenex_conv = + TOP_DEPTH_CONV BETA_CONV THENC + PURE_REWRITE_CONV[FORALL_SIMP; EXISTS_SIMP; complex_div; + COMPLEX_INV_INV; COMPLEX_INV_MUL; GSYM COMPLEX_POW_INV] THENC + NNFC_CONV THENC DEPTH_BINOP_CONV `(/\)` CONDS_CELIM_CONV THENC + PRENEX_CONV + and setup_conv = NNF_CONV THENC WEAK_CNF_CONV THENC CONJ_CANON_CONV + and is_inv = + let inv_tm = `inv:complex->complex` + and is_div = is_binop `(/):complex->complex->complex` in + fun tm -> (is_div tm or (is_comb tm & rator tm = inv_tm)) & + not(is_ratconst(rand tm)) in + let BASIC_COMPLEX_FIELD tm = + let is_freeinv t = is_inv t & free_in t tm in + let itms = setify(map rand (find_terms is_freeinv tm)) in + let hyps = map (fun t -> SPEC t COMPLEX_MUL_RINV) itms in + let tm' = itlist (fun th t -> mk_imp(concl th,t)) hyps tm in + let th1 = setup_conv tm' in + let cjs = conjuncts(rand(concl th1)) in + let ths = map COMPLEX_RING cjs in + let th2 = EQ_MP (SYM th1) (end_itlist CONJ ths) in + rev_itlist (C MP) hyps th2 in + fun tm -> + let th0 = prenex_conv tm in + let tm0 = rand(concl th0) in + let avs,bod = strip_forall tm0 in + let th1 = setup_conv bod in + let ths = map BASIC_COMPLEX_FIELD (conjuncts(rand(concl th1))) in + EQ_MP (SYM th0) (GENL avs (EQ_MP (SYM th1) (end_itlist CONJ ths)));; + +(* ------------------------------------------------------------------------- *) +(* More trivial lemmas. *) +(* ------------------------------------------------------------------------- *) + +let COMPLEX_DIV_1 = prove + (`!z. z / Cx(&1) = z`, + CONV_TAC COMPLEX_FIELD);; + +let COMPLEX_DIV_LMUL = prove + (`!x y. ~(y = Cx(&0)) ==> y * x / y = x`, + CONV_TAC COMPLEX_FIELD);; + +let COMPLEX_DIV_RMUL = prove + (`!x y. ~(y = Cx(&0)) ==> x / y * y = x`, + CONV_TAC COMPLEX_FIELD);; + +let COMPLEX_INV_EQ_0 = prove + (`!x. inv x = Cx(&0) <=> x = Cx(&0)`, + GEN_TAC THEN ASM_CASES_TAC `x = Cx(&0)` THEN + ASM_REWRITE_TAC[COMPLEX_INV_0] THEN POP_ASSUM MP_TAC THEN + CONV_TAC COMPLEX_FIELD);; + +let COMPLEX_INV_NEG = prove + (`!x:complex. inv(--x) = --(inv x)`, + GEN_TAC THEN ASM_CASES_TAC `x = Cx(&0)` THEN + ASM_REWRITE_TAC[COMPLEX_INV_0; COMPLEX_NEG_0] THEN + POP_ASSUM MP_TAC THEN CONV_TAC COMPLEX_FIELD);; + +let COMPLEX_NEG_INV = prove + (`!x:complex. --(inv x) = inv(--x)`, + REWRITE_TAC[COMPLEX_INV_NEG]);; + +let COMPLEX_INV_EQ_1 = prove + (`!x. inv x = Cx(&1) <=> x = Cx(&1)`, + GEN_TAC THEN ASM_CASES_TAC `x = Cx(&0)` THEN + ASM_REWRITE_TAC[COMPLEX_INV_0] THEN POP_ASSUM MP_TAC THEN + CONV_TAC COMPLEX_FIELD);; + +let COMPLEX_DIV_EQ_0 = prove + (`!w z. w / z = Cx(&0) <=> w = Cx(&0) \/ z = Cx(&0)`, + REWRITE_TAC[complex_div; COMPLEX_INV_EQ_0; COMPLEX_ENTIRE]);; + +(* ------------------------------------------------------------------------- *) +(* Powers. *) +(* ------------------------------------------------------------------------- *) + +let COMPLEX_POW_ADD = prove + (`!x m n. x pow (m + n) = x pow m * x pow n`, + GEN_TAC THEN INDUCT_TAC THEN + ASM_REWRITE_TAC[ADD_CLAUSES; complex_pow; + COMPLEX_MUL_LID; COMPLEX_MUL_ASSOC]);; + +let COMPLEX_POW_POW = prove + (`!x m n. (x pow m) pow n = x pow (m * n)`, + GEN_TAC THEN GEN_TAC THEN INDUCT_TAC THEN + ASM_REWRITE_TAC[complex_pow; MULT_CLAUSES; COMPLEX_POW_ADD]);; + +let COMPLEX_POW_1 = prove + (`!x. x pow 1 = x`, + REWRITE_TAC[num_CONV `1`] THEN REWRITE_TAC[complex_pow; COMPLEX_MUL_RID]);; + +let COMPLEX_POW_2 = prove + (`!x. x pow 2 = x * x`, + REWRITE_TAC[num_CONV `2`] THEN REWRITE_TAC[complex_pow; COMPLEX_POW_1]);; + +let COMPLEX_POW_NEG = prove + (`!x n. (--x) pow n = if EVEN n then x pow n else --(x pow n)`, + GEN_TAC THEN INDUCT_TAC THEN + ASM_REWRITE_TAC[complex_pow; EVEN] THEN + ASM_CASES_TAC `EVEN n` THEN + ASM_REWRITE_TAC[COMPLEX_MUL_RNEG; COMPLEX_MUL_LNEG; COMPLEX_NEG_NEG]);; + +let COMPLEX_POW_ONE = prove + (`!n. Cx(&1) pow n = Cx(&1)`, + INDUCT_TAC THEN ASM_REWRITE_TAC[complex_pow; COMPLEX_MUL_LID]);; + +let COMPLEX_POW_MUL = prove + (`!x y n. (x * y) pow n = (x pow n) * (y pow n)`, + GEN_TAC THEN GEN_TAC THEN INDUCT_TAC THEN + ASM_REWRITE_TAC[complex_pow; COMPLEX_MUL_LID; COMPLEX_MUL_AC]);; + +let COMPLEX_POW_DIV = prove + (`!x y n. (x / y) pow n = (x pow n) / (y pow n)`, + REWRITE_TAC[complex_div; COMPLEX_POW_MUL; COMPLEX_POW_INV]);; + +let COMPLEX_POW_II_2 = prove + (`ii pow 2 = --Cx(&1)`, + REWRITE_TAC[ii; COMPLEX_POW_2; complex_mul; CX_DEF; RE; IM; complex_neg] THEN + CONV_TAC REAL_RAT_REDUCE_CONV);; + +let COMPLEX_POW_EQ_0 = prove + (`!x n. (x pow n = Cx(&0)) <=> (x = Cx(&0)) /\ ~(n = 0)`, + GEN_TAC THEN INDUCT_TAC THEN + ASM_REWRITE_TAC[NOT_SUC; complex_pow; COMPLEX_ENTIRE] THENL + [SIMPLE_COMPLEX_ARITH_TAC; CONV_TAC TAUT]);; + +let COMPLEX_POW_ZERO = prove + (`!n. Cx(&0) pow n = if n = 0 then Cx(&1) else Cx(&0)`, + INDUCT_TAC THEN REWRITE_TAC[complex_pow; COMPLEX_MUL_LZERO; NOT_SUC]);; + +let COMPLEX_INV_II = prove + (`inv ii = --ii`, + CONV_TAC COMPLEX_FIELD);; + +let COMPLEX_DIV_POW = prove + (`!x:complex n k:num. + ~(x= Cx(&0)) /\ k <= n /\ ~(k = 0) + ==> x pow (n-k) = x pow n / x pow k`, + REPEAT STRIP_TAC THEN SUBGOAL_THEN `x:complex pow (n - k) * x pow k = + x pow n / x pow k * x pow k` (fun th-> ASM_MESON_TAC + [th;COMPLEX_POW_EQ_0;COMPLEX_EQ_MUL_RCANCEL]) + THEN ASM_SIMP_TAC[GSYM COMPLEX_POW_ADD;SUB_ADD] THEN + MP_TAC (MESON [COMPLEX_POW_EQ_0;ASSUME `~(k = 0)`; ASSUME `~(x = Cx(&0))`] + `~(x pow k = Cx(&0))`) THEN ASM_SIMP_TAC[COMPLEX_DIV_RMUL]);; + +(* ------------------------------------------------------------------------- *) +(* Norms (aka "moduli"). *) +(* ------------------------------------------------------------------------- *) + +let COMPLEX_VEC_0 = prove + (`vec 0 = Cx(&0)`, + SIMP_TAC[CART_EQ; VEC_COMPONENT; CX_DEF; complex; + DIMINDEX_2; FORALL_2; VECTOR_2]);; + +let COMPLEX_NORM_ZERO = prove + (`!z. (norm z = &0) <=> (z = Cx(&0))`, + REWRITE_TAC[NORM_EQ_0; COMPLEX_VEC_0]);; + +let COMPLEX_NORM_NUM = prove + (`!n. norm(Cx(&n)) = &n`, + REWRITE_TAC[COMPLEX_NORM_CX; REAL_ABS_NUM]);; + +let COMPLEX_NORM_0 = prove + (`norm(Cx(&0)) = &0`, + MESON_TAC[COMPLEX_NORM_ZERO]);; + +let COMPLEX_NORM_NZ = prove + (`!z. &0 < norm(z) <=> ~(z = Cx(&0))`, + REWRITE_TAC[NORM_POS_LT; COMPLEX_VEC_0]);; + +let COMPLEX_NORM_MUL = prove + (`!w z. norm(w * z) = norm(w) * norm(z)`, + REPEAT GEN_TAC THEN REWRITE_TAC[complex_norm; complex_mul; RE; IM] THEN + SIMP_TAC[GSYM SQRT_MUL; REAL_POW_2; REAL_LE_ADD; REAL_LE_SQUARE] THEN + AP_TERM_TAC THEN REAL_ARITH_TAC);; + +let COMPLEX_NORM_POW = prove + (`!z n. norm(z pow n) = norm(z) pow n`, + GEN_TAC THEN INDUCT_TAC THEN + ASM_REWRITE_TAC[complex_pow; real_pow; COMPLEX_NORM_NUM; COMPLEX_NORM_MUL]);; + +let COMPLEX_NORM_INV = prove + (`!z. norm(inv z) = inv(norm z)`, + GEN_TAC THEN REWRITE_TAC[complex_norm; complex_inv; RE; IM] THEN + REWRITE_TAC[REAL_POW_2; real_div] THEN + REWRITE_TAC[REAL_ARITH `(r * d) * r * d + (--i * d) * --i * d = + (r * r + i * i) * d * d:real`] THEN + ASM_CASES_TAC `Re z * Re z + Im z * Im z = &0` THENL + [ASM_REWRITE_TAC[REAL_INV_0; SQRT_0; REAL_MUL_LZERO]; ALL_TAC] THEN + CONV_TAC SYM_CONV THEN MATCH_MP_TAC REAL_MUL_RINV_UNIQ THEN + SIMP_TAC[GSYM SQRT_MUL; REAL_LE_MUL; REAL_LE_INV_EQ; REAL_LE_ADD; + REAL_LE_SQUARE] THEN + ONCE_REWRITE_TAC[AC REAL_MUL_AC + `a * a * b * b:real = (a * b) * (a * b)`] THEN + ASM_SIMP_TAC[REAL_MUL_RINV; REAL_MUL_LID; SQRT_1]);; + +let COMPLEX_NORM_DIV = prove + (`!w z. norm(w / z) = norm(w) / norm(z)`, + REWRITE_TAC[complex_div; real_div; COMPLEX_NORM_INV; COMPLEX_NORM_MUL]);; + +let COMPLEX_NORM_TRIANGLE_SUB = prove + (`!w z. norm(w) <= norm(w + z) + norm(z)`, + MESON_TAC[NORM_TRIANGLE; NORM_NEG; COMPLEX_ADD_ASSOC; + COMPLEX_ADD_RINV; COMPLEX_ADD_RID]);; + +let COMPLEX_NORM_ABS_NORM = prove + (`!w z. abs(norm w - norm z) <= norm(w - z)`, + REPEAT GEN_TAC THEN + MATCH_MP_TAC(REAL_ARITH + `a - b <= x /\ b - a <= x ==> abs(a - b) <= x:real`) THEN + MESON_TAC[COMPLEX_NEG_SUB; NORM_NEG; REAL_LE_SUB_RADD; complex_sub; + COMPLEX_NORM_TRIANGLE_SUB]);; + +let COMPLEX_POW_EQ_1 = prove + (`!z n. z pow n = Cx(&1) ==> norm(z) = &1 \/ n = 0`, + REPEAT GEN_TAC THEN + DISCH_THEN(MP_TAC o AP_TERM `norm:complex->real`) THEN + SIMP_TAC[COMPLEX_NORM_POW; COMPLEX_NORM_CX; REAL_POW_EQ_1; REAL_ABS_NUM] THEN + SIMP_TAC[REAL_ABS_NORM] THEN CONV_TAC TAUT);; + +(* ------------------------------------------------------------------------- *) +(* Complex conjugate. *) +(* ------------------------------------------------------------------------- *) + +let cnj = new_definition + `cnj(z) = complex(Re(z),--(Im(z)))`;; + +(* ------------------------------------------------------------------------- *) +(* Conjugation is an automorphism. *) +(* ------------------------------------------------------------------------- *) + +let CNJ_INJ = prove + (`!w z. (cnj(w) = cnj(z)) <=> (w = z)`, + REWRITE_TAC[cnj; COMPLEX_EQ; RE; IM; REAL_EQ_NEG2]);; + +let CNJ_CNJ = prove + (`!z. cnj(cnj z) = z`, + REWRITE_TAC[cnj; COMPLEX_EQ; RE; IM; REAL_NEG_NEG]);; + +let CNJ_CX = prove + (`!x. cnj(Cx x) = Cx x`, + REWRITE_TAC[cnj; COMPLEX_EQ; CX_DEF; REAL_NEG_0; RE; IM]);; + +let COMPLEX_NORM_CNJ = prove + (`!z. norm(cnj z) = norm(z)`, + REWRITE_TAC[complex_norm; cnj; REAL_POW_2] THEN + REWRITE_TAC[REAL_MUL_LNEG; REAL_MUL_RNEG; RE; IM; REAL_NEG_NEG]);; + +let CNJ_NEG = prove + (`!z. cnj(--z) = --(cnj z)`, + REWRITE_TAC[cnj; complex_neg; COMPLEX_EQ; RE; IM]);; + +let CNJ_INV = prove + (`!z. cnj(inv z) = inv(cnj z)`, + REWRITE_TAC[cnj; complex_inv; COMPLEX_EQ; RE; IM] THEN + REWRITE_TAC[real_div; REAL_NEG_NEG; REAL_POW_2; + REAL_MUL_LNEG; REAL_MUL_RNEG]);; + +let CNJ_ADD = prove + (`!w z. cnj(w + z) = cnj(w) + cnj(z)`, + REWRITE_TAC[cnj; complex_add; COMPLEX_EQ; RE; IM] THEN + REWRITE_TAC[REAL_NEG_ADD; REAL_MUL_LNEG; REAL_MUL_RNEG; REAL_NEG_NEG]);; + +let CNJ_SUB = prove + (`!w z. cnj(w - z) = cnj(w) - cnj(z)`, + REWRITE_TAC[complex_sub; CNJ_ADD; CNJ_NEG]);; + +let CNJ_MUL = prove + (`!w z. cnj(w * z) = cnj(w) * cnj(z)`, + REWRITE_TAC[cnj; complex_mul; COMPLEX_EQ; RE; IM] THEN + REWRITE_TAC[REAL_NEG_ADD; REAL_MUL_LNEG; REAL_MUL_RNEG; REAL_NEG_NEG]);; + +let CNJ_DIV = prove + (`!w z. cnj(w / z) = cnj(w) / cnj(z)`, + REWRITE_TAC[complex_div; CNJ_MUL; CNJ_INV]);; + +let CNJ_POW = prove + (`!z n. cnj(z pow n) = cnj(z) pow n`, + GEN_TAC THEN INDUCT_TAC THEN + ASM_REWRITE_TAC[complex_pow; CNJ_MUL; CNJ_CX]);; + +let RE_CNJ = prove + (`!z. Re(cnj z) = Re z`, + REWRITE_TAC[cnj; RE]);; + +let IM_CNJ = prove + (`!z. Im(cnj z) = --Im z`, + REWRITE_TAC[cnj; IM]);; + +let CNJ_EQ_CX = prove + (`!x z. cnj z = Cx x <=> z = Cx x`, + REWRITE_TAC[COMPLEX_EQ; RE_CNJ; IM_CNJ; RE_CX; IM_CX] THEN + CONV_TAC REAL_RING);; + +let CNJ_EQ_0 = prove + (`!z. cnj z = Cx(&0) <=> z = Cx(&0)`, + REWRITE_TAC[CNJ_EQ_CX]);; + +let COMPLEX_ADD_CNJ = prove + (`(!z. z + cnj z = Cx(&2 * Re z)) /\ (!z. cnj z + z = Cx(&2 * Re z))`, + REWRITE_TAC[COMPLEX_EQ; RE_CX; IM_CX; RE_ADD; IM_ADD; RE_CNJ; IM_CNJ] THEN + REAL_ARITH_TAC);; + +let CNJ_II = prove + (`cnj ii = --ii`, + REWRITE_TAC[cnj; ii; RE; IM; complex_neg; REAL_NEG_0]);; + +let CX_RE_CNJ = prove + (`!z. Cx(Re z) = (z + cnj z) / Cx(&2)`, + REWRITE_TAC[COMPLEX_EQ; RE_DIV_CX; IM_DIV_CX; RE_CX; IM_CX] THEN + REWRITE_TAC[RE_ADD; IM_ADD; RE_CNJ; IM_CNJ] THEN REAL_ARITH_TAC);; + +let CX_IM_CNJ = prove + (`!z. Cx(Im z) = --ii * (z - cnj z) / Cx(&2)`, + REWRITE_TAC[COMPLEX_EQ; RE_DIV_CX; IM_DIV_CX; RE_CX; IM_CX; + COMPLEX_MUL_LNEG; RE_NEG; IM_NEG; RE_MUL_II; IM_MUL_II] THEN + REWRITE_TAC[RE_SUB; IM_SUB; RE_CNJ; IM_CNJ] THEN REAL_ARITH_TAC);; + +let FORALL_CNJ = prove + (`(!z. P(cnj z)) <=> (!z. P z)`, + MESON_TAC[CNJ_CNJ]);; + +let EXISTS_CNJ = prove + (`(?z. P(cnj z)) <=> (?z. P z)`, + MESON_TAC[CNJ_CNJ]);; + +(* ------------------------------------------------------------------------- *) +(* Slightly ad hoc theorems relating multiplication, inverse and conjugation *) +(* ------------------------------------------------------------------------- *) + +let COMPLEX_NORM_POW_2 = prove + (`!z. Cx(norm z) pow 2 = z * cnj z`, + GEN_TAC THEN REWRITE_TAC [GSYM CX_POW; COMPLEX_SQNORM] THEN + REWRITE_TAC [cnj; complex_mul; CX_DEF; RE; IM; COMPLEX_EQ] THEN + CONV_TAC REAL_RING);; + +let COMPLEX_MUL_CNJ = prove + (`!z. cnj z * z = Cx(norm(z)) pow 2 /\ z * cnj z = Cx(norm(z)) pow 2`, + GEN_TAC THEN REWRITE_TAC[COMPLEX_MUL_SYM] THEN + REWRITE_TAC[cnj; complex_mul; RE; IM; GSYM CX_POW; COMPLEX_SQNORM] THEN + REWRITE_TAC[CX_DEF] THEN AP_TERM_TAC THEN BINOP_TAC THEN + CONV_TAC REAL_RING);; + +let COMPLEX_INV_CNJ = prove + (`!z. inv z = cnj z / Cx(norm z) pow 2`, + GEN_TAC THEN ASM_CASES_TAC `z = Cx(&0)` THENL + [ASM_REWRITE_TAC[CNJ_CX; complex_div; COMPLEX_INV_0; COMPLEX_MUL_LZERO]; + MATCH_MP_TAC(COMPLEX_FIELD + `x * y = z /\ ~(x = Cx(&0)) /\ ~(z = Cx(&0)) ==> inv x = y / z`) THEN + ASM_REWRITE_TAC[COMPLEX_MUL_CNJ; GSYM CX_POW; CX_INJ; REAL_POW_EQ_0] THEN + ASM_REWRITE_TAC[COMPLEX_NORM_ZERO; ARITH]]);; + +let COMPLEX_DIV_CNJ = prove + (`!a b. a / b = (a * cnj b) / Cx(norm b) pow 2`, + REPEAT GEN_TAC THEN REWRITE_TAC[complex_div; GSYM COMPLEX_MUL_ASSOC] THEN + AP_TERM_TAC THEN GEN_REWRITE_TAC LAND_CONV [COMPLEX_INV_CNJ] THEN + REWRITE_TAC[complex_div]);; + +let RE_COMPLEX_DIV_EQ_0 = prove + (`!a b. Re(a / b) = &0 <=> Re(a * cnj b) = &0`, + REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[COMPLEX_DIV_CNJ] THEN + REWRITE_TAC[complex_div; GSYM CX_POW; GSYM CX_INV] THEN + REWRITE_TAC[RE_MUL_CX; REAL_INV_EQ_0; REAL_POW_EQ_0; ARITH; + REAL_ENTIRE; COMPLEX_NORM_ZERO] THEN + ASM_CASES_TAC `b = Cx(&0)` THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[CNJ_CX; COMPLEX_MUL_RZERO; RE_CX]);; + +let IM_COMPLEX_DIV_EQ_0 = prove + (`!a b. Im(a / b) = &0 <=> Im(a * cnj b) = &0`, + REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[COMPLEX_DIV_CNJ] THEN + REWRITE_TAC[complex_div; GSYM CX_POW; GSYM CX_INV] THEN + REWRITE_TAC[IM_MUL_CX; REAL_INV_EQ_0; REAL_POW_EQ_0; ARITH; + REAL_ENTIRE; COMPLEX_NORM_ZERO] THEN + ASM_CASES_TAC `b = Cx(&0)` THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[CNJ_CX; COMPLEX_MUL_RZERO; IM_CX]);; + +let RE_COMPLEX_DIV_GT_0 = prove + (`!a b. &0 < Re(a / b) <=> &0 < Re(a * cnj b)`, + REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[COMPLEX_DIV_CNJ] THEN + REWRITE_TAC[complex_div; GSYM CX_POW; GSYM CX_INV] THEN + REWRITE_TAC[RE_MUL_CX; REAL_INV_EQ_0; REAL_POW_EQ_0; ARITH; + REAL_ENTIRE; COMPLEX_NORM_ZERO] THEN + ASM_CASES_TAC `b = Cx(&0)` THEN + ASM_REWRITE_TAC[CNJ_CX; COMPLEX_MUL_RZERO; RE_CX; REAL_MUL_LZERO] THEN + REWRITE_TAC[REAL_ARITH `&0 < a * x <=> &0 * x < a * x`] THEN + ASM_SIMP_TAC[REAL_LT_RMUL_EQ; REAL_LT_INV_EQ; REAL_POW_LT; ARITH; + COMPLEX_NORM_NZ]);; + +let IM_COMPLEX_DIV_GT_0 = prove + (`!a b. &0 < Im(a / b) <=> &0 < Im(a * cnj b)`, + REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[COMPLEX_DIV_CNJ] THEN + REWRITE_TAC[complex_div; GSYM CX_POW; GSYM CX_INV] THEN + REWRITE_TAC[IM_MUL_CX; REAL_INV_EQ_0; REAL_POW_EQ_0; ARITH; + REAL_ENTIRE; COMPLEX_NORM_ZERO] THEN + ASM_CASES_TAC `b = Cx(&0)` THEN + ASM_REWRITE_TAC[CNJ_CX; COMPLEX_MUL_RZERO; IM_CX; REAL_MUL_LZERO] THEN + REWRITE_TAC[REAL_ARITH `&0 < a * x <=> &0 * x < a * x`] THEN + ASM_SIMP_TAC[REAL_LT_RMUL_EQ; REAL_LT_INV_EQ; REAL_POW_LT; ARITH; + COMPLEX_NORM_NZ]);; + +let RE_COMPLEX_DIV_GE_0 = prove + (`!a b. &0 <= Re(a / b) <=> &0 <= Re(a * cnj b)`, + REWRITE_TAC[REAL_ARITH `&0 <= x <=> &0 < x \/ x = &0`] THEN + REWRITE_TAC[RE_COMPLEX_DIV_GT_0; RE_COMPLEX_DIV_EQ_0]);; + +let IM_COMPLEX_DIV_GE_0 = prove + (`!a b. &0 <= Im(a / b) <=> &0 <= Im(a * cnj b)`, + REWRITE_TAC[REAL_ARITH `&0 <= x <=> &0 < x \/ x = &0`] THEN + REWRITE_TAC[IM_COMPLEX_DIV_GT_0; IM_COMPLEX_DIV_EQ_0]);; + +let RE_COMPLEX_DIV_LE_0 = prove + (`!a b. Re(a / b) <= &0 <=> Re(a * cnj b) <= &0`, + REWRITE_TAC[GSYM REAL_NOT_LT; RE_COMPLEX_DIV_GT_0]);; + +let IM_COMPLEX_DIV_LE_0 = prove + (`!a b. Im(a / b) <= &0 <=> Im(a * cnj b) <= &0`, + REWRITE_TAC[GSYM REAL_NOT_LT; IM_COMPLEX_DIV_GT_0]);; + +let RE_COMPLEX_DIV_LT_0 = prove + (`!a b. Re(a / b) < &0 <=> Re(a * cnj b) < &0`, + REWRITE_TAC[GSYM REAL_NOT_LE; RE_COMPLEX_DIV_GE_0]);; + +let IM_COMPLEX_DIV_LT_0 = prove + (`!a b. Im(a / b) < &0 <=> Im(a * cnj b) < &0`, + REWRITE_TAC[GSYM REAL_NOT_LE; IM_COMPLEX_DIV_GE_0]);; + +let IM_COMPLEX_INV_GE_0 = prove + (`!z. &0 <= Im(inv z) <=> Im(z) <= &0`, + GEN_TAC THEN MP_TAC(ISPECL [`Cx(&1)`; `z:complex`] IM_COMPLEX_DIV_GE_0) THEN + REWRITE_TAC[complex_div; COMPLEX_MUL_LID; IM_CNJ] THEN REAL_ARITH_TAC);; + +let IM_COMPLEX_INV_LE_0 = prove + (`!z. Im(inv z) <= &0 <=> &0 <= Im(z)`, + MESON_TAC[IM_COMPLEX_INV_GE_0; COMPLEX_INV_INV]);; + +let IM_COMPLEX_INV_GT_0 = prove + (`!z. &0 < Im(inv z) <=> Im(z) < &0`, + REWRITE_TAC[REAL_ARITH `&0 < a <=> ~(a <= &0)`; IM_COMPLEX_INV_LE_0] THEN + REAL_ARITH_TAC);; + +let IM_COMPLEX_INV_LT_0 = prove + (`!z. Im(inv z) < &0 <=> &0 < Im(z)`, + REWRITE_TAC[REAL_ARITH `a < &0 <=> ~(&0 <= a)`; IM_COMPLEX_INV_GE_0] THEN + REAL_ARITH_TAC);; + +let IM_COMPLEX_INV_EQ_0 = prove + (`!z. Im(inv z) = &0 <=> Im(z) = &0`, + SIMP_TAC[GSYM REAL_LE_ANTISYM; IM_COMPLEX_INV_LE_0; IM_COMPLEX_INV_GE_0] THEN + REAL_ARITH_TAC);; + +let REAL_SGN_RE_COMPLEX_DIV = prove + (`!w z. real_sgn(Re(w / z)) = real_sgn(Re(w * cnj z))`, + REWRITE_TAC[real_sgn; RE_COMPLEX_DIV_GT_0; RE_COMPLEX_DIV_GE_0; + REAL_ARITH `x < &0 <=> ~(&0 <= x)`]);; + +let REAL_SGN_IM_COMPLEX_DIV = prove + (`!w z. real_sgn(Im(w / z)) = real_sgn(Im(w * cnj z))`, + REWRITE_TAC[real_sgn; IM_COMPLEX_DIV_GT_0; IM_COMPLEX_DIV_GE_0; + REAL_ARITH `x < &0 <=> ~(&0 <= x)`]);; + +(* ------------------------------------------------------------------------- *) +(* Norm versus components for complex numbers. *) +(* ------------------------------------------------------------------------- *) + +let COMPLEX_NORM_GE_RE_IM = prove + (`!z. abs(Re(z)) <= norm(z) /\ abs(Im(z)) <= norm(z)`, + GEN_TAC THEN ONCE_REWRITE_TAC[GSYM POW_2_SQRT_ABS] THEN + REWRITE_TAC[complex_norm] THEN + CONJ_TAC THEN + MATCH_MP_TAC SQRT_MONO_LE THEN + ASM_SIMP_TAC[REAL_LE_ADDR; REAL_LE_ADDL; REAL_POW_2; REAL_LE_SQUARE]);; + +let COMPLEX_NORM_LE_RE_IM = prove + (`!z. norm(z) <= abs(Re z) + abs(Im z)`, + GEN_TAC THEN MP_TAC(ISPEC `z:complex` NORM_LE_L1) THEN + REWRITE_TAC[DIMINDEX_2; SUM_2; RE_DEF; IM_DEF]);; + +let COMPLEX_L1_LE_NORM = prove + (`!z. sqrt(&2) / &2 * (abs(Re z) + abs(Im z)) <= norm z`, + GEN_TAC THEN MATCH_MP_TAC REAL_LE_LCANCEL_IMP THEN EXISTS_TAC `sqrt(&2)` THEN + SIMP_TAC[REAL_ARITH `x * x / &2 * y = (x pow 2) / &2 * y`; + SQRT_POW_2; REAL_POS; SQRT_POS_LT; REAL_OF_NUM_LT; ARITH] THEN + MP_TAC(ISPEC `z:complex` L1_LE_NORM) THEN + REWRITE_TAC[DIMINDEX_2; SUM_2; RE_DEF; IM_DEF] THEN REAL_ARITH_TAC);; + +(* ------------------------------------------------------------------------- *) +(* Complex square roots. *) +(* ------------------------------------------------------------------------- *) + +let csqrt = new_definition + `csqrt(z) = if Im(z) = &0 then + if &0 <= Re(z) then complex(sqrt(Re(z)),&0) + else complex(&0,sqrt(--Re(z))) + else complex(sqrt((norm(z) + Re(z)) / &2), + (Im(z) / abs(Im(z))) * + sqrt((norm(z) - Re(z)) / &2))`;; + + +let CSQRT = prove + (`!z. csqrt(z) pow 2 = z`, + GEN_TAC THEN REWRITE_TAC[COMPLEX_POW_2; csqrt] THEN COND_CASES_TAC THENL + [COND_CASES_TAC THEN + ASM_REWRITE_TAC[CX_DEF; complex_mul; RE; IM; REAL_MUL_RZERO; REAL_MUL_LZERO; + REAL_SUB_LZERO; REAL_SUB_RZERO; REAL_ADD_LID; COMPLEX_EQ] THEN + REWRITE_TAC[REAL_NEG_EQ; GSYM REAL_POW_2] THEN + ASM_SIMP_TAC[SQRT_POW_2; REAL_ARITH `~(&0 <= x) ==> &0 <= --x`]; + ALL_TAC] THEN + REWRITE_TAC[complex_mul; RE; IM] THEN + ONCE_REWRITE_TAC[REAL_ARITH + `(s * s - (i * s') * (i * s') = s * s - (i * i) * (s' * s')) /\ + (s * i * s' + (i * s')* s = &2 * i * s * s')`] THEN + REWRITE_TAC[GSYM REAL_POW_2] THEN + SUBGOAL_THEN `&0 <= norm(z) + Re(z) /\ &0 <= norm(z) - Re(z)` + STRIP_ASSUME_TAC THENL + [MP_TAC(SPEC `z:complex` COMPLEX_NORM_GE_RE_IM) THEN REAL_ARITH_TAC; + ALL_TAC] THEN + ASM_SIMP_TAC[REAL_LE_DIV; REAL_POS; GSYM SQRT_MUL; SQRT_POW_2] THEN + REWRITE_TAC[COMPLEX_EQ; RE; IM] THEN CONJ_TAC THENL + [ASM_SIMP_TAC[REAL_POW_DIV; REAL_POW2_ABS; + REAL_POW_EQ_0; REAL_DIV_REFL] THEN + REWRITE_TAC[real_div; REAL_MUL_LID; GSYM REAL_SUB_RDISTRIB] THEN + REWRITE_TAC[REAL_ARITH `(m + r) - (m - r) = r * &2`] THEN + REWRITE_TAC[GSYM REAL_MUL_ASSOC] THEN CONV_TAC REAL_RAT_REDUCE_CONV THEN + REWRITE_TAC[REAL_MUL_RID]; ALL_TAC] THEN + REWRITE_TAC[real_div] THEN + ONCE_REWRITE_TAC[AC REAL_MUL_AC + `(a * b) * a' * b = (a * a') * (b * b:real)`] THEN + REWRITE_TAC[REAL_DIFFSQ] THEN + REWRITE_TAC[complex_norm; GSYM REAL_POW_2] THEN + SIMP_TAC[SQRT_POW_2; REAL_LE_ADD; + REWRITE_RULE[GSYM REAL_POW_2] REAL_LE_SQUARE] THEN + REWRITE_TAC[REAL_ADD_SUB; GSYM REAL_POW_MUL] THEN + REWRITE_TAC[POW_2_SQRT_ABS] THEN + REWRITE_TAC[REAL_ABS_MUL; REAL_ABS_INV; REAL_ABS_NUM] THEN + ONCE_REWRITE_TAC[AC REAL_MUL_AC + `&2 * (i * a') * a * h = i * (&2 * h) * a * a'`] THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN + REWRITE_TAC[REAL_MUL_LID; GSYM real_div] THEN + ASM_SIMP_TAC[REAL_DIV_REFL; REAL_ABS_ZERO; REAL_MUL_RID]);; + +let CX_SQRT = prove + (`!x. &0 <= x ==> Cx(sqrt x) = csqrt(Cx x)`, + SIMP_TAC[csqrt; IM_CX; RE_CX; COMPLEX_EQ; RE; IM]);; + +let CSQRT_CX = prove + (`!x. &0 <= x ==> csqrt(Cx x) = Cx(sqrt x)`, + SIMP_TAC[CX_SQRT]);; + +let CSQRT_0 = prove + (`csqrt(Cx(&0)) = Cx(&0)`, + SIMP_TAC[CSQRT_CX; REAL_POS; SQRT_0]);; + +let CSQRT_1 = prove + (`csqrt(Cx(&1)) = Cx(&1)`, + SIMP_TAC[CSQRT_CX; REAL_POS; SQRT_1]);; + +let CSQRT_PRINCIPAL = prove + (`!z. &0 < Re(csqrt(z)) \/ Re(csqrt(z)) = &0 /\ &0 <= Im(csqrt(z))`, + GEN_TAC THEN REWRITE_TAC[csqrt] THEN + REPEAT(COND_CASES_TAC THEN ASM_REWRITE_TAC[RE; IM]) THENL + [FIRST_ASSUM(MP_TAC o MATCH_MP SQRT_POS_LE) THEN REAL_ARITH_TAC; + DISJ2_TAC THEN REWRITE_TAC[real_ge] THEN MATCH_MP_TAC SQRT_POS_LE THEN + ASM_REAL_ARITH_TAC; + DISJ1_TAC THEN MATCH_MP_TAC SQRT_POS_LT THEN + MATCH_MP_TAC(REAL_ARITH `abs(y) < x ==> &0 < (x + y) / &2`) THEN + REWRITE_TAC[complex_norm] THEN REWRITE_TAC[GSYM POW_2_SQRT_ABS] THEN + MATCH_MP_TAC SQRT_MONO_LT THEN + REWRITE_TAC[REAL_POW_2; REAL_LE_SQUARE; REAL_LT_ADDR] THEN + REWRITE_TAC[REAL_ARITH `&0 < x <=> &0 <= x /\ ~(x = &0)`] THEN + ASM_REWRITE_TAC[REAL_LE_SQUARE; REAL_ENTIRE]]);; + +let RE_CSQRT = prove + (`!z. &0 <= Re(csqrt z)`, + MP_TAC CSQRT_PRINCIPAL THEN MATCH_MP_TAC MONO_FORALL THEN REAL_ARITH_TAC);; + +let CSQRT_UNIQUE = prove + (`!s z. s pow 2 = z /\ (&0 < Re s \/ Re s = &0 /\ &0 <= Im s) + ==> csqrt z = s`, + REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN ASSUME_TAC) THEN + FIRST_X_ASSUM(SUBST_ALL_TAC o SYM) THEN + MP_TAC(SPEC `(s:complex) pow 2` CSQRT) THEN + SIMP_TAC[COMPLEX_RING `a pow 2 = b pow 2 <=> a = b \/ a = --b:complex`] THEN + STRIP_TAC THEN ASM_REWRITE_TAC[COMPLEX_RING `--z = z <=> z = Cx(&0)`] THEN + FIRST_ASSUM(MP_TAC o AP_TERM `Re`) THEN + FIRST_X_ASSUM(MP_TAC o AP_TERM `Im`) THEN + REWRITE_TAC[RE_NEG; IM_NEG; COMPLEX_EQ; RE_CX; IM_CX] THEN + MP_TAC(SPEC `(s:complex) pow 2` CSQRT_PRINCIPAL) THEN + POP_ASSUM MP_TAC THEN REAL_ARITH_TAC);; + +let POW_2_CSQRT = prove + (`!z. &0 < Re z \/ Re(z) = &0 /\ &0 <= Im(z) ==> csqrt(z pow 2) = z`, + MESON_TAC[CSQRT_UNIQUE]);; + +let CSQRT_EQ_0 = prove + (`!z. csqrt z = Cx(&0) <=> z = Cx(&0)`, + GEN_TAC THEN MP_TAC (SPEC `z:complex` CSQRT) THEN CONV_TAC COMPLEX_RING);; + +(* ------------------------------------------------------------------------- *) +(* A few more complex-specific cases of vector notions. *) +(* ------------------------------------------------------------------------- *) + +let COMPLEX_CMUL = prove + (`!c x. c % x = Cx(c) * x`, + SIMP_TAC[CART_EQ; VECTOR_MUL_COMPONENT; CX_DEF; complex; + complex_mul; DIMINDEX_2; FORALL_2; IM_DEF; RE_DEF; VECTOR_2] THEN + REAL_ARITH_TAC);; + +let LINEAR_COMPLEX_MUL = prove + (`!c. linear (\x. c * x)`, + REWRITE_TAC[linear; COMPLEX_CMUL] THEN CONV_TAC COMPLEX_RING);; + +let BILINEAR_COMPLEX_MUL = prove + (`bilinear( * )`, + REWRITE_TAC[bilinear; linear; COMPLEX_CMUL] THEN CONV_TAC COMPLEX_RING);; + +let LINEAR_CNJ = prove + (`linear cnj`, + REWRITE_TAC[linear; COMPLEX_CMUL; CNJ_ADD; CNJ_MUL; CNJ_CX]);; + +(* ------------------------------------------------------------------------- *) +(* Complex-specific theorems about sums. *) +(* ------------------------------------------------------------------------- *) + +let RE_VSUM = prove + (`!f s. FINITE s ==> Re(vsum s f) = sum s (\x. Re(f x))`, + SIMP_TAC[RE_DEF; VSUM_COMPONENT; DIMINDEX_2; ARITH]);; + +let IM_VSUM = prove + (`!f s. FINITE s ==> Im(vsum s f) = sum s (\x. Im(f x))`, + SIMP_TAC[IM_DEF; VSUM_COMPONENT; DIMINDEX_2; ARITH]);; + +let VSUM_COMPLEX_LMUL = prove + (`!c f s. FINITE(s) ==> vsum s (\x. c * f x) = c * vsum s f`, + GEN_TAC THEN GEN_TAC THEN MATCH_MP_TAC FINITE_INDUCT_STRONG THEN + SIMP_TAC[VSUM_CLAUSES; COMPLEX_VEC_0; COMPLEX_MUL_RZERO] THEN + SIMPLE_COMPLEX_ARITH_TAC);; + +let VSUM_COMPLEX_RMUL = prove + (`!c f s. FINITE(s) ==> vsum s (\x. f x * c) = vsum s f * c`, + ONCE_REWRITE_TAC[COMPLEX_MUL_SYM] THEN REWRITE_TAC[VSUM_COMPLEX_LMUL]);; + +let VSUM_CX = prove + (`!f:A->real s. FINITE s ==> vsum s (\a. Cx(f a)) = Cx(sum s f)`, + GEN_TAC THEN MATCH_MP_TAC FINITE_INDUCT_STRONG THEN + SIMP_TAC[SUM_CLAUSES; VSUM_CLAUSES; COMPLEX_VEC_0; CX_ADD]);; + +let CNJ_VSUM = prove + (`!f s. FINITE s ==> cnj(vsum s f) = vsum s (\x. cnj(f x))`, + GEN_TAC THEN MATCH_MP_TAC FINITE_INDUCT_STRONG THEN + SIMP_TAC[VSUM_CLAUSES; CNJ_ADD; CNJ_CX; COMPLEX_VEC_0]);; + +let VSUM_CX_NUMSEG = prove + (`!f m n. vsum (m..n) (\a. Cx(f a)) = Cx(sum (m..n) f)`, + SIMP_TAC[VSUM_CX; FINITE_NUMSEG]);; + +let COMPLEX_SUB_POW = prove + (`!x y n. + 1 <= n ==> x pow n - y pow n = + (x - y) * vsum(0..n-1) (\i. x pow i * y pow (n - 1 - i))`, + SIMP_TAC[GSYM VSUM_COMPLEX_LMUL; FINITE_NUMSEG] THEN + REWRITE_TAC[COMPLEX_RING + `(x - y) * (a * b):complex = (x * a) * b - a * (y * b)`] THEN + SIMP_TAC[GSYM complex_pow; ADD1; ARITH_RULE + `1 <= n /\ x <= n - 1 + ==> n - 1 - x = n - (x + 1) /\ SUC(n - 1 - x) = n - x`] THEN + REWRITE_TAC[VSUM_DIFFS_ALT; LE_0] THEN + SIMP_TAC[SUB_0; SUB_ADD; SUB_REFL; + complex_pow; COMPLEX_MUL_LID; COMPLEX_MUL_RID]);; + +let COMPLEX_SUB_POW_R1 = prove + (`!x n. 1 <= n + ==> x pow n - Cx(&1) = (x - Cx(&1)) * vsum(0..n-1) (\i. x pow i)`, + REPEAT GEN_TAC THEN + DISCH_THEN(MP_TAC o SPECL [`x:complex`; `Cx(&1)`] o + MATCH_MP COMPLEX_SUB_POW) THEN + REWRITE_TAC[COMPLEX_POW_ONE; COMPLEX_MUL_RID]);; + +let COMPLEX_SUB_POW_L1 = prove + (`!x n. 1 <= n + ==> Cx(&1) - x pow n = (Cx(&1) - x) * vsum(0..n-1) (\i. x pow i)`, + ONCE_REWRITE_TAC[GSYM COMPLEX_NEG_SUB] THEN + SIMP_TAC[COMPLEX_SUB_POW_R1] THEN REWRITE_TAC[COMPLEX_MUL_LNEG]);; + +(* ------------------------------------------------------------------------- *) +(* The complex numbers that are real (zero imaginary part). *) +(* ------------------------------------------------------------------------- *) + +let real = new_definition + `real z <=> Im z = &0`;; + +let REAL = prove + (`!z. real z <=> Cx(Re z) = z`, + REWRITE_TAC[COMPLEX_EQ; real; CX_DEF; RE; IM] THEN REAL_ARITH_TAC);; + +let REAL_CNJ = prove + (`!z. real z <=> cnj z = z`, + REWRITE_TAC[real; cnj; COMPLEX_EQ; RE; IM] THEN REAL_ARITH_TAC);; + +let REAL_IMP_CNJ = prove + (`!z. real z ==> cnj z = z`, + REWRITE_TAC[REAL_CNJ]);; + +let REAL_EXISTS = prove + (`!z. real z <=> ?x. z = Cx x`, + MESON_TAC[REAL; real; IM_CX]);; + +let FORALL_REAL = prove + (`(!z. real z ==> P z) <=> (!x. P(Cx x))`, + MESON_TAC[REAL_EXISTS]);; + +let EXISTS_REAL = prove + (`(?z. real z /\ P z) <=> (?x. P(Cx x))`, + MESON_TAC[REAL_EXISTS]);; + +let REAL_CX = prove + (`!x. real(Cx x)`, + REWRITE_TAC[REAL_CNJ; CNJ_CX]);; + +let REAL_MUL_CX = prove + (`!x z. real(Cx x * z) <=> x = &0 \/ real z`, + REWRITE_TAC[real; IM_MUL_CX; REAL_ENTIRE]);; + +let REAL_ADD = prove + (`!w z. real w /\ real z ==> real(w + z)`, + SIMP_TAC[REAL_CNJ; CNJ_ADD]);; + +let REAL_NEG = prove + (`!z. real z ==> real(--z)`, + SIMP_TAC[REAL_CNJ; CNJ_NEG]);; + +let REAL_SUB = prove + (`!w z. real w /\ real z ==> real(w - z)`, + SIMP_TAC[REAL_CNJ; CNJ_SUB]);; + +let REAL_MUL = prove + (`!w z. real w /\ real z ==> real(w * z)`, + SIMP_TAC[REAL_CNJ; CNJ_MUL]);; + +let REAL_POW = prove + (`!z n. real z ==> real(z pow n)`, + SIMP_TAC[REAL_CNJ; CNJ_POW]);; + +let REAL_INV = prove + (`!z. real z ==> real(inv z)`, + SIMP_TAC[REAL_CNJ; CNJ_INV]);; + +let REAL_INV_EQ = prove + (`!z. real(inv z) = real z`, + MESON_TAC[REAL_INV; COMPLEX_INV_INV]);; + +let REAL_DIV = prove + (`!w z. real w /\ real z ==> real(w / z)`, + SIMP_TAC[REAL_CNJ; CNJ_DIV]);; + +let REAL_VSUM = prove + (`!f s. FINITE s /\ (!a. a IN s ==> real(f a)) ==> real(vsum s f)`, + SIMP_TAC[CNJ_VSUM; REAL_CNJ]);; + +let REAL_SEGMENT = prove + (`!a b x. x IN segment[a,b] /\ real a /\ real b ==> real x`, + SIMP_TAC[segment; IN_ELIM_THM; real; COMPLEX_EQ; LEFT_AND_EXISTS_THM; + LEFT_IMP_EXISTS_THM; IM_ADD; IM_CMUL] THEN + REAL_ARITH_TAC);; + +let IN_SEGMENT_CX = prove + (`!a b x. Cx(x) IN segment[Cx(a),Cx(b)] <=> + a <= x /\ x <= b \/ b <= x /\ x <= a`, + REPEAT STRIP_TAC THEN REWRITE_TAC[segment; IN_ELIM_THM] THEN + REWRITE_TAC[COMPLEX_CMUL; GSYM CX_ADD; CX_INJ; GSYM CX_MUL] THEN + ASM_CASES_TAC `a:real = b` THENL + [ASM_REWRITE_TAC[REAL_ARITH `(&1 - u) * b + u * b = b`] THEN + ASM_CASES_TAC `x:real = b` THEN ASM_REWRITE_TAC[REAL_LE_ANTISYM] THEN + EXISTS_TAC `&0` THEN REWRITE_TAC[REAL_POS]; + ALL_TAC] THEN + EQ_TAC THENL + [DISCH_THEN(X_CHOOSE_THEN `u:real` + (CONJUNCTS_THEN2 STRIP_ASSUME_TAC SUBST1_TAC)) THEN + REWRITE_TAC[REAL_ARITH `a <= (&1 - u) * a + u * b <=> &0 <= u * (b - a)`; + REAL_ARITH `b <= (&1 - u) * a + u * b <=> &0 <= (&1 - u) * (a - b)`; + REAL_ARITH `(&1 - u) * a + u * b <= a <=> &0 <= u * (a - b)`; + REAL_ARITH `(&1 - u) * a + u * b <= b <=> &0 <= (&1 - u) * (b - a)`] THEN + DISJ_CASES_TAC(REAL_ARITH `a <= b \/ b <= a`) THENL + [DISJ1_TAC; DISJ2_TAC] THEN + CONJ_TAC THEN MATCH_MP_TAC REAL_LE_MUL THEN + ASM_REAL_ARITH_TAC; + ALL_TAC] THEN + STRIP_TAC THENL + [SUBGOAL_THEN `&0 < b - a` ASSUME_TAC THENL + [ASM_REAL_ARITH_TAC; + EXISTS_TAC `(x - a:real) / (b - a)`]; + SUBGOAL_THEN `&0 < a - b` ASSUME_TAC THENL + [ASM_REAL_ARITH_TAC; + EXISTS_TAC `(a - x:real) / (a - b)`]] THEN + (CONJ_TAC THENL + [ALL_TAC; UNDISCH_TAC `~(a:real = b)` THEN CONV_TAC REAL_FIELD]) THEN + ASM_SIMP_TAC[REAL_LE_LDIV_EQ; REAL_LE_RDIV_EQ] THEN + ASM_REAL_ARITH_TAC);; + +let IN_SEGMENT_CX_GEN = prove + (`!a b x. + x IN segment[Cx a,Cx b] <=> + Im(x) = &0 /\ (a <= Re x /\ Re x <= b \/ b <= Re x /\ Re x <= a)`, + REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM real] THEN + ASM_CASES_TAC `real x` THENL + [FIRST_X_ASSUM(SUBST1_TAC o SYM o REWRITE_RULE[REAL]) THEN + REWRITE_TAC[IN_SEGMENT_CX; REAL_CX; RE_CX] THEN REAL_ARITH_TAC; + ASM_MESON_TAC[REAL_SEGMENT; REAL_CX]]);; + +let RE_POS_SEGMENT = prove + (`!a b x. x IN segment[a,b] /\ &0 < Re a /\ &0 < Re b ==> &0 < Re x`, + SIMP_TAC[segment; IN_ELIM_THM; real; COMPLEX_EQ; LEFT_AND_EXISTS_THM; + LEFT_IMP_EXISTS_THM; RE_ADD; RE_CMUL] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC(REAL_ARITH + `&0 <= x /\ &0 <= y /\ ~(x = &0 /\ y = &0) ==> &0 < x + y`) THEN + ASM_SIMP_TAC[REAL_LE_MUL; REAL_SUB_LE; REAL_LT_IMP_LE; REAL_ENTIRE] THEN + ASM_REAL_ARITH_TAC);; + +let CONVEX_REAL = prove + (`convex real`, + REWRITE_TAC[convex; IN; COMPLEX_CMUL] THEN + SIMP_TAC[REAL_ADD; REAL_MUL; REAL_CX]);; + +let IMAGE_CX = prove + (`!s. IMAGE Cx s = {z | real z /\ Re(z) IN s}`, + REWRITE_TAC[EXTENSION; IN_ELIM_THM; IN_IMAGE] THEN MESON_TAC[RE_CX; REAL]);; + +(* ------------------------------------------------------------------------- *) +(* Useful bound-type theorems for real quantities. *) +(* ------------------------------------------------------------------------- *) + +let REAL_NORM = prove + (`!z. real z ==> norm(z) = abs(Re z)`, + SIMP_TAC[real; complex_norm] THEN CONV_TAC REAL_RAT_REDUCE_CONV THEN + REWRITE_TAC[POW_2_SQRT_ABS; REAL_ADD_RID]);; + +let REAL_NORM_POS = prove + (`!z. real z /\ &0 <= Re z ==> norm(z) = Re(z)`, + SIMP_TAC[REAL_NORM] THEN REAL_ARITH_TAC);; + +let COMPLEX_NORM_VSUM_SUM_RE = prove + (`!f s. FINITE s /\ (!x. x IN s ==> real(f x) /\ &0 <= Re(f x)) + ==> norm(vsum s f) = sum s (\x. Re(f x))`, + SIMP_TAC[GSYM RE_VSUM] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC REAL_NORM_POS THEN + ASM_SIMP_TAC[REAL_VSUM; RE_VSUM; SUM_POS_LE]);; + +let COMPLEX_NORM_VSUM_BOUND = prove + (`!s f:A->complex g:A->complex. + FINITE s /\ (!x. x IN s ==> real(g x) /\ norm(f x) <= Re(g x)) + ==> norm(vsum s f) <= norm(vsum s g)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `sum s (\x. norm((f:A->complex) x))` THEN + ASM_SIMP_TAC[VSUM_NORM] THEN + MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `sum s (\x. Re((g:A->complex) x))` THEN + ASM_SIMP_TAC[SUM_LE] THEN + MATCH_MP_TAC(REAL_ARITH `x:real = y ==> y <= x`) THEN + MATCH_MP_TAC COMPLEX_NORM_VSUM_SUM_RE THEN + ASM_MESON_TAC[REAL_LE_TRANS; NORM_POS_LE]);; + +let COMPLEX_NORM_VSUM_BOUND_SUBSET = prove + (`!f:A->complex g:A->complex s t. + FINITE s /\ t SUBSET s /\ + (!x. x IN s ==> real(g x) /\ norm(f x) <= Re(g x)) + ==> norm(vsum t f) <= norm(vsum s g)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `norm(vsum t (g:A->complex))` THEN CONJ_TAC THENL + [ASM_MESON_TAC[COMPLEX_NORM_VSUM_BOUND; SUBSET; FINITE_SUBSET];ALL_TAC] THEN + SUBGOAL_THEN + `norm(vsum t (g:A->complex)) = sum t (\x. Re(g x)) /\ + norm(vsum s g) = sum s (\x. Re(g x))` + (CONJUNCTS_THEN SUBST1_TAC) + THENL + [CONJ_TAC THEN MATCH_MP_TAC COMPLEX_NORM_VSUM_SUM_RE; + MATCH_MP_TAC SUM_SUBSET THEN REWRITE_TAC[IN_DIFF]] THEN + ASM_MESON_TAC[REAL_LE_TRANS; NORM_POS_LE; FINITE_SUBSET; SUBSET]);; + +(* ------------------------------------------------------------------------- *) +(* Geometric progression. *) +(* ------------------------------------------------------------------------- *) + +let VSUM_GP_BASIC = prove + (`!x n. (Cx(&1) - x) * vsum(0..n) (\i. x pow i) = Cx(&1) - x pow (SUC n)`, + GEN_TAC THEN INDUCT_TAC THEN REWRITE_TAC[VSUM_CLAUSES_NUMSEG] THEN + REWRITE_TAC[complex_pow; COMPLEX_MUL_RID; LE_0] THEN + ASM_REWRITE_TAC[COMPLEX_ADD_LDISTRIB; complex_pow] THEN + SIMPLE_COMPLEX_ARITH_TAC);; + +let VSUM_GP_MULTIPLIED = prove + (`!x m n. m <= n + ==> ((Cx(&1) - x) * vsum(m..n) (\i. x pow i) = + x pow m - x pow (SUC n))`, + REPEAT STRIP_TAC THEN + ASM_SIMP_TAC[VSUM_OFFSET_0; COMPLEX_POW_ADD; FINITE_NUMSEG; + COMPLEX_MUL_ASSOC; VSUM_GP_BASIC; VSUM_COMPLEX_RMUL] THEN + REWRITE_TAC[COMPLEX_SUB_RDISTRIB; GSYM COMPLEX_POW_ADD; COMPLEX_MUL_LID] THEN + ASM_SIMP_TAC[ARITH_RULE `m <= n ==> (SUC(n - m) + m = SUC n)`]);; + +let VSUM_GP = prove + (`!x m n. + vsum(m..n) (\i. x pow i) = + if n < m then Cx(&0) + else if x = Cx(&1) then Cx(&((n + 1) - m)) + else (x pow m - x pow (SUC n)) / (Cx(&1) - x)`, + REPEAT GEN_TAC THEN + DISJ_CASES_TAC(ARITH_RULE `n < m \/ ~(n < m) /\ m <= n:num`) THEN + ASM_SIMP_TAC[VSUM_TRIV_NUMSEG; COMPLEX_VEC_0] THEN COND_CASES_TAC THENL + [ASM_REWRITE_TAC[COMPLEX_POW_ONE; VSUM_CONST_NUMSEG; COMPLEX_MUL_RID]; + ALL_TAC] THEN + REWRITE_TAC[COMPLEX_CMUL; COMPLEX_MUL_RID] THEN + MATCH_MP_TAC(COMPLEX_FIELD + `~(z = Cx(&1)) /\ (Cx(&1) - z) * x = y ==> x = y / (Cx(&1) - z)`) THEN + ASM_SIMP_TAC[COMPLEX_DIV_LMUL; COMPLEX_SUB_0; VSUM_GP_MULTIPLIED]);; + +let VSUM_GP_OFFSET = prove + (`!x m n. vsum(m..m+n) (\i. x pow i) = + if x = Cx(&1) then Cx(&n) + Cx(&1) + else x pow m * (Cx(&1) - x pow (SUC n)) / (Cx(&1) - x)`, + REPEAT GEN_TAC THEN REWRITE_TAC[VSUM_GP; ARITH_RULE `~(m + n < m:num)`] THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[] THENL + [REWRITE_TAC[REAL_OF_NUM_ADD; GSYM CX_ADD] THEN + AP_TERM_TAC THEN AP_TERM_TAC THEN ARITH_TAC; + REWRITE_TAC[complex_div; complex_pow; COMPLEX_POW_ADD] THEN + SIMPLE_COMPLEX_ARITH_TAC]);; + +(* ------------------------------------------------------------------------- *) +(* Basics about polynomial functions: extremal behaviour and root counts. *) +(* ------------------------------------------------------------------------- *) + +let COMPLEX_SUB_POLYFUN = prove + (`!a x y n. + 1 <= n + ==> vsum(0..n) (\i. a i * x pow i) - vsum(0..n) (\i. a i * y pow i) = + (x - y) * + vsum(0..n-1) (\j. vsum(j+1..n) (\i. a i * y pow (i - j - 1)) * x pow j)`, + REPEAT STRIP_TAC THEN + REWRITE_TAC[GSYM VSUM_SUB_NUMSEG; GSYM COMPLEX_SUB_LDISTRIB] THEN + GEN_REWRITE_TAC LAND_CONV [MATCH_MP VSUM_CLAUSES_LEFT (SPEC_ALL LE_0)] THEN + REWRITE_TAC[COMPLEX_SUB_REFL; complex_pow; COMPLEX_MUL_RZERO; + COMPLEX_ADD_LID] THEN + SIMP_TAC[COMPLEX_SUB_POW; ADD_CLAUSES] THEN + ONCE_REWRITE_TAC[COMPLEX_RING `a * x * s:complex = x * a * s`] THEN + SIMP_TAC[VSUM_COMPLEX_LMUL; FINITE_NUMSEG] THEN AP_TERM_TAC THEN + SIMP_TAC[GSYM VSUM_COMPLEX_LMUL; GSYM VSUM_COMPLEX_RMUL; FINITE_NUMSEG; + VSUM_VSUM_PRODUCT; FINITE_NUMSEG] THEN + MATCH_MP_TAC VSUM_EQ_GENERAL_INVERSES THEN + REPEAT(EXISTS_TAC `\(x:num,y:num). (y,x)`) THEN + REWRITE_TAC[FORALL_IN_GSPEC; IN_ELIM_PAIR_THM; IN_NUMSEG] THEN + REWRITE_TAC[ARITH_RULE `a - b - c:num = a - (b + c)`; ADD_SYM] THEN + REWRITE_TAC[COMPLEX_MUL_AC] THEN ARITH_TAC);; + +let COMPLEX_SUB_POLYFUN_ALT = prove + (`!a x y n. + 1 <= n + ==> vsum(0..n) (\i. a i * x pow i) - vsum(0..n) (\i. a i * y pow i) = + (x - y) * + vsum(0..n-1) (\j. vsum(0..n-j-1) (\k. a(j+k+1) * y pow k) * x pow j)`, + REPEAT STRIP_TAC THEN ASM_SIMP_TAC[COMPLEX_SUB_POLYFUN] THEN AP_TERM_TAC THEN + MATCH_MP_TAC VSUM_EQ_NUMSEG THEN X_GEN_TAC `j:num` THEN REPEAT STRIP_TAC THEN + REWRITE_TAC[] THEN AP_THM_TAC THEN AP_TERM_TAC THEN + MATCH_MP_TAC VSUM_EQ_GENERAL_INVERSES THEN + MAP_EVERY EXISTS_TAC + [`\i. i - (j + 1)`; `\k. j + k + 1`] THEN + REWRITE_TAC[IN_NUMSEG] THEN REPEAT STRIP_TAC THEN + TRY(BINOP_TAC THEN AP_TERM_TAC) THEN ASM_ARITH_TAC);; + +let COMPLEX_POLYFUN_LINEAR_FACTOR = prove + (`!a c n. ?b. !z. vsum(0..n) (\i. c(i) * z pow i) = + (z - a) * vsum(0..n-1) (\i. b(i) * z pow i) + + vsum(0..n) (\i. c(i) * a pow i)`, + REPEAT GEN_TAC THEN REWRITE_TAC[GSYM COMPLEX_EQ_SUB_RADD] THEN + ASM_CASES_TAC `n = 0` THENL + [EXISTS_TAC `\i:num. Cx(&0)` THEN + ASM_SIMP_TAC[VSUM_SING; NUMSEG_SING; complex_pow; COMPLEX_MUL_LZERO] THEN + REWRITE_TAC[COMPLEX_SUB_REFL; GSYM COMPLEX_VEC_0; VSUM_0] THEN + REWRITE_TAC[COMPLEX_VEC_0; COMPLEX_MUL_RZERO]; + ASM_SIMP_TAC[COMPLEX_SUB_POLYFUN; LE_1] THEN + EXISTS_TAC `\j. vsum (j + 1..n) (\i. c i * a pow (i - j - 1))` THEN + REWRITE_TAC[]]);; + +let COMPLEX_POLYFUN_LINEAR_FACTOR_ROOT = prove + (`!a c n. vsum(0..n) (\i. c(i) * a pow i) = Cx(&0) + ==> ?b. !z. vsum(0..n) (\i. c(i) * z pow i) = + (z - a) * vsum(0..n-1) (\i. b(i) * z pow i)`, + MESON_TAC[COMPLEX_POLYFUN_LINEAR_FACTOR; COMPLEX_ADD_RID]);; + +let COMPLEX_POLYFUN_EXTREMAL_LEMMA = prove + (`!c n e. &0 < e + ==> ?M. !z. M <= norm(z) + ==> norm(vsum(0..n) (\i. c(i) * z pow i)) + <= e * norm(z) pow (n + 1)`, + GEN_TAC THEN INDUCT_TAC THEN SIMP_TAC[VSUM_CLAUSES_NUMSEG; LE_0] THEN + REPEAT STRIP_TAC THENL + [REWRITE_TAC[ADD_CLAUSES; complex_pow; REAL_POW_1; COMPLEX_MUL_RID] THEN + EXISTS_TAC `norm(c 0:complex) / e` THEN ASM_SIMP_TAC[REAL_LE_LDIV_EQ] THEN + REWRITE_TAC[REAL_MUL_AC]; + ALL_TAC] THEN + FIRST_X_ASSUM(MP_TAC o C MATCH_MP (REAL_ARITH `&0 < &1 / &2`)) THEN + DISCH_THEN(X_CHOOSE_TAC `M:real`) THEN + EXISTS_TAC `max M ((&1 / &2 + norm(c(n+1):complex)) / e)` THEN + X_GEN_TAC `z:complex` THEN REWRITE_TAC[REAL_MAX_LE] THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `z:complex`) THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC(NORM_ARITH + `a + norm(y) <= b ==> norm(x) <= a ==> norm(x + y) <= b`) THEN + SIMP_TAC[ADD1; COMPLEX_NORM_MUL; COMPLEX_NORM_POW; + GSYM REAL_ADD_RDISTRIB; ARITH_RULE `(n + 1) + 1 = 1 + n + 1`] THEN + GEN_REWRITE_TAC (RAND_CONV o RAND_CONV) [REAL_POW_ADD] THEN + REWRITE_TAC[REAL_MUL_ASSOC] THEN MATCH_MP_TAC REAL_LE_RMUL THEN + ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN + ASM_SIMP_TAC[GSYM REAL_LE_LDIV_EQ; REAL_POW_LE; NORM_POS_LE; REAL_POW_1]);; + +let COMPLEX_POLYFUN_EXTREMAL = prove + (`!c n. (!k. k IN 1..n ==> c(k) = Cx(&0)) \/ + !B. eventually (\z. norm(vsum(0..n) (\i. c(i) * z pow i)) >= B) + at_infinity`, + GEN_TAC THEN MATCH_MP_TAC num_WF THEN X_GEN_TAC `n:num` THEN DISCH_TAC THEN + ASM_CASES_TAC `n = 0` THEN + ASM_REWRITE_TAC[NUMSEG_CLAUSES; ARITH; NOT_IN_EMPTY] THEN + MP_TAC(ARITH_RULE `0 <= n`) THEN SIMP_TAC[GSYM NUMSEG_RREC] THEN + DISCH_THEN(K ALL_TAC) THEN ASM_CASES_TAC `c(n:num) = Cx(&0)` THENL + [FIRST_X_ASSUM(MP_TAC o SPEC `n - 1`) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN + ASM_SIMP_TAC[GSYM NUMSEG_RREC; LE_1] THEN + SIMP_TAC[IN_INSERT; VSUM_CLAUSES; FINITE_NUMSEG; IN_NUMSEG] THEN + ASM_REWRITE_TAC[COMPLEX_MUL_LZERO; COMPLEX_ADD_LID; COND_ID] THEN + ASM_MESON_TAC[]; + DISJ2_TAC THEN MP_TAC(ISPECL + [`c:num->complex`; `n - 1`; `norm(c(n:num):complex) / &2`] + COMPLEX_POLYFUN_EXTREMAL_LEMMA) THEN ASM_SIMP_TAC[SUB_ADD; LE_1] THEN + ASM_SIMP_TAC[COMPLEX_NORM_NZ; REAL_LT_DIV; REAL_OF_NUM_LT; ARITH] THEN + SIMP_TAC[IN_INSERT; VSUM_CLAUSES; FINITE_NUMSEG; IN_NUMSEG] THEN + ASM_SIMP_TAC[ARITH_RULE `~(n = 0) ==> ~(n <= n - 1)`] THEN + DISCH_THEN(X_CHOOSE_TAC `M:real`) THEN X_GEN_TAC `B:real` THEN + REWRITE_TAC[EVENTUALLY_AT_INFINITY] THEN EXISTS_TAC + `max M (max (&1) ((abs B + &1) / (norm(c(n:num):complex) / &2)))` THEN + X_GEN_TAC `z:complex` THEN REWRITE_TAC[real_ge; REAL_MAX_LE] THEN + STRIP_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC `z:complex`) THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC(NORM_ARITH + `abs b + &1 <= norm(y) - a ==> norm(x) <= a ==> b <= norm(y + x)`) THEN + REWRITE_TAC[COMPLEX_NORM_MUL; COMPLEX_NORM_POW] THEN + REWRITE_TAC[REAL_ARITH `c * x - c / &2 * x = x * c / &2`] THEN + ASM_SIMP_TAC[GSYM REAL_LE_LDIV_EQ; COMPLEX_NORM_NZ; REAL_LT_DIV; + REAL_OF_NUM_LT; ARITH] THEN + MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC `norm(z:complex) pow 1` THEN + CONJ_TAC THENL [ASM_REWRITE_TAC[REAL_POW_1]; ALL_TAC] THEN + MATCH_MP_TAC REAL_POW_MONO THEN ASM_SIMP_TAC[LE_1]]);; + +let COMPLEX_POLYFUN_ROOTBOUND = prove + (`!n c. ~(!i. i IN 0..n ==> c(i) = Cx(&0)) + ==> FINITE {z | vsum(0..n) (\i. c(i) * z pow i) = Cx(&0)} /\ + CARD {z | vsum(0..n) (\i. c(i) * z pow i) = Cx(&0)} <= n`, + REWRITE_TAC[TAUT `~a ==> b <=> a \/ b`] THEN INDUCT_TAC THEN GEN_TAC THENL + [SIMP_TAC[NUMSEG_SING; VSUM_SING; IN_SING; complex_pow] THEN + ASM_CASES_TAC `c 0 = Cx(&0)` THEN ASM_REWRITE_TAC[COMPLEX_MUL_RID] THEN + REWRITE_TAC[EMPTY_GSPEC; FINITE_RULES; CARD_CLAUSES; LE_REFL]; + ALL_TAC] THEN + ASM_CASES_TAC `{z | vsum(0..SUC n) (\i. c(i) * z pow i) = Cx(&0)} = {}` THEN + ASM_REWRITE_TAC[FINITE_RULES; CARD_CLAUSES; LE_0] THEN + FIRST_X_ASSUM(X_CHOOSE_THEN `a:complex` MP_TAC o + GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN + REWRITE_TAC[IN_ELIM_THM] THEN DISCH_TAC THEN + FIRST_ASSUM(MP_TAC o MATCH_MP COMPLEX_POLYFUN_LINEAR_FACTOR_ROOT) THEN + DISCH_THEN(X_CHOOSE_TAC `b:num->complex`) THEN + ASM_REWRITE_TAC[COMPLEX_ENTIRE; COMPLEX_SUB_0; SUC_SUB1; SET_RULE + `{z | z = a \/ P z} = a INSERT {z | P z}`] THEN + FIRST_X_ASSUM(MP_TAC o SPEC `b:num->complex`) THEN + STRIP_TAC THEN ASM_SIMP_TAC[CARD_CLAUSES; FINITE_RULES] THENL + [DISJ1_TAC; ASM_ARITH_TAC] THEN + MP_TAC(SPECL [`c:num->complex`; `SUC n`] COMPLEX_POLYFUN_EXTREMAL) THEN + ASM_REWRITE_TAC[] THEN FIRST_X_ASSUM(MP_TAC o SPEC `Cx(&0)`) THEN + ASM_SIMP_TAC[SUC_SUB1; COMPLEX_MUL_LZERO] THEN + SIMP_TAC[COMPLEX_POW_ZERO; COND_RAND; COMPLEX_MUL_RZERO] THEN + ASM_SIMP_TAC[VSUM_0; GSYM COMPLEX_VEC_0; VSUM_DELTA; IN_NUMSEG; LE_0] THEN + REWRITE_TAC[COMPLEX_VEC_0; COMPLEX_MUL_RZERO; COMPLEX_NORM_NUM] THEN + REWRITE_TAC[COMPLEX_MUL_RID; real_ge; EVENTUALLY_AT_INFINITY] THEN + REPEAT STRIP_TAC THENL [ASM_MESON_TAC[LE_1]; ALL_TAC] THEN + FIRST_X_ASSUM(MP_TAC o SPEC `&1`) THEN CONV_TAC REAL_RAT_REDUCE_CONV THEN + MATCH_MP_TAC(TAUT `~a ==> a ==> b`) THEN + REWRITE_TAC[NOT_EXISTS_THM; NOT_FORALL_THM] THEN X_GEN_TAC `b:real` THEN + MP_TAC(SPEC `b:real` (INST_TYPE [`:2`,`:N`] VECTOR_CHOOSE_SIZE)) THEN + ASM_MESON_TAC[NORM_POS_LE; REAL_LE_TOTAL; REAL_LE_TRANS]);; + +let COMPLEX_POLYFUN_FINITE_ROOTS = prove + (`!n c. FINITE {x | vsum(0..n) (\i. c i * x pow i) = Cx(&0)} <=> + ?i. i IN 0..n /\ ~(c i = Cx(&0))`, + REPEAT GEN_TAC THEN REWRITE_TAC[TAUT `a /\ ~b <=> ~(a ==> b)`] THEN + REWRITE_TAC[GSYM NOT_FORALL_THM] THEN EQ_TAC THEN + SIMP_TAC[COMPLEX_POLYFUN_ROOTBOUND] THEN + ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN + SIMP_TAC[COMPLEX_MUL_LZERO] THEN SIMP_TAC[GSYM COMPLEX_VEC_0; VSUM_0] THEN + REWRITE_TAC[SET_RULE `{x | T} = (:complex)`; GSYM INFINITE; + EUCLIDEAN_SPACE_INFINITE]);; + +let COMPLEX_POLYFUN_EQ_0 = prove + (`!n c. (!z. vsum(0..n) (\i. c i * z pow i) = Cx(&0)) <=> + (!i. i IN 0..n ==> c i = Cx(&0))`, + REPEAT GEN_TAC THEN EQ_TAC THEN DISCH_TAC THENL + [GEN_REWRITE_TAC I [TAUT `p <=> ~ ~p`] THEN DISCH_THEN(MP_TAC o MATCH_MP + COMPLEX_POLYFUN_ROOTBOUND) THEN + ASM_REWRITE_TAC[EUCLIDEAN_SPACE_INFINITE; GSYM INFINITE; DE_MORGAN_THM; + SET_RULE `{x | T} = (:complex)`]; + ASM_SIMP_TAC[IN_NUMSEG; LE_0; COMPLEX_MUL_LZERO] THEN + REWRITE_TAC[GSYM COMPLEX_VEC_0; VSUM_0]]);; + +let COMPLEX_POLYFUN_EQ_CONST = prove + (`!n c k. (!z. vsum(0..n) (\i. c i * z pow i) = k) <=> + c 0 = k /\ (!i. i IN 1..n ==> c i = Cx(&0))`, + REPEAT GEN_TAC THEN MATCH_MP_TAC EQ_TRANS THEN EXISTS_TAC + `!x. vsum(0..n) (\i. (if i = 0 then c 0 - k else c i) * x pow i) = + Cx(&0)` THEN + CONJ_TAC THENL + [SIMP_TAC[VSUM_CLAUSES_LEFT; LE_0; complex_pow; COMPLEX_MUL_RID] THEN + REWRITE_TAC[COMPLEX_RING `(c - k) + s = Cx(&0) <=> c + s = k`] THEN + AP_TERM_TAC THEN ABS_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN + AP_TERM_TAC THEN MATCH_MP_TAC VSUM_EQ THEN GEN_TAC THEN + REWRITE_TAC[IN_NUMSEG] THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[ARITH]; + REWRITE_TAC[COMPLEX_POLYFUN_EQ_0; IN_NUMSEG; LE_0] THEN + GEN_REWRITE_TAC LAND_CONV [MESON[] + `(!n. P n) <=> P 0 /\ (!n. ~(n = 0) ==> P n)`] THEN + SIMP_TAC[LE_0; COMPLEX_SUB_0] THEN MESON_TAC[LE_1]]);; + +(* ------------------------------------------------------------------------- *) +(* Complex products. *) +(* ------------------------------------------------------------------------- *) + +let cproduct = new_definition + `cproduct = iterate (( * ):complex->complex->complex)`;; + +let NEUTRAL_COMPLEX_MUL = prove + (`neutral(( * ):complex->complex->complex) = Cx(&1)`, + REWRITE_TAC[neutral] THEN MATCH_MP_TAC SELECT_UNIQUE THEN + MESON_TAC[COMPLEX_MUL_LID; COMPLEX_MUL_RID]);; + +let MONOIDAL_COMPLEX_MUL = prove + (`monoidal(( * ):complex->complex->complex)`, + REWRITE_TAC[monoidal; NEUTRAL_COMPLEX_MUL] THEN SIMPLE_COMPLEX_ARITH_TAC);; + +let CPRODUCT_CLAUSES = prove + (`(!f. cproduct {} f = Cx(&1)) /\ + (!x f s. FINITE(s) + ==> (cproduct (x INSERT s) f = + if x IN s then cproduct s f else f(x) * cproduct s f))`, + REWRITE_TAC[cproduct; GSYM NEUTRAL_COMPLEX_MUL] THEN + ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN + MATCH_MP_TAC ITERATE_CLAUSES THEN REWRITE_TAC[MONOIDAL_COMPLEX_MUL]);; + +let CPRODUCT_EQ_0 = prove + (`!f s. FINITE s ==> (cproduct s f = Cx(&0) <=> ?x. x IN s /\ f(x) = Cx(&0))`, + GEN_TAC THEN MATCH_MP_TAC FINITE_INDUCT_STRONG THEN + SIMP_TAC[CPRODUCT_CLAUSES; COMPLEX_ENTIRE; IN_INSERT; CX_INJ; REAL_OF_NUM_EQ; + ARITH; NOT_IN_EMPTY] THEN + MESON_TAC[]);; + +let CPRODUCT_INV = prove + (`!f s. FINITE s ==> cproduct s (\x. inv(f x)) = inv(cproduct s f)`, + GEN_TAC THEN MATCH_MP_TAC FINITE_INDUCT_STRONG THEN + SIMP_TAC[CPRODUCT_CLAUSES; COMPLEX_INV_1; COMPLEX_INV_MUL]);; + +let CPRODUCT_MUL = prove + (`!f g s. FINITE s + ==> cproduct s (\x. f x * g x) = cproduct s f * cproduct s g`, + GEN_TAC THEN GEN_TAC THEN MATCH_MP_TAC FINITE_INDUCT_STRONG THEN + SIMP_TAC[CPRODUCT_CLAUSES; COMPLEX_MUL_AC; COMPLEX_MUL_LID]);; + +let CPRODUCT_EQ_1 = prove + (`!f s. (!x:A. x IN s ==> (f(x) = Cx(&1))) ==> (cproduct s f = Cx(&1))`, + REWRITE_TAC[cproduct; GSYM NEUTRAL_COMPLEX_MUL] THEN + SIMP_TAC[ITERATE_EQ_NEUTRAL; MONOIDAL_COMPLEX_MUL]);; + +let CPRODUCT_1 = prove + (`!s. cproduct s (\n. Cx(&1)) = Cx(&1)`, + SIMP_TAC[CPRODUCT_EQ_1]);; + +let CPRODUCT_POW = prove + (`!f s n. FINITE s + ==> cproduct s (\x. f x pow n) = (cproduct s f) pow n`, + GEN_TAC THEN GEN_TAC THEN REWRITE_TAC[RIGHT_FORALL_IMP_THM] THEN + DISCH_TAC THEN INDUCT_TAC THEN + ASM_SIMP_TAC[complex_pow; CPRODUCT_MUL; CPRODUCT_1]);; + +let NORM_CPRODUCT = prove + (`!f s. FINITE s ==> norm(cproduct s f) = product s (\x. norm(f x))`, + GEN_TAC THEN MATCH_MP_TAC FINITE_INDUCT_STRONG THEN + SIMP_TAC[CPRODUCT_CLAUSES; COMPLEX_NORM_CX; REAL_ABS_NUM; + CPRODUCT_MUL; PRODUCT_CLAUSES; COMPLEX_NORM_MUL]);; + +let CPRODUCT_EQ = prove + (`!f g s. (!x. x IN s ==> (f x = g x)) ==> cproduct s f = cproduct s g`, + REWRITE_TAC[cproduct] THEN MATCH_MP_TAC ITERATE_EQ THEN + REWRITE_TAC[MONOIDAL_COMPLEX_MUL]);; diff --git a/Multivariate/convex.ml b/Multivariate/convex.ml new file mode 100644 index 0000000..05ebcdf --- /dev/null +++ b/Multivariate/convex.ml @@ -0,0 +1,11398 @@ +(* ========================================================================= *) +(* Convex sets, functions and related things. *) +(* *) +(* (c) Copyright, John Harrison 1998-2008 *) +(* (c) Copyright, Lars Schewe 2007 *) +(* (c) Copyright, Valentina Bruno 2010 *) +(* ========================================================================= *) + +needs "Multivariate/topology.ml";; + +(* ------------------------------------------------------------------------- *) +(* Some miscelleneous things that are convenient to prove here. *) +(* ------------------------------------------------------------------------- *) + +let TRANSLATION_GALOIS = prove + (`!s t a:real^N. s = IMAGE (\x. a + x) t <=> t = IMAGE (\x. --a + x) s`, + REPEAT STRIP_TAC THEN EQ_TAC THEN DISCH_TAC THEN + ASM_REWRITE_TAC[GSYM IMAGE_o; o_DEF] THEN + REWRITE_TAC[VECTOR_ARITH `--a + a + x:real^N = x`; + VECTOR_ARITH `a + --a + x:real^N = x`] THEN + REWRITE_TAC[IMAGE_ID]);; + +let TRANSLATION_EQ_IMP = prove + (`!P:(real^N->bool)->bool. + (!a s. P(IMAGE (\x. a + x) s) <=> P s) <=> + (!a s. P s ==> P (IMAGE (\x. a + x) s))`, + REPEAT GEN_TAC THEN EQ_TAC THEN DISCH_TAC THEN ASM_REWRITE_TAC[] THEN + MAP_EVERY X_GEN_TAC [`a:real^N`; `s:real^N->bool`] THEN + EQ_TAC THEN ASM_REWRITE_TAC[] THEN DISCH_TAC THEN FIRST_X_ASSUM + (MP_TAC o SPECL [`--a:real^N`; `IMAGE (\x:real^N. a + x) s`]) THEN + ASM_REWRITE_TAC[GSYM IMAGE_o; o_DEF; IMAGE_ID; + VECTOR_ARITH `--a + a + x:real^N = x`]);; + +let DIM_HYPERPLANE = prove + (`!a:real^N. ~(a = vec 0) ==> dim {x | a dot x = &0} = dimindex(:N) - 1`, + GEOM_BASIS_MULTIPLE_TAC 1 `a:real^N` THEN + SIMP_TAC[VECTOR_MUL_EQ_0; DE_MORGAN_THM; DOT_LMUL; DOT_BASIS; + DIMINDEX_GE_1; LE_REFL; REAL_ENTIRE; DIM_SPECIAL_HYPERPLANE]);; + +let LOWDIM_EQ_HYPERPLANE = prove + (`!s. dim s = dimindex(:N) - 1 + ==> ?a:real^N. ~(a = vec 0) /\ span s = {x | a dot x = &0}`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPEC `s:real^N->bool` LOWDIM_SUBSET_HYPERPLANE) THEN + ASM_SIMP_TAC[DIMINDEX_GE_1; ARITH_RULE `1 <= a ==> a - 1 < a`] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `a:real^N` THEN STRIP_TAC THEN + ASM_REWRITE_TAC[] THEN + MP_TAC(ISPEC `a:real^N` SUBSPACE_HYPERPLANE) THEN + ONCE_REWRITE_TAC[GSYM SPAN_EQ_SELF] THEN DISCH_THEN(SUBST1_TAC o SYM) THEN + MATCH_MP_TAC DIM_EQ_SPAN THEN + ASM_SIMP_TAC[DIM_HYPERPLANE; LE_REFL] THEN + ASM_MESON_TAC[SUBSET_TRANS; SPAN_INC]);; + +let DIM_EQ_HYPERPLANE = prove + (`!s. dim s = dimindex(:N) - 1 <=> + ?a:real^N. ~(a = vec 0) /\ span s = {x | a dot x = &0}`, + MESON_TAC[DIM_HYPERPLANE; LOWDIM_EQ_HYPERPLANE; DIM_SPAN]);; + +(* ------------------------------------------------------------------------- *) +(* Affine set and affine hull. *) +(* ------------------------------------------------------------------------- *) + +let affine = new_definition + `affine s <=> !x y u v. x IN s /\ y IN s /\ (u + v = &1) + ==> (u % x + v % y) IN s`;; + +let AFFINE_ALT = prove + (`affine s <=> !x y u. x IN s /\ y IN s ==> ((&1 - u) % x + u % y) IN s`, + REWRITE_TAC[affine] THEN + MESON_TAC[REAL_ARITH `(u + v = &1) <=> (u = &1 - v)`]);; + +let AFFINE_SCALING = prove + (`!s c. affine s ==> affine (IMAGE (\x. c % x) s)`, + REWRITE_TAC[affine; IN_IMAGE] THEN REPEAT STRIP_TAC THEN + ASM_REWRITE_TAC[VECTOR_ARITH + `u % c % x + v % c % y = c % (u % x + v % y)`] THEN + ASM_MESON_TAC[]);; + +let AFFINE_SCALING_EQ = prove + (`!s c. ~(c = &0) ==> (affine (IMAGE (\x. c % x) s) <=> affine s)`, + REPEAT STRIP_TAC THEN EQ_TAC THEN REWRITE_TAC[AFFINE_SCALING] THEN + DISCH_THEN(MP_TAC o SPEC `inv c` o MATCH_MP AFFINE_SCALING) THEN + ASM_SIMP_TAC[GSYM IMAGE_o; o_DEF; VECTOR_MUL_ASSOC; + REAL_MUL_LINV; VECTOR_MUL_LID; IMAGE_ID]);; + +let AFFINE_NEGATIONS = prove + (`!s. affine s ==> affine (IMAGE (--) s)`, + REWRITE_TAC[affine; IN_IMAGE] THEN REPEAT STRIP_TAC THEN + ASM_REWRITE_TAC[VECTOR_ARITH + `u % --x + v % --y = --(u % x + v % y)`] THEN + ASM_MESON_TAC[]);; + +let AFFINE_SUMS = prove + (`!s t. affine s /\ affine t ==> affine {x + y | x IN s /\ y IN t}`, + REWRITE_TAC[affine; IN_ELIM_THM] THEN REPEAT STRIP_TAC THEN + ASM_REWRITE_TAC[VECTOR_ARITH + `u % (a + b) + v % (c + d) = (u % a + v % c) + (u % b + v % d)`] THEN + ASM_MESON_TAC[]);; + +let AFFINE_DIFFERENCES = prove + (`!s t. affine s /\ affine t ==> affine {x - y | x IN s /\ y IN t}`, + REWRITE_TAC[affine; IN_ELIM_THM] THEN REPEAT STRIP_TAC THEN + ASM_REWRITE_TAC[VECTOR_ARITH + `u % (a - b) + v % (c - d) = (u % a + v % c) - (u % b + v % d)`] THEN + ASM_MESON_TAC[]);; + +let AFFINE_TRANSLATION_EQ = prove + (`!a:real^N s. affine (IMAGE (\x. a + x) s) <=> affine s`, + REWRITE_TAC[AFFINE_ALT; IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_IMAGE] THEN + REWRITE_TAC[IN_IMAGE; UNWIND_THM1; VECTOR_ARITH + `(&1 - u) % (a + x) + u % (a + y) = a + z <=> (&1 - u) % x + u % y = z`]);; + +add_translation_invariants [AFFINE_TRANSLATION_EQ];; + +let AFFINE_TRANSLATION = prove + (`!s a:real^N. affine s ==> affine (IMAGE (\x. a + x) s)`, + REWRITE_TAC[AFFINE_TRANSLATION_EQ]);; + +let AFFINE_AFFINITY = prove + (`!s a:real^N c. + affine s ==> affine (IMAGE (\x. a + c % x) s)`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN `(\x:real^N. a + c % x) = (\x. a + x) o (\x. c % x)` + SUBST1_TAC THENL [REWRITE_TAC[o_DEF]; ALL_TAC] THEN + ASM_SIMP_TAC[IMAGE_o; AFFINE_TRANSLATION; AFFINE_SCALING]);; + +let AFFINE_LINEAR_IMAGE = prove + (`!f s. affine s /\ linear f ==> affine(IMAGE f s)`, + REWRITE_TAC[affine; FORALL_IN_IMAGE; IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN + REWRITE_TAC[IN_IMAGE; linear] THEN MESON_TAC[]);; + +let AFFINE_LINEAR_IMAGE_EQ = prove + (`!f s. linear f /\ (!x y. f x = f y ==> x = y) + ==> (affine (IMAGE f s) <=> affine s)`, + MATCH_ACCEPT_TAC(LINEAR_INVARIANT_RULE AFFINE_LINEAR_IMAGE));; + +add_linear_invariants [AFFINE_LINEAR_IMAGE_EQ];; + +let AFFINE_EMPTY = prove + (`affine {}`, + REWRITE_TAC[affine; NOT_IN_EMPTY]);; + +let AFFINE_SING = prove + (`!x. affine {x}`, + SIMP_TAC[AFFINE_ALT; IN_SING] THEN + REWRITE_TAC[GSYM VECTOR_ADD_RDISTRIB] THEN + REWRITE_TAC[REAL_SUB_ADD; VECTOR_MUL_LID]);; + +let AFFINE_UNIV = prove + (`affine(UNIV:real^N->bool)`, + REWRITE_TAC[affine; IN_UNIV]);; + +let AFFINE_HYPERPLANE = prove + (`!a b. affine {x | a dot x = b}`, + REWRITE_TAC[affine; IN_ELIM_THM; DOT_RADD; DOT_RMUL] THEN + CONV_TAC REAL_RING);; + +let AFFINE_STANDARD_HYPERPLANE = prove + (`!a b k. affine {x:real^N | x$k = b}`, + REPEAT GEN_TAC THEN + SUBGOAL_THEN `?i. 1 <= i /\ i <= dimindex(:N) /\ !x:real^N. x$k = x$i` + CHOOSE_TAC THENL + [ASM_REWRITE_TAC[FINITE_INDEX_INRANGE]; ALL_TAC] THEN + MP_TAC(ISPECL [`basis i:real^N`; `b:real`] AFFINE_HYPERPLANE) THEN + ASM_SIMP_TAC[DOT_BASIS]);; + +let AFFINE_INTERS = prove + (`(!s. s IN f ==> affine s) ==> affine(INTERS f)`, + REWRITE_TAC[affine; IN_INTERS] THEN MESON_TAC[]);; + +let AFFINE_INTER = prove + (`!s t. affine s /\ affine t ==> affine(s INTER t)`, + REWRITE_TAC[affine; IN_INTER] THEN MESON_TAC[]);; + +let AFFINE_AFFINE_HULL = prove + (`!s. affine(affine hull s)`, + SIMP_TAC[P_HULL; AFFINE_INTERS]);; + +let AFFINE_HULL_EQ = prove + (`!s. (affine hull s = s) <=> affine s`, + SIMP_TAC[HULL_EQ; AFFINE_INTERS]);; + +let IS_AFFINE_HULL = prove + (`!s. affine s <=> ?t. s = affine hull t`, + GEN_TAC THEN MATCH_MP_TAC IS_HULL THEN SIMP_TAC[AFFINE_INTERS]);; + +let AFFINE_HULL_UNIV = prove + (`affine hull (:real^N) = (:real^N)`, + REWRITE_TAC[AFFINE_HULL_EQ; AFFINE_UNIV]);; + +let AFFINE_HULLS_EQ = prove + (`!s t. s SUBSET affine hull t /\ t SUBSET affine hull s + ==> affine hull s = affine hull t`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC HULLS_EQ THEN + ASM_SIMP_TAC[AFFINE_INTERS]);; + +let AFFINE_HULL_TRANSLATION = prove + (`!a s. affine hull (IMAGE (\x. a + x) s) = + IMAGE (\x. a + x) (affine hull s)`, + REWRITE_TAC[hull] THEN GEOM_TRANSLATE_TAC[]);; + +add_translation_invariants [AFFINE_HULL_TRANSLATION];; + +let AFFINE_HULL_LINEAR_IMAGE = prove + (`!f s. linear f + ==> affine hull (IMAGE f s) = IMAGE f (affine hull s)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE] THEN + CONJ_TAC THEN MATCH_MP_TAC HULL_INDUCT THEN + REWRITE_TAC[FORALL_IN_IMAGE] THEN SIMP_TAC[FUN_IN_IMAGE; HULL_INC] THEN + REWRITE_TAC[affine; IN_ELIM_THM] THEN + REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_IMAGE] THENL + [FIRST_ASSUM(fun th -> REWRITE_TAC[GSYM(MATCH_MP LINEAR_CMUL th)]) THEN + FIRST_ASSUM(fun th -> REWRITE_TAC[GSYM(MATCH_MP LINEAR_ADD th)]) THEN + REWRITE_TAC[IN_IMAGE] THEN + MESON_TAC[REWRITE_RULE[affine] AFFINE_AFFINE_HULL]; + ASM_SIMP_TAC[LINEAR_ADD; LINEAR_CMUL] THEN + MESON_TAC[REWRITE_RULE[affine] AFFINE_AFFINE_HULL]]);; + +add_linear_invariants [AFFINE_HULL_LINEAR_IMAGE];; + +let IN_AFFINE_HULL_LINEAR_IMAGE = prove + (`!f:real^M->real^N s x. + linear f /\ x IN affine hull s ==> (f x) IN affine hull (IMAGE f s)`, + SIMP_TAC[AFFINE_HULL_LINEAR_IMAGE] THEN SET_TAC[]);; + +let SAME_DISTANCES_TO_AFFINE_HULL = prove + (`!s a b:real^N. + (!x. x IN s ==> dist(x,a) = dist(x,b)) + ==> (!x. x IN affine hull s ==> dist(x,a) = dist(x,b))`, + REPEAT GEN_TAC THEN DISCH_TAC THEN MATCH_MP_TAC HULL_INDUCT THEN + ASM_REWRITE_TAC[AFFINE_ALT; IN_ELIM_THM] THEN + REWRITE_TAC[dist; NORM_EQ_SQUARE; NORM_POS_LE; VECTOR_ARITH + `((&1 - u) % x + u % y) - a:real^N = (&1 - u) % (x - a) + u % (y - a)`] THEN + REWRITE_TAC[NORM_POW_2; DOT_LMUL; DOT_RMUL; VECTOR_ARITH + `(x + y) dot (x + y):real^N = (x dot x + y dot y) + &2 * x dot y`] THEN + SIMP_TAC[DOT_LSUB; DOT_RSUB; DOT_SYM] THEN CONV_TAC REAL_RING);; + +(* ------------------------------------------------------------------------- *) +(* Some convenient lemmas about common affine combinations. *) +(* ------------------------------------------------------------------------- *) + +let IN_AFFINE_ADD_MUL = prove + (`!s a x:real^N d. affine s /\ a IN s /\ (a + x) IN s ==> (a + d % x) IN s`, + REWRITE_TAC[affine] THEN REPEAT STRIP_TAC THEN + SUBST1_TAC(VECTOR_ARITH `a + d % x:real^N = (&1 - d) % a + d % (a + x)`) THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[] THEN REAL_ARITH_TAC);; + +let IN_AFFINE_ADD_MUL_DIFF = prove + (`!s a x y z:real^N. + affine s /\ x IN s /\ y IN s /\ z IN s ==> (x + a % (y - z)) IN s`, + REWRITE_TAC[affine] THEN REPEAT STRIP_TAC THEN + REWRITE_TAC[VECTOR_ARITH + `x + a % (y - z):real^N = + &1 / &2 % ((&1 - &2 * a) % x + (&2 * a) % y) + + &1 / &2 % ((&1 + &2 * a) % x + (-- &2 * a) % z)`] THEN + FIRST_ASSUM MATCH_MP_TAC THEN CONV_TAC REAL_RAT_REDUCE_CONV THEN + CONJ_TAC THEN FIRST_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[] THEN + REAL_ARITH_TAC);; + +let IN_AFFINE_MUL_DIFF_ADD = prove + (`!s a x y z:real^N. + affine s /\ x IN s /\ y IN s /\ z IN s ==> a % (x - y) + z IN s`, + ONCE_REWRITE_TAC[VECTOR_ADD_SYM] THEN + SIMP_TAC[IN_AFFINE_ADD_MUL_DIFF]);; + +let IN_AFFINE_SUB_MUL_DIFF = prove + (`!s a x y z:real^N. + affine s /\ x IN s /\ y IN s /\ z IN s ==> x - a % (y - z) IN s`, + REWRITE_TAC[VECTOR_ARITH `x - a % (y - z):real^N = x + a % (z - y)`] THEN + SIMP_TAC[IN_AFFINE_ADD_MUL_DIFF]);; + +let AFFINE_DIFFS_SUBSPACE = prove + (`!s:real^N->bool a. + affine s /\ a IN s ==> subspace {x - a | x IN s}`, + REWRITE_TAC[subspace; IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN + REWRITE_TAC[FORALL_IN_GSPEC] THEN REWRITE_TAC[IN_ELIM_THM] THEN + REWRITE_TAC[VECTOR_ARITH `vec 0:real^N = x - a <=> x = a`; + VECTOR_ARITH `x - a + y - a:real^N = z - a <=> + z = (a + &1 % (x - a)) + &1 % (y - a)`; + VECTOR_ARITH `c % (x - a):real^N = y - a <=> + y = a + c % (x - a)`] THEN + MESON_TAC[IN_AFFINE_ADD_MUL_DIFF]);; + +(* ------------------------------------------------------------------------- *) +(* Explicit formulations for affine combinations. *) +(* ------------------------------------------------------------------------- *) + +let AFFINE_VSUM = prove + (`!s k u x:A->real^N. + FINITE k /\ affine s /\ sum k u = &1 /\ (!i. i IN k ==> x i IN s) + ==> vsum k (\i. u i % x i) IN s`, + REPEAT GEN_TAC THEN ASM_CASES_TAC `s:real^N->bool = {}` THENL + [ASM_REWRITE_TAC[NOT_IN_EMPTY; GSYM NOT_EXISTS_THM; MEMBER_NOT_EMPTY] THEN + ASM_CASES_TAC `k:A->bool = {}` THEN ASM_REWRITE_TAC[SUM_CLAUSES] THEN + REAL_ARITH_TAC; + ALL_TAC] THEN + STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN + DISCH_THEN(X_CHOOSE_TAC `a:real^N`) THEN + MP_TAC(ISPECL [`s:real^N->bool`; `a:real^N`] AFFINE_DIFFS_SUBSPACE) THEN + ASM_REWRITE_TAC[] THEN DISCH_TAC THEN + MP_TAC(ISPECL [`{x - a:real^N | x IN s}`; + `(\i. u i % (x i - a)):A->real^N`; + `k:A->bool`] SUBSPACE_VSUM) THEN + ANTS_TAC THENL + [ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC SUBSPACE_MUL THEN ASM_REWRITE_TAC[] THEN ASM SET_TAC[]; + ASM_SIMP_TAC[VSUM_SUB; IN_ELIM_THM; VECTOR_SUB_LDISTRIB; VSUM_RMUL] THEN + REWRITE_TAC[VECTOR_ARITH `x - &1 % a:real^N = y - a <=> x = y`] THEN + ASM_MESON_TAC[]]);; + +let AFFINE_INDEXED = prove + (`!s:real^N->bool. + affine s <=> + !k u x. (!i:num. 1 <= i /\ i <= k ==> x(i) IN s) /\ + (sum (1..k) u = &1) + ==> vsum (1..k) (\i. u(i) % x(i)) IN s`, + REPEAT GEN_TAC THEN EQ_TAC THENL + [REPEAT STRIP_TAC THEN MATCH_MP_TAC AFFINE_VSUM THEN + ASM_REWRITE_TAC[IN_NUMSEG; FINITE_NUMSEG]; + DISCH_TAC THEN REWRITE_TAC[affine] THEN + MAP_EVERY X_GEN_TAC [`x:real^N`; `y:real^N`; `u:real`; `v:real`] THEN + STRIP_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC `2`) THEN + DISCH_THEN(MP_TAC o SPEC `\n. if n = 1 then u else v:real`) THEN + DISCH_THEN(MP_TAC o SPEC `\n. if n = 1 then x else y:real^N`) THEN + REWRITE_TAC[num_CONV `2`; SUM_CLAUSES_NUMSEG; VSUM_CLAUSES_NUMSEG; + NUMSEG_SING; VSUM_SING; SUM_SING] THEN REWRITE_TAC[ARITH] THEN + ASM_MESON_TAC[]]);; + +let AFFINE_HULL_INDEXED = prove + (`!s. affine hull s = + {y:real^N | ?k u x. (!i. 1 <= i /\ i <= k ==> x i IN s) /\ + (sum (1..k) u = &1) /\ + (vsum (1..k) (\i. u i % x i) = y)}`, + GEN_TAC THEN MATCH_MP_TAC HULL_UNIQUE THEN REPEAT CONJ_TAC THENL + [REWRITE_TAC[SUBSET; IN_ELIM_THM] THEN + X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN + MAP_EVERY EXISTS_TAC [`1`; `\i:num. &1`; `\i:num. x:real^N`] THEN + ASM_SIMP_TAC[FINITE_RULES; IN_SING; SUM_SING; VECTOR_MUL_LID; VSUM_SING; + REAL_POS; NUMSEG_SING]; + ALL_TAC; + REWRITE_TAC[AFFINE_INDEXED; SUBSET; IN_ELIM_THM; LEFT_IMP_EXISTS_THM] THEN + MESON_TAC[]] THEN + REWRITE_TAC[affine; IN_ELIM_THM] THEN + MAP_EVERY X_GEN_TAC [`x:real^N`; `y:real^N`; `u:real`; `v:real`] THEN + REWRITE_TAC[LEFT_AND_EXISTS_THM] THEN REWRITE_TAC[RIGHT_AND_EXISTS_THM] THEN + REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN MAP_EVERY X_GEN_TAC + [`k1:num`; `u1:num->real`; `x1:num->real^N`; + `k2:num`; `u2:num->real`; `x2:num->real^N`] THEN + STRIP_TAC THEN EXISTS_TAC `k1 + k2:num` THEN + EXISTS_TAC `\i:num. if i <= k1 then u * u1(i) else v * u2(i - k1):real` THEN + EXISTS_TAC `\i:num. if i <= k1 then x1(i) else x2(i - k1):real^N` THEN + ASM_SIMP_TAC[NUMSEG_ADD_SPLIT; ARITH_RULE `1 <= x + 1 /\ x < x + 1`; + IN_NUMSEG; SUM_UNION; VSUM_UNION; FINITE_NUMSEG; DISJOINT_NUMSEG; + ARITH_RULE `k1 + 1 <= i ==> ~(i <= k1)`] THEN + REWRITE_TAC[ONCE_REWRITE_RULE[ADD_SYM] NUMSEG_OFFSET_IMAGE] THEN + ASM_SIMP_TAC[SUM_IMAGE; VSUM_IMAGE; EQ_ADD_LCANCEL; FINITE_NUMSEG] THEN + ASM_SIMP_TAC[o_DEF; ADD_SUB2; SUM_LMUL; VSUM_LMUL; GSYM VECTOR_MUL_ASSOC; + FINITE_NUMSEG; REAL_MUL_RID] THEN + ASM_MESON_TAC[REAL_LE_MUL; ARITH_RULE + `i <= k1 + k2 /\ ~(i <= k1) ==> 1 <= i - k1 /\ i - k1 <= k2`]);; + +let AFFINE = prove + (`!V:real^N->bool. + affine V <=> + !(s:real^N->bool) (u:real^N->real). + FINITE s /\ ~(s = {}) /\ s SUBSET V /\ sum s u = &1 + ==> vsum s (\x. u x % x) IN V`, + GEN_TAC THEN EQ_TAC THENL + [REPEAT STRIP_TAC THEN MATCH_MP_TAC AFFINE_VSUM THEN + ASM_REWRITE_TAC[] THEN ASM SET_TAC[]; + REWRITE_TAC[affine] THEN DISCH_TAC THEN + MAP_EVERY X_GEN_TAC [`x:real^N`; `y:real^N`; `u:real`; `v:real`] THEN + STRIP_TAC THEN ASM_CASES_TAC `x:real^N = y` THENL + [FIRST_X_ASSUM SUBST_ALL_TAC THEN + ASM_REWRITE_TAC[GSYM VECTOR_ADD_RDISTRIB;VECTOR_MUL_LID];ALL_TAC] THEN + FIRST_X_ASSUM(MP_TAC o SPEC `{x:real^N,y}`) THEN + DISCH_THEN(MP_TAC o SPEC `\w. if w = x:real^N then u else v:real`) THEN + ASM_SIMP_TAC[SUM_CLAUSES; VSUM_CLAUSES; FINITE_RULES; NUMSEG_SING; + VSUM_SING; SUM_SING;SUBSET;IN_INSERT;NOT_IN_EMPTY] THEN + ASM SET_TAC[]]);; + +let AFFINE_EXPLICIT = prove + (`!s:real^N->bool. + affine s <=> + !t u. FINITE t /\ t SUBSET s /\ sum t u = &1 + ==> vsum t (\x. u(x) % x) IN s`, + GEN_TAC THEN REWRITE_TAC[AFFINE] THEN + AP_TERM_TAC THEN GEN_REWRITE_TAC I [FUN_EQ_THM] THEN + X_GEN_TAC `t:real^N->bool` THEN REWRITE_TAC[] THEN + AP_TERM_TAC THEN ABS_TAC THEN + ASM_CASES_TAC `t:real^N->bool = {}` THEN + ASM_REWRITE_TAC[SUM_CLAUSES] THEN CONV_TAC REAL_RAT_REDUCE_CONV);; + +let AFFINE_HULL_EXPLICIT = prove + (`!(p:real^N -> bool). + affine hull p = + {y | ?s u. FINITE s /\ ~(s = {}) /\ s SUBSET p /\ + sum s u = &1 /\ vsum s (\v. u v % v) = y}`, + GEN_TAC THEN MATCH_MP_TAC HULL_UNIQUE THEN REPEAT CONJ_TAC THENL + [REWRITE_TAC[SUBSET;IN_ELIM_THM] THEN + X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN + MAP_EVERY EXISTS_TAC [`{x:real^N}`;`\v:real^N. &1:real`] THEN + ASM_SIMP_TAC[FINITE_RULES;IN_SING;SUM_SING;VSUM_SING;VECTOR_MUL_LID] THEN + SET_TAC[]; + REWRITE_TAC[affine;IN_ELIM_THM] THEN REPEAT STRIP_TAC THEN + EXISTS_TAC `(s UNION s'):real^N->bool` THEN + EXISTS_TAC + `\a:real^N. (\b:real^N.if (b IN s) then (u * (u' b)) else &0) a + + (\b:real^N.if (b IN s') then v * (u'' b) else &0) a` THEN + REPEAT CONJ_TAC THENL + [ASM_REWRITE_TAC[FINITE_UNION]; + ASM SET_TAC[]; + ASM_REWRITE_TAC[UNION_SUBSET]; + ASM_SIMP_TAC[REWRITE_RULE[REAL_ARITH `a + b = c + d <=> c = a + b - d`] + SUM_INCL_EXCL; GSYM SUM_RESTRICT_SET; + SET_RULE `{a | a IN (s:A->bool) /\ a IN s'} = s INTER s'`; + SUM_ADD;SUM_LMUL;REAL_MUL_RID; + FINITE_INTER;INTER_IDEMPOT] THEN + ASM_REWRITE_TAC[SET_RULE `(a INTER b) INTER a = a INTER b`; + SET_RULE `(a INTER b) INTER b = a INTER b`; + REAL_ARITH `(a + b) + (c + d) - (e + b) = (a + d) + c - e`; + REAL_ARITH `a + b - c = a <=> b = c`] THEN + AP_TERM_TAC THEN REWRITE_TAC[INTER_COMM]; + ASM_SIMP_TAC[REWRITE_RULE + [VECTOR_ARITH `(a:real^N) + b = c + d <=> c = a + b - d`] + VSUM_INCL_EXCL;GSYM VSUM_RESTRICT_SET; + SET_RULE `{a | a IN (s:A->bool) /\ a IN s'} = s INTER s'`; + VSUM_ADD;FINITE_INTER;INTER_IDEMPOT;VECTOR_ADD_RDISTRIB; + GSYM VECTOR_MUL_ASSOC;VSUM_LMUL; + MESON[] `(if P then a else b) % (x:real^N) = + (if P then a % x else b % x)`; + VECTOR_MUL_LZERO;GSYM VSUM_RESTRICT_SET] THEN + ASM_REWRITE_TAC[SET_RULE `(a INTER b) INTER a = a INTER b`; + SET_RULE `(a INTER b) INTER b = a INTER b`; + VECTOR_ARITH + `((a:real^N) + b) + (c + d) - (e + b) = (a + d) + c - e`; + VECTOR_ARITH `(a:real^N) + b - c = a <=> b = c`] THEN + AP_TERM_TAC THEN REWRITE_TAC[INTER_COMM]]; + ASM_CASES_TAC `(p:real^N->bool) = {}` THENL + [FIRST_X_ASSUM SUBST_ALL_TAC THEN + REWRITE_TAC[SUBSET_EMPTY;EMPTY_SUBSET] THEN ASM SET_TAC[]; + ALL_TAC] THEN + REWRITE_TAC[AFFINE; SUBSET; IN_ELIM_THM; LEFT_IMP_EXISTS_THM] THEN + ASM SET_TAC[]]);; + +let AFFINE_HULL_EXPLICIT_ALT = prove + (`!(p:real^N -> bool). + affine hull p = + {y | ?s u. FINITE s /\ s SUBSET p /\ + sum s u = &1 /\ vsum s (\v. u v % v) = y}`, + GEN_TAC THEN REWRITE_TAC[AFFINE_HULL_EXPLICIT] THEN + GEN_REWRITE_TAC I [EXTENSION] THEN REWRITE_TAC[IN_ELIM_THM] THEN + GEN_TAC THEN REPEAT(AP_TERM_TAC THEN ABS_TAC) THEN + EQ_TAC THEN DISCH_TAC THEN ASM_REWRITE_TAC[] THEN + POP_ASSUM MP_TAC THEN ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN + SIMP_TAC[SUM_CLAUSES; REAL_OF_NUM_EQ; ARITH_EQ]);; + +let AFFINE_HULL_FINITE = prove + (`!s:real^N->bool. + affine hull s = {y | ?u. sum s u = &1 /\ vsum s (\v. u v % v) = y}`, + GEN_TAC THEN GEN_REWRITE_TAC I [EXTENSION] THEN + REWRITE_TAC[AFFINE_HULL_EXPLICIT; IN_ELIM_THM] THEN + X_GEN_TAC `x:real^N` THEN EQ_TAC THEN REWRITE_TAC[LEFT_IMP_EXISTS_THM] THENL + [MAP_EVERY X_GEN_TAC [`t:real^N->bool`; `f:real^N->real`] THEN + STRIP_TAC THEN + EXISTS_TAC `\x:real^N. if x IN t then f x else &0` THEN + REWRITE_TAC[COND_RAND; COND_RATOR; VECTOR_MUL_LZERO] THEN + REWRITE_TAC[GSYM SUM_RESTRICT_SET; GSYM VSUM_RESTRICT_SET] THEN + ASM_SIMP_TAC[SET_RULE `t SUBSET s ==> {x | x IN s /\ x IN t} = t`]; + X_GEN_TAC `f:real^N->real` THEN + ASM_CASES_TAC `s:real^N->bool = {}` THEN + ASM_REWRITE_TAC[SUM_CLAUSES; REAL_OF_NUM_EQ; ARITH] THEN STRIP_TAC THEN + EXISTS_TAC `support (+) (f:real^N->real) s` THEN + EXISTS_TAC `f:real^N->real` THEN + MP_TAC(ASSUME `sum s (f:real^N->real) = &1`) THEN + GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [sum] THEN + REWRITE_TAC[iterate] THEN COND_CASES_TAC THEN + ASM_REWRITE_TAC[NEUTRAL_REAL_ADD; REAL_OF_NUM_EQ; ARITH] THEN + DISCH_THEN(K ALL_TAC) THEN + UNDISCH_TAC `sum s (f:real^N->real) = &1` THEN + GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [GSYM SUM_SUPPORT] THEN + ASM_CASES_TAC `support (+) (f:real^N->real) s = {}` THEN + ASM_SIMP_TAC[SUM_CLAUSES; REAL_OF_NUM_EQ; ARITH] THEN + DISCH_TAC THEN REWRITE_TAC[SUPPORT_SUBSET] THEN + FIRST_X_ASSUM(fun th -> GEN_REWRITE_TAC RAND_CONV [GSYM th]) THEN + CONV_TAC SYM_CONV THEN MATCH_MP_TAC VSUM_SUPERSET THEN + REWRITE_TAC[SUPPORT_SUBSET] THEN + REWRITE_TAC[support; IN_ELIM_THM; NEUTRAL_REAL_ADD] THEN + MESON_TAC[VECTOR_MUL_LZERO]]);; + +(* ------------------------------------------------------------------------- *) +(* Stepping theorems and hence small special cases. *) +(* ------------------------------------------------------------------------- *) + +let AFFINE_HULL_EMPTY = prove + (`affine hull {} = {}`, + MATCH_MP_TAC HULL_UNIQUE THEN + REWRITE_TAC[SUBSET_REFL; AFFINE_EMPTY; EMPTY_SUBSET]);; + +let AFFINE_HULL_EQ_EMPTY = prove + (`!s. (affine hull s = {}) <=> (s = {})`, + GEN_TAC THEN EQ_TAC THEN + MESON_TAC[SUBSET_EMPTY; HULL_SUBSET; AFFINE_HULL_EMPTY]);; + +let AFFINE_HULL_FINITE_STEP_GEN = prove + (`!P:real^N->real->bool. + ((?u. (!x. x IN {} ==> P x (u x)) /\ + sum {} u = w /\ vsum {} (\x. u(x) % x) = y) <=> + w = &0 /\ y = vec 0) /\ + (FINITE(s:real^N->bool) /\ + (!y. a IN s /\ P a y ==> P a (y / &2)) /\ + (!x y. a IN s /\ P a x /\ P a y ==> P a (x + y)) + ==> ((?u. (!x. x IN (a INSERT s) ==> P x (u x)) /\ + sum (a INSERT s) u = w /\ + vsum (a INSERT s) (\x. u(x) % x) = y) <=> + ?v u. P a v /\ (!x. x IN s ==> P x (u x)) /\ + sum s u = w - v /\ + vsum s (\x. u(x) % x) = y - v % a))`, + GEN_TAC THEN SIMP_TAC[SUM_CLAUSES; VSUM_CLAUSES; NOT_IN_EMPTY] THEN + CONJ_TAC THENL [MESON_TAC[]; ALL_TAC] THEN DISCH_TAC THEN + ASM_CASES_TAC `(a:real^N) IN s` THEN ASM_REWRITE_TAC[] THENL + [ASM_SIMP_TAC[SET_RULE `a IN s ==> a INSERT s = s`] THEN EQ_TAC THEN + REWRITE_TAC[LEFT_IMP_EXISTS_THM] THENL + [X_GEN_TAC `u:real^N->real` THEN STRIP_TAC THEN + EXISTS_TAC `(u:real^N->real) a / &2` THEN + EXISTS_TAC `\x:real^N. if x = a then u x / &2 else u x`; + MAP_EVERY X_GEN_TAC [`v:real`; `u:real^N->real`] THEN + STRIP_TAC THEN + EXISTS_TAC `\x:real^N. if x = a then u x + v else u x`] THEN + ASM_SIMP_TAC[] THEN (CONJ_TAC THENL [ASM_MESON_TAC[]; ALL_TAC]) THEN + ONCE_REWRITE_TAC[COND_RAND] THEN ONCE_REWRITE_TAC[COND_RATOR] THEN + ASM_SIMP_TAC[VSUM_CASES; SUM_CASES] THEN + ASM_SIMP_TAC[GSYM DELETE; SUM_DELETE; VSUM_DELETE] THEN + ASM_SIMP_TAC[SET_RULE `a IN s ==> {x | x IN s /\ x = a} = {a}`] THEN + REWRITE_TAC[SUM_SING; VSUM_SING] THEN + (CONJ_TAC THENL [REAL_ARITH_TAC; VECTOR_ARITH_TAC]); + EQ_TAC THEN REWRITE_TAC[LEFT_IMP_EXISTS_THM] THENL + [X_GEN_TAC `u:real^N->real` THEN STRIP_TAC THEN + EXISTS_TAC `(u:real^N->real) a` THEN + EXISTS_TAC `u:real^N->real` THEN ASM_SIMP_TAC[IN_INSERT] THEN + REPEAT(FIRST_X_ASSUM(SUBST1_TAC o SYM)) THEN + CONJ_TAC THENL [REAL_ARITH_TAC; VECTOR_ARITH_TAC]; + MAP_EVERY X_GEN_TAC [`v:real`; `u:real^N->real`] THEN + STRIP_TAC THEN + EXISTS_TAC `\x:real^N. if x = a then v:real else u x` THEN + ASM_SIMP_TAC[IN_INSERT] THEN CONJ_TAC THENL + [ASM_MESON_TAC[]; ALL_TAC] THEN + ONCE_REWRITE_TAC[COND_RAND] THEN ONCE_REWRITE_TAC[COND_RATOR] THEN + ASM_SIMP_TAC[VSUM_CASES; SUM_CASES] THEN + ASM_SIMP_TAC[GSYM DELETE; SUM_DELETE; VSUM_DELETE] THEN + ASM_SIMP_TAC[SET_RULE `~(a IN s) ==> {x | x IN s /\ x = a} = {}`] THEN + ASM_SIMP_TAC[SET_RULE `~(a IN s) ==> s DELETE a = s`] THEN + REWRITE_TAC[SUM_CLAUSES; VSUM_CLAUSES] THEN + CONJ_TAC THENL [REAL_ARITH_TAC; VECTOR_ARITH_TAC]]]);; + +let AFFINE_HULL_FINITE_STEP = prove + (`((?u. sum {} u = w /\ vsum {} (\x. u(x) % x) = y) <=> + w = &0 /\ y = vec 0) /\ + (FINITE(s:real^N->bool) + ==> ((?u. sum (a INSERT s) u = w /\ + vsum (a INSERT s) (\x. u(x) % x) = y) <=> + ?v u. sum s u = w - v /\ + vsum s (\x. u(x) % x) = y - v % a))`, + MATCH_ACCEPT_TAC (REWRITE_RULE[] + (ISPEC `\x:real^N y:real. T` AFFINE_HULL_FINITE_STEP_GEN)));; + +let AFFINE_HULL_2 = prove + (`!a b. affine hull {a,b} = + {u % a + v % b | u + v = &1}`, + SIMP_TAC[AFFINE_HULL_FINITE; FINITE_INSERT; FINITE_RULES] THEN + SIMP_TAC[AFFINE_HULL_FINITE_STEP; FINITE_INSERT; FINITE_RULES] THEN + REWRITE_TAC[REAL_ARITH `x - y = z:real <=> x = y + z`; + VECTOR_ARITH `x - y = z:real^N <=> x = y + z`] THEN + REWRITE_TAC[VECTOR_ADD_RID; REAL_ADD_RID] THEN SET_TAC[]);; + +let AFFINE_HULL_2_ALT = prove + (`!a b. affine hull {a,b} = {a + u % (b - a) | u IN (:real)}`, + REPEAT GEN_TAC THEN REWRITE_TAC[AFFINE_HULL_2] THEN + MATCH_MP_TAC SUBSET_ANTISYM THEN REWRITE_TAC[SUBSET; FORALL_IN_GSPEC] THEN + REWRITE_TAC[IN_ELIM_THM; IN_UNIV; ARITH_RULE `u + v = &1 <=> v = &1 - u`; + FORALL_UNWIND_THM2; UNWIND_THM2] THEN + CONJ_TAC THEN X_GEN_TAC `u:real` THEN EXISTS_TAC `&1 - u` THEN + VECTOR_ARITH_TAC);; + +let AFFINE_HULL_3 = prove + (`affine hull {a,b,c} = + { u % a + v % b + w % c | u + v + w = &1}`, + SIMP_TAC[AFFINE_HULL_FINITE; FINITE_INSERT; FINITE_RULES] THEN + SIMP_TAC[AFFINE_HULL_FINITE_STEP; FINITE_INSERT; FINITE_RULES] THEN + REWRITE_TAC[REAL_ARITH `x - y = z:real <=> x = y + z`; + VECTOR_ARITH `x - y = z:real^N <=> x = y + z`] THEN + REWRITE_TAC[VECTOR_ADD_RID; REAL_ADD_RID] THEN SET_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* Some relations between affine hull and subspaces. *) +(* ------------------------------------------------------------------------- *) + +let AFFINE_HULL_INSERT_SUBSET_SPAN = prove + (`!a:real^N s. + affine hull (a INSERT s) SUBSET {a + v | v | v IN span {x - a | x IN s}}`, + REPEAT GEN_TAC THEN GEN_REWRITE_TAC I [SUBSET] THEN + REWRITE_TAC[AFFINE_HULL_EXPLICIT; SPAN_EXPLICIT; IN_ELIM_THM] THEN + REWRITE_TAC[SIMPLE_IMAGE; CONJ_ASSOC; FINITE_SUBSET_IMAGE] THEN + REWRITE_TAC[MESON[] + `(?s u. (?t. P t /\ s = f t) /\ Q s u) <=> + (?t u. P t /\ Q (f t) u)`] THEN + REWRITE_TAC[MESON[] + `(?v. (?s u. P s /\ f s u = v) /\ (x = g a v)) <=> + (?s u. ~(P s ==> ~(g a (f s u) = x)))`] THEN + SIMP_TAC[VSUM_IMAGE; VECTOR_ARITH `x - a:real^N = y - a <=> x = y`] THEN + REWRITE_TAC[o_DEF] THEN X_GEN_TAC `y:real^N` THEN + REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`t:real^N->bool`; `u:real^N->real`] THEN + DISCH_THEN(CONJUNCTS_THEN2 STRIP_ASSUME_TAC (SUBST1_TAC o SYM)) THEN + MAP_EVERY EXISTS_TAC + [`t DELETE (a:real^N)`; `\x. (u:real^N->real)(x + a)`] THEN + ASM_SIMP_TAC[FINITE_DELETE; VECTOR_SUB_ADD; SET_RULE + `t SUBSET (a INSERT s) ==> t DELETE a SUBSET s`] THEN + MATCH_MP_TAC EQ_TRANS THEN + EXISTS_TAC `a + vsum t (\x. u x % (x - a)):real^N` THEN CONJ_TAC THENL + [AP_TERM_TAC THEN CONV_TAC SYM_CONV THEN MATCH_MP_TAC VSUM_SUPERSET THEN + REWRITE_TAC[VECTOR_MUL_EQ_0; VECTOR_SUB_EQ] THEN SET_TAC[]; + ASM_SIMP_TAC[VECTOR_SUB_LDISTRIB; FINITE_DELETE; VSUM_SUB] THEN + ASM_REWRITE_TAC[VSUM_RMUL] THEN + REWRITE_TAC[VECTOR_ARITH `a + x - &1 % a:real^N = x`]]);; + +let AFFINE_HULL_INSERT_SPAN = prove + (`!a:real^N s. + ~(a IN s) + ==> affine hull (a INSERT s) = + {a + v | v | v IN span {x - a | x IN s}}`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN + REWRITE_TAC[AFFINE_HULL_INSERT_SUBSET_SPAN] THEN REWRITE_TAC[SUBSET] THEN + REWRITE_TAC[AFFINE_HULL_EXPLICIT; SPAN_EXPLICIT; IN_ELIM_THM] THEN + REWRITE_TAC[SIMPLE_IMAGE; CONJ_ASSOC; FINITE_SUBSET_IMAGE] THEN + REWRITE_TAC[MESON[] + `(?s u. (?t. P t /\ s = f t) /\ Q s u) <=> + (?t u. P t /\ Q (f t) u)`] THEN + REWRITE_TAC[MESON[] + `(?v. (?s u. P s /\ f s u = v) /\ (x = g a v)) <=> + (?s u. ~(P s ==> ~(g a (f s u) = x)))`] THEN + SIMP_TAC[VSUM_IMAGE; VECTOR_ARITH `x - a:real^N = y - a <=> x = y`] THEN + REWRITE_TAC[o_DEF] THEN X_GEN_TAC `y:real^N` THEN + REWRITE_TAC[NOT_IMP; LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`t:real^N->bool`; `u:real^N->real`] THEN + DISCH_THEN(CONJUNCTS_THEN2 STRIP_ASSUME_TAC (SUBST1_TAC o SYM)) THEN + MAP_EVERY EXISTS_TAC + [`(a:real^N) INSERT t`; + `\x. if x = a then &1 - sum t (\x. u(x - a)) + else (u:real^N->real)(x - a)`] THEN + ASM_SIMP_TAC[SUM_CLAUSES; VSUM_CLAUSES] THEN + ASM_CASES_TAC `(a:real^N) IN t` THENL [ASM_MESON_TAC[SUBSET]; ALL_TAC] THEN + ASM_SIMP_TAC[FINITE_INSERT; NOT_INSERT_EMPTY; + SET_RULE `s SUBSET t ==> (a INSERT s) SUBSET (a INSERT t)`] THEN + SUBGOAL_THEN `!x:real^N. x IN t ==> ~(x = a)` MP_TAC THENL + [ASM SET_TAC[]; SIMP_TAC[] THEN DISCH_THEN(K ALL_TAC)] THEN + CONJ_TAC THENL [REAL_ARITH_TAC; ALL_TAC] THEN + ASM_SIMP_TAC[VECTOR_SUB_LDISTRIB; FINITE_DELETE; VSUM_SUB] THEN + ASM_REWRITE_TAC[VSUM_RMUL] THEN VECTOR_ARITH_TAC);; + +let AFFINE_HULL_SPAN = prove + (`!a:real^N s. + a IN s + ==> (affine hull s = + {a + v | v | v IN span {x - a | x | x IN (s DELETE a)}})`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`a:real^N`; `s DELETE (a:real^N)`] + AFFINE_HULL_INSERT_SPAN) THEN + ASM_REWRITE_TAC[IN_DELETE] THEN + DISCH_THEN(SUBST1_TAC o SYM) THEN AP_TERM_TAC THEN ASM SET_TAC[]);; + +let DIFFS_AFFINE_HULL_SPAN = prove + (`!a:real^N s. + a IN s ==> {x - a | x IN affine hull s} = span {x - a | x IN s}`, + REPEAT STRIP_TAC THEN + FIRST_ASSUM(SUBST1_TAC o MATCH_MP AFFINE_HULL_SPAN) THEN + REWRITE_TAC[SIMPLE_IMAGE; GSYM IMAGE_o; o_DEF; VECTOR_ADD_SUB; IMAGE_ID] THEN + SIMP_TAC[IMAGE_DELETE_INJ; + VECTOR_ARITH `x - a:real^N = y - a <=> x = y`] THEN + REWRITE_TAC[VECTOR_SUB_REFL; SPAN_DELETE_0]);; + +let AFFINE_HULL_SING = prove + (`!a. affine hull {a} = {a}`, + SIMP_TAC[AFFINE_HULL_INSERT_SPAN; NOT_IN_EMPTY] THEN + REWRITE_TAC[SET_RULE `{f x | x | F} = {}`; SPAN_EMPTY] THEN + REWRITE_TAC[SET_RULE `{f x | x IN {a}} = {f a}`; VECTOR_ADD_RID]);; + +let AFFINE_HULL_EQ_SING = prove + (`!s a:real^N. affine hull s = {a} <=> s = {a}`, + REPEAT GEN_TAC THEN ASM_CASES_TAC `s:real^N->bool = {}` THEN + ASM_REWRITE_TAC[AFFINE_HULL_EMPTY] THEN + EQ_TAC THEN STRIP_TAC THEN ASM_REWRITE_TAC[AFFINE_HULL_SING] THEN + MATCH_MP_TAC(SET_RULE `~(s = {}) /\ s SUBSET {a} ==> s = {a}`) THEN + ASM_REWRITE_TAC[] THEN FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN + REWRITE_TAC[HULL_SUBSET]);; + +(* ------------------------------------------------------------------------- *) +(* Convexity. *) +(* ------------------------------------------------------------------------- *) + +let convex = new_definition + `convex s <=> + !x y u v. x IN s /\ y IN s /\ &0 <= u /\ &0 <= v /\ (u + v = &1) + ==> (u % x + v % y) IN s`;; + +let CONVEX_ALT = prove + (`convex s <=> !x y u. x IN s /\ y IN s /\ &0 <= u /\ u <= &1 + ==> ((&1 - u) % x + u % y) IN s`, + REWRITE_TAC[convex] THEN + MESON_TAC[REAL_ARITH `&0 <= u /\ &0 <= v /\ (u + v = &1) + ==> v <= &1 /\ (u = &1 - v)`; + REAL_ARITH `u <= &1 ==> &0 <= &1 - u /\ ((&1 - u) + u = &1)`]);; + +let IN_CONVEX_SET = prove + (`!s a b u. + convex s /\ a IN s /\ b IN s /\ &0 <= u /\ u <= &1 + ==> ((&1 - u) % a + u % b) IN s`, + MESON_TAC[CONVEX_ALT]);; + +let CONVEX_EMPTY = prove + (`convex {}`, + REWRITE_TAC[convex; NOT_IN_EMPTY]);; + +let CONVEX_SING = prove + (`!a. convex {a}`, + SIMP_TAC[convex; IN_SING; GSYM VECTOR_ADD_RDISTRIB; VECTOR_MUL_LID]);; + +let CONVEX_UNIV = prove + (`convex(UNIV:real^N->bool)`, + REWRITE_TAC[convex; IN_UNIV]);; + +let CONVEX_INTERS = prove + (`(!s. s IN f ==> convex s) ==> convex(INTERS f)`, + REWRITE_TAC[convex; IN_INTERS] THEN MESON_TAC[]);; + +let CONVEX_INTER = prove + (`!s t. convex s /\ convex t ==> convex(s INTER t)`, + REWRITE_TAC[convex; IN_INTER] THEN MESON_TAC[]);; + +let CONVEX_HULLS_EQ = prove + (`!s t. s SUBSET convex hull t /\ t SUBSET convex hull s + ==> convex hull s = convex hull t`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC HULLS_EQ THEN + ASM_SIMP_TAC[CONVEX_INTERS]);; + +let CONVEX_HALFSPACE_LE = prove + (`!a b. convex {x | a dot x <= b}`, + REWRITE_TAC[convex; IN_ELIM_THM; DOT_RADD; DOT_RMUL] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `(u + v) * b` THEN CONJ_TAC THENL + [ASM_MESON_TAC[REAL_ADD_RDISTRIB; REAL_LE_ADD2; REAL_LE_LMUL]; + ASM_MESON_TAC[REAL_MUL_LID; REAL_LE_REFL]]);; + +let CONVEX_HALFSPACE_COMPONENT_LE = prove + (`!a k. convex {x:real^N | x$k <= a}`, + REPEAT GEN_TAC THEN + SUBGOAL_THEN `?i. 1 <= i /\ i <= dimindex(:N) /\ !x:real^N. x$k = x$i` + CHOOSE_TAC THENL + [ASM_REWRITE_TAC[FINITE_INDEX_INRANGE]; ALL_TAC] THEN + MP_TAC(ISPECL [`basis i:real^N`; `a:real`] CONVEX_HALFSPACE_LE) THEN + ASM_SIMP_TAC[DOT_BASIS]);; + +let CONVEX_HALFSPACE_GE = prove + (`!a b. convex {x:real^N | a dot x >= b}`, + REPEAT GEN_TAC THEN + SUBGOAL_THEN `{x:real^N | a dot x >= b} = {x | --a dot x <= --b}` + (fun th -> REWRITE_TAC[th; CONVEX_HALFSPACE_LE]) THEN + REWRITE_TAC[EXTENSION; IN_ELIM_THM; DOT_LNEG] THEN REAL_ARITH_TAC);; + +let CONVEX_HALFSPACE_COMPONENT_GE = prove + (`!a k. convex {x:real^N | x$k >= a}`, + REPEAT GEN_TAC THEN + SUBGOAL_THEN `?i. 1 <= i /\ i <= dimindex(:N) /\ !x:real^N. x$k = x$i` + CHOOSE_TAC THENL + [ASM_REWRITE_TAC[FINITE_INDEX_INRANGE]; ALL_TAC] THEN + MP_TAC(ISPECL [`basis i:real^N`; `a:real`] CONVEX_HALFSPACE_GE) THEN + ASM_SIMP_TAC[DOT_BASIS]);; + +let CONVEX_HYPERPLANE = prove + (`!a b. convex {x:real^N | a dot x = b}`, + REPEAT GEN_TAC THEN + SUBGOAL_THEN + `{x:real^N | a dot x = b} = {x | a dot x <= b} INTER {x | a dot x >= b}` + (fun th -> SIMP_TAC[th; CONVEX_INTER; + CONVEX_HALFSPACE_LE; CONVEX_HALFSPACE_GE]) THEN + REWRITE_TAC[EXTENSION; IN_INTER; IN_ELIM_THM] THEN REAL_ARITH_TAC);; + +let CONVEX_STANDARD_HYPERPLANE = prove + (`!k a. convex {x:real^N | x$k = a}`, + REPEAT GEN_TAC THEN + SUBGOAL_THEN `?i. 1 <= i /\ i <= dimindex(:N) /\ !x:real^N. x$k = x$i` + CHOOSE_TAC THENL + [ASM_REWRITE_TAC[FINITE_INDEX_INRANGE]; ALL_TAC] THEN + MP_TAC(ISPECL [`basis i:real^N`; `a:real`] CONVEX_HYPERPLANE) THEN + ASM_SIMP_TAC[DOT_BASIS]);; + +let CONVEX_HALFSPACE_LT = prove + (`!a b. convex {x | a dot x < b}`, + REWRITE_TAC[convex; IN_ELIM_THM; DOT_RADD; DOT_RMUL] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_CONVEX_BOUND_LT THEN + ASM_REWRITE_TAC[]);; + +let CONVEX_HALFSPACE_COMPONENT_LT = prove + (`!a k. convex {x:real^N | x$k < a}`, + REPEAT GEN_TAC THEN + SUBGOAL_THEN `?i. 1 <= i /\ i <= dimindex(:N) /\ !x:real^N. x$k = x$i` + CHOOSE_TAC THENL + [ASM_REWRITE_TAC[FINITE_INDEX_INRANGE]; ALL_TAC] THEN + MP_TAC(ISPECL [`basis i:real^N`; `a:real`] CONVEX_HALFSPACE_LT) THEN + ASM_SIMP_TAC[DOT_BASIS]);; + +let CONVEX_HALFSPACE_GT = prove + (`!a b. convex {x | a dot x > b}`, + REWRITE_TAC[REAL_ARITH `ax > b <=> --ax < --b`] THEN + REWRITE_TAC[GSYM DOT_LNEG; CONVEX_HALFSPACE_LT]);; + +let CONVEX_HALFSPACE_COMPONENT_GT = prove + (`!a k. convex {x:real^N | x$k > a}`, + REPEAT GEN_TAC THEN + SUBGOAL_THEN `?i. 1 <= i /\ i <= dimindex(:N) /\ !x:real^N. x$k = x$i` + CHOOSE_TAC THENL + [ASM_REWRITE_TAC[FINITE_INDEX_INRANGE]; ALL_TAC] THEN + MP_TAC(ISPECL [`basis i:real^N`; `a:real`] CONVEX_HALFSPACE_GT) THEN + ASM_SIMP_TAC[DOT_BASIS]);; + +let CONVEX_POSITIVE_ORTHANT = prove + (`convex {x:real^N | !i. 1 <= i /\ i <= dimindex(:N) + ==> &0 <= x$i}`, + SIMP_TAC[convex; IN_ELIM_THM; VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT; + REAL_LE_MUL; REAL_LE_ADD]);; + +let LIMPT_OF_CONVEX = prove + (`!s x:real^N. + convex s /\ x IN s ==> (x limit_point_of s <=> ~(s = {x}))`, + REPEAT STRIP_TAC THEN + ASM_CASES_TAC `s = {x:real^N}` THEN ASM_REWRITE_TAC[LIMPT_SING] THEN + SUBGOAL_THEN `?y:real^N. y IN s /\ ~(y = x)` STRIP_ASSUME_TAC THENL + [ASM SET_TAC[]; ALL_TAC] THEN + REWRITE_TAC[LIMPT_APPROACHABLE] THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN + ABBREV_TAC `u = min (&1 / &2) (e / &2 / norm(y - x:real^N))` THEN + SUBGOAL_THEN `&0 < u /\ u < &1` STRIP_ASSUME_TAC THENL + [EXPAND_TAC "u" THEN REWRITE_TAC[REAL_LT_MIN; REAL_MIN_LT] THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN + ASM_SIMP_TAC[REAL_HALF; REAL_LT_DIV; NORM_POS_LT; VECTOR_SUB_EQ]; + ALL_TAC] THEN + EXISTS_TAC `(&1 - u) % x + u % y:real^N` THEN REPEAT CONJ_TAC THENL + [FIRST_ASSUM(MATCH_MP_TAC o GEN_REWRITE_RULE I [CONVEX_ALT]) THEN + ASM_SIMP_TAC[REAL_LT_IMP_LE]; + ASM_REWRITE_TAC[VECTOR_MUL_EQ_0; VECTOR_SUB_EQ; VECTOR_ARITH + `(&1 - u) % x + u % y:real^N = x <=> u % (y - x) = vec 0`] THEN + ASM_REAL_ARITH_TAC; + REWRITE_TAC[dist; NORM_MUL; VECTOR_ARITH + `((&1 - u) % x + u % y) - x:real^N = u % (y - x)`] THEN + ASM_SIMP_TAC[REAL_ARITH `&0 < u ==> abs u = u`] THEN + MATCH_MP_TAC(REAL_ARITH `x <= e / &2 /\ &0 < e ==> x < e`) THEN + ASM_SIMP_TAC[GSYM REAL_LE_RDIV_EQ; NORM_POS_LT; VECTOR_SUB_EQ] THEN + ASM_REAL_ARITH_TAC]);; + +let TRIVIAL_LIMIT_WITHIN_CONVEX = prove + (`!s x:real^N. + convex s /\ x IN s ==> (trivial_limit(at x within s) <=> s = {x})`, + SIMP_TAC[TRIVIAL_LIMIT_WITHIN; LIMPT_OF_CONVEX]);; + +(* ------------------------------------------------------------------------- *) +(* Some invariance theorems for convex sets. *) +(* ------------------------------------------------------------------------- *) + +let CONVEX_TRANSLATION_EQ = prove + (`!a:real^N s. convex (IMAGE (\x. a + x) s) <=> convex s`, + REWRITE_TAC[CONVEX_ALT; IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_IMAGE] THEN + REWRITE_TAC[IN_IMAGE; UNWIND_THM1; VECTOR_ARITH + `(&1 - u) % (a + x) + u % (a + y) = a + z <=> (&1 - u) % x + u % y = z`]);; + +add_translation_invariants [CONVEX_TRANSLATION_EQ];; + +let CONVEX_TRANSLATION = prove + (`!s a:real^N. convex s ==> convex (IMAGE (\x. a + x) s)`, + REWRITE_TAC[CONVEX_TRANSLATION_EQ]);; + +let CONVEX_LINEAR_IMAGE = prove + (`!f s. convex s /\ linear f ==> convex(IMAGE f s)`, + REWRITE_TAC[convex; FORALL_IN_IMAGE; IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN + REWRITE_TAC[IN_IMAGE; linear] THEN MESON_TAC[]);; + +let CONVEX_LINEAR_IMAGE_EQ = prove + (`!f s. linear f /\ (!x y. f x = f y ==> x = y) + ==> (convex (IMAGE f s) <=> convex s)`, + MATCH_ACCEPT_TAC(LINEAR_INVARIANT_RULE CONVEX_LINEAR_IMAGE));; + +add_linear_invariants [CONVEX_LINEAR_IMAGE_EQ];; + +(* ------------------------------------------------------------------------- *) +(* Explicit expressions for convexity in terms of arbitrary sums. *) +(* ------------------------------------------------------------------------- *) + +let CONVEX_VSUM = prove + (`!s k u x:A->real^N. + FINITE k /\ convex s /\ sum k u = &1 /\ + (!i. i IN k ==> &0 <= u i /\ x i IN s) + ==> vsum k (\i. u i % x i) IN s`, + GEN_TAC THEN ASM_CASES_TAC `convex(s:real^N->bool)` THEN + ASM_REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN + MATCH_MP_TAC FINITE_INDUCT_STRONG THEN + SIMP_TAC[SUM_CLAUSES; VSUM_CLAUSES; FORALL_IN_INSERT] THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN + MAP_EVERY X_GEN_TAC [`i:A`; `k:A->bool`] THEN + GEN_REWRITE_TAC (BINOP_CONV o DEPTH_CONV) [RIGHT_IMP_FORALL_THM] THEN + REWRITE_TAC[IMP_IMP] THEN STRIP_TAC THEN + MAP_EVERY X_GEN_TAC [`u:A->real`; `x:A->real^N`] THEN + ASM_CASES_TAC `(u:A->real) i = &1` THENL + [ASM_REWRITE_TAC[REAL_ARITH `&1 + a = &1 <=> a = &0`] THEN + STRIP_TAC THEN + SUBGOAL_THEN `vsum k (\i:A. u i % x(i):real^N) = vec 0` + (fun th -> ASM_SIMP_TAC[th; VECTOR_ADD_RID; VECTOR_MUL_LID]) THEN + MATCH_MP_TAC VSUM_EQ_0 THEN REWRITE_TAC[VECTOR_MUL_EQ_0] THEN + REPEAT STRIP_TAC THEN DISJ1_TAC THEN + ASM_MESON_TAC[SUM_POS_EQ_0]; + STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `\j:A. u(j) / (&1 - u(i))`) THEN + ASM_REWRITE_TAC[real_div] THEN ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN + ASM_SIMP_TAC[SUM_LMUL; VSUM_LMUL; GSYM VECTOR_MUL_ASSOC] THEN + ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN REWRITE_TAC[GSYM real_div] THEN + SUBGOAL_THEN `&0 < &1 - u(i:A)` ASSUME_TAC THENL + [ASM_MESON_TAC[SUM_POS_LE; REAL_ADD_SYM; REAL_ARITH + `&0 <= a /\ &0 <= b /\ b + a = &1 /\ ~(a = &1) ==> &0 < &1 - a`]; + ALL_TAC] THEN + ASM_SIMP_TAC[REAL_LE_DIV; REAL_LT_IMP_LE] THEN + ASM_SIMP_TAC[REAL_EQ_LDIV_EQ; REAL_MUL_LID; REAL_EQ_SUB_LADD] THEN + DISCH_TAC THEN ONCE_REWRITE_TAC[VECTOR_ADD_SYM] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [convex]) THEN + DISCH_THEN(MP_TAC o SPECL + [`vsum k (\j. (u j / (&1 - u(i:A))) % x(j) :real^N)`; + `x(i:A):real^N`; `&1 - u(i:A)`; `u(i:A):real`]) THEN + REWRITE_TAC[real_div] THEN ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN + ASM_SIMP_TAC[GSYM VECTOR_MUL_ASSOC; VSUM_LMUL] THEN + ASM_SIMP_TAC[VECTOR_MUL_ASSOC; REAL_MUL_RINV; REAL_LT_IMP_NZ] THEN + REWRITE_TAC[VECTOR_MUL_LID] THEN DISCH_THEN MATCH_MP_TAC THEN + ASM_SIMP_TAC[REAL_LT_IMP_LE; VSUM_LMUL] THEN + CONJ_TAC THENL [FIRST_X_ASSUM MATCH_MP_TAC; REAL_ARITH_TAC] THEN + ASM_MESON_TAC[REAL_ADD_SYM]]);; + +let CONVEX_VSUM_STRONG = prove + (`!s k u x:A->real^N. + FINITE k /\ + convex s /\ + sum k u = &1 /\ + (!i. i IN k ==> &0 <= u i /\ (u i = &0 \/ x i IN s)) + ==> vsum k (\i. u i % x i) IN s`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN + `vsum k (\i. u i % (x:A->real^N) i) = + vsum {i | i IN k /\ ~(u i = &0)} (\i. u i % x i)` + SUBST1_TAC THENL + [MATCH_MP_TAC VSUM_SUPERSET THEN REWRITE_TAC[VECTOR_MUL_EQ_0] THEN + SET_TAC[]; + MATCH_MP_TAC CONVEX_VSUM THEN + ASM_SIMP_TAC[FINITE_RESTRICT; IN_ELIM_THM] THEN + CONJ_TAC THENL [ALL_TAC; ASM_MESON_TAC[]] THEN + FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN + CONV_TAC SYM_CONV THEN MATCH_MP_TAC SUM_SUPERSET THEN ASM SET_TAC[]]);; + +let CONVEX_INDEXED = prove + (`!s:real^N->bool. + convex s <=> + !k u x. (!i:num. 1 <= i /\ i <= k ==> &0 <= u(i) /\ x(i) IN s) /\ + (sum (1..k) u = &1) + ==> vsum (1..k) (\i. u(i) % x(i)) IN s`, + REPEAT GEN_TAC THEN EQ_TAC THENL + [REPEAT STRIP_TAC THEN MATCH_MP_TAC CONVEX_VSUM THEN + ASM_REWRITE_TAC[IN_NUMSEG; FINITE_NUMSEG]; + DISCH_TAC THEN REWRITE_TAC[convex] THEN + MAP_EVERY X_GEN_TAC [`x:real^N`; `y:real^N`; `u:real`; `v:real`] THEN + STRIP_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC `2`) THEN + DISCH_THEN(MP_TAC o SPEC `\n. if n = 1 then u else v:real`) THEN + DISCH_THEN(MP_TAC o SPEC `\n. if n = 1 then x else y:real^N`) THEN + REWRITE_TAC[num_CONV `2`; SUM_CLAUSES_NUMSEG; VSUM_CLAUSES_NUMSEG; + NUMSEG_SING; VSUM_SING; SUM_SING] THEN REWRITE_TAC[ARITH] THEN + ASM_MESON_TAC[]]);; + +let CONVEX_EXPLICIT = prove + (`!s:real^N->bool. + convex s <=> + !t u. FINITE t /\ t SUBSET s /\ (!x. x IN t ==> &0 <= u x) /\ + sum t u = &1 + ==> vsum t (\x. u(x) % x) IN s`, + REPEAT GEN_TAC THEN EQ_TAC THENL + [REPEAT STRIP_TAC THEN MATCH_MP_TAC CONVEX_VSUM THEN + ASM_REWRITE_TAC[] THEN ASM SET_TAC[]; + DISCH_TAC THEN REWRITE_TAC[convex] THEN + MAP_EVERY X_GEN_TAC [`x:real^N`; `y:real^N`; `u:real`; `v:real`] THEN + ASM_CASES_TAC `x:real^N = y` THENL + [ASM_SIMP_TAC[GSYM VECTOR_ADD_RDISTRIB; VECTOR_MUL_LID]; ALL_TAC] THEN + STRIP_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC `{x:real^N,y}`) THEN + DISCH_THEN(MP_TAC o SPEC `\z:real^N. if z = x then u else v:real`) THEN + ASM_SIMP_TAC[FINITE_INSERT; FINITE_RULES; SUM_CLAUSES; VSUM_CLAUSES; + NOT_IN_EMPTY] THEN + ASM_REWRITE_TAC[IN_INSERT; NOT_IN_EMPTY; REAL_ADD_RID; SUBSET] THEN + REWRITE_TAC[VECTOR_ADD_RID] THEN ASM_MESON_TAC[]]);; + +let CONVEX = prove + (`!V:real^N->bool. + convex V <=> + !(s:real^N->bool) (u:real^N->real). + FINITE s /\ ~(s = {}) /\ s SUBSET V /\ + (!x. x IN s ==> &0 <= u x) /\ sum s u = &1 + ==> vsum s (\x. u x % x) IN V`, + GEN_TAC THEN REWRITE_TAC[CONVEX_EXPLICIT] THEN + AP_TERM_TAC THEN GEN_REWRITE_TAC I [FUN_EQ_THM] THEN + X_GEN_TAC `t:real^N->bool` THEN REWRITE_TAC[] THEN + AP_TERM_TAC THEN ABS_TAC THEN + ASM_CASES_TAC `t:real^N->bool = {}` THEN + ASM_REWRITE_TAC[SUM_CLAUSES] THEN CONV_TAC REAL_RAT_REDUCE_CONV);; + +let CONVEX_FINITE = prove + (`!s:real^N->bool. + FINITE s + ==> (convex s <=> + !u. (!x. x IN s ==> &0 <= u x) /\ + sum s u = &1 + ==> vsum s (\x. u(x) % x) IN s)`, + REPEAT STRIP_TAC THEN REWRITE_TAC[CONVEX_EXPLICIT] THEN + EQ_TAC THENL [ASM_MESON_TAC[SUBSET_REFL]; ALL_TAC] THEN + DISCH_TAC THEN MAP_EVERY X_GEN_TAC [`t:real^N->bool`; `u:real^N->real`] THEN + STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `\x:real^N. if x IN t then u x else &0`) THEN + ASM_SIMP_TAC[GSYM SUM_RESTRICT_SET] THEN + ONCE_REWRITE_TAC[COND_RAND] THEN ONCE_REWRITE_TAC[COND_RATOR] THEN + ASM_SIMP_TAC[VECTOR_MUL_LZERO; REAL_LE_REFL; GSYM VSUM_RESTRICT_SET] THEN + ASM_SIMP_TAC[COND_ID; SET_RULE `t SUBSET s ==> {x | x IN s /\ x IN t} = t`]);; + +let AFFINE_PCROSS = prove + (`!s:real^M->bool t:real^N->bool. + affine s /\ affine t ==> affine(s PCROSS t)`, + REWRITE_TAC[affine; IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN + SIMP_TAC[FORALL_IN_PCROSS; GSYM PASTECART_CMUL; PASTECART_ADD] THEN + SIMP_TAC[PASTECART_IN_PCROSS]);; + +let AFFINE_PCROSS_EQ = prove + (`!s:real^M->bool t:real^N->bool. + affine(s PCROSS t) <=> s = {} \/ t = {} \/ affine s /\ affine t`, + REPEAT GEN_TAC THEN + ASM_CASES_TAC `s:real^M->bool = {}` THEN + ASM_REWRITE_TAC[PCROSS_EMPTY; AFFINE_EMPTY] THEN + ASM_CASES_TAC `t:real^N->bool = {}` THEN + ASM_REWRITE_TAC[PCROSS_EMPTY; AFFINE_EMPTY] THEN + EQ_TAC THEN REWRITE_TAC[AFFINE_PCROSS] THEN REPEAT STRIP_TAC THENL + [MP_TAC(ISPECL [`fstcart:real^(M,N)finite_sum->real^M`; + `(s:real^M->bool) PCROSS (t:real^N->bool)`] AFFINE_LINEAR_IMAGE) THEN + ASM_REWRITE_TAC[LINEAR_FSTCART]; + MP_TAC(ISPECL [`sndcart:real^(M,N)finite_sum->real^N`; + `(s:real^M->bool) PCROSS (t:real^N->bool)`] AFFINE_LINEAR_IMAGE) THEN + ASM_REWRITE_TAC[LINEAR_SNDCART]] THEN + MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN + REWRITE_TAC[EXTENSION; IN_IMAGE; EXISTS_PASTECART; PASTECART_IN_PCROSS; + FSTCART_PASTECART; SNDCART_PASTECART] THEN + ASM SET_TAC[]);; + +let CONVEX_PCROSS = prove + (`!s:real^M->bool t:real^N->bool. + convex s /\ convex t ==> convex(s PCROSS t)`, + REWRITE_TAC[convex; IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN + SIMP_TAC[FORALL_IN_PCROSS; GSYM PASTECART_CMUL; PASTECART_ADD] THEN + SIMP_TAC[PASTECART_IN_PCROSS]);; + +let CONVEX_PCROSS_EQ = prove + (`!s:real^M->bool t:real^N->bool. + convex(s PCROSS t) <=> s = {} \/ t = {} \/ convex s /\ convex t`, + REPEAT GEN_TAC THEN + ASM_CASES_TAC `s:real^M->bool = {}` THEN + ASM_REWRITE_TAC[PCROSS_EMPTY; CONVEX_EMPTY] THEN + ASM_CASES_TAC `t:real^N->bool = {}` THEN + ASM_REWRITE_TAC[PCROSS_EMPTY; CONVEX_EMPTY] THEN + EQ_TAC THEN REWRITE_TAC[CONVEX_PCROSS] THEN REPEAT STRIP_TAC THENL + [MP_TAC(ISPECL [`fstcart:real^(M,N)finite_sum->real^M`; + `(s:real^M->bool) PCROSS (t:real^N->bool)`] CONVEX_LINEAR_IMAGE) THEN + ASM_REWRITE_TAC[LINEAR_FSTCART]; + MP_TAC(ISPECL [`sndcart:real^(M,N)finite_sum->real^N`; + `(s:real^M->bool) PCROSS (t:real^N->bool)`] CONVEX_LINEAR_IMAGE) THEN + ASM_REWRITE_TAC[LINEAR_SNDCART]] THEN + MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN + REWRITE_TAC[EXTENSION; IN_IMAGE; EXISTS_PASTECART; PASTECART_IN_PCROSS; + FSTCART_PASTECART; SNDCART_PASTECART] THEN + ASM SET_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* Conic sets and conic hull. *) +(* ------------------------------------------------------------------------- *) + +let conic = new_definition + `conic s <=> !x c. x IN s /\ &0 <= c ==> (c % x) IN s`;; + +let SUBSPACE_IMP_CONIC = prove + (`!s. subspace s ==> conic s`, + SIMP_TAC[subspace; conic]);; + +let CONIC_EMPTY = prove + (`conic {}`, + REWRITE_TAC[conic; NOT_IN_EMPTY]);; + +let CONIC_UNIV = prove + (`conic (UNIV:real^N->bool)`, + REWRITE_TAC[conic; IN_UNIV]);; + +let CONIC_INTERS = prove + (`(!s. s IN f ==> conic s) ==> conic(INTERS f)`, + REWRITE_TAC[conic; IN_INTERS] THEN MESON_TAC[]);; + +let CONIC_LINEAR_IMAGE = prove + (`!f s. conic s /\ linear f ==> conic(IMAGE f s)`, + REWRITE_TAC[conic; IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_IMAGE] THEN + REWRITE_TAC[IN_IMAGE] THEN MESON_TAC[LINEAR_CMUL]);; + +let CONIC_LINEAR_IMAGE_EQ = prove + (`!f s. linear f /\ (!x y. f x = f y ==> x = y) + ==> (conic (IMAGE f s) <=> conic s)`, + MATCH_ACCEPT_TAC(LINEAR_INVARIANT_RULE CONIC_LINEAR_IMAGE));; + +add_linear_invariants [CONIC_LINEAR_IMAGE_EQ];; + +let CONIC_CONIC_HULL = prove + (`!s. conic(conic hull s)`, + SIMP_TAC[P_HULL; CONIC_INTERS]);; + +let CONIC_HULL_EQ = prove + (`!s. (conic hull s = s) <=> conic s`, + SIMP_TAC[HULL_EQ; CONIC_INTERS]);; + +let CONIC_NEGATIONS = prove + (`!s. conic s ==> conic (IMAGE (--) s)`, + REWRITE_TAC[conic; RIGHT_FORALL_IMP_THM; IMP_CONJ; FORALL_IN_IMAGE] THEN + REWRITE_TAC[IN_IMAGE; VECTOR_MUL_RNEG] THEN MESON_TAC[]);; + +let CONIC_SPAN = prove + (`!s. conic(span s)`, + SIMP_TAC[SUBSPACE_IMP_CONIC; SUBSPACE_SPAN]);; + +let CONIC_HULL_EXPLICIT = prove + (`!s:real^N->bool. conic hull s = {c % x | &0 <= c /\ x IN s}`, + GEN_TAC THEN MATCH_MP_TAC HULL_UNIQUE THEN + REWRITE_TAC[conic; SUBSET; RIGHT_FORALL_IMP_THM; IMP_CONJ] THEN + REWRITE_TAC[FORALL_IN_GSPEC] THEN + REWRITE_TAC[RIGHT_IMP_FORALL_THM; IMP_IMP; IN_ELIM_THM] THEN + REPEAT CONJ_TAC THENL + [X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN + MAP_EVERY EXISTS_TAC [`&1`; `x:real^N`] THEN + ASM_SIMP_TAC[REAL_POS; VECTOR_MUL_LID]; + REWRITE_TAC[VECTOR_MUL_ASSOC] THEN MESON_TAC[REAL_LE_MUL]; + MESON_TAC[]]);; + +let CONIC_HULL_LINEAR_IMAGE = prove + (`!f s. linear f ==> conic hull (IMAGE f s) = IMAGE f (conic hull s)`, + REPEAT GEN_TAC THEN REWRITE_TAC[CONIC_HULL_EXPLICIT] THEN + REWRITE_TAC[SET_RULE `IMAGE f {c % x | P c x} = {f(c % x) | P c x}`] THEN + REWRITE_TAC[SET_RULE `{c % x | &0 <= c /\ x IN IMAGE f s} = + {c % f(x) | &0 <= c /\ x IN s}`] THEN + DISCH_THEN(fun th -> REWRITE_TAC[MATCH_MP LINEAR_CMUL th]));; + +add_linear_invariants [CONIC_HULL_LINEAR_IMAGE];; + +let CONVEX_CONIC_HULL = prove + (`!s:real^N->bool. convex s ==> convex (conic hull s)`, + REWRITE_TAC[CONIC_HULL_EXPLICIT] THEN + REWRITE_TAC[CONVEX_ALT; IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN + REWRITE_TAC[FORALL_IN_GSPEC] THEN REWRITE_TAC[IN_ELIM_THM; IMP_IMP] THEN + X_GEN_TAC `s:real^N->bool` THEN DISCH_TAC THEN + MAP_EVERY X_GEN_TAC [`c:real`; `x:real^N`] THEN STRIP_TAC THEN + MAP_EVERY X_GEN_TAC [`d:real`; `y:real^N`] THEN STRIP_TAC THEN + X_GEN_TAC `u:real` THEN STRIP_TAC THEN REWRITE_TAC[VECTOR_MUL_ASSOC] THEN + ASM_CASES_TAC `(&1 - u) * c = &0` THENL + [ASM_REWRITE_TAC[VECTOR_MUL_LZERO; VECTOR_ADD_LID] THEN + ASM_MESON_TAC[REAL_LE_MUL]; + ALL_TAC] THEN + SUBGOAL_THEN `&0 < (&1 - u) * c + u * d` ASSUME_TAC THENL + [MATCH_MP_TAC REAL_LTE_ADD THEN ASM_REWRITE_TAC[REAL_LT_LE] THEN + CONJ_TAC THEN MATCH_MP_TAC REAL_LE_MUL THEN ASM_REAL_ARITH_TAC; + ALL_TAC] THEN + EXISTS_TAC `(&1 - u) * c + u * d:real` THEN + EXISTS_TAC `((&1 - u) * c) / ((&1 - u) * c + u * d) % x + + (u * d) / ((&1 - u) * c + u * d) % y:real^N` THEN + REWRITE_TAC[VECTOR_ADD_LDISTRIB; VECTOR_MUL_ASSOC] THEN + ASM_SIMP_TAC[REAL_DIV_LMUL; REAL_LT_IMP_NZ] THEN + ASM_SIMP_TAC[REAL_LE_ADD; REAL_LE_MUL; REAL_SUB_LE] THEN + ASM_SIMP_TAC[REAL_FIELD + `&0 < u + v ==> u / (u + v) = &1 - (v / (u + v))`] THEN + RULE_ASSUM_TAC(REWRITE_RULE[RIGHT_IMP_FORALL_THM; IMP_IMP]) THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[] THEN + ASM_SIMP_TAC[REAL_LE_LDIV_EQ; REAL_LE_RDIV_EQ] THEN + ASM_SIMP_TAC[REAL_MUL_LZERO; REAL_LE_MUL; REAL_MUL_LID; REAL_LE_ADDL; + REAL_SUB_LE]);; + +let CONIC_HALFSPACE_LE = prove + (`!a. conic {x | a dot x <= &0}`, + REWRITE_TAC[conic; IN_ELIM_THM; DOT_RMUL] THEN + REWRITE_TAC[REAL_ARITH `a <= &0 <=> &0 <= --a`] THEN + SIMP_TAC[GSYM REAL_MUL_RNEG; REAL_LE_MUL]);; + +let CONIC_HALFSPACE_GE = prove + (`!a. conic {x | a dot x >= &0}`, + SIMP_TAC[conic; IN_ELIM_THM; DOT_RMUL; real_ge; REAL_LE_MUL]);; + +let CONIC_HULL_EMPTY = prove + (`conic hull {} = {}`, + MATCH_MP_TAC HULL_UNIQUE THEN + REWRITE_TAC[SUBSET_REFL; CONIC_EMPTY; EMPTY_SUBSET]);; + +let CONIC_CONTAINS_0 = prove + (`!s:real^N->bool. conic s ==> (vec 0 IN s <=> ~(s = {}))`, + REPEAT STRIP_TAC THEN EQ_TAC THENL [SET_TAC[]; ALL_TAC] THEN + REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN + DISCH_THEN(X_CHOOSE_TAC `x:real^N`) THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [conic]) THEN + DISCH_THEN(MP_TAC o SPECL [`x:real^N`; `&0`]) THEN + ASM_REWRITE_TAC[REAL_POS; VECTOR_MUL_LZERO]);; + +let CONIC_HULL_EQ_EMPTY = prove + (`!s. (conic hull s = {}) <=> (s = {})`, + GEN_TAC THEN EQ_TAC THEN + MESON_TAC[SUBSET_EMPTY; HULL_SUBSET; CONIC_HULL_EMPTY]);; + +let CONIC_SUMS = prove + (`!s t. conic s /\ conic t ==> conic {x + y:real^N | x IN s /\ y IN t}`, + REWRITE_TAC[conic; IN_ELIM_THM] THEN + MESON_TAC[VECTOR_ADD_LDISTRIB]);; + +let CONIC_PCROSS = prove + (`!s:real^M->bool t:real^N->bool. + conic s /\ conic t ==> conic(s PCROSS t)`, + REWRITE_TAC[conic; IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN + SIMP_TAC[FORALL_IN_PCROSS; GSYM PASTECART_CMUL; PASTECART_ADD] THEN + SIMP_TAC[PASTECART_IN_PCROSS]);; + +let CONIC_PCROSS_EQ = prove + (`!s:real^M->bool t:real^N->bool. + conic(s PCROSS t) <=> s = {} \/ t = {} \/ conic s /\ conic t`, + REPEAT GEN_TAC THEN + ASM_CASES_TAC `s:real^M->bool = {}` THEN + ASM_REWRITE_TAC[PCROSS_EMPTY; CONIC_EMPTY] THEN + ASM_CASES_TAC `t:real^N->bool = {}` THEN + ASM_REWRITE_TAC[PCROSS_EMPTY; CONIC_EMPTY] THEN + EQ_TAC THEN REWRITE_TAC[CONIC_PCROSS] THEN REPEAT STRIP_TAC THENL + [MP_TAC(ISPECL [`fstcart:real^(M,N)finite_sum->real^M`; + `(s:real^M->bool) PCROSS (t:real^N->bool)`] CONIC_LINEAR_IMAGE) THEN + ASM_REWRITE_TAC[LINEAR_FSTCART]; + MP_TAC(ISPECL [`sndcart:real^(M,N)finite_sum->real^N`; + `(s:real^M->bool) PCROSS (t:real^N->bool)`] CONIC_LINEAR_IMAGE) THEN + ASM_REWRITE_TAC[LINEAR_SNDCART]] THEN + MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN + REWRITE_TAC[EXTENSION; IN_IMAGE; EXISTS_PASTECART; PASTECART_IN_PCROSS; + FSTCART_PASTECART; SNDCART_PASTECART] THEN + ASM SET_TAC[]);; + +let CONIC_POSITIVE_ORTHANT = prove + (`conic {x:real^N | !i. 1 <= i /\ i <= dimindex(:N) ==> &0 <= x$i}`, + SIMP_TAC[conic; IN_ELIM_THM; REAL_LE_MUL; VECTOR_MUL_COMPONENT]);; + +let SEPARATE_CLOSED_CONES = prove + (`!c d:real^N->bool. + conic c /\ closed c /\ conic d /\ closed d /\ c INTER d SUBSET {vec 0} + ==> ?e. &0 < e /\ + !x y. x IN c /\ y IN d + ==> dist(x,y) >= e * max (norm x) (norm y)`, + SUBGOAL_THEN + `!c d:real^N->bool. + conic c /\ closed c /\ conic d /\ closed d /\ c INTER d SUBSET {vec 0} + ==> ?e. &0 < e /\ + !x y. x IN c /\ y IN d ==> dist(x,y) + >= e * norm x` + ASSUME_TAC THENL + [REPEAT STRIP_TAC THEN REWRITE_TAC[real_ge] THEN + MP_TAC(ISPECL [`c INTER sphere(vec 0:real^N,&1)`; `d:real^N->bool`] + SEPARATE_COMPACT_CLOSED) THEN + ASM_SIMP_TAC[CLOSED_INTER_COMPACT; COMPACT_SPHERE] THEN ANTS_TAC THENL + [FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE + `c INTER d SUBSET {a} ==> ~(a IN s) ==> (c INTER s) INTER d = {}`)) THEN + REWRITE_TAC[IN_SPHERE_0; NORM_0] THEN REAL_ARITH_TAC; + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `e:real` THEN + REWRITE_TAC[IN_INTER; IN_SPHERE_0] THEN STRIP_TAC THEN + ASM_REWRITE_TAC[] THEN + MAP_EVERY X_GEN_TAC [`x:real^N`; `y:real^N`] THEN STRIP_TAC THEN + ASM_CASES_TAC `x:real^N = vec 0` THEN + ASM_REWRITE_TAC[DIST_POS_LE; REAL_MUL_RZERO; NORM_0] THEN + FIRST_X_ASSUM(MP_TAC o SPECL + [`inv(norm x) % x:real^N`; `inv(norm(x:real^N)) % y:real^N`]) THEN + REWRITE_TAC[dist; NORM_MUL; GSYM VECTOR_SUB_LDISTRIB] THEN + REWRITE_TAC[REAL_ARITH `abs x * a = a * abs x`] THEN + REWRITE_TAC[REAL_ABS_INV; GSYM real_div; REAL_ABS_NORM] THEN + ASM_SIMP_TAC[REAL_LE_RDIV_EQ; NORM_POS_LT] THEN + DISCH_THEN MATCH_MP_TAC THEN + ASM_SIMP_TAC[REAL_DIV_REFL; NORM_EQ_0] THEN + RULE_ASSUM_TAC(REWRITE_RULE[conic]) THEN + CONJ_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_SIMP_TAC[REAL_LE_INV_EQ; NORM_POS_LE]]; + REPEAT STRIP_TAC THEN FIRST_X_ASSUM(fun th -> + MP_TAC(SPECL [`c:real^N->bool`; `d:real^N->bool`] th) THEN + MP_TAC(SPECL [`d:real^N->bool`; `c:real^N->bool`] th)) THEN + ASM_REWRITE_TAC[] THEN ONCE_REWRITE_TAC[INTER_COMM] THEN + ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM; real_ge] THEN + X_GEN_TAC `d:real` THEN STRIP_TAC THEN + X_GEN_TAC `e:real` THEN STRIP_TAC THEN + EXISTS_TAC `min d e:real` THEN ASM_REWRITE_TAC[REAL_LT_MIN] THEN + MAP_EVERY X_GEN_TAC [`x:real^N`; `y:real^N`] THEN STRIP_TAC THEN + REWRITE_TAC[real_max] THEN COND_CASES_TAC THEN + MATCH_MP_TAC REAL_LE_TRANS THENL + [EXISTS_TAC `d * norm(y:real^N)` THEN ONCE_REWRITE_TAC[DIST_SYM]; + EXISTS_TAC `e * norm(x:real^N)`] THEN + ASM_SIMP_TAC[] THEN MATCH_MP_TAC REAL_LE_RMUL THEN NORM_ARITH_TAC]);; + +let CONTINUOUS_ON_COMPACT_SURFACE_PROJECTION = prove + (`!s:real^N->bool v d:real^N->real. + compact s /\ s SUBSET (v DELETE (vec 0)) /\ conic v /\ + (!x k. x IN v DELETE (vec 0) ==> (&0 < k /\ (k % x) IN s <=> d x = k)) + ==> (\x. d x % x) continuous_on (v DELETE (vec 0))`, + let lemma = prove + (`!s:real^N->real^N p srf:real^N->bool pnc. + compact srf /\ srf SUBSET pnc /\ + IMAGE s pnc SUBSET srf /\ (!x. x IN srf ==> s x = x) /\ + p continuous_on pnc /\ + (!x. x IN pnc ==> s(p x) = s x /\ p(s x) = p x) + ==> s continuous_on pnc`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC CONTINUOUS_ON_EQ THEN + EXISTS_TAC `(s:real^N->real^N) o (p:real^N->real^N)` THEN + CONJ_TAC THENL [ASM_SIMP_TAC[o_DEF]; ALL_TAC] THEN + MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN ASM_REWRITE_TAC[] THEN + SUBGOAL_THEN `IMAGE (p:real^N->real^N) pnc = IMAGE p srf` SUBST1_TAC THENL + [ASM SET_TAC[]; + MATCH_MP_TAC CONTINUOUS_ON_INVERSE THEN ASM_REWRITE_TAC[] THEN + CONJ_TAC THENL [ASM_MESON_TAC[CONTINUOUS_ON_SUBSET]; ASM SET_TAC[]]]) in + REWRITE_TAC[conic; IN_DELETE; SUBSET] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC lemma THEN + MAP_EVERY EXISTS_TAC [`\x:real^N. inv(norm x) % x`; `s:real^N->bool`] THEN + ASM_REWRITE_TAC[] THEN + CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + ONCE_REWRITE_TAC[TAUT `p /\ q /\ r <=> q /\ p /\ r`] THEN CONJ_TAC THENL + [MATCH_MP_TAC CONTINUOUS_ON_MUL THEN SIMP_TAC[o_DEF; CONTINUOUS_ON_ID] THEN + MATCH_MP_TAC(REWRITE_RULE[o_DEF] CONTINUOUS_ON_INV) THEN + SIMP_TAC[IN_DELETE; NORM_EQ_0; SIMP_RULE[o_DEF] CONTINUOUS_ON_LIFT_NORM]; + REWRITE_TAC[IN_UNIV; IN_DELETE]] THEN + CONJ_TAC THENL + [X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`x:real^N`; `&1`]) THEN + ASM_REWRITE_TAC[VECTOR_MUL_LID; REAL_LT_01; IN_DELETE] THEN + ASM_MESON_TAC[VECTOR_MUL_LID; SUBSET; IN_DELETE]; + ALL_TAC] THEN + X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN CONJ_TAC THENL + [FIRST_ASSUM(MP_TAC o SPECL + [`inv(norm x) % x:real^N`; `norm x * (d:real^N->real) x`]) THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`x:real^N`; `(d:real^N->real) x`]) THEN + ASM_SIMP_TAC[VECTOR_MUL_EQ_0; REAL_INV_EQ_0; NORM_EQ_0] THEN STRIP_TAC THEN + ASM_SIMP_TAC[REAL_LE_INV_EQ; NORM_POS_LE; REAL_LT_MUL; NORM_POS_LT] THEN + ASM_SIMP_TAC[VECTOR_MUL_ASSOC; NORM_EQ_0; REAL_FIELD + `~(n = &0) ==> (n * d) * inv n = d`]; + FIRST_X_ASSUM(MP_TAC o SPECL [`x:real^N`; `(d:real^N->real) x`]) THEN + ASM_REWRITE_TAC[] THEN STRIP_TAC THEN + ASM_SIMP_TAC[NORM_MUL; VECTOR_MUL_ASSOC; REAL_INV_MUL] THEN + ASM_SIMP_TAC[real_abs; REAL_LT_IMP_LE] THEN + ASM_SIMP_TAC[REAL_FIELD `&0 < x ==> (inv(x) * y) * x = y`]]);; + +(* ------------------------------------------------------------------------- *) +(* Affine dependence and consequential theorems (from Lars Schewe). *) +(* ------------------------------------------------------------------------- *) + +let affine_dependent = new_definition + `affine_dependent (s:real^N -> bool) <=> + ?x. x IN s /\ x IN (affine hull (s DELETE x))`;; + +let AFFINE_DEPENDENT_EXPLICIT = prove + (`!p. affine_dependent (p:real^N -> bool) <=> + (?s u. FINITE s /\ s SUBSET p /\ + sum s u = &0 /\ + (?v. v IN s /\ ~(u v = &0)) /\ + vsum s (\v. u v % v) = (vec 0):real^N)`, + X_GEN_TAC `p:real^N->bool` THEN EQ_TAC THENL + [REWRITE_TAC[affine_dependent;AFFINE_HULL_EXPLICIT; + IN_ELIM_THM] THEN + REPEAT STRIP_TAC THEN + EXISTS_TAC `(x:real^N) INSERT s` THEN + EXISTS_TAC `\v:real^N.if v = x then -- &1 else u v` THEN + ASM_SIMP_TAC[FINITE_INSERT;SUM_CLAUSES;VSUM_CLAUSES;INSERT_SUBSET] THEN + REPEAT CONJ_TAC THENL + [ASM SET_TAC[]; + COND_CASES_TAC THENL [ASM SET_TAC[];ALL_TAC] THEN + ASM_SIMP_TAC[SUM_CASES; SUM_CLAUSES; SET_RULE + `~((x:real^N) IN s) ==> {v | v IN s /\ v = x} = {} /\ + {v | v IN s /\ ~(v = x)} = s`] THEN + REAL_ARITH_TAC; + SET_TAC[REAL_ARITH `~(-- &1 = &0)`]; + MP_TAC (SET_RULE `s SUBSET p DELETE (x:real^N) ==> ~(x IN s)`) THEN + ASM_REWRITE_TAC[] THEN + DISCH_TAC THEN + ASM_SIMP_TAC[VECTOR_ARITH + `(-- &1 % (x:real^N)) + a = vec 0 <=> a = x`] THEN + MATCH_MP_TAC EQ_TRANS THEN + EXISTS_TAC `vsum s (\v:real^N. u v % v)` THEN + CONJ_TAC THENL [ + MATCH_MP_TAC VSUM_EQ THEN + ASM_SIMP_TAC[] THEN + ASM SET_TAC[]; + ASM_REWRITE_TAC[]]]; + ALL_TAC] THEN + REWRITE_TAC[affine_dependent;AFFINE_HULL_EXPLICIT;IN_ELIM_THM] THEN + REPEAT STRIP_TAC THEN + EXISTS_TAC `v:real^N` THEN + CONJ_TAC THENL [ASM SET_TAC[];ALL_TAC] THEN + EXISTS_TAC `s DELETE (v:real^N)` THEN + EXISTS_TAC `\x:real^N. -- (&1 / (u v)) * u x` THEN + ASM_SIMP_TAC[FINITE_DELETE;SUM_DELETE;VSUM_DELETE_CASES] THEN + ASM_SIMP_TAC[SUM_LMUL;GSYM VECTOR_MUL_ASSOC;VSUM_LMUL; + VECTOR_MUL_RZERO;VECTOR_ARITH `vec 0 - -- a % x = a % x:real^N`; + REAL_MUL_RZERO;REAL_ARITH `&0 - -- a * b = a * b`] THEN + ASM_SIMP_TAC[REAL_FIELD `~(x = &0) ==> &1 / x * x = &1`; + VECTOR_MUL_ASSOC;VECTOR_MUL_LID] THEN + CONJ_TAC THENL [ALL_TAC;ASM SET_TAC[]] THEN + ASM_SIMP_TAC[SET_RULE `v IN s ==> (s DELETE v = {} <=> s = {v})`] THEN + ASM_CASES_TAC `s = {v:real^N}` THEN + ASM_REWRITE_TAC[] THEN + FIRST_X_ASSUM SUBST_ALL_TAC THEN + FIND_ASSUM MP_TAC `sum {v:real^N} u = &0` THEN + REWRITE_TAC[SUM_SING] + THEN ASM_REWRITE_TAC[]);; + +let AFFINE_DEPENDENT_EXPLICIT_FINITE = prove + (`!s. FINITE(s:real^N -> bool) + ==> (affine_dependent s <=> + ?u. sum s u = &0 /\ + (?v. v IN s /\ ~(u v = &0)) /\ + vsum s (\v. u v % v) = vec 0)`, + REPEAT STRIP_TAC THEN REWRITE_TAC[AFFINE_DEPENDENT_EXPLICIT] THEN + EQ_TAC THENL [ALL_TAC; ASM_MESON_TAC[SUBSET_REFL]] THEN + DISCH_THEN(X_CHOOSE_THEN `t:real^N->bool` + (X_CHOOSE_THEN `u:real^N->real` STRIP_ASSUME_TAC)) THEN + EXISTS_TAC `\x:real^N. if x IN t then u(x) else &0` THEN + REWRITE_TAC[COND_RAND; COND_RATOR; VECTOR_MUL_LZERO] THEN + ASM_SIMP_TAC[GSYM SUM_RESTRICT_SET; GSYM VSUM_RESTRICT_SET] THEN + ASM_SIMP_TAC[SET_RULE `t SUBSET s ==> {x | x IN s /\ x IN t} = t`] THEN + ASM SET_TAC[]);; + +let AFFINE_DEPENDENT_TRANSLATION_EQ = prove + (`!a s. affine_dependent (IMAGE (\x. a + x) s) <=> affine_dependent s`, + REWRITE_TAC[affine_dependent] THEN GEOM_TRANSLATE_TAC[]);; + +add_translation_invariants [AFFINE_DEPENDENT_TRANSLATION_EQ];; + +let AFFINE_DEPENDENT_TRANSLATION = prove + (`!s a. affine_dependent s ==> affine_dependent (IMAGE (\x. a + x) s)`, + REWRITE_TAC[AFFINE_DEPENDENT_TRANSLATION_EQ]);; + +let AFFINE_DEPENDENT_LINEAR_IMAGE_EQ = prove + (`!f:real^M->real^N s. + linear f /\ (!x y. f x = f y ==> x = y) + ==> (affine_dependent(IMAGE f s) <=> affine_dependent s)`, + REWRITE_TAC[affine_dependent] THEN GEOM_TRANSFORM_TAC[]);; + +add_linear_invariants [AFFINE_DEPENDENT_LINEAR_IMAGE_EQ];; + +let AFFINE_DEPENDENT_LINEAR_IMAGE = prove + (`!f:real^M->real^N s. + linear f /\ (!x y. x IN s /\ y IN s /\ f x = f y ==> x = y) /\ + affine_dependent(s) + ==> affine_dependent(IMAGE f s)`, + REPEAT GEN_TAC THEN + REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + REWRITE_TAC[affine_dependent; EXISTS_IN_IMAGE] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `a:real^M` THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + SUBGOAL_THEN `IMAGE (f:real^M->real^N) s DELETE f a = IMAGE f (s DELETE a)` + (fun t -> ASM_SIMP_TAC[FUN_IN_IMAGE; AFFINE_HULL_LINEAR_IMAGE; t]) THEN + ASM SET_TAC[]);; + +let AFFINE_DEPENDENT_MONO = prove + (`!s t:real^N->bool. affine_dependent s /\ s SUBSET t ==> affine_dependent t`, + REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN + REWRITE_TAC[affine_dependent] THEN MATCH_MP_TAC MONO_EXISTS THEN + X_GEN_TAC `x:real^N` THEN MATCH_MP_TAC MONO_AND THEN CONJ_TAC THEN + FIRST_ASSUM(MP_TAC o MATCH_MP HULL_MONO o SPEC `x:real^N` o MATCH_MP + (SET_RULE `!x. s SUBSET t ==> (s DELETE x) SUBSET (t DELETE x)`)) THEN + ASM SET_TAC[]);; + +let AFFINE_INDEPENDENT_EMPTY = prove + (`~(affine_dependent {})`, + REWRITE_TAC[affine_dependent; NOT_IN_EMPTY]);; + +let AFFINE_INDEPENDENT_1 = prove + (`!a:real^N. ~(affine_dependent {a})`, + REWRITE_TAC[affine_dependent; EXISTS_IN_INSERT; NOT_IN_EMPTY] THEN + REWRITE_TAC[SET_RULE `{a} DELETE a = {}`; AFFINE_HULL_EMPTY; NOT_IN_EMPTY]);; + +let AFFINE_INDEPENDENT_2 = prove + (`!a b:real^N. ~(affine_dependent {a,b})`, + REPEAT GEN_TAC THEN ASM_CASES_TAC `b:real^N = a` THENL + [ASM_REWRITE_TAC[INSERT_AC; AFFINE_INDEPENDENT_1]; + REWRITE_TAC[affine_dependent; EXISTS_IN_INSERT; NOT_IN_EMPTY] THEN + ASM_SIMP_TAC[SET_RULE + `~(a = b) ==> {a,b} DELETE a = {b} /\ {a,b} DELETE b = {a}`] THEN + ASM_REWRITE_TAC[AFFINE_HULL_SING; IN_SING]]);; + +let AFFINE_INDEPENDENT_SUBSET = prove + (`!s t. ~affine_dependent t /\ s SUBSET t ==> ~affine_dependent s`, + REWRITE_TAC[IMP_CONJ_ALT; CONTRAPOS_THM] THEN + REWRITE_TAC[GSYM IMP_CONJ_ALT; AFFINE_DEPENDENT_MONO]);; + +let AFFINE_INDEPENDENT_DELETE = prove + (`!s a. ~affine_dependent s ==> ~affine_dependent(s DELETE a)`, + REPEAT GEN_TAC THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] AFFINE_INDEPENDENT_SUBSET) THEN + SET_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* Coplanarity, and collinearity in terms of affine hull. *) +(* ------------------------------------------------------------------------- *) + +let coplanar = new_definition + `coplanar s <=> ?u v w. s SUBSET affine hull {u,v,w}`;; + +let COLLINEAR_AFFINE_HULL = prove + (`!s:real^N->bool. collinear s <=> ?u v. s SUBSET affine hull {u,v}`, + GEN_TAC THEN REWRITE_TAC[collinear; AFFINE_HULL_2] THEN EQ_TAC THEN + REWRITE_TAC[SUBSET; IN_ELIM_THM; LEFT_IMP_EXISTS_THM] THEN + REWRITE_TAC[REAL_ARITH `u + v = &1 <=> &1 - u = v`; UNWIND_THM1] THENL + [X_GEN_TAC `u:real^N` THEN DISCH_TAC THEN + ASM_CASES_TAC `s:real^N->bool = {}` THEN + ASM_REWRITE_TAC[NOT_IN_EMPTY] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `x:real^N` THEN + DISCH_TAC THEN EXISTS_TAC `x + u:real^N` THEN X_GEN_TAC `y:real^N` THEN + DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`x:real^N`; `y:real^N`]) THEN + ASM_REWRITE_TAC[VECTOR_ARITH `x - y:real^N = z <=> x = y + z`] THEN + DISCH_THEN(X_CHOOSE_THEN `c:real` SUBST1_TAC) THEN + EXISTS_TAC `&1 + c` THEN VECTOR_ARITH_TAC; + MAP_EVERY X_GEN_TAC [`a:real^N`; `b:real^N`] THEN DISCH_TAC THEN + EXISTS_TAC `b - a:real^N` THEN + MAP_EVERY X_GEN_TAC [`x:real^N`; `y:real^N`] THEN STRIP_TAC THEN + FIRST_X_ASSUM(fun th -> + MP_TAC(SPEC `y:real^N` th) THEN MP_TAC(SPEC `x:real^N` th)) THEN + ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `r:real` THEN DISCH_THEN SUBST1_TAC THEN + X_GEN_TAC `s:real` THEN DISCH_THEN SUBST1_TAC THEN + EXISTS_TAC `s - r:real` THEN VECTOR_ARITH_TAC]);; + +let COLLINEAR_IMP_COPLANAR = prove + (`!s. collinear s ==> coplanar s`, + REWRITE_TAC[coplanar; COLLINEAR_AFFINE_HULL] THEN MESON_TAC[INSERT_AC]);; + +let COPLANAR_SMALL = prove + (`!s. FINITE s /\ CARD s <= 3 ==> coplanar s`, + GEN_TAC THEN REWRITE_TAC[ARITH_RULE `s <= 3 <=> s <= 2 \/ s = 3`] THEN + REWRITE_TAC[LEFT_OR_DISTRIB; GSYM HAS_SIZE] THEN + DISCH_THEN(DISJ_CASES_THEN MP_TAC) THEN + SIMP_TAC[COLLINEAR_IMP_COPLANAR; COLLINEAR_SMALL] THEN + CONV_TAC(LAND_CONV HAS_SIZE_CONV) THEN REWRITE_TAC[coplanar] THEN + REPEAT(MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC) THEN + STRIP_TAC THEN ASM_REWRITE_TAC[HULL_INC; SUBSET]);; + +let COPLANAR_EMPTY = prove + (`coplanar {}`, + SIMP_TAC[COLLINEAR_IMP_COPLANAR; COLLINEAR_EMPTY]);; + +let COPLANAR_SING = prove + (`!a. coplanar {a}`, + SIMP_TAC[COLLINEAR_IMP_COPLANAR; COLLINEAR_SING]);; + +let COPLANAR_2 = prove + (`!a b. coplanar {a,b}`, + SIMP_TAC[COLLINEAR_IMP_COPLANAR; COLLINEAR_2]);; + +let COPLANAR_3 = prove + (`!a b c. coplanar {a,b,c}`, + REPEAT GEN_TAC THEN MATCH_MP_TAC COPLANAR_SMALL THEN + SIMP_TAC[CARD_CLAUSES; FINITE_INSERT; FINITE_RULES] THEN ARITH_TAC);; + +let COLLINEAR_AFFINE_HULL_COLLINEAR = prove + (`!s. collinear(affine hull s) <=> collinear s`, + REWRITE_TAC[COLLINEAR_AFFINE_HULL] THEN + MESON_TAC[HULL_HULL; HULL_MONO; HULL_INC; SUBSET]);; + +let COPLANAR_AFFINE_HULL_COPLANAR = prove + (`!s. coplanar(affine hull s) <=> coplanar s`, + REWRITE_TAC[coplanar] THEN + MESON_TAC[HULL_HULL; HULL_MONO; HULL_INC; SUBSET]);; + +let COPLANAR_TRANSLATION_EQ = prove + (`!a:real^N s. coplanar(IMAGE (\x. a + x) s) <=> coplanar s`, + REWRITE_TAC[coplanar] THEN GEOM_TRANSLATE_TAC[]);; + +let COPLANAR_TRANSLATION = prove + (`!a:real^N s. coplanar s ==> coplanar(IMAGE (\x. a + x) s)`, + REWRITE_TAC[COPLANAR_TRANSLATION_EQ]);; + +add_translation_invariants [COPLANAR_TRANSLATION_EQ];; + +let COPLANAR_LINEAR_IMAGE = prove + (`!f:real^M->real^N s. coplanar s /\ linear f ==> coplanar(IMAGE f s)`, + REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN + REWRITE_TAC[coplanar; LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`a:real^M`; `b:real^M`; `c:real^M`] THEN STRIP_TAC THEN + MAP_EVERY EXISTS_TAC + [`(f:real^M->real^N) a`; `(f:real^M->real^N) b`; `(f:real^M->real^N) c`] THEN + REWRITE_TAC[SET_RULE `{f a,f b,f c} = IMAGE f {a,b,c}`] THEN + ASM_SIMP_TAC[AFFINE_HULL_LINEAR_IMAGE; IMAGE_SUBSET]);; + +let COPLANAR_LINEAR_IMAGE_EQ = prove + (`!f s. linear f /\ (!x y. f x = f y ==> x = y) + ==> (coplanar (IMAGE f s) <=> coplanar s)`, + MATCH_ACCEPT_TAC(LINEAR_INVARIANT_RULE COPLANAR_LINEAR_IMAGE));; + +add_linear_invariants [COPLANAR_LINEAR_IMAGE_EQ];; + +let COPLANAR_SUBSET = prove + (`!s t. coplanar t /\ s SUBSET t ==> coplanar s`, + REWRITE_TAC[coplanar] THEN SET_TAC[]);; + +let AFFINE_HULL_3_IMP_COLLINEAR = prove + (`!a b c. c IN affine hull {a,b} ==> collinear {a,b,c}`, + ONCE_REWRITE_TAC[GSYM COLLINEAR_AFFINE_HULL_COLLINEAR] THEN + SIMP_TAC[HULL_REDUNDANT_EQ; INSERT_AC] THEN + REWRITE_TAC[COLLINEAR_AFFINE_HULL_COLLINEAR; COLLINEAR_2]);; + +let COLLINEAR_3_AFFINE_HULL = prove + (`!a b c:real^N. + ~(a = b) ==> (collinear {a,b,c} <=> c IN affine hull {a,b})`, + REPEAT STRIP_TAC THEN EQ_TAC THEN SIMP_TAC[AFFINE_HULL_3_IMP_COLLINEAR] THEN + REWRITE_TAC[collinear] THEN + DISCH_THEN(X_CHOOSE_THEN `u:real^N` STRIP_ASSUME_TAC) THEN + FIRST_ASSUM(fun th -> MP_TAC(SPECL [`b:real^N`; `a:real^N`] th) THEN + MP_TAC(SPECL [`c:real^N`; `a:real^N`] th)) THEN + REWRITE_TAC[IN_INSERT; AFFINE_HULL_2; IN_ELIM_THM; LEFT_IMP_EXISTS_THM] THEN + REWRITE_TAC[VECTOR_ARITH `a - b:real^N = c <=> a = b + c`] THEN + X_GEN_TAC `x:real` THEN DISCH_TAC THEN X_GEN_TAC `y:real` THEN + ASM_CASES_TAC `y = &0` THEN + ASM_REWRITE_TAC[VECTOR_MUL_LZERO; VECTOR_ADD_RID] THEN DISCH_TAC THEN + ASM_REWRITE_TAC[] THEN + MAP_EVERY EXISTS_TAC [`&1 - x / y`; `x / y:real`] THEN + CONJ_TAC THENL [REAL_ARITH_TAC; ALL_TAC] THEN + REWRITE_TAC[VECTOR_ADD_LDISTRIB; VECTOR_MUL_ASSOC] THEN + ASM_SIMP_TAC[REAL_DIV_RMUL] THEN VECTOR_ARITH_TAC);; + +let COLLINEAR_3_EQ_AFFINE_DEPENDENT = prove + (`!a b c:real^N. + collinear{a,b,c} <=> + a = b \/ a = c \/ b = c \/ affine_dependent {a,b,c}`, + REPEAT GEN_TAC THEN + MAP_EVERY (fun t -> + ASM_CASES_TAC t THENL [ASM_REWRITE_TAC[INSERT_AC; COLLINEAR_2]; ALL_TAC]) + [`a:real^N = b`; `a:real^N = c`; `b:real^N = c`] THEN + ASM_REWRITE_TAC[affine_dependent] THEN EQ_TAC THENL + [ASM_SIMP_TAC[COLLINEAR_3_AFFINE_HULL] THEN DISCH_TAC THEN + EXISTS_TAC `c:real^N` THEN REWRITE_TAC[IN_INSERT]; + REWRITE_TAC[EXISTS_IN_INSERT; NOT_IN_EMPTY] THEN STRIP_TAC THENL + [ONCE_REWRITE_TAC[SET_RULE `{a,b,c} = {b,c,a}`]; + ONCE_REWRITE_TAC[SET_RULE `{a,b,c} = {c,a,b}`]; + ALL_TAC] THEN + ASM_SIMP_TAC[COLLINEAR_3_AFFINE_HULL]] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE + `x IN s ==> s SUBSET t ==> x IN t`)) THEN + MATCH_MP_TAC HULL_MONO THEN ASM SET_TAC[]);; + +let AFFINE_DEPENDENT_IMP_COLLINEAR_3 = prove + (`!a b c:real^N. affine_dependent {a,b,c} ==> collinear{a,b,c}`, + REPEAT GEN_TAC THEN REWRITE_TAC[affine_dependent] THEN + REWRITE_TAC[IN_INSERT; NOT_IN_EMPTY; RIGHT_OR_DISTRIB] THEN + REWRITE_TAC[EXISTS_OR_THM; UNWIND_THM2; COLLINEAR_AFFINE_HULL] THEN + STRIP_TAC THENL + [MAP_EVERY EXISTS_TAC [`b:real^N`; `c:real^N`]; + MAP_EVERY EXISTS_TAC [`a:real^N`; `c:real^N`]; + MAP_EVERY EXISTS_TAC [`a:real^N`; `b:real^N`]] THEN + SIMP_TAC[INSERT_SUBSET; EMPTY_SUBSET; HULL_INC; IN_INSERT] THEN + POP_ASSUM MP_TAC THEN + MATCH_MP_TAC(SET_RULE `s SUBSET t ==> a IN s ==> a IN t`) THEN + MATCH_MP_TAC HULL_MONO THEN SET_TAC[]);; + +let COLLINEAR_3_IN_AFFINE_HULL = prove + (`!v0 v1 x:real^N. + ~(v1 = v0) + ==> (collinear {v0,v1,x} <=> x IN affine hull {v0,v1})`, + REPEAT GEN_TAC THEN GEOM_ORIGIN_TAC `v0:real^N` THEN + REWRITE_TAC[COLLINEAR_LEMMA; AFFINE_HULL_2] THEN REPEAT STRIP_TAC THEN + ASM_REWRITE_TAC[VECTOR_MUL_RZERO; VECTOR_ADD_LID; IN_ELIM_THM] THEN + ASM_CASES_TAC `x:real^N = vec 0` THEN ASM_REWRITE_TAC[] THENL + [MAP_EVERY EXISTS_TAC [`&1`; `&0`] THEN CONV_TAC REAL_RAT_REDUCE_CONV THEN + VECTOR_ARITH_TAC; + MESON_TAC[REAL_ARITH `u + v = &1 <=> u = &1 - v`]]);; + +(* ------------------------------------------------------------------------- *) +(* A general lemma. *) +(* ------------------------------------------------------------------------- *) + +let CONVEX_CONNECTED = prove + (`!s:real^N->bool. convex s ==> connected s`, + REWRITE_TAC[CONVEX_ALT; connected; SUBSET; EXTENSION; IN_INTER; + IN_UNION; NOT_IN_EMPTY; NOT_FORALL_THM; NOT_EXISTS_THM] THEN + GEN_TAC THEN DISCH_TAC THEN REPEAT GEN_TAC THEN + MAP_EVERY (K(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC))) (1--4) THEN + DISCH_THEN(CONJUNCTS_THEN2 (X_CHOOSE_THEN `x1:real^N` STRIP_ASSUME_TAC) + (X_CHOOSE_THEN `x2:real^N` STRIP_ASSUME_TAC)) THEN + MP_TAC(ISPECL [`\u. (&1 - u) % x1 + u % (x2:real^N)`; + `&0`; `&1`; `e1:real^N->bool`; `e2:real^N->bool`] + (REWRITE_RULE[GSYM open_def] CONNECTED_REAL_LEMMA)) THEN + ASM_REWRITE_TAC[NOT_IMP; REAL_SUB_RZERO; VECTOR_MUL_LID; VECTOR_MUL_LZERO; + REAL_SUB_REFL; VECTOR_ADD_RID; VECTOR_ADD_LID; REAL_POS] THEN + REPEAT(CONJ_TAC THENL [ALL_TAC; ASM_MESON_TAC[]]) THEN + REPEAT STRIP_TAC THEN REWRITE_TAC[dist] THEN + REWRITE_TAC[NORM_MUL; VECTOR_ARITH + `((&1 - a) % x + a % y) - ((&1 - b) % x + b % y) = (a - b) % (y - x)`] THEN + MP_TAC(ISPEC `(x2 - x1):real^N` NORM_POS_LE) THEN + REWRITE_TAC[REAL_LE_LT] THEN STRIP_TAC THENL + [ALL_TAC; ASM_MESON_TAC[REAL_MUL_RZERO; REAL_LT_01]] THEN + EXISTS_TAC `e / norm((x2 - x1):real^N)` THEN + ASM_SIMP_TAC[REAL_LT_RDIV_EQ; REAL_LT_DIV]);; + +(* ------------------------------------------------------------------------- *) +(* Various topological facts are queued up here, just because they rely on *) +(* CONNECTED_UNIV, which is a trivial consequence of CONVEX_UNIV. It would *) +(* be fairly easy to prove it earlier and move these back to the topology.ml *) +(* file, which is a bit tidier intellectually. *) +(* ------------------------------------------------------------------------- *) + +let CONNECTED_UNIV = prove + (`connected (UNIV:real^N->bool)`, + SIMP_TAC[CONVEX_CONNECTED; CONVEX_UNIV]);; + +let CONNECTED_COMPONENT_UNIV = prove + (`!x. connected_component(:real^N) x = (:real^N)`, + MESON_TAC[CONNECTED_CONNECTED_COMPONENT_SET; CONNECTED_UNIV; IN_UNIV]);; + +let CONNECTED_COMPONENT_EQ_UNIV = prove + (`!s x. connected_component s x = (:real^N) <=> s = (:real^N)`, + REPEAT GEN_TAC THEN EQ_TAC THEN SIMP_TAC[CONNECTED_COMPONENT_UNIV] THEN + MATCH_MP_TAC(SET_RULE `s SUBSET t ==> s = UNIV ==> t = UNIV`) THEN + REWRITE_TAC[CONNECTED_COMPONENT_SUBSET]);; + +let CLOPEN = prove + (`!s. closed s /\ open s <=> s = {} \/ s = (:real^N)`, + GEN_TAC THEN EQ_TAC THEN STRIP_TAC THEN + ASM_REWRITE_TAC[CLOSED_EMPTY; OPEN_EMPTY; CLOSED_UNIV; OPEN_UNIV] THEN + MATCH_MP_TAC(REWRITE_RULE[CONNECTED_CLOPEN] CONNECTED_UNIV) THEN + ASM_REWRITE_TAC[SUBTOPOLOGY_UNIV; GSYM OPEN_IN; GSYM CLOSED_IN]);; + +let COMPACT_OPEN = prove + (`!s:real^N->bool. compact s /\ open s <=> s = {}`, + MESON_TAC[COMPACT_EMPTY; OPEN_EMPTY; COMPACT_IMP_CLOSED; CLOPEN; + COMPACT_IMP_BOUNDED; NOT_BOUNDED_UNIV]);; + +let FRONTIER_NOT_EMPTY = prove + (`!s. ~(s = {}) /\ ~(s = (:real^N)) ==> ~(frontier s = {})`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`(:real^N)`; `s:real^N->bool`] CONNECTED_INTER_FRONTIER) THEN + REWRITE_TAC[CONNECTED_UNIV] THEN ASM SET_TAC[]);; + +let FRONTIER_EQ_EMPTY = prove + (`!s. frontier s = {} <=> s = {} \/ s = (:real^N)`, + MESON_TAC[FRONTIER_NOT_EMPTY; FRONTIER_EMPTY; FRONTIER_UNIV]);; + +let EQ_INTERVAL = prove + (`(!a b c d:real^N. + interval[a,b] = interval[c,d] <=> + interval[a,b] = {} /\ interval[c,d] = {} \/ a = c /\ b = d) /\ + (!a b c d:real^N. + interval[a,b] = interval(c,d) <=> + interval[a,b] = {} /\ interval(c,d) = {}) /\ + (!a b c d:real^N. + interval(a,b) = interval[c,d] <=> + interval(a,b) = {} /\ interval[c,d] = {}) /\ + (!a b c d:real^N. + interval(a,b) = interval(c,d) <=> + interval(a,b) = {} /\ interval(c,d) = {} \/ a = c /\ b = d)`, + REPEAT CONJ_TAC THEN REPEAT GEN_TAC THEN + (EQ_TAC THENL [ALL_TAC; STRIP_TAC THEN ASM_REWRITE_TAC[]]) THEN + MATCH_MP_TAC(MESON[] + `(p = {} /\ q = {} ==> r) /\ (~(p = {}) /\ ~(q = {}) ==> p = q ==> r) + ==> p = q ==> r`) THEN + SIMP_TAC[] THENL + [REWRITE_TAC[INTERVAL_NE_EMPTY; CART_EQ] THEN + REWRITE_TAC[GSYM SUBSET_ANTISYM_EQ] THEN + SIMP_TAC[SUBSET_INTERVAL; GSYM REAL_LE_ANTISYM]; + STRIP_TAC THEN MATCH_MP_TAC(MESON[CLOPEN] + `closed s /\ open t /\ ~(s = {}) /\ ~(s = UNIV) ==> ~(s = t)`) THEN + ASM_REWRITE_TAC[CLOSED_INTERVAL; OPEN_INTERVAL; NOT_INTERVAL_UNIV]; + STRIP_TAC THEN MATCH_MP_TAC(MESON[CLOPEN] + `closed s /\ open t /\ ~(s = {}) /\ ~(s = UNIV) ==> ~(t = s)`) THEN + ASM_REWRITE_TAC[CLOSED_INTERVAL; OPEN_INTERVAL; NOT_INTERVAL_UNIV]; + REWRITE_TAC[INTERVAL_NE_EMPTY; CART_EQ] THEN + REWRITE_TAC[GSYM SUBSET_ANTISYM_EQ] THEN + SIMP_TAC[SUBSET_INTERVAL; GSYM REAL_LE_ANTISYM]]);; + +let CLOSED_INTERVAL_EQ = prove + (`(!a b:real^N. closed(interval[a,b])) /\ + (!a b:real^N. closed(interval(a,b)) <=> interval(a,b) = {})`, + REWRITE_TAC[CLOSED_INTERVAL] THEN + REPEAT GEN_TAC THEN EQ_TAC THEN STRIP_TAC THEN + ASM_REWRITE_TAC[CLOSED_EMPTY] THEN + MP_TAC(ISPEC `interval(a:real^N,b)` CLOPEN) THEN + ASM_REWRITE_TAC[OPEN_INTERVAL] THEN + MESON_TAC[BOUNDED_INTERVAL; NOT_BOUNDED_UNIV]);; + +let OPEN_INTERVAL_EQ = prove + (`(!a b:real^N. open(interval[a,b]) <=> interval[a,b] = {}) /\ + (!a b:real^N. open(interval(a,b)))`, + REWRITE_TAC[OPEN_INTERVAL] THEN + REPEAT GEN_TAC THEN EQ_TAC THEN STRIP_TAC THEN + ASM_REWRITE_TAC[CLOSED_EMPTY] THEN + MP_TAC(ISPEC `interval[a:real^N,b]` CLOPEN) THEN + ASM_REWRITE_TAC[CLOSED_INTERVAL] THEN + MESON_TAC[BOUNDED_INTERVAL; NOT_BOUNDED_UNIV]);; + +let COMPACT_INTERVAL_EQ = prove + (`(!a b:real^N. compact(interval[a,b])) /\ + (!a b:real^N. compact(interval(a,b)) <=> interval(a,b) = {})`, + REWRITE_TAC[COMPACT_EQ_BOUNDED_CLOSED; BOUNDED_INTERVAL] THEN + REWRITE_TAC[CLOSED_INTERVAL_EQ]);; + +let CONNECTED_CHAIN = prove + (`!f:(real^N->bool)->bool. + (!s. s IN f ==> compact s /\ connected s) /\ + (!s t. s IN f /\ t IN f ==> s SUBSET t \/ t SUBSET s) + ==> connected(INTERS f)`, + REPEAT STRIP_TAC THEN + ASM_CASES_TAC `f:(real^N->bool)->bool = {}` THEN + ASM_REWRITE_TAC[INTERS_0; CONNECTED_UNIV] THEN + ABBREV_TAC `c:real^N->bool = INTERS f` THEN + SUBGOAL_THEN `compact(c:real^N->bool)` ASSUME_TAC THENL + [EXPAND_TAC "c" THEN MATCH_MP_TAC COMPACT_INTERS THEN ASM SET_TAC[]; + ALL_TAC] THEN + ASM_SIMP_TAC[CONNECTED_CLOSED_SET; COMPACT_IMP_CLOSED; NOT_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`a:real^N->bool`; `b:real^N->bool`] THEN STRIP_TAC THEN + MP_TAC(ISPECL [`a:real^N->bool`; `b:real^N->bool`] SEPARATION_NORMAL) THEN + ASM_REWRITE_TAC[NOT_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`u:real^N->bool`; `v:real^N->bool`] THEN + STRIP_TAC THEN + SUBGOAL_THEN `?k:real^N->bool. k IN f` STRIP_ASSUME_TAC THENL + [ASM SET_TAC[]; ALL_TAC] THEN + SUBGOAL_THEN `?n:real^N->bool. open n /\ k SUBSET n` MP_TAC THENL + [ASM_MESON_TAC[BOUNDED_SUBSET_BALL; COMPACT_IMP_BOUNDED; OPEN_BALL]; + REWRITE_TAC[UNIONS_SUBSET] THEN STRIP_TAC] THEN + MP_TAC(ISPEC `k:real^N->bool` COMPACT_IMP_HEINE_BOREL) THEN + ASM_SIMP_TAC[] THEN DISCH_THEN(MP_TAC o SPEC + `(u UNION v:real^N->bool) INSERT {n DIFF s | s IN f}`) THEN + REWRITE_TAC[SIMPLE_IMAGE; FORALL_IN_INSERT; FORALL_IN_IMAGE] THEN + ASM_SIMP_TAC[OPEN_UNION; OPEN_DIFF; COMPACT_IMP_CLOSED; NOT_IMP] THEN + CONJ_TAC THENL + [REWRITE_TAC[UNIONS_INSERT] THEN REWRITE_TAC[SUBSET] THEN + X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN ONCE_REWRITE_TAC[IN_UNION] THEN + ASM_CASES_TAC `(x:real^N) IN c` THENL [ASM SET_TAC[]; DISJ2_TAC] THEN + REWRITE_TAC[UNIONS_IMAGE; IN_ELIM_THM] THEN + UNDISCH_TAC `~((x:real^N) IN c)` THEN + SUBST1_TAC(SYM(ASSUME `INTERS f:real^N->bool = c`)) THEN + REWRITE_TAC[IN_INTERS; NOT_FORALL_THM] THEN + MATCH_MP_TAC MONO_EXISTS THEN ASM SET_TAC[]; + ALL_TAC] THEN + DISCH_THEN(X_CHOOSE_THEN `g:(real^N->bool)->bool` MP_TAC) THEN + DISCH_THEN(CONJUNCTS_THEN2 MP_TAC STRIP_ASSUME_TAC) THEN + REWRITE_TAC[SUBSET_INSERT_DELETE] THEN + SUBGOAL_THEN `FINITE(g DELETE (u UNION v:real^N->bool))` MP_TAC THENL + [ASM_REWRITE_TAC[FINITE_DELETE]; + REWRITE_TAC[TAUT `p ==> ~q <=> ~(p /\ q)`]] THEN + REWRITE_TAC[FINITE_SUBSET_IMAGE] THEN + DISCH_THEN(X_CHOOSE_THEN `f':(real^N->bool)->bool` STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN + `?j:real^N->bool. j IN f /\ + UNIONS(IMAGE (\s. n DIFF s) f') SUBSET (n DIFF j)` + STRIP_ASSUME_TAC THENL + [ASM_CASES_TAC `f':(real^N->bool)->bool = {}` THEN + ASM_REWRITE_TAC[IMAGE_CLAUSES; UNIONS_0; EMPTY_SUBSET] THENL + [ASM SET_TAC[]; ALL_TAC] THEN + SUBGOAL_THEN + `?j:real^N->bool. j IN f' /\ + UNIONS(IMAGE (\s. n DIFF s) f') SUBSET (n DIFF j)` + MP_TAC THENL [ALL_TAC; ASM_MESON_TAC[SUBSET]] THEN + SUBGOAL_THEN + `!s t:real^N->bool. s IN f' /\ t IN f' ==> s SUBSET t \/ t SUBSET s` + MP_TAC THENL [ASM_MESON_TAC[SUBSET]; ALL_TAC] THEN + UNDISCH_TAC `~(f':(real^N->bool)->bool = {})` THEN + UNDISCH_TAC `FINITE(f':(real^N->bool)->bool)` THEN + SPEC_TAC(`f':(real^N->bool)->bool`,`f':(real^N->bool)->bool`) THEN + MATCH_MP_TAC FINITE_INDUCT_STRONG THEN REWRITE_TAC[] THEN + REWRITE_TAC[EXISTS_IN_INSERT; IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN + REWRITE_TAC[FORALL_IN_INSERT] THEN POP_ASSUM_LIST(K ALL_TAC) THEN + MAP_EVERY X_GEN_TAC [`i:real^N->bool`; `f:(real^N->bool)->bool`] THEN + ASM_CASES_TAC `f:(real^N->bool)->bool = {}` THEN + ASM_REWRITE_TAC[IMAGE_CLAUSES; UNIONS_INSERT; NOT_IN_EMPTY; + UNIONS_0; UNION_EMPTY; SUBSET_REFL] THEN + DISCH_THEN(fun th -> REPEAT DISCH_TAC THEN MP_TAC th) THEN + ANTS_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN + DISCH_THEN(X_CHOOSE_THEN `j:real^N->bool` STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN `(n DIFF j) SUBSET (n DIFF i) \/ + (n DIFF i:real^N->bool) SUBSET (n DIFF j)` + STRIP_ASSUME_TAC THENL + [FIRST_X_ASSUM(MP_TAC o SPEC `j:real^N->bool` o CONJUNCT2) THEN + ASM SET_TAC[]; + DISJ1_TAC THEN ASM SET_TAC[]; + DISJ2_TAC THEN EXISTS_TAC `j:real^N->bool` THEN ASM SET_TAC[]]; + ALL_TAC] THEN + SUBGOAL_THEN `(j INTER k:real^N->bool) SUBSET (u UNION v)` ASSUME_TAC THENL + [MATCH_MP_TAC(SET_RULE + `k SUBSET (u UNION v) UNION (n DIFF j) + ==> (j INTER k) SUBSET (u UNION v)`) THEN + MATCH_MP_TAC SUBSET_TRANS THEN + EXISTS_TAC `UNIONS g :real^N->bool` THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC SUBSET_TRANS THEN EXISTS_TAC + `UNIONS((u UNION v:real^N->bool) INSERT (g DELETE (u UNION v)))` THEN + CONJ_TAC THENL [MATCH_MP_TAC SUBSET_UNIONS THEN SET_TAC[]; ALL_TAC] THEN + ASM_REWRITE_TAC[] THEN ONCE_REWRITE_TAC[UNIONS_INSERT] THEN + ASM SET_TAC[]; + ALL_TAC] THEN + SUBGOAL_THEN `connected(j INTER k:real^N->bool)` MP_TAC THENL + [ASM_MESON_TAC[SET_RULE `s SUBSET t ==> s INTER t = s`; INTER_COMM]; + REWRITE_TAC[connected] THEN + MAP_EVERY EXISTS_TAC [`u:real^N->bool`; `v:real^N->bool`] THEN + ASM_REWRITE_TAC[] THEN ASM SET_TAC[]]);; + +let CONNECTED_CHAIN_GEN = prove + (`!f:(real^N->bool)->bool. + (!s. s IN f ==> closed s /\ connected s) /\ + (?s. s IN f /\ compact s) /\ + (!s t. s IN f /\ t IN f ==> s SUBSET t \/ t SUBSET s) + ==> connected(INTERS f)`, + GEN_TAC THEN DISCH_THEN(REPEAT_TCL CONJUNCTS_THEN ASSUME_TAC) THEN + FIRST_X_ASSUM(X_CHOOSE_THEN `s:real^N->bool` STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN + `INTERS f = INTERS(IMAGE (\t:real^N->bool. s INTER t) f)` + SUBST1_TAC THENL + [REWRITE_TAC[EXTENSION; INTERS_IMAGE] THEN ASM SET_TAC[]; + MATCH_MP_TAC CONNECTED_CHAIN THEN + REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_IMAGE] THEN + ASM_SIMP_TAC[COMPACT_INTER_CLOSED] THEN + CONJ_TAC THENL [X_GEN_TAC `t:real^N->bool`; ASM SET_TAC[]] THEN + DISCH_TAC THEN + SUBGOAL_THEN `s INTER t:real^N->bool = s \/ s INTER t = t` + (DISJ_CASES_THEN SUBST1_TAC) THEN + ASM SET_TAC[]]);; + +let CONNECTED_NEST = prove + (`!s. (!n. compact(s n) /\ connected(s n)) /\ + (!m n. m <= n ==> s n SUBSET s m) + ==> connected(INTERS {s n | n IN (:num)})`, + GEN_TAC THEN STRIP_TAC THEN MATCH_MP_TAC CONNECTED_CHAIN THEN + ASM_SIMP_TAC[FORALL_IN_GSPEC; IN_UNIV; IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN + MATCH_MP_TAC WLOG_LE THEN ASM_MESON_TAC[]);; + +let CONNECTED_NEST_GEN = prove + (`!s. (!n. closed(s n) /\ connected(s n)) /\ (?n. compact(s n)) /\ + (!m n. m <= n ==> s n SUBSET s m) + ==> connected(INTERS {s n | n IN (:num)})`, + GEN_TAC THEN + DISCH_THEN(REPEAT_TCL DISJ_CASES_THEN ASSUME_TAC) THEN + MATCH_MP_TAC CONNECTED_CHAIN_GEN THEN + ASM_SIMP_TAC[FORALL_IN_GSPEC; IN_UNIV; IMP_CONJ; RIGHT_FORALL_IMP_THM; + EXISTS_IN_GSPEC] THEN + MATCH_MP_TAC WLOG_LE THEN ASM_MESON_TAC[]);; + +let EQ_BALLS = prove + (`(!a a':real^N r r'. + ball(a,r) = ball(a',r') <=> a = a' /\ r = r' \/ r <= &0 /\ r' <= &0) /\ + (!a a':real^N r r'. + ball(a,r) = cball(a',r') <=> r <= &0 /\ r' < &0) /\ + (!a a':real^N r r'. + cball(a,r) = ball(a',r') <=> r < &0 /\ r' <= &0) /\ + (!a a':real^N r r'. + cball(a,r) = cball(a',r') <=> a = a' /\ r = r' \/ r < &0 /\ r' < &0)`, + REWRITE_TAC[AND_FORALL_THM] THEN REPEAT STRIP_TAC THEN + (EQ_TAC THENL + [ALL_TAC; REWRITE_TAC[EXTENSION; IN_BALL; IN_CBALL] THEN NORM_ARITH_TAC]) + THENL + [REWRITE_TAC[GSYM SUBSET_ANTISYM_EQ; SUBSET_BALLS] THEN NORM_ARITH_TAC; + ONCE_REWRITE_TAC[EQ_SYM_EQ]; + ALL_TAC; + REWRITE_TAC[GSYM SUBSET_ANTISYM_EQ; SUBSET_BALLS] THEN NORM_ARITH_TAC] THEN + DISCH_THEN(MP_TAC o MATCH_MP (MESON[CLOPEN; BOUNDED_BALL; NOT_BOUNDED_UNIV] + `s = t ==> closed s /\ open t /\ bounded t ==> s = {} /\ t = {}`)) THEN + REWRITE_TAC[OPEN_BALL; CLOSED_CBALL; BOUNDED_BALL; + BALL_EQ_EMPTY; CBALL_EQ_EMPTY] THEN + REAL_ARITH_TAC);; + +let FINITE_CBALL = prove + (`!a:real^N r. FINITE(cball(a,r)) <=> r <= &0`, + REPEAT STRIP_TAC THEN ASM_CASES_TAC `r < &0` THEN + ASM_SIMP_TAC[CBALL_EMPTY; REAL_LT_IMP_LE; FINITE_EMPTY] THEN + ASM_CASES_TAC `r = &0` THEN + ASM_REWRITE_TAC[CBALL_TRIVIAL; FINITE_SING; REAL_LE_REFL] THEN + EQ_TAC THENL [ALL_TAC; ASM_REAL_ARITH_TAC] THEN + DISCH_THEN(MP_TAC o MATCH_MP EMPTY_INTERIOR_FINITE) THEN + REWRITE_TAC[INTERIOR_CBALL; BALL_EQ_EMPTY] THEN ASM_REAL_ARITH_TAC);; + +let FINITE_BALL = prove + (`!a:real^N r. FINITE(ball(a,r)) <=> r <= &0`, + REPEAT STRIP_TAC THEN ASM_CASES_TAC `r <= &0` THEN + ASM_SIMP_TAC[BALL_EMPTY; REAL_LT_IMP_LE; FINITE_EMPTY] THEN + DISCH_THEN(MP_TAC o MATCH_MP (ONCE_REWRITE_RULE[IMP_CONJ] + FINITE_IMP_NOT_OPEN)) THEN + REWRITE_TAC[OPEN_BALL; BALL_EQ_EMPTY] THEN ASM_REAL_ARITH_TAC);; + +(* ------------------------------------------------------------------------- *) +(* Convex functions into the reals. *) +(* ------------------------------------------------------------------------- *) + +parse_as_infix ("convex_on",(12,"right"));; + +let convex_on = new_definition + `f convex_on s <=> + !x y u v. x IN s /\ y IN s /\ &0 <= u /\ &0 <= v /\ (u + v = &1) + ==> f(u % x + v % y) <= u * f(x) + v * f(y)`;; + +let CONVEX_ON_SUBSET = prove + (`!f s t. f convex_on t /\ s SUBSET t ==> f convex_on s`, + REWRITE_TAC[convex_on; SUBSET] THEN MESON_TAC[]);; + +let CONVEX_ADD = prove + (`!s f g. f convex_on s /\ g convex_on s ==> (\x. f(x) + g(x)) convex_on s`, + REWRITE_TAC[convex_on; AND_FORALL_THM] THEN + REPEAT(MATCH_MP_TAC MONO_FORALL ORELSE GEN_TAC) THEN + MATCH_MP_TAC(TAUT + `(b /\ c ==> d) ==> (a ==> b) /\ (a ==> c) ==> a ==> d`) THEN + REAL_ARITH_TAC);; + +let CONVEX_CMUL = prove + (`!s c f. &0 <= c /\ f convex_on s ==> (\x. c * f(x)) convex_on s`, + SIMP_TAC[convex_on; REAL_LE_LMUL; + REAL_ARITH `u * c * fx + v * c * fy = c * (u * fx + v * fy)`]);; + +let CONVEX_MAX = prove + (`!f g s. f convex_on s /\ g convex_on s + ==> (\x. max (f x) (g x)) convex_on s`, + REWRITE_TAC[convex_on; REAL_MAX_LE] THEN REPEAT STRIP_TAC THEN + FIRST_X_ASSUM(fun th -> + W(MP_TAC o PART_MATCH (lhand o rand) th o lhand o snd)) THEN + ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] REAL_LE_TRANS) THEN + MATCH_MP_TAC REAL_LE_ADD2 THEN CONJ_TAC THEN + MATCH_MP_TAC REAL_LE_LMUL THEN ASM_REAL_ARITH_TAC);; + +let CONVEX_LOWER = prove + (`!f s x y. f convex_on s /\ + x IN s /\ y IN s /\ &0 <= u /\ &0 <= v /\ (u + v = &1) + ==> f(u % x + v % y) <= max (f(x)) (f(y))`, + REWRITE_TAC[convex_on] THEN REPEAT STRIP_TAC THEN + GEN_REWRITE_TAC RAND_CONV [GSYM REAL_MUL_LID] THEN + FIRST_ASSUM(fun th -> GEN_REWRITE_TAC (RAND_CONV o LAND_CONV) [SYM th]) THEN + REWRITE_TAC[REAL_ADD_RDISTRIB] THEN MATCH_MP_TAC REAL_LE_TRANS THEN + ASM_MESON_TAC[REAL_LE_ADD2; REAL_LE_LMUL; REAL_MAX_MAX]);; + +let CONVEX_LOWER_SEGMENT = prove + (`!f s a b x:real^N. + f convex_on s /\ a IN s /\ b IN s /\ x IN segment[a,b] + ==> f(x) <= max (f a) (f b)`, + REWRITE_TAC[IN_SEGMENT] THEN REPEAT STRIP_TAC THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC CONVEX_LOWER THEN + EXISTS_TAC `s:real^N->bool` THEN ASM_REWRITE_TAC[] THEN ASM_REAL_ARITH_TAC);; + +let CONVEX_LOCAL_GLOBAL_MINIMUM = prove + (`!f s t x:real^N. + f convex_on s /\ x IN t /\ open t /\ t SUBSET s /\ + (!y. y IN t ==> f(x) <= f(y)) + ==> !y. y IN s ==> f(x) <= f(y)`, + REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM REAL_NOT_LT] THEN DISCH_TAC THEN + SUBGOAL_THEN `&0 < dist(x:real^N,y)` ASSUME_TAC THENL + [ASM_MESON_TAC[DIST_POS_LT; REAL_LT_REFL]; ALL_TAC] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [OPEN_CONTAINS_BALL]) THEN + DISCH_THEN(MP_TAC o SPEC `x:real^N`) THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `e:real` STRIP_ASSUME_TAC) THEN + MP_TAC(SPECL [`&1`; `e / dist(x:real^N,y)`] REAL_DOWN2) THEN + ANTS_TAC THENL [ASM_SIMP_TAC[REAL_LT_DIV; REAL_LT_01]; ALL_TAC] THEN + DISCH_THEN(X_CHOOSE_THEN `u:real` STRIP_ASSUME_TAC) THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [convex_on]) THEN + DISCH_THEN(MP_TAC o + SPECL [`x:real^N`; `y:real^N`; `&1 - u`; `u:real`]) THEN + ANTS_TAC THENL + [ASM_SIMP_TAC[REAL_SUB_ADD; REAL_SUB_LE; REAL_LT_IMP_LE] THEN + ASM_MESON_TAC[CENTRE_IN_BALL; SUBSET]; + ALL_TAC] THEN + REWRITE_TAC[REAL_NOT_LE] THEN MATCH_MP_TAC REAL_LTE_TRANS THEN + EXISTS_TAC `(&1 - u) * f(x) + u * f(x:real^N):real` THEN + ASM_SIMP_TAC[REAL_LT_LADD; REAL_LT_LMUL] THEN + REWRITE_TAC[REAL_ARITH `(&1 - x) * a + x * a = a`] THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN + FIRST_X_ASSUM(MATCH_MP_TAC o GEN_REWRITE_RULE I [SUBSET]) THEN + REWRITE_TAC[IN_BALL; dist] THEN + REWRITE_TAC[VECTOR_ARITH `x - ((&1 - u) % x + u % y):real^N = + u % (x - y)`] THEN + REWRITE_TAC[NORM_MUL; GSYM dist] THEN + ASM_SIMP_TAC[GSYM REAL_LT_RDIV_EQ; + REAL_ARITH `&0 < x /\ x < b ==> abs x < b`]);; + +let CONVEX_DISTANCE = prove + (`!s a. (\x. dist(a,x)) convex_on s`, + REWRITE_TAC[convex_on; dist] THEN REPEAT STRIP_TAC THEN + GEN_REWRITE_TAC (LAND_CONV o RAND_CONV o LAND_CONV) + [GSYM VECTOR_MUL_LID] THEN + FIRST_ASSUM(SUBST1_TAC o SYM) THEN + REWRITE_TAC[VECTOR_ARITH + `(u + v) % z - (u % x + v % y) = u % (z - x) + v % (z - y)`] THEN + ASM_MESON_TAC[NORM_TRIANGLE; NORM_MUL; REAL_ABS_REFL]);; + +let CONVEX_NORM = prove + (`!s:real^N->bool. norm convex_on s`, + GEN_TAC THEN + MP_TAC(ISPECL [`s:real^N->bool`; `vec 0:real^N`] CONVEX_DISTANCE) THEN + REWRITE_TAC[DIST_0; ETA_AX]);; + +let CONVEX_ON_COMPOSE_LINEAR = prove + (`!f g:real^M->real^N s. + f convex_on (IMAGE g s) /\ linear g ==> (f o g) convex_on s`, + REWRITE_TAC[convex_on; IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN + REWRITE_TAC[FORALL_IN_IMAGE; o_THM] THEN + REWRITE_TAC[RIGHT_IMP_FORALL_THM; IMP_IMP; GSYM CONJ_ASSOC] THEN + REPEAT STRIP_TAC THEN + FIRST_ASSUM(fun th -> REWRITE_TAC[MATCH_MP LINEAR_ADD th]) THEN + FIRST_ASSUM(fun th -> REWRITE_TAC[MATCH_MP LINEAR_CMUL th]) THEN + ASM_SIMP_TAC[]);; + +let CONVEX_ON_TRANSLATION = prove + (`!f a:real^N. + f convex_on (IMAGE (\x. a + x) s) <=> (\x. f(a + x)) convex_on s`, + REWRITE_TAC[convex_on; IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN + REWRITE_TAC[FORALL_IN_IMAGE; o_THM] THEN + REWRITE_TAC[VECTOR_ARITH + `u % (a + x) + v % (a + y):real^N = (u + v) % a + u % x + v % y`] THEN + SIMP_TAC[VECTOR_MUL_LID]);; + +(* ------------------------------------------------------------------------- *) +(* Open and closed balls are convex and hence connected. *) +(* ------------------------------------------------------------------------- *) + +let CONVEX_BALL = prove + (`!x:real^N e. convex(ball(x,e))`, + let lemma = REWRITE_RULE[convex_on; IN_UNIV] + (ISPEC `(:real^N)` CONVEX_DISTANCE) in + REWRITE_TAC[convex; IN_BALL] THEN REPEAT STRIP_TAC THEN + W(MP_TAC o PART_MATCH (lhand o rand) lemma o lhand o snd) THEN + ASM_MESON_TAC[REAL_LET_TRANS; REAL_CONVEX_BOUND_LT]);; + +let CONNECTED_BALL = prove + (`!x:real^N e. connected(ball(x,e))`, + SIMP_TAC[CONVEX_CONNECTED; CONVEX_BALL]);; + +let CONVEX_CBALL = prove + (`!x:real^N e. convex(cball(x,e))`, + REWRITE_TAC[convex; IN_CBALL; dist] THEN MAP_EVERY X_GEN_TAC + [`x:real^N`; `e:real`; `y:real^N`; `z:real^N`; `u:real`; `v:real`] THEN + STRIP_TAC THEN ONCE_REWRITE_TAC[VECTOR_ARITH `a - b = &1 % a - b`] THEN + FIRST_ASSUM(SUBST1_TAC o SYM) THEN + REWRITE_TAC[VECTOR_ARITH + `(a + b) % x - (a % y + b % z) = a % (x - y) + b % (x - z)`] THEN + MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `norm(u % (x - y)) + norm(v % (x - z):real^N)` THEN + REWRITE_TAC[NORM_TRIANGLE; NORM_MUL] THEN + MATCH_MP_TAC REAL_CONVEX_BOUND_LE THEN ASM_REWRITE_TAC[REAL_ABS_POS] THEN + ASM_SIMP_TAC[REAL_ARITH + `&0 <= u /\ &0 <= v /\ (u + v = &1) ==> (abs(u) + abs(v) = &1)`]);; + +let CONNECTED_CBALL = prove + (`!x:real^N e. connected(cball(x,e))`, + SIMP_TAC[CONVEX_CONNECTED; CONVEX_CBALL]);; + +let FRONTIER_OF_CONNECTED_COMPONENT_SUBSET = prove + (`!s c x:real^N. frontier(connected_component s x) SUBSET frontier s`, + REPEAT GEN_TAC THEN REWRITE_TAC[frontier; SUBSET; IN_DIFF] THEN + X_GEN_TAC `y:real^N` THEN REPEAT STRIP_TAC THENL + [FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE + `y IN s ==> s SUBSET t ==> y IN t`)) THEN + MATCH_MP_TAC SUBSET_CLOSURE THEN REWRITE_TAC[CONNECTED_COMPONENT_SUBSET]; + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_INTERIOR]) THEN + DISCH_THEN(X_CHOOSE_THEN `e:real` STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN `ball(y:real^N,e) SUBSET connected_component s y` + ASSUME_TAC THENL + [MATCH_MP_TAC CONNECTED_COMPONENT_MAXIMAL THEN + ASM_REWRITE_TAC[CONNECTED_BALL; CENTRE_IN_BALL]; + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [CLOSURE_APPROACHABLE]) THEN + DISCH_THEN(MP_TAC o SPEC `e:real`) THEN + ASM_REWRITE_TAC[ONCE_REWRITE_RULE[DIST_SYM] (GSYM IN_BALL)] THEN + STRIP_TAC THEN FIRST_X_ASSUM(MP_TAC o check (is_neg o concl)) THEN + REWRITE_TAC[IN_INTERIOR] THEN EXISTS_TAC `e:real` THEN + MP_TAC(ISPECL [`s:real^N->bool`; `x:real^N`; `y:real^N`] + CONNECTED_COMPONENT_OVERLAP) THEN + MATCH_MP_TAC(TAUT `p /\ (q ==> r) ==> (p <=> q) ==> r`) THEN + ASM_SIMP_TAC[] THEN ASM SET_TAC[]]]);; + +let FRONTIER_OF_COMPONENTS_SUBSET = prove + (`!s c:real^N->bool. + c IN components s ==> frontier c SUBSET frontier s`, + SIMP_TAC[components; FORALL_IN_GSPEC; + FRONTIER_OF_CONNECTED_COMPONENT_SUBSET]);; + +let FRONTIER_OF_COMPONENTS_CLOSED_COMPLEMENT = prove + (`!s c. closed s /\ c IN components ((:real^N) DIFF s) + ==> frontier c SUBSET s`, + REPEAT STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o MATCH_MP FRONTIER_OF_COMPONENTS_SUBSET) THEN + REWRITE_TAC[FRONTIER_COMPLEMENT] THEN + ASM_MESON_TAC[FRONTIER_SUBSET_EQ; SUBSET_TRANS]);; + +(* ------------------------------------------------------------------------- *) +(* A couple of lemmas about components (see Newman IV, 3.3 and 3.4). *) +(* ------------------------------------------------------------------------- *) + +let CONNECTED_UNION_CLOPEN_IN_COMPLEMENT = prove + (`!s t u:real^N->bool. + connected s /\ connected u /\ s SUBSET u /\ + open_in (subtopology euclidean (u DIFF s)) t /\ + closed_in (subtopology euclidean (u DIFF s)) t + ==> connected (s UNION t)`, + MAP_EVERY X_GEN_TAC + [`c:real^N->bool`; `h:real^N->bool`; `s:real^N->bool`] THEN + STRIP_TAC THEN + REWRITE_TAC[CONNECTED_CLOSED_IN_EQ; NOT_EXISTS_THM] THEN + MATCH_MP_TAC(MESON[] + `!Q. (!x y. P x y <=> P y x) /\ + (!x y. P x y ==> Q x \/ Q y) /\ + (!x y. P x y /\ Q x ==> F) + ==> (!x y. ~(P x y))`) THEN + EXISTS_TAC `\x:real^N->bool. c SUBSET x` THEN + CONJ_TAC THENL [MESON_TAC[INTER_COMM; UNION_COMM]; ALL_TAC] THEN + REWRITE_TAC[] THEN CONJ_TAC THEN + MAP_EVERY X_GEN_TAC [`h1:real^N->bool`; `h2:real^N->bool`] THENL + [STRIP_TAC THEN UNDISCH_TAC `connected(c:real^N->bool)` THEN + REWRITE_TAC[CONNECTED_CLOSED_IN; NOT_EXISTS_THM] THEN + DISCH_THEN(MP_TAC o + SPECL [`c INTER h1:real^N->bool`; `c INTER h2:real^N->bool`]) THEN + MATCH_MP_TAC(TAUT + `(p /\ q) /\ (~r ==> s) ==> ~(p /\ q /\ r) ==> s`) THEN + CONJ_TAC THENL [ALL_TAC; ASM SET_TAC[]] THEN CONJ_TAC THENL + [UNDISCH_TAC + `closed_in(subtopology euclidean (c UNION h)) (h1:real^N->bool)`; + UNDISCH_TAC + `closed_in(subtopology euclidean (c UNION h)) (h2:real^N->bool)`] THEN + REWRITE_TAC[CLOSED_IN_CLOSED] THEN MATCH_MP_TAC MONO_EXISTS THEN + ASM SET_TAC[]; + STRIP_TAC THEN + FIRST_ASSUM(ASSUME_TAC o CONJUNCT1 o GEN_REWRITE_RULE I [open_in]) THEN + SUBGOAL_THEN `(h2:real^N->bool) SUBSET h` ASSUME_TAC THENL + [ASM SET_TAC[]; ALL_TAC] THEN + UNDISCH_TAC `connected(s:real^N->bool)` THEN + REWRITE_TAC[CONNECTED_CLOPEN] THEN + DISCH_THEN(MP_TAC o SPEC `h2:real^N->bool`) THEN REWRITE_TAC[NOT_IMP] THEN + CONJ_TAC THENL [ALL_TAC; ASM SET_TAC[]] THEN + SUBGOAL_THEN `s:real^N->bool = (s DIFF c) UNION (c UNION h)` + SUBST1_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN CONJ_TAC THENL + [MATCH_MP_TAC OPEN_IN_SUBTOPOLOGY_UNION THEN + MATCH_MP_TAC(TAUT `q /\ (q ==> p) ==> p /\ q`) THEN CONJ_TAC THENL + [REWRITE_TAC[OPEN_IN_CLOSED_IN_EQ; TOPSPACE_EUCLIDEAN_SUBTOPOLOGY] THEN + CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + SUBGOAL_THEN `(c UNION h) DIFF h2:real^N->bool = h1` + (fun th -> ASM_REWRITE_TAC[th]) THEN ASM SET_TAC[]; + DISCH_TAC THEN MATCH_MP_TAC OPEN_IN_TRANS THEN + EXISTS_TAC `h:real^N->bool` THEN ASM_REWRITE_TAC[] THEN + UNDISCH_TAC + `open_in(subtopology euclidean (c UNION h)) (h2:real^N->bool)` THEN + REWRITE_TAC[OPEN_IN_OPEN] THEN MATCH_MP_TAC MONO_EXISTS THEN + ASM SET_TAC[]]; + MATCH_MP_TAC CLOSED_IN_SUBTOPOLOGY_UNION THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC CLOSED_IN_TRANS THEN EXISTS_TAC `h:real^N->bool` THEN + ASM_REWRITE_TAC[] THEN + UNDISCH_TAC + `closed_in(subtopology euclidean (c UNION h)) (h2:real^N->bool)` THEN + REWRITE_TAC[CLOSED_IN_CLOSED] THEN MATCH_MP_TAC MONO_EXISTS THEN + ASM SET_TAC[]]]);; + +let COMPONENT_COMPLEMENT_CONNECTED = prove + (`!s u c:real^N->bool. + connected s /\ connected u /\ s SUBSET u /\ c IN components (u DIFF s) + ==> connected(u DIFF c)`, + MAP_EVERY X_GEN_TAC + [`a:real^N->bool`; `s:real^N->bool`; `c:real^N->bool`] THEN + STRIP_TAC THEN UNDISCH_TAC `connected(a:real^N->bool)` THEN + REWRITE_TAC[CONNECTED_CLOSED_IN_EQ; NOT_EXISTS_THM] THEN + DISCH_TAC THEN MAP_EVERY X_GEN_TAC + [`h3:real^N->bool`; `h4:real^N->bool`] THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPECL + [`a INTER h3:real^N->bool`; `a INTER h4:real^N->bool`]) THEN + FIRST_ASSUM(MP_TAC o MATCH_MP IN_COMPONENTS_NONEMPTY) THEN + FIRST_ASSUM(MP_TAC o MATCH_MP IN_COMPONENTS_SUBSET) THEN + EVERY_ASSUM(fun th -> try + MP_TAC(CONJUNCT1(GEN_REWRITE_RULE I [closed_in] th)) + with Failure _ -> ALL_TAC) THEN + REWRITE_TAC[TOPSPACE_EUCLIDEAN_SUBTOPOLOGY] THEN REPEAT DISCH_TAC THEN + REPEAT CONJ_TAC THENL + [UNDISCH_TAC `closed_in (subtopology euclidean (s DIFF c)) + (h3:real^N->bool)` THEN + REWRITE_TAC[CLOSED_IN_CLOSED] THEN MATCH_MP_TAC MONO_EXISTS THEN + ASM SET_TAC[]; + UNDISCH_TAC `closed_in (subtopology euclidean (s DIFF c)) + (h4:real^N->bool)` THEN + REWRITE_TAC[CLOSED_IN_CLOSED] THEN MATCH_MP_TAC MONO_EXISTS THEN + ASM SET_TAC[]; + ASM SET_TAC[]; + ASM SET_TAC[]; + DISCH_TAC THEN + MP_TAC(ISPECL [`s DIFF a:real^N->bool`; `c UNION h3:real^N->bool`; + `c:real^N->bool`] COMPONENTS_MAXIMAL) THEN + ASM_REWRITE_TAC[NOT_IMP; GSYM CONJ_ASSOC] THEN + CONJ_TAC THENL [ALL_TAC; ASM SET_TAC[]] THEN + MATCH_MP_TAC CONNECTED_UNION_CLOPEN_IN_COMPLEMENT THEN + EXISTS_TAC `s:real^N->bool` THEN ASM_REWRITE_TAC[] THEN + REPEAT CONJ_TAC THENL + [ASM_MESON_TAC[IN_COMPONENTS_CONNECTED]; + ASM SET_TAC[]; + REWRITE_TAC[OPEN_IN_CLOSED_IN_EQ; TOPSPACE_EUCLIDEAN_SUBTOPOLOGY] THEN + CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + SUBGOAL_THEN `s DIFF c DIFF h3:real^N->bool = h4` SUBST1_TAC THEN + ASM SET_TAC[]]; + DISCH_TAC THEN + MP_TAC(ISPECL [`s DIFF a:real^N->bool`; `c UNION h4:real^N->bool`; + `c:real^N->bool`] COMPONENTS_MAXIMAL) THEN + ASM_REWRITE_TAC[NOT_IMP; GSYM CONJ_ASSOC] THEN + CONJ_TAC THENL [ALL_TAC; ASM SET_TAC[]] THEN + MATCH_MP_TAC CONNECTED_UNION_CLOPEN_IN_COMPLEMENT THEN + EXISTS_TAC `s:real^N->bool` THEN ASM_REWRITE_TAC[] THEN + REPEAT CONJ_TAC THENL + [ASM_MESON_TAC[IN_COMPONENTS_CONNECTED]; + ASM SET_TAC[]; + REWRITE_TAC[OPEN_IN_CLOSED_IN_EQ; TOPSPACE_EUCLIDEAN_SUBTOPOLOGY] THEN + CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + SUBGOAL_THEN `s DIFF c DIFF h4:real^N->bool = h3` SUBST1_TAC THEN + ASM SET_TAC[]]]);; + +(* ------------------------------------------------------------------------- *) +(* Sura-Bura's result about components of closed sets. *) +(* ------------------------------------------------------------------------- *) + +let SURA_BURA_COMPACT = prove + (`!s c:real^N->bool. + compact s /\ c IN components s + ==> c = INTERS {t | c SUBSET t /\ + open_in (subtopology euclidean s) t /\ + closed_in (subtopology euclidean s) t}`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN + CONJ_TAC THENL [SET_TAC[]; ALL_TAC] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE RAND_CONV [components]) THEN + REWRITE_TAC[IN_ELIM_THM] THEN + DISCH_THEN(X_CHOOSE_THEN `x:real^N` (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + DISCH_THEN(fun th -> SUBST1_TAC th THEN ASSUME_TAC(SYM th)) THEN + MATCH_MP_TAC CONNECTED_COMPONENT_MAXIMAL THEN + SUBGOAL_THEN `(x:real^N) IN c` ASSUME_TAC THENL + [ASM_MESON_TAC[CONNECTED_COMPONENT_REFL; IN]; ALL_TAC] THEN + SUBGOAL_THEN `(c:real^N->bool) SUBSET s` ASSUME_TAC THENL + [ASM_MESON_TAC[CONNECTED_COMPONENT_SUBSET]; ALL_TAC] THEN + CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN CONJ_TAC THENL + [ASM_REWRITE_TAC[]; + MATCH_MP_TAC(SET_RULE `s IN t ==> INTERS t SUBSET s`) THEN + REWRITE_TAC[IN_ELIM_THM; CONNECTED_COMPONENT_SUBSET; + OPEN_IN_SUBTOPOLOGY_REFL; CLOSED_IN_SUBTOPOLOGY_REFL] THEN + REWRITE_TAC[TOPSPACE_EUCLIDEAN; SUBSET_UNIV]] THEN + W(fun (asl,w) -> ABBREV_TAC(mk_eq(`k:real^N->bool`,rand w))) THEN + SUBGOAL_THEN `closed(k:real^N->bool)` ASSUME_TAC THENL + [EXPAND_TAC "k" THEN MATCH_MP_TAC CLOSED_INTERS THEN + REWRITE_TAC[IN_ELIM_THM] THEN + ASM_MESON_TAC[CLOSED_IN_CLOSED_TRANS; COMPACT_IMP_CLOSED]; + ALL_TAC] THEN + REWRITE_TAC[CONNECTED_CLOSED_IN_EQ; NOT_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`k1:real^N->bool`; `k2:real^N->bool`] THEN + STRIP_TAC THEN + MP_TAC(ISPECL [`k1:real^N->bool`; `k2:real^N->bool`] SEPARATION_NORMAL) THEN + ASM_REWRITE_TAC[NOT_EXISTS_THM; NOT_IMP] THEN CONJ_TAC THENL + [ASM_MESON_TAC[CLOSED_IN_CLOSED_TRANS; COMPACT_IMP_CLOSED]; ALL_TAC] THEN + MAP_EVERY X_GEN_TAC [`v1:real^N->bool`; `v2:real^N->bool`] THEN + STRIP_TAC THEN + MP_TAC(ISPECL [`s DIFF (v1 UNION v2):real^N->bool`; + `{t:real^N->bool | connected_component s x SUBSET t /\ + open_in (subtopology euclidean s) t /\ + closed_in (subtopology euclidean s) t}`] + COMPACT_IMP_FIP) THEN + ASM_SIMP_TAC[NOT_IMP; COMPACT_DIFF; OPEN_UNION; IN_ELIM_THM] THEN + REPEAT CONJ_TAC THENL + [ASM_MESON_TAC[CLOSED_IN_CLOSED_TRANS; COMPACT_IMP_CLOSED]; + ONCE_REWRITE_TAC[SUBSET] THEN REWRITE_TAC[IN_ELIM_THM]; + ASM SET_TAC[]] THEN + X_GEN_TAC `f:(real^N->bool)->bool` THEN REPEAT STRIP_TAC THEN + SUBGOAL_THEN + `?c0:real^N->bool. + c SUBSET c0 /\ c0 SUBSET (v1 UNION v2) /\ + open_in (subtopology euclidean s) c0 /\ + closed_in (subtopology euclidean s) c0` + STRIP_ASSUME_TAC THENL + [ASM_CASES_TAC `f:(real^N->bool)->bool = {}` THENL + [EXISTS_TAC `s:real^N->bool` THEN + ASM_REWRITE_TAC[TOPSPACE_EUCLIDEAN; SUBSET_UNIV; + OPEN_IN_SUBTOPOLOGY_REFL; CLOSED_IN_SUBTOPOLOGY_REFL] THEN + UNDISCH_TAC + `(s DIFF (v1 UNION v2)) INTER INTERS f :real^N->bool = {}` THEN + ASM_REWRITE_TAC[INTERS_0; INTER_UNIV] THEN SET_TAC[]; + EXISTS_TAC `INTERS f :real^N->bool` THEN REPEAT CONJ_TAC THENL + [ASM SET_TAC[]; + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE + `(s DIFF u) INTER t = {} + ==> t SUBSET s + ==> t SUBSET u`)) THEN + MATCH_MP_TAC(SET_RULE + `~(f = {}) /\ (!s. s IN f ==> s SUBSET t) ==> INTERS f SUBSET t`) THEN + ASM_MESON_TAC[CLOSED_IN_SUBSET; TOPSPACE_EUCLIDEAN_SUBTOPOLOGY]; + MATCH_MP_TAC OPEN_IN_INTERS THEN ASM_SIMP_TAC[]; + MATCH_MP_TAC CLOSED_IN_INTERS THEN ASM_SIMP_TAC[]]]; + ALL_TAC] THEN + SUBGOAL_THEN `connected(c:real^N->bool)` MP_TAC THENL + [ASM_MESON_TAC[CONNECTED_CONNECTED_COMPONENT]; ALL_TAC] THEN + SUBGOAL_THEN + `closed_in (subtopology euclidean c0) (c0 INTER v1 :real^N->bool) /\ + closed_in (subtopology euclidean c0) (c0 INTER v2 :real^N->bool)` + MP_TAC THENL + [CONJ_TAC THEN + MATCH_MP_TAC(MESON[] + `closed_in top (c INTER closure v) /\ + c INTER closure v = c INTER v + ==> closed_in top (c INTER v)`) THEN + (CONJ_TAC THENL + [MESON_TAC[CLOSED_IN_CLOSED; CLOSED_CLOSURE]; ALL_TAC]) THEN + FIRST_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE + `c0 SUBSET vv ==> c0 INTER (vv INTER v') = c0 INTER v + ==> c0 INTER v' = c0 INTER v`)) THEN + REWRITE_TAC[ONCE_REWRITE_RULE[INTER_COMM] UNION_OVER_INTER; + UNION_OVER_INTER] THEN + SIMP_TAC[SET_RULE `s SUBSET t ==> s INTER t = s`; CLOSURE_SUBSET] THENL + [ALL_TAC; ONCE_REWRITE_TAC[UNION_COMM]] THEN + MATCH_MP_TAC(SET_RULE `t = {} ==> s UNION (u INTER t) = s`) THEN + ASM_SIMP_TAC[OPEN_INTER_CLOSURE_EQ_EMPTY] THEN ASM SET_TAC[]; + ALL_TAC] THEN + REWRITE_TAC[CLOSED_IN_CLOSED] THEN DISCH_THEN(CONJUNCTS_THEN2 + (X_CHOOSE_THEN `u1:real^N->bool` STRIP_ASSUME_TAC) + (X_CHOOSE_THEN `u2:real^N->bool` STRIP_ASSUME_TAC)) THEN + SUBGOAL_THEN `closed(c0:real^N->bool)` ASSUME_TAC THENL + [ASM_MESON_TAC[CLOSED_IN_CLOSED_TRANS; COMPACT_IMP_CLOSED]; ALL_TAC] THEN + REWRITE_TAC[CONNECTED_CLOSED] THEN MAP_EVERY EXISTS_TAC + [`c0 INTER u1:real^N->bool`; `c0 INTER u2:real^N->bool`] THEN + ASM_SIMP_TAC[CLOSED_INTER] THEN + REPLICATE_TAC 2 (CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC]) THEN CONJ_TAC THENL + [STRIP_TAC THEN + SUBGOAL_THEN `c SUBSET (c0 INTER v2 :real^N->bool)` MP_TAC THENL + [ASM SET_TAC[]; ALL_TAC] THEN + SUBGOAL_THEN `k SUBSET (c0 INTER v2 :real^N->bool)` ASSUME_TAC THENL + [ALL_TAC; ASM SET_TAC[]]; + STRIP_TAC THEN + SUBGOAL_THEN `c SUBSET (c0 INTER v1 :real^N->bool)` ASSUME_TAC THENL + [ASM SET_TAC[]; ALL_TAC] THEN + SUBGOAL_THEN `k SUBSET (c0 INTER v1 :real^N->bool)` ASSUME_TAC THENL + [ALL_TAC; ASM SET_TAC[]]] THEN + (UNDISCH_THEN `k1 UNION k2 :real^N->bool = k` (K ALL_TAC) THEN + EXPAND_TAC "k" THEN + MATCH_MP_TAC(SET_RULE `s IN t ==> INTERS t SUBSET s`) THEN + REWRITE_TAC[IN_ELIM_THM] THEN REPEAT CONJ_TAC THENL + [ASM SET_TAC[]; + MATCH_MP_TAC OPEN_IN_INTER_OPEN THEN ASM_REWRITE_TAC[]; + ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC CLOSED_IN_INTER_CLOSED THEN ASM_REWRITE_TAC[]]));; + +let SURA_BURA_CLOSED = prove + (`!s c:real^N->bool. + closed s /\ c IN components s /\ compact c + ==> c = INTERS {k | c SUBSET k /\ compact k /\ + open_in (subtopology euclidean s) k}`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL + [SET_TAC[]; ALL_TAC] THEN + SUBGOAL_THEN + `!u:real^N->bool. + open u /\ c SUBSET u + ==> ?k. c SUBSET k /\ k SUBSET u /\ compact k /\ + open_in (subtopology euclidean s) k` + ASSUME_TAC THENL + [ALL_TAC; + REWRITE_TAC[SUBSET] THEN X_GEN_TAC `x:real^N` THEN + ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN DISCH_TAC THEN + MP_TAC(ISPECL [`{x:real^N}`; `c:real^N->bool`] SEPARATION_NORMAL) THEN + ASM_SIMP_TAC[COMPACT_IMP_CLOSED; CLOSED_SING] THEN + ANTS_TAC THENL [ASM SET_TAC[]; REWRITE_TAC[LEFT_IMP_EXISTS_THM]] THEN + MAP_EVERY X_GEN_TAC [`u:real^N->bool`; `v:real^N->bool`] THEN + STRIP_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC `v:real^N->bool`) THEN + ASM_REWRITE_TAC[IN_INTERS; NOT_FORALL_THM; IN_ELIM_THM; NOT_IMP] THEN + MATCH_MP_TAC MONO_EXISTS THEN REPEAT STRIP_TAC THEN ASM SET_TAC[]] THEN + REPEAT STRIP_TAC THEN + SUBGOAL_THEN + `?f. FINITE f /\ c SUBSET UNIONS f /\ + (!d:real^N->bool. d IN f ==> open d) /\ + (!d:real^N->bool. d IN f ==> bounded d) /\ + (!d. d IN f ==> closure d SUBSET u)` + STRIP_ASSUME_TAC THENL + [FIRST_ASSUM(MP_TAC o MATCH_MP COMPACT_IMP_HEINE_BOREL) THEN + DISCH_THEN(MP_TAC o SPEC + `{ ball(x:real^N,e) | x IN c /\ &0 < e /\ cball(x,e) SUBSET u}`) THEN + ANTS_TAC THENL + [REWRITE_TAC[FORALL_IN_GSPEC; UNIONS_GSPEC; OPEN_BALL] THEN + REWRITE_TAC[SUBSET; IN_ELIM_THM] THEN X_GEN_TAC `x:real^N` THEN + DISCH_TAC THEN EXISTS_TAC `x:real^N` THEN ASM_REWRITE_TAC[] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [OPEN_CONTAINS_CBALL]) THEN + DISCH_THEN(MP_TAC o SPEC `x:real^N`) THEN + ANTS_TAC THENL [ASM SET_TAC[]; MATCH_MP_TAC MONO_EXISTS] THEN + REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[CENTRE_IN_BALL] THEN + ASM SET_TAC[]; + MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC THEN STRIP_TAC THEN + ASM_SIMP_TAC[] THEN REPEAT CONJ_TAC THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP + (SET_RULE `t SUBSET s ==> (!x. x IN s ==> P x) + ==> (!x. x IN t ==> P x)`)) THEN + SIMP_TAC[FORALL_IN_GSPEC; OPEN_BALL; BOUNDED_BALL; CLOSURE_BALL]]; + ALL_TAC] THEN + ABBREV_TAC `v:real^N->bool = UNIONS f` THEN + SUBGOAL_THEN `bounded(v:real^N->bool)` ASSUME_TAC THENL + [EXPAND_TAC "v" THEN MATCH_MP_TAC BOUNDED_UNIONS THEN + ASM_MESON_TAC[]; + ALL_TAC] THEN + SUBGOAL_THEN `compact(closure v:real^N->bool)` ASSUME_TAC THENL + [ASM_REWRITE_TAC[COMPACT_CLOSURE]; ALL_TAC] THEN + SUBGOAL_THEN `(closure v:real^N->bool) SUBSET u` ASSUME_TAC THENL + [EXPAND_TAC "v" THEN ASM_SIMP_TAC[CLOSURE_UNIONS] THEN + ASM_REWRITE_TAC[UNIONS_SUBSET; FORALL_IN_GSPEC]; + ALL_TAC] THEN + SUBGOAL_THEN `open(v:real^N->bool)` ASSUME_TAC THENL + [EXPAND_TAC "v" THEN MATCH_MP_TAC OPEN_UNIONS THEN + ASM_REWRITE_TAC[]; + ALL_TAC] THEN + MP_TAC(ISPECL + [`closure v INTER s:real^N->bool`; `c:real^N->bool`] + SURA_BURA_COMPACT) THEN + ANTS_TAC THENL + [ASM_SIMP_TAC[COMPACT_INTER_CLOSED] THEN + REWRITE_TAC[IN_COMPONENTS_MAXIMAL] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_COMPONENTS_MAXIMAL]) THEN + ASM_MESON_TAC[SUBSET_INTER; SUBSET_TRANS; CLOSURE_SUBSET]; + ALL_TAC] THEN + SUBGOAL_THEN + `!t:real^N->bool. + c SUBSET t /\ + open_in (subtopology euclidean (closure v INTER s)) t /\ + closed_in (subtopology euclidean (closure v INTER s)) t <=> + c SUBSET t /\ t SUBSET (closure v INTER s) /\ compact t /\ + open_in (subtopology euclidean (closure v INTER s)) t` + (fun th -> REWRITE_TAC[th]) + THENL + [GEN_TAC THEN EQ_TAC THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THENL + [MATCH_MP_TAC(TAUT `p /\ (p ==> q) ==> p /\ q`) THEN CONJ_TAC THENL + [ASM_MESON_TAC[CLOSED_IN_SUBSET; TOPSPACE_EUCLIDEAN_SUBTOPOLOGY]; + STRIP_TAC THEN REWRITE_TAC[COMPACT_EQ_BOUNDED_CLOSED] THEN + CONJ_TAC THENL + [ASM_MESON_TAC[BOUNDED_SUBSET; COMPACT_IMP_BOUNDED; + COMPACT_INTER_CLOSED]; + MATCH_MP_TAC CLOSED_IN_CLOSED_TRANS THEN + EXISTS_TAC `closure v INTER s:real^N->bool` THEN + ASM_MESON_TAC[COMPACT_IMP_CLOSED; CLOSED_INTER]]]; + MATCH_MP_TAC CLOSED_CLOSED_IN_TRANS THEN + ASM_SIMP_TAC[COMPACT_IMP_CLOSED; CLOSED_INTER]]; + DISCH_THEN(ASSUME_TAC o SYM)] THEN + MP_TAC(ISPECL + [`(closure v INTER s) DIFF v:real^N->bool`; + `{t:real^N->bool | c SUBSET t /\ + t SUBSET (closure v INTER s) /\ compact t /\ + open_in (subtopology euclidean (closure v INTER s)) t}`] + COMPACT_IMP_FIP) THEN + ASM_SIMP_TAC[COMPACT_DIFF; COMPACT_INTER_CLOSED] THEN + MATCH_MP_TAC(TAUT + `p /\ r /\ (~q ==> s) ==> (p /\ q ==> ~r) ==> s`) THEN + REWRITE_TAC[IN_ELIM_THM] THEN REPEAT CONJ_TAC THENL + [MESON_TAC[COMPACT_IMP_CLOSED]; + ASM SET_TAC[]; + REWRITE_TAC[NOT_FORALL_THM; LEFT_IMP_EXISTS_THM]] THEN + X_GEN_TAC `g:(real^N->bool)->bool` THEN + GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [SUBSET] THEN + REWRITE_TAC[IN_ELIM_THM; NOT_IMP] THEN + ASM_CASES_TAC `g:(real^N->bool)->bool = {}` THENL + [ASM_REWRITE_TAC[FINITE_EMPTY; NOT_IN_EMPTY; INTERS_0; INTER_UNIV] THEN + REWRITE_TAC[SET_RULE `s DIFF t = {} <=> s SUBSET t`] THEN + STRIP_TAC THEN EXISTS_TAC `closure v INTER s :real^N->bool` THEN + REPEAT CONJ_TAC THENL + [FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_COMPONENTS_MAXIMAL]) THEN + MP_TAC(ISPEC `v:real^N->bool` CLOSURE_SUBSET) THEN ASM SET_TAC[]; + ASM SET_TAC[]; + ASM_SIMP_TAC[COMPACT_INTER_CLOSED]; + SUBGOAL_THEN `closure v INTER s :real^N->bool = s INTER v` + SUBST1_TAC THENL + [MP_TAC(ISPEC `v:real^N->bool` CLOSURE_SUBSET) THEN ASM SET_TAC[]; + ASM_SIMP_TAC[OPEN_IN_OPEN_INTER]]]; + STRIP_TAC THEN + EXISTS_TAC `INTERS g :real^N->bool` THEN REPEAT CONJ_TAC THENL + [ASM SET_TAC[]; + MP_TAC(ISPEC `v:real^N->bool` CLOSURE_SUBSET) THEN ASM SET_TAC[]; + MATCH_MP_TAC COMPACT_INTERS THEN ASM_MESON_TAC[]; + SUBGOAL_THEN + `open_in (subtopology euclidean (closure v INTER s)) + (INTERS g:real^N->bool)` + MP_TAC THENL + [MATCH_MP_TAC OPEN_IN_INTERS THEN ASM_MESON_TAC[]; ALL_TAC] THEN + FIRST_ASSUM(MP_TAC o MATCH_MP (SET_RULE + `(s DIFF t) INTER u = {} ==> u SUBSET s ==> u SUBSET t`)) THEN + ANTS_TAC THENL [ASM SET_TAC[]; DISCH_TAC] THEN + REWRITE_TAC[OPEN_IN_OPEN] THEN + DISCH_THEN(X_CHOOSE_THEN `t:real^N->bool` STRIP_ASSUME_TAC) THEN + ASM_REWRITE_TAC[] THEN + EXISTS_TAC `(v:real^N->bool) INTER t` THEN ASM_SIMP_TAC[OPEN_INTER] THEN + MP_TAC(ISPEC `v:real^N->bool` CLOSURE_SUBSET) THEN ASM SET_TAC[]]]);; + +(* ------------------------------------------------------------------------- *) +(* Condition for an open map's image to contain a ball. *) +(* ------------------------------------------------------------------------- *) + +let BALL_SUBSET_OPEN_MAP_IMAGE = prove + (`!f:real^M->real^N s a r. + bounded s /\ f continuous_on closure s /\ open(IMAGE f (interior s)) /\ + a IN s /\ &0 < r /\ (!z. z IN frontier s ==> r <= norm(f z - f a)) + ==> ball(f(a),r) SUBSET IMAGE f s`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`ball((f:real^M->real^N) a,r)`; + `(:real^N) DIFF IMAGE (f:real^M->real^N) s`] + CONNECTED_INTER_FRONTIER) THEN + REWRITE_TAC[CONNECTED_BALL] THEN MATCH_MP_TAC(SET_RULE + `~(b INTER s = {}) /\ b INTER f = {} ==> + (~(b INTER (UNIV DIFF s) = {}) /\ ~(b DIFF (UNIV DIFF s) = {}) + ==> ~(b INTER f = {})) + ==> b SUBSET s`) THEN + REWRITE_TAC[FRONTIER_COMPLEMENT] THEN CONJ_TAC THENL + [REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; IN_INTER] THEN + EXISTS_TAC `(f:real^M->real^N) a` THEN + ASM_REWRITE_TAC[CENTRE_IN_BALL] THEN ASM SET_TAC[]; + REWRITE_TAC[SET_RULE `s INTER t = {} <=> !x. x IN t ==> ~(x IN s)`] THEN + REWRITE_TAC[IN_BALL; REAL_NOT_LT]] THEN + MP_TAC(ISPECL[`frontier(IMAGE (f:real^M->real^N) s)`; `(f:real^M->real^N) a`] + DISTANCE_ATTAINS_INF) THEN + REWRITE_TAC[FRONTIER_CLOSED; FRONTIER_EQ_EMPTY] THEN ANTS_TAC THENL + [SIMP_TAC[DE_MORGAN_THM] THEN CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + MATCH_MP_TAC(MESON[NOT_BOUNDED_UNIV] `bounded s ==> ~(s = UNIV)`) THEN + MATCH_MP_TAC BOUNDED_SUBSET THEN + EXISTS_TAC `IMAGE (f:real^M->real^N) (closure s)` THEN + SIMP_TAC[IMAGE_SUBSET; CLOSURE_SUBSET] THEN + MATCH_MP_TAC COMPACT_IMP_BOUNDED THEN + MATCH_MP_TAC COMPACT_CONTINUOUS_IMAGE THEN + ASM_REWRITE_TAC[COMPACT_CLOSURE]; + DISCH_THEN(X_CHOOSE_THEN `w:real^N` STRIP_ASSUME_TAC)] THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE RAND_CONV [frontier]) THEN + REWRITE_TAC[IN_DIFF] THEN + DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN + REWRITE_TAC[CLOSURE_SEQUENTIAL] THEN + DISCH_THEN(X_CHOOSE_THEN `y:num->real^N` + (CONJUNCTS_THEN2 MP_TAC ASSUME_TAC)) THEN + REWRITE_TAC[IN_IMAGE; SKOLEM_THM; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `z:num->real^M` THEN REWRITE_TAC[FORALL_AND_THM] THEN + ONCE_REWRITE_TAC[GSYM FUN_EQ_THM] THEN + DISCH_THEN(CONJUNCTS_THEN2 SUBST_ALL_TAC ASSUME_TAC) THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM COMPACT_CLOSURE]) THEN + REWRITE_TAC[compact] THEN + DISCH_THEN(MP_TAC o SPEC `z:num->real^M`) THEN + ASM_SIMP_TAC[REWRITE_RULE[SUBSET] CLOSURE_SUBSET; LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`y:real^M`; `r:num->num`] THEN STRIP_TAC THEN + SUBGOAL_THEN + `(((\n. (f:real^M->real^N)(z n)) o (r:num->num)) --> w) sequentially` + MP_TAC THENL + [MATCH_MP_TAC LIM_SUBSEQUENCE THEN ASM_REWRITE_TAC[]; + ONCE_REWRITE_TAC[GSYM o_DEF] THEN REWRITE_TAC[GSYM o_ASSOC]] THEN + DISCH_TAC THEN + SUBGOAL_THEN `!n. ((z:num->real^M) o (r:num->num)) n IN s` MP_TAC THENL + [ASM_REWRITE_TAC[o_THM]; + UNDISCH_THEN `((\n. (f:real^M->real^N) ((z:num->real^M) n)) --> w) + sequentially` (K ALL_TAC) THEN + UNDISCH_THEN `!n. (z:num->real^M) n IN s` (K ALL_TAC)] THEN + POP_ASSUM_LIST(MP_TAC o end_itlist CONJ o rev) THEN + SPEC_TAC(`(z:num->real^M) o (r:num->num)`, `z:num->real^M`) THEN + REPEAT STRIP_TAC THEN + SUBGOAL_THEN `w = (f:real^M->real^N) y` SUBST_ALL_TAC THENL + [MATCH_MP_TAC(ISPEC `sequentially` LIM_UNIQUE) THEN + EXISTS_TAC `(f:real^M->real^N) o (z:num->real^M)` THEN + ASM_REWRITE_TAC[TRIVIAL_LIMIT_SEQUENTIALLY] THEN + ASM_MESON_TAC[CONTINUOUS_ON_CLOSURE_SEQUENTIALLY]; + ALL_TAC] THEN + MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `norm(f y - (f:real^M->real^N) a)` THEN CONJ_TAC THENL + [FIRST_X_ASSUM MATCH_MP_TAC; ASM_MESON_TAC[dist; NORM_SUB]] THEN + ASM_REWRITE_TAC[frontier; IN_DIFF] THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o check (is_neg o concl)) THEN + REWRITE_TAC[interior; IN_ELIM_THM] THEN + EXISTS_TAC `IMAGE (f:real^M->real^N) (interior s)` THEN + ASM_SIMP_TAC[IMAGE_SUBSET; INTERIOR_SUBSET] THEN ASM SET_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* Arithmetic operations on sets preserve convexity. *) +(* ------------------------------------------------------------------------- *) + +let CONVEX_SCALING = prove + (`!s c. convex s ==> convex (IMAGE (\x. c % x) s)`, + REWRITE_TAC[convex; IN_IMAGE] THEN REPEAT STRIP_TAC THEN + ASM_REWRITE_TAC[VECTOR_ARITH + `u % c % x + v % c % y = c % (u % x + v % y)`] THEN + ASM_MESON_TAC[]);; + +let CONVEX_SCALING_EQ = prove + (`!s c. ~(c = &0) ==> (convex (IMAGE (\x. c % x) s) <=> convex s)`, + REPEAT STRIP_TAC THEN EQ_TAC THEN REWRITE_TAC[CONVEX_SCALING] THEN + DISCH_THEN(MP_TAC o SPEC `inv c` o MATCH_MP CONVEX_SCALING) THEN + ASM_SIMP_TAC[GSYM IMAGE_o; o_DEF; VECTOR_MUL_ASSOC; + REAL_MUL_LINV; VECTOR_MUL_LID; IMAGE_ID]);; + +let CONVEX_NEGATIONS = prove + (`!s. convex s ==> convex (IMAGE (--) s)`, + REWRITE_TAC[convex; IN_IMAGE] THEN REPEAT STRIP_TAC THEN + ASM_REWRITE_TAC[VECTOR_ARITH + `u % --x + v % --y = --(u % x + v % y)`] THEN + ASM_MESON_TAC[]);; + +let CONVEX_SUMS = prove + (`!s t. convex s /\ convex t ==> convex {x + y | x IN s /\ y IN t}`, + REWRITE_TAC[convex; IN_ELIM_THM] THEN REPEAT STRIP_TAC THEN + ASM_REWRITE_TAC[VECTOR_ARITH + `u % (a + b) + v % (c + d) = (u % a + v % c) + (u % b + v % d)`] THEN + ASM_MESON_TAC[]);; + +let CONVEX_DIFFERENCES = prove + (`!s t. convex s /\ convex t ==> convex {x - y | x IN s /\ y IN t}`, + REWRITE_TAC[convex; IN_ELIM_THM] THEN REPEAT STRIP_TAC THEN + ASM_REWRITE_TAC[VECTOR_ARITH + `u % (a - b) + v % (c - d) = (u % a + v % c) - (u % b + v % d)`] THEN + ASM_MESON_TAC[]);; + +let CONVEX_AFFINITY = prove + (`!s a:real^N c. + convex s ==> convex (IMAGE (\x. a + c % x) s)`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN `(\x:real^N. a + c % x) = (\x. a + x) o (\x. c % x)` + SUBST1_TAC THENL [REWRITE_TAC[o_DEF]; ALL_TAC] THEN + ASM_SIMP_TAC[IMAGE_o; CONVEX_TRANSLATION; CONVEX_SCALING]);; + +let CONVEX_LINEAR_PREIMAGE = prove + (`!f:real^M->real^N. + linear f /\ convex s ==> convex {x | f(x) IN s}`, + REWRITE_TAC[CONVEX_ALT; IN_ELIM_THM] THEN + SIMP_TAC[LINEAR_ADD; LINEAR_CMUL]);; + +(* ------------------------------------------------------------------------- *) +(* Convex hull. *) +(* ------------------------------------------------------------------------- *) + +let CONVEX_CONVEX_HULL = prove + (`!s. convex(convex hull s)`, + SIMP_TAC[P_HULL; CONVEX_INTERS]);; + +let CONVEX_HULL_EQ = prove + (`!s. (convex hull s = s) <=> convex s`, + SIMP_TAC[HULL_EQ; CONVEX_INTERS]);; + +let IS_CONVEX_HULL = prove + (`!s. convex s <=> ?t. s = convex hull t`, + GEN_TAC THEN MATCH_MP_TAC IS_HULL THEN SIMP_TAC[CONVEX_INTERS]);; + +let CONVEX_HULL_UNIV = prove + (`convex hull (:real^N) = (:real^N)`, + REWRITE_TAC[CONVEX_HULL_EQ; CONVEX_UNIV]);; + +let BOUNDED_CONVEX_HULL = prove + (`!s:real^N->bool. bounded s ==> bounded(convex hull s)`, + GEN_TAC THEN GEN_REWRITE_TAC LAND_CONV [bounded] THEN + DISCH_THEN(X_CHOOSE_THEN `B:real` STRIP_ASSUME_TAC) THEN + MATCH_MP_TAC BOUNDED_SUBSET THEN EXISTS_TAC `cball(vec 0:real^N,B)` THEN + SIMP_TAC[BOUNDED_CBALL; SUBSET_HULL; CONVEX_CBALL] THEN + ASM_REWRITE_TAC[IN_CBALL; SUBSET; dist; VECTOR_SUB_LZERO; NORM_NEG]);; + +let BOUNDED_CONVEX_HULL_EQ = prove + (`!s. bounded(convex hull s) <=> bounded s`, + MESON_TAC[BOUNDED_CONVEX_HULL; HULL_SUBSET; BOUNDED_SUBSET]);; + +let FINITE_IMP_BOUNDED_CONVEX_HULL = prove + (`!s. FINITE s ==> bounded(convex hull s)`, + SIMP_TAC[BOUNDED_CONVEX_HULL; FINITE_IMP_BOUNDED]);; + +(* ------------------------------------------------------------------------- *) +(* Stepping theorems for convex hulls of finite sets. *) +(* ------------------------------------------------------------------------- *) + +let CONVEX_HULL_EMPTY = prove + (`convex hull {} = {}`, + MATCH_MP_TAC HULL_UNIQUE THEN + REWRITE_TAC[SUBSET_REFL; CONVEX_EMPTY; EMPTY_SUBSET]);; + +let CONVEX_HULL_EQ_EMPTY = prove + (`!s. (convex hull s = {}) <=> (s = {})`, + GEN_TAC THEN EQ_TAC THEN + MESON_TAC[SUBSET_EMPTY; HULL_SUBSET; CONVEX_HULL_EMPTY]);; + +let CONVEX_HULL_SING = prove + (`!a. convex hull {a} = {a}`, + REWRITE_TAC[CONVEX_HULL_EQ; CONVEX_SING]);; + +let CONVEX_HULL_EQ_SING = prove + (`!s a:real^N. convex hull s = {a} <=> s = {a}`, + REPEAT GEN_TAC THEN ASM_CASES_TAC `s:real^N->bool = {}` THEN + ASM_REWRITE_TAC[CONVEX_HULL_EMPTY] THEN + EQ_TAC THEN STRIP_TAC THEN ASM_REWRITE_TAC[CONVEX_HULL_SING] THEN + MATCH_MP_TAC(SET_RULE `~(s = {}) /\ s SUBSET {a} ==> s = {a}`) THEN + ASM_REWRITE_TAC[] THEN FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN + REWRITE_TAC[HULL_SUBSET]);; + +let CONVEX_HULL_INSERT = prove + (`!s a. ~(s = {}) + ==> (convex hull (a INSERT s) = + {x:real^N | ?u v b. &0 <= u /\ &0 <= v /\ (u + v = &1) /\ + b IN (convex hull s) /\ + (x = u % a + v % b)})`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL + [MATCH_MP_TAC HULL_MINIMAL THEN CONJ_TAC THENL + [REWRITE_TAC[SUBSET; IN_ELIM_THM; IN_INSERT] THEN + X_GEN_TAC `x:real^N` THEN STRIP_TAC THENL + [MAP_EVERY EXISTS_TAC [`&1`; `&0`]; + MAP_EVERY EXISTS_TAC [`&0`; `&1`]] THEN + ASM_REWRITE_TAC[VECTOR_MUL_LID; VECTOR_MUL_LZERO] THEN + ASM_REWRITE_TAC[VECTOR_ADD_LID; VECTOR_ADD_RID] THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN + ASM_MESON_TAC[MEMBER_NOT_EMPTY; HULL_SUBSET; SUBSET]; + ALL_TAC]; + REWRITE_TAC[SUBSET; IN_ELIM_THM] THEN + REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC(REWRITE_RULE[convex] CONVEX_CONVEX_HULL) THEN + ASM_REWRITE_TAC[] THEN + ASM_MESON_TAC[HULL_SUBSET; SUBSET; IN_INSERT; HULL_MONO]] THEN + REWRITE_TAC[convex; IN_ELIM_THM] THEN + REWRITE_TAC[LEFT_AND_EXISTS_THM; LEFT_IMP_EXISTS_THM] THEN + REWRITE_TAC[RIGHT_AND_EXISTS_THM; LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC + [`x:real^N`; `y:real^N`; `u:real`; `v:real`; `u1:real`; `v1:real`; + `b1:real^N`; `u2:real`; `v2:real`; `b2:real^N`] THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + MAP_EVERY EXISTS_TAC [`u * u1 + v * u2`; `u * v1 + v * v2`] THEN + REWRITE_TAC[VECTOR_ARITH + `u % (u1 % a + v1 % b1) + v % (u2 % a + v2 % b2) = + (u * u1 + v * u2) % a + (u * v1) % b1 + (v * v2) % b2`] THEN + ASM_SIMP_TAC[REAL_LE_ADD; REAL_LE_MUL] THEN + ASM_REWRITE_TAC[REAL_MUL_RID; REAL_ARITH + `(u * u1 + v * u2) + (u * v1 + v * v2) = + u * (u1 + v1) + v * (u2 + v2)`] THEN + ASM_CASES_TAC `u * v1 + v * v2 = &0` THENL + [FIRST_X_ASSUM(MP_TAC o MATCH_MP (REAL_ARITH + `(a + b = &0) ==> &0 <= a /\ &0 <= b ==> (a = &0) /\ (b = &0)`)) THEN + ASM_SIMP_TAC[REAL_LE_MUL; REAL_ADD_LID; VECTOR_MUL_LZERO; + VECTOR_ADD_RID] THEN + ASM_MESON_TAC[]; + ALL_TAC] THEN + EXISTS_TAC `(u * v1) / (u * v1 + v * v2) % b1 + + (v * v2) / (u * v1 + v * v2) % b2 :real^N` THEN + ASM_SIMP_TAC[VECTOR_ADD_LDISTRIB; VECTOR_MUL_ASSOC; REAL_DIV_LMUL] THEN + MATCH_MP_TAC(REWRITE_RULE[convex] CONVEX_CONVEX_HULL) THEN + ASM_SIMP_TAC[REAL_LE_DIV; REAL_LE_MUL; REAL_LE_ADD] THEN + ASM_SIMP_TAC[real_div; GSYM REAL_ADD_RDISTRIB; REAL_MUL_RINV]);; + +let CONVEX_HULL_INSERT_ALT = prove + (`!s a:real^N. + convex hull (a INSERT s) = + if s = {} then {a} + else {(&1 - u) % a + u % x | &0 <= u /\ u <= &1 /\ x IN convex hull s}`, + REPEAT STRIP_TAC THEN COND_CASES_TAC THEN + ASM_REWRITE_TAC[CONVEX_HULL_SING] THEN + ASM_SIMP_TAC[CONVEX_HULL_INSERT] THEN + ONCE_REWRITE_TAC[TAUT `a /\ b /\ c /\ d <=> b /\ c /\ a /\ d`] THEN + ONCE_REWRITE_TAC[SWAP_EXISTS_THM] THEN + REWRITE_TAC[RIGHT_EXISTS_AND_THM; UNWIND_THM2; REAL_SUB_LE; + REAL_ARITH `u + v = &1 <=> u = &1 - v`] THEN + SET_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* Explicit expression for convex hull. *) +(* ------------------------------------------------------------------------- *) + +let CONVEX_HULL_INDEXED = prove + (`!s. convex hull s = + {y:real^N | ?k u x. (!i. 1 <= i /\ i <= k ==> &0 <= u i /\ x i IN s) /\ + (sum (1..k) u = &1) /\ + (vsum (1..k) (\i. u i % x i) = y)}`, + GEN_TAC THEN MATCH_MP_TAC HULL_UNIQUE THEN REPEAT CONJ_TAC THENL + [REWRITE_TAC[SUBSET; IN_ELIM_THM] THEN + X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN + MAP_EVERY EXISTS_TAC [`1`; `\i:num. &1`; `\i:num. x:real^N`] THEN + ASM_SIMP_TAC[FINITE_RULES; IN_SING; SUM_SING; VECTOR_MUL_LID; VSUM_SING; + REAL_POS; NUMSEG_SING]; + ALL_TAC; + REWRITE_TAC[CONVEX_INDEXED; SUBSET; IN_ELIM_THM; LEFT_IMP_EXISTS_THM] THEN + MESON_TAC[]] THEN + REWRITE_TAC[convex; IN_ELIM_THM] THEN + MAP_EVERY X_GEN_TAC [`x:real^N`; `y:real^N`; `u:real`; `v:real`] THEN + REWRITE_TAC[LEFT_AND_EXISTS_THM] THEN REWRITE_TAC[RIGHT_AND_EXISTS_THM] THEN + REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN MAP_EVERY X_GEN_TAC + [`k1:num`; `u1:num->real`; `x1:num->real^N`; + `k2:num`; `u2:num->real`; `x2:num->real^N`] THEN + STRIP_TAC THEN EXISTS_TAC `k1 + k2:num` THEN + EXISTS_TAC `\i:num. if i <= k1 then u * u1(i) else v * u2(i - k1):real` THEN + EXISTS_TAC `\i:num. if i <= k1 then x1(i) else x2(i - k1):real^N` THEN + ASM_SIMP_TAC[NUMSEG_ADD_SPLIT; ARITH_RULE `1 <= x + 1 /\ x < x + 1`; + IN_NUMSEG; SUM_UNION; VSUM_UNION; FINITE_NUMSEG; DISJOINT_NUMSEG; + ARITH_RULE `k1 + 1 <= i ==> ~(i <= k1)`] THEN + REWRITE_TAC[ONCE_REWRITE_RULE[ADD_SYM] NUMSEG_OFFSET_IMAGE] THEN + ASM_SIMP_TAC[SUM_IMAGE; VSUM_IMAGE; EQ_ADD_LCANCEL; FINITE_NUMSEG] THEN + ASM_SIMP_TAC[o_DEF; ADD_SUB2; SUM_LMUL; VSUM_LMUL; GSYM VECTOR_MUL_ASSOC; + FINITE_NUMSEG; REAL_MUL_RID] THEN + ASM_MESON_TAC[REAL_LE_MUL; ARITH_RULE + `i <= k1 + k2 /\ ~(i <= k1) ==> 1 <= i - k1 /\ i - k1 <= k2`]);; + +(* ------------------------------------------------------------------------- *) +(* Another formulation from Lars Schewe. *) +(* ------------------------------------------------------------------------- *) + +let CONVEX_HULL_EXPLICIT = prove + (`!p. convex hull p = + {y:real^N | ?s u. FINITE s /\ s SUBSET p /\ + (!x. x IN s ==> &0 <= u x) /\ + sum s u = &1 /\ vsum s (\v. u v % v) = y}`, + REWRITE_TAC[CONVEX_HULL_INDEXED;EXTENSION;IN_ELIM_THM] THEN + REPEAT STRIP_TAC THEN EQ_TAC THEN REPEAT STRIP_TAC THENL + [MAP_EVERY EXISTS_TAC [`IMAGE (x':num->real^N) (1..k)`; + `\v:real^N.sum {i | i IN (1..k) /\ x' i = v} u`] + THEN ASM_SIMP_TAC[FINITE_IMAGE;FINITE_NUMSEG;IN_IMAGE] THEN + REPEAT STRIP_TAC THENL + [REWRITE_TAC[IMAGE;SUBSET;IN_ELIM_THM;IN_NUMSEG] THEN + ASM_MESON_TAC[]; + MATCH_MP_TAC SUM_POS_LE THEN + ASM_SIMP_TAC[FINITE_NUMSEG;FINITE_RESTRICT;IN_ELIM_THM;IN_NUMSEG]; + ASM_SIMP_TAC[GSYM SUM_IMAGE_GEN;FINITE_IMAGE;FINITE_NUMSEG]; + FIRST_X_ASSUM (fun th -> REWRITE_TAC[GSYM th]) THEN + ASM_SIMP_TAC[GSYM VSUM_IMAGE_GEN;FINITE_IMAGE; + FINITE_NUMSEG;VSUM_VMUL;FINITE_RESTRICT] THEN + MP_TAC (ISPECL [`x':num->real^N`;`\i:num.u i % (x' i):real^N`;`(1..k)`] + (GSYM VSUM_IMAGE_GEN)) THEN + ASM_SIMP_TAC[FINITE_NUMSEG]];ALL_TAC] THEN + STRIP_ASSUME_TAC (ASM_REWRITE_RULE [ASSUME `FINITE (s:real^N->bool)`] + (ISPEC `s:real^N->bool` FINITE_INDEX_NUMSEG)) THEN + MAP_EVERY EXISTS_TAC [`CARD (s:real^N->bool)`; + `(u:real^N->real) o (f:num->real^N)`; + `(f:num->real^N)`] THEN + REPEAT STRIP_TAC THENL + [REWRITE_TAC[o_DEF] THEN FIRST_ASSUM MATCH_MP_TAC THEN + FIRST_ASSUM SUBST1_TAC THEN + REWRITE_TAC[IN_IMAGE;IN_NUMSEG] THEN + ASM_MESON_TAC[]; + MATCH_MP_TAC (REWRITE_RULE [SUBSET] + (ASSUME `(s:real^N->bool) SUBSET p`)) THEN + FIRST_ASSUM SUBST1_TAC THEN + REWRITE_TAC[IN_IMAGE;IN_NUMSEG] THEN + ASM_MESON_TAC[]; + MATCH_MP_TAC EQ_TRANS THEN EXISTS_TAC `sum (s:real^N->bool) u` THEN + CONJ_TAC THENL [ALL_TAC;ASM_REWRITE_TAC[]] THEN + GEN_REWRITE_TAC (RAND_CONV o ONCE_DEPTH_CONV) + [ASSUME `(s:real^N->bool) = IMAGE f (1..CARD s)`] THEN + MATCH_MP_TAC (GSYM SUM_IMAGE) THEN + ASM_MESON_TAC[]; + REWRITE_TAC[MESON [o_THM;FUN_EQ_THM] + `(\i:num. (u o f) i % f i) = (\v:real^N. u v % v) o f`] THEN + MATCH_MP_TAC EQ_TRANS THEN + EXISTS_TAC `vsum (s:real^N->bool) (\v. u v % v)` THEN + CONJ_TAC THENL [ALL_TAC;ASM_REWRITE_TAC[]] THEN + GEN_REWRITE_TAC (RAND_CONV o ONCE_DEPTH_CONV) + [ASSUME `(s:real^N->bool) = IMAGE f (1..CARD s)`] THEN + MATCH_MP_TAC (GSYM VSUM_IMAGE) THEN + ASM SET_TAC[FINITE_NUMSEG]]);; + +let CONVEX_HULL_FINITE = prove + (`!s:real^N->bool. + convex hull s = + {y | ?u. (!x. x IN s ==> &0 <= u x) /\ + sum s u = &1 /\ + vsum s (\x. u x % x) = y}`, + GEN_TAC THEN GEN_REWRITE_TAC I [EXTENSION] THEN + REWRITE_TAC[CONVEX_HULL_EXPLICIT; IN_ELIM_THM] THEN + X_GEN_TAC `x:real^N` THEN EQ_TAC THEN REWRITE_TAC[LEFT_IMP_EXISTS_THM] THENL + [MAP_EVERY X_GEN_TAC [`t:real^N->bool`; `f:real^N->real`] THEN + STRIP_TAC THEN + EXISTS_TAC `\x:real^N. if x IN t then f x else &0` THEN + REWRITE_TAC[COND_RAND; COND_RATOR; VECTOR_MUL_LZERO] THEN + REWRITE_TAC[GSYM SUM_RESTRICT_SET; GSYM VSUM_RESTRICT_SET] THEN + ASM_SIMP_TAC[SET_RULE `t SUBSET s ==> {x | x IN s /\ x IN t} = t`] THEN + REWRITE_TAC[REAL_LE_REFL; COND_ID]; + X_GEN_TAC `f:real^N->real` THEN + ASM_CASES_TAC `s:real^N->bool = {}` THEN + ASM_REWRITE_TAC[SUM_CLAUSES; REAL_OF_NUM_EQ; ARITH] THEN STRIP_TAC THEN + EXISTS_TAC `support (+) (f:real^N->real) s` THEN + EXISTS_TAC `f:real^N->real` THEN + MP_TAC(ASSUME `sum s (f:real^N->real) = &1`) THEN + GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [sum] THEN + REWRITE_TAC[iterate] THEN COND_CASES_TAC THEN + ASM_REWRITE_TAC[NEUTRAL_REAL_ADD; REAL_OF_NUM_EQ; ARITH] THEN + DISCH_THEN(K ALL_TAC) THEN + UNDISCH_TAC `sum s (f:real^N->real) = &1` THEN + GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [GSYM SUM_SUPPORT] THEN + ASM_CASES_TAC `support (+) (f:real^N->real) s = {}` THEN + ASM_SIMP_TAC[SUM_CLAUSES; REAL_OF_NUM_EQ; ARITH] THEN + DISCH_TAC THEN REWRITE_TAC[SUPPORT_SUBSET] THEN CONJ_TAC THENL + [ASM_SIMP_TAC[support; IN_ELIM_THM]; ALL_TAC] THEN + FIRST_X_ASSUM(fun th -> GEN_REWRITE_TAC RAND_CONV [GSYM th]) THEN + CONV_TAC SYM_CONV THEN MATCH_MP_TAC VSUM_SUPERSET THEN + REWRITE_TAC[SUPPORT_SUBSET] THEN + REWRITE_TAC[support; IN_ELIM_THM; NEUTRAL_REAL_ADD] THEN + MESON_TAC[VECTOR_MUL_LZERO]]);; + +let CONVEX_HULL_UNION_EXPLICIT = prove + (`!s t:real^N->bool. + convex s /\ convex t + ==> convex hull (s UNION t) = + s UNION t UNION + {(&1 - u) % x + u % y | x IN s /\ y IN t /\ &0 <= u /\ u <= &1}`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL + [REWRITE_TAC[CONVEX_HULL_EXPLICIT] THEN GEN_REWRITE_TAC I [SUBSET] THEN + REWRITE_TAC[IN_ELIM_THM; LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`y:real^N`; `u:real^N->bool`; `f:real^N->real`] THEN + REPLICATE_TAC 3 (DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + SUBST1_TAC(SET_RULE `u:real^N->bool = (u INTER s) UNION (u DIFF s)`) THEN + ASM_SIMP_TAC[SUM_UNION; VSUM_UNION; FINITE_INTER; FINITE_DIFF; + SET_RULE `DISJOINT (u INTER s) (u DIFF s)`] THEN + ASM_CASES_TAC `sum (u INTER s) (f:real^N->real) = &0` THENL + [SUBGOAL_THEN `!x. x IN (u INTER s) ==> (f:real^N->real) x = &0` + ASSUME_TAC THENL + [ASM_MESON_TAC[SUM_POS_EQ_0; FINITE_INTER; IN_INTER]; + ASM_SIMP_TAC[VECTOR_MUL_LZERO; VSUM_0] THEN + REWRITE_TAC[VECTOR_ADD_LID; REAL_ADD_LID] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC (SUBST1_TAC o SYM)) THEN + REWRITE_TAC[IN_UNION] THEN DISJ2_TAC THEN DISJ1_TAC THEN + FIRST_X_ASSUM(MATCH_MP_TAC o GEN_REWRITE_RULE I [CONVEX_EXPLICIT]) THEN + ASM_SIMP_TAC[FINITE_DIFF; IN_DIFF] THEN ASM SET_TAC[]]; + ALL_TAC] THEN + ASM_CASES_TAC `sum (u DIFF s) (f:real^N->real) = &0` THENL + [SUBGOAL_THEN `!x. x IN (u DIFF s) ==> (f:real^N->real) x = &0` + ASSUME_TAC THENL + [ASM_MESON_TAC[SUM_POS_EQ_0; FINITE_DIFF; IN_DIFF]; + ASM_SIMP_TAC[VECTOR_MUL_LZERO; VSUM_0] THEN + REWRITE_TAC[VECTOR_ADD_RID; REAL_ADD_RID] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC (SUBST1_TAC o SYM)) THEN + REWRITE_TAC[IN_UNION] THEN DISJ1_TAC THEN + FIRST_X_ASSUM(MATCH_MP_TAC o GEN_REWRITE_RULE I [CONVEX_EXPLICIT]) THEN + ASM_SIMP_TAC[FINITE_INTER; IN_INTER] THEN ASM SET_TAC[]]; + ALL_TAC] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC (SUBST1_TAC o SYM)) THEN + REWRITE_TAC[IN_UNION; IN_ELIM_THM] THEN DISJ2_TAC THEN DISJ2_TAC THEN + MAP_EVERY EXISTS_TAC + [`vsum(u INTER s) (\v:real^N. (f v / sum(u INTER s) f) % v)`; + `sum(u DIFF s) (f:real^N->real)`; + `vsum(u DIFF s) (\v:real^N. (f v / sum(u DIFF s) f) % v)`] THEN + REPEAT CONJ_TAC THENL + [FIRST_X_ASSUM(MATCH_MP_TAC o GEN_REWRITE_RULE I [CONVEX_EXPLICIT]) THEN + ASM_SIMP_TAC[INTER_SUBSET; FINITE_INTER; SUM_POS_LE; REAL_LE_DIV; + IN_INTER; real_div; SUM_RMUL; REAL_MUL_RINV]; + FIRST_X_ASSUM(MATCH_MP_TAC o GEN_REWRITE_RULE I [CONVEX_EXPLICIT]) THEN + ASM_SIMP_TAC[SUBSET_DIFF; FINITE_DIFF; SUM_POS_LE; REAL_LE_DIV; + IN_DIFF; real_div; SUM_RMUL; REAL_MUL_RINV] THEN + ASM SET_TAC[]; + ASM_SIMP_TAC[SUM_POS_LE; IN_DIFF; FINITE_DIFF]; + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH + `a + b = &1 ==> &0 <= a ==> b <= &1`)) THEN + ASM_SIMP_TAC[SUM_POS_LE; IN_INTER; FINITE_INTER]; + ASM_SIMP_TAC[GSYM VSUM_LMUL; FINITE_INTER; FINITE_DIFF] THEN + SIMP_TAC[VECTOR_MUL_ASSOC; REAL_ARITH `a * b / c:real = a / c * b`] THEN + FIRST_ASSUM(SUBST1_TAC o MATCH_MP (REAL_ARITH + `a + b = &1 ==> &1 - b = a`)) THEN + ASM_SIMP_TAC[REAL_DIV_REFL; REAL_MUL_LID]]; + REWRITE_TAC[GSYM UNION_ASSOC] THEN ONCE_REWRITE_TAC[UNION_SUBSET] THEN + REWRITE_TAC[HULL_SUBSET] THEN REWRITE_TAC[SUBSET; FORALL_IN_GSPEC] THEN + MAP_EVERY X_GEN_TAC [`x:real^N`; `u:real`; `y:real^N`] THEN STRIP_TAC THEN + MATCH_MP_TAC(REWRITE_RULE[CONVEX_ALT] CONVEX_CONVEX_HULL) THEN + ASM_SIMP_TAC[HULL_INC; IN_UNION]]);; + +let CONVEX_HULL_UNION_NONEMPTY_EXPLICIT = prove + (`!s t:real^N->bool. + convex s /\ ~(s = {}) /\ convex t /\ ~(t = {}) + ==> convex hull (s UNION t) = + {(&1 - u) % x + u % y | x IN s /\ y IN t /\ &0 <= u /\ u <= &1}`, + REPEAT STRIP_TAC THEN ASM_SIMP_TAC[CONVEX_HULL_UNION_EXPLICIT] THEN + SIMP_TAC[SET_RULE `s UNION t UNION u = u <=> s SUBSET u /\ t SUBSET u`] THEN + CONJ_TAC THEN REWRITE_TAC[SUBSET; IN_ELIM_THM] THEN X_GEN_TAC `z:real^N` THEN + DISCH_TAC THENL + [MAP_EVERY EXISTS_TAC [`z:real^N`; `&0`] THEN + REWRITE_TAC[REAL_SUB_RZERO; VECTOR_MUL_LID; REAL_POS; VECTOR_MUL_LZERO; + VECTOR_ADD_RID] THEN + ASM SET_TAC[]; + SUBGOAL_THEN `?a:real^N. a IN s` MP_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC THEN DISCH_TAC THEN + MAP_EVERY EXISTS_TAC [`&1`; `z:real^N`] THEN + ASM_REWRITE_TAC[REAL_POS; REAL_LE_REFL] THEN VECTOR_ARITH_TAC]);; + +let CONVEX_HULL_UNION_UNIONS = prove + (`!f s:real^N->bool. + convex(UNIONS f) /\ ~(f = {}) + ==> convex hull (s UNION UNIONS f) = + UNIONS {convex hull (s UNION t) | t IN f}`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL + [ALL_TAC; + REWRITE_TAC[UNIONS_SUBSET; FORALL_IN_GSPEC] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC HULL_MONO THEN ASM SET_TAC[]] THEN + ASM_CASES_TAC `s:real^N->bool = {}` THENL + [ASM_SIMP_TAC[UNION_EMPTY; HULL_P; UNIONS_SUBSET] THEN + X_GEN_TAC `u:real^N->bool` THEN DISCH_TAC THEN + MATCH_MP_TAC SUBSET_TRANS THEN EXISTS_TAC `convex hull u:real^N->bool` THEN + REWRITE_TAC[HULL_SUBSET] THEN ASM SET_TAC[]; + ALL_TAC] THEN + ASM_CASES_TAC `UNIONS f :real^N->bool = {}` THENL + [ASM_REWRITE_TAC[UNION_EMPTY] THEN + SUBGOAL_THEN `?u:real^N->bool. u IN f` CHOOSE_TAC THENL + [ASM_REWRITE_TAC[MEMBER_NOT_EMPTY]; ALL_TAC] THEN + MATCH_MP_TAC SUBSET_TRANS THEN + EXISTS_TAC `convex hull (s UNION u:real^N->bool)` THEN + ASM_SIMP_TAC[HULL_MONO; SUBSET_UNION] THEN ASM SET_TAC[]; + ALL_TAC] THEN + GEN_REWRITE_TAC LAND_CONV [HULL_UNION_LEFT] THEN + ASM_SIMP_TAC[CONVEX_HULL_UNION_NONEMPTY_EXPLICIT; CONVEX_HULL_EQ_EMPTY; + CONVEX_CONVEX_HULL] THEN + REWRITE_TAC[SUBSET; FORALL_IN_GSPEC] THEN + REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_UNIONS] THEN + X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN + MAP_EVERY X_GEN_TAC [`a:real`; `u:real^N->bool`] THEN DISCH_TAC THEN + X_GEN_TAC `y:real^N` THEN REPEAT STRIP_TAC THEN + REWRITE_TAC[IN_UNIONS; EXISTS_IN_GSPEC] THEN + EXISTS_TAC `u:real^N->bool` THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC(REWRITE_RULE[CONVEX_ALT] CONVEX_CONVEX_HULL) THEN + ASM_MESON_TAC[HULL_MONO; IN_UNION; SUBSET; HULL_INC]);; + +(* ------------------------------------------------------------------------- *) +(* A stepping theorem for that expansion. *) +(* ------------------------------------------------------------------------- *) + +let CONVEX_HULL_FINITE_STEP = prove + (`((?u. (!x. x IN {} ==> &0 <= u x) /\ + sum {} u = w /\ + vsum {} (\x. u(x) % x) = y) <=> w = &0 /\ y = vec 0) /\ + (FINITE(s:real^N->bool) + ==> ((?u. (!x. x IN (a INSERT s) ==> &0 <= u x) /\ + sum (a INSERT s) u = w /\ + vsum (a INSERT s) (\x. u(x) % x) = y) <=> + ?v. &0 <= v /\ + ?u. (!x. x IN s ==> &0 <= u x) /\ + sum s u = w - v /\ + vsum s (\x. u(x) % x) = y - v % a))`, + MP_TAC(ISPEC `\x:real^N y:real. &0 <= y` AFFINE_HULL_FINITE_STEP_GEN) THEN + SIMP_TAC[REAL_ARITH `&0 <= x / &2 <=> &0 <= x`; REAL_LE_ADD] THEN + REWRITE_TAC[RIGHT_AND_EXISTS_THM]);; + +(* ------------------------------------------------------------------------- *) +(* Hence some special cases. *) +(* ------------------------------------------------------------------------- *) + +let CONVEX_HULL_2 = prove + (`!a b. convex hull {a,b} = + {u % a + v % b | &0 <= u /\ &0 <= v /\ u + v = &1}`, + SIMP_TAC[CONVEX_HULL_FINITE; FINITE_INSERT; FINITE_RULES] THEN + SIMP_TAC[CONVEX_HULL_FINITE_STEP; FINITE_INSERT; FINITE_RULES] THEN + REWRITE_TAC[REAL_ARITH `x - y = z:real <=> x = y + z`; + VECTOR_ARITH `x - y = z:real^N <=> x = y + z`] THEN + REWRITE_TAC[VECTOR_ADD_RID; REAL_ADD_RID] THEN SET_TAC[]);; + +let CONVEX_HULL_2_ALT = prove + (`!a b. convex hull {a,b} = {a + u % (b - a) | &0 <= u /\ u <= &1}`, + ONCE_REWRITE_TAC[SET_RULE `{a,b} = {b,a}`] THEN + REWRITE_TAC[CONVEX_HULL_2; EXTENSION; IN_ELIM_THM] THEN + REWRITE_TAC[REAL_ADD_ASSOC; CONJ_ASSOC] THEN + REWRITE_TAC[TAUT `(a /\ x + y = &1) /\ b <=> x + y = &1 /\ a /\ b`] THEN + REWRITE_TAC[REAL_ARITH `x + y = &1 <=> y = &1 - x`; UNWIND_THM2] THEN + REPEAT GEN_TAC THEN REPEAT(AP_TERM_TAC THEN ABS_TAC) THEN + BINOP_TAC THENL [REAL_ARITH_TAC; VECTOR_ARITH_TAC]);; + +let CONVEX_HULL_3 = prove + (`convex hull {a,b,c} = + { u % a + v % b + w % c | + &0 <= u /\ &0 <= v /\ &0 <= w /\ u + v + w = &1}`, + SIMP_TAC[CONVEX_HULL_FINITE; FINITE_INSERT; FINITE_RULES] THEN + SIMP_TAC[CONVEX_HULL_FINITE_STEP; FINITE_INSERT; FINITE_RULES] THEN + REWRITE_TAC[REAL_ARITH `x - y = z:real <=> x = y + z`; + VECTOR_ARITH `x - y = z:real^N <=> x = y + z`] THEN + REWRITE_TAC[VECTOR_ADD_RID; REAL_ADD_RID] THEN SET_TAC[]);; + +let CONVEX_HULL_3_ALT = prove + (`!a b c. convex hull {a,b,c} = + {a + u % (b - a) + v % (c - a) | + &0 <= u /\ &0 <= v /\ u + v <= &1}`, + ONCE_REWRITE_TAC[SET_RULE `{a,b,c} = {b,c,a}`] THEN + REWRITE_TAC[CONVEX_HULL_3; EXTENSION; IN_ELIM_THM] THEN + REWRITE_TAC[REAL_ADD_ASSOC; CONJ_ASSOC] THEN + REWRITE_TAC[TAUT `(a /\ x + y = &1) /\ b <=> x + y = &1 /\ a /\ b`] THEN + REWRITE_TAC[REAL_ARITH `x + y = &1 <=> y = &1 - x`; UNWIND_THM2] THEN + REPEAT GEN_TAC THEN REPEAT(AP_TERM_TAC THEN ABS_TAC) THEN + BINOP_TAC THENL [REAL_ARITH_TAC; VECTOR_ARITH_TAC]);; + +let CONVEX_HULL_SUMS = prove + (`!s t:real^N->bool. + convex hull {x + y | x IN s /\ y IN t} = + {x + y | x IN convex hull s /\ y IN convex hull t}`, + REPEAT GEN_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL + [MATCH_MP_TAC HULL_MINIMAL THEN + SIMP_TAC[CONVEX_SUMS; CONVEX_CONVEX_HULL] THEN + REWRITE_TAC[SUBSET; FORALL_IN_GSPEC] THEN + REWRITE_TAC[IN_ELIM_THM] THEN MESON_TAC[HULL_INC]; + REWRITE_TAC[SUBSET; FORALL_IN_GSPEC] THEN + MAP_EVERY X_GEN_TAC [`x:real^N`; `y:real^N`] THEN + GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [CONVEX_HULL_INDEXED] THEN + REWRITE_TAC[IN_ELIM_THM; LEFT_AND_EXISTS_THM] THEN + REWRITE_TAC[RIGHT_AND_EXISTS_THM; LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC + [`k1:num`; `u1:num->real`; `x1:num->real^N`; + `k2:num`; `u2:num->real`; `x2:num->real^N`] THEN + STRIP_TAC THEN + SUBGOAL_THEN + `x + y:real^N = + vsum(1..k1) (\i. vsum(1..k2) (\j. u1 i % u2 j % (x1 i + x2 j)))` + SUBST1_TAC THENL + [REWRITE_TAC[VECTOR_ADD_LDISTRIB; VSUM_ADD_NUMSEG] THEN + ASM_SIMP_TAC[VSUM_LMUL; VSUM_RMUL; VECTOR_MUL_LID]; + REWRITE_TAC[VSUM_LMUL] THEN MATCH_MP_TAC CONVEX_VSUM THEN + ASM_SIMP_TAC[FINITE_NUMSEG; CONVEX_CONVEX_HULL; IN_NUMSEG] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC CONVEX_VSUM THEN + ASM_SIMP_TAC[FINITE_NUMSEG; CONVEX_CONVEX_HULL; IN_NUMSEG] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC HULL_INC THEN ASM SET_TAC[]]]);; + +let AFFINE_HULL_PCROSS,CONVEX_HULL_PCROSS = (CONJ_PAIR o prove) + (`(!s:real^M->bool t:real^N->bool. + affine hull (s PCROSS t) = + (affine hull s) PCROSS (affine hull t)) /\ + (!s:real^M->bool t:real^N->bool. + convex hull (s PCROSS t) = + (convex hull s) PCROSS (convex hull t))`, + let lemma1 = prove + (`!u v x y:real^M z:real^N. + u + v = &1 + ==> pastecart z (u % x + v % y) = + u % pastecart z x + v % pastecart z y /\ + pastecart (u % x + v % y) z = + u % pastecart x z + v % pastecart y z`, + REWRITE_TAC[PASTECART_ADD; GSYM PASTECART_CMUL] THEN + SIMP_TAC[GSYM VECTOR_ADD_RDISTRIB; VECTOR_MUL_LID]) + and lemma2 = prove + (`INTERS {{x | pastecart x y IN u} | y IN t} = + {x | !y. y IN t ==> pastecart x y IN u}`, + REWRITE_TAC[INTERS_GSPEC; EXTENSION; IN_ELIM_THM] THEN SET_TAC[]) in + CONJ_TAC THENL + [REPEAT STRIP_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL + [MATCH_MP_TAC HULL_MINIMAL THEN + SIMP_TAC[AFFINE_PCROSS; AFFINE_AFFINE_HULL; HULL_SUBSET; PCROSS_MONO]; + REWRITE_TAC[SUBSET; FORALL_IN_PCROSS] THEN + REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN + MATCH_MP_TAC HULL_INDUCT THEN CONJ_TAC THENL + [X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN + MATCH_MP_TAC HULL_INDUCT THEN CONJ_TAC THENL + [X_GEN_TAC `y:real^N` THEN DISCH_TAC THEN + SUBGOAL_THEN `pastecart (x:real^M) (y:real^N) IN s PCROSS t` MP_TAC + THENL [ASM_REWRITE_TAC[PASTECART_IN_PCROSS]; ALL_TAC] THEN + REWRITE_TAC[HULL_INC]; + ALL_TAC]; + REWRITE_TAC[GSYM lemma2] THEN MATCH_MP_TAC AFFINE_INTERS THEN + REWRITE_TAC[FORALL_IN_GSPEC]] THEN + SIMP_TAC[affine; IN_ELIM_THM; lemma1; + ONCE_REWRITE_RULE[affine] AFFINE_AFFINE_HULL]]; + REPEAT STRIP_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL + [MATCH_MP_TAC HULL_MINIMAL THEN + SIMP_TAC[CONVEX_PCROSS; CONVEX_CONVEX_HULL; HULL_SUBSET; PCROSS_MONO]; + REWRITE_TAC[SUBSET; FORALL_IN_PCROSS] THEN + REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN + MATCH_MP_TAC HULL_INDUCT THEN CONJ_TAC THENL + [X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN + MATCH_MP_TAC HULL_INDUCT THEN CONJ_TAC THENL + [X_GEN_TAC `y:real^N` THEN DISCH_TAC THEN + SUBGOAL_THEN `pastecart (x:real^M) (y:real^N) IN s PCROSS t` MP_TAC + THENL [ASM_REWRITE_TAC[PASTECART_IN_PCROSS]; ALL_TAC] THEN + REWRITE_TAC[HULL_INC]; + ALL_TAC]; + REWRITE_TAC[GSYM lemma2] THEN MATCH_MP_TAC CONVEX_INTERS THEN + REWRITE_TAC[FORALL_IN_GSPEC]] THEN + SIMP_TAC[convex; IN_ELIM_THM; lemma1; + ONCE_REWRITE_RULE[convex] CONVEX_CONVEX_HULL]]]);; + +(* ------------------------------------------------------------------------- *) +(* Relations among closure notions and corresponding hulls. *) +(* ------------------------------------------------------------------------- *) + +let SUBSPACE_IMP_AFFINE = prove + (`!s. subspace s ==> affine s`, + REWRITE_TAC[subspace; affine] THEN MESON_TAC[]);; + +let AFFINE_IMP_CONVEX = prove + (`!s. affine s ==> convex s`, + REWRITE_TAC[affine; convex] THEN MESON_TAC[]);; + +let SUBSPACE_IMP_CONVEX = prove + (`!s. subspace s ==> convex s`, + MESON_TAC[SUBSPACE_IMP_AFFINE; AFFINE_IMP_CONVEX]);; + +let AFFINE_HULL_SUBSET_SPAN = prove + (`!s. (affine hull s) SUBSET (span s)`, + GEN_TAC THEN REWRITE_TAC[span] THEN MATCH_MP_TAC HULL_ANTIMONO THEN + REWRITE_TAC[SUBSET; IN; SUBSPACE_IMP_AFFINE]);; + +let CONVEX_HULL_SUBSET_SPAN = prove + (`!s. (convex hull s) SUBSET (span s)`, + GEN_TAC THEN REWRITE_TAC[span] THEN MATCH_MP_TAC HULL_ANTIMONO THEN + REWRITE_TAC[SUBSET; IN; SUBSPACE_IMP_CONVEX]);; + +let CONVEX_HULL_SUBSET_AFFINE_HULL = prove + (`!s. (convex hull s) SUBSET (affine hull s)`, + GEN_TAC THEN REWRITE_TAC[span] THEN MATCH_MP_TAC HULL_ANTIMONO THEN + REWRITE_TAC[SUBSET; IN; AFFINE_IMP_CONVEX]);; + +let COLLINEAR_CONVEX_HULL_COLLINEAR = prove + (`!s:real^N->bool. collinear(convex hull s) <=> collinear s`, + MESON_TAC[COLLINEAR_SUBSET; HULL_SUBSET; SUBSET_TRANS; + COLLINEAR_AFFINE_HULL_COLLINEAR; CONVEX_HULL_SUBSET_AFFINE_HULL]);; + +let AFFINE_SPAN = prove + (`!s. affine(span s)`, + SIMP_TAC[SUBSPACE_IMP_AFFINE; SUBSPACE_SPAN]);; + +let CONVEX_SPAN = prove + (`!s. convex(span s)`, + SIMP_TAC[SUBSPACE_IMP_CONVEX; SUBSPACE_SPAN]);; + +let AFFINE_EQ_SUBSPACE = prove + (`!s:real^N->bool. vec 0 IN s ==> (affine s <=> subspace s)`, + REPEAT STRIP_TAC THEN EQ_TAC THEN ASM_SIMP_TAC[subspace; affine] THEN + DISCH_TAC THEN MATCH_MP_TAC(TAUT `b /\ (b ==> a) ==> a /\ b`) THEN + CONJ_TAC THENL + [MAP_EVERY X_GEN_TAC [`c:real`; `x:real^N`] THEN STRIP_TAC THEN + SUBST1_TAC(VECTOR_ARITH `c % x:real^N = c % x + (&1 - c) % vec 0`) THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[] THEN REAL_ARITH_TAC; + DISCH_TAC THEN MAP_EVERY X_GEN_TAC [`x:real^N`; `y:real^N`] THEN + STRIP_TAC THEN SUBST1_TAC(VECTOR_ARITH + `x + y:real^N = &2 % (&1 / &2 % x + &1 / &2 % y)`) THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_REWRITE_TAC[] THEN REAL_ARITH_TAC]);; + +let AFFINE_IMP_SUBSPACE = prove + (`!s. affine s /\ vec 0 IN s ==> subspace s`, + SIMP_TAC[GSYM AFFINE_EQ_SUBSPACE]);; + +let AFFINE_HULL_EQ_SPAN = prove + (`!s:real^N->bool. (vec 0) IN affine hull s ==> affine hull s = span s`, + GEN_TAC THEN DISCH_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN + REWRITE_TAC[AFFINE_HULL_SUBSET_SPAN] THEN + REWRITE_TAC[SUBSET] THEN MATCH_MP_TAC SPAN_INDUCT THEN + ASM_REWRITE_TAC[SUBSET; subspace; IN_ELIM_THM; HULL_INC] THEN + REPEAT STRIP_TAC THENL + [SUBST1_TAC(VECTOR_ARITH + `x + y:real^N = &2 % (&1 / &2 % x + &1 / &2 % y) + --(&1) % vec 0`) THEN + MATCH_MP_TAC(REWRITE_RULE[affine] AFFINE_AFFINE_HULL) THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC(REWRITE_RULE[affine] AFFINE_AFFINE_HULL) THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN ASM_REWRITE_TAC[]; + SUBST1_TAC(VECTOR_ARITH + `c % x:real^N = c % x + (&1 - c) % vec 0`) THEN + MATCH_MP_TAC(REWRITE_RULE[affine] AFFINE_AFFINE_HULL) THEN + ASM_REWRITE_TAC[] THEN REAL_ARITH_TAC]);; + +let CLOSED_AFFINE = prove + (`!s:real^N->bool. affine s ==> closed s`, + GEN_TAC THEN ASM_CASES_TAC `s:real^N->bool = {}` THEN + ASM_REWRITE_TAC[CLOSED_EMPTY] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN + DISCH_THEN(X_CHOOSE_TAC `a:real^N`) THEN + SUBGOAL_THEN `affine (IMAGE (\x:real^N. --a + x) s) + ==> closed (IMAGE (\x:real^N. --a + x) s)` + MP_TAC THENL + [DISCH_THEN(fun th -> MATCH_MP_TAC CLOSED_SUBSPACE THEN MP_TAC th) THEN + MATCH_MP_TAC EQ_IMP THEN MATCH_MP_TAC AFFINE_EQ_SUBSPACE THEN + REWRITE_TAC[IN_IMAGE] THEN EXISTS_TAC `a:real^N` THEN + ASM_REWRITE_TAC[] THEN VECTOR_ARITH_TAC; + REWRITE_TAC[AFFINE_TRANSLATION_EQ; CLOSED_TRANSLATION_EQ]]);; + +let CLOSED_AFFINE_HULL = prove + (`!s. closed(affine hull s)`, + SIMP_TAC[CLOSED_AFFINE; AFFINE_AFFINE_HULL]);; + +let CLOSURE_SUBSET_AFFINE_HULL = prove + (`!s. closure s SUBSET affine hull s`, + GEN_TAC THEN MATCH_MP_TAC CLOSURE_MINIMAL THEN + REWRITE_TAC[CLOSED_AFFINE_HULL; HULL_SUBSET]);; + +let AFFINE_HULL_CLOSURE = prove + (`!s:real^N->bool. affine hull (closure s) = affine hull s`, + GEN_TAC THEN MATCH_MP_TAC HULL_UNIQUE THEN + REWRITE_TAC[CLOSURE_SUBSET_AFFINE_HULL; AFFINE_AFFINE_HULL] THEN + X_GEN_TAC `t:real^N->bool` THEN STRIP_TAC THEN + MATCH_MP_TAC HULL_MINIMAL THEN ASM_REWRITE_TAC[] THEN + ASM_MESON_TAC[CLOSURE_SUBSET; SUBSET]);; + +let AFFINE_HULL_EQ_SPAN_EQ = prove + (`!s:real^N->bool. (affine hull s = span s) <=> (vec 0) IN affine hull s`, + GEN_TAC THEN EQ_TAC THEN SIMP_TAC[SPAN_0; AFFINE_HULL_EQ_SPAN]);; + +let AFFINE_DEPENDENT_IMP_DEPENDENT = prove + (`!s. affine_dependent s ==> dependent s`, + REWRITE_TAC[affine_dependent; dependent] THEN + MESON_TAC[SUBSET; AFFINE_HULL_SUBSET_SPAN]);; + +let DEPENDENT_AFFINE_DEPENDENT_CASES = prove + (`!s:real^N->bool. + dependent s <=> affine_dependent s \/ (vec 0) IN affine hull s`, + REWRITE_TAC[DEPENDENT_EXPLICIT; AFFINE_DEPENDENT_EXPLICIT; + AFFINE_HULL_EXPLICIT_ALT; IN_ELIM_THM] THEN + GEN_TAC THEN ONCE_REWRITE_TAC[OR_EXISTS_THM] THEN + AP_TERM_TAC THEN GEN_REWRITE_TAC I [FUN_EQ_THM] THEN + X_GEN_TAC `t:real^N->bool` THEN + ASM_CASES_TAC `FINITE(t:real^N->bool)` THEN ASM_REWRITE_TAC[] THEN + EQ_TAC THEN DISCH_THEN(REPEAT_TCL DISJ_CASES_THEN + (X_CHOOSE_THEN `u:real^N->real` STRIP_ASSUME_TAC)) + THENL + [ASM_CASES_TAC `sum t (u:real^N->real) = &0` THENL + [ASM_MESON_TAC[]; ALL_TAC] THEN + DISJ2_TAC THEN EXISTS_TAC `\v:real^N. inv(sum t u) * u v` THEN + ASM_SIMP_TAC[SUM_LMUL; VSUM_LMUL; GSYM VECTOR_MUL_ASSOC] THEN + ASM_SIMP_TAC[VECTOR_MUL_RZERO; REAL_MUL_LINV]; + EXISTS_TAC `u:real^N->real` THEN ASM_MESON_TAC[]; + EXISTS_TAC `u:real^N->real` THEN + ASM_REWRITE_TAC[SET_RULE + `(?v. v IN t /\ ~p v) <=> ~(!v. v IN t ==> p v)`] THEN + DISCH_TAC THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH + `x = &1 ==> x = &0 ==> F`)) THEN + ASM_MESON_TAC[SUM_EQ_0]]);; + +let DEPENDENT_IMP_AFFINE_DEPENDENT = prove + (`!a:real^N s. dependent {x - a | x IN s} /\ ~(a IN s) + ==> affine_dependent(a INSERT s)`, + REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN + REWRITE_TAC[DEPENDENT_EXPLICIT; AFFINE_DEPENDENT_EXPLICIT] THEN + REWRITE_TAC[SIMPLE_IMAGE; CONJ_ASSOC; FINITE_SUBSET_IMAGE] THEN + REWRITE_TAC[LEFT_AND_EXISTS_THM] THEN REWRITE_TAC[GSYM CONJ_ASSOC] THEN + GEN_REWRITE_TAC LAND_CONV [SWAP_EXISTS_THM] THEN + GEN_REWRITE_TAC (LAND_CONV o BINDER_CONV) [SWAP_EXISTS_THM] THEN + REWRITE_TAC[TAUT `a /\ x = IMAGE f s /\ b <=> x = IMAGE f s /\ a /\ b`] THEN + REWRITE_TAC[UNWIND_THM2; EXISTS_IN_IMAGE] THEN + DISCH_THEN(X_CHOOSE_THEN `u:real^N->real` (X_CHOOSE_THEN `t:real^N->bool` + STRIP_ASSUME_TAC)) THEN + FIRST_X_ASSUM(MP_TAC o check (is_eq o concl)) THEN + ASM_SIMP_TAC[VSUM_IMAGE; VECTOR_ARITH `x - a:real^N = y - a <=> x = y`] THEN + ASM_SIMP_TAC[o_DEF; VECTOR_SUB_LDISTRIB; VSUM_SUB; VSUM_RMUL] THEN + STRIP_TAC THEN + MAP_EVERY EXISTS_TAC + [`(a:real^N) INSERT t`; + `\x. if x = a then --sum t (\x. u (x - a)) + else (u:real^N->real) (x - a)`] THEN + ASM_REWRITE_TAC[FINITE_INSERT; SUBSET_REFL] THEN + ASM_SIMP_TAC[SUM_CLAUSES; VSUM_CLAUSES] THEN + CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[] THENL [ASM SET_TAC[]; ALL_TAC] THEN + REPEAT CONJ_TAC THENL + [MATCH_MP_TAC(REAL_ARITH `x = y ==> --x + y = &0`) THEN + MATCH_MP_TAC SUM_EQ THEN ASM_MESON_TAC[]; + EXISTS_TAC `x:real^N` THEN CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN ASM_MESON_TAC[]; + MATCH_MP_TAC(VECTOR_ARITH + `!s. s - t % a = vec 0 /\ s = u ==> --t % a + u = vec 0`) THEN + EXISTS_TAC `vsum t (\x:real^N. u(x - a) % x)` THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC VSUM_EQ THEN + REPEAT STRIP_TAC THEN REWRITE_TAC[] THEN COND_CASES_TAC THEN + ASM_REWRITE_TAC[] THEN ASM_MESON_TAC[]]);; + +let AFFINE_DEPENDENT_BIGGERSET = prove + (`!s:real^N->bool. + (FINITE s ==> CARD s >= dimindex(:N) + 2) ==> affine_dependent s`, + GEN_TAC THEN ASM_CASES_TAC `s:real^N->bool = {}` THEN + ASM_SIMP_TAC[CARD_CLAUSES; ARITH_RULE `~(0 >= n + 2)`; FINITE_RULES] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN + DISCH_THEN(X_CHOOSE_TAC `a:real^N`) THEN + FIRST_ASSUM(SUBST1_TAC o MATCH_MP (SET_RULE + `x IN s ==> s = x INSERT (s DELETE x)`)) THEN + SIMP_TAC[FINITE_INSERT; CARD_CLAUSES; IN_DELETE] THEN + REWRITE_TAC[ARITH_RULE `SUC x >= n + 2 <=> x > n`] THEN DISCH_TAC THEN + MATCH_MP_TAC DEPENDENT_IMP_AFFINE_DEPENDENT THEN + REWRITE_TAC[IN_DELETE] THEN MATCH_MP_TAC DEPENDENT_BIGGERSET THEN + REWRITE_TAC[SET_RULE `{x - a:real^N | x | x IN s /\ ~(x = a)} = + IMAGE (\x. x - a) (s DELETE a)`] THEN + ASM_SIMP_TAC[FINITE_IMAGE_INJ_EQ; + VECTOR_ARITH `x - a = y - a <=> x:real^N = y`; + CARD_IMAGE_INJ]);; + +let AFFINE_DEPENDENT_BIGGERSET_GENERAL = prove + (`!s:real^N->bool. (FINITE s ==> CARD s >= dim s + 2) ==> affine_dependent s`, + GEN_TAC THEN ASM_CASES_TAC `s:real^N->bool = {}` THEN + ASM_SIMP_TAC[CARD_CLAUSES; ARITH_RULE `~(0 >= n + 2)`; FINITE_RULES] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN + DISCH_THEN(X_CHOOSE_TAC `a:real^N`) THEN + FIRST_ASSUM(SUBST1_TAC o MATCH_MP (SET_RULE + `x IN s ==> s = x INSERT (s DELETE x)`)) THEN + SIMP_TAC[FINITE_INSERT; CARD_CLAUSES; IN_DELETE] THEN + REWRITE_TAC[ARITH_RULE `SUC x >= n + 2 <=> x > n`] THEN DISCH_TAC THEN + MATCH_MP_TAC DEPENDENT_IMP_AFFINE_DEPENDENT THEN + REWRITE_TAC[IN_DELETE] THEN + MATCH_MP_TAC DEPENDENT_BIGGERSET_GENERAL THEN + REWRITE_TAC[SET_RULE `{x - a:real^N | x | x IN s /\ ~(x = a)} = + IMAGE (\x. x - a) (s DELETE a)`] THEN + ASM_SIMP_TAC[FINITE_IMAGE_INJ_EQ; FINITE_DELETE; + VECTOR_ARITH `x - a = y - a <=> x:real^N = y`; + CARD_IMAGE_INJ] THEN + DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o check(is_imp o concl)) THEN + ASM_REWRITE_TAC[FINITE_DELETE] THEN + MATCH_MP_TAC(ARITH_RULE `c:num <= b ==> (a > b ==> a > c)`) THEN + MATCH_MP_TAC SUBSET_LE_DIM THEN REWRITE_TAC[SUBSET; FORALL_IN_IMAGE] THEN + SIMP_TAC[SPAN_SUB; SPAN_SUPERSET; IN_INSERT]);; + +let AFFINE_INDEPENDENT_IMP_FINITE = prove + (`!s:real^N->bool. ~(affine_dependent s) ==> FINITE s`, + MESON_TAC[AFFINE_DEPENDENT_BIGGERSET]);; + +let AFFINE_INDEPENDENT_CARD_LE = prove + (`!s:real^N->bool. ~(affine_dependent s) ==> CARD s <= dimindex(:N) + 1`, + REWRITE_TAC[ARITH_RULE `s <= n + 1 <=> ~(n + 2 <= s)`; CONTRAPOS_THM] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC AFFINE_DEPENDENT_BIGGERSET THEN + ASM_REWRITE_TAC[GE]);; + +let AFFINE_INDEPENDENT_CONVEX_AFFINE_HULL = prove + (`!s t:real^N->bool. + ~affine_dependent s /\ t SUBSET s + ==> convex hull t = affine hull t INTER convex hull s`, + REPEAT STRIP_TAC THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP AFFINE_INDEPENDENT_IMP_FINITE) THEN + SUBGOAL_THEN `FINITE(t:real^N->bool)` ASSUME_TAC THENL + [ASM_MESON_TAC[FINITE_SUBSET]; ALL_TAC] THEN + MATCH_MP_TAC(SET_RULE + `ct SUBSET a /\ ct SUBSET cs /\ a INTER cs SUBSET ct + ==> ct = a INTER cs`) THEN + ASM_SIMP_TAC[HULL_MONO; CONVEX_HULL_SUBSET_AFFINE_HULL] THEN + REWRITE_TAC[SUBSET; IN_INTER; CONVEX_HULL_FINITE; AFFINE_HULL_FINITE] THEN + X_GEN_TAC `y:real^N` THEN REWRITE_TAC[IN_ELIM_THM] THEN + DISCH_THEN(CONJUNCTS_THEN2 + (X_CHOOSE_THEN `u:real^N->real` STRIP_ASSUME_TAC) + (X_CHOOSE_THEN `v:real^N->real` STRIP_ASSUME_TAC)) THEN + EXISTS_TAC `u:real^N->real` THEN ASM_REWRITE_TAC[] THEN + X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE RAND_CONV + [AFFINE_DEPENDENT_EXPLICIT]) THEN + REWRITE_TAC[NOT_EXISTS_THM] THEN + DISCH_THEN(MP_TAC o SPECL [`s:real^N->bool`; + `\x:real^N. if x IN t then v x - u x:real else v x`]) THEN + ASM_REWRITE_TAC[SUBSET_REFL] THEN REWRITE_TAC[MESON[] + `(if p then a else b) % x = if p then a % x else b % x`] THEN + ASM_SIMP_TAC[VSUM_CASES; SUM_CASES; SET_RULE + `t SUBSET s ==> {x | x IN s /\ x IN t} = t`] THEN + ASM_SIMP_TAC[GSYM DIFF; SUM_DIFF; VSUM_DIFF; VECTOR_SUB_RDISTRIB; + SUM_SUB; VSUM_SUB] THEN + REWRITE_TAC[REAL_ARITH `a - b + b - a = &0`; NOT_EXISTS_THM; + VECTOR_ARITH `a - b + b - a:real^N = vec 0`] THEN + DISCH_THEN(MP_TAC o SPEC `x:real^N`) THEN + ASM_REWRITE_TAC[REAL_SUB_0] THEN ASM SET_TAC[]);; + +let DISJOINT_AFFINE_HULL = prove + (`!s t u:real^N->bool. + ~affine_dependent s /\ t SUBSET s /\ u SUBSET s /\ DISJOINT t u + ==> DISJOINT (affine hull t) (affine hull u)`, + REPEAT STRIP_TAC THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP AFFINE_INDEPENDENT_IMP_FINITE) THEN + SUBGOAL_THEN `FINITE(t:real^N->bool) /\ FINITE (u:real^N->bool)` ASSUME_TAC + THENL [ASM_MESON_TAC[FINITE_SUBSET]; ALL_TAC] THEN + REWRITE_TAC[IN_DISJOINT; AFFINE_HULL_FINITE; IN_ELIM_THM] THEN + DISCH_THEN(X_CHOOSE_THEN `y:real^N` MP_TAC) THEN + DISCH_THEN(CONJUNCTS_THEN2 + (X_CHOOSE_THEN `a:real^N->real` STRIP_ASSUME_TAC) + (X_CHOOSE_THEN `b:real^N->real` STRIP_ASSUME_TAC)) THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE RAND_CONV + [AFFINE_DEPENDENT_EXPLICIT]) THEN + REWRITE_TAC[NOT_EXISTS_THM] THEN + MAP_EVERY EXISTS_TAC + [`s:real^N->bool`; + `\x:real^N. if x IN t then a x else if x IN u then --(b x) else &0`] THEN + ASM_REWRITE_TAC[SUBSET_REFL] THEN REWRITE_TAC[MESON[] + `(if p then a else b) % x = if p then a % x else b % x`] THEN + ASM_SIMP_TAC[SUM_CASES; SUBSET_REFL; VSUM_CASES; GSYM DIFF; SUM_DIFF; + VSUM_DIFF; SET_RULE `t SUBSET s ==> {x | x IN s /\ x IN t} = t`] THEN + ASM_SIMP_TAC[SUM_0; VSUM_0; VECTOR_MUL_LZERO; SUM_NEG; VSUM_NEG; + VECTOR_MUL_LNEG; SET_RULE `DISJOINT t u ==> ~(x IN t /\ x IN u)`] THEN + REWRITE_TAC[EMPTY_GSPEC; SUM_CLAUSES; VSUM_CLAUSES] THEN + CONJ_TAC THENL [REAL_ARITH_TAC; ALL_TAC] THEN + CONJ_TAC THENL [ALL_TAC; VECTOR_ARITH_TAC] THEN + UNDISCH_TAC `sum t (a:real^N->real) = &1` THEN + ASM_CASES_TAC `!x:real^N. x IN t ==> a x = &0` THEN + ASM_SIMP_TAC[SUM_EQ_0; REAL_OF_NUM_EQ; ARITH_EQ] THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [NOT_FORALL_THM]) THEN + MATCH_MP_TAC MONO_EXISTS THEN ASM SET_TAC[]);; + +let AFFINE_INDEPENDENT_SPAN_EQ = prove + (`!s. ~(affine_dependent s) /\ CARD s = dimindex(:N) + 1 + ==> affine hull s = (:real^N)`, + MATCH_MP_TAC SET_PROVE_CASES THEN + REWRITE_TAC[CARD_CLAUSES; ARITH_RULE `~(0 = n + 1)`] THEN + SIMP_TAC[IMP_CONJ; AFFINE_INDEPENDENT_IMP_FINITE; MESON[HAS_SIZE] + `FINITE s ==> (CARD s = n <=> s HAS_SIZE n)`] THEN + X_GEN_TAC `orig:real^N` THEN GEOM_ORIGIN_TAC `orig:real^N` THEN + SIMP_TAC[AFFINE_HULL_EQ_SPAN; IN_INSERT; SPAN_INSERT_0; HULL_INC] THEN + SIMP_TAC[HAS_SIZE; CARD_CLAUSES; FINITE_INSERT; IMP_CONJ] THEN + REWRITE_TAC[ARITH_RULE `SUC n = m + 1 <=> n = m`; GSYM UNIV_SUBSET] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC CARD_GE_DIM_INDEPENDENT THEN + ASM_REWRITE_TAC[DIM_UNIV; SUBSET_UNIV; LE_REFL; independent] THEN + UNDISCH_TAC `~affine_dependent((vec 0:real^N) INSERT s)` THEN + REWRITE_TAC[CONTRAPOS_THM] THEN DISCH_TAC THEN + MATCH_MP_TAC DEPENDENT_IMP_AFFINE_DEPENDENT THEN + ASM_REWRITE_TAC[VECTOR_SUB_RZERO; SET_RULE `{x | x IN s} = s`]);; + +let AFFINE_INDEPENDENT_SPAN_GT = prove + (`!s:real^N->bool. + ~(affine_dependent s) /\ dimindex(:N) < CARD s + ==> affine hull s = (:real^N)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC AFFINE_INDEPENDENT_SPAN_EQ THEN + ASM_REWRITE_TAC[] THEN + MP_TAC(SPEC `s:real^N->bool` AFFINE_DEPENDENT_BIGGERSET) THEN + ASM_SIMP_TAC[AFFINE_INDEPENDENT_IMP_FINITE] THEN ASM_ARITH_TAC);; + +let EMPTY_INTERIOR_AFFINE_HULL = prove + (`!s:real^N->bool. + FINITE s /\ CARD(s) <= dimindex(:N) + ==> interior(affine hull s) = {}`, + REWRITE_TAC[IMP_CONJ] THEN MATCH_MP_TAC FINITE_INDUCT_STRONG THEN + REWRITE_TAC[AFFINE_HULL_EMPTY; INTERIOR_EMPTY] THEN + SUBGOAL_THEN + `!x s:real^N->bool n. + ~(x IN s) /\ (x INSERT s) HAS_SIZE n /\ n <= dimindex(:N) + ==> interior(affine hull(x INSERT s)) = {}` + (fun th -> MESON_TAC[th; HAS_SIZE; FINITE_INSERT]) THEN + X_GEN_TAC `orig:real^N` THEN GEOM_ORIGIN_TAC `orig:real^N` THEN + SIMP_TAC[AFFINE_HULL_EQ_SPAN; IN_INSERT; SPAN_INSERT_0; HULL_INC] THEN + REWRITE_TAC[HAS_SIZE; FINITE_INSERT; IMP_CONJ] THEN + SIMP_TAC[CARD_CLAUSES] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC EMPTY_INTERIOR_LOWDIM THEN + MATCH_MP_TAC LET_TRANS THEN EXISTS_TAC `CARD(s:real^N->bool)` THEN + ASM_SIMP_TAC[DIM_LE_CARD; DIM_SPAN] THEN ASM_ARITH_TAC);; + +let EMPTY_INTERIOR_CONVEX_HULL = prove + (`!s:real^N->bool. + FINITE s /\ CARD(s) <= dimindex(:N) + ==> interior(convex hull s) = {}`, + REPEAT STRIP_TAC THEN + MATCH_MP_TAC(SET_RULE `!t. s SUBSET t /\ t = {} ==> s = {}`) THEN + EXISTS_TAC `interior(affine hull s):real^N->bool` THEN + SIMP_TAC[SUBSET_INTERIOR; CONVEX_HULL_SUBSET_AFFINE_HULL] THEN + ASM_SIMP_TAC[EMPTY_INTERIOR_AFFINE_HULL]);; + +let AFFINE_DEPENDENT_CHOOSE = prove + (`!s a:real^N. + ~(affine_dependent s) + ==> (affine_dependent(a INSERT s) <=> ~(a IN s) /\ a IN affine hull s)`, + REPEAT STRIP_TAC THEN ASM_CASES_TAC `(a:real^N) IN s` THEN + ASM_SIMP_TAC[SET_RULE `a IN s ==> a INSERT s = s`] THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP AFFINE_INDEPENDENT_IMP_FINITE) THEN + EQ_TAC THENL + [UNDISCH_TAC `~(affine_dependent(s:real^N->bool))` THEN + ASM_SIMP_TAC[AFFINE_DEPENDENT_EXPLICIT_FINITE; AFFINE_HULL_FINITE; + FINITE_INSERT; IN_ELIM_THM; SUM_CLAUSES; VSUM_CLAUSES] THEN + DISCH_TAC THEN REWRITE_TAC[EXISTS_IN_INSERT] THEN + DISCH_THEN(X_CHOOSE_THEN `u:real^N->real` MP_TAC) THEN + ASM_CASES_TAC `(u:real^N->real) a = &0` THEN ASM_REWRITE_TAC[] THENL + [REWRITE_TAC[REAL_ADD_LID; VECTOR_MUL_LZERO; VECTOR_ADD_LID] THEN + DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [NOT_EXISTS_THM]) THEN + DISCH_THEN(MP_TAC o SPEC `u:real^N->real`) THEN ASM_REWRITE_TAC[]; + ONCE_REWRITE_TAC[REAL_ARITH `ua + sa = &0 <=> sa = --ua`; + VECTOR_ARITH `va + sa:real^N = vec 0 <=> sa = --va`] THEN + STRIP_TAC THEN EXISTS_TAC `(\x. --(inv(u a)) * u x):real^N->real` THEN + ASM_SIMP_TAC[SUM_LMUL; GSYM VECTOR_MUL_ASSOC; VSUM_LMUL] THEN + ASM_REWRITE_TAC[VECTOR_MUL_ASSOC; GSYM VECTOR_MUL_LNEG] THEN + REWRITE_TAC[REAL_ARITH `--a * --b:real = a * b`] THEN + ASM_SIMP_TAC[REAL_MUL_LINV; VECTOR_MUL_LID]]; + DISCH_TAC THEN REWRITE_TAC[affine_dependent] THEN + EXISTS_TAC `a:real^N` THEN + ASM_SIMP_TAC[IN_INSERT; SET_RULE + `~(a IN s) ==> (a INSERT s) DELETE a = s`]]);; + +let AFFINE_INDEPENDENT_INSERT = prove + (`!s a:real^N. + ~(affine_dependent s) /\ ~(a IN affine hull s) + ==> ~(affine_dependent(a INSERT s))`, + SIMP_TAC[AFFINE_DEPENDENT_CHOOSE]);; + +let AFFINE_HULL_EXPLICIT_UNIQUE = prove + (`!s:real^N->bool u u'. + ~(affine_dependent s) /\ + sum s u = &1 /\ sum s u' = &1 /\ + vsum s (\x. u x % x) = vsum s (\x. u' x % x) + ==> !x. x IN s ==> u x = u' x`, + REPEAT GEN_TAC THEN STRIP_TAC THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP AFFINE_INDEPENDENT_IMP_FINITE) THEN + FIRST_ASSUM(MP_TAC o MATCH_MP AFFINE_DEPENDENT_EXPLICIT_FINITE) THEN + ASM_REWRITE_TAC[NOT_EXISTS_THM] THEN + DISCH_THEN(MP_TAC o SPEC `(\x. u x - u' x):real^N->real`) THEN + ASM_SIMP_TAC[VSUM_SUB; SUM_SUB; REAL_SUB_REFL; VECTOR_SUB_RDISTRIB; + VECTOR_SUB_REFL; VECTOR_SUB_EQ; REAL_SUB_0] THEN + MESON_TAC[]);; + +let INDEPENDENT_IMP_AFFINE_DEPENDENT_0 = prove + (`!s. independent s ==> ~(affine_dependent(vec 0 INSERT s))`, + REWRITE_TAC[independent; DEPENDENT_AFFINE_DEPENDENT_CASES] THEN + SIMP_TAC[DE_MORGAN_THM; AFFINE_INDEPENDENT_INSERT]);; + +let AFFINE_INDEPENDENT_STDBASIS = prove + (`~(affine_dependent + ((vec 0:real^N) INSERT {basis i | 1 <= i /\ i <= dimindex (:N)}))`, + SIMP_TAC[INDEPENDENT_IMP_AFFINE_DEPENDENT_0; INDEPENDENT_STDBASIS]);; + +(* ------------------------------------------------------------------------- *) +(* Nonempty affine sets are translates of (unique) subspaces. *) +(* ------------------------------------------------------------------------- *) + +let AFFINE_TRANSLATION_SUBSPACE = prove + (`!t:real^N->bool. + affine t /\ ~(t = {}) <=> ?a s. subspace s /\ t = IMAGE (\x. a + x) s`, + GEN_TAC THEN EQ_TAC THEN STRIP_TAC THEN + ASM_SIMP_TAC[SUBSPACE_IMP_NONEMPTY; IMAGE_EQ_EMPTY; + AFFINE_TRANSLATION; SUBSPACE_IMP_AFFINE] THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `a:real^N` THEN DISCH_TAC THEN + ONCE_REWRITE_TAC[TRANSLATION_GALOIS] THEN ONCE_REWRITE_TAC[CONJ_SYM] THEN + REWRITE_TAC[UNWIND_THM2] THEN MATCH_MP_TAC AFFINE_IMP_SUBSPACE THEN + ASM_REWRITE_TAC[AFFINE_TRANSLATION_EQ; IN_IMAGE] THEN + EXISTS_TAC `a:real^N` THEN ASM_REWRITE_TAC[] THEN VECTOR_ARITH_TAC);; + +let AFFINE_TRANSLATION_UNIQUE_SUBSPACE = prove + (`!t:real^N->bool. + affine t /\ ~(t = {}) <=> + ?!s. ?a. subspace s /\ t = IMAGE (\x. a + x) s`, + GEN_TAC THEN REWRITE_TAC[AFFINE_TRANSLATION_SUBSPACE] THEN + MATCH_MP_TAC(MESON[] + `(!a a' s s'. P s a /\ P s' a' ==> s = s') + ==> ((?a s. P s a) <=> (?!s. ?a. P s a))`) THEN + REPEAT GEN_TAC THEN + REPEAT(DISCH_THEN(CONJUNCTS_THEN2 STRIP_ASSUME_TAC MP_TAC)) THEN + DISCH_THEN(fun th -> ASSUME_TAC th THEN MP_TAC th) THEN + ASM_REWRITE_TAC[] THEN ONCE_REWRITE_TAC[TRANSLATION_GALOIS] THEN + DISCH_THEN SUBST1_TAC THEN CONV_TAC SYM_CONV THEN + REWRITE_TAC[GSYM IMAGE_o; o_DEF; VECTOR_ADD_ASSOC] THEN + MATCH_MP_TAC SUBSPACE_TRANSLATION_SELF THEN ASM_REWRITE_TAC[] THEN + ONCE_REWRITE_TAC[VECTOR_ARITH `--a' + a:real^N = --(a' - a)`] THEN + MATCH_MP_TAC SUBSPACE_NEG THEN ASM_REWRITE_TAC[] THEN + UNDISCH_TAC `t = IMAGE (\x:real^N. a' + x) s'` THEN + DISCH_THEN(MP_TAC o AP_TERM `\s. (a':real^N) IN s`) THEN + REWRITE_TAC[IN_IMAGE; VECTOR_ARITH `a:real^N = a + x <=> x = vec 0`] THEN + ASM_SIMP_TAC[UNWIND_THM2; SUBSPACE_0] THEN + REWRITE_TAC[IN_IMAGE; VECTOR_ARITH `a':real^N = a + x <=> x = a' - a`] THEN + REWRITE_TAC[UNWIND_THM2]);; + +let AFFINE_TRANSLATION_SUBSPACE_EXPLICIT = prove + (`!t:real^N->bool a. + affine t /\ a IN t + ==> subspace {x - a | x IN t} /\ + t = IMAGE (\x. a + x) {x - a | x IN t}`, + REPEAT STRIP_TAC THEN ASM_SIMP_TAC[AFFINE_DIFFS_SUBSPACE] THEN + ASM_REWRITE_TAC[SIMPLE_IMAGE; GSYM IMAGE_o] THEN + REWRITE_TAC[o_DEF; VECTOR_SUB_ADD2; IMAGE_ID]);; + +(* ------------------------------------------------------------------------- *) +(* If we take a slice out of a set, we can do it perpendicularly, *) +(* with the normal vector to the slice parallel to the affine hull. *) +(* ------------------------------------------------------------------------- *) + +let AFFINE_PARALLEL_SLICE = prove + (`!s a:real^N b. + affine s + ==> s INTER {x | a dot x <= b} = {} \/ s SUBSET {x | a dot x <= b} \/ + ?a' b'. ~(a' = vec 0) /\ + + s INTER {x | a' dot x <= b'} = s INTER {x | a dot x <= b} /\ + s INTER {x | a' dot x = b'} = s INTER {x | a dot x = b} /\ + !w. w IN s ==> (w + a') IN s`, + REPEAT STRIP_TAC THEN + ASM_CASES_TAC `s INTER {x:real^N | a dot x = b} = {}` THENL + [MATCH_MP_TAC(TAUT `~(~p /\ ~q) ==> p \/ q \/ r`) THEN + REPEAT STRIP_TAC THEN SUBGOAL_THEN + `?u v:real^N. u IN s /\ v IN s /\ + a dot u <= b /\ ~(a dot v <= b)` + STRIP_ASSUME_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + SUBGOAL_THEN `(a:real^N) dot u < b` ASSUME_TAC THENL + [ASM_REWRITE_TAC[REAL_LT_LE] THEN ASM SET_TAC[]; ALL_TAC] THEN + RULE_ASSUM_TAC(REWRITE_RULE[REAL_NOT_LE]) THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [EXTENSION]) THEN + REWRITE_TAC[NOT_IN_EMPTY; IN_INTER; NOT_FORALL_THM; IN_ELIM_THM] THEN + EXISTS_TAC + `u + (b - a dot u) / (a dot v - a dot u) % (v - u):real^N` THEN + ASM_SIMP_TAC[IN_AFFINE_ADD_MUL_DIFF] THEN + REWRITE_TAC[DOT_RADD; DOT_RMUL; DOT_RSUB] THEN + REPEAT(POP_ASSUM MP_TAC) THEN CONV_TAC REAL_FIELD; + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN + DISCH_THEN(X_CHOOSE_THEN `z:real^N` MP_TAC) THEN + REWRITE_TAC[IN_INTER; IN_ELIM_THM] THEN POP_ASSUM MP_TAC THEN + GEN_GEOM_ORIGIN_TAC `z:real^N` ["a"; "a'"; "b'"; "w"] THEN + REPEAT STRIP_TAC THEN FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN + REWRITE_TAC[VECTOR_ADD_RID; FORALL_IN_IMAGE] THEN + REWRITE_TAC[DOT_RADD; REAL_ARITH `a + x <= a <=> x <= &0`] THEN + SUBGOAL_THEN `subspace(s:real^N->bool) /\ span s = s` + STRIP_ASSUME_TAC THENL + [ASM_MESON_TAC[AFFINE_IMP_SUBSPACE; SPAN_EQ_SELF]; ALL_TAC] THEN + MP_TAC(ISPECL [`s:real^N->bool`; `a:real^N`] + ORTHOGONAL_SUBSPACE_DECOMP_EXISTS) THEN + ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM; orthogonal] THEN + MAP_EVERY X_GEN_TAC [`a':real^N`; `a'':real^N`] THEN + ASM_CASES_TAC `a':real^N = vec 0` THENL + [ASM_REWRITE_TAC[VECTOR_ADD_LID] THEN + ASM_CASES_TAC `a'':real^N = a` THEN ASM_REWRITE_TAC[] THEN + SIMP_TAC[SUBSET; IN_ELIM_THM; REAL_LE_REFL]; + ALL_TAC] THEN + STRIP_TAC THEN REPEAT DISJ2_TAC THEN + EXISTS_TAC `a':real^N` THEN ASM_REWRITE_TAC[] THEN + EXISTS_TAC `(a':real^N) dot z` THEN + REPEAT(CONJ_TAC THENL + [MATCH_MP_TAC(SET_RULE + `(!x. x IN s ==> (p x <=> q x)) + ==> s INTER {x | p x} = s INTER {x | q x}`) THEN + ASM_SIMP_TAC[DOT_LADD] THEN REAL_ARITH_TAC; + ALL_TAC]) THEN + X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN REWRITE_TAC[IN_IMAGE] THEN + EXISTS_TAC `x + a':real^N` THEN + ASM_SIMP_TAC[SUBSPACE_ADD; VECTOR_ADD_ASSOC]]);; + +(* ------------------------------------------------------------------------- *) +(* Affine dimension. *) +(* ------------------------------------------------------------------------- *) + +let MAXIMAL_AFFINE_INDEPENDENT_SUBSET = prove + (`!s b:real^N->bool. + b SUBSET s /\ ~(affine_dependent b) /\ + (!b'. b SUBSET b' /\ b' SUBSET s /\ ~(affine_dependent b') ==> b' = b) + ==> s SUBSET (affine hull b)`, + REPEAT STRIP_TAC THEN + MATCH_MP_TAC(SET_RULE `(!a. a IN t /\ ~(a IN s) ==> F) ==> t SUBSET s`) THEN + X_GEN_TAC `a:real^N` THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `(a:real^N) INSERT b`) THEN + FIRST_ASSUM(MP_TAC o MATCH_MP + (ONCE_REWRITE_RULE[GSYM CONTRAPOS_THM] HULL_INC)) THEN + ASM_SIMP_TAC[AFFINE_INDEPENDENT_INSERT; INSERT_SUBSET] THEN + ASM SET_TAC[]);; + +let MAXIMAL_AFFINE_INDEPENDENT_SUBSET_AFFINE = prove + (`!s b:real^N->bool. + affine s /\ b SUBSET s /\ ~(affine_dependent b) /\ + (!b'. b SUBSET b' /\ b' SUBSET s /\ ~(affine_dependent b') ==> b' = b) + ==> affine hull b = s`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL + [ASM_MESON_TAC[HULL_MONO; HULL_P]; + ASM_MESON_TAC[MAXIMAL_AFFINE_INDEPENDENT_SUBSET]]);; + +let EXTEND_TO_AFFINE_BASIS = prove + (`!s u:real^N->bool. + ~(affine_dependent s) /\ s SUBSET u + ==> ?t. ~(affine_dependent t) /\ s SUBSET t /\ t SUBSET u /\ + affine hull t = affine hull u`, + REPEAT STRIP_TAC THEN + MP_TAC(SPEC `\n. ?t:real^N->bool. ~(affine_dependent t) /\ s SUBSET t /\ + t SUBSET u /\ CARD t = n` + num_MAX) THEN + DISCH_THEN(MP_TAC o fst o EQ_IMP_RULE) THEN REWRITE_TAC[] THEN ANTS_TAC THENL + [ASM_MESON_TAC[SUBSET_REFL; AFFINE_INDEPENDENT_CARD_LE]; ALL_TAC] THEN + DISCH_THEN(X_CHOOSE_THEN `n:num` (CONJUNCTS_THEN2 MP_TAC ASSUME_TAC)) THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `t:real^N->bool` THEN STRIP_TAC THEN + ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL + [ASM_MESON_TAC[HULL_MONO; HULL_P]; ALL_TAC] THEN + MATCH_MP_TAC HULL_MINIMAL THEN REWRITE_TAC[AFFINE_AFFINE_HULL] THEN + MATCH_MP_TAC MAXIMAL_AFFINE_INDEPENDENT_SUBSET THEN ASM_REWRITE_TAC[] THEN + X_GEN_TAC `c:real^N->bool` THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `CARD(c:real^N->bool)`) THEN + REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + DISCH_THEN(MP_TAC o SPEC `c:real^N->bool`) THEN + ANTS_TAC THENL [ASM SET_TAC[]; DISCH_TAC] THEN + CONV_TAC SYM_CONV THEN MATCH_MP_TAC CARD_SUBSET_LE THEN + ASM_MESON_TAC[AFFINE_INDEPENDENT_IMP_FINITE]);; + +let AFFINE_BASIS_EXISTS = prove + (`!s:real^N->bool. + ?b. ~(affine_dependent b) /\ b SUBSET s /\ + affine hull b = affine hull s`, + GEN_TAC THEN + MP_TAC(ISPECL [`{}:real^N->bool`; `s:real^N->bool`] + EXTEND_TO_AFFINE_BASIS) THEN + REWRITE_TAC[AFFINE_INDEPENDENT_EMPTY; EMPTY_SUBSET]);; + +let aff_dim = new_definition + `aff_dim s = + @d:int. ?b. affine hull b = affine hull s /\ ~(affine_dependent b) /\ + &(CARD b) = d + &1`;; + +let AFF_DIM = prove + (`!s. ?b. affine hull b = affine hull s /\ + ~(affine_dependent b) /\ + aff_dim s = &(CARD b) - &1`, + GEN_TAC THEN + REWRITE_TAC[aff_dim; INT_ARITH `y:int = x + &1 <=> x = y - &1`] THEN + CONV_TAC SELECT_CONV THEN ONCE_REWRITE_TAC[SWAP_EXISTS_THM] THEN + REWRITE_TAC[RIGHT_EXISTS_AND_THM; EXISTS_REFL] THEN + MESON_TAC[AFFINE_BASIS_EXISTS]);; + +let AFF_DIM_EMPTY = prove + (`aff_dim {} = -- &1`, + REWRITE_TAC[aff_dim; AFFINE_HULL_EMPTY; AFFINE_HULL_EQ_EMPTY] THEN + REWRITE_TAC[UNWIND_THM2; AFFINE_INDEPENDENT_EMPTY; CARD_CLAUSES] THEN + REWRITE_TAC[INT_ARITH `&0 = d + &1 <=> d:int = -- &1`; SELECT_REFL]);; + +let AFF_DIM_AFFINE_HULL = prove + (`!s. aff_dim(affine hull s) = aff_dim s`, + REWRITE_TAC[aff_dim; HULL_HULL]);; + +let AFF_DIM_TRANSLATION_EQ = prove + (`!a:real^N s. aff_dim (IMAGE (\x. a + x) s) = aff_dim s`, + REWRITE_TAC[aff_dim] THEN GEOM_TRANSLATE_TAC[] THEN + ONCE_REWRITE_TAC[TAUT `a /\ b /\ c <=> ~(a /\ b ==> ~c)`] THEN + SIMP_TAC[AFFINE_INDEPENDENT_IMP_FINITE; CARD_IMAGE_INJ; + VECTOR_ARITH `a + x:real^N = a + y <=> x = y`]);; + +add_translation_invariants [AFF_DIM_TRANSLATION_EQ];; + +let AFFINE_INDEPENDENT_CARD_DIM_DIFFS = prove + (`!s a:real^N. + ~affine_dependent s /\ a IN s + ==> CARD s = dim {x - a | x IN s} + 1`, + REPEAT STRIP_TAC THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP AFFINE_INDEPENDENT_IMP_FINITE) THEN + MATCH_MP_TAC(ARITH_RULE `~(s = 0) /\ v = s - 1 ==> s = v + 1`) THEN + ASM_SIMP_TAC[CARD_EQ_0] THEN CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + MATCH_MP_TAC DIM_UNIQUE THEN + EXISTS_TAC `{b - a:real^N |b| b IN (s DELETE a)}` THEN REPEAT CONJ_TAC THENL + [SET_TAC[]; + REWRITE_TAC[SIMPLE_IMAGE; SUBSET; FORALL_IN_IMAGE] THEN + X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN ASM_CASES_TAC `x:real^N = a` THENL + [ASM_REWRITE_TAC[VECTOR_SUB_REFL; SPAN_0]; + MATCH_MP_TAC SPAN_SUPERSET THEN ASM SET_TAC[]]; + UNDISCH_TAC `~affine_dependent(s:real^N->bool)` THEN + REWRITE_TAC[independent; CONTRAPOS_THM] THEN DISCH_TAC THEN + SUBGOAL_THEN `s = (a:real^N) INSERT (s DELETE a)` SUBST1_TAC THENL + [ASM SET_TAC[]; ALL_TAC] THEN + MATCH_MP_TAC DEPENDENT_IMP_AFFINE_DEPENDENT THEN + ASM_REWRITE_TAC[IN_DELETE]; + REWRITE_TAC[SIMPLE_IMAGE] THEN MATCH_MP_TAC HAS_SIZE_IMAGE_INJ THEN + SIMP_TAC[VECTOR_ARITH `x - a:real^N = y - a <=> x = y`] THEN + ASM_SIMP_TAC[HAS_SIZE; FINITE_DELETE; CARD_DELETE]]);; + +let AFF_DIM_DIM_AFFINE_DIFFS = prove + (`!a:real^N s. affine s /\ a IN s ==> aff_dim s = &(dim {x - a | x IN s})`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPEC `s:real^N->bool` AFF_DIM) THEN + DISCH_THEN(X_CHOOSE_THEN `b:real^N->bool` MP_TAC) THEN + ASM_CASES_TAC `b:real^N->bool = {}` THENL + [ASM_MESON_TAC[AFFINE_HULL_EQ_EMPTY; NOT_IN_EMPTY]; ALL_TAC] THEN + STRIP_TAC THEN + ASM_REWRITE_TAC[INT_EQ_SUB_RADD; INT_OF_NUM_ADD; INT_OF_NUM_EQ] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN + DISCH_THEN(X_CHOOSE_TAC `c:real^N`) THEN MATCH_MP_TAC EQ_TRANS THEN + EXISTS_TAC `dim {x - c:real^N | x IN b} + 1` THEN CONJ_TAC THENL + [MATCH_MP_TAC AFFINE_INDEPENDENT_CARD_DIM_DIFFS THEN ASM_REWRITE_TAC[]; + ALL_TAC] THEN + MATCH_MP_TAC EQ_TRANS THEN + EXISTS_TAC `dim {x - c:real^N | x IN affine hull b} + 1` THEN CONJ_TAC THENL + [ASM_SIMP_TAC[DIFFS_AFFINE_HULL_SPAN; DIM_SPAN]; ALL_TAC] THEN + ASM_REWRITE_TAC[] THEN AP_THM_TAC THEN AP_TERM_TAC THEN AP_TERM_TAC THEN + SUBGOAL_THEN `affine hull s:real^N->bool = s` SUBST1_TAC THENL + [ASM_MESON_TAC[AFFINE_HULL_EQ]; ALL_TAC] THEN + SUBGOAL_THEN `(c:real^N) IN s` ASSUME_TAC THENL + [ASM_MESON_TAC[AFFINE_HULL_EQ; HULL_INC]; ALL_TAC] THEN + MATCH_MP_TAC SUBSET_ANTISYM THEN REWRITE_TAC[SUBSET; FORALL_IN_GSPEC] THEN + REWRITE_TAC[IN_ELIM_THM] THEN + SIMP_TAC[VECTOR_ARITH `x - c:real^N = y - a <=> y = x + &1 % (a - c)`] THEN + ASM_MESON_TAC[IN_AFFINE_ADD_MUL_DIFF]);; + +let AFF_DIM_DIM_0 = prove + (`!s:real^N->bool. vec 0 IN affine hull s ==> aff_dim s = &(dim s)`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`vec 0:real^N`; `affine hull s:real^N->bool`] + AFF_DIM_DIM_AFFINE_DIFFS) THEN + ASM_REWRITE_TAC[AFFINE_AFFINE_HULL; VECTOR_SUB_RZERO] THEN + REWRITE_TAC[AFF_DIM_AFFINE_HULL; SET_RULE `{x | x IN s} = s`] THEN + ASM_SIMP_TAC[AFFINE_HULL_EQ_SPAN; DIM_SPAN]);; + +let AFF_DIM_DIM_SUBSPACE = prove + (`!s:real^N->bool. subspace s ==> aff_dim s = &(dim s)`, + MESON_TAC[AFF_DIM_DIM_0; SUBSPACE_0; HULL_INC]);; + +let AFF_DIM_LINEAR_IMAGE_LE = prove + (`!f:real^M->real^N s. linear f ==> aff_dim(IMAGE f s) <= aff_dim s`, + REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[GSYM AFF_DIM_AFFINE_HULL] THEN + ASM_SIMP_TAC[AFFINE_HULL_LINEAR_IMAGE] THEN + MP_TAC(ISPEC `s:real^M->bool` AFFINE_AFFINE_HULL) THEN + SPEC_TAC(`affine hull s:real^M->bool`,`s:real^M->bool`) THEN + GEN_TAC THEN DISCH_TAC THEN ASM_CASES_TAC `s:real^M->bool = {}` THEN + ASM_REWRITE_TAC[IMAGE_CLAUSES; AFF_DIM_EMPTY; INT_LE_REFL] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN + DISCH_THEN(X_CHOOSE_TAC `a:real^M`) THEN + SUBGOAL_THEN `dim {x - f(a) |x| x IN IMAGE (f:real^M->real^N) s} <= + dim {x - a | x IN s}` + MP_TAC THENL + [REWRITE_TAC[SET_RULE `{f x | x IN IMAGE g s} = {f (g x) | x IN s}`] THEN + ASM_SIMP_TAC[GSYM LINEAR_SUB] THEN REWRITE_TAC[SIMPLE_IMAGE] THEN + ONCE_REWRITE_TAC[GSYM o_DEF] THEN REWRITE_TAC[IMAGE_o] THEN + MATCH_MP_TAC DIM_LINEAR_IMAGE_LE THEN ASM_REWRITE_TAC[]; + MATCH_MP_TAC EQ_IMP THEN REWRITE_TAC[GSYM INT_OF_NUM_LE] THEN + BINOP_TAC THEN CONV_TAC SYM_CONV THEN + MATCH_MP_TAC AFF_DIM_DIM_AFFINE_DIFFS THEN + ASM_SIMP_TAC[AFFINE_LINEAR_IMAGE; FUN_IN_IMAGE]]);; + +let AFF_DIM_INJECTIVE_LINEAR_IMAGE = prove + (`!f:real^M->real^N s. + linear f /\ (!x y. f x = f y ==> x = y) + ==> aff_dim(IMAGE f s) = aff_dim s`, + REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM INT_LE_ANTISYM] THEN + CONJ_TAC THENL [ASM_MESON_TAC[AFF_DIM_LINEAR_IMAGE_LE]; ALL_TAC] THEN + MP_TAC(ISPEC `f:real^M->real^N` LINEAR_INJECTIVE_LEFT_INVERSE) THEN + ASM_REWRITE_TAC[FUN_EQ_THM; o_THM; I_THM] THEN + DISCH_THEN(X_CHOOSE_THEN `g:real^N->real^M` STRIP_ASSUME_TAC) THEN + MATCH_MP_TAC INT_LE_TRANS THEN EXISTS_TAC + `aff_dim(IMAGE (g:real^N->real^M) (IMAGE (f:real^M->real^N) s))` THEN + CONJ_TAC THENL + [ASM_REWRITE_TAC[GSYM IMAGE_o; o_DEF; IMAGE_ID; INT_LE_REFL]; + MATCH_MP_TAC AFF_DIM_LINEAR_IMAGE_LE THEN ASM_REWRITE_TAC[]]);; + +add_linear_invariants [AFF_DIM_INJECTIVE_LINEAR_IMAGE];; + +let AFF_DIM_AFFINE_INDEPENDENT = prove + (`!b:real^N->bool. + ~(affine_dependent b) ==> aff_dim b = &(CARD b) - &1`, + GEN_TAC THEN ASM_CASES_TAC `b:real^N->bool = {}` THENL + [ASM_REWRITE_TAC[CARD_CLAUSES; AFF_DIM_EMPTY] THEN INT_ARITH_TAC; + ALL_TAC] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN + DISCH_THEN(X_CHOOSE_TAC `a:real^N`) THEN DISCH_TAC THEN + MP_TAC(ISPECL [`b:real^N->bool`; `a:real^N`] + AFFINE_INDEPENDENT_CARD_DIM_DIFFS) THEN + ASM_REWRITE_TAC[] THEN DISCH_THEN SUBST1_TAC THEN + REWRITE_TAC[GSYM INT_OF_NUM_ADD; INT_ARITH `(a + b) - b:int = a`] THEN + MP_TAC(ISPECL [`a:real^N`; `affine hull b:real^N->bool`] + AFF_DIM_DIM_AFFINE_DIFFS) THEN + ASM_SIMP_TAC[AFFINE_AFFINE_HULL; HULL_INC; AFF_DIM_AFFINE_HULL] THEN + DISCH_THEN(K ALL_TAC) THEN AP_TERM_TAC THEN + ASM_MESON_TAC[DIFFS_AFFINE_HULL_SPAN; DIM_SPAN]);; + +let AFF_DIM_UNIQUE = prove + (`!s b:real^N->bool. + affine hull b = affine hull s /\ ~(affine_dependent b) + ==> aff_dim s = &(CARD b) - &1`, + MESON_TAC[AFF_DIM_AFFINE_HULL; AFF_DIM_AFFINE_INDEPENDENT]);; + +let AFF_DIM_SING = prove + (`!a:real^N. aff_dim {a} = &0`, + GEN_TAC THEN MATCH_MP_TAC EQ_TRANS THEN + EXISTS_TAC `&(CARD {a:real^N}) - &1:int` THEN CONJ_TAC THENL + [MATCH_MP_TAC AFF_DIM_AFFINE_INDEPENDENT THEN + REWRITE_TAC[AFFINE_INDEPENDENT_1]; + SIMP_TAC[CARD_CLAUSES; FINITE_RULES; ARITH; NOT_IN_EMPTY; INT_SUB_REFL]]);; + +let AFF_DIM_LE_CARD = prove + (`!s:real^N->bool. FINITE s ==> aff_dim s <= &(CARD s) - &1`, + MATCH_MP_TAC SET_PROVE_CASES THEN + SIMP_TAC[AFF_DIM_EMPTY; CARD_CLAUSES] THEN CONV_TAC INT_REDUCE_CONV THEN + GEOM_ORIGIN_TAC `a:real^N` THEN + SIMP_TAC[AFF_DIM_DIM_0; IN_INSERT; HULL_INC] THEN + SIMP_TAC[CARD_IMAGE_INJ; VECTOR_ARITH `a + x:real^N = a + y <=> x = y`] THEN + SIMP_TAC[DIM_INSERT_0; INT_LE_SUB_LADD; CARD_CLAUSES; FINITE_INSERT] THEN + REWRITE_TAC[INT_OF_NUM_ADD; INT_OF_NUM_LE; ADD1; LE_ADD_RCANCEL] THEN + SIMP_TAC[DIM_LE_CARD]);; + +let AFF_DIM_GE = prove + (`!s:real^N->bool. -- &1 <= aff_dim s`, + GEN_TAC THEN MP_TAC(ISPEC `s:real^N->bool` AFF_DIM) THEN + STRIP_TAC THEN ASM_REWRITE_TAC[INT_LE_SUB_LADD; INT_ADD_LINV; INT_POS]);; + +let AFF_DIM_SUBSET = prove + (`!s t:real^N->bool. s SUBSET t ==> aff_dim s <= aff_dim t`, + MATCH_MP_TAC SET_PROVE_CASES THEN REWRITE_TAC[AFF_DIM_GE; AFF_DIM_EMPTY] THEN + GEOM_ORIGIN_TAC `a:real^N` THEN REPEAT STRIP_TAC THEN + SUBGOAL_THEN `(vec 0:real^N) IN t` ASSUME_TAC THENL + [ASM SET_TAC[]; ALL_TAC] THEN + ASM_SIMP_TAC[AFF_DIM_DIM_0; IN_INSERT; HULL_INC; INT_OF_NUM_LE; DIM_SUBSET]);; + +let AFF_DIM_LE_DIM = prove + (`!s:real^N->bool. aff_dim s <= &(dim s)`, + GEN_TAC THEN ONCE_REWRITE_TAC[GSYM DIM_SPAN] THEN + ASM_SIMP_TAC[GSYM AFF_DIM_DIM_SUBSPACE; SUBSPACE_SPAN] THEN + MATCH_MP_TAC AFF_DIM_SUBSET THEN REWRITE_TAC[SPAN_INC]);; + +let AFF_DIM_CONVEX_HULL = prove + (`!s:real^N->bool. aff_dim(convex hull s) = aff_dim s`, + GEN_TAC THEN MATCH_MP_TAC(INT_ARITH + `!c:int. c = a /\ a <= b /\ b <= c ==> b = a`) THEN + EXISTS_TAC `aff_dim(affine hull s:real^N->bool)` THEN + SIMP_TAC[AFF_DIM_AFFINE_HULL; AFF_DIM_SUBSET; HULL_SUBSET; + CONVEX_HULL_SUBSET_AFFINE_HULL]);; + +let AFF_DIM_CLOSURE = prove + (`!s:real^N->bool. aff_dim(closure s) = aff_dim s`, + GEN_TAC THEN MATCH_MP_TAC(INT_ARITH + `!h. h = s /\ s <= c /\ c <= h ==> c:int = s`) THEN + EXISTS_TAC `aff_dim(affine hull s:real^N->bool)` THEN + REPEAT CONJ_TAC THENL + [REWRITE_TAC[AFF_DIM_AFFINE_HULL]; + MATCH_MP_TAC AFF_DIM_SUBSET THEN REWRITE_TAC[CLOSURE_SUBSET]; + MATCH_MP_TAC AFF_DIM_SUBSET THEN + MATCH_MP_TAC CLOSURE_MINIMAL THEN + REWRITE_TAC[CLOSED_AFFINE_HULL; HULL_SUBSET]]);; + +let AFF_DIM_2 = prove + (`!a b:real^N. aff_dim {a,b} = if a = b then &0 else &1`, + REPEAT GEN_TAC THEN COND_CASES_TAC THENL + [ASM_REWRITE_TAC[INSERT_AC; AFF_DIM_SING]; ALL_TAC] THEN + MATCH_MP_TAC EQ_TRANS THEN EXISTS_TAC `&(CARD {a:real^N,b}) - &1:int` THEN + ASM_SIMP_TAC[AFF_DIM_AFFINE_INDEPENDENT; AFFINE_INDEPENDENT_2] THEN + ASM_SIMP_TAC[CARD_CLAUSES; FINITE_RULES; IN_INSERT; NOT_IN_EMPTY] THEN + CONV_TAC NUM_REDUCE_CONV THEN INT_ARITH_TAC);; + +let AFF_DIM_EQ_MINUS1 = prove + (`!s:real^N->bool. aff_dim s = -- &1 <=> s = {}`, + GEN_TAC THEN EQ_TAC THEN SIMP_TAC[AFF_DIM_EMPTY] THEN + ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN + REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `a:real^N` THEN DISCH_TAC THEN + MATCH_MP_TAC(INT_ARITH `&0:int <= n ==> ~(n = -- &1)`) THEN + MATCH_MP_TAC INT_LE_TRANS THEN EXISTS_TAC `aff_dim {a:real^N}` THEN + ASM_SIMP_TAC[AFF_DIM_SUBSET; SING_SUBSET] THEN + REWRITE_TAC[AFF_DIM_SING; INT_LE_REFL]);; + +let AFF_DIM_POS_LE = prove + (`!s:real^N->bool. &0 <= aff_dim s <=> ~(s = {})`, + GEN_TAC THEN REWRITE_TAC[GSYM AFF_DIM_EQ_MINUS1] THEN + MP_TAC(ISPEC `s:real^N->bool` AFF_DIM_GE) THEN INT_ARITH_TAC);; + +let AFF_DIM_EQ_0 = prove + (`!s:real^N->bool. aff_dim s = &0 <=> ?a. s = {a}`, + GEN_TAC THEN EQ_TAC THEN SIMP_TAC[AFF_DIM_SING; LEFT_IMP_EXISTS_THM] THEN + ASM_CASES_TAC `s:real^N->bool = {}` THEN ASM_REWRITE_TAC[AFF_DIM_EMPTY] THEN + CONV_TAC INT_REDUCE_CONV THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `a:real^N` THEN + MATCH_MP_TAC(SET_RULE + `(!b. ~(b = a) /\ {a,b} SUBSET s ==> F) ==> a IN s ==> s = {a}`) THEN + X_GEN_TAC `b:real^N` THEN STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o MATCH_MP AFF_DIM_SUBSET) THEN + MP_TAC(ISPECL [`a:real^N`; `b:real^N`] AFF_DIM_2) THEN + ASM_SIMP_TAC[] THEN INT_ARITH_TAC);; + +let CONNECTED_IMP_PERFECT_AFF_DIM = prove + (`!s x:real^N. + connected s /\ ~(aff_dim s = &0) /\ x IN s ==> x limit_point_of s`, + REWRITE_TAC[AFF_DIM_EQ_0; CONNECTED_IMP_PERFECT]);; + +let AFF_DIM_UNIV = prove + (`aff_dim(:real^N) = &(dimindex(:N))`, + SIMP_TAC[AFF_DIM_DIM_SUBSPACE; SUBSPACE_UNIV; DIM_UNIV]);; + +let AFF_DIM_EQ_AFFINE_HULL = prove + (`!s t:real^N->bool. + s SUBSET t /\ aff_dim t <= aff_dim s + ==> affine hull s = affine hull t`, + MATCH_MP_TAC SET_PROVE_CASES THEN + SIMP_TAC[AFF_DIM_EMPTY; AFF_DIM_EQ_MINUS1; AFF_DIM_GE; + INT_ARITH `a:int <= x ==> (x <= a <=> x = a)`] THEN + X_GEN_TAC `a:real^N` THEN GEOM_ORIGIN_TAC `a:real^N` THEN + SIMP_TAC[INSERT_SUBSET; IMP_CONJ; AFF_DIM_DIM_0; IN_INSERT; DIM_EQ_SPAN; + HULL_INC; AFFINE_HULL_EQ_SPAN; INT_OF_NUM_LE]);; + +let AFF_DIM_SUMS_INTER = prove + (`!s t:real^N->bool. + affine s /\ affine t /\ ~(s INTER t = {}) + ==> aff_dim {x + y | x IN s /\ y IN t} = + (aff_dim s + aff_dim t) - aff_dim(s INTER t)`, + REWRITE_TAC[TAUT `a /\ b /\ c ==> d <=> c ==> a /\ b ==> d`] THEN + REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; LEFT_IMP_EXISTS_THM] THEN + GEN_REWRITE_TAC BINDER_CONV [SWAP_FORALL_THM] THEN + GEN_REWRITE_TAC I [SWAP_FORALL_THM] THEN X_GEN_TAC `a:real^N` THEN + GEOM_ORIGIN_TAC `a:real^N` THEN + REWRITE_TAC[VECTOR_ARITH `(a + x) + (a + y):real^N = &2 % a + (x + y)`] THEN + ONCE_REWRITE_TAC[SET_RULE `{a + x + y:real^N | x IN s /\ y IN t} = + IMAGE (\x. a + x) {x + y | x IN s /\ y IN t}`] THEN + REWRITE_TAC[AFF_DIM_TRANSLATION_EQ; IN_INTER] THEN + MAP_EVERY X_GEN_TAC [`s:real^N->bool`; `t:real^N->bool`] THEN STRIP_TAC THEN + STRIP_TAC THEN + SUBGOAL_THEN `(vec 0:real^N) IN {x + y | x IN s /\ y IN t}` ASSUME_TAC THENL + [REWRITE_TAC[IN_ELIM_THM] THEN REPEAT(EXISTS_TAC `vec 0:real^N`) THEN + ASM_REWRITE_TAC[VECTOR_ADD_LID]; + ALL_TAC] THEN + ASM_SIMP_TAC[AFF_DIM_DIM_0; HULL_INC; IN_INTER] THEN + REWRITE_TAC[INT_EQ_SUB_LADD; INT_OF_NUM_ADD; INT_OF_NUM_EQ] THEN + MATCH_MP_TAC DIM_SUMS_INTER THEN ASM_SIMP_TAC[AFFINE_IMP_SUBSPACE]);; + +let AFF_DIM_PSUBSET = prove + (`!s t. (affine hull s) PSUBSET (affine hull t) ==> aff_dim s < aff_dim t`, + ONCE_REWRITE_TAC[GSYM AFF_DIM_AFFINE_HULL] THEN + SIMP_TAC[PSUBSET; AFF_DIM_SUBSET; INT_LT_LE] THEN + MESON_TAC[INT_EQ_IMP_LE; AFF_DIM_EQ_AFFINE_HULL; HULL_HULL]);; + +let AFF_DIM_EQ_FULL = prove + (`!s. aff_dim s = &(dimindex(:N)) <=> affine hull s = (:real^N)`, + GEN_TAC THEN EQ_TAC THENL + [DISCH_TAC THEN ONCE_REWRITE_TAC[GSYM AFFINE_HULL_UNIV] THEN + MATCH_MP_TAC AFF_DIM_EQ_AFFINE_HULL THEN + ASM_REWRITE_TAC[SUBSET_UNIV; AFF_DIM_UNIV; INT_LE_REFL]; + ONCE_REWRITE_TAC[GSYM AFF_DIM_AFFINE_HULL] THEN + SIMP_TAC[AFF_DIM_UNIV]]);; + +let AFF_DIM_LE_UNIV = prove + (`!s:real^N->bool. aff_dim s <= &(dimindex(:N))`, + GEN_TAC THEN ONCE_REWRITE_TAC[GSYM AFF_DIM_UNIV] THEN + MATCH_MP_TAC AFF_DIM_SUBSET THEN REWRITE_TAC[SUBSET_UNIV]);; + +let AFFINE_INDEPENDENT_IFF_CARD = prove + (`!s:real^N->bool. + ~affine_dependent s <=> FINITE s /\ aff_dim s = &(CARD s) - &1`, + GEN_TAC THEN EQ_TAC THEN + SIMP_TAC[AFF_DIM_AFFINE_INDEPENDENT; AFFINE_INDEPENDENT_IMP_FINITE] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN REWRITE_TAC[] THEN DISCH_TAC THEN + X_CHOOSE_THEN `b:real^N->bool` STRIP_ASSUME_TAC + (ISPEC `s:real^N->bool` AFFINE_BASIS_EXISTS) THEN + MATCH_MP_TAC(ARITH_RULE `!b:int. a <= b - &1 /\ b < s ==> ~(a = s - &1)`) THEN + EXISTS_TAC `&(CARD(b:real^N->bool)):int` THEN CONJ_TAC THENL + [ASM_MESON_TAC[AFF_DIM_LE_CARD; FINITE_SUBSET; AFF_DIM_AFFINE_HULL]; + REWRITE_TAC[INT_OF_NUM_LT] THEN MATCH_MP_TAC CARD_PSUBSET THEN + ASM_REWRITE_TAC[PSUBSET] THEN ASM_MESON_TAC[]]);; + +let AFFINE_HULL_CONVEX_INTER_NONEMPTY_INTERIOR = prove + (`!s t:real^N->bool. + convex s /\ ~(s INTER interior t = {}) + ==> affine hull (s INTER t) = affine hull s`, + REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; RIGHT_AND_EXISTS_THM; + LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`s:real^N->bool`; `t:real^N->bool`; `a:real^N`] THEN + GEOM_ORIGIN_TAC `a:real^N` THEN REWRITE_TAC[IN_INTER] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN + SIMP_TAC[HULL_MONO; INTER_SUBSET] THEN + SIMP_TAC[SUBSET_HULL; AFFINE_AFFINE_HULL] THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP (SIMP_RULE[SUBSET] INTERIOR_SUBSET)) THEN + ASM_SIMP_TAC[AFFINE_HULL_EQ_SPAN; HULL_INC; IN_INTER] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_INTERIOR_CBALL]) THEN + ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM; SUBSET; IN_CBALL_0] THEN + X_GEN_TAC `e:real` THEN STRIP_TAC THEN REWRITE_TAC[EXTENSION; IN_UNIV] THEN + X_GEN_TAC `x:real^N` THEN ASM_CASES_TAC `x:real^N = vec 0` THEN + ASM_SIMP_TAC[SPAN_SUPERSET; IN_INTER] THEN DISCH_TAC THEN + ABBREV_TAC `k = min (&1 / &2) (e / norm(x:real^N))` THEN + SUBGOAL_THEN `&0 < k /\ k < &1` STRIP_ASSUME_TAC THENL + [EXPAND_TAC "k" THEN + ASM_SIMP_TAC[REAL_LT_MIN; REAL_LT_DIV; NORM_POS_LT; REAL_MIN_LT] THEN + CONV_TAC REAL_RAT_REDUCE_CONV; + ALL_TAC] THEN + SUBGOAL_THEN `x:real^N = inv k % k % x` SUBST1_TAC THENL + [ASM_SIMP_TAC[VECTOR_MUL_ASSOC; REAL_MUL_LINV; VECTOR_MUL_LID; + REAL_LT_IMP_NZ]; + ALL_TAC] THEN + MATCH_MP_TAC SPAN_MUL THEN MATCH_MP_TAC SPAN_SUPERSET THEN + REWRITE_TAC[IN_INTER] THEN CONJ_TAC THENL + [ONCE_REWRITE_TAC[VECTOR_ARITH + `k % x:real^N = (&1 - k) % vec 0 + k % x`] THEN + MATCH_MP_TAC IN_CONVEX_SET THEN ASM_SIMP_TAC[REAL_LT_IMP_LE]; + FIRST_X_ASSUM MATCH_MP_TAC THEN EXPAND_TAC "k" THEN + ASM_SIMP_TAC[NORM_MUL; GSYM REAL_LE_RDIV_EQ; NORM_POS_LT] THEN + ASM_REAL_ARITH_TAC]);; + +let AFFINE_HULL_CONVEX_INTER_OPEN = prove + (`!s t:real^N->bool. + convex s /\ open t /\ ~(s INTER t = {}) + ==> affine hull (s INTER t) = affine hull s`, + ASM_SIMP_TAC[AFFINE_HULL_CONVEX_INTER_NONEMPTY_INTERIOR; INTERIOR_OPEN]);; + +let AFFINE_HULL_AFFINE_INTER_NONEMPTY_INTERIOR = prove + (`!s t:real^N->bool. + affine s /\ ~(s INTER interior t = {}) + ==> affine hull (s INTER t) = s`, + SIMP_TAC[AFFINE_HULL_CONVEX_INTER_NONEMPTY_INTERIOR; AFFINE_IMP_CONVEX; + HULL_P]);; + +let AFFINE_HULL_AFFINE_INTER_OPEN = prove + (`!s t:real^N->bool. + affine s /\ open t /\ ~(s INTER t = {}) + ==> affine hull (s INTER t) = s`, + SIMP_TAC[AFFINE_HULL_AFFINE_INTER_NONEMPTY_INTERIOR; INTERIOR_OPEN]);; + +let CONVEX_AND_AFFINE_INTER_OPEN = prove + (`!s t u:real^N->bool. + convex s /\ affine t /\ open u /\ + s INTER u = t INTER u /\ ~(s INTER u = {}) + ==> affine hull s = t`, + REPEAT STRIP_TAC THEN + MATCH_MP_TAC(MESON[] `!u v. x = u /\ u = v /\ v = y ==> x = y`) THEN + MAP_EVERY EXISTS_TAC + [`affine hull (s INTER u:real^N->bool)`; + `affine hull t:real^N->bool`] THEN + REPEAT CONJ_TAC THENL + [CONV_TAC SYM_CONV THEN MATCH_MP_TAC AFFINE_HULL_CONVEX_INTER_OPEN THEN + ASM_REWRITE_TAC[]; + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC AFFINE_HULL_CONVEX_INTER_OPEN THEN + ASM_SIMP_TAC[AFFINE_IMP_CONVEX] THEN ASM SET_TAC[]; + ASM_REWRITE_TAC[AFFINE_HULL_EQ]]);; + +let AFFINE_HULL_CONVEX_INTER_OPEN_IN = prove + (`!s t:real^N->bool. + convex s /\ open_in (subtopology euclidean (affine hull s)) t /\ + ~(s INTER t = {}) + ==> affine hull (s INTER t) = affine hull s`, + REPEAT STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [OPEN_IN_OPEN]) THEN + DISCH_THEN(X_CHOOSE_THEN `u:real^N->bool` STRIP_ASSUME_TAC) THEN + ASM_SIMP_TAC[SET_RULE `s SUBSET t ==> s INTER t INTER u = s INTER u`; + HULL_SUBSET] THEN + MATCH_MP_TAC AFFINE_HULL_CONVEX_INTER_OPEN THEN ASM SET_TAC[]);; + +let AFFINE_HULL_AFFINE_INTER_OPEN_IN = prove + (`!s t:real^N->bool. + affine s /\ open_in (subtopology euclidean s) t /\ ~(s INTER t = {}) + ==> affine hull (s INTER t) = s`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`affine hull s:real^N->bool`; `t:real^N->bool`] + AFFINE_HULL_CONVEX_INTER_OPEN_IN) THEN + ASM_SIMP_TAC[HULL_HULL; AFFINE_IMP_CONVEX; AFFINE_AFFINE_HULL; HULL_P]);; + +let AFFINE_HULL_CONVEX_INTER_OPEN_IN = prove + (`!s t:real^N->bool. + convex s /\ open_in (subtopology euclidean (affine hull s)) t /\ + ~(s INTER t = {}) + ==> affine hull (s INTER t) = affine hull s`, + REPEAT STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [OPEN_IN_OPEN]) THEN + DISCH_THEN(X_CHOOSE_THEN `u:real^N->bool` STRIP_ASSUME_TAC) THEN + ASM_SIMP_TAC[SET_RULE `s SUBSET t ==> s INTER t INTER u = s INTER u`; + HULL_SUBSET] THEN + MATCH_MP_TAC AFFINE_HULL_CONVEX_INTER_OPEN THEN ASM SET_TAC[]);; + +let AFFINE_HULL_AFFINE_INTER_OPEN_IN = prove + (`!s t:real^N->bool. + affine s /\ open_in (subtopology euclidean s) t /\ ~(s INTER t = {}) + ==> affine hull (s INTER t) = s`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`affine hull s:real^N->bool`; `t:real^N->bool`] + AFFINE_HULL_CONVEX_INTER_OPEN_IN) THEN + ASM_SIMP_TAC[HULL_HULL; AFFINE_IMP_CONVEX; AFFINE_AFFINE_HULL; HULL_P]);; + +let AFFINE_HULL_OPEN_IN = prove + (`!s t:real^N->bool. + open_in (subtopology euclidean (affine hull t)) s /\ ~(s = {}) + ==> affine hull s = affine hull t`, + REPEAT STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [OPEN_IN_OPEN]) THEN + DISCH_THEN(X_CHOOSE_THEN `u:real^N->bool` STRIP_ASSUME_TAC) THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC AFFINE_HULL_AFFINE_INTER_OPEN THEN + REWRITE_TAC[AFFINE_AFFINE_HULL] THEN ASM SET_TAC[]);; + +let AFFINE_HULL_OPEN = prove + (`!s. open s /\ ~(s = {}) ==> affine hull s = (:real^N)`, + GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + SUBST1_TAC(SET_RULE `s = (:real^N) INTER s`) THEN + ASM_SIMP_TAC[AFFINE_HULL_CONVEX_INTER_OPEN; CONVEX_UNIV] THEN + REWRITE_TAC[AFFINE_HULL_UNIV]);; + +let AFFINE_HULL_NONEMPTY_INTERIOR = prove + (`!s. ~(interior s = {}) ==> affine hull s = (:real^N)`, + REPEAT STRIP_TAC THEN + MATCH_MP_TAC(SET_RULE `!s. s SUBSET t /\ s = UNIV ==> t = UNIV`) THEN + EXISTS_TAC `affine hull (interior s:real^N->bool)` THEN + SIMP_TAC[HULL_MONO; INTERIOR_SUBSET] THEN + ASM_SIMP_TAC[AFFINE_HULL_OPEN; OPEN_INTERIOR]);; + +let AFF_DIM_OPEN = prove + (`!s:real^N->bool. open s /\ ~(s = {}) ==> aff_dim s = &(dimindex(:N))`, + SIMP_TAC[AFF_DIM_EQ_FULL; AFFINE_HULL_OPEN]);; + +let AFF_DIM_NONEMPTY_INTERIOR = prove + (`!s:real^N->bool. ~(interior s = {}) ==> aff_dim s = &(dimindex(:N))`, + SIMP_TAC[AFF_DIM_EQ_FULL; AFFINE_HULL_NONEMPTY_INTERIOR]);; + +let SPAN_OPEN = prove + (`!s. open s /\ ~(s = {}) ==> span s = (:real^N)`, + REPEAT STRIP_TAC THEN + MATCH_MP_TAC(SET_RULE `!s. s SUBSET t /\ s = UNIV ==> t = UNIV`) THEN + EXISTS_TAC `affine hull s:real^N->bool` THEN + ASM_SIMP_TAC[AFFINE_HULL_OPEN; AFFINE_HULL_SUBSET_SPAN]);; + +let DIM_OPEN = prove + (`!s:real^N->bool. open s /\ ~(s = {}) ==> dim s = dimindex(:N)`, + SIMP_TAC[DIM_EQ_FULL; SPAN_OPEN]);; + +let AFF_DIM_INSERT = prove + (`!a:real^N s. + aff_dim (a INSERT s) = + if a IN affine hull s then aff_dim s else aff_dim s + &1`, + ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN MATCH_MP_TAC SET_PROVE_CASES THEN + SIMP_TAC[AFF_DIM_EMPTY; AFF_DIM_SING; AFFINE_HULL_EMPTY; NOT_IN_EMPTY] THEN + CONV_TAC INT_REDUCE_CONV THEN REWRITE_TAC[RIGHT_IMP_FORALL_THM] THEN + MAP_EVERY X_GEN_TAC [`b:real^N`; `s:real^N->bool`; `a:real^N`] THEN + GEOM_ORIGIN_TAC `b:real^N` THEN + SIMP_TAC[AFFINE_HULL_EQ_SPAN; AFF_DIM_DIM_0; HULL_INC; IN_INSERT] THEN + MAP_EVERY X_GEN_TAC [`a:real^N`; `s:real^N->bool`] THEN + DISCH_THEN(K ALL_TAC) THEN + SPEC_TAC(`(vec 0:real^N) INSERT s`,`s:real^N->bool`) THEN + SIMP_TAC[DIM_INSERT; INT_OF_NUM_ADD] THEN MESON_TAC[]);; + +let AFFINE_BOUNDED_EQ_TRIVIAL = prove + (`!s:real^N->bool. + affine s ==> (bounded s <=> s = {} \/ ?a. s = {a})`, + GEN_TAC THEN ASM_CASES_TAC `s:real^N->bool = {}` THEN + ASM_REWRITE_TAC[BOUNDED_EMPTY] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN + DISCH_THEN(X_CHOOSE_THEN `b:real^N` MP_TAC) THEN + GEOM_ORIGIN_TAC `b:real^N` THEN SIMP_TAC[AFFINE_EQ_SUBSPACE] THEN + REPEAT STRIP_TAC THEN ASM_SIMP_TAC[SUBSPACE_BOUNDED_EQ_TRIVIAL] THEN + FIRST_ASSUM(MP_TAC o MATCH_MP SUBSPACE_0) THEN SET_TAC[]);; + +let AFFINE_BOUNDED_EQ_LOWDIM = prove + (`!s:real^N->bool. + affine s ==> (bounded s <=> aff_dim s <= &0)`, + SIMP_TAC[AFF_DIM_GE; INT_ARITH + `--(&1):int <= x ==> (x <= &0 <=> x = --(&1) \/ x = &0)`] THEN + SIMP_TAC[AFF_DIM_EQ_0; AFF_DIM_EQ_MINUS1; AFFINE_BOUNDED_EQ_TRIVIAL]);; + +let COLLINEAR_AFF_DIM = prove + (`!s:real^N->bool. collinear s <=> aff_dim s <= &1`, + GEN_TAC THEN EQ_TAC THENL + [REWRITE_TAC[COLLINEAR_AFFINE_HULL; LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`u:real^N`; `v:real^N`] THEN STRIP_TAC THEN + MATCH_MP_TAC INT_LE_TRANS THEN EXISTS_TAC `aff_dim{u:real^N,v}` THEN + CONJ_TAC THENL + [ASM_MESON_TAC[AFF_DIM_SUBSET; AFF_DIM_AFFINE_HULL]; + MATCH_MP_TAC INT_LE_TRANS THEN + EXISTS_TAC `&(CARD{u:real^N,v}) - &1:int` THEN + SIMP_TAC[AFF_DIM_LE_CARD; FINITE_INSERT; FINITE_EMPTY] THEN + REWRITE_TAC[INT_ARITH `x - &1:int <= &1 <=> x <= &2`; INT_OF_NUM_LE] THEN + SIMP_TAC[CARD_CLAUSES; FINITE_INSERT; FINITE_EMPTY] THEN ARITH_TAC]; + ONCE_REWRITE_TAC[GSYM COLLINEAR_AFFINE_HULL_COLLINEAR; + GSYM AFF_DIM_AFFINE_HULL] THEN + MP_TAC(ISPEC `s:real^N->bool` AFFINE_BASIS_EXISTS) THEN + DISCH_THEN(X_CHOOSE_THEN `b:real^N->bool` (STRIP_ASSUME_TAC o GSYM)) THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I + [AFFINE_INDEPENDENT_IFF_CARD]) THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + ASM_REWRITE_TAC[COLLINEAR_AFFINE_HULL_COLLINEAR; + AFF_DIM_AFFINE_HULL] THEN + REWRITE_TAC[INT_ARITH `x - &1:int <= &1 <=> x <= &2`; INT_OF_NUM_LE] THEN + ASM_SIMP_TAC[COLLINEAR_SMALL]]);; + +let HOMEOMORPHIC_AFFINE_SETS = prove + (`!s:real^M->bool t:real^N->bool. + affine s /\ affine t /\ aff_dim s = aff_dim t ==> s homeomorphic t`, + REPEAT GEN_TAC THEN + ASM_CASES_TAC `t:real^N->bool = {}` THEN + ASM_SIMP_TAC[AFF_DIM_EMPTY; AFF_DIM_EQ_MINUS1; HOMEOMORPHIC_EMPTY] THEN + POP_ASSUM MP_TAC THEN + GEN_REWRITE_TAC (RAND_CONV o LAND_CONV o ONCE_DEPTH_CONV) [EQ_SYM_EQ] THEN + ASM_CASES_TAC `s:real^M->bool = {}` THEN + ASM_SIMP_TAC[AFF_DIM_EMPTY; AFF_DIM_EQ_MINUS1; HOMEOMORPHIC_EMPTY] THEN + POP_ASSUM MP_TAC THEN REWRITE_TAC + [GSYM MEMBER_NOT_EMPTY; LEFT_IMP_EXISTS_THM; RIGHT_IMP_FORALL_THM] THEN + MAP_EVERY X_GEN_TAC [`a:real^M`; `b:real^N`] THEN + GEOM_ORIGIN_TAC `a:real^M` THEN GEOM_ORIGIN_TAC `b:real^N` THEN + SIMP_TAC[AFFINE_EQ_SUBSPACE; AFF_DIM_DIM_0; HULL_INC; INT_OF_NUM_EQ] THEN + MESON_TAC[HOMEOMORPHIC_SUBSPACES]);; + +let AFF_DIM_OPEN_IN = prove + (`!s t:real^N->bool. + ~(s = {}) /\ open_in (subtopology euclidean t) s /\ affine t + ==> aff_dim s = aff_dim t`, + REPEAT GEN_TAC THEN + REWRITE_TAC[IMP_CONJ; GSYM MEMBER_NOT_EMPTY; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `a:real^N` THEN GEOM_ORIGIN_TAC `a:real^N` THEN + REPEAT GEN_TAC THEN STRIP_TAC THEN DISCH_TAC THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP OPEN_IN_IMP_SUBSET) THEN + SUBGOAL_THEN `(vec 0:real^N) IN t` ASSUME_TAC THENL + [ASM SET_TAC[]; ALL_TAC] THEN + ASM_SIMP_TAC[AFF_DIM_DIM_0; HULL_INC; AFFINE_EQ_SUBSPACE] THEN + DISCH_TAC THEN AP_TERM_TAC THEN + ASM_SIMP_TAC[GSYM LE_ANTISYM; DIM_SUBSET] THEN + SUBGOAL_THEN `?e. &0 < e /\ cball(vec 0:real^N,e) INTER t SUBSET s` + MP_TAC THENL + [FIRST_X_ASSUM(STRIP_ASSUME_TAC o GEN_REWRITE_RULE I [OPEN_IN_OPEN]) THEN + FIRST_X_ASSUM(MP_TAC o SPEC `vec 0:real^N` o + GEN_REWRITE_RULE I [OPEN_CONTAINS_CBALL]) THEN + ASM SET_TAC[]; + REWRITE_TAC[SUBSET; IN_INTER; IN_CBALL_0] THEN + DISCH_THEN(X_CHOOSE_THEN `e:real` STRIP_ASSUME_TAC)] THEN + FIRST_ASSUM(MP_TAC o MATCH_MP ORTHONORMAL_BASIS_SUBSPACE) THEN + DISCH_THEN(X_CHOOSE_THEN `b:real^N->bool` STRIP_ASSUME_TAC) THEN + MP_TAC(ISPECL [`s:real^N->bool`; `IMAGE (\x:real^N. e % x) b`] + INDEPENDENT_CARD_LE_DIM) THEN + RULE_ASSUM_TAC(REWRITE_RULE[HAS_SIZE]) THEN + ASM_SIMP_TAC[CARD_IMAGE_INJ; VECTOR_MUL_LCANCEL; REAL_LT_IMP_NZ] THEN + ANTS_TAC THENL [REWRITE_TAC[SUBSET]; MESON_TAC[]] THEN CONJ_TAC THENL + [REWRITE_TAC[FORALL_IN_IMAGE] THEN REPEAT STRIP_TAC THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_SIMP_TAC[NORM_MUL] THEN + CONJ_TAC THENL [ASM_REAL_ARITH_TAC; MATCH_MP_TAC SUBSPACE_MUL] THEN + ASM SET_TAC[]; + MATCH_MP_TAC INDEPENDENT_INJECTIVE_IMAGE THEN + ASM_SIMP_TAC[VECTOR_MUL_LCANCEL; REAL_LT_IMP_NZ; LINEAR_SCALING]]);; + +let DIM_OPEN_IN = prove + (`!s t:real^N->bool. + ~(s = {}) /\ open_in (subtopology euclidean t) s /\ subspace t + ==> dim s = dim t`, + REPEAT STRIP_TAC THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP OPEN_IN_IMP_SUBSET) THEN + ASM_SIMP_TAC[GSYM LE_ANTISYM; DIM_SUBSET] THEN + REWRITE_TAC[GSYM INT_OF_NUM_LE] THEN + MATCH_MP_TAC INT_LE_TRANS THEN EXISTS_TAC `aff_dim(s:real^N->bool)` THEN + REWRITE_TAC[AFF_DIM_LE_DIM] THEN ASM_SIMP_TAC[GSYM AFF_DIM_DIM_SUBSPACE] THEN + MATCH_MP_TAC INT_EQ_IMP_LE THEN CONV_TAC SYM_CONV THEN + MATCH_MP_TAC AFF_DIM_OPEN_IN THEN ASM_SIMP_TAC[SUBSPACE_IMP_AFFINE]);; + +let AFF_DIM_CONVEX_INTER_NONEMPTY_INTERIOR = prove + (`!s t:real^N->bool. + convex s /\ ~(s INTER interior t = {}) + ==> aff_dim(s INTER t) = aff_dim s`, + ONCE_REWRITE_TAC[GSYM AFF_DIM_AFFINE_HULL] THEN + ASM_SIMP_TAC[AFFINE_HULL_CONVEX_INTER_NONEMPTY_INTERIOR] THEN + REWRITE_TAC[AFF_DIM_AFFINE_HULL]);; + +let AFF_DIM_CONVEX_INTER_OPEN = prove + (`!s t:real^N->bool. + convex s /\ open t /\ ~(s INTER t = {}) + ==> aff_dim(s INTER t) = aff_dim s`, + ONCE_REWRITE_TAC[GSYM AFF_DIM_AFFINE_HULL] THEN + ASM_SIMP_TAC[AFFINE_HULL_CONVEX_INTER_OPEN] THEN + REWRITE_TAC[AFF_DIM_AFFINE_HULL]);; + +let AFFINE_HULL_HALFSPACE_LT = prove + (`!a b. affine hull {x | a dot x < b} = + if a = vec 0 /\ b <= &0 then {} else (:real^N)`, + REPEAT GEN_TAC THEN COND_CASES_TAC THEN + ASM_SIMP_TAC[AFFINE_HULL_EQ_EMPTY; HALFSPACE_EQ_EMPTY_LT; + AFFINE_HULL_OPEN; OPEN_HALFSPACE_LT]);; + +let AFFINE_HULL_HALFSPACE_LE = prove + (`!a b. affine hull {x | a dot x <= b} = + if a = vec 0 /\ b < &0 then {} else (:real^N)`, + REPEAT GEN_TAC THEN ASM_CASES_TAC `a:real^N = vec 0` THENL + [ASM_SIMP_TAC[DOT_LZERO; SET_RULE `{x | p} = if p then UNIV else {}`] THEN + COND_CASES_TAC THEN ASM_SIMP_TAC[AFFINE_HULL_EMPTY; AFFINE_HULL_UNIV] THEN + COND_CASES_TAC THEN REWRITE_TAC[] THEN ASM_REAL_ARITH_TAC; + ASM_SIMP_TAC[GSYM CLOSURE_HALFSPACE_LT; AFFINE_HULL_CLOSURE] THEN + ASM_REWRITE_TAC[AFFINE_HULL_HALFSPACE_LT]]);; + +let AFFINE_HULL_HALFSPACE_GT = prove + (`!a b. affine hull {x | a dot x > b} = + if a = vec 0 /\ b >= &0 then {} else (:real^N)`, + REPEAT GEN_TAC THEN COND_CASES_TAC THEN + ASM_SIMP_TAC[AFFINE_HULL_EQ_EMPTY; HALFSPACE_EQ_EMPTY_GT; + AFFINE_HULL_OPEN; OPEN_HALFSPACE_GT]);; + +let AFFINE_HULL_HALFSPACE_GE = prove + (`!a b. affine hull {x | a dot x >= b} = + if a = vec 0 /\ b > &0 then {} else (:real^N)`, + REPEAT GEN_TAC THEN + MP_TAC(ISPECL [`--a:real^N`; `--b:real`] AFFINE_HULL_HALFSPACE_LE) THEN + SIMP_TAC[real_ge; DOT_LNEG; REAL_LE_NEG2; VECTOR_NEG_EQ_0] THEN + REWRITE_TAC[REAL_ARITH `--b < &0 <=> b > &0`]);; + +let AFF_DIM_HALFSPACE_LT = prove + (`!a:real^N b. + aff_dim {x | a dot x < b} = + if a = vec 0 /\ b <= &0 then --(&1) else &(dimindex(:N))`, + REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[GSYM AFF_DIM_AFFINE_HULL] THEN + SIMP_TAC[AFFINE_HULL_HALFSPACE_LT] THEN COND_CASES_TAC THEN + ASM_REWRITE_TAC[AFF_DIM_EMPTY; AFF_DIM_UNIV]);; + +let AFF_DIM_HALFSPACE_LE = prove + (`!a:real^N b. + aff_dim {x | a dot x <= b} = + if a = vec 0 /\ b < &0 then --(&1) else &(dimindex(:N))`, + REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[GSYM AFF_DIM_AFFINE_HULL] THEN + SIMP_TAC[AFFINE_HULL_HALFSPACE_LE] THEN COND_CASES_TAC THEN + ASM_REWRITE_TAC[AFF_DIM_EMPTY; AFF_DIM_UNIV]);; + +let AFF_DIM_HALFSPACE_GT = prove + (`!a:real^N b. + aff_dim {x | a dot x > b} = + if a = vec 0 /\ b >= &0 then --(&1) else &(dimindex(:N))`, + REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[GSYM AFF_DIM_AFFINE_HULL] THEN + SIMP_TAC[AFFINE_HULL_HALFSPACE_GT] THEN COND_CASES_TAC THEN + ASM_REWRITE_TAC[AFF_DIM_EMPTY; AFF_DIM_UNIV]);; + +let AFF_DIM_HALFSPACE_GE = prove + (`!a:real^N b. + aff_dim {x | a dot x >= b} = + if a = vec 0 /\ b > &0 then --(&1) else &(dimindex(:N))`, + REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[GSYM AFF_DIM_AFFINE_HULL] THEN + SIMP_TAC[AFFINE_HULL_HALFSPACE_GE] THEN COND_CASES_TAC THEN + ASM_REWRITE_TAC[AFF_DIM_EMPTY; AFF_DIM_UNIV]);; + +let CHOOSE_AFFINE_SUBSET = prove + (`!s:real^N->bool d. + affine s /\ --(&1) <= d /\ d <= aff_dim s + ==> ?t. affine t /\ t SUBSET s /\ aff_dim t = d`, + REPEAT GEN_TAC THEN ASM_CASES_TAC `d:int = --(&1)` THENL + [STRIP_TAC THEN EXISTS_TAC `{}:real^N->bool` THEN + ASM_REWRITE_TAC[EMPTY_SUBSET; AFFINE_EMPTY; AFF_DIM_EMPTY]; + ASM_SIMP_TAC[INT_ARITH + `~(d:int = --(&1)) ==> (--(&1) <= d <=> &0 <= d)`] THEN + POP_ASSUM(K ALL_TAC)] THEN + ASM_CASES_TAC `s:real^N->bool = {}` THENL + [ASM_REWRITE_TAC[AFF_DIM_EMPTY] THEN INT_ARITH_TAC; + POP_ASSUM MP_TAC] THEN + GEN_REWRITE_TAC LAND_CONV [GSYM MEMBER_NOT_EMPTY] THEN + DISCH_THEN(X_CHOOSE_THEN `a:real^N` MP_TAC) THEN + GEOM_ORIGIN_TAC `a:real^N` THEN + SIMP_TAC[IMP_CONJ; AFF_DIM_DIM_SUBSPACE; AFFINE_EQ_SUBSPACE] THEN + REPEAT GEN_TAC THEN DISCH_TAC THEN DISCH_TAC THEN + REWRITE_TAC[GSYM INT_OF_NUM_EXISTS] THEN + DISCH_THEN(X_CHOOSE_THEN `n:num` SUBST1_TAC) THEN + REWRITE_TAC[INT_OF_NUM_LE] THEN DISCH_TAC THEN + MP_TAC(ISPECL [`s:real^N->bool`; `n:num`] + CHOOSE_SUBSPACE_OF_SUBSPACE) THEN + ASM_SIMP_TAC[SPAN_OF_SUBSPACE] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `t:real^N->bool` THEN + ASM_SIMP_TAC[AFF_DIM_DIM_SUBSPACE; SUBSPACE_IMP_AFFINE]);; + +(* ------------------------------------------------------------------------- *) +(* Existence of a rigid transform between congruent sets. *) +(* ------------------------------------------------------------------------- *) + +let RIGID_TRANSFORMATION_BETWEEN_CONGRUENT_SETS = prove + (`!x:A->real^N y:A->real^N s. + (!i j. i IN s /\ j IN s ==> dist(x i,x j) = dist(y i,y j)) + ==> ?a f. orthogonal_transformation f /\ + !i. i IN s ==> y i = a + f(x i)`, + let lemma = prove + (`!x:(real^N)^M y:(real^N)^M. + (!i j. 1 <= i /\ i <= dimindex(:M) /\ + 1 <= j /\ j <= dimindex(:M) + ==> dist(x$i,x$j) = dist(y$i,y$j)) + ==> ?a f. orthogonal_transformation f /\ + !i. 1 <= i /\ i <= dimindex(:M) + ==> y$i = a + f(x$i)`, + REPEAT STRIP_TAC THEN + ABBREV_TAC `(X:real^M^N) = lambda i j. (x:real^N^M)$j$i - x$1$i` THEN + ABBREV_TAC `(Y:real^M^N) = lambda i j. (y:real^N^M)$j$i - y$1$i` THEN + SUBGOAL_THEN `transp(X:real^M^N) ** X = transp(Y:real^M^N) ** Y` + ASSUME_TAC THENL + [REWRITE_TAC[MATRIX_MUL_LTRANSP_DOT_COLUMN] THEN + MAP_EVERY EXPAND_TAC ["X"; "Y"] THEN + SIMP_TAC[CART_EQ; column; LAMBDA_BETA; dot] THEN + REWRITE_TAC[GSYM VECTOR_SUB_COMPONENT; GSYM dot] THEN + REWRITE_TAC[DOT_NORM_SUB; VECTOR_ARITH + `(x - a) - (y - a):real^N = x - y`] THEN + ASM_SIMP_TAC[GSYM dist; DIMINDEX_GE_1; LE_REFL]; + ALL_TAC] THEN + SUBGOAL_THEN + `?M:real^N^N. orthogonal_matrix M /\ (Y:real^M^N) = M ** (X:real^M^N)` + (CHOOSE_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THENL + [ALL_TAC; + GEN_REWRITE_TAC (LAND_CONV o TOP_DEPTH_CONV) [CART_EQ] THEN + MAP_EVERY EXPAND_TAC ["X"; "Y"] THEN + SIMP_TAC[LAMBDA_BETA; matrix_mul] THEN + REWRITE_TAC[REAL_ARITH `x - y:real = z <=> x = y + z`] THEN STRIP_TAC THEN + EXISTS_TAC `(y:real^N^M)$1 - (M:real^N^N) ** (x:real^N^M)$1` THEN + EXISTS_TAC `\x:real^N. (M:real^N^N) ** x` THEN + ASM_SIMP_TAC[ORTHOGONAL_TRANSFORMATION_MATRIX; + MATRIX_OF_MATRIX_VECTOR_MUL; MATRIX_VECTOR_MUL_LINEAR] THEN + SIMP_TAC[CART_EQ; matrix_vector_mul; LAMBDA_BETA; + VECTOR_ADD_COMPONENT] THEN + ASM_SIMP_TAC[REAL_SUB_LDISTRIB; SUM_SUB_NUMSEG] THEN + REWRITE_TAC[VECTOR_SUB_COMPONENT; REAL_ARITH + `a + y - b:real = a - z + y <=> z = b`] THEN + SIMP_TAC[LAMBDA_BETA]] THEN + MP_TAC(ISPEC `transp(X:real^M^N) ** X` + SYMMETRIC_MATRIX_DIAGONALIZABLE_EXPLICIT) THEN + REWRITE_TAC[MATRIX_TRANSP_MUL; TRANSP_TRANSP; LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`P:real^M^M`; `d:num->real`] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + DISCH_THEN(fun th -> MP_TAC th THEN ASM_REWRITE_TAC[] THEN MP_TAC th) THEN + REWRITE_TAC[MATRIX_MUL_ASSOC; GSYM MATRIX_TRANSP_MUL] THEN + REWRITE_TAC[GSYM MATRIX_MUL_ASSOC; LEFT_IMP_EXISTS_THM] THEN + REWRITE_TAC[IMP_IMP] THEN + GEN_REWRITE_TAC (LAND_CONV o TOP_DEPTH_CONV) [CART_EQ] THEN + SIMP_TAC[MATRIX_MUL_LTRANSP_DOT_COLUMN; LAMBDA_BETA] THEN STRIP_TAC THEN + MP_TAC(ISPECL [`\i. column i ((X:real^M^N) ** (P:real^M^M))`; + `\i. column i ((Y:real^M^N) ** (P:real^M^M))`; + `1..dimindex(:M)`] + ORTHOGONAL_TRANSFORMATION_BETWEEN_ORTHOGONAL_SETS) THEN + REWRITE_TAC[IN_NUMSEG] THEN ANTS_TAC THENL + [ASM_SIMP_TAC[pairwise; IN_NUMSEG; NORM_EQ; orthogonal]; ALL_TAC] THEN + DISCH_THEN(X_CHOOSE_THEN `f:real^N->real^N` (STRIP_ASSUME_TAC o GSYM)) THEN + EXISTS_TAC `matrix(f:real^N->real^N)` THEN CONJ_TAC THENL + [ASM_MESON_TAC[ORTHOGONAL_TRANSFORMATION_MATRIX]; ALL_TAC] THEN + SUBGOAL_THEN + `!M:real^M^N. M = M ** (P:real^M^M) ** transp P` + (fun th -> GEN_REWRITE_TAC BINOP_CONV [th]) + THENL + [ASM_MESON_TAC[orthogonal_matrix; MATRIX_MUL_RID]; + REWRITE_TAC[MATRIX_MUL_ASSOC] THEN AP_THM_TAC THEN AP_TERM_TAC] THEN + REWRITE_TAC[GSYM MATRIX_MUL_ASSOC] THEN + ASM_SIMP_TAC[MATRIX_EQUAL_COLUMNS] THEN + X_GEN_TAC `i:num` THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [orthogonal_transformation]) THEN + DISCH_THEN(ASSUME_TAC o GSYM o MATCH_MP MATRIX_WORKS o CONJUNCT1) THEN + ASM_REWRITE_TAC[] THEN + SIMP_TAC[CART_EQ; matrix_vector_mul; column; LAMBDA_BETA] THEN + X_GEN_TAC `j:num` THEN STRIP_TAC THEN + GEN_REWRITE_TAC (RAND_CONV o ONCE_DEPTH_CONV) [matrix_mul] THEN + ASM_SIMP_TAC[LAMBDA_BETA]) in + REPEAT GEN_TAC THEN ASM_CASES_TAC `s:A->bool = {}` THENL + [REPEAT STRIP_TAC THEN + MAP_EVERY EXISTS_TAC [`vec 0:real^N`; `\x:real^N. x`] THEN + ASM_REWRITE_TAC[NOT_IN_EMPTY; ORTHOGONAL_TRANSFORMATION_ID]; + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN + DISCH_THEN(X_CHOOSE_TAC `m:A`) THEN DISCH_TAC] THEN + SUBGOAL_THEN + `?r. IMAGE r (1..dimindex(:(N,1)finite_sum)) SUBSET s /\ + affine hull (IMAGE (y o r) (1..dimindex(:(N,1)finite_sum))) = + affine hull (IMAGE (y:A->real^N) s)` + MP_TAC THENL + [REWRITE_TAC[GSYM SUBSET_ANTISYM_EQ] THEN + SIMP_TAC[IMAGE_o; TAUT `p /\ q <=> ~(p ==> ~q)`; + HULL_MONO; IMAGE_SUBSET] THEN REWRITE_TAC[NOT_IMP] THEN + MP_TAC(ISPEC `IMAGE (y:A->real^N) s` AFFINE_BASIS_EXISTS) THEN + DISCH_THEN(X_CHOOSE_THEN `b:real^N->bool` STRIP_ASSUME_TAC) THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [AFFINE_INDEPENDENT_IFF_CARD]) THEN + STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [FINITE_INDEX_NUMSEG]) THEN + DISCH_THEN(X_CHOOSE_THEN `f:num->real^N` STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN `CARD(b:real^N->bool) <= dimindex(:(N,1)finite_sum)` + ASSUME_TAC THENL + [REWRITE_TAC[GSYM INT_OF_NUM_LE] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (INT_ARITH + `a:int = c - &1 ==> a + &1 <= n ==> c <= n`)) THEN + REWRITE_TAC[DIMINDEX_FINITE_SUM; DIMINDEX_1; GSYM INT_OF_NUM_ADD] THEN + REWRITE_TAC[INT_LE_RADD; AFF_DIM_LE_UNIV]; + ALL_TAC] THEN + UNDISCH_TAC `b SUBSET IMAGE (y:A->real^N) s` THEN + ONCE_ASM_REWRITE_TAC[] THEN REWRITE_TAC[SUBSET; FORALL_IN_IMAGE] THEN + REWRITE_TAC[IN_IMAGE] THEN + GEN_REWRITE_TAC (LAND_CONV o DEPTH_CONV) [RIGHT_IMP_EXISTS_THM] THEN + REWRITE_TAC[SKOLEM_THM; IN_NUMSEG] THEN + DISCH_THEN(X_CHOOSE_THEN `r:num->A` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `\i. if i <= CARD(b:real^N->bool) then r i else (m:A)` THEN + CONJ_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN + UNDISCH_THEN `affine hull b:real^N->bool = affine hull IMAGE y (s:A->bool)` + (SUBST1_TAC o SYM) THEN + REWRITE_TAC[GSYM SUBSET] THEN MATCH_MP_TAC HULL_MONO THEN + ONCE_ASM_REWRITE_TAC[] THEN + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; IN_NUMSEG] THEN + X_GEN_TAC `i:num` THEN STRIP_TAC THEN REWRITE_TAC[GSYM IMAGE_o] THEN + REWRITE_TAC[IN_IMAGE; IN_NUMSEG] THEN EXISTS_TAC `i:num` THEN + ASM_REWRITE_TAC[o_THM] THEN ASM_MESON_TAC[LE_TRANS]; + REWRITE_TAC[SUBSET; IN_NUMSEG; FORALL_IN_IMAGE] THEN + STRIP_TAC THEN MP_TAC(ISPECL + [`(lambda i. x(r i:A)):real^N^(N,1)finite_sum`; + `(lambda i. y(r i:A)):real^N^(N,1)finite_sum`] lemma) THEN + ASM_SIMP_TAC[LAMBDA_BETA] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `a:real^N` THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `f:real^N->real^N` THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + X_GEN_TAC `k:A` THEN STRIP_TAC THEN + SUBGOAL_THEN + `!z. z IN + affine hull IMAGE (y o (r:num->A)) (1..dimindex(:(N,1)finite_sum)) + ==> dist(z,y k) = dist(z,a + (f:real^N->real^N)(x k))` + MP_TAC THENL + [MATCH_MP_TAC SAME_DISTANCES_TO_AFFINE_HULL THEN + REWRITE_TAC[FORALL_IN_IMAGE; o_THM; IN_NUMSEG] THEN + X_GEN_TAC `j:num` THEN STRIP_TAC THEN MATCH_MP_TAC EQ_TRANS THEN + EXISTS_TAC `dist(x(r(j:num)),(x:A->real^N) k)` THEN CONJ_TAC THENL + [CONV_TAC SYM_CONV THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_SIMP_TAC[]; + REWRITE_TAC[dist] THEN ASM_SIMP_TAC[NORM_ARITH + `(a + x) - (a + y):real^N = x - y`] THEN + ASM_MESON_TAC[ORTHOGONAL_TRANSFORMATION; LINEAR_SUB]]; + ASM_SIMP_TAC[NORM_ARITH + `a:real^N = b <=> dist(a:real^N,a) = dist(a,b)`] THEN + DISCH_THEN MATCH_MP_TAC THEN MATCH_MP_TAC HULL_INC THEN + REWRITE_TAC[IN_IMAGE; IN_NUMSEG] THEN ASM_MESON_TAC[]]]);; + +let RIGID_TRANSFORMATION_BETWEEN_CONGRUENT_SETS_STRONG = prove + (`!x:A->real^N y:A->real^N s t. + t SUBSET s /\ affine hull (IMAGE y t) = affine hull (IMAGE y s) /\ + (!i j. i IN s /\ j IN t ==> dist(x i,x j) = dist(y i,y j)) + ==> ?a f. orthogonal_transformation f /\ + !i. i IN s ==> y i = a + f(x i)`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`x:A->real^N`; `y:A->real^N`; `t:A->bool`] + RIGID_TRANSFORMATION_BETWEEN_CONGRUENT_SETS) THEN + ANTS_TAC THENL [ASM_MESON_TAC[SUBSET]; ALL_TAC] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `a:real^N` THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `f:real^N->real^N` THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN X_GEN_TAC `i:A` THEN DISCH_TAC THEN + SUBGOAL_THEN + `!z. z IN affine hull (IMAGE (y:A->real^N) t) + ==> dist(z,y i) = dist(z,a + (f:real^N->real^N)(x i))` + MP_TAC THENL + [MATCH_MP_TAC SAME_DISTANCES_TO_AFFINE_HULL THEN + REWRITE_TAC[FORALL_IN_IMAGE; o_THM; IN_NUMSEG] THEN + X_GEN_TAC `j:A` THEN STRIP_TAC THEN MATCH_MP_TAC EQ_TRANS THEN + EXISTS_TAC `dist(a + f(x(j:A):real^N):real^N,a + f(x i))` THEN + CONJ_TAC THENL [ALL_TAC; ASM_MESON_TAC[]] THEN + REWRITE_TAC[NORM_ARITH `dist(a + x:real^N,a + y) = dist(x,y)`] THEN + ASM_MESON_TAC[ORTHOGONAL_TRANSFORMATION_ISOMETRY; DIST_SYM]; + ASM_SIMP_TAC[NORM_ARITH + `a:real^N = b <=> dist(a:real^N,a) = dist(a,b)`] THEN + DISCH_THEN MATCH_MP_TAC THEN MATCH_MP_TAC HULL_INC THEN + REWRITE_TAC[IN_IMAGE] THEN ASM_MESON_TAC[]]);; + +let RIGID_TRANSFORMATION_BETWEEN_3 = prove + (`!a b c a' b' c':real^N. + dist(a,b) = dist(a',b') /\ + dist(b,c) = dist(b',c') /\ + dist(c,a) = dist(c',a') + ==> ?k f. orthogonal_transformation f /\ + a' = k + f a /\ b' = k + f b /\ c' = k + f c`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL + [`FST:real^N#real^N->real^N`; `SND:real^N#real^N->real^N`; + `{(a:real^N,a':real^N), (b,b'), (c,c')}`] + RIGID_TRANSFORMATION_BETWEEN_CONGRUENT_SETS) THEN + REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_INSERT] THEN + REWRITE_TAC[NOT_IN_EMPTY; IMP_IMP] THEN DISCH_THEN MATCH_MP_TAC THEN + ASM_MESON_TAC[DIST_REFL; DIST_SYM]);; + +let RIGID_TRANSFORMATION_BETWEEN_2 = prove + (`!a b a' b':real^N. + dist(a,b) = dist(a',b') + ==> ?k f. orthogonal_transformation f /\ + a' = k + f a /\ b' = k + f b`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`a:real^N`; `b:real^N`; `a:real^N`; + `a':real^N`; `b':real^N`; `a':real^N`] + RIGID_TRANSFORMATION_BETWEEN_3) THEN + ASM_MESON_TAC[DIST_EQ_0; DIST_SYM]);; + +(* ------------------------------------------------------------------------- *) +(* Caratheodory's theorem. *) +(* ------------------------------------------------------------------------- *) + +let CONVEX_HULL_CARATHEODORY_AFF_DIM = prove + (`!p. convex hull p = + {y:real^N | ?s u. FINITE s /\ s SUBSET p /\ + &(CARD s) <= aff_dim p + &1 /\ + (!x. x IN s ==> &0 <= u x) /\ + sum s u = &1 /\ vsum s (\v. u v % v) = y}`, + GEN_TAC THEN REWRITE_TAC[CONVEX_HULL_EXPLICIT] THEN + REWRITE_TAC[EXTENSION; IN_ELIM_THM] THEN X_GEN_TAC `y:real^N` THEN + EQ_TAC THENL [ALL_TAC; MESON_TAC[]] THEN + MATCH_MP_TAC(TAUT `!q. (p ==> q) /\ (q ==> r) ==> (p ==> r)`) THEN + EXISTS_TAC `?n s u. CARD s = n /\ + FINITE s /\ s SUBSET p /\ + (!x. x IN s ==> &0 <= u x) /\ + sum s u = &1 /\ vsum s (\v. u v % v) = (y:real^N)` THEN + CONJ_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN + GEN_REWRITE_TAC LAND_CONV [num_WOP] THEN + DISCH_THEN(X_CHOOSE_THEN `n:num` MP_TAC) THEN + DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN + REPEAT(MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC) THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + GEN_REWRITE_TAC I [GSYM INT_NOT_LT] THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `n - 1`) THEN REWRITE_TAC[NOT_IMP] THEN + CONJ_TAC THENL + [MATCH_MP_TAC(ARITH_RULE `~(n = 0) ==> n - 1 < n`) THEN + DISCH_THEN SUBST_ALL_TAC THEN + UNDISCH_TAC `aff_dim(p:real^N->bool) + &1 < &0` THEN + REWRITE_TAC[INT_ARITH `p + &1:int < &0 <=> ~(-- &1 <= p)`] THEN + REWRITE_TAC[AFF_DIM_GE]; + ALL_TAC] THEN + MP_TAC(ISPEC `s:real^N->bool` AFF_DIM_AFFINE_INDEPENDENT) THEN + ASM_REWRITE_TAC[] THEN + SUBGOAL_THEN `~(aff_dim(s:real^N->bool) = &n - &1)` ASSUME_TAC THENL + [FIRST_ASSUM(MP_TAC o MATCH_MP AFF_DIM_SUBSET) THEN + + UNDISCH_TAC `aff_dim(p:real^N->bool) + &1 < &n` THEN + INT_ARITH_TAC; + ALL_TAC] THEN + ASM_SIMP_TAC[AFFINE_DEPENDENT_EXPLICIT_FINITE] THEN + DISCH_THEN(X_CHOOSE_THEN `w:real^N->real` STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN + `?t. (!v:real^N. v IN s ==> u(v) + t * w(v) >= &0) /\ + ?a. a IN s /\ u(a) + t * w(a) = &0` + STRIP_ASSUME_TAC THENL + [ABBREV_TAC + `i = IMAGE (\v. u(v) / --w(v)) {v:real^N | v IN s /\ w v < &0}` THEN + EXISTS_TAC `inf i` THEN MP_TAC(SPEC `i:real->bool` INF_FINITE) THEN + ANTS_TAC THENL + [EXPAND_TAC "i" THEN + ASM_SIMP_TAC[FINITE_IMAGE; FINITE_RESTRICT; IMAGE_EQ_EMPTY] THEN + REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; IN_ELIM_THM] THEN + MP_TAC(ISPECL [`w:real^N->real`; `s:real^N->bool`] SUM_ZERO_EXISTS) THEN + ASM_REWRITE_TAC[] THEN ASM_MESON_TAC[]; + ALL_TAC] THEN + ABBREV_TAC `t = inf i` THEN + EXPAND_TAC "i" THEN REWRITE_TAC[FORALL_IN_IMAGE] THEN + REWRITE_TAC[IN_IMAGE; IN_ELIM_THM] THEN + DISCH_THEN(CONJUNCTS_THEN2 (X_CHOOSE_THEN `a:real^N` + STRIP_ASSUME_TAC) MP_TAC) THEN + SIMP_TAC[REAL_LE_RDIV_EQ; REAL_ARITH `x < &0 ==> &0 < --x`; real_ge] THEN + REWRITE_TAC[REAL_ARITH `t * --w <= u <=> &0 <= u + t * w`] THEN + STRIP_TAC THEN CONJ_TAC THENL + [X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN + DISJ_CASES_TAC(REAL_ARITH `(w:real^N->real) x < &0 \/ &0 <= w x`) THEN + ASM_SIMP_TAC[] THEN MATCH_MP_TAC REAL_LE_ADD THEN ASM_SIMP_TAC[] THEN + MATCH_MP_TAC REAL_LE_MUL THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC REAL_LE_DIV THEN ASM_SIMP_TAC[] THEN + MATCH_MP_TAC(REAL_ARITH `w < &0 ==> &0 <= --w`) THEN ASM_REWRITE_TAC[]; + EXISTS_TAC `a:real^N` THEN ASM_REWRITE_TAC[] THEN + UNDISCH_TAC `w(a:real^N) < &0` THEN CONV_TAC REAL_FIELD]; + ALL_TAC] THEN + MAP_EVERY EXISTS_TAC + [`s DELETE (a:real^N)`; `(\v. u(v) + t * w(v)):real^N->real`] THEN + ASM_SIMP_TAC[SUM_DELETE; VSUM_DELETE; CARD_DELETE; FINITE_DELETE] THEN + ASM_SIMP_TAC[SUM_ADD; VECTOR_ADD_RDISTRIB; VSUM_ADD] THEN + ASM_SIMP_TAC[GSYM VECTOR_MUL_ASSOC; SUM_LMUL; VSUM_LMUL] THEN + REPEAT CONJ_TAC THENL + [ASM SET_TAC[]; ASM SET_TAC[real_ge]; REAL_ARITH_TAC; VECTOR_ARITH_TAC]);; + +let CARATHEODORY_AFF_DIM = prove + (`!p. convex hull p = + {x:real^N | ?s. FINITE s /\ s SUBSET p /\ + &(CARD s) <= aff_dim p + &1 /\ + x IN convex hull s}`, + REWRITE_TAC[EXTENSION; IN_ELIM_THM] THEN REPEAT GEN_TAC THEN EQ_TAC THENL + [GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) + [CONVEX_HULL_CARATHEODORY_AFF_DIM] THEN + REWRITE_TAC[IN_ELIM_THM] THEN MATCH_MP_TAC MONO_EXISTS THEN + ASM_MESON_TAC[HULL_SUBSET; CONVEX_EXPLICIT; CONVEX_CONVEX_HULL]; + MESON_TAC[SUBSET; HULL_MONO]]);; + +let CONVEX_HULL_CARATHEODORY = prove + (`!p. convex hull p = + {y:real^N | ?s u. FINITE s /\ s SUBSET p /\ + CARD(s) <= dimindex(:N) + 1 /\ + (!x. x IN s ==> &0 <= u x) /\ + sum s u = &1 /\ vsum s (\v. u v % v) = y}`, + + GEN_TAC THEN REWRITE_TAC[EXTENSION] THEN X_GEN_TAC `y:real^N` THEN + EQ_TAC THENL + [REWRITE_TAC[CONVEX_HULL_CARATHEODORY_AFF_DIM; IN_ELIM_THM] THEN + REPEAT(MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC) THEN + STRIP_TAC THEN + ASM_REWRITE_TAC[GSYM INT_OF_NUM_LE; GSYM INT_OF_NUM_ADD] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (INT_ARITH + `a:int <= x + &1 ==> x <= y ==> a <= y + &1`)) THEN + REWRITE_TAC[AFF_DIM_LE_UNIV]; + REWRITE_TAC[CONVEX_HULL_EXPLICIT; IN_ELIM_THM] THEN MESON_TAC[]]);; + +let CARATHEODORY = prove + (`!p. convex hull p = + {x:real^N | ?s. FINITE s /\ s SUBSET p /\ + CARD(s) <= dimindex(:N) + 1 /\ + x IN convex hull s}`, + REWRITE_TAC[EXTENSION; IN_ELIM_THM] THEN REPEAT GEN_TAC THEN EQ_TAC THENL + [GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) + [CONVEX_HULL_CARATHEODORY] THEN + REWRITE_TAC[IN_ELIM_THM] THEN MATCH_MP_TAC MONO_EXISTS THEN + ASM_MESON_TAC[HULL_SUBSET; CONVEX_EXPLICIT; CONVEX_CONVEX_HULL]; + MESON_TAC[SUBSET; HULL_MONO]]);; + +(* ------------------------------------------------------------------------- *) +(* Some results on decomposing convex hulls, e.g. simplicial subdivision. *) +(* ------------------------------------------------------------------------- *) + +let AFFINE_HULL_INTER,CONVEX_HULL_INTER = (CONJ_PAIR o prove) + (`(!s t:real^N->bool. + ~(affine_dependent(s UNION t)) + ==> affine hull s INTER affine hull t = affine hull (s INTER t)) /\ + (!s t:real^N->bool. + ~(affine_dependent (s UNION t)) + ==> convex hull s INTER convex hull t = convex hull (s INTER t))`, + CONJ_TAC THEN + (REPEAT STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o MATCH_MP AFFINE_INDEPENDENT_IMP_FINITE) THEN + REWRITE_TAC[FINITE_UNION] THEN STRIP_TAC THEN + MATCH_MP_TAC SUBSET_ANTISYM THEN REWRITE_TAC[SUBSET_INTER] THEN + SIMP_TAC[HULL_MONO; INTER_SUBSET] THEN + REWRITE_TAC[SUBSET; AFFINE_HULL_FINITE; CONVEX_HULL_FINITE; + IN_ELIM_THM; IN_INTER] THEN + X_GEN_TAC `y:real^N` THEN DISCH_THEN(CONJUNCTS_THEN2 + (X_CHOOSE_THEN `u:real^N->real` STRIP_ASSUME_TAC) + (X_CHOOSE_THEN `v:real^N->real` STRIP_ASSUME_TAC)) THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE RAND_CONV + [AFFINE_DEPENDENT_EXPLICIT]) THEN + REWRITE_TAC[NOT_EXISTS_THM] THEN + DISCH_THEN(MP_TAC o SPEC `(s UNION t):real^N->bool`) THEN + ASM_REWRITE_TAC[SUBSET_REFL] THEN + DISCH_THEN(MP_TAC o SPEC + `\x:real^N. (if x IN s then u x else &0) - + (if x IN t then v x else &0)`) THEN + ASM_SIMP_TAC[SUM_SUB; FINITE_UNION; VSUM_SUB; VECTOR_SUB_RDISTRIB] THEN + REWRITE_TAC[MESON[] + `(if p then a else b) % x = (if p then a % x else b % x)`] THEN + ASM_SIMP_TAC[SUM_CASES; VSUM_CASES; VECTOR_MUL_LZERO; FINITE_UNION] THEN + ASM_REWRITE_TAC[SUM_0; VSUM_0; + SET_RULE `{x | x IN (s UNION t) /\ x IN s} = s`; + SET_RULE `{x | x IN (s UNION t) /\ x IN t} = t`] THEN + MATCH_MP_TAC(TAUT `a /\ c /\ (~b ==> d) ==> ~(a /\ b /\ c) ==> d`) THEN + REPEAT CONJ_TAC THENL [REAL_ARITH_TAC; VECTOR_ARITH_TAC; ALL_TAC] THEN + DISCH_TAC THEN EXISTS_TAC `u:real^N->real` THEN ASM_SIMP_TAC[] THEN + CONJ_TAC THEN MATCH_MP_TAC EQ_TRANS THENL + [EXISTS_TAC `sum s (u:real^N->real)`; + EXISTS_TAC `vsum s (\x. (u:real^N->real) x % x)`] THEN + (CONJ_TAC THENL [ALL_TAC; FIRST_X_ASSUM ACCEPT_TAC]) THEN + CONV_TAC SYM_CONV THENL + [MATCH_MP_TAC SUM_EQ_SUPERSET; MATCH_MP_TAC VSUM_EQ_SUPERSET] THEN + ASM_SIMP_TAC[FINITE_INTER; INTER_SUBSET; IN_INTER] THEN + X_GEN_TAC `x:real^N` THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + ASM_REWRITE_TAC[VECTOR_MUL_EQ_0] THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [NOT_EXISTS_THM]) THEN + DISCH_THEN(MP_TAC o SPEC `x:real^N`) THEN + ASM_REWRITE_TAC[REAL_SUB_RZERO] THEN ASM SET_TAC[]));; + +let AFFINE_HULL_INTERS = prove + (`!s:(real^N->bool)->bool. + ~(affine_dependent(UNIONS s)) + ==> affine hull (INTERS s) = INTERS {affine hull t | t IN s}`, + REPEAT STRIP_TAC THEN FIRST_X_ASSUM(fun th -> + MP_TAC th THEN MP_TAC(MATCH_MP AFFINE_INDEPENDENT_IMP_FINITE th)) THEN + SPEC_TAC(`s:(real^N->bool)->bool`,`s:(real^N->bool)->bool`) THEN + REWRITE_TAC[FINITE_UNIONS; IMP_CONJ] THEN + MATCH_MP_TAC FINITE_INDUCT_STRONG THEN + REWRITE_TAC[UNIONS_0; INTERS_0; UNIONS_INSERT; INTERS_INSERT; + SET_RULE `{f x | x IN {}} = {}`; AFFINE_HULL_UNIV] THEN + MAP_EVERY X_GEN_TAC [`s:real^N->bool`; `f:(real^N->bool)->bool`] THEN + DISCH_THEN(CONJUNCTS_THEN2 MP_TAC STRIP_ASSUME_TAC) THEN + REWRITE_TAC[FORALL_IN_INSERT] THEN + DISCH_THEN(fun th -> STRIP_TAC THEN STRIP_TAC THEN MP_TAC th) THEN + ASM_REWRITE_TAC[] THEN ANTS_TAC THENL + [UNDISCH_TAC `~affine_dependent((s UNION UNIONS f):real^N->bool)` THEN + REWRITE_TAC[CONTRAPOS_THM] THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] AFFINE_DEPENDENT_MONO) THEN + SET_TAC[]; + DISCH_TAC] THEN + ASM_CASES_TAC `f:(real^N->bool)->bool = {}` THENL + [ASM_REWRITE_TAC[INTERS_0; INTER_UNIV; IN_SING] THEN + REWRITE_TAC[SET_RULE `{f x | x = a} = {f a}`; INTERS_1]; + ALL_TAC] THEN + W(MP_TAC o PART_MATCH (rhs o rand) AFFINE_HULL_INTER o lhand o snd) THEN + ANTS_TAC THENL + [UNDISCH_TAC `~affine_dependent((s UNION UNIONS f):real^N->bool)` THEN + REWRITE_TAC[CONTRAPOS_THM] THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] AFFINE_DEPENDENT_MONO) THEN + UNDISCH_TAC `~(f:(real^N->bool)->bool = {})` THEN SET_TAC[]; + DISCH_THEN(SUBST1_TAC o SYM)] THEN + REWRITE_TAC[SET_RULE + `{f x | x IN (a INSERT s)} = (f a) INSERT {f x | x IN s}`] THEN + ASM_REWRITE_TAC[INTERS_INSERT]);; + +let CONVEX_HULL_INTERS = prove + (`!s:(real^N->bool)->bool. + ~(affine_dependent(UNIONS s)) + ==> convex hull (INTERS s) = INTERS {convex hull t | t IN s}`, + REPEAT STRIP_TAC THEN FIRST_X_ASSUM(fun th -> + MP_TAC th THEN MP_TAC(MATCH_MP AFFINE_INDEPENDENT_IMP_FINITE th)) THEN + SPEC_TAC(`s:(real^N->bool)->bool`,`s:(real^N->bool)->bool`) THEN + REWRITE_TAC[FINITE_UNIONS; IMP_CONJ] THEN + MATCH_MP_TAC FINITE_INDUCT_STRONG THEN + REWRITE_TAC[UNIONS_0; INTERS_0; UNIONS_INSERT; INTERS_INSERT; + SET_RULE `{f x | x IN {}} = {}`; CONVEX_HULL_UNIV] THEN + MAP_EVERY X_GEN_TAC [`s:real^N->bool`; `f:(real^N->bool)->bool`] THEN + DISCH_THEN(CONJUNCTS_THEN2 MP_TAC STRIP_ASSUME_TAC) THEN + REWRITE_TAC[FORALL_IN_INSERT] THEN + DISCH_THEN(fun th -> STRIP_TAC THEN STRIP_TAC THEN MP_TAC th) THEN + ASM_REWRITE_TAC[] THEN ANTS_TAC THENL + [UNDISCH_TAC `~affine_dependent((s UNION UNIONS f):real^N->bool)` THEN + REWRITE_TAC[CONTRAPOS_THM] THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] AFFINE_DEPENDENT_MONO) THEN + SET_TAC[]; + DISCH_TAC] THEN + ASM_CASES_TAC `f:(real^N->bool)->bool = {}` THENL + [ASM_REWRITE_TAC[INTERS_0; INTER_UNIV; IN_SING] THEN + REWRITE_TAC[SET_RULE `{f x | x = a} = {f a}`; INTERS_1]; + ALL_TAC] THEN + W(MP_TAC o PART_MATCH (rhs o rand) CONVEX_HULL_INTER o lhand o snd) THEN + ANTS_TAC THENL + [UNDISCH_TAC `~affine_dependent((s UNION UNIONS f):real^N->bool)` THEN + REWRITE_TAC[CONTRAPOS_THM] THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] AFFINE_DEPENDENT_MONO) THEN + UNDISCH_TAC `~(f:(real^N->bool)->bool = {})` THEN SET_TAC[]; + DISCH_THEN(SUBST1_TAC o SYM)] THEN + REWRITE_TAC[SET_RULE + `{f x | x IN (a INSERT s)} = (f a) INSERT {f x | x IN s}`] THEN + ASM_REWRITE_TAC[INTERS_INSERT]);; + +let IN_CONVEX_HULL_EXCHANGE = prove + (`!s a x:real^N. + a IN convex hull s /\ x IN convex hull s + ==> ?b. b IN s /\ x IN convex hull (a INSERT (s DELETE b))`, + REPEAT STRIP_TAC THEN ASM_CASES_TAC `(a:real^N) IN s` THENL + [EXISTS_TAC `a:real^N` THEN ASM_SIMP_TAC[INSERT_DELETE]; ALL_TAC] THEN + ASM_CASES_TAC `FINITE(s:real^N->bool) /\ CARD s <= dimindex(:N) + 1` THENL + [ALL_TAC; + UNDISCH_TAC `(x:real^N) IN convex hull s` THEN + GEN_REWRITE_TAC (LAND_CONV o RAND_CONV) [CARATHEODORY] THEN + REWRITE_TAC[LEFT_IMP_EXISTS_THM; IN_ELIM_THM] THEN + X_GEN_TAC `t:real^N->bool` THEN STRIP_TAC THEN + ASM_CASES_TAC `t:real^N->bool = s` THENL [ASM_MESON_TAC[]; ALL_TAC] THEN + SUBGOAL_THEN `?b:real^N. b IN s /\ ~(b IN t)` MP_TAC THENL + [ASM SET_TAC[]; ALL_TAC] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `b:real^N` THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + UNDISCH_TAC `(x:real^N) IN convex hull t` THEN + SPEC_TAC(`x:real^N`,`x:real^N`) THEN REWRITE_TAC[GSYM SUBSET] THEN + MATCH_MP_TAC HULL_MONO THEN ASM SET_TAC[]] THEN + MP_TAC(ASSUME `(a:real^N) IN convex hull s`) THEN + MP_TAC(ASSUME `(x:real^N) IN convex hull s`) THEN + REWRITE_TAC[CONVEX_HULL_FINITE; IN_ELIM_THM; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `v:real^N->real` THEN STRIP_TAC THEN + X_GEN_TAC `u:real^N->real` THEN STRIP_TAC THEN + ASM_CASES_TAC `?b. b IN s /\ (v:real^N->real) b = &0` THENL + [FIRST_X_ASSUM(fun th -> MP_TAC th THEN MATCH_MP_TAC MONO_EXISTS) THEN + X_GEN_TAC `b:real^N` THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + EXISTS_TAC `\x:real^N. if x = a then &0 else v x` THEN + ASM_SIMP_TAC[FORALL_IN_INSERT; REAL_LE_REFL] THEN + ASM_SIMP_TAC[SUM_CLAUSES; VSUM_CLAUSES; FINITE_DELETE] THEN + ASM_REWRITE_TAC[IN_DELETE] THEN + ASM_SIMP_TAC[SUM_DELETE; VSUM_DELETE; COND_ID] THEN + ONCE_REWRITE_TAC[COND_RAND] THEN ONCE_REWRITE_TAC[COND_RATOR] THEN + ASM_SIMP_TAC[SUM_CASES; VSUM_CASES; REAL_LE_REFL; COND_ID] THEN + REWRITE_TAC[VECTOR_MUL_LZERO; SUM_0; VSUM_0] THEN + ASM_SIMP_TAC[SET_RULE `~(a IN s) ==> {x | x IN s /\ ~(x = a)} = s`] THEN + CONJ_TAC THENL [REAL_ARITH_TAC; VECTOR_ARITH_TAC]; + ALL_TAC] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [NOT_EXISTS_THM]) THEN + REWRITE_TAC[TAUT `~(a /\ b) <=> a ==> ~b`] THEN DISCH_TAC THEN + MP_TAC(ISPEC `IMAGE (\b. (u:real^N->real) b / v b) s` SUP_FINITE) THEN + ASM_CASES_TAC `s:real^N->bool = {}` THENL + [ASM_MESON_TAC[CONVEX_HULL_EMPTY; NOT_IN_EMPTY]; ALL_TAC] THEN + ASM_SIMP_TAC[FINITE_IMAGE; IMAGE_EQ_EMPTY; FORALL_IN_IMAGE] THEN + DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN + REWRITE_TAC[IN_IMAGE] THEN MATCH_MP_TAC MONO_EXISTS THEN + X_GEN_TAC `b:real^N` THEN + DISCH_THEN(CONJUNCTS_THEN2 SUBST_ALL_TAC ASSUME_TAC) THEN + ASM_REWRITE_TAC[] THEN + SUBGOAL_THEN `!b. b IN s ==> &0 < (v:real^N->real) b` ASSUME_TAC THENL + [ASM_SIMP_TAC[REAL_LT_LE]; ALL_TAC] THEN + SUBGOAL_THEN `&0 < (u:real^N->real) b /\ &0 < v b` STRIP_ASSUME_TAC THENL + [ASM_SIMP_TAC[REAL_LT_LE] THEN + UNDISCH_TAC `!x. x IN s ==> (u:real^N->real) x / v x <= u b / v b` THEN + ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN REWRITE_TAC[] THEN + DISCH_THEN(SUBST1_TAC o SYM) THEN ASM_SIMP_TAC[REAL_LE_LDIV_EQ] THEN + REWRITE_TAC[real_div; REAL_MUL_LZERO] THEN + ASM_SIMP_TAC[REAL_ARITH `&0 <= x ==> (x <= &0 <=> x = &0)`] THEN + DISCH_TAC THEN UNDISCH_TAC `sum s (u:real^N->real) = &1` THEN + MATCH_MP_TAC(REAL_ARITH `x = &0 ==> x = &1 ==> F`) THEN + ASM_SIMP_TAC[SUM_EQ_0]; + ALL_TAC] THEN + EXISTS_TAC `(\x. if x = a then v b / u b else v x - (v b / u b) * u x): + real^N->real` THEN + ASM_SIMP_TAC[FORALL_IN_INSERT; REAL_LE_DIV; REAL_LT_IMP_LE] THEN + ONCE_REWRITE_TAC[COND_RAND] THEN ONCE_REWRITE_TAC[COND_RATOR] THEN + ASM_SIMP_TAC[SUM_CLAUSES; VSUM_CLAUSES; FINITE_DELETE] THEN + ASM_SIMP_TAC[SUM_DELETE; VSUM_DELETE; IN_DELETE] THEN + ASM_SIMP_TAC[SUM_CASES; VSUM_CASES; FINITE_DELETE] THEN + ASM_SIMP_TAC[SET_RULE `~(a IN s) ==> {x | x IN s /\ ~(x = a)} = s`; + SET_RULE `~(a IN s) ==> {x | x IN s /\ x = a} = {}`] THEN + REWRITE_TAC[VSUM_CLAUSES; SUM_CLAUSES] THEN + ASM_CASES_TAC `b:real^N = a` THENL [ASM_MESON_TAC[]; ASM_REWRITE_TAC[]] THEN + ASM_SIMP_TAC[VECTOR_SUB_RDISTRIB; VSUM_SUB; SUM_SUB] THEN + REWRITE_TAC[GSYM VECTOR_MUL_ASSOC; VECTOR_ADD_LID; REAL_ADD_LID] THEN + ASM_SIMP_TAC[SUM_LMUL; VSUM_LMUL] THEN REWRITE_TAC[VECTOR_MUL_ASSOC] THEN + ASM_SIMP_TAC[REAL_DIV_RMUL; REAL_LT_IMP_NZ] THEN REPEAT CONJ_TAC THENL + [ALL_TAC; REAL_ARITH_TAC; VECTOR_ARITH_TAC] THEN + X_GEN_TAC `c:real^N` THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN + STRIP_TAC THEN ASM_CASES_TAC `(u:real^N->real) c = &0` THENL + [ASM_SIMP_TAC[REAL_MUL_RZERO; REAL_SUB_RZERO]; ALL_TAC] THEN + REWRITE_TAC[REAL_SUB_LE] THEN + ASM_SIMP_TAC[GSYM REAL_LE_RDIV_EQ; REAL_LT_LE] THEN + ONCE_REWRITE_TAC[GSYM REAL_INV_DIV] THEN MATCH_MP_TAC REAL_LE_INV2 THEN + ASM_SIMP_TAC[REAL_LT_DIV; REAL_LT_LE]);; + +let IN_CONVEX_HULL_EXCHANGE_UNIQUE = prove + (`!s t t' a x:real^N. + ~(affine_dependent s) /\ + a IN convex hull s /\ + t SUBSET s /\ t' SUBSET s /\ + x IN convex hull (a INSERT t) /\ + x IN convex hull (a INSERT t') + ==> x IN convex hull (a INSERT (t INTER t'))`, + REPEAT GEN_TAC THEN ASM_CASES_TAC `(a:real^N) IN s` THENL + [REPEAT STRIP_TAC THEN REWRITE_TAC[SET_RULE + `a INSERT (s INTER t) = (a INSERT s) INTER (a INSERT t)`] THEN + W(MP_TAC o PART_MATCH (rand o rand) CONVEX_HULL_INTER o rand o snd) THEN + ANTS_TAC THENL + [UNDISCH_TAC `~(affine_dependent(s:real^N->bool))` THEN + REWRITE_TAC[CONTRAPOS_THM] THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] AFFINE_DEPENDENT_MONO); + DISCH_THEN(SUBST1_TAC o SYM)] THEN + ASM SET_TAC[]; + ALL_TAC] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP AFFINE_INDEPENDENT_IMP_FINITE) THEN + REWRITE_TAC[CONVEX_HULL_FINITE; IN_ELIM_THM] THEN + DISCH_THEN(CONJUNCTS_THEN2 (X_CHOOSE_THEN `b:real^N->real` STRIP_ASSUME_TAC) + MP_TAC) THEN + REPLICATE_TAC 2 (DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + SUBGOAL_THEN `~((a:real^N) IN t) /\ ~(a IN t')` STRIP_ASSUME_TAC THENL + [ASM SET_TAC[]; ALL_TAC] THEN + SUBGOAL_THEN `FINITE(t:real^N->bool) /\ FINITE(t':real^N->bool)` + STRIP_ASSUME_TAC THENL [ASM_MESON_TAC[FINITE_SUBSET]; ALL_TAC] THEN + ASM_SIMP_TAC[AFFINE_HULL_FINITE_STEP_GEN; REAL_LE_ADD; + REAL_ARITH `&0 <= a / &2 <=> &0 <= a`] THEN + REWRITE_TAC[IMP_CONJ; LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`u':real`; `u:real^N->real`] THEN REPEAT DISCH_TAC THEN + MAP_EVERY X_GEN_TAC [`v':real`; `v:real^N->real`] THEN REPEAT DISCH_TAC THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE RAND_CONV + [AFFINE_DEPENDENT_EXPLICIT]) THEN + REWRITE_TAC[NOT_EXISTS_THM] THEN + DISCH_THEN(MP_TAC o SPEC `s:real^N->bool`) THEN + ASM_REWRITE_TAC[SUBSET_REFL] THEN + DISCH_THEN(MP_TAC o SPEC + `\x:real^N. (if x IN t then u x else &0) - (if x IN t' then v x else &0) + + (u' - v') * b x`) THEN + ASM_SIMP_TAC[SUM_ADD; VSUM_ADD; SUM_LMUL; VSUM_LMUL; VECTOR_ADD_RDISTRIB] THEN + ASM_SIMP_TAC[SUM_SUB; VSUM_SUB; VECTOR_SUB_RDISTRIB] THEN + REWRITE_TAC[MESON[] + `(if p then a else b) % x = (if p then a % x else b % x)`] THEN + ASM_SIMP_TAC[SUM_CASES; VSUM_CASES; VECTOR_MUL_LZERO; SUM_0; VSUM_0] THEN + ASM_SIMP_TAC[SET_RULE `t SUBSET s ==> {x | x IN s /\ x IN t} = t`] THEN + ASM_SIMP_TAC[SUM_ADD; SUM_LMUL; VSUM_ADD; VSUM_LMUL; VECTOR_ADD_RDISTRIB; + GSYM VECTOR_MUL_ASSOC] THEN + MATCH_MP_TAC(TAUT `a /\ c /\ (~b ==> d) ==> ~(a /\ b /\ c) ==> d`) THEN + REPEAT CONJ_TAC THENL [REAL_ARITH_TAC; VECTOR_ARITH_TAC; ALL_TAC] THEN + DISCH_TAC THEN + SUBGOAL_THEN + `(!x. x IN s ==> (if x IN t then u x else &0) <= + (if x IN t' then v x else &0)) \/ + (!x:real^N. x IN s ==> (if x IN t' then v x else &0) <= + (if x IN t then u x else &0))` + (DISJ_CASES_THEN(LABEL_TAC "*")) THENL + [MP_TAC(REAL_ARITH `&0 <= (u' - v') \/ &0 <= (v' - u')`) THEN + MATCH_MP_TAC MONO_OR THEN CONJ_TAC THEN + DISCH_TAC THEN X_GEN_TAC `y:real^N` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [NOT_EXISTS_THM]) THEN + DISCH_THEN(MP_TAC o SPEC `y:real^N`) THEN ASM_REWRITE_TAC[] THENL + [MATCH_MP_TAC(REAL_ARITH `&0 <= c ==> a - b + c = &0 ==> a <= b`); + MATCH_MP_TAC(REAL_ARITH `&0 <= --c ==> a - b + c = &0 ==> b <= a`)] THEN + ASM_SIMP_TAC[REAL_LE_MUL; GSYM REAL_MUL_LNEG; REAL_NEG_SUB]; + EXISTS_TAC `(\x. if x = a then u' else u x):real^N->real`; + EXISTS_TAC `(\x. if x = a then v' else v x):real^N->real`] THEN + ASM_SIMP_TAC[FORALL_IN_INSERT] THEN + (CONJ_TAC THENL [ASM_MESON_TAC[IN_INTER]; ALL_TAC]) THEN + ASM_SIMP_TAC[SUM_CLAUSES; VSUM_CLAUSES; FINITE_INTER] THEN + ASM_REWRITE_TAC[IN_INTER] THEN + REWRITE_TAC[REAL_ARITH `u' + u = &1 <=> u = &1 - u'`; + VECTOR_ARITH `u' + u:real^N = y <=> u = y - u'`] THEN + (CONJ_TAC THEN + FIRST_X_ASSUM(fun th -> GEN_REWRITE_TAC RAND_CONV [GSYM th]) THEN + CONV_TAC SYM_CONV THENL + [MATCH_MP_TAC SUM_EQ_SUPERSET; MATCH_MP_TAC VSUM_EQ_SUPERSET]) THEN + ASM_SIMP_TAC[FINITE_INTER; INTER_SUBSET; IN_INTER] THEN + (CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC]) THEN + X_GEN_TAC `y:real^N` THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + ASM_REWRITE_TAC[VECTOR_MUL_EQ_0] THEN DISCH_TAC THEN + REMOVE_THEN "*" (MP_TAC o SPEC `y:real^N`) THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[GSYM REAL_LE_ANTISYM] THEN ASM SET_TAC[]);; + +let CONVEX_HULL_EXCHANGE_UNION = prove + (`!s a:real^N. + a IN convex hull s + ==> convex hull s = + UNIONS {convex hull (a INSERT (s DELETE b)) |b| b IN s}`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL + [ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN REWRITE_TAC[UNIONS_IMAGE] THEN + REWRITE_TAC[SUBSET; IN_ELIM_THM] THEN + ASM_MESON_TAC[IN_CONVEX_HULL_EXCHANGE]; + REWRITE_TAC[SUBSET; FORALL_IN_UNIONS; FORALL_IN_GSPEC; + IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN + GEN_TAC THEN DISCH_TAC THEN REWRITE_TAC[GSYM SUBSET] THEN + ASM_SIMP_TAC[SUBSET_HULL; CONVEX_CONVEX_HULL] THEN + ASM_REWRITE_TAC[INSERT_SUBSET] THEN + MESON_TAC[HULL_INC; SUBSET; IN_DELETE]]);; + +let CONVEX_HULL_EXCHANGE_INTER = prove + (`!s a:real^N t t'. + ~affine_dependent s /\ + a IN convex hull s /\ + t SUBSET s /\ + t' SUBSET s + ==> (convex hull (a INSERT t)) INTER (convex hull (a INSERT t')) = + convex hull (a INSERT (t INTER t'))`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL + [REWRITE_TAC[SUBSET; IN_INTER] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC IN_CONVEX_HULL_EXCHANGE_UNIQUE THEN + EXISTS_TAC `s:real^N->bool` THEN ASM_REWRITE_TAC[]; + REWRITE_TAC[SUBSET_INTER] THEN CONJ_TAC THEN + MATCH_MP_TAC HULL_MONO THEN SET_TAC[]]);; + +(* ------------------------------------------------------------------------- *) +(* Representing affine hull as hyperplane or finite intersection of them. *) +(* ------------------------------------------------------------------------- *) + +let AFF_DIM_EQ_HYPERPLANE = prove + (`!s. aff_dim s = &(dimindex(:N)) - &1 <=> + ?a b. ~(a = vec 0) /\ affine hull s = {x:real^N | a dot x = b}`, + GEN_TAC THEN ASM_CASES_TAC `s:real^N->bool = {}` THENL + [ASM_REWRITE_TAC[AFF_DIM_EMPTY; INT_ARITH `--a:int = b - a <=> b = &0`] THEN + SIMP_TAC[INT_OF_NUM_EQ; LE_1; DIMINDEX_GE_1; AFFINE_HULL_EMPTY] THEN + REWRITE_TAC[EXTENSION; IN_ELIM_THM; NOT_IN_EMPTY; NOT_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`a:real^N`; `b:real`] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + DISCH_THEN(MP_TAC o SPEC `(b / (a dot a)) % a:real^N`) THEN + ASM_SIMP_TAC[DOT_RMUL; REAL_DIV_RMUL; DOT_EQ_0]; + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN + REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN X_GEN_TAC `c:real^N` THEN + GEN_GEOM_ORIGIN_TAC `c:real^N` ["a"] THEN + SIMP_TAC[AFF_DIM_DIM_0; HULL_INC] THEN + SIMP_TAC[INT_OF_NUM_SUB; DIMINDEX_GE_1; INT_OF_NUM_EQ] THEN + SIMP_TAC[AFFINE_HULL_EQ_SPAN; HULL_INC; DIM_EQ_HYPERPLANE] THEN + REPEAT STRIP_TAC THEN AP_TERM_TAC THEN + GEN_REWRITE_TAC I [FUN_EQ_THM] THEN X_GEN_TAC `a:real^N` THEN + REWRITE_TAC[] THEN ASM_CASES_TAC `a:real^N = vec 0` THEN + ASM_REWRITE_TAC[DOT_RADD; REAL_ARITH `a + b:real = c <=> b = c - a`] THEN + EQ_TAC THEN STRIP_TAC THENL + [EXISTS_TAC `(a:real^N) dot c` THEN ASM_REWRITE_TAC[REAL_SUB_REFL]; + ASM_REWRITE_TAC[] THEN + FIRST_X_ASSUM(MP_TAC o AP_TERM `\s. (vec 0:real^N) IN s`) THEN + ASM_SIMP_TAC[SPAN_SUPERSET; IN_ELIM_THM; DOT_RZERO]]]);; + +let AFF_DIM_HYPERPLANE = prove + (`!a b. ~(a = vec 0) + ==> aff_dim {x:real^N | a dot x = b} = &(dimindex(:N)) - &1`, + REPEAT STRIP_TAC THEN REWRITE_TAC[AFF_DIM_EQ_HYPERPLANE] THEN + MAP_EVERY EXISTS_TAC [`a:real^N`; `b:real`] THEN + ASM_REWRITE_TAC[AFFINE_HULL_EQ; AFFINE_HYPERPLANE]);; + +let BOUNDED_HYPERPLANE_EQ_TRIVIAL = prove + (`!a b. bounded {x:real^N | a dot x = b} <=> + if a = vec 0 then ~(b = &0) else dimindex(:N) = 1`, + REPEAT GEN_TAC THEN ASM_CASES_TAC `a:real^N = vec 0` THEN + ASM_REWRITE_TAC[DOT_LZERO] THENL + [ASM_CASES_TAC `b = &0` THEN + ASM_REWRITE_TAC[EMPTY_GSPEC; BOUNDED_EMPTY] THEN + REWRITE_TAC[NOT_BOUNDED_UNIV; SET_RULE `{x | T} = UNIV`]; + ASM_SIMP_TAC[AFFINE_BOUNDED_EQ_LOWDIM; AFF_DIM_HYPERPLANE; + AFFINE_HYPERPLANE] THEN + REWRITE_TAC[INT_ARITH `a - &1:int <= &0 <=> a <= &1`; INT_OF_NUM_LE] THEN + MATCH_MP_TAC(ARITH_RULE `1 <= n ==> (n <= 1 <=> n = 1)`) THEN + REWRITE_TAC[DIMINDEX_GE_1]]);; + +let AFFINE_HULL_FINITE_INTERSECTION_HYPERPLANES = prove + (`!s:real^N->bool. + ?f. FINITE f /\ + &(CARD f) + aff_dim s = &(dimindex(:N)) /\ + affine hull s = INTERS f /\ + (!h. h IN f ==> ?a b. ~(a = vec 0) /\ h = {x | a dot x = b})`, + GEN_TAC THEN ONCE_REWRITE_TAC[GSYM AFF_DIM_AFFINE_HULL] THEN + MP_TAC(ISPEC `s:real^N->bool` AFFINE_BASIS_EXISTS) THEN + DISCH_THEN(X_CHOOSE_THEN `b:real^N->bool` STRIP_ASSUME_TAC) THEN + FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN + MP_TAC(ISPECL [`b:real^N->bool`; `(:real^N)`] EXTEND_TO_AFFINE_BASIS) THEN + ASM_REWRITE_TAC[SUBSET_UNIV; AFFINE_HULL_UNIV] THEN + DISCH_THEN(X_CHOOSE_THEN `c:real^N->bool` STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN `FINITE(c:real^N->bool)` ASSUME_TAC THENL + [ASM_MESON_TAC[AFFINE_INDEPENDENT_IMP_FINITE]; ALL_TAC] THEN + REWRITE_TAC[GSYM AFF_DIM_UNIV] THEN FIRST_ASSUM(SUBST1_TAC o SYM) THEN + REWRITE_TAC[AFF_DIM_AFFINE_HULL] THEN + ASM_SIMP_TAC[AFF_DIM_AFFINE_INDEPENDENT; CARD_DIFF] THEN + REWRITE_TAC[INT_ARITH `f + b - &1:int = c - &1 <=> f = c - b`] THEN + ASM_SIMP_TAC[INT_OF_NUM_SUB; CARD_SUBSET; GSYM CARD_DIFF; INT_OF_NUM_EQ] THEN + ASM_CASES_TAC `c:real^N->bool = b` THENL + [EXISTS_TAC `{}:(real^N->bool)->bool` THEN + ASM_REWRITE_TAC[CARD_CLAUSES; FINITE_RULES; NOT_IN_EMPTY; INTERS_0; + DIFF_EQ_EMPTY] THEN + ASM_MESON_TAC[]; + ALL_TAC] THEN + EXISTS_TAC `{affine hull (c DELETE a) |a| (a:real^N) IN (c DIFF b)}` THEN + REWRITE_TAC[FORALL_IN_GSPEC] THEN REWRITE_TAC[SIMPLE_IMAGE] THEN + ASM_SIMP_TAC[FINITE_IMAGE; FINITE_DIFF] THEN REPEAT CONJ_TAC THENL + [MATCH_MP_TAC CARD_IMAGE_INJ THEN ASM_SIMP_TAC[FINITE_DIFF] THEN + MAP_EVERY X_GEN_TAC [`x:real^N`; `y:real^N`] THEN REWRITE_TAC[IN_DIFF] THEN + STRIP_TAC THEN ASM_CASES_TAC `x:real^N = y` THEN ASM_REWRITE_TAC[] THEN + UNDISCH_TAC `~affine_dependent(c:real^N->bool)` THEN + REWRITE_TAC[affine_dependent] THEN EXISTS_TAC `x:real^N` THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC HULL_INC THEN ASM SET_TAC[]; + ONCE_REWRITE_TAC[GSYM o_DEF] THEN REWRITE_TAC[IMAGE_o] THEN + ONCE_REWRITE_TAC[GSYM SIMPLE_IMAGE] THEN + W(MP_TAC o PART_MATCH (rhs o rand) AFFINE_HULL_INTERS o rand o snd) THEN + ANTS_TAC THENL + [MATCH_MP_TAC AFFINE_INDEPENDENT_SUBSET THEN + EXISTS_TAC `c:real^N->bool` THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[SUBSET; FORALL_IN_UNIONS; FORALL_IN_IMAGE; + IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN SET_TAC[]; + DISCH_THEN(SUBST1_TAC o SYM) THEN AP_TERM_TAC THEN + GEN_REWRITE_TAC I [EXTENSION] THEN + REWRITE_TAC[IN_INTERS; FORALL_IN_IMAGE] THEN ASM SET_TAC[]]; + REWRITE_TAC[GSYM AFF_DIM_EQ_HYPERPLANE] THEN + ASM_SIMP_TAC[IN_DIFF; AFFINE_INDEPENDENT_DELETE; + AFF_DIM_AFFINE_INDEPENDENT; CARD_DELETE] THEN + REWRITE_TAC[GSYM AFF_DIM_UNIV] THEN FIRST_ASSUM(SUBST1_TAC o SYM) THEN + REWRITE_TAC[AFF_DIM_AFFINE_HULL] THEN + ASM_SIMP_TAC[AFF_DIM_AFFINE_INDEPENDENT; CARD_DIFF] THEN + REPEAT STRIP_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN + MATCH_MP_TAC(GSYM INT_OF_NUM_SUB) THEN + MATCH_MP_TAC(ARITH_RULE `~(c = 0) ==> 1 <= c`) THEN + ASM_SIMP_TAC[CARD_EQ_0] THEN ASM SET_TAC[]]);; + +let AFFINE_HYPERPLANE_SUMS_EQ_UNIV = prove + (`!a b s. + affine s /\ + ~(s INTER {v | a dot v = b} = {}) /\ + ~(s DIFF {v | a dot v = b} = {}) + ==> {x + y | x IN s /\ y IN {v | a dot v = b}} = (:real^N)`, + REPEAT GEN_TAC THEN ASM_CASES_TAC `a:real^N = vec 0` THENL + [ASM_REWRITE_TAC[DOT_LZERO] THEN SET_TAC[]; ALL_TAC] THEN + REWRITE_TAC[TAUT `a /\ b /\ c ==> d <=> b ==> a /\ c ==> d`] THEN + GEN_REWRITE_TAC LAND_CONV [GSYM MEMBER_NOT_EMPTY] THEN + REWRITE_TAC[LEFT_IMP_EXISTS_THM; IN_ELIM_THM] THEN X_GEN_TAC `c:real^N` THEN + ONCE_REWRITE_TAC[SET_RULE + `{x + y:real^N | x IN s /\ P y} = + {z | ?x y. x IN s /\ P y /\ z = x + y}`] THEN + GEOM_ORIGIN_TAC `c:real^N` THEN REPEAT GEN_TAC THEN + REWRITE_TAC[DOT_RADD; REAL_ARITH `b dot c + a = d <=> a = d - b dot c`] THEN + REWRITE_TAC[IN_INTER; IN_ELIM_THM; DOT_RZERO] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC (SUBST1_TAC o SYM)) THEN + ASM_SIMP_TAC[AFFINE_EQ_SUBSPACE; HULL_INC] THEN STRIP_TAC THEN + REWRITE_TAC[VECTOR_ARITH `c + z:real^N = (c + x) + (c + y) <=> + z = c + x + y`] THEN + REWRITE_TAC[SET_RULE + `{z | ?x y. x IN s /\ P y /\ z = c + x + y} = + IMAGE (\x. c + x) {x + y:real^N | x IN s /\ y IN {v | P v}}`] THEN + MATCH_MP_TAC(SET_RULE + `!f. (!x. g(f x) = x) /\ s = UNIV ==> IMAGE g s = UNIV`) THEN + EXISTS_TAC `\x:real^N. x - c` THEN + REWRITE_TAC[VECTOR_ARITH `c + x - c:real^N = x`] THEN + MATCH_MP_TAC(MESON[SPAN_EQ_SELF] `subspace s /\ span s = t ==> s = t`) THEN + CONJ_TAC THENL + [ASM_SIMP_TAC[SUBSPACE_SUMS; SUBSPACE_HYPERPLANE]; + ALL_TAC] THEN + REWRITE_TAC[GSYM DIM_EQ_FULL] THEN + REWRITE_TAC[GSYM LE_ANTISYM; DIM_SUBSET_UNIV] THEN + MATCH_MP_TAC(ARITH_RULE `m - 1 < n ==> m <= n`) THEN + MATCH_MP_TAC LET_TRANS THEN EXISTS_TAC `dim {x:real^N | a dot x = &0}` THEN + CONJ_TAC THENL [ASM_SIMP_TAC[DIM_HYPERPLANE; LE_REFL]; ALL_TAC] THEN + MATCH_MP_TAC DIM_PSUBSET THEN + ASM_SIMP_TAC[snd(EQ_IMP_RULE(SPEC_ALL SPAN_EQ_SELF)); + SUBSPACE_SUMS; SUBSPACE_HYPERPLANE] THEN + REWRITE_TAC[PSUBSET; SUBSET; FORALL_IN_GSPEC] THEN + REWRITE_TAC[EXTENSION; IN_ELIM_THM] THEN CONJ_TAC THENL + [X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN + MAP_EVERY EXISTS_TAC [`vec 0:real^N`; `x:real^N`] THEN + ASM_SIMP_TAC[SUBSPACE_0; VECTOR_ADD_LID]; + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN + REWRITE_TAC[NOT_FORALL_THM] THEN MATCH_MP_TAC MONO_EXISTS THEN + X_GEN_TAC `x:real^N` THEN SIMP_TAC[IN_DIFF; IN_ELIM_THM] THEN + DISCH_TAC THEN MAP_EVERY EXISTS_TAC [`x:real^N`; `vec 0:real^N`] THEN + ASM_REWRITE_TAC[DOT_RZERO; VECTOR_ADD_RID]]);; + +let AFF_DIM_AFFINE_INTER_HYPERPLANE = prove + (`!a b s:real^N->bool. + affine s + ==> aff_dim(s INTER {x | a dot x = b}) = + if s INTER {v | a dot v = b} = {} then -- &1 + else if s SUBSET {v | a dot v = b} then aff_dim s + else aff_dim s - &1`, + REPEAT GEN_TAC THEN ASM_CASES_TAC `a:real^N = vec 0` THENL + [ASM_REWRITE_TAC[DOT_LZERO] THEN ASM_CASES_TAC `b = &0` THEN + ASM_REWRITE_TAC[EMPTY_GSPEC; INTER_EMPTY; AFF_DIM_EMPTY] THEN + SIMP_TAC[SET_RULE `{x | T} = UNIV`; IN_UNIV; INTER_UNIV; SUBSET_UNIV] THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[AFF_DIM_EMPTY]; + STRIP_TAC THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[AFF_DIM_EMPTY] THEN + COND_CASES_TAC THENL [AP_TERM_TAC THEN ASM SET_TAC[]; ALL_TAC] THEN + MP_TAC(ISPECL [`s:real^N->bool`; `{x:real^N | a dot x = b}`] + AFF_DIM_SUMS_INTER) THEN + ASM_SIMP_TAC[AFFINE_HYPERPLANE; AFF_DIM_HYPERPLANE] THEN + ASM_SIMP_TAC[AFFINE_HYPERPLANE_SUMS_EQ_UNIV; AFF_DIM_UNIV; + SET_RULE `~(s SUBSET t) ==> ~(s DIFF t = {})`] THEN + SPEC_TAC(`aff_dim (s INTER {x:real^N | a dot x = b})`,`i:int`) THEN + INT_ARITH_TAC]);; + +let AFF_DIM_LT_FULL = prove + (`!s. aff_dim s < &(dimindex(:N)) <=> ~(affine hull s = (:real^N))`, + GEN_TAC THEN REWRITE_TAC[GSYM AFF_DIM_EQ_FULL] THEN + MP_TAC(ISPEC `s:real^N->bool` AFF_DIM_LE_UNIV) THEN ARITH_TAC);; + +let AFF_LOWDIM_SUBSET_HYPERPLANE = prove + (`!s:real^N->bool. + aff_dim s < &(dimindex(:N)) + ==> ?a b. ~(a = vec 0) /\ s SUBSET {x | a dot x = b}`, + MATCH_MP_TAC SET_PROVE_CASES THEN CONJ_TAC THENL + [DISCH_TAC THEN EXISTS_TAC `basis 1:real^N` THEN + SIMP_TAC[EMPTY_SUBSET; BASIS_NONZERO; LE_REFL; DIMINDEX_GE_1]; + MAP_EVERY X_GEN_TAC [`c:real^N`; `s:real^N->bool`] THEN + CONV_TAC(ONCE_DEPTH_CONV(GEN_ALPHA_CONV `a:real^N`)) THEN + GEN_GEOM_ORIGIN_TAC `c:real^N` ["a"] THEN + SIMP_TAC[AFF_DIM_DIM_0; HULL_INC; IN_INSERT; INT_OF_NUM_LT] THEN + REPEAT GEN_TAC THEN DISCH_TAC THEN + DISCH_THEN(MP_TAC o MATCH_MP LOWDIM_SUBSET_HYPERPLANE) THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `u:real^N` THEN + STRIP_TAC THEN EXISTS_TAC `(u:real^N) dot c` THEN + ASM_REWRITE_TAC[DOT_RADD; REAL_EQ_ADD_LCANCEL_0] THEN + ASM_MESON_TAC[SPAN_INC; SUBSET_TRANS]]);; + +(* ------------------------------------------------------------------------- *) +(* An additional lemma about hyperplanes. *) +(* ------------------------------------------------------------------------- *) + +let SUBSET_HYPERPLANES = prove + (`!a b a' b'. + {x | a dot x = b} SUBSET {x | a' dot x = b'} <=> + {x | a dot x = b} = {} \/ {x | a' dot x = b'} = (:real^N) \/ + {x | a dot x = b} = {x | a' dot x = b'}`, + REPEAT GEN_TAC THEN + ASM_CASES_TAC `{x:real^N | a dot x = b} = {}` THEN + ASM_REWRITE_TAC[EMPTY_SUBSET] THEN + ASM_CASES_TAC `{x | a' dot x = b'} = (:real^N)` THEN + ASM_REWRITE_TAC[SUBSET_UNIV] THEN + RULE_ASSUM_TAC(REWRITE_RULE + [HYPERPLANE_EQ_EMPTY; HYPERPLANE_EQ_UNIV]) THEN + REWRITE_TAC[GSYM SUBSET_ANTISYM_EQ] THEN + ASM_CASES_TAC `{x:real^N | a dot x = b} SUBSET {x | a' dot x = b'}` THEN + ASM_REWRITE_TAC[] THEN + MP_TAC(ISPECL [`{x:real^N | a dot x = b}`; `{x:real^N | a' dot x = b'}`] + AFF_DIM_PSUBSET) THEN + ASM_SIMP_TAC[PSUBSET; + REWRITE_RULE[GSYM AFFINE_HULL_EQ] AFFINE_HYPERPLANE] THEN + ASM_CASES_TAC `{x:real^N | a dot x = b} = {x | a' dot x = b'}` THEN + ASM_REWRITE_TAC[SUBSET_REFL] THEN ASM_CASES_TAC `a':real^N = vec 0` THENL + [ASM_CASES_TAC `b' = &0` THENL [ASM_MESON_TAC[]; ALL_TAC] THEN + ASM_REWRITE_TAC[DOT_LZERO] THEN SET_TAC[]; + ALL_TAC] THEN + ASM_CASES_TAC `a:real^N = vec 0` THENL + [ASM_CASES_TAC `b = &0` THENL [ALL_TAC; ASM_MESON_TAC[]] THEN + ASM_REWRITE_TAC[DOT_LZERO] THEN SET_TAC[]; + ALL_TAC] THEN + ASM_SIMP_TAC[AFF_DIM_HYPERPLANE; INT_LT_REFL]);; + +(* ------------------------------------------------------------------------- *) +(* Openness and compactness are preserved by convex hull operation. *) +(* ------------------------------------------------------------------------- *) + +let OPEN_CONVEX_HULL = prove + (`!s:real^N->bool. open s ==> open(convex hull s)`, + REPEAT GEN_TAC THEN + REWRITE_TAC[CONVEX_HULL_EXPLICIT; OPEN_CONTAINS_CBALL] THEN + REWRITE_TAC[IN_ELIM_THM; SUBSET; LEFT_IMP_EXISTS_THM] THEN DISCH_TAC THEN + MAP_EVERY X_GEN_TAC [`a:real^N`; `t:real^N->bool`; `u:real^N->real`] THEN + STRIP_TAC THEN + SUBGOAL_THEN `?b. !x:real^N. x IN t ==> &0 < b(x) /\ cball(x,b(x)) SUBSET s` + STRIP_ASSUME_TAC THENL + [REWRITE_TAC[GSYM SKOLEM_THM] THEN ASM_MESON_TAC[SUBSET]; ALL_TAC] THEN + ABBREV_TAC `i = IMAGE (b:real^N->real) t` THEN + EXISTS_TAC `inf i` THEN MP_TAC(SPEC `i:real->bool` INF_FINITE) THEN + EXPAND_TAC "i" THEN ASM_REWRITE_TAC[FORALL_IN_IMAGE; IN_IMAGE] THEN + ANTS_TAC THENL + [EXPAND_TAC "i" THEN CONJ_TAC THENL + [ASM_SIMP_TAC[FINITE_IMAGE]; ALL_TAC] THEN + REWRITE_TAC[IMAGE_EQ_EMPTY] THEN + ASM_MESON_TAC[SUM_CLAUSES; REAL_ARITH `~(&1 = &0)`]; + ALL_TAC] THEN + STRIP_TAC THEN CONJ_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN + X_GEN_TAC `y:real^N` THEN REWRITE_TAC[IN_CBALL; dist] THEN + DISCH_TAC THEN EXISTS_TAC `IMAGE (\v:real^N. v + (y - a)) t` THEN + EXISTS_TAC `\v. (u:real^N->real)(v - (y - a))` THEN + ASM_SIMP_TAC[FINITE_IMAGE; FORALL_IN_IMAGE; SUM_IMAGE; VSUM_IMAGE; + VECTOR_ARITH `v + a:real^N = w + a <=> v = w`] THEN + ASM_REWRITE_TAC[o_DEF; VECTOR_ARITH `(v + a) - a:real^N = v`] THEN + ASM_REWRITE_TAC[VECTOR_ADD_LDISTRIB; ETA_AX] THEN + ASM_SIMP_TAC[VSUM_ADD; VSUM_RMUL] THEN + CONJ_TAC THENL [ALL_TAC; VECTOR_ARITH_TAC] THEN + X_GEN_TAC `z:real^N` THEN STRIP_TAC THEN + SUBGOAL_THEN `z + (y - a) IN cball(z:real^N,b z)` + (fun th -> ASM_MESON_TAC[th; SUBSET]) THEN + REWRITE_TAC[IN_CBALL; dist; NORM_ARITH + `norm(z - (z + a - y)) = norm(y - a)`] THEN + ASM_MESON_TAC[REAL_LE_TRANS]);; + +let COMPACT_CONVEX_COMBINATIONS = prove + (`!s t. compact s /\ compact t + ==> compact { (&1 - u) % x + u % y :real^N | + &0 <= u /\ u <= &1 /\ x IN s /\ y IN t}`, + REPEAT STRIP_TAC THEN SUBGOAL_THEN + `{ (&1 - u) % x + u % y :real^N | &0 <= u /\ u <= &1 /\ x IN s /\ y IN t} = + IMAGE (\z. (&1 - drop(fstcart z)) % fstcart(sndcart z) + + drop(fstcart z) % sndcart(sndcart z)) + { pastecart u w | u IN interval[vec 0,vec 1] /\ + w IN { pastecart x y | x IN s /\ y IN t} }` + SUBST1_TAC THENL + [REWRITE_TAC[EXTENSION; IN_ELIM_THM; IN_IMAGE] THEN + X_GEN_TAC `x:real^N` THEN + REWRITE_TAC[RIGHT_AND_EXISTS_THM; LEFT_AND_EXISTS_THM] THEN + CONV_TAC(ONCE_DEPTH_CONV UNWIND_CONV) THEN + REWRITE_TAC[FSTCART_PASTECART; SNDCART_PASTECART] THEN + REWRITE_TAC[IN_INTERVAL_1; GSYM EXISTS_DROP; DROP_VEC] THEN MESON_TAC[]; + ALL_TAC] THEN + MATCH_MP_TAC COMPACT_CONTINUOUS_IMAGE THEN + ASM_SIMP_TAC[COMPACT_PCROSS; GSYM PCROSS; COMPACT_INTERVAL] THEN + MATCH_MP_TAC CONTINUOUS_AT_IMP_CONTINUOUS_ON THEN + X_GEN_TAC `z:real^(1,(N,N)finite_sum)finite_sum` THEN + DISCH_THEN(K ALL_TAC) THEN REWRITE_TAC[PCROSS] THEN + MATCH_MP_TAC CONTINUOUS_ADD THEN CONJ_TAC THEN + MATCH_MP_TAC CONTINUOUS_MUL THEN REWRITE_TAC[o_DEF; LIFT_SUB; LIFT_DROP] THEN + CONJ_TAC THEN TRY(MATCH_MP_TAC CONTINUOUS_SUB) THEN + REWRITE_TAC[CONTINUOUS_CONST] THEN + MATCH_MP_TAC LINEAR_CONTINUOUS_AT THEN + REWRITE_TAC[LINEAR_FSTCART; LINEAR_SNDCART; ETA_AX] THEN + GEN_REWRITE_TAC RAND_CONV [GSYM o_DEF] THEN + MATCH_MP_TAC LINEAR_COMPOSE THEN + REWRITE_TAC[LINEAR_FSTCART; LINEAR_SNDCART]);; + +let COMPACT_CONVEX_HULL = prove + (`!s:real^N->bool. compact s ==> compact(convex hull s)`, + REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[CARATHEODORY] THEN + SPEC_TAC(`dimindex(:N) + 1`,`n:num`) THEN + ASM_CASES_TAC `s:real^N->bool = {}` THENL + [ASM_REWRITE_TAC[SUBSET_EMPTY] THEN + CONV_TAC(ONCE_DEPTH_CONV UNWIND_CONV) THEN + REWRITE_TAC[CONVEX_HULL_EMPTY; NOT_IN_EMPTY] THEN + REWRITE_TAC[SET_RULE `{x | F} = {}`; COMPACT_EMPTY]; + ALL_TAC] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN + DISCH_THEN(X_CHOOSE_TAC `w:real^N`) THEN INDUCT_TAC THENL + [SUBGOAL_THEN + `{x:real^N | ?t. FINITE t /\ t SUBSET s /\ CARD t <= 0 /\ + x IN convex hull t} = {}` + (fun th -> REWRITE_TAC[th; COMPACT_EMPTY]) THEN + REWRITE_TAC[EXTENSION; NOT_IN_EMPTY; LE; IN_ELIM_THM] THEN + MESON_TAC[CARD_EQ_0; CONVEX_HULL_EMPTY; NOT_IN_EMPTY]; + ALL_TAC] THEN + ASM_CASES_TAC `n = 0` THENL + [ASM_REWRITE_TAC[ARITH_RULE `s <= SUC 0 <=> s = 0 \/ s = 1`] THEN + UNDISCH_TAC `compact(s:real^N->bool)` THEN + MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN + REWRITE_TAC[EXTENSION; IN_ELIM_THM] THEN + REWRITE_TAC[TAUT `a /\ b /\ (c \/ d) /\ e <=> + (a /\ c) /\ (b /\ e) \/ (a /\ d) /\ (b /\ e)`] THEN + REWRITE_TAC[GSYM HAS_SIZE; num_CONV `1`; HAS_SIZE_CLAUSES] THEN + REWRITE_TAC[EXISTS_OR_THM; LEFT_AND_EXISTS_THM; RIGHT_AND_EXISTS_THM] THEN + CONV_TAC(TOP_DEPTH_CONV UNWIND_CONV) THEN + REWRITE_TAC[NOT_IN_EMPTY; CONVEX_HULL_EMPTY] THEN + REWRITE_TAC[CONVEX_HULL_SING] THEN SET_TAC[]; + ALL_TAC] THEN + SUBGOAL_THEN + `{x:real^N | ?t. FINITE t /\ t SUBSET s /\ CARD t <= SUC n /\ + x IN convex hull t} = + { (&1 - u) % x + u % y :real^N | + &0 <= u /\ u <= &1 /\ x IN s /\ + y IN {x | ?t. FINITE t /\ t SUBSET s /\ + CARD t <= n /\ x IN convex hull t}}` + (fun th -> ASM_SIMP_TAC[th; COMPACT_CONVEX_COMBINATIONS]) THEN + REWRITE_TAC[EXTENSION; IN_ELIM_THM] THEN + X_GEN_TAC `x:real^N` THEN EQ_TAC THENL + [ALL_TAC; + REWRITE_TAC[LEFT_IMP_EXISTS_THM; RIGHT_AND_EXISTS_THM; + LEFT_AND_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`u:real^N`; `c:real`; `v:real^N`; + `t:real^N->bool`] THEN + STRIP_TAC THEN EXISTS_TAC `(u:real^N) INSERT t` THEN + ASM_REWRITE_TAC[FINITE_INSERT; INSERT_SUBSET] THEN + ASM_SIMP_TAC[CARD_CLAUSES] THEN CONJ_TAC THENL + [ASM_ARITH_TAC; ALL_TAC] THEN + MATCH_MP_TAC IN_CONVEX_SET THEN + ASM_REWRITE_TAC[CONVEX_CONVEX_HULL] THEN CONJ_TAC THEN + ASM_MESON_TAC[HULL_SUBSET; SUBSET; IN_INSERT; HULL_MONO]] THEN + DISCH_THEN(X_CHOOSE_THEN `t:real^N->bool` STRIP_ASSUME_TAC) THEN + ASM_CASES_TAC `CARD(t:real^N->bool) <= n` THENL + [MAP_EVERY EXISTS_TAC [`w:real^N`; `&1`; `x:real^N`] THEN + ASM_REWRITE_TAC[REAL_POS; REAL_LE_REFL] THEN + CONJ_TAC THENL [ASM_MESON_TAC[]; VECTOR_ARITH_TAC]; + ALL_TAC] THEN + SUBGOAL_THEN `(t:real^N->bool) HAS_SIZE (SUC n)` MP_TAC THENL + [ASM_REWRITE_TAC[HAS_SIZE] THEN ASM_ARITH_TAC; + ALL_TAC] THEN + REWRITE_TAC[HAS_SIZE_CLAUSES] THEN + DISCH_THEN(X_CHOOSE_THEN `a:real^N` (X_CHOOSE_THEN `u:real^N->bool` + STRIP_ASSUME_TAC)) THEN + FIRST_X_ASSUM SUBST_ALL_TAC THEN + UNDISCH_TAC `(x:real^N) IN convex hull (a INSERT u)` THEN + RULE_ASSUM_TAC(REWRITE_RULE[FINITE_INSERT]) THEN + ASM_CASES_TAC `(u:real^N->bool) = {}` THENL + [ASM_REWRITE_TAC[CONVEX_HULL_SING; IN_SING] THEN + DISCH_THEN SUBST_ALL_TAC THEN + MAP_EVERY EXISTS_TAC [`a:real^N`; `&1`; `a:real^N`] THEN + ASM_REWRITE_TAC[REAL_POS; REAL_LE_REFL] THEN + CONJ_TAC THENL [ALL_TAC; VECTOR_ARITH_TAC] THEN + CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + EXISTS_TAC `{a:real^N}` THEN SIMP_TAC[FINITE_RULES] THEN + REWRITE_TAC[CONVEX_HULL_SING; IN_SING] THEN + CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + SIMP_TAC[CARD_CLAUSES; FINITE_RULES; NOT_IN_EMPTY] THEN + UNDISCH_TAC `~(n = 0)` THEN ARITH_TAC; + ALL_TAC] THEN + ASM_SIMP_TAC[CONVEX_HULL_INSERT; IN_ELIM_THM; LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`c:real`; `d:real`; `z:real^N`] THEN STRIP_TAC THEN + MAP_EVERY EXISTS_TAC [`a:real^N`; `d:real`; `z:real^N`] THEN + FIRST_X_ASSUM(SUBST_ALL_TAC o MATCH_MP (REAL_ARITH + `c + d = &1 ==> c = (&1 - d)`)) THEN + ASM_REWRITE_TAC[REAL_ARITH `d <= &1 <=> &0 <= &1 - d`] THEN + CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + EXISTS_TAC `u:real^N->bool` THEN ASM_REWRITE_TAC[] THEN + CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + UNDISCH_TAC `CARD ((a:real^N) INSERT u) <= SUC n` THEN + ASM_SIMP_TAC[CARD_CLAUSES; LE_SUC]);; + +let FINITE_IMP_COMPACT_CONVEX_HULL = prove + (`!s:real^N->bool. FINITE s ==> compact(convex hull s)`, + SIMP_TAC[FINITE_IMP_COMPACT; COMPACT_CONVEX_HULL]);; + +(* ------------------------------------------------------------------------- *) +(* Extremal points of a simplex are some vertices. *) +(* ------------------------------------------------------------------------- *) + +let DIST_INCREASES_ONLINE = prove + (`!a b d. ~(d = vec 0) + ==> dist(a,b + d) > dist(a,b) \/ dist(a,b - d) > dist(a,b)`, + REWRITE_TAC[dist; vector_norm; real_gt; GSYM NORM_POS_LT] THEN + SIMP_TAC[SQRT_MONO_LT_EQ; DOT_POS_LE; SQRT_LT_0] THEN + REWRITE_TAC[DOT_RSUB; DOT_RADD; DOT_LSUB; DOT_LADD] THEN REAL_ARITH_TAC);; + +let NORM_INCREASES_ONLINE = prove + (`!a:real^N d. ~(d = vec 0) + ==> norm(a + d) > norm(a) \/ norm(a - d) > norm(a)`, + MP_TAC(ISPEC `vec 0 :real^N` DIST_INCREASES_ONLINE) THEN + REWRITE_TAC[dist; VECTOR_SUB_LZERO; NORM_NEG]);; + +let SIMPLEX_FURTHEST_LT = prove + (`!a:real^N s. + FINITE s + ==> !x. x IN (convex hull s) /\ ~(x IN s) + ==> ?y. y IN (convex hull s) /\ norm(x - a) < norm(y - a)`, + GEN_TAC THEN MATCH_MP_TAC FINITE_INDUCT_STRONG THEN + REWRITE_TAC[CONVEX_HULL_EMPTY; NOT_IN_EMPTY] THEN + MAP_EVERY X_GEN_TAC [`x:real^N`; `s:real^N->bool`] THEN + ASM_CASES_TAC `s:real^N->bool = {}` THENL + [ASM_REWRITE_TAC[CONVEX_HULL_SING; IN_SING] THEN MESON_TAC[]; + ALL_TAC] THEN + ASM_SIMP_TAC[CONVEX_HULL_INSERT] THEN + STRIP_TAC THEN X_GEN_TAC `y:real^N` THEN + REWRITE_TAC[IN_ELIM_THM; LEFT_AND_EXISTS_THM; LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`u:real`; `v:real`; `b:real^N`] THEN + ASM_CASES_TAC `y:real^N IN (convex hull s)` THENL + [REWRITE_TAC[IN_INSERT; DE_MORGAN_THM] THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `y:real^N`) THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC MONO_EXISTS THEN + X_GEN_TAC `c:real^N` THEN STRIP_TAC THEN + MAP_EVERY EXISTS_TAC [`&0`; `&1`; `c:real^N`] THEN + ASM_REWRITE_TAC[REAL_ADD_LID; REAL_POS] THEN VECTOR_ARITH_TAC; + ALL_TAC] THEN + ASM_CASES_TAC `u = &0` THENL + [ASM_SIMP_TAC[REAL_ADD_LID; VECTOR_MUL_LZERO; VECTOR_ADD_LID] THEN + ASM_MESON_TAC[VECTOR_MUL_LID]; + ALL_TAC] THEN + ASM_CASES_TAC `v = &0` THENL + [ASM_SIMP_TAC[REAL_ADD_RID; VECTOR_MUL_LZERO; VECTOR_ADD_RID] THEN + ASM_CASES_TAC `u = &1` THEN ASM_REWRITE_TAC[VECTOR_MUL_LID] THEN + ASM_CASES_TAC `y = a:real^N` THEN ASM_REWRITE_TAC[IN_INSERT] THEN + ASM_MESON_TAC[]; + ALL_TAC] THEN + REWRITE_TAC[IN_INSERT; DE_MORGAN_THM] THEN STRIP_TAC THEN + MP_TAC(SPECL [`u:real`; `v:real`] REAL_DOWN2) THEN ANTS_TAC THENL + [ASM_REWRITE_TAC[REAL_LT_LE]; ALL_TAC] THEN + DISCH_THEN(X_CHOOSE_THEN `w:real` STRIP_ASSUME_TAC) THEN + MP_TAC(ISPECL [`a:real^N`; `y:real^N`; `w % (x - b):real^N`] + DIST_INCREASES_ONLINE) THEN + ANTS_TAC THENL + [ASM_SIMP_TAC[VECTOR_MUL_EQ_0; REAL_LT_IMP_NZ] THEN + REWRITE_TAC[VECTOR_ARITH `(x - y = vec 0) <=> (x = y)`] THEN + DISCH_THEN SUBST_ALL_TAC THEN + UNDISCH_TAC `~(y:real^N IN convex hull s)` THEN + ASM_REWRITE_TAC[GSYM VECTOR_ADD_RDISTRIB; VECTOR_MUL_LID]; + ALL_TAC] THEN + ASM_REWRITE_TAC[dist; real_gt] THEN + REWRITE_TAC[VECTOR_ARITH + `((u % x + v % b) + w % (x - b) = (u + w) % x + (v - w) % b) /\ + ((u % x + v % b) - w % (x - b) = (u - w) % x + (v + w) % b)`] THEN + STRIP_TAC THENL + [MAP_EVERY EXISTS_TAC + [`(u + w) % x + (v - w) % b:real^N`; `u + w`; `v - w`; `b:real^N`]; + MAP_EVERY EXISTS_TAC + [`(u - w) % x + (v + w) % b:real^N`; `u - w`; `v + w`; `b:real^N`]] THEN + ONCE_REWRITE_TAC[NORM_SUB] THEN ASM_REWRITE_TAC[] THEN + ASM_SIMP_TAC[REAL_LE_ADD; REAL_LT_IMP_LE; REAL_SUB_LE] THEN + UNDISCH_TAC `u + v = &1` THEN REAL_ARITH_TAC);; + +let SIMPLEX_FURTHEST_LE = prove + (`!a:real^N s. + FINITE s /\ ~(s = {}) + ==> ?y. y IN s /\ + !x. x IN (convex hull s) ==> norm(x - a) <= norm(y - a)`, + REPEAT GEN_TAC THEN DISCH_TAC THEN + MP_TAC(ISPEC `convex hull (s:real^N->bool)` DISTANCE_ATTAINS_SUP) THEN + DISCH_THEN(MP_TAC o SPEC `a:real^N`) THEN ANTS_TAC THENL + [ASM_SIMP_TAC[FINITE_IMP_COMPACT_CONVEX_HULL] THEN + ASM_MESON_TAC[SUBSET_EMPTY; HULL_SUBSET]; + ALL_TAC] THEN + ONCE_REWRITE_TAC[DIST_SYM] THEN REWRITE_TAC[dist] THEN + ASM_MESON_TAC[SIMPLEX_FURTHEST_LT; REAL_NOT_LE]);; + +let SIMPLEX_FURTHEST_LE_EXISTS = prove + (`!a:real^N s. + FINITE s + ==> !x. x IN (convex hull s) + ==> ?y. y IN s /\ norm(x - a) <= norm(y - a)`, + MESON_TAC[NOT_IN_EMPTY; CONVEX_HULL_EMPTY; SIMPLEX_FURTHEST_LE]);; + +let SIMPLEX_EXTREMAL_LE = prove + (`!s:real^N->bool. + FINITE s /\ ~(s = {}) + ==> ?u v. u IN s /\ v IN s /\ + !x y. x IN convex hull s /\ y IN convex hull s + ==> norm(x - y) <= norm(u - v)`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPEC `convex hull (s:real^N->bool)` COMPACT_SUP_MAXDISTANCE) THEN + ANTS_TAC THENL + [ASM_SIMP_TAC[FINITE_IMP_COMPACT_CONVEX_HULL] THEN + ASM_MESON_TAC[SUBSET_EMPTY; HULL_SUBSET]; + ALL_TAC] THEN + REPEAT(MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC) THEN + SIMP_TAC[] THEN ASM_MESON_TAC[SIMPLEX_FURTHEST_LT; REAL_NOT_LE; NORM_SUB]);; + +let SIMPLEX_EXTREMAL_LE_EXISTS = prove + (`!s:real^N->bool x y. FINITE s /\ x IN convex hull s /\ y IN convex hull s + ==> ?u v. u IN s /\ v IN s /\ + norm(x - y) <= norm(u - v)`, + MESON_TAC[NOT_IN_EMPTY; CONVEX_HULL_EMPTY; SIMPLEX_EXTREMAL_LE]);; + +let DIAMETER_CONVEX_HULL = prove + (`!s:real^N->bool. diameter(convex hull s) = diameter s`, + let lemma = prove + (`!a b s. (!x. x IN s ==> dist(a,x) <= b) + ==> (!x. x IN convex hull s ==> dist(a,x) <= b)`, + REPEAT GEN_TAC THEN DISCH_TAC THEN + MATCH_MP_TAC HULL_INDUCT THEN ASM_REWRITE_TAC[GSYM cball; CONVEX_CBALL]) in + GEN_TAC THEN REWRITE_TAC[diameter; CONVEX_HULL_EQ_EMPTY] THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN MATCH_MP_TAC SUP_EQ THEN + REWRITE_TAC[FORALL_IN_GSPEC] THEN X_GEN_TAC `b:real` THEN + EQ_TAC THENL [MESON_TAC[SUBSET; HULL_SUBSET]; ALL_TAC] THEN + MATCH_MP_TAC(TAUT `!b. (a ==> b) /\ (b ==> c) ==> a ==> c`) THEN + EXISTS_TAC `!x:real^N y. x IN s /\ y IN convex hull s ==> norm(x - y) <= b` + THEN CONJ_TAC THENL + [MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `x:real^N` THEN + ASM_CASES_TAC `(x:real^N) IN s` THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[GSYM dist; lemma]; + ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN + MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `y:real^N` THEN + ASM_CASES_TAC `(y:real^N) IN convex hull s` THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[GSYM(ONCE_REWRITE_RULE[DIST_SYM] dist); lemma]]);; + +let DIAMETER_SIMPLEX = prove + (`!s:real^N->bool. + ~(s = {}) + ==> diameter(convex hull s) = sup { dist(x,y) | x IN s /\ y IN s}`, + REWRITE_TAC[DIAMETER_CONVEX_HULL] THEN SIMP_TAC[diameter; dist]);; + +(* ------------------------------------------------------------------------- *) +(* Closest point of a convex set is unique, with a continuous projection. *) +(* ------------------------------------------------------------------------- *) + +let CLOSER_POINTS_LEMMA = prove + (`!y:real^N z. + y dot z > &0 + ==> ?u. &0 < u /\ + !v. &0 < v /\ v <= u ==> norm(v % z - y) < norm y`, + REWRITE_TAC[NORM_LT; DOT_LSUB; DOT_RSUB; DOT_LMUL; DOT_RMUL; + REAL_SUB_LDISTRIB; real_gt] THEN REPEAT GEN_TAC THEN + REWRITE_TAC[REAL_ARITH `(a - b) - (c - d) < d <=> a < b + c`] THEN + STRIP_TAC THEN SUBST1_TAC(VECTOR_ARITH `(z:real^N) dot y = y dot z`) THEN + SIMP_TAC[GSYM REAL_ADD_LDISTRIB; REAL_LT_LMUL_EQ] THEN + EXISTS_TAC `(y dot (z:real^N)) / (z dot z)` THEN + SUBGOAL_THEN `&0 < z dot (z:real^N)` ASSUME_TAC THENL + [ASM_MESON_TAC[DOT_POS_LT; DOT_RZERO; REAL_LT_REFL]; ALL_TAC] THEN + ASM_SIMP_TAC[REAL_LT_DIV; REAL_LE_RDIV_EQ] THEN + ASM_SIMP_TAC[REAL_ARITH `&0 < y /\ x <= y ==> x < y + y`; REAL_LT_MUL]);; + +let CLOSER_POINT_LEMMA = prove + (`!x y z. (y - x) dot (z - x) > &0 + ==> ?u. &0 < u /\ u <= &1 /\ dist(x + u % (z - x),y) < dist(x,y)`, + REPEAT STRIP_TAC THEN FIRST_ASSUM(MP_TAC o MATCH_MP CLOSER_POINTS_LEMMA) THEN + ONCE_REWRITE_TAC[DIST_SYM] THEN REWRITE_TAC[dist; NORM_LT] THEN + REWRITE_TAC[VECTOR_ARITH + `(y - (x + z)) dot (y - (x + z)) = (z - (y - x)) dot (z - (y - x))`] THEN + DISCH_THEN(X_CHOOSE_THEN `u:real` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `min u (&1)` THEN + ASM_SIMP_TAC[REAL_LT_MIN; REAL_MIN_LE; REAL_LT_01; REAL_LE_REFL]);; + +let ANY_CLOSEST_POINT_DOT = prove + (`!s a x y:real^N. + convex s /\ closed s /\ x IN s /\ y IN s /\ + (!z. z IN s ==> dist(a,x) <= dist(a,z)) + ==> (a - x) dot (y - x) <= &0`, + REPEAT STRIP_TAC THEN REWRITE_TAC[REAL_ARITH `x <= &0 <=> ~(x > &0)`] THEN + DISCH_THEN(MP_TAC o MATCH_MP CLOSER_POINT_LEMMA) THEN + DISCH_THEN(X_CHOOSE_THEN `u:real` (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + REWRITE_TAC[REAL_NOT_LT] THEN ONCE_REWRITE_TAC[DIST_SYM] THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN + REWRITE_TAC[VECTOR_ARITH `x + u % (y - x) = (&1 - u) % x + u % y`] THEN + MATCH_MP_TAC IN_CONVEX_SET THEN ASM_SIMP_TAC[REAL_LT_IMP_LE]);; + +let ANY_CLOSEST_POINT_UNIQUE = prove + (`!s a x y:real^N. + convex s /\ closed s /\ x IN s /\ y IN s /\ + (!z. z IN s ==> dist(a,x) <= dist(a,z)) /\ + (!z. z IN s ==> dist(a,y) <= dist(a,z)) + ==> x = y`, + REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[GSYM VECTOR_SUB_EQ] THEN + REWRITE_TAC[GSYM NORM_LE_0; NORM_LE_SQUARE] THEN + SUBGOAL_THEN `(a - x:real^N) dot (y - x) <= &0 /\ (a - y) dot (x - y) <= &0` + MP_TAC THENL [ASM_MESON_TAC[ANY_CLOSEST_POINT_DOT]; ALL_TAC] THEN + REWRITE_TAC[NORM_LT; DOT_LSUB; DOT_RSUB] THEN REAL_ARITH_TAC);; + +let CLOSEST_POINT_UNIQUE = prove + (`!s a x:real^N. + convex s /\ closed s /\ x IN s /\ + (!z. z IN s ==> dist(a,x) <= dist(a,z)) + ==> x = closest_point s a`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC ANY_CLOSEST_POINT_UNIQUE THEN + MAP_EVERY EXISTS_TAC [`s:real^N->bool`; `a:real^N`] THEN + ASM_MESON_TAC[CLOSEST_POINT_EXISTS; MEMBER_NOT_EMPTY]);; + +let CLOSEST_POINT_DOT = prove + (`!s a x:real^N. + convex s /\ closed s /\ x IN s + ==> (a - closest_point s a) dot (x - closest_point s a) <= &0`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC ANY_CLOSEST_POINT_DOT THEN + EXISTS_TAC `s:real^N->bool` THEN + ASM_MESON_TAC[CLOSEST_POINT_EXISTS; MEMBER_NOT_EMPTY]);; + +let CLOSEST_POINT_LT = prove + (`!s a x. convex s /\ closed s /\ x IN s /\ ~(x = closest_point s a) + ==> dist(a,closest_point s a) < dist(a,x)`, + REPEAT GEN_TAC THEN + REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + REWRITE_TAC[GSYM REAL_NOT_LE; CONTRAPOS_THM] THEN + DISCH_TAC THEN MATCH_MP_TAC CLOSEST_POINT_UNIQUE THEN + ASM_REWRITE_TAC[] THEN ASM_MESON_TAC[CLOSEST_POINT_LE; REAL_LE_TRANS]);; + +let CLOSEST_POINT_LIPSCHITZ = prove + (`!s x y:real^N. + convex s /\ closed s /\ ~(s = {}) + ==> dist(closest_point s x,closest_point s y) <= dist(x,y)`, + REPEAT STRIP_TAC THEN REWRITE_TAC[dist; NORM_LE] THEN + SUBGOAL_THEN + `(x - closest_point s x :real^N) dot + (closest_point s y - closest_point s x) <= &0 /\ + (y - closest_point s y) dot + (closest_point s x - closest_point s y) <= &0` + MP_TAC THENL + [CONJ_TAC THEN MATCH_MP_TAC ANY_CLOSEST_POINT_DOT THEN + EXISTS_TAC `s:real^N->bool` THEN ASM_MESON_TAC[CLOSEST_POINT_EXISTS]; + MP_TAC(ISPEC `(x - closest_point s x :real^N) - (y - closest_point s y)` + DOT_POS_LE) THEN + REWRITE_TAC[NORM_LT; DOT_LSUB; DOT_RSUB; DOT_SYM] THEN REAL_ARITH_TAC]);; + +let CONTINUOUS_AT_CLOSEST_POINT = prove + (`!s x. convex s /\ closed s /\ ~(s = {}) + ==> (closest_point s) continuous (at x)`, + REPEAT STRIP_TAC THEN REWRITE_TAC[continuous_at] THEN + ASM_MESON_TAC[CLOSEST_POINT_LIPSCHITZ; REAL_LET_TRANS]);; + +let CONTINUOUS_ON_CLOSEST_POINT = prove + (`!s t. convex s /\ closed s /\ ~(s = {}) + ==> (closest_point s) continuous_on t`, + MESON_TAC[CONTINUOUS_AT_IMP_CONTINUOUS_ON; CONTINUOUS_AT_CLOSEST_POINT]);; + +(* ------------------------------------------------------------------------- *) +(* Relating closest points and orthogonality. *) +(* ------------------------------------------------------------------------- *) + +let ANY_CLOSEST_POINT_AFFINE_ORTHOGONAL = prove + (`!s a b:real^N. + affine s /\ b IN s /\ (!x. x IN s ==> dist(a,b) <= dist(a,x)) + ==> (!x. x IN s ==> orthogonal (x - b) (a - b))`, + REPEAT GEN_TAC THEN GEOM_ORIGIN_TAC `b:real^N` THEN + REWRITE_TAC[DIST_0; VECTOR_SUB_RZERO; orthogonal; dist; NORM_LE] THEN + REWRITE_TAC[DOT_LSUB] THEN REWRITE_TAC[DOT_RSUB] THEN + REWRITE_TAC[DOT_SYM; REAL_ARITH `a <= a - y - (y - x) <=> &2 * y <= x`] THEN + REPEAT STRIP_TAC THEN ASM_CASES_TAC `x:real^N = vec 0` THEN + ASM_REWRITE_TAC[DOT_RZERO] THEN FIRST_X_ASSUM(fun th -> + MP_TAC(SPEC `vec 0 + --((a dot x) / (x dot x)) % (x - vec 0:real^N)` th) THEN + MP_TAC(SPEC `vec 0 + (a dot x) / (x dot x) % (x - vec 0:real^N)` th)) THEN + ASM_SIMP_TAC[IN_AFFINE_ADD_MUL_DIFF] THEN + REWRITE_TAC[VECTOR_SUB_RZERO; VECTOR_ADD_LID; DOT_RMUL] THEN + REWRITE_TAC[DOT_LMUL; IMP_IMP] THEN DISCH_THEN(MP_TAC o MATCH_MP (REAL_ARITH + `&2 * x * a <= b * c * z /\ &2 * --x * a <= --b * --c * z + ==> &2 * abs(x * a) <= b * c * z`)) THEN + ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN DISCH_TAC THEN + ASM_SIMP_TAC[REAL_NOT_LE; REAL_DIV_RMUL; DOT_EQ_0] THEN + MATCH_MP_TAC(REAL_ARITH `~(x = &0) ==> x < &2 * abs x`) THEN + RULE_ASSUM_TAC(REWRITE_RULE[GSYM DOT_EQ_0]) THEN + REPEAT(POP_ASSUM MP_TAC) THEN CONV_TAC REAL_FIELD);; + +let ORTHOGONAL_ANY_CLOSEST_POINT = prove + (`!s a b:real^N. + b IN s /\ (!x. x IN s ==> orthogonal (x - b) (a - b)) + ==> (!x. x IN s ==> dist(a,b) <= dist(a,x))`, + REPEAT GEN_TAC THEN GEOM_ORIGIN_TAC `b:real^N` THEN + REWRITE_TAC[dist; NORM_LE; orthogonal; VECTOR_SUB_RZERO] THEN + SIMP_TAC[DOT_LSUB; DOT_RSUB; DOT_SYM] THEN + REWRITE_TAC[DOT_POS_LE; REAL_ARITH `a <= a - &0 - (&0 - x) <=> &0 <= x`]);; + +let CLOSEST_POINT_AFFINE_ORTHOGONAL = prove + (`!s a:real^N x. + affine s /\ ~(s = {}) /\ x IN s + ==> orthogonal (x - closest_point s a) (a - closest_point s a)`, + GEN_TAC THEN REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN + DISCH_TAC THEN DISCH_TAC THEN GEN_TAC THEN + MATCH_MP_TAC ANY_CLOSEST_POINT_AFFINE_ORTHOGONAL THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC CLOSEST_POINT_EXISTS THEN + ASM_SIMP_TAC[CLOSED_AFFINE]);; + +let CLOSEST_POINT_AFFINE_ORTHOGONAL_EQ = prove + (`!s a b:real^N. + affine s /\ b IN s + ==> (closest_point s a = b <=> + !x. x IN s ==> orthogonal (x - b) (a - b))`, + REPEAT STRIP_TAC THEN EQ_TAC THENL + [ASM_MESON_TAC[CLOSEST_POINT_AFFINE_ORTHOGONAL; MEMBER_NOT_EMPTY]; + DISCH_TAC THEN CONV_TAC SYM_CONV THEN + MATCH_MP_TAC CLOSEST_POINT_UNIQUE THEN + ASM_SIMP_TAC[CLOSED_AFFINE; AFFINE_IMP_CONVEX] THEN + MATCH_MP_TAC ORTHOGONAL_ANY_CLOSEST_POINT THEN ASM_REWRITE_TAC[]]);; + +(* ------------------------------------------------------------------------- *) +(* Various point-to-set separating/supporting hyperplane theorems. *) +(* ------------------------------------------------------------------------- *) + +let SUPPORTING_HYPERPLANE_COMPACT_POINT_SUP = prove + (`!a c s:real^N->bool. + compact s /\ ~(s = {}) + ==> ?b y. y IN s /\ a dot (y - c) = b /\ + (!x. x IN s ==> a dot (x - c) <= b)`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`\x:real^N. a dot (x - c)`; `s:real^N->bool`] + CONTINUOUS_ATTAINS_SUP) THEN + ASM_REWRITE_TAC[] THEN + ANTS_TAC THENL [ALL_TAC; MESON_TAC[]] THEN + SUBGOAL_THEN `(\x:real^N. a dot (x - c)) = (\x. a dot x) o (\x. x - c)` + SUBST1_TAC THENL [REWRITE_TAC[o_DEF]; ALL_TAC] THEN + REWRITE_TAC[o_ASSOC] THEN MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN + SIMP_TAC[CONTINUOUS_ON_LIFT_DOT; CONTINUOUS_ON_SUB; CONTINUOUS_ON_CONST; + CONTINUOUS_ON_ID]);; + +let SUPPORTING_HYPERPLANE_COMPACT_POINT_INF = prove + (`!a c s:real^N->bool. + compact s /\ ~(s = {}) + ==> ?b y. y IN s /\ a dot (y - c) = b /\ + (!x. x IN s ==> a dot (x - c) >= b)`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`--a:real^N`; `c:real^N`; `s:real^N->bool`] + SUPPORTING_HYPERPLANE_COMPACT_POINT_SUP) THEN + ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `b:real` + (fun th -> EXISTS_TAC `--b:real` THEN MP_TAC th)) THEN + REWRITE_TAC[DOT_LNEG; REAL_ARITH `x >= -- b <=> --x <= b`] THEN + REWRITE_TAC[REAL_NEG_EQ]);; + +let SUPPORTING_HYPERPLANE_CLOSED_POINT = prove + (`!s z:real^N. convex s /\ closed s /\ ~(s = {}) /\ ~(z IN s) + ==> ?a b y. a dot z < b /\ y IN s /\ (a dot y = b) /\ + (!x. x IN s ==> a dot x >= b)`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`s:real^N->bool`; `z:real^N`] DISTANCE_ATTAINS_INF) THEN + ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `y:real^N` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `y - z:real^N` THEN EXISTS_TAC `(y - z:real^N) dot y` THEN + EXISTS_TAC `y:real^N` THEN ONCE_REWRITE_TAC[GSYM REAL_SUB_LT] THEN + ASM_REWRITE_TAC[GSYM DOT_RSUB; DOT_POS_LT; VECTOR_SUB_EQ] THEN + CONJ_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN X_GEN_TAC `x:real^N` THEN + DISCH_TAC THEN SUBGOAL_THEN + `!u. &0 <= u /\ u <= &1 ==> dist(z:real^N,y) <= dist(z,(&1 - u) % y + u % x)` + MP_TAC THENL [ASM_MESON_TAC[CONVEX_ALT]; ALL_TAC] THEN + ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN ONCE_REWRITE_TAC[DIST_SYM] THEN + REWRITE_TAC[real_ge; REAL_NOT_LE; NOT_FORALL_THM; NOT_IMP] THEN + GEN_REWRITE_TAC LAND_CONV [REAL_ARITH `x < y <=> y - x > &0`] THEN + REWRITE_TAC[VECTOR_ARITH + `(a - b) dot x - (a - b) dot y = (b - a) dot (y - x)`] THEN + DISCH_THEN(MP_TAC o MATCH_MP CLOSER_POINT_LEMMA) THEN + REWRITE_TAC[VECTOR_ARITH `y + u % (x - y) = (&1 - u) % y + u % x`] THEN + MESON_TAC[REAL_LT_IMP_LE]);; + +let SEPARATING_HYPERPLANE_CLOSED_POINT_INSET = prove + (`!s z:real^N. convex s /\ closed s /\ ~(s = {}) /\ ~(z IN s) + ==> ?a b. a IN s /\ + (a - z) dot z < b /\ + (!x. x IN s ==> (a - z) dot x > b)`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`s:real^N->bool`; `z:real^N`] DISTANCE_ATTAINS_INF) THEN + ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `y:real^N` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `y:real^N` THEN ASM_REWRITE_TAC[] THEN + EXISTS_TAC `(y - z:real^N) dot z + norm(y - z) pow 2 / &2` THEN + SUBGOAL_THEN `&0 < norm(y - z:real^N)` ASSUME_TAC THENL + [ASM_MESON_TAC[NORM_POS_LT; VECTOR_SUB_EQ]; ALL_TAC] THEN + ASM_SIMP_TAC[REAL_LT_ADDR; REAL_LT_DIV; REAL_POW_LT; + REAL_OF_NUM_LT; ARITH] THEN + REWRITE_TAC[NORM_POW_2; REAL_ARITH `a > b + c <=> c < a - b`] THEN + X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN + SIMP_TAC[REAL_LT_LDIV_EQ; REAL_OF_NUM_LT; ARITH] THEN + ONCE_REWRITE_TAC[GSYM REAL_SUB_LT] THEN + REWRITE_TAC[VECTOR_ARITH + `((y - z) dot x - (y - z) dot z) * &2 - (y - z) dot (y - z) = + &2 * ((y - z) dot (x - y)) + (y - z) dot (y - z)`] THEN + MATCH_MP_TAC(REAL_ARITH `~(--x > &0) /\ &0 < y ==> &0 < &2 * x + y`) THEN + ASM_SIMP_TAC[GSYM NORM_POW_2; REAL_POW_LT] THEN + REWRITE_TAC[GSYM DOT_LNEG; VECTOR_NEG_SUB] THEN + DISCH_THEN(MP_TAC o MATCH_MP CLOSER_POINT_LEMMA) THEN + REWRITE_TAC[NOT_EXISTS_THM] THEN ONCE_REWRITE_TAC[DIST_SYM] THEN + GEN_TAC THEN REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + REWRITE_TAC[REAL_NOT_LT] THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + REWRITE_TAC[VECTOR_ARITH `y + u % (x - y) = (&1 - u) % y + u % x`] THEN + ASM_MESON_TAC[CONVEX_ALT; REAL_LT_IMP_LE]);; + +let SEPARATING_HYPERPLANE_CLOSED_0_INSET = prove + (`!s:real^N->bool. + convex s /\ closed s /\ ~(s = {}) /\ ~(vec 0 IN s) + ==> ?a b. a IN s /\ ~(a = vec 0) /\ &0 < b /\ + (!x. x IN s ==> a dot x > b)`, + REPEAT GEN_TAC THEN DISCH_TAC THEN + FIRST_ASSUM(MP_TAC o MATCH_MP SEPARATING_HYPERPLANE_CLOSED_POINT_INSET) THEN + REWRITE_TAC[DOT_RZERO; real_gt] THEN + REPEAT(MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC) THEN + SIMP_TAC[VECTOR_SUB_RZERO] THEN ASM_MESON_TAC[]);; + +let SEPARATING_HYPERPLANE_CLOSED_POINT = prove + (`!s z:real^N. convex s /\ closed s /\ ~(z IN s) + ==> ?a b. a dot z < b /\ (!x. x IN s ==> a dot x > b)`, + REPEAT STRIP_TAC THEN ASM_CASES_TAC `s:real^N->bool = {}` THENL + [MAP_EVERY EXISTS_TAC [`--z:real^N`; `&1`] THEN + SIMP_TAC[DOT_LNEG; REAL_ARITH `&0 <= x ==> --x < &1`; DOT_POS_LE] THEN + ASM_MESON_TAC[NOT_IN_EMPTY]; + ALL_TAC] THEN + ASM_MESON_TAC[SEPARATING_HYPERPLANE_CLOSED_POINT_INSET]);; + +let SEPARATING_HYPERPLANE_CLOSED_0 = prove + (`!s:real^N->bool. + convex s /\ closed s /\ ~(vec 0 IN s) + ==> ?a b. ~(a = vec 0) /\ &0 < b /\ (!x. x IN s ==> a dot x > b)`, + REPEAT GEN_TAC THEN DISCH_TAC THEN ASM_CASES_TAC `s:real^N->bool = {}` THENL + [EXISTS_TAC `basis 1:real^N` THEN EXISTS_TAC `&1` THEN + ASM_REWRITE_TAC[NOT_IN_EMPTY; REAL_LT_01; GSYM NORM_POS_LT] THEN + ASM_SIMP_TAC[NORM_BASIS; DIMINDEX_GE_1; LE_REFL; REAL_LT_01]; + FIRST_X_ASSUM(MP_TAC o MATCH_MP SEPARATING_HYPERPLANE_CLOSED_POINT) THEN + REWRITE_TAC[DOT_RZERO; real_gt] THEN + REPEAT(MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC) THEN + ASM_MESON_TAC[MEMBER_NOT_EMPTY; DOT_LZERO; REAL_LT_ANTISYM]]);; + +(* ------------------------------------------------------------------------- *) +(* Now set-to-set for closed/compact sets. *) +(* ------------------------------------------------------------------------- *) + +let SEPARATING_HYPERPLANE_CLOSED_COMPACT = prove + (`!s t. convex s /\ closed s /\ + convex t /\ compact t /\ ~(t = {}) /\ DISJOINT s t + ==> ?a:real^N b. (!x. x IN s ==> a dot x < b) /\ + (!x. x IN t ==> a dot x > b)`, + REPEAT STRIP_TAC THEN ASM_CASES_TAC `s:real^N->bool = {}` THENL + [ASM_REWRITE_TAC[NOT_IN_EMPTY] THEN + FIRST_ASSUM(MP_TAC o MATCH_MP COMPACT_IMP_BOUNDED) THEN + REWRITE_TAC[BOUNDED_POS] THEN + DISCH_THEN(X_CHOOSE_THEN `b:real` STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN `?z:real^N. norm(z) = b + &1` CHOOSE_TAC THENL + [ASM_SIMP_TAC[VECTOR_CHOOSE_SIZE; REAL_ARITH `&0 < b ==> &0 <= b + &1`]; + ALL_TAC] THEN + MP_TAC(SPECL [`t:real^N->bool`; `z:real^N`] + SEPARATING_HYPERPLANE_CLOSED_POINT) THEN + ANTS_TAC THENL [ALL_TAC; ASM_MESON_TAC[]] THEN + ASM_SIMP_TAC[COMPACT_IMP_CLOSED] THEN + ASM_MESON_TAC[REAL_ARITH `~(b + &1 <= b)`]; + ALL_TAC] THEN + MP_TAC(ISPECL [`{x - y:real^N | x IN s /\ y IN t}`; `vec 0 :real^N`] + SEPARATING_HYPERPLANE_CLOSED_POINT) THEN + ASM_SIMP_TAC[CLOSED_COMPACT_DIFFERENCES; CONVEX_DIFFERENCES] THEN + ANTS_TAC THENL + [REWRITE_TAC[IN_ELIM_THM] THEN ONCE_REWRITE_TAC[EQ_SYM_EQ] THEN + REWRITE_TAC[VECTOR_SUB_EQ] THEN + ASM_MESON_TAC[DISJOINT; NOT_IN_EMPTY; IN_INTER; EXTENSION]; + ALL_TAC] THEN + SIMP_TAC[DOT_RZERO; IN_ELIM_THM; LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`a:real^N`; `b:real`] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + GEN_REWRITE_TAC LAND_CONV [SWAP_FORALL_THM] THEN + GEN_REWRITE_TAC (LAND_CONV o BINDER_CONV) [SWAP_FORALL_THM] THEN + ONCE_REWRITE_TAC[IMP_CONJ] THEN REWRITE_TAC[RIGHT_FORALL_IMP_THM] THEN + REWRITE_TAC[LEFT_FORALL_IMP_THM; EXISTS_REFL; DOT_RSUB] THEN + REWRITE_TAC[real_gt; REAL_LT_SUB_LADD] THEN DISCH_TAC THEN + EXISTS_TAC `--a:real^N` THEN + MP_TAC(SPEC `IMAGE (\x:real^N. a dot x) t` SUP) THEN + ABBREV_TAC `k = sup (IMAGE (\x:real^N. a dot x) t)` THEN + ASM_REWRITE_TAC[FORALL_IN_IMAGE; IMAGE_EQ_EMPTY] THEN ANTS_TAC THENL + [ASM_MESON_TAC[REAL_ARITH `b + x < y ==> x <= y - b`; MEMBER_NOT_EMPTY]; + ALL_TAC] THEN + STRIP_TAC THEN EXISTS_TAC `--(k + b / &2)` THEN + REWRITE_TAC[DOT_LNEG; REAL_LT_NEG2] THEN REPEAT STRIP_TAC THEN + ASM_SIMP_TAC[REAL_LT_DIV; REAL_OF_NUM_LT; ARITH; + REAL_ARITH `&0 < b /\ x <= k ==> x < k + b`] THEN + FIRST_X_ASSUM(MP_TAC o SPEC `k - b / &2`) THEN + ASM_SIMP_TAC[REAL_ARITH `k <= k - b2 <=> ~(&0 < b2)`; REAL_LT_DIV; + REAL_OF_NUM_LT; ARITH; NOT_FORALL_THM; LEFT_IMP_EXISTS_THM; NOT_IMP] THEN + X_GEN_TAC `y:real^N` THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + MATCH_MP_TAC(REAL_ARITH + `!b. (b2 + b2 = b) /\ b + ay < ax ==> ~(ay <= k - b2) ==> k + b2 < ax`) THEN + ASM_MESON_TAC[REAL_HALF]);; + +let SEPARATING_HYPERPLANE_COMPACT_CLOSED = prove + (`!s t. convex s /\ compact s /\ ~(s = {}) /\ + convex t /\ closed t /\ DISJOINT s t + ==> ?a:real^N b. (!x. x IN s ==> a dot x < b) /\ + (!x. x IN t ==> a dot x > b)`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`t:real^N->bool`; `s:real^N->bool`] + SEPARATING_HYPERPLANE_CLOSED_COMPACT) THEN + ANTS_TAC THENL [ASM_MESON_TAC[DISJOINT_SYM]; ALL_TAC] THEN + REWRITE_TAC[real_gt] THEN + DISCH_THEN(X_CHOOSE_THEN `a:real^N` (X_CHOOSE_THEN `b:real` + STRIP_ASSUME_TAC)) THEN + MAP_EVERY EXISTS_TAC [`--a:real^N`; `--b:real`] THEN + ASM_REWRITE_TAC[REAL_LT_NEG2; DOT_LNEG]);; + +let SEPARATING_HYPERPLANE_COMPACT_CLOSED_NONZERO = prove + (`!s t:real^N->bool. + convex s /\ compact s /\ ~(s = {}) /\ + convex t /\ closed t /\ DISJOINT s t + ==> ?a b. ~(a = vec 0) /\ + (!x. x IN s ==> a dot x < b) /\ + (!x. x IN t ==> a dot x > b)`, + REPEAT GEN_TAC THEN ASM_CASES_TAC `t:real^N->bool = {}` THENL + [ASM_REWRITE_TAC[NOT_IN_EMPTY] THEN STRIP_TAC THEN + EXISTS_TAC `basis 1:real^N` THEN + SUBGOAL_THEN + `bounded(IMAGE (\x:real^N. lift(basis 1 dot x)) s)` + MP_TAC THENL + [MATCH_MP_TAC COMPACT_IMP_BOUNDED THEN + MATCH_MP_TAC COMPACT_CONTINUOUS_IMAGE THEN + ASM_SIMP_TAC[REWRITE_RULE[o_DEF] CONTINUOUS_ON_LIFT_DOT]; + REWRITE_TAC[BOUNDED_POS_LT; FORALL_IN_IMAGE; NORM_LIFT] THEN + SIMP_TAC[BASIS_NONZERO; DIMINDEX_GE_1; LE_REFL] THEN + MESON_TAC[REAL_ARITH `abs x < b ==> x < b`]]; + STRIP_TAC THEN + MP_TAC(ISPECL [`s:real^N->bool`; `t:real^N->bool`] + SEPARATING_HYPERPLANE_COMPACT_CLOSED) THEN + ASM_REWRITE_TAC[] THEN + REPEAT(MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC) THEN + ASM_CASES_TAC `a:real^N = vec 0` THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[DOT_LZERO; real_gt] THEN + ASM_MESON_TAC[REAL_LT_ANTISYM; MEMBER_NOT_EMPTY]]);; + +let SEPARATING_HYPERPLANE_COMPACT_COMPACT = prove + (`!s t:real^N->bool. + convex s /\ compact s /\ convex t /\ compact t /\ DISJOINT s t + ==> ?a b. ~(a = vec 0) /\ + (!x. x IN s ==> a dot x < b) /\ + (!x. x IN t ==> a dot x > b)`, + REPEAT GEN_TAC THEN ASM_CASES_TAC `s:real^N->bool = {}` THENL + [ASM_REWRITE_TAC[NOT_IN_EMPTY] THEN STRIP_TAC THEN + EXISTS_TAC `--basis 1:real^N` THEN + SUBGOAL_THEN + `bounded(IMAGE (\x:real^N. lift(basis 1 dot x)) t)` + MP_TAC THENL + [MATCH_MP_TAC COMPACT_IMP_BOUNDED THEN + MATCH_MP_TAC COMPACT_CONTINUOUS_IMAGE THEN + ASM_SIMP_TAC[REWRITE_RULE[o_DEF] CONTINUOUS_ON_LIFT_DOT]; + REWRITE_TAC[BOUNDED_POS_LT; FORALL_IN_IMAGE; NORM_LIFT] THEN + SIMP_TAC[VECTOR_NEG_EQ_0; BASIS_NONZERO; DIMINDEX_GE_1; LE_REFL] THEN + DISCH_THEN(X_CHOOSE_THEN `b:real` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `--b:real` THEN REWRITE_TAC[DOT_LNEG] THEN + REWRITE_TAC[REAL_ARITH `--x > --y <=> x < y`] THEN + ASM_MESON_TAC[REAL_ARITH `abs x < b ==> x < b`]]; + STRIP_TAC THEN + MATCH_MP_TAC SEPARATING_HYPERPLANE_COMPACT_CLOSED_NONZERO THEN + ASM_SIMP_TAC[COMPACT_IMP_CLOSED]]);; + +(* ------------------------------------------------------------------------- *) +(* General case without assuming closure and getting non-strict separation. *) +(* ------------------------------------------------------------------------- *) + +let SEPARATING_HYPERPLANE_SET_0_INSPAN = prove + (`!s:real^N->bool. + convex s /\ ~(s = {}) /\ ~(vec 0 IN s) + ==> ?a b. a IN span s /\ ~(a = vec 0) /\ + !x. x IN s ==> &0 <= a dot x`, + REPEAT STRIP_TAC THEN + ABBREV_TAC `k = \c:real^N. {x | &0 <= c dot x}` THEN + SUBGOAL_THEN + `~((span s INTER frontier(cball(vec 0:real^N,&1))) INTER + (INTERS (IMAGE k (s:real^N->bool))) = {})` + MP_TAC THENL + [ALL_TAC; + SIMP_TAC[EXTENSION; NOT_IN_EMPTY; IN_INTER; IN_INTERS; NOT_FORALL_THM; + FORALL_IN_IMAGE; FRONTIER_CBALL; REAL_LT_01] THEN + EXPAND_TAC "k" THEN REWRITE_TAC[IN_SPHERE_0; IN_ELIM_THM; NORM_NEG] THEN + MESON_TAC[NORM_EQ_0; REAL_ARITH `~(&1 = &0)`; DOT_SYM]] THEN + MATCH_MP_TAC COMPACT_IMP_FIP THEN + SIMP_TAC[COMPACT_CBALL; COMPACT_FRONTIER; FORALL_IN_IMAGE; + CLOSED_INTER_COMPACT; CLOSED_SPAN] THEN + CONJ_TAC THENL + [EXPAND_TAC "k" THEN REWRITE_TAC[GSYM real_ge; CLOSED_HALFSPACE_GE]; + ALL_TAC] THEN + REWRITE_TAC[FINITE_SUBSET_IMAGE] THEN GEN_TAC THEN + DISCH_THEN(X_CHOOSE_THEN `c:real^N->bool` MP_TAC) THEN + ASM_CASES_TAC `c:real^N->bool = {}` THENL + [ASM_SIMP_TAC[INTERS_0; INTER_UNIV; IMAGE_CLAUSES] THEN + DISCH_THEN(K ALL_TAC) THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN + DISCH_THEN(X_CHOOSE_TAC `a:real^N`) THEN + SUBGOAL_THEN `~(a:real^N = vec 0)` ASSUME_TAC THENL + [ASM_MESON_TAC[]; ALL_TAC] THEN + REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN + EXISTS_TAC `inv(norm a) % a:real^N` THEN + ASM_SIMP_TAC[IN_INTER; FRONTIER_CBALL; SPAN_CLAUSES; IN_SPHERE_0] THEN + REWRITE_TAC[DIST_0; NORM_MUL; REAL_ABS_INV; REAL_ABS_NORM] THEN + ASM_SIMP_TAC[REAL_MUL_LINV; NORM_EQ_0]; + ALL_TAC] THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + MP_TAC(ISPEC `convex hull (c:real^N->bool)` + SEPARATING_HYPERPLANE_CLOSED_0_INSET) THEN + ANTS_TAC THENL + [ASM_REWRITE_TAC[CONVEX_HULL_EQ_EMPTY] THEN + ASM_MESON_TAC[CONVEX_CONVEX_HULL; SUBSET; SUBSET_HULL; HULL_SUBSET; + FINITE_IMP_COMPACT_CONVEX_HULL; COMPACT_IMP_CLOSED]; + ALL_TAC] THEN + REWRITE_TAC[DOT_RZERO; real_gt] THEN + DISCH_THEN(X_CHOOSE_THEN `a:real^N` (X_CHOOSE_THEN `b:real` + STRIP_ASSUME_TAC)) THEN + REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; IN_INTER; IN_INTERS; FORALL_IN_IMAGE] THEN + EXPAND_TAC "k" THEN SIMP_TAC[IN_ELIM_THM; FRONTIER_CBALL; REAL_LT_01] THEN + REWRITE_TAC[dist; VECTOR_SUB_LZERO; NORM_NEG] THEN + EXISTS_TAC `inv(norm(a)) % a:real^N` THEN REWRITE_TAC[DOT_RMUL] THEN + SUBGOAL_THEN `(a:real^N) IN s` ASSUME_TAC THENL + [ASM_MESON_TAC[SUBSET; HULL_MINIMAL]; ASM_SIMP_TAC[SPAN_CLAUSES]] THEN + REWRITE_TAC[IN_SPHERE_0; VECTOR_SUB_LZERO; NORM_NEG; NORM_MUL] THEN + REWRITE_TAC[REAL_ABS_INV; REAL_ABS_NORM] THEN + ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN REWRITE_TAC[GSYM real_div] THEN + ASM_SIMP_TAC[REAL_LE_RDIV_EQ; REAL_EQ_LDIV_EQ; NORM_POS_LT] THEN + REWRITE_TAC[REAL_MUL_LZERO; REAL_MUL_LID] THEN + ASM_MESON_TAC[REAL_LT_IMP_LE; REAL_LE_TRANS; HULL_SUBSET; SUBSET; DOT_SYM]);; + +let SEPARATING_HYPERPLANE_SET_POINT_INAFF = prove + (`!s z:real^N. + convex s /\ ~(s = {}) /\ ~(z IN s) + ==> ?a b. (z + a) IN affine hull (z INSERT s) /\ ~(a = vec 0) /\ + a dot z <= b /\ (!x. x IN s ==> a dot x >= b)`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPEC `IMAGE (\x:real^N. --z + x) s` + SEPARATING_HYPERPLANE_SET_0_INSPAN) THEN + ASM_SIMP_TAC[FORALL_IN_IMAGE; CONVEX_TRANSLATION; IMAGE_EQ_EMPTY] THEN + REWRITE_TAC[IN_IMAGE; VECTOR_ARITH `vec 0:real^N = --z + x <=> x = z`] THEN + ASM_SIMP_TAC[UNWIND_THM2; AFFINE_HULL_INSERT_SPAN; IN_ELIM_THM] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `a:real^N` THEN + REWRITE_TAC[GSYM SIMPLE_IMAGE; VECTOR_ARITH `--x + y:real^N = y - x`] THEN + STRIP_TAC THEN ASM_REWRITE_TAC[RIGHT_EXISTS_AND_THM] THEN + CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + EXISTS_TAC `(a:real^N) dot z` THEN REWRITE_TAC[REAL_LE_REFL] THEN + ASM_REWRITE_TAC[REAL_ARITH `x >= y <=> &0 <= x - y`; GSYM DOT_RSUB]);; + +let SEPARATING_HYPERPLANE_SET_0 = prove + (`!s:real^N->bool. + convex s /\ ~(vec 0 IN s) + ==> ?a b. ~(a = vec 0) /\ !x. x IN s ==> &0 <= a dot x`, + REPEAT STRIP_TAC THEN ASM_CASES_TAC `s:real^N->bool = {}` THENL + [ASM_REWRITE_TAC[NOT_IN_EMPTY] THEN + MESON_TAC[BASIS_NONZERO; LE_REFL; DIMINDEX_GE_1]; + ASM_MESON_TAC[SEPARATING_HYPERPLANE_SET_0_INSPAN]]);; + +let SEPARATING_HYPERPLANE_SETS = prove + (`!s t. convex s /\ convex t /\ ~(s = {}) /\ ~(t = {}) /\ DISJOINT s t + ==> ?a:real^N b. ~(a = vec 0) /\ + (!x. x IN s ==> a dot x <= b) /\ + (!x. x IN t ==> a dot x >= b)`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPEC `{y - x:real^N | y IN t /\ x IN s}` + SEPARATING_HYPERPLANE_SET_0) THEN + ASM_SIMP_TAC[CONVEX_DIFFERENCES] THEN ANTS_TAC THENL + [REWRITE_TAC[IN_ELIM_THM] THEN ONCE_REWRITE_TAC[EQ_SYM_EQ] THEN + REWRITE_TAC[VECTOR_SUB_EQ] THEN + ASM_MESON_TAC[DISJOINT; NOT_IN_EMPTY; IN_INTER; EXTENSION]; + ALL_TAC] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `a:real^N` THEN + SIMP_TAC[IN_ELIM_THM; LEFT_IMP_EXISTS_THM] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + GEN_REWRITE_TAC LAND_CONV [SWAP_FORALL_THM] THEN + GEN_REWRITE_TAC (LAND_CONV o BINDER_CONV) [SWAP_FORALL_THM] THEN + ONCE_REWRITE_TAC[IMP_CONJ] THEN REWRITE_TAC[RIGHT_FORALL_IMP_THM] THEN + REWRITE_TAC[LEFT_FORALL_IMP_THM; EXISTS_REFL; DOT_RSUB; REAL_SUB_LE] THEN + DISCH_TAC THEN + MP_TAC(SPEC `IMAGE (\x:real^N. a dot x) s` SUP) THEN + ABBREV_TAC `k = sup (IMAGE (\x:real^N. a dot x) s)` THEN + ASM_REWRITE_TAC[FORALL_IN_IMAGE; IMAGE_EQ_EMPTY; real_ge] THEN ANTS_TAC THENL + [ASM_MESON_TAC[MEMBER_NOT_EMPTY]; ASM_MESON_TAC[]]);; + +(* ------------------------------------------------------------------------- *) +(* More convexity generalities. *) +(* ------------------------------------------------------------------------- *) + +let CONVEX_CLOSURE = prove + (`!s:real^N->bool. convex s ==> convex(closure s)`, + REWRITE_TAC[convex; CLOSURE_SEQUENTIAL] THEN + GEN_TAC THEN DISCH_TAC THEN + MAP_EVERY X_GEN_TAC [`x:real^N`; `y:real^N`; `u:real`; `v:real`] THEN + DISCH_THEN(CONJUNCTS_THEN2 (X_CHOOSE_TAC `a:num->real^N`) MP_TAC) THEN + DISCH_THEN(CONJUNCTS_THEN2 (X_CHOOSE_TAC `b:num->real^N`) MP_TAC) THEN + STRIP_TAC THEN EXISTS_TAC `\n:num. u % a(n) + v % b(n) :real^N` THEN + ASM_SIMP_TAC[LIM_ADD; LIM_CMUL]);; + +let CONVEX_INTERIOR = prove + (`!s:real^N->bool. convex s ==> convex(interior s)`, + REWRITE_TAC[CONVEX_ALT; IN_INTERIOR; SUBSET; IN_BALL; dist] THEN + REPEAT GEN_TAC THEN STRIP_TAC THEN REPEAT GEN_TAC THEN + DISCH_THEN(CONJUNCTS_THEN2 (X_CHOOSE_TAC `d:real`) MP_TAC) THEN + DISCH_THEN(CONJUNCTS_THEN2 (X_CHOOSE_TAC `e:real`) STRIP_ASSUME_TAC) THEN + EXISTS_TAC `min d e` THEN ASM_REWRITE_TAC[REAL_LT_MIN] THEN + X_GEN_TAC `z:real^N` THEN STRIP_TAC THEN + SUBST1_TAC(VECTOR_ARITH `z:real^N = + (&1 - u) % (z - u % (y - x)) + u % (z + (&1 - u) % (y - x))`) THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[] THEN + ASM_MESON_TAC[VECTOR_ARITH `x - (z - u % (y - x)) = + ((&1 - u) % x + u % y) - z:real^N`; + VECTOR_ARITH `y - (z + (&1 - u) % (y - x)) = + ((&1 - u) % x + u % y) - z:real^N`]);; + +(* ------------------------------------------------------------------------- *) +(* Moving and scaling convex hulls. *) +(* ------------------------------------------------------------------------- *) + +let CONVEX_HULL_TRANSLATION = prove + (`!a:real^N s. + convex hull (IMAGE (\x. a + x) s) = IMAGE (\x. a + x) (convex hull s)`, + REPEAT GEN_TAC THEN MATCH_MP_TAC HULL_IMAGE THEN + REWRITE_TAC[CONVEX_TRANSLATION_EQ; CONVEX_CONVEX_HULL] THEN + REWRITE_TAC[VECTOR_ARITH `a + x:real^N = y <=> x = y - a`; EXISTS_REFL] THEN + VECTOR_ARITH_TAC);; + +add_translation_invariants [CONVEX_HULL_TRANSLATION];; + +let CONVEX_HULL_SCALING = prove + (`!s:real^N->bool c. + convex hull (IMAGE (\x. c % x) s) = IMAGE (\x. c % x) (convex hull s)`, + REPEAT GEN_TAC THEN ASM_CASES_TAC `c = &0` THENL + [ASM_SIMP_TAC[IMAGE_CONST; VECTOR_MUL_LZERO; CONVEX_HULL_EQ_EMPTY] THEN + COND_CASES_TAC THEN REWRITE_TAC[CONVEX_HULL_EMPTY; CONVEX_HULL_SING]; + ALL_TAC] THEN + MATCH_MP_TAC HULL_IMAGE THEN + ASM_SIMP_TAC[CONVEX_SCALING_EQ; CONVEX_CONVEX_HULL] THEN + REWRITE_TAC[VECTOR_ARITH `c % x = c % y <=> c % (x - y) = vec 0`] THEN + ASM_SIMP_TAC[VECTOR_MUL_EQ_0; VECTOR_SUB_EQ] THEN + X_GEN_TAC `x:real^N` THEN EXISTS_TAC `inv c % x:real^N` THEN + ASM_SIMP_TAC[VECTOR_MUL_ASSOC; REAL_MUL_RINV; VECTOR_MUL_LID]);; + +let CONVEX_HULL_AFFINITY = prove + (`!s a:real^N c. + convex hull (IMAGE (\x. a + c % x) s) = + IMAGE (\x. a + c % x) (convex hull s)`, + REPEAT GEN_TAC THEN + SUBGOAL_THEN `(\x:real^N. a + c % x) = (\x. a + x) o (\x. c % x)` + SUBST1_TAC THENL [REWRITE_TAC[o_DEF]; ALL_TAC] THEN + ASM_SIMP_TAC[IMAGE_o; CONVEX_HULL_TRANSLATION; CONVEX_HULL_SCALING]);; + +(* ------------------------------------------------------------------------- *) +(* Convex set as intersection of halfspaces. *) +(* ------------------------------------------------------------------------- *) + +let CONVEX_HALFSPACE_INTERSECTION = prove + (`!s. closed(s:real^N->bool) /\ convex s + ==> s = INTERS {h | s SUBSET h /\ ?a b. h = {x | a dot x <= b}}`, + REPEAT STRIP_TAC THEN + GEN_REWRITE_TAC I [EXTENSION] THEN REWRITE_TAC[IN_INTERS] THEN + X_GEN_TAC `x:real^N` THEN REWRITE_TAC[IN_ELIM_THM] THEN + REWRITE_TAC[MESON[] `(!t. (P t /\ ?a b. t = x a b) ==> Q t) <=> + (!a b. P(x a b) ==> Q(x a b))`] THEN + EQ_TAC THENL [SET_TAC[]; ALL_TAC] THEN STRIP_TAC THEN + MATCH_MP_TAC(TAUT `(~p ==> F) ==> p`) THEN DISCH_TAC THEN + MP_TAC(ISPECL [`s:real^N->bool`; `x:real^N`] + SEPARATING_HYPERPLANE_CLOSED_POINT) THEN + ASM_REWRITE_TAC[NOT_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`a:real^N`; `b:real`] THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`--a:real^N`; `--b:real`]) THEN + ASM_SIMP_TAC[SUBSET; IN_ELIM_THM; DOT_LNEG; NOT_IMP] THEN + ASM_SIMP_TAC[REAL_LE_NEG2; REAL_LT_NEG2; REAL_NOT_LE; + REAL_ARITH `a > b ==> b <= a`]);; + +(* ------------------------------------------------------------------------- *) +(* Radon's theorem (from Lars Schewe). *) +(* ------------------------------------------------------------------------- *) + +let RADON_EX_LEMMA = prove + (`!(c:real^N->bool). + FINITE c /\ affine_dependent c + ==> (?u. sum c u = &0 /\ (?v. v IN c /\ ~(u v = &0)) /\ + vsum c (\v. u v % v) = (vec 0):real^N)`, + REWRITE_TAC[AFFINE_DEPENDENT_EXPLICIT] THEN + REPEAT STRIP_TAC THEN + EXISTS_TAC `\v:real^N. if v IN s then u v else &0` THEN + ASM_SIMP_TAC[GSYM SUM_RESTRICT_SET] THEN + ASM_SIMP_TAC[COND_RAND;COND_RATOR; + VECTOR_MUL_LZERO;GSYM VSUM_RESTRICT_SET] THEN + ASM_SIMP_TAC[SET_RULE `s SUBSET c ==> {x | x IN c /\ x IN s} = s`] THEN + EXISTS_TAC `v:real^N` THEN + ASM_REWRITE_TAC[] THEN ASM SET_TAC[]);; + +let RADON_S_LEMMA = prove + (`!(s:A->bool) f. + FINITE s /\ sum s f = &0 + ==> sum {x | x IN s /\ &0 < f x} f = + -- sum {x | x IN s /\ f x < &0} f`, + REWRITE_TAC[REAL_ARITH `a = --b <=> a + b = &0`] THEN + REPEAT STRIP_TAC THEN + ASM_SIMP_TAC[FINITE_RESTRICT;GSYM SUM_UNION; + REWRITE_RULE [REAL_ARITH `&0 < f x ==> ~(f x < &0)`] + (SET_RULE `(!x:A. &0 < f x ==> ~(f x < &0)) + ==> DISJOINT {x | x IN s /\ &0 < f x} + {x | x IN s /\ f x < &0}`)] THEN + MATCH_MP_TAC (REAL_ARITH `!a b.a = &0 /\ a + b = &0 ==> b = &0`) THEN + EXISTS_TAC `sum {x:A | x IN s /\ f x = &0} f` THEN + CONJ_TAC THENL + [ASM_SIMP_TAC[SUM_RESTRICT_SET] THEN REWRITE_TAC[COND_ID;SUM_0]; + ALL_TAC] THEN + SUBGOAL_THEN `DISJOINT {x:A | x IN s /\ f x = &0} + ({x | x IN s /\ &0 < f x} UNION + {x | x IN s /\ f x < &0})` ASSUME_TAC THENL + [REWRITE_TAC[DISJOINT;UNION;INTER;IN_ELIM_THM;EXTENSION;NOT_IN_EMPTY] THEN + REAL_ARITH_TAC; + ALL_TAC] THEN + ASM_SIMP_TAC[FINITE_UNION;FINITE_RESTRICT;GSYM SUM_UNION] THEN + FIRST_X_ASSUM (SUBST1_TAC o GSYM) THEN + MATCH_MP_TAC (MESON[] `a = b ==> sum a f = sum b f`) THEN + REWRITE_TAC[EXTENSION;IN_ELIM_THM;UNION] THEN + MESON_TAC[REAL_LT_TOTAL]);; + +let RADON_V_LEMMA = prove + (`!(s:A->bool) f g. + FINITE s /\ vsum s f = vec 0 /\ (!x. g x = &0 ==> f x = vec 0) + ==> (vsum {x | x IN s /\ &0 < g x} f) :real^N = + -- vsum {x | x IN s /\ g x < &0} f`, + REWRITE_TAC[VECTOR_ARITH `a:real^N = --b <=> a + b = vec 0`] THEN + REPEAT STRIP_TAC THEN + ASM_SIMP_TAC[FINITE_RESTRICT;GSYM VSUM_UNION; + REWRITE_RULE [REAL_ARITH `&0 < f x ==> ~(f x < &0)`] + (SET_RULE `(!x:A. &0 < f x ==> ~(f x < &0)) + ==> DISJOINT {x | x IN s /\ &0 < f x} + {x | x IN s /\ f x < &0}`)] THEN + MATCH_MP_TAC (VECTOR_ARITH + `!a b. (a:real^N) = vec 0 /\ a + b = vec 0 ==> b = vec 0`) THEN + EXISTS_TAC `(vsum {x:A | x IN s /\ g x = &0} f):real^N` THEN + CONJ_TAC THENL + [ASM_SIMP_TAC[VSUM_RESTRICT_SET;COND_ID;VSUM_0];ALL_TAC] THEN + SUBGOAL_THEN `DISJOINT {x:A | x IN s /\ g x = &0} + ({x | x IN s /\ &0 < g x} UNION + {x | x IN s /\ g x < &0})` ASSUME_TAC THENL + [REWRITE_TAC[DISJOINT;UNION;INTER;IN_ELIM_THM;EXTENSION;NOT_IN_EMPTY] THEN + REAL_ARITH_TAC; + ALL_TAC] THEN + ASM_SIMP_TAC[FINITE_UNION;FINITE_RESTRICT;GSYM VSUM_UNION] THEN + FIRST_X_ASSUM (SUBST1_TAC o GSYM) THEN + MATCH_MP_TAC (MESON[] `a = b ==> vsum a f = vsum b f`) THEN + REWRITE_TAC[EXTENSION;IN_ELIM_THM;UNION] THEN + MESON_TAC[REAL_LT_TOTAL]);; + +let RADON_PARTITION = prove + (`!(c:real^N->bool). + FINITE c /\ affine_dependent c + ==> ?(m:real^N->bool) (p:real^N->bool). + (DISJOINT m p) /\ + (m UNION p = c) /\ + ~(DISJOINT (convex hull m) (convex hull p))`, + REPEAT STRIP_TAC THEN + MP_TAC (ISPEC `c:real^N->bool` RADON_EX_LEMMA) THEN + ASM_REWRITE_TAC[] THEN + REPEAT STRIP_TAC THEN + MAP_EVERY EXISTS_TAC [`{v:real^N | v IN c /\ u v <= &0}`; + `{v:real^N | v IN c /\ u v > &0}`] THEN + REPEAT CONJ_TAC THENL + [REWRITE_TAC[DISJOINT;INTER; + IN_ELIM_THM;REAL_ARITH `x <= &0 <=> ~(x > &0)`] THEN + SET_TAC[]; + REWRITE_TAC[UNION;IN_ELIM_THM;REAL_ARITH `x <= &0 <=> ~(x > &0)`] THEN + SET_TAC[]; + ALL_TAC] THEN + SUBGOAL_THEN `~(sum {x:real^N | x IN c /\ u x > &0} u = &0)` ASSUME_TAC THENL + [MATCH_MP_TAC (REAL_ARITH `a > &0 ==> ~(a = &0)`) THEN + REWRITE_TAC[REAL_ARITH `a > &0 <=> &0 < a`] THEN + MATCH_MP_TAC (REWRITE_RULE[SUM_0] (ISPEC `\x. &0` SUM_LT_ALL)) THEN + ASM_SIMP_TAC[FINITE_RESTRICT;IN_ELIM_THM;EXTENSION;NOT_IN_EMPTY] THEN + REWRITE_TAC[MESON[]`~(!x. ~(P x /\ Q x)) = ?x. P x /\ Q x`] THEN + ASM_CASES_TAC `&0 < u (v:real^N)` THENL + [ASM SET_TAC[];ALL_TAC] THEN + POP_ASSUM MP_TAC THEN POP_ASSUM (K ALL_TAC) THEN POP_ASSUM MP_TAC THEN + REWRITE_TAC[IMP_IMP;REAL_ARITH `~(a = &0) /\ ~(&0 < a) <=> a < &0`] THEN + DISCH_TAC THEN + REWRITE_TAC[MESON[REAL_NOT_LT] + `(?x:real^N. P x /\ &0 < u x) <=> (!x. P x ==> u x <= &0) ==> F`] THEN + DISCH_TAC THEN + MP_TAC (ISPECL [`u:real^N->real`;`\x:real^N. &0`;`c:real^N->bool`] + SUM_LT) THEN + ASM_REWRITE_TAC[SUM_0;REAL_ARITH `~(&0 < &0)`] THEN + ASM_MESON_TAC[];ALL_TAC] THEN + REWRITE_TAC[SET_RULE `~DISJOINT a b <=> ?y. y IN a /\ y IN b`] THEN + EXISTS_TAC `&1 / (sum {x:real^N | x IN c /\ u x > &0} u) % + vsum {x:real^N | x IN c /\ u x > &0} (\x. u x % x)` THEN + REWRITE_TAC[CONVEX_HULL_EXPLICIT;IN_ELIM_THM] THEN + CONJ_TAC THENL + [MAP_EVERY EXISTS_TAC [`{v:real^N | v IN c /\ u v < &0}`; + `\y:real^N. + &1 / (sum {x:real^N | x IN c /\ u x > &0} u) * + (--(u y))`] THEN + ASM_SIMP_TAC[FINITE_RESTRICT;SUBSET;IN_ELIM_THM] THEN + REPEAT CONJ_TAC THENL + [REAL_ARITH_TAC; + REPEAT STRIP_TAC THEN + MATCH_MP_TAC REAL_LE_MUL THEN + CONJ_TAC THENL [ALL_TAC; + ASM_REWRITE_TAC[REAL_NEG_GE0;REAL_LE_LT]] THEN + MATCH_MP_TAC REAL_LE_DIV THEN + REWRITE_TAC[REAL_LE_01] THEN + MATCH_MP_TAC SUM_POS_LE THEN + ASM_SIMP_TAC[FINITE_RESTRICT;IN_ELIM_THM] THEN + REAL_ARITH_TAC; + ASM_SIMP_TAC[FINITE_RESTRICT;SUM_LMUL] THEN + MATCH_MP_TAC (REAL_FIELD `!a. ~(a = &0) /\ a * b = a * c ==> b = c`) THEN + EXISTS_TAC `sum {x:real^N | x IN c /\ u x > &0} u` THEN + REWRITE_TAC[SUM_LMUL] THEN + ASM_SIMP_TAC[REAL_FIELD `~(a = &0) ==> a * &1 / a * b = b`] THEN + REWRITE_TAC[SUM_NEG;REAL_MUL_RID] THEN + REWRITE_TAC[REAL_ARITH `a > &0 <=> &0 < a`] THEN + MATCH_MP_TAC (GSYM RADON_S_LEMMA) THEN + ASM_REWRITE_TAC[]; + ALL_TAC] THEN + REWRITE_TAC[GSYM VECTOR_MUL_ASSOC;VSUM_LMUL;VECTOR_MUL_LCANCEL] THEN + REWRITE_TAC[VECTOR_MUL_LNEG;VSUM_NEG] THEN + DISJ2_TAC THEN + MATCH_MP_TAC (REWRITE_RULE[REAL_ARITH `&0 < a <=> a > &0`] + (GSYM RADON_V_LEMMA)) THEN + ASM_REWRITE_TAC[] THEN + MESON_TAC[VECTOR_MUL_LZERO];ALL_TAC] THEN + MAP_EVERY EXISTS_TAC [`{v:real^N | v IN c /\ u v > &0}`; + `\y:real^N. + &1 / (sum {x:real^N | x IN c /\ u x > &0} u) * + (u y)`] THEN + ASM_SIMP_TAC[FINITE_RESTRICT;SUBSET;IN_ELIM_THM] THEN + REPEAT CONJ_TAC THENL + [REPEAT STRIP_TAC THEN + MATCH_MP_TAC REAL_LE_MUL THEN + CONJ_TAC THENL [ALL_TAC; + ASM_SIMP_TAC[REAL_ARITH `a > &0 ==> &0 <= a`]] THEN + MATCH_MP_TAC REAL_LE_DIV THEN + REWRITE_TAC[REAL_LE_01] THEN + MATCH_MP_TAC SUM_POS_LE THEN + ASM_SIMP_TAC[FINITE_RESTRICT;IN_ELIM_THM] THEN + REAL_ARITH_TAC; + ASM_SIMP_TAC[FINITE_RESTRICT;SUM_LMUL] THEN + MATCH_MP_TAC (REAL_FIELD `!a. ~(a = &0) /\ a * b = a * c ==> b = c`) THEN + EXISTS_TAC `sum {x:real^N | x IN c /\ u x > &0} u` THEN + REWRITE_TAC[SUM_LMUL] THEN + ASM_SIMP_TAC[REAL_FIELD `~(a = &0) ==> a * &1 / a * b = b`] THEN + REWRITE_TAC[SUM_NEG;REAL_MUL_RID] THEN + REWRITE_TAC[REAL_ARITH `a > &0 <=> &0 < a`] THEN + MATCH_MP_TAC (GSYM RADON_S_LEMMA) THEN + ASM_REWRITE_TAC[]; + ALL_TAC] THEN + REWRITE_TAC[GSYM VECTOR_MUL_ASSOC;VSUM_LMUL;VECTOR_MUL_LCANCEL] THEN + REWRITE_TAC[VECTOR_MUL_LNEG;VSUM_NEG] THEN + DISJ2_TAC THEN + MATCH_MP_TAC (REWRITE_RULE[REAL_ARITH `&0 < a <=> a > &0`] + (GSYM RADON_V_LEMMA)) THEN + ASM_REWRITE_TAC[] THEN + MESON_TAC[VECTOR_MUL_LZERO]);; + +let RADON = prove + (`!(c:real^N->bool). + affine_dependent c + ==> ?(m:real^N->bool) (p:real^N->bool). + m SUBSET c /\ + p SUBSET c /\ + DISJOINT m p /\ + ~(DISJOINT (convex hull m) (convex hull p))`, + REPEAT STRIP_TAC THEN MP_TAC + (ISPEC `c:real^N->bool` AFFINE_DEPENDENT_EXPLICIT) THEN + ASM_SIMP_TAC[] THEN REPEAT STRIP_TAC THEN MP_TAC + (ISPEC `s:real^N->bool` RADON_PARTITION) THEN + ANTS_TAC THENL + [ASM_SIMP_TAC[AFFINE_DEPENDENT_EXPLICIT] THEN + MAP_EVERY EXISTS_TAC [`s:real^N->bool`;`u:real^N->real`] THEN + ASM SET_TAC[];ALL_TAC] THEN + DISCH_THEN STRIP_ASSUME_TAC THEN + MAP_EVERY EXISTS_TAC [`m:real^N->bool`;`p:real^N->bool`] THEN + ASM SET_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* Helly's theorem. *) +(* ------------------------------------------------------------------------- *) + +let HELLY_INDUCT = prove + (`!n f. f HAS_SIZE n /\ n >= dimindex(:N) + 1 /\ + (!s:real^N->bool. s IN f ==> convex s) /\ + (!t. t SUBSET f /\ CARD(t) = dimindex(:N) + 1 + ==> ~(INTERS t = {})) + ==> ~(INTERS f = {})`, + INDUCT_TAC THEN REWRITE_TAC[ARITH_RULE `~(0 >= n + 1)`] THEN GEN_TAC THEN + POP_ASSUM(LABEL_TAC "*") THEN STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [HAS_SIZE_SUC]) THEN + STRIP_TAC THEN RULE_ASSUM_TAC(REWRITE_RULE[HAS_SIZE]) THEN + FIRST_X_ASSUM(DISJ_CASES_TAC o MATCH_MP (ARITH_RULE + `SUC n >= m + 1 ==> m = n \/ n >= m + 1`)) + THENL + [FIRST_X_ASSUM MATCH_MP_TAC THEN RULE_ASSUM_TAC(REWRITE_RULE[HAS_SIZE]) THEN + ASM_SIMP_TAC[CARD_CLAUSES; SUBSET_REFL] THEN ARITH_TAC; + ALL_TAC] THEN + SUBGOAL_THEN + `?X. !s:real^N->bool. s IN f ==> X(s) IN INTERS (f DELETE s)` + STRIP_ASSUME_TAC THENL + [REWRITE_TAC[GSYM SKOLEM_THM; MEMBER_NOT_EMPTY; RIGHT_EXISTS_IMP_THM] THEN + GEN_TAC THEN STRIP_TAC THEN REMOVE_THEN "*" MATCH_MP_TAC THEN + ASM_SIMP_TAC[FINITE_DELETE; CARD_DELETE] THEN ASM SET_TAC[]; + ALL_TAC] THEN + ASM_CASES_TAC + `?s t:real^N->bool. s IN f /\ t IN f /\ ~(s = t) /\ X s:real^N = X t` + THENL + [FIRST_X_ASSUM(CHOOSE_THEN STRIP_ASSUME_TAC) THEN + REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN + EXISTS_TAC `(X:(real^N->bool)->real^N) t` THEN + FIRST_X_ASSUM(fun th -> GEN_REWRITE_TAC ONCE_DEPTH_CONV + [MATCH_MP + (SET_RULE`~(s = t) + ==> INTERS f = INTERS(f DELETE s) INTER INTERS(f DELETE t)`) + th]) THEN + REWRITE_TAC[IN_INTER] THEN ASM_MESON_TAC[]; + ALL_TAC] THEN + MP_TAC(ISPEC `IMAGE (X:(real^N->bool)->real^N) f` RADON_PARTITION) THEN + ANTS_TAC THENL + [ASM_SIMP_TAC[FINITE_IMAGE] THEN + MATCH_MP_TAC AFFINE_DEPENDENT_BIGGERSET THEN + ASM_SIMP_TAC[FINITE_IMAGE] THEN + MATCH_MP_TAC(ARITH_RULE + `!f n. n >= d + 1 /\ f = SUC n /\ c = f ==> c >= d + 2`) THEN + MAP_EVERY EXISTS_TAC [`CARD(f:(real^N->bool)->bool)`; `n:num`] THEN + REPEAT(CONJ_TAC THENL [ASM_MESON_TAC[]; ALL_TAC]) THEN + MATCH_MP_TAC CARD_IMAGE_INJ THEN ASM_MESON_TAC[]; + ALL_TAC] THEN + ONCE_REWRITE_TAC[SET_RULE + `P /\ m UNION p = s /\ Q <=> + m SUBSET s /\ p SUBSET s /\ m UNION p = s /\ P /\ Q`] THEN + REWRITE_TAC[SUBSET_IMAGE; DISJOINT] THEN + REWRITE_TAC[MESON[] + `(?m p. (?u. P u /\ m = t u) /\ (?u. P u /\ p = t u) /\ Q m p) ==> r <=> + (!u v. P u /\ P v /\ Q (t u) (t v) ==> r)`] THEN + MAP_EVERY X_GEN_TAC [`g:(real^N->bool)->bool`; `h:(real^N->bool)->bool`] THEN + REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + SUBGOAL_THEN `(f:(real^N->bool)->bool) = h UNION g` SUBST1_TAC THENL + [MATCH_MP_TAC SUBSET_ANTISYM THEN ASM_REWRITE_TAC[UNION_SUBSET] THEN + REWRITE_TAC[SUBSET; IN_UNION] THEN X_GEN_TAC `s:real^N->bool` THEN + DISCH_THEN(fun th -> ASSUME_TAC th THEN MP_TAC th) THEN + DISCH_THEN(MP_TAC o ISPEC `X:(real^N->bool)->real^N` o + MATCH_MP FUN_IN_IMAGE) THEN + FIRST_X_ASSUM(fun th -> + GEN_REWRITE_TAC (LAND_CONV o RAND_CONV) [GSYM th]) THEN + ONCE_REWRITE_TAC[DISJ_SYM] THEN REWRITE_TAC[IN_UNION; IN_IMAGE] THEN + MATCH_MP_TAC MONO_OR THEN ASM_MESON_TAC[SUBSET]; + ALL_TAC] THEN + MATCH_MP_TAC(SET_RULE + `g SUBSET INTERS g' /\ h SUBSET INTERS h' + ==> ~(g INTER h = {}) ==> ~(INTERS(g' UNION h') = {})`) THEN + FIRST_X_ASSUM(ASSUME_TAC o MATCH_MP (SET_RULE + `IMAGE X s INTER IMAGE X t = {} ==> s INTER t = {}`)) THEN + CONJ_TAC THEN MATCH_MP_TAC HULL_MINIMAL THEN + (CONJ_TAC THENL [ALL_TAC; ASM_MESON_TAC[SUBSET; CONVEX_INTERS]]) THEN + REWRITE_TAC[SUBSET; IN_INTERS; FORALL_IN_IMAGE] THEN ASM SET_TAC[]);; + +let HELLY = prove + (`!f:(real^N->bool)->bool. + FINITE f /\ CARD(f) >= dimindex(:N) + 1 /\ + (!s. s IN f ==> convex s) /\ + (!t. t SUBSET f /\ CARD(t) = dimindex(:N) + 1 ==> ~(INTERS t = {})) + ==> ~(INTERS f = {})`, + GEN_TAC THEN DISCH_TAC THEN MATCH_MP_TAC HELLY_INDUCT THEN + ASM_REWRITE_TAC[HAS_SIZE] THEN ASM_MESON_TAC[]);; + +let HELLY_ALT = prove + (`!f:(real^N->bool)->bool. + FINITE f /\ + (!s. s IN f ==> convex s) /\ + (!t. t SUBSET f /\ CARD(t) <= dimindex(:N) + 1 ==> ~(INTERS t = {})) + ==> ~(INTERS f = {})`, + GEN_TAC THEN STRIP_TAC THEN + ASM_CASES_TAC `CARD(f:(real^N->bool)->bool) < dimindex(:N) + 1` THEN + ASM_SIMP_TAC[SUBSET_REFL; LT_IMP_LE] THEN MATCH_MP_TAC HELLY THEN + ASM_SIMP_TAC[GE; GSYM NOT_LT] THEN ASM_MESON_TAC[LE_REFL]);; + +let HELLY_CLOSED_ALT = prove + (`!f:(real^N->bool)->bool. + (!s. s IN f ==> convex s /\ closed s) /\ (?s. s IN f /\ bounded s) /\ + (!t. t SUBSET f /\ FINITE t /\ CARD(t) <= dimindex(:N) + 1 + ==> ~(INTERS t = {})) + ==> ~(INTERS f = {})`, + GEN_TAC THEN + DISCH_THEN(REPEAT_TCL CONJUNCTS_THEN ASSUME_TAC) THEN + MATCH_MP_TAC CLOSED_FIP THEN ASM_SIMP_TAC[] THEN + X_GEN_TAC `g:(real^N->bool)->bool` THEN STRIP_TAC THEN + MATCH_MP_TAC HELLY_ALT THEN ASM_REWRITE_TAC[] THEN CONJ_TAC THENL + [ASM SET_TAC[]; + ASM_MESON_TAC[SUBSET_TRANS; FINITE_SUBSET]]);; + +let HELLY_COMPACT_ALT = prove + (`!f:(real^N->bool)->bool. + (!s. s IN f ==> convex s /\ compact s) /\ + (!t. t SUBSET f /\ FINITE t /\ CARD(t) <= dimindex(:N) + 1 + ==> ~(INTERS t = {})) + ==> ~(INTERS f = {})`, + GEN_TAC THEN STRIP_TAC THEN + ASM_CASES_TAC `f:(real^N->bool)->bool = {}` THEN + ASM_REWRITE_TAC[INTERS_0; UNIV_NOT_EMPTY] THEN + MATCH_MP_TAC HELLY_CLOSED_ALT THEN + ASM_SIMP_TAC[COMPACT_IMP_CLOSED] THEN + ASM_MESON_TAC[MEMBER_NOT_EMPTY; COMPACT_IMP_BOUNDED]);; + +let HELLY_CLOSED = prove + (`!f:(real^N->bool)->bool. + (FINITE f ==> CARD f >= dimindex (:N) + 1) /\ + (!s. s IN f ==> convex s /\ closed s) /\ (?s. s IN f /\ bounded s) /\ + (!t. t SUBSET f /\ FINITE t /\ CARD(t) = dimindex(:N) + 1 + ==> ~(INTERS t = {})) + ==> ~(INTERS f = {})`, + GEN_TAC THEN REWRITE_TAC[GE] THEN + DISCH_THEN(REPEAT_TCL CONJUNCTS_THEN ASSUME_TAC) THEN + MATCH_MP_TAC HELLY_CLOSED_ALT THEN ASM_REWRITE_TAC[] THEN + X_GEN_TAC `g:(real^N->bool)->bool` THEN STRIP_TAC THEN + MP_TAC(ISPECL [`dimindex(:N) + 1`; `g:(real^N->bool)->bool`; + `f:(real^N->bool)->bool`] CHOOSE_SUBSET_BETWEEN) THEN + ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `h:(real^N->bool)->bool` STRIP_ASSUME_TAC) THEN + MATCH_MP_TAC(SET_RULE `!s. s SUBSET t /\ ~(s = {}) ==> ~(t = {})`) THEN + EXISTS_TAC `INTERS h: real^N->bool` THEN + CONJ_TAC THENL [ASM SET_TAC[]; FIRST_X_ASSUM MATCH_MP_TAC] THEN + ASM_MESON_TAC[HAS_SIZE]);; + +let HELLY_COMPACT = prove + (`!f:(real^N->bool)->bool. + (FINITE f ==> CARD f >= dimindex (:N) + 1) /\ + (!s. s IN f ==> convex s /\ compact s) /\ + (!t. t SUBSET f /\ FINITE t /\ CARD(t) = dimindex(:N) + 1 + ==> ~(INTERS t = {})) + ==> ~(INTERS f = {})`, + GEN_TAC THEN STRIP_TAC THEN + ASM_CASES_TAC `f:(real^N->bool)->bool = {}` THEN + ASM_REWRITE_TAC[INTERS_0; UNIV_NOT_EMPTY] THEN + MATCH_MP_TAC HELLY_CLOSED THEN + ASM_SIMP_TAC[COMPACT_IMP_CLOSED] THEN + ASM_MESON_TAC[MEMBER_NOT_EMPTY; COMPACT_IMP_BOUNDED]);; + +(* ------------------------------------------------------------------------- *) +(* Kirchberger's theorem *) +(* ------------------------------------------------------------------------- *) + +let KIRCHBERGER = prove + (`!s t:real^N->bool. + compact s /\ compact t /\ + (!s' t'. s' SUBSET s /\ t' SUBSET t /\ FINITE s' /\ FINITE t' /\ + CARD(s') + CARD(t') <= dimindex(:N) + 2 + ==> ?a b. (!x. x IN s' ==> a dot x < b) /\ + (!x. x IN t' ==> a dot x > b)) + ==> ?a b. ~(a = vec 0) /\ + (!x. x IN s ==> a dot x < b) /\ + (!x. x IN t ==> a dot x > b)`, + let lemma = prove + (`(!x. x IN convex hull s ==> a dot x < b) /\ + (!x. x IN convex hull t ==> a dot x > b) <=> + (!x. x IN s ==> a dot x < b) /\ (!x. x IN t ==> a dot x > b)`, + REWRITE_TAC[SET_RULE `(!x. x IN s ==> P x) <=> s SUBSET {x | P x}`] THEN + SIMP_TAC[SUBSET_HULL; CONVEX_HALFSPACE_LT; CONVEX_HALFSPACE_GT]) + and KIRCH_LEMMA = prove + (`!s t:real^N->bool. + FINITE s /\ FINITE t /\ + (!s' t'. s' SUBSET s /\ t' SUBSET t /\ + CARD(s') + CARD(t') <= dimindex(:N) + 2 + ==> ?a b. (!x. x IN s' ==> a dot x < b) /\ + (!x. x IN t' ==> a dot x > b)) + ==> ?a b. (!x. x IN s ==> a dot x < b) /\ + (!x. x IN t ==> a dot x > b)`, + REPEAT STRIP_TAC THEN MP_TAC(ISPECL + [`IMAGE (\r. {z:real^(N,1)finite_sum | + fstcart z dot r < drop(sndcart z)}) s UNION + IMAGE (\r. {z:real^(N,1)finite_sum | + fstcart z dot r > drop(sndcart z)}) t`] + HELLY_ALT) THEN + REWRITE_TAC[FORALL_SUBSET_UNION; IN_UNION; IMP_CONJ] THEN + REWRITE_TAC[RIGHT_FORALL_IMP_THM; FORALL_SUBSET_IMAGE] THEN + ASM_SIMP_TAC[FINITE_UNION; FINITE_IMAGE; INTERS_UNION] THEN + REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; INTERS_IMAGE; IN_INTER; + EXISTS_PASTECART; IN_ELIM_PASTECART_THM; + FSTCART_PASTECART; SNDCART_PASTECART] THEN + REWRITE_TAC[TAUT `p \/ q ==> r <=> (p ==> r) /\ (q ==> r)`] THEN + REWRITE_TAC[FORALL_AND_THM; FORALL_IN_IMAGE; RIGHT_IMP_FORALL_THM] THEN + REWRITE_TAC[IMP_IMP; GSYM CONJ_ASSOC; GSYM EXISTS_DROP] THEN + DISCH_THEN MATCH_MP_TAC THEN REWRITE_TAC[CONJ_ASSOC] THEN CONJ_TAC THENL + [REWRITE_TAC[REAL_ARITH `a > b <=> --a < --b`; GSYM DOT_RNEG] THEN + REWRITE_TAC[convex; IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_GSPEC] THEN + SIMP_TAC[PASTECART_ADD; GSYM PASTECART_CMUL; IN_ELIM_PASTECART_THM] THEN + SIMP_TAC[DOT_LADD; DOT_LMUL; DROP_ADD; DROP_CMUL; GSYM FORALL_DROP] THEN + REWRITE_TAC[REAL_ARITH `--(a * x + b * y):real = a * --x + b * --y`] THEN + REPEAT STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o MATCH_MP (REAL_ARITH + `u + v = &1 + ==> &0 <= u /\ &0 <= v + ==> u = &0 /\ v = &1 \/ u = &1 /\ v = &0 \/ &0 < u /\ &0 < v`)) THEN + ASM_REWRITE_TAC[] THEN STRIP_TAC THEN + ASM_REWRITE_TAC[REAL_MUL_LZERO; REAL_MUL_LID; + REAL_ADD_LID; REAL_ADD_RID] THEN + MATCH_MP_TAC REAL_LT_ADD2 THEN ASM_SIMP_TAC[REAL_LT_LMUL_EQ]; + REWRITE_TAC[DIMINDEX_FINITE_SUM; DIMINDEX_1; + ARITH_RULE `(n + 1) + 1 = n + 2`] THEN + MAP_EVERY X_GEN_TAC [`u:real^N->bool`; `v:real^N->bool`] THEN + DISCH_THEN(CONJUNCTS_THEN2 STRIP_ASSUME_TAC MP_TAC) THEN + SUBGOAL_THEN `FINITE(u:real^N->bool) /\ FINITE(v:real^N->bool)` + STRIP_ASSUME_TAC THENL [ASM_MESON_TAC[FINITE_SUBSET]; ALL_TAC] THEN + W(MP_TAC o PART_MATCH (lhs o rand) CARD_UNION o lhand o lhand o snd) THEN + ASM_SIMP_TAC[FINITE_IMAGE] THEN ANTS_TAC THENL + [REWRITE_TAC[SET_RULE `IMAGE f s INTER IMAGE g t = {} <=> + !x y. x IN s /\ y IN t ==> ~(f x = g y)`] THEN + MAP_EVERY X_GEN_TAC [`x:real^N`; `y:real^N`] THEN STRIP_TAC THEN + REWRITE_TAC[EXTENSION; FORALL_PASTECART; IN_ELIM_PASTECART_THM] THEN + DISCH_THEN(MP_TAC o SPEC `vec 0:real^N`) THEN + REWRITE_TAC[GSYM FORALL_DROP; DOT_LZERO] THEN + DISCH_THEN(MP_TAC o SPEC `&1`) THEN REAL_ARITH_TAC; + DISCH_THEN SUBST1_TAC] THEN + DISCH_THEN(fun th -> FIRST_X_ASSUM MATCH_MP_TAC THEN MP_TAC th) THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC(ARITH_RULE + `a = a' /\ b = b' ==> a + b <= n + 2 ==> a' + b' <= n + 2`) THEN + CONJ_TAC THEN MATCH_MP_TAC CARD_IMAGE_INJ THEN + ASM_REWRITE_TAC[EXTENSION; FORALL_PASTECART; IN_ELIM_PASTECART_THM] THEN + SIMP_TAC[GSYM FORALL_DROP; real_gt; VECTOR_EQ_LDOT; + MESON[REAL_LT_TOTAL; REAL_LT_REFL] + `((!y:real. a < y <=> b < y) <=> a = b) /\ + ((!y:real. y < a <=> y < b) <=> a = b)`]]) in + REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[GSYM lemma] THEN + MATCH_MP_TAC SEPARATING_HYPERPLANE_COMPACT_COMPACT THEN + ASM_SIMP_TAC[CONVEX_CONVEX_HULL; COMPACT_CONVEX_HULL; + CONVEX_HULL_EQ_EMPTY] THEN + SUBGOAL_THEN + `!s' t'. (s':real^N->bool) SUBSET s /\ t' SUBSET t /\ + FINITE s' /\ CARD(s') <= dimindex(:N) + 1 /\ + FINITE t' /\ CARD(t') <= dimindex(:N) + 1 + ==> DISJOINT (convex hull s') (convex hull t')` + MP_TAC THENL + [REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`s':real^N->bool`; `t':real^N->bool`] KIRCH_LEMMA) THEN + ANTS_TAC THENL + [ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_MESON_TAC[SUBSET; FINITE_SUBSET]; + ONCE_REWRITE_TAC[GSYM lemma] THEN SET_TAC[REAL_LT_ANTISYM; real_gt]]; + POP_ASSUM_LIST(K ALL_TAC) THEN STRIP_TAC THEN + REWRITE_TAC[SET_RULE `DISJOINT s t <=> !x. x IN s /\ x IN t ==> F`] THEN + X_GEN_TAC `x:real^N` THEN ONCE_REWRITE_TAC[CARATHEODORY] THEN + REWRITE_TAC[IN_ELIM_THM] THEN + DISCH_THEN(CONJUNCTS_THEN2 + (X_CHOOSE_THEN `s':real^N->bool` STRIP_ASSUME_TAC) + (X_CHOOSE_THEN `t':real^N->bool` STRIP_ASSUME_TAC)) THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`s':real^N->bool`; `t':real^N->bool`]) THEN + ASM_REWRITE_TAC[] THEN ASM SET_TAC[]]);; + +(* ------------------------------------------------------------------------- *) +(* Convex hull is "preserved" by a linear function. *) +(* ------------------------------------------------------------------------- *) + +let CONVEX_HULL_LINEAR_IMAGE = prove + (`!f s. linear f ==> convex hull (IMAGE f s) = IMAGE f (convex hull s)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE] THEN + CONJ_TAC THEN MATCH_MP_TAC HULL_INDUCT THEN + REWRITE_TAC[FORALL_IN_IMAGE] THEN SIMP_TAC[FUN_IN_IMAGE; HULL_INC] THEN + REWRITE_TAC[convex; IN_ELIM_THM] THEN + REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_IMAGE] THENL + [FIRST_ASSUM(fun th -> REWRITE_TAC[GSYM(MATCH_MP LINEAR_CMUL th)]) THEN + FIRST_ASSUM(fun th -> REWRITE_TAC[GSYM(MATCH_MP LINEAR_ADD th)]) THEN + REWRITE_TAC[IN_IMAGE] THEN + MESON_TAC[REWRITE_RULE[convex] CONVEX_CONVEX_HULL]; + ASM_SIMP_TAC[LINEAR_ADD; LINEAR_CMUL] THEN + MESON_TAC[REWRITE_RULE[convex] CONVEX_CONVEX_HULL]]);; + +add_linear_invariants [CONVEX_HULL_LINEAR_IMAGE];; + +let IN_CONVEX_HULL_LINEAR_IMAGE = prove + (`!f:real^M->real^N s x. + linear f /\ x IN convex hull s ==> (f x) IN convex hull (IMAGE f s)`, + SIMP_TAC[CONVEX_HULL_LINEAR_IMAGE] THEN SET_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* Convexity of general and special intervals. *) +(* ------------------------------------------------------------------------- *) + +let IS_INTERVAL_CONVEX = prove + (`!s:real^N->bool. is_interval s ==> convex s`, + REWRITE_TAC[is_interval; convex] THEN + REPEAT STRIP_TAC THEN FIRST_ASSUM MATCH_MP_TAC THEN + MAP_EVERY EXISTS_TAC [`x:real^N`; `y:real^N`] THEN + ASM_SIMP_TAC[VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT] THEN + GEN_TAC THEN STRIP_TAC THEN + DISJ_CASES_TAC(SPECL [`(x:real^N)$i`; `(y:real^N)$i`] REAL_LE_TOTAL) THENL + [DISJ1_TAC; DISJ2_TAC] THEN + MATCH_MP_TAC(REAL_ARITH + `&1 * a <= b /\ b <= &1 * c ==> a <= b /\ b <= c`) THEN + FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN + ASM_SIMP_TAC[GSYM VECTOR_MUL_COMPONENT; + VECTOR_ADD_RDISTRIB; VECTOR_ADD_COMPONENT] THEN + ASM_SIMP_TAC[VECTOR_MUL_COMPONENT; REAL_LE_LMUL; + REAL_LE_LADD; REAL_LE_RADD]);; + +let IS_INTERVAL_CONNECTED = prove + (`!s:real^N->bool. is_interval s ==> connected s`, + MESON_TAC[IS_INTERVAL_CONVEX; CONVEX_CONNECTED]);; + +let IS_INTERVAL_CONNECTED_1 = prove + (`!s:real^1->bool. is_interval s <=> connected s`, + GEN_TAC THEN EQ_TAC THEN REWRITE_TAC[IS_INTERVAL_CONNECTED] THEN + ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN + REWRITE_TAC[IS_INTERVAL_1; connected; NOT_FORALL_THM; LEFT_IMP_EXISTS_THM; + NOT_IMP; FORALL_LIFT; LIFT_DROP] THEN + MAP_EVERY X_GEN_TAC [`a:real`; `b:real`; `x:real`] THEN STRIP_TAC THEN + MAP_EVERY EXISTS_TAC + [`{z:real^1 | basis 1 dot z < x}`; `{z:real^1 | basis 1 dot z > x}`] THEN + REWRITE_TAC[OPEN_HALFSPACE_LT; OPEN_HALFSPACE_GT] THEN + SIMP_TAC[SUBSET; EXTENSION; IN_UNION; IN_INTER; GSYM drop; NOT_FORALL_THM; + real_gt; NOT_IN_EMPTY; IN_ELIM_THM; DOT_BASIS; DIMINDEX_1; ARITH] THEN + REPEAT CONJ_TAC THENL + [ASM_MESON_TAC[REAL_LT_TOTAL; LIFT_DROP]; + REAL_ARITH_TAC; + EXISTS_TAC `lift a`; + EXISTS_TAC `lift b`] THEN + ASM_REWRITE_TAC[REAL_LT_LE; LIFT_DROP] THEN ASM_MESON_TAC[]);; + +let CONVEX_INTERVAL = prove + (`!a b:real^N. convex(interval [a,b]) /\ convex(interval (a,b))`, + SIMP_TAC[IS_INTERVAL_CONVEX; IS_INTERVAL_INTERVAL]);; + +let CONNECTED_INTERVAL = prove + (`(!a b:real^N. connected(interval[a,b])) /\ + (!a b:real^N. connected(interval(a,b)))`, + SIMP_TAC[CONVEX_CONNECTED; CONVEX_INTERVAL]);; + +(* ------------------------------------------------------------------------- *) +(* On real^1, is_interval, convex and connected are all equivalent. *) +(* ------------------------------------------------------------------------- *) + +let IS_INTERVAL_CONVEX_1 = prove + (`!s:real^1->bool. is_interval s <=> convex s`, + MESON_TAC[IS_INTERVAL_CONVEX; CONVEX_CONNECTED; IS_INTERVAL_CONNECTED_1]);; + +let CONVEX_CONNECTED_1 = prove + (`!s:real^1->bool. convex s <=> connected s`, + REWRITE_TAC[GSYM IS_INTERVAL_CONVEX_1; GSYM IS_INTERVAL_CONNECTED_1]);; + +let CONNECTED_CONVEX_1 = prove + (`!s:real^1->bool. connected s <=> convex s`, + REWRITE_TAC[GSYM IS_INTERVAL_CONVEX_1; GSYM IS_INTERVAL_CONNECTED_1]);; + +let CONNECTED_COMPACT_INTERVAL_1 = prove + (`!s:real^1->bool. connected s /\ compact s <=> ?a b. s = interval[a,b]`, + REWRITE_TAC[GSYM IS_INTERVAL_CONNECTED_1; IS_INTERVAL_COMPACT]);; + +let CONVEX_CONNECTED_1_GEN = prove + (`!s:real^N->bool. + dimindex(:N) = 1 ==> (convex s <=> connected s)`, + REWRITE_TAC[RIGHT_FORALL_IMP_THM] THEN + REWRITE_TAC[GSYM DIMINDEX_1] THEN + DISCH_THEN(ACCEPT_TAC o C GEOM_EQUAL_DIMENSION_RULE CONVEX_CONNECTED_1));; + +let CONNECTED_CONVEX_1_GEN = prove + (`!s:real^N->bool. + dimindex(:N) = 1 ==> (convex s <=> connected s)`, + SIMP_TAC[CONVEX_CONNECTED_1_GEN]);; + +(* ------------------------------------------------------------------------- *) +(* Jung's theorem. *) +(* Proof taken from http://cstheory.wordpress.com/2010/08/07/jungs-theorem/ *) +(* ------------------------------------------------------------------------- *) + +let JUNG = prove + (`!s:real^N->bool r. + bounded s /\ + sqrt(&(dimindex(:N)) / &(2 * dimindex(:N) + 2)) * diameter s <= r + ==> ?a. s SUBSET cball(a,r)`, + let lemma = prove + (`&0 < x /\ x <= y ==> (x - &1) / x <= (y - &1) / y`, + SIMP_TAC[REAL_LE_LDIV_EQ] THEN REPEAT STRIP_TAC THEN + ONCE_REWRITE_TAC[REAL_ARITH `x / y * z:real = (x * z) / y`] THEN + SUBGOAL_THEN `&0 < y` ASSUME_TAC THENL + [ASM_REAL_ARITH_TAC; ASM_SIMP_TAC[REAL_LE_RDIV_EQ]] THEN + ASM_REAL_ARITH_TAC) in + REPEAT STRIP_TAC THEN + SUBGOAL_THEN `&0 <= r` ASSUME_TAC THENL + [FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ_ALT] + REAL_LE_TRANS)) THEN + MATCH_MP_TAC REAL_LE_MUL THEN ASM_SIMP_TAC[DIAMETER_POS_LE] THEN + SIMP_TAC[SQRT_POS_LE; REAL_LE_DIV; REAL_POS]; + ALL_TAC] THEN + MP_TAC(ISPEC `IMAGE (\x:real^N. cball(x,r)) s` HELLY_COMPACT_ALT) THEN + REWRITE_TAC[FORALL_IN_IMAGE; COMPACT_CBALL; CONVEX_CBALL] THEN + REWRITE_TAC[TAUT `p /\ q /\ r ==> s <=> q /\ p ==> r ==> s`] THEN + REWRITE_TAC[FORALL_FINITE_SUBSET_IMAGE] THEN + REWRITE_TAC[INTERS_IMAGE; GSYM MEMBER_NOT_EMPTY] THEN + REWRITE_TAC[SUBSET; IN_CBALL; IN_ELIM_THM] THEN + ANTS_TAC THENL [ALL_TAC; MESON_TAC[DIST_SYM]] THEN + X_GEN_TAC `t:real^N->bool` THEN REWRITE_TAC[GSYM SUBSET] THEN + STRIP_TAC THEN + ASM_SIMP_TAC[CARD_IMAGE_INJ; EQ_BALLS; GSYM REAL_NOT_LE] THEN + UNDISCH_TAC `FINITE(t:real^N->bool)` THEN + SUBGOAL_THEN `bounded(t:real^N->bool)` MP_TAC THENL + [ASM_MESON_TAC[BOUNDED_SUBSET]; ALL_TAC] THEN + UNDISCH_TAC `&0 <= r` THEN + SUBGOAL_THEN + `sqrt(&(dimindex(:N)) / &(2 * dimindex(:N) + 2)) * + diameter(t:real^N->bool) <= r` + MP_TAC THENL + [FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ_ALT] + REAL_LE_TRANS)) THEN + MATCH_MP_TAC REAL_LE_LMUL THEN + ASM_SIMP_TAC[DIAMETER_SUBSET; SQRT_POS_LE; REAL_POS; REAL_LE_DIV]; + POP_ASSUM_LIST(K ALL_TAC) THEN + SPEC_TAC(`t:real^N->bool`,`s:real^N->bool`) THEN + REPEAT STRIP_TAC] THEN + ASM_CASES_TAC `s:real^N->bool = {}` THEN ASM_REWRITE_TAC[NOT_IN_EMPTY] THEN + MP_TAC(ISPEC `{d | &0 <= d /\ ?a:real^N. s SUBSET cball(a,d)}` INF) THEN + ABBREV_TAC `d = inf {d | &0 <= d /\ ?a:real^N. s SUBSET cball(a,d)}` THEN + REWRITE_TAC[IN_ELIM_THM] THEN ANTS_TAC THENL + [REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; IN_ELIM_THM] THEN + ASM_MESON_TAC[BOUNDED_SUBSET_CBALL; REAL_LT_IMP_LE]; + DISCH_THEN(CONJUNCTS_THEN2 (LABEL_TAC "P") (LABEL_TAC "M"))] THEN + SUBGOAL_THEN `&0 <= d` ASSUME_TAC THENL + [ASM_MESON_TAC[REAL_LE_REFL]; ALL_TAC] THEN + SUBGOAL_THEN `?a:real^N. s SUBSET cball(a,d)` MP_TAC THENL + [SUBGOAL_THEN + `!n. ?a:real^N. s SUBSET cball(a,d + inv(&n + &1))` + MP_TAC THENL + [X_GEN_TAC `n:num` THEN + REMOVE_THEN "M" (MP_TAC o SPEC `d + inv(&n + &1)`) THEN + REWRITE_TAC[REAL_ARITH `d + i <= d <=> ~(&0 < i)`] THEN + REWRITE_TAC[REAL_LT_INV_EQ; REAL_ARITH `&0 < &n + &1`] THEN + REWRITE_TAC[NOT_FORALL_THM; NOT_IMP; REAL_NOT_LE] THEN + MESON_TAC[SUBSET_CBALL; REAL_LT_IMP_LE; SUBSET_TRANS]; + ALL_TAC] THEN + REWRITE_TAC[LEFT_IMP_EXISTS_THM; SKOLEM_THM] THEN + X_GEN_TAC `aa:num->real^N` THEN DISCH_TAC THEN + SUBGOAL_THEN `?t. compact t /\ !n. (aa:num->real^N) n IN t` MP_TAC THENL + [FIRST_X_ASSUM(MP_TAC o SPEC `vec 0:real^N` o + MATCH_MP BOUNDED_SUBSET_CBALL) THEN + REWRITE_TAC[LEFT_IMP_EXISTS_THM; SUBSET; IN_CBALL_0] THEN + X_GEN_TAC `B:real` THEN STRIP_TAC THEN + EXISTS_TAC `cball(vec 0:real^N,B + d + &1)` THEN + REWRITE_TAC[COMPACT_CBALL; IN_CBALL_0] THEN X_GEN_TAC `n:num` THEN + RULE_ASSUM_TAC(REWRITE_RULE[SUBSET; IN_CBALL]) THEN + MATCH_MP_TAC(NORM_ARITH + `(?x:real^N. norm(x) <= B /\ dist(a,x) <= d) ==> norm(a) <= B + d`) THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN + MATCH_MP_TAC MONO_EXISTS THEN REPEAT STRIP_TAC THEN ASM_SIMP_TAC[] THEN + MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC `d + inv(&n + &1)` THEN + ASM_SIMP_TAC[REAL_LE_LADD] THEN + MATCH_MP_TAC REAL_INV_LE_1 THEN REAL_ARITH_TAC; + ALL_TAC] THEN + REWRITE_TAC[compact; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `t:real^N->bool` THEN + DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN + DISCH_THEN(MP_TAC o SPEC `aa:num->real^N`) THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `a:real^N` THEN + DISCH_THEN(X_CHOOSE_THEN `r:num->num` STRIP_ASSUME_TAC) THEN + REWRITE_TAC[SUBSET; IN_CBALL] THEN X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN + REWRITE_TAC[GSYM REAL_NOT_LT] THEN DISCH_TAC THEN + MP_TAC(SPEC `(dist(a:real^N,x) - d) / &2` REAL_ARCH_INV) THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [LIM_SEQUENTIALLY]) THEN + DISCH_THEN(MP_TAC o SPEC `(dist(a:real^N,x) - d) / &2`) THEN + ASM_SIMP_TAC[REAL_SUB_LT; REAL_HALF; o_THM] THEN + DISCH_THEN(X_CHOOSE_THEN `N1:num` STRIP_ASSUME_TAC) THEN + DISCH_THEN(X_CHOOSE_THEN `N2:num` STRIP_ASSUME_TAC) THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE BINDER_CONV [SUBSET]) THEN + DISCH_THEN(MP_TAC o SPECL [`(r:num->num)(N1 + N2)`; `x:real^N`]) THEN + ASM_REWRITE_TAC[IN_CBALL; REAL_NOT_LE] THEN + FIRST_X_ASSUM(MP_TAC o SPEC `N1 + N2:num`) THEN + ASM_REWRITE_TAC[LE_ADD] THEN + SUBGOAL_THEN `inv(&(r (N1 + N2:num)) + &1) < (dist(a:real^N,x) - d) / &2` + MP_TAC THENL [ALL_TAC; NORM_ARITH_TAC] THEN + MATCH_MP_TAC REAL_LET_TRANS THEN EXISTS_TAC `inv(&N2)` THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC REAL_LE_INV2 THEN + CONJ_TAC THENL [ASM_MESON_TAC[REAL_LT_INV_EQ]; ALL_TAC] THEN + REWRITE_TAC[REAL_OF_NUM_LE; REAL_OF_NUM_ADD] THEN + MATCH_MP_TAC(ARITH_RULE + `N1 + N2 <= r(N1 + N2) ==> N2 <= r(N1 + N2) + 1`) THEN + ASM_MESON_TAC[MONOTONE_BIGGER]; + ALL_TAC] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `a:real^N` THEN + ONCE_REWRITE_TAC[DIST_SYM] THEN + REWRITE_TAC[GSYM IN_CBALL; GSYM SUBSET] THEN + DISCH_THEN(fun th -> ASSUME_TAC th THEN MP_TAC th) THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] SUBSET_TRANS) THEN + MATCH_MP_TAC SUBSET_CBALL THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH + `a * s <= r ==> d <= a * s ==> d <= r`)) THEN + UNDISCH_THEN `&0 <= r` (K ALL_TAC) THEN REMOVE_THEN "M" (K ALL_TAC) THEN + FIRST_X_ASSUM(K ALL_TAC o SYM) THEN REMOVE_THEN "P" MP_TAC THEN + REWRITE_TAC[RIGHT_AND_EXISTS_THM; LEFT_IMP_EXISTS_THM] THEN + ABBREV_TAC `n = CARD(s:real^N->bool)` THEN + SUBGOAL_THEN `(s:real^N->bool) HAS_SIZE n` MP_TAC THENL + [ASM_REWRITE_TAC[HAS_SIZE]; ALL_TAC] THEN + UNDISCH_THEN `CARD(s:real^N->bool) = n` (K ALL_TAC) THEN + POP_ASSUM_LIST(MP_TAC o end_itlist CONJ o rev) THEN + SPEC_TAC(`d:real`,`r:real`) THEN GEN_TAC THEN + GEOM_ORIGIN_TAC `a:real^N` THEN SIMP_TAC[HAS_SIZE] THEN + REPEAT STRIP_TAC THEN FIRST_X_ASSUM(SUBST_ALL_TAC o SYM) THEN + ABBREV_TAC `t = {x:real^N | x IN s /\ norm(x) = r}` THEN + SUBGOAL_THEN `FINITE(t:real^N->bool)` ASSUME_TAC THENL + [EXPAND_TAC "t" THEN ASM_SIMP_TAC[FINITE_RESTRICT]; ALL_TAC] THEN + SUBGOAL_THEN `(vec 0:real^N) IN convex hull t` MP_TAC THENL + [MATCH_MP_TAC(TAUT `(~p ==> F) ==> p`) THEN DISCH_TAC THEN + MP_TAC(ISPEC `convex hull t:real^N->bool` + SEPARATING_HYPERPLANE_CLOSED_0) THEN + ASM_SIMP_TAC[CONVEX_CONVEX_HULL; NOT_IMP; COMPACT_CONVEX_HULL; + FINITE_IMP_COMPACT; COMPACT_IMP_CLOSED] THEN + REWRITE_TAC[NOT_EXISTS_THM; TAUT `~(p /\ q) <=> p ==> ~q`] THEN + X_GEN_TAC `v:real^N` THEN + ABBREV_TAC `k = CARD(s:real^N->bool)` THEN + SUBGOAL_THEN `(s:real^N->bool) HAS_SIZE k` MP_TAC THENL + [ASM_REWRITE_TAC[HAS_SIZE]; ALL_TAC] THEN + UNDISCH_THEN `CARD(s:real^N->bool) = k` (K ALL_TAC) THEN + POP_ASSUM_LIST(MP_TAC o end_itlist CONJ o rev) THEN + GEOM_BASIS_MULTIPLE_TAC 1 `v:real^N` THEN X_GEN_TAC `m:real` THEN + GEN_REWRITE_TAC LAND_CONV [REAL_ARITH `&0 <= x <=> x = &0 \/ &0 < x`] THEN + STRIP_TAC THEN ASM_REWRITE_TAC[VECTOR_MUL_EQ_0] THEN + ASM_SIMP_TAC[BASIS_NONZERO; DIMINDEX_GE_1; LE_REFL; REAL_LT_IMP_NZ] THEN + REPEAT GEN_TAC THEN STRIP_TAC THEN ASM_REWRITE_TAC[HAS_SIZE] THEN + DISCH_THEN(SUBST_ALL_TAC o SYM) THEN X_GEN_TAC `b:real` THEN DISCH_TAC THEN + ASM_SIMP_TAC[DOT_LMUL; DOT_BASIS; DIMINDEX_GE_1; LE_REFL] THEN + ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN + ASM_SIMP_TAC[real_gt; GSYM REAL_LT_LDIV_EQ] THEN + SUBGOAL_THEN `&0 < b / m` MP_TAC THENL + [ASM_SIMP_TAC[REAL_LT_DIV]; + UNDISCH_THEN `&0 < b` (K ALL_TAC) THEN + SPEC_TAC(`b / m:real`,`b:real`)] THEN + X_GEN_TAC `b:real` THEN DISCH_TAC THEN DISCH_TAC THEN + SUBGOAL_THEN + `!x:real^N e. &0 < e /\ e < b /\ x IN t ==> norm(x - e % basis 1) < r` + ASSUME_TAC THENL + [MAP_EVERY X_GEN_TAC [`x:real^N`; `e:real`] THEN STRIP_TAC THEN + SUBGOAL_THEN `r = norm(x:real^N)` SUBST1_TAC THENL + [ASM SET_TAC[]; REWRITE_TAC[NORM_LT; dot]] THEN + SIMP_TAC[SUM_CLAUSES_LEFT; DIMINDEX_GE_1] THEN + SIMP_TAC[VECTOR_SUB_COMPONENT; VECTOR_MUL_COMPONENT; + BASIS_COMPONENT; DIMINDEX_GE_1; LE_REFL; + ARITH_RULE `2 <= n ==> 1 <= n /\ ~(n = 1)`; ARITH] THEN + REWRITE_TAC[REAL_MUL_RZERO; REAL_SUB_RZERO; REAL_LT_RADD] THEN + REWRITE_TAC[GSYM REAL_POW_2; GSYM REAL_LT_SQUARE_ABS] THEN + MATCH_MP_TAC(REAL_ARITH + `!b. &0 < e /\ e < b /\ b < x ==> abs(x - e * &1) < abs x`) THEN + EXISTS_TAC `b:real` THEN ASM_REWRITE_TAC[] THEN + ASM_MESON_TAC[HULL_INC]; + ALL_TAC] THEN + SUBGOAL_THEN + `?d. &0 < d /\ + !x:real^N a. x IN (s DIFF t) /\ norm(a) < d ==> norm(x - a) < r` + STRIP_ASSUME_TAC THENL + [ASM_CASES_TAC `s DIFF t:real^N->bool = {}` THENL + [ASM_REWRITE_TAC[NOT_IN_EMPTY] THEN MESON_TAC[REAL_LT_01]; ALL_TAC] THEN + EXISTS_TAC `inf (IMAGE (\x:real^N. r - norm x) (s DIFF t))` THEN + SUBGOAL_THEN `FINITE(s DIFF t:real^N->bool)` ASSUME_TAC THENL + [ASM_MESON_TAC[FINITE_DIFF]; ALL_TAC] THEN + ASM_SIMP_TAC[REAL_LT_INF_FINITE; FINITE_IMAGE; IMAGE_EQ_EMPTY] THEN + REWRITE_TAC[FORALL_IN_IMAGE] THEN SIMP_TAC + [NORM_ARITH `norm a < r - norm x ==> norm(x - a:real^N) < r`] THEN + EXPAND_TAC "t" THEN REWRITE_TAC[IN_DIFF; IN_ELIM_THM; REAL_SUB_LT] THEN + RULE_ASSUM_TAC(REWRITE_RULE[SUBSET; IN_CBALL_0]) THEN + ASM_MESON_TAC[REAL_LT_LE]; + ALL_TAC] THEN + SUBGOAL_THEN + `?a. !x. x IN s ==> norm(x - a:real^N) < r` + STRIP_ASSUME_TAC THENL + [EXISTS_TAC `min (b / &2) (d / &2) % basis 1:real^N` THEN + X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN + ASM_CASES_TAC `(x:real^N) IN t` THENL + [MATCH_MP_TAC(ASSUME + `!x:real^N e. &0 < e /\ e < b /\ x IN t + ==> norm (x - e % basis 1) < r`) THEN + ASM_REWRITE_TAC[] THEN ASM_REAL_ARITH_TAC; + MATCH_MP_TAC(ASSUME + `!x:real^N a. x IN s DIFF t /\ norm a < d ==> norm (x - a) < r`) THEN + ASM_SIMP_TAC[IN_DIFF; NORM_MUL; LE_REFL; NORM_BASIS; + DIMINDEX_GE_1] THEN + ASM_REAL_ARITH_TAC]; + SUBGOAL_THEN `&0 < r` ASSUME_TAC THENL + [ASM_MESON_TAC[MEMBER_NOT_EMPTY; NORM_ARITH + `norm(x:real^N) < r ==> &0 < r`]; + ALL_TAC] THEN + UNDISCH_THEN + `!x a:real^N. &0 <= x /\ s SUBSET cball (a,x) ==> r <= x` (MP_TAC o + SPECL [`max (&0) (r - inf (IMAGE (\x:real^N. r - norm(x - a)) s))`; + `a:real^N`]) THEN + ASM_SIMP_TAC[REAL_ARITH `&0 < r ==> (r <= max (&0) a <=> r <= a)`] THEN + REWRITE_TAC[SUBSET; IN_CBALL; REAL_ARITH `a <= max a b`] THEN + REWRITE_TAC[NOT_IMP; REAL_ARITH `~(r <= r - x) <=> &0 < x`] THEN + ASM_SIMP_TAC[REAL_LT_INF_FINITE; FINITE_IMAGE; IMAGE_EQ_EMPTY] THEN + ASM_REWRITE_TAC[FORALL_IN_IMAGE; REAL_SUB_LT] THEN + X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN + MATCH_MP_TAC(REAL_ARITH `d <= b ==> d <= max a b`) THEN + ONCE_REWRITE_TAC[REAL_ARITH `a <= b - c <=> c <= b - a`] THEN + ASM_SIMP_TAC[REAL_INF_LE_FINITE; FINITE_IMAGE; IMAGE_EQ_EMPTY] THEN + REWRITE_TAC[EXISTS_IN_IMAGE; ONCE_REWRITE_RULE[NORM_SUB] dist] THEN + ASM_MESON_TAC[REAL_LE_REFL]]; + ALL_TAC] THEN + ASM_CASES_TAC `t:real^N->bool = {}` THEN + ASM_REWRITE_TAC[CONVEX_HULL_EMPTY; NOT_IN_EMPTY] THEN + REWRITE_TAC[CONVEX_HULL_FINITE; IN_ELIM_THM] THEN + DISCH_THEN(X_CHOOSE_THEN `l:real^N->real` STRIP_ASSUME_TAC) THEN + MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `sqrt((&(dimindex (:N)) / &(2 * dimindex (:N) + 2)) * + diameter(s:real^N->bool) pow 2)` THEN + CONJ_TAC THENL + [MATCH_MP_TAC REAL_LE_RSQRT; + ASM_SIMP_TAC[SQRT_MUL; DIAMETER_POS_LE; REAL_POW_LE; REAL_LE_DIV; + REAL_POS; POW_2_SQRT; REAL_LE_REFL]] THEN + + SUBGOAL_THEN + `sum t (\y:real^N. &2 * r pow 2) <= + sum t (\y. (&1 - l y) * diameter(s:real^N->bool) pow 2)` + MP_TAC THENL + [MATCH_MP_TAC SUM_LE THEN ASM_REWRITE_TAC[] THEN + X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN + MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `sum (t DELETE x) (\x:real^N. l(x)) * + diameter(s:real^N->bool) pow 2` THEN CONJ_TAC THENL + [ALL_TAC; ASM_SIMP_TAC[SUM_DELETE; ETA_AX; REAL_LE_REFL]] THEN + REWRITE_TAC[GSYM SUM_RMUL] THEN MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `sum (t DELETE x) (\y:real^N. l y * norm(y - x) pow 2)` THEN + CONJ_TAC THENL + [ALL_TAC; + MATCH_MP_TAC SUM_LE THEN ASM_REWRITE_TAC[FINITE_DELETE; IN_DELETE] THEN + X_GEN_TAC `y:real^N` THEN STRIP_TAC THEN MATCH_MP_TAC REAL_LE_LMUL THEN + ASM_SIMP_TAC[] THEN MATCH_MP_TAC REAL_POW_LE2 THEN + REWRITE_TAC[NORM_POS_LE] THEN + MATCH_MP_TAC DIAMETER_BOUNDED_BOUND THEN ASM SET_TAC[]] THEN + MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `sum t (\y:real^N. l y * norm (y - x) pow 2)` THEN + CONJ_TAC THENL + [ALL_TAC; + MATCH_MP_TAC REAL_EQ_IMP_LE THEN MATCH_MP_TAC SUM_EQ_SUPERSET THEN + ASM_REWRITE_TAC[FINITE_DELETE] THEN + CONJ_TAC THENL [SET_TAC[]; REWRITE_TAC[IN_DELETE]] THEN + SIMP_TAC[TAUT `p /\ ~(p /\ ~q) <=> p /\ q`] THEN + REWRITE_TAC[VECTOR_SUB_REFL; NORM_0] THEN REAL_ARITH_TAC] THEN + REWRITE_TAC[NORM_POW_2; VECTOR_ARITH + `(y - x:real^N) dot (y - x) = (x dot x + y dot y) - &2 * x dot y`] THEN + MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `sum t (\y:real^N. l y * (&2 * r pow 2 - &2 * (x dot y)))` THEN + CONJ_TAC THENL + [ALL_TAC; + MATCH_MP_TAC REAL_EQ_IMP_LE THEN MATCH_MP_TAC SUM_EQ THEN + UNDISCH_TAC `(x:real^N) IN t` THEN EXPAND_TAC "t" THEN + REWRITE_TAC[IN_DELETE; IN_ELIM_THM] THEN + SIMP_TAC[NORM_EQ_SQUARE; NORM_POW_2] THEN REAL_ARITH_TAC] THEN + REWRITE_TAC[REAL_ARITH `x * (&2 * y - &2 * z) = &2 * (x * y - x * z)`] THEN + REWRITE_TAC[SUM_LMUL] THEN MATCH_MP_TAC REAL_LE_LMUL THEN + REWRITE_TAC[REAL_POS] THEN + ASM_SIMP_TAC[SUM_SUB; FINITE_DELETE; SUM_RMUL] THEN + REWRITE_TAC[GSYM DOT_RMUL] THEN + ASM_SIMP_TAC[GSYM DOT_RSUM; DOT_RZERO] THEN REAL_ARITH_TAC; + ASM_SIMP_TAC[SUM_CONST; SUM_RMUL; SUM_SUB] THEN + REWRITE_TAC[REAL_OF_NUM_MUL; MULT_CLAUSES] THEN + GEN_REWRITE_TAC (LAND_CONV o LAND_CONV) [REAL_MUL_SYM] THEN + SUBGOAL_THEN `&0 < &(CARD(t:real^N->bool) * 2)` ASSUME_TAC THENL + [REWRITE_TAC[REAL_OF_NUM_LT; ARITH_RULE `0 < n * 2 <=> ~(n = 0)`] THEN + ASM_SIMP_TAC[CARD_EQ_0]; + ASM_SIMP_TAC[GSYM REAL_LE_RDIV_EQ] THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] REAL_LE_TRANS) THEN + REWRITE_TAC[REAL_ARITH `(a * b) / c:real = a / c * b`] THEN + MATCH_MP_TAC REAL_LE_RMUL THEN REWRITE_TAC[REAL_LE_POW_2] THEN + REWRITE_TAC[ARITH_RULE `2 * n + 2 = (n + 1) * 2`; GSYM REAL_OF_NUM_MUL; + real_div; REAL_INV_MUL; REAL_MUL_ASSOC] THEN + MATCH_MP_TAC REAL_LE_RMUL THEN REWRITE_TAC[GSYM real_div] THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN + SUBGOAL_THEN `&(dimindex(:N)) = &(dimindex(:N) + 1) - &1` + SUBST1_TAC THENL + [REWRITE_TAC[GSYM REAL_OF_NUM_ADD] THEN REAL_ARITH_TAC; + MATCH_MP_TAC lemma THEN + ASM_SIMP_TAC[REAL_OF_NUM_LE; REAL_OF_NUM_LT; CARD_EQ_0; + ARITH_RULE `0 < n <=> ~(n = 0)`] THEN + MATCH_MP_TAC LE_TRANS THEN EXISTS_TAC `CARD(s:real^N->bool)` THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC CARD_SUBSET THEN + ASM SET_TAC[]]]]);; + +(* ------------------------------------------------------------------------- *) +(* Convex cones and corresponding hulls. *) +(* ------------------------------------------------------------------------- *) + +let convex_cone = new_definition + `convex_cone s <=> ~(s = {}) /\ convex s /\ conic s`;; + +let CONVEX_CONE = prove + (`!s:real^N->bool. + convex_cone s <=> + vec 0 IN s /\ + (!x y. x IN s /\ y IN s ==> (x + y) IN s) /\ + (!x c. x IN s /\ &0 <= c ==> (c % x) IN s)`, + GEN_TAC THEN REWRITE_TAC[convex_cone; GSYM conic] THEN + ASM_CASES_TAC `conic(s:real^N->bool)` THEN + ASM_SIMP_TAC[CONIC_CONTAINS_0] THEN AP_TERM_TAC THEN + RULE_ASSUM_TAC(REWRITE_RULE[conic]) THEN + REWRITE_TAC[convex] THEN EQ_TAC THEN + ASM_SIMP_TAC[REAL_SUB_LE] THEN DISCH_TAC THEN + MAP_EVERY X_GEN_TAC [`x:real^N`; `y:real^N`] THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPECL + [`&2 % (x:real^N)`; `&2 % (y:real^N)`; `&1 / &2`; `&1 / &2`]) THEN + REWRITE_TAC[VECTOR_MUL_ASSOC] THEN CONV_TAC REAL_RAT_REDUCE_CONV THEN + ASM_SIMP_TAC[VECTOR_MUL_LID; REAL_POS]);; + +let CONVEX_CONE_LINEAR_IMAGE = prove + (`!f:real^M->real^N s. + convex_cone s /\ linear f ==> convex_cone(IMAGE f s)`, + SIMP_TAC[convex_cone; CONVEX_LINEAR_IMAGE; IMAGE_EQ_EMPTY; + CONIC_LINEAR_IMAGE]);; + +let CONVEX_CONE_LINEAR_IMAGE_EQ = prove + (`!f:real^M->real^N s. + linear f /\ (!x y. f x = f y ==> x = y) + ==> (convex_cone(IMAGE f s) <=> convex_cone s)`, + REWRITE_TAC[convex_cone] THEN + MESON_TAC[IMAGE_EQ_EMPTY; CONVEX_LINEAR_IMAGE_EQ; CONIC_LINEAR_IMAGE_EQ]);; + +add_linear_invariants [CONVEX_CONE_LINEAR_IMAGE_EQ];; + +let CONVEX_CONE_HALFSPACE_GE = prove + (`!a. convex_cone {x | a dot x >= &0}`, + SIMP_TAC[CONVEX_CONE; real_ge; IN_ELIM_THM; DOT_RZERO; DOT_RADD; DOT_RMUL; + REAL_LE_ADD; REAL_LE_MUL; REAL_LE_REFL]);; + +let CONVEX_CONE_HALFSPACE_LE = prove + (`!a. convex_cone {x | a dot x <= &0}`, + REWRITE_TAC[REAL_ARITH `x <= &0 <=> &0 <= --x`; GSYM DOT_LNEG] THEN + REWRITE_TAC[GSYM real_ge; CONVEX_CONE_HALFSPACE_GE]);; + +let CONVEX_CONE_CONTAINS_0 = prove + (`!s:real^N->bool. convex_cone s ==> vec 0 IN s`, + SIMP_TAC[CONVEX_CONE]);; + +let CONVEX_CONE_INTERS = prove + (`!f. (!s:real^N->bool. s IN f ==> convex_cone s) ==> convex_cone(INTERS f)`, + SIMP_TAC[convex_cone; CONIC_INTERS; CONVEX_INTERS] THEN + REWRITE_TAC[GSYM convex_cone] THEN GEN_TAC THEN DISCH_TAC THEN + REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN EXISTS_TAC `vec 0:real^N` THEN + ASM_SIMP_TAC[IN_INTERS; CONVEX_CONE_CONTAINS_0]);; + +let CONVEX_CONE_CONVEX_CONE_HULL = prove + (`!s. convex_cone(convex_cone hull s)`, + SIMP_TAC[P_HULL; CONVEX_CONE_INTERS]);; + +let CONVEX_CONVEX_CONE_HULL = prove + (`!s. convex(convex_cone hull s)`, + MESON_TAC[CONVEX_CONE_CONVEX_CONE_HULL; convex_cone]);; + +let CONIC_CONVEX_CONE_HULL = prove + (`!s. conic(convex_cone hull s)`, + MESON_TAC[CONVEX_CONE_CONVEX_CONE_HULL; convex_cone]);; + +let CONVEX_CONE_HULL_NONEMPTY = prove + (`!s. ~(convex_cone hull s = {})`, + MESON_TAC[CONVEX_CONE_CONVEX_CONE_HULL; convex_cone]);; + +let CONVEX_CONE_HULL_CONTAINS_0 = prove + (`!s. vec 0 IN convex_cone hull s`, + MESON_TAC[CONVEX_CONE_CONVEX_CONE_HULL; CONVEX_CONE]);; + +let CONVEX_CONE_HULL_ADD = prove + (`!s x y:real^N. + x IN convex_cone hull s /\ y IN convex_cone hull s + ==> x + y IN convex_cone hull s`, + MESON_TAC[CONVEX_CONE; CONVEX_CONE_CONVEX_CONE_HULL]);; + +let CONVEX_CONE_HULL_MUL = prove + (`!s c x:real^N. + &0 <= c /\ x IN convex_cone hull s + ==> (c % x) IN convex_cone hull s`, + MESON_TAC[CONVEX_CONE; CONVEX_CONE_CONVEX_CONE_HULL]);; + +let CONVEX_CONE_SUMS = prove + (`!s t. convex_cone s /\ convex_cone t + ==> convex_cone {x + y:real^N | x IN s /\ y IN t}`, + SIMP_TAC[convex_cone; CONIC_SUMS; CONVEX_SUMS] THEN SET_TAC[]);; + +let CONVEX_CONE_PCROSS = prove + (`!s:real^M->bool t:real^N->bool. + convex_cone s /\ convex_cone t ==> convex_cone(s PCROSS t)`, + SIMP_TAC[convex_cone; CONVEX_PCROSS; CONIC_PCROSS; PCROSS_EQ_EMPTY]);; + +let CONVEX_CONE_PCROSS_EQ = prove + (`!s:real^M->bool t:real^N->bool. + convex_cone(s PCROSS t) <=> convex_cone s /\ convex_cone t`, + REPEAT GEN_TAC THEN + ASM_CASES_TAC `s:real^M->bool = {}` THENL + [ASM_REWRITE_TAC[PCROSS_EMPTY; convex_cone]; ALL_TAC] THEN + ASM_CASES_TAC `t:real^N->bool = {}` THENL + [ASM_REWRITE_TAC[PCROSS_EMPTY; convex_cone]; ALL_TAC] THEN + EQ_TAC THEN REWRITE_TAC[CONVEX_CONE_PCROSS] THEN REPEAT STRIP_TAC THENL + [MP_TAC(ISPECL [`fstcart:real^(M,N)finite_sum->real^M`; + `(s:real^M->bool) PCROSS (t:real^N->bool)`] CONVEX_CONE_LINEAR_IMAGE) THEN + ASM_REWRITE_TAC[LINEAR_FSTCART]; + MP_TAC(ISPECL [`sndcart:real^(M,N)finite_sum->real^N`; + `(s:real^M->bool) PCROSS (t:real^N->bool)`] CONVEX_CONE_LINEAR_IMAGE) THEN + ASM_REWRITE_TAC[LINEAR_SNDCART]] THEN + MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN + REWRITE_TAC[EXTENSION; IN_IMAGE; EXISTS_PASTECART; PASTECART_IN_PCROSS; + FSTCART_PASTECART; SNDCART_PASTECART] THEN + ASM SET_TAC[]);; + +let CONVEX_CONE_HULL_UNION = prove + (`!s t. convex_cone hull(s UNION t) = + {x + y:real^N | x IN convex_cone hull s /\ y IN convex_cone hull t}`, + REPEAT GEN_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL + [MATCH_MP_TAC HULL_MINIMAL THEN + SIMP_TAC[CONVEX_CONE_SUMS; CONVEX_CONE_CONVEX_CONE_HULL] THEN + REWRITE_TAC[SUBSET; IN_UNION; IN_ELIM_THM] THEN + X_GEN_TAC `x:real^N` THEN STRIP_TAC THENL + [MAP_EVERY EXISTS_TAC [`x:real^N`; `vec 0:real^N`] THEN + ASM_SIMP_TAC[HULL_INC; CONVEX_CONE_HULL_CONTAINS_0; VECTOR_ADD_RID]; + MAP_EVERY EXISTS_TAC [`vec 0:real^N`; `x:real^N`] THEN + ASM_SIMP_TAC[HULL_INC; CONVEX_CONE_HULL_CONTAINS_0; VECTOR_ADD_LID]]; + REWRITE_TAC[SUBSET; FORALL_IN_GSPEC] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC CONVEX_CONE_HULL_ADD THEN + ASM_MESON_TAC[HULL_MONO; SUBSET_UNION; SUBSET]]);; + +let CONVEX_CONE_SING = prove + (`convex_cone {vec 0}`, + SIMP_TAC[CONVEX_CONE; IN_SING; VECTOR_ADD_LID; VECTOR_MUL_RZERO]);; + +let CONVEX_HULL_SUBSET_CONVEX_CONE_HULL = prove + (`!s. convex hull s SUBSET convex_cone hull s`, + GEN_TAC THEN MATCH_MP_TAC HULL_ANTIMONO THEN + SIMP_TAC[convex_cone; SUBSET; IN]);; + +let CONIC_HULL_SUBSET_CONVEX_CONE_HULL = prove + (`!s. conic hull s SUBSET convex_cone hull s`, + GEN_TAC THEN MATCH_MP_TAC HULL_ANTIMONO THEN + SIMP_TAC[convex_cone; SUBSET; IN]);; + +let CONVEX_CONE_HULL_SEPARATE_NONEMPTY = prove + (`!s:real^N->bool. + ~(s = {}) + ==> convex_cone hull s = conic hull (convex hull s)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THEN + MATCH_MP_TAC HULL_MINIMAL THEN + REWRITE_TAC[CONIC_CONVEX_CONE_HULL; CONVEX_HULL_SUBSET_CONVEX_CONE_HULL] THEN + ASM_SIMP_TAC[CONVEX_CONIC_HULL; CONVEX_CONVEX_HULL; CONIC_CONIC_HULL; + convex_cone; CONIC_HULL_EQ_EMPTY; CONVEX_HULL_EQ_EMPTY] THEN + ASM_MESON_TAC[HULL_SUBSET; SUBSET_REFL; SUBSET_TRANS]);; + +let CONVEX_CONE_HULL_EMPTY = prove + (`convex_cone hull {} = {vec 0}`, + MATCH_MP_TAC HULL_UNIQUE THEN + REWRITE_TAC[CONVEX_CONE_CONTAINS_0; EMPTY_SUBSET; CONVEX_CONE_SING; + SET_RULE `{a} SUBSET s <=> a IN s`; CONVEX_CONE_CONTAINS_0]);; + +let CONVEX_CONE_HULL_SEPARATE = prove + (`!s:real^N->bool. + convex_cone hull s = vec 0 INSERT conic hull (convex hull s)`, + GEN_TAC THEN ASM_CASES_TAC `s:real^N->bool = {}` THEN + ASM_SIMP_TAC[CONVEX_CONE_HULL_EMPTY; CONVEX_HULL_EMPTY; CONIC_HULL_EMPTY] THEN + ASM_SIMP_TAC[CONVEX_CONE_HULL_SEPARATE_NONEMPTY] THEN + MATCH_MP_TAC(SET_RULE `a IN s ==> s = a INSERT s`) THEN + ASM_SIMP_TAC[CONIC_CONTAINS_0; CONIC_CONIC_HULL] THEN + ASM_REWRITE_TAC[CONIC_HULL_EQ_EMPTY; CONVEX_HULL_EQ_EMPTY]);; + +let CONVEX_CONE_HULL_CONVEX_HULL_NONEMPTY = prove + (`!s:real^N->bool. + ~(s = {}) + ==> convex_cone hull s = {c % x | &0 <= c /\ x IN convex hull s}`, + SIMP_TAC[CONVEX_CONE_HULL_SEPARATE_NONEMPTY; CONIC_HULL_EXPLICIT]);; + +let CONVEX_CONE_HULL_CONVEX_HULL = prove + (`!s:real^N->bool. + convex_cone hull s = + vec 0 INSERT {c % x | &0 <= c /\ x IN convex hull s}`, + REWRITE_TAC[CONVEX_CONE_HULL_SEPARATE; CONIC_HULL_EXPLICIT]);; + +let CONVEX_CONE_HULL_LINEAR_IMAGE = prove + (`!f:real^M->real^N s. + linear f + ==> convex_cone hull (IMAGE f s) = IMAGE f (convex_cone hull s)`, + REPEAT STRIP_TAC THEN + ASM_CASES_TAC `s:real^M-> bool = {}` THEN + ASM_SIMP_TAC[CONVEX_CONE_HULL_SEPARATE_NONEMPTY; IMAGE_EQ_EMPTY; + CONVEX_HULL_LINEAR_IMAGE; CONIC_HULL_LINEAR_IMAGE] THEN + REWRITE_TAC[IMAGE_CLAUSES; CONVEX_CONE_HULL_EMPTY] THEN + MATCH_MP_TAC(SET_RULE `f x = y ==> {y} = {f x}`) THEN + ASM_MESON_TAC[LINEAR_0]);; + +add_linear_invariants [CONVEX_CONE_HULL_LINEAR_IMAGE];; + +let SUBSPACE_IMP_CONVEX_CONE = prove + (`!s. subspace s ==> convex_cone s`, + SIMP_TAC[subspace; CONVEX_CONE]);; + +let CONVEX_CONE_SPAN = prove + (`!s. convex_cone(span s)`, + SIMP_TAC[convex_cone; CONVEX_SPAN; CONIC_SPAN; GSYM MEMBER_NOT_EMPTY] THEN + MESON_TAC[SPAN_0]);; + +let CONVEX_CONE_NEGATIONS = prove + (`!s. convex_cone s ==> convex_cone (IMAGE (--) s)`, + SIMP_TAC[convex_cone; IMAGE_EQ_EMPTY; CONIC_NEGATIONS; CONVEX_NEGATIONS]);; + +let SUBSPACE_CONVEX_CONE_SYMMETRIC = prove + (`!s:real^N->bool. + subspace s <=> convex_cone s /\ (!x. x IN s ==> --x IN s)`, + GEN_TAC THEN REWRITE_TAC[subspace; CONVEX_CONE] THEN + EQ_TAC THEN STRIP_TAC THEN ASM_SIMP_TAC[] THENL + [ASM_MESON_TAC[VECTOR_ARITH `--x:real^N = -- &1 % x`]; + MAP_EVERY X_GEN_TAC [`c:real`; `x:real^N`] THEN DISCH_TAC THEN + DISJ_CASES_TAC(SPEC `c:real` REAL_LE_NEGTOTAL) THEN ASM_SIMP_TAC[] THEN + ASM_MESON_TAC[VECTOR_ARITH `c % x:real^N = --(--c % x)`]]);; + +let SPAN_CONVEX_CONE_ALLSIGNS = prove + (`!s:real^N->bool. span s = convex_cone hull (s UNION IMAGE (--) s)`, + GEN_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL + [MATCH_MP_TAC SPAN_SUBSET_SUBSPACE THEN CONJ_TAC THENL + [MESON_TAC[HULL_SUBSET; SUBSET_UNION; SUBSET_TRANS]; ALL_TAC] THEN + REWRITE_TAC[SUBSPACE_CONVEX_CONE_SYMMETRIC; + CONVEX_CONE_CONVEX_CONE_HULL] THEN + MATCH_MP_TAC HULL_INDUCT THEN CONJ_TAC THENL + [X_GEN_TAC `x:real^N` THEN REWRITE_TAC[IN_UNION; IN_IMAGE] THEN + DISCH_TAC THEN MATCH_MP_TAC HULL_INC THEN + REWRITE_TAC[IN_UNION; IN_IMAGE] THEN ASM_MESON_TAC[VECTOR_NEG_NEG]; + SUBGOAL_THEN `!s. {x:real^N | (--x) IN s} = IMAGE (--) s` + (fun th -> SIMP_TAC[th; CONVEX_CONE_NEGATIONS; + CONVEX_CONE_CONVEX_CONE_HULL]) THEN + GEN_TAC THEN CONV_TAC SYM_CONV THEN MATCH_MP_TAC SURJECTIVE_IMAGE_EQ THEN + REWRITE_TAC[IN_ELIM_THM] THEN MESON_TAC[VECTOR_NEG_NEG]]; + MATCH_MP_TAC HULL_MINIMAL THEN REWRITE_TAC[CONVEX_CONE_SPAN] THEN + REWRITE_TAC[UNION_SUBSET; SPAN_INC] THEN + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE] THEN + MESON_TAC[SPAN_SUPERSET; SPAN_NEG]]);; + +(* ------------------------------------------------------------------------- *) +(* Epigraphs of convex functions. *) +(* ------------------------------------------------------------------------- *) + +let epigraph = new_definition + `epigraph s (f:real^N->real) = + {xy:real^((N,1)finite_sum) | + fstcart xy IN s /\ f(fstcart xy) <= drop(sndcart xy)}`;; + +let IN_EPIGRAPH = prove + (`!x y. (pastecart x (lift y)) IN epigraph s f <=> x IN s /\ f(x) <= y`, + REWRITE_TAC[epigraph; IN_ELIM_THM; FSTCART_PASTECART; SNDCART_PASTECART; + LIFT_DROP]);; + +let CONVEX_EPIGRAPH = prove + (`!f s. f convex_on s /\ convex s <=> convex(epigraph s f)`, + REWRITE_TAC[convex; convex_on; IN_ELIM_THM; SNDCART_ADD; SNDCART_CMUL; + epigraph; FSTCART_ADD; FSTCART_CMUL; FORALL_PASTECART; FSTCART_PASTECART; + SNDCART_PASTECART] THEN + REWRITE_TAC[GSYM FORALL_DROP; DROP_ADD; DROP_CMUL] THEN + MESON_TAC[REAL_LE_REFL; REAL_LE_ADD2; REAL_LE_LMUL; REAL_LE_TRANS]);; + +let CONVEX_EPIGRAPH_CONVEX = prove + (`!f s. convex s ==> (f convex_on s <=> convex(epigraph s f))`, + REWRITE_TAC[GSYM CONVEX_EPIGRAPH] THEN CONV_TAC TAUT);; + +let CONVEX_ON_EPIGRAPH_SLICE_LE = prove + (`!f:real^N->real s a. + f convex_on s /\ convex s ==> convex {x | x IN s /\ f(x) <= a}`, + SIMP_TAC[convex_on; convex; IN_ELIM_THM] THEN REPEAT STRIP_TAC THEN + FIRST_X_ASSUM(fun th -> + W(MP_TAC o PART_MATCH (lhand o rand) th o lhand o snd)) THEN + ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] REAL_LE_TRANS) THEN + MATCH_MP_TAC REAL_CONVEX_BOUND_LE THEN ASM_REWRITE_TAC[]);; + +let CONVEX_ON_EPIGRAPH_SLICE_LT = prove + (`!f:real^N->real s a. + f convex_on s /\ convex s ==> convex {x | x IN s /\ f(x) < a}`, + SIMP_TAC[convex_on; convex; IN_ELIM_THM] THEN REPEAT STRIP_TAC THEN + FIRST_X_ASSUM(fun th -> + W(MP_TAC o PART_MATCH (lhand o rand) th o lhand o snd)) THEN + ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] REAL_LET_TRANS) THEN + MATCH_MP_TAC REAL_CONVEX_BOUND_LT THEN ASM_REWRITE_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* Use this to derive general bound property of convex function. *) +(* ------------------------------------------------------------------------- *) + +let FORALL_OF_PASTECART = prove + (`(!p. P (fstcart o p) (sndcart o p)) <=> (!x:A->B^M y:A->B^N. P x y)`, + EQ_TAC THENL [ALL_TAC; MESON_TAC[]] THEN REPEAT STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o SPEC `\a:A. pastecart (x a :B^M) (y a :B^N)`) THEN + REWRITE_TAC[o_DEF; FSTCART_PASTECART; SNDCART_PASTECART; ETA_AX]);; + +let FORALL_OF_DROP = prove + (`(!v. P (drop o v)) <=> (!x:A->real. P x)`, + EQ_TAC THENL [ALL_TAC; MESON_TAC[]] THEN REPEAT STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o SPEC `\a:A. lift(x a)`) THEN + REWRITE_TAC[o_DEF; LIFT_DROP; ETA_AX]);; + +let CONVEX_ON_JENSEN = prove + (`!f:real^N->real s. + convex s + ==> (f convex_on s <=> + !k u x. + (!i:num. 1 <= i /\ i <= k ==> &0 <= u(i) /\ x(i) IN s) /\ + (sum (1..k) u = &1) + ==> f(vsum (1..k) (\i. u(i) % x(i))) + <= sum (1..k) (\i. u(i) * f(x(i))))`, + let lemma = prove + (`(!x. P x ==> (Q x = R x)) ==> (!x. P x) ==> ((!x. Q x) <=> (!x. R x))`, + MESON_TAC[]) in + REPEAT STRIP_TAC THEN FIRST_ASSUM + (fun th -> REWRITE_TAC[MATCH_MP CONVEX_EPIGRAPH_CONVEX th]) THEN + REWRITE_TAC[CONVEX_INDEXED; epigraph] THEN + SIMP_TAC[IN_ELIM_THM; SNDCART_ADD; SNDCART_CMUL; FINITE_NUMSEG; + FSTCART_ADD; FSTCART_CMUL; FORALL_PASTECART; DROP_CMUL; + FSTCART_PASTECART; SNDCART_PASTECART; + FSTCART_VSUM; SNDCART_VSUM; DROP_VSUM; o_DEF] THEN + REWRITE_TAC[GSYM(ISPEC `fstcart` o_THM); GSYM(ISPEC `sndcart` o_THM)] THEN + REWRITE_TAC[GSYM(ISPEC `drop` o_THM)] THEN + REWRITE_TAC[FORALL_OF_PASTECART; FORALL_OF_DROP] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [CONVEX_INDEXED]) THEN + REPEAT(MATCH_MP_TAC lemma THEN GEN_TAC) THEN SIMP_TAC[] THEN + REWRITE_TAC[TAUT `a ==> b /\ c <=> (a ==> b) /\ (a ==> c)`] THEN + REWRITE_TAC[FORALL_AND_THM] THEN DISCH_THEN(K ALL_TAC) THEN + EQ_TAC THEN SIMP_TAC[REAL_LE_REFL] THEN + DISCH_THEN(fun th -> REPEAT STRIP_TAC THEN MP_TAC th) THEN + ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC(REAL_ARITH `a <= b ==> x <= a ==> x <= b`) THEN + ASM_SIMP_TAC[SUM_LE_NUMSEG; REAL_LE_LMUL]);; + +(* ------------------------------------------------------------------------- *) +(* Another intermediate value theorem formulation. *) +(* ------------------------------------------------------------------------- *) + +let IVT_INCREASING_COMPONENT_ON_1 = prove + (`!f:real^1->real^N a b y k. + drop a <= drop b /\ 1 <= k /\ k <= dimindex(:N) /\ + f continuous_on interval[a,b] /\ + f(a)$k <= y /\ y <= f(b)$k + ==> ?x. x IN interval[a,b] /\ f(x)$k = y`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`IMAGE (f:real^1->real^N) (interval[a,b])`] + CONNECTED_IVT_COMPONENT) THEN + REWRITE_TAC[EXISTS_IN_IMAGE] THEN DISCH_THEN MATCH_MP_TAC THEN + REWRITE_TAC[RIGHT_EXISTS_AND_THM; EXISTS_IN_IMAGE] THEN + ASM_SIMP_TAC[CONNECTED_CONTINUOUS_IMAGE; CONVEX_CONNECTED; + CONVEX_INTERVAL] THEN + EXISTS_TAC `a:real^1` THEN ASM_REWRITE_TAC[IN_INTERVAL_1; REAL_LE_REFL] THEN + EXISTS_TAC `b:real^1` THEN ASM_REWRITE_TAC[IN_INTERVAL_1; REAL_LE_REFL]);; + +let IVT_INCREASING_COMPONENT_1 = prove + (`!f:real^1->real^N a b y k. + drop a <= drop b /\ 1 <= k /\ k <= dimindex(:N) /\ + (!x. x IN interval[a,b] ==> f continuous at x) /\ + f(a)$k <= y /\ y <= f(b)$k + ==> ?x. x IN interval[a,b] /\ f(x)$k = y`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC IVT_INCREASING_COMPONENT_ON_1 THEN + ASM_SIMP_TAC[CONTINUOUS_AT_IMP_CONTINUOUS_ON]);; + +let IVT_DECREASING_COMPONENT_ON_1 = prove + (`!f:real^1->real^N a b y k. + drop a <= drop b /\ 1 <= k /\ k <= dimindex(:N) /\ + f continuous_on interval[a,b] /\ + f(b)$k <= y /\ y <= f(a)$k + ==> ?x. x IN interval[a,b] /\ f(x)$k = y`, + REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[GSYM REAL_EQ_NEG2] THEN + ASM_SIMP_TAC[GSYM VECTOR_NEG_COMPONENT] THEN + MATCH_MP_TAC IVT_INCREASING_COMPONENT_ON_1 THEN + ASM_SIMP_TAC[VECTOR_NEG_COMPONENT; CONTINUOUS_ON_NEG; REAL_LE_NEG2]);; + +let IVT_DECREASING_COMPONENT_1 = prove + (`!f:real^1->real^N a b y k. + drop a <= drop b /\ 1 <= k /\ k <= dimindex(:N) /\ + (!x. x IN interval[a,b] ==> f continuous at x) /\ + f(b)$k <= y /\ y <= f(a)$k + ==> ?x. x IN interval[a,b] /\ f(x)$k = y`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC IVT_DECREASING_COMPONENT_ON_1 THEN + ASM_SIMP_TAC[CONTINUOUS_AT_IMP_CONTINUOUS_ON]);; + +(* ------------------------------------------------------------------------- *) +(* A bound within a convex hull, and so an interval. *) +(* ------------------------------------------------------------------------- *) + +let CONVEX_ON_CONVEX_HULL_BOUND = prove + (`!f s b. f convex_on (convex hull s) /\ + (!x:real^N. x IN s ==> f(x) <= b) + ==> !x. x IN convex hull s ==> f(x) <= b`, + REPEAT GEN_TAC THEN SIMP_TAC[CONVEX_ON_JENSEN; CONVEX_CONVEX_HULL] THEN + STRIP_TAC THEN GEN_TAC THEN REWRITE_TAC[CONVEX_HULL_INDEXED] THEN + REWRITE_TAC[IN_ELIM_THM; LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`k:num`; `u:num->real`; `v:num->real^N`] THEN + DISCH_THEN(STRIP_ASSUME_TAC o GSYM) THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `sum(1..k) (\i. u i * f(v i :real^N))` THEN CONJ_TAC THENL + [FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_MESON_TAC[SUBSET; HULL_SUBSET]; + ALL_TAC] THEN + MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC `sum(1..k) (\i. u i * b)` THEN + CONJ_TAC THENL + [MATCH_MP_TAC SUM_LE_NUMSEG THEN ASM_SIMP_TAC[REAL_LE_LMUL]; + ALL_TAC] THEN + ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN REWRITE_TAC[SUM_LMUL] THEN + ASM_MESON_TAC[REAL_LE_REFL; REAL_MUL_RID]);; + +let UNIT_INTERVAL_CONVEX_HULL = prove + (`interval [vec 0,vec 1:real^N] = + convex hull + {x:real^N | !i. 1 <= i /\ i <= dimindex(:N) + ==> ((x$i = &0) \/ (x$i = &1))}`, + let lemma = prove + (`FINITE {i | 1 <= i /\ i <= n /\ P(i)} /\ + CARD {i | 1 <= i /\ i <= n /\ P(i)} <= n`, + CONJ_TAC THENL + [MATCH_MP_TAC FINITE_SUBSET THEN EXISTS_TAC `1..n`; + GEN_REWRITE_TAC RAND_CONV [ARITH_RULE `x = (x + 1) - 1`] THEN + REWRITE_TAC[GSYM CARD_NUMSEG] THEN MATCH_MP_TAC CARD_SUBSET] THEN + SIMP_TAC[FINITE_NUMSEG; IN_NUMSEG; SUBSET; IN_ELIM_THM]) in + MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL + [ALL_TAC; + MATCH_MP_TAC HULL_MINIMAL THEN + REWRITE_TAC[CONVEX_INTERVAL; SUBSET; IN_INTERVAL; IN_ELIM_THM] THEN + SIMP_TAC[VEC_COMPONENT] THEN MESON_TAC[REAL_LE_REFL; REAL_POS]] THEN + SUBGOAL_THEN + `!n x:real^N. + x IN interval[vec 0,vec 1] /\ + n <= dimindex(:N) /\ + CARD {i | 1 <= i /\ i <= dimindex(:N) /\ ~(x$i = &0)} <= n + ==> x IN convex hull + {x:real^N | !i. 1 <= i /\ i <= dimindex(:N) + ==> ((x$i = &0) \/ (x$i = &1))}` + MP_TAC THENL + [ALL_TAC; + REWRITE_TAC[SUBSET] THEN REPEAT STRIP_TAC THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN EXISTS_TAC `dimindex(:N)` THEN + ASM_REWRITE_TAC[LE_REFL; lemma]] THEN + INDUCT_TAC THEN X_GEN_TAC `x:real^N` THENL + [SIMP_TAC[LE; lemma; CARD_EQ_0] THEN + GEN_REWRITE_TAC (LAND_CONV o TOP_DEPTH_CONV) + [EXTENSION; IN_ELIM_THM; NOT_IN_EMPTY; BETA_THM] THEN + REWRITE_TAC[TAUT `~(a /\ b /\ c) <=> a /\ b ==> ~c`] THEN STRIP_TAC THEN + SUBGOAL_THEN `x = vec 0:real^N` SUBST1_TAC THENL + [ASM_SIMP_TAC[CART_EQ; VEC_COMPONENT]; ALL_TAC] THEN + MATCH_MP_TAC(REWRITE_RULE[SUBSET] HULL_SUBSET) THEN + SIMP_TAC[IN_ELIM_THM; VEC_COMPONENT]; + ALL_TAC] THEN + ASM_CASES_TAC + `{i | 1 <= i /\ i <= dimindex(:N) /\ ~((x:real^N)$i = &0)} = {}` + THENL + [DISCH_THEN(K ALL_TAC) THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [EXTENSION]) THEN + GEN_REWRITE_TAC (LAND_CONV o TOP_DEPTH_CONV) + [EXTENSION; IN_ELIM_THM; NOT_IN_EMPTY; BETA_THM] THEN + REWRITE_TAC[TAUT `~(a /\ b /\ c) <=> a /\ b ==> ~c`] THEN STRIP_TAC THEN + SUBGOAL_THEN `x = vec 0:real^N` SUBST1_TAC THENL + [ASM_SIMP_TAC[CART_EQ; VEC_COMPONENT]; ALL_TAC] THEN + MATCH_MP_TAC(REWRITE_RULE[SUBSET] HULL_SUBSET) THEN + SIMP_TAC[IN_ELIM_THM; VEC_COMPONENT]; + ALL_TAC] THEN + MP_TAC(ISPEC + `IMAGE (\i. x$i) + {i | 1 <= i /\ i <= dimindex(:N) /\ ~((x:real^N)$i = &0)}` + INF_FINITE) THEN + ABBREV_TAC `xi = inf + (IMAGE (\i. x$i) + {i | 1 <= i /\ i <= dimindex(:N) /\ ~((x:real^N)$i = &0)})` THEN + ASM_SIMP_TAC[FINITE_IMAGE; IMAGE_EQ_EMPTY; lemma] THEN + REWRITE_TAC[FORALL_IN_IMAGE] THEN + GEN_REWRITE_TAC (LAND_CONV o TOP_DEPTH_CONV) [IN_IMAGE; IN_ELIM_THM] THEN + REWRITE_TAC[] THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + FIRST_X_ASSUM(X_CHOOSE_THEN `i:num` STRIP_ASSUME_TAC) THEN + FIRST_X_ASSUM SUBST_ALL_TAC THEN REPEAT STRIP_TAC THEN + SUBGOAL_THEN `&0 <= (x:real^N)$i /\ x$i <= &1` STRIP_ASSUME_TAC THENL + [UNDISCH_TAC `x:real^N IN interval [vec 0,vec 1]` THEN + ASM_SIMP_TAC[IN_INTERVAL; VEC_COMPONENT]; + ALL_TAC] THEN + FIRST_X_ASSUM(DISJ_CASES_TAC o MATCH_MP (REAL_ARITH + `x <= &1 ==> (x = &1) \/ x < &1`)) + THENL + [SUBGOAL_THEN + `x = lambda i. if (x:real^N)$i = &0 then &0 else &1` + SUBST1_TAC THENL + [UNDISCH_TAC `x:real^N IN interval [vec 0,vec 1]` THEN + ASM_SIMP_TAC[CART_EQ; IN_INTERVAL; VEC_COMPONENT; LAMBDA_BETA] THEN + ASM_MESON_TAC[REAL_LE_ANTISYM]; + ALL_TAC] THEN + MATCH_MP_TAC(REWRITE_RULE[SUBSET] HULL_SUBSET) THEN + SIMP_TAC[IN_ELIM_THM; LAMBDA_BETA] THEN MESON_TAC[]; + ALL_TAC] THEN + SUBGOAL_THEN + `x:real^N = + x$i % (lambda j. if x$j = &0 then &0 else &1) + + (&1 - x$i) % + (lambda j. if x$j = &0 then &0 else (x$j - x$i) / (&1 - x$i))` + SUBST1_TAC THENL + [SIMP_TAC[CART_EQ; VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT; + LAMBDA_BETA; VEC_COMPONENT] THEN + REPEAT STRIP_TAC THEN COND_CASES_TAC THEN + ASM_REWRITE_TAC[REAL_MUL_RZERO; REAL_ADD_LID] THEN + ASM_SIMP_TAC[REAL_DIV_LMUL; ARITH_RULE `x < &1 ==> ~(&1 - x = &0)`] THEN + REPEAT STRIP_TAC THEN REAL_ARITH_TAC; + ALL_TAC] THEN + MATCH_MP_TAC(REWRITE_RULE[convex] CONVEX_CONVEX_HULL) THEN + ASM_SIMP_TAC[REAL_ARITH `x < &1 ==> &0 <= &1 - x`; + REAL_ARITH `x + &1 - x = &1`] THEN + CONJ_TAC THENL + [MATCH_MP_TAC(REWRITE_RULE[SUBSET] HULL_SUBSET) THEN + SIMP_TAC[LAMBDA_BETA; IN_ELIM_THM] THEN MESON_TAC[]; + ALL_TAC] THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_SIMP_TAC[ARITH_RULE `SUC k <= n ==> k <= n`] THEN CONJ_TAC THENL + [SIMP_TAC[IN_INTERVAL; LAMBDA_BETA; VEC_COMPONENT] THEN + GEN_TAC THEN STRIP_TAC THEN + COND_CASES_TAC THEN REWRITE_TAC[REAL_LE_REFL; REAL_POS] THEN + ASM_SIMP_TAC[REAL_LE_LDIV_EQ; REAL_LE_RDIV_EQ; + REAL_ARITH `x < &1 ==> &0 < &1 - x`] THEN + ASM_REWRITE_TAC[REAL_MUL_LZERO; REAL_SUB_LE; REAL_MUL_LID] THEN + ASM_SIMP_TAC[REAL_ARITH `a - b <= &1 - b <=> a <= &1`] THEN + UNDISCH_TAC `x:real^N IN interval [vec 0,vec 1]` THEN + ASM_SIMP_TAC[CART_EQ; IN_INTERVAL; VEC_COMPONENT; LAMBDA_BETA]; + ALL_TAC] THEN + MATCH_MP_TAC LE_TRANS THEN + EXISTS_TAC + `CARD({i | 1 <= i /\ i <= dimindex(:N) /\ ~((x:real^N)$i = &0)} + DELETE i)` THEN + CONJ_TAC THENL + [MATCH_MP_TAC CARD_SUBSET THEN REWRITE_TAC[lemma; FINITE_DELETE] THEN + REWRITE_TAC[SUBSET; IN_DELETE; IN_ELIM_THM] THEN + GEN_TAC THEN REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + ASM_SIMP_TAC[LAMBDA_BETA] THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[CONTRAPOS_THM] THEN + SIMP_TAC[real_div; REAL_SUB_REFL; REAL_MUL_LZERO]; + SIMP_TAC[lemma; CARD_DELETE] THEN COND_CASES_TAC THEN + ASM_SIMP_TAC[ARITH_RULE `x <= SUC n ==> x - 1 <= n`] THEN + RULE_ASSUM_TAC(REWRITE_RULE[IN_ELIM_THM]) THEN + ASM_MESON_TAC[]]);; + +(* ------------------------------------------------------------------------- *) +(* Representation of any interval as a finite convex hull. *) +(* ------------------------------------------------------------------------- *) + +let CLOSED_INTERVAL_AS_CONVEX_HULL = prove + (`!a b:real^N. ?s. FINITE s /\ interval[a,b] = convex hull s`, + REPEAT GEN_TAC THEN ASM_CASES_TAC `interval[a:real^N,b] = {}` THENL + [ASM_MESON_TAC[CONVEX_HULL_EMPTY; FINITE_EMPTY]; ALL_TAC] THEN + ASM_SIMP_TAC[CLOSED_INTERVAL_IMAGE_UNIT_INTERVAL] THEN + SUBGOAL_THEN + `?s:real^N->bool. FINITE s /\ interval[vec 0,vec 1] = convex hull s` + STRIP_ASSUME_TAC THENL + [EXISTS_TAC + `{x:real^N | !i. 1 <= i /\ i <= dimindex(:N) + ==> ((x$i = &0) \/ (x$i = &1))}` THEN + REWRITE_TAC[UNIT_INTERVAL_CONVEX_HULL] THEN + MATCH_MP_TAC FINITE_SUBSET THEN EXISTS_TAC + `IMAGE (\s. (lambda i. if i IN s then &1 else &0):real^N) + {t | t SUBSET (1..dimindex(:N))}` THEN + ASM_SIMP_TAC[FINITE_POWERSET; FINITE_IMAGE; FINITE_NUMSEG] THEN + REWRITE_TAC[SUBSET; IN_ELIM_THM; IN_IMAGE] THEN + X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN EXISTS_TAC + `{i | 1 <= i /\ i <= dimindex(:N) /\ ((x:real^N)$i = &1)}` THEN + SIMP_TAC[CART_EQ; IN_ELIM_THM; IN_NUMSEG; LAMBDA_BETA] THEN + ASM_MESON_TAC[]; + EXISTS_TAC `IMAGE (\x:real^N. a + x) + (IMAGE (\x. (lambda i. ((b:real^N)$i - a$i) * x$i)) + (s:real^N->bool))` THEN + ASM_SIMP_TAC[FINITE_IMAGE; CONVEX_HULL_TRANSLATION] THEN + AP_TERM_TAC THEN MATCH_MP_TAC(GSYM CONVEX_HULL_LINEAR_IMAGE) THEN + SIMP_TAC[linear; CART_EQ; LAMBDA_BETA; VECTOR_ADD_COMPONENT; + VECTOR_MUL_COMPONENT] THEN + REPEAT STRIP_TAC THEN REAL_ARITH_TAC]);; + +(* ------------------------------------------------------------------------- *) +(* Bounded convex function on open set is continuous. *) +(* ------------------------------------------------------------------------- *) + +let CONVEX_ON_BOUNDED_CONTINUOUS = prove + (`!f:real^N->real s b. + open s /\ f convex_on s /\ (!x. x IN s ==> abs(f x) <= b) + ==> (lift o f) continuous_on s`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC CONTINUOUS_AT_IMP_CONTINUOUS_ON THEN + X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN + REWRITE_TAC[CONTINUOUS_AT_LIFT_RANGE] THEN + ABBREV_TAC `B = abs(b) + &1` THEN + SUBGOAL_THEN `&0 < B /\ !x:real^N. x IN s ==> abs(f x) <= B` + STRIP_ASSUME_TAC THENL + [EXPAND_TAC "B" THEN CONJ_TAC THENL [REAL_ARITH_TAC; ALL_TAC] THEN + ASM_MESON_TAC[REAL_ARITH `x <= b ==> x <= abs b + &1`]; + ALL_TAC] THEN + X_GEN_TAC `e:real` THEN DISCH_TAC THEN + REWRITE_TAC[REAL_ARITH `abs(x - y) < e <=> x - y < e /\ y - x < e`] THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [OPEN_CONTAINS_CBALL]) THEN + DISCH_THEN(MP_TAC o SPEC `x:real^N`) THEN REWRITE_TAC[SUBSET; IN_CBALL] THEN + ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `k:real` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `min (k / &2) (e / (&2 * B) * k)` THEN + ASM_SIMP_TAC[REAL_LT_MIN; REAL_LT_DIV; REAL_LT_MUL; + REAL_OF_NUM_LT; ARITH] THEN + X_GEN_TAC `y:real^N` THEN + ASM_CASES_TAC `y:real^N = x` THEN ASM_REWRITE_TAC[REAL_SUB_REFL] THEN + STRIP_TAC THEN + ABBREV_TAC `t = k / norm(y - x:real^N)` THEN + SUBGOAL_THEN `&2 < t` ASSUME_TAC THENL + [EXPAND_TAC "t" THEN + ASM_SIMP_TAC[REAL_LT_RDIV_EQ; NORM_POS_LT; VECTOR_SUB_EQ] THEN + ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN + ASM_SIMP_TAC[GSYM REAL_LT_RDIV_EQ; REAL_OF_NUM_LT; ARITH]; + ALL_TAC] THEN + FIRST_ASSUM(STRIP_ASSUME_TAC o MATCH_MP (REAL_ARITH + `&2 < t ==> &0 < t /\ ~(t = &0) /\ &0 < t - &1 /\ + &0 < &1 + t /\ ~(&1 + t = &0)`)) THEN + SUBGOAL_THEN `y:real^N IN s` ASSUME_TAC THENL + [FIRST_ASSUM MATCH_MP_TAC THEN REWRITE_TAC[dist] THEN + ONCE_REWRITE_TAC[NORM_SUB] THEN + FIRST_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH + `x < k / &2 ==> k / &2 <= k ==> x <= k`)) THEN + ASM_SIMP_TAC[REAL_LE_LDIV_EQ; REAL_OF_NUM_LT; ARITH] THEN + UNDISCH_TAC `&0 < k` THEN REAL_ARITH_TAC; + ALL_TAC] THEN + CONJ_TAC THENL + [ABBREV_TAC `w:real^N = x + t % (y - x)` THEN + SUBGOAL_THEN `w:real^N IN s` STRIP_ASSUME_TAC THENL + [FIRST_ASSUM MATCH_MP_TAC THEN EXPAND_TAC "w" THEN + REWRITE_TAC[dist; VECTOR_ARITH `x - (x + t) = --t:real^N`] THEN + EXPAND_TAC "t" THEN REWRITE_TAC[NORM_NEG; NORM_MUL; REAL_ABS_DIV] THEN + REWRITE_TAC[REAL_ABS_NORM; real_div; GSYM REAL_MUL_ASSOC] THEN + ASM_SIMP_TAC[REAL_MUL_LINV; REAL_LT_IMP_NZ; NORM_POS_LT; VECTOR_SUB_EQ; + REAL_MUL_RID; REAL_ARITH `&0 < x ==> abs(x) <= x`]; + ALL_TAC] THEN + SUBGOAL_THEN `(&1 / t) % w + (t - &1) / t % x = y:real^N` ASSUME_TAC THENL + [EXPAND_TAC "w" THEN + REWRITE_TAC[VECTOR_ARITH + `b % (x + c % (y - x)) + a % x = + (a + b - b * c) % x + (b * c) % y`] THEN + ASM_SIMP_TAC[REAL_DIV_RMUL; VECTOR_MUL_LID] THEN + ASM_SIMP_TAC[real_div; REAL_MUL_RINV; REAL_SUB_REFL; + VECTOR_MUL_LZERO; VECTOR_ADD_LID; + REAL_ARITH `(a - &1) * b + &1 * b - &1 = a * b - &1`]; + ALL_TAC] THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [convex_on]) THEN + DISCH_THEN(MP_TAC o SPECL + [`w:real^N`; `x:real^N`; `&1 / t`; `(t - &1) / t`]) THEN + ASM_SIMP_TAC[REAL_LT_IMP_LE; REAL_LT_DIV; REAL_LT_01] THEN + REWRITE_TAC[real_div; GSYM REAL_ADD_RDISTRIB] THEN + ASM_SIMP_TAC[REAL_SUB_ADD2; REAL_MUL_RINV] THEN + MATCH_MP_TAC(REAL_ARITH + `a * fw + (b - &1) * fx < e + ==> fy <= a * fw + b * fx ==> fy - fx < e`) THEN + ASM_SIMP_TAC[real_div; REAL_SUB_RDISTRIB; REAL_MUL_RINV; REAL_MUL_LID; + REAL_ARITH `a * x + y - a * y - y = a * (x - y)`] THEN + ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN + ASM_SIMP_TAC[GSYM real_div; REAL_LT_LDIV_EQ] THEN + MATCH_MP_TAC(REAL_ARITH + `!b. abs(x) <= b /\ abs(y) <= b /\ &2 * b < z ==> x - y < z`) THEN + EXISTS_TAC `B:real` THEN ASM_SIMP_TAC[] THEN EXPAND_TAC "t" THEN + REWRITE_TAC[real_div; REAL_MUL_ASSOC] THEN REWRITE_TAC[GSYM real_div] THEN + ASM_SIMP_TAC[REAL_LT_RDIV_EQ; NORM_POS_LT; VECTOR_SUB_EQ] THEN + ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN + ASM_SIMP_TAC[GSYM REAL_LT_RDIV_EQ; REAL_LT_MUL; REAL_OF_NUM_LT; ARITH] THEN + REWRITE_TAC[real_div; REAL_ARITH `(a * b) * inv c = (b * inv c) * a`] THEN + ASM_REWRITE_TAC[GSYM real_div]; + + ABBREV_TAC `w:real^N = x - t % (y - x)` THEN + SUBGOAL_THEN `w:real^N IN s` STRIP_ASSUME_TAC THENL + [FIRST_ASSUM MATCH_MP_TAC THEN EXPAND_TAC "w" THEN + REWRITE_TAC[dist; VECTOR_ARITH `x - (x - t) = t:real^N`] THEN + EXPAND_TAC "t" THEN REWRITE_TAC[NORM_MUL; REAL_ABS_DIV] THEN + REWRITE_TAC[REAL_ABS_NORM; real_div; GSYM REAL_MUL_ASSOC] THEN + ASM_SIMP_TAC[REAL_MUL_LINV; REAL_LT_IMP_NZ; NORM_POS_LT; VECTOR_SUB_EQ; + REAL_MUL_RID; REAL_ARITH `&0 < x ==> abs(x) <= x`]; + ALL_TAC] THEN + SUBGOAL_THEN `(&1 / (&1 + t)) % w + t / (&1 + t) % y = x:real^N` + ASSUME_TAC THENL + [EXPAND_TAC "w" THEN + REWRITE_TAC[VECTOR_ARITH + `b % (x - c % (y - x)) + a % y = + (b * (&1 + c)) % x + (a - b * c) % y`] THEN + ASM_SIMP_TAC[REAL_DIV_RMUL; VECTOR_MUL_LID] THEN + REWRITE_TAC[real_div; REAL_MUL_AC; REAL_MUL_LID; REAL_MUL_RID] THEN + REWRITE_TAC[REAL_SUB_REFL; VECTOR_MUL_LZERO; VECTOR_ADD_RID]; + ALL_TAC] THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [convex_on]) THEN + DISCH_THEN(MP_TAC o SPECL + [`w:real^N`; `y:real^N`; `&1 / (&1 + t)`; `t / (&1 + t)`]) THEN + ASM_SIMP_TAC[REAL_LT_IMP_LE; REAL_LT_DIV; REAL_LT_01] THEN + REWRITE_TAC[real_div; GSYM REAL_ADD_RDISTRIB] THEN + ASM_SIMP_TAC[REAL_SUB_ADD2; REAL_MUL_RINV] THEN + MATCH_MP_TAC(REAL_ARITH + `a * fw + (b - &1) * fx < e + ==> fy <= a * fw + b * fx ==> fy - fx < e`) THEN + SUBGOAL_THEN `t * inv(&1 + t) - &1 = --(inv(&1 + t))` SUBST1_TAC THENL + [REWRITE_TAC[REAL_ARITH `(a * b - &1 = --b) <=> ((&1 + a) * b = &1)`] THEN + ASM_SIMP_TAC[REAL_MUL_RINV]; + ALL_TAC] THEN + REWRITE_TAC[REAL_ARITH `(&1 * a) * x + --a * y = a * (x - y)`] THEN + ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN + ASM_SIMP_TAC[GSYM real_div; REAL_LT_LDIV_EQ] THEN + MATCH_MP_TAC(REAL_ARITH + `!b. abs(x) <= b /\ abs(y) <= b /\ &2 * b < z ==> x - y < z`) THEN + EXISTS_TAC `B:real` THEN ASM_SIMP_TAC[] THEN + MATCH_MP_TAC(REAL_ARITH `&0 < e /\ x < e * k ==> x < e * (&1 + k)`) THEN + EXPAND_TAC "t" THEN REWRITE_TAC[real_div; REAL_MUL_ASSOC] THEN + REWRITE_TAC[GSYM real_div] THEN + ASM_SIMP_TAC[REAL_LT_RDIV_EQ; NORM_POS_LT; VECTOR_SUB_EQ] THEN + ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN + ASM_SIMP_TAC[GSYM REAL_LT_RDIV_EQ; REAL_LT_MUL; REAL_OF_NUM_LT; ARITH] THEN + REWRITE_TAC[real_div; REAL_ARITH `(a * b) * inv c = (b * inv c) * a`] THEN + ASM_REWRITE_TAC[GSYM real_div]]);; + +(* ------------------------------------------------------------------------- *) +(* Upper bound on a ball implies upper and lower bounds. *) +(* ------------------------------------------------------------------------- *) + +let CONVEX_BOUNDS_LEMMA = prove + (`!f x:real^N e. + f convex_on cball(x,e) /\ + (!y. y IN cball(x,e) ==> f(y) <= b) + ==> !y. y IN cball(x,e) ==> abs(f(y)) <= b + &2 * abs(f(x))`, + REPEAT GEN_TAC THEN ASM_CASES_TAC `&0 <= e` THENL + [ALL_TAC; + REWRITE_TAC[IN_CBALL] THEN ASM_MESON_TAC[DIST_POS_LE; REAL_LE_TRANS]] THEN + REPEAT STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [convex_on]) THEN + DISCH_THEN(MP_TAC o SPECL + [`y:real^N`; `&2 % x - y:real^N`; `&1 / &2`; `&1 / &2`]) THEN + REWRITE_TAC[GSYM VECTOR_ADD_LDISTRIB; GSYM REAL_ADD_LDISTRIB] THEN + REWRITE_TAC[VECTOR_ARITH `y + x - y = x:real^N`] THEN + REWRITE_TAC[VECTOR_MUL_ASSOC] THEN CONV_TAC REAL_RAT_REDUCE_CONV THEN + ABBREV_TAC `z = &2 % x - y:real^N` THEN + SUBGOAL_THEN `z:real^N IN cball(x,e)` ASSUME_TAC THENL + [UNDISCH_TAC `y:real^N IN cball(x,e)` THEN + EXPAND_TAC "z" THEN REWRITE_TAC[dist; IN_CBALL] THEN + REWRITE_TAC[VECTOR_ARITH `x - (&2 % x - y) = y - x`] THEN + REWRITE_TAC[NORM_SUB]; + ALL_TAC] THEN + ASM_REWRITE_TAC[VECTOR_MUL_LID] THEN ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN + REWRITE_TAC[real_div; REAL_MUL_LID] THEN REWRITE_TAC[GSYM real_div] THEN + ASM_SIMP_TAC[REAL_LE_RDIV_EQ; REAL_OF_NUM_LT; ARITH] THEN + FIRST_X_ASSUM(fun th -> + MAP_EVERY (MP_TAC o C SPEC th) [`y:real^N`; `z:real^N`]) THEN + ASM_REWRITE_TAC[CENTRE_IN_CBALL] THEN REAL_ARITH_TAC);; + +(* ------------------------------------------------------------------------- *) +(* Hence a convex function on an open set is continuous. *) +(* ------------------------------------------------------------------------- *) + +let CONVEX_ON_CONTINUOUS = prove + (`!f s:real^N->bool. open s /\ f convex_on s ==> lift o f continuous_on s`, + REPEAT STRIP_TAC THEN ASM_SIMP_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_AT] THEN + X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [OPEN_CONTAINS_CBALL]) THEN + DISCH_THEN(MP_TAC o SPEC `x:real^N`) THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `e:real` STRIP_ASSUME_TAC) THEN + ABBREV_TAC `d = e / &(dimindex(:N))` THEN + SUBGOAL_THEN `&0 < d` ASSUME_TAC THENL + [EXPAND_TAC "d" THEN MATCH_MP_TAC REAL_LT_DIV THEN + ASM_REWRITE_TAC[REAL_OF_NUM_LT; DIMINDEX_GE_1; + ARITH_RULE `0 < d <=> 1 <= d`]; + ALL_TAC] THEN + SUBGOAL_THEN + `?b. !y:real^N. y IN interval[(x - lambda i. d),(x + lambda i. d)] + ==> f(y) <= b` + STRIP_ASSUME_TAC THENL + [MP_TAC(ISPECL [`x - (lambda i. d):real^N`; `x + (lambda i. d):real^N`] + CLOSED_INTERVAL_AS_CONVEX_HULL) THEN + DISCH_THEN(X_CHOOSE_THEN `c:real^N->bool` STRIP_ASSUME_TAC) THEN + ASM_REWRITE_TAC[] THEN ASM_CASES_TAC `c = {}:real^N->bool` THEN + ASM_REWRITE_TAC[CONVEX_HULL_EMPTY; NOT_IN_EMPTY] THEN + MP_TAC(ISPEC `IMAGE (f:real^N->real) c` SUP_FINITE) THEN + ASM_SIMP_TAC[FINITE_IMAGE; IMAGE_EQ_EMPTY; FORALL_IN_IMAGE] THEN + ABBREV_TAC `k = sup(IMAGE (f:real^N->real) c)` THEN + STRIP_TAC THEN EXISTS_TAC `k:real` THEN + MATCH_MP_TAC CONVEX_ON_CONVEX_HULL_BOUND THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC CONVEX_ON_SUBSET THEN + EXISTS_TAC `s:real^N->bool` THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC SUBSET_TRANS THEN EXISTS_TAC `cball (x:real^N,e)` THEN + ASM_REWRITE_TAC[] THEN + FIRST_X_ASSUM(fun th -> GEN_REWRITE_TAC LAND_CONV [SYM th]) THEN + REWRITE_TAC[SUBSET; IN_INTERVAL; IN_CBALL] THEN + SIMP_TAC[VECTOR_ADD_COMPONENT; VECTOR_SUB_COMPONENT; LAMBDA_BETA] THEN + X_GEN_TAC `z:real^N` THEN + REWRITE_TAC[REAL_ARITH `x - d <= z /\ z <= x + d <=> abs(x - z) <= d`] THEN + DISCH_TAC THEN REWRITE_TAC[dist] THEN + MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC + `sum(1..dimindex(:N)) (\i. abs((x - z:real^N)$i))` THEN + REWRITE_TAC[NORM_LE_L1] THEN + MATCH_MP_TAC SUM_BOUND_GEN THEN + REWRITE_TAC[FINITE_NUMSEG; NUMSEG_EMPTY; CARD_NUMSEG] THEN + ASM_SIMP_TAC[IN_NUMSEG; NOT_LT; DIMINDEX_GE_1; ADD_SUB; + VECTOR_SUB_COMPONENT]; + ALL_TAC] THEN + SUBGOAL_THEN `cball(x:real^N,d) SUBSET cball(x,e)` ASSUME_TAC THENL + [REWRITE_TAC[SUBSET; IN_CBALL] THEN GEN_TAC THEN + MATCH_MP_TAC(REAL_ARITH `d <= e ==> x <= d ==> x <= e`) THEN + EXPAND_TAC "d" THEN + ASM_SIMP_TAC[REAL_LE_LDIV_EQ; REAL_OF_NUM_LT; DIMINDEX_GE_1; + ARITH_RULE `0 < x <=> 1 <= x`] THEN + GEN_REWRITE_TAC LAND_CONV [GSYM REAL_MUL_RID] THEN + ASM_SIMP_TAC[REAL_LE_LMUL_EQ; REAL_OF_NUM_LE; DIMINDEX_GE_1]; + ALL_TAC] THEN + SUBGOAL_THEN + `!y:real^N. y IN cball(x,d) ==> abs(f(y)) <= b + &2 * abs(f(x))` + ASSUME_TAC THENL + [MATCH_MP_TAC CONVEX_BOUNDS_LEMMA THEN CONJ_TAC THENL + [ASM_MESON_TAC[CONVEX_ON_SUBSET; SUBSET_TRANS]; ALL_TAC] THEN + REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + UNDISCH_TAC `y:real^N IN cball(x,d)` THEN REWRITE_TAC[IN_CBALL] THEN + REWRITE_TAC[IN_INTERVAL; IN_CBALL; dist] THEN DISCH_TAC THEN + SIMP_TAC[VECTOR_ADD_COMPONENT; VECTOR_SUB_COMPONENT; LAMBDA_BETA] THEN + REWRITE_TAC[REAL_ARITH `x - d <= z /\ z <= x + d <=> abs(x - z) <= d`] THEN + SIMP_TAC[GSYM VECTOR_SUB_COMPONENT] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC `norm(x - y:real^N)` THEN + ASM_SIMP_TAC[COMPONENT_LE_NORM]; + ALL_TAC] THEN + SUBGOAL_THEN `(lift o f) continuous_on (ball(x:real^N,d))` MP_TAC THENL + [MATCH_MP_TAC CONVEX_ON_BOUNDED_CONTINUOUS THEN REWRITE_TAC[OPEN_BALL] THEN + EXISTS_TAC `b + &2 * abs(f(x:real^N))` THEN + ASM_MESON_TAC[SUBSET; CONVEX_ON_SUBSET; SUBSET_TRANS; BALL_SUBSET_CBALL]; + ALL_TAC] THEN + ASM_SIMP_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_AT; OPEN_BALL; CENTRE_IN_BALL]);; + +(* ------------------------------------------------------------------------- *) +(* Characterizations of convex functions in terms of sequents. *) +(* ------------------------------------------------------------------------- *) + +let CONVEX_ON_LEFT_SECANT_MUL,CONVEX_ON_RIGHT_SECANT_MUL = (CONJ_PAIR o prove) + (`(!f s:real^N->bool. + f convex_on s <=> + !a b x. a IN s /\ b IN s /\ x IN segment[a,b] + ==> (f x - f a) * norm(b - a) <= (f b - f a) * norm(x - a)) /\ + (!f s:real^N->bool. + f convex_on s <=> + !a b x. a IN s /\ b IN s /\ x IN segment[a,b] + ==> (f b - f a) * norm(b - x) <= (f b - f x) * norm(b - a))`, + CONJ_TAC THEN + REPEAT GEN_TAC THEN REWRITE_TAC[convex_on] THEN + AP_TERM_TAC THEN GEN_REWRITE_TAC I [FUN_EQ_THM] THEN + X_GEN_TAC `a:real^N` THEN REWRITE_TAC[] THEN + AP_TERM_TAC THEN GEN_REWRITE_TAC I [FUN_EQ_THM] THEN + X_GEN_TAC `b:real^N` THEN REWRITE_TAC[] THEN + ASM_CASES_TAC `(a:real^N) IN s` THEN ASM_REWRITE_TAC[] THEN + ASM_CASES_TAC `(b:real^N) IN s` THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[IN_SEGMENT; LEFT_IMP_EXISTS_THM] THEN + ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN + AP_TERM_TAC THEN GEN_REWRITE_TAC I [FUN_EQ_THM] THEN + X_GEN_TAC `u:real` THEN REWRITE_TAC[] THEN + REWRITE_TAC[TAUT `a /\ x = y <=> x = y /\ a`; + TAUT `a /\ x = y /\ b <=> x = y /\ a /\ b`] THEN + REWRITE_TAC[REAL_ARITH `v + u = &1 <=> v = &1 - u`] THEN + REWRITE_TAC[FORALL_UNWIND_THM2; IMP_CONJ] THEN + REWRITE_TAC[REAL_SUB_LE] THEN + ASM_CASES_TAC `&0 <= u` THEN ASM_REWRITE_TAC[] THEN + ASM_CASES_TAC `u <= &1` THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[VECTOR_ARITH `((&1 - u) % a + u % b) - a:real^N = u % (b - a)`; + VECTOR_ARITH `b - ((&1 - u) % a + u % b):real^N = (&1 - u) % (b - a)`] THEN + REWRITE_TAC[NORM_MUL; REAL_MUL_ASSOC] THEN + (ASM_CASES_TAC `b:real^N = a` THENL + [ASM_REWRITE_TAC[VECTOR_SUB_REFL; REAL_SUB_REFL; + VECTOR_ARITH `(&1 - u) % a + u % a:real^N = a`] THEN + REAL_ARITH_TAC; + ASM_SIMP_TAC[REAL_LE_RMUL_EQ; NORM_POS_LT; VECTOR_SUB_EQ] THEN + ASM_SIMP_TAC[REAL_ARITH + `&0 <= u /\ u <= &1 ==> abs u = u /\ abs(&1 - u) = &1 - u`] THEN + REAL_ARITH_TAC]));; + +let CONVEX_ON_LEFT_SECANT,CONVEX_ON_RIGHT_SECANT = (CONJ_PAIR o prove) + (`(!f s:real^N->bool. + f convex_on s <=> + !a b x. a IN s /\ b IN s /\ x IN segment(a,b) + ==> (f x - f a) / norm(x - a) <= (f b - f a) / norm(b - a)) /\ + (!f s:real^N->bool. + f convex_on s <=> + !a b x. a IN s /\ b IN s /\ x IN segment(a,b) + ==> (f b - f a) / norm(b - a) <= (f b - f x) / norm(b - x))`, + CONJ_TAC THEN REPEAT GEN_TAC THENL + [REWRITE_TAC[CONVEX_ON_LEFT_SECANT_MUL]; + REWRITE_TAC[CONVEX_ON_RIGHT_SECANT_MUL]] THEN + AP_TERM_TAC THEN GEN_REWRITE_TAC I [FUN_EQ_THM] THEN + X_GEN_TAC `a:real^N` THEN REWRITE_TAC[] THEN + AP_TERM_TAC THEN GEN_REWRITE_TAC I [FUN_EQ_THM] THEN + X_GEN_TAC `b:real^N` THEN REWRITE_TAC[] THEN + ASM_CASES_TAC `(a:real^N) IN s` THEN ASM_REWRITE_TAC[] THEN + ASM_CASES_TAC `(b:real^N) IN s` THEN ASM_REWRITE_TAC[] THEN + ASM_CASES_TAC `a:real^N = b` THEN + ASM_REWRITE_TAC[SEGMENT_REFL; NOT_IN_EMPTY; REAL_SUB_REFL; VECTOR_SUB_REFL; + NORM_0; REAL_MUL_LZERO; REAL_MUL_RZERO; REAL_LE_REFL] THEN + AP_TERM_TAC THEN GEN_REWRITE_TAC I [FUN_EQ_THM] THEN + X_GEN_TAC `x:real^N` THEN REWRITE_TAC[] THEN + REWRITE_TAC[open_segment; IN_DIFF; IN_INSERT; NOT_IN_EMPTY] THEN + MAP_EVERY ASM_CASES_TAC [`x:real^N = a`; `x:real^N = b`] THEN + ASM_REWRITE_TAC[REAL_LE_REFL; REAL_SUB_REFL; VECTOR_SUB_REFL; NORM_0; + REAL_MUL_LZERO; REAL_MUL_RZERO] THEN + ASM_SIMP_TAC[REAL_LE_RDIV_EQ; GSYM REAL_LE_LDIV_EQ; NORM_POS_LT; + VECTOR_SUB_EQ] THEN + AP_TERM_TAC THEN REAL_ARITH_TAC);; + +(* ------------------------------------------------------------------------- *) +(* Starlike sets and more stuff about line segments. *) +(* ------------------------------------------------------------------------- *) + +let starlike = new_definition + `starlike s <=> ?a. a IN s /\ !x. x IN s ==> segment[a,x] SUBSET s`;; + +let CONVEX_CONTAINS_SEGMENT = prove + (`!s. convex s <=> !a b. a IN s /\ b IN s ==> segment[a,b] SUBSET s`, + REWRITE_TAC[CONVEX_ALT; segment; SUBSET; IN_ELIM_THM] THEN MESON_TAC[]);; + +let CONVEX_CONTAINS_SEGMENT_EQ = prove + (`!s:real^N->bool. + convex s <=> !a b. segment[a,b] SUBSET s <=> a IN s /\ b IN s`, + REWRITE_TAC[CONVEX_CONTAINS_SEGMENT; SUBSET] THEN + MESON_TAC[ENDS_IN_SEGMENT]);; + +let CONVEX_CONTAINS_SEGMENT_IMP = prove + (`!s a b. convex s ==> (segment[a,b] SUBSET s <=> a IN s /\ b IN s)`, + SIMP_TAC[CONVEX_CONTAINS_SEGMENT_EQ]);; + +let CONVEX_IMP_STARLIKE = prove + (`!s. convex s /\ ~(s = {}) ==> starlike s`, + REWRITE_TAC[CONVEX_CONTAINS_SEGMENT; starlike; GSYM MEMBER_NOT_EMPTY] THEN + MESON_TAC[]);; + +let SEGMENT_CONVEX_HULL = prove + (`!a b. segment[a,b] = convex hull {a,b}`, + REPEAT GEN_TAC THEN + SIMP_TAC[CONVEX_HULL_INSERT; CONVEX_HULL_SING; NOT_INSERT_EMPTY] THEN + REWRITE_TAC[IN_SING; RIGHT_EXISTS_AND_THM; UNWIND_THM2] THEN + REWRITE_TAC[segment; EXTENSION; IN_ELIM_THM] THEN + REWRITE_TAC[REAL_ARITH `u + v = &1 <=> u = &1 - v`] THEN + REWRITE_TAC[RIGHT_AND_EXISTS_THM] THEN + ONCE_REWRITE_TAC[TAUT `a /\ b /\ c /\ d <=> c /\ a /\ b /\ d`] THEN + ONCE_REWRITE_TAC[SWAP_EXISTS_THM] THEN REWRITE_TAC[UNWIND_THM2] THEN + REWRITE_TAC[REAL_LE_SUB_LADD; REAL_ADD_LID] THEN MESON_TAC[]);; + +let SEGMENT_FURTHEST_LE = prove + (`!a b x y:real^N. + x IN segment[a,b] ==> norm(y - x) <= norm(y - a) \/ + norm(y - x) <= norm(y - b)`, + REWRITE_TAC[SEGMENT_CONVEX_HULL] THEN REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`y:real^N`; `{a:real^N,b}`] SIMPLEX_FURTHEST_LE) THEN + ASM_REWRITE_TAC[FINITE_INSERT; FINITE_RULES; NOT_INSERT_EMPTY] THEN + REWRITE_TAC[IN_INSERT; NOT_IN_EMPTY] THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `x:real^N`) THEN + ASM_MESON_TAC[NORM_SUB]);; + +let SEGMENT_BOUND = prove + (`!a b x:real^N. + x IN segment[a,b] ==> norm(x - a) <= norm(b - a) /\ + norm(x - b) <= norm(b - a)`, + REPEAT STRIP_TAC THEN + MP_TAC(SPECL [`a:real^N`; `b:real^N`; `x:real^N`] SEGMENT_FURTHEST_LE) THENL + [DISCH_THEN(MP_TAC o SPEC `a:real^N`); + DISCH_THEN(MP_TAC o SPEC `b:real^N`)] THEN + REWRITE_TAC[VECTOR_SUB_REFL; NORM_0] THEN + ASM_MESON_TAC[NORM_POS_LE; REAL_LE_TRANS; NORM_SUB]);; + +let BETWEEN_IN_CONVEX_HULL = prove + (`!x a b:real^N. between x (a,b) <=> x IN convex hull {a,b}`, + REWRITE_TAC[BETWEEN_IN_SEGMENT; SEGMENT_CONVEX_HULL]);; + +let STARLIKE_LINEAR_IMAGE = prove + (`!f s. starlike s /\ linear f ==> starlike(IMAGE f s)`, + REWRITE_TAC[starlike; FORALL_IN_IMAGE; EXISTS_IN_IMAGE] THEN + SIMP_TAC[CLOSED_SEGMENT_LINEAR_IMAGE] THEN SET_TAC[]);; + +let STARLIKE_LINEAR_IMAGE_EQ = prove + (`!f s. linear f /\ (!x y. f x = f y ==> x = y) + ==> (starlike (IMAGE f s) <=> starlike s)`, + MATCH_ACCEPT_TAC(LINEAR_INVARIANT_RULE STARLIKE_LINEAR_IMAGE));; + +add_linear_invariants [STARLIKE_LINEAR_IMAGE_EQ];; + +let STARLIKE_TRANSLATION_EQ = prove + (`!a s. starlike (IMAGE (\x. a + x) s) <=> starlike s`, + REWRITE_TAC[starlike] THEN GEOM_TRANSLATE_TAC[]);; + +add_translation_invariants [STARLIKE_TRANSLATION_EQ];; + +let BETWEEN_LINEAR_IMAGE_EQ = prove + (`!f x y z. linear f /\ (!x y. f x = f y ==> x = y) + ==> (between (f x) (f y,f z) <=> between x (y,z))`, + SIMP_TAC[BETWEEN_IN_SEGMENT; CLOSED_SEGMENT_LINEAR_IMAGE] THEN SET_TAC[]);; + +add_linear_invariants [BETWEEN_LINEAR_IMAGE_EQ];; + +let BETWEEN_TRANSLATION = prove + (`!a x y. between (a + x) (a + y,a + z) <=> between x (y,z)`, + REWRITE_TAC[between] THEN NORM_ARITH_TAC);; + +add_translation_invariants [STARLIKE_TRANSLATION_EQ];; + +let STARLIKE_CLOSURE = prove + (`!s:real^N->bool. starlike s ==> starlike(closure s)`, + GEN_TAC THEN REWRITE_TAC[starlike; SUBSET; segment; FORALL_IN_GSPEC] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `a:real^N` THEN + STRIP_TAC THEN ASM_SIMP_TAC[REWRITE_RULE[SUBSET] CLOSURE_SUBSET] THEN + X_GEN_TAC `x:real^N` THEN REWRITE_TAC[SUBSET; CLOSURE_APPROACHABLE] THEN + DISCH_TAC THEN X_GEN_TAC `u:real` THEN STRIP_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_THEN `y:real^N` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `(&1 - u) % a + u % y:real^N` THEN + ASM_SIMP_TAC[dist; NORM_MUL; VECTOR_ARITH + `(v % a + u % y) - (v % a + u % z):real^N = u % (y - z)`] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ_ALT] + REAL_LET_TRANS)) THEN + REWRITE_TAC[dist; REAL_ARITH `u * n <= n <=> &0 <= n * (&1 - u)`] THEN + MATCH_MP_TAC REAL_LE_MUL THEN REWRITE_TAC[NORM_POS_LE] THEN + ASM_REAL_ARITH_TAC);; + +let STARLIKE_UNIV = prove + (`starlike(:real^N)`, + MESON_TAC[CONVEX_IMP_STARLIKE; CONVEX_UNIV; + BOUNDED_EMPTY; NOT_BOUNDED_UNIV]);; + +let STARLIKE_PCROSS = prove + (`!s:real^M->bool t:real^N->bool. + starlike s /\ starlike t ==> starlike(s PCROSS t)`, + SIMP_TAC[starlike; EXISTS_IN_PCROSS; SUBSET; IN_SEGMENT] THEN + REPEAT GEN_TAC THEN REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN + REWRITE_TAC[FORALL_IN_PCROSS; IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN + REWRITE_TAC[FORALL_UNWIND_THM2; IMP_IMP] THEN + REWRITE_TAC[GSYM PASTECART_CMUL; PASTECART_ADD] THEN + REWRITE_TAC[PASTECART_IN_PCROSS] THEN MESON_TAC[]);; + +let STARLIKE_PCROSS_EQ = prove + (`!s:real^M->bool t:real^N->bool. + starlike(s PCROSS t) <=> starlike s /\ starlike t`, + REPEAT GEN_TAC THEN + ASM_CASES_TAC `s:real^M->bool = {}` THENL + [ASM_REWRITE_TAC[PCROSS_EMPTY] THEN MESON_TAC[starlike; NOT_IN_EMPTY]; + ALL_TAC] THEN + ASM_CASES_TAC `t:real^N->bool = {}` THENL + [ASM_REWRITE_TAC[PCROSS_EMPTY] THEN MESON_TAC[starlike; NOT_IN_EMPTY]; + ALL_TAC] THEN + EQ_TAC THEN REWRITE_TAC[STARLIKE_PCROSS] THEN REPEAT STRIP_TAC THENL + [MP_TAC(ISPECL [`fstcart:real^(M,N)finite_sum->real^M`; + `(s:real^M->bool) PCROSS (t:real^N->bool)`] STARLIKE_LINEAR_IMAGE) THEN + ASM_REWRITE_TAC[LINEAR_FSTCART]; + MP_TAC(ISPECL [`sndcart:real^(M,N)finite_sum->real^N`; + `(s:real^M->bool) PCROSS (t:real^N->bool)`] STARLIKE_LINEAR_IMAGE) THEN + ASM_REWRITE_TAC[LINEAR_SNDCART]] THEN + MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN + REWRITE_TAC[EXTENSION; IN_IMAGE; EXISTS_PASTECART; PASTECART_IN_PCROSS; + FSTCART_PASTECART; SNDCART_PASTECART] THEN + ASM SET_TAC[]);; + +let BETWEEN_DIST_LT = prove + (`!r a b c:real^N. + dist(c,a) < r /\ dist(c,b) < r /\ between x (a,b) ==> dist(c,x) < r`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN `convex hull {a,b} SUBSET ball(c:real^N,r)` MP_TAC THENL + [MATCH_MP_TAC HULL_MINIMAL THEN + ASM_REWRITE_TAC[CONVEX_BALL; INSERT_SUBSET; EMPTY_SUBSET; IN_BALL]; + ASM_SIMP_TAC[SUBSET; GSYM BETWEEN_IN_CONVEX_HULL; IN_BALL]]);; + +let BETWEEN_DIST_LE = prove + (`!r a b c:real^N. + dist(c,a) <= r /\ dist(c,b) <= r /\ between x (a,b) ==> dist(c,x) <= r`, + + REPEAT STRIP_TAC THEN + SUBGOAL_THEN `convex hull {a,b} SUBSET cball(c:real^N,r)` MP_TAC THENL + [MATCH_MP_TAC HULL_MINIMAL THEN + ASM_REWRITE_TAC[CONVEX_CBALL; INSERT_SUBSET; EMPTY_SUBSET; IN_CBALL]; + ASM_SIMP_TAC[SUBSET; GSYM BETWEEN_IN_CONVEX_HULL; IN_CBALL]]);; + +let BETWEEN_NORM_LT = prove + (`!r a b x:real^N. + norm a < r /\ norm b < r /\ between x (a,b) ==> norm x < r`, + REWRITE_TAC[GSYM(CONJUNCT2(SPEC_ALL DIST_0)); BETWEEN_DIST_LT]);; + +let BETWEEN_NORM_LE = prove + (`!r a b x:real^N. + norm a <= r /\ norm b <= r /\ between x (a,b) ==> norm x <= r`, + REWRITE_TAC[GSYM(CONJUNCT2(SPEC_ALL DIST_0)); BETWEEN_DIST_LE]);; + +(* ------------------------------------------------------------------------- *) +(* Shrinking towards the interior of a convex set. *) +(* ------------------------------------------------------------------------- *) + +let IN_INTERIOR_CONVEX_SHRINK = prove + (`!s e x c:real^N. + convex s /\ c IN interior s /\ + x IN s /\ &0 < e /\ e <= &1 + ==> x - e % (x - c) IN interior s`, + REPEAT STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_INTERIOR]) THEN + REWRITE_TAC[IN_INTERIOR; SUBSET; IN_BALL; dist] THEN + DISCH_THEN(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `e * d:real` THEN ASM_SIMP_TAC[REAL_LT_MUL] THEN + X_GEN_TAC `y':real^N` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `(&1 / e) % y' - ((&1 - e) / e) % x:real^N`) THEN + ANTS_TAC THENL + [UNDISCH_TAC `norm (x - e % (x - c) - y':real^N) < e * d` THEN + SUBGOAL_THEN `x - e % (x - c) - y':real^N = + e % (c - (&1 / e % y' - (&1 - e) / e % x))` + SUBST1_TAC THENL + [ASM_SIMP_TAC[VECTOR_SUB_LDISTRIB; VECTOR_MUL_ASSOC; + REAL_DIV_LMUL; REAL_LT_IMP_NZ] THEN VECTOR_ARITH_TAC; + ASM_SIMP_TAC[NORM_MUL; REAL_LT_LMUL_EQ; real_abs; REAL_LT_IMP_LE]]; + DISCH_TAC THEN + SUBGOAL_THEN `y' = (&1 - (&1 - e)) % (&1 / e % y' - (&1 - e) / e % x) + + (&1 - e) % x:real^N` + SUBST1_TAC THENL + [ASM_SIMP_TAC[REAL_ARITH `&1 - (&1 - e) = e`; VECTOR_SUB_LDISTRIB; + VECTOR_MUL_ASSOC; REAL_DIV_LMUL; REAL_LT_IMP_NZ] THEN + VECTOR_ARITH_TAC; + FIRST_X_ASSUM(MATCH_MP_TAC o GEN_REWRITE_RULE I [CONVEX_ALT]) THEN + ASM_REWRITE_TAC[] THEN ASM_REAL_ARITH_TAC]]);; + +let IN_INTERIOR_CLOSURE_CONVEX_SHRINK = prove + (`!s e x c:real^N. + convex s /\ c IN interior s /\ + x IN closure s /\ &0 < e /\ e <= &1 + ==> x - e % (x - c) IN interior s`, + REPEAT STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_INTERIOR]) THEN + DISCH_THEN(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN `?y:real^N. y IN s /\ norm(y - x) * (&1 - e) < e * d` + STRIP_ASSUME_TAC THENL + [ASM_CASES_TAC `(x:real^N) IN s` THENL + [EXISTS_TAC `x:real^N` THEN + ASM_SIMP_TAC[REAL_LT_MUL; VECTOR_SUB_REFL; NORM_0; REAL_MUL_LZERO]; + ALL_TAC] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE RAND_CONV [closure]) THEN + ASM_REWRITE_TAC[IN_UNION; IN_ELIM_THM; LIMPT_APPROACHABLE; dist] THEN + FIRST_ASSUM(DISJ_CASES_TAC o MATCH_MP (REAL_ARITH + `e <= &1 ==> e = &1 \/ e < &1`)) THEN + ASM_SIMP_TAC[REAL_SUB_REFL; GSYM REAL_LT_RDIV_EQ; REAL_SUB_LT] THENL + [DISCH_THEN(MP_TAC o SPEC `&1`) THEN + REWRITE_TAC[REAL_MUL_RZERO; REAL_LT_01]; + DISCH_THEN(MP_TAC o SPEC `(e * d) / (&1 - e)`)] THEN + ASM_SIMP_TAC[REAL_LT_RDIV_EQ; REAL_SUB_LT; REAL_MUL_LZERO; REAL_LT_MUL; + REAL_MUL_LID] THEN + MATCH_MP_TAC MONO_EXISTS THEN MESON_TAC[]; + ALL_TAC] THEN + ABBREV_TAC `z:real^N = c + ((&1 - e) / e) % (x - y)` THEN + SUBGOAL_THEN `x - e % (x - c):real^N = y - e % (y - z)` SUBST1_TAC THENL + [EXPAND_TAC "z" THEN + REWRITE_TAC[VECTOR_SUB_LDISTRIB; VECTOR_ADD_LDISTRIB] THEN + ASM_SIMP_TAC[VECTOR_MUL_ASSOC; REAL_DIV_LMUL; REAL_LT_IMP_NZ] THEN + VECTOR_ARITH_TAC; + ALL_TAC] THEN + MATCH_MP_TAC IN_INTERIOR_CONVEX_SHRINK THEN ASM_REWRITE_TAC[] THEN + FIRST_ASSUM(MATCH_MP_TAC o REWRITE_RULE[SUBSET] o + MATCH_MP SUBSET_INTERIOR) THEN + SIMP_TAC[INTERIOR_OPEN; OPEN_BALL] THEN + REWRITE_TAC[IN_BALL; dist] THEN EXPAND_TAC "z" THEN + REWRITE_TAC[NORM_ARITH `norm(c - (c + x)) = norm(x)`] THEN + REWRITE_TAC[NORM_MUL; REAL_ABS_DIV] THEN + ASM_SIMP_TAC[real_abs; REAL_LT_IMP_LE; REAL_SUB_LE] THEN + ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN + REWRITE_TAC[real_div; REAL_MUL_ASSOC] THEN + ASM_SIMP_TAC[GSYM real_div; REAL_LT_LDIV_EQ] THEN + ASM_MESON_TAC[REAL_MUL_SYM; NORM_SUB]);; + +let IN_INTERIOR_CLOSURE_CONVEX_SEGMENT = prove + (`!s a b:real^N. + convex s /\ a IN interior s /\ b IN closure s + ==> segment(a,b) SUBSET interior s`, + REWRITE_TAC[SUBSET; IN_SEGMENT] THEN REPEAT STRIP_TAC THEN + ASM_REWRITE_TAC[VECTOR_ARITH + `(&1 - u) % a + u % b:real^N = b - (&1 - u) % (b - a)`] THEN + MATCH_MP_TAC IN_INTERIOR_CLOSURE_CONVEX_SHRINK THEN + ASM_REWRITE_TAC[] THEN ASM_REAL_ARITH_TAC);; + +(* ------------------------------------------------------------------------- *) +(* Relative interior of a set. *) +(* ------------------------------------------------------------------------- *) + +let relative_interior = new_definition + `relative_interior s = + {x | ?t. open_in (subtopology euclidean (affine hull s)) t /\ + x IN t /\ t SUBSET s}`;; + +let relative_frontier = new_definition + `relative_frontier s = closure s DIFF relative_interior s`;; + +let RELATIVE_INTERIOR = prove + (`!s. relative_interior s = + {x | x IN s /\ + ?t. open t /\ x IN t /\ t INTER (affine hull s) SUBSET s}`, + REWRITE_TAC[EXTENSION; relative_interior; IN_ELIM_THM] THEN + REPEAT GEN_TAC THEN REWRITE_TAC[OPEN_IN_OPEN; LEFT_AND_EXISTS_THM] THEN + ONCE_REWRITE_TAC[SWAP_EXISTS_THM] THEN + ONCE_REWRITE_TAC[TAUT `(a /\ b) /\ c /\ d <=> b /\ a /\ c /\ d`] THEN + REWRITE_TAC[UNWIND_THM2; SUBSET; IN_INTER; RIGHT_AND_EXISTS_THM] THEN + AP_TERM_TAC THEN ABS_TAC THEN MESON_TAC[HULL_INC]);; + +let RELATIVE_INTERIOR_EQ = prove + (`!s. relative_interior s = s <=> + open_in(subtopology euclidean (affine hull s)) s`, + GEN_TAC THEN REWRITE_TAC[EXTENSION; relative_interior; IN_ELIM_THM] THEN + GEN_REWRITE_TAC RAND_CONV [OPEN_IN_SUBOPEN] THEN MESON_TAC[SUBSET]);; + +let RELATIVE_INTERIOR_OPEN_IN = prove + (`!s. open_in(subtopology euclidean (affine hull s)) s + ==> relative_interior s = s`, + REWRITE_TAC[RELATIVE_INTERIOR_EQ]);; + +let RELATIVE_INTERIOR_EMPTY = prove + (`relative_interior {} = {}`, + SIMP_TAC[RELATIVE_INTERIOR_OPEN_IN; OPEN_IN_EMPTY]);; + +let RELATIVE_FRONTIER_EMPTY = prove + (`relative_frontier {} = {}`, + REWRITE_TAC[relative_frontier; CLOSURE_EMPTY; EMPTY_DIFF]);; + +let RELATIVE_INTERIOR_AFFINE = prove + (`!s:real^N->bool. affine s ==> relative_interior s = s`, + SIMP_TAC[RELATIVE_INTERIOR_EQ; OPEN_IN_SUBTOPOLOGY_REFL; HULL_P] THEN + REWRITE_TAC[TOPSPACE_EUCLIDEAN; SUBSET_UNIV]);; + +let RELATIVE_INTERIOR_UNIV = prove + (`!s. relative_interior(affine hull s) = affine hull s`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC RELATIVE_INTERIOR_OPEN_IN THEN + REWRITE_TAC[HULL_HULL; OPEN_IN_SUBTOPOLOGY_REFL] THEN + REWRITE_TAC[TOPSPACE_EUCLIDEAN; SUBSET_UNIV]);; + +let OPEN_IN_RELATIVE_INTERIOR = prove + (`!s. open_in (subtopology euclidean (affine hull s)) + (relative_interior s)`, + GEN_TAC THEN REWRITE_TAC[relative_interior] THEN + GEN_REWRITE_TAC I [OPEN_IN_SUBOPEN] THEN + REWRITE_TAC[SUBSET; IN_ELIM_THM] THEN MESON_TAC[]);; + +let RELATIVE_INTERIOR_SUBSET = prove + (`!s. (relative_interior s) SUBSET s`, + REWRITE_TAC[SUBSET; relative_interior; IN_ELIM_THM] THEN MESON_TAC[]);; + +let SUBSET_RELATIVE_INTERIOR = prove + (`!s t. s SUBSET t /\ affine hull s = affine hull t + ==> (relative_interior s) SUBSET (relative_interior t)`, + REWRITE_TAC[relative_interior; SUBSET; IN_ELIM_THM] THEN MESON_TAC[]);; + +let RELATIVE_INTERIOR_MAXIMAL = prove + (`!s t. t SUBSET s /\ + open_in(subtopology euclidean (affine hull s)) t + ==> t SUBSET (relative_interior s)`, + REWRITE_TAC[relative_interior; SUBSET; IN_ELIM_THM] THEN MESON_TAC[]);; + +let RELATIVE_INTERIOR_UNIQUE = prove + (`!s t. t SUBSET s /\ + open_in(subtopology euclidean (affine hull s)) t /\ + (!t'. t' SUBSET s /\ + open_in(subtopology euclidean (affine hull s)) t' + ==> t' SUBSET t) + ==> (relative_interior s = t)`, + MESON_TAC[SUBSET_ANTISYM; RELATIVE_INTERIOR_MAXIMAL; RELATIVE_INTERIOR_SUBSET; + OPEN_IN_RELATIVE_INTERIOR]);; + +let IN_RELATIVE_INTERIOR = prove + (`!x:real^N s. + x IN relative_interior s <=> + x IN s /\ ?e. &0 < e /\ (ball(x,e) INTER (affine hull s)) SUBSET s`, + REPEAT GEN_TAC THEN REWRITE_TAC[relative_interior; IN_ELIM_THM] THEN + REWRITE_TAC[OPEN_IN_OPEN; LEFT_AND_EXISTS_THM] THEN + ONCE_REWRITE_TAC[SWAP_EXISTS_THM] THEN + ONCE_REWRITE_TAC[TAUT `(a /\ b) /\ c /\ d <=> b /\ a /\ c /\ d`] THEN + REWRITE_TAC[UNWIND_THM2; SUBSET; IN_INTER] THEN EQ_TAC THENL + [ASM_MESON_TAC[SUBSET; OPEN_CONTAINS_BALL]; + STRIP_TAC THEN EXISTS_TAC `ball(x:real^N,e)` THEN + ASM_SIMP_TAC[OPEN_BALL; CENTRE_IN_BALL; HULL_INC]]);; + +let IN_RELATIVE_INTERIOR_CBALL = prove + (`!x:real^N s. + x IN relative_interior s <=> + x IN s /\ ?e. &0 < e /\ (cball(x,e) INTER affine hull s) SUBSET s`, + REPEAT GEN_TAC THEN REWRITE_TAC[IN_RELATIVE_INTERIOR] THEN + AP_TERM_TAC THEN EQ_TAC THEN + DISCH_THEN(X_CHOOSE_THEN `e:real` STRIP_ASSUME_TAC) THENL + [EXISTS_TAC `e / &2` THEN ASM_REWRITE_TAC[REAL_HALF] THEN + MATCH_MP_TAC SUBSET_TRANS THEN + EXISTS_TAC `ball(x:real^N,e) INTER affine hull s` THEN + ASM_REWRITE_TAC[] THEN + REWRITE_TAC[SUBSET; IN_INTER; IN_BALL; IN_CBALL] THEN + ASM_SIMP_TAC[REAL_ARITH `&0 < e /\ x <= e / &2 ==> x < e`]; + EXISTS_TAC `e:real` THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC SUBSET_TRANS THEN + EXISTS_TAC `cball(x:real^N,e) INTER affine hull s` THEN + ASM_REWRITE_TAC[] THEN + SIMP_TAC[SUBSET; IN_INTER; IN_BALL; IN_CBALL; REAL_LT_IMP_LE]]);; + +let OPEN_IN_SUBSET_RELATIVE_INTERIOR = prove + (`!s t. open_in(subtopology euclidean (affine hull t)) s + ==> (s SUBSET relative_interior t <=> s SUBSET t)`, + MESON_TAC[RELATIVE_INTERIOR_MAXIMAL; RELATIVE_INTERIOR_SUBSET; + SUBSET_TRANS]);; + +let RELATIVE_INTERIOR_TRANSLATION = prove + (`!a:real^N s. + relative_interior (IMAGE (\x. a + x) s) = + IMAGE (\x. a + x) (relative_interior s)`, + REWRITE_TAC[relative_interior; OPEN_IN_OPEN] THEN GEOM_TRANSLATE_TAC[]);; + +add_translation_invariants [RELATIVE_INTERIOR_TRANSLATION];; + +let RELATIVE_FRONTIER_TRANSLATION = prove + (`!a:real^N s. + relative_frontier (IMAGE (\x. a + x) s) = + IMAGE (\x. a + x) (relative_frontier s)`, + REWRITE_TAC[relative_frontier] THEN GEOM_TRANSLATE_TAC[]);; + +add_translation_invariants [RELATIVE_FRONTIER_TRANSLATION];; + +let RELATIVE_INTERIOR_INJECTIVE_LINEAR_IMAGE = prove + (`!f:real^M->real^N s. + linear f /\ (!x y. f x = f y ==> x = y) + ==> relative_interior(IMAGE f s) = IMAGE f (relative_interior s)`, + REPEAT GEN_TAC THEN DISCH_TAC THEN + ASM_SIMP_TAC[relative_interior; AFFINE_HULL_LINEAR_IMAGE] THEN + ONCE_REWRITE_TAC[TAUT `a /\ b /\ c <=> c /\ a /\ b`] THEN + REWRITE_TAC[EXISTS_SUBSET_IMAGE] THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP OPEN_IN_INJECTIVE_LINEAR_IMAGE) THEN + ASM_REWRITE_TAC[] THEN ASM SET_TAC[]);; + +add_linear_invariants [RELATIVE_INTERIOR_INJECTIVE_LINEAR_IMAGE];; + +let RELATIVE_FRONTIER_INJECTIVE_LINEAR_IMAGE = prove + (`!f:real^M->real^N s. + linear f /\ (!x y. f x = f y ==> x = y) + ==> relative_frontier(IMAGE f s) = IMAGE f (relative_frontier s)`, + REWRITE_TAC[relative_frontier] THEN GEOM_TRANSFORM_TAC[]);; + +add_linear_invariants [RELATIVE_FRONTIER_INJECTIVE_LINEAR_IMAGE];; + +let RELATIVE_INTERIOR_EQ_EMPTY = prove + (`!s:real^N->bool. + convex s ==> (relative_interior s = {} <=> s = {})`, + SUBGOAL_THEN + `!s:real^N->bool. + vec 0 IN s /\ convex s ==> ~(relative_interior s = {})` + ASSUME_TAC THENL + [ALL_TAC; + GEN_TAC THEN DISCH_TAC THEN + ASM_CASES_TAC `s:real^N->bool = {}` THEN + ASM_REWRITE_TAC[RELATIVE_INTERIOR_EMPTY] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN + DISCH_THEN(X_CHOOSE_TAC `a:real^N`) THEN + FIRST_X_ASSUM(MP_TAC o SPEC `IMAGE (\x:real^N. --a + x) s`) THEN + REWRITE_TAC[CONVEX_TRANSLATION_EQ; RELATIVE_INTERIOR_TRANSLATION] THEN + ASM_REWRITE_TAC[IMAGE_EQ_EMPTY; IN_IMAGE] THEN + DISCH_THEN MATCH_MP_TAC THEN EXISTS_TAC `a:real^N` THEN + ASM_REWRITE_TAC[] THEN VECTOR_ARITH_TAC] THEN + GEN_TAC THEN STRIP_TAC THEN + REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; IN_RELATIVE_INTERIOR] THEN + ASM_SIMP_TAC[AFFINE_HULL_EQ_SPAN; HULL_INC] THEN + X_CHOOSE_THEN `b:real^N->bool` STRIP_ASSUME_TAC + (ISPEC `s:real^N->bool` BASIS_EXISTS) THEN + SUBGOAL_THEN `span(s:real^N->bool) = span b` SUBST_ALL_TAC THENL + [ASM_SIMP_TAC[SPAN_EQ] THEN ASM_MESON_TAC[SPAN_INC; SUBSET_TRANS]; + ALL_TAC] THEN + RULE_ASSUM_TAC(REWRITE_RULE[HAS_SIZE]) THEN + ABBREV_TAC `n = dim(s:real^N->bool)` THEN + SUBGOAL_THEN + `!c. (!v. v IN b ==> &0 <= c(v)) /\ sum b c <= &1 + ==> vsum b (\v:real^N. c(v) % v) IN s` + ASSUME_TAC THENL + [REPEAT STRIP_TAC THEN SUBGOAL_THEN + `vsum (vec 0 INSERT b :real^N->bool) + (\v. (if v = vec 0 then &1 - sum b c else c v) % v) IN s` + MP_TAC THENL + [FIRST_X_ASSUM(MATCH_MP_TAC o GEN_REWRITE_RULE I [CONVEX_EXPLICIT]) THEN + ASM_SIMP_TAC[INSERT_SUBSET; FINITE_INSERT; SUM_CLAUSES; + INDEPENDENT_NONZERO; IN_INSERT] THEN + CONJ_TAC THENL [ASM_MESON_TAC[REAL_SUB_LE]; ALL_TAC] THEN + REWRITE_TAC[REAL_ARITH `&1 - x + y = &1 <=> x = y`] THEN + MATCH_MP_TAC SUM_EQ THEN ASM_MESON_TAC[INDEPENDENT_NONZERO]; + MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_TERM_TAC THEN + ASM_SIMP_TAC[VSUM_CLAUSES; INDEPENDENT_NONZERO] THEN + REWRITE_TAC[VECTOR_MUL_RZERO; VECTOR_ADD_LID] THEN + MATCH_MP_TAC VSUM_EQ THEN ASM_MESON_TAC[INDEPENDENT_NONZERO]]; + ALL_TAC] THEN + ABBREV_TAC `a:real^N = vsum b (\v. inv(&2 * &n + &1) % v)` THEN + EXISTS_TAC `a:real^N` THEN CONJ_TAC THENL + [EXPAND_TAC "a" THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_SIMP_TAC[SUM_CONST; REAL_LE_INV_EQ; REAL_ARITH `&0 < &2 * &n + &1`; + GSYM real_div; REAL_LT_IMP_LE; REAL_LE_LDIV_EQ] THEN + REAL_ARITH_TAC; + ALL_TAC] THEN + MP_TAC(ISPECL [`b:real^N->bool`; `inv(&2 * &n + &1)`] + BASIS_COORDINATES_CONTINUOUS) THEN + ASM_REWRITE_TAC[REAL_LT_INV_EQ] THEN + ANTS_TAC THENL [REAL_ARITH_TAC; ALL_TAC] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `d:real` THEN STRIP_TAC THEN + ASM_SIMP_TAC[SUBSET; IN_INTER; IMP_CONJ_ALT] THEN + ASM_SIMP_TAC[SPAN_FINITE; LEFT_IMP_EXISTS_THM; IN_ELIM_THM] THEN + GEN_TAC THEN X_GEN_TAC `u:real^N->real` THEN + DISCH_THEN(SUBST1_TAC o SYM) THEN REWRITE_TAC[IN_BALL; dist] THEN + EXPAND_TAC "a" THEN ASM_SIMP_TAC[GSYM VSUM_SUB] THEN + DISCH_THEN(fun th -> FIRST_X_ASSUM MATCH_MP_TAC THEN MP_TAC th) THEN + REWRITE_TAC[GSYM VECTOR_SUB_RDISTRIB] THEN + DISCH_THEN(fun th -> FIRST_X_ASSUM(MP_TAC o C MATCH_MP th)) THEN + REWRITE_TAC[REAL_ARITH `abs(x - y) < x <=> &0 < y /\ abs(y) < &2 * x`] THEN + SIMP_TAC[REAL_LT_IMP_LE] THEN DISCH_TAC THEN + MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `&(CARD(b:real^N->bool)) * &2 * inv(&2 * &n + &1)` THEN + CONJ_TAC THENL + [MATCH_MP_TAC SUM_BOUND THEN + ASM_SIMP_TAC[REAL_ARITH `abs x < a ==> x <= a`]; + ASM_REWRITE_TAC[REAL_MUL_ASSOC] THEN REWRITE_TAC[GSYM real_div] THEN + ASM_SIMP_TAC[REAL_LE_LDIV_EQ; REAL_ARITH `&0 < &2 * &n + &1`] THEN + REAL_ARITH_TAC]);; + +let RELATIVE_INTERIOR_INTERIOR = prove + (`!s. affine hull s = (:real^N) + ==> relative_interior s = interior s`, + SIMP_TAC[relative_interior; interior; SUBTOPOLOGY_UNIV; OPEN_IN]);; + +let RELATIVE_INTERIOR_OPEN = prove + (`!s:real^N->bool. open s ==> relative_interior s = s`, + REPEAT STRIP_TAC THEN ASM_CASES_TAC `s:real^N->bool = {}` THEN + ASM_REWRITE_TAC[RELATIVE_INTERIOR_EMPTY] THEN + ASM_SIMP_TAC[RELATIVE_INTERIOR_INTERIOR; AFFINE_HULL_OPEN; INTERIOR_EQ]);; + +let RELATIVE_INTERIOR_NONEMPTY_INTERIOR = prove + (`!s. ~(interior s = {}) ==> relative_interior s = interior s`, + MESON_TAC[RELATIVE_INTERIOR_INTERIOR; AFFINE_HULL_NONEMPTY_INTERIOR]);; + +let RELATIVE_FRONTIER_NONEMPTY_INTERIOR = prove + (`!s. ~(interior s = {}) ==> relative_frontier s = frontier s`, + SIMP_TAC[relative_frontier; frontier; RELATIVE_INTERIOR_NONEMPTY_INTERIOR]);; + +let RELATIVE_FRONTIER_FRONTIER = prove + (`!s. affine hull s = (:real^N) ==> relative_frontier s = frontier s`, + SIMP_TAC[relative_frontier; frontier; RELATIVE_INTERIOR_INTERIOR]);; + +let AFFINE_HULL_CONVEX_HULL = prove + (`!s. affine hull (convex hull s) = affine hull s`, + GEN_TAC THEN MATCH_MP_TAC HULL_UNIQUE THEN + REWRITE_TAC[AFFINE_AFFINE_HULL; CONVEX_HULL_SUBSET_AFFINE_HULL] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC HULL_MINIMAL THEN + ASM_MESON_TAC[SUBSET_TRANS; HULL_SUBSET]);; + +let INTERIOR_SIMPLEX_NONEMPTY = prove + (`!s:real^N->bool. + independent s /\ s HAS_SIZE (dimindex(:N)) + ==> ?a. a IN interior(convex hull (vec 0 INSERT s))`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPEC `convex hull (vec 0 INSERT s):real^N->bool` + RELATIVE_INTERIOR_EQ_EMPTY) THEN + ASM_SIMP_TAC[AFFINE_HULL_CONVEX_HULL] THEN + REWRITE_TAC[CONVEX_HULL_EQ_EMPTY; CONVEX_CONVEX_HULL; NOT_INSERT_EMPTY] THEN + REWRITE_TAC[MEMBER_NOT_EMPTY] THEN MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN + AP_THM_TAC THEN AP_TERM_TAC THEN MATCH_MP_TAC RELATIVE_INTERIOR_INTERIOR THEN + SIMP_TAC[AFFINE_HULL_EQ_SPAN; IN_INSERT; HULL_INC] THEN + MATCH_MP_TAC(SET_RULE `!s. s SUBSET t /\ s = UNIV ==> t = UNIV`) THEN + EXISTS_TAC `span s:real^N->bool` THEN CONJ_TAC THENL + [MATCH_MP_TAC SPAN_MONO THEN MATCH_MP_TAC(SET_RULE + `(a INSERT s) SUBSET P hull (a INSERT s) + ==> s SUBSET P hull (a INSERT s)`) THEN REWRITE_TAC[HULL_SUBSET]; + MATCH_MP_TAC(SET_RULE `UNIV SUBSET s ==> s = UNIV`) THEN + MATCH_MP_TAC CARD_GE_DIM_INDEPENDENT THEN + ASM_REWRITE_TAC[DIM_UNIV; SUBSET_UNIV] THEN + ASM_MESON_TAC[LE_REFL;HAS_SIZE]]);; + +let INTERIOR_SUBSET_RELATIVE_INTERIOR = prove + (`!s. interior s SUBSET relative_interior s`, + REWRITE_TAC[SUBSET; IN_INTERIOR; IN_RELATIVE_INTERIOR; IN_INTER] THEN + MESON_TAC[CENTRE_IN_BALL]);; + +let CONVEX_RELATIVE_INTERIOR = prove + (`!s:real^N->bool. convex s ==> convex(relative_interior s)`, + REWRITE_TAC[CONVEX_ALT; IN_RELATIVE_INTERIOR; IN_INTER; + SUBSET; IN_BALL; dist] THEN + GEN_TAC THEN DISCH_TAC THEN REPEAT GEN_TAC THEN + REWRITE_TAC[TAUT `(a /\ b) /\ (c /\ d) /\ e ==> f <=> + a /\ c /\ e ==> b /\ d ==> f`] THEN + STRIP_TAC THEN ASM_SIMP_TAC[] THEN + MATCH_MP_TAC(MESON[] `(!d e. P d /\ Q e ==> R(min d e)) + ==> (?e. P e) /\ (?e. Q e) ==> (?e. R e)`) THEN + REPEAT GEN_TAC THEN DISCH_TAC THEN ASM_REWRITE_TAC[REAL_LT_MIN] THEN + X_GEN_TAC `z:real^N` THEN STRIP_TAC THEN + SUBST1_TAC(VECTOR_ARITH `z:real^N = + (&1 - u) % (z - u % (y - x)) + u % (z + (&1 - u) % (y - x))`) THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[] THEN + FIRST_X_ASSUM(CONJUNCTS_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + REWRITE_TAC[GSYM IMP_CONJ_ALT] THEN MATCH_MP_TAC MONO_AND THEN + CONJ_TAC THEN DISCH_THEN MATCH_MP_TAC THEN + (CONJ_TAC THENL + [FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH + `norm x < e ==> norm x = y ==> y < e`)) THEN + AP_TERM_TAC THEN VECTOR_ARITH_TAC; + REWRITE_TAC[VECTOR_ARITH `a - b % c:real^N = a + --b % c`] THEN + MATCH_MP_TAC IN_AFFINE_ADD_MUL_DIFF THEN + ASM_SIMP_TAC[AFFINE_AFFINE_HULL; HULL_INC]]));; + +let IN_RELATIVE_INTERIOR_CONVEX_SHRINK = prove + (`!s e x c:real^N. + convex s /\ c IN relative_interior s /\ + x IN s /\ &0 < e /\ e <= &1 + ==> x - e % (x - c) IN relative_interior s`, + REPEAT STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_RELATIVE_INTERIOR]) THEN + REWRITE_TAC[IN_RELATIVE_INTERIOR; SUBSET; IN_INTER; IN_BALL; dist] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + DISCH_THEN(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC) THEN CONJ_TAC THENL + [REWRITE_TAC[VECTOR_ARITH + `x - e % (x - c):real^N = (&1 - e) % x + e % c`] THEN + FIRST_ASSUM(MATCH_MP_TAC o GEN_REWRITE_RULE I [convex]) THEN + ASM_REWRITE_TAC[] THEN ASM_REAL_ARITH_TAC; + ALL_TAC] THEN + EXISTS_TAC `e * d:real` THEN ASM_SIMP_TAC[REAL_LT_MUL] THEN + X_GEN_TAC `y':real^N` THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `(&1 / e) % y' - ((&1 - e) / e) % x:real^N`) THEN + ANTS_TAC THENL + [CONJ_TAC THENL + [UNDISCH_TAC `norm (x - e % (x - c) - y':real^N) < e * d` THEN + SUBGOAL_THEN `x - e % (x - c) - y':real^N = + e % (c - (&1 / e % y' - (&1 - e) / e % x))` + SUBST1_TAC THENL + [ASM_SIMP_TAC[VECTOR_SUB_LDISTRIB; VECTOR_MUL_ASSOC; + REAL_DIV_LMUL; REAL_LT_IMP_NZ] THEN VECTOR_ARITH_TAC; + ASM_SIMP_TAC[NORM_MUL; REAL_LT_LMUL_EQ; real_abs; REAL_LT_IMP_LE]]; + REWRITE_TAC[real_div; REAL_SUB_RDISTRIB] THEN + ASM_SIMP_TAC[REAL_MUL_RINV; REAL_LT_IMP_NZ] THEN + REWRITE_TAC[VECTOR_ARITH `a % y - (b - c) % x:real^N = + (c - b) % x + a % y`] THEN + MATCH_MP_TAC(REWRITE_RULE[AFFINE_ALT] AFFINE_AFFINE_HULL) THEN + ASM_SIMP_TAC[HULL_INC]]; + DISCH_TAC THEN + SUBGOAL_THEN `y' = (&1 - (&1 - e)) % (&1 / e % y' - (&1 - e) / e % x) + + (&1 - e) % x:real^N` + SUBST1_TAC THENL + [ASM_SIMP_TAC[REAL_ARITH `&1 - (&1 - e) = e`; VECTOR_SUB_LDISTRIB; + VECTOR_MUL_ASSOC; REAL_DIV_LMUL; REAL_LT_IMP_NZ] THEN + VECTOR_ARITH_TAC; + FIRST_X_ASSUM(MATCH_MP_TAC o GEN_REWRITE_RULE I [CONVEX_ALT]) THEN + ASM_REWRITE_TAC[] THEN ASM_REAL_ARITH_TAC]]);; + +let IN_RELATIVE_INTERIOR_CLOSURE_CONVEX_SHRINK = prove + (`!s e x c:real^N. + convex s /\ c IN relative_interior s /\ + x IN closure s /\ &0 < e /\ e <= &1 + ==> x - e % (x - c) IN relative_interior s`, + REPEAT STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_RELATIVE_INTERIOR]) THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + DISCH_THEN(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN `?y:real^N. y IN s /\ norm(y - x) * (&1 - e) < e * d` + STRIP_ASSUME_TAC THENL + [ASM_CASES_TAC `(x:real^N) IN s` THENL + [EXISTS_TAC `x:real^N` THEN + ASM_SIMP_TAC[REAL_LT_MUL; VECTOR_SUB_REFL; NORM_0; REAL_MUL_LZERO]; + ALL_TAC] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE RAND_CONV [closure]) THEN + ASM_REWRITE_TAC[IN_UNION; IN_ELIM_THM; LIMPT_APPROACHABLE; dist] THEN + FIRST_ASSUM(DISJ_CASES_TAC o MATCH_MP (REAL_ARITH + `e <= &1 ==> e = &1 \/ e < &1`)) THEN + ASM_SIMP_TAC[REAL_SUB_REFL; GSYM REAL_LT_RDIV_EQ; REAL_SUB_LT] THENL + [DISCH_THEN(MP_TAC o SPEC `&1`) THEN + REWRITE_TAC[REAL_MUL_RZERO; REAL_LT_01]; + DISCH_THEN(MP_TAC o SPEC `(e * d) / (&1 - e)`)] THEN + ASM_SIMP_TAC[REAL_LT_RDIV_EQ; REAL_SUB_LT; REAL_MUL_LZERO; REAL_LT_MUL; + REAL_MUL_LID] THEN + MATCH_MP_TAC MONO_EXISTS THEN MESON_TAC[]; + ALL_TAC] THEN + ABBREV_TAC `z:real^N = c + ((&1 - e) / e) % (x - y)` THEN + SUBGOAL_THEN `x - e % (x - c):real^N = y - e % (y - z)` SUBST1_TAC THENL + [EXPAND_TAC "z" THEN + REWRITE_TAC[VECTOR_SUB_LDISTRIB; VECTOR_ADD_LDISTRIB] THEN + ASM_SIMP_TAC[VECTOR_MUL_ASSOC; REAL_DIV_LMUL; REAL_LT_IMP_NZ] THEN + VECTOR_ARITH_TAC; + ALL_TAC] THEN + MATCH_MP_TAC IN_RELATIVE_INTERIOR_CONVEX_SHRINK THEN ASM_REWRITE_TAC[] THEN + SUBGOAL_THEN `dist(c:real^N,z) < d` ASSUME_TAC THENL + [EXPAND_TAC "z" THEN + REWRITE_TAC[NORM_ARITH `dist(c:real^N,c + x) = norm x`] THEN + REWRITE_TAC[NORM_MUL; REAL_ABS_DIV] THEN ONCE_REWRITE_TAC[NORM_SUB] THEN + REWRITE_TAC[REAL_ARITH `a / b * c:real = (c * a) / b`] THEN + ASM_SIMP_TAC[real_abs; REAL_SUB_LE; REAL_LT_IMP_LE; REAL_LT_LDIV_EQ] THEN + ASM_REAL_ARITH_TAC; + ALL_TAC] THEN + SUBGOAL_THEN `(z:real^N) IN affine hull s` ASSUME_TAC THENL + [EXPAND_TAC "z" THEN MATCH_MP_TAC IN_AFFINE_ADD_MUL_DIFF THEN + ASM_SIMP_TAC[AFFINE_AFFINE_HULL; HULL_INC] THEN + MATCH_MP_TAC(SET_RULE `!t. x IN t /\ t = s ==> x IN s`) THEN + EXISTS_TAC `closure(affine hull s):real^N->bool` THEN + SIMP_TAC[CLOSURE_EQ; CLOSED_AFFINE_HULL] THEN + ASM_MESON_TAC[SUBSET_CLOSURE; HULL_INC; SUBSET]; + ALL_TAC] THEN + ASM_REWRITE_TAC[IN_RELATIVE_INTERIOR] THEN CONJ_TAC THENL + [ASM_MESON_TAC[IN_BALL; IN_INTER; SUBSET]; ALL_TAC] THEN + EXISTS_TAC `d - dist(c:real^N,z)` THEN ASM_REWRITE_TAC[REAL_SUB_LT] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP + (REWRITE_RULE[IMP_CONJ_ALT] SUBSET_TRANS)) THEN + REWRITE_TAC[SUBSET; IN_INTER] THEN GEN_TAC THEN + MATCH_MP_TAC MONO_AND THEN REWRITE_TAC[] THEN + UNDISCH_TAC `dist(c:real^N,z) < d` THEN REWRITE_TAC[IN_BALL] THEN + NORM_ARITH_TAC);; + +let IN_RELATIVE_INTERIOR_CLOSURE_CONVEX_SEGMENT = prove + (`!s a b:real^N. + convex s /\ a IN relative_interior s /\ b IN closure s + ==> segment(a,b) SUBSET relative_interior s`, + REWRITE_TAC[SUBSET; IN_SEGMENT] THEN REPEAT STRIP_TAC THEN + ASM_REWRITE_TAC[VECTOR_ARITH + `(&1 - u) % a + u % b:real^N = b - (&1 - u) % (b - a)`] THEN + MATCH_MP_TAC IN_RELATIVE_INTERIOR_CLOSURE_CONVEX_SHRINK THEN + ASM_REWRITE_TAC[] THEN ASM_REAL_ARITH_TAC);; + +let RELATIVE_INTERIOR_SING = prove + (`!a. relative_interior {a} = {a}`, + GEN_TAC THEN MATCH_MP_TAC(SET_RULE + `s SUBSET {a} /\ ~(s = {}) ==> s = {a}`) THEN + SIMP_TAC[RELATIVE_INTERIOR_SUBSET; RELATIVE_INTERIOR_EQ_EMPTY; + CONVEX_SING] THEN + SET_TAC[]);; + +let RELATIVE_FRONTIER_SING = prove + (`!a:real^N. relative_frontier {a} = {}`, + REWRITE_TAC[relative_frontier; RELATIVE_INTERIOR_SING; CLOSURE_SING] THEN + SET_TAC[]);; + +let RELATIVE_FRONTIER_CBALL = prove + (`!a:real^N r. relative_frontier(cball(a,r)) = + if r = &0 then {} else sphere(a,r)`, + REPEAT STRIP_TAC THEN COND_CASES_TAC THEN + ASM_SIMP_TAC[CBALL_SING; RELATIVE_FRONTIER_SING] THEN + ASM_CASES_TAC `r < &0` THEN + ASM_SIMP_TAC[CBALL_EMPTY; SPHERE_EMPTY; RELATIVE_FRONTIER_EMPTY] THEN + SUBGOAL_THEN `&0 < r` ASSUME_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN + ASM_SIMP_TAC[RELATIVE_FRONTIER_NONEMPTY_INTERIOR; INTERIOR_CBALL; + BALL_EQ_EMPTY; GSYM REAL_NOT_LT; FRONTIER_CBALL]);; + +let RELATIVE_FRONTIER_BALL = prove + (`!a:real^N r. relative_frontier(ball(a,r)) = + if r = &0 then {} else sphere(a,r)`, + REPEAT STRIP_TAC THEN COND_CASES_TAC THEN + ASM_SIMP_TAC[BALL_EMPTY; REAL_LE_REFL; RELATIVE_FRONTIER_EMPTY] THEN + ASM_CASES_TAC `r < &0` THEN + ASM_SIMP_TAC[BALL_EMPTY; REAL_LT_IMP_LE; SPHERE_EMPTY; + RELATIVE_FRONTIER_EMPTY] THEN + SUBGOAL_THEN `&0 < r` ASSUME_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN + ASM_SIMP_TAC[RELATIVE_FRONTIER_NONEMPTY_INTERIOR; INTERIOR_OPEN; OPEN_BALL; + BALL_EQ_EMPTY; GSYM REAL_NOT_LT; FRONTIER_BALL]);; + +let STARLIKE_CONVEX_TWEAK_BOUNDARY_POINTS = prove + (`!s t:real^N->bool. + convex s /\ ~(s = {}) /\ + relative_interior s SUBSET t /\ t SUBSET closure s + ==> starlike t`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN `~(relative_interior s:real^N->bool = {})` MP_TAC THENL + [ASM_SIMP_TAC[RELATIVE_INTERIOR_EQ_EMPTY]; REWRITE_TAC[starlike]] THEN + REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN MATCH_MP_TAC MONO_EXISTS THEN + X_GEN_TAC `a:real^N` THEN + REPEAT STRIP_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + MATCH_MP_TAC(SET_RULE + `a IN s /\ b IN s /\ segment[a,b] DIFF {a,b} SUBSET s + ==> segment[a:real^N,b] SUBSET s`) THEN + ASM_REWRITE_TAC[GSYM open_segment] THEN + ASM_MESON_TAC[IN_RELATIVE_INTERIOR_CLOSURE_CONVEX_SEGMENT; SUBSET]);; + +let RELATIVE_INTERIOR_PROLONG = prove + (`!s x y:real^N. + x IN relative_interior s /\ y IN s + ==> ?t. &1 < t /\ (y + t % (x - y)) IN s`, + REPEAT GEN_TAC THEN + REWRITE_TAC[IN_RELATIVE_INTERIOR_CBALL; IN_ELIM_THM] THEN + DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC (X_CHOOSE_THEN `e:real` + STRIP_ASSUME_TAC)) THEN + ASM_CASES_TAC `y:real^N = x` THENL + [ASM_REWRITE_TAC[VECTOR_ARITH `y + t % (x - x):real^N = y`] THEN + EXISTS_TAC `&2` THEN CONV_TAC REAL_RAT_REDUCE_CONV; + EXISTS_TAC `&1 + e / norm(x - y:real^N)` THEN + ASM_SIMP_TAC[REAL_LT_ADDR; REAL_LT_DIV; NORM_POS_LT; VECTOR_SUB_EQ] THEN + REWRITE_TAC[VECTOR_ARITH + `y + (&1 + e) % (x - y):real^N = x + e % (x - y)`] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o REWRITE_RULE[SUBSET]) THEN + ASM_SIMP_TAC[AFFINE_AFFINE_HULL; IN_INTER; IN_AFFINE_ADD_MUL_DIFF; + HULL_INC; IN_CBALL] THEN + REWRITE_TAC[NORM_ARITH `dist(x:real^N,x + y) = norm y`] THEN + REWRITE_TAC[NORM_MUL; REAL_ABS_DIV; REAL_ABS_NORM] THEN + ASM_SIMP_TAC[REAL_DIV_RMUL; NORM_EQ_0; VECTOR_SUB_EQ] THEN + ASM_REAL_ARITH_TAC]);; + +let RELATIVE_INTERIOR_CONVEX_PROLONG = prove + (`!s. convex s + ==> relative_interior s = + {x:real^N | x IN s /\ + !y. y IN s ==> ?t. &1 < t /\ (y + t % (x - y)) IN s}`, + REPEAT STRIP_TAC THEN REWRITE_TAC[EXTENSION; IN_ELIM_THM] THEN + X_GEN_TAC `x:real^N` THEN EQ_TAC THENL + [SIMP_TAC[RELATIVE_INTERIOR_PROLONG] THEN + MESON_TAC[SUBSET; RELATIVE_INTERIOR_SUBSET]; + STRIP_TAC THEN + SUBGOAL_THEN `?y:real^N. y IN relative_interior s` STRIP_ASSUME_TAC THENL + [ASM_SIMP_TAC[MEMBER_NOT_EMPTY; RELATIVE_INTERIOR_EQ_EMPTY] THEN + ASM SET_TAC[]; + ALL_TAC] THEN + FIRST_X_ASSUM(MP_TAC o SPEC `y:real^N`) THEN ANTS_TAC THENL + [ASM_MESON_TAC[RELATIVE_INTERIOR_SUBSET; SUBSET]; ALL_TAC] THEN + ASM_CASES_TAC `y:real^N = x` THENL [ASM_MESON_TAC[]; ALL_TAC] THEN + DISCH_THEN(X_CHOOSE_THEN `t:real` STRIP_ASSUME_TAC) THEN + MP_TAC(ISPECL [`s:real^N->bool`; `y:real^N`; `y + t % (x - y):real^N`] + IN_RELATIVE_INTERIOR_CLOSURE_CONVEX_SEGMENT) THEN + ANTS_TAC THENL [ASM_MESON_TAC[SUBSET; CLOSURE_SUBSET]; ALL_TAC] THEN + REWRITE_TAC[SUBSET] THEN DISCH_THEN MATCH_MP_TAC THEN + REWRITE_TAC[IN_SEGMENT; IN_ELIM_THM] THEN + ASM_REWRITE_TAC[VECTOR_ARITH `y:real^N = y + x <=> x = vec 0`; + VECTOR_ARITH `(&1 - u) % y + u % (y + t % (x - y)):real^N = + y + t % u % (x - y)`] THEN + ASM_REWRITE_TAC[VECTOR_MUL_EQ_0; VECTOR_SUB_EQ] THEN + CONJ_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN + EXISTS_TAC `inv t:real` THEN + ASM_SIMP_TAC[VECTOR_MUL_ASSOC; REAL_MUL_RINV; REAL_LT_INV_EQ; + REAL_INV_LT_1; REAL_LT_IMP_NZ; REAL_ARITH `&1 < x ==> &0 < x`] THEN + VECTOR_ARITH_TAC]);; + +let RELATIVE_INTERIOR_EQ_CLOSURE = prove + (`!s:real^N->bool. + relative_interior s = closure s <=> affine s`, + GEN_TAC THEN ASM_CASES_TAC `s:real^N->bool = {}` THEN + ASM_REWRITE_TAC[RELATIVE_INTERIOR_EMPTY; CLOSURE_EMPTY; AFFINE_EMPTY] THEN + EQ_TAC THEN + SIMP_TAC[RELATIVE_INTERIOR_AFFINE; CLOSURE_CLOSED; CLOSED_AFFINE] THEN + DISCH_THEN(MP_TAC o MATCH_MP (SET_RULE + `relative_interior s = closure s + ==> relative_interior s SUBSET s /\ s SUBSET closure s + ==> relative_interior s = s /\ closure s = s`)) THEN + REWRITE_TAC[RELATIVE_INTERIOR_SUBSET; CLOSURE_SUBSET] THEN + REWRITE_TAC[RELATIVE_INTERIOR_EQ; CLOSURE_EQ; GSYM AFFINE_HULL_EQ] THEN + STRIP_TAC THEN FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE + `~(s = {}) ==> s = {} \/ s = a ==> a = s`)) THEN + MP_TAC(ISPEC `affine hull s:real^N->bool` CONNECTED_CLOPEN) THEN + SIMP_TAC[AFFINE_IMP_CONVEX; CONVEX_CONNECTED; AFFINE_AFFINE_HULL] THEN + DISCH_THEN MATCH_MP_TAC THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC CLOSED_SUBSET THEN ASM_REWRITE_TAC[HULL_SUBSET]);; + +let RAY_TO_RELATIVE_FRONTIER = prove + (`!s a l:real^N. + bounded s /\ a IN relative_interior s /\ + (a + l) IN affine hull s /\ ~(l = vec 0) + ==> ?d. &0 < d /\ + (a + d % l) IN relative_frontier s /\ + !e. &0 <= e /\ e < d ==> (a + e % l) IN relative_interior s`, + REPEAT STRIP_TAC THEN REWRITE_TAC[relative_frontier] THEN + MP_TAC(ISPEC + `{d | &0 < d /\ ~((a + d % l:real^N) IN relative_interior(s))}` INF) THEN + ABBREV_TAC + `d = inf {d | &0 < d /\ ~((a + d % l:real^N) IN relative_interior(s))}` THEN + SUBGOAL_THEN + `?e. &0 < e /\ !d. &0 <= d /\ d < e + ==> (a + d % l:real^N) IN relative_interior s` + (X_CHOOSE_THEN `k:real` (LABEL_TAC "0")) + THENL + [MP_TAC(ISPEC `s:real^N->bool` OPEN_IN_RELATIVE_INTERIOR) THEN + REWRITE_TAC[open_in; GSYM MEMBER_NOT_EMPTY; IN_ELIM_THM] THEN + DISCH_THEN(MP_TAC o SPEC `a:real^N` o CONJUNCT2) THEN + ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `e:real` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `e / norm(l:real^N)` THEN + ASM_SIMP_TAC[REAL_LT_DIV; NORM_POS_LT] THEN X_GEN_TAC `x:real` THEN + STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN CONJ_TAC THENL + [MATCH_MP_TAC IN_AFFINE_ADD_MUL THEN + ASM_REWRITE_TAC[AFFINE_AFFINE_HULL] THEN + ASM_MESON_TAC[SUBSET; HULL_SUBSET; RELATIVE_INTERIOR_SUBSET]; + REWRITE_TAC[NORM_ARITH `dist(a + x:real^N,a) = norm x`] THEN + ASM_SIMP_TAC[NORM_MUL; GSYM REAL_LT_RDIV_EQ; NORM_POS_LT] THEN + ASM_REAL_ARITH_TAC]; + ALL_TAC] THEN + ANTS_TAC THENL + [REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; IN_ELIM_THM] THEN + CONJ_TAC THENL [ALL_TAC; ASM_MESON_TAC[REAL_NOT_LT; REAL_LT_IMP_LE]] THEN + FIRST_X_ASSUM(MP_TAC o SPEC `a:real^N` o + MATCH_MP BOUNDED_SUBSET_BALL) THEN + REWRITE_TAC[SUBSET; IN_BALL] THEN + DISCH_THEN(X_CHOOSE_THEN `B:real` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `B / norm(l:real^N)` THEN + ASM_SIMP_TAC[REAL_LT_DIV; NORM_POS_LT] THEN + DISCH_THEN(MP_TAC o MATCH_MP + (REWRITE_RULE[SUBSET] RELATIVE_INTERIOR_SUBSET)) THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE BINDER_CONV + [GSYM CONTRAPOS_THM]) THEN + REWRITE_TAC[REAL_NOT_LT] THEN DISCH_THEN MATCH_MP_TAC THEN + REWRITE_TAC[NORM_ARITH `dist(a:real^N,a + x) = norm x`] THEN + ASM_SIMP_TAC[NORM_MUL; REAL_ABS_DIV; REAL_ABS_NORM; + REAL_DIV_RMUL; NORM_EQ_0] THEN + ASM_REAL_ARITH_TAC; + REWRITE_TAC[IN_ELIM_THM] THEN + DISCH_THEN(CONJUNCTS_THEN2 (LABEL_TAC "1") (LABEL_TAC "2")) THEN + EXISTS_TAC `d:real` THEN + MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN CONJ_TAC THENL + [MATCH_MP_TAC REAL_LTE_TRANS THEN EXISTS_TAC `k:real` THEN + ASM_MESON_TAC[REAL_NOT_LT; REAL_LT_IMP_LE]; + DISCH_TAC] THEN + MATCH_MP_TAC(TAUT `b /\ (b ==> a) ==> a /\ b`) THEN CONJ_TAC THENL + [REWRITE_TAC[REAL_LE_LT] THEN + ASM_MESON_TAC[VECTOR_ARITH `a + &0 % l:real^N = a`; + REAL_NOT_LT; REAL_LT_IMP_LE]; + DISCH_TAC] THEN + REWRITE_TAC[IN_DIFF] THEN CONJ_TAC THENL + [REWRITE_TAC[CLOSURE_APPROACHABLE] THEN + X_GEN_TAC `x:real` THEN DISCH_TAC THEN + EXISTS_TAC `a + (d - min d (x / &2 / norm(l:real^N))) % l` THEN + CONJ_TAC THENL + [MATCH_MP_TAC(REWRITE_RULE[SUBSET] RELATIVE_INTERIOR_SUBSET) THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN + CONJ_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN + MATCH_MP_TAC(REAL_ARITH `&0 < x /\ &0 < d ==> d - min d x < d`) THEN + ASM_SIMP_TAC[REAL_HALF; REAL_LT_DIV; NORM_POS_LT]; + REWRITE_TAC[NORM_ARITH `dist(a + x:real^N,a + y) = norm(x - y)`] THEN + REWRITE_TAC[GSYM VECTOR_SUB_RDISTRIB; NORM_MUL] THEN + ASM_SIMP_TAC[GSYM REAL_LT_RDIV_EQ; NORM_POS_LT] THEN + MATCH_MP_TAC(REAL_ARITH + `&0 < x /\ x < y /\ &0 < d ==> abs((d - min d x) - d) < y`) THEN + REWRITE_TAC[REAL_ARITH `x / &2 / y < x / y <=> &0 < x / y`] THEN + ASM_SIMP_TAC[REAL_HALF; REAL_LT_DIV; NORM_POS_LT]]; + DISCH_TAC THEN + MP_TAC(ISPEC `s:real^N->bool` OPEN_IN_RELATIVE_INTERIOR) THEN + REWRITE_TAC[open_in; GSYM MEMBER_NOT_EMPTY; IN_ELIM_THM] THEN + DISCH_THEN(MP_TAC o SPEC `a + d % l:real^N` o CONJUNCT2) THEN + ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `e:real` + (CONJUNCTS_THEN2 ASSUME_TAC (LABEL_TAC "3"))) THEN + REMOVE_THEN "2" (MP_TAC o SPEC `d + e / norm(l:real^N)`) THEN + ASM_SIMP_TAC[NOT_IMP; REAL_ARITH `~(d + l <= d) <=> &0 < l`; + REAL_LT_DIV; NORM_POS_LT] THEN + X_GEN_TAC `x:real` THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN + REWRITE_TAC[REAL_NOT_LE] THEN DISCH_TAC THEN + ASM_CASES_TAC `x < d` THEN ASM_SIMP_TAC[REAL_LT_IMP_LE] THEN + REMOVE_THEN "3" MATCH_MP_TAC THEN CONJ_TAC THENL + [MATCH_MP_TAC IN_AFFINE_ADD_MUL THEN + ASM_REWRITE_TAC[AFFINE_AFFINE_HULL] THEN + ASM_MESON_TAC[SUBSET; HULL_SUBSET; RELATIVE_INTERIOR_SUBSET]; + REWRITE_TAC[NORM_ARITH `dist(a + x:real^N,a + y) = norm(x - y)`] THEN + REWRITE_TAC[GSYM VECTOR_SUB_RDISTRIB; NORM_MUL] THEN + ASM_SIMP_TAC[GSYM REAL_LT_RDIV_EQ; NORM_POS_LT] THEN + ASM_REAL_ARITH_TAC]]]);; + +let RAY_TO_FRONTIER = prove + (`!s a l:real^N. + bounded s /\ a IN interior s /\ ~(l = vec 0) + ==> ?d. &0 < d /\ (a + d % l) IN frontier s /\ + !e. &0 <= e /\ e < d ==> (a + e % l) IN interior s`, + REPEAT STRIP_TAC THEN REWRITE_TAC[frontier] THEN + SUBGOAL_THEN `interior s:real^N->bool = relative_interior s` SUBST1_TAC THENL + [ALL_TAC; + REWRITE_TAC[GSYM relative_frontier] THEN + MATCH_MP_TAC RAY_TO_RELATIVE_FRONTIER THEN ASM_REWRITE_TAC[]] THEN + ASM_MESON_TAC[NOT_IN_EMPTY; RELATIVE_INTERIOR_NONEMPTY_INTERIOR; IN_UNIV; + AFFINE_HULL_NONEMPTY_INTERIOR]);; + +let RELATIVE_FRONTIER_NOT_SING = prove + (`!s a:real^N. bounded s ==> ~(relative_frontier s = {a})`, + REPEAT GEN_TAC THEN ASM_CASES_TAC `s:real^N->bool = {}` THEN + ASM_REWRITE_TAC[RELATIVE_FRONTIER_EMPTY; NOT_INSERT_EMPTY] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN + DISCH_THEN(X_CHOOSE_TAC `z:real^N`) THEN + ASM_CASES_TAC `s = {z:real^N}` THEN + ASM_REWRITE_TAC[RELATIVE_FRONTIER_SING; NOT_INSERT_EMPTY] THEN + SUBGOAL_THEN `?w:real^N. w IN s /\ ~(w = z)` STRIP_ASSUME_TAC THENL + [ASM SET_TAC[]; REPEAT STRIP_TAC] THEN + SUBGOAL_THEN + `~((w:real^N) IN relative_frontier s /\ z IN relative_frontier s)` + MP_TAC THENL [ASM SET_TAC[]; DISCH_TAC] THEN + MAP_EVERY UNDISCH_TAC + [`relative_frontier s = {a:real^N}`; `bounded(s:real^N->bool)`; + `~(w:real^N = z)`; `(z:real^N) IN s`; `(w:real^N) IN s`; + `~((w:real^N) IN relative_frontier s /\ z IN relative_frontier s)`] THEN + POP_ASSUM_LIST(K ALL_TAC) THEN REWRITE_TAC[DE_MORGAN_THM] THEN + MAP_EVERY (fun t -> SPEC_TAC(t,t)) [`z:real^N`; `w:real^N`] THEN + MATCH_MP_TAC(MESON[] + `(!w z. Q w z <=> Q z w) /\ (!w z. P z ==> Q w z) + ==> !w z. P w \/ P z ==> Q w z`) THEN + CONJ_TAC THENL [MESON_TAC[]; REPEAT GEN_TAC] THEN + DISCH_THEN(fun th -> REPEAT STRIP_TAC THEN MP_TAC th) THEN + REWRITE_TAC[relative_frontier; IN_DIFF] THEN + CONJ_TAC THENL [ASM_MESON_TAC[SUBSET; CLOSURE_SUBSET]; DISCH_TAC] THEN + MP_TAC(GEN `d:real` + (ISPECL [`s:real^N->bool`; `z:real^N`; `d % (w - z):real^N`] + RAY_TO_RELATIVE_FRONTIER)) THEN + ASM_SIMP_TAC[VECTOR_SUB_EQ; IN_AFFINE_ADD_MUL_DIFF; AFFINE_AFFINE_HULL; + HULL_INC; VECTOR_MUL_EQ_0] THEN + DISCH_THEN(fun th -> MP_TAC(SPEC `&1` th) THEN MP_TAC(SPEC `--(&1)` th)) THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN REWRITE_TAC[IN_SING] THEN + DISCH_THEN(X_CHOOSE_THEN `e:real` (STRIP_ASSUME_TAC o GSYM)) THEN + ASM_REWRITE_TAC[VECTOR_MUL_RCANCEL; VECTOR_MUL_ASSOC; VECTOR_SUB_EQ; + VECTOR_ARITH `a + x:real^N = a + y <=> x = y`] THEN + ASM_REAL_ARITH_TAC);; + +let RELATIVE_INTERIOR_PCROSS = prove + (`!s:real^M->bool t:real^N->bool. + relative_interior(s PCROSS t) = + relative_interior s PCROSS relative_interior t`, + REPEAT STRIP_TAC THEN MAP_EVERY ASM_CASES_TAC + [`s:real^M->bool = {}`; `t:real^N->bool = {}`] THEN + ASM_REWRITE_TAC[PCROSS_EMPTY; RELATIVE_INTERIOR_EMPTY] THEN + REWRITE_TAC[relative_interior; AFFINE_HULL_PCROSS] THEN + REWRITE_TAC[EXTENSION; FORALL_PASTECART; IN_ELIM_THM; + PASTECART_IN_PCROSS] THEN + MAP_EVERY X_GEN_TAC [`x:real^M`; `y:real^N`] THEN EQ_TAC THENL + [ONCE_REWRITE_TAC[TAUT `p /\ q /\ r <=> r /\ q /\ p`] THEN + DISCH_THEN(X_CHOOSE_THEN `u:real^(M,N)finite_sum->bool` + (CONJUNCTS_THEN ASSUME_TAC)) THEN + FIRST_ASSUM(MP_TAC o MATCH_MP PASTECART_IN_INTERIOR_SUBTOPOLOGY) THEN + REWRITE_TAC[LEFT_AND_EXISTS_THM] THEN + REWRITE_TAC[RIGHT_AND_EXISTS_THM] THEN + REPEAT(MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC) THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + W(MP_TAC o PART_MATCH (funpow 3 rand) SUBSET_PCROSS o snd) THEN + ASM SET_TAC[]; + DISCH_THEN(CONJUNCTS_THEN2 + (X_CHOOSE_THEN `v:real^M->bool` STRIP_ASSUME_TAC) + (X_CHOOSE_THEN `w:real^N->bool` STRIP_ASSUME_TAC)) THEN + EXISTS_TAC `(v:real^M->bool) PCROSS (w:real^N->bool)` THEN + ASM_SIMP_TAC[PASTECART_IN_PCROSS; SUBSET_PCROSS; OPEN_IN_PCROSS]]);; + +let RELATIVE_FRONTIER_EQ_EMPTY = prove + (`!s:real^N->bool. relative_frontier s = {} <=> affine s`, + GEN_TAC THEN REWRITE_TAC[relative_frontier] THEN + REWRITE_TAC[GSYM RELATIVE_INTERIOR_EQ_CLOSURE] THEN + MP_TAC(ISPEC `s:real^N->bool` RELATIVE_INTERIOR_SUBSET) THEN + MP_TAC(ISPEC `s:real^N->bool` CLOSURE_SUBSET) THEN SET_TAC[]);; + +let DIAMETER_BOUNDED_BOUND_LT = prove + (`!s x y:real^N. + bounded s /\ x IN relative_interior s /\ y IN closure s /\ + ~(diameter s = &0) + ==> norm(x - y) < diameter s`, + let lemma = prove + (`!s x y:real^N. + bounded s /\ x IN relative_interior s /\ y IN s /\ + ~(diameter s = &0) + ==> norm(x - y) < diameter s`, + REPEAT STRIP_TAC THEN FIRST_X_ASSUM + (MP_TAC o GEN_REWRITE_RULE I [IN_RELATIVE_INTERIOR_CBALL]) THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC (X_CHOOSE_THEN `e:real` + STRIP_ASSUME_TAC)) THEN + ASM_SIMP_TAC[REAL_LT_LE; DIAMETER_BOUNDED_BOUND] THEN + ASM_CASES_TAC `y:real^N = x` THEN + ASM_SIMP_TAC[VECTOR_SUB_REFL; NORM_0] THEN + DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [SUBSET]) THEN + DISCH_THEN(MP_TAC o SPEC `x + e / norm(x - y) % (x - y):real^N`) THEN + REWRITE_TAC[NOT_IMP; IN_INTER] THEN REPEAT CONJ_TAC THENL + [REWRITE_TAC[IN_CBALL; NORM_ARITH `dist(x:real^M,x + y) = norm y`] THEN + ASM_SIMP_TAC[NORM_MUL; REAL_ABS_DIV; REAL_ABS_NORM; REAL_DIV_RMUL; + NORM_EQ_0; VECTOR_SUB_EQ] THEN ASM_REAL_ARITH_TAC; + MATCH_MP_TAC IN_AFFINE_ADD_MUL_DIFF THEN + ASM_SIMP_TAC[HULL_INC; AFFINE_AFFINE_HULL]; + DISCH_TAC THEN MP_TAC(ISPECL + [`s:real^N->bool`; `x + e / norm(x - y) % (x - y):real^N`; `y:real^N`] + DIAMETER_BOUNDED_BOUND) THEN + ASM_REWRITE_TAC[] THEN FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN + REWRITE_TAC[VECTOR_ARITH + `(x + e % (x - y)) - y:real^N = (&1 + e) % (x - y)`] THEN + SIMP_TAC[NORM_MUL; REAL_ARITH `~(a * n <= n) <=> &0 < n * (a - &1)`] THEN + MATCH_MP_TAC REAL_LT_MUL THEN + ASM_REWRITE_TAC[NORM_POS_LT; VECTOR_SUB_EQ] THEN + MATCH_MP_TAC(REAL_ARITH `&0 < e ==> &0 < abs(&1 + e) - &1`) THEN + MATCH_MP_TAC REAL_LT_DIV THEN + ASM_REWRITE_TAC[NORM_POS_LT; VECTOR_SUB_EQ]]) in + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`closure s:real^N->bool`; `x:real^N`; `y:real^N`] + lemma) THEN + ASM_SIMP_TAC[DIAMETER_CLOSURE; BOUNDED_CLOSURE] THEN + DISCH_THEN MATCH_MP_TAC THEN FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP + (SET_RULE `x IN s ==> s SUBSET t ==> x IN t`)) THEN + MATCH_MP_TAC SUBSET_RELATIVE_INTERIOR THEN + REWRITE_TAC[CLOSURE_SUBSET; AFFINE_HULL_CLOSURE]);; + +let DIAMETER_ATTAINED_RELATIVE_FRONTIER = prove + (`!s:real^N->bool. + bounded s /\ ~(diameter s = &0) + ==> ?x y. x IN relative_frontier s /\ + y IN relative_frontier s /\ + norm(x - y) = diameter s`, + REPEAT GEN_TAC THEN ASM_CASES_TAC `s:real^N->bool = {}` THEN + ASM_REWRITE_TAC[DIAMETER_EMPTY; relative_frontier] THEN REPEAT STRIP_TAC THEN + MP_TAC(ISPEC `closure s:real^N->bool` DIAMETER_COMPACT_ATTAINED) THEN + ASM_SIMP_TAC[COMPACT_CLOSURE; CLOSURE_EQ_EMPTY; DIAMETER_CLOSURE] THEN + REPEAT(MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC) THEN + STRIP_TAC THEN ASM_REWRITE_TAC[IN_DIFF] THEN REPEAT STRIP_TAC THEN + MP_TAC(ISPEC `s:real^N->bool` DIAMETER_BOUNDED_BOUND_LT) THENL + [DISCH_THEN(MP_TAC o SPECL [`x:real^N`; `y:real^N`]); + DISCH_THEN(MP_TAC o SPECL [`y:real^N`; `x:real^N`])] THEN + ASM_MESON_TAC[REAL_LT_REFL; NORM_SUB]);; + +let DIAMETER_RELATIVE_FRONTIER = prove + (`!s:real^N->bool. + bounded s /\ ~(?a. s = {a}) + ==> diameter(relative_frontier s) = diameter s`, + REPEAT STRIP_TAC THEN ASM_CASES_TAC `s:real^N->bool = {}` THEN + ASM_REWRITE_TAC[RELATIVE_FRONTIER_EMPTY] THEN + REWRITE_TAC[relative_frontier] THEN + ASM_SIMP_TAC[GSYM DIAMETER_CLOSURE; GSYM REAL_LE_ANTISYM] THEN + ASM_SIMP_TAC[SUBSET_DIFF; DIAMETER_SUBSET; BOUNDED_CLOSURE] THEN + ASM_SIMP_TAC[DIAMETER_CLOSURE] THEN + MP_TAC(ISPEC `s:real^N->bool` DIAMETER_ATTAINED_RELATIVE_FRONTIER) THEN + ASM_SIMP_TAC[DIAMETER_EQ_0; relative_frontier] THEN STRIP_TAC THEN + FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN MATCH_MP_TAC DIAMETER_BOUNDED_BOUND THEN + ASM_SIMP_TAC[BOUNDED_CLOSURE; BOUNDED_DIFF]);; + +let DIAMETER_ATTAINED_FRONTIER = prove + (`!s:real^N->bool. + bounded s /\ ~(diameter s = &0) + ==> ?x y. x IN frontier s /\ y IN frontier s /\ + norm(x - y) = diameter s`, + REPEAT GEN_TAC THEN + DISCH_THEN(MP_TAC o MATCH_MP DIAMETER_ATTAINED_RELATIVE_FRONTIER) THEN + REWRITE_TAC[frontier; relative_frontier; IN_DIFF] THEN + MESON_TAC[REWRITE_RULE[SUBSET] INTERIOR_SUBSET_RELATIVE_INTERIOR]);; + +let DIAMETER_FRONTIER = prove + (`!s:real^N->bool. bounded s ==> diameter(frontier s) = diameter s`, + REPEAT STRIP_TAC THEN ASM_CASES_TAC `?a:real^N. s = {a}` THENL + [ASM_MESON_TAC[FRONTIER_SING]; ALL_TAC] THEN + MATCH_MP_TAC(REAL_ARITH + `!r. r <= f /\ f <= s /\ r = s ==> f = s`) THEN + EXISTS_TAC `diameter(closure s DIFF relative_interior s:real^N->bool)` THEN + REPEAT CONJ_TAC THENL + [ASM_SIMP_TAC[GSYM DIAMETER_CLOSURE] THEN MATCH_MP_TAC DIAMETER_SUBSET THEN + ASM_SIMP_TAC[BOUNDED_FRONTIER] THEN REWRITE_TAC[frontier] THEN + MP_TAC(ISPEC `s:real^N->bool` INTERIOR_SUBSET_RELATIVE_INTERIOR) THEN + SET_TAC[]; + ASM_SIMP_TAC[GSYM DIAMETER_CLOSURE] THEN MATCH_MP_TAC DIAMETER_SUBSET THEN + ASM_SIMP_TAC[BOUNDED_CLOSURE; frontier; SUBSET_DIFF]; + ASM_SIMP_TAC[DIAMETER_RELATIVE_FRONTIER; GSYM relative_frontier]]);; + +let DIAMETER_SPHERE = prove + (`!a:real^N r. diameter(sphere(a,r)) = if r < &0 then &0 else &2 * r`, + REWRITE_TAC[GSYM FRONTIER_CBALL] THEN + ASM_SIMP_TAC[DIAMETER_FRONTIER; BOUNDED_CBALL; DIAMETER_CBALL]);; + +let CLOSEST_POINT_IN_RELATIVE_INTERIOR = prove + (`!s x:real^N. + closed s /\ ~(s = {}) /\ x IN affine hull s + ==> ((closest_point s x) IN relative_interior s <=> + x IN relative_interior s)`, + REPEAT STRIP_TAC THEN ASM_CASES_TAC `(x:real^N) IN s` THEN + ASM_SIMP_TAC[CLOSEST_POINT_SELF] THEN + MATCH_MP_TAC(TAUT `~q /\ ~p ==> (p <=> q)`) THEN CONJ_TAC THENL + [ASM_MESON_TAC[RELATIVE_INTERIOR_SUBSET; SUBSET]; STRIP_TAC] THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_RELATIVE_INTERIOR_CBALL]) THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + DISCH_THEN(X_CHOOSE_THEN `e:real` STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN `~(closest_point s (x:real^N) = x)` ASSUME_TAC THENL + [ASM_MESON_TAC[]; ALL_TAC] THEN + MP_TAC(ISPECL [`s:real^N->bool`; `x:real^N`; + `closest_point s x - + (min (&1) (e / norm(closest_point s x - x))) % + (closest_point s x - x):real^N`] + CLOSEST_POINT_LE) THEN + ASM_REWRITE_TAC[dist; NOT_IMP; VECTOR_ARITH + `x - (y - e % (y - x)):real^N = (&1 - e) % (x - y)`] THEN + CONJ_TAC THENL + [FIRST_X_ASSUM(MATCH_MP_TAC o GEN_REWRITE_RULE I [SUBSET]) THEN + REWRITE_TAC[IN_CBALL; IN_INTER] THEN CONJ_TAC THENL + [REWRITE_TAC[NORM_ARITH `dist(a:real^N,a - x) = norm x`] THEN + REWRITE_TAC[NORM_MUL; REAL_ABS_DIV; REAL_ABS_NORM] THEN + ASM_SIMP_TAC[GSYM REAL_LE_RDIV_EQ; NORM_POS_LT; VECTOR_SUB_EQ] THEN + MATCH_MP_TAC(REAL_ARITH `&0 <= a ==> abs(min (&1) a) <= a`) THEN + ASM_SIMP_TAC[REAL_LT_IMP_LE; REAL_LE_DIV; NORM_POS_LE]; + MATCH_MP_TAC IN_AFFINE_SUB_MUL_DIFF THEN + ASM_SIMP_TAC[AFFINE_AFFINE_HULL; HULL_INC]]; + REWRITE_TAC[NORM_MUL; REAL_ARITH + `~(n <= a * n) <=> &0 < (&1 - a) * n`] THEN + MATCH_MP_TAC REAL_LT_MUL THEN + ASM_SIMP_TAC[NORM_POS_LT; VECTOR_SUB_EQ] THEN + MATCH_MP_TAC(REAL_ARITH + `&0 < e /\ e <= &1 ==> &0 < &1 - abs(&1 - e)`) THEN + REWRITE_TAC[REAL_MIN_LE; REAL_LT_MIN; REAL_LT_01; REAL_LE_REFL] THEN + ASM_SIMP_TAC[REAL_LT_DIV; NORM_POS_LT; VECTOR_SUB_EQ]]);; + +let CLOSEST_POINT_IN_RELATIVE_FRONTIER = prove + (`!s x:real^N. + closed s /\ ~(s = {}) /\ x IN affine hull s DIFF relative_interior s + ==> closest_point s x IN relative_frontier s`, + SIMP_TAC[relative_frontier; IN_DIFF; CLOSEST_POINT_IN_RELATIVE_INTERIOR] THEN + MESON_TAC[CLOSURE_SUBSET; CLOSEST_POINT_IN_SET; SUBSET]);; + +(* ------------------------------------------------------------------------- *) +(* Interior, relative interior and closure interrelations. *) +(* ------------------------------------------------------------------------- *) + +let CONVEX_CLOSURE_INTERIOR = prove + (`!s:real^N->bool. + convex s /\ ~(interior s = {}) + ==> closure(interior s) = closure s`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN + SIMP_TAC[SUBSET_CLOSURE; INTERIOR_SUBSET] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN + DISCH_THEN(X_CHOOSE_TAC `a:real^N`) THEN REWRITE_TAC[SUBSET] THEN + X_GEN_TAC `b:real^N` THEN DISCH_TAC THEN ASM_CASES_TAC `b:real^N = a` THENL + [ASM_MESON_TAC[CLOSURE_SUBSET; SUBSET]; ALL_TAC] THEN + REWRITE_TAC[closure; IN_UNION; IN_ELIM_THM] THEN DISJ2_TAC THEN + REWRITE_TAC[LIMPT_APPROACHABLE] THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN + EXISTS_TAC `b - min (e / &2 / norm(b - a)) (&1) % (b - a):real^N` THEN + REPEAT CONJ_TAC THENL + [MATCH_MP_TAC IN_INTERIOR_CLOSURE_CONVEX_SHRINK THEN + ASM_REWRITE_TAC[REAL_MIN_LE; REAL_LT_MIN; REAL_LE_REFL; REAL_LT_01]; + REWRITE_TAC[VECTOR_ARITH `b - x:real^N = b <=> x = vec 0`] THEN + ASM_REWRITE_TAC[VECTOR_MUL_EQ_0; VECTOR_SUB_EQ] THEN + MATCH_MP_TAC(REAL_ARITH `&0 < x ==> ~(min x (&1) = &0)`); + REWRITE_TAC[NORM_ARITH `dist(b - x:real^N,b) = norm x`] THEN + REWRITE_TAC[NORM_MUL] THEN MATCH_MP_TAC REAL_LET_TRANS THEN + EXISTS_TAC `e / &2 / norm(b - a:real^N) * norm(b - a)` THEN CONJ_TAC THENL + [MATCH_MP_TAC REAL_LE_RMUL THEN REWRITE_TAC[NORM_POS_LE] THEN + MATCH_MP_TAC(REAL_ARITH `&0 < x ==> abs(min x (&1)) <= x`); + ASM_SIMP_TAC[REAL_DIV_RMUL; NORM_POS_LT; REAL_LT_IMP_NZ; + VECTOR_SUB_EQ] THEN + ASM_REAL_ARITH_TAC]] THEN + ASM_SIMP_TAC[REAL_LT_DIV; NORM_POS_LT; REAL_OF_NUM_LT; + VECTOR_SUB_EQ; ARITH]);; + +let EMPTY_INTERIOR_SUBSET_HYPERPLANE = prove + (`!s. convex s /\ interior s = {} + ==> ?a:real^N b. ~(a = vec 0) /\ s SUBSET {x | a dot x = b}`, + let lemma = prove + (`!s. convex s /\ (vec 0) IN s /\ interior s = {} + ==> ?a:real^N b. ~(a = vec 0) /\ s SUBSET {x | a dot x = b}`, + GEN_TAC THEN + REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN DISCH_TAC THEN + SUBGOAL_THEN `~(relative_interior(s:real^N->bool) = {})` MP_TAC THENL + [ASM_MESON_TAC[RELATIVE_INTERIOR_EQ_EMPTY; MEMBER_NOT_EMPTY]; ALL_TAC] THEN + ASM_REWRITE_TAC[CONTRAPOS_THM] THEN MATCH_MP_TAC EQ_IMP THEN + AP_THM_TAC THEN AP_TERM_TAC THEN CONV_TAC SYM_CONV THEN + MATCH_MP_TAC RELATIVE_INTERIOR_INTERIOR THEN + ASM_SIMP_TAC[AFFINE_HULL_EQ_SPAN; HULL_INC] THEN + ONCE_REWRITE_TAC[GSYM SPAN_UNIV] THEN MATCH_MP_TAC DIM_EQ_SPAN THEN + REWRITE_TAC[SUBSET_UNIV; DIM_UNIV; GSYM NOT_LT] THEN + DISCH_THEN(MP_TAC o MATCH_MP LOWDIM_SUBSET_HYPERPLANE) THEN + DISCH_THEN(X_CHOOSE_THEN `a:real^N` STRIP_ASSUME_TAC) THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [NOT_EXISTS_THM]) THEN + DISCH_THEN(MP_TAC o SPEC `a:real^N`) THEN + ASM_REWRITE_TAC[NOT_EXISTS_THM] THEN EXISTS_TAC `&0` THEN + ASM_MESON_TAC[SUBSET_TRANS; SPAN_INC]) in + GEN_TAC THEN ASM_CASES_TAC `s:real^N->bool = {}` THENL + [ASM_MESON_TAC[EMPTY_SUBSET; BASIS_NONZERO; LE_REFL; DIMINDEX_GE_1]; + ALL_TAC] THEN + STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN + DISCH_THEN(X_CHOOSE_TAC `a:real^N`) THEN + MP_TAC(ISPEC `IMAGE (\x:real^N. --a + x) s` lemma) THEN + ASM_REWRITE_TAC[CONVEX_TRANSLATION_EQ; INTERIOR_TRANSLATION; + IMAGE_EQ_EMPTY; IN_IMAGE; UNWIND_THM2; + VECTOR_ARITH `vec 0:real^N = --a + x <=> x = a`] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `c:real^N` THEN + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; IN_ELIM_THM; DOT_RADD] THEN + MESON_TAC[REAL_ARITH `a + x:real = b <=> x = b - a`]);; + +let CONVEX_INTERIOR_CLOSURE = prove + (`!s:real^N->bool. convex s ==> interior(closure s) = interior s`, + REPEAT STRIP_TAC THEN + ASM_CASES_TAC `interior(s:real^N->bool) = {}` THENL + [MP_TAC(ISPEC `s:real^N->bool` EMPTY_INTERIOR_SUBSET_HYPERPLANE) THEN + ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`a:real^N`; `b:real`] THEN STRIP_TAC THEN + MATCH_MP_TAC(SET_RULE `!t. s SUBSET t /\ t = {} ==> s = {}`) THEN + EXISTS_TAC `interior {x:real^N | a dot x = b}` THEN CONJ_TAC THENL + [ALL_TAC; ASM_SIMP_TAC[INTERIOR_HYPERPLANE]] THEN + MATCH_MP_TAC SUBSET_INTERIOR THEN MATCH_MP_TAC CLOSURE_MINIMAL THEN + ASM_REWRITE_TAC[CLOSED_HYPERPLANE]; + ALL_TAC] THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN + DISCH_THEN(X_CHOOSE_THEN `a:real^N` STRIP_ASSUME_TAC) THEN + MATCH_MP_TAC SUBSET_ANTISYM THEN + SIMP_TAC[SUBSET_INTERIOR; CLOSURE_SUBSET] THEN + REWRITE_TAC[SUBSET] THEN X_GEN_TAC `b:real^N` THEN DISCH_TAC THEN + MP_TAC(ASSUME `(b:real^N) IN interior(closure s)`) THEN + GEN_REWRITE_TAC LAND_CONV [IN_INTERIOR_CBALL] THEN + REWRITE_TAC[SUBSET; IN_CBALL; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `e:real` THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + ASM_CASES_TAC `b:real^N = a` THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(MP_TAC o SPEC `b + e / norm(b - a) % (b - a):real^N`) THEN + ASM_SIMP_TAC[NORM_ARITH `dist(b:real^N,b + e) = norm e`; NORM_MUL; + REAL_ABS_DIV; REAL_ABS_NORM; REAL_DIV_RMUL; NORM_EQ_0; VECTOR_SUB_EQ; + REAL_ARITH `&0 < e ==> abs e <= e`] THEN + DISCH_TAC THEN + SUBGOAL_THEN + `b = (b + e / norm(b - a) % (b - a)) - + e / norm(b - a) / (&1 + e / norm(b - a)) % + ((b + e / norm(b - a) % (b - a)) - a):real^N` + SUBST1_TAC THENL + [REWRITE_TAC[VECTOR_ARITH + `b = (b + e % (b - a)) - d % ((b + e % (b - a)) - a) <=> + (e - d * (&1 + e)) % (b - a) = vec 0`] THEN + ASM_REWRITE_TAC[VECTOR_SUB_EQ; VECTOR_MUL_EQ_0]; + MATCH_MP_TAC IN_INTERIOR_CLOSURE_CONVEX_SHRINK] THEN + ASM_SIMP_TAC[REAL_LE_LDIV_EQ; REAL_LT_DIV; NORM_POS_LT; + VECTOR_SUB_EQ; REAL_ARITH `&0 < x ==> &0 < &1 + x`; + REAL_ARITH `&0 < x ==> ~(&1 + x = &0)`; + REAL_MUL_LID; REAL_ADD_RDISTRIB; REAL_DIV_RMUL; + REAL_LT_IMP_NZ; REAL_LE_ADDL; NORM_POS_LE; REAL_SUB_REFL]);; + +let FRONTIER_CLOSURE_CONVEX = prove + (`!s:real^N->bool. convex s ==> frontier(closure s) = frontier s`, + SIMP_TAC[frontier; CLOSURE_CLOSURE; CONVEX_INTERIOR_CLOSURE]);; + +let CONVEX_CLOSURE_RELATIVE_INTERIOR = prove + (`!s:real^N->bool. + convex s ==> closure(relative_interior s) = closure s`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN + SIMP_TAC[SUBSET_CLOSURE; RELATIVE_INTERIOR_SUBSET] THEN + ASM_CASES_TAC `relative_interior(s:real^N->bool) = {}` THENL + [ASM_MESON_TAC[RELATIVE_INTERIOR_EQ_EMPTY; SUBSET_REFL]; ALL_TAC] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN + DISCH_THEN(X_CHOOSE_TAC `a:real^N`) THEN REWRITE_TAC[SUBSET] THEN + X_GEN_TAC `b:real^N` THEN DISCH_TAC THEN ASM_CASES_TAC `b:real^N = a` THENL + [ASM_MESON_TAC[CLOSURE_SUBSET; SUBSET]; ALL_TAC] THEN + REWRITE_TAC[closure; IN_UNION; IN_ELIM_THM] THEN DISJ2_TAC THEN + REWRITE_TAC[LIMPT_APPROACHABLE] THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN + EXISTS_TAC `b - min (e / &2 / norm(b - a)) (&1) % (b - a):real^N` THEN + REPEAT CONJ_TAC THENL + [MATCH_MP_TAC IN_RELATIVE_INTERIOR_CLOSURE_CONVEX_SHRINK THEN + ASM_REWRITE_TAC[REAL_MIN_LE; REAL_LT_MIN; REAL_LE_REFL; REAL_LT_01]; + REWRITE_TAC[VECTOR_ARITH `b - x:real^N = b <=> x = vec 0`] THEN + ASM_REWRITE_TAC[VECTOR_MUL_EQ_0; VECTOR_SUB_EQ] THEN + MATCH_MP_TAC(REAL_ARITH `&0 < x ==> ~(min x (&1) = &0)`); + REWRITE_TAC[NORM_ARITH `dist(b - x:real^N,b) = norm x`] THEN + REWRITE_TAC[NORM_MUL] THEN MATCH_MP_TAC REAL_LET_TRANS THEN + EXISTS_TAC `e / &2 / norm(b - a:real^N) * norm(b - a)` THEN CONJ_TAC THENL + [MATCH_MP_TAC REAL_LE_RMUL THEN REWRITE_TAC[NORM_POS_LE] THEN + MATCH_MP_TAC(REAL_ARITH `&0 < x ==> abs(min x (&1)) <= x`); + ASM_SIMP_TAC[REAL_DIV_RMUL; NORM_POS_LT; REAL_LT_IMP_NZ; + VECTOR_SUB_EQ] THEN + ASM_REAL_ARITH_TAC]] THEN + ASM_SIMP_TAC[REAL_LT_DIV; NORM_POS_LT; REAL_OF_NUM_LT; + VECTOR_SUB_EQ; ARITH]);; + +let AFFINE_HULL_RELATIVE_INTERIOR = prove + (`!s. convex s + ==> affine hull (relative_interior s) = affine hull s`, + MESON_TAC[CONVEX_CLOSURE_RELATIVE_INTERIOR; AFFINE_HULL_CLOSURE]);; + +let CONVEX_RELATIVE_INTERIOR_CLOSURE = prove + (`!s:real^N->bool. + convex s ==> relative_interior(closure s) = relative_interior s`, + REPEAT STRIP_TAC THEN ASM_CASES_TAC `s:real^N->bool = {}` THEN + ASM_REWRITE_TAC[CLOSURE_EMPTY; RELATIVE_INTERIOR_EMPTY] THEN + SUBGOAL_THEN `?a:real^N. a IN relative_interior s` STRIP_ASSUME_TAC THENL + [ASM_SIMP_TAC[MEMBER_NOT_EMPTY; RELATIVE_INTERIOR_EQ_EMPTY]; + ALL_TAC] THEN + MATCH_MP_TAC SUBSET_ANTISYM THEN REWRITE_TAC[SUBSET] THEN CONJ_TAC THENL + [ALL_TAC; + REWRITE_TAC[IN_RELATIVE_INTERIOR; AFFINE_HULL_CLOSURE; SUBSET] THEN + MESON_TAC[CLOSURE_SUBSET; SUBSET]] THEN + X_GEN_TAC `b:real^N` THEN DISCH_TAC THEN + MP_TAC(ASSUME `(b:real^N) IN relative_interior(closure s)`) THEN + GEN_REWRITE_TAC LAND_CONV [IN_RELATIVE_INTERIOR_CBALL] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + REWRITE_TAC[SUBSET; IN_CBALL; IN_INTER; LEFT_IMP_EXISTS_THM; + AFFINE_HULL_CLOSURE] THEN + X_GEN_TAC `e:real` THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + ASM_CASES_TAC `b:real^N = a` THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(MP_TAC o SPEC `b + e / norm(b - a) % (b - a):real^N`) THEN + ASM_SIMP_TAC[NORM_ARITH `dist(b:real^N,b + e) = norm e`; NORM_MUL; + REAL_ABS_DIV; REAL_ABS_NORM; REAL_DIV_RMUL; NORM_EQ_0; VECTOR_SUB_EQ; + REAL_ARITH `&0 < e ==> abs e <= e`] THEN + ANTS_TAC THENL + [MATCH_MP_TAC IN_AFFINE_ADD_MUL_DIFF THEN + ASM_MESON_TAC[SUBSET; AFFINE_AFFINE_HULL; RELATIVE_INTERIOR_SUBSET; + CLOSURE_SUBSET_AFFINE_HULL; HULL_INC]; + ALL_TAC] THEN + DISCH_TAC THEN + SUBGOAL_THEN + `b = (b + e / norm(b - a) % (b - a)) - + e / norm(b - a) / (&1 + e / norm(b - a)) % + ((b + e / norm(b - a) % (b - a)) - a):real^N` + SUBST1_TAC THENL + [REWRITE_TAC[VECTOR_ARITH + `b = (b + e % (b - a)) - d % ((b + e % (b - a)) - a) <=> + (e - d * (&1 + e)) % (b - a) = vec 0`] THEN + ASM_REWRITE_TAC[VECTOR_SUB_EQ; VECTOR_MUL_EQ_0]; + MATCH_MP_TAC IN_RELATIVE_INTERIOR_CLOSURE_CONVEX_SHRINK] THEN + ASM_SIMP_TAC[REAL_LE_LDIV_EQ; REAL_LT_DIV; NORM_POS_LT; + VECTOR_SUB_EQ; REAL_ARITH `&0 < x ==> &0 < &1 + x`; + REAL_ARITH `&0 < x ==> ~(&1 + x = &0)`; + REAL_MUL_LID; REAL_ADD_RDISTRIB; REAL_DIV_RMUL; + REAL_LT_IMP_NZ; REAL_LE_ADDL; NORM_POS_LE; REAL_SUB_REFL]);; + +let RELATIVE_FRONTIER_CLOSURE = prove + (`!s. convex s ==> relative_frontier(closure s) = relative_frontier s`, + SIMP_TAC[relative_frontier; CLOSURE_CLOSURE; + CONVEX_RELATIVE_INTERIOR_CLOSURE]);; + +let CONNECTED_INTER_RELATIVE_FRONTIER = prove + (`!s t:real^N->bool. + connected s /\ s SUBSET affine hull t /\ + ~(s INTER t = {}) /\ ~(s DIFF t = {}) + ==> ~(s INTER relative_frontier t = {})`, + REWRITE_TAC[relative_frontier] THEN REPEAT STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [CONNECTED_OPEN_IN]) THEN + REWRITE_TAC[] THEN MAP_EVERY EXISTS_TAC + [`s INTER relative_interior t:real^N->bool`; + `s DIFF closure t:real^N->bool`] THEN + REPEAT CONJ_TAC THENL + [MATCH_MP_TAC OPEN_IN_SUBTOPOLOGY_INTER_SUBSET THEN + EXISTS_TAC `affine hull t:real^N->bool` THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC OPEN_IN_INTER THEN + REWRITE_TAC[OPEN_IN_RELATIVE_INTERIOR; OPEN_IN_SUBTOPOLOGY_REFL] THEN + REWRITE_TAC[TOPSPACE_EUCLIDEAN; SUBSET_UNIV]; + ONCE_REWRITE_TAC[SET_RULE `s DIFF t = s INTER (UNIV DIFF t)`] THEN + MATCH_MP_TAC OPEN_IN_OPEN_INTER THEN + REWRITE_TAC[GSYM closed; CLOSED_CLOSURE]; + ASM SET_TAC[]; + MATCH_MP_TAC(SET_RULE + `i SUBSET t /\ t SUBSET c ==> (s INTER i) INTER (s DIFF c) = {}`) THEN + REWRITE_TAC[RELATIVE_INTERIOR_SUBSET; CLOSURE_SUBSET]; + MP_TAC(ISPEC `t:real^N->bool` CLOSURE_SUBSET) THEN ASM SET_TAC[]; + MP_TAC(ISPEC `t:real^N->bool` RELATIVE_INTERIOR_SUBSET) THEN + ASM SET_TAC[]]);; + +let CLOSED_RELATIVE_FRONTIER = prove + (`!s:real^N->bool. closed(relative_frontier s)`, + REPEAT GEN_TAC THEN REWRITE_TAC[relative_frontier] THEN + MATCH_MP_TAC CLOSED_IN_CLOSED_TRANS THEN + EXISTS_TAC `affine hull s:real^N->bool` THEN + REWRITE_TAC[CLOSED_AFFINE_HULL] THEN MATCH_MP_TAC CLOSED_IN_DIFF THEN + REWRITE_TAC[OPEN_IN_RELATIVE_INTERIOR] THEN + MATCH_MP_TAC CLOSED_SUBSET THEN REWRITE_TAC[CLOSED_CLOSURE] THEN + MATCH_MP_TAC(SET_RULE + `s SUBSET closure t /\ closure t = t ==> s SUBSET t`) THEN + SIMP_TAC[SUBSET_CLOSURE; HULL_SUBSET; CLOSURE_EQ; CLOSED_AFFINE_HULL]);; + +let CLOSED_RELATIVE_BOUNDARY = prove + (`!s. closed s ==> closed(s DIFF relative_interior s)`, + MESON_TAC[CLOSED_RELATIVE_FRONTIER; relative_frontier; CLOSURE_CLOSED]);; + +let COMPACT_RELATIVE_BOUNDARY = prove + (`!s. compact s ==> compact(s DIFF relative_interior s)`, + SIMP_TAC[COMPACT_EQ_BOUNDED_CLOSED; CLOSED_RELATIVE_BOUNDARY; + BOUNDED_DIFF]);; + +let BOUNDED_RELATIVE_FRONTIER = prove + (`!s:real^N->bool. bounded s ==> bounded(relative_frontier s)`, + REWRITE_TAC[relative_frontier] THEN + MESON_TAC[BOUNDED_CLOSURE; BOUNDED_SUBSET; SUBSET_DIFF]);; + +let COMPACT_RELATIVE_FRONTIER_BOUNDED = prove + (`!s:real^N->bool. bounded s ==> compact(relative_frontier s)`, + SIMP_TAC[COMPACT_EQ_BOUNDED_CLOSED; CLOSED_RELATIVE_FRONTIER; + BOUNDED_RELATIVE_FRONTIER]);; + +let COMPACT_RELATIVE_FRONTIER = prove + (`!s:real^N->bool. compact s ==> compact(relative_frontier s)`, + SIMP_TAC[COMPACT_RELATIVE_FRONTIER_BOUNDED; COMPACT_IMP_BOUNDED]);; + +let CONVEX_SAME_RELATIVE_INTERIOR_CLOSURE = prove + (`!s t. convex s /\ convex t + ==> (relative_interior s = relative_interior t <=> + closure s = closure t)`, + MESON_TAC[CONVEX_CLOSURE_RELATIVE_INTERIOR; + CONVEX_RELATIVE_INTERIOR_CLOSURE]);; + +let CONVEX_SAME_RELATIVE_INTERIOR_CLOSURE_STRADDLE = prove + (`!s t. convex s /\ convex t + ==> (relative_interior s = relative_interior t <=> + relative_interior s SUBSET t /\ t SUBSET closure s)`, + MESON_TAC[CONVEX_CLOSURE_RELATIVE_INTERIOR; + CONVEX_RELATIVE_INTERIOR_CLOSURE; SUBSET_CLOSURE; + SUBSET_ANTISYM; RELATIVE_INTERIOR_SUBSET; + CLOSURE_SUBSET; CLOSURE_CLOSURE]);; + +let RELATIVE_INTERIOR_LINEAR_IMAGE_CONVEX = prove + (`!f:real^M->real^N s. + linear f /\ convex s + ==> relative_interior(IMAGE f s) = IMAGE f (relative_interior s)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL + [SUBGOAL_THEN + `relative_interior (IMAGE f (relative_interior s)) = + relative_interior (IMAGE (f:real^M->real^N) s)` + (fun th -> REWRITE_TAC[SYM th; RELATIVE_INTERIOR_SUBSET]) THEN + ASM_SIMP_TAC[CONVEX_SAME_RELATIVE_INTERIOR_CLOSURE_STRADDLE; + CONVEX_RELATIVE_INTERIOR; CONVEX_LINEAR_IMAGE] THEN + CONJ_TAC THENL + [MATCH_MP_TAC SUBSET_TRANS THEN + EXISTS_TAC `IMAGE (f:real^M->real^N) (relative_interior s)` THEN + SIMP_TAC[RELATIVE_INTERIOR_SUBSET; IMAGE_SUBSET]; + MATCH_MP_TAC SUBSET_TRANS THEN EXISTS_TAC + `IMAGE (f:real^M->real^N) (closure(relative_interior s))` THEN + ASM_SIMP_TAC[CLOSURE_LINEAR_IMAGE_SUBSET] THEN + ASM_SIMP_TAC[CONVEX_CLOSURE_RELATIVE_INTERIOR] THEN + MATCH_MP_TAC IMAGE_SUBSET THEN REWRITE_TAC[CLOSURE_SUBSET]]; + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE] THEN X_GEN_TAC `z:real^M` THEN + DISCH_TAC THEN + ASM_SIMP_TAC[RELATIVE_INTERIOR_CONVEX_PROLONG; CONVEX_LINEAR_IMAGE] THEN + REWRITE_TAC[IN_ELIM_THM; FORALL_IN_IMAGE] THEN CONJ_TAC THENL + [MATCH_MP_TAC FUN_IN_IMAGE THEN + ASM_MESON_TAC[SUBSET; RELATIVE_INTERIOR_SUBSET]; + ALL_TAC] THEN + X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN + MP_TAC(ISPECL [`s:real^M->bool`; `z:real^M`; `x:real^M`] + RELATIVE_INTERIOR_PROLONG) THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `t:real` THEN + MATCH_MP_TAC MONO_AND THEN REWRITE_TAC[] THEN + DISCH_THEN(MP_TAC o ISPEC `f:real^M->real^N` o MATCH_MP FUN_IN_IMAGE) THEN + ASM_MESON_TAC[LINEAR_ADD; LINEAR_SUB; LINEAR_CMUL]]);; + +let CLOSURE_INTERS_CONVEX = prove + (`!f:(real^N->bool)->bool. + (!s. s IN f ==> convex s) /\ + ~(INTERS(IMAGE relative_interior f) = {}) + ==> closure(INTERS f) = INTERS(IMAGE closure f)`, + REPEAT STRIP_TAC THEN + MATCH_MP_TAC SUBSET_ANTISYM THEN REWRITE_TAC[CLOSURE_INTERS_SUBSET] THEN + REWRITE_TAC[SUBSET; IN_INTERS; FORALL_IN_IMAGE] THEN + X_GEN_TAC `b:real^N` THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN + REWRITE_TAC[INTERS_IMAGE; IN_ELIM_THM; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `a:real^N` THEN DISCH_TAC THEN + REWRITE_TAC[CLOSURE_APPROACHABLE] THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN + ASM_CASES_TAC `b:real^N = a` THENL + [EXISTS_TAC `a:real^N` THEN ASM_REWRITE_TAC[DIST_REFL; IN_INTERS] THEN + ASM_MESON_TAC[SUBSET; RELATIVE_INTERIOR_SUBSET]; + ALL_TAC] THEN + EXISTS_TAC `b - min (&1 / &2) (e / &2 / norm(b - a)) % (b - a):real^N` THEN + CONJ_TAC THENL + [ALL_TAC; + REWRITE_TAC[NORM_ARITH `dist(b - a:real^N,b) = norm a`; NORM_MUL] THEN + ASM_SIMP_TAC[GSYM REAL_LT_RDIV_EQ; NORM_POS_LT; VECTOR_SUB_EQ] THEN + MATCH_MP_TAC(REAL_ARITH + `&0 < a /\ &0 < x /\ x < y ==> abs(min a x) < y`) THEN + ASM_SIMP_TAC[REAL_LT_DIV2_EQ; REAL_HALF; REAL_LT_DIV; NORM_POS_LT; + VECTOR_SUB_EQ] THEN + ASM_REAL_ARITH_TAC] THEN + REWRITE_TAC[IN_INTERS] THEN X_GEN_TAC `s:real^N->bool` THEN DISCH_TAC THEN + MATCH_MP_TAC + (MESON[RELATIVE_INTERIOR_SUBSET; SUBSET] + `!x. x IN relative_interior s ==> x IN s`) THEN + MATCH_MP_TAC IN_RELATIVE_INTERIOR_CLOSURE_CONVEX_SHRINK THEN + ASM_SIMP_TAC[REAL_LT_MIN; REAL_HALF; REAL_LT_DIV; NORM_POS_LT; + VECTOR_SUB_EQ] THEN + REAL_ARITH_TAC);; + +let CLOSURE_INTERS_CONVEX_OPEN = prove + (`!f:(real^N->bool)->bool. + (!s. s IN f ==> convex s /\ open s) + ==> closure(INTERS f) = + if INTERS f = {} then {} + else INTERS(IMAGE closure f)`, + REPEAT STRIP_TAC THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[CLOSURE_EMPTY] THEN + MATCH_MP_TAC CLOSURE_INTERS_CONVEX THEN ASM_SIMP_TAC[] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE + `~(s = {}) ==> s = t ==> ~(t = {})`)) THEN + AP_TERM_TAC THEN MATCH_MP_TAC(SET_RULE + `(!x. x IN s ==> f x = x) ==> s = IMAGE f s`) THEN + ASM_SIMP_TAC[RELATIVE_INTERIOR_OPEN; INTERIOR_EQ]);; + +let CLOSURE_INTER_CONVEX = prove + (`!s t:real^N->bool. + convex s /\ convex t /\ + ~(relative_interior s INTER relative_interior t = {}) + ==> closure(s INTER t) = closure(s) INTER closure(t)`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPEC `{s:real^N->bool,t}` CLOSURE_INTERS_CONVEX) THEN + ASM_SIMP_TAC[IMAGE_CLAUSES; INTERS_2] THEN + ASM_REWRITE_TAC[FORALL_IN_INSERT; NOT_IN_EMPTY]);; + +let CLOSURE_INTER_CONVEX_OPEN = prove + (`!s t. convex s /\ open s /\ convex t /\ open t + ==> closure(s INTER t) = + if s INTER t = {} then {} else closure(s) INTER closure(t)`, + REPEAT STRIP_TAC THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[CLOSURE_EMPTY] THEN + MATCH_MP_TAC CLOSURE_INTER_CONVEX THEN + ASM_SIMP_TAC[RELATIVE_INTERIOR_OPEN]);; + +let CLOSURE_CONVEX_INTER_SUPERSET = prove + (`!s t:real^N->bool. + convex s /\ ~(interior s = {}) /\ interior s SUBSET closure t + ==> closure(s INTER t) = closure s`, + REPEAT GEN_TAC THEN DISCH_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN + SIMP_TAC[SUBSET_CLOSURE; INTER_SUBSET; SUBSET_INTER] THEN + MATCH_MP_TAC SUBSET_TRANS THEN + EXISTS_TAC `closure(interior s):real^N->bool` THEN CONJ_TAC THENL + [ASM_SIMP_TAC[CONVEX_CLOSURE_INTERIOR; SUBSET_REFL]; + ASM_SIMP_TAC[GSYM CLOSURE_OPEN_INTER_SUPERSET; OPEN_INTERIOR] THEN + MATCH_MP_TAC SUBSET_CLOSURE THEN + MP_TAC(ISPEC `s:real^N->bool` INTERIOR_SUBSET) THEN SET_TAC[]]);; + +let CLOSURE_DYADIC_RATIONALS_IN_CONVEX_SET = prove + (`!s:real^N->bool. + convex s /\ ~(interior s = {}) + ==> closure(s INTER + { inv(&2 pow n) % x | n,x | + !i. 1 <= i /\ i <= dimindex(:N) ==> integer(x$i) }) = + closure s`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC CLOSURE_CONVEX_INTER_SUPERSET THEN + ASM_REWRITE_TAC[CLOSURE_DYADIC_RATIONALS; SUBSET_UNIV]);; + +let CLOSURE_RATIONALS_IN_CONVEX_SET = prove + (`!s:real^N->bool. + convex s /\ ~(interior s = {}) + ==> closure(s INTER + { x | !i. 1 <= i /\ i <= dimindex(:N) ==> rational(x$i) }) = + closure s`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC CLOSURE_CONVEX_INTER_SUPERSET THEN + ASM_REWRITE_TAC[CLOSURE_RATIONAL_COORDINATES; SUBSET_UNIV]);; + +let RELATIVE_INTERIOR_CONVEX_INTER_AFFINE = prove + (`!s t:real^N->bool. + convex s /\ affine t /\ ~(interior s INTER t = {}) + ==> relative_interior(s INTER t) = interior s INTER t`, + REPEAT GEN_TAC THEN + REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; RIGHT_AND_EXISTS_THM] THEN + DISCH_THEN(X_CHOOSE_THEN `a:real^N` MP_TAC) THEN + GEOM_ORIGIN_TAC `a:real^N` THEN REWRITE_TAC[IN_INTER] THEN + REPEAT GEN_TAC THEN ASM_CASES_TAC `(vec 0:real^N) IN t` THEN + ASM_SIMP_TAC[AFFINE_EQ_SUBSPACE] THEN STRIP_TAC THEN + GEN_REWRITE_TAC I [EXTENSION] THEN X_GEN_TAC `x:real^N` THEN + MP_TAC(ISPECL [`t:real^N->bool`; `s:real^N->bool`] + (ONCE_REWRITE_RULE[INTER_COMM] + AFFINE_HULL_AFFINE_INTER_NONEMPTY_INTERIOR)) THEN + ASM_SIMP_TAC[SUBSPACE_IMP_AFFINE; IN_RELATIVE_INTERIOR_CBALL] THEN + ANTS_TAC THENL [ASM SET_TAC[]; REWRITE_TAC[IN_INTER; IN_INTERIOR_CBALL]] THEN + DISCH_THEN SUBST1_TAC THEN + ASM_CASES_TAC `(x:real^N) IN t` THEN ASM_REWRITE_TAC[] THEN + SIMP_TAC[SUBSET; IN_INTER] THEN + ASM_CASES_TAC `(x:real^N) IN s` THENL + [ASM_REWRITE_TAC[]; ASM_MESON_TAC[CENTRE_IN_CBALL; REAL_LT_IMP_LE]] THEN + EQ_TAC THENL [REWRITE_TAC[IN_CBALL]; MESON_TAC[]] THEN + DISCH_THEN(X_CHOOSE_THEN `e:real` STRIP_ASSUME_TAC) THEN + ASM_CASES_TAC `x:real^N = vec 0` THENL + [FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_INTERIOR_CBALL]) THEN + ASM_REWRITE_TAC[SUBSET; IN_CBALL]; + ALL_TAC] THEN + MP_TAC(ISPECL + [`s:real^N->bool`; `vec 0:real^N`; `(&1 + e / norm x) % x:real^N`] + IN_INTERIOR_CLOSURE_CONVEX_SEGMENT) THEN + ASM_REWRITE_TAC[] THEN ANTS_TAC THENL + [MATCH_MP_TAC(REWRITE_RULE[SUBSET] CLOSURE_SUBSET) THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_SIMP_TAC[SUBSPACE_MUL] THEN + REWRITE_TAC[VECTOR_ADD_RDISTRIB; VECTOR_MUL_LID; + NORM_ARITH `dist(a:real^N,a + x) = norm x`] THEN + ASM_SIMP_TAC[NORM_MUL; REAL_ABS_DIV; REAL_ABS_NORM; + REAL_DIV_RMUL; NORM_EQ_0] THEN + ASM_REAL_ARITH_TAC; + REWRITE_TAC[SUBSET; IN_INTERIOR_CBALL; IN_CBALL] THEN + DISCH_THEN MATCH_MP_TAC THEN REWRITE_TAC[IN_SEGMENT] THEN + CONV_TAC(ONCE_DEPTH_CONV SYM_CONV) THEN + ASM_REWRITE_TAC[VECTOR_MUL_EQ_0; VECTOR_MUL_RZERO; VECTOR_ADD_LID] THEN + REWRITE_TAC[RIGHT_AND_EXISTS_THM] THEN + EXISTS_TAC `inv(&1 + e / norm(x:real^N))` THEN + ASM_SIMP_TAC[VECTOR_MUL_ASSOC; REAL_LT_DIV; NORM_POS_LT; VECTOR_MUL_LID; + REAL_LT_INV_EQ; REAL_MUL_LINV; REAL_INV_LT_1; REAL_ARITH + `&0 < x ==> &1 < &1 + x /\ &0 < &1 + x /\ ~(&1 + x = &0)`]]);; + +(* ------------------------------------------------------------------------- *) +(* Homeomorphism of all convex compact sets with same affine dimension, and *) +(* in particular all those with nonempty interior. *) +(* ------------------------------------------------------------------------- *) + +let COMPACT_FRONTIER_LINE_LEMMA = prove + (`!s x. compact s /\ (vec 0 IN s) /\ ~(x = vec 0 :real^N) + ==> ?u. &0 <= u /\ (u % x) IN frontier s /\ + !v. u < v ==> ~((v % x) IN s)`, + REPEAT STRIP_TAC THEN FIRST_ASSUM(MP_TAC o MATCH_MP COMPACT_IMP_BOUNDED) THEN + REWRITE_TAC[BOUNDED_POS] THEN + DISCH_THEN(X_CHOOSE_THEN `b:real` STRIP_ASSUME_TAC) THEN + MP_TAC(ISPECL + [`{y:real^N | ?u. &0 <= u /\ u <= b / norm(x) /\ (y = u % x)} INTER s`; + `vec 0:real^N`] + DISTANCE_ATTAINS_SUP) THEN + ANTS_TAC THENL + [CONJ_TAC THENL + [ALL_TAC; + REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN EXISTS_TAC `vec 0:real^N` THEN + ASM_REWRITE_TAC[IN_INTER; IN_ELIM_THM] THEN + EXISTS_TAC `&0` THEN + ASM_SIMP_TAC[VECTOR_MUL_LZERO; REAL_LE_REFL; REAL_LT_IMP_LE; + REAL_LT_DIV; NORM_POS_LT]] THEN + MATCH_MP_TAC COMPACT_INTER THEN ASM_REWRITE_TAC[] THEN + SUBGOAL_THEN + `{y:real^N | ?u. &0 <= u /\ u <= b / norm(x) /\ (y = u % x)} = + IMAGE (\u. drop u % x) (interval [vec 0,lambda i. b / norm(x:real^N)])` + SUBST1_TAC THENL + [REWRITE_TAC[EXTENSION; IN_ELIM_THM; IN_IMAGE; IN_INTERVAL] THEN + SIMP_TAC[LAMBDA_BETA] THEN + SIMP_TAC[DIMINDEX_1; ARITH_RULE `1 <= i /\ i <= 1 <=> (i = 1)`] THEN + REWRITE_TAC[GSYM drop; LEFT_FORALL_IMP_THM; EXISTS_REFL; DROP_VEC] THEN + REWRITE_TAC[EXISTS_LIFT; LIFT_DROP] THEN MESON_TAC[]; + ALL_TAC] THEN + MATCH_MP_TAC COMPACT_CONTINUOUS_IMAGE THEN + REWRITE_TAC[COMPACT_INTERVAL] THEN + MATCH_MP_TAC CONTINUOUS_AT_IMP_CONTINUOUS_ON THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC CONTINUOUS_VMUL THEN + REWRITE_TAC[o_DEF; LIFT_DROP; CONTINUOUS_AT_ID]; + ALL_TAC] THEN + REWRITE_TAC[IN_INTER; IN_ELIM_THM; LEFT_AND_EXISTS_THM] THEN + ONCE_REWRITE_TAC[TAUT `(a /\ b /\ c) /\ d <=> c /\ a /\ b /\ d`] THEN + SIMP_TAC[LEFT_IMP_EXISTS_THM] THEN ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN + GEN_REWRITE_TAC (BINDER_CONV o ONCE_DEPTH_CONV) [SWAP_FORALL_THM] THEN + SIMP_TAC[IMP_CONJ] THEN + REWRITE_TAC[LEFT_FORALL_IMP_THM; EXISTS_REFL] THEN + REWRITE_TAC[IMP_IMP] THEN REWRITE_TAC[LEFT_FORALL_IMP_THM] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `u:real` THEN + REWRITE_TAC[dist; VECTOR_SUB_LZERO; NORM_NEG; NORM_MUL] THEN + ASM_SIMP_TAC[REAL_LE_RMUL_EQ; NORM_POS_LT] THEN + DISCH_THEN(CONJUNCTS_THEN2 STRIP_ASSUME_TAC MP_TAC) THEN + ASM_SIMP_TAC[real_abs] THEN REPEAT STRIP_TAC THENL + [REWRITE_TAC[FRONTIER_STRADDLE] THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN + CONJ_TAC THENL + [EXISTS_TAC `u % x :real^N` THEN ASM_REWRITE_TAC[DIST_REFL]; + ALL_TAC] THEN + EXISTS_TAC `(u + (e / &2) / norm(x)) % x :real^N` THEN + REWRITE_TAC[dist; VECTOR_ARITH `u % x - (u + a) % x = --(a % x)`] THEN + ASM_SIMP_TAC[NORM_NEG; NORM_MUL; REAL_ABS_DIV; REAL_ABS_NORM; NORM_EQ_0; + REAL_DIV_RMUL; REAL_ABS_NUM; REAL_LT_LDIV_EQ; REAL_OF_NUM_LT; + ARITH; REAL_ARITH `abs e < e * &2 <=> &0 < e`] THEN + DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `u + (e / &2) / norm(x:real^N)`) THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC(REAL_ARITH + `&0 < e /\ &0 <= u /\ u + e <= b + ==> ~(&0 <= u + e /\ u + e <= b ==> u + e <= u)`) THEN + ASM_SIMP_TAC[REAL_LT_DIV; REAL_OF_NUM_LT; ARITH; NORM_POS_LT] THEN + FIRST_X_ASSUM(MP_TAC o SPEC `(u + (e / &2) / norm(x:real^N)) % x`) THEN + ASM_SIMP_TAC[NORM_MUL; GSYM REAL_LE_RDIV_EQ; NORM_POS_LT] THEN + REAL_ARITH_TAC; + ALL_TAC] THEN + FIRST_X_ASSUM(MP_TAC o SPEC `v:real`) THEN + ASM_REWRITE_TAC[GSYM REAL_NOT_LT] THEN ASM_REWRITE_TAC[REAL_NOT_LT] THEN + CONJ_TAC THENL [ASM_MESON_TAC[REAL_LET_TRANS; REAL_LT_IMP_LE]; ALL_TAC] THEN + FIRST_X_ASSUM(MP_TAC o SPEC `v % x:real^N`) THEN + ASM_SIMP_TAC[NORM_MUL; GSYM REAL_LE_RDIV_EQ; NORM_POS_LT] THEN + REAL_ARITH_TAC);; + +let STARLIKE_COMPACT_PROJECTIVE = prove + (`!s:real^N->bool a. + compact s /\ a IN relative_interior s /\ + (!x. x IN s ==> segment(a,x) SUBSET relative_interior s) + ==> s DIFF relative_interior s homeomorphic + sphere(a,&1) INTER affine hull s /\ + s homeomorphic cball(a,&1) INTER affine hull s`, + REPEAT GEN_TAC THEN GEOM_ORIGIN_TAC `a:real^N` THEN + REWRITE_TAC[SUBSET; IMP_IMP; RIGHT_IMP_FORALL_THM] THEN + GEN_TAC THEN STRIP_TAC THEN + SUBGOAL_THEN + `!x:real^N u. x IN s /\ &0 <= u /\ u < &1 + ==> (u % x) IN relative_interior s` + ASSUME_TAC THENL + [REWRITE_TAC[REAL_ARITH `&0 <= u <=> u = &0 \/ &0 < u`] THEN + REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[VECTOR_MUL_LZERO] THEN + ASM_CASES_TAC `x:real^N = vec 0` THEN + ASM_REWRITE_TAC[VECTOR_MUL_RZERO] THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[IN_SEGMENT] THEN + REWRITE_TAC[VECTOR_MUL_RZERO; VECTOR_ADD_LID] THEN ASM_MESON_TAC[]; + FIRST_X_ASSUM(K ALL_TAC o SPECL [`x:real^N`; `x:real^N`])] THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP (REWRITE_RULE[SUBSET] + RELATIVE_INTERIOR_SUBSET)) THEN + ABBREV_TAC `proj = \x:real^N. inv(norm(x)) % x` THEN + SUBGOAL_THEN + `!x:real^N y. (proj(x) = proj(y):real^N) /\ (norm x = norm y) <=> (x = y)` + ASSUME_TAC THENL + [REPEAT GEN_TAC THEN EQ_TAC THENL [ALL_TAC; MESON_TAC[]] THEN + ASM_CASES_TAC `y:real^N = vec 0` THEN + ASM_SIMP_TAC[NORM_EQ_0; NORM_0] THEN + ASM_CASES_TAC `x:real^N = vec 0` THENL + [ASM_MESON_TAC[NORM_EQ_0]; ALL_TAC] THEN + DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN + EXPAND_TAC "proj" THEN REWRITE_TAC[] THEN + ASM_REWRITE_TAC[VECTOR_ARITH + `a % x = a % y <=> a % (x - y):real^N = vec 0`] THEN + ASM_REWRITE_TAC[VECTOR_MUL_EQ_0; REAL_INV_EQ_0; NORM_EQ_0; VECTOR_SUB_EQ]; + ALL_TAC] THEN + SUBGOAL_THEN + `(!x. x IN affine hull s ==> proj x IN affine hull s) /\ + (!x. ~(x = vec 0) ==> norm(proj x) = &1) /\ + (!x:real^N. proj x = vec 0 <=> x = vec 0)` + STRIP_ASSUME_TAC THENL + [EXPAND_TAC "proj" THEN REWRITE_TAC[NORM_MUL; VECTOR_MUL_EQ_0] THEN + REWRITE_TAC[REAL_INV_EQ_0; NORM_EQ_0; REAL_ABS_INV; REAL_ABS_NORM] THEN + SIMP_TAC[REAL_MUL_LINV; NORM_EQ_0] THEN REPEAT STRIP_TAC THEN + GEN_REWRITE_TAC LAND_CONV [GSYM VECTOR_ADD_LID] THEN + MATCH_MP_TAC IN_AFFINE_ADD_MUL THEN + ASM_SIMP_TAC[AFFINE_AFFINE_HULL; VECTOR_ADD_LID; HULL_INC]; + ALL_TAC] THEN + SUBGOAL_THEN `(proj:real^N->real^N) continuous_on (UNIV DELETE vec 0)` + ASSUME_TAC THENL + [MATCH_MP_TAC CONTINUOUS_AT_IMP_CONTINUOUS_ON THEN + REWRITE_TAC[IN_DELETE; IN_UNIV] THEN EXPAND_TAC "proj" THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC CONTINUOUS_MUL THEN + ASM_SIMP_TAC[CONTINUOUS_AT_ID] THEN + REWRITE_TAC[GSYM(ISPEC `lift` o_DEF); + GSYM(ISPEC `inv:real->real` o_DEF)] THEN + MATCH_MP_TAC CONTINUOUS_AT_INV THEN + ASM_REWRITE_TAC[NORM_EQ_0; VECTOR_SUB_EQ; CONTINUOUS_AT_LIFT_NORM]; + ALL_TAC] THEN + ABBREV_TAC `usph = {x:real^N | x IN affine hull s /\ norm x = &1}` THEN + SUBGOAL_THEN ` sphere(vec 0:real^N,&1) INTER affine hull s = usph` + SUBST1_TAC THENL + [EXPAND_TAC "usph" THEN REWRITE_TAC[EXTENSION; IN_INTER; IN_SPHERE_0] THEN + SET_TAC[]; + ALL_TAC] THEN + SUBGOAL_THEN + `!x. x IN affine hull s /\ ~(x = vec 0) + ==> (proj:real^N->real^N) x IN usph` + ASSUME_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + SUBGOAL_THEN `?surf. homeomorphism (s DIFF relative_interior s,usph) + (proj:real^N->real^N,surf)` + MP_TAC THENL + [MATCH_MP_TAC HOMEOMORPHISM_COMPACT THEN + ASM_SIMP_TAC[COMPACT_RELATIVE_BOUNDARY] THEN REPEAT CONJ_TAC THENL + [FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET)) THEN + ASM SET_TAC[]; + MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL + [REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; IN_DIFF] THEN + EXPAND_TAC "usph" THEN REWRITE_TAC[IN_ELIM_THM] THEN + ASM_MESON_TAC[HULL_INC]; + MAP_EVERY EXPAND_TAC ["proj"; "usph"] THEN + REWRITE_TAC[SUBSET; IN_ELIM_THM] THEN X_GEN_TAC `x:real^N` THEN + ASM_CASES_TAC `x:real^N = vec 0` THEN + ASM_REWRITE_TAC[NORM_0; REAL_OF_NUM_EQ; ARITH_EQ] THEN STRIP_TAC THEN + MP_TAC(ISPECL [`s:real^N->bool`; `vec 0:real^N`; `x:real^N`] + RAY_TO_RELATIVE_FRONTIER) THEN + REWRITE_TAC[relative_frontier] THEN + ASM_SIMP_TAC[COMPACT_IMP_BOUNDED; CLOSURE_CLOSED; COMPACT_IMP_CLOSED; + VECTOR_ADD_LID] THEN + DISCH_THEN(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC) THEN + EXPAND_TAC "proj" THEN REWRITE_TAC[IN_IMAGE] THEN + EXISTS_TAC `d % x:real^N` THEN ASM_REWRITE_TAC[NORM_MUL] THEN + ASM_SIMP_TAC[REAL_MUL_RID; real_abs; REAL_LT_IMP_LE] THEN + ASM_SIMP_TAC[VECTOR_MUL_ASSOC; REAL_MUL_LINV; REAL_LT_IMP_NZ; + VECTOR_MUL_LID]]; + MAP_EVERY X_GEN_TAC [`x:real^N`; `y:real^N`] THEN + REWRITE_TAC[IN_DIFF] THEN STRIP_TAC THEN + ASM_CASES_TAC `x:real^N = vec 0` THENL [ASM SET_TAC[]; ALL_TAC] THEN + ASM_CASES_TAC `y:real^N = vec 0` THENL [ASM SET_TAC[]; ALL_TAC] THEN + UNDISCH_TAC `(proj:real^N->real^N) x = proj y` THEN + EXPAND_TAC "proj" THEN + REPEAT_TCL DISJ_CASES_THEN ASSUME_TAC (REAL_ARITH + `norm(x:real^N) = norm(y:real^N) \/ + norm x < norm y \/ norm y < norm x`) + THENL + [ASM_REWRITE_TAC[VECTOR_MUL_LCANCEL; REAL_INV_EQ_0; NORM_EQ_0]; + DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o SPECL + [`y:real^N`; `norm(x:real^N) / norm(y:real^N)`]); + DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o SPECL + [`x:real^N`; `norm(y:real^N) / norm(x:real^N)`])] THEN + ASM_SIMP_TAC[REAL_LE_DIV; NORM_POS_LE; REAL_LT_LDIV_EQ; NORM_POS_LT; + REAL_MUL_LID] THEN + ASM_REWRITE_TAC[real_div; GSYM VECTOR_MUL_ASSOC] THENL + [FIRST_X_ASSUM(SUBST1_TAC o SYM); ALL_TAC] THEN + ASM_SIMP_TAC[VECTOR_MUL_ASSOC; REAL_MUL_RINV; NORM_EQ_0] THEN + ASM_REWRITE_TAC[VECTOR_MUL_LID]]; + DISCH_THEN(fun th -> + CONJ_TAC THENL + [MESON_TAC[homeomorphic; th]; + ONCE_REWRITE_TAC[HOMEOMORPHIC_SYM] THEN + MATCH_MP_TAC HOMEOMORPHIC_COMPACT THEN + SIMP_TAC[COMPACT_INTER_CLOSED; CLOSED_AFFINE_HULL; COMPACT_CBALL] THEN + MP_TAC th]) THEN + REWRITE_TAC[HOMEOMORPHISM; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `surf:real^N->real^N` THEN STRIP_TAC THEN + EXISTS_TAC `\x:real^N. norm(x) % (surf:real^N->real^N)(proj(x))` THEN + REWRITE_TAC[]] THEN + UNDISCH_THEN + `(proj:real^N->real^N) continuous_on s DIFF relative_interior s` + (K ALL_TAC) THEN + REWRITE_TAC[] THEN CONJ_TAC THENL + [REWRITE_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN; IN_INTER] THEN + X_GEN_TAC `x:real^N` THEN STRIP_TAC THEN + ASM_CASES_TAC `x = vec 0:real^N` THENL + [ASM_REWRITE_TAC[CONTINUOUS_WITHIN; VECTOR_MUL_LZERO; NORM_0] THEN + MATCH_MP_TAC LIM_NULL_VMUL_BOUNDED THEN + FIRST_ASSUM(MP_TAC o MATCH_MP COMPACT_IMP_BOUNDED) THEN + REWRITE_TAC[BOUNDED_POS] THEN MATCH_MP_TAC MONO_EXISTS THEN + REPEAT STRIP_TAC THENL + [REWRITE_TAC[LIM_WITHIN; o_THM; DIST_0; NORM_LIFT; REAL_ABS_NORM] THEN + MESON_TAC[]; + REWRITE_TAC[EVENTUALLY_WITHIN] THEN EXISTS_TAC `&1` THEN + REWRITE_TAC[REAL_LT_01; IN_INTER; DIST_0; NORM_POS_LT] THEN + ASM SET_TAC[]]; + MATCH_MP_TAC CONTINUOUS_WITHIN_SUBSET THEN + EXISTS_TAC `affine hull s:real^N->bool` THEN + REWRITE_TAC[INTER_SUBSET] THEN MATCH_MP_TAC CONTINUOUS_MUL THEN + SIMP_TAC[CONTINUOUS_LIFT_NORM_COMPOSE; CONTINUOUS_WITHIN_ID; o_DEF] THEN + SUBGOAL_THEN + `((surf:real^N->real^N) o (proj:real^N->real^N)) continuous_on + (affine hull s DELETE vec 0)` + MP_TAC THENL + [MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN + ASM_REWRITE_TAC[] THEN CONJ_TAC THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET)) THEN + SIMP_TAC[SUBSET; IN_DELETE; IN_UNIV; FORALL_IN_IMAGE] THEN + EXPAND_TAC "usph" THEN ASM_SIMP_TAC[IN_ELIM_THM]; + SIMP_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN] THEN + DISCH_THEN(MP_TAC o SPEC `x:real^N`) THEN ASM_SIMP_TAC[IN_DELETE] THEN + REWRITE_TAC[CONTINUOUS_WITHIN; o_DEF] THEN MATCH_MP_TAC EQ_IMP THEN + MATCH_MP_TAC LIM_TRANSFORM_WITHIN_SET THEN + REWRITE_TAC[EVENTUALLY_AT] THEN EXISTS_TAC `norm(x:real^N)` THEN + ASM_REWRITE_TAC[IN_DELETE; IN_INTER; IN_CBALL; NORM_POS_LT] THEN + X_GEN_TAC `y:real^N` THEN + ASM_CASES_TAC `(y:real^N) IN affine hull s` THEN ASM_REWRITE_TAC[] THEN + CONV_TAC NORM_ARITH]]; + ALL_TAC] THEN + SUBGOAL_THEN + `!a x. &0 < a ==> (proj:real^N->real^N)(a % x) = proj x` + ASSUME_TAC THENL + [REPEAT GEN_TAC THEN EXPAND_TAC "proj" THEN + REWRITE_TAC[NORM_MUL; REAL_INV_MUL; VECTOR_MUL_ASSOC] THEN + SIMP_TAC[REAL_FIELD `&0 < a ==> (inv(a) * x) * a = x`; real_abs; + REAL_LT_IMP_LE]; + ALL_TAC] THEN + CONJ_TAC THENL + [ALL_TAC; + MAP_EVERY X_GEN_TAC [`x:real^N`; `y:real^N`] THEN + ASM_CASES_TAC `y:real^N = vec 0` THENL + [ASM_SIMP_TAC[VECTOR_MUL_LZERO; VECTOR_MUL_EQ_0; NORM_0; NORM_EQ_0] THEN + ASM SET_TAC[]; + ALL_TAC] THEN + ASM_CASES_TAC `x:real^N = vec 0` THENL + [CONV_TAC(ONCE_DEPTH_CONV SYM_CONV) THEN + ASM_SIMP_TAC[VECTOR_MUL_LZERO; VECTOR_MUL_EQ_0; NORM_0; NORM_EQ_0] THEN + ASM SET_TAC[]; + ALL_TAC] THEN + REWRITE_TAC[IN_INTER; IN_CBALL_0] THEN + REPEAT(DISCH_THEN(CONJUNCTS_THEN2 STRIP_ASSUME_TAC MP_TAC)) THEN + DISCH_THEN(fun th -> MP_TAC th THEN + MP_TAC(AP_TERM `proj:real^N->real^N` th)) THEN + ASM_SIMP_TAC[NORM_POS_LT; VECTOR_MUL_RCANCEL] THEN ASM SET_TAC[]] THEN + MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL + [REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; IN_INTER; IN_CBALL_0] THEN + X_GEN_TAC `x:real^N` THEN ASM_CASES_TAC `x:real^N = vec 0` THEN + ASM_REWRITE_TAC[NORM_0; VECTOR_MUL_LZERO; IN_INTER] THEN + REWRITE_TAC[IN_CBALL_0; REAL_LE_LT] THEN STRIP_TAC THENL + [MATCH_MP_TAC(REWRITE_RULE[SUBSET] RELATIVE_INTERIOR_SUBSET) THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[NORM_POS_LE] THEN + ASM SET_TAC[]; + ASM_REWRITE_TAC[VECTOR_MUL_LID] THEN ASM SET_TAC[]]; + ALL_TAC] THEN + REWRITE_TAC[SUBSET; IN_IMAGE; IN_CBALL_0; IN_INTER] THEN + X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN + ASM_CASES_TAC `x:real^N = vec 0` THENL + [EXISTS_TAC `vec 0:real^N` THEN + ASM_SIMP_TAC[NORM_0; VECTOR_MUL_LZERO; HULL_INC; REAL_POS]; + ALL_TAC] THEN + SUBGOAL_THEN + `!x. x IN usph ==> ~((surf:real^N->real^N) x = vec 0)` + ASSUME_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + EXISTS_TAC `inv(norm(surf(proj x:real^N):real^N)) % x:real^N` THEN + FIRST_ASSUM(fun th -> GEN_REWRITE_TAC LAND_CONV [GSYM th]) THEN + REWRITE_TAC[GSYM CONJ_ASSOC] THEN + ASM (CONV_TAC o GEN_SIMPLIFY_CONV TOP_DEPTH_SQCONV (basic_ss []) 5) + [NORM_POS_LT; REAL_LT_INV_EQ; HULL_INC; REAL_LT_MUL; NORM_MUL; + REAL_ABS_INV; REAL_ABS_NORM] THEN + REPEAT CONJ_TAC THENL + [MATCH_MP_TAC(REAL_FIELD `~(y = &0) ==> x = (inv y * x) * y`) THEN + ASM_SIMP_TAC[NORM_EQ_0; HULL_INC]; + ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN + ASM (CONV_TAC o GEN_SIMPLIFY_CONV TOP_DEPTH_SQCONV (basic_ss []) 5) + [GSYM real_div; REAL_LE_LDIV_EQ; NORM_POS_LT; HULL_INC; REAL_MUL_LID] THEN + FIRST_X_ASSUM(MP_TAC o SPECL + [`x:real^N`; `norm(surf(proj x:real^N):real^N) / norm(x:real^N)`]) THEN + ASM_SIMP_TAC[REAL_LE_DIV; NORM_POS_LE; REAL_LT_LDIV_EQ; NORM_POS_LT] THEN + GEN_REWRITE_TAC LAND_CONV [GSYM CONTRAPOS_THM] THEN + REWRITE_TAC[REAL_NOT_LT; REAL_MUL_LID] THEN DISCH_THEN MATCH_MP_TAC THEN + SUBGOAL_THEN + `norm(surf(proj x)) / norm x % x:real^N = surf(proj x:real^N)` + SUBST1_TAC THENL + [FIRST_X_ASSUM(fun th -> GEN_REWRITE_TAC I [GSYM th]) THEN + ASM (CONV_TAC o GEN_SIMPLIFY_CONV TOP_DEPTH_SQCONV (basic_ss []) 5) + [NORM_POS_LT; REAL_LT_INV_EQ; HULL_INC; REAL_LT_MUL; NORM_MUL; + REAL_ABS_INV; REAL_ABS_NORM; REAL_ABS_DIV; REAL_LT_DIV; + REAL_DIV_RMUL; NORM_EQ_0]; + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE + `IMAGE f s SUBSET t DIFF u ==> x IN s ==> ~(f x IN u)`)) THEN + ASM_SIMP_TAC[HULL_INC]]; + GEN_REWRITE_TAC LAND_CONV [GSYM VECTOR_ADD_LID] THEN + MATCH_MP_TAC IN_AFFINE_ADD_MUL THEN + ASM_SIMP_TAC[AFFINE_AFFINE_HULL; VECTOR_ADD_LID; HULL_INC]]);; + +let HOMEOMORPHIC_CONVEX_COMPACT_SETS, + HOMEOMORPHIC_RELATIVE_FRONTIERS_CONVEX_BOUNDED_SETS = (CONJ_PAIR o prove) + (`(!s:real^M->bool t:real^N->bool. + convex s /\ compact s /\ convex t /\ compact t /\ aff_dim s = aff_dim t + ==> s homeomorphic t) /\ + (!s:real^M->bool t:real^N->bool. + convex s /\ bounded s /\ convex t /\ bounded t /\ aff_dim s = aff_dim t + ==> relative_frontier s homeomorphic relative_frontier t)`, + let lemma = prove + (`!s:real^M->bool t:real^N->bool. + convex s /\ compact s /\ convex t /\ compact t /\ + aff_dim s = aff_dim t + ==> (s DIFF relative_interior s) homeomorphic + (t DIFF relative_interior t) /\ + s homeomorphic t`, + REPEAT GEN_TAC THEN + REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + ASM_CASES_TAC `relative_interior t:real^N->bool = {}` THENL + [UNDISCH_TAC `relative_interior t:real^N->bool = {}` THEN + ASM_SIMP_TAC[AFF_DIM_EMPTY; AFF_DIM_EQ_MINUS1; + EMPTY_DIFF; HOMEOMORPHIC_EMPTY; RELATIVE_INTERIOR_EQ_EMPTY]; + FIRST_X_ASSUM(X_CHOOSE_THEN `b:real^N` MP_TAC o + GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY])] THEN + CONV_TAC(ONCE_DEPTH_CONV SYM_CONV) THEN + ASM_CASES_TAC `relative_interior s:real^M->bool = {}` THENL + [UNDISCH_TAC `relative_interior s:real^M->bool = {}` THEN + ASM_SIMP_TAC[AFF_DIM_EMPTY; AFF_DIM_EQ_MINUS1; + EMPTY_DIFF; HOMEOMORPHIC_EMPTY; RELATIVE_INTERIOR_EQ_EMPTY]; + FIRST_X_ASSUM(X_CHOOSE_THEN `a:real^M` MP_TAC o + GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY])] THEN + REPEAT(POP_ASSUM MP_TAC) THEN + GEOM_ORIGIN_TAC `b:real^N` THEN REPEAT GEN_TAC THEN + GEOM_ORIGIN_TAC `a:real^M` THEN REPEAT GEN_TAC THEN + REPEAT DISCH_TAC THEN + MP_TAC(ISPECL [`s:real^M->bool`; `vec 0:real^M`] + STARLIKE_COMPACT_PROJECTIVE) THEN + MP_TAC(ISPECL [`t:real^N->bool`; `vec 0:real^N`] + STARLIKE_COMPACT_PROJECTIVE) THEN + ASM_SIMP_TAC[IN_RELATIVE_INTERIOR_CLOSURE_CONVEX_SEGMENT; + REWRITE_RULE[SUBSET] CLOSURE_SUBSET] THEN + DISCH_THEN(fun th -> MATCH_MP_TAC MONO_AND THEN MP_TAC th) THEN + MATCH_MP_TAC MONO_AND THEN CONJ_TAC THEN + DISCH_THEN(fun th -> + MATCH_MP_TAC(ONCE_REWRITE_RULE[IMP_CONJ_ALT] HOMEOMORPHIC_TRANS) THEN + MP_TAC(ONCE_REWRITE_RULE[HOMEOMORPHIC_SYM] th)) THEN + MATCH_MP_TAC(ONCE_REWRITE_RULE[IMP_CONJ] HOMEOMORPHIC_TRANS) THEN + REPEAT(FIRST_X_ASSUM(ASSUME_TAC o MATCH_MP (REWRITE_RULE[SUBSET] + RELATIVE_INTERIOR_SUBSET))) THEN + FIRST_X_ASSUM(MP_TAC o SYM) THEN + ASM_SIMP_TAC[AFFINE_HULL_EQ_SPAN; HULL_INC; AFF_DIM_DIM_0] THEN + REWRITE_TAC[INT_OF_NUM_EQ] THEN DISCH_TAC THEN + MP_TAC(ISPECL [`span s:real^M->bool`; `span t:real^N->bool`] + ISOMETRIES_SUBSPACES) THEN + ASM_REWRITE_TAC[SUBSPACE_SPAN; DIM_SPAN; homeomorphic; HOMEOMORPHISM] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `f:real^M->real^N` THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `g:real^N->real^M` THEN + SIMP_TAC[SUBSET; FORALL_IN_IMAGE; IN_INTER; IN_CBALL_0; IN_SPHERE_0] THEN + SIMP_TAC[LINEAR_CONTINUOUS_ON] THEN ASM SET_TAC[]) in + SIMP_TAC[lemma; relative_frontier] THEN REPEAT STRIP_TAC THEN + MP_TAC(SPECL [`closure s:real^M->bool`; `closure t:real^N->bool`] lemma) THEN + ASM_SIMP_TAC[CONVEX_CLOSURE; COMPACT_CLOSURE; AFF_DIM_CLOSURE] THEN + ASM_SIMP_TAC[CONVEX_RELATIVE_INTERIOR_CLOSURE]);; + +let HOMEOMORPHIC_CONVEX_COMPACT = prove + (`!s:real^N->bool t:real^N->bool. + convex s /\ compact s /\ ~(interior s = {}) /\ + convex t /\ compact t /\ ~(interior t = {}) + ==> s homeomorphic t`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC HOMEOMORPHIC_CONVEX_COMPACT_SETS THEN + ASM_SIMP_TAC[AFF_DIM_NONEMPTY_INTERIOR]);; + +let HOMEOMORPHIC_CONVEX_COMPACT_CBALL = prove + (`!s:real^N->bool b:real^N e. + convex s /\ compact s /\ ~(interior s = {}) /\ &0 < e + ==> s homeomorphic cball(b,e)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC HOMEOMORPHIC_CONVEX_COMPACT THEN + ASM_REWRITE_TAC[COMPACT_CBALL; INTERIOR_CBALL; CONVEX_CBALL] THEN + ASM_REWRITE_TAC[BALL_EQ_EMPTY; REAL_NOT_LE]);; + +let HOMEOMORPHIC_CLOSED_INTERVALS = prove + (`!a b:real^N c d:real^N. + ~(interval(a,b) = {}) /\ ~(interval(c,d) = {}) + ==> interval[a,b] homeomorphic interval[c,d]`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC HOMEOMORPHIC_CONVEX_COMPACT THEN + REWRITE_TAC[CONVEX_INTERVAL; COMPACT_INTERVAL] THEN + ASM_REWRITE_TAC[INTERIOR_CLOSED_INTERVAL]);; + +(* ------------------------------------------------------------------------- *) +(* More about affine dimension of special sets. *) +(* ------------------------------------------------------------------------- *) + +let AFF_DIM_NONEMPTY_INTERIOR_EQ = prove + (`!s:real^N->bool. + convex s ==> (aff_dim s = &(dimindex (:N)) <=> ~(interior s = {}))`, + REPEAT STRIP_TAC THEN EQ_TAC THEN + ASM_SIMP_TAC[AFF_DIM_NONEMPTY_INTERIOR] THEN + REPEAT STRIP_TAC THEN + MP_TAC(ISPEC `s:real^N->bool` EMPTY_INTERIOR_SUBSET_HYPERPLANE) THEN + ASM_REWRITE_TAC[] THEN STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o MATCH_MP AFF_DIM_SUBSET) THEN + ASM_SIMP_TAC[AFF_DIM_HYPERPLANE] THEN INT_ARITH_TAC);; + +let AFF_DIM_BALL = prove + (`!a:real^N r. + aff_dim(ball(a,r)) = if &0 < r then &(dimindex(:N)) else --(&1)`, + REPEAT GEN_TAC THEN COND_CASES_TAC THENL + [MATCH_MP_TAC AFF_DIM_OPEN THEN + ASM_REWRITE_TAC[OPEN_BALL; BALL_EQ_EMPTY; REAL_NOT_LE]; + RULE_ASSUM_TAC(REWRITE_RULE[REAL_NOT_LT; GSYM BALL_EQ_EMPTY]) THEN + ASM_REWRITE_TAC[AFF_DIM_EMPTY]]);; + +let AFF_DIM_CBALL = prove + (`!a:real^N r. + aff_dim(cball(a,r)) = + if &0 < r then &(dimindex(:N)) + else if r = &0 then &0 else --(&1)`, + REPEAT GEN_TAC THEN REPEAT COND_CASES_TAC THENL + [MATCH_MP_TAC AFF_DIM_NONEMPTY_INTERIOR THEN + ASM_REWRITE_TAC[INTERIOR_CBALL; BALL_EQ_EMPTY] THEN ASM_REAL_ARITH_TAC; + ASM_SIMP_TAC[CBALL_SING; AFF_DIM_SING]; + MATCH_MP_TAC(MESON[AFF_DIM_EMPTY] `s = {} ==> aff_dim s = --(&1)`) THEN + REWRITE_TAC[CBALL_EQ_EMPTY] THEN ASM_REAL_ARITH_TAC]);; + +let AFF_DIM_INTERVAL = prove + (`(!a b:real^N. + aff_dim(interval[a,b]) = + if interval[a,b] = {} then --(&1) + else &(CARD {i | 1 <= i /\ i <= dimindex(:N) /\ a$i < b$i})) /\ + (!a b:real^N. + aff_dim(interval(a,b)) = + if interval(a,b) = {} then --(&1) + else &(dimindex(:N)))`, + REPEAT STRIP_TAC THEN COND_CASES_TAC THEN + ASM_SIMP_TAC[AFF_DIM_EMPTY; AFF_DIM_OPEN; OPEN_INTERVAL] THEN + POP_ASSUM MP_TAC THEN GEOM_ORIGIN_TAC `a:real^N` THEN + REPEAT STRIP_TAC THEN + REWRITE_TAC[VECTOR_ADD_COMPONENT; VEC_COMPONENT; REAL_LT_LADD] THEN + ASM_SIMP_TAC[AFF_DIM_DIM_0; HULL_INC; ENDS_IN_INTERVAL] THEN AP_TERM_TAC THEN + ONCE_REWRITE_TAC[GSYM DIM_SPAN] THEN MATCH_MP_TAC DIM_UNIQUE THEN EXISTS_TAC + `{basis i:real^N | 1 <= i /\ i <= dimindex(:N) /\ &0 < (b:real^N)$i}` THEN + RULE_ASSUM_TAC(REWRITE_RULE[INTERVAL_NE_EMPTY; VEC_COMPONENT]) THEN + REPEAT CONJ_TAC THENL + [REWRITE_TAC[SUBSET; FORALL_IN_GSPEC] THEN + X_GEN_TAC `i:num` THEN STRIP_TAC THEN + SUBGOAL_THEN `basis i:real^N = inv(b$i) % (b:real^N)$i % basis i` + SUBST1_TAC THENL + [ASM_SIMP_TAC[VECTOR_MUL_ASSOC; REAL_MUL_LINV; REAL_LT_IMP_NZ] THEN + REWRITE_TAC[VECTOR_MUL_LID]; + MATCH_MP_TAC SPAN_MUL THEN MATCH_MP_TAC SPAN_SUPERSET THEN + SIMP_TAC[IN_INTERVAL; VECTOR_MUL_COMPONENT; BASIS_COMPONENT] THEN + X_GEN_TAC `j:num` THEN REWRITE_TAC[VEC_COMPONENT] THEN + COND_CASES_TAC THEN + ASM_SIMP_TAC[REAL_MUL_RZERO; REAL_MUL_RID; REAL_LE_REFL]]; + MATCH_MP_TAC SPAN_SUBSET_SUBSPACE THEN + REWRITE_TAC[SUBSPACE_SPAN; SUBSET; IN_INTERVAL; VEC_COMPONENT] THEN + X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN + GEN_REWRITE_TAC LAND_CONV [GSYM BASIS_EXPANSION] THEN + MATCH_MP_TAC SPAN_VSUM THEN REWRITE_TAC[FINITE_NUMSEG] THEN + X_GEN_TAC `i:num` THEN REWRITE_TAC[IN_NUMSEG] THEN STRIP_TAC THEN + ASM_CASES_TAC `&0 < (b:real^N)$i` THENL + [MATCH_MP_TAC SPAN_MUL THEN MATCH_MP_TAC SPAN_SUPERSET THEN ASM SET_TAC[]; + SUBGOAL_THEN `(x:real^N)$i = &0` + (fun th -> REWRITE_TAC[th; VECTOR_MUL_LZERO; SPAN_0]) THEN + REPEAT(FIRST_X_ASSUM(MP_TAC o SPEC `i:num`)) THEN + ASM_REWRITE_TAC[] THEN ASM_REAL_ARITH_TAC]; + MATCH_MP_TAC PAIRWISE_ORTHOGONAL_INDEPENDENT THEN + REWRITE_TAC[SET_RULE `~(a IN {f x | P x}) <=> !x. P x ==> ~(f x = a)`] THEN + SIMP_TAC[BASIS_NONZERO; pairwise; IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN + SIMP_TAC[FORALL_IN_GSPEC; BASIS_INJ_EQ; ORTHOGONAL_BASIS_BASIS]; + GEN_REWRITE_TAC LAND_CONV [SIMPLE_IMAGE_GEN] THEN + MATCH_MP_TAC HAS_SIZE_IMAGE_INJ THEN + SIMP_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_GSPEC; BASIS_INJ_EQ; + HAS_SIZE] THEN + SIMP_TAC[CONJ_ASSOC; GSYM IN_NUMSEG; FINITE_RESTRICT; FINITE_NUMSEG]]);; + +(* ------------------------------------------------------------------------- *) +(* Deducing convexity from midpoint convexity in common cases. *) +(* ------------------------------------------------------------------------- *) + +let MIDPOINT_CONVEX_DYADIC_RATIONALS = prove + (`!f:real^N->real s. + (!x y. x IN s /\ y IN s + ==> midpoint(x,y) IN s /\ + f(midpoint(x,y)) <= (f(x) + f(y)) / &2) + ==> !n m p x y. + x IN s /\ y IN s /\ m + p = 2 EXP n + ==> (&m / &2 pow n % x + &p / &2 pow n % y) IN s /\ + f(&m / &2 pow n % x + &p / &2 pow n % y) + <= &m / &2 pow n * f x + &p / &2 pow n * f y`, + REPEAT GEN_TAC THEN DISCH_TAC THEN INDUCT_TAC THENL + [REWRITE_TAC[ARITH_RULE + `m + p = 2 EXP 0 <=> m = 0 /\ p = 1 \/ m = 1 /\ p = 0`] THEN + REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN + ASM_REWRITE_TAC[VECTOR_MUL_LID; VECTOR_MUL_LZERO; + VECTOR_ADD_LID; VECTOR_ADD_RID] THEN + REAL_ARITH_TAC; + MATCH_MP_TAC WLOG_LE THEN CONJ_TAC THENL + [REWRITE_TAC[VECTOR_ADD_SYM; REAL_ADD_SYM; ADD_SYM] THEN MESON_TAC[]; + ALL_TAC] THEN + MAP_EVERY X_GEN_TAC [`m:num`; `p:num`] THEN DISCH_TAC THEN + REPEAT GEN_TAC THEN REWRITE_TAC[EXP; real_pow] THEN STRIP_TAC THEN + REWRITE_TAC[real_div; REAL_INV_MUL] THEN + ONCE_REWRITE_TAC[REAL_ARITH `x * inv(&2) * y = inv(&2) * x * y`] THEN + ONCE_REWRITE_TAC[GSYM REAL_MUL_ASSOC; GSYM VECTOR_MUL_ASSOC] THEN + REWRITE_TAC[GSYM REAL_ADD_LDISTRIB; GSYM VECTOR_ADD_LDISTRIB] THEN + SUBGOAL_THEN `2 EXP n <= p` ASSUME_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `&p * inv(&2 pow n) = &(p - 2 EXP n) * inv(&2 pow n) + &1` + SUBST1_TAC THENL + [ASM_SIMP_TAC[GSYM REAL_OF_NUM_SUB; GSYM REAL_OF_NUM_POW] THEN + ASM_SIMP_TAC[REAL_SUB_RDISTRIB; REAL_MUL_RINV; REAL_LT_IMP_NZ; + REAL_LT_POW2] THEN REAL_ARITH_TAC; + REWRITE_TAC[VECTOR_ADD_RDISTRIB; REAL_ADD_RDISTRIB] THEN + REWRITE_TAC[VECTOR_MUL_LID; REAL_MUL_LID] THEN + REWRITE_TAC[VECTOR_ADD_ASSOC; REAL_ADD_ASSOC] THEN + REWRITE_TAC[GSYM midpoint; GSYM real_div] THEN FIRST_X_ASSUM(fun th -> + W(MP_TAC o PART_MATCH (lhand o rand) th o lhand o snd)) THEN + FIRST_X_ASSUM(fun th -> + W(MP_TAC o PART_MATCH (lhand o rand) th o funpow 3 lhand o snd)) THEN + ASM_REWRITE_TAC[] THEN ANTS_TAC THENL + [ASM_ARITH_TAC; SIMP_TAC[] THEN REAL_ARITH_TAC]]]);; + +let CONTINUOUS_MIDPOINT_CONVEX = prove + (`!f:real^N->real s. + (lift o f) continuous_on s /\ convex s /\ + (!x y. x IN s /\ y IN s ==> f(midpoint(x,y)) <= (f(x) + f(y)) / &2) + ==> f convex_on s`, + REWRITE_TAC[midpoint] THEN REPEAT STRIP_TAC THEN REWRITE_TAC[convex_on] THEN + REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN + X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN REWRITE_TAC[GSYM IMP_CONJ_ALT] THEN + X_GEN_TAC `y:real^N` THEN DISCH_TAC THEN + REWRITE_TAC[REAL_ARITH `u + v = &1 <=> v = &1 - u`; IMP_CONJ] THEN + REWRITE_TAC[FORALL_UNWIND_THM2; REAL_SUB_LE] THEN + REWRITE_TAC[FORALL_DROP; GSYM DROP_VEC; IMP_IMP; GSYM IN_INTERVAL_1] THEN + MP_TAC(ISPEC `interval[vec 0:real^1,vec 1]` + CLOSURE_DYADIC_RATIONALS_IN_CONVEX_SET) THEN + SIMP_TAC[CONVEX_INTERVAL; INTERIOR_CLOSED_INTERVAL; + CLOSURE_CLOSED; CLOSED_INTERVAL; UNIT_INTERVAL_NONEMPTY] THEN + REWRITE_TAC[DIMINDEX_1; FORALL_1; GSYM drop] THEN + DISCH_THEN(fun th -> SUBST1_TAC(SYM th) THEN ASSUME_TAC th) THEN + ONCE_REWRITE_TAC[REAL_ARITH `a <= b <=> a - b <= &0`] THEN + MATCH_MP_TAC CONTINUOUS_LE_ON_CLOSURE THEN + REWRITE_TAC[IN_INTER; IMP_CONJ_ALT; FORALL_IN_GSPEC] THEN + FIRST_X_ASSUM SUBST1_TAC THEN + REWRITE_TAC[IN_INTERVAL_1; DROP_CMUL; GSYM FORALL_DROP; DROP_VEC] THEN + CONJ_TAC THENL + [REWRITE_TAC[o_DEF; LIFT_SUB; LIFT_ADD; LIFT_CMUL] THEN + MATCH_MP_TAC CONTINUOUS_ON_SUB THEN CONJ_TAC THENL + [REPLICATE_TAC 2 (ONCE_REWRITE_TAC[GSYM o_DEF]) THEN + REWRITE_TAC[o_ASSOC] THEN MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN + CONJ_TAC THENL + [ALL_TAC; + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET)) THEN + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; IN_INTERVAL_1; GSYM FORALL_DROP; + DROP_VEC] THEN REPEAT STRIP_TAC THEN + FIRST_X_ASSUM(MATCH_MP_TAC o GEN_REWRITE_RULE I [convex]) THEN + ASM_REWRITE_TAC[] THEN ASM_REAL_ARITH_TAC]; + ALL_TAC] THEN + MATCH_MP_TAC CONTINUOUS_ON_ADD THEN CONJ_TAC THEN + MATCH_MP_TAC CONTINUOUS_ON_MUL THEN + SIMP_TAC[o_DEF; LIFT_DROP; CONTINUOUS_ON_ID; CONTINUOUS_ON_CONST; + LIFT_SUB; CONTINUOUS_ON_SUB]; + MAP_EVERY X_GEN_TAC [`n:num`; `i:real`] THEN + ASM_SIMP_TAC[REAL_LE_MUL_EQ; REAL_LT_INV_EQ; REAL_LT_POW2] THEN + ASM_CASES_TAC `&0 <= i` THEN ASM_SIMP_TAC[INTEGER_POS] THEN + DISCH_THEN(X_CHOOSE_THEN `m:num` SUBST_ALL_TAC) THEN + REWRITE_TAC[ONCE_REWRITE_RULE[REAL_MUL_SYM] (GSYM real_div)] THEN + SIMP_TAC[REAL_LE_LDIV_EQ; REAL_LT_POW2; REAL_MUL_LID] THEN + GEN_REWRITE_TAC (LAND_CONV o DEPTH_CONV) + [REAL_OF_NUM_POW; REAL_OF_NUM_LE] THEN DISCH_TAC THEN + MP_TAC(ISPECL [`f:real^N->real`; `s:real^N->bool`] + MIDPOINT_CONVEX_DYADIC_RATIONALS) THEN + ANTS_TAC THENL + [ASM_SIMP_TAC[midpoint] THEN REWRITE_TAC[VECTOR_ADD_LDISTRIB] THEN + REPEAT STRIP_TAC THEN + FIRST_X_ASSUM(MATCH_MP_TAC o GEN_REWRITE_RULE I [convex]) THEN + ASM_REWRITE_TAC[] THEN REAL_ARITH_TAC; + DISCH_THEN(MP_TAC o SPECL + [`n:num`; `m:num`; `2 EXP n - m`; `x:real^N`; `y:real^N`]) THEN + ASM_REWRITE_TAC[] THEN + ANTS_TAC THENL [ASM_ARITH_TAC; DISCH_THEN(MP_TAC o CONJUNCT2)] THEN + ASM_SIMP_TAC[GSYM REAL_OF_NUM_SUB; GSYM REAL_OF_NUM_POW] THEN + ASM_SIMP_TAC[REAL_LT_POW2; REAL_FIELD + `&0 < y ==> (y - x) / y = &1 - x / y`] THEN + REAL_ARITH_TAC]]);; + +(* ------------------------------------------------------------------------- *) +(* Slightly shaper separating/supporting hyperplane results. *) +(* ------------------------------------------------------------------------- *) + +let SEPARATING_HYPERPLANE_RELATIVE_INTERIORS = prove + (`!s t. convex s /\ convex t /\ + ~(s = {} /\ t = (:real^N) \/ s = (:real^N) /\ t = {}) /\ + DISJOINT (relative_interior s) (relative_interior t) + ==> ?a b. ~(a = vec 0) /\ + (!x. x IN s ==> a dot x <= b) /\ + (!x. x IN t ==> a dot x >= b)`, + REPEAT GEN_TAC THEN MAP_EVERY ASM_CASES_TAC + [`s:real^N->bool = {}`; `t:real^N->bool = {}`] THEN + ASM_REWRITE_TAC[NOT_IN_EMPTY; UNIV_NOT_EMPTY; CONVEX_EMPTY; + RELATIVE_INTERIOR_EMPTY] THEN + STRIP_TAC THENL + [EXISTS_TAC `basis 1:real^N` THEN + SIMP_TAC[BASIS_NONZERO; DIMINDEX_GE_1; LE_REFL]; + FIRST_X_ASSUM(X_CHOOSE_TAC `x:real^N` o MATCH_MP (SET_RULE + `~(s = UNIV) ==> ?a. ~(a IN s)`)) THEN + MP_TAC(ISPECL [`t:real^N->bool`; `x:real^N`] + SEPARATING_HYPERPLANE_SET_POINT_INAFF) THEN + ASM_MESON_TAC[]; + FIRST_X_ASSUM(X_CHOOSE_TAC `x:real^N` o MATCH_MP (SET_RULE + `~(s = UNIV) ==> ?a. ~(a IN s)`)) THEN + MP_TAC(ISPECL [`s:real^N->bool`; `x:real^N`] + SEPARATING_HYPERPLANE_SET_POINT_INAFF) THEN + ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM; real_ge] THEN + MAP_EVERY X_GEN_TAC [`a:real^N`; `b:real`] THEN STRIP_TAC THEN + MAP_EVERY EXISTS_TAC [`--a:real^N`; `--b:real`] THEN + ASM_REWRITE_TAC[VECTOR_NEG_EQ_0; DOT_LNEG; REAL_LE_NEG2]; + MP_TAC(ISPECL [`relative_interior s:real^N->bool`; + `relative_interior t:real^N->bool`] + SEPARATING_HYPERPLANE_SETS) THEN + ASM_SIMP_TAC[RELATIVE_INTERIOR_EQ_EMPTY; CONVEX_RELATIVE_INTERIOR] THEN + SIMP_TAC[real_ge] THEN MATCH_MP_TAC MONO_EXISTS THEN + X_GEN_TAC `a:real^N` THEN MATCH_MP_TAC MONO_EXISTS THEN + X_GEN_TAC `b:real` THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + CONJ_TAC THEN MATCH_MP_TAC + (MESON[CONVEX_CLOSURE_RELATIVE_INTERIOR; CLOSURE_SUBSET; SUBSET] + `convex s /\ (!x. x IN closure(relative_interior s) ==> P x) + ==> !x. x IN s ==> P x`) THEN + ASM_REWRITE_TAC[] THENL + [MATCH_MP_TAC CONTINUOUS_LE_ON_CLOSURE; + MATCH_MP_TAC CONTINUOUS_GE_ON_CLOSURE] THEN + ASM_REWRITE_TAC[CONTINUOUS_ON_LIFT_DOT]]);; + +let SUPPORTING_HYPERPLANE_RELATIVE_BOUNDARY = prove + (`!s x:real^N. + convex s /\ x IN s /\ ~(x IN relative_interior s) + ==> ?a. ~(a = vec 0) /\ + (!y. y IN s ==> a dot x <= a dot y) /\ + (!y. y IN relative_interior s ==> a dot x < a dot y)`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`relative_interior s:real^N->bool`; `x:real^N`] + SEPARATING_HYPERPLANE_SET_POINT_INAFF) THEN + ASM_SIMP_TAC[CONVEX_SING; CONVEX_RELATIVE_INTERIOR; + RELATIVE_INTERIOR_EQ_EMPTY; real_ge] THEN + ANTS_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `a:real^N` THEN + REWRITE_TAC[FORALL_IN_INSERT; NOT_IN_EMPTY] THEN + DISCH_THEN(X_CHOOSE_THEN `b:real` STRIP_ASSUME_TAC) THEN ASM_SIMP_TAC[] THEN + MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN CONJ_TAC THENL + [X_GEN_TAC `y:real^N` THEN DISCH_TAC THEN + MP_TAC(ISPECL [`lift o (\x:real^N. a dot x)`; + `relative_interior s:real^N->bool`; + `y:real^N`; `(a:real^N) dot x`; `1`] + CONTINUOUS_ON_CLOSURE_COMPONENT_GE) THEN + REWRITE_TAC[CONTINUOUS_ON_LIFT_DOT; GSYM drop; o_THM; LIFT_DROP] THEN + ASM_SIMP_TAC[CONVEX_CLOSURE_RELATIVE_INTERIOR] THEN + ASM_MESON_TAC[CLOSURE_SUBSET; REAL_LE_TRANS; SUBSET]; + DISCH_TAC] THEN + X_GEN_TAC `y:real^N` THEN DISCH_TAC THEN + REWRITE_TAC[REAL_LT_LE] THEN CONJ_TAC THENL + [ASM_MESON_TAC[REAL_LE_TRANS]; ALL_TAC] THEN + DISCH_TAC THEN UNDISCH_TAC `(y:real^N) IN relative_interior s` THEN + REWRITE_TAC[IN_RELATIVE_INTERIOR_CBALL] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + REWRITE_TAC[LEFT_IMP_EXISTS_THM; SUBSET; IN_INTER; IN_CBALL] THEN + X_GEN_TAC `e:real` THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + DISCH_THEN(MP_TAC o SPEC `y + --(e / norm(a)) % ((x + a) - x):real^N`) THEN + REWRITE_TAC[NOT_IMP] THEN REPEAT CONJ_TAC THENL + [SIMP_TAC[NORM_ARITH `dist(y:real^N,y + e) = norm e`; VECTOR_ADD_SUB] THEN + REWRITE_TAC[NORM_MUL; REAL_ABS_NEG; REAL_ABS_DIV; REAL_ABS_NORM] THEN + ASM_SIMP_TAC[REAL_DIV_RMUL; NORM_EQ_0] THEN ASM_REAL_ARITH_TAC; + MATCH_MP_TAC IN_AFFINE_ADD_MUL_DIFF THEN + ASM_SIMP_TAC[AFFINE_AFFINE_HULL; HULL_INC] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE + `x IN s ==> s SUBSET t ==> x IN t`)) THEN + MATCH_MP_TAC HULL_MONO THEN + ASM_REWRITE_TAC[INSERT_SUBSET; RELATIVE_INTERIOR_SUBSET]; + REWRITE_TAC[VECTOR_ADD_SUB] THEN DISCH_TAC THEN + UNDISCH_TAC `!y:real^N. y IN s ==> a dot x <= a dot y` THEN + DISCH_THEN(MP_TAC o SPEC `y + --(e / norm(a)) % a:real^N`) THEN + ASM_REWRITE_TAC[DOT_RMUL; DOT_RNEG; DOT_RADD] THEN + MATCH_MP_TAC(REAL_ARITH `&0 < x * y ==> ~(a <= a + --x * y)`) THEN + ASM_SIMP_TAC[REAL_LT_MUL; REAL_LT_DIV; NORM_POS_LT; DOT_POS_LT]]);; + +let SUPPORTING_HYPERPLANE_RELATIVE_FRONTIER = prove + (`!s x:real^N. + convex s /\ x IN closure s /\ ~(x IN relative_interior s) + ==> ?a. ~(a = vec 0) /\ + (!y. y IN closure s ==> a dot x <= a dot y) /\ + (!y. y IN relative_interior s ==> a dot x < a dot y)`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`closure s:real^N->bool`; `x:real^N`] + SUPPORTING_HYPERPLANE_RELATIVE_BOUNDARY) THEN + ASM_SIMP_TAC[CONVEX_CLOSURE; CONVEX_RELATIVE_INTERIOR_CLOSURE]);; + +(* ------------------------------------------------------------------------- *) +(* Containment of rays in unbounded convex sets. *) +(* ------------------------------------------------------------------------- *) + +let UNBOUNDED_CONVEX_CLOSED_CONTAINS_RAY = prove + (`!s a:real^N. + convex s /\ ~bounded s /\ closed s /\ a IN s + ==> ?l. ~(l = vec 0) /\ !t. &0 <= t ==> (a + t % l) IN s`, + GEN_GEOM_ORIGIN_TAC `a:real^N` ["l"] THEN + REWRITE_TAC[VECTOR_ADD_LID] THEN REPEAT STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE RAND_CONV [BOUNDED_POS]) THEN + REWRITE_TAC[NOT_EXISTS_THM; TAUT `~(p /\ q) <=> p ==> ~q`] THEN + DISCH_THEN(MP_TAC o GEN `n:num` o SPEC `&n + &1:real`) THEN + REWRITE_TAC[NOT_FORALL_THM; NOT_IMP; REAL_ARITH `&0 < &n + &1`] THEN + REWRITE_TAC[REAL_NOT_LE; SKOLEM_THM; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `x:num->real^N` THEN REWRITE_TAC[FORALL_AND_THM] THEN + STRIP_TAC THEN + SUBGOAL_THEN `!n. ~((x:num->real^N) n = vec 0)` ASSUME_TAC THENL + [ASM_MESON_TAC[NORM_ARITH `~(&n + &1 < norm(vec 0:real^N))`]; ALL_TAC] THEN + MP_TAC(ISPEC `sphere(vec 0:real^N,&1)` compact) THEN + REWRITE_TAC[COMPACT_SPHERE] THEN + DISCH_THEN(MP_TAC o SPEC `\n. inv(norm(x n)) % (x:num->real^N) n`) THEN + ASM_SIMP_TAC[IN_SPHERE_0; NORM_MUL; REAL_ABS_INV; REAL_ABS_NORM; + REAL_MUL_LINV; NORM_EQ_0; o_DEF] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `l:real^N` THEN + DISCH_THEN(X_CHOOSE_THEN `r:num->num` STRIP_ASSUME_TAC) THEN CONJ_TAC THENL + [ASM_MESON_TAC[NORM_ARITH `~(norm(vec 0:real^N) = &1)`]; ALL_TAC] THEN + X_GEN_TAC `t:real` THEN DISCH_TAC THEN + MATCH_MP_TAC CLOSED_CONTAINS_SEQUENTIAL_LIMIT THEN + SUBGOAL_THEN + `?N:num. !n. N <= n ==> t / norm(x n:real^N) <= &1` + STRIP_ASSUME_TAC THENL + [ASM_SIMP_TAC[REAL_LE_LDIV_EQ; NORM_POS_LT] THEN + MP_TAC(SPEC `t:real` REAL_ARCH_SIMPLE) THEN + MATCH_MP_TAC MONO_EXISTS THEN + REWRITE_TAC[GSYM REAL_OF_NUM_LE; REAL_MUL_LID] THEN + ASM_MESON_TAC[REAL_ARITH `t <= m /\ m <= n /\ n + &1 < x ==> t <= x`]; + EXISTS_TAC `\n:num. t / norm((x:num->real^N)(r(N + n))) % x(r(N + n))` THEN + ASM_REWRITE_TAC[] THEN CONJ_TAC THENL + [X_GEN_TAC `n:num` THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [CONVEX_ALT]) THEN + DISCH_THEN(MP_TAC o SPEC `vec 0:real^N`) THEN + ASM_REWRITE_TAC[VECTOR_MUL_RZERO; VECTOR_ADD_LID] THEN + DISCH_THEN MATCH_MP_TAC THEN ASM_SIMP_TAC[REAL_LE_DIV; NORM_POS_LE] THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN + FIRST_ASSUM(MP_TAC o SPEC `N + n:num` o MATCH_MP MONOTONE_BIGGER) THEN + ARITH_TAC; + REWRITE_TAC[real_div; GSYM VECTOR_MUL_ASSOC] THEN + MATCH_MP_TAC LIM_CMUL THEN ONCE_REWRITE_TAC[ADD_SYM] THEN + FIRST_ASSUM(MP_TAC o SPEC `N:num` o MATCH_MP SEQ_OFFSET) THEN + ASM_REWRITE_TAC[]]]);; + +let CONVEX_CLOSED_CONTAINS_SAME_RAY = prove + (`!s a b l:real^N. + convex s /\ closed s /\ b IN s /\ (!t. &0 <= t ==> (a + t % l) IN s) + ==> !t. &0 <= t ==> (b + t % l) IN s`, + REPEAT STRIP_TAC THEN FIRST_ASSUM(MP_TAC o SPEC `&0`) THEN + REWRITE_TAC[VECTOR_MUL_LZERO; VECTOR_ADD_RID] THEN DISCH_TAC THEN + MATCH_MP_TAC(ISPEC `sequentially` LIM_IN_CLOSED_SET) THEN + EXISTS_TAC `\n. (&1 - t / (&n + &1)) % b + + t / (&n + &1) % (a + (&n + &1) % l):real^N` THEN + ASM_REWRITE_TAC[TRIVIAL_LIMIT_SEQUENTIALLY] THEN CONJ_TAC THENL + [REWRITE_TAC[EVENTUALLY_SEQUENTIALLY] THEN + MP_TAC(SPEC `t:real` REAL_ARCH_SIMPLE) THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `N:num` THEN + DISCH_TAC THEN X_GEN_TAC `n:num` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MATCH_MP_TAC o GEN_REWRITE_RULE I [CONVEX_ALT]) THEN + ASM_SIMP_TAC[REAL_LE_DIV; REAL_ARITH `&0 <= &n + &1`] THEN + ASM_SIMP_TAC[REAL_LE_LDIV_EQ; REAL_ARITH `&0 < &n + &1`] THEN + RULE_ASSUM_TAC(REWRITE_RULE[GSYM REAL_OF_NUM_LE]) THEN ASM_REAL_ARITH_TAC; + REWRITE_TAC[VECTOR_ARITH + `(&1 - u) % b + u % c:real^N = b + u % (c - b)`] THEN + MATCH_MP_TAC LIM_ADD THEN REWRITE_TAC[LIM_CONST] THEN + REWRITE_TAC[VECTOR_ADD_LDISTRIB; VECTOR_SUB_LDISTRIB] THEN + SIMP_TAC[VECTOR_MUL_ASSOC; REAL_FIELD `t / (&n + &1) * (&n + &1) = t`] THEN + SIMP_TAC[VECTOR_ARITH `(v % a + b) - v % c:real^N = b + v % (a - c)`] THEN + GEN_REWRITE_TAC LAND_CONV [GSYM VECTOR_ADD_RID] THEN + MATCH_MP_TAC LIM_ADD THEN REWRITE_TAC[LIM_CONST] THEN + REWRITE_TAC[real_div; VECTOR_ARITH `(x * y) % a:real^N = y % x % a`] THEN + MATCH_MP_TAC LIM_NULL_VMUL_BOUNDED THEN + EXISTS_TAC `norm(t % (a - b):real^N)` THEN + REWRITE_TAC[REAL_LE_REFL; EVENTUALLY_TRUE; o_DEF] THEN + MP_TAC(MATCH_MP SEQ_OFFSET SEQ_HARMONIC) THEN + SIMP_TAC[REAL_OF_NUM_ADD]]);; + +let UNBOUNDED_CONVEX_CLOSED_CONTAINS_RAYS = prove + (`!s:real^N->bool. + convex s /\ ~bounded s /\ closed s + ==> ?l. ~(l = vec 0) /\ !a t. a IN s /\ &0 <= t ==> (a + t % l) IN s`, + REPEAT GEN_TAC THEN ASM_CASES_TAC `s:real^N->bool = {}` THEN + ASM_REWRITE_TAC[BOUNDED_EMPTY] THEN + RULE_ASSUM_TAC(REWRITE_RULE[GSYM MEMBER_NOT_EMPTY]) THEN + ASM_MESON_TAC[UNBOUNDED_CONVEX_CLOSED_CONTAINS_RAY; + CONVEX_CLOSED_CONTAINS_SAME_RAY]);; + +let RELATIVE_INTERIOR_UNBOUNDED_CONVEX_CONTAINS_RAY = prove + (`!s a:real^N. + convex s /\ ~bounded s /\ a IN relative_interior s + ==> ?l. ~(l = vec 0) /\ + !t. &0 <= t ==> (a + t % l) IN relative_interior s`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`closure s:real^N->bool`; `a:real^N`] + UNBOUNDED_CONVEX_CLOSED_CONTAINS_RAY) THEN + ASM_SIMP_TAC[CONVEX_CLOSURE; CLOSED_CLOSURE] THEN ANTS_TAC THENL + [ASM_MESON_TAC[BOUNDED_SUBSET; SUBSET; CLOSURE_SUBSET; + RELATIVE_INTERIOR_SUBSET]; + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `l:real^N` THEN STRIP_TAC THEN + ASM_REWRITE_TAC[] THEN + ONCE_REWRITE_TAC[VECTOR_ARITH + `a + t % l:real^N = + (a + (&2 * t) % l) - inv(&2) % ((a + (&2 * t) % l) - a)`] THEN + REPEAT STRIP_TAC THEN + MATCH_MP_TAC IN_RELATIVE_INTERIOR_CLOSURE_CONVEX_SHRINK THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN ASM_REWRITE_TAC[] THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REAL_ARITH_TAC]);; + +let RELATIVE_INTERIOR_CONVEX_CONTAINS_SAME_RAY = prove + (`!s a b l:real^N. + convex s /\ b IN relative_interior s /\ + (!t. &0 <= t ==> (a + t % l) IN relative_interior s) + ==> !t. &0 <= t ==> (b + t % l) IN relative_interior s`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`closure s:real^N->bool`; `a:real^N`; `b:real^N`; `l:real^N`] + CONVEX_CLOSED_CONTAINS_SAME_RAY) THEN + ASM_SIMP_TAC[CONVEX_CLOSURE; CLOSED_CLOSURE] THEN ANTS_TAC THENL + [ASM_MESON_TAC[BOUNDED_SUBSET; SUBSET; CLOSURE_SUBSET; + RELATIVE_INTERIOR_SUBSET]; + DISCH_TAC THEN + ONCE_REWRITE_TAC[VECTOR_ARITH + `a + t % l:real^N = + (a + (&2 * t) % l) - inv(&2) % ((a + (&2 * t) % l) - a)`] THEN + REPEAT STRIP_TAC THEN + MATCH_MP_TAC IN_RELATIVE_INTERIOR_CLOSURE_CONVEX_SHRINK THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN ASM_REWRITE_TAC[] THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REAL_ARITH_TAC]);; + +let RELATIVE_INTERIOR_UNBOUNDED_CONVEX_CONTAINS_RAYS = prove + (`!s:real^N->bool. + convex s /\ ~bounded s + ==> ?l. ~(l = vec 0) /\ + !a t. a IN relative_interior s /\ &0 <= t + ==> (a + t % l) IN relative_interior s`, + REPEAT GEN_TAC THEN + ASM_CASES_TAC `relative_interior s:real^N->bool = {}` THENL + [ASM_MESON_TAC[RELATIVE_INTERIOR_EQ_EMPTY; BOUNDED_EMPTY]; ALL_TAC] THEN + RULE_ASSUM_TAC(REWRITE_RULE[GSYM MEMBER_NOT_EMPTY]) THEN + ASM_MESON_TAC[RELATIVE_INTERIOR_UNBOUNDED_CONVEX_CONTAINS_RAY; + RELATIVE_INTERIOR_CONVEX_CONTAINS_SAME_RAY]);; + +(* ------------------------------------------------------------------------- *) +(* Explicit formulas for interior and relative interior of convex hull. *) +(* ------------------------------------------------------------------------- *) + +let EXPLICIT_SUBSET_RELATIVE_INTERIOR_CONVEX_HULL = prove + (`!s. FINITE s + ==> {y:real^N | ?u. (!x. x IN s ==> &0 < u x /\ u x < &1) /\ + sum s u = &1 /\ + vsum s (\x. u x % x) = y} + SUBSET relative_interior(convex hull s)`, + REPEAT GEN_TAC THEN ASM_CASES_TAC `s:real^N->bool = {}` THEN + ASM_REWRITE_TAC[SUM_CLAUSES; REAL_OF_NUM_EQ; ARITH_EQ] THEN + REWRITE_TAC[EMPTY_GSPEC; EMPTY_SUBSET] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC RELATIVE_INTERIOR_MAXIMAL THEN + REWRITE_TAC[AFFINE_HULL_CONVEX_HULL] THEN CONJ_TAC THENL + [REWRITE_TAC[CONVEX_HULL_FINITE; SUBSET; IN_ELIM_THM] THEN + GEN_TAC THEN MATCH_MP_TAC MONO_EXISTS THEN SIMP_TAC[REAL_LT_IMP_LE]; + ALL_TAC] THEN + REWRITE_TAC[open_in; IN_ELIM_THM] THEN CONJ_TAC THENL + [REWRITE_TAC[AFFINE_HULL_FINITE; SUBSET; IN_ELIM_THM] THEN + GEN_TAC THEN MATCH_MP_TAC MONO_EXISTS THEN SIMP_TAC[REAL_LT_IMP_LE]; + ALL_TAC] THEN + X_GEN_TAC `y:real^N` THEN + DISCH_THEN(X_CHOOSE_THEN `u:real^N->real` STRIP_ASSUME_TAC) THEN + ABBREV_TAC `e = inf (IMAGE (\x:real^N. min (&1 - u x) (u x)) s)` THEN + SUBGOAL_THEN `&0 < e` ASSUME_TAC THENL + [EXPAND_TAC "e" THEN + ASM_SIMP_TAC[REAL_LT_INF_FINITE; FINITE_IMAGE; IMAGE_EQ_EMPTY] THEN + ASM_SIMP_TAC[REAL_LT_MIN; REAL_SUB_LT; FORALL_IN_IMAGE]; + ALL_TAC] THEN + MP_TAC(ISPEC `IMAGE (\z:real^N. z - y) (affine hull s)` BASIS_EXISTS) THEN + REWRITE_TAC[SUBSET_IMAGE] THEN + DISCH_THEN(X_CHOOSE_THEN `b:real^N->bool` + (CONJUNCTS_THEN2 (X_CHOOSE_THEN `c:real^N->bool` (STRIP_ASSUME_TAC o GSYM)) + MP_TAC)) THEN + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; HAS_SIZE] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + DISCH_THEN(CONJUNCTS_THEN2 MP_TAC STRIP_ASSUME_TAC) THEN + ASM_SIMP_TAC[SPAN_FINITE; IN_ELIM_THM] 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 `compo:real^N->real^N->real`) THEN + FIRST_ASSUM(X_CHOOSE_THEN `B:real` STRIP_ASSUME_TAC o + MATCH_MP BASIS_COORDINATES_LIPSCHITZ) THEN + SUBGOAL_THEN + `!i. i IN b ==> ?u. sum s u = &0 /\ vsum s (\x:real^N. u x % x) = i` + MP_TAC THENL + [EXPAND_TAC "b" THEN REWRITE_TAC[FORALL_IN_IMAGE] THEN + X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN + SUBGOAL_THEN `(x:real^N) IN affine hull s` MP_TAC THENL + [ASM SET_TAC[]; REWRITE_TAC[AFFINE_HULL_FINITE; IN_ELIM_THM]] THEN + DISCH_THEN(X_CHOOSE_THEN `v:real^N->real` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `(\x. v x - u x):real^N->real` THEN + ASM_SIMP_TAC[SUM_SUB; VSUM_SUB; VECTOR_SUB_RDISTRIB] THEN + REWRITE_TAC[REAL_SUB_REFL; VECTOR_SUB_RZERO]; + GEN_REWRITE_TAC (LAND_CONV o TOP_DEPTH_CONV) + [RIGHT_IMP_EXISTS_THM; SKOLEM_THM; FORALL_AND_THM; + TAUT `(a ==> b /\ c) <=> (a ==> b) /\ (a ==> c)`] THEN + DISCH_THEN(X_CHOOSE_THEN `w:real^N->real^N->real` STRIP_ASSUME_TAC)] THEN + EXISTS_TAC `e / B / + (&1 + sum (b:real^N->bool) + (\i. abs(sup(IMAGE (abs o w i) (s:real^N->bool)))))` THEN + ASM_SIMP_TAC[REAL_LT_DIV; REAL_ARITH `&0 <= x ==> &0 < &1 + x`; + SUM_POS_LE; REAL_ABS_POS] THEN + X_GEN_TAC `z:real^N` THEN STRIP_TAC THEN + EXISTS_TAC + `\x:real^N. u x + sum (b:real^N->bool) + (\i. compo (z:real^N) i * w i x)` THEN + REWRITE_TAC[] THEN REPEAT CONJ_TAC THENL + [ALL_TAC; + ASM_SIMP_TAC[SUM_ADD; REAL_ARITH `&1 + x = &1 <=> x = &0`] THEN + W(MP_TAC o PART_MATCH (lhs o rand) SUM_SWAP o lhand o snd) THEN + ASM_REWRITE_TAC[FINITE_NUMSEG] THEN DISCH_THEN SUBST1_TAC THEN + MATCH_MP_TAC SUM_EQ_0 THEN + ASM_SIMP_TAC[SUM_LMUL; ETA_AX; REAL_MUL_RZERO; SUM_0]; + ASM_SIMP_TAC[VSUM_ADD; VECTOR_ADD_RDISTRIB] THEN + ONCE_REWRITE_TAC[VECTOR_ARITH `y + w:real^N = z <=> w = z - y`] THEN + ASM_SIMP_TAC[GSYM VSUM_LMUL; GSYM VSUM_RMUL; GSYM VECTOR_MUL_ASSOC] THEN + W(MP_TAC o PART_MATCH (lhs o rand) VSUM_SWAP o lhand o snd) THEN + ASM_REWRITE_TAC[] THEN DISCH_THEN SUBST1_TAC THEN + ASM_SIMP_TAC[VSUM_LMUL] THEN MATCH_MP_TAC EQ_TRANS THEN + EXISTS_TAC `vsum b (\v:real^N. compo (z:real^N) v % v)` THEN + CONJ_TAC THENL [ALL_TAC; ASM_SIMP_TAC[]] THEN + MATCH_MP_TAC VSUM_EQ THEN ASM_SIMP_TAC[]] THEN + X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN REWRITE_TAC[] THEN + MATCH_MP_TAC(REAL_ARITH + `abs(x) < min u (&1 - u) ==> &0 < u + x /\ u + x < &1`) THEN + MATCH_MP_TAC REAL_LET_TRANS THEN EXISTS_TAC + `B * norm(z - y:real^N) * sum (b:real^N->bool) + (\i. abs(sup(IMAGE (abs o w i) (s:real^N->bool))))` THEN + CONJ_TAC THENL + [REWRITE_TAC[GSYM SUM_LMUL] THEN MATCH_MP_TAC SUM_ABS_LE THEN + ASM_REWRITE_TAC[REAL_ABS_MUL; REAL_MUL_ASSOC] THEN + X_GEN_TAC `i:real^N` THEN STRIP_TAC THEN MATCH_MP_TAC REAL_LE_MUL2 THEN + REWRITE_TAC[REAL_ABS_POS] THEN CONJ_TAC THENL + [FIRST_X_ASSUM(MP_TAC o SPECL [`(compo:real^N->real^N->real) z`; + `i:real^N`]) THEN + ASM_SIMP_TAC[]; + MATCH_MP_TAC(REAL_ARITH `x <= a ==> x <= abs a`) THEN + ASM_SIMP_TAC[REAL_LE_SUP_FINITE; FINITE_IMAGE; IMAGE_EQ_EMPTY] THEN + REWRITE_TAC[EXISTS_IN_IMAGE; o_THM] THEN ASM_MESON_TAC[REAL_LE_REFL]]; + ALL_TAC] THEN + GEN_REWRITE_TAC LAND_CONV [REAL_MUL_SYM] THEN + ASM_SIMP_TAC[GSYM REAL_LT_RDIV_EQ] THEN + MATCH_MP_TAC(REAL_ARITH + `&0 <= x /\ x * (&1 + e) < d ==> x * e < d`) THEN + REWRITE_TAC[NORM_POS_LE] THEN + ASM_SIMP_TAC[NORM_POS_LE; GSYM REAL_LT_RDIV_EQ; + REAL_ARITH `&0 <= x ==> &0 < &1 + x`; + SUM_POS_LE; REAL_ABS_POS] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (NORM_ARITH + `dist(z:real^N,y) < k ==> k <= d ==> norm(z - y) < d`)) THEN + ASM_SIMP_TAC[REAL_LE_DIV2_EQ; REAL_ARITH `&0 <= x ==> &0 < &1 + x`; + SUM_POS_LE; REAL_ABS_POS] THEN + EXPAND_TAC "e" THEN + ASM_SIMP_TAC[REAL_INF_LE_FINITE; FINITE_IMAGE; IMAGE_EQ_EMPTY] THEN + REWRITE_TAC[EXISTS_IN_IMAGE] THEN EXISTS_TAC `x:real^N` THEN + ASM_REWRITE_TAC[] THEN REAL_ARITH_TAC);; + +let EXPLICIT_SUBSET_RELATIVE_INTERIOR_CONVEX_HULL_MINIMAL = prove + (`!s. FINITE s + ==> {y:real^N | ?u. (!x. x IN s ==> &0 < u x) /\ + sum s u = &1 /\ + vsum s (\x. u x % x) = y} + SUBSET relative_interior(convex hull s)`, + REPEAT STRIP_TAC THEN + ASM_CASES_TAC `s:real^N->bool = {}` THEN + ASM_REWRITE_TAC[SUM_CLAUSES; REAL_OF_NUM_EQ; ARITH_EQ] THEN + REWRITE_TAC[EMPTY_GSPEC; EMPTY_SUBSET] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN + DISCH_THEN(X_CHOOSE_THEN `a:real^N` STRIP_ASSUME_TAC) THEN + ASM_CASES_TAC `s = {a:real^N}` THENL + [ASM_REWRITE_TAC[SUM_SING; VSUM_SING; FORALL_IN_INSERT; NOT_IN_EMPTY] THEN + REWRITE_TAC[RELATIVE_INTERIOR_SING; CONVEX_HULL_SING] THEN + REWRITE_TAC[SUBSET; IN_ELIM_THM; IN_SING] THEN + MESON_TAC[VECTOR_MUL_LID]; + FIRST_ASSUM(MP_TAC o MATCH_MP + EXPLICIT_SUBSET_RELATIVE_INTERIOR_CONVEX_HULL) THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] SUBSET_TRANS) THEN + REWRITE_TAC[SUBSET; IN_ELIM_THM] THEN X_GEN_TAC `w:real^N` THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `u:real^N->real` THEN + STRIP_TAC THEN ASM_SIMP_TAC[] THEN X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN + SUBGOAL_THEN `?y:real^N. y IN s /\ ~(y = x)` STRIP_ASSUME_TAC THENL + [ASM SET_TAC[]; ALL_TAC] THEN + SUBGOAL_THEN `sum {x,y} u <= sum s (u:real^N->real)` MP_TAC THENL + [MATCH_MP_TAC SUM_SUBSET_SIMPLE THEN + ASM_SIMP_TAC[AFFINE_INDEPENDENT_IMP_FINITE; REAL_LT_IMP_LE; IN_DIFF] THEN + ASM SET_TAC[]; + ASM_SIMP_TAC[SUM_CLAUSES; FINITE_INSERT; FINITE_EMPTY] THEN + ASM_REWRITE_TAC[IN_INSERT; NOT_IN_EMPTY] THEN + MATCH_MP_TAC(REAL_ARITH `&0 < y ==> x + y + &0 <= &1 ==> x < &1`) THEN + ASM_SIMP_TAC[]]]);; + +let RELATIVE_INTERIOR_CONVEX_HULL_EXPLICIT = prove + (`!s. ~(affine_dependent s) + ==> relative_interior(convex hull s) = + {y:real^N | ?u. (!x. x IN s ==> &0 < u x) /\ + sum s u = &1 /\ + vsum s (\x. u x % x) = y}`, + REPEAT STRIP_TAC THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP AFFINE_INDEPENDENT_IMP_FINITE) THEN + MATCH_MP_TAC SUBSET_ANTISYM THEN + ASM_SIMP_TAC[EXPLICIT_SUBSET_RELATIVE_INTERIOR_CONVEX_HULL_MINIMAL] THEN + ASM_CASES_TAC `?a:real^N. s = {a}` THENL + [FIRST_X_ASSUM(CHOOSE_THEN SUBST1_TAC) THEN + ASM_REWRITE_TAC[SUM_SING; VSUM_SING; CONVEX_HULL_SING; + RELATIVE_INTERIOR_SING] THEN + REWRITE_TAC[IN_ELIM_THM; SUBSET; IN_SING] THEN + REPEAT STRIP_TAC THEN EXISTS_TAC `\x:real^N. &1` THEN + ASM_REWRITE_TAC[VECTOR_MUL_LID; REAL_LT_01]; + ALL_TAC] THEN + MATCH_MP_TAC(SET_RULE + `relative_interior s SUBSET s /\ + (!x. x IN s /\ ~(x IN t) ==> ~(x IN relative_interior s)) + ==> relative_interior s SUBSET t`) THEN + REWRITE_TAC[RELATIVE_INTERIOR_SUBSET] THEN + X_GEN_TAC `y:real^N` THEN REWRITE_TAC[IN_RELATIVE_INTERIOR] THEN + REWRITE_TAC[AFFINE_HULL_CONVEX_HULL; IN_ELIM_THM; NOT_EXISTS_THM] THEN + REWRITE_TAC[CONVEX_HULL_FINITE; IN_ELIM_THM] THEN + DISCH_THEN(CONJUNCTS_THEN2 + (X_CHOOSE_THEN `u:real^N->real` STRIP_ASSUME_TAC) + (MP_TAC o SPEC `u:real^N->real`)) THEN + ASM_REWRITE_TAC[NOT_FORALL_THM; NOT_IMP; IN_RELATIVE_INTERIOR; DE_MORGAN_THM; + SUBSET; IN_ELIM_THM; IN_BALL; IN_INTER] THEN + DISCH_THEN(X_CHOOSE_THEN `a:real^N` STRIP_ASSUME_TAC) THEN DISJ2_TAC THEN + DISCH_THEN(X_CHOOSE_THEN `e:real` + (CONJUNCTS_THEN2 ASSUME_TAC (LABEL_TAC "*"))) THEN + SUBGOAL_THEN `(u:real^N->real) a = &0` ASSUME_TAC THENL + [ASM_SIMP_TAC[REAL_ARITH `&0 <= x /\ ~(&0 < x) ==> x = &0`]; ALL_TAC] THEN + SUBGOAL_THEN `?b:real^N. b IN s /\ ~(b = a)` STRIP_ASSUME_TAC THENL + [ASM SET_TAC[];ALL_TAC] THEN + SUBGOAL_THEN `?d. &0 < d /\ norm(d % (a - b):real^N) < e` + STRIP_ASSUME_TAC THENL + [EXISTS_TAC `e / &2 / norm(a - b:real^N)` THEN + ASM_SIMP_TAC[NORM_MUL; REAL_LT_DIV; REAL_OF_NUM_LT; ARITH; NORM_POS_LT; + REAL_ABS_DIV; REAL_ABS_NORM; REAL_ABS_NUM; + REAL_DIV_RMUL; REAL_LT_IMP_NZ; VECTOR_SUB_EQ] THEN + ASM_REAL_ARITH_TAC; + ALL_TAC] THEN + REMOVE_THEN "*" (MP_TAC o SPEC `y - d % (a - b):real^N`) THEN + ASM_REWRITE_TAC[NORM_ARITH `dist(a:real^N,a - b) = norm b`] THEN + REWRITE_TAC[NOT_IMP] THEN CONJ_TAC THENL + [MATCH_MP_TAC IN_AFFINE_SUB_MUL_DIFF THEN + ASM_SIMP_TAC[HULL_INC; AFFINE_AFFINE_HULL] THEN + REWRITE_TAC[AFFINE_HULL_FINITE; IN_ELIM_THM] THEN + EXISTS_TAC `u:real^N->real` THEN ASM_REWRITE_TAC[]; + ALL_TAC] THEN + DISCH_THEN(X_CHOOSE_THEN `v:real^N->real` STRIP_ASSUME_TAC) THEN + UNDISCH_TAC `~(affine_dependent(s:real^N->bool))` THEN + ASM_SIMP_TAC[AFFINE_DEPENDENT_EXPLICIT_FINITE] THEN + EXISTS_TAC `\x:real^N. (v x - u x) - + (if x = a then --d else if x = b then d else &0)` THEN + REWRITE_TAC[VECTOR_SUB_RDISTRIB; MESON[] + `(if p then a else b) % x = (if p then a % x else b % x)`] THEN + ASM_SIMP_TAC[SUM_SUB; VSUM_SUB] THEN + ASM_SIMP_TAC[VSUM_CASES; SUM_CASES; FINITE_RESTRICT; IN_ELIM_THM] THEN + ASM_SIMP_TAC[SET_RULE `a IN s ==> {x | x IN s /\ x = a} = {a}`; + SET_RULE `b IN s /\ ~(b = a) + ==> {x | (x IN s /\ ~(x = a)) /\ x = b} = {b}`] THEN + ASM_SIMP_TAC[VECTOR_MUL_LZERO; SUM_0; VSUM_0; SUM_SING; VSUM_SING] THEN + CONJ_TAC THENL [REAL_ARITH_TAC; ALL_TAC] THEN + CONJ_TAC THENL [ALL_TAC; VECTOR_ARITH_TAC] THEN + EXISTS_TAC `a:real^N` THEN ASM_REWRITE_TAC[] THEN + FIRST_X_ASSUM(MP_TAC o SPEC `a:real^N`) THEN ASM_REWRITE_TAC[] THEN + ASM_REAL_ARITH_TAC);; + +let EXPLICIT_SUBSET_INTERIOR_CONVEX_HULL = prove + (`!s. FINITE s /\ affine hull s = (:real^N) + ==> {y | ?u. (!x. x IN s ==> &0 < u x /\ u x < &1) /\ + sum s u = &1 /\ + vsum s (\x. u x % x) = y} + SUBSET interior(convex hull s)`, + REPEAT STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o + MATCH_MP EXPLICIT_SUBSET_RELATIVE_INTERIOR_CONVEX_HULL) THEN + ASM_SIMP_TAC[RELATIVE_INTERIOR_INTERIOR; AFFINE_HULL_CONVEX_HULL]);; + +let EXPLICIT_SUBSET_INTERIOR_CONVEX_HULL_MINIMAL = prove + (`!s. FINITE s /\ affine hull s = (:real^N) + ==> {y | ?u. (!x. x IN s ==> &0 < u x) /\ + sum s u = &1 /\ + vsum s (\x. u x % x) = y} + SUBSET interior(convex hull s)`, + REPEAT STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o + MATCH_MP EXPLICIT_SUBSET_RELATIVE_INTERIOR_CONVEX_HULL_MINIMAL) THEN + ASM_SIMP_TAC[RELATIVE_INTERIOR_INTERIOR; AFFINE_HULL_CONVEX_HULL]);; + +let INTERIOR_CONVEX_HULL_EXPLICIT_MINIMAL = prove + (`!s:real^N->bool. + ~(affine_dependent s) + ==> interior(convex hull s) = + if CARD(s) <= dimindex(:N) then {} + else {y | ?u. (!x. x IN s ==> &0 < u x) /\ + sum s u = &1 /\ + vsum s (\x. u x % x) = y}`, + REPEAT STRIP_TAC THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP AFFINE_INDEPENDENT_IMP_FINITE) THEN + COND_CASES_TAC THEN ASM_SIMP_TAC[EMPTY_INTERIOR_CONVEX_HULL] THEN + MATCH_MP_TAC EQ_TRANS THEN + EXISTS_TAC `relative_interior(convex hull s):real^N->bool` THEN + CONJ_TAC THENL + [CONV_TAC SYM_CONV THEN MATCH_MP_TAC RELATIVE_INTERIOR_INTERIOR THEN + REWRITE_TAC[AFFINE_HULL_CONVEX_HULL] THEN + MATCH_MP_TAC AFFINE_INDEPENDENT_SPAN_GT THEN + ASM_REWRITE_TAC[] THEN ASM_ARITH_TAC; + ASM_SIMP_TAC[RELATIVE_INTERIOR_CONVEX_HULL_EXPLICIT]]);; + +let INTERIOR_CONVEX_HULL_EXPLICIT = prove + (`!s:real^N->bool. + ~(affine_dependent s) + ==> interior(convex hull s) = + if CARD(s) <= dimindex(:N) then {} + else {y | ?u. (!x. x IN s ==> &0 < u x /\ u x < &1) /\ + sum s u = &1 /\ + vsum s (\x. u x % x) = y}`, + REPEAT STRIP_TAC THEN + ASM_SIMP_TAC[INTERIOR_CONVEX_HULL_EXPLICIT_MINIMAL] THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[EXTENSION; IN_ELIM_THM] THEN X_GEN_TAC `v:real^N` THEN + AP_TERM_TAC THEN REWRITE_TAC[FUN_EQ_THM] THEN X_GEN_TAC `u:real^N->real` THEN + EQ_TAC THEN STRIP_TAC THEN ASM_SIMP_TAC[] THEN + X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN + MP_TAC(ISPEC `s:real^N->bool` CHOOSE_SUBSET) THEN + ASM_SIMP_TAC[AFFINE_INDEPENDENT_IMP_FINITE] THEN + DISCH_THEN(MP_TAC o SPEC `2`) THEN ANTS_TAC THENL + [FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (ARITH_RULE + `~(c <= n) ==> 1 <= n ==> 2 <= c`)) THEN + REWRITE_TAC[DIMINDEX_GE_1]; + ALL_TAC] THEN + CONV_TAC(ONCE_DEPTH_CONV HAS_SIZE_CONV) THEN + REWRITE_TAC[SUBSET] THEN + DISCH_THEN(X_CHOOSE_THEN `t:real^N->bool` (CONJUNCTS_THEN2 ASSUME_TAC + MP_TAC)) THEN + DISCH_THEN(X_CHOOSE_THEN `a:real^N` (X_CHOOSE_THEN `b:real^N` + STRIP_ASSUME_TAC)) THEN + SUBGOAL_THEN `?y:real^N. y IN s /\ ~(y = x)` STRIP_ASSUME_TAC THENL + [ASM SET_TAC[]; ALL_TAC] THEN + SUBGOAL_THEN `sum {x,y} u <= sum s (u:real^N->real)` MP_TAC THENL + [MATCH_MP_TAC SUM_SUBSET_SIMPLE THEN + ASM_SIMP_TAC[AFFINE_INDEPENDENT_IMP_FINITE; REAL_LT_IMP_LE; IN_DIFF] THEN + ASM SET_TAC[]; + ALL_TAC] THEN + ASM_SIMP_TAC[SUM_CLAUSES; FINITE_INSERT; FINITE_EMPTY] THEN + ASM_REWRITE_TAC[IN_INSERT; NOT_IN_EMPTY] THEN + MATCH_MP_TAC(REAL_ARITH `&0 < y ==> x + y + &0 <= &1 ==> x < &1`) THEN + ASM_SIMP_TAC[]);; + +let INTERIOR_CONVEX_HULL_3_MINIMAL = prove + (`!a b c:real^2. + ~collinear{a,b,c} + ==> interior(convex hull {a,b,c}) = + {v | ?x y z. &0 < x /\ + &0 < y /\ + &0 < z /\ + x + y + z = &1 /\ + x % a + y % b + z % c = v}`, + REWRITE_TAC[COLLINEAR_3_EQ_AFFINE_DEPENDENT; DE_MORGAN_THM] THEN + REPEAT STRIP_TAC THEN + ASM_SIMP_TAC[INTERIOR_CONVEX_HULL_EXPLICIT_MINIMAL] THEN + ASM_SIMP_TAC[CARD_CLAUSES; FINITE_INSERT; FINITE_EMPTY] THEN + CONV_TAC(LAND_CONV(RATOR_CONV(LAND_CONV(ONCE_DEPTH_CONV(REWRITE_CONV + [IN_INSERT; NOT_IN_EMPTY]))))) THEN + ASM_REWRITE_TAC[DIMINDEX_2; ARITH] THEN + SIMP_TAC[FINITE_INSERT; FINITE_UNION; FINITE_EMPTY; RIGHT_EXISTS_AND_THM; + AFFINE_HULL_FINITE_STEP_GEN; REAL_LT_ADD; REAL_HALF] THEN + REWRITE_TAC[REAL_ARITH `&1 - a - b - c = &0 <=> a + b + c = &1`; + VECTOR_ARITH `y - a - b - c:real^N = vec 0 <=> a + b + c = y`]);; + +let INTERIOR_CONVEX_HULL_3 = prove + (`!a b c:real^2. + ~collinear{a,b,c} + ==> interior(convex hull {a,b,c}) = + {v | ?x y z. &0 < x /\ x < &1 /\ + &0 < y /\ y < &1 /\ + &0 < z /\ z < &1 /\ + x + y + z = &1 /\ + x % a + y % b + z % c = v}`, + REPEAT STRIP_TAC THEN ASM_SIMP_TAC[INTERIOR_CONVEX_HULL_3_MINIMAL] THEN + REWRITE_TAC[EXTENSION; IN_ELIM_THM] THEN GEN_TAC THEN + REPEAT(AP_TERM_TAC THEN ABS_TAC) THEN EQ_TAC THEN STRIP_TAC THEN + ASM_REWRITE_TAC[] THEN ASM_REAL_ARITH_TAC);; + +(* ------------------------------------------------------------------------- *) +(* Similar results for closure and (relative or absolute) frontier. *) +(* ------------------------------------------------------------------------- *) + +let CLOSURE_CONVEX_HULL = prove + (`!s. compact s ==> closure(convex hull s) = convex hull s`, + SIMP_TAC[CLOSURE_CLOSED; COMPACT_IMP_CLOSED; COMPACT_CONVEX_HULL]);; + +let RELATIVE_FRONTIER_CONVEX_HULL_EXPLICIT = prove + (`!s:real^N->bool. + ~(affine_dependent s) + ==> relative_frontier(convex hull s) = + {y | ?u. (!x. x IN s ==> &0 <= u x) /\ + (?x. x IN s /\ u x = &0) /\ + sum s u = &1 /\ + vsum s (\x. u x % x) = y}`, + REPEAT STRIP_TAC THEN REWRITE_TAC[relative_frontier; UNIONS_GSPEC] THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP AFFINE_INDEPENDENT_IMP_FINITE) THEN + ASM_SIMP_TAC[CLOSURE_CONVEX_HULL; FINITE_IMP_COMPACT] THEN + ASM_SIMP_TAC[CONVEX_HULL_FINITE; RELATIVE_INTERIOR_CONVEX_HULL_EXPLICIT] THEN + GEN_REWRITE_TAC I [EXTENSION] THEN X_GEN_TAC `y:real^N` THEN + REWRITE_TAC[IN_DIFF; IN_ELIM_THM] THEN EQ_TAC THENL + [DISCH_THEN(CONJUNCTS_THEN2 + (X_CHOOSE_THEN `u:real^N->real` STRIP_ASSUME_TAC) ASSUME_TAC) THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [NOT_EXISTS_THM]) THEN + DISCH_THEN(MP_TAC o SPEC `u:real^N->real`) THEN + ASM_REWRITE_TAC[NOT_FORALL_THM; NOT_IMP] THEN + DISCH_THEN(CHOOSE_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + ASM_SIMP_TAC[REAL_ARITH `&0 <= x ==> (~(&0 < x) <=> x = &0)`] THEN + DISCH_TAC THEN EXISTS_TAC `u:real^N->real` THEN + ASM_REWRITE_TAC[] THEN ASM_MESON_TAC[]; + DISCH_THEN(X_CHOOSE_THEN `u:real^N->real` + (REPEAT_TCL CONJUNCTS_THEN ASSUME_TAC)) THEN + CONJ_TAC THENL + [EXISTS_TAC `u:real^N->real` THEN ASM_SIMP_TAC[]; ALL_TAC] THEN + DISCH_THEN(X_CHOOSE_THEN `v:real^N->real` STRIP_ASSUME_TAC) THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE RAND_CONV + [AFFINE_DEPENDENT_EXPLICIT]) THEN + REWRITE_TAC[] THEN MAP_EVERY EXISTS_TAC + [`s:real^N->bool`; `(\x. u x - v x):real^N->real`] THEN + ASM_SIMP_TAC[SUBSET_REFL; VECTOR_SUB_RDISTRIB; SUM_SUB; VSUM_SUB] THEN + REWRITE_TAC[REAL_SUB_0; VECTOR_SUB_EQ] THEN ASM_MESON_TAC[REAL_LT_REFL]]);; + +let FRONTIER_CONVEX_HULL_EXPLICIT = prove + (`!s:real^N->bool. + ~(affine_dependent s) + ==> frontier(convex hull s) = + {y | ?u. (!x. x IN s ==> &0 <= u x) /\ + (dimindex(:N) < CARD s ==> ?x. x IN s /\ u x = &0) /\ + sum s u = &1 /\ + vsum s (\x. u x % x) = y}`, + REPEAT STRIP_TAC THEN REWRITE_TAC[frontier] THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP AFFINE_INDEPENDENT_IMP_FINITE) THEN + DISJ_CASES_TAC + (ARITH_RULE `CARD(s:real^N->bool) <= dimindex(:N) \/ + dimindex(:N) < CARD(s:real^N->bool)`) + THENL + [ASM_SIMP_TAC[GSYM NOT_LE; INTERIOR_CONVEX_HULL_EXPLICIT] THEN + ASM_SIMP_TAC[CLOSURE_CONVEX_HULL; FINITE_IMP_COMPACT; DIFF_EMPTY] THEN + REWRITE_TAC[CONVEX_HULL_FINITE]; + ASM_SIMP_TAC[GSYM RELATIVE_FRONTIER_CONVEX_HULL_EXPLICIT] THEN + REWRITE_TAC[relative_frontier] THEN AP_TERM_TAC THEN CONV_TAC SYM_CONV THEN + MATCH_MP_TAC RELATIVE_INTERIOR_INTERIOR THEN + MATCH_MP_TAC(SET_RULE `!s. s SUBSET t /\ s = UNIV ==> t = UNIV`) THEN + EXISTS_TAC `affine hull s:real^N->bool` THEN + ASM_SIMP_TAC[AFFINE_INDEPENDENT_SPAN_GT; HULL_MONO; HULL_SUBSET]]);; + +let RELATIVE_FRONTIER_CONVEX_HULL_CASES = prove + (`!s:real^N->bool. + ~(affine_dependent s) + ==> relative_frontier(convex hull s) = + UNIONS { convex hull (s DELETE a) |a| a IN s }`, + REPEAT STRIP_TAC THEN REWRITE_TAC[UNIONS_GSPEC] THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP AFFINE_INDEPENDENT_IMP_FINITE) THEN + ASM_SIMP_TAC[RELATIVE_FRONTIER_CONVEX_HULL_EXPLICIT] THEN + REWRITE_TAC[EXTENSION; IN_ELIM_THM; CONVEX_HULL_FINITE] THEN + X_GEN_TAC `y:real^N` THEN EQ_TAC THENL + [DISCH_THEN(X_CHOOSE_THEN `u:real^N->real` MP_TAC) THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + DISCH_THEN(CONJUNCTS_THEN2 MP_TAC STRIP_ASSUME_TAC) THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `a:real^N` THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN EXISTS_TAC `u:real^N->real` THEN + ASM_SIMP_TAC[IN_DELETE; SUM_DELETE; VSUM_DELETE; REAL_SUB_RZERO] THEN + VECTOR_ARITH_TAC; + REWRITE_TAC[IN_DELETE] THEN + DISCH_THEN(X_CHOOSE_THEN `a:real^N` (CONJUNCTS_THEN2 ASSUME_TAC + (X_CHOOSE_THEN `u:real^N->real` STRIP_ASSUME_TAC))) THEN + EXISTS_TAC `(\x. if x = a then &0 else u x):real^N->real` THEN + ASM_SIMP_TAC[COND_RAND; COND_RATOR; REAL_LE_REFL; COND_ID] THEN + CONJ_TAC THENL [MESON_TAC[]; ALL_TAC] THEN + ASM_SIMP_TAC[SUM_CASES; VSUM_CASES; VECTOR_MUL_LZERO] THEN + ASM_SIMP_TAC[GSYM DELETE; SUM_0; VSUM_0; REAL_ADD_LID; VECTOR_ADD_LID]]);; + +let FRONTIER_CONVEX_HULL_CASES = prove + (`!s:real^N->bool. + ~(affine_dependent s) + ==> frontier(convex hull s) = + if CARD(s) <= dimindex(:N) then convex hull s + else UNIONS { convex hull (s DELETE a) |a| a IN s }`, + REPEAT STRIP_TAC THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP AFFINE_INDEPENDENT_IMP_FINITE) THEN + ASM_SIMP_TAC[frontier; CLOSURE_CONVEX_HULL; FINITE_IMP_COMPACT] THEN + COND_CASES_TAC THENL + [ASM_SIMP_TAC[INTERIOR_CONVEX_HULL_EXPLICIT; DIFF_EMPTY]; ALL_TAC] THEN + ASM_SIMP_TAC[GSYM RELATIVE_FRONTIER_CONVEX_HULL_CASES] THEN + ASM_SIMP_TAC[relative_frontier; frontier; + CLOSURE_CONVEX_HULL; FINITE_IMP_COMPACT] THEN + AP_TERM_TAC THEN CONV_TAC SYM_CONV THEN + RULE_ASSUM_TAC(REWRITE_RULE[NOT_LE]) THEN + MATCH_MP_TAC RELATIVE_INTERIOR_INTERIOR THEN + MATCH_MP_TAC(SET_RULE `!s. s SUBSET t /\ s = UNIV ==> t = UNIV`) THEN + EXISTS_TAC `affine hull s:real^N->bool` THEN + ASM_SIMP_TAC[AFFINE_INDEPENDENT_SPAN_GT; HULL_MONO; HULL_SUBSET]);; + +let IN_FRONTIER_CONVEX_HULL = prove + (`!s x:real^N. + FINITE s /\ CARD s <= dimindex(:N) + 1 /\ x IN s + ==> x IN frontier(convex hull s)`, + REPEAT STRIP_TAC THEN ASM_CASES_TAC `affine_dependent(s:real^N->bool)` THENL + [FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [affine_dependent]) THEN + DISCH_THEN(X_CHOOSE_THEN `a:real^N` STRIP_ASSUME_TAC) THEN + ASM_SIMP_TAC[frontier; CLOSURE_CONVEX_HULL; FINITE_IMP_COMPACT] THEN + ASM_SIMP_TAC[HULL_INC; IN_DIFF] THEN MATCH_MP_TAC(SET_RULE + `!t. s SUBSET t /\ t = {} ==> ~(x IN s)`) THEN + EXISTS_TAC `interior(affine hull s):real^N->bool` THEN + SIMP_TAC[SUBSET_INTERIOR; CONVEX_HULL_SUBSET_AFFINE_HULL] THEN + SUBGOAL_THEN `s = (a:real^N) INSERT (s DELETE a)` SUBST1_TAC THENL + [ASM SET_TAC[]; ALL_TAC] THEN + ASM_SIMP_TAC[HULL_REDUNDANT] THEN + MATCH_MP_TAC EMPTY_INTERIOR_AFFINE_HULL THEN + ASM_SIMP_TAC[FINITE_DELETE; CARD_DELETE] THEN ASM_ARITH_TAC; + ASM_SIMP_TAC[FRONTIER_CONVEX_HULL_CASES] THEN + COND_CASES_TAC THEN ASM_SIMP_TAC[HULL_INC] THEN + REWRITE_TAC[UNIONS_GSPEC; IN_ELIM_THM] THEN + SUBGOAL_THEN `?y:real^N. y IN s /\ ~(y = x)` MP_TAC THENL + [FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE + `x IN s ==> ~(s = {x}) ==> ?y. y IN s /\ ~(y = x)`)) THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [NOT_LE]) THEN + ASM_SIMP_TAC[CARD_CLAUSES; FINITE_INSERT; FINITE_EMPTY] THEN + REWRITE_TAC[NOT_LT; NOT_IN_EMPTY; ARITH_SUC; DIMINDEX_GE_1]; + MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC THEN STRIP_TAC THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC HULL_INC THEN ASM SET_TAC[]]]);; + +let NOT_IN_INTERIOR_CONVEX_HULL = prove + (`!s x:real^N. + FINITE s /\ CARD s <= dimindex(:N) + 1 /\ x IN s + ==> ~(x IN interior(convex hull s))`, + REPEAT GEN_TAC THEN + DISCH_THEN(MP_TAC o MATCH_MP IN_FRONTIER_CONVEX_HULL) THEN + SIMP_TAC[frontier; IN_DIFF]);; + +let INTERIOR_CONVEX_HULL_EQ_EMPTY = prove + (`!s:real^N->bool. + s HAS_SIZE (dimindex(:N) + 1) + ==> (interior(convex hull s) = {} <=> affine_dependent s)`, + REPEAT GEN_TAC THEN REWRITE_TAC[HAS_SIZE] THEN STRIP_TAC THEN + ASM_CASES_TAC `affine_dependent(s:real^N->bool)` THENL + [ASM_REWRITE_TAC[] THEN FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I + [affine_dependent]) THEN + DISCH_THEN(X_CHOOSE_THEN `a:real^N` STRIP_ASSUME_TAC) THEN + ASM_SIMP_TAC[frontier; CLOSURE_CONVEX_HULL; FINITE_IMP_COMPACT] THEN + ASM_SIMP_TAC[HULL_INC; IN_DIFF] THEN MATCH_MP_TAC(SET_RULE + `!t. s SUBSET t /\ t = {} ==> s = {}`) THEN + EXISTS_TAC `interior(affine hull s):real^N->bool` THEN + SIMP_TAC[SUBSET_INTERIOR; CONVEX_HULL_SUBSET_AFFINE_HULL] THEN + SUBGOAL_THEN `s = (a:real^N) INSERT (s DELETE a)` SUBST1_TAC THENL + [ASM SET_TAC[]; ALL_TAC] THEN + ASM_SIMP_TAC[HULL_REDUNDANT] THEN + MATCH_MP_TAC EMPTY_INTERIOR_AFFINE_HULL THEN + ASM_SIMP_TAC[FINITE_DELETE; CARD_DELETE] THEN ASM_ARITH_TAC; + ASM_SIMP_TAC[INTERIOR_CONVEX_HULL_EXPLICIT_MINIMAL] THEN + REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; ARITH_RULE `~(n + 1 <= n)`] THEN + EXISTS_TAC `vsum s (\x:real^N. inv(&(dimindex(:N)) + &1) % x)` THEN + REWRITE_TAC[IN_ELIM_THM] THEN + EXISTS_TAC `\x:real^N. inv(&(dimindex(:N)) + &1)` THEN + ASM_SIMP_TAC[REAL_LT_INV_EQ; REAL_ARITH `&0 < &n + &1`] THEN + ASM_SIMP_TAC[SUM_CONST; GSYM REAL_OF_NUM_ADD] THEN + CONV_TAC REAL_FIELD]);; + +(* ------------------------------------------------------------------------- *) +(* Similar things in special case (could use above as lemmas here instead). *) +(* ------------------------------------------------------------------------- *) + +let SIMPLEX_EXPLICIT = prove + (`!s:real^N->bool. + FINITE s /\ ~(vec 0 IN s) + ==> convex hull (vec 0 INSERT s) = + { y | ?u. (!x. x IN s ==> &0 <= u x) /\ + sum s u <= &1 /\ + vsum s (\x. u x % x) = y}`, + REPEAT STRIP_TAC THEN ASM_SIMP_TAC[CONVEX_HULL_FINITE; FINITE_INSERT] THEN + REWRITE_TAC[EXTENSION; IN_ELIM_THM] THEN X_GEN_TAC `y:real^N` THEN + ASM_SIMP_TAC[SUM_CLAUSES; VSUM_CLAUSES; IN_INSERT] THEN + REWRITE_TAC[VECTOR_MUL_RZERO; VECTOR_ADD_LID] THEN + EQ_TAC THEN DISCH_THEN(X_CHOOSE_THEN `u:real^N->real` STRIP_ASSUME_TAC) THENL + [EXISTS_TAC `u:real^N->real` THEN ASM_SIMP_TAC[REAL_LE_REFL] THEN + FIRST_X_ASSUM(MP_TAC o SPEC `vec 0:real^N`) THEN REWRITE_TAC[] THEN + ASM_REAL_ARITH_TAC; + EXISTS_TAC `\x:real^N. if x = vec 0 then &1 - sum (s:real^N->bool) u + else u(x)` THEN + ASM_REWRITE_TAC[] THEN REPEAT CONJ_TAC THENL + [X_GEN_TAC `x:real^N` THEN ASM_CASES_TAC `x:real^N = vec 0` THEN + ASM_REWRITE_TAC[REAL_SUB_LE]; + MATCH_MP_TAC(REAL_ARITH `s = t ==> &1 - s + t = &1`) THEN + MATCH_MP_TAC SUM_EQ THEN ASM_MESON_TAC[]; + FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN + MATCH_MP_TAC VSUM_EQ THEN ASM_MESON_TAC[]]]);; + +let STD_SIMPLEX = prove + (`convex hull (vec 0 INSERT { basis i | 1 <= i /\ i <= dimindex(:N)}) = + {x:real^N | (!i. 1 <= i /\ i <= dimindex(:N) ==> &0 <= x$i) /\ + sum (1..dimindex(:N)) (\i. x$i) <= &1 }`, + W(MP_TAC o PART_MATCH (lhs o rand) SIMPLEX_EXPLICIT o lhs o snd) THEN ANTS_TAC THENL + [REWRITE_TAC[SIMPLE_IMAGE; GSYM IN_NUMSEG] THEN + SIMP_TAC[FINITE_IMAGE; FINITE_NUMSEG; IN_IMAGE] THEN + REWRITE_TAC[IN_NUMSEG] THEN MESON_TAC[BASIS_NONZERO]; + ALL_TAC] THEN + DISCH_THEN SUBST1_TAC THEN REWRITE_TAC[EXTENSION] THEN + ONCE_REWRITE_TAC[IN_ELIM_THM] THEN X_GEN_TAC `x:real^N` THEN + REWRITE_TAC[SIMPLE_IMAGE; GSYM IN_NUMSEG] THEN + SUBGOAL_THEN `!u. sum (IMAGE (basis:num->real^N) (1..dimindex(:N))) u = + sum (1..dimindex(:N)) (u o basis)` + (fun th -> REWRITE_TAC[th]) + THENL + [GEN_TAC THEN MATCH_MP_TAC SUM_IMAGE THEN REWRITE_TAC[IN_NUMSEG] THEN + REWRITE_TAC[GSYM CONJ_ASSOC; BASIS_INJ]; + ALL_TAC] THEN + SUBGOAL_THEN `!u. vsum (IMAGE (basis:num->real^N) (1..dimindex(:N))) u = + vsum (1..dimindex(:N)) ((u:real^N->real^N) o basis)` + (fun th -> REWRITE_TAC[th]) + THENL + [GEN_TAC THEN MATCH_MP_TAC VSUM_IMAGE THEN REWRITE_TAC[IN_NUMSEG] THEN + REWRITE_TAC[GSYM CONJ_ASSOC; BASIS_INJ; FINITE_NUMSEG]; + ALL_TAC] THEN + REWRITE_TAC[o_DEF; BASIS_EXPANSION_UNIQUE; FORALL_IN_IMAGE] THEN + REWRITE_TAC[IN_NUMSEG] THEN EQ_TAC THENL + [DISCH_THEN(X_CHOOSE_THEN `u:real^N->real` STRIP_ASSUME_TAC) THEN + CONJ_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH + `x <= &1 ==> x = y ==> y <= &1`)) THEN + MATCH_MP_TAC SUM_EQ THEN ASM_SIMP_TAC[IN_NUMSEG]; + STRIP_TAC THEN EXISTS_TAC `\y:real^N. y dot x` THEN + ASM_SIMP_TAC[DOT_BASIS]]);; + +let INTERIOR_STD_SIMPLEX = prove + (`interior + (convex hull (vec 0 INSERT { basis i | 1 <= i /\ i <= dimindex(:N)})) = + {x:real^N | (!i. 1 <= i /\ i <= dimindex(:N) ==> &0 < x$i) /\ + sum (1..dimindex(:N)) (\i. x$i) < &1 }`, + REWRITE_TAC[EXTENSION; IN_INTERIOR; IN_ELIM_THM; STD_SIMPLEX] THEN + REWRITE_TAC[SUBSET; IN_BALL; IN_ELIM_THM] THEN + X_GEN_TAC `x:real^N` THEN EQ_TAC THENL + [DISCH_THEN(X_CHOOSE_THEN `e:real` STRIP_ASSUME_TAC) THEN + FIRST_ASSUM(MP_TAC o SPEC `x:real^N`) THEN REWRITE_TAC[DIST_REFL] THEN + ASM_REWRITE_TAC[] THEN STRIP_TAC THEN ASM_SIMP_TAC[REAL_LT_LE] THEN + CONJ_TAC THENL + [X_GEN_TAC `k:num` THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `x - (e / &2) % basis k:real^N`) THEN + REWRITE_TAC[NORM_ARITH `dist(x,x - e) = norm(e)`; NORM_MUL] THEN + ASM_SIMP_TAC[NORM_BASIS; REAL_ARITH `&0 < e ==> abs(e / &2) * &1 < e`; + VECTOR_SUB_COMPONENT; VECTOR_MUL_COMPONENT] THEN + DISCH_THEN(MP_TAC o SPEC `k:num` o CONJUNCT1) THEN ASM_REWRITE_TAC[] THEN + ASM_SIMP_TAC[BASIS_COMPONENT] THEN UNDISCH_TAC `&0 < e` THEN + REAL_ARITH_TAC; + FIRST_X_ASSUM(MP_TAC o SPEC `x + (e / &2) % basis 1:real^N`) THEN + REWRITE_TAC[NORM_ARITH `dist(x,x + e) = norm(e)`; NORM_MUL] THEN + ASM_SIMP_TAC[NORM_BASIS; LE_REFL; DIMINDEX_GE_1] THEN + ASM_SIMP_TAC[REAL_ARITH `&0 < e ==> abs(e / &2) * &1 < e`] THEN + DISCH_THEN(MP_TAC o CONJUNCT2) THEN + MATCH_MP_TAC(REAL_ARITH `x < y ==> y <= &1 ==> ~(x = &1)`) THEN + MATCH_MP_TAC SUM_LT THEN REWRITE_TAC[FINITE_NUMSEG; IN_NUMSEG] THEN + ONCE_REWRITE_TAC[TAUT `(a /\ b) /\ c <=> ~(a /\ b ==> ~c)`] THEN + SIMP_TAC[VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT; + BASIS_COMPONENT] THEN + CONJ_TAC THENL + [GEN_TAC THEN COND_CASES_TAC; + EXISTS_TAC `1` THEN REWRITE_TAC[LE_REFL; DIMINDEX_GE_1]] THEN + ASM_REAL_ARITH_TAC]; + STRIP_TAC THEN + EXISTS_TAC + `min (inf(IMAGE (\i. (x:real^N)$i) (1..dimindex(:N)))) + ((&1 - sum (1..dimindex(:N)) (\i. x$i)) / &(dimindex(:N)))` THEN + ASM_SIMP_TAC[REAL_LT_MIN] THEN + SIMP_TAC[REAL_LT_INF_FINITE; FINITE_IMAGE; FINITE_NUMSEG; + IMAGE_EQ_EMPTY; NUMSEG_EMPTY; GSYM NOT_LE; DIMINDEX_GE_1] THEN + REWRITE_TAC[FORALL_IN_IMAGE] THEN + ASM_SIMP_TAC[REAL_LT_RDIV_EQ; REAL_OF_NUM_LT; + ARITH_RULE `0 < x <=> 1 <= x`; DIMINDEX_GE_1] THEN + ASM_REWRITE_TAC[IN_NUMSEG; REAL_MUL_LZERO; REAL_SUB_LT] THEN + REPEAT(POP_ASSUM(K ALL_TAC)) THEN X_GEN_TAC `y:real^N` THEN + MATCH_MP_TAC MONO_AND THEN CONJ_TAC THENL + [MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `k:num` THEN + DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN + ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC(REAL_ARITH `abs(xk - yk) <= d ==> d < xk ==> &0 <= yk`); + GEN_REWRITE_TAC (LAND_CONV o LAND_CONV o RAND_CONV o RAND_CONV) + [GSYM CARD_NUMSEG_1] THEN + ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN + SIMP_TAC[GSYM SUM_CONST; FINITE_NUMSEG] THEN + MATCH_MP_TAC(REAL_ARITH + `s2 <= s0 + s1 ==> s0 < &1 - s1 ==> s2 <= &1`) THEN + REWRITE_TAC[GSYM SUM_ADD_NUMSEG] THEN + MATCH_MP_TAC SUM_LE_NUMSEG THEN REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC(REAL_ARITH `abs(y - x) <= z ==> x <= z + y`)] THEN + ASM_SIMP_TAC[GSYM VECTOR_SUB_COMPONENT; dist] THEN + MATCH_MP_TAC COMPONENT_LE_NORM THEN ASM_REWRITE_TAC[]]);; diff --git a/Multivariate/cross.ml b/Multivariate/cross.ml new file mode 100644 index 0000000..e7538b9 --- /dev/null +++ b/Multivariate/cross.ml @@ -0,0 +1,279 @@ +(* ========================================================================= *) +(* Cross products in real^3. *) +(* ========================================================================= *) + +needs "Multivariate/topology.ml";; + +prioritize_vector();; + +(* ------------------------------------------------------------------------- *) +(* The definition. *) +(* ------------------------------------------------------------------------- *) + +parse_as_infix("cross",(20,"right"));; + +let cross = new_definition + `(a:real^3) cross (b:real^3) = + vector [a$2 * b$3 - a$3 * b$2; + a$3 * b$1 - a$1 * b$3; + a$1 * b$2 - a$2 * b$1] :real^3`;; + +(* ------------------------------------------------------------------------- *) +(* Some simple automation. *) +(* ------------------------------------------------------------------------- *) + +let VEC3_TAC = + SIMP_TAC[CART_EQ; LAMBDA_BETA; FORALL_3; SUM_3; DIMINDEX_3; VECTOR_3; + vector_add; vec; dot; cross; orthogonal; basis; DET_3; + vector_neg; vector_sub; vector_mul; ARITH] THEN + CONV_TAC REAL_RING;; + +let VEC3_RULE tm = prove(tm,VEC3_TAC);; + +(* ------------------------------------------------------------------------- *) +(* Basic lemmas. *) +(* ------------------------------------------------------------------------- *) + +let ORTHOGONAL_CROSS = prove + (`!x y. orthogonal (x cross y) x /\ orthogonal (x cross y) y /\ + orthogonal x (x cross y) /\ orthogonal y (x cross y)`, + VEC3_TAC);; + +let CROSS_LZERO = prove + (`!x. (vec 0) cross x = vec 0`, + VEC3_TAC);; + +let CROSS_RZERO = prove + (`!x. x cross (vec 0) = vec 0`, + VEC3_TAC);; + +let CROSS_SKEW = prove + (`!x y. (x cross y) = --(y cross x)`, + VEC3_TAC);; + +let CROSS_REFL = prove + (`!x. x cross x = vec 0`, + VEC3_TAC);; + +let CROSS_LADD = prove + (`!x y z. (x + y) cross z = (x cross z) + (y cross z)`, + VEC3_TAC);; + +let CROSS_RADD = prove + (`!x y z. x cross (y + z) = (x cross y) + (x cross z)`, + VEC3_TAC);; + +let CROSS_LMUL = prove + (`!c x y. (c % x) cross y = c % (x cross y)`, + VEC3_TAC);; + +let CROSS_RMUL = prove + (`!c x y. x cross (c % y) = c % (x cross y)`, + VEC3_TAC);; + +let CROSS_LNEG = prove + (`!x y. (--x) cross y = --(x cross y)`, + VEC3_TAC);; + +let CROSS_RNEG = prove + (`!x y. x cross (--y) = --(x cross y)`, + VEC3_TAC);; + +let CROSS_LSUB = prove + (`!x y z. (x - y) cross z = x cross z - y cross z`, + VEC3_TAC);; + +let CROSS_RSUB = prove + (`!x y z. x cross (y - z) = x cross y - x cross z`, + VEC3_TAC);; + +let CROSS_JACOBI = prove + (`!x y z. + x cross (y cross z) + y cross (z cross x) + z cross (x cross y) = vec 0`, + VEC3_TAC);; + +let CROSS_LAGRANGE = prove + (`!x y z. x cross (y cross z) = (x dot z) % y - (x dot y) % z`, + VEC3_TAC);; + +let CROSS_TRIPLE = prove + (`!x y z. (x cross y) dot z = (y cross z) dot x`, + VEC3_TAC);; + +let DOT_CROSS_SELF = prove + (`(!x y. x dot (x cross y) = &0) /\ + (!x y. x dot (y cross x) = &0) /\ + (!x y. (x cross y) dot y = &0) /\ + (!x y. (y cross x) dot y = &0)`, + VEC3_TAC);; + +let CROSS_COMPONENTS = prove + (`!x y. (x cross y)$1 = x$2 * y$3 - y$2 * x$3 /\ + (x cross y)$2 = x$3 * y$1 - y$3 * x$1 /\ + (x cross y)$3 = x$1 * y$2 - y$1 * x$2`, + VEC3_TAC);; + +let CROSS_BASIS = prove + (`(basis 1) cross (basis 2) = basis 3 /\ + (basis 2) cross (basis 1) = --(basis 3) /\ + (basis 2) cross (basis 3) = basis 1 /\ + (basis 3) cross (basis 2) = --(basis 1) /\ + (basis 3) cross (basis 1) = basis 2 /\ + (basis 1) cross (basis 3) = --(basis 2)`, + VEC3_TAC);; + +let CROSS_BASIS_NONZERO = prove + (`!u. ~(u = vec 0) + ==> ~(u cross basis 1 = vec 0) \/ + ~(u cross basis 2 = vec 0) \/ + ~(u cross basis 3 = vec 0)`, + VEC3_TAC);; + +let CROSS_DOT_CANCEL = prove + (`!x y z. + x dot y = x dot z /\ x cross y = x cross z /\ ~(x = vec 0) ==> y = z`, + ONCE_REWRITE_TAC[GSYM VECTOR_SUB_EQ] THEN REWRITE_TAC[GSYM DOT_EQ_0] THEN + VEC3_TAC);; + +let NORM_CROSS_DOT = prove + (`!x y. norm(x cross y) pow 2 + (x dot y) pow 2 = (norm(x) * norm y) pow 2`, + REWRITE_TAC[REAL_POW_MUL; NORM_POW_2] THEN VEC3_TAC);; + +let DOT_CROSS_DET = prove + (`!x y z. x dot (y cross z) = det(vector[x;y;z]:real^3^3)`, + VEC3_TAC);; + +let CROSS_CROSS_DET = prove + (`!w x y z. (w cross x) cross (y cross z) = + det(vector[w;x;z]:real^3^3) % y - + det(vector[w;x;y]:real^3^3) % z`, + VEC3_TAC);; + +let DOT_CROSS = prove + (`!w x y z. (w cross x) dot (y cross z) = + (w dot y) * (x dot z) - (w dot z) * (x dot y)`, + VEC3_TAC);; + +let NORM_CROSS = prove + (`!x y. norm(x cross y) pow 2 = + norm(x) pow 2 * norm(y) pow 2 - (x dot y) pow 2`, + REWRITE_TAC[NORM_POW_2] THEN VEC3_TAC);; + +let CROSS_EQ_0 = prove + (`!x y. x cross y = vec 0 <=> collinear{vec 0,x,y}`, + REPEAT GEN_TAC THEN REWRITE_TAC[GSYM NORM_EQ_0] THEN + ONCE_REWRITE_TAC[REAL_RING `x = &0 <=> x pow 2 = &0`] THEN + REWRITE_TAC[NORM_CROSS; REAL_SUB_0; GSYM REAL_POW_MUL] THEN + REWRITE_TAC[GSYM REAL_EQ_SQUARE_ABS; GSYM NORM_CAUCHY_SCHWARZ_EQUAL] THEN + SIMP_TAC[real_abs; REAL_LE_MUL; NORM_POS_LE; EQ_SYM_EQ]);; + +let CROSS_0 = prove + (`(!x. vec 0 cross x = vec 0) /\ + (!x. x cross vec 0 = vec 0)`, + VEC3_TAC);; + +let CROSS_EQ_SELF = prove + (`(!x y. x cross y = x <=> x = vec 0) /\ + (!x y. x cross y = y <=> y = vec 0)`, + MESON_TAC[ORTHOGONAL_CROSS; CROSS_0; ORTHOGONAL_REFL]);; + +let NORM_AND_CROSS_EQ_0 = prove + (`!x y. x dot y = &0 /\ x cross y = vec 0 <=> x = vec 0 \/ y = vec 0`, + REPEAT GEN_TAC THEN ASM_CASES_TAC `x:real^3 = vec 0` THEN + ASM_REWRITE_TAC[CROSS_0; DOT_LZERO] THEN ASM_CASES_TAC `y:real^3 = vec 0` THEN + ASM_REWRITE_TAC[CROSS_0; DOT_RZERO] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + ASM_REWRITE_TAC[GSYM DOT_EQ_0; DOT_CROSS; REAL_MUL_LZERO] THEN + ASM_REWRITE_TAC[REAL_SUB_RZERO; REAL_ENTIRE; DOT_EQ_0]);; + +let BILINEAR_CROSS = prove + (`bilinear(cross)`, + REWRITE_TAC[linear; bilinear; CROSS_LADD; CROSS_RADD; + CROSS_LMUL; CROSS_RMUL]);; + +(* ------------------------------------------------------------------------- *) +(* Preservation by rotation, or other orthogonal transformation up to sign. *) +(* ------------------------------------------------------------------------- *) + +let CROSS_MATRIX_MUL = prove + (`!A x y. transp A ** ((A ** x) cross (A ** y)) = det A % (x cross y)`, + SIMP_TAC[CART_EQ; DIMINDEX_3; FORALL_3; SUM_3; matrix_vector_mul; + CROSS_COMPONENTS; LAMBDA_BETA; ARITH; transp; DET_3; + VECTOR_MUL_COMPONENT] THEN + REAL_ARITH_TAC);; + +let CROSS_ORTHOGONAL_MATRIX = prove + (`!A x y. orthogonal_matrix A + ==> (A ** x) cross (A ** y) = det A % (A ** (x cross y))`, + MP_TAC CROSS_MATRIX_MUL THEN + REPEAT(MATCH_MP_TAC MONO_FORALL THEN GEN_TAC) THEN + REWRITE_TAC[orthogonal_matrix] THEN + DISCH_THEN(fun th -> DISCH_TAC THEN MP_TAC th) THEN + DISCH_THEN(MP_TAC o AP_TERM `matrix_vector_mul (A:real^3^3)`) THEN + ASM_REWRITE_TAC[MATRIX_VECTOR_MUL_ASSOC; MATRIX_VECTOR_MUL_LID] THEN + DISCH_THEN SUBST1_TAC THEN REWRITE_TAC[MATRIX_VECTOR_MUL_RMUL]);; + +let CROSS_ROTATION_MATRIX = prove + (`!A x y. rotation_matrix A + ==> (A ** x) cross (A ** y) = A ** (x cross y)`, + SIMP_TAC[rotation_matrix; CROSS_ORTHOGONAL_MATRIX; VECTOR_MUL_LID]);; + +let CROSS_ROTOINVERSION_MATRIX = prove + (`!A x y. rotoinversion_matrix A + ==> (A ** x) cross (A ** y) = --(A ** (x cross y))`, + SIMP_TAC[rotoinversion_matrix; CROSS_ORTHOGONAL_MATRIX; VECTOR_MUL_LID; + VECTOR_MUL_LNEG]);; + +let CROSS_ORTHOGONAL_TRANSFORMATION = prove + (`!f x y. + orthogonal_transformation f + ==> (f x) cross (f y) = det(matrix f) % f(x cross y)`, + GEN_TAC THEN + MP_TAC(ISPEC `matrix(f:real^3->real^3)` CROSS_ORTHOGONAL_MATRIX) THEN + REPEAT(MATCH_MP_TAC MONO_FORALL THEN GEN_TAC) THEN + DISCH_THEN(fun th -> DISCH_TAC THEN MP_TAC th) THEN + ANTS_TAC THENL + [ASM_MESON_TAC[ORTHOGONAL_TRANSFORMATION_MATRIX; + ORTHOGONAL_TRANSFORMATION_LINEAR]; + ASM_SIMP_TAC[MATRIX_WORKS; ORTHOGONAL_TRANSFORMATION_LINEAR]]);; + +let CROSS_LINEAR_IMAGE = prove + (`!f x y. linear f /\ (!x. norm(f x) = norm x) /\ det(matrix f) = &1 + ==> (f x) cross (f y) = f(x cross y)`, + SIMP_TAC[ORTHOGONAL_TRANSFORMATION; CONJ_ASSOC; VECTOR_MUL_LID; + CROSS_ORTHOGONAL_TRANSFORMATION]);; + +(* ------------------------------------------------------------------------- *) +(* Continuity. *) +(* ------------------------------------------------------------------------- *) + +let CONTINUOUS_CROSS = prove + (`!net:(A)net f g. + f continuous net /\ g continuous net + ==> (\x. (f x) cross (g x)) continuous net`, + REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[CONTINUOUS_COMPONENTWISE_LIFT] THEN + REWRITE_TAC[cross; VECTOR_3; DIMINDEX_3; FORALL_3; LIFT_SUB] THEN + REPEAT CONJ_TAC THEN MATCH_MP_TAC CONTINUOUS_SUB THEN + REWRITE_TAC[LIFT_CMUL] THEN CONJ_TAC THEN MATCH_MP_TAC CONTINUOUS_MUL THEN + ASM_SIMP_TAC[o_DEF; CONTINUOUS_LIFT_COMPONENT_COMPOSE]);; + +let CONTINUOUS_ON_CROSS = prove + (`!f:real^N->real^3 g s. + f continuous_on s /\ g continuous_on s + ==> (\x. (f x) cross (g x)) continuous_on s`, + SIMP_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN; CONTINUOUS_CROSS]);; + +(* ------------------------------------------------------------------------- *) +(* Prove a weaker variant for more convenient interface with functions *) +(* intended to work in 1 dimension. *) +(* ------------------------------------------------------------------------- *) + +let CROSS_LINEAR_IMAGE_WEAK = prove + (`!f x y. linear f /\ (!x. norm(f x) = norm x) /\ + (2 <= dimindex(:3) ==> det(matrix f) = &1) + ==> (f x) cross (f y) = f(x cross y)`, + REWRITE_TAC[DIMINDEX_3; ARITH] THEN + SIMP_TAC[ORTHOGONAL_TRANSFORMATION; CONJ_ASSOC; VECTOR_MUL_LID; + CROSS_ORTHOGONAL_TRANSFORMATION]);; + +add_linear_invariants [CROSS_LINEAR_IMAGE_WEAK];; diff --git a/Multivariate/derivatives.ml b/Multivariate/derivatives.ml new file mode 100644 index 0000000..56dd6a6 --- /dev/null +++ b/Multivariate/derivatives.ml @@ -0,0 +1,2620 @@ +(* ========================================================================= *) +(* Multivariate calculus in Euclidean space. *) +(* *) +(* (c) Copyright, John Harrison 1998-2008 *) +(* ========================================================================= *) + +needs "Multivariate/dimension.ml";; + +(* ------------------------------------------------------------------------- *) +(* Derivatives. The definition is slightly tricky since we make it work over *) +(* nets of a particular form. This lets us prove theorems generally and use *) +(* "at a" or "at a within s" for restriction to a set (1-sided on R etc.) *) +(* ------------------------------------------------------------------------- *) + +parse_as_infix ("has_derivative",(12,"right"));; + +let has_derivative = new_definition + `(f has_derivative f') net <=> + linear f' /\ + ((\y. inv(norm(y - netlimit net)) % + (f(y) - + (f(netlimit net) + f'(y - netlimit net)))) --> vec 0) net`;; + +(* ------------------------------------------------------------------------- *) +(* These are the only cases we'll care about, probably. *) +(* ------------------------------------------------------------------------- *) + +let has_derivative_within = prove + (`!f:real^M->real^N f' x s. + (f has_derivative f') (at x within s) <=> + linear f' /\ + ((\y. inv(norm(y - x)) % (f(y) - (f(x) + f'(y - x)))) --> vec 0) + (at x within s)`, + REPEAT GEN_TAC THEN REWRITE_TAC[has_derivative] THEN AP_TERM_TAC THEN + ASM_CASES_TAC `trivial_limit(at (x:real^M) within s)` THENL + [ASM_REWRITE_TAC[LIM]; ASM_SIMP_TAC[NETLIMIT_WITHIN]]);; + +let has_derivative_at = prove + (`!f:real^M->real^N f' x. + (f has_derivative f') (at x) <=> + linear f' /\ + ((\y. inv(norm(y - x)) % (f(y) - (f(x) + f'(y - x)))) --> vec 0) + (at x)`, + ONCE_REWRITE_TAC[GSYM WITHIN_UNIV] THEN + REWRITE_TAC[has_derivative_within]);; + +(* ------------------------------------------------------------------------- *) +(* More explicit epsilon-delta forms. *) +(* ------------------------------------------------------------------------- *) + +let HAS_DERIVATIVE_WITHIN = prove + (`(f has_derivative f')(at x within s) <=> + linear f' /\ + !e. &0 < e + ==> ?d. &0 < d /\ + !x'. x' IN s /\ + &0 < norm(x' - x) /\ norm(x' - x) < d + ==> norm(f(x') - f(x) - f'(x' - x)) / + norm(x' - x) < e`, + SIMP_TAC[has_derivative_within; LIM_WITHIN] THEN AP_TERM_TAC THEN + REWRITE_TAC[dist; VECTOR_ARITH `(x' - (x + d)) = x' - x - d:real^N`] THEN + REWRITE_TAC[real_div; VECTOR_SUB_RZERO; NORM_MUL] THEN + REWRITE_TAC[REAL_MUL_AC; REAL_ABS_INV; REAL_ABS_NORM]);; + +let HAS_DERIVATIVE_AT = prove + (`(f has_derivative f')(at x) <=> + linear f' /\ + !e. &0 < e + ==> ?d. &0 < d /\ + !x'. &0 < norm(x' - x) /\ norm(x' - x) < d + ==> norm(f(x') - f(x) - f'(x' - x)) / + norm(x' - x) < e`, + ONCE_REWRITE_TAC[GSYM WITHIN_UNIV] THEN + REWRITE_TAC[HAS_DERIVATIVE_WITHIN; IN_UNIV]);; + +let HAS_DERIVATIVE_AT_WITHIN = prove + (`!f x s. (f has_derivative f') (at x) + ==> (f has_derivative f') (at x within s)`, + REWRITE_TAC[HAS_DERIVATIVE_WITHIN; HAS_DERIVATIVE_AT] THEN MESON_TAC[]);; + +let HAS_DERIVATIVE_WITHIN_OPEN = prove + (`!f f' a s. + a IN s /\ open s + ==> ((f has_derivative f') (at a within s) <=> + (f has_derivative f') (at a))`, + SIMP_TAC[has_derivative_within; has_derivative_at; LIM_WITHIN_OPEN]);; + +(* ------------------------------------------------------------------------- *) +(* Combining theorems. *) +(* ------------------------------------------------------------------------- *) + +let HAS_DERIVATIVE_LINEAR = prove + (`!f net. linear f ==> (f has_derivative f) net`, + REWRITE_TAC[has_derivative; linear] THEN + SIMP_TAC[VECTOR_ARITH `x - y = x + --(&1) % y`] THEN + REWRITE_TAC[VECTOR_ARITH `x + --(&1) % (y + x + --(&1) % y) = vec 0`] THEN + REWRITE_TAC[VECTOR_MUL_RZERO; LIM_CONST]);; + +let HAS_DERIVATIVE_ID = prove + (`!net. ((\x. x) has_derivative (\h. h)) net`, + SIMP_TAC[HAS_DERIVATIVE_LINEAR; LINEAR_ID]);; + +let HAS_DERIVATIVE_CONST = prove + (`!c net. ((\x. c) has_derivative (\h. vec 0)) net`, + REPEAT GEN_TAC THEN REWRITE_TAC[has_derivative; linear] THEN + REWRITE_TAC[VECTOR_ADD_RID; VECTOR_SUB_REFL; VECTOR_MUL_RZERO; LIM_CONST]);; + +let HAS_DERIVATIVE_LIFT_COMPONENT = prove + (`!net:(real^N)net. ((\x. lift(x$i)) has_derivative (\x. lift(x$i))) net`, + GEN_TAC THEN MATCH_MP_TAC HAS_DERIVATIVE_LINEAR THEN + REWRITE_TAC[linear; VECTOR_MUL_COMPONENT; VECTOR_ADD_COMPONENT] THEN + REWRITE_TAC[LIFT_ADD; LIFT_CMUL]);; + +let HAS_DERIVATIVE_CMUL = prove + (`!f f' net c. (f has_derivative f') net + ==> ((\x. c % f(x)) has_derivative (\h. c % f'(h))) net`, + REPEAT GEN_TAC THEN SIMP_TAC[has_derivative; LINEAR_COMPOSE_CMUL] THEN + DISCH_THEN(MP_TAC o SPEC `c:real` o MATCH_MP LIM_CMUL o CONJUNCT2) THEN + REWRITE_TAC[VECTOR_MUL_RZERO] THEN + MATCH_MP_TAC EQ_IMP THEN + AP_THM_TAC THEN AP_THM_TAC THEN + AP_TERM_TAC THEN ABS_TAC THEN VECTOR_ARITH_TAC);; + +let HAS_DERIVATIVE_CMUL_EQ = prove + (`!f f' net c. + ~(c = &0) + ==> (((\x. c % f(x)) has_derivative (\h. c % f'(h))) net <=> + (f has_derivative f') net)`, + REPEAT STRIP_TAC THEN EQ_TAC THEN + DISCH_THEN(MP_TAC o MATCH_MP HAS_DERIVATIVE_CMUL) THENL + [DISCH_THEN(MP_TAC o SPEC `inv(c):real`); + DISCH_THEN(MP_TAC o SPEC `c:real`)] THEN + ASM_SIMP_TAC[VECTOR_MUL_ASSOC; REAL_MUL_LINV; VECTOR_MUL_LID; ETA_AX]);; + +let HAS_DERIVATIVE_NEG = prove + (`!f f' net. (f has_derivative f') net + ==> ((\x. --(f(x))) has_derivative (\h. --(f'(h)))) net`, + ONCE_REWRITE_TAC[VECTOR_NEG_MINUS1] THEN + SIMP_TAC[HAS_DERIVATIVE_CMUL]);; + +let HAS_DERIVATIVE_NEG_EQ = prove + (`!f f' net. ((\x. --(f(x))) has_derivative (\h. --(f'(h)))) net <=> + (f has_derivative f') net`, + REPEAT GEN_TAC THEN EQ_TAC THEN + DISCH_THEN(MP_TAC o MATCH_MP HAS_DERIVATIVE_NEG) THEN + REWRITE_TAC[VECTOR_NEG_NEG; ETA_AX]);; + +let HAS_DERIVATIVE_ADD = prove + (`!f f' g g' net. + (f has_derivative f') net /\ (g has_derivative g') net + ==> ((\x. f(x) + g(x)) has_derivative (\h. f'(h) + g'(h))) net`, + REPEAT GEN_TAC THEN SIMP_TAC[has_derivative; LINEAR_COMPOSE_ADD] THEN + DISCH_THEN(MP_TAC o MATCH_MP (TAUT `(a /\ b) /\ (c /\ d) ==> b /\ d`)) THEN + DISCH_THEN(MP_TAC o MATCH_MP LIM_ADD) THEN REWRITE_TAC[VECTOR_ADD_LID] THEN + MATCH_MP_TAC EQ_IMP THEN + AP_THM_TAC THEN AP_THM_TAC THEN + AP_TERM_TAC THEN ABS_TAC THEN VECTOR_ARITH_TAC);; + +let HAS_DERIVATIVE_SUB = prove + (`!f f' g g' net. + (f has_derivative f') net /\ (g has_derivative g') net + ==> ((\x. f(x) - g(x)) has_derivative (\h. f'(h) - g'(h))) net`, + SIMP_TAC[VECTOR_SUB; HAS_DERIVATIVE_ADD; HAS_DERIVATIVE_NEG]);; + +let HAS_DERIVATIVE_VSUM = prove + (`!f net s. + FINITE s /\ + (!a. a IN s ==> ((f a) has_derivative (f' a)) net) + ==> ((\x. vsum s (\a. f a x)) has_derivative (\h. vsum s (\a. f' a h))) + net`, + GEN_TAC THEN GEN_TAC THEN REWRITE_TAC[IMP_CONJ] THEN + MATCH_MP_TAC FINITE_INDUCT_STRONG THEN + SIMP_TAC[VSUM_CLAUSES; HAS_DERIVATIVE_CONST] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_DERIVATIVE_ADD THEN + REWRITE_TAC[ETA_AX] THEN ASM_SIMP_TAC[IN_INSERT]);; + +let HAS_DERIVATIVE_VSUM_NUMSEG = prove + (`!f net m n. + (!i. m <= i /\ i <= n ==> ((f i) has_derivative (f' i)) net) + ==> ((\x. vsum (m..n) (\i. f i x)) has_derivative + (\h. vsum (m..n) (\i. f' i h))) net`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_DERIVATIVE_VSUM THEN + ASM_REWRITE_TAC[IN_NUMSEG; FINITE_NUMSEG]);; + +let HAS_DERIVATIVE_COMPONENTWISE_WITHIN = prove + (`!f:real^M->real^N f' a s. + (f has_derivative f') (at a within s) <=> + !i. 1 <= i /\ i <= dimindex(:N) + ==> ((\x. lift(f(x)$i)) has_derivative (\x. lift(f'(x)$i))) + (at a within s)`, + REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[has_derivative_within] THEN + GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) + [LINEAR_COMPONENTWISE; LIM_COMPONENTWISE_LIFT] THEN + SIMP_TAC[AND_FORALL_THM; TAUT `(p ==> q) /\ (p ==> r) <=> p ==> q /\ r`] THEN + REWRITE_TAC[GSYM LIFT_ADD; GSYM LIFT_CMUL; GSYM LIFT_SUB] THEN + REWRITE_TAC[VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT; VEC_COMPONENT; + VECTOR_SUB_COMPONENT; LIFT_NUM]);; + +let HAS_DERIVATIVE_COMPONENTWISE_AT = prove + (`!f:real^M->real^N f' a. + (f has_derivative f') (at a) <=> + !i. 1 <= i /\ i <= dimindex(:N) + ==> ((\x. lift(f(x)$i)) has_derivative (\x. lift(f'(x)$i))) (at a)`, + ONCE_REWRITE_TAC[GSYM WITHIN_UNIV] THEN + MATCH_ACCEPT_TAC HAS_DERIVATIVE_COMPONENTWISE_WITHIN);; + +(* ------------------------------------------------------------------------- *) +(* Somewhat different results for derivative of scalar multiplier. *) +(* ------------------------------------------------------------------------- *) + +let HAS_DERIVATIVE_VMUL_COMPONENT = prove + (`!c:real^M->real^N c' k v:real^P. + 1 <= k /\ k <= dimindex(:N) /\ (c has_derivative c') net + ==> ((\x. c(x)$k % v) has_derivative (\x. c'(x)$k % v)) net`, + SIMP_TAC[has_derivative; LINEAR_VMUL_COMPONENT] THEN + REPEAT STRIP_TAC THEN + REWRITE_TAC[GSYM VECTOR_ADD_RDISTRIB; GSYM VECTOR_SUB_RDISTRIB] THEN + SUBST1_TAC(VECTOR_ARITH `vec 0 = &0 % (v:real^P)`) THEN + REWRITE_TAC[VECTOR_MUL_ASSOC] THEN MATCH_MP_TAC LIM_VMUL THEN + ASM_SIMP_TAC[GSYM VECTOR_SUB_COMPONENT; GSYM VECTOR_ADD_COMPONENT] THEN + ASM_SIMP_TAC[GSYM VECTOR_MUL_COMPONENT] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [LIM]) THEN REWRITE_TAC[LIM] THEN + REWRITE_TAC[dist; LIFT_NUM; VECTOR_SUB_RZERO; o_THM; NORM_LIFT] THEN + ASM_SIMP_TAC[VECTOR_MUL_COMPONENT; REAL_ABS_MUL; NORM_MUL] THEN + ASM_MESON_TAC[REAL_LET_TRANS; COMPONENT_LE_NORM; + REAL_LE_LMUL; REAL_ABS_POS]);; + +let HAS_DERIVATIVE_VMUL_DROP = prove + (`!c c' v. (c has_derivative c') net + ==> ((\x. drop(c(x)) % v) has_derivative (\x. drop(c'(x)) % v)) net`, + SIMP_TAC[drop; LE_REFL; DIMINDEX_1; HAS_DERIVATIVE_VMUL_COMPONENT]);; + +let HAS_DERIVATIVE_LIFT_DOT = prove + (`!f:real^M->real^N f'. + (f has_derivative f') net + ==> ((\x. lift(v dot f(x))) has_derivative (\t. lift(v dot (f' t)))) net`, + REPEAT GEN_TAC THEN REWRITE_TAC[has_derivative] THEN + REWRITE_TAC[GSYM LIFT_SUB; GSYM LIFT_ADD; GSYM LIFT_CMUL] THEN + REWRITE_TAC[GSYM DOT_RADD; GSYM DOT_RSUB; GSYM DOT_RMUL] THEN + SUBGOAL_THEN + `(\t. lift (v dot (f':real^M->real^N) t)) = (\y. lift(v dot y)) o f'` + SUBST1_TAC THENL [REWRITE_TAC[o_DEF]; ALL_TAC] THEN + SIMP_TAC[LINEAR_COMPOSE; LINEAR_LIFT_DOT] THEN + DISCH_THEN(MP_TAC o MATCH_MP LIM_LIFT_DOT o CONJUNCT2) THEN + SIMP_TAC[o_DEF; DOT_RZERO; LIFT_NUM]);; + +(* ------------------------------------------------------------------------- *) +(* Limit transformation for derivatives. *) +(* ------------------------------------------------------------------------- *) + +let HAS_DERIVATIVE_TRANSFORM_WITHIN = prove + (`!f f' g x s d. + &0 < d /\ x IN s /\ + (!x'. x' IN s /\ dist (x',x) < d ==> f x' = g x') /\ + (f has_derivative f') (at x within s) + ==> (g has_derivative f') (at x within s)`, + REPEAT GEN_TAC THEN SIMP_TAC[has_derivative_within; IMP_CONJ] THEN + REPLICATE_TAC 4 DISCH_TAC THEN + MATCH_MP_TAC(REWRITE_RULE[TAUT `a /\ b /\ c ==> d <=> a /\ b ==> c ==> d`] + LIM_TRANSFORM_WITHIN) THEN + EXISTS_TAC `d:real` THEN ASM_SIMP_TAC[DIST_REFL]);; + +let HAS_DERIVATIVE_TRANSFORM_AT = prove + (`!f f' g x d. + &0 < d /\ (!x'. dist (x',x) < d ==> f x' = g x') /\ + (f has_derivative f') (at x) + ==> (g has_derivative f') (at x)`, + ONCE_REWRITE_TAC[GSYM WITHIN_UNIV] THEN + MESON_TAC[HAS_DERIVATIVE_TRANSFORM_WITHIN; IN_UNIV]);; + +let HAS_DERIVATIVE_TRANSFORM_WITHIN_OPEN = prove + (`!f g:real^M->real^N s x. + open s /\ x IN s /\ + (!y. y IN s ==> f y = g y) /\ + (f has_derivative f') (at x) + ==> (g has_derivative f') (at x)`, + REPEAT GEN_TAC THEN SIMP_TAC[has_derivative_at; IMP_CONJ] THEN + REPLICATE_TAC 4 DISCH_TAC THEN + MATCH_MP_TAC(REWRITE_RULE + [TAUT `a /\ b /\ c /\ d ==> e <=> a /\ b /\ c ==> d ==> e`] + LIM_TRANSFORM_WITHIN_OPEN) THEN + EXISTS_TAC `s:real^M->bool` THEN ASM_SIMP_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* Differentiability. *) +(* ------------------------------------------------------------------------- *) + +parse_as_infix ("differentiable",(12,"right"));; +parse_as_infix ("differentiable_on",(12,"right"));; + +let differentiable = new_definition + `f differentiable net <=> ?f'. (f has_derivative f') net`;; + +let differentiable_on = new_definition + `f differentiable_on s <=> !x. x IN s ==> f differentiable (at x within s)`;; + +let HAS_DERIVATIVE_IMP_DIFFERENTIABLE = prove + (`!f f' net. (f has_derivative f') net ==> f differentiable net`, + REWRITE_TAC[differentiable] THEN MESON_TAC[]);; + +let DIFFERENTIABLE_AT_WITHIN = prove + (`!f s x. f differentiable (at x) + ==> f differentiable (at x within s)`, + REWRITE_TAC[differentiable] THEN MESON_TAC[HAS_DERIVATIVE_AT_WITHIN]);; + +let DIFFERENTIABLE_WITHIN_OPEN = prove + (`!f a s. + a IN s /\ open s + ==> (f differentiable (at a within s) <=> (f differentiable (at a)))`, + SIMP_TAC[differentiable; HAS_DERIVATIVE_WITHIN_OPEN]);; + +let DIFFERENTIABLE_AT_IMP_DIFFERENTIABLE_ON = prove + (`!f s. (!x. x IN s ==> f differentiable at x) ==> f differentiable_on s`, + REWRITE_TAC[differentiable_on] THEN MESON_TAC[DIFFERENTIABLE_AT_WITHIN]);; + +let DIFFERENTIABLE_ON_EQ_DIFFERENTIABLE_AT = prove + (`!f s. open s ==> (f differentiable_on s <=> + !x. x IN s ==> f differentiable at x)`, + SIMP_TAC[differentiable_on; DIFFERENTIABLE_WITHIN_OPEN]);; + +let DIFFERENTIABLE_TRANSFORM_WITHIN = prove + (`!f g x s d. + &0 < d /\ x IN s /\ + (!x'. x' IN s /\ dist (x',x) < d ==> f x' = g x') /\ + f differentiable (at x within s) + ==> g differentiable (at x within s)`, + REWRITE_TAC[differentiable] THEN + MESON_TAC[HAS_DERIVATIVE_TRANSFORM_WITHIN]);; + +let DIFFERENTIABLE_TRANSFORM_AT = prove + (`!f g x d. + &0 < d /\ + (!x'. dist (x',x) < d ==> f x' = g x') /\ + f differentiable at x + ==> g differentiable at x`, + REWRITE_TAC[differentiable] THEN + MESON_TAC[HAS_DERIVATIVE_TRANSFORM_AT]);; + +(* ------------------------------------------------------------------------- *) +(* Frechet derivative and Jacobian matrix. *) +(* ------------------------------------------------------------------------- *) + +let frechet_derivative = new_definition + `frechet_derivative f net = @f'. (f has_derivative f') net`;; + +let FRECHET_DERIVATIVE_WORKS = prove + (`!f net. f differentiable net <=> + (f has_derivative (frechet_derivative f net)) net`, + REPEAT GEN_TAC THEN REWRITE_TAC[frechet_derivative] THEN + CONV_TAC(RAND_CONV SELECT_CONV) THEN REWRITE_TAC[differentiable]);; + +let LINEAR_FRECHET_DERIVATIVE = prove + (`!f net. f differentiable net ==> linear(frechet_derivative f net)`, + SIMP_TAC[FRECHET_DERIVATIVE_WORKS; has_derivative]);; + +let jacobian = new_definition + `jacobian f net = matrix(frechet_derivative f net)`;; + +let JACOBIAN_WORKS = prove + (`!f net. f differentiable net <=> + (f has_derivative (\h. jacobian f net ** h)) net`, + REPEAT GEN_TAC THEN EQ_TAC THENL [ALL_TAC; MESON_TAC[differentiable]] THEN + REWRITE_TAC[FRECHET_DERIVATIVE_WORKS] THEN + SIMP_TAC[jacobian; MATRIX_WORKS; has_derivative] THEN SIMP_TAC[ETA_AX]);; + +(* ------------------------------------------------------------------------- *) +(* Differentiability implies continuity. *) +(* ------------------------------------------------------------------------- *) + +let LIM_MUL_NORM_WITHIN = prove + (`!f a s. (f --> vec 0) (at a within s) + ==> ((\x. norm(x - a) % f(x)) --> vec 0) (at a within s)`, + REPEAT GEN_TAC THEN REWRITE_TAC[LIM_WITHIN] THEN + MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `e:real` THEN + ASM_CASES_TAC `&0 < e` THEN ASM_REWRITE_TAC[dist; VECTOR_SUB_RZERO] THEN + DISCH_THEN(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `min d (&1)` THEN ASM_REWRITE_TAC[REAL_LT_MIN; REAL_LT_01] THEN + REPEAT STRIP_TAC THEN REWRITE_TAC[NORM_MUL; REAL_ABS_NORM] THEN + GEN_REWRITE_TAC RAND_CONV [GSYM REAL_MUL_LID] THEN + ASM_SIMP_TAC[REAL_LT_MUL2; NORM_POS_LE]);; + +let DIFFERENTIABLE_IMP_CONTINUOUS_WITHIN = prove + (`!f:real^M->real^N s. + f differentiable (at x within s) ==> f continuous (at x within s)`, + REWRITE_TAC[differentiable; has_derivative_within; CONTINUOUS_WITHIN] THEN + REPEAT GEN_TAC THEN + DISCH_THEN(X_CHOOSE_THEN `f':real^M->real^N` MP_TAC) THEN + STRIP_TAC THEN FIRST_X_ASSUM(MP_TAC o MATCH_MP LIM_MUL_NORM_WITHIN) THEN + SUBGOAL_THEN + `((f':real^M->real^N) o (\y. y - x)) continuous (at x within s)` + MP_TAC THENL + [MATCH_MP_TAC CONTINUOUS_WITHIN_COMPOSE THEN + ASM_SIMP_TAC[LINEAR_CONTINUOUS_WITHIN] THEN + SIMP_TAC[CONTINUOUS_SUB; CONTINUOUS_CONST; CONTINUOUS_WITHIN_ID]; + ALL_TAC] THEN + REWRITE_TAC[CONTINUOUS_WITHIN; o_DEF] THEN + ASM_REWRITE_TAC[VECTOR_MUL_ASSOC; IMP_IMP; IN_UNIV] THEN + DISCH_THEN(MP_TAC o MATCH_MP LIM_ADD) THEN + SIMP_TAC[LIM_WITHIN; GSYM DIST_NZ; REAL_MUL_RINV; NORM_EQ_0; + VECTOR_ARITH `(x - y = vec 0) <=> (x = y)`; + VECTOR_MUL_LID; VECTOR_SUB_REFL] THEN + FIRST_ASSUM(SUBST1_TAC o MATCH_MP LINEAR_0) THEN + REWRITE_TAC[dist; VECTOR_SUB_RZERO] THEN + REWRITE_TAC[VECTOR_ARITH `(a + b - (c + a)) - (vec 0 + vec 0) = b - c`]);; + +let DIFFERENTIABLE_IMP_CONTINUOUS_AT = prove + (`!f:real^M->real^N x. f differentiable (at x) ==> f continuous (at x)`, + ONCE_REWRITE_TAC[GSYM WITHIN_UNIV] THEN + REWRITE_TAC[DIFFERENTIABLE_IMP_CONTINUOUS_WITHIN]);; + +let DIFFERENTIABLE_IMP_CONTINUOUS_ON = prove + (`!f:real^M->real^N s. f differentiable_on s ==> f continuous_on s`, + SIMP_TAC[differentiable_on; CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN; + DIFFERENTIABLE_IMP_CONTINUOUS_WITHIN]);; + +let HAS_DERIVATIVE_WITHIN_SUBSET = prove + (`!f s t x. (f has_derivative f') (at x within s) /\ t SUBSET s + ==> (f has_derivative f') (at x within t)`, + REWRITE_TAC[has_derivative_within] THEN MESON_TAC[LIM_WITHIN_SUBSET]);; + +let DIFFERENTIABLE_WITHIN_SUBSET = prove + (`!f:real^M->real^N s t. + f differentiable (at x within t) /\ s SUBSET t + ==> f differentiable (at x within s)`, + REWRITE_TAC[differentiable] THEN MESON_TAC[HAS_DERIVATIVE_WITHIN_SUBSET]);; + +let DIFFERENTIABLE_ON_SUBSET = prove + (`!f:real^M->real^N s t. + f differentiable_on t /\ s SUBSET t ==> f differentiable_on s`, + REWRITE_TAC[differentiable_on] THEN + MESON_TAC[SUBSET; DIFFERENTIABLE_WITHIN_SUBSET]);; + +let DIFFERENTIABLE_ON_EMPTY = prove + (`!f. f differentiable_on {}`, + REWRITE_TAC[differentiable_on; NOT_IN_EMPTY]);; + +(* ------------------------------------------------------------------------- *) +(* Several results are easier using a "multiplied-out" variant. *) +(* (I got this idea from Dieudonne's proof of the chain rule). *) +(* ------------------------------------------------------------------------- *) + +let HAS_DERIVATIVE_WITHIN_ALT = prove + (`!f:real^M->real^N f' s x. + (f has_derivative f') (at x within s) <=> + linear f' /\ + !e. &0 < e + ==> ?d. &0 < d /\ + !y. y IN s /\ norm(y - x) < d + ==> norm(f(y) - f(x) - f'(y - x)) <= + e * norm(y - x)`, + REPEAT GEN_TAC THEN REWRITE_TAC[has_derivative_within; LIM_WITHIN] THEN + ASM_REWRITE_TAC[dist; VECTOR_SUB_RZERO] THEN + ASM_CASES_TAC `linear(f':real^M->real^N)` THEN + ASM_REWRITE_TAC[NORM_MUL; REAL_ABS_INV; REAL_ABS_NORM] THEN + GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [REAL_MUL_SYM] THEN + SIMP_TAC[GSYM real_div; REAL_LT_LDIV_EQ] THEN + REWRITE_TAC[VECTOR_ARITH `a - (b + c) = a - b - c :real^M`] THEN + EQ_TAC THEN DISCH_TAC THEN X_GEN_TAC `e:real` THEN DISCH_TAC THENL + [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` THEN STRIP_TAC THEN + ASM_REWRITE_TAC[] THEN X_GEN_TAC `y:real^M` THEN DISCH_TAC THEN + ASM_CASES_TAC `&0 < norm(y - x :real^M)` THENL + [ASM_SIMP_TAC[REAL_LT_IMP_LE]; ALL_TAC] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE RAND_CONV [NORM_POS_LT]) THEN + ASM_SIMP_TAC[VECTOR_SUB_EQ; VECTOR_SUB_REFL; NORM_0; REAL_MUL_RZERO; + VECTOR_ARITH `vec 0 - x = --x`; NORM_NEG] THEN + ASM_MESON_TAC[LINEAR_0; NORM_0; REAL_LE_REFL]; + FIRST_X_ASSUM(MP_TAC o SPEC `e / &2`) THEN + ASM_SIMP_TAC[REAL_LT_DIV; REAL_OF_NUM_LT; ARITH] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `d:real` THEN STRIP_TAC THEN + ASM_REWRITE_TAC[] THEN X_GEN_TAC `y:real^M` THEN STRIP_TAC THEN + MATCH_MP_TAC REAL_LET_TRANS THEN + EXISTS_TAC `e / &2 * norm(y - x :real^M)` THEN + ASM_SIMP_TAC[REAL_LT_RMUL_EQ; REAL_LT_LDIV_EQ; REAL_OF_NUM_LT; ARITH] THEN + UNDISCH_TAC `&0 < e` THEN REAL_ARITH_TAC]);; + +let HAS_DERIVATIVE_AT_ALT = prove + (`!f:real^M->real^N f' x. + (f has_derivative f') (at x) <=> + linear f' /\ + !e. &0 < e + ==> ?d. &0 < d /\ + !y. norm(y - x) < d + ==> norm(f(y) - f(x) - f'(y - x)) <= e * norm(y - x)`, + ONCE_REWRITE_TAC[GSYM WITHIN_UNIV] THEN + REWRITE_TAC[HAS_DERIVATIVE_WITHIN_ALT; IN_UNIV]);; + +(* ------------------------------------------------------------------------- *) +(* The chain rule. *) +(* ------------------------------------------------------------------------- *) + +let DIFF_CHAIN_WITHIN = prove + (`!f:real^M->real^N g:real^N->real^P f' g' x s. + (f has_derivative f') (at x within s) /\ + (g has_derivative g') (at (f x) within (IMAGE f s)) + ==> ((g o f) has_derivative (g' o f'))(at x within s)`, + REPEAT GEN_TAC THEN SIMP_TAC[HAS_DERIVATIVE_WITHIN_ALT; LINEAR_COMPOSE] THEN + DISCH_THEN(CONJUNCTS_THEN2 STRIP_ASSUME_TAC MP_TAC) THEN + FIRST_ASSUM(X_CHOOSE_TAC `B1:real` o MATCH_MP LINEAR_BOUNDED_POS) THEN + DISCH_THEN(fun th -> X_GEN_TAC `e:real` THEN DISCH_TAC THEN MP_TAC th) THEN + DISCH_THEN(CONJUNCTS_THEN2 + (fun th -> ASSUME_TAC th THEN X_CHOOSE_TAC `B2:real` (MATCH_MP + LINEAR_BOUNDED_POS th)) MP_TAC) THEN + FIRST_X_ASSUM(fun th -> MP_TAC th THEN MP_TAC(SPEC `e / &2 / B2` th)) THEN + ASM_SIMP_TAC[REAL_LT_DIV; REAL_OF_NUM_LT; ARITH] THEN + DISCH_THEN(X_CHOOSE_THEN `d1:real` STRIP_ASSUME_TAC) THEN DISCH_TAC THEN + DISCH_THEN(MP_TAC o SPEC `e / &2 / (&1 + B1)`) THEN + ASM_SIMP_TAC[REAL_LT_DIV; REAL_OF_NUM_LT; ARITH; REAL_LT_ADD] THEN + DISCH_THEN(X_CHOOSE_THEN `de:real` STRIP_ASSUME_TAC) THEN + FIRST_X_ASSUM(MP_TAC o SPEC `&1`) THEN + REWRITE_TAC[REAL_LT_01; REAL_MUL_LID] THEN + DISCH_THEN(X_CHOOSE_THEN `d2:real` STRIP_ASSUME_TAC) THEN + MP_TAC(SPECL [`d1:real`; `d2:real`] REAL_DOWN2) THEN + ASM_SIMP_TAC[REAL_LT_DIV; REAL_LT_ADD; REAL_LT_01] THEN + DISCH_THEN(X_CHOOSE_THEN `d0:real` STRIP_ASSUME_TAC) THEN + MP_TAC(SPECL [`d0:real`; `de / (B1 + &1)`] REAL_DOWN2) THEN + ASM_SIMP_TAC[REAL_LT_DIV; REAL_LT_ADD; REAL_LT_01] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `d:real` THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN X_GEN_TAC `y:real^M` THEN + DISCH_TAC THEN UNDISCH_TAC + `!y. y IN s /\ norm(y - x) < d2 + ==> norm ((f:real^M->real^N) y - f x - f'(y - x)) <= norm(y - x)` THEN + DISCH_THEN(MP_TAC o SPEC `y:real^M`) THEN ANTS_TAC THENL + [ASM_MESON_TAC[REAL_LT_TRANS]; DISCH_TAC] THEN + FIRST_X_ASSUM(MP_TAC o SPEC `y:real^M`) THEN ANTS_TAC THENL + [ASM_MESON_TAC[REAL_LT_TRANS]; DISCH_TAC] THEN + FIRST_X_ASSUM(MP_TAC o SPEC `(f:real^M->real^N) y`) THEN ANTS_TAC THENL + [CONJ_TAC THENL [ASM_MESON_TAC[IN_IMAGE]; ALL_TAC] THEN + MATCH_MP_TAC REAL_LET_TRANS THEN EXISTS_TAC + `norm(f'(y - x)) + norm((f:real^M->real^N) y - f x - f'(y - x))` THEN + REWRITE_TAC[NORM_TRIANGLE_SUB] THEN + MATCH_MP_TAC REAL_LET_TRANS THEN + EXISTS_TAC `B1 * norm(y - x) + norm(y - x :real^M)` THEN + ASM_SIMP_TAC[REAL_LE_ADD2] THEN + REWRITE_TAC[REAL_ARITH `a * x + x = x * (a + &1)`] THEN + ASM_SIMP_TAC[GSYM REAL_LT_RDIV_EQ; REAL_LT_ADD; REAL_LT_01] THEN + ASM_MESON_TAC[REAL_LT_TRANS]; + DISCH_TAC] THEN + REWRITE_TAC[o_THM] THEN MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `norm((g:real^N->real^P)(f(y:real^M)) - g(f x) - g'(f y - f x)) + + norm((g(f y) - g(f x) - g'(f'(y - x))) - + (g(f y) - g(f x) - g'(f y - f x)))` THEN + REWRITE_TAC[NORM_TRIANGLE_SUB] THEN + REWRITE_TAC[VECTOR_ARITH `(a - b - c1) - (a - b - c2) = c2 - c1:real^M`] THEN + ASM_SIMP_TAC[GSYM LINEAR_SUB] THEN + FIRST_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH + `a <= d ==> b <= ee - d ==> a + b <= ee`)) THEN + MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `B2 * norm((f:real^M->real^N) y - f x - f'(y - x))` THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `B2 * e / &2 / B2 * norm(y - x :real^M)` THEN + ASM_SIMP_TAC[REAL_LE_LMUL; REAL_LT_IMP_LE] THEN REWRITE_TAC[real_div] THEN + ONCE_REWRITE_TAC[REAL_ARITH + `b * ((e * h) * b') * x <= e * x - d <=> + d <= e * (&1 - h * b' * b) * x`] THEN + ASM_SIMP_TAC[REAL_MUL_LINV; REAL_LT_IMP_NZ] THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN REWRITE_TAC[GSYM REAL_MUL_ASSOC] THEN + ASM_SIMP_TAC[REAL_LE_LMUL_EQ; REAL_LT_DIV; REAL_OF_NUM_LT; ARITH] THEN + ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN REWRITE_TAC[GSYM real_div] THEN + ASM_SIMP_TAC[REAL_LE_LDIV_EQ; REAL_LT_ADD; REAL_LT_01] THEN + MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC + `norm(f'(y - x)) + norm((f:real^M->real^N) y - f x - f'(y - x))` THEN + REWRITE_TAC[NORM_TRIANGLE_SUB] THEN MATCH_MP_TAC(REAL_ARITH + `u <= x * b /\ v <= b ==> u + v <= b * (&1 + x)`) THEN + ASM_REWRITE_TAC[]);; + +let DIFF_CHAIN_AT = prove + (`!f:real^M->real^N g:real^N->real^P f' g' x. + (f has_derivative f') (at x) /\ + (g has_derivative g') (at (f x)) + ==> ((g o f) has_derivative (g' o f')) (at x)`, + ONCE_REWRITE_TAC[GSYM WITHIN_UNIV] THEN + ASM_MESON_TAC[DIFF_CHAIN_WITHIN; LIM_WITHIN_SUBSET; SUBSET_UNIV; + HAS_DERIVATIVE_WITHIN_SUBSET]);; + +(* ------------------------------------------------------------------------- *) +(* Composition rules stated just for differentiability. *) +(* ------------------------------------------------------------------------- *) + +let DIFFERENTIABLE_LINEAR = prove + (`!net f:real^M->real^N. linear f ==> f differentiable net`, + REWRITE_TAC[differentiable] THEN MESON_TAC[HAS_DERIVATIVE_LINEAR]);; + +let DIFFERENTIABLE_CONST = prove + (`!c net. (\z. c) differentiable net`, + REWRITE_TAC[differentiable] THEN MESON_TAC[HAS_DERIVATIVE_CONST]);; + +let DIFFERENTIABLE_ID = prove + (`!net. (\z. z) differentiable net`, + REWRITE_TAC[differentiable] THEN MESON_TAC[HAS_DERIVATIVE_ID]);; + +let DIFFERENTIABLE_LIFT_COMPONENT = prove + (`!net:(real^N)net. (\x. lift(x$i)) differentiable net`, + REWRITE_TAC[differentiable] THEN MESON_TAC[HAS_DERIVATIVE_LIFT_COMPONENT]);; + +let DIFFERENTIABLE_CMUL = prove + (`!net f c. f differentiable net ==> (\x. c % f(x)) differentiable net`, + REWRITE_TAC[differentiable] THEN MESON_TAC[HAS_DERIVATIVE_CMUL]);; + +let DIFFERENTIABLE_NEG = prove + (`!f net. f differentiable net ==> (\z. --(f z)) differentiable net`, + REWRITE_TAC[differentiable] THEN MESON_TAC[HAS_DERIVATIVE_NEG]);; + +let DIFFERENTIABLE_ADD = prove + (`!f g net. + f differentiable net /\ + g differentiable net + ==> (\z. f z + g z) differentiable net`, + REWRITE_TAC[differentiable] THEN MESON_TAC[HAS_DERIVATIVE_ADD]);; + +let DIFFERENTIABLE_SUB = prove + (`!f g net. + f differentiable net /\ + g differentiable net + ==> (\z. f z - g z) differentiable net`, + REWRITE_TAC[differentiable] THEN MESON_TAC[HAS_DERIVATIVE_SUB]);; + +let DIFFERENTIABLE_VSUM = prove + (`!f net s. + FINITE s /\ + (!a. a IN s ==> (f a) differentiable net) + ==> (\x. vsum s (\a. f a x)) differentiable net`, + REPEAT GEN_TAC THEN REWRITE_TAC[differentiable] THEN + GEN_REWRITE_TAC (LAND_CONV o TOP_DEPTH_CONV) + [RIGHT_IMP_EXISTS_THM; SKOLEM_THM; RIGHT_AND_EXISTS_THM] THEN + DISCH_THEN(CHOOSE_THEN (MP_TAC o MATCH_MP HAS_DERIVATIVE_VSUM)) THEN + MESON_TAC[]);; + +let DIFFERENTIABLE_VSUM_NUMSEG = prove + (`!f net m n. + FINITE s /\ + (!i. m <= i /\ i <= n ==> (f i) differentiable net) + ==> (\x. vsum (m..n) (\a. f a x)) differentiable net`, + SIMP_TAC[DIFFERENTIABLE_VSUM; FINITE_NUMSEG; IN_NUMSEG]);; + +let DIFFERENTIABLE_CHAIN_AT = prove + (`!f g x. + f differentiable (at x) /\ + g differentiable (at(f x)) + ==> (g o f) differentiable (at x)`, + REWRITE_TAC[differentiable] THEN MESON_TAC[DIFF_CHAIN_AT]);; + +let DIFFERENTIABLE_CHAIN_WITHIN = prove + (`!f g x s. + f differentiable (at x within s) /\ + g differentiable (at(f x) within IMAGE f s) + ==> (g o f) differentiable (at x within s)`, + REWRITE_TAC[differentiable] THEN MESON_TAC[DIFF_CHAIN_WITHIN]);; + +let DIFFERENTIABLE_COMPONENTWISE_WITHIN = prove + (`!f:real^M->real^N a s. + f differentiable (at a within s) <=> + !i. 1 <= i /\ i <= dimindex(:N) + ==> (\x. lift(f(x)$i)) differentiable (at a within s)`, + REPEAT GEN_TAC THEN REWRITE_TAC[differentiable] THEN + GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) + [HAS_DERIVATIVE_COMPONENTWISE_WITHIN] THEN + REWRITE_TAC[RIGHT_IMP_EXISTS_THM; SKOLEM_THM] THEN EQ_TAC THENL + [DISCH_THEN(X_CHOOSE_TAC `g':real^M->real^N`) THEN + EXISTS_TAC `\i x. lift((g':real^M->real^N) x$i)` THEN ASM_REWRITE_TAC[]; + DISCH_THEN(X_CHOOSE_TAC `g':num->real^M->real^1`) THEN + EXISTS_TAC `(\x. lambda i. drop((g':num->real^M->real^1) i x)) + :real^M->real^N` THEN + ASM_SIMP_TAC[LAMBDA_BETA; LIFT_DROP; ETA_AX]]);; + +let DIFFERENTIABLE_COMPONENTWISE_AT = prove + (`!f:real^M->real^N a. + f differentiable (at a) <=> + !i. 1 <= i /\ i <= dimindex(:N) + ==> (\x. lift(f(x)$i)) differentiable (at a)`, + ONCE_REWRITE_TAC[GSYM WITHIN_UNIV] THEN + MATCH_ACCEPT_TAC DIFFERENTIABLE_COMPONENTWISE_WITHIN);; + +(* ------------------------------------------------------------------------- *) +(* Similarly for "differentiable_on". *) +(* ------------------------------------------------------------------------- *) + +let DIFFERENTIABLE_ON_LINEAR = prove + (`!f:real^M->real^N s. linear f ==> f differentiable_on s`, + SIMP_TAC[differentiable_on; DIFFERENTIABLE_LINEAR]);; + +let DIFFERENTIABLE_ON_CONST = prove + (`!s c. (\z. c) differentiable_on s`, + REWRITE_TAC[differentiable_on; DIFFERENTIABLE_CONST]);; + +let DIFFERENTIABLE_ON_ID = prove + (`!s. (\z. z) differentiable_on s`, + REWRITE_TAC[differentiable_on; DIFFERENTIABLE_ID]);; + +let DIFFERENTIABLE_ON_COMPOSE = prove + (`!f g s. f differentiable_on s /\ g differentiable_on (IMAGE f s) + ==> (g o f) differentiable_on s`, + SIMP_TAC[differentiable_on; FORALL_IN_IMAGE] THEN + MESON_TAC[DIFFERENTIABLE_CHAIN_WITHIN]);; + +let DIFFERENTIABLE_ON_NEG = prove + (`!f s. f differentiable_on s ==> (\z. --(f z)) differentiable_on s`, + SIMP_TAC[differentiable_on; DIFFERENTIABLE_NEG]);; + +let DIFFERENTIABLE_ON_ADD = prove + (`!f g s. + f differentiable_on s /\ g differentiable_on s + ==> (\z. f z + g z) differentiable_on s`, + SIMP_TAC[differentiable_on; DIFFERENTIABLE_ADD]);; + +let DIFFERENTIABLE_ON_SUB = prove + (`!f g s. + f differentiable_on s /\ g differentiable_on s + ==> (\z. f z - g z) differentiable_on s`, + SIMP_TAC[differentiable_on; DIFFERENTIABLE_SUB]);; + +(* ------------------------------------------------------------------------- *) +(* Uniqueness of derivative. *) +(* *) +(* The general result is a bit messy because we need approachability of the *) +(* limit point from any direction. But OK for nontrivial intervals etc. *) +(* ------------------------------------------------------------------------- *) + +let FRECHET_DERIVATIVE_UNIQUE_WITHIN = prove + (`!f:real^M->real^N f' f'' x s. + (f has_derivative f') (at x within s) /\ + (f has_derivative f'') (at x within s) /\ + (!i e. 1 <= i /\ i <= dimindex(:M) /\ &0 < e + ==> ?d. &0 < abs(d) /\ abs(d) < e /\ (x + d % basis i) IN s) + ==> f' = f''`, + REPEAT GEN_TAC THEN REWRITE_TAC[has_derivative] THEN + ONCE_REWRITE_TAC[CONJ_ASSOC] THEN + DISCH_THEN(CONJUNCTS_THEN2 MP_TAC STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN `(x:real^M) limit_point_of s` ASSUME_TAC THENL + [REWRITE_TAC[LIMPT_APPROACHABLE] THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`1`; `e:real`]) THEN + ASM_REWRITE_TAC[DIMINDEX_GE_1; LE_REFL] THEN + DISCH_THEN(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `(x:real^M) + d % basis 1` THEN + ASM_REWRITE_TAC[dist] THEN ONCE_REWRITE_TAC[GSYM VECTOR_SUB_EQ] THEN + ASM_SIMP_TAC[VECTOR_ADD_SUB; NORM_MUL; NORM_BASIS; DIMINDEX_GE_1; LE_REFL; + VECTOR_MUL_EQ_0; REAL_MUL_RID; DE_MORGAN_THM; REAL_ABS_NZ; + BASIS_NONZERO]; + ALL_TAC] THEN + DISCH_THEN(CONJUNCTS_THEN (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + REWRITE_TAC[IMP_IMP] THEN DISCH_THEN(MP_TAC o MATCH_MP LIM_SUB) THEN + SUBGOAL_THEN `netlimit(at x within s) = x:real^M` SUBST_ALL_TAC THENL + [ASM_MESON_TAC[NETLIMIT_WITHIN; TRIVIAL_LIMIT_WITHIN]; ALL_TAC] THEN + REWRITE_TAC[GSYM VECTOR_SUB_LDISTRIB; NORM_MUL] THEN + REWRITE_TAC[VECTOR_ARITH + `fx - (fa + f'') - (fx - (fa + f')):real^M = f' - f''`] THEN + DISCH_TAC THEN MATCH_MP_TAC LINEAR_EQ_STDBASIS THEN ASM_REWRITE_TAC[] THEN + X_GEN_TAC `i:num` THEN STRIP_TAC THEN + ONCE_REWRITE_TAC[GSYM VECTOR_SUB_EQ] THEN + GEN_REWRITE_TAC I [TAUT `p = ~ ~p`] THEN + PURE_REWRITE_TAC[GSYM NORM_POS_LT] THEN DISCH_TAC THEN ABBREV_TAC + `e = norm((f':real^M->real^N) (basis i) - f''(basis i :real^M))` THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [LIM_WITHIN]) THEN + DISCH_THEN(MP_TAC o SPEC `e:real`) THEN + ASM_REWRITE_TAC[dist; VECTOR_SUB_RZERO] THEN + DISCH_THEN(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC) THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`i:num`; `d:real`]) THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `c:real` STRIP_ASSUME_TAC) THEN + FIRST_X_ASSUM(MP_TAC o SPEC `(x:real^M) + c % basis i`) THEN + ASM_REWRITE_TAC[VECTOR_ADD_SUB; NORM_MUL] THEN + ASM_SIMP_TAC[NORM_BASIS; REAL_MUL_RID] THEN + ASM_SIMP_TAC[LINEAR_CMUL; GSYM VECTOR_SUB_LDISTRIB; NORM_MUL] THEN + REWRITE_TAC[REAL_ABS_INV; REAL_ABS_ABS] THEN + ASM_SIMP_TAC[REAL_MUL_LINV; REAL_LT_IMP_NZ; REAL_MUL_ASSOC] THEN + REWRITE_TAC[REAL_MUL_LID; REAL_LT_REFL]);; + +let FRECHET_DERIVATIVE_UNIQUE_AT = prove + (`!f:real^M->real^N f' f'' x. + (f has_derivative f') (at x) /\ (f has_derivative f'') (at x) + ==> f' = f''`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC FRECHET_DERIVATIVE_UNIQUE_WITHIN THEN + MAP_EVERY EXISTS_TAC + [`f:real^M->real^N`; `x:real^M`; `(:real^M)`] THEN + ASM_REWRITE_TAC[IN_UNIV; WITHIN_UNIV] THEN + MESON_TAC[REAL_ARITH `&0 < e ==> &0 < abs(e / &2) /\ abs(e / &2) < e`]);; + +let HAS_FRECHET_DERIVATIVE_UNIQUE_AT = prove + (`!f:real^M->real^N f' x. + (f has_derivative f') (at x) + ==> frechet_derivative f (at x) = f'`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC FRECHET_DERIVATIVE_UNIQUE_AT THEN + MAP_EVERY EXISTS_TAC [`f:real^M->real^N`; `x:real^M`] THEN + ASM_REWRITE_TAC[frechet_derivative] THEN CONV_TAC SELECT_CONV THEN + ASM_MESON_TAC[]);; + +let FRECHET_DERIVATIVE_CONST_AT = prove + (`!c:real^N a:real^M. frechet_derivative (\x. c) (at a) = \h. vec 0`, + REPEAT GEN_TAC THEN MATCH_MP_TAC HAS_FRECHET_DERIVATIVE_UNIQUE_AT THEN + REWRITE_TAC[HAS_DERIVATIVE_CONST]);; + +let FRECHET_DERIVATIVE_UNIQUE_WITHIN_CLOSED_INTERVAL = prove + (`!f:real^M->real^N f' f'' x a b. + (!i. 1 <= i /\ i <= dimindex(:M) ==> a$i < b$i) /\ + x IN interval[a,b] /\ + (f has_derivative f') (at x within interval[a,b]) /\ + (f has_derivative f'') (at x within interval[a,b]) + ==> f' = f''`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC FRECHET_DERIVATIVE_UNIQUE_WITHIN THEN + MAP_EVERY EXISTS_TAC + [`f:real^M->real^N`; `x:real^M`; `interval[a:real^M,b]`] THEN + ASM_REWRITE_TAC[] THEN + MAP_EVERY X_GEN_TAC [`i:num`; `e:real`] THEN STRIP_TAC THEN + MATCH_MP_TAC(MESON[] `(?a. P a \/ P(--a)) ==> (?a:real. P a)`) THEN + EXISTS_TAC `(min ((b:real^M)$i - (a:real^M)$i) e) / &2` THEN + REWRITE_TAC[REAL_ABS_NEG; GSYM LEFT_OR_DISTRIB] THEN + REWRITE_TAC[CONJ_ASSOC] THEN CONJ_TAC THENL + [UNDISCH_TAC `&0 < e` THEN FIRST_X_ASSUM(MP_TAC o SPEC `i:num`) THEN + ASM_REWRITE_TAC[] THEN REAL_ARITH_TAC; + ALL_TAC] THEN + UNDISCH_TAC `(x:real^M) IN interval[a,b]` THEN REWRITE_TAC[IN_INTERVAL] THEN + DISCH_TAC THEN + ASM_SIMP_TAC[VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT; + BASIS_COMPONENT] THEN + SUBGOAL_THEN + `!P. (!j. 1 <= j /\ j <= dimindex(:M) ==> P j) <=> + P i /\ + (!j. 1 <= j /\ j <= dimindex(:M) /\ ~(j = i) ==> P j)` + (fun th -> ONCE_REWRITE_TAC[th]) + THENL [ASM_MESON_TAC[]; ALL_TAC] THEN + ASM_SIMP_TAC[REAL_MUL_RZERO; REAL_ADD_RID; REAL_MUL_RID] THEN + REPEAT(FIRST_X_ASSUM(MP_TAC o SPEC `i:num`)) THEN + UNDISCH_TAC `&0 < e` THEN ASM_REWRITE_TAC[] THEN REAL_ARITH_TAC);; + +let FRECHET_DERIVATIVE_UNIQUE_WITHIN_OPEN_INTERVAL = prove + (`!f:real^M->real^N f' f'' x a b. + x IN interval(a,b) /\ + (f has_derivative f') (at x within interval(a,b)) /\ + (f has_derivative f'') (at x within interval(a,b)) + ==> f' = f''`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC FRECHET_DERIVATIVE_UNIQUE_WITHIN THEN + MAP_EVERY EXISTS_TAC + [`f:real^M->real^N`; `x:real^M`; `interval(a:real^M,b)`] THEN + ASM_REWRITE_TAC[] THEN + MAP_EVERY X_GEN_TAC [`i:num`; `e:real`] THEN STRIP_TAC THEN + MATCH_MP_TAC(MESON[] `(?a. P a \/ P(--a)) ==> (?a:real. P a)`) THEN + EXISTS_TAC `(min ((b:real^M)$i - (a:real^M)$i) e) / &3` THEN + REWRITE_TAC[REAL_ABS_NEG; GSYM LEFT_OR_DISTRIB] THEN + REWRITE_TAC[CONJ_ASSOC] THEN CONJ_TAC THENL + [UNDISCH_TAC `&0 < e` THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_INTERVAL]) THEN + DISCH_THEN(MP_TAC o SPEC `i:num`) THEN + ASM_REWRITE_TAC[] THEN REAL_ARITH_TAC; + ALL_TAC] THEN + UNDISCH_TAC `(x:real^M) IN interval(a,b)` THEN REWRITE_TAC[IN_INTERVAL] THEN + DISCH_TAC THEN + ASM_SIMP_TAC[VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT; + BASIS_COMPONENT] THEN + SUBGOAL_THEN + `!P. (!j. 1 <= j /\ j <= dimindex(:M) ==> P j) <=> + P i /\ + (!j. 1 <= j /\ j <= dimindex(:M) /\ ~(j = i) ==> P j)` + (fun th -> ONCE_REWRITE_TAC[th]) + THENL [ASM_MESON_TAC[]; ALL_TAC] THEN + ASM_SIMP_TAC[REAL_MUL_RZERO; REAL_ADD_RID; REAL_MUL_RID] THEN + REPEAT(FIRST_X_ASSUM(MP_TAC o SPEC `i:num`)) THEN + UNDISCH_TAC `&0 < e` THEN ASM_REWRITE_TAC[] THEN REAL_ARITH_TAC);; + +let FRECHET_DERIVATIVE_AT = prove + (`!f:real^M->real^N f' x. + (f has_derivative f') (at x) ==> (f' = frechet_derivative f (at x))`, + MESON_TAC[has_derivative; FRECHET_DERIVATIVE_WORKS; + differentiable; FRECHET_DERIVATIVE_UNIQUE_AT]);; + +let FRECHET_DERIVATIVE_WITHIN_CLOSED_INTERVAL = prove + (`!f:real^M->real^N f' x a b. + (!i. 1 <= i /\ i <= dimindex(:M) ==> a$i < b$i) /\ + x IN interval[a,b] /\ + (f has_derivative f') (at x within interval[a,b]) + ==> frechet_derivative f (at x within interval[a,b]) = f'`, + ASM_MESON_TAC[has_derivative; FRECHET_DERIVATIVE_WORKS; + differentiable; FRECHET_DERIVATIVE_UNIQUE_WITHIN_CLOSED_INTERVAL]);; + +(* ------------------------------------------------------------------------- *) +(* Component of the differential must be zero if it exists at a local *) +(* maximum or minimum for that corresponding component. Start with slightly *) +(* sharper forms that fix the sign of the derivative on the boundary. *) +(* ------------------------------------------------------------------------- *) + +let DIFFERENTIAL_COMPONENT_POS_AT_MINIMUM = prove + (`!f:real^M->real^N f' x s k e. + 1 <= k /\ k <= dimindex(:N) /\ + x IN s /\ convex s /\ (f has_derivative f') (at x within s) /\ + &0 < e /\ (!w. w IN s INTER ball(x,e) ==> (f x)$k <= (f w)$k) + ==> !y. y IN s ==> &0 <= (f'(y - x))$k`, + REWRITE_TAC[has_derivative_within] THEN REPEAT STRIP_TAC THEN + ASM_CASES_TAC `y:real^M = x` THENL + [ASM_MESON_TAC[VECTOR_SUB_REFL; LINEAR_0; VEC_COMPONENT; REAL_LE_REFL]; + ALL_TAC] THEN + ONCE_REWRITE_TAC[GSYM REAL_NOT_LT] THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [LIM_WITHIN]) THEN + DISCH_THEN(MP_TAC o SPEC + `--((f':real^M->real^N)(y - x)$k) / norm(y - x)`) THEN + ASM_SIMP_TAC[REAL_LT_DIV; NORM_POS_LT; VECTOR_SUB_EQ; + NOT_EXISTS_THM; REAL_ARITH `&0 < --x <=> x < &0`] THEN + X_GEN_TAC `d:real` THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + ABBREV_TAC `de = min (&1) ((min d e) / &2 / norm(y - x:real^M))` THEN + DISCH_THEN(MP_TAC o SPEC `x + de % (y - x):real^M`) THEN + REWRITE_TAC[dist; VECTOR_ADD_SUB; NOT_IMP; GSYM CONJ_ASSOC] THEN + SUBGOAL_THEN `norm(de % (y - x):real^M) < min d e` MP_TAC THENL + [ASM_SIMP_TAC[NORM_MUL; GSYM REAL_LT_RDIV_EQ; + NORM_POS_LT; VECTOR_SUB_EQ] THEN + EXPAND_TAC "de" THEN MATCH_MP_TAC(REAL_ARITH + `&0 < de / x ==> abs(min (&1) (de / &2 / x)) < de / x`) THEN + ASM_SIMP_TAC[REAL_LT_DIV; REAL_LT_MIN; NORM_POS_LT; VECTOR_SUB_EQ]; + REWRITE_TAC[REAL_LT_MIN] THEN STRIP_TAC] THEN + SUBGOAL_THEN `&0 < de /\ de <= &1` STRIP_ASSUME_TAC THENL + [EXPAND_TAC "de" THEN CONJ_TAC THENL [ALL_TAC; REAL_ARITH_TAC] THEN + ASM_SIMP_TAC[REAL_LT_MIN; REAL_LT_01; REAL_HALF; REAL_LT_DIV; + NORM_POS_LT; VECTOR_SUB_EQ]; + ALL_TAC] THEN + MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN CONJ_TAC THENL + [REWRITE_TAC[VECTOR_ARITH + `x + a % (y - x):real^N = (&1 - a) % x + a % y`] THEN + MATCH_MP_TAC IN_CONVEX_SET THEN ASM_SIMP_TAC[REAL_LT_IMP_LE]; + DISCH_TAC] THEN + ASM_REWRITE_TAC[] THEN REWRITE_TAC[NORM_MUL] THEN + ASM_SIMP_TAC[REAL_LT_MUL; REAL_ARITH `&0 < x ==> &0 < abs x`; + NORM_POS_LT; VECTOR_SUB_EQ; VECTOR_SUB_RZERO] THEN + MATCH_MP_TAC(NORM_ARITH + `abs(y$k) <= norm(y) /\ ~(abs(y$k) < e) ==> ~(norm y < e)`) THEN + ASM_SIMP_TAC[COMPONENT_LE_NORM] THEN REWRITE_TAC[VECTOR_MUL_COMPONENT] THEN + REWRITE_TAC[REAL_ABS_INV; REAL_ABS_MUL; REAL_ABS_NORM; REAL_ABS_ABS] THEN + REWRITE_TAC[REAL_NOT_LT; REAL_INV_MUL; REAL_ARITH + `d <= (a * inv b) * c <=> d <= (c * a) / b`] THEN + ASM_SIMP_TAC[REAL_LE_DIV2_EQ; NORM_POS_LT; VECTOR_SUB_EQ] THEN + ASM_SIMP_TAC[GSYM real_div; REAL_LE_RDIV_EQ; VECTOR_SUB_COMPONENT; + VECTOR_ADD_COMPONENT; REAL_ARITH `&0 < x ==> &0 < abs x`] THEN + MATCH_MP_TAC(REAL_ARITH + `fx <= fy /\ a = --b /\ b < &0 ==> a <= abs(fy - (fx + b))`) THEN + FIRST_ASSUM(fun th -> REWRITE_TAC[MATCH_MP LINEAR_CMUL th]) THEN + ASM_SIMP_TAC[real_abs; VECTOR_MUL_COMPONENT; REAL_LT_IMP_LE] THEN + ONCE_REWRITE_TAC[REAL_ARITH `x * y < &0 <=> &0 < x * --y`] THEN + ASM_SIMP_TAC[REAL_LT_MUL_EQ] THEN + CONJ_TAC THENL [FIRST_X_ASSUM MATCH_MP_TAC; ASM_REAL_ARITH_TAC] THEN + ASM_REWRITE_TAC[IN_INTER; IN_BALL; NORM_ARITH + `dist(x:real^M,x + e) = norm e`]);; + +let DIFFERENTIAL_COMPONENT_NEG_AT_MAXIMUM = prove + (`!f:real^M->real^N f' x s k e. + 1 <= k /\ k <= dimindex(:N) /\ + x IN s /\ convex s /\ (f has_derivative f') (at x within s) /\ + &0 < e /\ (!w. w IN s INTER ball(x,e) ==> (f w)$k <= (f x)$k) + ==> !y. y IN s ==> (f'(y - x))$k <= &0`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL + [`\x. --((f:real^M->real^N) x)`; `\x. --((f':real^M->real^N) x)`; + `x:real^M`; `s:real^M->bool`; `k:num`; `e:real`] + DIFFERENTIAL_COMPONENT_POS_AT_MINIMUM) THEN + ASM_SIMP_TAC[HAS_DERIVATIVE_NEG] THEN + ASM_SIMP_TAC[REAL_LE_NEG2; VECTOR_NEG_COMPONENT; REAL_NEG_GE0]);; + +let DROP_DIFFERENTIAL_POS_AT_MINIMUM = prove + (`!f:real^N->real^1 f' x s e. + x IN s /\ convex s /\ (f has_derivative f') (at x within s) /\ + &0 < e /\ (!w. w IN s INTER ball(x,e) ==> drop(f x) <= drop(f w)) + ==> !y. y IN s ==> &0 <= drop(f'(y - x))`, + REPEAT GEN_TAC THEN REWRITE_TAC[drop] THEN STRIP_TAC THEN + MATCH_MP_TAC DIFFERENTIAL_COMPONENT_POS_AT_MINIMUM THEN + MAP_EVERY EXISTS_TAC [`f:real^N->real^1`; `e:real`] THEN + ASM_REWRITE_TAC[DIMINDEX_1; LE_REFL]);; + +let DROP_DIFFERENTIAL_NEG_AT_MAXIMUM = prove + (`!f:real^N->real^1 f' x s e. + x IN s /\ convex s /\ (f has_derivative f') (at x within s) /\ + &0 < e /\ (!w. w IN s INTER ball(x,e) ==> drop(f w) <= drop(f x)) + ==> !y. y IN s ==> drop(f'(y - x)) <= &0`, + REPEAT GEN_TAC THEN REWRITE_TAC[drop] THEN STRIP_TAC THEN + MATCH_MP_TAC DIFFERENTIAL_COMPONENT_NEG_AT_MAXIMUM THEN + MAP_EVERY EXISTS_TAC [`f:real^N->real^1`; `e:real`] THEN + ASM_REWRITE_TAC[DIMINDEX_1; LE_REFL]);; + +let DIFFERENTIAL_COMPONENT_ZERO_AT_MAXMIN = prove + (`!f:real^M->real^N f' x s k. + 1 <= k /\ k <= dimindex(:N) /\ + x IN s /\ open s /\ (f has_derivative f') (at x) /\ + ((!w. w IN s ==> (f w)$k <= (f x)$k) \/ + (!w. w IN s ==> (f x)$k <= (f w)$k)) + ==> !h. (f' h)$k = &0`, + REPEAT GEN_TAC THEN + DISCH_THEN(REPEAT_TCL CONJUNCTS_THEN ASSUME_TAC) THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [OPEN_CONTAINS_CBALL]) THEN + DISCH_THEN(MP_TAC o SPEC `x:real^M`) THEN ASM_REWRITE_TAC[SUBSET] THEN + DISCH_THEN(X_CHOOSE_THEN `e:real` STRIP_ASSUME_TAC) THEN + FIRST_X_ASSUM DISJ_CASES_TAC THENL + [MP_TAC(ISPECL [`f:real^M->real^N`; `f':real^M->real^N`; + `x:real^M`; `cball(x:real^M,e)`; `k:num`; `e:real`] + DIFFERENTIAL_COMPONENT_NEG_AT_MAXIMUM); + MP_TAC(ISPECL [`f:real^M->real^N`; `f':real^M->real^N`; + `x:real^M`; `cball(x:real^M,e)`; `k:num`; `e:real`] + DIFFERENTIAL_COMPONENT_POS_AT_MINIMUM)] THEN + ASM_SIMP_TAC[HAS_DERIVATIVE_AT_WITHIN; CENTRE_IN_CBALL; + CONVEX_CBALL; REAL_LT_IMP_LE; IN_INTER] THEN + DISCH_THEN(LABEL_TAC "*") THEN X_GEN_TAC `h:real^M` THEN + FIRST_X_ASSUM(STRIP_ASSUME_TAC o GEN_REWRITE_RULE I [has_derivative_at]) THEN + (ASM_CASES_TAC `h:real^M = vec 0` THENL + [ASM_MESON_TAC[LINEAR_0; VEC_COMPONENT]; ALL_TAC]) THEN + REMOVE_THEN "*" (fun th -> + MP_TAC(SPEC `x + e / norm h % h:real^M` th) THEN + MP_TAC(SPEC `x - e / norm h % h:real^M` th)) THEN + REWRITE_TAC[IN_CBALL; NORM_ARITH + `dist(x:real^N,x - e) = norm e /\ dist(x:real^N,x + e) = norm e`] THEN + REWRITE_TAC[NORM_MUL; REAL_ABS_DIV; REAL_ABS_NORM] THEN + ASM_SIMP_TAC[real_abs; REAL_DIV_RMUL; NORM_EQ_0; REAL_LT_IMP_LE; + REAL_LE_REFL] THEN + REWRITE_TAC[VECTOR_ARITH `x - e - x:real^N = --e /\ (x + e) - x = e`] THEN + FIRST_ASSUM(fun th -> REWRITE_TAC[MATCH_MP LINEAR_NEG th]) THEN + REWRITE_TAC[IMP_IMP; REAL_ARITH `&0 <= --x /\ &0 <= x <=> x = &0`; + VECTOR_NEG_COMPONENT; REAL_ARITH `--x <= &0 /\ x <= &0 <=> x = &0`] THEN + DISCH_THEN(MP_TAC o AP_TERM `(*) (norm(h:real^M) / e)`) THEN + REWRITE_TAC[GSYM VECTOR_MUL_COMPONENT] THEN + FIRST_ASSUM(fun th -> REWRITE_TAC[GSYM(MATCH_MP LINEAR_CMUL th)]) THEN + REWRITE_TAC[REAL_MUL_RZERO; VECTOR_MUL_ASSOC] THEN + ASM_SIMP_TAC[REAL_FIELD `~(x = &0) /\ ~(y = &0) ==> x / y * y / x = &1`; + NORM_EQ_0; REAL_LT_IMP_NZ; VECTOR_MUL_LID]);; + +let DIFFERENTIAL_ZERO_MAXMIN_COMPONENT = prove + (`!f:real^M->real^N x e k. + 1 <= k /\ k <= dimindex(:N) /\ &0 < e /\ + ((!y. y IN ball(x,e) ==> (f y)$k <= (f x)$k) \/ + (!y. y IN ball(x,e) ==> (f x)$k <= (f y)$k)) /\ + f differentiable (at x) + ==> (jacobian f (at x) $ k = vec 0)`, + REWRITE_TAC[JACOBIAN_WORKS] THEN REPEAT STRIP_TAC THEN + MP_TAC(ISPECL + [`f:real^M->real^N`; `\h. jacobian (f:real^M->real^N) (at x) ** h`; + `x:real^M`; `ball(x:real^M,e)`; `k:num`] + DIFFERENTIAL_COMPONENT_ZERO_AT_MAXMIN) THEN + ASM_REWRITE_TAC[CENTRE_IN_BALL; OPEN_BALL] THEN + ASM_SIMP_TAC[MATRIX_VECTOR_MUL_COMPONENT; FORALL_DOT_EQ_0]);; + +let DIFFERENTIAL_ZERO_MAXMIN = prove + (`!f:real^N->real^1 f' x s. + x IN s /\ open s /\ (f has_derivative f') (at x) /\ + ((!y. y IN s ==> drop(f y) <= drop(f x)) \/ + (!y. y IN s ==> drop(f x) <= drop(f y))) + ==> (f' = \v. vec 0)`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`f:real^N->real^1`; `f':real^N->real^1`; + `x:real^N`; `s:real^N->bool`; `1:num`] + DIFFERENTIAL_COMPONENT_ZERO_AT_MAXMIN) THEN + ASM_REWRITE_TAC[GSYM drop; DIMINDEX_1; LE_REFL] THEN + REWRITE_TAC[GSYM LIFT_EQ; LIFT_NUM; FUN_EQ_THM; LIFT_DROP]);; + +(* ------------------------------------------------------------------------- *) +(* The traditional Rolle theorem in one dimension. *) +(* ------------------------------------------------------------------------- *) + +let ROLLE = prove + (`!f:real^1->real^1 f' a b. + drop a < drop b /\ (f a = f b) /\ + f continuous_on interval[a,b] /\ + (!x. x IN interval(a,b) ==> (f has_derivative f'(x)) (at x)) + ==> ?x. x IN interval(a,b) /\ (f'(x) = \v. vec 0)`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`f:real^1->real^1`; `a:real^1`; `b:real^1`] + CONTINUOUS_IVT_LOCAL_EXTREMUM) THEN + ASM_SIMP_TAC[SEGMENT_1; REAL_LT_IMP_LE] THEN + ANTS_TAC THENL [ASM_MESON_TAC[REAL_LT_REFL]; MATCH_MP_TAC MONO_EXISTS] THEN + X_GEN_TAC `c:real^1` THEN DISCH_TAC THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC DIFFERENTIAL_ZERO_MAXMIN THEN MAP_EVERY EXISTS_TAC + [`f:real^1->real^1`; `c:real^1`; `interval(a:real^1,b)`] THEN + ASM_MESON_TAC[INTERVAL_OPEN_SUBSET_CLOSED; SUBSET; OPEN_INTERVAL]);; + +(* ------------------------------------------------------------------------- *) +(* One-dimensional mean value theorem. *) +(* ------------------------------------------------------------------------- *) + +let MVT = prove + (`!f:real^1->real^1 f' a b. + drop a < drop b /\ + f continuous_on interval[a,b] /\ + (!x. x IN interval(a,b) ==> (f has_derivative f'(x)) (at x)) + ==> ?x. x IN interval(a,b) /\ (f(b) - f(a) = f'(x) (b - a))`, + REPEAT STRIP_TAC THEN + MP_TAC(SPECL [`\x. f(x) - (drop(f b - f a) / drop(b - a)) % x`; + `\k:real^1 x:real^1. + f'(k)(x) - (drop(f b - f a) / drop(b - a)) % x`; + `a:real^1`; `b:real^1`] + ROLLE) THEN + REWRITE_TAC[] THEN ANTS_TAC THENL + [ASM_SIMP_TAC[CONTINUOUS_ON_SUB; CONTINUOUS_ON_CMUL; CONTINUOUS_ON_ID] THEN + CONJ_TAC THENL + [REWRITE_TAC[VECTOR_ARITH + `(fa - k % a = fb - k % b) <=> (fb - fa = k % (b - a))`]; + REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_DERIVATIVE_SUB THEN + ASM_SIMP_TAC[HAS_DERIVATIVE_CMUL; HAS_DERIVATIVE_ID; ETA_AX]]; + MATCH_MP_TAC MONO_EXISTS THEN SIMP_TAC[FUN_EQ_THM] THEN + X_GEN_TAC `x:real^1` THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC (MP_TAC o SPEC `b - a:real^1`))] THEN + SIMP_TAC[VECTOR_SUB_EQ; GSYM DROP_EQ; DROP_SUB; DROP_CMUL] THEN + ASM_SIMP_TAC[REAL_DIV_RMUL; REAL_SUB_LT; REAL_LT_IMP_NZ]);; + +let MVT_SIMPLE = prove + (`!f:real^1->real^1 f' a b. + drop a < drop b /\ + (!x. x IN interval[a,b] + ==> (f has_derivative f'(x)) (at x within interval[a,b])) + ==> ?x. x IN interval(a,b) /\ (f(b) - f(a) = f'(x) (b - a))`, + MP_TAC MVT THEN + REPEAT(MATCH_MP_TAC MONO_FORALL THEN GEN_TAC) THEN + REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[] THEN + CONJ_TAC THENL + [MATCH_MP_TAC DIFFERENTIABLE_IMP_CONTINUOUS_ON THEN + ASM_MESON_TAC[differentiable_on; differentiable]; + ASM_MESON_TAC[HAS_DERIVATIVE_WITHIN_OPEN; OPEN_INTERVAL; + HAS_DERIVATIVE_WITHIN_SUBSET; INTERVAL_OPEN_SUBSET_CLOSED; + SUBSET]]);; + +let MVT_VERY_SIMPLE = prove + (`!f:real^1->real^1 f' a b. + drop a <= drop b /\ + (!x. x IN interval[a,b] + ==> (f has_derivative f'(x)) (at x within interval[a,b])) + ==> ?x. x IN interval[a,b] /\ (f(b) - f(a) = f'(x) (b - a))`, + REPEAT GEN_TAC THEN ASM_CASES_TAC `b:real^1 = a` THENL + [ASM_REWRITE_TAC[VECTOR_SUB_REFL] THEN REPEAT STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `a:real^1`) THEN + REWRITE_TAC[INTERVAL_SING; IN_SING; has_derivative; UNWIND_THM2] THEN + MESON_TAC[LINEAR_0]; + ASM_REWRITE_TAC[REAL_LE_LT; DROP_EQ] THEN + DISCH_THEN(MP_TAC o MATCH_MP MVT_SIMPLE) THEN + MATCH_MP_TAC MONO_EXISTS THEN + SIMP_TAC[REWRITE_RULE[SUBSET] INTERVAL_OPEN_SUBSET_CLOSED]]);; + +(* ------------------------------------------------------------------------- *) +(* A nice generalization (see Havin's proof of 5.19 from Rudin's book). *) +(* ------------------------------------------------------------------------- *) + +let MVT_GENERAL = prove + (`!f:real^1->real^N f' a b. + drop a < drop b /\ + f continuous_on interval[a,b] /\ + (!x. x IN interval(a,b) ==> (f has_derivative f'(x)) (at x)) + ==> ?x. x IN interval(a,b) /\ + norm(f(b) - f(a)) <= norm(f'(x) (b - a))`, + REPEAT STRIP_TAC THEN + MP_TAC(SPECL [`(lift o (\y. (f(b) - f(a)) dot y)) o (f:real^1->real^N)`; + `\x t. lift((f(b:real^1) - f(a)) dot + ((f':real^1->real^1->real^N) x t))`; + `a:real^1`; `b:real^1`] MVT) THEN + ANTS_TAC THENL + [ASM_SIMP_TAC[CONTINUOUS_ON_LIFT_DOT; CONTINUOUS_ON_COMPOSE] THEN + REPEAT STRIP_TAC THEN REWRITE_TAC[o_DEF] THEN + MATCH_MP_TAC HAS_DERIVATIVE_LIFT_DOT THEN ASM_SIMP_TAC[ETA_AX]; + ALL_TAC] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `x:real^1` THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + ASM_REWRITE_TAC[o_THM; GSYM LIFT_SUB; GSYM DOT_RSUB; LIFT_EQ] THEN + DISCH_TAC THEN ASM_CASES_TAC `(f:real^1->real^N) b = f a` THENL + [ASM_REWRITE_TAC[VECTOR_SUB_REFL; NORM_0; NORM_POS_LE]; ALL_TAC] THEN + MATCH_MP_TAC REAL_LE_LCANCEL_IMP THEN + EXISTS_TAC `norm((f:real^1->real^N) b - f a)` THEN + ASM_REWRITE_TAC[NORM_POS_LT; VECTOR_SUB_EQ; GSYM REAL_POW_2] THEN + ASM_REWRITE_TAC[NORM_POW_2; NORM_CAUCHY_SCHWARZ]);; + +(* ------------------------------------------------------------------------- *) +(* Still more general bound theorem. *) +(* ------------------------------------------------------------------------- *) + +let DIFFERENTIABLE_BOUND = prove + (`!f:real^M->real^N f' s B. + convex s /\ + (!x. x IN s ==> (f has_derivative f'(x)) (at x within s)) /\ + (!x. x IN s ==> onorm(f'(x)) <= B) + ==> !x y. x IN s /\ y IN s ==> norm(f(x) - f(y)) <= B * norm(x - y)`, + ONCE_REWRITE_TAC[NORM_SUB] THEN REPEAT STRIP_TAC THEN + SUBGOAL_THEN + `!x y. x IN s ==> norm((f':real^M->real^M->real^N)(x) y) <= B * norm(y)` + ASSUME_TAC THENL + [ASM_MESON_TAC[ONORM; has_derivative; REAL_LE_TRANS; NORM_POS_LE; + REAL_LE_RMUL]; ALL_TAC] THEN + SUBGOAL_THEN + `!u. u IN interval[vec 0,vec 1] ==> (x + drop u % (y - x) :real^M) IN s` + ASSUME_TAC THENL + [REWRITE_TAC[IN_INTERVAL; FORALL_DIMINDEX_1; drop] THEN + SIMP_TAC[VEC_COMPONENT; LE_REFL; DIMINDEX_1] THEN + REWRITE_TAC[VECTOR_ARITH `x + u % (y - x) = (&1 - u) % x + u % y`] THEN + ASM_MESON_TAC[CONVEX_ALT]; + ALL_TAC] THEN + SUBGOAL_THEN + `!u. u IN interval(vec 0,vec 1) ==> (x + drop u % (y - x) :real^M) IN s` + ASSUME_TAC THENL + [ASM_MESON_TAC[SUBSET; INTERVAL_OPEN_SUBSET_CLOSED]; ALL_TAC] THEN + MP_TAC(SPECL + [`(f:real^M->real^N) o (\u. x + drop u % (y - x))`; + `\u. (f':real^M->real^M->real^N) (x + drop u % (y - x)) o + (\u. vec 0 + drop u % (y - x))`; + `vec 0:real^1`; `vec 1:real^1`] MVT_GENERAL) THEN + REWRITE_TAC[o_THM; DROP_VEC; VECTOR_ARITH `x + &1 % (y - x) = y`; + VECTOR_MUL_LZERO; VECTOR_SUB_RZERO; VECTOR_ADD_RID] THEN + REWRITE_TAC[VECTOR_MUL_LID] THEN ANTS_TAC THENL + [ALL_TAC; ASM_MESON_TAC[VECTOR_ADD_LID; REAL_LE_TRANS]] THEN + REWRITE_TAC[REAL_LT_01] THEN CONJ_TAC THENL + [MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN + SIMP_TAC[CONTINUOUS_ON_ADD; CONTINUOUS_ON_CONST; CONTINUOUS_ON_VMUL; + o_DEF; LIFT_DROP; CONTINUOUS_ON_ID] THEN + MATCH_MP_TAC CONTINUOUS_ON_SUBSET THEN EXISTS_TAC `s:real^M->bool` THEN + ASM_REWRITE_TAC[SUBSET; FORALL_IN_IMAGE] THEN + ASM_MESON_TAC[DIFFERENTIABLE_IMP_CONTINUOUS_WITHIN; differentiable; + CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN]; + ALL_TAC] THEN + X_GEN_TAC `a:real^1` THEN DISCH_TAC THEN + SUBGOAL_THEN `a IN interval(vec 0:real^1,vec 1) /\ + open(interval(vec 0:real^1,vec 1))` + MP_TAC THENL [ASM_MESON_TAC[OPEN_INTERVAL]; ALL_TAC] THEN + DISCH_THEN(fun th -> ONCE_REWRITE_TAC[GSYM(MATCH_MP + HAS_DERIVATIVE_WITHIN_OPEN th)]) THEN + MATCH_MP_TAC DIFF_CHAIN_WITHIN THEN + ASM_SIMP_TAC[HAS_DERIVATIVE_ADD; HAS_DERIVATIVE_CONST; + HAS_DERIVATIVE_VMUL_DROP; HAS_DERIVATIVE_ID] THEN + MATCH_MP_TAC HAS_DERIVATIVE_WITHIN_SUBSET THEN + EXISTS_TAC `s:real^M->bool` THEN + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE] THEN + ASM_MESON_TAC[INTERVAL_OPEN_SUBSET_CLOSED; SUBSET]);; + +(* ------------------------------------------------------------------------- *) +(* In particular. *) +(* ------------------------------------------------------------------------- *) + +let HAS_DERIVATIVE_ZERO_CONSTANT = prove + (`!f:real^M->real^N s. + convex s /\ + (!x. x IN s ==> (f has_derivative (\h. vec 0)) (at x within s)) + ==> ?c. !x. x IN s ==> f(x) = c`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`f:real^M->real^N`; `(\x h. vec 0):real^M->real^M->real^N`; + `s:real^M->bool`; `&0`] DIFFERENTIABLE_BOUND) THEN + ASM_REWRITE_TAC[REAL_MUL_LZERO; ONORM_CONST; NORM_0; REAL_LE_REFL] THEN + SIMP_TAC[NORM_LE_0; VECTOR_SUB_EQ] THEN MESON_TAC[]);; + +let HAS_DERIVATIVE_ZERO_UNIQUE = prove + (`!f s a c. convex s /\ a IN s /\ f a = c /\ + (!x. x IN s ==> (f has_derivative (\h. vec 0)) (at x within s)) + ==> !x. x IN s ==> f x = c`, + MESON_TAC[HAS_DERIVATIVE_ZERO_CONSTANT]);; + +let HAS_DERIVATIVE_ZERO_CONNECTED_CONSTANT = prove + (`!f:real^M->real^N s. + open s /\ connected s /\ + (!x. x IN s ==> (f has_derivative (\h. vec 0)) (at x)) + ==> ?c. !x. x IN s ==> f(x) = c`, + REPEAT STRIP_TAC THEN + ASM_CASES_TAC `s:real^M->bool = {}` THEN ASM_REWRITE_TAC[NOT_IN_EMPTY] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN + DISCH_THEN(X_CHOOSE_TAC `a:real^M`) THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [CONNECTED_CLOPEN]) THEN + DISCH_THEN(MP_TAC o SPEC `{x | x IN s /\ (f:real^M->real^N) x = f a}`) THEN + ANTS_TAC THENL [ALL_TAC; ASM SET_TAC[]] THEN CONJ_TAC THENL + [SIMP_TAC[open_in; SUBSET; IN_ELIM_THM] THEN + X_GEN_TAC `x:real^M` THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [OPEN_CONTAINS_BALL]) THEN + DISCH_THEN(MP_TAC o SPEC `x:real^M`) THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `e:real` THEN + REWRITE_TAC[SUBSET; IN_BALL] THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + MP_TAC(ISPECL [`f:real^M->real^N`; `ball(x:real^M,e)`] + HAS_DERIVATIVE_ZERO_CONSTANT) THEN + REWRITE_TAC[IN_BALL; CONVEX_BALL] THEN + ASM_MESON_TAC[HAS_DERIVATIVE_AT_WITHIN; DIST_SYM; DIST_REFL]; + MATCH_MP_TAC CONTINUOUS_CLOSED_IN_PREIMAGE_CONSTANT THEN + MATCH_MP_TAC DIFFERENTIABLE_IMP_CONTINUOUS_ON THEN + ASM_SIMP_TAC[DIFFERENTIABLE_ON_EQ_DIFFERENTIABLE_AT] THEN + ASM_MESON_TAC[differentiable]]);; + +let HAS_DERIVATIVE_ZERO_CONNECTED_UNIQUE = prove + (`!f s a c. open s /\ connected s /\ a IN s /\ f a = c /\ + (!x. x IN s ==> (f has_derivative (\h. vec 0)) (at x)) + ==> !x. x IN s ==> f x = c`, + MESON_TAC[HAS_DERIVATIVE_ZERO_CONNECTED_CONSTANT]);; + +(* ------------------------------------------------------------------------- *) +(* Differentiability of inverse function (most basic form). *) +(* ------------------------------------------------------------------------- *) + +let HAS_DERIVATIVE_INVERSE_BASIC = prove + (`!f:real^M->real^N g f' g' t y. + (f has_derivative f') (at (g y)) /\ linear g' /\ (g' o f' = I) /\ + g continuous (at y) /\ + open t /\ y IN t /\ (!z. z IN t ==> (f(g(z)) = z)) + ==> (g has_derivative g') (at y)`, + REWRITE_TAC[FUN_EQ_THM; o_THM; I_THM] THEN REPEAT STRIP_TAC THEN + FIRST_ASSUM(X_CHOOSE_TAC `C:real` o MATCH_MP LINEAR_BOUNDED_POS) THEN + SUBGOAL_THEN + `!e. &0 < e ==> ?d. &0 < d /\ + !z. norm(z - y) < d + ==> norm((g:real^N->real^M)(z) - g(y) - g'(z - y)) + <= e * norm(g(z) - g(y))` + ASSUME_TAC THENL + [X_GEN_TAC `e:real` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [HAS_DERIVATIVE_AT_ALT]) THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC (MP_TAC o SPEC `e / C`)) THEN + ASM_SIMP_TAC[REAL_LT_DIV] THEN + DISCH_THEN(X_CHOOSE_THEN `d0:real` + (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + DISCH_THEN(ASSUME_TAC o GEN `z:real^N` o SPEC `(g:real^N->real^M) z`) THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [continuous_at]) THEN + DISCH_THEN(MP_TAC o SPEC `d0:real`) THEN ASM_REWRITE_TAC[dist] THEN + DISCH_THEN(X_CHOOSE_THEN `d1:real` STRIP_ASSUME_TAC) THEN + FIRST_X_ASSUM(MP_TAC o SPEC `y:real^N` o + GEN_REWRITE_RULE I [open_def]) THEN + ASM_REWRITE_TAC[dist] THEN + DISCH_THEN(X_CHOOSE_THEN `d2:real` STRIP_ASSUME_TAC) THEN + MP_TAC(SPECL [`d1:real`; `d2:real`] REAL_DOWN2) THEN + ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `d:real` THEN STRIP_TAC THEN + ASM_REWRITE_TAC[] THEN + X_GEN_TAC `z:real^N` THEN DISCH_TAC THEN MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `C * (e / C) * norm((g:real^N->real^M) z - g y)` THEN + CONJ_TAC THENL + [ALL_TAC; + ASM_SIMP_TAC[REAL_MUL_ASSOC; REAL_LE_RMUL; REAL_DIV_LMUL; + REAL_EQ_IMP_LE; REAL_LT_IMP_NZ; NORM_POS_LE]] THEN + MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `C * norm(f((g:real^N->real^M) z) - y - f'(g z - g y))` THEN + CONJ_TAC THENL [ALL_TAC; ASM_MESON_TAC[REAL_LT_TRANS; REAL_LE_LMUL_EQ]] THEN + MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC + `norm(g'(f((g:real^N->real^M) z) - y - f'(g z - g y)):real^M)` THEN + ASM_REWRITE_TAC[] THEN ASM_SIMP_TAC[LINEAR_SUB] THEN + GEN_REWRITE_TAC LAND_CONV [GSYM NORM_NEG] THEN + REWRITE_TAC[VECTOR_ARITH + `--(gz:real^N - gy - (z - y)) = z - y - (gz - gy)`] THEN + ASM_MESON_TAC[REAL_LE_REFL; REAL_LT_TRANS]; + ALL_TAC] THEN + SUBGOAL_THEN + `?B d. &0 < B /\ &0 < d /\ + !z. norm(z - y) < d + ==> norm((g:real^N->real^M)(z) - g(y)) <= B * norm(z - y)` + STRIP_ASSUME_TAC THENL + [EXISTS_TAC `&2 * C` THEN + FIRST_X_ASSUM(MP_TAC o SPEC `&1 / &2`) THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `d:real` THEN + ASM_SIMP_TAC[REAL_LT_MUL; REAL_OF_NUM_LT; ARITH] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `z:real^N` THEN + MATCH_MP_TAC MONO_IMP THEN REWRITE_TAC[] THEN + MATCH_MP_TAC(REAL_ARITH + `norm(dg) <= norm(dg') + norm(dg - dg') /\ + ((&2 * (&1 - h)) * norm(dg) = &1 * norm(dg)) /\ + norm(dg') <= c * norm(d) + ==> norm(dg - dg') <= h * norm(dg) + ==> norm(dg) <= (&2 * c) * norm(d)`) THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN ASM_REWRITE_TAC[NORM_TRIANGLE_SUB]; + ALL_TAC] THEN + REWRITE_TAC[HAS_DERIVATIVE_AT_ALT] THEN ASM_REWRITE_TAC[] THEN + X_GEN_TAC `e:real` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `e / B`) THEN + ASM_SIMP_TAC[REAL_LT_DIV] THEN + DISCH_THEN(X_CHOOSE_THEN `d':real` STRIP_ASSUME_TAC) THEN + MP_TAC(SPECL [`d:real`; `d':real`] REAL_DOWN2) THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `k:real` THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN X_GEN_TAC `z:real^N` THEN + DISCH_TAC THEN MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `e / B * norm ((g:real^N->real^M) z - g y)` THEN + CONJ_TAC THENL [ASM_MESON_TAC[REAL_LT_TRANS]; ALL_TAC] THEN + ASM_SIMP_TAC[real_div; GSYM REAL_MUL_ASSOC; REAL_LE_LMUL_EQ] THEN + ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN + ASM_SIMP_TAC[GSYM real_div; REAL_LE_LDIV_EQ] THEN + ASM_MESON_TAC[REAL_MUL_SYM; REAL_LT_TRANS]);; + +(* ------------------------------------------------------------------------- *) +(* Simply rewrite that based on the domain point x. *) +(* ------------------------------------------------------------------------- *) + +let HAS_DERIVATIVE_INVERSE_BASIC_X = prove + (`!f:real^M->real^N g f' g' t x. + (f has_derivative f') (at x) /\ linear g' /\ (g' o f' = I) /\ + g continuous (at (f(x))) /\ (g(f(x)) = x) /\ + open t /\ f(x) IN t /\ (!y. y IN t ==> (f(g(y)) = y)) + ==> (g has_derivative g') (at (f(x)))`, + MESON_TAC[HAS_DERIVATIVE_INVERSE_BASIC]);; + +(* ------------------------------------------------------------------------- *) +(* This is the version in Dieudonne', assuming continuity of f and g. *) +(* ------------------------------------------------------------------------- *) + +let HAS_DERIVATIVE_INVERSE_DIEUDONNE = prove + (`!f:real^M->real^N g s. + open s /\ open (IMAGE f s) /\ + f continuous_on s /\ g continuous_on (IMAGE f s) /\ + (!x. x IN s ==> (g(f(x)) = x)) + ==> !f' g' x. x IN s /\ (f has_derivative f') (at x) /\ + linear g' /\ (g' o f' = I) + ==> (g has_derivative g') (at (f(x)))`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_DERIVATIVE_INVERSE_BASIC_X THEN + EXISTS_TAC `f':real^M->real^N` THEN + EXISTS_TAC `IMAGE (f:real^M->real^N) s` THEN + ASM_MESON_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_AT; IN_IMAGE]);; + +(* ------------------------------------------------------------------------- *) +(* Here's the simplest way of not assuming much about g. *) +(* ------------------------------------------------------------------------- *) + +let HAS_DERIVATIVE_INVERSE = prove + (`!f:real^M->real^N g f' g' s x. + compact s /\ x IN s /\ f(x) IN interior(IMAGE f s) /\ + f continuous_on s /\ (!x. x IN s ==> (g(f(x)) = x)) /\ + (f has_derivative f') (at x) /\ linear g' /\ (g' o f' = I) + ==> (g has_derivative g') (at (f(x)))`, + REPEAT STRIP_TAC THEN + MATCH_MP_TAC HAS_DERIVATIVE_INVERSE_BASIC_X THEN + EXISTS_TAC `f':real^M->real^N` THEN + EXISTS_TAC `interior(IMAGE (f:real^M->real^N) s)` THEN + ASM_MESON_TAC[CONTINUOUS_ON_INTERIOR; CONTINUOUS_ON_INVERSE; + OPEN_INTERIOR; IN_IMAGE; INTERIOR_SUBSET; SUBSET]);; + +(* ------------------------------------------------------------------------- *) +(* Proving surjectivity via Brouwer fixpoint theorem. *) +(* ------------------------------------------------------------------------- *) + +let BROUWER_SURJECTIVE = prove + (`!f:real^N->real^N s t. + compact t /\ convex t /\ ~(t = {}) /\ f continuous_on t /\ + (!x y. x IN s /\ y IN t ==> x + (y - f(y)) IN t) + ==> !x. x IN s ==> ?y. y IN t /\ (f(y) = x)`, + REPEAT STRIP_TAC THEN + ONCE_REWRITE_TAC[VECTOR_ARITH + `((f:real^N->real^N)(y) = x) <=> (x + (y - f(y)) = y)`] THEN + ASM_SIMP_TAC[CONTINUOUS_ON_ADD; CONTINUOUS_ON_CONST; CONTINUOUS_ON_SUB; + BROUWER; SUBSET; FORALL_IN_IMAGE; CONTINUOUS_ON_ID]);; + +let BROUWER_SURJECTIVE_CBALL = prove + (`!f:real^N->real^N s a e. + &0 < e /\ + f continuous_on cball(a,e) /\ + (!x y. x IN s /\ y IN cball(a,e) ==> x + (y - f(y)) IN cball(a,e)) + ==> !x. x IN s ==> ?y. y IN cball(a,e) /\ (f(y) = x)`, + REPEAT GEN_TAC THEN STRIP_TAC THEN MATCH_MP_TAC BROUWER_SURJECTIVE THEN + ASM_REWRITE_TAC[COMPACT_CBALL; CONVEX_CBALL] THEN + ASM_SIMP_TAC[CBALL_EQ_EMPTY; REAL_LT_IMP_LE; REAL_NOT_LT]);; + +(* ------------------------------------------------------------------------- *) +(* See Sussmann: "Multidifferential calculus", Theorem 2.1.1 *) +(* ------------------------------------------------------------------------- *) + +let SUSSMANN_OPEN_MAPPING = prove + (`!f:real^M->real^N f' g' s x. + open s /\ f continuous_on s /\ + x IN s /\ (f has_derivative f') (at x) /\ linear g' /\ (f' o g' = I) + ==> !t. t SUBSET s /\ x IN interior(t) + ==> f(x) IN interior(IMAGE f t)`, + REWRITE_TAC[HAS_DERIVATIVE_AT_ALT] THEN + REWRITE_TAC[FUN_EQ_THM; o_THM; I_THM] THEN REPEAT STRIP_TAC THEN + MP_TAC(MATCH_MP LINEAR_BOUNDED_POS (ASSUME `linear(g':real^N->real^M)`)) THEN + DISCH_THEN(X_CHOOSE_THEN `B:real` STRIP_ASSUME_TAC) THEN + FIRST_X_ASSUM(MP_TAC o SPEC `&1 / (&2 * B)`) THEN + ASM_SIMP_TAC[REAL_LT_MUL; REAL_LT_DIV; REAL_OF_NUM_LT; ARITH] THEN + DISCH_THEN(X_CHOOSE_THEN `e0:real` STRIP_ASSUME_TAC) THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_INTERIOR_CBALL]) THEN + DISCH_THEN(X_CHOOSE_THEN `e1:real` STRIP_ASSUME_TAC) THEN + MP_TAC(SPECL [`e0 / B`; `e1 / B`] REAL_DOWN2) THEN + ASM_SIMP_TAC[REAL_LT_DIV] THEN + DISCH_THEN(X_CHOOSE_THEN `e:real` STRIP_ASSUME_TAC) THEN + MP_TAC(ISPECL + [`\y. (f:real^M->real^N)(x + g'(y - f(x)))`; + `cball((f:real^M->real^N) x,e / &2)`; `(f:real^M->real^N) x`; `e:real`] + BROUWER_SURJECTIVE_CBALL) THEN + REWRITE_TAC[] THEN ANTS_TAC THENL + [ASM_REWRITE_TAC[] THEN CONJ_TAC THENL + [ONCE_REWRITE_TAC[GSYM o_DEF] THEN + MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN CONJ_TAC THENL + [MATCH_MP_TAC CONTINUOUS_ON_ADD THEN + REWRITE_TAC[CONTINUOUS_ON_CONST] THEN + ONCE_REWRITE_TAC[GSYM o_DEF] THEN + MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN + ASM_SIMP_TAC[CONTINUOUS_ON_SUB; CONTINUOUS_ON_CONST; + CONTINUOUS_ON_ID; LINEAR_CONTINUOUS_ON]; + ALL_TAC] THEN + MATCH_MP_TAC CONTINUOUS_ON_SUBSET THEN + EXISTS_TAC `cball(x:real^M,e1)` THEN CONJ_TAC THENL + [ASM_MESON_TAC[CONTINUOUS_ON_SUBSET; SUBSET_TRANS]; ALL_TAC] THEN + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE] THEN X_GEN_TAC `y:real^N` THEN + REWRITE_TAC[IN_CBALL; dist] THEN + REWRITE_TAC[VECTOR_ARITH `x - (x + y) = --y:real^N`] THEN + GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [NORM_SUB] THEN + DISCH_TAC THEN MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `B * norm(y - (f:real^M->real^N) x)` THEN + ASM_REWRITE_TAC[NORM_NEG] THEN ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN + ASM_SIMP_TAC[GSYM REAL_LE_RDIV_EQ] THEN + ASM_MESON_TAC[REAL_LE_TRANS; REAL_LT_IMP_LE]; + ALL_TAC] THEN + MAP_EVERY X_GEN_TAC [`y:real^N`; `z:real^N`] THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `x + g'(z - (f:real^M->real^N) x)`) THEN + ASM_REWRITE_TAC[VECTOR_ADD_SUB] THEN ANTS_TAC THENL + [MATCH_MP_TAC REAL_LET_TRANS THEN + EXISTS_TAC `B * norm(z - (f:real^M->real^N) x)` THEN + ASM_REWRITE_TAC[NORM_NEG] THEN ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN + ASM_SIMP_TAC[GSYM REAL_LT_RDIV_EQ] THEN + ASM_MESON_TAC[IN_CBALL; dist; NORM_SUB; REAL_LET_TRANS]; + ALL_TAC] THEN + REWRITE_TAC[VECTOR_ARITH `a - b - (c - b) = a - c:real^N`] THEN + DISCH_TAC THEN REWRITE_TAC[IN_CBALL; dist] THEN + ONCE_REWRITE_TAC[VECTOR_ARITH + `f0 - (y + z - f1) = (f1 - z) + (f0 - y):real^N`] THEN + MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC + `norm(f(x + g'(z - (f:real^M->real^N) x)) - z) + norm(f x - y)` THEN + REWRITE_TAC[NORM_TRIANGLE] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH + `x <= a ==> y <= b - a ==> x + y <= b`)) THEN + MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC `e / &2` THEN CONJ_TAC THENL + [ASM_MESON_TAC[IN_CBALL; dist]; ALL_TAC] THEN + REWRITE_TAC[REAL_ARITH `e / &2 <= e - x <=> x <= e / &2`] THEN + REWRITE_TAC[real_div; REAL_INV_MUL; REAL_MUL_ASSOC] THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN + SIMP_TAC[REAL_ARITH `(&1 / &2 * b) * x <= e * &1 / &2 <=> x * b <= e`] THEN + ASM_SIMP_TAC[GSYM real_div; REAL_LE_LDIV_EQ] THEN + MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `B * norm(z - (f:real^M->real^N) x)` THEN + ASM_REWRITE_TAC[] THEN + ASM_MESON_TAC[REAL_LE_LMUL_EQ; REAL_MUL_SYM; IN_CBALL; dist; DIST_SYM]; + ALL_TAC] THEN + REWRITE_TAC[IN_INTERIOR] THEN + DISCH_THEN(fun th -> EXISTS_TAC `e / &2` THEN MP_TAC th) THEN + ASM_SIMP_TAC[REAL_LT_DIV; REAL_OF_NUM_LT; ARITH; SUBSET] THEN + MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `y:real^N` THEN + MATCH_MP_TAC MONO_IMP THEN + REWRITE_TAC[REWRITE_RULE[SUBSET] BALL_SUBSET_CBALL] THEN + DISCH_THEN(X_CHOOSE_THEN `z:real^N` (STRIP_ASSUME_TAC o GSYM)) THEN + ASM_REWRITE_TAC[IN_IMAGE] THEN + EXISTS_TAC `x + g'(z - (f:real^M->real^N) x)` THEN REWRITE_TAC[] THEN + FIRST_ASSUM(MATCH_MP_TAC o REWRITE_RULE[SUBSET]) THEN + REWRITE_TAC[IN_CBALL; dist; VECTOR_ARITH `x - (x + y) = --y:real^N`] THEN + MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `B * norm(z - (f:real^M->real^N) x)` THEN + ASM_REWRITE_TAC[NORM_NEG] THEN + ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN + ASM_SIMP_TAC[GSYM REAL_LE_RDIV_EQ] THEN + ASM_MESON_TAC[IN_CBALL; dist; NORM_SUB; REAL_LT_IMP_LE; REAL_LE_TRANS]);; + +(* ------------------------------------------------------------------------- *) +(* Hence the following eccentric variant of the inverse function theorem. *) +(* This has no continuity assumptions, but we do need the inverse function. *) +(* We could put f' o g = I but this happens to fit with the minimal linear *) +(* algebra theory I've set up so far. *) +(* ------------------------------------------------------------------------- *) + +let HAS_DERIVATIVE_INVERSE_STRONG = prove + (`!f:real^N->real^N g f' g' s x. + open s /\ x IN s /\ f continuous_on s /\ + (!x. x IN s ==> (g(f(x)) = x)) /\ + (f has_derivative f') (at x) /\ (f' o g' = I) + ==> (g has_derivative g') (at (f(x)))`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_DERIVATIVE_INVERSE_BASIC_X THEN + SUBGOAL_THEN `linear (g':real^N->real^N) /\ (g' o f' = I)` + STRIP_ASSUME_TAC THENL + [ASM_MESON_TAC[has_derivative; RIGHT_INVERSE_LINEAR; LINEAR_INVERSE_LEFT]; + ALL_TAC] THEN + EXISTS_TAC `f':real^N->real^N` THEN + EXISTS_TAC `interior (IMAGE (f:real^N->real^N) s)` THEN + ASM_REWRITE_TAC[] THEN REPEAT CONJ_TAC THENL + [ALL_TAC; + ASM_SIMP_TAC[]; + REWRITE_TAC[OPEN_INTERIOR]; + ASM_MESON_TAC[INTERIOR_OPEN; SUSSMANN_OPEN_MAPPING; LINEAR_INVERSE_LEFT; + SUBSET_REFL; has_derivative]; + ASM_MESON_TAC[IN_IMAGE; SUBSET; INTERIOR_SUBSET]] THEN + REWRITE_TAC[continuous_at] THEN + X_GEN_TAC `e:real` THEN DISCH_TAC THEN + SUBGOAL_THEN + `!t. t SUBSET s /\ x IN interior(t) + ==> (f:real^N->real^N)(x) IN interior(IMAGE f t)` + MP_TAC THENL + [ASM_MESON_TAC[SUSSMANN_OPEN_MAPPING; LINEAR_INVERSE_LEFT; has_derivative]; + ALL_TAC] THEN + DISCH_THEN(MP_TAC o SPEC `ball(x:real^N,e) INTER s`) THEN ANTS_TAC THENL + [ASM_SIMP_TAC[IN_INTER; OPEN_BALL; INTERIOR_OPEN; OPEN_INTER; + INTER_SUBSET; CENTRE_IN_BALL]; + ALL_TAC] THEN + REWRITE_TAC[IN_INTERIOR] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `d:real` THEN + ASM_CASES_TAC `&0 < d` THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[SUBSET; IN_BALL; IN_IMAGE; IN_INTER] THEN + MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `y:real^N` THEN + REWRITE_TAC[DIST_SYM] THEN MATCH_MP_TAC MONO_IMP THEN + ASM_MESON_TAC[DIST_SYM]);; + +(* ------------------------------------------------------------------------- *) +(* A rewrite based on the other domain. *) +(* ------------------------------------------------------------------------- *) + +let HAS_DERIVATIVE_INVERSE_STRONG_X = prove + (`!f:real^N->real^N g f' g' s y. + open s /\ (g y) IN s /\ f continuous_on s /\ + (!x. x IN s ==> (g(f(x)) = x)) /\ + (f has_derivative f') (at (g y)) /\ (f' o g' = I) /\ + f(g y) = y + ==> (g has_derivative g') (at y)`, + REPEAT STRIP_TAC THEN + FIRST_ASSUM(fun th -> GEN_REWRITE_TAC (RAND_CONV o RAND_CONV) [SYM th]) THEN + MATCH_MP_TAC HAS_DERIVATIVE_INVERSE_STRONG THEN + MAP_EVERY EXISTS_TAC [`f':real^N->real^N`; `s:real^N->bool`] THEN + ASM_REWRITE_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* On a region. *) +(* ------------------------------------------------------------------------- *) + +let HAS_DERIVATIVE_INVERSE_ON = prove + (`!f:real^N->real^N s. + open s /\ + (!x. x IN s ==> (f has_derivative f'(x)) (at x) /\ (g(f(x)) = x) /\ + (f'(x) o g'(x) = I)) + ==> !x. x IN s ==> (g has_derivative g'(x)) (at (f(x)))`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_DERIVATIVE_INVERSE_STRONG THEN + EXISTS_TAC `(f':real^N->real^N->real^N) x` THEN + EXISTS_TAC `s:real^N->bool` THEN + ASM_MESON_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_AT; + DIFFERENTIABLE_IMP_CONTINUOUS_AT; differentiable]);; + +(* ------------------------------------------------------------------------- *) +(* Invertible derivative continous at a point implies local injectivity. *) +(* It's only for this we need continuity of the derivative, except of course *) +(* if we want the fact that the inverse derivative is also continuous. So if *) +(* we know for some other reason that the inverse function exists, it's OK. *) +(* ------------------------------------------------------------------------- *) + +let HAS_DERIVATIVE_LOCALLY_INJECTIVE = prove + (`!f:real^M->real^N f' g' s a. + a IN s /\ open s /\ linear g' /\ (g' o f'(a) = I) /\ + (!x. x IN s ==> (f has_derivative f'(x)) (at x)) /\ + (!e. &0 < e + ==> ?d. &0 < d /\ + !x. dist(a,x) < d ==> onorm(\v. f'(x) v - f'(a) v) < e) + ==> ?t. a IN t /\ open t /\ + !x x'. x IN t /\ x' IN t /\ (f x' = f x) ==> (x' = x)`, + REWRITE_TAC[FUN_EQ_THM; o_THM; I_THM] THEN REPEAT STRIP_TAC THEN + SUBGOAL_THEN `&0 < onorm(g':real^N->real^M)` ASSUME_TAC THENL + [ASM_SIMP_TAC[ONORM_POS_LT] THEN ASM_MESON_TAC[VEC_EQ; ARITH_EQ]; + ALL_TAC] THEN + ABBREV_TAC `k = &1 / onorm(g':real^N->real^M) / &2` THEN + SUBGOAL_THEN + `?d. &0 < d /\ ball(a,d) SUBSET s /\ + !x. x IN ball(a,d) + ==> onorm(\v. (f':real^M->real^M->real^N)(x) v - f'(a) v) < k` + STRIP_ASSUME_TAC THENL + [FIRST_X_ASSUM(MP_TAC o SPEC `k:real`) THEN EXPAND_TAC "k" THEN + ASM_SIMP_TAC[REAL_LT_DIV; REAL_OF_NUM_LT; ARITH] THEN + DISCH_THEN(X_CHOOSE_THEN `d1:real` STRIP_ASSUME_TAC) THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [OPEN_CONTAINS_BALL]) THEN + DISCH_THEN(MP_TAC o SPEC `a:real^M`) THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[SUBSET; IN_BALL] THEN DISCH_THEN(X_CHOOSE_TAC `d2:real`) THEN + EXISTS_TAC `min d1 d2` THEN ASM_REWRITE_TAC[REAL_LT_MIN; IN_BALL] THEN + ASM_MESON_TAC[REAL_LT_TRANS]; + ALL_TAC] THEN + EXISTS_TAC `ball(a:real^M,d)` THEN + ASM_SIMP_TAC[OPEN_BALL; CENTRE_IN_BALL] THEN + MAP_EVERY X_GEN_TAC [`x:real^M`; `x':real^M`] THEN STRIP_TAC THEN + ABBREV_TAC `ph = \w. w - g'(f(w) - (f:real^M->real^N)(x))` THEN + SUBGOAL_THEN `norm((ph:real^M->real^M) x' - ph x) <= norm(x' - x) / &2` + MP_TAC THENL + [ALL_TAC; + EXPAND_TAC "ph" THEN ASM_REWRITE_TAC[VECTOR_SUB_REFL] THEN + FIRST_ASSUM(fun th -> REWRITE_TAC[MATCH_MP LINEAR_0 th]) THEN + ONCE_REWRITE_TAC[GSYM VECTOR_SUB_EQ] THEN + REWRITE_TAC[VECTOR_SUB_RZERO; GSYM NORM_LE_0] THEN REAL_ARITH_TAC] THEN + SUBGOAL_THEN + `!u v:real^M. u IN ball(a,d) /\ v IN ball(a,d) + ==> norm(ph u - ph v :real^M) <= norm(u - v) / &2` + (fun th -> ASM_SIMP_TAC[th]) THEN + REWRITE_TAC[real_div] THEN ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN + MATCH_MP_TAC DIFFERENTIABLE_BOUND THEN + REWRITE_TAC[CONVEX_BALL; OPEN_BALL] THEN + EXISTS_TAC `\x v. v - g'((f':real^M->real^M->real^N) x v)` THEN + CONJ_TAC THEN X_GEN_TAC `u:real^M` THEN DISCH_TAC THEN REWRITE_TAC[] THENL + [EXPAND_TAC "ph" THEN + MATCH_MP_TAC HAS_DERIVATIVE_SUB THEN REWRITE_TAC[HAS_DERIVATIVE_ID] THEN + FIRST_ASSUM(fun th -> REWRITE_TAC[MATCH_MP LINEAR_SUB th]) THEN + GEN_REWRITE_TAC (RATOR_CONV o BINDER_CONV) [GSYM VECTOR_SUB_RZERO] THEN + MATCH_MP_TAC HAS_DERIVATIVE_SUB THEN REWRITE_TAC[HAS_DERIVATIVE_CONST] THEN + ONCE_REWRITE_TAC[GSYM o_DEF] THEN MATCH_MP_TAC DIFF_CHAIN_WITHIN THEN + ONCE_REWRITE_TAC[ETA_AX] THEN + ASM_MESON_TAC[HAS_DERIVATIVE_LINEAR; SUBSET; HAS_DERIVATIVE_AT_WITHIN]; + ALL_TAC] THEN + SUBGOAL_THEN + `(\w. w - g'((f':real^M->real^M->real^N) u w)) = + g' o (\w. f' a w - f' u w)` + SUBST1_TAC THENL + [REWRITE_TAC[FUN_EQ_THM; o_THM] THEN ASM_MESON_TAC[LINEAR_SUB]; + ALL_TAC] THEN + SUBGOAL_THEN `linear(\w. f' a w - (f':real^M->real^M->real^N) u w)` + ASSUME_TAC THENL + [MATCH_MP_TAC LINEAR_COMPOSE_SUB THEN ONCE_REWRITE_TAC[ETA_AX] THEN + ASM_MESON_TAC[has_derivative; SUBSET; CENTRE_IN_BALL]; + ALL_TAC] THEN + MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC + `onorm(g':real^N->real^M) * + onorm(\w. f' a w - (f':real^M->real^M->real^N) u w)` THEN + ASM_SIMP_TAC[ONORM_COMPOSE] THEN + ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN ASM_SIMP_TAC[GSYM REAL_LE_RDIV_EQ] THEN + REWRITE_TAC[real_div; REAL_ARITH `inv(&2) * x = (&1 * x) * inv(&2)`] THEN + ASM_REWRITE_TAC[GSYM real_div] THEN + SUBGOAL_THEN `onorm(\w. (f':real^M->real^M->real^N) a w - f' u w) = + onorm(\w. f' u w - f' a w)` + (fun th -> ASM_SIMP_TAC[th; REAL_LT_IMP_LE]) THEN + GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [GSYM VECTOR_NEG_SUB] THEN + MATCH_MP_TAC ONORM_NEG THEN ONCE_REWRITE_TAC[GSYM VECTOR_NEG_SUB] THEN + ASM_SIMP_TAC[LINEAR_COMPOSE_NEG]);; + +(* ------------------------------------------------------------------------- *) +(* Uniformly convergent sequence of derivatives. *) +(* ------------------------------------------------------------------------- *) + +let HAS_DERIVATIVE_SEQUENCE_LIPSCHITZ = prove + (`!s f:num->real^M->real^N f' g'. + convex s /\ + (!n x. x IN s ==> ((f n) has_derivative (f' n x)) (at x within s)) /\ + (!e. &0 < e + ==> ?N. !n x h. n >= N /\ x IN s + ==> norm(f' n x h - g' x h) <= e * norm(h)) + ==> !e. &0 < e + ==> ?N. !m n x y. m >= N /\ n >= N /\ x IN s /\ y IN s + ==> norm((f m x - f n x) - (f m y - f n y)) + <= e * norm(x - y)`, + REPEAT STRIP_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 `N:num` THEN DISCH_TAC THEN + MAP_EVERY X_GEN_TAC [`m:num`; `n:num`] THEN + ASM_CASES_TAC `m:num >= N` THEN ASM_REWRITE_TAC[] THEN + ASM_CASES_TAC `n:num >= N` THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC DIFFERENTIABLE_BOUND THEN + EXISTS_TAC `\x h. (f':num->real^M->real^M->real^N) m x h - f' n x h` THEN + ASM_SIMP_TAC[HAS_DERIVATIVE_SUB; ETA_AX] THEN + X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN + SUBGOAL_THEN + `!h. norm((f':num->real^M->real^M->real^N) m x h - f' n x h) <= e * norm(h)` + MP_TAC THEN RULE_ASSUM_TAC(REWRITE_RULE[HAS_DERIVATIVE_WITHIN_ALT]) THEN + ASM_SIMP_TAC[ONORM; LINEAR_COMPOSE_SUB; ETA_AX] THEN + X_GEN_TAC `h:real^M` THEN SUBST1_TAC(VECTOR_ARITH + `(f':num->real^M->real^M->real^N) m x h - f' n x h = + (f' m x h - g' x h) + --(f' n x h - g' x h)`) THEN + MATCH_MP_TAC NORM_TRIANGLE_LE THEN + ASM_SIMP_TAC[NORM_NEG; REAL_ARITH + `a <= e / &2 * h /\ b <= e / &2 * h ==> a + b <= e * h`]);; + +let HAS_DERIVATIVE_SEQUENCE = prove + (`!s f:num->real^M->real^N f' g'. + convex s /\ + (!n x. x IN s ==> ((f n) has_derivative (f' n x)) (at x within s)) /\ + (!e. &0 < e + ==> ?N. !n x h. n >= N /\ x IN s + ==> norm(f' n x h - g' x h) <= e * norm(h)) /\ + (?x l. x IN s /\ ((\n. f n x) --> l) sequentially) + ==> ?g. !x. x IN s + ==> ((\n. f n x) --> g x) sequentially /\ + (g has_derivative g'(x)) (at x within s)`, + REPEAT GEN_TAC THEN + REPLICATE_TAC 2 (DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + DISCH_THEN(CONJUNCTS_THEN2 (LABEL_TAC "O") MP_TAC) THEN + DISCH_THEN(X_CHOOSE_THEN `x0:real^M` STRIP_ASSUME_TAC) THEN + SUBGOAL_TAC "A" + `!e. &0 < e + ==> ?N. !m n x y. m >= N /\ n >= N /\ x IN s /\ y IN s + ==> norm(((f:num->real^M->real^N) m x - f n x) - + (f m y - f n y)) + <= e * norm(x - y)` + [MATCH_MP_TAC HAS_DERIVATIVE_SEQUENCE_LIPSCHITZ THEN + ASM_REWRITE_TAC[] THEN ASM_MESON_TAC[]] THEN + SUBGOAL_THEN + `?g:real^M->real^N. !x. x IN s ==> ((\n. f n x) --> g x) sequentially` + MP_TAC THENL + [REWRITE_TAC[GSYM SKOLEM_THM; RIGHT_EXISTS_IMP_THM] THEN + X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN + GEN_REWRITE_TAC I [CONVERGENT_EQ_CAUCHY] THEN + FIRST_X_ASSUM(MP_TAC o MATCH_MP CONVERGENT_IMP_CAUCHY) THEN + REWRITE_TAC[cauchy; dist] THEN DISCH_THEN(LABEL_TAC "B") THEN + X_GEN_TAC `e:real` THEN DISCH_TAC THEN + ASM_CASES_TAC `x:real^M = x0` THEN ASM_SIMP_TAC[] THEN + REMOVE_THEN "B" (MP_TAC o SPEC `e / &2`) THEN + ASM_REWRITE_TAC[REAL_HALF] THEN + DISCH_THEN(X_CHOOSE_THEN `N1:num` STRIP_ASSUME_TAC) THEN + REMOVE_THEN "A" (MP_TAC o SPEC `e / &2 / norm(x - x0:real^M)`) THEN + ASM_SIMP_TAC[REAL_LT_DIV; NORM_POS_LT; REAL_HALF; VECTOR_SUB_EQ] THEN + DISCH_THEN(X_CHOOSE_TAC `N2:num`) THEN + EXISTS_TAC `N1 + N2:num` THEN REPEAT GEN_TAC THEN + DISCH_THEN(CONJUNCTS_THEN (STRIP_ASSUME_TAC o MATCH_MP + (ARITH_RULE `m >= N1 + N2:num ==> m >= N1 /\ m >= N2`))) THEN + SUBST1_TAC(VECTOR_ARITH + `(f:num->real^M->real^N) m x - f n x = + (f m x - f n x - (f m x0 - f n x0)) + (f m x0 - f n x0)`) THEN + MATCH_MP_TAC NORM_TRIANGLE_LT THEN + FIRST_X_ASSUM(MP_TAC o SPECL + [`m:num`; `n:num`; `x:real^M`; `x0:real^M`]) THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`m:num`; `n:num`]) THEN + ASM_SIMP_TAC[REAL_DIV_RMUL; NORM_EQ_0; VECTOR_SUB_EQ] THEN REAL_ARITH_TAC; + ALL_TAC] THEN + MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC THEN SIMP_TAC[] THEN + DISCH_THEN(LABEL_TAC "B") THEN X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN + REWRITE_TAC[HAS_DERIVATIVE_WITHIN_ALT] THEN + SUBGOAL_TAC "C" + `!e. &0 < e + ==> ?N. !n x y. n >= N /\ x IN s /\ y IN s + ==> norm(((f:num->real^M->real^N) n x - f n y) - + (g x - g y)) + <= e * norm(x - y)` + [X_GEN_TAC `e:real` THEN DISCH_TAC THEN + REMOVE_THEN "A" (MP_TAC o SPEC `e:real`) THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `N:num` THEN + MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `n:num` THEN + DISCH_TAC THEN MAP_EVERY X_GEN_TAC [`u:real^M`; `v:real^M`] THEN + STRIP_TAC THEN FIRST_X_ASSUM(MP_TAC o GEN `m:num` o SPECL + [`m:num`; `u:real^M`; `v:real^M`]) THEN + DISCH_TAC THEN MATCH_MP_TAC(ISPEC `sequentially` LIM_NORM_UBOUND) THEN + EXISTS_TAC + `\m. ((f:num->real^M->real^N) n u - f n v) - (f m u - f m v)` THEN + REWRITE_TAC[eventually; TRIVIAL_LIMIT_SEQUENTIALLY] THEN + ASM_SIMP_TAC[SEQUENTIALLY; LIM_SUB; LIM_CONST] THEN EXISTS_TAC `N:num` THEN + ONCE_REWRITE_TAC[VECTOR_ARITH + `(x - y) - (u - v) = (x - u) - (y - v):real^N`] THEN + ASM_MESON_TAC[GE_REFL]] THEN + CONJ_TAC THENL + [SUBGOAL_TAC "D" + `!u. ((\n. (f':num->real^M->real^M->real^N) n x u) --> g' x u) sequentially` + [REWRITE_TAC[LIM_SEQUENTIALLY; dist] THEN REPEAT STRIP_TAC THEN + ASM_CASES_TAC `u = vec 0:real^M` THENL + [REMOVE_THEN "O" (MP_TAC o SPEC `e:real`); + REMOVE_THEN "O" (MP_TAC o SPEC `e / &2 / norm(u:real^M)`)] THEN + ASM_SIMP_TAC[NORM_POS_LT; 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 + DISCH_THEN(MP_TAC o SPECL [`x:real^M`; `u:real^M`]) THEN + DISCH_THEN(fun th -> DISCH_TAC THEN MP_TAC th) THEN + ASM_SIMP_TAC[GE; NORM_0; REAL_MUL_RZERO; NORM_LE_0] THEN + ASM_SIMP_TAC[REAL_DIV_RMUL; NORM_EQ_0] THEN + UNDISCH_TAC `&0 < e` THEN REAL_ARITH_TAC] THEN + REWRITE_TAC[linear] THEN ONCE_REWRITE_TAC[GSYM VECTOR_SUB_EQ] THEN + CONJ_TAC THENL + [MAP_EVERY X_GEN_TAC [`u:real^M`; `v:real^M`]; + MAP_EVERY X_GEN_TAC [`c:real`; `u:real^M`]] THEN + MATCH_MP_TAC(ISPEC `sequentially` LIM_UNIQUE) THENL + [EXISTS_TAC + `\n. (f':num->real^M->real^M->real^N) n x (u + v) - + (f' n x u + f' n x v)`; + EXISTS_TAC + `\n. (f':num->real^M->real^M->real^N) n x (c % u) - + c % f' n x u`] THEN + ASM_SIMP_TAC[TRIVIAL_LIMIT_SEQUENTIALLY; LIM_SUB; LIM_ADD; LIM_CMUL] THEN + RULE_ASSUM_TAC(REWRITE_RULE[has_derivative_within; linear]) THEN + ASM_SIMP_TAC[VECTOR_SUB_REFL; LIM_CONST]; + ALL_TAC] THEN + X_GEN_TAC `e:real` THEN DISCH_TAC THEN + MAP_EVERY (fun s -> REMOVE_THEN s (MP_TAC o SPEC `e / &3`)) ["C"; "O"] THEN + ASM_SIMP_TAC[REAL_LT_DIV; REAL_OF_NUM_LT; ARITH] THEN + DISCH_THEN(X_CHOOSE_THEN `N1:num` (LABEL_TAC "C")) THEN + DISCH_THEN(X_CHOOSE_THEN `N2:num` (LABEL_TAC "A")) THEN + REMOVE_THEN "C" (MP_TAC o GEN `y:real^M` o + SPECL [`N1 + N2:num`; `x:real^M`; `y - x:real^M`]) THEN + REMOVE_THEN "A" (MP_TAC o GEN `y:real^M` o + SPECL [`N1 + N2:num`; `y:real^M`; `x:real^M`]) THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`N1 + N2:num`; `x:real^M`]) THEN + ASM_REWRITE_TAC[ARITH_RULE `m + n >= m:num /\ m + n >= n`] THEN + REWRITE_TAC[HAS_DERIVATIVE_WITHIN_ALT] THEN + DISCH_THEN(MP_TAC o SPEC `e / &3` o CONJUNCT2) THEN + ASM_SIMP_TAC[REAL_LT_DIV; REAL_OF_NUM_LT; ARITH] THEN + DISCH_THEN(X_CHOOSE_THEN `d1:real` STRIP_ASSUME_TAC) THEN + DISCH_THEN(LABEL_TAC "D1") THEN DISCH_THEN(LABEL_TAC "D2") THEN + EXISTS_TAC `d1:real` THEN ASM_REWRITE_TAC[] THEN X_GEN_TAC `y:real^M` THEN + DISCH_TAC THEN REMOVE_THEN "D2" (MP_TAC o SPEC `y:real^M`) THEN + REMOVE_THEN "D1" (MP_TAC o SPEC `y:real^M`) THEN ANTS_TAC THENL + [ASM_MESON_TAC[REAL_LT_TRANS; NORM_SUB]; ALL_TAC] THEN + FIRST_X_ASSUM(MP_TAC o SPEC `y:real^M`) THEN ANTS_TAC THENL + [ASM_MESON_TAC[REAL_LT_TRANS; NORM_SUB]; ALL_TAC] THEN + MATCH_MP_TAC(REAL_ARITH + `d <= a + b + c + ==> a <= e / &3 * n ==> b <= e / &3 * n ==> c <= e / &3 * n + ==> d <= e * n`) THEN + GEN_REWRITE_TAC (funpow 2 RAND_CONV o LAND_CONV) [NORM_SUB] THEN + MATCH_MP_TAC(REAL_ARITH + `(norm(x + y + z) = norm(a)) /\ + norm(x + y + z) <= norm(x) + norm(y + z) /\ + norm(y + z) <= norm(y) + norm(z) + ==> norm(a) <= norm(x) + norm(y) + norm(z)`) THEN + REWRITE_TAC[NORM_TRIANGLE] THEN AP_TERM_TAC THEN VECTOR_ARITH_TAC);; + +(* ------------------------------------------------------------------------- *) +(* Can choose to line up antiderivatives if we want. *) +(* ------------------------------------------------------------------------- *) + +let HAS_ANTIDERIVATIVE_SEQUENCE = prove + (`!s f:num->real^M->real^N f' g'. + convex s /\ + (!n x. x IN s ==> ((f n) has_derivative (f' n x)) (at x within s)) /\ + (!e. &0 < e + ==> ?N. !n x h. n >= N /\ x IN s + ==> norm(f' n x h - g' x h) <= e * norm(h)) + ==> ?g. !x. x IN s ==> (g has_derivative g'(x)) (at x within s)`, + REPEAT STRIP_TAC THEN ASM_CASES_TAC `(s:real^M->bool) = {}` THEN + ASM_REWRITE_TAC[NOT_IN_EMPTY] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN + DISCH_THEN(X_CHOOSE_TAC `a:real^M`) THEN + MP_TAC(ISPECL + [`s:real^M->bool`; + `\n x. (f:num->real^M->real^N) n x + (f 0 a - f n a)`; + `f':num->real^M->real^M->real^N`; + `g':real^M->real^M->real^N`] + HAS_DERIVATIVE_SEQUENCE) THEN + ASM_REWRITE_TAC[] THEN ANTS_TAC THENL [ALL_TAC; MESON_TAC[]] THEN + CONJ_TAC THENL + [REPEAT STRIP_TAC THEN + SUBGOAL_THEN `(f':num->real^M->real^M->real^N) n x = + \h. f' n x h + vec 0` + SUBST1_TAC THENL [SIMP_TAC[FUN_EQ_THM] THEN VECTOR_ARITH_TAC; ALL_TAC] THEN + MATCH_MP_TAC HAS_DERIVATIVE_ADD THEN + ASM_SIMP_TAC[HAS_DERIVATIVE_CONST; ETA_AX]; + MAP_EVERY EXISTS_TAC [`a:real^M`; `f 0 (a:real^M) :real^N`] THEN + ASM_REWRITE_TAC[VECTOR_ARITH `a + b - a = b:real^N`; LIM_CONST]]);; + +let HAS_ANTIDERIVATIVE_LIMIT = prove + (`!s g':real^M->real^M->real^N. + convex s /\ + (!e. &0 < e + ==> ?f f'. !x. x IN s + ==> (f has_derivative (f' x)) (at x within s) /\ + (!h. norm(f' x h - g' x h) <= e * norm(h))) + ==> ?g. !x. x IN s ==> (g has_derivative g'(x)) (at x within s)`, + REPEAT STRIP_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] THEN DISCH_TAC THEN + MATCH_MP_TAC HAS_ANTIDERIVATIVE_SEQUENCE THEN + UNDISCH_TAC `convex(s:real^M->bool)` THEN SIMP_TAC[] THEN + DISCH_THEN(K ALL_TAC) THEN POP_ASSUM MP_TAC THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `f:num->real^M->real^N` THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `f':num->real^M->real^M->real^N` THEN + REPEAT STRIP_TAC THEN ASM_SIMP_TAC[] THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [REAL_ARCH_INV]) THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `N:num` THEN STRIP_TAC THEN + X_GEN_TAC `n:num` THEN REWRITE_TAC[GE] THEN + MAP_EVERY X_GEN_TAC [`x:real^M`; `h:real^M`] THEN STRIP_TAC THEN + MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `inv(&n + &1) * norm(h:real^M)` THEN + ASM_SIMP_TAC[] THEN MATCH_MP_TAC REAL_LE_RMUL THEN + REWRITE_TAC[NORM_POS_LE] THEN MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `inv(&N)` THEN ASM_SIMP_TAC[REAL_LT_IMP_LE] 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);; + +(* ------------------------------------------------------------------------- *) +(* Differentiation of a series. *) +(* ------------------------------------------------------------------------- *) + +let HAS_DERIVATIVE_SERIES = prove + (`!s f:num->real^M->real^N f' g' k. + convex s /\ + (!n x. x IN s ==> ((f n) has_derivative (f' n x)) (at x within s)) /\ + (!e. &0 < e + ==> ?N. !n x h. n >= N /\ x IN s + ==> norm(vsum(k INTER (0..n)) (\i. f' i x h) - + g' x h) <= e * norm(h)) /\ + (?x l. x IN s /\ ((\n. f n x) sums l) k) + ==> ?g. !x. x IN s ==> ((\n. f n x) sums (g x)) k /\ + (g has_derivative g'(x)) (at x within s)`, + REPEAT GEN_TAC THEN REWRITE_TAC[sums] THEN + DISCH_THEN(REPEAT_TCL CONJUNCTS_THEN ASSUME_TAC) THEN + MATCH_MP_TAC HAS_DERIVATIVE_SEQUENCE THEN EXISTS_TAC + `\n:num x:real^M h:real^M. vsum(k INTER (0..n)) (\n. f' n x h):real^N` THEN + ASM_SIMP_TAC[ETA_AX; FINITE_INTER_NUMSEG; HAS_DERIVATIVE_VSUM]);; + +(* ------------------------------------------------------------------------- *) +(* Derivative with composed bilinear function. *) +(* ------------------------------------------------------------------------- *) + +let HAS_DERIVATIVE_BILINEAR_WITHIN = prove + (`!h:real^M->real^N->real^P f g f' g' x:real^Q s. + (f has_derivative f') (at x within s) /\ + (g has_derivative g') (at x within s) /\ + bilinear h + ==> ((\x. h (f x) (g x)) has_derivative + (\d. h (f x) (g' d) + h (f' d) (g x))) (at x within s)`, + REPEAT STRIP_TAC THEN + SUBGOAL_TAC "contg" `((g:real^Q->real^N) --> g(x)) (at x within s)` + [REWRITE_TAC[GSYM CONTINUOUS_WITHIN] THEN + ASM_MESON_TAC[differentiable; DIFFERENTIABLE_IMP_CONTINUOUS_WITHIN]] THEN + UNDISCH_TAC `((f:real^Q->real^M) has_derivative f') (at x within s)` THEN + REWRITE_TAC[has_derivative_within] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC (LABEL_TAC "df")) THEN + SUBGOAL_TAC "contf" + `((\y. (f:real^Q->real^M)(x) + f'(y - x)) --> f(x)) (at x within s)` + [GEN_REWRITE_TAC LAND_CONV [GSYM VECTOR_ADD_RID] THEN + MATCH_MP_TAC LIM_ADD THEN REWRITE_TAC[LIM_CONST] THEN + SUBGOAL_THEN `vec 0 = (f':real^Q->real^M)(x - x)` SUBST1_TAC THENL + [ASM_MESON_TAC[LINEAR_0; VECTOR_SUB_REFL]; ALL_TAC] THEN + ASM_SIMP_TAC[LIM_LINEAR; LIM_SUB; LIM_CONST; LIM_WITHIN_ID]] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [has_derivative_within]) THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC (LABEL_TAC "dg")) THEN + CONJ_TAC THENL + [FIRST_ASSUM(STRIP_ASSUME_TAC o GEN_REWRITE_RULE I [bilinear]) THEN + RULE_ASSUM_TAC(REWRITE_RULE[linear]) THEN ASM_REWRITE_TAC[linear] THEN + REPEAT STRIP_TAC THEN VECTOR_ARITH_TAC; + ALL_TAC] THEN + MP_TAC(ISPECL [`at (x:real^Q) within s`; `h:real^M->real^N->real^P`] + LIM_BILINEAR) THEN + ASM_REWRITE_TAC[] THEN STRIP_TAC THEN + REMOVE_THEN "contg" MP_TAC THEN REMOVE_THEN "df" MP_TAC THEN + REWRITE_TAC[IMP_IMP] THEN DISCH_THEN(ANTE_RES_THEN MP_TAC) THEN + REMOVE_THEN "dg" MP_TAC THEN REMOVE_THEN "contf" MP_TAC THEN + ONCE_REWRITE_TAC[IMP_IMP] THEN DISCH_THEN(ANTE_RES_THEN MP_TAC) THEN + REWRITE_TAC[IMP_IMP] THEN DISCH_THEN(MP_TAC o MATCH_MP LIM_ADD) THEN + SUBGOAL_THEN + `((\y:real^Q. inv(norm(y - x)) % + (h:real^M->real^N->real^P) (f'(y - x)) (g'(y - x))) + --> vec 0) (at x within s)` + MP_TAC THENL + [FIRST_ASSUM(X_CHOOSE_THEN `B:real` STRIP_ASSUME_TAC o MATCH_MP + BILINEAR_BOUNDED_POS) THEN + X_CHOOSE_THEN `C:real` STRIP_ASSUME_TAC + (MATCH_MP LINEAR_BOUNDED_POS (ASSUME `linear (f':real^Q->real^M)`)) THEN + X_CHOOSE_THEN `D:real` STRIP_ASSUME_TAC + (MATCH_MP LINEAR_BOUNDED_POS (ASSUME `linear (g':real^Q->real^N)`)) THEN + REWRITE_TAC[LIM_WITHIN; dist; VECTOR_SUB_RZERO] THEN + X_GEN_TAC `e:real` THEN STRIP_TAC THEN EXISTS_TAC `e / (B * C * D)` THEN + ASM_SIMP_TAC[REAL_LT_DIV; NORM_MUL; REAL_LT_MUL] THEN + X_GEN_TAC `x':real^Q` THEN + REWRITE_TAC[REAL_ABS_MUL; REAL_ABS_NORM; REAL_ABS_INV] THEN + STRIP_TAC THEN MATCH_MP_TAC REAL_LET_TRANS THEN + EXISTS_TAC `inv(norm(x' - x :real^Q)) * + B * (C * norm(x' - x)) * (D * norm(x' - x))` THEN + CONJ_TAC THENL + [MATCH_MP_TAC REAL_LE_LMUL THEN SIMP_TAC[REAL_LE_INV_EQ; NORM_POS_LE] THEN + ASM_MESON_TAC[REAL_LE_LMUL; REAL_LT_IMP_LE; REAL_LE_MUL2; NORM_POS_LE; + REAL_LE_TRANS]; + ONCE_REWRITE_TAC[AC REAL_MUL_AC + `i * b * (c * x) * (d * x) = (i * x) * x * (b * c * d)`] THEN + ASM_SIMP_TAC[REAL_MUL_LINV; REAL_LT_IMP_NZ; REAL_MUL_LID] THEN + ASM_SIMP_TAC[GSYM REAL_LT_RDIV_EQ; REAL_LT_MUL]]; + REWRITE_TAC[IMP_IMP] THEN DISCH_THEN(MP_TAC o MATCH_MP LIM_ADD) THEN + REWRITE_TAC (map (C MATCH_MP (ASSUME `bilinear(h:real^M->real^N->real^P)`)) + [BILINEAR_RZERO; BILINEAR_LZERO; BILINEAR_LADD; BILINEAR_RADD; + BILINEAR_LMUL; BILINEAR_RMUL; BILINEAR_LSUB; BILINEAR_RSUB]) THEN + MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN + BINOP_TAC THEN REWRITE_TAC[FUN_EQ_THM] THEN VECTOR_ARITH_TAC]);; + +let HAS_DERIVATIVE_BILINEAR_AT = prove + (`!h:real^M->real^N->real^P f g f' g' x:real^Q. + (f has_derivative f') (at x) /\ + (g has_derivative g') (at x) /\ + bilinear h + ==> ((\x. h (f x) (g x)) has_derivative + (\d. h (f x) (g' d) + h (f' d) (g x))) (at x)`, + REWRITE_TAC[has_derivative_at] THEN + ONCE_REWRITE_TAC[GSYM WITHIN_UNIV] THEN + REWRITE_TAC[GSYM has_derivative_within; HAS_DERIVATIVE_BILINEAR_WITHIN]);; + +let BILINEAR_DIFFERENTIABLE_AT_COMPOSE = prove + (`!f:real^M->real^N g:real^M->real^P h:real^N->real^P->real^Q a. + f differentiable at a /\ g differentiable at a /\ bilinear h + ==> (\x. h (f x) (g x)) differentiable at a`, + REPEAT GEN_TAC THEN REWRITE_TAC[FRECHET_DERIVATIVE_WORKS] THEN + DISCH_THEN(MP_TAC o MATCH_MP HAS_DERIVATIVE_BILINEAR_AT) THEN + REWRITE_TAC[GSYM FRECHET_DERIVATIVE_WORKS; differentiable] THEN + MESON_TAC[]);; + +let BILINEAR_DIFFERENTIABLE_WITHIN_COMPOSE = prove + (`!f:real^M->real^N g:real^M->real^P h:real^N->real^P->real^Q x s. + f differentiable at x within s /\ g differentiable at x within s /\ + bilinear h + ==> (\x. h (f x) (g x)) differentiable at x within s`, + REPEAT GEN_TAC THEN REWRITE_TAC[FRECHET_DERIVATIVE_WORKS] THEN + DISCH_THEN(MP_TAC o MATCH_MP HAS_DERIVATIVE_BILINEAR_WITHIN) THEN + REWRITE_TAC[GSYM FRECHET_DERIVATIVE_WORKS; differentiable] THEN + MESON_TAC[]);; + +let BILINEAR_DIFFERENTIABLE_ON_COMPOSE = prove + (`!f:real^M->real^N g:real^M->real^P h:real^N->real^P->real^Q s. + f differentiable_on s /\ g differentiable_on s /\ bilinear h + ==> (\x. h (f x) (g x)) differentiable_on s`, + REWRITE_TAC[differentiable_on] THEN + MESON_TAC[BILINEAR_DIFFERENTIABLE_WITHIN_COMPOSE]);; + +let DIFFERENTIABLE_AT_LIFT_DOT2 = prove + (`!f:real^M->real^N g x. + f differentiable at x /\ g differentiable at x + ==> (\x. lift(f x dot g x)) differentiable at x`, + REPEAT GEN_TAC THEN DISCH_THEN(MP_TAC o MATCH_MP (MATCH_MP (REWRITE_RULE + [TAUT `p /\ q /\ r ==> s <=> r ==> p /\ q ==> s`] + BILINEAR_DIFFERENTIABLE_AT_COMPOSE) BILINEAR_DOT)) THEN REWRITE_TAC[]);; + +let DIFFERENTIABLE_WITHIN_LIFT_DOT2 = prove + (`!f:real^M->real^N g x s. + f differentiable (at x within s) /\ g differentiable (at x within s) + ==> (\x. lift(f x dot g x)) differentiable (at x within s)`, + REPEAT GEN_TAC THEN DISCH_THEN(MP_TAC o MATCH_MP (MATCH_MP (REWRITE_RULE + [TAUT `p /\ q /\ r ==> s <=> r ==> p /\ q ==> s`] + BILINEAR_DIFFERENTIABLE_WITHIN_COMPOSE) BILINEAR_DOT)) THEN REWRITE_TAC[]);; + +let DIFFERENTIABLE_ON_LIFT_DOT2 = prove + (`!f:real^M->real^N g s. + f differentiable_on s /\ g differentiable_on s + ==> (\x. lift(f x dot g x)) differentiable_on s`, + REPEAT GEN_TAC THEN DISCH_THEN(MP_TAC o MATCH_MP (MATCH_MP (REWRITE_RULE + [TAUT `p /\ q /\ r ==> s <=> r ==> p /\ q ==> s`] + BILINEAR_DIFFERENTIABLE_ON_COMPOSE) BILINEAR_DOT)) THEN REWRITE_TAC[]);; + +let HAS_DERIVATIVE_MUL_WITHIN = prove + (`!f f' g:real^M->real^N g' a s. + ((lift o f) has_derivative (lift o f')) (at a within s) /\ + (g has_derivative g') (at a within s) + ==> ((\x. f x % g x) has_derivative + (\h. f a % g' h + f' h % g a)) (at a within s)`, + REPEAT GEN_TAC THEN + DISCH_THEN(MP_TAC o MATCH_MP (REWRITE_RULE[BILINEAR_DROP_MUL] + (ISPEC `\x y:real^M. drop x % y` HAS_DERIVATIVE_BILINEAR_WITHIN))) THEN + REWRITE_TAC[o_DEF; DROP_CMUL; LIFT_DROP]);; + +let HAS_DERIVATIVE_MUL_AT = prove + (`!f f' g:real^M->real^N g' a. + ((lift o f) has_derivative (lift o f')) (at a) /\ + (g has_derivative g') (at a) + ==> ((\x. f x % g x) has_derivative + (\h. f a % g' h + f' h % g a)) (at a)`, + ONCE_REWRITE_TAC[GSYM WITHIN_UNIV] THEN + REWRITE_TAC[HAS_DERIVATIVE_MUL_WITHIN]);; + +let HAS_DERIVATIVE_SQNORM_AT = prove + (`!a:real^N. + ((\x. lift(norm x pow 2)) has_derivative (\x. &2 % lift(a dot x))) (at a)`, + GEN_TAC THEN MP_TAC(ISPECL + [`\x y:real^N. lift(x dot y)`; + `\x:real^N. x`; `\x:real^N. x`; `\x:real^N. x`; `\x:real^N. x`; + `a:real^N`] HAS_DERIVATIVE_BILINEAR_AT) THEN + REWRITE_TAC[HAS_DERIVATIVE_ID; BILINEAR_DOT; NORM_POW_2] THEN + MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_TERM_TAC THEN + REWRITE_TAC[FUN_EQ_THM; DOT_SYM] THEN VECTOR_ARITH_TAC);; + +let DIFFERENTIABLE_MUL_WITHIN = prove + (`!f g:real^M->real^N a s. + (lift o f) differentiable (at a within s) /\ + g differentiable (at a within s) + ==> (\x. f x % g x) differentiable (at a within s)`, + REPEAT GEN_TAC THEN MP_TAC(ISPECL + [`lift o (f:real^M->real)`; `g:real^M->real^N`; `\x y:real^N. drop x % y`; + `a:real^M`; `s:real^M->bool`] BILINEAR_DIFFERENTIABLE_WITHIN_COMPOSE) THEN + REWRITE_TAC[o_DEF; LIFT_DROP; BILINEAR_DROP_MUL]);; + +let DIFFERENTIABLE_MUL_AT = prove + (`!f g:real^M->real^N a. + (lift o f) differentiable (at a) /\ g differentiable (at a) + ==> (\x. f x % g x) differentiable (at a)`, + ONCE_REWRITE_TAC[GSYM WITHIN_UNIV] THEN + REWRITE_TAC[DIFFERENTIABLE_MUL_WITHIN]);; + +let DIFFERENTIABLE_SQNORM_AT = prove + (`!a:real^N. (\x. lift(norm x pow 2)) differentiable (at a)`, + REWRITE_TAC[differentiable] THEN MESON_TAC[HAS_DERIVATIVE_SQNORM_AT]);; + +let DIFFERENTIABLE_ON_MUL = prove + (`!f g:real^M->real^N s. + (lift o f) differentiable_on s /\ g differentiable_on s + ==> (\x. f x % g x) differentiable_on s`, + REPEAT GEN_TAC THEN MP_TAC(ISPECL + [`lift o (f:real^M->real)`; `g:real^M->real^N`; `\x y:real^N. drop x % y`; + `s:real^M->bool`] BILINEAR_DIFFERENTIABLE_ON_COMPOSE) THEN + REWRITE_TAC[o_DEF; LIFT_DROP; BILINEAR_DROP_MUL]);; + +let DIFFERENTIABLE_ON_SQNORM = prove + (`!s:real^N->bool. (\x. lift(norm x pow 2)) differentiable_on s`, + SIMP_TAC[DIFFERENTIABLE_AT_IMP_DIFFERENTIABLE_ON; + DIFFERENTIABLE_SQNORM_AT]);; + +(* ------------------------------------------------------------------------- *) +(* Considering derivative R(^1)->R^n as a vector. *) +(* ------------------------------------------------------------------------- *) + +parse_as_infix ("has_vector_derivative",(12,"right"));; + +let has_vector_derivative = new_definition + `(f has_vector_derivative f') net <=> + (f has_derivative (\x. drop(x) % f')) net`;; + +let vector_derivative = new_definition + `vector_derivative (f:real^1->real^N) net = + @f'. (f has_vector_derivative f') net`;; + +let VECTOR_DERIVATIVE_WORKS = prove + (`!net f:real^1->real^N. + f differentiable net <=> + (f has_vector_derivative (vector_derivative f net)) net`, + REPEAT GEN_TAC THEN REWRITE_TAC[vector_derivative] THEN + CONV_TAC(RAND_CONV SELECT_CONV) THEN + SIMP_TAC[FRECHET_DERIVATIVE_WORKS; has_vector_derivative] THEN EQ_TAC THENL + [ALL_TAC; MESON_TAC[FRECHET_DERIVATIVE_WORKS; differentiable]] THEN + DISCH_TAC THEN EXISTS_TAC `column 1 (jacobian (f:real^1->real^N) net)` THEN + FIRST_ASSUM MP_TAC THEN MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN + AP_TERM_TAC THEN REWRITE_TAC[jacobian] THEN + MATCH_MP_TAC LINEAR_FROM_REALS THEN + RULE_ASSUM_TAC(REWRITE_RULE[has_derivative]) THEN ASM_REWRITE_TAC[]);; + +let VECTOR_DERIVATIVE_UNIQUE_AT = prove + (`!f:real^1->real^N x f' f''. + (f has_vector_derivative f') (at x) /\ + (f has_vector_derivative f'') (at x) + ==> f' = f''`, + REWRITE_TAC[has_vector_derivative; drop] THEN REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`f:real^1->real^N`; + `\x. drop x % (f':real^N)`; `\x. drop x % (f'':real^N)`; + `x:real^1`] FRECHET_DERIVATIVE_UNIQUE_AT) THEN + ASM_SIMP_TAC[DIMINDEX_1; LE_ANTISYM; drop] THEN + REWRITE_TAC[FUN_EQ_THM] THEN DISCH_THEN(MP_TAC o SPEC `vec 1:real^1`) THEN + SIMP_TAC[VEC_COMPONENT; DIMINDEX_1; ARITH; VECTOR_MUL_LID]);; + +let HAS_VECTOR_DERIVATIVE_UNIQUE_AT = prove + (`!f:real^1->real^N f' x. + (f has_vector_derivative f') (at x) + ==> vector_derivative f (at x) = f'`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC VECTOR_DERIVATIVE_UNIQUE_AT THEN + MAP_EVERY EXISTS_TAC [`f:real^1->real^N`; `x:real^1`] THEN + ASM_REWRITE_TAC[vector_derivative] THEN CONV_TAC SELECT_CONV THEN + ASM_MESON_TAC[]);; + +let VECTOR_DERIVATIVE_UNIQUE_WITHIN_CLOSED_INTERVAL = prove + (`!f:real^1->real^N a b x f' f''. + drop a < drop b /\ + x IN interval [a,b] /\ + (f has_vector_derivative f') (at x within interval [a,b]) /\ + (f has_vector_derivative f'') (at x within interval [a,b]) + ==> f' = f''`, + REWRITE_TAC[has_vector_derivative; drop] THEN REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`f:real^1->real^N`; + `\x. drop x % (f':real^N)`; `\x. drop x % (f'':real^N)`; + `x:real^1`; `a:real^1`; `b:real^1`] + FRECHET_DERIVATIVE_UNIQUE_WITHIN_CLOSED_INTERVAL) THEN + ASM_SIMP_TAC[DIMINDEX_1; LE_ANTISYM; drop] THEN + ANTS_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN REWRITE_TAC[FUN_EQ_THM] THEN + DISCH_THEN(MP_TAC o SPEC `vec 1:real^1`) THEN + SIMP_TAC[VEC_COMPONENT; DIMINDEX_1; ARITH; VECTOR_MUL_LID]);; + +let VECTOR_DERIVATIVE_AT = prove + (`(f has_vector_derivative f') (at x) ==> vector_derivative f (at x) = f'`, + ASM_MESON_TAC[VECTOR_DERIVATIVE_UNIQUE_AT; + VECTOR_DERIVATIVE_WORKS; differentiable; has_vector_derivative]);; + +let VECTOR_DERIVATIVE_WITHIN_CLOSED_INTERVAL = prove + (`!f:real^1->real^N f' x a b. + drop a < drop b /\ x IN interval[a,b] /\ + (f has_vector_derivative f') (at x within interval [a,b]) + ==> vector_derivative f (at x within interval [a,b]) = f'`, + ASM_MESON_TAC[VECTOR_DERIVATIVE_UNIQUE_WITHIN_CLOSED_INTERVAL; + VECTOR_DERIVATIVE_WORKS; differentiable; has_vector_derivative]);; + +let HAS_VECTOR_DERIVATIVE_WITHIN_SUBSET = prove + (`!f s t x. (f has_vector_derivative f') (at x within s) /\ t SUBSET s + ==> (f has_vector_derivative f') (at x within t)`, + REWRITE_TAC[has_vector_derivative; HAS_DERIVATIVE_WITHIN_SUBSET]);; + +let HAS_VECTOR_DERIVATIVE_CONST = prove + (`!c net. ((\x. c) has_vector_derivative vec 0) net`, + REWRITE_TAC[has_vector_derivative] THEN + REWRITE_TAC[VECTOR_MUL_RZERO; HAS_DERIVATIVE_CONST]);; + +let VECTOR_DERIVATIVE_CONST_AT = prove + (`!c:real^N a. vector_derivative (\x. c) (at a) = vec 0`, + REPEAT GEN_TAC THEN MATCH_MP_TAC HAS_VECTOR_DERIVATIVE_UNIQUE_AT THEN + REWRITE_TAC[HAS_VECTOR_DERIVATIVE_CONST]);; + +let HAS_VECTOR_DERIVATIVE_ID = prove + (`!net. ((\x. x) has_vector_derivative (vec 1)) net`, + REWRITE_TAC[has_vector_derivative] THEN + SUBGOAL_THEN `(\x. drop x % vec 1) = (\x. x)` + (fun th -> REWRITE_TAC[HAS_DERIVATIVE_ID; th]) THEN + REWRITE_TAC[FUN_EQ_THM; GSYM DROP_EQ; DROP_CMUL; DROP_VEC] THEN + REAL_ARITH_TAC);; + +let HAS_VECTOR_DERIVATIVE_CMUL = prove + (`!f f' net c. (f has_vector_derivative f') net + ==> ((\x. c % f(x)) has_vector_derivative (c % f')) net`, + SIMP_TAC[has_vector_derivative] THEN + ONCE_REWRITE_TAC[VECTOR_ARITH `a % b % x = b % a % x`] THEN + SIMP_TAC[HAS_DERIVATIVE_CMUL]);; + +let HAS_VECTOR_DERIVATIVE_CMUL_EQ = prove + (`!f f' net c. + ~(c = &0) + ==> (((\x. c % f(x)) has_vector_derivative (c % f')) net <=> + (f has_vector_derivative f') net)`, + REPEAT STRIP_TAC THEN EQ_TAC THEN + DISCH_THEN(MP_TAC o MATCH_MP HAS_VECTOR_DERIVATIVE_CMUL) THENL + [DISCH_THEN(MP_TAC o SPEC `inv(c):real`); + DISCH_THEN(MP_TAC o SPEC `c:real`)] THEN + ASM_SIMP_TAC[VECTOR_MUL_ASSOC; REAL_MUL_LINV; VECTOR_MUL_LID; ETA_AX]);; + +let HAS_VECTOR_DERIVATIVE_NEG = prove + (`!f f' net. (f has_vector_derivative f') net + ==> ((\x. --(f(x))) has_vector_derivative (--f')) net`, + SIMP_TAC[has_vector_derivative; VECTOR_MUL_RNEG; HAS_DERIVATIVE_NEG]);; + +let HAS_VECTOR_DERIVATIVE_NEG_EQ = prove + (`!f f' net. ((\x. --(f(x))) has_vector_derivative --f') net <=> + (f has_vector_derivative f') net`, + SIMP_TAC[has_vector_derivative; HAS_DERIVATIVE_NEG_EQ; VECTOR_MUL_RNEG]);; + +let HAS_VECTOR_DERIVATIVE_ADD = prove + (`!f f' g g' net. + (f has_vector_derivative f') net /\ (g has_vector_derivative g') net + ==> ((\x. f(x) + g(x)) has_vector_derivative (f' + g')) net`, + SIMP_TAC[has_vector_derivative; VECTOR_ADD_LDISTRIB; HAS_DERIVATIVE_ADD]);; + +let HAS_VECTOR_DERIVATIVE_SUB = prove + (`!f f' g g' net. + (f has_vector_derivative f') net /\ (g has_vector_derivative g') net + ==> ((\x. f(x) - g(x)) has_vector_derivative (f' - g')) net`, + SIMP_TAC[has_vector_derivative; VECTOR_SUB_LDISTRIB; HAS_DERIVATIVE_SUB]);; + +let HAS_VECTOR_DERIVATIVE_BILINEAR_WITHIN = prove + (`!h:real^M->real^N->real^P f g f' g' x s. + (f has_vector_derivative f') (at x within s) /\ + (g has_vector_derivative g') (at x within s) /\ + bilinear h + ==> ((\x. h (f x) (g x)) has_vector_derivative + (h (f x) g' + h f' (g x))) (at x within s)`, + REPEAT GEN_TAC THEN REWRITE_TAC[has_vector_derivative] THEN + DISCH_TAC THEN + FIRST_ASSUM(MP_TAC o MATCH_MP HAS_DERIVATIVE_BILINEAR_WITHIN) THEN + RULE_ASSUM_TAC(REWRITE_RULE[bilinear; linear]) THEN + ASM_REWRITE_TAC[VECTOR_ADD_LDISTRIB]);; + +let HAS_VECTOR_DERIVATIVE_BILINEAR_AT = prove + (`!h:real^M->real^N->real^P f g f' g' x. + (f has_vector_derivative f') (at x) /\ + (g has_vector_derivative g') (at x) /\ + bilinear h + ==> ((\x. h (f x) (g x)) has_vector_derivative + (h (f x) g' + h f' (g x))) (at x)`, + REPEAT GEN_TAC THEN REWRITE_TAC[has_vector_derivative] THEN + DISCH_TAC THEN + FIRST_ASSUM(MP_TAC o MATCH_MP HAS_DERIVATIVE_BILINEAR_AT) THEN + RULE_ASSUM_TAC(REWRITE_RULE[bilinear; linear]) THEN + ASM_REWRITE_TAC[VECTOR_ADD_LDISTRIB]);; + +let HAS_VECTOR_DERIVATIVE_AT_WITHIN = prove + (`!f x s. (f has_vector_derivative f') (at x) + ==> (f has_vector_derivative f') (at x within s)`, + SIMP_TAC[has_vector_derivative; HAS_DERIVATIVE_AT_WITHIN]);; + +let HAS_VECTOR_DERIVATIVE_TRANSFORM_WITHIN = prove + (`!f f' g x s d. + &0 < d /\ x IN s /\ + (!x'. x' IN s /\ dist (x',x) < d ==> f x' = g x') /\ + (f has_vector_derivative f') (at x within s) + ==> (g has_vector_derivative f') (at x within s)`, + REWRITE_TAC[has_vector_derivative; HAS_DERIVATIVE_TRANSFORM_WITHIN]);; + +let HAS_VECTOR_DERIVATIVE_TRANSFORM_AT = prove + (`!f f' g x d. + &0 < d /\ (!x'. dist (x',x) < d ==> f x' = g x') /\ + (f has_vector_derivative f') (at x) + ==> (g has_vector_derivative f') (at x)`, + REWRITE_TAC[has_vector_derivative; HAS_DERIVATIVE_TRANSFORM_AT]);; + +let HAS_VECTOR_DERIVATIVE_TRANSFORM_WITHIN_OPEN = prove + (`!f g s x. + open s /\ x IN s /\ + (!y. y IN s ==> f y = g y) /\ + (f has_vector_derivative f') (at x) + ==> (g has_vector_derivative f') (at x)`, + REWRITE_TAC[has_vector_derivative; HAS_DERIVATIVE_TRANSFORM_WITHIN_OPEN]);; + +let VECTOR_DIFF_CHAIN_AT = prove + (`!f g f' g' x. + (f has_vector_derivative f') (at x) /\ + (g has_vector_derivative g') (at (f x)) + ==> ((g o f) has_vector_derivative (drop f' % g')) (at x)`, + REPEAT GEN_TAC THEN REWRITE_TAC[has_vector_derivative] THEN + DISCH_THEN(MP_TAC o MATCH_MP DIFF_CHAIN_AT) THEN + REWRITE_TAC[o_DEF; DROP_CMUL; GSYM VECTOR_MUL_ASSOC]);; + +let VECTOR_DIFF_CHAIN_WITHIN = prove + (`!f g f' g' s x. + (f has_vector_derivative f') (at x within s) /\ + (g has_vector_derivative g') (at (f x) within IMAGE f s) + ==> ((g o f) has_vector_derivative (drop f' % g')) (at x within s)`, + REPEAT GEN_TAC THEN REWRITE_TAC[has_vector_derivative] THEN + DISCH_THEN(MP_TAC o MATCH_MP DIFF_CHAIN_WITHIN) THEN + REWRITE_TAC[o_DEF; DROP_CMUL; GSYM VECTOR_MUL_ASSOC]);; + +(* ------------------------------------------------------------------------- *) +(* Various versions of Kachurovskii's theorem. *) +(* ------------------------------------------------------------------------- *) + +let CONVEX_ON_DERIVATIVE_SECANT_IMP = prove + (`!f f' s x y:real^N. + f convex_on s /\ segment[x,y] SUBSET s /\ + ((lift o f) has_derivative (lift o f')) (at x within s) + ==> f'(y - x) <= f y - f x`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN `(x:real^N) IN s /\ (y:real^N) IN s` ASSUME_TAC THENL + [ASM_MESON_TAC[SUBSET; ENDS_IN_SEGMENT]; ALL_TAC] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [has_derivative_within]) THEN + REWRITE_TAC[LIM_WITHIN; DIST_0; o_THM] THEN + REWRITE_TAC[GSYM LIFT_ADD; GSYM LIFT_SUB; GSYM LIFT_CMUL; NORM_LIFT] THEN + STRIP_TAC THEN ASM_CASES_TAC `y:real^N = x` THENL + [FIRST_X_ASSUM(MP_TAC o MATCH_MP LINEAR_0) THEN + REWRITE_TAC[o_THM; VECTOR_SUB_REFL; GSYM DROP_EQ; DROP_VEC; LIFT_DROP] THEN + ASM_SIMP_TAC[REAL_SUB_REFL; REAL_LE_REFL; VECTOR_SUB_REFL]; + ALL_TAC] THEN + ABBREV_TAC `e = (f':real^N->real)(y - x) - (f y - f x)` THEN + ASM_CASES_TAC `&0 < e` THENL [ALL_TAC; ASM_REAL_ARITH_TAC] THEN + FIRST_X_ASSUM(MP_TAC o SPEC `e / &2 / norm(y - x:real^N)`) THEN + ASM_SIMP_TAC[REAL_LT_DIV; REAL_HALF; NORM_POS_LT; VECTOR_SUB_EQ] THEN + DISCH_THEN(X_CHOOSE_THEN `d:real` (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + ABBREV_TAC `u = min (&1 / &2) (d / &2 / norm (y - x:real^N))` THEN + SUBGOAL_THEN `&0 < u /\ u < &1` STRIP_ASSUME_TAC THENL + [EXPAND_TAC "u" THEN REWRITE_TAC[REAL_LT_MIN; REAL_MIN_LT] THEN + ASM_SIMP_TAC[REAL_LT_DIV; NORM_POS_LT; REAL_HALF; VECTOR_SUB_EQ] THEN + CONV_TAC REAL_RAT_REDUCE_CONV; + ALL_TAC] THEN + ABBREV_TAC `z:real^N = (&1 - u) % x + u % y` THEN + SUBGOAL_THEN `(z:real^N) IN segment(x,y)` MP_TAC THENL + [ASM_MESON_TAC[IN_SEGMENT]; ALL_TAC] THEN + SIMP_TAC[open_segment; IN_DIFF; IN_INSERT; NOT_IN_EMPTY; DE_MORGAN_THM] THEN + STRIP_TAC THEN DISCH_THEN(MP_TAC o SPEC `z:real^N`) THEN + SUBGOAL_THEN `(z:real^N) IN s` ASSUME_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + ANTS_TAC THENL + [ASM_SIMP_TAC[DIST_POS_LT] THEN + EXPAND_TAC "z" THEN REWRITE_TAC[dist; NORM_MUL; VECTOR_ARITH + `((&1 - u) % x + u % y) - x:real^N = u % (y - x)`] THEN + ASM_SIMP_TAC[GSYM REAL_LT_RDIV_EQ; NORM_POS_LT; VECTOR_SUB_EQ] THEN + ASM_REAL_ARITH_TAC; + ALL_TAC] THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [CONVEX_ON_LEFT_SECANT]) THEN + DISCH_THEN(MP_TAC o SPECL [`x:real^N`; `y:real^N`; `z:real^N`]) THEN + ASM_REWRITE_TAC[open_segment; IN_DIFF; IN_INSERT; NOT_IN_EMPTY] THEN + SIMP_TAC[REAL_ARITH `inv y * (z - (x + d)):real = (z - x) / y - d / y`] THEN + REWRITE_TAC[IMP_IMP] THEN DISCH_THEN(MP_TAC o MATCH_MP (REAL_ARITH + `z <= y / n /\ abs(z - d) < e / n ==> d <= (y + e) / n`)) THEN + SUBGOAL_THEN + `(f':real^N->real)(z - x) / norm(z - x) = f'(y - x) / norm(y - x)` + SUBST1_TAC THENL + [EXPAND_TAC "z" THEN + REWRITE_TAC[VECTOR_ARITH + `((&1 - u) % x + u % y) - x:real^N = u % (y - x)`] THEN + FIRST_ASSUM(MP_TAC o MATCH_MP LINEAR_CMUL) THEN + DISCH_THEN(MP_TAC o SPECL [`u:real`; `y - x:real^N`]) THEN + ASM_REWRITE_TAC[GSYM LIFT_CMUL; o_THM; LIFT_EQ] THEN + DISCH_THEN SUBST1_TAC THEN REWRITE_TAC[NORM_MUL] THEN + ASM_SIMP_TAC[real_abs; REAL_LT_IMP_LE] THEN + REWRITE_TAC[real_div; REAL_INV_MUL; REAL_MUL_ASSOC] THEN + AP_THM_TAC THEN AP_TERM_TAC THEN REWRITE_TAC[GSYM REAL_MUL_ASSOC] THEN + REWRITE_TAC[GSYM real_div] THEN MATCH_MP_TAC REAL_DIV_LMUL THEN + ASM_REAL_ARITH_TAC; + ASM_SIMP_TAC[REAL_LE_DIV2_EQ; NORM_POS_LT; VECTOR_SUB_EQ] THEN + ASM_REAL_ARITH_TAC]);; + +let CONVEX_ON_SECANT_DERIVATIVE_IMP = prove + (`!f f' s x y:real^N. + f convex_on s /\ segment[x,y] SUBSET s /\ + ((lift o f) has_derivative (lift o f')) (at y within s) + ==> f y - f x <= f'(y - x)`, + ONCE_REWRITE_TAC[SEGMENT_SYM] THEN REPEAT STRIP_TAC THEN + MP_TAC(ISPECL + [`f:real^N->real`; `f':real^N->real`; `s:real^N->bool`; + `y:real^N`; `x:real^N`] CONVEX_ON_DERIVATIVE_SECANT_IMP) THEN + ASM_REWRITE_TAC[] THEN ONCE_REWRITE_TAC[SEGMENT_SYM] THEN + MATCH_MP_TAC(REAL_ARITH + `f' = --f'' ==> f' <= x - y ==> y - x <= f''`) THEN + GEN_REWRITE_TAC (LAND_CONV o RAND_CONV) [GSYM VECTOR_NEG_SUB] THEN + GEN_REWRITE_TAC I [GSYM LIFT_EQ] THEN REWRITE_TAC[LIFT_NEG] THEN + SPEC_TAC(`y - x:real^N`,`z:real^N`) THEN + MATCH_MP_TAC(REWRITE_RULE[RIGHT_FORALL_IMP_THM] LINEAR_NEG) THEN + REWRITE_TAC[GSYM o_DEF] THEN ASM_MESON_TAC[has_derivative]);; + +let CONVEX_ON_DERIVATIVES_IMP = prove + (`!f f'x f'y s x y:real^N. + f convex_on s /\ segment[x,y] SUBSET s /\ + ((lift o f) has_derivative (lift o f'x)) (at x within s) /\ + ((lift o f) has_derivative (lift o f'y)) (at y within s) + ==> f'x(y - x) <= f'y(y - x)`, + ASM_MESON_TAC[CONVEX_ON_DERIVATIVE_SECANT_IMP; + CONVEX_ON_SECANT_DERIVATIVE_IMP; + SEGMENT_SYM; REAL_LE_TRANS]);; + +let CONVEX_ON_DERIVATIVE_SECANT,CONVEX_ON_DERIVATIVES = + (CONJ_PAIR o prove) + (`(!f f' s:real^N->bool. + convex s /\ + (!x. x IN s ==> ((lift o f) has_derivative (lift o f'(x))) + (at x within s)) + ==> (f convex_on s <=> + !x y. x IN s /\ y IN s ==> f'(x)(y - x) <= f y - f x)) /\ + (!f f' s:real^N->bool. + convex s /\ + (!x. x IN s ==> ((lift o f) has_derivative (lift o f'(x))) + (at x within s)) + ==> (f convex_on s <=> + !x y. x IN s /\ y IN s ==> f'(x)(y - x) <= f'(y)(y - x)))`, + REWRITE_TAC[AND_FORALL_THM] THEN REPEAT GEN_TAC THEN + REWRITE_TAC[TAUT `(a ==> b) /\ (a ==> c) <=> a ==> b /\ c`] THEN + STRIP_TAC THEN MATCH_MP_TAC(TAUT + `(a ==> b) /\ (b ==> c) /\ (c ==> a) ==> (a <=> b) /\ (a <=> c)`) THEN + REPEAT CONJ_TAC THENL + [REPEAT STRIP_TAC THEN MATCH_MP_TAC CONVEX_ON_DERIVATIVE_SECANT_IMP THEN + EXISTS_TAC `s:real^N->bool` THEN ASM_SIMP_TAC[ETA_AX] THEN + ASM_MESON_TAC[CONVEX_CONTAINS_SEGMENT]; + DISCH_TAC THEN MAP_EVERY X_GEN_TAC [`x:real^N`; `y:real^N`] THEN + STRIP_TAC THEN FIRST_X_ASSUM(fun th -> + MP_TAC(ISPECL [`x:real^N`; `y:real^N`] th) THEN + MP_TAC(ISPECL [`y:real^N`; `x:real^N`] th)) THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC(REAL_ARITH + `f''' = --f'' ==> f''' <= x - y ==> f' <= y - x ==> f' <= f''`) THEN + GEN_REWRITE_TAC (LAND_CONV o RAND_CONV) [GSYM VECTOR_NEG_SUB] THEN + GEN_REWRITE_TAC I [GSYM LIFT_EQ] THEN REWRITE_TAC[LIFT_NEG] THEN + SPEC_TAC(`y - x:real^N`,`z:real^N`) THEN + MATCH_MP_TAC(REWRITE_RULE[RIGHT_FORALL_IMP_THM] LINEAR_NEG) THEN + REWRITE_TAC[GSYM o_DEF] THEN REWRITE_TAC[GSYM I_DEF; I_O_ID] THEN + ASM_MESON_TAC[has_derivative]; + ALL_TAC] THEN + DISCH_TAC THEN REWRITE_TAC[convex_on] THEN + MAP_EVERY X_GEN_TAC [`a:real^N`; `b:real^N`] THEN + ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN + REWRITE_TAC[TAUT `a /\ b /\ c /\ d /\ e <=> e /\ a /\ b /\ c /\ d`] THEN + REWRITE_TAC[IMP_CONJ; REAL_ARITH `u + v = &1 <=> u = &1 - v`] THEN + REWRITE_TAC[FORALL_UNWIND_THM2; REAL_SUB_LE] THEN X_GEN_TAC `u:real` THEN + REPEAT STRIP_TAC THEN + ASM_CASES_TAC `u = &0` THEN + ASM_SIMP_TAC[REAL_SUB_RZERO; VECTOR_MUL_LZERO; VECTOR_MUL_LID; REAL_LE_REFL; + REAL_MUL_LZERO; REAL_MUL_LID; VECTOR_ADD_RID; REAL_ADD_RID] THEN + ASM_CASES_TAC `u = &1` THEN + ASM_SIMP_TAC[REAL_SUB_REFL; VECTOR_MUL_LZERO; VECTOR_MUL_LID; REAL_LE_REFL; + REAL_MUL_LZERO; REAL_MUL_LID; VECTOR_ADD_LID; REAL_ADD_LID] THEN + SUBGOAL_THEN `&0 < u /\ u < &1` STRIP_ASSUME_TAC THENL + [ASM_REWRITE_TAC[REAL_LT_LE]; ALL_TAC] THEN + MP_TAC(ISPECL + [`lift o (f:real^N->real) o (\u. (&1 - drop u) % a + drop u % b)`; + `\x:real^1. lift o f'((&1 - drop x) % a + drop x % b) o + (\u. --(drop u) % a + drop u % b:real^N)`] MVT_VERY_SIMPLE) THEN + DISCH_THEN(fun th -> + MP_TAC(ISPECL [`vec 0:real^1`; `lift u`] th) THEN + MP_TAC(ISPECL [`lift u`; `vec 1:real^1`] th)) THEN + ASM_REWRITE_TAC[LIFT_DROP; o_THM] THEN + ASM_SIMP_TAC[DROP_VEC; VECTOR_MUL_LZERO; REAL_SUB_RZERO; REAL_LT_IMP_LE; + VECTOR_ADD_RID; VECTOR_MUL_LID; VECTOR_SUB_RZERO] THEN + MATCH_MP_TAC(TAUT + `(a1 /\ a2) /\ (b1 ==> b2 ==> c) ==> (a1 ==> b1) ==> (a2 ==> b2) ==> c`) THEN + CONJ_TAC THENL + [CONJ_TAC THEN X_GEN_TAC `v:real^1` THEN DISCH_TAC THEN + (REWRITE_TAC[o_ASSOC] THEN MATCH_MP_TAC DIFF_CHAIN_WITHIN THEN + REWRITE_TAC[] THEN CONJ_TAC THENL + [MATCH_MP_TAC HAS_DERIVATIVE_ADD THEN CONJ_TAC THENL + [ONCE_REWRITE_TAC[VECTOR_ARITH `(&1 - a) % x:real^N = x + --a % x`; + VECTOR_ARITH `--u % a:real^N = vec 0 + --u % a`] THEN + MATCH_MP_TAC HAS_DERIVATIVE_ADD THEN + REWRITE_TAC[HAS_DERIVATIVE_CONST]; + ALL_TAC] THEN + MATCH_MP_TAC HAS_DERIVATIVE_LINEAR THEN + REWRITE_TAC[linear; DROP_ADD; DROP_CMUL] THEN VECTOR_ARITH_TAC; + MATCH_MP_TAC HAS_DERIVATIVE_WITHIN_SUBSET THEN + EXISTS_TAC `s:real^N->bool` THEN CONJ_TAC THENL + [FIRST_X_ASSUM MATCH_MP_TAC; + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE] THEN GEN_TAC THEN DISCH_TAC] THEN + FIRST_ASSUM(MATCH_MP_TAC o GEN_REWRITE_RULE I [CONVEX_ALT]) THEN + RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1; LIFT_DROP; DROP_VEC]) THEN + ASM_REWRITE_TAC[] THEN ASM_REAL_ARITH_TAC]); + REWRITE_TAC[REAL_SUB_REFL; VECTOR_MUL_LZERO; VECTOR_ADD_LID] THEN + REWRITE_TAC[EXISTS_LIFT; LIFT_DROP; IN_INTERVAL_1; DROP_VEC] THEN + REWRITE_TAC[GSYM LIFT_SUB; LIFT_EQ] THEN + REWRITE_TAC[DROP_SUB; DROP_VEC; LIFT_DROP] THEN + REWRITE_TAC[VECTOR_ARITH `--u % a + u % b:real^N = u % (b - a)`] THEN + REWRITE_TAC[LEFT_IMP_EXISTS_THM; RIGHT_IMP_FORALL_THM] THEN + MAP_EVERY X_GEN_TAC [`w:real`; `v:real`] THEN + DISCH_THEN(CONJUNCTS_THEN2 STRIP_ASSUME_TAC MP_TAC) THEN + ONCE_REWRITE_TAC[TAUT `a ==> b /\ c ==> d <=> b ==> a ==> c ==> d`] THEN + STRIP_TAC THEN REWRITE_TAC[IMP_IMP] THEN + DISCH_THEN(CONJUNCTS_THEN2 (MP_TAC o AP_TERM `(*) (u:real)`) + (MP_TAC o AP_TERM `(*) (&1 - u:real)`)) THEN + MATCH_MP_TAC(REAL_ARITH + `f1 <= f2 /\ (xa <= xb ==> a <= b) + ==> xa = f1 ==> xb = f2 ==> a <= b`) THEN + CONJ_TAC THENL [ALL_TAC; REAL_ARITH_TAC] THEN + SUBGOAL_THEN + `((&1 - v) % a + v % b:real^N) IN s /\ + ((&1 - w) % a + w % b:real^N) IN s` + STRIP_ASSUME_TAC THENL + [CONJ_TAC THEN + FIRST_X_ASSUM(MATCH_MP_TAC o GEN_REWRITE_RULE I [CONVEX_ALT]) THEN + ASM_REWRITE_TAC[] THEN ASM_REAL_ARITH_TAC; + ALL_TAC] THEN + SUBGOAL_THEN + `linear(lift o (f'((&1 - v) % a + v % b:real^N):real^N->real)) /\ + linear(lift o (f'((&1 - w) % a + w % b:real^N):real^N->real))` + MP_TAC THENL [ASM_MESON_TAC[has_derivative]; ALL_TAC] THEN + DISCH_THEN(CONJUNCTS_THEN(MP_TAC o MATCH_MP LINEAR_CMUL)) THEN + ASM_REWRITE_TAC[o_THM; GSYM LIFT_NEG; GSYM LIFT_CMUL; LIFT_EQ] THEN + REPEAT DISCH_TAC THEN ASM_REWRITE_TAC[] THEN + ONCE_REWRITE_TAC[REAL_ARITH `(&1 - u) * u * x = u * (&1 - u) * x`] THEN + REPEAT(MATCH_MP_TAC REAL_LE_LMUL THEN + CONJ_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC]) THEN + FIRST_X_ASSUM(MP_TAC o SPECL + [`(&1 - v) % a + v % b:real^N`; `(&1 - w) % a + w % b:real^N`]) THEN + ASM_REWRITE_TAC[VECTOR_ARITH + `((&1 - v) % a + v % b) - ((&1 - w) % a + w % b):real^N = + (v - w) % (b - a)`] THEN + ASM_CASES_TAC `v:real = w` THEN ASM_SIMP_TAC[REAL_LE_REFL] THEN + SUBGOAL_THEN `&0 < w - v` (fun th -> SIMP_TAC[th; REAL_LE_LMUL_EQ]) THEN + ASM_REAL_ARITH_TAC]);; + +let CONVEX_ON_SECANT_DERIVATIVE = prove + (`!f f' s:real^N->bool. + convex s /\ + (!x. x IN s ==> ((lift o f) has_derivative (lift o f'(x))) + (at x within s)) + ==> (f convex_on s <=> + !x y. x IN s /\ y IN s ==> f y - f x <= f'(y)(y - x))`, + REPEAT GEN_TAC THEN DISCH_TAC THEN + FIRST_ASSUM(SUBST1_TAC o MATCH_MP CONVEX_ON_DERIVATIVE_SECANT) THEN + GEN_REWRITE_TAC RAND_CONV [SWAP_FORALL_THM] THEN + AP_TERM_TAC THEN GEN_REWRITE_TAC I [FUN_EQ_THM] THEN + X_GEN_TAC `x:real^N` THEN REWRITE_TAC[] THEN + AP_TERM_TAC THEN GEN_REWRITE_TAC I [FUN_EQ_THM] THEN + X_GEN_TAC `y:real^N` THEN REWRITE_TAC[] THEN + MAP_EVERY ASM_CASES_TAC [`(x:real^N) IN s`; `(y:real^N) IN s`] THEN + ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC(REAL_ARITH + `f' = --f'' ==> (f' <= y - x <=> x - y <= f'')`) THEN + GEN_REWRITE_TAC (LAND_CONV o RAND_CONV) [GSYM VECTOR_NEG_SUB] THEN + GEN_REWRITE_TAC I [GSYM LIFT_EQ] THEN REWRITE_TAC[LIFT_NEG] THEN + SPEC_TAC(`x - y:real^N`,`z:real^N`) THEN + MATCH_MP_TAC(REWRITE_RULE[RIGHT_FORALL_IMP_THM] LINEAR_NEG) THEN + REWRITE_TAC[GSYM o_DEF] THEN + REWRITE_TAC[GSYM I_DEF; I_O_ID] THEN ASM_MESON_TAC[has_derivative]);; diff --git a/Multivariate/determinants.ml b/Multivariate/determinants.ml new file mode 100644 index 0000000..4033193 --- /dev/null +++ b/Multivariate/determinants.ml @@ -0,0 +1,3136 @@ +(* ========================================================================= *) +(* Determinant and trace of a square matrix. *) +(* *) +(* (c) Copyright, John Harrison 1998-2008 *) +(* ========================================================================= *) + +needs "Multivariate/vectors.ml";; +needs "Library/permutations.ml";; +needs "Library/floor.ml";; +needs "Library/products.ml";; + +prioritize_real();; + +(* ------------------------------------------------------------------------- *) +(* Trace of a matrix (this is relatively easy). *) +(* ------------------------------------------------------------------------- *) + +let trace = new_definition + `(trace:real^N^N->real) A = sum(1..dimindex(:N)) (\i. A$i$i)`;; + +let TRACE_0 = prove + (`trace(mat 0) = &0`, + SIMP_TAC[trace; mat; LAMBDA_BETA; SUM_0]);; + +let TRACE_I = prove + (`trace(mat 1 :real^N^N) = &(dimindex(:N))`, + SIMP_TAC[trace; mat; LAMBDA_BETA; SUM_CONST_NUMSEG; REAL_MUL_RID] THEN + AP_TERM_TAC THEN ARITH_TAC);; + +let TRACE_ADD = prove + (`!A B:real^N^N. trace(A + B) = trace(A) + trace(B)`, + SIMP_TAC[trace; matrix_add; SUM_ADD_NUMSEG; LAMBDA_BETA]);; + +let TRACE_SUB = prove + (`!A B:real^N^N. trace(A - B) = trace(A) - trace(B)`, + SIMP_TAC[trace; matrix_sub; SUM_SUB_NUMSEG; LAMBDA_BETA]);; + +let TRACE_MUL_SYM = prove + (`!A B:real^N^N. trace(A ** B) = trace(B ** A)`, + REPEAT GEN_TAC THEN SIMP_TAC[trace; matrix_mul; LAMBDA_BETA] THEN + GEN_REWRITE_TAC RAND_CONV [SUM_SWAP_NUMSEG] THEN REWRITE_TAC[REAL_MUL_SYM]);; + +let TRACE_TRANSP = prove + (`!A:real^N^N. trace(transp A) = trace A`, + SIMP_TAC[trace; transp; LAMBDA_BETA]);; + +let TRACE_CONJUGATE = prove + (`!A:real^N^N U:real^N^N. + invertible U ==> trace(matrix_inv U ** A ** U) = trace A`, + REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[TRACE_MUL_SYM] THEN + ASM_SIMP_TAC[GSYM MATRIX_MUL_ASSOC; MATRIX_INV; MATRIX_MUL_RID]);; + +(* ------------------------------------------------------------------------- *) +(* Definition of determinant. *) +(* ------------------------------------------------------------------------- *) + +let det = new_definition + `det(A:real^N^N) = + sum { p | p permutes 1..dimindex(:N) } + (\p. sign(p) * product (1..dimindex(:N)) (\i. A$i$(p i)))`;; + +(* ------------------------------------------------------------------------- *) +(* A few general lemmas we need below. *) +(* ------------------------------------------------------------------------- *) + +let IN_DIMINDEX_SWAP = prove + (`!m n j. 1 <= m /\ m <= dimindex(:N) /\ + 1 <= n /\ n <= dimindex(:N) /\ + 1 <= j /\ j <= dimindex(:N) + ==> 1 <= swap(m,n) j /\ swap(m,n) j <= dimindex(:N)`, + REWRITE_TAC[swap] THEN ARITH_TAC);; + +let LAMBDA_BETA_PERM = prove + (`!p i. p permutes 1..dimindex(:N) /\ 1 <= i /\ i <= dimindex(:N) + ==> ((lambda) g :A^N) $ p(i) = g(p i)`, + ASM_MESON_TAC[LAMBDA_BETA; PERMUTES_IN_IMAGE; IN_NUMSEG]);; + +let PRODUCT_PERMUTE = prove + (`!f p s. p permutes s ==> product s f = product s (f o p)`, + REWRITE_TAC[product] THEN MATCH_MP_TAC ITERATE_PERMUTE THEN + REWRITE_TAC[MONOIDAL_REAL_MUL]);; + +let PRODUCT_PERMUTE_NUMSEG = prove + (`!f p m n. p permutes m..n ==> product(m..n) f = product(m..n) (f o p)`, + MESON_TAC[PRODUCT_PERMUTE; FINITE_NUMSEG]);; + +let REAL_MUL_SUM = prove + (`!s t f g. + FINITE s /\ FINITE t + ==> sum s f * sum t g = sum s (\i. sum t (\j. f(i) * g(j)))`, + SIMP_TAC[SUM_LMUL] THEN + ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN SIMP_TAC[SUM_LMUL]);; + +let REAL_MUL_SUM_NUMSEG = prove + (`!m n p q. sum(m..n) f * sum(p..q) g = + sum(m..n) (\i. sum(p..q) (\j. f(i) * g(j)))`, + SIMP_TAC[REAL_MUL_SUM; FINITE_NUMSEG]);; + +(* ------------------------------------------------------------------------- *) +(* Basic determinant properties. *) +(* ------------------------------------------------------------------------- *) + +let DET_CMUL = prove + (`!A:real^N^N c. det(c %% A) = c pow dimindex(:N) * det A`, + REPEAT GEN_TAC THEN + SIMP_TAC[det; MATRIX_CMUL_COMPONENT; PRODUCT_MUL; FINITE_NUMSEG] THEN + SIMP_TAC[PRODUCT_CONST_NUMSEG_1; GSYM SUM_LMUL] THEN + REWRITE_TAC[REAL_MUL_AC]);; + +let DET_NEG = prove + (`!A:real^N^N. det(--A) = --(&1) pow dimindex(:N) * det A`, + REWRITE_TAC[MATRIX_NEG_MINUS1; DET_CMUL]);; + +let DET_TRANSP = prove + (`!A:real^N^N. det(transp A) = det A`, + GEN_TAC THEN REWRITE_TAC[det] THEN + GEN_REWRITE_TAC LAND_CONV [SUM_PERMUTATIONS_INVERSE] THEN + MATCH_MP_TAC SUM_EQ THEN + SIMP_TAC[FINITE_PERMUTATIONS; FINITE_NUMSEG] THEN X_GEN_TAC `p:num->num` THEN + REWRITE_TAC[IN_ELIM_THM] THEN DISCH_TAC THEN BINOP_TAC THENL + [ASM_MESON_TAC[SIGN_INVERSE; PERMUTATION_PERMUTES; FINITE_NUMSEG]; + ALL_TAC] THEN + FIRST_ASSUM(fun th -> GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) + [GSYM(MATCH_MP PERMUTES_IMAGE th)]) THEN + MATCH_MP_TAC EQ_TRANS THEN EXISTS_TAC + `product(1..dimindex(:N)) + ((\i. (transp A:real^N^N)$i$inverse p(i)) o p)` THEN + CONJ_TAC THENL + [MATCH_MP_TAC PRODUCT_IMAGE THEN + ASM_MESON_TAC[FINITE_NUMSEG; PERMUTES_INJECTIVE; PERMUTES_INVERSE]; + MATCH_MP_TAC PRODUCT_EQ THEN REWRITE_TAC[FINITE_NUMSEG; IN_NUMSEG] THEN + SIMP_TAC[transp; LAMBDA_BETA; o_THM] THEN + FIRST_ASSUM(MP_TAC o MATCH_MP PERMUTES_INVERSES_o) THEN + SIMP_TAC[FUN_EQ_THM; I_THM; o_THM] THEN STRIP_TAC THEN + ASM_SIMP_TAC[PERMUTES_IN_NUMSEG; LAMBDA_BETA_PERM; LAMBDA_BETA]]);; + +let DET_LOWERTRIANGULAR = prove + (`!A:real^N^N. + (!i j. 1 <= i /\ i <= dimindex(:N) /\ + 1 <= j /\ j <= dimindex(:N) /\ i < j ==> A$i$j = &0) + ==> det(A) = product(1..dimindex(:N)) (\i. A$i$i)`, + REPEAT STRIP_TAC THEN REWRITE_TAC[det] THEN MATCH_MP_TAC EQ_TRANS THEN + EXISTS_TAC `sum {I} + (\p. sign p * product(1..dimindex(:N)) (\i. (A:real^N^N)$i$p(i)))` THEN + CONJ_TAC THENL + [ALL_TAC; REWRITE_TAC[SUM_SING; SIGN_I; REAL_MUL_LID; I_THM]] THEN + MATCH_MP_TAC SUM_SUPERSET THEN + SIMP_TAC[IN_SING; FINITE_RULES; SUBSET; IN_ELIM_THM; PERMUTES_I] THEN + X_GEN_TAC `p:num->num` THEN STRIP_TAC THEN + ASM_REWRITE_TAC[PRODUCT_EQ_0_NUMSEG; REAL_ENTIRE; SIGN_NZ] THEN + MP_TAC(SPECL [`p:num->num`; `1..dimindex(:N)`] PERMUTES_NUMSET_LE) THEN + ASM_MESON_TAC[PERMUTES_IN_IMAGE; IN_NUMSEG; NOT_LT]);; + +let DET_UPPERTRIANGULAR = prove + (`!A:real^N^N. + (!i j. 1 <= i /\ i <= dimindex(:N) /\ + 1 <= j /\ j <= dimindex(:N) /\ j < i ==> A$i$j = &0) + ==> det(A) = product(1..dimindex(:N)) (\i. A$i$i)`, + REPEAT STRIP_TAC THEN REWRITE_TAC[det] THEN MATCH_MP_TAC EQ_TRANS THEN + EXISTS_TAC `sum {I} + (\p. sign p * product(1..dimindex(:N)) (\i. (A:real^N^N)$i$p(i)))` THEN + CONJ_TAC THENL + [ALL_TAC; REWRITE_TAC[SUM_SING; SIGN_I; REAL_MUL_LID; I_THM]] THEN + MATCH_MP_TAC SUM_SUPERSET THEN + SIMP_TAC[IN_SING; FINITE_RULES; SUBSET; IN_ELIM_THM; PERMUTES_I] THEN + X_GEN_TAC `p:num->num` THEN STRIP_TAC THEN + ASM_REWRITE_TAC[PRODUCT_EQ_0_NUMSEG; REAL_ENTIRE; SIGN_NZ] THEN + MP_TAC(SPECL [`p:num->num`; `1..dimindex(:N)`] PERMUTES_NUMSET_GE) THEN + ASM_MESON_TAC[PERMUTES_IN_IMAGE; IN_NUMSEG; NOT_LT]);; + +let DET_DIAGONAL = prove + (`!A:real^N^N. + (!i j. 1 <= i /\ i <= dimindex(:N) /\ + 1 <= j /\ j <= dimindex(:N) /\ ~(i = j) ==> A$i$j = &0) + ==> det(A) = product(1..dimindex(:N)) (\i. A$i$i)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC DET_LOWERTRIANGULAR THEN + REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[] THEN + ASM_MESON_TAC[LT_REFL]);; + +let DET_I = prove + (`det(mat 1 :real^N^N) = &1`, + MATCH_MP_TAC EQ_TRANS THEN + EXISTS_TAC `product(1..dimindex(:N)) (\i. (mat 1:real^N^N)$i$i)` THEN + CONJ_TAC THENL + [MATCH_MP_TAC DET_LOWERTRIANGULAR; + MATCH_MP_TAC PRODUCT_EQ_1_NUMSEG] THEN + SIMP_TAC[mat; LAMBDA_BETA] THEN MESON_TAC[LT_REFL]);; + +let DET_0 = prove + (`det(mat 0 :real^N^N) = &0`, + MATCH_MP_TAC EQ_TRANS THEN + EXISTS_TAC `product(1..dimindex(:N)) (\i. (mat 0:real^N^N)$i$i)` THEN + CONJ_TAC THENL + [MATCH_MP_TAC DET_LOWERTRIANGULAR; + REWRITE_TAC[PRODUCT_EQ_0_NUMSEG] THEN EXISTS_TAC `1`] THEN + SIMP_TAC[mat; LAMBDA_BETA; COND_ID; DIMINDEX_GE_1; LE_REFL]);; + +let DET_PERMUTE_ROWS = prove + (`!A:real^N^N p. + p permutes 1..dimindex(:N) + ==> det(lambda i. A$p(i)) = sign(p) * det(A)`, + REWRITE_TAC[det] THEN SIMP_TAC[LAMBDA_BETA] THEN REPEAT STRIP_TAC THEN + SIMP_TAC[GSYM SUM_LMUL; FINITE_PERMUTATIONS; FINITE_NUMSEG] THEN + FIRST_ASSUM(fun th -> GEN_REWRITE_TAC LAND_CONV + [MATCH_MP SUM_PERMUTATIONS_COMPOSE_R th]) THEN + MATCH_MP_TAC SUM_EQ THEN + SIMP_TAC[FINITE_PERMUTATIONS; FINITE_NUMSEG] THEN X_GEN_TAC `q:num->num` THEN + REWRITE_TAC[IN_ELIM_THM; REAL_MUL_ASSOC] THEN DISCH_TAC THEN BINOP_TAC THENL + [ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN + ASM_MESON_TAC[SIGN_COMPOSE; PERMUTATION_PERMUTES; FINITE_NUMSEG]; + ALL_TAC] THEN + MP_TAC(MATCH_MP PERMUTES_INVERSE (ASSUME `p permutes 1..dimindex(:N)`)) THEN + DISCH_THEN(fun th -> GEN_REWRITE_TAC LAND_CONV + [MATCH_MP PRODUCT_PERMUTE_NUMSEG th]) THEN + MATCH_MP_TAC PRODUCT_EQ THEN REWRITE_TAC[IN_NUMSEG; FINITE_NUMSEG] THEN + REPEAT STRIP_TAC THEN REWRITE_TAC[o_THM] THEN + ASM_MESON_TAC[PERMUTES_INVERSES]);; + +let DET_PERMUTE_COLUMNS = prove + (`!A:real^N^N p. + p permutes 1..dimindex(:N) + ==> det((lambda i j. A$i$p(j)):real^N^N) = sign(p) * det(A)`, + REPEAT STRIP_TAC THEN + GEN_REWRITE_TAC (funpow 2 RAND_CONV) [GSYM DET_TRANSP] THEN + FIRST_ASSUM(fun th -> ONCE_REWRITE_TAC + [GSYM(MATCH_MP DET_PERMUTE_ROWS th)]) THEN + GEN_REWRITE_TAC RAND_CONV [GSYM DET_TRANSP] THEN AP_TERM_TAC THEN + ASM_SIMP_TAC[CART_EQ; transp; LAMBDA_BETA; LAMBDA_BETA_PERM]);; + +let DET_IDENTICAL_ROWS = prove + (`!A:real^N^N i j. 1 <= i /\ i <= dimindex(:N) /\ + 1 <= j /\ j <= dimindex(:N) /\ ~(i = j) /\ + row i A = row j A + ==> det A = &0`, + REPEAT STRIP_TAC THEN + MP_TAC(SPECL [`A:real^N^N`; `swap(i:num,j:num)`] DET_PERMUTE_ROWS) THEN + ASM_SIMP_TAC[PERMUTES_SWAP; IN_NUMSEG; SIGN_SWAP] THEN + MATCH_MP_TAC(REAL_ARITH `a = b ==> b = -- &1 * a ==> a = &0`) THEN + AP_TERM_TAC THEN FIRST_X_ASSUM(MP_TAC o SYM) THEN + SIMP_TAC[row; CART_EQ; LAMBDA_BETA] THEN + REWRITE_TAC[swap] THEN ASM_MESON_TAC[]);; + +let DET_IDENTICAL_COLUMNS = prove + (`!A:real^N^N i j. 1 <= i /\ i <= dimindex(:N) /\ + 1 <= j /\ j <= dimindex(:N) /\ ~(i = j) /\ + column i A = column j A + ==> det A = &0`, + REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[GSYM DET_TRANSP] THEN + MATCH_MP_TAC DET_IDENTICAL_ROWS THEN ASM_MESON_TAC[ROW_TRANSP]);; + +let DET_ZERO_ROW = prove + (`!A:real^N^N i. + 1 <= i /\ i <= dimindex(:N) /\ row i A = vec 0 ==> det A = &0`, + SIMP_TAC[det; row; CART_EQ; LAMBDA_BETA; VEC_COMPONENT] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC SUM_EQ_0 THEN + REWRITE_TAC[IN_ELIM_THM; REAL_ENTIRE; SIGN_NZ] THEN REPEAT STRIP_TAC THEN + SIMP_TAC[PRODUCT_EQ_0; FINITE_NUMSEG; IN_NUMSEG] THEN + ASM_MESON_TAC[PERMUTES_IN_IMAGE; IN_NUMSEG]);; + +let DET_ZERO_COLUMN = prove + (`!A:real^N^N i. + 1 <= i /\ i <= dimindex(:N) /\ column i A = vec 0 ==> det A = &0`, + REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[GSYM DET_TRANSP] THEN + MATCH_MP_TAC DET_ZERO_ROW THEN ASM_MESON_TAC[ROW_TRANSP]);; + +let DET_ROW_ADD = prove + (`!a b c k. + 1 <= k /\ k <= dimindex(:N) + ==> det((lambda i. if i = k then a + b else c i):real^N^N) = + det((lambda i. if i = k then a else c i):real^N^N) + + det((lambda i. if i = k then b else c i):real^N^N)`, + SIMP_TAC[det; LAMBDA_BETA; GSYM SUM_ADD; + FINITE_PERMUTATIONS; FINITE_NUMSEG] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC SUM_EQ THEN + SIMP_TAC[FINITE_PERMUTATIONS; FINITE_NUMSEG] THEN + X_GEN_TAC `p:num->num` THEN REWRITE_TAC[IN_ELIM_THM] THEN + DISCH_TAC THEN REWRITE_TAC[GSYM REAL_ADD_LDISTRIB] THEN AP_TERM_TAC THEN + SUBGOAL_THEN `1..dimindex(:N) = k INSERT ((1..dimindex(:N)) DELETE k)` + SUBST1_TAC THENL [ASM_MESON_TAC[INSERT_DELETE; IN_NUMSEG]; ALL_TAC] THEN + SIMP_TAC[PRODUCT_CLAUSES; FINITE_DELETE; FINITE_NUMSEG; IN_DELETE] THEN + MATCH_MP_TAC(REAL_RING + `c = a + b /\ y = x:real /\ z = x ==> c * x = a * y + b * z`) THEN + REWRITE_TAC[VECTOR_ADD_COMPONENT] THEN + CONJ_TAC THEN MATCH_MP_TAC PRODUCT_EQ THEN + SIMP_TAC[IN_DELETE; FINITE_DELETE; FINITE_NUMSEG]);; + +let DET_ROW_MUL = prove + (`!a b c k. + 1 <= k /\ k <= dimindex(:N) + ==> det((lambda i. if i = k then c % a else b i):real^N^N) = + c * det((lambda i. if i = k then a else b i):real^N^N)`, + SIMP_TAC[det; LAMBDA_BETA; GSYM SUM_LMUL; + FINITE_PERMUTATIONS; FINITE_NUMSEG] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC SUM_EQ THEN + SIMP_TAC[FINITE_PERMUTATIONS; FINITE_NUMSEG] THEN + X_GEN_TAC `p:num->num` THEN REWRITE_TAC[IN_ELIM_THM] THEN DISCH_TAC THEN + SUBGOAL_THEN `1..dimindex(:N) = k INSERT ((1..dimindex(:N)) DELETE k)` + SUBST1_TAC THENL [ASM_MESON_TAC[INSERT_DELETE; IN_NUMSEG]; ALL_TAC] THEN + SIMP_TAC[PRODUCT_CLAUSES; FINITE_DELETE; FINITE_NUMSEG; IN_DELETE] THEN + MATCH_MP_TAC(REAL_RING + `cp = c * p /\ p1 = p2:real ==> s * cp * p1 = c * s * p * p2`) THEN + REWRITE_TAC[VECTOR_MUL_COMPONENT] THEN MATCH_MP_TAC PRODUCT_EQ THEN + SIMP_TAC[IN_DELETE; FINITE_DELETE; FINITE_NUMSEG]);; + +let DET_ROW_OPERATION = prove + (`!A:real^N^N i. + 1 <= i /\ i <= dimindex(:N) /\ + 1 <= j /\ j <= dimindex(:N) /\ ~(i = j) + ==> det(lambda k. if k = i then row i A + c % row j A else row k A) = + det A`, + REPEAT STRIP_TAC THEN ASM_SIMP_TAC[DET_ROW_ADD; DET_ROW_MUL] THEN + MATCH_MP_TAC(REAL_RING `a = b /\ d = &0 ==> a + c * d = b`) THEN + CONJ_TAC THENL + [AP_TERM_TAC THEN ASM_SIMP_TAC[LAMBDA_BETA; CART_EQ] THEN + REPEAT STRIP_TAC THEN COND_CASES_TAC THEN + ASM_SIMP_TAC[row; LAMBDA_BETA; CART_EQ]; + MATCH_MP_TAC DET_IDENTICAL_ROWS THEN + MAP_EVERY EXISTS_TAC [`i:num`; `j:num`] THEN + ASM_SIMP_TAC[row; LAMBDA_BETA; CART_EQ]]);; + +let DET_ROW_SPAN = prove + (`!A:real^N^N i x. + 1 <= i /\ i <= dimindex(:N) /\ + x IN span {row j A | 1 <= j /\ j <= dimindex(:N) /\ ~(j = i)} + ==> det(lambda k. if k = i then row i A + x else row k A) = + det A`, + GEN_TAC THEN GEN_TAC THEN + REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN REPEAT DISCH_TAC THEN + MATCH_MP_TAC SPAN_INDUCT_ALT THEN CONJ_TAC THENL + [AP_TERM_TAC THEN SIMP_TAC[CART_EQ; LAMBDA_BETA; VECTOR_ADD_RID] THEN + REPEAT STRIP_TAC THEN COND_CASES_TAC THEN ASM_SIMP_TAC[row; LAMBDA_BETA]; + ALL_TAC] THEN + REPEAT GEN_TAC THEN REWRITE_TAC[IN_ELIM_THM] THEN + DISCH_THEN(CONJUNCTS_THEN2 (X_CHOOSE_TAC `j:num`) (SUBST_ALL_TAC o SYM)) THEN + ONCE_REWRITE_TAC[VECTOR_ARITH + `a + c % x + y:real^N = (a + y) + c % x`] THEN + ABBREV_TAC `z = row i (A:real^N^N) + y` THEN + ASM_SIMP_TAC[DET_ROW_MUL; DET_ROW_ADD] THEN + MATCH_MP_TAC(REAL_RING `d = &0 ==> a + c * d = a`) THEN + MATCH_MP_TAC DET_IDENTICAL_ROWS THEN + MAP_EVERY EXISTS_TAC [`i:num`; `j:num`] THEN + ASM_SIMP_TAC[row; LAMBDA_BETA; CART_EQ]);; + +(* ------------------------------------------------------------------------- *) +(* May as well do this, though it's a bit unsatisfactory since it ignores *) +(* exact duplicates by considering the rows/columns as a set. *) +(* ------------------------------------------------------------------------- *) + +let DET_DEPENDENT_ROWS = prove + (`!A:real^N^N. dependent(rows A) ==> det A = &0`, + GEN_TAC THEN + REWRITE_TAC[dependent; rows; IN_ELIM_THM; LEFT_AND_EXISTS_THM] THEN + REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN GEN_TAC THEN X_GEN_TAC `i:num` THEN + STRIP_TAC THEN FIRST_X_ASSUM SUBST_ALL_TAC THEN + ASM_CASES_TAC + `?i j. 1 <= i /\ i <= dimindex(:N) /\ + 1 <= j /\ j <= dimindex(:N) /\ ~(i = j) /\ + row i (A:real^N^N) = row j A` + THENL [ASM_MESON_TAC[DET_IDENTICAL_ROWS]; ALL_TAC] THEN + MP_TAC(SPECL [`A:real^N^N`; `i:num`; `--(row i (A:real^N^N))`] + DET_ROW_SPAN) THEN + ANTS_TAC THENL + [ASM_REWRITE_TAC[] THEN MATCH_MP_TAC SPAN_NEG THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN]) THEN + MATCH_MP_TAC(TAUT `a = b ==> a ==> b`) THEN + REWRITE_TAC[IN] THEN AP_THM_TAC THEN AP_TERM_TAC THEN + REWRITE_TAC[EXTENSION; IN_DELETE; IN_ELIM_THM] THEN ASM_MESON_TAC[]; + DISCH_THEN(SUBST1_TAC o SYM) THEN MATCH_MP_TAC DET_ZERO_ROW THEN + EXISTS_TAC `i:num` THEN + ASM_SIMP_TAC[row; LAMBDA_BETA; CART_EQ; VECTOR_ADD_COMPONENT; + VECTOR_NEG_COMPONENT; VEC_COMPONENT] THEN + REAL_ARITH_TAC]);; + +let DET_DEPENDENT_COLUMNS = prove + (`!A:real^N^N. dependent(columns A) ==> det A = &0`, + MESON_TAC[DET_DEPENDENT_ROWS; ROWS_TRANSP; DET_TRANSP]);; + +(* ------------------------------------------------------------------------- *) +(* Multilinearity and the multiplication formula. *) +(* ------------------------------------------------------------------------- *) + +let DET_LINEAR_ROW_VSUM = prove + (`!a c s k. + FINITE s /\ 1 <= k /\ k <= dimindex(:N) + ==> det((lambda i. if i = k then vsum s a else c i):real^N^N) = + sum s + (\j. det((lambda i. if i = k then a(j) else c i):real^N^N))`, + GEN_TAC THEN GEN_TAC THEN ONCE_REWRITE_TAC[IMP_CONJ] THEN + REWRITE_TAC[RIGHT_FORALL_IMP_THM] THEN + MATCH_MP_TAC FINITE_INDUCT_STRONG THEN + SIMP_TAC[VSUM_CLAUSES; SUM_CLAUSES; DET_ROW_ADD] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC DET_ZERO_ROW THEN EXISTS_TAC `k:num` THEN + ASM_SIMP_TAC[row; LAMBDA_BETA; CART_EQ; VEC_COMPONENT]);; + +let BOUNDED_FUNCTIONS_BIJECTIONS_1 = prove + (`!p. p IN {(y,g) | y IN s /\ + g IN {f | (!i. 1 <= i /\ i <= k ==> f i IN s) /\ + (!i. ~(1 <= i /\ i <= k) ==> f i = i)}} + ==> (\(y,g) i. if i = SUC k then y else g(i)) p IN + {f | (!i. 1 <= i /\ i <= SUC k ==> f i IN s) /\ + (!i. ~(1 <= i /\ i <= SUC k) ==> f i = i)} /\ + (\h. h(SUC k),(\i. if i = SUC k then i else h(i))) + ((\(y,g) i. if i = SUC k then y else g(i)) p) = p`, + REWRITE_TAC[FORALL_PAIR_THM; IN_ELIM_PAIR_THM] THEN + CONV_TAC(REDEPTH_CONV GEN_BETA_CONV) THEN REWRITE_TAC[IN_ELIM_THM] THEN + MAP_EVERY X_GEN_TAC [`y:num`; `h:num->num`] THEN REPEAT STRIP_TAC THENL + [ASM_MESON_TAC[LE]; + ASM_MESON_TAC[LE; ARITH_RULE `~(1 <= i /\ i <= SUC k) ==> ~(i = SUC k)`]; + REWRITE_TAC[PAIR_EQ; FUN_EQ_THM] THEN + ASM_MESON_TAC[ARITH_RULE `~(SUC k <= k)`]]);; + +let BOUNDED_FUNCTIONS_BIJECTIONS_2 = prove + (`!h. h IN {f | (!i. 1 <= i /\ i <= SUC k ==> f i IN s) /\ + (!i. ~(1 <= i /\ i <= SUC k) ==> f i = i)} + ==> (\h. h(SUC k),(\i. if i = SUC k then i else h(i))) h IN + {(y,g) | y IN s /\ + g IN {f | (!i. 1 <= i /\ i <= k ==> f i IN s) /\ + (!i. ~(1 <= i /\ i <= k) ==> f i = i)}} /\ + (\(y,g) i. if i = SUC k then y else g(i)) + ((\h. h(SUC k),(\i. if i = SUC k then i else h(i))) h) = h`, + REWRITE_TAC[IN_ELIM_PAIR_THM] THEN + CONV_TAC(REDEPTH_CONV GEN_BETA_CONV) THEN REWRITE_TAC[IN_ELIM_THM] THEN + X_GEN_TAC `h:num->num` THEN REPEAT STRIP_TAC THENL + [FIRST_X_ASSUM MATCH_MP_TAC THEN ARITH_TAC; + ASM_MESON_TAC[ARITH_RULE `i <= k ==> i <= SUC k /\ ~(i = SUC k)`]; + ASM_MESON_TAC[ARITH_RULE `i <= SUC k /\ ~(i = SUC k) ==> i <= k`]; + REWRITE_TAC[FUN_EQ_THM] THEN ASM_MESON_TAC[LE_REFL]]);; + +let FINITE_BOUNDED_FUNCTIONS = prove + (`!s k. FINITE s + ==> FINITE {f | (!i. 1 <= i /\ i <= k ==> f(i) IN s) /\ + (!i. ~(1 <= i /\ i <= k) ==> f(i) = i)}`, + REWRITE_TAC[RIGHT_FORALL_IMP_THM] THEN GEN_TAC THEN DISCH_TAC THEN + INDUCT_TAC THENL + [REWRITE_TAC[ARITH_RULE `~(1 <= i /\ i <= 0)`] THEN + SIMP_TAC[GSYM FUN_EQ_THM; SET_RULE `{x | x = y} = {y}`; FINITE_RULES]; + ALL_TAC] THEN + UNDISCH_TAC `FINITE(s:num->bool)` THEN POP_ASSUM MP_TAC THEN + REWRITE_TAC[TAUT `a ==> b ==> c <=> b /\ a ==> c`] THEN + DISCH_THEN(MP_TAC o MATCH_MP FINITE_PRODUCT) THEN + DISCH_THEN(MP_TAC o ISPEC `\(y:num,g) i. if i = SUC k then y else g(i)` o + MATCH_MP FINITE_IMAGE) THEN + MATCH_MP_TAC(TAUT `a = b ==> a ==> b`) THEN AP_TERM_TAC THEN + REWRITE_TAC[EXTENSION; IN_IMAGE] THEN + X_GEN_TAC `h:num->num` THEN EQ_TAC THENL + [STRIP_TAC THEN ASM_SIMP_TAC[BOUNDED_FUNCTIONS_BIJECTIONS_1]; ALL_TAC] THEN + DISCH_TAC THEN EXISTS_TAC + `(\h. h(SUC k),(\i. if i = SUC k then i else h(i))) h` THEN + PURE_ONCE_REWRITE_TAC[CONJ_SYM] THEN CONV_TAC (RAND_CONV SYM_CONV) THEN + MATCH_MP_TAC BOUNDED_FUNCTIONS_BIJECTIONS_2 THEN ASM_REWRITE_TAC[]);; + +let DET_LINEAR_ROWS_VSUM_LEMMA = prove + (`!s k a c. + FINITE s /\ k <= dimindex(:N) + ==> det((lambda i. if i <= k then vsum s (a i) else c i):real^N^N) = + sum {f | (!i. 1 <= i /\ i <= k ==> f(i) IN s) /\ + !i. ~(1 <= i /\ i <= k) ==> f(i) = i} + (\f. det((lambda i. if i <= k then a i (f i) else c i) + :real^N^N))`, + let lemma = prove + (`(lambda i. if i <= 0 then x(i) else y(i)) = (lambda i. y i)`, + SIMP_TAC[CART_EQ; ARITH; LAMBDA_BETA; ARITH_RULE + `1 <= k ==> ~(k <= 0)`]) in + ONCE_REWRITE_TAC[IMP_CONJ] THEN + REWRITE_TAC[RIGHT_FORALL_IMP_THM] THEN GEN_TAC THEN DISCH_TAC THEN + INDUCT_TAC THENL + [REWRITE_TAC[lemma; LE_0] THEN GEN_TAC THEN + REWRITE_TAC[ARITH_RULE `~(1 <= i /\ i <= 0)`] THEN + REWRITE_TAC[GSYM FUN_EQ_THM; SET_RULE `{x | x = y} = {y}`] THEN + REWRITE_TAC[SUM_SING]; + ALL_TAC] THEN + DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o check (is_imp o concl)) THEN + ASM_SIMP_TAC[ARITH_RULE `SUC k <= n ==> k <= n`] THEN REPEAT STRIP_TAC THEN + GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [LE] THEN + REWRITE_TAC[TAUT + `(if a \/ b then c else d) = (if a then c else if b then c else d)`] THEN + ASM_SIMP_TAC[DET_LINEAR_ROW_VSUM; ARITH_RULE `1 <= SUC k`] THEN + ONCE_REWRITE_TAC[TAUT + `(if a then b else if c then d else e) = + (if c then (if a then b else d) else (if a then b else e))`] THEN + ASM_SIMP_TAC[ARITH_RULE `i <= k ==> ~(i = SUC k)`] THEN + ASM_SIMP_TAC[SUM_SUM_PRODUCT; FINITE_BOUNDED_FUNCTIONS] THEN + MATCH_MP_TAC SUM_EQ_GENERAL_INVERSES THEN + EXISTS_TAC `\(y:num,g) i. if i = SUC k then y else g(i)` THEN + EXISTS_TAC `\h. h(SUC k),(\i. if i = SUC k then i else h(i))` THEN + CONJ_TAC THENL [ACCEPT_TAC BOUNDED_FUNCTIONS_BIJECTIONS_2; ALL_TAC] THEN + X_GEN_TAC `p:num#(num->num)` THEN + DISCH_THEN(STRIP_ASSUME_TAC o MATCH_MP BOUNDED_FUNCTIONS_BIJECTIONS_1) THEN + ASM_REWRITE_TAC[] THEN + SPEC_TAC(`p:num#(num->num)`,`q:num#(num->num)`) THEN + REWRITE_TAC[FORALL_PAIR_THM] THEN + CONV_TAC(ONCE_DEPTH_CONV GEN_BETA_CONV) THEN + MAP_EVERY X_GEN_TAC [`y:num`; `g:num->num`] THEN AP_TERM_TAC THEN + SIMP_TAC[CART_EQ; LAMBDA_BETA] THEN + REPEAT STRIP_TAC THEN REPEAT(COND_CASES_TAC THEN ASM_REWRITE_TAC[]) THEN + ASM_MESON_TAC[LE; ARITH_RULE `~(SUC k <= k)`]);; + +let DET_LINEAR_ROWS_VSUM = prove + (`!s a. + FINITE s + ==> det((lambda i. vsum s (a i)):real^N^N) = + sum {f | (!i. 1 <= i /\ i <= dimindex(:N) ==> f(i) IN s) /\ + !i. ~(1 <= i /\ i <= dimindex(:N)) ==> f(i) = i} + (\f. det((lambda i. a i (f i)):real^N^N))`, + let lemma = prove + (`(lambda i. if i <= dimindex(:N) then x(i) else y(i)):real^N^N = + (lambda i. x(i))`, + SIMP_TAC[CART_EQ; LAMBDA_BETA]) in + REPEAT STRIP_TAC THEN + MP_TAC(SPECL [`s:num->bool`; `dimindex(:N)`] DET_LINEAR_ROWS_VSUM_LEMMA) THEN + ASM_REWRITE_TAC[LE_REFL; lemma] THEN SIMP_TAC[]);; + +let MATRIX_MUL_VSUM_ALT = prove + (`!A:real^N^N B:real^N^N. A ** B = + lambda i. vsum (1..dimindex(:N)) (\k. A$i$k % B$k)`, + SIMP_TAC[matrix_mul; CART_EQ; LAMBDA_BETA; VECTOR_MUL_COMPONENT; + VSUM_COMPONENT]);; + +let DET_ROWS_MUL = prove + (`!a c. det((lambda i. c(i) % a(i)):real^N^N) = + product(1..dimindex(:N)) (\i. c(i)) * + det((lambda i. a(i)):real^N^N)`, + REPEAT GEN_TAC THEN SIMP_TAC[det; LAMBDA_BETA] THEN + SIMP_TAC[GSYM SUM_LMUL; FINITE_PERMUTATIONS; FINITE_NUMSEG] THEN + MATCH_MP_TAC SUM_EQ THEN SIMP_TAC[FINITE_PERMUTATIONS; FINITE_NUMSEG] THEN + X_GEN_TAC `p:num->num` THEN REWRITE_TAC[IN_ELIM_THM] THEN DISCH_TAC THEN + MATCH_MP_TAC(REAL_RING `b = c * d ==> s * b = c * s * d`) THEN + SIMP_TAC[GSYM PRODUCT_MUL_NUMSEG] THEN + MATCH_MP_TAC PRODUCT_EQ_NUMSEG THEN + ASM_MESON_TAC[PERMUTES_IN_IMAGE; IN_NUMSEG; VECTOR_MUL_COMPONENT]);; + +let DET_MUL = prove + (`!A B:real^N^N. det(A ** B) = det(A) * det(B)`, + REPEAT GEN_TAC THEN REWRITE_TAC[MATRIX_MUL_VSUM_ALT] THEN + SIMP_TAC[DET_LINEAR_ROWS_VSUM; FINITE_NUMSEG] THEN + MATCH_MP_TAC EQ_TRANS THEN + EXISTS_TAC `sum {p | p permutes 1..dimindex(:N)} + (\f. det (lambda i. (A:real^N^N)$i$f i % (B:real^N^N)$f i))` THEN + CONJ_TAC THENL + [REWRITE_TAC[DET_ROWS_MUL] THEN + MATCH_MP_TAC SUM_SUPERSET THEN + SIMP_TAC[FINITE_PERMUTATIONS; FINITE_NUMSEG] THEN + REWRITE_TAC[SUBSET; IN_ELIM_THM] THEN CONJ_TAC THENL + [MESON_TAC[permutes; IN_NUMSEG]; ALL_TAC] THEN + X_GEN_TAC `f:num->num` THEN REWRITE_TAC[permutes; IN_NUMSEG] THEN + DISCH_THEN(CONJUNCTS_THEN2 STRIP_ASSUME_TAC MP_TAC) THEN + ASM_REWRITE_TAC[] THEN DISCH_TAC THEN + REWRITE_TAC[REAL_ENTIRE] THEN DISJ2_TAC THEN + MATCH_MP_TAC DET_IDENTICAL_ROWS THEN + MP_TAC(ISPECL [`1..dimindex(:N)`; `f:num->num`] + SURJECTIVE_IFF_INJECTIVE) THEN + ASM_REWRITE_TAC[SUBSET; IN_NUMSEG; FINITE_NUMSEG; FORALL_IN_IMAGE] THEN + MATCH_MP_TAC(TAUT `(~b ==> c) /\ (b ==> ~a) ==> (a <=> b) ==> c`) THEN + CONJ_TAC THENL + [REWRITE_TAC[NOT_FORALL_THM] THEN + REPEAT(MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC) THEN + SIMP_TAC[CART_EQ; LAMBDA_BETA; row; NOT_IMP]; + ALL_TAC] THEN + DISCH_TAC THEN + SUBGOAL_THEN `!x y. (f:num->num)(x) = f(y) ==> x = y` ASSUME_TAC THENL + [REPEAT GEN_TAC THEN + ASM_CASES_TAC `1 <= x /\ x <= dimindex(:N)` THEN + ASM_CASES_TAC `1 <= y /\ y <= dimindex(:N)` THEN + ASM_MESON_TAC[]; + ALL_TAC] THEN + ASM_MESON_TAC[]; + ALL_TAC] THEN + SIMP_TAC[det; REAL_MUL_SUM; FINITE_PERMUTATIONS; FINITE_NUMSEG] THEN + MATCH_MP_TAC SUM_EQ THEN SIMP_TAC[FINITE_PERMUTATIONS; FINITE_NUMSEG] THEN + X_GEN_TAC `p:num->num` THEN REWRITE_TAC[IN_ELIM_THM] THEN DISCH_TAC THEN + FIRST_ASSUM(fun th -> GEN_REWRITE_TAC RAND_CONV + [MATCH_MP SUM_PERMUTATIONS_COMPOSE_R (MATCH_MP PERMUTES_INVERSE th)]) THEN + MATCH_MP_TAC SUM_EQ THEN SIMP_TAC[FINITE_PERMUTATIONS; FINITE_NUMSEG] THEN + X_GEN_TAC `q:num->num` THEN REWRITE_TAC[IN_ELIM_THM] THEN DISCH_TAC THEN + REWRITE_TAC[o_THM] THEN ONCE_REWRITE_TAC[AC REAL_MUL_AC + `(p * x) * (q * y) = (p * q) * (x * y)`] THEN + BINOP_TAC THENL + [SUBGOAL_THEN `sign(q o inverse p) = sign(p:num->num) * sign(q:num->num)` + (fun t -> SIMP_TAC[REAL_MUL_ASSOC; SIGN_IDEMPOTENT; REAL_MUL_LID; t]) THEN + ASM_MESON_TAC[SIGN_COMPOSE; PERMUTES_INVERSE; PERMUTATION_PERMUTES; + FINITE_NUMSEG; SIGN_INVERSE; REAL_MUL_SYM]; + ALL_TAC] THEN + GEN_REWRITE_TAC (RAND_CONV o RAND_CONV) + [MATCH_MP PRODUCT_PERMUTE_NUMSEG (ASSUME `p permutes 1..dimindex(:N)`)] THEN + SIMP_TAC[GSYM PRODUCT_MUL; FINITE_NUMSEG] THEN + MATCH_MP_TAC PRODUCT_EQ_NUMSEG THEN + ASM_SIMP_TAC[LAMBDA_BETA; LAMBDA_BETA_PERM; o_THM] THEN + X_GEN_TAC `i:num` THEN STRIP_TAC THEN MATCH_MP_TAC EQ_TRANS THEN + EXISTS_TAC `(A:real^N^N)$i$p(i) * (B:real^N^N)$p(i)$q(i)` THEN CONJ_TAC THENL + [ASM_MESON_TAC[VECTOR_MUL_COMPONENT; PERMUTES_IN_IMAGE; IN_NUMSEG]; + ASM_MESON_TAC[PERMUTES_INVERSES]]);; + +(* ------------------------------------------------------------------------- *) +(* Relation to invertibility. *) +(* ------------------------------------------------------------------------- *) + +let INVERTIBLE_DET_NZ = prove + (`!A:real^N^N. invertible(A) <=> ~(det A = &0)`, + GEN_TAC THEN EQ_TAC THENL + [REWRITE_TAC[INVERTIBLE_RIGHT_INVERSE; LEFT_IMP_EXISTS_THM] THEN + GEN_TAC THEN DISCH_THEN(MP_TAC o AP_TERM `det:real^N^N->real`) THEN + REWRITE_TAC[DET_MUL; DET_I] THEN CONV_TAC REAL_RING; + ALL_TAC] THEN + ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN + REWRITE_TAC[INVERTIBLE_RIGHT_INVERSE] THEN + REWRITE_TAC[MATRIX_RIGHT_INVERTIBLE_INDEPENDENT_ROWS] THEN + REWRITE_TAC[NOT_FORALL_THM; NOT_IMP] THEN + REWRITE_TAC[RIGHT_AND_EXISTS_THM; LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`c:num->real`; `i:num`] THEN STRIP_TAC THEN + MP_TAC(SPECL [`A:real^N^N`; `i:num`; `--(row i (A:real^N^N))`] + DET_ROW_SPAN) THEN + ANTS_TAC THENL + [ASM_REWRITE_TAC[] THEN + SUBGOAL_THEN + `--(row i (A:real^N^N)) = + vsum ((1..dimindex(:N)) DELETE i) (\j. inv(c i) % c j % row j A)` + SUBST1_TAC THENL + [ASM_SIMP_TAC[VSUM_DELETE_CASES; FINITE_NUMSEG; IN_NUMSEG; VSUM_LMUL] THEN + ASM_SIMP_TAC[VECTOR_MUL_ASSOC; REAL_MUL_LINV] THEN VECTOR_ARITH_TAC; + ALL_TAC] THEN + MATCH_MP_TAC SPAN_VSUM THEN + REWRITE_TAC[FINITE_NUMSEG; IN_NUMSEG; FINITE_DELETE; IN_DELETE] THEN + X_GEN_TAC `j:num` THEN STRIP_TAC THEN REPEAT(MATCH_MP_TAC SPAN_MUL) THEN + MATCH_MP_TAC(CONJUNCT1 SPAN_CLAUSES) THEN + REWRITE_TAC[IN_ELIM_THM] THEN ASM_MESON_TAC[]; + ALL_TAC] THEN + DISCH_THEN(SUBST1_TAC o SYM) THEN MATCH_MP_TAC DET_ZERO_ROW THEN + EXISTS_TAC `i:num` THEN + ASM_SIMP_TAC[row; CART_EQ; LAMBDA_BETA; VEC_COMPONENT; + VECTOR_ARITH `x + --x:real^N = vec 0`]);; + +let DET_EQ_0 = prove + (`!A:real^N^N. det(A) = &0 <=> ~invertible(A)`, + REWRITE_TAC[INVERTIBLE_DET_NZ]);; + +let MATRIX_MUL_LINV = prove + (`!A:real^N^N. ~(det A = &0) ==> matrix_inv A ** A = mat 1`, + SIMP_TAC[MATRIX_INV; DET_EQ_0]);; + +let MATRIX_MUL_RINV = prove + (`!A:real^N^N. ~(det A = &0) ==> A ** matrix_inv A = mat 1`, + SIMP_TAC[MATRIX_INV; DET_EQ_0]);; + +let DET_MATRIX_EQ_0 = prove + (`!f:real^N->real^N. + linear f + ==> (det(matrix f) = &0 <=> + ~(?g. linear g /\ f o g = I /\ g o f = I))`, + SIMP_TAC[DET_EQ_0; MATRIX_INVERTIBLE]);; + +let DET_MATRIX_EQ_0_LEFT = prove + (`!f:real^N->real^N. + linear f + ==> (det(matrix f) = &0 <=> + ~(?g. linear g /\ g o f = I))`, + SIMP_TAC[DET_MATRIX_EQ_0] THEN MESON_TAC[LINEAR_INVERSE_LEFT]);; + +let DET_MATRIX_EQ_0_RIGHT = prove + (`!f:real^N->real^N. + linear f + ==> (det(matrix f) = &0 <=> + ~(?g. linear g /\ f o g = I))`, + SIMP_TAC[DET_MATRIX_EQ_0] THEN MESON_TAC[LINEAR_INVERSE_LEFT]);; + +let DET_EQ_0_RANK = prove + (`!A:real^N^N. det A = &0 <=> rank A < dimindex(:N)`, + REWRITE_TAC[DET_EQ_0; INVERTIBLE_LEFT_INVERSE; GSYM FULL_RANK_INJECTIVE; + MATRIX_LEFT_INVERTIBLE_INJECTIVE] THEN + GEN_TAC THEN MP_TAC(ISPEC `A:real^N^N` RANK_BOUND) THEN + ARITH_TAC);; + +let HOMOGENEOUS_LINEAR_EQUATIONS_DET = prove + (`!A:real^N^N. (?x. ~(x = vec 0) /\ A ** x = vec 0) <=> det A = &0`, + GEN_TAC THEN + REWRITE_TAC[MATRIX_NONFULL_LINEAR_EQUATIONS_EQ; DET_EQ_0_RANK] THEN + MATCH_MP_TAC(ARITH_RULE `r <= MIN N N ==> (~(r = N) <=> r < N)`) THEN + REWRITE_TAC[RANK_BOUND]);; + +let INVERTIBLE_MATRIX_MUL = prove + (`!A:real^N^N B:real^N^N. + invertible(A ** B) <=> invertible A /\ invertible B`, + REWRITE_TAC[INVERTIBLE_DET_NZ; DET_MUL; DE_MORGAN_THM; REAL_ENTIRE]);; + +let MATRIX_INV_MUL = prove + (`!A:real^N^N B:real^N^N. + invertible A /\ invertible B + ==> matrix_inv(A ** B) = matrix_inv B ** matrix_inv A`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC MATRIX_INV_UNIQUE THEN + ONCE_REWRITE_TAC[MATRIX_MUL_ASSOC] THEN + GEN_REWRITE_TAC (BINOP_CONV o LAND_CONV o LAND_CONV) + [GSYM MATRIX_MUL_ASSOC] THEN + ASM_SIMP_TAC[MATRIX_MUL_LINV; DET_EQ_0; MATRIX_MUL_RID; MATRIX_MUL_RINV]);; + +(* ------------------------------------------------------------------------- *) +(* Cramer's rule. *) +(* ------------------------------------------------------------------------- *) + +let CRAMER_LEMMA_TRANSP = prove + (`!A:real^N^N x:real^N. + 1 <= k /\ k <= dimindex(:N) + ==> det((lambda i. if i = k + then vsum(1..dimindex(:N)) (\i. x$i % row i A) + else row i A):real^N^N) = + x$k * det A`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN `1..dimindex(:N) = k INSERT ((1..dimindex(:N)) DELETE k)` + SUBST1_TAC THENL [ASM_MESON_TAC[INSERT_DELETE; IN_NUMSEG]; ALL_TAC] THEN + SIMP_TAC[VSUM_CLAUSES; FINITE_NUMSEG; FINITE_DELETE; IN_DELETE] THEN + REWRITE_TAC[VECTOR_ARITH + `(x:real^N)$k % row k (A:real^N^N) + s = + (x$k - &1) % row k A + row k A + s`] THEN + W(MP_TAC o PART_MATCH (lhs o rand) DET_ROW_ADD o lhand o snd) THEN + ASM_SIMP_TAC[DET_ROW_MUL] THEN DISCH_THEN(K ALL_TAC) THEN + MATCH_MP_TAC(REAL_RING `d = d' /\ e = d' ==> (c - &1) * d + e = c * d'`) THEN + CONJ_TAC THENL + [AP_TERM_TAC THEN ASM_SIMP_TAC[CART_EQ; LAMBDA_BETA] THEN + REPEAT STRIP_TAC THEN COND_CASES_TAC THEN ASM_SIMP_TAC[LAMBDA_BETA; row]; + MATCH_MP_TAC DET_ROW_SPAN THEN ASM_REWRITE_TAC[] THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC SPAN_VSUM THEN + REWRITE_TAC[FINITE_NUMSEG; IN_NUMSEG; FINITE_DELETE; IN_DELETE] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC SPAN_MUL THEN + MATCH_MP_TAC(CONJUNCT1 SPAN_CLAUSES) THEN + REWRITE_TAC[IN_ELIM_THM] THEN ASM_MESON_TAC[]]);; + +let CRAMER_LEMMA = prove + (`!A:real^N^N x:real^N. + 1 <= k /\ k <= dimindex(:N) + ==> det((lambda i j. if j = k then (A**x)$i else A$i$j):real^N^N) = + x$k * det(A)`, + REPEAT GEN_TAC THEN DISCH_TAC THEN REWRITE_TAC[MATRIX_MUL_VSUM] THEN + FIRST_ASSUM(MP_TAC o SYM o SPECL [`transp(A:real^N^N)`; `x:real^N`] o + MATCH_MP CRAMER_LEMMA_TRANSP) THEN + REWRITE_TAC[DET_TRANSP] THEN DISCH_THEN SUBST1_TAC THEN + GEN_REWRITE_TAC LAND_CONV [GSYM DET_TRANSP] THEN AP_TERM_TAC THEN + ASM_SIMP_TAC[CART_EQ; transp; LAMBDA_BETA; MATRIX_MUL_VSUM; row; column; + COND_COMPONENT; VECTOR_MUL_COMPONENT; VSUM_COMPONENT]);; + +let CRAMER = prove + (`!A:real^N^N x b. + ~(det(A) = &0) + ==> (A ** x = b <=> + x = lambda k. + det((lambda i j. if j = k then b$i else A$i$j):real^N^N) / + det(A))`, + GEN_TAC THEN REWRITE_TAC[RIGHT_FORALL_IMP_THM] THEN DISCH_TAC THEN + ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN GEN_TAC THEN MATCH_MP_TAC(MESON[] + `(?x. p(x)) /\ (!x. p(x) ==> x = a) ==> !x. p(x) <=> x = a`) THEN + CONJ_TAC THENL + [MP_TAC(SPEC `A:real^N^N` INVERTIBLE_DET_NZ) THEN + ASM_MESON_TAC[invertible; MATRIX_VECTOR_MUL_ASSOC; MATRIX_VECTOR_MUL_LID]; + GEN_TAC THEN DISCH_THEN(SUBST1_TAC o SYM) THEN + ASM_SIMP_TAC[CART_EQ; CRAMER_LEMMA; LAMBDA_BETA; REAL_FIELD + `~(z = &0) ==> (x = y / z <=> x * z = y)`]]);; + +(* ------------------------------------------------------------------------- *) +(* Variants of Cramer's rule for matrix-matrix multiplication. *) +(* ------------------------------------------------------------------------- *) + +let CRAMER_MATRIX_LEFT = prove + (`!A:real^N^N X:real^N^N B:real^N^N. + ~(det A = &0) + ==> (X ** A = B <=> + X = lambda k l. + det((lambda i j. if j = l then B$k$i else A$j$i):real^N^N) / + det A)`, + REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[CART_EQ] THEN + ASM_SIMP_TAC[MATRIX_MUL_COMPONENT; CRAMER; DET_TRANSP] THEN + SIMP_TAC[CART_EQ; LAMBDA_BETA] THEN + REPLICATE_TAC 2 (AP_TERM_TAC THEN ABS_TAC THEN AP_TERM_TAC) THEN + AP_TERM_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN AP_TERM_TAC THEN + SIMP_TAC[CART_EQ; LAMBDA_BETA; transp]);; + +let CRAMER_MATRIX_RIGHT = prove + (`!A:real^N^N X:real^N^N B:real^N^N. + ~(det A = &0) + ==> (A ** X = B <=> + X = lambda k l. + det((lambda i j. if j = k then B$i$l else A$i$j):real^N^N) / + det A)`, + REPEAT STRIP_TAC THEN + GEN_REWRITE_TAC LAND_CONV [GSYM TRANSP_EQ] THEN + REWRITE_TAC[MATRIX_TRANSP_MUL] THEN + ASM_SIMP_TAC[CRAMER_MATRIX_LEFT; DET_TRANSP] THEN + GEN_REWRITE_TAC LAND_CONV [GSYM TRANSP_EQ] THEN + REWRITE_TAC[TRANSP_TRANSP] THEN AP_TERM_TAC THEN + SIMP_TAC[CART_EQ; LAMBDA_BETA; transp] THEN + REPEAT(GEN_TAC THEN STRIP_TAC) THEN + AP_THM_TAC THEN AP_TERM_TAC THEN AP_TERM_TAC THEN + SIMP_TAC[CART_EQ; LAMBDA_BETA; transp]);; + +let CRAMER_MATRIX_RIGHT_INVERSE = prove + (`!A:real^N^N A':real^N^N. + A ** A' = mat 1 <=> + ~(det A = &0) /\ + A' = lambda k l. + det((lambda i j. if j = k then if i = l then &1 else &0 + else A$i$j):real^N^N) / + det A`, + REPEAT GEN_TAC THEN ASM_CASES_TAC `det(A:real^N^N) = &0` THENL + [ASM_REWRITE_TAC[] THEN + DISCH_THEN(MP_TAC o AP_TERM `det:real^N^N->real`) THEN + ASM_REWRITE_TAC[DET_MUL; DET_I] THEN REAL_ARITH_TAC; + ASM_SIMP_TAC[CRAMER_MATRIX_RIGHT] THEN AP_TERM_TAC THEN + SIMP_TAC[CART_EQ; LAMBDA_BETA] THEN + REPEAT(GEN_TAC THEN STRIP_TAC) THEN + AP_THM_TAC THEN AP_TERM_TAC THEN AP_TERM_TAC THEN + ASM_SIMP_TAC[CART_EQ; LAMBDA_BETA; mat]]);; + +let CRAMER_MATRIX_LEFT_INVERSE = prove + (`!A:real^N^N A':real^N^N. + A' ** A = mat 1 <=> + ~(det A = &0) /\ + A' = lambda k l. + det((lambda i j. if j = l then if i = k then &1 else &0 + else A$j$i):real^N^N) / + det A`, + REPEAT GEN_TAC THEN ASM_CASES_TAC `det(A:real^N^N) = &0` THENL + [ASM_REWRITE_TAC[] THEN + DISCH_THEN(MP_TAC o AP_TERM `det:real^N^N->real`) THEN + ASM_REWRITE_TAC[DET_MUL; DET_I] THEN REAL_ARITH_TAC; + ASM_SIMP_TAC[CRAMER_MATRIX_LEFT] THEN AP_TERM_TAC THEN + SIMP_TAC[CART_EQ; LAMBDA_BETA] THEN + REPEAT(GEN_TAC THEN STRIP_TAC) THEN + AP_THM_TAC THEN AP_TERM_TAC THEN AP_TERM_TAC THEN + ASM_SIMP_TAC[CART_EQ; LAMBDA_BETA; mat] THEN MESON_TAC[]]);; + +(* ------------------------------------------------------------------------- *) +(* Cofactors and their relationship to inverse matrices. *) +(* ------------------------------------------------------------------------- *) + +let cofactor = new_definition + `(cofactor:real^N^N->real^N^N) A = + lambda i j. det((lambda k l. if k = i /\ l = j then &1 + else if k = i \/ l = j then &0 + else A$k$l):real^N^N)`;; + +let COFACTOR_TRANSP = prove + (`!A:real^N^N. cofactor(transp A) = transp(cofactor A)`, + SIMP_TAC[cofactor; CART_EQ; LAMBDA_BETA; transp] THEN REPEAT STRIP_TAC THEN + GEN_REWRITE_TAC RAND_CONV [GSYM DET_TRANSP] THEN + AP_TERM_TAC THEN SIMP_TAC[cofactor; CART_EQ; LAMBDA_BETA; transp] THEN + MESON_TAC[]);; + +let COFACTOR_COLUMN = prove + (`!A:real^N^N. + cofactor A = + lambda i j. det((lambda k l. if l = j then if k = i then &1 else &0 + else A$k$l):real^N^N)`, + GEN_TAC THEN CONV_TAC SYM_CONV THEN + SIMP_TAC[cofactor; CART_EQ; LAMBDA_BETA] THEN + X_GEN_TAC `i:num` THEN STRIP_TAC THEN + X_GEN_TAC `j:num` THEN STRIP_TAC THEN + REWRITE_TAC[det] THEN MATCH_MP_TAC SUM_EQ THEN + REWRITE_TAC[FORALL_IN_GSPEC] THEN GEN_TAC THEN + DISCH_TAC THEN AP_TERM_TAC THEN + ASM_CASES_TAC `(p:num->num) i = j` THENL + [MATCH_MP_TAC PRODUCT_EQ THEN + X_GEN_TAC `k:num` THEN SIMP_TAC[IN_NUMSEG; LAMBDA_BETA] THEN STRIP_TAC THEN + SUBGOAL_THEN `(p:num->num) k IN 1..dimindex(:N)` MP_TAC THENL + [ASM_MESON_TAC[PERMUTES_IN_IMAGE; IN_NUMSEG]; + SIMP_TAC[LAMBDA_BETA; IN_NUMSEG] THEN STRIP_TAC] THEN + ASM_CASES_TAC `(p:num->num) k = j` THEN ASM_REWRITE_TAC[] THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN ASM_MESON_TAC[]; + MATCH_MP_TAC(REAL_ARITH `s = &0 /\ t = &0 ==> s = t`) THEN + ASM_SIMP_TAC[PRODUCT_EQ_0; FINITE_NUMSEG] THEN CONJ_TAC THEN + EXISTS_TAC `inverse (p:num->num) j` THEN + ASM_SIMP_TAC[IN_NUMSEG; LAMBDA_BETA] THEN + (SUBGOAL_THEN `inverse(p:num->num) j IN 1..dimindex(:N)` MP_TAC THENL + [ASM_MESON_TAC[PERMUTES_IN_IMAGE; PERMUTES_INVERSE; IN_NUMSEG]; + SIMP_TAC[LAMBDA_BETA; IN_NUMSEG] THEN STRIP_TAC] THEN + SUBGOAL_THEN `(p:num->num)(inverse p j) = j` SUBST1_TAC THENL + [ASM_MESON_TAC[PERMUTES_INVERSES; IN_NUMSEG]; + ASM_SIMP_TAC[LAMBDA_BETA] THEN + ASM_MESON_TAC[PERMUTES_INVERSE_EQ]])]);; + +let COFACTOR_ROW = prove + (`!A:real^N^N. + cofactor A = + lambda i j. det((lambda k l. if k = i then if l = j then &1 else &0 + else A$k$l):real^N^N)`, + GEN_TAC THEN ONCE_REWRITE_TAC[GSYM TRANSP_EQ] THEN + REWRITE_TAC[GSYM COFACTOR_TRANSP] THEN + SIMP_TAC[COFACTOR_COLUMN; CART_EQ; LAMBDA_BETA; transp] THEN + REPEAT STRIP_TAC THEN + GEN_REWRITE_TAC RAND_CONV [GSYM DET_TRANSP] THEN + AP_TERM_TAC THEN SIMP_TAC[cofactor; CART_EQ; LAMBDA_BETA; transp]);; + +let MATRIX_RIGHT_INVERSE_COFACTOR = prove + (`!A:real^N^N A':real^N^N. + A ** A' = mat 1 <=> + ~(det A = &0) /\ A' = inv(det A) %% transp(cofactor A)`, + REPEAT GEN_TAC THEN REWRITE_TAC[CRAMER_MATRIX_RIGHT_INVERSE] THEN + ASM_CASES_TAC `det(A:real^N^N) = &0` THEN ASM_REWRITE_TAC[] THEN + AP_TERM_TAC THEN SIMP_TAC[CART_EQ; LAMBDA_BETA; MATRIX_CMUL_COMPONENT] THEN + X_GEN_TAC `k:num` THEN STRIP_TAC THEN + X_GEN_TAC `l:num` THEN STRIP_TAC THEN + REWRITE_TAC[ONCE_REWRITE_RULE[REAL_MUL_SYM] real_div] THEN AP_TERM_TAC THEN + ASM_SIMP_TAC[transp; COFACTOR_COLUMN; LAMBDA_BETA] THEN + AP_TERM_TAC THEN SIMP_TAC[CART_EQ; LAMBDA_BETA]);; + +let MATRIX_LEFT_INVERSE_COFACTOR = prove + (`!A:real^N^N A':real^N^N. + A' ** A = mat 1 <=> + ~(det A = &0) /\ A' = inv(det A) %% transp(cofactor A)`, + REPEAT GEN_TAC THEN + ONCE_REWRITE_TAC[MATRIX_LEFT_RIGHT_INVERSE] THEN + REWRITE_TAC[MATRIX_RIGHT_INVERSE_COFACTOR]);; + +let MATRIX_INV_COFACTOR = prove + (`!A. ~(det A = &0) ==> matrix_inv A = inv(det A) %% transp(cofactor A)`, + GEN_TAC THEN DISCH_THEN(MP_TAC o MATCH_MP MATRIX_MUL_LINV) THEN + SIMP_TAC[MATRIX_LEFT_INVERSE_COFACTOR]);; + +let COFACTOR_MATRIX_INV = prove + (`!A:real^N^N. ~(det A = &0) ==> cofactor A = det(A) %% transp(matrix_inv A)`, + SIMP_TAC[MATRIX_INV_COFACTOR; TRANSP_MATRIX_CMUL; TRANSP_TRANSP] THEN + SIMP_TAC[MATRIX_CMUL_ASSOC; REAL_MUL_RINV; MATRIX_CMUL_LID]);; + +let COFACTOR_I = prove + (`cofactor(mat 1:real^N^N) = mat 1`, + SIMP_TAC[COFACTOR_MATRIX_INV; DET_I; REAL_OF_NUM_EQ; ARITH_EQ] THEN + REWRITE_TAC[MATRIX_INV_I; MATRIX_CMUL_LID; TRANSP_MAT]);; + +let DET_COFACTOR_EXPANSION = prove + (`!A:real^N^N i. + 1 <= i /\ i <= dimindex(:N) + ==> det A = sum (1..dimindex(:N)) + (\j. A$i$j * (cofactor A)$i$j)`, + REPEAT STRIP_TAC THEN ASM_SIMP_TAC[COFACTOR_COLUMN; LAMBDA_BETA; det] THEN + REWRITE_TAC[GSYM SUM_LMUL] THEN + W(MP_TAC o PART_MATCH (lhand o rand) SUM_SWAP o rand o snd) THEN + ANTS_TAC THENL [SIMP_TAC[FINITE_PERMUTATIONS; FINITE_NUMSEG]; ALL_TAC] THEN + DISCH_THEN SUBST1_TAC THEN + MATCH_MP_TAC SUM_EQ THEN REWRITE_TAC[FORALL_IN_GSPEC] THEN + GEN_TAC THEN DISCH_TAC THEN + ONCE_REWRITE_TAC[REAL_ARITH `a * s * p:real = s * a * p`] THEN + REWRITE_TAC[SUM_LMUL] THEN AP_TERM_TAC THEN MATCH_MP_TAC EQ_TRANS THEN + EXISTS_TAC + `sum (1..dimindex (:N)) + (\j. (A:real^N^N)$i$j * + product + (inverse p j INSERT ((1..dimindex(:N)) DELETE (inverse p j))) + (\k. if k = inverse p j then if k = i then &1 else &0 + else A$k$(p k)))` THEN + CONJ_TAC THENL + [SIMP_TAC[PRODUCT_CLAUSES; FINITE_DELETE; FINITE_PERMUTATIONS; + FINITE_NUMSEG; IN_DELETE] THEN + SUBGOAL_THEN `!j. inverse (p:num->num) j = i <=> j = p i` + (fun th -> REWRITE_TAC[th]) + THENL [ASM_MESON_TAC[PERMUTES_INVERSES; IN_NUMSEG]; ALL_TAC] THEN + REWRITE_TAC[REAL_ARITH + `x * (if p then &1 else &0) * y = if p then x * y else &0`] THEN + SIMP_TAC[SUM_DELTA] THEN COND_CASES_TAC THENL + [ALL_TAC; ASM_MESON_TAC[PERMUTES_IN_IMAGE; IN_NUMSEG]] THEN + SUBGOAL_THEN + `1..dimindex(:N) = i INSERT ((1..dimindex(:N)) DELETE i)` + (fun th -> GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [th]) + THENL + [ASM_SIMP_TAC[IN_NUMSEG; SET_RULE `s = x INSERT (s DELETE x) <=> x IN s`]; + SIMP_TAC[PRODUCT_CLAUSES; FINITE_DELETE; FINITE_NUMSEG; IN_DELETE] THEN + AP_TERM_TAC THEN MATCH_MP_TAC(MESON[PRODUCT_EQ] + `s = t /\ (!x. x IN t ==> f x = g x) ==> product s f = product t g`) THEN + SIMP_TAC[IN_DELETE] THEN ASM_MESON_TAC[PERMUTES_INVERSES; IN_NUMSEG]]; + MATCH_MP_TAC SUM_EQ_NUMSEG THEN X_GEN_TAC `j:num` THEN STRIP_TAC THEN + REWRITE_TAC[] THEN AP_TERM_TAC THEN MATCH_MP_TAC(MESON[PRODUCT_EQ] + `s = t /\ (!x. x IN t ==> f x = g x) ==> product s f = product t g`) THEN + CONJ_TAC THENL + [REWRITE_TAC[SET_RULE `x INSERT (s DELETE x) = s <=> x IN s`] THEN + ASM_MESON_TAC[PERMUTES_IN_IMAGE; IN_NUMSEG; PERMUTES_INVERSE]; + X_GEN_TAC `k:num` THEN REWRITE_TAC[IN_NUMSEG] THEN STRIP_TAC THEN + SUBGOAL_THEN `(p:num->num) k IN 1..dimindex(:N)` MP_TAC THENL + [ASM_MESON_TAC[PERMUTES_IN_IMAGE; IN_NUMSEG]; ALL_TAC] THEN + SIMP_TAC[LAMBDA_BETA; IN_NUMSEG] THEN + ASM_MESON_TAC[PERMUTES_INVERSES; IN_NUMSEG]]]);; + +let MATRIX_MUL_RIGHT_COFACTOR = prove + (`!A:real^N^N. A ** transp(cofactor A) = det(A) %% mat 1`, + GEN_TAC THEN + SIMP_TAC[CART_EQ; MATRIX_CMUL_COMPONENT; mat; + matrix_mul; LAMBDA_BETA; transp] THEN + X_GEN_TAC `i:num` THEN STRIP_TAC THEN + X_GEN_TAC `i':num` THEN STRIP_TAC THEN + COND_CASES_TAC THEN + ASM_SIMP_TAC[GSYM DET_COFACTOR_EXPANSION; REAL_MUL_RID] THEN + MATCH_MP_TAC EQ_TRANS THEN + EXISTS_TAC `det((lambda k l. if k = i' then (A:real^N^N)$i$l + else A$k$l):real^N^N)` THEN + CONJ_TAC THENL + [MP_TAC(GEN `A:real^N^N` + (ISPECL [`A:real^N^N`; `i':num`] DET_COFACTOR_EXPANSION)) THEN + ASM_REWRITE_TAC[] THEN ASM_SIMP_TAC[] THEN DISCH_THEN(K ALL_TAC) THEN + MATCH_MP_TAC SUM_EQ THEN X_GEN_TAC `j:num` THEN + REWRITE_TAC[IN_NUMSEG] THEN STRIP_TAC THEN + ASM_SIMP_TAC[LAMBDA_BETA] THEN AP_TERM_TAC THEN + ASM_SIMP_TAC[cofactor; LAMBDA_BETA] THEN AP_TERM_TAC THEN + SIMP_TAC[CART_EQ; LAMBDA_BETA] THEN ASM_MESON_TAC[]; + REWRITE_TAC[REAL_MUL_RZERO] THEN MATCH_MP_TAC DET_IDENTICAL_ROWS THEN + MAP_EVERY EXISTS_TAC [`i:num`;` i':num`] THEN + ASM_SIMP_TAC[CART_EQ; LAMBDA_BETA; row]]);; + +let MATRIX_MUL_LEFT_COFACTOR = prove + (`!A:real^N^N. transp(cofactor A) ** A = det(A) %% mat 1`, + GEN_TAC THEN ONCE_REWRITE_TAC[GSYM TRANSP_EQ] THEN + REWRITE_TAC[MATRIX_TRANSP_MUL] THEN + ONCE_REWRITE_TAC[GSYM COFACTOR_TRANSP] THEN + REWRITE_TAC[MATRIX_MUL_RIGHT_COFACTOR; TRANSP_MATRIX_CMUL] THEN + REWRITE_TAC[DET_TRANSP; TRANSP_MAT]);; + +let COFACTOR_CMUL = prove + (`!A:real^N^N c. cofactor(c %% A) = c pow (dimindex(:N) - 1) %% cofactor A`, + REPEAT GEN_TAC THEN + SIMP_TAC[CART_EQ; cofactor; LAMBDA_BETA; MATRIX_CMUL_COMPONENT] THEN + X_GEN_TAC `i:num` THEN STRIP_TAC THEN + X_GEN_TAC `j:num` THEN STRIP_TAC THEN + REWRITE_TAC[det; GSYM SUM_LMUL] THEN + MATCH_MP_TAC SUM_EQ THEN REWRITE_TAC[FORALL_IN_GSPEC] THEN + X_GEN_TAC `p:num->num` THEN DISCH_TAC THEN + ONCE_REWRITE_TAC[REAL_ARITH `a * b * c:real = b * a * c`] THEN + AP_TERM_TAC THEN + SUBGOAL_THEN + `1..dimindex (:N) = i INSERT ((1..dimindex (:N)) DELETE i)` + SUBST1_TAC THENL + [REWRITE_TAC[EXTENSION; IN_INSERT; IN_NUMSEG; IN_DELETE] THEN ASM_ARITH_TAC; + SIMP_TAC[PRODUCT_CLAUSES; FINITE_DELETE; FINITE_NUMSEG; IN_DELETE]] THEN + SUBGOAL_THEN + `1 <= (p:num->num) i /\ p i <= dimindex(:N)` + ASSUME_TAC THENL + [FIRST_ASSUM(MP_TAC o MATCH_MP PERMUTES_IMAGE) THEN + REWRITE_TAC[EXTENSION; IN_IMAGE; IN_NUMSEG] THEN ASM SET_TAC[]; + ASM_SIMP_TAC[LAMBDA_BETA]] THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[REAL_MUL_LZERO; REAL_MUL_RZERO] THEN + SUBGOAL_THEN + `dimindex(:N) - 1 = CARD((1..dimindex(:N)) DELETE i)` + SUBST1_TAC THENL + [ASM_SIMP_TAC[CARD_DELETE; FINITE_NUMSEG; IN_NUMSEG; CARD_NUMSEG_1]; + ASM_SIMP_TAC[REAL_MUL_LID; GSYM PRODUCT_CONST; FINITE_NUMSEG; + FINITE_DELETE; GSYM PRODUCT_MUL]] THEN + MATCH_MP_TAC PRODUCT_EQ THEN + X_GEN_TAC `k:num` THEN REWRITE_TAC[IN_DELETE; IN_NUMSEG] THEN STRIP_TAC THEN + SUBGOAL_THEN + `1 <= (p:num->num) k /\ p k <= dimindex(:N)` + ASSUME_TAC THENL + [FIRST_ASSUM(MP_TAC o MATCH_MP PERMUTES_IMAGE) THEN + REWRITE_TAC[EXTENSION; IN_IMAGE; IN_NUMSEG] THEN ASM SET_TAC[]; + ASM_SIMP_TAC[LAMBDA_BETA] THEN REAL_ARITH_TAC]);; + +let COFACTOR_0 = prove + (`cofactor(mat 0:real^N^N) = if dimindex(:N) = 1 then mat 1 else mat 0`, + MP_TAC(ISPECL [`mat 1:real^N^N`; `&0`] COFACTOR_CMUL) THEN + REWRITE_TAC[MATRIX_CMUL_LZERO; COFACTOR_I; REAL_POW_ZERO] THEN + DISCH_THEN SUBST1_TAC THEN + SIMP_TAC[DIMINDEX_GE_1; ARITH_RULE `1 <= n ==> (n - 1 = 0 <=> n = 1)`] THEN + COND_CASES_TAC THEN REWRITE_TAC[MATRIX_CMUL_LZERO; MATRIX_CMUL_LID]);; + +(* ------------------------------------------------------------------------- *) +(* Explicit formulas for low dimensions. *) +(* ------------------------------------------------------------------------- *) + +let PRODUCT_1 = prove + (`product(1..1) f = f(1)`, + REWRITE_TAC[PRODUCT_SING_NUMSEG]);; + +let PRODUCT_2 = prove + (`!t. product(1..2) t = t(1) * t(2)`, + REWRITE_TAC[num_CONV `2`; PRODUCT_CLAUSES_NUMSEG] THEN + REWRITE_TAC[PRODUCT_SING_NUMSEG; ARITH; REAL_MUL_ASSOC]);; + +let PRODUCT_3 = prove + (`!t. product(1..3) t = t(1) * t(2) * t(3)`, + REWRITE_TAC[num_CONV `3`; num_CONV `2`; PRODUCT_CLAUSES_NUMSEG] THEN + REWRITE_TAC[PRODUCT_SING_NUMSEG; ARITH; REAL_MUL_ASSOC]);; + +let PRODUCT_4 = prove + (`!t. product(1..4) t = t(1) * t(2) * t(3) * t(4)`, + REWRITE_TAC[num_CONV `4`; num_CONV `3`; num_CONV `2`; + PRODUCT_CLAUSES_NUMSEG] THEN + REWRITE_TAC[PRODUCT_SING_NUMSEG; ARITH; REAL_MUL_ASSOC]);; + +let DET_1 = prove + (`!A:real^1^1. det A = A$1$1`, + REWRITE_TAC[det; DIMINDEX_1; PERMUTES_SING; NUMSEG_SING] THEN + REWRITE_TAC[SUM_SING; SET_RULE `{x | x = a} = {a}`; PRODUCT_SING] THEN + REWRITE_TAC[SIGN_I; I_THM] THEN REAL_ARITH_TAC);; + +let DET_2 = prove + (`!A:real^2^2. det A = A$1$1 * A$2$2 - A$1$2 * A$2$1`, + GEN_TAC THEN REWRITE_TAC[det; DIMINDEX_2] THEN + CONV_TAC(LAND_CONV(RATOR_CONV(ONCE_DEPTH_CONV NUMSEG_CONV))) THEN + SIMP_TAC[SUM_OVER_PERMUTATIONS_INSERT; FINITE_INSERT; FINITE_EMPTY; + ARITH_EQ; IN_INSERT; NOT_IN_EMPTY] THEN + REWRITE_TAC[PERMUTES_EMPTY; SUM_SING; SET_RULE `{x | x = a} = {a}`] THEN + REWRITE_TAC[SWAP_REFL; I_O_ID] THEN + REWRITE_TAC[GSYM(NUMSEG_CONV `1..2`); SUM_2] THEN + SIMP_TAC[SUM_CLAUSES; FINITE_INSERT; FINITE_EMPTY; + ARITH_EQ; IN_INSERT; NOT_IN_EMPTY] THEN + SIMP_TAC[SIGN_COMPOSE; PERMUTATION_SWAP] THEN + REWRITE_TAC[SIGN_SWAP; ARITH] THEN REWRITE_TAC[PRODUCT_2] THEN + REWRITE_TAC[o_THM; swap; ARITH] THEN REAL_ARITH_TAC);; + +let DET_3 = prove + (`!A:real^3^3. + det(A) = A$1$1 * A$2$2 * A$3$3 + + A$1$2 * A$2$3 * A$3$1 + + A$1$3 * A$2$1 * A$3$2 - + A$1$1 * A$2$3 * A$3$2 - + A$1$2 * A$2$1 * A$3$3 - + A$1$3 * A$2$2 * A$3$1`, + GEN_TAC THEN REWRITE_TAC[det; DIMINDEX_3] THEN + CONV_TAC(LAND_CONV(RATOR_CONV(ONCE_DEPTH_CONV NUMSEG_CONV))) THEN + SIMP_TAC[SUM_OVER_PERMUTATIONS_INSERT; FINITE_INSERT; FINITE_EMPTY; + ARITH_EQ; IN_INSERT; NOT_IN_EMPTY] THEN + REWRITE_TAC[PERMUTES_EMPTY; SUM_SING; SET_RULE `{x | x = a} = {a}`] THEN + REWRITE_TAC[SWAP_REFL; I_O_ID] THEN + REWRITE_TAC[GSYM(NUMSEG_CONV `1..3`); SUM_3] THEN + SIMP_TAC[SUM_CLAUSES; FINITE_INSERT; FINITE_EMPTY; + ARITH_EQ; IN_INSERT; NOT_IN_EMPTY] THEN + SIMP_TAC[SIGN_COMPOSE; PERMUTATION_SWAP] THEN + REWRITE_TAC[SIGN_SWAP; ARITH] THEN REWRITE_TAC[PRODUCT_3] THEN + REWRITE_TAC[o_THM; swap; ARITH] THEN REAL_ARITH_TAC);; + +let DET_4 = prove + (`!A:real^4^4. + det(A) = A$1$1 * A$2$2 * A$3$3 * A$4$4 + + A$1$1 * A$2$3 * A$3$4 * A$4$2 + + A$1$1 * A$2$4 * A$3$2 * A$4$3 + + A$1$2 * A$2$1 * A$3$4 * A$4$3 + + A$1$2 * A$2$3 * A$3$1 * A$4$4 + + A$1$2 * A$2$4 * A$3$3 * A$4$1 + + A$1$3 * A$2$1 * A$3$2 * A$4$4 + + A$1$3 * A$2$2 * A$3$4 * A$4$1 + + A$1$3 * A$2$4 * A$3$1 * A$4$2 + + A$1$4 * A$2$1 * A$3$3 * A$4$2 + + A$1$4 * A$2$2 * A$3$1 * A$4$3 + + A$1$4 * A$2$3 * A$3$2 * A$4$1 - + A$1$1 * A$2$2 * A$3$4 * A$4$3 - + A$1$1 * A$2$3 * A$3$2 * A$4$4 - + A$1$1 * A$2$4 * A$3$3 * A$4$2 - + A$1$2 * A$2$1 * A$3$3 * A$4$4 - + A$1$2 * A$2$3 * A$3$4 * A$4$1 - + A$1$2 * A$2$4 * A$3$1 * A$4$3 - + A$1$3 * A$2$1 * A$3$4 * A$4$2 - + A$1$3 * A$2$2 * A$3$1 * A$4$4 - + A$1$3 * A$2$4 * A$3$2 * A$4$1 - + A$1$4 * A$2$1 * A$3$2 * A$4$3 - + A$1$4 * A$2$2 * A$3$3 * A$4$1 - + A$1$4 * A$2$3 * A$3$1 * A$4$2`, + let lemma = prove + (`(sum {3,4} f = f 3 + f 4) /\ + (sum {2,3,4} f = f 2 + f 3 + f 4)`, + SIMP_TAC[SUM_CLAUSES; FINITE_INSERT; FINITE_EMPTY] THEN + REWRITE_TAC[ARITH_EQ; IN_INSERT; NOT_IN_EMPTY] THEN REAL_ARITH_TAC) in + GEN_TAC THEN REWRITE_TAC[det; DIMINDEX_4] THEN + CONV_TAC(LAND_CONV(RATOR_CONV(ONCE_DEPTH_CONV NUMSEG_CONV))) THEN + SIMP_TAC[SUM_OVER_PERMUTATIONS_INSERT; FINITE_INSERT; FINITE_EMPTY; + ARITH_EQ; IN_INSERT; NOT_IN_EMPTY] THEN + REWRITE_TAC[PERMUTES_EMPTY; SUM_SING; SET_RULE `{x | x = a} = {a}`] THEN + REWRITE_TAC[SWAP_REFL; I_O_ID] THEN + REWRITE_TAC[GSYM(NUMSEG_CONV `1..4`); SUM_4; lemma] THEN + SIMP_TAC[SIGN_COMPOSE; PERMUTATION_SWAP; PERMUTATION_COMPOSE] THEN + REWRITE_TAC[SIGN_SWAP; ARITH] THEN REWRITE_TAC[PRODUCT_4] THEN + REWRITE_TAC[o_THM; swap; ARITH] THEN REAL_ARITH_TAC);; + +(* ------------------------------------------------------------------------- *) +(* Existence of the characteristic polynomial. *) +(* ------------------------------------------------------------------------- *) + +let CHARACTERISTIC_POLYNOMIAL = prove + (`!A:real^N^N. + ?a. a(dimindex(:N)) = &1 /\ + !x. det(x %% mat 1 - A) = + sum (0..dimindex(:N)) (\i. a i * x pow i)`, + GEN_TAC THEN REWRITE_TAC[det] THEN + SUBGOAL_THEN + `!p n. IMAGE p (1..dimindex(:N)) SUBSET 1..dimindex(:N) /\ + n <= dimindex(:N) + ==> ?a. a n = (if !i. 1 <= i /\ i <= n ==> p i = i then &1 else &0) /\ + !x. product (1..n) (\i. (x %% mat 1 - A:real^N^N)$i$p i) = + sum (0..n) (\i. a i * x pow i)` + MP_TAC THENL + [GEN_TAC THEN REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN + DISCH_TAC THEN INDUCT_TAC THEN + REWRITE_TAC[PRODUCT_CLAUSES_NUMSEG] THEN + REWRITE_TAC[LE_0; ARITH_EQ; ARITH_RULE `1 <= SUC n`] THENL + [EXISTS_TAC `\i. if i = 0 then &1 else &0` THEN + SIMP_TAC[real_pow; REAL_MUL_LID; ARITH_RULE `1 <= i ==> ~(i <= 0)`; + SUM_CLAUSES_NUMSEG]; + DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o check (is_imp o concl)) THEN + ASM_SIMP_TAC[ARITH_RULE `SUC n <= N ==> n <= N`] THEN + DISCH_THEN(X_CHOOSE_THEN `a:num->real` STRIP_ASSUME_TAC) THEN + ASM_REWRITE_TAC[] THEN + REWRITE_TAC[MATRIX_SUB_COMPONENT; MATRIX_CMUL_COMPONENT] THEN + ASSUME_TAC(ARITH_RULE `1 <= SUC n`) THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [SUBSET]) THEN + REWRITE_TAC[FORALL_IN_IMAGE; IN_NUMSEG] THEN + DISCH_THEN(MP_TAC o SPEC `SUC n`) THEN ASM_REWRITE_TAC[] THEN + STRIP_TAC THEN ASM_SIMP_TAC[MAT_COMPONENT] THEN + ASM_CASES_TAC `p(SUC n) = SUC n` THEN ASM_REWRITE_TAC[] THENL + [ALL_TAC; + EXISTS_TAC `\i. if i <= n + then --((A:real^N^N)$(SUC n)$(p(SUC n))) * a i + else &0` THEN + SIMP_TAC[SUM_CLAUSES_NUMSEG; LE_0; ARITH_RULE `~(SUC n <= n)`] THEN + CONJ_TAC THENL + [COND_CASES_TAC THEN REWRITE_TAC[] THEN + FIRST_X_ASSUM(MP_TAC o SPEC `SUC n`) THEN + ASM_REWRITE_TAC[] THEN ASM_ARITH_TAC; + REWRITE_TAC[REAL_MUL_LZERO; REAL_ADD_RID; GSYM SUM_RMUL] THEN + GEN_TAC THEN MATCH_MP_TAC SUM_EQ_NUMSEG THEN REWRITE_TAC[] THEN + REAL_ARITH_TAC]] THEN + REWRITE_TAC[REAL_SUB_LDISTRIB; REAL_MUL_RID] THEN + REWRITE_TAC[GSYM SUM_RMUL] THEN EXISTS_TAC + `\i. (if i = 0 then &0 else a(i - 1)) - + (if i = SUC n then &0 else (A:real^N^N)$(SUC n)$(SUC n) * a i)` THEN + ASM_REWRITE_TAC[NOT_SUC; LE; SUC_SUB1; REAL_SUB_RZERO] THEN + CONJ_TAC THENL [ASM_MESON_TAC[LE_REFL]; ALL_TAC] THEN + REWRITE_TAC[REAL_SUB_RDISTRIB; SUM_SUB_NUMSEG] THEN + GEN_TAC THEN BINOP_TAC THENL + [SIMP_TAC[SUM_CLAUSES_LEFT; ARITH_RULE `0 <= SUC n`] THEN + REWRITE_TAC[ADD1; SUM_OFFSET; ARITH_RULE `~(i + 1 = 0)`; ADD_SUB] THEN + REWRITE_TAC[REAL_MUL_LZERO; REAL_POW_ADD; REAL_POW_1; REAL_ADD_LID]; + SIMP_TAC[SUM_CLAUSES_NUMSEG; LE_0; REAL_MUL_LZERO; REAL_ADD_RID] THEN + SIMP_TAC[ARITH_RULE `i <= n ==> ~(i = SUC n)`]] THEN + MATCH_MP_TAC SUM_EQ_NUMSEG THEN REWRITE_TAC[REAL_ADD_LID; REAL_MUL_AC]]; + GEN_REWRITE_TAC LAND_CONV [SWAP_FORALL_THM] THEN + DISCH_THEN(MP_TAC o SPEC `dimindex(:N)`) THEN REWRITE_TAC[LE_REFL] THEN + GEN_REWRITE_TAC (LAND_CONV o BINDER_CONV) [RIGHT_IMP_EXISTS_THM] THEN + REWRITE_TAC[SKOLEM_THM; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `a:(num->num)->num->real` THEN DISCH_TAC] THEN + EXISTS_TAC + `\i:num. sum {p | p permutes 1..dimindex(:N)} (\p. sign p * a p i)` THEN + REWRITE_TAC[] THEN CONJ_TAC THENL + [MP_TAC(ISPECL + [`\p:num->num. sign p * a p (dimindex(:N))`; + `{p | p permutes 1..dimindex(:N)}`; + `I:num->num`] SUM_DELETE) THEN + SIMP_TAC[IN_ELIM_THM; PERMUTES_I; FINITE_PERMUTATIONS; FINITE_NUMSEG] THEN + MATCH_MP_TAC(REAL_ARITH `k = &1 /\ s' = &0 ==> s' = s - k ==> s = &1`) THEN + CONJ_TAC THENL + [FIRST_X_ASSUM(MP_TAC o SPEC `I:num->num`) THEN + SIMP_TAC[IMAGE_I; SUBSET_REFL; SIGN_I; I_THM; REAL_MUL_LID]; + MATCH_MP_TAC SUM_EQ_0 THEN X_GEN_TAC `p:num->num` THEN + REWRITE_TAC[IN_ELIM_THM; IN_DELETE] THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `p:num->num`) THEN ANTS_TAC THENL + [ASM_MESON_TAC[PERMUTES_IMAGE; SUBSET_REFL]; ALL_TAC] THEN + COND_CASES_TAC THEN SIMP_TAC[REAL_MUL_RZERO] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [permutes]) THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE RAND_CONV [FUN_EQ_THM]) THEN + REWRITE_TAC[IN_NUMSEG; I_THM] THEN ASM_MESON_TAC[]]; + X_GEN_TAC `x:real` THEN REWRITE_TAC[GSYM SUM_RMUL] THEN + W(MP_TAC o PART_MATCH (lhs o rand) SUM_SWAP o rand o snd) THEN + SIMP_TAC[FINITE_PERMUTATIONS; FINITE_NUMSEG] THEN + DISCH_THEN SUBST1_TAC THEN MATCH_MP_TAC SUM_EQ THEN + X_GEN_TAC `p:num->num` THEN REWRITE_TAC[IN_ELIM_THM] THEN DISCH_TAC THEN + REWRITE_TAC[GSYM REAL_MUL_ASSOC; SUM_LMUL] THEN AP_TERM_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `p:num->num`) THEN ANTS_TAC THENL + [ASM_MESON_TAC[PERMUTES_IMAGE; SUBSET_REFL]; SIMP_TAC[]]]);; + +(* ------------------------------------------------------------------------- *) +(* Grassmann-Plucker relations for n = 2, n = 3 and n = 4. *) +(* I have a proof of the general n case but the proof is a bit long and the *) +(* result doesn't seem generally useful enough to go in the main theories. *) +(* ------------------------------------------------------------------------- *) + +let GRASSMANN_PLUCKER_2 = prove + (`!x1 x2 y1 y2:real^2. + det(vector[x1;x2]) * det(vector[y1;y2]) = + det(vector[y1;x2]) * det(vector[x1;y2]) + + det(vector[y2;x2]) * det(vector[y1;x1])`, + REWRITE_TAC[DET_2; VECTOR_2] THEN REAL_ARITH_TAC);; + +let GRASSMANN_PLUCKER_3 = prove + (`!x1 x2 x3 y1 y2 y3:real^3. + det(vector[x1;x2;x3]) * det(vector[y1;y2;y3]) = + det(vector[y1;x2;x3]) * det(vector[x1;y2;y3]) + + det(vector[y2;x2;x3]) * det(vector[y1;x1;y3]) + + det(vector[y3;x2;x3]) * det(vector[y1;y2;x1])`, + REWRITE_TAC[DET_3; VECTOR_3] THEN REAL_ARITH_TAC);; + +let GRASSMANN_PLUCKER_4 = prove + (`!x1 x2 x3 x4:real^4 y1 y2 y3 y4:real^4. + det(vector[x1;x2;x3;x4]) * det(vector[y1;y2;y3;y4]) = + det(vector[y1;x2;x3;x4]) * det(vector[x1;y2;y3;y4]) + + det(vector[y2;x2;x3;x4]) * det(vector[y1;x1;y3;y4]) + + det(vector[y3;x2;x3;x4]) * det(vector[y1;y2;x1;y4]) + + det(vector[y4;x2;x3;x4]) * det(vector[y1;y2;y3;x1])`, + REWRITE_TAC[DET_4; VECTOR_4] THEN REAL_ARITH_TAC);; + +(* ------------------------------------------------------------------------- *) +(* Determinants of integer matrices. *) +(* ------------------------------------------------------------------------- *) + +let INTEGER_PRODUCT = prove + (`!f s. (!x. x IN s ==> integer(f x)) ==> integer(product s f)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC PRODUCT_CLOSED THEN + ASM_REWRITE_TAC[INTEGER_CLOSED]);; + +let INTEGER_SIGN = prove + (`!p. integer(sign p)`, + SIMP_TAC[sign; COND_RAND; INTEGER_CLOSED; COND_ID]);; + +let INTEGER_DET = prove + (`!M:real^N^N. + (!i j. 1 <= i /\ i <= dimindex(:N) /\ + 1 <= j /\ j <= dimindex(:N) + ==> integer(M$i$j)) + ==> integer(det M)`, + REPEAT STRIP_TAC THEN REWRITE_TAC[det] THEN + MATCH_MP_TAC INTEGER_SUM THEN X_GEN_TAC `p:num->num` THEN + REWRITE_TAC[IN_ELIM_THM] THEN DISCH_TAC THEN + MATCH_MP_TAC INTEGER_MUL THEN REWRITE_TAC[INTEGER_SIGN] THEN + MATCH_MP_TAC INTEGER_PRODUCT THEN REWRITE_TAC[IN_NUMSEG] THEN + REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_MESON_TAC[IN_NUMSEG; permutes]);; + +(* ------------------------------------------------------------------------- *) +(* Diagonal matrices (for arbitrary rectangular matrix, not just square). *) +(* ------------------------------------------------------------------------- *) + +let diagonal_matrix = new_definition + `diagonal_matrix(A:real^N^M) <=> + !i j. 1 <= i /\ i <= dimindex(:M) /\ + 1 <= j /\ j <= dimindex(:N) /\ + ~(i = j) + ==> A$i$j = &0`;; + +let TRANSP_DIAGONAL_MATRIX = prove + (`!A:real^N^N. diagonal_matrix A ==> transp A = A`, + GEN_TAC THEN REWRITE_TAC[diagonal_matrix; CART_EQ; TRANSP_COMPONENT] THEN + STRIP_TAC THEN X_GEN_TAC `i:num` THEN STRIP_TAC THEN X_GEN_TAC `j:num` THEN + STRIP_TAC THEN ASM_CASES_TAC `i:num = j` THEN ASM_SIMP_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* Orthogonality of a transformation and matrix. *) +(* ------------------------------------------------------------------------- *) + +let orthogonal_transformation = new_definition + `orthogonal_transformation(f:real^N->real^N) <=> + linear f /\ !v w. f(v) dot f(w) = v dot w`;; + +let ORTHOGONAL_TRANSFORMATION = prove + (`!f. orthogonal_transformation f <=> linear f /\ !v. norm(f v) = norm(v)`, + GEN_TAC THEN REWRITE_TAC[orthogonal_transformation] THEN EQ_TAC THENL + [MESON_TAC[vector_norm]; SIMP_TAC[DOT_NORM] THEN MESON_TAC[LINEAR_ADD]]);; + +let ORTHOGONAL_TRANSFORMATION_COMPOSE = prove + (`!f g. orthogonal_transformation f /\ orthogonal_transformation g + ==> orthogonal_transformation(f o g)`, + SIMP_TAC[orthogonal_transformation; LINEAR_COMPOSE; o_THM]);; + +let orthogonal_matrix = new_definition + `orthogonal_matrix(Q:real^N^N) <=> + transp(Q) ** Q = mat 1 /\ Q ** transp(Q) = mat 1`;; + +let ORTHOGONAL_MATRIX = prove + (`orthogonal_matrix(Q:real^N^N) <=> transp(Q) ** Q = mat 1`, + MESON_TAC[MATRIX_LEFT_RIGHT_INVERSE; orthogonal_matrix]);; + +let ORTHOGONAL_MATRIX_ALT = prove + (`!A:real^N^N. orthogonal_matrix A <=> A ** transp A = mat 1`, + MESON_TAC[MATRIX_LEFT_RIGHT_INVERSE; orthogonal_matrix]);; + +let ORTHOGONAL_MATRIX_ID = prove + (`orthogonal_matrix(mat 1)`, + REWRITE_TAC[orthogonal_matrix; TRANSP_MAT; MATRIX_MUL_LID]);; + +let ORTHOGONAL_MATRIX_MUL = prove + (`!A B. orthogonal_matrix A /\ orthogonal_matrix B + ==> orthogonal_matrix(A ** B)`, + REWRITE_TAC[orthogonal_matrix; MATRIX_TRANSP_MUL] THEN + REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[GSYM MATRIX_MUL_ASSOC] THEN + GEN_REWRITE_TAC (LAND_CONV o RAND_CONV) [MATRIX_MUL_ASSOC] THEN + ASM_REWRITE_TAC[MATRIX_MUL_LID; MATRIX_MUL_RID]);; + +let ORTHOGONAL_TRANSFORMATION_MATRIX = prove + (`!f:real^N->real^N. + orthogonal_transformation f <=> linear f /\ orthogonal_matrix(matrix f)`, + REPEAT STRIP_TAC THEN EQ_TAC THENL + [REWRITE_TAC[orthogonal_transformation; ORTHOGONAL_MATRIX] THEN + STRIP_TAC THEN ASM_SIMP_TAC[CART_EQ; LAMBDA_BETA] THEN + X_GEN_TAC `i:num` THEN STRIP_TAC THEN + X_GEN_TAC `j:num` THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`basis i:real^N`; `basis j:real^N`]) THEN + FIRST_ASSUM(fun th -> REWRITE_TAC[GSYM(MATCH_MP MATRIX_WORKS th)]) THEN + REWRITE_TAC[DOT_MATRIX_VECTOR_MUL] THEN + ABBREV_TAC `A = transp (matrix f) ** matrix(f:real^N->real^N)` THEN + ASM_SIMP_TAC[matrix_mul; columnvector; rowvector; basis; LAMBDA_BETA; + SUM_DELTA; DIMINDEX_1; LE_REFL; dot; IN_NUMSEG; mat; + MESON[REAL_MUL_LID; REAL_MUL_LZERO; REAL_MUL_RID; REAL_MUL_RZERO] + `(if b then &1 else &0) * x = (if b then x else &0) /\ + x * (if b then &1 else &0) = (if b then x else &0)`]; + REWRITE_TAC[orthogonal_matrix; ORTHOGONAL_TRANSFORMATION; NORM_EQ] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + FIRST_ASSUM(fun th -> REWRITE_TAC[GSYM(MATCH_MP MATRIX_WORKS th)]) THEN + ASM_REWRITE_TAC[DOT_MATRIX_VECTOR_MUL] THEN + SIMP_TAC[DOT_MATRIX_PRODUCT; MATRIX_MUL_LID]]);; + +let ORTHOGONAL_MATRIX_TRANSFORMATION = prove + (`!A:real^N^N. orthogonal_matrix A <=> orthogonal_transformation(\x. A ** x)`, + REWRITE_TAC[ORTHOGONAL_TRANSFORMATION_MATRIX; MATRIX_VECTOR_MUL_LINEAR] THEN + REWRITE_TAC[MATRIX_OF_MATRIX_VECTOR_MUL]);; + +let ORTHOGONAL_MATRIX_MATRIX = prove + (`!f:real^N->real^N. + orthogonal_transformation f ==> orthogonal_matrix(matrix f)`, + SIMP_TAC[ORTHOGONAL_TRANSFORMATION_MATRIX]);; + +let DET_ORTHOGONAL_MATRIX = prove + (`!Q. orthogonal_matrix Q ==> det(Q) = &1 \/ det(Q) = -- &1`, + GEN_TAC THEN REWRITE_TAC[REAL_RING `x = &1 \/ x = -- &1 <=> x * x = &1`] THEN + GEN_REWRITE_TAC (RAND_CONV o LAND_CONV o RAND_CONV) [GSYM DET_TRANSP] THEN + SIMP_TAC[GSYM DET_MUL; orthogonal_matrix; DET_I]);; + +let ORTHOGONAL_MATRIX_TRANSP = prove + (`!A:real^N^N. orthogonal_matrix(transp A) <=> orthogonal_matrix A`, + REWRITE_TAC[orthogonal_matrix; TRANSP_TRANSP; CONJ_ACI]);; + +let MATRIX_MUL_LTRANSP_DOT_COLUMN = prove + (`!A:real^N^M. transp A ** A = (lambda i j. (column i A) dot (column j A))`, + SIMP_TAC[matrix_mul; CART_EQ; LAMBDA_BETA; transp; dot; column]);; + +let MATRIX_MUL_RTRANSP_DOT_ROW = prove + (`!A:real^N^M. A ** transp A = (lambda i j. (row i A) dot (row j A))`, + SIMP_TAC[matrix_mul; CART_EQ; LAMBDA_BETA; transp; dot; row]);; + +let ORTHOGONAL_MATRIX_ORTHONORMAL_COLUMNS = prove + (`!A:real^N^N. + orthogonal_matrix A <=> + (!i. 1 <= i /\ i <= dimindex(:N) ==> norm(column i A) = &1) /\ + (!i j. 1 <= i /\ i <= dimindex(:N) /\ + 1 <= j /\ j <= dimindex(:N) /\ ~(i = j) + ==> orthogonal (column i A) (column j A))`, + REWRITE_TAC[ORTHOGONAL_MATRIX] THEN + SIMP_TAC[MATRIX_MUL_LTRANSP_DOT_COLUMN; CART_EQ; mat; LAMBDA_BETA] THEN + REWRITE_TAC[orthogonal; NORM_EQ_1] THEN MESON_TAC[]);; + +let ORTHOGONAL_MATRIX_ORTHONORMAL_ROWS = prove + (`!A:real^N^N. + orthogonal_matrix A <=> + (!i. 1 <= i /\ i <= dimindex(:N) ==> norm(row i A) = &1) /\ + (!i j. 1 <= i /\ i <= dimindex(:N) /\ + 1 <= j /\ j <= dimindex(:N) /\ ~(i = j) + ==> orthogonal (row i A) (row j A))`, + ONCE_REWRITE_TAC[GSYM ORTHOGONAL_MATRIX_TRANSP] THEN + SIMP_TAC[ORTHOGONAL_MATRIX_ORTHONORMAL_COLUMNS; COLUMN_TRANSP]);; + +let ORTHOGONAL_MATRIX_ORTHONORMAL_ROWS_INDEXED = prove + (`!A:real^N^N. + orthogonal_matrix A <=> + (!i. 1 <= i /\ i <= dimindex(:N) ==> norm(row i A) = &1) /\ + pairwise (\i j. orthogonal (row i A) (row j A)) (1..dimindex(:N))`, + REPEAT GEN_TAC THEN REWRITE_TAC[ORTHOGONAL_MATRIX_ALT] THEN + SIMP_TAC[CART_EQ; LAMBDA_BETA; pairwise; MAT_COMPONENT] THEN + SIMP_TAC[MATRIX_MUL_RTRANSP_DOT_ROW; IN_NUMSEG; LAMBDA_BETA] THEN + REWRITE_TAC[NORM_EQ_SQUARE; REAL_POS] THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN REWRITE_TAC[orthogonal] THEN + MESON_TAC[]);; + +let ORTHOGONAL_MATRIX_ORTHONORMAL_ROWS_PAIRWISE = prove + (`!A:real^N^N. + orthogonal_matrix A <=> + CARD(rows A) = dimindex(:N) /\ + (!i. 1 <= i /\ i <= dimindex(:N) ==> norm(row i A) = &1) /\ + pairwise orthogonal (rows A)`, + REWRITE_TAC[rows; ORTHOGONAL_MATRIX_ORTHONORMAL_ROWS_INDEXED] THEN + GEN_TAC THEN ONCE_REWRITE_TAC[SIMPLE_IMAGE_GEN] THEN + REWRITE_TAC[PAIRWISE_IMAGE; GSYM numseg] THEN + MATCH_MP_TAC(TAUT `(p ==> (q <=> r /\ s)) ==> (p /\ q <=> r /\ p /\ s)`) THEN + DISCH_TAC THEN GEN_REWRITE_TAC (RAND_CONV o LAND_CONV o RAND_CONV) + [GSYM CARD_NUMSEG_1] THEN + SIMP_TAC[CARD_IMAGE_EQ_INJ; FINITE_NUMSEG] THEN + REWRITE_TAC[pairwise; IN_NUMSEG] THEN + ASM_MESON_TAC[ORTHOGONAL_REFL; NORM_ARITH `~(norm(vec 0:real^N) = &1)`]);; + +let ORTHOGONAL_MATRIX_ORTHONORMAL_ROWS_SPAN = prove + (`!A:real^N^N. + orthogonal_matrix A <=> + span(rows A) = (:real^N) /\ + (!i. 1 <= i /\ i <= dimindex(:N) ==> norm(row i A) = &1) /\ + pairwise orthogonal (rows A)`, + GEN_TAC THEN REWRITE_TAC[ORTHOGONAL_MATRIX_ORTHONORMAL_ROWS_PAIRWISE] THEN + EQ_TAC THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THENL + [MATCH_MP_TAC(SET_RULE `UNIV SUBSET s ==> s = UNIV`) THEN + MATCH_MP_TAC CARD_GE_DIM_INDEPENDENT THEN + ASM_REWRITE_TAC[DIM_UNIV; SUBSET_UNIV; LE_REFL]; + CONV_TAC SYM_CONV THEN REWRITE_TAC[GSYM DIM_UNIV] THEN + FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN REWRITE_TAC[DIM_SPAN] THEN + MATCH_MP_TAC DIM_EQ_CARD] THEN + MATCH_MP_TAC PAIRWISE_ORTHOGONAL_INDEPENDENT THEN + ASM_REWRITE_TAC[rows; IN_ELIM_THM] THEN + ASM_MESON_TAC[NORM_ARITH `~(norm(vec 0:real^N) = &1)`]);; + +let ORTHOGONAL_MATRIX_ORTHONORMAL_COLUMNS_INDEXED = prove + (`!A:real^N^N. + orthogonal_matrix A <=> + (!i. 1 <= i /\ i <= dimindex(:N) ==> norm(column i A) = &1) /\ + pairwise (\i j. orthogonal (column i A) (column j A)) (1..dimindex(:N))`, + ONCE_REWRITE_TAC[GSYM ORTHOGONAL_MATRIX_TRANSP] THEN + REWRITE_TAC[ORTHOGONAL_MATRIX_ORTHONORMAL_ROWS_INDEXED] THEN + SIMP_TAC[ROW_TRANSP; ROWS_TRANSP; pairwise; IN_NUMSEG]);; + +let ORTHOGONAL_MATRIX_ORTHONORMAL_COLUMNS_PAIRWISE = prove + (`!A:real^N^N. + orthogonal_matrix A <=> + CARD(columns A) = dimindex(:N) /\ + (!i. 1 <= i /\ i <= dimindex(:N) ==> norm(column i A) = &1) /\ + pairwise orthogonal (columns A)`, + ONCE_REWRITE_TAC[GSYM ORTHOGONAL_MATRIX_TRANSP] THEN + REWRITE_TAC[ORTHOGONAL_MATRIX_ORTHONORMAL_ROWS_PAIRWISE] THEN + SIMP_TAC[ROW_TRANSP; ROWS_TRANSP]);; + +let ORTHOGONAL_MATRIX_ORTHONORMAL_COLUMNS_SPAN = prove + (`!A:real^N^N. + orthogonal_matrix A <=> + span(columns A) = (:real^N) /\ + (!i. 1 <= i /\ i <= dimindex(:N) ==> norm(column i A) = &1) /\ + pairwise orthogonal (columns A)`, + ONCE_REWRITE_TAC[GSYM ORTHOGONAL_MATRIX_TRANSP] THEN + REWRITE_TAC[ORTHOGONAL_MATRIX_ORTHONORMAL_ROWS_SPAN] THEN + SIMP_TAC[ROW_TRANSP; ROWS_TRANSP]);; + +let ORTHOGONAL_MATRIX_2 = prove + (`!A:real^2^2. orthogonal_matrix A <=> + A$1$1 pow 2 + A$2$1 pow 2 = &1 /\ + A$1$2 pow 2 + A$2$2 pow 2 = &1 /\ + A$1$1 * A$1$2 + A$2$1 * A$2$2 = &0`, + SIMP_TAC[orthogonal_matrix; CART_EQ; matrix_mul; LAMBDA_BETA; + TRANSP_COMPONENT; MAT_COMPONENT] THEN + REWRITE_TAC[DIMINDEX_2; FORALL_2; SUM_2] THEN + CONV_TAC NUM_REDUCE_CONV THEN CONV_TAC REAL_RING);; + +let ORTHOGONAL_MATRIX_2_ALT = prove + (`!A:real^2^2. orthogonal_matrix A <=> + A$1$1 pow 2 + A$2$1 pow 2 = &1 /\ + (A$1$1 = A$2$2 /\ A$1$2 = --(A$2$1) \/ + A$1$1 = --(A$2$2) /\ A$1$2 = A$2$1)`, + REWRITE_TAC[ORTHOGONAL_MATRIX_2] THEN CONV_TAC REAL_RING);; + +let ORTHOGONAL_MATRIX_INV = prove + (`!A:real^N^N. orthogonal_matrix A ==> matrix_inv A = transp A`, + MESON_TAC[orthogonal_matrix; MATRIX_INV_UNIQUE]);; + +let ORTHOGONAL_TRANSFORMATION_ORTHOGONAL_EIGENVECTORS = prove + (`!f:real^N->real^N v w a b. + orthogonal_transformation f /\ f v = a % v /\ f w = b % w /\ ~(a = b) + ==> orthogonal v w`, + REWRITE_TAC[orthogonal_transformation] THEN REPEAT STRIP_TAC THEN + FIRST_X_ASSUM(fun th -> + MP_TAC(SPECL [`v:real^N`; `v:real^N`] th) THEN + MP_TAC(SPECL [`v:real^N`; `w:real^N`] th) THEN + MP_TAC(SPECL [`w:real^N`; `w:real^N`] th)) THEN + ASM_REWRITE_TAC[DOT_LMUL; DOT_RMUL; orthogonal] THEN + REWRITE_TAC[REAL_MUL_ASSOC; REAL_RING `x * y = y <=> x = &1 \/ y = &0`] THEN + REWRITE_TAC[DOT_EQ_0] THEN + ASM_CASES_TAC `v:real^N = vec 0` THEN ASM_REWRITE_TAC[DOT_LZERO] THEN + ASM_CASES_TAC `w:real^N = vec 0` THEN ASM_REWRITE_TAC[DOT_RZERO] THEN + ASM_CASES_TAC `(v:real^N) dot w = &0` THEN ASM_REWRITE_TAC[] THEN + UNDISCH_TAC `~(a:real = b)` THEN CONV_TAC REAL_RING);; + +let ORTHOGONAL_MATRIX_ORTHOGONAL_EIGENVECTORS = prove + (`!A:real^N^N v w a b. + orthogonal_matrix A /\ A ** v = a % v /\ A ** w = b % w /\ ~(a = b) + ==> orthogonal v w`, + REWRITE_TAC[ORTHOGONAL_MATRIX_TRANSFORMATION; + ORTHOGONAL_TRANSFORMATION_ORTHOGONAL_EIGENVECTORS]);; + +(* ------------------------------------------------------------------------- *) +(* Linearity of scaling, and hence isometry, that preserves origin. *) +(* ------------------------------------------------------------------------- *) + +let SCALING_LINEAR = prove + (`!f:real^M->real^N c. + (f(vec 0) = vec 0) /\ (!x y. dist(f x,f y) = c * dist(x,y)) + ==> linear(f)`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN `!v w. ((f:real^M->real^N) v) dot (f w) = c pow 2 * (v dot w)` + ASSUME_TAC THENL + [FIRST_ASSUM(MP_TAC o GEN `v:real^M` o + SPECL [`v:real^M`; `vec 0 :real^M`]) THEN + REWRITE_TAC[dist] THEN ASM_REWRITE_TAC[VECTOR_SUB_RZERO] THEN + DISCH_TAC THEN ASM_REWRITE_TAC[DOT_NORM_NEG; GSYM dist] THEN + REAL_ARITH_TAC; + ALL_TAC] THEN + REWRITE_TAC[linear; VECTOR_EQ] THEN + ASM_REWRITE_TAC[DOT_LADD; DOT_RADD; DOT_LMUL; DOT_RMUL] THEN + REAL_ARITH_TAC);; + +let ISOMETRY_LINEAR = prove + (`!f:real^M->real^N. + (f(vec 0) = vec 0) /\ (!x y. dist(f x,f y) = dist(x,y)) + ==> linear(f)`, + MESON_TAC[SCALING_LINEAR; REAL_MUL_LID]);; + +let ISOMETRY_IMP_AFFINITY = prove + (`!f:real^M->real^N. + (!x y. dist(f x,f y) = dist(x,y)) + ==> ?h. linear h /\ !x. f(x) = f(vec 0) + h(x)`, + REPEAT STRIP_TAC THEN + EXISTS_TAC `\x. (f:real^M->real^N) x - f(vec 0)` THEN + REWRITE_TAC[VECTOR_ARITH `a + (x - a):real^N = x`] THEN + MATCH_MP_TAC ISOMETRY_LINEAR THEN REWRITE_TAC[VECTOR_SUB_REFL] THEN + ASM_REWRITE_TAC[NORM_ARITH `dist(x - a:real^N,y - a) = dist(x,y)`]);; + +(* ------------------------------------------------------------------------- *) +(* Hence another formulation of orthogonal transformation. *) +(* ------------------------------------------------------------------------- *) + +let ORTHOGONAL_TRANSFORMATION_ISOMETRY = prove + (`!f:real^N->real^N. + orthogonal_transformation f <=> + (f(vec 0) = vec 0) /\ (!x y. dist(f x,f y) = dist(x,y))`, + GEN_TAC THEN REWRITE_TAC[ORTHOGONAL_TRANSFORMATION] THEN EQ_TAC THENL + [MESON_TAC[LINEAR_0; LINEAR_SUB; dist]; STRIP_TAC] THEN + ASM_SIMP_TAC[ISOMETRY_LINEAR] THEN X_GEN_TAC `x:real^N` THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`x:real^N`; `vec 0:real^N`]) THEN + ASM_REWRITE_TAC[dist; VECTOR_SUB_RZERO]);; + +(* ------------------------------------------------------------------------- *) +(* Can extend an isometry from unit sphere. *) +(* ------------------------------------------------------------------------- *) + +let ISOMETRY_SPHERE_EXTEND = prove + (`!f:real^N->real^N. + (!x. norm(x) = &1 ==> norm(f x) = &1) /\ + (!x y. norm(x) = &1 /\ norm(y) = &1 ==> dist(f x,f y) = dist(x,y)) + ==> ?g. orthogonal_transformation g /\ + (!x. norm(x) = &1 ==> g(x) = f(x))`, + let lemma = prove + (`!x:real^N y:real^N x':real^N y':real^N x0 y0 x0' y0'. + x = norm(x) % x0 /\ y = norm(y) % y0 /\ + x' = norm(x) % x0' /\ y' = norm(y) % y0' /\ + norm(x0) = &1 /\ norm(x0') = &1 /\ norm(y0) = &1 /\ norm(y0') = &1 /\ + norm(x0' - y0') = norm(x0 - y0) + ==> norm(x' - y') = norm(x - y)`, + REPEAT GEN_TAC THEN + MAP_EVERY ABBREV_TAC [`a = norm(x:real^N)`; `b = norm(y:real^N)`] THEN + REPLICATE_TAC 4 (DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + ASM_REWRITE_TAC[] THEN REWRITE_TAC[NORM_EQ; NORM_EQ_1] THEN + REWRITE_TAC[DOT_LSUB; DOT_RSUB; DOT_LMUL; DOT_RMUL] THEN + REWRITE_TAC[DOT_SYM] THEN CONV_TAC REAL_RING) in + REPEAT STRIP_TAC THEN + EXISTS_TAC `\x. if x = vec 0 then vec 0 + else norm(x) % (f:real^N->real^N)(inv(norm x) % x)` THEN + REWRITE_TAC[ORTHOGONAL_TRANSFORMATION_ISOMETRY] THEN + SIMP_TAC[VECTOR_MUL_LID; REAL_INV_1] THEN CONJ_TAC THENL + [ALL_TAC; MESON_TAC[NORM_0; REAL_ARITH `~(&1 = &0)`]] THEN + REPEAT GEN_TAC THEN REPEAT(COND_CASES_TAC THEN ASM_REWRITE_TAC[]) THEN + REWRITE_TAC[dist; VECTOR_SUB_LZERO; VECTOR_SUB_RZERO; NORM_NEG; NORM_MUL; + REAL_ABS_NORM] THEN + ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN + ASM_SIMP_TAC[GSYM REAL_EQ_RDIV_EQ; NORM_POS_LT] THEN + ASM_SIMP_TAC[REAL_DIV_REFL; REAL_LT_IMP_NZ; NORM_EQ_0] THEN + TRY(FIRST_X_ASSUM MATCH_MP_TAC) THEN + REWRITE_TAC[NORM_MUL; REAL_ABS_INV; REAL_ABS_NORM] THEN + ASM_SIMP_TAC[REAL_MUL_LINV; NORM_EQ_0] THEN + MATCH_MP_TAC lemma THEN MAP_EVERY EXISTS_TAC + [`inv(norm x) % x:real^N`; `inv(norm y) % y:real^N`; + `(f:real^N->real^N) (inv (norm x) % x)`; + `(f:real^N->real^N) (inv (norm y) % y)`] THEN + REWRITE_TAC[NORM_MUL; VECTOR_MUL_ASSOC; REAL_ABS_INV; REAL_ABS_NORM] THEN + ASM_SIMP_TAC[REAL_MUL_LINV; REAL_MUL_RINV; NORM_EQ_0] THEN + ASM_REWRITE_TAC[GSYM dist; VECTOR_MUL_LID] THEN + REPEAT CONJ_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + REWRITE_TAC[NORM_MUL; VECTOR_MUL_ASSOC; REAL_ABS_INV; REAL_ABS_NORM] THEN + ASM_SIMP_TAC[REAL_MUL_LINV; REAL_MUL_RINV; NORM_EQ_0]);; + +let ORTHOGONAL_TRANSFORMATION_LINEAR = prove + (`!f:real^N->real^N. orthogonal_transformation f ==> linear f`, + SIMP_TAC[orthogonal_transformation]);; + +let ORTHOGONAL_TRANSFORMATION_INJECTIVE = prove + (`!f:real^N->real^N. + orthogonal_transformation f ==> !x y. f x = f y ==> x = y`, + SIMP_TAC[LINEAR_INJECTIVE_0; ORTHOGONAL_TRANSFORMATION; GSYM NORM_EQ_0]);; + +let ORTHOGONAL_TRANSFORMATION_SURJECTIVE = prove + (`!f:real^N->real^N. + orthogonal_transformation f ==> !y. ?x. f x = y`, + MESON_TAC[LINEAR_INJECTIVE_IMP_SURJECTIVE; + ORTHOGONAL_TRANSFORMATION_INJECTIVE; orthogonal_transformation]);; + +let ORTHOGONAL_TRANSFORMATION_INVERSE_o = prove + (`!f:real^N->real^N. + orthogonal_transformation f + ==> ?g. orthogonal_transformation g /\ g o f = I /\ f o g = I`, + REPEAT STRIP_TAC THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP ORTHOGONAL_TRANSFORMATION_LINEAR) THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP ORTHOGONAL_TRANSFORMATION_INJECTIVE) THEN + MP_TAC(ISPEC `f:real^N->real^N` LINEAR_INJECTIVE_LEFT_INVERSE) THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC MONO_EXISTS THEN + X_GEN_TAC `g:real^N->real^N` THEN STRIP_TAC THEN + MP_TAC(ISPECL [`f:real^N->real^N`; `g:real^N->real^N`] + LINEAR_INVERSE_LEFT) THEN + ASM_REWRITE_TAC[] THEN DISCH_TAC THEN ASM_REWRITE_TAC[] THEN + ASM_REWRITE_TAC[ORTHOGONAL_TRANSFORMATION] THEN X_GEN_TAC `v:real^N` THEN + MATCH_MP_TAC EQ_TRANS THEN + EXISTS_TAC `norm((f:real^N->real^N)((g:real^N->real^N) v))` THEN + CONJ_TAC THENL [ASM_MESON_TAC[ORTHOGONAL_TRANSFORMATION]; ALL_TAC] THEN + RULE_ASSUM_TAC(REWRITE_RULE[FUN_EQ_THM; o_THM; I_THM]) THEN + ASM_REWRITE_TAC[]);; + +let ORTHOGONAL_TRANSFORMATION_INVERSE = prove + (`!f:real^N->real^N. + orthogonal_transformation f + ==> ?g. orthogonal_transformation g /\ + (!x. g(f x) = x) /\ (!y. f(g y) = y)`, + GEN_TAC THEN + DISCH_THEN(MP_TAC o MATCH_MP ORTHOGONAL_TRANSFORMATION_INVERSE_o) THEN + REWRITE_TAC[FUN_EQ_THM; o_THM; I_THM]);; + +let ORTHOGONAL_TRANSFORMATION_ID = prove + (`orthogonal_transformation(\x. x)`, + REWRITE_TAC[orthogonal_transformation; LINEAR_ID]);; + +let ORTHOGONAL_TRANSFORMATION_I = prove + (`orthogonal_transformation I`, + REWRITE_TAC[I_DEF; ORTHOGONAL_TRANSFORMATION_ID]);; + +(* ------------------------------------------------------------------------- *) +(* We can find an orthogonal matrix taking any unit vector to any other. *) +(* ------------------------------------------------------------------------- *) + +let FINITE_INDEX_NUMSEG_SPECIAL = prove + (`!s a:A. + FINITE s /\ a IN s + ==> ?f. (!i j. i IN 1..CARD s /\ j IN 1..CARD s /\ f i = f j + ==> i = j) /\ + s = IMAGE f (1..CARD s) /\ + f 1 = a`, + REPEAT STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [FINITE_INDEX_NUMSEG]) THEN + DISCH_THEN(X_CHOOSE_THEN `f:num->A` STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN `?k. k IN 1..CARD(s:A->bool) /\ (a:A) = f k` + STRIP_ASSUME_TAC THENL[ASM SET_TAC[]; ALL_TAC] THEN + EXISTS_TAC `(f:num->A) o swap(1,k)` THEN + SUBGOAL_THEN `1 IN 1..CARD(s:A->bool)` ASSUME_TAC THENL + [REWRITE_TAC[IN_NUMSEG; LE_REFL; ARITH_RULE `1 <= x <=> ~(x = 0)`] THEN + ASM_SIMP_TAC[CARD_EQ_0; ARITH_EQ] THEN ASM SET_TAC[]; + ALL_TAC] THEN + ASM_REWRITE_TAC[o_THM; swap] THEN + CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + UNDISCH_THEN `s = IMAGE (f:num->A) (1..CARD(s:A->bool))` + (fun th -> GEN_REWRITE_TAC LAND_CONV [th]) THEN + REWRITE_TAC[EXTENSION; IN_IMAGE; o_THM] THEN + X_GEN_TAC `b:A` THEN EQ_TAC THEN + DISCH_THEN(X_CHOOSE_THEN `i:num` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `swap(1,k) i` THEN + REWRITE_TAC[swap] THEN ASM_MESON_TAC[swap]);; + +let ORTHOGONAL_MATRIX_EXISTS_BASIS = prove + (`!a:real^N. + norm(a) = &1 + ==> ?A. orthogonal_matrix A /\ A**(basis 1) = a`, + REPEAT STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o MATCH_MP VECTOR_IN_ORTHONORMAL_BASIS) THEN + REWRITE_TAC[HAS_SIZE] THEN + DISCH_THEN(X_CHOOSE_THEN `s:real^N->bool` STRIP_ASSUME_TAC) THEN + MP_TAC(ISPECL [`s:real^N->bool`; `a:real^N`] + FINITE_INDEX_NUMSEG_SPECIAL) THEN ASM_REWRITE_TAC[IN_NUMSEG] THEN + REWRITE_TAC[TAUT `a /\ b ==> c <=> c \/ ~a \/ ~b`] THEN + DISCH_THEN(X_CHOOSE_THEN `f:num->real^N` + (CONJUNCTS_THEN2 ASSUME_TAC (CONJUNCTS_THEN2 (ASSUME_TAC o SYM) + ASSUME_TAC))) THEN + EXISTS_TAC `(lambda i j. ((f j):real^N)$i):real^N^N` THEN + SIMP_TAC[CART_EQ; LAMBDA_BETA; matrix_vector_mul; BASIS_COMPONENT; + IN_NUMSEG] THEN + ONCE_REWRITE_TAC[COND_RAND] THEN SIMP_TAC[REAL_MUL_RZERO; SUM_DELTA] THEN + ASM_REWRITE_TAC[IN_NUMSEG; REAL_MUL_RID; LE_REFL; DIMINDEX_GE_1] THEN + REWRITE_TAC[ORTHOGONAL_MATRIX_ORTHONORMAL_COLUMNS] THEN + SIMP_TAC[column; LAMBDA_BETA] THEN CONJ_TAC THENL + [X_GEN_TAC `i:num` THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC EQ_TRANS THEN + EXISTS_TAC `norm((f:num->real^N) i)` THEN CONJ_TAC THENL + [AP_TERM_TAC THEN ASM_SIMP_TAC[CART_EQ; LAMBDA_BETA]; + ASM_MESON_TAC[IN_IMAGE; IN_NUMSEG]]; + MAP_EVERY X_GEN_TAC [`i:num`; `j:num`] THEN STRIP_TAC THEN + SUBGOAL_THEN `orthogonal ((f:num->real^N) i) (f j)` MP_TAC THENL + [ASM_MESON_TAC[pairwise; IN_IMAGE; IN_NUMSEG]; ALL_TAC] THEN + MATCH_MP_TAC EQ_IMP THEN BINOP_TAC THEN + ASM_SIMP_TAC[CART_EQ; LAMBDA_BETA]]);; + +let ORTHOGONAL_TRANSFORMATION_EXISTS_1 = prove + (`!a b:real^N. + norm(a) = &1 /\ norm(b) = &1 + ==> ?f. orthogonal_transformation f /\ f a = b`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPEC `b:real^N` ORTHOGONAL_MATRIX_EXISTS_BASIS) THEN + MP_TAC(ISPEC `a:real^N` ORTHOGONAL_MATRIX_EXISTS_BASIS) THEN + ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `A:real^N^N` (STRIP_ASSUME_TAC o GSYM)) THEN + DISCH_THEN(X_CHOOSE_THEN `B:real^N^N` (STRIP_ASSUME_TAC o GSYM)) THEN + EXISTS_TAC `\x:real^N. ((B:real^N^N) ** transp(A:real^N^N)) ** x` THEN + REWRITE_TAC[ORTHOGONAL_TRANSFORMATION_MATRIX; MATRIX_VECTOR_MUL_LINEAR; + MATRIX_OF_MATRIX_VECTOR_MUL] THEN + ASM_SIMP_TAC[ORTHOGONAL_MATRIX_MUL; ORTHOGONAL_MATRIX_TRANSP] THEN + REWRITE_TAC[GSYM MATRIX_VECTOR_MUL_ASSOC] THEN AP_TERM_TAC THEN + RULE_ASSUM_TAC(REWRITE_RULE[ORTHOGONAL_MATRIX]) THEN + ASM_REWRITE_TAC[MATRIX_VECTOR_MUL_ASSOC; MATRIX_VECTOR_MUL_LID]);; + +let ORTHOGONAL_TRANSFORMATION_EXISTS = prove + (`!a b:real^N. + norm(a) = norm(b) ==> ?f. orthogonal_transformation f /\ f a = b`, + REPEAT GEN_TAC THEN ASM_CASES_TAC `b:real^N = vec 0` THEN + ASM_SIMP_TAC[NORM_0; NORM_EQ_0] THENL + [MESON_TAC[ORTHOGONAL_TRANSFORMATION_ID]; ALL_TAC] THEN + ASM_CASES_TAC `a:real^N = vec 0` THENL + [ASM_MESON_TAC[NORM_0; NORM_EQ_0]; ALL_TAC] THEN + DISCH_TAC THEN + MP_TAC(ISPECL [`inv(norm a) % a:real^N`; `inv(norm b) % b:real^N`] + ORTHOGONAL_TRANSFORMATION_EXISTS_1) THEN + REWRITE_TAC[NORM_MUL; REAL_ABS_INV; REAL_ABS_NORM] THEN + ASM_SIMP_TAC[NORM_EQ_0; REAL_MUL_LINV] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `f:real^N->real^N` THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + ASM_REWRITE_TAC[] THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP LINEAR_CMUL o + MATCH_MP ORTHOGONAL_TRANSFORMATION_LINEAR) THEN + ASM_REWRITE_TAC[VECTOR_ARITH + `a % x:real^N = a % y <=> a % (x - y) = vec 0`] THEN + ASM_REWRITE_TAC[VECTOR_MUL_EQ_0; REAL_INV_EQ_0; NORM_EQ_0; VECTOR_SUB_EQ]);; + +(* ------------------------------------------------------------------------- *) +(* Or indeed, taking any subspace to another of suitable dimension. *) +(* ------------------------------------------------------------------------- *) + +let ORTHOGONAL_TRANSFORMATION_INTO_SUBSPACE = prove + (`!s t:real^N->bool. + subspace s /\ subspace t /\ dim s <= dim t + ==> ?f. orthogonal_transformation f /\ IMAGE f s SUBSET t`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPEC `t:real^N->bool` ORTHONORMAL_BASIS_SUBSPACE) THEN + MP_TAC(ISPEC `s:real^N->bool` ORTHONORMAL_BASIS_SUBSPACE) THEN + ASM_REWRITE_TAC[HAS_SIZE] THEN + DISCH_THEN(X_CHOOSE_THEN `b:real^N->bool` STRIP_ASSUME_TAC) THEN + DISCH_THEN(X_CHOOSE_THEN `c:real^N->bool` STRIP_ASSUME_TAC) THEN + MP_TAC(ISPECL [`c:real^N->bool`; `(:real^N)`] ORTHONORMAL_EXTENSION) THEN + MP_TAC(ISPECL [`b:real^N->bool`; `(:real^N)`] ORTHONORMAL_EXTENSION) THEN + ASM_REWRITE_TAC[UNION_UNIV; SPAN_UNIV; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `b':real^N->bool` THEN STRIP_TAC THEN + X_GEN_TAC `c':real^N->bool` THEN STRIP_TAC THEN + SUBGOAL_THEN + `independent(b UNION b':real^N->bool) /\ + independent(c UNION c':real^N->bool)` + STRIP_ASSUME_TAC THENL + [CONJ_TAC THEN MATCH_MP_TAC PAIRWISE_ORTHOGONAL_INDEPENDENT THEN + ASM_REWRITE_TAC[IN_UNION] THEN + ASM_MESON_TAC[NORM_ARITH `~(norm(vec 0:real^N) = &1)`]; + ALL_TAC] THEN + SUBGOAL_THEN `FINITE(b UNION b':real^N->bool) /\ + FINITE(c UNION c':real^N->bool)` + MP_TAC THENL + [ASM_SIMP_TAC[PAIRWISE_ORTHOGONAL_IMP_FINITE]; + REWRITE_TAC[FINITE_UNION] THEN STRIP_TAC] THEN + SUBGOAL_THEN + `?f:real^N->real^N. + (!x y. x IN b UNION b' /\ y IN b UNION b' ==> (f x = f y <=> x = y)) /\ + IMAGE f b SUBSET c /\ + IMAGE f (b UNION b') SUBSET c UNION c'` + (X_CHOOSE_THEN `fb:real^N->real^N` STRIP_ASSUME_TAC) + THENL + [MP_TAC(ISPECL [`b:real^N->bool`; `c:real^N->bool`] + CARD_LE_INJ) THEN + ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM; INJECTIVE_ON_ALT] THEN + X_GEN_TAC `f:real^N->real^N` THEN STRIP_TAC THEN + MP_TAC(ISPECL [`b':real^N->bool`; + `(c UNION c') DIFF IMAGE (f:real^N->real^N) b`] + CARD_LE_INJ) THEN + ANTS_TAC THENL + [ASM_SIMP_TAC[FINITE_UNION; FINITE_DIFF] THEN + W(MP_TAC o PART_MATCH (lhs o rand) CARD_DIFF o rand o snd) THEN + ASM_REWRITE_TAC[FINITE_UNION] THEN + ANTS_TAC THENL [ASM SET_TAC[]; DISCH_THEN SUBST1_TAC] THEN + MATCH_MP_TAC(ARITH_RULE `a + b:num = c ==> a <= c - b`) THEN + W(MP_TAC o PART_MATCH (lhs o rand) CARD_IMAGE_INJ o + rand o lhs o snd) THEN + ANTS_TAC THENL [ASM_MESON_TAC[]; DISCH_THEN SUBST1_TAC] THEN + W(MP_TAC o PART_MATCH (rhs o rand) CARD_UNION o lhs o snd) THEN + ANTS_TAC THENL [ASM SET_TAC[]; DISCH_THEN(SUBST1_TAC o SYM)] THEN + GEN_REWRITE_TAC (LAND_CONV o RAND_CONV) [UNION_COMM] THEN + MATCH_MP_TAC(MESON[LE_ANTISYM] + `(FINITE s /\ CARD s <= CARD t) /\ + (FINITE t /\ CARD t <= CARD s) ==> CARD s = CARD t`) THEN + CONJ_TAC THEN MATCH_MP_TAC INDEPENDENT_SPAN_BOUND THEN + ASM_REWRITE_TAC[FINITE_UNION; SUBSET_UNIV]; + DISCH_THEN(X_CHOOSE_THEN `g:real^N->real^N` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `\x. if x IN b then (f:real^N->real^N) x else g x` THEN + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE] THEN ASM SET_TAC[]]; + ALL_TAC] THEN + MP_TAC(ISPECL [`fb:real^N->real^N`; `b UNION b':real^N->bool`] + LINEAR_INDEPENDENT_EXTEND) THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `f:real^N->real^N` THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN CONJ_TAC THENL + [ASM_REWRITE_TAC[ORTHOGONAL_TRANSFORMATION]; + REWRITE_TAC[SYM(ASSUME `span b:real^N->bool = s`)] THEN + ASM_SIMP_TAC[GSYM SPAN_LINEAR_IMAGE] THEN + REWRITE_TAC[SYM(ASSUME `span c:real^N->bool = t`)] THEN + MATCH_MP_TAC SPAN_MONO THEN ASM SET_TAC[]] THEN + SUBGOAL_THEN + `!v. v IN UNIV ==> norm((f:real^N->real^N) v) = norm v` + (fun th -> ASM_MESON_TAC[th; IN_UNIV]) THEN + UNDISCH_THEN `span (b UNION b') = (:real^N)` (SUBST1_TAC o SYM) THEN + ASM_SIMP_TAC[SPAN_FINITE; FINITE_UNION; IN_ELIM_THM; LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`z:real^N`; `u:real^N->real`] THEN + DISCH_THEN(SUBST1_TAC o SYM) THEN ASM_SIMP_TAC[LINEAR_VSUM; FINITE_UNION] THEN + REWRITE_TAC[o_DEF; NORM_EQ_SQUARE; NORM_POS_LE; GSYM NORM_POW_2] THEN + ASM_SIMP_TAC[LINEAR_CMUL] THEN + W(MP_TAC o PART_MATCH (lhand o rand) + NORM_VSUM_PYTHAGOREAN o rand o snd) THEN + W(MP_TAC o PART_MATCH (lhand o rand) + NORM_VSUM_PYTHAGOREAN o lhand o rand o snd) THEN + RULE_ASSUM_TAC(REWRITE_RULE[pairwise]) THEN + ASM_SIMP_TAC[pairwise; ORTHOGONAL_CLAUSES; FINITE_UNION] THEN ANTS_TAC THENL + [REPEAT STRIP_TAC THEN REWRITE_TAC[ORTHOGONAL_MUL] THEN + REPEAT DISJ2_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM SET_TAC[]; + REPEAT(DISCH_THEN SUBST1_TAC) THEN ASM_SIMP_TAC[NORM_MUL] THEN + MATCH_MP_TAC SUM_EQ THEN ASM SET_TAC[]]);; + +let ORTHOGONAL_TRANSFORMATION_ONTO_SUBSPACE = prove + (`!s t:real^N->bool. + subspace s /\ subspace t /\ dim s = dim t + ==> ?f. orthogonal_transformation f /\ IMAGE f s = t`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`s:real^N->bool`; `t:real^N->bool`] + ORTHOGONAL_TRANSFORMATION_INTO_SUBSPACE) THEN + ASM_REWRITE_TAC[LE_REFL] THEN MATCH_MP_TAC MONO_EXISTS THEN + X_GEN_TAC `f:real^N->real^N` THEN STRIP_TAC THEN + ASM_REWRITE_TAC[] THEN + SUBGOAL_THEN `span(IMAGE (f:real^N->real^N) s) = span t` MP_TAC THENL + [MATCH_MP_TAC DIM_EQ_SPAN THEN ASM_REWRITE_TAC[] THEN + W(MP_TAC o PART_MATCH (lhs o rand) DIM_INJECTIVE_LINEAR_IMAGE o + rand o snd) THEN + ASM_MESON_TAC[LE_REFL; orthogonal_transformation; + ORTHOGONAL_TRANSFORMATION_INJECTIVE]; + ASM_SIMP_TAC[SPAN_LINEAR_IMAGE; ORTHOGONAL_TRANSFORMATION_LINEAR] THEN + ASM_SIMP_TAC[SPAN_OF_SUBSPACE]]);; + +(* ------------------------------------------------------------------------- *) +(* Rotation, reflection, rotoinversion. *) +(* ------------------------------------------------------------------------- *) + +let rotation_matrix = new_definition + `rotation_matrix Q <=> orthogonal_matrix Q /\ det(Q) = &1`;; + +let rotoinversion_matrix = new_definition + `rotoinversion_matrix Q <=> orthogonal_matrix Q /\ det(Q) = -- &1`;; + +let ORTHOGONAL_ROTATION_OR_ROTOINVERSION = prove + (`!Q. orthogonal_matrix Q <=> rotation_matrix Q \/ rotoinversion_matrix Q`, + MESON_TAC[rotation_matrix; rotoinversion_matrix; DET_ORTHOGONAL_MATRIX]);; + +let ROTATION_MATRIX_2 = prove + (`!A:real^2^2. rotation_matrix A <=> + A$1$1 pow 2 + A$2$1 pow 2 = &1 /\ + A$1$1 = A$2$2 /\ A$1$2 = --(A$2$1)`, + REWRITE_TAC[rotation_matrix; ORTHOGONAL_MATRIX_2; DET_2] THEN + CONV_TAC REAL_RING);; + +(* ------------------------------------------------------------------------- *) +(* Slightly stronger results giving rotation, but only in >= 2 dimensions. *) +(* ------------------------------------------------------------------------- *) + +let ROTATION_MATRIX_EXISTS_BASIS = prove + (`!a:real^N. + 2 <= dimindex(:N) /\ norm(a) = &1 + ==> ?A. rotation_matrix A /\ A**(basis 1) = a`, + REPEAT STRIP_TAC THEN + FIRST_X_ASSUM(X_CHOOSE_THEN `A:real^N^N` STRIP_ASSUME_TAC o + MATCH_MP ORTHOGONAL_MATRIX_EXISTS_BASIS) THEN + FIRST_ASSUM(DISJ_CASES_TAC o GEN_REWRITE_RULE I + [ORTHOGONAL_ROTATION_OR_ROTOINVERSION]) + THENL [ASM_MESON_TAC[]; ALL_TAC] THEN + EXISTS_TAC `transp(lambda i. if i = dimindex(:N) then -- &1 % transp A$i + else (transp A:real^N^N)$i):real^N^N` THEN + REWRITE_TAC[rotation_matrix; DET_TRANSP] THEN REPEAT CONJ_TAC THENL + [REWRITE_TAC[ORTHOGONAL_MATRIX_TRANSP]; + SIMP_TAC[DET_ROW_MUL; DIMINDEX_GE_1; LE_REFL] THEN + MATCH_MP_TAC(REAL_ARITH `x = -- &1 ==> -- &1 * x = &1`) THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [rotoinversion_matrix]) THEN + DISCH_THEN(SUBST1_TAC o SYM o CONJUNCT2) THEN + GEN_REWRITE_TAC RAND_CONV [GSYM DET_TRANSP] THEN + AP_TERM_TAC THEN SIMP_TAC[CART_EQ; LAMBDA_BETA] THEN MESON_TAC[]; + FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN + SIMP_TAC[matrix_vector_mul; LAMBDA_BETA; CART_EQ; transp; + BASIS_COMPONENT] THEN + ONCE_REWRITE_TAC[REAL_ARITH + `x * (if p then &1 else &0) = if p then x else &0`] THEN + ASM_SIMP_TAC[ARITH_RULE `2 <= n ==> ~(1 = n)`; LAMBDA_BETA]] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I + [GSYM ORTHOGONAL_MATRIX_TRANSP]) THEN + SPEC_TAC(`transp(A:real^N^N)`,`B:real^N^N`) THEN GEN_TAC THEN + SUBGOAL_THEN `!i. 1 <= i /\ i <= dimindex(:N) + ==> row i ((lambda i. if i = dimindex(:N) then -- &1 % B$i + else (B:real^N^N)$i):real^N^N) = + if i = dimindex(:N) then --(row i B) else row i B` + ASSUME_TAC THENL + [SIMP_TAC[row; LAMBDA_BETA; LAMBDA_ETA; VECTOR_MUL_LID; VECTOR_MUL_LNEG]; + ASM_SIMP_TAC[ORTHOGONAL_MATRIX_ORTHONORMAL_ROWS] THEN + ASM_MESON_TAC[ORTHOGONAL_LNEG; ORTHOGONAL_RNEG; NORM_NEG]]);; + +let ROTATION_EXISTS_1 = prove + (`!a b:real^N. + 2 <= dimindex(:N) /\ norm(a) = &1 /\ norm(b) = &1 + ==> ?f. orthogonal_transformation f /\ det(matrix f) = &1 /\ f a = b`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPEC `b:real^N` ROTATION_MATRIX_EXISTS_BASIS) THEN + MP_TAC(ISPEC `a:real^N` ROTATION_MATRIX_EXISTS_BASIS) THEN + ASM_REWRITE_TAC[rotation_matrix] THEN + DISCH_THEN(X_CHOOSE_THEN `A:real^N^N` + (CONJUNCTS_THEN2 STRIP_ASSUME_TAC (ASSUME_TAC o SYM))) THEN + DISCH_THEN(X_CHOOSE_THEN `B:real^N^N` + (CONJUNCTS_THEN2 STRIP_ASSUME_TAC (ASSUME_TAC o SYM))) THEN + EXISTS_TAC `\x:real^N. ((B:real^N^N) ** transp(A:real^N^N)) ** x` THEN + REWRITE_TAC[ORTHOGONAL_TRANSFORMATION_MATRIX; MATRIX_VECTOR_MUL_LINEAR; + MATRIX_OF_MATRIX_VECTOR_MUL; DET_MUL; DET_TRANSP] THEN + ASM_SIMP_TAC[ORTHOGONAL_MATRIX_MUL; ORTHOGONAL_MATRIX_TRANSP] THEN + REWRITE_TAC[GSYM MATRIX_VECTOR_MUL_ASSOC; REAL_MUL_LID] THEN AP_TERM_TAC THEN + RULE_ASSUM_TAC(REWRITE_RULE[ORTHOGONAL_MATRIX]) THEN + ASM_REWRITE_TAC[MATRIX_VECTOR_MUL_ASSOC; MATRIX_VECTOR_MUL_LID]);; + +let ROTATION_EXISTS = prove + (`!a b:real^N. + 2 <= dimindex(:N) /\ norm(a) = norm(b) + ==> ?f. orthogonal_transformation f /\ det(matrix f) = &1 /\ f a = b`, + REPEAT GEN_TAC THEN ASM_CASES_TAC `b:real^N = vec 0` THEN + ASM_SIMP_TAC[NORM_0; NORM_EQ_0] THENL + [MESON_TAC[ORTHOGONAL_TRANSFORMATION_ID; MATRIX_ID; DET_I]; ALL_TAC] THEN + ASM_CASES_TAC `a:real^N = vec 0` THENL + [ASM_MESON_TAC[ORTHOGONAL_TRANSFORMATION_ID; MATRIX_ID; DET_I; NORM_0; + NORM_EQ_0]; ALL_TAC] THEN + DISCH_TAC THEN + MP_TAC(ISPECL [`inv(norm a) % a:real^N`; `inv(norm b) % b:real^N`] + ROTATION_EXISTS_1) THEN + REWRITE_TAC[NORM_MUL; REAL_ABS_INV; REAL_ABS_NORM] THEN + ASM_SIMP_TAC[NORM_EQ_0; REAL_MUL_LINV] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `f:real^N->real^N` THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + ASM_REWRITE_TAC[] THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP LINEAR_CMUL o + MATCH_MP ORTHOGONAL_TRANSFORMATION_LINEAR) THEN + ASM_REWRITE_TAC[VECTOR_ARITH + `a % x:real^N = a % y <=> a % (x - y) = vec 0`] THEN + ASM_REWRITE_TAC[VECTOR_MUL_EQ_0; REAL_INV_EQ_0; NORM_EQ_0; VECTOR_SUB_EQ]);; + +let ROTATION_RIGHTWARD_LINE = prove + (`!a:real^N k. + 1 <= k /\ k <= dimindex(:N) + ==> ?b f. orthogonal_transformation f /\ + (2 <= dimindex(:N) ==> det(matrix f) = &1) /\ + f(b % basis k) = a /\ + &0 <= b`, + REPEAT STRIP_TAC THEN EXISTS_TAC `norm(a:real^N)` THEN + ASM_SIMP_TAC[VECTOR_MUL_COMPONENT; BASIS_COMPONENT; LE_REFL; DIMINDEX_GE_1; + REAL_MUL_RID; NORM_POS_LE; LT_IMP_LE; LTE_ANTISYM] THEN + REWRITE_TAC[ARITH_RULE `2 <= n <=> 1 <= n /\ ~(n = 1)`; DIMINDEX_GE_1] THEN + ASM_CASES_TAC `dimindex(:N) = 1` THEN ASM_REWRITE_TAC[] THENL + [MATCH_MP_TAC ORTHOGONAL_TRANSFORMATION_EXISTS; + MATCH_MP_TAC ROTATION_EXISTS] THEN + ASM_SIMP_TAC[NORM_MUL; NORM_BASIS; LE_REFL; DIMINDEX_GE_1] THEN + REWRITE_TAC[REAL_ABS_NORM; REAL_MUL_RID] THEN + MATCH_MP_TAC(ARITH_RULE `~(n = 1) /\ 1 <= n ==> 2 <= n`) THEN + ASM_REWRITE_TAC[DIMINDEX_GE_1]);; + +(* ------------------------------------------------------------------------- *) +(* In 3 dimensions, a rotation is indeed about an "axis". *) +(* ------------------------------------------------------------------------- *) + +let EULER_ROTATION_THEOREM = prove + (`!A:real^3^3. rotation_matrix A ==> ?v:real^3. ~(v = vec 0) /\ A ** v = v`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPEC `A - mat 1:real^3^3` HOMOGENEOUS_LINEAR_EQUATIONS_DET) THEN + REWRITE_TAC[MATRIX_VECTOR_MUL_SUB_RDISTRIB; + VECTOR_SUB_EQ; MATRIX_VECTOR_MUL_LID] THEN + DISCH_THEN SUBST1_TAC THEN POP_ASSUM MP_TAC THEN + REWRITE_TAC[rotation_matrix; orthogonal_matrix; DET_3] THEN + SIMP_TAC[CART_EQ; FORALL_3; MAT_COMPONENT; DIMINDEX_3; LAMBDA_BETA; ARITH; + MATRIX_SUB_COMPONENT; MAT_COMPONENT; SUM_3; + matrix_mul; transp; matrix_vector_mul] THEN + CONV_TAC REAL_RING);; + +let EULER_ROTOINVERSION_THEOREM = prove + (`!A:real^3^3. + rotoinversion_matrix A ==> ?v:real^3. ~(v = vec 0) /\ A ** v = --v`, + REPEAT STRIP_TAC THEN + REWRITE_TAC[VECTOR_ARITH `a:real^N = --v <=> a + v = vec 0`] THEN + MP_TAC(ISPEC `A + mat 1:real^3^3` HOMOGENEOUS_LINEAR_EQUATIONS_DET) THEN + REWRITE_TAC[MATRIX_VECTOR_MUL_ADD_RDISTRIB; MATRIX_VECTOR_MUL_LID] THEN + DISCH_THEN SUBST1_TAC THEN POP_ASSUM MP_TAC THEN + REWRITE_TAC[rotoinversion_matrix; orthogonal_matrix; DET_3] THEN + SIMP_TAC[CART_EQ; FORALL_3; MAT_COMPONENT; DIMINDEX_3; LAMBDA_BETA; ARITH; + MATRIX_ADD_COMPONENT; MAT_COMPONENT; SUM_3; + matrix_mul; transp; matrix_vector_mul] THEN + CONV_TAC REAL_RING);; + +(* ------------------------------------------------------------------------- *) +(* We can always rotate so that a hyperplane is "horizontal". *) +(* ------------------------------------------------------------------------- *) + +let ROTATION_LOWDIM_HORIZONTAL = prove + (`!s:real^N->bool. + dim s < dimindex(:N) + ==> ?f. orthogonal_transformation f /\ det(matrix f) = &1 /\ + (IMAGE f s) SUBSET {z | z$(dimindex(:N)) = &0}`, + GEN_TAC THEN ASM_CASES_TAC `dim(s:real^N->bool) = 0` THENL + [RULE_ASSUM_TAC(REWRITE_RULE[DIM_EQ_0]) THEN DISCH_TAC THEN + EXISTS_TAC `\x:real^N. x` THEN + REWRITE_TAC[ORTHOGONAL_TRANSFORMATION_ID; MATRIX_ID; DET_I] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE + `s SUBSET {a} ==> a IN t ==> IMAGE (\x. x) s SUBSET t`)) THEN + SIMP_TAC[IN_ELIM_THM; VEC_COMPONENT; LE_REFL; DIMINDEX_GE_1]; + DISCH_TAC] THEN + SUBGOAL_THEN `2 <= dimindex(:N)` ASSUME_TAC THENL + [ASM_ARITH_TAC; ALL_TAC] THEN + FIRST_X_ASSUM(X_CHOOSE_THEN `a:real^N` STRIP_ASSUME_TAC o MATCH_MP + LOWDIM_SUBSET_HYPERPLANE) THEN + MP_TAC(ISPECL [`a:real^N`; `norm(a:real^N) % basis(dimindex(:N)):real^N`] + ROTATION_EXISTS) THEN + ASM_SIMP_TAC[NORM_MUL; NORM_BASIS; LE_REFL; DIMINDEX_GE_1] THEN + REWRITE_TAC[REAL_ABS_NORM; REAL_MUL_RID] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `f:real^N->real^N` THEN + STRIP_TAC THEN ASM_REWRITE_TAC[FORALL_IN_IMAGE; SUBSET; IN_ELIM_THM] THEN + X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN + SUBGOAL_THEN `(f:real^N->real^N) x dot (f a) = &0` MP_TAC THENL + [RULE_ASSUM_TAC(REWRITE_RULE[orthogonal_transformation]) THEN + ASM_REWRITE_TAC[] THEN ONCE_REWRITE_TAC[DOT_SYM] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [SUBSET]) THEN + ASM_SIMP_TAC[SPAN_SUPERSET; IN_ELIM_THM]; + ASM_SIMP_TAC[DOT_BASIS; LE_REFL; DIMINDEX_GE_1; DOT_RMUL] THEN + ASM_REWRITE_TAC[REAL_ENTIRE; NORM_EQ_0]]);; + +let ORTHOGONAL_TRANSFORMATION_LOWDIM_HORIZONTAL = prove + (`!s:real^N->bool. + dim s < dimindex(:N) + ==> ?f. orthogonal_transformation f /\ + (IMAGE f s) SUBSET {z | z$(dimindex(:N)) = &0}`, + GEN_TAC THEN DISCH_THEN(MP_TAC o MATCH_MP ROTATION_LOWDIM_HORIZONTAL) THEN + MATCH_MP_TAC MONO_EXISTS THEN SIMP_TAC[]);; + +let ORTHOGONAL_TRANSFORMATION_BETWEEN_ORTHOGONAL_SETS = prove + (`!v:num->real^N w k. + pairwise (\i j. orthogonal (v i) (v j)) k /\ + pairwise (\i j. orthogonal (w i) (w j)) k /\ + (!i. i IN k ==> norm(v i) = norm(w i)) + ==> ?f. orthogonal_transformation f /\ + (!i. i IN k ==> f(v i) = w i)`, + let lemma1 = prove + (`!v:num->real^N n. + pairwise (\i j. orthogonal (v i) (v j)) (1..n) /\ + (!i. 1 <= i /\ i <= n ==> norm(v i) = &1) + ==> ?f. orthogonal_transformation f /\ + (!i. 1 <= i /\ i <= n ==> f(basis i) = v i)`, + REWRITE_TAC[pairwise; IN_NUMSEG; GSYM CONJ_ASSOC] THEN + REPEAT STRIP_TAC THEN + SUBGOAL_THEN `pairwise orthogonal (IMAGE (v:num->real^N) (1..n))` + ASSUME_TAC THENL + [REWRITE_TAC[PAIRWISE_IMAGE] THEN ASM_SIMP_TAC[pairwise; IN_NUMSEG]; + ALL_TAC] THEN + FIRST_ASSUM(MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + PAIRWISE_ORTHOGONAL_INDEPENDENT)) THEN + REWRITE_TAC[SET_RULE + `~(a IN IMAGE f s) <=> !x. x IN s ==> ~(f x = a)`] THEN + ANTS_TAC THENL + [REWRITE_TAC[IN_NUMSEG] THEN + ASM_MESON_TAC[NORM_0; REAL_ARITH `~(&1 = &0)`]; + DISCH_THEN(MP_TAC o CONJUNCT2 o MATCH_MP INDEPENDENT_BOUND)] THEN + SUBGOAL_THEN + `!i j. 1 <= i /\ i <= n /\ 1 <= j /\ j <= n /\ ~(i = j) + ==> ~(v i:real^N = v j)` + ASSUME_TAC THENL + [ASM_MESON_TAC[ORTHOGONAL_REFL; NORM_0; REAL_ARITH `~(&1 = &0)`]; + ALL_TAC] THEN + SUBGOAL_THEN `CARD(IMAGE (v:num->real^N) (1..n)) = n` ASSUME_TAC THENL + [W(MP_TAC o PART_MATCH (lhs o rand) CARD_IMAGE_INJ o lhs o snd) THEN + ASM_REWRITE_TAC[CARD_NUMSEG_1; IN_NUMSEG; FINITE_NUMSEG] THEN + ASM_MESON_TAC[]; + ASM_REWRITE_TAC[] THEN DISCH_TAC] THEN + SUBGOAL_THEN + `?w:num->real^N. + pairwise (\i j. orthogonal (w i) (w j)) (1..dimindex(:N)) /\ + (!i. 1 <= i /\ i <= dimindex(:N) ==> norm(w i) = &1) /\ + (!i. 1 <= i /\ i <= n ==> w i = v i)` + STRIP_ASSUME_TAC THENL + [ALL_TAC; + EXISTS_TAC + `(\x. vsum(1..dimindex(:N)) (\i. x$i % w i)):real^N->real^N` THEN + SIMP_TAC[BASIS_COMPONENT; IN_NUMSEG; COND_RATOR; COND_RAND] THEN + REWRITE_TAC[VECTOR_MUL_LID; VECTOR_MUL_LZERO; VSUM_DELTA] THEN + ASM_SIMP_TAC[IN_NUMSEG] THEN CONJ_TAC THENL + [ALL_TAC; ASM_MESON_TAC[LE_TRANS]] THEN + REWRITE_TAC[ORTHOGONAL_TRANSFORMATION_MATRIX] THEN + CONJ_TAC THENL + [MATCH_MP_TAC LINEAR_COMPOSE_VSUM THEN + REWRITE_TAC[FINITE_NUMSEG; IN_NUMSEG] THEN + REWRITE_TAC[linear; VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT] THEN + REPEAT STRIP_TAC THEN VECTOR_ARITH_TAC; + ALL_TAC] THEN + REWRITE_TAC[matrix; column; ORTHOGONAL_MATRIX_ORTHONORMAL_COLUMNS] THEN + SIMP_TAC[LAMBDA_BETA; LAMBDA_ETA; BASIS_COMPONENT; IN_NUMSEG] THEN + SIMP_TAC[COND_RATOR; COND_RAND; VECTOR_MUL_LZERO; VSUM_DELTA] THEN + SIMP_TAC[IN_NUMSEG; orthogonal; dot; LAMBDA_BETA; NORM_EQ_SQUARE] THEN + REWRITE_TAC[VECTOR_MUL_LID; GSYM dot; GSYM NORM_EQ_SQUARE] THEN + RULE_ASSUM_TAC(REWRITE_RULE[pairwise; IN_NUMSEG; orthogonal]) THEN + ASM_SIMP_TAC[]] THEN + FIRST_ASSUM(MP_TAC o SPEC `(:real^N)` o MATCH_MP + (REWRITE_RULE[IMP_CONJ] ORTHONORMAL_EXTENSION)) THEN + ASM_REWRITE_TAC[FORALL_IN_IMAGE; IN_NUMSEG; UNION_UNIV; SPAN_UNIV] THEN + DISCH_THEN(X_CHOOSE_THEN `t:real^N->bool` STRIP_ASSUME_TAC) THEN + MP_TAC(ISPECL [`n+1..dimindex(:N)`; `t:real^N->bool`] + CARD_EQ_BIJECTION) THEN + ANTS_TAC THENL + [REWRITE_TAC[FINITE_NUMSEG] THEN + MP_TAC(ISPECL [`(:real^N)`; `IMAGE v (1..n) UNION t:real^N->bool`] + BASIS_CARD_EQ_DIM) THEN + ASM_REWRITE_TAC[SUBSET_UNIV] THEN ANTS_TAC THENL + [MATCH_MP_TAC PAIRWISE_ORTHOGONAL_INDEPENDENT THEN + ASM_REWRITE_TAC[IN_UNION; DE_MORGAN_THM; IN_NUMSEG] THEN + ASM_REWRITE_TAC[FORALL_IN_IMAGE; IN_NUMSEG; SET_RULE + `~(x IN s) <=> !y. y IN s ==> ~(y = x)`] THEN + ASM_MESON_TAC[NORM_0; REAL_ARITH `~(&1 = &0)`]; + ALL_TAC] THEN + ASM_SIMP_TAC[FINITE_UNION; IMP_CONJ; FINITE_IMAGE; CARD_UNION; + SET_RULE `t INTER s = {} <=> DISJOINT s t`] THEN + DISCH_TAC THEN DISCH_TAC THEN REWRITE_TAC[CARD_NUMSEG; DIM_UNIV] THEN + ARITH_TAC; + ALL_TAC] THEN + REWRITE_TAC[CONJ_ASSOC; SET_RULE + `(!x. x IN s ==> f x IN t) /\ (!y. y IN t ==> ?x. x IN s /\ f x = y) <=> + t = IMAGE f s`] THEN + REWRITE_TAC[GSYM CONJ_ASSOC; LEFT_IMP_EXISTS_THM; IN_NUMSEG] THEN + X_GEN_TAC `w:num->real^N` THEN + DISCH_THEN(CONJUNCTS_THEN2 SUBST_ALL_TAC MP_TAC) THEN + REWRITE_TAC[ARITH_RULE `n + 1 <= x <=> n < x`; CONJ_ASSOC] THEN + ONCE_REWRITE_TAC[TAUT `p /\ q ==> r <=> p /\ ~r ==> ~q`] THEN + REWRITE_TAC[GSYM CONJ_ASSOC] THEN STRIP_TAC THEN + REWRITE_TAC[TAUT `p /\ ~r ==> ~q <=> p /\ q ==> r`] THEN + EXISTS_TAC `\i. if i <= n then (v:num->real^N) i else w i` THEN + SIMP_TAC[] THEN + RULE_ASSUM_TAC(REWRITE_RULE[FORALL_IN_IMAGE; IN_NUMSEG]) THEN + CONJ_TAC THENL + [ALL_TAC; ASM_MESON_TAC[ARITH_RULE `~(i <= n) ==> n + 1 <= i`]] THEN + REWRITE_TAC[pairwise] THEN MATCH_MP_TAC WLOG_LT THEN REWRITE_TAC[] THEN + CONJ_TAC THENL [MESON_TAC[ORTHOGONAL_SYM]; ALL_TAC] THEN + MAP_EVERY X_GEN_TAC [`i:num`; `j:num`] THEN DISCH_TAC THEN + ASM_CASES_TAC `j:num <= n` THEN ASM_REWRITE_TAC[IN_NUMSEG] THENL + [COND_CASES_TAC THEN ASM_SIMP_TAC[] THEN ASM_ARITH_TAC; ALL_TAC] THEN + ASM_CASES_TAC `i:num <= n` THEN ASM_REWRITE_TAC[] THEN STRIP_TAC THEN + UNDISCH_TAC + `pairwise orthogonal + (IMAGE (v:num->real^N) (1..n) UNION IMAGE w (n+1..dimindex (:N)))` THEN + REWRITE_TAC[pairwise] THEN ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN + DISCH_THEN(MP_TAC o SPEC `(w:num->real^N) j`) THENL + [DISCH_THEN(MP_TAC o SPEC `(v:num->real^N) i`); + DISCH_THEN(MP_TAC o SPEC `(w:num->real^N) i`)] THEN + ASM_REWRITE_TAC[IN_UNION; IN_IMAGE; IN_NUMSEG] THEN + DISCH_THEN MATCH_MP_TAC THENL + [CONJ_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN + CONJ_TAC THENL + [ASM_MESON_TAC[ARITH_RULE `~(x <= n) ==> n + 1 <= x`]; ALL_TAC]; + ASM_MESON_TAC[ARITH_RULE `~(x <= n) ==> n + 1 <= x /\ n < x`]] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [DISJOINT]) THEN + REWRITE_TAC[SET_RULE `IMAGE w t INTER IMAGE v s = {} <=> + !i j. i IN s /\ j IN t ==> ~(v i = w j)`] THEN + DISCH_THEN MATCH_MP_TAC THEN ASM_REWRITE_TAC[IN_NUMSEG] THEN + ASM_ARITH_TAC) in + let lemma2 = prove + (`!v:num->real^N w k. + pairwise (\i j. orthogonal (v i) (v j)) k /\ + pairwise (\i j. orthogonal (w i) (w j)) k /\ + (!i. i IN k ==> norm(v i) = norm(w i)) /\ + (!i. i IN k ==> ~(v i = vec 0) /\ ~(w i = vec 0)) + ==> ?f. orthogonal_transformation f /\ + (!i. i IN k ==> f(v i) = w i)`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN `FINITE(k:num->bool)` MP_TAC THENL + [SUBGOAL_THEN `pairwise orthogonal (IMAGE (v:num->real^N) k)` + ASSUME_TAC THENL + [REWRITE_TAC[PAIRWISE_IMAGE] THEN + RULE_ASSUM_TAC(REWRITE_RULE[pairwise]) THEN ASM_SIMP_TAC[pairwise]; + ALL_TAC] THEN + FIRST_ASSUM(MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + PAIRWISE_ORTHOGONAL_INDEPENDENT)) THEN + ANTS_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + DISCH_THEN(MP_TAC o MATCH_MP INDEPENDENT_IMP_FINITE) THEN + MATCH_MP_TAC EQ_IMP THEN MATCH_MP_TAC FINITE_IMAGE_INJ_EQ THEN + RULE_ASSUM_TAC(REWRITE_RULE[pairwise]) THEN + ASM_MESON_TAC[ORTHOGONAL_REFL]; + ALL_TAC] THEN + DISCH_THEN(MP_TAC o GEN_REWRITE_RULE I [FINITE_INDEX_NUMSEG]) THEN + ONCE_REWRITE_TAC[TAUT `p /\ q /\ r ==> s <=> p /\ q /\ ~s ==> ~r`] THEN + DISCH_THEN(X_CHOOSE_THEN `n:num->num` MP_TAC) THEN + REWRITE_TAC[IN_NUMSEG] THEN GEN_REWRITE_TAC I [IMP_CONJ] THEN + DISCH_THEN(fun th -> DISCH_THEN SUBST_ALL_TAC THEN ASSUME_TAC th) THEN + RULE_ASSUM_TAC(REWRITE_RULE + [PAIRWISE_IMAGE; FORALL_IN_IMAGE; IN_NUMSEG]) THEN + MP_TAC(ISPECL + [`\i. inv(norm(w(n i))) % (w:num->real^N) ((n:num->num) i)`; + `CARD(k:num->bool)`] lemma1) THEN + MP_TAC(ISPECL + [`\i. inv(norm(v(n i))) % (v:num->real^N) ((n:num->num) i)`; + `CARD(k:num->bool)`] lemma1) THEN + ASM_SIMP_TAC[NORM_MUL; REAL_MUL_LINV; NORM_EQ_0; REAL_ABS_INV; + REAL_ABS_NORM; pairwise; orthogonal; IN_NUMSEG] THEN + RULE_ASSUM_TAC(REWRITE_RULE[pairwise; orthogonal; IN_NUMSEG]) THEN + ASM_SIMP_TAC[DOT_LMUL; DOT_RMUL; REAL_ENTIRE; FORALL_IN_IMAGE] THEN + DISCH_THEN(X_CHOOSE_THEN `f:real^N->real^N` STRIP_ASSUME_TAC) THEN + DISCH_THEN(X_CHOOSE_THEN `g:real^N->real^N` STRIP_ASSUME_TAC) THEN + MP_TAC(ISPEC `f:real^N->real^N` ORTHOGONAL_TRANSFORMATION_INVERSE) THEN + ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `f':real^N->real^N` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `(g:real^N->real^N) o (f':real^N->real^N)` THEN + ASM_SIMP_TAC[ORTHOGONAL_TRANSFORMATION_COMPOSE; IN_NUMSEG] THEN + X_GEN_TAC `i:num` THEN DISCH_TAC THEN REWRITE_TAC[o_THM] THEN + MATCH_MP_TAC EQ_TRANS THEN EXISTS_TAC + `(g:real^N->real^N) (norm((w:num->real^N)(n(i:num))) % basis i)` THEN + CONJ_TAC THENL + [AP_TERM_TAC THEN FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (MESON[] + `(!x. f'(f x) = x) ==> f x = y ==> f' y = x`)); + ALL_TAC] THEN + RULE_ASSUM_TAC(REWRITE_RULE[orthogonal_transformation]) THEN + ASM_SIMP_TAC[LINEAR_CMUL; VECTOR_MUL_ASSOC] THEN + ASM_SIMP_TAC[REAL_MUL_RINV; NORM_EQ_0; VECTOR_MUL_LID]) in + REPEAT STRIP_TAC THEN MP_TAC(ISPECL + [`v:num->real^N`; `w:num->real^N`; + `{i | i IN k /\ ~((v:num->real^N) i = vec 0)}`] lemma2) THEN + ASM_SIMP_TAC[IN_ELIM_THM; CONJ_ASSOC] THEN ANTS_TAC THENL + [CONJ_TAC THENL [ALL_TAC; ASM_MESON_TAC[NORM_EQ_0]] THEN + CONJ_TAC THEN MATCH_MP_TAC PAIRWISE_MONO THEN EXISTS_TAC `k:num->bool` THEN + ASM_REWRITE_TAC[] THEN SET_TAC[]; + MATCH_MP_TAC MONO_EXISTS THEN SIMP_TAC[orthogonal_transformation] THEN + GEN_TAC THEN STRIP_TAC THEN X_GEN_TAC `i:num` THEN DISCH_TAC THEN + ASM_CASES_TAC `(v:num->real^N) i = vec 0` THEN ASM_SIMP_TAC[] THEN + ASM_MESON_TAC[LINEAR_0; NORM_EQ_0]]);; + +(* ------------------------------------------------------------------------- *) +(* Reflection of a vector about 0 along a line. *) +(* ------------------------------------------------------------------------- *) + +let reflect_along = new_definition + `reflect_along v (x:real^N) = x - (&2 * (x dot v) / (v dot v)) % v`;; + +let REFLECT_ALONG_ADD = prove + (`!v x y:real^N. + reflect_along v (x + y) = reflect_along v x + reflect_along v y`, + REPEAT GEN_TAC THEN + REWRITE_TAC[reflect_along; VECTOR_ARITH + `x - a % v + y - b % v:real^N = (x + y) - (a + b) % v`] THEN + AP_TERM_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN + REWRITE_TAC[DOT_LADD] THEN REAL_ARITH_TAC);; + +let REFLECT_ALONG_MUL = prove + (`!v a x:real^N. reflect_along v (a % x) = a % reflect_along v x`, + REWRITE_TAC[reflect_along; DOT_LMUL; REAL_ARITH + `&2 * (a * x) / y = a * &2 * x / y`] THEN + REWRITE_TAC[VECTOR_SUB_LDISTRIB; VECTOR_MUL_ASSOC]);; + +let LINEAR_REFLECT_ALONG = prove + (`!v:real^N. linear(reflect_along v)`, + REWRITE_TAC[linear; REFLECT_ALONG_ADD; REFLECT_ALONG_MUL]);; + +let REFLECT_ALONG_0 = prove + (`!v:real^N. reflect_along v (vec 0) = vec 0`, + REWRITE_TAC[MATCH_MP LINEAR_0 (SPEC_ALL LINEAR_REFLECT_ALONG)]);; + +let REFLECT_ALONG_REFL = prove + (`!v:real^N. reflect_along v v = --v`, + GEN_TAC THEN ASM_CASES_TAC `v:real^N = vec 0` THEN + ASM_REWRITE_TAC[VECTOR_NEG_0; REFLECT_ALONG_0] THEN + REWRITE_TAC[reflect_along] THEN + ASM_SIMP_TAC[REAL_DIV_REFL; DOT_EQ_0] THEN VECTOR_ARITH_TAC);; + +let REFLECT_ALONG_INVOLUTION = prove + (`!v x:real^N. reflect_along v (reflect_along v x) = x`, + REWRITE_TAC[reflect_along; DOT_LSUB; VECTOR_MUL_EQ_0; VECTOR_ARITH + `x - a % v - b % v:real^N = x <=> (a + b) % v = vec 0`] THEN + REWRITE_TAC[DOT_LMUL; GSYM DOT_EQ_0] THEN CONV_TAC REAL_FIELD);; + +let REFLECT_ALONG_EQ_0 = prove + (`!v x:real^N. reflect_along v x = vec 0 <=> x = vec 0`, + MESON_TAC[REFLECT_ALONG_0; REFLECT_ALONG_INVOLUTION]);; + +let ORTHGOONAL_TRANSFORMATION_REFLECT_ALONG = prove + (`!v:real^N. orthogonal_transformation(reflect_along v)`, + GEN_TAC THEN ASM_CASES_TAC `v:real^N = vec 0` THENL + [GEN_REWRITE_TAC RAND_CONV [GSYM ETA_AX] THEN + ASM_REWRITE_TAC[reflect_along; VECTOR_MUL_RZERO; VECTOR_SUB_RZERO; + ORTHOGONAL_TRANSFORMATION_ID]; + REWRITE_TAC[ORTHOGONAL_TRANSFORMATION] THEN + REWRITE_TAC[LINEAR_REFLECT_ALONG; NORM_EQ] THEN + REWRITE_TAC[reflect_along; VECTOR_ARITH + `(a - b:real^N) dot (a - b) = (a dot a + b dot b) - &2 * a dot b`] THEN + REWRITE_TAC[DOT_LMUL; DOT_RMUL] THEN X_GEN_TAC `w:real^N` THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE RAND_CONV [GSYM DOT_EQ_0]) THEN + CONV_TAC REAL_FIELD]);; + +let REFLECT_ALONG_EQ_SELF = prove + (`!v x:real^N. reflect_along v x = x <=> orthogonal v x`, + REPEAT GEN_TAC THEN REWRITE_TAC[reflect_along; orthogonal] THEN + REWRITE_TAC[VECTOR_ARITH `x - a:real^N = x <=> a = vec 0`] THEN + REWRITE_TAC[VECTOR_MUL_EQ_0] THEN + ASM_CASES_TAC `v:real^N = vec 0` THEN ASM_SIMP_TAC[DOT_LZERO; DOT_SYM] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE RAND_CONV [GSYM DOT_EQ_0]) THEN + CONV_TAC REAL_FIELD);; + +let REFLECT_ALONG_ZERO = prove + (`!x:real^N. reflect_along (vec 0) = I`, + REWRITE_TAC[FUN_EQ_THM; I_THM; REFLECT_ALONG_EQ_SELF; ORTHOGONAL_0]);; + +let REFLECT_ALONG_LINEAR_IMAGE = prove + (`!f:real^M->real^N v x. + linear f /\ (!x. norm(f x) = norm x) + ==> reflect_along (f v) (f x) = f(reflect_along v x)`, + REWRITE_TAC[reflect_along] THEN + SIMP_TAC[PRESERVES_NORM_PRESERVES_DOT; LINEAR_SUB; LINEAR_CMUL]);; + +add_linear_invariants [REFLECT_ALONG_LINEAR_IMAGE];; + +let REFLECT_ALONG_SCALE = prove + (`!c v x:real^N. ~(c = &0) ==> reflect_along (c % v) x = reflect_along v x`, + REPEAT STRIP_TAC THEN + ASM_CASES_TAC `v:real^N = vec 0` THEN + ASM_REWRITE_TAC[VECTOR_MUL_RZERO; REFLECT_ALONG_ZERO] THEN + REWRITE_TAC[reflect_along; VECTOR_MUL_ASSOC] THEN + AP_TERM_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN + REWRITE_TAC[DOT_RMUL] THEN REWRITE_TAC[DOT_LMUL] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE RAND_CONV [GSYM DOT_EQ_0]) THEN + POP_ASSUM MP_TAC THEN CONV_TAC REAL_FIELD);; + +let REFLECT_ALONG_1D = prove + (`!v x:real^N. + dimindex(:N) = 1 ==> reflect_along v x = if v = vec 0 then x else --x`, + REPEAT STRIP_TAC THEN + ASM_SIMP_TAC[reflect_along; dot; SUM_1; CART_EQ; FORALL_1] THEN + REWRITE_TAC[VEC_COMPONENT; COND_RATOR; COND_RAND] THEN + SIMP_TAC[VECTOR_NEG_COMPONENT; VECTOR_MUL_COMPONENT; + VECTOR_SUB_COMPONENT; REAL_MUL_RZERO] THEN + CONV_TAC REAL_FIELD);; + +let REFLECT_ALONG_BASIS = prove + (`!x:real^N k. + 1 <= k /\ k <= dimindex(:N) + ==> reflect_along (basis k) x = x - (&2 * x$k) % basis k`, + SIMP_TAC[reflect_along; DOT_BASIS; BASIS_COMPONENT; REAL_DIV_1]);; + +let MATRIX_REFLECT_ALONG_BASIS = prove + (`!k. 1 <= k /\ k <= dimindex(:N) + ==> matrix(reflect_along (basis k)):real^N^N = + lambda i j. if i = k /\ j = k then --(&1) + else if i = j then &1 + else &0`, + SIMP_TAC[CART_EQ; LAMBDA_BETA; matrix; REFLECT_ALONG_BASIS; + VECTOR_SUB_COMPONENT; BASIS_COMPONENT; VECTOR_MUL_COMPONENT] THEN + X_GEN_TAC `k:num` THEN STRIP_TAC THEN + X_GEN_TAC `i:num` THEN STRIP_TAC THEN + X_GEN_TAC `j:num` THEN STRIP_TAC THEN + ASM_CASES_TAC `i:num = j` THEN ASM_REWRITE_TAC[] THEN + REPEAT(COND_CASES_TAC THEN ASM_REWRITE_TAC[]) THEN ASM_REAL_ARITH_TAC);; + +let ROTOINVERSION_MATRIX_REFLECT_ALONG = prove + (`!v:real^N. ~(v = vec 0) ==> rotoinversion_matrix(matrix(reflect_along v))`, + REPEAT STRIP_TAC THEN REWRITE_TAC[rotoinversion_matrix] THEN + CONJ_TAC THENL + [ASM_MESON_TAC[ORTHOGONAL_TRANSFORMATION_MATRIX; + ORTHGOONAL_TRANSFORMATION_REFLECT_ALONG]; + ALL_TAC] THEN + ABBREV_TAC `w:real^N = inv(norm v) % v` THEN + SUBGOAL_THEN `reflect_along (v:real^N) = reflect_along w` SUBST1_TAC THENL + [EXPAND_TAC "w" THEN REWRITE_TAC[FUN_EQ_THM] THEN + ASM_SIMP_TAC[REFLECT_ALONG_SCALE; REAL_INV_EQ_0; NORM_EQ_0]; + SUBGOAL_THEN `norm(w:real^N) = &1` MP_TAC THENL + [EXPAND_TAC "w" THEN SIMP_TAC[NORM_MUL; REAL_ABS_INV; REAL_ABS_NORM] THEN + MATCH_MP_TAC REAL_MUL_LINV THEN ASM_REWRITE_TAC[NORM_EQ_0]; + POP_ASSUM_LIST(K ALL_TAC) THEN SPEC_TAC(`w:real^N`,`v:real^N`)]] THEN + X_GEN_TAC `v:real^N` THEN ASM_CASES_TAC `v:real^N = vec 0` THEN + ASM_REWRITE_TAC[NORM_0; REAL_OF_NUM_EQ; ARITH_EQ] THEN DISCH_TAC THEN + MP_TAC(ISPECL [`v:real^N`; `basis 1:real^N`] + ORTHOGONAL_TRANSFORMATION_EXISTS) THEN + ASM_SIMP_TAC[NORM_BASIS; DIMINDEX_GE_1; LE_REFL] THEN + DISCH_THEN(X_CHOOSE_THEN `f:real^N->real^N` STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN + `matrix(reflect_along v) = + transp(matrix(f:real^N->real^N)) ** matrix(reflect_along (f v)) ** matrix f` + SUBST1_TAC THENL + [UNDISCH_THEN `(f:real^N->real^N) v = basis 1` (K ALL_TAC) THEN + REWRITE_TAC[MATRIX_EQ; GSYM MATRIX_VECTOR_MUL_ASSOC] THEN + ASM_SIMP_TAC[MATRIX_WORKS; LINEAR_REFLECT_ALONG; + ORTHOGONAL_TRANSFORMATION_LINEAR] THEN + X_GEN_TAC `x:real^N` THEN MATCH_MP_TAC EQ_TRANS THEN + EXISTS_TAC `(transp(matrix(f:real^N->real^N)) ** matrix f) ** + (reflect_along v x:real^N)` THEN + CONJ_TAC THENL + [ASM_MESON_TAC[ORTHOGONAL_MATRIX; MATRIX_VECTOR_MUL_LID; + ORTHOGONAL_TRANSFORMATION_MATRIX]; + REWRITE_TAC[GSYM MATRIX_VECTOR_MUL_ASSOC] THEN + ASM_SIMP_TAC[MATRIX_WORKS; ORTHOGONAL_TRANSFORMATION_LINEAR] THEN + AP_TERM_TAC THEN CONV_TAC SYM_CONV THEN + MATCH_MP_TAC REFLECT_ALONG_LINEAR_IMAGE THEN + ASM_REWRITE_TAC[GSYM ORTHOGONAL_TRANSFORMATION]]; + ASM_REWRITE_TAC[DET_MUL; DET_TRANSP] THEN + MATCH_MP_TAC(REAL_RING + `(x = &1 \/ x = -- &1) /\ y = a ==> x * y * x = a`) THEN + CONJ_TAC THENL + [ASM_MESON_TAC[DET_ORTHOGONAL_MATRIX; ORTHOGONAL_TRANSFORMATION_MATRIX]; + ALL_TAC] THEN + W(MP_TAC o PART_MATCH (lhs o rand) DET_UPPERTRIANGULAR o lhand o snd) THEN + SIMP_TAC[MATRIX_REFLECT_ALONG_BASIS; DIMINDEX_GE_1; LE_REFL] THEN + SIMP_TAC[LAMBDA_BETA; ARITH_RULE + `j < i ==> ~(i = j) /\ ~(i = 1 /\ j = 1)`] THEN + DISCH_THEN(K ALL_TAC) THEN + SIMP_TAC[PRODUCT_CLAUSES_LEFT; DIMINDEX_GE_1] THEN + MATCH_MP_TAC(REAL_RING `x = &1 ==> a * x = a`) THEN + MATCH_MP_TAC PRODUCT_EQ_1 THEN + REWRITE_TAC[IN_NUMSEG] THEN REPEAT STRIP_TAC THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN ASM_ARITH_TAC]);; + +let DET_MATRIX_REFLECT_ALONG = prove + (`!v:real^N. det(matrix(reflect_along v)) = + if v = vec 0 then &1 else --(&1)`, + GEN_TAC THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[REFLECT_ALONG_ZERO] THEN + REWRITE_TAC[MATRIX_I; DET_I] THEN + FIRST_ASSUM(MP_TAC o MATCH_MP ROTOINVERSION_MATRIX_REFLECT_ALONG) THEN + SIMP_TAC[rotoinversion_matrix]);; + +(* ------------------------------------------------------------------------- *) +(* All orthogonal transformations are a composition of reflections. *) +(* ------------------------------------------------------------------------- *) + +let ORTHOGONAL_TRANSFORMATION_GENERATED_BY_REFLECTIONS = prove + (`!f:real^N->real^N n. + orthogonal_transformation f /\ + dimindex(:N) <= dim {x | f x = x} + n + ==> ?l. LENGTH l <= n /\ ALL (\v. ~(v = vec 0)) l /\ + f = ITLIST (\v h. reflect_along v o h) l I`, + ONCE_REWRITE_TAC[GSYM SWAP_FORALL_THM] THEN INDUCT_TAC THENL + [REWRITE_TAC[CONJUNCT1 LE; LENGTH_EQ_NIL; ADD_CLAUSES; UNWIND_THM2] THEN + SIMP_TAC[DIM_SUBSET_UNIV; ARITH_RULE `a:num <= b ==> (b <= a <=> a = b)`; + ITLIST; DIM_EQ_FULL; orthogonal_transformation] THEN + SIMP_TAC[SPAN_OF_SUBSPACE; SUBSPACE_LINEAR_FIXED_POINTS; IMP_CONJ] THEN + REWRITE_TAC[EXTENSION; IN_UNIV; IN_ELIM_THM] THEN + SIMP_TAC[FUN_EQ_THM; I_THM; ALL]; + REPEAT STRIP_TAC THEN ASM_CASES_TAC `!x:real^N. f x = x` THENL + [EXISTS_TAC `[]:(real^N) list` THEN + ASM_REWRITE_TAC[ITLIST; FUN_EQ_THM; I_THM; ALL; LENGTH; LE_0]; + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [NOT_FORALL_THM])] THEN + DISCH_THEN(X_CHOOSE_TAC `a:real^N`) THEN + ABBREV_TAC `v:real^N = inv(&2) % (f a - a)` THEN FIRST_X_ASSUM + (MP_TAC o SPEC `reflect_along v o (f:real^N->real^N)`) THEN + ASM_SIMP_TAC[ORTHGOONAL_TRANSFORMATION_REFLECT_ALONG; + ORTHOGONAL_TRANSFORMATION_COMPOSE] THEN + ANTS_TAC THENL + [FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (ARITH_RULE + `a <= d + SUC n ==> d < d' ==> a <= d' + n`)) THEN + MATCH_MP_TAC DIM_PSUBSET THEN REWRITE_TAC[PSUBSET_ALT] THEN + SUBGOAL_THEN + `!y:real^N. dist(y,f a) = dist(y,a) ==> reflect_along v y = y` + ASSUME_TAC THENL + [REWRITE_TAC[dist; NORM_EQ_SQUARE; NORM_POS_LE; NORM_POW_2] THEN + REWRITE_TAC[VECTOR_ARITH + `(y - b:real^N) dot (y - b) = + (y dot y + b dot b) - &2 * y dot b`] THEN + REWRITE_TAC[REAL_ARITH `(y + aa) - &2 * a = (y + bb) - &2 * b <=> + a - b = inv(&2) * (aa - bb)`] THEN + RULE_ASSUM_TAC(REWRITE_RULE[orthogonal_transformation]) THEN + ASM_REWRITE_TAC[REAL_SUB_REFL; REAL_MUL_RZERO] THEN + EXPAND_TAC "v" THEN REWRITE_TAC[GSYM DOT_RSUB; reflect_along] THEN + SIMP_TAC[DOT_RMUL; real_div; REAL_MUL_LZERO; REAL_MUL_RZERO] THEN + REWRITE_TAC[VECTOR_MUL_LZERO; VECTOR_SUB_RZERO]; + ALL_TAC] THEN + CONJ_TAC THENL + [MATCH_MP_TAC SPAN_MONO THEN SIMP_TAC[SUBSET; IN_ELIM_THM; o_THM] THEN + ASM_MESON_TAC[ORTHOGONAL_TRANSFORMATION_ISOMETRY]; + ALL_TAC] THEN + EXISTS_TAC `a:real^N` THEN + ASM_SIMP_TAC[SUBSPACE_LINEAR_FIXED_POINTS; SPAN_OF_SUBSPACE; + ORTHOGONAL_TRANSFORMATION_LINEAR; IN_ELIM_THM] THEN + MATCH_MP_TAC SPAN_SUPERSET THEN REWRITE_TAC[IN_ELIM_THM; o_THM] THEN + MATCH_MP_TAC EQ_TRANS THEN + EXISTS_TAC `reflect_along (v:real^N) (midpoint(f a,a) + v)` THEN + CONJ_TAC THENL + [AP_TERM_TAC; + REWRITE_TAC[REFLECT_ALONG_ADD] THEN + ASM_SIMP_TAC[DIST_MIDPOINT; REFLECT_ALONG_REFL]] THEN + EXPAND_TAC "v" THEN REWRITE_TAC[midpoint] THEN VECTOR_ARITH_TAC; + DISCH_THEN(X_CHOOSE_THEN `l:(real^N)list` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `CONS (v:real^N) l` THEN + ASM_REWRITE_TAC[ALL; LENGTH; LE_SUC; VECTOR_SUB_EQ; ITLIST] THEN + EXPAND_TAC "v" THEN ASM_REWRITE_TAC[VECTOR_MUL_EQ_0] THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN ASM_REWRITE_TAC[VECTOR_SUB_EQ] THEN + FIRST_X_ASSUM(MP_TAC o AP_TERM + `(o)(reflect_along (v:real^N)):(real^N->real^N)->(real^N->real^N)`) THEN + REWRITE_TAC[FUN_EQ_THM; o_THM; REFLECT_ALONG_INVOLUTION]]]);; + +(* ------------------------------------------------------------------------- *) +(* Extract scaling, translation and linear invariance theorems. *) +(* For the linear case, chain through some basic consequences automatically, *) +(* e.g. norm-preserving and linear implies injective. *) +(* ------------------------------------------------------------------------- *) + +let SCALING_THEOREMS v = + let th1 = UNDISCH(snd(EQ_IMP_RULE(ISPEC v NORM_POS_LT))) in + let t = rand(concl th1) in + end_itlist CONJ (map (C MP th1 o SPEC t) (!scaling_theorems));; + +let TRANSLATION_INVARIANTS x = + end_itlist CONJ (mapfilter (ISPEC x) (!invariant_under_translation));; + +let USABLE_CONCLUSION f ths th = + let ith = PURE_REWRITE_RULE[RIGHT_FORALL_IMP_THM] (ISPEC f th) in + let bod = concl ith in + let cjs = conjuncts(fst(dest_imp bod)) in + let ths = map (fun t -> find(fun th -> aconv (concl th) t) ths) cjs in + GEN_ALL(MP ith (end_itlist CONJ ths));; + +let LINEAR_INVARIANTS = + let sths = (CONJUNCTS o prove) + (`(!f:real^M->real^N. + linear f /\ (!x. norm(f x) = norm x) + ==> (!x y. f x = f y ==> x = y)) /\ + (!f:real^N->real^N. + linear f /\ (!x. norm(f x) = norm x) ==> (!y. ?x. f x = y)) /\ + (!f:real^N->real^N. linear f /\ (!x y. f x = f y ==> x = y) + ==> (!y. ?x. f x = y)) /\ + (!f:real^N->real^N. linear f /\ (!y. ?x. f x = y) + ==> (!x y. f x = f y ==> x = y))`, + CONJ_TAC THENL + [ONCE_REWRITE_TAC[GSYM VECTOR_SUB_EQ] THEN + SIMP_TAC[GSYM LINEAR_SUB; GSYM NORM_EQ_0]; + MESON_TAC[ORTHOGONAL_TRANSFORMATION_SURJECTIVE; + ORTHOGONAL_TRANSFORMATION_INJECTIVE; ORTHOGONAL_TRANSFORMATION; + LINEAR_SURJECTIVE_IFF_INJECTIVE]]) in + fun f ths -> + let ths' = ths @ mapfilter (USABLE_CONCLUSION f ths) sths in + end_itlist CONJ + (mapfilter (USABLE_CONCLUSION f ths') (!invariant_under_linear));; + +(* ------------------------------------------------------------------------- *) +(* Tactic to pick WLOG a particular point as the origin. The conversion form *) +(* assumes it's the outermost universal variable; the tactic is more general *) +(* and allows any free or outer universally quantified variable. The list *) +(* "avoid" is the points not to translate. There is also a tactic to help in *) +(* proving new translation theorems, which uses similar machinery. *) +(* ------------------------------------------------------------------------- *) + +let GEOM_ORIGIN_CONV,GEOM_TRANSLATE_CONV = + let pth = prove + (`!a:real^N. a = a + vec 0 /\ + {} = IMAGE (\x. a + x) {} /\ + {} = IMAGE (IMAGE (\x. a + x)) {} /\ + (:real^N) = IMAGE (\x. a + x) (:real^N) /\ + (:real^N->bool) = IMAGE (IMAGE (\x. a + x)) (:real^N->bool) /\ + [] = MAP (\x. a + x) []`, + REWRITE_TAC[IMAGE_CLAUSES; VECTOR_ADD_RID; MAP] THEN + REWRITE_TAC[SET_RULE `UNIV = IMAGE f UNIV <=> !y. ?x. f x = y`] THEN + REWRITE_TAC[SURJECTIVE_IMAGE] THEN + REWRITE_TAC[VECTOR_ARITH `a + y:real^N = x <=> y = x - a`; EXISTS_REFL]) + and qth = prove + (`!a:real^N. + ((!P. (!x. P x) <=> (!x. P (a + x))) /\ + (!P. (?x. P x) <=> (?x. P (a + x))) /\ + (!Q. (!s. Q s) <=> (!s. Q(IMAGE (\x. a + x) s))) /\ + (!Q. (?s. Q s) <=> (?s. Q(IMAGE (\x. a + x) s))) /\ + (!Q. (!s. Q s) <=> (!s. Q(IMAGE (IMAGE (\x. a + x)) s))) /\ + (!Q. (?s. Q s) <=> (?s. Q(IMAGE (IMAGE (\x. a + x)) s))) /\ + (!P. (!g:real^1->real^N. P g) <=> (!g. P ((\x. a + x) o g))) /\ + (!P. (?g:real^1->real^N. P g) <=> (?g. P ((\x. a + x) o g))) /\ + (!P. (!g:num->real^N. P g) <=> (!g. P ((\x. a + x) o g))) /\ + (!P. (?g:num->real^N. P g) <=> (?g. P ((\x. a + x) o g))) /\ + (!Q. (!l. Q l) <=> (!l. Q(MAP (\x. a + x) l))) /\ + (!Q. (?l. Q l) <=> (?l. Q(MAP (\x. a + x) l)))) /\ + ((!P. {x | P x} = IMAGE (\x. a + x) {x | P(a + x)}) /\ + (!Q. {s | Q s} = + IMAGE (IMAGE (\x. a + x)) {s | Q(IMAGE (\x. a + x) s)}) /\ + (!R. {l | R l} = IMAGE (MAP (\x. a + x)) {l | R(MAP (\x. a + x) l)}))`, + GEN_TAC THEN MATCH_MP_TAC QUANTIFY_SURJECTION_HIGHER_THM THEN + X_GEN_TAC `y:real^N` THEN EXISTS_TAC `y - a:real^N` THEN + VECTOR_ARITH_TAC) in + let GEOM_ORIGIN_CONV avoid tm = + let x,tm0 = dest_forall tm in + let th0 = ISPEC x pth in + let x' = genvar(type_of x) in + let ith = ISPEC x' qth in + let th1 = PARTIAL_EXPAND_QUANTS_CONV avoid (ASSUME(concl ith)) tm0 in + let th2 = CONV_RULE(RAND_CONV(SUBS_CONV(CONJUNCTS th0))) th1 in + let th3 = INST[x,x'] (PROVE_HYP ith th2) in + let ths = TRANSLATION_INVARIANTS x in + let thr = REFL x in + let th4 = GEN_REWRITE_RULE (RAND_CONV o REDEPTH_CONV) + [BETA_THM;ADD_ASSUM(concl thr) ths] th3 in + let th5 = MK_FORALL x (PROVE_HYP thr th4) in + GEN_REWRITE_RULE (RAND_CONV o TRY_CONV) [FORALL_SIMP] th5 + and GEOM_TRANSLATE_CONV avoid a tm = + let cth = CONJUNCT2(ISPEC a pth) + and vth = ISPEC a qth in + let th1 = PARTIAL_EXPAND_QUANTS_CONV avoid (ASSUME(concl vth)) tm in + let th2 = CONV_RULE(RAND_CONV(SUBS_CONV(CONJUNCTS cth))) th1 in + let th3 = PROVE_HYP vth th2 in + let ths = TRANSLATION_INVARIANTS a in + let thr = REFL a in + let th4 = GEN_REWRITE_RULE (RAND_CONV o REDEPTH_CONV) + [BETA_THM;ADD_ASSUM(concl thr) ths] th3 in + PROVE_HYP thr th4 in + GEOM_ORIGIN_CONV,GEOM_TRANSLATE_CONV;; + +let GEN_GEOM_ORIGIN_TAC x avoid (asl,w as gl) = + let avs,bod = strip_forall w + and avs' = subtract (frees w) (freesl(map (concl o snd) asl)) in + (MAP_EVERY X_GEN_TAC avs THEN + MAP_EVERY (fun t -> SPEC_TAC(t,t)) (rev(subtract (avs@avs') [x])) THEN + SPEC_TAC(x,x) THEN CONV_TAC(GEOM_ORIGIN_CONV avoid)) gl;; + +let GEOM_ORIGIN_TAC x = GEN_GEOM_ORIGIN_TAC x [];; + +let GEOM_TRANSLATE_TAC avoid (asl,w) = + let a,bod = dest_forall w in + let n = length(fst(strip_forall bod)) in + (X_GEN_TAC a THEN + CONV_TAC(funpow n BINDER_CONV (LAND_CONV(GEOM_TRANSLATE_CONV avoid a))) THEN + REWRITE_TAC[]) (asl,w);; + +(* ------------------------------------------------------------------------- *) +(* Rename existential variables in conclusion to fresh genvars. *) +(* ------------------------------------------------------------------------- *) + +let EXISTS_GENVAR_RULE = + let rec rule vs th = + match vs with + [] -> th + | v::ovs -> let x,bod = dest_exists(concl th) in + let th1 = rule ovs (ASSUME bod) in + let th2 = SIMPLE_CHOOSE x (SIMPLE_EXISTS x th1) in + PROVE_HYP th (CONV_RULE (GEN_ALPHA_CONV v) th2) in + fun th -> rule (map (genvar o type_of) (fst(strip_exists(concl th)))) th;; + +(* ------------------------------------------------------------------------- *) +(* Rotate so that WLOG some point is a +ve multiple of basis vector k. *) +(* For general N, it's better to use k = 1 so the side-condition can be *) +(* discharged. For dimensions 1, 2 and 3 anything will work automatically. *) +(* Could generalize by asking the user to prove theorem 1 <= k <= N. *) +(* ------------------------------------------------------------------------- *) + +let GEOM_BASIS_MULTIPLE_RULE = + let pth = prove + (`!f. orthogonal_transformation (f:real^N->real^N) + ==> (vec 0 = f(vec 0) /\ + {} = IMAGE f {} /\ + {} = IMAGE (IMAGE f) {} /\ + (:real^N) = IMAGE f (:real^N) /\ + (:real^N->bool) = IMAGE (IMAGE f) (:real^N->bool) /\ + [] = MAP f []) /\ + ((!P. (!x. P x) <=> (!x. P (f x))) /\ + (!P. (?x. P x) <=> (?x. P (f x))) /\ + (!Q. (!s. Q s) <=> (!s. Q (IMAGE f s))) /\ + (!Q. (?s. Q s) <=> (?s. Q (IMAGE f s))) /\ + (!Q. (!s. Q s) <=> (!s. Q (IMAGE (IMAGE f) s))) /\ + (!Q. (?s. Q s) <=> (?s. Q (IMAGE (IMAGE f) s))) /\ + (!P. (!g:real^1->real^N. P g) <=> (!g. P (f o g))) /\ + (!P. (?g:real^1->real^N. P g) <=> (?g. P (f o g))) /\ + (!P. (!g:num->real^N. P g) <=> (!g. P (f o g))) /\ + (!P. (?g:num->real^N. P g) <=> (?g. P (f o g))) /\ + (!Q. (!l. Q l) <=> (!l. Q(MAP f l))) /\ + (!Q. (?l. Q l) <=> (?l. Q(MAP f l)))) /\ + ((!P. {x | P x} = IMAGE f {x | P(f x)}) /\ + (!Q. {s | Q s} = IMAGE (IMAGE f) {s | Q(IMAGE f s)}) /\ + (!R. {l | R l} = IMAGE (MAP f) {l | R(MAP f l)}))`, + REPEAT GEN_TAC THEN DISCH_TAC THEN + FIRST_ASSUM(ASSUME_TAC o + MATCH_MP ORTHOGONAL_TRANSFORMATION_SURJECTIVE) THEN + CONJ_TAC THENL + [REWRITE_TAC[IMAGE_CLAUSES; MAP] THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP ORTHOGONAL_TRANSFORMATION_LINEAR) THEN + CONJ_TAC THENL [ASM_MESON_TAC[LINEAR_0]; ALL_TAC] THEN + REWRITE_TAC[SET_RULE `UNIV = IMAGE f UNIV <=> !y. ?x. f x = y`] THEN + ASM_REWRITE_TAC[SURJECTIVE_IMAGE]; + MATCH_MP_TAC QUANTIFY_SURJECTION_HIGHER_THM THEN ASM_REWRITE_TAC[]]) + and oth = prove + (`!f:real^N->real^N. + orthogonal_transformation f /\ + (2 <= dimindex(:N) ==> det(matrix f) = &1) + ==> linear f /\ + (!x y. f x = f y ==> x = y) /\ + (!y. ?x. f x = y) /\ + (!x. norm(f x) = norm x) /\ + (2 <= dimindex(:N) ==> det(matrix f) = &1)`, + GEN_TAC THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN REPEAT CONJ_TAC THENL + [ASM_SIMP_TAC[ORTHOGONAL_TRANSFORMATION_LINEAR]; + ASM_MESON_TAC[ORTHOGONAL_TRANSFORMATION_INJECTIVE]; + ASM_MESON_TAC[ORTHOGONAL_TRANSFORMATION_SURJECTIVE]; + ASM_MESON_TAC[ORTHOGONAL_TRANSFORMATION]]) + and arithconv = REWRITE_CONV[DIMINDEX_1; DIMINDEX_2; DIMINDEX_3; + ARITH_RULE `1 <= 1`; DIMINDEX_GE_1] THENC + NUM_REDUCE_CONV in + fun k tm -> + let x,bod = dest_forall tm in + let th0 = ISPECL [x; mk_small_numeral k] ROTATION_RIGHTWARD_LINE in + let th1 = EXISTS_GENVAR_RULE + (MP th0 (EQT_ELIM(arithconv(lhand(concl th0))))) in + let [a;f],tm1 = strip_exists(concl th1) in + let th_orth,th2 = CONJ_PAIR(ASSUME tm1) in + let th_det,th2a = CONJ_PAIR th2 in + let th_works,th_zero = CONJ_PAIR th2a in + let thc,thq = CONJ_PAIR(PROVE_HYP th2 (UNDISCH(ISPEC f pth))) in + let th3 = CONV_RULE(RAND_CONV(SUBS_CONV(GSYM th_works::CONJUNCTS thc))) + (EXPAND_QUANTS_CONV(ASSUME(concl thq)) bod) in + let th4 = PROVE_HYP thq th3 in + let thps = CONJUNCTS(MATCH_MP oth (CONJ th_orth th_det)) in + let th5 = LINEAR_INVARIANTS f thps in + let th6 = PROVE_HYP th_orth + (GEN_REWRITE_RULE (RAND_CONV o REDEPTH_CONV) [BETA_THM; th5] th4) in + let ntm = mk_forall(a,mk_imp(concl th_zero,rand(concl th6))) in + let th7 = MP(SPEC a (ASSUME ntm)) th_zero in + let th8 = DISCH ntm (EQ_MP (SYM th6) th7) in + if intersect (frees(concl th8)) [a;f] = [] then + let th9 = PROVE_HYP th1 (itlist SIMPLE_CHOOSE [a;f] th8) in + let th10 = DISCH ntm (GEN x (UNDISCH th9)) in + let a' = variant (frees(concl th10)) + (mk_var(fst(dest_var x),snd(dest_var a))) in + CONV_RULE(LAND_CONV (GEN_ALPHA_CONV a')) th10 + else + let mtm = list_mk_forall([a;f],mk_imp(hd(hyp th8),rand(concl th6))) in + let th9 = EQ_MP (SYM th6) (UNDISCH(SPECL [a;f] (ASSUME mtm))) in + let th10 = itlist SIMPLE_CHOOSE [a;f] (DISCH mtm th9) in + let th11 = GEN x (PROVE_HYP th1 th10) in + MATCH_MP MONO_FORALL th11;; + +let GEOM_BASIS_MULTIPLE_TAC k l (asl,w as gl) = + let avs,bod = strip_forall w + and avs' = subtract (frees w) (freesl(map (concl o snd) asl)) in + (MAP_EVERY X_GEN_TAC avs THEN + MAP_EVERY (fun t -> SPEC_TAC(t,t)) (rev(subtract (avs@avs') [l])) THEN + SPEC_TAC(l,l) THEN + W(MATCH_MP_TAC o GEOM_BASIS_MULTIPLE_RULE k o snd)) gl;; + +(* ------------------------------------------------------------------------- *) +(* Create invariance theorems automatically, in simple cases. If there are *) +(* any nested quantifiers, this will need surjectivity. It's often possible *) +(* to prove a stronger theorem by more delicate manual reasoning, so this *) +(* isn't used nearly as often as GEOM_TRANSLATE_CONV / GEOM_TRANSLATE_TAC. *) +(* As a small step, some ad-hoc rewrites analogous to FORALL_IN_IMAGE are *) +(* tried if the first step doesn't finish the goal, but it's very ad hoc. *) +(* ------------------------------------------------------------------------- *) + +let GEOM_TRANSFORM_TAC = + let cth0 = prove + (`!f:real^M->real^N. + linear f + ==> vec 0 = f(vec 0) /\ + {} = IMAGE f {} /\ + {} = IMAGE (IMAGE f) {}`, + REWRITE_TAC[IMAGE_CLAUSES] THEN MESON_TAC[LINEAR_0]) + and cth1 = prove + (`!f:real^M->real^N. + (!y. ?x. f x = y) + ==> (:real^N) = IMAGE f (:real^M) /\ + (:real^N->bool) = IMAGE (IMAGE f) (:real^M->bool)`, + REWRITE_TAC[SET_RULE `UNIV = IMAGE f UNIV <=> !y. ?x. f x = y`] THEN + REWRITE_TAC[SURJECTIVE_IMAGE]) + and sths = (CONJUNCTS o prove) + (`(!f:real^M->real^N. + linear f /\ (!x. norm(f x) = norm x) + ==> (!x y. f x = f y ==> x = y)) /\ + (!f:real^N->real^N. + linear f /\ (!x. norm(f x) = norm x) ==> (!y. ?x. f x = y)) /\ + (!f:real^N->real^N. linear f /\ (!x y. f x = f y ==> x = y) + ==> (!y. ?x. f x = y)) /\ + (!f:real^N->real^N. linear f /\ (!y. ?x. f x = y) + ==> (!x y. f x = f y ==> x = y))`, + CONJ_TAC THENL + [ONCE_REWRITE_TAC[GSYM VECTOR_SUB_EQ] THEN + SIMP_TAC[GSYM LINEAR_SUB; GSYM NORM_EQ_0]; + MESON_TAC[ORTHOGONAL_TRANSFORMATION_SURJECTIVE; + ORTHOGONAL_TRANSFORMATION_INJECTIVE; ORTHOGONAL_TRANSFORMATION; + LINEAR_SURJECTIVE_IFF_INJECTIVE]]) + and aths = (CONJUNCTS o prove) + (`(!f s P. (!y. y IN IMAGE f s ==> P y) <=> (!x. x IN s ==> P(f x))) /\ + (!f s P. (!u. u IN IMAGE (IMAGE f) s ==> P u) <=> + (!t. t IN s ==> P(IMAGE f t))) /\ + (!f s P. (?y. y IN IMAGE f s /\ P y) <=> (?x. x IN s /\ P(f x))) /\ + (!f s P. (?u. u IN IMAGE (IMAGE f) s /\ P u) <=> + (?t. t IN s /\ P(IMAGE f t)))`, + SET_TAC[]) in + fun avoid (asl,w as gl) -> + let f,wff = dest_forall w in + let vs,bod = strip_forall wff in + let ant,cons = dest_imp bod in + let hths = CONJUNCTS(ASSUME ant) in + let fths = hths @ mapfilter (USABLE_CONCLUSION f hths) sths in + let cths = mapfilter (USABLE_CONCLUSION f fths) [cth0; cth1] + and vconv = + try let vth = USABLE_CONCLUSION f fths QUANTIFY_SURJECTION_HIGHER_THM in + PROVE_HYP vth o PARTIAL_EXPAND_QUANTS_CONV avoid (ASSUME(concl vth)) + with Failure _ -> ALL_CONV + and bths = LINEAR_INVARIANTS f fths in + (MAP_EVERY X_GEN_TAC (f::vs) THEN DISCH_TAC THEN + GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) cths THEN + CONV_TAC(LAND_CONV vconv) THEN + GEN_REWRITE_TAC (LAND_CONV o REDEPTH_CONV) [bths] THEN + REWRITE_TAC[] THEN + REWRITE_TAC(mapfilter (ADD_ASSUM ant o ISPEC f) aths) THEN + GEN_REWRITE_TAC (LAND_CONV o REDEPTH_CONV) [bths] THEN + REWRITE_TAC[]) gl;; + +(* ------------------------------------------------------------------------- *) +(* Scale so that a chosen vector has size 1. Generates a conjunction of *) +(* two formulas, one for the zero case (which one hopes is trivial) and *) +(* one just like the original goal but with a norm(...) = 1 assumption. *) +(* ------------------------------------------------------------------------- *) + +let GEOM_NORMALIZE_RULE = + let pth = prove + (`!a:real^N. ~(a = vec 0) + ==> vec 0 = norm(a) % vec 0 /\ + a = norm(a) % inv(norm a) % a /\ + {} = IMAGE (\x. norm(a) % x) {} /\ + {} = IMAGE (IMAGE (\x. norm(a) % x)) {} /\ + (:real^N) = IMAGE (\x. norm(a) % x) (:real^N) /\ + (:real^N->bool) = + IMAGE (IMAGE (\x. norm(a) % x)) (:real^N->bool) /\ + [] = MAP (\x. norm(a) % x) []`, + REWRITE_TAC[IMAGE_CLAUSES; VECTOR_MUL_ASSOC; VECTOR_MUL_RZERO; MAP] THEN + SIMP_TAC[NORM_EQ_0; REAL_MUL_RINV; VECTOR_MUL_LID] THEN + GEN_TAC THEN DISCH_TAC THEN + REWRITE_TAC[SET_RULE `UNIV = IMAGE f UNIV <=> !y. ?x. f x = y`] THEN + ASM_REWRITE_TAC[SURJECTIVE_IMAGE] THEN + X_GEN_TAC `y:real^N` THEN EXISTS_TAC `inv(norm(a:real^N)) % y:real^N` THEN + ASM_SIMP_TAC[VECTOR_MUL_ASSOC; NORM_EQ_0; REAL_MUL_RINV; VECTOR_MUL_LID]) + and qth = prove + (`!a:real^N. + ~(a = vec 0) + ==> ((!P. (!r:real. P r) <=> (!r. P(norm a * r))) /\ + (!P. (?r:real. P r) <=> (?r. P(norm a * r))) /\ + (!P. (!x:real^N. P x) <=> (!x. P (norm(a) % x))) /\ + (!P. (?x:real^N. P x) <=> (?x. P (norm(a) % x))) /\ + (!Q. (!s:real^N->bool. Q s) <=> + (!s. Q(IMAGE (\x. norm(a) % x) s))) /\ + (!Q. (?s:real^N->bool. Q s) <=> + (?s. Q(IMAGE (\x. norm(a) % x) s))) /\ + (!Q. (!s:(real^N->bool)->bool. Q s) <=> + (!s. Q(IMAGE (IMAGE (\x. norm(a) % x)) s))) /\ + (!Q. (?s:(real^N->bool)->bool. Q s) <=> + (?s. Q(IMAGE (IMAGE (\x. norm(a) % x)) s))) /\ + (!P. (!g:real^1->real^N. P g) <=> + (!g. P ((\x. norm(a) % x) o g))) /\ + (!P. (?g:real^1->real^N. P g) <=> + (?g. P ((\x. norm(a) % x) o g))) /\ + (!P. (!g:num->real^N. P g) <=> + (!g. P ((\x. norm(a) % x) o g))) /\ + (!P. (?g:num->real^N. P g) <=> + (?g. P ((\x. norm(a) % x) o g))) /\ + (!Q. (!l. Q l) <=> (!l. Q(MAP (\x:real^N. norm(a) % x) l))) /\ + (!Q. (?l. Q l) <=> (?l. Q(MAP (\x:real^N. norm(a) % x) l)))) /\ + ((!P. {x:real^N | P x} = + IMAGE (\x. norm(a) % x) {x | P(norm(a) % x)}) /\ + (!Q. {s:real^N->bool | Q s} = + IMAGE (IMAGE (\x. norm(a) % x)) + {s | Q(IMAGE (\x. norm(a) % x) s)}) /\ + (!R. {l:(real^N)list | R l} = + IMAGE (MAP (\x:real^N. norm(a) % x)) + {l | R(MAP (\x:real^N. norm(a) % x) l)}))`, + GEN_TAC THEN DISCH_TAC THEN MATCH_MP_TAC(TAUT + `(a /\ b) /\ c /\ d ==> (a /\ b /\ c) /\ d`) THEN + CONJ_TAC THENL + [ASM_MESON_TAC[NORM_EQ_0; REAL_FIELD `~(x = &0) ==> x * inv x * a = a`]; + MP_TAC(ISPEC `\x:real^N. norm(a:real^N) % x` + (INST_TYPE [`:real^1`,`:C`] QUANTIFY_SURJECTION_HIGHER_THM)) THEN + ASM_REWRITE_TAC[] THEN DISCH_THEN MATCH_MP_TAC THEN + ASM_SIMP_TAC[SURJECTIVE_SCALING; NORM_EQ_0]]) + and lth = prove + (`(!b:real^N. ~(b = vec 0) ==> (P(b) <=> Q(inv(norm b) % b))) + ==> P(vec 0) /\ (!b. norm(b) = &1 ==> Q b) ==> (!b. P b)`, + REPEAT STRIP_TAC THEN + ASM_CASES_TAC `b:real^N = vec 0` THEN ASM_SIMP_TAC[] THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_SIMP_TAC[NORM_MUL; REAL_ABS_INV; REAL_ABS_NORM; + REAL_MUL_LINV; NORM_EQ_0]) in + fun avoid tm -> + let x,tm0 = dest_forall tm in + let cth = UNDISCH(ISPEC x pth) + and vth = UNDISCH(ISPEC x qth) in + let th1 = ONCE_REWRITE_CONV[cth] tm0 in + let th2 = CONV_RULE (RAND_CONV + (PARTIAL_EXPAND_QUANTS_CONV avoid vth)) th1 in + let th3 = SCALING_THEOREMS x in + let th3' = (end_itlist CONJ (map + (fun th -> let avs,_ = strip_forall(concl th) in + let gvs = map (genvar o type_of) avs in + GENL gvs (SPECL gvs th)) + (CONJUNCTS th3))) in + let th4 = GEN_REWRITE_RULE (RAND_CONV o REDEPTH_CONV) + [BETA_THM; th3'] th2 in + MATCH_MP lth (GEN x (DISCH_ALL th4));; + +let GEN_GEOM_NORMALIZE_TAC x avoid (asl,w as gl) = + let avs,bod = strip_forall w + and avs' = subtract (frees w) (freesl(map (concl o snd) asl)) in + (MAP_EVERY X_GEN_TAC avs THEN + MAP_EVERY (fun t -> SPEC_TAC(t,t)) (rev(subtract (avs@avs') [x])) THEN + SPEC_TAC(x,x) THEN + W(MATCH_MP_TAC o GEOM_NORMALIZE_RULE avoid o snd)) gl;; + +let GEOM_NORMALIZE_TAC x = GEN_GEOM_NORMALIZE_TAC x [];; + +(* ------------------------------------------------------------------------- *) +(* Add invariance theorems for collinearity. *) +(* ------------------------------------------------------------------------- *) + +let COLLINEAR_TRANSLATION_EQ = prove + (`!a s. collinear (IMAGE (\x. a + x) s) <=> collinear s`, + REWRITE_TAC[collinear] THEN GEOM_TRANSLATE_TAC["u"]);; + +add_translation_invariants [COLLINEAR_TRANSLATION_EQ];; + +let COLLINEAR_TRANSLATION = prove + (`!s a. collinear s ==> collinear (IMAGE (\x. a + x) s)`, + REWRITE_TAC[COLLINEAR_TRANSLATION_EQ]);; + +let COLLINEAR_LINEAR_IMAGE = prove + (`!f s. collinear s /\ linear f ==> collinear(IMAGE f s)`, + REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN + REWRITE_TAC[collinear; IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_IMAGE] THEN + ASM_MESON_TAC[LINEAR_SUB; LINEAR_CMUL]);; + +let COLLINEAR_LINEAR_IMAGE_EQ = prove + (`!f s. linear f /\ (!x y. f x = f y ==> x = y) + ==> (collinear (IMAGE f s) <=> collinear s)`, + MATCH_ACCEPT_TAC(LINEAR_INVARIANT_RULE COLLINEAR_LINEAR_IMAGE));; + +add_linear_invariants [COLLINEAR_LINEAR_IMAGE_EQ];; + +(* ------------------------------------------------------------------------- *) +(* Take a theorem "th" with outer universal quantifiers involving real^N *) +(* and a theorem "dth" asserting |- dimindex(:M) <= dimindex(:N) and *) +(* return a theorem replacing type :N by :M in th. Neither N or M need be a *) +(* type variable. *) +(* ------------------------------------------------------------------------- *) + +let GEOM_DROP_DIMENSION_RULE = + let oth = prove + (`!f:real^M->real^N. + linear f /\ (!x. norm(f x) = norm x) + ==> linear f /\ + (!x y. f x = f y ==> x = y) /\ + (!x. norm(f x) = norm x)`, + MESON_TAC[PRESERVES_NORM_INJECTIVE]) + and cth = prove + (`linear(f:real^M->real^N) + ==> vec 0 = f(vec 0) /\ + {} = IMAGE f {} /\ + {} = IMAGE (IMAGE f) {} /\ + [] = MAP f []`, + REWRITE_TAC[IMAGE_CLAUSES; MAP; GSYM LINEAR_0]) in + fun dth th -> + let ath = GEN_ALL th + and eth = MATCH_MP ISOMETRY_UNIV_UNIV dth + and avoid = variables(concl th) in + let f,bod = dest_exists(concl eth) in + let fimage = list_mk_icomb "IMAGE" [f] + and fmap = list_mk_icomb "MAP" [f] + and fcompose = list_mk_icomb "o" [f] in + let fimage2 = list_mk_icomb "IMAGE" [fimage] in + let lin,iso = CONJ_PAIR(ASSUME bod) in + let olduniv = rand(rand(concl dth)) + and newuniv = rand(lhand(concl dth)) in + let oldty = fst(dest_fun_ty(type_of olduniv)) + and newty = fst(dest_fun_ty(type_of newuniv)) in + let newvar v = + let n,t = dest_var v in + variant avoid (mk_var(n,tysubst[newty,oldty] t)) in + let newterm v = + try let v' = newvar v in + tryfind (fun f -> mk_comb(f,v')) [f;fimage;fmap;fcompose;fimage2] + with Failure _ -> v in + let specrule th = + let v = fst(dest_forall(concl th)) in SPEC (newterm v) th in + let sth = SUBS(CONJUNCTS(MATCH_MP cth lin)) ath in + let fth = SUBS[SYM(MATCH_MP LINEAR_0 lin)] (repeat specrule sth) in + let thps = CONJUNCTS(MATCH_MP oth (ASSUME bod)) in + let th5 = LINEAR_INVARIANTS f thps in + let th6 = GEN_REWRITE_RULE REDEPTH_CONV [th5] fth in + let th7 = PROVE_HYP eth (SIMPLE_CHOOSE f th6) in + GENL (map newvar (fst(strip_forall(concl ath)))) th7;; + +(* ------------------------------------------------------------------------- *) +(* Transfer theorems automatically between same-dimension spaces. *) +(* Given dth = A |- dimindex(:M) = dimindex(:N) *) +(* and a theorem th involving variables of type real^N *) +(* returns a corresponding theorem mapped to type real^M with assumptions A. *) +(* ------------------------------------------------------------------------- *) + +let GEOM_EQUAL_DIMENSION_RULE = + let bth = prove + (`dimindex(:M) = dimindex(:N) + ==> ?f:real^M->real^N. + (linear f /\ (!y. ?x. f x = y)) /\ + (!x. norm(f x) = norm x)`, + REWRITE_TAC[SET_RULE `(!y. ?x. f x = y) <=> IMAGE f UNIV = UNIV`] THEN + DISCH_TAC THEN REWRITE_TAC[GSYM CONJ_ASSOC] THEN + MATCH_MP_TAC ISOMETRY_UNIV_SUBSPACE THEN + REWRITE_TAC[SUBSPACE_UNIV; DIM_UNIV] THEN FIRST_ASSUM ACCEPT_TAC) + and pth = prove + (`!f:real^M->real^N. + linear f /\ (!y. ?x. f x = y) + ==> (vec 0 = f(vec 0) /\ + {} = IMAGE f {} /\ + {} = IMAGE (IMAGE f) {} /\ + (:real^N) = IMAGE f (:real^M) /\ + (:real^N->bool) = IMAGE (IMAGE f) (:real^M->bool) /\ + [] = MAP f []) /\ + ((!P. (!x. P x) <=> (!x. P (f x))) /\ + (!P. (?x. P x) <=> (?x. P (f x))) /\ + (!Q. (!s. Q s) <=> (!s. Q (IMAGE f s))) /\ + (!Q. (?s. Q s) <=> (?s. Q (IMAGE f s))) /\ + (!Q. (!s. Q s) <=> (!s. Q (IMAGE (IMAGE f) s))) /\ + (!Q. (?s. Q s) <=> (?s. Q (IMAGE (IMAGE f) s))) /\ + (!P. (!g:real^1->real^N. P g) <=> (!g. P (f o g))) /\ + (!P. (?g:real^1->real^N. P g) <=> (?g. P (f o g))) /\ + (!P. (!g:num->real^N. P g) <=> (!g. P (f o g))) /\ + (!P. (?g:num->real^N. P g) <=> (?g. P (f o g))) /\ + (!Q. (!l. Q l) <=> (!l. Q(MAP f l))) /\ + (!Q. (?l. Q l) <=> (?l. Q(MAP f l)))) /\ + ((!P. {x | P x} = IMAGE f {x | P(f x)}) /\ + (!Q. {s | Q s} = IMAGE (IMAGE f) {s | Q(IMAGE f s)}) /\ + (!R. {l | R l} = IMAGE (MAP f) {l | R(MAP f l)}))`, + GEN_TAC THEN + SIMP_TAC[SET_RULE `UNIV = IMAGE f UNIV <=> (!y. ?x. f x = y)`; + SURJECTIVE_IMAGE] THEN + MATCH_MP_TAC MONO_AND THEN + REWRITE_TAC[QUANTIFY_SURJECTION_HIGHER_THM] THEN + REWRITE_TAC[IMAGE_CLAUSES; MAP] THEN MESON_TAC[LINEAR_0]) in + fun dth th -> + let eth = EXISTS_GENVAR_RULE (MATCH_MP bth dth) in + let f,bod = dest_exists(concl eth) in + let lsth,neth = CONJ_PAIR(ASSUME bod) in + let cth,qth = CONJ_PAIR(MATCH_MP pth lsth) in + let th1 = CONV_RULE + (EXPAND_QUANTS_CONV qth THENC SUBS_CONV(CONJUNCTS cth)) th in + let ith = LINEAR_INVARIANTS f (neth::CONJUNCTS lsth) in + let th2 = GEN_REWRITE_RULE (RAND_CONV o REDEPTH_CONV) [BETA_THM;ith] th1 in + let th3 = GEN f (DISCH bod th2) in + MP (CONV_RULE (REWR_CONV LEFT_FORALL_IMP_THM) th3) eth;; diff --git a/Multivariate/dimension.ml b/Multivariate/dimension.ml new file mode 100644 index 0000000..d45401d --- /dev/null +++ b/Multivariate/dimension.ml @@ -0,0 +1,6177 @@ +(* ========================================================================= *) +(* Results connected with topological dimension. *) +(* *) +(* At the moment this is just Brouwer's fixpoint theorem. The proof is from *) +(* Kuhn: "some combinatorial lemmas in topology", IBM J. v4. (1960) p. 518 *) +(* See "http://www.research.ibm.com/journal/rd/045/ibmrd0405K.pdf". *) +(* *) +(* The script below is quite messy, but at least we avoid formalizing any *) +(* topological machinery; we don't even use barycentric subdivision; this is *) +(* the big advantage of Kuhn's proof over the usual Sperner's lemma one. *) +(* *) +(* (c) Copyright, John Harrison 1998-2008 *) +(* ========================================================================= *) + +needs "Multivariate/topology.ml";; +needs "Multivariate/paths.ml";; + +let BROUWER_COMPACTNESS_LEMMA = prove + (`!f:real^M->real^N s. + compact s /\ f continuous_on s /\ ~(?x. x IN s /\ (f x = vec 0)) + ==> ?d. &0 < d /\ !x. x IN s ==> d <= norm(f x)`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`norm o (f:real^M->real^N)`; `s:real^M->bool`] + CONTINUOUS_ATTAINS_INF) THEN + ASM_CASES_TAC `s:real^M->bool = {}` THEN ASM_REWRITE_TAC[NOT_IN_EMPTY] THENL + [MESON_TAC[REAL_LT_01]; ALL_TAC] THEN + ASM_SIMP_TAC[CONTINUOUS_ON_COMPOSE; o_ASSOC; CONTINUOUS_ON_LIFT_NORM] THEN + REWRITE_TAC[o_THM] THEN ASM_MESON_TAC[NORM_POS_LT]);; + +let KUHN_LABELLING_LEMMA = prove + (`!f:real^N->real^N P Q. + (!x. P x ==> P (f x)) + ==> (!x. P x ==> (!i. Q i ==> &0 <= x$i /\ x$i <= &1)) + ==> ?l. (!x i. l x i <= 1) /\ + (!x i. P x /\ Q i /\ (x$i = &0) ==> (l x i = 0)) /\ + (!x i. P x /\ Q i /\ (x$i = &1) ==> (l x i = 1)) /\ + (!x i. P x /\ Q i /\ (l x i = 0) ==> x$i <= f(x)$i) /\ + (!x i. P x /\ Q i /\ (l x i = 1) ==> f(x)$i <= x$i)`, + REPEAT GEN_TAC THEN REWRITE_TAC[AND_FORALL_THM; GSYM SKOLEM_THM] THEN + REWRITE_TAC[ARITH_RULE `n <= 1 <=> (n = 0) \/ (n = 1)`; + RIGHT_OR_DISTRIB; EXISTS_OR_THM; UNWIND_THM2; ARITH_EQ] THEN + MESON_TAC[REAL_ARITH + `!x y. &0 <= x /\ x <= &1 /\ &0 <= y /\ y <= &1 + ==> ~(x = &1) /\ x <= y \/ ~(x = &0) /\ y <= x`]);; + +(* ------------------------------------------------------------------------- *) +(* The key "counting" observation, somewhat abstracted. *) +(* ------------------------------------------------------------------------- *) + +let KUHN_COUNTING_LEMMA = prove + (`!face:F->S->bool faces simplices comp comp' bnd. + FINITE faces /\ FINITE simplices /\ + (!f. f IN faces /\ bnd f + ==> (CARD {s | s IN simplices /\ face f s} = 1)) /\ + (!f. f IN faces /\ ~bnd f + ==> (CARD {s | s IN simplices /\ face f s} = 2)) /\ + (!s. s IN simplices /\ comp s + ==> (CARD {f | f IN faces /\ face f s /\ comp' f} = 1)) /\ + (!s. s IN simplices /\ ~comp s + ==> (CARD {f | f IN faces /\ face f s /\ comp' f} = 0) \/ + (CARD {f | f IN faces /\ face f s /\ comp' f} = 2)) + ==> ODD(CARD {f | f IN faces /\ comp' f /\ bnd f}) + ==> ODD(CARD {s | s IN simplices /\ comp s})`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN + `sum simplices + (\s:S. &(CARD {f:F | f IN faces /\ face f s /\ comp' f})) = + sum simplices + (\s. &(CARD {f | f IN {f | f IN faces /\ comp' f /\ bnd f} /\ + face f s})) + + sum simplices + (\s. &(CARD {f | f IN {f | f IN faces /\ comp' f /\ ~(bnd f)} /\ + face f s}))` + MP_TAC THENL + [ASM_SIMP_TAC[GSYM SUM_ADD] THEN MATCH_MP_TAC SUM_EQ THEN + ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN CONV_TAC SYM_CONV THEN + REWRITE_TAC[REAL_OF_NUM_ADD; REAL_OF_NUM_EQ] THEN + MATCH_MP_TAC CARD_UNION_EQ THEN ASM_SIMP_TAC[FINITE_RESTRICT] THEN + REWRITE_TAC[EXTENSION; IN_ELIM_THM; IN_INTER; IN_UNION; NOT_IN_EMPTY] THEN + CONJ_TAC THEN GEN_TAC THEN CONV_TAC TAUT; + ALL_TAC] THEN + MP_TAC(ISPECL + [`\s f. (face:F->S->bool) f s`; `simplices:S->bool`; + `{f:F | f IN faces /\ comp' f /\ bnd f}`; `1`] SUM_MULTICOUNT) THEN + MP_TAC(ISPECL + [`\s f. (face:F->S->bool) f s`; `simplices:S->bool`; + `{f:F | f IN faces /\ comp' f /\ ~(bnd f)}`; `2`] SUM_MULTICOUNT) THEN + REWRITE_TAC[] THEN + REPEAT(ANTS_TAC THENL + [ASM_SIMP_TAC[FINITE_RESTRICT] THEN GEN_TAC THEN + DISCH_THEN(fun th -> FIRST_ASSUM MATCH_MP_TAC THEN MP_TAC th) THEN + SIMP_TAC[IN_ELIM_THM]; + DISCH_THEN SUBST1_TAC]) THEN + SUBGOAL_THEN + `sum simplices + (\s:S. &(CARD {f:F | f IN faces /\ face f s /\ comp' f})) = + sum {s | s IN simplices /\ comp s} + (\s:S. &(CARD {f:F | f IN faces /\ face f s /\ comp' f})) + + sum {s | s IN simplices /\ ~(comp s)} + (\s:S. &(CARD {f:F | f IN faces /\ face f s /\ comp' f}))` + SUBST1_TAC THENL + [CONV_TAC SYM_CONV THEN MATCH_MP_TAC SUM_UNION_EQ THEN + ASM_REWRITE_TAC[] THEN REWRITE_TAC[EXTENSION; NOT_IN_EMPTY] THEN + REWRITE_TAC[IN_ELIM_THM; IN_INTER; IN_UNION] THEN + CONJ_TAC THEN GEN_TAC THEN CONV_TAC TAUT; + ALL_TAC] THEN + SUBGOAL_THEN + `sum {s | s IN simplices /\ comp s} + (\s:S. &(CARD {f:F | f IN faces /\ face f s /\ comp' f})) = + sum {s | s IN simplices /\ comp s} (\s. &1)` + SUBST1_TAC THENL + [MATCH_MP_TAC SUM_EQ THEN ASM_SIMP_TAC[FINITE_RESTRICT] THEN + GEN_TAC THEN REWRITE_TAC[REAL_OF_NUM_EQ] THEN + DISCH_THEN(fun th -> FIRST_ASSUM MATCH_MP_TAC THEN MP_TAC th) THEN + SIMP_TAC[IN_ELIM_THM]; + ALL_TAC] THEN + SUBGOAL_THEN + `sum {s | s IN simplices /\ ~(comp s)} + (\s:S. &(CARD {f:F | f IN faces /\ face f s /\ comp' f})) = + sum {s | s IN simplices /\ ~(comp s) /\ + (CARD {f | f IN faces /\ face f s /\ comp' f} = 0)} + (\s:S. &(CARD {f:F | f IN faces /\ face f s /\ comp' f})) + + sum {s | s IN simplices /\ ~(comp s) /\ + (CARD {f | f IN faces /\ face f s /\ comp' f} = 2)} + (\s:S. &(CARD {f:F | f IN faces /\ face f s /\ comp' f}))` + SUBST1_TAC THENL + [CONV_TAC SYM_CONV THEN MATCH_MP_TAC SUM_UNION_EQ THEN + ASM_SIMP_TAC[FINITE_RESTRICT] THEN + REWRITE_TAC[EXTENSION; NOT_IN_EMPTY; IN_INTER; IN_UNION] THEN + CONJ_TAC THENL + [REWRITE_TAC[IN_ELIM_THM] THEN MESON_TAC[ARITH_RULE `~(2 = 0)`]; + ALL_TAC] THEN + X_GEN_TAC `s:S` THEN UNDISCH_TAC + `!s:S. s IN simplices /\ ~comp s + ==> (CARD {f:F | f IN faces /\ face f s /\ comp' f} = 0) \/ + (CARD {f | f IN faces /\ face f s /\ comp' f} = 2)` THEN + DISCH_THEN(MP_TAC o SPEC `s:S`) THEN + REWRITE_TAC[IN_ELIM_THM] THEN CONV_TAC TAUT; + ALL_TAC] THEN + SUBGOAL_THEN + `!n. sum {s | s IN simplices /\ ~(comp s) /\ + (CARD {f | f IN faces /\ face f s /\ comp' f} = n)} + (\s:S. &(CARD {f:F | f IN faces /\ face f s /\ comp' f})) = + sum {s | s IN simplices /\ ~(comp s) /\ + (CARD {f | f IN faces /\ face f s /\ comp' f} = n)} + (\s:S. &n)` + (fun th -> REWRITE_TAC[th]) + THENL + [GEN_TAC THEN MATCH_MP_TAC SUM_EQ THEN ASM_SIMP_TAC[FINITE_RESTRICT] THEN + SIMP_TAC[IN_ELIM_THM]; + ALL_TAC] THEN + REWRITE_TAC[SUM_0] THEN ASM_SIMP_TAC[SUM_CONST; FINITE_RESTRICT] THEN + REWRITE_TAC[REAL_OF_NUM_MUL; REAL_OF_NUM_ADD; REAL_OF_NUM_EQ] THEN + REWRITE_TAC[ADD_CLAUSES; MULT_CLAUSES] THEN + FIRST_X_ASSUM(CHOOSE_THEN SUBST1_TAC o GEN_REWRITE_RULE I [ODD_EXISTS]) THEN + DISCH_THEN(MP_TAC o AP_TERM `ODD`) THEN + REWRITE_TAC[ODD_ADD; ODD_MULT; ARITH_ODD; ODD]);; + +(* ------------------------------------------------------------------------- *) +(* The odd/even result for faces of complete vertices, generalized. *) +(* ------------------------------------------------------------------------- *) + +let HAS_SIZE_1_EXISTS = prove + (`!s. s HAS_SIZE 1 <=> ?!x. x IN s`, + REPEAT GEN_TAC THEN CONV_TAC(LAND_CONV HAS_SIZE_CONV) THEN + REWRITE_TAC[EXTENSION; IN_SING] THEN MESON_TAC[]);; + +let HAS_SIZE_2_EXISTS = prove + (`!s. s HAS_SIZE 2 <=> ?x y. ~(x = y) /\ !z. z IN s <=> (z = x) \/ (z = y)`, + REPEAT GEN_TAC THEN CONV_TAC(LAND_CONV HAS_SIZE_CONV) THEN + REWRITE_TAC[EXTENSION; IN_INSERT; NOT_IN_EMPTY] THEN MESON_TAC[]);; + +let IMAGE_LEMMA_0 = prove + (`!f:A->B s n. + {a | a IN s /\ (IMAGE f (s DELETE a) = t DELETE b)} HAS_SIZE n + ==> {s' | ?a. a IN s /\ (s' = s DELETE a) /\ (IMAGE f s' = t DELETE b)} + HAS_SIZE n`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN + `{s' | ?a. a IN s /\ (s' = s DELETE a) /\ (IMAGE f s' = t DELETE b)} = + IMAGE (\a. s DELETE a) + {a | a IN s /\ (IMAGE (f:A->B) (s DELETE a) = t DELETE b)}` + SUBST1_TAC THENL + [GEN_REWRITE_TAC I [EXTENSION] THEN + REWRITE_TAC[IN_ELIM_THM; IN_IMAGE] THEN MESON_TAC[]; + MATCH_MP_TAC HAS_SIZE_IMAGE_INJ THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[EXTENSION; IN_ELIM_THM; IN_DELETE] THEN MESON_TAC[]]);; + +let IMAGE_LEMMA_1 = prove + (`!f:A->B s t b. + FINITE s /\ FINITE t /\ (CARD s = CARD t) /\ + (IMAGE f s = t) /\ b IN t + ==> (CARD {s' | ?a. a IN s /\ (s' = s DELETE a) /\ + (IMAGE f s' = t DELETE b)} = 1)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_SIZE_CARD THEN + MATCH_MP_TAC IMAGE_LEMMA_0 THEN REWRITE_TAC[HAS_SIZE_1_EXISTS] THEN + SUBGOAL_THEN `!x y. x IN s /\ y IN s /\ ((f:A->B) x = f y) ==> (x = y)` + ASSUME_TAC THENL [ASM_MESON_TAC[IMAGE_IMP_INJECTIVE_GEN]; ALL_TAC] THEN + REWRITE_TAC[EXISTS_UNIQUE_THM; IN_ELIM_THM] THEN CONJ_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [EXTENSION]) THEN + REWRITE_TAC[IN_IMAGE] THENL + [DISCH_THEN(fun th -> MP_TAC(SPEC `b:B` th) THEN MP_TAC th) THEN + ASM_REWRITE_TAC[] THEN DISCH_TAC THEN MATCH_MP_TAC MONO_EXISTS THEN + REWRITE_TAC[EXTENSION; IN_IMAGE; IN_DELETE] THEN + REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THEN ASM_MESON_TAC[]; + REWRITE_TAC[EXTENSION; IN_IMAGE; IN_DELETE] THEN ASM_MESON_TAC[]]);; + +let IMAGE_LEMMA_2 = prove + (`!f:A->B s t b. + FINITE s /\ FINITE t /\ (CARD s = CARD t) /\ + (IMAGE f s) SUBSET t /\ ~(IMAGE f s = t) /\ b IN t + ==> (CARD {s' | ?a. a IN s /\ (s' = s DELETE a) /\ + (IMAGE f s' = t DELETE b)} = 0) \/ + (CARD {s' | ?a. a IN s /\ (s' = s DELETE a) /\ + (IMAGE f s' = t DELETE b)} = 2)`, + REPEAT STRIP_TAC THEN ASM_CASES_TAC + `{a | a IN s /\ (IMAGE (f:A->B) (s DELETE a) = t DELETE b)} = {}` + THENL [DISJ1_TAC; DISJ2_TAC] THEN MATCH_MP_TAC HAS_SIZE_CARD THEN + MATCH_MP_TAC IMAGE_LEMMA_0 THEN + ASM_REWRITE_TAC[HAS_SIZE_0; HAS_SIZE_2_EXISTS] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `a1:A` THEN + REWRITE_TAC[IN_ELIM_THM] THEN STRIP_TAC THEN + SUBGOAL_THEN `(f:A->B) a1 IN (t DELETE b)` ASSUME_TAC THENL + [REWRITE_TAC[IN_DELETE] THEN + ASM_MESON_TAC[SUBSET; IN_IMAGE; INSERT_DELETE; IMAGE_CLAUSES]; + ALL_TAC] THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [EXTENSION]) THEN + DISCH_THEN(MP_TAC o SPEC `(f:A->B) a1`) THEN ASM_REWRITE_TAC[IN_IMAGE] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `a2:A` THEN + REWRITE_TAC[IN_DELETE] THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + SUBGOAL_THEN + `!x y. x IN (s DELETE a1) /\ y IN (s DELETE a1) /\ ((f:A->B) x = f y) + ==> (x = y)` + MP_TAC THENL + [MATCH_MP_TAC IMAGE_IMP_INJECTIVE_GEN THEN EXISTS_TAC `t DELETE (b:B)` THEN + ASM_SIMP_TAC[CARD_DELETE; FINITE_DELETE]; + REWRITE_TAC[IN_DELETE] THEN DISCH_TAC] THEN + X_GEN_TAC `a:A` THEN ASM_CASES_TAC `a:A = a1` THEN ASM_REWRITE_TAC[] THEN + ASM_CASES_TAC `(a:A) IN s` THEN ASM_REWRITE_TAC[] THENL + [ALL_TAC; ASM_MESON_TAC[]] THEN + MATCH_MP_TAC EQ_TRANS THEN EXISTS_TAC `(f:A->B) a = f a1` THEN CONJ_TAC THENL + [ALL_TAC; ASM_MESON_TAC[IN_DELETE]] THEN + FIRST_X_ASSUM(fun t -> GEN_REWRITE_TAC (LAND_CONV o RAND_CONV) [SYM t]) THEN + REWRITE_TAC[EXTENSION; IN_IMAGE; IN_DELETE] THEN EQ_TAC THENL + [DISCH_THEN(MP_TAC o SPEC `(f:A->B) a`); ALL_TAC] THEN + ASM_MESON_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* Combine this with the basic counting lemma. *) +(* ------------------------------------------------------------------------- *) + +let KUHN_COMPLETE_LEMMA = prove + (`!face:(A->bool)->(A->bool)->bool simplices rl bnd n. + FINITE simplices /\ + (!f s. face f s <=> ?a. a IN s /\ (f = s DELETE a)) /\ + (!s. s IN simplices ==> s HAS_SIZE (n + 2) /\ + (IMAGE rl s) SUBSET 0..n+1) /\ + (!f. f IN {f | ?s. s IN simplices /\ face f s} /\ bnd f + ==> (CARD {s | s IN simplices /\ face f s} = 1)) /\ + (!f. f IN {f | ?s. s IN simplices /\ face f s} /\ ~bnd f + ==> (CARD {s | s IN simplices /\ face f s} = 2)) + ==> ODD(CARD {f | f IN {f | ?s. s IN simplices /\ face f s} /\ + (IMAGE rl f = 0..n) /\ bnd f}) + ==> ODD(CARD {s | s IN simplices /\ (IMAGE rl s = 0..n+1)})`, + REPEAT GEN_TAC THEN STRIP_TAC THEN + SUBGOAL_THEN + `!P f:A->bool s. + s IN simplices + ==> (f IN {f | ?s. s IN simplices /\ (?a. a IN s /\ (f = s DELETE a))} /\ + (?a. a IN s /\ (f = s DELETE a)) /\ P f <=> + (?a. a IN s /\ (f = s DELETE a) /\ P f))` + ASSUME_TAC THENL + [ASM_REWRITE_TAC[IN_ELIM_THM] THEN MESON_TAC[]; ALL_TAC] THEN + SUBGOAL_THEN `0..n = (0..n+1) DELETE (n+1)` SUBST1_TAC THENL + [REWRITE_TAC[EXTENSION; IN_NUMSEG; IN_DELETE] THEN ARITH_TAC; + ALL_TAC] THEN + MATCH_MP_TAC KUHN_COUNTING_LEMMA THEN + EXISTS_TAC `face:(A->bool)->(A->bool)->bool` THEN + REPEAT CONJ_TAC THEN TRY(FIRST_ASSUM ACCEPT_TAC) THEN + ASM_SIMP_TAC[] THENL + [SUBGOAL_THEN + `{f:A->bool | ?s. s IN simplices /\ (?a. a IN s /\ (f = s DELETE a))} = + UNIONS (IMAGE (\s. {f | ?a. a IN s /\ (f = s DELETE a)}) simplices)` + SUBST1_TAC THENL + [REWRITE_TAC[EXTENSION; UNIONS_IMAGE; IN_ELIM_THM]; ALL_TAC] THEN + ASM_SIMP_TAC[FINITE_UNIONS; FINITE_IMAGE] THEN + REWRITE_TAC[FORALL_IN_IMAGE] THEN X_GEN_TAC `s:A->bool` THEN + DISCH_TAC THEN MATCH_MP_TAC FINITE_SUBSET THEN + EXISTS_TAC `{t:A->bool | t SUBSET s}` THEN CONJ_TAC THENL + [MATCH_MP_TAC FINITE_POWERSET THEN ASM_MESON_TAC[HAS_SIZE]; + SIMP_TAC[SUBSET; IN_ELIM_THM; LEFT_IMP_EXISTS_THM; IN_DELETE]]; + REPEAT STRIP_TAC THEN MATCH_MP_TAC IMAGE_LEMMA_1; + REPEAT STRIP_TAC THEN MATCH_MP_TAC IMAGE_LEMMA_2] THEN + ASM_REWRITE_TAC[FINITE_NUMSEG; IN_NUMSEG; LE_0; LE_REFL] THEN + REWRITE_TAC[CARD_NUMSEG; ARITH_RULE `((n + 1) + 1) - 0 = n + 2`] THEN + ASM_MESON_TAC[HAS_SIZE]);; + +(* ------------------------------------------------------------------------- *) +(* We use the following notion of ordering rather than pointwise indexing. *) +(* ------------------------------------------------------------------------- *) + +let kle = new_definition + `kle n x y <=> ?k. k SUBSET 1..n /\ + (!j. y(j) = x(j) + (if j IN k then 1 else 0))`;; + +let KLE_REFL = prove + (`!n x. kle n x x`, + REPEAT GEN_TAC THEN REWRITE_TAC[kle] THEN EXISTS_TAC `{}:num->bool` THEN + REWRITE_TAC[ADD_CLAUSES; NOT_IN_EMPTY; EMPTY_SUBSET]);; + +let KLE_ANTISYM = prove + (`!n x y. kle n x y /\ kle n y x <=> (x = y)`, + REPEAT GEN_TAC THEN EQ_TAC THENL [REWRITE_TAC[kle]; MESON_TAC[KLE_REFL]] THEN + DISCH_THEN(CONJUNCTS_THEN2 STRIP_ASSUME_TAC MP_TAC) THEN + ASM_REWRITE_TAC[FUN_EQ_THM] THEN + MESON_TAC[ARITH_RULE `(x = (x + a) + b) ==> (x = x + a:num)`]);; + +let POINTWISE_MINIMAL,POINTWISE_MAXIMAL = (CONJ_PAIR o prove) + (`(!s:(num->num)->bool. + FINITE s + ==> ~(s = {}) /\ + (!x y. x IN s /\ y IN s + ==> (!j. x(j) <= y(j)) \/ (!j. y(j) <= x(j))) + ==> ?a. a IN s /\ !x. x IN s ==> !j. a(j) <= x(j)) /\ + (!s:(num->num)->bool. + FINITE s + ==> ~(s = {}) /\ + (!x y. x IN s /\ y IN s + ==> (!j. x(j) <= y(j)) \/ (!j. y(j) <= x(j))) + ==> ?a. a IN s /\ !x. x IN s ==> !j. x(j) <= a(j))`, + CONJ_TAC THEN + (MATCH_MP_TAC FINITE_INDUCT_STRONG THEN REWRITE_TAC[NOT_INSERT_EMPTY] THEN + MAP_EVERY X_GEN_TAC [`a:num->num`; `s:(num->num)->bool`] THEN + ASM_CASES_TAC `s:(num->num)->bool = {}` THEN ASM_REWRITE_TAC[] THENL + [REWRITE_TAC[IN_SING] THEN MESON_TAC[LE_REFL]; ALL_TAC] THEN + DISCH_THEN(CONJUNCTS_THEN2 MP_TAC STRIP_ASSUME_TAC) THEN + DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN + ANTS_TAC THENL [ASM_MESON_TAC[IN_INSERT]; ALL_TAC] THEN + DISCH_THEN(X_CHOOSE_THEN `b:num->num` STRIP_ASSUME_TAC) THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`a:num->num`; `b:num->num`]) THEN + ASM_REWRITE_TAC[IN_INSERT] THEN ASM_MESON_TAC[LE_CASES; LE_TRANS]));; + +let KLE_IMP_POINTWISE = prove + (`!n x y. kle n x y ==> !j. x(j) <= y(j)`, + REWRITE_TAC[kle] THEN REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[LE_ADD]);; + +let POINTWISE_ANTISYM = prove + (`!x y:num->num. (!j. x(j) <= y(j)) /\ (!j. y(j) <= x(j)) <=> (x = y)`, + REWRITE_TAC[AND_FORALL_THM; FUN_EQ_THM; LE_ANTISYM]);; + +let KLE_TRANS = prove + (`!x y z n. kle n x y /\ kle n y z /\ (kle n x z \/ kle n z x) + ==> kle n x z`, + REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + SUBGOAL_THEN `x:num->num = z` (fun th -> REWRITE_TAC[KLE_REFL; th]) THEN + REWRITE_TAC[FUN_EQ_THM; GSYM LE_ANTISYM; FORALL_AND_THM] THEN + ASM_MESON_TAC[KLE_IMP_POINTWISE; LE_TRANS]);; + +let KLE_STRICT = prove + (`!n x y. kle n x y /\ ~(x = y) + ==> (!j. x(j) <= y(j)) /\ (?k. 1 <= k /\ k <= n /\ x(k) < y(k))`, + REPEAT GEN_TAC THEN REWRITE_TAC[kle] THEN + DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN + DISCH_THEN(X_CHOOSE_THEN `k:num->bool` MP_TAC) THEN + ASM_CASES_TAC `k:num->bool = {}` THENL + [ASM_REWRITE_TAC[NOT_IN_EMPTY; ADD_CLAUSES; GSYM FUN_EQ_THM; ETA_AX]; + STRIP_TAC THEN ASM_REWRITE_TAC[LE_ADD] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `i:num` THEN + STRIP_TAC THEN ASM_REWRITE_TAC[ARITH_RULE `n < n + 1`] THEN + ASM_MESON_TAC[SUBSET; IN_NUMSEG]]);; + +let KLE_MINIMAL = prove + (`!s n. FINITE s /\ ~(s = {}) /\ + (!x y. x IN s /\ y IN s ==> kle n x y \/ kle n y x) + ==> ?a. a IN s /\ !x. x IN s ==> kle n a x`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN `?a:num->num. a IN s /\ !x. x IN s ==> !j. a(j) <= x(j)` + MP_TAC THENL + [MATCH_MP_TAC(REWRITE_RULE[IMP_IMP] POINTWISE_MINIMAL); ALL_TAC] THEN + ASM_MESON_TAC[POINTWISE_ANTISYM; KLE_IMP_POINTWISE]);; + +let KLE_MAXIMAL = prove + (`!s n. FINITE s /\ ~(s = {}) /\ + (!x y. x IN s /\ y IN s ==> kle n x y \/ kle n y x) + ==> ?a. a IN s /\ !x. x IN s ==> kle n x a`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN `?a:num->num. a IN s /\ !x. x IN s ==> !j. x(j) <= a(j)` + MP_TAC THENL + [MATCH_MP_TAC(REWRITE_RULE[IMP_IMP] POINTWISE_MAXIMAL); ALL_TAC] THEN + ASM_MESON_TAC[POINTWISE_ANTISYM; KLE_IMP_POINTWISE]);; + +let KLE_STRICT_SET = prove + (`!n x y. kle n x y /\ ~(x = y) ==> 1 <= CARD {k | k IN 1..n /\ x(k) < y(k)}`, + REPEAT GEN_TAC THEN DISCH_THEN(MP_TAC o MATCH_MP KLE_STRICT) THEN + DISCH_THEN(X_CHOOSE_THEN `i:num` STRIP_ASSUME_TAC o CONJUNCT2) THEN + MATCH_MP_TAC LE_TRANS THEN EXISTS_TAC `CARD {i:num}` THEN CONJ_TAC THENL + [SIMP_TAC[CARD_CLAUSES; FINITE_RULES; ARITH; NOT_IN_EMPTY]; + MATCH_MP_TAC CARD_SUBSET THEN SIMP_TAC[FINITE_RESTRICT; FINITE_NUMSEG] THEN + SIMP_TAC[IN_ELIM_THM; IN_NUMSEG; SUBSET; IN_SING] THEN ASM_MESON_TAC[]]);; + +let KLE_RANGE_COMBINE = prove + (`!n x y m1 m2. + kle n x y /\ kle n y z /\ (kle n x z \/ kle n z x) /\ + m1 <= CARD {k | k IN 1..n /\ x(k) < y(k)} /\ + m2 <= CARD {k | k IN 1..n /\ y(k) < z(k)} + ==> kle n x z /\ m1 + m2 <= CARD {k | k IN 1..n /\ x(k) < z(k)}`, + REPEAT GEN_TAC THEN DISCH_THEN(REPEAT_TCL CONJUNCTS_THEN ASSUME_TAC) THEN + MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN CONJ_TAC THENL + [ASM_MESON_TAC[KLE_TRANS]; DISCH_TAC] THEN + MATCH_MP_TAC LE_TRANS THEN + EXISTS_TAC `CARD {k | k IN 1..n /\ x(k):num < y(k)} + + CARD {k | k IN 1..n /\ y(k) < z(k)}` THEN + ASM_SIMP_TAC[LE_ADD2] THEN MATCH_MP_TAC EQ_IMP_LE THEN + MATCH_MP_TAC CARD_UNION_EQ THEN + SIMP_TAC[FINITE_RESTRICT; FINITE_NUMSEG] THEN + REWRITE_TAC[EXTENSION; IN_ELIM_THM; IN_INTER; IN_UNION; NOT_IN_EMPTY] THEN + CONJ_TAC THENL + [ALL_TAC; + ASM_MESON_TAC[KLE_IMP_POINTWISE; ARITH_RULE + `x <= y:num /\ y <= z ==> (x < y \/ y < z <=> x < z)`]] THEN + X_GEN_TAC `i:num` THEN UNDISCH_TAC `kle n x z` THEN + REWRITE_TAC[kle] THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + ASM_CASES_TAC `i IN 1..n` THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC(ARITH_RULE `d <= 1 ==> ~(a < x /\ x < a + d)`) THEN + COND_CASES_TAC THEN REWRITE_TAC[ARITH]);; + +let KLE_RANGE_COMBINE_L = prove + (`!n x y m. + kle n x y /\ kle n y z /\ (kle n x z \/ kle n z x) /\ + m <= CARD {k | k IN 1..n /\ y(k) < z(k)} + ==> kle n x z /\ m <= CARD {k | k IN 1..n /\ x(k) < z(k)}`, + REPEAT GEN_TAC THEN ASM_CASES_TAC `x:num->num = y` THEN ASM_SIMP_TAC[] THEN + DISCH_THEN(REPEAT_TCL CONJUNCTS_THEN ASSUME_TAC) THEN + SUBGOAL_THEN `kle n x z /\ 1 + m <= CARD {k | k IN 1 .. n /\ x k < z k}` + (fun th -> MESON_TAC[th; ARITH_RULE `1 + m <= x ==> m <= x`]) THEN + MATCH_MP_TAC KLE_RANGE_COMBINE THEN EXISTS_TAC `y:num->num` THEN + ASM_SIMP_TAC[KLE_STRICT_SET]);; + +let KLE_RANGE_COMBINE_R = prove + (`!n x y m. + kle n x y /\ kle n y z /\ (kle n x z \/ kle n z x) /\ + m <= CARD {k | k IN 1..n /\ x(k) < y(k)} + ==> kle n x z /\ m <= CARD {k | k IN 1..n /\ x(k) < z(k)}`, + REPEAT GEN_TAC THEN ASM_CASES_TAC `y:num->num = z` THEN ASM_SIMP_TAC[] THEN + DISCH_THEN(REPEAT_TCL CONJUNCTS_THEN ASSUME_TAC) THEN + SUBGOAL_THEN `kle n x z /\ m + 1 <= CARD {k | k IN 1 .. n /\ x k < z k}` + (fun th -> MESON_TAC[th; ARITH_RULE `m + 1 <= x ==> m <= x`]) THEN + MATCH_MP_TAC KLE_RANGE_COMBINE THEN EXISTS_TAC `y:num->num` THEN + ASM_SIMP_TAC[KLE_STRICT_SET]);; + +let KLE_RANGE_INDUCT = prove + (`!n m s. s HAS_SIZE (SUC m) + ==> (!x y. x IN s /\ y IN s ==> kle n x y \/ kle n y x) + ==> ?x y. x IN s /\ y IN s /\ kle n x y /\ + m <= CARD {k | k IN 1..n /\ x(k) < y(k)}`, + GEN_TAC THEN INDUCT_TAC THENL + [GEN_TAC THEN REWRITE_TAC[ARITH; LE_0] THEN + CONV_TAC(LAND_CONV HAS_SIZE_CONV) THEN MESON_TAC[IN_SING; KLE_REFL]; + ALL_TAC] THEN + X_GEN_TAC `s:(num->num)->bool` THEN + ONCE_REWRITE_TAC[HAS_SIZE_SUC] THEN REPEAT STRIP_TAC THEN + MP_TAC(SPECL [`s:(num->num)->bool`; `n:num`] KLE_MINIMAL) THEN + ANTS_TAC THENL [ASM_MESON_TAC[HAS_SIZE_SUC; HAS_SIZE]; ALL_TAC] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `a:num->num` THEN + STRIP_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC `s DELETE (a:num->num)`) THEN + REPEAT(ANTS_TAC THENL [ASM_MESON_TAC[IN_DELETE]; ALL_TAC]) THEN + DISCH_THEN(X_CHOOSE_THEN `x:num->num` MP_TAC) THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `b:num->num` THEN + REWRITE_TAC[IN_DELETE] THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[ARITH_RULE `SUC m = 1 + m`] THEN + MATCH_MP_TAC KLE_RANGE_COMBINE THEN EXISTS_TAC `x:num->num` THEN + ASM_SIMP_TAC[KLE_STRICT_SET]);; + +let KLE_SUC = prove + (`!n x y. kle n x y ==> kle (n + 1) x y`, + REPEAT GEN_TAC THEN REWRITE_TAC[kle] THEN MATCH_MP_TAC MONO_EXISTS THEN + REWRITE_TAC[SUBSET; IN_NUMSEG] THEN + MESON_TAC[ARITH_RULE `k <= n ==> k <= n + 1`]);; + +let KLE_TRANS_1 = prove + (`!n x y. kle n x y ==> !j. x j <= y j /\ y j <= x j + 1`, + SIMP_TAC[kle; LEFT_IMP_EXISTS_THM] THEN + REPEAT STRIP_TAC THEN COND_CASES_TAC THEN ARITH_TAC);; + +let KLE_TRANS_2 = prove + (`!a b c. kle n a b /\ kle n b c /\ (!j. c j <= a j + 1) + ==> kle n a c`, + REPEAT GEN_TAC THEN REWRITE_TAC[IMP_CONJ] THEN + REWRITE_TAC[kle] THEN + DISCH_THEN(X_CHOOSE_THEN `kk1:num->bool` STRIP_ASSUME_TAC) THEN + DISCH_THEN(X_CHOOSE_THEN `kk2:num->bool` STRIP_ASSUME_TAC) THEN + ASM_REWRITE_TAC[] THEN + DISCH_THEN(fun th -> + EXISTS_TAC `(kk1:num->bool) UNION kk2` THEN MP_TAC th) THEN + ASM_REWRITE_TAC[UNION_SUBSET; IN_UNION] THEN + MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `i:num` THEN + ASM_CASES_TAC `(i:num) IN kk1` THEN ASM_CASES_TAC `(i:num) IN kk2` THEN + ASM_REWRITE_TAC[] THEN ARITH_TAC);; + +let KLE_BETWEEN_R = prove + (`!a b c x. kle n a b /\ kle n b c /\ kle n a x /\ kle n c x + ==> kle n b x`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC KLE_TRANS_2 THEN + EXISTS_TAC `c:num->num` THEN ASM_REWRITE_TAC[] THEN + ASM_MESON_TAC[KLE_TRANS_1; ARITH_RULE + `x <= c + 1 /\ c <= b ==> x <= b + 1`]);; + +let KLE_BETWEEN_L = prove + (`!a b c x. kle n a b /\ kle n b c /\ kle n x a /\ kle n x c + ==> kle n x b`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC KLE_TRANS_2 THEN + EXISTS_TAC `a:num->num` THEN ASM_REWRITE_TAC[] THEN + ASM_MESON_TAC[KLE_TRANS_1; ARITH_RULE + `c <= x + 1 /\ b <= c ==> b <= x + 1`]);; + +let KLE_ADJACENT = prove + (`!a b x k. + 1 <= k /\ k <= n /\ (!j. b(j) = if j = k then a(j) + 1 else a(j)) /\ + kle n a x /\ kle n x b + ==> (x = a) \/ (x = b)`, + REPEAT STRIP_TAC THEN + REPEAT(FIRST_X_ASSUM(MP_TAC o MATCH_MP KLE_IMP_POINTWISE)) THEN + ASM_REWRITE_TAC[FUN_EQ_THM; IMP_IMP; AND_FORALL_THM] THEN + ASM_CASES_TAC `(x:num->num) k = a k` THENL + [DISCH_THEN(fun th -> DISJ1_TAC THEN MP_TAC th); + DISCH_THEN(fun th -> DISJ2_TAC THEN MP_TAC th)] THEN + MATCH_MP_TAC MONO_FORALL THEN GEN_TAC THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[LE_ANTISYM] THEN + ASM_MESON_TAC[ARITH_RULE + `a <= x /\ x <= a + 1 /\ ~(x = a) ==> (x = a + 1)`]);; + +(* ------------------------------------------------------------------------- *) +(* Kuhn's notion of a simplex (my reformulation to avoid so much indexing). *) +(* ------------------------------------------------------------------------- *) + +let ksimplex = new_definition + `ksimplex p n s <=> + s HAS_SIZE (n + 1) /\ + (!x j. x IN s ==> x(j) <= p) /\ + (!x j. x IN s /\ ~(1 <= j /\ j <= n) ==> (x j = p)) /\ + (!x y. x IN s /\ y IN s ==> kle n x y \/ kle n y x)`;; + +let KSIMPLEX_EXTREMA = prove + (`!p n s. + ksimplex p n s + ==> ?a b. a IN s /\ b IN s /\ + (!x. x IN s ==> kle n a x /\ kle n x b) /\ + (!i. b(i) = if 1 <= i /\ i <= n then a(i) + 1 else a(i))`, + REPEAT GEN_TAC THEN REWRITE_TAC[ksimplex] THEN ASM_CASES_TAC `n = 0` THENL + [ASM_REWRITE_TAC[ARITH_RULE `1 <= i /\ i <= 0 <=> F`; GSYM FUN_EQ_THM] THEN + REWRITE_TAC[ADD_CLAUSES; ETA_AX] THEN + CONV_TAC(LAND_CONV(LAND_CONV HAS_SIZE_CONV)) THEN + DISCH_THEN(CONJUNCTS_THEN2 STRIP_ASSUME_TAC MP_TAC) THEN + ASM_REWRITE_TAC[IN_SING] THEN MESON_TAC[KLE_REFL]; + ALL_TAC] THEN + REPEAT STRIP_TAC THEN + MP_TAC(SPECL [`s:(num->num)->bool`; `n:num`] KLE_MINIMAL) THEN + ANTS_TAC THENL [ASM_MESON_TAC[HAS_SIZE; HAS_SIZE_SUC; ADD1]; ALL_TAC] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `a:num->num` THEN STRIP_TAC THEN + MP_TAC(SPECL [`s:(num->num)->bool`; `n:num`] KLE_MAXIMAL) THEN + ANTS_TAC THENL [ASM_MESON_TAC[HAS_SIZE; HAS_SIZE_SUC; ADD1]; ALL_TAC] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `b:num->num` THEN STRIP_TAC THEN + ASM_SIMP_TAC[] THEN + MP_TAC(SPECL [`n:num`; `n:num`; `s:(num->num)->bool`] KLE_RANGE_INDUCT) THEN + ASM_REWRITE_TAC[ADD1] THEN + DISCH_THEN(X_CHOOSE_THEN `c:num->num` (X_CHOOSE_THEN `d:num->num` + STRIP_ASSUME_TAC)) THEN + SUBGOAL_THEN `{k | k IN 1 .. n /\ a k :num < b k} = 1..n` MP_TAC THENL + [MATCH_MP_TAC CARD_SUBSET_LE THEN + ASM_REWRITE_TAC[CARD_NUMSEG; ADD_SUB; FINITE_NUMSEG; SUBSET_RESTRICT] THEN + SUBGOAL_THEN `kle n a b /\ n <= CARD {k | k IN 1..n /\ a(k) < b(k)}` + (fun th -> REWRITE_TAC[th]) THEN + MATCH_MP_TAC KLE_RANGE_COMBINE_L THEN EXISTS_TAC `c:num->num` THEN + ASM_SIMP_TAC[] THEN + SUBGOAL_THEN `kle n c b /\ n <= CARD {k | k IN 1 .. n /\ c k < b k}` + (fun th -> REWRITE_TAC[th]) THEN + MATCH_MP_TAC KLE_RANGE_COMBINE_R THEN EXISTS_TAC `d:num->num` THEN + ASM_SIMP_TAC[]; + ALL_TAC] THEN + SUBGOAL_THEN `kle n a b` MP_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN + DISCH_THEN(STRIP_ASSUME_TAC o GEN_REWRITE_RULE I [kle]) THEN + ASM_REWRITE_TAC[EXTENSION; IN_ELIM_THM; IN_NUMSEG] THEN + MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `i:num` THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[ADD_CLAUSES; LT_REFL] THEN + ASM_MESON_TAC[SUBSET; IN_NUMSEG]);; + +let KSIMPLEX_EXTREMA_STRONG = prove + (`!p n s. + ksimplex p n s /\ ~(n = 0) + ==> ?a b. a IN s /\ b IN s /\ ~(a = b) /\ + (!x. x IN s ==> kle n a x /\ kle n x b) /\ + (!i. b(i) = if 1 <= i /\ i <= n then a(i) + 1 else a(i))`, + REPEAT STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o MATCH_MP KSIMPLEX_EXTREMA) THEN + REPEAT(MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC) THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN DISCH_THEN SUBST_ALL_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `1`) THEN + ASM_REWRITE_TAC[LE_REFL; ARITH_RULE `1 <= n <=> ~(n = 0)`] THEN ARITH_TAC);; + +let KSIMPLEX_SUCCESSOR = prove + (`!a p n s. + ksimplex p n s /\ a IN s + ==> (!x. x IN s ==> kle n x a) \/ + (?y. y IN s /\ ?k. 1 <= k /\ k <= n /\ + !j. y(j) = if j = k then a(j) + 1 else a(j))`, + REWRITE_TAC[ksimplex] THEN REPEAT STRIP_TAC THEN + REWRITE_TAC[TAUT `a \/ b <=> ~a ==> b`] THEN + REWRITE_TAC[NOT_FORALL_THM; NOT_IMP] THEN DISCH_TAC THEN + MP_TAC(SPECL [`{x | x IN s /\ ~kle n x a}`; `n:num`] KLE_MINIMAL) THEN + RULE_ASSUM_TAC(REWRITE_RULE[HAS_SIZE]) THEN + ASM_SIMP_TAC[FINITE_RESTRICT] THEN + ASM_SIMP_TAC[GSYM MEMBER_NOT_EMPTY; IN_ELIM_THM] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `b:num->num` THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + SUBGOAL_THEN `1 <= CARD {k | k IN 1..n /\ a(k):num < b(k)}` MP_TAC THENL + [MATCH_MP_TAC KLE_STRICT_SET THEN ASM_MESON_TAC[]; ALL_TAC] THEN + DISCH_THEN(DISJ_CASES_THEN MP_TAC o MATCH_MP (ARITH_RULE + `1 <= n ==> (n = 1) \/ 2 <= n`)) + THENL + [DISCH_TAC THEN + MP_TAC(HAS_SIZE_CONV `{k | k IN 1 .. n /\ a k :num < b k} HAS_SIZE 1`) THEN + ASM_SIMP_TAC[HAS_SIZE; FINITE_RESTRICT; FINITE_NUMSEG] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `k:num` THEN + REWRITE_TAC[EXTENSION; IN_ELIM_THM; IN_SING; IN_NUMSEG] THEN + DISCH_THEN(fun th -> CONJ_TAC THENL [MESON_TAC[th]; MP_TAC th]) THEN + DISCH_THEN(fun th -> CONJ_TAC THENL [MESON_TAC[th]; MP_TAC th]) THEN + MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `i:num` THEN + SUBGOAL_THEN `kle n a b` MP_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN + DISCH_THEN(STRIP_ASSUME_TAC o GEN_REWRITE_RULE I [kle]) THEN + ASM_REWRITE_TAC[EXTENSION; IN_ELIM_THM; IN_NUMSEG] THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[ADD_CLAUSES; LT_REFL] THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[ADD_CLAUSES; LT_REFL] THEN + ASM_MESON_TAC[SUBSET; IN_NUMSEG; ARITH_RULE `~(a + 1 = a)`; + ARITH_RULE `a < a + 1`]; + ALL_TAC] THEN + DISCH_TAC THEN + MP_TAC(SPECL [`n:num`; `PRE(CARD {x | x IN s /\ ~(kle n x a)})`; + `{x | x IN s /\ ~(kle n x a)}`] KLE_RANGE_INDUCT) THEN + ASM_SIMP_TAC[HAS_SIZE; FINITE_RESTRICT; CARD_EQ_0; GSYM MEMBER_NOT_EMPTY; + ARITH_RULE `(n = SUC(PRE n)) <=> ~(n = 0)`] THEN + REPEAT(ANTS_TAC THENL + [REWRITE_TAC[IN_ELIM_THM] THEN ASM_MESON_TAC[]; ALL_TAC]) THEN + DISCH_THEN(X_CHOOSE_THEN `c:num->num` + (X_CHOOSE_THEN `d:num->num` MP_TAC)) THEN + REPEAT(DISCH_THEN(CONJUNCTS_THEN2 + (STRIP_ASSUME_TAC o REWRITE_RULE[IN_ELIM_THM]) MP_TAC)) THEN + DISCH_TAC THEN + MP_TAC(SPECL [`n:num`; `PRE(CARD {x | x IN s /\ kle n x a})`; + `{x | x IN s /\ kle n x a}`] KLE_RANGE_INDUCT) THEN + ASM_SIMP_TAC[HAS_SIZE; FINITE_RESTRICT; CARD_EQ_0; GSYM MEMBER_NOT_EMPTY; + ARITH_RULE `(n = SUC(PRE n)) <=> ~(n = 0)`] THEN + REPEAT(ANTS_TAC THENL + [REWRITE_TAC[IN_ELIM_THM] THEN ASM_MESON_TAC[KLE_REFL]; ALL_TAC]) THEN + DISCH_THEN(X_CHOOSE_THEN `e:num->num` + (X_CHOOSE_THEN `f:num->num` MP_TAC)) THEN + REPEAT(DISCH_THEN(CONJUNCTS_THEN2 + (STRIP_ASSUME_TAC o REWRITE_RULE[IN_ELIM_THM]) MP_TAC)) THEN + DISCH_TAC THEN + SUBGOAL_THEN `kle n e d /\ n + 1 <= CARD {k | k IN 1..n /\ e(k) < d(k)}` + MP_TAC THENL + [ALL_TAC; + ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN DISCH_THEN(K ALL_TAC) THEN + DISCH_THEN(MP_TAC o CONJUNCT2) THEN + REWRITE_TAC[ARITH_RULE `~(n + 1 <= x) <=> x <= n`] THEN + MATCH_MP_TAC LE_TRANS THEN EXISTS_TAC `CARD(1..n)` THEN + SIMP_TAC[CARD_SUBSET; SUBSET_RESTRICT; FINITE_RESTRICT; FINITE_NUMSEG] THEN + REWRITE_TAC[CARD_NUMSEG; ADD_SUB; LE_REFL]] THEN + SUBGOAL_THEN + `(CARD {x | x IN s /\ kle n x a} - 1) + + 2 + (CARD {x | x IN s /\ ~kle n x a} - 1) = n + 1` + (SUBST1_TAC o SYM) + THENL + [MATCH_MP_TAC(ARITH_RULE + `~(a = 0) /\ ~(b = 0) /\ (a + b = n + 1) + ==> ((a - 1) + 2 + (b - 1) = n + 1)`) THEN + ASM_SIMP_TAC[CARD_EQ_0; FINITE_RESTRICT; GSYM MEMBER_NOT_EMPTY] THEN + REPEAT (CONJ_TAC THENL + [REWRITE_TAC[IN_ELIM_THM] THEN ASM_MESON_TAC[]; ALL_TAC]) THEN + FIRST_ASSUM(SUBST1_TAC o SYM o CONJUNCT2) THEN + MATCH_MP_TAC CARD_UNION_EQ THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[EXTENSION; NOT_IN_EMPTY; IN_INTER; IN_UNION; IN_ELIM_THM] THEN + ASM_MESON_TAC[]; + ALL_TAC] THEN + MATCH_MP_TAC KLE_RANGE_COMBINE THEN EXISTS_TAC `a:num->num` THEN + CONJ_TAC THENL [ASM_MESON_TAC[KLE_TRANS]; ALL_TAC] THEN + CONJ_TAC THENL [ASM_MESON_TAC[KLE_TRANS]; ALL_TAC] THEN + CONJ_TAC THENL [ASM_MESON_TAC[KLE_TRANS]; ALL_TAC] THEN CONJ_TAC THENL + [W(fun(asl,w) -> SUBGOAL_THEN(mk_conj(`kle n e a`,w)) + (fun th -> REWRITE_TAC[th])) THEN + MATCH_MP_TAC KLE_RANGE_COMBINE_R THEN EXISTS_TAC `f:num->num` THEN + ASM_REWRITE_TAC[ARITH_RULE `k - 1 = PRE k`]; + ALL_TAC] THEN + W(fun(asl,w) -> SUBGOAL_THEN(mk_conj(`kle n a d`,w)) + (fun th -> REWRITE_TAC[th])) THEN + MATCH_MP_TAC KLE_RANGE_COMBINE THEN EXISTS_TAC `b:num->num` THEN + ASM_REWRITE_TAC[ARITH_RULE `k - 1 = PRE k`] THEN + CONJ_TAC THENL [ASM_MESON_TAC[KLE_TRANS]; ALL_TAC] THEN + CONJ_TAC THENL [ASM_MESON_TAC[KLE_TRANS]; ALL_TAC] THEN + CONJ_TAC THENL [ASM_MESON_TAC[KLE_TRANS]; ALL_TAC] THEN + W(fun(asl,w) -> SUBGOAL_THEN(mk_conj(`kle n b d`,w)) + (fun th -> REWRITE_TAC[th])) THEN + MATCH_MP_TAC KLE_RANGE_COMBINE_L THEN EXISTS_TAC `c:num->num` THEN + ASM_REWRITE_TAC[ARITH_RULE `k - 1 = PRE k`] THEN ASM_MESON_TAC[KLE_TRANS]);; + +let KSIMPLEX_PREDECESSOR = prove + (`!a p n s. + ksimplex p n s /\ a IN s + ==> (!x. x IN s ==> kle n a x) \/ + (?y. y IN s /\ ?k. 1 <= k /\ k <= n /\ + !j. a(j) = if j = k then y(j) + 1 else y(j))`, + REWRITE_TAC[ksimplex] THEN REPEAT STRIP_TAC THEN + REWRITE_TAC[TAUT `a \/ b <=> ~a ==> b`] THEN + REWRITE_TAC[NOT_FORALL_THM; NOT_IMP] THEN DISCH_TAC THEN + MP_TAC(SPECL [`{x | x IN s /\ ~kle n a x}`; `n:num`] KLE_MAXIMAL) THEN + RULE_ASSUM_TAC(REWRITE_RULE[HAS_SIZE]) THEN + ASM_SIMP_TAC[FINITE_RESTRICT] THEN + ASM_SIMP_TAC[GSYM MEMBER_NOT_EMPTY; IN_ELIM_THM] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `b:num->num` THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + SUBGOAL_THEN `1 <= CARD {k | k IN 1..n /\ b(k):num < a(k)}` MP_TAC THENL + [MATCH_MP_TAC KLE_STRICT_SET THEN ASM_MESON_TAC[]; ALL_TAC] THEN + DISCH_THEN(DISJ_CASES_THEN MP_TAC o MATCH_MP (ARITH_RULE + `1 <= n ==> (n = 1) \/ 2 <= n`)) + THENL + [DISCH_TAC THEN + MP_TAC(HAS_SIZE_CONV `{k | k IN 1 .. n /\ b k :num < a k} HAS_SIZE 1`) THEN + ASM_SIMP_TAC[HAS_SIZE; FINITE_RESTRICT; FINITE_NUMSEG] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `k:num` THEN + REWRITE_TAC[EXTENSION; IN_ELIM_THM; IN_SING; IN_NUMSEG] THEN + DISCH_THEN(fun th -> CONJ_TAC THENL [MESON_TAC[th]; MP_TAC th]) THEN + DISCH_THEN(fun th -> CONJ_TAC THENL [MESON_TAC[th]; MP_TAC th]) THEN + MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `i:num` THEN + SUBGOAL_THEN `kle n b a` MP_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN + DISCH_THEN(STRIP_ASSUME_TAC o GEN_REWRITE_RULE I [kle]) THEN + ASM_REWRITE_TAC[EXTENSION; IN_ELIM_THM; IN_NUMSEG] THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[ADD_CLAUSES; LT_REFL] THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[ADD_CLAUSES; LT_REFL] THEN + ASM_MESON_TAC[SUBSET; IN_NUMSEG; ARITH_RULE `~(a + 1 = a)`; + ARITH_RULE `a < a + 1`]; + ALL_TAC] THEN + DISCH_TAC THEN + MP_TAC(SPECL [`n:num`; `PRE(CARD {x | x IN s /\ ~(kle n a x)})`; + `{x | x IN s /\ ~(kle n a x)}`] KLE_RANGE_INDUCT) THEN + ASM_SIMP_TAC[HAS_SIZE; FINITE_RESTRICT; CARD_EQ_0; GSYM MEMBER_NOT_EMPTY; + ARITH_RULE `(n = SUC(PRE n)) <=> ~(n = 0)`] THEN + REPEAT(ANTS_TAC THENL + [REWRITE_TAC[IN_ELIM_THM] THEN ASM_MESON_TAC[]; ALL_TAC]) THEN + DISCH_THEN(X_CHOOSE_THEN `d:num->num` + (X_CHOOSE_THEN `c:num->num` MP_TAC)) THEN + REPEAT(DISCH_THEN(CONJUNCTS_THEN2 + (STRIP_ASSUME_TAC o REWRITE_RULE[IN_ELIM_THM]) MP_TAC)) THEN + DISCH_TAC THEN + MP_TAC(SPECL [`n:num`; `PRE(CARD {x | x IN s /\ kle n a x})`; + `{x | x IN s /\ kle n a x}`] KLE_RANGE_INDUCT) THEN + ASM_SIMP_TAC[HAS_SIZE; FINITE_RESTRICT; CARD_EQ_0; GSYM MEMBER_NOT_EMPTY; + ARITH_RULE `(n = SUC(PRE n)) <=> ~(n = 0)`] THEN + REPEAT(ANTS_TAC THENL + [REWRITE_TAC[IN_ELIM_THM] THEN ASM_MESON_TAC[KLE_REFL]; ALL_TAC]) THEN + DISCH_THEN(X_CHOOSE_THEN `f:num->num` + (X_CHOOSE_THEN `e:num->num` MP_TAC)) THEN + REPEAT(DISCH_THEN(CONJUNCTS_THEN2 + (STRIP_ASSUME_TAC o REWRITE_RULE[IN_ELIM_THM]) MP_TAC)) THEN + DISCH_TAC THEN + SUBGOAL_THEN `kle n d e /\ n + 1 <= CARD {k | k IN 1..n /\ d(k) < e(k)}` + MP_TAC THENL + [ALL_TAC; + ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN DISCH_THEN(K ALL_TAC) THEN + DISCH_THEN(MP_TAC o CONJUNCT2) THEN + REWRITE_TAC[ARITH_RULE `~(n + 1 <= x) <=> x <= n`] THEN + MATCH_MP_TAC LE_TRANS THEN EXISTS_TAC `CARD(1..n)` THEN + SIMP_TAC[CARD_SUBSET; SUBSET_RESTRICT; FINITE_RESTRICT; FINITE_NUMSEG] THEN + REWRITE_TAC[CARD_NUMSEG; ADD_SUB; LE_REFL]] THEN + SUBGOAL_THEN + `((CARD {x | x IN s /\ ~kle n a x} - 1) + 2) + + (CARD {x | x IN s /\ kle n a x} - 1) = n + 1` + (SUBST1_TAC o SYM) + THENL + [MATCH_MP_TAC(ARITH_RULE + `~(a = 0) /\ ~(b = 0) /\ (a + b = n + 1) + ==> (((b - 1) + 2) + (a - 1) = n + 1)`) THEN + ASM_SIMP_TAC[CARD_EQ_0; FINITE_RESTRICT; GSYM MEMBER_NOT_EMPTY] THEN + REPEAT (CONJ_TAC THENL + [REWRITE_TAC[IN_ELIM_THM] THEN ASM_MESON_TAC[]; ALL_TAC]) THEN + FIRST_ASSUM(SUBST1_TAC o SYM o CONJUNCT2) THEN + MATCH_MP_TAC CARD_UNION_EQ THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[EXTENSION; NOT_IN_EMPTY; IN_INTER; IN_UNION; IN_ELIM_THM] THEN + ASM_MESON_TAC[]; + ALL_TAC] THEN + MATCH_MP_TAC KLE_RANGE_COMBINE THEN EXISTS_TAC `a:num->num` THEN + CONJ_TAC THENL [ASM_MESON_TAC[KLE_TRANS]; ALL_TAC] THEN + CONJ_TAC THENL [ASM_MESON_TAC[KLE_TRANS]; ALL_TAC] THEN + CONJ_TAC THENL [ASM_MESON_TAC[KLE_TRANS]; ALL_TAC] THEN CONJ_TAC THENL + [ALL_TAC; + W(fun(asl,w) -> SUBGOAL_THEN(mk_conj(`kle n a e`,w)) + (fun th -> REWRITE_TAC[th])) THEN + MATCH_MP_TAC KLE_RANGE_COMBINE_L THEN EXISTS_TAC `f:num->num` THEN + ASM_REWRITE_TAC[ARITH_RULE `k - 1 = PRE k`]] THEN + W(fun(asl,w) -> SUBGOAL_THEN(mk_conj(`kle n d a`,w)) + (fun th -> REWRITE_TAC[th])) THEN + MATCH_MP_TAC KLE_RANGE_COMBINE THEN EXISTS_TAC `b:num->num` THEN + ASM_REWRITE_TAC[ARITH_RULE `k - 1 = PRE k`] THEN + CONJ_TAC THENL [ASM_MESON_TAC[KLE_TRANS]; ALL_TAC] THEN + CONJ_TAC THENL [ASM_MESON_TAC[KLE_TRANS]; ALL_TAC] THEN + CONJ_TAC THENL [ASM_MESON_TAC[KLE_TRANS]; ALL_TAC] THEN + W(fun(asl,w) -> SUBGOAL_THEN(mk_conj(`kle n d b`,w)) + (fun th -> REWRITE_TAC[th])) THEN + MATCH_MP_TAC KLE_RANGE_COMBINE_R THEN EXISTS_TAC `c:num->num` THEN + ASM_REWRITE_TAC[ARITH_RULE `k - 1 = PRE k`] THEN ASM_MESON_TAC[KLE_TRANS]);; + +(* ------------------------------------------------------------------------- *) +(* The lemmas about simplices that we need. *) +(* ------------------------------------------------------------------------- *) + +let FINITE_SIMPLICES = prove + (`!p n. FINITE {s | ksimplex p n s}`, + REPEAT STRIP_TAC THEN + MATCH_MP_TAC FINITE_SUBSET THEN + EXISTS_TAC `{s | s SUBSET {f | (!i. i IN 1..n ==> f(i) IN 0..p) /\ + (!i. ~(i IN 1..n) ==> (f(i) = p))}}` THEN + ASM_SIMP_TAC[FINITE_POWERSET; FINITE_FUNSPACE; FINITE_NUMSEG] THEN + REWRITE_TAC[SUBSET; IN_ELIM_THM; ksimplex] THEN + ASM_SIMP_TAC[IN_NUMSEG; LE_0]);; + +let SIMPLEX_TOP_FACE = prove + (`0 < p /\ + (!x. x IN f ==> (x(n + 1) = p)) + ==> ((?s a. ksimplex p (n + 1) s /\ a IN s /\ (f = s DELETE a)) <=> + ksimplex p n f)`, + REPEAT STRIP_TAC THEN EQ_TAC THENL + [REWRITE_TAC[ksimplex; LEFT_IMP_EXISTS_THM] THEN + REPEAT GEN_TAC THEN STRIP_TAC THEN ASM_REWRITE_TAC[IN_DELETE] THEN + REPEAT CONJ_TAC THENL + [UNDISCH_TAC `(s:(num->num)->bool) HAS_SIZE ((n + 1) + 1)` THEN + SIMP_TAC[HAS_SIZE; CARD_DELETE; FINITE_DELETE] THEN + ASM_REWRITE_TAC[] THEN STRIP_TAC THEN ARITH_TAC; + REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[]; + GEN_TAC THEN X_GEN_TAC `j:num` THEN + ONCE_REWRITE_TAC[ARITH_RULE + `(1 <= j /\ j <= n) <=> (1 <= j /\ j <= n + 1) /\ ~(j = (n + 1))`] THEN + ASM_MESON_TAC[IN_DELETE]; + REPEAT STRIP_TAC THEN + SUBGOAL_THEN `kle (n + 1) x y \/ kle (n + 1) y x` MP_TAC THENL + [ASM_MESON_TAC[]; ALL_TAC] THEN + MATCH_MP_TAC MONO_OR THEN CONJ_TAC THEN + (REWRITE_TAC[kle] THEN + MATCH_MP_TAC MONO_EXISTS THEN + REWRITE_TAC[GSYM ADD1; NUMSEG_CLAUSES; ARITH_RULE `1 <= SUC n`] THEN + X_GEN_TAC `k:num->bool` THEN SIMP_TAC[] THEN + REWRITE_TAC[SUBSET; IN_INSERT] THEN + ASM_CASES_TAC `(SUC n) IN k` THENL + [ALL_TAC; ASM_MESON_TAC[]] THEN + DISCH_THEN(MP_TAC o SPEC `n + 1` o CONJUNCT2) THEN + ASM_REWRITE_TAC[GSYM ADD1] THEN + ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN DISCH_THEN(K ALL_TAC) THEN + MATCH_MP_TAC(ARITH_RULE `(x = p) /\ (y = p) ==> ~(x = SUC y)`) THEN + CONJ_TAC THEN ASM_MESON_TAC[ADD1; IN_DELETE])]; + ALL_TAC] THEN + DISCH_TAC THEN FIRST_ASSUM(MP_TAC o MATCH_MP KSIMPLEX_EXTREMA) THEN + DISCH_THEN(X_CHOOSE_THEN `a:num->num` (X_CHOOSE_THEN `b:num->num` + STRIP_ASSUME_TAC)) THEN + ABBREV_TAC `c = \i. if i = (n + 1) then p - 1 else a(i)` THEN + MAP_EVERY EXISTS_TAC [`(c:num->num) INSERT f`; `c:num->num`] THEN + REWRITE_TAC[IN_INSERT; DELETE_INSERT] THEN + SUBGOAL_THEN `~((c:num->num) IN f)` ASSUME_TAC THENL + [DISCH_TAC THEN UNDISCH_TAC `!x:num->num. x IN f ==> (x (n + 1) = p)` THEN + DISCH_THEN(MP_TAC o SPEC `c:num->num`) THEN ASM_REWRITE_TAC[] THEN + EXPAND_TAC "c" THEN REWRITE_TAC[] THEN UNDISCH_TAC `0 < p` THEN ARITH_TAC; + ALL_TAC] THEN + CONJ_TAC THENL + [ALL_TAC; UNDISCH_TAC `~((c:num->num) IN f)` THEN SET_TAC[]] THEN + UNDISCH_TAC `ksimplex p n f` THEN REWRITE_TAC[ksimplex] THEN + REPEAT(MATCH_MP_TAC MONO_AND THEN CONJ_TAC) THENL + [SIMP_TAC[HAS_SIZE; FINITE_RULES; CARD_CLAUSES] THEN ASM_REWRITE_TAC[ADD1]; + EXPAND_TAC "c" THEN REWRITE_TAC[IN_INSERT] THEN + SIMP_TAC[TAUT `(a \/ b ==> c) <=> (a ==> c) /\ (b ==> c)`] THEN + ASM_MESON_TAC[ARITH_RULE `p - 1 <= p`]; + EXPAND_TAC "c" THEN REWRITE_TAC[IN_INSERT; TAUT + `(a \/ b) /\ c ==> d <=> (a /\ c ==> d) /\ (b /\ c ==> d)`] THEN + DISCH_TAC THEN REPEAT GEN_TAC THEN CONJ_TAC THENL + [DISCH_THEN(CONJUNCTS_THEN2 SUBST1_TAC MP_TAC); ALL_TAC] THEN + ASM_MESON_TAC[LE_REFL; ARITH_RULE `1 <= n + 1`; + ARITH_RULE `j <= n ==> j <= n + 1`]; + ALL_TAC] THEN + DISCH_TAC THEN REWRITE_TAC[IN_INSERT] THEN + SUBGOAL_THEN `!x. x IN f ==> kle (n + 1) c x` + (fun th -> ASM_MESON_TAC[th; KLE_SUC; KLE_REFL]) THEN + X_GEN_TAC `x:num->num` THEN DISCH_TAC THEN + SUBGOAL_THEN `kle (n + 1) a x` MP_TAC THENL + [ASM_MESON_TAC[KLE_SUC]; ALL_TAC] THEN + EXPAND_TAC "c" THEN REWRITE_TAC[kle] THEN + DISCH_THEN(X_CHOOSE_THEN `k:num->bool` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `(n + 1) INSERT k` THEN + ASM_REWRITE_TAC[INSERT_SUBSET; IN_NUMSEG] THEN + ASM_REWRITE_TAC[LE_REFL; ARITH_RULE `1 <= n + 1`] THEN + X_GEN_TAC `j:num` THEN REWRITE_TAC[IN_INSERT] THEN + ASM_CASES_TAC `j = n + 1` THEN ASM_REWRITE_TAC[] THEN + SUBGOAL_THEN `~(n + 1 IN k)` + (fun th -> ASM_MESON_TAC[th; ARITH_RULE `0 < p ==> (p = (p - 1) + 1)`]) THEN + DISCH_TAC THEN UNDISCH_TAC `!x:num->num. x IN f ==> (x (n + 1) = p)` THEN + DISCH_THEN(fun th -> MP_TAC(SPEC `x:num->num` th) THEN + MP_TAC(SPEC `a:num->num` th)) THEN + ASM_REWRITE_TAC[] THEN MESON_TAC[ARITH_RULE `~(p + 1 = p)`]);; + +let KSIMPLEX_FIX_PLANE = prove + (`!p q n j s a a0 a1. + ksimplex p n s /\ a IN s /\ + 1 <= j /\ j <= n /\ (!x. x IN (s DELETE a) ==> (x j = q)) /\ + a0 IN s /\ a1 IN s /\ + (!i. a1 i = (if 1 <= i /\ i <= n then a0 i + 1 else a0 i)) + ==> (a = a0) \/ (a = a1)`, + REPEAT STRIP_TAC THEN + MATCH_MP_TAC(TAUT `(~a /\ ~b ==> F) ==> a \/ b`) THEN STRIP_TAC THEN + UNDISCH_TAC `!x:num->num. x IN s DELETE a ==> (x j = q)` THEN + DISCH_THEN(fun th -> + MP_TAC(SPEC `a0:num->num` th) THEN MP_TAC(SPEC `a1:num->num` th)) THEN + ASM_REWRITE_TAC[IN_DELETE] THEN ARITH_TAC);; + +let KSIMPLEX_FIX_PLANE_0 = prove + (`!p n j s a a0 a1. + ksimplex p n s /\ a IN s /\ + 1 <= j /\ j <= n /\ (!x. x IN (s DELETE a) ==> (x j = 0)) /\ + a0 IN s /\ a1 IN s /\ + (!i. a1 i = (if 1 <= i /\ i <= n then a0 i + 1 else a0 i)) + ==> (a = a1)`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN `(a = a0) \/ (a = a1:num->num)` MP_TAC THENL + [MATCH_MP_TAC KSIMPLEX_FIX_PLANE THEN + MAP_EVERY EXISTS_TAC + [`p:num`; `0`; `n:num`; `j:num`; `s:(num->num)->bool`] THEN + ASM_REWRITE_TAC[]; + ALL_TAC] THEN + ASM_CASES_TAC `a0:num->num = a1` THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC(TAUT `~a ==> (a \/ b ==> b)`) THEN + DISCH_THEN SUBST_ALL_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `a1:num->num`) THEN + ASM_REWRITE_TAC[IN_DELETE] THEN ARITH_TAC);; + +let KSIMPLEX_FIX_PLANE_P = prove + (`!p n j s a a0 a1. + ksimplex p n s /\ a IN s /\ + 1 <= j /\ j <= n /\ (!x. x IN (s DELETE a) ==> (x j = p)) /\ + a0 IN s /\ a1 IN s /\ + (!i. a1 i = (if 1 <= i /\ i <= n then a0 i + 1 else a0 i)) + ==> (a = a0)`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN `(a = a0) \/ (a = a1:num->num)` MP_TAC THENL + [MATCH_MP_TAC KSIMPLEX_FIX_PLANE THEN + MAP_EVERY EXISTS_TAC + [`p:num`; `p:num`; `n:num`; `j:num`; `s:(num->num)->bool`] THEN + ASM_REWRITE_TAC[]; + ALL_TAC] THEN + ASM_CASES_TAC `a0:num->num = a1` THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC(TAUT `~b ==> (a \/ b ==> a)`) THEN + DISCH_THEN SUBST_ALL_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `a0:num->num`) THEN + ASM_REWRITE_TAC[IN_DELETE] THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [ksimplex]) THEN + DISCH_THEN(MP_TAC o SPEC `a1:num->num` o CONJUNCT1 o CONJUNCT2) THEN + DISCH_THEN(MP_TAC o SPEC `j:num`) THEN ASM_REWRITE_TAC[] THEN ARITH_TAC);; + +let KSIMPLEX_REPLACE_0 = prove + (`ksimplex p n s /\ a IN s /\ ~(n = 0) /\ + (?j. 1 <= j /\ j <= n /\ !x. x IN (s DELETE a) ==> (x j = 0)) + ==> (CARD + {s' | ksimplex p n s' /\ ?b. b IN s' /\ (s' DELETE b = s DELETE a)} = + 1)`, + let lemma = prove + (`!a a'. (s' DELETE a' = s DELETE a) /\ (a' = a) /\ a' IN s' /\ a IN s + ==> (s' = s)`, + SET_TAC[]) in + REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_SIZE_CARD THEN + REWRITE_TAC[HAS_SIZE_1_EXISTS] THEN REWRITE_TAC[IN_ELIM_THM] THEN + SUBGOAL_THEN + `!s' a'. ksimplex p n s' /\ a' IN s' /\ (s' DELETE a' = s DELETE a) + ==> (s' = s)` + (fun th -> ASM_MESON_TAC[th]) THEN + REPEAT STRIP_TAC THEN + MP_TAC(SPECL [`p:num`; `n:num`; `s:(num->num)->bool`] + KSIMPLEX_EXTREMA_STRONG) THEN + ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `a0:num->num` (X_CHOOSE_THEN `a1:num->num` + STRIP_ASSUME_TAC)) THEN + MP_TAC(SPECL [`p:num`; `n:num`; `s':(num->num)->bool`] + KSIMPLEX_EXTREMA_STRONG) THEN + ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `b0:num->num` (X_CHOOSE_THEN `b1:num->num` + STRIP_ASSUME_TAC)) THEN + SUBGOAL_THEN `a:num->num = a1` SUBST_ALL_TAC THENL + [MATCH_MP_TAC KSIMPLEX_FIX_PLANE_0 THEN MAP_EVERY EXISTS_TAC + [`p:num`; `n:num`; `j:num`; `s:(num->num)->bool`; `a0:num->num`] THEN + ASM_REWRITE_TAC[]; + ALL_TAC] THEN + SUBGOAL_THEN `a':num->num = b1` SUBST_ALL_TAC THENL + [MATCH_MP_TAC KSIMPLEX_FIX_PLANE_0 THEN MAP_EVERY EXISTS_TAC + [`p:num`; `n:num`; `j:num`; `s':(num->num)->bool`; `b0:num->num`] THEN + ASM_REWRITE_TAC[]; + ALL_TAC] THEN + MATCH_MP_TAC lemma THEN + MAP_EVERY EXISTS_TAC [`a1:num->num`; `b1:num->num`] THEN + ASM_REWRITE_TAC[] THEN + SUBGOAL_THEN `b0:num->num = a0` MP_TAC THENL + [ONCE_REWRITE_TAC[GSYM KLE_ANTISYM] THEN ASM_MESON_TAC[IN_DELETE]; + ASM_REWRITE_TAC[FUN_EQ_THM] THEN MESON_TAC[]]);; + +let KSIMPLEX_REPLACE_1 = prove + (`ksimplex p n s /\ a IN s /\ ~(n = 0) /\ + (?j. 1 <= j /\ j <= n /\ !x. x IN (s DELETE a) ==> (x j = p)) + ==> (CARD + {s' | ksimplex p n s' /\ ?b. b IN s' /\ (s' DELETE b = s DELETE a)} = + 1)`, + let lemma = prove + (`!a a'. (s' DELETE a' = s DELETE a) /\ (a' = a) /\ a' IN s' /\ a IN s + ==> (s' = s)`, + SET_TAC[]) in + REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_SIZE_CARD THEN + REWRITE_TAC[HAS_SIZE_1_EXISTS] THEN REWRITE_TAC[IN_ELIM_THM] THEN + SUBGOAL_THEN + `!s' a'. ksimplex p n s' /\ a' IN s' /\ (s' DELETE a' = s DELETE a) + ==> (s' = s)` + (fun th -> ASM_MESON_TAC[th]) THEN + REPEAT STRIP_TAC THEN + MP_TAC(SPECL [`p:num`; `n:num`; `s:(num->num)->bool`] + KSIMPLEX_EXTREMA_STRONG) THEN + ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `a0:num->num` (X_CHOOSE_THEN `a1:num->num` + STRIP_ASSUME_TAC)) THEN + MP_TAC(SPECL [`p:num`; `n:num`; `s':(num->num)->bool`] + KSIMPLEX_EXTREMA_STRONG) THEN + ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `b0:num->num` (X_CHOOSE_THEN `b1:num->num` + STRIP_ASSUME_TAC)) THEN + SUBGOAL_THEN `a:num->num = a0` SUBST_ALL_TAC THENL + [MATCH_MP_TAC KSIMPLEX_FIX_PLANE_P THEN MAP_EVERY EXISTS_TAC + [`p:num`; `n:num`; `j:num`; `s:(num->num)->bool`; `a1:num->num`] THEN + ASM_REWRITE_TAC[]; + ALL_TAC] THEN + SUBGOAL_THEN `a':num->num = b0` SUBST_ALL_TAC THENL + [MATCH_MP_TAC KSIMPLEX_FIX_PLANE_P THEN MAP_EVERY EXISTS_TAC + [`p:num`; `n:num`; `j:num`; `s':(num->num)->bool`; `b1:num->num`] THEN + ASM_REWRITE_TAC[]; + ALL_TAC] THEN + MATCH_MP_TAC lemma THEN + MAP_EVERY EXISTS_TAC [`a0:num->num`; `b0:num->num`] THEN + ASM_REWRITE_TAC[] THEN + SUBGOAL_THEN `b1:num->num = a1` MP_TAC THENL + [ONCE_REWRITE_TAC[GSYM KLE_ANTISYM] THEN ASM_MESON_TAC[IN_DELETE]; + ASM_REWRITE_TAC[FUN_EQ_THM] THEN MATCH_MP_TAC MONO_FORALL THEN + MESON_TAC[EQ_ADD_RCANCEL]]);; + +let KSIMPLEX_REPLACE_2 = prove + (`ksimplex p n s /\ a IN s /\ ~(n = 0) /\ + ~(?j. 1 <= j /\ j <= n /\ !x. x IN (s DELETE a) ==> (x j = 0)) /\ + ~(?j. 1 <= j /\ j <= n /\ !x. x IN (s DELETE a) ==> (x j = p)) + ==> (CARD + {s' | ksimplex p n s' /\ ?b. b IN s' /\ (s' DELETE b = s DELETE a)} = + 2)`, + let lemma = prove + (`!a a'. (s' DELETE a' = s DELETE a) /\ (a' = a) /\ a' IN s' /\ a IN s + ==> (s' = s)`, + SET_TAC[]) + and lemma_1 = prove + (`a IN s /\ ~(b = a) ==> ~(s = b INSERT (s DELETE a))`, + SET_TAC[]) in + REPEAT STRIP_TAC THEN + MP_TAC(SPECL [`p:num`; `n:num`; `s:(num->num)->bool`] + KSIMPLEX_EXTREMA_STRONG) THEN + ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `a0:num->num` (X_CHOOSE_THEN `a1:num->num` + STRIP_ASSUME_TAC)) THEN + ASM_CASES_TAC `a:num->num = a0` THENL + [FIRST_X_ASSUM SUBST_ALL_TAC THEN + MP_TAC(SPECL [`a0:num->num`; `p:num`; `n:num`; `s:(num->num)->bool`] + KSIMPLEX_SUCCESSOR) THEN + ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC(TAUT `~a /\ (b ==> c) ==> a \/ b ==> c`) THEN CONJ_TAC THENL + [DISCH_THEN(MP_TAC o SPEC `a1:num->num`) THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(MP_TAC o SPEC `1` o MATCH_MP KLE_IMP_POINTWISE) THEN + ASM_REWRITE_TAC[ARITH_RULE `1 <= n <=> ~(n = 0)`; ARITH] THEN ARITH_TAC; + ALL_TAC] THEN + DISCH_THEN(X_CHOOSE_THEN `a2:num->num` + (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + DISCH_THEN(X_CHOOSE_THEN `k:num` STRIP_ASSUME_TAC) THEN + ABBREV_TAC `a3 = \j:num. if j = k then a1 j + 1 else a1 j` THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [FUN_EQ_THM]) THEN + REWRITE_TAC[] THEN DISCH_THEN(STRIP_ASSUME_TAC o GSYM) THEN + MATCH_MP_TAC HAS_SIZE_CARD THEN CONV_TAC HAS_SIZE_CONV THEN + MAP_EVERY EXISTS_TAC + [`s:(num->num)->bool`; `a3 INSERT (s DELETE (a0:num->num))`] THEN + SUBGOAL_THEN `~((a3:num->num) IN s)` ASSUME_TAC THENL + [DISCH_TAC THEN SUBGOAL_THEN `kle n a3 a1` MP_TAC THENL + [ASM_MESON_TAC[]; ALL_TAC] THEN + DISCH_THEN(MP_TAC o SPEC `k:num` o MATCH_MP KLE_IMP_POINTWISE) THEN + ASM_REWRITE_TAC[LE_REFL] THEN ARITH_TAC; + ALL_TAC] THEN + SUBGOAL_THEN `~(a3:num->num = a0) /\ ~(a3 = a1)` STRIP_ASSUME_TAC THENL + [ASM_MESON_TAC[]; ALL_TAC] THEN + SUBGOAL_THEN `~(a2:num->num = a0)` ASSUME_TAC THENL + [ASM_REWRITE_TAC[FUN_EQ_THM] THEN MESON_TAC[ARITH_RULE `~(x + 1 = x)`]; + ALL_TAC] THEN + CONJ_TAC THENL [MATCH_MP_TAC lemma_1 THEN ASM_REWRITE_TAC[]; ALL_TAC] THEN + SUBGOAL_THEN `!x. x IN (s DELETE a0) ==> kle n a2 x` ASSUME_TAC THENL + [GEN_TAC THEN REWRITE_TAC[IN_DELETE] THEN STRIP_TAC THEN + SUBGOAL_THEN `kle n a2 x \/ kle n x a2` MP_TAC THENL + [ASM_MESON_TAC[ksimplex]; ALL_TAC] THEN + MATCH_MP_TAC(TAUT `(~b ==> ~a) ==> b \/ a ==> b`) THEN + DISCH_TAC THEN SUBGOAL_THEN `kle n a0 x` MP_TAC THENL + [ASM_MESON_TAC[]; ALL_TAC] THEN REPEAT STRIP_TAC THEN + SUBGOAL_THEN `(x:num->num = a0) \/ (x = a2)` + (fun th -> ASM_MESON_TAC[KLE_REFL; th]) THEN + MATCH_MP_TAC KLE_ADJACENT THEN + EXISTS_TAC `k:num` THEN ASM_REWRITE_TAC[]; + ALL_TAC] THEN + SUBGOAL_THEN `ksimplex p n (a3 INSERT (s DELETE a0))` ASSUME_TAC THENL + [MP_TAC(ASSUME `ksimplex p n s`) THEN REWRITE_TAC[ksimplex] THEN + MATCH_MP_TAC MONO_AND THEN CONJ_TAC THENL + [SIMP_TAC[HAS_SIZE; FINITE_INSERT; FINITE_DELETE; CARD_CLAUSES; + CARD_DELETE] THEN + ASM_REWRITE_TAC[IN_DELETE] THEN STRIP_TAC THEN ARITH_TAC; + ALL_TAC] THEN + MATCH_MP_TAC MONO_AND THEN CONJ_TAC THENL + [DISCH_TAC THEN REWRITE_TAC[IN_INSERT; IN_DELETE] THEN + SUBGOAL_THEN `!j. (a3:num->num) j <= p` + (fun th -> ASM_MESON_TAC[th]) THEN + X_GEN_TAC `j:num` THEN ONCE_ASM_REWRITE_TAC[] THEN COND_CASES_TAC THENL + [ALL_TAC; ASM_MESON_TAC[]] THEN + FIRST_X_ASSUM SUBST_ALL_TAC THEN + UNDISCH_TAC + `~(?j. 1 <= j /\ j <= n /\ + (!x. x IN s DELETE a0 ==> (x j = (p:num))))` THEN + REWRITE_TAC[NOT_EXISTS_THM] THEN DISCH_THEN(MP_TAC o SPEC `k:num`) THEN + REWRITE_TAC[ASSUME `1 <= k`; ASSUME `k:num <= n`; NOT_FORALL_THM] THEN + DISCH_THEN(X_CHOOSE_THEN `a4:num->num` MP_TAC) THEN + REWRITE_TAC[IN_DELETE; NOT_IMP] THEN STRIP_TAC THEN + UNDISCH_TAC `!x. x IN s DELETE a0 ==> kle n a2 x` THEN + DISCH_THEN(MP_TAC o SPEC `a4:num->num`) THEN + ASM_REWRITE_TAC[IN_DELETE] THEN + DISCH_THEN(MP_TAC o MATCH_MP KLE_IMP_POINTWISE) THEN + ASM_REWRITE_TAC[] THEN DISCH_THEN(MP_TAC o SPEC `k:num`) THEN + ASM_REWRITE_TAC[] THEN + UNDISCH_TAC `~((a4:num->num) k = p)` THEN + SUBGOAL_THEN `(a4:num->num) k <= p` MP_TAC THENL + [ASM_MESON_TAC[ksimplex]; ARITH_TAC]; + ALL_TAC] THEN + MATCH_MP_TAC MONO_AND THEN CONJ_TAC THENL + [REWRITE_TAC[IN_INSERT; IN_DELETE] THEN REPEAT STRIP_TAC THENL + [ALL_TAC; ASM_MESON_TAC[]] THEN + FIRST_X_ASSUM SUBST_ALL_TAC THEN + ONCE_ASM_REWRITE_TAC[] THEN ASM_MESON_TAC[]; + ALL_TAC] THEN + DISCH_TAC THEN REWRITE_TAC[IN_INSERT; IN_DELETE] THEN + SUBGOAL_THEN `!x. x IN s /\ ~(x = a0) ==> kle n x a3` + (fun th -> ASM_MESON_TAC[th; KLE_REFL]) THEN + X_GEN_TAC `x:num->num` THEN STRIP_TAC THEN + SUBGOAL_THEN `kle n a2 x /\ kle n x a1` MP_TAC THENL + [ASM_MESON_TAC[IN_DELETE]; ALL_TAC] THEN + REWRITE_TAC[IMP_CONJ] THEN + DISCH_THEN(MP_TAC o SPEC `k:num` o MATCH_MP KLE_IMP_POINTWISE) THEN + DISCH_TAC THEN REWRITE_TAC[kle] THEN + DISCH_THEN(X_CHOOSE_THEN `kk:num->bool` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `(k:num) INSERT kk` THEN + REWRITE_TAC[INSERT_SUBSET; IN_NUMSEG] THEN + CONJ_TAC THENL [ASM_REWRITE_TAC[]; ALL_TAC] THEN + X_GEN_TAC `j:num` THEN + FIRST_ASSUM(fun th -> GEN_REWRITE_TAC LAND_CONV [th]) THEN + REWRITE_TAC[IN_INSERT] THEN ASM_CASES_TAC `j:num = k` THENL + [ALL_TAC; ASM_MESON_TAC[]] THEN + FIRST_X_ASSUM SUBST_ALL_TAC THEN REWRITE_TAC[] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (ARITH_RULE + `a2 <= x ==> !a0. x <= a1 /\ (a1 = a0 + 1) /\ (a2 = a0 + 1) + ==> (a1 + 1 = x + 1)`)) THEN + EXISTS_TAC `(a0:num->num) k` THEN + ASM_MESON_TAC[KLE_IMP_POINTWISE]; + ALL_TAC] THEN + GEN_REWRITE_TAC I [EXTENSION] THEN + REWRITE_TAC[IN_ELIM_THM; IN_INSERT; NOT_IN_EMPTY] THEN + X_GEN_TAC `s':(num->num)->bool` THEN EQ_TAC THENL + [ALL_TAC; + DISCH_THEN(DISJ_CASES_THEN SUBST_ALL_TAC) THENL + [ASM_REWRITE_TAC[] THEN ASM_MESON_TAC[]; ALL_TAC] THEN + ASM_REWRITE_TAC[] THEN EXISTS_TAC `a3:num->num` THEN + REWRITE_TAC[IN_INSERT; DELETE_INSERT] THEN + UNDISCH_TAC `~((a3:num->num) IN s)` THEN SET_TAC[]] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + DISCH_THEN(X_CHOOSE_THEN `a':num->num` STRIP_ASSUME_TAC) THEN + MP_TAC(SPECL [`p:num`; `n:num`; `s':(num->num)->bool`] + KSIMPLEX_EXTREMA_STRONG) THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `a_min:num->num` (X_CHOOSE_THEN `a_max:num->num` + STRIP_ASSUME_TAC)) THEN + SUBGOAL_THEN `(a':num->num = a_min) \/ (a' = a_max)` MP_TAC THENL + [MATCH_MP_TAC KSIMPLEX_FIX_PLANE THEN MAP_EVERY EXISTS_TAC + [`p:num`; `(a2:num->num) k`; `n:num`; + `k:num`; `s':(num->num)->bool`] THEN + REPEAT CONJ_TAC THEN TRY(FIRST_ASSUM MATCH_ACCEPT_TAC) THEN + X_GEN_TAC `x:num->num` THEN ASM_REWRITE_TAC[] THEN DISCH_TAC THEN + SUBGOAL_THEN `kle n a2 x /\ kle n x a1` MP_TAC THENL + [ASM_MESON_TAC[IN_DELETE]; ALL_TAC] THEN + DISCH_THEN(CONJUNCTS_THEN (MP_TAC o SPEC `k:num` o MATCH_MP + KLE_IMP_POINTWISE)) THEN + ASM_REWRITE_TAC[] THEN ARITH_TAC; + ALL_TAC] THEN + DISCH_THEN(DISJ_CASES_THEN SUBST_ALL_TAC) THENL + [DISJ1_TAC THEN MATCH_MP_TAC lemma THEN + MAP_EVERY EXISTS_TAC [`a0:num->num`; `a_min:num->num`] THEN + ASM_REWRITE_TAC[] THEN + SUBGOAL_THEN `a_max:num->num = a1` MP_TAC THENL + [SUBGOAL_THEN `a1:num->num IN (s' DELETE a_min) /\ + a_max:num->num IN (s DELETE a0)` + MP_TAC THENL + [ASM_MESON_TAC[IN_DELETE]; ASM_MESON_TAC[KLE_ANTISYM; IN_DELETE]]; + ALL_TAC] THEN + ASM_REWRITE_TAC[FUN_EQ_THM] THEN MATCH_MP_TAC MONO_FORALL THEN + MESON_TAC[EQ_ADD_RCANCEL]; + DISJ2_TAC THEN MATCH_MP_TAC lemma THEN + MAP_EVERY EXISTS_TAC [`a3:num->num`; `a_max:num->num`] THEN + ASM_REWRITE_TAC[IN_INSERT] THEN CONJ_TAC THENL + [UNDISCH_TAC `~(a3:num->num IN s)` THEN SET_TAC[]; ALL_TAC] THEN + SUBGOAL_THEN `a_min:num->num = a2` MP_TAC THENL + [SUBGOAL_THEN `a2:num->num IN (s' DELETE a_max) /\ + a_min:num->num IN (s DELETE a0)` + MP_TAC THENL + [ASM_MESON_TAC[IN_DELETE]; ASM_MESON_TAC[KLE_ANTISYM; IN_DELETE]]; + ALL_TAC] THEN + ASM_REWRITE_TAC[FUN_EQ_THM] THEN MATCH_MP_TAC MONO_FORALL THEN + MESON_TAC[EQ_ADD_RCANCEL]]; + ALL_TAC] THEN + ASM_CASES_TAC `a:num->num = a1` THENL + [FIRST_X_ASSUM SUBST_ALL_TAC THEN + MP_TAC(SPECL [`a1:num->num`; `p:num`; `n:num`; `s:(num->num)->bool`] + KSIMPLEX_PREDECESSOR) THEN + ANTS_TAC THENL [ASM_REWRITE_TAC[]; ALL_TAC] THEN + MATCH_MP_TAC(TAUT `~a /\ (b ==> c) ==> a \/ b ==> c`) THEN CONJ_TAC THENL + [DISCH_THEN(MP_TAC o SPEC `a0:num->num`) THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(MP_TAC o SPEC `1` o MATCH_MP KLE_IMP_POINTWISE) THEN + ASM_REWRITE_TAC[ARITH_RULE `1 <= n <=> ~(n = 0)`; ARITH] THEN ARITH_TAC; + ALL_TAC] THEN + DISCH_THEN(X_CHOOSE_THEN `a2:num->num` + (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + DISCH_THEN(X_CHOOSE_THEN `k:num` STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN `!x. x IN (s DELETE a1) ==> kle n x a2` ASSUME_TAC THENL + [GEN_TAC THEN REWRITE_TAC[IN_DELETE] THEN STRIP_TAC THEN + SUBGOAL_THEN `kle n a2 x \/ kle n x a2` MP_TAC THENL + [ASM_MESON_TAC[ksimplex]; ALL_TAC] THEN + MATCH_MP_TAC(TAUT `(~b ==> ~a) ==> a \/ b ==> b`) THEN + DISCH_TAC THEN SUBGOAL_THEN `kle n x a1` MP_TAC THENL + [ASM_MESON_TAC[]; ALL_TAC] THEN REPEAT STRIP_TAC THEN + SUBGOAL_THEN `(x:num->num = a2) \/ (x = a1)` + (fun th -> ASM_MESON_TAC[KLE_REFL; th]) THEN + MATCH_MP_TAC KLE_ADJACENT THEN EXISTS_TAC `k:num` THEN + REPEAT CONJ_TAC THEN FIRST_X_ASSUM MATCH_ACCEPT_TAC; + ALL_TAC] THEN + SUBGOAL_THEN `~(a2:num->num = a1)` ASSUME_TAC THENL + [REWRITE_TAC[FUN_EQ_THM] THEN ASM_MESON_TAC[ARITH_RULE `~(x + 1 = x)`]; + ALL_TAC] THEN + ABBREV_TAC `a3 = \j:num. if j = k then a0 j - 1 else a0 j` THEN + SUBGOAL_THEN `!j:num. a0(j) = if j = k then a3(j) + 1 else a3 j` + ASSUME_TAC THENL + [X_GEN_TAC `j:num` THEN EXPAND_TAC "a3" THEN REWRITE_TAC[] THEN + COND_CASES_TAC THEN + REWRITE_TAC[ARITH_RULE `(a = a - 1 + 1) <=> ~(a = 0)`] THEN + FIRST_X_ASSUM SUBST_ALL_TAC THEN DISCH_TAC THEN + UNDISCH_TAC `!j:num. a1 j = (if j = k then a2 j + 1 else a2 j)` THEN + DISCH_THEN(MP_TAC o SPEC `k:num`) THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[ARITH_RULE `(0 + 1 = x + 1) <=> (x = 0)`] THEN DISCH_TAC THEN + UNDISCH_TAC + `~(?j. 1 <= j /\ j <= n /\ (!x. x IN s DELETE a1 ==> (x j = 0)))` THEN + REWRITE_TAC[NOT_EXISTS_THM] THEN EXISTS_TAC `k:num` THEN + ASM_MESON_TAC[KLE_IMP_POINTWISE; LE]; + ALL_TAC] THEN + SUBGOAL_THEN `~(kle n a0 a3)` ASSUME_TAC THENL + [ASM_MESON_TAC[KLE_IMP_POINTWISE; ARITH_RULE `~(a + 1 <= a)`]; + ALL_TAC] THEN + SUBGOAL_THEN `~(a3:num->num IN s)` ASSUME_TAC THENL + [ASM_MESON_TAC[]; ALL_TAC] THEN + SUBGOAL_THEN `kle n a3 a2` ASSUME_TAC THENL + [SUBGOAL_THEN `kle n a0 a1` MP_TAC THENL + [ASM_MESON_TAC[]; ALL_TAC] THEN + REWRITE_TAC[kle] THEN MATCH_MP_TAC MONO_EXISTS THEN + GEN_TAC THEN MATCH_MP_TAC MONO_AND THEN REWRITE_TAC[] THEN + MATCH_MP_TAC MONO_FORALL THEN GEN_TAC THEN + ONCE_REWRITE_TAC[ + ASSUME `!j:num. a0 j = (if j = k then a3 j + 1 else a3 j)`; + ASSUME `!j:num. a1 j = (if j = k then a2 j + 1 else a2 j)`] THEN + REPEAT(COND_CASES_TAC THEN REWRITE_TAC[]) THEN ARITH_TAC; + ALL_TAC] THEN + SUBGOAL_THEN `kle n a3 a0` ASSUME_TAC THENL + [REWRITE_TAC[kle] THEN EXISTS_TAC `{k:num}` THEN + ASM_REWRITE_TAC[SUBSET; IN_SING; IN_NUMSEG] THEN + ASM_MESON_TAC[ADD_CLAUSES]; + ALL_TAC] THEN + MATCH_MP_TAC HAS_SIZE_CARD THEN CONV_TAC HAS_SIZE_CONV THEN + MAP_EVERY EXISTS_TAC + [`s:(num->num)->bool`; `a3 INSERT (s DELETE (a1:num->num))`] THEN + SUBGOAL_THEN `~(a3:num->num = a1) /\ ~(a3 = a0)` STRIP_ASSUME_TAC THENL + [ASM_MESON_TAC[]; ALL_TAC] THEN + CONJ_TAC THENL [MATCH_MP_TAC lemma_1 THEN ASM_REWRITE_TAC[]; ALL_TAC] THEN + SUBGOAL_THEN `ksimplex p n (a3 INSERT (s DELETE a1))` ASSUME_TAC THENL + [MP_TAC(ASSUME `ksimplex p n s`) THEN REWRITE_TAC[ksimplex] THEN + MATCH_MP_TAC MONO_AND THEN CONJ_TAC THENL + [SIMP_TAC[HAS_SIZE; FINITE_INSERT; FINITE_DELETE; CARD_CLAUSES; + CARD_DELETE] THEN + ASM_REWRITE_TAC[IN_DELETE] THEN STRIP_TAC THEN ARITH_TAC; + ALL_TAC] THEN + MATCH_MP_TAC MONO_AND THEN CONJ_TAC THENL + [DISCH_TAC THEN REWRITE_TAC[IN_INSERT; IN_DELETE] THEN + SUBGOAL_THEN `!j. (a3:num->num) j <= p` + (fun th -> ASM_MESON_TAC[th]) THEN + X_GEN_TAC `j:num` THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`a0:num->num`; `j:num`]) THEN + ASM_REWRITE_TAC[] THEN COND_CASES_TAC THEN ARITH_TAC; + ALL_TAC] THEN + MATCH_MP_TAC MONO_AND THEN CONJ_TAC THENL + [REWRITE_TAC[IN_INSERT; IN_DELETE] THEN REPEAT STRIP_TAC THENL + [ALL_TAC; ASM_MESON_TAC[]] THEN + FIRST_X_ASSUM SUBST_ALL_TAC THEN + EXPAND_TAC "a3" THEN REWRITE_TAC[] THEN ASM_MESON_TAC[]; + ALL_TAC] THEN + DISCH_TAC THEN REWRITE_TAC[IN_INSERT; IN_DELETE] THEN + SUBGOAL_THEN `!x. x IN s /\ ~(x = a1) ==> kle n a3 x` + (fun th -> ASM_MESON_TAC[th; KLE_REFL]) THEN + X_GEN_TAC `x:num->num` THEN STRIP_TAC THEN + MATCH_MP_TAC KLE_BETWEEN_L THEN + MAP_EVERY EXISTS_TAC [`a0:num->num`; `a2:num->num`] THEN + ASM_MESON_TAC[IN_DELETE]; + ALL_TAC] THEN + GEN_REWRITE_TAC I [EXTENSION] THEN + REWRITE_TAC[IN_ELIM_THM; IN_INSERT; NOT_IN_EMPTY] THEN + X_GEN_TAC `s':(num->num)->bool` THEN EQ_TAC THENL + [ALL_TAC; + DISCH_THEN(DISJ_CASES_THEN SUBST_ALL_TAC) THENL + [ASM_REWRITE_TAC[] THEN ASM_MESON_TAC[]; ALL_TAC] THEN + ASM_REWRITE_TAC[] THEN EXISTS_TAC `a3:num->num` THEN + REWRITE_TAC[IN_INSERT; DELETE_INSERT] THEN + UNDISCH_TAC `~((a3:num->num) IN s)` THEN SET_TAC[]] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + DISCH_THEN(X_CHOOSE_THEN `a':num->num` STRIP_ASSUME_TAC) THEN + MP_TAC(SPECL [`p:num`; `n:num`; `s':(num->num)->bool`] + KSIMPLEX_EXTREMA_STRONG) THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `a_min:num->num` (X_CHOOSE_THEN `a_max:num->num` + STRIP_ASSUME_TAC)) THEN + SUBGOAL_THEN `(a':num->num = a_min) \/ (a' = a_max)` MP_TAC THENL + [MATCH_MP_TAC KSIMPLEX_FIX_PLANE THEN MAP_EVERY EXISTS_TAC + [`p:num`; `(a2:num->num) k`; `n:num`; + `k:num`; `s':(num->num)->bool`] THEN + REPEAT CONJ_TAC THEN TRY(FIRST_ASSUM MATCH_ACCEPT_TAC) THEN + X_GEN_TAC `x:num->num` THEN ASM_REWRITE_TAC[] THEN DISCH_TAC THEN + SUBGOAL_THEN `kle n a0 x /\ kle n x a2` MP_TAC THENL + [ASM_MESON_TAC[IN_DELETE]; ALL_TAC] THEN + DISCH_THEN(CONJUNCTS_THEN (MP_TAC o SPEC `k:num` o MATCH_MP + KLE_IMP_POINTWISE)) THEN + SUBGOAL_THEN `(a2:num->num) k <= a0 k` + (fun th -> MP_TAC th THEN ARITH_TAC) THEN + UNDISCH_TAC `!j:num. a1 j = (if j = k then a2 j + 1 else a2 j)` THEN + DISCH_THEN(MP_TAC o SPEC `k:num`) THEN ASM_REWRITE_TAC[] THEN ARITH_TAC; + ALL_TAC] THEN + DISCH_THEN(DISJ_CASES_THEN SUBST_ALL_TAC) THENL + [DISJ2_TAC THEN MATCH_MP_TAC lemma THEN + MAP_EVERY EXISTS_TAC [`a3:num->num`; `a_min:num->num`] THEN + ASM_REWRITE_TAC[IN_INSERT] THEN CONJ_TAC THENL + [UNDISCH_TAC `~(a3:num->num IN s)` THEN SET_TAC[]; ALL_TAC] THEN + SUBGOAL_THEN `a_max:num->num = a2` MP_TAC THENL + [SUBGOAL_THEN `a2:num->num IN (s' DELETE a_min) /\ + a_max:num->num IN (s DELETE a1)` + MP_TAC THENL + [ASM_MESON_TAC[IN_DELETE]; ASM_MESON_TAC[KLE_ANTISYM; IN_DELETE]]; + ALL_TAC] THEN + SUBGOAL_THEN + `!j. a2 j = if 1 <= j /\ j <= n then a3 j + 1 else a3 j` + (fun th -> ASM_REWRITE_TAC[th; FUN_EQ_THM]) + THENL + [ALL_TAC; + MATCH_MP_TAC MONO_FORALL THEN MESON_TAC[EQ_ADD_RCANCEL]] THEN + UNDISCH_TAC `!j:num. a1 j = (if j = k then a2 j + 1 else a2 j)` THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC MONO_FORALL THEN + MESON_TAC[EQ_ADD_RCANCEL]; + DISJ1_TAC THEN MATCH_MP_TAC lemma THEN + MAP_EVERY EXISTS_TAC [`a1:num->num`; `a_max:num->num`] THEN + REPEAT CONJ_TAC THEN TRY(FIRST_ASSUM ACCEPT_TAC) THEN + SUBGOAL_THEN `a_min:num->num = a0` MP_TAC THENL + [SUBGOAL_THEN `a0:num->num IN (s' DELETE a_max) /\ + a_min:num->num IN (s DELETE a1)` + MP_TAC THENL + [ASM_MESON_TAC[IN_DELETE]; ASM_MESON_TAC[KLE_ANTISYM; IN_DELETE]]; + ALL_TAC] THEN + UNDISCH_THEN `!j:num. a1 j = (if j = k then a2 j + 1 else a2 j)` + (K ALL_TAC) THEN + ASM_REWRITE_TAC[FUN_EQ_THM] THEN MATCH_MP_TAC MONO_FORALL THEN + MESON_TAC[EQ_ADD_RCANCEL]]; + ALL_TAC] THEN + MP_TAC(SPECL [`a:num->num`; `p:num`; `n:num`; `s:(num->num)->bool`] + KSIMPLEX_PREDECESSOR) THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC(TAUT `~a /\ (b ==> c) ==> a \/ b ==> c`) THEN CONJ_TAC THENL + [ASM_MESON_TAC[KLE_ANTISYM]; ALL_TAC] THEN + DISCH_THEN(X_CHOOSE_THEN `u:num->num` + (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + DISCH_THEN(X_CHOOSE_THEN `k:num` STRIP_ASSUME_TAC) THEN + MP_TAC(SPECL [`a:num->num`; `p:num`; `n:num`; `s:(num->num)->bool`] + KSIMPLEX_SUCCESSOR) THEN + REWRITE_TAC[ASSUME `ksimplex p n s`; ASSUME `a:num->num IN s`] THEN + MATCH_MP_TAC(TAUT `~a /\ (b ==> c) ==> a \/ b ==> c`) THEN CONJ_TAC THENL + [ASM_MESON_TAC[KLE_ANTISYM]; ALL_TAC] THEN + DISCH_THEN(X_CHOOSE_THEN `v:num->num` + (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + DISCH_THEN(X_CHOOSE_THEN `l:num` STRIP_ASSUME_TAC) THEN + ABBREV_TAC `a' = \j:num. if j = l then u(j) + 1 else u(j)` THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [FUN_EQ_THM]) THEN + REWRITE_TAC[] THEN DISCH_THEN(ASSUME_TAC o GSYM) THEN + SUBGOAL_THEN `~(k:num = l)` ASSUME_TAC THENL + [DISCH_TAC THEN + UNDISCH_TAC `!j:num. v j = (if j = l then a j + 1 else a j)` THEN + ASM_REWRITE_TAC[] THEN DISCH_THEN(MP_TAC o SPEC `l:num`) THEN + REWRITE_TAC[] THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [ksimplex]) THEN + DISCH_THEN(MP_TAC o last o CONJUNCTS) THEN + DISCH_THEN(MP_TAC o SPECL [`u:num->num`; `v:num->num`]) THEN + ASM_REWRITE_TAC[] THEN + ASM_REWRITE_TAC[kle] THEN + DISCH_THEN(DISJ_CASES_THEN (CHOOSE_THEN (MP_TAC o SPEC `l:num` o + CONJUNCT2))) THEN + ASM_REWRITE_TAC[] THEN COND_CASES_TAC THEN ARITH_TAC; + ALL_TAC] THEN + SUBGOAL_THEN `~(a':num->num = a)` ASSUME_TAC THENL + [ASM_REWRITE_TAC[FUN_EQ_THM] THEN DISCH_THEN(MP_TAC o SPEC `k:num`) THEN + ASM_REWRITE_TAC[] THEN ARITH_TAC; + ALL_TAC] THEN + SUBGOAL_THEN `~((a':num->num) IN s)` ASSUME_TAC THENL + [DISCH_TAC THEN FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [ksimplex]) THEN + DISCH_THEN(MP_TAC o SPECL [`a:num->num`; `a':num->num`] o + last o CONJUNCTS) THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(DISJ_CASES_THEN (MP_TAC o MATCH_MP KLE_IMP_POINTWISE)) THENL + [DISCH_THEN(MP_TAC o SPEC `k:num`) THEN ASM_REWRITE_TAC[] THEN ARITH_TAC; + DISCH_THEN(MP_TAC o SPEC `l:num`) THEN ASM_REWRITE_TAC[] THEN + ARITH_TAC]; + ALL_TAC] THEN + SUBGOAL_THEN + `kle n u a /\ kle n u a' /\ kle n a v /\ kle n a' v` + STRIP_ASSUME_TAC THENL + [REWRITE_TAC[kle] THEN REPEAT CONJ_TAC THENL + [EXISTS_TAC `{k:num}`; + EXISTS_TAC `{l:num}`; + EXISTS_TAC `{l:num}`; + EXISTS_TAC `{k:num}`] THEN + ASM_REWRITE_TAC[IN_SING; SUBSET; IN_NUMSEG] THEN + ASM_MESON_TAC[ADD_CLAUSES]; + ALL_TAC] THEN + SUBGOAL_THEN `!x. kle n u x /\ kle n x v + ==> ((x = u) \/ (x = a) \/ (x = a') \/ (x = v))` + ASSUME_TAC THENL + [X_GEN_TAC `x:num->num` THEN + DISCH_THEN(CONJUNCTS_THEN (MP_TAC o MATCH_MP KLE_IMP_POINTWISE)) THEN + ASM_REWRITE_TAC[FUN_EQ_THM; IMP_IMP; AND_FORALL_THM] THEN + ONCE_REWRITE_TAC[COND_RAND] THEN + ASM_CASES_TAC `(x:num->num) k = u k` THEN + ASM_CASES_TAC `(x:num->num) l = u l` THENL + [DISCH_THEN(fun th -> DISJ1_TAC THEN MP_TAC th); + DISCH_THEN(fun th -> DISJ2_TAC THEN DISJ2_TAC THEN DISJ1_TAC THEN + MP_TAC th); + DISCH_THEN(fun th -> DISJ2_TAC THEN DISJ1_TAC THEN MP_TAC th); + DISCH_THEN(fun th -> REPEAT DISJ2_TAC THEN MP_TAC th)] THEN + MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `j:num` THEN + REPEAT(COND_CASES_TAC THEN + ASM_REWRITE_TAC[LE_ANTISYM; + ARITH_RULE `x <= u + 1 /\ u <= x <=> (x = u) \/ (x = u + 1)`]); + ALL_TAC] THEN + SUBGOAL_THEN `kle n u v` ASSUME_TAC THENL + [ASM_MESON_TAC[KLE_TRANS; ksimplex]; ALL_TAC] THEN + SUBGOAL_THEN `ksimplex p n (a' INSERT (s DELETE a))` ASSUME_TAC THENL + [MP_TAC(ASSUME `ksimplex p n s`) THEN REWRITE_TAC[ksimplex] THEN + MATCH_MP_TAC MONO_AND THEN CONJ_TAC THENL + [SIMP_TAC[HAS_SIZE; FINITE_INSERT; FINITE_DELETE; CARD_CLAUSES; + CARD_DELETE; IN_DELETE] THEN + ASM_REWRITE_TAC[] THEN STRIP_TAC THEN ARITH_TAC; + ALL_TAC] THEN + MATCH_MP_TAC MONO_AND THEN CONJ_TAC THENL + [REWRITE_TAC[IN_INSERT; IN_DELETE] THEN + SIMP_TAC[TAUT `a \/ b ==> c <=> (a ==> c) /\ (b ==> c)`] THEN + REWRITE_TAC[RIGHT_FORALL_IMP_THM; LEFT_FORALL_IMP_THM; EXISTS_REFL] THEN + ASM_REWRITE_TAC[] THEN + DISCH_THEN(fun th -> X_GEN_TAC `j:num` THEN MP_TAC th) THEN + COND_CASES_TAC THEN ASM_SIMP_TAC[] THEN + DISCH_THEN(MP_TAC o SPEC `v:num->num`) THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(MP_TAC o SPEC `l:num`) THEN ASM_REWRITE_TAC[]; + ALL_TAC] THEN + MATCH_MP_TAC MONO_AND THEN CONJ_TAC THENL + [REWRITE_TAC[IN_INSERT; IN_DELETE] THEN + REWRITE_TAC[TAUT `(a \/ b) /\ c <=> a /\ c \/ b /\ c`] THEN + SIMP_TAC[TAUT `a \/ b ==> c <=> (a ==> c) /\ (b ==> c)`] THEN + REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN + REWRITE_TAC[EXISTS_REFL; LEFT_FORALL_IMP_THM] THEN + ASM_REWRITE_TAC[] THEN ASM_MESON_TAC[]; + ALL_TAC] THEN + REWRITE_TAC[IN_INSERT; IN_DELETE] THEN + SUBGOAL_THEN + `!x. x IN s /\ kle n v x ==> kle n a' x` + ASSUME_TAC THENL + [X_GEN_TAC `x:num->num` THEN STRIP_TAC THEN + MATCH_MP_TAC KLE_BETWEEN_R THEN + MAP_EVERY EXISTS_TAC [`u:num->num`; `v:num->num`] THEN + ASM_REWRITE_TAC[] THEN ASM_MESON_TAC[ksimplex; KLE_TRANS]; + ALL_TAC] THEN + SUBGOAL_THEN + `!x. x IN s /\ kle n x u ==> kle n x a'` + ASSUME_TAC THENL + [X_GEN_TAC `x:num->num` THEN STRIP_TAC THEN + MATCH_MP_TAC KLE_BETWEEN_L THEN + MAP_EVERY EXISTS_TAC [`u:num->num`; `v:num->num`] THEN + ASM_REWRITE_TAC[] THEN ASM_MESON_TAC[ksimplex; KLE_TRANS]; + ALL_TAC] THEN + SUBGOAL_THEN + `!x. x IN s /\ ~(x = a) ==> kle n a' x \/ kle n x a'` + (fun th -> MESON_TAC[th; KLE_REFL; ASSUME `(a:num->num) IN s`]) THEN + X_GEN_TAC `x:num->num` THEN STRIP_TAC THEN + ASM_CASES_TAC `kle n v x` THENL [ASM_MESON_TAC[]; ALL_TAC] THEN + ASM_CASES_TAC `kle n x u` THENL [ASM_MESON_TAC[]; ALL_TAC] THEN + SUBGOAL_THEN `(x:num->num = u) \/ (x = a) \/ (x = a') \/ (x = v)` + (fun th -> ASM_MESON_TAC[th; KLE_REFL]) THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_MESON_TAC[ksimplex]; + ALL_TAC] THEN + MATCH_MP_TAC HAS_SIZE_CARD THEN CONV_TAC HAS_SIZE_CONV THEN + MAP_EVERY EXISTS_TAC + [`s:(num->num)->bool`; `a' INSERT (s DELETE (a:num->num))`] THEN + CONJ_TAC THENL + [REWRITE_TAC[EXTENSION; IN_DELETE; IN_INSERT] THEN ASM_MESON_TAC[]; + ALL_TAC] THEN + GEN_REWRITE_TAC I [EXTENSION] THEN REWRITE_TAC[IN_ELIM_THM] THEN + X_GEN_TAC `s':(num->num)->bool` THEN + REWRITE_TAC[IN_INSERT; NOT_IN_EMPTY] THEN EQ_TAC THENL + [ALL_TAC; + DISCH_THEN(DISJ_CASES_THEN SUBST1_TAC) THENL + [ASM_MESON_TAC[]; ALL_TAC] THEN + ASM_REWRITE_TAC[] THEN EXISTS_TAC `a':num->num` THEN + REWRITE_TAC[EXTENSION; IN_INSERT; IN_DELETE] THEN ASM_MESON_TAC[]] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + DISCH_THEN(X_CHOOSE_THEN `a'':num->num` STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN `(a:num->num) IN s' \/ a' IN s'` MP_TAC THENL + [ALL_TAC; + MATCH_MP_TAC MONO_OR THEN CONJ_TAC THEN DISCH_TAC THEN + MP_TAC(ASSUME `s' DELETE a'' = s DELETE (a:num->num)`) THEN + REWRITE_TAC[EXTENSION] THEN + DISCH_THEN(fun th -> MP_TAC th THEN MP_TAC th) THENL + [DISCH_THEN(MP_TAC o SPEC `a:num->num`); + DISCH_THEN(MP_TAC o SPEC `a':num->num`)] THEN + REWRITE_TAC[IN_DELETE] THEN ASM_REWRITE_TAC[IN_INSERT; IN_DELETE] THEN + DISCH_THEN(SUBST_ALL_TAC o SYM) THEN ASM_MESON_TAC[]] THEN + SUBGOAL_THEN `~(u:num->num = v)` ASSUME_TAC THENL + [ASM_REWRITE_TAC[FUN_EQ_THM] THEN DISCH_THEN(MP_TAC o SPEC `l:num`) THEN + ASM_REWRITE_TAC[] THEN ARITH_TAC; + ALL_TAC] THEN + SUBGOAL_THEN `~(kle n v u)` ASSUME_TAC THENL + [ASM_MESON_TAC[KLE_ANTISYM]; ALL_TAC] THEN + SUBGOAL_THEN `~(u:num->num = a)` ASSUME_TAC THENL + [ASM_REWRITE_TAC[FUN_EQ_THM] THEN DISCH_THEN(MP_TAC o SPEC `k:num`) THEN + ASM_REWRITE_TAC[] THEN ARITH_TAC; + ALL_TAC] THEN + SUBGOAL_THEN `~(v:num->num = a)` ASSUME_TAC THENL + [ASM_REWRITE_TAC[FUN_EQ_THM] THEN DISCH_THEN(MP_TAC o SPEC `l:num`) THEN + ASM_REWRITE_TAC[] THEN ARITH_TAC; + ALL_TAC] THEN + SUBGOAL_THEN `u:num->num IN s' /\ v IN s'` STRIP_ASSUME_TAC THENL + [ASM_MESON_TAC[EXTENSION; IN_DELETE]; ALL_TAC] THEN + ASM_CASES_TAC + `!x. x IN s' ==> kle n x u \/ kle n v x` + THENL + [ALL_TAC; + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [NOT_FORALL_THM]) THEN + DISCH_THEN(X_CHOOSE_THEN `w:num->num` MP_TAC) THEN + REWRITE_TAC[NOT_IMP; DE_MORGAN_THM] THEN STRIP_TAC THEN + SUBGOAL_THEN `(w:num->num = u) \/ (w = a) \/ (w = a') \/ (w = v)` + (fun th -> ASM_MESON_TAC[KLE_REFL; th]) THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_MESON_TAC[ksimplex]] THEN + MP_TAC(SPECL [`u:num->num`; `p:num`; `n:num`; `s':(num->num)->bool`] + KSIMPLEX_SUCCESSOR) THEN + ANTS_TAC THENL [ASM_MESON_TAC[EXTENSION; IN_DELETE]; ALL_TAC] THEN + DISCH_THEN(DISJ_CASES_THEN2 (MP_TAC o SPEC `v:num->num`) MP_TAC) THENL + [ASM_MESON_TAC[EXTENSION; IN_DELETE]; ALL_TAC] THEN + ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN DISCH_THEN(K ALL_TAC) THEN + UNDISCH_TAC `!x. x IN s' ==> kle n x u \/ kle n v x` THEN + REWRITE_TAC[NOT_EXISTS_THM] THEN MATCH_MP_TAC MONO_FORALL THEN + X_GEN_TAC `w:num->num` THEN + DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN + ASM_REWRITE_TAC[] THEN + DISCH_THEN(DISJ_CASES_THEN(MP_TAC o MATCH_MP KLE_IMP_POINTWISE)) THEN + ASM_REWRITE_TAC[] THENL + [MESON_TAC[ARITH_RULE `~(i + 1 <= i)`]; ALL_TAC] THEN + DISCH_THEN(fun th -> MP_TAC(SPEC `k:num` th) THEN + MP_TAC(SPEC `l:num` th)) THEN + ASM_REWRITE_TAC[] THEN + REPEAT(COND_CASES_TAC THEN ASM_REWRITE_TAC[]) THEN TRY ARITH_TAC THEN + UNDISCH_TAC `~(k:num = l)` THEN ASM_REWRITE_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* Hence another step towards concreteness. *) +(* ------------------------------------------------------------------------- *) + +let KUHN_SIMPLEX_LEMMA = prove + (`!p n. (!s. ksimplex p (n + 1) s ==> (IMAGE rl s SUBSET 0..n+1)) /\ + ODD(CARD{f | (?s a. ksimplex p (n + 1) s /\ + a IN s /\ + (f = s DELETE a)) /\ + (IMAGE rl f = 0 .. n) /\ + ((?j. 1 <= j /\ j <= n + 1 /\ + !x. x IN f ==> (x j = 0)) \/ + (?j. 1 <= j /\ j <= n + 1 /\ + !x. x IN f ==> (x j = p)))}) + ==> ODD(CARD {s | s IN {s | ksimplex p (n + 1) s} /\ + (IMAGE rl s = 0..n+1)})`, + REPEAT STRIP_TAC THEN SUBGOAL_THEN + `ODD(CARD {f | f IN {f | ?s. s IN {s | ksimplex p (n + 1) s} /\ + (?a. a IN s /\ (f = s DELETE a))} /\ + (IMAGE rl f = 0..n) /\ + ((?j. 1 <= j /\ j <= n + 1 /\ !x. x IN f ==> (x j = 0)) \/ + (?j. 1 <= j /\ j <= n + 1 /\ !x. x IN f ==> (x j = p)))})` + MP_TAC THENL + [ASM_REWRITE_TAC[IN_ELIM_THM; RIGHT_AND_EXISTS_THM]; ALL_TAC] THEN + MATCH_MP_TAC KUHN_COMPLETE_LEMMA THEN REWRITE_TAC[FINITE_SIMPLICES] THEN + ASM_REWRITE_TAC[IN_ELIM_THM] THEN REPEAT STRIP_TAC THEN + CONV_TAC(LAND_CONV(ONCE_DEPTH_CONV SYM_CONV)) THEN ASM_REWRITE_TAC[] THENL + [ASM_MESON_TAC[ksimplex; ARITH_RULE `(n + 1) + 1 = n + 2`]; + ASM_SIMP_TAC[]; + MATCH_MP_TAC KSIMPLEX_REPLACE_0; + MATCH_MP_TAC KSIMPLEX_REPLACE_1; + MATCH_MP_TAC KSIMPLEX_REPLACE_2] THEN + ASM_MESON_TAC[ARITH_RULE `~(n + 1 = 0)`]);; + +(* ------------------------------------------------------------------------- *) +(* Reduced labelling. *) +(* ------------------------------------------------------------------------- *) + +let reduced = new_definition + `reduced label n (x:num->num) = + @k. k <= n /\ + (!i. 1 <= i /\ i < k + 1 ==> (label x i = 0)) /\ + ((k = n) \/ ~(label x (k + 1) = 0))`;; + +let REDUCED_LABELLING = prove + (`!label x n. + reduced label n x <= n /\ + (!i. 1 <= i /\ i < reduced label n x + 1 ==> (label x i = 0)) /\ + ((reduced label n x = n) \/ ~(label x (reduced label n x + 1) = 0))`, + REPEAT GEN_TAC THEN REWRITE_TAC[reduced] THEN CONV_TAC SELECT_CONV THEN + MP_TAC(SPEC `\j. j <= n /\ ~(label (x:num->num) (j + 1) = 0) \/ (n = j)` + num_WOP) THEN + REWRITE_TAC[] THEN + MATCH_MP_TAC(TAUT `a /\ (b ==> c) ==> (a <=> b) ==> c`) THEN + CONJ_TAC THENL [MESON_TAC[]; ALL_TAC] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `k:num` THEN + ASM_CASES_TAC `k = n:num` THEN ASM_REWRITE_TAC[] THEN STRIP_TAC THEN + ASM_REWRITE_TAC[LE_REFL] THEN X_GEN_TAC `i:num` THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `i - 1`) THEN + SIMP_TAC[LT_IMP_LE] THEN + ASM_SIMP_TAC[ARITH_RULE `1 <= i /\ i < n + 1 ==> i - 1 < n`] THEN + ASM_SIMP_TAC[ARITH_RULE `1 <= i /\ i < n + 1 ==> ~(n = i - 1)`] THEN + ASM_SIMP_TAC[SUB_ADD] THEN POP_ASSUM_LIST(MP_TAC o end_itlist CONJ) THEN + ARITH_TAC);; + +let REDUCED_LABELLING_UNIQUE = prove + (`!label x n. + r <= n /\ + (!i. 1 <= i /\ i < r + 1 ==> (label x i = 0)) /\ + ((r = n) \/ ~(label x (r + 1) = 0)) + ==> (reduced label n x = r)`, + REPEAT GEN_TAC THEN DISCH_THEN(REPEAT_TCL CONJUNCTS_THEN ASSUME_TAC) THEN + REPEAT_TCL CONJUNCTS_THEN ASSUME_TAC(SPECL + [`label:(num->num)->(num->num)`; `x:num->num`; `n:num`] + REDUCED_LABELLING) THEN + MATCH_MP_TAC(ARITH_RULE `~(a < b) /\ ~(b < a:num) ==> (a = b)`) THEN + ASM_MESON_TAC[ARITH_RULE `s < r:num /\ r <= n ==> ~(s = n)`; + ARITH_RULE `s < r ==> 1 <= s + 1 /\ s + 1 < r + 1`]);; + +let REDUCED_LABELLING_0 = prove + (`!label n x j. + 1 <= j /\ j <= n /\ (label x j = 0) + ==> ~(reduced label n x = j - 1)`, + REPEAT STRIP_TAC THEN + MP_TAC(SPECL [`label:(num->num)->num->num`; `x:num->num`; `n:num`] + REDUCED_LABELLING) THEN + ASM_SIMP_TAC[SUB_ADD; ARITH_RULE `1 <= j /\ j <= n ==> ~(j - 1 = n)`]);; + +let REDUCED_LABELLING_1 = prove + (`!label n x j. + 1 <= j /\ j <= n /\ ~(label x j = 0) + ==> reduced label n x < j`, + REWRITE_TAC[GSYM NOT_LE] THEN REPEAT STRIP_TAC THEN + MP_TAC(SPECL [`label:(num->num)->num->num`; `x:num->num`; `n:num`] + REDUCED_LABELLING) THEN + DISCH_THEN(MP_TAC o SPEC `j:num` o CONJUNCT1 o CONJUNCT2) THEN + ASM_REWRITE_TAC[ARITH_RULE `y < x + 1 <=> (y <= x)`]);; + +let REDUCED_LABELLING_SUC = prove + (`!lab n x. + ~(reduced lab (n + 1) x = n + 1) + ==> (reduced lab (n + 1) x = reduced lab n x)`, + REPEAT STRIP_TAC THEN CONV_TAC SYM_CONV THEN + MATCH_MP_TAC REDUCED_LABELLING_UNIQUE THEN + ASM_MESON_TAC[REDUCED_LABELLING; ARITH_RULE + `x <= n + 1 /\ ~(x = n + 1) ==> x <= n`]);; + +let COMPLETE_FACE_TOP = prove + (`!lab f n. + (!x j. x IN f /\ 1 <= j /\ j <= n + 1 /\ (x j = 0) + ==> (lab x j = 0)) /\ + (!x j. x IN f /\ 1 <= j /\ j <= n + 1 /\ (x j = p) + ==> (lab x j = 1)) + ==> ((IMAGE (reduced lab (n + 1)) f = 0..n) /\ + ((?j. 1 <= j /\ j <= n + 1 /\ !x. x IN f ==> (x j = 0)) \/ + (?j. 1 <= j /\ j <= n + 1 /\ !x. x IN f ==> (x j = p))) <=> + (IMAGE (reduced lab (n + 1)) f = 0..n) /\ + (!x. x IN f ==> (x (n + 1) = p)))`, + REPEAT STRIP_TAC THEN EQ_TAC THENL + [ALL_TAC; MESON_TAC[ARITH_RULE `1 <= n + 1`; LE_REFL]] THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [EXTENSION]) THENL + [DISCH_THEN(MP_TAC o SPEC `j - 1`) THEN + ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN DISCH_THEN(K ALL_TAC) THEN + ASM_SIMP_TAC[IN_IMAGE; IN_NUMSEG; LE_0; NOT_EXISTS_THM; + ARITH_RULE `j <= n + 1 ==> j - 1 <= n`] THEN + ASM_MESON_TAC[REDUCED_LABELLING_0]; + DISCH_THEN(MP_TAC o SPEC `j:num`) THEN + REWRITE_TAC[IN_IMAGE; IN_NUMSEG; LE_0; NOT_LE] THEN + ASM_SIMP_TAC[ARITH_RULE `j <= n + 1 ==> ((j <= n) <=> ~(j = n + 1))`] THEN + ASM_MESON_TAC[REDUCED_LABELLING_1; ARITH_RULE `~(1 = 0)`; LT_REFL]]);; + +(* ------------------------------------------------------------------------- *) +(* Hence we get just about the nice induction. *) +(* ------------------------------------------------------------------------- *) + +let KUHN_INDUCTION = prove + (`!p n. 0 < p /\ + (!x j. (!j. x(j) <= p) /\ 1 <= j /\ j <= n + 1 /\ (x j = 0) + ==> (lab x j = 0)) /\ + (!x j. (!j. x(j) <= p) /\ 1 <= j /\ j <= n + 1 /\ (x j = p) + ==> (lab x j = 1)) + ==> ODD(CARD {f | ksimplex p n f /\ + (IMAGE (reduced lab n) f = 0..n)}) + ==> ODD(CARD {s | ksimplex p (n + 1) s /\ + (IMAGE (reduced lab (n + 1)) s = 0..n+1)})`, + REPEAT STRIP_TAC THEN + MATCH_MP_TAC(REWRITE_RULE[IN_ELIM_THM] KUHN_SIMPLEX_LEMMA) THEN + CONJ_TAC THENL + [REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; IN_NUMSEG; LE_0] THEN + MESON_TAC[ARITH_RULE `x <= n ==> x <= n + 1`; REDUCED_LABELLING]; + ALL_TAC] THEN + FIRST_ASSUM(fun th -> MP_TAC th THEN + MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC) THEN + AP_TERM_TAC THEN GEN_REWRITE_TAC I [EXTENSION] THEN + X_GEN_TAC `f:(num->num)->bool` THEN REWRITE_TAC[IN_ELIM_THM] THEN + ASM_CASES_TAC + `(!x j. x IN f /\ 1 <= j /\ j <= n + 1 /\ (x j = 0) ==> (lab x j = 0)) /\ + (!x j. x IN f /\ 1 <= j /\ j <= n + 1 /\ (x j = p) ==> (lab x j = 1))` + THENL + [ALL_TAC; + MATCH_MP_TAC(TAUT `~a /\ ~b ==> (a /\ c <=> b /\ d)`) THEN + CONJ_TAC THEN FIRST_X_ASSUM(MP_TAC o check (is_neg o concl)) THEN + REWRITE_TAC[CONTRAPOS_THM] THEN REWRITE_TAC[ksimplex] THEN + ASM_MESON_TAC[IN_DELETE]] THEN + ASM_SIMP_TAC[COMPLETE_FACE_TOP] THEN + ASM_CASES_TAC `!x. x IN f ==> (x(n + 1):num = p)` THENL + [ALL_TAC; + ASM_REWRITE_TAC[] THEN DISCH_THEN(MP_TAC o CONJUNCT1) THEN + REWRITE_TAC[ksimplex] THEN + ASM_MESON_TAC[ARITH_RULE `~(n + 1 <= n)`]] THEN + ASM_SIMP_TAC[SIMPLEX_TOP_FACE] THEN + ASM_CASES_TAC `ksimplex p n f` THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[EXTENSION; IN_IMAGE] THEN + AP_TERM_TAC THEN GEN_REWRITE_TAC I [FUN_EQ_THM] THEN + X_GEN_TAC `k:num` THEN REWRITE_TAC[] THEN AP_THM_TAC THEN AP_TERM_TAC THEN + AP_TERM_TAC THEN GEN_REWRITE_TAC I [FUN_EQ_THM] THEN + X_GEN_TAC `x:num->num` THEN REWRITE_TAC[] THEN + ASM_CASES_TAC `(x:num->num) IN f` THEN ASM_REWRITE_TAC[] THEN + AP_TERM_TAC THEN CONV_TAC SYM_CONV THEN + MATCH_MP_TAC REDUCED_LABELLING_SUC THEN + MATCH_MP_TAC(ARITH_RULE `a:num < b ==> ~(a = b)`) THEN + MATCH_MP_TAC REDUCED_LABELLING_1 THEN + REWRITE_TAC[LE_REFL; ARITH_RULE `1 <= n + 1`] THEN + MATCH_MP_TAC(ARITH_RULE `(n = 1) ==> ~(n = 0)`) THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN + REWRITE_TAC[LE_REFL; ARITH_RULE `1 <= n + 1`] THEN + ASM_MESON_TAC[ksimplex]);; + +(* ------------------------------------------------------------------------- *) +(* And so we get the final combinatorial result. *) +(* ------------------------------------------------------------------------- *) + +let KSIMPLEX_0 = prove + (`ksimplex p 0 s <=> (s = {(\x. p)})`, + REWRITE_TAC[ksimplex; ADD_CLAUSES] THEN + CONV_TAC(LAND_CONV(LAND_CONV HAS_SIZE_CONV)) THEN + REWRITE_TAC[ARITH_RULE `1 <= j /\ j <= 0 <=> F`] THEN + ONCE_REWRITE_TAC[TAUT `a /\ b <=> ~(a ==> ~b)`] THEN + SIMP_TAC[LEFT_IMP_EXISTS_THM] THEN REWRITE_TAC[IN_SING] THEN + SIMP_TAC[RIGHT_FORALL_IMP_THM] THEN REWRITE_TAC[KLE_REFL] THEN + REWRITE_TAC[LEFT_FORALL_IMP_THM; EXISTS_REFL] THEN + REWRITE_TAC[AND_FORALL_THM; ARITH_RULE + `x <= y:num /\ (x = y) <=> (x = y)`] THEN + REWRITE_TAC[NOT_FORALL_THM; NOT_IMP] THEN + REWRITE_TAC[GSYM FUN_EQ_THM] THEN ONCE_REWRITE_TAC[CONJ_SYM] THEN + REWRITE_TAC[UNWIND_THM2]);; + +let REDUCE_LABELLING_0 = prove + (`!lab x. reduced lab 0 x = 0`, + REPEAT GEN_TAC THEN MATCH_MP_TAC REDUCED_LABELLING_UNIQUE THEN + REWRITE_TAC[LE_REFL] THEN ARITH_TAC);; + +let KUHN_COMBINATORIAL = prove + (`!lab p n. + 0 < p /\ + (!x j. (!j. x(j) <= p) /\ 1 <= j /\ j <= n /\ (x j = 0) + ==> (lab x j = 0)) /\ + (!x j. (!j. x(j) <= p) /\ 1 <= j /\ j <= n /\ (x j = p) + ==> (lab x j = 1)) + ==> ODD(CARD {s | ksimplex p n s /\ + (IMAGE (reduced lab n) s = 0..n)})`, + GEN_TAC THEN GEN_TAC THEN ONCE_REWRITE_TAC[IMP_CONJ] THEN + REWRITE_TAC[RIGHT_FORALL_IMP_THM] THEN DISCH_TAC THEN + INDUCT_TAC THENL + [DISCH_THEN(K ALL_TAC) THEN + SUBGOAL_THEN `{s | ksimplex p 0 s /\ (IMAGE (reduced lab 0) s = 0 .. 0)} = + {{(\x. p)}}` + (fun th -> SIMP_TAC[CARD_CLAUSES; NOT_IN_EMPTY; + FINITE_RULES; th; ARITH]) THEN + GEN_REWRITE_TAC I [EXTENSION] THEN + REWRITE_TAC[IN_ELIM_THM; KSIMPLEX_0; IN_SING] THEN + GEN_TAC THEN MATCH_MP_TAC(TAUT `(a ==> b) ==> (a /\ b <=> a)`) THEN + DISCH_THEN SUBST_ALL_TAC THEN + REWRITE_TAC[NUMSEG_SING; EXTENSION; IN_SING; IN_IMAGE] THEN + REWRITE_TAC[REDUCE_LABELLING_0] THEN MESON_TAC[]; + STRIP_TAC THEN FIRST_X_ASSUM(MP_TAC o check (is_imp o concl)) THEN + ANTS_TAC THENL + [ASM_MESON_TAC[ARITH_RULE `j <= n ==> j <= SUC n`]; + ALL_TAC] THEN + REWRITE_TAC[ADD1] THEN MATCH_MP_TAC KUHN_INDUCTION THEN + ASM_REWRITE_TAC[GSYM ADD1]]);; + +let KUHN_LEMMA = prove + (`!n p label. + 0 < p /\ 0 < n /\ + (!x. (!i. 1 <= i /\ i <= n ==> x(i) <= p) + ==> !i. 1 <= i /\ i <= n ==> (label x i = 0) \/ (label x i = 1)) /\ + (!x. (!i. 1 <= i /\ i <= n ==> x(i) <= p) + ==> !i. 1 <= i /\ i <= n /\ (x i = 0) ==> (label x i = 0)) /\ + (!x. (!i. 1 <= i /\ i <= n ==> x(i) <= p) + ==> !i. 1 <= i /\ i <= n /\ (x i = p) ==> (label x i = 1)) + ==> ?q. (!i. 1 <= i /\ i <= n ==> q(i) < p) /\ + (!i. 1 <= i /\ i <= n + ==> ?r s. (!j. 1 <= j /\ j <= n + ==> q(j) <= r(j) /\ r(j) <= q(j) + 1) /\ + (!j. 1 <= j /\ j <= n + ==> q(j) <= s(j) /\ s(j) <= q(j) + 1) /\ + ~(label r i = label s i))`, + REPEAT STRIP_TAC THEN + MP_TAC(SPECL [`label:(num->num)->num->num`; `p:num`; `n:num`] + KUHN_COMBINATORIAL) THEN + ANTS_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN + ASM_CASES_TAC + `{s | ksimplex p n s /\ (IMAGE (reduced label n) s = 0 .. n)} = {}` + THENL [ASM_REWRITE_TAC[CARD_CLAUSES; ARITH]; ALL_TAC] THEN + DISCH_THEN(K ALL_TAC) THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN + REWRITE_TAC[IN_ELIM_THM] THEN + DISCH_THEN(X_CHOOSE_THEN `s:(num->num)->bool` STRIP_ASSUME_TAC) THEN + MP_TAC(SPECL [`p:num`; `n:num`; `s:(num->num)->bool`] + KSIMPLEX_EXTREMA_STRONG) THEN + ASM_REWRITE_TAC[GSYM LT_NZ] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `a:num->num` THEN + DISCH_THEN(X_CHOOSE_THEN `b:num->num` STRIP_ASSUME_TAC) THEN + CONJ_TAC THEN X_GEN_TAC `i:num` THEN STRIP_TAC THENL + [MATCH_MP_TAC(ARITH_RULE `x + 1 <= y ==> x < y`) THEN + MATCH_MP_TAC LE_TRANS THEN EXISTS_TAC `(b:num->num) i` THEN + CONJ_TAC THENL [ASM_REWRITE_TAC[LE_REFL]; ALL_TAC] THEN + ASM_MESON_TAC[ksimplex]; + ALL_TAC] THEN + UNDISCH_TAC `IMAGE (reduced label n) s = 0 .. n` THEN + REWRITE_TAC[EXTENSION; IN_IMAGE] THEN + DISCH_THEN(fun th -> + MP_TAC(SPEC `i - 1` th) THEN MP_TAC(SPEC `i:num` th)) THEN + ASM_REWRITE_TAC[IN_NUMSEG; LE_0] THEN + DISCH_THEN(X_CHOOSE_THEN `u:num->num` (STRIP_ASSUME_TAC o GSYM)) THEN + ASM_SIMP_TAC[ARITH_RULE `1 <= i /\ i <= n ==> i - 1 <= n`] THEN + DISCH_THEN(X_CHOOSE_THEN `v:num->num` (STRIP_ASSUME_TAC o GSYM)) THEN + MAP_EVERY EXISTS_TAC [`u:num->num`; `v:num->num`] THEN + REWRITE_TAC[CONJ_ASSOC] THEN + CONJ_TAC THENL [ASM_MESON_TAC[KLE_IMP_POINTWISE]; ALL_TAC] THEN + MP_TAC(SPECL [`label:(num->num)->num->num`; `u:num->num`; `n:num`] + REDUCED_LABELLING) THEN + MP_TAC(SPECL [`label:(num->num)->num->num`; `v:num->num`; `n:num`] + REDUCED_LABELLING) THEN + ASM_REWRITE_TAC[] THEN + ASM_SIMP_TAC[ARITH_RULE `1 <= i /\ i <= n ==> ~(i - 1 = n)`] THEN + ASM_SIMP_TAC[SUB_ADD] THEN ASM_MESON_TAC[ARITH_RULE `i < i + 1`]);; + +(* ------------------------------------------------------------------------- *) +(* The main result for the unit cube. *) +(* ------------------------------------------------------------------------- *) + +let BROUWER_CUBE = prove + (`!f:real^N->real^N. + f continuous_on (interval [vec 0,vec 1]) /\ + IMAGE f (interval [vec 0,vec 1]) SUBSET (interval [vec 0,vec 1]) + ==> ?x. x IN interval[vec 0,vec 1] /\ (f x = x)`, + REPEAT STRIP_TAC THEN ABBREV_TAC `n = dimindex(:N)` THEN + SUBGOAL_THEN `1 <= n /\ 0 < n /\ ~(n = 0)` STRIP_ASSUME_TAC THENL + [EXPAND_TAC "n" THEN REWRITE_TAC[DIMINDEX_NONZERO; DIMINDEX_GE_1] THEN + ASM_MESON_TAC[LT_NZ; DIMINDEX_NONZERO]; + ALL_TAC] THEN + GEN_REWRITE_TAC I [TAUT `p <=> ~ ~ p`] THEN + PURE_REWRITE_TAC[NOT_EXISTS_THM; TAUT `~(a /\ b) <=> a ==> ~b`] THEN + DISCH_TAC THEN SUBGOAL_THEN + `?d. &0 < d /\ !x:real^N. x IN interval[vec 0,vec 1] ==> d <= norm(f x - x)` + STRIP_ASSUME_TAC THENL + [MATCH_MP_TAC BROUWER_COMPACTNESS_LEMMA THEN + ASM_SIMP_TAC[COMPACT_INTERVAL; CONTINUOUS_ON_SUB; CONTINUOUS_ON_CONST; + CONTINUOUS_ON_ID] THEN + ASM_MESON_TAC[VECTOR_SUB_EQ]; + ALL_TAC] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [SUBSET]) THEN + REWRITE_TAC[FORALL_IN_IMAGE] THEN + FREEZE_THEN(fun th -> DISCH_THEN(MP_TAC o MATCH_MP th)) + (SPEC `f:real^N->real^N` KUHN_LABELLING_LEMMA) THEN + DISCH_THEN(MP_TAC o SPEC `\i. 1 <= i /\ i <= n`) THEN + ANTS_TAC THENL [ASM_SIMP_TAC[IN_INTERVAL; VEC_COMPONENT]; ALL_TAC] THEN + REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `label:real^N->num->num` STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN + `!x y i. x IN interval[vec 0,vec 1] /\ y IN interval[vec 0,vec 1] /\ + 1 <= i /\ i <= n /\ ~(label (x:real^N) i :num = label y i) + ==> abs((f(x) - x)$i) <= norm(f(y) - f(x)) + norm(y - x)` + ASSUME_TAC THENL + [REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `abs(((f:real^N->real^N)(y) - f(x))$i) + abs((y - x)$i)` THEN + ASM_SIMP_TAC[REAL_LE_ADD2; COMPONENT_LE_NORM] THEN + ASM_SIMP_TAC[VECTOR_SUB_COMPONENT] THEN + MATCH_MP_TAC(REAL_ARITH + `!x y fx fy d. (x <= fx /\ fy <= y \/ fx <= x /\ y <= fy) + ==> abs(fx - x) <= abs(fy - fx) + abs(y - x)`) THEN + FIRST_X_ASSUM(MP_TAC o MATCH_MP (ARITH_RULE + `~(a = b) + ==> a <= 1 /\ b <= 1 ==> (a = 0) /\ (b = 1) \/ (a = 1) /\ (b = 0)`)) THEN + ASM_SIMP_TAC[] THEN STRIP_TAC THEN ASM_SIMP_TAC[]; + ALL_TAC] THEN + SUBGOAL_THEN + `?e. &0 < e /\ + !x y z i. x IN interval[vec 0,vec 1] /\ + y IN interval[vec 0,vec 1] /\ + z IN interval[vec 0,vec 1] /\ + 1 <= i /\ i <= n /\ + norm(x - z) < e /\ norm(y - z) < e /\ + ~(label (x:real^N) i :num = label y i) + ==> abs((f(z) - z)$i) < d / &n` + MP_TAC THENL + [SUBGOAL_THEN + `(f:real^N->real^N) uniformly_continuous_on interval[vec 0,vec 1]` + MP_TAC THENL + [ASM_SIMP_TAC[COMPACT_UNIFORMLY_CONTINUOUS; COMPACT_INTERVAL]; + ALL_TAC] THEN + REWRITE_TAC[uniformly_continuous_on] THEN + DISCH_THEN(MP_TAC o SPEC `d / &n / &8`) THEN + SUBGOAL_THEN `&0 < d / &n / &8` ASSUME_TAC THENL + [ASM_SIMP_TAC[REAL_LT_DIV; REAL_OF_NUM_LT; LT_MULT; ARITH]; + ALL_TAC] THEN + ASM_REWRITE_TAC[dist] THEN + DISCH_THEN(X_CHOOSE_THEN `e:real` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `min (e / &2) (d / &n / &8)` THEN + ASM_REWRITE_TAC[REAL_MUL_LZERO; REAL_LT_MIN; REAL_HALF] THEN + MAP_EVERY X_GEN_TAC [`x:real^N`; `y:real^N`; `z:real^N`; `i:num`] THEN + STRIP_TAC THEN + ASM_SIMP_TAC[VECTOR_SUB_COMPONENT] THEN + MATCH_MP_TAC(REAL_ARITH + `!x fx n1 n2 n3 n4 d4. + abs(fx - x) <= n1 + n2 /\ + abs(fx - fz) <= n3 /\ abs(x - z) <= n4 /\ + n1 < d4 /\ n2 < &2 * d4 /\ n3 < d4 /\ n4 < d4 /\ (&8 * d4 = d) + ==> abs(fz - z) < d`) THEN + MAP_EVERY EXISTS_TAC + [`(x:real^N)$i`; `(f:real^N->real^N)(x)$i`; + `norm((f:real^N->real^N) y - f x)`; `norm(y - x:real^N)`; + `norm((f:real^N->real^N) x - f z)`; + `norm(x - z:real^N)`; `d / &n / &8`] THEN + ASM_SIMP_TAC[GSYM VECTOR_SUB_COMPONENT; COMPONENT_LE_NORM] THEN + SIMP_TAC[REAL_DIV_LMUL; REAL_OF_NUM_EQ; ARITH] THEN + REPEAT CONJ_TAC THENL + [FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC REAL_LET_TRANS THEN + EXISTS_TAC `norm(x - z:real^N) + norm(y - z)` THEN + ASM_SIMP_TAC[REAL_ARITH `a < e / &2 /\ b < e / &2 /\ + (&2 * (e / &2) = e) ==> a + b < e`; + REAL_DIV_LMUL; REAL_OF_NUM_EQ; ARITH_EQ] THEN + REWRITE_TAC[GSYM dist] THEN MESON_TAC[DIST_TRIANGLE; DIST_SYM]; + MATCH_MP_TAC REAL_LET_TRANS THEN + EXISTS_TAC `norm(x - z:real^N) + norm(y - z)` THEN + ASM_SIMP_TAC[REAL_ARITH `a < e /\ b < e ==> a + b < &2 * e`] THEN + REWRITE_TAC[GSYM dist] THEN MESON_TAC[DIST_TRIANGLE; DIST_SYM]; + FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC(REAL_ARITH + `a < e / &2 /\ &0 < e /\ (&2 * (e / &2) = e) ==> a < e`) THEN + ASM_REWRITE_TAC[] THEN + SIMP_TAC[REAL_DIV_LMUL; REAL_OF_NUM_EQ; ARITH_EQ]]; + ALL_TAC] THEN + DISCH_THEN(X_CHOOSE_THEN `e:real` (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + X_CHOOSE_THEN `p:num` MP_TAC (SPEC `&1 + &n / e` REAL_ARCH_SIMPLE) THEN + DISJ_CASES_TAC(ARITH_RULE `(p = 0) \/ 0 < p`) THENL + [DISCH_THEN(fun th -> DISCH_THEN(K ALL_TAC) THEN MP_TAC th) THEN + ASM_REWRITE_TAC[LT_REFL; REAL_NOT_LE] THEN + ASM_SIMP_TAC[REAL_LT_DIV; REAL_OF_NUM_LT; + REAL_ARITH `&0 < x ==> &0 < &1 + x`]; + ALL_TAC] THEN + DISCH_TAC THEN ASM_REWRITE_TAC[NOT_FORALL_THM] THEN + MP_TAC(SPECL [`n:num`; `p:num`; + `\v:(num->num). label((lambda i. &(v i) / &p):real^N):num->num`] + KUHN_LEMMA) THEN + ASM_REWRITE_TAC[ARITH_RULE `(x = 0) \/ (x = 1) <=> x <= 1`] THEN + ANTS_TAC THENL + [REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_SIMP_TAC[LAMBDA_BETA; IN_INTERVAL; VEC_COMPONENT] THEN + ASM_SIMP_TAC[REAL_LE_RDIV_EQ; REAL_LE_LDIV_EQ; REAL_OF_NUM_LT] THEN + ASM_SIMP_TAC[REAL_DIV_REFL; REAL_MUL_LZERO; REAL_MUL_LID; + REAL_LT_IMP_NZ; REAL_OF_NUM_LT] THEN + ASM_REWRITE_TAC[LE_0; REAL_OF_NUM_LE] THEN + REWRITE_TAC[real_div; REAL_MUL_LZERO]; + ALL_TAC] THEN + DISCH_THEN(X_CHOOSE_THEN `q:num->num` STRIP_ASSUME_TAC) THEN + GEN_REWRITE_TAC BINDER_CONV [SWAP_EXISTS_THM] THEN + GEN_REWRITE_TAC I [SWAP_EXISTS_THM] THEN + ABBREV_TAC `z:real^N = lambda i. &(q i) / &p` THEN EXISTS_TAC `z:real^N` THEN + REWRITE_TAC[TAUT `~(a ==> b) <=> ~b /\ a`] THEN + GEN_REWRITE_TAC BINDER_CONV [SWAP_EXISTS_THM] THEN + ONCE_REWRITE_TAC[RIGHT_EXISTS_AND_THM] THEN + GEN_REWRITE_TAC I [SWAP_EXISTS_THM] THEN + ONCE_REWRITE_TAC[RIGHT_EXISTS_AND_THM] THEN + SUBGOAL_THEN `z:real^N IN interval[vec 0,vec 1]` ASSUME_TAC THENL + [EXPAND_TAC "z" THEN + SIMP_TAC[IN_INTERVAL; LAMBDA_BETA; VEC_COMPONENT] THEN + ASM_SIMP_TAC[REAL_LE_RDIV_EQ; REAL_LE_LDIV_EQ; REAL_OF_NUM_LT] THEN + REWRITE_TAC[REAL_MUL_LZERO; REAL_MUL_LID; REAL_OF_NUM_LE] THEN + ASM_SIMP_TAC[LE_0; LT_IMP_LE]; + ALL_TAC] THEN + SUBGOAL_THEN `?i. 1 <= i /\ i <= n /\ d / &n <= abs((f z - z:real^N)$i)` + MP_TAC THENL + [SUBGOAL_THEN `d <= norm(f z - z:real^N)` MP_TAC THENL + [ASM_SIMP_TAC[]; ALL_TAC] THEN + ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN + REWRITE_TAC[NOT_EXISTS_THM; TAUT `~(a /\ b /\ c) <=> a /\ b ==> ~c`] THEN + REWRITE_TAC[REAL_NOT_LE] THEN DISCH_TAC THEN + MATCH_MP_TAC REAL_LET_TRANS THEN EXISTS_TAC + `sum(1..dimindex(:N)) (\i. abs((f z - z:real^N)$i))` THEN + REWRITE_TAC[NORM_LE_L1] THEN MATCH_MP_TAC SUM_BOUND_LT_GEN THEN + REWRITE_TAC[FINITE_NUMSEG; IN_NUMSEG; NUMSEG_EMPTY; CARD_NUMSEG] THEN + ASM_REWRITE_TAC[NOT_LT; ADD_SUB]; + ALL_TAC] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `i:num` THEN + STRIP_TAC THEN ASM_REWRITE_TAC[REAL_NOT_LT] THEN + FIRST_X_ASSUM(MP_TAC o SPEC `i:num`) THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `r:num->num` (X_CHOOSE_THEN `s:num->num` + STRIP_ASSUME_TAC)) THEN + EXISTS_TAC `(lambda i. &(r i) / &p) :real^N` THEN + EXISTS_TAC `(lambda i. &(s i) / &p) :real^N` THEN + ASM_REWRITE_TAC[] THEN REPEAT CONJ_TAC THENL + [SIMP_TAC[IN_INTERVAL; LAMBDA_BETA; VEC_COMPONENT] THEN + ASM_SIMP_TAC[REAL_LE_RDIV_EQ; REAL_LE_LDIV_EQ; REAL_OF_NUM_LT] THEN + REWRITE_TAC[REAL_MUL_LZERO; REAL_MUL_LID; REAL_OF_NUM_LE] THEN + ASM_MESON_TAC[LE_0; ARITH_RULE `r <= q + 1 /\ q < p ==> r <= p`]; + SIMP_TAC[IN_INTERVAL; LAMBDA_BETA; VEC_COMPONENT] THEN + ASM_SIMP_TAC[REAL_LE_RDIV_EQ; REAL_LE_LDIV_EQ; REAL_OF_NUM_LT] THEN + REWRITE_TAC[REAL_MUL_LZERO; REAL_MUL_LID; REAL_OF_NUM_LE] THEN + ASM_MESON_TAC[LE_0; ARITH_RULE `r <= q + 1 /\ q < p ==> r <= p`]; + ALL_TAC; + ALL_TAC] THEN + MATCH_MP_TAC(MATCH_MP (REAL_ARITH `a <= b ==> b < e ==> a < e`) + (SPEC_ALL NORM_LE_L1)) THEN + MATCH_MP_TAC SUM_BOUND_LT_GEN THEN + REWRITE_TAC[FINITE_NUMSEG; IN_NUMSEG; NUMSEG_EMPTY; CARD_NUMSEG] THEN + ASM_REWRITE_TAC[NOT_LT; ADD_SUB] THEN EXPAND_TAC "z" THEN + EXPAND_TAC "n" THEN SIMP_TAC[VECTOR_SUB_COMPONENT; LAMBDA_BETA] THEN + ASM_REWRITE_TAC[real_div; GSYM REAL_SUB_RDISTRIB] THEN + REWRITE_TAC[GSYM real_div; REAL_ABS_DIV; REAL_ABS_NUM] THEN + ASM_SIMP_TAC[REAL_LT_LDIV_EQ; REAL_OF_NUM_LT] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_LET_TRANS THEN + EXISTS_TAC `&1` THEN + ASM_SIMP_TAC[REAL_ARITH `q <= r /\ r <= q + &1 ==> abs(r - q) <= &1`; + REAL_OF_NUM_LE; REAL_OF_NUM_ADD] THEN + GEN_REWRITE_TAC BINOP_CONV [GSYM REAL_INV_INV] THEN + MATCH_MP_TAC REAL_LT_INV2 THEN + REWRITE_TAC[REAL_INV_DIV; REAL_INV_MUL] THEN + ASM_SIMP_TAC[GSYM real_div; REAL_LT_LDIV_EQ; REAL_LT_RDIV_EQ; + REAL_OF_NUM_LT; ARITH] THEN + ASM_REWRITE_TAC[REAL_MUL_LZERO; REAL_OF_NUM_LT] THEN + REWRITE_TAC[REAL_INV_1; REAL_MUL_LID] THEN + ASM_SIMP_TAC[GSYM REAL_LT_LDIV_EQ; REAL_ARITH `&1 + x <= y ==> x < y`]);; + +(* ------------------------------------------------------------------------- *) +(* Retractions. *) +(* ------------------------------------------------------------------------- *) + +parse_as_infix("retract_of",(12,"right"));; + +let retraction = new_definition + `retraction (s,t) (r:real^N->real^N) <=> + t SUBSET s /\ r continuous_on s /\ (IMAGE r s SUBSET t) /\ + (!x. x IN t ==> (r x = x))`;; + +let retract_of = new_definition + `t retract_of s <=> ?r. retraction (s,t) r`;; + +let RETRACTION = prove + (`!s t r. retraction (s,t) r <=> + t SUBSET s /\ + r continuous_on s /\ + IMAGE r s = t /\ + (!x. x IN t ==> r x = x)`, + REWRITE_TAC[retraction] THEN SET_TAC[]);; + +let RETRACT_OF_IMP_EXTENSIBLE = prove + (`!f:real^M->real^N u s t. + s retract_of t /\ f continuous_on s /\ IMAGE f s SUBSET u + ==> ?g. g continuous_on t /\ IMAGE g t SUBSET u /\ + (!x. x IN s ==> g x = f x)`, + REPEAT STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [retract_of]) THEN + REWRITE_TAC[RETRACTION; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `r:real^M->real^M` THEN STRIP_TAC THEN + EXISTS_TAC `(f:real^M->real^N) o (r:real^M->real^M)` THEN + REWRITE_TAC[IMAGE_o; o_THM] THEN + CONJ_TAC THENL [MATCH_MP_TAC CONTINUOUS_ON_COMPOSE; ASM SET_TAC[]] THEN + ASM_MESON_TAC[]);; + +let RETRACTION_IDEMPOTENT = prove + (`!r s t. retraction (s,t) r ==> !x. x IN s ==> (r(r(x)) = r(x))`, + REWRITE_TAC[retraction; SUBSET; FORALL_IN_IMAGE] THEN MESON_TAC[]);; + +let IDEMPOTENT_IMP_RETRACTION = prove + (`!f:real^N->real^N s. + f continuous_on s /\ IMAGE f s SUBSET s /\ + (!x. x IN s ==> f(f x) = f x) + ==> retraction (s,IMAGE f s) f`, + REWRITE_TAC[retraction] THEN SET_TAC[]);; + +let RETRACTION_SUBSET = prove + (`!r s s' t. retraction (s,t) r /\ t SUBSET s' /\ s' SUBSET s + ==> retraction (s',t) r`, + SIMP_TAC[retraction] THEN + MESON_TAC[IMAGE_SUBSET; SUBSET_TRANS; CONTINUOUS_ON_SUBSET]);; + +let RETRACT_OF_SUBSET = prove + (`!s s' t. t retract_of s /\ t SUBSET s' /\ s' SUBSET s + ==> t retract_of s'`, + REPEAT GEN_TAC THEN + REWRITE_TAC[retract_of; LEFT_AND_EXISTS_THM] THEN + MATCH_MP_TAC MONO_EXISTS THEN MESON_TAC[RETRACTION_SUBSET]);; + +let RETRACT_OF_TRANSLATION = prove + (`!a t s:real^N->bool. + t retract_of s + ==> (IMAGE (\x. a + x) t) retract_of (IMAGE (\x. a + x) s)`, + REPEAT GEN_TAC THEN REWRITE_TAC[retract_of; retraction] THEN + DISCH_THEN(X_CHOOSE_THEN `r:real^N->real^N` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `(\x:real^N. a + x) o r o (\x:real^N. --a + x)` THEN + ASM_SIMP_TAC[IMAGE_SUBSET; FORALL_IN_IMAGE] THEN REPEAT CONJ_TAC THENL + [REPEAT(MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN + SIMP_TAC[CONTINUOUS_ON_ADD; CONTINUOUS_ON_CONST; CONTINUOUS_ON_ID]) THEN + ASM_REWRITE_TAC[GSYM IMAGE_o; o_DEF; VECTOR_ARITH `--a + a + x:real^N = x`; + IMAGE_ID]; + REWRITE_TAC[IMAGE_o] THEN MATCH_MP_TAC IMAGE_SUBSET THEN + GEN_REWRITE_TAC (LAND_CONV o RAND_CONV o ONCE_DEPTH_CONV) + [GSYM IMAGE_o] THEN + ASM_REWRITE_TAC[o_DEF; VECTOR_ARITH `--a + a + x:real^N = x`; IMAGE_ID]; + ASM_SIMP_TAC[o_DEF; VECTOR_ARITH `--a + a + x:real^N = x`]]);; + +let RETRACT_OF_TRANSLATION_EQ = prove + (`!a t s:real^N->bool. + (IMAGE (\x. a + x) t) retract_of (IMAGE (\x. a + x) s) <=> + t retract_of s`, + REPEAT GEN_TAC THEN EQ_TAC THEN REWRITE_TAC[RETRACT_OF_TRANSLATION] THEN + DISCH_THEN(MP_TAC o SPEC `--a:real^N` o MATCH_MP RETRACT_OF_TRANSLATION) THEN + REWRITE_TAC[GSYM IMAGE_o; o_DEF; IMAGE_ID; + VECTOR_ARITH `--a + a + x:real^N = x`]);; + +add_translation_invariants [RETRACT_OF_TRANSLATION_EQ];; + +let RETRACT_OF_INJECTIVE_LINEAR_IMAGE = prove + (`!f:real^M->real^N s t. + linear f /\ (!x y. f x = f y ==> x = y) /\ t retract_of s + ==> (IMAGE f t) retract_of (IMAGE f s)`, + REPEAT GEN_TAC THEN + REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + REWRITE_TAC[retract_of; retraction] THEN + DISCH_THEN(X_CHOOSE_THEN `r:real^M->real^M` STRIP_ASSUME_TAC) THEN + MP_TAC(ISPEC `f:real^M->real^N` LINEAR_INJECTIVE_LEFT_INVERSE) THEN + ASM_REWRITE_TAC[FUN_EQ_THM; o_THM; I_THM] THEN + DISCH_THEN(X_CHOOSE_THEN `g:real^N->real^M` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `(f:real^M->real^N) o r o (g:real^N->real^M)` THEN + UNDISCH_THEN `!x y. (f:real^M->real^N) x = f y ==> x = y` (K ALL_TAC) THEN + ASM_SIMP_TAC[IMAGE_SUBSET; FORALL_IN_IMAGE] THEN REPEAT CONJ_TAC THENL + [REPEAT(MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN + ASM_SIMP_TAC[LINEAR_CONTINUOUS_ON]) THEN + ASM_REWRITE_TAC[GSYM IMAGE_o; o_DEF; IMAGE_ID]; + REWRITE_TAC[IMAGE_o] THEN MATCH_MP_TAC IMAGE_SUBSET THEN + GEN_REWRITE_TAC (LAND_CONV o RAND_CONV o ONCE_DEPTH_CONV) + [GSYM IMAGE_o] THEN + ASM_REWRITE_TAC[o_DEF; IMAGE_ID]; + ASM_SIMP_TAC[o_DEF]]);; + +let RETRACT_OF_LINEAR_IMAGE_EQ = prove + (`!f:real^M->real^N s t. + linear f /\ (!x y. f x = f y ==> x = y) /\ (!y. ?x. f x = y) + ==> ((IMAGE f t) retract_of (IMAGE f s) <=> t retract_of s)`, + REPEAT GEN_TAC THEN DISCH_TAC THEN EQ_TAC THENL + [DISCH_TAC; ASM_MESON_TAC[RETRACT_OF_INJECTIVE_LINEAR_IMAGE]] THEN + FIRST_ASSUM(X_CHOOSE_THEN `h:real^N->real^M` STRIP_ASSUME_TAC o + MATCH_MP LINEAR_BIJECTIVE_LEFT_RIGHT_INVERSE) THEN + SUBGOAL_THEN + `!s. s = IMAGE (h:real^N->real^M) (IMAGE (f:real^M->real^N) s)` + (fun th -> ONCE_REWRITE_TAC[th]) THENL [ASM SET_TAC[]; ALL_TAC] THEN + MATCH_MP_TAC RETRACT_OF_INJECTIVE_LINEAR_IMAGE THEN + ASM_REWRITE_TAC[] THEN ASM_MESON_TAC[]);; + +add_linear_invariants [RETRACT_OF_LINEAR_IMAGE_EQ];; + +let RETRACTION_REFL = prove + (`!s. retraction (s,s) (\x. x)`, + REWRITE_TAC[retraction; IMAGE_ID; SUBSET_REFL; CONTINUOUS_ON_ID]);; + +let RETRACT_OF_REFL = prove + (`!s. s retract_of s`, + REWRITE_TAC[retract_of] THEN MESON_TAC[RETRACTION_REFL]);; + +let RETRACT_OF_IMP_SUBSET = prove + (`!s t. s retract_of t ==> s SUBSET t`, + SIMP_TAC[retract_of; retraction] THEN MESON_TAC[]);; + +let RETRACT_OF_EMPTY = prove + (`(!s:real^N->bool. {} retract_of s <=> s = {}) /\ + (!s:real^N->bool. s retract_of {} <=> s = {})`, + REWRITE_TAC[retract_of; retraction; SUBSET_EMPTY; IMAGE_CLAUSES] THEN + CONJ_TAC THEN X_GEN_TAC `s:real^N->bool` THEN + ASM_CASES_TAC `s:real^N->bool = {}` THEN + ASM_REWRITE_TAC[NOT_IN_EMPTY; IMAGE_EQ_EMPTY; CONTINUOUS_ON_EMPTY; + SUBSET_REFL]);; + +let RETRACT_OF_SING = prove + (`!s x:real^N. {x} retract_of s <=> x IN s`, + REPEAT GEN_TAC THEN REWRITE_TAC[retract_of; RETRACTION] THEN EQ_TAC THENL + [SET_TAC[]; ALL_TAC] THEN + DISCH_TAC THEN EXISTS_TAC `(\y. x):real^N->real^N` THEN + REWRITE_TAC[CONTINUOUS_ON_CONST] THEN ASM SET_TAC[]);; + +let RETRACTION_o = prove + (`!f g s t u:real^N->bool. + retraction (s,t) f /\ retraction (t,u) g + ==> retraction (s,u) (g o f)`, + REPEAT GEN_TAC THEN REWRITE_TAC[retraction] THEN REPEAT STRIP_TAC THENL + [ASM SET_TAC[]; + MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN ASM_REWRITE_TAC[] THEN + ASM_MESON_TAC[CONTINUOUS_ON_SUBSET]; + REWRITE_TAC[IMAGE_o] THEN ASM SET_TAC[]; + REWRITE_TAC[o_THM] THEN ASM SET_TAC[]]);; + +let RETRACT_OF_TRANS = prove + (`!s t u:real^N->bool. + s retract_of t /\ t retract_of u ==> s retract_of u`, + REWRITE_TAC[retract_of] THEN MESON_TAC[RETRACTION_o]);; + +let CLOSED_IN_RETRACT = prove + (`!s t:real^N->bool. + s retract_of t ==> closed_in (subtopology euclidean t) s`, + REPEAT GEN_TAC THEN REWRITE_TAC[retract_of; retraction] THEN + DISCH_THEN(X_CHOOSE_THEN `r:real^N->real^N` STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN + `s = {x:real^N | x IN t /\ lift(norm(r x - x)) = vec 0}` + SUBST1_TAC THENL + [REWRITE_TAC[GSYM DROP_EQ; DROP_VEC; LIFT_DROP; NORM_EQ_0] THEN + REWRITE_TAC[VECTOR_SUB_EQ] THEN ASM SET_TAC[]; + MATCH_MP_TAC CONTINUOUS_CLOSED_IN_PREIMAGE_CONSTANT THEN + MATCH_MP_TAC CONTINUOUS_ON_LIFT_NORM_COMPOSE THEN + MATCH_MP_TAC CONTINUOUS_ON_SUB THEN ASM_SIMP_TAC[CONTINUOUS_ON_ID]]);; + +let RETRACT_OF_CONTRACTIBLE = prove + (`!s t:real^N->bool. contractible t /\ s retract_of t ==> contractible s`, + REPEAT GEN_TAC THEN REWRITE_TAC[contractible; retract_of] THEN + DISCH_THEN(CONJUNCTS_THEN2 MP_TAC (X_CHOOSE_TAC `r:real^N->real^N`)) THEN + SIMP_TAC[HOMOTOPIC_WITH; PCROSS; LEFT_IMP_EXISTS_THM] THEN + FIRST_X_ASSUM(STRIP_ASSUME_TAC o GEN_REWRITE_RULE I [retraction]) THEN + MAP_EVERY X_GEN_TAC [`a:real^N`; `h:real^(1,N)finite_sum->real^N`] THEN + RULE_ASSUM_TAC(REWRITE_RULE[SUBSET; FORALL_IN_IMAGE]) THEN + STRIP_TAC THEN MAP_EVERY EXISTS_TAC + [`(r:real^N->real^N) a`; + `(r:real^N->real^N) o (h:real^(1,N)finite_sum->real^N)`] THEN + ASM_SIMP_TAC[o_THM; IMAGE_o; SUBSET] THEN CONJ_TAC THENL + [MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN CONJ_TAC THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP(REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET)) THEN ASM SET_TAC[]; + ASM SET_TAC[]]);; + +let RETRACT_OF_COMPACT = prove + (`!s t:real^N->bool. compact t /\ s retract_of t ==> compact s`, + REWRITE_TAC[retract_of; RETRACTION] THEN + MESON_TAC[COMPACT_CONTINUOUS_IMAGE]);; + +let RETRACT_OF_CLOSED = prove + (`!s t. closed t /\ s retract_of t ==> closed t`, + MESON_TAC[CLOSED_IN_CLOSED_EQ; CLOSED_IN_RETRACT]);; + +let RETRACT_OF_CONNECTED = prove + (`!s t:real^N->bool. connected t /\ s retract_of t ==> connected s`, + REWRITE_TAC[retract_of; RETRACTION] THEN + MESON_TAC[CONNECTED_CONTINUOUS_IMAGE]);; + +let RETRACT_OF_PATH_CONNECTED = prove + (`!s t:real^N->bool. path_connected t /\ s retract_of t ==> path_connected s`, + REWRITE_TAC[retract_of; RETRACTION] THEN + MESON_TAC[PATH_CONNECTED_CONTINUOUS_IMAGE]);; + +let RETRACT_OF_SIMPLY_CONNECTED = prove + (`!s t:real^N->bool. + simply_connected t /\ s retract_of t ==> simply_connected s`, + REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN + MATCH_MP_TAC(ONCE_REWRITE_RULE[IMP_CONJ] + (REWRITE_RULE[CONJ_ASSOC] SIMPLY_CONNECTED_RETRACTION_GEN)) THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [retract_of]) THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `r:real^N->real^N` THEN + REWRITE_TAC[RETRACTION] THEN STRIP_TAC THEN EXISTS_TAC `\x:real^N. x` THEN + ASM_REWRITE_TAC[IMAGE_ID; CONTINUOUS_ON_ID]);; + +let RETRACT_OF_HOMOTOPICALLY_TRIVIAL = prove + (`!s t:real^N->bool u:real^M->bool. + t retract_of s /\ + (!f g. f continuous_on u /\ IMAGE f u SUBSET s /\ + g continuous_on u /\ IMAGE g u SUBSET s + ==> homotopic_with (\x. T) (u,s) f g) + ==> (!f g. f continuous_on u /\ IMAGE f u SUBSET t /\ + g continuous_on u /\ IMAGE g u SUBSET t + ==> homotopic_with (\x. T) (u,t) f g)`, + REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + ONCE_REWRITE_TAC[TAUT `p /\ q /\ r /\ s <=> p /\ q /\ T /\ r /\ s /\ T`] THEN + MATCH_MP_TAC(ONCE_REWRITE_RULE[IMP_CONJ] + HOMOTOPICALLY_TRIVIAL_RETRACTION_GEN) THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [retract_of]) THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `r:real^N->real^N` THEN + REWRITE_TAC[RETRACTION] THEN STRIP_TAC THEN EXISTS_TAC `\x:real^N. x` THEN + ASM_REWRITE_TAC[CONTINUOUS_ON_ID; IMAGE_ID]);; + +let RETRACT_OF_HOMOTOPICALLY_TRIVIAL_NULL = prove + (`!s t:real^N->bool u:real^M->bool. + t retract_of s /\ + (!f. f continuous_on u /\ IMAGE f u SUBSET s + ==> ?c. homotopic_with (\x. T) (u,s) f (\x. c)) + ==> (!f. f continuous_on u /\ IMAGE f u SUBSET t + ==> ?c. homotopic_with (\x. T) (u,t) f (\x. c))`, + REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + ONCE_REWRITE_TAC[TAUT `p /\ q <=> p /\ q /\ T`] THEN + MATCH_MP_TAC(ONCE_REWRITE_RULE[IMP_CONJ] + HOMOTOPICALLY_TRIVIAL_RETRACTION_NULL_GEN) THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [retract_of]) THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `r:real^N->real^N` THEN + REWRITE_TAC[RETRACTION] THEN STRIP_TAC THEN EXISTS_TAC `\x:real^N. x` THEN + ASM_REWRITE_TAC[CONTINUOUS_ON_ID; IMAGE_ID]);; + +let RETRACT_OF_COHOMOTOPICALLY_TRIVIAL = prove + (`!s t:real^N->bool u:real^M->bool. + t retract_of s /\ + (!f g. f continuous_on s /\ IMAGE f s SUBSET u /\ + g continuous_on s /\ IMAGE g s SUBSET u + ==> homotopic_with (\x. T) (s,u) f g) + ==> (!f g. f continuous_on t /\ IMAGE f t SUBSET u /\ + g continuous_on t /\ IMAGE g t SUBSET u + ==> homotopic_with (\x. T) (t,u) f g)`, + REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + ONCE_REWRITE_TAC[TAUT `p /\ q /\ r /\ s <=> p /\ q /\ T /\ r /\ s /\ T`] THEN + MATCH_MP_TAC(ONCE_REWRITE_RULE[IMP_CONJ] + COHOMOTOPICALLY_TRIVIAL_RETRACTION_GEN) THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [retract_of]) THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `r:real^N->real^N` THEN + REWRITE_TAC[RETRACTION] THEN STRIP_TAC THEN EXISTS_TAC `\x:real^N. x` THEN + ASM_REWRITE_TAC[CONTINUOUS_ON_ID; IMAGE_ID]);; + +let RETRACT_OF_COHOMOTOPICALLY_TRIVIAL_NULL = prove + (`!s t:real^N->bool u:real^M->bool. + t retract_of s /\ + (!f. f continuous_on s /\ IMAGE f s SUBSET u + ==> ?c. homotopic_with (\x. T) (s,u) f (\x. c)) + ==> (!f. f continuous_on t /\ IMAGE f t SUBSET u + ==> ?c. homotopic_with (\x. T) (t,u) f (\x. c))`, + REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + ONCE_REWRITE_TAC[TAUT `p /\ q <=> p /\ q /\ T`] THEN + MATCH_MP_TAC(ONCE_REWRITE_RULE[IMP_CONJ] + COHOMOTOPICALLY_TRIVIAL_RETRACTION_NULL_GEN) THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [retract_of]) THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `r:real^N->real^N` THEN + REWRITE_TAC[RETRACTION] THEN STRIP_TAC THEN EXISTS_TAC `\x:real^N. x` THEN + ASM_REWRITE_TAC[CONTINUOUS_ON_ID; IMAGE_ID]);; + +let RETRACTION_IMP_QUOTIENT_MAP = prove + (`!r s t:real^N->bool. + retraction (s,t) r + ==> !u. u SUBSET t + ==> (open_in (subtopology euclidean s) {x | x IN s /\ r x IN u} <=> + open_in (subtopology euclidean t) u)`, + REPEAT GEN_TAC THEN REWRITE_TAC[RETRACTION] THEN STRIP_TAC THEN + MATCH_MP_TAC CONTINUOUS_RIGHT_INVERSE_IMP_QUOTIENT_MAP THEN + EXISTS_TAC `\x:real^N. x` THEN + ASM_REWRITE_TAC[CONTINUOUS_ON_ID; SUBSET_REFL; IMAGE_ID]);; + +let RETRACT_OF_LOCALLY_CONNECTED = prove + (`!s t:real^N->bool. + s retract_of t /\ locally connected t ==> locally connected s`, + REPEAT GEN_TAC THEN REWRITE_TAC[retract_of] THEN + DISCH_THEN(CONJUNCTS_THEN2 STRIP_ASSUME_TAC MP_TAC) THEN + FIRST_ASSUM(SUBST1_TAC o SYM o el 2 o CONJUNCTS o GEN_REWRITE_RULE I + [RETRACTION]) THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] LOCALLY_CONNECTED_QUOTIENT_IMAGE) THEN + MATCH_MP_TAC RETRACTION_IMP_QUOTIENT_MAP THEN + ASM_MESON_TAC[RETRACTION]);; + +let RETRACT_OF_LOCALLY_PATH_CONNECTED = prove + (`!s t:real^N->bool. + s retract_of t /\ locally path_connected t + ==> locally path_connected s`, + REPEAT GEN_TAC THEN REWRITE_TAC[retract_of] THEN + DISCH_THEN(CONJUNCTS_THEN2 STRIP_ASSUME_TAC MP_TAC) THEN + FIRST_ASSUM(SUBST1_TAC o SYM o el 2 o CONJUNCTS o GEN_REWRITE_RULE I + [RETRACTION]) THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] + LOCALLY_PATH_CONNECTED_QUOTIENT_IMAGE) THEN + MATCH_MP_TAC RETRACTION_IMP_QUOTIENT_MAP THEN + ASM_MESON_TAC[RETRACTION]);; + +let RETRACT_OF_LOCALLY_COMPACT = prove + (`!s t:real^N->bool. + locally compact s /\ t retract_of s ==> locally compact t`, + MESON_TAC[CLOSED_IN_RETRACT; LOCALLY_COMPACT_CLOSED_IN]);; + +let ABSOLUTE_RETRACTION_CONVEX_CLOSED_RELATIVE = prove + (`!s:real^N->bool t. + convex s /\ closed s /\ ~(s = {}) /\ s SUBSET t + ==> ?r. retraction (t,s) r /\ + !x. x IN (affine hull s) DIFF (relative_interior s) + ==> r(x) IN relative_frontier s`, + REPEAT STRIP_TAC THEN REWRITE_TAC[retraction] THEN + EXISTS_TAC `closest_point(s:real^N->bool)` THEN + ASM_SIMP_TAC[CONTINUOUS_ON_CLOSEST_POINT; CLOSEST_POINT_SELF] THEN + ASM_SIMP_TAC[SUBSET; FORALL_IN_IMAGE; CLOSEST_POINT_IN_SET] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC CLOSEST_POINT_IN_RELATIVE_FRONTIER THEN + ASM_MESON_TAC[SUBSET; RELATIVE_INTERIOR_SUBSET]);; + +let ABSOLUTE_RETRACTION_CONVEX_CLOSED = prove + (`!s:real^N->bool t. + convex s /\ closed s /\ ~(s = {}) /\ s SUBSET t + ==> ?r. retraction (t,s) r /\ + (!x. ~(x IN s) ==> r(x) IN frontier s)`, + REPEAT STRIP_TAC THEN REWRITE_TAC[retraction] THEN + EXISTS_TAC `closest_point(s:real^N->bool)` THEN + ASM_SIMP_TAC[CONTINUOUS_ON_CLOSEST_POINT; CLOSEST_POINT_SELF] THEN + ASM_SIMP_TAC[SUBSET; FORALL_IN_IMAGE; CLOSEST_POINT_IN_SET] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC CLOSEST_POINT_IN_FRONTIER THEN + ASM_MESON_TAC[SUBSET; INTERIOR_SUBSET]);; + +let ABSOLUTE_RETRACT_CONVEX_CLOSED = prove + (`!s:real^N->bool t. + convex s /\ closed s /\ ~(s = {}) /\ s SUBSET t + ==> s retract_of t`, + REWRITE_TAC[retract_of] THEN MESON_TAC[ABSOLUTE_RETRACTION_CONVEX_CLOSED]);; + +(* ------------------------------------------------------------------------- *) +(* A neighbourhood retract is an ANR for Euclidean space. *) +(* ------------------------------------------------------------------------- *) + +let NEIGHBOURHOOD_RETRACT_IMP_ANR = prove + (`!s:real^M->bool s':real^N->bool t u. + s retract_of t /\ open t /\ s homeomorphic s' /\ s' SUBSET u + ==> ?t'. open_in (subtopology euclidean u) t' /\ s' retract_of t'`, + MAP_EVERY X_GEN_TAC + [`X:real^M->bool`; `Y:real^N->bool`; `U:real^M->bool`; + `K:real^N->bool`] THEN + STRIP_TAC THEN + SUBGOAL_THEN `locally compact (Y:real^N->bool)` ASSUME_TAC THENL + [ASM_MESON_TAC[RETRACT_OF_LOCALLY_COMPACT; + OPEN_IMP_LOCALLY_COMPACT; HOMEOMORPHIC_LOCAL_COMPACTNESS]; + ALL_TAC] THEN + SUBGOAL_THEN + `?W:real^N->bool. + open_in (subtopology euclidean K) W /\ + closed_in (subtopology euclidean W) Y` + STRIP_ASSUME_TAC THENL + [FIRST_ASSUM(X_CHOOSE_THEN `W:real^N->bool` STRIP_ASSUME_TAC o + MATCH_MP LOCALLY_COMPACT_CLOSED_IN_OPEN) THEN + EXISTS_TAC `K INTER W:real^N->bool` THEN + ASM_SIMP_TAC[OPEN_IN_OPEN_INTER; CLOSED_IN_CLOSED] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [CLOSED_IN_CLOSED]) THEN + ASM SET_TAC[]; + ALL_TAC] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [homeomorphic]) THEN + REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN MAP_EVERY X_GEN_TAC + [`f:real^M->real^N`; `g:real^N->real^M`] THEN + REWRITE_TAC[homeomorphism] THEN STRIP_TAC THEN + MP_TAC(ISPECL [`g:real^N->real^M`; `W:real^N->bool`; `Y:real^N->bool`] + TIETZE_UNBOUNDED) THEN + ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `h:real^N->real^M` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `{x | x IN W /\ (h:real^N->real^M) x IN U}` THEN CONJ_TAC THENL + [MATCH_MP_TAC OPEN_IN_TRANS THEN EXISTS_TAC `W:real^N->bool` THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC CONTINUOUS_OPEN_IN_PREIMAGE_GEN THEN + EXISTS_TAC `(:real^M)` THEN + ASM_REWRITE_TAC[SUBTOPOLOGY_UNIV; GSYM OPEN_IN; SUBSET_UNIV]; + ALL_TAC] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [retract_of]) THEN + REWRITE_TAC[retraction; retract_of; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `r:real^M->real^M` THEN STRIP_TAC THEN + EXISTS_TAC `(f:real^M->real^N) o r o (h:real^N->real^M)` THEN + SUBGOAL_THEN + `(W:real^N->bool) SUBSET K /\ Y SUBSET W` + STRIP_ASSUME_TAC THENL + [ASM_MESON_TAC[OPEN_IN_IMP_SUBSET; CLOSED_IN_IMP_SUBSET]; ALL_TAC] THEN + REWRITE_TAC[IMAGE_o; o_THM] THEN CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + CONJ_TAC THENL [ALL_TAC; ASM SET_TAC[]] THEN + REPEAT(MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN CONJ_TAC) THEN + REWRITE_TAC[IMAGE_o] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET)) THEN + ASM SET_TAC[]);; + +let NEIGHBOURHOOD_RETRACT_IMP_ANR_UNIV = prove + (`!s:real^M->bool s':real^N->bool t. + s retract_of t /\ open t /\ s homeomorphic s' + ==> ?t'. open t' /\ s' retract_of t'`, + REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[OPEN_IN] THEN + ONCE_REWRITE_TAC[GSYM SUBTOPOLOGY_UNIV] THEN + MATCH_MP_TAC NEIGHBOURHOOD_RETRACT_IMP_ANR THEN + ASM_MESON_TAC[SUBSET_UNIV]);; + +let HOMEOMORPHIC_ANRNESS = prove + (`!s:real^M->bool t:real^N->bool. + s homeomorphic t + ==> ((?u. open u /\ s retract_of u) <=> (?u. open u /\ t retract_of u))`, + REPEAT STRIP_TAC THEN EQ_TAC THEN DISCH_TAC THENL + [MP_TAC(ISPECL [`s:real^M->bool`; `t:real^N->bool`] + NEIGHBOURHOOD_RETRACT_IMP_ANR_UNIV); + MP_TAC(ISPECL [`t:real^N->bool`; `s:real^M->bool`] + NEIGHBOURHOOD_RETRACT_IMP_ANR_UNIV)] THEN + ASM_REWRITE_TAC[] THEN DISCH_THEN MATCH_MP_TAC THEN + ASM_MESON_TAC[HOMEOMORPHIC_SYM]);; + +(* ------------------------------------------------------------------------- *) +(* Likewise for ARs, at least given closedness. *) +(* ------------------------------------------------------------------------- *) + +let ABSOLUTE_RETRACT_IMP_AR_GEN = prove + (`!s:real^M->bool s':real^N->bool t u. + s retract_of t /\ convex t /\ closed t /\ ~(t = {}) /\ + s homeomorphic s' /\ closed_in (subtopology euclidean u) s' + ==> s' retract_of u`, + REPEAT STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [homeomorphic]) THEN + REWRITE_TAC[homeomorphism; LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`f:real^M->real^N`; `g:real^N->real^M`] THEN + STRIP_TAC THEN + MP_TAC(ISPECL [`g:real^N->real^M`; `u:real^N->bool`; `s':real^N->bool`] + TIETZE_UNBOUNDED) THEN + ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `h:real^N->real^M` THEN STRIP_TAC THEN + SUBGOAL_THEN `s retract_of (:real^M)` MP_TAC THENL + [MATCH_MP_TAC RETRACT_OF_TRANS THEN EXISTS_TAC `t:real^M->bool` THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC ABSOLUTE_RETRACT_CONVEX_CLOSED THEN + ASM_REWRITE_TAC[SUBSET_UNIV]; + REWRITE_TAC[retract_of; retraction; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `r:real^M->real^M` THEN STRIP_TAC THEN + EXISTS_TAC `(f:real^M->real^N) o r o (h:real^N->real^M)` THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP CLOSED_IN_IMP_SUBSET) THEN + ASM_REWRITE_TAC[IMAGE_o; o_THM] THEN + CONJ_TAC THENL [ALL_TAC; ASM SET_TAC[]] THEN + REPEAT(MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN CONJ_TAC) THEN + REWRITE_TAC[IMAGE_o] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET)) THEN + ASM SET_TAC[]]);; + +let ABSOLUTE_RETRACT_IMP_AR = prove + (`!s s'. s retract_of (:real^M) /\ s homeomorphic s' /\ closed s' + ==> s' retract_of (:real^N)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC ABSOLUTE_RETRACT_IMP_AR_GEN THEN + MAP_EVERY EXISTS_TAC [`s:real^M->bool`; `(:real^M)`] THEN + ASM_REWRITE_TAC[SUBTOPOLOGY_UNIV; GSYM CLOSED_IN] THEN + REWRITE_TAC[CONVEX_UNIV; CLOSED_UNIV; UNIV_NOT_EMPTY]);; + +let HOMEOMORPHIC_COMPACT_ARNESS = prove + (`!s s'. s homeomorphic s' + ==> (compact s /\ s retract_of (:real^M) <=> + compact s' /\ s' retract_of (:real^N))`, + REPEAT STRIP_TAC THEN + ASM_CASES_TAC `compact(s:real^M->bool) /\ compact(s':real^N->bool)` THENL + [ALL_TAC; ASM_MESON_TAC[HOMEOMORPHIC_COMPACTNESS]] THEN + ASM_REWRITE_TAC[] THEN EQ_TAC THEN + MATCH_MP_TAC(ONCE_REWRITE_RULE[IMP_CONJ_ALT] ABSOLUTE_RETRACT_IMP_AR) THEN + ASM_MESON_TAC[HOMEOMORPHIC_SYM; COMPACT_IMP_CLOSED]);; + +(* ------------------------------------------------------------------------- *) +(* More retract properties including connection of complements. *) +(* ------------------------------------------------------------------------- *) + +let ABSOLUTE_RETRACT_HOMEOMORPHIC_CONVEX_COMPACT = prove + (`!s:real^N->bool t u:real^M->bool. + s homeomorphic u /\ ~(s = {}) /\ s SUBSET t /\ convex u /\ compact u + ==> s retract_of t`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC RETRACT_OF_SUBSET THEN + EXISTS_TAC `(:real^N)` THEN ASM_REWRITE_TAC[SUBSET_UNIV] THEN + FIRST_ASSUM(MP_TAC o MATCH_MP HOMEOMORPHIC_COMPACT_ARNESS) THEN + FIRST_ASSUM(MP_TAC o MATCH_MP HOMEOMORPHIC_COMPACTNESS) THEN + ASM_SIMP_TAC[] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC ABSOLUTE_RETRACT_CONVEX_CLOSED THEN + ASM_MESON_TAC[COMPACT_IMP_CLOSED; HOMEOMORPHIC_EMPTY; SUBSET_UNIV]);; + +let ABSOLUTE_RETRACT_PATH_IMAGE_ARC = prove + (`!g s:real^N->bool. + arc g /\ path_image g SUBSET s ==> (path_image g) retract_of s`, + REPEAT STRIP_TAC THEN MP_TAC + (ISPECL [`path_image g:real^N->bool`; `s:real^N->bool`; + `interval[vec 0:real^1,vec 1:real^1]`] + ABSOLUTE_RETRACT_HOMEOMORPHIC_CONVEX_COMPACT) THEN + DISCH_THEN MATCH_MP_TAC THEN ASM_REWRITE_TAC[PATH_IMAGE_NONEMPTY] THEN + REWRITE_TAC[COMPACT_INTERVAL; CONVEX_INTERVAL] THEN + ONCE_REWRITE_TAC[HOMEOMORPHIC_SYM] THEN + MATCH_MP_TAC HOMEOMORPHIC_COMPACT THEN + EXISTS_TAC `g:real^1->real^N` THEN + RULE_ASSUM_TAC(REWRITE_RULE[arc; path; path_image]) THEN + ASM_REWRITE_TAC[COMPACT_INTERVAL; path_image]);; + +let RELATIVE_BOUNDARY_RETRACT_OF_PUNCTURED_AFFINE_HULL = prove + (`!s a:real^N. + convex s /\ compact s /\ a IN relative_interior s + ==> (s DIFF relative_interior s) retract_of + ((affine hull s) DELETE a)`, + REPEAT GEN_TAC THEN GEOM_ORIGIN_TAC `a:real^N` THEN REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`s:real^N->bool`; `vec 0:real^N`] + RAY_TO_RELATIVE_FRONTIER) THEN + REWRITE_TAC[relative_frontier] THEN + ASM_SIMP_TAC[VECTOR_ADD_LID; RIGHT_IMP_EXISTS_THM; COMPACT_IMP_BOUNDED; + CLOSURE_CLOSED; COMPACT_IMP_CLOSED] THEN + REWRITE_TAC[SKOLEM_THM; LEFT_IMP_EXISTS_THM] THEN + REWRITE_TAC[TAUT `p ==> q /\ r <=> (p ==> q) /\ (p ==> r)`] THEN + REWRITE_TAC[FORALL_AND_THM] THEN + X_GEN_TAC `dd:real^N->real` THEN STRIP_TAC THEN + REWRITE_TAC[retract_of; retraction] THEN + EXISTS_TAC `\x:real^N. dd x % x` THEN REPEAT CONJ_TAC THENL + [MP_TAC(ISPECL [`affine:(real^N->bool)->bool`; `s:real^N->bool`] + HULL_SUBSET) THEN ASM SET_TAC[]; + MATCH_MP_TAC CONTINUOUS_ON_COMPACT_SURFACE_PROJECTION THEN + EXISTS_TAC `s DIFF relative_interior s:real^N->bool` THEN + ASM_SIMP_TAC[COMPACT_RELATIVE_BOUNDARY] THEN REPEAT CONJ_TAC THENL + [MATCH_MP_TAC(SET_RULE + `s SUBSET t /\ z IN s' ==> s DIFF s' SUBSET t DELETE z`) THEN + ASM_REWRITE_TAC[HULL_SUBSET]; + MATCH_MP_TAC(MESON[AFFINE_EQ_SUBSPACE; SUBSPACE_IMP_CONIC] + `affine s /\ vec 0 IN s ==> conic s`) THEN + REWRITE_TAC[AFFINE_AFFINE_HULL] THEN + ASM_MESON_TAC[HULL_INC; SUBSET; RELATIVE_INTERIOR_SUBSET]; + MAP_EVERY X_GEN_TAC [`x:real^N`; `k:real`] THEN + REWRITE_TAC[IN_DELETE; IN_DIFF] THEN STRIP_TAC THEN EQ_TAC THENL + [STRIP_TAC; ASM_MESON_TAC[IN_DIFF]] THEN + MATCH_MP_TAC(REAL_ARITH `~(a < b) /\ ~(b < a) ==> a = b`) THEN + CONJ_TAC THEN DISCH_TAC THENL + [ALL_TAC; ASM_MESON_TAC[REAL_LT_IMP_LE]] THEN + MP_TAC(ISPECL [`s:real^N->bool`; `vec 0:real^N`; `k % x:real^N`] + IN_RELATIVE_INTERIOR_CLOSURE_CONVEX_SEGMENT) THEN + ASM_SIMP_TAC[COMPACT_IMP_CLOSED; CLOSURE_CLOSED] THEN + REWRITE_TAC[SUBSET; IN_SEGMENT; NOT_FORALL_THM] THEN + EXISTS_TAC `dd(x) % x:real^N` THEN + RULE_ASSUM_TAC(REWRITE_RULE[IN_DIFF]) THEN ASM_SIMP_TAC[] THEN + ONCE_REWRITE_TAC[EQ_SYM_EQ] THEN + ASM_SIMP_TAC[VECTOR_MUL_EQ_0; REAL_LT_IMP_NZ] THEN + EXISTS_TAC `(dd:real^N->real) x / k` THEN + ASM_SIMP_TAC[REAL_LT_DIV; VECTOR_MUL_RZERO; VECTOR_ADD_LID; + REAL_LT_LDIV_EQ; VECTOR_MUL_ASSOC; REAL_MUL_LID; + REAL_DIV_RMUL; REAL_LT_IMP_NZ]]; + ASM_REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; IN_DELETE; IN_UNIV]; + X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN REWRITE_TAC[] THEN + SUBGOAL_THEN `x IN affine hull s /\ ~(x:real^N = vec 0)` + STRIP_ASSUME_TAC THENL + [MP_TAC(ISPECL [`affine:(real^N->bool)->bool`; `s:real^N->bool`] + HULL_SUBSET) THEN ASM SET_TAC[]; + REPEAT(FIRST_X_ASSUM(MP_TAC o SPEC `x:real^N`)) THEN + ASM_REWRITE_TAC[IN_DIFF] THEN REPEAT STRIP_TAC] THEN + SUBGOAL_THEN `(dd:real^N->real) x = &1` + (fun th -> REWRITE_TAC[th; VECTOR_MUL_LID]) THEN + MATCH_MP_TAC(REAL_ARITH `~(d < &1) /\ ~(&1 < d) ==> d = &1`) THEN + CONJ_TAC THEN DISCH_TAC THEN + MP_TAC(ISPECL [`s:real^N->bool`; `vec 0:real^N`] + IN_RELATIVE_INTERIOR_CLOSURE_CONVEX_SEGMENT) + THENL + [DISCH_THEN(MP_TAC o SPEC `x:real^N`); + DISCH_THEN(MP_TAC o SPEC `(dd x) % x:real^N`)] THEN + RULE_ASSUM_TAC(REWRITE_RULE[IN_DIFF]) THEN + ASM_SIMP_TAC[CLOSURE_CLOSED; COMPACT_IMP_CLOSED] THEN + REWRITE_TAC[SUBSET; IN_SEGMENT; NOT_FORALL_THM; NOT_IMP] THEN + REWRITE_TAC[VECTOR_MUL_RZERO; VECTOR_ADD_LID] THENL + [EXISTS_TAC `dd x % x:real^N` THEN ASM_REWRITE_TAC[] THEN ASM_MESON_TAC[]; + EXISTS_TAC `x:real^N` THEN + ASM_SIMP_TAC[VECTOR_ARITH `vec 0 = a % x <=> a % x:real^N = vec 0`] THEN + ASM_SIMP_TAC[VECTOR_MUL_EQ_0; REAL_LT_IMP_NZ] THEN + EXISTS_TAC `inv((dd:real^N->real) x)` THEN + ASM_SIMP_TAC[VECTOR_MUL_ASSOC; REAL_MUL_LINV; REAL_LT_IMP_NZ] THEN + ASM_SIMP_TAC[VECTOR_MUL_LID; REAL_LT_INV_EQ; REAL_INV_LT_1]]]);; + +let RELATIVE_FRONTIER_RETRACT_OF_PUNCTURED_AFFINE_HULL = prove + (`!s a:real^N. + convex s /\ bounded s /\ a IN relative_interior s + ==> relative_frontier s retract_of (affine hull s) DELETE a`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`closure s:real^N->bool`; `a:real^N`] + RELATIVE_BOUNDARY_RETRACT_OF_PUNCTURED_AFFINE_HULL) THEN + ASM_SIMP_TAC[COMPACT_CLOSURE; CONVEX_CLOSURE; relative_frontier; + CONVEX_RELATIVE_INTERIOR_CLOSURE; AFFINE_HULL_CLOSURE]);; + +let ANR_RELATIVE_FRONTIER_CONVEX = prove + (`!s:real^N->bool. + bounded s /\ convex s + ==> ?t. open t /\ (relative_frontier s) retract_of t`, + REPEAT STRIP_TAC THEN ASM_CASES_TAC `s:real^N->bool = {}` THEN + ASM_REWRITE_TAC[RELATIVE_FRONTIER_EMPTY] THENL + [ASM_MESON_TAC[RETRACT_OF_REFL; OPEN_EMPTY]; ALL_TAC] THEN + SUBGOAL_THEN `~(relative_interior s:real^N->bool = {})` MP_TAC THENL + [ASM_SIMP_TAC[RELATIVE_INTERIOR_EQ_EMPTY]; ALL_TAC] THEN + REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `a:real^N` THEN DISCH_TAC THEN + EXISTS_TAC `{x | x IN (:real^N) /\ + closest_point (affine hull s) x IN + ((:real^N) DELETE a)}` THEN + CONJ_TAC THENL + [REWRITE_TAC[OPEN_IN] THEN ONCE_REWRITE_TAC[GSYM SUBTOPOLOGY_UNIV] THEN + MATCH_MP_TAC CONTINUOUS_OPEN_IN_PREIMAGE_GEN THEN + EXISTS_TAC `(:real^N)` THEN + SIMP_TAC[OPEN_IN_DELETE; OPEN_IN_REFL; SUBSET_UNIV; ETA_AX]; + MATCH_MP_TAC RETRACT_OF_TRANS THEN + EXISTS_TAC `(affine hull s) DELETE (a:real^N)` THEN CONJ_TAC THENL + [MATCH_MP_TAC RELATIVE_FRONTIER_RETRACT_OF_PUNCTURED_AFFINE_HULL THEN + ASM_REWRITE_TAC[]; + REWRITE_TAC[retract_of; retraction] THEN + EXISTS_TAC `closest_point (affine hull s:real^N->bool)` THEN + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; IN_DELETE] THEN + ASM_SIMP_TAC[IN_ELIM_THM; IN_UNIV; CLOSEST_POINT_SELF; + CLOSEST_POINT_IN_SET; AFFINE_HULL_EQ_EMPTY; + CLOSED_AFFINE_HULL]]] THEN + MATCH_MP_TAC CONTINUOUS_ON_CLOSEST_POINT THEN + ASM_SIMP_TAC[AFFINE_IMP_CONVEX; AFFINE_AFFINE_HULL; + CLOSED_AFFINE_HULL; AFFINE_HULL_EQ_EMPTY]);; + +let FRONTIER_RETRACT_OF_PUNCTURED_UNIVERSE = prove + (`!s a. convex s /\ bounded s /\ a IN interior s + ==> (frontier s) retract_of ((:real^N) DELETE a)`, + REPEAT STRIP_TAC THEN FIRST_ASSUM(ASSUME_TAC o MATCH_MP (SET_RULE + `a IN s ==> ~(s = {})`)) THEN + MP_TAC(ISPECL [`s:real^N->bool`; `a:real^N`] + RELATIVE_FRONTIER_RETRACT_OF_PUNCTURED_AFFINE_HULL) THEN + ASM_SIMP_TAC[RELATIVE_FRONTIER_NONEMPTY_INTERIOR; + RELATIVE_INTERIOR_NONEMPTY_INTERIOR; + AFFINE_HULL_NONEMPTY_INTERIOR]);; + +let SPHERE_RETRACT_OF_PUNCTURED_UNIVERSE_GEN = prove + (`!a r b:real^N. + b IN ball(a,r) ==> sphere(a,r) retract_of ((:real^N) DELETE b)`, + REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM FRONTIER_CBALL] THEN + MATCH_MP_TAC FRONTIER_RETRACT_OF_PUNCTURED_UNIVERSE THEN + ASM_REWRITE_TAC[CONVEX_CBALL; BOUNDED_CBALL; INTERIOR_CBALL]);; + +let SPHERE_RETRACT_OF_PUNCTURED_UNIVERSE = prove + (`!a r. &0 < r ==> sphere(a,r) retract_of ((:real^N) DELETE a)`, + REPEAT STRIP_TAC THEN + MATCH_MP_TAC SPHERE_RETRACT_OF_PUNCTURED_UNIVERSE_GEN THEN + ASM_REWRITE_TAC[CENTRE_IN_BALL]);; + +let RETRACT_OF_PCROSS = prove + (`!s:real^M->bool s' t:real^N->bool t'. + s retract_of s' /\ t retract_of t' + ==> (s PCROSS t) retract_of (s' PCROSS t')`, + REPEAT GEN_TAC THEN REWRITE_TAC[PCROSS] THEN + REWRITE_TAC[retract_of; retraction; SUBSET; FORALL_IN_IMAGE] THEN + DISCH_THEN(CONJUNCTS_THEN2 + (X_CHOOSE_THEN `f:real^M->real^M` STRIP_ASSUME_TAC) + (X_CHOOSE_THEN `g:real^N->real^N` STRIP_ASSUME_TAC)) THEN + EXISTS_TAC `\z. pastecart ((f:real^M->real^M) (fstcart z)) + ((g:real^N->real^N) (sndcart z))` THEN + REWRITE_TAC[FORALL_PASTECART; IN_ELIM_PASTECART_THM] THEN + ASM_SIMP_TAC[FSTCART_PASTECART; SNDCART_PASTECART] THEN + MATCH_MP_TAC CONTINUOUS_ON_PASTECART THEN + CONJ_TAC THEN GEN_REWRITE_TAC LAND_CONV [GSYM o_DEF] THEN + MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN + SIMP_TAC[LINEAR_CONTINUOUS_ON; LINEAR_FSTCART; LINEAR_SNDCART] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET)) THEN + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; FORALL_IN_GSPEC] THEN + SIMP_TAC[FSTCART_PASTECART; SNDCART_PASTECART]);; + +let LOCALLY_PATH_CONNECTED_SPHERE_GEN = prove + (`!s:real^N->bool. + bounded s /\ convex s ==> locally path_connected (relative_frontier s)`, + REPEAT STRIP_TAC THEN + ASM_CASES_TAC `relative_interior(s:real^N->bool) = {}` THENL + [UNDISCH_TAC `relative_interior(s:real^N->bool) = {}` THEN + ASM_SIMP_TAC[RELATIVE_INTERIOR_EQ_EMPTY] THEN + REWRITE_TAC[LOCALLY_EMPTY; RELATIVE_FRONTIER_EMPTY]; + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN + DISCH_THEN(X_CHOOSE_TAC `a:real^N`) THEN + MATCH_MP_TAC RETRACT_OF_LOCALLY_PATH_CONNECTED THEN + EXISTS_TAC `(affine hull s) DELETE (a:real^N)` THEN + ASM_SIMP_TAC[RELATIVE_FRONTIER_RETRACT_OF_PUNCTURED_AFFINE_HULL] THEN + MATCH_MP_TAC LOCALLY_OPEN_SUBSET THEN + EXISTS_TAC `affine hull s:real^N->bool` THEN + SIMP_TAC[OPEN_IN_DELETE; OPEN_IN_REFL] THEN + SIMP_TAC[CONVEX_IMP_LOCALLY_PATH_CONNECTED; AFFINE_IMP_CONVEX; + AFFINE_AFFINE_HULL]]);; + +let LOCALLY_CONNECTED_SPHERE_GEN = prove + (`!s:real^N->bool. + bounded s /\ convex s ==> locally connected (relative_frontier s)`, + SIMP_TAC[LOCALLY_PATH_CONNECTED_SPHERE_GEN; + LOCALLY_PATH_CONNECTED_IMP_LOCALLY_CONNECTED]);; + +let LOCALLY_PATH_CONNECTED_SPHERE = prove + (`!a:real^N r. locally path_connected (sphere(a,r))`, + REPEAT GEN_TAC THEN + MP_TAC(ISPEC `cball(a:real^N,r)` LOCALLY_PATH_CONNECTED_SPHERE_GEN) THEN + MP_TAC(ISPECL [`a:real^N`; `r:real`] RELATIVE_FRONTIER_CBALL) THEN + COND_CASES_TAC THEN + ASM_SIMP_TAC[SPHERE_SING; LOCALLY_SING; PATH_CONNECTED_SING; + BOUNDED_CBALL; CONVEX_CBALL]);; + +let LOCALLY_CONNECTED_SPHERE = prove + (`!a:real^N r. locally connected(sphere(a,r))`, + SIMP_TAC[LOCALLY_PATH_CONNECTED_SPHERE; + LOCALLY_PATH_CONNECTED_IMP_LOCALLY_CONNECTED]);; + +(* ------------------------------------------------------------------------- *) +(* Extending a function into an ANR. *) +(* ------------------------------------------------------------------------- *) + +let NEIGHBOURHOOD_EXTENSION_INTO_ANR_LOCAL = prove + (`!f:real^M->real^N c s t u. + f continuous_on c /\ IMAGE f c SUBSET t /\ open u /\ t retract_of u /\ + closed_in (subtopology euclidean s) c + ==> ?v g. c SUBSET v /\ open_in (subtopology euclidean s) v /\ + g continuous_on v /\ IMAGE g v SUBSET t /\ + !x. x IN c ==> g x = f x`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`f:real^M->real^N`; `s:real^M->bool`; `c:real^M->bool`] + TIETZE_UNBOUNDED) THEN + ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `g:real^M->real^N` THEN STRIP_TAC THEN + EXISTS_TAC `{x | x IN s /\ (g:real^M->real^N) x IN u}` THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [retract_of]) THEN + REWRITE_TAC[retraction] THEN + DISCH_THEN(X_CHOOSE_THEN `r:real^N->real^N` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `(r:real^N->real^N) o (g:real^M->real^N)` THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP CLOSED_IN_IMP_SUBSET) THEN + REPEAT CONJ_TAC THENL + [ASM SET_TAC[]; + MATCH_MP_TAC CONTINUOUS_OPEN_IN_PREIMAGE THEN ASM_REWRITE_TAC[]; + MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN CONJ_TAC THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET)) THEN ASM SET_TAC[]; + REWRITE_TAC[IMAGE_o] THEN ASM SET_TAC[]; + REWRITE_TAC[o_THM] THEN ASM SET_TAC[]]);; + +let NEIGHBOURHOOD_EXTENSION_INTO_ANR = prove + (`!f:real^M->real^N s t u. + f continuous_on s /\ IMAGE f s SUBSET t /\ open u /\ t retract_of u /\ + closed s + ==> ?v g. s SUBSET v /\ open v /\ g continuous_on v /\ + IMAGE g v SUBSET t /\ !x. x IN s ==> g x = f x`, + REPEAT GEN_TAC THEN + MP_TAC(ISPECL + [`f:real^M->real^N`; `s:real^M->bool`; `(:real^M)`; `t:real^N->bool`; + `u:real^N->bool`] NEIGHBOURHOOD_EXTENSION_INTO_ANR_LOCAL) THEN + REWRITE_TAC[GSYM OPEN_IN; GSYM CLOSED_IN; SUBTOPOLOGY_UNIV]);; + +(* ------------------------------------------------------------------------- *) +(* Borsuk homotopy extension thorem. It's only this late so we can use the *) +(* concept of retraction, essentially that the range is an ANR. *) +(* ------------------------------------------------------------------------- *) + +let BORSUK_HOMOTOPY_EXTENSION = prove + (`!f:real^M->real^N g s t u v. + closed s /\ closed t /\ u retract_of v /\ open v /\ + f continuous_on t /\ IMAGE f t SUBSET u /\ + g continuous_on s /\ IMAGE g s SUBSET u /\ + homotopic_with (\x. T) (s,u) f g + ==> ?g'. g' continuous_on t /\ IMAGE g' t SUBSET u /\ + !x. x IN s ==> g'(x) = g(x)`, + REPEAT STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [homotopic_with]) THEN + REWRITE_TAC[PCROSS] THEN + DISCH_THEN(X_CHOOSE_THEN `h:real^(1,M)finite_sum->real^N` + STRIP_ASSUME_TAC) THEN + ABBREV_TAC `B = {pastecart (vec 0:real^1) (x:real^M) | x IN t} UNION + {pastecart u x | u IN interval[vec 0,vec 1] /\ x IN s}` THEN + SUBGOAL_THEN `closed(B:real^(1,M)finite_sum->bool)` ASSUME_TAC THENL + [EXPAND_TAC "B" THEN MATCH_MP_TAC CLOSED_UNION THEN + REWRITE_TAC[SET_RULE `{pastecart (vec 0) (x:real^M) | x IN t} = + {pastecart u x | u IN {vec 0} /\ x IN t}`] THEN + ASM_SIMP_TAC[REWRITE_RULE[PCROSS] CLOSED_PCROSS; + CLOSED_SING; CLOSED_INTERVAL]; + ALL_TAC] THEN + SUBGOAL_THEN + `?k:real^(1,M)finite_sum->real^N. + k continuous_on (:real^(1,M)finite_sum) /\ + (!x. x IN t ==> k(pastecart (vec 0) x) = f(x)) /\ + (!u x. u IN interval[vec 0,vec 1] /\ x IN s + ==> k(pastecart u x) = h(pastecart u x))` + STRIP_ASSUME_TAC THENL + [SUBGOAL_THEN + `?k:real^(1,M)finite_sum->real^N. + k continuous_on B /\ + (!x. x IN t ==> k(pastecart (vec 0) x) = f(x)) /\ + (!u x. u IN interval[vec 0,vec 1] /\ x IN s + ==> k(pastecart u x) = h(pastecart u x))` + STRIP_ASSUME_TAC THENL + [EXISTS_TAC `\z. if fstcart z = vec 0 then f(sndcart z) + else (h:real^(1,M)finite_sum->real^N) z` THEN + REWRITE_TAC[FSTCART_PASTECART; SNDCART_PASTECART] THEN + CONJ_TAC THENL [ALL_TAC; ASM_MESON_TAC[]] THEN + EXPAND_TAC "B" THEN MATCH_MP_TAC CONTINUOUS_ON_CASES THEN + REWRITE_TAC[SET_RULE `{pastecart (vec 0) (x:real^M) | x IN t} = + {pastecart u x | u IN {vec 0} /\ x IN t}`] THEN + ASM_SIMP_TAC[REWRITE_RULE[PCROSS] CLOSED_PCROSS; + CLOSED_SING; CLOSED_INTERVAL] THEN + REWRITE_TAC[TAUT `(a \/ b /\ c ==> d) <=> (a ==> d) /\ (b ==> c ==> d)`; + IMP_CONJ; FORALL_AND_THM; FORALL_IN_GSPEC; IN_ELIM_PASTECART_THM] THEN + ASM_SIMP_TAC[FSTCART_PASTECART; SNDCART_PASTECART; IN_SING] THEN + GEN_REWRITE_TAC LAND_CONV [GSYM o_DEF] THEN + MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN + SIMP_TAC[LINEAR_CONTINUOUS_ON; LINEAR_SNDCART] THEN + MATCH_MP_TAC CONTINUOUS_ON_SUBSET THEN EXISTS_TAC `t:real^M->bool` THEN + ASM_REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; FORALL_IN_GSPEC] THEN + SIMP_TAC[SNDCART_PASTECART]; + MP_TAC(ISPECL + [`k:real^(1,M)finite_sum->real^N`; `(:real^(1,M)finite_sum)`; + `B:real^(1,M)finite_sum->bool`] + TIETZE_UNBOUNDED) THEN + ASM_REWRITE_TAC[SUBTOPOLOGY_UNIV; GSYM CLOSED_IN] THEN + MATCH_MP_TAC MONO_EXISTS THEN + X_GEN_TAC `g:real^(1,M)finite_sum->real^N` THEN STRIP_TAC THEN + ASM_REWRITE_TAC[] THEN ASM SET_TAC[]]; + ALL_TAC] THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP RETRACT_OF_IMP_SUBSET) THEN + ABBREV_TAC + `V = {x | x IN UNIV /\ (k:real^(1,M)finite_sum->real^N) x IN v}` THEN + SUBGOAL_THEN `open(V:real^(1,M)finite_sum->bool)` ASSUME_TAC THENL + [EXPAND_TAC "V" THEN MATCH_MP_TAC CONTINUOUS_OPEN_PREIMAGE THEN + ASM_REWRITE_TAC[OPEN_UNIV]; + ALL_TAC] THEN + SUBGOAL_THEN `(B:real^(1,M)finite_sum->bool) SUBSET V` ASSUME_TAC THENL + [MAP_EVERY EXPAND_TAC ["B"; "V"] THEN REWRITE_TAC[UNION_SUBSET] THEN + REWRITE_TAC[SUBSET; FORALL_IN_GSPEC] THEN + ASM_SIMP_TAC[IN_ELIM_THM; IN_UNIV] THEN ASM SET_TAC[]; + ALL_TAC] THEN + ABBREV_TAC `s' = {x | ?u. u IN interval[vec 0,vec 1] /\ + ~((pastecart (u:real^1) (x:real^M)) IN V)}` THEN + SUBGOAL_THEN `closed(s':real^M->bool)` ASSUME_TAC THENL + [EXPAND_TAC "s'" THEN + REWRITE_TAC[SET_RULE `~(x IN s) <=> x IN (UNIV DIFF s)`] THEN + MATCH_MP_TAC CLOSED_COMPACT_PROJECTION THEN + ASM_REWRITE_TAC[GSYM OPEN_CLOSED; COMPACT_INTERVAL]; + ALL_TAC] THEN + MP_TAC(ISPECL [`s:real^M->bool`; `s':real^M->bool`; + `vec 1:real^1`; `vec 0:real^1`] URYSOHN) THEN + ASM_REWRITE_TAC[] THEN ANTS_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + ONCE_REWRITE_TAC[SEGMENT_SYM] THEN + REWRITE_TAC[SEGMENT_1; DROP_VEC; REAL_POS] THEN + DISCH_THEN(X_CHOOSE_THEN `a:real^M->real^1` STRIP_ASSUME_TAC) THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [retract_of]) THEN + REWRITE_TAC[retraction; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `r:real^N->real^N` THEN STRIP_TAC THEN + EXISTS_TAC + `(r:real^N->real^N) o + (\x. (k:real^(1,M)finite_sum->real^N) (pastecart (a x) x))` THEN + REWRITE_TAC[o_THM; IMAGE_o] THEN CONJ_TAC THENL [ALL_TAC; ASM SET_TAC[]] THEN + MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN CONJ_TAC THENL + [GEN_REWRITE_TAC LAND_CONV [GSYM o_DEF] THEN + MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN CONJ_TAC THENL + [MATCH_MP_TAC CONTINUOUS_ON_PASTECART THEN + REWRITE_TAC[CONTINUOUS_ON_ID] THEN + ASM_MESON_TAC[CONTINUOUS_ON_SUBSET; SUBSET_UNIV]; + ASM_MESON_TAC[CONTINUOUS_ON_SUBSET; SUBSET_UNIV]]; + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET)) THEN + ASM SET_TAC[]]);; + +let NULLHOMOTOPIC_INTO_ANR_EXTENSION = prove + (`!f:real^M->real^N s t u. + closed s /\ f continuous_on s /\ ~(s = {}) /\ + IMAGE f s SUBSET t /\ open u /\ t retract_of u + ==> ((?c. homotopic_with (\x. T) (s,t) f (\x. c)) <=> + (?g. g continuous_on (:real^M) /\ + IMAGE g (:real^M) SUBSET t /\ + !x. x IN s ==> g x = f x))`, + REPEAT STRIP_TAC THEN EQ_TAC THEN STRIP_TAC THENL + [MATCH_MP_TAC BORSUK_HOMOTOPY_EXTENSION THEN + ONCE_REWRITE_TAC[HOMOTOPIC_WITH_SYM] THEN + MAP_EVERY EXISTS_TAC [`(\x. c):real^M->real^N`; `u:real^N->bool`] THEN + ASM_REWRITE_TAC[CLOSED_UNIV; CONTINUOUS_ON_CONST] THEN + FIRST_X_ASSUM(MP_TAC o MATCH_MP HOMOTOPIC_WITH_IMP_SUBSET) THEN + ASM SET_TAC[]; + MP_TAC(ISPECL [`g:real^M->real^N`; `(:real^M)`; `t:real^N->bool`] + NULLHOMOTOPIC_FROM_CONTRACTIBLE) THEN + ASM_REWRITE_TAC[CONTRACTIBLE_UNIV] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `c:real^N` THEN + DISCH_TAC THEN MATCH_MP_TAC HOMOTOPIC_WITH_EQ THEN + MAP_EVERY EXISTS_TAC [`g:real^M->real^N`; `(\x. c):real^M->real^N`] THEN + ASM_SIMP_TAC[] THEN MATCH_MP_TAC HOMOTOPIC_WITH_SUBSET_LEFT THEN + EXISTS_TAC `(:real^M)` THEN ASM_REWRITE_TAC[SUBSET_UNIV]]);; + +let NULLHOMOTOPIC_INTO_RELATIVE_FRONTIER_EXTENSION = prove + (`!f:real^M->real^N s t. + closed s /\ f continuous_on s /\ ~(s = {}) /\ + IMAGE f s SUBSET relative_frontier t /\ convex t /\ bounded t + ==> ((?c. homotopic_with (\x. T) (s,relative_frontier t) f (\x. c)) <=> + (?g. g continuous_on (:real^M) /\ + IMAGE g (:real^M) SUBSET relative_frontier t /\ + !x. x IN s ==> g x = f x))`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC NULLHOMOTOPIC_INTO_ANR_EXTENSION THEN + MP_TAC(ISPEC `t:real^N->bool` ANR_RELATIVE_FRONTIER_CONVEX) THEN + ASM_REWRITE_TAC[]);; + +let NULLHOMOTOPIC_INTO_SPHERE_EXTENSION = prove + (`!f:real^M->real^N s a r. + closed s /\ f continuous_on s /\ ~(s = {}) /\ IMAGE f s SUBSET sphere(a,r) + ==> ((?c. homotopic_with (\x. T) (s,sphere(a,r)) f (\x. c)) <=> + (?g. g continuous_on (:real^M) /\ + IMAGE g (:real^M) SUBSET sphere(a,r) /\ + !x. x IN s ==> g x = f x))`, + REPEAT GEN_TAC THEN + MP_TAC(ISPECL [`a:real^N`; `r:real`] RELATIVE_FRONTIER_CBALL) THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[] THENL + [ASM_SIMP_TAC[SPHERE_SING] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC(TAUT `p /\ q ==> (p <=> q)`) THEN CONJ_TAC THENL + [EXISTS_TAC `a:real^N` THEN SIMP_TAC[HOMOTOPIC_WITH; PCROSS] THEN + EXISTS_TAC `\y:real^(1,M)finite_sum. (a:real^N)`; + EXISTS_TAC `(\x. a):real^M->real^N`] THEN + REWRITE_TAC[CONTINUOUS_ON_CONST] THEN ASM SET_TAC[]; + DISCH_THEN(SUBST1_TAC o SYM) THEN STRIP_TAC THEN + MATCH_MP_TAC NULLHOMOTOPIC_INTO_RELATIVE_FRONTIER_EXTENSION THEN + ASM_REWRITE_TAC[CONVEX_CBALL; BOUNDED_CBALL]]);; + +let ABSOLUTE_RETRACT_CONTRACTIBLE_ANR = prove + (`!s t. closed s /\ contractible s /\ ~(s = {}) /\ s retract_of t /\ open t + ==> s retract_of (:real^N)`, + REPEAT STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [contractible]) THEN + ONCE_REWRITE_TAC[HOMOTOPIC_WITH_SYM] THEN + DISCH_THEN(X_CHOOSE_TAC `a:real^N`) THEN + REWRITE_TAC[retract_of; retraction; SUBSET_UNIV] THEN + MATCH_MP_TAC BORSUK_HOMOTOPY_EXTENSION THEN + MAP_EVERY EXISTS_TAC [`(\x. a):real^N->real^N`; `t:real^N->bool`] THEN + ASM_SIMP_TAC[CLOSED_UNIV; IMAGE_ID] THEN + REWRITE_TAC[SUBSET_REFL; CONTINUOUS_ON_ID; CONTINUOUS_ON_CONST] THEN + FIRST_X_ASSUM(MP_TAC o MATCH_MP HOMOTOPIC_WITH_IMP_SUBSET) THEN + ASM SET_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* Preservation of fixpoints under (more general notion of) retraction. *) +(* ------------------------------------------------------------------------- *) + +let INVERTIBLE_FIXPOINT_PROPERTY = prove + (`!s:real^M->bool t:real^N->bool i r. + i continuous_on t /\ IMAGE i t SUBSET s /\ + r continuous_on s /\ IMAGE r s SUBSET t /\ + (!y. y IN t ==> (r(i(y)) = y)) + ==> (!f. f continuous_on s /\ IMAGE f s SUBSET s + ==> ?x. x IN s /\ (f x = x)) + ==> !g. g continuous_on t /\ IMAGE g t SUBSET t + ==> ?y. y IN t /\ (g y = y)`, + REPEAT STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC + `(i:real^N->real^M) o (g:real^N->real^N) o (r:real^M->real^N)`) THEN + ANTS_TAC THENL + [ASM_MESON_TAC[CONTINUOUS_ON_SUBSET; CONTINUOUS_ON_COMPOSE; IMAGE_SUBSET; + SUBSET_TRANS; IMAGE_o]; + RULE_ASSUM_TAC(REWRITE_RULE[SUBSET; FORALL_IN_IMAGE]) THEN + REWRITE_TAC[o_THM] THEN ASM_MESON_TAC[]]);; + +let HOMEOMORPHIC_FIXPOINT_PROPERTY = prove + (`!s t. s homeomorphic t + ==> ((!f. f continuous_on s /\ IMAGE f s SUBSET s + ==> ?x. x IN s /\ (f x = x)) <=> + (!g. g continuous_on t /\ IMAGE g t SUBSET t + ==> ?y. y IN t /\ (g y = y)))`, + REWRITE_TAC[homeomorphic; homeomorphism] THEN REPEAT STRIP_TAC THEN + EQ_TAC THEN MATCH_MP_TAC INVERTIBLE_FIXPOINT_PROPERTY THEN + ASM_MESON_TAC[SUBSET_REFL]);; + +let RETRACT_FIXPOINT_PROPERTY = prove + (`!s t:real^N->bool. + t retract_of s /\ + (!f. f continuous_on s /\ IMAGE f s SUBSET s + ==> ?x. x IN s /\ (f x = x)) + ==> !g. g continuous_on t /\ IMAGE g t SUBSET t + ==> ?y. y IN t /\ (g y = y)`, + REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + MATCH_MP_TAC INVERTIBLE_FIXPOINT_PROPERTY THEN + EXISTS_TAC `\x:real^N. x` THEN REWRITE_TAC[CONTINUOUS_ON_ID] THEN + POP_ASSUM MP_TAC THEN REWRITE_TAC[retract_of] THEN + MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC THEN REWRITE_TAC[retraction] THEN + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE]);; + +(* ------------------------------------------------------------------------- *) +(* So the Brouwer theorem for any set with nonempty interior. *) +(* ------------------------------------------------------------------------- *) + +let BROUWER_WEAK = prove + (`!f:real^N->real^N s. + compact s /\ convex s /\ ~(interior s = {}) /\ + f continuous_on s /\ IMAGE f s SUBSET s + ==> ?x. x IN s /\ f x = x`, + GEN_TAC THEN ONCE_REWRITE_TAC + [TAUT `a /\ b /\ c /\ d ==> e <=> a /\ b /\ c ==> d ==> e`] THEN + GEN_TAC THEN STRIP_TAC THEN + MP_TAC(ISPECL [`interval[vec 0:real^N,vec 1]`; `s:real^N->bool`] + HOMEOMORPHIC_CONVEX_COMPACT) THEN + ANTS_TAC THENL + [ASM_REWRITE_TAC[CONVEX_INTERVAL; COMPACT_INTERVAL] THEN + REWRITE_TAC[INTERIOR_CLOSED_INTERVAL; INTERVAL_EQ_EMPTY] THEN + MESON_TAC[VEC_COMPONENT; REAL_ARITH `~(&1 <= &0)`]; + DISCH_THEN(MP_TAC o MATCH_MP HOMEOMORPHIC_FIXPOINT_PROPERTY) THEN + REWRITE_TAC[BROUWER_CUBE] THEN SIMP_TAC[]]);; + +(* ------------------------------------------------------------------------- *) +(* And in particular for a closed ball. *) +(* ------------------------------------------------------------------------- *) + +let BROUWER_BALL = prove + (`!f:real^N->real^N a e. + &0 < e /\ + f continuous_on cball(a,e) /\ IMAGE f (cball(a,e)) SUBSET (cball(a,e)) + ==> ?x. x IN cball(a,e) /\ (f x = x)`, + ASM_SIMP_TAC[BROUWER_WEAK; CONVEX_CBALL; COMPACT_CBALL; INTERIOR_CBALL; + REAL_LT_IMP_LE; REAL_NOT_LE; BALL_EQ_EMPTY]);; + +(* ------------------------------------------------------------------------- *) +(* Still more general form; could derive this directly without using the *) +(* rather involved HOMEOMORPHIC_CONVEX_COMPACT theorem, just using *) +(* a scaling and translation to put the set inside the unit cube. *) +(* ------------------------------------------------------------------------- *) + +let BROUWER = prove + (`!f:real^N->real^N s. + compact s /\ convex s /\ ~(s = {}) /\ + f continuous_on s /\ IMAGE f s SUBSET s + ==> ?x. x IN s /\ f x = x`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN `?e. &0 < e /\ s SUBSET cball(vec 0:real^N,e)` + STRIP_ASSUME_TAC THENL + [REWRITE_TAC[SUBSET; IN_CBALL; NORM_ARITH `dist(vec 0,x) = norm(x)`] THEN + ASM_MESON_TAC[BOUNDED_POS; COMPACT_IMP_BOUNDED]; + ALL_TAC] THEN + SUBGOAL_THEN + `?x:real^N. x IN cball(vec 0,e) /\ (f o closest_point s) x = x` + MP_TAC THENL + [MATCH_MP_TAC BROUWER_BALL THEN ASM_REWRITE_TAC[] THEN CONJ_TAC THENL + [REWRITE_TAC[ETA_AX] THEN MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN + ASM_SIMP_TAC[CONTINUOUS_ON_CLOSEST_POINT; COMPACT_IMP_CLOSED] THEN + MATCH_MP_TAC CONTINUOUS_ON_SUBSET THEN EXISTS_TAC `s:real^N->bool` THEN + ASM_REWRITE_TAC[SUBSET; FORALL_IN_IMAGE]; + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE] THEN X_GEN_TAC `x:real^N` THEN + REPEAT STRIP_TAC THEN + REPEAT(FIRST_X_ASSUM(MATCH_MP_TAC o REWRITE_RULE[SUBSET])) THEN + REWRITE_TAC[o_THM; IN_IMAGE] THEN + EXISTS_TAC `closest_point s x:real^N` THEN + ASM_SIMP_TAC[COMPACT_IMP_CLOSED; CLOSEST_POINT_IN_SET]] THEN + ASM_SIMP_TAC[COMPACT_IMP_CLOSED; CLOSEST_POINT_IN_SET]; + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `x:real^N` THEN + REWRITE_TAC[o_THM] THEN STRIP_TAC THEN + RULE_ASSUM_TAC(REWRITE_RULE[SUBSET; FORALL_IN_IMAGE]) THEN + ASM_MESON_TAC[CLOSEST_POINT_SELF; + CLOSEST_POINT_IN_SET; COMPACT_IMP_CLOSED]]);; + +(* ------------------------------------------------------------------------- *) +(* So we get the no-retraction theorem, first for a ball, then more general. *) +(* ------------------------------------------------------------------------- *) + +let NO_RETRACTION_CBALL = prove + (`!a:real^N e. &0 < e ==> ~(sphere(a,e) retract_of cball(a,e))`, + REPEAT GEN_TAC THEN DISCH_TAC THEN + DISCH_THEN(MP_TAC o MATCH_MP(REWRITE_RULE[IMP_CONJ] + RETRACT_FIXPOINT_PROPERTY)) THEN + ASM_SIMP_TAC[BROUWER_BALL] THEN REWRITE_TAC[NOT_FORALL_THM] THEN + EXISTS_TAC `\x:real^N. &2 % a - x` THEN REWRITE_TAC[NOT_IMP] THEN + SIMP_TAC[CONTINUOUS_ON_SUB; CONTINUOUS_ON_ID; CONTINUOUS_ON_CONST] THEN + ASM_SIMP_TAC[SUBSET; FORALL_IN_IMAGE; IN_SPHERE] THEN + SIMP_TAC[dist; VECTOR_ARITH `a - (&2 % a - x) = --(a - x)`; NORM_NEG] THEN + REWRITE_TAC[VECTOR_ARITH `(&2 % a - y = y) <=> (a - y = vec 0)`] THEN + ASM_MESON_TAC[NORM_0; REAL_LT_REFL]);; + +let FRONTIER_SUBSET_RETRACTION = prove + (`!s:real^N->bool t r. + bounded s /\ + frontier s SUBSET t /\ + r continuous_on (closure s) /\ + IMAGE r s SUBSET t /\ + (!x. x IN t ==> r x = x) + ==> s SUBSET t`, + ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN + REWRITE_TAC[SET_RULE `~(s SUBSET t) <=> ?x. x IN s /\ ~(x IN t)`] THEN + REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; LEFT_IMP_EXISTS_THM] THEN + REPLICATE_TAC 3 GEN_TAC THEN X_GEN_TAC `a:real^N` THEN REPEAT STRIP_TAC THEN + ABBREV_TAC `q = \z:real^N. if z IN closure s then r(z) else z` THEN + SUBGOAL_THEN + `(q:real^N->real^N) continuous_on + closure(s) UNION closure((:real^N) DIFF s)` + MP_TAC THENL + [EXPAND_TAC "q" THEN MATCH_MP_TAC CONTINUOUS_ON_CASES THEN + ASM_REWRITE_TAC[CLOSED_CLOSURE; CONTINUOUS_ON_ID] THEN + REWRITE_TAC[TAUT `p /\ ~p <=> F`] THEN X_GEN_TAC `z:real^N` THEN + REWRITE_TAC[CLOSURE_COMPLEMENT; IN_DIFF; IN_UNIV] THEN STRIP_TAC THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN + RULE_ASSUM_TAC(REWRITE_RULE[SUBSET; frontier; IN_DIFF]) THEN + ASM_MESON_TAC[]; + ALL_TAC] THEN + SUBGOAL_THEN `closure(s) UNION closure((:real^N) DIFF s) = (:real^N)` + SUBST1_TAC THENL + [MATCH_MP_TAC(SET_RULE + `s SUBSET closure s /\ t SUBSET closure t /\ s UNION t = UNIV + ==> closure s UNION closure t = UNIV`) THEN + REWRITE_TAC[CLOSURE_SUBSET] THEN SET_TAC[]; + DISCH_TAC] THEN + FIRST_ASSUM(X_CHOOSE_THEN `B:real` STRIP_ASSUME_TAC o SPEC `a:real^N` o + MATCH_MP BOUNDED_SUBSET_BALL o MATCH_MP BOUNDED_CLOSURE) THEN + SUBGOAL_THEN `!x. ~((q:real^N->real^N) x = a)` ASSUME_TAC THENL + [GEN_TAC THEN EXPAND_TAC "q" THEN COND_CASES_TAC THENL + [ASM_CASES_TAC `(x:real^N) IN s` THENL [ASM SET_TAC[]; ALL_TAC] THEN + SUBGOAL_THEN `(x:real^N) IN t` (fun th -> ASM_MESON_TAC[th]) THEN + UNDISCH_TAC `frontier(s:real^N->bool) SUBSET t` THEN + REWRITE_TAC[SUBSET; frontier; IN_DIFF] THEN + DISCH_THEN MATCH_MP_TAC THEN ASM_MESON_TAC[SUBSET; INTERIOR_SUBSET]; + ASM_MESON_TAC[SUBSET; INTERIOR_SUBSET; CLOSURE_SUBSET]]; + ALL_TAC] THEN + MP_TAC(ISPECL [`a:real^N`; `B:real`] NO_RETRACTION_CBALL) THEN + ASM_REWRITE_TAC[retract_of; GSYM FRONTIER_CBALL] THEN + EXISTS_TAC `(\y. a + B / norm(y - a) % (y - a)) o (q:real^N->real^N)` THEN + REWRITE_TAC[retraction; FRONTIER_SUBSET_EQ; CLOSED_CBALL] THEN + REWRITE_TAC[FRONTIER_CBALL; SUBSET; FORALL_IN_IMAGE; FORALL_IN_GSPEC] THEN + REWRITE_TAC[IN_SPHERE; DIST_0] THEN REPEAT CONJ_TAC THENL + [MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN CONJ_TAC THENL + [ASM_MESON_TAC[CONTINUOUS_ON_SUBSET; SUBSET_UNIV]; ALL_TAC] THEN + MATCH_MP_TAC CONTINUOUS_ON_ADD THEN REWRITE_TAC[CONTINUOUS_ON_CONST] THEN + MATCH_MP_TAC CONTINUOUS_ON_MUL THEN + SIMP_TAC[CONTINUOUS_ON_SUB; CONTINUOUS_ON_ID; CONTINUOUS_ON_CONST] THEN + REWRITE_TAC[o_DEF; real_div; LIFT_CMUL] THEN + MATCH_MP_TAC CONTINUOUS_ON_CMUL THEN + MATCH_MP_TAC(REWRITE_RULE[o_DEF] CONTINUOUS_ON_INV) THEN + ASM_REWRITE_TAC[FORALL_IN_IMAGE; NORM_EQ_0; VECTOR_SUB_EQ] THEN + SUBGOAL_THEN `(\x:real^N. lift(norm(x - a))) = (lift o norm) o (\x. x - a)` + SUBST1_TAC THENL [REWRITE_TAC[FUN_EQ_THM; o_THM]; ALL_TAC] THEN + MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN + ASM_SIMP_TAC[CONTINUOUS_ON_SUB; CONTINUOUS_ON_ID; CONTINUOUS_ON_CONST] THEN + REWRITE_TAC[CONTINUOUS_ON_LIFT_NORM]; + REWRITE_TAC[o_THM; NORM_MUL; REAL_ABS_DIV; REAL_ABS_NORM; + NORM_ARITH `dist(a,a + b) = norm b`] THEN + ASM_SIMP_TAC[REAL_DIV_RMUL; VECTOR_SUB_EQ; NORM_EQ_0] THEN + ASM_REAL_ARITH_TAC; + X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN REWRITE_TAC[o_THM] THEN + EXPAND_TAC "q" THEN REWRITE_TAC[] THEN COND_CASES_TAC THENL + [RULE_ASSUM_TAC(REWRITE_RULE[SUBSET; IN_BALL]) THEN + ASM_MESON_TAC[REAL_LT_REFL]; + REWRITE_TAC[NORM_ARITH `norm(x - a) = dist(a,x)`] THEN + ASM_SIMP_TAC[REAL_DIV_REFL; REAL_LT_IMP_NZ; VECTOR_MUL_LID] THEN + VECTOR_ARITH_TAC]]);; + +let NO_RETRACTION_FRONTIER_BOUNDED = prove + (`!s:real^N->bool. + bounded s /\ ~(interior s = {}) ==> ~((frontier s) retract_of s)`, + GEN_TAC THEN STRIP_TAC THEN REWRITE_TAC[retract_of; retraction] THEN + REWRITE_TAC[FRONTIER_SUBSET_EQ] THEN + DISCH_THEN(X_CHOOSE_THEN `r:real^N->real^N` STRIP_ASSUME_TAC) THEN + MP_TAC(ISPECL [`s:real^N->bool`; `frontier s:real^N->bool`; + `r:real^N->real^N`] FRONTIER_SUBSET_RETRACTION) THEN + ASM_SIMP_TAC[CLOSURE_CLOSED; SUBSET_REFL] THEN REWRITE_TAC[frontier] THEN + MP_TAC(ISPEC `s:real^N->bool` INTERIOR_SUBSET) THEN ASM SET_TAC[]);; + +let COMPACT_SUBSET_FRONTIER_RETRACTION = prove + (`!f:real^N->real^N s. + compact s /\ f continuous_on s /\ (!x. x IN frontier s ==> f x = x) + ==> s SUBSET IMAGE f s`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`s UNION (IMAGE f s):real^N->bool`; `vec 0:real^N`] + BOUNDED_SUBSET_BALL) THEN + ASM_SIMP_TAC[BOUNDED_UNION; COMPACT_IMP_BOUNDED; + COMPACT_CONTINUOUS_IMAGE; UNION_SUBSET] THEN + DISCH_THEN(X_CHOOSE_THEN `r:real` STRIP_ASSUME_TAC) THEN + ABBREV_TAC `g = \x:real^N. if x IN s then f(x) else x` THEN + SUBGOAL_THEN `(g:real^N->real^N) continuous_on (:real^N)` ASSUME_TAC THENL + [SUBGOAL_THEN `(:real^N) = s UNION closure((:real^N) DIFF s)` SUBST1_TAC + THENL + [MATCH_MP_TAC(SET_RULE `UNIV DIFF s SUBSET t ==> UNIV = s UNION t`) THEN + REWRITE_TAC[CLOSURE_SUBSET]; + ALL_TAC] THEN + EXPAND_TAC "g" THEN MATCH_MP_TAC CONTINUOUS_ON_CASES THEN + ASM_SIMP_TAC[CLOSED_CLOSURE; CONTINUOUS_ON_ID; COMPACT_IMP_CLOSED] THEN + REWRITE_TAC[CLOSURE_COMPLEMENT; IN_DIFF; IN_UNIV] THEN + REWRITE_TAC[TAUT `p /\ ~p <=> F`] THEN REPEAT STRIP_TAC THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[frontier; IN_DIFF] THEN + ASM_SIMP_TAC[CLOSURE_CLOSED; COMPACT_IMP_CLOSED]; + ALL_TAC] THEN + REWRITE_TAC[SUBSET] THEN X_GEN_TAC `p:real^N` THEN DISCH_TAC THEN + SUBGOAL_THEN + `?h:real^N->real^N. + retraction (UNIV DELETE p,sphere(vec 0,r)) h` + STRIP_ASSUME_TAC THENL + [REWRITE_TAC[GSYM retract_of] THEN + MATCH_MP_TAC SPHERE_RETRACT_OF_PUNCTURED_UNIVERSE_GEN THEN + ASM SET_TAC[]; + ALL_TAC] THEN + MP_TAC(ISPECL [`vec 0:real^N`; `r:real`] NO_RETRACTION_CBALL) THEN + ASM_REWRITE_TAC[retract_of; NOT_EXISTS_THM] THEN + DISCH_THEN(MP_TAC o SPEC `(h:real^N->real^N) o (g:real^N->real^N)`) THEN + ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN DISCH_TAC THEN REWRITE_TAC[] THEN + REWRITE_TAC[retraction] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [retraction]) THEN + SIMP_TAC[SUBSET; IN_SPHERE; IN_CBALL; REAL_EQ_IMP_LE] THEN + REWRITE_TAC[FORALL_IN_IMAGE; IN_DELETE; IN_UNIV; o_THM] THEN STRIP_TAC THEN + SUBGOAL_THEN + `!x. x IN cball (vec 0,r) ==> ~((g:real^N->real^N) x = p)` + ASSUME_TAC THENL + [X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN EXPAND_TAC "g" THEN + COND_CASES_TAC THEN ASM SET_TAC[]; + ALL_TAC] THEN + ASM_SIMP_TAC[] THEN REPEAT STRIP_TAC THENL + [MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN CONJ_TAC THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET)) THEN + ASM_REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; IN_UNIV; IN_DELETE]; + SUBGOAL_THEN `(g:real^N->real^N) x = x` (fun th -> ASM_SIMP_TAC[th]) THEN + EXPAND_TAC "g" THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN + ASM_MESON_TAC[IN_BALL; REAL_LT_REFL; SUBSET]]);; + +let NOT_ABSOLUTE_RETRACT_COBOUNDED = prove + (`!s. bounded s /\ ((:real^N) DIFF s) retract_of (:real^N) ==> s = {}`, + GEN_TAC THEN DISCH_TAC THEN + MATCH_MP_TAC(SET_RULE `(!x. x IN s ==> F) ==> s = {}`) THEN + X_GEN_TAC `a:real^N` THEN POP_ASSUM MP_TAC THEN + GEOM_ORIGIN_TAC `a:real^N` THEN REPEAT STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `vec 0:real^N` o + MATCH_MP BOUNDED_SUBSET_BALL) THEN + DISCH_THEN(X_CHOOSE_THEN `r:real` STRIP_ASSUME_TAC) THEN + FIRST_ASSUM(MP_TAC o SPEC `vec 0:real^N` o MATCH_MP NO_RETRACTION_CBALL) THEN + REWRITE_TAC[] THEN MATCH_MP_TAC RETRACT_OF_SUBSET THEN + EXISTS_TAC `(:real^N)` THEN SIMP_TAC[SUBSET_UNIV; SPHERE_SUBSET_CBALL] THEN + MATCH_MP_TAC RETRACT_OF_TRANS THEN EXISTS_TAC `(:real^N) DIFF s` THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC RETRACT_OF_SUBSET THEN + EXISTS_TAC `(:real^N) DELETE (vec 0)` THEN + ASM_SIMP_TAC[SPHERE_RETRACT_OF_PUNCTURED_UNIVERSE] THEN + CONJ_TAC THENL [ALL_TAC; ASM SET_TAC[]] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [SUBSET]) THEN + REWRITE_TAC[SUBSET; IN_BALL; IN_SPHERE; IN_DIFF; IN_UNIV] THEN + MESON_TAC[REAL_LT_REFL]);; + +(* ------------------------------------------------------------------------- *) +(* Similarly we get noncontractibility of a non-trivial sphere. *) +(* ------------------------------------------------------------------------- *) + +let CONTRACTIBLE_SPHERE = prove + (`!a:real^N r. contractible(sphere(a,r)) <=> r <= &0`, + REPEAT GEN_TAC THEN REWRITE_TAC[contractible; GSYM REAL_NOT_LT] THEN + REWRITE_TAC[NULLHOMOTOPIC_FROM_SPHERE_EXTENSION] THEN + ASM_CASES_TAC `&0 < r` THEN ASM_REWRITE_TAC[] THENL + [FIRST_ASSUM(MP_TAC o ISPEC `a:real^N` o MATCH_MP NO_RETRACTION_CBALL) THEN + SIMP_TAC[retract_of; retraction; SPHERE_SUBSET_CBALL]; + RULE_ASSUM_TAC(REWRITE_RULE[REAL_NOT_LT]) THEN + EXISTS_TAC `\x:real^N. x` THEN REWRITE_TAC[CONTINUOUS_ON_ID; IMAGE_ID] THEN + REWRITE_TAC[SUBSET; IN_CBALL; IN_SPHERE; IN_ELIM_THM] THEN + POP_ASSUM MP_TAC THEN NORM_ARITH_TAC]);; + +(* ------------------------------------------------------------------------- *) +(* We also get fixpoint properties for suitable ANRs. *) +(* ------------------------------------------------------------------------- *) + +let BROUWER_INESSENTIAL_ANR = prove + (`!f:real^N->real^N s t. + compact s /\ ~(s = {}) /\ s retract_of t /\ open t /\ + f continuous_on s /\ IMAGE f s SUBSET s /\ + (?a. homotopic_with (\x. T) (s,s) f (\x. a)) + ==> ?x. x IN s /\ f x = x`, + ONCE_REWRITE_TAC[HOMOTOPIC_WITH_SYM] THEN REPEAT STRIP_TAC THEN + FIRST_ASSUM(X_CHOOSE_TAC `r:real` o SPEC `vec 0:real^N` o + MATCH_MP BOUNDED_SUBSET_CBALL o MATCH_MP COMPACT_IMP_BOUNDED) THEN + MP_TAC(ISPECL + [`(\x. a):real^N->real^N`; `f:real^N->real^N`; + `s:real^N->bool`; `cball(vec 0:real^N,r)`; `s:real^N->bool`; + `t:real^N->bool`] BORSUK_HOMOTOPY_EXTENSION) THEN + ASM_SIMP_TAC[COMPACT_IMP_CLOSED; CONTINUOUS_ON_CONST; CLOSED_CBALL] THEN + FIRST_X_ASSUM(ASSUME_TAC o MATCH_MP HOMOTOPIC_WITH_IMP_SUBSET) THEN + ANTS_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + DISCH_THEN(X_CHOOSE_THEN `g:real^N->real^N` STRIP_ASSUME_TAC) THEN + MP_TAC(ISPECL [`g:real^N->real^N`; `cball(vec 0:real^N,r)`] + BROUWER) THEN + ASM_SIMP_TAC[COMPACT_CBALL; CONVEX_CBALL; CBALL_EQ_EMPTY] THEN + ASM_SIMP_TAC[REAL_ARITH `&0 < r ==> ~(r < &0)`] THEN ASM SET_TAC[]);; + +let BROUWER_CONTRACTIBLE_ANR = prove + (`!f:real^N->real^N s t. + compact s /\ contractible s /\ ~(s = {}) /\ s retract_of t /\ open t /\ + f continuous_on s /\ IMAGE f s SUBSET s + ==> ?x. x IN s /\ f x = x`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC BROUWER_INESSENTIAL_ANR THEN + EXISTS_TAC `t:real^N->bool` THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC NULLHOMOTOPIC_FROM_CONTRACTIBLE THEN ASM_REWRITE_TAC[]);; + +let FIXED_POINT_INESSENTIAL_SPHERE_MAP = prove + (`!f a:real^N r c. + &0 < r /\ homotopic_with (\x. T) (sphere(a,r),sphere(a,r)) f (\x. c) + ==> ?x. x IN sphere(a,r) /\ f x = x`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC BROUWER_INESSENTIAL_ANR THEN + EXISTS_TAC `(:real^N) DELETE a` THEN + ASM_SIMP_TAC[SPHERE_RETRACT_OF_PUNCTURED_UNIVERSE] THEN + SIMP_TAC[SPHERE_EQ_EMPTY; COMPACT_SPHERE; OPEN_DELETE; OPEN_UNIV] THEN + FIRST_ASSUM(STRIP_ASSUME_TAC o MATCH_MP HOMOTOPIC_WITH_IMP_CONTINUOUS) THEN + FIRST_ASSUM(STRIP_ASSUME_TAC o MATCH_MP HOMOTOPIC_WITH_IMP_SUBSET) THEN + ASM_SIMP_TAC[REAL_NOT_LT; REAL_LT_IMP_LE] THEN ASM_MESON_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* Some other related fixed-point theorems. *) +(* ------------------------------------------------------------------------- *) + +let SCHAUDER_PROJECTION = prove + (`!s:real^N->bool e. + compact s /\ &0 < e + ==> ?t f. FINITE t /\ t SUBSET s /\ + f continuous_on s /\ IMAGE f s SUBSET (convex hull t) /\ + (!x. x IN s ==> norm(f x - x) < e)`, + REPEAT STRIP_TAC THEN FIRST_ASSUM + (MP_TAC o SPEC `e:real` o MATCH_MP COMPACT_IMP_TOTALLY_BOUNDED) THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC MONO_EXISTS THEN + X_GEN_TAC `t:real^N->bool` THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + ABBREV_TAC `g = \p x:real^N. max (&0) (e - norm(x - p))` THEN + SUBGOAL_THEN + `!x. x IN s ==> &0 < sum t (\p. (g:real^N->real^N->real) p x)` + ASSUME_TAC THENL + [REPEAT STRIP_TAC THEN MATCH_MP_TAC SUM_POS_LT THEN + ASM_REWRITE_TAC[] THEN EXPAND_TAC "g" THEN + REWRITE_TAC[REAL_ARITH `&0 <= max (&0) b`] THEN + REWRITE_TAC[REAL_ARITH `&0 < max (&0) b <=> &0 < b`; REAL_SUB_LT] THEN + UNDISCH_TAC `s SUBSET UNIONS (IMAGE (\x:real^N. ball(x,e)) t)` THEN + REWRITE_TAC[SUBSET; UNIONS_IMAGE; IN_BALL; IN_ELIM_THM] THEN + DISCH_THEN(MP_TAC o SPEC `x:real^N`) THEN ASM_REWRITE_TAC[dist; NORM_SUB]; + ALL_TAC] THEN + EXISTS_TAC + `(\x. inv(sum t (\p. g p x)) % vsum t (\p. g p x % p)):real^N->real^N` THEN + REPEAT CONJ_TAC THENL + [MATCH_MP_TAC CONTINUOUS_ON_MUL THEN REWRITE_TAC[o_DEF] THEN CONJ_TAC THENL + [MATCH_MP_TAC(REWRITE_RULE[o_DEF] CONTINUOUS_ON_INV) THEN + ASM_SIMP_TAC[REAL_LT_IMP_NZ; LIFT_SUM; o_DEF]; + ALL_TAC] THEN + MATCH_MP_TAC CONTINUOUS_ON_VSUM THEN ASM_REWRITE_TAC[] THEN + X_GEN_TAC `y:real^N` THEN DISCH_TAC THENL + [ALL_TAC; MATCH_MP_TAC CONTINUOUS_ON_MUL] THEN + REWRITE_TAC[o_DEF; CONTINUOUS_ON_CONST] THEN + EXPAND_TAC "g" THEN + (SUBGOAL_THEN + `(\x. lift (max (&0) (e - norm (x - y:real^N)))) = + (\x. (lambda i. max (lift(&0)$i) (lift(e - norm (x - y))$i)))` + SUBST1_TAC THENL + [SIMP_TAC[CART_EQ; LAMBDA_BETA; FUN_EQ_THM] THEN + REWRITE_TAC[DIMINDEX_1; FORALL_1; GSYM drop; LIFT_DROP]; + MATCH_MP_TAC CONTINUOUS_ON_MAX] THEN + REWRITE_TAC[CONTINUOUS_ON_CONST; LIFT_SUB] THEN + MATCH_MP_TAC CONTINUOUS_ON_SUB THEN REWRITE_TAC[CONTINUOUS_ON_CONST] THEN + REWRITE_TAC[ONCE_REWRITE_RULE[NORM_SUB] (GSYM dist)] THEN + REWRITE_TAC[REWRITE_RULE[o_DEF] CONTINUOUS_ON_LIFT_DIST]); + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; GSYM VSUM_LMUL; VECTOR_MUL_ASSOC] THEN + X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN MATCH_MP_TAC CONVEX_VSUM THEN + ASM_SIMP_TAC[HULL_INC; CONVEX_CONVEX_HULL; SUM_LMUL] THEN + ASM_SIMP_TAC[REAL_LT_IMP_NZ; REAL_MUL_LINV] THEN + X_GEN_TAC `y:real^N` THEN DISCH_TAC THEN MATCH_MP_TAC REAL_LE_MUL THEN + ASM_SIMP_TAC[REAL_LE_INV_EQ; REAL_LT_IMP_LE] THEN + EXPAND_TAC "g" THEN REAL_ARITH_TAC; + X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN + REWRITE_TAC[] THEN ONCE_REWRITE_TAC[NORM_SUB] THEN + REWRITE_TAC[REWRITE_RULE[dist] (GSYM IN_BALL)] THEN + REWRITE_TAC[GSYM VSUM_LMUL; VECTOR_MUL_ASSOC] THEN + MATCH_MP_TAC CONVEX_VSUM_STRONG THEN + ASM_REWRITE_TAC[CONVEX_BALL; SUM_LMUL; REAL_ENTIRE] THEN + ASM_SIMP_TAC[REAL_LT_IMP_NZ; REAL_MUL_LINV; REAL_LT_INV_EQ; + REAL_LE_MUL_EQ] THEN + X_GEN_TAC `y:real^N` THEN DISCH_TAC THEN + EXPAND_TAC "g" THEN REWRITE_TAC[IN_BALL; dist; NORM_SUB] THEN + REAL_ARITH_TAC]);; + +let SCHAUDER = prove + (`!f s t:real^N->bool. + convex s /\ ~(s = {}) /\ t SUBSET s /\ compact t /\ + f continuous_on s /\ IMAGE f s SUBSET t + ==> ?x. x IN s /\ f x = x`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC(TAUT `(~p ==> F) ==> p`) THEN + DISCH_TAC THEN + MP_TAC(ISPECL [`\x:real^N. f x - x`; `convex hull t:real^N->bool`] + BROUWER_COMPACTNESS_LEMMA) THEN + SUBGOAL_THEN `(t:real^N->bool) SUBSET convex hull t` ASSUME_TAC THENL + [REWRITE_TAC[HULL_SUBSET]; ALL_TAC] THEN + SUBGOAL_THEN `(convex hull t:real^N->bool) SUBSET s` ASSUME_TAC THENL + [ASM_SIMP_TAC[SUBSET_HULL] THEN ASM SET_TAC[]; ALL_TAC] THEN + REWRITE_TAC[NOT_IMP] THEN CONJ_TAC THENL + [ASM_SIMP_TAC[COMPACT_CONVEX_HULL; VECTOR_SUB_EQ] THEN + CONJ_TAC THENL [ALL_TAC; ASM SET_TAC[]] THEN + MATCH_MP_TAC CONTINUOUS_ON_SUB THEN + REWRITE_TAC[CONTINUOUS_ON_ID; ETA_AX] THEN + ASM_MESON_TAC[CONTINUOUS_ON_SUBSET]; + DISCH_THEN(X_CHOOSE_THEN `e:real` STRIP_ASSUME_TAC)] THEN + MP_TAC(ISPECL [`convex hull t:real^N->bool`; `e:real`] + SCHAUDER_PROJECTION) THEN + ASM_SIMP_TAC[NOT_EXISTS_THM; COMPACT_CONVEX_HULL] THEN + MAP_EVERY X_GEN_TAC [`k:real^N->bool`; `g:real^N->real^N`] THEN + STRIP_TAC THEN + SUBGOAL_THEN `(convex hull k:real^N->bool) SUBSET s` ASSUME_TAC THENL + [ASM_SIMP_TAC[SUBSET_HULL] THEN ASM SET_TAC[]; ALL_TAC] THEN + MP_TAC(ISPECL + [`(g:real^N->real^N) o (f:real^N->real^N)`; `convex hull k:real^N->bool`] + BROUWER) THEN + ASM_SIMP_TAC[COMPACT_CONVEX_HULL; FINITE_IMP_COMPACT] THEN + REWRITE_TAC[CONVEX_CONVEX_HULL; NOT_IMP; GSYM CONJ_ASSOC; o_THM] THEN + SUBGOAL_THEN `~(k:real^N->bool = {})` ASSUME_TAC THENL + [ASM_MESON_TAC[IMAGE_EQ_EMPTY; SUBSET_EMPTY; CONVEX_HULL_EQ_EMPTY]; + ASM_REWRITE_TAC[CONVEX_HULL_EQ_EMPTY]] THEN + REPEAT CONJ_TAC THENL + [MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN CONJ_TAC THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET)) THEN ASM SET_TAC[]; + REWRITE_TAC[IMAGE_o] THEN ASM SET_TAC[]; + DISCH_THEN(X_CHOOSE_THEN `x:real^N` STRIP_ASSUME_TAC) THEN + FIRST_X_ASSUM(MP_TAC o SPEC `(f:real^N->real^N) x`) THEN + ASM_REWRITE_TAC[NOT_IMP; NORM_ARITH + `norm(x - y:real^N) < e <=> ~(e <= norm(y - x))`] THEN + CONJ_TAC THENL [ASM SET_TAC[]; FIRST_X_ASSUM MATCH_MP_TAC] THEN + UNDISCH_TAC `(x:real^N) IN convex hull k` THEN + SPEC_TAC(`x:real^N`,`x:real^N`) THEN REWRITE_TAC[GSYM SUBSET] THEN + ASM_SIMP_TAC[SUBSET_HULL; CONVEX_CONVEX_HULL]]);; + +let SCHAUDER_UNIV = prove + (`!f:real^N->real^N. + f continuous_on (:real^N) /\ bounded (IMAGE f (:real^N)) + ==> ?x. f x = x`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`f:real^N->real^N`; `(:real^N)`; + `closure(IMAGE (f:real^N->real^N) (:real^N))`] SCHAUDER) THEN + ASM_REWRITE_TAC[UNIV_NOT_EMPTY; CONVEX_UNIV; COMPACT_CLOSURE; IN_UNIV] THEN + REWRITE_TAC[SUBSET_UNIV; CLOSURE_SUBSET]);; + +let ROTHE = prove + (`!f s:real^N->bool. + closed s /\ convex s /\ ~(s = {}) /\ + f continuous_on s /\ bounded(IMAGE f s) /\ + IMAGE f (frontier s) SUBSET s + ==> ?x. x IN s /\ f x = x`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`s:real^N->bool`; `(:real^N)`] + ABSOLUTE_RETRACTION_CONVEX_CLOSED) THEN + ASM_REWRITE_TAC[retraction; SUBSET_UNIV] THEN + DISCH_THEN(X_CHOOSE_THEN `r:real^N->real^N` STRIP_ASSUME_TAC) THEN + MP_TAC(ISPECL + [`(r:real^N->real^N) o (f:real^N->real^N)`; `s:real^N->bool`; + `IMAGE (r:real^N->real^N) (closure(IMAGE (f:real^N->real^N) s))`] + SCHAUDER) THEN + ANTS_TAC THENL + [ASM_SIMP_TAC[CLOSURE_SUBSET; IMAGE_SUBSET; IMAGE_o] THEN + CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN CONJ_TAC THENL + [MATCH_MP_TAC COMPACT_CONTINUOUS_IMAGE THEN + ASM_REWRITE_TAC[COMPACT_CLOSURE]; + MATCH_MP_TAC CONTINUOUS_ON_COMPOSE] THEN + ASM_MESON_TAC[CONTINUOUS_ON_SUBSET; SUBSET_UNIV]; + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `y:real^N` THEN + REWRITE_TAC[o_THM] THEN STRIP_TAC THEN ASM SET_TAC[]]);; + +(* ------------------------------------------------------------------------- *) +(* Bijections between intervals. *) +(* ------------------------------------------------------------------------- *) + +let interval_bij = new_definition + `interval_bij (a:real^N,b:real^N) (u:real^N,v:real^N) (x:real^N) = + (lambda i. u$i + (x$i - a$i) / (b$i - a$i) * (v$i - u$i)):real^N`;; + +let INTERVAL_BIJ_AFFINE = prove + (`interval_bij (a,b) (u,v) = + \x. (lambda i. (v$i - u$i) / (b$i - a$i) * x$i) + + (lambda i. u$i - (v$i - u$i) / (b$i - a$i) * a$i)`, + SIMP_TAC[FUN_EQ_THM; CART_EQ; VECTOR_ADD_COMPONENT; LAMBDA_BETA; + interval_bij] THEN + REAL_ARITH_TAC);; + +let CONTINUOUS_INTERVAL_BIJ = prove + (`!a b u v x. (interval_bij (a:real^N,b:real^N) (u:real^N,v:real^N)) + continuous at x`, + REPEAT GEN_TAC THEN REWRITE_TAC[INTERVAL_BIJ_AFFINE] THEN + MATCH_MP_TAC CONTINUOUS_ADD THEN REWRITE_TAC[CONTINUOUS_CONST] THEN + MATCH_MP_TAC LINEAR_CONTINUOUS_AT THEN + SIMP_TAC[linear; CART_EQ; LAMBDA_BETA; + VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT] THEN + REAL_ARITH_TAC);; + +let CONTINUOUS_ON_INTERVAL_BIJ = prove + (`!a b u v s. interval_bij (a,b) (u,v) continuous_on s`, + REPEAT GEN_TAC THEN MATCH_MP_TAC CONTINUOUS_AT_IMP_CONTINUOUS_ON THEN + REWRITE_TAC[CONTINUOUS_INTERVAL_BIJ]);; + +let IN_INTERVAL_INTERVAL_BIJ = prove + (`!a b u v x:real^N. + x IN interval[a,b] /\ ~(interval[u,v] = {}) + ==> (interval_bij (a,b) (u,v) x) IN interval[u,v]`, + SIMP_TAC[IN_INTERVAL; interval_bij; LAMBDA_BETA; INTERVAL_NE_EMPTY] THEN + REWRITE_TAC[REAL_ARITH `u <= u + x <=> &0 <= x`; + REAL_ARITH `u + x <= v <=> x <= &1 * (v - u)`] THEN + REPEAT STRIP_TAC THENL + [MATCH_MP_TAC REAL_LE_MUL THEN CONJ_TAC THEN + TRY(MATCH_MP_TAC REAL_LE_DIV) THEN + ASM_SIMP_TAC[REAL_SUB_LE] THEN ASM_MESON_TAC[REAL_LE_TRANS]; + MATCH_MP_TAC REAL_LE_RMUL THEN ASM_SIMP_TAC[REAL_SUB_LE] THEN + SUBGOAL_THEN `(a:real^N)$i <= (b:real^N)$i` MP_TAC THENL + [ASM_MESON_TAC[REAL_LE_TRANS]; ALL_TAC] THEN + GEN_REWRITE_TAC LAND_CONV [REAL_LE_LT] THEN STRIP_TAC THENL + [ASM_SIMP_TAC[REAL_LE_LDIV_EQ; REAL_SUB_LT] THEN + ASM_SIMP_TAC[REAL_ARITH `a <= x /\ x <= b ==> x - a <= &1 * (b - a)`]; + ASM_REWRITE_TAC[real_div; REAL_SUB_REFL; REAL_INV_0] THEN + REAL_ARITH_TAC]]);; + +let INTERVAL_BIJ_BIJ = prove + (`!a b u v x:real^N. + (!i. 1 <= i /\ i <= dimindex(:N) ==> a$i < b$i /\ u$i < v$i) + ==> interval_bij (a,b) (u,v) (interval_bij (u,v) (a,b) x) = x`, + SIMP_TAC[interval_bij; CART_EQ; LAMBDA_BETA; REAL_ADD_SUB] THEN + REPEAT GEN_TAC THEN REWRITE_TAC[AND_FORALL_THM] THEN + MATCH_MP_TAC MONO_FORALL THEN GEN_TAC THEN MATCH_MP_TAC MONO_IMP THEN + REWRITE_TAC[] THEN CONV_TAC REAL_FIELD);; + +(* ------------------------------------------------------------------------- *) +(* Fashoda meet theorem. *) +(* ------------------------------------------------------------------------- *) + +let INFNORM_2 = prove + (`infnorm (x:real^2) = max (abs(x$1)) (abs(x$2))`, + REWRITE_TAC[infnorm; INFNORM_SET_IMAGE; NUMSEG_CONV `1..2`; DIMINDEX_2] THEN + REWRITE_TAC[IMAGE_CLAUSES; GSYM REAL_MAX_SUP]);; + +let INFNORM_EQ_1_2 = prove + (`infnorm (x:real^2) = &1 <=> + abs(x$1) <= &1 /\ abs(x$2) <= &1 /\ + (x$1 = -- &1 \/ x$1 = &1 \/ x$2 = -- &1 \/ x$2 = &1)`, + REWRITE_TAC[INFNORM_2] THEN REAL_ARITH_TAC);; + +let INFNORM_EQ_1_IMP = prove + (`infnorm (x:real^2) = &1 ==> abs(x$1) <= &1 /\ abs(x$2) <= &1`, + SIMP_TAC[INFNORM_EQ_1_2]);; + +let FASHODA_UNIT = prove + (`!f:real^1->real^2 g:real^1->real^2. + IMAGE f (interval[--vec 1,vec 1]) SUBSET interval[--vec 1,vec 1] /\ + IMAGE g (interval[--vec 1,vec 1]) SUBSET interval[--vec 1,vec 1] /\ + f continuous_on interval[--vec 1,vec 1] /\ + g continuous_on interval[--vec 1,vec 1] /\ + f(--vec 1)$1 = -- &1 /\ f(vec 1)$1 = &1 /\ + g(--vec 1)$2 = -- &1 /\ g(vec 1)$2 = &1 + ==> ?s t. s IN interval[--vec 1,vec 1] /\ + t IN interval[--vec 1,vec 1] /\ + f(s) = g(t)`, + REPEAT STRIP_TAC THEN GEN_REWRITE_TAC I [TAUT `p <=> ~ ~p`] THEN + DISCH_THEN(MP_TAC o REWRITE_RULE[NOT_EXISTS_THM]) THEN + REWRITE_TAC[TAUT `~(a /\ b /\ c) <=> a /\ b ==> ~c`] THEN DISCH_TAC THEN + ABBREV_TAC `sqprojection = \z:real^2. inv(infnorm z) % z` THEN + ABBREV_TAC `(negatex:real^2->real^2) = \x. vector[--(x$1); x$2]` THEN + SUBGOAL_THEN `!z:real^2. infnorm(negatex z:real^2) = infnorm z` ASSUME_TAC + THENL + [EXPAND_TAC "negatex" THEN SIMP_TAC[VECTOR_2; INFNORM_2] THEN + REAL_ARITH_TAC; + ALL_TAC] THEN + SUBGOAL_THEN + `!z. ~(z = vec 0) ==> infnorm((sqprojection:real^2->real^2) z) = &1` + ASSUME_TAC THENL + [EXPAND_TAC "sqprojection" THEN + REWRITE_TAC[INFNORM_MUL; REAL_ABS_INFNORM; REAL_ABS_INV] THEN + SIMP_TAC[REAL_MUL_LINV; INFNORM_EQ_0]; + ALL_TAC] THEN + MP_TAC(ISPECL [`(\w. (negatex:real^2->real^2) + (sqprojection(f(lift(w$1)) - g(lift(w$2)):real^2))) + :real^2->real^2`; + `interval[--vec 1,vec 1]:real^2->bool`] + BROUWER_WEAK) THEN + REWRITE_TAC[NOT_IMP; COMPACT_INTERVAL; CONVEX_INTERVAL] THEN + REPEAT CONJ_TAC THENL + [REWRITE_TAC[INTERIOR_CLOSED_INTERVAL; INTERVAL_NE_EMPTY] THEN + SIMP_TAC[VEC_COMPONENT; VECTOR_NEG_COMPONENT] THEN REAL_ARITH_TAC; + MATCH_MP_TAC(REWRITE_RULE[o_DEF] CONTINUOUS_ON_COMPOSE) THEN CONJ_TAC THENL + [ALL_TAC; + MATCH_MP_TAC LINEAR_CONTINUOUS_ON THEN EXPAND_TAC "negatex" THEN + SIMP_TAC[linear; VECTOR_2; CART_EQ; FORALL_2; DIMINDEX_2; + VECTOR_MUL_COMPONENT; VECTOR_NEG_COMPONENT; + VECTOR_ADD_COMPONENT; ARITH] THEN + REAL_ARITH_TAC] THEN + MATCH_MP_TAC(REWRITE_RULE[o_DEF] CONTINUOUS_ON_COMPOSE) THEN CONJ_TAC THENL + [MATCH_MP_TAC CONTINUOUS_ON_SUB THEN CONJ_TAC THEN + MATCH_MP_TAC(REWRITE_RULE[o_DEF] CONTINUOUS_ON_COMPOSE) THEN + SIMP_TAC[CONTINUOUS_ON_LIFT_COMPONENT; DIMINDEX_2; ARITH] THEN + MATCH_MP_TAC CONTINUOUS_ON_SUBSET THEN + EXISTS_TAC `interval[--vec 1:real^1,vec 1]`; + MATCH_MP_TAC CONTINUOUS_AT_IMP_CONTINUOUS_ON THEN + EXPAND_TAC "sqprojection" THEN REWRITE_TAC[FORALL_IN_IMAGE] THEN + X_GEN_TAC `x:real^2` THEN STRIP_TAC THEN + MATCH_MP_TAC CONTINUOUS_MUL THEN REWRITE_TAC[CONTINUOUS_AT_ID] THEN + GEN_REWRITE_TAC (LAND_CONV o RAND_CONV) [GSYM o_DEF] THEN + MATCH_MP_TAC CONTINUOUS_AT_INV THEN + REWRITE_TAC[CONTINUOUS_AT_LIFT_INFNORM; INFNORM_EQ_0; VECTOR_SUB_EQ] THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_INTERVAL])] THEN + ASM_SIMP_TAC[SUBSET; FORALL_IN_IMAGE; IN_INTERVAL_1] THEN + SIMP_TAC[IN_INTERVAL; DIMINDEX_2; FORALL_2; VEC_COMPONENT; ARITH; + VECTOR_NEG_COMPONENT; DROP_NEG; DROP_VEC; LIFT_DROP]; + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE] THEN + X_GEN_TAC `x:real^2` THEN STRIP_TAC THEN + SIMP_TAC[IN_INTERVAL; DIMINDEX_2; FORALL_2; REAL_BOUNDS_LE; + VECTOR_NEG_COMPONENT; VEC_COMPONENT; ARITH] THEN + MATCH_MP_TAC INFNORM_EQ_1_IMP THEN ASM_REWRITE_TAC[] THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN + REWRITE_TAC[VECTOR_SUB_EQ] THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_INTERVAL]) THEN + ASM_SIMP_TAC[SUBSET; FORALL_IN_IMAGE; IN_INTERVAL_1] THEN + SIMP_TAC[IN_INTERVAL; DIMINDEX_2; FORALL_2; VEC_COMPONENT; ARITH; + VECTOR_NEG_COMPONENT; DROP_NEG; DROP_VEC; LIFT_DROP]; + ALL_TAC] THEN + DISCH_THEN(X_CHOOSE_THEN `x:real^2` STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN `infnorm(x:real^2) = &1` MP_TAC THENL + [FIRST_X_ASSUM(fun th -> GEN_REWRITE_TAC (LAND_CONV o RAND_CONV) + [SYM th]) THEN + ASM_REWRITE_TAC[] THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + REWRITE_TAC[VECTOR_SUB_EQ] THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + REWRITE_TAC[IN_INTERVAL_1] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_INTERVAL]) THEN + SIMP_TAC[IN_INTERVAL; DIMINDEX_2; FORALL_2; VEC_COMPONENT; ARITH; + VECTOR_NEG_COMPONENT; DROP_NEG; DROP_VEC; LIFT_DROP]; + ALL_TAC] THEN + SUBGOAL_THEN + `(!x i. 1 <= i /\ i <= 2 /\ ~(x = vec 0) + ==> (&0 < ((sqprojection:real^2->real^2) x)$i <=> &0 < x$i)) /\ + (!x i. 1 <= i /\ i <= 2 /\ ~(x = vec 0) + ==> ((sqprojection x)$i < &0 <=> x$i < &0))` + STRIP_ASSUME_TAC THENL + [EXPAND_TAC "sqprojection" THEN + SIMP_TAC[VECTOR_MUL_COMPONENT; DIMINDEX_2; ARITH] THEN + REWRITE_TAC[GSYM(ONCE_REWRITE_RULE[REAL_MUL_SYM] real_div)] THEN + SIMP_TAC[REAL_LT_LDIV_EQ; REAL_LT_RDIV_EQ; INFNORM_POS_LT] THEN + REWRITE_TAC[REAL_MUL_LZERO]; + ALL_TAC] THEN + REWRITE_TAC[INFNORM_EQ_1_2; CONJ_ASSOC] THEN + DISCH_THEN(CONJUNCTS_THEN2 STRIP_ASSUME_TAC + (REPEAT_TCL DISJ_CASES_THEN (fun th -> ASSUME_TAC th THEN MP_TAC th))) THEN + MAP_EVERY EXPAND_TAC ["x"; "negatex"] THEN REWRITE_TAC[VECTOR_2] THENL + [DISCH_THEN(MP_TAC o MATCH_MP (REAL_ARITH `--x = -- &1 ==> &0 < x`)); + DISCH_THEN(MP_TAC o MATCH_MP (REAL_ARITH `--x = &1 ==> x < &0`)); + DISCH_THEN(MP_TAC o MATCH_MP (REAL_ARITH `x = -- &1 ==> x < &0`)); + DISCH_THEN(MP_TAC o MATCH_MP (REAL_ARITH `x = &1 ==> &0 < x`))] THEN + W(fun (_,w) -> FIRST_X_ASSUM(fun th -> + MP_TAC(PART_MATCH (lhs o rand) th (lhand w)))) THEN + (ANTS_TAC THENL + [REWRITE_TAC[VECTOR_SUB_EQ; ARITH] THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_INTERVAL]) THEN + ASM_SIMP_TAC[SUBSET; FORALL_IN_IMAGE; IN_INTERVAL_1] THEN + SIMP_TAC[IN_INTERVAL; DIMINDEX_2; FORALL_2; VEC_COMPONENT; ARITH; + VECTOR_NEG_COMPONENT; DROP_NEG; DROP_VEC; LIFT_DROP] THEN + REAL_ARITH_TAC; + DISCH_THEN SUBST1_TAC]) THEN + ASM_SIMP_TAC[VECTOR_SUB_COMPONENT; DIMINDEX_2; ARITH; + LIFT_NEG; LIFT_NUM] + THENL + [MATCH_MP_TAC(REAL_ARITH + `abs(x$1) <= &1 /\ abs(x$2) <= &1 ==> ~(&0 < -- &1 - x$1)`); + MATCH_MP_TAC(REAL_ARITH + `abs(x$1) <= &1 /\ abs(x$2) <= &1 ==> ~(&1 - x$1 < &0)`); + MATCH_MP_TAC(REAL_ARITH + `abs(x$1) <= &1 /\ abs(x$2) <= &1 ==> ~(x$2 - -- &1 < &0)`); + MATCH_MP_TAC(REAL_ARITH + `abs(x$1) <= &1 /\ abs(x$2) <= &1 ==> ~(&0 < x$2 - &1)`)] THEN + (SUBGOAL_THEN `!z:real^2. abs(z$1) <= &1 /\ abs(z$2) <= &1 <=> + z IN interval[--vec 1,vec 1]` + (fun th -> REWRITE_TAC[th]) THENL + [SIMP_TAC[IN_INTERVAL; DIMINDEX_2; FORALL_2; VEC_COMPONENT; ARITH; + VECTOR_NEG_COMPONENT; DROP_NEG; DROP_VEC; LIFT_DROP] THEN + REAL_ARITH_TAC; + ALL_TAC]) THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE + `IMAGE f s SUBSET t ==> x IN s ==> f x IN t`)) THEN + REWRITE_TAC[IN_INTERVAL_1; DROP_NEG; DROP_VEC; LIFT_DROP] THEN + ASM_REWRITE_TAC[REAL_BOUNDS_LE]);; + +let FASHODA_UNIT_PATH = prove + (`!f:real^1->real^2 g:real^1->real^2. + path f /\ path g /\ + path_image f SUBSET interval[--vec 1,vec 1] /\ + path_image g SUBSET interval[--vec 1,vec 1] /\ + (pathstart f)$1 = -- &1 /\ (pathfinish f)$1 = &1 /\ + (pathstart g)$2 = -- &1 /\ (pathfinish g)$2 = &1 + ==> ?z. z IN path_image f /\ z IN path_image g`, + SIMP_TAC[path; path_image; pathstart; pathfinish] THEN REPEAT STRIP_TAC THEN + ABBREV_TAC `iscale = \z:real^1. inv(&2) % (z + vec 1)` THEN + MP_TAC(ISPECL + [`(f:real^1->real^2) o (iscale:real^1->real^1)`; + `(g:real^1->real^2) o (iscale:real^1->real^1)`] + FASHODA_UNIT) THEN + SUBGOAL_THEN + `IMAGE (iscale:real^1->real^1) (interval[--vec 1,vec 1]) + SUBSET interval[vec 0,vec 1]` + ASSUME_TAC THENL + [REWRITE_TAC[SUBSET; FORALL_IN_IMAGE] THEN EXPAND_TAC "iscale" THEN + REWRITE_TAC[IN_INTERVAL_1; DROP_NEG; DROP_VEC; DROP_CMUL; DROP_ADD] THEN + REAL_ARITH_TAC; + ALL_TAC] THEN + SUBGOAL_THEN `(iscale:real^1->real^1) continuous_on interval [--vec 1,vec 1]` + ASSUME_TAC THENL + [EXPAND_TAC "iscale" THEN + SIMP_TAC[CONTINUOUS_ON_CMUL; CONTINUOUS_ON_ID; CONTINUOUS_ON_ADD; + CONTINUOUS_ON_CONST]; + ALL_TAC] THEN + ASM_REWRITE_TAC[IMAGE_o] THEN ANTS_TAC THENL + [REPLICATE_TAC 2 (CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC]) THEN + REPLICATE_TAC 2 (CONJ_TAC THENL + [MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN ASM_REWRITE_TAC[] THEN + ASM_MESON_TAC[CONTINUOUS_ON_SUBSET]; + ALL_TAC]) THEN + EXPAND_TAC "iscale" THEN REWRITE_TAC[o_THM] THEN + ASM_REWRITE_TAC[VECTOR_ARITH `inv(&2) % (--x + x) = vec 0`; + VECTOR_ARITH `inv(&2) % (x + x) = x`]; + REWRITE_TAC[o_THM; LEFT_IMP_EXISTS_THM; IN_IMAGE] THEN ASM SET_TAC[]]);; + +let FASHODA = prove + (`!f g a b:real^2. + path f /\ path g /\ + path_image f SUBSET interval[a,b] /\ + path_image g SUBSET interval[a,b] /\ + (pathstart f)$1 = a$1 /\ (pathfinish f)$1 = b$1 /\ + (pathstart g)$2 = a$2 /\ (pathfinish g)$2 = b$2 + ==> ?z. z IN path_image f /\ z IN path_image g`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN `~(interval[a:real^2,b] = {})` MP_TAC THENL + [FIRST_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE + `s SUBSET t ==> ~(s = {}) ==> ~(t = {})`)) THEN + REWRITE_TAC[PATH_IMAGE_NONEMPTY]; + ALL_TAC] THEN + REWRITE_TAC[INTERVAL_NE_EMPTY; DIMINDEX_2; FORALL_2] THEN STRIP_TAC THEN + MP_TAC(ASSUME `(a:real^2)$1 <= (b:real^2)$1`) THEN + REWRITE_TAC[REAL_ARITH `a <= b <=> b = a \/ a < b`] THEN STRIP_TAC THENL + [SUBGOAL_THEN + `?z:real^2. z IN path_image g /\ z$2 = (pathstart f:real^2)$2` + MP_TAC THENL + [MATCH_MP_TAC CONNECTED_IVT_COMPONENT THEN + MAP_EVERY EXISTS_TAC [`pathstart(g:real^1->real^2)`; + `pathfinish(g:real^1->real^2)`] THEN + ASM_SIMP_TAC[CONNECTED_PATH_IMAGE; PATHSTART_IN_PATH_IMAGE; REAL_LE_REFL; + PATHFINISH_IN_PATH_IMAGE; DIMINDEX_2; ARITH] THEN + UNDISCH_TAC `path_image f SUBSET interval[a:real^2,b]` THEN + REWRITE_TAC[SUBSET; path_image; IN_INTERVAL_1; FORALL_IN_IMAGE] THEN + DISCH_THEN(MP_TAC o SPEC `vec 0:real^1`) THEN SIMP_TAC[pathstart] THEN + SIMP_TAC[DROP_VEC; REAL_POS; IN_INTERVAL; FORALL_2; DIMINDEX_2]; + ALL_TAC] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `z:real^2` THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN SIMP_TAC[path_image; IN_IMAGE] THEN + EXISTS_TAC `vec 0:real^1` THEN + REWRITE_TAC[IN_INTERVAL_1; DROP_VEC; REAL_POS] THEN + ASM_REWRITE_TAC[CART_EQ; FORALL_2; DIMINDEX_2; pathstart] THEN + SUBGOAL_THEN + `(z:real^2) IN interval[a,b] /\ f(vec 0:real^1) IN interval[a,b]` + MP_TAC THENL + [ASM_MESON_TAC[SUBSET; path_image; IN_IMAGE; PATHSTART_IN_PATH_IMAGE; + pathstart]; + ASM_REWRITE_TAC[IN_INTERVAL; FORALL_2; DIMINDEX_2] THEN REAL_ARITH_TAC]; + ALL_TAC] THEN + MP_TAC(ASSUME `(a:real^2)$2 <= (b:real^2)$2`) THEN + REWRITE_TAC[REAL_ARITH `a <= b <=> b = a \/ a < b`] THEN STRIP_TAC THENL + [SUBGOAL_THEN + `?z:real^2. z IN path_image f /\ z$1 = (pathstart g:real^2)$1` + MP_TAC THENL + [MATCH_MP_TAC CONNECTED_IVT_COMPONENT THEN + MAP_EVERY EXISTS_TAC [`pathstart(f:real^1->real^2)`; + `pathfinish(f:real^1->real^2)`] THEN + ASM_SIMP_TAC[CONNECTED_PATH_IMAGE; PATHSTART_IN_PATH_IMAGE; REAL_LE_REFL; + PATHFINISH_IN_PATH_IMAGE; DIMINDEX_2; ARITH] THEN + UNDISCH_TAC `path_image g SUBSET interval[a:real^2,b]` THEN + REWRITE_TAC[SUBSET; path_image; IN_INTERVAL_1; FORALL_IN_IMAGE] THEN + DISCH_THEN(MP_TAC o SPEC `vec 0:real^1`) THEN SIMP_TAC[pathstart] THEN + SIMP_TAC[DROP_VEC; REAL_POS; IN_INTERVAL; FORALL_2; DIMINDEX_2]; + ALL_TAC] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `z:real^2` THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN SIMP_TAC[path_image; IN_IMAGE] THEN + EXISTS_TAC `vec 0:real^1` THEN + REWRITE_TAC[IN_INTERVAL_1; DROP_VEC; REAL_POS] THEN + ASM_REWRITE_TAC[CART_EQ; FORALL_2; DIMINDEX_2; pathstart] THEN + SUBGOAL_THEN + `(z:real^2) IN interval[a,b] /\ g(vec 0:real^1) IN interval[a,b]` + MP_TAC THENL + [ASM_MESON_TAC[SUBSET; path_image; IN_IMAGE; PATHSTART_IN_PATH_IMAGE; + pathstart]; + ASM_REWRITE_TAC[IN_INTERVAL; FORALL_2; DIMINDEX_2] THEN REAL_ARITH_TAC]; + ALL_TAC] THEN + MP_TAC(ISPECL + [`interval_bij (a,b) (--vec 1,vec 1) o (f:real^1->real^2)`; + `interval_bij (a,b) (--vec 1,vec 1) o (g:real^1->real^2)`] + FASHODA_UNIT_PATH) THEN + RULE_ASSUM_TAC(REWRITE_RULE[path; path_image; pathstart; pathfinish]) THEN + ASM_REWRITE_TAC[path; path_image; pathstart; pathfinish; o_THM] THEN + ANTS_TAC THENL + [ASM_SIMP_TAC[CONTINUOUS_ON_COMPOSE; CONTINUOUS_ON_INTERVAL_BIJ] THEN + REWRITE_TAC[IMAGE_o] THEN REPLICATE_TAC 2 (CONJ_TAC THENL + [REWRITE_TAC[SUBSET] THEN ONCE_REWRITE_TAC[FORALL_IN_IMAGE] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC IN_INTERVAL_INTERVAL_BIJ THEN + SIMP_TAC[INTERVAL_NE_EMPTY; VECTOR_NEG_COMPONENT; VEC_COMPONENT] THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN ASM SET_TAC[]; + ALL_TAC]) THEN + ASM_SIMP_TAC[interval_bij; LAMBDA_BETA; DIMINDEX_2; ARITH] THEN + ASM_SIMP_TAC[REAL_DIV_REFL; REAL_LT_IMP_NZ; REAL_SUB_LT] THEN + REWRITE_TAC[real_div; REAL_SUB_REFL; REAL_MUL_LZERO] THEN + SIMP_TAC[VECTOR_NEG_COMPONENT; VEC_COMPONENT; DIMINDEX_2; ARITH] THEN + CONV_TAC REAL_RAT_REDUCE_CONV; + ALL_TAC] THEN + DISCH_THEN(X_CHOOSE_THEN `z:real^2` + (fun th -> EXISTS_TAC `interval_bij (--vec 1,vec 1) (a,b) (z:real^2)` THEN + MP_TAC th)) THEN + MATCH_MP_TAC MONO_AND THEN CONJ_TAC THEN REWRITE_TAC[IMAGE_o] THEN + MATCH_MP_TAC(SET_RULE + `(!x. x IN s ==> g(f(x)) = x) ==> x IN IMAGE f s ==> g x IN s`) THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC INTERVAL_BIJ_BIJ THEN + ASM_SIMP_TAC[FORALL_2; DIMINDEX_2; VECTOR_NEG_COMPONENT; VEC_COMPONENT; + ARITH] THEN + CONV_TAC REAL_RAT_REDUCE_CONV);; + +(* ------------------------------------------------------------------------- *) +(* Some slightly ad hoc lemmas I use below *) +(* ------------------------------------------------------------------------- *) + +let SEGMENT_VERTICAL = prove + (`!a:real^2 b:real^2 x:real^2. + a$1 = b$1 + ==> (x IN segment[a,b] <=> + x$1 = a$1 /\ x$1 = b$1 /\ + (a$2 <= x$2 /\ x$2 <= b$2 \/ b$2 <= x$2 /\ x$2 <= a$2))`, + GEOM_ORIGIN_TAC `a:real^2` THEN + REWRITE_TAC[VECTOR_ADD_COMPONENT; VEC_COMPONENT; REAL_LE_LADD; + REAL_EQ_ADD_LCANCEL] THEN + REPEAT GEN_TAC THEN DISCH_THEN(ASSUME_TAC o SYM) THEN + SUBST1_TAC(SYM(ISPEC `b:real^2` BASIS_EXPANSION)) THEN + ASM_REWRITE_TAC[DIMINDEX_2; VSUM_2; VECTOR_MUL_LZERO; VECTOR_ADD_LID] THEN + SUBST1_TAC(VECTOR_ARITH `vec 0:real^2 = &0 % basis 2`) THEN + REWRITE_TAC[SEGMENT_SCALAR_MULTIPLE; IN_ELIM_THM; CART_EQ] THEN + REWRITE_TAC[DIMINDEX_2; FORALL_2; VECTOR_MUL_COMPONENT] THEN + SIMP_TAC[BASIS_COMPONENT; DIMINDEX_2; ARITH; + REAL_MUL_RZERO; REAL_MUL_RID] THEN MESON_TAC[]);; + +let SEGMENT_HORIZONTAL = prove + (`!a:real^2 b:real^2 x:real^2. + a$2 = b$2 + ==> (x IN segment[a,b] <=> + x$2 = a$2 /\ x$2 = b$2 /\ + (a$1 <= x$1 /\ x$1 <= b$1 \/ b$1 <= x$1 /\ x$1 <= a$1))`, + GEOM_ORIGIN_TAC `a:real^2` THEN + REWRITE_TAC[VECTOR_ADD_COMPONENT; VEC_COMPONENT; REAL_LE_LADD; + REAL_EQ_ADD_LCANCEL] THEN + REPEAT GEN_TAC THEN DISCH_THEN(ASSUME_TAC o SYM) THEN + SUBST1_TAC(SYM(ISPEC `b:real^2` BASIS_EXPANSION)) THEN + ASM_REWRITE_TAC[DIMINDEX_2; VSUM_2; VECTOR_MUL_LZERO; VECTOR_ADD_RID] THEN + SUBST1_TAC(VECTOR_ARITH `vec 0:real^2 = &0 % basis 1`) THEN + REWRITE_TAC[SEGMENT_SCALAR_MULTIPLE; IN_ELIM_THM; CART_EQ] THEN + REWRITE_TAC[DIMINDEX_2; FORALL_2; VECTOR_MUL_COMPONENT] THEN + SIMP_TAC[BASIS_COMPONENT; DIMINDEX_2; ARITH; + REAL_MUL_RZERO; REAL_MUL_RID] THEN MESON_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* Useful Fashoda corollary pointed out to me by Tom Hales. *) +(* ------------------------------------------------------------------------- *) + +let FASHODA_INTERLACE = prove + (`!f g a b:real^2. + path f /\ path g /\ + path_image f SUBSET interval[a,b] /\ + path_image g SUBSET interval[a,b] /\ + (pathstart f)$2 = a$2 /\ (pathfinish f)$2 = a$2 /\ + (pathstart g)$2 = a$2 /\ (pathfinish g)$2 = a$2 /\ + (pathstart f)$1 < (pathstart g)$1 /\ + (pathstart g)$1 < (pathfinish f)$1 /\ + (pathfinish f)$1 < (pathfinish g)$1 + ==> ?z. z IN path_image f /\ z IN path_image g`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN `~(interval[a:real^2,b] = {})` MP_TAC THENL + [FIRST_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE + `s SUBSET t ==> ~(s = {}) ==> ~(t = {})`)) THEN + REWRITE_TAC[PATH_IMAGE_NONEMPTY]; + ALL_TAC] THEN + SUBGOAL_THEN + `pathstart (f:real^1->real^2) IN interval[a,b] /\ + pathfinish f IN interval[a,b] /\ + pathstart g IN interval[a,b] /\ + pathfinish g IN interval[a,b]` + MP_TAC THENL + [ASM_MESON_TAC[SUBSET; PATHSTART_IN_PATH_IMAGE; PATHFINISH_IN_PATH_IMAGE]; + ALL_TAC] THEN + REWRITE_TAC[INTERVAL_NE_EMPTY; IN_INTERVAL; FORALL_2; DIMINDEX_2] THEN + REPEAT STRIP_TAC THEN + MP_TAC(SPECL + [`linepath(vector[a$1 - &2;a$2 - &2],vector[(pathstart f)$1;a$2 - &2]) ++ + linepath(vector[(pathstart f)$1;(a:real^2)$2 - &2],pathstart f) ++ + (f:real^1->real^2) ++ + linepath(pathfinish f,vector[(pathfinish f)$1;a$2 - &2]) ++ + linepath(vector[(pathfinish f)$1;a$2 - &2], + vector[(b:real^2)$1 + &2;a$2 - &2])`; + `linepath(vector[(pathstart g)$1; (pathstart g)$2 - &3],pathstart g) ++ + (g:real^1->real^2) ++ + linepath(pathfinish g,vector[(pathfinish g)$1;(a:real^2)$2 - &1]) ++ + linepath(vector[(pathfinish g)$1;a$2 - &1],vector[b$1 + &1;a$2 - &1]) ++ + linepath(vector[b$1 + &1;a$2 - &1],vector[(b:real^2)$1 + &1;b$2 + &3])`; + `vector[(a:real^2)$1 - &2; a$2 - &3]:real^2`; + `vector[(b:real^2)$1 + &2; b$2 + &3]:real^2`] + FASHODA) THEN + ASM_SIMP_TAC[PATH_JOIN; PATHSTART_JOIN; PATHFINISH_JOIN; PATH_IMAGE_JOIN; + PATHSTART_LINEPATH; PATHFINISH_LINEPATH; PATH_LINEPATH] THEN + REWRITE_TAC[VECTOR_2] THEN ANTS_TAC THENL + [CONJ_TAC THEN + REPEAT(MATCH_MP_TAC + (SET_RULE `s SUBSET u /\ t SUBSET u ==> (s UNION t) SUBSET u`) THEN + CONJ_TAC) THEN + TRY(REWRITE_TAC[PATH_IMAGE_LINEPATH] THEN + MATCH_MP_TAC(REWRITE_RULE[CONVEX_CONTAINS_SEGMENT] + (CONJUNCT1 (SPEC_ALL CONVEX_INTERVAL))) THEN + ASM_REWRITE_TAC[IN_INTERVAL; FORALL_2; DIMINDEX_2; VECTOR_2] THEN + ASM_REAL_ARITH_TAC) THEN + MATCH_MP_TAC SUBSET_TRANS THEN + EXISTS_TAC `interval[a:real^2,b:real^2]` THEN + ASM_REWRITE_TAC[SUBSET_REFL] THEN + REWRITE_TAC[SUBSET_INTERVAL; FORALL_2; DIMINDEX_2; VECTOR_2] THEN + ASM_REAL_ARITH_TAC; + ALL_TAC] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `z:real^2` THEN + REWRITE_TAC[PATH_IMAGE_LINEPATH] THEN + SUBGOAL_THEN + `!f s:real^2->bool. path_image f UNION s = + path_image f UNION (s DIFF {pathstart f,pathfinish f})` + (fun th -> ONCE_REWRITE_TAC[th] THEN + REWRITE_TAC[GSYM UNION_ASSOC] THEN + ONCE_REWRITE_TAC[SET_RULE `(s UNION t) UNION u = + u UNION t UNION s`] THEN + ONCE_REWRITE_TAC[th]) + THENL + [REWRITE_TAC[EXTENSION; IN_UNION; IN_DIFF; IN_INSERT; NOT_IN_EMPTY] THEN + ASM_MESON_TAC[PATHSTART_IN_PATH_IMAGE; PATHFINISH_IN_PATH_IMAGE]; + ALL_TAC] THEN + REWRITE_TAC[IN_UNION; IN_DIFF; GSYM DISJ_ASSOC; LEFT_OR_DISTRIB; + RIGHT_OR_DISTRIB; GSYM CONJ_ASSOC; + SET_RULE `~(z IN {x,y}) <=> ~(z = x) /\ ~(z = y)`] THEN + DISCH_THEN(REPEAT_TCL DISJ_CASES_THEN MP_TAC) THEN + ASM_SIMP_TAC[SEGMENT_VERTICAL; SEGMENT_HORIZONTAL; VECTOR_2] THEN + REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + UNDISCH_TAC `path_image (f:real^1->real^2) SUBSET interval [a,b]` THEN + REWRITE_TAC[SUBSET] THEN DISCH_THEN(MP_TAC o SPEC `z:real^2`) THEN + UNDISCH_TAC `path_image (g:real^1->real^2) SUBSET interval [a,b]` THEN + REWRITE_TAC[SUBSET] THEN DISCH_THEN(MP_TAC o SPEC `z:real^2`) THEN + ASM_REWRITE_TAC[IN_INTERVAL; FORALL_2; DIMINDEX_2] THEN + REPEAT(DISCH_THEN(fun th -> if is_imp(concl th) then ALL_TAC else + ASSUME_TAC th)) THEN + REPEAT(POP_ASSUM MP_TAC) THEN TRY REAL_ARITH_TAC THEN + REWRITE_TAC[CART_EQ; FORALL_2; DIMINDEX_2] THEN REAL_ARITH_TAC);; + +(* ------------------------------------------------------------------------- *) +(* Complement in dimension N >= 2 of set homeomorphic to any interval in *) +(* any dimension is (path-)connected. This naively generalizes the argument *) +(* in Ryuji Maehara's paper "The Jordan curve theorem via the Brouwer *) +(* fixed point theorem", American Mathematical Monthly 1984. *) +(* ------------------------------------------------------------------------- *) + +let UNBOUNDED_COMPONENTS_COMPLEMENT_ABSOLUTE_RETRACT = prove + (`!s c. compact s /\ s retract_of (:real^N) /\ + c IN components((:real^N) DIFF s) + ==> ~bounded c`, + REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; components; FORALL_IN_GSPEC] THEN + GEN_TAC THEN DISCH_TAC THEN DISCH_TAC THEN X_GEN_TAC `y:real^N` THEN + REWRITE_TAC[IN_DIFF; IN_UNIV] THEN REPEAT STRIP_TAC THEN + SUBGOAL_THEN `open((:real^N) DIFF s)` ASSUME_TAC THENL + [ASM_SIMP_TAC[GSYM closed; COMPACT_IMP_CLOSED]; ALL_TAC] THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [retract_of]) THEN + REWRITE_TAC[retraction; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `r:real^N->real^N` THEN STRIP_TAC THEN + MP_TAC(ISPECL [`connected_component ((:real^N) DIFF s) y`; + `s:real^N->bool`; + `r:real^N->real^N`] + FRONTIER_SUBSET_RETRACTION) THEN + ASM_SIMP_TAC[NOT_IMP; INTERIOR_OPEN; OPEN_CONNECTED_COMPONENT] THEN + REPEAT CONJ_TAC THENL + [REWRITE_TAC[frontier] THEN + ASM_SIMP_TAC[INTERIOR_OPEN; OPEN_CONNECTED_COMPONENT] THEN + REWRITE_TAC[SUBSET; IN_DIFF] THEN X_GEN_TAC `z:real^N` THEN + ASM_CASES_TAC `(z:real^N) IN s` THEN ASM_REWRITE_TAC[] THEN + ASM_SIMP_TAC[IN_CLOSURE_CONNECTED_COMPONENT; IN_UNIV; IN_DIFF] THEN + CONV_TAC TAUT; + ASM_MESON_TAC[CONTINUOUS_ON_SUBSET; SUBSET_UNIV]; + ASM SET_TAC[]; + MATCH_MP_TAC(SET_RULE + `~(c = {}) /\ c SUBSET (:real^N) DIFF s ==> ~(c SUBSET s)`) THEN + REWRITE_TAC[CONNECTED_COMPONENT_SUBSET; CONNECTED_COMPONENT_EQ_EMPTY] THEN + ASM_REWRITE_TAC[IN_UNIV; IN_DIFF]]);; + +let CONNECTED_COMPLEMENT_ABSOLUTE_RETRACT = prove + (`!s. 2 <= dimindex(:N) /\ compact s /\ s retract_of (:real^N) + ==> connected((:real^N) DIFF s)`, + REPEAT STRIP_TAC THEN REWRITE_TAC[CONNECTED_EQ_CONNECTED_COMPONENT_EQ] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC COBOUNDED_UNIQUE_UNBOUNDED_COMPONENT THEN + ASM_SIMP_TAC[SET_RULE`UNIV DIFF (UNIV DIFF s) = s`; COMPACT_IMP_BOUNDED] THEN + CONJ_TAC THEN + MATCH_MP_TAC UNBOUNDED_COMPONENTS_COMPLEMENT_ABSOLUTE_RETRACT THEN + EXISTS_TAC `s:real^N->bool` THEN + ASM_REWRITE_TAC[IN_COMPONENTS] THEN ASM_MESON_TAC[]);; + +let PATH_CONNECTED_COMPLEMENT_ABSOLUTE_RETRACT = prove + (`!s:real^N->bool. + 2 <= dimindex(:N) /\ compact s /\ s retract_of (:real^N) + ==> path_connected((:real^N) DIFF s)`, + REPEAT GEN_TAC THEN DISCH_TAC THEN FIRST_ASSUM + (MP_TAC o MATCH_MP CONNECTED_COMPLEMENT_ABSOLUTE_RETRACT) THEN + MATCH_MP_TAC EQ_IMP THEN CONV_TAC SYM_CONV THEN + MATCH_MP_TAC PATH_CONNECTED_EQ_CONNECTED THEN + REWRITE_TAC[GSYM closed] THEN + ASM_MESON_TAC[HOMEOMORPHIC_COMPACTNESS; COMPACT_INTERVAL; + COMPACT_IMP_CLOSED]);; + +let CONNECTED_COMPLEMENT_HOMEOMORPHIC_CONVEX_COMPACT = prove + (`!s:real^N->bool t:real^M->bool. + 2 <= dimindex(:N) /\ s homeomorphic t /\ convex t /\ compact t + ==> connected((:real^N) DIFF s)`, + REPEAT STRIP_TAC THEN + ASM_CASES_TAC `s:real^N->bool = {}` THEN + ASM_REWRITE_TAC[DIFF_EMPTY; CONNECTED_UNIV] THEN + MATCH_MP_TAC CONNECTED_COMPLEMENT_ABSOLUTE_RETRACT THEN + ASM_REWRITE_TAC[] THEN CONJ_TAC THENL + [ASM_MESON_TAC[HOMEOMORPHIC_COMPACTNESS]; ALL_TAC] THEN + MATCH_MP_TAC ABSOLUTE_RETRACT_HOMEOMORPHIC_CONVEX_COMPACT THEN + EXISTS_TAC `t:real^M->bool` THEN ASM_REWRITE_TAC[SUBSET_UNIV]);; + +let PATH_CONNECTED_COMPLEMENT_HOMEOMORPHIC_CONVEX_COMPACT = prove + (`!s:real^N->bool t:real^M->bool. + 2 <= dimindex(:N) /\ s homeomorphic t /\ convex t /\ compact t + ==> path_connected((:real^N) DIFF s)`, + REPEAT GEN_TAC THEN DISCH_TAC THEN FIRST_ASSUM + (MP_TAC o MATCH_MP CONNECTED_COMPLEMENT_HOMEOMORPHIC_CONVEX_COMPACT) THEN + MATCH_MP_TAC EQ_IMP THEN CONV_TAC SYM_CONV THEN + MATCH_MP_TAC PATH_CONNECTED_EQ_CONNECTED THEN + REWRITE_TAC[GSYM closed] THEN + ASM_MESON_TAC[HOMEOMORPHIC_COMPACTNESS; COMPACT_INTERVAL; + COMPACT_IMP_CLOSED]);; + +(* ------------------------------------------------------------------------- *) +(* In particular, apply all these to the special case of an arc. *) +(* ------------------------------------------------------------------------- *) + +let RETRACTION_ARC = prove + (`!p. arc p + ==> ?f. f continuous_on (:real^N) /\ + IMAGE f (:real^N) SUBSET path_image p /\ + (!x. x IN path_image p ==> f x = x)`, + REPEAT STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `(:real^N)` o MATCH_MP (REWRITE_RULE[IMP_CONJ] + ABSOLUTE_RETRACT_PATH_IMAGE_ARC)) THEN + REWRITE_TAC[SUBSET_UNIV; retract_of; retraction]);; + +let PATH_CONNECTED_ARC_COMPLEMENT = prove + (`!p. 2 <= dimindex(:N) /\ arc p + ==> path_connected((:real^N) DIFF path_image p)`, + REWRITE_TAC[arc; path] THEN REPEAT STRIP_TAC THEN SIMP_TAC[path_image] THEN + MP_TAC(ISPECL [`path_image p:real^N->bool`; `interval[vec 0:real^1,vec 1]`] + PATH_CONNECTED_COMPLEMENT_HOMEOMORPHIC_CONVEX_COMPACT) THEN + ASM_REWRITE_TAC[CONVEX_INTERVAL; COMPACT_INTERVAL; path_image] THEN + DISCH_THEN MATCH_MP_TAC THEN ONCE_REWRITE_TAC[HOMEOMORPHIC_SYM] THEN + MATCH_MP_TAC HOMEOMORPHIC_COMPACT THEN + EXISTS_TAC `p:real^1->real^N` THEN ASM_REWRITE_TAC[COMPACT_INTERVAL]);; + +let CONNECTED_ARC_COMPLEMENT = prove + (`!p. 2 <= dimindex(:N) /\ arc p + ==> connected((:real^N) DIFF path_image p)`, + SIMP_TAC[PATH_CONNECTED_ARC_COMPLEMENT; PATH_CONNECTED_IMP_CONNECTED]);; + +let INSIDE_ARC_EMPTY = prove + (`!p:real^1->real^N. arc p ==> inside(path_image p) = {}`, + REPEAT STRIP_TAC THEN ASM_CASES_TAC `dimindex(:N) = 1` THENL + [MATCH_MP_TAC INSIDE_CONVEX THEN + ASM_SIMP_TAC[CONVEX_CONNECTED_1_GEN; CONNECTED_PATH_IMAGE; ARC_IMP_PATH]; + MATCH_MP_TAC INSIDE_BOUNDED_COMPLEMENT_CONNECTED_EMPTY THEN + ASM_SIMP_TAC[BOUNDED_PATH_IMAGE; ARC_IMP_PATH] THEN + MATCH_MP_TAC CONNECTED_ARC_COMPLEMENT THEN + ASM_REWRITE_TAC[ARITH_RULE `2 <= n <=> 1 <= n /\ ~(n = 1)`] THEN + REWRITE_TAC[DIMINDEX_GE_1]]);; + +let INSIDE_SIMPLE_CURVE_IMP_CLOSED = prove + (`!g x:real^N. + simple_path g /\ x IN inside(path_image g) + ==> pathfinish g = pathstart g`, + MESON_TAC[ARC_SIMPLE_PATH; INSIDE_ARC_EMPTY; NOT_IN_EMPTY]);; + +(* ------------------------------------------------------------------------- *) +(* The Jordan curve theorem, again approximately following Maehara. *) +(* ------------------------------------------------------------------------- *) + +let JORDAN_CURVE_THEOREM = prove + (`!c:real^1->real^2. + simple_path c /\ pathfinish c = pathstart c + ==> ?ins out. + ~(ins = {}) /\ open ins /\ connected ins /\ + ~(out = {}) /\ open out /\ connected out /\ + bounded ins /\ ~bounded out /\ + ins INTER out = {} /\ + ins UNION out = (:real^2) DIFF path_image c /\ + frontier ins = path_image c /\ + frontier out = path_image c`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPEC `path_image(c:real^1->real^2)` DIAMETER_BOUNDED_BOUND) THEN + MP_TAC(ISPEC `path_image(c:real^1->real^2)` DIAMETER_COMPACT_ATTAINED) THEN + ASM_SIMP_TAC[COMPACT_PATH_IMAGE; PATH_IMAGE_NONEMPTY; SIMPLE_PATH_IMP_PATH; + COMPACT_IMP_BOUNDED; LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`a:real^2`; `b:real^2`] THEN + ABBREV_TAC `m:real^2 = midpoint(a,b)` THEN + POP_ASSUM_LIST(MP_TAC o end_itlist CONJ) THEN REWRITE_TAC[IMP_IMP] THEN + GEOM_ORIGIN_TAC `m:real^2` THEN REPEAT GEN_TAC THEN + REWRITE_TAC[midpoint; VECTOR_ARITH + `inv(&2) % (a + b):real^N = vec 0 <=> a = --b`] THEN + ASM_CASES_TAC `a:real^2 = --b` THEN ASM_REWRITE_TAC[] THEN + POP_ASSUM(K ALL_TAC) THEN + REWRITE_TAC[NORM_ARITH `norm(--b - b) = &2 * norm(b)`] THEN + ASM_CASES_TAC + `diameter(path_image(c:real^1->real^2)) = &2 * norm(b:real^2)` THEN + ASM_REWRITE_TAC[] THEN POP_ASSUM(K ALL_TAC) THEN + GEOM_NORMALIZE_TAC `b:real^2` THEN CONJ_TAC THENL + [REWRITE_TAC[NORM_0; REAL_MUL_RZERO] THEN + REWRITE_TAC[NORM_ARITH `norm(x - y) <= &0 <=> x = y`] THEN + REWRITE_TAC[simple_path; path_image; IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN + REWRITE_TAC[FORALL_IN_IMAGE] THEN + SUBGOAL_THEN + `(vec 0:real^1) IN interval[vec 0,vec 1] /\ + lift(&1 / &2) IN interval[vec 0,vec 1] /\ + ~(lift(&1 / &2) = vec 0) /\ ~(lift(&1 / &2) = vec 1)` + (fun th -> MESON_TAC[th]) THEN + REWRITE_TAC[IN_INTERVAL_1; DROP_VEC; LIFT_DROP; GSYM DROP_EQ] THEN + CONV_TAC REAL_RAT_REDUCE_CONV; + ALL_TAC] THEN + GEOM_BASIS_MULTIPLE_TAC 1 `b:real^2` THEN + GEN_TAC THEN DISCH_TAC THEN + SIMP_TAC[NORM_MUL; NORM_BASIS; DIMINDEX_2; ARITH] THEN + ASM_SIMP_TAC[REAL_ARITH `&0 <= b ==> (abs b * &1 = &1 <=> b = &1)`] THEN + DISCH_TAC THEN POP_ASSUM_LIST(K ALL_TAC) THEN + REWRITE_TAC[VECTOR_MUL_LID; REAL_MUL_RID; GSYM CONJ_ASSOC] THEN + X_GEN_TAC `c:real^1->real^2` THEN STRIP_TAC THEN + SUBGOAL_THEN + `(!z:real^2. z IN path_image c /\ z$1 = -- &1 <=> z = --basis 1) /\ + (!z:real^2. z IN path_image c /\ z$1 = &1 <=> z = basis 1)` + (CONJUNCTS_THEN2 (LABEL_TAC "touchleft") (LABEL_TAC "touchright")) THENL + [CONJ_TAC THEN X_GEN_TAC `z:real^2` THEN EQ_TAC THEN + ASM_SIMP_TAC[BASIS_COMPONENT; VECTOR_NEG_COMPONENT; DIMINDEX_2; ARITH] THEN + STRIP_TAC THENL + [FIRST_X_ASSUM(MP_TAC o ISPECL [`basis 1:real^2`; `z:real^2`]); + FIRST_X_ASSUM(MP_TAC o ISPECL [`--basis 1:real^2`; `z:real^2`])] THEN + ASM_REWRITE_TAC[NORM_LE_SQUARE; DOT_2; VECTOR_SUB_COMPONENT] THEN + ASM_SIMP_TAC[BASIS_COMPONENT; DIMINDEX_2; ARITH; VECTOR_NEG_COMPONENT; + CART_EQ; FORALL_2] THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN REWRITE_TAC[REAL_ARITH + `&4 + (&0 - x) * (&0 - x) <= &4 <=> x pow 2 <= &0`] THEN + ONCE_REWRITE_TAC[REAL_RING `z = &0 <=> z * z = &0`] THEN + SIMP_TAC[REAL_POW_2; REAL_LE_SQUARE; GSYM REAL_LE_ANTISYM]; + ALL_TAC] THEN + SUBGOAL_THEN + `!z:real^2. z IN path_image c ==> abs(z$1) <= &1` + (LABEL_TAC "xbound") THENL + [X_GEN_TAC `z:real^2` THEN STRIP_TAC THEN + REWRITE_TAC[REAL_ABS_BOUNDS] THEN CONJ_TAC THENL + [FIRST_X_ASSUM(MP_TAC o ISPECL [`basis 1:real^2`; `z:real^2`]); + FIRST_X_ASSUM(MP_TAC o ISPECL [`z:real^2`; `--basis 1:real^2`])] THEN + ASM_REWRITE_TAC[] THEN ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN + REWRITE_TAC[REAL_NOT_LE] THEN DISCH_TAC THEN MATCH_MP_TAC(REAL_ARITH + `abs(z$1) <= norm z /\ &2 < z$1 ==> &2 < norm z`) THEN + SIMP_TAC[COMPONENT_LE_NORM; DIMINDEX_2; ARITH] THEN + SIMP_TAC[VECTOR_SUB_COMPONENT; VECTOR_NEG_COMPONENT; + BASIS_COMPONENT; DIMINDEX_2; ARITH] THEN + ASM_REAL_ARITH_TAC; + ALL_TAC] THEN + SUBGOAL_THEN + `!z:real^2. z IN path_image c ==> abs(z$2) <= &9 / &5` + (LABEL_TAC "ybound") THENL + [REPEAT STRIP_TAC THEN FIRST_X_ASSUM(fun th -> + MP_TAC(ISPECL [`basis 1:real^2`; `z:real^2`] th) THEN + MP_TAC(ISPECL [`--basis 1:real^2`; `z:real^2`] th)) THEN + SUBST1_TAC(REAL_ARITH `&9 / &5 = abs(&9 / &5)`) THEN + ASM_REWRITE_TAC[NORM_LE_SQUARE; REAL_LE_SQUARE_ABS] THEN + SIMP_TAC[DOT_2; VECTOR_SUB_COMPONENT; BASIS_COMPONENT; + DIMINDEX_2; ARITH; VECTOR_NEG_COMPONENT] THEN + MP_TAC(ISPEC `(z:real^2)$1` REAL_LE_SQUARE) THEN REAL_ARITH_TAC; + ALL_TAC] THEN + SUBGOAL_THEN + `!z:real^2. z IN path_image c ==> abs(z$2) < &2` + (LABEL_TAC "ybounds") THENL + [ASM_MESON_TAC[REAL_ARITH `x <= &9 / &5 ==> x < &2`]; ALL_TAC] THEN + SUBGOAL_THEN + `?t. t$1 = &0 /\ t IN path_image c /\ + !z:real^2. z$1 = &0 /\ z IN path_image c ==> z$2 <= t$2` + STRIP_ASSUME_TAC THENL + [MP_TAC(ISPECL + [`\z:real^2. z$2`; `{z:real^2 | z$1 = &0} INTER path_image c`] + CONTINUOUS_ATTAINS_SUP) THEN + SIMP_TAC[CONTINUOUS_ON_LIFT_COMPONENT; DIMINDEX_2; ARITH; o_DEF] THEN + REWRITE_TAC[IN_INTER; IN_ELIM_THM; GSYM CONJ_ASSOC] THEN + DISCH_THEN MATCH_MP_TAC THEN + ASM_SIMP_TAC[CLOSED_INTER_COMPACT; COMPACT_PATH_IMAGE; + CLOSED_STANDARD_HYPERPLANE; SIMPLE_PATH_IMP_PATH] THEN + ONCE_REWRITE_TAC[INTER_COMM] THEN REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN + REWRITE_TAC[IN_INTER; IN_ELIM_THM] THEN + MATCH_MP_TAC CONNECTED_IVT_COMPONENT THEN + ASM_SIMP_TAC[CONNECTED_PATH_IMAGE; SIMPLE_PATH_IMP_PATH] THEN + MAP_EVERY EXISTS_TAC [`--basis 1:real^2`; `basis 1:real^2`] THEN + ASM_SIMP_TAC[BASIS_COMPONENT; DIMINDEX_2; ARITH; VECTOR_NEG_COMPONENT] THEN + REAL_ARITH_TAC; + ALL_TAC] THEN + SUBGOAL_THEN + `(abs((t:real^2)$2) <= &9 / &5 /\ abs(t$2) < &2) /\ + t IN interval[--vector[&1; &9 / &5],vector[&1; &9 / &5]] /\ + t IN interval[--vector[&1; &2],vector[&1; &2]]` + STRIP_ASSUME_TAC THENL + [MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN + CONJ_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN + ASM_REWRITE_TAC[IN_INTERVAL; FORALL_2; DIMINDEX_2; VECTOR_2; + VECTOR_NEG_COMPONENT] THEN + REAL_ARITH_TAC; + ALL_TAC] THEN + SUBGOAL_THEN + `?U D. arc U /\ arc D /\ + pathstart U = --basis 1 /\ pathfinish U = basis 1 /\ + pathstart D = basis 1 /\ pathfinish D = --basis 1 /\ + (t:real^2) IN path_image U /\ + (path_image U) INTER (path_image D) = {--basis 1,basis 1} /\ + path_image (c:real^1->real^2) = path_image(U) UNION path_image(D)` + STRIP_ASSUME_TAC THENL + [MP_TAC(ISPECL [`c:real^1->real^2`; `--basis 1:real^2`; `basis 1:real^2`] + EXISTS_DOUBLE_ARC) THEN + ASM_REWRITE_TAC[VECTOR_ARITH `--b = b <=> b = vec 0`] THEN + ASM_SIMP_TAC[BASIS_NONZERO; DIMINDEX_GE_1; LE_REFL] THEN + REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`U:real^1->real^2`; `D:real^1->real^2`] THEN + REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + DISCH_THEN(SUBST_ALL_TAC o SYM) THEN + UNDISCH_TAC `(t:real^2) IN path_image U UNION path_image D` THEN + ASM_SIMP_TAC[PATH_IMAGE_JOIN; ARC_IMP_PATH; IN_UNION] THEN STRIP_TAC THENL + [MAP_EVERY EXISTS_TAC [`U:real^1->real^2`; `D:real^1->real^2`] THEN + ASM_REWRITE_TAC[]; + MAP_EVERY EXISTS_TAC + [`reversepath D:real^1->real^2`; `reversepath U:real^1->real^2`] THEN + ONCE_REWRITE_TAC[INTER_COMM] THEN + ASM_SIMP_TAC[PATHSTART_REVERSEPATH; PATHFINISH_REVERSEPATH; + PATH_IMAGE_JOIN; PATH_IMAGE_REVERSEPATH; SIMPLE_PATH_JOIN_LOOP; + ARC_REVERSEPATH] THEN + ASM SET_TAC[]]; + ALL_TAC] THEN + SUBGOAL_THEN + `path_image U INTER path_image D SUBSET {--basis 1:real^2, basis 1}` + ASSUME_TAC THENL [ASM_REWRITE_TAC[SUBSET_REFL]; ALL_TAC] THEN + SUBGOAL_THEN `simple_path(U ++ D:real^1->real^2)` ASSUME_TAC THENL + [MATCH_MP_TAC SIMPLE_PATH_JOIN_LOOP THEN ASM_REWRITE_TAC[SUBSET_REFL]; + ALL_TAC] THEN + SUBGOAL_THEN + `path_image(U ++ D:real^1->real^2) = path_image(U) UNION path_image(D)` + ASSUME_TAC THENL + [ASM_SIMP_TAC[PATH_IMAGE_JOIN; ARC_IMP_PATH]; ALL_TAC] THEN + UNDISCH_THEN `path_image c :real^2->bool = path_image U UNION path_image D` + SUBST_ALL_TAC THEN POP_ASSUM_LIST(MAP_EVERY + (fun th -> if free_in `c:real^1->real^2` (concl th) then ALL_TAC + else ASSUME_TAC th) o rev) THEN + SUBGOAL_THEN + `path_image(U:real^1->real^2) UNION path_image(D) SUBSET + interval[--vector[&1; &9 / &5],vector[&1; &9 / &5]] /\ + path_image(U) UNION path_image(D) SUBSET + interval[--vector[&1; &2],vector[&1; &2]]` + MP_TAC THENL + [MATCH_MP_TAC(SET_RULE + `p SUBSET s /\ s SUBSET t ==> p SUBSET s /\ p SUBSET t`) THEN + ASM_SIMP_TAC[SUBSET_INTERVAL; SUBSET; DIMINDEX_2; FORALL_2; VECTOR_2; + VECTOR_NEG_COMPONENT; IN_INTERVAL; REAL_BOUNDS_LE] THEN + CONV_TAC REAL_RAT_REDUCE_CONV; + REWRITE_TAC[UNION_SUBSET] THEN STRIP_TAC] THEN + SUBGOAL_THEN + `?p. p$1 = &0 /\ p IN path_image U /\ + !z:real^2. z$1 = &0 /\ z IN path_image U ==> p$2 <= z$2` + STRIP_ASSUME_TAC THENL + [MP_TAC(ISPECL + [`\z:real^2. z$2`; `{z:real^2 | z$1 = &0} INTER path_image U`] + CONTINUOUS_ATTAINS_INF) THEN + SIMP_TAC[CONTINUOUS_ON_LIFT_COMPONENT; DIMINDEX_2; ARITH; o_DEF] THEN + REWRITE_TAC[IN_INTER; IN_ELIM_THM; GSYM CONJ_ASSOC] THEN + DISCH_THEN MATCH_MP_TAC THEN + ASM_SIMP_TAC[CLOSED_INTER_COMPACT; COMPACT_PATH_IMAGE; + CLOSED_STANDARD_HYPERPLANE; ARC_IMP_PATH] THEN + ONCE_REWRITE_TAC[INTER_COMM] THEN REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN + REWRITE_TAC[IN_INTER; IN_ELIM_THM] THEN + MATCH_MP_TAC CONNECTED_IVT_COMPONENT THEN + ASM_SIMP_TAC[CONNECTED_PATH_IMAGE; ARC_IMP_PATH] THEN + MAP_EVERY EXISTS_TAC [`pathstart U:real^2`; `pathfinish U:real^2`] THEN + REWRITE_TAC[PATHSTART_IN_PATH_IMAGE; PATHFINISH_IN_PATH_IMAGE] THEN + ASM_SIMP_TAC[BASIS_COMPONENT; DIMINDEX_2; ARITH; VECTOR_NEG_COMPONENT] THEN + REAL_ARITH_TAC; + ALL_TAC] THEN + SUBGOAL_THEN `(p:real^2)$2 <= (t:real^2)$2` ASSUME_TAC THENL + [ASM_MESON_TAC[]; ALL_TAC] THEN + SUBGOAL_THEN + `(abs((p:real^2)$2) <= &9 / &5 /\ abs(p$2) < &2) /\ + p IN interval[--vector[&1; &9 / &5],vector[&1; &9 / &5]] /\ + p IN interval[--vector[&1; &2],vector[&1; &2]]` + STRIP_ASSUME_TAC THENL + [MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN + CONJ_TAC THENL [ASM_MESON_TAC[IN_UNION]; ALL_TAC] THEN + ASM_REWRITE_TAC[IN_INTERVAL; FORALL_2; DIMINDEX_2; VECTOR_2; + VECTOR_NEG_COMPONENT] THEN + REAL_ARITH_TAC; + ALL_TAC] THEN + MP_TAC(ISPECL [`U:real^1->real^2`; `t:real^2`; `p:real^2`] + EXISTS_SUBPATH_OF_ARC_NOENDS) THEN + ANTS_TAC THENL + [ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC(SET_RULE + `~(a = c) /\ ~(a = d) /\ ~(b = c) /\ ~(b = d) + ==> {a,b} INTER {c,d} = {}`) THEN + REPEAT CONJ_TAC THEN DISCH_THEN(MP_TAC o AP_TERM `\z:real^2. z$1`) THEN + ASM_SIMP_TAC[VECTOR_NEG_COMPONENT; BASIS_COMPONENT; DIMINDEX_2; ARITH] THEN + REAL_ARITH_TAC; + DISCH_THEN(X_CHOOSE_THEN `h:real^1->real^2` STRIP_ASSUME_TAC)] THEN + SUBGOAL_THEN + `~((t:real^2) IN path_image D) /\ ~(p IN path_image D)` + STRIP_ASSUME_TAC THENL + [REPEAT CONJ_TAC THEN + UNDISCH_TAC + `path_image U INTER path_image D SUBSET {--basis 1:real^2, basis 1}` THEN + MATCH_MP_TAC(SET_RULE + `(t IN s ==> t IN u) /\ ~(t IN v) + ==> u SUBSET v ==> ~(t IN s)`) THEN + ASM_SIMP_TAC[IN_INTER] THEN REWRITE_TAC[IN_INSERT; NOT_IN_EMPTY] THEN + DISCH_THEN(DISJ_CASES_THEN (MP_TAC o AP_TERM `\z:real^2. z$1`)) THEN + ASM_SIMP_TAC[VECTOR_NEG_COMPONENT; BASIS_COMPONENT; DIMINDEX_2; ARITH] THEN + REAL_ARITH_TAC; + ALL_TAC] THEN + SUBGOAL_THEN + `?q. q$2 <= (p:real^2)$2 /\ q$1 = &0 /\ q IN path_image D /\ + !z:real^2. z$2 <= p$2 /\ z$1 = &0 /\ z IN path_image D ==> z$2 <= q$2` + STRIP_ASSUME_TAC THENL + [MP_TAC(ISPECL + [`\z:real^2. z$2`; + `{z:real^2 | z$2 <= (p:real^2)$2} INTER + {z:real^2 | z$1 = &0} INTER path_image D`] + CONTINUOUS_ATTAINS_SUP) THEN + SIMP_TAC[CONTINUOUS_ON_LIFT_COMPONENT; DIMINDEX_2; ARITH; o_DEF] THEN + REWRITE_TAC[IN_INTER; IN_ELIM_THM; GSYM CONJ_ASSOC] THEN + DISCH_THEN MATCH_MP_TAC THEN + ASM_SIMP_TAC[CLOSED_INTER_COMPACT; COMPACT_PATH_IMAGE; + CLOSED_STANDARD_HYPERPLANE; ARC_IMP_PATH] THEN + CONJ_TAC THENL + [REWRITE_TAC[GSYM INTER_ASSOC] THEN MATCH_MP_TAC CLOSED_INTER_COMPACT THEN + ASM_SIMP_TAC[COMPACT_PATH_IMAGE; ARC_IMP_PATH] THEN + ASM_SIMP_TAC[CLOSED_INTER; CLOSED_STANDARD_HYPERPLANE; + CLOSED_HALFSPACE_COMPONENT_LE]; + ALL_TAC] THEN + MP_TAC(ISPECL + [`reversepath D:real^1->real^2`; + `linepath(--(&2 % basis 2):real^2,p) ++ reversepath h ++ + linepath(t,&2 % basis 2)`; + `--vector[&1; &2]:real^2`; `vector[&1; &2]:real^2`] + FASHODA) THEN + ASM_SIMP_TAC[ARC_IMP_PATH; PATH_REVERSEPATH; PATH_JOIN; PATH_IMAGE_JOIN; + PATHSTART_JOIN; PATHFINISH_JOIN; PATHSTART_LINEPATH; + PATHFINISH_LINEPATH; PATH_LINEPATH; PATH_IMAGE_REVERSEPATH; + PATHSTART_REVERSEPATH; PATHFINISH_REVERSEPATH] THEN + ANTS_TAC THENL + [ASM_SIMP_TAC[UNION_SUBSET; PATH_IMAGE_LINEPATH; SEGMENT_CONVEX_HULL; + SUBSET_HULL; CONVEX_INTERVAL; INSERT_SUBSET; EMPTY_SUBSET] THEN + SIMP_TAC[IN_INTERVAL; DIMINDEX_2; FORALL_2; VECTOR_NEG_COMPONENT; + VECTOR_MUL_COMPONENT; VECTOR_2; BASIS_COMPONENT; ARITH] THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN ASM SET_TAC[]; + ALL_TAC] THEN + REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; IN_INTER; IN_ELIM_THM] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `z:real^2` THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + ASM_REWRITE_TAC[IN_UNION; PATH_IMAGE_LINEPATH] THEN STRIP_TAC THENL + [MP_TAC(ISPECL [`--(&2 % basis 2):real^2`; `p:real^2`; `z:real^2`] + SEGMENT_VERTICAL) THEN + ASM_SIMP_TAC[VECTOR_MUL_COMPONENT; BASIS_COMPONENT; DIMINDEX_2; ARITH; + VECTOR_NEG_COMPONENT] THEN + ASM_REAL_ARITH_TAC; + UNDISCH_TAC + `path_image(h:real^1->real^2) SUBSET + path_image U DIFF {pathstart U, pathfinish U}` THEN + ASM_REWRITE_TAC[SUBSET] THEN + DISCH_THEN(MP_TAC o SPEC `z:real^2`) THEN ASM SET_TAC[]; + MP_TAC(ISPECL [`t:real^2`; `&2 % basis 2:real^2`; `z:real^2`] + SEGMENT_VERTICAL) THEN + ASM_SIMP_TAC[VECTOR_MUL_COMPONENT; BASIS_COMPONENT; DIMINDEX_2; ARITH; + VECTOR_NEG_COMPONENT] THEN + ASM_CASES_TAC `z:real^2 = t` THENL + [ASM_MESON_TAC[]; UNDISCH_TAC `~(z:real^2 = t)`] THEN + ASM_REWRITE_TAC[CART_EQ; FORALL_2; DIMINDEX_2] THEN + ASM_CASES_TAC `(z:real^2)$1 = &0` THEN + ASM_REWRITE_TAC[REAL_MUL_RZERO] THEN + SUBGOAL_THEN `(z:real^2)$2 <= (t:real^2)$2` MP_TAC THENL + [ASM SET_TAC[]; ASM_REAL_ARITH_TAC]]; + ALL_TAC] THEN + SUBGOAL_THEN + `?b. b$1 = &0 /\ b IN path_image D /\ + !z:real^2. z$1 = &0 /\ z IN path_image D ==> b$2 <= z$2` + STRIP_ASSUME_TAC THENL + [MP_TAC(ISPECL + [`\z:real^2. z$2`; `{z:real^2 | z$1 = &0} INTER path_image D`] + CONTINUOUS_ATTAINS_INF) THEN + SIMP_TAC[CONTINUOUS_ON_LIFT_COMPONENT; DIMINDEX_2; ARITH; o_DEF] THEN + REWRITE_TAC[IN_INTER; IN_ELIM_THM; GSYM CONJ_ASSOC] THEN + DISCH_THEN MATCH_MP_TAC THEN + ASM_SIMP_TAC[CLOSED_INTER_COMPACT; COMPACT_PATH_IMAGE; + CLOSED_STANDARD_HYPERPLANE; ARC_IMP_PATH] THEN + ONCE_REWRITE_TAC[INTER_COMM] THEN REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN + REWRITE_TAC[IN_INTER; IN_ELIM_THM] THEN + MATCH_MP_TAC CONNECTED_IVT_COMPONENT THEN + ASM_SIMP_TAC[CONNECTED_PATH_IMAGE; ARC_IMP_PATH] THEN + MAP_EVERY EXISTS_TAC [`pathfinish D:real^2`; `pathstart D:real^2`] THEN + REWRITE_TAC[PATHSTART_IN_PATH_IMAGE; PATHFINISH_IN_PATH_IMAGE] THEN + ASM_SIMP_TAC[BASIS_COMPONENT; DIMINDEX_2; ARITH; VECTOR_NEG_COMPONENT] THEN + REAL_ARITH_TAC; + ALL_TAC] THEN + MP_TAC(ISPECL [`D:real^1->real^2`; `q:real^2`; `b:real^2`] + EXISTS_SUBPATH_OF_ARC_NOENDS) THEN + ANTS_TAC THENL + [ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC(SET_RULE + `~(a = c) /\ ~(a = d) /\ ~(b = c) /\ ~(b = d) + ==> {a,b} INTER {c,d} = {}`) THEN + REPEAT CONJ_TAC THEN DISCH_THEN(MP_TAC o AP_TERM `\z:real^2. z$1`) THEN + ASM_SIMP_TAC[VECTOR_NEG_COMPONENT; BASIS_COMPONENT; DIMINDEX_2; ARITH] THEN + REAL_ARITH_TAC; + DISCH_THEN(X_CHOOSE_THEN `l:real^1->real^2` STRIP_ASSUME_TAC)] THEN + SUBGOAL_THEN + `~((q:real^2) IN path_image U) /\ ~(b IN path_image U)` + STRIP_ASSUME_TAC THENL + [REPEAT CONJ_TAC THEN + UNDISCH_TAC + `path_image U INTER path_image D SUBSET {--basis 1:real^2, basis 1}` THEN + MATCH_MP_TAC(SET_RULE + `(t IN s ==> t IN u) /\ ~(t IN v) + ==> u SUBSET v ==> ~(t IN s)`) THEN + ASM_SIMP_TAC[IN_INTER] THEN REWRITE_TAC[IN_INSERT; NOT_IN_EMPTY] THEN + DISCH_THEN(DISJ_CASES_THEN (MP_TAC o AP_TERM `\z:real^2. z$1`)) THEN + ASM_SIMP_TAC[VECTOR_NEG_COMPONENT; BASIS_COMPONENT; DIMINDEX_2; ARITH] THEN + REAL_ARITH_TAC; + ALL_TAC] THEN + SUBGOAL_THEN `~(p:real^2 = q)` ASSUME_TAC THENL + [ASM_MESON_TAC[]; ALL_TAC] THEN + SUBGOAL_THEN `(q:real^2)$2 < (p:real^2)$2` ASSUME_TAC THENL + [ASM_REWRITE_TAC[REAL_LT_LE] THEN DISCH_TAC THEN + UNDISCH_TAC `~(p:real^2 = q)` THEN + ASM_REWRITE_TAC[DIMINDEX_2; FORALL_2; CART_EQ]; + ALL_TAC] THEN + ABBREV_TAC `y:real^2 = midpoint(p,q)` THEN + EXISTS_TAC + `connected_component ((:real^2) DIFF path_image(U ++ D)) y` THEN + EXISTS_TAC + `connected_component ((:real^2) DIFF path_image(U ++ D)) + (&2 % basis 2)` THEN + REWRITE_TAC[CONNECTED_COMPONENT_EQ_EMPTY; CONNECTED_CONNECTED_COMPONENT] THEN + ABBREV_TAC `K = (:real^2) DIFF path_image(U ++ D)` THEN + SUBGOAL_THEN `open(K:real^2->bool)` ASSUME_TAC THENL + [EXPAND_TAC "K" THEN REWRITE_TAC[GSYM closed] THEN + ASM_SIMP_TAC[COMPACT_PATH_IMAGE; SIMPLE_PATH_IMP_PATH; + COMPACT_IMP_CLOSED]; + ALL_TAC] THEN + ASM_SIMP_TAC[OPEN_CONNECTED_COMPONENT] THEN + ABBREV_TAC `n:real^2 = &2 % basis 2` THEN + SUBGOAL_THEN `(y:real^2)$1 = &0 /\ (n:real^2)$1 = &0` STRIP_ASSUME_TAC THENL + [MAP_EVERY EXPAND_TAC ["y"; "n"] THEN + SIMP_TAC[BASIS_COMPONENT; VECTOR_MUL_COMPONENT; DIMINDEX_2; ARITH] THEN + REWRITE_TAC[midpoint; VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT] THEN + ASM_REWRITE_TAC[] THEN CONV_TAC REAL_RAT_REDUCE_CONV; + ALL_TAC] THEN + SUBGOAL_THEN `(y:real^2)$2 = ((p:real^2)$2 + (q:real^2)$2) / &2` + ASSUME_TAC THENL + [EXPAND_TAC "y" THEN + REWRITE_TAC[midpoint; VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT] THEN + REAL_ARITH_TAC; + ALL_TAC] THEN + SUBGOAL_THEN `(n:real^2)$2 = &2` ASSUME_TAC THENL + [EXPAND_TAC "n" THEN + SIMP_TAC[BASIS_COMPONENT; VECTOR_MUL_COMPONENT; DIMINDEX_2; ARITH] THEN + REAL_ARITH_TAC; + ALL_TAC] THEN + SUBGOAL_THEN `(b:real^2)$2 <= (q:real^2)$2` ASSUME_TAC THENL + [ASM_MESON_TAC[IN_UNION]; ALL_TAC] THEN + SUBGOAL_THEN + `((abs((q:real^2)$2) <= &9 / &5 /\ abs(q$2) < &2) /\ + q IN interval[--vector[&1; &9 / &5],vector[&1; &9 / &5]] /\ + q IN interval[--vector[&1; &2],vector[&1; &2]]) /\ + ((abs((b:real^2)$2) <= &9 / &5 /\ abs(b$2) < &2) /\ + b IN interval[--vector[&1; &9 / &5],vector[&1; &9 / &5]] /\ + b IN interval[--vector[&1; &2],vector[&1; &2]])` + STRIP_ASSUME_TAC THENL + [CONJ_TAC THEN MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN + (CONJ_TAC THENL [ASM_MESON_TAC[IN_UNION]; ALL_TAC]) THEN + ASM_REWRITE_TAC[IN_INTERVAL; FORALL_2; DIMINDEX_2; VECTOR_2; + VECTOR_NEG_COMPONENT] THEN + REAL_ARITH_TAC; + ALL_TAC] THEN + SUBGOAL_THEN + `path_image(h:real^1->real^2) SUBSET + interval[--vector[&1; &9 / &5],vector[&1; &9 / &5]] /\ + path_image h SUBSET + interval[--vector[&1; &2],vector[&1; &2]] /\ + path_image l SUBSET + interval[--vector[&1; &9 / &5],vector[&1; &9 / &5]] /\ + path_image(l:real^1->real^2) SUBSET + interval[--vector[&1; &2],vector[&1; &2]] /\ + ~(basis 1 IN path_image h) /\ + ~(basis 1 IN path_image l) /\ + ~(--basis 1 IN path_image h) /\ + ~(--basis 1 IN path_image l)` + STRIP_ASSUME_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + SUBGOAL_THEN + `(n:real^2) IN interval[--vector[&1; &2],vector[&1; &2]] /\ + (--n) IN interval[--vector[&1; &2],vector[&1; &2]]` + STRIP_ASSUME_TAC THENL + [ASM_REWRITE_TAC[IN_INTERVAL; DIMINDEX_2; FORALL_2; VECTOR_2; + VECTOR_NEG_COMPONENT] THEN CONV_TAC REAL_RAT_REDUCE_CONV; + ALL_TAC] THEN + SUBGOAL_THEN + `(q:real^2)$2 < (y:real^2)$2 /\ (y:real^2)$2 < (p:real^2)$2 /\ + (q:real^2)$2 <= (y:real^2)$2 /\ (y:real^2)$2 <= (p:real^2)$2` + STRIP_ASSUME_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN + REWRITE_TAC[SYM(ASSUME + `path_image(U ++ D):real^2->bool = path_image U UNION path_image D`)] THEN + ASM_REWRITE_TAC[] THEN + SUBGOAL_THEN `(y:real^2) IN K` ASSUME_TAC THENL + [EXPAND_TAC "K" THEN REWRITE_TAC[IN_UNIV; IN_DIFF] THEN + ASM_REWRITE_TAC[IN_UNION; DE_MORGAN_THM] THEN ASM_MESON_TAC[REAL_NOT_LE]; + ASM_REWRITE_TAC[]] THEN + SUBGOAL_THEN `(n:real^2) IN K` ASSUME_TAC THENL + [EXPAND_TAC "K" THEN ASM_REWRITE_TAC[IN_DIFF; IN_UNIV] THEN + ASM_MESON_TAC[REAL_ARITH `~(abs x < x)`]; + ASM_REWRITE_TAC[]] THEN + MATCH_MP_TAC(TAUT `(a /\ b ==> c) /\ b /\ a /\ d ==> a /\ b /\ c /\ d`) THEN + CONJ_TAC THENL [MESON_TAC[CONNECTED_COMPONENT_NONOVERLAP]; ALL_TAC] THEN + SUBGOAL_THEN + `(y:real^2) IN interval[--vector [&1; &9 / &5],vector [&1; &9 / &5]] /\ + (y:real^2) IN interval[--vector [&1; &2],vector [&1; &2]]` + STRIP_ASSUME_TAC THENL + [REWRITE_TAC[IN_INTERVAL; FORALL_2; DIMINDEX_2; VECTOR_2; + VECTOR_NEG_COMPONENT] THEN + ASM_REAL_ARITH_TAC; + ALL_TAC] THEN + SUBGOAL_THEN + `((:real^2) DIFF interval[--vector [&1; &9 / &5],vector [&1; &9 / &5]]) + SUBSET connected_component K n /\ + ((:real^2) DIFF interval[--vector [&1; &2],vector [&1; &2]]) + SUBSET connected_component K n` + STRIP_ASSUME_TAC THENL + [MATCH_MP_TAC(SET_RULE + `i SUBSET j /\ UNIV DIFF i SUBSET s + ==> UNIV DIFF i SUBSET s /\ UNIV DIFF j SUBSET s`) THEN + REWRITE_TAC[SUBSET_INTERVAL; DIMINDEX_2; FORALL_2; VECTOR_2; + VECTOR_NEG_COMPONENT] THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN + MATCH_MP_TAC CONNECTED_COMPONENT_MAXIMAL THEN + SIMP_TAC[CONNECTED_COMPLEMENT_BOUNDED_CONVEX; LE_REFL; DIMINDEX_2; + BOUNDED_INTERVAL; CONVEX_INTERVAL] THEN + EXPAND_TAC "K" THEN + ASM_REWRITE_TAC[SET_RULE `UNIV DIFF s SUBSET UNIV DIFF t <=> t SUBSET s`; + UNION_SUBSET] THEN + ASM_REWRITE_TAC[IN_UNIV; IN_DIFF; IN_INTERVAL; FORALL_2; DIMINDEX_2; + VECTOR_2; VECTOR_NEG_COMPONENT] THEN + CONV_TAC REAL_RAT_REDUCE_CONV; + ALL_TAC] THEN + SUBGOAL_THEN `~bounded(connected_component K (n:real^2))` ASSUME_TAC THENL + [MATCH_MP_TAC COBOUNDED_IMP_UNBOUNDED THEN + MATCH_MP_TAC BOUNDED_SUBSET THEN + EXISTS_TAC `interval[--vector[&1; &2]:real^2,vector [&1; &2]]` THEN + ONCE_REWRITE_TAC[SET_RULE + `UNIV DIFF s SUBSET t <=> UNIV DIFF t SUBSET s`] THEN + ASM_REWRITE_TAC[BOUNDED_INTERVAL]; + ASM_REWRITE_TAC[]] THEN + SUBGOAL_THEN `bounded(connected_component K (y:real^2))` ASSUME_TAC THENL + [REWRITE_TAC[bounded] THEN EXISTS_TAC `&4` THEN + X_GEN_TAC `z:real^2` THEN REWRITE_TAC[GSYM REAL_NOT_LT] THEN + ASM_SIMP_TAC[GSYM OPEN_PATH_CONNECTED_COMPONENT] THEN + REWRITE_TAC[path_component; IN] THEN + DISCH_THEN(X_CHOOSE_THEN `i:real^1->real^2` STRIP_ASSUME_TAC) THEN + STRIP_TAC THEN + MP_TAC(ISPECL + [`i:real^1->real^2`; `interval[--vector[&1; &2]:real^2,vector[&1; &2]]`] + EXISTS_PATH_SUBPATH_TO_FRONTIER_CLOSED) THEN + ASM_REWRITE_TAC[CLOSED_INTERVAL; NOT_IMP; SUBSET_INTER; + GSYM CONJ_ASSOC] THEN + CONJ_TAC THENL + [REWRITE_TAC[IN_INTERVAL; VECTOR_2; DIMINDEX_2; FORALL_2; + VECTOR_NEG_COMPONENT; GSYM REAL_ABS_BOUNDS] THEN + STRIP_TAC THEN UNDISCH_TAC `&4 < norm(z:real^2)` THEN + REWRITE_TAC[REAL_NOT_LT] THEN + W(MP_TAC o PART_MATCH lhand NORM_LE_L1 o lhand o snd) THEN + REWRITE_TAC[DIMINDEX_2; SUM_2] THEN ASM_REAL_ARITH_TAC; + REWRITE_TAC[IN_DIFF; FRONTIER_CLOSED_INTERVAL; IN_INTERVAL; + FORALL_2; DIMINDEX_2; VECTOR_2; VECTOR_NEG_COMPONENT] THEN + DISCH_THEN(X_CHOOSE_THEN `j:real^1->real^2` MP_TAC) THEN + REPEAT(DISCH_THEN(CONJUNCTS_THEN2 STRIP_ASSUME_TAC MP_TAC)) THEN + ASM_REWRITE_TAC[REAL_LT_LE; REAL_ARITH `x:real = i$j <=> i$j = x`] THEN + REWRITE_TAC[GSYM DE_MORGAN_THM; GSYM DISJ_ASSOC] THEN DISCH_TAC] THEN + SUBGOAL_THEN `path_image(j:real^1->real^2) SUBSET K` ASSUME_TAC THENL + [ASM_MESON_TAC[SUBSET_TRANS]; ALL_TAC] THEN + SUBGOAL_THEN + `~(pathfinish(j):real^2 = basis 1) /\ ~(pathfinish(j):real^2 = --basis 1)` + STRIP_ASSUME_TAC THENL + [REPEAT STRIP_TAC THEN UNDISCH_THEN + `path_image(j:real^1->real^2) SUBSET K` + (MP_TAC o SPEC `pathfinish(j):real^2` o REWRITE_RULE[SUBSET]) THEN + ASM_REWRITE_TAC[PATHFINISH_IN_PATH_IMAGE] THEN + EXPAND_TAC "K" THEN ASM_REWRITE_TAC[IN_DIFF; IN_UNIV; IN_UNION]; + ALL_TAC] THEN + SUBGOAL_THEN + `?e:real^1->real^2. + path e /\ pathstart e = y /\ + ((pathfinish e)$2 = -- &2 \/ (pathfinish e)$2 = &2) /\ + path_image e SUBSET K /\ + path_image e SUBSET interval[--vector [&1; &2],vector [&1; &2]]` + MP_TAC THENL + [FIRST_X_ASSUM(DISJ_CASES_THEN STRIP_ASSUME_TAC) THENL + [UNDISCH_TAC `~((pathfinish j):real^2 = --basis 1)` THEN + SIMP_TAC[CART_EQ; DIMINDEX_2; FORALL_2; BASIS_COMPONENT; + VECTOR_NEG_COMPONENT; ARITH] THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(DISJ_CASES_TAC o MATCH_MP (REAL_ARITH + `~(x = -- &0) ==> x < &0 \/ &0 < x`)) THENL + [EXISTS_TAC `(j:real^1->real^2) ++ + linepath(pathfinish j,--vector [&1; &2])` THEN + ASM_SIMP_TAC[PATH_JOIN; PATHSTART_JOIN; PATHFINISH_JOIN; + PATH_LINEPATH; PATHSTART_LINEPATH; PATHFINISH_LINEPATH; + PATH_IMAGE_JOIN] THEN + REWRITE_TAC[VECTOR_2; VECTOR_NEG_COMPONENT] THEN + REWRITE_TAC[UNION_SUBSET; PATH_IMAGE_LINEPATH] THEN + ONCE_REWRITE_TAC[AC CONJ_ACI + `(a /\ b) /\ c /\ d <=> (a /\ c) /\ b /\ d`] THEN + CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN EXPAND_TAC "K" THEN + MATCH_MP_TAC(SET_RULE + `(!x. x IN s ==> x IN t /\ ~(x IN u)) + ==> s SUBSET (UNIV DIFF u) /\ s SUBSET t`) THEN + X_GEN_TAC `x:real^2` THEN DISCH_TAC THEN + MP_TAC(ISPECL [`pathfinish(j:real^1->real^2)`; + `--vector[&1; &2]:real^2`; + `x:real^2`] SEGMENT_VERTICAL) THEN + ASM_SIMP_TAC[VECTOR_NEG_COMPONENT; VECTOR_2; IN_INTERVAL; + FORALL_2; DIMINDEX_2] THEN + DISCH_TAC THEN CONJ_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN + DISCH_TAC THEN + UNDISCH_THEN + `!z:real^2. z IN path_image U UNION path_image D /\ z$1 = -- &1 <=> + z = --basis 1` + (MP_TAC o SPEC `x:real^2`) THEN + ASM_REWRITE_TAC[] THEN + ASM_SIMP_TAC[CART_EQ; DIMINDEX_2; FORALL_2; BASIS_COMPONENT; + VECTOR_NEG_COMPONENT; ARITH; REAL_NEG_0] THEN + ASM_REAL_ARITH_TAC; + EXISTS_TAC `(j:real^1->real^2) ++ + linepath(pathfinish j,vector [-- &1; &2])` THEN + ASM_SIMP_TAC[PATH_JOIN; PATHSTART_JOIN; PATHFINISH_JOIN; + PATH_LINEPATH; PATHSTART_LINEPATH; PATHFINISH_LINEPATH; + PATH_IMAGE_JOIN] THEN + REWRITE_TAC[VECTOR_2; VECTOR_NEG_COMPONENT] THEN + REWRITE_TAC[UNION_SUBSET; PATH_IMAGE_LINEPATH] THEN + ONCE_REWRITE_TAC[AC CONJ_ACI + `(a /\ b) /\ c /\ d <=> (a /\ c) /\ b /\ d`] THEN + CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN EXPAND_TAC "K" THEN + MATCH_MP_TAC(SET_RULE + `(!x. x IN s ==> x IN t /\ ~(x IN u)) + ==> s SUBSET (UNIV DIFF u) /\ s SUBSET t`) THEN + X_GEN_TAC `x:real^2` THEN DISCH_TAC THEN + MP_TAC(ISPECL [`pathfinish(j:real^1->real^2)`; + `vector[-- &1; &2]:real^2`; + `x:real^2`] SEGMENT_VERTICAL) THEN + ASM_SIMP_TAC[VECTOR_NEG_COMPONENT; VECTOR_2; IN_INTERVAL; + FORALL_2; DIMINDEX_2] THEN + DISCH_TAC THEN CONJ_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN + DISCH_TAC THEN + UNDISCH_THEN + `!z:real^2. z IN path_image U UNION path_image D /\ z$1 = -- &1 <=> + z = --basis 1` + (MP_TAC o SPEC `x:real^2`) THEN + ASM_REWRITE_TAC[] THEN + ASM_SIMP_TAC[CART_EQ; DIMINDEX_2; FORALL_2; BASIS_COMPONENT; + VECTOR_NEG_COMPONENT; ARITH; REAL_NEG_0] THEN + ASM_REAL_ARITH_TAC]; + UNDISCH_TAC `~((pathfinish j):real^2 = basis 1)` THEN + SIMP_TAC[CART_EQ; DIMINDEX_2; FORALL_2; BASIS_COMPONENT; + VECTOR_NEG_COMPONENT; ARITH] THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(DISJ_CASES_TAC o MATCH_MP (REAL_ARITH + `~(x = &0) ==> x < &0 \/ &0 < x`)) THENL + [EXISTS_TAC `(j:real^1->real^2) ++ + linepath(pathfinish j,vector [&1; -- &2])` THEN + ASM_SIMP_TAC[PATH_JOIN; PATHSTART_JOIN; PATHFINISH_JOIN; + PATH_LINEPATH; PATHSTART_LINEPATH; PATHFINISH_LINEPATH; + PATH_IMAGE_JOIN] THEN + REWRITE_TAC[VECTOR_2; VECTOR_NEG_COMPONENT] THEN + REWRITE_TAC[UNION_SUBSET; PATH_IMAGE_LINEPATH] THEN + ONCE_REWRITE_TAC[AC CONJ_ACI + `(a /\ b) /\ c /\ d <=> (a /\ c) /\ b /\ d`] THEN + CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN EXPAND_TAC "K" THEN + MATCH_MP_TAC(SET_RULE + `(!x. x IN s ==> x IN t /\ ~(x IN u)) + ==> s SUBSET (UNIV DIFF u) /\ s SUBSET t`) THEN + X_GEN_TAC `x:real^2` THEN DISCH_TAC THEN + MP_TAC(ISPECL [`pathfinish(j:real^1->real^2)`; + `vector[&1; -- &2]:real^2`; + `x:real^2`] SEGMENT_VERTICAL) THEN + ASM_SIMP_TAC[VECTOR_NEG_COMPONENT; VECTOR_2; IN_INTERVAL; + FORALL_2; DIMINDEX_2] THEN + DISCH_TAC THEN CONJ_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN + DISCH_TAC THEN + UNDISCH_THEN + `!z:real^2. z IN path_image U UNION path_image D /\ z$1 = &1 <=> + z = basis 1` + (MP_TAC o SPEC `x:real^2`) THEN + ASM_REWRITE_TAC[] THEN + ASM_SIMP_TAC[CART_EQ; DIMINDEX_2; FORALL_2; BASIS_COMPONENT; + VECTOR_NEG_COMPONENT; ARITH; REAL_NEG_0] THEN + ASM_REAL_ARITH_TAC; + EXISTS_TAC `(j:real^1->real^2) ++ + linepath(pathfinish j,vector [&1; &2])` THEN + ASM_SIMP_TAC[PATH_JOIN; PATHSTART_JOIN; PATHFINISH_JOIN; + PATH_LINEPATH; PATHSTART_LINEPATH; PATHFINISH_LINEPATH; + PATH_IMAGE_JOIN] THEN + REWRITE_TAC[VECTOR_2; VECTOR_NEG_COMPONENT] THEN + REWRITE_TAC[UNION_SUBSET; PATH_IMAGE_LINEPATH] THEN + ONCE_REWRITE_TAC[AC CONJ_ACI + `(a /\ b) /\ c /\ d <=> (a /\ c) /\ b /\ d`] THEN + CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN EXPAND_TAC "K" THEN + MATCH_MP_TAC(SET_RULE + `(!x. x IN s ==> x IN t /\ ~(x IN u)) + ==> s SUBSET (UNIV DIFF u) /\ s SUBSET t`) THEN + X_GEN_TAC `x:real^2` THEN DISCH_TAC THEN + MP_TAC(ISPECL [`pathfinish(j:real^1->real^2)`; + `vector[&1; &2]:real^2`; + `x:real^2`] SEGMENT_VERTICAL) THEN + ASM_SIMP_TAC[VECTOR_NEG_COMPONENT; VECTOR_2; IN_INTERVAL; + FORALL_2; DIMINDEX_2] THEN + DISCH_TAC THEN CONJ_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN + DISCH_TAC THEN + UNDISCH_THEN + `!z:real^2. z IN path_image U UNION path_image D /\ z$1 = &1 <=> + z = basis 1` + (MP_TAC o SPEC `x:real^2`) THEN + ASM_REWRITE_TAC[] THEN + ASM_SIMP_TAC[CART_EQ; DIMINDEX_2; FORALL_2; BASIS_COMPONENT; + VECTOR_NEG_COMPONENT; ARITH; REAL_NEG_0] THEN + ASM_REAL_ARITH_TAC]; + EXISTS_TAC `j:real^1->real^2` THEN ASM_REWRITE_TAC[]; + EXISTS_TAC `j:real^1->real^2` THEN ASM_REWRITE_TAC[]]; + FIRST_X_ASSUM(K ALL_TAC o check (is_disj o concl))] THEN + STRIP_TAC THENL + [MP_TAC(ISPECL [`reversepath(D:real^1->real^2)`; + `reversepath e ++ linepath(y,p) ++ reversepath h ++ + linepath(t:real^2,vector[t$1;&2])`; + `--vector[&1; &2]:real^2`; `vector[&1; &2]:real^2`] + FASHODA) THEN + ASM_SIMP_TAC + [PATH_REVERSEPATH; ARC_IMP_PATH; PATH_JOIN; + PATH_LINEPATH; PATHSTART_LINEPATH; PATHFINISH_LINEPATH; + PATHSTART_REVERSEPATH; PATHFINISH_REVERSEPATH; PATH_IMAGE_JOIN; + PATHSTART_JOIN; PATHFINISH_JOIN; PATH_IMAGE_REVERSEPATH] THEN + SIMP_TAC[VECTOR_2; VECTOR_NEG_COMPONENT; BASIS_COMPONENT; + DIMINDEX_2; ARITH; NOT_IMP; GSYM CONJ_ASSOC] THEN + CONJ_TAC THENL + [ASM_SIMP_TAC[UNION_SUBSET; PATH_IMAGE_LINEPATH; SEGMENT_CONVEX_HULL; + SUBSET_HULL; CONVEX_INTERVAL; INSERT_SUBSET; EMPTY_SUBSET] THEN + REWRITE_TAC[IN_INTERVAL; DIMINDEX_2; FORALL_2; VECTOR_NEG_COMPONENT; + VECTOR_2] THEN + CONV_TAC REAL_RAT_REDUCE_CONV; + DISCH_THEN(X_CHOOSE_THEN `x:real^2` + (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + REWRITE_TAC[DE_MORGAN_THM; IN_UNION] THEN REPEAT CONJ_TAC THENL + [ASM SET_TAC[]; + REWRITE_TAC[PATH_IMAGE_LINEPATH] THEN DISCH_TAC THEN + MP_TAC(ISPECL [`y:real^2`; `p:real^2`; `x:real^2`] + SEGMENT_VERTICAL) THEN + ASM_REWRITE_TAC[] THEN + UNDISCH_THEN + `!z:real^2. z$2 <= (p:real^2)$2 /\ z$1 = &0 /\ z IN path_image D + ==> z$2 <= (q:real^2)$2` + (MP_TAC o SPEC `x:real^2`) THEN + ASM_REWRITE_TAC[] THEN ASM_REAL_ARITH_TAC; + DISCH_TAC THEN + UNDISCH_THEN + `path_image(h:real^1->real^2) SUBSET + (path_image U) DIFF {pathstart U, pathfinish U}` + (MP_TAC o SPEC `x:real^2` o REWRITE_RULE[SUBSET]) THEN + ASM_REWRITE_TAC[] THEN ASM SET_TAC[]; + REWRITE_TAC[PATH_IMAGE_LINEPATH] THEN DISCH_TAC THEN + MP_TAC(ISPECL [`t:real^2`; `vector[&0;&2]:real^2`; `x:real^2`] + SEGMENT_VERTICAL) THEN + ASM_REWRITE_TAC[VECTOR_2] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + ASM_CASES_TAC `x:real^2 = t` THENL + [ASM_MESON_TAC[]; UNDISCH_TAC `~(x:real^2 = t)`] THEN + ASM_REWRITE_TAC[CART_EQ; DIMINDEX_2; FORALL_2] THEN + UNDISCH_THEN + `!z:real^2. z$1 = &0 /\ z IN path_image U UNION path_image D + ==> z$2 <= (t:real^2)$2` + (MP_TAC o SPEC `x:real^2`) THEN + ASM_REWRITE_TAC[IN_UNION] THEN ASM_REAL_ARITH_TAC]]; + MP_TAC(ISPECL [`U:real^1->real^2`; + `linepath(vector[b$1; -- &2],b) ++ + reversepath l ++ + linepath(q:real^2,y) ++ e`; + `--vector[&1; &2]:real^2`; `vector[&1; &2]:real^2`] + FASHODA) THEN + ASM_SIMP_TAC + [PATH_REVERSEPATH; ARC_IMP_PATH; PATH_JOIN; + PATH_LINEPATH; PATHSTART_LINEPATH; PATHFINISH_LINEPATH; + PATHSTART_REVERSEPATH; PATHFINISH_REVERSEPATH; PATH_IMAGE_JOIN; + PATHSTART_JOIN; PATHFINISH_JOIN; PATH_IMAGE_REVERSEPATH] THEN + SIMP_TAC[VECTOR_2; VECTOR_NEG_COMPONENT; BASIS_COMPONENT; + DIMINDEX_2; ARITH; NOT_IMP; GSYM CONJ_ASSOC] THEN + CONJ_TAC THENL + [ASM_SIMP_TAC[UNION_SUBSET; PATH_IMAGE_LINEPATH; SEGMENT_CONVEX_HULL; + SUBSET_HULL; CONVEX_INTERVAL; INSERT_SUBSET; EMPTY_SUBSET] THEN + REWRITE_TAC[IN_INTERVAL; DIMINDEX_2; FORALL_2; VECTOR_NEG_COMPONENT; + VECTOR_2] THEN + CONV_TAC REAL_RAT_REDUCE_CONV; + DISCH_THEN(X_CHOOSE_THEN `x:real^2` + (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + REWRITE_TAC[DE_MORGAN_THM; IN_UNION] THEN REPEAT CONJ_TAC THENL + [REWRITE_TAC[PATH_IMAGE_LINEPATH] THEN DISCH_TAC THEN + MP_TAC(ISPECL [`vector[&0; -- &2]:real^2`; `b:real^2`; `x:real^2`] + SEGMENT_VERTICAL) THEN + ASM_REWRITE_TAC[VECTOR_2] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + ASM_CASES_TAC `x:real^2 = b` THENL + [ASM_MESON_TAC[]; UNDISCH_TAC `~(x:real^2 = b)`] THEN + ASM_REWRITE_TAC[CART_EQ; DIMINDEX_2; FORALL_2] THEN + UNDISCH_THEN + `!z:real^2. z$1 = &0 /\ z IN path_image U ==> (p:real^2)$2 <= z$2` + (MP_TAC o SPEC `x:real^2`) THEN + ASM_REWRITE_TAC[] THEN ASM_REAL_ARITH_TAC; + DISCH_TAC THEN UNDISCH_THEN + `path_image(l:real^1->real^2) SUBSET + (path_image D) DIFF {pathstart D, pathfinish D}` + (MP_TAC o SPEC `x:real^2` o REWRITE_RULE[SUBSET]) THEN + ASM_REWRITE_TAC[] THEN ASM SET_TAC[]; + REWRITE_TAC[PATH_IMAGE_LINEPATH] THEN DISCH_TAC THEN + MP_TAC(ISPECL [`q:real^2`; `y:real^2`; `x:real^2`] + SEGMENT_VERTICAL) THEN + ASM_REWRITE_TAC[] THEN + UNDISCH_THEN + `!z:real^2. z$1 = &0 /\ z IN path_image U ==> (p:real^2)$2 <= z$2` + (MP_TAC o SPEC `x:real^2`) THEN + ASM_REWRITE_TAC[] THEN ASM_REAL_ARITH_TAC; + ASM SET_TAC[]]]]; + ASM_REWRITE_TAC[]] THEN + SUBGOAL_THEN + `!x:real^2. x IN K /\ ~bounded(connected_component K x) + ==> connected_component K x = connected_component K n` + ASSUME_TAC THENL + [X_GEN_TAC `z:real^2` THEN DISCH_TAC THEN + MATCH_MP_TAC COBOUNDED_UNIQUE_UNBOUNDED_COMPONENT THEN + ASM_REWRITE_TAC[DIMINDEX_2; LE_REFL] THEN EXPAND_TAC "K" THEN + REWRITE_TAC[SET_RULE `UNIV DIFF (UNIV DIFF s) = s`] THEN + ASM_SIMP_TAC[COMPACT_PATH_IMAGE; COMPACT_IMP_BOUNDED; + SIMPLE_PATH_IMP_PATH]; + ALL_TAC] THEN + SUBGOAL_THEN + `!x:real^2. x IN K + ==> frontier(connected_component K x) = + path_image U UNION path_image D` + ASSUME_TAC THENL + [X_GEN_TAC `x:real^2` THEN DISCH_TAC THEN REWRITE_TAC[frontier] THEN + ASM_SIMP_TAC[OPEN_CONNECTED_COMPONENT; INTERIOR_OPEN] THEN + MATCH_MP_TAC(SET_RULE `s SUBSET t /\ ~(s PSUBSET t) ==> s = t`) THEN + CONJ_TAC THENL + [REWRITE_TAC[SUBSET; IN_DIFF] THEN X_GEN_TAC `w:real^2` THEN + ASM_CASES_TAC `(w:real^2) IN K` THENL [ALL_TAC; ASM SET_TAC[]] THEN + ASM_SIMP_TAC[IN_CLOSURE_CONNECTED_COMPONENT] THEN CONV_TAC TAUT; + DISCH_TAC] THEN + SUBGOAL_THEN + `?A:real^1->real^2. + arc A /\ + (closure (connected_component K x) DIFF connected_component K x) + SUBSET path_image A /\ + path_image A SUBSET path_image(U) UNION path_image(D)` + STRIP_ASSUME_TAC THENL + [SUBST1_TAC(SYM(ASSUME + `path_image(U ++ D:real^1->real^2) = + path_image U UNION path_image D`)) THEN + MATCH_MP_TAC EXISTS_ARC_PSUBSET_SIMPLE_PATH THEN + ASM_REWRITE_TAC[] THEN + ASM_SIMP_TAC[CLOSED_DIFF; CLOSED_CLOSURE; OPEN_CONNECTED_COMPONENT]; + ALL_TAC] THEN + MP_TAC(ISPEC `A:real^1->real^2` RETRACTION_ARC) THEN + ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `rr:real^2->real^2` STRIP_ASSUME_TAC) THEN + ASM_CASES_TAC `bounded(connected_component K (x:real^2))` THENL + [MP_TAC(ISPECL [`connected_component K (x:real^2)`; + `path_image(A:real^1->real^2)`; + `rr:real^2->real^2`] + FRONTIER_SUBSET_RETRACTION) THEN + ASM_REWRITE_TAC[NOT_IMP; GSYM CONJ_ASSOC] THEN + ASM_SIMP_TAC[frontier; INTERIOR_OPEN; OPEN_CONNECTED_COMPONENT] THEN + CONJ_TAC THENL + [ASM_MESON_TAC[CONTINUOUS_ON_SUBSET; SUBSET_UNIV]; ALL_TAC] THEN + CONJ_TAC THENL [ASM SET_TAC[]; REWRITE_TAC[SUBSET]] THEN + DISCH_THEN(MP_TAC o SPEC `x:real^2`) THEN + GEN_REWRITE_TAC (LAND_CONV o LAND_CONV) [IN] THEN + ASM_REWRITE_TAC[CONNECTED_COMPONENT_REFL_EQ] THEN DISCH_TAC THEN + UNDISCH_TAC `(x:real^2) IN K` THEN + UNDISCH_TAC `path_image(A:real^1->real^2) SUBSET + path_image U UNION path_image D` THEN + REWRITE_TAC[SUBSET] THEN EXPAND_TAC "K" THEN + REWRITE_TAC[IN_UNIV; IN_DIFF] THEN + DISCH_THEN(MP_TAC o SPEC `x:real^2`) THEN ASM_REWRITE_TAC[]; + MP_TAC(ISPECL [`(:real^2) DIFF (connected_component K (x:real^2))`; + `path_image(A:real^1->real^2)`; + `rr:real^2->real^2`] + FRONTIER_SUBSET_RETRACTION) THEN + ASM_REWRITE_TAC[FRONTIER_COMPLEMENT; NOT_IMP; GSYM CONJ_ASSOC] THEN + UNDISCH_THEN + `!x:real^2. x IN K /\ ~bounded (connected_component K x) + ==> connected_component K x = connected_component K n` + (MP_TAC o SPEC `x:real^2`) THEN + ASM_REWRITE_TAC[] THEN DISCH_THEN SUBST_ALL_TAC THEN REPEAT CONJ_TAC THENL + [MATCH_MP_TAC BOUNDED_SUBSET THEN + EXISTS_TAC `interval[--vector[&1; &2]:real^2,vector [&1; &2]]` THEN + ONCE_REWRITE_TAC[SET_RULE + `UNIV DIFF s SUBSET t <=> UNIV DIFF t SUBSET s`] THEN + ASM_REWRITE_TAC[BOUNDED_INTERVAL]; + REWRITE_TAC[frontier] THEN FIRST_ASSUM(MATCH_MP_TAC o MATCH_MP + (SET_RULE `s DIFF t SUBSET u ==> t' = t ==> s DIFF t' SUBSET u`)) THEN + MATCH_MP_TAC INTERIOR_OPEN THEN + MATCH_MP_TAC OPEN_CONNECTED_COMPONENT THEN ASM_REWRITE_TAC[]; + MATCH_MP_TAC CONTINUOUS_ON_SUBSET THEN EXISTS_TAC `(:real^2)` THEN + ASM_REWRITE_TAC[SUBSET_UNIV]; + MATCH_MP_TAC(SET_RULE + `IMAGE f UNIV SUBSET s ==> IMAGE f t SUBSET s`) THEN + ASM_REWRITE_TAC[]; + UNDISCH_TAC + `path_image(A:real^1->real^2) SUBSET + path_image U UNION path_image D` THEN + MATCH_MP_TAC(SET_RULE + `!y. y IN c /\ ~(y IN p) ==> a SUBSET p ==> ~(c SUBSET a)`) THEN + EXISTS_TAC `y:real^2` THEN REWRITE_TAC[IN_DIFF; IN_UNIV] THEN + CONJ_TAC THENL + [DISCH_THEN(MP_TAC o MATCH_MP CONNECTED_COMPONENT_EQ) THEN + DISCH_THEN SUBST_ALL_TAC THEN ASM_MESON_TAC[]; + UNDISCH_TAC `(y:real^2) IN K` THEN EXPAND_TAC "K" THEN + REWRITE_TAC[IN_UNIV; IN_DIFF] THEN ASM_REWRITE_TAC[]]]]; + ALL_TAC] THEN + CONJ_TAC THENL [ALL_TAC; ASM_MESON_TAC[]] THEN + MATCH_MP_TAC SUBSET_ANTISYM THEN + REWRITE_TAC[UNION_SUBSET; CONNECTED_COMPONENT_SUBSET] THEN + REWRITE_TAC[SUBSET; IN_UNION; IN_ELIM_THM] THEN X_GEN_TAC `x:real^2` THEN + DISCH_THEN(fun th -> ASSUME_TAC th THEN + MP_TAC(MATCH_MP CONNECTED_COMPONENT_REFL th)) THEN + GEN_REWRITE_TAC LAND_CONV [GSYM IN] THEN + ASM_CASES_TAC + `connected_component K (x:real^2) = connected_component K y` THEN + ASM_REWRITE_TAC[] THEN SIMP_TAC[] THEN + ASM_CASES_TAC + `connected_component K (x:real^2) = connected_component K n` THEN + ASM_REWRITE_TAC[] THEN SIMP_TAC[] THEN DISCH_TAC THEN + MATCH_MP_TAC(TAUT `F ==> p`) THEN + SUBGOAL_THEN `bounded(connected_component K (x:real^2))` ASSUME_TAC THENL + [ASM_MESON_TAC[]; ALL_TAC] THEN + ABBREV_TAC + `bp = (linepath(n:real^2,t) ++ h) ++ + linepath(p,q) ++ + (l ++ linepath(b,--n))` THEN + SUBGOAL_THEN + `path_image bp SUBSET + ((path_image U UNION path_image D) DIFF {--basis 1:real^2,basis 1}) UNION + (connected_component K n) UNION (connected_component K y)` + (LABEL_TAC "*") THENL + [EXPAND_TAC "bp" THEN + REPEAT(MATCH_MP_TAC SUBSET_PATH_IMAGE_JOIN THEN CONJ_TAC) THEN + REPEAT CONJ_TAC THENL + [MATCH_MP_TAC(SET_RULE + `(path_image(linepath(n,t)) DELETE t) SUBSET nn /\ + t IN uu DIFF kk + ==> path_image(linepath(n,t)) SUBSET + ((uu UNION dd) DIFF kk) UNION nn UNION yy`) THEN + ASM_REWRITE_TAC[IN_DIFF; IN_INSERT; NOT_IN_EMPTY] THEN CONJ_TAC THENL + [ALL_TAC; + SIMP_TAC[CART_EQ; FORALL_2; DIMINDEX_2; BASIS_COMPONENT; + VECTOR_NEG_COMPONENT; ARITH; REAL_NEG_0] THEN + ASM_REWRITE_TAC[] THEN CONV_TAC REAL_RAT_REDUCE_CONV] THEN + MATCH_MP_TAC CONNECTED_COMPONENT_MAXIMAL THEN + SIMP_TAC[CONVEX_CONNECTED; PATH_IMAGE_LINEPATH; + CONVEX_SEMIOPEN_SEGMENT; IN_DELETE; ENDS_IN_SEGMENT] THEN + CONJ_TAC THENL + [DISCH_THEN(MP_TAC o AP_TERM `\z:real^2. z$2`) THEN + ASM_REWRITE_TAC[] THEN ASM_REAL_ARITH_TAC; + ALL_TAC] THEN + REWRITE_TAC[SUBSET; IN_DELETE] THEN X_GEN_TAC `w:real^2` THEN + STRIP_TAC THEN + MP_TAC(ISPECL [`n:real^2`; `t:real^2`; `w:real^2`] SEGMENT_VERTICAL) THEN + ASM_REWRITE_TAC[] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + UNDISCH_TAC `~(w:real^2 = t)` THEN + ASM_REWRITE_TAC[CART_EQ; FORALL_2; DIMINDEX_2; IMP_IMP] THEN + DISCH_THEN(MP_TAC o MATCH_MP (REAL_ARITH + `~(w = t) /\ (&2 <= w /\ w <= t \/ t <= w /\ w <= &2) + ==> abs(t) < &2 ==> t < w`)) THEN + MATCH_MP_TAC(TAUT `a /\ (~c ==> ~b) ==> (a ==> b) ==> c`) THEN + CONJ_TAC THENL + [FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[IN_UNION]; + EXPAND_TAC "K" THEN + ASM_REWRITE_TAC[IN_DIFF; IN_UNIV; REAL_NOT_LT] THEN ASM_MESON_TAC[]]; + MATCH_MP_TAC SUBSET_TRANS THEN + EXISTS_TAC `path_image U DIFF {pathstart U:real^2, pathfinish U}` THEN + ASM_REWRITE_TAC[] THEN CONV_TAC SET_RULE; + MATCH_MP_TAC(SET_RULE + `(p IN uu /\ q IN dd /\ ~(p IN kk) /\ ~(q IN kk)) /\ + (path_image(linepath(p,q)) DIFF {p,q}) SUBSET yy + ==> path_image(linepath(p,q)) SUBSET + ((uu UNION dd) DIFF kk) UNION nn UNION yy`) THEN + ASM_REWRITE_TAC[IN_INSERT; NOT_IN_EMPTY] THEN CONJ_TAC THENL + [SIMP_TAC[CART_EQ; FORALL_2; DIMINDEX_2; BASIS_COMPONENT; + VECTOR_NEG_COMPONENT; ARITH; REAL_NEG_0] THEN + ASM_REWRITE_TAC[] THEN CONV_TAC REAL_RAT_REDUCE_CONV; + ALL_TAC] THEN + MATCH_MP_TAC CONNECTED_COMPONENT_MAXIMAL THEN + REWRITE_TAC[PATH_IMAGE_LINEPATH; GSYM open_segment] THEN + REWRITE_TAC[CONNECTED_SEGMENT] THEN EXPAND_TAC "y" THEN + REWRITE_TAC[MIDPOINT_IN_SEGMENT] THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[open_segment; SUBSET; IN_DIFF; IN_INSERT; NOT_IN_EMPTY] THEN + X_GEN_TAC `w:real^2` THEN REWRITE_TAC[DE_MORGAN_THM] THEN STRIP_TAC THEN + MP_TAC(ISPECL [`p:real^2`; `q:real^2`; `w:real^2`] SEGMENT_VERTICAL) THEN + ASM_REWRITE_TAC[] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + MAP_EVERY UNDISCH_TAC [`~(w:real^2 = p)`; `~(w:real^2 = q)`] THEN + ASM_REWRITE_TAC[CART_EQ; FORALL_2; DIMINDEX_2; IMP_IMP] THEN + DISCH_THEN(MP_TAC o MATCH_MP (REAL_ARITH + `(~(w = q) /\ ~(w = p)) /\ + (p <= w /\ w <= q \/ q <= w /\ w <= p) + ==> q < p ==> q < w /\ w < p`)) THEN + ASM_REWRITE_TAC[] THEN STRIP_TAC THEN + MAP_EVERY (C UNDISCH_THEN (MP_TAC o SPEC `w:real^2`)) + [`!z:real^2. z$2 <= (p:real^2)$2 /\ z$1 = &0 /\ z IN path_image D + ==> z$2 <= (q:real^2)$2`; + `!z:real^2. z$1 = &0 /\ z IN path_image U ==> (p:real^2)$2 <= z$2`] THEN + ASM_REWRITE_TAC[GSYM REAL_NOT_LT] THEN DISCH_TAC THEN + EXPAND_TAC "K" THEN ASM_REWRITE_TAC[IN_DIFF; IN_UNIV; IN_UNION] THEN + MATCH_MP_TAC(TAUT `~p ==> ~(~p /\ q) ==> ~q`) THEN ASM_REAL_ARITH_TAC; + MATCH_MP_TAC SUBSET_TRANS THEN + EXISTS_TAC `path_image D DIFF {pathstart D:real^2, pathfinish D}` THEN + ASM_REWRITE_TAC[] THEN CONV_TAC SET_RULE; + MATCH_MP_TAC(SET_RULE + `(path_image(linepath(b,n)) DELETE b) SUBSET nn /\ + b IN dd DIFF kk + ==> path_image(linepath(b,n)) SUBSET + ((uu UNION dd) DIFF kk) UNION nn UNION yy`) THEN + ASM_REWRITE_TAC[IN_DIFF; IN_INSERT; NOT_IN_EMPTY] THEN CONJ_TAC THENL + [ALL_TAC; + SIMP_TAC[CART_EQ; FORALL_2; DIMINDEX_2; BASIS_COMPONENT; + VECTOR_NEG_COMPONENT; ARITH; REAL_NEG_0] THEN + ASM_REWRITE_TAC[] THEN CONV_TAC REAL_RAT_REDUCE_CONV] THEN + SUBGOAL_THEN + `connected_component K (n:real^2) = connected_component K (--n)` + SUBST1_TAC THENL + [CONV_TAC SYM_CONV THEN + MATCH_MP_TAC CONNECTED_COMPONENT_EQ THEN + MATCH_MP_TAC(REWRITE_RULE[SUBSET] + (ASSUME `(:real^2) DIFF + interval[--vector [&1; &9 / &5],vector [&1; &9 / &5]] SUBSET + connected_component K n`)) THEN + ASM_REWRITE_TAC[IN_UNIV; IN_DIFF; IN_INTERVAL; DIMINDEX_2; FORALL_2; + VECTOR_NEG_COMPONENT; VECTOR_2] THEN + CONV_TAC REAL_RAT_REDUCE_CONV; + ALL_TAC] THEN + MATCH_MP_TAC CONNECTED_COMPONENT_MAXIMAL THEN + SIMP_TAC[CONVEX_CONNECTED; PATH_IMAGE_LINEPATH; + CONVEX_SEMIOPEN_SEGMENT; IN_DELETE; ENDS_IN_SEGMENT] THEN + CONJ_TAC THENL + [DISCH_THEN(MP_TAC o AP_TERM `\z:real^2. z$2`) THEN + ASM_REWRITE_TAC[VECTOR_NEG_COMPONENT] THEN ASM_REAL_ARITH_TAC; + ALL_TAC] THEN + REWRITE_TAC[SUBSET; IN_DELETE] THEN X_GEN_TAC `w:real^2` THEN + STRIP_TAC THEN + MP_TAC(ISPECL [`b:real^2`; `--n:real^2`; `w:real^2`] + SEGMENT_VERTICAL) THEN + ASM_REWRITE_TAC[VECTOR_NEG_COMPONENT; REAL_NEG_0] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + UNDISCH_TAC `~(w:real^2 = b)` THEN + ASM_REWRITE_TAC[CART_EQ; FORALL_2; DIMINDEX_2; IMP_IMP] THEN + DISCH_THEN(MP_TAC o MATCH_MP (REAL_ARITH + `~(w = b) /\ (b <= w /\ w <= -- &2 \/ -- &2 <= w /\ w <= b) + ==> abs(b) < &2 ==> w < b`)) THEN + MATCH_MP_TAC(TAUT `a /\ (~c ==> ~b) ==> (a ==> b) ==> c`) THEN + CONJ_TAC THENL + [FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[IN_UNION]; + EXPAND_TAC "K" THEN + ASM_REWRITE_TAC[IN_DIFF; IN_UNIV; IN_UNION; REAL_NOT_LT] THEN + ASM_CASES_TAC `(w:real^2) IN path_image D` THEN + ASM_REWRITE_TAC[] THENL [ASM_MESON_TAC[]; DISCH_TAC] THEN + UNDISCH_TAC `!z. z$1 = &0 /\ z IN path_image U + ==> (p:real^2)$2 <= (z:real^2)$2` THEN + DISCH_THEN(MP_TAC o SPEC `w:real^2`) THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC(REAL_ARITH + `!q. b <= q /\ q < p ==> p <= w ==> b <= w`) THEN + EXISTS_TAC `(q:real^2)$2` THEN ASM_MESON_TAC[]]]; + ALL_TAC] THEN + SUBGOAL_THEN `path(bp:real^1->real^2)` ASSUME_TAC THENL + [EXPAND_TAC "bp" THEN + REPEAT(MATCH_MP_TAC PATH_JOIN_IMP THEN REPEAT CONJ_TAC THEN + ASM_REWRITE_TAC[PATHSTART_LINEPATH; PATHFINISH_LINEPATH]) THEN + ASM_REWRITE_TAC[PATH_LINEPATH; PATHSTART_JOIN; PATHFINISH_JOIN; + PATHSTART_LINEPATH; PATHFINISH_LINEPATH]; + ALL_TAC] THEN + SUBGOAL_THEN + `(?d1. &0 < d1 /\ + cball(--basis 1,d1) SUBSET ((:real^2) DIFF path_image bp)) /\ + (?d2. &0 < d2 /\ + cball(basis 1,d2) SUBSET ((:real^2) DIFF path_image bp))` + STRIP_ASSUME_TAC THENL + [CONJ_TAC THEN MATCH_MP_TAC(REWRITE_RULE[RIGHT_IMP_FORALL_THM; IMP_IMP] + (fst(EQ_IMP_RULE(SPEC_ALL OPEN_CONTAINS_CBALL)))) THEN + REWRITE_TAC[GSYM closed; IN_DIFF; IN_UNIV] THEN + (CONJ_TAC THENL + [ASM_MESON_TAC[COMPACT_IMP_CLOSED; COMPACT_PATH_IMAGE]; ALL_TAC]) THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE + `bp SUBSET s ==> ~(x IN s) ==> ~(x IN bp)`)) THEN + ASM_REWRITE_TAC[IN_UNION; IN_DIFF; IN_INSERT] THEN + MATCH_MP_TAC(SET_RULE + `(!x. connected_component k x SUBSET k) /\ ~(a IN k) /\ ~(b IN k) + ==> ~(a IN connected_component k x \/ + b IN connected_component k y)`) THEN + REWRITE_TAC[CONNECTED_COMPONENT_SUBSET] THEN + EXPAND_TAC "K" THEN REWRITE_TAC[IN_UNIV; IN_DIFF] THEN + ASM_REWRITE_TAC[]; + ALL_TAC] THEN + SUBGOAL_THEN + `--(basis 1) IN frontier(connected_component K (x:real^2)) /\ + (basis 1) IN frontier(connected_component K x)` + MP_TAC THENL [ASM_SIMP_TAC[]; ALL_TAC] THEN + REWRITE_TAC[frontier] THEN + ASM_SIMP_TAC[OPEN_CONNECTED_COMPONENT; INTERIOR_OPEN] THEN + REWRITE_TAC[IN_DIFF] THEN + DISCH_THEN(CONJUNCTS_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC)) THEN + REWRITE_TAC[CLOSURE_APPROACHABLE] THEN + DISCH_THEN(MP_TAC o SPEC `d2:real`) THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `w2:real^2` STRIP_ASSUME_TAC) THEN + DISCH_THEN(MP_TAC o SPEC `d1:real`) THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `w1:real^2` STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN + `(w1:real^2) IN interval[--vector [&1; &2],vector [&1; &2]] /\ + (w2:real^2) IN interval[--vector [&1; &2],vector [&1; &2]]` + STRIP_ASSUME_TAC THENL + [CONJ_TAC THEN MATCH_MP_TAC(SET_RULE + `!n j. j SUBSET i /\ (:real^N) DIFF j SUBSET n /\ ~(w IN n) + ==> w IN i`) THEN + EXISTS_TAC `connected_component K (n:real^2)` THEN + EXISTS_TAC + `interval[--vector [&1; &9 / &5]:real^2,vector [&1; &9 / &5]]` THEN + ASM_REWRITE_TAC[SUBSET_INTERVAL; DIMINDEX_2; FORALL_2; VECTOR_2; + VECTOR_NEG_COMPONENT] THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN + ASM_MESON_TAC[CONNECTED_COMPONENT_EQ]; + ALL_TAC] THEN + SUBGOAL_THEN + `?br. path br /\ + path_image br SUBSET connected_component K x /\ + pathstart br = w1 /\ pathfinish br = (w2:real^2)` + STRIP_ASSUME_TAC THENL + [MP_TAC(ISPEC `connected_component K (x:real^2)` path_connected) THEN + ASM_SIMP_TAC[PATH_CONNECTED_EQ_CONNECTED; OPEN_CONNECTED_COMPONENT] THEN + REWRITE_TAC[CONNECTED_CONNECTED_COMPONENT] THEN + DISCH_THEN MATCH_MP_TAC THEN ASM_REWRITE_TAC[]; + ALL_TAC] THEN + SUBGOAL_THEN + `pathstart bp = n:real^2 /\ pathfinish bp = (--n:real^2)` + STRIP_ASSUME_TAC THENL + [EXPAND_TAC "bp" THEN REWRITE_TAC[PATHSTART_JOIN; PATHFINISH_JOIN] THEN + REWRITE_TAC[PATHSTART_LINEPATH; PATHFINISH_LINEPATH]; + ALL_TAC] THEN + MP_TAC(ISPECL + [`linepath(--basis 1:real^2,w1) ++ br ++ linepath(w2,basis 1)`; + `reversepath bp:real^1->real^2`; + `--vector[&1; &2]:real^2`; `vector[&1; &2]:real^2`] + FASHODA) THEN + ASM_SIMP_TAC[PATH_JOIN; PATH_LINEPATH; PATH_REVERSEPATH; + PATHSTART_REVERSEPATH; PATHFINISH_REVERSEPATH; + PATHSTART_LINEPATH; PATHFINISH_LINEPATH; + PATHSTART_JOIN; PATHFINISH_JOIN; + PATH_IMAGE_JOIN; PATH_IMAGE_REVERSEPATH] THEN + SUBST1_TAC(SYM(ASSUME `&2 % basis 2:real^2 = n`)) THEN + SIMP_TAC[BASIS_COMPONENT; VECTOR_2; VECTOR_NEG_COMPONENT; DIMINDEX_2; ARITH; + VECTOR_MUL_COMPONENT] THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN + REWRITE_TAC[NOT_IMP; UNION_SUBSET; GSYM CONJ_ASSOC] THEN + REWRITE_TAC[PATH_IMAGE_LINEPATH; SEGMENT_CONVEX_HULL] THEN + SIMP_TAC[SUBSET_HULL; CONVEX_INTERVAL] THEN + ASM_REWRITE_TAC[SET_RULE `{a,b} SUBSET s <=> a IN s /\ b IN s`] THEN + SIMP_TAC[IN_INTERVAL; DIMINDEX_2; FORALL_2; VECTOR_2; + BASIS_COMPONENT; ARITH; VECTOR_NEG_COMPONENT] THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN REPEAT CONJ_TAC THENL + [MATCH_MP_TAC SUBSET_TRANS THEN + EXISTS_TAC `connected_component K (x:real^2)` THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC(SET_RULE + `!n j. j SUBSET i /\ (:real^N) DIFF j SUBSET n /\ c INTER n = {} + ==> c SUBSET i`) THEN + EXISTS_TAC `connected_component K (n:real^2)` THEN + EXISTS_TAC + `interval[--vector [&1; &9 / &5]:real^2,vector [&1; &9 / &5]]` THEN + ASM_REWRITE_TAC[SUBSET_INTERVAL; DIMINDEX_2; FORALL_2; VECTOR_2; + VECTOR_NEG_COMPONENT] THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN + ASM_REWRITE_TAC[CONNECTED_COMPONENT_NONOVERLAP]; + EXPAND_TAC "bp" THEN + REPEAT(MATCH_MP_TAC SUBSET_PATH_IMAGE_JOIN THEN CONJ_TAC) THEN + ASM_REWRITE_TAC[] THEN + REWRITE_TAC[PATH_IMAGE_LINEPATH; SEGMENT_CONVEX_HULL] THEN + SIMP_TAC[SUBSET_HULL; CONVEX_INTERVAL] THEN + ASM_REWRITE_TAC[SET_RULE `{a,b} SUBSET s <=> a IN s /\ b IN s`] THEN + SUBST1_TAC(SYM(ASSUME `&2 % basis 2:real^2 = n`)) THEN + SIMP_TAC[BASIS_COMPONENT; VECTOR_2; VECTOR_NEG_COMPONENT; DIMINDEX_2; ARITH; + VECTOR_MUL_COMPONENT; IN_INTERVAL; FORALL_2] THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN ASM SET_TAC[]; + ALL_TAC] THEN + DISCH_THEN(X_CHOOSE_THEN `w:real^2` (CONJUNCTS_THEN2 MP_TAC ASSUME_TAC)) THEN + REWRITE_TAC[IN_UNION; DE_MORGAN_THM] THEN REPEAT CONJ_TAC THENL + [UNDISCH_TAC `cball(--basis 1,d1) SUBSET (:real^2) DIFF path_image bp` THEN + REWRITE_TAC[SUBSET; IN_DIFF; IN_UNIV] THEN + DISCH_THEN(MP_TAC o SPEC `w:real^2`) THEN + ASM_REWRITE_TAC[CONTRAPOS_THM] THEN + SPEC_TAC(`w:real^2`,`u:real^2`) THEN REWRITE_TAC[GSYM SUBSET] THEN + SIMP_TAC[SUBSET_HULL; CONVEX_CBALL] THEN + REWRITE_TAC[SET_RULE `{a,b} SUBSET s <=> a IN s /\ b IN s`] THEN + ASM_SIMP_TAC[CENTRE_IN_CBALL; REAL_LT_IMP_LE] THEN + REWRITE_TAC[IN_CBALL] THEN ASM_MESON_TAC[REAL_LT_IMP_LE; DIST_SYM]; + ALL_TAC; + UNDISCH_TAC `cball(basis 1,d2) SUBSET (:real^2) DIFF path_image bp` THEN + REWRITE_TAC[SUBSET; IN_DIFF; IN_UNIV] THEN + DISCH_THEN(MP_TAC o SPEC `w:real^2`) THEN + ASM_REWRITE_TAC[CONTRAPOS_THM] THEN + SPEC_TAC(`w:real^2`,`u:real^2`) THEN REWRITE_TAC[GSYM SUBSET] THEN + SIMP_TAC[SUBSET_HULL; CONVEX_CBALL] THEN + REWRITE_TAC[SET_RULE `{a,b} SUBSET s <=> a IN s /\ b IN s`] THEN + ASM_SIMP_TAC[CENTRE_IN_CBALL; REAL_LT_IMP_LE] THEN + REWRITE_TAC[IN_CBALL] THEN ASM_MESON_TAC[REAL_LT_IMP_LE; DIST_SYM]] THEN + FIRST_X_ASSUM(MP_TAC o C MATCH_MP (ASSUME `(w:real^2) IN path_image bp`) o + GEN_REWRITE_RULE I [SUBSET]) THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE + `br SUBSET k ==> s INTER k = {} ==> w IN s ==> ~(w IN br)`)) THEN + MATCH_MP_TAC(SET_RULE + `xx SUBSET (UNIV DIFF du) /\ nn INTER xx = {} /\ yy INTER xx = {} + ==> ((du DIFF ee) UNION nn UNION yy) INTER xx = {}`) THEN + ASM_REWRITE_TAC[CONNECTED_COMPONENT_NONOVERLAP] THEN + MATCH_MP_TAC SUBSET_TRANS THEN EXISTS_TAC `K:real^2->bool` THEN + REWRITE_TAC[CONNECTED_COMPONENT_SUBSET] THEN + EXPAND_TAC "K" THEN MATCH_MP_TAC(SET_RULE `s = t ==> s SUBSET t`) THEN + AP_TERM_TAC THEN ASM_REWRITE_TAC[]);; + +let JORDAN_DISCONNECTED = prove + (`!c. simple_path c /\ pathfinish c = pathstart c + ==> ~connected((:real^2) DIFF path_image c)`, + GEN_TAC THEN DISCH_TAC THEN REWRITE_TAC[connected] THEN + FIRST_ASSUM(MP_TAC o MATCH_MP JORDAN_CURVE_THEOREM) THEN + REPEAT(MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC) THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN ASM SET_TAC[]);; + +let JORDAN_INSIDE_OUTSIDE = prove + (`!c:real^1->real^2. + simple_path c /\ pathfinish c = pathstart c + ==> ~(inside(path_image c) = {}) /\ + open(inside(path_image c)) /\ + connected(inside(path_image c)) /\ + ~(outside(path_image c) = {}) /\ + open(outside(path_image c)) /\ + connected(outside(path_image c)) /\ + bounded(inside(path_image c)) /\ + ~bounded(outside(path_image c)) /\ + inside(path_image c) INTER outside(path_image c) = {} /\ + inside(path_image c) UNION outside(path_image c) = + (:real^2) DIFF path_image c /\ + frontier(inside(path_image c)) = path_image c /\ + frontier(outside(path_image c)) = path_image c`, + GEN_TAC THEN DISCH_TAC THEN + FIRST_ASSUM(MP_TAC o MATCH_MP JORDAN_CURVE_THEOREM) THEN + REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`ins:real^2->bool`; `out:real^2->bool`] THEN + STRIP_TAC THEN + SUBGOAL_THEN `inside(path_image c) :real^2->bool = ins /\ + outside(path_image c):real^2->bool = out ` + (fun th -> ASM_REWRITE_TAC[th]) THEN + MATCH_MP_TAC INSIDE_OUTSIDE_UNIQUE THEN ASM_SIMP_TAC[JORDAN_DISCONNECTED]);; + +(* ------------------------------------------------------------------------- *) +(* Splitting the inside of a closed curve into two with a cut across it. *) +(* The hardest part, that there is no third component inside the original *) +(* curve, is taken from Whyburn's, "Topological Analysis" (1.4 on p31). *) +(* ------------------------------------------------------------------------- *) + +let SPLIT_INSIDE_SIMPLE_CLOSED_CURVE = prove + (`!c1 c2 c a b:real^2. + ~(a = b) /\ + simple_path c1 /\ pathstart c1 = a /\ pathfinish c1 = b /\ + simple_path c2 /\ pathstart c2 = a /\ pathfinish c2 = b /\ + simple_path c /\ pathstart c = a /\ pathfinish c = b /\ + path_image c1 INTER path_image c2 = {a,b} /\ + path_image c1 INTER path_image c = {a,b} /\ + path_image c2 INTER path_image c = {a,b} /\ + ~(path_image c INTER inside(path_image c1 UNION path_image c2) = {}) + ==> inside(path_image c1 UNION path_image c) INTER + inside(path_image c2 UNION path_image c) = {} /\ + inside(path_image c1 UNION path_image c) UNION + inside(path_image c2 UNION path_image c) UNION + (path_image c DIFF {a,b}) = + inside(path_image c1 UNION path_image c2)`, + REPEAT GEN_TAC THEN STRIP_TAC THEN + MAP_EVERY (MP_TAC o C ISPEC JORDAN_INSIDE_OUTSIDE) + [`(c1 ++ reversepath c2):real^1->real^2`; + `(c1 ++ reversepath c):real^1->real^2`; + `(c2 ++ reversepath c):real^1->real^2`] THEN + ASM_SIMP_TAC[PATHSTART_JOIN; PATHFINISH_JOIN; + PATHSTART_REVERSEPATH; PATHFINISH_REVERSEPATH; + SIMPLE_PATH_JOIN_LOOP; SIMPLE_PATH_IMP_ARC; + PATH_IMAGE_JOIN; SIMPLE_PATH_IMP_PATH; PATH_IMAGE_REVERSEPATH; + SIMPLE_PATH_REVERSEPATH; ARC_REVERSEPATH; + SUBSET_REFL] THEN + REPLICATE_TAC 3 STRIP_TAC THEN + SUBGOAL_THEN + `path_image(c:real^1->real^2) INTER + outside(path_image c1 UNION path_image c2) = {}` + ASSUME_TAC THENL + [MATCH_MP_TAC(TAUT `(~p ==> F) ==> p`) THEN DISCH_TAC THEN + SUBGOAL_THEN + `connected(path_image(c:real^1->real^2) DIFF + {pathstart c,pathfinish c})` + MP_TAC THENL [ASM_SIMP_TAC[CONNECTED_SIMPLE_PATH_ENDLESS]; ALL_TAC] THEN + ASM_REWRITE_TAC[connected] THEN + MAP_EVERY EXISTS_TAC + [`inside(path_image c1 UNION path_image c2):real^2->bool`; + `outside(path_image c1 UNION path_image c2):real^2->bool`] THEN + ASM_REWRITE_TAC[] THEN ASM SET_TAC[]; + ALL_TAC] THEN + SUBGOAL_THEN + `outside(path_image c1 UNION path_image c2) SUBSET + outside(path_image c1 UNION path_image (c:real^1->real^2)) /\ + outside(path_image c1 UNION path_image c2) SUBSET + outside(path_image c2 UNION path_image c)` + STRIP_ASSUME_TAC THENL + [CONJ_TAC THENL + [ALL_TAC; GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [UNION_COMM]] THEN + MATCH_MP_TAC OUTSIDE_UNION_OUTSIDE_UNION THEN ASM_REWRITE_TAC[] THEN + ONCE_REWRITE_TAC[UNION_COMM] THEN ASM_REWRITE_TAC[]; + ALL_TAC] THEN + SUBGOAL_THEN + `path_image(c1:real^1->real^2) INTER + inside(path_image c2 UNION path_image c) = {}` + ASSUME_TAC THENL + [MATCH_MP_TAC(TAUT `(~p ==> F) ==> p`) THEN DISCH_TAC THEN + SUBGOAL_THEN + `frontier(outside(path_image c1 UNION path_image c2)):real^2->bool = + frontier(outside(path_image c2 UNION path_image c))` + MP_TAC THENL + [AP_TERM_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN ASM_REWRITE_TAC[] THEN + GEN_REWRITE_TAC (RAND_CONV o RAND_CONV) [UNION_COMM] THEN + MATCH_MP_TAC OUTSIDE_UNION_OUTSIDE_UNION THEN + MATCH_MP_TAC(TAUT `(~p ==> F) ==> p`) THEN DISCH_TAC THEN + SUBGOAL_THEN + `connected(path_image(c1:real^1->real^2) DIFF + {pathstart c1,pathfinish c1})` + MP_TAC THENL [ASM_SIMP_TAC[CONNECTED_SIMPLE_PATH_ENDLESS]; ALL_TAC] THEN + ASM_REWRITE_TAC[connected] THEN + MAP_EVERY EXISTS_TAC + [`inside(path_image c2 UNION path_image c):real^2->bool`; + `outside(path_image c2 UNION path_image c):real^2->bool`] THEN + ASM_REWRITE_TAC[] THEN ASM SET_TAC[]; + MP_TAC(ISPEC `c:real^1->real^2` NONEMPTY_SIMPLE_PATH_ENDLESS) THEN + ASM_REWRITE_TAC[] THEN ASM SET_TAC[]]; + ALL_TAC] THEN + SUBGOAL_THEN + `path_image(c2:real^1->real^2) INTER + inside(path_image c1 UNION path_image c) = {}` + ASSUME_TAC THENL + [MATCH_MP_TAC(TAUT `(~p ==> F) ==> p`) THEN DISCH_TAC THEN + SUBGOAL_THEN + `frontier(outside(path_image c1 UNION path_image c2)):real^2->bool = + frontier(outside(path_image c1 UNION path_image c))` + MP_TAC THENL + [AP_TERM_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC OUTSIDE_UNION_OUTSIDE_UNION THEN + MATCH_MP_TAC(TAUT `(~p ==> F) ==> p`) THEN DISCH_TAC THEN + SUBGOAL_THEN + `connected(path_image(c2:real^1->real^2) DIFF + {pathstart c2,pathfinish c2})` + MP_TAC THENL [ASM_SIMP_TAC[CONNECTED_SIMPLE_PATH_ENDLESS]; ALL_TAC] THEN + ASM_REWRITE_TAC[connected] THEN + MAP_EVERY EXISTS_TAC + [`inside(path_image c1 UNION path_image c):real^2->bool`; + `outside(path_image c1 UNION path_image c):real^2->bool`] THEN + ASM_REWRITE_TAC[] THEN ASM SET_TAC[]; + MP_TAC(ISPEC `c:real^1->real^2` NONEMPTY_SIMPLE_PATH_ENDLESS) THEN + ASM_REWRITE_TAC[] THEN ASM SET_TAC[]]; + ALL_TAC] THEN + SUBGOAL_THEN + `inside(path_image c1 UNION path_image (c:real^1->real^2)) SUBSET + inside(path_image c1 UNION path_image c2) /\ + inside(path_image c2 UNION path_image (c:real^1->real^2)) SUBSET + inside(path_image c1 UNION path_image c2)` + STRIP_ASSUME_TAC THENL + [CONJ_TAC THEN REWRITE_TAC[INSIDE_OUTSIDE] THEN + REWRITE_TAC[SET_RULE `UNIV DIFF t SUBSET UNIV DIFF s <=> s SUBSET t`] THENL + [ALL_TAC; GEN_REWRITE_TAC (LAND_CONV o LAND_CONV) [UNION_COMM]] THEN + MATCH_MP_TAC(SET_RULE + `out1 SUBSET out2 /\ c2 DIFF (c1 UNION c) SUBSET out2 + ==> (c1 UNION c2) UNION out1 SUBSET (c1 UNION c) UNION out2`) THEN + ASM_REWRITE_TAC[] THEN + REWRITE_TAC[OUTSIDE_INSIDE] THEN ASM SET_TAC[]; + ALL_TAC] THEN + SUBGOAL_THEN + `inside(path_image c1 UNION path_image c :real^2->bool) SUBSET + outside(path_image c2 UNION path_image c) /\ + inside(path_image c2 UNION path_image c) SUBSET + outside(path_image c1 UNION path_image c)` + STRIP_ASSUME_TAC THENL + [REWRITE_TAC[SUBSET] THEN CONJ_TAC THEN + X_GEN_TAC `x:real^2` THEN DISCH_TAC THENL + [SUBGOAL_THEN `?z:real^2. z IN path_image c1 /\ + z IN outside(path_image c2 UNION path_image c)` + (CHOOSE_THEN (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THENL + [REWRITE_TAC[OUTSIDE_INSIDE; IN_DIFF; IN_UNION; IN_UNIV] THEN + MP_TAC(ISPEC `c1:real^1->real^2` NONEMPTY_SIMPLE_PATH_ENDLESS) THEN + ASM_REWRITE_TAC[] THEN ASM SET_TAC[]; + ALL_TAC] THEN + DISCH_THEN(fun th -> ASSUME_TAC th THEN MP_TAC th) THEN + REWRITE_TAC[OUTSIDE; IN_ELIM_THM; CONTRAPOS_THM] THEN + MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN + MATCH_MP_TAC CONNECTED_COMPONENT_EQ THEN REWRITE_TAC[IN] THEN + MP_TAC(ASSUME + `open(outside(path_image c2 UNION path_image c):real^2->bool)`) THEN + REWRITE_TAC[OPEN_CONTAINS_BALL] THEN + DISCH_THEN(MP_TAC o SPEC `z:real^2`) THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `e:real` STRIP_ASSUME_TAC) THEN + MP_TAC(ASSUME + `frontier(inside(path_image c1 UNION path_image c):real^2->bool) = + path_image c1 UNION path_image c`) THEN + GEN_REWRITE_TAC LAND_CONV [EXTENSION] THEN + DISCH_THEN(MP_TAC o SPEC `z:real^2`) THEN REWRITE_TAC[frontier] THEN + ASM_SIMP_TAC[IN_UNION; IN_DIFF; CLOSURE_APPROACHABLE; IN_ELIM_THM] THEN + DISCH_THEN(MP_TAC o SPEC `e:real` o CONJUNCT1) THEN + ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `w:real^2` THEN STRIP_TAC THEN + MATCH_MP_TAC CONNECTED_COMPONENT_TRANS THEN EXISTS_TAC `w:real^2` THEN + REWRITE_TAC[connected_component] THEN CONJ_TAC THENL + [EXISTS_TAC + `outside(path_image c2 UNION path_image c:real^2->bool)` THEN + ASM_REWRITE_TAC[SET_RULE `s SUBSET UNIV DIFF t <=> s INTER t = {}`; + OUTSIDE_NO_OVERLAP] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o GEN_REWRITE_RULE I [SUBSET]) THEN + ASM_REWRITE_TAC[ONCE_REWRITE_RULE[DIST_SYM] IN_BALL]; + EXISTS_TAC `inside(path_image c1 UNION path_image c:real^2->bool)` THEN + ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC(SET_RULE + `inside(c1 UNION c) INTER (c1 UNION c) = {} /\ + c2 INTER inside(c1 UNION c) = {} + ==> inside(c1 UNION c) SUBSET UNIV DIFF (c2 UNION c)`) THEN + ASM_REWRITE_TAC[INSIDE_NO_OVERLAP]]; + SUBGOAL_THEN `?z:real^2. z IN path_image c2 /\ + z IN outside(path_image c1 UNION path_image c)` + (CHOOSE_THEN (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THENL + [REWRITE_TAC[OUTSIDE_INSIDE; IN_DIFF; IN_UNION; IN_UNIV] THEN + MP_TAC(ISPEC `c2:real^1->real^2` NONEMPTY_SIMPLE_PATH_ENDLESS) THEN + ASM_REWRITE_TAC[] THEN ASM SET_TAC[]; + ALL_TAC] THEN + DISCH_THEN(fun th -> ASSUME_TAC th THEN MP_TAC th) THEN + REWRITE_TAC[OUTSIDE; IN_ELIM_THM; CONTRAPOS_THM] THEN + MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN + MATCH_MP_TAC CONNECTED_COMPONENT_EQ THEN REWRITE_TAC[IN] THEN + MP_TAC(ASSUME + `open(outside(path_image c1 UNION path_image c):real^2->bool)`) THEN + REWRITE_TAC[OPEN_CONTAINS_BALL] THEN + DISCH_THEN(MP_TAC o SPEC `z:real^2`) THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `e:real` STRIP_ASSUME_TAC) THEN + MP_TAC(ASSUME + `frontier(inside(path_image c2 UNION path_image c):real^2->bool) = + path_image c2 UNION path_image c`) THEN + GEN_REWRITE_TAC LAND_CONV [EXTENSION] THEN + DISCH_THEN(MP_TAC o SPEC `z:real^2`) THEN REWRITE_TAC[frontier] THEN + ASM_SIMP_TAC[IN_UNION; IN_DIFF; CLOSURE_APPROACHABLE; IN_ELIM_THM] THEN + DISCH_THEN(MP_TAC o SPEC `e:real` o CONJUNCT1) THEN + ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `w:real^2` THEN STRIP_TAC THEN + MATCH_MP_TAC CONNECTED_COMPONENT_TRANS THEN EXISTS_TAC `w:real^2` THEN + REWRITE_TAC[connected_component] THEN CONJ_TAC THENL + [EXISTS_TAC + `outside(path_image c1 UNION path_image c:real^2->bool)` THEN + ASM_REWRITE_TAC[SET_RULE `s SUBSET UNIV DIFF t <=> s INTER t = {}`; + OUTSIDE_NO_OVERLAP] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o GEN_REWRITE_RULE I [SUBSET]) THEN + ASM_REWRITE_TAC[ONCE_REWRITE_RULE[DIST_SYM] IN_BALL]; + EXISTS_TAC `inside(path_image c2 UNION path_image c:real^2->bool)` THEN + ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC(SET_RULE + `inside(c2 UNION c) INTER (c2 UNION c) = {} /\ + c1 INTER inside(c2 UNION c) = {} + ==> inside(c2 UNION c) SUBSET UNIV DIFF (c1 UNION c)`) THEN + ASM_REWRITE_TAC[INSIDE_NO_OVERLAP]]]; + ALL_TAC] THEN + CONJ_TAC THENL + [MATCH_MP_TAC(SET_RULE + `!u. s SUBSET u /\ t INTER u = {} ==> s INTER t = {}`) THEN + EXISTS_TAC `outside(path_image c2 UNION path_image c):real^2->bool` THEN + ASM_REWRITE_TAC[INSIDE_INTER_OUTSIDE]; + ALL_TAC] THEN + SUBGOAL_THEN + `!x:real^2. ~(x IN path_image c) /\ + x IN inside(path_image c1 UNION path_image c2) /\ + ~(x IN inside(path_image c1 UNION path_image c)) /\ + ~(x IN inside(path_image c2 UNION path_image c)) ==> F` + ASSUME_TAC THENL [ALL_TAC; ASM SET_TAC[]] THEN + X_GEN_TAC `z:real^2` THEN STRIP_TAC THEN + SUBGOAL_THEN `~((z:real^2) IN (path_image c1 UNION path_image c2))` + MP_TAC THENL + [ASM_MESON_TAC[INSIDE_NO_OVERLAP; NOT_IN_EMPTY; IN_INTER]; + PURE_REWRITE_TAC[IN_UNION; DE_MORGAN_THM] THEN STRIP_TAC] THEN + MAP_EVERY (MP_TAC o C ISPEC INSIDE_UNION_OUTSIDE) + [`path_image c1 UNION path_image c:real^2->bool`; + `path_image c2 UNION path_image c:real^2->bool`] THEN + PURE_REWRITE_TAC[IMP_IMP] THEN REWRITE_TAC[EXTENSION; IN_UNION] THEN + REWRITE_TAC[AND_FORALL_THM] THEN DISCH_THEN(MP_TAC o SPEC `z:real^2`) THEN + ASM_REWRITE_TAC[IN_UNIV; IN_DIFF; IN_UNION] THEN STRIP_TAC THEN + MP_TAC(ASSUME + `~(outside(path_image c1 UNION path_image c2:real^2->bool) = {})`) THEN + GEN_REWRITE_TAC LAND_CONV [GSYM MEMBER_NOT_EMPTY] THEN + DISCH_THEN(X_CHOOSE_TAC `w:real^2`) THEN + SUBGOAL_THEN `(w:real^2) IN outside(path_image c1 UNION path_image c) /\ + w IN outside(path_image c2 UNION path_image c)` + STRIP_ASSUME_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + SUBGOAL_THEN + `~((w:real^2) IN (path_image c1 UNION path_image c2)) /\ + ~(w IN path_image c1 UNION path_image c)` + MP_TAC THENL + [ASM_MESON_TAC[OUTSIDE_NO_OVERLAP; NOT_IN_EMPTY; IN_INTER]; + PURE_REWRITE_TAC[IN_UNION; CONJ_ACI; DE_MORGAN_THM] THEN STRIP_TAC] THEN + MAP_EVERY (MP_TAC o C ISPEC INSIDE_INTER_OUTSIDE) + [`path_image c1 UNION path_image c2:real^2->bool`; + `path_image c1 UNION path_image c:real^2->bool`; + `path_image c2 UNION path_image c:real^2->bool`] THEN + PURE_REWRITE_TAC[IMP_IMP] THEN + REWRITE_TAC[EXTENSION; IN_INTER; NOT_IN_EMPTY] THEN + REWRITE_TAC[AND_FORALL_THM] THEN DISCH_THEN(MP_TAC o SPEC `w:real^2`) THEN + ASM_REWRITE_TAC[] THEN STRIP_TAC THEN + MP_TAC(ISPEC + `outside(path_image c2 UNION path_image c):real^2->bool` + CONNECTED_OPEN_ARC_CONNECTED) THEN + ASM_REWRITE_TAC[] THEN + DISCH_THEN(MP_TAC o SPECL [`z:real^2`; `w:real^2`]) THEN + ASM_REWRITE_TAC[] THEN + DISCH_THEN(DISJ_CASES_THEN MP_TAC) THENL [ASM_MESON_TAC[]; ALL_TAC] THEN + DISCH_THEN(X_CHOOSE_THEN `g1:real^1->real^2` STRIP_ASSUME_TAC) THEN + MP_TAC(ISPEC + `outside(path_image c1 UNION path_image c):real^2->bool` + CONNECTED_OPEN_ARC_CONNECTED) THEN + ASM_REWRITE_TAC[] THEN + DISCH_THEN(MP_TAC o SPECL [`z:real^2`; `w:real^2`]) THEN + ASM_REWRITE_TAC[] THEN + DISCH_THEN(DISJ_CASES_THEN MP_TAC) THENL [ASM_MESON_TAC[]; ALL_TAC] THEN + DISCH_THEN(X_CHOOSE_THEN `g2:real^1->real^2` STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN + `?h. arc h /\ pathstart h = (z:real^2) /\ + path_image h DELETE pathfinish h SUBSET + inside(path_image c1 UNION path_image c2) INTER + outside(path_image c1 UNION path_image c) INTER + outside(path_image c2 UNION path_image c) /\ + pathfinish h IN path_image c1 /\ + ~(pathfinish h IN path_image c2)` + (X_CHOOSE_THEN `gzx:real^1->real^2` STRIP_ASSUME_TAC) THENL + [MP_TAC(ISPECL + [`g1:real^1->real^2`; + `inside(path_image c1 UNION path_image c2) INTER + outside(path_image c1 UNION path_image c) INTER + outside(path_image c2 UNION path_image c):real^2->bool`] + SUBPATH_TO_FRONTIER) THEN + ASM_SIMP_TAC[ARC_IMP_PATH; IN_INTER; INTERIOR_INTER; INTERIOR_OPEN] THEN + DISCH_THEN(X_CHOOSE_THEN `u:real^1` STRIP_ASSUME_TAC) THEN + ABBREV_TAC `h:real^1->real^2 = subpath (vec 0) u g1` THEN + EXISTS_TAC `h:real^1->real^2` THEN ASM_REWRITE_TAC[] THEN + EXPAND_TAC "h" THEN + REWRITE_TAC[PATHSTART_SUBPATH; PATHFINISH_SUBPATH] THEN + MATCH_MP_TAC(TAUT `b /\ (c ==> a) /\ c ==> a /\ b /\ c`) THEN + CONJ_TAC THENL [ASM_MESON_TAC[pathstart]; ALL_TAC] THEN CONJ_TAC THENL + [DISCH_TAC THEN MATCH_MP_TAC ARC_SIMPLE_PATH_SUBPATH THEN + ASM_SIMP_TAC[ENDS_IN_UNIT_INTERVAL; ARC_IMP_SIMPLE_PATH] THEN + DISCH_THEN(SUBST_ALL_TAC o SYM) THEN + MP_TAC(ISPEC `path_image c1 UNION path_image c2:real^2->bool` + INSIDE_NO_OVERLAP) THEN + REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN + EXISTS_TAC `pathstart(g1:real^1->real^2)` THEN + ASM_REWRITE_TAC[IN_INTER] THEN + REWRITE_TAC[IN_UNION] THEN DISJ1_TAC THEN ASM_MESON_TAC[pathstart]; + ALL_TAC] THEN + UNDISCH_TAC + `(pathfinish h:real^2) IN + frontier + (inside (path_image c1 UNION path_image c2) INTER + outside (path_image c1 UNION path_image c) INTER + outside (path_image c2 UNION path_image c))` THEN + EXPAND_TAC "h" THEN REWRITE_TAC[PATHFINISH_SUBPATH] THEN + DISCH_THEN(MP_TAC o MATCH_MP (REWRITE_RULE[SUBSET] + FRONTIER_INTER_SUBSET)) THEN ASM_REWRITE_TAC[] THEN + MP_TAC(ASSUME + `(path_image g1:real^2->bool) SUBSET + outside(path_image c2 UNION path_image c)`) THEN + DISCH_THEN(MP_TAC o SPEC `(g1:real^1->real^2) u` o + REWRITE_RULE[SUBSET]) THEN + GEN_REWRITE_TAC (LAND_CONV o LAND_CONV o ONCE_DEPTH_CONV) [path_image] THEN + REWRITE_TAC[IN_IMAGE] THEN ANTS_TAC THENL [ASM_MESON_TAC[]; DISCH_TAC] THEN + MP_TAC(ISPEC `path_image c2 UNION path_image c:real^2->bool` + OUTSIDE_NO_OVERLAP) THEN + GEN_REWRITE_TAC LAND_CONV [EXTENSION] THEN + DISCH_THEN(MP_TAC o SPEC `(g1:real^1->real^2) u`) THEN + ASM_REWRITE_TAC[IN_INTER; IN_UNION; NOT_IN_EMPTY; DE_MORGAN_THM] THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(DISJ_CASES_THEN2 ACCEPT_TAC MP_TAC) THEN + DISCH_THEN(MP_TAC o MATCH_MP (REWRITE_RULE[SUBSET] + FRONTIER_INTER_SUBSET)) THEN ASM_REWRITE_TAC[] THEN + ASM_REWRITE_TAC[IN_UNION]; + ABBREV_TAC `x:real^2 = pathfinish gzx`] THEN + SUBGOAL_THEN + `?h. arc h /\ pathstart h = (w:real^2) /\ + path_image h DELETE pathfinish h SUBSET + outside(path_image c1 UNION path_image c2) /\ + pathfinish h IN path_image c1 /\ + ~(pathfinish h IN path_image c2)` + (X_CHOOSE_THEN `gwx:real^1->real^2` STRIP_ASSUME_TAC) THENL + [MP_TAC(ISPECL + [`reversepath g1:real^1->real^2`; + `outside(path_image c1 UNION path_image c2):real^2->bool`] + SUBPATH_TO_FRONTIER) THEN + ASM_SIMP_TAC[ARC_IMP_PATH; IN_INTER; INTERIOR_INTER; INTERIOR_OPEN; + PATH_REVERSEPATH; PATHSTART_REVERSEPATH; PATHFINISH_REVERSEPATH] THEN + ANTS_TAC THENL + [ASM_MESON_TAC[INSIDE_INTER_OUTSIDE; IN_INTER; NOT_IN_EMPTY]; + ALL_TAC] THEN + DISCH_THEN(X_CHOOSE_THEN `u:real^1` STRIP_ASSUME_TAC) THEN + ABBREV_TAC `h:real^1->real^2 = subpath (vec 0) u (reversepath g1)` THEN + EXISTS_TAC `h:real^1->real^2` THEN ASM_REWRITE_TAC[] THEN + EXPAND_TAC "h" THEN + REWRITE_TAC[PATHSTART_SUBPATH; PATHFINISH_SUBPATH] THEN + MATCH_MP_TAC(TAUT `b /\ (c ==> a) /\ c ==> a /\ b /\ c`) THEN + CONJ_TAC THENL + [ASM_MESON_TAC[pathstart; PATHSTART_REVERSEPATH]; ALL_TAC] THEN + CONJ_TAC THENL + [DISCH_TAC THEN MATCH_MP_TAC ARC_SIMPLE_PATH_SUBPATH THEN + ASM_SIMP_TAC[ENDS_IN_UNIT_INTERVAL; ARC_IMP_SIMPLE_PATH; + SIMPLE_PATH_REVERSEPATH] THEN + DISCH_THEN(SUBST_ALL_TAC o SYM) THEN + MP_TAC(ISPEC `path_image c1 UNION path_image c2:real^2->bool` + OUTSIDE_NO_OVERLAP) THEN + REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN + EXISTS_TAC `pathstart(reversepath g1:real^1->real^2)` THEN + ASM_REWRITE_TAC[IN_INTER] THEN CONJ_TAC THENL + [ASM_REWRITE_TAC[PATHSTART_REVERSEPATH]; + REWRITE_TAC[IN_UNION] THEN DISJ1_TAC THEN ASM_MESON_TAC[pathstart]]; + ALL_TAC] THEN + UNDISCH_TAC + `(pathfinish h:real^2) IN path_image c1 UNION path_image c2` THEN + EXPAND_TAC "h" THEN REWRITE_TAC[PATHFINISH_SUBPATH] THEN + MP_TAC(ASSUME + `(path_image g1:real^2->bool) SUBSET + outside(path_image c2 UNION path_image c)`) THEN + DISCH_THEN(MP_TAC o SPEC `reversepath (g1:real^1->real^2) u` o + REWRITE_RULE[SUBSET]) THEN + ANTS_TAC THENL + [ONCE_REWRITE_TAC[GSYM PATH_IMAGE_REVERSEPATH] THEN + REWRITE_TAC[path_image; IN_IMAGE] THEN ASM_MESON_TAC[]; + DISCH_TAC] THEN + MP_TAC(ISPEC `path_image c2 UNION path_image c:real^2->bool` + OUTSIDE_NO_OVERLAP) THEN + GEN_REWRITE_TAC LAND_CONV [EXTENSION] THEN + DISCH_THEN(MP_TAC o SPEC `reversepath (g1:real^1->real^2) u`) THEN + ASM_REWRITE_TAC[IN_INTER; IN_UNION; NOT_IN_EMPTY; DE_MORGAN_THM] THEN + CONV_TAC TAUT; + ABBREV_TAC `x':real^2 = pathfinish gwx`] THEN + SUBGOAL_THEN + `?h. arc h /\ pathstart h = (z:real^2) /\ + path_image h DELETE pathfinish h SUBSET + inside(path_image c1 UNION path_image c2) INTER + outside(path_image c1 UNION path_image c) INTER + outside(path_image c2 UNION path_image c) /\ + pathfinish h IN path_image c2 /\ + ~(pathfinish h IN path_image c1)` + (X_CHOOSE_THEN `gzy:real^1->real^2` STRIP_ASSUME_TAC) THENL + [MP_TAC(ISPECL + [`g2:real^1->real^2`; + `inside(path_image c1 UNION path_image c2) INTER + outside(path_image c1 UNION path_image c) INTER + outside(path_image c2 UNION path_image c):real^2->bool`] + SUBPATH_TO_FRONTIER) THEN + ASM_SIMP_TAC[ARC_IMP_PATH; IN_INTER; INTERIOR_INTER; INTERIOR_OPEN] THEN + DISCH_THEN(X_CHOOSE_THEN `u:real^1` STRIP_ASSUME_TAC) THEN + ABBREV_TAC `h:real^1->real^2 = subpath (vec 0) u g2` THEN + EXISTS_TAC `h:real^1->real^2` THEN ASM_REWRITE_TAC[] THEN + EXPAND_TAC "h" THEN + REWRITE_TAC[PATHSTART_SUBPATH; PATHFINISH_SUBPATH] THEN + MATCH_MP_TAC(TAUT `b /\ (c ==> a) /\ c ==> a /\ b /\ c`) THEN + CONJ_TAC THENL [ASM_MESON_TAC[pathstart]; ALL_TAC] THEN CONJ_TAC THENL + [DISCH_TAC THEN MATCH_MP_TAC ARC_SIMPLE_PATH_SUBPATH THEN + ASM_SIMP_TAC[ENDS_IN_UNIT_INTERVAL; ARC_IMP_SIMPLE_PATH] THEN + DISCH_THEN(SUBST_ALL_TAC o SYM) THEN + MP_TAC(ISPEC `path_image c1 UNION path_image c2:real^2->bool` + INSIDE_NO_OVERLAP) THEN + REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN + EXISTS_TAC `pathstart(g2:real^1->real^2)` THEN + ASM_REWRITE_TAC[IN_INTER] THEN + REWRITE_TAC[IN_UNION] THEN DISJ1_TAC THEN ASM_MESON_TAC[pathstart]; + ALL_TAC] THEN + UNDISCH_TAC + `(pathfinish h:real^2) IN + frontier + (inside (path_image c1 UNION path_image c2) INTER + outside (path_image c1 UNION path_image c) INTER + outside (path_image c2 UNION path_image c))` THEN + EXPAND_TAC "h" THEN REWRITE_TAC[PATHFINISH_SUBPATH] THEN + DISCH_THEN(MP_TAC o MATCH_MP (REWRITE_RULE[SUBSET] + FRONTIER_INTER_SUBSET)) THEN ASM_REWRITE_TAC[] THEN + MP_TAC(ASSUME + `(path_image g2:real^2->bool) SUBSET + outside(path_image c1 UNION path_image c)`) THEN + DISCH_THEN(MP_TAC o SPEC `(g2:real^1->real^2) u` o + REWRITE_RULE[SUBSET]) THEN + GEN_REWRITE_TAC (LAND_CONV o LAND_CONV o ONCE_DEPTH_CONV) [path_image] THEN + REWRITE_TAC[IN_IMAGE] THEN ANTS_TAC THENL [ASM_MESON_TAC[]; DISCH_TAC] THEN + MP_TAC(ISPEC `path_image c1 UNION path_image c:real^2->bool` + OUTSIDE_NO_OVERLAP) THEN + GEN_REWRITE_TAC LAND_CONV [EXTENSION] THEN + DISCH_THEN(MP_TAC o SPEC `(g2:real^1->real^2) u`) THEN + ASM_REWRITE_TAC[IN_INTER; IN_UNION; NOT_IN_EMPTY; DE_MORGAN_THM] THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(DISJ_CASES_THEN2 ACCEPT_TAC MP_TAC) THEN + DISCH_THEN(MP_TAC o MATCH_MP (REWRITE_RULE[SUBSET] + FRONTIER_INTER_SUBSET)) THEN ASM_REWRITE_TAC[] THEN + ASM_REWRITE_TAC[IN_UNION]; + ABBREV_TAC `y:real^2 = pathfinish gzy`] THEN + SUBGOAL_THEN + `?h. arc h /\ pathstart h = (w:real^2) /\ + path_image h DELETE pathfinish h SUBSET + outside(path_image c1 UNION path_image c2) /\ + pathfinish h IN path_image c2 /\ + ~(pathfinish h IN path_image c1)` + (X_CHOOSE_THEN `gwy:real^1->real^2` STRIP_ASSUME_TAC) THENL + [MP_TAC(ISPECL + [`reversepath g2:real^1->real^2`; + `outside(path_image c1 UNION path_image c2):real^2->bool`] + SUBPATH_TO_FRONTIER) THEN + ASM_SIMP_TAC[ARC_IMP_PATH; IN_INTER; INTERIOR_INTER; INTERIOR_OPEN; + PATH_REVERSEPATH; PATHSTART_REVERSEPATH; PATHFINISH_REVERSEPATH] THEN + ANTS_TAC THENL + [ASM_MESON_TAC[INSIDE_INTER_OUTSIDE; IN_INTER; NOT_IN_EMPTY]; + ALL_TAC] THEN + DISCH_THEN(X_CHOOSE_THEN `u:real^1` STRIP_ASSUME_TAC) THEN + ABBREV_TAC `h:real^1->real^2 = subpath (vec 0) u (reversepath g2)` THEN + EXISTS_TAC `h:real^1->real^2` THEN ASM_REWRITE_TAC[] THEN + EXPAND_TAC "h" THEN + REWRITE_TAC[PATHSTART_SUBPATH; PATHFINISH_SUBPATH] THEN + MATCH_MP_TAC(TAUT `b /\ (c ==> a) /\ c ==> a /\ b /\ c`) THEN + CONJ_TAC THENL + [ASM_MESON_TAC[pathstart; PATHSTART_REVERSEPATH]; ALL_TAC] THEN + CONJ_TAC THENL + [DISCH_TAC THEN MATCH_MP_TAC ARC_SIMPLE_PATH_SUBPATH THEN + ASM_SIMP_TAC[ENDS_IN_UNIT_INTERVAL; ARC_IMP_SIMPLE_PATH; + SIMPLE_PATH_REVERSEPATH] THEN + DISCH_THEN(SUBST_ALL_TAC o SYM) THEN + MP_TAC(ISPEC `path_image c1 UNION path_image c2:real^2->bool` + OUTSIDE_NO_OVERLAP) THEN + REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN + EXISTS_TAC `pathstart(reversepath g2:real^1->real^2)` THEN + ASM_REWRITE_TAC[IN_INTER] THEN CONJ_TAC THENL + [ASM_REWRITE_TAC[PATHSTART_REVERSEPATH]; + REWRITE_TAC[IN_UNION] THEN DISJ2_TAC THEN ASM_MESON_TAC[pathstart]]; + ALL_TAC] THEN + UNDISCH_TAC + `(pathfinish h:real^2) IN path_image c1 UNION path_image c2` THEN + EXPAND_TAC "h" THEN REWRITE_TAC[PATHFINISH_SUBPATH] THEN + MP_TAC(ASSUME + `(path_image g2:real^2->bool) SUBSET + outside(path_image c1 UNION path_image c)`) THEN + DISCH_THEN(MP_TAC o SPEC `reversepath (g2:real^1->real^2) u` o + REWRITE_RULE[SUBSET]) THEN + ANTS_TAC THENL + [ONCE_REWRITE_TAC[GSYM PATH_IMAGE_REVERSEPATH] THEN + REWRITE_TAC[path_image; IN_IMAGE] THEN ASM_MESON_TAC[]; + DISCH_TAC] THEN + MP_TAC(ISPEC `path_image c1 UNION path_image c:real^2->bool` + OUTSIDE_NO_OVERLAP) THEN + GEN_REWRITE_TAC LAND_CONV [EXTENSION] THEN + DISCH_THEN(MP_TAC o SPEC `reversepath (g2:real^1->real^2) u`) THEN + ASM_REWRITE_TAC[IN_INTER; IN_UNION; NOT_IN_EMPTY; DE_MORGAN_THM] THEN + CONV_TAC TAUT; + ABBREV_TAC `y':real^2 = pathfinish gwy`] THEN + MP_TAC(ISPECL [`reversepath gzx:real^1->real^2`; `gzy:real^1->real^2`] + ARC_CONNECTED_TRANS) THEN + ASM_SIMP_TAC[ARC_REVERSEPATH; PATHSTART_REVERSEPATH; PATHFINISH_REVERSEPATH; + PATH_IMAGE_REVERSEPATH; NOT_IMP] THEN + CONJ_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN + DISCH_THEN(X_CHOOSE_THEN `xy:real^1->real^2` STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN + `(path_image xy DIFF {x:real^2,y}) SUBSET + inside(path_image c1 UNION path_image c2) INTER + outside(path_image c1 UNION path_image c) INTER + outside(path_image c2 UNION path_image c)` + ASSUME_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + SUBGOAL_THEN + `~(((path_image xy):real^2->bool) INTER + inside(path_image c1 UNION path_image c2) INTER + outside(path_image c1 UNION path_image c) INTER + outside(path_image c2 UNION path_image c) = {})` + ASSUME_TAC THENL + [MATCH_MP_TAC(SET_RULE + `!x y. ~(s DIFF {x,y} = {}) /\ s DIFF {x,y} SUBSET t + ==> ~(s INTER t = {})`) THEN + MAP_EVERY EXISTS_TAC [`x:real^2`; `y:real^2`] THEN ASM_REWRITE_TAC[] THEN + ASM_MESON_TAC[NONEMPTY_SIMPLE_PATH_ENDLESS; ARC_IMP_SIMPLE_PATH]; + ALL_TAC] THEN + MP_TAC(ISPECL [`reversepath gwy:real^1->real^2`; `gwx:real^1->real^2`] + ARC_CONNECTED_TRANS) THEN + ASM_SIMP_TAC[ARC_REVERSEPATH; PATHSTART_REVERSEPATH; PATHFINISH_REVERSEPATH; + PATH_IMAGE_REVERSEPATH; NOT_IMP] THEN + CONJ_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN + DISCH_THEN(X_CHOOSE_THEN `y'x':real^1->real^2` STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN + `(path_image y'x' DIFF {x':real^2,y'}) SUBSET + outside(path_image c1 UNION path_image c2)` + ASSUME_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + SUBGOAL_THEN + `?xy'. arc xy' /\ + pathstart xy' = x /\ pathfinish xy' = (y':real^2) /\ + (path_image xy' DELETE x) SUBSET + (inside (path_image c1 UNION path_image c2) INTER + outside (path_image c1 UNION path_image c) INTER + outside (path_image c2 UNION path_image c)) UNION + (path_image c2 DIFF {a,b}) /\ + ~(path_image xy' INTER + inside(path_image c1 UNION path_image c2) INTER + outside(path_image c1 UNION path_image c) INTER + outside(path_image c2 UNION path_image c) = {})` + STRIP_ASSUME_TAC THENL + [ASM_CASES_TAC `y':real^2 = y` THENL + [UNDISCH_THEN `y':real^2 = y` SUBST_ALL_TAC THEN + EXISTS_TAC `xy:real^1->real^2` THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC(SET_RULE + `!y. p DIFF {x,y} SUBSET i /\ y IN j + ==> p DELETE x SUBSET (i UNION j)`) THEN + EXISTS_TAC `y:real^2` THEN ASM_REWRITE_TAC[IN_DIFF] THEN ASM SET_TAC[]; + ALL_TAC] THEN + MP_TAC(ISPECL [`c2:real^1->real^2`; `y:real^2`; `y':real^2`] + EXISTS_SUBARC_OF_ARC_NOENDS) THEN + ASM_SIMP_TAC[SIMPLE_PATH_IMP_ARC; NOT_IMP] THEN + ANTS_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + DISCH_THEN(X_CHOOSE_THEN `yy':real^1->real^2` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `xy ++ yy':real^1->real^2` THEN + ASM_REWRITE_TAC[PATHSTART_JOIN; PATHFINISH_JOIN] THEN CONJ_TAC THENL + [MATCH_MP_TAC ARC_JOIN THEN ASM_REWRITE_TAC[] THEN ASM SET_TAC[]; + ASM_SIMP_TAC[PATH_IMAGE_JOIN; ARC_IMP_PATH] THEN + ASM_SIMP_TAC[SET_RULE + `~(a INTER c = {}) ==> ~((a UNION b) INTER c = {})`] THEN + MATCH_MP_TAC(SET_RULE + `s SUBSET (y INSERT t) ==> s DELETE y SUBSET t`) THEN ASM SET_TAC[]]; + ALL_TAC] THEN + SUBGOAL_THEN + `~((path_image y'x':real^2->bool) INTER + outside(path_image c1 UNION path_image c2) = {})` + ASSUME_TAC THENL + [MP_TAC(ISPEC `y'x':real^1->real^2` NONEMPTY_SIMPLE_PATH_ENDLESS) THEN + ASM_SIMP_TAC[ARC_IMP_SIMPLE_PATH] THEN ASM SET_TAC[]; + ALL_TAC] THEN + SUBGOAL_THEN + `?y'x. arc y'x /\ + pathstart y'x = y' /\ pathfinish y'x = (x:real^2) /\ + ~(path_image y'x INTER + outside(path_image c1 UNION path_image c2) = {}) /\ + (path_image y'x DELETE y') SUBSET + outside(path_image c1 UNION path_image c2) UNION + (path_image c1 DIFF {a,b})` + STRIP_ASSUME_TAC THENL + [ASM_CASES_TAC `x':real^2 = x` THENL + [UNDISCH_THEN `x':real^2 = x` SUBST_ALL_TAC THEN + EXISTS_TAC `y'x':real^1->real^2` THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC(SET_RULE + `!y. p DIFF {x,y} SUBSET i /\ y IN j + ==> p DELETE x SUBSET (i UNION j)`) THEN + EXISTS_TAC `x:real^2` THEN ASM_REWRITE_TAC[IN_DIFF] THEN ASM SET_TAC[]; + ALL_TAC] THEN + MP_TAC(ISPECL [`c1:real^1->real^2`; `x':real^2`; `x:real^2`] + EXISTS_SUBARC_OF_ARC_NOENDS) THEN + ASM_SIMP_TAC[SIMPLE_PATH_IMP_ARC; NOT_IMP] THEN + ANTS_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + DISCH_THEN(X_CHOOSE_THEN `x'x:real^1->real^2` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `y'x' ++ x'x:real^1->real^2` THEN + ASM_REWRITE_TAC[PATHSTART_JOIN; PATHFINISH_JOIN] THEN + ASM_SIMP_TAC[PATH_IMAGE_JOIN; ARC_IMP_PATH] THEN REPEAT CONJ_TAC THENL + [MATCH_MP_TAC ARC_JOIN THEN ASM_REWRITE_TAC[] THEN ASM SET_TAC[]; + ASM SET_TAC[]; + ASM SET_TAC[]]; + ALL_TAC] THEN + SUBGOAL_THEN + `?j. simple_path j /\ pathstart j = x /\ pathfinish j = (x:real^2) /\ + ~(path_image j INTER + inside(path_image c1 UNION path_image c2) = {}) /\ + ~(path_image j INTER + outside(path_image c1 UNION path_image c2) = {}) /\ + path_image j SUBSET + (inside(path_image c1 UNION path_image c2) INTER + outside(path_image c1 UNION path_image c) INTER + outside(path_image c2 UNION path_image c)) UNION + outside(path_image c1 UNION path_image c2) UNION + ((path_image c1 UNION path_image c2) DIFF {a,b})` + STRIP_ASSUME_TAC THENL + [EXISTS_TAC `xy' ++ y'x:real^1->real^2` THEN + ASM_REWRITE_TAC[PATHSTART_JOIN; PATHFINISH_JOIN] THEN + ASM_SIMP_TAC[PATH_IMAGE_JOIN; ARC_IMP_PATH] THEN + CONJ_TAC THENL [ALL_TAC; ASM SET_TAC[]] THEN + MATCH_MP_TAC SIMPLE_PATH_JOIN_LOOP THEN ASM_REWRITE_TAC[] THEN + FIRST_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE + `xy DELETE x SUBSET s + ==> !t. yx DELETE y SUBSET t /\ s INTER t = {} + ==> xy INTER yx SUBSET {x,y}`)) THEN + EXISTS_TAC `outside(path_image c1 UNION path_image c2) UNION + path_image c1 DIFF {a:real^2, b}` THEN + ASM_REWRITE_TAC[] THEN + MP_TAC(ISPEC `path_image c1 UNION path_image c2:real^2->bool` + INSIDE_NO_OVERLAP) THEN + MP_TAC(ISPEC `path_image c1 UNION path_image c2:real^2->bool` + INSIDE_INTER_OUTSIDE) THEN + ASM SET_TAC[]; + ALL_TAC] THEN + SUBGOAL_THEN `~((a:real^2) IN path_image j)` ASSUME_TAC THENL + [FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE + `s SUBSET t ==> ~(a IN t) ==> ~(a IN s)`)) THEN + MATCH_MP_TAC(SET_RULE + `~(a IN s) /\ ~(a IN t) + ==> ~(a IN ((s INTER s' INTER s'') UNION t UNION (u DIFF {a,b})))`) THEN + MAP_EVERY (MP_TAC o ISPEC `path_image c1 UNION path_image c2:real^2->bool`) + [OUTSIDE_NO_OVERLAP; INSIDE_NO_OVERLAP] THEN + REWRITE_TAC[IMP_IMP] THEN MATCH_MP_TAC MONO_AND THEN + ASM SET_TAC[]; + ALL_TAC] THEN + SUBGOAL_THEN + `?u v. ~(u = {}) /\ open u /\ connected u /\ + ~(v = {}) /\ open v /\ connected v /\ + u INTER v = {} /\ u UNION v = (:real^2) DIFF path_image j /\ + frontier u = path_image j /\ frontier v = path_image j /\ + a IN u` + STRIP_ASSUME_TAC THENL + [MP_TAC(ISPEC `j:real^1->real^2` JORDAN_CURVE_THEOREM) THEN + ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`u:real^2->bool`; `v:real^2->bool`] THEN + STRIP_TAC THEN + SUBGOAL_THEN `(a:real^2) IN u \/ (a:real^2) IN v` MP_TAC THENL + [ASM SET_TAC[]; ALL_TAC] THEN + STRIP_TAC THENL + [MAP_EVERY EXISTS_TAC [`u:real^2->bool`; `v:real^2->bool`]; + MAP_EVERY EXISTS_TAC [`v:real^2->bool`; `u:real^2->bool`]] THEN + ASM_REWRITE_TAC[] THEN + ONCE_REWRITE_TAC[INTER_COMM; UNION_COMM] THEN ASM_REWRITE_TAC[]; + ALL_TAC] THEN + SUBGOAL_THEN + `~(v INTER inside(path_image c1 UNION path_image c2) = {}) /\ + ~((v:real^2->bool) INTER outside(path_image c1 UNION path_image c2) = {})` + STRIP_ASSUME_TAC THENL + [CONJ_TAC THENL + [UNDISCH_TAC + `~((path_image j:real^2->bool) INTER + inside(path_image c1 UNION path_image c2) = {})` THEN + REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; IN_INTER] THEN + SUBST1_TAC(SYM(ASSUME `frontier v:real^2->bool = path_image j`)) THEN + DISCH_THEN(X_CHOOSE_THEN `p:real^2` MP_TAC) THEN + DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN + REWRITE_TAC[frontier; IN_DIFF; CLOSURE_APPROACHABLE] THEN + MP_TAC(GEN_REWRITE_RULE I [OPEN_CONTAINS_BALL] (ASSUME + `open(inside(path_image c1 UNION path_image c2):real^2->bool)`)) THEN + DISCH_THEN(MP_TAC o SPEC `p:real^2`) THEN ONCE_REWRITE_TAC[DIST_SYM] THEN + ASM_REWRITE_TAC[SUBSET; IN_BALL] THEN ASM_MESON_TAC[]; + UNDISCH_TAC + `~((path_image j:real^2->bool) INTER + outside(path_image c1 UNION path_image c2) = {})` THEN + REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; IN_INTER] THEN + SUBST1_TAC(SYM(ASSUME `frontier v:real^2->bool = path_image j`)) THEN + DISCH_THEN(X_CHOOSE_THEN `p:real^2` MP_TAC) THEN + DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN + REWRITE_TAC[frontier; IN_DIFF; CLOSURE_APPROACHABLE] THEN + MP_TAC(GEN_REWRITE_RULE I [OPEN_CONTAINS_BALL] (ASSUME + `open(outside(path_image c1 UNION path_image c2):real^2->bool)`)) THEN + DISCH_THEN(MP_TAC o SPEC `p:real^2`) THEN ONCE_REWRITE_TAC[DIST_SYM] THEN + ASM_REWRITE_TAC[SUBSET; IN_BALL] THEN ASM_MESON_TAC[]]; + ALL_TAC] THEN + SUBGOAL_THEN + `~((v:real^2->bool) INTER (path_image c1 UNION path_image c2) = {})` + MP_TAC THENL + [MP_TAC(ASSUME `connected(v:real^2->bool)`) THEN + REWRITE_TAC[connected; CONTRAPOS_THM] THEN DISCH_TAC THEN + MAP_EVERY EXISTS_TAC + [`inside(path_image c1 UNION path_image c2):real^2->bool`; + `outside(path_image c1 UNION path_image c2):real^2->bool`] THEN + ASM_REWRITE_TAC[] THEN ASM SET_TAC[]; + GEN_REWRITE_TAC LAND_CONV [GSYM MEMBER_NOT_EMPTY]] THEN + REWRITE_TAC[IN_INTER; IN_UNION] THEN + DISCH_THEN(X_CHOOSE_THEN `p:real^2` (CONJUNCTS_THEN ASSUME_TAC)) THEN + SUBGOAL_THEN `~(p:real^2 = a)` ASSUME_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + FIRST_X_ASSUM DISJ_CASES_TAC THENL + [SUBGOAL_THEN + `~((u:real^2->bool) INTER inside(path_image c1 UNION path_image c) = {})` + ASSUME_TAC THENL + [MP_TAC(ASSUME `open(u:real^2->bool)`) THEN + REWRITE_TAC[OPEN_CONTAINS_BALL; SUBSET; IN_BALL] THEN + DISCH_THEN(MP_TAC o SPEC `a:real^2`) THEN ASM_REWRITE_TAC[] THEN + ONCE_REWRITE_TAC[DIST_SYM] THEN + SUBGOAL_THEN + `(a:real^2) IN frontier(inside(path_image c1 UNION path_image c))` + MP_TAC THENL [ASM SET_TAC[]; REWRITE_TAC[frontier; IN_DIFF]] THEN + REWRITE_TAC[CLOSURE_APPROACHABLE; GSYM MEMBER_NOT_EMPTY; IN_INTER] THEN + MESON_TAC[]; + ALL_TAC] THEN + SUBGOAL_THEN + `~((v:real^2->bool) INTER inside(path_image c1 UNION path_image c) = {})` + ASSUME_TAC THENL + [MP_TAC(ASSUME `open(v:real^2->bool)`) THEN + REWRITE_TAC[OPEN_CONTAINS_BALL; SUBSET; IN_BALL] THEN + DISCH_THEN(MP_TAC o SPEC `p:real^2`) THEN ASM_REWRITE_TAC[] THEN + ONCE_REWRITE_TAC[DIST_SYM] THEN + SUBGOAL_THEN + `(p:real^2) IN frontier(inside(path_image c1 UNION path_image c))` + MP_TAC THENL [ASM SET_TAC[]; REWRITE_TAC[frontier; IN_DIFF]] THEN + REWRITE_TAC[CLOSURE_APPROACHABLE; GSYM MEMBER_NOT_EMPTY; IN_INTER] THEN + MESON_TAC[]; + ALL_TAC] THEN + MP_TAC(ASSUME + `connected(inside(path_image c1 UNION path_image c):real^2->bool)`) THEN + REWRITE_TAC[connected] THEN + MAP_EVERY EXISTS_TAC [`u:real^2->bool`; `v:real^2->bool`] THEN + ASM_REWRITE_TAC[GSYM INTER_ASSOC; INTER_EMPTY] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE + `j SUBSET t ==> s INTER t = {} ==> s SUBSET UNIV DIFF j`)) THEN + MATCH_MP_TAC(SET_RULE + `!x. s INTER t2 = {} /\ u SUBSET t2 /\ + x INTER v = {} /\ s SUBSET x + ==> s INTER + (t1 INTER t2 INTER t3 UNION u UNION (v DIFF w)) = {}`) THEN + EXISTS_TAC `inside(path_image c1 UNION path_image c2:real^2->bool)` THEN + ASM_REWRITE_TAC[INSIDE_INTER_OUTSIDE; INSIDE_NO_OVERLAP]; + SUBGOAL_THEN + `~((u:real^2->bool) INTER inside(path_image c2 UNION path_image c) = {})` + ASSUME_TAC THENL + [MP_TAC(ASSUME `open(u:real^2->bool)`) THEN + REWRITE_TAC[OPEN_CONTAINS_BALL; SUBSET; IN_BALL] THEN + DISCH_THEN(MP_TAC o SPEC `a:real^2`) THEN ASM_REWRITE_TAC[] THEN + ONCE_REWRITE_TAC[DIST_SYM] THEN + SUBGOAL_THEN + `(a:real^2) IN frontier(inside(path_image c2 UNION path_image c))` + MP_TAC THENL [ASM SET_TAC[]; REWRITE_TAC[frontier; IN_DIFF]] THEN + REWRITE_TAC[CLOSURE_APPROACHABLE; GSYM MEMBER_NOT_EMPTY; IN_INTER] THEN + MESON_TAC[]; + ALL_TAC] THEN + SUBGOAL_THEN + `~((v:real^2->bool) INTER inside(path_image c2 UNION path_image c) = {})` + ASSUME_TAC THENL + [MP_TAC(ASSUME `open(v:real^2->bool)`) THEN + REWRITE_TAC[OPEN_CONTAINS_BALL; SUBSET; IN_BALL] THEN + DISCH_THEN(MP_TAC o SPEC `p:real^2`) THEN ASM_REWRITE_TAC[] THEN + ONCE_REWRITE_TAC[DIST_SYM] THEN + SUBGOAL_THEN + `(p:real^2) IN frontier(inside(path_image c2 UNION path_image c))` + MP_TAC THENL [ASM SET_TAC[]; REWRITE_TAC[frontier; IN_DIFF]] THEN + REWRITE_TAC[CLOSURE_APPROACHABLE; GSYM MEMBER_NOT_EMPTY; IN_INTER] THEN + MESON_TAC[]; + ALL_TAC] THEN + MP_TAC(ASSUME + `connected(inside(path_image c2 UNION path_image c):real^2->bool)`) THEN + REWRITE_TAC[connected] THEN + MAP_EVERY EXISTS_TAC [`u:real^2->bool`; `v:real^2->bool`] THEN + ASM_REWRITE_TAC[GSYM INTER_ASSOC; INTER_EMPTY] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE + `j SUBSET t ==> s INTER t = {} ==> s SUBSET UNIV DIFF j`)) THEN + MATCH_MP_TAC(SET_RULE + `!x. s INTER t3 = {} /\ u SUBSET t3 /\ + x INTER v = {} /\ s SUBSET x + ==> s INTER + (t1 INTER t2 INTER t3 UNION u UNION (v DIFF w)) = {}`) THEN + EXISTS_TAC `inside(path_image c1 UNION path_image c2:real^2->bool)` THEN + ASM_REWRITE_TAC[INSIDE_INTER_OUTSIDE; INSIDE_NO_OVERLAP]]);; diff --git a/Multivariate/flyspeck.ml b/Multivariate/flyspeck.ml new file mode 100644 index 0000000..ee46b82 --- /dev/null +++ b/Multivariate/flyspeck.ml @@ -0,0 +1,7029 @@ +(* ========================================================================= *) +(* Results intended for Flyspeck. *) +(* ========================================================================= *) + +needs "Multivariate/polytope.ml";; +needs "Multivariate/realanalysis.ml";; +needs "Multivariate/geom.ml";; +needs "Multivariate/cross.ml";; + +prioritize_vector();; + +(* ------------------------------------------------------------------------- *) +(* Not really Flyspeck-specific but needs both angles and cross products. *) +(* ------------------------------------------------------------------------- *) + +let NORM_CROSS = prove + (`!x y. norm(x cross y) = norm(x) * norm(y) * sin(vector_angle x y)`, + REPEAT GEN_TAC THEN + MATCH_MP_TAC REAL_POW_EQ THEN EXISTS_TAC `2` THEN + SIMP_TAC[NORM_POS_LE; SIN_VECTOR_ANGLE_POS; REAL_LE_MUL; ARITH_EQ] THEN + MP_TAC(SPECL [`x:real^3`; `y:real^3`] NORM_CROSS_DOT) THEN + REWRITE_TAC[VECTOR_ANGLE] THEN + MP_TAC(SPEC `vector_angle (x:real^3) y` SIN_CIRCLE) THEN + CONV_TAC REAL_RING);; + +(* ------------------------------------------------------------------------- *) +(* Other miscelleneous lemmas. *) +(* ------------------------------------------------------------------------- *) + +let COPLANAR_INSERT_0_NEG = prove + (`coplanar(vec 0 INSERT --x INSERT s) <=> coplanar(vec 0 INSERT x INSERT s)`, + REWRITE_TAC[coplanar; INSERT_SUBSET] THEN + ONCE_REWRITE_TAC[TAUT `a /\ b /\ c <=> ~(a ==> ~(b /\ c))`] THEN + SIMP_TAC[AFFINE_HULL_EQ_SPAN; SPAN_NEG_EQ]);; + +let COPLANAR_IMP_NEGLIGIBLE = prove + (`!s:real^3->bool. coplanar s ==> negligible s`, + REWRITE_TAC[coplanar] THEN + MESON_TAC[NEGLIGIBLE_AFFINE_HULL_3; NEGLIGIBLE_SUBSET]);; + +let NOT_COPLANAR_0_4_IMP_INDEPENDENT = prove + (`!v1 v2 v3:real^N. ~coplanar {vec 0,v1,v2,v3} ==> independent {v1,v2,v3}`, + REPEAT GEN_TAC THEN REWRITE_TAC[independent; CONTRAPOS_THM] THEN + REWRITE_TAC[dependent] THEN + SUBGOAL_THEN + `!v1 v2 v3:real^N. v1 IN span {v2,v3} ==> coplanar{vec 0,v1,v2,v3}` + ASSUME_TAC THENL + [REPEAT STRIP_TAC THEN REWRITE_TAC[coplanar] THEN + MAP_EVERY EXISTS_TAC [`vec 0:real^N`; `v2:real^N`; `v3:real^N`] THEN + SIMP_TAC[AFFINE_HULL_EQ_SPAN; HULL_INC; IN_INSERT] THEN + REWRITE_TAC[INSERT_SUBSET; EMPTY_SUBSET] THEN + ASM_SIMP_TAC[SPAN_SUPERSET; IN_INSERT] THEN + POP_ASSUM MP_TAC THEN SPEC_TAC(`v1:real^N`,`v1:real^N`) THEN + REWRITE_TAC[GSYM SUBSET] THEN MATCH_MP_TAC SPAN_MONO THEN SET_TAC[]; + REWRITE_TAC[IN_INSERT; NOT_IN_EMPTY] THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + FIRST_X_ASSUM SUBST_ALL_TAC THENL + [FIRST_X_ASSUM(MP_TAC o SPECL [`v1:real^N`; `v2:real^N`; `v3:real^N`]); + FIRST_X_ASSUM(MP_TAC o SPECL [`v2:real^N`; `v3:real^N`; `v1:real^N`]); + FIRST_X_ASSUM(MP_TAC o SPECL [`v3:real^N`; `v1:real^N`; `v2:real^N`])] + THEN REWRITE_TAC[INSERT_AC] THEN DISCH_THEN MATCH_MP_TAC THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE + `a IN s ==> s SUBSET t ==> a IN t`)) THEN + MATCH_MP_TAC SPAN_MONO THEN SET_TAC[]]);; + +let NOT_COPLANAR_NOT_COLLINEAR = prove + (`!v1 v2 v3 w:real^N. ~coplanar {v1, v2, v3, w} ==> ~collinear {v1, v2, v3}`, + REPEAT GEN_TAC THEN + REWRITE_TAC[COLLINEAR_AFFINE_HULL; coplanar; CONTRAPOS_THM] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `x:real^N` THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `y:real^N` THEN + REWRITE_TAC[INSERT_SUBSET; EMPTY_SUBSET] THEN STRIP_TAC THEN + EXISTS_TAC `w:real^N` THEN ASM_SIMP_TAC[HULL_INC; IN_INSERT] THEN + REPEAT CONJ_TAC THEN + MATCH_MP_TAC(SET_RULE `!t. t SUBSET s /\ x IN t ==> x IN s`) THEN + EXISTS_TAC `affine hull {x:real^N,y}` THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC HULL_MONO THEN SET_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* Some special scaling theorems. *) +(* ------------------------------------------------------------------------- *) + +let SUBSET_AFFINE_HULL_SPECIAL_SCALE = prove + (`!a x s t. + ~(a = &0) + ==> (vec 0 INSERT (a % x) INSERT s SUBSET affine hull t <=> + vec 0 INSERT x INSERT s SUBSET affine hull t)`, + REPEAT STRIP_TAC THEN REWRITE_TAC[INSERT_SUBSET] THEN + MATCH_MP_TAC(TAUT `(a ==> (b <=> c)) ==> (a /\ b <=> a /\ c)`) THEN + ASM_SIMP_TAC[AFFINE_HULL_EQ_SPAN; SPAN_MUL_EQ]);; + +let COLLINEAR_SPECIAL_SCALE = prove + (`!a x y. ~(a = &0) ==> (collinear {vec 0,a % x,y} <=> collinear{vec 0,x,y})`, + REPEAT STRIP_TAC THEN REWRITE_TAC[COLLINEAR_AFFINE_HULL] THEN + ASM_SIMP_TAC[SUBSET_AFFINE_HULL_SPECIAL_SCALE]);; + +let COLLINEAR_SCALE_ALL = prove + (`!a b v w. ~(a = &0) /\ ~(b = &0) + ==> (collinear {vec 0,a % v,b % w} <=> collinear {vec 0,v,w})`, + REPEAT STRIP_TAC THEN ASM_SIMP_TAC[COLLINEAR_SPECIAL_SCALE] THEN + ONCE_REWRITE_TAC[SET_RULE `{a,b,c} = {a,c,b}`] THEN + ASM_SIMP_TAC[COLLINEAR_SPECIAL_SCALE]);; + +let COPLANAR_SPECIAL_SCALE = prove + (`!a x y z. + ~(a = &0) ==> (coplanar {vec 0,a % x,y,z} <=> coplanar {vec 0,x,y,z})`, + REPEAT STRIP_TAC THEN REWRITE_TAC[coplanar] THEN + ASM_SIMP_TAC[SUBSET_AFFINE_HULL_SPECIAL_SCALE]);; + +let COPLANAR_SCALE_ALL = prove + (`!a b c x y z. + ~(a = &0) /\ ~(b = &0) /\ ~(c = &0) + ==> (coplanar {vec 0,a % x,b % y,c % z} <=> coplanar {vec 0,x,y,z})`, + REPEAT STRIP_TAC THEN ASM_SIMP_TAC[COPLANAR_SPECIAL_SCALE] THEN + ONCE_REWRITE_TAC[SET_RULE `{a,b,c,d} = {a,c,d,b}`] THEN + ASM_SIMP_TAC[COPLANAR_SPECIAL_SCALE] THEN + ONCE_REWRITE_TAC[SET_RULE `{a,b,c,d} = {a,c,d,b}`] THEN + ASM_SIMP_TAC[COPLANAR_SPECIAL_SCALE]);; + +(* ------------------------------------------------------------------------- *) +(* Specialized lemmas about "dropout". *) +(* ------------------------------------------------------------------------- *) + +let DROPOUT_BASIS_3 = prove + (`(dropout 3:real^3->real^2) (basis 1) = basis 1 /\ + (dropout 3:real^3->real^2) (basis 2) = basis 2 /\ + (dropout 3:real^3->real^2) (basis 3) = vec 0`, + SIMP_TAC[LAMBDA_BETA; dropout; basis; CART_EQ; DIMINDEX_2; DIMINDEX_3; ARITH; + VEC_COMPONENT; LT_IMP_LE; ARITH_RULE `i <= 2 ==> i + 1 <= 3`; + ARITH_RULE `1 <= i + 1`] THEN + ARITH_TAC);; + +let COLLINEAR_BASIS_3 = prove + (`collinear {vec 0,basis 3,x} <=> (dropout 3:real^3->real^2) x = vec 0`, + SIMP_TAC[CART_EQ; FORALL_2; FORALL_3; DIMINDEX_2; DIMINDEX_3; + dropout; LAMBDA_BETA; BASIS_COMPONENT; ARITH; REAL_MUL_RID; + VECTOR_MUL_COMPONENT; VEC_COMPONENT; REAL_MUL_RZERO; UNWIND_THM1; + COLLINEAR_LEMMA] THEN + REWRITE_TAC[RIGHT_EXISTS_AND_THM; GSYM EXISTS_REFL] THEN REAL_ARITH_TAC);; + +let OPEN_DROPOUT_3 = prove + (`!P. open {x | P x} ==> open {x | P((dropout 3:real^3->real^2) x)}`, + REPEAT STRIP_TAC THEN MP_TAC(ISPECL + [`dropout 3:real^3->real^2`; `{x:real^2 | P x}`] + CONTINUOUS_OPEN_PREIMAGE_UNIV) THEN + ASM_REWRITE_TAC[IN_ELIM_THM] THEN DISCH_THEN MATCH_MP_TAC THEN + GEN_TAC THEN MATCH_MP_TAC LINEAR_CONTINUOUS_AT THEN + SIMP_TAC[LINEAR_DROPOUT; DIMINDEX_2; DIMINDEX_3; ARITH]);; + +let SLICE_DROPOUT_3 = prove + (`!P t. slice 3 t {x | P((dropout 3:real^3->real^2) x)} = {x | P x}`, + REPEAT GEN_TAC THEN REWRITE_TAC[slice] THEN + REWRITE_TAC[EXTENSION; IN_IMAGE; IN_ELIM_THM; IN_INTER] THEN + X_GEN_TAC `y:real^2` THEN EQ_TAC THENL [MESON_TAC[]; ALL_TAC] THEN + DISCH_TAC THEN EXISTS_TAC `(pushin 3 t:real^2->real^3) y` THEN + ASM_SIMP_TAC[DIMINDEX_2; DIMINDEX_3; DROPOUT_PUSHIN; ARITH] THEN + SIMP_TAC[pushin; LAMBDA_BETA; LT_REFL; DIMINDEX_3; ARITH]);; + +let NOT_COPLANAR_IMP_NOT_COLLINEAR_DROPOUT_3 = prove + (`!x y:real^3. + ~coplanar {vec 0,basis 3, x, y} + ==> ~collinear {vec 0,dropout 3 x:real^2,dropout 3 y}`, + REPEAT GEN_TAC THEN REWRITE_TAC[COLLINEAR_AFFINE_HULL; coplanar] THEN + REWRITE_TAC[CONTRAPOS_THM; INSERT_SUBSET; LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`u:real^2`; `v:real^2`] THEN + REWRITE_TAC[EMPTY_SUBSET] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + ASM_SIMP_TAC[AFFINE_HULL_EQ_SPAN] THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE RAND_CONV [AFFINE_HULL_2]) THEN + REWRITE_TAC[IN_ELIM_THM; LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`a:real`;`b:real`] THEN STRIP_TAC THEN + SUBGOAL_THEN `?r s. a * r + b * s = -- &1` STRIP_ASSUME_TAC THENL + [ASM_CASES_TAC `a = &0` THENL + [UNDISCH_TAC `a + b = &1` THEN + ASM_SIMP_TAC[REAL_MUL_LZERO; REAL_ADD_LID; REAL_MUL_LID; EXISTS_REFL]; + ASM_SIMP_TAC[REAL_FIELD + `~(a = &0) ==> (a * r + x = y <=> r = (y - x) / a)`] THEN + MESON_TAC[]]; + ALL_TAC] THEN + EXISTS_TAC `vector[(u:real^2)$1; u$2; r]:real^3` THEN + EXISTS_TAC `vector[(v:real^2)$1; v$2; s]:real^3` THEN + EXISTS_TAC `basis 3:real^3` THEN + MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN CONJ_TAC THENL + [REWRITE_TAC[AFFINE_HULL_3; IN_ELIM_THM; LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY EXISTS_TAC [`a / &2`;`b / &2`; `&1 / &2`] THEN + ASM_REWRITE_TAC[REAL_ARITH + `a / &2 + b / &2 + &1 / &2 = &1 <=> a + b = &1`] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [CART_EQ]) THEN + SIMP_TAC[CART_EQ; DIMINDEX_2; DIMINDEX_3; FORALL_2; FORALL_3; + VEC_COMPONENT; VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT; + VECTOR_3; BASIS_COMPONENT; ARITH] THEN + REPEAT(FIRST_X_ASSUM(MP_TAC o SYM)) THEN CONV_TAC REAL_RING; + ALL_TAC] THEN + SIMP_TAC[AFFINE_HULL_EQ_SPAN] THEN DISCH_TAC THEN + SIMP_TAC[SPAN_SUPERSET; IN_INSERT] THEN + SUBGOAL_THEN + `!x. (dropout 3:real^3->real^2) x IN span {u,v} + ==> x IN span {vector [u$1; u$2; r], vector [v$1; v$2; s], basis 3}` + (fun th -> ASM_MESON_TAC[th]) THEN + GEN_TAC THEN REWRITE_TAC[SPAN_2; SPAN_3] THEN + SIMP_TAC[IN_ELIM_THM; IN_UNIV; CART_EQ; DIMINDEX_2; DIMINDEX_3; + FORALL_2; FORALL_3; dropout; VECTOR_ADD_COMPONENT; LAMBDA_BETA; + VECTOR_MUL_COMPONENT; VECTOR_3; BASIS_COMPONENT; ARITH] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `c:real` THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `d:real` THEN + STRIP_TAC THEN ASM_REWRITE_TAC[REAL_MUL_RZERO; REAL_ADD_RID] THEN + REWRITE_TAC[REAL_ARITH `x = a + b + c * &1 <=> c = x - a - b`] THEN + REWRITE_TAC[EXISTS_REFL]);; + +let SLICE_312 = prove + (`!s:real^3->bool. slice 1 t s = {y:real^2 | vector[t;y$1;y$2] IN s}`, + SIMP_TAC[EXTENSION; IN_SLICE; DIMINDEX_2; DIMINDEX_3; ARITH] THEN + REPEAT GEN_TAC THEN REWRITE_TAC[IN_ELIM_THM] THEN + AP_THM_TAC THEN AP_TERM_TAC THEN + SIMP_TAC[CART_EQ; pushin; LAMBDA_BETA; FORALL_3; DIMINDEX_3; ARITH; + VECTOR_3]);; + +let SLICE_123 = prove + (`!s:real^3->bool. slice 3 t s = {y:real^2 | vector[y$1;y$2;t] IN s}`, + SIMP_TAC[EXTENSION; IN_SLICE; DIMINDEX_2; DIMINDEX_3; ARITH] THEN + REPEAT GEN_TAC THEN REWRITE_TAC[IN_ELIM_THM] THEN + AP_THM_TAC THEN AP_TERM_TAC THEN + SIMP_TAC[CART_EQ; pushin; LAMBDA_BETA; FORALL_3; DIMINDEX_3; ARITH; + VECTOR_3]);; + +(* ------------------------------------------------------------------------- *) +(* "Padding" injection from real^2 -> real^3 with zero last coordinate. *) +(* ------------------------------------------------------------------------- *) + +let pad2d3d = new_definition + `(pad2d3d:real^2->real^3) x = lambda i. if i < 3 then x$i else &0`;; + +let FORALL_PAD2D3D_THM = prove + (`!P. (!y:real^3. y$3 = &0 ==> P y) <=> (!x. P(pad2d3d x))`, + GEN_TAC THEN EQ_TAC THEN REPEAT STRIP_TAC THENL + [FIRST_X_ASSUM MATCH_MP_TAC THEN REWRITE_TAC[pad2d3d] THEN + SIMP_TAC[LAMBDA_BETA; DIMINDEX_3; ARITH; LT_REFL]; + FIRST_X_ASSUM(MP_TAC o SPEC `(lambda i. (y:real^3)$i):real^2`) THEN + MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN + SIMP_TAC[CART_EQ; pad2d3d; DIMINDEX_3; ARITH; LAMBDA_BETA; DIMINDEX_2; + ARITH_RULE `i < 3 <=> i <= 2`] THEN + REWRITE_TAC[ARITH_RULE `i <= 3 <=> i <= 2 \/ i = 3`] THEN + ASM_MESON_TAC[]]);; + +let QUANTIFY_PAD2D3D_THM = prove + (`(!P. (!y:real^3. y$3 = &0 ==> P y) <=> (!x. P(pad2d3d x))) /\ + (!P. (?y:real^3. y$3 = &0 /\ P y) <=> (?x. P(pad2d3d x)))`, + REWRITE_TAC[MESON[] `(?y. P y) <=> ~(!x. ~P x)`] THEN + REWRITE_TAC[GSYM FORALL_PAD2D3D_THM] THEN MESON_TAC[]);; + +let LINEAR_PAD2D3D = prove + (`linear pad2d3d`, + REWRITE_TAC[linear; pad2d3d] THEN + SIMP_TAC[CART_EQ; VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT; + LAMBDA_BETA; DIMINDEX_2; DIMINDEX_3; ARITH; + ARITH_RULE `i < 3 ==> i <= 2`] THEN + REPEAT STRIP_TAC THEN REPEAT(COND_CASES_TAC THEN ASM_REWRITE_TAC[]) THEN + REAL_ARITH_TAC);; + +let INJECTIVE_PAD2D3D = prove + (`!x y. pad2d3d x = pad2d3d y ==> x = y`, + SIMP_TAC[CART_EQ; pad2d3d; LAMBDA_BETA; DIMINDEX_3; DIMINDEX_2] THEN + REWRITE_TAC[ARITH_RULE `i < 3 <=> i <= 2`] THEN + MESON_TAC[ARITH_RULE `i <= 2 ==> i <= 3`]);; + +let NORM_PAD2D3D = prove + (`!x. norm(pad2d3d x) = norm x`, + SIMP_TAC[NORM_EQ; DOT_2; DOT_3; pad2d3d; LAMBDA_BETA; + DIMINDEX_2; DIMINDEX_3; ARITH] THEN + REAL_ARITH_TAC);; + +(* ------------------------------------------------------------------------- *) +(* Apply 3D->2D conversion to a goal. Take care to preserve variable names. *) +(* ------------------------------------------------------------------------- *) + +let PAD2D3D_QUANTIFY_CONV = + let gv = genvar `:real^2` in + let pth = CONV_RULE (BINOP_CONV(BINDER_CONV(RAND_CONV(GEN_ALPHA_CONV gv)))) + QUANTIFY_PAD2D3D_THM in + let conv1 = GEN_REWRITE_CONV I [pth] + and dest_quant tm = try dest_forall tm with Failure _ -> dest_exists tm in + fun tm -> + let th = conv1 tm in + let name = fst(dest_var(fst(dest_quant tm))) in + let ty = snd(dest_var(fst(dest_quant(rand(concl th))))) in + CONV_RULE(RAND_CONV(GEN_ALPHA_CONV(mk_var(name,ty)))) th;; + +let PAD2D3D_TAC = + let pad2d3d_tm = `pad2d3d` + and pths = [LINEAR_PAD2D3D; INJECTIVE_PAD2D3D; NORM_PAD2D3D] + and cth = prove + (`{} = IMAGE pad2d3d {} /\ + vec 0 = pad2d3d(vec 0)`, + REWRITE_TAC[IMAGE_CLAUSES] THEN MESON_TAC[LINEAR_PAD2D3D; LINEAR_0]) in + let lasttac = + GEN_REWRITE_TAC REDEPTH_CONV [LINEAR_INVARIANTS pad2d3d_tm pths] in + fun gl -> (GEN_REWRITE_TAC ONCE_DEPTH_CONV [cth] THEN + CONV_TAC(DEPTH_CONV PAD2D3D_QUANTIFY_CONV) THEN + lasttac) gl;; + +(* ------------------------------------------------------------------------- *) +(* The notion of a plane, and using it to characterize coplanarity. *) +(* ------------------------------------------------------------------------- *) + +let plane = new_definition + `plane x = (?u v w. ~(collinear {u,v,w}) /\ x = affine hull {u,v,w})`;; + +let PLANE_TRANSLATION_EQ = prove + (`!a:real^N s. plane(IMAGE (\x. a + x) s) <=> plane s`, + REWRITE_TAC[plane] THEN GEOM_TRANSLATE_TAC[]);; + +let PLANE_TRANSLATION = prove + (`!a:real^N s. plane s ==> plane(IMAGE (\x. a + x) s)`, + REWRITE_TAC[PLANE_TRANSLATION_EQ]);; + +add_translation_invariants [PLANE_TRANSLATION_EQ];; + +let PLANE_LINEAR_IMAGE_EQ = prove + (`!f:real^M->real^N p. + linear f /\ (!x y. f x = f y ==> x = y) + ==> (plane(IMAGE f p) <=> plane p)`, + REPEAT STRIP_TAC THEN REWRITE_TAC[plane] THEN + MATCH_MP_TAC EQ_TRANS THEN EXISTS_TAC + `?u. u IN IMAGE f (:real^M) /\ + ?v. v IN IMAGE f (:real^M) /\ + ?w. w IN IMAGE (f:real^M->real^N) (:real^M) /\ + ~collinear {u, v, w} /\ IMAGE f p = affine hull {u, v, w}` THEN + CONJ_TAC THENL + [REWRITE_TAC[RIGHT_AND_EXISTS_THM; IN_IMAGE; IN_UNIV] THEN + REPEAT(AP_TERM_TAC THEN ABS_TAC) THEN + EQ_TAC THEN DISCH_TAC THEN ASM_REWRITE_TAC[] THEN + SUBGOAL_THEN `{u,v,w} SUBSET IMAGE (f:real^M->real^N) p` MP_TAC THENL + [ASM_REWRITE_TAC[HULL_SUBSET]; SET_TAC[]]; + REWRITE_TAC[EXISTS_IN_IMAGE; IN_UNIV] THEN + REWRITE_TAC[SET_RULE `{f a,f b,f c} = IMAGE f {a,b,c}`] THEN + ASM_SIMP_TAC[AFFINE_HULL_LINEAR_IMAGE] THEN + REPEAT(AP_TERM_TAC THEN ABS_TAC) THEN BINOP_TAC THENL + [ASM_MESON_TAC[COLLINEAR_LINEAR_IMAGE_EQ]; ASM SET_TAC[]]]);; + +let PLANE_LINEAR_IMAGE = prove + (`!f:real^M->real^N p. + linear f /\ plane p /\ (!x y. f x = f y ==> x = y) + ==> plane(IMAGE f p)`, + MESON_TAC[PLANE_LINEAR_IMAGE_EQ]);; + +add_linear_invariants [PLANE_LINEAR_IMAGE_EQ];; + +let AFFINE_PLANE = prove + (`!p. plane p ==> affine p`, + SIMP_TAC[plane; LEFT_IMP_EXISTS_THM; AFFINE_AFFINE_HULL]);; + +let ROTATION_PLANE_HORIZONTAL = prove + (`!s. plane s + ==> ?a f. orthogonal_transformation f /\ det(matrix f) = &1 /\ + IMAGE f (IMAGE (\x. a + x) s) = {z:real^3 | z$3 = &0}`, + let lemma = prove + (`span {z:real^3 | z$3 = &0} = {z:real^3 | z$3 = &0}`, + REWRITE_TAC[SPAN_EQ_SELF; subspace; IN_ELIM_THM] THEN + SIMP_TAC[VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT; VEC_COMPONENT; + DIMINDEX_3; ARITH] THEN REAL_ARITH_TAC) in + REPEAT STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [plane]) THEN + REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`a:real^3`; `b:real^3`; `c:real^3`] THEN + MAP_EVERY (fun t -> + ASM_CASES_TAC t THENL [ASM_REWRITE_TAC[COLLINEAR_2; INSERT_AC]; + ALL_TAC]) + [`a:real^3 = b`; `a:real^3 = c`; `b:real^3 = c`] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC SUBST1_TAC) THEN + ASM_SIMP_TAC[AFFINE_HULL_INSERT_SPAN; IN_INSERT; NOT_IN_EMPTY] THEN + EXISTS_TAC `--a:real^3` THEN + REWRITE_TAC[SET_RULE `IMAGE (\x:real^3. --a + x) {a + x | x | x IN s} = + IMAGE (\x. --a + a + x) s`] THEN + REWRITE_TAC[VECTOR_ARITH `--a + a + x:real^3 = x`; IMAGE_ID] THEN + REWRITE_TAC[SET_RULE `{x - a:real^x | x = b \/ x = c} = {b - a,c - a}`] THEN + MP_TAC(ISPEC `span{b - a:real^3,c - a}` + ROTATION_LOWDIM_HORIZONTAL) THEN + REWRITE_TAC[DIMINDEX_3] THEN ANTS_TAC THENL + [MATCH_MP_TAC LET_TRANS THEN + EXISTS_TAC `CARD{b - a:real^3,c - a}` THEN + SIMP_TAC[DIM_SPAN; DIM_LE_CARD; FINITE_RULES] THEN + SIMP_TAC[CARD_CLAUSES; FINITE_RULES] THEN ARITH_TAC; + ALL_TAC] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `f:real^3->real^3` THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP ORTHOGONAL_TRANSFORMATION_LINEAR) THEN + ASM_SIMP_TAC[GSYM SPAN_LINEAR_IMAGE] THEN + GEN_REWRITE_TAC RAND_CONV [GSYM lemma] THEN + MATCH_MP_TAC DIM_EQ_SPAN THEN CONJ_TAC THENL + [ASM_MESON_TAC[IMAGE_SUBSET; SPAN_INC; SUBSET_TRANS]; ALL_TAC] THEN + MATCH_MP_TAC LE_TRANS THEN EXISTS_TAC `2` THEN CONJ_TAC THENL + [MP_TAC(ISPECL [`{z:real^3 | z$3 = &0}`; `(:real^3)`] DIM_EQ_SPAN) THEN + REWRITE_TAC[SUBSET_UNIV; DIM_UNIV; DIMINDEX_3; lemma] THEN + MATCH_MP_TAC(TAUT `~r /\ (~p ==> q) ==> (q ==> r) ==> p`) THEN + REWRITE_TAC[ARITH_RULE `~(x <= 2) <=> 3 <= x`] THEN + REWRITE_TAC[EXTENSION; SPAN_UNIV; IN_ELIM_THM] THEN + DISCH_THEN(MP_TAC o SPEC `vector[&0;&0;&1]:real^3`) THEN + REWRITE_TAC[IN_UNIV; VECTOR_3] THEN REAL_ARITH_TAC; + ALL_TAC] THEN + MATCH_MP_TAC LE_TRANS THEN EXISTS_TAC `dim {b - a:real^3,c - a}` THEN + CONJ_TAC THENL + [ALL_TAC; ASM_MESON_TAC[LE_REFL; DIM_INJECTIVE_LINEAR_IMAGE; + ORTHOGONAL_TRANSFORMATION_INJECTIVE]] THEN + MP_TAC(ISPEC `{b - a:real^3,c - a}` INDEPENDENT_BOUND_GENERAL) THEN + SIMP_TAC[CARD_CLAUSES; FINITE_RULES; IN_SING; NOT_IN_EMPTY] THEN + ASM_REWRITE_TAC[VECTOR_ARITH `b - a:real^3 = c - a <=> b = c`; ARITH] THEN + DISCH_THEN MATCH_MP_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE (RAND_CONV o RAND_CONV) + [SET_RULE `{a,b,c} = {b,a,c}`]) THEN + REWRITE_TAC[] THEN ONCE_REWRITE_TAC[COLLINEAR_3] THEN + REWRITE_TAC[independent; CONTRAPOS_THM; dependent] THEN + REWRITE_TAC[IN_INSERT; NOT_IN_EMPTY; RIGHT_OR_DISTRIB] THEN + REWRITE_TAC[EXISTS_OR_THM; UNWIND_THM2] THEN + ASM_SIMP_TAC[SET_RULE `~(a = b) ==> {a,b} DELETE b = {a}`; + SET_RULE `~(a = b) ==> {a,b} DELETE a = {b}`; + VECTOR_ARITH `b - a:real^3 = c - a <=> b = c`] THEN + REWRITE_TAC[SPAN_BREAKDOWN_EQ; SPAN_EMPTY; IN_SING] THEN + ONCE_REWRITE_TAC[VECTOR_SUB_EQ] THEN MESON_TAC[COLLINEAR_LEMMA; INSERT_AC]);; + +let ROTATION_HORIZONTAL_PLANE = prove + (`!p. plane p + ==> ?a f. orthogonal_transformation f /\ det(matrix f) = &1 /\ + IMAGE (\x. a + x) (IMAGE f {z:real^3 | z$3 = &0}) = p`, + REPEAT STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o MATCH_MP ROTATION_PLANE_HORIZONTAL) THEN + DISCH_THEN(X_CHOOSE_THEN `a:real^3` + (X_CHOOSE_THEN `f:real^3->real^3` STRIP_ASSUME_TAC)) THEN + FIRST_ASSUM(X_CHOOSE_THEN `g:real^3->real^3` STRIP_ASSUME_TAC o MATCH_MP + ORTHOGONAL_TRANSFORMATION_INVERSE) THEN + MAP_EVERY EXISTS_TAC [`--a:real^3`; `g:real^3->real^3`] THEN + FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN + ASM_REWRITE_TAC[GSYM IMAGE_o; o_DEF; IMAGE_ID; + VECTOR_ARITH `--a + a + x:real^3 = x`] THEN + MATCH_MP_TAC(REAL_RING `!f. f * g = &1 /\ f = &1 ==> g = &1`) THEN + EXISTS_TAC `det(matrix(f:real^3->real^3))` THEN + REWRITE_TAC[GSYM DET_MUL] THEN + ASM_SIMP_TAC[GSYM MATRIX_COMPOSE; ORTHOGONAL_TRANSFORMATION_LINEAR] THEN + ASM_REWRITE_TAC[o_DEF; MATRIX_ID; DET_I]);; + +let COPLANAR = prove + (`2 <= dimindex(:N) + ==> !s:real^N->bool. coplanar s <=> ?x. plane x /\ s SUBSET x`, + DISCH_TAC THEN GEN_TAC THEN REWRITE_TAC[coplanar; plane] THEN + CONV_TAC SYM_CONV THEN REWRITE_TAC[LEFT_AND_EXISTS_THM] THEN + ONCE_REWRITE_TAC[MESON[] + `(?x u v w. p x u v w) <=> (?u v w x. p x u v w)`] THEN + REWRITE_TAC[GSYM CONJ_ASSOC; RIGHT_EXISTS_AND_THM; UNWIND_THM2] THEN + EQ_TAC THENL [MESON_TAC[]; REWRITE_TAC[LEFT_IMP_EXISTS_THM]] THEN + MAP_EVERY X_GEN_TAC [`u:real^N`; `v:real^N`; `w:real^N`] THEN DISCH_TAC THEN + SUBGOAL_THEN + `s SUBSET {u + x:real^N | x | x IN span {y - u | y IN {v,w}}}` + MP_TAC THENL + [FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP + (REWRITE_RULE[IMP_CONJ] SUBSET_TRANS)) THEN + REWRITE_TAC[AFFINE_HULL_INSERT_SUBSET_SPAN]; + ALL_TAC] THEN + ONCE_REWRITE_TAC[SIMPLE_IMAGE_GEN] THEN + DISCH_THEN(MP_TAC o ISPEC `\x:real^N. x - u` o MATCH_MP IMAGE_SUBSET) THEN + REWRITE_TAC[GSYM IMAGE_o; o_DEF; VECTOR_ADD_SUB; IMAGE_ID; SIMPLE_IMAGE] THEN + REWRITE_TAC[IMAGE_CLAUSES] THEN + MP_TAC(ISPECL [`{v - u:real^N,w - u}`; `2`] LOWDIM_EXPAND_BASIS) THEN + ANTS_TAC THENL + [ASM_REWRITE_TAC[] THEN MATCH_MP_TAC LE_TRANS THEN + EXISTS_TAC `CARD{v - u:real^N,w - u}` THEN + SIMP_TAC[DIM_LE_CARD; FINITE_INSERT; FINITE_RULES] THEN + SIMP_TAC[CARD_CLAUSES; FINITE_RULES] THEN ARITH_TAC; + ALL_TAC] THEN + DISCH_THEN(X_CHOOSE_THEN `t:real^N->bool` + (CONJUNCTS_THEN2 MP_TAC STRIP_ASSUME_TAC)) THEN + CONV_TAC(LAND_CONV HAS_SIZE_CONV) THEN + REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`a:real^N`; `b:real^N`] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC SUBST_ALL_TAC) THEN + UNDISCH_TAC `span {v - u, w - u} SUBSET span {a:real^N, b}` THEN + REWRITE_TAC[GSYM IMP_CONJ_ALT] THEN + DISCH_THEN(ASSUME_TAC o MATCH_MP SUBSET_TRANS) THEN + MAP_EVERY EXISTS_TAC [`u:real^N`; `u + a:real^N`; `u + b:real^N`] THEN + CONJ_TAC THENL + [REWRITE_TAC[COLLINEAR_3; COLLINEAR_LEMMA; + VECTOR_ARITH `--x = vec 0 <=> x = vec 0`; + VECTOR_ARITH `u - (u + a):real^N = --a`; + VECTOR_ARITH `(u + b) - (u + a):real^N = b - a`] THEN + REWRITE_TAC[DE_MORGAN_THM; VECTOR_SUB_EQ; + VECTOR_ARITH `b - a = c % -- a <=> (c - &1) % a + &1 % b = vec 0`] THEN + ASM_REWRITE_TAC[] THEN CONJ_TAC THENL + [ASM_MESON_TAC[IN_INSERT; INDEPENDENT_NONZERO]; ALL_TAC] THEN + DISCH_THEN(X_CHOOSE_TAC `u:real`) THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [independent]) THEN + REWRITE_TAC[DEPENDENT_EXPLICIT] THEN + MAP_EVERY EXISTS_TAC [`{a:real^N,b}`; + `\x:real^N. if x = a then u - &1 else &1`] THEN + REWRITE_TAC[FINITE_INSERT; FINITE_RULES; SUBSET_REFL] THEN + CONJ_TAC THENL + [EXISTS_TAC `b:real^N` THEN ASM_REWRITE_TAC[IN_INSERT] THEN + REAL_ARITH_TAC; + ALL_TAC] THEN + SIMP_TAC[VSUM_CLAUSES; FINITE_RULES] THEN + ASM_REWRITE_TAC[IN_INSERT; NOT_IN_EMPTY; VECTOR_ADD_RID]; + ALL_TAC] THEN + W(MP_TAC o PART_MATCH (lhs o rand) AFFINE_HULL_INSERT_SPAN o rand o snd) THEN + ANTS_TAC THENL + [REWRITE_TAC[IN_INSERT; NOT_IN_EMPTY] THEN + REWRITE_TAC[VECTOR_ARITH `u = u + a <=> a = vec 0`] THEN + ASM_MESON_TAC[INDEPENDENT_NONZERO; IN_INSERT]; + ALL_TAC] THEN + DISCH_THEN SUBST1_TAC THEN + FIRST_ASSUM(MP_TAC o ISPEC `\x:real^N. u + x` o MATCH_MP IMAGE_SUBSET) THEN + REWRITE_TAC[GSYM IMAGE_o; o_DEF; IMAGE_ID; + ONCE_REWRITE_RULE[VECTOR_ADD_SYM] VECTOR_SUB_ADD] THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] SUBSET_TRANS) THEN + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE] THEN + REWRITE_TAC[SIMPLE_IMAGE; IMAGE_CLAUSES; VECTOR_ADD_SUB] THEN + SET_TAC[]);; + +let COPLANAR_DET_EQ_0 = prove + (`!v0 v1 (v2: real^3) v3. + coplanar {v0,v1,v2,v3} <=> + det(vector[v1 - v0; v2 - v0; v3 - v0]) = &0`, + REPEAT GEN_TAC THEN REWRITE_TAC[DET_EQ_0_RANK; RANK_ROW] THEN + REWRITE_TAC[rows; row; LAMBDA_ETA] THEN + ONCE_REWRITE_TAC[SIMPLE_IMAGE_GEN] THEN + REWRITE_TAC[GSYM numseg; DIMINDEX_3] THEN + CONV_TAC(ONCE_DEPTH_CONV NUMSEG_CONV) THEN + SIMP_TAC[IMAGE_CLAUSES; coplanar; VECTOR_3] THEN EQ_TAC THENL + [REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`a:real^3`; `b:real^3`; `c:real^3`] THEN + W(MP_TAC o PART_MATCH lhand AFFINE_HULL_INSERT_SUBSET_SPAN o + rand o lhand o snd) THEN + REWRITE_TAC[GSYM IMP_CONJ_ALT] THEN + DISCH_THEN(MP_TAC o MATCH_MP SUBSET_TRANS) THEN + DISCH_THEN(MP_TAC o ISPEC `\x:real^3. x - a` o MATCH_MP IMAGE_SUBSET) THEN + ONCE_REWRITE_TAC[SIMPLE_IMAGE_GEN] THEN + REWRITE_TAC[IMAGE_CLAUSES; GSYM IMAGE_o; o_DEF; VECTOR_ADD_SUB; IMAGE_ID; + SIMPLE_IMAGE] THEN + REWRITE_TAC[INSERT_SUBSET] THEN STRIP_TAC THEN + GEN_REWRITE_TAC LAND_CONV [GSYM DIM_SPAN] THEN MATCH_MP_TAC LET_TRANS THEN + EXISTS_TAC `CARD {b - a:real^3,c - a}` THEN + CONJ_TAC THENL + [MATCH_MP_TAC SPAN_CARD_GE_DIM; + SIMP_TAC[CARD_CLAUSES; FINITE_RULES] THEN ARITH_TAC] THEN + REWRITE_TAC[FINITE_INSERT; FINITE_RULES] THEN + GEN_REWRITE_TAC RAND_CONV [GSYM SPAN_SPAN] THEN + MATCH_MP_TAC SPAN_MONO THEN REWRITE_TAC[INSERT_SUBSET; EMPTY_SUBSET] THEN + MP_TAC(VECTOR_ARITH `!x y:real^3. x - y = (x - a) - (y - a)`) THEN + DISCH_THEN(fun th -> REPEAT CONJ_TAC THEN + GEN_REWRITE_TAC LAND_CONV [th]) THEN + MATCH_MP_TAC SPAN_SUB THEN ASM_REWRITE_TAC[]; + DISCH_TAC THEN + MP_TAC(ISPECL [`{v1 - v0,v2 - v0,v3 - v0}:real^3->bool`; `2`] + LOWDIM_EXPAND_BASIS) THEN + ASM_REWRITE_TAC[ARITH_RULE `n <= 2 <=> n < 3`; DIMINDEX_3; ARITH] THEN + DISCH_THEN(X_CHOOSE_THEN `t:real^3->bool` + (CONJUNCTS_THEN2 MP_TAC STRIP_ASSUME_TAC)) THEN + CONV_TAC(LAND_CONV HAS_SIZE_CONV) THEN + REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`a:real^3`; `b:real^3`] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC SUBST_ALL_TAC) THEN + SIMP_TAC[COPLANAR; DIMINDEX_3; ARITH; plane] THEN + MAP_EVERY EXISTS_TAC [`v0:real^3`; `v0 + a:real^3`; `v0 + b:real^3`] THEN + W(MP_TAC o PART_MATCH (lhs o rand) AFFINE_HULL_INSERT_SPAN o + rand o snd) THEN + ANTS_TAC THENL + [REWRITE_TAC[IN_INSERT; NOT_IN_EMPTY] THEN + REWRITE_TAC[VECTOR_ARITH `u = u + a <=> a = vec 0`] THEN + ASM_MESON_TAC[INDEPENDENT_NONZERO; IN_INSERT]; + ALL_TAC] THEN + DISCH_THEN SUBST1_TAC THEN + ONCE_REWRITE_TAC[SIMPLE_IMAGE_GEN] THEN + REWRITE_TAC[SIMPLE_IMAGE; IMAGE_CLAUSES; IMAGE_ID; VECTOR_ADD_SUB] THEN + MATCH_MP_TAC SUBSET_TRANS THEN EXISTS_TAC + `IMAGE (\v:real^3. v0 + v) (span{v1 - v0, v2 - v0, v3 - v0})` THEN + ASM_SIMP_TAC[IMAGE_SUBSET] THEN + REWRITE_TAC[INSERT_SUBSET; EMPTY_SUBSET; IN_IMAGE] THEN CONJ_TAC THENL + [EXISTS_TAC `vec 0:real^3` THEN REWRITE_TAC[SPAN_0] THEN VECTOR_ARITH_TAC; + REWRITE_TAC[VECTOR_ARITH `v1:real^N = v0 + x <=> x = v1 - v0`] THEN + REWRITE_TAC[UNWIND_THM2] THEN REPEAT CONJ_TAC THEN + MATCH_MP_TAC SPAN_SUPERSET THEN REWRITE_TAC[IN_INSERT]]]);; + +let COPLANAR_CROSS_DOT = prove + (`!v w x y. coplanar {v,w,x,y} <=> ((w - v) cross (x - v)) dot (y - v) = &0`, + REWRITE_TAC[COPLANAR_DET_EQ_0; GSYM DOT_CROSS_DET] THEN + MESON_TAC[CROSS_TRIPLE; DOT_SYM]);; + +let PLANE_AFFINE_HULL_3 = prove + (`!a b c:real^N. plane(affine hull {a,b,c}) <=> ~collinear{a,b,c}`, + REWRITE_TAC[plane] THEN MESON_TAC[COLLINEAR_AFFINE_HULL_COLLINEAR]);; + +let AFFINE_HULL_3_GENERATED = prove + (`!s u v w:real^N. + s SUBSET affine hull {u,v,w} /\ ~collinear s + ==> affine hull {u,v,w} = affine hull s`, + REWRITE_TAC[COLLINEAR_AFF_DIM; INT_NOT_LE] THEN REPEAT STRIP_TAC THEN + CONV_TAC SYM_CONV THEN + GEN_REWRITE_TAC RAND_CONV [GSYM HULL_HULL] THEN + MATCH_MP_TAC AFF_DIM_EQ_AFFINE_HULL THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC INT_LE_TRANS THEN EXISTS_TAC `&2:int` THEN + CONJ_TAC THENL [ALL_TAC; ASM_INT_ARITH_TAC] THEN + REWRITE_TAC[AFF_DIM_AFFINE_HULL] THEN + W(MP_TAC o PART_MATCH (lhand o rand) AFF_DIM_LE_CARD o lhand o snd) THEN + REWRITE_TAC[FINITE_INSERT; FINITE_EMPTY] THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] INT_LE_TRANS) THEN + REWRITE_TAC[INT_LE_SUB_RADD; INT_OF_NUM_ADD; INT_OF_NUM_LE] THEN + SIMP_TAC[CARD_CLAUSES; FINITE_INSERT; FINITE_EMPTY] THEN ARITH_TAC);; + +(* ------------------------------------------------------------------------- *) +(* Additional WLOG tactic to rotate any plane p to {z | z$3 = &0}. *) +(* ------------------------------------------------------------------------- *) + +let GEOM_HORIZONTAL_PLANE_RULE = + let ifn = MATCH_MP + (TAUT `(p ==> (x <=> x')) /\ (~p ==> (x <=> T)) ==> (x' ==> x)`) + and pth = prove + (`!a f. orthogonal_transformation (f:real^N->real^N) + ==> ((!P. (!x. P x) <=> (!x. P (a + f x))) /\ + (!P. (?x. P x) <=> (?x. P (a + f x))) /\ + (!Q. (!s. Q s) <=> (!s. Q (IMAGE (\x. a + x) (IMAGE f s)))) /\ + (!Q. (?s. Q s) <=> (?s. Q (IMAGE (\x. a + x) (IMAGE f s))))) /\ + (!P. {x | P x} = + IMAGE (\x. a + x) (IMAGE f {x | P(a + f x)}))`, + REPEAT GEN_TAC THEN DISCH_TAC THEN + MP_TAC(ISPEC `(\x. a + x) o (f:real^N->real^N)` + QUANTIFY_SURJECTION_THM) THEN REWRITE_TAC[o_THM; IMAGE_o] THEN + DISCH_THEN MATCH_MP_TAC THEN + ASM_MESON_TAC[ORTHOGONAL_TRANSFORMATION_SURJECTIVE; + VECTOR_ARITH `a + (x - a:real^N) = x`]) + and cth = prove + (`!a f. {} = IMAGE (\x:real^3. a + x) (IMAGE f {})`, + REWRITE_TAC[IMAGE_CLAUSES]) + and oth = prove + (`!f:real^3->real^3. + orthogonal_transformation f /\ det(matrix f) = &1 + ==> linear f /\ + (!x y. f x = f y ==> x = y) /\ + (!y. ?x. f x = y) /\ + (!x. norm(f x) = norm x) /\ + (2 <= dimindex(:3) ==> det(matrix f) = &1)`, + GEN_TAC THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN REPEAT CONJ_TAC THENL + [ASM_SIMP_TAC[ORTHOGONAL_TRANSFORMATION_LINEAR]; + ASM_MESON_TAC[ORTHOGONAL_TRANSFORMATION_INJECTIVE]; + ASM_MESON_TAC[ORTHOGONAL_TRANSFORMATION_SURJECTIVE]; + ASM_MESON_TAC[ORTHOGONAL_TRANSFORMATION]]) + and fth = MESON[] + `(!a f. q a f ==> (p <=> p' a f)) + ==> ((?a f. q a f) ==> (p <=> !a f. q a f ==> p' a f))` in + fun tm -> + let x,bod = dest_forall tm in + let th1 = EXISTS_GENVAR_RULE + (UNDISCH(ISPEC x ROTATION_HORIZONTAL_PLANE)) in + let [a;f],tm1 = strip_exists(concl th1) in + let [th_orth;th_det;th_im] = CONJUNCTS(ASSUME tm1) in + let th2 = PROVE_HYP th_orth (UNDISCH(ISPECL [a;f] pth)) in + let th3 = (EXPAND_QUANTS_CONV(ASSUME(concl th2)) THENC + SUBS_CONV[GSYM th_im; ISPECL [a;f] cth]) bod in + let th4 = PROVE_HYP th2 th3 in + let th5 = TRANSLATION_INVARIANTS a in + let th6 = GEN_REWRITE_RULE (RAND_CONV o REDEPTH_CONV) + [ASSUME(concl th5)] th4 in + let th7 = PROVE_HYP th5 th6 in + let th8s = CONJUNCTS(MATCH_MP oth (CONJ th_orth th_det)) in + let th9 = LINEAR_INVARIANTS f th8s in + let th10 = GEN_REWRITE_RULE (RAND_CONV o REDEPTH_CONV) [th9] th7 in + let th11 = if intersect (frees(concl th10)) [a;f] = [] + then PROVE_HYP th1 (itlist SIMPLE_CHOOSE [a;f] th10) + else MP (MATCH_MP fth (GENL [a;f] (DISCH_ALL th10))) th1 in + let th12 = REWRITE_CONV[ASSUME(mk_neg(hd(hyp th11)))] bod in + let th13 = ifn(CONJ (DISCH_ALL th11) (DISCH_ALL th12)) in + let th14 = MATCH_MP MONO_FORALL (GEN x th13) in + GEN_REWRITE_RULE (TRY_CONV o LAND_CONV) [FORALL_SIMP] th14;; + +let GEOM_HORIZONTAL_PLANE_TAC p = + W(fun (asl,w) -> + let avs,bod = strip_forall w + and avs' = subtract (frees w) (freesl(map (concl o snd) asl)) in + let avs,bod = strip_forall w in + MAP_EVERY X_GEN_TAC avs THEN + MAP_EVERY (fun t -> SPEC_TAC(t,t)) (rev(subtract (avs@avs') [p])) THEN + SPEC_TAC(p,p) THEN + W(MATCH_MP_TAC o GEOM_HORIZONTAL_PLANE_RULE o snd));; + +(* ------------------------------------------------------------------------- *) +(* Affsign and its special cases, with invariance theorems. *) +(* ------------------------------------------------------------------------- *) + +let lin_combo = new_definition + `lin_combo V f = vsum V (\v. f v % (v:real^N))`;; + +let affsign = new_definition + `affsign sgn s t (v:real^A) <=> + (?f. (v = lin_combo (s UNION t) f) /\ + (!w. t w ==> sgn (f w)) /\ + (sum (s UNION t) f = &1))`;; + +let sgn_gt = new_definition `sgn_gt = (\t. (&0 < t))`;; +let sgn_ge = new_definition `sgn_ge = (\t. (&0 <= t))`;; +let sgn_lt = new_definition `sgn_lt = (\t. (t < &0))`;; +let sgn_le = new_definition `sgn_le = (\t. (t <= &0))`;; + +let aff_gt_def = new_definition `aff_gt = affsign sgn_gt`;; +let aff_ge_def = new_definition `aff_ge = affsign sgn_ge`;; +let aff_lt_def = new_definition `aff_lt = affsign sgn_lt`;; +let aff_le_def = new_definition `aff_le = affsign sgn_le`;; + +let AFFSIGN = prove + (`affsign sgn s t = + {y | ?f. y = vsum (s UNION t) (\v. f v % v) /\ + (!w. w IN t ==> sgn(f w)) /\ + sum (s UNION t) f = &1}`, + REWRITE_TAC[FUN_EQ_THM; affsign; lin_combo; IN_ELIM_THM] THEN + REWRITE_TAC[IN]);; + +let AFFSIGN_ALT = prove + (`affsign sgn s t = + {y | ?f. (!w. w IN (s UNION t) ==> w IN t ==> sgn(f w)) /\ + sum (s UNION t) f = &1 /\ + vsum (s UNION t) (\v. f v % v) = y}`, + REWRITE_TAC[SET_RULE `(w IN (s UNION t) ==> w IN t ==> P w) <=> + (w IN t ==> P w)`] THEN + REWRITE_TAC[AFFSIGN; EXTENSION; IN_ELIM_THM] THEN MESON_TAC[]);; + +let IN_AFFSIGN = prove + (`y IN affsign sgn s t <=> + ?u. (!x. x IN t ==> sgn(u x)) /\ + sum (s UNION t) u = &1 /\ + vsum (s UNION t) (\x. u(x) % x) = y`, + REWRITE_TAC[AFFSIGN; IN_ELIM_THM] THEN SET_TAC[]);; + +let AFFSIGN_DISJOINT_DIFF = prove + (`!s t. affsign sgn s t = affsign sgn (s DIFF t) t`, + REWRITE_TAC[AFFSIGN; SET_RULE `(s DIFF t) UNION t = s UNION t`]);; + +let AFF_GE_DISJOINT_DIFF = prove + (`!s t. aff_ge s t = aff_ge (s DIFF t) t`, + REWRITE_TAC[aff_ge_def] THEN MATCH_ACCEPT_TAC AFFSIGN_DISJOINT_DIFF);; + +let AFFSIGN_INJECTIVE_LINEAR_IMAGE = prove + (`!f:real^M->real^N sgn s t v. + linear f /\ (!x y. f x = f y ==> x = y) + ==> (affsign sgn (IMAGE f s) (IMAGE f t) = + IMAGE f (affsign sgn s t))`, + let lemma0 = prove + (`vsum s (\x. u x % x) = vsum {x | x IN s /\ ~(u x = &0)} (\x. u x % x)`, + MATCH_MP_TAC VSUM_SUPERSET THEN SIMP_TAC[SUBSET; IN_ELIM_THM] THEN + REWRITE_TAC[TAUT `p /\ ~(p /\ ~q) <=> p /\ q`] THEN + SIMP_TAC[o_THM; VECTOR_MUL_LZERO]) in + let lemma1 = prove + (`!f:real^M->real^N s. + linear f /\ (!x y. f x = f y ==> x = y) + ==> (sum(IMAGE f s) u = &1 /\ vsum(IMAGE f s) (\x. u x % x) = y <=> + sum s (u o f) = &1 /\ f(vsum s (\x. (u o f) x % x)) = y)`, + REPEAT STRIP_TAC THEN + W(MP_TAC o PART_MATCH (lhs o rand) SUM_IMAGE o funpow 3 lhand o snd) THEN + ANTS_TAC THENL [ASM_MESON_TAC[]; DISCH_THEN SUBST1_TAC] THEN + MATCH_MP_TAC(MESON[] `(p ==> z = x) ==> (p /\ x = y <=> p /\ z = y)`) THEN + DISCH_TAC THEN ONCE_REWRITE_TAC[lemma0] THEN + SUBGOAL_THEN + `{y | y IN IMAGE (f:real^M->real^N) s /\ ~(u y = &0)} = + IMAGE f {x | x IN s /\ ~(u(f x) = &0)}` + SUBST1_TAC THENL [ASM SET_TAC[]; CONV_TAC SYM_CONV] THEN + SUBGOAL_THEN `FINITE {x | x IN s /\ ~(u((f:real^M->real^N) x) = &0)}` + ASSUME_TAC THENL + [FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE + (LAND_CONV o RATOR_CONV o RATOR_CONV) [sum]) THEN + ONCE_REWRITE_TAC[ITERATE_EXPAND_CASES] THEN + REWRITE_TAC[GSYM sum; support; NEUTRAL_REAL_ADD; o_THM] THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[REAL_OF_NUM_EQ; ARITH_EQ]; + W(MP_TAC o PART_MATCH (lhs o rand) VSUM_IMAGE o lhand o snd) THEN + ANTS_TAC THENL [ASM_REWRITE_TAC[] THEN ASM_MESON_TAC[]; ALL_TAC] THEN + DISCH_THEN SUBST1_TAC THEN REWRITE_TAC[o_DEF] THEN + ASM_SIMP_TAC[LINEAR_VSUM; o_DEF; GSYM LINEAR_CMUL]]) in + REPEAT GEN_TAC THEN DISCH_TAC THEN REWRITE_TAC[EXTENSION; IN_AFFSIGN] THEN + REWRITE_TAC[FORALL_IN_IMAGE] THEN REWRITE_TAC[IN_IMAGE; IN_AFFSIGN] THEN + REWRITE_TAC[GSYM IMAGE_UNION] THEN + FIRST_ASSUM(fun th -> REWRITE_TAC[MATCH_MP lemma1 th]) THEN + X_GEN_TAC `y:real^N` THEN EQ_TAC THENL + [DISCH_THEN(X_CHOOSE_THEN `u:real^N->real` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `vsum (s UNION t) (\x. (u o (f:real^M->real^N)) x % x)` THEN + ASM_REWRITE_TAC[] THEN + EXISTS_TAC `(u:real^N->real) o (f:real^M->real^N)` THEN + ASM_REWRITE_TAC[] THEN ASM_REWRITE_TAC[o_THM]; + MP_TAC(ISPEC `f:real^M->real^N` LINEAR_INJECTIVE_LEFT_INVERSE) THEN + ASM_REWRITE_TAC[FUN_EQ_THM; o_THM; I_THM] THEN + DISCH_THEN(X_CHOOSE_THEN `g:real^N->real^M` STRIP_ASSUME_TAC) THEN + DISCH_THEN(X_CHOOSE_THEN `x:real^M` + (CONJUNCTS_THEN2 SUBST1_TAC MP_TAC)) THEN + DISCH_THEN(X_CHOOSE_THEN `u:real^M->real` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `(u:real^M->real) o (g:real^N->real^M)` THEN + ASM_REWRITE_TAC[o_DEF; ETA_AX]]);; + +let AFF_GE_INJECTIVE_LINEAR_IMAGE = prove + (`!f:real^M->real^N s t. + linear f /\ (!x y. f x = f y ==> x = y) + ==> aff_ge (IMAGE f s) (IMAGE f t) = IMAGE f (aff_ge s t)`, + REWRITE_TAC[aff_ge_def; AFFSIGN_INJECTIVE_LINEAR_IMAGE]);; + +let AFF_GT_INJECTIVE_LINEAR_IMAGE = prove + (`!f:real^M->real^N s t. + linear f /\ (!x y. f x = f y ==> x = y) + ==> aff_gt (IMAGE f s) (IMAGE f t) = IMAGE f (aff_gt s t)`, + REWRITE_TAC[aff_gt_def; AFFSIGN_INJECTIVE_LINEAR_IMAGE]);; + +let AFF_LE_INJECTIVE_LINEAR_IMAGE = prove + (`!f:real^M->real^N s t. + linear f /\ (!x y. f x = f y ==> x = y) + ==> aff_le (IMAGE f s) (IMAGE f t) = IMAGE f (aff_le s t)`, + REWRITE_TAC[aff_le_def; AFFSIGN_INJECTIVE_LINEAR_IMAGE]);; + +let AFF_LT_INJECTIVE_LINEAR_IMAGE = prove + (`!f:real^M->real^N s t. + linear f /\ (!x y. f x = f y ==> x = y) + ==> aff_lt (IMAGE f s) (IMAGE f t) = IMAGE f (aff_lt s t)`, + REWRITE_TAC[aff_lt_def; AFFSIGN_INJECTIVE_LINEAR_IMAGE]);; + +add_linear_invariants + [AFFSIGN_INJECTIVE_LINEAR_IMAGE; + AFF_GE_INJECTIVE_LINEAR_IMAGE; + AFF_GT_INJECTIVE_LINEAR_IMAGE; + AFF_LE_INJECTIVE_LINEAR_IMAGE; + AFF_LT_INJECTIVE_LINEAR_IMAGE];; + +let IN_AFFSIGN_TRANSLATION = prove + (`!sgn s t a v:real^N. + affsign sgn s t v + ==> affsign sgn (IMAGE (\x. a + x) s) (IMAGE (\x. a + x) t) (a + v)`, + REPEAT GEN_TAC THEN REWRITE_TAC[affsign; lin_combo] THEN + ONCE_REWRITE_TAC[SET_RULE `(!x. s x ==> p x) <=> (!x. x IN s ==> p x)`] THEN + DISCH_THEN(X_CHOOSE_THEN `f:real^N->real` + (CONJUNCTS_THEN2 SUBST_ALL_TAC STRIP_ASSUME_TAC)) THEN + EXISTS_TAC `\x. (f:real^N->real)(x - a)` THEN + ASM_REWRITE_TAC[GSYM IMAGE_UNION] THEN REPEAT CONJ_TAC THENL + [ALL_TAC; + ASM_REWRITE_TAC[FORALL_IN_IMAGE; ETA_AX; + VECTOR_ARITH `(a + x) - a:real^N = x`]; + W(MP_TAC o PART_MATCH (lhs o rand) SUM_IMAGE o lhs o snd) THEN + SIMP_TAC[VECTOR_ARITH `a + x:real^N = a + y <=> x = y`] THEN + ASM_REWRITE_TAC[o_DEF; VECTOR_ADD_SUB; ETA_AX]] THEN + MATCH_MP_TAC EQ_TRANS THEN EXISTS_TAC + `a + vsum {x | x IN s UNION t /\ ~(f x = &0)} (\v:real^N. f v % v)` THEN + CONJ_TAC THENL + [AP_TERM_TAC THEN MATCH_MP_TAC VSUM_SUPERSET THEN + REWRITE_TAC[VECTOR_MUL_EQ_0; SUBSET; IN_ELIM_THM] THEN MESON_TAC[]; + ALL_TAC] THEN + MATCH_MP_TAC EQ_TRANS THEN + EXISTS_TAC `vsum (IMAGE (\x:real^N. a + x) + {x | x IN s UNION t /\ ~(f x = &0)}) + (\v. f(v - a) % v)` THEN + CONJ_TAC THENL + [ALL_TAC; + CONV_TAC SYM_CONV THEN MATCH_MP_TAC VSUM_SUPERSET THEN + CONJ_TAC THENL [SET_TAC[]; ALL_TAC] THEN + ASM_REWRITE_TAC[IMP_CONJ; FORALL_IN_IMAGE; VECTOR_MUL_EQ_0] THEN + REWRITE_TAC[VECTOR_ADD_SUB] THEN SET_TAC[]] THEN + SUBGOAL_THEN `FINITE {x:real^N | x IN s UNION t /\ ~(f x = &0)}` + ASSUME_TAC THENL + [FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE + (LAND_CONV o RATOR_CONV o RATOR_CONV) [sum]) THEN + ONCE_REWRITE_TAC[ITERATE_EXPAND_CASES] THEN + REWRITE_TAC[GSYM sum; support; NEUTRAL_REAL_ADD] THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[REAL_OF_NUM_EQ; ARITH_EQ]; + ALL_TAC] THEN + W(MP_TAC o PART_MATCH (lhs o rand) VSUM_IMAGE o rhs o snd) THEN + ASM_SIMP_TAC[VECTOR_ARITH `a + x:real^N = a + y <=> x = y`] THEN + DISCH_THEN(K ALL_TAC) THEN REWRITE_TAC[o_DEF; VECTOR_ADD_SUB] THEN + ASM_SIMP_TAC[VECTOR_ADD_LDISTRIB; VSUM_ADD] THEN + AP_THM_TAC THEN AP_TERM_TAC THEN REWRITE_TAC[VSUM_RMUL] THEN + GEN_REWRITE_TAC LAND_CONV [GSYM VECTOR_MUL_LID] THEN + AP_THM_TAC THEN AP_TERM_TAC THEN FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN + MATCH_MP_TAC SUM_SUPERSET THEN SET_TAC[]);; + +let AFFSIGN_TRANSLATION = prove + (`!a:real^N sgn s t. + affsign sgn (IMAGE (\x. a + x) s) (IMAGE (\x. a + x) t) = + IMAGE (\x. a + x) (affsign sgn s t)`, + REPEAT GEN_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL + [REWRITE_TAC[SUBSET; IN] THEN GEN_TAC THEN + DISCH_THEN(MP_TAC o SPEC `--a:real^N` o + MATCH_MP IN_AFFSIGN_TRANSLATION) THEN + REWRITE_TAC[GSYM IMAGE_o; o_DEF; VECTOR_ARITH `--a + a + x:real^N = x`; + IMAGE_ID] THEN + DISCH_TAC THEN REWRITE_TAC[IMAGE; IN_ELIM_THM] THEN + EXISTS_TAC `--a + x:real^N` THEN ASM_REWRITE_TAC[IN] THEN VECTOR_ARITH_TAC; + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE] THEN GEN_TAC THEN REWRITE_TAC[IN] THEN + DISCH_THEN(MP_TAC o SPEC `a:real^N` o MATCH_MP IN_AFFSIGN_TRANSLATION) THEN + REWRITE_TAC[]]);; + +let AFF_GE_TRANSLATION = prove + (`!a:real^N s t. + aff_ge (IMAGE (\x. a + x) s) (IMAGE (\x. a + x) t) = + IMAGE (\x. a + x) (aff_ge s t)`, + REWRITE_TAC[aff_ge_def; AFFSIGN_TRANSLATION]);; + +let AFF_GT_TRANSLATION = prove + (`!a:real^N s t. + aff_gt (IMAGE (\x. a + x) s) (IMAGE (\x. a + x) t) = + IMAGE (\x. a + x) (aff_gt s t)`, + REWRITE_TAC[aff_gt_def; AFFSIGN_TRANSLATION]);; + +let AFF_LE_TRANSLATION = prove + (`!a:real^N s t. + aff_le (IMAGE (\x. a + x) s) (IMAGE (\x. a + x) t) = + IMAGE (\x. a + x) (aff_le s t)`, + REWRITE_TAC[aff_le_def; AFFSIGN_TRANSLATION]);; + +let AFF_LT_TRANSLATION = prove + (`!a:real^N s t. + aff_lt (IMAGE (\x. a + x) s) (IMAGE (\x. a + x) t) = + IMAGE (\x. a + x) (aff_lt s t)`, + REWRITE_TAC[aff_lt_def; AFFSIGN_TRANSLATION]);; + +add_translation_invariants + [AFFSIGN_TRANSLATION; + AFF_GE_TRANSLATION; + AFF_GT_TRANSLATION; + AFF_LE_TRANSLATION; + AFF_LT_TRANSLATION];; + +(* ------------------------------------------------------------------------- *) +(* Automate special cases of affsign. *) +(* ------------------------------------------------------------------------- *) + +let AFF_TAC = + REWRITE_TAC[DISJOINT_INSERT; DISJOINT_EMPTY] THEN + REWRITE_TAC[IN_INSERT; NOT_IN_EMPTY; DE_MORGAN_THM] THEN + REPEAT STRIP_TAC THEN + REWRITE_TAC[aff_ge_def; aff_gt_def; aff_le_def; aff_lt_def; + sgn_ge; sgn_gt; sgn_le; sgn_lt; AFFSIGN_ALT] THEN + REWRITE_TAC[SET_RULE `(x INSERT s) UNION t = x INSERT (s UNION t)`] THEN + REWRITE_TAC[UNION_EMPTY] THEN + SIMP_TAC[FINITE_INSERT; FINITE_UNION; AFFINE_HULL_FINITE_STEP_GEN; + FINITE_EMPTY; RIGHT_EXISTS_AND_THM; REAL_LT_ADD; + REAL_LE_ADD; REAL_ARITH `&0 <= a / &2 <=> &0 <= a`; + REAL_ARITH `&0 < a / &2 <=> &0 < a`; + REAL_ARITH `a / &2 <= &0 <=> a <= &0`; + REAL_ARITH `a / &2 < &0 <=> a < &0`; + REAL_ARITH `a < &0 /\ b < &0 ==> a + b < &0`; + REAL_ARITH `a < &0 /\ b <= &0 ==> a + b <= &0`] THEN + ASM_REWRITE_TAC[IN_INSERT; NOT_IN_EMPTY; real_ge] THEN + REWRITE_TAC[REAL_ARITH `x - y:real = z <=> x = y + z`; + VECTOR_ARITH `x - y:real^N = z <=> x = y + z`] THEN + REWRITE_TAC[RIGHT_AND_EXISTS_THM; REAL_ADD_RID; VECTOR_ADD_RID] THEN + ONCE_REWRITE_TAC[REAL_ARITH `&1 = x <=> x = &1`] THEN + REWRITE_TAC[] THEN SET_TAC[];; + +let AFF_GE_1_1 = prove + (`!x v w. + DISJOINT {x} {v} + ==> aff_ge {x} {v} = + {y | ?t1 t2. + &0 <= t2 /\ + t1 + t2 = &1 /\ + y = t1 % x + t2 % v }`, + AFF_TAC);; + +let AFF_GE_1_2 = prove + (`!x v w. + DISJOINT {x} {v,w} + ==> aff_ge {x} {v,w} = + {y | ?t1 t2 t3. + + &0 <= t2 /\ &0 <= t3 /\ + + t1 + t2 + t3 = &1 /\ + y = t1 % x + t2 % v + t3 % w}`, + AFF_TAC);; + +let AFF_GE_2_1 = prove + (`!x v w. + DISJOINT {x,v} {w} + ==> aff_ge {x,v} {w} = + {y | ?t1 t2 t3. + &0 <= t3 /\ + t1 + t2 + t3 = &1 /\ + y = t1 % x + t2 % v + t3 % w}`, + AFF_TAC);; + +let AFF_GT_1_1 = prove + (`!x v w. + DISJOINT {x} {v} + ==> aff_gt {x} {v} = + {y | ?t1 t2. + &0 < t2 /\ + t1 + t2 = &1 /\ + y = t1 % x + t2 % v}`, + AFF_TAC);; + +let AFF_GT_1_2 = prove + (`!x v w. + DISJOINT {x} {v,w} + ==> aff_gt {x} {v,w} = + {y | ?t1 t2 t3. + &0 < t2 /\ &0 < t3 /\ + t1 + t2 + t3 = &1 /\ + y = t1 % x + t2 % v + t3 % w}`, + AFF_TAC);; + +let AFF_GT_2_1 = prove + (`!x v w. + DISJOINT {x,v} {w} + ==> aff_gt {x,v} {w} = + {y | ?t1 t2 t3. + &0 < t3 /\ + t1 + t2 + t3 = &1 /\ + y = t1 % x + t2 % v + t3 % w}`, + AFF_TAC);; + +let AFF_GT_3_1 = prove + (`!v w x y. + DISJOINT {v,w,x} {y} + ==> aff_gt {v,w,x} {y} = + {z | ?t1 t2 t3 t4. + &0 < t4 /\ + t1 + t2 + t3 + t4 = &1 /\ + z = t1 % v + t2 % w + t3 % x + t4 % y}`, + AFF_TAC);; + +let AFF_LT_1_1 = prove + (`!x v. + DISJOINT {x} {v} + ==> aff_lt {x} {v} = + {y | ?t1 t2. + t2 < &0 /\ + t1 + t2 = &1 /\ + y = t1 % x + t2 % v}`, + AFF_TAC);; + +let AFF_LT_2_1 = prove + (`!x v w. + DISJOINT {x,v} {w} + ==> aff_lt {x,v} {w} = + {y | ?t1 t2 t3. + t3 < &0 /\ + t1 + t2 + t3 = &1 /\ + y = t1 % x + t2 % v + t3 % w}`, + AFF_TAC);; + +let AFF_GE_1_2_0 = prove + (`!v w. + ~(v = vec 0) /\ ~(w = vec 0) + ==> aff_ge {vec 0} {v,w} = {a % v + b % w | &0 <= a /\ &0 <= b}`, + SIMP_TAC[AFF_GE_1_2; + SET_RULE `DISJOINT {a} {b,c} <=> ~(b = a) /\ ~(c = a)`] THEN + REWRITE_TAC[VECTOR_MUL_RZERO; VECTOR_ADD_LID] THEN + ONCE_REWRITE_TAC[MESON[] + `(?a b c. P b c /\ Q b c /\ R a b c /\ S b c) <=> + (?b c. P b c /\ Q b c /\ S b c /\ ?a. R a b c)`] THEN + REWRITE_TAC[REAL_ARITH `t + s:real = &1 <=> t = &1 - s`; EXISTS_REFL] THEN + SET_TAC[]);; + +let AFF_GE_1_1_0 = prove + (`!v. ~(v = vec 0) ==> aff_ge {vec 0} {v} = {a % v | &0 <= a}`, + REPEAT STRIP_TAC THEN + GEN_REWRITE_TAC (LAND_CONV o RAND_CONV) [SET_RULE `{a} = {a,a}`] THEN + ASM_SIMP_TAC[AFF_GE_1_2_0; GSYM VECTOR_ADD_RDISTRIB] THEN + REWRITE_TAC[EXTENSION; IN_ELIM_THM] THEN + MESON_TAC[REAL_LE_ADD; REAL_ARITH + `&0 <= a ==> &0 <= a / &2 /\ a / &2 + a / &2 = a`]);; + +let AFF_GE_2_1_0 = prove + (`!v w. DISJOINT {vec 0, v} {w} + ==> aff_ge {vec 0, v} {w} = {s % v + t % w |s,t| &0 <= t}`, + SIMP_TAC[AFF_GE_2_1; VECTOR_MUL_RZERO; VECTOR_ADD_LID] THEN + REPEAT STRIP_TAC THEN + ONCE_REWRITE_TAC[TAUT `p /\ q /\ r <=> q /\ p /\ r`] THEN + ONCE_REWRITE_TAC[MESON[] `(?a b c. P a b c) <=> (?c b a. P a b c)`] THEN + REWRITE_TAC[REAL_ARITH `t + u = &1 <=> t = &1 - u`; UNWIND_THM2] THEN + SET_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* Properties of affsign variants. *) +(* ------------------------------------------------------------------------- *) + +let CONVEX_AFFSIGN = prove + (`!sgn. (!x y u. sgn(x) /\ sgn(y) /\ &0 <= u /\ u <= &1 + ==> sgn((&1 - u) * x + u * y)) + ==> !s t:real^N->bool. convex(affsign sgn s t)`, + REPEAT STRIP_TAC THEN REWRITE_TAC[AFFSIGN; CONVEX_ALT] THEN + MAP_EVERY X_GEN_TAC [`x:real^N`; `y:real^N`; `u:real`] THEN + REWRITE_TAC[IN_ELIM_THM; IMP_CONJ; LEFT_IMP_EXISTS_THM] THEN + REWRITE_TAC[IMP_IMP; GSYM CONJ_ASSOC] THEN + X_GEN_TAC `f:real^N->real` THEN STRIP_TAC THEN + X_GEN_TAC `g:real^N->real` THEN STRIP_TAC THEN + EXISTS_TAC `\x:real^N. (&1 - u) * f x + u * g x` THEN + ASM_REWRITE_TAC[VECTOR_ADD_RDISTRIB] THEN REPEAT CONJ_TAC THENL + [CONV_TAC SYM_CONV THEN + W(MP_TAC o PART_MATCH (lhs o rand) VSUM_ADD_GEN o lhand o snd) THEN + REWRITE_TAC[GSYM VECTOR_MUL_ASSOC; VSUM_LMUL] THEN + DISCH_THEN MATCH_MP_TAC; + ASM_MESON_TAC[]; + W(MP_TAC o PART_MATCH (lhs o rand) SUM_ADD_GEN o lhand o snd) THEN + ASM_REWRITE_TAC[GSYM VECTOR_MUL_ASSOC; SUM_LMUL] THEN + REWRITE_TAC[REAL_MUL_RID; REAL_SUB_ADD] THEN DISCH_THEN MATCH_MP_TAC] THEN + (CONJ_TAC THENL + [MP_TAC(ASSUME `sum (s UNION t:real^N->bool) f = &1`); + MP_TAC(ASSUME `sum (s UNION t:real^N->bool) g = &1`)]) THEN + GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [sum] THEN + ONCE_REWRITE_TAC[iterate] THEN + REWRITE_TAC[support; NEUTRAL_REAL_ADD] THEN + COND_CASES_TAC THEN REWRITE_TAC[REAL_OF_NUM_EQ; ARITH_EQ] THEN + DISCH_THEN(K ALL_TAC) THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP + (REWRITE_RULE[IMP_CONJ] FINITE_SUBSET)) THEN + REWRITE_TAC[SUBSET; IN_ELIM_THM] THEN GEN_TAC THEN + MATCH_MP_TAC MONO_AND THEN REWRITE_TAC[CONTRAPOS_THM] THEN + DISCH_THEN SUBST1_TAC THEN + REWRITE_TAC[VECTOR_MUL_LZERO; VECTOR_MUL_RZERO; REAL_MUL_RZERO]);; + +let CONVEX_AFF_GE = prove + (`!s t. convex(aff_ge s t)`, + REWRITE_TAC[aff_ge_def; sgn_ge] THEN MATCH_MP_TAC CONVEX_AFFSIGN THEN + SIMP_TAC[REAL_LE_MUL; REAL_LE_ADD; REAL_SUB_LE]);; + +let CONVEX_AFF_LE = prove + (`!s t. convex(aff_le s t)`, + REWRITE_TAC[aff_le_def; sgn_le] THEN MATCH_MP_TAC CONVEX_AFFSIGN THEN + REWRITE_TAC[REAL_ARITH `x <= &0 <=> &0 <= --x`; REAL_NEG_ADD; GSYM + REAL_MUL_RNEG] THEN + SIMP_TAC[REAL_LE_MUL; REAL_LE_ADD; REAL_SUB_LE]);; + +let CONVEX_AFF_GT = prove + (`!s t. convex(aff_gt s t)`, + REWRITE_TAC[aff_gt_def; sgn_gt] THEN MATCH_MP_TAC CONVEX_AFFSIGN THEN + REWRITE_TAC[REAL_ARITH `&0 <= x <=> x = &0 \/ &0 < x`; + REAL_ARITH `x <= &1 <=> x = &1 \/ x < &1`] THEN + REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN + REWRITE_TAC[REAL_MUL_LZERO; REAL_ADD_LID; REAL_ADD_RID; REAL_MUL_LID] THEN + ASM_SIMP_TAC[REAL_LT_ADD; REAL_LT_MUL; REAL_SUB_LT]);; + +let CONVEX_AFF_LT = prove + (`!s t. convex(aff_lt s t)`, + REWRITE_TAC[aff_lt_def; sgn_lt] THEN MATCH_MP_TAC CONVEX_AFFSIGN THEN + REWRITE_TAC[REAL_ARITH `x < &0 <=> &0 < --x`; REAL_NEG_ADD; GSYM + REAL_MUL_RNEG] THEN + REWRITE_TAC[REAL_ARITH `&0 <= x <=> x = &0 \/ &0 < x`; + REAL_ARITH `x <= &1 <=> x = &1 \/ x < &1`] THEN + REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN + REWRITE_TAC[REAL_MUL_LZERO; REAL_ADD_LID; REAL_ADD_RID; REAL_MUL_LID] THEN + ASM_SIMP_TAC[REAL_LT_ADD; REAL_LT_MUL; REAL_SUB_LT]);; + +let AFFSIGN_SUBSET_AFFINE_HULL = prove + (`!sgn s t. (affsign sgn s t) SUBSET (affine hull (s UNION t))`, + REWRITE_TAC[AFFINE_HULL_FINITE; AFFSIGN] THEN SET_TAC[]);; + +let AFF_GE_SUBSET_AFFINE_HULL = prove + (`!s t. (aff_ge s t) SUBSET (affine hull (s UNION t))`, + REWRITE_TAC[aff_ge_def; AFFSIGN_SUBSET_AFFINE_HULL]);; + +let AFF_LE_SUBSET_AFFINE_HULL = prove + (`!s t. (aff_le s t) SUBSET (affine hull (s UNION t))`, + REWRITE_TAC[aff_le_def; AFFSIGN_SUBSET_AFFINE_HULL]);; + +let AFF_GT_SUBSET_AFFINE_HULL = prove + (`!s t. (aff_gt s t) SUBSET (affine hull (s UNION t))`, + REWRITE_TAC[aff_gt_def; AFFSIGN_SUBSET_AFFINE_HULL]);; + +let AFF_LT_SUBSET_AFFINE_HULL = prove + (`!s t. (aff_lt s t) SUBSET (affine hull (s UNION t))`, + REWRITE_TAC[aff_lt_def; AFFSIGN_SUBSET_AFFINE_HULL]);; + +let AFFSIGN_EQ_AFFINE_HULL = prove + (`!sgn s t. affsign sgn s {} = affine hull s`, + REWRITE_TAC[AFFSIGN; AFFINE_HULL_FINITE] THEN + REWRITE_TAC[UNION_EMPTY; NOT_IN_EMPTY] THEN SET_TAC[]);; + +let AFF_GE_EQ_AFFINE_HULL = prove + (`!s t. aff_ge s {} = affine hull s`, + REWRITE_TAC[aff_ge_def; AFFSIGN_EQ_AFFINE_HULL]);; + +let AFF_LE_EQ_AFFINE_HULL = prove + (`!s t. aff_le s {} = affine hull s`, + REWRITE_TAC[aff_le_def; AFFSIGN_EQ_AFFINE_HULL]);; + +let AFF_GT_EQ_AFFINE_HULL = prove + (`!s t. aff_gt s {} = affine hull s`, + REWRITE_TAC[aff_gt_def; AFFSIGN_EQ_AFFINE_HULL]);; + +let AFF_LT_EQ_AFFINE_HULL = prove + (`!s t. aff_lt s {} = affine hull s`, + REWRITE_TAC[aff_lt_def; AFFSIGN_EQ_AFFINE_HULL]);; + +let AFFSIGN_SUBSET_AFFSIGN = prove + (`!sgn1 sgn2 s t. + (!x. sgn1 x ==> sgn2 x) ==> affsign sgn1 s t SUBSET affsign sgn2 s t`, + REPEAT STRIP_TAC THEN REWRITE_TAC[AFFSIGN; SUBSET; IN_ELIM_THM] THEN + GEN_TAC THEN MATCH_MP_TAC MONO_EXISTS THEN ASM_MESON_TAC[]);; + +let AFF_GT_SUBSET_AFF_GE = prove + (`!s t. aff_gt s t SUBSET aff_ge s t`, + REPEAT GEN_TAC THEN REWRITE_TAC[aff_gt_def; aff_ge_def] THEN + MATCH_MP_TAC AFFSIGN_SUBSET_AFFSIGN THEN + SIMP_TAC[sgn_gt; sgn_ge; REAL_LT_IMP_LE]);; + +let AFFSIGN_MONO_LEFT = prove + (`!sgn s s' t:real^N->bool. + s SUBSET s' ==> affsign sgn s t SUBSET affsign sgn s' t`, + REPEAT STRIP_TAC THEN + REWRITE_TAC[AFFSIGN; SUBSET; IN_ELIM_THM] THEN + X_GEN_TAC `y:real^N` THEN + DISCH_THEN(X_CHOOSE_THEN `u:real^N->real` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `\x:real^N. if x IN s UNION t then u x else &0` THEN + REWRITE_TAC[COND_RAND; COND_RATOR; VECTOR_MUL_LZERO] THEN + REWRITE_TAC[GSYM SUM_RESTRICT_SET; GSYM VSUM_RESTRICT_SET] THEN + ASM_SIMP_TAC[SET_RULE + `s SUBSET s' ==> {x | x IN s' UNION t /\ x IN s UNION t} = s UNION t`] THEN + ASM SET_TAC[]);; + +let AFFSIGN_MONO_SHUFFLE = prove + (`!sgn s t s' t'. + s' UNION t' = s UNION t /\ t' SUBSET t + ==> affsign sgn s t SUBSET affsign sgn s' t'`, + REPEAT STRIP_TAC THEN REWRITE_TAC[AFFSIGN; SUBSET; IN_ELIM_THM] THEN + GEN_TAC THEN MATCH_MP_TAC MONO_EXISTS THEN + ASM_REWRITE_TAC[] THEN ASM SET_TAC[]);; + +let AFF_GT_MONO_LEFT = prove + (`!s s' t. s SUBSET s' ==> aff_gt s t SUBSET aff_gt s' t`, + REWRITE_TAC[aff_gt_def; AFFSIGN_MONO_LEFT]);; + +let AFF_GE_MONO_LEFT = prove + (`!s s' t. s SUBSET s' ==> aff_ge s t SUBSET aff_ge s' t`, + REWRITE_TAC[aff_ge_def; AFFSIGN_MONO_LEFT]);; + +let AFF_LT_MONO_LEFT = prove + (`!s s' t. s SUBSET s' ==> aff_lt s t SUBSET aff_lt s' t`, + REWRITE_TAC[aff_lt_def; AFFSIGN_MONO_LEFT]);; + +let AFF_LE_MONO_LEFT = prove + (`!s s' t. s SUBSET s' ==> aff_le s t SUBSET aff_le s' t`, + REWRITE_TAC[aff_le_def; AFFSIGN_MONO_LEFT]);; + +let AFFSIGN_MONO_RIGHT = prove + (`!sgn s t t':real^N->bool. + sgn(&0) /\ t SUBSET t' /\ DISJOINT s t' + ==> affsign sgn s t SUBSET affsign sgn s t'`, + REPEAT STRIP_TAC THEN + REWRITE_TAC[AFFSIGN; SUBSET; IN_ELIM_THM] THEN + X_GEN_TAC `y:real^N` THEN + DISCH_THEN(X_CHOOSE_THEN `u:real^N->real` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `\x:real^N. if x IN s UNION t then u x else &0` THEN + REWRITE_TAC[COND_RAND; COND_RATOR; VECTOR_MUL_LZERO] THEN + REWRITE_TAC[GSYM SUM_RESTRICT_SET; GSYM VSUM_RESTRICT_SET] THEN + ASM_SIMP_TAC[SET_RULE + `t SUBSET t' ==> {x | x IN s UNION t' /\ x IN s UNION t} = s UNION t`] THEN + ASM SET_TAC[]);; + +let AFF_GE_MONO_RIGHT = prove + (`!s t t'. t SUBSET t' /\ DISJOINT s t' ==> aff_ge s t SUBSET aff_ge s t'`, + SIMP_TAC[aff_ge_def; AFFSIGN_MONO_RIGHT; sgn_ge; REAL_POS]);; + +let AFF_LE_MONO_RIGHT = prove + (`!s t t'. t SUBSET t' /\ DISJOINT s t' ==> aff_le s t SUBSET aff_le s t'`, + SIMP_TAC[aff_le_def; AFFSIGN_MONO_RIGHT; sgn_le; REAL_LE_REFL]);; + +let AFFINE_HULL_SUBSET_AFFSIGN = prove + (`!sgn s t:real^N->bool. + sgn(&0) /\ DISJOINT s t + ==> affine hull s SUBSET affsign sgn s t`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC SUBSET_TRANS THEN + EXISTS_TAC `affsign sgn (s:real^N->bool) {}` THEN CONJ_TAC THENL + [REWRITE_TAC[AFFSIGN_EQ_AFFINE_HULL; SUBSET_REFL]; + MATCH_MP_TAC AFFSIGN_MONO_RIGHT THEN ASM SET_TAC[]]);; + +let AFFINE_HULL_SUBSET_AFF_GE = prove + (`!s t. DISJOINT s t ==> affine hull s SUBSET aff_ge s t`, + SIMP_TAC[aff_ge_def; sgn_ge; REAL_LE_REFL; AFFINE_HULL_SUBSET_AFFSIGN]);; + +let AFF_GE_AFF_GT_DECOMP = prove + (`!s:real^N->bool. + FINITE s /\ FINITE t /\ DISJOINT s t + ==> aff_ge s t = aff_gt s t UNION + UNIONS {aff_ge s (t DELETE a) | a | a IN t}`, + REPEAT STRIP_TAC THEN + MATCH_MP_TAC(SET_RULE + `t' SUBSET t /\ (!a. a IN s ==> f(a) SUBSET t) /\ + (!y. y IN t ==> y IN t' \/ ?a. a IN s /\ y IN f(a)) + ==> t = t' UNION UNIONS {f a | a IN s}`) THEN + REWRITE_TAC[AFF_GT_SUBSET_AFF_GE] THEN + ASM_SIMP_TAC[DELETE_SUBSET; AFF_GE_MONO_RIGHT] THEN + REWRITE_TAC[aff_ge_def; aff_gt_def; AFFSIGN; sgn_ge; sgn_gt] THEN + X_GEN_TAC `y:real^N` THEN REWRITE_TAC[IN_ELIM_THM] THEN + DISCH_THEN(X_CHOOSE_THEN `u:real^N->real` STRIP_ASSUME_TAC) THEN + ASM_CASES_TAC `!x:real^N. x IN t ==> &0 < u x` THENL + [DISJ1_TAC THEN EXISTS_TAC `u:real^N->real` THEN ASM_REWRITE_TAC[]; + DISJ2_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [NOT_FORALL_THM]) THEN + ASM_SIMP_TAC[REAL_ARITH `&0 <= x ==> (&0 < x <=> ~(x = &0))`] THEN + REWRITE_TAC[NOT_IMP] THEN MATCH_MP_TAC MONO_EXISTS THEN + X_GEN_TAC `a:real^N` THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + EXISTS_TAC `u:real^N->real` THEN + ASM_SIMP_TAC[SET_RULE + `a IN t /\ DISJOINT s t + ==> s UNION (t DELETE a) = (s UNION t) DELETE a`] THEN + ASM_SIMP_TAC[IN_DELETE; SUM_DELETE; VSUM_DELETE; REAL_SUB_RZERO; + FINITE_UNION; IN_UNION] THEN + REWRITE_TAC[VECTOR_MUL_LZERO; VECTOR_SUB_RZERO]]);; + +let AFFSIGN_SPECIAL_SCALE = prove + (`!sgn s t a v. + FINITE s /\ FINITE t /\ + ~(vec 0 IN t) /\ ~(v IN t) /\ ~((a % v) IN t) /\ + (!x. sgn x ==> sgn(x / &2)) /\ + (!x y. sgn x /\ sgn y ==> sgn(x + y)) /\ + &0 < a + ==> affsign sgn (vec 0 INSERT (a % v) INSERT s) t = + affsign sgn (vec 0 INSERT v INSERT s) t`, + REWRITE_TAC[EXTENSION] THEN REPEAT STRIP_TAC THEN + REWRITE_TAC[AFFSIGN_ALT; IN_ELIM_THM; INSERT_UNION_EQ] THEN + ASM_SIMP_TAC[FINITE_INSERT; FINITE_UNION; AFFINE_HULL_FINITE_STEP_GEN; + RIGHT_EXISTS_AND_THM] THEN + REWRITE_TAC[VECTOR_MUL_RZERO; VECTOR_SUB_RZERO] THEN + GEN_REWRITE_TAC BINOP_CONV [SWAP_EXISTS_THM] THEN + GEN_REWRITE_TAC (BINOP_CONV o BINDER_CONV) [SWAP_EXISTS_THM] THEN + REWRITE_TAC[LEFT_EXISTS_AND_THM; RIGHT_EXISTS_AND_THM] THEN + REWRITE_TAC[REAL_ARITH `x = &1 - v - v' <=> v = &1 - (x + v')`] THEN + REWRITE_TAC[EXISTS_REFL] THEN + FIRST_ASSUM(MP_TAC o MATCH_MP(MESON[REAL_LT_IMP_NZ; REAL_DIV_LMUL] + `!a. &0 < a ==> (!y. ?x. a * x = y)`)) THEN + DISCH_THEN(MP_TAC o MATCH_MP QUANTIFY_SURJECTION_THM) THEN + DISCH_THEN(CONV_TAC o RAND_CONV o EXPAND_QUANTS_CONV) THEN + REWRITE_TAC[VECTOR_MUL_ASSOC; REAL_MUL_SYM]);; + +let AFF_GE_SPECIAL_SCALE = prove + (`!s t a v. + FINITE s /\ FINITE t /\ + ~(vec 0 IN t) /\ ~(v IN t) /\ ~((a % v) IN t) /\ + &0 < a + ==> aff_ge (vec 0 INSERT (a % v) INSERT s) t = + aff_ge (vec 0 INSERT v INSERT s) t`, + REPEAT STRIP_TAC THEN REWRITE_TAC[aff_ge_def] THEN + MATCH_MP_TAC AFFSIGN_SPECIAL_SCALE THEN + ASM_REWRITE_TAC[sgn_ge] THEN REAL_ARITH_TAC);; + +let AFF_LE_SPECIAL_SCALE = prove + (`!s t a v. + FINITE s /\ FINITE t /\ + ~(vec 0 IN t) /\ ~(v IN t) /\ ~((a % v) IN t) /\ + &0 < a + ==> aff_le (vec 0 INSERT (a % v) INSERT s) t = + aff_le (vec 0 INSERT v INSERT s) t`, + REPEAT STRIP_TAC THEN REWRITE_TAC[aff_le_def] THEN + MATCH_MP_TAC AFFSIGN_SPECIAL_SCALE THEN + ASM_REWRITE_TAC[sgn_le] THEN REAL_ARITH_TAC);; + +let AFF_GT_SPECIAL_SCALE = prove + (`!s t a v. + FINITE s /\ FINITE t /\ + ~(vec 0 IN t) /\ ~(v IN t) /\ ~((a % v) IN t) /\ + &0 < a + ==> aff_gt (vec 0 INSERT (a % v) INSERT s) t = + aff_gt (vec 0 INSERT v INSERT s) t`, + REPEAT STRIP_TAC THEN REWRITE_TAC[aff_gt_def] THEN + MATCH_MP_TAC AFFSIGN_SPECIAL_SCALE THEN + ASM_REWRITE_TAC[sgn_gt] THEN REAL_ARITH_TAC);; + +let AFF_LT_SPECIAL_SCALE = prove + (`!s t a v. + FINITE s /\ FINITE t /\ + ~(vec 0 IN t) /\ ~(v IN t) /\ ~((a % v) IN t) /\ + &0 < a + ==> aff_lt (vec 0 INSERT (a % v) INSERT s) t = + aff_lt (vec 0 INSERT v INSERT s) t`, + REPEAT STRIP_TAC THEN REWRITE_TAC[aff_lt_def] THEN + MATCH_MP_TAC AFFSIGN_SPECIAL_SCALE THEN + ASM_REWRITE_TAC[sgn_lt] THEN REAL_ARITH_TAC);; + +let AFF_GE_SCALE_LEMMA = prove + (`!a u v:real^N. + &0 < a /\ ~(v = vec 0) + ==> aff_ge {vec 0} {a % u,v} = aff_ge {vec 0} {u,v}`, + REPEAT STRIP_TAC THEN ASM_CASES_TAC `u:real^N = vec 0` THEN + ASM_REWRITE_TAC[VECTOR_MUL_RZERO] THEN + ASM_SIMP_TAC[AFF_GE_1_2_0; VECTOR_MUL_EQ_0; REAL_LT_IMP_NZ; + SET_RULE `DISJOINT {a} {b,c} <=> ~(b = a) /\ ~(c = a)`] THEN + REWRITE_TAC[GSYM SUBSET_ANTISYM_EQ; SUBSET; FORALL_IN_GSPEC] THEN + CONJ_TAC THEN MAP_EVERY X_GEN_TAC [`b:real`; `c:real`] THEN + REWRITE_TAC[IN_ELIM_THM] THEN STRIP_TAC THENL + [EXISTS_TAC `a * b:real`; EXISTS_TAC `b / a:real`] THEN + EXISTS_TAC `c:real` THEN + ASM_SIMP_TAC[REAL_LE_DIV; REAL_LE_MUL; REAL_LT_IMP_LE] THEN + REWRITE_TAC[VECTOR_MUL_ASSOC] THEN + REPLICATE_TAC 2 (AP_THM_TAC THEN AP_TERM_TAC) THEN + UNDISCH_TAC `&0 < a` THEN CONV_TAC REAL_FIELD);; + +let AFFSIGN_0 = prove + (`!sgn s t. + FINITE s /\ FINITE t /\ (vec 0) IN (s DIFF t) + ==> affsign sgn s t = + { vsum (s UNION t) (\v. f v % v) |f| + !x:real^N. x IN t ==> sgn(f x)}`, + REPEAT STRIP_TAC THEN REWRITE_TAC[AFFSIGN] THEN + FIRST_ASSUM(SUBST1_TAC o MATCH_MP (SET_RULE + `x IN s DIFF t ==> s UNION t = x INSERT ((s UNION t) DELETE x)`)) THEN + ASM_SIMP_TAC[SUM_CLAUSES; VSUM_CLAUSES; FINITE_UNION; FINITE_DELETE] THEN + REWRITE_TAC[IN_DELETE; VECTOR_MUL_RZERO; VECTOR_ADD_LID] THEN + MATCH_MP_TAC SUBSET_ANTISYM THEN + REWRITE_TAC[FORALL_IN_GSPEC; SUBSET; LEFT_IMP_EXISTS_THM] THEN + REWRITE_TAC[IN_ELIM_THM] THEN CONJ_TAC THENL + [MAP_EVERY X_GEN_TAC [`y:real^N`; `f:real^N->real`] THEN + STRIP_TAC THEN EXISTS_TAC `f:real^N->real` THEN ASM_REWRITE_TAC[]; + X_GEN_TAC `f:real^N->real` THEN DISCH_TAC THEN + EXISTS_TAC + `\x:real^N. if x = vec 0 + then &1 - sum ((s UNION t) DELETE vec 0) (\x. f x) + else f x` THEN + MP_TAC(SET_RULE + `!x:real^N. x IN (s UNION t) DELETE vec 0 ==> ~(x = vec 0)`) THEN + SIMP_TAC[ETA_AX; REAL_SUB_ADD] THEN DISCH_THEN(K ALL_TAC) THEN + ASM SET_TAC[]]);; + +let AFF_GE_0_AFFINE_MULTIPLE_CONVEX = prove + (`!s t:real^N->bool. + FINITE s /\ FINITE t /\ vec 0 IN (s DIFF t) /\ ~(t = {}) + ==> aff_ge s t = + {x + c % y | x IN affine hull (s DIFF t) /\ + y IN convex hull t /\ &0 <= c}`, + REPEAT STRIP_TAC THEN ASM_SIMP_TAC[aff_ge_def; AFFSIGN_0; sgn_ge] THEN + ONCE_REWRITE_TAC[SET_RULE `s UNION t = (s DIFF t) UNION t`] THEN + ASM_SIMP_TAC[VSUM_UNION; FINITE_DIFF; + SET_RULE `DISJOINT (s DIFF t) t`] THEN + ASM_SIMP_TAC[AFFINE_HULL_EQ_SPAN; HULL_INC] THEN + ASM_SIMP_TAC[SPAN_FINITE; FINITE_DIFF; CONVEX_HULL_FINITE] THEN + MATCH_MP_TAC SUBSET_ANTISYM THEN REWRITE_TAC[SUBSET; FORALL_IN_GSPEC] THEN + REWRITE_TAC[IN_ELIM_THM] THEN CONJ_TAC THENL + [X_GEN_TAC `f:real^N->real` THEN DISCH_TAC THEN + EXISTS_TAC `vsum (s DIFF t) (\x:real^N. f x % x)` THEN + ASM_CASES_TAC `sum t (f:real^N->real) = &0` THENL + [MP_TAC(ISPECL [`f:real^N->real`; `t:real^N->bool`] SUM_POS_EQ_0) THEN + ASM_SIMP_TAC[VECTOR_MUL_LZERO; REAL_MUL_LZERO; VSUM_0] THEN + DISCH_TAC THEN EXISTS_TAC `&0` THEN + REWRITE_TAC[VECTOR_MUL_LZERO; REAL_LE_REFL] THEN + REWRITE_TAC[RIGHT_EXISTS_AND_THM] THEN CONJ_TAC THENL + [EXISTS_TAC `f:real^N->real` THEN REWRITE_TAC[]; ALL_TAC] THEN + ONCE_REWRITE_TAC[SWAP_EXISTS_THM] THEN + REWRITE_TAC[RIGHT_EXISTS_AND_THM; GSYM EXISTS_REFL] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN + DISCH_THEN(X_CHOOSE_TAC `a:real^N`) THEN + EXISTS_TAC `\x:real^N. if x = a then &1 else &0` THEN + ASM_REWRITE_TAC[SUM_DELTA] THEN MESON_TAC[REAL_POS]; + EXISTS_TAC `sum t (f:real^N->real)` THEN + EXISTS_TAC `inv(sum t (f:real^N->real)) % vsum t (\v. f v % v)` THEN + REPEAT CONJ_TAC THENL + [EXISTS_TAC `f:real^N->real` THEN REWRITE_TAC[]; + EXISTS_TAC `\x:real^N. f x / sum t (f:real^N->real)` THEN + ASM_SIMP_TAC[REAL_LE_DIV; SUM_POS_LE] THEN + ONCE_REWRITE_TAC[REAL_ARITH `x / y:real = inv y * x`] THEN + ASM_SIMP_TAC[GSYM VECTOR_MUL_ASSOC; SUM_LMUL; VSUM_LMUL] THEN + ASM_SIMP_TAC[REAL_MUL_LINV]; + ASM_SIMP_TAC[SUM_POS_LE]; + AP_TERM_TAC THEN ASM_CASES_TAC `sum t (f:real^N->real) = &0` THEN + ASM_SIMP_TAC[VECTOR_MUL_ASSOC; REAL_MUL_RINV; VECTOR_MUL_LID]]]; + MAP_EVERY X_GEN_TAC [`x:real^N`; `c:real`; `y:real^N`] THEN + DISCH_THEN(CONJUNCTS_THEN2 + (X_CHOOSE_THEN `u:real^N->real` (SUBST1_TAC o SYM)) MP_TAC) THEN + DISCH_THEN(CONJUNCTS_THEN2 + (X_CHOOSE_THEN `v:real^N->real`MP_TAC) ASSUME_TAC) THEN + REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + DISCH_THEN(SUBST1_TAC o SYM) THEN + EXISTS_TAC `(\x. if x IN t then c * v x else u x):real^N->real` THEN + ASM_SIMP_TAC[REAL_LE_MUL; VSUM_LMUL; GSYM VECTOR_MUL_ASSOC] THEN + AP_THM_TAC THEN AP_TERM_TAC THEN MATCH_MP_TAC VSUM_EQ THEN + SIMP_TAC[IN_DIFF]]);; + +let AFF_GE_0_MULTIPLE_AFFINE_CONVEX = prove + (`!s t:real^N->bool. + FINITE s /\ FINITE t /\ vec 0 IN (s DIFF t) /\ ~(t = {}) + ==> aff_ge s t = + affine hull (s DIFF t) UNION + {c % (x + y) | x IN affine hull (s DIFF t) /\ + y IN convex hull t /\ &0 <= c}`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN + REWRITE_TAC[UNION_SUBSET] THEN REPEAT CONJ_TAC THENL + [ASM_SIMP_TAC[AFF_GE_0_AFFINE_MULTIPLE_CONVEX; + AFFINE_HULL_EQ_SPAN; HULL_INC] THEN + REWRITE_TAC[SUBSET; FORALL_IN_GSPEC] THEN + MAP_EVERY X_GEN_TAC [`x:real^N`; `c:real`; `y:real^N`] THEN STRIP_TAC THEN + REWRITE_TAC[IN_ELIM_THM; IN_UNION] THEN ASM_CASES_TAC `c = &0` THENL + [DISJ1_TAC THEN ASM_REWRITE_TAC[VECTOR_MUL_LZERO; VECTOR_ADD_RID]; + DISJ2_TAC THEN MAP_EVERY EXISTS_TAC + [`c:real`; `inv(c) % x:real^N`; `y:real^N`] THEN + ASM_SIMP_TAC[SPAN_MUL; VECTOR_ADD_LDISTRIB; VECTOR_MUL_ASSOC; + REAL_MUL_RINV; VECTOR_MUL_LID]]; + REWRITE_TAC[aff_ge_def] THEN ONCE_REWRITE_TAC[AFFSIGN_DISJOINT_DIFF] THEN + REWRITE_TAC[GSYM aff_ge_def] THEN + MATCH_MP_TAC AFFINE_HULL_SUBSET_AFF_GE THEN SET_TAC[]; + ASM_SIMP_TAC[AFF_GE_0_AFFINE_MULTIPLE_CONVEX; + AFFINE_HULL_EQ_SPAN; HULL_INC] THEN + REWRITE_TAC[SUBSET; FORALL_IN_GSPEC] THEN + MAP_EVERY X_GEN_TAC [`c:real`; `x:real^N`; `y:real^N`] THEN STRIP_TAC THEN + REWRITE_TAC[IN_ELIM_THM] THEN MAP_EVERY EXISTS_TAC + [`c % x:real^N`; `c:real`; `y:real^N`] THEN + ASM_SIMP_TAC[SPAN_MUL; VECTOR_ADD_LDISTRIB]]);; + +let AFF_GE_0_AFFINE_CONVEX_CONE = prove + (`!s t:real^N->bool. + FINITE s /\ FINITE t /\ vec 0 IN (s DIFF t) + ==> aff_ge s t = + {x + y | x IN affine hull (s DIFF t) /\ + y IN convex_cone hull t}`, + REPEAT STRIP_TAC THEN ASM_CASES_TAC `t:real^N->bool = {}` THENL + [ASM_REWRITE_TAC[AFF_GE_EQ_AFFINE_HULL; CONVEX_CONE_HULL_EMPTY] THEN + REWRITE_TAC[IN_SING; DIFF_EMPTY] THEN + REWRITE_TAC[SET_RULE `{x + y:real^N | P x /\ y = a} = {x + a | P x}`] THEN + REWRITE_TAC[VECTOR_ADD_RID] THEN SET_TAC[]; + ASM_SIMP_TAC[CONVEX_CONE_HULL_CONVEX_HULL_NONEMPTY; + AFF_GE_0_AFFINE_MULTIPLE_CONVEX] THEN + SET_TAC[]]);; + +let AFF_GE_0_N = prove + (`!s:real^N->bool. + FINITE s /\ ~(vec 0 IN s) + ==> aff_ge {vec 0} s = + {y | ?u. (!x. x IN s ==> &0 <= u x) /\ + y = vsum s (\x. u x % x)}`, + REPEAT STRIP_TAC THEN REWRITE_TAC[aff_ge_def] THEN + ASM_SIMP_TAC[AFFSIGN_0; IN_DIFF; IN_INSERT; NOT_IN_EMPTY; + FINITE_INSERT; FINITE_EMPTY] THEN + ASM_SIMP_TAC[EXTENSION; sgn_ge; IN_ELIM_THM; INSERT_UNION; UNION_EMPTY] THEN + ASM_SIMP_TAC[VSUM_CLAUSES; VECTOR_MUL_RZERO; VECTOR_ADD_LID]);; + +let AFF_GE_0_CONVEX_HULL = prove + (`!s:real^N->bool. + FINITE s /\ ~(s = {}) /\ ~(vec 0 IN s) + ==> aff_ge {vec 0} s = {t % y | &0 <= t /\ y IN convex hull s}`, + REPEAT STRIP_TAC THEN + ASM_SIMP_TAC[AFF_GE_0_AFFINE_MULTIPLE_CONVEX; IN_DIFF; + FINITE_INSERT; FINITE_EMPTY; IN_INSERT] THEN + ASM_SIMP_TAC[SET_RULE `~(a IN s) ==> {a} DIFF s = {a}`] THEN + REWRITE_TAC[AFFINE_HULL_SING; IN_SING] THEN + REWRITE_TAC[EXTENSION; IN_ELIM_THM] THEN MESON_TAC[VECTOR_ADD_LID]);; + +let AFF_GE_0_CONVEX_HULL_ALT = prove + (`!s:real^N->bool. + FINITE s /\ ~(vec 0 IN s) + ==> aff_ge {vec 0} s = + vec 0 INSERT {t % y | &0 < t /\ y IN convex hull s}`, + REPEAT STRIP_TAC THEN + ASM_CASES_TAC `s:real^N->bool = {}` THENL + [ASM_REWRITE_TAC[AFF_GE_EQ_AFFINE_HULL; CONVEX_HULL_EMPTY] THEN + REWRITE_TAC[AFFINE_HULL_SING; NOT_IN_EMPTY] THEN SET_TAC[]; + ASM_SIMP_TAC[AFF_GE_0_CONVEX_HULL; EXTENSION; IN_ELIM_THM; IN_INSERT] THEN + X_GEN_TAC `y:real^N` THEN ASM_CASES_TAC `y:real^N = vec 0` THEN + ASM_REWRITE_TAC[] THENL + [EXISTS_TAC `&0` THEN ASM_REWRITE_TAC[REAL_POS; VECTOR_MUL_LZERO] THEN + ASM_REWRITE_TAC[MEMBER_NOT_EMPTY; CONVEX_HULL_EQ_EMPTY]; + AP_TERM_TAC THEN REWRITE_TAC[FUN_EQ_THM] THEN X_GEN_TAC `t:real` THEN + AP_TERM_TAC THEN ABS_TAC THEN + ASM_CASES_TAC `t = &0` THEN + ASM_REWRITE_TAC[VECTOR_MUL_LZERO; REAL_LT_REFL] THEN + ASM_REWRITE_TAC[REAL_LT_LE]]]);; + +let AFF_GE_0_CONVEX_CONE_NEGATIONS = prove + (`!s t:real^N->bool. + FINITE s /\ FINITE t /\ vec 0 IN (s DIFF t) + ==> aff_ge s t = + convex_cone hull (s UNION t UNION IMAGE (--) (s DIFF t))`, + REPEAT STRIP_TAC THEN ASM_SIMP_TAC[AFF_GE_0_AFFINE_CONVEX_CONE] THEN + ASM_SIMP_TAC[AFFINE_HULL_EQ_SPAN; HULL_INC] THEN + REWRITE_TAC[SPAN_CONVEX_CONE_ALLSIGNS; GSYM CONVEX_CONE_HULL_UNION] THEN + AP_TERM_TAC THEN SET_TAC[]);; + +let CONVEX_HULL_AFF_GE = prove + (`!s. convex hull s = aff_ge {} s`, + SIMP_TAC[aff_ge_def; AFFSIGN; CONVEX_HULL_FINITE; sgn_ge; UNION_EMPTY] THEN + REWRITE_TAC[EXTENSION; IN_ELIM_THM] THEN REPEAT GEN_TAC THEN + AP_TERM_TAC THEN REWRITE_TAC[FUN_EQ_THM] THEN MESON_TAC[]);; + +let POLYHEDRON_AFF_GE = prove + (`!s t:real^N->bool. FINITE s /\ FINITE t ==> polyhedron(aff_ge s t)`, + REPEAT STRIP_TAC THEN REWRITE_TAC[aff_ge_def] THEN + ONCE_REWRITE_TAC[AFFSIGN_DISJOINT_DIFF] THEN + REWRITE_TAC[GSYM aff_ge_def] THEN + SUBGOAL_THEN `FINITE(s DIFF t) /\ FINITE(t:real^N->bool) /\ + DISJOINT (s DIFF t) t` + MP_TAC THENL [ASM_SIMP_TAC[FINITE_DIFF] THEN ASM SET_TAC[]; ALL_TAC] THEN + POP_ASSUM_LIST(K ALL_TAC) THEN + SPEC_TAC(`s DIFF t:real^N->bool`,`s:real^N->bool`) THEN + MATCH_MP_TAC SET_PROVE_CASES THEN CONJ_TAC THENL + [REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM CONVEX_HULL_AFF_GE] THEN + MATCH_MP_TAC POLYTOPE_IMP_POLYHEDRON THEN REWRITE_TAC[polytope] THEN + ASM_MESON_TAC[]; + ALL_TAC] THEN + MAP_EVERY X_GEN_TAC [`a:real^N`; `s:real^N->bool`] THEN + GEOM_ORIGIN_TAC `a:real^N` THEN REPEAT STRIP_TAC THEN + SUBGOAL_THEN `(vec 0:real^N) IN ((vec 0 INSERT s) DIFF t)` ASSUME_TAC THENL + [ASM SET_TAC[]; ALL_TAC] THEN + ASM_SIMP_TAC[AFF_GE_0_CONVEX_CONE_NEGATIONS; FINITE_INSERT] THEN + MATCH_MP_TAC POLYHEDRON_CONVEX_CONE_HULL THEN + ASM_SIMP_TAC[FINITE_INSERT; FINITE_UNION; FINITE_DIFF; FINITE_IMAGE]);; + +let CLOSED_AFF_GE = prove + (`!s t:real^N->bool. FINITE s /\ FINITE t ==> closed(aff_ge s t)`, + SIMP_TAC[POLYHEDRON_AFF_GE; POLYHEDRON_IMP_CLOSED]);; + +let CONIC_AFF_GE_0 = prove + (`!s:real^N->bool. FINITE s /\ ~(vec 0 IN s) ==> conic(aff_ge {vec 0} s)`, + REPEAT STRIP_TAC THEN ASM_SIMP_TAC[AFF_GE_0_N; conic] THEN + REWRITE_TAC[IN_ELIM_THM] THEN GEN_TAC THEN X_GEN_TAC `c:real` THEN + DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN + DISCH_THEN(X_CHOOSE_THEN `u:real^N->real` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `\v. c * (u:real^N->real) v` THEN + REWRITE_TAC[GSYM VECTOR_MUL_ASSOC; VSUM_LMUL] THEN + ASM_MESON_TAC[REAL_LE_MUL]);; + +let ANGLES_ADD_AFF_GE = prove + (`!u v w x:real^N. + ~(v = u) /\ ~(w = u) /\ ~(x = u) /\ x IN aff_ge {u} {v,w} + ==> angle(v,u,x) + angle(x,u,w) = angle(v,u,w)`, + GEOM_ORIGIN_TAC `u:real^N` THEN REPEAT GEN_TAC THEN + REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + ASM_SIMP_TAC[AFF_GE_1_2_0] THEN + REWRITE_TAC[IN_ELIM_THM; LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`a:real`; `b:real`] THEN + DISCH_THEN(CONJUNCTS_THEN2 STRIP_ASSUME_TAC MP_TAC) THEN + SUBGOAL_THEN `a = &0 /\ b = &0 \/ &0 < a + b` STRIP_ASSUME_TAC THENL + [ASM_REAL_ARITH_TAC; + ASM_REWRITE_TAC[VECTOR_MUL_LZERO; VECTOR_ADD_LID]; + ALL_TAC] THEN + DISCH_TAC THEN MP_TAC(ISPECL + [`v:real^N`; `w:real^N`; `inv(a + b) % x:real^N`; `vec 0:real^N`] + ANGLES_ADD_BETWEEN) THEN + ASM_REWRITE_TAC[angle; VECTOR_SUB_RZERO] THEN + ASM_SIMP_TAC[VECTOR_ANGLE_RMUL; VECTOR_ANGLE_LMUL; + REAL_INV_EQ_0; REAL_LE_INV_EQ; REAL_LT_IMP_NZ; REAL_LT_IMP_LE] THEN + DISCH_THEN MATCH_MP_TAC THEN + REWRITE_TAC[BETWEEN_IN_SEGMENT; CONVEX_HULL_2; SEGMENT_CONVEX_HULL] THEN + REWRITE_TAC[IN_ELIM_THM] THEN + MAP_EVERY EXISTS_TAC [`a / (a + b):real`; `b / (a + b):real`] THEN + ASM_SIMP_TAC[REAL_LE_DIV; REAL_LT_IMP_LE; VECTOR_ADD_LDISTRIB] THEN + REWRITE_TAC[VECTOR_MUL_ASSOC; real_div; REAL_MUL_AC] THEN + UNDISCH_TAC `&0 < a + b` THEN CONV_TAC REAL_FIELD);; + +let AFF_GE_2_1_0_DROPOUT_3 = prove + (`!w z:real^3. + ~collinear{vec 0,basis 3,z} + ==> (w IN aff_ge {vec 0,basis 3} {z} <=> + (dropout 3 w) IN aff_ge {vec 0:real^2} {dropout 3 z})`, + REPEAT GEN_TAC THEN + ASM_CASES_TAC `z:real^3 = vec 0` THENL + [ASM_REWRITE_TAC[COLLINEAR_2; INSERT_AC]; ALL_TAC] THEN + ASM_CASES_TAC `z:real^3 = basis 3` THENL + [ASM_REWRITE_TAC[COLLINEAR_2; INSERT_AC]; ALL_TAC] THEN + REWRITE_TAC[COLLINEAR_BASIS_3] THEN DISCH_TAC THEN + ASM_SIMP_TAC[AFF_GE_2_1_0; SET_RULE `DISJOINT s {a} <=> ~(a IN s)`; + IN_INSERT; NOT_IN_EMPTY; AFF_GE_1_1_0] THEN + REWRITE_TAC[IN_ELIM_THM] THEN + MATCH_MP_TAC(MESON[] + `(!t. ((?s. P s t) <=> Q t)) ==> ((?s t. P s t) <=> (?t. Q t))`) THEN + X_GEN_TAC `t:real` THEN EQ_TAC THENL + [STRIP_TAC THEN + ASM_REWRITE_TAC[DROPOUT_ADD; DROPOUT_MUL; DROPOUT_BASIS_3] THEN + VECTOR_ARITH_TAC; + STRIP_TAC THEN EXISTS_TAC `(w:real^3)$3 - t * (z:real^3)$3` THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [CART_EQ]) THEN + ASM_REWRITE_TAC[CART_EQ; FORALL_2; FORALL_3; DIMINDEX_2; DIMINDEX_3] THEN + REWRITE_TAC[VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT] THEN + SIMP_TAC[dropout; LAMBDA_BETA; DIMINDEX_2; ARITH; BASIS_COMPONENT; + DIMINDEX_3] THEN + CONV_TAC REAL_RING]);; + +let AFF_GE_2_1_0_SEMIALGEBRAIC = prove + (`!x y z:real^3. + ~collinear {vec 0,x,y} /\ ~collinear {vec 0,x,z} + ==> (z IN aff_ge {vec 0,x} {y} <=> + (x cross y) cross x cross z = vec 0 /\ + &0 <= (x cross z) dot (x cross y))`, + let lemma0 = prove + (`~(y = vec 0) ==> ((?s. x = s % y) <=> y cross x = vec 0)`, + REWRITE_TAC[CROSS_EQ_0] THEN SIMP_TAC[COLLINEAR_LEMMA_ALT]) + and lemma1 = prove + (`!x y:real^N. + ~(y = vec 0) + ==> ((?t. &0 <= t /\ x = t % y) <=> + (?t. x = t % y) /\ &0 <= x dot y)`, + REPEAT STRIP_TAC THEN REWRITE_TAC[LEFT_AND_EXISTS_THM] THEN + AP_TERM_TAC THEN REWRITE_TAC[FUN_EQ_THM] THEN X_GEN_TAC `t:real` THEN + ASM_CASES_TAC `x:real^N = t % y` THEN + ASM_SIMP_TAC[DOT_LMUL; REAL_LE_MUL_EQ; DOT_POS_LT]) in + REPEAT GEN_TAC THEN + MAP_EVERY (fun t -> ASM_CASES_TAC t THENL + [ASM_REWRITE_TAC[COLLINEAR_2; INSERT_AC]; ALL_TAC]) + [`x:real^3 = vec 0`; `y:real^3 = vec 0`; `y:real^3 = x`] THEN + STRIP_TAC THEN + ASM_SIMP_TAC[AFF_GE_2_1_0; IN_ELIM_THM; SET_RULE + `DISJOINT {a,b} {c} <=> ~(a = c) /\ ~(b = c)`] THEN + ONCE_REWRITE_TAC[SWAP_EXISTS_THM] THEN + REWRITE_TAC[RIGHT_EXISTS_AND_THM; VECTOR_ARITH + `a:real^N = b + c <=> a - c = b`] THEN + RULE_ASSUM_TAC(REWRITE_RULE[GSYM CROSS_EQ_0]) THEN + ASM_SIMP_TAC[lemma0; lemma1; CROSS_RMUL; CROSS_RSUB; VECTOR_SUB_EQ]);; + +(* ------------------------------------------------------------------------- *) +(* Special case of aff_ge {x} {y}, i.e. rays or half-lines. *) +(* ------------------------------------------------------------------------- *) + +let HALFLINE_REFL = prove + (`!x. aff_ge {x} {x} = {x}`, + ONCE_REWRITE_TAC[AFF_GE_DISJOINT_DIFF] THEN + ASM_REWRITE_TAC[DIFF_EQ_EMPTY; GSYM CONVEX_HULL_AFF_GE; CONVEX_HULL_SING]);; + +let HALFLINE_EXPLICIT = prove + (`!x y:real^N. + aff_ge {x} {y} = + {z | ?t1 t2. &0 <= t2 /\ t1 + t2 = &1 /\ z = t1 % x + t2 % y}`, + REPEAT GEN_TAC THEN ASM_CASES_TAC `x:real^N = y` THENL + [ASM_REWRITE_TAC[HALFLINE_REFL]; AFF_TAC] THEN + REWRITE_TAC[REAL_ARITH `x + y = &1 <=> x = &1 - y`] THEN + REWRITE_TAC[VECTOR_ARITH `(&1 - x) % v + x % v:real^N = v`; + MESON[] `(?x y. P y /\ x = f y /\ Q x y) <=> (?y. P y /\ Q (f y) y)`] THEN + REWRITE_TAC[IN_ELIM_THM; IN_SING; EXTENSION] THEN MESON_TAC[REAL_POS]);; + +let HALFLINE = prove + (`!x y:real^N. + aff_ge {x} {y} = + {z | ?t. &0 <= t /\ z = (&1 - t) % x + t % y}`, + REWRITE_TAC[HALFLINE_EXPLICIT; REAL_ARITH `x + y = &1 <=> x = &1 - y`] THEN + SET_TAC[]);; + +let CLOSED_HALFLINE = prove + (`!x y. closed(aff_ge {x} {y})`, + SIMP_TAC[CLOSED_AFF_GE; FINITE_SING]);; + +let SEGMENT_SUBSET_HALFLINE = prove + (`!x y. segment[x,y] SUBSET aff_ge {x} {y}`, + REWRITE_TAC[SEGMENT_CONVEX_HULL; CONVEX_HULL_2; HALFLINE_EXPLICIT] THEN + SET_TAC[]);; + +let ENDS_IN_HALFLINE = prove + (`(!x y. x IN aff_ge {x} {y}) /\ (!x y. y IN aff_ge {x} {y})`, + MESON_TAC[SEGMENT_SUBSET_HALFLINE; SUBSET; ENDS_IN_SEGMENT]);; + +let HALFLINE_SUBSET_AFFINE_HULL = prove + (`!x y. aff_ge {x} {y} SUBSET affine hull {x,y}`, + REWRITE_TAC[AFF_GE_SUBSET_AFFINE_HULL; SET_RULE `{x,y} = {x} UNION {y}`]);; + +let HALFLINE_INTER_COMPACT_SEGMENT = prove + (`!s a b:real^N. + compact s /\ convex s /\ a IN s + ==> ?c. aff_ge {a} {b} INTER s = segment[a,c]`, + REPEAT STRIP_TAC THEN ASM_CASES_TAC `b:real^N = a` THENL + [EXISTS_TAC `a:real^N` THEN + ASM_REWRITE_TAC[SEGMENT_REFL; HALFLINE_REFL] THEN ASM SET_TAC[]; + ALL_TAC] THEN + SUBGOAL_THEN + `?u v:real^N. aff_ge {a} {b} INTER s = segment[u,v]` + STRIP_ASSUME_TAC THENL + [MATCH_MP_TAC COMPACT_CONVEX_COLLINEAR_SEGMENT THEN + ASM_SIMP_TAC[CLOSED_INTER_COMPACT; CLOSED_AFF_GE; FINITE_SING] THEN + ASM_SIMP_TAC[CONVEX_INTER; CONVEX_AFF_GE] THEN CONJ_TAC THENL + [REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; IN_INTER] THEN + ASM_MESON_TAC[ENDS_IN_HALFLINE]; + MATCH_MP_TAC COLLINEAR_SUBSET THEN + EXISTS_TAC `affine hull {a:real^N,b}` THEN + REWRITE_TAC[COLLINEAR_AFFINE_HULL_COLLINEAR; COLLINEAR_2] THEN + MATCH_MP_TAC(SET_RULE `s SUBSET u ==> (s INTER t) SUBSET u`) THEN + REWRITE_TAC[HALFLINE_SUBSET_AFFINE_HULL]]; + ASM_CASES_TAC `u:real^N = a` THENL [ASM_MESON_TAC[]; ALL_TAC] THEN + ASM_CASES_TAC `v:real^N = a` THENL + [ASM_MESON_TAC[SEGMENT_SYM]; ALL_TAC] THEN + SUBGOAL_THEN `u IN aff_ge {a:real^N} {b} /\ v IN aff_ge {a} {b}` + MP_TAC THENL [ASM_MESON_TAC[IN_INTER; ENDS_IN_SEGMENT]; ALL_TAC] THEN + GEN_REWRITE_TAC (LAND_CONV o TOP_DEPTH_CONV) [HALFLINE; IN_ELIM_THM] THEN + DISCH_THEN(CONJUNCTS_THEN2 + (X_CHOOSE_THEN `s:real` MP_TAC) (X_CHOOSE_THEN `t:real` MP_TAC)) THEN + MAP_EVERY ASM_CASES_TAC [`s = &0`; `t = &0`] THEN + ASM_REWRITE_TAC[REAL_SUB_RZERO; VECTOR_MUL_LID; VECTOR_MUL_LZERO; + VECTOR_ADD_RID] THEN + ASM_REWRITE_TAC[REAL_LE_LT] THEN REPEAT STRIP_TAC THEN + SUBGOAL_THEN `(a:real^N) IN segment[u,v]` MP_TAC THENL + [ASM_MESON_TAC[IN_INTER; ENDS_IN_HALFLINE]; ALL_TAC] THEN + ASM_REWRITE_TAC[IN_SEGMENT; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `u:real` THEN + REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + REWRITE_TAC[VECTOR_ARITH + `a = (&1 - u) % ((&1 - s) % a + s % b) + u % ((&1 - t) % a + t % b) <=> + ((&1 - u) * s + u * t) % (b - a):real^N = vec 0`] THEN + ASM_REWRITE_TAC[VECTOR_MUL_EQ_0; VECTOR_SUB_EQ] THEN + ASM_SIMP_TAC[REAL_LE_MUL; REAL_SUB_LE; REAL_LT_IMP_LE; REAL_ARITH + `&0 <= x /\ &0 <= y ==> (x + y = &0 <=> x = &0 /\ y = &0)`] THEN + ASM_SIMP_TAC[REAL_ENTIRE; REAL_LT_IMP_NZ] THEN REAL_ARITH_TAC]);; + +(* ------------------------------------------------------------------------- *) +(* Definition and properties of conv0. *) +(* ------------------------------------------------------------------------- *) + +let conv0 = new_definition `conv0 S:real^A->bool = affsign sgn_gt {} S`;; + +let CONV0_INJECTIVE_LINEAR_IMAGE = prove + (`!f s. linear f /\ (!x y. f x = f y ==> x = y) + ==> conv0(IMAGE f s) = IMAGE f (conv0 s)`, + REPEAT GEN_TAC THEN DISCH_TAC THEN + FIRST_ASSUM(ASSUME_TAC o GSYM o MATCH_MP AFFSIGN_INJECTIVE_LINEAR_IMAGE) THEN + ASM_REWRITE_TAC[conv0; IMAGE_CLAUSES]);; + +add_linear_invariants [CONV0_INJECTIVE_LINEAR_IMAGE];; + +let CONV0_TRANSLATION = prove + (`!a s. conv0(IMAGE (\x. a + x) s) = IMAGE (\x. a + x) (conv0 s)`, + REWRITE_TAC[conv0; GSYM AFFSIGN_TRANSLATION; IMAGE_CLAUSES]);; + +add_translation_invariants [CONV0_TRANSLATION];; + +let CONV0_SUBSET_CONVEX_HULL = prove + (`!s. conv0 s SUBSET convex hull s`, + REWRITE_TAC[conv0; AFFSIGN; sgn_gt; CONVEX_HULL_FINITE; UNION_EMPTY] THEN + REWRITE_TAC[SUBSET; IN_ELIM_THM] THEN + REPEAT GEN_TAC THEN MATCH_MP_TAC MONO_EXISTS THEN + MESON_TAC[REAL_LT_IMP_LE]);; + +let CONV0_AFF_GT = prove + (`!s. conv0 s = aff_gt {} s`, + REWRITE_TAC[conv0; aff_gt_def]);; + +let CONVEX_HULL_CONV0_DECOMP = prove + (`!s:real^N->bool. + FINITE s + ==> convex hull s = conv0 s UNION + UNIONS {convex hull (s DELETE a) | a | a IN s}`, + REWRITE_TAC[CONV0_AFF_GT; CONVEX_HULL_AFF_GE] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC AFF_GE_AFF_GT_DECOMP THEN + ASM_REWRITE_TAC[FINITE_EMPTY] THEN SET_TAC[]);; + +let CONVEX_CONV0 = prove + (`!s. convex(conv0 s)`, + REWRITE_TAC[CONV0_AFF_GT; CONVEX_AFF_GT]);; + +let BOUNDED_CONV0 = prove + (`!s:real^N->bool. bounded s ==> bounded(conv0 s)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC BOUNDED_SUBSET THEN + EXISTS_TAC `convex hull s:real^N->bool` THEN + ASM_SIMP_TAC[BOUNDED_CONVEX_HULL; CONV0_SUBSET_CONVEX_HULL]);; + +let MEASURABLE_CONV0 = prove + (`!s. bounded s ==> measurable(conv0 s)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC MEASURABLE_CONVEX THEN + ASM_SIMP_TAC[CONVEX_CONV0; BOUNDED_CONV0]);; + +let NEGLIGIBLE_CONVEX_HULL_DIFF_CONV0 = prove + (`!s:real^N->bool. + FINITE s /\ CARD s <= dimindex(:N) + 1 + ==> negligible(convex hull s DIFF conv0 s)`, + REPEAT STRIP_TAC THEN ASM_SIMP_TAC[CONVEX_HULL_CONV0_DECOMP] THEN + REWRITE_TAC[SET_RULE `(s UNION t) DIFF s = t DIFF s`] THEN + MATCH_MP_TAC NEGLIGIBLE_DIFF THEN MATCH_MP_TAC NEGLIGIBLE_UNIONS THEN + ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN ASM_SIMP_TAC[FINITE_IMAGE] THEN + REWRITE_TAC[FORALL_IN_IMAGE] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC NEGLIGIBLE_CONVEX_HULL THEN + ASM_SIMP_TAC[FINITE_DELETE; CARD_DELETE] THEN ASM_ARITH_TAC);; + +let MEASURE_CONV0_CONVEX_HULL = prove + (`!s:real^N->bool. + FINITE s /\ CARD s <= dimindex(:N) + 1 + ==> measure(conv0 s) = measure(convex hull s)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC MEASURE_NEGLIGIBLE_SYMDIFF THEN + ASM_SIMP_TAC[MEASURABLE_CONVEX_HULL; FINITE_IMP_BOUNDED] THEN + MATCH_MP_TAC NEGLIGIBLE_UNION THEN + ASM_SIMP_TAC[NEGLIGIBLE_CONVEX_HULL_DIFF_CONV0] THEN + ASM_SIMP_TAC[CONV0_SUBSET_CONVEX_HULL; NEGLIGIBLE_EMPTY; + SET_RULE `s SUBSET t ==> s DIFF t = {}`]);; + +(* ------------------------------------------------------------------------- *) +(* Orthonormal triples of vectors in 3D. *) +(* ------------------------------------------------------------------------- *) + +let orthonormal = new_definition + `orthonormal e1 e2 e3 <=> + e1 dot e1 = &1 /\ e2 dot e2 = &1 /\ e3 dot e3 = &1 /\ + e1 dot e2 = &0 /\ e1 dot e3 = &0 /\ e2 dot e3 = &0 /\ + &0 < (e1 cross e2) dot e3`;; + +let ORTHONORMAL_LINEAR_IMAGE = prove + (`!f. linear(f) /\ (!x. norm(f x) = norm x) /\ + (2 <= dimindex(:3) ==> det(matrix f) = &1) + ==> !e1 e2 e3. orthonormal (f e1) (f e2) (f e3) <=> + orthonormal e1 e2 e3`, + SIMP_TAC[DIMINDEX_3; ARITH; CONJ_ASSOC; GSYM ORTHOGONAL_TRANSFORMATION] THEN + SIMP_TAC[orthonormal; CROSS_ORTHOGONAL_TRANSFORMATION] THEN + SIMP_TAC[orthogonal_transformation; VECTOR_MUL_LID]);; + +add_linear_invariants [ORTHONORMAL_LINEAR_IMAGE];; + +let ORTHONORMAL_PERMUTE = prove + (`!e1 e2 e3. orthonormal e1 e2 e3 ==> orthonormal e2 e3 e1`, + REWRITE_TAC[orthonormal] THEN + REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + ONCE_REWRITE_TAC[GSYM CROSS_TRIPLE] THEN ASM_REWRITE_TAC[] THEN + ONCE_REWRITE_TAC[DOT_SYM] THEN ASM_REWRITE_TAC[]);; + +let ORTHONORMAL_CROSS = prove + (`!e1 e2 e3. + orthonormal e1 e2 e3 + ==> e2 cross e3 = e1 /\ e3 cross e1 = e2 /\ e1 cross e2 = e3`, + SUBGOAL_THEN + `!e1 e2 e3. orthonormal e1 e2 e3 ==> e3 cross e1 = e2` + (fun th -> MESON_TAC[th; ORTHONORMAL_PERMUTE]) THEN + GEOM_BASIS_MULTIPLE_TAC 1 `e1:real^3` THEN X_GEN_TAC `k:real` THEN + REWRITE_TAC[orthonormal; DOT_LMUL; DOT_RMUL] THEN + SIMP_TAC[DOT_BASIS_BASIS; DIMINDEX_3; ARITH; REAL_MUL_RID] THEN + REWRITE_TAC[REAL_RING `k * k = &1 <=> k = &1 \/ k = -- &1`] THEN + ASM_CASES_TAC `k = -- &1` THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN + ASM_CASES_TAC `k = &1` THEN + ASM_REWRITE_TAC[VECTOR_MUL_LID; REAL_MUL_LID; REAL_MUL_RID] THEN + SIMP_TAC[cross; DOT_3; VECTOR_3; CART_EQ; FORALL_3; DIMINDEX_3; + BASIS_COMPONENT; DIMINDEX_3; ARITH; REAL_POS] THEN + REWRITE_TAC[REAL_MUL_LZERO; REAL_SUB_RZERO; REAL_ADD_RID; + REAL_MUL_LID] THEN + REPEAT GEN_TAC THEN + ASM_CASES_TAC `(e2:real^3)$1 = &0` THEN ASM_REWRITE_TAC[] THEN + ASM_CASES_TAC `(e3:real^3)$1 = &0` THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[REAL_MUL_RZERO; REAL_SUB_RZERO; REAL_ADD_LID] THEN + REWRITE_TAC[REAL_SUB_LZERO; REAL_MUL_RID] THEN + MATCH_MP_TAC(REAL_ARITH + `(u = &1 /\ v = &1 /\ w = &0 ==> a = b /\ --c = d \/ a = --b /\ c = d) /\ + (a = --b /\ c = d ==> x <= &0) + ==> (u = &1 /\ v = &1 /\ w = &0 /\ &0 < x + ==> a:real = b /\ --c:real = d)`) THEN + CONJ_TAC THENL [CONV_TAC REAL_RING; ALL_TAC] THEN + DISCH_THEN(CONJUNCTS_THEN SUBST1_TAC) THEN + MATCH_MP_TAC(REAL_ARITH + `&0 <= x * x /\ &0 <= y * y ==> --x * x + y * -- y <= &0`) THEN + REWRITE_TAC[REAL_LE_SQUARE]);; + +let ORTHONORMAL_IMP_NONZERO = prove + (`!e1 e2 e3. orthonormal e1 e2 e3 + ==> ~(e1 = vec 0) /\ ~(e2 = vec 0) /\ ~(e3 = vec 0)`, + REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN + REWRITE_TAC[DE_MORGAN_THM] THEN STRIP_TAC THEN + ASM_REWRITE_TAC[orthonormal; DOT_LZERO] THEN REAL_ARITH_TAC);; + +let ORTHONORMAL_IMP_DISTINCT = prove + (`!e1 e2 e3. orthonormal e1 e2 e3 ==> ~(e1 = e2) /\ ~(e1 = e3) /\ ~(e2 = e3)`, + REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN + REWRITE_TAC[DE_MORGAN_THM] THEN STRIP_TAC THEN + ASM_REWRITE_TAC[orthonormal; DOT_LZERO] THEN REAL_ARITH_TAC);; + +let ORTHONORMAL_IMP_INDEPENDENT = prove + (`!e1 e2 e3. orthonormal e1 e2 e3 ==> independent {e1,e2,e3}`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC PAIRWISE_ORTHOGONAL_INDEPENDENT THEN + CONJ_TAC THENL [ALL_TAC; ASM SET_TAC[ORTHONORMAL_IMP_NONZERO]] THEN + RULE_ASSUM_TAC(REWRITE_RULE[orthonormal]) THEN + REWRITE_TAC[pairwise; IN_INSERT; NOT_IN_EMPTY] THEN + REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[orthogonal] THEN + ASM_MESON_TAC[DOT_SYM]);; + +let ORTHONORMAL_IMP_SPANNING = prove + (`!e1 e2 e3. orthonormal e1 e2 e3 ==> span {e1,e2,e3} = (:real^3)`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`(:real^3)`; `{e1:real^3,e2,e3}`] CARD_EQ_DIM) THEN + ASM_SIMP_TAC[ORTHONORMAL_IMP_INDEPENDENT; SUBSET_UNIV] THEN + REWRITE_TAC[DIM_UNIV; DIMINDEX_3; HAS_SIZE; FINITE_INSERT; FINITE_EMPTY] THEN + SIMP_TAC[CARD_CLAUSES; FINITE_INSERT; FINITE_EMPTY; IN_INSERT] THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP ORTHONORMAL_IMP_DISTINCT) THEN + ASM_REWRITE_TAC[NOT_IN_EMPTY; ARITH] THEN SET_TAC[]);; + +let ORTHONORMAL_IMP_INDEPENDENT_EXPLICIT_0 = prove + (`!e1 e2 e3 t1 t2 t3. + orthonormal e1 e2 e3 + ==> (t1 % e1 + t2 % e2 + t3 % e3 = vec 0 <=> + t1 = &0 /\ t2 = &0 /\ t3 = &0)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC INDEPENDENT_3 THEN + ASM_MESON_TAC[ORTHONORMAL_IMP_INDEPENDENT; ORTHONORMAL_IMP_DISTINCT]);; + +let ORTHONORMAL_IMP_INDEPENDENT_EXPLICIT = prove + (`!e1 e2 e3 s1 s2 s3 t1 t2 t3. + orthonormal e1 e2 e3 + ==> (s1 % e1 + s2 % e2 + s3 % e3 = t1 % e1 + t2 % e2 + t3 % e3 <=> + s1 = t1 /\ s2 = t2 /\ s3 = t3)`, + SIMP_TAC[ORTHONORMAL_IMP_INDEPENDENT_EXPLICIT_0; REAL_SUB_0; VECTOR_ARITH + `a % x + b % y + c % z:real^3 = a' % x + b' % y + c' % z <=> + (a - a') % x + (b - b') % y + (c - c') % z = vec 0`]);; + +(* ------------------------------------------------------------------------- *) +(* Flyspeck arcV is the same as angle even in degenerate cases. *) +(* ------------------------------------------------------------------------- *) + +let arcV = new_definition + `arcV u v w = acs (( (v - u) dot (w - u))/((norm (v-u)) * (norm (w-u))))`;; + +let ARCV_ANGLE = prove + (`!u v w:real^N. arcV u v w = angle(v,u,w)`, + REPEAT GEN_TAC THEN REWRITE_TAC[arcV; angle; vector_angle] THEN + REWRITE_TAC[VECTOR_SUB_EQ] THEN + ASM_CASES_TAC `v:real^N = u` THEN + ASM_REWRITE_TAC[VECTOR_SUB_REFL; NORM_0; DOT_LZERO] THEN + REWRITE_TAC[real_div; REAL_MUL_LZERO; ACS_0] THEN + ASM_CASES_TAC `w:real^N = u` THEN + ASM_REWRITE_TAC[VECTOR_SUB_REFL; NORM_0; DOT_RZERO] THEN + REWRITE_TAC[real_div; REAL_MUL_LZERO; ACS_0]);; + +let ARCV_LINEAR_IMAGE_EQ = prove + (`!f a b c. + linear f /\ (!x. norm(f x) = norm x) + ==> arcV (f a) (f b) (f c) = arcV a b c`, + REWRITE_TAC[ARCV_ANGLE; ANGLE_LINEAR_IMAGE_EQ]);; + +add_linear_invariants [ARCV_LINEAR_IMAGE_EQ];; + +let ARCV_TRANSLATION_EQ = prove + (`!a b c d. arcV (a + b) (a + c) (a + d) = arcV b c d`, + REWRITE_TAC[ARCV_ANGLE; ANGLE_TRANSLATION_EQ]);; + +add_translation_invariants [ARCV_TRANSLATION_EQ];; + +(* ------------------------------------------------------------------------- *) +(* Azimuth angle. *) +(* ------------------------------------------------------------------------- *) + +let AZIM_EXISTS = prove + (`!v w w1 w2. + ?theta. &0 <= theta /\ theta < &2 * pi /\ + ?h1 h2. + !e1 e2 e3. + orthonormal e1 e2 e3 /\ + dist(w,v) % e3 = w - v /\ + ~(w = v) + ==> ?psi r1 r2. + w1 - v = (r1 * cos psi) % e1 + + (r1 * sin psi) % e2 + + h1 % (w - v) /\ + w2 - v = (r2 * cos (psi + theta)) % e1 + + (r2 * sin (psi + theta)) % e2 + + h2 % (w - v) /\ + (~collinear {v, w, w1} ==> &0 < r1) /\ + (~collinear {v, w, w2} ==> &0 < r2)`, + let lemma = prove + (`cos(p) % e + sin(p) % rotate2d (pi / &2) e = rotate2d p e`, + SIMP_TAC[CART_EQ; VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT; + FORALL_2; rotate2d; LAMBDA_BETA; DIMINDEX_2; ARITH; VECTOR_2] THEN + REWRITE_TAC[SIN_PI2; COS_PI2] THEN REAL_ARITH_TAC) in + GEN_GEOM_ORIGIN_TAC `v:real^3` ["e1"; "e2"; "e3"] THEN + REWRITE_TAC[VECTOR_SUB_RZERO; DIST_0] THEN + REPEAT GEN_TAC THEN REWRITE_TAC[RIGHT_AND_EXISTS_THM] THEN + GEN_REWRITE_TAC I [SWAP_EXISTS_THM] THEN + EXISTS_TAC `(w dot (w1:real^3)) / (w dot w)` THEN + GEN_REWRITE_TAC I [SWAP_EXISTS_THM] THEN + EXISTS_TAC `(w dot (w2:real^3)) / (w dot w)` THEN + GEOM_BASIS_MULTIPLE_TAC 3 `w:real^3` THEN + X_GEN_TAC `w:real` THEN GEN_REWRITE_TAC LAND_CONV + [REAL_ARITH `&0 <= w <=> w = &0 \/ &0 < w`] THEN + STRIP_TAC THENL + [ASM_REWRITE_TAC[VECTOR_MUL_LZERO; VECTOR_MUL_RZERO; NORM_0] THEN + EXISTS_TAC `&0` THEN MP_TAC PI_POS THEN REAL_ARITH_TAC; + ALL_TAC] THEN + SIMP_TAC[DOT_LMUL; NORM_MUL; DIMINDEX_3; ARITH; DOT_RMUL; DOT_BASIS; + VECTOR_MUL_COMPONENT; NORM_BASIS; BASIS_COMPONENT] THEN + REWRITE_TAC[VECTOR_MUL_ASSOC; REAL_MUL_RID] THEN + ASM_SIMP_TAC[REAL_FIELD `&0 < w ==> (w * x) / (w * w) * w = x`; + REAL_ARITH `&0 < w ==> abs w = w`] THEN + ASM_REWRITE_TAC[VECTOR_ARITH + `a % x:real^3 = a % y <=> a % (x - y) = vec 0`] THEN + ASM_SIMP_TAC[VECTOR_MUL_EQ_0; REAL_LT_IMP_NZ; BASIS_NONZERO; + DIMINDEX_3; ARITH; VECTOR_SUB_EQ] THEN + REWRITE_TAC[MESON[] `(!e3. p e3 /\ e3 = a ==> q e3) <=> p a ==> q a`] THEN + ONCE_REWRITE_TAC[VECTOR_ARITH `x:real^3 = a + b + c <=> x - c = a + b`] THEN + REPEAT GEN_TAC THEN + ABBREV_TAC `v1:real^3 = w1 - (w1$3) % basis 3` THEN + ABBREV_TAC `v2:real^3 = w2 - (w2$3) % basis 3` THEN + SUBGOAL_THEN + `(collinear{vec 0, w % basis 3, w1} <=> + w1 - w1$3 % basis 3:real^3 = vec 0) /\ + (collinear{vec 0, w % basis 3, w2} <=> + w2 - w2$3 % basis 3:real^3 = vec 0)` + (fun th -> REWRITE_TAC[th]) + THENL + [ASM_SIMP_TAC[COLLINEAR_LEMMA; VECTOR_MUL_EQ_0; REAL_LT_IMP_NZ; + BASIS_NONZERO; DIMINDEX_3; ARITH] THEN + MAP_EVERY EXPAND_TAC ["v1"; "v2"] THEN + SIMP_TAC[CART_EQ; VEC_COMPONENT; VECTOR_ADD_COMPONENT; FORALL_3; + VECTOR_MUL_COMPONENT; BASIS_COMPONENT; DIMINDEX_3; ARITH; + VECTOR_SUB_COMPONENT; REAL_MUL_RZERO; REAL_MUL_RID; + REAL_SUB_RZERO] THEN + REWRITE_TAC[RIGHT_EXISTS_AND_THM] THEN + CONV_TAC(BINOP_CONV(BINOP_CONV(ONCE_DEPTH_CONV SYM_CONV))) THEN + ASM_SIMP_TAC[GSYM REAL_EQ_RDIV_EQ; EXISTS_REFL] THEN REAL_ARITH_TAC; + ALL_TAC] THEN + ASM_REWRITE_TAC[] THEN + SUBGOAL_THEN `(v1:real^3)$3 = &0 /\ (v2:real^3)$3 = &0` MP_TAC THENL + [MAP_EVERY EXPAND_TAC ["v1"; "v2"] THEN + REWRITE_TAC[VECTOR_SUB_COMPONENT; VECTOR_MUL_COMPONENT; VECTOR_SUB_EQ] THEN + SIMP_TAC[BASIS_COMPONENT; DIMINDEX_3; ARITH] THEN REAL_ARITH_TAC; + ALL_TAC] THEN + MAP_EVERY (fun t -> SPEC_TAC(t,t)) [`v2:real^3`; `v1:real^3`] THEN + POP_ASSUM_LIST(K ALL_TAC) THEN REWRITE_TAC[orthonormal] THEN + SIMP_TAC[DOT_BASIS; BASIS_COMPONENT; DIMINDEX_3; ARITH] THEN + ONCE_REWRITE_TAC[TAUT `a /\ b /\ c /\ d /\ e /\ f <=> + d /\ e /\ a /\ b /\ c /\ f`] THEN + REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN + PAD2D3D_TAC THEN REPEAT STRIP_TAC THEN + SIMP_TAC[cross; VECTOR_3; pad2d3d; LAMBDA_BETA; DIMINDEX_3; ARITH] THEN + REWRITE_TAC[IMP_IMP; GSYM CONJ_ASSOC] THEN + ASM_CASES_TAC `v1:real^2 = vec 0` THEN ASM_REWRITE_TAC[NORM_POS_LT] THENL + [MP_TAC(ISPECL [`basis 1:real^2`; `v2:real^2`] + ROTATION_ROTATE2D_EXISTS_GEN) THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `t:real` THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`e1:real^2`; `basis 1:real^2`] + ROTATION_ROTATE2D_EXISTS_GEN) THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `p:real` THEN STRIP_TAC THEN + MAP_EVERY EXISTS_TAC [`&0`; `norm(v2:real^2)`] THEN + ASM_REWRITE_TAC[NORM_POS_LT] THEN + REWRITE_TAC[REAL_MUL_LZERO; VECTOR_MUL_LZERO; VECTOR_ADD_RID] THEN + SUBGOAL_THEN `norm(e1:real^2) = &1 /\ norm(e2:real^2) = &1` + STRIP_ASSUME_TAC THENL [ASM_REWRITE_TAC[NORM_EQ_1]; ALL_TAC] THEN + SUBGOAL_THEN `e2 = rotate2d (pi / &2) e1` SUBST1_TAC THENL + [MATCH_MP_TAC ROTATION_ROTATE2D_EXISTS_ORTHOGONAL_ORIENTED THEN + ASM_REWRITE_TAC[NORM_EQ_1; orthogonal]; + ALL_TAC] THEN + REWRITE_TAC[GSYM VECTOR_MUL_ASSOC; GSYM VECTOR_ADD_LDISTRIB] THEN + REWRITE_TAC[lemma] THEN ONCE_REWRITE_TAC[REAL_ADD_SYM] THEN + REWRITE_TAC[ROTATE2D_ADD] THEN ASM_REWRITE_TAC[VECTOR_MUL_LID] THEN + MATCH_MP_TAC VECTOR_MUL_LCANCEL_IMP THEN + EXISTS_TAC `norm(basis 1:real^2)` THEN + ASM_SIMP_TAC[NORM_EQ_0; BASIS_NONZERO; DIMINDEX_2; ARITH] THEN + FIRST_X_ASSUM(fun th -> GEN_REWRITE_TAC LAND_CONV [SYM th]) THEN + ONCE_REWRITE_TAC[VECTOR_ARITH `a % b % x:real^2 = b % a % x`] THEN + AP_TERM_TAC THEN + SIMP_TAC[GSYM(MATCH_MP LINEAR_CMUL (SPEC_ALL LINEAR_ROTATE2D))] THEN + AP_TERM_TAC THEN + ASM_SIMP_TAC[LINEAR_CMUL; LINEAR_ROTATE2D; VECTOR_MUL_LID]; + MP_TAC(ISPECL [`v1:real^2`; `v2:real^2`] ROTATION_ROTATE2D_EXISTS_GEN) THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `t:real` THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`e1:real^2`; `v1:real^2`] ROTATION_ROTATE2D_EXISTS_GEN) THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `p:real` THEN STRIP_TAC THEN + MAP_EVERY EXISTS_TAC [`norm(v1:real^2)`; `norm(v2:real^2)`] THEN + ASM_REWRITE_TAC[NORM_POS_LT] THEN + SUBGOAL_THEN `norm(e1:real^2) = &1 /\ norm(e2:real^2) = &1` + STRIP_ASSUME_TAC THENL [ASM_REWRITE_TAC[NORM_EQ_1]; ALL_TAC] THEN + SUBGOAL_THEN `e2 = rotate2d (pi / &2) e1` SUBST1_TAC THENL + [MATCH_MP_TAC ROTATION_ROTATE2D_EXISTS_ORTHOGONAL_ORIENTED THEN + ASM_REWRITE_TAC[NORM_EQ_1; orthogonal]; + ALL_TAC] THEN + REWRITE_TAC[GSYM VECTOR_MUL_ASSOC; GSYM VECTOR_ADD_LDISTRIB] THEN + REWRITE_TAC[lemma] THEN ONCE_REWRITE_TAC[REAL_ADD_SYM] THEN + REWRITE_TAC[ROTATE2D_ADD] THEN ASM_REWRITE_TAC[VECTOR_MUL_LID] THEN + MATCH_MP_TAC VECTOR_MUL_LCANCEL_IMP THEN EXISTS_TAC `norm(v1:real^2)` THEN + ASM_REWRITE_TAC[NORM_EQ_0] THEN + FIRST_X_ASSUM(fun th -> GEN_REWRITE_TAC LAND_CONV [SYM th]) THEN + ONCE_REWRITE_TAC[VECTOR_ARITH `a % b % x:real^2 = b % a % x`] THEN + AP_TERM_TAC THEN + SIMP_TAC[GSYM(MATCH_MP LINEAR_CMUL (SPEC_ALL LINEAR_ROTATE2D))] THEN + AP_TERM_TAC THEN + ASM_SIMP_TAC[LINEAR_CMUL; LINEAR_ROTATE2D; VECTOR_MUL_LID]]);; + +let azim_spec = + (REWRITE_RULE[SKOLEM_THM] + (REWRITE_RULE[RIGHT_EXISTS_IMP_THM] AZIM_EXISTS));; + +let azim_def = new_definition + `azim v w w1 w2 = + if collinear {v,w,w1} \/ collinear {v,w,w2} then &0 + else @theta. &0 <= theta /\ theta < &2 * pi /\ + ?h1 h2. + !e1 e2 e3. + orthonormal e1 e2 e3 /\ + dist(w,v) % e3 = w - v /\ + ~(w = v) + ==> ?psi r1 r2. + w1 - v = (r1 * cos psi) % e1 + + (r1 * sin psi) % e2 + + h1 % (w - v) /\ + w2 - v = (r2 * cos (psi + theta)) % e1 + + (r2 * sin (psi + theta)) % e2 + + h2 % (w - v) /\ + &0 < r1 /\ &0 < r2`;; + +let azim = prove + (`!v w w1 w2:real^3. + &0 <= azim v w w1 w2 /\ azim v w w1 w2 < &2 * pi /\ + ?h1 h2. + !e1 e2 e3. + orthonormal e1 e2 e3 /\ + dist(w,v) % e3 = w - v /\ + ~(w = v) + ==> ?psi r1 r2. + w1 - v = (r1 * cos psi) % e1 + + (r1 * sin psi) % e2 + + h1 % (w - v) /\ + w2 - v = (r2 * cos (psi + azim v w w1 w2)) % e1 + + (r2 * sin (psi + azim v w w1 w2)) % e2 + + h2 % (w - v) /\ + (~collinear {v, w, w1} ==> &0 < r1) /\ + (~collinear {v, w, w2} ==> &0 < r2)`, + REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[azim_def] THEN + COND_CASES_TAC THENL + [ALL_TAC; + RULE_ASSUM_TAC(REWRITE_RULE[DE_MORGAN_THM]) THEN ASM_REWRITE_TAC[] THEN + CONV_TAC SELECT_CONV THEN + MP_TAC(ISPECL [`v:real^3`; `w:real^3`; `w1:real^3`; `w2:real^3`] + AZIM_EXISTS) THEN + ASM_REWRITE_TAC[]] THEN + SIMP_TAC[PI_POS; REAL_LT_MUL; REAL_OF_NUM_LT; ARITH; REAL_LE_REFL] THEN + FIRST_X_ASSUM DISJ_CASES_TAC THENL + [MP_TAC(ISPECL [`v:real^3`; `w:real^3`; `w2:real^3`; `w1:real^3`] + AZIM_EXISTS) THEN + DISCH_THEN(CHOOSE_THEN(MP_TAC o CONJUNCT2 o CONJUNCT2)) THEN + REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`h2:real`; `h1:real`] THEN + DISCH_TAC THEN MAP_EVERY EXISTS_TAC [`h1:real`; `h2:real`] THEN + MAP_EVERY X_GEN_TAC [`e1:real^3`; `e2:real^3`; `e3:real^3`] THEN + STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`e1:real^3`; `e2:real^3`; `e3:real^3`]) THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC MONO_EXISTS THEN + X_GEN_TAC `psi:real` THEN + REWRITE_TAC[LEFT_IMP_EXISTS_THM; REAL_ADD_RID] THEN + MAP_EVERY X_GEN_TAC [`r2:real`; `r1:real`] THEN STRIP_TAC THEN + MAP_EVERY EXISTS_TAC [`&0`; `r2:real`]; + MP_TAC(ISPECL [`v:real^3`; `w:real^3`; `w1:real^3`; `w2:real^3`] + AZIM_EXISTS) THEN + DISCH_THEN(CHOOSE_THEN(MP_TAC o CONJUNCT2 o CONJUNCT2)) THEN + REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`h1:real`; `h2:real`] THEN + DISCH_TAC THEN MAP_EVERY EXISTS_TAC [`h1:real`; `h2:real`] THEN + MAP_EVERY X_GEN_TAC [`e1:real^3`; `e2:real^3`; `e3:real^3`] THEN + STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`e1:real^3`; `e2:real^3`; `e3:real^3`]) THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC MONO_EXISTS THEN + X_GEN_TAC `psi:real` THEN + REWRITE_TAC[LEFT_IMP_EXISTS_THM; REAL_ADD_RID] THEN + MAP_EVERY X_GEN_TAC [`r1:real`; `r2:real`] THEN STRIP_TAC THEN + MAP_EVERY EXISTS_TAC [`r1:real`; `&0`]] THEN + ASM_REWRITE_TAC[] THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE RAND_CONV + [SET_RULE `{v,w,x} = {w,v,x}`]) THEN + ONCE_REWRITE_TAC[COLLINEAR_3] THEN ASM_REWRITE_TAC[] THEN + UNDISCH_THEN `dist(w:real^3,v) % e3 = w - v` (SUBST1_TAC o SYM) THEN + REWRITE_TAC[GSYM DOT_CAUCHY_SCHWARZ_EQUAL] THEN + RULE_ASSUM_TAC(REWRITE_RULE[orthonormal]) THEN + ASM_REWRITE_TAC[DOT_LADD; DOT_RADD; DOT_LMUL; DOT_RMUL; REAL_MUL_RZERO] THEN + ONCE_REWRITE_TAC[DOT_SYM] THEN ASM_REWRITE_TAC[REAL_MUL_RZERO] THEN + REWRITE_TAC[REAL_ADD_LID; REAL_ADD_RID; REAL_MUL_RID] THEN + REWRITE_TAC[REAL_ARITH `(r * c) * (r * c):real = r pow 2 * c pow 2`] THEN + REWRITE_TAC[REAL_ARITH `r * c + r * s + f:real = r * (s + c) + f`] THEN + REWRITE_TAC[SIN_CIRCLE] THEN REWRITE_TAC[REAL_RING + `(d * h * d) pow 2 = (d * d) * (r * &1 + h * d * h * d) <=> + d = &0 \/ r = &0`] THEN + ASM_REWRITE_TAC[DIST_EQ_0; REAL_POW_EQ_0; ARITH] THEN + DISCH_THEN SUBST1_TAC THEN REWRITE_TAC[REAL_MUL_LZERO; DOT_LZERO]);; + +let AZIM_UNIQUE = prove + (`!v w w1 w2 h1 h2 r1 r2 e1 e2 e3 psi theta. + &0 <= theta /\ + theta < &2 * pi /\ + orthonormal e1 e2 e3 /\ + dist(w,v) % e3 = w - v /\ + ~(w = v) /\ + &0 < r1 /\ &0 < r2 /\ + w1 - v = (r1 * cos psi) % e1 + + (r1 * sin psi) % e2 + + h1 % (w - v) /\ + w2 - v = (r2 * cos (psi + theta)) % e1 + + (r2 * sin (psi + theta)) % e2 + + h2 % (w - v) + ==> azim v w w1 w2 = theta`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN `~collinear{v:real^3,w,w2} /\ ~collinear {v,w,w1}` + STRIP_ASSUME_TAC THENL + [ONCE_REWRITE_TAC[SET_RULE `{a,b,c} = {b,a,c}`] THEN + ONCE_REWRITE_TAC[COLLINEAR_3] THEN REWRITE_TAC[COLLINEAR_LEMMA] THEN + ASM_REWRITE_TAC[] THEN ASM_REWRITE_TAC[VECTOR_SUB_EQ] THEN + UNDISCH_THEN `dist(w:real^3,v) % e3 = w - v` (SUBST1_TAC o SYM) THEN + REWRITE_TAC[VECTOR_MUL_ASSOC; VECTOR_ARITH + `a + b + c % x:real^N = d % x <=> a + b + (c - d) % x = vec 0`] THEN + ASM_SIMP_TAC[ORTHONORMAL_IMP_INDEPENDENT_EXPLICIT_0] THEN + ASM_SIMP_TAC[CONJ_ASSOC; REAL_LT_IMP_NZ; SIN_CIRCLE; REAL_RING + `s pow 2 + c pow 2 = &1 ==> (r * c = &0 /\ r * s = &0 <=> r = &0)`]; + ALL_TAC] THEN + SUBGOAL_THEN `(azim v w w1 w2 - theta) / (&2 * pi) = &0` MP_TAC THENL + [ALL_TAC; MP_TAC PI_POS THEN CONV_TAC REAL_FIELD] THEN + MATCH_MP_TAC REAL_EQ_INTEGERS_IMP THEN + ASM_SIMP_TAC[REAL_SUB_RZERO; REAL_ABS_DIV; REAL_ABS_MUL; REAL_ABS_NUM; + REAL_ABS_PI; REAL_LT_LDIV_EQ; REAL_LT_MUL; REAL_OF_NUM_LT; ARITH; + PI_POS; INTEGER_CLOSED; REAL_MUL_LID] THEN + MP_TAC(ISPECL [`v:real^3`; `w:real^3`; `w1:real^3`; `w2:real^3`] azim) THEN + ASM_REWRITE_TAC[] THEN + REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + ASM_SIMP_TAC[REAL_ARITH + `&0 <= x /\ x < k /\ &0 <= y /\ y < k ==> abs(x - y) < k`] THEN + REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`k1:real`; `k2:real`] THEN + DISCH_THEN(MP_TAC o SPECL [`e1:real^3`; `e2:real^3`; `e3:real^3`]) THEN + ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`phi:real`; `s1:real`; `s2:real`] THEN + UNDISCH_THEN `dist(w:real^3,v) % e3 = w - v` (SUBST1_TAC o SYM) THEN + REWRITE_TAC[VECTOR_MUL_ASSOC] THEN + ASM_SIMP_TAC[ORTHONORMAL_IMP_INDEPENDENT_EXPLICIT] THEN + ONCE_REWRITE_TAC[TAUT `a /\ b /\ c /\ d <=> (c /\ d) /\ a /\ b`] THEN + DISCH_THEN(CONJUNCTS_THEN2 STRIP_ASSUME_TAC MP_TAC) THEN + DISCH_THEN(CONJUNCTS_THEN (MP_TAC o MATCH_MP (REAL_FIELD + `r * c = r' * c' /\ r * s = r' * s' /\ u:real = v + ==> s pow 2 + c pow 2 = &1 /\ s' pow 2 + c' pow 2 = &1 /\ + &0 < r /\ (r pow 2 = r' pow 2 ==> r = r') + ==> s = s' /\ c = c'`))) THEN + ASM_REWRITE_TAC[SIN_CIRCLE; GSYM REAL_EQ_SQUARE_ABS] THEN + ASM_SIMP_TAC[REAL_ARITH + `&0 < x /\ &0 < y ==> (abs x = abs y <=> x = y)`] THEN + REWRITE_TAC[SIN_COS_EQ] THEN + REWRITE_TAC[REAL_ARITH + `psi + theta = (phi + az) + x:real <=> psi = phi + x + (az - theta)`] THEN + DISCH_THEN(X_CHOOSE_THEN `m:real` STRIP_ASSUME_TAC) THEN + ASM_REWRITE_TAC[REAL_EQ_ADD_LCANCEL] THEN + REWRITE_TAC[REAL_ARITH + `&2 * m * pi + x = &2 * n * pi <=> x = (n - m) * &2 * pi`] THEN + DISCH_THEN(X_CHOOSE_THEN `n:real` STRIP_ASSUME_TAC) THEN + ASM_SIMP_TAC[PI_POS; REAL_FIELD `&0 < pi ==> (x * &2 * pi) / (&2 * pi) = x`; + INTEGER_CLOSED]);; + +let AZIM_TRANSLATION = prove + (`!a v w w1 w2. azim (a + v) (a + w) (a + w1) (a + w2) = azim v w w1 w2`, + REPEAT GEN_TAC THEN REWRITE_TAC[azim_def] THEN + REWRITE_TAC[VECTOR_ARITH `(a + w) - (a + v):real^3 = w - v`; + VECTOR_ARITH `a + w:real^3 = a + v <=> w = v`; + NORM_ARITH `dist(a + v,a + w) = dist(v,w)`] THEN + REWRITE_TAC[SET_RULE + `{a + x,a + y,a + z} = IMAGE (\x:real^3. a + x) {x,y,z}`] THEN + REWRITE_TAC[COLLINEAR_TRANSLATION_EQ]);; + +add_translation_invariants [AZIM_TRANSLATION];; + +let AZIM_LINEAR_IMAGE = prove + (`!f. linear f /\ (!x. norm(f x) = norm x) /\ + (2 <= dimindex(:3) ==> det(matrix f) = &1) + ==> !v w w1 w2. azim (f v) (f w) (f w1) (f w2) = azim v w w1 w2`, + REPEAT STRIP_TAC THEN REWRITE_TAC[azim_def] THEN + ASM_SIMP_TAC[GSYM LINEAR_SUB; dist] THEN + MP_TAC(ISPEC `f:real^3->real^3` QUANTIFY_SURJECTION_THM) THEN + ANTS_TAC THENL + [ASM_MESON_TAC[ORTHOGONAL_TRANSFORMATION; + ORTHOGONAL_TRANSFORMATION_SURJECTIVE]; + ALL_TAC] THEN + DISCH_THEN(CONV_TAC o LAND_CONV o EXPAND_QUANTS_CONV) THEN + ASM_SIMP_TAC[ORTHONORMAL_LINEAR_IMAGE] THEN + ASM_SIMP_TAC[GSYM LINEAR_CMUL; GSYM LINEAR_ADD] THEN + SUBGOAL_THEN `!x y. (f:real^3->real^3) x = f y <=> x = y` ASSUME_TAC THENL + [ASM_MESON_TAC[PRESERVES_NORM_INJECTIVE]; ALL_TAC] THEN + ASM_REWRITE_TAC[] THEN + REWRITE_TAC[SET_RULE `{f x,f y,f z} = IMAGE f {x,y,z}`] THEN + ASM_SIMP_TAC[COLLINEAR_LINEAR_IMAGE_EQ]);; + +add_linear_invariants [AZIM_LINEAR_IMAGE];; + +let AZIM_DEGENERATE = prove + (`(!v w w1 w2. v = w ==> azim v w w1 w2 = &0) /\ + (!v w w1 w2. collinear{v,w,w1} ==> azim v w w1 w2 = &0) /\ + (!v w w1 w2. collinear{v,w,w2} ==> azim v w w1 w2 = &0)`, + REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[azim_def] THEN + ASM_REWRITE_TAC[] THEN REWRITE_TAC[INSERT_AC; COLLINEAR_2]);; + +let AZIM_REFL_ALT = prove + (`!v x y. azim v v x y = &0`, + REPEAT GEN_TAC THEN MATCH_MP_TAC(last(CONJUNCTS AZIM_DEGENERATE)) THEN + REWRITE_TAC[COLLINEAR_2; INSERT_AC]);; + +let AZIM_SPECIAL_SCALE = prove + (`!a v w1 w2. + &0 < a + ==> azim (vec 0) (a % v) w1 w2 = azim (vec 0) v w1 w2`, + REPEAT STRIP_TAC THEN REWRITE_TAC[azim_def] THEN + REWRITE_TAC[VECTOR_SUB_RZERO; DIST_0] THEN + FIRST_ASSUM(MP_TAC o MATCH_MP(MESON[REAL_LT_IMP_NZ; REAL_DIV_LMUL] + `!a. &0 < a ==> (!y. ?x. a * x = y)`)) THEN + DISCH_THEN(MP_TAC o MATCH_MP QUANTIFY_SURJECTION_THM) THEN + DISCH_THEN(CONV_TAC o RAND_CONV o + PARTIAL_EXPAND_QUANTS_CONV ["psi"; "r1"; "r2"]) THEN + REWRITE_TAC[VECTOR_MUL_ASSOC; REAL_MUL_SYM] THEN + ASM_SIMP_TAC[VECTOR_MUL_EQ_0; REAL_LT_IMP_NZ] THEN + ASM_SIMP_TAC[NORM_MUL; REAL_ARITH `&0 < a ==> abs a = a`] THEN + REWRITE_TAC[GSYM VECTOR_MUL_ASSOC] THEN + REWRITE_TAC[VECTOR_ARITH `a % x:real^3 = a % y <=> a % (x - y) = vec 0`] THEN + ASM_SIMP_TAC[REAL_LT_IMP_NZ; VECTOR_MUL_EQ_0] THEN + REWRITE_TAC[VECTOR_SUB_EQ] THEN + ASM_SIMP_TAC[COLLINEAR_SPECIAL_SCALE; REAL_LT_IMP_NZ]);; + +let AZIM_SCALE_ALL = prove + (`!a v w1 w2. + &0 < a /\ &0 < b /\ &0 < c + ==> azim (vec 0) (a % v) (b % w1) (c % w2) = azim (vec 0) v w1 w2`, + let lemma = MESON[REAL_LT_IMP_NZ; REAL_DIV_LMUL] + `!a. &0 < a ==> (!y. ?x. a * x = y)` in + let SCALE_QUANT_TAC side asm avoid = + MP_TAC(MATCH_MP lemma (ASSUME asm)) THEN + DISCH_THEN(MP_TAC o MATCH_MP QUANTIFY_SURJECTION_THM) THEN + DISCH_THEN(CONV_TAC o side o PARTIAL_EXPAND_QUANTS_CONV avoid) in + REPEAT STRIP_TAC THEN + ASM_SIMP_TAC[azim_def; COLLINEAR_SCALE_ALL; REAL_LT_IMP_NZ] THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[VECTOR_SUB_RZERO] THEN + ASM_SIMP_TAC[DIST_0; NORM_MUL; GSYM VECTOR_MUL_ASSOC] THEN + ASM_SIMP_TAC[REAL_ARITH `&0 < a ==> abs a = a`; VECTOR_MUL_LCANCEL] THEN + ASM_SIMP_TAC[VECTOR_MUL_EQ_0; REAL_LT_IMP_NZ] THEN + SCALE_QUANT_TAC RAND_CONV `&0 < a` ["psi"; "r1"; "r2"] THEN + SCALE_QUANT_TAC LAND_CONV `&0 < b` ["psi"; "h2"; "r2"] THEN + SCALE_QUANT_TAC LAND_CONV `&0 < c` ["psi"; "h1"; "r1"] THEN + ASM_SIMP_TAC[GSYM VECTOR_MUL_ASSOC; GSYM VECTOR_ADD_LDISTRIB; + VECTOR_MUL_LCANCEL; REAL_LT_IMP_NZ; REAL_LT_MUL_EQ] THEN + REWRITE_TAC[VECTOR_MUL_ASSOC; REAL_MUL_AC]);; + +let AZIM_ARG = prove + (`!x y:real^3. azim (vec 0) (basis 3) x y = Arg(dropout 3 y / dropout 3 x)`, + let lemma = prove + (`(r * cos t) % basis 1 + (r * sin t) % basis 2 = Cx r * cexp(ii * Cx t)`, + REWRITE_TAC[CEXP_EULER; COMPLEX_BASIS; GSYM CX_SIN; GSYM CX_COS; + COMPLEX_CMUL; CX_MUL] THEN + CONV_TAC COMPLEX_RING) in + REPEAT STRIP_TAC THEN + ASM_CASES_TAC `collinear {vec 0:real^3,basis 3,x}` THENL + [ASM_SIMP_TAC[AZIM_DEGENERATE] THEN + RULE_ASSUM_TAC(REWRITE_RULE[COLLINEAR_BASIS_3]) THEN + ASM_REWRITE_TAC[COMPLEX_VEC_0; complex_div; COMPLEX_INV_0; + COMPLEX_MUL_RZERO; ARG_0]; + ALL_TAC] THEN + ASM_CASES_TAC `collinear {vec 0:real^3,basis 3,y}` THENL + [ASM_SIMP_TAC[AZIM_DEGENERATE] THEN + RULE_ASSUM_TAC(REWRITE_RULE[COLLINEAR_BASIS_3]) THEN + ASM_REWRITE_TAC[COMPLEX_VEC_0; complex_div; COMPLEX_MUL_LZERO; ARG_0]; + ALL_TAC] THEN + MP_TAC(ISPECL [`vec 0:real^3`; `basis 3:real^3`; `x:real^3`; `y:real^3`] + azim) THEN + ABBREV_TAC `a = azim (vec 0) (basis 3) x (y:real^3)` THEN + REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM; VECTOR_SUB_RZERO; DIST_0] THEN + MAP_EVERY X_GEN_TAC [`h1:real`; `h2:real`] THEN + DISCH_THEN(MP_TAC o SPECL + [`basis 1:real^3`; `basis 2:real^3`; `basis 3:real^3`]) THEN + SIMP_TAC[orthonormal; DOT_BASIS_BASIS; CROSS_BASIS; DIMINDEX_3; NORM_BASIS; + ARITH; VECTOR_MUL_LID; BASIS_NONZERO; REAL_LT_01; LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`psi:real`; `r1:real`; `r2:real`] THEN + DISCH_THEN(STRIP_ASSUME_TAC o GSYM) THEN + REWRITE_TAC[DROPOUT_ADD; DROPOUT_MUL; DROPOUT_BASIS_3] THEN + REWRITE_TAC[VECTOR_MUL_RZERO; VECTOR_ADD_RID; lemma] THEN + REWRITE_TAC[complex_div; COMPLEX_INV_MUL] THEN + ONCE_REWRITE_TAC[COMPLEX_RING + `(a * b) * (c * d):complex = (a * c) * b * d`] THEN + REWRITE_TAC[GSYM complex_div; GSYM CX_DIV; GSYM CEXP_SUB] THEN + CONV_TAC SYM_CONV THEN MATCH_MP_TAC ARG_UNIQUE THEN + EXISTS_TAC `r2 / r1:real` THEN ASM_SIMP_TAC[REAL_LT_DIV] THEN + AP_TERM_TAC THEN AP_TERM_TAC THEN REWRITE_TAC[CX_ADD] THEN + CONV_TAC COMPLEX_RING);; + +let REAL_CONTINUOUS_AT_AZIM_SHARP = prove + (`!v w w1 w2. + ~collinear{v,w,w1} /\ ~(w2 IN aff_ge {v,w} {w1}) + ==> (azim v w w1) real_continuous at w2`, + GEOM_ORIGIN_TAC `v:real^3` THEN + GEOM_BASIS_MULTIPLE_TAC 3 `w:real^3` THEN + X_GEN_TAC `w:real` THEN ASM_CASES_TAC `w = &0` THENL + [ASM_REWRITE_TAC[VECTOR_MUL_LZERO; INSERT_AC; COLLINEAR_2]; ALL_TAC] THEN + ASM_SIMP_TAC[REAL_LE_LT; COLLINEAR_SPECIAL_SCALE] THEN + DISCH_TAC THEN REPEAT GEN_TAC THEN + REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + W(MP_TAC o PART_MATCH (lhs o rand) AFF_GE_SPECIAL_SCALE o + rand o rand o lhand o snd) THEN + ASM_REWRITE_TAC[FINITE_INSERT; FINITE_EMPTY; IN_SING] THEN ANTS_TAC THENL + [POP_ASSUM_LIST(MP_TAC o end_itlist CONJ) THEN + ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN REWRITE_TAC[DE_MORGAN_THM] THEN + DISCH_THEN(STRIP_ASSUME_TAC o GSYM) THENL + [ASM_REWRITE_TAC[COLLINEAR_2; INSERT_AC]; + ASM_REWRITE_TAC[COLLINEAR_2; INSERT_AC]; + ASM_SIMP_TAC[COLLINEAR_LEMMA_ALT; BASIS_NONZERO; DIMINDEX_3; ARITH] THEN + MESON_TAC[]]; + DISCH_THEN SUBST1_TAC THEN DISCH_TAC] THEN + ASM_SIMP_TAC[AZIM_SPECIAL_SCALE; AZIM_ARG] THEN + MATCH_MP_TAC(REWRITE_RULE[o_DEF] + REAL_CONTINUOUS_CONTINUOUS_AT_COMPOSE) THEN + CONJ_TAC THENL + [REWRITE_TAC[complex_div] THEN MATCH_MP_TAC CONTINUOUS_COMPLEX_MUL THEN + REWRITE_TAC[CONTINUOUS_CONST; ETA_AX] THEN + SIMP_TAC[LINEAR_CONTINUOUS_AT; LINEAR_DROPOUT; DIMINDEX_3; DIMINDEX_2; + ARITH]; + ALL_TAC] THEN + MATCH_MP_TAC REAL_CONTINUOUS_AT_WITHIN THEN + MATCH_MP_TAC REAL_CONTINUOUS_AT_ARG THEN + MP_TAC(ISPECL [`w2:real^3`; `w1:real^3`] AFF_GE_2_1_0_DROPOUT_3) THEN + ASM_REWRITE_TAC[] THEN + REPEAT(FIRST_X_ASSUM(MP_TAC o + GEN_REWRITE_RULE RAND_CONV [COLLINEAR_BASIS_3])) THEN + SPEC_TAC(`(dropout 3:real^3->real^2) w2`,`v2:real^2`) THEN + SPEC_TAC(`(dropout 3:real^3->real^2) w1`,`v1:real^2`) THEN + POP_ASSUM_LIST(K ALL_TAC) THEN + GEOM_BASIS_MULTIPLE_TAC 1 `v1:complex` THEN + X_GEN_TAC `w:real` THEN ASM_CASES_TAC `w = &0` THEN + ASM_REWRITE_TAC[VECTOR_MUL_LZERO] THEN + GEN_REWRITE_TAC LAND_CONV [REAL_LE_LT] THEN ASM_REWRITE_TAC[] THEN + DISCH_TAC THEN X_GEN_TAC `z:complex` THEN + DISCH_THEN(K ALL_TAC) THEN + REWRITE_TAC[CONTRAPOS_THM; COMPLEX_BASIS; COMPLEX_CMUL] THEN + REWRITE_TAC[COMPLEX_MUL_RID; RE_DIV_CX; IM_DIV_CX; real] THEN + ASM_SIMP_TAC[REAL_DIV_EQ_0; REAL_LE_RDIV_EQ; REAL_MUL_LZERO] THEN + STRIP_TAC THEN + W(MP_TAC o PART_MATCH (lhs o rand) AFF_GE_1_1_0 o rand o snd) THEN + ASM_REWRITE_TAC[COMPLEX_VEC_0; CX_INJ] THEN DISCH_THEN SUBST1_TAC THEN + REWRITE_TAC[IN_ELIM_THM] THEN EXISTS_TAC `Re z / w` THEN + ASM_SIMP_TAC[REAL_LE_DIV; REAL_LT_IMP_LE; COMPLEX_EQ] THEN + ASM_SIMP_TAC[COMPLEX_CMUL; CX_DIV; COMPLEX_DIV_RMUL; CX_INJ] THEN + REWRITE_TAC[RE_CX; IM_CX]);; + +let REAL_CONTINUOUS_AT_AZIM = prove + (`!v w w1 w2. ~coplanar{v,w,w1,w2} ==> (azim v w w1) real_continuous at w2`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_CONTINUOUS_AT_AZIM_SHARP THEN + CONJ_TAC THENL + [ASM_MESON_TAC[NOT_COPLANAR_NOT_COLLINEAR; INSERT_AC]; + DISCH_THEN(MP_TAC o MATCH_MP (REWRITE_RULE[SUBSET] + AFF_GE_SUBSET_AFFINE_HULL)) THEN + POP_ASSUM MP_TAC THEN REWRITE_TAC[coplanar; CONTRAPOS_THM] THEN + REWRITE_TAC[SET_RULE `{a,b} UNION {c} = {a,b,c}`] THEN + DISCH_TAC THEN MAP_EVERY EXISTS_TAC + [`v:real^3`; `w:real^3`; `w1:real^3`] THEN + SIMP_TAC[SET_RULE `{a,b,c,d} SUBSET s <=> {a,b,c} SUBSET s /\ d IN s`] THEN + ASM_REWRITE_TAC[HULL_SUBSET]]);; + +let AZIM_REFL = prove + (`!v0 v1 w. azim v0 v1 w w = &0`, + GEOM_ORIGIN_TAC `v0:real^3` THEN + GEOM_BASIS_MULTIPLE_TAC 3 `v1:real^3` THEN + GEN_TAC THEN + GEN_REWRITE_TAC LAND_CONV [REAL_ARITH `&0 <= x <=> x = &0 \/ &0 < x`] THEN + STRIP_TAC THEN ASM_SIMP_TAC[VECTOR_MUL_LZERO; AZIM_DEGENERATE] THEN + ASM_SIMP_TAC[AZIM_SPECIAL_SCALE; AZIM_ARG; ARG_EQ_0] THEN + X_GEN_TAC `w:real^3` THEN + ASM_CASES_TAC `(dropout 3 :real^3->real^2) w = Cx(&0)` THEN + ASM_SIMP_TAC[COMPLEX_DIV_REFL; REAL_CX; RE_CX; REAL_POS] THEN + ASM_SIMP_TAC[complex_div; COMPLEX_MUL_LZERO; REAL_CX; RE_CX; REAL_POS]);; + +let AZIM_EQ = prove + (`!v0 v1 w x y. + ~collinear{v0,v1,w} /\ ~collinear{v0,v1,x} /\ ~collinear{v0,v1,y} + ==> (azim v0 v1 w x = azim v0 v1 w y <=> y IN aff_gt {v0,v1} {x})`, + GEOM_ORIGIN_TAC `v0:real^3` THEN + GEOM_BASIS_MULTIPLE_TAC 3 `v1:real^3` THEN + GEN_TAC THEN + GEN_REWRITE_TAC LAND_CONV [REAL_ARITH `&0 <= x <=> x = &0 \/ &0 < x`] THEN + STRIP_TAC THENL + [ASM_REWRITE_TAC[VECTOR_MUL_LZERO; INSERT_AC; COLLINEAR_2]; ALL_TAC] THEN + ASM_SIMP_TAC[AZIM_SPECIAL_SCALE; REAL_LT_IMP_NZ; COLLINEAR_SPECIAL_SCALE] THEN + REPEAT STRIP_TAC THEN + W(MP_TAC o PART_MATCH (lhs o rand) AFF_GT_SPECIAL_SCALE o + rand o rand o snd) THEN + ANTS_TAC THENL + [ASM_REWRITE_TAC[IN_INSERT; FINITE_INSERT; FINITE_EMPTY; NOT_IN_EMPTY] THEN + REPEAT CONJ_TAC THEN DISCH_THEN(SUBST_ALL_TAC o SYM) THEN + TRY(RULE_ASSUM_TAC(REWRITE_RULE[INSERT_AC; COLLINEAR_2]) THEN + FIRST_X_ASSUM CONTR_TAC) THEN + UNDISCH_TAC `~collinear {vec 0:real^3, basis 3, v1 % basis 3}` THEN + REWRITE_TAC[COLLINEAR_LEMMA] THEN MESON_TAC[]; + DISCH_THEN SUBST1_TAC] THEN + REWRITE_TAC[AZIM_ARG] THEN CONV_TAC(LAND_CONV SYM_CONV) THEN + W(MP_TAC o PART_MATCH (lhs o rand) ARG_EQ o lhand o snd) THEN + RULE_ASSUM_TAC(REWRITE_RULE[COLLINEAR_BASIS_3]) THEN + ASM_REWRITE_TAC[complex_div; COMPLEX_ENTIRE; COMPLEX_INV_EQ_0] THEN + ASM_REWRITE_TAC[GSYM complex_div; GSYM COMPLEX_VEC_0] THEN + DISCH_THEN SUBST1_TAC THEN + ASM_SIMP_TAC[GSYM COMPLEX_VEC_0; COMPLEX_FIELD + `~(w = Cx(&0)) ==> (y / w = x * u / w <=> y = x * u)`] THEN + W(MP_TAC o PART_MATCH (lhs o rand) AFF_GT_2_1 o rand o rand o snd) THEN + ANTS_TAC THENL + [REWRITE_TAC[SET_RULE `DISJOINT {a,b} {x} <=> ~(x = a) /\ ~(x = b)`] THEN + ASM_MESON_TAC[DROPOUT_BASIS_3; DROPOUT_0]; + DISCH_THEN SUBST1_TAC] THEN + REWRITE_TAC[IN_ELIM_THM; VECTOR_MUL_RZERO; VECTOR_ADD_LID] THEN + ONCE_REWRITE_TAC[MESON[] + `(?a b c. p c /\ q a b c /\ r b c) <=> + (?c. p c /\ ?b. r b c /\ ?a. q a b c)`] THEN + SIMP_TAC[REAL_ARITH `a + b + c = &1 <=> a = &1 - b - c`; EXISTS_REFL] THEN + AP_TERM_TAC THEN GEN_REWRITE_TAC I [FUN_EQ_THM] THEN + X_GEN_TAC `t:real` THEN REWRITE_TAC[] THEN AP_TERM_TAC THEN + REWRITE_TAC[GSYM COMPLEX_CMUL] THEN + SIMP_TAC[CART_EQ; FORALL_2; FORALL_3; DIMINDEX_2; DIMINDEX_3; + dropout; LAMBDA_BETA; BASIS_COMPONENT; ARITH; REAL_MUL_RID; + VECTOR_MUL_COMPONENT; VEC_COMPONENT; REAL_MUL_RZERO; UNWIND_THM1; + VECTOR_ADD_COMPONENT; REAL_ADD_LID; RIGHT_EXISTS_AND_THM] THEN + REWRITE_TAC[REAL_ARITH `y:real = t + z <=> t = y - z`; EXISTS_REFL]);; + +let AZIM_EQ_ALT = prove + (`!v0 v1 w x y. + ~collinear{v0,v1,w} /\ ~collinear{v0,v1,x} /\ ~collinear{v0,v1,y} + ==> (azim v0 v1 w x = azim v0 v1 w y <=> x IN aff_gt {v0,v1} {y})`, + ASM_SIMP_TAC[GSYM AZIM_EQ] THEN MESON_TAC[]);; + +let AZIM_EQ_0 = prove + (`!v0 v1 w x. + ~collinear{v0,v1,w} /\ ~collinear{v0,v1,x} + ==> (azim v0 v1 w x = &0 <=> w IN aff_gt {v0,v1} {x})`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC EQ_TRANS THEN + EXISTS_TAC `azim v0 v1 w x = azim v0 v1 w w` THEN CONJ_TAC THENL + [REWRITE_TAC[AZIM_REFL]; + ASM_SIMP_TAC[AZIM_EQ]]);; + +let AZIM_EQ_0_ALT = prove + (`!v0 v1 w x. + ~collinear{v0,v1,w} /\ ~collinear{v0,v1,x} + ==> (azim v0 v1 w x = &0 <=> x IN aff_gt {v0,v1} {w})`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC EQ_TRANS THEN + EXISTS_TAC `azim v0 v1 w x = azim v0 v1 w w` THEN CONJ_TAC THENL + [REWRITE_TAC[AZIM_REFL]; + ASM_SIMP_TAC[AZIM_EQ_ALT]]);; + +let AZIM_EQ_0_GE = prove + (`!v0 v1 w x. + ~collinear{v0,v1,w} /\ ~collinear{v0,v1,x} + ==> (azim v0 v1 w x = &0 <=> w IN aff_ge {v0,v1} {x})`, + REPEAT GEN_TAC THEN + ASM_CASES_TAC `v1:real^3 = v0` THENL + [ASM_REWRITE_TAC[INSERT_AC; COLLINEAR_2]; STRIP_TAC] THEN + W(MP_TAC o PART_MATCH (lhs o rand) AFF_GE_AFF_GT_DECOMP o + rand o rand o snd) THEN + ANTS_TAC THENL + [SIMP_TAC[FINITE_INSERT; FINITE_EMPTY; DISJOINT_INSERT; DISJOINT_EMPTY] THEN + REWRITE_TAC[IN_SING] THEN + CONJ_TAC THEN DISCH_THEN SUBST_ALL_TAC THEN + RULE_ASSUM_TAC(REWRITE_RULE[COLLINEAR_2; INSERT_AC]) THEN + FIRST_ASSUM CONTR_TAC; + DISCH_THEN SUBST1_TAC] THEN + ASM_SIMP_TAC[AZIM_EQ_0] THEN + REWRITE_TAC[SIMPLE_IMAGE; IMAGE_CLAUSES; UNIONS_1] THEN + REWRITE_TAC[SET_RULE `{x} DELETE x = {}`] THEN + REWRITE_TAC[AFF_GE_EQ_AFFINE_HULL; IN_UNION] THEN + ASM_SIMP_TAC[GSYM COLLINEAR_3_AFFINE_HULL]);; + +let AZIM_COMPL_EQ_0 = prove + (`!z w w1 w2. + ~collinear {z,w,w1} /\ ~collinear {z,w,w2} /\ azim z w w1 w2 = &0 + ==> azim z w w2 w1 = &0`, + REWRITE_TAC[IMP_CONJ] THEN + GEOM_ORIGIN_TAC `z:real^3` THEN + GEOM_BASIS_MULTIPLE_TAC 3 `w:real^3` THEN + X_GEN_TAC `w:real` THEN GEN_REWRITE_TAC LAND_CONV [REAL_LE_LT] THEN + ASM_CASES_TAC `w = &0` THEN ASM_REWRITE_TAC[] THENL + [ASM_REWRITE_TAC[VECTOR_MUL_LZERO; INSERT_AC; COLLINEAR_2]; ALL_TAC] THEN + DISCH_TAC THEN REPEAT GEN_TAC THEN + ASM_SIMP_TAC[AZIM_SPECIAL_SCALE; COLLINEAR_SPECIAL_SCALE; AZIM_ARG] THEN + REWRITE_TAC[ARG_EQ_0; real; IM_COMPLEX_DIV_EQ_0; RE_COMPLEX_DIV_GE_0] THEN + REWRITE_TAC[complex_mul; RE; IM; cnj] THEN REAL_ARITH_TAC);; + +let AZIM_COMPL = prove + (`!z w w1 w2. + ~collinear {z,w,w1} /\ ~collinear {z,w,w2} + ==> azim z w w2 w1 = if azim z w w1 w2 = &0 then &0 + else &2 * pi - azim z w w1 w2`, + REPEAT GEN_TAC THEN COND_CASES_TAC THENL + [ASM_MESON_TAC[AZIM_COMPL_EQ_0]; ALL_TAC] THEN + DISCH_THEN(fun th -> POP_ASSUM MP_TAC THEN MP_TAC th) THEN + GEOM_ORIGIN_TAC `z:real^3` THEN + GEOM_BASIS_MULTIPLE_TAC 3 `w:real^3` THEN + X_GEN_TAC `w:real` THEN GEN_REWRITE_TAC LAND_CONV [REAL_LE_LT] THEN + ASM_CASES_TAC `w = &0` THEN ASM_REWRITE_TAC[] THENL + [ASM_REWRITE_TAC[VECTOR_MUL_LZERO; INSERT_AC; COLLINEAR_2]; ALL_TAC] THEN + DISCH_TAC THEN REPEAT GEN_TAC THEN + ASM_SIMP_TAC[AZIM_SPECIAL_SCALE; COLLINEAR_SPECIAL_SCALE; AZIM_ARG] THEN + REWRITE_TAC[COLLINEAR_BASIS_3] THEN REWRITE_TAC[ARG_EQ_0] THEN + REPEAT STRIP_TAC THEN + MP_TAC(ISPEC `(dropout 3:real^3->real^2) w2 / + (dropout 3:real^3->real^2) w1` ARG_INV) THEN + ASM_REWRITE_TAC[COMPLEX_INV_DIV]);; + +let AZIM_EQ_PI_SYM = prove + (`!z w w1 w2. + ~collinear {z, w, w1} /\ ~collinear {z, w, w2} + ==> (azim z w w1 w2 = pi <=> azim z w w2 w1 = pi)`, + REPEAT STRIP_TAC THEN + W(MP_TAC o PART_MATCH (lhs o rand) AZIM_COMPL o lhand o rand o snd) THEN + ASM_REWRITE_TAC[] THEN REAL_ARITH_TAC);; + +let AZIM_EQ_0_SYM = prove + (`!z w w1 w2. + ~collinear {z, w, w1} /\ ~collinear {z, w, w2} + ==> (azim z w w1 w2 = &0 <=> azim z w w2 w1 = &0)`, + MESON_TAC[AZIM_COMPL_EQ_0]);; + +let AZIM_EQ_0_GE_ALT = prove + (`!v0 v1 w x. + ~collinear{v0,v1,w} /\ ~collinear{v0,v1,x} + ==> (azim v0 v1 w x = &0 <=> x IN aff_ge {v0,v1} {w})`, + ASM_MESON_TAC[AZIM_EQ_0_SYM; AZIM_EQ_0_GE]);; + +let AZIM_EQ_PI = prove + (`!v0 v1 w x. + ~collinear{v0,v1,w} /\ ~collinear{v0,v1,x} + ==> (azim v0 v1 w x = pi <=> w IN aff_lt {v0,v1} {x})`, + GEOM_ORIGIN_TAC `v0:real^3` THEN + GEOM_BASIS_MULTIPLE_TAC 3 `v1:real^3` THEN + GEN_TAC THEN + GEN_REWRITE_TAC LAND_CONV [REAL_ARITH `&0 <= x <=> x = &0 \/ &0 < x`] THEN + STRIP_TAC THENL + [ASM_REWRITE_TAC[VECTOR_MUL_LZERO; INSERT_AC; COLLINEAR_2]; ALL_TAC] THEN + ASM_SIMP_TAC[AZIM_SPECIAL_SCALE; REAL_LT_IMP_NZ; + COLLINEAR_SPECIAL_SCALE] THEN + REPEAT STRIP_TAC THEN + W(MP_TAC o PART_MATCH (lhs o rand) AFF_LT_SPECIAL_SCALE o + rand o rand o snd) THEN + ANTS_TAC THENL + [ASM_REWRITE_TAC[IN_INSERT; FINITE_INSERT; FINITE_EMPTY; NOT_IN_EMPTY] THEN + REPEAT CONJ_TAC THEN DISCH_THEN(SUBST_ALL_TAC o SYM) THEN + TRY(RULE_ASSUM_TAC(REWRITE_RULE[INSERT_AC; COLLINEAR_2]) THEN + FIRST_X_ASSUM CONTR_TAC) THEN + UNDISCH_TAC `~collinear {vec 0:real^3, basis 3, v1 % basis 3}` THEN + REWRITE_TAC[COLLINEAR_LEMMA] THEN MESON_TAC[]; + DISCH_THEN SUBST1_TAC] THEN + REWRITE_TAC[AZIM_ARG] THEN CONV_TAC(LAND_CONV SYM_CONV) THEN + CONV_TAC(LAND_CONV SYM_CONV) THEN REWRITE_TAC[ARG_EQ_PI] THEN + MATCH_MP_TAC EQ_TRANS THEN EXISTS_TAC + `(dropout 3 (w:real^3)) IN aff_lt {vec 0:real^2} {dropout 3 (x:real^3)}` THEN + CONJ_TAC THENL + [REPEAT(POP_ASSUM MP_TAC) THEN REWRITE_TAC[COLLINEAR_BASIS_3] THEN + SPEC_TAC(`(dropout 3:real^3->real^2) x`,`y:complex`) THEN + SPEC_TAC(`(dropout 3:real^3->real^2) w`,`v:complex`) THEN + GEOM_BASIS_MULTIPLE_TAC 1 `v:complex` THEN + X_GEN_TAC `v:real` THEN GEN_REWRITE_TAC LAND_CONV [REAL_LE_LT] THEN + ASM_CASES_TAC `v = &0` THEN ASM_REWRITE_TAC[VECTOR_MUL_LZERO] THEN + REWRITE_TAC[COMPLEX_CMUL; COMPLEX_BASIS; COMPLEX_VEC_0] THEN + SIMP_TAC[ARG_DIV_CX; COMPLEX_MUL_RID] THEN + REWRITE_TAC[real; RE_DIV_CX; IM_DIV_CX; CX_INJ] THEN + ASM_SIMP_TAC[REAL_LT_LDIV_EQ; REAL_EQ_LDIV_EQ; REAL_MUL_LZERO] THEN + REPEAT STRIP_TAC THEN + W(MP_TAC o PART_MATCH (lhs o rand) AFF_LT_1_1 o rand o rand o snd) THEN + ASM_REWRITE_TAC[DISJOINT_INSERT; DISJOINT_EMPTY; IN_SING] THEN + DISCH_THEN SUBST1_TAC THEN + REWRITE_TAC[COMPLEX_CMUL; IN_ELIM_THM; COMPLEX_MUL_RZERO] THEN + ONCE_REWRITE_TAC[SWAP_EXISTS_THM] THEN + REWRITE_TAC[REAL_ARITH `t1 + t2 = &1 <=> t1 = &1 - t2`] THEN + REWRITE_TAC[RIGHT_EXISTS_AND_THM; UNWIND_THM2; COMPLEX_ADD_LID] THEN + EQ_TAC THENL + [REWRITE_TAC[GSYM real; REAL] THEN + DISCH_THEN(CONJUNCTS_THEN2 (SUBST1_TAC o SYM) ASSUME_TAC) THEN + EXISTS_TAC `v / Re y` THEN REWRITE_TAC[GSYM CX_MUL; CX_INJ] THEN + CONJ_TAC THENL + [ALL_TAC; REPEAT(POP_ASSUM MP_TAC) THEN CONV_TAC REAL_FIELD]; + DISCH_THEN(X_CHOOSE_THEN `t:real` + (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + ASM_SIMP_TAC[CX_INJ; REAL_ARITH `x < &0 ==> ~(x = &0)`; COMPLEX_FIELD + `~(t = Cx(&0)) ==> (v = t * y <=> y = v / t)`] THEN + DISCH_THEN SUBST1_TAC THEN REWRITE_TAC[GSYM CX_DIV] THEN + REWRITE_TAC[RE_CX; IM_CX]] THEN + REWRITE_TAC[REAL_ARITH `x < &0 <=> &0 < --x`] THEN + REWRITE_TAC[real_div; GSYM REAL_MUL_RNEG; GSYM REAL_INV_NEG] THEN + MATCH_MP_TAC REAL_LT_MUL THEN ASM_REWRITE_TAC[REAL_LT_INV_EQ] THEN + ASM_REAL_ARITH_TAC; + W(MP_TAC o PART_MATCH (lhs o rand) AFF_LT_2_1 o rand o rand o snd) THEN + ANTS_TAC THENL + [REWRITE_TAC[SET_RULE `DISJOINT {a,b} {x} <=> ~(x = a) /\ ~(x = b)`] THEN + CONJ_TAC THEN DISCH_THEN SUBST_ALL_TAC THEN + RULE_ASSUM_TAC(REWRITE_RULE[COLLINEAR_2; INSERT_AC]) THEN + FIRST_ASSUM CONTR_TAC; + DISCH_THEN SUBST1_TAC] THEN + W(MP_TAC o PART_MATCH (lhs o rand) AFF_LT_1_1 o rand o lhand o snd) THEN + ANTS_TAC THENL + [REWRITE_TAC[SET_RULE `DISJOINT {a} {x} <=> ~(x = a)`] THEN + ASM_MESON_TAC[COLLINEAR_BASIS_3]; + DISCH_THEN SUBST1_TAC] THEN + REWRITE_TAC[VECTOR_MUL_RZERO; VECTOR_ADD_LID; IN_ELIM_THM] THEN + ONCE_REWRITE_TAC[REAL_ARITH `s + t = &1 <=> s = &1- t`] THEN + ONCE_REWRITE_TAC[SWAP_EXISTS_THM] THEN + REWRITE_TAC[RIGHT_EXISTS_AND_THM; UNWIND_THM2] THEN + GEN_REWRITE_TAC (RAND_CONV o BINDER_CONV) [SWAP_EXISTS_THM] THEN + REWRITE_TAC[RIGHT_EXISTS_AND_THM; UNWIND_THM2] THEN + ONCE_REWRITE_TAC[SWAP_EXISTS_THM] THEN AP_TERM_TAC THEN + REWRITE_TAC[FUN_EQ_THM; RIGHT_EXISTS_AND_THM] THEN X_GEN_TAC `t:real` THEN + AP_TERM_TAC THEN + SIMP_TAC[CART_EQ; FORALL_2; FORALL_3; DIMINDEX_2; DIMINDEX_3; + dropout; LAMBDA_BETA; BASIS_COMPONENT; ARITH; REAL_MUL_RID; + VECTOR_MUL_COMPONENT; VEC_COMPONENT; REAL_MUL_RZERO; UNWIND_THM1; + VECTOR_ADD_COMPONENT; REAL_ADD_LID; RIGHT_EXISTS_AND_THM] THEN + REWRITE_TAC[REAL_ARITH `x:real = t + y <=> t = x - y`] THEN + REWRITE_TAC[EXISTS_REFL]]);; + +let AZIM_EQ_PI_ALT = prove + (`!v0 v1 w x. + ~collinear{v0,v1,w} /\ ~collinear{v0,v1,x} + ==> (azim v0 v1 w x = pi <=> x IN aff_lt {v0,v1} {w})`, + REPEAT GEN_TAC THEN DISCH_TAC THEN + FIRST_ASSUM(SUBST1_TAC o MATCH_MP AZIM_EQ_PI_SYM) THEN + ASM_SIMP_TAC[AZIM_EQ_PI]);; + +let AZIM_EQ_0_PI_IMP_COPLANAR = prove + (`!v0 v1 w1 w2. + azim v0 v1 w1 w2 = &0 \/ azim v0 v1 w1 w2 = pi + ==> coplanar {v0,v1,w1,w2}`, + REPEAT GEN_TAC THEN ASM_CASES_TAC `collinear {v0:real^3,v1,w1}` THENL + [MP_TAC(ISPECL [`v0:real^3`; `v1:real^3`; `w1:real^3`; `w2:real^3`] + NOT_COPLANAR_NOT_COLLINEAR) THEN + ASM_REWRITE_TAC[] THEN CONV_TAC TAUT; + POP_ASSUM MP_TAC] THEN + ASM_CASES_TAC `collinear {v0:real^3,v1,w2}` THENL + [MP_TAC(ISPECL [`v0:real^3`; `v1:real^3`; `w2:real^3`; `w1:real^3`] + NOT_COPLANAR_NOT_COLLINEAR) THEN + ASM_REWRITE_TAC[] THEN REWRITE_TAC[INSERT_AC] THEN CONV_TAC TAUT; + POP_ASSUM MP_TAC] THEN + MAP_EVERY (fun t -> SPEC_TAC(t,t)) + [`w2:real^3`; `w1:real^3`; `v1:real^3`; `v0:real^3`] THEN + GEOM_ORIGIN_TAC `v0:real^3` THEN + GEOM_BASIS_MULTIPLE_TAC 3 `v1:real^3` THEN + X_GEN_TAC `w:real` THEN GEN_REWRITE_TAC LAND_CONV [REAL_LE_LT] THEN + ASM_CASES_TAC `w = &0` THEN ASM_REWRITE_TAC[] THENL + [ASM_REWRITE_TAC[VECTOR_MUL_LZERO; INSERT_AC; COLLINEAR_2]; ALL_TAC] THEN + SIMP_TAC[AZIM_SPECIAL_SCALE] THEN + ASM_SIMP_TAC[AZIM_ARG; COLLINEAR_SPECIAL_SCALE] THEN + REWRITE_TAC[COLLINEAR_BASIS_3; ARG_EQ_0_PI] THEN + REWRITE_TAC[real; IM_COMPLEX_DIV_EQ_0] THEN + REWRITE_TAC[complex_mul; cnj; IM; RE] THEN + REWRITE_TAC[REAL_ARITH `x * --y + a * b = &0 <=> x * y = a * b`] THEN + REWRITE_TAC[RE_DEF; IM_DEF] THEN DISCH_TAC THEN REPEAT GEN_TAC THEN + DISCH_TAC THEN DISCH_TAC THEN + SIMP_TAC[dropout; LAMBDA_BETA; DIMINDEX_3; ARITH; DIMINDEX_2] THEN + DISCH_TAC THEN REWRITE_TAC[coplanar] THEN + MAP_EVERY EXISTS_TAC [`vec 0:real^3`; `w % basis 3:real^3`; `w1:real^3`] THEN + ONCE_REWRITE_TAC[SET_RULE `{a,b,c,d} = d INSERT {a,b,c}`] THEN + ONCE_REWRITE_TAC[INSERT_SUBSET] THEN REWRITE_TAC[HULL_SUBSET] THEN + SIMP_TAC[AFFINE_HULL_EQ_SPAN; IN_INSERT; HULL_INC] THEN + REWRITE_TAC[SPAN_BREAKDOWN_EQ; SPAN_EMPTY; IN_SING] THEN + REWRITE_TAC[VECTOR_MUL_RZERO; VECTOR_SUB_RZERO] THEN + REPEAT(POP_ASSUM MP_TAC) THEN + SIMP_TAC[CART_EQ; DIMINDEX_2; FORALL_2; FORALL_3; dropout; LAMBDA_BETA; + DIMINDEX_2; DIMINDEX_3; ARITH; VEC_COMPONENT; ARITH; + VECTOR_SUB_COMPONENT; VECTOR_MUL_COMPONENT; BASIS_COMPONENT] THEN + REPEAT STRIP_TAC THEN + REWRITE_TAC[REAL_MUL_RZERO; REAL_SUB_RZERO] THEN + ONCE_REWRITE_TAC[SWAP_EXISTS_THM] THEN + REWRITE_TAC[RIGHT_EXISTS_AND_THM] THEN + ASM_SIMP_TAC[EXISTS_REFL; REAL_FIELD + `&0 < w ==> (x - k * w * &1 - y = &0 <=> k = (x - y) / w)`] THEN + SUBGOAL_THEN `~((w1:real^3)$2 = &0) \/ ~((w2:real^3)$1 = &0)` + STRIP_ASSUME_TAC THENL + [REPEAT(POP_ASSUM MP_TAC) THEN CONV_TAC REAL_RING; + EXISTS_TAC `(w2:real^3)$2 / (w1:real^3)$2` THEN + REPEAT(POP_ASSUM MP_TAC) THEN CONV_TAC REAL_FIELD; + EXISTS_TAC `(w2:real^3)$1 / (w1:real^3)$1` THEN + REPEAT(POP_ASSUM MP_TAC) THEN CONV_TAC REAL_FIELD]);; + +let AZIM_SAME_WITHIN_AFF_GE = prove + (`!a u v w z. + v IN aff_ge {a} {u,w} /\ ~collinear{a,u,v} /\ ~collinear{a,u,w} + ==> azim a u v z = azim a u w z`, + GEOM_ORIGIN_TAC `a:real^3` THEN + GEOM_BASIS_MULTIPLE_TAC 3 `u:real^3` THEN + X_GEN_TAC `u:real` THEN ASM_CASES_TAC `u = &0` THEN + ASM_SIMP_TAC[AZIM_DEGENERATE; VECTOR_MUL_LZERO; REAL_LE_LT] THEN + ASM_SIMP_TAC[AZIM_SPECIAL_SCALE; COLLINEAR_SPECIAL_SCALE] THEN + DISCH_TAC THEN REPEAT GEN_TAC THEN + ASM_CASES_TAC `w:real^3 = vec 0` THENL + [ASM_REWRITE_TAC[COLLINEAR_2; INSERT_AC]; ALL_TAC] THEN + ASM_SIMP_TAC[AFF_GE_SCALE_LEMMA] THEN + REWRITE_TAC[COLLINEAR_BASIS_3; AZIM_ARG] THEN + ASM_SIMP_TAC[AFF_GE_1_2_0; BASIS_NONZERO; ARITH; DIMINDEX_3; + SET_RULE `DISJOINT {a} {b,c} <=> ~(b = a) /\ ~(c = a)`] THEN + REWRITE_TAC[IMP_CONJ; LEFT_IMP_EXISTS_THM; IN_ELIM_THM] THEN + MAP_EVERY X_GEN_TAC [`a:real`; `b:real`] THEN DISCH_TAC THEN DISCH_TAC THEN + DISCH_THEN(MP_TAC o AP_TERM `dropout 3:real^3->real^2`) THEN + REWRITE_TAC[DROPOUT_ADD; DROPOUT_MUL; DROPOUT_BASIS_3] THEN + REWRITE_TAC[VECTOR_MUL_RZERO; VECTOR_ADD_LID] THEN + DISCH_THEN SUBST1_TAC THEN REPEAT DISCH_TAC THEN + REWRITE_TAC[COMPLEX_CMUL] THEN + REWRITE_TAC[complex_div; COMPLEX_INV_MUL; GSYM CX_INV] THEN + ONCE_REWRITE_TAC[COMPLEX_RING `a * b * c:complex = b * a * c`] THEN + MATCH_MP_TAC ARG_MUL_CX THEN REWRITE_TAC[REAL_LT_INV_EQ] THEN + ASM_REWRITE_TAC[REAL_LT_LE] THEN ASM_MESON_TAC[VECTOR_MUL_LZERO]);; + +let AZIM_SAME_WITHIN_AFF_GE_ALT = prove + (`!a u v w z. + v IN aff_ge {a} {u,w} /\ ~collinear{a,u,v} /\ ~collinear{a,u,w} + ==> azim a u z v = azim a u z w`, + REPEAT GEN_TAC THEN DISCH_TAC THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP AZIM_SAME_WITHIN_AFF_GE) THEN + ASM_CASES_TAC `collinear {a:real^3,u,z}` THEN + ASM_SIMP_TAC[AZIM_DEGENERATE] THEN + W(MP_TAC o PART_MATCH (lhs o rand) AZIM_COMPL o lhand o snd) THEN + ASM_REWRITE_TAC[] THEN DISCH_THEN SUBST1_TAC THEN + W(MP_TAC o PART_MATCH (lhs o rand) AZIM_COMPL o rand o snd) THEN + ASM_SIMP_TAC[]);; + +let COLLINEAR_WITHIN_AFF_GE_COLLINEAR = prove + (`!a u v w:real^N. + v IN aff_ge {a} {u,w} /\ collinear{a,u,w} ==> collinear{a,v,w}`, + GEOM_ORIGIN_TAC `a:real^N` THEN REPEAT GEN_TAC THEN + ASM_CASES_TAC `w:real^N = vec 0` THENL + [ASM_REWRITE_TAC[COLLINEAR_2; INSERT_AC]; ALL_TAC] THEN + ASM_CASES_TAC `u:real^N = vec 0` THENL + [ONCE_REWRITE_TAC[AFF_GE_DISJOINT_DIFF] THEN + ASM_REWRITE_TAC[SET_RULE `{a} DIFF {a,b} = {}`] THEN + REWRITE_TAC[GSYM CONVEX_HULL_AFF_GE] THEN + ONCE_REWRITE_TAC[SET_RULE `{z,v,w} = {z,w,v}`] THEN + ASM_SIMP_TAC[COLLINEAR_3_AFFINE_HULL] THEN + MESON_TAC[CONVEX_HULL_SUBSET_AFFINE_HULL; SUBSET]; + ONCE_REWRITE_TAC[SET_RULE `{z,v,w} = {z,w,v}`] THEN + ASM_REWRITE_TAC[COLLINEAR_LEMMA_ALT] THEN + DISCH_THEN(CONJUNCTS_THEN2 MP_TAC (X_CHOOSE_TAC `a:real`)) THEN + ASM_SIMP_TAC[AFF_GE_1_2_0; SET_RULE + `DISJOINT {a} {b,c} <=> ~(b = a) /\ ~(c = a)`] THEN + REWRITE_TAC[IN_ELIM_THM; LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`b:real`; `c:real`] THEN STRIP_TAC THEN + ASM_REWRITE_TAC[GSYM VECTOR_ADD_RDISTRIB; VECTOR_MUL_ASSOC] THEN + MESON_TAC[]]);; + +let AZIM_EQ_IMP = prove + (`!v0 v1 w x y. + ~collinear {v0, v1, w} /\ + ~collinear {v0, v1, y} /\ + x IN aff_gt {v0, v1} {y} + ==> azim v0 v1 w x = azim v0 v1 w y`, + REPEAT GEN_TAC THEN ASM_CASES_TAC `v1:real^3 = v0` THENL + [ASM_REWRITE_TAC[INSERT_AC; COLLINEAR_2]; ALL_TAC] THEN + ASM_CASES_TAC `collinear {v0:real^3,v1,x}` THENL + [ALL_TAC; ASM_SIMP_TAC[AZIM_EQ_ALT]] THEN + UNDISCH_TAC `collinear {v0:real^3,v1,x}` THEN + MATCH_MP_TAC(TAUT + `(s /\ p ==> r) ==> p ==> ~q /\ ~r /\ s ==> t`) THEN + ASM_SIMP_TAC[COLLINEAR_3_IN_AFFINE_HULL] THEN + ASM_CASES_TAC `y:real^3 = v0` THEN + ASM_SIMP_TAC[HULL_INC; IN_INSERT] THEN + ASM_CASES_TAC `y:real^3 = v1` THEN + ASM_SIMP_TAC[HULL_INC; IN_INSERT] THEN + ASM_SIMP_TAC[AFF_GT_2_1; SET_RULE + `DISJOINT {a,b} {c} <=> ~(c = a) /\ ~(c = b)`] THEN + REWRITE_TAC[AFFINE_HULL_2; IN_ELIM_THM; LEFT_AND_EXISTS_THM] THEN + REWRITE_TAC[RIGHT_AND_EXISTS_THM; LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC + [`t1:real`; `t2:real`; `t3:real`; `s1:real`; `s2:real`] THEN + DISCH_THEN(CONJUNCTS_THEN2 STRIP_ASSUME_TAC MP_TAC) THEN + FIRST_X_ASSUM(MP_TAC o AP_TERM `(%) (inv t3) :real^3->real^3`) THEN + ASM_SIMP_TAC[VECTOR_ADD_LDISTRIB; VECTOR_MUL_ASSOC; REAL_MUL_LINV; + REAL_LT_IMP_NZ; VECTOR_ARITH + `x:real^N = y + z + &1 % w <=> w = x - (y + z)`] THEN + REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + EXISTS_TAC `inv t3 * s1 - inv t3 * t1:real` THEN + EXISTS_TAC `inv t3 * s2 - inv t3 * t2:real` THEN CONJ_TAC THENL + [ASM_SIMP_TAC[REAL_FIELD + `&0 < t ==> (inv t * a - inv t * b + inv t * c - inv t * d = &1 <=> + (a + c) - (b + d) = t)`] THEN + ASM_REAL_ARITH_TAC; + VECTOR_ARITH_TAC]);; + +let AZIM_EQ_0_GE_IMP = prove + (`!v0 v1 w x. x IN aff_ge {v0, v1} {w} ==> azim v0 v1 w x = &0`, + REPEAT STRIP_TAC THEN ASM_CASES_TAC `collinear {v0:real^3,v1,w}` THEN + ASM_SIMP_TAC[AZIM_DEGENERATE] THEN + ASM_CASES_TAC `collinear {v0:real^3,v1,x}` THEN + ASM_SIMP_TAC[AZIM_DEGENERATE] THEN ASM_MESON_TAC[AZIM_EQ_0_GE_ALT]);; + +let REAL_SGN_SIN_AZIM = prove + (`!v w x y. real_sgn(sin(azim v w x y)) = + real_sgn(((w - v) cross (x - v)) dot (y - v))`, + GEOM_ORIGIN_TAC `v:real^3` THEN REWRITE_TAC[VECTOR_SUB_RZERO] THEN + GEOM_BASIS_MULTIPLE_TAC 3 `w:real^3` THEN + X_GEN_TAC `w:real` THEN ASM_CASES_TAC `w = &0` THEN + ASM_REWRITE_TAC[VECTOR_MUL_LZERO; CROSS_LZERO; DOT_LZERO; REAL_SGN_0; + AZIM_REFL_ALT; SIN_0] THEN + ASM_REWRITE_TAC[REAL_LE_LT] THEN REPEAT STRIP_TAC THEN + ASM_SIMP_TAC[AZIM_SPECIAL_SCALE; CROSS_LMUL; DOT_LMUL] THEN + REWRITE_TAC[REAL_SGN_MUL] THEN + GEN_REWRITE_TAC (RAND_CONV o LAND_CONV) [real_sgn] THEN + ASM_REWRITE_TAC[REAL_MUL_LID; AZIM_ARG] THEN + MATCH_MP_TAC EQ_TRANS THEN + EXISTS_TAC `real_sgn(Im(dropout 3 (y:real^3) / dropout 3 (x:real^3)))` THEN + CONJ_TAC THENL + [ALL_TAC; + REWRITE_TAC[REAL_SGN_IM_COMPLEX_DIV] THEN AP_TERM_TAC THEN + SIMP_TAC[CART_EQ; DIMINDEX_3; FORALL_3; cross; VECTOR_3; DOT_3; dropout; + LAMBDA_BETA; ARITH; cnj; complex_mul; RE_DEF; IM_DEF; DIMINDEX_2; + complex; VECTOR_2; BASIS_COMPONENT] THEN REAL_ARITH_TAC] THEN + + SPEC_TAC(`(dropout 3:real^3->real^2) x`,`z:complex`) THEN + SPEC_TAC(`(dropout 3:real^3->real^2) y`,`w:complex`) THEN + POP_ASSUM_LIST(K ALL_TAC) THEN GEOM_BASIS_MULTIPLE_TAC 1 `z:complex` THEN + REWRITE_TAC[COMPLEX_CMUL; COMPLEX_BASIS; COMPLEX_MUL_RID] THEN + X_GEN_TAC `x:real` THEN DISCH_TAC THEN X_GEN_TAC `z:complex` THEN + ASM_CASES_TAC `x = &0` THENL + [ASM_REWRITE_TAC[complex_div; COMPLEX_INV_0; COMPLEX_MUL_RZERO] THEN + REWRITE_TAC[ARG_0; SIN_0; IM_CX; REAL_SGN_0]; + SUBGOAL_THEN `&0 < x` ASSUME_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC]] THEN + ASM_SIMP_TAC[ARG_DIV_CX; IM_DIV_CX; REAL_SGN_DIV] THEN + GEN_REWRITE_TAC (RAND_CONV o RAND_CONV) [real_sgn] THEN + ASM_REWRITE_TAC[REAL_DIV_1] THEN ASM_CASES_TAC `z = Cx(&0)` THEN + ASM_REWRITE_TAC[IM_CX; ARG_0; SIN_0] THEN + GEN_REWRITE_TAC (funpow 3 RAND_CONV) [ARG] THEN + REWRITE_TAC[IM_MUL_CX; REAL_SGN_MUL] THEN + GEN_REWRITE_TAC (RAND_CONV o LAND_CONV) [real_sgn] THEN + ASM_REWRITE_TAC[COMPLEX_NORM_NZ; REAL_MUL_LID] THEN + REWRITE_TAC[IM_CEXP; RE_MUL_II; IM_MUL_II; RE_CX; REAL_SGN_MUL] THEN + GEN_REWRITE_TAC (RAND_CONV o LAND_CONV) [real_sgn] THEN + REWRITE_TAC[REAL_EXP_POS_LT; REAL_MUL_LID]);; + +let AZIM_IN_UPPER_HALFSPACE = prove + (`!v w x y. azim v w x y <= pi <=> + &0 <= ((w - v) cross (x - v)) dot (y - v)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC EQ_TRANS THEN + EXISTS_TAC `&0 <= sin(azim v w x y)` THEN CONJ_TAC THENL + [EQ_TAC THEN SIMP_TAC[SIN_POS_PI_LE; azim] THEN + MP_TAC(ISPEC `azim v w x y - pi` SIN_POS_PI) THEN + REWRITE_TAC[SIN_SUB; SIN_PI; COS_PI; azim; + REAL_ARITH `x - pi < pi <=> x < &2 * pi`] THEN + REAL_ARITH_TAC; + ONCE_REWRITE_TAC[GSYM REAL_SGN_INEQS] THEN + REWRITE_TAC[REAL_SGN_SIN_AZIM]]);; + +(* ------------------------------------------------------------------------- *) +(* Dihedral angle and relation to azimuth angle. *) +(* ------------------------------------------------------------------------- *) + +let dihV = new_definition + `dihV w0 w1 w2 w3 = + let va = w2 - w0 in + let vb = w3 - w0 in + let vc = w1 - w0 in + let vap = ( vc dot vc) % va - ( va dot vc) % vc in + let vbp = ( vc dot vc) % vb - ( vb dot vc) % vc in + arcV (vec 0) vap vbp`;; + +let DIHV = prove + (`dihV (w0:real^N) w1 w2 w3 = + let va = w2 - w0 in + let vb = w3 - w0 in + let vc = w1 - w0 in + let vap = (vc dot vc) % va - (va dot vc) % vc in + let vbp = (vc dot vc) % vb - (vb dot vc) % vc in + angle(vap,vec 0,vbp)`, + REWRITE_TAC[dihV; ARCV_ANGLE]);; + +let DIHV_TRANSLATION_EQ = prove + (`!a w0 w1 w2 w3:real^N. + dihV (a + w0) (a + w1) (a + w2) (a + w3) = dihV w0 w1 w2 w3`, + REWRITE_TAC[DIHV; VECTOR_ARITH `(a + x) - (a + y):real^N = x - y`]);; + +add_translation_invariants [DIHV_TRANSLATION_EQ];; + +let DIHV_LINEAR_IMAGE = prove + (`!f:real^M->real^N w0 w1 w2 w3. + linear f /\ (!x. norm(f x) = norm x) + ==> dihV (f w0) (f w1) (f w2) (f w3) = dihV w0 w1 w2 w3`, + REPEAT STRIP_TAC THEN REWRITE_TAC[DIHV] THEN + ASM_SIMP_TAC[GSYM LINEAR_SUB] THEN + CONV_TAC(TOP_DEPTH_CONV let_CONV) THEN + ASM_SIMP_TAC[PRESERVES_NORM_PRESERVES_DOT] THEN + ASM_SIMP_TAC[GSYM LINEAR_CMUL; GSYM LINEAR_SUB] THEN + REWRITE_TAC[angle; VECTOR_SUB_RZERO] THEN + ASM_SIMP_TAC[VECTOR_ANGLE_LINEAR_IMAGE_EQ]);; + +add_linear_invariants [DIHV_LINEAR_IMAGE];; + +let DIHV_SPECIAL_SCALE = prove + (`!a v w1 w2:real^N. + ~(a = &0) + ==> dihV (vec 0) (a % v) w1 w2 = dihV (vec 0) v w1 w2`, + REPEAT STRIP_TAC THEN REWRITE_TAC[DIHV; VECTOR_SUB_RZERO] THEN + CONV_TAC(TOP_DEPTH_CONV let_CONV) THEN + REWRITE_TAC[DOT_LMUL; DOT_RMUL; GSYM VECTOR_MUL_ASSOC] THEN + REWRITE_TAC[VECTOR_ARITH `a % a % x - a % b % a % y:real^N = + (a * a) % (x - b % y)`] THEN + REWRITE_TAC[angle; VECTOR_SUB_RZERO] THEN + REWRITE_TAC[VECTOR_ANGLE_LMUL; VECTOR_ANGLE_RMUL] THEN + ASM_REWRITE_TAC[REAL_LE_SQUARE; REAL_ENTIRE]);; + +let DIHV_RANGE = prove + (`!w0 w1 w2 w3. &0 <= dihV w0 w1 w2 w3 /\ dihV w0 w1 w2 w3 <= pi`, + REWRITE_TAC[DIHV] THEN CONV_TAC(TOP_DEPTH_CONV let_CONV) THEN + REWRITE_TAC[ANGLE_RANGE]);; + +let COS_AZIM_DIHV = prove + (`!v w v1 v2:real^3. + ~collinear {v,w,v1} /\ ~collinear {v,w,v2} + ==> cos(azim v w v1 v2) = cos(dihV v w v1 v2)`, + REPEAT GEN_TAC THEN ASM_CASES_TAC `w:real^3 = v` THENL + [ASM_REWRITE_TAC[INSERT_AC; COLLINEAR_2]; POP_ASSUM MP_TAC] THEN + REWRITE_TAC[IMP_IMP; GSYM CONJ_ASSOC] THEN + GEOM_ORIGIN_TAC `v:real^3` THEN GEOM_BASIS_MULTIPLE_TAC 3 `w:real^3` THEN + X_GEN_TAC `w:real` THEN GEN_REWRITE_TAC LAND_CONV [REAL_LE_LT] THEN + ASM_CASES_TAC `w = &0` THEN ASM_REWRITE_TAC[VECTOR_MUL_LZERO] THEN + ASM_SIMP_TAC[AZIM_SPECIAL_SCALE; DIHV_SPECIAL_SCALE; REAL_LT_IMP_NZ; + COLLINEAR_SPECIAL_SCALE; COLLINEAR_BASIS_3] THEN + DISCH_TAC THEN POP_ASSUM_LIST(K ALL_TAC) THEN + MAP_EVERY X_GEN_TAC [`w1:real^3`; `w2:real^3`] THEN + DISCH_THEN(STRIP_ASSUME_TAC o CONJUNCT2) THEN + REWRITE_TAC[DIHV; VECTOR_SUB_RZERO] THEN + CONV_TAC(TOP_DEPTH_CONV let_CONV) THEN + SIMP_TAC[DOT_BASIS_BASIS; DIMINDEX_3; ARITH] THEN + SIMP_TAC[DOT_BASIS; DIMINDEX_3; ARITH; VECTOR_MUL_LID] THEN + MP_TAC(ISPECL [`vec 0:real^3`; `basis 3:real^3`; `w1:real^3`; `w2:real^3`] + azim) THEN + ABBREV_TAC `a = azim (vec 0) (basis 3) w1 (w2:real^3)` THEN + REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM; VECTOR_SUB_RZERO; DIST_0] THEN + MAP_EVERY X_GEN_TAC [`h1:real`; `h2:real`] THEN + DISCH_THEN(MP_TAC o SPECL + [`basis 1:real^3`; `basis 2:real^3`; `basis 3:real^3`]) THEN + SIMP_TAC[orthonormal; DOT_BASIS_BASIS; CROSS_BASIS; DIMINDEX_3; NORM_BASIS; + ARITH; VECTOR_MUL_LID; BASIS_NONZERO; REAL_LT_01; LEFT_IMP_EXISTS_THM] THEN + ASM_REWRITE_TAC[COLLINEAR_BASIS_3] THEN + MAP_EVERY X_GEN_TAC [`psi:real`; `r1:real`; `r2:real`] THEN + DISCH_THEN(STRIP_ASSUME_TAC o GSYM) THEN + REWRITE_TAC[VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT] THEN + SIMP_TAC[BASIS_COMPONENT; DIMINDEX_3; ARITH; REAL_MUL_RZERO] THEN + REWRITE_TAC[REAL_MUL_RID; REAL_ADD_LID] THEN + REWRITE_TAC[VECTOR_ARITH `(a + b + c) - c:real^N = a + b`] THEN + REWRITE_TAC[COS_ANGLE; VECTOR_SUB_RZERO] THEN + REWRITE_TAC[vector_norm; GSYM DOT_EQ_0; DIMINDEX_3; FORALL_3; DOT_3] THEN + REWRITE_TAC[VEC_COMPONENT; VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT] THEN + SIMP_TAC[BASIS_COMPONENT; DIMINDEX_3; ARITH; REAL_MUL_RZERO] THEN + REWRITE_TAC[REAL_MUL_RID; REAL_ADD_LID; REAL_ADD_RID; REAL_MUL_RZERO] THEN + REWRITE_TAC[REAL_ARITH `(r * c) * (r * c) + (r * s) * (r * s):real = + r pow 2 * (s pow 2 + c pow 2)`] THEN + ASM_SIMP_TAC[SIN_CIRCLE; REAL_MUL_RID; REAL_POW_EQ_0; REAL_LT_IMP_NZ] THEN + ASM_SIMP_TAC[POW_2_SQRT; REAL_LT_IMP_LE] THEN + REWRITE_TAC[REAL_ARITH `(r1 * c1) * (r2 * c2) + (r1 * s1) * (r2 * s2):real = + (r1 * r2) * (c1 * c2 + s1 * s2)`] THEN + ASM_SIMP_TAC[REAL_FIELD + `&0 < r1 /\ &0 < r2 ==> ((r1 * r2) * x) / (r1 * r2) = x`] THEN + ONCE_REWRITE_TAC[REAL_ARITH `a:real = b + c * d <=> b - --c * d = a`] THEN + GEN_REWRITE_TAC (funpow 3 LAND_CONV) [GSYM COS_NEG] THEN + REWRITE_TAC[GSYM SIN_NEG; GSYM COS_ADD] THEN AP_TERM_TAC THEN + REAL_ARITH_TAC);; + +let AZIM_DIHV_SAME = prove + (`!v w v1 v2:real^3. + ~collinear {v,w,v1} /\ ~collinear {v,w,v2} /\ + azim v w v1 v2 < pi + ==> azim v w v1 v2 = dihV v w v1 v2`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC COS_INJ_PI THEN + ASM_SIMP_TAC[COS_AZIM_DIHV; azim; REAL_LT_IMP_LE; DIHV_RANGE]);; + +let AZIM_DIHV_COMPL = prove + (`!v w v1 v2:real^3. + ~collinear {v,w,v1} /\ ~collinear {v,w,v2} /\ + pi <= azim v w v1 v2 + ==> azim v w v1 v2 = &2 * pi - dihV v w v1 v2`, + REPEAT STRIP_TAC THEN + ONCE_REWRITE_TAC[REAL_ARITH `x = &2 * pi - y <=> y = &2 * pi - x`] THEN + MATCH_MP_TAC COS_INJ_PI THEN + REWRITE_TAC[COS_SUB; SIN_NPI; COS_NPI; REAL_MUL_LZERO] THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN + ASM_SIMP_TAC[COS_AZIM_DIHV; REAL_ADD_RID; REAL_MUL_LID] THEN + ASM_REWRITE_TAC[DIHV_RANGE] THEN MATCH_MP_TAC(REAL_ARITH + `p <= x /\ x < &2 * p ==> &0 <= &2 * p - x /\ &2 * p - x <= p`) THEN + ASM_SIMP_TAC[azim]);; + +let AZIM_DIVH = prove + (`!v w v1 v2:real^3. + ~collinear {v,w,v1} /\ ~collinear {v,w,v2} + ==> azim v w v1 v2 = if azim v w v1 v2 < pi then dihV v w v1 v2 + else &2 * pi - dihV v w v1 v2`, + REPEAT STRIP_TAC THEN COND_CASES_TAC THEN + RULE_ASSUM_TAC(REWRITE_RULE[REAL_NOT_LT]) THEN + ASM_SIMP_TAC[AZIM_DIHV_SAME; AZIM_DIHV_COMPL]);; + +let AZIM_DIHV_EQ_0 = prove + (`!v0 v1 w1 w2. + ~collinear {v0,v1,w1} /\ ~collinear {v0,v1,w2} + ==> (azim v0 v1 w1 w2 = &0 <=> dihV v0 v1 w1 w2 = &0)`, + REPEAT STRIP_TAC THEN + W(MP_TAC o PART_MATCH (lhs o rand) AZIM_DIVH o lhs o lhs o snd) THEN + ASM_REWRITE_TAC[] THEN COND_CASES_TAC THEN ASM_SIMP_TAC[] THEN + ONCE_REWRITE_TAC[REAL_ARITH `a:real = p - b <=> b = p - a`] THEN + DISCH_THEN SUBST1_TAC THEN + REWRITE_TAC[REAL_ARITH `&2 * p - (&2 * p - a) = &0 <=> a = &0`] THEN + MATCH_MP_TAC(REAL_ARITH + `a < &2 * pi /\ ~(a < pi) ==> (a = &0 <=> &2 * pi - a = &0)`) THEN + ASM_REWRITE_TAC[azim]);; + +let AZIM_DIHV_EQ_PI = prove + (`!v0 v1 w1 w2. + ~collinear {v0,v1,w1} /\ ~collinear {v0,v1,w2} + ==> (azim v0 v1 w1 w2 = pi <=> dihV v0 v1 w1 w2 = pi)`, + REPEAT STRIP_TAC THEN + W(MP_TAC o PART_MATCH (lhs o rand) AZIM_DIVH o lhs o lhs o snd) THEN + ASM_REWRITE_TAC[] THEN REAL_ARITH_TAC);; + +let AZIM_EQ_0_PI_EQ_COPLANAR = prove + (`!v0 v1 w1 w2. + ~collinear {v0,v1,w1} /\ ~collinear {v0,v1,w2} + ==> (azim v0 v1 w1 w2 = &0 \/ azim v0 v1 w1 w2 = pi <=> + coplanar {v0,v1,w1,w2})`, + REWRITE_TAC[TAUT `(a <=> b) <=> (a ==> b) /\ (b ==> a)`] THEN + REWRITE_TAC[AZIM_EQ_0_PI_IMP_COPLANAR] THEN + SIMP_TAC[GSYM IMP_CONJ_ALT; COPLANAR; DIMINDEX_3; ARITH] THEN + REWRITE_TAC[IMP_CONJ; LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC + [`v0:real^3`; `v1:real^3`; `v2:real^3`; `v3:real^3`; `p:real^3->bool`] THEN + GEOM_HORIZONTAL_PLANE_TAC `p:real^3->bool` THEN + REWRITE_TAC[INSERT_SUBSET; IN_ELIM_THM; IMP_CONJ; RIGHT_FORALL_IMP_THM; + EMPTY_SUBSET] THEN + SIMP_TAC[AZIM_DIHV_EQ_0; AZIM_DIHV_EQ_PI] THEN + REWRITE_TAC[DIHV] THEN + CONV_TAC(TOP_DEPTH_CONV let_CONV) THEN + DISCH_THEN(K ALL_TAC) THEN PAD2D3D_TAC THEN + REWRITE_TAC[angle; VECTOR_SUB_RZERO] THEN + GEOM_ORIGIN_TAC `v0:real^2` THEN REWRITE_TAC[VECTOR_SUB_RZERO] THEN + REPEAT STRIP_TAC THEN + W(MP_TAC o PART_MATCH (rand o rand) COLLINEAR_VECTOR_ANGLE o snd) THEN + ANTS_TAC THENL + [REPEAT(POP_ASSUM MP_TAC); DISCH_THEN(SUBST1_TAC o SYM)] THEN + REWRITE_TAC[GSYM DOT_CAUCHY_SCHWARZ_EQUAL] THEN + REWRITE_TAC[DOT_2; CART_EQ; FORALL_2; DIMINDEX_2; VEC_COMPONENT; + VECTOR_SUB_COMPONENT; VECTOR_MUL_COMPONENT] THEN + CONV_TAC REAL_RING);; + +let DIHV_EQ_0_PI_EQ_COPLANAR = prove + (`!v0 v1 w1 w2:real^3. + ~collinear {v0,v1,w1} /\ ~collinear {v0,v1,w2} + ==> (dihV v0 v1 w1 w2 = &0 \/ dihV v0 v1 w1 w2 = pi <=> + coplanar {v0,v1,w1,w2})`, + SIMP_TAC[GSYM AZIM_DIHV_EQ_0; GSYM AZIM_DIHV_EQ_PI; + AZIM_EQ_0_PI_EQ_COPLANAR]);; + +let DIHV_SYM = prove + (`!v0 v1 v2 v3:real^N. + dihV v0 v1 v3 v2 = dihV v0 v1 v2 v3`, + REPEAT GEN_TAC THEN REWRITE_TAC[DIHV] THEN + CONV_TAC(TOP_DEPTH_CONV let_CONV) THEN + REWRITE_TAC[DOT_SYM; ANGLE_SYM]);; + +let DIHV_NEG = prove + (`!v0 v1 v2 v3. dihV (--v0) (--v1) (--v2) (--v3) = dihV v0 v1 v2 v3`, + REWRITE_TAC[DIHV; VECTOR_ARITH `--a - --b:real^N = --(a - b)`] THEN + CONV_TAC(TOP_DEPTH_CONV let_CONV) THEN + REWRITE_TAC[DOT_RNEG; DOT_LNEG; REAL_NEG_NEG] THEN + REWRITE_TAC[VECTOR_MUL_RNEG] THEN + REWRITE_TAC[angle; VECTOR_ARITH `--a - --b:real^N = --(a - b)`] THEN + REWRITE_TAC[VECTOR_SUB_RZERO; VECTOR_ANGLE_NEG2]);; + +let DIHV_NEG_0 = prove + (`!v1 v2 v3. dihV (vec 0) (--v1) (--v2) (--v3) = dihV (vec 0) v1 v2 v3`, + REPEAT GEN_TAC THEN + GEN_REWRITE_TAC RAND_CONV [GSYM DIHV_NEG] THEN + REWRITE_TAC[VECTOR_NEG_0]);; + +let DIHV_ARCV = prove + (`!e u v w:real^N. + orthogonal (e - u) (v - u) /\ orthogonal (e - u) (w - u) /\ ~(e = u) + ==> dihV u e v w = arcV u v w`, + GEOM_ORIGIN_TAC `u:real^N` THEN + REWRITE_TAC[dihV; orthogonal; VECTOR_SUB_RZERO] THEN + CONV_TAC(TOP_DEPTH_CONV let_CONV) THEN + SIMP_TAC[DOT_SYM; VECTOR_MUL_LZERO; VECTOR_SUB_RZERO] THEN + REWRITE_TAC[ARCV_ANGLE; angle; VECTOR_SUB_RZERO] THEN + REWRITE_TAC[VECTOR_ANGLE_LMUL; VECTOR_ANGLE_RMUL] THEN + SIMP_TAC[DOT_POS_LE; DOT_EQ_0]);; + +let AZIM_DIHV_SAME_STRONG = prove + (`!v w v1 v2:real^3. + ~collinear {v,w,v1} /\ ~collinear {v,w,v2} /\ + azim v w v1 v2 <= pi + ==> azim v w v1 v2 = dihV v w v1 v2`, + REWRITE_TAC[REAL_LE_LT] THEN + MESON_TAC[AZIM_DIHV_SAME; AZIM_DIHV_EQ_PI]);; + +let AZIM_ARCV = prove + (`!e u v w:real^3. + orthogonal (e - u) (v - u) /\ orthogonal (e - u) (w - u) /\ + ~collinear{u,e,v} /\ ~collinear{u,e,w} /\ + azim u e v w <= pi + ==> azim u e v w = arcV u v w`, + REPEAT GEN_TAC THEN ASM_CASES_TAC `u:real^3 = e` THENL + [ASM_REWRITE_TAC[INSERT_AC; COLLINEAR_2]; ALL_TAC] THEN + STRIP_TAC THEN ASM_SIMP_TAC[GSYM DIHV_ARCV] THEN + MATCH_MP_TAC AZIM_DIHV_SAME_STRONG THEN ASM_REWRITE_TAC[]);; + +let COLLINEAR_AZIM_0_OR_PI = prove + (`!u e v w. collinear {u,v,w} ==> azim u e v w = &0 \/ azim u e v w = pi`, + REPEAT STRIP_TAC THEN + ASM_CASES_TAC `collinear{u:real^3,e,v}` THEN + ASM_SIMP_TAC[AZIM_DEGENERATE] THEN + ASM_CASES_TAC `collinear{u:real^3,e,w}` THEN + ASM_SIMP_TAC[AZIM_DEGENERATE] THEN + ASM_SIMP_TAC[AZIM_EQ_0_PI_EQ_COPLANAR] THEN + ONCE_REWRITE_TAC[SET_RULE `{u,e,v,w} = {u,v,w,e}`] THEN + ASM_MESON_TAC[NOT_COPLANAR_NOT_COLLINEAR]);; + +let REAL_CONTINUOUS_WITHIN_DIHV_COMPOSE = prove + (`!f:real^M->real^N g h k x s. + ~collinear {f x,g x,h x} /\ ~collinear {f x,g x,k x} /\ + f continuous (at x within s) /\ g continuous (at x within s) /\ + h continuous (at x within s) /\ k continuous (at x within s) + ==> (\x. dihV (f x) (g x) (h x) (k x)) real_continuous (at x within s)`, + REPEAT STRIP_TAC THEN REWRITE_TAC[dihV] THEN + CONV_TAC(TOP_DEPTH_CONV let_CONV) THEN + REWRITE_TAC[ARCV_ANGLE; angle; REAL_CONTINUOUS_CONTINUOUS; o_DEF] THEN + REWRITE_TAC[VECTOR_SUB_RZERO] THEN + MATCH_MP_TAC CONTINUOUS_WITHIN_CX_VECTOR_ANGLE_COMPOSE THEN + ASM_REWRITE_TAC[VECTOR_SUB_EQ; GSYM COLLINEAR_3_DOT_MULTIPLES] THEN + CONJ_TAC THEN MATCH_MP_TAC CONTINUOUS_SUB THEN CONJ_TAC THEN + MATCH_MP_TAC CONTINUOUS_MUL THEN REWRITE_TAC[o_DEF] THEN + ASM_SIMP_TAC[CONTINUOUS_LIFT_DOT2; o_DEF; CONTINUOUS_SUB]);; + +let REAL_CONTINUOUS_AT_DIHV_COMPOSE = prove + (`!f:real^M->real^N g h k x. + ~collinear {f x,g x,h x} /\ ~collinear {f x,g x,k x} /\ + f continuous (at x) /\ g continuous (at x) /\ + h continuous (at x) /\ k continuous (at x) + ==> (\x. dihV (f x) (g x) (h x) (k x)) real_continuous (at x)`, + ONCE_REWRITE_TAC[GSYM WITHIN_UNIV] THEN + REWRITE_TAC[REAL_CONTINUOUS_WITHIN_DIHV_COMPOSE]);; + +let REAL_CONTINUOUS_WITHINREAL_DIHV_COMPOSE = prove + (`!f:real->real^N g h k x s. + ~collinear {f x,g x,h x} /\ ~collinear {f x,g x,k x} /\ + f continuous (atreal x within s) /\ g continuous (atreal x within s) /\ + h continuous (atreal x within s) /\ k continuous (atreal x within s) + ==> (\x. dihV (f x) (g x) (h x) (k x)) real_continuous + (atreal x within s)`, + REWRITE_TAC[CONTINUOUS_CONTINUOUS_WITHINREAL; + REAL_CONTINUOUS_REAL_CONTINUOUS_WITHINREAL] THEN + SIMP_TAC[o_DEF; REAL_CONTINUOUS_WITHIN_DIHV_COMPOSE; LIFT_DROP]);; + +let REAL_CONTINUOUS_ATREAL_DIHV_COMPOSE = prove + (`!f:real->real^N g h k x. + ~collinear {f x,g x,h x} /\ ~collinear {f x,g x,k x} /\ + f continuous (atreal x) /\ g continuous (atreal x) /\ + h continuous (atreal x) /\ k continuous (atreal x) + ==> (\x. dihV (f x) (g x) (h x) (k x)) real_continuous (atreal x)`, + ONCE_REWRITE_TAC[GSYM WITHINREAL_UNIV] THEN + REWRITE_TAC[REAL_CONTINUOUS_WITHINREAL_DIHV_COMPOSE]);; + +let REAL_CONTINUOUS_AT_DIHV = prove + (`!v w w1 w2:real^N. + ~collinear {v, w, w2} ==> dihV v w w1 real_continuous at w2`, + REPEAT STRIP_TAC THEN GEN_REWRITE_TAC LAND_CONV [GSYM ETA_AX] THEN + REWRITE_TAC[dihV] THEN CONV_TAC(TOP_DEPTH_CONV let_CONV) THEN + GEN_REWRITE_TAC LAND_CONV [GSYM o_DEF] THEN + MATCH_MP_TAC REAL_CONTINUOUS_CONTINUOUS_AT_COMPOSE THEN CONJ_TAC THENL + [MATCH_MP_TAC CONTINUOUS_SUB THEN CONJ_TAC THEN + MATCH_MP_TAC CONTINUOUS_MUL THEN + SIMP_TAC[CONTINUOUS_CONST; o_DEF; CONTINUOUS_SUB; CONTINUOUS_AT_ID; + CONTINUOUS_LIFT_DOT2]; + GEN_REWRITE_TAC LAND_CONV [GSYM ETA_AX] THEN + REWRITE_TAC[ARCV_ANGLE; angle] THEN + REWRITE_TAC[VECTOR_SUB_RZERO; ETA_AX] THEN + MATCH_MP_TAC REAL_CONTINUOUS_WITHIN_VECTOR_ANGLE THEN + POP_ASSUM MP_TAC THEN GEOM_ORIGIN_TAC `v:real^N` THEN + REWRITE_TAC[VECTOR_SUB_RZERO; CONTRAPOS_THM; VECTOR_SUB_EQ] THEN + MAP_EVERY X_GEN_TAC [`z:real^N`; `w:real^N`] THEN + ASM_CASES_TAC `w:real^N = vec 0` THEN + ASM_REWRITE_TAC[COLLINEAR_LEMMA_ALT] THEN DISCH_THEN(MP_TAC o AP_TERM + `(%) (inv((w:real^N) dot w)):real^N->real^N`) THEN + ASM_SIMP_TAC[VECTOR_MUL_ASSOC; REAL_MUL_LINV; DOT_EQ_0] THEN + MESON_TAC[VECTOR_MUL_LID]]);; + +let REAL_CONTINUOUS_WITHIN_AZIM_COMPOSE = prove + (`!f:real^M->real^3 g h k x s. + ~collinear {f x,g x,h x} /\ ~collinear {f x,g x,k x} /\ + ~(k x IN aff_ge {f x,g x} {h x}) /\ + f continuous (at x within s) /\ g continuous (at x within s) /\ + h continuous (at x within s) /\ k continuous (at x within s) + ==> (\x. azim (f x) (g x) (h x) (k x)) real_continuous (at x within s)`, + let lemma = prove + (`!s t u f:real^M->real^N g h. + (closed s /\ closed t) /\ s UNION t = UNIV /\ + (g continuous_on (u INTER s) /\ h continuous_on (u INTER t)) /\ + (!x. x IN u INTER s ==> g x = f x) /\ + (!x. x IN u INTER t ==> h x = f x) + ==> f continuous_on u`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN `u:real^M->bool = (u INTER s) UNION (u INTER t)` + SUBST1_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + MATCH_MP_TAC CONTINUOUS_ON_UNION_LOCAL THEN + REWRITE_TAC[CLOSED_IN_CLOSED] THEN REPEAT CONJ_TAC THENL + [EXISTS_TAC `s:real^M->bool` THEN ASM SET_TAC[]; + EXISTS_TAC `t:real^M->bool` THEN ASM SET_TAC[]; + ASM_MESON_TAC[CONTINUOUS_ON_EQ]; + ASM_MESON_TAC[CONTINUOUS_ON_EQ]]) in + REPEAT STRIP_TAC THEN REWRITE_TAC[REAL_CONTINUOUS_CONTINUOUS; o_DEF] THEN + SUBGOAL_THEN + `(\x:real^M. Cx(azim (f x) (g x) (h x) (k x))) = + (\z. Cx(azim (vec 0) (fstcart z) + (fstcart(sndcart z)) (sndcart(sndcart z)))) o + (\x. pastecart (g x - f x) (pastecart (h x - f x) (k x - f x)))` + SUBST1_TAC THENL + [REWRITE_TAC[FUN_EQ_THM; o_THM; FSTCART_PASTECART; SNDCART_PASTECART] THEN + X_GEN_TAC `y:real^M` THEN + SUBST1_TAC(VECTOR_ARITH `vec 0 = (f:real^M->real^3) y - f y`) THEN + SIMP_TAC[ONCE_REWRITE_RULE[VECTOR_ADD_SYM] AZIM_TRANSLATION; VECTOR_SUB]; + MATCH_MP_TAC CONTINUOUS_WITHIN_COMPOSE THEN + ASM_SIMP_TAC[CONTINUOUS_PASTECART; CONTINUOUS_SUB]] THEN + MATCH_MP_TAC CONTINUOUS_AT_WITHIN THEN + SUBGOAL_THEN + `!z. ~collinear {vec 0,fstcart z,fstcart(sndcart z)} /\ + ~collinear {vec 0,fstcart z,sndcart(sndcart z)} /\ + ~(sndcart(sndcart z) IN aff_ge {vec 0,fstcart z} {fstcart(sndcart z)}) + ==> (\z. Cx(azim (vec 0) (fstcart z) (fstcart(sndcart z)) + (sndcart(sndcart z)))) + continuous (at z)` + MATCH_MP_TAC THENL + [ALL_TAC; + ASM_SIMP_TAC[FSTCART_PASTECART; SNDCART_PASTECART; GSYM COLLINEAR_3] THEN + REPEAT(CONJ_TAC THENL [ASM_MESON_TAC[INSERT_AC]; ALL_TAC]) THEN + SUBST1_TAC(VECTOR_ARITH `vec 0 = (f:real^M->real^3) x - f x`) THEN + ONCE_REWRITE_TAC[SET_RULE `{a,b} = {a} UNION {b}`] THEN + REWRITE_TAC[GSYM IMAGE_UNION; SET_RULE + `{a - b:real^3} = IMAGE (\x. x - b) {a}`] THEN + REWRITE_TAC[ONCE_REWRITE_RULE[VECTOR_ADD_SYM] AFF_GE_TRANSLATION; + VECTOR_SUB] THEN + ASM_REWRITE_TAC[IN_IMAGE; VECTOR_ARITH `a + x:real^3 = b + x <=> a = b`; + UNWIND_THM1; SET_RULE `{a} UNION {b} = {a,b}`]] THEN + ONCE_REWRITE_TAC[SET_RULE + `(!x. ~P x /\ ~Q x /\ ~R x ==> J x) <=> + (!x. x IN UNIV DIFF (({x | P x} UNION {x | Q x}) UNION {x | R x}) + ==> J x)`] THEN + MATCH_MP_TAC(MESON[CONTINUOUS_ON_EQ_CONTINUOUS_AT] + `open s /\ f continuous_on s ==> !z. z IN s ==> f continuous at z`) THEN + CONJ_TAC THENL + [REWRITE_TAC[GSYM closed] THEN + MATCH_MP_TAC(MESON[] + `!t'. s UNION t = s UNION t' /\ closed(s UNION t') + ==> closed(s UNION t)`) THEN + EXISTS_TAC + `{z | (fstcart z cross fstcart(sndcart z)) cross + fstcart z cross sndcart(sndcart z) = vec 0 /\ + &0 <= (fstcart z cross sndcart(sndcart z)) dot + (fstcart z cross fstcart(sndcart z))}` THEN + CONJ_TAC THENL + [MATCH_MP_TAC(SET_RULE + `(!x. ~(x IN s) ==> (x IN t <=> x IN t')) + ==> s UNION t = s UNION t'`) THEN + REWRITE_TAC[AFF_GE_2_1_0_SEMIALGEBRAIC; IN_UNION; IN_ELIM_THM; + DE_MORGAN_THM]; + ALL_TAC] THEN + MATCH_MP_TAC CLOSED_UNION THEN CONJ_TAC THENL + [MATCH_MP_TAC CLOSED_UNION THEN CONJ_TAC THEN + REWRITE_TAC[GSYM DOT_CAUCHY_SCHWARZ_EQUAL] THEN + ONCE_REWRITE_TAC[GSYM REAL_SUB_0] THEN + REWRITE_TAC[GSYM LIFT_EQ; LIFT_NUM] THEN + SIMP_TAC[SET_RULE `{x | f x = a} = {x | x IN UNIV /\ f x IN {a}}`] THEN + MATCH_MP_TAC CONTINUOUS_CLOSED_PREIMAGE THEN + SIMP_TAC[CLOSED_UNIV; CLOSED_SING; LIFT_SUB; REAL_POW_2; LIFT_CMUL] THEN + MATCH_MP_TAC CONTINUOUS_ON_SUB THEN + CONJ_TAC THEN MATCH_MP_TAC CONTINUOUS_ON_MUL THEN + REWRITE_TAC[o_DEF] THEN REPEAT CONJ_TAC THEN + MATCH_MP_TAC CONTINUOUS_ON_LIFT_DOT2 THEN CONJ_TAC; + ONCE_REWRITE_TAC[MESON[LIFT_DROP; real_ge] + `&0 <= x <=> drop(lift x) >= &0`] THEN + REWRITE_TAC[SET_RULE + `{z | f z = vec 0 /\ drop(g z) >= &0} = + {z | z IN UNIV /\ f z IN {vec 0}} INTER + {z | z IN UNIV /\ g z IN {k | drop(k) >= &0}}`] THEN + MATCH_MP_TAC CLOSED_INTER THEN + CONJ_TAC THEN MATCH_MP_TAC CONTINUOUS_CLOSED_PREIMAGE THEN + REWRITE_TAC[CLOSED_SING; drop; CLOSED_UNIV; + CLOSED_HALFSPACE_COMPONENT_GE] THEN + REPEAT((MATCH_MP_TAC CONTINUOUS_ON_CROSS ORELSE + MATCH_MP_TAC CONTINUOUS_ON_LIFT_DOT2) THEN CONJ_TAC)] THEN + TRY(GEN_REWRITE_TAC LAND_CONV [GSYM o_DEF]) THEN + SIMP_TAC[CONTINUOUS_ON_COMPOSE; LINEAR_CONTINUOUS_ON; + LINEAR_FSTCART; LINEAR_SNDCART]; + MATCH_MP_TAC lemma THEN + MAP_EVERY EXISTS_TAC + [`{z | z IN UNIV /\ lift((fstcart z cross (fstcart(sndcart z))) dot + (sndcart(sndcart z))) IN {x | x$1 >= &0}}`; + `{z | z IN UNIV /\ lift((fstcart z cross (fstcart(sndcart z))) dot + (sndcart(sndcart z))) IN {x | x$1 <= &0}}`; + `\z. Cx(dihV (vec 0:real^3) (fstcart z) + (fstcart(sndcart z)) (sndcart(sndcart z)))`; + `\z. Cx(&2 * pi - dihV (vec 0:real^3) (fstcart z) + (fstcart(sndcart z)) (sndcart(sndcart z)))`] THEN + CONJ_TAC THENL + [CONJ_TAC THEN MATCH_MP_TAC CONTINUOUS_CLOSED_PREIMAGE THEN + REWRITE_TAC[CLOSED_UNIV; CLOSED_HALFSPACE_COMPONENT_GE; + CLOSED_HALFSPACE_COMPONENT_LE] THEN + MATCH_MP_TAC CONTINUOUS_ON_LIFT_DOT2 THEN + (CONJ_TAC THENL [MATCH_MP_TAC CONTINUOUS_ON_CROSS; ALL_TAC]) THEN + ONCE_REWRITE_TAC[GSYM o_DEF] THEN + SIMP_TAC[CONTINUOUS_ON_COMPOSE; LINEAR_CONTINUOUS_ON; + LINEAR_FSTCART; LINEAR_SNDCART]; + ALL_TAC] THEN + CONJ_TAC THENL + [REWRITE_TAC[EXTENSION; IN_UNION; IN_UNIV; IN_ELIM_THM] THEN + REAL_ARITH_TAC; + ALL_TAC] THEN + CONJ_TAC THENL + [CONJ_TAC THEN MATCH_MP_TAC CONTINUOUS_AT_IMP_CONTINUOUS_ON THEN + REWRITE_TAC[FORALL_PASTECART; IN_DIFF; IN_UNIV; IN_UNION; IN_INTER; + FSTCART_PASTECART; SNDCART_PASTECART; IN_ELIM_THM; DE_MORGAN_THM] THEN + MAP_EVERY X_GEN_TAC [`x:real^3`; `y:real^3`; `z:real^3`] THEN + REPEAT STRIP_TAC THEN REWRITE_TAC[CX_SUB] THEN + TRY(MATCH_MP_TAC CONTINUOUS_SUB THEN REWRITE_TAC[CONTINUOUS_CONST]) THEN + GEN_REWRITE_TAC LAND_CONV [GSYM o_DEF] THEN + REWRITE_TAC[GSYM REAL_CONTINUOUS_CONTINUOUS] THEN + MATCH_MP_TAC REAL_CONTINUOUS_AT_DIHV_COMPOSE THEN + ASM_REWRITE_TAC[FSTCART_PASTECART; SNDCART_PASTECART; + CONTINUOUS_CONST] THEN + ONCE_REWRITE_TAC[GSYM o_DEF] THEN + SIMP_TAC[CONTINUOUS_AT_COMPOSE; LINEAR_CONTINUOUS_AT; + LINEAR_FSTCART; LINEAR_SNDCART]; + ALL_TAC] THEN + REWRITE_TAC[FORALL_PASTECART; IN_DIFF; IN_UNIV; IN_UNION; IN_INTER; CX_INJ; + FSTCART_PASTECART; SNDCART_PASTECART; IN_ELIM_THM; DE_MORGAN_THM] THEN + CONJ_TAC THENL + [REWRITE_TAC[GSYM drop; LIFT_DROP; real_ge] THEN + MAP_EVERY X_GEN_TAC [`x:real^3`; `y:real^3`; `z:real^3`] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC(GSYM AZIM_DIHV_SAME_STRONG) THEN + ASM_REWRITE_TAC[AZIM_IN_UPPER_HALFSPACE; VECTOR_SUB_RZERO]; + REWRITE_TAC[GSYM drop; LIFT_DROP] THEN + MAP_EVERY X_GEN_TAC [`x:real^3`; `y:real^3`; `z:real^3`] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC(GSYM AZIM_DIHV_COMPL) THEN + ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC(REAL_ARITH + `(x <= pi ==> x = pi) ==> pi <= x`) THEN + ASM_REWRITE_TAC[AZIM_IN_UPPER_HALFSPACE; VECTOR_SUB_RZERO] THEN + ASM_SIMP_TAC[REAL_ARITH `x <= &0 ==> (&0 <= x <=> x = &0)`] THEN + REWRITE_TAC[REWRITE_RULE[VECTOR_SUB_RZERO] + (SPEC `vec 0:real^3` (GSYM COPLANAR_CROSS_DOT))] THEN + ASM_SIMP_TAC[GSYM AZIM_EQ_0_PI_EQ_COPLANAR; AZIM_EQ_0_GE_ALT]]]);; + +let REAL_CONTINUOUS_AT_AZIM_COMPOSE = prove + (`!f:real^M->real^3 g h k x. + ~collinear {f x,g x,h x} /\ ~collinear {f x,g x,k x} /\ + ~(k x IN aff_ge {f x,g x} {h x}) /\ + f continuous (at x) /\ g continuous (at x) /\ + h continuous (at x) /\ k continuous (at x) + ==> (\x. azim (f x) (g x) (h x) (k x)) real_continuous (at x)`, + ONCE_REWRITE_TAC[GSYM WITHIN_UNIV] THEN + REWRITE_TAC[REAL_CONTINUOUS_WITHIN_AZIM_COMPOSE]);; + +let REAL_CONTINUOUS_WITHINREAL_AZIM_COMPOSE = prove + (`!f:real->real^3 g h k x s. + ~collinear {f x,g x,h x} /\ ~collinear {f x,g x,k x} /\ + ~(k x IN aff_ge {f x,g x} {h x}) /\ + f continuous (atreal x within s) /\ g continuous (atreal x within s) /\ + h continuous (atreal x within s) /\ k continuous (atreal x within s) + ==> (\x. azim (f x) (g x) (h x) (k x)) real_continuous + (atreal x within s)`, + REWRITE_TAC[CONTINUOUS_CONTINUOUS_WITHINREAL; + REAL_CONTINUOUS_REAL_CONTINUOUS_WITHINREAL] THEN + SIMP_TAC[o_DEF; REAL_CONTINUOUS_WITHIN_AZIM_COMPOSE; LIFT_DROP]);; + +let REAL_CONTINUOUS_ATREAL_AZIM_COMPOSE = prove + (`!f:real->real^3 g h k x. + ~collinear {f x,g x,h x} /\ ~collinear {f x,g x,k x} /\ + ~(k x IN aff_ge {f x,g x} {h x}) /\ + f continuous (atreal x) /\ g continuous (atreal x) /\ + h continuous (atreal x) /\ k continuous (atreal x) + ==> (\x. azim (f x) (g x) (h x) (k x)) real_continuous (atreal x)`, + ONCE_REWRITE_TAC[GSYM WITHINREAL_UNIV] THEN + REWRITE_TAC[REAL_CONTINUOUS_WITHINREAL_AZIM_COMPOSE]);; + +(* ------------------------------------------------------------------------- *) +(* Can consider angle as defined by arcV a zenith angle. *) +(* ------------------------------------------------------------------------- *) + +let ZENITH_EXISTS = prove + (`!u v w:real^3. + ~(u = v) /\ ~(w = v) + ==> (?u' r phi e3. + phi = arcV v u w /\ + r = dist(u,v) /\ + dist(w,v) % e3 = w - v /\ + u' dot e3 = &0 /\ + u = v + u' + (r * cos phi) % e3)`, + ONCE_REWRITE_TAC[VECTOR_ARITH + `u:real^3 = v + u' + x <=> u - v = u' + x`] THEN + GEN_GEOM_ORIGIN_TAC `v:real^3` ["u'"; "e3"] THEN + REWRITE_TAC[VECTOR_SUB_RZERO; DIST_0] THEN + ONCE_REWRITE_TAC[VECTOR_ARITH + `u:real^3 = u' + x <=> u - u' = x`] THEN + GEOM_BASIS_MULTIPLE_TAC 3 `w:real^3` THEN + X_GEN_TAC `w:real` THEN ASM_CASES_TAC `w = &0` THEN + ASM_REWRITE_TAC[VECTOR_MUL_LZERO; REAL_LE_LT] THEN DISCH_TAC THEN + SIMP_TAC[NORM_MUL; NORM_BASIS; DIMINDEX_3; ARITH] THEN + ASM_SIMP_TAC[REAL_ARITH `&0 < w ==> abs w * &1 = w`] THEN + ASM_SIMP_TAC[VECTOR_MUL_LCANCEL; REAL_LT_IMP_NZ] THEN + REWRITE_TAC[RIGHT_EXISTS_AND_THM; UNWIND_THM2] THEN + REWRITE_TAC[ARCV_ANGLE; angle; VECTOR_SUB_RZERO] THEN + ASM_SIMP_TAC[VECTOR_MUL_EQ_0; REAL_LT_IMP_NZ] THEN REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`u:real^3`; `w % basis 3:real^3`] VECTOR_ANGLE) THEN + REWRITE_TAC[DOT_RMUL; NORM_MUL] THEN + ASM_SIMP_TAC[REAL_ARITH + `&0 < w ==> n * ((abs w) * x) * y = w * n * x * y`] THEN + ASM_REWRITE_TAC[REAL_EQ_MUL_LCANCEL] THEN + SIMP_TAC[NORM_BASIS; DIMINDEX_3; ARITH; REAL_MUL_LID] THEN + DISCH_THEN(SUBST1_TAC o SYM) THEN + REWRITE_TAC[VECTOR_ARITH `u - u':real^3 = x <=> u' = u - x`] THEN + ONCE_REWRITE_TAC[CONJ_SYM] THEN REWRITE_TAC[UNWIND_THM2] THEN + REWRITE_TAC[DOT_LSUB; DOT_RMUL; DOT_LMUL] THEN + SIMP_TAC[DOT_BASIS_BASIS; DIMINDEX_3; ARITH] THEN REAL_ARITH_TAC);; + +(* ------------------------------------------------------------------------- *) +(* Spherical coordinates. *) +(* ------------------------------------------------------------------------- *) + +let SPHERICAL_COORDINATES = prove + (`!u v w u' e1 e2 e3 r phi theta. + ~collinear {v, w, u} /\ + ~collinear {v, w, u'} /\ + orthonormal e1 e2 e3 /\ + dist(w,v) % e3 = w - v /\ + (v + e1) IN aff_gt {v, w} {u} /\ + r = dist(v,u') /\ + phi = arcV v u' w /\ + theta = azim v w u u' + ==> u' = v + (r * cos theta * sin phi) % e1 + + (r * sin theta * sin phi) % e2 + + (r * cos phi) % e3`, + ONCE_REWRITE_TAC[VECTOR_ARITH + `u':real^3 = u + v + w <=> u' - u = v + w`] THEN + GEN_GEOM_ORIGIN_TAC `v:real^3` ["e1"; "e2"; "e3"] THEN + REWRITE_TAC[VECTOR_ADD_RID; VECTOR_ADD_LID] THEN + REWRITE_TAC[TRANSLATION_INVARIANTS `v:real^3`] THEN + GEOM_BASIS_MULTIPLE_TAC 3 `w:real^3` THEN + REWRITE_TAC[VECTOR_SUB_RZERO; DIST_0] THEN + X_GEN_TAC `w:real` THEN ASM_CASES_TAC `w = &0` THENL + [ASM_REWRITE_TAC[VECTOR_MUL_LZERO; INSERT_AC; COLLINEAR_2]; ALL_TAC] THEN + ASM_REWRITE_TAC[REAL_LE_LT] THEN DISCH_TAC THEN + MAP_EVERY X_GEN_TAC + [`u:real^3`; `v:real^3`; `e1:real^3`; `e2:real^3`; `e3:real^3`; + `r:real`; `phi:real`; `theta:real`] THEN + ASM_CASES_TAC `u:real^3 = w % basis 3` THENL + [ASM_REWRITE_TAC[INSERT_AC; COLLINEAR_2]; ALL_TAC] THEN + ASM_CASES_TAC `v:real^3 = w % basis 3` THENL + [ASM_REWRITE_TAC[INSERT_AC; COLLINEAR_2]; ALL_TAC] THEN + DISCH_THEN(MP_TAC o GSYM) THEN + ASM_SIMP_TAC[AZIM_SPECIAL_SCALE; COLLINEAR_SPECIAL_SCALE] THEN + SIMP_TAC[NORM_MUL; NORM_BASIS; DIMINDEX_3; ARITH] THEN + ASM_SIMP_TAC[REAL_ARITH `&0 < w ==> abs w * &1 = w`] THEN + ASM_REWRITE_TAC[VECTOR_MUL_LCANCEL] THEN + ASM_CASES_TAC `e3:real^3 = basis 3` THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[ARCV_ANGLE; angle; VECTOR_SUB_RZERO] THEN + ASM_SIMP_TAC[VECTOR_ANGLE_RMUL; REAL_LT_IMP_LE] THEN + ASM_CASES_TAC `u:real^3 = vec 0` THENL + [ASM_REWRITE_TAC[INSERT_AC; COLLINEAR_2]; ALL_TAC] THEN + ASM_CASES_TAC `v:real^3 = vec 0` THENL + [ASM_REWRITE_TAC[INSERT_AC; COLLINEAR_2]; ALL_TAC] THEN + ASM_CASES_TAC `u:real^3 = basis 3` THENL + [ASM_REWRITE_TAC[INSERT_AC; COLLINEAR_2]; ALL_TAC] THEN + ASM_CASES_TAC `v:real^3 = basis 3` THENL + [ASM_REWRITE_TAC[INSERT_AC; COLLINEAR_2]; ALL_TAC] THEN + STRIP_TAC THEN + MP_TAC(ISPECL [`v:real^3`; `basis 3:real^3`] VECTOR_ANGLE) THEN + ASM_SIMP_TAC[DOT_BASIS; NORM_BASIS; DIMINDEX_3; ARITH; REAL_MUL_LID] THEN + DISCH_TAC THEN + MP_TAC(ISPECL + [`vec 0:real^3`; `w % basis 3:real^3`; `u:real^3`; `e1:real^3`] + AZIM_EQ_0_ALT) THEN + ASM_SIMP_TAC[AZIM_SPECIAL_SCALE; COLLINEAR_SPECIAL_SCALE] THEN + ANTS_TAC THENL + [SIMP_TAC[COLLINEAR_LEMMA; BASIS_NONZERO; DIMINDEX_3; ARITH] THEN + STRIP_TAC THEN UNDISCH_TAC `orthonormal e1 e2 (basis 3)` THEN + ASM_REWRITE_TAC[orthonormal; DOT_LZERO; REAL_OF_NUM_EQ; ARITH_EQ] THEN + ASM_CASES_TAC `c = &0` THEN + ASM_SIMP_TAC[VECTOR_MUL_LZERO; CROSS_LZERO; DOT_LZERO; REAL_LT_REFL; + DOT_LMUL; DOT_BASIS_BASIS; DIMINDEX_3; ARITH; REAL_MUL_RID]; + DISCH_TAC] THEN + SUBGOAL_THEN + `dropout 3 (v:real^3):real^2 = + norm(dropout 3 (v:real^3):real^2) % + (cos theta % (dropout 3 (e1:real^3)) + + sin theta % (dropout 3 (e2:real^3)))` + MP_TAC THENL + [ALL_TAC; + SUBGOAL_THEN `norm((dropout 3:real^3->real^2) v) = r * sin phi` + SUBST1_TAC THENL + [REWRITE_TAC[NORM_EQ_SQUARE] THEN CONJ_TAC THENL + [ASM_MESON_TAC[REAL_LE_MUL; NORM_POS_LE; SIN_VECTOR_ANGLE_POS]; + ALL_TAC] THEN + UNDISCH_TAC `(v:real^3)$3 = r * cos phi` THEN + MATCH_MP_TAC(REAL_RING + `x + a pow 2 = y + b pow 2 ==> a:real = b ==> x = y`) THEN + REWRITE_TAC[REAL_POW_MUL; GSYM REAL_ADD_LDISTRIB] THEN + REWRITE_TAC[SIN_CIRCLE; REAL_MUL_RID] THEN + UNDISCH_THEN `norm(v:real^3) = r` (SUBST1_TAC o SYM) THEN + REWRITE_TAC[NORM_POW_2; DOT_2; DOT_3] THEN + SIMP_TAC[dropout; LAMBDA_BETA; DIMINDEX_2; ARITH] THEN + REAL_ARITH_TAC; + ALL_TAC] THEN + REWRITE_TAC[CART_EQ; DIMINDEX_3; DIMINDEX_2; FORALL_3; FORALL_2] THEN + SIMP_TAC[dropout; LAMBDA_BETA; DIMINDEX_2; ARITH; VECTOR_ADD_COMPONENT; + VECTOR_MUL_COMPONENT; BASIS_COMPONENT; DIMINDEX_3] THEN + REPEAT STRIP_TAC THEN TRY REAL_ARITH_TAC THEN + ASM_REWRITE_TAC[] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [orthonormal]) THEN + SIMP_TAC[DOT_BASIS; DIMINDEX_3; ARITH] THEN CONV_TAC REAL_RING] THEN + REPEAT(FIRST_X_ASSUM(MP_TAC o + GEN_REWRITE_RULE LAND_CONV [AZIM_ARG])) THEN + REPEAT(FIRST_X_ASSUM(MP_TAC o + GEN_REWRITE_RULE RAND_CONV [COLLINEAR_BASIS_3])) THEN + SUBGOAL_THEN `norm((dropout 3:real^3->real^2) e1) = &1 /\ + norm((dropout 3:real^3->real^2) e2) = &1 /\ + dropout 3 (e2:real^3) / dropout 3 (e1:real^3) = ii` + MP_TAC THENL + [MATCH_MP_TAC(TAUT `(a /\ b) /\ (a /\ b ==> c) ==> a /\ b /\ c`) THEN + CONJ_TAC THENL + [REWRITE_TAC[NORM_EQ_1] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [orthonormal]) THEN + SIMP_TAC[DOT_BASIS; DIMINDEX_3; ARITH; dropout; LAMBDA_BETA; + DOT_2; DIMINDEX_2; DOT_3] THEN + CONV_TAC REAL_RING; + ALL_TAC] THEN + ASM_CASES_TAC `dropout 3 (e1:real^3) = Cx(&0)` THEN + ASM_SIMP_TAC[COMPLEX_NORM_CX; REAL_OF_NUM_EQ; ARITH_EQ; REAL_ABS_NUM] THEN + ASM_SIMP_TAC[COMPLEX_FIELD + `~(x = Cx(&0)) ==> (y / x = ii <=> y = ii * x)`] THEN + DISCH_TAC THEN FIRST_ASSUM(MP_TAC o MATCH_MP ORTHONORMAL_CROSS) THEN + SIMP_TAC[CART_EQ; DIMINDEX_2; DIMINDEX_3; FORALL_2; FORALL_3; + cross; VECTOR_3; BASIS_COMPONENT; ARITH; dropout; LAMBDA_BETA; + complex_mul; ii; complex; RE_DEF; IM_DEF; VECTOR_2] THEN + CONV_TAC REAL_RING; + ALL_TAC] THEN + SPEC_TAC(`(dropout 3:real^3->real^2) e2`,`d2:real^2`) THEN + SPEC_TAC(`(dropout 3:real^3->real^2) e1`,`d1:real^2`) THEN + SPEC_TAC(`(dropout 3:real^3->real^2) v`,`z:real^2`) THEN + SPEC_TAC(`(dropout 3:real^3->real^2) u`,`w:real^2`) THEN + POP_ASSUM_LIST(K ALL_TAC) THEN + GEOM_BASIS_MULTIPLE_TAC 1 `w:real^2` THEN + X_GEN_TAC `k:real` THEN GEN_REWRITE_TAC LAND_CONV [REAL_LE_LT] THEN + ASM_CASES_TAC `k = &0` THEN ASM_REWRITE_TAC[VECTOR_MUL_LZERO] THEN + REWRITE_TAC[COMPLEX_CMUL; COMPLEX_BASIS; COMPLEX_VEC_0] THEN + SIMP_TAC[ARG_DIV_CX; COMPLEX_MUL_RID] THEN DISCH_TAC THEN REPEAT GEN_TAC THEN + ASM_CASES_TAC `d1 = Cx(&1)` THENL + [ASM_SIMP_TAC[COMPLEX_DIV_1; COMPLEX_MUL_LID] THEN + REPEAT STRIP_TAC THEN MP_TAC(SPEC `z:complex` ARG) THEN + ASM_REWRITE_TAC[CEXP_EULER; CX_SIN; CX_COS; COMPLEX_MUL_RID] THEN + CONV_TAC COMPLEX_RING; + ASM_REWRITE_TAC[ARG_EQ_0] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE RAND_CONV [COMPLEX_EQ]) THEN + REWRITE_TAC[RE_CX; IM_CX;real] THEN + ASM_CASES_TAC `Im d1 = &0` THEN ASM_REWRITE_TAC[] THEN + ASM_SIMP_TAC[REAL_NORM; real] THEN REAL_ARITH_TAC]);; + +(* ------------------------------------------------------------------------- *) +(* Definition of a wedge and invariance theorems. *) +(* ------------------------------------------------------------------------- *) + +let wedge = new_definition + `wedge v0 v1 w1 w2 = {y | ~collinear {v0,v1,y} /\ + &0 < azim v0 v1 w1 y /\ + azim v0 v1 w1 y < azim v0 v1 w1 w2}`;; + +let WEDGE_ALT = prove + (`!v0 v1 w1 w2. + ~(v0 = v1) + ==> wedge v0 v1 w1 w2 = {y | ~(y IN affine hull {v0,v1}) /\ + &0 < azim v0 v1 w1 y /\ + azim v0 v1 w1 y < azim v0 v1 w1 w2}`, + SIMP_TAC[wedge; COLLINEAR_3_AFFINE_HULL]);; + +let WEDGE_TRANSLATION = prove + (`!a v w w1 w2. wedge (a + v) (a + w) (a + w1) (a + w2) = + IMAGE (\x. a + x) (wedge v w w1 w2)`, + REPEAT GEN_TAC THEN CONV_TAC SYM_CONV THEN + MATCH_MP_TAC SURJECTIVE_IMAGE_EQ THEN CONJ_TAC THENL + [MESON_TAC[VECTOR_ARITH `a + (x - a):real^3 = x`]; ALL_TAC] THEN + REWRITE_TAC[wedge; IN_ELIM_THM; AZIM_TRANSLATION] THEN + REWRITE_TAC[SET_RULE + `{a + x,a + y,a + z} = IMAGE (\x:real^N. a + x) {x,y,z}`] THEN + REWRITE_TAC[COLLINEAR_TRANSLATION_EQ]);; + +add_translation_invariants [WEDGE_TRANSLATION];; + +let WEDGE_LINEAR_IMAGE = prove + (`!f. linear f /\ (!x. norm(f x) = norm x) /\ + (2 <= dimindex(:3) ==> det(matrix f) = &1) + ==> !v w w1 w2. wedge (f v) (f w) (f w1) (f w2) = + IMAGE f (wedge v w w1 w2)`, + REPEAT STRIP_TAC THEN CONV_TAC SYM_CONV THEN + MATCH_MP_TAC SURJECTIVE_IMAGE_EQ THEN CONJ_TAC THENL + [ASM_MESON_TAC[ORTHOGONAL_TRANSFORMATION_SURJECTIVE; + ORTHOGONAL_TRANSFORMATION]; + ALL_TAC] THEN + X_GEN_TAC `y:real^3` THEN REWRITE_TAC[wedge; IN_ELIM_THM] THEN + BINOP_TAC THEN ASM_SIMP_TAC[AZIM_LINEAR_IMAGE] THEN + SUBST1_TAC(SET_RULE `{f v,f w,f y} = IMAGE (f:real^3->real^3) {v,w,y}`) THEN + ASM_MESON_TAC[COLLINEAR_LINEAR_IMAGE_EQ; PRESERVES_NORM_INJECTIVE]);; + +add_linear_invariants [WEDGE_LINEAR_IMAGE];; + +let WEDGE_SPECIAL_SCALE = prove + (`!a v w1 w2. + &0 < a /\ + ~collinear{vec 0,a % v,w1} /\ + ~collinear{vec 0,a % v,w2} + ==> wedge (vec 0) (a % v) w1 w2 = wedge (vec 0) v w1 w2`, + SIMP_TAC[wedge; AZIM_SPECIAL_SCALE; COLLINEAR_SPECIAL_SCALE; + REAL_LT_IMP_NZ]);; + +let WEDGE_DEGENERATE = prove + (`(!z w w1 w2. z = w ==> wedge z w w1 w2 = {}) /\ + (!z w w1 w2. collinear{z,w,w1} ==> wedge z w w1 w2 = {}) /\ + (!z w w1 w2. collinear{z,w,w2} ==> wedge z w w1 w2 = {})`, + REWRITE_TAC[wedge] THEN SIMP_TAC[AZIM_DEGENERATE] THEN + REWRITE_TAC[REAL_LT_REFL; REAL_LT_ANTISYM; EMPTY_GSPEC]);; + +(* ------------------------------------------------------------------------- *) +(* Basic relation between wedge and aff, so Tarski-type characterization. *) +(* ------------------------------------------------------------------------- *) + +let AFF_GT_LEMMA = prove + (`!v1 v2:real^N. + &0 < t1 /\ ~(v2 = vec 0) + ==> aff_gt {vec 0} {t1 % basis 1, v2} = + {a % basis 1 + b % v2 | &0 < a /\ &0 < b}`, + REWRITE_TAC[AFFSIGN_ALT; aff_gt_def; sgn_gt; IN_ELIM_THM] THEN + REWRITE_TAC[SET_RULE `{a} UNION {b,c} = {a,b,c}`] THEN + REWRITE_TAC[SET_RULE `x IN {a} <=> a = x`] THEN + ASM_SIMP_TAC[FINITE_INSERT; FINITE_UNION; AFFINE_HULL_FINITE_STEP_GEN; + RIGHT_EXISTS_AND_THM; REAL_LT_ADD; REAL_HALF; FINITE_EMPTY] THEN + ASM_REWRITE_TAC[IN_INSERT; NOT_IN_EMPTY] THEN + REWRITE_TAC[IN_INSERT; VECTOR_ARITH `vec 0 = a % x <=> a % x = vec 0`] THEN + ASM_SIMP_TAC[VECTOR_MUL_EQ_0; REAL_LT_IMP_NZ; BASIS_NONZERO; + DIMINDEX_GE_1; LE_REFL] THEN + REPEAT STRIP_TAC THEN REWRITE_TAC[VECTOR_MUL_RZERO; VECTOR_SUB_RZERO] THEN + REWRITE_TAC[EXTENSION; IN_ELIM_THM] THEN X_GEN_TAC `y:real^N` THEN + REWRITE_TAC[RIGHT_AND_EXISTS_THM] THEN + REWRITE_TAC[REAL_ARITH `&1 - v - v' - v'' = &0 <=> v = &1 - v' - v''`] THEN + ONCE_REWRITE_TAC[MESON[] `(?a b c. P a b c) <=> (?b c a. P a b c)`] THEN + REWRITE_TAC[RIGHT_EXISTS_AND_THM; UNWIND_THM2] THEN + REWRITE_TAC[RIGHT_AND_EXISTS_THM] THEN ONCE_REWRITE_TAC[SWAP_EXISTS_THM] THEN + AP_TERM_TAC THEN REWRITE_TAC[FUN_EQ_THM] THEN X_GEN_TAC `b:real` THEN + REWRITE_TAC[VECTOR_ARITH `y - a - b:real^N = vec 0 <=> y = a + b`] THEN + EQ_TAC THEN DISCH_THEN(X_CHOOSE_THEN `a:real` STRIP_ASSUME_TAC) THENL + [EXISTS_TAC `a * t1:real`; EXISTS_TAC `a / t1:real`] THEN + ASM_SIMP_TAC[REAL_LT_DIV; REAL_LT_MUL; VECTOR_MUL_ASSOC] THEN + ASM_SIMP_TAC[REAL_DIV_RMUL; REAL_LT_IMP_NZ]);; + +let WEDGE_LUNE_GT = prove + (`!v0 v1 w1 w2. + ~collinear {v0,v1,w1} /\ ~collinear {v0,v1,w2} /\ + &0 < azim v0 v1 w1 w2 /\ azim v0 v1 w1 w2 < pi + ==> wedge v0 v1 w1 w2 = aff_gt {v0,v1} {w1,w2}`, + let lemma = prove + (`!a x:real^3. (?a. x = a % basis 3) <=> dropout 3 x:real^2 = vec 0`, + SIMP_TAC[CART_EQ; FORALL_2; FORALL_3; DIMINDEX_2; DIMINDEX_3; + dropout; LAMBDA_BETA; BASIS_COMPONENT; ARITH; REAL_MUL_RID; + VECTOR_MUL_COMPONENT; VEC_COMPONENT; REAL_MUL_RZERO; UNWIND_THM1] THEN + MESON_TAC[]) in + REWRITE_TAC[wedge] THEN GEOM_ORIGIN_TAC `v0:real^3` THEN + GEOM_BASIS_MULTIPLE_TAC 3 `v1:real^3` THEN + X_GEN_TAC `w:real` THEN GEN_REWRITE_TAC LAND_CONV [REAL_LE_LT] THEN + ASM_CASES_TAC `w = &0` THEN ASM_REWRITE_TAC[] THENL + [ASM_REWRITE_TAC[VECTOR_MUL_LZERO; INSERT_AC; COLLINEAR_2]; ALL_TAC] THEN + ASM_SIMP_TAC[AZIM_SPECIAL_SCALE; COLLINEAR_SPECIAL_SCALE] THEN + POP_ASSUM_LIST(K ALL_TAC) THEN DISCH_TAC THEN + MAP_EVERY X_GEN_TAC [`w1:real^3`; `w2:real^3`] THEN + REPLICATE_TAC 2 (DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + ONCE_REWRITE_TAC[TAUT `~a /\ b /\ c <=> ~(~a ==> ~(b /\ c))`] THEN + ASM_SIMP_TAC[AZIM_ARG] THEN REWRITE_TAC[COLLINEAR_BASIS_3] THEN + RULE_ASSUM_TAC(REWRITE_RULE[COLLINEAR_BASIS_3]) THEN STRIP_TAC THEN + REWRITE_TAC[NOT_IMP; GSYM CONJ_ASSOC] THEN + W(MP_TAC o PART_MATCH (lhs o rand) AFF_GT_SPECIAL_SCALE o rand o snd) THEN + SUBGOAL_THEN + `~(w1:real^3 = vec 0) /\ ~(w2:real^3 = vec 0) /\ + ~(w1 = basis 3) /\ ~(w2 = basis 3)` + STRIP_ASSUME_TAC THENL + [REPEAT STRIP_TAC THEN + REPEAT(FIRST_X_ASSUM(MP_TAC o check (is_neg o concl))) THEN + ASM_REWRITE_TAC[DROPOUT_BASIS_3; DROPOUT_0; DROPOUT_MUL; VECTOR_MUL_RZERO]; + ALL_TAC] THEN + ANTS_TAC THENL + [ASM_REWRITE_TAC[FINITE_INSERT; FINITE_EMPTY; IN_INSERT; NOT_IN_EMPTY] THEN + DISCH_THEN(DISJ_CASES_THEN (SUBST_ALL_TAC o SYM)) THEN + REPEAT(FIRST_X_ASSUM(MP_TAC o check (is_neg o concl))) THEN + ASM_REWRITE_TAC[DROPOUT_BASIS_3; DROPOUT_0; DROPOUT_MUL; VECTOR_MUL_RZERO]; + DISCH_THEN SUBST1_TAC] THEN + REWRITE_TAC[AFFSIGN_ALT; aff_gt_def; sgn_gt; IN_ELIM_THM] THEN + REWRITE_TAC[SET_RULE `{a,b} UNION {c,d} = {a,b,d,c}`] THEN + REWRITE_TAC[SET_RULE `x IN {a} <=> a = x`] THEN + ASM_SIMP_TAC[FINITE_INSERT; FINITE_UNION; AFFINE_HULL_FINITE_STEP_GEN; + RIGHT_EXISTS_AND_THM; REAL_LT_ADD; REAL_HALF; FINITE_EMPTY] THEN + ASM_REWRITE_TAC[IN_INSERT; NOT_IN_EMPTY] THEN + REWRITE_TAC[VECTOR_MUL_RZERO; VECTOR_SUB_RZERO] THEN + MATCH_MP_TAC EQ_TRANS THEN + EXISTS_TAC `{y | (dropout 3:real^3->real^2) y IN + aff_gt {vec 0} + {dropout 3 (w1:real^3),dropout 3 (w2:real^3)}}` THEN + CONJ_TAC THENL + [ALL_TAC; + REWRITE_TAC[AFFSIGN_ALT; aff_gt_def; sgn_gt; IN_ELIM_THM] THEN + REWRITE_TAC[SET_RULE `{a} UNION {b,c} = {a,b,c}`] THEN + REWRITE_TAC[SET_RULE `x IN {a} <=> a = x`] THEN + ASM_SIMP_TAC[FINITE_INSERT; FINITE_UNION; AFFINE_HULL_FINITE_STEP_GEN; + RIGHT_EXISTS_AND_THM; REAL_LT_ADD; REAL_HALF; FINITE_EMPTY] THEN + ASM_REWRITE_TAC[IN_INSERT; NOT_IN_EMPTY] THEN + REWRITE_TAC[VECTOR_MUL_RZERO; VECTOR_SUB_RZERO] THEN + REWRITE_TAC[REAL_EQ_SUB_RADD; RIGHT_AND_EXISTS_THM] THEN + REWRITE_TAC[REAL_ARITH `&1 = x + v <=> v = &1 - x`] THEN + ONCE_REWRITE_TAC[TAUT `a /\ b /\ c /\ d <=> c /\ d /\ a /\ b`] THEN + ONCE_REWRITE_TAC[MESON[] + `(?a b c d. P a b c d) <=> (?b c d a. P a b c d)`] THEN + REWRITE_TAC[UNWIND_THM2] THEN + ONCE_REWRITE_TAC[MESON[] + `(?a b c. P a b c) <=> (?c b a. P a b c)`] THEN + REWRITE_TAC[UNWIND_THM2] THEN REWRITE_TAC[VECTOR_ARITH + `y - a - b - c:real^N = vec 0 <=> y - b - c = a`] THEN + REWRITE_TAC[LEFT_EXISTS_AND_THM; lemma] THEN + REWRITE_TAC[DROPOUT_SUB; DROPOUT_MUL] THEN + REWRITE_TAC[VECTOR_ARITH `y - a - b:real^2 = vec 0 <=> y = a + b`] THEN + REWRITE_TAC[EXTENSION; IN_ELIM_THM] THEN MESON_TAC[VECTOR_ADD_SYM]] THEN + MATCH_MP_TAC(SET_RULE + `{x | P x} = s ==> {y | P(dropout 3 y)} = {y | dropout 3 y IN s}`) THEN + MP_TAC(CONJ (ASSUME `~((dropout 3:real^3->real^2) w1 = vec 0)`) + (ASSUME `~((dropout 3:real^3->real^2) w2 = vec 0)`)) THEN + UNDISCH_TAC `Arg(dropout 3 (w2:real^3) / dropout 3 (w1:real^3)) < pi` THEN + UNDISCH_TAC `&0 < Arg(dropout 3 (w2:real^3) / dropout 3 (w1:real^3))` THEN + SPEC_TAC(`(dropout 3:real^3->real^2) w2`,`v2:complex`) THEN + SPEC_TAC(`(dropout 3:real^3->real^2) w1`,`v1:complex`) THEN + POP_ASSUM_LIST(K ALL_TAC) THEN GEOM_BASIS_MULTIPLE_TAC 1 `v1:complex` THEN + X_GEN_TAC `v1:real` THEN GEN_REWRITE_TAC LAND_CONV [REAL_LE_LT] THEN + ASM_CASES_TAC `v1 = &0` THEN ASM_REWRITE_TAC[VECTOR_MUL_LZERO] THEN + SIMP_TAC[AFF_GT_LEMMA] THEN + REWRITE_TAC[COMPLEX_CMUL; COMPLEX_BASIS; COMPLEX_VEC_0] THEN + ASM_SIMP_TAC[ARG_DIV_CX; COMPLEX_MUL_RID; CX_INJ] THEN DISCH_TAC THEN + POP_ASSUM_LIST(K ALL_TAC) THEN X_GEN_TAC `z:complex` THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN + REWRITE_TAC[SUBSET; FORALL_IN_GSPEC; IN_ELIM_THM] THEN CONJ_TAC THENL + [X_GEN_TAC `w:complex` THEN STRIP_TAC THEN + MP_TAC(SPECL [`\t. Arg(Cx t + Cx(&1 - t) * z)`; + `&0`; `&1`; `Arg w`] REAL_IVT_DECREASING) THEN + REWRITE_TAC[REAL_POS; REAL_SUB_REFL; COMPLEX_MUL_LZERO] THEN + REWRITE_TAC[REAL_SUB_RZERO; COMPLEX_ADD_LID; COMPLEX_MUL_LID] THEN + ASM_SIMP_TAC[COMPLEX_ADD_RID; ARG_NUM; REAL_LT_IMP_LE] THEN ANTS_TAC THENL + [REWRITE_TAC[REAL_CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN] THEN + REWRITE_TAC[REAL_CONTINUOUS_CONTINUOUS; IN_REAL_INTERVAL] THEN + X_GEN_TAC `t:real` THEN STRIP_TAC THEN + ONCE_REWRITE_TAC[GSYM o_DEF] THEN REWRITE_TAC[o_ASSOC] THEN + MATCH_MP_TAC CONTINUOUS_WITHINREAL_COMPOSE THEN + REWRITE_TAC[] THEN CONJ_TAC THENL + [MATCH_MP_TAC CONTINUOUS_ADD THEN CONJ_TAC THENL + [GEN_REWRITE_TAC LAND_CONV [SYM(CONJUNCT2(SPEC_ALL I_O_ID))] THEN + REWRITE_TAC[GSYM REAL_CONTINUOUS_CONTINUOUS] THEN + REWRITE_TAC[I_DEF; REAL_CONTINUOUS_WITHIN_ID]; + MATCH_MP_TAC CONTINUOUS_COMPLEX_MUL THEN + REWRITE_TAC[CONTINUOUS_CONST] THEN ONCE_REWRITE_TAC[GSYM o_DEF] THEN + REWRITE_TAC[GSYM REAL_CONTINUOUS_CONTINUOUS] THEN + SIMP_TAC[REAL_CONTINUOUS_SUB; REAL_CONTINUOUS_CONST; + REAL_CONTINUOUS_WITHIN_ID]]; + MATCH_MP_TAC CONTINUOUS_WITHIN_SUBSET THEN + EXISTS_TAC `{z | &0 <= Im z}` THEN CONJ_TAC THENL + [MATCH_MP_TAC CONTINUOUS_WITHIN_UPPERHALF_ARG THEN + ASM_CASES_TAC `t = &1` THENL + [ASM_REWRITE_TAC[REAL_SUB_REFL] THEN CONV_TAC COMPLEX_RING; + ALL_TAC] THEN + DISCH_THEN(MP_TAC o AP_TERM `Im`) THEN + REWRITE_TAC[IM_ADD; IM_CX; IM_MUL_CX; REAL_ADD_LID; REAL_ENTIRE] THEN + ASM_REWRITE_TAC[REAL_SUB_0] THEN + ASM_MESON_TAC[ARG_LT_PI; REAL_LT_IMP_NZ; REAL_LT_TRANS]; + REWRITE_TAC[FORALL_IN_IMAGE; SUBSET; IN_REAL_INTERVAL] THEN + REWRITE_TAC[IN_ELIM_THM; IM_ADD; IM_CX; IM_MUL_CX] THEN + REPEAT STRIP_TAC THEN REWRITE_TAC[REAL_ADD_LID] THEN + MATCH_MP_TAC REAL_LE_MUL THEN REWRITE_TAC[GSYM ARG_LE_PI] THEN + ASM_REAL_ARITH_TAC]]; + REWRITE_TAC[IN_REAL_INTERVAL] THEN + DISCH_THEN(X_CHOOSE_THEN `t:real` MP_TAC) THEN + ASM_CASES_TAC `t = &0` THENL + [ASM_REWRITE_TAC[REAL_SUB_RZERO; COMPLEX_ADD_LID; COMPLEX_MUL_LID] THEN + ASM_MESON_TAC[REAL_LT_REFL]; + ALL_TAC] THEN + ASM_CASES_TAC `t = &1` THENL + [ASM_REWRITE_TAC[REAL_SUB_REFL; COMPLEX_MUL_LZERO] THEN + REWRITE_TAC[COMPLEX_ADD_RID; ARG_NUM] THEN ASM_MESON_TAC[REAL_LT_REFL]; + ALL_TAC] THEN + GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [REAL_LE_LT] THEN + ASM_REWRITE_TAC[] THEN ABBREV_TAC `u = Cx t + Cx(&1 - t) * z` THEN + ASM_CASES_TAC `u = Cx(&0)` THENL + [ASM_MESON_TAC[ARG_0; REAL_LT_REFL]; ALL_TAC] THEN + STRIP_TAC THEN + EXISTS_TAC `norm(w:complex) / norm(u:complex) * t` THEN + EXISTS_TAC `norm(w:complex) / norm(u:complex) * (&1 - t)` THEN + ASM_SIMP_TAC[REAL_LT_MUL; REAL_LT_DIV; COMPLEX_NORM_NZ; REAL_SUB_LT] THEN + SIMP_TAC[CX_MUL; GSYM COMPLEX_MUL_ASSOC; GSYM COMPLEX_ADD_LDISTRIB] THEN + ASM_REWRITE_TAC[CX_DIV] THEN + ASM_SIMP_TAC[CX_INJ; COMPLEX_NORM_ZERO; COMPLEX_FIELD + `~(nu = Cx(&0)) ==> (w = nw / nu * u <=> nu * w = nw * u)`] THEN + GEN_REWRITE_TAC (BINOP_CONV o RAND_CONV) [ARG] THEN + ASM_REWRITE_TAC[COMPLEX_MUL_AC]]; + MAP_EVERY X_GEN_TAC [`a:real`; `b:real`] THEN STRIP_TAC THEN + SUBGOAL_THEN `Cx a + Cx b * z = complex(a + b * Re z,b * Im z)` + SUBST1_TAC THENL + [REWRITE_TAC[COMPLEX_EQ; RE; IM; RE_ADD; IM_ADD; RE_CX; IM_CX; + RE_MUL_CX; IM_MUL_CX] THEN + REAL_ARITH_TAC; + ALL_TAC] THEN + REWRITE_TAC[COMPLEX_EQ; IM; IM_CX] THEN + SUBGOAL_THEN `&0 < Im z` ASSUME_TAC THENL + [ASM_REWRITE_TAC[GSYM ARG_LT_PI]; ALL_TAC] THEN + ASM_SIMP_TAC[ARG_ATAN_UPPERHALF; REAL_LT_MUL; REAL_LT_IMP_NZ; IM] THEN + REWRITE_TAC[RE; REAL_SUB_LT; ATN_BOUNDS] THEN + REWRITE_TAC[REAL_ARITH `pi / &2 - x < pi / &2 - y <=> y < x`] THEN + REWRITE_TAC[ATN_MONO_LT_EQ] THEN + ASM_SIMP_TAC[REAL_LT_RDIV_EQ; REAL_LT_MUL] THEN + ASM_SIMP_TAC[REAL_FIELD `&0 < z ==> w / z * b * z = b * w`] THEN + ASM_REAL_ARITH_TAC]);; + +let WEDGE_LUNE_GE = prove + (`!v0 v1 w1 w2. + ~collinear {v0,v1,w1} /\ ~collinear {v0,v1,w2} /\ + &0 < azim v0 v1 w1 w2 /\ azim v0 v1 w1 w2 < pi + ==> {x | &0 <= azim v0 v1 w1 x /\ + azim v0 v1 w1 x <= azim v0 v1 w1 w2} = + aff_ge {v0,v1} {w1,w2}`, + REPEAT GEN_TAC THEN + MAP_EVERY (fun t -> ASM_CASES_TAC t THENL + [ASM_REWRITE_TAC[COLLINEAR_2; INSERT_AC] THEN NO_TAC; ALL_TAC]) + [`v1:real^3 = v0`; `w1:real^3 = v0`; `w2:real^3 = v0`; + `w1:real^3 = v1`; `w2:real^3 = v1`] THEN + ASM_CASES_TAC `w1:real^3 = w2` THEN + ASM_REWRITE_TAC[AZIM_REFL; REAL_LT_REFL] THEN + STRIP_TAC THEN ASM_SIMP_TAC[REAL_ARITH + `&0 < a + ==> (&0 <= x /\ x <= a <=> x = &0 \/ x = a \/ &0 < x /\ x < a)`] THEN + MATCH_MP_TAC(SET_RULE + `!c. c SUBSET {x | p x} /\ c SUBSET s /\ + ({x | ~(~c x ==> ~p x)} UNION {x | ~(~c x ==> ~q x)} UNION + ({x | ~c x /\ r x} DIFF c) = s DIFF c) + ==> {x | p x \/ q x \/ r x} = s`) THEN + EXISTS_TAC `{x:real^3 | collinear {v0,v1,x}}` THEN + ASM_SIMP_TAC[IN_ELIM_THM; AZIM_EQ_ALT; AZIM_EQ_0_ALT; + GSYM wedge; WEDGE_LUNE_GT] THEN + REPEAT CONJ_TAC THENL + [ASM_SIMP_TAC[SUBSET; IN_ELIM_THM; AZIM_DEGENERATE]; + ASM_SIMP_TAC[COLLINEAR_3_AFFINE_HULL] THEN + REWRITE_TAC[SET_RULE `{x | x IN s} = s`] THEN + MATCH_MP_TAC AFFINE_HULL_SUBSET_AFF_GE THEN + ASM_REWRITE_TAC[DISJOINT_INSERT; IN_INSERT; NOT_IN_EMPTY; DISJOINT_EMPTY]; + ALL_TAC] THEN + REWRITE_TAC[NOT_IMP] THEN MATCH_MP_TAC(SET_RULE + `(!x. ~c x ==> (p x \/ q x \/ x IN t <=> x IN e)) + ==> {x | ~c x /\ p x} UNION {x | ~c x /\ q x} UNION (t DIFF {x | c x}) = + e DIFF {x | c x}`) THEN + X_GEN_TAC `y:real^3` THEN DISCH_TAC THEN + W(MP_TAC o PART_MATCH (lhs o rand) AFF_GE_AFF_GT_DECOMP o rand o + rand o snd) THEN + ANTS_TAC THENL + [ASM_REWRITE_TAC[FINITE_INSERT; FINITE_EMPTY] THEN + ASM_REWRITE_TAC[DISJOINT_INSERT; IN_INSERT; NOT_IN_EMPTY; DISJOINT_EMPTY]; + DISCH_THEN SUBST1_TAC] THEN + REWRITE_TAC[IN_UNION] THEN + REWRITE_TAC[SIMPLE_IMAGE; IMAGE_CLAUSES; UNIONS_2] THEN + ASM_SIMP_TAC[SET_RULE `~(w1 = w2) ==> {w1,w2} DELETE w1 = {w2}`; + SET_RULE `~(w1 = w2) ==> {w1,w2} DELETE w2 = {w1}`] THEN + REWRITE_TAC[IN_UNION; DISJ_ACI] THEN + W(MP_TAC o PART_MATCH (lhs o rand) AFF_GE_AFF_GT_DECOMP o rand o lhand o + rand o snd) THEN + ANTS_TAC THENL + [ASM_REWRITE_TAC[FINITE_INSERT; FINITE_EMPTY] THEN + ASM_REWRITE_TAC[DISJOINT_INSERT; IN_INSERT; NOT_IN_EMPTY; DISJOINT_EMPTY]; + DISCH_THEN SUBST1_TAC] THEN + W(MP_TAC o PART_MATCH (lhs o rand) AFF_GE_AFF_GT_DECOMP o rand o lhand o + rand o rand o snd) THEN + ANTS_TAC THENL + [ASM_REWRITE_TAC[FINITE_INSERT; FINITE_EMPTY] THEN + ASM_REWRITE_TAC[DISJOINT_INSERT; IN_INSERT; NOT_IN_EMPTY; DISJOINT_EMPTY]; + DISCH_THEN SUBST1_TAC] THEN + REWRITE_TAC[IN_UNION] THEN + REWRITE_TAC[SIMPLE_IMAGE; IMAGE_CLAUSES; UNIONS_1] THEN + REWRITE_TAC[SET_RULE `{a} DELETE a = {}`; AFF_GE_EQ_AFFINE_HULL] THEN + ASM_MESON_TAC[COLLINEAR_3_AFFINE_HULL]);; + +let WEDGE_LUNE = prove + (`!v0 v1 w1 w2. + ~coplanar{v0,v1,w1,w2} /\ azim v0 v1 w1 w2 < pi + ==> wedge v0 v1 w1 w2 = aff_gt {v0,v1} {w1,w2}`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC WEDGE_LUNE_GT THEN + ASM_REWRITE_TAC[] THEN REPEAT CONJ_TAC THENL + [MP_TAC(ISPECL [`v0:real^3`; `v1:real^3`; `w1:real^3`; `w2:real^3`] + NOT_COPLANAR_NOT_COLLINEAR) THEN + ASM_REWRITE_TAC[]; + MP_TAC(ISPECL [`v0:real^3`; `v1:real^3`; `w2:real^3`; `w1:real^3`] + NOT_COPLANAR_NOT_COLLINEAR) THEN + ONCE_REWRITE_TAC[SET_RULE `{a,b,c,d} = {a,b,d,c}`] THEN + ASM_REWRITE_TAC[]; + REWRITE_TAC[azim; REAL_LT_LE] THEN + ASM_MESON_TAC[AZIM_EQ_0_PI_IMP_COPLANAR]]);; + +let WEDGE = prove + (`wedge v1 v2 w1 w2 = + if collinear{v1,v2,w1} \/ collinear{v1,v2,w2} then {} + else + let z = v2 - v1 in + let u1 = w1 - v1 in + let u2 = w2 - v1 in + let n = z cross u1 in + let d = n dot u2 in + if w2 IN (aff_ge {v1,v2} {w1}) then {} + else if w2 IN (aff_lt {v1,v2} {w1}) then aff_gt {v1,v2,w1} {v1 + n} + else if d > &0 then aff_gt {v1,v2} {w1,w2} + else (:real^3) DIFF aff_ge {v1,v2} {w1,w2}`, + REPEAT GEN_TAC THEN COND_CASES_TAC THENL + [FIRST_X_ASSUM DISJ_CASES_TAC THEN + ASM_SIMP_TAC[WEDGE_DEGENERATE]; + POP_ASSUM MP_TAC THEN REWRITE_TAC[DE_MORGAN_THM] THEN STRIP_TAC] THEN + ASM_SIMP_TAC[GSYM AZIM_EQ_0_GE_ALT] THEN + ASM_CASES_TAC `azim v1 v2 w1 w2 = &0` THENL + [ASM_REWRITE_TAC[wedge] THEN + ASM_REWRITE_TAC[REAL_LT_ANTISYM; LET_DEF; LET_END_DEF; EMPTY_GSPEC]; + ALL_TAC] THEN + ASM_SIMP_TAC[GSYM AZIM_EQ_PI_ALT] THEN + ASM_CASES_TAC `azim v1 v2 w1 w2 = pi` THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[LET_DEF; LET_END_DEF] THEN + POP_ASSUM_LIST(MP_TAC o end_itlist CONJ) THEN + GEOM_ORIGIN_TAC `v1:real^3` THEN + REWRITE_TAC[VECTOR_ADD_RID; TRANSLATION_INVARIANTS `v1:real^3`] THEN + REWRITE_TAC[VECTOR_SUB_RZERO; VECTOR_ADD_LID] THEN + GEOM_BASIS_MULTIPLE_TAC 3 `v2:real^3` THEN + X_GEN_TAC `v2:real` THEN + GEN_REWRITE_TAC LAND_CONV [REAL_ARITH `&0 <= x <=> x = &0 \/ &0 < x`] THEN + (STRIP_TAC THENL + [ASM_REWRITE_TAC[VECTOR_MUL_LZERO; INSERT_AC; COLLINEAR_2]; ALL_TAC]) THEN + ASM_SIMP_TAC[AZIM_SPECIAL_SCALE; COLLINEAR_SPECIAL_SCALE; REAL_LT_IMP_NZ; + WEDGE_SPECIAL_SCALE] THEN + (REPEAT GEN_TAC THEN + MAP_EVERY (fun t -> ASM_CASES_TAC t THENL + [ASM_REWRITE_TAC[COLLINEAR_2; INSERT_AC] THEN NO_TAC; ALL_TAC]) + [`w1:real^3 = vec 0`; `w2:real^3 = vec 0`; `w1:real^3 = basis 3`; + `w2:real^3 = basis 3`] THEN + ASM_CASES_TAC `w1:real^3 = v2 % basis 3` THENL + [ASM_REWRITE_TAC[COLLINEAR_LEMMA] THEN MESON_TAC[]; ALL_TAC] THEN + ASM_CASES_TAC `w2:real^3 = v2 % basis 3` THENL + [ASM_REWRITE_TAC[COLLINEAR_LEMMA] THEN MESON_TAC[]; ALL_TAC]) + THENL + [REPEAT STRIP_TAC THEN REWRITE_TAC[EXTENSION] THEN X_GEN_TAC `y:real^3` THEN + MATCH_MP_TAC EQ_TRANS THEN EXISTS_TAC + `(dropout 3 (y:real^3)) IN + aff_gt {vec 0:real^2,dropout 3 (w1:real^3)} + {rotate2d (pi / &2) (dropout 3 (w1:real^3))}` THEN + CONJ_TAC THENL + [FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE LAND_CONV [AZIM_ARG]) THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE (RAND_CONV o LAND_CONV) + [AZIM_ARG]) THEN + REPEAT(FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE RAND_CONV + [COLLINEAR_BASIS_3])) THEN + POP_ASSUM_LIST(K ALL_TAC) THEN + REWRITE_TAC[wedge; IN_ELIM_THM; AZIM_ARG; COLLINEAR_BASIS_3] THEN + SPEC_TAC(`(dropout 3:real^3->real^2) y`,`x:real^2`) THEN + SPEC_TAC(`(dropout 3:real^3->real^2) w2`,`v2:real^2`) THEN + SPEC_TAC(`(dropout 3:real^3->real^2) w1`,`v1:real^2`) THEN + GEOM_BASIS_MULTIPLE_TAC 1 `v1:complex` THEN + X_GEN_TAC `v:real` THEN GEN_REWRITE_TAC LAND_CONV [REAL_LE_LT] THEN + ASM_CASES_TAC `v = &0` THEN ASM_REWRITE_TAC[VECTOR_MUL_LZERO] THEN + REWRITE_TAC[COMPLEX_CMUL; COMPLEX_BASIS; COMPLEX_VEC_0] THEN + SIMP_TAC[ARG_DIV_CX; COMPLEX_MUL_RID] THEN + REWRITE_TAC[real; RE_DIV_CX; IM_DIV_CX; CX_INJ] THEN + ASM_SIMP_TAC[REAL_LT_LDIV_EQ; REAL_EQ_LDIV_EQ; REAL_MUL_LZERO] THEN + REPEAT STRIP_TAC THEN REWRITE_TAC[ARG_LT_PI; ROTATE2D_PI2] THEN + W(MP_TAC o PART_MATCH (lhs o rand) AFF_GT_2_1 o rand o rand o snd) THEN + ASM_REWRITE_TAC[DISJOINT_INSERT; DISJOINT_EMPTY; IN_SING] THEN + ANTS_TAC THENL + [CONV_TAC(ONCE_DEPTH_CONV SYM_CONV) THEN + ASM_REWRITE_TAC[COMPLEX_ENTIRE; II_NZ; CX_INJ] THEN + DISCH_THEN(MP_TAC o AP_TERM `Re`) THEN + REWRITE_TAC[RE_MUL_II; RE_CX; IM_CX] THEN ASM_REAL_ARITH_TAC; + DISCH_THEN SUBST1_TAC] THEN + REWRITE_TAC[COMPLEX_CMUL; IN_ELIM_THM; COMPLEX_MUL_RZERO] THEN + ONCE_REWRITE_TAC[MESON[] `(?a b c. P a b c) <=> (?b c a. P a b c)`] THEN + REWRITE_TAC[REAL_ARITH `t1 + t2 = &1 <=> t1 = &1 - t2`] THEN + REWRITE_TAC[RIGHT_EXISTS_AND_THM; UNWIND_THM2; COMPLEX_ADD_LID] THEN + EQ_TAC THENL + [DISCH_TAC THEN + MAP_EVERY EXISTS_TAC [`Re x / v`; `Im x / v`] THEN + ASM_SIMP_TAC[REAL_LT_DIV; COMPLEX_EQ; IM_ADD; RE_ADD] THEN + REWRITE_TAC[RE_MUL_CX; IM_MUL_CX; RE_CX; IM_CX; RE_II; IM_II] THEN + UNDISCH_TAC `~(v = &0)` THEN CONV_TAC REAL_FIELD; + REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`s:real`; `t:real`] THEN + STRIP_TAC THEN ASM_REWRITE_TAC[COMPLEX_EQ; IM_ADD; RE_ADD] THEN + REWRITE_TAC[RE_MUL_CX; IM_MUL_CX; RE_CX; IM_CX; RE_II; IM_II] THEN + ASM_SIMP_TAC[REAL_MUL_RZERO; REAL_MUL_LID; REAL_LT_MUL; REAL_ADD_LID; + REAL_MUL_LZERO] THEN + MAP_EVERY UNDISCH_TAC [`&0 < v`; `&0 < t`] THEN + CONV_TAC REAL_FIELD]; + ALL_TAC] THEN + W(MP_TAC o PART_MATCH (lhs o rand) AFF_GT_3_1 o rand o rand o snd) THEN + ANTS_TAC THENL + [REWRITE_TAC[SET_RULE + `DISJOINT {a,b,c} {x} <=> ~(x = a) /\ ~(x = b) /\ ~(x = c)`] THEN + ASM_SIMP_TAC[CROSS_EQ_0; CROSS_EQ_SELF; VECTOR_MUL_EQ_0; REAL_LT_IMP_NZ; + REAL_LT_IMP_NZ; BASIS_NONZERO; DIMINDEX_3; + ARITH; COLLINEAR_SPECIAL_SCALE]; + DISCH_THEN SUBST1_TAC] THEN + W(MP_TAC o PART_MATCH (lhs o rand) AFF_GT_2_1 o rand o lhand o snd) THEN + REWRITE_TAC[ROTATE2D_PI2] THEN ANTS_TAC THENL + [REWRITE_TAC[SET_RULE `DISJOINT {a,b} {x} <=> ~(x = a) /\ ~(x = b)`] THEN + REWRITE_TAC[COMPLEX_ENTIRE; COMPLEX_RING `ii * x = x <=> x = Cx(&0)`; + COMPLEX_VEC_0; II_NZ] THEN + ASM_REWRITE_TAC[GSYM COMPLEX_VEC_0; GSYM COLLINEAR_BASIS_3]; + DISCH_THEN SUBST1_TAC] THEN + REWRITE_TAC[IN_ELIM_THM; VECTOR_MUL_RZERO; VECTOR_ADD_LID] THEN + ONCE_REWRITE_TAC[MESON[] + `(?a b c d. P a b c d) <=> (?d c b a. P a b c d)`] THEN + ONCE_REWRITE_TAC[REAL_ARITH `s + t = &1 <=> s = &1 - t`] THEN + REWRITE_TAC[UNWIND_THM2; RIGHT_EXISTS_AND_THM] THEN + ONCE_REWRITE_TAC[MESON[] `(?a b c. P a b c) <=> (?c b a. P a b c)`] THEN + REWRITE_TAC[UNWIND_THM2; RIGHT_EXISTS_AND_THM] THEN + REWRITE_TAC[RIGHT_AND_EXISTS_THM] THEN + SIMP_TAC[CART_EQ; FORALL_2; FORALL_3; DIMINDEX_2; DIMINDEX_3; + dropout; LAMBDA_BETA; BASIS_COMPONENT; ARITH; REAL_MUL_RID; + VECTOR_MUL_COMPONENT; VEC_COMPONENT; REAL_MUL_RZERO; UNWIND_THM1; + VECTOR_ADD_COMPONENT; cross; VECTOR_3; + REWRITE_RULE[RE_DEF; IM_DEF] RE_MUL_II; + REWRITE_RULE[RE_DEF; IM_DEF] IM_MUL_II; + REAL_ADD_LID; REAL_MUL_LZERO; REAL_SUB_REFL; REAL_ADD_RID; + REAL_SUB_LZERO; REAL_SUB_RZERO] THEN + ONCE_REWRITE_TAC[SWAP_EXISTS_THM] THEN + AP_TERM_TAC THEN REWRITE_TAC[FUN_EQ_THM] THEN X_GEN_TAC `s:real` THEN + REWRITE_TAC[RIGHT_EXISTS_AND_THM] THEN + ASM_SIMP_TAC[EXISTS_REFL; REAL_FIELD + `&0 < v ==> (x = a * v + b <=> a = (x - b) / v)`] THEN + REWRITE_TAC[REAL_MUL_RNEG; REAL_MUL_ASSOC] THEN EQ_TAC THEN + DISCH_THEN(X_CHOOSE_THEN `t:real` STRIP_ASSUME_TAC) THENL + [EXISTS_TAC `t / v2:real`; EXISTS_TAC `t * v2:real`] THEN + ASM_SIMP_TAC[REAL_DIV_RMUL; REAL_LT_DIV; REAL_LT_IMP_NZ; REAL_LT_MUL]; + ALL_TAC] THEN + REWRITE_TAC[CROSS_LMUL] THEN + SIMP_TAC[cross; BASIS_COMPONENT; DIMINDEX_3; ARITH; DOT_3; VECTOR_3; + VECTOR_MUL_COMPONENT; REAL_MUL_LZERO; REAL_SUB_RZERO; REAL_NEG_0; + REAL_MUL_RZERO; REAL_SUB_LZERO; REAL_MUL_LID; REAL_ADD_RID] THEN + REWRITE_TAC[REAL_ARITH + `(v * --x2) * y1 + (v * x1) * y2 > &0 <=> &0 < v * (x1 * y2 - x2 * y1)`] THEN + ASM_SIMP_TAC[REAL_LT_MUL_EQ; REAL_SUB_LT] THEN + REWRITE_TAC[AZIM_ARG; COLLINEAR_BASIS_3] THEN STRIP_TAC THEN + SUBGOAL_THEN + `w1$2 * w2$1 < w1$1 * w2$2 <=> + Arg(dropout 3 (w2:real^3) / dropout 3 (w1:real^3)) < pi` + SUBST1_TAC THENL + [MATCH_MP_TAC EQ_TRANS THEN + EXISTS_TAC `&0 < Im(dropout 3 (w2:real^3) / dropout 3 (w1:real^3))` THEN + CONJ_TAC THENL + [REWRITE_TAC[IM_COMPLEX_DIV_GT_0] THEN + REWRITE_TAC[complex_mul; cnj; RE_DEF; IM_DEF; complex] THEN + SIMP_TAC[dropout; VECTOR_2; LAMBDA_BETA; DIMINDEX_3; ARITH; + DIMINDEX_2] THEN + REAL_ARITH_TAC; + REWRITE_TAC[GSYM ARG_LT_PI] THEN ASM_MESON_TAC[ARG_LT_NZ]]; + ALL_TAC] THEN + COND_CASES_TAC THENL + [W(MP_TAC o PART_MATCH (lhs o rand) AFF_GT_SPECIAL_SCALE o rand o snd) THEN + ASM_REWRITE_TAC[FINITE_INSERT; FINITE_EMPTY; IN_INSERT; NOT_IN_EMPTY] THEN + DISCH_THEN SUBST1_TAC THEN MATCH_MP_TAC WEDGE_LUNE THEN + ASM_SIMP_TAC[GSYM AZIM_EQ_0_PI_EQ_COPLANAR; COLLINEAR_BASIS_3] THEN + ASM_REWRITE_TAC[AZIM_ARG]; + ALL_TAC] THEN + REWRITE_TAC[wedge] THEN + GEN_REWRITE_TAC (funpow 3 RAND_CONV) [SET_RULE `{a,b} = {b,a}`] THEN + W(MP_TAC o PART_MATCH (rand o rand) WEDGE_LUNE_GE o rand o rand o snd) THEN + ASM_SIMP_TAC[COLLINEAR_SPECIAL_SCALE; REAL_LT_IMP_NZ; AZIM_SPECIAL_SCALE] THEN + ASM_REWRITE_TAC[AZIM_ARG; COLLINEAR_BASIS_3] THEN ANTS_TAC THENL + [ASM_REWRITE_TAC[ARG_LT_NZ] THEN + ONCE_REWRITE_TAC[GSYM ARG_INV_EQ_0] THEN + ASM_REWRITE_TAC[COMPLEX_INV_DIV] THEN + ONCE_REWRITE_TAC[GSYM COMPLEX_INV_DIV] THEN + ASM_SIMP_TAC[ARG_INV; GSYM ARG_EQ_0] THEN + ASM_REAL_ARITH_TAC; + ALL_TAC] THEN + DISCH_THEN(SUBST1_TAC o SYM) THEN + REWRITE_TAC[EXTENSION; IN_DIFF; IN_UNIV; IN_ELIM_THM; ARG] THEN + REWRITE_TAC[REAL_NOT_LE] THEN + POP_ASSUM_LIST(MP_TAC o end_itlist CONJ) THEN + SPEC_TAC(`(dropout 3:real^3->real^2) w1`,`w:complex`) THEN + SPEC_TAC(`(dropout 3:real^3->real^2) w2`,`z:complex`) THEN + REPEAT GEN_TAC THEN STRIP_TAC THEN X_GEN_TAC `x3:real^3` THEN + SPEC_TAC(`(dropout 3:real^3->real^2) x3`,`x:complex`) THEN + GEN_TAC THEN REWRITE_TAC[COMPLEX_VEC_0] THEN + RULE_ASSUM_TAC(REWRITE_RULE[COMPLEX_VEC_0]) THEN + ASM_CASES_TAC `x = Cx(&0)` THEN ASM_REWRITE_TAC[] THENL + [ASM_REWRITE_TAC[complex_div; COMPLEX_MUL_LZERO; REAL_NOT_LT; ARG; ARG_0]; + ALL_TAC] THEN + ASM_REWRITE_TAC[ARG_LT_NZ] THEN + MAP_EVERY UNDISCH_TAC + [`~(Arg (z / w) < pi)`; + `~(Arg (z / w) = pi)`; + `~(Arg (z / w) = &0)`; + `~(x = Cx (&0))`; + `~(w = Cx (&0))`; + `~(z = Cx (&0))`] THEN + POP_ASSUM_LIST(K ALL_TAC) THEN REWRITE_TAC[GSYM COMPLEX_VEC_0] THEN + GEOM_BASIS_MULTIPLE_TAC 1 `w:complex` THEN + X_GEN_TAC `w:real` THEN GEN_REWRITE_TAC LAND_CONV [REAL_LE_LT] THEN + ASM_CASES_TAC `w = &0` THEN ASM_REWRITE_TAC[VECTOR_MUL_LZERO] THEN + REWRITE_TAC[COMPLEX_CMUL; COMPLEX_BASIS; COMPLEX_VEC_0] THEN + SIMP_TAC[ARG_DIV_CX; COMPLEX_MUL_RID] THEN + REWRITE_TAC[real; RE_DIV_CX; IM_DIV_CX; CX_INJ] THEN + SIMP_TAC[complex_div; ARG_MUL_CX] THEN + SIMP_TAC[ARG_INV; GSYM ARG_EQ_0; ARG_INV_EQ_0] THEN + DISCH_TAC THEN REPEAT GEN_TAC THEN REWRITE_TAC[GSYM complex_div] THEN + ASM_CASES_TAC `Arg x = &0` THEN ASM_REWRITE_TAC[] THENL + [FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [ARG_EQ_0]) THEN + DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN + REWRITE_TAC[REAL] THEN DISCH_THEN(SUBST1_TAC o SYM) THEN + REWRITE_TAC[complex_div; CX_INJ] THEN + ASM_SIMP_TAC[ARG_MUL_CX; REAL_LT_LE] THEN + ASM_SIMP_TAC[ARG_INV; GSYM ARG_EQ_0]; + ALL_TAC] THEN + REWRITE_TAC[IMP_IMP; GSYM CONJ_ASSOC] THEN + SIMP_TAC[PI_POS; REAL_ARITH + `&0 < pi ==> (~(z = &0) /\ ~(z = pi) /\ ~(z < pi) <=> pi < z)`] THEN + STRIP_TAC THEN REWRITE_TAC[REAL_LT_SUB_RADD] THEN + DISJ_CASES_TAC(REAL_ARITH `Arg z <= Arg x \/ Arg x < Arg z`) THENL + [ASM_REWRITE_TAC[GSYM REAL_NOT_LE] THEN + ONCE_REWRITE_TAC[REAL_ADD_SYM] THEN + ASM_SIMP_TAC[GSYM ARG_LE_DIV_SUM] THEN + SIMP_TAC[ARG; REAL_LT_IMP_LE]; + ALL_TAC] THEN + ASM_REWRITE_TAC[] THEN + MP_TAC(ISPECL [`x:complex`; `z:complex`] ARG_LE_DIV_SUM) THEN + ASM_SIMP_TAC[REAL_LT_IMP_LE] THEN DISCH_THEN SUBST1_TAC THEN + MATCH_MP_TAC(REAL_ARITH + `&0 <= x /\ ~(x = &0) /\ y = k - z ==> k < y + x + z`) THEN + ASM_REWRITE_TAC[ARG] THEN + GEN_REWRITE_TAC (LAND_CONV o RAND_CONV) [GSYM COMPLEX_INV_DIV] THEN + MATCH_MP_TAC ARG_INV THEN REWRITE_TAC[REAL] THEN + DISCH_THEN(STRIP_ASSUME_TAC o GSYM) THEN + ABBREV_TAC `t = Re(z / x)` THEN UNDISCH_TAC `Arg x < Arg z` THEN + UNDISCH_TAC `z / x = Cx t` THEN + ASM_SIMP_TAC[COMPLEX_FIELD + `~(x = Cx(&0)) ==> (z / x = t <=> z = t * x)`] THEN + ASM_CASES_TAC `t = &0` THEN ASM_REWRITE_TAC[COMPLEX_MUL_LZERO] THEN + ASM_SIMP_TAC[ARG_MUL_CX; REAL_LT_LE]);; + +let OPEN_WEDGE = prove + (`!z:real^3 w w1 w2. open(wedge z w w1 w2)`, + REPEAT GEN_TAC THEN + ASM_CASES_TAC `z:real^3 = w \/ collinear{z,w,w1} \/ collinear{z,w,w2}` THENL + [FIRST_X_ASSUM STRIP_ASSUME_TAC THEN + ASM_SIMP_TAC[WEDGE_DEGENERATE; OPEN_EMPTY]; + FIRST_X_ASSUM MP_TAC THEN REWRITE_TAC[DE_MORGAN_THM]] THEN + REWRITE_TAC[wedge] THEN GEOM_ORIGIN_TAC `z:real^3` THEN + GEOM_BASIS_MULTIPLE_TAC 3 `w:real^3` THEN + X_GEN_TAC `w:real` THEN GEN_REWRITE_TAC LAND_CONV [REAL_LE_LT] THEN + ASM_CASES_TAC `w = &0` THEN ASM_REWRITE_TAC[VECTOR_MUL_LZERO] THEN + ASM_SIMP_TAC[AZIM_SPECIAL_SCALE; COLLINEAR_SPECIAL_SCALE] THEN + REPEAT STRIP_TAC THEN + ONCE_REWRITE_TAC[TAUT `~a /\ b /\ c <=> ~(~a ==> ~(b /\ c))`] THEN + ASM_SIMP_TAC[AZIM_ARG] THEN REWRITE_TAC[COLLINEAR_BASIS_3] THEN + RULE_ASSUM_TAC(REWRITE_RULE[COLLINEAR_BASIS_3]) THEN + REWRITE_TAC[NOT_IMP; GSYM CONJ_ASSOC; DROPOUT_0] THEN + MATCH_MP_TAC OPEN_DROPOUT_3 THEN + UNDISCH_TAC `~((dropout 3:real^3->real^2) w1 = vec 0)` THEN + UNDISCH_TAC `~((dropout 3:real^3->real^2) w2 = vec 0)` THEN + SPEC_TAC(`(dropout 3:real^3->real^2) w2`,`v2:complex`) THEN + SPEC_TAC(`(dropout 3:real^3->real^2) w1`,`v1:complex`) THEN + POP_ASSUM_LIST(K ALL_TAC) THEN GEOM_BASIS_MULTIPLE_TAC 1 `v1:complex` THEN + X_GEN_TAC `v1:real` THEN GEN_REWRITE_TAC LAND_CONV [REAL_LE_LT] THEN + ASM_CASES_TAC `v1 = &0` THEN ASM_REWRITE_TAC[VECTOR_MUL_LZERO] THEN + REWRITE_TAC[COMPLEX_CMUL; COMPLEX_BASIS; COMPLEX_VEC_0] THEN + SIMP_TAC[ARG_DIV_CX; COMPLEX_MUL_RID] THEN REPEAT STRIP_TAC THEN + REWRITE_TAC[SET_RULE `{x | ~(x = a) /\ P x} = {x | P x} DIFF {a}`] THEN + MATCH_MP_TAC OPEN_DIFF THEN REWRITE_TAC[CLOSED_SING] THEN + MATCH_MP_TAC OPEN_ARG_LTT THEN + SIMP_TAC[REAL_LT_IMP_LE; REAL_LE_REFL; ARG]);; + +let ARG_EQ_SUBSET_HALFLINE = prove + (`!a. ?b. ~(b = vec 0) /\ {z | Arg z = a} SUBSET aff_ge {vec 0} {b}`, + GEN_TAC THEN ASM_CASES_TAC `{z | Arg z = a} SUBSET {vec 0}` THENL + [EXISTS_TAC `basis 1:real^2` THEN + SIMP_TAC[BASIS_NONZERO; DIMINDEX_2; ARITH] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + SUBSET_TRANS)) THEN SIMP_TAC[SUBSET; IN_SING; ENDS_IN_HALFLINE]; + ALL_TAC] THEN + FIRST_X_ASSUM(MP_TAC o MATCH_MP (SET_RULE + `~(s SUBSET {a}) ==> ?z. ~(a = z) /\ z IN s`)) THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `z:complex` THEN + REWRITE_TAC[IN_ELIM_THM] THEN DISCH_THEN(STRIP_ASSUME_TAC o GSYM) THEN + ASM_REWRITE_TAC[SUBSET; IN_ELIM_THM] THEN + X_GEN_TAC `x:complex` THEN + ASM_CASES_TAC `x:complex = vec 0` THEN ASM_REWRITE_TAC[ENDS_IN_HALFLINE] THEN + RULE_ASSUM_TAC(REWRITE_RULE[COMPLEX_VEC_0]) THEN ASM_SIMP_TAC[ARG_EQ] THEN + DISCH_THEN(X_CHOOSE_THEN `u:real` STRIP_ASSUME_TAC) THEN + ASM_REWRITE_TAC[GSYM COMPLEX_CMUL] THEN + REWRITE_TAC[HALFLINE_EXPLICIT; IN_ELIM_THM; VECTOR_MUL_RZERO] THEN + MAP_EVERY EXISTS_TAC [`&1 - u`; `u:real`] THEN + ASM_SIMP_TAC[VECTOR_ADD_LID; REAL_LT_IMP_LE] THEN ASM_REAL_ARITH_TAC);; + +let ARG_DIV_EQ_SUBSET_HALFLINE = prove + (`!w a. ~(w = vec 0) + ==> ?b. ~(b = vec 0) /\ + {z | Arg(z / w) = a} SUBSET aff_ge {vec 0} {b}`, + REPEAT GEN_TAC THEN GEOM_BASIS_MULTIPLE_TAC 1 `w:complex` THEN + X_GEN_TAC `w:real` THEN ASM_CASES_TAC `w = &0` THEN + ASM_REWRITE_TAC[VECTOR_MUL_LZERO; REAL_LE_LT] THEN DISCH_TAC THEN + X_GEN_TAC `a:real` THEN DISCH_THEN(K ALL_TAC) THEN + ASM_SIMP_TAC[ARG_DIV_CX; COMPLEX_CMUL; COMPLEX_BASIS; GSYM CX_MUL; + REAL_MUL_RID; ARG_EQ_SUBSET_HALFLINE]);; + +let COPLANAR_AZIM_EQ = prove + (`!v0 v1 w1 a. + (collinear{v0,v1,w1} ==> ~(a = &0)) + ==> coplanar {z | azim v0 v1 w1 z = a}`, + REPEAT GEN_TAC THEN ASM_CASES_TAC `collinear{v0:real^3,v1,w1}` THENL + [ASM_SIMP_TAC[azim_def; EMPTY_GSPEC; COPLANAR_EMPTY]; ALL_TAC] THEN + ASM_REWRITE_TAC[] THEN POP_ASSUM MP_TAC THEN + GEOM_ORIGIN_TAC `v0:real^3` THEN + GEOM_BASIS_MULTIPLE_TAC 3 `v1:real^3` THEN + X_GEN_TAC `v1:real` THEN ASM_CASES_TAC `v1 = &0` THENL + [ASM_REWRITE_TAC[VECTOR_MUL_LZERO; INSERT_AC; COLLINEAR_2]; ALL_TAC] THEN + ASM_SIMP_TAC[REAL_LE_LT; COLLINEAR_SPECIAL_SCALE] THEN REPEAT STRIP_TAC THEN + ASM_SIMP_TAC[AZIM_SPECIAL_SCALE; AZIM_ARG] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE RAND_CONV [COLLINEAR_BASIS_3]) THEN + POP_ASSUM_LIST(K ALL_TAC) THEN DISCH_THEN(X_CHOOSE_THEN `b:real^2` + STRIP_ASSUME_TAC o SPEC `a:real` o MATCH_MP ARG_DIV_EQ_SUBSET_HALFLINE) THEN + REWRITE_TAC[coplanar] THEN MAP_EVERY EXISTS_TAC + [`vec 0:real^3`; `pushin 3 (&0) (b:real^2):real^3`; `basis 3:real^3`] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [SUBSET]) THEN + REWRITE_TAC[AFFINE_HULL_3; HALFLINE; SUBSET; IN_ELIM_THM] THEN + DISCH_THEN(fun th -> X_GEN_TAC `x:real^3` THEN DISCH_TAC THEN + MP_TAC(SPEC `(dropout 3:real^3->real^2) x` th)) THEN + ASM_REWRITE_TAC[VECTOR_MUL_RZERO; VECTOR_ADD_LID] THEN + DISCH_THEN(X_CHOOSE_THEN `v:real` STRIP_ASSUME_TAC) THEN + MAP_EVERY EXISTS_TAC [`&1 - v - (x:real^3)$3`; `v:real`; `(x:real^3)$3`] THEN + CONJ_TAC THENL [REAL_ARITH_TAC; ALL_TAC] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [CART_EQ]) THEN + SIMP_TAC[CART_EQ; DIMINDEX_2; DIMINDEX_3; FORALL_2; FORALL_3; LAMBDA_BETA; + dropout; pushin; VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT; ARITH; + BASIS_COMPONENT] THEN + REAL_ARITH_TAC);; + +(* ------------------------------------------------------------------------- *) +(* Volume of a tetrahedron defined by conv0. *) +(* ------------------------------------------------------------------------- *) + +let delta_x = new_definition + `delta_x x1 x2 x3 x4 x5 x6 = + x1*x4*(--x1 + x2 + x3 -x4 + x5 + x6) + + x2*x5*(x1 - x2 + x3 + x4 -x5 + x6) + + x3*x6*(x1 + x2 - x3 + x4 + x5 - x6) + -x2*x3*x4 - x1*x3*x5 - x1*x2*x6 -x4*x5*x6:real`;; + +let VOLUME_OF_CLOSED_TETRAHEDRON = prove + (`!x1 x2 x3 x4:real^3. + measure(convex hull {x1,x2,x3,x4}) = + sqrt(delta_x (dist(x1,x2) pow 2) (dist(x1,x3) pow 2) (dist(x1,x4) pow 2) + (dist(x3,x4) pow 2) (dist(x2,x4) pow 2) (dist(x2,x3) pow 2)) + / &12`, + REPEAT GEN_TAC THEN REWRITE_TAC[LET_DEF; LET_END_DEF] THEN + REWRITE_TAC[MEASURE_TETRAHEDRON] THEN + REWRITE_TAC[REAL_ARITH `x / &6 = y / &12 <=> y = &2 * x`] THEN + MATCH_MP_TAC SQRT_UNIQUE THEN + SIMP_TAC[REAL_LE_MUL; REAL_ABS_POS; REAL_POS] THEN + REWRITE_TAC[REAL_POW_MUL; REAL_POW2_ABS; delta_x] THEN + REWRITE_TAC[dist; NORM_POW_2] THEN + SIMP_TAC[DOT_3; VECTOR_SUB_COMPONENT; DIMINDEX_3; ARITH] THEN + CONV_TAC REAL_RING);; + +let VOLUME_OF_TETRAHEDRON = prove + (`!v1 v2 v3 v4:real^3. + measure(conv0 {v1,v2,v3,v4}) = + let x12 = dist(v1,v2) pow 2 in + let x13 = dist(v1,v3) pow 2 in + let x14 = dist(v1,v4) pow 2 in + let x23 = dist(v2,v3) pow 2 in + let x24 = dist(v2,v4) pow 2 in + let x34 = dist(v3,v4) pow 2 in + sqrt(delta_x x12 x13 x14 x34 x24 x23)/(&12)`, + REPEAT GEN_TAC THEN CONV_TAC(TOP_DEPTH_CONV let_CONV) THEN + ASM_SIMP_TAC[GSYM VOLUME_OF_CLOSED_TETRAHEDRON] THEN + MATCH_MP_TAC MEASURE_CONV0_CONVEX_HULL THEN + SIMP_TAC[DIMINDEX_3; FINITE_INSERT; FINITE_EMPTY; CARD_CLAUSES] THEN + ARITH_TAC);; + +(* ------------------------------------------------------------------------- *) +(* Circle area. Should maybe extend WLOG tactics for such scaling. *) +(* ------------------------------------------------------------------------- *) + +let AREA_UNIT_CBALL = prove + (`measure(cball(vec 0:real^2,&1)) = pi`, + REPEAT STRIP_TAC THEN + MATCH_MP_TAC(INST_TYPE[`:1`,`:M`; `:2`,`:N`] FUBINI_SIMPLE_COMPACT) THEN + EXISTS_TAC `1` THEN + SIMP_TAC[DIMINDEX_1; DIMINDEX_2; ARITH; COMPACT_CBALL; SLICE_CBALL] THEN + REWRITE_TAC[VEC_COMPONENT; DROPOUT_0; REAL_SUB_RZERO] THEN + ONCE_REWRITE_TAC[COND_RAND] THEN REWRITE_TAC[MEASURE_EMPTY] THEN + SUBGOAL_THEN `!t. abs(t) <= &1 <=> t IN real_interval[-- &1,&1]` + (fun th -> REWRITE_TAC[th]) + THENL [REWRITE_TAC[IN_REAL_INTERVAL] THEN REAL_ARITH_TAC; ALL_TAC] THEN + REWRITE_TAC[HAS_REAL_INTEGRAL_RESTRICT_UNIV; BALL_1] THEN + MATCH_MP_TAC HAS_REAL_INTEGRAL_EQ THEN + EXISTS_TAC `\t. &2 * sqrt(&1 - t pow 2)` THEN CONJ_TAC THENL + [X_GEN_TAC `t:real` THEN SIMP_TAC[IN_REAL_INTERVAL; MEASURE_INTERVAL] THEN + REWRITE_TAC[REAL_BOUNDS_LE; VECTOR_ADD_LID; VECTOR_SUB_LZERO] THEN + DISCH_TAC THEN + W(MP_TAC o PART_MATCH (lhs o rand) CONTENT_1 o rand o snd) THEN + REWRITE_TAC[LIFT_DROP; DROP_NEG] THEN + ANTS_TAC THENL [ALL_TAC; SIMP_TAC[REAL_POW_ONE] THEN REAL_ARITH_TAC] THEN + MATCH_MP_TAC(REAL_ARITH `&0 <= x ==> --x <= x`) THEN + ASM_SIMP_TAC[SQRT_POS_LE; REAL_SUB_LE; GSYM REAL_LE_SQUARE_ABS; + REAL_ABS_NUM]; + ALL_TAC] THEN + MP_TAC(ISPECL + [`\x. asn(x) + x * sqrt(&1 - x pow 2)`; + `\x. &2 * sqrt(&1 - x pow 2)`; + `-- &1`; `&1`] REAL_FUNDAMENTAL_THEOREM_OF_CALCULUS_INTERIOR) THEN + REWRITE_TAC[ASN_1; ASN_NEG_1] THEN CONV_TAC REAL_RAT_REDUCE_CONV THEN + REWRITE_TAC[SQRT_0; REAL_MUL_RZERO; REAL_ADD_RID] THEN + REWRITE_TAC[REAL_ARITH `x / &2 - --(x / &2) = x`] THEN + DISCH_THEN MATCH_MP_TAC THEN CONJ_TAC THENL + [MATCH_MP_TAC REAL_CONTINUOUS_ON_ADD THEN + SIMP_TAC[REAL_CONTINUOUS_ON_ASN; IN_REAL_INTERVAL; REAL_BOUNDS_LE] THEN + MATCH_MP_TAC REAL_CONTINUOUS_ON_MUL THEN + REWRITE_TAC[REAL_CONTINUOUS_ON_ID] THEN + GEN_REWRITE_TAC LAND_CONV [GSYM o_DEF] THEN + MATCH_MP_TAC REAL_CONTINUOUS_ON_COMPOSE THEN + SIMP_TAC[REAL_CONTINUOUS_ON_SUB; REAL_CONTINUOUS_ON_POW; + REAL_CONTINUOUS_ON_ID; REAL_CONTINUOUS_ON_CONST] THEN + MATCH_MP_TAC REAL_CONTINUOUS_ON_SQRT THEN + REWRITE_TAC[FORALL_IN_IMAGE; IN_REAL_INTERVAL] THEN + REWRITE_TAC[REAL_ARITH `&0 <= &1 - x <=> x <= &1 pow 2`] THEN + REWRITE_TAC[GSYM REAL_LE_SQUARE_ABS; REAL_ABS_NUM] THEN + REAL_ARITH_TAC; + REWRITE_TAC[IN_REAL_INTERVAL; REAL_BOUNDS_LT] THEN REPEAT STRIP_TAC THEN + REAL_DIFF_TAC THEN + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[REAL_MUL_LID; REAL_POW_1; REAL_MUL_RID] THEN + REWRITE_TAC[REAL_SUB_LZERO; REAL_MUL_RNEG; REAL_INV_MUL] THEN + ASM_REWRITE_TAC[REAL_SUB_LT; ABS_SQUARE_LT_1] THEN + MATCH_MP_TAC(REAL_FIELD + `s pow 2 = &1 - x pow 2 /\ x pow 2 < &1 + ==> (inv s + x * --(&2 * x) * inv (&2) * inv s + s) = &2 * s`) THEN + ASM_SIMP_TAC[ABS_SQUARE_LT_1; SQRT_POW_2; REAL_SUB_LE; REAL_LT_IMP_LE]]);; + +let AREA_CBALL = prove + (`!z:real^2 r. &0 <= r ==> measure(cball(z,r)) = pi * r pow 2`, + REPEAT STRIP_TAC THEN ASM_CASES_TAC `r = &0` THENL + [ASM_SIMP_TAC[CBALL_SING; REAL_POW_2; REAL_MUL_RZERO] THEN + MATCH_MP_TAC MEASURE_UNIQUE THEN + REWRITE_TAC[HAS_MEASURE_0; NEGLIGIBLE_SING]; + ALL_TAC] THEN + SUBGOAL_THEN `&0 < r` ASSUME_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN + MP_TAC(ISPECL [`cball(vec 0:real^2,&1)`; `r:real`; `z:real^2`; `pi`] + HAS_MEASURE_AFFINITY) THEN + REWRITE_TAC[HAS_MEASURE_MEASURABLE_MEASURE; MEASURABLE_CBALL; + AREA_UNIT_CBALL] THEN + ASM_REWRITE_TAC[real_abs; DIMINDEX_2] THEN + DISCH_THEN(MP_TAC o CONJUNCT2) THEN + GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [REAL_MUL_SYM] THEN + DISCH_THEN(SUBST1_TAC o SYM) THEN AP_TERM_TAC THEN + MATCH_MP_TAC SUBSET_ANTISYM THEN REWRITE_TAC[SUBSET; FORALL_IN_IMAGE] THEN + REWRITE_TAC[IN_CBALL_0; IN_IMAGE] THEN REWRITE_TAC[IN_CBALL] THEN + REWRITE_TAC[NORM_ARITH `dist(z,a + z) = norm a`; NORM_MUL] THEN + ONCE_REWRITE_TAC[REAL_ARITH `abs r * x <= r <=> abs r * x <= r * &1`] THEN + ASM_SIMP_TAC[real_abs; REAL_LE_LMUL; dist] THEN X_GEN_TAC `w:real^2` THEN + DISCH_TAC THEN EXISTS_TAC `inv(r) % (w - z):real^2` THEN + ASM_SIMP_TAC[VECTOR_MUL_ASSOC; REAL_MUL_RINV] THEN + CONJ_TAC THENL [NORM_ARITH_TAC; ALL_TAC] THEN + REWRITE_TAC[NORM_MUL; REAL_ABS_INV] THEN ASM_REWRITE_TAC[real_abs] THEN + ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN + ASM_SIMP_TAC[GSYM real_div; REAL_LE_LDIV_EQ; REAL_MUL_LID] THEN + ONCE_REWRITE_TAC[NORM_SUB] THEN ASM_REWRITE_TAC[]);; + +let AREA_BALL = prove + (`!z:real^2 r. &0 <= r ==> measure(ball(z,r)) = pi * r pow 2`, + SIMP_TAC[GSYM INTERIOR_CBALL; GSYM AREA_CBALL] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC MEASURE_INTERIOR THEN + SIMP_TAC[BOUNDED_CBALL; NEGLIGIBLE_CONVEX_FRONTIER; CONVEX_CBALL]);; + +(* ------------------------------------------------------------------------- *) +(* Volume of a ball. *) +(* ------------------------------------------------------------------------- *) + +let VOLUME_CBALL = prove + (`!z:real^3 r. &0 <= r ==> measure(cball(z,r)) = &4 / &3 * pi * r pow 3`, + GEOM_ORIGIN_TAC `z:real^3` THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC(INST_TYPE[`:2`,`:M`; `:3`,`:N`] FUBINI_SIMPLE_COMPACT) THEN + EXISTS_TAC `1` THEN + SIMP_TAC[DIMINDEX_2; DIMINDEX_3; ARITH; COMPACT_CBALL; SLICE_CBALL] THEN + REWRITE_TAC[VEC_COMPONENT; DROPOUT_0; REAL_SUB_RZERO] THEN + ONCE_REWRITE_TAC[COND_RAND] THEN REWRITE_TAC[MEASURE_EMPTY] THEN + SUBGOAL_THEN `!t. abs(t) <= r <=> t IN real_interval[--r,r]` + (fun th -> REWRITE_TAC[th]) + THENL [REWRITE_TAC[IN_REAL_INTERVAL] THEN REAL_ARITH_TAC; ALL_TAC] THEN + REWRITE_TAC[HAS_REAL_INTEGRAL_RESTRICT_UNIV] THEN + MATCH_MP_TAC HAS_REAL_INTEGRAL_EQ THEN + EXISTS_TAC `\t. pi * (r pow 2 - t pow 2)` THEN CONJ_TAC THENL + [X_GEN_TAC `t:real` THEN REWRITE_TAC[IN_REAL_INTERVAL; REAL_BOUNDS_LE] THEN + SIMP_TAC[AREA_CBALL; SQRT_POS_LE; REAL_SUB_LE; GSYM REAL_LE_SQUARE_ABS; + SQRT_POW_2; REAL_ARITH `abs x <= r ==> abs x <= abs r`]; + ALL_TAC] THEN + MP_TAC(ISPECL + [`\t. pi * (r pow 2 * t - &1 / &3 * t pow 3)`; + `\t. pi * (r pow 2 - t pow 2)`; + `--r:real`; `r:real`] REAL_FUNDAMENTAL_THEOREM_OF_CALCULUS) THEN + REWRITE_TAC[] THEN ANTS_TAC THENL + [CONJ_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN + REPEAT STRIP_TAC THEN REAL_DIFF_TAC THEN + CONV_TAC NUM_REDUCE_CONV THEN CONV_TAC REAL_RING; + MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_TERM_TAC THEN + CONV_TAC REAL_RING]);; + +let VOLUME_BALL = prove + (`!z:real^3 r. &0 <= r ==> measure(ball(z,r)) = &4 / &3 * pi * r pow 3`, + SIMP_TAC[GSYM INTERIOR_CBALL; GSYM VOLUME_CBALL] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC MEASURE_INTERIOR THEN + SIMP_TAC[BOUNDED_CBALL; NEGLIGIBLE_CONVEX_FRONTIER; CONVEX_CBALL]);; + +(* ------------------------------------------------------------------------- *) +(* Frustum. *) +(* ------------------------------------------------------------------------- *) + +let rconesgn = new_definition + `rconesgn sgn v w h = + {x:real^A | sgn ((x-v) dot (w-v)) (dist(x,v)*dist(w,v)*h)}`;; + +let rcone_gt = new_definition `rcone_gt = rconesgn ( > )`;; + +let rcone_ge = new_definition `rcone_ge = rconesgn ( >= )`;; + +let rcone_eq = new_definition `rcone_eq = rconesgn ( = )`;; + +let frustum = new_definition + `frustum v0 v1 h1 h2 a = + { y:real^N | rcone_gt v0 v1 a y /\ + let d = (y - v0) dot (v1 - v0) in + let n = norm(v1 - v0) in + (h1*n < d /\ d < h2*n)}`;; + +let frustt = new_definition `frustt v0 v1 h a = frustum v0 v1 (&0) h a`;; + +let FRUSTUM_DEGENERATE = prove + (`!v0 h1 h2 a. frustum v0 v0 h1 h2 a = {}`, + REWRITE_TAC[frustum; VECTOR_SUB_REFL; NORM_0; DOT_RZERO] THEN + CONV_TAC(TOP_DEPTH_CONV let_CONV) THEN + REWRITE_TAC[REAL_MUL_RZERO; REAL_LT_REFL] THEN SET_TAC[]);; + +let CONVEX_RCONE_GT = prove + (`!v0 v1:real^N a. &0 <= a ==> convex(rcone_gt v0 v1 a)`, + REWRITE_TAC[rcone_gt; rconesgn] THEN + GEOM_ORIGIN_TAC `v0:real^N` THEN REPEAT GEN_TAC THEN + REWRITE_TAC[VECTOR_SUB_RZERO; DIST_0] THEN + REWRITE_TAC[CONVEX_ALT; IN_ELIM_THM; real_gt; DOT_LADD; DOT_LMUL] THEN + DISCH_TAC THEN MAP_EVERY X_GEN_TAC [`x:real^N`; `y:real^N`; `t:real`] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_LET_TRANS THEN + EXISTS_TAC `(&1 - t) * norm(x:real^N) * norm v1 * a + + t * norm(y:real^N) * norm(v1:real^N) * a` THEN + CONJ_TAC THENL + [REWRITE_TAC[GSYM REAL_ADD_RDISTRIB; REAL_MUL_ASSOC] THEN + MATCH_MP_TAC REAL_LE_RMUL THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC REAL_LE_RMUL THEN REWRITE_TAC[NORM_POS_LE] THEN + MATCH_MP_TAC(NORM_ARITH + `norm(x:real^N) = a /\ norm(y) = b ==> norm(x + y) <= a + b`) THEN + REWRITE_TAC[NORM_MUL] THEN CONJ_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN + ASM_REAL_ARITH_TAC; + MATCH_MP_TAC REAL_CONVEX_BOUND2_LT THEN ASM_REAL_ARITH_TAC]);; + +let OPEN_RCONE_GT = prove + (`!v0 v1:real^N a. open(rcone_gt v0 v1 a)`, + REWRITE_TAC[rcone_gt; rconesgn] THEN + GEOM_ORIGIN_TAC `v0:real^N` THEN REPEAT GEN_TAC THEN + REWRITE_TAC[VECTOR_SUB_RZERO; DIST_0] THEN + MP_TAC(ISPECL [`\x:real^N. lift(x dot v1 - norm x * norm v1 * a)`; + `{x:real^1 | x$1 > &0}`] + CONTINUOUS_OPEN_PREIMAGE_UNIV) THEN + REWRITE_TAC[OPEN_HALFSPACE_COMPONENT_GT] THEN REWRITE_TAC[GSYM drop] THEN + REWRITE_TAC[IN_ELIM_THM; real_gt; REAL_SUB_LT; LIFT_DROP] THEN + DISCH_THEN MATCH_MP_TAC THEN GEN_TAC THEN REWRITE_TAC[LIFT_SUB] THEN + ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN REWRITE_TAC[LIFT_CMUL] THEN + MATCH_MP_TAC CONTINUOUS_SUB THEN ONCE_REWRITE_TAC[DOT_SYM] THEN + REWRITE_TAC[REWRITE_RULE[o_DEF] CONTINUOUS_AT_LIFT_DOT] THEN + MATCH_MP_TAC CONTINUOUS_CMUL THEN + REWRITE_TAC[REWRITE_RULE[o_DEF] CONTINUOUS_AT_LIFT_NORM]);; + +let RCONE_GT_NEG = prove + (`!v0 v1:real^N a. + rcone_gt v0 v1 (--a) = + IMAGE (\x. &2 % v0 - x) ((:real^N) DIFF rcone_ge v0 v1 a)`, + REPEAT GEN_TAC THEN CONV_TAC SYM_CONV THEN + MATCH_MP_TAC SURJECTIVE_IMAGE_EQ THEN REWRITE_TAC[] THEN CONJ_TAC THENL + [MESON_TAC[VECTOR_ARITH `a - (a - b):real^N = b`]; + REWRITE_TAC[rcone_gt; rconesgn; rcone_ge; + IN_ELIM_THM; IN_DIFF; IN_UNIV] THEN + REWRITE_TAC[NORM_ARITH `dist(&2 % x - y,x) = dist(y,x)`] THEN + REWRITE_TAC[VECTOR_ARITH `&2 % v - x - v:real^N = --(x - v)`] THEN + REWRITE_TAC[DOT_LNEG] THEN REAL_ARITH_TAC]);; + +let VOLUME_FRUSTT_STRONG = prove + (`!v0 v1:real^3 h a. + &0 < a + ==> bounded(frustt v0 v1 h a) /\ + convex(frustt v0 v1 h a) /\ + measurable(frustt v0 v1 h a) /\ + measure(frustt v0 v1 h a) = + if v1 = v0 \/ &1 <= a \/ h < &0 then &0 + else pi * ((h / a) pow 2 - h pow 2) * h / &3`, + REPEAT GEN_TAC THEN DISCH_TAC THEN + REWRITE_TAC[frustt; frustum; rcone_gt; rconesgn; IN_ELIM_THM] THEN + CONV_TAC(TOP_DEPTH_CONV let_CONV) THEN GEOM_ORIGIN_TAC `v0:real^3` THEN + REWRITE_TAC[VECTOR_SUB_RZERO; REAL_MUL_LZERO; DIST_0; real_gt] THEN + GEOM_BASIS_MULTIPLE_TAC 1 `v1:real^3` THEN + X_GEN_TAC `b:real` THEN REPEAT(GEN_TAC ORELSE DISCH_TAC) THEN + FIRST_ASSUM(DISJ_CASES_TAC o MATCH_MP (REAL_ARITH + `&0 <= x ==> x = &0 \/ &0 < x`)) THEN + ASM_REWRITE_TAC[DOT_RZERO; REAL_MUL_LZERO; REAL_MUL_RZERO; REAL_LT_REFL; + MEASURABLE_EMPTY; MEASURE_EMPTY; EMPTY_GSPEC; VECTOR_MUL_LZERO; + BOUNDED_EMPTY; CONVEX_EMPTY] THEN + ASM_CASES_TAC `&1 <= a` THEN ASM_REWRITE_TAC[] THENL + [SUBGOAL_THEN + `!y:real^3. ~(norm(y) * norm(b % basis 1:real^3) * a + < y dot (b % basis 1))` + (fun th -> REWRITE_TAC[th; EMPTY_GSPEC; MEASURABLE_EMPTY; + BOUNDED_EMPTY; CONVEX_EMPTY; MEASURE_EMPTY]) THEN + REWRITE_TAC[REAL_NOT_LT] THEN X_GEN_TAC `y:real^3` THEN + MATCH_MP_TAC(REAL_ARITH `abs(x) <= a ==> x <= a`) THEN + SIMP_TAC[DOT_RMUL; NORM_MUL; REAL_ABS_MUL; DOT_BASIS; NORM_BASIS; + DIMINDEX_3; ARITH] THEN + REWRITE_TAC[REAL_ARITH + `b * y <= n * (b * &1) * a <=> b * &1 * y <= b * a * n`] THEN + MATCH_MP_TAC REAL_LE_LMUL THEN REWRITE_TAC[REAL_ABS_POS] THEN + MATCH_MP_TAC REAL_LE_MUL2 THEN + ASM_SIMP_TAC[REAL_POS; REAL_ABS_POS; COMPONENT_LE_NORM; DIMINDEX_3; ARITH]; + ALL_TAC] THEN + RULE_ASSUM_TAC(REWRITE_RULE[REAL_NOT_LE]) THEN + SIMP_TAC[NORM_MUL; NORM_BASIS; DOT_BASIS; DOT_RMUL; DIMINDEX_3; ARITH] THEN + ONCE_REWRITE_TAC[REAL_ARITH `n * x * a:real = x * n * a`] THEN + ASM_REWRITE_TAC[real_abs; REAL_MUL_RID] THEN + ASM_SIMP_TAC[REAL_MUL_RID; REAL_LT_LMUL_EQ; REAL_LT_MUL_EQ; NORM_POS_LT] THEN + ASM_SIMP_TAC[VECTOR_MUL_EQ_0; BASIS_NONZERO; DIMINDEX_3; ARITH; + REAL_LT_IMP_NZ] THEN + ASM_SIMP_TAC[GSYM REAL_LT_RDIV_EQ; NORM_LT_SQUARE] THEN + ASM_SIMP_TAC[REAL_POW_DIV; REAL_POW_LT; REAL_LT_RDIV_EQ] THEN + REWRITE_TAC[REAL_ARITH `(&0 * x < y /\ u < v) /\ &0 < y /\ y < h <=> + &0 < y /\ y < h /\ u < v`] THEN + MATCH_MP_TAC(TAUT `a /\ b /\ (a /\ b ==> c) ==> a /\ b /\ c`) THEN + REPEAT CONJ_TAC THENL + [MATCH_MP_TAC BOUNDED_SUBSET THEN + EXISTS_TAC `ball(vec 0:real^3,h / a)` THEN + REWRITE_TAC[BOUNDED_BALL; IN_BALL_0; SUBSET; IN_ELIM_THM] THEN + REWRITE_TAC[NORM_LT_SQUARE] THEN + ASM_SIMP_TAC[REAL_POW_DIV; REAL_LT_RDIV_EQ; REAL_POW_LT] THEN + X_GEN_TAC `x:real^3` THEN STRIP_TAC THEN + CONJ_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP + (REWRITE_RULE[IMP_CONJ] REAL_LTE_TRANS)) THEN + MATCH_MP_TAC REAL_POW_LE2 THEN ASM_REAL_ARITH_TAC; + REWRITE_TAC[SET_RULE `{x | P x /\ Q x /\ R x} = + {x | Q x} INTER {x | P x /\ R x}`] THEN + REWRITE_TAC[REAL_ARITH `&0 < y <=> y > &0`] THEN + MATCH_MP_TAC CONVEX_INTER THEN + REWRITE_TAC[CONVEX_HALFSPACE_COMPONENT_LT] THEN + MP_TAC(ISPECL [`vec 0:real^3`; `basis 1:real^3`; `a:real`] + CONVEX_RCONE_GT) THEN + ASM_SIMP_TAC[REAL_LT_IMP_LE; rcone_gt; rconesgn] THEN + REWRITE_TAC[VECTOR_SUB_RZERO; DIST_0] THEN + SIMP_TAC[DOT_BASIS; NORM_BASIS; DIMINDEX_3; ARITH] THEN + REWRITE_TAC[real_gt; REAL_MUL_LID] THEN + ASM_SIMP_TAC[GSYM REAL_LT_RDIV_EQ] THEN + REWRITE_TAC[NORM_LT_SQUARE] THEN + ASM_SIMP_TAC[REAL_POW_DIV; REAL_LT_RDIV_EQ; REAL_POW_LT] THEN + REWRITE_TAC[REAL_MUL_LZERO]; + ALL_TAC] THEN + STRIP_TAC THEN + MATCH_MP_TAC(INST_TYPE [`:2`,`:M`] FUBINI_SIMPLE_CONVEX_STRONG) THEN + EXISTS_TAC `1` THEN REWRITE_TAC[DIMINDEX_2; DIMINDEX_3; ARITH] THEN + ASM_REWRITE_TAC[] THEN + SIMP_TAC[SLICE_312; DIMINDEX_2; DIMINDEX_3; ARITH; IN_ELIM_THM; + VECTOR_3; DOT_3; GSYM DOT_2] THEN + SUBGOAL_THEN `&0 < inv(a pow 2) - &1` ASSUME_TAC THENL + [REWRITE_TAC[REAL_SUB_LT] THEN MATCH_MP_TAC REAL_INV_1_LT THEN + ASM_SIMP_TAC[REAL_POW_1_LT; REAL_LT_IMP_LE; ARITH; REAL_POW_LT]; + ALL_TAC] THEN + MATCH_MP_TAC HAS_REAL_INTEGRAL_EQ THEN + EXISTS_TAC `\t. if &0 < t /\ t < h then pi * (inv(a pow 2) - &1) * t pow 2 + else &0` THEN + CONJ_TAC THENL + [X_GEN_TAC `t:real` THEN DISCH_TAC THEN REWRITE_TAC[] THEN + COND_CASES_TAC THEN + ASM_REWRITE_TAC[EMPTY_GSPEC; CONJ_ASSOC; + MEASURE_EMPTY; MEASURABLE_EMPTY] THEN + MATCH_MP_TAC EQ_TRANS THEN + EXISTS_TAC `measure(ball(vec 0:real^2,sqrt(inv(a pow 2) - &1) * t))` THEN + CONJ_TAC THENL + [W(MP_TAC o PART_MATCH (lhs o rand) AREA_BALL o rand o snd) THEN + ASM_SIMP_TAC[REAL_LT_IMP_LE; SQRT_POS_LT; REAL_LT_MUL] THEN + ASM_SIMP_TAC[SQRT_POW_2; REAL_LT_IMP_LE; REAL_POW_MUL]; + AP_TERM_TAC THEN REWRITE_TAC[IN_BALL_0; EXTENSION; IN_ELIM_THM] THEN + REWRITE_TAC[NORM_LT_SQUARE] THEN + ASM_SIMP_TAC[SQRT_POS_LT; SQRT_POW_2; REAL_LT_IMP_LE; REAL_LT_MUL; + REAL_POW_MUL; GSYM REAL_LT_RDIV_EQ; REAL_POW_LT] THEN + REAL_ARITH_TAC]; + ALL_TAC] THEN + REWRITE_TAC[GSYM IN_REAL_INTERVAL; HAS_REAL_INTEGRAL_RESTRICT_UNIV] THEN + REWRITE_TAC[HAS_REAL_INTEGRAL_OPEN_INTERVAL] THEN + COND_CASES_TAC THENL + [ASM_MESON_TAC[REAL_INTERVAL_EQ_EMPTY; HAS_REAL_INTEGRAL_EMPTY]; + RULE_ASSUM_TAC(REWRITE_RULE[REAL_NOT_LT])] THEN + MP_TAC(ISPECL + [`\t. pi / &3 * (inv (a pow 2) - &1) * t pow 3`; + `\t. pi * (inv (a pow 2) - &1) * t pow 2`; + `&0`; `h:real`] REAL_FUNDAMENTAL_THEOREM_OF_CALCULUS) THEN + REWRITE_TAC[] THEN ANTS_TAC THENL + [ASM_REWRITE_TAC[] THEN + REPEAT STRIP_TAC THEN REAL_DIFF_TAC THEN + CONV_TAC NUM_REDUCE_CONV THEN CONV_TAC REAL_RING; + MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_TERM_TAC THEN + UNDISCH_TAC `&0 < a` THEN CONV_TAC REAL_FIELD]);; + +let VOLUME_FRUSTT = prove + (`!v0 v1:real^3 h a. + &0 < a + ==> measurable(frustt v0 v1 h a) /\ + measure(frustt v0 v1 h a) = + if v1 = v0 \/ &1 <= a \/ h < &0 then &0 + else pi * ((h / a) pow 2 - h pow 2) * h / &3`, + SIMP_TAC[VOLUME_FRUSTT_STRONG]);; + +(* ------------------------------------------------------------------------- *) +(* Ellipsoid. *) +(* ------------------------------------------------------------------------- *) + +let scale = new_definition + `scale (t:real^3) (u:real^3):real^3 = + vector[t$1 * u$1; t$2 * u$2; t$3 * u$3]`;; + +let normball = new_definition `normball x r = { y:real^A | dist(y,x) < r}`;; + +let ellipsoid = new_definition + `ellipsoid t r = IMAGE (scale t) (normball(vec 0) r)`;; + +let NORMBALL_BALL = prove + (`!z r. normball z r = ball(z,r)`, + REWRITE_TAC[normball; ball; DIST_SYM]);; + +let MEASURE_SCALE = prove + (`!s. measurable s + ==> measurable(IMAGE (scale t) s) /\ + measure(IMAGE (scale t) s) = abs(t$1 * t$2 * t$3) * measure s`, + GEN_TAC THEN GEN_REWRITE_TAC LAND_CONV [HAS_MEASURE_MEASURE] THEN + DISCH_THEN(MP_TAC o SPEC `\i. (t:real^3)$i` o + MATCH_MP HAS_MEASURE_STRETCH) THEN + REWRITE_TAC[DIMINDEX_3; PRODUCT_3] THEN + SUBGOAL_THEN `(\x:real^3. (lambda k. t$k * x$k):real^3) = scale t` + SUBST1_TAC THENL + [SIMP_TAC[CART_EQ; FUN_EQ_THM; scale; LAMBDA_BETA; DIMINDEX_3; + VECTOR_3; ARITH; FORALL_3]; + MESON_TAC[measurable; MEASURE_UNIQUE]]);; + +let MEASURE_ELLIPSOID = prove + (`!t r. &0 <= r + ==> measurable(ellipsoid t r) /\ + measure(ellipsoid t r) = + abs(t$1 * t$2 * t$3) * &4 / &3 * pi * r pow 3`, + REPEAT GEN_TAC THEN DISCH_TAC THEN + FIRST_X_ASSUM(SUBST1_TAC o SYM o + SPEC `vec 0:real^3` o MATCH_MP VOLUME_BALL) THEN + REWRITE_TAC[normball; ellipsoid] THEN ONCE_REWRITE_TAC[DIST_SYM] THEN + REWRITE_TAC[GSYM ball] THEN MATCH_MP_TAC MEASURE_SCALE THEN + REWRITE_TAC[MEASURABLE_BALL]);; + +let MEASURABLE_ELLIPSOID = prove + (`!t r. measurable(ellipsoid t r)`, + REPEAT GEN_TAC THEN + ASM_CASES_TAC `&0 <= r` THEN ASM_SIMP_TAC[MEASURE_ELLIPSOID] THEN + REWRITE_TAC[ellipsoid; NORMBALL_BALL; IMAGE; IN_BALL_0] THEN + ASM_SIMP_TAC[NORM_ARITH `~(&0 <= r) ==> ~(norm(x:real^3) < r)`] THEN + REWRITE_TAC[EMPTY_GSPEC; MEASURABLE_EMPTY]);; + +(* ------------------------------------------------------------------------- *) +(* Conic cap. *) +(* ------------------------------------------------------------------------- *) + +let conic_cap = new_definition + `conic_cap v0 v1 r a = normball v0 r INTER rcone_gt v0 v1 a`;; + +let CONIC_CAP_DEGENERATE = prove + (`!v0 r a. conic_cap v0 v0 r a = {}`, + REWRITE_TAC[conic_cap; rcone_gt; rconesgn; VECTOR_SUB_REFL] THEN + REWRITE_TAC[DIST_REFL; DOT_RZERO; REAL_MUL_RZERO; REAL_MUL_LZERO] THEN + REWRITE_TAC[real_gt; REAL_LT_REFL] THEN SET_TAC[]);; + +let BOUNDED_CONIC_CAP = prove + (`!v0 v1:real^3 r a. bounded(conic_cap v0 v1 r a)`, + REPEAT GEN_TAC THEN REWRITE_TAC[conic_cap; NORMBALL_BALL] THEN + MATCH_MP_TAC BOUNDED_SUBSET THEN EXISTS_TAC `ball(v0:real^3,r)` THEN + REWRITE_TAC[BOUNDED_BALL] THEN SET_TAC[]);; + +let MEASURABLE_CONIC_CAP = prove + (`!v0 v1:real^3 r a. measurable(conic_cap v0 v1 r a)`, + REPEAT GEN_TAC THEN REWRITE_TAC[conic_cap; NORMBALL_BALL] THEN + MATCH_MP_TAC MEASURABLE_OPEN THEN + SIMP_TAC[OPEN_INTER; OPEN_RCONE_GT; OPEN_BALL] THEN + MATCH_MP_TAC BOUNDED_SUBSET THEN EXISTS_TAC `ball(v0:real^3,r)` THEN + REWRITE_TAC[BOUNDED_BALL] THEN SET_TAC[]);; + +let VOLUME_CONIC_CAP_STRONG = prove + (`!v0 v1:real^3 r a. + &0 < a + ==> bounded(conic_cap v0 v1 r a) /\ + convex(conic_cap v0 v1 r a) /\ + measurable(conic_cap v0 v1 r a) /\ + measure(conic_cap v0 v1 r a) = + if v1 = v0 \/ &1 <= a \/ r < &0 then &0 + else &2 / &3 * pi * (&1 - a) * r pow 3`, + REPEAT GEN_TAC THEN DISCH_TAC THEN + REWRITE_TAC[conic_cap; rcone_gt; rconesgn; IN_ELIM_THM] THEN + REWRITE_TAC[ONCE_REWRITE_RULE[DIST_SYM] normball; GSYM ball] THEN + CONV_TAC(TOP_DEPTH_CONV let_CONV) THEN GEOM_ORIGIN_TAC `v0:real^3` THEN + REWRITE_TAC[VECTOR_SUB_RZERO; REAL_MUL_LZERO; DIST_0; real_gt] THEN + GEOM_BASIS_MULTIPLE_TAC 1 `v1:real^3` THEN + X_GEN_TAC `b:real` THEN REPEAT(GEN_TAC ORELSE DISCH_TAC) THEN + FIRST_ASSUM(DISJ_CASES_TAC o MATCH_MP (REAL_ARITH + `&0 <= x ==> x = &0 \/ &0 < x`)) + THENL + [ASM_REWRITE_TAC[VECTOR_MUL_LZERO; GSYM REAL_NOT_LE; DOT_RZERO] THEN + ASM_SIMP_TAC[REAL_LE_MUL; REAL_LT_IMP_LE; NORM_POS_LE] THEN + REWRITE_TAC[EMPTY_GSPEC; INTER_EMPTY; MEASURE_EMPTY; MEASURABLE_EMPTY; + CONVEX_EMPTY; BOUNDED_EMPTY]; + ALL_TAC] THEN + ASM_CASES_TAC `&1 <= a` THEN ASM_REWRITE_TAC[] THENL + [SUBGOAL_THEN + `!y:real^3. ~(norm(y) * norm(b % basis 1:real^3) * a + < y dot (b % basis 1))` + (fun th -> REWRITE_TAC[th; EMPTY_GSPEC; INTER_EMPTY; MEASURE_EMPTY; + MEASURABLE_EMPTY; BOUNDED_EMPTY; CONVEX_EMPTY]) THEN + REWRITE_TAC[REAL_NOT_LT] THEN X_GEN_TAC `y:real^3` THEN + MATCH_MP_TAC(REAL_ARITH `abs(x) <= a ==> x <= a`) THEN + SIMP_TAC[DOT_RMUL; NORM_MUL; REAL_ABS_MUL; DOT_BASIS; NORM_BASIS; + DIMINDEX_3; ARITH] THEN + REWRITE_TAC[REAL_ARITH + `b * y <= n * (b * &1) * a <=> b * &1 * y <= b * a * n`] THEN + MATCH_MP_TAC REAL_LE_LMUL THEN REWRITE_TAC[REAL_ABS_POS] THEN + MATCH_MP_TAC REAL_LE_MUL2 THEN + ASM_SIMP_TAC[REAL_POS; REAL_ABS_POS; COMPONENT_LE_NORM; DIMINDEX_3; ARITH]; + ALL_TAC] THEN + RULE_ASSUM_TAC(REWRITE_RULE[REAL_NOT_LE]) THEN + SIMP_TAC[DOT_RMUL; NORM_MUL; REAL_ABS_NORM; DOT_BASIS; + DIMINDEX_3; ARITH; NORM_BASIS] THEN + ONCE_REWRITE_TAC[REAL_ARITH `n * x * a:real = x * n * a`] THEN + ASM_REWRITE_TAC[real_abs; REAL_MUL_RID] THEN + ASM_SIMP_TAC[REAL_MUL_RID; REAL_LT_LMUL_EQ; REAL_LT_MUL_EQ; NORM_POS_LT] THEN + ASM_SIMP_TAC[GSYM REAL_LT_RDIV_EQ; NORM_LT_SQUARE] THEN + ASM_SIMP_TAC[REAL_POW_DIV; REAL_POW_LT; REAL_LT_RDIV_EQ] THEN + REWRITE_TAC[INTER; REAL_MUL_LZERO; IN_BALL_0; IN_ELIM_THM] THEN + ASM_SIMP_TAC[VECTOR_MUL_EQ_0; BASIS_NONZERO; DIMINDEX_3; ARITH; + REAL_LT_IMP_NZ] THEN + COND_CASES_TAC THENL + [ASM_SIMP_TAC[NORM_ARITH `r < &0 ==> ~(norm x < r)`] THEN + REWRITE_TAC[EMPTY_GSPEC; MEASURE_EMPTY; MEASURABLE_EMPTY; + BOUNDED_EMPTY; CONVEX_EMPTY]; + RULE_ASSUM_TAC(ONCE_REWRITE_RULE[REAL_NOT_LT])] THEN + MATCH_MP_TAC(TAUT `a /\ b /\ (a /\ b ==> c /\ d) ==> a /\ b /\ c /\ d`) THEN + REPEAT CONJ_TAC THENL + [MATCH_MP_TAC BOUNDED_SUBSET THEN + EXISTS_TAC `ball(vec 0:real^3,r)` THEN + SIMP_TAC[BOUNDED_BALL; IN_BALL_0; SUBSET; IN_ELIM_THM]; + ONCE_REWRITE_TAC[SET_RULE + `{x | P x /\ Q x} = {x | P x} INTER {x | Q x}`] THEN + MATCH_MP_TAC CONVEX_INTER THEN + REWRITE_TAC[GSYM IN_BALL_0; CONVEX_BALL; SIMPLE_IMAGE; IMAGE_ID] THEN + MP_TAC(ISPECL [`vec 0:real^3`; `basis 1:real^3`; `a:real`] + CONVEX_RCONE_GT) THEN + ASM_SIMP_TAC[REAL_LT_IMP_LE; rcone_gt; rconesgn] THEN + REWRITE_TAC[VECTOR_SUB_RZERO; DIST_0] THEN + SIMP_TAC[DOT_BASIS; NORM_BASIS; DIMINDEX_3; ARITH] THEN + REWRITE_TAC[real_gt; REAL_MUL_LID] THEN + ASM_SIMP_TAC[GSYM REAL_LT_RDIV_EQ] THEN + REWRITE_TAC[NORM_LT_SQUARE] THEN + ASM_SIMP_TAC[REAL_POW_DIV; REAL_LT_RDIV_EQ; REAL_POW_LT] THEN + REWRITE_TAC[REAL_MUL_LZERO]; + STRIP_TAC] THEN + MATCH_MP_TAC(INST_TYPE [`:2`,`:M`] FUBINI_SIMPLE_CONVEX_STRONG) THEN + EXISTS_TAC `1` THEN ASM_REWRITE_TAC[DIMINDEX_2; DIMINDEX_3; ARITH] THEN + SIMP_TAC[SLICE_312; DIMINDEX_2; DIMINDEX_3; ARITH; IN_ELIM_THM; + VECTOR_3; DOT_3; GSYM DOT_2] THEN + SUBGOAL_THEN `&0 < inv(a pow 2) - &1` ASSUME_TAC THENL + [REWRITE_TAC[REAL_SUB_LT] THEN MATCH_MP_TAC REAL_INV_1_LT THEN + ASM_SIMP_TAC[REAL_POW_1_LT; REAL_LT_IMP_LE; ARITH; REAL_POW_LT]; + ALL_TAC] THEN + MATCH_MP_TAC HAS_REAL_INTEGRAL_EQ THEN + EXISTS_TAC `\t. if &0 < t /\ t < r + then measure + {y:real^2 | norm(vector[t; y$1; y$2]:real^3) pow 2 + < r pow 2 /\ + (t * t + y dot y) * a pow 2 < t pow 2} + else &0` THEN + CONJ_TAC THENL + [X_GEN_TAC `t:real` THEN DISCH_TAC THEN REWRITE_TAC[] THEN + ASM_CASES_TAC `&0 < t` THEN + ASM_REWRITE_TAC[EMPTY_GSPEC; MEASURE_EMPTY; MEASURABLE_EMPTY] THEN + ASM_CASES_TAC `t:real < r` THEN ASM_REWRITE_TAC[] THENL + [REWRITE_TAC[NORM_LT_SQUARE] THEN + SUBGOAL_THEN `&0 < r` (fun th -> REWRITE_TAC[th; NORM_POW_2]) THEN + ASM_REAL_ARITH_TAC; + ALL_TAC] THEN + SUBGOAL_THEN `!y. ~(norm(vector[t; (y:real^2)$1; y$2]:real^3) < r)` + (fun th -> REWRITE_TAC[th; EMPTY_GSPEC; MEASURE_EMPTY; + MEASURABLE_EMPTY]) THEN + ASM_REWRITE_TAC[NORM_LT_SQUARE; DOT_3; VECTOR_3] THEN + GEN_TAC THEN + MATCH_MP_TAC(REAL_ARITH `&0 <= a /\ &0 <= b /\ c <= d + ==> ~(&0 < r /\ d + a + b < c)`) THEN + REWRITE_TAC[REAL_LE_SQUARE] THEN + REWRITE_TAC[REAL_POW_2] THEN MATCH_MP_TAC REAL_LE_MUL2 THEN + ASM_REAL_ARITH_TAC; + ALL_TAC] THEN + REWRITE_TAC[GSYM IN_REAL_INTERVAL; HAS_REAL_INTEGRAL_RESTRICT_UNIV] THEN + REWRITE_TAC[HAS_REAL_INTEGRAL_OPEN_INTERVAL] THEN + REWRITE_TAC[NORM_POW_2; DOT_3; VECTOR_3; DOT_2] THEN + ONCE_REWRITE_TAC[REAL_ARITH + `pi * &2 / &3 * (&1 - a) * r pow 3 = + pi / &3 * (inv (a pow 2) - &1) * (a * r) pow 3 + + (pi * &2 / &3 * (&1 - a) * r pow 3 - + pi / &3 * (inv (a pow 2) - &1) * (a * r) pow 3)`] THEN + MATCH_MP_TAC HAS_REAL_INTEGRAL_COMBINE THEN + EXISTS_TAC `a * r:real` THEN + REWRITE_TAC[REAL_ARITH `a * r <= r <=> &0 <= r * (&1 - a)`] THEN + ASM_SIMP_TAC[REAL_LE_MUL; REAL_SUB_LE; REAL_LT_IMP_LE] THEN CONJ_TAC THENL + [MATCH_MP_TAC HAS_REAL_INTEGRAL_EQ THEN EXISTS_TAC + `\t. measure(ball(vec 0:real^2,sqrt(inv(a pow 2) - &1) * t))` THEN + CONJ_TAC THENL + [X_GEN_TAC `t:real` THEN REWRITE_TAC[IN_REAL_INTERVAL] THEN + STRIP_TAC THEN AP_TERM_TAC THEN REWRITE_TAC[EXTENSION; IN_ELIM_THM] THEN + REWRITE_TAC[IN_BALL_0; NORM_LT_SQUARE_ALT] THEN + ASM_SIMP_TAC[SQRT_POS_LE; REAL_LE_MUL; SQRT_POW_2; REAL_LT_IMP_LE; + REAL_POW_MUL] THEN + REWRITE_TAC[REAL_ARITH `x < (a - &1) * t <=> t + x < t * a`] THEN + ASM_SIMP_TAC[GSYM real_div; REAL_LT_RDIV_EQ; REAL_POW_LT] THEN + X_GEN_TAC `x:real^2` THEN REWRITE_TAC[DOT_2] THEN + ASM_SIMP_TAC[GSYM REAL_POW_2; GSYM REAL_LT_RDIV_EQ; REAL_POW_LT] THEN + MATCH_MP_TAC(REAL_ARITH `b <= a ==> (x < b <=> x < a /\ x < b)`) THEN + ASM_SIMP_TAC[REAL_LE_LDIV_EQ; REAL_POW_LT; GSYM REAL_POW_MUL] THEN + ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN + REWRITE_TAC[GSYM REAL_LE_SQUARE_ABS] THEN ASM_REAL_ARITH_TAC; + ALL_TAC] THEN + MATCH_MP_TAC HAS_REAL_INTEGRAL_EQ THEN + EXISTS_TAC `\t. pi * (inv(a pow 2) - &1) * t pow 2` THEN + CONJ_TAC THENL + [X_GEN_TAC `t:real` THEN REWRITE_TAC[IN_REAL_INTERVAL] THEN + STRIP_TAC THEN + W(MP_TAC o PART_MATCH (lhs o rand) AREA_BALL o rand o snd) THEN + ASM_SIMP_TAC[REAL_POW_MUL; REAL_LT_IMP_LE; SQRT_POS_LT; REAL_LE_MUL; + SQRT_POW_2]; + ALL_TAC] THEN + MP_TAC(ISPECL + [`\t. pi / &3 * (inv (a pow 2) - &1) * t pow 3`; + `\t. pi * (inv (a pow 2) - &1) * t pow 2`; + `&0`; `a * r:real`] REAL_FUNDAMENTAL_THEOREM_OF_CALCULUS) THEN + ASM_SIMP_TAC[REAL_LE_MUL; REAL_LT_IMP_LE] THEN ANTS_TAC THENL + [ASM_REWRITE_TAC[] THEN + REPEAT STRIP_TAC THEN REAL_DIFF_TAC THEN + CONV_TAC NUM_REDUCE_CONV THEN CONV_TAC REAL_RING; + MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_TERM_TAC THEN + UNDISCH_TAC `&0 < a` THEN CONV_TAC REAL_FIELD]; + MATCH_MP_TAC HAS_REAL_INTEGRAL_EQ THEN EXISTS_TAC + `\t. measure(ball(vec 0:real^2,sqrt(r pow 2 - t pow 2)))` THEN + CONJ_TAC THENL + [X_GEN_TAC `t:real` THEN REWRITE_TAC[IN_REAL_INTERVAL] THEN + STRIP_TAC THEN AP_TERM_TAC THEN REWRITE_TAC[EXTENSION; IN_ELIM_THM] THEN + REWRITE_TAC[IN_BALL_0; NORM_LT_SQUARE_ALT] THEN + SUBGOAL_THEN `&0 <= t` ASSUME_TAC THENL + [MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC `a * r:real` THEN + ASM_SIMP_TAC[REAL_LE_MUL; REAL_LT_IMP_LE]; + ALL_TAC] THEN + ASM_SIMP_TAC[SQRT_POS_LE; SQRT_POW_2; REAL_SUB_LE; REAL_POW_LE2] THEN + X_GEN_TAC `x:real^2` THEN REWRITE_TAC[DOT_2] THEN + REWRITE_TAC[REAL_ARITH `x < r - t <=> t + x < r`] THEN + ASM_SIMP_TAC[GSYM REAL_POW_2; GSYM REAL_LT_RDIV_EQ; REAL_POW_LT] THEN + MATCH_MP_TAC(REAL_ARITH `a <= b ==> (x < a <=> x < a /\ x < b)`) THEN + ASM_SIMP_TAC[REAL_LE_RDIV_EQ; REAL_POW_LT; GSYM REAL_POW_MUL] THEN + ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN + ASM_SIMP_TAC[REAL_POW_LE2; REAL_LE_MUL; REAL_LT_IMP_LE]; + ALL_TAC] THEN + MATCH_MP_TAC HAS_REAL_INTEGRAL_EQ THEN + EXISTS_TAC `\t. pi * (r pow 2 - t pow 2)` THEN + CONJ_TAC THENL + [X_GEN_TAC `t:real` THEN REWRITE_TAC[IN_REAL_INTERVAL] THEN + STRIP_TAC THEN + W(MP_TAC o PART_MATCH (lhs o rand) AREA_BALL o rand o snd) THEN + SUBGOAL_THEN `&0 <= t` ASSUME_TAC THENL + [MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC `a * r:real` THEN + ASM_SIMP_TAC[REAL_LE_MUL; REAL_LT_IMP_LE]; + ALL_TAC] THEN + ASM_SIMP_TAC[SQRT_POS_LE; SQRT_POW_2; REAL_SUB_LE; REAL_POW_LE2]; + ALL_TAC] THEN + MP_TAC(ISPECL + [`\t. pi * (r pow 2 * t - t pow 3 / &3)`; + `\t. pi * (r pow 2 - t pow 2)`; + `a * r:real`; `r:real`] REAL_FUNDAMENTAL_THEOREM_OF_CALCULUS) THEN + ASM_SIMP_TAC[REAL_LE_MUL; REAL_LT_IMP_LE] THEN ANTS_TAC THENL + [ASM_REWRITE_TAC[REAL_ARITH `a * r <= r <=> &0 <= r * (&1 - a)`] THEN + ASM_SIMP_TAC[REAL_LE_MUL; REAL_LT_IMP_LE; REAL_SUB_LE] THEN + REPEAT STRIP_TAC THEN REAL_DIFF_TAC THEN + CONV_TAC NUM_REDUCE_CONV THEN CONV_TAC REAL_RING; + MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_TERM_TAC THEN + UNDISCH_TAC `&0 < a` THEN CONV_TAC REAL_FIELD]]);; + +let VOLUME_CONIC_CAP = prove + (`!v0 v1:real^3 r a. + &0 < a + ==> measurable(conic_cap v0 v1 r a) /\ measure(conic_cap v0 v1 r a) = + if v1 = v0 \/ &1 <= a \/ r < &0 then &0 + else &2 / &3 * pi * (&1 - a) * r pow 3`, + SIMP_TAC[VOLUME_CONIC_CAP_STRONG]);; + +(* ------------------------------------------------------------------------- *) +(* Negligibility of a circular cone. *) +(* This isn't exactly using the Flyspeck definition of "cone" but we use it *) +(* to get that later on. Could now simplify this using WLOG tactics. *) +(* ------------------------------------------------------------------------- *) + +let NEGLIGIBLE_CIRCULAR_CONE_0_NONPARALLEL = prove + (`!c:real^N k. ~(c = vec 0) /\ ~(k = &0) /\ ~(k = pi) + ==> negligible {x | vector_angle c x = k}`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC NEGLIGIBLE_SUBSET THEN + EXISTS_TAC `(vec 0:real^N) INSERT + UNIONS { {x | x IN ((:real^N) DIFF ball(vec 0,inv(&n + &1))) /\ + Cx(vector_angle c x) = Cx k} | + n IN (:num) }` THEN + CONJ_TAC THENL + [ALL_TAC; + REWRITE_TAC[SUBSET; IN_INSERT; IN_UNIONS; IN_ELIM_THM; CX_INJ] THEN + X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN REWRITE_TAC[IN_UNIV] THEN + ASM_CASES_TAC `x:real^N = vec 0` THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[LEFT_AND_EXISTS_THM; IN_DIFF; IN_UNIV] THEN + ONCE_REWRITE_TAC[SWAP_EXISTS_THM] THEN REWRITE_TAC[UNWIND_THM2] THEN + ASM_REWRITE_TAC[IN_ELIM_THM] THEN + MP_TAC(SPEC `norm(x:real^N)` REAL_ARCH_INV) THEN + ASM_REWRITE_TAC[NORM_POS_LT; IN_BALL_0; REAL_NOT_LT; REAL_LT_INV_EQ] THEN + MATCH_MP_TAC MONO_EXISTS THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC `inv(&n)` THEN + ASM_SIMP_TAC[REAL_LT_IMP_LE] THEN MATCH_MP_TAC REAL_LE_INV2 THEN + ASM_REAL_ARITH_TAC] THEN + REWRITE_TAC[NEGLIGIBLE_INSERT] THEN + MATCH_MP_TAC NEGLIGIBLE_COUNTABLE_UNIONS THEN X_GEN_TAC `n:num` THEN + MATCH_MP_TAC STARLIKE_NEGLIGIBLE_STRONG THEN EXISTS_TAC `c:real^N` THEN + CONJ_TAC THENL + [MATCH_MP_TAC CONTINUOUS_CLOSED_PREIMAGE_CONSTANT THEN + SIMP_TAC[CLOSED_DIFF; CLOSED_UNIV; OPEN_BALL] THEN + MATCH_MP_TAC(REWRITE_RULE[o_DEF] CONTINUOUS_ON_CX_VECTOR_ANGLE) THEN + REWRITE_TAC[IN_DIFF; IN_BALL_0; NORM_0; IN_UNIV] THEN + REWRITE_TAC[REAL_LT_INV_EQ] THEN REAL_ARITH_TAC; + ALL_TAC] THEN + MAP_EVERY X_GEN_TAC [`a:real`; `x:real^N`] THEN + SIMP_TAC[IN_ELIM_THM; IN_UNIV; IN_DIFF; IN_BALL_0; REAL_NOT_LT; CX_INJ] THEN + REWRITE_TAC[DE_MORGAN_THM] THEN ASM_CASES_TAC `(c + x:real^N) = vec 0` THENL + [ASM_REWRITE_TAC[GSYM REAL_NOT_LT; REAL_LT_INV_EQ; NORM_0] THEN + REAL_ARITH_TAC; + ALL_TAC] THEN + ASM_CASES_TAC `c + a % x:real^N = vec 0` THENL + [ASM_REWRITE_TAC[GSYM REAL_NOT_LT; REAL_LT_INV_EQ; NORM_0] THEN + REAL_ARITH_TAC; + ALL_TAC] THEN + ASM_CASES_TAC `x:real^N = vec 0` THENL + [ASM_REWRITE_TAC[VECTOR_ADD_RID; VECTOR_ANGLE_REFL]; + ALL_TAC] THEN + ASM_CASES_TAC `a = &0` THENL + [ASM_REWRITE_TAC[VECTOR_MUL_LZERO; VECTOR_ADD_RID; VECTOR_ANGLE_REFL]; + ALL_TAC] THEN + REWRITE_TAC[TAUT `~a \/ ~b <=> a ==> ~b`] THEN REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`vec 0:real^N`; `c:real^N`; `c + a % x:real^N`; + `vec 0:real^N`; `c:real^N`; `c + x:real^N`] + CONGRUENT_TRIANGLES_ASA_FULL) THEN + REWRITE_TAC[angle; VECTOR_ADD_SUB] THEN ASM_SIMP_TAC[VECTOR_SUB_RZERO] THEN + REWRITE_TAC[NORM_ARITH `dist(x,x + a) = norm(a)`; NORM_MUL] THEN + REWRITE_TAC[REAL_FIELD `a * x = x <=> a = &1 \/ x = &0`] THEN + ASM_SIMP_TAC[REAL_ARITH `&0 <= a /\ a < &1 ==> ~(abs a = &1)`] THEN + ASM_REWRITE_TAC[NORM_EQ_0; VECTOR_ANGLE_RMUL; COLLINEAR_LEMMA] THEN + DISCH_THEN(X_CHOOSE_THEN `u:real` MP_TAC) THEN + DISCH_THEN(MP_TAC o AP_TERM `\x:real^N. inv(a) % x`) THEN + ASM_SIMP_TAC[VECTOR_MUL_ASSOC; VECTOR_ADD_LDISTRIB; + VECTOR_MUL_LID; REAL_MUL_LINV] THEN + REWRITE_TAC[VECTOR_ARITH `a % c + x = b % c <=> x = (b - a) % c`] THEN + DISCH_THEN SUBST_ALL_TAC THEN + RULE_ASSUM_TAC(REWRITE_RULE[VECTOR_ARITH `c + a % c = (a + &1) % c`]) THEN + UNDISCH_TAC `vector_angle c ((inv a * u - inv a + &1) % c:real^N) = k` THEN + RULE_ASSUM_TAC(REWRITE_RULE + [VECTOR_ANGLE_RMUL; VECTOR_MUL_EQ_0; DE_MORGAN_THM]) THEN + ASM_REWRITE_TAC[VECTOR_ANGLE_RMUL; VECTOR_ANGLE_REFL] THEN + ASM_REAL_ARITH_TAC);; + +let NEGLIGIBLE_CIRCULAR_CONE_0 = prove + (`!c:real^N k. 2 <= dimindex(:N) /\ ~(c = vec 0) + ==> negligible {x | vector_angle c x = k}`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN `orthogonal (basis 1:real^N) (basis 2)` ASSUME_TAC THENL + [ASM_SIMP_TAC[ORTHOGONAL_BASIS_BASIS; ARITH; + ARITH_RULE `2 <= d ==> 1 <= d`]; + ALL_TAC] THEN + ASM_CASES_TAC `k = &0 \/ k = pi` THENL + [ALL_TAC; ASM_MESON_TAC[NEGLIGIBLE_CIRCULAR_CONE_0_NONPARALLEL]] THEN + SUBGOAL_THEN + `?b:real^N. ~(b = vec 0) /\ + ~(vector_angle c b = &0) /\ + ~(vector_angle c b = pi)` + STRIP_ASSUME_TAC THENL + [MATCH_MP_TAC(MESON[] `!a b. P a \/ P b ==> ?x. P x`) THEN + MAP_EVERY EXISTS_TAC [`basis 1:real^N`; `basis 2:real^N`] THEN + REWRITE_TAC[BASIS_EQ_0] THEN + ASM_SIMP_TAC[ARITH_RULE `2 <= d ==> 1 <= d`; IN_NUMSEG; ARITH] THEN + REWRITE_TAC[GSYM DE_MORGAN_THM] THEN STRIP_TAC THEN + REPEAT(FIRST_X_ASSUM(MP_TAC o SPEC `basis 1:real^N` o + MATCH_MP VECTOR_ANGLE_EQ_0_LEFT)) THEN + REPEAT(FIRST_X_ASSUM(MP_TAC o SPEC `basis 1:real^N` o + MATCH_MP VECTOR_ANGLE_EQ_PI_LEFT)) THEN + DISCH_THEN SUBST1_TAC THEN REWRITE_TAC[VECTOR_ANGLE_REFL; BASIS_EQ_0] THEN + ASM_SIMP_TAC[ARITH_RULE `2 <= d ==> 1 <= d`; IN_NUMSEG; ARITH] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [ORTHOGONAL_VECTOR_ANGLE]) THEN + REWRITE_TAC[VECTOR_ANGLE_SYM] THEN MP_TAC PI_POS THEN REAL_ARITH_TAC; + ALL_TAC] THEN + ASM_CASES_TAC `k = &0 \/ k = pi` THENL + [ALL_TAC; ASM_MESON_TAC[NEGLIGIBLE_CIRCULAR_CONE_0_NONPARALLEL]] THEN + MATCH_MP_TAC NEGLIGIBLE_SUBSET THEN + FIRST_X_ASSUM(DISJ_CASES_THEN SUBST_ALL_TAC) THENL + [EXISTS_TAC `{x:real^N | vector_angle b x = vector_angle c b}` THEN + ASM_SIMP_TAC[NEGLIGIBLE_CIRCULAR_CONE_0_NONPARALLEL] THEN + REWRITE_TAC[SUBSET; IN_ELIM_THM] THEN + MESON_TAC[VECTOR_ANGLE_EQ_0_RIGHT; VECTOR_ANGLE_SYM]; + EXISTS_TAC `{x:real^N | vector_angle b x = pi - vector_angle c b}` THEN + ASM_SIMP_TAC[NEGLIGIBLE_CIRCULAR_CONE_0_NONPARALLEL; + REAL_SUB_0; REAL_ARITH `p - x = p <=> x = &0`] THEN + REWRITE_TAC[SUBSET; IN_ELIM_THM] THEN + MESON_TAC[VECTOR_ANGLE_EQ_PI_RIGHT; VECTOR_ANGLE_SYM]]);; + +let NEGLIGIBLE_CIRCULAR_CONE = prove + (`!a:real^N c k. + 2 <= dimindex(:N) /\ ~(c = vec 0) + ==> negligible(a INSERT {x | vector_angle c (x - a) = k})`, + REPEAT STRIP_TAC THEN REWRITE_TAC[NEGLIGIBLE_INSERT] THEN + MATCH_MP_TAC NEGLIGIBLE_TRANSLATION_REV THEN EXISTS_TAC `--a:real^N` THEN + MATCH_MP_TAC NEGLIGIBLE_SUBSET THEN + EXISTS_TAC `{x:real^N | vector_angle c x = k}` THEN + ASM_SIMP_TAC[NEGLIGIBLE_CIRCULAR_CONE_0] THEN + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; IN_ELIM_THM] THEN + REWRITE_TAC[VECTOR_ARITH `--a + x:real^N = x - a`]);; + +let NEGLIGIBLE_RCONE_EQ = prove + (`!w z:real^3 h. ~(w = z) ==> negligible(rcone_eq z w h)`, + REWRITE_TAC[rcone_eq; rconesgn] THEN GEOM_ORIGIN_TAC `z:real^3` THEN + REPEAT STRIP_TAC THEN REWRITE_TAC[DIST_0; VECTOR_SUB_RZERO] THEN + ASM_CASES_TAC `abs(h) <= &1` THENL + [MP_TAC(ISPECL [`w:real^3`; `acs h`] NEGLIGIBLE_CIRCULAR_CONE_0) THEN + ASM_REWRITE_TAC[DIMINDEX_3; ARITH] THEN + REWRITE_TAC[GSYM HAS_MEASURE_0] THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] + HAS_MEASURE_NEGLIGIBLE_SYMDIFF) THEN + MATCH_MP_TAC NEGLIGIBLE_SUBSET THEN EXISTS_TAC `{vec 0:real^3}` THEN + REWRITE_TAC[NEGLIGIBLE_SING] THEN MATCH_MP_TAC(SET_RULE + `(!x. ~(x = a) ==> (x IN s <=> x IN t)) + ==> (s DIFF t) UNION (t DIFF s) SUBSET {a}`) THEN + X_GEN_TAC `x:real^3` THEN DISCH_TAC THEN REWRITE_TAC[IN_ELIM_THM] THEN + ASM_SIMP_TAC[vector_angle] THEN ASM_SIMP_TAC[NORM_EQ_0; REAL_FIELD + `~(x = &0) /\ ~(w = &0) ==> (a = x * w * b <=> a / (w * x) = b)`] THEN + GEN_REWRITE_TAC (RAND_CONV o ONCE_DEPTH_CONV) [DOT_SYM] THEN + MATCH_MP_TAC ACS_INJ THEN ASM_REWRITE_TAC[NORM_CAUCHY_SCHWARZ_DIV]; + MATCH_MP_TAC NEGLIGIBLE_SUBSET THEN + EXISTS_TAC `{vec 0}:real^3->bool` THEN + REWRITE_TAC[NEGLIGIBLE_SING] THEN + REWRITE_TAC[SET_RULE `{x | P x} SUBSET {a} <=> !x. ~(x = a) ==> ~P x`] THEN + X_GEN_TAC `x:real^3` THEN REPEAT DISCH_TAC THEN + MP_TAC(ISPECL [`x:real^3`; `w:real^3`] NORM_CAUCHY_SCHWARZ_ABS) THEN + ASM_REWRITE_TAC[REAL_ABS_MUL; REAL_ABS_NORM; REAL_ARITH + `~(x * w * h <= x * w) <=> &0 < x * w * (h - &1)`] THEN + REPEAT(MATCH_MP_TAC REAL_LT_MUL THEN ASM_REWRITE_TAC[NORM_POS_LT]) THEN + ASM_REAL_ARITH_TAC]);; + +(* ------------------------------------------------------------------------- *) +(* Area of sector of a circle delimited by Arg values. *) +(* ------------------------------------------------------------------------- *) + +let NEGLIGIBLE_ARG_EQ = prove + (`!t. negligible {z | Arg z = t}`, + GEN_TAC THEN MATCH_MP_TAC NEGLIGIBLE_SUBSET THEN + EXISTS_TAC `{z | cexp(ii * Cx(pi / &2 + t)) dot z = &0}` THEN + SIMP_TAC[NEGLIGIBLE_HYPERPLANE; COMPLEX_VEC_0; CEXP_NZ] THEN + REWRITE_TAC[SUBSET; IN_ELIM_THM] THEN X_GEN_TAC `z:complex` THEN + DISCH_TAC THEN MP_TAC(SPEC `z:complex` ARG) THEN ASM_REWRITE_TAC[] THEN + REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + DISCH_THEN SUBST1_TAC THEN + REWRITE_TAC[GSYM COMPLEX_CMUL; DOT_RMUL; REAL_ENTIRE] THEN + DISJ2_TAC THEN REWRITE_TAC[CEXP_EULER] THEN + REWRITE_TAC[DOT_2; GSYM RE_DEF; GSYM IM_DEF] THEN + REWRITE_TAC[GSYM CX_SIN; GSYM CX_COS; RE_ADD; IM_ADD; + RE_MUL_II; IM_MUL_II; RE_CX; IM_CX] THEN + REWRITE_TAC[SIN_ADD; COS_ADD; SIN_PI2; COS_PI2] THEN + REAL_ARITH_TAC);; + +let MEASURABLE_CLOSED_SECTOR_LE = prove + (`!r t. measurable {z | norm(z) <= r /\ Arg z <= t}`, + REPEAT GEN_TAC THEN MATCH_MP_TAC MEASURABLE_COMPACT THEN + REWRITE_TAC[SET_RULE `{z | P z /\ Q z} = {z | P z} INTER {z | Q z}`] THEN + MATCH_MP_TAC COMPACT_INTER_CLOSED THEN REWRITE_TAC[CLOSED_ARG_LE] THEN + REWRITE_TAC[NORM_ARITH `norm z = dist(vec 0,z)`; GSYM cball] THEN + REWRITE_TAC[COMPACT_CBALL]);; + +let MEASURABLE_CLOSED_SECTOR_LT = prove + (`!r t. measurable {z | norm(z) <= r /\ Arg z < t}`, + REPEAT GEN_TAC THEN MATCH_MP_TAC MEASURABLE_NEGLIGIBLE_SYMDIFF THEN + EXISTS_TAC `{z | norm(z) <= r /\ Arg z <= t}` THEN + REWRITE_TAC[MEASURABLE_CLOSED_SECTOR_LE] THEN + MATCH_MP_TAC NEGLIGIBLE_SUBSET THEN + EXISTS_TAC `{z | Arg z = t}` THEN + REWRITE_TAC[NEGLIGIBLE_ARG_EQ; NEGLIGIBLE_UNION_EQ] THEN + REWRITE_TAC[SUBSET; IN_DIFF; IN_UNION; IN_ELIM_THM] THEN REAL_ARITH_TAC);; + +let MEASURABLE_CLOSED_SECTOR_LTE = prove + (`!r s t. measurable {z | norm(z) <= r /\ s < Arg z /\ Arg z <= t}`, + REPEAT GEN_TAC THEN REWRITE_TAC[SET_RULE + `{z | P z /\ Q z /\ R z} = {z | P z /\ R z} DIFF {z | P z /\ ~Q z}`] THEN + SIMP_TAC[MEASURABLE_DIFF; REAL_NOT_LT; MEASURABLE_CLOSED_SECTOR_LE]);; + +let MEASURE_CLOSED_SECTOR_LE = prove + (`!t r. &0 <= r /\ &0 <= t /\ t <= &2 * pi + ==> measure {x:real^2 | norm(x) <= r /\ Arg(x) <= t} = + t * r pow 2 / &2`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL + [`\t. measure {z:real^2 | norm(z) <= r /\ Arg(z) <= t}`; + `&2 * pi`] REAL_CONTINUOUS_ADDITIVE_IMP_LINEAR_INTERVAL) THEN + ANTS_TAC THENL + [ALL_TAC; + DISCH_THEN(MP_TAC o SPECL [`t / (&2 * pi)`; `&2 * pi`]) THEN + MP_TAC(SPECL [`vec 0:real^2`; `r:real`] AREA_CBALL) THEN + ASM_REWRITE_TAC[cball; NORM_ARITH `dist(vec 0,z) = norm z`] THEN + SIMP_TAC[ARG; REAL_LT_IMP_LE] THEN DISCH_THEN(K ALL_TAC) THEN + SIMP_TAC[PI_POS; REAL_FIELD `&0 < p ==> t / (&2 * p) * p * r = t * r / &2`; + REAL_FIELD `&0 < p ==> t / (&2 * p) * &2 * p = t`] THEN + DISCH_THEN MATCH_MP_TAC THEN MP_TAC PI_POS THEN ASM_REAL_ARITH_TAC] THEN + REWRITE_TAC[] THEN REPEAT STRIP_TAC THENL + [MATCH_MP_TAC REALLIM_TRANSFORM_BOUND THEN + EXISTS_TAC `\t. r pow 2 * sin(t)` THEN REWRITE_TAC[] THEN CONJ_TAC THENL + [REWRITE_TAC[EVENTUALLY_WITHINREAL] THEN EXISTS_TAC `pi / &2` THEN + SIMP_TAC[PI_POS; REAL_LT_DIV; IN_ELIM_THM; REAL_OF_NUM_LT; ARITH] THEN + X_GEN_TAC `x:real` THEN REWRITE_TAC[REAL_SUB_RZERO] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + ASM_SIMP_TAC[real_abs; MEASURE_POS_LE; MEASURABLE_CLOSED_SECTOR_LE] THEN + STRIP_TAC THEN MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `measure(interval[vec 0,complex(r,r * sin x)])` THEN + CONJ_TAC THENL + [MATCH_MP_TAC MEASURE_SUBSET THEN + REWRITE_TAC[MEASURABLE_CLOSED_SECTOR_LE; MEASURABLE_INTERVAL] THEN + REWRITE_TAC[SUBSET; IN_ELIM_THM; IN_INTERVAL] THEN + X_GEN_TAC `z:complex` THEN STRIP_TAC THEN + REWRITE_TAC[DIMINDEX_2; FORALL_2; VEC_COMPONENT] THEN + REWRITE_TAC[GSYM IM_DEF; GSYM RE_DEF; IM; RE] THEN + SUBST1_TAC(last(CONJUNCTS(SPEC `z:complex` ARG))) THEN + REWRITE_TAC[RE_MUL_CX; IM_MUL_CX; CEXP_EULER] THEN + REWRITE_TAC[RE_ADD; GSYM CX_COS; GSYM CX_SIN; RE_CX; IM_CX; + RE_MUL_II; IM_MUL_II; IM_ADD] THEN + REWRITE_TAC[REAL_NEG_0; REAL_ADD_LID; REAL_ADD_RID] THEN + SUBGOAL_THEN `&0 <= Arg z /\ Arg z < pi / &2 /\ Arg z <= pi / &2` + STRIP_ASSUME_TAC THENL + [REWRITE_TAC[ARG] THEN ASM_REAL_ARITH_TAC; ALL_TAC] THEN + REPEAT CONJ_TAC THENL + [MATCH_MP_TAC REAL_LE_MUL THEN REWRITE_TAC[NORM_POS_LE] THEN + MATCH_MP_TAC COS_POS_PI_LE THEN ASM_REAL_ARITH_TAC; + MATCH_MP_TAC(REAL_ARITH `abs(a * b) <= c * &1 ==> a * b <= c`) THEN + REWRITE_TAC[REAL_ABS_MUL; REAL_ABS_NORM] THEN + MATCH_MP_TAC REAL_LE_MUL2 THEN + ASM_REWRITE_TAC[NORM_POS_LE; REAL_ABS_POS; COS_BOUND]; + MATCH_MP_TAC REAL_LE_MUL THEN REWRITE_TAC[NORM_POS_LE] THEN + MATCH_MP_TAC SIN_POS_PI_LE THEN ASM_REAL_ARITH_TAC; + MATCH_MP_TAC REAL_LE_MUL2 THEN ASM_REWRITE_TAC[NORM_POS_LE] THEN + CONJ_TAC THENL + [MATCH_MP_TAC SIN_POS_PI_LE THEN ASM_REAL_ARITH_TAC; + MATCH_MP_TAC SIN_MONO_LE THEN ASM_REAL_ARITH_TAC]]; + REWRITE_TAC[MEASURE_INTERVAL; CONTENT_CLOSED_INTERVAL_CASES] THEN + REWRITE_TAC[FORALL_2; PRODUCT_2; DIMINDEX_2; VEC_COMPONENT] THEN + REWRITE_TAC[GSYM IM_DEF; GSYM RE_DEF; IM; RE] THEN + REWRITE_TAC[REAL_SUB_RZERO; REAL_POW_2; REAL_MUL_ASSOC] THEN + SUBGOAL_THEN `&0 <= sin x` (fun th -> + ASM_SIMP_TAC[REAL_LE_MUL; REAL_LE_REFL; REAL_LE_MUL; th]) THEN + MATCH_MP_TAC SIN_POS_PI_LE THEN ASM_REAL_ARITH_TAC]; + MATCH_MP_TAC REALLIM_ATREAL_WITHINREAL THEN + SUBGOAL_THEN `(\t. r pow 2 * sin t) real_continuous atreal (&0)` + MP_TAC THENL + [MATCH_MP_TAC REAL_CONTINUOUS_LMUL THEN + REWRITE_TAC[ETA_AX; REAL_CONTINUOUS_AT_SIN]; + REWRITE_TAC[REAL_CONTINUOUS_ATREAL; SIN_0; REAL_MUL_RZERO]]]; + ASM_SIMP_TAC[REAL_ARITH + `&0 <= x /\ &0 <= y + ==> (norm z <= r /\ Arg z <= x + y <=> + norm z <= r /\ Arg z <= x \/ + norm z <= r /\ x < Arg z /\ Arg z <= x + y)`] THEN + REWRITE_TAC[SET_RULE `{z | Q z \/ R z} = {z | Q z} UNION {z | R z}`] THEN + SIMP_TAC[MEASURE_UNION; MEASURABLE_CLOSED_SECTOR_LE; + MEASURABLE_CLOSED_SECTOR_LTE] THEN + REWRITE_TAC[GSYM REAL_NOT_LE; SET_RULE + `{z | P z /\ Q z} INTER {z | P z /\ ~Q z /\ R z} = {}`] THEN + REWRITE_TAC[MEASURE_EMPTY; REAL_SUB_RZERO; REAL_EQ_ADD_LCANCEL] THEN + REWRITE_TAC[REAL_NOT_LE] THEN MATCH_MP_TAC EQ_TRANS THEN + EXISTS_TAC `measure {z | norm z <= r /\ x < Arg z /\ Arg z < x + y}` THEN + CONJ_TAC THENL + [MATCH_MP_TAC MEASURE_NEGLIGIBLE_SYMDIFF THEN + REWRITE_TAC[MEASURABLE_CLOSED_SECTOR_LTE] THEN + MATCH_MP_TAC NEGLIGIBLE_SUBSET THEN + EXISTS_TAC `{z | Arg z = x + y}` THEN + REWRITE_TAC[NEGLIGIBLE_ARG_EQ; NEGLIGIBLE_UNION_EQ] THEN + REWRITE_TAC[SUBSET; IN_DIFF; IN_UNION; IN_ELIM_THM] THEN REAL_ARITH_TAC; + ALL_TAC] THEN + MATCH_MP_TAC EQ_TRANS THEN + EXISTS_TAC `measure {z | norm z <= r /\ &0 < Arg z /\ Arg z < y}` THEN + CONJ_TAC THENL + [ALL_TAC; + MATCH_MP_TAC MEASURE_NEGLIGIBLE_SYMDIFF THEN + REWRITE_TAC[MEASURABLE_CLOSED_SECTOR_LE] THEN + MATCH_MP_TAC NEGLIGIBLE_SUBSET THEN + EXISTS_TAC `{z | Arg z = &0} UNION {z | Arg z = y}` THEN + REWRITE_TAC[NEGLIGIBLE_ARG_EQ; NEGLIGIBLE_UNION_EQ] THEN + REWRITE_TAC[SUBSET; IN_DIFF; IN_UNION; IN_ELIM_THM] THEN + MP_TAC ARG THEN MATCH_MP_TAC MONO_FORALL THEN REAL_ARITH_TAC] THEN + MATCH_MP_TAC EQ_TRANS THEN EXISTS_TAC + `measure (IMAGE (rotate2d x) + {z | norm z <= r /\ &0 < Arg z /\ Arg z < y})` THEN + CONJ_TAC THENL + [ALL_TAC; + ASM_SIMP_TAC[MEASURE_ORTHOGONAL_IMAGE_EQ; + ORTHOGONAL_TRANSFORMATION_ROTATE2D]] THEN + AP_TERM_TAC THEN CONV_TAC SYM_CONV THEN + MATCH_MP_TAC SURJECTIVE_IMAGE_EQ THEN CONJ_TAC THENL + [ASM_MESON_TAC[ORTHOGONAL_TRANSFORMATION_SURJECTIVE; + ORTHOGONAL_TRANSFORMATION_ROTATE2D]; ALL_TAC] THEN + X_GEN_TAC `z:complex` THEN REWRITE_TAC[IN_ELIM_THM] THEN + ASM_CASES_TAC `z = Cx(&0)` THENL + [ASM_REWRITE_TAC[Arg_DEF; ROTATE2D_0] THEN + ASM_REAL_ARITH_TAC; + ALL_TAC] THEN + REWRITE_TAC[NORM_ROTATE2D] THEN AP_TERM_TAC THEN EQ_TAC THENL + [STRIP_TAC THEN + SUBGOAL_THEN `z = rotate2d (--x) (rotate2d x z)` SUBST1_TAC THENL + [REWRITE_TAC[GSYM ROTATE2D_ADD; REAL_ADD_LINV; ROTATE2D_ZERO]; + ALL_TAC] THEN + MP_TAC(ISPECL [`--x:real`; `rotate2d x z`] ARG_ROTATE2D) THEN + ASM_REWRITE_TAC[ROTATE2D_EQ_0] THEN + ANTS_TAC THENL [ASM_REAL_ARITH_TAC; DISCH_THEN SUBST1_TAC] THEN + ASM_REAL_ARITH_TAC; + STRIP_TAC THEN + MP_TAC(ISPECL [`x:real`; `z:complex`] ARG_ROTATE2D) THEN + ASM_REWRITE_TAC[ROTATE2D_EQ_0] THEN + ANTS_TAC THENL [ASM_REAL_ARITH_TAC; DISCH_THEN SUBST1_TAC] THEN + ASM_REAL_ARITH_TAC]]);; + +let HAS_MEASURE_OPEN_SECTOR_LT = prove + (`!t r. &0 <= t /\ t <= &2 * pi + ==> {x:real^2 | norm(x) < r /\ &0 < Arg x /\ Arg x < t} + has_measure (if &0 <= r then t * r pow 2 / &2 else &0)`, + REPEAT STRIP_TAC THEN COND_CASES_TAC THEN + ASM_SIMP_TAC[NORM_ARITH `~(&0 <= r) ==> ~(norm x < r)`; + EMPTY_GSPEC; HAS_MEASURE_EMPTY] THEN + MATCH_MP_TAC HAS_MEASURE_NEGLIGIBLE_SYMDIFF THEN + EXISTS_TAC `{x | norm x <= r /\ Arg x <= t}` THEN + REWRITE_TAC[HAS_MEASURE_MEASURABLE_MEASURE] THEN + ASM_SIMP_TAC[MEASURE_CLOSED_SECTOR_LE; MEASURABLE_CLOSED_SECTOR_LE] THEN + MATCH_MP_TAC NEGLIGIBLE_SUBSET THEN + EXISTS_TAC `{x | dist(vec 0,x) = r} UNION + {z | Arg z = &0} UNION {z | Arg z = t}` THEN + REWRITE_TAC[NEGLIGIBLE_ARG_EQ; REWRITE_RULE[sphere] NEGLIGIBLE_SPHERE; + NEGLIGIBLE_UNION_EQ] THEN + REWRITE_TAC[DIST_0; SUBSET; IN_DIFF; IN_UNION; IN_ELIM_THM] THEN + MP_TAC ARG THEN MATCH_MP_TAC MONO_FORALL THEN REAL_ARITH_TAC);; + +let MEASURE_OPEN_SECTOR_LT = prove + (`!t r. &0 <= t /\ t <= &2 * pi + ==> measure {x:real^2 | norm(x) < r /\ &0 < Arg x /\ Arg x < t} = + if &0 <= r then t * r pow 2 / &2 else &0`, + SIMP_TAC[REWRITE_RULE[HAS_MEASURE_MEASURABLE_MEASURE] + HAS_MEASURE_OPEN_SECTOR_LT]);; + +let HAS_MEASURE_OPEN_SECTOR_LT_GEN = prove + (`!w z. + ~(w = vec 0) + ==> {x | norm(x) < r /\ &0 < Arg(x / w) /\ Arg(x / w) < Arg(z / w)} + has_measure (if &0 <= r then Arg(z / w) * r pow 2 / &2 else &0)`, + GEOM_BASIS_MULTIPLE_TAC 1 `w:complex` THEN + X_GEN_TAC `w:real` THEN GEN_REWRITE_TAC LAND_CONV [REAL_LE_LT] THEN + ASM_CASES_TAC `w = &0` THEN ASM_REWRITE_TAC[VECTOR_MUL_LZERO] THEN + REWRITE_TAC[COMPLEX_CMUL; COMPLEX_BASIS; COMPLEX_VEC_0] THEN + SIMP_TAC[ARG_DIV_CX; COMPLEX_MUL_RID] THEN ASM_REWRITE_TAC[CX_INJ] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_MEASURE_OPEN_SECTOR_LT THEN + SIMP_TAC[ARG; REAL_LT_IMP_LE]);; + +(* ------------------------------------------------------------------------- *) +(* Hence volume of a wedge of a ball. *) +(* ------------------------------------------------------------------------- *) + +let MEASURABLE_BALL_WEDGE = prove + (`!z:real^3 w w1 w2. measurable(ball(z,r) INTER wedge z w w1 w2)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC MEASURABLE_OPEN THEN CONJ_TAC THENL + [MATCH_MP_TAC BOUNDED_INTER THEN REWRITE_TAC[BOUNDED_BALL]; + MATCH_MP_TAC OPEN_INTER THEN REWRITE_TAC[OPEN_BALL] THEN + ASM_SIMP_TAC[OPEN_WEDGE]]);; + +let VOLUME_BALL_WEDGE = prove + (`!z:real^3 w r w1 w2. + &0 <= r ==> measure(ball(z,r) INTER wedge z w w1 w2) = + azim z w w1 w2 * &2 * r pow 3 / &3`, + REPEAT GEN_TAC THEN + ASM_CASES_TAC `z:real^3 = w \/ collinear{z,w,w1} \/ collinear{z,w,w2}` THENL + [FIRST_X_ASSUM STRIP_ASSUME_TAC THEN + ASM_SIMP_TAC[WEDGE_DEGENERATE; AZIM_DEGENERATE; INTER_EMPTY; REAL_MUL_LZERO; + MEASURE_EMPTY]; + FIRST_X_ASSUM MP_TAC THEN REWRITE_TAC[IMP_IMP; DE_MORGAN_THM]] THEN + REWRITE_TAC[wedge] THEN GEOM_ORIGIN_TAC `z:real^3` THEN + GEOM_BASIS_MULTIPLE_TAC 3 `w:real^3` THEN + X_GEN_TAC `w:real` THEN GEN_REWRITE_TAC LAND_CONV [REAL_LE_LT] THEN + ASM_CASES_TAC `w = &0` THEN ASM_REWRITE_TAC[VECTOR_MUL_LZERO] THEN + ASM_SIMP_TAC[AZIM_SPECIAL_SCALE; COLLINEAR_SPECIAL_SCALE] THEN + REPEAT STRIP_TAC THEN + MATCH_MP_TAC(INST_TYPE[`:2`,`:M`; `:3`,`:N`] FUBINI_SIMPLE_OPEN) THEN + EXISTS_TAC `3` THEN REWRITE_TAC[DIMINDEX_2; DIMINDEX_3; ARITH] THEN + REPEAT CONJ_TAC THENL + [MESON_TAC[BOUNDED_SUBSET; INTER_SUBSET; BOUNDED_BALL]; + REWRITE_TAC[GSYM wedge] THEN MATCH_MP_TAC OPEN_INTER THEN + ASM_REWRITE_TAC[OPEN_BALL; OPEN_WEDGE]; + SIMP_TAC[SLICE_INTER; DIMINDEX_2; DIMINDEX_3; ARITH; SLICE_BALL]] THEN + ONCE_REWRITE_TAC[TAUT `~a /\ b /\ c <=> ~(~a ==> ~(b /\ c))`] THEN + ASM_SIMP_TAC[AZIM_ARG] THEN REWRITE_TAC[COLLINEAR_BASIS_3] THEN + RULE_ASSUM_TAC(REWRITE_RULE[COLLINEAR_BASIS_3]) THEN + REWRITE_TAC[NOT_IMP; GSYM CONJ_ASSOC; DROPOUT_0] THEN + MAP_EVERY ABBREV_TAC + [`v1:real^2 = dropout 3 (w1:real^3)`; + `v2:real^2 = dropout 3 (w2:real^3)`] THEN + REWRITE_TAC[SLICE_DROPOUT_3; VEC_COMPONENT; REAL_SUB_RZERO] THEN + ONCE_REWRITE_TAC[COND_RAND] THEN + ONCE_REWRITE_TAC[COND_RATOR] THEN + REWRITE_TAC[INTER_EMPTY] THEN REWRITE_TAC[INTER; IN_BALL_0; IN_ELIM_THM] THEN + ONCE_REWRITE_TAC[COND_RAND] THEN REWRITE_TAC[MEASURE_EMPTY] THEN + MAP_EVERY UNDISCH_TAC + [`~(v1:complex = vec 0)`; `~(v2:complex = vec 0)`] THEN + MAP_EVERY (fun t -> SPEC_TAC(t,t)) [`v2:complex`; `v1:complex`] THEN + UNDISCH_TAC `&0 <= r` THEN SPEC_TAC(`r:real`,`r:real`) THEN + REWRITE_TAC[RIGHT_IMP_FORALL_THM; IMP_IMP; GSYM CONJ_ASSOC] THEN + POP_ASSUM_LIST(K ALL_TAC) THEN GEOM_BASIS_MULTIPLE_TAC 1 `v1:complex` THEN + X_GEN_TAC `v1:real` THEN GEN_REWRITE_TAC LAND_CONV [REAL_LE_LT] THEN + ASM_CASES_TAC `v1 = &0` THEN ASM_REWRITE_TAC[VECTOR_MUL_LZERO] THEN + REWRITE_TAC[COMPLEX_CMUL; COMPLEX_BASIS; COMPLEX_VEC_0] THEN + SIMP_TAC[ARG_DIV_CX; COMPLEX_MUL_RID; CX_INJ] THEN REPEAT STRIP_TAC THEN + SUBGOAL_THEN + `!t z. ~(z = Cx(&0)) /\ &0 < Arg z /\ Arg z < t <=> + &0 < Arg z /\ Arg z < t` + (fun th -> REWRITE_TAC[th]) + THENL [MESON_TAC[ARG_0; REAL_LT_REFL]; ALL_TAC] THEN + ASM_SIMP_TAC[MEASURE_OPEN_SECTOR_LT; REAL_LE_REFL; ARG; REAL_LT_IMP_LE] THEN + SUBGOAL_THEN `!t. abs(t) < r <=> t IN real_interval(--r,r)` + (fun th -> REWRITE_TAC[th]) + THENL [REWRITE_TAC[IN_REAL_INTERVAL] THEN REAL_ARITH_TAC; ALL_TAC] THEN + REWRITE_TAC[HAS_REAL_INTEGRAL_RESTRICT_UNIV] THEN + REWRITE_TAC[HAS_REAL_INTEGRAL_OPEN_INTERVAL] THEN + MATCH_MP_TAC HAS_REAL_INTEGRAL_EQ THEN + EXISTS_TAC `\t. Arg v2 * (r pow 2 - t pow 2) / &2` THEN CONJ_TAC THENL + [X_GEN_TAC `t:real` THEN REWRITE_TAC[IN_REAL_INTERVAL; REAL_BOUNDS_LE] THEN + SIMP_TAC[AREA_CBALL; SQRT_POS_LE; REAL_SUB_LE; GSYM REAL_LE_SQUARE_ABS; + SQRT_POW_2; REAL_ARITH `abs x <= r ==> abs x <= abs r`]; + ALL_TAC] THEN + MP_TAC(ISPECL + [`\t. Arg v2 * (r pow 2 * t - &1 / &3 * t pow 3) / &2`; + `\t. Arg v2 * (r pow 2 - t pow 2) / &2`; + `--r:real`; `r:real`] REAL_FUNDAMENTAL_THEOREM_OF_CALCULUS) THEN + REWRITE_TAC[] THEN ANTS_TAC THENL + [CONJ_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN + REPEAT STRIP_TAC THEN REAL_DIFF_TAC THEN + CONV_TAC NUM_REDUCE_CONV THEN CONV_TAC REAL_RING; + MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_TERM_TAC THEN + CONV_TAC REAL_RING]);; + +(* ------------------------------------------------------------------------- *) +(* Hence volume of lune. *) +(* ------------------------------------------------------------------------- *) + +let HAS_MEASURE_LUNE = prove + (`!z:real^3 w r w1 w2. + &0 <= r /\ ~(w = z) /\ + ~collinear {z,w,w1} /\ ~collinear {z,w,w2} /\ ~(dihV z w w1 w2 = pi) + ==> (ball(z,r) INTER aff_gt {z,w} {w1,w2}) + has_measure (dihV z w w1 w2 * &2 * r pow 3 / &3)`, + GEOM_ORIGIN_TAC `z:real^3` THEN + GEOM_BASIS_MULTIPLE_TAC 3 `w:real^3` THEN + X_GEN_TAC `w:real` THEN GEN_REWRITE_TAC LAND_CONV [REAL_LE_LT] THEN + ASM_CASES_TAC `w = &0` THEN ASM_REWRITE_TAC[] THENL + [ASM_REWRITE_TAC[VECTOR_MUL_LZERO; INSERT_AC; COLLINEAR_2]; ALL_TAC] THEN + DISCH_TAC THEN REPEAT GEN_TAC THEN + ASM_SIMP_TAC[DIHV_SPECIAL_SCALE] THEN + MP_TAC(ISPECL [`{}:real^3->bool`; `{w1:real^3,w2:real^3}`; + `w:real`; `basis 3:real^3`] AFF_GT_SPECIAL_SCALE) THEN + ASM_CASES_TAC `w1:real^3 = vec 0` THENL + [ASM_REWRITE_TAC[INSERT_AC; COLLINEAR_2]; ALL_TAC] THEN + ASM_CASES_TAC `w2:real^3 = vec 0` THENL + [ASM_REWRITE_TAC[INSERT_AC; COLLINEAR_2]; ALL_TAC] THEN + ASM_REWRITE_TAC[FINITE_INSERT; FINITE_EMPTY; IN_INSERT; NOT_IN_EMPTY] THEN + ASM_CASES_TAC `w1:real^3 = w % basis 3` THENL + [ASM_REWRITE_TAC[INSERT_AC; COLLINEAR_2]; ALL_TAC] THEN + ASM_CASES_TAC `w2:real^3 = w % basis 3` THENL + [ASM_REWRITE_TAC[INSERT_AC; COLLINEAR_2]; ALL_TAC] THEN + ASM_SIMP_TAC[COLLINEAR_SPECIAL_SCALE] THEN + ASM_CASES_TAC `w1:real^3 = basis 3` THENL + [ASM_REWRITE_TAC[INSERT_AC; COLLINEAR_2]; ALL_TAC] THEN + ASM_CASES_TAC `w2:real^3 = basis 3` THENL + [ASM_REWRITE_TAC[INSERT_AC; COLLINEAR_2]; ALL_TAC] THEN + ASM_REWRITE_TAC[] THEN DISCH_THEN SUBST1_TAC THEN + ASM_SIMP_TAC[VECTOR_MUL_EQ_0; REAL_LT_IMP_NZ] THEN STRIP_TAC THEN + ASM_CASES_TAC `azim (vec 0) (basis 3) w1 w2 = &0` THENL + [MP_TAC(ASSUME `azim (vec 0) (basis 3) w1 w2 = &0`) THEN + W(MP_TAC o PART_MATCH (lhs o rand) AZIM_DIVH o lhs o lhand o snd) THEN + ASM_REWRITE_TAC[PI_POS] THEN DISCH_THEN(SUBST1_TAC o SYM) THEN + REWRITE_TAC[REAL_MUL_LZERO; HAS_MEASURE_0] THEN + MATCH_MP_TAC COPLANAR_IMP_NEGLIGIBLE THEN + MATCH_MP_TAC COPLANAR_SUBSET THEN + EXISTS_TAC `affine hull {vec 0:real^3,basis 3,w1,w2}` THEN + CONJ_TAC THENL + [ASM_MESON_TAC[COPLANAR_AFFINE_HULL_COPLANAR; AZIM_EQ_0_PI_IMP_COPLANAR]; + ALL_TAC] THEN + MATCH_MP_TAC(SET_RULE `t SUBSET u ==> (s INTER t) SUBSET u`) THEN + SIMP_TAC[aff_gt_def; AFFSIGN; sgn_gt; AFFINE_HULL_FINITE; + FINITE_INSERT; FINITE_EMPTY] THEN + REWRITE_TAC[SET_RULE `{a,b} UNION {c,d} = {a,b,c,d}`] THEN + REWRITE_TAC[SUBSET; IN_ELIM_THM] THEN GEN_TAC THEN + MATCH_MP_TAC MONO_EXISTS THEN REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[]; + ALL_TAC] THEN + SUBGOAL_THEN `&0 < azim (vec 0) (basis 3) w1 w2` ASSUME_TAC THENL + [ASM_REWRITE_TAC[REAL_LT_LE; azim]; ALL_TAC] THEN + ASM_CASES_TAC `azim (vec 0) (basis 3) w1 w2 < pi` THENL + [ASM_SIMP_TAC[GSYM AZIM_DIHV_SAME; GSYM WEDGE_LUNE_GT] THEN + ASM_SIMP_TAC[HAS_MEASURE_MEASURABLE_MEASURE; MEASURABLE_BALL_WEDGE; + VOLUME_BALL_WEDGE]; + ALL_TAC] THEN + ASM_CASES_TAC `azim (vec 0) (basis 3) w1 w2 = pi` THENL + [MP_TAC(ISPECL [`vec 0:real^3`; `basis 3:real^3`; `w1:real^3`; `w2:real^3`] + AZIM_DIVH) THEN + ASM_REWRITE_TAC[REAL_LT_REFL] THEN ASM_REAL_ARITH_TAC; + ALL_TAC] THEN + SUBGOAL_THEN + `dihV (vec 0) (basis 3) w1 w2 = azim (vec 0) (basis 3) w2 w1` + SUBST1_TAC THENL + [W(MP_TAC o PART_MATCH (lhs o rand) AZIM_COMPL o rand o snd) THEN + ASM_REWRITE_TAC[] THEN DISCH_THEN SUBST1_TAC THEN + ONCE_REWRITE_TAC[REAL_ARITH `x:real = y - z <=> z = y - x`] THEN + MATCH_MP_TAC AZIM_DIHV_COMPL THEN + ASM_REWRITE_TAC[GSYM REAL_NOT_LT]; + ALL_TAC] THEN + SUBGOAL_THEN `&0 < azim (vec 0) (basis 3) w2 w1 /\ + azim (vec 0) (basis 3) w2 w1 < pi` + ASSUME_TAC THENL + [W(MP_TAC o PART_MATCH (lhs o rand) AZIM_COMPL o lhand o rand o snd) THEN + ASM_REWRITE_TAC[] THEN DISCH_THEN SUBST1_TAC THEN + MP_TAC(ISPECL [`vec 0:real^3`; `basis 3:real^3`; `w1:real^3`; `w2:real^3`] + azim) THEN + REWRITE_TAC[CONJ_ASSOC] THEN DISCH_THEN(MP_TAC o CONJUNCT1) THEN + ASM_REAL_ARITH_TAC; + ALL_TAC] THEN + SUBST1_TAC(SET_RULE `{w1:real^3,w2} = {w2,w1}`) THEN + ASM_SIMP_TAC[GSYM AZIM_DIHV_SAME; GSYM WEDGE_LUNE_GT] THEN + ASM_SIMP_TAC[HAS_MEASURE_MEASURABLE_MEASURE; MEASURABLE_BALL_WEDGE; + VOLUME_BALL_WEDGE]);; + +let HAS_MEASURE_LUNE_SIMPLE = prove + (`!z:real^3 w r w1 w2. + &0 <= r /\ ~coplanar{z,w,w1,w2} + ==> (ball(z,r) INTER aff_gt {z,w} {w1,w2}) + has_measure (dihV z w w1 w2 * &2 * r pow 3 / &3)`, + REPEAT GEN_TAC THEN + ASM_CASES_TAC `w:real^3 = z` THENL + [ASM_REWRITE_TAC[INSERT_AC; COPLANAR_3]; ALL_TAC] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_MEASURE_LUNE THEN + ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC(TAUT `a /\ b /\ (a /\ b ==> c) ==> a /\ b /\ c`) THEN + REPEAT(CONJ_TAC THENL + [ASM_MESON_TAC[NOT_COPLANAR_NOT_COLLINEAR; INSERT_AC]; ALL_TAC]) THEN + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`z:real^3`; `w:real^3`; `w1:real^3`; `w2:real^3`] + AZIM_DIVH) THEN + ASM_REWRITE_TAC[REAL_ARITH `&2 * pi - pi = pi`; COND_ID] THEN + ASM_MESON_TAC[AZIM_EQ_0_PI_IMP_COPLANAR]);; + +(* ------------------------------------------------------------------------- *) +(* Now the volume of a solid triangle. *) +(* ------------------------------------------------------------------------- *) + +let MEASURABLE_BALL_AFF_GT = prove + (`!z r s t. measurable(ball(z,r) INTER aff_gt s t)`, + MESON_TAC[MEASURABLE_CONVEX; CONVEX_INTER; CONVEX_AFF_GT; CONVEX_BALL; + BOUNDED_INTER; BOUNDED_BALL]);; + +let AFF_GT_SHUFFLE = prove + (`!s t v:real^N. + FINITE s /\ FINITE t /\ + vec 0 IN s /\ ~(vec 0 IN t) /\ + ~(v IN s) /\ ~(--v IN s) /\ ~(v IN t) + ==> aff_gt (v INSERT s) t = + aff_gt s (v INSERT t) UNION + aff_gt s (--v INSERT t) UNION + aff_gt s t`, + REPEAT STRIP_TAC THEN + REWRITE_TAC[aff_gt_def; AFFSIGN_ALT; sgn_gt] THEN + REWRITE_TAC[SET_RULE `(v INSERT s) UNION t = v INSERT (s UNION t)`; + SET_RULE `s UNION (v INSERT t) = v INSERT (s UNION t)`] THEN + ASM_SIMP_TAC[FINITE_INSERT; FINITE_UNION; AFFINE_HULL_FINITE_STEP_GEN; + RIGHT_EXISTS_AND_THM; REAL_LT_ADD; REAL_HALF; FINITE_EMPTY] THEN + REWRITE_TAC[IN_INSERT] THEN + ASM_SIMP_TAC[SET_RULE + `~(a IN s) + ==> ((w IN s UNION t ==> w = a \/ w IN t ==> P w) <=> + (w IN t ==> P w))`] THEN + REWRITE_TAC[SET_RULE `x IN (s UNION t) + ==> x IN t ==> P x <=> x IN t ==> P x`] THEN + REWRITE_TAC[EXTENSION; IN_UNION; IN_ELIM_THM] THEN + X_GEN_TAC `y:real^N` THEN EQ_TAC THENL + [DISCH_THEN(X_CHOOSE_THEN `v:real` ASSUME_TAC) THEN + ASM_CASES_TAC `&0 < v` THENL + [DISJ1_TAC THEN EXISTS_TAC `v:real` THEN ASM_REWRITE_TAC[]; + DISJ2_TAC] THEN + ASM_CASES_TAC `v = &0` THENL + [DISJ2_TAC THEN + FIRST_ASSUM(fun th -> MP_TAC th THEN MATCH_MP_TAC MONO_EXISTS) THEN + ASM_REWRITE_TAC[REAL_SUB_RZERO; VECTOR_MUL_LZERO; VECTOR_SUB_RZERO]; + DISJ1_TAC] THEN + EXISTS_TAC `--v:real` THEN CONJ_TAC THENL + [ASM_REAL_ARITH_TAC; ALL_TAC] THEN + FIRST_X_ASSUM(X_CHOOSE_THEN `f:real^N->real` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `\x:real^N. if x = vec 0 then f(x) + &2 * v else f(x)` THEN + REWRITE_TAC[] THEN REPEAT CONJ_TAC THENL + [ASM_MESON_TAC[]; + ASM_SIMP_TAC[SUM_CASES_1; FINITE_UNION; IN_UNION] THEN REAL_ARITH_TAC; + REWRITE_TAC[VECTOR_ARITH `--a % --x:real^N = a % x`] THEN + FIRST_X_ASSUM(fun th -> GEN_REWRITE_TAC RAND_CONV [GSYM th]) THEN + MATCH_MP_TAC VSUM_EQ THEN REWRITE_TAC[] THEN + REPEAT STRIP_TAC THEN COND_CASES_TAC THEN + ASM_REWRITE_TAC[VECTOR_MUL_RZERO]]; + DISCH_THEN(DISJ_CASES_THEN MP_TAC) THENL [MESON_TAC[]; ALL_TAC] THEN + DISCH_THEN(DISJ_CASES_THEN MP_TAC) THENL + [DISCH_THEN(X_CHOOSE_THEN `a:real` + (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + DISCH_THEN(X_CHOOSE_THEN `f:real^N->real` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `--a:real` THEN + EXISTS_TAC `\x:real^N. if x = vec 0 then &2 * a + f(vec 0) else f x` THEN + ASM_SIMP_TAC[SUM_CASES_1; FINITE_UNION; IN_UNION] THEN + CONJ_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN + CONJ_TAC THENL [REAL_ARITH_TAC; ALL_TAC] THEN + ONCE_REWRITE_TAC[VECTOR_ARITH `y - --a % v:real^N = y - a % --v`] THEN + FIRST_X_ASSUM(fun th -> GEN_REWRITE_TAC RAND_CONV [SYM th]) THEN + MATCH_MP_TAC VSUM_EQ THEN REPEAT GEN_TAC THEN REWRITE_TAC[] THEN + DISCH_TAC THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[VECTOR_MUL_RZERO]; + GEN_REWRITE_TAC RAND_CONV [SWAP_EXISTS_THM] THEN + MATCH_MP_TAC MONO_EXISTS THEN REPEAT STRIP_TAC THEN + EXISTS_TAC `&0` THEN ASM_REWRITE_TAC[REAL_SUB_RZERO] THEN + VECTOR_ARITH_TAC]]);; + +let MEASURE_BALL_AFF_GT_SHUFFLE_LEMMA = prove + (`!r s t v:real^N. + &0 <= r /\ + independent(v INSERT((s DELETE vec 0) UNION t)) /\ + FINITE s /\ FINITE t /\ CARD(s UNION t) <= dimindex(:N) /\ + vec 0 IN s /\ ~(vec 0 IN t) /\ + ~(v IN s) /\ ~(--v IN s) /\ ~(v IN t) + ==> measure(ball(vec 0,r) INTER aff_gt (v INSERT s) t) = + measure(ball(vec 0,r) INTER aff_gt s (v INSERT t)) + + measure(ball(vec 0,r) INTER aff_gt s (--v INSERT t))`, + let lemma = prove + (`!s t u:real^N->bool. + measurable s /\ measurable t /\ s INTER t = {} /\ negligible u + ==> measure(s UNION t UNION u) = measure s + measure t`, + REPEAT STRIP_TAC THEN REWRITE_TAC[UNION_ASSOC] THEN + ASM_SIMP_TAC[GSYM MEASURE_DISJOINT_UNION; DISJOINT] THEN + MATCH_MP_TAC MEASURE_NEGLIGIBLE_SYMDIFF THEN + ASM_SIMP_TAC[MEASURABLE_UNION] THEN + FIRST_ASSUM(MATCH_MP_TAC o MATCH_MP + (REWRITE_RULE[IMP_CONJ] NEGLIGIBLE_SUBSET)) THEN SET_TAC[]) in + REPEAT STRIP_TAC THEN + W(MP_TAC o PART_MATCH (lhs o rand) AFF_GT_SHUFFLE o + rand o rand o lhand o snd) THEN + ASM_REWRITE_TAC[] THEN DISCH_THEN SUBST1_TAC THEN + REWRITE_TAC[UNION_OVER_INTER] THEN MATCH_MP_TAC lemma THEN + ASM_REWRITE_TAC[MEASURABLE_BALL_AFF_GT] THEN CONJ_TAC THENL + [MATCH_MP_TAC(SET_RULE + `t INTER u = {} ==> (s INTER t) INTER (s INTER u) = {}`) THEN + REWRITE_TAC[aff_gt_def; AFFSIGN_ALT; sgn_gt] THEN + REWRITE_TAC[SET_RULE `(v INSERT s) UNION t = v INSERT (s UNION t)`; + SET_RULE `s UNION (v INSERT t) = v INSERT (s UNION t)`] THEN + ASM_SIMP_TAC[FINITE_INSERT; FINITE_UNION; AFFINE_HULL_FINITE_STEP_GEN; + RIGHT_EXISTS_AND_THM; REAL_LT_ADD; + REAL_HALF; FINITE_EMPTY] THEN + REWRITE_TAC[IN_INSERT] THEN + ASM_SIMP_TAC[SET_RULE + `~(a IN s) ==> ((w IN s UNION t ==> w = a \/ w IN t ==> P w) <=> + (w IN t ==> P w))`] THEN + GEN_REWRITE_TAC I [EXTENSION] THEN + REWRITE_TAC[IN_INTER; NOT_IN_EMPTY; IN_ELIM_THM] THEN + X_GEN_TAC `y:real^N` THEN + DISCH_THEN(CONJUNCTS_THEN2 + (X_CHOOSE_THEN `a:real` + (CONJUNCTS_THEN2 ASSUME_TAC + (X_CHOOSE_THEN `f:real^N->real` STRIP_ASSUME_TAC))) + (X_CHOOSE_THEN `b:real` + (CONJUNCTS_THEN2 ASSUME_TAC + (X_CHOOSE_THEN `g:real^N->real` STRIP_ASSUME_TAC)))) THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [INDEPENDENT_EXPLICIT]) THEN + REWRITE_TAC[FINITE_INSERT; FINITE_DELETE; FINITE_UNION] THEN + DISCH_THEN(CONJUNCTS_THEN2 STRIP_ASSUME_TAC MP_TAC) THEN + DISCH_THEN(MP_TAC o SPEC + `\x. if x = v then a + b else (f:real^N->real) x - g x`) THEN + ASM_SIMP_TAC[VSUM_CLAUSES; FINITE_DELETE; FINITE_UNION] THEN + ASM_REWRITE_TAC[IN_DELETE; IN_UNION] THEN + REWRITE_TAC[NOT_IMP] THEN CONJ_TAC THENL + [ALL_TAC; DISCH_THEN(MP_TAC o SPEC `v:real^N`) THEN + REWRITE_TAC[IN_INSERT] THEN ASM_REAL_ARITH_TAC] THEN + ASM_SIMP_TAC[SET_RULE + `~(a IN t) ==> (s DELETE a) UNION t = (s UNION t) DELETE a`] THEN + ASM_SIMP_TAC[VSUM_DELETE_CASES; FINITE_UNION; IN_UNION] THEN + REWRITE_TAC[VECTOR_MUL_RZERO; VECTOR_SUB_RZERO] THEN + SUBGOAL_THEN + `!x:real^N. (if x = v then a + b else f x - g x) % x = + (if x = v then a else f x) % x - + (if x = v then --b else g x) % x` + (fun th -> REWRITE_TAC[th]) + THENL + [GEN_TAC THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN VECTOR_ARITH_TAC; + ASM_SIMP_TAC[VSUM_SUB; FINITE_UNION]] THEN + MATCH_MP_TAC EQ_TRANS THEN + EXISTS_TAC `(a + b) % v + (y - a % v) - (y - b % --v):real^N` THEN + CONJ_TAC THENL [ALL_TAC; VECTOR_ARITH_TAC] THEN + AP_TERM_TAC THEN BINOP_TAC THEN + FIRST_X_ASSUM(fun th -> GEN_REWRITE_TAC RAND_CONV [GSYM th]) THEN + MATCH_MP_TAC VSUM_EQ THEN GEN_TAC THEN REWRITE_TAC[] THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[IN_UNION]; + MATCH_MP_TAC NEGLIGIBLE_SUBSET THEN + EXISTS_TAC `aff_gt s t :real^N->bool` THEN + REWRITE_TAC[INTER_SUBSET] THEN + MATCH_MP_TAC NEGLIGIBLE_SUBSET THEN + EXISTS_TAC `affine hull (s UNION t:real^N->bool)` THEN + REWRITE_TAC[AFF_GT_SUBSET_AFFINE_HULL] THEN + ASM_SIMP_TAC[AFFINE_HULL_EQ_SPAN; IN_UNION; HULL_INC] THEN + ONCE_REWRITE_TAC[GSYM SPAN_DELETE_0] THEN + MATCH_MP_TAC NEGLIGIBLE_LOWDIM THEN + MATCH_MP_TAC LET_TRANS THEN + EXISTS_TAC `CARD((s UNION t) DELETE (vec 0:real^N))` THEN + ASM_SIMP_TAC[DIM_LE_CARD; FINITE_DELETE; FINITE_UNION; DIM_SPAN] THEN + ASM_SIMP_TAC[CARD_DELETE; IN_UNION; FINITE_UNION] THEN + MATCH_MP_TAC(ARITH_RULE `1 <= n /\ x <= n ==> x - 1 < n`) THEN + ASM_REWRITE_TAC[DIMINDEX_GE_1]]);; + +let MEASURE_BALL_AFF_GT_SHUFFLE = prove + (`!r s t v:real^N. + &0 <= r /\ ~(v IN (s UNION t)) /\ + independent(v INSERT (s UNION t)) + ==> measure(ball(vec 0,r) INTER aff_gt (vec 0 INSERT v INSERT s) t) = + measure(ball(vec 0,r) INTER aff_gt (vec 0 INSERT s) (v INSERT t)) + + measure(ball(vec 0,r) INTER + aff_gt (vec 0 INSERT s) (--v INSERT t))`, + REWRITE_TAC[IN_UNION; DE_MORGAN_THM] THEN REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`r:real`; `(vec 0:real^N) INSERT s`; + `t:real^N->bool`; `v:real^N`] + MEASURE_BALL_AFF_GT_SHUFFLE_LEMMA) THEN + ANTS_TAC THENL [ALL_TAC; REWRITE_TAC[INSERT_AC]] THEN + ASM_REWRITE_TAC[IN_INSERT; FINITE_INSERT] THEN + FIRST_ASSUM(MP_TAC o MATCH_MP INDEPENDENT_NONZERO) THEN + REWRITE_TAC[IN_INSERT; IN_UNION; DE_MORGAN_THM] THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + FIRST_ASSUM(MP_TAC o MATCH_MP INDEPENDENT_BOUND) THEN + REWRITE_TAC[FINITE_INSERT; FINITE_UNION] THEN + DISCH_THEN(CONJUNCTS_THEN2 STRIP_ASSUME_TAC MP_TAC) THEN + REWRITE_TAC[SET_RULE `(a INSERT s) UNION t = a INSERT (s UNION t)`] THEN + ASM_SIMP_TAC[CARD_CLAUSES; FINITE_UNION; IN_UNION; FINITE_INSERT] THEN + DISCH_TAC THEN ASM_REWRITE_TAC[VECTOR_NEG_EQ_0] THEN CONJ_TAC THENL + [FIRST_ASSUM(MATCH_MP_TAC o MATCH_MP + (REWRITE_RULE[IMP_CONJ] INDEPENDENT_MONO)) THEN + SET_TAC[]; + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [independent]) THEN + REWRITE_TAC[dependent; CONTRAPOS_THM] THEN DISCH_TAC THEN + EXISTS_TAC `v:real^N` THEN REWRITE_TAC[IN_INSERT] THEN + GEN_REWRITE_TAC LAND_CONV [GSYM VECTOR_NEG_NEG] THEN + MATCH_MP_TAC SPAN_NEG THEN MATCH_MP_TAC SPAN_SUPERSET THEN + ASM_REWRITE_TAC[IN_DELETE; VECTOR_ARITH `--v:real^N = v <=> v = vec 0`; + IN_INSERT; IN_UNION]]);; + +let MEASURE_LUNE_DECOMPOSITION = prove + (`!v1 v2 v3:real^3. + &0 <= r /\ ~coplanar {vec 0, v1, v2, v3} + ==> measure(ball(vec 0,r) INTER aff_gt {vec 0} {v1,v2,v3}) + + measure(ball(vec 0,r) INTER aff_gt {vec 0} {--v1,v2,v3}) = + dihV (vec 0) v1 v2 v3 * &2 * r pow 3 / &3`, + let rec distinctpairs l = + match l with + x::t -> itlist (fun y a -> (x,y) :: a) t (distinctpairs t) + | [] -> [] in + REPEAT GEN_TAC THEN MAP_EVERY + (fun t -> ASM_CASES_TAC t THENL + [ASM_REWRITE_TAC[INSERT_AC; COPLANAR_3]; ALL_TAC]) + (map mk_eq (distinctpairs + [`v3:real^3`; `v2:real^3`; `v1:real^3`; `vec 0:real^3`])) THEN + REPEAT STRIP_TAC THEN + ASM_SIMP_TAC[GSYM(REWRITE_RULE[HAS_MEASURE_MEASURABLE_MEASURE] + HAS_MEASURE_LUNE_SIMPLE)] THEN + CONV_TAC SYM_CONV THEN MATCH_MP_TAC MEASURE_BALL_AFF_GT_SHUFFLE THEN + ASM_REWRITE_TAC[UNION_EMPTY; IN_INSERT; NOT_IN_EMPTY] THEN + ASM_SIMP_TAC[NOT_COPLANAR_0_4_IMP_INDEPENDENT]);; + +let SOLID_TRIANGLE_CONGRUENT_NEG = prove + (`!r v1 v2 v3:real^N. + measure(ball(vec 0,r) INTER aff_gt {vec 0} {--v1, --v2, --v3}) = + measure(ball(vec 0,r) INTER aff_gt {vec 0} {v1, v2, v3})`, + REPEAT GEN_TAC THEN + SUBGOAL_THEN + `ball(vec 0:real^N,r) INTER aff_gt {vec 0} {--v1, --v2, --v3} = + IMAGE (--) + (ball(vec 0,r) INTER aff_gt {vec 0} {v1, v2, v3})` + SUBST1_TAC THENL + [ALL_TAC; + MATCH_MP_TAC MEASURE_ORTHOGONAL_IMAGE_EQ THEN + REWRITE_TAC[ORTHOGONAL_TRANSFORMATION; linear; NORM_NEG] THEN + CONJ_TAC THEN VECTOR_ARITH_TAC] THEN + CONV_TAC SYM_CONV THEN MATCH_MP_TAC SURJECTIVE_IMAGE_EQ THEN + CONJ_TAC THENL [MESON_TAC[VECTOR_NEG_NEG]; ALL_TAC] THEN + REWRITE_TAC[IN_INTER; IN_BALL_0; NORM_NEG] THEN + REWRITE_TAC[AFFSIGN_ALT; aff_gt_def; sgn_gt; IN_ELIM_THM] THEN + REWRITE_TAC[SET_RULE `{a} UNION {b,c,d} = {a,b,d,c}`] THEN + REWRITE_TAC[SET_RULE `x IN {a} <=> a = x`] THEN + ASM_SIMP_TAC[FINITE_INSERT; FINITE_UNION; AFFINE_HULL_FINITE_STEP_GEN; + RIGHT_EXISTS_AND_THM; REAL_LT_ADD; REAL_HALF; FINITE_EMPTY] THEN + ASM_REWRITE_TAC[IN_INSERT; NOT_IN_EMPTY] THEN + REWRITE_TAC[VECTOR_MUL_RZERO; VECTOR_SUB_RZERO] THEN + REWRITE_TAC[VECTOR_ARITH `vec 0:real^N = --x <=> vec 0 = x`] THEN + REWRITE_TAC[VECTOR_ARITH `--x - a % --w:real^N = --(x - a % w)`] THEN + REWRITE_TAC[VECTOR_NEG_EQ_0]);; + +let VOLUME_SOLID_TRIANGLE = prove + (`!r v0 v1 v2 v3:real^3. + &0 < r /\ ~coplanar{v0, v1, v2, v3} + ==> measure(ball(v0,r) INTER aff_gt {v0} {v1,v2,v3}) = + let a123 = dihV v0 v1 v2 v3 in + let a231 = dihV v0 v2 v3 v1 in + let a312 = dihV v0 v3 v1 v2 in + (a123 + a231 + a312 - pi) * r pow 3 / &3`, + let tac convl = + W(MP_TAC o PART_MATCH (lhs o rand) MEASURE_BALL_AFF_GT_SHUFFLE o + convl o lhand o lhand o snd) THEN + ASM_REWRITE_TAC[UNION_EMPTY; IN_INSERT; IN_UNION; NOT_IN_EMPTY] THEN + REWRITE_TAC[SET_RULE `(a INSERT s) UNION t = a INSERT (s UNION t)`] THEN + ASM_SIMP_TAC[UNION_EMPTY; REAL_LT_IMP_LE] THEN ANTS_TAC THENL + [CONJ_TAC THENL + [DISCH_THEN(STRIP_THM_THEN SUBST_ALL_TAC) THEN + RULE_ASSUM_TAC(REWRITE_RULE[INSERT_AC]) THEN + RULE_ASSUM_TAC(REWRITE_RULE[COPLANAR_3]) THEN + FIRST_ASSUM CONTR_TAC; + MATCH_MP_TAC NOT_COPLANAR_0_4_IMP_INDEPENDENT THEN + RULE_ASSUM_TAC(REWRITE_RULE[INSERT_AC]) THEN + ASM_REWRITE_TAC[INSERT_AC]]; + DISCH_THEN SUBST1_TAC] in + GEN_TAC THEN GEOM_ORIGIN_TAC `v0:real^3` THEN + CONV_TAC(TOP_DEPTH_CONV let_CONV) THEN REPEAT STRIP_TAC THEN + SUBGOAL_THEN + `measure(ball(vec 0:real^3,r) INTER aff_gt {vec 0,v1,v2,v3} {}) = + &4 / &3 * pi * r pow 3` + MP_TAC THENL + [MP_TAC(SPECL [`vec 0:real^3`; `r:real`] VOLUME_BALL) THEN + ASM_SIMP_TAC[REAL_LT_IMP_LE] THEN + DISCH_THEN(SUBST1_TAC o SYM) THEN AP_TERM_TAC THEN + MATCH_MP_TAC(SET_RULE `t = UNIV ==> s INTER t = s`) THEN + REWRITE_TAC[AFF_GT_EQ_AFFINE_HULL] THEN + SIMP_TAC[AFFINE_HULL_EQ_SPAN; HULL_INC; IN_INSERT; SPAN_INSERT_0] THEN + REWRITE_TAC[SET_RULE `s = UNIV <=> UNIV SUBSET s`] THEN + MATCH_MP_TAC CARD_GE_DIM_INDEPENDENT THEN + ASM_SIMP_TAC[DIM_UNIV; DIMINDEX_3; SUBSET_UNIV] THEN + ASM_SIMP_TAC[NOT_COPLANAR_0_4_IMP_INDEPENDENT] THEN + SIMP_TAC[CARD_CLAUSES; FINITE_INSERT; FINITE_EMPTY] THEN + REWRITE_TAC[IN_INSERT; NOT_IN_EMPTY] THEN + MAP_EVERY (fun t -> + ASM_CASES_TAC t THENL + [FIRST_X_ASSUM SUBST_ALL_TAC THEN + RULE_ASSUM_TAC(REWRITE_RULE[INSERT_AC; COPLANAR_3]) THEN + ASM_MESON_TAC[]; + ASM_REWRITE_TAC[]]) + [`v3:real^3 = v2`; `v3:real^3 = v1`; `v2:real^3 = v1`] THEN + CONV_TAC NUM_REDUCE_CONV; + ALL_TAC] THEN + SUBGOAL_THEN + `~(coplanar {vec 0:real^3,v1,v2,v3}) /\ + ~(coplanar {vec 0,--v1,v2,v3}) /\ + ~(coplanar {vec 0,v1,--v2,v3}) /\ + ~(coplanar {vec 0,--v1,--v2,v3}) /\ + ~(coplanar {vec 0,--v1,--v2,v3}) /\ + ~(coplanar {vec 0,--v1,v2,--v3}) /\ + ~(coplanar {vec 0,v1,--v2,--v3}) /\ + ~(coplanar {vec 0,--v1,--v2,--v3}) /\ + ~(coplanar {vec 0,--v1,--v2,--v3})` + STRIP_ASSUME_TAC THENL + [REPLICATE_TAC 3 + (REWRITE_TAC[COPLANAR_INSERT_0_NEG] THEN + ONCE_REWRITE_TAC[SET_RULE `{vec 0,a,b,c} = {vec 0,b,c,a}`]) THEN + ASM_REWRITE_TAC[]; + ALL_TAC] THEN + MAP_EVERY tac + [I; lhand; rand; + lhand o lhand; rand o lhand; lhand o rand; rand o rand] THEN + MP_TAC(ISPECL [`v1:real^3`; `v2:real^3`; `v3:real^3`] + MEASURE_LUNE_DECOMPOSITION) THEN + MP_TAC(ISPECL [`v2:real^3`; `v3:real^3`; `v1:real^3`] + MEASURE_LUNE_DECOMPOSITION) THEN + MP_TAC(ISPECL [`v3:real^3`; `v1:real^3`; `v2:real^3`] + MEASURE_LUNE_DECOMPOSITION) THEN + MP_TAC(ISPECL [`--v1:real^3`; `--v2:real^3`; `--v3:real^3`] + MEASURE_LUNE_DECOMPOSITION) THEN + MP_TAC(ISPECL [`--v2:real^3`; `--v3:real^3`; `--v1:real^3`] + MEASURE_LUNE_DECOMPOSITION) THEN + MP_TAC(ISPECL [`--v3:real^3`; `--v1:real^3`; `--v2:real^3`] + MEASURE_LUNE_DECOMPOSITION) THEN + ASM_REWRITE_TAC[VECTOR_NEG_NEG] THEN + ASM_SIMP_TAC[REAL_LT_IMP_LE; INSERT_AC] THEN + RULE_ASSUM_TAC(REWRITE_RULE[INSERT_AC]) THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[DIHV_NEG_0] THEN + REWRITE_TAC[SOLID_TRIANGLE_CONGRUENT_NEG] THEN + REWRITE_TAC[INSERT_AC] THEN REAL_ARITH_TAC);; + +(* ------------------------------------------------------------------------- *) +(* Volume of wedge of a frustum. *) +(* ------------------------------------------------------------------------- *) + +let MEASURABLE_BOUNDED_INTER_OPEN = prove + (`!s t:real^N->bool. + measurable s /\ bounded s /\ open t ==> measurable(s INTER t)`, + REPEAT STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o MATCH_MP BOUNDED_SUBSET_OPEN_INTERVAL) THEN + REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`a:real^N`; `b:real^N`] THEN + DISCH_THEN(SUBST1_TAC o MATCH_MP (SET_RULE + `s SUBSET i ==> s INTER t = s INTER (t INTER i)`)) THEN + MATCH_MP_TAC MEASURABLE_INTER THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC MEASURABLE_OPEN THEN + ASM_SIMP_TAC[OPEN_INTER; OPEN_INTERVAL; BOUNDED_INTER; BOUNDED_INTERVAL]);; + +let SLICE_SPECIAL_WEDGE = prove + (`!w1 w2. + ~collinear {vec 0, basis 3, w1} /\ ~collinear {vec 0, basis 3, w2} + ==> slice 3 t (wedge (vec 0) (basis 3) w1 w2) = + {z | &0 < Arg(z / dropout 3 w1) /\ + Arg(z / dropout 3 w1) < Arg(dropout 3 w2 / dropout 3 w1)}`, + REWRITE_TAC[wedge] THEN + ONCE_REWRITE_TAC[TAUT `~a /\ b /\ c <=> ~(~a ==> ~(b /\ c))`] THEN + ASM_SIMP_TAC[AZIM_ARG] THEN REWRITE_TAC[COLLINEAR_BASIS_3] THEN + REWRITE_TAC[NOT_IMP; GSYM CONJ_ASSOC; DROPOUT_0] THEN + MAP_EVERY ABBREV_TAC + [`v1:real^2 = dropout 3 (w1:real^3)`; + `v2:real^2 = dropout 3 (w2:real^3)`] THEN + REWRITE_TAC[SLICE_DROPOUT_3; VEC_COMPONENT; REAL_SUB_RZERO] THEN + REPEAT STRIP_TAC THEN + REWRITE_TAC[EXTENSION; IN_ELIM_THM; COMPLEX_VEC_0] THEN + X_GEN_TAC `w:complex` THEN + ASM_CASES_TAC `w = Cx(&0)` THEN ASM_REWRITE_TAC[] THEN + ASM_REWRITE_TAC[complex_div; COMPLEX_MUL_LZERO; ARG_0; REAL_LT_REFL]);; + +let VOLUME_FRUSTT_WEDGE = prove + (`!v0 v1:real^3 w1 w2 h a. + &0 < a /\ ~collinear {v0,v1,w1} /\ ~collinear {v0,v1,w2} + ==> bounded(frustt v0 v1 h a INTER wedge v0 v1 w1 w2) /\ + measurable(frustt v0 v1 h a INTER wedge v0 v1 w1 w2) /\ + measure(frustt v0 v1 h a INTER wedge v0 v1 w1 w2) = + if &1 <= a \/ h < &0 then &0 + else azim v0 v1 w1 w2 * ((h / a) pow 2 - h pow 2) * h / &6`, + REPEAT GEN_TAC THEN ASM_CASES_TAC `v1:real^3 = v0` THENL + [ASM_REWRITE_TAC[INSERT_AC; COLLINEAR_2]; STRIP_TAC] THEN + MATCH_MP_TAC(TAUT `a /\ b /\ (a /\ b ==> c) ==> a /\ b /\ c`) THEN + REPEAT CONJ_TAC THENL + [MATCH_MP_TAC BOUNDED_INTER THEN ASM_SIMP_TAC[VOLUME_FRUSTT_STRONG]; + MATCH_MP_TAC MEASURABLE_BOUNDED_INTER_OPEN THEN + ASM_SIMP_TAC[VOLUME_FRUSTT_STRONG; OPEN_WEDGE]; + ALL_TAC] THEN + REWRITE_TAC[frustt; frustum; rcone_gt; rconesgn; IN_ELIM_THM] THEN + CONV_TAC(TOP_DEPTH_CONV let_CONV) THEN + POP_ASSUM_LIST(MP_TAC o end_itlist CONJ) THEN + GEOM_ORIGIN_TAC `v0:real^3` THEN + REWRITE_TAC[VECTOR_SUB_RZERO; REAL_MUL_LZERO; DIST_0; real_gt] THEN + GEOM_BASIS_MULTIPLE_TAC 3 `v1:real^3` THEN + X_GEN_TAC `b:real` THEN GEN_REWRITE_TAC LAND_CONV [REAL_LE_LT] THEN + ASM_CASES_TAC `b = &0` THEN ASM_REWRITE_TAC[VECTOR_MUL_LZERO] THEN + ASM_SIMP_TAC[COLLINEAR_SPECIAL_SCALE; WEDGE_SPECIAL_SCALE] THEN + ASM_REWRITE_TAC[VECTOR_MUL_EQ_0] THEN + DISCH_TAC THEN REPEAT GEN_TAC THEN STRIP_TAC THEN + ASM_CASES_TAC `&1 <= a` THEN ASM_REWRITE_TAC[] THENL + [SUBGOAL_THEN + `!y:real^3. ~(norm(y) * norm(b % basis 3:real^3) * a + < y dot (b % basis 3))` + (fun th -> REWRITE_TAC[th; EMPTY_GSPEC; MEASURABLE_EMPTY; + INTER_EMPTY; MEASURE_EMPTY]) THEN + REWRITE_TAC[REAL_NOT_LT] THEN X_GEN_TAC `y:real^3` THEN + MATCH_MP_TAC(REAL_ARITH `abs(x) <= a ==> x <= a`) THEN + SIMP_TAC[DOT_RMUL; NORM_MUL; REAL_ABS_MUL; DOT_BASIS; NORM_BASIS; + DIMINDEX_3; ARITH] THEN + REWRITE_TAC[REAL_ARITH + `b * y <= n * (b * &1) * a <=> b * &1 * y <= b * a * n`] THEN + MATCH_MP_TAC REAL_LE_LMUL THEN REWRITE_TAC[REAL_ABS_POS] THEN + MATCH_MP_TAC REAL_LE_MUL2 THEN + ASM_SIMP_TAC[REAL_POS; REAL_ABS_POS; COMPONENT_LE_NORM; DIMINDEX_3; ARITH]; + ALL_TAC] THEN + RULE_ASSUM_TAC(REWRITE_RULE[REAL_NOT_LE]) THEN + SIMP_TAC[NORM_MUL; NORM_BASIS; DOT_BASIS; DOT_RMUL; DIMINDEX_3; ARITH] THEN + ONCE_REWRITE_TAC[REAL_ARITH `n * x * a:real = x * n * a`] THEN + ASM_REWRITE_TAC[real_abs; REAL_MUL_RID] THEN + ASM_SIMP_TAC[REAL_MUL_RID; REAL_LT_LMUL_EQ; REAL_LT_MUL_EQ; NORM_POS_LT] THEN + ASM_SIMP_TAC[VECTOR_MUL_EQ_0; BASIS_NONZERO; DIMINDEX_3; ARITH; + REAL_LT_IMP_NZ] THEN + ASM_SIMP_TAC[GSYM REAL_LT_RDIV_EQ; NORM_LT_SQUARE] THEN + ASM_SIMP_TAC[REAL_POW_DIV; REAL_POW_LT; REAL_LT_RDIV_EQ] THEN + REWRITE_TAC[REAL_ARITH `(&0 * x < y /\ u < v) /\ &0 < y /\ y < h <=> + &0 < y /\ y < h /\ u < v`] THEN + DISCH_TAC THEN MATCH_MP_TAC(INST_TYPE [`:2`,`:M`] FUBINI_SIMPLE_ALT) THEN + EXISTS_TAC `3` THEN ASM_REWRITE_TAC[DIMINDEX_2; DIMINDEX_3; ARITH] THEN + ASM_SIMP_TAC[WEDGE_SPECIAL_SCALE; REAL_LT_IMP_LE] THEN + ASM_SIMP_TAC[REAL_LT_LMUL_EQ; SLICE_INTER; DIMINDEX_2; + DIMINDEX_3; ARITH] THEN + SUBGOAL_THEN + `!t. slice 3 t {y:real^3 | norm y * a < y$3 /\ &0 < y$3 /\ y$3 < h} = + if t < h + then ball(vec 0:real^2,sqrt(inv(a pow 2) - &1) * t) + else {}` + (fun th -> ASM_SIMP_TAC[th; SLICE_SPECIAL_WEDGE]) + THENL + [REWRITE_TAC[EXTENSION] THEN + MAP_EVERY X_GEN_TAC [`t:real`; `z:real^2`] THEN + SIMP_TAC[SLICE_123; DIMINDEX_2; DIMINDEX_3; ARITH; IN_ELIM_THM; + VECTOR_3; DOT_3; GSYM DOT_2] THEN + ASM_CASES_TAC `t < h` THEN ASM_REWRITE_TAC[NOT_IN_EMPTY] THEN + REWRITE_TAC[IN_BALL_0; IN_DELETE] THEN + MATCH_MP_TAC(REAL_ARITH + `&0 <= a /\ (a < t <=> u < v) ==> (a < t /\ &0 < t <=> u < v)`) THEN + ASM_SIMP_TAC[REAL_LE_MUL; NORM_POS_LE; REAL_LT_IMP_LE] THEN + ASM_SIMP_TAC[GSYM REAL_LT_RDIV_EQ; NORM_LT_SQUARE] THEN + SUBGOAL_THEN `&0 < inv(a pow 2) - &1` ASSUME_TAC THENL + [REWRITE_TAC[REAL_SUB_LT] THEN MATCH_MP_TAC REAL_INV_1_LT THEN + ASM_SIMP_TAC[REAL_POW_1_LT; REAL_LT_IMP_LE; ARITH; REAL_POW_LT]; + ALL_TAC] THEN + ASM_SIMP_TAC[REAL_LT_MUL; SQRT_POS_LT; REAL_POW_MUL; SQRT_POW_2; + REAL_LT_IMP_LE; REAL_LT_MUL_EQ] THEN + ASM_SIMP_TAC[real_div; REAL_LT_MUL_EQ; REAL_LT_INV_EQ] THEN + ASM_CASES_TAC `&0 < t` THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[DOT_3; DOT_2; VECTOR_3; REAL_INV_POW] THEN + REAL_ARITH_TAC; + ALL_TAC] THEN + GEN_REWRITE_TAC (LAND_CONV o TOP_DEPTH_CONV) [COND_RATOR; COND_RAND] THEN + GEN_REWRITE_TAC (RAND_CONV o RATOR_CONV o LAND_CONV o TOP_DEPTH_CONV) + [COND_RATOR; COND_RAND] THEN + REWRITE_TAC[INTER_EMPTY; MEASURABLE_EMPTY; MEASURE_EMPTY] THEN + REWRITE_TAC[INTER; IN_BALL_0; IN_ELIM_THM] THEN + RULE_ASSUM_TAC(REWRITE_RULE[COLLINEAR_BASIS_3]) THEN + ASM_SIMP_TAC[REWRITE_RULE[HAS_MEASURE_MEASURABLE_MEASURE] + HAS_MEASURE_OPEN_SECTOR_LT_GEN] THEN + REWRITE_TAC[COND_ID] THEN + SUBGOAL_THEN `&0 < inv(a pow 2) - &1` ASSUME_TAC THENL + [REWRITE_TAC[REAL_SUB_LT] THEN MATCH_MP_TAC REAL_INV_1_LT THEN + ASM_SIMP_TAC[REAL_POW_1_LT; REAL_LT_IMP_LE; ARITH; REAL_POW_LT]; + ALL_TAC] THEN + ASM_SIMP_TAC[REAL_LE_MUL_EQ; SQRT_POS_LT] THEN + ASM_SIMP_TAC[AZIM_SPECIAL_SCALE; AZIM_ARG; COLLINEAR_BASIS_3] THEN + MATCH_MP_TAC HAS_REAL_INTEGRAL_EQ THEN + EXISTS_TAC + `\t. if &0 < t /\ t < h + then Arg(dropout 3 (w2:real^3) / dropout 3 (w1:real^3)) / &2 * + (inv(a pow 2) - &1) * t pow 2 + else &0` THEN + CONJ_TAC THENL + [X_GEN_TAC `t:real` THEN DISCH_TAC THEN REWRITE_TAC[] THEN + ASM_CASES_TAC `t < h` THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[REAL_ARITH `&0 <= t <=> t = &0 \/ &0 < t`] THEN + ASM_CASES_TAC `t = &0` THEN + ASM_REWRITE_TAC[REAL_LT_REFL; REAL_MUL_RZERO; SQRT_0] THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN REWRITE_TAC[REAL_MUL_RZERO] THEN + ASM_SIMP_TAC[REAL_POW_MUL; SQRT_POW_2; REAL_LT_IMP_LE] THEN + REAL_ARITH_TAC; + ALL_TAC] THEN + REWRITE_TAC[GSYM IN_REAL_INTERVAL; HAS_REAL_INTEGRAL_RESTRICT_UNIV] THEN + REWRITE_TAC[HAS_REAL_INTEGRAL_OPEN_INTERVAL] THEN + COND_CASES_TAC THENL + [ASM_MESON_TAC[REAL_INTERVAL_EQ_EMPTY; HAS_REAL_INTEGRAL_EMPTY]; + RULE_ASSUM_TAC(REWRITE_RULE[REAL_NOT_LT])] THEN + ABBREV_TAC `g = Arg(dropout 3 (w2:real^3) / dropout 3 (w1:real^3))` THEN + MP_TAC(ISPECL + [`\t. g / &6 * (inv (a pow 2) - &1) * t pow 3`; + `\t. g / &2 * (inv (a pow 2) - &1) * t pow 2`; + `&0`; `h:real`] REAL_FUNDAMENTAL_THEOREM_OF_CALCULUS) THEN + REWRITE_TAC[] THEN ANTS_TAC THENL + [ASM_REWRITE_TAC[] THEN + REPEAT STRIP_TAC THEN REAL_DIFF_TAC THEN + CONV_TAC NUM_REDUCE_CONV THEN CONV_TAC REAL_RING; + MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_TERM_TAC THEN + UNDISCH_TAC `&0 < a` THEN CONV_TAC REAL_FIELD]);; + +(* ------------------------------------------------------------------------- *) +(* Wedge of a conic cap. *) +(* ------------------------------------------------------------------------- *) + +let VOLUME_CONIC_CAP_WEDGE_WEAK = prove + (`!v0 v1:real^3 w1 w2 r a. + &0 < a /\ ~collinear {v0,v1,w1} /\ ~collinear {v0,v1,w2} + ==> bounded(conic_cap v0 v1 r a INTER wedge v0 v1 w1 w2) /\ + measurable(conic_cap v0 v1 r a INTER wedge v0 v1 w1 w2) /\ + measure(conic_cap v0 v1 r a INTER wedge v0 v1 w1 w2) = + if &1 <= a \/ r < &0 then &0 + else azim v0 v1 w1 w2 / &3 * (&1 - a) * r pow 3`, + REPEAT GEN_TAC THEN ASM_CASES_TAC `v1:real^3 = v0` THENL + [ASM_REWRITE_TAC[COLLINEAR_2; INSERT_AC]; STRIP_TAC] THEN + MATCH_MP_TAC(TAUT `a /\ b /\ (a /\ b ==> c) ==> a /\ b /\ c`) THEN + REPEAT CONJ_TAC THENL + [MATCH_MP_TAC BOUNDED_INTER THEN ASM_SIMP_TAC[VOLUME_CONIC_CAP_STRONG]; + MATCH_MP_TAC MEASURABLE_BOUNDED_INTER_OPEN THEN + ASM_SIMP_TAC[VOLUME_CONIC_CAP_STRONG; OPEN_WEDGE]; + ALL_TAC] THEN + REWRITE_TAC[conic_cap; rcone_gt; rconesgn; IN_ELIM_THM] THEN + REWRITE_TAC[ONCE_REWRITE_RULE[DIST_SYM] normball; GSYM ball] THEN + CONV_TAC(TOP_DEPTH_CONV let_CONV) THEN + POP_ASSUM_LIST(MP_TAC o end_itlist CONJ) THEN + GEOM_ORIGIN_TAC `v0:real^3` THEN + REWRITE_TAC[VECTOR_SUB_RZERO; REAL_MUL_LZERO; DIST_0; real_gt] THEN + GEOM_BASIS_MULTIPLE_TAC 3 `v1:real^3` THEN + X_GEN_TAC `b:real` THEN + ASM_CASES_TAC `b = &0` THEN ASM_REWRITE_TAC[VECTOR_MUL_LZERO] THEN + SIMP_TAC[COLLINEAR_SPECIAL_SCALE; WEDGE_SPECIAL_SCALE] THEN + ASM_REWRITE_TAC[VECTOR_MUL_EQ_0] THEN + DISCH_TAC THEN REPEAT GEN_TAC THEN STRIP_TAC THEN + ASM_CASES_TAC `&1 <= a` THEN ASM_REWRITE_TAC[] THENL + [SUBGOAL_THEN + `!y:real^3. ~(norm(y) * norm(b % basis 3:real^3) * a + < y dot (b % basis 3))` + (fun th -> REWRITE_TAC[th; EMPTY_GSPEC; INTER_EMPTY; MEASURE_EMPTY; + MEASURABLE_EMPTY; BOUNDED_EMPTY; CONVEX_EMPTY]) THEN + REWRITE_TAC[REAL_NOT_LT] THEN X_GEN_TAC `y:real^3` THEN + MATCH_MP_TAC(REAL_ARITH `abs(x) <= a ==> x <= a`) THEN + SIMP_TAC[DOT_RMUL; NORM_MUL; REAL_ABS_MUL; DOT_BASIS; NORM_BASIS; + DIMINDEX_3; ARITH] THEN + REWRITE_TAC[REAL_ARITH + `b * y <= n * (b * &1) * a <=> b * &1 * y <= b * a * n`] THEN + MATCH_MP_TAC REAL_LE_LMUL THEN REWRITE_TAC[REAL_ABS_POS] THEN + MATCH_MP_TAC REAL_LE_MUL2 THEN + ASM_SIMP_TAC[REAL_POS; REAL_ABS_POS; COMPONENT_LE_NORM; DIMINDEX_3; ARITH]; + ALL_TAC] THEN + RULE_ASSUM_TAC(REWRITE_RULE[REAL_NOT_LE]) THEN + SIMP_TAC[DOT_RMUL; NORM_MUL; REAL_ABS_NORM; DOT_BASIS; + DIMINDEX_3; ARITH; NORM_BASIS] THEN + ONCE_REWRITE_TAC[REAL_ARITH `n * x * a:real = x * n * a`] THEN + ASM_REWRITE_TAC[real_abs; REAL_MUL_RID] THEN + ASM_SIMP_TAC[REAL_MUL_RID; REAL_LT_LMUL_EQ; REAL_LT_MUL_EQ; NORM_POS_LT] THEN + ASM_SIMP_TAC[GSYM REAL_LT_RDIV_EQ; NORM_LT_SQUARE] THEN + ASM_SIMP_TAC[REAL_POW_DIV; REAL_POW_LT; REAL_LT_RDIV_EQ] THEN + REWRITE_TAC[INTER; REAL_MUL_LZERO; IN_BALL_0; IN_ELIM_THM] THEN + ASM_SIMP_TAC[VECTOR_MUL_EQ_0; BASIS_NONZERO; DIMINDEX_3; ARITH; + REAL_LT_IMP_NZ] THEN + COND_CASES_TAC THENL + [ASM_SIMP_TAC[NORM_ARITH `r < &0 ==> ~(norm x < r)`] THEN + REWRITE_TAC[EMPTY_GSPEC; MEASURE_EMPTY; MEASURABLE_EMPTY; + BOUNDED_EMPTY; CONVEX_EMPTY]; + RULE_ASSUM_TAC(ONCE_REWRITE_RULE[REAL_NOT_LT])] THEN + STRIP_TAC THEN MATCH_MP_TAC(INST_TYPE [`:2`,`:M`] FUBINI_SIMPLE_ALT) THEN + EXISTS_TAC `3` THEN ASM_REWRITE_TAC[DIMINDEX_2; DIMINDEX_3; ARITH] THEN + SUBGOAL_THEN `&0 < b` ASSUME_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN + ASM_SIMP_TAC[WEDGE_SPECIAL_SCALE; AZIM_SPECIAL_SCALE] THEN + ONCE_REWRITE_TAC[SET_RULE `{x | P x /\ x IN s} = {x | P x} INTER s`] THEN + ASM_SIMP_TAC[REAL_LT_LMUL_EQ; SLICE_INTER; DIMINDEX_2; + DIMINDEX_3; ARITH] THEN + RULE_ASSUM_TAC + (REWRITE_RULE[MATCH_MP COLLINEAR_SPECIAL_SCALE (ASSUME `~(b = &0)`)]) THEN + SUBGOAL_THEN `&0 < inv(a pow 2) - &1` ASSUME_TAC THENL + [REWRITE_TAC[REAL_SUB_LT] THEN MATCH_MP_TAC REAL_INV_1_LT THEN + ASM_SIMP_TAC[REAL_POW_1_LT; REAL_LT_IMP_LE; ARITH; REAL_POW_LT]; + ALL_TAC] THEN + SUBGOAL_THEN + `!t. slice 3 t {y:real^3 | norm y < r /\ norm y * a < y$3} = + if &0 < t /\ t < r + then ball(vec 0:real^2,min (sqrt(r pow 2 - t pow 2)) + (t * sqrt(inv(a pow 2) - &1))) + else {}` + (fun th -> ASM_SIMP_TAC[th; SLICE_SPECIAL_WEDGE]) + THENL + [REWRITE_TAC[EXTENSION] THEN + MAP_EVERY X_GEN_TAC [`t:real`; `z:real^2`] THEN + SIMP_TAC[SLICE_123; DIMINDEX_2; DIMINDEX_3; ARITH; IN_ELIM_THM; + VECTOR_3; DOT_3; GSYM DOT_2] THEN + ASM_CASES_TAC `&0 < t` THEN ASM_REWRITE_TAC[] THENL + [ALL_TAC; + REWRITE_TAC[NOT_IN_EMPTY; DE_MORGAN_THM] THEN DISJ2_TAC THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH + `~(&0 < t) ==> &0 <= a ==> ~(a < t)`)) THEN + ASM_SIMP_TAC[REAL_LE_MUL; NORM_POS_LE; REAL_LT_IMP_LE]] THEN + ASM_CASES_TAC `t < r` THEN ASM_REWRITE_TAC[] THENL + [ALL_TAC; + REWRITE_TAC[NOT_IN_EMPTY; DE_MORGAN_THM] THEN DISJ1_TAC THEN + REWRITE_TAC[NORM_LT_SQUARE; DE_MORGAN_THM] THEN DISJ2_TAC THEN + REWRITE_TAC[DOT_3; VECTOR_3] THEN + MATCH_MP_TAC(REAL_ARITH + `r <= t /\ &0 <= a /\ &0 <= b ==> ~(a + b + t < r)`) THEN + REWRITE_TAC[REAL_LE_SQUARE; REAL_POW_2] THEN + MATCH_MP_TAC REAL_LE_MUL2 THEN ASM_REAL_ARITH_TAC] THEN + REWRITE_TAC[IN_BALL_0; REAL_LT_MIN] THEN + ASM_SIMP_TAC[GSYM REAL_LT_RDIV_EQ] THEN REWRITE_TAC[NORM_LT_SQUARE] THEN + SUBGOAL_THEN `&0 < r` ASSUME_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `t pow 2 < r pow 2` ASSUME_TAC THENL + [MATCH_MP_TAC REAL_POW_LT2 THEN REWRITE_TAC[ARITH] THEN + ASM_REAL_ARITH_TAC; + ALL_TAC] THEN + ASM_SIMP_TAC[REAL_LT_DIV; SQRT_POS_LT; REAL_LT_MUL; REAL_SUB_LT; + SQRT_POW_2; REAL_LT_IMP_LE; REAL_POW_MUL] THEN + REWRITE_TAC[DOT_2; DOT_3; VECTOR_3] THEN + ONCE_REWRITE_TAC[REAL_ARITH `a + b + c < d <=> a + b < d - c`] THEN + BINOP_TAC THEN AP_TERM_TAC THEN + UNDISCH_TAC `&0 < a` THEN CONV_TAC REAL_FIELD; + ALL_TAC] THEN + GEN_REWRITE_TAC (LAND_CONV o TOP_DEPTH_CONV) [COND_RATOR; COND_RAND] THEN + GEN_REWRITE_TAC (RAND_CONV o RATOR_CONV o LAND_CONV o TOP_DEPTH_CONV) + [COND_RATOR; COND_RAND] THEN + REWRITE_TAC[INTER_EMPTY; MEASURABLE_EMPTY; MEASURE_EMPTY] THEN + REWRITE_TAC[INTER; IN_BALL_0; IN_ELIM_THM] THEN + RULE_ASSUM_TAC(REWRITE_RULE[COLLINEAR_BASIS_3]) THEN + ASM_SIMP_TAC[REWRITE_RULE[HAS_MEASURE_MEASURABLE_MEASURE] + HAS_MEASURE_OPEN_SECTOR_LT_GEN] THEN + REWRITE_TAC[COND_ID] THEN + ASM_SIMP_TAC[REAL_LE_MIN; SQRT_POS_LE; REAL_LT_IMP_LE; REAL_LE_MUL; + REAL_POW_LE2; ARITH; REAL_SUB_LE; REAL_LT_MUL; SQRT_POS_LT] THEN + REWRITE_TAC[GSYM IN_REAL_INTERVAL; HAS_REAL_INTEGRAL_RESTRICT_UNIV] THEN + REWRITE_TAC[HAS_REAL_INTEGRAL_OPEN_INTERVAL] THEN + REWRITE_TAC[NORM_POW_2; DOT_3; VECTOR_3; DOT_2] THEN + ASM_SIMP_TAC[AZIM_ARG; COLLINEAR_BASIS_3] THEN + ONCE_REWRITE_TAC[REAL_ARITH + `(&1 - a) * az / &3 * r pow 3 = + az / &6 * (inv (a pow 2) - &1) * (a * r) pow 3 + + (az * &1 / &3 * (&1 - a) * r pow 3 - + az / &6 * (inv (a pow 2) - &1) * (a * r) pow 3)`] THEN + MATCH_MP_TAC HAS_REAL_INTEGRAL_COMBINE THEN + EXISTS_TAC `a * r:real` THEN + REWRITE_TAC[REAL_ARITH `a * r <= r <=> &0 <= r * (&1 - a)`] THEN + ASM_SIMP_TAC[REAL_LE_MUL; REAL_SUB_LE; REAL_LT_IMP_LE] THEN + ABBREV_TAC `k = Arg(dropout 3 (w2:real^3) / dropout 3 (w1:real^3))` THEN + CONJ_TAC THENL + [MATCH_MP_TAC HAS_REAL_INTEGRAL_EQ THEN EXISTS_TAC + `\t. k * t pow 2 * (inv(a pow 2) - &1) / &2` THEN + CONJ_TAC THENL + [X_GEN_TAC `t:real` THEN REWRITE_TAC[IN_REAL_INTERVAL] THEN + STRIP_TAC THEN AP_TERM_TAC THEN + SUBGOAL_THEN `t pow 2 * (inv(a pow 2) - &1) <= r pow 2 - t pow 2` + ASSUME_TAC THENL + [REWRITE_TAC[REAL_ARITH `t * (a - &1) <= r - t <=> t * a <= r`] THEN + ASM_SIMP_TAC[GSYM real_div; REAL_LE_LDIV_EQ; REAL_POW_LT] THEN + REWRITE_TAC[GSYM REAL_POW_MUL] THEN MATCH_MP_TAC REAL_POW_LE2 THEN + ASM_REAL_ARITH_TAC; + ALL_TAC] THEN + SUBGOAL_THEN `t * sqrt(inv(a pow 2) - &1) <= sqrt(r pow 2 - t pow 2)` + (fun th -> SIMP_TAC[th; REAL_ARITH `a <= b ==> min b a = a`]) + THENL + [MATCH_MP_TAC REAL_POW_LE2_REV THEN EXISTS_TAC `2` THEN + REWRITE_TAC[ARITH] THEN + SUBGOAL_THEN `&0 <= r pow 2 - t pow 2` ASSUME_TAC THENL + [FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH + `a <= x ==> &0 <= a ==> &0 <= x`)) THEN + ASM_SIMP_TAC[REAL_POW_2; REAL_LE_MUL; REAL_LE_SQUARE; REAL_LT_IMP_LE]; + ASM_SIMP_TAC[SQRT_POS_LE; REAL_POW_MUL; SQRT_POW_2; + REAL_LT_IMP_LE]]; + ASM_SIMP_TAC[REAL_POW_MUL; SQRT_POW_2; SQRT_POW_2; REAL_LT_IMP_LE] THEN + REAL_ARITH_TAC]; + MP_TAC(ISPECL + [`\t. k / &6 * (inv (a pow 2) - &1) * t pow 3`; + `\t. k * t pow 2 * (inv (a pow 2) - &1) / &2`; + `&0`; `a * r:real`] REAL_FUNDAMENTAL_THEOREM_OF_CALCULUS) THEN + ASM_SIMP_TAC[REAL_LE_MUL; REAL_LT_IMP_LE] THEN ANTS_TAC THENL + [ASM_REWRITE_TAC[] THEN + REPEAT STRIP_TAC THEN REAL_DIFF_TAC THEN + CONV_TAC NUM_REDUCE_CONV THEN CONV_TAC REAL_RING; + MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_TERM_TAC THEN + UNDISCH_TAC `&0 < a` THEN CONV_TAC REAL_FIELD]]; + MATCH_MP_TAC HAS_REAL_INTEGRAL_EQ THEN EXISTS_TAC + `\t:real. k * (r pow 2 - t pow 2) / &2` THEN + CONJ_TAC THENL + [X_GEN_TAC `t:real` THEN REWRITE_TAC[IN_REAL_INTERVAL] THEN + STRIP_TAC THEN AP_TERM_TAC THEN + SUBGOAL_THEN `&0 <= t` ASSUME_TAC THENL + [MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC `a * r:real` THEN + ASM_SIMP_TAC[REAL_LE_MUL; REAL_LT_IMP_LE]; + ALL_TAC] THEN + MATCH_MP_TAC(REAL_ARITH + `a <= b /\ a pow 2 = x ==> x / &2 = (min a b pow 2) / &2`) THEN + SUBGOAL_THEN `&0 <= r pow 2 - t pow 2` ASSUME_TAC THENL + [REWRITE_TAC[GSYM REAL_LE_SQUARE_ABS; REAL_SUB_LE] THEN + ASM_REAL_ARITH_TAC; + ALL_TAC] THEN + ASM_SIMP_TAC[SQRT_POW_2] THEN MATCH_MP_TAC REAL_POW_LE2_REV THEN + EXISTS_TAC `2` THEN REWRITE_TAC[ARITH] THEN + ASM_SIMP_TAC[SQRT_POW_2; REAL_POW_MUL; REAL_LE_MUL; SQRT_POS_LT; + REAL_LT_MUL; REAL_LT_IMP_LE; SQRT_POS_LE] THEN + REWRITE_TAC[REAL_ARITH `r - t <= t * (a - &1) <=> r <= t * a`] THEN + REWRITE_TAC[REAL_INV_POW; GSYM REAL_POW_MUL] THEN + MATCH_MP_TAC REAL_POW_LE2 THEN + ASM_SIMP_TAC[GSYM real_div; REAL_LE_RDIV_EQ] THEN + ASM_REAL_ARITH_TAC; + MP_TAC(ISPECL + [`\t. k / &2 * (r pow 2 * t - t pow 3 / &3)`; + `\t. k * (r pow 2 - t pow 2) / &2`; + `a * r:real`; `r:real`] REAL_FUNDAMENTAL_THEOREM_OF_CALCULUS) THEN + ASM_SIMP_TAC[REAL_LE_MUL; REAL_LT_IMP_LE] THEN ANTS_TAC THENL + [ASM_REWRITE_TAC[REAL_ARITH `a * r <= r <=> &0 <= r * (&1 - a)`] THEN + ASM_SIMP_TAC[REAL_LE_MUL; REAL_LT_IMP_LE; REAL_SUB_LE] THEN + REPEAT STRIP_TAC THEN REAL_DIFF_TAC THEN + CONV_TAC NUM_REDUCE_CONV THEN CONV_TAC REAL_RING; + MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_TERM_TAC THEN + UNDISCH_TAC `&0 < a` THEN CONV_TAC REAL_FIELD]]]);; + +let BOUNDED_CONIC_CAP_WEDGE = prove + (`!v0 v1:real^3 w1 w2 r a. + bounded(conic_cap v0 v1 r a INTER wedge v0 v1 w1 w2)`, + REPEAT GEN_TAC THEN MATCH_MP_TAC BOUNDED_SUBSET THEN + EXISTS_TAC `conic_cap (v0:real^3) v1 r a` THEN + REWRITE_TAC[BOUNDED_CONIC_CAP] THEN SET_TAC[]);; + +let MEASURABLE_CONIC_CAP_WEDGE = prove + (`!v0 v1:real^3 w1 w2 r a. + measurable(conic_cap v0 v1 r a INTER wedge v0 v1 w1 w2)`, + REPEAT GEN_TAC THEN MATCH_MP_TAC MEASURABLE_BOUNDED_INTER_OPEN THEN + REWRITE_TAC[BOUNDED_CONIC_CAP; MEASURABLE_CONIC_CAP; OPEN_WEDGE]);; + +let VOLUME_CONIC_CAP_COMPL = prove + (`!v0 v1:real^3 w1 w2 r a. + &0 <= r + ==> measure(conic_cap v0 v1 r a INTER wedge v0 v1 w1 w2) + + measure(conic_cap v0 v1 r (--a) INTER wedge v0 v1 w1 w2) = + azim v0 v1 w1 w2 * &2 * r pow 3 / &3`, + let lemma = prove + (`!f:real^N->real^N s t t' u. + measurable(s) /\ measurable(t) /\ measurable(u) /\ + orthogonal_transformation f /\ + s SUBSET u /\ t' SUBSET u /\ s INTER t' = {} /\ + negligible(u DIFF (s UNION t')) /\ + ((!y. ?x. f x = y) ==> IMAGE f t = t') + ==> measure s + measure t = measure u`, + REPEAT GEN_TAC THEN + ASM_CASES_TAC `orthogonal_transformation(f:real^N->real^N)` THEN + ASM_SIMP_TAC[ORTHOGONAL_TRANSFORMATION_SURJECTIVE] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC EQ_TRANS THEN + EXISTS_TAC + `measure(s:real^N->bool) + measure(t':real^N->bool)` THEN + CONJ_TAC THENL [ASM_MESON_TAC[MEASURE_ORTHOGONAL_IMAGE_EQ]; ALL_TAC] THEN + W(MP_TAC o PART_MATCH (rhs o rand) MEASURE_DISJOINT_UNION o + lhand o snd) THEN + ASM_REWRITE_TAC[DISJOINT] THEN ANTS_TAC THENL + [ASM_MESON_TAC[MEASURABLE_LINEAR_IMAGE; ORTHOGONAL_TRANSFORMATION_LINEAR]; + DISCH_THEN(SUBST1_TAC o SYM)] THEN + MATCH_MP_TAC MEASURE_NEGLIGIBLE_SYMDIFF THEN ASM_REWRITE_TAC[] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + NEGLIGIBLE_SUBSET)) THEN + REPEAT(POP_ASSUM MP_TAC) THEN SET_TAC[]) in + REWRITE_TAC[conic_cap; rcone_gt; NORMBALL_BALL; rconesgn] THEN + GEOM_ORIGIN_TAC `v0:real^3` THEN + REWRITE_TAC[VECTOR_SUB_RZERO; DIST_0; real_gt] THEN + GEOM_BASIS_MULTIPLE_TAC 3 `v1:real^3` THEN + X_GEN_TAC `v1:real` THEN + GEN_REWRITE_TAC LAND_CONV [REAL_ARITH `&0 <= x <=> x = &0 \/ &0 < x`] THEN + STRIP_TAC THENL + [ASM_SIMP_TAC[VECTOR_MUL_LZERO; WEDGE_DEGENERATE; AZIM_DEGENERATE] THEN + REWRITE_TAC[INTER_EMPTY; MEASURE_EMPTY] THEN REAL_ARITH_TAC; + ALL_TAC] THEN + ASM_SIMP_TAC[GSYM VOLUME_BALL_WEDGE] THEN REPEAT STRIP_TAC THEN + ASM_CASES_TAC `collinear {vec 0:real^3,v1 % basis 3,w1}` THENL + [ASM_SIMP_TAC[WEDGE_DEGENERATE; AZIM_DEGENERATE] THEN + REWRITE_TAC[INTER_EMPTY; MEASURE_EMPTY] THEN REAL_ARITH_TAC; + ALL_TAC] THEN + ASM_SIMP_TAC[GSYM VOLUME_BALL_WEDGE] THEN REPEAT STRIP_TAC THEN + ASM_CASES_TAC `collinear {vec 0:real^3,v1 % basis 3,w2}` THENL + [ASM_SIMP_TAC[WEDGE_DEGENERATE; AZIM_DEGENERATE] THEN + REWRITE_TAC[INTER_EMPTY; MEASURE_EMPTY] THEN REAL_ARITH_TAC; + ALL_TAC] THEN + ASM_SIMP_TAC[WEDGE_SPECIAL_SCALE] THEN + MAP_EVERY UNDISCH_TAC + [`~collinear{vec 0:real^3,v1 % basis 3,w1}`; + `~collinear{vec 0:real^3,v1 % basis 3,w2}`] THEN + ASM_SIMP_TAC[COLLINEAR_SPECIAL_SCALE] THEN REPEAT DISCH_TAC THEN + REWRITE_TAC[NORM_MUL; DOT_RMUL] THEN + ASM_SIMP_TAC[REAL_LT_LMUL_EQ; REAL_ARITH + `&0 < v1 ==> n * (abs v1 * y) * a = v1 * n * y * a`] THEN + MATCH_MP_TAC lemma THEN + MP_TAC(ISPECL + [`vec 0:real^3`; `basis 3:real^3`; `w1:real^3`; `w2:real^3`; + `r:real`; `a:real`] MEASURABLE_CONIC_CAP_WEDGE) THEN + MP_TAC(ISPECL + [`vec 0:real^3`; `basis 3:real^3`; `w1:real^3`; `w2:real^3`; + `r:real`; `--a:real`] MEASURABLE_CONIC_CAP_WEDGE) THEN + REWRITE_TAC[conic_cap; rcone_gt; NORMBALL_BALL; rconesgn] THEN + REWRITE_TAC[VECTOR_SUB_RZERO; DIST_0; real_gt] THEN + REPEAT DISCH_TAC THEN ASM_REWRITE_TAC[MEASURABLE_BALL_WEDGE] THEN + SIMP_TAC[NORM_BASIS; DOT_BASIS; DIMINDEX_3; ARITH; REAL_MUL_LID] THEN + EXISTS_TAC `(\x. vector[x$1; x$2; --(x$3)]):real^3->real^3` THEN + EXISTS_TAC `(ball(vec 0,r) INTER {x | norm x * a > x$3}) INTER + wedge (vec 0:real^3) (basis 3) w1 w2` THEN + CONJ_TAC THENL + [REWRITE_TAC[ORTHOGONAL_TRANSFORMATION; linear] THEN + REWRITE_TAC[CART_EQ; DIMINDEX_3; FORALL_3; VECTOR_3; vector_norm; DOT_3; + VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT] THEN + REPEAT(GEN_TAC ORELSE CONJ_TAC ORELSE AP_TERM_TAC) THEN + REAL_ARITH_TAC; + ALL_TAC] THEN + CONJ_TAC THENL [SET_TAC[]; ALL_TAC] THEN + CONJ_TAC THENL [SET_TAC[]; ALL_TAC] THEN + CONJ_TAC THENL + [REWRITE_TAC[EXTENSION; NOT_IN_EMPTY; IN_INTER; IN_ELIM_THM; real_gt] THEN + MESON_TAC[REAL_LT_ANTISYM]; + ALL_TAC] THEN + CONJ_TAC THENL + [MATCH_MP_TAC NEGLIGIBLE_SUBSET THEN + EXISTS_TAC `rcone_eq (vec 0:real^3) (basis 3) a` THEN + SIMP_TAC[NEGLIGIBLE_RCONE_EQ; BASIS_NONZERO; DIMINDEX_3; ARITH] THEN + REWRITE_TAC[SUBSET; rcone_eq; rconesgn; VECTOR_SUB_RZERO; DIST_0] THEN + SIMP_TAC[DOT_BASIS; NORM_BASIS; DIMINDEX_3; ARITH] THEN + REWRITE_TAC[IN_DIFF; IN_ELIM_THM; IN_INTER; IN_UNION] THEN + GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + ASM_REWRITE_TAC[] THEN REAL_ARITH_TAC; + ALL_TAC] THEN + REWRITE_TAC[] THEN DISCH_TAC THEN MATCH_MP_TAC SURJECTIVE_IMAGE_EQ THEN + ASM_REWRITE_TAC[] THEN + REWRITE_TAC[IN_INTER; IN_BALL_0; IN_ELIM_THM; VECTOR_3] THEN + X_GEN_TAC `x:real^3` THEN + SUBGOAL_THEN `norm(vector [x$1; x$2; --(x$3)]:real^3) = norm(x:real^3)` + SUBST1_TAC THENL + [REWRITE_TAC[NORM_EQ; DOT_3; VECTOR_3] THEN REAL_ARITH_TAC; + ALL_TAC] THEN + REWRITE_TAC[REAL_ARITH `n * a > --x <=> n * --a < x`] THEN + MATCH_MP_TAC(TAUT `(a ==> (b <=> b')) ==> (a /\ b <=> a /\ b')`) THEN + STRIP_TAC THEN + REWRITE_TAC[COLLINEAR_BASIS_3; wedge; AZIM_ARG] THEN + REWRITE_TAC[IN_ELIM_THM] THEN + SUBGOAL_THEN `(dropout 3 :real^3->real^2) (vector [x$1; x$2; --(x$3)]) = + (dropout 3 :real^3->real^2) x` + (fun th -> REWRITE_TAC[th]) THEN + SIMP_TAC[CART_EQ; DIMINDEX_2; FORALL_2; dropout; LAMBDA_BETA; ARITH; + VECTOR_3]);; + +let VOLUME_CONIC_CAP_WEDGE_MEDIUM = prove + (`!v0 v1:real^3 w1 w2 r a. + &0 <= a /\ ~collinear {v0,v1,w1} /\ ~collinear {v0,v1,w2} + ==> bounded(conic_cap v0 v1 r a INTER wedge v0 v1 w1 w2) /\ + measurable(conic_cap v0 v1 r a INTER wedge v0 v1 w1 w2) /\ + measure(conic_cap v0 v1 r a INTER wedge v0 v1 w1 w2) = + if &1 < abs a \/ r < &0 then &0 + else azim v0 v1 w1 w2 / &3 * (&1 - a) * r pow 3`, + REWRITE_TAC[BOUNDED_CONIC_CAP_WEDGE; MEASURABLE_CONIC_CAP_WEDGE] THEN + REPEAT STRIP_TAC THEN FIRST_X_ASSUM(DISJ_CASES_TAC o MATCH_MP (REAL_ARITH + `&0 <= a ==> &0 < a \/ a = &0`)) + THENL + [ASM_SIMP_TAC[VOLUME_CONIC_CAP_WEDGE_WEAK] THEN + REWRITE_TAC[REAL_LE_LT] THEN + ASM_CASES_TAC `a = &1` THEN ASM_REWRITE_TAC[] THEN ASM_REAL_ARITH_TAC; + ALL_TAC] THEN + ASM_REWRITE_TAC[] THEN CONV_TAC REAL_RAT_REDUCE_CONV THEN + COND_CASES_TAC THENL + [REWRITE_TAC[conic_cap; NORMBALL_BALL] THEN + SUBGOAL_THEN `ball(v0:real^3,r) = {}` + (fun th -> SIMP_TAC[th; INTER_EMPTY; MEASURE_EMPTY]) THEN + REWRITE_TAC[BALL_EQ_EMPTY] THEN ASM_REAL_ARITH_TAC; + MP_TAC(ISPECL [`v0:real^3`; `v1:real^3`; `w1:real^3`; `w2:real^3`; + `r:real`; `&0`] VOLUME_CONIC_CAP_COMPL) THEN + REWRITE_TAC[REAL_NEG_0] THEN ASM_REAL_ARITH_TAC]);; + +let VOLUME_CONIC_CAP_WEDGE = prove + (`!v0 v1:real^3 w1 w2 r a. + ~collinear {v0,v1,w1} /\ ~collinear {v0,v1,w2} + ==> bounded(conic_cap v0 v1 r a INTER wedge v0 v1 w1 w2) /\ + measurable(conic_cap v0 v1 r a INTER wedge v0 v1 w1 w2) /\ + measure(conic_cap v0 v1 r a INTER wedge v0 v1 w1 w2) = + if &1 < a \/ r < &0 then &0 + else azim v0 v1 w1 w2 / &3 * (&1 - max a (-- &1)) * r pow 3`, + REWRITE_TAC[BOUNDED_CONIC_CAP_WEDGE; MEASURABLE_CONIC_CAP_WEDGE] THEN + REPEAT STRIP_TAC THEN + ASM_CASES_TAC `&0 <= a` THEN + ASM_SIMP_TAC[VOLUME_CONIC_CAP_WEDGE_MEDIUM; + REAL_ARITH `&0 <= a ==> abs a = a /\ max a (-- &1) = a`] THEN + MP_TAC(ISPECL [`v0:real^3`; `v1:real^3`; `w1:real^3`; `w2:real^3`; + `r:real`; `--a:real`] VOLUME_CONIC_CAP_WEDGE_MEDIUM) THEN + ASM_REWRITE_TAC[] THEN ANTS_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN + STRIP_TAC THEN + MP_TAC(ISPECL [`v0:real^3`; `v1:real^3`; `w1:real^3`; `w2:real^3`; + `r:real`; `a:real`] VOLUME_CONIC_CAP_COMPL) THEN + ASM_CASES_TAC `r < &0` THENL + [REWRITE_TAC[conic_cap; NORMBALL_BALL] THEN + SUBGOAL_THEN `ball(v0:real^3,r) = {}` + (fun th -> SIMP_TAC[th; INTER_EMPTY; MEASURE_EMPTY]) THEN + REWRITE_TAC[BALL_EQ_EMPTY] THEN ASM_REAL_ARITH_TAC; + ALL_TAC] THEN + ASM_REWRITE_TAC[GSYM REAL_NOT_LT; REAL_ABS_NEG] THEN + ASM_SIMP_TAC[REAL_ARITH `~(&0 <= a) ==> ~(&1 < a) /\ abs a = --a`] THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[] THENL + [ASM_SIMP_TAC[REAL_ARITH `&1 < --a ==> max a (-- &1) = -- &1`] THEN + REAL_ARITH_TAC; + ASM_SIMP_TAC[REAL_ARITH `~(&1 < --a) ==> max a (-- &1) = a`] THEN + REAL_ARITH_TAC]);; + +(* ------------------------------------------------------------------------- *) +(* Precise formulation of Flyspeck volume properties. *) +(* ------------------------------------------------------------------------- *) + +(*** Might be preferable to switch + *** + *** normball z r -> ball(z,r) + *** rect a b -> interval(a,b) + *** + *** to fit existing libraries. But I left this alone for now, + *** to be absolutely sure I didn't introduce new errors. + *** I also maintain + *** + *** NULLSET -> negligible + *** vol -> measure + *** + *** as interface maps for the real^3 case. + ***) + +let cone = new_definition `cone v S:real^A->bool = affsign sgn_ge {v} S`;; + +(*** JRH: should we exclude v for S = {}? Make it always open ***) + +let cone0 = new_definition `cone0 v S:real^A->bool = affsign sgn_gt {v} S`;; + +(*** JRH changed from cone to cone0 ***) + +let solid_triangle = new_definition + `solid_triangle v0 S r = normball v0 r INTER cone0 v0 S`;; + +let rect = new_definition + `rect (a:real^3) (b:real^3) = + {(v:real^3) | !i. (a$i < v$i /\ v$i < b$i )}`;; + +let RECT_INTERVAL = prove + (`!a b. rect a b = interval(a,b)`, + REWRITE_TAC[rect; EXTENSION; IN_INTERVAL; IN_ELIM_THM] THEN + MESON_TAC[FINITE_INDEX_INRANGE]);; + +let RCONE_GE_GT = prove + (`rcone_ge z w h = + rcone_gt z w h UNION + { x | (x - z) dot (w - z) = norm(x - z) * norm(w - z) * h}`, + REWRITE_TAC[rcone_ge; rcone_gt; rconesgn] THEN + REWRITE_TAC[dist; EXTENSION; IN_UNION; NORM_SUB; IN_ELIM_THM] THEN + REAL_ARITH_TAC);; + +let RCONE_GT_GE = prove + (`rcone_gt z w h = + rcone_ge z w h DIFF + { x | (x - z) dot (w - z) = norm(x - z) * norm(w - z) * h}`, + REWRITE_TAC[rcone_ge; rcone_gt; rconesgn] THEN + REWRITE_TAC[dist; EXTENSION; IN_DIFF; NORM_SUB; IN_ELIM_THM] THEN + REAL_ARITH_TAC);; + +override_interface("NULLSET",`negligible:(real^3->bool)->bool`);; +override_interface("vol",`measure:(real^3->bool)->real`);; + +let is_sphere= new_definition + `is_sphere x=(?(v:real^3)(r:real). (r> &0)/\ (x={w:real^3 | norm (w-v)= r}))`;; + +let c_cone = new_definition + `c_cone (v,w:real^3, r:real)= + {x:real^3 | ((x-v) dot w = norm (x-v)* norm w* r)}`;; + +(*** JRH added the condition ~(w = 0), or the cone is all of space ***) + +let circular_cone =new_definition + `circular_cone (V:real^3-> bool)= + (? (v,w:real^3)(r:real). ~(w = vec 0) /\ V = c_cone (v,w,r))`;; + +let NULLSET_RULES = prove + (`(!P. ((plane P)\/ (is_sphere P) \/ (circular_cone P)) ==> NULLSET P) /\ + (!(s:real^3->bool) t. (NULLSET s /\ NULLSET t) ==> NULLSET (s UNION t))`, + SIMP_TAC[NEGLIGIBLE_UNION] THEN + X_GEN_TAC `s:real^3->bool` THEN STRIP_TAC THENL + [MATCH_MP_TAC COPLANAR_IMP_NEGLIGIBLE THEN + SIMP_TAC[COPLANAR; DIMINDEX_3; ARITH] THEN ASM_MESON_TAC[SUBSET_REFL]; + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [is_sphere]) THEN + STRIP_TAC THEN ASM_REWRITE_TAC[GSYM dist] THEN + ONCE_REWRITE_TAC[DIST_SYM] THEN + REWRITE_TAC[REWRITE_RULE[sphere] NEGLIGIBLE_SPHERE]; + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [circular_cone]) THEN + REWRITE_TAC[EXISTS_PAIRED_THM; c_cone] THEN STRIP_TAC THEN + ASM_REWRITE_TAC[] THEN + MP_TAC(ISPECL [`w + v:real^3`; `v:real^3`; `r:real`] + NEGLIGIBLE_RCONE_EQ) THEN + ASM_REWRITE_TAC[rcone_eq; rconesgn] THEN + REWRITE_TAC[dist; VECTOR_ARITH `(w + v) - v:real^N = w`] THEN + ASM_REWRITE_TAC[VECTOR_ARITH `w + v:real^N = v <=> w = vec 0`]]);; + +(*** JRH added &0 < a for frustum; otherwise it's in general unbounded ***) + +let primitive = new_definition `primitive (C:real^3->bool) = + ((?v0 v1 v2 v3 r. (C = solid_triangle v0 {v1,v2,v3} r)) \/ + (?v0 v1 v2 v3. (C = conv0 {v0,v1,v2,v3})) \/ + (?v0 v1 v2 v3 h a. &0 < a /\ + (C = frustt v0 v1 h a INTER wedge v0 v1 v2 v3)) \/ + (?v0 v1 v2 v3 r c. (C = conic_cap v0 v1 r c INTER wedge v0 v1 v2 v3)) \/ + (?a b. (C = rect a b)) \/ + (?t r. (C = ellipsoid t r)) \/ + (?v0 v1 v2 v3 r. (C = normball v0 r INTER wedge v0 v1 v2 v3)))`;; + +let MEASURABLE_RULES = prove + (`(!C. primitive C ==> measurable C) /\ + (!Z. NULLSET Z ==> measurable Z) /\ + (!X t. measurable X ==> (measurable (IMAGE (scale t) X))) /\ + (!X v. measurable X ==> (measurable (IMAGE ((+) v) X))) /\ + (!(s:real^3->bool) t. (measurable s /\ measurable t) + ==> measurable (s UNION t)) /\ + (!(s:real^3->bool) t. (measurable s /\ measurable t) + ==> measurable (s INTER t)) /\ + (!(s:real^3->bool) t. (measurable s /\ measurable t) + ==> measurable (s DIFF t))`, + SIMP_TAC[MEASURABLE_UNION; MEASURABLE_INTER; MEASURABLE_DIFF] THEN + REWRITE_TAC[REWRITE_RULE[ETA_AX] MEASURABLE_TRANSLATION] THEN + SIMP_TAC[GSYM HAS_MEASURE_0; HAS_MEASURE_MEASURABLE_MEASURE] THEN + CONJ_TAC THENL + [ALL_TAC; + MAP_EVERY X_GEN_TAC [`X:real^3->bool`; `t:real^3`] THEN + REWRITE_TAC[HAS_MEASURE_MEASURE] THEN + DISCH_THEN(MP_TAC o MATCH_MP HAS_MEASURE_STRETCH) THEN + DISCH_THEN(MP_TAC o SPEC `\i. (t:real^3)$i`) THEN + REWRITE_TAC[HAS_MEASURE_MEASURABLE_MEASURE] THEN + DISCH_THEN(MP_TAC o CONJUNCT1) THEN MATCH_MP_TAC EQ_IMP THEN + AP_TERM_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN + SIMP_TAC[FUN_EQ_THM; scale; CART_EQ; LAMBDA_BETA; + DIMINDEX_3; VECTOR_3; FORALL_3]] THEN + X_GEN_TAC `C:real^3->bool` THEN REWRITE_TAC[primitive] THEN + REWRITE_TAC[NORMBALL_BALL; RECT_INTERVAL] THEN + DISCH_THEN(REPEAT_TCL DISJ_CASES_THEN MP_TAC) THEN + REWRITE_TAC[LEFT_IMP_EXISTS_THM] THENL + [REPEAT STRIP_TAC THEN + ASM_REWRITE_TAC[solid_triangle; NORMBALL_BALL; cone0; GSYM aff_gt_def] THEN + REWRITE_TAC[MEASURABLE_BALL_AFF_GT]; + REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC MEASURABLE_CONV0 THEN MATCH_MP_TAC FINITE_IMP_BOUNDED THEN + REWRITE_TAC[FINITE_INSERT; FINITE_EMPTY]; + MAP_EVERY X_GEN_TAC + [`v0:real^3`; `v1:real^3`; `v2:real^3`; `v3:real^3`; + `h:real`; `a:real`] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC SUBST1_TAC) THEN + ASM_CASES_TAC `collinear {v0:real^3, v1, v2}` THENL + [ASM_SIMP_TAC[WEDGE_DEGENERATE; INTER_EMPTY; MEASURABLE_EMPTY]; + ALL_TAC] THEN + ASM_CASES_TAC `collinear {v0:real^3, v1, v3}` THENL + [ASM_SIMP_TAC[WEDGE_DEGENERATE; INTER_EMPTY; MEASURABLE_EMPTY]; + ALL_TAC] THEN + ASM_SIMP_TAC[VOLUME_FRUSTT_WEDGE]; + REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC MEASURABLE_BOUNDED_INTER_OPEN THEN + REWRITE_TAC[MEASURABLE_CONIC_CAP; BOUNDED_CONIC_CAP; OPEN_WEDGE]; + SIMP_TAC[MEASURABLE_INTERVAL]; + SIMP_TAC[MEASURABLE_ELLIPSOID]; + SIMP_TAC[MEASURABLE_BALL_WEDGE]]);; + +let vol_solid_triangle = new_definition `vol_solid_triangle v0 v1 v2 v3 r = + let a123 = dihV v0 v1 v2 v3 in + let a231 = dihV v0 v2 v3 v1 in + let a312 = dihV v0 v3 v1 v2 in + (a123 + a231 + a312 - pi)*(r pow 3)/(&3)`;; + +let vol_frustt_wedge = new_definition `vol_frustt_wedge v0 v1 v2 v3 h a = + (azim v0 v1 v2 v3)*(h pow 3)*(&1/(a*a) - &1)/(&6)`;; + +let vol_conic_cap_wedge = new_definition `vol_conic_cap_wedge v0 v1 v2 v3 r c = + (azim v0 v1 v2 v3)*(&1 - c)*(r pow 3)/(&3)`;; + +(*** JRH corrected delta_x x12 x13 x14 x34 x24 x34 ***) +(*** to delta_x x12 x13 x14 x34 x24 x23 ***) + +let vol_conv = new_definition `vol_conv v1 v2 v3 v4 = + let x12 = dist(v1,v2) pow 2 in + let x13 = dist(v1,v3) pow 2 in + let x14 = dist(v1,v4) pow 2 in + let x23 = dist(v2,v3) pow 2 in + let x24 = dist(v2,v4) pow 2 in + let x34 = dist(v3,v4) pow 2 in + sqrt(delta_x x12 x13 x14 x34 x24 x23)/(&12)`;; + +let vol_rect = new_definition `vol_rect a b = + if (a$1 < b$1) /\ (a$2 < b$2) /\ (a$3 < b$3) then + (b$3-a$3)*(b$2-a$2)*(b$1-a$1) else &0`;; + +let vol_ball_wedge = new_definition `vol_ball_wedge v0 v1 v2 v3 r = + (azim v0 v1 v2 v3)*(&2)*(r pow 3)/(&3)`;; + +let SDIFF = new_definition `SDIFF X Y = (X DIFF Y) UNION (Y DIFF X)`;; + +(*** JRH added the hypothesis "measurable" to the first one ***) +(*** Could change the definition to make this hold anyway ***) + +(*** JRH changed solid triangle hypothesis to ~coplanar{...} ***) +(*** since the current condition is not enough in general ***) + +let volume_props = prove + (`(!C. measurable C ==> vol C >= &0) /\ + (!Z. NULLSET Z ==> (vol Z = &0)) /\ + (!X Y. measurable X /\ measurable Y /\ NULLSET (SDIFF X Y) + ==> (vol X = vol Y)) /\ + (!X t. (measurable X) /\ (measurable (IMAGE (scale t) X)) + ==> (vol (IMAGE (scale t) X) = abs(t$1 * t$2 * t$3)*vol(X))) /\ + (!X v. measurable X ==> (vol (IMAGE ((+) v) X) = vol X)) /\ + (!v0 v1 v2 v3 r. (r > &0) /\ ~coplanar{v0,v1,v2,v3} + ==> vol (solid_triangle v0 {v1,v2,v3} r) = + vol_solid_triangle v0 v1 v2 v3 r) /\ + (!v0 v1 v2 v3. vol(conv0 {v0,v1,v2,v3}) = vol_conv v0 v1 v2 v3) /\ + (!v0 v1 v2 v3 h a. ~(collinear {v0,v1,v2}) /\ ~(collinear {v0,v1,v3}) /\ + (h >= &0) /\ (a > &0) /\ (a <= &1) + ==> vol(frustt v0 v1 h a INTER wedge v0 v1 v2 v3) = + vol_frustt_wedge v0 v1 v2 v3 h a) /\ + (!v0 v1 v2 v3 r c. ~(collinear {v0,v1,v2}) /\ ~(collinear {v0,v1,v3}) /\ + (r >= &0) /\ (c >= -- (&1)) /\ (c <= &1) + ==> (vol(conic_cap v0 v1 r c INTER wedge v0 v1 v2 v3) = + vol_conic_cap_wedge v0 v1 v2 v3 r c)) /\ + (!(a:real^3) (b:real^3). vol(rect a b) = vol_rect a b) /\ + (!v0 v1 v2 v3 r. ~(collinear {v0,v1,v2}) /\ ~(collinear {v0,v1,v3}) /\ + (r >= &0) + ==> (vol(normball v0 r INTER wedge v0 v1 v2 v3) = + vol_ball_wedge v0 v1 v2 v3 r))`, + SIMP_TAC[MEASURE_POS_LE; real_ge; real_gt] THEN REPEAT CONJ_TAC THENL + [SIMP_TAC[GSYM HAS_MEASURE_0; HAS_MEASURE_MEASURABLE_MEASURE]; + MAP_EVERY X_GEN_TAC [`s:real^3->bool`; `t:real^3->bool`] THEN + STRIP_TAC THEN MATCH_MP_TAC MEASURE_NEGLIGIBLE_SYMDIFF THEN + ASM_REWRITE_TAC[] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + NEGLIGIBLE_SUBSET)) THEN + REWRITE_TAC[SDIFF] THEN SET_TAC[]; + MAP_EVERY X_GEN_TAC [`X:real^3->bool`; `t:real^3`] THEN + REWRITE_TAC[HAS_MEASURE_MEASURE] THEN + DISCH_THEN(MP_TAC o MATCH_MP HAS_MEASURE_STRETCH o CONJUNCT1) THEN + DISCH_THEN(MP_TAC o SPEC `\i. (t:real^3)$i`) THEN + REWRITE_TAC[HAS_MEASURE_MEASURABLE_MEASURE] THEN + DISCH_THEN(MP_TAC o CONJUNCT2) THEN + REWRITE_TAC[DIMINDEX_3; PRODUCT_3] THEN + DISCH_THEN(SUBST1_TAC o SYM) THEN + AP_TERM_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN + SIMP_TAC[FUN_EQ_THM; scale; CART_EQ; LAMBDA_BETA; + DIMINDEX_3; VECTOR_3; FORALL_3]; + REWRITE_TAC[REWRITE_RULE[ETA_AX] MEASURE_TRANSLATION]; + REPEAT STRIP_TAC THEN + REWRITE_TAC[solid_triangle; vol_solid_triangle; NORMBALL_BALL] THEN + REWRITE_TAC[cone0; GSYM aff_gt_def] THEN + MATCH_MP_TAC VOLUME_SOLID_TRIANGLE THEN ASM_REWRITE_TAC[]; + REWRITE_TAC[vol_conv; VOLUME_OF_TETRAHEDRON]; + SIMP_TAC[VOLUME_FRUSTT_WEDGE; vol_frustt_wedge] THEN + SIMP_TAC[REAL_ARITH `&0 <= h ==> ~(h < &0)`] THEN + SIMP_TAC[REAL_ARITH `a <= &1 ==> (&1 <= a <=> a = &1)`] THEN + REPEAT STRIP_TAC THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN + REPEAT(POP_ASSUM MP_TAC) THEN CONV_TAC REAL_FIELD; + SIMP_TAC[VOLUME_CONIC_CAP_WEDGE; vol_conic_cap_wedge] THEN + SIMP_TAC[REAL_ARITH `&0 <= r ==> ~(r < &0)`] THEN + SIMP_TAC[REAL_ARITH `c <= &1 ==> ~(&1 < c)`] THEN + ASM_SIMP_TAC[REAL_ARITH `-- &1 <= c ==> max c (-- &1) = c`] THEN + REPEAT STRIP_TAC THEN REAL_ARITH_TAC; + REWRITE_TAC[vol_rect; RECT_INTERVAL; MEASURE_INTERVAL] THEN + REWRITE_TAC[CONTENT_CLOSED_INTERVAL_CASES] THEN + REWRITE_TAC[DIMINDEX_3; FORALL_3; PRODUCT_3] THEN + MAP_EVERY X_GEN_TAC [`a:real^3`; `b:real^3`] THEN + REWRITE_TAC[REAL_LE_LT] THEN + ASM_CASES_TAC `(a:real^3)$1 = (b:real^3)$1` THEN + ASM_REWRITE_TAC[REAL_LT_REFL; REAL_MUL_LZERO; REAL_MUL_RZERO; + REAL_SUB_REFL; COND_ID] THEN + ASM_CASES_TAC `(a:real^3)$2 = (b:real^3)$2` THEN + ASM_REWRITE_TAC[REAL_LT_REFL; REAL_MUL_LZERO; REAL_MUL_RZERO; + REAL_SUB_REFL; COND_ID] THEN + ASM_CASES_TAC `(a:real^3)$3 = (b:real^3)$3` THEN + ASM_REWRITE_TAC[REAL_LT_REFL; REAL_MUL_LZERO; REAL_MUL_RZERO; + REAL_SUB_REFL; COND_ID] THEN + REWRITE_TAC[REAL_MUL_AC]; + SIMP_TAC[VOLUME_BALL_WEDGE; NORMBALL_BALL; vol_ball_wedge]]);; + +(* ------------------------------------------------------------------------- *) +(* Additional results on polyhedra and relation to fans. *) +(* ------------------------------------------------------------------------- *) + +let POLYHEDRON_COLLINEAR_FACES_STRONG = prove + (`!P:real^N->bool f f' p q s t. + polyhedron P /\ vec 0 IN relative_interior P /\ + f face_of P /\ ~(f = P) /\ f' face_of P /\ ~(f' = P) /\ + p IN f /\ q IN f' /\ s > &0 /\ t > &0 /\ s % p = t % q + ==> s = t`, + ONCE_REWRITE_TAC[MESON[] + `(!P f f' p q s t. Q P f f' p q s t) <=> + (!s t P f f' p q. Q P f f' p q s t)`] THEN + MATCH_MP_TAC REAL_WLOG_LT THEN + REWRITE_TAC[real_gt] THEN CONJ_TAC THENL [MESON_TAC[]; ALL_TAC] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC(TAUT `F ==> p`) THEN + FIRST_X_ASSUM(MP_TAC o AP_TERM `(%) (inv s):real^N->real^N`) THEN + ASM_SIMP_TAC[VECTOR_MUL_ASSOC; REAL_MUL_LINV; REAL_LT_IMP_NZ] THEN + ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN + REWRITE_TAC[VECTOR_MUL_LID; GSYM real_div] THEN + ABBREV_TAC `u:real = t / s` THEN + SUBGOAL_THEN `&0 < u /\ &1 < u` MP_TAC THENL + [EXPAND_TAC "u" THEN ASM_SIMP_TAC[REAL_LT_RDIV_EQ] THEN + ASM_REWRITE_TAC[REAL_MUL_LZERO; REAL_MUL_LID]; + ALL_TAC] THEN + MAP_EVERY (C UNDISCH_THEN (K ALL_TAC)) + [`s < t`; `&0 < s`; `&0 < t`; `t:real / s = u`] THEN + SPEC_TAC(`u:real`,`t:real`) THEN GEN_TAC THEN STRIP_TAC THEN + DISCH_THEN(ASSUME_TAC o SYM) THEN + SUBGOAL_THEN `?g:real^N->bool. g facet_of P /\ f' SUBSET g` + STRIP_ASSUME_TAC THENL + [MATCH_MP_TAC FACE_OF_POLYHEDRON_SUBSET_FACET THEN ASM SET_TAC[]; + ALL_TAC] THEN + SUBGOAL_THEN `~((vec 0:real^N) IN g)` ASSUME_TAC THENL + [DISCH_TAC THEN + MP_TAC(ISPECL [`P:real^N->bool`; `g:real^N->bool`; `P:real^N->bool`] + SUBSET_OF_FACE_OF) THEN + ASM_REWRITE_TAC[SUBSET_REFL; NOT_IMP] THEN CONJ_TAC THENL + [CONJ_TAC THENL [ASM_MESON_TAC[facet_of]; ASM SET_TAC[]]; + ASM_MESON_TAC[facet_of; FACET_OF_REFL; + SUBSET_ANTISYM; FACE_OF_IMP_SUBSET]]; + ALL_TAC] THEN + SUBGOAL_THEN `(g:real^N->bool) face_of P` MP_TAC THENL + [ASM_MESON_TAC[facet_of]; ALL_TAC] THEN + REWRITE_TAC[face_of] THEN DISCH_THEN(MP_TAC o last o CONJUNCTS) THEN + DISCH_THEN(MP_TAC o SPECL [`vec 0:real^N`; `t % q:real^N`; `q:real^N`]) THEN + ASM_REWRITE_TAC[] THEN REPEAT CONJ_TAC THENL + [ASM_MESON_TAC[RELATIVE_INTERIOR_SUBSET; SUBSET]; + ASM_MESON_TAC[FACE_OF_IMP_SUBSET; SUBSET]; + ASM_MESON_TAC[FACE_OF_IMP_SUBSET; SUBSET]; + ALL_TAC] THEN + EXPAND_TAC "p" THEN REWRITE_TAC[IN_SEGMENT] THEN CONJ_TAC THENL + [CONV_TAC(RAND_CONV SYM_CONV) THEN + ASM_SIMP_TAC[VECTOR_MUL_EQ_0; REAL_LT_IMP_NZ] THEN ASM SET_TAC[]; + EXISTS_TAC `inv t:real` THEN + ASM_SIMP_TAC[REAL_LT_INV_EQ; REAL_INV_LT_1] THEN + EXPAND_TAC "p" THEN REWRITE_TAC[VECTOR_MUL_ASSOC] THEN + ASM_SIMP_TAC[REAL_MUL_LINV; REAL_LT_IMP_NZ] THEN VECTOR_ARITH_TAC]);; + +let POLYHEDRON_COLLINEAR_FACES = prove + (`!P:real^N->bool f f' p q s t. + polyhedron P /\ vec 0 IN interior P /\ + f face_of P /\ ~(f = P) /\ f' face_of P /\ ~(f' = P) /\ + p IN f /\ q IN f' /\ s > &0 /\ t > &0 /\ s % p = t % q + ==> s = t`, + MESON_TAC[POLYHEDRON_COLLINEAR_FACES_STRONG; + INTERIOR_SUBSET_RELATIVE_INTERIOR; SUBSET]);; + +let vertices = new_definition + `vertices s = {x:real^N | x extreme_point_of s}`;; + +let edges = new_definition + `edges s = {{v,w} | segment[v,w] edge_of s}`;; + +let VERTICES_TRANSLATION = prove + (`!a s. vertices (IMAGE (\x. a + x) s) = IMAGE (\x. a + x) (vertices s)`, + REWRITE_TAC[vertices] THEN GEOM_TRANSLATE_TAC[]);; + +let VERTICES_LINEAR_IMAGE = prove + (`!f s. linear f /\ (!x y. f x = f y ==> x = y) + ==> vertices(IMAGE f s) = IMAGE f (vertices s)`, + REWRITE_TAC[vertices; EXTREME_POINTS_OF_LINEAR_IMAGE]);; + +let EDGES_TRANSLATION = prove + (`!a s. edges (IMAGE (\x. a + x) s) = IMAGE (IMAGE (\x. a + x)) (edges s)`, + REWRITE_TAC[edges] THEN GEOM_TRANSLATE_TAC[] THEN SET_TAC[]);; + +let EDGES_LINEAR_IMAGE = prove + (`!f:real^M->real^N s. + linear f /\ (!x y. f x = f y ==> x = y) + ==> edges(IMAGE f s) = IMAGE (IMAGE f) (edges s)`, + REPEAT GEN_TAC THEN DISCH_TAC THEN REWRITE_TAC[edges] THEN + MATCH_MP_TAC SUBSET_ANTISYM THEN + REWRITE_TAC[SUBSET; FORALL_IN_GSPEC; FORALL_IN_IMAGE] THEN CONJ_TAC THENL + [MAP_EVERY X_GEN_TAC [`x:real^N`; `y:real^N`] THEN STRIP_TAC THEN + REWRITE_TAC[IN_IMAGE] THEN ONCE_REWRITE_TAC[CONJ_SYM] THEN + REWRITE_TAC[EXISTS_IN_GSPEC] THEN + SUBGOAL_THEN `?v w. x = (f:real^M->real^N) v /\ y = f w` MP_TAC THENL + [ASM_MESON_TAC[ENDS_IN_SEGMENT; EDGE_OF_IMP_SUBSET; SUBSET; IN_IMAGE]; + REPEAT(MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC) THEN + DISCH_THEN(CONJUNCTS_THEN SUBST_ALL_TAC)]; + MAP_EVERY X_GEN_TAC [`v:real^M`; `w:real^M`] THEN DISCH_TAC THEN + REWRITE_TAC[IN_ELIM_THM] THEN + MAP_EVERY EXISTS_TAC [`(f:real^M->real^N) v`; `(f:real^M->real^N) w`]] THEN + REWRITE_TAC[IMAGE_CLAUSES] THEN + ASM_MESON_TAC[EDGE_OF_LINEAR_IMAGE; CLOSED_SEGMENT_LINEAR_IMAGE]);; + +add_translation_invariants [VERTICES_TRANSLATION; EDGES_TRANSLATION];; +add_linear_invariants [VERTICES_LINEAR_IMAGE; EDGES_LINEAR_IMAGE];; + +(*** Correspondence with Flypaper: + +Definition 4.5: IS_AFFINE_HULL + affine / hull + aff_dim + AFF_DIM_EMPTY + +Definition 4.6 : IN_INTERIOR + IN_RELATIVE_INTERIOR + CLOSURE_APPROACHABLE + (Don't have definition of relative boundary, but several + theorems use closure s DIFF relative_interior s.) + +Definition 4.7: face_of + extreme_point_of (presumably it's meant to be the point not + the singleton set, which the definition literally gives) + facet_of + edge_of + (Don't have a definition of "proper"; I just use + ~(f = {}) and/or ~(f = P) as needed.) + +Lemma 4.18: KREIN_MILMAN_MINKOWSKI + +Definition 4.8: polyhedron + vertices + +Lemma 4.19: AFFINE_IMP_POLYHEDRON + +Lemma 4.20 (i): FACET_OF_POLYHEDRON_EXPLICIT + +Lemma 4.20 (ii): Direct consequence of RELATIVE_INTERIOR_POLYHEDRON + +Lemma 4.20 (iii): FACE_OF_POLYHEDRON_EXPLICIT / FACE_OF_POLYHEDRON + +Lemma 4.20 (iv): FACE_OF_TRANS + +Lemma 4.20 (v): EXTREME_POINT_OF_FACE + +Lemma 4.20 (vi): FACE_OF_EQ + +Corr. 4.7: FACE_OF_POLYHEDRON_POLYHEDRON + +Lemma 4.21: POLYHEDRON_COLLINEAR_FACES + +Def 4.9: vertices + edges + +****) + +(* ------------------------------------------------------------------------- *) +(* Temporary backwards-compatible fix for introduction of "sphere" and *) +(* "relative_frontier". *) +(* ------------------------------------------------------------------------- *) + +let COMPACT_SPHERE = + REWRITE_RULE[sphere; NORM_ARITH `dist(a:real^N,b) = norm(b - a)`] + COMPACT_SPHERE;; + +let FRONTIER_CBALL = REWRITE_RULE[sphere] FRONTIER_CBALL;; + +let NEGLIGIBLE_SPHERE = REWRITE_RULE[sphere] NEGLIGIBLE_SPHERE;; + +let RELATIVE_FRONTIER_OF_POLYHEDRON = RELATIVE_BOUNDARY_OF_POLYHEDRON;; + +(* ------------------------------------------------------------------------- *) +(* Fix the congruence rules as expected in Flyspeck. *) +(* Should exclude 6 recent mixed real/vector limit results. *) +(* ------------------------------------------------------------------------- *) + +let bcs = + [`(p <=> p') ==> (p' ==> (q <=> q')) ==> (p ==> q <=> p' ==> q')`; + `(g <=> g') + ==> (g' ==> t = t') + ==> (~g' ==> e = e') + ==> (if g then t else e) = (if g' then t' else e')`; + `(!x. p x ==> f x = g x) ==> nsum {y | p y} (\i. f i) = nsum {y | p y} g`; + `(!i. a <= i /\ i <= b ==> f i = g i) + ==> nsum (a..b) (\i. f i) = nsum (a..b) g`; + `(!x. x IN s ==> f x = g x) ==> nsum s (\i. f i) = nsum s g`; + `(!x. p x ==> f x = g x) ==> sum {y | p y} (\i. f i) = sum {y | p y} g`; + `(!i. a <= i /\ i <= b ==> f i = g i) + ==> sum (a..b) (\i. f i) = sum (a..b) g`; + `(!x. x IN s ==> f x = g x) ==> sum s (\i. f i) = sum s g`; + `(!x. p x ==> f x = g x) ==> vsum {y | p y} (\i. f i) = vsum {y | p y} g`; + `(!i. a <= i /\ i <= b ==> f i = g i) + ==> vsum (a..b) (\i. f i) = vsum (a..b) g`; + `(!x. x IN s ==> f x = g x) ==> vsum s (\i. f i) = vsum s g`; + `(!x. p x ==> f x = g x) + ==> product {y | p y} (\i. f i) = product {y | p y} g`; + `(!i. a <= i /\ i <= b ==> f i = g i) + ==> product (a..b) (\i. f i) = product (a..b) g`; + `(!x. x IN s ==> f x = g x) ==> product s (\i. f i) = product s g`; + `(!x. ~(x = a) ==> f x = g x) + ==> (((\x. f x) --> l) (at a) <=> (g --> l) (at a))`; + `(!x. ~(x = a) ==> f x = g x) + ==> (((\x. f x) --> l) (at a within s) <=> (g --> l) (at a within s))`] +and equiv t1 t2 = can (term_match [] t1) t2 & can (term_match [] t2) t1 in +let congs' = + filter (fun th -> exists (equiv (concl th)) bcs) (basic_congs()) in +set_basic_congs congs';; diff --git a/Multivariate/geom.ml b/Multivariate/geom.ml new file mode 100644 index 0000000..d14a463 --- /dev/null +++ b/Multivariate/geom.ml @@ -0,0 +1,933 @@ +(* ========================================================================= *) +(* Some geometric notions in real^N. *) +(* ========================================================================= *) + +needs "Multivariate/realanalysis.ml";; + +prioritize_vector();; + +(* ------------------------------------------------------------------------- *) +(* Pythagoras's theorem is almost immediate. *) +(* ------------------------------------------------------------------------- *) + +let PYTHAGORAS = prove + (`!A B C:real^N. + orthogonal (A - B) (C - B) + ==> norm(C - A) pow 2 = norm(B - A) pow 2 + norm(C - B) pow 2`, + REWRITE_TAC[NORM_POW_2; orthogonal; DOT_LSUB; DOT_RSUB; DOT_SYM] THEN + CONV_TAC REAL_RING);; + +(* ------------------------------------------------------------------------- *) +(* Angle between vectors (always 0 <= angle <= pi). *) +(* ------------------------------------------------------------------------- *) + +let vector_angle = new_definition + `vector_angle x y = if x = vec 0 \/ y = vec 0 then pi / &2 + else acs((x dot y) / (norm x * norm y))`;; + +let VECTOR_ANGLE_LINEAR_IMAGE_EQ = prove + (`!f x y. linear f /\ (!x. norm(f x) = norm x) + ==> (vector_angle (f x) (f y) = vector_angle x y)`, + REPEAT STRIP_TAC THEN ASM_SIMP_TAC[vector_angle; GSYM NORM_EQ_0] THEN + ASM_MESON_TAC[PRESERVES_NORM_PRESERVES_DOT]);; + +add_linear_invariants [VECTOR_ANGLE_LINEAR_IMAGE_EQ];; + +(* ------------------------------------------------------------------------- *) +(* Basic properties of vector angles. *) +(* ------------------------------------------------------------------------- *) + +let VECTOR_ANGLE_REFL = prove + (`!x. vector_angle x x = if x = vec 0 then pi / &2 else &0`, + GEN_TAC THEN REWRITE_TAC[vector_angle; DISJ_ACI] THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[GSYM NORM_POW_2; REAL_POW_2] THEN + ASM_SIMP_TAC[REAL_DIV_REFL; REAL_ENTIRE; NORM_EQ_0; ACS_1]);; + +let VECTOR_ANGLE_SYM = prove + (`!x y. vector_angle x y = vector_angle y x`, + REWRITE_TAC[vector_angle; DISJ_SYM; DOT_SYM; REAL_MUL_SYM]);; + +let VECTOR_ANGLE_LMUL = prove + (`!a x y:real^N. + vector_angle (a % x) y = + if a = &0 then pi / &2 + else if &0 <= a then vector_angle x y + else pi - vector_angle x y`, + REPEAT STRIP_TAC THEN COND_CASES_TAC THEN + ASM_REWRITE_TAC[vector_angle; VECTOR_MUL_EQ_0] THEN + ASM_CASES_TAC `x:real^N = vec 0 \/ y:real^N = vec 0` THEN + ASM_REWRITE_TAC[] THENL [REAL_ARITH_TAC; ALL_TAC] THEN + REWRITE_TAC[NORM_MUL; DOT_LMUL; real_div; REAL_INV_MUL; real_abs] THEN + COND_CASES_TAC THEN + ASM_REWRITE_TAC[REAL_INV_NEG; REAL_MUL_LNEG; REAL_MUL_RNEG] THEN + ASM_SIMP_TAC[REAL_FIELD + `~(a = &0) ==> (a * x) * (inv a * y) * z = x * y * z`] THEN + MATCH_MP_TAC ACS_NEG THEN + REWRITE_TAC[GSYM REAL_ABS_BOUNDS; GSYM REAL_INV_MUL] THEN + REWRITE_TAC[GSYM real_div; NORM_CAUCHY_SCHWARZ_DIV]);; + +let VECTOR_ANGLE_RMUL = prove + (`!a x y:real^N. + vector_angle x (a % y) = + if a = &0 then pi / &2 + else if &0 <= a then vector_angle x y + else pi - vector_angle x y`, + ONCE_REWRITE_TAC[VECTOR_ANGLE_SYM] THEN + REWRITE_TAC[VECTOR_ANGLE_LMUL]);; + +let VECTOR_ANGLE_LNEG = prove + (`!x y. vector_angle (--x) y = pi - vector_angle x y`, + REWRITE_TAC[VECTOR_ARITH `--x = -- &1 % x`; VECTOR_ANGLE_LMUL] THEN + CONV_TAC REAL_RAT_REDUCE_CONV);; + +let VECTOR_ANGLE_RNEG = prove + (`!x y. vector_angle x (--y) = pi - vector_angle x y`, + ONCE_REWRITE_TAC[VECTOR_ANGLE_SYM] THEN REWRITE_TAC[VECTOR_ANGLE_LNEG]);; + +let VECTOR_ANGLE_NEG2 = prove + (`!x y. vector_angle (--x) (--y) = vector_angle x y`, + REWRITE_TAC[VECTOR_ANGLE_LNEG; VECTOR_ANGLE_RNEG] THEN REAL_ARITH_TAC);; + +let VECTOR_ANGLE = prove + (`!x y:real^N. x dot y = norm(x) * norm(y) * cos(vector_angle x y)`, + REPEAT GEN_TAC THEN REWRITE_TAC[vector_angle] THEN + ASM_CASES_TAC `x:real^N = vec 0` THEN + ASM_REWRITE_TAC[DOT_LZERO; NORM_0; REAL_MUL_LZERO] THEN + ASM_CASES_TAC `y:real^N = vec 0` THEN + ASM_REWRITE_TAC[DOT_RZERO; NORM_0; REAL_MUL_LZERO; REAL_MUL_RZERO] THEN + ONCE_REWRITE_TAC[AC REAL_MUL_AC `a * b * c:real = c * a * b`] THEN + ASM_SIMP_TAC[GSYM REAL_EQ_LDIV_EQ; REAL_LT_MUL; NORM_POS_LT] THEN + MATCH_MP_TAC(GSYM COS_ACS) THEN + ASM_REWRITE_TAC[REAL_BOUNDS_LE; NORM_CAUCHY_SCHWARZ_DIV]);; + +let VECTOR_ANGLE_RANGE = prove + (`!x y:real^N. &0 <= vector_angle x y /\ vector_angle x y <= pi`, + REPEAT GEN_TAC THEN REWRITE_TAC[vector_angle] THEN COND_CASES_TAC THENL + [MP_TAC PI_POS THEN REAL_ARITH_TAC; ALL_TAC] THEN + RULE_ASSUM_TAC(REWRITE_RULE[DE_MORGAN_THM]) THEN MATCH_MP_TAC ACS_BOUNDS THEN + ASM_REWRITE_TAC[REAL_BOUNDS_LE; NORM_CAUCHY_SCHWARZ_DIV]);; + +let ORTHOGONAL_VECTOR_ANGLE = prove + (`!x y:real^N. orthogonal x y <=> vector_angle x y = pi / &2`, + REPEAT STRIP_TAC THEN REWRITE_TAC[orthogonal; vector_angle] THEN + ASM_CASES_TAC `x:real^N = vec 0` THEN ASM_REWRITE_TAC[DOT_LZERO] THEN + ASM_CASES_TAC `y:real^N = vec 0` THEN ASM_REWRITE_TAC[DOT_RZERO] THEN + EQ_TAC THENL + [SIMP_TAC[real_div; REAL_MUL_LZERO] THEN DISCH_TAC THEN + REWRITE_TAC[GSYM real_div; GSYM COS_PI2] THEN + MATCH_MP_TAC ACS_COS THEN MP_TAC PI_POS THEN REAL_ARITH_TAC; + DISCH_THEN(MP_TAC o AP_TERM `cos`) THEN + SIMP_TAC[COS_ACS; REAL_BOUNDS_LE; NORM_CAUCHY_SCHWARZ_DIV; COS_PI2] THEN + ASM_SIMP_TAC[REAL_EQ_LDIV_EQ; REAL_LT_MUL; NORM_POS_LT; REAL_MUL_LZERO]]);; + +let VECTOR_ANGLE_EQ_0 = prove + (`!x y:real^N. vector_angle x y = &0 <=> + ~(x = vec 0) /\ ~(y = vec 0) /\ norm(x) % y = norm(y) % x`, + REPEAT GEN_TAC THEN + MAP_EVERY ASM_CASES_TAC [`x:real^N = vec 0`; `y:real^N = vec 0`] THEN + ASM_SIMP_TAC[vector_angle; PI_NZ; REAL_ARITH `x / &2 = &0 <=> x = &0`] THEN + REWRITE_TAC[GSYM NORM_CAUCHY_SCHWARZ_EQ] THEN + GEN_REWRITE_TAC (RAND_CONV o RAND_CONV) [GSYM REAL_MUL_LID] THEN + ASM_SIMP_TAC[GSYM REAL_EQ_LDIV_EQ; NORM_POS_LT; REAL_LT_MUL] THEN + MESON_TAC[ACS_1; COS_ACS; REAL_BOUNDS_LE; NORM_CAUCHY_SCHWARZ_DIV; COS_0]);; + +let VECTOR_ANGLE_EQ_PI = prove + (`!x y:real^N. vector_angle x y = pi <=> + ~(x = vec 0) /\ ~(y = vec 0) /\ + norm(x) % y + norm(y) % x = vec 0`, + REPEAT GEN_TAC THEN + MP_TAC(ISPECL [`x:real^N`; `--y:real^N`] VECTOR_ANGLE_EQ_0) THEN + SIMP_TAC[VECTOR_ANGLE_RNEG; REAL_ARITH `pi - x = &0 <=> x = pi`] THEN + STRIP_TAC THEN + REWRITE_TAC[NORM_NEG; VECTOR_ARITH `--x = vec 0 <=> x = vec 0`] THEN + AP_TERM_TAC THEN AP_TERM_TAC THEN VECTOR_ARITH_TAC);; + +let VECTOR_ANGLE_EQ_0_DIST = prove + (`!x y:real^N. vector_angle x y = &0 <=> + ~(x = vec 0) /\ ~(y = vec 0) /\ norm(x + y) = norm x + norm y`, + REWRITE_TAC[VECTOR_ANGLE_EQ_0; GSYM NORM_TRIANGLE_EQ]);; + +let VECTOR_ANGLE_EQ_PI_DIST = prove + (`!x y:real^N. vector_angle x y = pi <=> + ~(x = vec 0) /\ ~(y = vec 0) /\ norm(x - y) = norm x + norm y`, + REPEAT GEN_TAC THEN + MP_TAC(ISPECL [`x:real^N`; `--y:real^N`] VECTOR_ANGLE_EQ_0_DIST) THEN + SIMP_TAC[VECTOR_ANGLE_RNEG; REAL_ARITH `pi - x = &0 <=> x = pi`] THEN + STRIP_TAC THEN REWRITE_TAC[NORM_NEG] THEN NORM_ARITH_TAC);; + +let SIN_VECTOR_ANGLE_POS = prove + (`!v w. &0 <= sin(vector_angle v w)`, + SIMP_TAC[SIN_POS_PI_LE; VECTOR_ANGLE_RANGE]);; + +let SIN_VECTOR_ANGLE_EQ_0 = prove + (`!x y. sin(vector_angle x y) = &0 <=> + vector_angle x y = &0 \/ vector_angle x y = pi`, + MESON_TAC[SIN_POS_PI; VECTOR_ANGLE_RANGE; REAL_LT_LE; SIN_0; SIN_PI]);; + +let ASN_SIN_VECTOR_ANGLE = prove + (`!x y:real^N. + asn(sin(vector_angle x y)) = + if vector_angle x y <= pi / &2 then vector_angle x y + else pi - vector_angle x y`, + REPEAT GEN_TAC THEN COND_CASES_TAC THENL + [ALL_TAC; + MATCH_MP_TAC EQ_TRANS THEN + EXISTS_TAC `asn(sin(pi - vector_angle (x:real^N) y))` THEN CONJ_TAC THENL + [AP_TERM_TAC THEN REWRITE_TAC[SIN_SUB; SIN_PI; COS_PI] THEN + REAL_ARITH_TAC; + ALL_TAC]] THEN + MATCH_MP_TAC ASN_SIN THEN + MP_TAC(ISPECL [`x:real^N`; `y:real^N`] VECTOR_ANGLE_RANGE) THEN + ASM_REAL_ARITH_TAC);; + +let SIN_VECTOR_ANGLE_EQ = prove + (`!x y w z. + sin(vector_angle x y) = sin(vector_angle w z) <=> + vector_angle x y = vector_angle w z \/ + vector_angle x y = pi - vector_angle w z`, + REPEAT GEN_TAC THEN EQ_TAC THEN + STRIP_TAC THEN ASM_REWRITE_TAC[SIN_SUB; SIN_PI; COS_PI] THENL + [ALL_TAC; REAL_ARITH_TAC] THEN + FIRST_X_ASSUM(MP_TAC o AP_TERM `asn`) THEN + REWRITE_TAC[ASN_SIN_VECTOR_ANGLE] THEN REAL_ARITH_TAC);; + +let CONTINUOUS_WITHIN_CX_VECTOR_ANGLE_COMPOSE = prove + (`!f:real^M->real^N g x s. + ~(f x = vec 0) /\ ~(g x = vec 0) /\ + f continuous (at x within s) /\ + g continuous (at x within s) + ==> (\x. Cx(vector_angle (f x) (g x))) continuous (at x within s)`, + REPEAT STRIP_TAC THEN + ASM_CASES_TAC `trivial_limit(at (x:real^M) within s)` THEN + ASM_SIMP_TAC[CONTINUOUS_TRIVIAL_LIMIT; vector_angle] THEN + SUBGOAL_THEN + `(cacs o (\x. Cx(((f x:real^N) dot g x) / (norm(f x) * norm(g x))))) + continuous (at (x:real^M) within s)` + MP_TAC THENL + [MATCH_MP_TAC CONTINUOUS_WITHIN_COMPOSE THEN CONJ_TAC THENL + [REWRITE_TAC[CX_DIV; CX_MUL] THEN REWRITE_TAC[WITHIN_UNIV] THEN + MATCH_MP_TAC CONTINUOUS_COMPLEX_DIV THEN + ASM_SIMP_TAC[NETLIMIT_WITHIN; COMPLEX_ENTIRE; CX_INJ; NORM_EQ_0] THEN + REWRITE_TAC[CONTINUOUS_CX_LIFT; GSYM CX_MUL; LIFT_CMUL] THEN + ASM_SIMP_TAC[CONTINUOUS_LIFT_DOT2] THEN + MATCH_MP_TAC CONTINUOUS_MUL THEN + ASM_SIMP_TAC[CONTINUOUS_LIFT_NORM_COMPOSE; o_DEF]; + MATCH_MP_TAC CONTINUOUS_WITHIN_SUBSET THEN + EXISTS_TAC `{z | real z /\ abs(Re z) <= &1}` THEN + REWRITE_TAC[CONTINUOUS_WITHIN_CACS_REAL] THEN + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; IN_UNIV; IN_ELIM_THM] THEN + REWRITE_TAC[REAL_CX; RE_CX; NORM_CAUCHY_SCHWARZ_DIV]]; + ASM_SIMP_TAC[CONTINUOUS_WITHIN; CX_ACS; o_DEF; + NORM_CAUCHY_SCHWARZ_DIV] THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] LIM_TRANSFORM_EVENTUALLY) THEN + SUBGOAL_THEN + `eventually (\y. ~((f:real^M->real^N) y = vec 0) /\ + ~((g:real^M->real^N) y = vec 0)) + (at x within s)` + MP_TAC THENL + [REWRITE_TAC[EVENTUALLY_AND] THEN CONJ_TAC THENL + [UNDISCH_TAC `(f:real^M->real^N) continuous (at x within s)`; + UNDISCH_TAC `(g:real^M->real^N) continuous (at x within s)`] THEN + REWRITE_TAC[CONTINUOUS_WITHIN; tendsto] THENL + [DISCH_THEN(MP_TAC o SPEC `norm((f:real^M->real^N) x)`); + DISCH_THEN(MP_TAC o SPEC `norm((g:real^M->real^N) x)`)] THEN + ASM_REWRITE_TAC[NORM_POS_LT] THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] EVENTUALLY_MONO) THEN + REWRITE_TAC[] THEN CONV_TAC NORM_ARITH; + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] EVENTUALLY_MONO) THEN + SIMP_TAC[CX_ACS; NORM_CAUCHY_SCHWARZ_DIV]]]);; + +let CONTINUOUS_AT_CX_VECTOR_ANGLE = prove + (`!c x:real^N. ~(x = vec 0) ==> (Cx o vector_angle c) continuous (at x)`, + REPEAT STRIP_TAC THEN REWRITE_TAC[o_DEF; vector_angle] THEN + ASM_CASES_TAC `c:real^N = vec 0` THEN ASM_REWRITE_TAC[CONTINUOUS_CONST] THEN + MATCH_MP_TAC CONTINUOUS_TRANSFORM_AT THEN + MAP_EVERY EXISTS_TAC [`\x:real^N. cacs(Cx((c dot x) / (norm c * norm x)))`; + `norm(x:real^N)`] THEN + ASM_REWRITE_TAC[NORM_POS_LT] THEN CONJ_TAC THENL + [X_GEN_TAC `z:real^N` THEN DISCH_TAC THEN COND_CASES_TAC THENL + [ASM_MESON_TAC[NORM_ARITH `~(dist(vec 0,x) < norm x)`]; ALL_TAC] THEN + MATCH_MP_TAC(GSYM CX_ACS) THEN REWRITE_TAC[NORM_CAUCHY_SCHWARZ_DIV]; + ALL_TAC] THEN + ONCE_REWRITE_TAC[GSYM WITHIN_UNIV] THEN + MATCH_MP_TAC(REWRITE_RULE[o_DEF] CONTINUOUS_WITHIN_COMPOSE) THEN + CONJ_TAC THENL + [REWRITE_TAC[CX_DIV; CX_MUL] THEN REWRITE_TAC[WITHIN_UNIV] THEN + MATCH_MP_TAC CONTINUOUS_COMPLEX_DIV THEN + ASM_REWRITE_TAC[NETLIMIT_AT; COMPLEX_ENTIRE; CX_INJ; NORM_EQ_0] THEN + SIMP_TAC[CONTINUOUS_COMPLEX_MUL; CONTINUOUS_CONST; + CONTINUOUS_AT_CX_NORM; CONTINUOUS_AT_CX_DOT]; + MATCH_MP_TAC CONTINUOUS_WITHIN_SUBSET THEN + EXISTS_TAC `{z | real z /\ abs(Re z) <= &1}` THEN + REWRITE_TAC[CONTINUOUS_WITHIN_CACS_REAL] THEN + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; IN_UNIV; IN_ELIM_THM] THEN + REWRITE_TAC[REAL_CX; RE_CX; NORM_CAUCHY_SCHWARZ_DIV]]);; + +let CONTINUOUS_WITHIN_CX_VECTOR_ANGLE = prove + (`!c x:real^N s. + ~(x = vec 0) ==> (Cx o vector_angle c) continuous (at x within s)`, + SIMP_TAC[CONTINUOUS_AT_WITHIN; CONTINUOUS_AT_CX_VECTOR_ANGLE]);; + +let REAL_CONTINUOUS_AT_VECTOR_ANGLE = prove + (`!c x:real^N. ~(x = vec 0) ==> (vector_angle c) real_continuous (at x)`, + REWRITE_TAC[REAL_CONTINUOUS_CONTINUOUS; CONTINUOUS_AT_CX_VECTOR_ANGLE]);; + +let REAL_CONTINUOUS_WITHIN_VECTOR_ANGLE = prove + (`!c s x:real^N. ~(x = vec 0) + ==> (vector_angle c) real_continuous (at x within s)`, + REWRITE_TAC[REAL_CONTINUOUS_CONTINUOUS; CONTINUOUS_WITHIN_CX_VECTOR_ANGLE]);; + +let CONTINUOUS_ON_CX_VECTOR_ANGLE = prove + (`!s. ~(vec 0 IN s) ==> (Cx o vector_angle c) continuous_on s`, + REPEAT STRIP_TAC THEN REWRITE_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN] THEN + ASM_MESON_TAC[CONTINUOUS_WITHIN_CX_VECTOR_ANGLE]);; + +let VECTOR_ANGLE_EQ = prove + (`!u v x y. ~(u = vec 0) /\ ~(v = vec 0) /\ ~(x = vec 0) /\ ~(y = vec 0) + ==> (vector_angle u v = vector_angle x y <=> + (x dot y) * norm(u) * norm(v) = + (u dot v) * norm(x) * norm(y))`, + SIMP_TAC[vector_angle; NORM_EQ_0; REAL_FIELD + `~(u = &0) /\ ~(v = &0) /\ ~(x = &0) /\ ~(y = &0) + ==> (a * u * v = b * x * y <=> a / (x * y) = b / (u * v))`] THEN + REPEAT STRIP_TAC THEN EQ_TAC THEN SIMP_TAC[] THEN + DISCH_THEN(MP_TAC o AP_TERM `cos`) THEN + SIMP_TAC[COS_ACS; NORM_CAUCHY_SCHWARZ_DIV; REAL_BOUNDS_LE]);; + +let COS_VECTOR_ANGLE_EQ = prove + (`!u v x y. + cos(vector_angle u v) = cos(vector_angle x y) <=> + vector_angle u v = vector_angle x y`, + MESON_TAC[ACS_COS; VECTOR_ANGLE_RANGE]);; + +let COLLINEAR_VECTOR_ANGLE = prove + (`!x y. ~(x = vec 0) /\ ~(y = vec 0) + ==> (collinear {vec 0,x,y} <=> + vector_angle x y = &0 \/ vector_angle x y = pi)`, + REWRITE_TAC[GSYM NORM_CAUCHY_SCHWARZ_EQUAL; NORM_CAUCHY_SCHWARZ_ABS_EQ; + VECTOR_ANGLE_EQ_0; VECTOR_ANGLE_EQ_PI] THEN + REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THEN BINOP_TAC THEN + VECTOR_ARITH_TAC);; + +let COLLINEAR_SIN_VECTOR_ANGLE = prove + (`!x y. ~(x = vec 0) /\ ~(y = vec 0) + ==> (collinear {vec 0,x,y} <=> sin(vector_angle x y) = &0)`, + REWRITE_TAC[SIN_VECTOR_ANGLE_EQ_0; COLLINEAR_VECTOR_ANGLE]);; + +let COLLINEAR_SIN_VECTOR_ANGLE_IMP = prove + (`!x y. sin(vector_angle x y) = &0 + ==> ~(x = vec 0) /\ ~(y = vec 0) /\ collinear {vec 0,x,y}`, + MESON_TAC[COLLINEAR_SIN_VECTOR_ANGLE; SIN_VECTOR_ANGLE_EQ_0; + VECTOR_ANGLE_EQ_0_DIST; VECTOR_ANGLE_EQ_PI_DIST]);; + +let VECTOR_ANGLE_EQ_0_RIGHT = prove + (`!x y z:real^N. vector_angle x y = &0 + ==> (vector_angle x z = vector_angle y z)`, + REWRITE_TAC[VECTOR_ANGLE_EQ_0] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC EQ_TRANS THEN + EXISTS_TAC `vector_angle (norm(x:real^N) % y) (z:real^N)` THEN CONJ_TAC THENL + [ASM_REWRITE_TAC[] THEN + ASM_REWRITE_TAC[VECTOR_ANGLE_LMUL; NORM_EQ_0; NORM_POS_LE]; + REWRITE_TAC[VECTOR_ANGLE_LMUL] THEN + ASM_REWRITE_TAC[NORM_EQ_0; NORM_POS_LE]]);; + +let VECTOR_ANGLE_EQ_0_LEFT = prove + (`!x y z:real^N. vector_angle x y = &0 + ==> (vector_angle z x = vector_angle z y)`, + MESON_TAC[VECTOR_ANGLE_EQ_0_RIGHT; VECTOR_ANGLE_SYM]);; + +let VECTOR_ANGLE_EQ_PI_RIGHT = prove + (`!x y z:real^N. vector_angle x y = pi + ==> (vector_angle x z = pi - vector_angle y z)`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`--x:real^N`; `y:real^N`; `z:real^N`] + VECTOR_ANGLE_EQ_0_RIGHT) THEN + ASM_REWRITE_TAC[VECTOR_ANGLE_LNEG] THEN REAL_ARITH_TAC);; + +let VECTOR_ANGLE_EQ_PI_LEFT = prove + (`!x y z:real^N. vector_angle x y = pi + ==> (vector_angle z x = pi - vector_angle z y)`, + MESON_TAC[VECTOR_ANGLE_EQ_PI_RIGHT; VECTOR_ANGLE_SYM]);; + +let COS_VECTOR_ANGLE = prove + (`!x y:real^N. + cos(vector_angle x y) = if x = vec 0 \/ y = vec 0 then &0 + else (x dot y) / (norm x * norm y)`, + REPEAT GEN_TAC THEN + ASM_CASES_TAC `x:real^N = vec 0` THENL + [ASM_REWRITE_TAC[vector_angle; COS_PI2]; ALL_TAC] THEN + ASM_CASES_TAC `y:real^N = vec 0` THENL + [ASM_REWRITE_TAC[vector_angle; COS_PI2]; ALL_TAC] THEN + ASM_SIMP_TAC[REAL_EQ_RDIV_EQ; REAL_LT_MUL; NORM_POS_LT; VECTOR_ANGLE] THEN + REAL_ARITH_TAC);; + +let SIN_VECTOR_ANGLE = prove + (`!x y:real^N. + sin(vector_angle x y) = + if x = vec 0 \/ y = vec 0 then &1 + else sqrt(&1 - ((x dot y) / (norm x * norm y)) pow 2)`, + SIMP_TAC[SIN_COS_SQRT; SIN_VECTOR_ANGLE_POS; COS_VECTOR_ANGLE] THEN + REPEAT GEN_TAC THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN REWRITE_TAC[SQRT_1]);; + +let SIN_SQUARED_VECTOR_ANGLE = prove + (`!x y:real^N. + sin(vector_angle x y) pow 2 = + if x = vec 0 \/ y = vec 0 then &1 + else &1 - ((x dot y) / (norm x * norm y)) pow 2`, + REPEAT GEN_TAC THEN REWRITE_TAC + [REWRITE_RULE [REAL_ARITH `s + c = &1 <=> s = &1 - c`] SIN_CIRCLE] THEN + REWRITE_TAC[COS_VECTOR_ANGLE] THEN REAL_ARITH_TAC);; + +let VECTOR_ANGLE_COMPLEX_LMUL = prove + (`!a. ~(a = Cx(&0)) + ==> vector_angle (a * x) (a * y) = vector_angle x y`, + REPEAT STRIP_TAC THEN + ASM_CASES_TAC `x = Cx(&0)` THENL + [ASM_REWRITE_TAC[COMPLEX_MUL_RZERO; vector_angle; COMPLEX_VEC_0]; + ALL_TAC] THEN + ASM_CASES_TAC `y = Cx(&0)` THENL + [ASM_REWRITE_TAC[COMPLEX_MUL_RZERO; vector_angle; COMPLEX_VEC_0]; + ALL_TAC] THEN + MP_TAC(ISPECL + [`a * x:complex`; `a * y:complex`; `x:complex`; `y:complex`] + VECTOR_ANGLE_EQ) THEN + ASM_REWRITE_TAC[COMPLEX_VEC_0; COMPLEX_ENTIRE] THEN + DISCH_THEN SUBST1_TAC THEN + REWRITE_TAC[COMPLEX_NORM_MUL] THEN MATCH_MP_TAC(REAL_RING + `a pow 2 * xy:real = d ==> xy * (a * x) * (a * y) = d * x * y`) THEN + REWRITE_TAC[NORM_POW_2] THEN + REWRITE_TAC[DOT_2; complex_mul; GSYM RE_DEF; GSYM IM_DEF; RE; IM] THEN + REAL_ARITH_TAC);; + +let VECTOR_ANGLE_1 = prove + (`!x. vector_angle x (Cx(&1)) = acs(Re x / norm x)`, + GEN_TAC THEN + SIMP_TAC[vector_angle; COMPLEX_VEC_0; CX_INJ; REAL_OF_NUM_EQ; ARITH_EQ] THEN + COND_CASES_TAC THENL + [ASM_REWRITE_TAC[real_div; RE_CX; ACS_0; REAL_MUL_LZERO]; ALL_TAC] THEN + REWRITE_TAC[COMPLEX_NORM_CX; REAL_ABS_NUM; REAL_MUL_RID] THEN + REWRITE_TAC[DOT_2; GSYM RE_DEF; GSYM IM_DEF; RE_CX; IM_CX] THEN + AP_TERM_TAC THEN REAL_ARITH_TAC);; + +let ARG_EQ_VECTOR_ANGLE_1 = prove + (`!z. ~(z = Cx(&0)) /\ &0 <= Im z ==> Arg z = vector_angle z (Cx(&1))`, + REPEAT STRIP_TAC THEN REWRITE_TAC[VECTOR_ANGLE_1] THEN + GEN_REWRITE_TAC (RAND_CONV o RAND_CONV o LAND_CONV o RAND_CONV) [ARG] THEN + REWRITE_TAC[RE_MUL_CX; RE_CEXP; RE_II; IM_MUL_II; IM_CX; RE_CX] THEN + REWRITE_TAC[REAL_MUL_LZERO; REAL_EXP_0; REAL_MUL_LID] THEN + ASM_SIMP_TAC[COMPLEX_NORM_ZERO; REAL_FIELD + `~(z = &0) ==> (z * x) / z = x`] THEN + CONV_TAC SYM_CONV THEN MATCH_MP_TAC ACS_COS THEN + ASM_REWRITE_TAC[ARG; ARG_LE_PI]);; + +let VECTOR_ANGLE_ARG = prove + (`!w z. ~(w = Cx(&0)) /\ ~(z = Cx(&0)) + ==> vector_angle w z = if &0 <= Im(z / w) then Arg(z / w) + else &2 * pi - Arg(z / w)`, + REPEAT STRIP_TAC THEN COND_CASES_TAC THENL + [SUBGOAL_THEN `z = w * (z / w) /\ w = w * Cx(&1)` MP_TAC THENL + [REPEAT(POP_ASSUM MP_TAC) THEN CONV_TAC COMPLEX_FIELD; ALL_TAC]; + SUBGOAL_THEN `w = z * (w / z) /\ z = z * Cx(&1)` MP_TAC THENL + [REPEAT(POP_ASSUM MP_TAC) THEN CONV_TAC COMPLEX_FIELD; ALL_TAC]] THEN + DISCH_THEN(fun th -> GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [th]) THEN + ASM_SIMP_TAC[VECTOR_ANGLE_COMPLEX_LMUL] THENL + [ONCE_REWRITE_TAC[VECTOR_ANGLE_SYM] THEN CONV_TAC SYM_CONV THEN + MATCH_MP_TAC ARG_EQ_VECTOR_ANGLE_1 THEN ASM_REWRITE_TAC[] THEN + REPEAT(POP_ASSUM MP_TAC) THEN CONV_TAC COMPLEX_FIELD; + MP_TAC(ISPEC `z / w:complex` ARG_INV) THEN ANTS_TAC THENL + [ASM_MESON_TAC[real; REAL_LE_REFL]; DISCH_THEN(SUBST1_TAC o SYM)] THEN + REWRITE_TAC[COMPLEX_INV_DIV] THEN CONV_TAC SYM_CONV THEN + MATCH_MP_TAC ARG_EQ_VECTOR_ANGLE_1 THEN CONJ_TAC THENL + [REPEAT(POP_ASSUM MP_TAC) THEN CONV_TAC COMPLEX_FIELD; + ONCE_REWRITE_TAC[GSYM COMPLEX_INV_DIV] THEN + REWRITE_TAC[IM_COMPLEX_INV_GE_0] THEN ASM_REAL_ARITH_TAC]]);; + +(* ------------------------------------------------------------------------- *) +(* Traditional geometric notion of angle (always 0 <= theta <= pi). *) +(* ------------------------------------------------------------------------- *) + +let angle = new_definition + `angle(a,b,c) = vector_angle (a - b) (c - b)`;; + +let ANGLE_LINEAR_IMAGE_EQ = prove + (`!f a b c. + linear f /\ (!x. norm(f x) = norm x) + ==> angle(f a,f b,f c) = angle(a,b,c)`, + SIMP_TAC[angle; GSYM LINEAR_SUB; VECTOR_ANGLE_LINEAR_IMAGE_EQ]);; + +add_linear_invariants [ANGLE_LINEAR_IMAGE_EQ];; + +let ANGLE_TRANSLATION_EQ = prove + (`!a b c d. angle(a + b,a + c,a + d) = angle(b,c,d)`, + REPEAT GEN_TAC THEN REWRITE_TAC[angle] THEN + BINOP_TAC THEN VECTOR_ARITH_TAC);; + +add_translation_invariants [ANGLE_TRANSLATION_EQ];; + +let VECTOR_ANGLE_ANGLE = prove + (`vector_angle x y = angle(x,vec 0,y)`, + REWRITE_TAC[angle; VECTOR_SUB_RZERO]);; + +let ANGLE_EQ_PI_DIST = prove + (`!A B C:real^N. + angle(A,B,C) = pi <=> + ~(A = B) /\ ~(C = B) /\ dist(A,C) = dist(A,B) + dist(B,C)`, + REWRITE_TAC[angle; VECTOR_ANGLE_EQ_PI_DIST] THEN NORM_ARITH_TAC);; + +let SIN_ANGLE_POS = prove + (`!A B C. &0 <= sin(angle(A,B,C))`, + REWRITE_TAC[angle; SIN_VECTOR_ANGLE_POS]);; + +let ANGLE = prove + (`!A B C. (A - C) dot (B - C) = dist(A,C) * dist(B,C) * cos(angle(A,C,B))`, + REWRITE_TAC[angle; dist; GSYM VECTOR_ANGLE]);; + +let ANGLE_REFL = prove + (`!A B. angle(A,A,B) = pi / &2 /\ angle(B,A,A) = pi / &2`, + REWRITE_TAC[angle; vector_angle; VECTOR_SUB_REFL]);; + +let ANGLE_REFL_MID = prove + (`!A B. ~(A = B) ==> angle(A,B,A) = &0`, + SIMP_TAC[angle; vector_angle; VECTOR_SUB_EQ; GSYM NORM_POW_2; ARITH; + GSYM REAL_POW_2; REAL_DIV_REFL; ACS_1; REAL_POW_EQ_0; NORM_EQ_0]);; + +let ANGLE_SYM = prove + (`!A B C. angle(A,B,C) = angle(C,B,A)`, + REWRITE_TAC[angle; vector_angle; VECTOR_SUB_EQ; DISJ_SYM; + REAL_MUL_SYM; DOT_SYM]);; + +let ANGLE_RANGE = prove + (`!A B C. &0 <= angle(A,B,C) /\ angle(A,B,C) <= pi`, + REWRITE_TAC[angle; VECTOR_ANGLE_RANGE]);; + +let COS_ANGLE_EQ = prove + (`!a b c a' b' c'. + cos(angle(a,b,c)) = cos(angle(a',b',c')) <=> + angle(a,b,c) = angle(a',b',c')`, + REWRITE_TAC[angle; COS_VECTOR_ANGLE_EQ]);; + +let ANGLE_EQ = prove + (`!a b c a' b' c'. + ~(a = b) /\ ~(c = b) /\ ~(a' = b') /\ ~(c' = b') + ==> (angle(a,b,c) = angle(a',b',c') <=> + ((a' - b') dot (c' - b')) * norm (a - b) * norm (c - b) = + ((a - b) dot (c - b)) * norm (a' - b') * norm (c' - b'))`, + SIMP_TAC[angle; VECTOR_ANGLE_EQ; VECTOR_SUB_EQ]);; + +let SIN_ANGLE_EQ_0 = prove + (`!A B C. sin(angle(A,B,C)) = &0 <=> angle(A,B,C) = &0 \/ angle(A,B,C) = pi`, + REWRITE_TAC[angle; SIN_VECTOR_ANGLE_EQ_0]);; + +let SIN_ANGLE_EQ = prove + (`!A B C A' B' C'. sin(angle(A,B,C)) = sin(angle(A',B',C')) <=> + angle(A,B,C) = angle(A',B',C') \/ + angle(A,B,C) = pi - angle(A',B',C')`, + REWRITE_TAC[angle; SIN_VECTOR_ANGLE_EQ]);; + +let COLLINEAR_ANGLE = prove + (`!A B C. ~(A = B) /\ ~(B = C) + ==> (collinear {A,B,C} <=> angle(A,B,C) = &0 \/ angle(A,B,C) = pi)`, + ONCE_REWRITE_TAC[COLLINEAR_3] THEN + SIMP_TAC[COLLINEAR_VECTOR_ANGLE; VECTOR_SUB_EQ; angle]);; + +let COLLINEAR_SIN_ANGLE = prove + (`!A B C. ~(A = B) /\ ~(B = C) + ==> (collinear {A,B,C} <=> sin(angle(A,B,C)) = &0)`, + REWRITE_TAC[SIN_ANGLE_EQ_0; COLLINEAR_ANGLE]);; + +let COLLINEAR_SIN_ANGLE_IMP = prove + (`!A B C. sin(angle(A,B,C)) = &0 + ==> ~(A = B) /\ ~(B = C) /\ collinear {A,B,C}`, + REPEAT GEN_TAC THEN + ONCE_REWRITE_TAC[COLLINEAR_3] THEN REWRITE_TAC[angle] THEN + DISCH_THEN(MP_TAC o MATCH_MP COLLINEAR_SIN_VECTOR_ANGLE_IMP) THEN + SIMP_TAC[VECTOR_SUB_EQ]);; + +let ANGLE_EQ_0_RIGHT = prove + (`!A B C. angle(A,B,C) = &0 ==> angle(A,B,D) = angle(C,B,D)`, + REWRITE_TAC[VECTOR_ANGLE_EQ_0_RIGHT; angle]);; + +let ANGLE_EQ_0_LEFT = prove + (`!A B C. angle(A,B,C) = &0 ==> angle(D,B,A) = angle(D,B,C)`, + MESON_TAC[ANGLE_EQ_0_RIGHT; ANGLE_SYM]);; + +let ANGLE_EQ_PI_RIGHT = prove + (`!A B C. angle(A,B,C) = pi ==> angle(A,B,D) = pi - angle(C,B,D)`, + REWRITE_TAC[VECTOR_ANGLE_EQ_PI_RIGHT; angle]);; + +let ANGLE_EQ_PI_LEFT = prove + (`!A B C. angle(A,B,C) = pi ==> angle(A,B,D) = pi - angle(C,B,D)`, + MESON_TAC[ANGLE_EQ_PI_RIGHT; ANGLE_SYM]);; + +let COS_ANGLE = prove + (`!a b c. cos(angle(a,b,c)) = if a = b \/ c = b then &0 + else ((a - b) dot (c - b)) / + (norm(a - b) * norm(c - b))`, + REWRITE_TAC[angle; COS_VECTOR_ANGLE; VECTOR_SUB_EQ]);; + +let SIN_ANGLE = prove + (`!a b c. sin(angle(a,b,c)) = + if a = b \/ c = b then &1 + else sqrt(&1 - (((a - b) dot (c - b)) / + (norm(a - b) * norm(c - b))) pow 2)`, + REWRITE_TAC[angle; SIN_VECTOR_ANGLE; VECTOR_SUB_EQ]);; + +let SIN_SQUARED_ANGLE = prove + (`!a b c. sin(angle(a,b,c)) pow 2 = + if a = b \/ c = b then &1 + else &1 - (((a - b) dot (c - b)) / + (norm(a - b) * norm(c - b))) pow 2`, + REWRITE_TAC[angle; SIN_SQUARED_VECTOR_ANGLE; VECTOR_SUB_EQ]);; + +(* ------------------------------------------------------------------------- *) +(* The law of cosines. *) +(* ------------------------------------------------------------------------- *) + +let LAW_OF_COSINES = prove + (`!A B C:real^N. + dist(B,C) pow 2 = (dist(A,B) pow 2 + dist(A,C) pow 2) - + &2 * dist(A,B) * dist(A,C) * cos(angle(B,A,C))`, + REPEAT GEN_TAC THEN + REWRITE_TAC[angle; ONCE_REWRITE_RULE[NORM_SUB] dist; GSYM VECTOR_ANGLE; + NORM_POW_2] THEN + VECTOR_ARITH_TAC);; + +(* ------------------------------------------------------------------------- *) +(* The law of sines. *) +(* ------------------------------------------------------------------------- *) + +let LAW_OF_SINES = prove + (`!A B C:real^N. + sin(angle(A,B,C)) * dist(B,C) = sin(angle(B,A,C)) * dist(A,C)`, + REPEAT GEN_TAC THEN MATCH_MP_TAC REAL_POW_EQ THEN EXISTS_TAC `2` THEN + SIMP_TAC[SIN_ANGLE_POS; DIST_POS_LE; REAL_LE_MUL; ARITH] THEN + REWRITE_TAC[REAL_POW_MUL; MATCH_MP + (REAL_ARITH `x + y = &1 ==> x = &1 - y`) (SPEC_ALL SIN_CIRCLE)] THEN + ASM_CASES_TAC `A:real^N = B` THEN ASM_REWRITE_TAC[ANGLE_REFL; COS_PI2] THEN + RULE_ASSUM_TAC(ONCE_REWRITE_RULE[GSYM VECTOR_SUB_EQ]) THEN + RULE_ASSUM_TAC(REWRITE_RULE[GSYM NORM_EQ_0]) THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_RING + `~(a = &0) ==> a pow 2 * x = a pow 2 * y ==> x = y`)) THEN + ONCE_REWRITE_TAC[DIST_SYM] THEN REWRITE_TAC[GSYM dist] THEN + GEN_REWRITE_TAC (RAND_CONV o LAND_CONV o ONCE_DEPTH_CONV) [DIST_SYM] THEN + REWRITE_TAC[REAL_RING + `a * (&1 - x) * b = c * (&1 - y) * d <=> + a * b - a * b * x = c * d - c * d * y`] THEN + REWRITE_TAC[GSYM REAL_POW_MUL; GSYM ANGLE] THEN + REWRITE_TAC[REAL_POW_MUL; dist; NORM_POW_2] THEN + REWRITE_TAC[DOT_LSUB; DOT_RSUB; DOT_SYM] THEN CONV_TAC REAL_RING);; + +(* ------------------------------------------------------------------------- *) +(* The sum of the angles of a triangle. *) +(* ------------------------------------------------------------------------- *) + +let TRIANGLE_ANGLE_SUM_LEMMA = prove + (`!A B C:real^N. ~(A = B) /\ ~(A = C) /\ ~(B = C) + ==> cos(angle(B,A,C) + angle(A,B,C) + angle(B,C,A)) = -- &1`, + REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[GSYM VECTOR_SUB_EQ] THEN + REWRITE_TAC[GSYM NORM_EQ_0] THEN + MP_TAC(ISPECL [`A:real^N`; `B:real^N`; `C:real^N`] LAW_OF_COSINES) THEN + MP_TAC(ISPECL [`B:real^N`; `A:real^N`; `C:real^N`] LAW_OF_COSINES) THEN + MP_TAC(ISPECL [`C:real^N`; `B:real^N`; `A:real^N`] LAW_OF_COSINES) THEN + MP_TAC(ISPECL [`A:real^N`; `B:real^N`; `C:real^N`] LAW_OF_SINES) THEN + MP_TAC(ISPECL [`B:real^N`; `A:real^N`; `C:real^N`] LAW_OF_SINES) THEN + MP_TAC(ISPECL [`B:real^N`; `C:real^N`; `A:real^N`] LAW_OF_SINES) THEN + REWRITE_TAC[COS_ADD; SIN_ADD; dist; NORM_SUB] THEN + MAP_EVERY (fun t -> MP_TAC(SPEC t SIN_CIRCLE)) + [`angle(B:real^N,A,C)`; `angle(A:real^N,B,C)`; `angle(B:real^N,C,A)`] THEN + REWRITE_TAC[COS_ADD; SIN_ADD; ANGLE_SYM] THEN CONV_TAC REAL_RING);; + +let COS_MINUS1_LEMMA = prove + (`!x. cos(x) = -- &1 /\ &0 <= x /\ x < &3 * pi ==> x = pi`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN `?n. integer n /\ x = n * pi` + (X_CHOOSE_THEN `nn:real` (CONJUNCTS_THEN2 ASSUME_TAC SUBST_ALL_TAC)) THEN + REWRITE_TAC[GSYM SIN_EQ_0] THENL + [MP_TAC(SPEC `x:real` SIN_CIRCLE) THEN ASM_REWRITE_TAC[] THEN + CONV_TAC REAL_RING; + ALL_TAC] THEN + SUBGOAL_THEN `?n. nn = &n` (X_CHOOSE_THEN `n:num` SUBST_ALL_TAC) THENL + [FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [REAL_MUL_POS_LE]) THEN + SIMP_TAC[PI_POS; REAL_ARITH `&0 < p ==> ~(p < &0) /\ ~(p = &0)`] THEN + ASM_MESON_TAC[INTEGER_POS; REAL_LT_LE]; + ALL_TAC] THEN + MATCH_MP_TAC(REAL_RING `n = &1 ==> n * p = p`) THEN + REWRITE_TAC[REAL_OF_NUM_EQ] THEN + MATCH_MP_TAC(ARITH_RULE `n < 3 /\ ~(n = 0) /\ ~(n = 2) ==> n = 1`) THEN + RULE_ASSUM_TAC(SIMP_RULE[REAL_LT_RMUL_EQ; PI_POS; REAL_OF_NUM_LT]) THEN + ASM_REWRITE_TAC[] THEN CONJ_TAC THEN DISCH_THEN SUBST_ALL_TAC THEN + REPEAT(POP_ASSUM MP_TAC) THEN SIMP_TAC[COS_0; REAL_MUL_LZERO; COS_NPI] THEN + REAL_ARITH_TAC);; + +let TRIANGLE_ANGLE_SUM = prove + (`!A B C:real^N. ~(A = B /\ B = C /\ A = C) + ==> angle(B,A,C) + angle(A,B,C) + angle(B,C,A) = pi`, + REPEAT GEN_TAC THEN MAP_EVERY ASM_CASES_TAC + [`A:real^N = B`; `B:real^N = C`; `A:real^N = C`] THEN + ASM_SIMP_TAC[ANGLE_REFL_MID; ANGLE_REFL; REAL_HALF; REAL_ADD_RID] THEN + REPEAT(FIRST_X_ASSUM SUBST_ALL_TAC) THEN + REPEAT(POP_ASSUM MP_TAC) THEN REWRITE_TAC[REAL_ADD_LID; REAL_HALF] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC COS_MINUS1_LEMMA THEN + ASM_SIMP_TAC[TRIANGLE_ANGLE_SUM_LEMMA; REAL_LE_ADD; ANGLE_RANGE] THEN + MATCH_MP_TAC(REAL_ARITH + `&0 <= x /\ x <= p /\ &0 <= y /\ y <= p /\ &0 <= z /\ z <= p /\ + ~(x = p /\ y = p /\ z = p) + ==> x + y + z < &3 * p`) THEN + ASM_SIMP_TAC[ANGLE_RANGE] THEN REPEAT STRIP_TAC THEN + REPEAT(FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [ANGLE_EQ_PI_DIST])) THEN + REPEAT(FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE RAND_CONV + [GSYM VECTOR_SUB_EQ])) THEN + REWRITE_TAC[GSYM NORM_EQ_0; dist; NORM_SUB] THEN REAL_ARITH_TAC);; + +(* ------------------------------------------------------------------------- *) +(* A few more lemmas about angles. *) +(* ------------------------------------------------------------------------- *) + +let ANGLE_EQ_PI_OTHERS = prove + (`!A B C:real^N. + angle(A,B,C) = pi + ==> angle(B,C,A) = &0 /\ angle(A,C,B) = &0 /\ + angle(B,A,C) = &0 /\ angle(C,A,B) = &0`, + REPEAT GEN_TAC THEN DISCH_TAC THEN + FIRST_ASSUM(STRIP_ASSUME_TAC o GEN_REWRITE_RULE I [ANGLE_EQ_PI_DIST]) THEN + MP_TAC(ISPECL [`A:real^N`; `B:real^N`; `C:real^N`] TRIANGLE_ANGLE_SUM) THEN + ASM_REWRITE_TAC[] THEN DISCH_THEN(MP_TAC o MATCH_MP (REAL_ARITH + `x + p + y = p ==> &0 <= x /\ &0 <= y ==> x = &0 /\ y = &0`)) THEN + SIMP_TAC[ANGLE_RANGE; ANGLE_SYM]);; + +let ANGLE_EQ_0_DIST = prove + (`!A B C:real^N. angle(A,B,C) = &0 <=> + ~(A = B) /\ ~(C = B) /\ + (dist(A,B) = dist(A,C) + dist(C,B) \/ + dist(B,C) = dist(A,C) + dist(A,B))`, + REPEAT GEN_TAC THEN + ASM_CASES_TAC `A:real^N = B` THENL + [ASM_REWRITE_TAC[angle; VECTOR_ANGLE_EQ_0; VECTOR_SUB_EQ]; ALL_TAC] THEN + ASM_CASES_TAC `B:real^N = C` THENL + [ASM_REWRITE_TAC[angle; VECTOR_ANGLE_EQ_0; VECTOR_SUB_EQ]; ALL_TAC] THEN + ASM_CASES_TAC `A:real^N = C` THENL + [ASM_SIMP_TAC[ANGLE_REFL_MID; DIST_REFL; REAL_ADD_LID]; ALL_TAC] THEN + EQ_TAC THENL + [ALL_TAC; + STRIP_TAC THENL + [MP_TAC(ISPECL[`A:real^N`; `C:real^N`; `B:real^N`] ANGLE_EQ_PI_DIST); + MP_TAC(ISPECL[`B:real^N`; `A:real^N`; `C:real^N`] ANGLE_EQ_PI_DIST)] THEN + ASM_REWRITE_TAC[] THEN REWRITE_TAC[DIST_SYM; REAL_ADD_AC] THEN + DISCH_THEN(MP_TAC o MATCH_MP ANGLE_EQ_PI_OTHERS) THEN SIMP_TAC[]] THEN + ASM_REWRITE_TAC[angle; VECTOR_ANGLE_EQ_0; VECTOR_SUB_EQ] THEN + REPEAT_TCL DISJ_CASES_THEN ASSUME_TAC + (ISPECL [`norm(A - B:real^N)`; `norm(C - B:real^N)`] + REAL_LT_TOTAL) + THENL + [ASM_REWRITE_TAC[VECTOR_MUL_LCANCEL; NORM_EQ_0; VECTOR_SUB_EQ; + VECTOR_ARITH `c - b:real^N = a - b <=> a = c`]; + ONCE_REWRITE_TAC[VECTOR_ARITH + `norm(A - B) % (C - B) = norm(C - B) % (A - B) <=> + (norm(C - B) - norm(A - B)) % (A - B) = norm(A - B) % (C - A)`]; + ONCE_REWRITE_TAC[VECTOR_ARITH + `norm(A - B) % (C - B) = norm(C - B) % (A - B) <=> + (norm(A - B) - norm(C - B)) % (C - B) = norm(C - B) % (A - C)`]] THEN + DISCH_THEN(MP_TAC o MATCH_MP + (REWRITE_RULE[IMP_CONJ] NORM_CROSS_MULTIPLY)) THEN + ASM_SIMP_TAC[REAL_SUB_LT; NORM_POS_LT; VECTOR_SUB_EQ] THEN + SIMP_TAC[GSYM DIST_TRIANGLE_EQ] THEN SIMP_TAC[DIST_SYM]);; + +let ANGLE_EQ_0_DIST_ABS = prove + (`!A B C:real^N. angle(A,B,C) = &0 <=> + ~(A = B) /\ ~(C = B) /\ + dist(A,C) = abs(dist(A,B) - dist(C,B))`, + REPEAT GEN_TAC THEN REWRITE_TAC[ANGLE_EQ_0_DIST] THEN + AP_TERM_TAC THEN AP_TERM_TAC THEN + MP_TAC(ISPECL [`A:real^N`; `C:real^N`] DIST_POS_LE) THEN + REWRITE_TAC[DIST_SYM] THEN REAL_ARITH_TAC);; + +(* ------------------------------------------------------------------------- *) +(* Some rules for congruent triangles (not necessarily in the same real^N). *) +(* ------------------------------------------------------------------------- *) + +let CONGRUENT_TRIANGLES_SSS = prove + (`!A B C:real^M A' B' C':real^N. + dist(A,B) = dist(A',B') /\ + dist(B,C) = dist(B',C') /\ + dist(C,A) = dist(C',A') + ==> angle(A,B,C) = angle(A',B',C')`, + REPEAT GEN_TAC THEN MAP_EVERY ASM_CASES_TAC + [`dist(A':real^N,B') = &0`; `dist(B':real^N,C') = &0`] THEN + ASM_REWRITE_TAC[] THEN STRIP_TAC THEN + RULE_ASSUM_TAC(REWRITE_RULE[DIST_EQ_0]) THEN + ASM_SIMP_TAC[ANGLE_REFL_MID; ANGLE_REFL] THEN + ONCE_REWRITE_TAC[GSYM COS_ANGLE_EQ] THEN + MP_TAC(ISPECL [`B:real^M`; `A:real^M`; `C:real^M`] LAW_OF_COSINES) THEN + MP_TAC(ISPECL [`B':real^N`; `A':real^N`; `C':real^N`] LAW_OF_COSINES) THEN + REPEAT(POP_ASSUM MP_TAC) THEN REWRITE_TAC[GSYM DIST_EQ_0; DIST_SYM] THEN + CONV_TAC REAL_FIELD);; + +let CONGRUENT_TRIANGLES_SAS = prove + (`!A B C:real^M A' B' C':real^N. + dist(A,B) = dist(A',B') /\ + angle(A,B,C) = angle(A',B',C') /\ + dist(B,C) = dist(B',C') + ==> dist(A,C) = dist(A',C')`, + REPEAT STRIP_TAC THEN REWRITE_TAC[DIST_EQ] THEN + MP_TAC(ISPECL [`B:real^M`; `A:real^M`; `C:real^M`] LAW_OF_COSINES) THEN + MP_TAC(ISPECL [`B':real^N`; `A':real^N`; `C':real^N`] LAW_OF_COSINES) THEN + REPEAT(DISCH_THEN SUBST1_TAC) THEN + REPEAT BINOP_TAC THEN ASM_MESON_TAC[DIST_SYM]);; + +let CONGRUENT_TRIANGLES_AAS = prove + (`!A B C:real^M A' B' C':real^N. + angle(A,B,C) = angle(A',B',C') /\ + angle(B,C,A) = angle(B',C',A') /\ + dist(A,B) = dist(A',B') /\ + ~(collinear {A,B,C}) + ==> dist(A,C) = dist(A',C') /\ dist(B,C) = dist(B',C')`, + REPEAT GEN_TAC THEN ASM_CASES_TAC `A:real^M = B` THENL + [FIRST_X_ASSUM SUBST_ALL_TAC THEN REWRITE_TAC[INSERT_AC; COLLINEAR_2]; + ALL_TAC] THEN + DISCH_TAC THEN SUBGOAL_THEN `~(A':real^N = B')` ASSUME_TAC THENL + [ASM_MESON_TAC[DIST_EQ_0]; ALL_TAC] THEN + SUBGOAL_THEN `angle(C:real^M,A,B) = angle(C':real^N,A',B')` ASSUME_TAC THENL + [MP_TAC(ISPECL [`A:real^M`; `B:real^M`; `C:real^M`] TRIANGLE_ANGLE_SUM) THEN + MP_TAC(ISPECL [`A':real^N`; `B':real^N`; `C':real^N`] + TRIANGLE_ANGLE_SUM) THEN ASM_REWRITE_TAC[IMP_IMP] THEN + REWRITE_TAC[ANGLE_SYM] THEN REAL_ARITH_TAC; + ALL_TAC] THEN + MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN CONJ_TAC THENL + [MP_TAC(ISPECL [`C:real^M`; `B:real^M`; `A:real^M`] LAW_OF_SINES) THEN + MP_TAC(ISPECL [`C':real^N`; `B':real^N`; `A':real^N`] LAW_OF_SINES) THEN + SUBGOAL_THEN `~(sin(angle(B':real^N,C',A')) = &0)` MP_TAC THENL + [ASM_MESON_TAC[COLLINEAR_SIN_ANGLE_IMP; INSERT_AC]; + ASM_REWRITE_TAC[] THEN ONCE_REWRITE_TAC[ANGLE_SYM; DIST_SYM] THEN + ASM_REWRITE_TAC[] THEN REWRITE_TAC[ANGLE_SYM; DIST_SYM] THEN + CONV_TAC REAL_FIELD]; + ASM_MESON_TAC[CONGRUENT_TRIANGLES_SAS; DIST_SYM; ANGLE_SYM]]);; + +let CONGRUENT_TRIANGLES_ASA = prove + (`!A B C:real^M A' B' C':real^N. + angle(A,B,C) = angle(A',B',C') /\ + dist(A,B) = dist(A',B') /\ + angle(B,A,C) = angle(B',A',C') /\ + ~(collinear {A,B,C}) + ==> dist(A,C) = dist(A',C')`, + REPEAT GEN_TAC THEN ASM_CASES_TAC `A:real^M = B` THENL + [FIRST_X_ASSUM SUBST_ALL_TAC THEN REWRITE_TAC[INSERT_AC; COLLINEAR_2]; + ALL_TAC] THEN + REPEAT STRIP_TAC THEN SUBGOAL_THEN `~(A':real^N = B')` ASSUME_TAC THENL + [ASM_MESON_TAC[DIST_EQ_0]; ALL_TAC] THEN + MP_TAC(ISPECL [`A:real^M`; `B:real^M`; `C:real^M`] TRIANGLE_ANGLE_SUM) THEN + MP_TAC(ISPECL [`A':real^N`; `B':real^N`; `C':real^N`] + TRIANGLE_ANGLE_SUM) THEN + ASM_REWRITE_TAC[IMP_IMP] THEN + DISCH_THEN(MP_TAC o MATCH_MP (REAL_ARITH + `a + b + x = pi /\ a + b + y = pi ==> x = y`)) THEN + ASM_MESON_TAC[CONGRUENT_TRIANGLES_AAS; DIST_SYM; ANGLE_SYM]);; + +(* ------------------------------------------------------------------------- *) +(* Full versions where we deduce everything from the conditions. *) +(* ------------------------------------------------------------------------- *) + +let CONGRUENT_TRIANGLES_SSS_FULL = prove + (`!A B C:real^M A' B' C':real^N. + dist(A,B) = dist(A',B') /\ + dist(B,C) = dist(B',C') /\ + dist(C,A) = dist(C',A') + ==> dist(A,B) = dist(A',B') /\ + dist(B,C) = dist(B',C') /\ + dist(C,A) = dist(C',A') /\ + angle(A,B,C) = angle(A',B',C') /\ + angle(B,C,A) = angle(B',C',A') /\ + angle(C,A,B) = angle(C',A',B')`, + MESON_TAC[CONGRUENT_TRIANGLES_SSS; DIST_SYM; ANGLE_SYM]);; + +let CONGRUENT_TRIANGLES_SAS_FULL = prove + (`!A B C:real^M A' B' C':real^N. + dist(A,B) = dist(A',B') /\ + angle(A,B,C) = angle(A',B',C') /\ + dist(B,C) = dist(B',C') + ==> dist(A,B) = dist(A',B') /\ + dist(B,C) = dist(B',C') /\ + dist(C,A) = dist(C',A') /\ + angle(A,B,C) = angle(A',B',C') /\ + angle(B,C,A) = angle(B',C',A') /\ + angle(C,A,B) = angle(C',A',B')`, + MESON_TAC[CONGRUENT_TRIANGLES_SSS; DIST_SYM; ANGLE_SYM; + CONGRUENT_TRIANGLES_SAS]);; + +let CONGRUENT_TRIANGLES_AAS_FULL = prove + (`!A B C:real^M A' B' C':real^N. + angle(A,B,C) = angle(A',B',C') /\ + angle(B,C,A) = angle(B',C',A') /\ + dist(A,B) = dist(A',B') /\ + ~(collinear {A,B,C}) + ==> dist(A,B) = dist(A',B') /\ + dist(B,C) = dist(B',C') /\ + dist(C,A) = dist(C',A') /\ + angle(A,B,C) = angle(A',B',C') /\ + angle(B,C,A) = angle(B',C',A') /\ + angle(C,A,B) = angle(C',A',B')`, + MESON_TAC[CONGRUENT_TRIANGLES_SSS; DIST_SYM; ANGLE_SYM; + CONGRUENT_TRIANGLES_AAS]);; + +let CONGRUENT_TRIANGLES_ASA_FULL = prove + (`!A B C:real^M A' B' C':real^N. + angle(A,B,C) = angle(A',B',C') /\ + dist(A,B) = dist(A',B') /\ + angle(B,A,C) = angle(B',A',C') /\ + ~(collinear {A,B,C}) + ==> dist(A,B) = dist(A',B') /\ + dist(B,C) = dist(B',C') /\ + dist(C,A) = dist(C',A') /\ + angle(A,B,C) = angle(A',B',C') /\ + angle(B,C,A) = angle(B',C',A') /\ + angle(C,A,B) = angle(C',A',B')`, + MESON_TAC[CONGRUENT_TRIANGLES_ASA; CONGRUENT_TRIANGLES_SAS_FULL; + DIST_SYM; ANGLE_SYM]);; + +(* ------------------------------------------------------------------------- *) +(* Between-ness. *) +(* ------------------------------------------------------------------------- *) + +let ANGLE_BETWEEN = prove + (`!a b x. angle(a,x,b) = pi <=> ~(x = a) /\ ~(x = b) /\ between x (a,b)`, + REPEAT GEN_TAC THEN REWRITE_TAC[between; ANGLE_EQ_PI_DIST] THEN + REWRITE_TAC[EQ_SYM_EQ]);; + +let BETWEEN_ANGLE = prove + (`!a b x. between x (a,b) <=> x = a \/ x = b \/ angle(a,x,b) = pi`, + REPEAT GEN_TAC THEN REWRITE_TAC[ANGLE_BETWEEN] THEN + MESON_TAC[BETWEEN_REFL]);; + +let ANGLES_ALONG_LINE = prove + (`!A B C D:real^N. + ~(C = A) /\ ~(C = B) /\ between C (A,B) + ==> angle(A,C,D) + angle(B,C,D) = pi`, + REPEAT GEN_TAC THEN REWRITE_TAC[GSYM ANGLE_BETWEEN] THEN + DISCH_THEN(SUBST1_TAC o MATCH_MP ANGLE_EQ_PI_LEFT) THEN REAL_ARITH_TAC);; + +let ANGLES_ADD_BETWEEN = prove + (`!A B C D:real^N. + between C (A,B) /\ ~(D = A) /\ ~(D = B) + ==> angle(A,D,C) + angle(C,D,B) = angle(A,D,B)`, + REPEAT GEN_TAC THEN ASM_CASES_TAC `A:real^N = B` THENL + [ASM_SIMP_TAC[BETWEEN_REFL_EQ] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + ASM_SIMP_TAC[ANGLE_REFL_MID; REAL_ADD_LID]; + ALL_TAC] THEN + ASM_CASES_TAC `C:real^N = A` THEN + ASM_SIMP_TAC[ANGLE_REFL_MID; REAL_ADD_LID] THEN + ASM_CASES_TAC `C:real^N = B` THEN + ASM_SIMP_TAC[ANGLE_REFL_MID; REAL_ADD_RID] THEN + STRIP_TAC THEN + MP_TAC(ISPECL [`A:real^N`; `B:real^N`; `C:real^N`; `D:real^N`] + ANGLES_ALONG_LINE) THEN + MP_TAC(ISPECL [`A:real^N`; `B:real^N`; `D:real^N`] TRIANGLE_ANGLE_SUM) THEN + MP_TAC(ISPECL [`A:real^N`; `C:real^N`; `D:real^N`] TRIANGLE_ANGLE_SUM) THEN + MP_TAC(ISPECL [`B:real^N`; `C:real^N`; `D:real^N`] TRIANGLE_ANGLE_SUM) THEN + ASM_REWRITE_TAC[] THEN + SUBGOAL_THEN `angle(C:real^N,A,D) = angle(B,A,D) /\ + angle(A,B,D) = angle(C,B,D)` + (CONJUNCTS_THEN SUBST1_TAC) + THENL [ALL_TAC; REWRITE_TAC[ANGLE_SYM] THEN REAL_ARITH_TAC] THEN + CONJ_TAC THEN MATCH_MP_TAC ANGLE_EQ_0_RIGHT THEN + ASM_MESON_TAC[ANGLE_EQ_PI_OTHERS; BETWEEN_ANGLE]);; diff --git a/Multivariate/integration.ml b/Multivariate/integration.ml new file mode 100644 index 0000000..a8e2d5f --- /dev/null +++ b/Multivariate/integration.ml @@ -0,0 +1,16782 @@ +(* ========================================================================= *) +(* 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. *) +(* ------------------------------------------------------------------------- *) + +let INTERIOR_SUBSET_UNION_INTERVALS = prove + (`!s i j. (?a b:real^N. i = interval[a,b]) /\ (?c d. j = interval[c,d]) /\ + ~(interior j = {}) /\ + i SUBSET j UNION s /\ + interior(i) INTER interior(j) = {} + ==> interior i SUBSET interior s`, + REPEAT STRIP_TAC THEN + REPEAT(FIRST_X_ASSUM(SUBST_ALL_TAC o check (is_var o lhs o concl))) THEN + MATCH_MP_TAC INTERIOR_MAXIMAL THEN REWRITE_TAC[OPEN_INTERIOR] THEN + RULE_ASSUM_TAC(REWRITE_RULE[INTERIOR_CLOSED_INTERVAL]) THEN + SUBGOAL_THEN `interval(a:real^N,b) INTER interval[c,d] = {}` ASSUME_TAC THENL + [ASM_SIMP_TAC[INTER_INTERVAL_MIXED_EQ_EMPTY]; + MP_TAC(ISPECL [`a:real^N`; `b:real^N`] INTERVAL_OPEN_SUBSET_CLOSED) THEN + REWRITE_TAC[INTERIOR_CLOSED_INTERVAL] THEN + REPEAT(POP_ASSUM MP_TAC) THEN SET_TAC[]]);; + +let INTER_INTERIOR_UNIONS_INTERVALS = prove + (`!s f. FINITE f /\ open s /\ + (!t. t IN f ==> ?a b:real^N. t = interval[a,b]) /\ + (!t. t IN f ==> s INTER (interior t) = {}) + ==> s INTER interior(UNIONS f) = {}`, + ONCE_REWRITE_TAC[TAUT + `a /\ b /\ c /\ d ==> e <=> a /\ b /\ c ==> ~e ==> ~d`] THEN + REWRITE_TAC[NOT_FORALL_THM; NOT_IMP; GSYM MEMBER_NOT_EMPTY] THEN + SIMP_TAC[OPEN_CONTAINS_BALL_EQ; OPEN_INTER; OPEN_INTERIOR] THEN + SIMP_TAC[OPEN_SUBSET_INTERIOR; OPEN_BALL; SUBSET_INTER] THEN + REWRITE_TAC[GSYM SUBSET_INTER] THEN + GEN_TAC THEN ONCE_REWRITE_TAC[IMP_CONJ] THEN + MATCH_MP_TAC FINITE_INDUCT_STRONG THEN CONJ_TAC THENL + [REWRITE_TAC[UNIONS_0; INTER_EMPTY; SUBSET_EMPTY] THEN + MESON_TAC[CENTRE_IN_BALL; NOT_IN_EMPTY]; + ALL_TAC] THEN + MAP_EVERY X_GEN_TAC [`i:real^N->bool`; `f:(real^N->bool)->bool`] THEN + DISCH_TAC THEN + REWRITE_TAC[UNIONS_INSERT; IN_INSERT] THEN + REWRITE_TAC[TAUT `a \/ b ==> c <=> (a ==> c) /\ (b ==> c)`] THEN + REWRITE_TAC[RIGHT_OR_DISTRIB; FORALL_AND_THM; EXISTS_OR_THM] THEN + REWRITE_TAC[GSYM CONJ_ASSOC; UNWIND_THM2] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + DISCH_THEN(CONJUNCTS_THEN2 MP_TAC STRIP_ASSUME_TAC) THEN + DISCH_THEN(MP_TAC o SPEC `i:real^N->bool`) THEN REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `a:real^N` (X_CHOOSE_THEN `b:real^N` + SUBST_ALL_TAC)) THEN + FIRST_X_ASSUM(CONJUNCTS_THEN2 MP_TAC STRIP_ASSUME_TAC) THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC(TAUT + `(r ==> s \/ p) ==> (p ==> q) ==> r ==> s \/ q`) THEN + POP_ASSUM_LIST(K ALL_TAC) THEN STRIP_TAC THEN + ASM_CASES_TAC `(x:real^N) IN interval[a,b]` THENL + [ALL_TAC; + SUBGOAL_THEN + `?d. &0 < d /\ ball(x,d) SUBSET ((:real^N) DIFF interval[a,b])` + STRIP_ASSUME_TAC THENL + [ASM_MESON_TAC[closed; OPEN_CONTAINS_BALL; CLOSED_INTERVAL; + IN_DIFF; IN_UNIV]; + ALL_TAC] THEN + DISJ2_TAC THEN MAP_EVERY EXISTS_TAC [`x:real^N`; `min d e`] THEN + ASM_REWRITE_TAC[REAL_LT_MIN; SUBSET] THEN + REPEAT(FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [SUBSET])) THEN + SIMP_TAC[IN_BALL; REAL_LT_MIN; IN_DIFF; IN_INTER; IN_UNIV; IN_UNION] THEN + ASM_MESON_TAC[]] THEN + ASM_CASES_TAC `(x:real^N) IN interval(a,b)` THENL + [DISJ1_TAC THEN + SUBGOAL_THEN + `?d. &0 < d /\ ball(x:real^N,d) SUBSET interval(a,b)` + STRIP_ASSUME_TAC THENL + [ASM_MESON_TAC[OPEN_CONTAINS_BALL; OPEN_INTERVAL]; ALL_TAC] THEN + MAP_EVERY EXISTS_TAC [`x:real^N`; `min d e`] THEN + ASM_REWRITE_TAC[REAL_LT_MIN; SUBSET] THEN + REPEAT(FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [SUBSET])) THEN + SIMP_TAC[IN_BALL; REAL_LT_MIN; IN_DIFF; IN_INTER; IN_UNIV; IN_UNION] THEN + ASM_MESON_TAC[INTERVAL_OPEN_SUBSET_CLOSED; SUBSET]; + ALL_TAC] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE RAND_CONV [IN_INTERVAL]) THEN + RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL]) THEN ASM_SIMP_TAC[REAL_LT_LE] THEN + REWRITE_TAC[NOT_FORALL_THM; NOT_IMP; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `k:num` THEN REWRITE_TAC[GSYM REAL_LT_LE; DE_MORGAN_THM] THEN + STRIP_TAC THEN DISJ2_TAC THENL + [EXISTS_TAC `x + --e / &2 % basis k :real^N`; + EXISTS_TAC `x + e / &2 % basis k :real^N`] THEN + EXISTS_TAC `e / &2` THEN ASM_REWRITE_TAC[REAL_HALF] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE + `b1 SUBSET k INTER (i UNION s) + ==> b2 SUBSET b1 /\ b2 INTER i = {} + ==> b2 SUBSET k INTER s`)) THEN + (CONJ_TAC THENL + [REWRITE_TAC[SUBSET; IN_BALL] THEN + GEN_TAC THEN MATCH_MP_TAC(NORM_ARITH `norm(d) = e / &2 ==> + dist(x + d,y) < e / &2 ==> dist(x,y) < e`) THEN + ASM_SIMP_TAC[NORM_MUL; NORM_BASIS] THEN UNDISCH_TAC `&0 < e` THEN + REAL_ARITH_TAC; + ALL_TAC]) THEN + REWRITE_TAC[EXTENSION; IN_INTER; IN_INTERVAL; NOT_IN_EMPTY] THEN + X_GEN_TAC `y:real^N` THEN REWRITE_TAC[IN_BALL; dist] THEN + REWRITE_TAC[TAUT `~(a /\ b) <=> a ==> ~b`] THEN + W(MP_TAC o C ISPEC COMPONENT_LE_NORM o rand o lhand o lhand o snd) THEN + DISCH_THEN(MP_TAC o SPEC `k:num`) THEN ASM_REWRITE_TAC[IMP_IMP] THEN + DISCH_THEN(MP_TAC o MATCH_MP (REAL_ARITH `x <= y /\ y < e ==> x < e`)) THEN + ASM_SIMP_TAC[VECTOR_SUB_COMPONENT; VECTOR_ADD_COMPONENT; + VECTOR_MUL_COMPONENT; BASIS_COMPONENT] THEN + DISCH_THEN(fun th -> DISCH_THEN(MP_TAC o SPEC `k:num`) THEN MP_TAC th) THEN + ASM_REWRITE_TAC[] THEN UNDISCH_TAC `&0 < e` THEN REAL_ARITH_TAC);; + +(* ------------------------------------------------------------------------- *) +(* This lemma about iterations comes up in a few places. *) +(* ------------------------------------------------------------------------- *) + +let ITERATE_NONZERO_IMAGE_LEMMA = prove + (`!op s f g a. + monoidal op /\ FINITE s /\ + g(a) = neutral op /\ + (!x y. x IN s /\ y IN s /\ f x = f y /\ ~(x = y) ==> g(f x) = neutral op) + ==> iterate op {f x | x | x IN s /\ ~(f x = a)} g = + iterate op s (g o f)`, + REPEAT STRIP_TAC THEN + GEN_REWRITE_TAC RAND_CONV [GSYM ITERATE_SUPPORT] THEN + REWRITE_TAC[support] THEN + ONCE_REWRITE_TAC[SET_RULE `{f x |x| x IN s /\ ~(f x = a)} = + IMAGE f {x | x IN s /\ ~(f x = a)}`] THEN + W(fun (asl,w) -> FIRST_ASSUM(fun th -> + MP_TAC(PART_MATCH (rand o rand) + (MATCH_MP ITERATE_IMAGE th) (rand w)))) THEN + ANTS_TAC THENL + [REWRITE_TAC[IN_ELIM_THM; o_THM] THEN ASM_MESON_TAC[]; ALL_TAC] THEN + DISCH_THEN(SUBST1_TAC o SYM) THEN + FIRST_ASSUM(MATCH_MP_TAC o MATCH_MP ITERATE_SUPERSET) THEN + ASM_SIMP_TAC[FINITE_IMAGE; FINITE_RESTRICT] THEN + REWRITE_TAC[IMP_CONJ; FORALL_IN_IMAGE; SUBSET] THEN + REWRITE_TAC[IN_ELIM_THM; IN_IMAGE; o_THM] THEN + ASM_MESON_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* Bounds on intervals where they exist. *) +(* ------------------------------------------------------------------------- *) + +let interval_upperbound = new_definition + `(interval_upperbound:(real^M->bool)->real^M) s = + lambda i. sup {a | ?x. x IN s /\ (x$i = a)}`;; + +let interval_lowerbound = new_definition + `(interval_lowerbound:(real^M->bool)->real^M) s = + lambda i. inf {a | ?x. x IN s /\ (x$i = a)}`;; + +let INTERVAL_UPPERBOUND = prove + (`!a b:real^N. (!i. 1 <= i /\ i <= dimindex(:N) ==> a$i <= b$i) + ==> interval_upperbound(interval[a,b]) = b`, + SIMP_TAC[interval_upperbound; CART_EQ; LAMBDA_BETA] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_SUP_UNIQUE THEN + REWRITE_TAC[IN_ELIM_THM; IN_INTERVAL] THEN ASM_MESON_TAC[REAL_LE_REFL]);; + +let INTERVAL_LOWERBOUND = prove + (`!a b:real^N. (!i. 1 <= i /\ i <= dimindex(:N) ==> a$i <= b$i) + ==> interval_lowerbound(interval[a,b]) = a`, + SIMP_TAC[interval_lowerbound; CART_EQ; LAMBDA_BETA] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_INF_UNIQUE THEN + REWRITE_TAC[IN_ELIM_THM; IN_INTERVAL] THEN ASM_MESON_TAC[REAL_LE_REFL]);; + +let INTERVAL_UPPERBOUND_1 = prove + (`!a b. drop a <= drop b ==> interval_upperbound(interval[a,b]) = b`, + SIMP_TAC[INTERVAL_UPPERBOUND; DIMINDEX_1; FORALL_1; drop]);; + +let INTERVAL_LOWERBOUND_1 = prove + (`!a b. drop a <= drop b ==> interval_lowerbound(interval[a,b]) = a`, + SIMP_TAC[INTERVAL_LOWERBOUND; DIMINDEX_1; FORALL_1; drop]);; + +(* ------------------------------------------------------------------------- *) +(* Content (length, area, volume...) of an interval. *) +(* ------------------------------------------------------------------------- *) + +let content = new_definition + `content(s:real^M->bool) = + if s = {} then &0 else + product(1..dimindex(:M)) + (\i. (interval_upperbound s)$i - (interval_lowerbound s)$i)`;; + +let CONTENT_CLOSED_INTERVAL = prove + (`!a b:real^N. (!i. 1 <= i /\ i <= dimindex(:N) ==> a$i <= b$i) + ==> content(interval[a,b]) = + product(1..dimindex(:N)) (\i. b$i - a$i)`, + SIMP_TAC[content; INTERVAL_UPPERBOUND; INTERVAL_EQ_EMPTY; + INTERVAL_LOWERBOUND] THEN + MESON_TAC[REAL_NOT_LT]);; + +let CONTENT_1 = prove + (`!a b. drop a <= drop b ==> content(interval[a,b]) = drop b - drop a`, + SIMP_TAC[CONTENT_CLOSED_INTERVAL; FORALL_1; drop; DIMINDEX_1] THEN + REWRITE_TAC[PRODUCT_SING_NUMSEG]);; + +let CONTENT_UNIT = prove + (`content(interval[vec 0:real^N,vec 1]) = &1`, + REWRITE_TAC[content] THEN COND_CASES_TAC THENL + [POP_ASSUM MP_TAC THEN CONV_TAC REAL_RAT_REDUCE_CONV THEN + SIMP_TAC[INTERVAL_NE_EMPTY; VEC_COMPONENT; REAL_POS]; + MATCH_MP_TAC PRODUCT_EQ_1 THEN + SIMP_TAC[INTERVAL_UPPERBOUND; INTERVAL_LOWERBOUND; + VEC_COMPONENT; REAL_POS; IN_NUMSEG; REAL_SUB_RZERO]]);; + +let CONTENT_UNIT_1 = prove + (`content(interval[vec 0:real^1,vec 1]) = &1`, + MATCH_ACCEPT_TAC CONTENT_UNIT);; + +let CONTENT_POS_LE = prove + (`!a b:real^N. &0 <= content(interval[a,b])`, + REPEAT GEN_TAC THEN REWRITE_TAC[content] THEN + COND_CASES_TAC THEN REWRITE_TAC[REAL_LE_REFL] THEN + MATCH_MP_TAC PRODUCT_POS_LE_NUMSEG THEN + RULE_ASSUM_TAC(REWRITE_RULE[INTERVAL_NE_EMPTY]) THEN + ASM_SIMP_TAC[INTERVAL_UPPERBOUND; INTERVAL_LOWERBOUND; REAL_SUB_LE]);; + +let CONTENT_POS_LT = prove + (`!a b:real^N. + (!i. 1 <= i /\ i <= dimindex(:N) ==> a$i < b$i) + ==> &0 < content(interval[a,b])`, + REPEAT STRIP_TAC THEN + ASM_SIMP_TAC[CONTENT_CLOSED_INTERVAL; REAL_LT_IMP_LE] THEN + MATCH_MP_TAC PRODUCT_POS_LT_NUMSEG THEN + ASM_SIMP_TAC[INTERVAL_UPPERBOUND; INTERVAL_LOWERBOUND; REAL_SUB_LT; + REAL_LT_IMP_LE]);; + +let CONTENT_POS_LT_1 = prove + (`!a b. drop a < drop b ==> &0 < content(interval[a,b])`, + SIMP_TAC[CONTENT_POS_LT; FORALL_1; DIMINDEX_1; GSYM drop]);; + +let CONTENT_EQ_0_GEN = prove + (`!s:real^N->bool. + bounded s + ==> (content s = &0 <=> + ?i a. 1 <= i /\ i <= dimindex(:N) /\ !x. x IN s ==> x$i = a)`, + REPEAT GEN_TAC THEN REWRITE_TAC[content] THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[NOT_IN_EMPTY] THENL + [MESON_TAC[DIMINDEX_GE_1; LE_REFL]; ALL_TAC] THEN + REWRITE_TAC[PRODUCT_EQ_0_NUMSEG; REAL_SUB_0] THEN DISCH_TAC THEN + AP_TERM_TAC THEN GEN_REWRITE_TAC I [FUN_EQ_THM] THEN + X_GEN_TAC `k:num` THEN + ASM_CASES_TAC `1 <= k` THEN ASM_REWRITE_TAC[] THEN + ASM_CASES_TAC `k <= dimindex(:N)` THEN ASM_REWRITE_TAC[] THEN + ASM_SIMP_TAC[interval_upperbound; interval_lowerbound; LAMBDA_BETA] THEN + W(MP_TAC o PART_MATCH (lhs o rand) REAL_SUP_EQ_INF o lhs o snd) THEN + ANTS_TAC THENL + [CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [bounded]) THEN + REWRITE_TAC[IN_ELIM_THM] THEN + ASM_MESON_TAC[COMPONENT_LE_NORM; REAL_LE_TRANS]; + DISCH_THEN SUBST1_TAC THEN ASM SET_TAC[]]);; + +let CONTENT_EQ_0 = prove + (`!a b:real^N. + content(interval[a,b]) = &0 <=> + ?i. 1 <= i /\ i <= dimindex(:N) /\ b$i <= a$i`, + REPEAT GEN_TAC THEN REWRITE_TAC[content; INTERVAL_EQ_EMPTY] THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[] THENL + [ASM_MESON_TAC[REAL_LT_IMP_LE]; ALL_TAC] THEN + REWRITE_TAC[PRODUCT_EQ_0_NUMSEG; REAL_SUB_0] THEN + AP_TERM_TAC THEN ABS_TAC THEN POP_ASSUM MP_TAC THEN + REWRITE_TAC[NOT_EXISTS_THM; TAUT `~(a /\ b /\ c) <=> a /\ b ==> ~c`] THEN + SIMP_TAC[REAL_NOT_LT; INTERVAL_LOWERBOUND; INTERVAL_UPPERBOUND] THEN + MESON_TAC[REAL_NOT_LE; REAL_LE_LT]);; + +let CONTENT_0_SUBSET_GEN = prove + (`!s t:real^N->bool. + s SUBSET t /\ bounded t /\ content t = &0 ==> content s = &0`, + REPEAT GEN_TAC THEN + REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + SUBGOAL_THEN `bounded(s:real^N->bool)` ASSUME_TAC THENL + [ASM_MESON_TAC[BOUNDED_SUBSET]; ALL_TAC] THEN + ASM_SIMP_TAC[CONTENT_EQ_0_GEN] THEN ASM SET_TAC[]);; + +let CONTENT_0_SUBSET = prove + (`!s a b:real^N. + s SUBSET interval[a,b] /\ content(interval[a,b]) = &0 + ==> content s = &0`, + MESON_TAC[CONTENT_0_SUBSET_GEN; BOUNDED_INTERVAL]);; + +let CONTENT_CLOSED_INTERVAL_CASES = prove + (`!a b:real^N. + content(interval[a,b]) = + if !i. 1 <= i /\ i <= dimindex(:N) ==> a$i <= b$i + then product(1..dimindex(:N)) (\i. b$i - a$i) + else &0`, + REPEAT GEN_TAC THEN COND_CASES_TAC THEN + ASM_SIMP_TAC[CONTENT_EQ_0; CONTENT_CLOSED_INTERVAL] THEN + ASM_MESON_TAC[REAL_LE_TOTAL]);; + +let CONTENT_EQ_0_INTERIOR = prove + (`!a b:real^N. + content(interval[a,b]) = &0 <=> interior(interval[a,b]) = {}`, + REWRITE_TAC[CONTENT_EQ_0; INTERIOR_CLOSED_INTERVAL; INTERVAL_EQ_EMPTY]);; + +let CONTENT_EQ_0_1 = prove + (`!a b:real^1. + content(interval[a,b]) = &0 <=> drop b <= drop a`, + REWRITE_TAC[CONTENT_EQ_0; drop; DIMINDEX_1; CONJ_ASSOC; LE_ANTISYM] THEN + MESON_TAC[]);; + +let CONTENT_POS_LT_EQ = prove + (`!a b:real^N. + &0 < content(interval[a,b]) <=> + !i. 1 <= i /\ i <= dimindex(:N) ==> a$i < b$i`, + REPEAT GEN_TAC THEN EQ_TAC THEN REWRITE_TAC[CONTENT_POS_LT] THEN + REWRITE_TAC[REAL_ARITH `&0 < x <=> &0 <= x /\ ~(x = &0)`] THEN + REWRITE_TAC[CONTENT_POS_LE; CONTENT_EQ_0] THEN MESON_TAC[REAL_NOT_LE]);; + +let CONTENT_EMPTY = prove + (`content {} = &0`, + REWRITE_TAC[content]);; + +let CONTENT_SUBSET = prove + (`!a b c d:real^N. + interval[a,b] SUBSET interval[c,d] + ==> content(interval[a,b]) <= content(interval[c,d])`, + REPEAT STRIP_TAC THEN GEN_REWRITE_TAC LAND_CONV [content] THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[CONTENT_POS_LE] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [SUBSET]) THEN + RULE_ASSUM_TAC(REWRITE_RULE[INTERVAL_NE_EMPTY]) THEN + REWRITE_TAC[IN_INTERVAL] THEN DISCH_THEN(fun th -> + MP_TAC(SPEC `a:real^N` th) THEN MP_TAC(SPEC `b:real^N` th)) THEN + ASM_SIMP_TAC[REAL_LE_REFL; content] THEN REPEAT STRIP_TAC THEN + ONCE_REWRITE_TAC[TAUT `(if b then c else d) = (if ~b then d else c)`] THEN + REWRITE_TAC[INTERVAL_NE_EMPTY] THEN COND_CASES_TAC THENL + [ALL_TAC; ASM_MESON_TAC[REAL_LE_TRANS]] THEN + MATCH_MP_TAC PRODUCT_LE_NUMSEG THEN + ASM_SIMP_TAC[INTERVAL_LOWERBOUND; INTERVAL_UPPERBOUND] THEN + REPEAT(POP_ASSUM MP_TAC) THEN REWRITE_TAC[IMP_IMP; AND_FORALL_THM] THEN + MATCH_MP_TAC MONO_FORALL THEN GEN_TAC THEN + DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN ASM_REWRITE_TAC[] THEN + REAL_ARITH_TAC);; + +let CONTENT_LT_NZ = prove + (`!a b. &0 < content(interval[a,b]) <=> ~(content(interval[a,b]) = &0)`, + REWRITE_TAC[CONTENT_POS_LT_EQ; CONTENT_EQ_0] THEN MESON_TAC[REAL_NOT_LE]);; + +let INTERVAL_BOUNDS_NULL_1 = prove + (`!a b:real^1. + content(interval[a,b]) = &0 + ==> interval_upperbound(interval[a,b]) = + interval_lowerbound(interval[a,b])`, + REPEAT GEN_TAC THEN ASM_CASES_TAC `interval[a:real^1,b] = {}` THENL + [ASM_REWRITE_TAC[interval_upperbound; interval_lowerbound] THEN + REWRITE_TAC[sup; inf; NOT_IN_EMPTY; EMPTY_GSPEC] THEN DISCH_TAC THEN + REPLICATE_TAC 2 (AP_TERM_TAC THEN ABS_TAC) THEN + MESON_TAC[REAL_ARITH `~(x <= x - &1) /\ ~(x + &1 <= x)`]; + RULE_ASSUM_TAC(REWRITE_RULE[INTERVAL_EQ_EMPTY_1; REAL_NOT_LT]) THEN + ASM_SIMP_TAC[INTERVAL_UPPERBOUND_1; INTERVAL_LOWERBOUND_1] THEN + REWRITE_TAC[CONTENT_EQ_0_1; GSYM DROP_EQ] THEN ASM_REAL_ARITH_TAC]);; + +let INTERVAL_BOUNDS_EMPTY_1 = prove + (`interval_upperbound({}:real^1->bool) = + interval_lowerbound({}:real^1->bool)`, + MESON_TAC[INTERVAL_BOUNDS_NULL_1; CONTENT_EMPTY; EMPTY_AS_INTERVAL]);; + +let CONTENT_PASTECART = prove + (`!a b:real^M c d:real^N. + content(interval[pastecart a c,pastecart b d]) = + content(interval[a,b]) * content(interval[c,d])`, + REPEAT GEN_TAC THEN + SIMP_TAC[CONTENT_CLOSED_INTERVAL_CASES; LAMBDA_BETA] THEN + MATCH_MP_TAC(MESON[REAL_MUL_LZERO; REAL_MUL_RZERO] + `(p <=> p1 /\ p2) /\ z = x * y + ==> (if p then z else &0) = + (if p1 then x else &0) * (if p2 then y else &0)`) THEN + CONJ_TAC THENL + [EQ_TAC THEN DISCH_TAC THEN TRY CONJ_TAC THEN X_GEN_TAC `i:num` THEN + STRIP_TAC THENL + [FIRST_X_ASSUM(MP_TAC o SPEC `i:num`) THEN + ASM_SIMP_TAC[pastecart; LAMBDA_BETA; DIMINDEX_FINITE_SUM] THEN + DISCH_THEN MATCH_MP_TAC THEN ASM_ARITH_TAC; + FIRST_X_ASSUM(MP_TAC o SPEC `i + dimindex(:M)`) THEN + ASM_SIMP_TAC[pastecart; LAMBDA_BETA; DIMINDEX_FINITE_SUM] THEN + ANTS_TAC THENL [ASM_ARITH_TAC; REWRITE_TAC[ADD_SUB]] THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN ASM_ARITH_TAC; + RULE_ASSUM_TAC(REWRITE_RULE[DIMINDEX_FINITE_SUM]) THEN + ASM_CASES_TAC `i <= dimindex(:M)` THENL + [FIRST_X_ASSUM(MP_TAC o SPEC `i:num` o CONJUNCT1); + FIRST_X_ASSUM(MP_TAC o SPEC `i - dimindex(:M)` o CONJUNCT2)] THEN + ASM_SIMP_TAC[pastecart; LAMBDA_BETA; DIMINDEX_FINITE_SUM; + ARITH_RULE `i:num <= m ==> i <= m + n`] THEN + DISCH_THEN MATCH_MP_TAC THEN ASM_ARITH_TAC]; + SIMP_TAC[DIMINDEX_FINITE_SUM; ARITH_RULE `1 <= n + 1`; + PRODUCT_ADD_SPLIT] THEN + BINOP_TAC THENL + [ALL_TAC; + ONCE_REWRITE_TAC[ADD_SYM] THEN REWRITE_TAC[PRODUCT_OFFSET]] THEN + MATCH_MP_TAC PRODUCT_EQ_NUMSEG THEN + SIMP_TAC[pastecart; LAMBDA_BETA; DIMINDEX_FINITE_SUM; ADD_SUB; + ARITH_RULE `i:num <= m ==> i <= m + n`; + ARITH_RULE `i:num <= n ==> i + m <= m + n`] THEN + REPEAT STRIP_TAC THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN + ASM_ARITH_TAC]);; + +(* ------------------------------------------------------------------------- *) +(* The notion of a gauge --- simply an open set containing the point. *) +(* ------------------------------------------------------------------------- *) + +let gauge = new_definition + `gauge d <=> !x. x IN d(x) /\ open(d(x))`;; + +let GAUGE_BALL_DEPENDENT = prove + (`!e. (!x. &0 < e(x)) ==> gauge(\x. ball(x,e(x)))`, + SIMP_TAC[gauge; OPEN_BALL; IN_BALL; DIST_REFL]);; + +let GAUGE_BALL = prove + (`!e. &0 < e ==> gauge (\x. ball(x,e))`, + SIMP_TAC[gauge; OPEN_BALL; IN_BALL; DIST_REFL]);; + +let GAUGE_TRIVIAL = prove + (`gauge (\x. ball(x,&1))`, + SIMP_TAC[GAUGE_BALL; REAL_LT_01]);; + +let GAUGE_INTER = prove + (`!d1 d2. gauge d1 /\ gauge d2 ==> gauge (\x. (d1 x) INTER (d2 x))`, + SIMP_TAC[gauge; IN_INTER; OPEN_INTER]);; + +let GAUGE_INTERS = prove + (`!s. FINITE s /\ (!d. d IN s ==> gauge (f d)) + ==> gauge(\x. INTERS {f d x | d IN s})`, + REWRITE_TAC[gauge; IN_INTERS] THEN + REWRITE_TAC[SET_RULE `{f d x | d IN s} = IMAGE (\d. f d x) s`] THEN + SIMP_TAC[FORALL_IN_IMAGE; OPEN_INTERS; FINITE_IMAGE]);; + +let GAUGE_EXISTENCE_LEMMA = prove + (`(!x. ?d. p x ==> &0 < d /\ q d x) <=> + (!x. ?d. &0 < d /\ (p x ==> q d x))`, + MESON_TAC[REAL_LT_01]);; + +(* ------------------------------------------------------------------------- *) +(* Divisions. *) +(* ------------------------------------------------------------------------- *) + +parse_as_infix("division_of",(12,"right"));; + +let division_of = new_definition + `s division_of i <=> + FINITE s /\ + (!k. k IN s + ==> k SUBSET i /\ ~(k = {}) /\ ?a b. k = interval[a,b]) /\ + (!k1 k2. k1 IN s /\ k2 IN s /\ ~(k1 = k2) + ==> interior(k1) INTER interior(k2) = {}) /\ + (UNIONS s = i)`;; + +let DIVISION_OF = prove + (`s division_of i <=> + FINITE s /\ + (!k. k IN s ==> ~(k = {}) /\ ?a b. k = interval[a,b]) /\ + (!k1 k2. k1 IN s /\ k2 IN s /\ ~(k1 = k2) + ==> interior(k1) INTER interior(k2) = {}) /\ + UNIONS s = i`, + REWRITE_TAC[division_of] THEN SET_TAC[]);; + +let DIVISION_OF_FINITE = prove + (`!s i. s division_of i ==> FINITE s`, + MESON_TAC[division_of]);; + +let DIVISION_OF_SELF = prove + (`!a b. ~(interval[a,b] = {}) ==> {interval[a,b]} division_of interval[a,b]`, + REWRITE_TAC[division_of; FINITE_INSERT; FINITE_RULES; IN_SING; UNIONS_1] THEN + MESON_TAC[SUBSET_REFL]);; + +let DIVISION_OF_TRIVIAL = prove + (`!s. s division_of {} <=> s = {}`, + REWRITE_TAC[division_of; SUBSET_EMPTY; CONJ_ASSOC] THEN + REWRITE_TAC[TAUT `~(p /\ ~p)`; GSYM NOT_EXISTS_THM; MEMBER_NOT_EMPTY] THEN + REWRITE_TAC[AC CONJ_ACI `((a /\ b) /\ c) /\ d <=> b /\ a /\ c /\ d`] THEN + GEN_TAC THEN MATCH_MP_TAC(TAUT `(a ==> b) ==> (a /\ b <=> a)`) THEN + DISCH_THEN SUBST1_TAC THEN + REWRITE_TAC[FINITE_RULES; UNIONS_0; NOT_IN_EMPTY]);; + +let EMPTY_DIVISION_OF = prove + (`!s. {} division_of s <=> s = {}`, + REWRITE_TAC[division_of; UNIONS_0; FINITE_EMPTY; NOT_IN_EMPTY] THEN + MESON_TAC[]);; + +let DIVISION_OF_SING = prove + (`!s a. s division_of interval[a,a] <=> s = {interval[a,a]}`, + let lemma = prove + (`s SUBSET {{a}} /\ p /\ UNIONS s = {a} <=> s = {{a}} /\ p`, + EQ_TAC THEN STRIP_TAC THEN + ASM_REWRITE_TAC[SET_RULE `UNIONS {a} = a`] THEN ASM SET_TAC[]) in + REWRITE_TAC[division_of; INTERVAL_SING] THEN + REWRITE_TAC[SET_RULE `k SUBSET {a} /\ ~(k = {}) /\ p <=> k = {a} /\ p`] THEN + REWRITE_TAC[GSYM INTERVAL_SING] THEN + REWRITE_TAC[MESON[] `(k = interval[a,b] /\ ?c d. k = interval[c,d]) <=> + (k = interval[a,b])`] THEN + REWRITE_TAC[SET_RULE `(!k. k IN s ==> k = a) <=> s SUBSET {a}`] THEN + REWRITE_TAC[INTERVAL_SING; lemma] THEN MESON_TAC[FINITE_RULES; IN_SING]);; + +let ELEMENTARY_EMPTY = prove + (`?p. p division_of {}`, + REWRITE_TAC[DIVISION_OF_TRIVIAL; EXISTS_REFL]);; + +let ELEMENTARY_INTERVAL = prove + (`!a b. ?p. p division_of interval[a,b]`, + MESON_TAC[DIVISION_OF_TRIVIAL; DIVISION_OF_SELF]);; + +let DIVISION_CONTAINS = prove + (`!s i. s division_of i ==> !x. x IN i ==> ?k. x IN k /\ k IN s`, + REWRITE_TAC[division_of; EXTENSION; IN_UNIONS] THEN MESON_TAC[]);; + +let FORALL_IN_DIVISION = prove + (`!P d i. d division_of i + ==> ((!x. x IN d ==> P x) <=> + (!a b. interval[a,b] IN d ==> P(interval[a,b])))`, + REWRITE_TAC[division_of] THEN MESON_TAC[]);; + +let FORALL_IN_DIVISION_NONEMPTY = prove + (`!P d i. + d division_of i + ==> ((!x. x IN d ==> P x) <=> + (!a b. interval [a,b] IN d /\ ~(interval[a,b] = {}) + ==> P (interval [a,b])))`, + REWRITE_TAC[division_of] THEN MESON_TAC[]);; + +let DIVISION_OF_SUBSET = prove + (`!p q:(real^N->bool)->bool. + p division_of (UNIONS p) /\ q SUBSET p ==> q division_of (UNIONS q)`, + REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN + REWRITE_TAC[division_of] THEN + REPEAT(MATCH_MP_TAC MONO_AND THEN CONJ_TAC) THENL + [ASM_MESON_TAC[FINITE_SUBSET]; ASM SET_TAC[]; ASM SET_TAC[]]);; + +let DIVISION_OF_UNION_SELF = prove + (`!p s. p division_of s ==> p division_of (UNIONS p)`, + REWRITE_TAC[division_of] THEN MESON_TAC[]);; + +let DIVISION_OF_CONTENT_0 = prove + (`!a b d. content(interval[a,b]) = &0 /\ d division_of interval[a,b] + ==> !k. k IN d ==> content k = &0`, + REPEAT GEN_TAC THEN STRIP_TAC THEN + FIRST_ASSUM(fun th -> REWRITE_TAC[MATCH_MP FORALL_IN_DIVISION th]) THEN + REWRITE_TAC[GSYM REAL_LE_ANTISYM; CONTENT_POS_LE] THEN + ASM_MESON_TAC[CONTENT_SUBSET; division_of]);; + +let DIVISION_INTER = prove + (`!s1 s2:real^N->bool p1 p2. + p1 division_of s1 /\ + p2 division_of s2 + ==> {k1 INTER k2 | k1 IN p1 /\ k2 IN p2 /\ ~(k1 INTER k2 = {})} + division_of (s1 INTER s2)`, + let lemma = prove + (`{k1 INTER k2 | k1 IN p1 /\ k2 IN p2 /\ ~(k1 INTER k2 = {})} = + {s | s IN IMAGE (\(k1,k2). k1 INTER k2) (p1 CROSS p2) /\ + ~(s = {})}`, + REWRITE_TAC[EXTENSION] THEN + REWRITE_TAC[IN_IMAGE; IN_ELIM_THM; EXISTS_PAIR_THM; IN_CROSS] THEN + MESON_TAC[]) in + REPEAT GEN_TAC THEN REWRITE_TAC[DIVISION_OF] THEN STRIP_TAC THEN + ASM_SIMP_TAC[lemma; FINITE_RESTRICT; FINITE_CROSS; FINITE_IMAGE] THEN + REWRITE_TAC[IN_ELIM_THM] THEN + REWRITE_TAC[IMP_CONJ; FORALL_IN_IMAGE; RIGHT_FORALL_IMP_THM] THEN + REWRITE_TAC[FORALL_PAIR_THM; IN_CROSS] THEN REPEAT CONJ_TAC THENL + [ASM_MESON_TAC[INTER_INTERVAL]; + REPEAT STRIP_TAC THEN + MATCH_MP_TAC(SET_RULE + `(interior x1 INTER interior x2 = {} \/ + interior y1 INTER interior y2 = {}) /\ + interior(x1 INTER y1) SUBSET interior(x1) /\ + interior(x1 INTER y1) SUBSET interior(y1) /\ + interior(x2 INTER y2) SUBSET interior(x2) /\ + interior(x2 INTER y2) SUBSET interior(y2) + ==> interior(x1 INTER y1) INTER interior(x2 INTER y2) = {}`) THEN + CONJ_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN + REPEAT CONJ_TAC THEN MATCH_MP_TAC SUBSET_INTERIOR THEN SET_TAC[]; + REWRITE_TAC[SET_RULE `UNIONS {x | x IN s /\ ~(x = {})} = UNIONS s`] THEN + REPEAT(FIRST_X_ASSUM(SUBST_ALL_TAC o SYM)) THEN + GEN_REWRITE_TAC I [EXTENSION] THEN + REWRITE_TAC[IN_UNIONS; IN_IMAGE; EXISTS_PAIR_THM; IN_CROSS; IN_INTER] THEN + MESON_TAC[IN_INTER]]);; + +let DIVISION_INTER_1 = prove + (`!d i a b:real^N. + d division_of i /\ interval[a,b] SUBSET i + ==> { interval[a,b] INTER k | k | + k IN d /\ ~(interval[a,b] INTER k = {}) } + division_of interval[a,b]`, + REPEAT STRIP_TAC THEN + ASM_CASES_TAC `interval[a:real^N,b] = {}` THEN + ASM_REWRITE_TAC[INTER_EMPTY; SET_RULE `{{} | F} = {}`; + DIVISION_OF_TRIVIAL] THEN + MP_TAC(ISPECL [`interval[a:real^N,b]`; `i:real^N->bool`; + `{interval[a:real^N,b]}`; `d:(real^N->bool)->bool`] + DIVISION_INTER) THEN + ASM_SIMP_TAC[DIVISION_OF_SELF; SET_RULE `s SUBSET t ==> s INTER t = s`] THEN + MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_TERM_TAC THEN SET_TAC[]);; + +let ELEMENTARY_INTER = prove + (`!s t. (?p. p division_of s) /\ (?p. p division_of t) + ==> ?p. p division_of (s INTER t)`, + MESON_TAC[DIVISION_INTER]);; + +let ELEMENTARY_INTERS = prove + (`!f:(real^N->bool)->bool. + FINITE f /\ ~(f = {}) /\ + (!s. s IN f ==> ?p. p division_of s) + ==> ?p. p division_of (INTERS f)`, + REWRITE_TAC[IMP_CONJ] THEN MATCH_MP_TAC FINITE_INDUCT_STRONG THEN + REWRITE_TAC[INTERS_INSERT] THEN + MAP_EVERY X_GEN_TAC [`s:real^N->bool`; `s:(real^N->bool)->bool`] THEN + ASM_CASES_TAC `s:(real^N->bool)->bool = {}` THEN ASM_REWRITE_TAC[] THENL + [REWRITE_TAC[INTERS_0; INTER_UNIV; IN_SING] THEN MESON_TAC[]; + REWRITE_TAC[IN_INSERT] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC ELEMENTARY_INTER THEN ASM_MESON_TAC[]]);; + +let DIVISION_DISJOINT_UNION = prove + (`!s1 s2:real^N->bool p1 p2. + p1 division_of s1 /\ + p2 division_of s2 /\ + interior s1 INTER interior s2 = {} + ==> (p1 UNION p2) division_of (s1 UNION s2)`, + REPEAT GEN_TAC THEN REWRITE_TAC[division_of] THEN STRIP_TAC THEN + ASM_REWRITE_TAC[FINITE_UNION; IN_UNION; EXISTS_OR_THM; SET_RULE + `UNIONS {x | P x \/ Q x} = UNIONS {x | P x} UNION UNIONS {x | Q x}`] THEN + CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + CONJ_TAC THENL [ALL_TAC; ASM SET_TAC[]] THEN + REPEAT STRIP_TAC THENL + [ASM SET_TAC[]; ALL_TAC; ALL_TAC; ASM SET_TAC[]] THEN + MATCH_MP_TAC(SET_RULE + `!s' t'. s SUBSET s' /\ t SUBSET t' /\ s' INTER t' = {} + ==> s INTER t = {}`) + THENL + [MAP_EVERY EXISTS_TAC + [`interior s1:real^N->bool`; `interior s2:real^N->bool`]; + MAP_EVERY EXISTS_TAC + [`interior s2:real^N->bool`; `interior s1:real^N->bool`]] THEN + REPEAT CONJ_TAC THEN TRY(MATCH_MP_TAC SUBSET_INTERIOR) THEN + ASM SET_TAC[]);; + +let PARTIAL_DIVISION_EXTEND_1 = prove + (`!a b c d:real^N. + interval[c,d] SUBSET interval[a,b] /\ ~(interval[c,d] = {}) + ==> ?p. p division_of interval[a,b] /\ + interval[c,d] IN p`, + REPEAT STRIP_TAC THEN ASM_CASES_TAC `interval[a:real^N,b] = {}` THENL + [ASM SET_TAC[]; ALL_TAC] THEN + REPEAT(FIRST_X_ASSUM(STRIP_ASSUME_TAC o + GEN_REWRITE_RULE I [INTERVAL_NE_EMPTY])) THEN + EXISTS_TAC + `{interval + [(lambda i. if i < l then (c:real^N)$i else (a:real^N)$i):real^N, + (lambda i. if i < l then d$i else if i = l then c$l else b$i)] | + l IN 1..(dimindex(:N)+1)} UNION + {interval + [(lambda i. if i < l then c$i else if i = l then d$l else a$i), + (lambda i. if i < l then (d:real^N)$i else (b:real^N)$i):real^N] | + l IN 1..(dimindex(:N)+1)}` THEN + MATCH_MP_TAC(TAUT `b /\ (b ==> a) ==> a /\ b`) THEN CONJ_TAC THENL + [REWRITE_TAC[IN_UNION] THEN DISJ1_TAC THEN + REWRITE_TAC[IN_ELIM_THM] THEN EXISTS_TAC `dimindex(:N)+1` THEN + REWRITE_TAC[IN_NUMSEG; LE_REFL; ARITH_RULE `1 <= n + 1`] THEN + AP_TERM_TAC THEN SIMP_TAC[CONS_11; PAIR_EQ; CART_EQ; LAMBDA_BETA] THEN + SIMP_TAC[ARITH_RULE `i <= n ==> i < n + 1`]; + DISCH_TAC] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [SUBSET_INTERVAL]) THEN + ASM_REWRITE_TAC[DIVISION_OF] THEN DISCH_TAC THEN REPEAT CONJ_TAC THENL + [REWRITE_TAC[SIMPLE_IMAGE] THEN + SIMP_TAC[FINITE_UNION; FINITE_IMAGE; FINITE_NUMSEG]; + REWRITE_TAC[IN_UNION; TAUT `a \/ b ==> c <=> (a ==> c) /\ (b ==> c)`] THEN + REWRITE_TAC[SIMPLE_IMAGE; FORALL_AND_THM; FORALL_IN_IMAGE] THEN + ASM_SIMP_TAC[IN_NUMSEG; INTERVAL_NE_EMPTY; LAMBDA_BETA] THEN + CONJ_TAC THEN X_GEN_TAC `l:num` THEN DISCH_TAC THEN + (CONJ_TAC THENL [ALL_TAC; MESON_TAC[]]) THEN + REPEAT STRIP_TAC THEN + REPEAT(COND_CASES_TAC THEN ASM_SIMP_TAC[]) THEN + ASM_MESON_TAC[REAL_LE_TRANS]; + REWRITE_TAC[IN_UNION; IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN + REWRITE_TAC[SET_RULE + `(!y. y IN {f x | x IN s} \/ y IN {g x | x IN s} ==> P y) <=> + (!x. x IN s ==> P(f x) /\ P(g x))`] THEN + REWRITE_TAC[AND_FORALL_THM; IN_NUMSEG] THEN + REWRITE_TAC[TAUT `(a ==> b) /\ (a ==> c) <=> a ==> b /\ c`] THEN + REWRITE_TAC[RIGHT_IMP_FORALL_THM] THEN + MATCH_MP_TAC WLOG_LE THEN CONJ_TAC THENL + [REPEAT GEN_TAC THEN + REWRITE_TAC[TAUT `a ==> b ==> c <=> b ==> a ==> c`] THEN + REWRITE_TAC[INTER_ACI; CONJ_ACI] THEN MESON_TAC[]; + ALL_TAC] THEN + MAP_EVERY X_GEN_TAC [`l:num`; `m:num`] THEN + DISCH_TAC THEN STRIP_TAC THEN STRIP_TAC THEN + ONCE_REWRITE_TAC[TAUT `(~p ==> q) <=> (~q ==> p)`] THEN + REWRITE_TAC[INTERIOR_CLOSED_INTERVAL] THEN + REWRITE_TAC[SET_RULE `s INTER t = {} <=> !x. ~(x IN s /\ x IN t)`] THEN + ASM_SIMP_TAC[IN_NUMSEG; INTERVAL_NE_EMPTY; LAMBDA_BETA; IN_INTERVAL; + 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 REPEAT CONJ_TAC THEN + DISCH_THEN(X_CHOOSE_THEN `x:real^N` (LABEL_TAC "*")) THEN + AP_TERM_TAC THEN SIMP_TAC[CONS_11; PAIR_EQ; CART_EQ; LAMBDA_BETA] THENL + (let tac1 = + UNDISCH_TAC `l:num <= m` THEN GEN_REWRITE_TAC LAND_CONV [LE_LT] THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + REMOVE_THEN "*" (MP_TAC o SPEC `l:num`) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN + ASM_REWRITE_TAC[LT_REFL] THEN REAL_ARITH_TAC + and tac2 = + UNDISCH_TAC `l:num <= m` THEN GEN_REWRITE_TAC LAND_CONV [LE_LT] THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THENL + [REMOVE_THEN "*" (MP_TAC o SPEC `l:num`) THEN ANTS_TAC THENL + [ASM_ARITH_TAC; ALL_TAC] THEN + ASM_REWRITE_TAC[LT_REFL] THEN REAL_ARITH_TAC; + ALL_TAC] THEN + FIRST_X_ASSUM(SUBST_ALL_TAC o SYM) THEN + CONJ_TAC THEN X_GEN_TAC `i:num` THEN ASM_CASES_TAC `i:num = l` THEN + ASM_REWRITE_TAC[LT_REFL] THEN FIRST_X_ASSUM SUBST_ALL_TAC THEN + DISCH_TAC THEN REPEAT(FIRST_X_ASSUM(MP_TAC o SPEC `l:num`)) THEN + ASM_REWRITE_TAC[LT_REFL] THEN REAL_ARITH_TAC in + [tac1; tac2; tac2; tac1]); + MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL + [REWRITE_TAC[IMP_CONJ; SUBSET; FORALL_IN_UNIONS; SIMPLE_IMAGE] THEN + REWRITE_TAC[IN_UNIONS; IN_INSERT; IN_UNION; FORALL_IN_IMAGE; + RIGHT_FORALL_IMP_THM; FORALL_AND_THM; + TAUT `(a \/ b ==> c) <=> (a ==> c) /\ (b ==> c)`] THEN + ASM_SIMP_TAC[IN_INTERVAL; IN_NUMSEG; LAMBDA_BETA] THEN + REPEAT CONJ_TAC THEN GEN_TAC THEN DISCH_TAC THEN GEN_TAC THEN + MATCH_MP_TAC MONO_FORALL THEN GEN_TAC THEN + ASM_MESON_TAC[REAL_LE_TRANS]; + ALL_TAC] THEN + FIRST_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE + `a IN s ==> (c DIFF a) SUBSET UNIONS s ==> c SUBSET UNIONS s`)) THEN + REWRITE_TAC[SUBSET; IN_DIFF; IN_INTERVAL] THEN X_GEN_TAC `x:real^N` THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + REWRITE_TAC[NOT_FORALL_THM; NOT_IMP] THEN + GEN_REWRITE_TAC LAND_CONV [num_WOP] THEN + REWRITE_TAC[TAUT `a ==> ~(b /\ ~c) <=> a /\ b ==> c`] THEN + DISCH_THEN(X_CHOOSE_THEN `l:num` STRIP_ASSUME_TAC) THEN + REWRITE_TAC[IN_UNIONS; SIMPLE_IMAGE; EXISTS_IN_IMAGE; IN_UNION; + EXISTS_OR_THM; RIGHT_OR_DISTRIB] THEN + REWRITE_TAC[OR_EXISTS_THM] THEN EXISTS_TAC `l:num` THEN + ASM_SIMP_TAC[IN_NUMSEG; IN_INTERVAL; LAMBDA_BETA; + ARITH_RULE `x <= n ==> x <= n + 1`] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [DE_MORGAN_THM]) THEN + MATCH_MP_TAC MONO_OR THEN REWRITE_TAC[REAL_NOT_LE] THEN + REPEAT STRIP_TAC THEN REPEAT(COND_CASES_TAC THEN ASM_SIMP_TAC[]) THEN + ASM_MESON_TAC[REAL_LT_IMP_LE; REAL_LE_TRANS]]);; + +let PARTIAL_DIVISION_EXTEND_INTERVAL = prove + (`!p a b:real^N. + p division_of (UNIONS p) /\ (UNIONS p) SUBSET interval[a,b] + ==> ?q. p SUBSET q /\ q division_of interval[a,b]`, + REPEAT GEN_TAC THEN ASM_CASES_TAC `p:(real^N->bool)->bool = {}` THEN + ASM_REWRITE_TAC[EMPTY_SUBSET] THENL + [MESON_TAC[ELEMENTARY_INTERVAL]; STRIP_TAC] THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP DIVISION_OF_FINITE) THEN + SUBGOAL_THEN `!k:real^N->bool. k IN p ==> ?q. q division_of interval[a,b] /\ + k IN q` + 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 el 1 o CONJUNCTS) THEN + ASM_REWRITE_TAC[] THEN STRIP_TAC THEN FIRST_X_ASSUM SUBST_ALL_TAC THEN + MATCH_MP_TAC PARTIAL_DIVISION_EXTEND_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 + SUBGOAL_THEN + `?d. d division_of INTERS {UNIONS(q i DELETE i) | (i:real^N->bool) IN p}` + MP_TAC THENL + [MATCH_MP_TAC ELEMENTARY_INTERS THEN ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN + ASM_SIMP_TAC[IMAGE_EQ_EMPTY; FINITE_IMAGE] THEN + REWRITE_TAC[FORALL_IN_IMAGE] THEN X_GEN_TAC `k:real^N->bool` THEN + DISCH_TAC THEN EXISTS_TAC `(q k) DELETE (k:real^N->bool)` THEN + MATCH_MP_TAC DIVISION_OF_SUBSET THEN + EXISTS_TAC `(q:(real^N->bool)->(real^N->bool)->bool) k` THEN + REWRITE_TAC[DELETE_SUBSET] THEN ASM_MESON_TAC[division_of]; + ALL_TAC] THEN + DISCH_THEN(X_CHOOSE_TAC `d:(real^N->bool)->bool`) THEN + EXISTS_TAC `(d UNION p):(real^N->bool)->bool` THEN + REWRITE_TAC[SUBSET_UNION] THEN + SUBGOAL_THEN `interval[a:real^N,b] = + INTERS {UNIONS (q i DELETE i) | i IN p} UNION + UNIONS p` + SUBST1_TAC THENL + [ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN MATCH_MP_TAC(SET_RULE + `~(s = {}) /\ + (!i. i IN s ==> f i UNION i = t) + ==> t = INTERS (IMAGE f s) UNION (UNIONS s)`) THEN + ASM_REWRITE_TAC[] THEN X_GEN_TAC `k:real^N->bool` THEN DISCH_TAC THEN + MATCH_MP_TAC(SET_RULE + `UNIONS k = s /\ i IN k ==> UNIONS (k DELETE i) UNION i = s`) THEN + ASM_MESON_TAC[division_of]; + ALL_TAC] THEN + MATCH_MP_TAC DIVISION_DISJOINT_UNION THEN ASM_REWRITE_TAC[] 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 + MATCH_MP_TAC(SET_RULE + `!s. u SUBSET s /\ s INTER t = {} ==> u INTER t = {}`) THEN + EXISTS_TAC `interior(UNIONS(q k DELETE (k:real^N->bool)))` THEN + CONJ_TAC THENL + [MATCH_MP_TAC SUBSET_INTERIOR THEN + MATCH_MP_TAC(SET_RULE `x IN s ==> INTERS s SUBSET x`) THEN ASM SET_TAC[]; + ALL_TAC] THEN + ONCE_REWRITE_TAC[INTER_COMM] THEN + MATCH_MP_TAC INTER_INTERIOR_UNIONS_INTERVALS THEN + REWRITE_TAC[OPEN_INTERIOR; FINITE_DELETE; IN_DELETE] THEN + ASM_MESON_TAC[division_of]);; + +let ELEMENTARY_BOUNDED = prove + (`!s. (?p. p division_of s) ==> bounded s`, + REWRITE_TAC[division_of] THEN + ASM_MESON_TAC[BOUNDED_UNIONS; BOUNDED_INTERVAL]);; + +let ELEMENTARY_SUBSET_INTERVAL = prove + (`!s. (?p. p division_of s) ==> ?a b. s SUBSET interval[a,b]`, + MESON_TAC[ELEMENTARY_BOUNDED; BOUNDED_SUBSET_CLOSED_INTERVAL]);; + +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 DIVISION_OF_UNIONS = prove + (`!f. FINITE f /\ + (!p. p IN f ==> p division_of (UNIONS p)) /\ + (!k1 k2. k1 IN UNIONS f /\ k2 IN UNIONS f /\ ~(k1 = k2) + ==> interior k1 INTER interior k2 = {}) + ==> (UNIONS f) division_of UNIONS(UNIONS f)`, + REWRITE_TAC[division_of] THEN + SIMP_TAC[FINITE_UNIONS] THEN REWRITE_TAC[FORALL_IN_UNIONS] THEN + GEN_TAC THEN DISCH_THEN(MP_TAC o el 1 o CONJUNCTS) THEN + MATCH_MP_TAC MONO_FORALL THEN GEN_TAC THEN SET_TAC[]);; + +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 ELEMENTARY_UNION_INTERVAL = prove + (`!p a b:real^N. + p division_of (UNIONS p) + ==> ?q. q division_of (interval[a,b] UNION UNIONS p)`, + MESON_TAC[ELEMENTARY_UNION_INTERVAL_STRONG]);; + +let ELEMENTARY_UNIONS_INTERVALS = prove + (`!f. FINITE f /\ + (!s. s IN f ==> ?a b:real^N. s = interval[a,b]) + ==> (?p. p division_of (UNIONS f))`, + REWRITE_TAC[IMP_CONJ] THEN + MATCH_MP_TAC FINITE_INDUCT_STRONG THEN + REWRITE_TAC[UNIONS_0; UNIONS_INSERT; ELEMENTARY_EMPTY] THEN + REWRITE_TAC[IN_INSERT; TAUT `a \/ b ==> c <=> (a ==> c) /\ (b ==> c)`] THEN + SIMP_TAC[FORALL_AND_THM; LEFT_FORALL_IMP_THM; EXISTS_REFL] THEN + REPEAT GEN_TAC THEN DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN + ASM_REWRITE_TAC[] THEN + DISCH_THEN(CONJUNCTS_THEN2 MP_TAC STRIP_ASSUME_TAC) THEN + DISCH_THEN(X_CHOOSE_TAC `p:(real^N->bool)->bool`) THEN + SUBGOAL_THEN `UNIONS f:real^N->bool = UNIONS p` SUBST1_TAC THENL + [ASM_MESON_TAC[division_of]; ALL_TAC] THEN + MATCH_MP_TAC ELEMENTARY_UNION_INTERVAL THEN ASM_MESON_TAC[division_of]);; + +let ELEMENTARY_UNION = prove + (`!s t:real^N->bool. + (?p. p division_of s) /\ (?p. p division_of t) + ==> (?p. p division_of (s UNION t))`, + REPEAT GEN_TAC THEN DISCH_THEN + (CONJUNCTS_THEN2 (X_CHOOSE_TAC `p1:(real^N->bool)->bool`) + (X_CHOOSE_TAC `p2:(real^N->bool)->bool`)) THEN + SUBGOAL_THEN `s UNION t :real^N->bool = UNIONS p1 UNION UNIONS p2` + SUBST1_TAC THENL [ASM_MESON_TAC[division_of]; ALL_TAC] THEN + REWRITE_TAC[SET_RULE `UNIONS p1 UNION UNIONS p2 = UNIONS(p1 UNION p2)`] THEN + MATCH_MP_TAC ELEMENTARY_UNIONS_INTERVALS THEN + REWRITE_TAC[IN_UNION; FINITE_UNION] THEN + ASM_MESON_TAC[division_of]);; + +let PARTIAL_DIVISION_EXTEND = prove + (`!p q s t:real^N->bool. + p division_of s /\ q division_of t /\ s SUBSET t + ==> ?r. p SUBSET r /\ r division_of t`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN `?a b:real^N. t SUBSET interval[a,b]` MP_TAC THENL + [ASM_MESON_TAC[ELEMENTARY_SUBSET_INTERVAL]; ALL_TAC] THEN + REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`a:real^N`; `b:real^N`] THEN DISCH_TAC THEN + SUBGOAL_THEN `?r1. p SUBSET r1 /\ r1 division_of interval[a:real^N,b]` + STRIP_ASSUME_TAC THENL + [MATCH_MP_TAC PARTIAL_DIVISION_EXTEND_INTERVAL THEN + ASM_MESON_TAC[division_of; SUBSET_TRANS]; + ALL_TAC] THEN + SUBGOAL_THEN + `?r2:(real^N->bool)->bool. + r2 division_of (UNIONS(r1 DIFF p)) INTER (UNIONS q)` + STRIP_ASSUME_TAC THENL + [MATCH_MP_TAC ELEMENTARY_INTER THEN + ASM_MESON_TAC[FINITE_DIFF; IN_DIFF; division_of; + ELEMENTARY_UNIONS_INTERVALS]; + ALL_TAC] THEN + EXISTS_TAC `p UNION r2:(real^N->bool)->bool` THEN + CONJ_TAC THENL [SET_TAC[]; ALL_TAC] THEN + SUBGOAL_THEN + `t:real^N->bool = UNIONS p UNION (UNIONS(r1 DIFF p) INTER UNIONS q)` + SUBST1_TAC THENL + [REPEAT(FIRST_X_ASSUM(MP_TAC o last o CONJUNCTS o + GEN_REWRITE_RULE I [division_of])) THEN + REPEAT(POP_ASSUM MP_TAC) THEN SET_TAC[]; + MATCH_MP_TAC DIVISION_DISJOINT_UNION THEN ASM_REWRITE_TAC[] THEN + CONJ_TAC THENL [ASM_MESON_TAC[division_of]; ALL_TAC] THEN + MATCH_MP_TAC(SET_RULE + `!t'. t SUBSET t' /\ s INTER t' = {} ==> s INTER t = {}`) THEN + EXISTS_TAC `interior(UNIONS(r1 DIFF p)):real^N->bool` THEN + CONJ_TAC THENL [MATCH_MP_TAC SUBSET_INTERIOR THEN SET_TAC[]; ALL_TAC] THEN + REPEAT(MATCH_MP_TAC INTER_INTERIOR_UNIONS_INTERVALS THEN + REWRITE_TAC[OPEN_INTERIOR] THEN + REPEAT(CONJ_TAC THENL + [ASM_MESON_TAC[IN_DIFF; FINITE_DIFF; division_of]; ALL_TAC]) THEN + REWRITE_TAC[IN_DIFF] THEN REPEAT STRIP_TAC THEN + ONCE_REWRITE_TAC[INTER_COMM]) THEN + ASM_MESON_TAC[division_of; SUBSET]]);; + +let INTERVAL_SUBDIVISION = prove + (`!a b c:real^N. + c IN interval[a,b] + ==> IMAGE (\s. interval[(lambda i. if i IN s then c$i else a$i), + (lambda i. if i IN s then b$i else c$i)]) + {s | s SUBSET 1..dimindex(:N)} + division_of interval[a,b]`, + REPEAT STRIP_TAC THEN + FIRST_ASSUM(ASSUME_TAC o GEN_REWRITE_RULE I [IN_INTERVAL]) THEN + REWRITE_TAC[DIVISION_OF] THEN + SIMP_TAC[FINITE_IMAGE; FINITE_POWERSET; FINITE_NUMSEG] THEN + REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_IMAGE] THEN + REWRITE_TAC[FORALL_IN_GSPEC; SUBSET_INTERVAL; INTERVAL_NE_EMPTY] THEN + REWRITE_TAC[INTERIOR_CLOSED_INTERVAL] THEN REPEAT CONJ_TAC THENL + [SIMP_TAC[LAMBDA_BETA] THEN ASM_MESON_TAC[REAL_LE_TRANS]; + X_GEN_TAC `s:num->bool` THEN DISCH_TAC THEN + X_GEN_TAC `s':num->bool` THEN DISCH_TAC THEN + REWRITE_TAC[SET_RULE + `(~p ==> s INTER t = {}) <=> (!x. x IN s /\ x IN t ==> p)`] THEN + X_GEN_TAC `x:real^N` THEN REWRITE_TAC[IN_INTERVAL; AND_FORALL_THM] THEN + REWRITE_TAC[TAUT `(a ==> b) /\ (a ==> c) <=> a ==> b /\ c`] THEN + SIMP_TAC[LAMBDA_BETA] THEN + ASM_CASES_TAC `s':num->bool = s` THEN ASM_REWRITE_TAC[] THEN + FIRST_X_ASSUM(MP_TAC o MATCH_MP (SET_RULE + `~(s' = s) ==> ?x. x IN s' /\ ~(x IN s) \/ x IN s /\ ~(x IN s')`)) THEN + DISCH_THEN(X_CHOOSE_THEN `k:num` STRIP_ASSUME_TAC) THEN + DISCH_THEN(MP_TAC o SPEC `k:num`) THEN ASM_REWRITE_TAC[] THEN + (ANTS_TAC THENL [ASM_MESON_TAC[SUBSET; IN_NUMSEG]; REAL_ARITH_TAC]); + MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THEN + GEN_REWRITE_TAC I [SUBSET] THENL + [REWRITE_TAC[FORALL_IN_UNIONS] THEN ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN + REWRITE_TAC[IMP_CONJ; FORALL_IN_IMAGE; FORALL_IN_GSPEC] THEN + ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN + REWRITE_TAC[RIGHT_FORALL_IMP_THM; GSYM SUBSET] THEN + SIMP_TAC[SUBSET_INTERVAL; LAMBDA_BETA] THEN + ASM_MESON_TAC[REAL_LE_TRANS; REAL_LE_REFL]; + X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN + REWRITE_TAC[IN_UNIONS; EXISTS_IN_IMAGE; EXISTS_IN_GSPEC] THEN EXISTS_TAC + `{i | i IN 1..dimindex(:N) /\ (c:real^N)$i <= (x:real^N)$i}` THEN + CONJ_TAC THENL [SET_TAC[]; REWRITE_TAC[IN_INTERVAL]] THEN + SIMP_TAC[LAMBDA_BETA; IN_ELIM_THM; IN_NUMSEG] THEN + RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL]) THEN + ASM_MESON_TAC[REAL_LE_TOTAL]]]);; + +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 DIVISION_OF_AFFINITY = prove + (`!d s:real^N->bool m c. + IMAGE (IMAGE (\x. m % x + c)) d division_of (IMAGE (\x. m % x + c) s) <=> + if m = &0 then if s = {} then d = {} + else ~(d = {}) /\ !k. k IN d ==> ~(k = {}) + else d division_of s`, + REPEAT GEN_TAC THEN ASM_CASES_TAC `m = &0` THEN ASM_REWRITE_TAC[] THENL + [ASM_CASES_TAC `s:real^N->bool = {}` THEN + ASM_REWRITE_TAC[IMAGE_CLAUSES; DIVISION_OF_TRIVIAL; IMAGE_EQ_EMPTY] THEN + ASM_CASES_TAC `d:(real^N->bool)->bool = {}` THEN + ASM_REWRITE_TAC[IMAGE_CLAUSES; EMPTY_DIVISION_OF; UNIONS_0; + IMAGE_EQ_EMPTY] THEN + REWRITE_TAC[VECTOR_MUL_LZERO; VECTOR_ADD_LID] THEN + ASM_SIMP_TAC[SET_RULE `~(s = {}) ==> IMAGE (\x. c) s = {c}`] THEN + ASM_CASES_TAC `!k:real^N->bool. k IN d ==> ~(k = {})` THEN + ASM_REWRITE_TAC[division_of] THENL + [ALL_TAC; + REWRITE_TAC[FORALL_IN_IMAGE] THEN ASM_MESON_TAC[IMAGE_EQ_EMPTY]] THEN + SUBGOAL_THEN + `IMAGE (IMAGE ((\x. c):real^N->real^N)) d = {{c}}` + SUBST1_TAC THENL + [GEN_REWRITE_TAC I [EXTENSION] THEN + REWRITE_TAC[IN_IMAGE; IN_SING] THEN ASM SET_TAC[]; + SIMP_TAC[UNIONS_1; FINITE_SING; IN_SING; IMP_CONJ] THEN + REWRITE_TAC[SUBSET_REFL; NOT_INSERT_EMPTY] THEN + MESON_TAC[INTERVAL_SING]]; + REWRITE_TAC[division_of] THEN + REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_IMAGE] THEN + REWRITE_TAC[IMAGE_EQ_EMPTY; GSYM INTERIOR_INTER] THEN + ASM_SIMP_TAC[FINITE_IMAGE_INJ_EQ; GSYM IMAGE_UNIONS; + VECTOR_ARITH `x + a:real^N = y + a <=> x = y`; + VECTOR_MUL_LCANCEL; + SET_RULE `(!x y. f x = f y <=> x = y) + ==> (IMAGE f s SUBSET IMAGE f t <=> s SUBSET t) /\ + (IMAGE f s = IMAGE f t <=> s = t) /\ + (IMAGE f s INTER IMAGE f t = IMAGE f (s INTER t))`] THEN + AP_TERM_TAC THEN BINOP_TAC THENL + [AP_TERM_TAC THEN ABS_TAC THEN REPLICATE_TAC 3 AP_TERM_TAC THEN + EQ_TAC THEN REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`a:real^N`; `b:real^N`] THEN DISCH_TAC THEN + ASM_SIMP_TAC[IMAGE_AFFINITY_INTERVAL] THENL [ALL_TAC; MESON_TAC[]] THEN + FIRST_X_ASSUM(MP_TAC o AP_TERM + `IMAGE (\x:real^N. inv m % x + --(inv m % c))`) THEN + ASM_SIMP_TAC[GSYM IMAGE_o; AFFINITY_INVERSES] THEN + ASM_REWRITE_TAC[IMAGE_I; IMAGE_AFFINITY_INTERVAL] THEN MESON_TAC[]; + SUBGOAL_THEN `(\x:real^N. m % x + c) = (\x. c + x) o (\x. m % x)` + SUBST1_TAC THENL + [REWRITE_TAC[FUN_EQ_THM; o_THM] THEN VECTOR_ARITH_TAC; + REWRITE_TAC[IMAGE_o; INTERIOR_TRANSLATION] THEN + ASM_SIMP_TAC[INTERIOR_INJECTIVE_LINEAR_IMAGE; LINEAR_SCALING; + VECTOR_MUL_LCANCEL; IMAGE_EQ_EMPTY]]]]);; + +let DIVISION_OF_TRANSLATION = prove + (`!d s:real^N->bool. + IMAGE (IMAGE (\x. a + x)) d division_of (IMAGE (\x. a + x) s) <=> + d division_of s`, + ONCE_REWRITE_TAC[VECTOR_ARITH `a + x:real^N = &1 % x + a`] THEN + REWRITE_TAC[DIVISION_OF_AFFINITY] THEN CONV_TAC REAL_RAT_REDUCE_CONV);; + +let DIVISION_OF_REFLECT = prove + (`!d s:real^N->bool. + IMAGE (IMAGE (--)) d division_of IMAGE (--) s <=> + d division_of s`, + REPEAT GEN_TAC THEN SUBGOAL_THEN `(--) = \x:real^N. --(&1) % x + vec 0` + SUBST1_TAC THENL + [REWRITE_TAC[FUN_EQ_THM] THEN VECTOR_ARITH_TAC; + REWRITE_TAC[DIVISION_OF_AFFINITY] THEN CONV_TAC REAL_RAT_REDUCE_CONV]);; + +let ELEMENTARY_COMPACT = prove + (`!s. (?d. d division_of s) ==> compact s`, + REWRITE_TAC[division_of] THEN + MESON_TAC[COMPACT_UNIONS; COMPACT_INTERVAL]);; + +(* ------------------------------------------------------------------------- *) +(* Tagged (partial) divisions. *) +(* ------------------------------------------------------------------------- *) + +parse_as_infix("tagged_partial_division_of",(12,"right"));; +parse_as_infix("tagged_division_of",(12,"right"));; + +let tagged_partial_division_of = new_definition + `s tagged_partial_division_of i <=> + FINITE s /\ + (!x k. (x,k) IN s + ==> x IN k /\ k SUBSET i /\ ?a b. k = interval[a,b]) /\ + (!x1 k1 x2 k2. (x1,k1) IN s /\ (x2,k2) IN s /\ ~((x1,k1) = (x2,k2)) + ==> (interior(k1) INTER interior(k2) = {}))`;; + +let tagged_division_of = new_definition + `s tagged_division_of i <=> + s tagged_partial_division_of i /\ (UNIONS {k | ?x. (x,k) IN s} = i)`;; + +let TAGGED_DIVISION_OF_FINITE = prove + (`!s i. s tagged_division_of i ==> FINITE s`, + SIMP_TAC[tagged_division_of; tagged_partial_division_of]);; + +let TAGGED_DIVISION_OF = prove + (`s tagged_division_of i <=> + FINITE s /\ + (!x k. (x,k) IN s + ==> x IN k /\ k SUBSET i /\ ?a b. k = interval[a,b]) /\ + (!x1 k1 x2 k2. (x1,k1) IN s /\ (x2,k2) IN s /\ ~((x1,k1) = (x2,k2)) + ==> (interior(k1) INTER interior(k2) = {})) /\ + (UNIONS {k | ?x. (x,k) IN s} = i)`, + REWRITE_TAC[tagged_division_of; tagged_partial_division_of; CONJ_ASSOC]);; + +let DIVISION_OF_TAGGED_DIVISION = prove + (`!s i. s tagged_division_of i ==> (IMAGE SND s) division_of i`, + REWRITE_TAC[TAGGED_DIVISION_OF; division_of] THEN + ASM_SIMP_TAC[FINITE_IMAGE; FORALL_IN_IMAGE; FORALL_PAIR_THM; PAIR_EQ] THEN + REWRITE_TAC[IN_IMAGE; EXISTS_PAIR_THM] THEN + REPEAT GEN_TAC THEN STRIP_TAC THEN REPEAT CONJ_TAC THENL + [ASM_MESON_TAC[MEMBER_NOT_EMPTY]; + REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_MESON_TAC[]; + FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN + REWRITE_TAC[EXTENSION; IN_ELIM_THM; IN_IMAGE; IN_UNIONS] THEN + REWRITE_TAC[FORALL_PAIR_THM; EXISTS_PAIR_THM] THEN MESON_TAC[]]);; + +let PARTIAL_DIVISION_OF_TAGGED_DIVISION = prove + (`!s i. s tagged_partial_division_of i + ==> (IMAGE SND s) division_of UNIONS(IMAGE SND s)`, + REWRITE_TAC[tagged_partial_division_of; division_of] THEN + REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_IMAGE] THEN + REWRITE_TAC[FORALL_PAIR_THM; PAIR_EQ; DE_MORGAN_THM] THEN + GEN_TAC THEN DISCH_TAC THEN GEN_TAC THEN REPEAT DISCH_TAC THEN + REPEAT CONJ_TAC THENL + [ASM_MESON_TAC[FINITE_IMAGE]; + ALL_TAC; + ASM_MESON_TAC[]] THEN + REPEAT GEN_TAC THEN STRIP_TAC THEN CONJ_TAC THENL + [ALL_TAC; ASM_MESON_TAC[MEMBER_NOT_EMPTY]] THEN + REWRITE_TAC[SUBSET; IN_UNIONS; IN_IMAGE; EXISTS_PAIR_THM] THEN + CONV_TAC(ONCE_DEPTH_CONV UNWIND_CONV) THEN ASM SET_TAC[]);; + +let TAGGED_PARTIAL_DIVISION_SUBSET = prove + (`!s t i. s tagged_partial_division_of i /\ t SUBSET s + ==> t tagged_partial_division_of i`, + REWRITE_TAC[tagged_partial_division_of] THEN + MESON_TAC[FINITE_SUBSET; SUBSET]);; + +let VSUM_OVER_TAGGED_PARTIAL_DIVISION_LEMMA = prove + (`!d:(real^M->bool)->real^N p i. + p tagged_partial_division_of i /\ + (!u v. ~(interval[u,v] = {}) /\ content(interval[u,v]) = &0 + ==> d(interval[u,v]) = vec 0) + ==> vsum p (\(x,k). d k) = vsum (IMAGE SND p) d`, + REWRITE_TAC[CONTENT_EQ_0_INTERIOR] THEN REPEAT STRIP_TAC THEN + SUBGOAL_THEN `(\(x:real^M,k:real^M->bool). d k:real^N) = d o SND` + SUBST1_TAC THENL [SIMP_TAC[FUN_EQ_THM; FORALL_PAIR_THM; o_THM]; ALL_TAC] THEN + CONV_TAC SYM_CONV THEN MATCH_MP_TAC VSUM_IMAGE_NONZERO THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [tagged_partial_division_of]) THEN + MATCH_MP_TAC MONO_AND THEN REWRITE_TAC[FORALL_PAIR_THM] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `x:real^M` THEN + MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `k:real^M->bool` THEN + MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `y:real^M` THEN + MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `k':real^M->bool` THEN + ASM_CASES_TAC `k':real^M->bool = k` THEN + ASM_REWRITE_TAC[PAIR_EQ; INTER_ACI] THEN + RULE_ASSUM_TAC(REWRITE_RULE[GSYM MEMBER_NOT_EMPTY]) THEN + ASM_MESON_TAC[]);; + +let VSUM_OVER_TAGGED_DIVISION_LEMMA = prove + (`!d:(real^M->bool)->real^N p i. + p tagged_division_of i /\ + (!u v. ~(interval[u,v] = {}) /\ content(interval[u,v]) = &0 + ==> d(interval[u,v]) = vec 0) + ==> vsum p (\(x,k). d k) = vsum (IMAGE SND p) d`, + REWRITE_TAC[tagged_division_of] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC VSUM_OVER_TAGGED_PARTIAL_DIVISION_LEMMA THEN + EXISTS_TAC `i:real^M->bool` THEN ASM_REWRITE_TAC[]);; + +let SUM_OVER_TAGGED_PARTIAL_DIVISION_LEMMA = prove + (`!d:(real^N->bool)->real p i. + p tagged_partial_division_of i /\ + (!u v. ~(interval[u,v] = {}) /\ content(interval[u,v]) = &0 + ==> d(interval[u,v]) = &0) + ==> sum p (\(x,k). d k) = sum (IMAGE SND p) d`, + REPEAT STRIP_TAC THEN + FIRST_ASSUM(ASSUME_TAC o CONJUNCT1 o + REWRITE_RULE[tagged_partial_division_of]) THEN + ONCE_REWRITE_TAC[GSYM LIFT_EQ] THEN + ASM_SIMP_TAC[LIFT_SUM; FINITE_IMAGE; o_DEF; LAMBDA_PAIR_THM] THEN + MATCH_MP_TAC VSUM_OVER_TAGGED_PARTIAL_DIVISION_LEMMA THEN + ASM_SIMP_TAC[GSYM DROP_EQ; DROP_VEC; LIFT_DROP] THEN ASM_MESON_TAC[]);; + +let SUM_OVER_TAGGED_DIVISION_LEMMA = prove + (`!d:(real^N->bool)->real p i. + p tagged_division_of i /\ + (!u v. ~(interval[u,v] = {}) /\ content(interval[u,v]) = &0 + ==> d(interval[u,v]) = &0) + ==> sum p (\(x,k). d k) = sum (IMAGE SND p) d`, + REWRITE_TAC[tagged_division_of] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC SUM_OVER_TAGGED_PARTIAL_DIVISION_LEMMA THEN + EXISTS_TAC `i:real^N->bool` THEN ASM_REWRITE_TAC[]);; + +let TAG_IN_INTERVAL = prove + (`!p i k. p tagged_division_of i /\ (x,k) IN p ==> x IN i`, + REWRITE_TAC[TAGGED_DIVISION_OF] THEN SET_TAC[]);; + +let TAGGED_DIVISION_OF_EMPTY = prove + (`{} tagged_division_of {}`, + REWRITE_TAC[tagged_division_of; tagged_partial_division_of] THEN + REWRITE_TAC[FINITE_RULES; EXTENSION; NOT_IN_EMPTY; IN_UNIONS; IN_ELIM_THM]);; + +let TAGGED_PARTIAL_DIVISION_OF_TRIVIAL = prove + (`!p. p tagged_partial_division_of {} <=> p = {}`, + REWRITE_TAC[tagged_partial_division_of; SUBSET_EMPTY; CONJ_ASSOC] THEN + REWRITE_TAC[SET_RULE `x IN k /\ k = {} <=> F`] THEN + REWRITE_TAC[GSYM FORALL_PAIR_THM; GSYM NOT_EXISTS_THM; MEMBER_NOT_EMPTY] THEN + REWRITE_TAC[AC CONJ_ACI `(a /\ b) /\ c <=> b /\ a /\ c`] THEN + GEN_TAC THEN MATCH_MP_TAC(TAUT `(a ==> b) ==> (a /\ b <=> a)`) THEN + DISCH_THEN SUBST1_TAC THEN + REWRITE_TAC[FINITE_RULES; UNIONS_0; NOT_IN_EMPTY]);; + +let TAGGED_DIVISION_OF_TRIVIAL = prove + (`!p. p tagged_division_of {} <=> p = {}`, + REWRITE_TAC[tagged_division_of; TAGGED_PARTIAL_DIVISION_OF_TRIVIAL] THEN + GEN_TAC THEN MATCH_MP_TAC(TAUT `(a ==> b) ==> (a /\ b <=> a)`) THEN + DISCH_THEN SUBST1_TAC THEN REWRITE_TAC[NOT_IN_EMPTY] THEN SET_TAC[]);; + +let TAGGED_DIVISION_OF_SELF = prove + (`!x a b. x IN interval[a,b] + ==> {(x,interval[a,b])} tagged_division_of interval[a,b]`, + REWRITE_TAC[TAGGED_DIVISION_OF; FINITE_INSERT; FINITE_RULES; IN_SING] THEN + REWRITE_TAC[FORALL_PAIR_THM; PAIR_EQ] THEN REPEAT STRIP_TAC THEN + ASM_REWRITE_TAC[SUBSET_REFL; UNWIND_THM2; SET_RULE `{k | k = a} = {a}`] THEN + REWRITE_TAC[UNIONS_1] THEN ASM_MESON_TAC[]);; + +let TAGGED_DIVISION_UNION = prove + (`!s1 s2:real^N->bool p1 p2. + p1 tagged_division_of s1 /\ + p2 tagged_division_of s2 /\ + interior s1 INTER interior s2 = {} + ==> (p1 UNION p2) tagged_division_of (s1 UNION s2)`, + REPEAT GEN_TAC THEN REWRITE_TAC[TAGGED_DIVISION_OF] THEN STRIP_TAC THEN + ASM_REWRITE_TAC[FINITE_UNION; IN_UNION; EXISTS_OR_THM; SET_RULE + `UNIONS {x | P x \/ Q x} = UNIONS {x | P x} UNION UNIONS {x | Q x}`] THEN + CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + REPEAT STRIP_TAC THENL + [ASM_MESON_TAC[]; ALL_TAC; + ONCE_REWRITE_TAC[INTER_COMM]; ASM_MESON_TAC[]] THEN + MATCH_MP_TAC(SET_RULE + `!s' t'. s SUBSET s' /\ t SUBSET t' /\ s' INTER t' = {} + ==> s INTER t = {}`) THEN + MAP_EVERY EXISTS_TAC + [`interior s1:real^N->bool`; `interior s2:real^N->bool`] THEN + ASM_SIMP_TAC[] THEN CONJ_TAC THEN MATCH_MP_TAC SUBSET_INTERIOR THEN + ASM_MESON_TAC[]);; + +let TAGGED_DIVISION_UNIONS = prove + (`!iset pfn. FINITE iset /\ + (!i:real^M->bool. i IN iset ==> pfn(i) tagged_division_of i) /\ + (!i1 i2. i1 IN iset /\ i2 IN iset /\ ~(i1 = i2) + ==> (interior(i1) INTER interior(i2) = {})) + ==> UNIONS(IMAGE pfn iset) tagged_division_of (UNIONS iset)`, + let lemma1 = prove + (`(?t. (?x. (t = f x) /\ P x) /\ Q t) <=> ?x. P x /\ Q(f x)`, + MESON_TAC[]) + and lemma2 = prove + (`!s1 t1 s2 t2. s1 SUBSET t1 /\ s2 SUBSET t2 /\ (t1 INTER t2 = {}) + ==> (s1 INTER s2 = {})`, + SET_TAC[]) in + REPEAT GEN_TAC THEN + REWRITE_TAC[ONCE_REWRITE_RULE[EXTENSION] tagged_division_of] THEN + REWRITE_TAC[tagged_partial_division_of; IN_UNIONS; IN_ELIM_THM] THEN + REWRITE_TAC[SUBSET; IN_ELIM_THM; IN_UNIONS; IN_IMAGE] THEN + SIMP_TAC[FINITE_UNIONS; FINITE_IMAGE; FORALL_IN_IMAGE] THEN + STRIP_TAC THEN REPEAT CONJ_TAC THENL + [ASM_MESON_TAC[]; ALL_TAC; ASM_MESON_TAC[]] THEN + REPEAT GEN_TAC THEN REWRITE_TAC[lemma1] THEN + REWRITE_TAC[LEFT_AND_EXISTS_THM] THEN REWRITE_TAC[RIGHT_AND_EXISTS_THM] THEN + REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`i1:real^M->bool`; `i2:real^M->bool`] THEN + ASM_CASES_TAC `i1 = i2:real^M->bool` THENL + [ASM_MESON_TAC[]; ALL_TAC] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC lemma2 THEN + MAP_EVERY EXISTS_TAC + [`interior(i1:real^M->bool)`; `interior(i2:real^M->bool)`] THEN + ASM_MESON_TAC[SUBSET; SUBSET_INTERIOR]);; + +let TAGGED_PARTIAL_DIVISION_OF_UNION_SELF = prove + (`!p s. p tagged_partial_division_of s + ==> p tagged_division_of (UNIONS(IMAGE SND p))`, + SIMP_TAC[tagged_partial_division_of; TAGGED_DIVISION_OF] THEN + REPEAT GEN_TAC THEN STRIP_TAC THEN REPEAT CONJ_TAC THENL + [REPEAT STRIP_TAC THENL [ALL_TAC; ASM_MESON_TAC[]] THEN + REWRITE_TAC[SUBSET; IN_UNIONS; IN_IMAGE; EXISTS_PAIR_THM] THEN + ASM_MESON_TAC[]; + ASM_MESON_TAC[]; + AP_TERM_TAC THEN GEN_REWRITE_TAC I [EXTENSION] THEN + REWRITE_TAC[IN_ELIM_THM; IN_IMAGE; EXISTS_PAIR_THM] THEN MESON_TAC[]]);; + +let TAGGED_DIVISION_OF_UNION_SELF = prove + (`!p s. p tagged_division_of s + ==> p tagged_division_of (UNIONS(IMAGE SND p))`, + SIMP_TAC[TAGGED_DIVISION_OF] THEN REPEAT GEN_TAC THEN STRIP_TAC THEN + MATCH_MP_TAC(TAUT `(c ==> a /\ b) /\ c ==> a /\ b /\ c`) THEN CONJ_TAC THENL + [DISCH_THEN(SUBST1_TAC o SYM) THEN ASM_SIMP_TAC[] THEN ASM_MESON_TAC[]; + FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN AP_TERM_TAC THEN + GEN_REWRITE_TAC I [EXTENSION] THEN + REWRITE_TAC[IN_ELIM_THM; IN_IMAGE; EXISTS_PAIR_THM] THEN MESON_TAC[]]);; + +let TAGGED_DIVISION_UNION_IMAGE_SND = prove + (`!p s. p tagged_division_of s ==> s = UNIONS(IMAGE SND p)`, + MESON_TAC[TAGGED_PARTIAL_DIVISION_OF_UNION_SELF; tagged_division_of]);; + +let TAGGED_DIVISION_OF_ALT = prove + (`!p s. p tagged_division_of s <=> + p tagged_partial_division_of s /\ + (!x. x IN s ==> ?t k. (t,k) IN p /\ x IN k)`, + REWRITE_TAC[tagged_division_of; GSYM SUBSET_ANTISYM_EQ] THEN + REWRITE_TAC[SUBSET; FORALL_IN_UNIONS; IN_ELIM_THM] THEN + REWRITE_TAC[IN_UNIONS; EXISTS_PAIR_THM; IN_ELIM_THM] THEN + REWRITE_TAC[tagged_partial_division_of; SUBSET] THEN MESON_TAC[]);; + +let TAGGED_DIVISION_OF_ANOTHER = prove + (`!p s s'. + p tagged_partial_division_of s' /\ + (!t k. (t,k) IN p ==> k SUBSET s) /\ + (!x. x IN s ==> ?t k. (t,k) IN p /\ x IN k) + ==> p tagged_division_of s`, + REWRITE_TAC[TAGGED_DIVISION_OF_ALT; tagged_partial_division_of] THEN + SET_TAC[]);; + +let TAGGED_PARTIAL_DIVISION_OF_SUBSET = prove + (`!p s t. p tagged_partial_division_of s /\ s SUBSET t + ==> p tagged_partial_division_of t`, + REWRITE_TAC[tagged_partial_division_of] THEN SET_TAC[]);; + +let TAGGED_DIVISION_OF_NONTRIVIAL = prove + (`!s a b:real^N. + s tagged_division_of interval[a,b] /\ ~(content(interval[a,b]) = &0) + ==> {(x,k) | (x,k) IN s /\ ~(content k = &0)} + tagged_division_of interval[a,b]`, + REPEAT STRIP_TAC THEN REWRITE_TAC[TAGGED_DIVISION_OF_ALT] THEN + CONJ_TAC THENL + [MATCH_MP_TAC TAGGED_PARTIAL_DIVISION_SUBSET THEN + EXISTS_TAC `s:(real^N#(real^N->bool))->bool` THEN + RULE_ASSUM_TAC(REWRITE_RULE[tagged_division_of]) THEN + ASM_REWRITE_TAC[] THEN SET_TAC[]; + FIRST_ASSUM(MP_TAC o MATCH_MP DIVISION_OF_TAGGED_DIVISION) THEN + DISCH_THEN(MP_TAC o + MATCH_MP(REWRITE_RULE[IMP_CONJ] DIVISION_OF_NONTRIVIAL)) THEN + ASM_REWRITE_TAC[] THEN + REWRITE_TAC[division_of] THEN DISCH_THEN(MP_TAC o last o CONJUNCTS) THEN + REWRITE_TAC[GSYM SUBSET_ANTISYM_EQ; SUBSET; IN_ELIM_PAIR_THM] THEN + REWRITE_TAC[IN_UNIONS; EXISTS_IN_IMAGE; EXISTS_PAIR_THM; IN_ELIM_THM; + GSYM CONJ_ASSOC] THEN + MESON_TAC[]]);; + +(* ------------------------------------------------------------------------- *) +(* Fine-ness of a partition w.r.t. a gauge. *) +(* ------------------------------------------------------------------------- *) + +parse_as_infix("fine",(12,"right"));; + +let fine = new_definition + `d fine s <=> !x k. (x,k) IN s ==> k SUBSET d(x)`;; + +let FINE_INTER = prove + (`!p d1 d2. (\x. d1(x) INTER d2(x)) fine p <=> d1 fine p /\ d2 fine p`, + let lemma = prove + (`s SUBSET (t INTER u) <=> s SUBSET t /\ s SUBSET u`,SET_TAC[]) in + REWRITE_TAC[fine; IN_INTER; lemma] THEN MESON_TAC[]);; + +let FINE_INTERS = prove + (`!f s p. (\x. INTERS {f d x | d IN s}) fine p <=> + !d. d IN s ==> (f d) fine p`, + REWRITE_TAC[fine; SET_RULE `s SUBSET INTERS u <=> !t. t IN u ==> s SUBSET t`; + IN_ELIM_THM] THEN MESON_TAC[]);; + +let FINE_UNION = prove + (`!d p1 p2. d fine p1 /\ d fine p2 ==> d fine (p1 UNION p2)`, + REWRITE_TAC[fine; IN_UNION] THEN MESON_TAC[]);; + +let FINE_UNIONS = prove + (`!d ps. (!p. p IN ps ==> d fine p) ==> d fine (UNIONS ps)`, + REWRITE_TAC[fine; IN_UNIONS] THEN MESON_TAC[]);; + +let FINE_SUBSET = prove + (`!d p q. p SUBSET q /\ d fine q ==> d fine p`, + REWRITE_TAC[fine; SUBSET] THEN MESON_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* Gauge integral. Define on compact intervals first, then use a limit. *) +(* ------------------------------------------------------------------------- *) + +parse_as_infix("has_integral_compact_interval",(12,"right"));; +parse_as_infix("has_integral",(12,"right"));; +parse_as_infix("integrable_on",(12,"right"));; + +let has_integral_compact_interval = new_definition + `(f has_integral_compact_interval y) i <=> + !e. &0 < e + ==> ?d. gauge d /\ + !p. p tagged_division_of i /\ d fine p + ==> norm(vsum p (\(x,k). content(k) % f(x)) - y) < e`;; + +let has_integral_def = new_definition + `(f has_integral y) i <=> + if ?a b. i = interval[a,b] then (f has_integral_compact_interval y) i + else !e. &0 < e + ==> ?B. &0 < B /\ + !a b. ball(vec 0,B) SUBSET interval[a,b] + ==> ?z. ((\x. if x IN i then f(x) else vec 0) + has_integral_compact_interval z) + (interval[a,b]) /\ + norm(z - y) < e`;; + +let has_integral = prove + (`(f has_integral y) (interval[a,b]) <=> + !e. &0 < e + ==> ?d. gauge d /\ + !p. p tagged_division_of interval[a,b] /\ d fine p + ==> norm(vsum p (\(x,k). content(k) % f(x)) - y) < e`, + REWRITE_TAC[has_integral_def; has_integral_compact_interval] THEN + MESON_TAC[]);; + +let has_integral_alt = prove + (`(f has_integral y) i <=> + if ?a b. i = interval[a,b] then (f has_integral y) i + else !e. &0 < e + ==> ?B. &0 < B /\ + !a b. ball(vec 0,B) SUBSET interval[a,b] + ==> ?z. ((\x. if x IN i then f(x) else vec 0) + has_integral z) (interval[a,b]) /\ + norm(z - y) < e`, + REPEAT GEN_TAC THEN GEN_REWRITE_TAC LAND_CONV [has_integral_def] THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[] THENL + [POP_ASSUM(REPEAT_TCL CHOOSE_THEN SUBST1_TAC); ALL_TAC] THEN + REWRITE_TAC[has_integral_compact_interval; has_integral]);; + +let integrable_on = new_definition + `f integrable_on i <=> ?y. (f has_integral y) i`;; + +let integral = new_definition + `integral i f = @y. (f has_integral y) i`;; + +let INTEGRABLE_INTEGRAL = prove + (`!f i. f integrable_on i ==> (f has_integral (integral i f)) i`, + REPEAT GEN_TAC THEN REWRITE_TAC[integrable_on; integral] THEN + CONV_TAC(RAND_CONV SELECT_CONV) THEN REWRITE_TAC[]);; + +let HAS_INTEGRAL_INTEGRABLE = prove + (`!f i s. (f has_integral i) s ==> f integrable_on s`, + REWRITE_TAC[integrable_on] THEN MESON_TAC[]);; + +let HAS_INTEGRAL_INTEGRAL = prove + (`!f s. f integrable_on s <=> (f has_integral (integral s f)) s`, + MESON_TAC[INTEGRABLE_INTEGRAL; HAS_INTEGRAL_INTEGRABLE]);; + +let VSUM_CONTENT_NULL = prove + (`!f:real^M->real^N a b p. + content(interval[a,b]) = &0 /\ + p tagged_division_of interval[a,b] + ==> vsum p (\(x,k). content k % f x) = vec 0`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC VSUM_EQ_0 THEN + REWRITE_TAC[FORALL_PAIR_THM] THEN + MAP_EVERY X_GEN_TAC [`p:real^M`; `k:real^M->bool`] THEN + DISCH_TAC THEN REWRITE_TAC[VECTOR_MUL_EQ_0] THEN DISJ1_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [TAGGED_DIVISION_OF]) THEN + DISCH_THEN(MP_TAC o CONJUNCT1 o CONJUNCT2) THEN + DISCH_THEN(MP_TAC o SPECL [`p:real^M`; `k:real^M->bool`]) THEN + ASM_MESON_TAC[CONTENT_SUBSET; CONTENT_POS_LE; REAL_ARITH + `&0 <= x /\ x <= y /\ y = &0 ==> x = &0`]);; + +(* ------------------------------------------------------------------------- *) +(* Some basic combining lemmas. *) +(* ------------------------------------------------------------------------- *) + +let TAGGED_DIVISION_UNIONS_EXISTS = prove + (`!d iset i:real^M->bool. + FINITE iset /\ + (!i. i IN iset ==> ?p. p tagged_division_of i /\ d fine p) /\ + (!i1 i2. i1 IN iset /\ i2 IN iset /\ ~(i1 = i2) + ==> (interior(i1) INTER interior(i2) = {})) /\ + (UNIONS iset = i) + ==> ?p. p tagged_division_of i /\ d fine p`, + REPEAT GEN_TAC THEN + GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [RIGHT_IMP_EXISTS_THM] THEN + REWRITE_TAC[SKOLEM_THM; LEFT_AND_EXISTS_THM; LEFT_IMP_EXISTS_THM] THEN + REPEAT STRIP_TAC THEN FIRST_X_ASSUM(SUBST_ALL_TAC o SYM) THEN + EXISTS_TAC `UNIONS (IMAGE(p:(real^M->bool)->((real^M#(real^M->bool))->bool)) + iset)` THEN + ASM_SIMP_TAC[TAGGED_DIVISION_UNIONS] THEN + ASM_MESON_TAC[FINE_UNIONS; IN_IMAGE]);; + +(* ------------------------------------------------------------------------- *) +(* The set we're concerned with must be closed. *) +(* ------------------------------------------------------------------------- *) + +let DIVISION_OF_CLOSED = prove + (`!s i. s division_of i ==> closed i`, + REWRITE_TAC[division_of] THEN MESON_TAC[CLOSED_UNIONS; CLOSED_INTERVAL]);; + +(* ------------------------------------------------------------------------- *) +(* General bisection principle for intervals; might be useful elsewhere. *) +(* ------------------------------------------------------------------------- *) + +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[]);; + +(* ------------------------------------------------------------------------- *) +(* Cousin's lemma. *) +(* ------------------------------------------------------------------------- *) + +let FINE_DIVISION_EXISTS = prove + (`!g a b:real^M. + gauge g ==> ?p. p tagged_division_of (interval[a,b]) /\ g fine p`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPEC `\s:real^M->bool. ?p. p tagged_division_of s /\ g fine p` + INTERVAL_BISECTION) THEN + REWRITE_TAC[] THEN ANTS_TAC THENL + [MESON_TAC[TAGGED_DIVISION_UNION; FINE_UNION; + TAGGED_DIVISION_OF_EMPTY; fine; NOT_IN_EMPTY]; + DISCH_THEN(MP_TAC o SPECL [`a:real^M`; `b:real^M`])] THEN + GEN_REWRITE_TAC LAND_CONV [GSYM CONTRAPOS_THM] THEN + REWRITE_TAC[] THEN DISCH_THEN MATCH_MP_TAC THEN + DISCH_THEN(X_CHOOSE_THEN `x:real^M` (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + FIRST_ASSUM(MP_TAC o SPEC `x:real^M` o REWRITE_RULE[gauge]) THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + REWRITE_TAC[OPEN_CONTAINS_BALL; NOT_FORALL_THM] THEN + DISCH_THEN(MP_TAC o SPEC `x:real^M`) THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `e:real` THEN + STRIP_TAC THEN ASM_REWRITE_TAC[NOT_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`c:real^M`; `d:real^M`] THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `{(x:real^M,interval[c:real^M,d])}`) THEN + ASM_SIMP_TAC[TAGGED_DIVISION_OF_SELF] THEN + REWRITE_TAC[fine; IN_SING; PAIR_EQ] THEN ASM_MESON_TAC[SUBSET_TRANS]);; + +(* ------------------------------------------------------------------------- *) +(* Basic theorems about integrals. *) +(* ------------------------------------------------------------------------- *) + +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 INTEGRAL_UNIQUE = prove + (`!f y k. + (f has_integral y) k ==> integral k f = y`, + REPEAT STRIP_TAC THEN REWRITE_TAC[integral] THEN + MATCH_MP_TAC SELECT_UNIQUE THEN ASM_MESON_TAC[HAS_INTEGRAL_UNIQUE]);; + +let HAS_INTEGRAL_INTEGRABLE_INTEGRAL = prove + (`!f:real^M->real^N i s. + (f has_integral i) s <=> f integrable_on s /\ integral s f = i`, + MESON_TAC[INTEGRABLE_INTEGRAL; INTEGRAL_UNIQUE; integrable_on]);; + +let INTEGRAL_EQ_HAS_INTEGRAL = prove + (`!s f y. f integrable_on s ==> (integral s f = y <=> (f has_integral y) s)`, + MESON_TAC[INTEGRABLE_INTEGRAL; INTEGRAL_UNIQUE]);; + +let HAS_INTEGRAL_IS_0 = prove + (`!f:real^M->real^N s. + (!x. x IN s ==> (f(x) = vec 0)) ==> (f has_integral vec 0) s`, + SUBGOAL_THEN + `!f:real^M->real^N a b. + (!x. x IN interval[a,b] ==> (f(x) = vec 0)) + ==> (f has_integral vec 0) (interval[a,b])` + ASSUME_TAC THENL + [REPEAT STRIP_TAC THEN REWRITE_TAC[has_integral] THEN + REPEAT STRIP_TAC THEN EXISTS_TAC `\x:real^M. ball(x,&1)` THEN + SIMP_TAC[gauge; OPEN_BALL; CENTRE_IN_BALL; REAL_LT_01] THEN + REPEAT STRIP_TAC THEN REWRITE_TAC[REAL_SUB_RZERO] THEN + UNDISCH_TAC `&0 < e` THEN MATCH_MP_TAC(TAUT `(a <=> b) ==> b ==> a`) THEN + AP_THM_TAC THEN AP_TERM_TAC THEN + REWRITE_TAC[NORM_EQ_0; VECTOR_SUB_EQ; VECTOR_ADD_LID] THEN + MATCH_MP_TAC VSUM_EQ_0 THEN REWRITE_TAC[FORALL_PAIR_THM] THEN + CONV_TAC(ONCE_DEPTH_CONV GEN_BETA_CONV) THEN + X_GEN_TAC `x:real^M` THEN REPEAT STRIP_TAC THEN + SUBGOAL_THEN `(x:real^M) IN interval[a,b]` + (fun th -> ASM_SIMP_TAC[th; VECTOR_MUL_RZERO]) THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [tagged_division_of]) THEN + REWRITE_TAC[tagged_partial_division_of; SUBSET] THEN ASM_MESON_TAC[]; + ALL_TAC] THEN + REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[has_integral_alt] THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[] THENL + [ASM_MESON_TAC[]; ALL_TAC] THEN + GEN_TAC THEN DISCH_TAC THEN EXISTS_TAC `&1` THEN REWRITE_TAC[REAL_LT_01] THEN + REPEAT STRIP_TAC THEN EXISTS_TAC `vec 0:real^N` THEN + ASM_REWRITE_TAC[VECTOR_SUB_REFL; NORM_0] THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_MESON_TAC[]);; + +let HAS_INTEGRAL_0 = prove + (`!s. ((\x. vec 0) has_integral vec 0) s`, + SIMP_TAC[HAS_INTEGRAL_IS_0]);; + +let HAS_INTEGRAL_0_EQ = prove + (`!i s. ((\x. vec 0) has_integral i) s <=> i = vec 0`, + MESON_TAC[HAS_INTEGRAL_UNIQUE; HAS_INTEGRAL_0]);; + +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_CMUL = prove + (`!(f:real^M->real^N) k s c. + (f has_integral k) s + ==> ((\x. c % f(x)) has_integral (c % k)) s`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC + (REWRITE_RULE[o_DEF] HAS_INTEGRAL_LINEAR) THEN + ASM_REWRITE_TAC[linear] THEN CONJ_TAC THEN VECTOR_ARITH_TAC);; + +let HAS_INTEGRAL_NEG = prove + (`!f k s. (f has_integral k) s ==> ((\x. --(f x)) has_integral (--k)) s`, + ONCE_REWRITE_TAC[VECTOR_NEG_MINUS1] THEN REWRITE_TAC[HAS_INTEGRAL_CMUL]);; + +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 HAS_INTEGRAL_SUB = 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`, + SIMP_TAC[VECTOR_SUB; HAS_INTEGRAL_NEG; HAS_INTEGRAL_ADD]);; + +let INTEGRAL_0 = prove + (`!s. integral s (\x. vec 0) = vec 0`, + MESON_TAC[INTEGRAL_UNIQUE; HAS_INTEGRAL_0]);; + +let INTEGRAL_ADD = prove + (`!f:real^M->real^N g k l s. + f integrable_on s /\ g integrable_on s + ==> integral s (\x. f x + g x) = integral s f + integral s g`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC INTEGRAL_UNIQUE THEN + MATCH_MP_TAC HAS_INTEGRAL_ADD THEN ASM_SIMP_TAC[INTEGRABLE_INTEGRAL]);; + +let INTEGRAL_CMUL = prove + (`!f:real^M->real^N c s. + f integrable_on s ==> integral s (\x. c % f(x)) = c % integral s f`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC INTEGRAL_UNIQUE THEN + MATCH_MP_TAC HAS_INTEGRAL_CMUL THEN ASM_SIMP_TAC[INTEGRABLE_INTEGRAL]);; + +let INTEGRAL_NEG = prove + (`!f:real^M->real^N s. + f integrable_on s ==> integral s (\x. --f(x)) = --integral s f`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC INTEGRAL_UNIQUE THEN + MATCH_MP_TAC HAS_INTEGRAL_NEG THEN ASM_SIMP_TAC[INTEGRABLE_INTEGRAL]);; + +let INTEGRAL_SUB = prove + (`!f:real^M->real^N g k l s. + f integrable_on s /\ g integrable_on s + ==> integral s (\x. f x - g x) = integral s f - integral s g`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC INTEGRAL_UNIQUE THEN + MATCH_MP_TAC HAS_INTEGRAL_SUB THEN ASM_SIMP_TAC[INTEGRABLE_INTEGRAL]);; + +let INTEGRABLE_0 = prove + (`!s. (\x. vec 0) integrable_on s`, + REWRITE_TAC[integrable_on] THEN MESON_TAC[HAS_INTEGRAL_0]);; + +let INTEGRABLE_ADD = prove + (`!f:real^M->real^N g s. + f integrable_on s /\ g integrable_on s + ==> (\x. f x + g x) integrable_on s`, + REWRITE_TAC[integrable_on] THEN MESON_TAC[HAS_INTEGRAL_ADD]);; + +let INTEGRABLE_CMUL = prove + (`!f:real^M->real^N c s. + f integrable_on s ==> (\x. c % f(x)) integrable_on s`, + REWRITE_TAC[integrable_on] THEN MESON_TAC[HAS_INTEGRAL_CMUL]);; + +let INTEGRABLE_NEG = prove + (`!f:real^M->real^N s. + f integrable_on s ==> (\x. --f(x)) integrable_on s`, + REWRITE_TAC[integrable_on] THEN MESON_TAC[HAS_INTEGRAL_NEG]);; + +let INTEGRABLE_SUB = prove + (`!f:real^M->real^N g s. + f integrable_on s /\ g integrable_on s + ==> (\x. f x - g x) integrable_on s`, + REWRITE_TAC[integrable_on] THEN MESON_TAC[HAS_INTEGRAL_SUB]);; + +let INTEGRABLE_LINEAR = prove + (`!f h s. f integrable_on s /\ linear h ==> (h o f) integrable_on s`, + REWRITE_TAC[integrable_on] THEN MESON_TAC[HAS_INTEGRAL_LINEAR]);; + +let INTEGRAL_LINEAR = prove + (`!f:real^M->real^N s h:real^N->real^P. + f integrable_on s /\ linear h + ==> integral s (h o f) = h(integral s f)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_INTEGRAL_UNIQUE THEN + MAP_EVERY EXISTS_TAC + [`(h:real^N->real^P) o (f:real^M->real^N)`; `s:real^M->bool`] THEN + CONJ_TAC THENL [ALL_TAC; MATCH_MP_TAC HAS_INTEGRAL_LINEAR] THEN + ASM_SIMP_TAC[GSYM HAS_INTEGRAL_INTEGRAL; INTEGRABLE_LINEAR]);; + +let HAS_INTEGRAL_VSUM = prove + (`!f:A->real^M->real^N s t. + FINITE t /\ + (!a. a IN t ==> ((f a) has_integral (i a)) s) + ==> ((\x. vsum t (\a. f a x)) has_integral (vsum t i)) s`, + GEN_TAC THEN GEN_TAC THEN REWRITE_TAC[IMP_CONJ] THEN + MATCH_MP_TAC FINITE_INDUCT_STRONG THEN + SIMP_TAC[VSUM_CLAUSES; HAS_INTEGRAL_0; IN_INSERT] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_INTEGRAL_ADD THEN + ASM_REWRITE_TAC[ETA_AX] THEN CONJ_TAC THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_SIMP_TAC[]);; + +let INTEGRAL_VSUM = prove + (`!f:A->real^M->real^N s t. + FINITE t /\ + (!a. a IN t ==> (f a) integrable_on s) + ==> integral s (\x. vsum t (\a. f a x)) = + vsum t (\a. integral s (f a))`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC INTEGRAL_UNIQUE THEN + MATCH_MP_TAC HAS_INTEGRAL_VSUM THEN ASM_SIMP_TAC[INTEGRABLE_INTEGRAL]);; + +let INTEGRABLE_VSUM = prove + (`!f:A->real^M->real^N s t. + FINITE t /\ + (!a. a IN t ==> (f a) integrable_on s) + ==> (\x. vsum t (\a. f a x)) integrable_on s`, + REWRITE_TAC[integrable_on] THEN MESON_TAC[HAS_INTEGRAL_VSUM]);; + +let HAS_INTEGRAL_EQ = prove + (`!f:real^M->real^N g k s. + (!x. x IN s ==> (f(x) = g(x))) /\ + (f has_integral k) s + ==> (g has_integral k) s`, + REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[GSYM VECTOR_SUB_EQ] THEN + DISCH_THEN(CONJUNCTS_THEN2 (MP_TAC o MATCH_MP HAS_INTEGRAL_IS_0) MP_TAC) THEN + REWRITE_TAC[IMP_IMP] THEN DISCH_THEN(MP_TAC o MATCH_MP HAS_INTEGRAL_SUB) THEN + SIMP_TAC[VECTOR_ARITH `x - (x - y:real^N) = y`; ETA_AX; VECTOR_SUB_RZERO]);; + +let INTEGRABLE_EQ = prove + (`!f:real^M->real^N g s. + (!x. x IN s ==> (f(x) = g(x))) /\ + f integrable_on s + ==> g integrable_on s`, + REWRITE_TAC[integrable_on] THEN MESON_TAC[HAS_INTEGRAL_EQ]);; + +let HAS_INTEGRAL_EQ_EQ = prove + (`!f:real^M->real^N g k s. + (!x. x IN s ==> (f(x) = g(x))) + ==> ((f has_integral k) s <=> (g has_integral k) s)`, + MESON_TAC[HAS_INTEGRAL_EQ]);; + +let HAS_INTEGRAL_NULL = prove + (`!f:real^M->real^N a b. + content(interval[a,b]) = &0 ==> (f has_integral vec 0) (interval[a,b])`, + REPEAT STRIP_TAC THEN REWRITE_TAC[has_integral] THEN + X_GEN_TAC `e:real` THEN DISCH_TAC THEN + EXISTS_TAC `\x:real^M. ball(x,&1)` THEN REWRITE_TAC[GAUGE_TRIVIAL] THEN + REPEAT STRIP_TAC THEN REWRITE_TAC[VECTOR_SUB_RZERO] THEN + MATCH_MP_TAC(REAL_ARITH `x = &0 /\ &0 < e ==> x < e`) THEN + ASM_REWRITE_TAC[NORM_EQ_0] THEN ASM_MESON_TAC[VSUM_CONTENT_NULL]);; + +let HAS_INTEGRAL_NULL_EQ = prove + (`!f a b i. content(interval[a,b]) = &0 + ==> ((f has_integral i) (interval[a,b]) <=> i = vec 0)`, + ASM_MESON_TAC[INTEGRAL_UNIQUE; HAS_INTEGRAL_NULL]);; + +let INTEGRAL_NULL = prove + (`!f a b. content(interval[a,b]) = &0 + ==> integral(interval[a,b]) f = vec 0`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC INTEGRAL_UNIQUE THEN + ASM_MESON_TAC[HAS_INTEGRAL_NULL]);; + +let INTEGRABLE_ON_NULL = prove + (`!f a b. content(interval[a,b]) = &0 + ==> f integrable_on interval[a,b]`, + REWRITE_TAC[integrable_on] THEN MESON_TAC[HAS_INTEGRAL_NULL]);; + +let HAS_INTEGRAL_EMPTY = prove + (`!f. (f has_integral vec 0) {}`, + MESON_TAC[HAS_INTEGRAL_NULL; CONTENT_EMPTY; EMPTY_AS_INTERVAL]);; + +let HAS_INTEGRAL_EMPTY_EQ = prove + (`!f i. (f has_integral i) {} <=> i = vec 0`, + MESON_TAC[HAS_INTEGRAL_UNIQUE; HAS_INTEGRAL_EMPTY]);; + +let INTEGRABLE_ON_EMPTY = prove + (`!f. f integrable_on {}`, + REWRITE_TAC[integrable_on] THEN MESON_TAC[HAS_INTEGRAL_EMPTY]);; + +let INTEGRAL_EMPTY = prove + (`!f. integral {} f = vec 0`, + MESON_TAC[EMPTY_AS_INTERVAL; INTEGRAL_UNIQUE; HAS_INTEGRAL_EMPTY]);; + +let HAS_INTEGRAL_REFL = prove + (`!f a. (f has_integral vec 0) (interval[a,a])`, + REPEAT GEN_TAC THEN MATCH_MP_TAC HAS_INTEGRAL_NULL THEN + SIMP_TAC[INTERVAL_SING; INTERIOR_CLOSED_INTERVAL; CONTENT_EQ_0_INTERIOR]);; + +let INTEGRABLE_ON_REFL = prove + (`!f a. f integrable_on interval[a,a]`, + REWRITE_TAC[integrable_on] THEN MESON_TAC[HAS_INTEGRAL_REFL]);; + +let INTEGRAL_REFL = prove + (`!f a. integral (interval[a,a]) f = vec 0`, + MESON_TAC[INTEGRAL_UNIQUE; HAS_INTEGRAL_REFL]);; + +(* ------------------------------------------------------------------------- *) +(* Cauchy-type criterion for integrability. *) +(* ------------------------------------------------------------------------- *) + +let INTEGRABLE_CAUCHY = prove + (`!f:real^M->real^N a b. + f integrable_on interval[a,b] <=> + !e. &0 < e + ==> ?d. gauge d /\ + !p1 p2. p1 tagged_division_of interval[a,b] /\ d fine p1 /\ + p2 tagged_division_of interval[a,b] /\ d fine p2 + ==> norm(vsum p1 (\(x,k). content k % f x) - + vsum p2 (\(x,k). content k % f x)) < e`, + REPEAT GEN_TAC THEN REWRITE_TAC[integrable_on; has_integral] THEN + EQ_TAC THEN DISCH_TAC THENL + [X_GEN_TAC `e:real` THEN DISCH_TAC THEN + FIRST_X_ASSUM(X_CHOOSE_THEN `y:real^N` (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 + REWRITE_TAC[GSYM dist] THEN MESON_TAC[DIST_TRIANGLE_HALF_L]; + 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`; SKOLEM_THM] THEN + DISCH_THEN(X_CHOOSE_THEN `d:num->real^M->real^M->bool` MP_TAC) THEN + REWRITE_TAC[FORALL_AND_THM] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC (LABEL_TAC "*")) THEN + MP_TAC(GEN `n:num` + (ISPECL [`\x. INTERS {(d:num->real^M->real^M->bool) i x | i IN 0..n}`; + `a:real^M`; `b:real^M`] + FINE_DIVISION_EXISTS)) THEN + ASM_SIMP_TAC[GAUGE_INTERS; FINE_INTERS; FINITE_NUMSEG; SKOLEM_THM] THEN + REWRITE_TAC[IN_NUMSEG; LE_0; FORALL_AND_THM] THEN + DISCH_THEN(X_CHOOSE_THEN `p:num->(real^M#(real^M->bool))->bool` + STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN + `cauchy (\n. vsum (p n) + (\(x,k:real^M->bool). content k % (f:real^M->real^N) x))` + MP_TAC THENL + [REWRITE_TAC[cauchy] THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [REAL_ARCH_INV]) THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `N:num` THEN STRIP_TAC THEN + MATCH_MP_TAC WLOG_LE THEN CONJ_TAC THENL + [MESON_TAC[DIST_SYM]; ALL_TAC] THEN + MAP_EVERY X_GEN_TAC [`m:num`; `n:num`] THEN REWRITE_TAC[GE] THEN + REPEAT STRIP_TAC THEN + MATCH_MP_TAC REAL_LTE_TRANS THEN EXISTS_TAC `inv(&m + &1)` THEN + CONJ_TAC THENL + [REWRITE_TAC[dist] THEN ASM_MESON_TAC[LE_REFL]; ALL_TAC] THEN + MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC `inv(&N)` THEN + ASM_SIMP_TAC[REAL_LT_IMP_LE] 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; LIM_SEQUENTIALLY] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `y:real^N` THEN + REWRITE_TAC[dist] THEN STRIP_TAC THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN + MP_TAC(SPEC `e / &2` REAL_ARCH_INV) THEN ASM_REWRITE_TAC[REAL_HALF] THEN + DISCH_THEN(X_CHOOSE_THEN `N1:num` STRIP_ASSUME_TAC) THEN + FIRST_X_ASSUM(MP_TAC o SPEC `e / &2`) THEN ASM_REWRITE_TAC[REAL_HALF] THEN + DISCH_THEN(X_CHOOSE_TAC `N2:num`) THEN EXISTS_TAC + `(d:num->real^M->real^M->bool) (N1 + N2)` THEN + ASM_REWRITE_TAC[] THEN + X_GEN_TAC `q:(real^M#(real^M->bool))->bool` THEN STRIP_TAC THEN + REWRITE_TAC[GSYM dist] THEN MATCH_MP_TAC DIST_TRIANGLE_HALF_L THEN + EXISTS_TAC `vsum (p(N1+N2:num)) + (\(x,k:real^M->bool). content k % (f:real^M->real^N) x)` THEN + CONJ_TAC THENL + [REWRITE_TAC[dist] THEN MATCH_MP_TAC REAL_LTE_TRANS THEN + EXISTS_TAC `inv(&(N1 + N2) + &1)` THEN CONJ_TAC THENL + [FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_MESON_TAC[LE_REFL]; ALL_TAC] THEN + MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC `inv(&N1)` THEN + ASM_SIMP_TAC[REAL_LT_IMP_LE] 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; + ONCE_REWRITE_TAC[DIST_SYM] THEN REWRITE_TAC[dist] THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN ARITH_TAC]);; + +(* ------------------------------------------------------------------------- *) +(* Additivity of integral on abutting intervals. *) +(* ------------------------------------------------------------------------- *) + +let INTERVAL_SPLIT = prove + (`!a b:real^N c k. + 1 <= k /\ k <= dimindex(:N) + ==> interval[a,b] INTER {x | x$k <= c} = + interval[a,(lambda i. if i = k then min (b$k) c else b$i)] /\ + interval[a,b] INTER {x | x$k >= c} = + interval[(lambda i. if i = k then max (a$k) c else a$i),b]`, + REPEAT STRIP_TAC THEN + REWRITE_TAC[EXTENSION; IN_INTERVAL; IN_INTER; IN_ELIM_THM] THEN + ASM_SIMP_TAC[LAMBDA_BETA] THEN X_GEN_TAC `y:real^N` THEN + MATCH_MP_TAC(TAUT `(c ==> b) /\ (c ==> a) /\ (a /\ b ==> c) + ==> (a /\ b <=> c)`) THEN + (CONJ_TAC THENL + [ASM_MESON_TAC[REAL_MAX_LE; REAL_LE_MIN; real_ge]; ALL_TAC]) THEN + REWRITE_TAC[LEFT_AND_FORALL_THM; real_ge] THEN CONJ_TAC THEN + MATCH_MP_TAC MONO_FORALL THEN ASM_MESON_TAC[REAL_MAX_LE; REAL_LE_MIN]);; + +let CONTENT_SPLIT = prove + (`!a b:real^N k. + 1 <= k /\ k <= dimindex(:N) + ==> content(interval[a,b]) = + content(interval[a,b] INTER {x | x$k <= c}) + + content(interval[a,b] INTER {x | x$k >= c})`, + SIMP_TAC[INTERVAL_SPLIT; CONTENT_CLOSED_INTERVAL_CASES; LAMBDA_BETA] THEN + REPEAT GEN_TAC THEN REWRITE_TAC[REAL_ARITH + `((a <= if p then b else c) <=> (p ==> a <= b) /\ (~p ==> a <= c)) /\ + ((if p then b else c) <= a <=> (p ==> b <= a) /\ (~p ==> c <= a))`] THEN + REWRITE_TAC[REAL_LE_MIN; REAL_MAX_LE] THEN + REWRITE_TAC[MESON[] `(i = k ==> p i k) <=> (i = k ==> p i i)`] THEN + REWRITE_TAC[TAUT `(p ==> a /\ b) /\ (~p ==> a) <=> a /\ (p ==> b)`] THEN + REWRITE_TAC[TAUT `a ==> b /\ c <=> (a ==> b) /\ (a ==> c)`] THEN + REWRITE_TAC[FORALL_AND_THM] THEN STRIP_TAC THEN + ASM_CASES_TAC + `!i. 1 <= i /\ i <= dimindex(:N) ==> (a:real^N)$i <= (b:real^N)$i` THEN + ASM_REWRITE_TAC[REAL_ADD_RID] THEN + REWRITE_TAC[MESON[] `(!i. P i ==> i = k ==> Q i) <=> (P k ==> Q k)`] THEN + ASM_REWRITE_TAC[] THEN + REWRITE_TAC[REAL_ARITH `min b c = if c <= b then c else b`; + REAL_ARITH `max a c = if a <= c then c else a`] THEN + REPEAT(COND_CASES_TAC THEN ASM_REWRITE_TAC[REAL_ADD_LID; REAL_ADD_RID]) THEN + REWRITE_TAC[MESON[] `(if i = k then a k else a i) = a i`] THENL + [ALL_TAC; ASM_MESON_TAC[REAL_LE_TRANS; REAL_LE_TOTAL]] THEN + SUBGOAL_THEN `1..dimindex(:N) = k INSERT ((1..dimindex(:N)) DELETE k)` + SUBST1_TAC THENL + [REWRITE_TAC[EXTENSION; IN_INSERT; IN_DELETE; IN_NUMSEG] THEN + ASM_MESON_TAC[]; + ALL_TAC] THEN + SIMP_TAC[PRODUCT_CLAUSES; FINITE_DELETE; FINITE_NUMSEG; IN_DELETE] THEN + MATCH_MP_TAC(REAL_RING + `p'' = p /\ p':real = p + ==> (b - a) * p = (c - a) * p' + (b - c) * p''`) THEN + CONJ_TAC THEN MATCH_MP_TAC PRODUCT_EQ THEN SIMP_TAC[IN_DELETE]);; + +let DIVISION_SPLIT_LEFT_INJ,DIVISION_SPLIT_RIGHT_INJ = (CONJ_PAIR o prove) + (`(!d i k1 k2 k c. + d division_of i /\ 1 <= k /\ k <= dimindex(:N) /\ + k1 IN d /\ k2 IN d /\ ~(k1 = k2) /\ + k1 INTER {x | x$k <= c} = k2 INTER {x | x$k <= c} + ==> content(k1 INTER {x:real^N | x$k <= c}) = &0) /\ + (!d i k1 k2 k c. + d division_of i /\ 1 <= k /\ k <= dimindex(:N) /\ + k1 IN d /\ k2 IN d /\ ~(k1 = k2) /\ + k1 INTER {x | x$k >= c} = k2 INTER {x | x$k >= c} + ==> content(k1 INTER {x:real^N | x$k >= c}) = &0)`, + let lemma = prove + (`!a b:real^N c k. + 1 <= k /\ k <= dimindex(:N) + ==> (content(interval[a,b] INTER {x | x$k <= c}) = &0 <=> + interior(interval[a,b] INTER {x | x$k <= c}) = {}) /\ + (content(interval[a,b] INTER {x | x$k >= c}) = &0 <=> + interior(interval[a,b] INTER {x | x$k >= c}) = {})`, + SIMP_TAC[INTERVAL_SPLIT; CONTENT_EQ_0_INTERIOR]) in + REPEAT STRIP_TAC THEN + REWRITE_TAC[CONTENT_EQ_0_INTERIOR] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [division_of]) THEN + DISCH_THEN(CONJUNCTS_THEN2 MP_TAC (MP_TAC o CONJUNCT1) o CONJUNCT2) THEN + DISCH_THEN(MP_TAC o SPECL + [`k1:real^N->bool`; `k2:real^N->bool`]) THEN + ASM_REWRITE_TAC[PAIR_EQ] THEN DISCH_TAC THEN + DISCH_THEN(MP_TAC o SPEC `k2:real^N->bool`) THEN + ASM_REWRITE_TAC[] THEN + REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + DISCH_THEN(X_CHOOSE_THEN `u:real^N` (X_CHOOSE_THEN `v:real^N` + SUBST_ALL_TAC)) THEN + ASM_SIMP_TAC[lemma] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE + `s INTER t = {} + ==> u SUBSET s /\ u SUBSET t ==> u = {}`)) THEN + CONJ_TAC THEN MATCH_MP_TAC SUBSET_INTERIOR THEN ASM SET_TAC[]);; + +let TAGGED_DIVISION_SPLIT_LEFT_INJ = prove + (`!d i x1 k1 x2 k2 k c. + d tagged_division_of i /\ 1 <= k /\ k <= dimindex(:N) /\ + (x1,k1) IN d /\ (x2,k2) IN d /\ ~(k1 = k2) /\ + k1 INTER {x | x$k <= c} = k2 INTER {x | x$k <= c} + ==> content(k1 INTER {x:real^N | x$k <= c}) = &0`, + REPEAT STRIP_TAC THEN + FIRST_X_ASSUM(ASSUME_TAC o MATCH_MP DIVISION_OF_TAGGED_DIVISION) THEN + MATCH_MP_TAC DIVISION_SPLIT_LEFT_INJ THEN + EXISTS_TAC `IMAGE SND (d:(real^N#(real^N->bool))->bool)` THEN + ASM_REWRITE_TAC[IN_IMAGE] THEN ASM_MESON_TAC[SND]);; + +let TAGGED_DIVISION_SPLIT_RIGHT_INJ = prove + (`!d i x1 k1 x2 k2 k c. + d tagged_division_of i /\ 1 <= k /\ k <= dimindex(:N) /\ + (x1,k1) IN d /\ (x2,k2) IN d /\ ~(k1 = k2) /\ + k1 INTER {x | x$k >= c} = k2 INTER {x | x$k >= c} + ==> content(k1 INTER {x:real^N | x$k >= c}) = &0`, + REPEAT STRIP_TAC THEN + FIRST_X_ASSUM(ASSUME_TAC o MATCH_MP DIVISION_OF_TAGGED_DIVISION) THEN + MATCH_MP_TAC DIVISION_SPLIT_RIGHT_INJ THEN + EXISTS_TAC `IMAGE SND (d:(real^N#(real^N->bool))->bool)` THEN + ASM_REWRITE_TAC[IN_IMAGE] THEN ASM_MESON_TAC[SND]);; + +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]));; + +(* ------------------------------------------------------------------------- *) +(* A sort of converse, integrability on subintervals. *) +(* ------------------------------------------------------------------------- *) + +let TAGGED_DIVISION_UNION_INTERVAL = prove + (`!a b:real^N p1 p2 c k. + 1 <= k /\ k <= dimindex(:N) /\ + p1 tagged_division_of (interval[a,b] INTER {x | x$k <= c}) /\ + p2 tagged_division_of (interval[a,b] INTER {x | x$k >= c}) + ==> (p1 UNION p2) tagged_division_of (interval[a,b])`, + REPEAT STRIP_TAC THEN SUBGOAL_THEN + `interval[a,b] = (interval[a,b] INTER {x:real^N | x$k <= c}) UNION + (interval[a,b] INTER {x:real^N | x$k >= c})` + SUBST1_TAC THENL + [MATCH_MP_TAC(SET_RULE + `(t UNION u = UNIV) ==> s = (s INTER t) UNION (s INTER u)`) THEN + REWRITE_TAC[EXTENSION; IN_UNIV; IN_UNION; IN_ELIM_THM] THEN REAL_ARITH_TAC; + ALL_TAC] THEN + MATCH_MP_TAC TAGGED_DIVISION_UNION THEN ASM_REWRITE_TAC[] THEN + ASM_SIMP_TAC[INTERVAL_SPLIT; INTERIOR_CLOSED_INTERVAL] THEN + REWRITE_TAC[EXTENSION; IN_INTER; NOT_IN_EMPTY; IN_INTERVAL] THEN + GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN (MP_TAC o SPEC `k:num`)) THEN + ASM_SIMP_TAC[LAMBDA_BETA] THEN REAL_ARITH_TAC);; + +let HAS_INTEGRAL_SEPARATE_SIDES = prove + (`!f:real^M->real^N i a b k. + (f has_integral i) (interval[a,b]) /\ + 1 <= k /\ k <= dimindex(:M) + ==> !e. &0 < e + ==> ?d. gauge d /\ + !p1 p2. p1 tagged_division_of + (interval[a,b] INTER {x | x$k <= c}) /\ + d fine p1 /\ + p2 tagged_division_of + (interval[a,b] INTER {x | x$k >= c}) /\ + d fine p2 + ==> norm((vsum p1 (\(x,k). content k % f x) + + vsum p2 (\(x,k). content k % f x)) - + i) < e`, + REWRITE_TAC[has_integral] THEN REPEAT GEN_TAC THEN + DISCH_THEN(CONJUNCTS_THEN2 MP_TAC STRIP_ASSUME_TAC) THEN + MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `e:real` THEN + ASM_CASES_TAC `&0 < e` 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 REPEAT STRIP_TAC THEN + SUBGOAL_THEN + `vsum p1 (\(x,k). content k % f x) + vsum p2 (\(x,k). content k % f x) = + vsum (p1 UNION p2) (\(x,k:real^M->bool). content k % (f:real^M->real^N) x)` + SUBST1_TAC THENL + [ALL_TAC; ASM_MESON_TAC[TAGGED_DIVISION_UNION_INTERVAL; FINE_UNION]] THEN + CONV_TAC SYM_CONV THEN MATCH_MP_TAC VSUM_UNION_NONZERO THEN + REPEAT(FIRST_X_ASSUM(STRIP_ASSUME_TAC o GEN_REWRITE_RULE I + [TAGGED_DIVISION_OF])) THEN ASM_REWRITE_TAC[FORALL_PAIR_THM] THEN + MAP_EVERY X_GEN_TAC [`x:real^M`; `l:real^M->bool`] THEN + REWRITE_TAC[IN_INTER; VECTOR_MUL_EQ_0] THEN STRIP_TAC THEN DISJ1_TAC THEN + SUBGOAL_THEN + `(?a b:real^M. l = interval[a,b]) /\ + l SUBSET (interval[a,b] INTER {x | x$k <= c}) /\ + l SUBSET (interval[a,b] INTER {x | x$k >= c})` + MP_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN + DISCH_THEN(CONJUNCTS_THEN2 STRIP_ASSUME_TAC MP_TAC) THEN + ASM_REWRITE_TAC[SET_RULE + `s SUBSET t /\ s SUBSET u <=> s SUBSET (t INTER u)`] THEN + ASM_SIMP_TAC[INTERVAL_SPLIT; INTER_INTERVAL] THEN + DISCH_THEN(MP_TAC o MATCH_MP SUBSET_INTERIOR) THEN + REWRITE_TAC[INTERIOR_CLOSED_INTERVAL; CONTENT_EQ_0_INTERIOR] THEN + MATCH_MP_TAC(SET_RULE `t = {} ==> s SUBSET t ==> s = {}`) THEN + REWRITE_TAC[INTERVAL_EQ_EMPTY] THEN EXISTS_TAC `k:num` THEN + ASM_SIMP_TAC[LAMBDA_BETA] THEN REAL_ARITH_TAC);; + +let INTEGRABLE_SPLIT = prove + (`!f:real^M->real^N a b. + f integrable_on (interval[a,b]) /\ 1 <= k /\ k <= dimindex(:M) + ==> f integrable_on (interval[a,b] INTER {x | x$k <= c}) /\ + f integrable_on (interval[a,b] INTER {x | x$k >= c})`, + let lemma = prove + (`b - a = c + ==> norm(a:real^N) < e / &2 ==> norm(b) < e / &2 ==> norm(c) < e`, + DISCH_THEN(SUBST1_TAC o SYM) THEN REWRITE_TAC[GSYM dist] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC DIST_TRIANGLE_HALF_L THEN + EXISTS_TAC `vec 0:real^N` THEN + ASM_REWRITE_TAC[dist; VECTOR_SUB_LZERO; VECTOR_SUB_RZERO; NORM_NEG]) in + REPEAT GEN_TAC THEN + GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [integrable_on] THEN + REWRITE_TAC[LEFT_IMP_EXISTS_THM; LEFT_AND_EXISTS_THM] THEN + X_GEN_TAC `y:real^N` THEN DISCH_TAC THEN CONJ_TAC THEN + ASM_SIMP_TAC[INTERVAL_SPLIT; INTEGRABLE_CAUCHY] THEN + X_GEN_TAC `e:real` THEN DISCH_TAC THEN + FIRST_ASSUM(MP_TAC o SPEC `e / &2` o + MATCH_MP HAS_INTEGRAL_SEPARATE_SIDES) THEN + MAP_EVERY ABBREV_TAC + [`b' = (lambda i. if i = k then min ((b:real^M)$k) c else b$i):real^M`; + `a' = (lambda i. if i = k then max ((a:real^M)$k) c else a$i):real^M`] THEN + ASM_SIMP_TAC[REAL_HALF; INTERVAL_SPLIT] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `d:real^M->real^M->bool` THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + FIRST_ASSUM(MP_TAC o MATCH_MP FINE_DIVISION_EXISTS) THENL + [DISCH_THEN(MP_TAC o SPECL [`a':real^M`; `b:real^M`]) THEN + RULE_ASSUM_TAC(ONCE_REWRITE_RULE[SWAP_FORALL_THM]); + 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 + REPEAT STRIP_TAC THEN FIRST_X_ASSUM(fun th -> + MP_TAC(SPECL [`p:(real^M#(real^M->bool))->bool`; + `p1:(real^M#(real^M->bool))->bool`] th) THEN + MP_TAC(SPECL [`p:(real^M#(real^M->bool))->bool`; + `p2:(real^M#(real^M->bool))->bool`] th)) THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC lemma THEN VECTOR_ARITH_TAC);; + +(* ------------------------------------------------------------------------- *) +(* Generalized notion of additivity. *) +(* ------------------------------------------------------------------------- *) + +let operative = new_definition + `operative op (f:(real^N->bool)->A) <=> + (!a b. content(interval[a,b]) = &0 ==> f(interval[a,b]) = neutral(op)) /\ + (!a b c k. 1 <= k /\ k <= dimindex(:N) + ==> f(interval[a,b]) = + op (f(interval[a,b] INTER {x | x$k <= c})) + (f(interval[a,b] INTER {x | x$k >= c})))`;; + +let OPERATIVE_TRIVIAL = prove + (`!op f a b. + operative op f /\ content(interval[a,b]) = &0 + ==> f(interval[a,b]) = neutral op`, + REWRITE_TAC[operative] THEN MESON_TAC[]);; + +let PROPERTY_EMPTY_INTERVAL = prove + (`!P. (!a b:real^N. content(interval[a,b]) = &0 ==> P(interval[a,b])) + ==> P {}`, + MESON_TAC[EMPTY_AS_INTERVAL; CONTENT_EMPTY]);; + +let OPERATIVE_EMPTY = prove + (`!op f:(real^N->bool)->A. operative op f ==> f {} = neutral op`, + REPEAT GEN_TAC THEN REWRITE_TAC[operative] THEN + DISCH_THEN(ACCEPT_TAC o MATCH_MP PROPERTY_EMPTY_INTERVAL o CONJUNCT1));; + +(* ------------------------------------------------------------------------- *) +(* Using additivity of lifted function to encode definedness. *) +(* ------------------------------------------------------------------------- *) + +let FORALL_OPTION = prove + (`(!x. P x) <=> P NONE /\ !x. P(SOME x)`, + MESON_TAC[cases "option"]);; + +let EXISTS_OPTION = prove + (`(?x. P x) <=> P NONE \/ ?x. P(SOME x)`, + MESON_TAC[cases "option"]);; + +let lifted = define + `(lifted op NONE _ = NONE) /\ + (lifted op _ NONE = NONE) /\ + (lifted op (SOME x) (SOME y) = SOME(op x y))`;; + +let NEUTRAL_LIFTED = prove + (`!op. monoidal op ==> neutral(lifted op) = SOME(neutral op)`, + REWRITE_TAC[neutral; monoidal] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC SELECT_UNIQUE THEN + REWRITE_TAC[FORALL_OPTION; lifted; distinctness "option"; + injectivity "option"] THEN + ASM_MESON_TAC[]);; + +let MONOIDAL_LIFTED = prove + (`!op. monoidal op ==> monoidal(lifted op)`, + REPEAT STRIP_TAC THEN ASM_SIMP_TAC[NEUTRAL_LIFTED; monoidal] THEN + REWRITE_TAC[FORALL_OPTION; lifted; distinctness "option"; + injectivity "option"] THEN + ASM_MESON_TAC[monoidal]);; + +let ITERATE_SOME = prove + (`!op. monoidal op + ==> !f s. FINITE s + ==> iterate (lifted op) s (\x. SOME(f x)) = + SOME(iterate op s f)`, + GEN_TAC THEN DISCH_TAC THEN GEN_TAC THEN + MATCH_MP_TAC FINITE_INDUCT_STRONG THEN + ASM_SIMP_TAC[ITERATE_CLAUSES; MONOIDAL_LIFTED; NEUTRAL_LIFTED] THEN + REWRITE_TAC[lifted]);; + +(* ------------------------------------------------------------------------- *) +(* Two key instances of additivity. *) +(* ------------------------------------------------------------------------- *) + +let OPERATIVE_CONTENT = prove + (`operative(+) content`, + REWRITE_TAC[operative; NEUTRAL_REAL_ADD; CONTENT_SPLIT]);; + +let OPERATIVE_INTEGRAL = prove + (`!f:real^M->real^N. + operative(lifted(+)) + (\i. if f integrable_on i then SOME(integral i f) else NONE)`, + SIMP_TAC[operative; NEUTRAL_LIFTED; MONOIDAL_VECTOR_ADD] THEN + REWRITE_TAC[NEUTRAL_VECTOR_ADD] THEN + REPEAT STRIP_TAC THEN REPEAT(COND_CASES_TAC THEN ASM_REWRITE_TAC[]) THEN + REWRITE_TAC[lifted; distinctness "option"; injectivity "option"] THENL + [REWRITE_TAC[integral] THEN ASM_MESON_TAC[HAS_INTEGRAL_NULL_EQ]; + RULE_ASSUM_TAC(REWRITE_RULE[integrable_on]) THEN + ASM_MESON_TAC[HAS_INTEGRAL_NULL]; + REPEAT(FIRST_X_ASSUM(MP_TAC o MATCH_MP INTEGRABLE_INTEGRAL)) THEN + ASM_MESON_TAC[HAS_INTEGRAL_SPLIT; HAS_INTEGRAL_UNIQUE]; + ASM_MESON_TAC[INTEGRABLE_SPLIT; integrable_on]; + ASM_MESON_TAC[INTEGRABLE_SPLIT]; + ASM_MESON_TAC[INTEGRABLE_SPLIT]; + RULE_ASSUM_TAC(REWRITE_RULE[integrable_on]) THEN + ASM_MESON_TAC[HAS_INTEGRAL_SPLIT]]);; + +(* ------------------------------------------------------------------------- *) +(* Points of division of a partition. *) +(* ------------------------------------------------------------------------- *) + +let division_points = new_definition + `division_points (k:real^N->bool) (d:(real^N->bool)->bool) = + {j,x | 1 <= j /\ j <= dimindex(:N) /\ + (interval_lowerbound k)$j < x /\ x < (interval_upperbound k)$j /\ + ?i. i IN d /\ + ((interval_lowerbound i)$j = x \/ + (interval_upperbound i)$j = x)}`;; + +let DIVISION_POINTS_FINITE = prove + (`!d i:real^N->bool. d division_of i ==> FINITE(division_points i d)`, + REWRITE_TAC[division_of; division_points] THEN + REPEAT STRIP_TAC THEN REWRITE_TAC[CONJ_ASSOC; GSYM IN_NUMSEG] THEN + REWRITE_TAC[IN; GSYM CONJ_ASSOC] THEN + MATCH_MP_TAC(REWRITE_RULE[IN] FINITE_PRODUCT_DEPENDENT) THEN + REWRITE_TAC[ETA_AX; FINITE_NUMSEG] THEN + X_GEN_TAC `j:num` THEN GEN_REWRITE_TAC LAND_CONV [GSYM IN] THEN + REWRITE_TAC[IN_NUMSEG] THEN STRIP_TAC THEN + MATCH_MP_TAC FINITE_SUBSET THEN EXISTS_TAC + `IMAGE (\i:real^N->bool. (interval_lowerbound i)$j) d UNION + IMAGE (\i:real^N->bool. (interval_upperbound i)$j) d` THEN + ASM_SIMP_TAC[FINITE_UNION; FINITE_IMAGE] THEN + REWRITE_TAC[SUBSET; IN_IMAGE; IN_UNION; IN_ELIM_THM] THEN MESON_TAC[IN]);; + +let DIVISION_POINTS_SUBSET = prove + (`!a b:real^N c d k. + d division_of interval[a,b] /\ + (!i. 1 <= i /\ i <= dimindex(:N) ==> a$i < b$i) /\ + 1 <= k /\ k <= dimindex(:N) /\ a$k < c /\ c < b$k + ==> division_points (interval[a,b] INTER {x | x$k <= c}) + {l INTER {x | x$k <= c} | l | + l IN d /\ ~(l INTER {x | x$k <= c} = {})} + SUBSET division_points (interval[a,b]) d /\ + division_points (interval[a,b] INTER {x | x$k >= c}) + {l INTER {x | x$k >= c} | l | + l IN d /\ ~(l INTER {x | x$k >= c} = {})} + SUBSET division_points (interval[a,b]) d`, + REPEAT STRIP_TAC THEN + (REWRITE_TAC[SUBSET; division_points; FORALL_PAIR_THM] THEN + MAP_EVERY X_GEN_TAC [`j:num`; `x:real`] THEN + REWRITE_TAC[IN_ELIM_PAIR_THM] THEN REWRITE_TAC[IN_ELIM_THM] THEN + ASM_SIMP_TAC[INTERVAL_SPLIT; INTERVAL_LOWERBOUND; INTERVAL_UPPERBOUND; + REAL_LT_IMP_LE] THEN + ASM_SIMP_TAC[REAL_ARITH `a < c ==> max a c = c`; + REAL_ARITH `c < b ==> min b c = c`] THEN + REPLICATE_TAC 2 (DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + ASM_SIMP_TAC[INTERVAL_UPPERBOUND; INTERVAL_LOWERBOUND; LAMBDA_BETA; + REAL_LT_IMP_LE; COND_ID; + TAUT `(a <= if p then x else y) <=> (if p then a <= x else a <= y)`; + TAUT `(if p then x else y) <= a <=> (if p then x <= a else y <= a)`] THEN + REPLICATE_TAC 2 (DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + DISCH_THEN(fun th -> CONJ_TAC THEN MP_TAC th) THENL + [DISCH_THEN(K ALL_TAC) THEN REPEAT(POP_ASSUM MP_TAC) THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN REAL_ARITH_TAC; + ALL_TAC] THEN + REWRITE_TAC[LEFT_AND_EXISTS_THM] THEN ONCE_REWRITE_TAC[SWAP_EXISTS_THM] THEN + MATCH_MP_TAC MONO_EXISTS THEN + ONCE_REWRITE_TAC[TAUT `(a /\ b) /\ c <=> b /\ a /\ c`] THEN + REWRITE_TAC[UNWIND_THM2] THEN SIMP_TAC[GSYM CONJ_ASSOC] THEN + ONCE_REWRITE_TAC[IMP_CONJ] THEN + 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 + ASM_SIMP_TAC[INTERVAL_SPLIT] THEN + SUBGOAL_THEN + `!i. 1 <= i /\ i <= dimindex(:N) ==> (u:real^N)$i <= (v:real^N)$i` + ASSUME_TAC THENL + [REWRITE_TAC[GSYM INTERVAL_NE_EMPTY] THEN ASM_MESON_TAC[division_of]; + ALL_TAC] THEN + REWRITE_TAC[INTERVAL_NE_EMPTY] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + ASM_SIMP_TAC[INTERVAL_UPPERBOUND; INTERVAL_LOWERBOUND] THEN + ASM_SIMP_TAC[LAMBDA_BETA] THEN REPEAT(POP_ASSUM MP_TAC) THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN REAL_ARITH_TAC));; + +let DIVISION_POINTS_PSUBSET = prove + (`!a b:real^N c d k. + d division_of interval[a,b] /\ + (!i. 1 <= i /\ i <= dimindex(:N) ==> a$i < b$i) /\ + 1 <= k /\ k <= dimindex(:N) /\ a$k < c /\ c < b$k /\ + (?l. l IN d /\ + (interval_lowerbound l$k = c \/ interval_upperbound l$k = c)) + ==> division_points (interval[a,b] INTER {x | x$k <= c}) + {l INTER {x | x$k <= c} | l | + l IN d /\ ~(l INTER {x | x$k <= c} = {})} + PSUBSET division_points (interval[a,b]) d /\ + division_points (interval[a,b] INTER {x | x$k >= c}) + {l INTER {x | x$k >= c} | l | + l IN d /\ ~(l INTER {x | x$k >= c} = {})} + PSUBSET division_points (interval[a,b]) d`, + REPEAT STRIP_TAC THEN + ASM_SIMP_TAC[PSUBSET_MEMBER; DIVISION_POINTS_SUBSET] THENL + [EXISTS_TAC `k,(interval_lowerbound l:real^N)$k`; + EXISTS_TAC `k,(interval_lowerbound l:real^N)$k`; + EXISTS_TAC `k,(interval_upperbound l:real^N)$k`; + EXISTS_TAC `k,(interval_upperbound l:real^N)$k`] THEN + ASM_REWRITE_TAC[division_points; IN_ELIM_PAIR_THM] THEN + ASM_SIMP_TAC[INTERVAL_LOWERBOUND; INTERVAL_UPPERBOUND; REAL_LT_IMP_LE] THEN + (CONJ_TAC THENL [ASM_MESON_TAC[]; ALL_TAC]) THEN + ASM_SIMP_TAC[INTERVAL_SPLIT; INTERVAL_LOWERBOUND; INTERVAL_UPPERBOUND; + REAL_LT_IMP_LE] THEN + ASM_SIMP_TAC[REAL_ARITH `a < c ==> max a c = c`; + REAL_ARITH `c < b ==> min b c = c`] THEN + ASM_SIMP_TAC[INTERVAL_UPPERBOUND; INTERVAL_LOWERBOUND; LAMBDA_BETA; + REAL_LT_IMP_LE; COND_ID; + TAUT `(a <= if p then x else y) <=> (if p then a <= x else a <= y)`; + TAUT `(if p then x else y) <= a <=> (if p then x <= a else y <= a)`] THEN + REWRITE_TAC[REAL_LT_REFL]);; + +(* ------------------------------------------------------------------------- *) +(* Preservation by divisions and tagged divisions. *) +(* ------------------------------------------------------------------------- *) + +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"; "d2"] THEN BINOP_TAC THEN + GEN_REWRITE_TAC (RAND_CONV o RAND_CONV) [GSYM o_DEF] THEN + MATCH_MP_TAC ITERATE_NONZERO_IMAGE_LEMMA THEN ASM_REWRITE_TAC[] THEN + (CONJ_TAC THENL [ASM_MESON_TAC[OPERATIVE_EMPTY]; ALL_TAC] THEN + MAP_EVERY X_GEN_TAC [`l:real^N->bool`; `m:real^N->bool`] THEN STRIP_TAC THEN + MATCH_MP_TAC(MESON[OPERATIVE_TRIVIAL] + `operative op f /\ (?a b. l = interval[a,b]) /\ content l = &0 + ==> f l = neutral op`) THEN + ASM_REWRITE_TAC[] THEN CONJ_TAC THENL + [ALL_TAC; ASM_MESON_TAC[DIVISION_SPLIT_LEFT_INJ; + DIVISION_SPLIT_RIGHT_INJ]] THEN + SUBGOAL_THEN `?a b:real^N. m = interval[a,b]` STRIP_ASSUME_TAC THENL + [ASM_MESON_TAC[division_of]; ALL_TAC] THEN + ASM_SIMP_TAC[INTERVAL_SPLIT] THEN MESON_TAC[]));; + +let OPERATIVE_TAGGED_DIVISION = prove + (`!op d a b f:(real^N->bool)->A. + monoidal op /\ operative op f /\ d tagged_division_of interval[a,b] + ==> iterate(op) d (\(x,l). f l) = f(interval[a,b])`, + let lemma = prove + (`(\(x,l). f l) = (f o SND)`, + REWRITE_TAC[FUN_EQ_THM; o_THM; FORALL_PAIR_THM]) in + REPEAT STRIP_TAC THEN MATCH_MP_TAC EQ_TRANS THEN EXISTS_TAC + `iterate op (IMAGE SND (d:(real^N#(real^N->bool)->bool))) f :A` THEN + CONJ_TAC THENL + [ALL_TAC; + ASM_MESON_TAC[DIVISION_OF_TAGGED_DIVISION; OPERATIVE_DIVISION]] THEN + REWRITE_TAC[lemma] THEN CONV_TAC SYM_CONV THEN + MATCH_MP_TAC(REWRITE_RULE[RIGHT_IMP_FORALL_THM; IMP_IMP] + ITERATE_IMAGE_NONZERO) THEN + ASM_REWRITE_TAC[FORALL_PAIR_THM] THEN + CONJ_TAC THENL [ASM_MESON_TAC[TAGGED_DIVISION_OF_FINITE]; ALL_TAC] THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [TAGGED_DIVISION_OF]) THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC (MP_TAC o CONJUNCT1 o CONJUNCT2)) THEN + REPEAT(MATCH_MP_TAC MONO_FORALL THEN GEN_TAC) THEN REWRITE_TAC[PAIR_EQ] THEN + DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN + ASM_SIMP_TAC[INTER_ACI] THEN + ASM_MESON_TAC[CONTENT_EQ_0_INTERIOR; OPERATIVE_TRIVIAL; + TAGGED_DIVISION_OF]);; + +(* ------------------------------------------------------------------------- *) +(* Additivity of content. *) +(* ------------------------------------------------------------------------- *) + +let ADDITIVE_CONTENT_DIVISION = prove + (`!d a b:real^N. + d division_of interval[a,b] + ==> sum d content = content(interval[a,b])`, + REPEAT GEN_TAC THEN DISCH_THEN(MP_TAC o MATCH_MP + (MATCH_MP + (REWRITE_RULE[TAUT `a /\ b /\ c ==> d <=> a /\ b ==> c ==> d`] + OPERATIVE_DIVISION) + (CONJ MONOIDAL_REAL_ADD OPERATIVE_CONTENT))) THEN + REWRITE_TAC[sum]);; + +let ADDITIVE_CONTENT_TAGGED_DIVISION = prove + (`!d a b:real^N. + d tagged_division_of interval[a,b] + ==> sum d (\(x,l). content l) = content(interval[a,b])`, + REPEAT GEN_TAC THEN DISCH_THEN(MP_TAC o MATCH_MP + (MATCH_MP + (REWRITE_RULE[TAUT `a /\ b /\ c ==> d <=> a /\ b ==> c ==> d`] + OPERATIVE_TAGGED_DIVISION) + (CONJ MONOIDAL_REAL_ADD OPERATIVE_CONTENT))) THEN + REWRITE_TAC[sum]);; + +let SUBADDITIVE_CONTENT_DIVISION = prove + (`!d s a b:real^M. + d division_of s /\ s SUBSET interval[a,b] + ==> sum d content <= content(interval[a,b])`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`d:(real^M->bool)->bool`; `a:real^M`; `b:real^M`] + PARTIAL_DIVISION_EXTEND_INTERVAL) THEN + ANTS_TAC THENL + [REWRITE_TAC[UNIONS_SUBSET] THEN + ASM_MESON_TAC[division_of; DIVISION_OF_UNION_SELF; SUBSET_TRANS]; + DISCH_THEN(X_CHOOSE_THEN `p:(real^M->bool)->bool` STRIP_ASSUME_TAC) THEN + MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `sum (p:(real^M->bool)->bool) content` THEN CONJ_TAC THENL + [MATCH_MP_TAC SUM_SUBSET_SIMPLE THEN + ASM_MESON_TAC[division_of; CONTENT_POS_LE; IN_DIFF]; + ASM_MESON_TAC[ADDITIVE_CONTENT_DIVISION; REAL_LE_REFL]]]);; + +(* ------------------------------------------------------------------------- *) +(* Finally, the integral of a constant! *) +(* ------------------------------------------------------------------------- *) + +let HAS_INTEGRAL_CONST = prove + (`!a b:real^M c:real^N. + ((\x. c) has_integral (content(interval[a,b]) % c)) (interval[a,b])`, + REWRITE_TAC[has_integral] THEN REPEAT STRIP_TAC THEN + EXISTS_TAC `\x:real^M. ball(x,&1)` THEN REWRITE_TAC[GAUGE_TRIVIAL] THEN + REPEAT STRIP_TAC THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP TAGGED_DIVISION_OF_FINITE) THEN + FIRST_X_ASSUM(fun th -> + ONCE_REWRITE_TAC[GSYM(MATCH_MP ADDITIVE_CONTENT_TAGGED_DIVISION th)]) THEN + ASM_SIMP_TAC[VSUM_VMUL; GSYM VSUM_SUB] THEN + REWRITE_TAC[LAMBDA_PAIR_THM; VECTOR_SUB_REFL] THEN + ASM_REWRITE_TAC[GSYM LAMBDA_PAIR_THM; VSUM_0; NORM_0]);; + +let INTEGRABLE_CONST = prove + (`!a b:real^M c:real^N. (\x. c) integrable_on interval[a,b]`, + REPEAT STRIP_TAC THEN REWRITE_TAC[integrable_on] THEN + EXISTS_TAC `content(interval[a:real^M,b]) % c:real^N` THEN + REWRITE_TAC[HAS_INTEGRAL_CONST]);; + +let INTEGRAL_CONST = prove + (`!a b c. integral (interval[a,b]) (\x. c) = content(interval[a,b]) % c`, + REPEAT GEN_TAC THEN MATCH_MP_TAC INTEGRAL_UNIQUE THEN + REWRITE_TAC[HAS_INTEGRAL_CONST]);; + +let INTEGRAL_PASTECART_CONST = prove + (`!a b:real^M c d:real^N k:real^P. + integral (interval[pastecart a c,pastecart b d]) (\x. k) = + integral (interval[a,b]) + (\x. integral (interval[c,d]) (\y. k))`, + REWRITE_TAC[INTEGRAL_CONST; CONTENT_PASTECART; VECTOR_MUL_ASSOC]);; + +(* ------------------------------------------------------------------------- *) +(* Bounds on the norm of Riemann sums and the integral itself. *) +(* ------------------------------------------------------------------------- *) + +let DSUM_BOUND = prove + (`!p a b:real^M c:real^N e. + p division_of interval[a,b] /\ norm(c) <= e + ==> norm(vsum p (\l. content l % c)) <= e * content(interval[a,b])`, + REPEAT STRIP_TAC THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP DIVISION_OF_FINITE) 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; NORM_MUL] THEN + MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `sum p (\k:real^M->bool. content k * e)` THEN + CONJ_TAC THENL + [MATCH_MP_TAC SUM_LE THEN ASM_REWRITE_TAC[FORALL_PAIR_THM] THEN + X_GEN_TAC `l:real^M->bool` THEN DISCH_TAC THEN + MATCH_MP_TAC REAL_LE_MUL2 THEN SIMP_TAC[REAL_ABS_POS; NORM_POS_LE] THEN + ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC(REAL_ARITH `&0 <= x ==> abs(x) <= x`) THEN + ASM_MESON_TAC[DIVISION_OF; CONTENT_POS_LE]; + REWRITE_TAC[SUM_RMUL; ETA_AX] THEN + ASM_MESON_TAC[ADDITIVE_CONTENT_DIVISION; REAL_LE_REFL; REAL_MUL_SYM]]);; + +let RSUM_BOUND = prove + (`!p a b f:real^M->real^N e. + p tagged_division_of interval[a,b] /\ + (!x. x IN interval[a,b] ==> norm(f x) <= e) + ==> norm(vsum p (\(x,k). content k % f x)) + <= e * content(interval[a,b])`, + REPEAT STRIP_TAC THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP TAGGED_DIVISION_OF_FINITE) 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; NORM_MUL] THEN + MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `sum p (\(x:real^M,k:real^M->bool). content k * e)` 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`; `l:real^M->bool`] THEN DISCH_TAC THEN + MATCH_MP_TAC REAL_LE_MUL2 THEN SIMP_TAC[REAL_ABS_POS; NORM_POS_LE] THEN + CONJ_TAC THENL + [ASM_MESON_TAC[TAGGED_DIVISION_OF; CONTENT_POS_LE; REAL_ABS_REFL; + REAL_LE_REFL]; + ASM_MESON_TAC[TAG_IN_INTERVAL]]; + FIRST_ASSUM(fun th -> REWRITE_TAC + [GSYM(MATCH_MP ADDITIVE_CONTENT_TAGGED_DIVISION th)]) THEN + REWRITE_TAC[GSYM SUM_LMUL; LAMBDA_PAIR_THM] THEN + REWRITE_TAC[REAL_MUL_AC; REAL_LE_REFL]]);; + +let RSUM_DIFF_BOUND = prove + (`!p a b f g:real^M->real^N. + p tagged_division_of interval[a,b] /\ + (!x. x IN interval[a,b] ==> norm(f x - g x) <= e) + ==> norm(vsum p (\(x,k). content k % f x) - + vsum p (\(x,k). content k % g x)) + <= e * content(interval[a,b])`, + REPEAT STRIP_TAC THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP TAGGED_DIVISION_OF_FINITE) THEN + MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC + `norm(vsum p (\(x,k). + content(k:real^M->bool) % ((f:real^M->real^N) x - g x)))` THEN + CONJ_TAC THENL + [ASM_SIMP_TAC[GSYM VSUM_SUB; VECTOR_SUB_LDISTRIB] THEN + REWRITE_TAC[LAMBDA_PAIR_THM; REAL_LE_REFL]; + ASM_SIMP_TAC[RSUM_BOUND]]);; + +let HAS_INTEGRAL_BOUND = prove + (`!f:real^M->real^N a b i B. + &0 <= B /\ + (f has_integral i) (interval[a,b]) /\ + (!x. x IN interval[a,b] ==> norm(f x) <= B) + ==> norm i <= B * content(interval[a,b])`, + let lemma = prove + (`norm(s) <= B ==> ~(norm(s - i) < norm(i) - B)`, + MATCH_MP_TAC(REAL_ARITH `n1 <= n + n2 ==> n <= B ==> ~(n2 < n1 - B)`) THEN + ONCE_REWRITE_TAC[NORM_SUB] THEN REWRITE_TAC[NORM_TRIANGLE_SUB]) in + REPEAT STRIP_TAC THEN + ASM_CASES_TAC `&0 < content(interval[a:real^M,b])` THENL + [ALL_TAC; + SUBGOAL_THEN `i:real^N = vec 0` SUBST1_TAC THEN + ASM_SIMP_TAC[REAL_LE_MUL; NORM_0; CONTENT_POS_LE] THEN + ASM_MESON_TAC[HAS_INTEGRAL_NULL_EQ; CONTENT_LT_NZ]] THEN + ONCE_REWRITE_TAC[GSYM REAL_NOT_LT] THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [has_integral]) THEN + DISCH_THEN(MP_TAC o SPEC + `norm(i:real^N) - B * content(interval[a:real^M,b])`) THEN + ASM_REWRITE_TAC[REAL_SUB_LT] THEN + DISCH_THEN(X_CHOOSE_THEN `d:real^M->real^M->bool` STRIP_ASSUME_TAC) THEN + MP_TAC(SPECL [`d:real^M->real^M->bool`; `a:real^M`; `b:real^M`] + FINE_DIVISION_EXISTS) THEN + ASM_REWRITE_TAC[] THEN DISCH_THEN + (X_CHOOSE_THEN `p:(real^M#(real^M->bool)->bool)` STRIP_ASSUME_TAC) THEN + FIRST_X_ASSUM(MP_TAC o SPEC `p:(real^M#(real^M->bool)->bool)`) THEN + ASM_MESON_TAC[lemma; RSUM_BOUND]);; + +(* ------------------------------------------------------------------------- *) +(* Similar theorems about relationship among components. *) +(* ------------------------------------------------------------------------- *) + +let RSUM_COMPONENT_LE = prove + (`!p a b f:real^M->real^N g:real^M->real^N. + p tagged_division_of interval[a,b] /\ 1 <= i /\ i <= dimindex(:N) /\ + (!x. x IN interval[a,b] ==> (f x)$i <= (g x)$i) + ==> vsum p (\(x,k). content k % f x)$i <= + vsum p (\(x,k). content k % g x)$i`, + REPEAT STRIP_TAC THEN ASM_SIMP_TAC[VSUM_COMPONENT] THEN + MATCH_MP_TAC SUM_LE THEN + ASM_SIMP_TAC[FORALL_PAIR_THM; VECTOR_MUL_COMPONENT] THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP TAGGED_DIVISION_OF_FINITE) THEN + REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [TAGGED_DIVISION_OF]) THEN + ASM_MESON_TAC[SUBSET; REAL_LE_LMUL; CONTENT_POS_LE]);; + +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 INTEGRAL_COMPONENT_LE = prove + (`!f:real^M->real^N g:real^M->real^N s k. + 1 <= k /\ k <= dimindex(:N) /\ + f integrable_on s /\ g integrable_on s /\ + (!x. x IN s ==> (f x)$k <= (g x)$k) + ==> (integral s f)$k <= (integral s g)$k`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_INTEGRAL_COMPONENT_LE THEN + ASM_MESON_TAC[INTEGRABLE_INTEGRAL]);; + +let HAS_INTEGRAL_DROP_LE = prove + (`!f:real^M->real^1 g:real^M->real^1 s i j. + (f has_integral i) s /\ (g has_integral j) s /\ + (!x. x IN s ==> drop(f x) <= drop(g x)) + ==> drop i <= drop j`, + REWRITE_TAC[drop] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC HAS_INTEGRAL_COMPONENT_LE THEN + REWRITE_TAC[DIMINDEX_1; LE_REFL] THEN ASM_MESON_TAC[]);; + +let INTEGRAL_DROP_LE = prove + (`!f:real^M->real^1 g:real^M->real^1 s. + f integrable_on s /\ g integrable_on s /\ + (!x. x IN s ==> drop(f x) <= drop(g x)) + ==> drop(integral s f) <= drop(integral s g)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_INTEGRAL_DROP_LE THEN + ASM_MESON_TAC[INTEGRABLE_INTEGRAL]);; + +let HAS_INTEGRAL_COMPONENT_POS = prove + (`!f:real^M->real^N s i k. + 1 <= k /\ k <= dimindex(:N) /\ + (f has_integral i) s /\ + (!x. x IN s ==> &0 <= (f x)$k) + ==> &0 <= i$k`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`(\x. vec 0):real^M->real^N`; `f:real^M->real^N`; + `s:real^M->bool`; `vec 0:real^N`; + `i:real^N`; `k:num`] HAS_INTEGRAL_COMPONENT_LE) THEN + ASM_SIMP_TAC[VEC_COMPONENT; HAS_INTEGRAL_0]);; + +let INTEGRAL_COMPONENT_POS = prove + (`!f:real^M->real^N s k. + 1 <= k /\ k <= dimindex(:N) /\ + f integrable_on s /\ + (!x. x IN s ==> &0 <= (f x)$k) + ==> &0 <= (integral s f)$k`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_INTEGRAL_COMPONENT_POS THEN + ASM_MESON_TAC[INTEGRABLE_INTEGRAL]);; + +let HAS_INTEGRAL_DROP_POS = prove + (`!f:real^M->real^1 s i. + (f has_integral i) s /\ + (!x. x IN s ==> &0 <= drop(f x)) + ==> &0 <= drop i`, + REWRITE_TAC[drop] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC HAS_INTEGRAL_COMPONENT_POS THEN + REWRITE_TAC[DIMINDEX_1; LE_REFL] THEN ASM_MESON_TAC[]);; + +let INTEGRAL_DROP_POS = prove + (`!f:real^M->real^1 s. + f integrable_on s /\ + (!x. x IN s ==> &0 <= drop(f x)) + ==> &0 <= drop(integral s f)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_INTEGRAL_DROP_POS THEN + ASM_MESON_TAC[INTEGRABLE_INTEGRAL]);; + +let HAS_INTEGRAL_COMPONENT_NEG = prove + (`!f:real^M->real^N s i k. + 1 <= k /\ k <= dimindex(:N) /\ + (f has_integral i) s /\ + (!x. x IN s ==> (f x)$k <= &0) + ==> i$k <= &0`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`f:real^M->real^N`; `(\x. vec 0):real^M->real^N`; + `s:real^M->bool`; `i:real^N`; `vec 0:real^N`; + `k:num`] HAS_INTEGRAL_COMPONENT_LE) THEN + ASM_SIMP_TAC[VEC_COMPONENT; HAS_INTEGRAL_0]);; + +let HAS_INTEGRAL_DROP_NEG = prove + (`!f:real^M->real^1 s i. + (f has_integral i) s /\ + (!x. x IN s ==> drop(f x) <= &0) + ==> drop i <= &0`, + REWRITE_TAC[drop] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC HAS_INTEGRAL_COMPONENT_NEG THEN + REWRITE_TAC[DIMINDEX_1; LE_REFL] THEN ASM_MESON_TAC[]);; + +let HAS_INTEGRAL_COMPONENT_LBOUND = prove + (`!f:real^M->real^N a b i k. + (f has_integral i) (interval[a,b]) /\ 1 <= k /\ k <= dimindex(:N) /\ + (!x. x IN interval[a,b] ==> B <= f(x)$k) + ==> B * content(interval[a,b]) <= i$k`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`(\x. lambda i. B):real^M->real^N`; `f:real^M->real^N`; + `interval[a:real^M,b]`; + `content(interval[a:real^M,b]) % (lambda i. B):real^N`; + `i:real^N`; `k:num`] + HAS_INTEGRAL_COMPONENT_LE) THEN + ASM_SIMP_TAC[VECTOR_MUL_COMPONENT; LAMBDA_BETA; HAS_INTEGRAL_CONST] THEN + REWRITE_TAC[REAL_MUL_AC]);; + +let HAS_INTEGRAL_COMPONENT_UBOUND = prove + (`!f:real^M->real^N a b i k. + (f has_integral i) (interval[a,b]) /\ 1 <= k /\ k <= dimindex(:N) /\ + (!x. x IN interval[a,b] ==> f(x)$k <= B) + ==> i$k <= B * content(interval[a,b])`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`f:real^M->real^N`; `(\x. lambda i. B):real^M->real^N`; + `interval[a:real^M,b]`; `i:real^N`; + `content(interval[a:real^M,b]) % (lambda i. B):real^N`; + `k:num`] + HAS_INTEGRAL_COMPONENT_LE) THEN + ASM_SIMP_TAC[VECTOR_MUL_COMPONENT; LAMBDA_BETA; HAS_INTEGRAL_CONST] THEN + REWRITE_TAC[REAL_MUL_AC]);; + +let INTEGRAL_COMPONENT_LBOUND = prove + (`!f:real^M->real^N a b k. + f integrable_on interval[a,b] /\ 1 <= k /\ k <= dimindex(:N) /\ + (!x. x IN interval[a,b] ==> B <= f(x)$k) + ==> B * content(interval[a,b]) <= (integral(interval[a,b]) f)$k`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_INTEGRAL_COMPONENT_LBOUND THEN + EXISTS_TAC `f:real^M->real^N` THEN + ASM_REWRITE_TAC[GSYM HAS_INTEGRAL_INTEGRAL]);; + +let INTEGRAL_COMPONENT_UBOUND = prove + (`!f:real^M->real^N a b k. + f integrable_on interval[a,b] /\ 1 <= k /\ k <= dimindex(:N) /\ + (!x. x IN interval[a,b] ==> f(x)$k <= B) + ==> (integral(interval[a,b]) f)$k <= B * content(interval[a,b])`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_INTEGRAL_COMPONENT_UBOUND THEN + EXISTS_TAC `f:real^M->real^N` THEN + ASM_REWRITE_TAC[GSYM HAS_INTEGRAL_INTEGRAL]);; + +(* ------------------------------------------------------------------------- *) +(* Uniform limit of integrable functions is integrable. *) +(* ------------------------------------------------------------------------- *) + +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);; + +(* ------------------------------------------------------------------------- *) +(* Negligible sets. *) +(* ------------------------------------------------------------------------- *) + +let indicator = new_definition + `indicator s :real^M->real^1 = \x. if x IN s then vec 1 else vec 0`;; + +let DROP_INDICATOR = prove + (`!s x. drop(indicator s x) = if x IN s then &1 else &0`, + REPEAT GEN_TAC THEN REWRITE_TAC[indicator] THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[DROP_VEC]);; + +let DROP_INDICATOR_POS_LE = prove + (`!s x. &0 <= drop(indicator s x)`, + REWRITE_TAC[DROP_INDICATOR] THEN REAL_ARITH_TAC);; + +let DROP_INDICATOR_LE_1 = prove + (`!s x. drop(indicator s x) <= &1`, + REWRITE_TAC[DROP_INDICATOR] THEN REAL_ARITH_TAC);; + +let DROP_INDICATOR_ABS_LE_1 = prove + (`!s x. abs(drop(indicator s x)) <= &1`, + REWRITE_TAC[DROP_INDICATOR] THEN REAL_ARITH_TAC);; + +let negligible = new_definition + `negligible s <=> !a b. (indicator s has_integral (vec 0)) (interval[a,b])`;; + +(* ------------------------------------------------------------------------- *) +(* Negligibility of hyperplane. *) +(* ------------------------------------------------------------------------- *) + +let VSUM_NONZERO_IMAGE_LEMMA = prove + (`!s f:A->B g:B->real^N a. + FINITE s /\ g(a) = vec 0 /\ + (!x y. x IN s /\ y IN s /\ f x = f y /\ ~(x = y) ==> g(f x) = vec 0) + ==> vsum {f x |x| x IN s /\ ~(f x = a)} g = + vsum s (g o f)`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN `FINITE {(f:A->B) x |x| x IN s /\ ~(f x = a)}` + ASSUME_TAC THENL + [MATCH_MP_TAC FINITE_SUBSET THEN EXISTS_TAC `IMAGE (f:A->B) s` THEN + ASM_SIMP_TAC[FINITE_IMAGE; SUBSET; IN_IMAGE; IN_ELIM_THM] THEN MESON_TAC[]; + ASM_SIMP_TAC[VSUM] THEN MATCH_MP_TAC ITERATE_NONZERO_IMAGE_LEMMA THEN + ASM_REWRITE_TAC[NEUTRAL_VECTOR_ADD; MONOIDAL_VECTOR_ADD]]);; + +let INTERVAL_DOUBLESPLIT = prove + (`1 <= k /\ k <= dimindex(:N) + ==> interval[a,b] INTER {x:real^N | abs(x$k - c) <= e} = + interval[(lambda i. if i = k then max (a$k) (c - e) else a$i), + (lambda i. if i = k then min (b$k) (c + e) else b$i)]`, + REWRITE_TAC[REAL_ARITH `abs(x - c) <= e <=> x >= c - e /\ x <= c + e`] THEN + REWRITE_TAC[SET_RULE `s INTER {x | P x /\ Q x} = + (s INTER {x | Q x}) INTER {x | P x}`] THEN + SIMP_TAC[INTERVAL_SPLIT]);; + +let DIVISION_DOUBLESPLIT = prove + (`!p a b:real^N k c e. + p division_of interval[a,b] /\ 1 <= k /\ k <= dimindex(:N) + ==> {l INTER {x | abs(x$k - c) <= e} |l| + l IN p /\ ~(l INTER {x | abs(x$k - c) <= e} = {})} + division_of (interval[a,b] INTER {x | abs(x$k - c) <= e})`, + REPEAT GEN_TAC THEN DISCH_TAC THEN + FIRST_ASSUM(MP_TAC o SPEC `c + e:real` o MATCH_MP DIVISION_SPLIT) THEN + DISCH_THEN(MP_TAC o CONJUNCT1) THEN + ASM_SIMP_TAC[INTERVAL_SPLIT] THEN + FIRST_ASSUM MP_TAC THEN REWRITE_TAC[IMP_IMP] THEN + DISCH_THEN(MP_TAC o MATCH_MP (TAUT + `(a /\ b /\ c) /\ d ==> d /\ b /\ c`)) THEN + DISCH_THEN(MP_TAC o CONJUNCT2 o SPEC `c - e:real` o + MATCH_MP DIVISION_SPLIT) THEN + ASM_SIMP_TAC[INTERVAL_DOUBLESPLIT; INTERVAL_SPLIT] THEN + MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_TERM_TAC THEN + REWRITE_TAC[REAL_ARITH `abs(x - c) <= e <=> x >= c - e /\ x <= c + e`] THEN + GEN_REWRITE_TAC I [EXTENSION] THEN REWRITE_TAC[IN_INTER; IN_ELIM_THM] THEN + GEN_TAC THEN REWRITE_TAC[LEFT_AND_EXISTS_THM] THEN + ONCE_REWRITE_TAC[SWAP_EXISTS_THM] THEN REWRITE_TAC[GSYM CONJ_ASSOC] THEN + ONCE_REWRITE_TAC[TAUT `a /\ b /\ c /\ d <=> c /\ a /\ b /\ d`] THEN + REWRITE_TAC[UNWIND_THM2] THEN AP_TERM_TAC THEN ABS_TAC THEN SET_TAC[]);; + +let CONTENT_DOUBLESPLIT = prove + (`!a b:real^N k c e. + &0 < e /\ 1 <= k /\ k <= dimindex(:N) + ==> ?d. &0 < d /\ + content(interval[a,b] INTER {x | abs(x$k - c) <= d}) < e`, + REPEAT STRIP_TAC THEN + ASM_CASES_TAC `content(interval[a:real^N,b]) = &0` THENL + [EXISTS_TAC `&1` THEN REWRITE_TAC[REAL_LT_01] THEN + MATCH_MP_TAC REAL_LET_TRANS THEN + EXISTS_TAC `content(interval[a:real^N,b])` THEN + CONJ_TAC THENL [FIRST_X_ASSUM(K ALL_TAC o SYM); ASM_REWRITE_TAC[]] THEN + ASM_SIMP_TAC[INTERVAL_DOUBLESPLIT] THEN MATCH_MP_TAC CONTENT_SUBSET THEN + ASM_SIMP_TAC[GSYM INTERVAL_DOUBLESPLIT] THEN SET_TAC[]; + ALL_TAC] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE RAND_CONV [CONTENT_EQ_0]) THEN + REWRITE_TAC[NOT_EXISTS_THM; TAUT `~(a /\ b /\ c) <=> a /\ b ==> ~c`] THEN + REWRITE_TAC[REAL_NOT_LE] THEN DISCH_TAC THEN + SUBGOAL_THEN `&0 < product ((1..dimindex (:N)) DELETE k) + (\i. (b:real^N)$i - (a:real^N)$i)` + ASSUME_TAC THENL + [MATCH_MP_TAC PRODUCT_POS_LT THEN + ASM_SIMP_TAC[FINITE_DELETE; FINITE_NUMSEG; IN_DELETE; IN_NUMSEG; + REAL_SUB_LT]; + ALL_TAC] THEN + ABBREV_TAC `d = e / &3 / product ((1..dimindex (:N)) DELETE k) + (\i. (b:real^N)$i - (a:real^N)$i)` THEN + EXISTS_TAC `d:real` THEN SUBGOAL_THEN `&0 < d` ASSUME_TAC THENL + [EXPAND_TAC "d" THEN MATCH_MP_TAC REAL_LT_DIV THEN + ASM_SIMP_TAC[REAL_LT_DIV; REAL_OF_NUM_LT; ARITH]; + ALL_TAC] THEN + ASM_SIMP_TAC[content; INTERVAL_DOUBLESPLIT] THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN + FIRST_X_ASSUM(ASSUME_TAC o GEN_REWRITE_RULE I [INTERVAL_NE_EMPTY]) THEN + SUBGOAL_THEN `1..dimindex(:N) = k INSERT ((1..dimindex(:N)) DELETE k)` + SUBST1_TAC THENL + [REWRITE_TAC[EXTENSION; IN_INSERT; IN_DELETE; IN_NUMSEG] THEN + ASM_MESON_TAC[]; + ALL_TAC] THEN + SIMP_TAC[PRODUCT_CLAUSES; FINITE_NUMSEG; FINITE_DELETE; IN_DELETE] THEN + ASM_SIMP_TAC[INTERVAL_LOWERBOUND; INTERVAL_UPPERBOUND; REAL_LT_IMP_LE; + LAMBDA_BETA; IN_DELETE; IN_NUMSEG] THEN + SUBGOAL_THEN + `product ((1..dimindex (:N)) DELETE k) + (\j. ((lambda i. if i = k then min (b$k) (c + d) else b$i):real^N)$j - + ((lambda i. if i = k then max (a$k) (c - d) else a$i):real^N)$j) = + product ((1..dimindex (:N)) DELETE k) + (\i. (b:real^N)$i - (a:real^N)$i)` + SUBST1_TAC THENL + [MATCH_MP_TAC PRODUCT_EQ THEN + SIMP_TAC[IN_DELETE; IN_NUMSEG; LAMBDA_BETA]; + ALL_TAC] THEN + ASM_SIMP_TAC[GSYM REAL_LT_RDIV_EQ] THEN + MATCH_MP_TAC REAL_LET_TRANS THEN EXISTS_TAC `&2 * d` THEN + CONJ_TAC THENL [REAL_ARITH_TAC; ALL_TAC] THEN + MATCH_MP_TAC(REAL_ARITH `&0 < d /\ &3 * d <= x ==> &2 * d < x`) THEN + ASM_REWRITE_TAC[] THEN EXPAND_TAC "d" THEN REAL_ARITH_TAC);; + +let NEGLIGIBLE_STANDARD_HYPERPLANE = prove + (`!c k. 1 <= k /\ k <= dimindex(:N) ==> negligible {x:real^N | x$k = c}`, + REPEAT STRIP_TAC THEN REWRITE_TAC[negligible; has_integral] THEN + REPEAT STRIP_TAC THEN REWRITE_TAC[VECTOR_SUB_RZERO] THEN + MP_TAC(ISPECL [`a:real^N`; `b:real^N`; `k:num`; `c:real`; `e:real`] + CONTENT_DOUBLESPLIT) THEN + ASM_REWRITE_TAC[] THEN STRIP_TAC THEN + EXISTS_TAC `\x:real^N. ball(x,d)` THEN ASM_SIMP_TAC[GAUGE_BALL] THEN + ABBREV_TAC `i = indicator {x:real^N | x$k = c}` THEN REPEAT STRIP_TAC THEN + SUBGOAL_THEN + `vsum p (\(x,l). content l % i x) = + vsum p (\(x,l). content(l INTER {x:real^N | abs(x$k - c) <= d}) % + (i:real^N->real^1) x)` + SUBST1_TAC THENL + [MATCH_MP_TAC VSUM_EQ THEN REWRITE_TAC[FORALL_PAIR_THM] THEN + MAP_EVERY X_GEN_TAC [`x:real^N`; `l:real^N->bool`] THEN + DISCH_TAC THEN EXPAND_TAC "i" THEN REWRITE_TAC[indicator] THEN + REWRITE_TAC[IN_ELIM_THM] THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[VECTOR_MUL_RZERO] THEN + AP_THM_TAC THEN AP_TERM_TAC THEN AP_TERM_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [fine]) THEN + DISCH_THEN(MP_TAC o SPECL [`x:real^N`; `l:real^N->bool`]) THEN + ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC(SET_RULE `s SUBSET t ==> l SUBSET s ==> l = l INTER t`) THEN + REWRITE_TAC[SUBSET; IN_BALL; IN_ELIM_THM; dist] THEN + UNDISCH_THEN `(x:real^N)$k = c` (SUBST1_TAC o SYM) THEN + ASM_SIMP_TAC[GSYM VECTOR_SUB_COMPONENT] THEN + ONCE_REWRITE_TAC[NORM_SUB] THEN + ASM_MESON_TAC[COMPONENT_LE_NORM; REAL_LE_TRANS; REAL_LT_IMP_LE]; + ALL_TAC] THEN + MATCH_MP_TAC REAL_LET_TRANS THEN EXISTS_TAC + `norm(vsum p (\(x:real^N,l). + content(l INTER {x:real^N | abs(x$k - c) <= d}) % + vec 1:real^1))` THEN + CONJ_TAC THENL + [FIRST_ASSUM(ASSUME_TAC o MATCH_MP TAGGED_DIVISION_OF_FINITE) THEN + ASM_SIMP_TAC[VSUM_REAL; NORM_LIFT] THEN + MATCH_MP_TAC(REAL_ARITH `&0 <= x /\ x <= y ==> abs(x) <= abs(y)`) THEN + REWRITE_TAC[o_DEF; LAMBDA_PAIR_THM; DROP_CMUL] THEN CONJ_TAC THENL + [MATCH_MP_TAC SUM_POS_LE; MATCH_MP_TAC SUM_LE] THEN + ASM_REWRITE_TAC[FORALL_PAIR_THM] THEN + MAP_EVERY X_GEN_TAC [`x:real^N`; `l:real^N->bool`] THEN STRIP_TAC THENL + [MATCH_MP_TAC REAL_LE_MUL; MATCH_MP_TAC REAL_LE_LMUL] THEN + EXPAND_TAC "i" THEN REWRITE_TAC[DROP_VEC] THEN + REWRITE_TAC[DROP_INDICATOR_POS_LE; DROP_INDICATOR_LE_1] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [TAGGED_DIVISION_OF]) THEN + DISCH_THEN(MP_TAC o SPECL [`x:real^N`; `l:real^N->bool`] o + el 1 o CONJUNCTS) THEN + ASM_REWRITE_TAC[] THEN + STRIP_TAC THEN ASM_SIMP_TAC[INTERVAL_DOUBLESPLIT; CONTENT_POS_LE]; + ALL_TAC] THEN + MP_TAC(ISPECL [`(\l. content (l INTER {x | abs (x$k - c) <= d}) % vec 1): + (real^N->bool)->real^1`; + `p:real^N#(real^N->bool)->bool`; + `interval[a:real^N,b]`] + VSUM_OVER_TAGGED_DIVISION_LEMMA) THEN + ASM_REWRITE_TAC[] THEN ANTS_TAC THENL + [MAP_EVERY X_GEN_TAC [`u:real^N`; `v:real^N`] THEN STRIP_TAC THEN + REWRITE_TAC[VECTOR_MUL_EQ_0] THEN DISJ1_TAC THEN + MATCH_MP_TAC(REAL_ARITH `!x. x = &0 /\ &0 <= y /\ y <= x ==> y = &0`) THEN + EXISTS_TAC `content(interval[u:real^N,v])` THEN + CONJ_TAC THEN POP_ASSUM MP_TAC THEN REWRITE_TAC[] THEN + DISCH_THEN(K ALL_TAC) THEN + ASM_SIMP_TAC[CONTENT_POS_LE; INTERVAL_DOUBLESPLIT] THEN + MATCH_MP_TAC CONTENT_SUBSET THEN + ASM_SIMP_TAC[GSYM INTERVAL_DOUBLESPLIT] THEN SET_TAC[]; + ALL_TAC] THEN + DISCH_THEN SUBST1_TAC THEN + MP_TAC(ISPECL + [`IMAGE SND (p:real^N#(real^N->bool)->bool)`; + `\l. l INTER {x:real^N | abs (x$k - c) <= d}`; + `\l:real^N->bool. content l % vec 1 :real^1`; + `{}:real^N->bool`] VSUM_NONZERO_IMAGE_LEMMA) THEN + REWRITE_TAC[o_DEF] THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP DIVISION_OF_TAGGED_DIVISION) THEN + ANTS_TAC THENL + [CONJ_TAC THENL [ASM_MESON_TAC[DIVISION_OF_FINITE]; ALL_TAC] THEN + REWRITE_TAC[CONTENT_EMPTY; VECTOR_MUL_LZERO] THEN + ONCE_REWRITE_TAC[IMP_CONJ] THEN + REWRITE_TAC[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^N`; `v:real^N`] THEN DISCH_TAC THEN + X_GEN_TAC `m:real^N->bool` THEN STRIP_TAC THEN + REWRITE_TAC[VECTOR_MUL_EQ_0] THEN DISJ1_TAC THEN + SIMP_TAC[INTERVAL_DOUBLESPLIT; ASSUME `1 <= k`; + ASSUME `k <= dimindex(:N)`] THEN + REWRITE_TAC[CONTENT_EQ_0_INTERIOR] THEN + ASM_SIMP_TAC[GSYM INTERVAL_DOUBLESPLIT] THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [division_of]) THEN + DISCH_THEN(MP_TAC o SPECL [`interval[u:real^N,v]`; `m:real^N->bool`] o + el 2 o CONJUNCTS) THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC(SET_RULE + `u SUBSET s /\ u SUBSET t ==> s INTER t = {} ==> u = {}`) THEN + CONJ_TAC THEN MATCH_MP_TAC SUBSET_INTERIOR THEN ASM SET_TAC[]; + ALL_TAC] THEN + REWRITE_TAC[o_DEF] THEN DISCH_THEN(SUBST1_TAC o SYM) THEN + MATCH_MP_TAC REAL_LET_TRANS THEN + EXISTS_TAC + `&1 * content(interval[a,b] INTER {x:real^N | abs (x$k - c) <= d})` THEN + CONJ_TAC THENL [ALL_TAC; ASM_REWRITE_TAC[REAL_MUL_LID]] THEN + FIRST_ASSUM(MP_TAC o MATCH_MP(REWRITE_RULE[IMP_CONJ] + DIVISION_DOUBLESPLIT)) THEN + DISCH_THEN(MP_TAC o SPECL [`k:num`; `c:real`; `d:real`]) THEN + ASM_SIMP_TAC[INTERVAL_DOUBLESPLIT] THEN DISCH_TAC THEN + MATCH_MP_TAC DSUM_BOUND THEN + ASM_SIMP_TAC[NORM_REAL; VEC_COMPONENT; DIMINDEX_1; LE_REFL] THEN + REAL_ARITH_TAC);; + +(* ------------------------------------------------------------------------- *) +(* A technical lemma about "refinement" of division. *) +(* ------------------------------------------------------------------------- *) + +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[]));; + +(* ------------------------------------------------------------------------- *) +(* Hence the main theorem about negligible sets. *) +(* ------------------------------------------------------------------------- *) + +let HAS_INTEGRAL_NEGLIGIBLE = prove + (`!f:real^M->real^N s t. + negligible s /\ (!x. x IN (t DIFF s) ==> f x = vec 0) + ==> (f has_integral (vec 0)) t`, + let lemma = prove + (`!f:B->real g:A#B->real s t. + FINITE s /\ FINITE t /\ + (!x y. (x,y) IN t ==> &0 <= g(x,y)) /\ + (!y. y IN s ==> ?x. (x,y) IN t /\ f(y) <= g(x,y)) + ==> sum s f <= sum t g`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC SUM_LE_INCLUDED THEN + EXISTS_TAC `SND:A#B->B` THEN + REWRITE_TAC[EXISTS_PAIR_THM; FORALL_PAIR_THM] THEN + ASM_MESON_TAC[]) in + SUBGOAL_THEN + `!f:real^M->real^N s a b. + negligible s /\ (!x. ~(x IN s) ==> f x = vec 0) + ==> (f has_integral (vec 0)) (interval[a,b])` + ASSUME_TAC THENL + [ALL_TAC; + REWRITE_TAC[IN_DIFF] THEN REPEAT STRIP_TAC THEN + ONCE_REWRITE_TAC[has_integral_alt] THEN COND_CASES_TAC THENL + [MATCH_MP_TAC HAS_INTEGRAL_EQ THEN + EXISTS_TAC `\x. if x IN t then (f:real^M->real^N) x else vec 0` THEN + SIMP_TAC[] THEN + FIRST_X_ASSUM(CHOOSE_THEN(CHOOSE_THEN SUBST_ALL_TAC)) THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_MESON_TAC[]; + ALL_TAC] THEN + GEN_TAC THEN DISCH_TAC THEN EXISTS_TAC `&1` THEN + REWRITE_TAC[REAL_LT_01] THEN + REPEAT STRIP_TAC THEN EXISTS_TAC `vec 0:real^N` THEN + ASM_REWRITE_TAC[NORM_0; VECTOR_SUB_REFL] THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN + EXISTS_TAC `s:real^M->bool` THEN ASM_MESON_TAC[]] THEN + REWRITE_TAC[negligible; has_integral; RIGHT_FORALL_IMP_THM] THEN + REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN + MAP_EVERY(fun t -> MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC t) + [`a:real^M`; `b:real^M`] THEN + REWRITE_TAC[VECTOR_SUB_RZERO] THEN DISCH_TAC THEN + X_GEN_TAC `e:real` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN `n:num` o + SPEC `e / &2 / ((&n + &1) * &2 pow n)`) THEN + REWRITE_TAC[real_div; REAL_MUL_POS_LT] THEN REWRITE_TAC[GSYM real_div] THEN + ASM_SIMP_TAC[REAL_LT_INV_EQ; REAL_LT_MUL; REAL_POW_LT; REAL_OF_NUM_LT; + FORALL_AND_THM; ARITH; REAL_ARITH `&0 < &n + &1`; SKOLEM_THM] THEN + DISCH_THEN(X_CHOOSE_THEN `d:num->real^M->real^M->bool` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `\x. (d:num->real^M->real^M->bool) + (num_of_int(int_of_real(floor(norm(f x:real^N))))) x` THEN + CONJ_TAC THENL [REWRITE_TAC[gauge] THEN ASM_MESON_TAC[gauge]; ALL_TAC] 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 + ASM_CASES_TAC `p:real^M#(real^M->bool)->bool = {}` THEN + ASM_REWRITE_TAC[VSUM_CLAUSES; NORM_0] THEN + MP_TAC(SPEC `sup(IMAGE (\(x,k:real^M->bool). norm((f:real^M->real^N) x)) p)` + REAL_ARCH_SIMPLE) THEN + ASM_SIMP_TAC[REAL_SUP_LE_FINITE; FINITE_IMAGE; IMAGE_EQ_EMPTY] THEN + REWRITE_TAC[FORALL_IN_IMAGE; FORALL_PAIR_THM] THEN + DISCH_THEN(X_CHOOSE_TAC `N:num`) THEN + MP_TAC(GEN `i:num` + (ISPECL [`p:real^M#(real^M->bool)->bool`; `a:real^M`; `b:real^M`; + `(d:num->real^M->real^M->bool) i`] + TAGGED_DIVISION_FINER)) THEN + ASM_REWRITE_TAC[SKOLEM_THM; RIGHT_IMP_EXISTS_THM; FORALL_AND_THM] THEN + DISCH_THEN(X_CHOOSE_THEN `q:num->real^M#(real^M->bool)->bool` + STRIP_ASSUME_TAC) THEN + MATCH_MP_TAC REAL_LET_TRANS THEN EXISTS_TAC + `sum(0..N+1) (\i. (&i + &1) * + norm(vsum (q i) (\(x:real^M,k:real^M->bool). + content k % indicator s x)))` THEN + CONJ_TAC THENL + [ALL_TAC; + MATCH_MP_TAC REAL_LET_TRANS THEN + EXISTS_TAC `sum (0..N+1) (\i. e / &2 / &2 pow i)` THEN CONJ_TAC THENL + [ALL_TAC; + REWRITE_TAC[real_div; SUM_LMUL; GSYM REAL_POW_INV] THEN + REWRITE_TAC[SUM_GP; LT] THEN CONV_TAC REAL_RAT_REDUCE_CONV THEN + REWRITE_TAC[REAL_ARITH `(e * &1 / &2) * (&1 - x) / (&1 / &2) < e <=> + &0 < e * x`] THEN + ASM_SIMP_TAC[REAL_LT_MUL; REAL_POW_LT; REAL_ARITH `&0 < &1 / &2`]] THEN + MATCH_MP_TAC SUM_LE_NUMSEG THEN REPEAT STRIP_TAC THEN + REWRITE_TAC[] THEN ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN + ASM_SIMP_TAC[GSYM REAL_LE_RDIV_EQ; REAL_ARITH `&0 < &n + &1`] THEN + REWRITE_TAC[real_div] THEN ONCE_REWRITE_TAC[GSYM REAL_MUL_ASSOC] THEN + REWRITE_TAC[GSYM REAL_INV_MUL] THEN REWRITE_TAC[GSYM real_div] THEN + ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN MATCH_MP_TAC REAL_LT_IMP_LE THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[]] THEN + FIRST_ASSUM(ASSUME_TAC o GEN `i:num` o + MATCH_MP TAGGED_DIVISION_OF_FINITE o SPEC `i:num`) THEN + ASM_SIMP_TAC[VSUM_REAL; NORM_LIFT] THEN + REWRITE_TAC[o_DEF; LAMBDA_PAIR_THM; DROP_CMUL] THEN + REWRITE_TAC[real_abs] THEN + SUBGOAL_THEN + `!i:num. &0 <= sum (q i) (\(x:real^M,y:real^M->bool). + content y * drop (indicator s x))` + ASSUME_TAC THENL + [REPEAT GEN_TAC THEN MATCH_MP_TAC SUM_POS_LE THEN + ASM_REWRITE_TAC[FORALL_PAIR_THM] THEN + REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THEN MATCH_MP_TAC REAL_LE_MUL THEN + REWRITE_TAC[DROP_INDICATOR_POS_LE] THEN + ASM_MESON_TAC[TAGGED_DIVISION_OF; CONTENT_POS_LE]; + ALL_TAC] THEN + ASM_REWRITE_TAC[GSYM SUM_LMUL] THEN + REWRITE_TAC[LAMBDA_PAIR_THM] 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 `x <= y ==> n <= x ==> n <= y`) THEN + ASM_SIMP_TAC[SUM_SUM_PRODUCT; FINITE_NUMSEG] THEN + MATCH_MP_TAC lemma THEN + ASM_SIMP_TAC[FINITE_PRODUCT_DEPENDENT; FORALL_PAIR_THM; FINITE_NUMSEG] THEN + REWRITE_TAC[IN_ELIM_PAIR_THM] THEN CONJ_TAC THENL + [REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_LE_MUL THEN + CONJ_TAC THENL [REAL_ARITH_TAC; MATCH_MP_TAC REAL_LE_MUL] THEN + REWRITE_TAC[DROP_INDICATOR_POS_LE] THEN + ASM_MESON_TAC[TAGGED_DIVISION_OF; CONTENT_POS_LE]; + ALL_TAC] THEN + MAP_EVERY X_GEN_TAC [`x:real^M`; `k:real^M->bool`] THEN DISCH_TAC THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [fine]) THEN + DISCH_THEN(MP_TAC o SPECL [`x:real^M`; `k:real^M->bool`]) THEN + ASM_REWRITE_TAC[] THEN ABBREV_TAC + `n = num_of_int(int_of_real(floor(norm((f:real^M->real^N) x))))` THEN + SUBGOAL_THEN `&n <= norm((f:real^M->real^N) x) /\ + norm(f x) < &n + &1` + STRIP_ASSUME_TAC THENL + [SUBGOAL_THEN `&n = floor(norm((f:real^M->real^N) x))` + (fun th -> MESON_TAC[th; FLOOR]) THEN + EXPAND_TAC "n" THEN + MP_TAC(ISPEC `norm((f:real^M->real^N) x)` FLOOR_POS) THEN + REWRITE_TAC[NORM_POS_LE; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `m:num` THEN DISCH_THEN SUBST1_TAC THEN + REWRITE_TAC[GSYM int_of_num; NUM_OF_INT_OF_NUM]; + ALL_TAC] THEN + DISCH_TAC THEN EXISTS_TAC `n:num` THEN ASM_REWRITE_TAC[] THEN CONJ_TAC THENL + [ASM_SIMP_TAC[IN_NUMSEG; LE_0] THEN + REWRITE_TAC[GSYM REAL_OF_NUM_LE; GSYM REAL_OF_NUM_ADD] THEN + MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `norm((f:real^M->real^N) x)` THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC(REAL_ARITH `x <= n ==> x <= n + &1`) THEN + ASM_MESON_TAC[]; + ALL_TAC] THEN + ASM_CASES_TAC `(x:real^M) IN s` THEN ASM_SIMP_TAC[indicator] THEN + REWRITE_TAC[DROP_VEC; REAL_MUL_RZERO; NORM_0; + VECTOR_MUL_RZERO; REAL_LE_REFL] THEN + ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN + REWRITE_TAC[DROP_VEC; REAL_MUL_RID; NORM_MUL] THEN + SUBGOAL_THEN `&0 <= content(k:real^M->bool)` ASSUME_TAC THENL + [ASM_MESON_TAC[TAGGED_DIVISION_OF; CONTENT_POS_LE]; ALL_TAC] THEN + ASM_REWRITE_TAC[real_abs] THEN MATCH_MP_TAC REAL_LE_LMUL THEN + ASM_SIMP_TAC[REAL_LT_IMP_LE]);; + +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 HAS_INTEGRAL_SPIKE_EQ = prove + (`!f:real^M->real^N g s t y. + negligible s /\ (!x. x IN (t DIFF s) ==> g x = f x) + ==> ((f has_integral y) t <=> (g has_integral y) t)`, + REPEAT STRIP_TAC THEN EQ_TAC THEN DISCH_TAC THEN + MATCH_MP_TAC HAS_INTEGRAL_SPIKE THENL + [EXISTS_TAC `f:real^M->real^N`; EXISTS_TAC `g:real^M->real^N`] THEN + EXISTS_TAC `s:real^M->bool` THEN ASM_REWRITE_TAC[] THEN + ASM_MESON_TAC[NORM_SUB]);; + +let INTEGRABLE_SPIKE = prove + (`!f:real^M->real^N g s t. + negligible s /\ (!x. x IN (t DIFF s) ==> g x = f x) + ==> f integrable_on t ==> g integrable_on t`, + REPEAT GEN_TAC THEN DISCH_TAC THEN REWRITE_TAC[integrable_on] THEN + MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC THEN + MP_TAC(SPEC_ALL HAS_INTEGRAL_SPIKE) THEN ASM_REWRITE_TAC[]);; + +let INTEGRAL_SPIKE = prove + (`!f:real^M->real^N g s t y. + negligible s /\ (!x. x IN (t DIFF s) ==> g x = f x) + ==> integral t f = integral t g`, + REPEAT STRIP_TAC THEN REWRITE_TAC[integral] THEN + AP_TERM_TAC THEN ABS_TAC THEN MATCH_MP_TAC HAS_INTEGRAL_SPIKE_EQ THEN + ASM_MESON_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* Some other trivialities about negligible sets. *) +(* ------------------------------------------------------------------------- *) + +let NEGLIGIBLE_SUBSET = prove + (`!s:real^N->bool t:real^N->bool. + negligible s /\ t SUBSET s ==> negligible t`, + REPEAT STRIP_TAC THEN REWRITE_TAC[negligible] THEN + MAP_EVERY X_GEN_TAC [`a:real^N`; `b:real^N`] THEN + MATCH_MP_TAC HAS_INTEGRAL_SPIKE THEN + MAP_EVERY EXISTS_TAC [`(\x. vec 0):real^N->real^1`; `s:real^N->bool`] THEN + ASM_REWRITE_TAC[HAS_INTEGRAL_0] THEN + REWRITE_TAC[indicator] THEN ASM SET_TAC[]);; + +let NEGLIGIBLE_DIFF = prove + (`!s t:real^N->bool. negligible s ==> negligible(s DIFF t)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC NEGLIGIBLE_SUBSET THEN + EXISTS_TAC `s:real^N->bool` THEN ASM_REWRITE_TAC[SUBSET_DIFF]);; + +let NEGLIGIBLE_INTER = prove + (`!s t. negligible s \/ negligible t ==> negligible(s INTER t)`, + MESON_TAC[NEGLIGIBLE_SUBSET; INTER_SUBSET]);; + +let NEGLIGIBLE_UNION = prove + (`!s t:real^N->bool. + negligible s /\ negligible t ==> negligible (s UNION t)`, + REPEAT GEN_TAC THEN DISCH_TAC THEN FIRST_ASSUM MP_TAC THEN + REWRITE_TAC[negligible; AND_FORALL_THM] THEN + MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `a:real^N` THEN + MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `b:real^N` THEN + DISCH_THEN(MP_TAC o MATCH_MP HAS_INTEGRAL_ADD) THEN + REWRITE_TAC[VECTOR_ADD_LID] THEN MATCH_MP_TAC EQ_IMP THEN + MATCH_MP_TAC HAS_INTEGRAL_SPIKE_EQ THEN + EXISTS_TAC `s:real^N->bool` THEN ASM_REWRITE_TAC[] THEN + SIMP_TAC[indicator; IN_UNION; IN_DIFF; VECTOR_ADD_LID]);; + +let NEGLIGIBLE_UNION_EQ = prove + (`!s t:real^N->bool. + negligible (s UNION t) <=> negligible s /\ negligible t`, + MESON_TAC[NEGLIGIBLE_UNION; SUBSET_UNION; NEGLIGIBLE_SUBSET]);; + +let NEGLIGIBLE_SING = prove + (`!a:real^N. negligible {a}`, + GEN_TAC THEN MATCH_MP_TAC NEGLIGIBLE_SUBSET THEN + EXISTS_TAC `{x | (x:real^N)$1 = (a:real^N)$1}` THEN + SIMP_TAC[NEGLIGIBLE_STANDARD_HYPERPLANE; LE_REFL; DIMINDEX_GE_1] THEN + SET_TAC[]);; + +let NEGLIGIBLE_INSERT = prove + (`!a:real^N s. negligible(a INSERT s) <=> negligible s`, + ONCE_REWRITE_TAC[SET_RULE `a INSERT s = {a} UNION s`] THEN + REWRITE_TAC[NEGLIGIBLE_UNION_EQ; NEGLIGIBLE_SING]);; + +let NEGLIGIBLE_EMPTY = prove + (`negligible {}`, + MESON_TAC[EMPTY_SUBSET; NEGLIGIBLE_SUBSET; NEGLIGIBLE_SING]);; + +let NEGLIGIBLE_FINITE = prove + (`!s. FINITE s ==> negligible s`, + MATCH_MP_TAC FINITE_INDUCT_STRONG THEN + SIMP_TAC[NEGLIGIBLE_EMPTY; NEGLIGIBLE_INSERT]);; + +let NEGLIGIBLE_UNIONS = prove + (`!s. FINITE s /\ (!t. t IN s ==> negligible t) + ==> negligible(UNIONS s)`, + REWRITE_TAC[IMP_CONJ] THEN MATCH_MP_TAC FINITE_INDUCT_STRONG THEN + REWRITE_TAC[UNIONS_0; UNIONS_INSERT; NEGLIGIBLE_EMPTY; IN_INSERT] THEN + SIMP_TAC[NEGLIGIBLE_UNION]);; + +let NEGLIGIBLE = prove + (`!s:real^N->bool. negligible s <=> !t. (indicator s has_integral vec 0) t`, + GEN_TAC THEN EQ_TAC THENL + [ALL_TAC; REWRITE_TAC[negligible] THEN SIMP_TAC[]] THEN + DISCH_TAC THEN GEN_TAC THEN ONCE_REWRITE_TAC[has_integral_alt] THEN + COND_CASES_TAC THENL [ASM_MESON_TAC[negligible]; ALL_TAC] THEN + GEN_TAC THEN DISCH_TAC THEN EXISTS_TAC `&1` THEN REWRITE_TAC[REAL_LT_01] THEN + REPEAT STRIP_TAC THEN EXISTS_TAC `vec 0:real^1` THEN + MP_TAC(ISPECL [`s:real^N->bool`; `s INTER t:real^N->bool`] + NEGLIGIBLE_SUBSET) THEN + ASM_REWRITE_TAC[INTER_SUBSET; negligible; VECTOR_SUB_REFL; NORM_0] THEN + REWRITE_TAC[indicator; IN_INTER] THEN + SIMP_TAC[TAUT `(if p /\ q then r else s) = + (if q then if p then r else s else s)`]);; + +(* ------------------------------------------------------------------------- *) +(* Finite or empty cases of the spike theorem are quite commonly needed. *) +(* ------------------------------------------------------------------------- *) + +let HAS_INTEGRAL_SPIKE_FINITE = prove + (`!f:real^M->real^N g s t y. + FINITE s /\ (!x. x IN (t DIFF s) ==> g x = f x) /\ + (f has_integral y) t + ==> (g has_integral y) t`, + MESON_TAC[HAS_INTEGRAL_SPIKE; NEGLIGIBLE_FINITE]);; + +let HAS_INTEGRAL_SPIKE_FINITE_EQ = prove + (`!f:real^M->real^N g s y. + FINITE s /\ (!x. x IN (t DIFF s) ==> g x = f x) + ==> ((f has_integral y) t <=> (g has_integral y) t)`, + MESON_TAC[HAS_INTEGRAL_SPIKE_FINITE]);; + +let INTEGRABLE_SPIKE_FINITE = prove + (`!f:real^M->real^N g s. + FINITE s /\ (!x. x IN (t DIFF s) ==> g x = f x) + ==> f integrable_on t + ==> g integrable_on t`, + REPEAT GEN_TAC THEN DISCH_TAC THEN REWRITE_TAC[integrable_on] THEN + MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC THEN + MP_TAC(SPEC_ALL HAS_INTEGRAL_SPIKE_FINITE) THEN ASM_REWRITE_TAC[]);; + +let INTEGRAL_EQ = prove + (`!f:real^M->real^N g s. + (!x. x IN s ==> f x = g x) ==> integral s f = integral s g`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC INTEGRAL_SPIKE THEN + EXISTS_TAC `{}:real^M->bool` THEN ASM_SIMP_TAC[NEGLIGIBLE_EMPTY; IN_DIFF]);; + +let INTEGRAL_EQ_0 = prove + (`!f:real^M->real^N s. (!x. x IN s ==> f x = vec 0) ==> integral s f = vec 0`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC EQ_TRANS THEN + EXISTS_TAC `integral s ((\x. vec 0):real^M->real^N)` THEN + CONJ_TAC THENL + [MATCH_MP_TAC INTEGRAL_EQ THEN ASM_REWRITE_TAC[]; + REWRITE_TAC[INTEGRAL_0]]);; + +(* ------------------------------------------------------------------------- *) +(* In particular, the boundary of an interval is negligible. *) +(* ------------------------------------------------------------------------- *) + +let NEGLIGIBLE_FRONTIER_INTERVAL = prove + (`!a b:real^N. negligible(interval[a,b] DIFF interval(a,b))`, + REPEAT GEN_TAC THEN MATCH_MP_TAC NEGLIGIBLE_SUBSET THEN + EXISTS_TAC `UNIONS (IMAGE (\k. {x:real^N | x$k = (a:real^N)$k} UNION + {x:real^N | x$k = (b:real^N)$k}) + (1..dimindex(:N)))` THEN + CONJ_TAC THENL + [MATCH_MP_TAC NEGLIGIBLE_UNIONS THEN + SIMP_TAC[FINITE_IMAGE; FINITE_NUMSEG; FORALL_IN_IMAGE] THEN + SIMP_TAC[IN_NUMSEG; NEGLIGIBLE_UNION_EQ; NEGLIGIBLE_STANDARD_HYPERPLANE]; + REWRITE_TAC[SUBSET; IN_DIFF; IN_INTERVAL; IN_UNIONS; EXISTS_IN_IMAGE] THEN + REWRITE_TAC[IN_NUMSEG; IN_UNION; IN_ELIM_THM; REAL_LT_LE] THEN + MESON_TAC[]]);; + +let HAS_INTEGRAL_SPIKE_INTERIOR = prove + (`!f:real^M->real^N g a b y. + (!x. x IN interval(a,b) ==> g x = f x) /\ + (f has_integral y) (interval[a,b]) + ==> (g has_integral y) (interval[a,b])`, + REPEAT GEN_TAC THEN REWRITE_TAC[IMP_CONJ] THEN DISCH_TAC THEN + MATCH_MP_TAC(REWRITE_RULE[TAUT `a /\ b /\ c ==> d <=> a /\ b ==> c ==> d`] + HAS_INTEGRAL_SPIKE) THEN + EXISTS_TAC `interval[a:real^M,b] DIFF interval(a,b)` THEN + REWRITE_TAC[NEGLIGIBLE_FRONTIER_INTERVAL] THEN ASM SET_TAC[]);; + +let HAS_INTEGRAL_SPIKE_INTERIOR_EQ = prove + (`!f:real^M->real^N g a b y. + (!x. x IN interval(a,b) ==> g x = f x) + ==> ((f has_integral y) (interval[a,b]) <=> + (g has_integral y) (interval[a,b]))`, + MESON_TAC[HAS_INTEGRAL_SPIKE_INTERIOR]);; + +let INTEGRABLE_SPIKE_INTERIOR = prove + (`!f:real^M->real^N g a b. + (!x. x IN interval(a,b) ==> g x = f x) + ==> f integrable_on (interval[a,b]) + ==> g integrable_on (interval[a,b])`, + REPEAT GEN_TAC THEN DISCH_TAC THEN REWRITE_TAC[integrable_on] THEN + MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC THEN + MP_TAC(SPEC_ALL HAS_INTEGRAL_SPIKE_INTERIOR) THEN ASM_REWRITE_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* Integrability of continuous functions. *) +(* ------------------------------------------------------------------------- *) + +let NEUTRAL_AND = prove + (`neutral(/\) = T`, + REWRITE_TAC[neutral; FORALL_BOOL_THM] THEN MESON_TAC[]);; + +let MONOIDAL_AND = prove + (`monoidal(/\)`, + REWRITE_TAC[monoidal; NEUTRAL_AND; CONJ_ACI]);; + +let ITERATE_AND = prove + (`!p s. FINITE s ==> (iterate(/\) s p <=> !x. x IN s ==> p x)`, + GEN_TAC THEN MATCH_MP_TAC FINITE_INDUCT_STRONG THEN + ASM_SIMP_TAC[MONOIDAL_AND; NEUTRAL_AND; ITERATE_CLAUSES] THEN SET_TAC[]);; + +let OPERATIVE_DIVISION_AND = prove + (`!P d a b. operative(/\) P /\ d division_of interval[a,b] + ==> ((!i. i IN d ==> P i) <=> P(interval[a,b]))`, + REPEAT GEN_TAC THEN DISCH_THEN(ASSUME_TAC o CONJ MONOIDAL_AND) THEN + FIRST_ASSUM(MP_TAC o MATCH_MP OPERATIVE_DIVISION) THEN + ASM_MESON_TAC[ITERATE_AND; DIVISION_OF_FINITE]);; + +let OPERATIVE_APPROXIMABLE = prove + (`!f:real^M->real^N e. + &0 <= e + ==> operative(/\) + (\i. ?g. (!x. x IN i ==> norm (f x - g x) <= e) /\ + g integrable_on i)`, + REPEAT STRIP_TAC THEN REWRITE_TAC[operative; NEUTRAL_AND] THEN CONJ_TAC THENL + [REPEAT STRIP_TAC THEN EXISTS_TAC `f:real^M->real^N` THEN + ASM_REWRITE_TAC[VECTOR_SUB_REFL; NORM_0; integrable_on] THEN + ASM_MESON_TAC[HAS_INTEGRAL_NULL]; + ALL_TAC] THEN + MAP_EVERY X_GEN_TAC [`u:real^M`; `v:real^M`; `c:real`; `k:num`] THEN + STRIP_TAC THEN EQ_TAC THENL + [ASM_MESON_TAC[INTEGRABLE_SPLIT; IN_INTER]; ALL_TAC] THEN + DISCH_THEN(CONJUNCTS_THEN2 + (X_CHOOSE_THEN `g1:real^M->real^N` STRIP_ASSUME_TAC) + (X_CHOOSE_THEN `g2:real^M->real^N` STRIP_ASSUME_TAC)) THEN + EXISTS_TAC `\x. if x$k = c then (f:real^M->real^N)(x) else + if x$k <= c then g1(x) else g2(x)` THEN + CONJ_TAC THENL + [GEN_TAC THEN STRIP_TAC THEN REWRITE_TAC[] THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[VECTOR_SUB_REFL; NORM_0] THEN + RULE_ASSUM_TAC(REWRITE_RULE[IN_INTER; IN_ELIM_THM]) THEN + ASM_MESON_TAC[REAL_ARITH `x <= c \/ x >= c`]; + ALL_TAC] THEN + SUBGOAL_THEN + `(\x:real^M. if x$k = c then f x else if x$k <= c then g1 x else g2 x) + integrable_on (interval[u,v] INTER {x | x$k <= c}) /\ + (\x. if x$k = c then f x :real^N else if x$k <= c then g1 x else g2 x) + integrable_on (interval[u,v] INTER {x | x$k >= c})` + MP_TAC THENL + [ALL_TAC; + REWRITE_TAC[integrable_on] THEN ASM_MESON_TAC[HAS_INTEGRAL_SPLIT]] THEN + CONJ_TAC THENL + [UNDISCH_TAC + `(g1:real^M->real^N) integrable_on (interval[u,v] INTER {x | x$k <= c})`; + UNDISCH_TAC + `(g2:real^M->real^N) integrable_on (interval[u,v] INTER {x | x$k >= c})` + ] THEN + ASM_SIMP_TAC[INTERVAL_SPLIT] THEN MATCH_MP_TAC INTEGRABLE_SPIKE THEN + ASM_SIMP_TAC[GSYM INTERVAL_SPLIT] THEN + EXISTS_TAC `{x:real^M | x$k = c}` THEN + ASM_SIMP_TAC[NEGLIGIBLE_STANDARD_HYPERPLANE; IN_DIFF; IN_INTER; IN_ELIM_THM; + REAL_ARITH `x >= c /\ ~(x = c) ==> ~(x <= c)`] THEN + EXISTS_TAC `e:real` THEN REPEAT STRIP_TAC THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[IN_INTER; IN_ELIM_THM]);; + +let APPROXIMABLE_ON_DIVISION = prove + (`!f:real^M->real^N d a b. + &0 <= e /\ + (d division_of interval[a,b]) /\ + (!i. i IN d + ==> ?g. (!x. x IN i ==> norm (f x - g x) <= e) /\ + g integrable_on i) + ==> ?g. (!x. x IN interval[a,b] ==> norm (f x - g x) <= e) /\ + g integrable_on interval[a,b]`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`(/\)`; `d:(real^M->bool)->bool`; + `a:real^M`; `b:real^M`; + `\i. ?g:real^M->real^N. + (!x. x IN i ==> norm (f x - g x) <= e) /\ + g integrable_on i`] + OPERATIVE_DIVISION) THEN + ASM_SIMP_TAC[OPERATIVE_APPROXIMABLE; MONOIDAL_AND] THEN + DISCH_THEN(SUBST1_TAC o SYM) THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP DIVISION_OF_FINITE) THEN + ASM_SIMP_TAC[ITERATE_AND]);; + +let INTEGRABLE_CONTINUOUS = prove + (`!f:real^M->real^N a b. + f continuous_on interval[a,b] ==> f integrable_on interval[a,b]`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC INTEGRABLE_UNIFORM_LIMIT THEN + X_GEN_TAC `e:real` THEN DISCH_TAC THEN + MATCH_MP_TAC APPROXIMABLE_ON_DIVISION THEN + ASM_SIMP_TAC[REAL_LT_IMP_LE] 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[dist] THEN + DISCH_THEN(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN + `?p. p tagged_division_of interval[a:real^M,b] /\ (\x. ball(x,d)) fine p` + STRIP_ASSUME_TAC THENL + [ASM_MESON_TAC[FINE_DIVISION_EXISTS; GAUGE_BALL]; ALL_TAC] THEN + EXISTS_TAC `IMAGE SND (p:real^M#(real^M->bool)->bool)` THEN + ASM_SIMP_TAC[DIVISION_OF_TAGGED_DIVISION] THEN + REWRITE_TAC[FORALL_IN_IMAGE; FORALL_PAIR_THM] THEN + MAP_EVERY X_GEN_TAC [`x:real^M`; `l:real^M->bool`] THEN + DISCH_TAC THEN EXISTS_TAC `\y:real^M. (f:real^M->real^N) x` 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[SUBSET] THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [fine]) THEN + REWRITE_TAC[SUBSET; IN_BALL; dist] THEN + FIRST_X_ASSUM SUBST_ALL_TAC THEN REPEAT STRIP_TAC THENL + [ASM_MESON_TAC[REAL_LT_IMP_LE; NORM_SUB]; + REWRITE_TAC[integrable_on] THEN + EXISTS_TAC `content(interval[a':real^M,b']) % (f:real^M->real^N) x` THEN + REWRITE_TAC[HAS_INTEGRAL_CONST]]);; + +(* ------------------------------------------------------------------------- *) +(* Specialization of additivity to one dimension. *) +(* ------------------------------------------------------------------------- *) + +let OPERATIVE_1_LT = prove + (`!op. monoidal op + ==> !f. operative op f <=> + (!a b. drop b <= drop a ==> f(interval[a,b]) = neutral op) /\ + (!a b c. drop a < drop c /\ drop c < drop b + ==> op (f(interval[a,c])) (f(interval[c,b])) = + f(interval[a,b]))`, + REPEAT STRIP_TAC THEN REWRITE_TAC[operative; CONTENT_EQ_0_1] THEN + MATCH_MP_TAC(TAUT `(a ==> (b <=> c)) ==> (a /\ b <=> a /\ c)`) THEN + DISCH_TAC THEN REWRITE_TAC[FORALL_1; DIMINDEX_1] THEN + AP_TERM_TAC THEN REWRITE_TAC[FUN_EQ_THM] THEN X_GEN_TAC `a:real^1` THEN + AP_TERM_TAC THEN REWRITE_TAC[FUN_EQ_THM] THEN X_GEN_TAC `b:real^1` THEN + EQ_TAC THEN DISCH_TAC THENL + [X_GEN_TAC `c:real^1` THEN FIRST_ASSUM(SUBST1_TAC o SPEC `drop c`) THEN + DISCH_TAC THEN FIRST_ASSUM(ASSUME_TAC o MATCH_MP REAL_LT_TRANS) THEN + ASM_SIMP_TAC[INTERVAL_SPLIT; DIMINDEX_1; LE_REFL; REAL_LT_IMP_LE] THEN + BINOP_TAC THEN AP_TERM_TAC THEN AP_TERM_TAC THEN + REWRITE_TAC[CONS_11; PAIR_EQ] THEN + SIMP_TAC[FORALL_1; CART_EQ; DIMINDEX_1; LAMBDA_BETA; LE_REFL] THEN + REWRITE_TAC[GSYM drop] THEN ASM_REAL_ARITH_TAC; + ALL_TAC] THEN + X_GEN_TAC `d:real` THEN ABBREV_TAC `c = lift d` THEN + SUBGOAL_THEN `d = drop c` SUBST1_TAC THENL + [ASM_MESON_TAC[LIFT_DROP]; ALL_TAC] THEN + SIMP_TAC[INTERVAL_SPLIT; LE_REFL; drop; DIMINDEX_1] THEN + REWRITE_TAC[GSYM drop] THEN + DISJ_CASES_TAC(REAL_ARITH `drop c <= drop a \/ drop a < drop c`) THENL + [SUBGOAL_THEN + `content(interval[a:real^1, + (lambda i. if i = 1 then min (drop b) (drop c) else b$i)]) = &0 /\ + interval[(lambda i. if i = 1 then max (drop a) (drop c) else a$i),b] = + interval[a,b]` + (CONJUNCTS_THEN2 MP_TAC SUBST1_TAC) THENL + [CONJ_TAC THENL + [SIMP_TAC[CONTENT_EQ_0_1]; + AP_TERM_TAC THEN REWRITE_TAC[CONS_11; PAIR_EQ]] THEN + SIMP_TAC[drop; CART_EQ; FORALL_1; LAMBDA_BETA; DIMINDEX_1; LE_REFL] THEN + UNDISCH_TAC `drop c <= drop a` THEN REWRITE_TAC[drop] THEN + REAL_ARITH_TAC; + REWRITE_TAC[CONTENT_EQ_0_1] THEN + DISCH_THEN(ANTE_RES_THEN SUBST1_TAC) THEN ASM_MESON_TAC[monoidal]]; + ALL_TAC] THEN + DISJ_CASES_TAC(REAL_ARITH `drop b <= drop c \/ drop c < drop b`) THENL + [SUBGOAL_THEN + `interval[a,(lambda i. if i = 1 then min (drop b) (drop c) else b$i)] = + interval[a,b] /\ + content(interval + [(lambda i. if i = 1 then max (drop a) (drop c) else a$i),b]) = &0` + (CONJUNCTS_THEN2 SUBST1_TAC MP_TAC) THENL + [CONJ_TAC THENL + [AP_TERM_TAC THEN REWRITE_TAC[CONS_11; PAIR_EQ]; + SIMP_TAC[CONTENT_EQ_0_1]] THEN + SIMP_TAC[drop; CART_EQ; FORALL_1; LAMBDA_BETA; DIMINDEX_1; LE_REFL] THEN + UNDISCH_TAC `drop b <= drop c` THEN REWRITE_TAC[drop] THEN + REAL_ARITH_TAC; + REWRITE_TAC[CONTENT_EQ_0_1] THEN + DISCH_THEN(ANTE_RES_THEN SUBST1_TAC) THEN ASM_MESON_TAC[monoidal]]; + ALL_TAC] THEN + SUBGOAL_THEN + `(lambda i. if i = 1 then min (drop b) (drop c) else b$i) = c /\ + (lambda i. if i = 1 then max (drop a) (drop c) else a$i) = c` + (fun th -> REWRITE_TAC[th] THEN ASM_MESON_TAC[]) THEN + SIMP_TAC[CART_EQ; FORALL_1; DIMINDEX_1; LE_REFL; LAMBDA_BETA] THEN + REWRITE_TAC[GSYM drop] THEN ASM_REAL_ARITH_TAC);; + +let OPERATIVE_1_LE = prove + (`!op. monoidal op + ==> !f. operative op f <=> + (!a b. drop b <= drop a ==> f(interval[a,b]) = neutral op) /\ + (!a b c. drop a <= drop c /\ drop c <= drop b + ==> op (f(interval[a,c])) (f(interval[c,b])) = + f(interval[a,b]))`, + GEN_TAC THEN DISCH_TAC THEN GEN_TAC THEN EQ_TAC THENL + [ALL_TAC; ASM_SIMP_TAC[OPERATIVE_1_LT] THEN MESON_TAC[REAL_LT_IMP_LE]] THEN + REWRITE_TAC[operative; CONTENT_EQ_0_1] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[FORALL_1; DIMINDEX_1] THEN + MAP_EVERY (fun t -> MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC t) + [`a:real^1`; `b:real^1`] THEN DISCH_TAC THEN + X_GEN_TAC `c:real^1` THEN FIRST_ASSUM(SUBST1_TAC o SPEC `drop c`) THEN + DISCH_TAC THEN FIRST_ASSUM(ASSUME_TAC o MATCH_MP REAL_LE_TRANS) THEN + ASM_SIMP_TAC[INTERVAL_SPLIT; DIMINDEX_1; LE_REFL] THEN + BINOP_TAC THEN AP_TERM_TAC THEN AP_TERM_TAC THEN + REWRITE_TAC[CONS_11; PAIR_EQ] THEN + SIMP_TAC[FORALL_1; CART_EQ; DIMINDEX_1; LAMBDA_BETA; LE_REFL] THEN + REWRITE_TAC[GSYM drop] THEN ASM_REAL_ARITH_TAC);; + +(* ------------------------------------------------------------------------- *) +(* Special case of additivity we need for the FCT. *) +(* ------------------------------------------------------------------------- *) + +let ADDITIVE_TAGGED_DIVISION_1 = prove + (`!f:real^1->real^N p a b. + drop a <= drop b /\ + p tagged_division_of interval[a,b] + ==> vsum p + (\(x,k). f(interval_upperbound k) - f(interval_lowerbound k)) = + f b - f a`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL + [`(+):real^N->real^N->real^N`; + `p:(real^1#(real^1->bool)->bool)`; + `a:real^1`; `b:real^1`; + `(\k. if k = {} then vec 0 + else f(interval_upperbound k) - f(interval_lowerbound k)): + ((real^1->bool)->real^N)`] OPERATIVE_TAGGED_DIVISION) THEN + ASM_SIMP_TAC[MONOIDAL_VECTOR_ADD; OPERATIVE_1_LT; NEUTRAL_VECTOR_ADD; + INTERVAL_LOWERBOUND_1; INTERVAL_UPPERBOUND_1] THEN + ANTS_TAC THENL + [ASM_SIMP_TAC[INTERVAL_EQ_EMPTY_1; REAL_ARITH `a <= b ==> ~(b < a)`; + REAL_LT_IMP_LE; CONTENT_EQ_0_1; + INTERVAL_LOWERBOUND_1; INTERVAL_UPPERBOUND_1] THEN + SIMP_TAC[REAL_ARITH `b <= a ==> (b < a <=> ~(b = a))`] THEN + SIMP_TAC[DROP_EQ; TAUT + `(if ~p then x else y) = (if p then y else x)`] THEN + SIMP_TAC[INTERVAL_LOWERBOUND_1; INTERVAL_UPPERBOUND_1; REAL_LE_REFL] THEN + REWRITE_TAC[VECTOR_SUB_REFL; COND_ID; EQ_SYM_EQ] THEN + REPEAT GEN_TAC THEN DISCH_TAC THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP REAL_LT_TRANS) THEN + ASM_SIMP_TAC[INTERVAL_LOWERBOUND_1; INTERVAL_UPPERBOUND_1; + REAL_ARITH `b < a ==> ~(a < b)`; REAL_LT_IMP_LE] THEN + MESON_TAC[VECTOR_ARITH `(c - a) + (b - c):real^N = b - a`]; + ALL_TAC] THEN + ASM_SIMP_TAC[INTERVAL_EQ_EMPTY_1; GSYM REAL_NOT_LE] 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] THEN MATCH_MP_TAC VSUM_EQ THEN + REWRITE_TAC[FORALL_PAIR_THM] THEN + ASM_MESON_TAC[TAGGED_DIVISION_OF; MEMBER_NOT_EMPTY]);; + +(* ------------------------------------------------------------------------- *) +(* A useful lemma allowing us to factor out the content size. *) +(* ------------------------------------------------------------------------- *) + +let HAS_INTEGRAL_FACTOR_CONTENT = prove + (`!f:real^M->real^N i a b. + (f has_integral i) (interval[a,b]) <=> + (!e. &0 < e + ==> ?d. gauge d /\ + (!p. p tagged_division_of interval[a,b] /\ d fine p + ==> norm (vsum p (\(x,k). content k % f x) - i) + <= e * content(interval[a,b])))`, + REPEAT GEN_TAC THEN + ASM_CASES_TAC `content(interval[a:real^M,b]) = &0` THENL + [MP_TAC(SPECL [`f:real^M->real^N`; `a:real^M`; `b:real^M`] + VSUM_CONTENT_NULL) THEN + ASM_SIMP_TAC[HAS_INTEGRAL_NULL_EQ; VECTOR_SUB_LZERO; NORM_NEG] THEN + DISCH_TAC THEN REWRITE_TAC[REAL_MUL_RZERO; NORM_LE_0] THEN + ASM_MESON_TAC[FINE_DIVISION_EXISTS; GAUGE_TRIVIAL; REAL_LT_01]; + ALL_TAC] THEN + REWRITE_TAC[has_integral] THEN EQ_TAC THEN DISCH_TAC THEN + X_GEN_TAC `e:real` THEN DISCH_TAC THENL + [FIRST_X_ASSUM(MP_TAC o SPEC `e * content(interval[a:real^M,b])`) THEN + ASM_SIMP_TAC[REAL_LT_MUL; CONTENT_LT_NZ] THEN MESON_TAC[REAL_LT_IMP_LE]; + ALL_TAC] THEN + FIRST_X_ASSUM(MP_TAC o SPEC `e / &2 / content(interval[a:real^M,b])`) THEN + ASM_SIMP_TAC[REAL_LT_DIV; CONTENT_LT_NZ; REAL_OF_NUM_LT; ARITH] THEN + ASM_SIMP_TAC[REAL_DIV_RMUL] THEN + ASM_MESON_TAC[REAL_ARITH `&0 < e /\ x <= e / &2 ==> x < e`]);; + +(* ------------------------------------------------------------------------- *) +(* Attempt a systematic general set of "offset" results for components. *) +(* ------------------------------------------------------------------------- *) + +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]);; + +(* ------------------------------------------------------------------------- *) +(* Integrabibility on subintervals. *) +(* ------------------------------------------------------------------------- *) + +let OPERATIVE_INTEGRABLE = prove + (`!f. operative (/\) (\i. f integrable_on i)`, + GEN_TAC THEN REWRITE_TAC[operative; NEUTRAL_AND] THEN CONJ_TAC THENL + [REWRITE_TAC[integrable_on] THEN MESON_TAC[HAS_INTEGRAL_NULL_EQ]; + REPEAT STRIP_TAC THEN EQ_TAC THEN ASM_SIMP_TAC[INTEGRABLE_SPLIT] THEN + REWRITE_TAC[integrable_on] THEN ASM_MESON_TAC[HAS_INTEGRAL_SPLIT]]);; + +let INTEGRABLE_SUBINTERVAL = prove + (`!f:real^M->real^N a b c d. + f integrable_on interval[a,b] /\ + interval[c,d] SUBSET interval[a,b] + ==> f integrable_on interval[c,d]`, + REPEAT STRIP_TAC THEN + ASM_CASES_TAC `interval[c:real^M,d] = {}` THENL + [ASM_REWRITE_TAC[integrable_on] THEN + MESON_TAC[HAS_INTEGRAL_NULL; CONTENT_EMPTY; EMPTY_AS_INTERVAL]; + ASM_MESON_TAC[OPERATIVE_INTEGRABLE; OPERATIVE_DIVISION_AND; + PARTIAL_DIVISION_EXTEND_1]]);; + +(* ------------------------------------------------------------------------- *) +(* Combining adjacent intervals in 1 dimension. *) +(* ------------------------------------------------------------------------- *) + +let HAS_INTEGRAL_COMBINE = prove + (`!f i:real^N j a b c. + drop a <= drop c /\ drop c <= drop b /\ + (f has_integral i) (interval[a,c]) /\ + (f has_integral j) (interval[c,b]) + ==> (f has_integral (i + j)) (interval[a,b])`, + REPEAT STRIP_TAC THEN MP_TAC + ((CONJUNCT2 o GEN_REWRITE_RULE I + [MATCH_MP OPERATIVE_1_LE(MATCH_MP MONOIDAL_LIFTED MONOIDAL_VECTOR_ADD)]) + (ISPEC `f:real^1->real^N` OPERATIVE_INTEGRAL)) THEN + DISCH_THEN(MP_TAC o SPECL [`a:real^1`; `b:real^1`; `c:real^1`]) THEN + ASM_REWRITE_TAC[] THEN + REPEAT(COND_CASES_TAC THEN + ASM_REWRITE_TAC[lifted; distinctness "option"; injectivity "option"]) THEN + ASM_MESON_TAC[INTEGRABLE_INTEGRAL; HAS_INTEGRAL_UNIQUE; integrable_on; + INTEGRAL_UNIQUE]);; + +let INTEGRAL_COMBINE = prove + (`!f:real^1->real^N a b c. + drop a <= drop c /\ drop c <= drop b /\ f integrable_on (interval[a,b]) + ==> integral(interval[a,c]) f + integral(interval[c,b]) f = + integral(interval[a,b]) f`, + REPEAT STRIP_TAC THEN CONV_TAC SYM_CONV THEN + MATCH_MP_TAC INTEGRAL_UNIQUE THEN MATCH_MP_TAC HAS_INTEGRAL_COMBINE THEN + EXISTS_TAC `c:real^1` THEN ASM_REWRITE_TAC[] THEN CONJ_TAC THEN + MATCH_MP_TAC INTEGRABLE_INTEGRAL THEN + MATCH_MP_TAC INTEGRABLE_SUBINTERVAL THEN + MAP_EVERY EXISTS_TAC [`a:real^1`; `b:real^1`] THEN + ASM_REWRITE_TAC[SUBSET_INTERVAL_1; REAL_LE_REFL]);; + +let INTEGRABLE_COMBINE = prove + (`!f a b c. + drop a <= drop c /\ drop c <= drop b /\ + f integrable_on interval[a,c] /\ + f integrable_on interval[c,b] + ==> f integrable_on interval[a,b]`, + REWRITE_TAC[integrable_on] THEN MESON_TAC[HAS_INTEGRAL_COMBINE]);; + +(* ------------------------------------------------------------------------- *) +(* Reduce integrability to "local" integrability. *) +(* ------------------------------------------------------------------------- *) + +let INTEGRABLE_ON_LITTLE_SUBINTERVALS = prove + (`!f:real^M->real^N a b. + (!x. x IN interval[a,b] + ==> ?d. &0 < d /\ + !u v. x IN interval[u,v] /\ + interval[u,v] SUBSET ball(x,d) /\ + interval[u,v] SUBSET interval[a,b] + ==> f integrable_on interval[u,v]) + ==> f integrable_on interval[a,b]`, + REPEAT GEN_TAC THEN + REWRITE_TAC[RIGHT_IMP_EXISTS_THM; GAUGE_EXISTENCE_LEMMA] THEN + REWRITE_TAC[SKOLEM_THM; FORALL_AND_THM] THEN + DISCH_THEN(X_CHOOSE_THEN `d:real^M->real` STRIP_ASSUME_TAC) THEN + MP_TAC(ISPECL [`\x:real^M. ball(x,d x)`; `a:real^M`; `b:real^M`] + FINE_DIVISION_EXISTS) THEN + ASM_SIMP_TAC[GAUGE_BALL_DEPENDENT; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `p:real^M#(real^M->bool)->bool` THEN STRIP_TAC THEN + MP_TAC(MATCH_MP (REWRITE_RULE[IMP_CONJ] OPERATIVE_DIVISION_AND) + (ISPEC `f:real^M->real^N` OPERATIVE_INTEGRABLE)) THEN + DISCH_THEN(MP_TAC o SPECL + [`IMAGE SND (p:real^M#(real^M->bool)->bool)`; `a:real^M`; `b:real^M`]) THEN + ASM_SIMP_TAC[DIVISION_OF_TAGGED_DIVISION] THEN + DISCH_THEN(SUBST1_TAC o SYM) THEN REWRITE_TAC[FORALL_IN_IMAGE] THEN + REWRITE_TAC[FORALL_PAIR_THM] THEN + MAP_EVERY X_GEN_TAC [`x:real^M`; `k:real^M->bool`] THEN DISCH_TAC THEN + FIRST_ASSUM(MP_TAC o el 1 o CONJUNCTS o + GEN_REWRITE_RULE I [TAGGED_DIVISION_OF]) THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [fine]) THEN + REWRITE_TAC[IMP_IMP; AND_FORALL_THM] THEN + DISCH_THEN(MP_TAC o SPECL [`x:real^M`; `k:real^M->bool`]) THEN + ASM_REWRITE_TAC[] THEN ASM_MESON_TAC[SUBSET]);; + +(* ------------------------------------------------------------------------- *) +(* Second FCT or existence of antiderivative. *) +(* ------------------------------------------------------------------------- *) + +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 ANTIDERIVATIVE_CONTINUOUS = prove + (`!f:real^1->real^N a b. + (f continuous_on interval[a,b]) + ==> ?g. !x. x IN interval[a,b] + ==> (g has_vector_derivative f(x)) + (at x within interval[a,b])`, + MESON_TAC[INTEGRAL_HAS_VECTOR_DERIVATIVE]);; + +(* ------------------------------------------------------------------------- *) +(* General "twiddling" for interval-to-interval function image. *) +(* ------------------------------------------------------------------------- *) + +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]);; + +(* ------------------------------------------------------------------------- *) +(* Special case of a basic affine transformation. *) +(* ------------------------------------------------------------------------- *) + +let INTERVAL_IMAGE_AFFINITY_INTERVAL = prove + (`!a b m c. ?u v. IMAGE (\x. m % x + c) (interval[a,b]) = interval[u,v]`, + REWRITE_TAC[IMAGE_AFFINITY_INTERVAL] THEN + MESON_TAC[EMPTY_AS_INTERVAL]);; + +let CONTENT_IMAGE_AFFINITY_INTERVAL = prove + (`!a b:real^N m c. + content(IMAGE (\x. m % x + c) (interval[a,b])) = + (abs m) pow (dimindex(:N)) * content(interval[a,b])`, + REPEAT STRIP_TAC THEN REWRITE_TAC[IMAGE_AFFINITY_INTERVAL] THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[CONTENT_EMPTY; REAL_MUL_RZERO] THEN + RULE_ASSUM_TAC(REWRITE_RULE[INTERVAL_NE_EMPTY]) THEN COND_CASES_TAC THEN + W(fun (asl,w) -> MP_TAC(PART_MATCH (lhand o rand) CONTENT_CLOSED_INTERVAL + (lhs w))) THEN + (ANTS_TAC THENL + [X_GEN_TAC `i:num` THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `i:num`) THEN + ASM_SIMP_TAC[VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT; + REAL_LE_RADD; REAL_LE_LMUL] THEN + ONCE_REWRITE_TAC[REAL_ARITH `m * b <= m * a <=> --m * a <= --m * b`] THEN + ASM_SIMP_TAC[REAL_ARITH `~(&0 <= x) ==> &0 <= --x`; REAL_LE_LMUL]; + ALL_TAC]) THEN + DISCH_THEN SUBST1_TAC THEN + ONCE_REWRITE_TAC[GSYM PRODUCT_CONST_NUMSEG_1] THEN + ASM_SIMP_TAC[CONTENT_CLOSED_INTERVAL; GSYM PRODUCT_MUL_NUMSEG] THEN + MATCH_MP_TAC PRODUCT_EQ THEN + SIMP_TAC[IN_NUMSEG; VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT] THEN + ASM_REAL_ARITH_TAC);; + +let HAS_INTEGRAL_AFFINITY = prove + (`!f:real^M->real^N i a b m c. + (f has_integral i) (interval[a,b]) /\ ~(m = &0) + ==> ((\x. f(m % x + c)) has_integral + (inv(abs(m) pow dimindex(:M)) % i)) + (IMAGE (\x. inv m % x + --(inv(m) % c)) (interval[a,b]))`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_INTEGRAL_TWIDDLE THEN + ASM_SIMP_TAC[INTERVAL_IMAGE_AFFINITY_INTERVAL; GSYM REAL_ABS_NZ; + REAL_POW_LT; PRODUCT_EQ_0_NUMSEG; CONTENT_IMAGE_AFFINITY_INTERVAL] THEN + ASM_SIMP_TAC[CONTINUOUS_CMUL; CONTINUOUS_AT_ID; CONTINUOUS_CONST; + CONTINUOUS_ADD] THEN + REWRITE_TAC[VECTOR_ADD_LDISTRIB; VECTOR_MUL_ASSOC; VECTOR_MUL_RNEG] THEN + ASM_SIMP_TAC[REAL_MUL_LINV; REAL_MUL_RINV] THEN + CONJ_TAC THEN VECTOR_ARITH_TAC);; + +let INTEGRABLE_AFFINITY = prove + (`!f:real^M->real^N a b m c. + f integrable_on interval[a,b] /\ ~(m = &0) + ==> (\x. f(m % x + c)) integrable_on + (IMAGE (\x. inv m % x + --(inv(m) % c)) (interval[a,b]))`, + REWRITE_TAC[integrable_on] THEN MESON_TAC[HAS_INTEGRAL_AFFINITY]);; + +(* ------------------------------------------------------------------------- *) +(* Special case of stretching coordinate axes separately. *) +(* ------------------------------------------------------------------------- *) + +let CONTENT_IMAGE_STRETCH_INTERVAL = prove + (`!a b:real^N m. + content(IMAGE (\x. lambda k. m k * x$k) (interval[a,b]):real^N->bool) = + abs(product(1..dimindex(:N)) m) * content(interval[a,b])`, + REPEAT GEN_TAC THEN REWRITE_TAC[content; IMAGE_EQ_EMPTY] THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[REAL_MUL_RZERO] THEN + ASM_REWRITE_TAC[IMAGE_STRETCH_INTERVAL] THEN + RULE_ASSUM_TAC(REWRITE_RULE[INTERVAL_NE_EMPTY]) THEN + ASM_SIMP_TAC[INTERVAL_UPPERBOUND; INTERVAL_LOWERBOUND; LAMBDA_BETA; + REAL_ARITH `min a b <= max a b`] THEN + ASM_REWRITE_TAC[REAL_ARITH `max a b - min a b = abs(b - a)`; + GSYM REAL_SUB_LDISTRIB; REAL_ABS_MUL] THEN + ASM_SIMP_TAC[PRODUCT_MUL; FINITE_NUMSEG; + REAL_ARITH `a <= b ==> abs(b - a) = b - a`] THEN + ASM_SIMP_TAC[PRODUCT_ABS; FINITE_NUMSEG]);; + +let HAS_INTEGRAL_STRETCH = prove + (`!f:real^M->real^N i m a b. + (f has_integral i) (interval[a,b]) /\ + (!k. 1 <= k /\ k <= dimindex(:M) ==> ~(m k = &0)) + ==> ((\x:real^M. f(lambda k. m k * x$k)) has_integral + (inv(abs(product(1..dimindex(:M)) m)) % i)) + (IMAGE (\x. lambda k. inv(m k) * x$k) (interval[a,b]))`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_INTEGRAL_TWIDDLE THEN + SIMP_TAC[CART_EQ; LAMBDA_BETA] THEN + ASM_SIMP_TAC[REAL_MUL_ASSOC; REAL_MUL_LINV; REAL_MUL_RINV; REAL_MUL_LID] THEN + ASM_REWRITE_TAC[GSYM REAL_ABS_NZ; PRODUCT_EQ_0_NUMSEG] THEN + CONJ_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN CONJ_TAC THENL + [GEN_TAC THEN MATCH_MP_TAC LINEAR_CONTINUOUS_AT THEN + SIMP_TAC[linear; LAMBDA_BETA; CART_EQ; VECTOR_ADD_COMPONENT; + VECTOR_MUL_COMPONENT] THEN REAL_ARITH_TAC; + REWRITE_TAC[CONTENT_IMAGE_STRETCH_INTERVAL] THEN + REWRITE_TAC[IMAGE_STRETCH_INTERVAL] THEN MESON_TAC[EMPTY_AS_INTERVAL]]);; + +let INTEGRABLE_STRETCH = prove + (`!f:real^M->real^N m a b. + f integrable_on interval[a,b] /\ + (!k. 1 <= k /\ k <= dimindex(:M) ==> ~(m k = &0)) + ==> (\x:real^M. f(lambda k. m k * x$k)) integrable_on + (IMAGE (\x. lambda k. inv(m k) * x$k) (interval[a,b]))`, + REWRITE_TAC[integrable_on] THEN MESON_TAC[HAS_INTEGRAL_STRETCH]);; + +(* ------------------------------------------------------------------------- *) +(* Even more special cases. *) +(* ------------------------------------------------------------------------- *) + +let HAS_INTEGRAL_REFLECT_LEMMA = prove + (`!f:real^M->real^N i a b. + (f has_integral i) (interval[a,b]) + ==> ((\x. f(--x)) has_integral i) (interval[--b,--a])`, + REPEAT STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o C CONJ (REAL_ARITH `~(-- &1 = &0)`)) THEN + DISCH_THEN(MP_TAC o MATCH_MP HAS_INTEGRAL_AFFINITY) THEN + DISCH_THEN(MP_TAC o SPEC `vec 0:real^M`) THEN + REWRITE_TAC[IMAGE_AFFINITY_INTERVAL] THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN + REWRITE_TAC[REAL_ABS_NEG; REAL_ABS_NUM; REAL_POW_ONE] THEN + REWRITE_TAC[VECTOR_MUL_RZERO; VECTOR_NEG_0] THEN + REWRITE_TAC[REAL_INV_NEG; REAL_INV_1] THEN + REWRITE_TAC[VECTOR_ARITH `-- &1 % x + vec 0 = --x`] THEN + REWRITE_TAC[VECTOR_MUL_LID] THEN MATCH_MP_TAC EQ_IMP THEN + AP_TERM_TAC THEN POP_ASSUM(K ALL_TAC) THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN CONV_TAC SYM_CONV THEN + POP_ASSUM MP_TAC THEN REWRITE_TAC[INTERVAL_EQ_EMPTY] THEN + REWRITE_TAC[TAUT `a /\ b /\ c <=> ~(a /\ b ==> ~c)`] THEN + SIMP_TAC[VECTOR_NEG_COMPONENT; REAL_LT_NEG2]);; + +let HAS_INTEGRAL_REFLECT = prove + (`!f:real^M->real^N i a b. + ((\x. f(--x)) has_integral i) (interval[--b,--a]) <=> + (f has_integral i) (interval[a,b])`, + REPEAT GEN_TAC THEN EQ_TAC THEN + DISCH_THEN(MP_TAC o MATCH_MP HAS_INTEGRAL_REFLECT_LEMMA) THEN + REWRITE_TAC[VECTOR_NEG_NEG; ETA_AX]);; + +let INTEGRABLE_REFLECT = prove + (`!f:real^M->real^N a b. + (\x. f(--x)) integrable_on (interval[--b,--a]) <=> + f integrable_on (interval[a,b])`, + REWRITE_TAC[integrable_on; HAS_INTEGRAL_REFLECT]);; + +let INTEGRAL_REFLECT = prove + (`!f:real^M->real^N a b. + integral (interval[--b,--a]) (\x. f(--x)) = + integral (interval[a,b]) f`, + REWRITE_TAC[integral; HAS_INTEGRAL_REFLECT]);; + +(* ------------------------------------------------------------------------- *) +(* Technical lemmas about how many non-trivial intervals of a division a *) +(* point can be in (we sometimes need this for bounding sums). *) +(* ------------------------------------------------------------------------- *) + +let DIVISION_COMMON_POINT_BOUND = prove + (`!d s:real^N->bool x. + d division_of s + ==> CARD {k | k IN d /\ ~(content k = &0) /\ x IN k} + <= 2 EXP (dimindex(:N))`, + let lemma = prove + (`!f s. (!x y. x IN s /\ y IN s /\ f x = f y ==> x = y) /\ + FINITE s /\ CARD(IMAGE f s) <= n + ==> CARD(s) <= n`, + MESON_TAC[CARD_IMAGE_INJ]) in + REPEAT STRIP_TAC THEN + SUBGOAL_THEN `!k. k IN d ==> ?a b:real^N. interval[a,b] = k` MP_TAC THENL + [ASM_MESON_TAC[division_of]; ALL_TAC] THEN + REWRITE_TAC[RIGHT_IMP_EXISTS_THM; SKOLEM_THM; LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC + [`A:(real^N->bool)->real^N`; `B:(real^N->bool)->real^N`] THEN + STRIP_TAC THEN MATCH_MP_TAC(ISPEC + `\d. (lambda i. (x:real^N)$i = (A:(real^N->bool)->real^N)(d)$i):bool^N` + lemma) THEN + REPEAT CONJ_TAC THENL + [ALL_TAC; + MATCH_MP_TAC FINITE_RESTRICT THEN ASM_MESON_TAC[division_of]; + MATCH_MP_TAC LE_TRANS THEN EXISTS_TAC `CARD(:bool^N)` THEN CONJ_TAC THENL + [MATCH_MP_TAC CARD_SUBSET THEN REWRITE_TAC[SUBSET_UNIV] THEN + SIMP_TAC[FINITE_CART_UNIV; FINITE_BOOL]; + SIMP_TAC[FINITE_BOOL; CARD_CART_UNIV; CARD_BOOL; LE_REFL]]] THEN + MAP_EVERY X_GEN_TAC [`k:real^N->bool`; `l:real^N->bool`] THEN + SIMP_TAC[IN_ELIM_THM; CART_EQ; LAMBDA_BETA] THEN STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [division_of]) THEN + DISCH_THEN(MP_TAC o SPECL [`k:real^N->bool`; `l:real^N->bool`] o + el 2 o CONJUNCTS) THEN + ASM_REWRITE_TAC[GSYM INTERIOR_INTER] THEN + MATCH_MP_TAC(TAUT `~q ==> (~p ==> q) ==> p`) THEN + MAP_EVERY UNDISCH_TAC + [`(x:real^N) IN k`; `(x:real^N) IN l`; + `~(content(k:real^N->bool) = &0)`; + `~(content(l:real^N->bool) = &0)`] THEN + SUBGOAL_THEN + `k = interval[A k:real^N,B k] /\ l = interval[A l,B l]` + (CONJUNCTS_THEN SUBST1_TAC) + THENL [ASM_MESON_TAC[]; REWRITE_TAC[INTER_INTERVAL]] THEN + REWRITE_TAC[CONTENT_EQ_0_INTERIOR; INTERIOR_CLOSED_INTERVAL] THEN + SIMP_TAC[IN_INTERVAL; INTERVAL_NE_EMPTY; LAMBDA_BETA] THEN + REPEAT 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 TAGGED_PARTIAL_DIVISION_COMMON_POINT_BOUND = prove + (`!p s:real^N->bool y. + p tagged_partial_division_of s + ==> CARD {(x,k) | (x,k) IN p /\ y IN k /\ ~(content k = &0)} + <= 2 EXP (dimindex(:N))`, + let lemma = prove + (`!f s. (!x y. x IN s /\ y IN s /\ f x = f y ==> x = y) /\ + FINITE s /\ CARD(IMAGE f s) <= n + ==> CARD(s) <= n`, + MESON_TAC[CARD_IMAGE_INJ]) in + REPEAT STRIP_TAC THEN MATCH_MP_TAC(ISPEC `SND` lemma) THEN + REPEAT CONJ_TAC THENL + [REWRITE_TAC[IMP_CONJ; FORALL_IN_GSPEC; RIGHT_FORALL_IMP_THM; PAIR_EQ] THEN + MAP_EVERY X_GEN_TAC [`x1:real^N`; `k1:real^N->bool`] THEN + REPEAT DISCH_TAC THEN + MAP_EVERY X_GEN_TAC [`x2:real^N`; `k2:real^N->bool`] THEN + REPEAT DISCH_TAC THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [tagged_partial_division_of]) THEN + DISCH_THEN(MP_TAC o SPECL + [`x1:real^N`; `k1:real^N->bool`; `x2:real^N`; `k2:real^N->bool`] o + CONJUNCT2 o CONJUNCT2) THEN + ASM_REWRITE_TAC[PAIR_EQ] THEN + MATCH_MP_TAC(TAUT `~q ==> (~p ==> q) ==> p`) THEN + REWRITE_TAC[INTER_ACI] THEN + ASM_MESON_TAC[CONTENT_EQ_0_INTERIOR; tagged_partial_division_of]; + MATCH_MP_TAC FINITE_SUBSET THEN + EXISTS_TAC `p:real^N#(real^N->bool)->bool` THEN CONJ_TAC THENL + [ASM_MESON_TAC[tagged_partial_division_of]; SET_TAC[]]; + FIRST_ASSUM(MP_TAC o MATCH_MP PARTIAL_DIVISION_OF_TAGGED_DIVISION) THEN + DISCH_THEN(MP_TAC o SPEC `y:real^N` o + MATCH_MP DIVISION_COMMON_POINT_BOUND) THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] LE_TRANS) THEN + MATCH_MP_TAC CARD_SUBSET THEN CONJ_TAC THENL + [REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; FORALL_IN_GSPEC] THEN + REWRITE_TAC[IN_ELIM_THM; IN_IMAGE; EXISTS_PAIR_THM] THEN MESON_TAC[]; + MATCH_MP_TAC FINITE_RESTRICT THEN MATCH_MP_TAC FINITE_IMAGE THEN + ASM_MESON_TAC[tagged_partial_division_of]]]);; + +let TAGGED_PARTIAL_DIVISION_COMMON_TAGS = prove + (`!p s:real^N->bool x. + p tagged_partial_division_of s + ==> CARD {(x,k) | k | (x,k) IN p /\ ~(content k = &0)} + <= 2 EXP (dimindex(:N))`, + REPEAT STRIP_TAC THEN FIRST_ASSUM(MP_TAC o SPEC `x:real^N` o + MATCH_MP TAGGED_PARTIAL_DIVISION_COMMON_POINT_BOUND) THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] LE_TRANS) THEN + MATCH_MP_TAC CARD_SUBSET THEN CONJ_TAC THENL + [REWRITE_TAC[SUBSET; FORALL_IN_GSPEC; IN_ELIM_PAIR_THM] THEN + ASM_MESON_TAC[tagged_partial_division_of]; + MATCH_MP_TAC FINITE_SUBSET THEN + EXISTS_TAC `p:real^N#(real^N->bool)->bool` THEN CONJ_TAC THENL + [ASM_MESON_TAC[tagged_partial_division_of]; SET_TAC[]]]);; + +(* ------------------------------------------------------------------------- *) +(* Integrating characteristic function of an interval. *) +(* ------------------------------------------------------------------------- *) + +let HAS_INTEGRAL_RESTRICT_OPEN_SUBINTERVAL = prove + (`!f:real^M->real^N a b c d i. + (f has_integral i) (interval[c,d]) /\ + interval[c,d] SUBSET interval[a,b] + ==> ((\x. if x IN interval(c,d) then f x else vec 0) has_integral i) + (interval[a,b])`, + REPEAT GEN_TAC THEN ASM_CASES_TAC `interval[c:real^M,d] = {}` THENL + [FIRST_ASSUM(MP_TAC o AP_TERM + `interior:(real^M->bool)->(real^M->bool)`) THEN + SIMP_TAC[INTERIOR_CLOSED_INTERVAL; INTERIOR_EMPTY] THEN + ASM_SIMP_TAC[NOT_IN_EMPTY; HAS_INTEGRAL_0_EQ; HAS_INTEGRAL_EMPTY_EQ]; + ALL_TAC] THEN + ABBREV_TAC `g:real^M->real^N = + \x. if x IN interval(c,d) then f x else vec 0` THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + FIRST_X_ASSUM(MP_TAC o check(is_neg o concl)) THEN + REWRITE_TAC[TAUT `a ==> b ==> c <=> b /\ a ==> c`] THEN + DISCH_THEN(MP_TAC o MATCH_MP PARTIAL_DIVISION_EXTEND_1) THEN + DISCH_THEN(X_CHOOSE_THEN `p:(real^M->bool)->bool` STRIP_ASSUME_TAC) THEN + MP_TAC(ISPECL + [`lifted((+):real^N->real^N->real^N)`; + `p:(real^M->bool)->bool`; + `a:real^M`; `b:real^M`; + `\i. if (g:real^M->real^N) integrable_on i + then SOME (integral i g) else NONE`] + OPERATIVE_DIVISION) THEN + ASM_SIMP_TAC[OPERATIVE_INTEGRAL; MONOIDAL_LIFTED; MONOIDAL_VECTOR_ADD] THEN + SUBGOAL_THEN + `iterate (lifted (+)) p + (\i. if (g:real^M->real^N) integrable_on i + then SOME (integral i g) else NONE) = + SOME i` + SUBST1_TAC THENL + [ALL_TAC; + COND_CASES_TAC THEN + REWRITE_TAC[distinctness "option"; injectivity "option"] THEN + ASM_MESON_TAC[INTEGRABLE_INTEGRAL]] THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP DIVISION_OF_FINITE) THEN + FIRST_ASSUM(SUBST1_TAC o MATCH_MP (SET_RULE + `x IN s ==> s = x INSERT (s DELETE x)`)) THEN + ASM_SIMP_TAC[ITERATE_CLAUSES; MONOIDAL_LIFTED; MONOIDAL_VECTOR_ADD; + FINITE_DELETE; IN_DELETE] THEN + SUBGOAL_THEN `(g:real^M->real^N) integrable_on interval[c,d]` + ASSUME_TAC THENL + [FIRST_ASSUM(MP_TAC o MATCH_MP HAS_INTEGRAL_INTEGRABLE) THEN + MATCH_MP_TAC INTEGRABLE_SPIKE_INTERIOR THEN + EXPAND_TAC "g" THEN SIMP_TAC[]; + ALL_TAC] THEN + ASM_REWRITE_TAC[] THEN + SUBGOAL_THEN + `iterate (lifted (+)) (p DELETE interval[c,d]) + (\i. if (g:real^M->real^N) integrable_on i + then SOME (integral i g) else NONE) = SOME(vec 0)` + SUBST1_TAC THENL + [ALL_TAC; + REWRITE_TAC[lifted; VECTOR_ADD_RID] THEN AP_TERM_TAC THEN + MATCH_MP_TAC INTEGRAL_UNIQUE THEN + MATCH_MP_TAC HAS_INTEGRAL_SPIKE_INTERIOR THEN + EXISTS_TAC `f:real^M->real^N` THEN + EXPAND_TAC "g" THEN ASM_SIMP_TAC[]] THEN + SIMP_TAC[GSYM NEUTRAL_VECTOR_ADD; GSYM NEUTRAL_LIFTED; + MONOIDAL_VECTOR_ADD] THEN + MATCH_MP_TAC(MATCH_MP ITERATE_EQ_NEUTRAL + (MATCH_MP MONOIDAL_LIFTED(SPEC_ALL MONOIDAL_VECTOR_ADD))) THEN + SIMP_TAC[NEUTRAL_LIFTED; NEUTRAL_VECTOR_ADD; MONOIDAL_VECTOR_ADD] THEN + X_GEN_TAC `k:real^M->bool` THEN REWRITE_TAC[IN_DELETE] THEN STRIP_TAC THEN + SUBGOAL_THEN `((g:real^M->real^N) has_integral (vec 0)) k` + (fun th -> MESON_TAC[th; integrable_on; INTEGRAL_UNIQUE]) THEN + SUBGOAL_THEN `?u v:real^M. k = interval[u,v]` MP_TAC THENL + [ASM_MESON_TAC[division_of]; ALL_TAC] THEN + DISCH_THEN(REPEAT_TCL CHOOSE_THEN SUBST_ALL_TAC) THEN + MATCH_MP_TAC HAS_INTEGRAL_SPIKE_INTERIOR THEN + EXISTS_TAC `(\x. vec 0):real^M->real^N` THEN + REWRITE_TAC[HAS_INTEGRAL_0] THEN X_GEN_TAC `x:real^M` 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[c:real^M,d]`; `interval[u:real^M,v]`]) THEN + ASM_REWRITE_TAC[INTERIOR_CLOSED_INTERVAL] THEN + EXPAND_TAC "g" THEN REWRITE_TAC[] THEN COND_CASES_TAC THEN ASM SET_TAC[]);; + +let HAS_INTEGRAL_RESTRICT_CLOSED_SUBINTERVAL = prove + (`!f:real^M->real^N a b c d i. + (f has_integral i) (interval[c,d]) /\ + interval[c,d] SUBSET interval[a,b] + ==> ((\x. if x IN interval[c,d] then f x else vec 0) has_integral i) + (interval[a,b])`, + REPEAT GEN_TAC THEN + DISCH_THEN(MP_TAC o MATCH_MP HAS_INTEGRAL_RESTRICT_OPEN_SUBINTERVAL) THEN + MATCH_MP_TAC(REWRITE_RULE[TAUT `a /\ b /\ c ==> d <=> a /\ b ==> c ==> d`] + HAS_INTEGRAL_SPIKE) THEN + EXISTS_TAC `interval[c:real^M,d] DIFF interval(c,d)` THEN + REWRITE_TAC[NEGLIGIBLE_FRONTIER_INTERVAL] THEN REWRITE_TAC[IN_DIFF] THEN + MP_TAC(ISPECL [`c:real^M`; `d:real^M`] INTERVAL_OPEN_SUBSET_CLOSED) THEN + SET_TAC[]);; + +let HAS_INTEGRAL_RESTRICT_CLOSED_SUBINTERVALS_EQ = prove + (`!f:real^M->real^N a b c d i. + interval[c,d] SUBSET interval[a,b] + ==> (((\x. if x IN interval[c,d] then f x else vec 0) has_integral i) + (interval[a,b]) <=> + (f has_integral i) (interval[c,d]))`, + REPEAT STRIP_TAC THEN ASM_CASES_TAC `interval[c:real^M,d] = {}` THENL + [ASM_REWRITE_TAC[NOT_IN_EMPTY; HAS_INTEGRAL_0_EQ; HAS_INTEGRAL_EMPTY_EQ]; + ALL_TAC] THEN + EQ_TAC THEN DISCH_TAC THEN + ASM_SIMP_TAC[HAS_INTEGRAL_RESTRICT_CLOSED_SUBINTERVAL] THEN + SUBGOAL_THEN `(f:real^M->real^N) integrable_on interval[c,d]` MP_TAC THENL + [MATCH_MP_TAC INTEGRABLE_EQ THEN + EXISTS_TAC `\x. if x IN interval[c:real^M,d] + then f x:real^N else vec 0` THEN + SIMP_TAC[] THEN MATCH_MP_TAC INTEGRABLE_SUBINTERVAL THEN + ASM_MESON_TAC[integrable_on]; + ALL_TAC] THEN + DISCH_THEN(fun th -> ASSUME_TAC th THEN MP_TAC th) THEN + DISCH_THEN(MP_TAC o MATCH_MP INTEGRABLE_INTEGRAL) THEN + MP_TAC(ASSUME `interval[c:real^M,d] SUBSET interval[a,b]`) THEN + REWRITE_TAC[IMP_IMP] THEN ONCE_REWRITE_TAC[CONJ_SYM] THEN + DISCH_THEN(MP_TAC o MATCH_MP HAS_INTEGRAL_RESTRICT_CLOSED_SUBINTERVAL) THEN + ASM_MESON_TAC[HAS_INTEGRAL_UNIQUE; INTEGRABLE_INTEGRAL]);; + +(* ------------------------------------------------------------------------- *) +(* Hence we can apply the limit process uniformly to all integrals. *) +(* ------------------------------------------------------------------------- *) + +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"; "d"] THEN + SIMP_TAC[LAMBDA_BETA; REAL_BOUNDS_LE] THEN STRIP_TAC THEN + MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC `norm(x:real^M)` THEN + ASM_SIMP_TAC[COMPONENT_LE_NORM] THEN + MATCH_MP_TAC(REAL_ARITH `x <= B ==> x <= max B C`) THEN + ASM_SIMP_TAC[]; + ALL_TAC] THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`c:real^M`; `d:real^M`]) THEN ANTS_TAC THENL + [REWRITE_TAC[SUBSET; IN_BALL; NORM_ARITH `dist(vec 0,x) = norm x`] 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"; "d"] THEN + SIMP_TAC[LAMBDA_BETA; REAL_BOUNDS_LE] THEN STRIP_TAC THEN + MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC `norm(x:real^M)` THEN + ASM_SIMP_TAC[COMPONENT_LE_NORM] THEN + MATCH_MP_TAC(REAL_ARITH `x < C ==> x <= max B C`) THEN + ASM_SIMP_TAC[]; + ALL_TAC] THEN + MESON_TAC[integrable_on]; + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [integrable_on]) THEN + ASM_SIMP_TAC[HAS_INTEGRAL_RESTRICT_CLOSED_SUBINTERVALS_EQ]]; + ALL_TAC] THEN + DISCH_THEN(X_CHOOSE_TAC `y:real^N`) THEN + SUBGOAL_THEN `i:real^N = y` ASSUME_TAC THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC(NORM_ARITH `~(&0 < norm(y - i)) ==> i = y`) THEN + DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC `norm(y - i:real^N)`) THEN + ASM_REWRITE_TAC[NOT_EXISTS_THM] THEN X_GEN_TAC `C:real` THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + REWRITE_TAC[NOT_FORALL_THM; NOT_IMP] 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; IN_BALL; NORM_ARITH `dist(vec 0,x) = norm x`] 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"; "d"] THEN + SIMP_TAC[LAMBDA_BETA; REAL_BOUNDS_LE] THEN STRIP_TAC THEN + MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC `norm(x:real^M)` THEN + ASM_SIMP_TAC[COMPONENT_LE_NORM] THEN + MATCH_MP_TAC(REAL_ARITH `x < C ==> x <= max B C`) THEN + ASM_SIMP_TAC[]; + ALL_TAC] THEN + SUBGOAL_THEN `interval[a:real^M,b] SUBSET interval[c,d]` ASSUME_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"; "d"] THEN + SIMP_TAC[LAMBDA_BETA; REAL_BOUNDS_LE] THEN STRIP_TAC THEN + MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC `norm(x:real^M)` THEN + ASM_SIMP_TAC[COMPONENT_LE_NORM] THEN + MATCH_MP_TAC(REAL_ARITH `x <= B ==> x <= max B C`) THEN + ASM_SIMP_TAC[]; + ALL_TAC] THEN + ASM_SIMP_TAC[HAS_INTEGRAL_RESTRICT_CLOSED_SUBINTERVALS_EQ] THEN + ASM_MESON_TAC[REAL_LT_REFL; HAS_INTEGRAL_UNIQUE]);; + +(* ------------------------------------------------------------------------- *) +(* Hence a general restriction property. *) +(* ------------------------------------------------------------------------- *) + +let HAS_INTEGRAL_RESTRICT = prove + (`!f:real^M->real^N s t i. + s SUBSET t + ==> (((\x. if x IN s then f x else vec 0) has_integral i) t <=> + (f has_integral i) s)`, + REWRITE_TAC[SUBSET] THEN REPEAT STRIP_TAC THEN + ONCE_REWRITE_TAC[HAS_INTEGRAL] THEN REWRITE_TAC[] THEN + ONCE_REWRITE_TAC[MESON[] `(if p then if q then x else y else y) = + (if q then if p then x else y else y)`] THEN + ASM_SIMP_TAC[]);; + +let INTEGRAL_RESTRICT = prove + (`!f:real^M->real^N s t. + s SUBSET t + ==> integral t (\x. if x IN s then f x else vec 0) = + integral s f`, + SIMP_TAC[integral; HAS_INTEGRAL_RESTRICT]);; + +let INTEGRABLE_RESTRICT = prove + (`!f:real^M->real^N s t. + s SUBSET t + ==> ((\x. if x IN s then f x else vec 0) integrable_on t <=> + f integrable_on s)`, + SIMP_TAC[integrable_on; HAS_INTEGRAL_RESTRICT]);; + +let HAS_INTEGRAL_RESTRICT_UNIV = prove + (`!f:real^M->real^N s i. + ((\x. if x IN s then f x else vec 0) has_integral i) (:real^M) <=> + (f has_integral i) s`, + SIMP_TAC[HAS_INTEGRAL_RESTRICT; SUBSET_UNIV]);; + +let INTEGRAL_RESTRICT_UNIV = prove + (`!f:real^M->real^N s. + integral (:real^M) (\x. if x IN s then f x else vec 0) = + integral s f`, + REWRITE_TAC[integral; HAS_INTEGRAL_RESTRICT_UNIV]);; + +let INTEGRABLE_RESTRICT_UNIV = prove + (`!f s. (\x. if x IN s then f x else vec 0) integrable_on (:real^M) <=> + f integrable_on s`, + REWRITE_TAC[integrable_on; HAS_INTEGRAL_RESTRICT_UNIV]);; + +let HAS_INTEGRAL_RESTRICT_INTER = prove + (`!f:real^M->real^N s t. + ((\x. if x IN s then f x else vec 0) has_integral i) t <=> + (f has_integral i) (s INTER t)`, + REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[GSYM HAS_INTEGRAL_RESTRICT_UNIV] THEN + REWRITE_TAC[IN_INTER] THEN AP_THM_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN + REWRITE_TAC[FUN_EQ_THM] THEN MESON_TAC[]);; + +let INTEGRAL_RESTRICT_INTER = prove + (`!f:real^M->real^N s t. + integral t (\x. if x IN s then f x else vec 0) = + integral (s INTER t) f`, + REWRITE_TAC[integral; HAS_INTEGRAL_RESTRICT_INTER]);; + +let INTEGRABLE_RESTRICT_INTER = prove + (`!f:real^M->real^N s t. + (\x. if x IN s then f x else vec 0) integrable_on t <=> + f integrable_on (s INTER t)`, + REWRITE_TAC[integrable_on; HAS_INTEGRAL_RESTRICT_INTER]);; + +let HAS_INTEGRAL_ON_SUPERSET = prove + (`!f s t. + (!x. ~(x IN s) ==> f x = vec 0) /\ s SUBSET t /\ (f has_integral i) s + ==> (f has_integral i) t`, + REPEAT GEN_TAC THEN REWRITE_TAC[SUBSET] THEN + REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + ONCE_REWRITE_TAC[GSYM HAS_INTEGRAL_RESTRICT_UNIV] THEN + MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_THM_TAC THEN + AP_TERM_TAC THEN ABS_TAC THEN ASM_MESON_TAC[]);; + +let INTEGRABLE_ON_SUPERSET = prove + (`!f s t. + (!x. ~(x IN s) ==> f x = vec 0) /\ s SUBSET t /\ f integrable_on s + ==> f integrable_on t`, + REWRITE_TAC[integrable_on] THEN MESON_TAC[HAS_INTEGRAL_ON_SUPERSET]);; + +let NEGLIGIBLE_ON_INTERVALS = prove + (`!s. negligible s <=> !a b:real^N. negligible(s INTER interval[a,b])`, + GEN_TAC THEN EQ_TAC THEN REPEAT STRIP_TAC THENL + [MATCH_MP_TAC NEGLIGIBLE_SUBSET THEN EXISTS_TAC `s:real^N->bool` THEN + ASM_REWRITE_TAC[] THEN SET_TAC[]; + ALL_TAC] THEN + REWRITE_TAC[negligible] THEN + MAP_EVERY X_GEN_TAC [`a:real^N`; `b:real^N`] THEN + FIRST_ASSUM(ASSUME_TAC o SPECL [`a:real^N`; `b:real^N`]) THEN + MATCH_MP_TAC HAS_INTEGRAL_NEGLIGIBLE THEN + EXISTS_TAC `s INTER interval[a:real^N,b]` THEN + ASM_REWRITE_TAC[] THEN SIMP_TAC[indicator; IN_DIFF; IN_INTER] THEN + MESON_TAC[]);; + +let HAS_INTEGRAL_SPIKE_SET_EQ = prove + (`!f:real^M->real^N s t y. + negligible(s DIFF t UNION t DIFF s) + ==> ((f has_integral y) s <=> (f has_integral y) t)`, + REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[GSYM HAS_INTEGRAL_RESTRICT_UNIV] THEN + MATCH_MP_TAC HAS_INTEGRAL_SPIKE_EQ THEN + EXISTS_TAC `s DIFF t UNION t DIFF s:real^M->bool` THEN + ASM_REWRITE_TAC[] THEN SET_TAC[]);; + +let HAS_INTEGRAL_SPIKE_SET = prove + (`!f:real^M->real^N s t y. + negligible(s DIFF t UNION t DIFF s) /\ + (f has_integral y) s + ==> (f has_integral y) t`, + MESON_TAC[HAS_INTEGRAL_SPIKE_SET_EQ]);; + +let INTEGRABLE_SPIKE_SET = prove + (`!f:real^M->real^N s t. + negligible(s DIFF t UNION t DIFF s) + ==> f integrable_on s ==> f integrable_on t`, + REWRITE_TAC[integrable_on] THEN MESON_TAC[HAS_INTEGRAL_SPIKE_SET_EQ]);; + +let INTEGRABLE_SPIKE_SET_EQ = prove + (`!f:real^M->real^N s t. + negligible(s DIFF t UNION t DIFF s) + ==> (f integrable_on s <=> f integrable_on t)`, + MESON_TAC[INTEGRABLE_SPIKE_SET; UNION_COMM]);; + +let INTEGRAL_SPIKE_SET = prove + (`!f:real^M->real^N g s t. + negligible(s DIFF t UNION t DIFF s) + ==> integral s f = integral t f`, + REPEAT STRIP_TAC THEN REWRITE_TAC[integral] THEN + AP_TERM_TAC THEN ABS_TAC THEN MATCH_MP_TAC HAS_INTEGRAL_SPIKE_SET_EQ THEN + ASM_MESON_TAC[]);; + +let HAS_INTEGRAL_INTERIOR = prove + (`!f:real^M->real^N y s. + negligible(frontier s) + ==> ((f has_integral y) (interior s) <=> (f has_integral y) s)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_INTEGRAL_SPIKE_SET_EQ THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + NEGLIGIBLE_SUBSET)) THEN + REWRITE_TAC[frontier] THEN + MP_TAC(ISPEC `s:real^M->bool` INTERIOR_SUBSET) THEN + MP_TAC(ISPEC `s:real^M->bool` CLOSURE_SUBSET) THEN + SET_TAC[]);; + +let HAS_INTEGRAL_CLOSURE = prove + (`!f:real^M->real^N y s. + negligible(frontier s) + ==> ((f has_integral y) (closure s) <=> (f has_integral y) s)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_INTEGRAL_SPIKE_SET_EQ THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + NEGLIGIBLE_SUBSET)) THEN + REWRITE_TAC[frontier] THEN + MP_TAC(ISPEC `s:real^M->bool` INTERIOR_SUBSET) THEN + MP_TAC(ISPEC `s:real^M->bool` CLOSURE_SUBSET) THEN + SET_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* More lemmas that are useful later. *) +(* ------------------------------------------------------------------------- *) + +let HAS_INTEGRAL_SUBSET_COMPONENT_LE = prove + (`!f:real^M->real^N s t i j k. + s SUBSET t /\ (f has_integral i) s /\ (f has_integral j) t /\ + 1 <= k /\ k <= dimindex(:N) /\ + (!x. x IN t ==> &0 <= f(x)$k) + ==> i$k <= j$k`, + REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[GSYM HAS_INTEGRAL_RESTRICT_UNIV] THEN + STRIP_TAC THEN MATCH_MP_TAC HAS_INTEGRAL_COMPONENT_LE THEN + MAP_EVERY EXISTS_TAC + [`(\x. if x IN s then f x else vec 0):real^M->real^N`; + `(\x. if x IN t then f x else vec 0):real^M->real^N`; + `(:real^M)`] THEN + ASM_REWRITE_TAC[] THEN + REPEAT STRIP_TAC THEN + REPEAT(COND_CASES_TAC THEN ASM_REWRITE_TAC[REAL_LE_REFL]) THEN + ASM_SIMP_TAC[VEC_COMPONENT] THEN ASM SET_TAC[]);; + +let INTEGRAL_SUBSET_COMPONENT_LE = prove + (`!f:real^M->real^N s t k. + s SUBSET t /\ f integrable_on s /\ f integrable_on t /\ + 1 <= k /\ k <= dimindex(:N) /\ + (!x. x IN t ==> &0 <= f(x)$k) + ==> (integral s f)$k <= (integral t f)$k`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_INTEGRAL_SUBSET_COMPONENT_LE THEN + ASM_MESON_TAC[INTEGRABLE_INTEGRAL]);; + +let HAS_INTEGRAL_SUBSET_DROP_LE = prove + (`!f:real^M->real^1 s t i j. + s SUBSET t /\ (f has_integral i) s /\ (f has_integral j) t /\ + (!x. x IN t ==> &0 <= drop(f x)) + ==> drop i <= drop j`, + REWRITE_TAC[drop] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC HAS_INTEGRAL_SUBSET_COMPONENT_LE THEN + REWRITE_TAC[DIMINDEX_1; LE_REFL] THEN ASM_MESON_TAC[]);; + +let INTEGRAL_SUBSET_DROP_LE = prove + (`!f:real^M->real^1 s t. + s SUBSET t /\ f integrable_on s /\ f integrable_on t /\ + (!x. x IN t ==> &0 <= drop(f(x))) + ==> drop(integral s f) <= drop(integral t f)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_INTEGRAL_SUBSET_DROP_LE THEN + ASM_MESON_TAC[INTEGRABLE_INTEGRAL]);; + +let HAS_INTEGRAL_ALT = prove + (`!f:real^M->real^N s i. + (f has_integral i) 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. ball (vec 0,B) SUBSET interval[a,b] + ==> norm(integral(interval[a,b]) + (\x. if x IN s then f x else vec 0) - + i) < e)`, + REPEAT GEN_TAC THEN GEN_REWRITE_TAC LAND_CONV [HAS_INTEGRAL] THEN + SPEC_TAC(`\x. if x IN s then (f:real^M->real^N) x else vec 0`, + `f:real^M->real^N`) THEN + GEN_TAC THEN EQ_TAC THENL + [ALL_TAC; MESON_TAC[INTEGRAL_UNIQUE; integrable_on]] THEN + DISCH_TAC THEN CONJ_TAC THENL + [ALL_TAC; ASM_MESON_TAC[INTEGRAL_UNIQUE]] THEN + MAP_EVERY X_GEN_TAC [`a:real^M`; `b:real^M`] THEN + POP_ASSUM(MP_TAC o C MATCH_MP REAL_LT_01) THEN + DISCH_THEN(X_CHOOSE_THEN `B:real` STRIP_ASSUME_TAC) THEN + MATCH_MP_TAC INTEGRABLE_SUBINTERVAL THEN + EXISTS_TAC `(lambda i. min ((a:real^M)$i) (--B)):real^M` THEN + EXISTS_TAC `(lambda i. max ((b:real^M)$i) B):real^M` THEN CONJ_TAC THENL + [FIRST_X_ASSUM(MP_TAC o SPECL + [`(lambda i. min ((a:real^M)$i) (--B)):real^M`; + `(lambda i. max ((b:real^M)$i) B):real^M`]) THEN + ANTS_TAC THENL [ALL_TAC; MESON_TAC[integrable_on]]; + SIMP_TAC[SUBSET; IN_INTERVAL; IN_BALL; LAMBDA_BETA; + REAL_MIN_LE; REAL_LE_MAX]] THEN + SIMP_TAC[SUBSET; IN_BALL; IN_INTERVAL; LAMBDA_BETA] THEN + GEN_TAC THEN REWRITE_TAC[NORM_ARITH `dist(vec 0,x) = norm x`] THEN + DISCH_TAC THEN X_GEN_TAC `k:num` THEN STRIP_TAC THEN + MATCH_MP_TAC(REAL_ARITH + `abs(x) <= B ==> min a (--B) <= x /\ x <= max b B`) THEN + MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC `norm(x:real^M)` THEN + ASM_SIMP_TAC[REAL_LT_IMP_LE; COMPONENT_LE_NORM]);; + +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 INTEGRABLE_ON_SUBINTERVAL = prove + (`!f:real^M->real^N s a b. + f integrable_on s /\ interval[a,b] SUBSET s + ==> f integrable_on interval[a,b]`, + REPEAT GEN_TAC THEN + GEN_REWRITE_TAC (LAND_CONV o LAND_CONV) [INTEGRABLE_ALT] THEN + DISCH_THEN(CONJUNCTS_THEN2 (MP_TAC o CONJUNCT1) ASSUME_TAC) THEN + DISCH_THEN(MP_TAC o SPECL [`a:real^M`; `b:real^M`]) THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] INTEGRABLE_EQ) THEN + ASM SET_TAC[]);; + +let INTEGRAL_SPLIT = prove + (`!f:real^M->real^N a b t k. + f integrable_on interval[a,b] /\ 1 <= k /\ k <= dimindex(:M) + ==> integral (interval[a,b]) f = + integral(interval + [a,(lambda i. if i = k then min (b$k) t else b$i)]) f + + integral(interval + [(lambda i. if i = k then max (a$k) t else a$i),b]) f`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC INTEGRAL_UNIQUE THEN + MATCH_MP_TAC HAS_INTEGRAL_SPLIT THEN + MAP_EVERY EXISTS_TAC [`k:num`; `t:real`] THEN + ASM_SIMP_TAC[INTERVAL_SPLIT; GSYM HAS_INTEGRAL_INTEGRAL] THEN + CONJ_TAC THEN MATCH_MP_TAC INTEGRABLE_ON_SUBINTERVAL THEN + EXISTS_TAC `interval[a:real^M,b]` 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);; + +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 INTEGRAL_INTERVALS_DIFF_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 - integral(interval[a,c]) f = + vsum {s | ~(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)`, + REPEAT GEN_TAC THEN DISCH_TAC THEN + FIRST_ASSUM(SUBST1_TAC o + MATCH_MP INTEGRAL_INTERVALS_INCLUSION_EXCLUSION) THEN + REWRITE_TAC[SET_RULE `{s | ~(s = a) /\ P s} = {s | P s} DELETE a`] THEN + SIMP_TAC[VSUM_DELETE; FINITE_POWERSET; FINITE_NUMSEG; EMPTY_SUBSET; + IN_ELIM_THM] THEN + REWRITE_TAC[NOT_IN_EMPTY; EMPTY_GSPEC; CARD_CLAUSES; LAMBDA_ETA] THEN + REWRITE_TAC[real_pow; VECTOR_MUL_LID]);; + +let INTEGRAL_INTERVALS_INCLUSION_EXCLUSION_RIGHT = prove + (`!f:real^M->real^N a b c. + f integrable_on interval[a,b] /\ c IN interval[a,b] + ==> integral(interval[a,c]) f = + vsum {s | s SUBSET 1..dimindex (:M)} + (\s. --(&1) pow CARD s % + integral + (interval[(lambda i. if i IN s then c$i else a$i), + b]) + f)`, + REPEAT STRIP_TAC THEN MP_TAC(ISPECL + [`f:real^M->real^N`; `a:real^M`; `b:real^M`; `b:real^M`; `c:real^M`] + INTEGRAL_INTERVALS_INCLUSION_EXCLUSION) THEN + ASM_REWRITE_TAC[ENDS_IN_INTERVAL] THEN ANTS_TAC THENL + [ASM_MESON_TAC[ENDS_IN_INTERVAL; MEMBER_NOT_EMPTY]; ALL_TAC] THEN + DISCH_THEN SUBST1_TAC THEN MATCH_MP_TAC VSUM_EQ THEN + X_GEN_TAC `s:num->bool` THEN REWRITE_TAC[IN_ELIM_THM] THEN STRIP_TAC THEN + ASM_CASES_TAC `?k. k IN s /\ (c:real^M)$k = (b:real^M)$k` THENL + [FIRST_X_ASSUM(X_CHOOSE_THEN `k:num` STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN `1 <= k /\ k <= dimindex(:M)` STRIP_ASSUME_TAC THENL + [ASM_MESON_TAC[IN_NUMSEG; SUBSET]; ALL_TAC] THEN + MATCH_MP_TAC(MESON[] `a:real^N = vec 0 /\ b = vec 0 ==> a = b`) THEN + CONJ_TAC THEN REWRITE_TAC[VECTOR_MUL_EQ_0] THEN DISJ2_TAC THEN + MATCH_MP_TAC INTEGRAL_NULL THEN REWRITE_TAC[CONTENT_EQ_0] THEN + EXISTS_TAC `k:num` THEN ASM_SIMP_TAC[LAMBDA_BETA] THEN REAL_ARITH_TAC; + ALL_TAC] THEN + RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL]) THEN BINOP_TAC THENL + [AP_TERM_TAC THEN AP_TERM_TAC THEN REWRITE_TAC[EXTENSION; IN_ELIM_THM] THEN + ASM_MESON_TAC[REAL_LT_LE; SUBSET; IN_NUMSEG]; + AP_THM_TAC THEN AP_TERM_TAC THEN AP_TERM_TAC THEN + AP_THM_TAC THEN AP_TERM_TAC THEN + ASM_SIMP_TAC[CART_EQ; PAIR_EQ; LAMBDA_BETA] THEN + CONJ_TAC THEN X_GEN_TAC `i:num` THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `i:num`) THEN ASM_REWRITE_TAC[] THEN + REAL_ARITH_TAC]);; + +let INTEGRAL_INTERVALS_INCLUSION_EXCLUSION_LEFT = prove + (`!f:real^M->real^N a b c. + f integrable_on interval[a,b] /\ c IN interval[a,b] + ==> integral(interval[c,b]) f = + vsum {s | s SUBSET 1..dimindex (:M)} + (\s. --(&1) pow CARD s % + integral + (interval[a,(lambda i. if i IN s then c$i else b$i)]) + f)`, + REPEAT STRIP_TAC THEN MP_TAC(ISPECL + [`\x. (f:real^M->real^N) (--x)`; + `--b:real^M`; + `--a:real^M`; + `--c:real^M`] + INTEGRAL_INTERVALS_INCLUSION_EXCLUSION_RIGHT) THEN + REWRITE_TAC[REAL_ARITH `min (--a) (--b) = --(max a b)`; + REAL_ARITH `max (--a) (--b) = --(min a b)`; + VECTOR_NEG_COMPONENT] THEN + SUBGOAL_THEN + `!P x y. (lambda i. if P i then --(x i) else --(y i)):real^M = + --(lambda i. if P i then x i else y i)` + (fun th -> REWRITE_TAC[th]) + THENL + [SIMP_TAC[CART_EQ; VECTOR_NEG_COMPONENT; LAMBDA_BETA] THEN MESON_TAC[]; + ALL_TAC] THEN + ASM_REWRITE_TAC[INTEGRAL_REFLECT; INTEGRABLE_REFLECT; + IN_INTERVAL_REFLECT]);; + +(* ------------------------------------------------------------------------- *) +(* A straddling criterion for integrability. *) +(* ------------------------------------------------------------------------- *) + +let INTEGRABLE_STRADDLE_INTERVAL = prove + (`!f:real^N->real^1 a b. + (!e. &0 < e + ==> ?g h i j. (g has_integral i) (interval[a,b]) /\ + (h has_integral j) (interval[a,b]) /\ + norm(i - j) < e /\ + !x. x IN interval[a,b] + ==> drop(g x) <= drop(f x) /\ + drop(f x) <= drop(h x)) + ==> f integrable_on interval[a,b]`, + REPEAT STRIP_TAC THEN REWRITE_TAC[INTEGRABLE_CAUCHY] THEN + X_GEN_TAC `e:real` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `e / &3`) THEN + ASM_SIMP_TAC[REAL_LT_DIV; REAL_OF_NUM_LT; ARITH; 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[has_integral] THEN REWRITE_TAC[IMP_CONJ] THEN + DISCH_THEN(MP_TAC o SPEC `e / &3`) THEN + ASM_SIMP_TAC[REAL_LT_DIV; REAL_OF_NUM_LT; ARITH] THEN + DISCH_THEN(X_CHOOSE_THEN `d1:real^N->real^N->bool` STRIP_ASSUME_TAC) THEN + DISCH_THEN(MP_TAC o SPEC `e / &3`) THEN + ASM_SIMP_TAC[REAL_LT_DIV; REAL_OF_NUM_LT; ARITH] THEN + DISCH_THEN(X_CHOOSE_THEN `d2:real^N->real^N->bool` STRIP_ASSUME_TAC) THEN + DISCH_TAC THEN DISCH_TAC THEN + EXISTS_TAC `(\x. d1 x INTER d2 x):real^N->real^N->bool` THEN + ASM_SIMP_TAC[GAUGE_INTER; FINE_INTER] THEN + MAP_EVERY X_GEN_TAC + [`p1:(real^N#(real^N->bool))->bool`; + `p2:(real^N#(real^N->bool))->bool`] THEN + REPEAT STRIP_TAC THEN + REPEAT(FIRST_X_ASSUM(fun th -> + MP_TAC(SPEC `p1:(real^N#(real^N->bool))->bool` th) THEN + MP_TAC(SPEC `p2:(real^N#(real^N->bool))->bool` th))) THEN + EVERY_ASSUM(fun th -> try ASSUME_TAC(MATCH_MP TAGGED_DIVISION_OF_FINITE th) + with Failure _ -> ALL_TAC) THEN + ASM_SIMP_TAC[VSUM_REAL] THEN REWRITE_TAC[o_DEF; LAMBDA_PAIR_THM] THEN + SUBST1_TAC(SYM(ISPEC `i:real^1` (CONJUNCT1 LIFT_DROP))) THEN + SUBST1_TAC(SYM(ISPEC `j:real^1` (CONJUNCT1 LIFT_DROP))) THEN + REWRITE_TAC[GSYM LIFT_SUB; DROP_CMUL; NORM_LIFT] THEN + MATCH_MP_TAC(REAL_ARITH + `g1 - h2 <= f1 - f2 /\ f1 - f2 <= h1 - g2 /\ + abs(i - j) < e / &3 + ==> abs(g2 - i) < e / &3 + ==> abs(g1 - i) < e / &3 + ==> abs(h2 - j) < e / &3 + ==> abs(h1 - j) < e / &3 + ==> abs(f1 - f2) < e`) THEN + ASM_REWRITE_TAC[GSYM DROP_SUB; GSYM NORM_LIFT; LIFT_DROP] THEN CONJ_TAC THEN + MATCH_MP_TAC(REAL_ARITH `x <= x' /\ y' <= y ==> x - y <= x' - y'`) THEN + CONJ_TAC THEN MATCH_MP_TAC SUM_LE THEN + REWRITE_TAC[FORALL_PAIR_THM] THEN REPEAT STRIP_TAC THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC REAL_LE_LMUL THEN + ASM_MESON_TAC[TAGGED_DIVISION_OF; CONTENT_POS_LE; SUBSET]);; + +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"; "d"] THEN + SIMP_TAC[SUBSET; IN_BALL; IN_INTERVAL; LAMBDA_BETA] THEN + GEN_TAC THEN REWRITE_TAC[NORM_ARITH `dist(vec 0,x) = norm x`] THEN + DISCH_TAC THEN X_GEN_TAC `k:num` THEN STRIP_TAC THEN + MATCH_MP_TAC(REAL_ARITH + `abs(x) <= B ==> min a (--B) <= x /\ x <= max b B`) THEN + MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC `norm(x:real^N)` THEN + ASM_SIMP_TAC[REAL_LT_IMP_LE; COMPONENT_LE_NORM; REAL_LE_MAX]; + ALL_TAC] THEN + MATCH_MP_TAC(NORM_ARITH + `norm(i - j) < e / &4 /\ + norm(ah - ag) <= norm(ch - cg) + ==> norm(cg - i) < e / &4 /\ + norm(ch - j) < e / &4 + ==> norm(ag - ah) < e`) THEN + ASM_REWRITE_TAC[] THEN ASM_SIMP_TAC[GSYM INTEGRAL_SUB] THEN + MATCH_MP_TAC lemma THEN CONJ_TAC THENL + [MATCH_MP_TAC(INST_TYPE [`:N`,`:M`] HAS_INTEGRAL_DROP_POS) THEN + MAP_EVERY EXISTS_TAC + [`(\x. (if x IN s then h x else vec 0) - (if x IN s then g x else vec 0)) + :real^N->real^1`; + `interval[a:real^N,b]`] THEN + ASM_SIMP_TAC[INTEGRABLE_INTEGRAL; HAS_INTEGRAL_SUB] THEN + ASM_SIMP_TAC[INTEGRABLE_SUB; INTEGRABLE_INTEGRAL] THEN + REPEAT STRIP_TAC THEN COND_CASES_TAC THEN + ASM_SIMP_TAC[DROP_SUB; DROP_VEC; REAL_SUB_LE; REAL_POS] THEN + ASM_MESON_TAC[REAL_LE_TRANS]; + ALL_TAC] THEN + MATCH_MP_TAC(INST_TYPE [`:N`,`:M`] HAS_INTEGRAL_SUBSET_DROP_LE) THEN + MAP_EVERY EXISTS_TAC + [`(\x. (if x IN s then h x else vec 0) - (if x IN s then g x else vec 0)) + :real^N->real^1`; + `interval[a:real^N,b]`; `interval[c:real^N,d]`] THEN + ASM_SIMP_TAC[INTEGRABLE_SUB; INTEGRABLE_INTEGRAL] THEN CONJ_TAC THENL + [REWRITE_TAC[SUBSET_INTERVAL] THEN DISCH_TAC THEN + MAP_EVERY EXPAND_TAC ["c"; "d"] THEN + SIMP_TAC[LAMBDA_BETA] THEN REAL_ARITH_TAC; + ALL_TAC] THEN + REPEAT STRIP_TAC THEN COND_CASES_TAC THEN + ASM_SIMP_TAC[DROP_SUB; DROP_VEC; REAL_SUB_LE; REAL_POS] THEN + ASM_MESON_TAC[REAL_LE_TRANS]; + ALL_TAC] THEN + ONCE_REWRITE_TAC[INTEGRABLE_ALT] THEN ASM_REWRITE_TAC[] THEN + X_GEN_TAC `e:real` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `e / &3`) THEN + ASM_SIMP_TAC[REAL_LT_DIV; REAL_OF_NUM_LT; ARITH] THEN + ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM; HAS_INTEGRAL_ALT] THEN + MAP_EVERY X_GEN_TAC + [`g:real^N->real^1`; `h:real^N->real^1`; `i:real^1`; `j:real^1`] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + DISCH_THEN(CONJUNCTS_THEN2 MP_TAC STRIP_ASSUME_TAC) THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC (MP_TAC o SPEC `e / &3`)) THEN + FIRST_X_ASSUM(CONJUNCTS_THEN2 ASSUME_TAC (MP_TAC o SPEC `e / &3`)) THEN + ASM_SIMP_TAC[REAL_LT_DIV; REAL_OF_NUM_LT; ARITH] THEN + DISCH_THEN(X_CHOOSE_THEN `B1:real` + (CONJUNCTS_THEN2 ASSUME_TAC (LABEL_TAC "G"))) THEN + DISCH_THEN(X_CHOOSE_THEN `B2:real` + (CONJUNCTS_THEN2 ASSUME_TAC (LABEL_TAC "H"))) THEN + EXISTS_TAC `max B1 B2` THEN + ASM_REWRITE_TAC[REAL_LT_MAX; BALL_MAX_UNION; UNION_SUBSET] THEN + MAP_EVERY X_GEN_TAC [`a:real^N`; `b:real^N`; `c:real^N`; `d:real^N`] THEN + STRIP_TAC THEN REWRITE_TAC[ABS_DROP; DROP_SUB] THEN + MATCH_MP_TAC(REAL_ARITH + `!ga gc ha hc i j. + ga <= fa /\ fa <= ha /\ + gc <= fc /\ fc <= hc /\ + abs(ga - i) < e / &3 /\ + abs(gc - i) < e / &3 /\ + abs(ha - j) < e / &3 /\ + abs(hc - j) < e / &3 /\ + abs(i - j) < e / &3 + ==> abs(fa - fc) < e`) THEN + MAP_EVERY EXISTS_TAC + [`drop(integral(interval[a:real^N,b]) (\x. if x IN s then g x else vec 0))`; + `drop(integral(interval[c:real^N,d]) (\x. if x IN s then g x else vec 0))`; + `drop(integral(interval[a:real^N,b]) (\x. if x IN s then h x else vec 0))`; + `drop(integral(interval[c:real^N,d]) (\x. if x IN s then h x else vec 0))`; + `drop i`; `drop j`] THEN + REWRITE_TAC[GSYM DROP_SUB; GSYM ABS_DROP] THEN ASM_SIMP_TAC[] THEN + REPEAT CONJ_TAC THEN MATCH_MP_TAC INTEGRAL_DROP_LE THEN + ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN + COND_CASES_TAC THEN ASM_SIMP_TAC[REAL_LE_REFL]);; + +let HAS_INTEGRAL_STRADDLE_NULL = prove + (`!f g:real^N->real^1 s. + (!x. x IN s ==> &0 <= drop(f x) /\ drop(f x) <= drop(g x)) /\ + (g has_integral (vec 0)) s + ==> (f has_integral (vec 0)) s`, + REPEAT STRIP_TAC THEN REWRITE_TAC[HAS_INTEGRAL_INTEGRABLE_INTEGRAL] THEN + MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN CONJ_TAC THENL + [MATCH_MP_TAC INTEGRABLE_STRADDLE THEN + GEN_TAC THEN DISCH_TAC THEN + MAP_EVERY EXISTS_TAC + [`(\x. vec 0):real^N->real^1`; `g:real^N->real^1`; + `vec 0:real^1`; `vec 0:real^1`] THEN + ASM_REWRITE_TAC[DROP_VEC; HAS_INTEGRAL_0; VECTOR_SUB_REFL; NORM_0]; + DISCH_TAC THEN ONCE_REWRITE_TAC[GSYM DROP_EQ] THEN + REWRITE_TAC[GSYM REAL_LE_ANTISYM] THEN CONJ_TAC THENL + [MATCH_MP_TAC(ISPECL [`f:real^N->real^1`; `g:real^N->real^1`] + HAS_INTEGRAL_DROP_LE); + MATCH_MP_TAC(ISPECL [`(\x. vec 0):real^N->real^1`; `f:real^N->real^1`] + HAS_INTEGRAL_DROP_LE)] THEN + EXISTS_TAC `s:real^N->bool` THEN + ASM_SIMP_TAC[GSYM HAS_INTEGRAL_INTEGRAL; DROP_VEC; HAS_INTEGRAL_0]]);; + +(* ------------------------------------------------------------------------- *) +(* Adding integrals over several sets. *) +(* ------------------------------------------------------------------------- *) + +let HAS_INTEGRAL_UNION = prove + (`!f:real^M->real^N i j s t. + (f has_integral i) s /\ (f has_integral j) t /\ negligible(s INTER t) + ==> (f has_integral (i + j)) (s UNION t)`, + REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[GSYM HAS_INTEGRAL_RESTRICT_UNIV] THEN + REWRITE_TAC[CONJ_ASSOC] THEN DISCH_THEN(CONJUNCTS_THEN ASSUME_TAC) THEN + MATCH_MP_TAC HAS_INTEGRAL_SPIKE THEN + EXISTS_TAC `(\x. if x IN (s INTER t) then &2 % f(x) + else if x IN (s UNION t) then f(x) + else vec 0):real^M->real^N` THEN + EXISTS_TAC `s INTER t:real^M->bool` THEN + ASM_REWRITE_TAC[IN_DIFF; IN_UNION; IN_INTER; IN_UNIV] THEN + CONJ_TAC THENL [MESON_TAC[]; ALL_TAC] THEN + FIRST_X_ASSUM(MP_TAC o MATCH_MP HAS_INTEGRAL_ADD) THEN + MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN + REWRITE_TAC[FUN_EQ_THM] THEN GEN_TAC THEN + MAP_EVERY ASM_CASES_TAC [`(x:real^M) IN s`; `(x:real^M) IN t`] THEN + ASM_REWRITE_TAC[] THEN VECTOR_ARITH_TAC);; + +let INTEGRAL_UNION = prove + (`!f:real^M->real^N s t. + f integrable_on s /\ f integrable_on t /\ negligible(s INTER t) + ==> integral (s UNION t) f = integral s f + integral t f`, + REPEAT STRIP_TAC THEN + MATCH_MP_TAC INTEGRAL_UNIQUE THEN + MATCH_MP_TAC HAS_INTEGRAL_UNION THEN + ASM_REWRITE_TAC[GSYM HAS_INTEGRAL_INTEGRAL]);; + +let HAS_INTEGRAL_UNIONS = prove + (`!f:real^M->real^N i t. + FINITE t /\ + (!s. s IN t ==> (f has_integral (i s)) s) /\ + (!s s'. s IN t /\ s' IN t /\ ~(s = s') ==> negligible(s INTER s')) + ==> (f has_integral (vsum t i)) (UNIONS t)`, + REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[GSYM HAS_INTEGRAL_RESTRICT_UNIV] THEN + REWRITE_TAC[CONJ_ASSOC] THEN DISCH_THEN(CONJUNCTS_THEN ASSUME_TAC) THEN + FIRST_ASSUM(MP_TAC o MATCH_MP HAS_INTEGRAL_VSUM) THEN REWRITE_TAC[] THEN + MATCH_MP_TAC(REWRITE_RULE[TAUT `a /\ b /\ c ==> d <=> a /\ b ==> c ==> d`] + HAS_INTEGRAL_SPIKE) THEN + EXISTS_TAC + `UNIONS (IMAGE (\(a,b). a INTER b :real^M->bool) + {a,b | a IN t /\ b IN {y | y IN t /\ ~(a = y)}})` THEN + CONJ_TAC THENL + [MATCH_MP_TAC NEGLIGIBLE_UNIONS THEN CONJ_TAC THENL + [MATCH_MP_TAC FINITE_IMAGE THEN MATCH_MP_TAC FINITE_PRODUCT_DEPENDENT THEN + ASM_SIMP_TAC[FINITE_RESTRICT]; + REWRITE_TAC[FORALL_IN_IMAGE; FORALL_PAIR_THM; IN_ELIM_PAIR_THM] THEN + ASM_SIMP_TAC[IN_ELIM_THM]]; + X_GEN_TAC `x:real^M` THEN REWRITE_TAC[IN_UNIV; IN_DIFF] THEN + ASM_CASES_TAC `(x:real^M) IN UNIONS t` THEN ASM_REWRITE_TAC[] THENL + [ALL_TAC; + RULE_ASSUM_TAC(REWRITE_RULE[SET_RULE + `~(x IN UNIONS t) <=> !s. s IN t ==> ~(x IN s)`]) THEN + ASM_SIMP_TAC[VSUM_0]] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_UNIONS]) THEN + DISCH_THEN(X_CHOOSE_THEN `a:real^M->bool` STRIP_ASSUME_TAC) THEN + REWRITE_TAC[IN_UNIONS; EXISTS_IN_IMAGE; EXISTS_PAIR_THM] THEN + REWRITE_TAC[IN_ELIM_PAIR_THM; NOT_EXISTS_THM] THEN + DISCH_THEN(MP_TAC o SPEC `a:real^M->bool`) THEN + ASM_REWRITE_TAC[IN_ELIM_THM; IN_INTER] THEN + ASM_SIMP_TAC[MESON[] + `x IN a /\ a IN t + ==> ((!b. ~((b IN t /\ ~(a = b)) /\ x IN b)) <=> + (!b. b IN t ==> (x IN b <=> b = a)))`] THEN + ASM_REWRITE_TAC[VSUM_DELTA]]);; + +let HAS_INTEGRAL_DIFF = prove + (`!f:real^M->real^N i j s t. + (f has_integral i) s /\ + (f has_integral j) t /\ + negligible (t DIFF s) + ==> (f has_integral (i - j)) (s DIFF t)`, + REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[GSYM HAS_INTEGRAL_RESTRICT_UNIV] THEN + REWRITE_TAC[CONJ_ASSOC] THEN DISCH_THEN(CONJUNCTS_THEN ASSUME_TAC) THEN + MATCH_MP_TAC HAS_INTEGRAL_SPIKE THEN + EXISTS_TAC `(\x. if x IN (t DIFF s) then --(f x) + else if x IN (s DIFF t) then f x + else vec 0):real^M->real^N` THEN + EXISTS_TAC `t DIFF s:real^M->bool` THEN + ASM_REWRITE_TAC[IN_DIFF; IN_UNION; IN_INTER; IN_UNIV] THEN + CONJ_TAC THENL [MESON_TAC[]; ALL_TAC] THEN + FIRST_X_ASSUM(MP_TAC o MATCH_MP HAS_INTEGRAL_SUB) THEN + MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN + REWRITE_TAC[FUN_EQ_THM] THEN GEN_TAC THEN + MAP_EVERY ASM_CASES_TAC [`(x:real^M) IN s`; `(x:real^M) IN t`] THEN + ASM_REWRITE_TAC[] THEN VECTOR_ARITH_TAC);; + +let INTEGRAL_DIFF = prove + (`!f:real^M->real^N s t. + f integrable_on s /\ f integrable_on t /\ negligible(t DIFF s) + ==> integral (s DIFF t) f = integral s f - integral t f`, + REPEAT STRIP_TAC THEN + MATCH_MP_TAC INTEGRAL_UNIQUE THEN + MATCH_MP_TAC HAS_INTEGRAL_DIFF THEN + ASM_REWRITE_TAC[GSYM HAS_INTEGRAL_INTEGRAL]);; + +(* ------------------------------------------------------------------------- *) +(* In particular adding integrals over a division, maybe not of an interval. *) +(* ------------------------------------------------------------------------- *) + +let HAS_INTEGRAL_COMBINE_DIVISION = prove + (`!f:real^M->real^N s d i. + d division_of s /\ + (!k. k IN d ==> (f has_integral (i k)) k) + ==> (f has_integral (vsum d i)) s`, + REPEAT STRIP_TAC THEN + FIRST_ASSUM(SUBST1_TAC o SYM o last o CONJUNCTS o + GEN_REWRITE_RULE I [division_of]) THEN + MATCH_MP_TAC HAS_INTEGRAL_UNIONS THEN ASM_REWRITE_TAC[] THEN + CONJ_TAC THENL [ASM_MESON_TAC[DIVISION_OF_FINITE]; ALL_TAC] THEN + MAP_EVERY X_GEN_TAC [`k1:real^M->bool`; `k2:real^M->bool`] THEN + STRIP_TAC THEN + SUBGOAL_THEN `?u v:real^M x y:real^M. + k1 = interval[u,v] /\ k2 = interval[x,y]` + (REPEAT_TCL CHOOSE_THEN (CONJUNCTS_THEN SUBST_ALL_TAC)) + THENL [ASM_MESON_TAC[division_of]; ALL_TAC] THEN + FIRST_ASSUM(MP_TAC o el 2 o CONJUNCTS o + GEN_REWRITE_RULE I [division_of]) THEN + DISCH_THEN(MP_TAC o SPECL + [`interval[u:real^M,v]`; `interval[x:real^M,y]`]) THEN + ASM_REWRITE_TAC[INTERIOR_CLOSED_INTERVAL] THEN DISCH_TAC THEN + MATCH_MP_TAC NEGLIGIBLE_SUBSET THEN + EXISTS_TAC `(interval[u,v:real^M] DIFF interval(u,v)) UNION + (interval[x,y] DIFF interval(x,y))` THEN + SIMP_TAC[NEGLIGIBLE_FRONTIER_INTERVAL; NEGLIGIBLE_UNION] THEN + ASM SET_TAC[]);; + +let INTEGRAL_COMBINE_DIVISION_BOTTOMUP = prove + (`!f:real^M->real^N d s. + d division_of s /\ (!k. k IN d ==> f integrable_on k) + ==> integral s f = vsum d (\i. integral i f)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC INTEGRAL_UNIQUE THEN + MATCH_MP_TAC HAS_INTEGRAL_COMBINE_DIVISION THEN + ASM_REWRITE_TAC[GSYM HAS_INTEGRAL_INTEGRAL]);; + +let HAS_INTEGRAL_COMBINE_DIVISION_TOPDOWN = prove + (`!f:real^M->real^N s d k. + f integrable_on s /\ d division_of k /\ k SUBSET s + ==> (f has_integral (vsum d (\i. integral i f))) k`, + REPEAT STRIP_TAC THEN + MATCH_MP_TAC HAS_INTEGRAL_COMBINE_DIVISION THEN + ASM_REWRITE_TAC[GSYM HAS_INTEGRAL_INTEGRAL] THEN + FIRST_ASSUM(fun th -> REWRITE_TAC[MATCH_MP FORALL_IN_DIVISION th]) THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC INTEGRABLE_ON_SUBINTERVAL THEN + EXISTS_TAC `s:real^M->bool` THEN ASM_REWRITE_TAC[] THEN + ASM_MESON_TAC[division_of; SUBSET_TRANS]);; + +let INTEGRAL_COMBINE_DIVISION_TOPDOWN = prove + (`!f:real^M->real^N d s. + f integrable_on s /\ d division_of s + ==> integral s f = vsum d (\i. integral i f)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC INTEGRAL_UNIQUE THEN + MATCH_MP_TAC HAS_INTEGRAL_COMBINE_DIVISION_TOPDOWN THEN + EXISTS_TAC `s:real^M->bool` THEN ASM_REWRITE_TAC[SUBSET_REFL]);; + +let INTEGRABLE_COMBINE_DIVISION = prove + (`!f d s. + d division_of s /\ (!i. i IN d ==> f integrable_on i) + ==> f integrable_on s`, + REWRITE_TAC[integrable_on] THEN MESON_TAC[HAS_INTEGRAL_COMBINE_DIVISION]);; + +let INTEGRABLE_ON_SUBDIVISION = prove + (`!f:real^M->real^N s d i. + d division_of i /\ + f integrable_on s /\ i SUBSET s + ==> f integrable_on i`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC INTEGRABLE_COMBINE_DIVISION THEN + EXISTS_TAC `d:(real^M->bool)->bool` THEN ASM_REWRITE_TAC[] THEN + FIRST_ASSUM(fun th -> REWRITE_TAC[MATCH_MP FORALL_IN_DIVISION th]) THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC INTEGRABLE_ON_SUBINTERVAL THEN + ASM_MESON_TAC[division_of; UNIONS_SUBSET]);; + +(* ------------------------------------------------------------------------- *) +(* Also tagged divisions. *) +(* ------------------------------------------------------------------------- *) + +let HAS_INTEGRAL_COMBINE_TAGGED_DIVISION = prove + (`!f:real^M->real^N s p i. + p tagged_division_of s /\ + (!x k. (x,k) IN p ==> (f has_integral (i k)) k) + ==> (f has_integral (vsum p (\(x,k). i k))) s`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN + `!x:real^M k:real^M->bool. + (x,k) IN p ==> ((f:real^M->real^N) has_integral integral k f) k` + ASSUME_TAC THENL + [ASM_MESON_TAC[HAS_INTEGRAL_INTEGRAL; integrable_on]; ALL_TAC] THEN + SUBGOAL_THEN + `((f:real^M->real^N) has_integral + (vsum (IMAGE SND (p:real^M#(real^M->bool)->bool)) + (\k. integral k f))) s` + MP_TAC THENL + [MATCH_MP_TAC HAS_INTEGRAL_COMBINE_DIVISION THEN + ASM_REWRITE_TAC[FORALL_IN_IMAGE; FORALL_PAIR_THM] THEN + ASM_SIMP_TAC[DIVISION_OF_TAGGED_DIVISION]; + ALL_TAC] THEN + MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN + AP_TERM_TAC THEN CONV_TAC SYM_CONV THEN + MATCH_MP_TAC EQ_TRANS THEN + EXISTS_TAC `vsum p (\(x:real^M,k:real^M->bool). integral k f:real^N)` THEN + CONJ_TAC THENL + [MATCH_MP_TAC VSUM_EQ THEN REWRITE_TAC[FORALL_PAIR_THM] THEN + ASM_MESON_TAC[HAS_INTEGRAL_UNIQUE]; + MATCH_MP_TAC VSUM_OVER_TAGGED_DIVISION_LEMMA THEN + EXISTS_TAC `s:real^M->bool` THEN ASM_SIMP_TAC[INTEGRAL_NULL]]);; + +let INTEGRAL_COMBINE_TAGGED_DIVISION_BOTTOMUP = prove + (`!f:real^M->real^N p a b. + p tagged_division_of interval[a,b] /\ + (!x k. (x,k) IN p ==> f integrable_on k) + ==> integral (interval[a,b]) f = vsum p (\(x,k). integral k f)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC INTEGRAL_UNIQUE THEN + MATCH_MP_TAC HAS_INTEGRAL_COMBINE_TAGGED_DIVISION THEN + ASM_REWRITE_TAC[GSYM HAS_INTEGRAL_INTEGRAL]);; + +let HAS_INTEGRAL_COMBINE_TAGGED_DIVISION_TOPDOWN = prove + (`!f:real^M->real^N a b p. + f integrable_on interval[a,b] /\ p tagged_division_of interval[a,b] + ==> (f has_integral (vsum p (\(x,k). integral k f))) (interval[a,b])`, + REPEAT STRIP_TAC THEN + MATCH_MP_TAC HAS_INTEGRAL_COMBINE_TAGGED_DIVISION THEN + ASM_REWRITE_TAC[GSYM HAS_INTEGRAL_INTEGRAL] THEN + ASM_MESON_TAC[INTEGRABLE_SUBINTERVAL; TAGGED_DIVISION_OF]);; + +let INTEGRAL_COMBINE_TAGGED_DIVISION_TOPDOWN = prove + (`!f:real^M->real^N a b p. + f integrable_on interval[a,b] /\ p tagged_division_of interval[a,b] + ==> integral (interval[a,b]) f = vsum p (\(x,k). integral k f)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC INTEGRAL_UNIQUE THEN + MATCH_MP_TAC HAS_INTEGRAL_COMBINE_TAGGED_DIVISION_TOPDOWN THEN + ASM_REWRITE_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* Henstock's lemma. *) +(* ------------------------------------------------------------------------- *) + +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 HENSTOCK_LEMMA_PART2 = 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 + ==> sum p (\(x,k). norm(content k % f x - + integral k f)) + <= &2 * &(dimindex(:N)) * e`, + REPEAT STRIP_TAC THEN REWRITE_TAC[LAMBDA_PAIR] THEN + MATCH_MP_TAC VSUM_NORM_ALLSUBSETS_BOUND THEN + REWRITE_TAC[LAMBDA_PAIR_THM] THEN + CONJ_TAC THENL [ASM_MESON_TAC[tagged_partial_division_of]; ALL_TAC] THEN + X_GEN_TAC `q:(real^M#(real^M->bool))->bool` THEN DISCH_TAC THEN + MATCH_MP_TAC(REWRITE_RULE[RIGHT_IMP_FORALL_THM; IMP_IMP] + HENSTOCK_LEMMA_PART1) THEN + MAP_EVERY EXISTS_TAC + [`a:real^M`; `b:real^M`; `d:real^M->real^M->bool`] THEN + ASM_REWRITE_TAC[] THEN + ASM_MESON_TAC[FINE_SUBSET; TAGGED_PARTIAL_DIVISION_SUBSET]);; + +let HENSTOCK_LEMMA = prove + (`!f:real^M->real^N a b. + f integrable_on interval[a,b] + ==> !e. &0 < e + ==> ?d. gauge d /\ + !p. p tagged_partial_division_of interval[a,b] /\ + d fine p + ==> sum p (\(x,k). norm(content k % f x - + integral k f)) < e`, + MP_TAC HENSTOCK_LEMMA_PART2 THEN + REPEAT(MATCH_MP_TAC MONO_FORALL THEN GEN_TAC) THEN + DISCH_THEN(fun th -> STRIP_TAC THEN X_GEN_TAC `e:real` THEN + STRIP_TAC THEN MP_TAC th) THEN + FIRST_ASSUM(MP_TAC o MATCH_MP INTEGRABLE_INTEGRAL) THEN + GEN_REWRITE_TAC LAND_CONV [has_integral] THEN + DISCH_THEN(MP_TAC o SPEC `e / (&2 * (&(dimindex(:N)) + &1))`) THEN + ASM_SIMP_TAC[REAL_LT_DIV; REAL_ARITH `&0 < &2 * (&n + &1)`] THEN + DISCH_THEN(X_CHOOSE_THEN `d:real^M->real^M->bool` STRIP_ASSUME_TAC) THEN + DISCH_THEN(MP_TAC o SPECL + [`d:real^M->real^M->bool`; `e / (&2 * (&(dimindex(:N)) + &1))`]) THEN + ASM_SIMP_TAC[REAL_LT_DIV; REAL_ARITH `&0 < &2 * (&n + &1)`] THEN + DISCH_THEN(fun th -> EXISTS_TAC `d:real^M->real^M->bool` THEN MP_TAC th) THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC MONO_FORALL THEN GEN_TAC THEN + MATCH_MP_TAC MONO_IMP THEN REWRITE_TAC[] THEN + MATCH_MP_TAC(REAL_ARITH `d < e ==> x <= d ==> x < e`) THEN + REWRITE_TAC[real_div; REAL_INV_MUL; REAL_INV_INV; REAL_MUL_ASSOC] THEN + SIMP_TAC[GSYM real_div; REAL_LT_LDIV_EQ; REAL_ARITH `&0 < &n + &1`] THEN + UNDISCH_TAC `&0 < e` THEN REAL_ARITH_TAC);; + +(* ------------------------------------------------------------------------- *) +(* Monotone convergence (bounded interval first). *) +(* ------------------------------------------------------------------------- *) + +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 MONOTONE_CONVERGENCE_INCREASING = prove + (`!f:num->real^N->real^1 g s. + (!k. (f k) integrable_on s) /\ + (!k x. x IN s ==> drop(f k x) <= drop(f (SUC k) x)) /\ + (!x. x IN s ==> ((\k. f k x) --> g x) sequentially) /\ + bounded {integral s (f k) | k IN (:num)} + ==> g integrable_on s /\ + ((\k. integral s (f k)) --> integral s g) sequentially`, + SUBGOAL_THEN + `!f:num->real^N->real^1 g s. + (!k x. x IN s ==> &0 <= drop(f k x)) /\ + (!k. (f k) integrable_on s) /\ + (!k x. x IN s ==> drop(f k x) <= drop(f (SUC k) x)) /\ + (!x. x IN s ==> ((\k. f k x) --> g x) sequentially) /\ + bounded {integral s (f k) | k IN (:num)} + ==> g integrable_on s /\ + ((\k. integral s (f k)) --> integral s g) sequentially` + ASSUME_TAC THENL + [ALL_TAC; + REPEAT GEN_TAC THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o ISPECL + [`\n x:real^N. f(SUC n) x - f 0 x:real^1`; + `\x. (g:real^N->real^1) x - f 0 x`; `s:real^N->bool`]) THEN + REWRITE_TAC[] THEN ANTS_TAC THEN REPEAT CONJ_TAC THENL + [REPEAT STRIP_TAC THEN REWRITE_TAC[DROP_SUB; REAL_SUB_LE] THEN + MP_TAC(ISPEC + `\m n:num. drop (f m (x:real^N)) <= drop (f n x)` + TRANSITIVE_STEPWISE_LE) THEN + REWRITE_TAC[REAL_LE_TRANS; REAL_LE_REFL] THEN ASM_MESON_TAC[LE_0]; + GEN_TAC THEN MATCH_MP_TAC INTEGRABLE_SUB THEN ASM_REWRITE_TAC[ETA_AX]; + REPEAT STRIP_TAC THEN REWRITE_TAC[DROP_SUB; REAL_SUB_LE] THEN + ASM_SIMP_TAC[REAL_ARITH `x - a <= y - a <=> x <= y`]; + REPEAT STRIP_TAC THEN MATCH_MP_TAC LIM_SUB THEN SIMP_TAC[LIM_CONST] THEN + REWRITE_TAC[ADD1] THEN + MATCH_MP_TAC(ISPECL[`f:num->real^1`; `l:real^1`; `1`] SEQ_OFFSET) THEN + ASM_SIMP_TAC[]; + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [bounded]) THEN + ASM_SIMP_TAC[INTEGRAL_SUB; ETA_AX; bounded] THEN + ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN + REWRITE_TAC[FORALL_IN_IMAGE; IN_UNIV] THEN + DISCH_THEN(X_CHOOSE_THEN `B:real` + (fun th -> EXISTS_TAC `B + norm(integral s (f 0:real^N->real^1))` THEN + X_GEN_TAC `k:num` THEN MP_TAC(SPEC `SUC k` th))) THEN + NORM_ARITH_TAC; + ASM_SIMP_TAC[INTEGRAL_SUB; ETA_AX; IMP_CONJ] THEN + SUBGOAL_THEN `(f 0:real^N->real^1) integrable_on s` MP_TAC THENL + [ASM_REWRITE_TAC[]; ONCE_REWRITE_TAC[IMP_IMP]] THEN + DISCH_THEN(MP_TAC o MATCH_MP INTEGRABLE_ADD) THEN + REWRITE_TAC[ETA_AX; VECTOR_ARITH `f + (g - f):real^N = g`] THEN + DISCH_TAC THEN ASM_SIMP_TAC[INTEGRAL_SUB; ETA_AX] THEN + MP_TAC(ISPECL [`sequentially`; `integral s (f 0:real^N->real^1)`] + LIM_CONST) THEN + REWRITE_TAC[IMP_IMP] THEN DISCH_THEN(MP_TAC o MATCH_MP LIM_ADD) THEN + REWRITE_TAC[ETA_AX; VECTOR_ARITH `f + (g - f):real^N = g`] THEN + REWRITE_TAC[ADD1] THEN + SIMP_TAC[ISPECL[`f:num->real^1`; `l:real^1`; `1`] SEQ_OFFSET_REV]]] THEN + REPEAT GEN_TAC THEN STRIP_TAC THEN + SUBGOAL_THEN + `!x:real^N k:num. x IN s ==> 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 s (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 s ((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(s) ((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) s` ASSUME_TAC THENL + [ALL_TAC; + CONJ_TAC THENL [ASM_MESON_TAC[integrable_on]; ALL_TAC] THEN + FIRST_ASSUM(SUBST1_TAC o MATCH_MP INTEGRAL_UNIQUE) THEN + ASM_REWRITE_TAC[]] THEN + REWRITE_TAC[HAS_INTEGRAL_ALT] THEN + MP_TAC(ISPECL + [`\k x. if x IN s then (f:num->real^N->real^1) k x else vec 0`; + `\x. if x IN s then (g:real^N->real^1) x else vec 0`] + (MATCH_MP(MESON[] `(!a b c d. P a b c d ==> Q a b c d) + ==> !a b. (!c d. P a b c d) ==> (!c d. Q a b c d)`) + MONOTONE_CONVERGENCE_INTERVAL)) THEN + ANTS_TAC THENL + [REPEAT GEN_TAC THEN REWRITE_TAC[] THEN + MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN CONJ_TAC THENL + [FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE BINDER_CONV [INTEGRABLE_ALT]) THEN + SIMP_TAC[]; + DISCH_TAC] THEN + CONJ_TAC THENL + [REPEAT STRIP_TAC THEN COND_CASES_TAC THEN ASM_SIMP_TAC[REAL_LE_REFL]; + ALL_TAC] THEN + CONJ_TAC THENL + [REPEAT STRIP_TAC THEN COND_CASES_TAC THEN ASM_SIMP_TAC[LIM_CONST]; + ALL_TAC] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [bounded]) THEN + ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN + REWRITE_TAC[bounded; FORALL_IN_IMAGE; IN_UNIV] THEN + MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC THEN + MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `k:num` THEN + REWRITE_TAC[ABS_DROP] THEN MATCH_MP_TAC(REAL_ARITH + `&0 <= y /\ y <= x ==> abs(x) <= a ==> abs(y) <= a`) THEN + CONJ_TAC THENL + [MATCH_MP_TAC INTEGRAL_DROP_POS THEN ASM_REWRITE_TAC[] THEN + REPEAT STRIP_TAC THEN COND_CASES_TAC THEN + ASM_SIMP_TAC[REAL_LE_REFL; DROP_VEC]; + ALL_TAC] THEN + GEN_REWRITE_TAC (RAND_CONV o RAND_CONV) [GSYM INTEGRAL_RESTRICT_UNIV] THEN + MATCH_MP_TAC INTEGRAL_SUBSET_DROP_LE THEN + ASM_REWRITE_TAC[SUBSET_UNIV; IN_UNIV] THEN + ASM_REWRITE_TAC[INTEGRABLE_RESTRICT_UNIV; ETA_AX] THEN + GEN_TAC THEN COND_CASES_TAC THEN + ASM_SIMP_TAC[REAL_LE_REFL; DROP_VEC; REAL_LE_REFL]; + ALL_TAC] THEN + REWRITE_TAC[FORALL_AND_THM] THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + X_GEN_TAC `e:real` THEN DISCH_TAC THEN + 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[dist; REAL_LT_DIV; REAL_OF_NUM_LT; ARITH] THEN + DISCH_THEN(X_CHOOSE_THEN `N:num` STRIP_ASSUME_TAC) THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE BINDER_CONV + [HAS_INTEGRAL_INTEGRAL]) THEN + GEN_REWRITE_TAC (LAND_CONV o BINDER_CONV) [HAS_INTEGRAL_ALT] THEN + REWRITE_TAC[FORALL_AND_THM] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + DISCH_THEN(MP_TAC o SPECL [`N:num`; `e / &4`]) THEN + ASM_SIMP_TAC[dist; REAL_LT_DIV; REAL_OF_NUM_LT; ARITH] 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^N`; `b:real^N`] THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`a:real^N`; `b:real^N`]) THEN + ASM_REWRITE_TAC[] THEN + FIRST_ASSUM(MP_TAC o C MATCH_MP (ARITH_RULE `N:num <= N`)) THEN + REWRITE_TAC[IMP_IMP] THEN + DISCH_THEN(MP_TAC o MATCH_MP (NORM_ARITH + `norm(x - y) < e / &4 /\ norm(z - x) < e / &4 + ==> norm(z - y) < e / &2`)) THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE (BINDER_CONV o BINDER_CONV) + [LIM_SEQUENTIALLY]) THEN + DISCH_THEN(MP_TAC o SPECL [`a:real^N`; `b:real^N`; `e / &2`]) THEN + ASM_REWRITE_TAC[dist; REAL_HALF] THEN + DISCH_THEN(X_CHOOSE_THEN `M:num` (MP_TAC o SPEC `M + N:num`)) THEN + REWRITE_TAC[LE_ADD; ABS_DROP; DROP_SUB] THEN + MATCH_MP_TAC(REAL_ARITH + `f1 <= f2 /\ f2 <= i + ==> abs(f2 - g) < e / &2 ==> abs(f1 - i) < e / &2 ==> abs(g - i) < e`) THEN + CONJ_TAC THENL + [MATCH_MP_TAC INTEGRAL_DROP_LE THEN ASM_REWRITE_TAC[] THEN + X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[REAL_LE_REFL] THEN + MP_TAC(ISPEC + `\m n:num. drop (f m (x:real^N)) <= drop (f n x)` + TRANSITIVE_STEPWISE_LE) THEN + REWRITE_TAC[REAL_LE_REFL; REAL_LE_TRANS] THEN + ANTS_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN + DISCH_THEN MATCH_MP_TAC THEN ARITH_TAC; + ALL_TAC] THEN + MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `drop(integral s ((f:num->real^N->real^1) (M + N)))` THEN + ASM_REWRITE_TAC[] THEN + GEN_REWRITE_TAC (RAND_CONV o RAND_CONV) [GSYM INTEGRAL_RESTRICT_UNIV] THEN + MATCH_MP_TAC INTEGRAL_SUBSET_DROP_LE THEN + ASM_REWRITE_TAC[SUBSET_UNIV; IN_UNIV] THEN + ASM_REWRITE_TAC[INTEGRABLE_RESTRICT_UNIV; ETA_AX] THEN + GEN_TAC THEN COND_CASES_TAC THEN + ASM_SIMP_TAC[REAL_LE_REFL; DROP_VEC; REAL_LE_REFL]);; + +let MONOTONE_CONVERGENCE_DECREASING = prove + (`!f:num->real^N->real^1 g s. + (!k. (f k) integrable_on s) /\ + (!k x. x IN s ==> drop(f (SUC k) x) <= drop(f k x)) /\ + (!x. x IN s ==> ((\k. f k x) --> g x) sequentially) /\ + bounded {integral s (f k) | k IN (:num)} + ==> g integrable_on s /\ + ((\k. integral s (f k)) --> integral s g) sequentially`, + REPEAT GEN_TAC THEN DISCH_TAC THEN + MP_TAC(ISPECL + [`(\k x. --(f k x)):num->real^N->real^1`; + `(\x. --(g x)):real^N->real^1`; `s:real^N->bool`] + MONOTONE_CONVERGENCE_INCREASING) THEN + FIRST_ASSUM MP_TAC THEN + MATCH_MP_TAC(TAUT `(a ==> b) /\ (c ==> d) ==> a ==> (b ==> c) ==> d`) THEN + REWRITE_TAC[] THEN CONJ_TAC THENL + [REPEAT(MATCH_MP_TAC MONO_AND THEN CONJ_TAC) THENL + [MATCH_MP_TAC MONO_FORALL THEN GEN_TAC THEN + DISCH_THEN(MP_TAC o MATCH_MP INTEGRABLE_NEG) THEN REWRITE_TAC[]; + SIMP_TAC[DROP_NEG; REAL_LE_NEG2]; + REPEAT STRIP_TAC THEN MATCH_MP_TAC LIM_NEG THEN ASM_SIMP_TAC[]; + ALL_TAC] THEN + DISCH_TAC THEN MATCH_MP_TAC BOUNDED_SUBSET THEN + EXISTS_TAC `IMAGE (\x. --x) + {integral s (f k:real^N->real^1) | k IN (:num)}` THEN + CONJ_TAC THENL + [MATCH_MP_TAC BOUNDED_LINEAR_IMAGE THEN + ASM_SIMP_TAC[LINEAR_COMPOSE_NEG; LINEAR_ID]; + ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN REWRITE_TAC[GSYM IMAGE_o] THEN + REWRITE_TAC[SUBSET; IN_IMAGE] THEN + GEN_TAC THEN MATCH_MP_TAC MONO_EXISTS THEN + REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[o_THM] THEN + MATCH_MP_TAC INTEGRAL_NEG THEN ASM_REWRITE_TAC[]]; + ALL_TAC] THEN + DISCH_THEN(CONJUNCTS_THEN2 + (MP_TAC o MATCH_MP INTEGRABLE_NEG) (MP_TAC o MATCH_MP LIM_NEG)) THEN + REWRITE_TAC[VECTOR_NEG_NEG; ETA_AX] THEN + DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN + BINOP_TAC THEN REWRITE_TAC[FUN_EQ_THM] THEN TRY GEN_TAC THEN + MATCH_MP_TAC(VECTOR_ARITH `x:real^N = --y ==> --x = y`) THEN + MATCH_MP_TAC INTEGRAL_NEG THEN ASM_REWRITE_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* More lemmas about existence and bounds between integrals. *) +(* ------------------------------------------------------------------------- *) + +let INTEGRAL_NORM_BOUND_INTEGRAL = prove + (`!f:real^M->real^N g s. + f integrable_on s /\ g integrable_on s /\ + (!x. x IN s ==> norm(f x) <= drop(g x)) + ==> norm(integral s f) <= drop(integral s g)`, + let lemma = prove + (`(!e. &0 < e ==> x < y + e) ==> x <= y`, + DISCH_THEN(MP_TAC o SPEC `x - y:real`) THEN REAL_ARITH_TAC) in + SUBGOAL_THEN + `!f:real^M->real^N g a b. + f integrable_on interval[a,b] /\ g integrable_on interval[a,b] /\ + (!x. x IN interval[a,b] ==> norm(f x) <= drop(g x)) + ==> norm(integral(interval[a,b]) f) <= drop(integral(interval[a,b]) g)` + ASSUME_TAC THENL + [REPEAT STRIP_TAC THEN MATCH_MP_TAC lemma THEN + X_GEN_TAC `e:real` THEN DISCH_TAC THEN + UNDISCH_TAC `(f:real^M->real^N) integrable_on interval[a,b]` THEN + DISCH_THEN(MP_TAC o MATCH_MP INTEGRABLE_INTEGRAL) THEN + FIRST_X_ASSUM(MP_TAC o MATCH_MP INTEGRABLE_INTEGRAL) THEN + REWRITE_TAC[has_integral] THEN DISCH_THEN(MP_TAC o SPEC `e / &2`) THEN + ASM_REWRITE_TAC[REAL_HALF; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `d1:real^M->real^M->bool` THEN STRIP_TAC THEN + DISCH_THEN(MP_TAC o SPEC `e / &2`) THEN + ASM_REWRITE_TAC[REAL_HALF; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `d2:real^M->real^M->bool` THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + MP_TAC(ISPECL [`d1:real^M->real^M->bool`; `d2: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 [`a:real^M`; `b:real^M`]) THEN + REWRITE_TAC[FINE_INTER; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `p:(real^M#(real^M->bool))->bool` THEN STRIP_TAC THEN + DISCH_THEN(MP_TAC o SPEC `p:(real^M#(real^M->bool))->bool`) THEN + FIRST_X_ASSUM(MP_TAC o SPEC `p:(real^M#(real^M->bool))->bool`) THEN + ASM_REWRITE_TAC[ABS_DROP; DROP_SUB] THEN MATCH_MP_TAC(NORM_ARITH + `norm(sg) <= dsa + ==> abs(dsa - dia) < e / &2 ==> norm(sg - ig) < e / &2 + ==> norm(ig) < dia + e`) THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP TAGGED_DIVISION_OF_FINITE) THEN + ASM_SIMP_TAC[DROP_VSUM] THEN MATCH_MP_TAC VSUM_NORM_LE THEN + ASM_REWRITE_TAC[o_DEF; FORALL_PAIR_THM] THEN + MAP_EVERY X_GEN_TAC [`x:real^M`; `k:real^M->bool`] THEN DISCH_TAC THEN + REWRITE_TAC[NORM_MUL; DROP_CMUL] THEN + MATCH_MP_TAC REAL_LE_MUL2 THEN REWRITE_TAC[REAL_ABS_POS; NORM_POS_LE] THEN + REWRITE_TAC[REAL_ARITH `abs x <= x <=> &0 <= x`] THEN + ASM_MESON_TAC[CONTENT_POS_LE; TAGGED_DIVISION_OF; SUBSET]; + ALL_TAC] THEN + REPEAT GEN_TAC THEN REWRITE_TAC[CONJ_ASSOC] THEN + DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN + DISCH_THEN(CONJUNCTS_THEN (fun th -> + ASSUME_TAC(CONJUNCT1(GEN_REWRITE_RULE I [INTEGRABLE_ALT] th)) THEN + MP_TAC(MATCH_MP INTEGRABLE_INTEGRAL th))) THEN + ONCE_REWRITE_TAC[HAS_INTEGRAL] THEN + DISCH_THEN(LABEL_TAC "A") THEN DISCH_TAC THEN MATCH_MP_TAC lemma THEN + X_GEN_TAC `e:real` THEN DISCH_TAC THEN + REMOVE_THEN "A" (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 `B1:real` + (CONJUNCTS_THEN2 ASSUME_TAC (LABEL_TAC "F"))) THEN + DISCH_THEN(X_CHOOSE_THEN `B2:real` + (CONJUNCTS_THEN2 ASSUME_TAC (LABEL_TAC "A"))) THEN + MP_TAC(ISPEC `ball(vec 0,max B1 B2):real^M->bool` + BOUNDED_SUBSET_CLOSED_INTERVAL) THEN + REWRITE_TAC[BOUNDED_BALL; LEFT_IMP_EXISTS_THM] 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 `z:real^1` (CONJUNCTS_THEN2 ASSUME_TAC + (fun th -> DISCH_THEN(X_CHOOSE_THEN `w:real^N` + (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN MP_TAC th))) THEN + ASM_REWRITE_TAC[ABS_DROP; DROP_SUB] THEN MATCH_MP_TAC(NORM_ARITH + `norm(sg) <= dsa + ==> abs(dsa - dia) < e / &2 ==> norm(sg - ig) < e / &2 + ==> norm(ig) < dia + e`) THEN + REPEAT(FIRST_X_ASSUM(SUBST1_TAC o SYM o MATCH_MP INTEGRAL_UNIQUE)) THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[] THEN + REPEAT STRIP_TAC THEN + COND_CASES_TAC THEN ASM_SIMP_TAC[NORM_0; DROP_VEC; REAL_LE_REFL]);; + +let INTEGRAL_NORM_BOUND_INTEGRAL_COMPONENT = prove + (`!f:real^M->real^N g:real^M->real^P s k. + 1 <= k /\ k <= dimindex(:P) /\ + f integrable_on s /\ g integrable_on s /\ + (!x. x IN s ==> norm(f x) <= (g x)$k) + ==> norm(integral s f) <= (integral s g)$k`, + REPEAT STRIP_TAC THEN + MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `drop(integral s ((\y. lift(y$k)) o (g:real^M->real^P)))` THEN + SUBGOAL_THEN `linear(\y:real^P. lift(y$k))` ASSUME_TAC THENL + [ASM_SIMP_TAC[linear; VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT; + LIFT_ADD; LIFT_CMUL]; + ALL_TAC] THEN + CONJ_TAC THENL + [MATCH_MP_TAC INTEGRAL_NORM_BOUND_INTEGRAL THEN + ASM_SIMP_TAC[o_THM; LIFT_DROP] THEN MATCH_MP_TAC INTEGRABLE_LINEAR THEN + ASM_SIMP_TAC[]; + ALL_TAC] THEN + SUBGOAL_THEN + `integral s ((\y. lift (y$k)) o (g:real^M->real^P)) = + (\y. lift (y$k)) (integral s g)` + SUBST1_TAC THENL + [MATCH_MP_TAC INTEGRAL_LINEAR THEN ASM_REWRITE_TAC[]; + REWRITE_TAC[LIFT_DROP; REAL_LE_REFL]]);; + +let HAS_INTEGRAL_NORM_BOUND_INTEGRAL_COMPONENT = prove + (`!f:real^M->real^N g:real^M->real^P s i j k. + 1 <= k /\ k <= dimindex(:P) /\ + (f has_integral i) s /\ (g has_integral j) s /\ + (!x. x IN s ==> norm(f x) <= (g x)$k) + ==> norm(i) <= j$k`, + REPEAT STRIP_TAC THEN + REPEAT(FIRST_X_ASSUM(fun th -> + SUBST1_TAC(SYM(MATCH_MP INTEGRAL_UNIQUE th)) THEN + ASSUME_TAC(MATCH_MP HAS_INTEGRAL_INTEGRABLE th))) THEN + MATCH_MP_TAC INTEGRAL_NORM_BOUND_INTEGRAL_COMPONENT THEN + ASM_REWRITE_TAC[]);; + +let INTEGRABLE_ON_ALL_INTERVALS_INTEGRABLE_BOUND = prove + (`!f:real^M->real^N g s. + (!a b. (\x. if x IN s then f x else vec 0) + integrable_on interval[a,b]) /\ + (!x. x IN s ==> norm(f x) <= drop(g x)) /\ + g integrable_on s + ==> f integrable_on s`, + let lemma = prove + (`!f:real^M->real^N g. + (!a b. f integrable_on interval[a,b]) /\ + (!x. norm(f x) <= drop(g x)) /\ + g integrable_on (:real^M) + ==> f integrable_on (:real^M)`, + REPEAT GEN_TAC THEN + REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + ONCE_REWRITE_TAC[INTEGRABLE_ALT_SUBSET] THEN + ASM_REWRITE_TAC[IN_UNIV; ETA_AX] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `e:real` THEN + ASM_CASES_TAC `&0 < e` THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `B:real` THEN + MATCH_MP_TAC MONO_AND THEN REWRITE_TAC[] THEN + REPEAT(MATCH_MP_TAC MONO_FORALL THEN GEN_TAC) THEN + DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC(REAL_ARITH `a <= b ==> b < c ==> a < c`) THEN + ONCE_REWRITE_TAC[NORM_SUB] THEN + ASM_SIMP_TAC[GSYM INTEGRAL_DIFF; NEGLIGIBLE_EMPTY; + SET_RULE `s SUBSET t ==> s DIFF t = {}`] THEN + REWRITE_TAC[ABS_DROP] THEN + MATCH_MP_TAC(REAL_ARITH `x <= y ==> x <= abs y`) THEN + MATCH_MP_TAC INTEGRAL_NORM_BOUND_INTEGRAL THEN + ASM_MESON_TAC[integrable_on; HAS_INTEGRAL_DIFF; NEGLIGIBLE_EMPTY; + SET_RULE `s SUBSET t ==> s DIFF t = {}`]) in + REPEAT GEN_TAC THEN + REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + ONCE_REWRITE_TAC[GSYM INTEGRABLE_RESTRICT_UNIV] THEN + DISCH_TAC THEN MATCH_MP_TAC lemma THEN + EXISTS_TAC `(\x. if x IN s then g x else vec 0):real^M->real^1` THEN + ASM_REWRITE_TAC[] THEN + GEN_TAC THEN COND_CASES_TAC THEN ASM_SIMP_TAC[NORM_0; DROP_VEC; REAL_POS]);; + +(* ------------------------------------------------------------------------- *) +(* Interval functions of bounded variation on a set. *) +(* ------------------------------------------------------------------------- *) + +parse_as_infix("has_bounded_setvariation_on",(12,"right"));; + +let set_variation = new_definition + `set_variation s (f:(real^M->bool)->real^N) = + sup { sum d (\k. norm(f k)) | ?t. d division_of t /\ t SUBSET s}`;; + +let has_bounded_setvariation_on = new_definition + `(f:(real^M->bool)->real^N) has_bounded_setvariation_on s <=> + ?B. !d t. d division_of t /\ t SUBSET s + ==> sum d (\k. norm(f k)) <= B`;; + +let HAS_BOUNDED_SETVARIATION_ON = prove + (`!f:(real^M->bool)->real^N s. + f has_bounded_setvariation_on s <=> + ?B. &0 < B /\ !d t. d division_of t /\ t SUBSET s + ==> sum d (\k. norm(f k)) <= B`, + REWRITE_TAC[has_bounded_setvariation_on] THEN + MESON_TAC[REAL_ARITH `&0 < abs B + &1 /\ (x <= B ==> x <= abs B + &1)`]);; + +let HAS_BOUNDED_SETVARIATION_ON_EQ = prove + (`!f g:(real^M->bool)->real^N s. + (!a b. ~(interval[a,b] = {}) /\ interval[a,b] SUBSET s + ==> f(interval[a,b]) = g(interval[a,b])) /\ + f has_bounded_setvariation_on s + ==> g has_bounded_setvariation_on s`, + REPEAT GEN_TAC THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + REWRITE_TAC[has_bounded_setvariation_on] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `B:real` THEN + MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `d:(real^M->bool)->bool` THEN + MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `t:real^M->bool` THEN + DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC(REAL_ARITH `x = y ==> x <= B ==> y <= B`) THEN + MATCH_MP_TAC SUM_EQ THEN FIRST_ASSUM(fun th -> + GEN_REWRITE_TAC I [MATCH_MP FORALL_IN_DIVISION_NONEMPTY th]) THEN + REPEAT STRIP_TAC THEN REWRITE_TAC[] THEN AP_TERM_TAC THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_MESON_TAC[division_of; SUBSET_TRANS]);; + +let SET_VARIATION_EQ = prove + (`!f g:(real^M->bool)->real^N s. + (!a b. ~(interval[a,b] = {}) /\ interval[a,b] SUBSET s + ==> f(interval[a,b]) = g(interval[a,b])) + ==> set_variation s f = set_variation s g`, + REPEAT STRIP_TAC THEN REWRITE_TAC[set_variation] THEN AP_TERM_TAC THEN + MATCH_MP_TAC(SET_RULE + `(!x. P x ==> f x = g x) ==> {f x | P x} = {g x | P x}`) THEN + X_GEN_TAC `d:(real^M->bool)->bool` THEN + DISCH_THEN(X_CHOOSE_THEN `t:real^M->bool` STRIP_ASSUME_TAC) THEN + MATCH_MP_TAC SUM_EQ THEN FIRST_ASSUM(fun th -> + GEN_REWRITE_TAC I [MATCH_MP FORALL_IN_DIVISION_NONEMPTY th]) THEN + REPEAT STRIP_TAC THEN REWRITE_TAC[] THEN AP_TERM_TAC THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_MESON_TAC[division_of; SUBSET_TRANS]);; + +let HAS_BOUNDED_SETVARIATION_ON_COMPONENTWISE = prove + (`!f:(real^M->bool)->real^N s. + f has_bounded_setvariation_on s <=> + !i. 1 <= i /\ i <= dimindex(:N) + ==> (\k. lift(f k$i)) has_bounded_setvariation_on s`, + REPEAT GEN_TAC THEN + REWRITE_TAC[has_bounded_setvariation_on; NORM_LIFT] THEN EQ_TAC THENL + [DISCH_THEN(X_CHOOSE_THEN `B:real` STRIP_ASSUME_TAC) THEN + X_GEN_TAC `i:num` THEN STRIP_TAC THEN EXISTS_TAC `B:real` THEN + MAP_EVERY X_GEN_TAC [`d:(real^M->bool)->bool`; `t:real^M->bool`] THEN + STRIP_TAC THEN FIRST_X_ASSUM(MP_TAC o SPECL + [`d:(real^M->bool)->bool`; `t:real^M->bool`]) THEN + ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] REAL_LE_TRANS) THEN + MATCH_MP_TAC SUM_LE THEN ASM_SIMP_TAC[COMPONENT_LE_NORM] THEN + ASM_MESON_TAC[DIVISION_OF_FINITE]; + GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [RIGHT_IMP_EXISTS_THM] THEN + REWRITE_TAC[SKOLEM_THM; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `B:num->real` THEN DISCH_TAC THEN + EXISTS_TAC `sum (1..dimindex(:N)) B` THEN + MAP_EVERY X_GEN_TAC [`d:(real^M->bool)->bool`; `t:real^M->bool`] THEN + STRIP_TAC THEN MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `sum d (\k. sum (1..dimindex(:N)) + (\i. abs(((f:(real^M->bool)->real^N) k)$i)))` THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP DIVISION_OF_FINITE) THEN + ASM_SIMP_TAC[SUM_LE; NORM_LE_L1] THEN + W(MP_TAC o PART_MATCH (lhs o rand) SUM_SWAP o lhand o snd) THEN + ASM_SIMP_TAC[FINITE_NUMSEG] THEN DISCH_THEN SUBST1_TAC THEN + MATCH_MP_TAC SUM_LE_NUMSEG THEN ASM_MESON_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 HAS_BOUNDED_SETVARIATION_ON_ELEMENTARY = prove + (`!f:(real^M->bool)->real^N s. + (?d. d division_of s) + ==> (f has_bounded_setvariation_on s <=> + ?B. !d. d division_of s ==> sum d (\k. norm(f k)) <= B)`, + REPEAT GEN_TAC THEN DISCH_TAC THEN + REWRITE_TAC[has_bounded_setvariation_on] THEN EQ_TAC THEN + MATCH_MP_TAC MONO_EXISTS THENL [MESON_TAC[SUBSET_REFL]; ALL_TAC] THEN + GEN_TAC THEN DISCH_TAC THEN + MAP_EVERY X_GEN_TAC [`d:(real^M->bool)->bool`; `t:real^M->bool`] THEN + STRIP_TAC THEN FIRST_X_ASSUM(X_CHOOSE_TAC `d':(real^M->bool)->bool`) THEN + MP_TAC(ISPECL [`d:(real^M->bool)->bool`; `d':(real^M->bool)->bool`; + `t:real^M->bool`; `s:real^M->bool`] PARTIAL_DIVISION_EXTEND) THEN + ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_TAC `d'':(real^M->bool)->bool`) THEN + MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `sum d'' (\k:real^M->bool. norm(f k:real^N))` THEN + ASM_SIMP_TAC[] THEN MATCH_MP_TAC SUM_SUBSET_SIMPLE THEN + ASM_REWRITE_TAC[NORM_POS_LE] THEN ASM_MESON_TAC[DIVISION_OF_FINITE]);; + +let HAS_BOUNDED_SETVARIATION_ON_INTERVAL = prove + (`!f:(real^M->bool)->real^N a b. + f has_bounded_setvariation_on interval[a,b] <=> + ?B. !d. d division_of interval[a,b] ==> sum d (\k. norm(f k)) <= B`, + REPEAT GEN_TAC THEN MATCH_MP_TAC HAS_BOUNDED_SETVARIATION_ON_ELEMENTARY THEN + REWRITE_TAC[ELEMENTARY_INTERVAL]);; + +let HAS_BOUNDED_SETVARIATION_ON_UNIV = prove + (`!f:(real^M->bool)->real^N. + f has_bounded_setvariation_on (:real^M) <=> + ?B. !d. d division_of UNIONS d ==> sum d (\k. norm(f k)) <= B`, + REPEAT GEN_TAC THEN + REWRITE_TAC[has_bounded_setvariation_on; SUBSET_UNIV] THEN + MESON_TAC[DIVISION_OF_UNION_SELF]);; + +let HAS_BOUNDED_SETVARIATION_ON_SUBSET = prove + (`!f:(real^M->bool)->real^N s t. + f has_bounded_setvariation_on s /\ t SUBSET s + ==> f has_bounded_setvariation_on t`, + REPEAT GEN_TAC THEN + DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN + REWRITE_TAC[has_bounded_setvariation_on] THEN + MATCH_MP_TAC MONO_EXISTS THEN ASM_MESON_TAC[SUBSET_TRANS]);; + +let HAS_BOUNDED_SETVARIATION_ON_IMP_BOUNDED_ON_SUBINTERVALS = prove + (`!f:(real^M->bool)->real^N s. + f has_bounded_setvariation_on s + ==> bounded { f(interval[c,d]) | interval[c,d] SUBSET s}`, + REPEAT GEN_TAC THEN REWRITE_TAC[has_bounded_setvariation_on; bounded] THEN + DISCH_THEN(X_CHOOSE_TAC `B:real`) THEN + EXISTS_TAC `max (abs B) (norm((f:(real^M->bool)->real^N) {}))` THEN + REWRITE_TAC[FORALL_IN_GSPEC] THEN + MAP_EVERY X_GEN_TAC [`c:real^M`; `d:real^M`] THEN DISCH_TAC THEN + ASM_CASES_TAC `interval[c:real^M,d] = {}` THEN + ASM_REWRITE_TAC[REAL_ARITH `a <= max b a`] THEN + FIRST_X_ASSUM(MP_TAC o SPECL + [`{interval[c:real^M,d]}`; `interval[c:real^M,d]`]) THEN + ASM_SIMP_TAC[DIVISION_OF_SELF; SUM_SING] THEN REAL_ARITH_TAC);; + +let HAS_BOUNDED_SETVARIATION_ON_NORM = prove + (`!f:(real^M->bool)->real^N s. + f has_bounded_setvariation_on s + ==> (\x. lift(norm(f x))) has_bounded_setvariation_on s`, + REWRITE_TAC[has_bounded_setvariation_on; NORM_REAL; GSYM drop] THEN + REWRITE_TAC[REAL_ABS_NORM; LIFT_DROP]);; + +let HAS_BOUNDED_SETVARIATION_ON_COMPOSE_LINEAR = prove + (`!f:(real^M->bool)->real^N g:real^N->real^P s. + f has_bounded_setvariation_on s /\ linear g + ==> (g o f) has_bounded_setvariation_on s`, + REPEAT GEN_TAC THEN + REWRITE_TAC[HAS_BOUNDED_SETVARIATION_ON] THEN + DISCH_THEN(CONJUNCTS_THEN2 (X_CHOOSE_TAC `B:real`) ASSUME_TAC) THEN + FIRST_X_ASSUM(X_CHOOSE_TAC `C:real` o MATCH_MP LINEAR_BOUNDED_POS) THEN + EXISTS_TAC `B * C:real` THEN ASM_SIMP_TAC[REAL_LT_MUL] THEN + MAP_EVERY X_GEN_TAC [`d:(real^M->bool)->bool`; `t:real^M->bool`] THEN + STRIP_TAC THEN REWRITE_TAC[o_THM] THEN MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `sum d (\k. C * norm((f:(real^M->bool)->real^N) k))` THEN + CONJ_TAC THENL + [MATCH_MP_TAC SUM_LE THEN ASM_MESON_TAC[DIVISION_OF_FINITE]; + GEN_REWRITE_TAC RAND_CONV [REAL_MUL_SYM] THEN + REWRITE_TAC[SUM_LMUL] THEN ASM_SIMP_TAC[REAL_LE_LMUL_EQ] THEN + ASM_MESON_TAC[]]);; + +let HAS_BOUNDED_SETVARIATION_ON_0 = prove + (`!s:real^N->bool. (\x. vec 0) has_bounded_setvariation_on s`, + REWRITE_TAC[has_bounded_setvariation_on; NORM_0; SUM_0] THEN + MESON_TAC[REAL_LE_REFL]);; + +let SET_VARIATION_0 = prove + (`!s:real^N->bool. set_variation s (\x. vec 0) = &0`, + GEN_TAC THEN REWRITE_TAC[set_variation; NORM_0; SUM_0] THEN + GEN_REWRITE_TAC RAND_CONV [GSYM SUP_SING] THEN + AP_TERM_TAC THEN REWRITE_TAC[EXTENSION; IN_ELIM_THM; IN_SING] THEN + MESON_TAC[ELEMENTARY_EMPTY; EMPTY_SUBSET]);; + +let HAS_BOUNDED_SETVARIATION_ON_CMUL = prove + (`!f:(real^M->bool)->real^N c s. + f has_bounded_setvariation_on s + ==> (\x. c % f x) has_bounded_setvariation_on s`, + REPEAT GEN_TAC THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT; o_DEF] + HAS_BOUNDED_SETVARIATION_ON_COMPOSE_LINEAR) THEN + REWRITE_TAC[linear] THEN VECTOR_ARITH_TAC);; + +let HAS_BOUNDED_SETVARIATION_ON_NEG = prove + (`!f:(real^M->bool)->real^N s. + f has_bounded_setvariation_on s + ==> (\x. --(f x)) has_bounded_setvariation_on s`, + REWRITE_TAC[VECTOR_ARITH `--x:real^N = -- &1 % x`] THEN + REWRITE_TAC[HAS_BOUNDED_SETVARIATION_ON_CMUL]);; + +let HAS_BOUNDED_SETVARIATION_ON_ADD = prove + (`!f:(real^M->bool)->real^N g s. + f has_bounded_setvariation_on s /\ + g has_bounded_setvariation_on s + ==> (\x. f x + g x) has_bounded_setvariation_on s`, + REPEAT GEN_TAC THEN REWRITE_TAC[has_bounded_setvariation_on] THEN + DISCH_THEN(CONJUNCTS_THEN2 + (X_CHOOSE_THEN `B:real` STRIP_ASSUME_TAC) + (X_CHOOSE_THEN `C:real` STRIP_ASSUME_TAC)) THEN + EXISTS_TAC `B + C:real` THEN + MAP_EVERY X_GEN_TAC [`d:(real^M->bool)->bool`; `t:real^M->bool`] THEN + STRIP_TAC THEN MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `sum d (\k. norm((f:(real^M->bool)->real^N) k)) + + sum d (\k. norm((g:(real^M->bool)->real^N) k))` THEN + CONJ_TAC THENL [ALL_TAC; ASM_MESON_TAC[REAL_LE_ADD2]] THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP DIVISION_OF_FINITE) THEN + ASM_SIMP_TAC[GSYM SUM_ADD] THEN + MATCH_MP_TAC SUM_LE THEN ASM_REWRITE_TAC[NORM_TRIANGLE]);; + +let HAS_BOUNDED_SETVARIATION_ON_SUB = prove + (`!f:(real^M->bool)->real^N g s. + f has_bounded_setvariation_on s /\ + g has_bounded_setvariation_on s + ==> (\x. f x - g x) has_bounded_setvariation_on s`, + REWRITE_TAC[VECTOR_ARITH `x - y:real^N = x + --y`] THEN + SIMP_TAC[HAS_BOUNDED_SETVARIATION_ON_ADD; HAS_BOUNDED_SETVARIATION_ON_NEG]);; + +let HAS_BOUNDED_SETVARIATION_ON_NULL = prove + (`!f:(real^M->bool)->real^N s. + (!a b. content(interval[a,b]) = &0 ==> f(interval[a,b]) = vec 0) /\ + content s = &0 /\ bounded s + ==> f has_bounded_setvariation_on s`, + REPEAT STRIP_TAC THEN REWRITE_TAC[has_bounded_setvariation_on] THEN + EXISTS_TAC `&0` THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC(REAL_ARITH `x = &0 ==> x <= &0`) THEN + MATCH_MP_TAC SUM_EQ_0 THEN REWRITE_TAC[NORM_EQ_0] THEN + FIRST_ASSUM(fun th -> REWRITE_TAC[MATCH_MP FORALL_IN_DIVISION th]) THEN + REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + MATCH_MP_TAC CONTENT_0_SUBSET_GEN THEN + EXISTS_TAC `s:real^M->bool` THEN ASM_REWRITE_TAC[] THEN + ASM_MESON_TAC[division_of; SUBSET_TRANS]);; + +let SET_VARIATION_ELEMENTARY_LEMMA = prove + (`!f:(real^M->bool)->real^N s. + (?d. d division_of s) + ==> ((!d t. d division_of t /\ t SUBSET s + ==> sum d (\k. norm(f k)) <= b) <=> + (!d. d division_of s ==> sum d (\k. norm(f k)) <= b))`, + REPEAT GEN_TAC THEN DISCH_THEN(X_CHOOSE_TAC `d1:(real^M->bool)->bool`) THEN + EQ_TAC THENL [MESON_TAC[SUBSET_REFL]; ALL_TAC] THEN + DISCH_TAC THEN X_GEN_TAC `d2:(real^M->bool)->bool` THEN + X_GEN_TAC `t:real^M->bool` THEN STRIP_TAC THEN MP_TAC(ISPECL + [`d2:(real^M->bool)->bool`; `d1:(real^M->bool)->bool`; + `t:real^M->bool`; `s:real^M->bool`] PARTIAL_DIVISION_EXTEND) THEN + ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_TAC `d3:(real^M->bool)->bool`) THEN + MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `sum d3 (\k:real^M->bool. norm(f k:real^N))` THEN + ASM_SIMP_TAC[] THEN MATCH_MP_TAC SUM_SUBSET_SIMPLE THEN + ASM_REWRITE_TAC[NORM_POS_LE] THEN ASM_MESON_TAC[DIVISION_OF_FINITE]);; + +let SET_VARIATION_ON_ELEMENTARY = prove + (`!f:(real^M->bool)->real^N s. + (?d. d division_of s) + ==> set_variation s f = + sup { sum d (\k. norm(f k)) | d division_of s}`, + REPEAT GEN_TAC THEN DISCH_TAC THEN REWRITE_TAC[set_variation; sup] THEN + REWRITE_TAC[FORALL_IN_GSPEC; LEFT_IMP_EXISTS_THM] THEN + ASM_SIMP_TAC[SET_VARIATION_ELEMENTARY_LEMMA]);; + +let SET_VARIATION_ON_INTERVAL = prove + (`!f:(real^M->bool)->real^N a b. + set_variation (interval[a,b]) f = + sup { sum d (\k. norm(f k)) | d division_of interval[a,b]}`, + REPEAT GEN_TAC THEN MATCH_MP_TAC SET_VARIATION_ON_ELEMENTARY THEN + REWRITE_TAC[ELEMENTARY_INTERVAL]);; + +let HAS_BOUNDED_SETVARIATION_WORKS = prove + (`!f:(real^M->bool)->real^N s. + f has_bounded_setvariation_on s + ==> (!d t. d division_of t /\ t SUBSET s + ==> sum d (\k. norm(f k)) <= set_variation s f) /\ + (!B. (!d t. d division_of t /\ t SUBSET s + ==> sum d (\k. norm (f k)) <= B) + ==> set_variation s f <= B)`, + REPEAT GEN_TAC THEN REWRITE_TAC[has_bounded_setvariation_on] THEN + DISCH_TAC THEN + MP_TAC(ISPEC `{ sum d (\k. norm((f:(real^M->bool)->real^N) k)) | + ?t. d division_of t /\ t SUBSET s}` + SUP) THEN + REWRITE_TAC[FORALL_IN_GSPEC; LEFT_IMP_EXISTS_THM] THEN + REWRITE_TAC[set_variation] THEN DISCH_THEN MATCH_MP_TAC THEN + ASM_REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; IN_ELIM_THM] THEN + MAP_EVERY EXISTS_TAC [`&0`; `{}:(real^M->bool)->bool`] THEN + REWRITE_TAC[SUM_CLAUSES] THEN EXISTS_TAC `{}:real^M->bool` THEN + SIMP_TAC[division_of; EMPTY_SUBSET; NOT_IN_EMPTY; FINITE_EMPTY; UNIONS_0]);; + +let HAS_BOUNDED_SETVARIATION_WORKS_ON_ELEMENTARY = prove + (`!f:(real^M->bool)->real^N s. + f has_bounded_setvariation_on s /\ (?d. d division_of s) + ==> (!d. d division_of s + ==> sum d (\k. norm(f k)) <= set_variation s f) /\ + (!B. (!d. d division_of s ==> sum d (\k. norm(f k)) <= B) + ==> set_variation s f <= B)`, + SIMP_TAC[GSYM SET_VARIATION_ELEMENTARY_LEMMA] THEN + MESON_TAC[HAS_BOUNDED_SETVARIATION_WORKS]);; + +let HAS_BOUNDED_SETVARIATION_WORKS_ON_INTERVAL = prove + (`!f:(real^M->bool)->real^N a b. + f has_bounded_setvariation_on interval[a,b] + ==> (!d. d division_of interval[a,b] + ==> sum d (\k. norm(f k)) <= set_variation (interval[a,b]) f) /\ + (!B. (!d. d division_of interval[a,b] + ==> sum d (\k. norm(f k)) <= B) + ==> set_variation (interval[a,b]) f <= B)`, + SIMP_TAC[HAS_BOUNDED_SETVARIATION_WORKS_ON_ELEMENTARY; ELEMENTARY_INTERVAL]);; + +let SET_VARIATION_UBOUND = prove + (`!f:(real^M->bool)->real^N s B. + f has_bounded_setvariation_on s /\ + (!d t. d division_of t /\ t SUBSET s ==> sum d (\k. norm(f k)) <= B) + ==> set_variation s f <= B`, + MESON_TAC[HAS_BOUNDED_SETVARIATION_WORKS]);; + +let SET_VARIATION_UBOUND_ON_INTERVAL = prove + (`!f:(real^M->bool)->real^N a b B. + f has_bounded_setvariation_on interval[a,b] /\ + (!d. d division_of interval[a,b] ==> sum d (\k. norm(f k)) <= B) + ==> set_variation (interval[a,b]) f <= B`, + SIMP_TAC[GSYM SET_VARIATION_ELEMENTARY_LEMMA; ELEMENTARY_INTERVAL] THEN + MESON_TAC[SET_VARIATION_UBOUND]);; + +let SET_VARIATION_LBOUND = prove + (`!f:(real^M->bool)->real^N s B. + f has_bounded_setvariation_on s /\ + (?d t. d division_of t /\ t SUBSET s /\ B <= sum d (\k. norm(f k))) + ==> B <= set_variation s f`, + MESON_TAC[HAS_BOUNDED_SETVARIATION_WORKS; REAL_LE_TRANS]);; + +let SET_VARIATION_LBOUND_ON_INTERVAL = prove + (`!f:(real^M->bool)->real^N a b B. + f has_bounded_setvariation_on interval[a,b] /\ + (?d. d division_of interval[a,b] /\ B <= sum d (\k. norm(f k))) + ==> B <= set_variation (interval[a,b]) f`, + MESON_TAC[HAS_BOUNDED_SETVARIATION_WORKS_ON_INTERVAL; REAL_LE_TRANS]);; + +let SET_VARIATION = prove + (`!f:(real^M->bool)->real^N s d t. + f has_bounded_setvariation_on s /\ d division_of t /\ t SUBSET s + ==> sum d (\k. norm(f k)) <= set_variation s f`, + MESON_TAC[HAS_BOUNDED_SETVARIATION_WORKS]);; + +let SET_VARIATION_WORKS_ON_INTERVAL = prove + (`!f:(real^M->bool)->real^N a b d. + f has_bounded_setvariation_on interval[a,b] /\ + d division_of interval[a,b] + ==> sum d (\k. norm(f k)) <= set_variation (interval[a,b]) f`, + MESON_TAC[HAS_BOUNDED_SETVARIATION_WORKS_ON_INTERVAL]);; + +let SET_VARIATION_POS_LE = prove + (`!f:(real^M->bool)->real^N s. + f has_bounded_setvariation_on s ==> &0 <= set_variation s f`, + REPEAT STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] SET_VARIATION)) THEN + DISCH_THEN(MP_TAC o SPECL[`{}:(real^M->bool)->bool`; `{}:real^M->bool`]) THEN + REWRITE_TAC[EMPTY_SUBSET; SUM_CLAUSES; DIVISION_OF_TRIVIAL]);; + +let SET_VARIATION_GE_FUNCTION = prove + (`!f:(real^M->bool)->real^N s a b. + f has_bounded_setvariation_on s /\ + interval[a,b] SUBSET s /\ ~(interval[a,b] = {}) + ==> norm(f(interval[a,b])) <= set_variation s f`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC SET_VARIATION_LBOUND THEN + ASM_REWRITE_TAC[] THEN EXISTS_TAC `{interval[a:real^M,b]}` THEN + EXISTS_TAC `interval[a:real^M,b]` THEN + ASM_REWRITE_TAC[SUM_SING; REAL_LE_REFL] THEN + ASM_SIMP_TAC[DIVISION_OF_SELF]);; + +let SET_VARIATION_ON_NULL = prove + (`!f:(real^M->bool)->real^N s. + (!a b. content(interval[a,b]) = &0 ==> f(interval[a,b]) = vec 0) /\ + content s = &0 /\ bounded s + ==> set_variation s f = &0`, + REPEAT STRIP_TAC THEN + ONCE_REWRITE_TAC[GSYM REAL_LE_ANTISYM] THEN CONJ_TAC THENL + [MATCH_MP_TAC SET_VARIATION_UBOUND THEN + ASM_SIMP_TAC[HAS_BOUNDED_SETVARIATION_ON_NULL] THEN + REPEAT STRIP_TAC THEN + MATCH_MP_TAC(REAL_ARITH `x = &0 ==> x <= &0`) THEN + MATCH_MP_TAC SUM_EQ_0 THEN REWRITE_TAC[NORM_EQ_0] THEN + FIRST_ASSUM(fun th -> REWRITE_TAC[MATCH_MP FORALL_IN_DIVISION th]) THEN + REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + MATCH_MP_TAC CONTENT_0_SUBSET_GEN THEN + EXISTS_TAC `s:real^M->bool` THEN ASM_REWRITE_TAC[] THEN + ASM_MESON_TAC[division_of; SUBSET_TRANS]; + MATCH_MP_TAC SET_VARIATION_POS_LE THEN + ASM_SIMP_TAC[HAS_BOUNDED_SETVARIATION_ON_NULL]]);; + +let SET_VARIATION_TRIANGLE = prove + (`!f:(real^M->bool)->real^N g s. + f has_bounded_setvariation_on s /\ + g has_bounded_setvariation_on s + ==> set_variation s (\x. f x + g x) + <= set_variation s f + set_variation s g`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC SET_VARIATION_UBOUND THEN + ASM_SIMP_TAC[HAS_BOUNDED_SETVARIATION_ON_ADD] THEN + MAP_EVERY X_GEN_TAC [`d:(real^M->bool)->bool`; `t:real^M->bool`] THEN + STRIP_TAC THEN MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `sum d (\k. norm((f:(real^M->bool)->real^N) k)) + + sum d (\k. norm((g:(real^M->bool)->real^N) k))` THEN + CONJ_TAC THENL + [FIRST_ASSUM(ASSUME_TAC o MATCH_MP DIVISION_OF_FINITE) THEN + ASM_SIMP_TAC[GSYM SUM_ADD] THEN + MATCH_MP_TAC SUM_LE THEN ASM_REWRITE_TAC[NORM_TRIANGLE]; + MATCH_MP_TAC REAL_LE_ADD2 THEN + CONJ_TAC THEN MATCH_MP_TAC SET_VARIATION 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 HAS_BOUNDED_SETVARIATION_ON_DIVISION = prove + (`!f:(real^M->bool)->real^N a b d. + operative (+) f /\ d division_of interval[a,b] + ==> ((!k. k IN d ==> f has_bounded_setvariation_on k) <=> + f has_bounded_setvariation_on interval[a,b])`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC OPERATIVE_DIVISION_AND THEN + ASM_REWRITE_TAC[operative; NEUTRAL_AND] THEN CONJ_TAC THENL + [RULE_ASSUM_TAC(REWRITE_RULE[operative; NEUTRAL_VECTOR_ADD]) THEN + ASM_SIMP_TAC[HAS_BOUNDED_SETVARIATION_ON_NULL; BOUNDED_INTERVAL]; + FIRST_ASSUM(MP_TAC o MATCH_MP OPERATIVE_LIFTED_SETVARIATION) THEN + REWRITE_TAC[operative] THEN DISCH_THEN(MP_TAC o CONJUNCT2) THEN + REPEAT(MATCH_MP_TAC MONO_FORALL THEN GEN_TAC) THEN + REPEAT(COND_CASES_TAC THEN + ASM_REWRITE_TAC[lifted; distinctness "option"])]);; + +let SET_VARIATION_ON_DIVISION = prove + (`!f:(real^M->bool)->real^N a b d. + operative (+) f /\ d division_of interval[a,b] /\ + f has_bounded_setvariation_on interval[a,b] + ==> sum d (\k. set_variation k f) = set_variation (interval[a,b]) f`, + let lemma0 = prove + (`!op x y. lifted op (SOME x) y = SOME z <=> ?w. y = SOME w /\ op x w = z`, + GEN_TAC THEN GEN_TAC THEN MATCH_MP_TAC option_INDUCT THEN + REWRITE_TAC[lifted; distinctness "option"; injectivity "option"] THEN + MESON_TAC[]) in + let lemma = prove + (`!P op f s z. + monoidal op /\ FINITE s /\ + iterate(lifted op) s (\i. if P i then SOME(f i) else NONE) = SOME z + ==> iterate op s f = z`, + REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN + REPEAT GEN_TAC THEN DISCH_TAC THEN GEN_TAC THEN + MATCH_MP_TAC FINITE_INDUCT_STRONG THEN + ASM_SIMP_TAC[ITERATE_CLAUSES; MONOIDAL_LIFTED; NEUTRAL_LIFTED] THEN + REWRITE_TAC[injectivity "option"] THEN REPEAT GEN_TAC THEN + STRIP_TAC THEN GEN_TAC THEN COND_CASES_TAC THEN + REWRITE_TAC[lifted; distinctness "option"] THEN ASM_MESON_TAC[lemma0]) in + REPEAT STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o MATCH_MP OPERATIVE_LIFTED_SETVARIATION) THEN + DISCH_THEN(MP_TAC o SPECL[`d:(real^M->bool)->bool`; `a:real^M`; `b:real^M`] o + MATCH_MP (REWRITE_RULE [TAUT `a /\ b /\ c ==> d <=> b ==> a /\ c ==> d`] + OPERATIVE_DIVISION)) THEN + ASM_SIMP_TAC[MONOIDAL_LIFTED; MONOIDAL_REAL_ADD] THEN + MP_TAC(ISPECL + [`\k. (f:(real^M->bool)->real^N) has_bounded_setvariation_on k`; + `(+):real->real->real`; + `\k. set_variation k (f:(real^M->bool)->real^N)`; + `d:(real^M->bool)->bool`; + `set_variation (interval[a,b]) (f:(real^M->bool)->real^N)`] + lemma) THEN + FIRST_X_ASSUM(ASSUME_TAC o MATCH_MP DIVISION_OF_FINITE) THEN + ASM_REWRITE_TAC[sum; MONOIDAL_REAL_ADD]);; + +let SET_VARIATION_MONOTONE = prove + (`!f:(real^M->bool)->real^N s t. + f has_bounded_setvariation_on s /\ t SUBSET s + ==> set_variation t f <= set_variation s f`, + REPEAT STRIP_TAC THEN REWRITE_TAC[set_variation] THEN + MATCH_MP_TAC REAL_SUP_LE_SUBSET THEN REPEAT CONJ_TAC THENL + [REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; IN_ELIM_THM] THEN + MAP_EVERY EXISTS_TAC [`&0`; `{}:(real^M->bool)->bool`] THEN + REWRITE_TAC[SUM_CLAUSES] THEN EXISTS_TAC `{}:real^M->bool` THEN + REWRITE_TAC[EMPTY_SUBSET; DIVISION_OF_TRIVIAL]; + MATCH_MP_TAC(SET_RULE + `(!d. P d ==> Q d) ==> {f d | P d} SUBSET {f d | Q d}`) THEN + ASM_MESON_TAC[SUBSET_TRANS]; + REWRITE_TAC[FORALL_IN_GSPEC; LEFT_IMP_EXISTS_THM] THEN + ASM_REWRITE_TAC[GSYM has_bounded_setvariation_on]]);; + +let HAS_BOUNDED_SETVARIATION_REFLECT2_EQ,SET_VARIATION_REFLECT2 = + (CONJ_PAIR o prove) + (`(!f:(real^M->bool)->real^N s. + (\k. f(IMAGE (--) k)) has_bounded_setvariation_on (IMAGE (--) s) <=> + f has_bounded_setvariation_on s) /\ + (!f:(real^M->bool)->real^N s. + set_variation (IMAGE (--) s) (\k. f(IMAGE (--) k)) = + set_variation s f)`, + MATCH_MP_TAC SETVARIATION_EQUAL_LEMMA THEN + EXISTS_TAC `IMAGE ((--):real^M->real^M)` THEN + SIMP_TAC[IMAGE_SUBSET; GSYM IMAGE_o; o_DEF] THEN + REWRITE_TAC[VECTOR_NEG_NEG; IMAGE_ID; REFLECT_INTERVAL] THEN + SIMP_TAC[ETA_AX; DIVISION_OF_REFLECT] THEN + SIMP_TAC[EQ_INTERVAL; TAUT `~q /\ (p /\ q \/ r) <=> ~q /\ r`] THEN + REWRITE_TAC[TAUT `p /\ q /\ r <=> r /\ q /\ p`] THEN + REWRITE_TAC[UNWIND_THM1; CONTRAPOS_THM] THEN + REWRITE_TAC[INTERVAL_EQ_EMPTY; VECTOR_NEG_COMPONENT; REAL_LT_NEG2]);; + +let HAS_BOUNDED_SETVARIATION_TRANSLATION2_EQ, SET_VARIATION_TRANSLATION2 = + (CONJ_PAIR o prove) + (`(!a f:(real^M->bool)->real^N s. + (\k. f(IMAGE (\x. a + x) k)) + has_bounded_setvariation_on (IMAGE (\x. --a + x) s) <=> + f has_bounded_setvariation_on s) /\ + (!a f:(real^M->bool)->real^N s. + set_variation (IMAGE (\x. --a + x) s) (\k. f(IMAGE (\x. a + x) k)) = + set_variation s f)`, + GEN_REWRITE_TAC I [AND_FORALL_THM] THEN X_GEN_TAC `a:real^M` THEN + MATCH_MP_TAC SETVARIATION_EQUAL_LEMMA THEN + EXISTS_TAC `\s. IMAGE (\x:real^M. a + x) s` THEN + SIMP_TAC[IMAGE_SUBSET; GSYM IMAGE_o; o_DEF] THEN + REWRITE_TAC[VECTOR_ARITH `a + --a + x:real^N = x`; IMAGE_ID; + VECTOR_ARITH `--a + a + x:real^N = x`] THEN + REWRITE_TAC[GSYM INTERVAL_TRANSLATION] THEN + SIMP_TAC[EQ_INTERVAL; TAUT `~q /\ (p /\ q \/ r) <=> ~q /\ r`] THEN + REWRITE_TAC[TAUT `p /\ q /\ r <=> r /\ q /\ p`] THEN + REWRITE_TAC[UNWIND_THM1; CONTRAPOS_THM] THEN + REWRITE_TAC[INTERVAL_EQ_EMPTY; VECTOR_ADD_COMPONENT; REAL_LT_LADD] THEN + REPEAT STRIP_TAC THEN + GEN_REWRITE_TAC (LAND_CONV o LAND_CONV) [ETA_AX] THEN + ASM_SIMP_TAC[DIVISION_OF_TRANSLATION]);; + +let HAS_BOUNDED_SETVARIATION_TRANSLATION = prove + (`!f:(real^M->bool)->real^N s a. + f has_bounded_setvariation_on s + ==> (\k. f(IMAGE (\x. a + x) k)) + has_bounded_setvariation_on (IMAGE (\x. --a + x) s)`, + REWRITE_TAC[HAS_BOUNDED_SETVARIATION_TRANSLATION2_EQ]);; + +(* ------------------------------------------------------------------------- *) +(* Absolute integrability (this is the same as Lebesgue integrability). *) +(* ------------------------------------------------------------------------- *) + +parse_as_infix("absolutely_integrable_on",(12,"right"));; + +let absolutely_integrable_on = new_definition + `f absolutely_integrable_on s <=> + f integrable_on s /\ (\x. lift(norm(f x))) integrable_on s`;; + +let ABSOLUTELY_INTEGRABLE_IMP_INTEGRABLE = prove + (`!f s. f absolutely_integrable_on s ==> f integrable_on s`, + SIMP_TAC[absolutely_integrable_on]);; + +let ABSOLUTELY_INTEGRABLE_LE = prove + (`!f:real^M->real^N s. + f absolutely_integrable_on s + ==> norm(integral s f) <= drop(integral s (\x. lift(norm(f x))))`, + REWRITE_TAC[absolutely_integrable_on] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC INTEGRAL_NORM_BOUND_INTEGRAL THEN + ASM_REWRITE_TAC[LIFT_DROP; REAL_LE_REFL]);; + +let ABSOLUTELY_INTEGRABLE_0 = prove + (`!s. (\x. vec 0) absolutely_integrable_on s`, + REWRITE_TAC[absolutely_integrable_on; NORM_0; LIFT_NUM; INTEGRABLE_0]);; + +let ABSOLUTELY_INTEGRABLE_CMUL = prove + (`!f s c. f absolutely_integrable_on s + ==> (\x. c % f(x)) absolutely_integrable_on s`, + SIMP_TAC[absolutely_integrable_on; INTEGRABLE_CMUL; NORM_MUL; LIFT_CMUL]);; + +let ABSOLUTELY_INTEGRABLE_NEG = prove + (`!f s. f absolutely_integrable_on s + ==> (\x. --f(x)) absolutely_integrable_on s`, + SIMP_TAC[absolutely_integrable_on; INTEGRABLE_NEG; NORM_NEG]);; + +let ABSOLUTELY_INTEGRABLE_NORM = prove + (`!f s. f absolutely_integrable_on s + ==> (\x. lift(norm(f x))) absolutely_integrable_on s`, + SIMP_TAC[absolutely_integrable_on; NORM_LIFT; REAL_ABS_NORM]);; + +let ABSOLUTELY_INTEGRABLE_ABS_1 = prove + (`!f s. f absolutely_integrable_on s + ==> (\x. lift(abs(drop(f x)))) absolutely_integrable_on s`, + REWRITE_TAC[GSYM NORM_LIFT; LIFT_DROP; ABSOLUTELY_INTEGRABLE_NORM]);; + +let ABSOLUTELY_INTEGRABLE_ON_SUBINTERVAL = prove + (`!f:real^M->real^N s a b. + f absolutely_integrable_on s /\ interval[a,b] SUBSET s + ==> f absolutely_integrable_on interval[a,b]`, + REWRITE_TAC[absolutely_integrable_on] THEN + MESON_TAC[INTEGRABLE_ON_SUBINTERVAL]);; + +let ABSOLUTELY_INTEGRABLE_BOUNDED_SETVARIATION = prove + (`!f:real^M->real^N s. + f absolutely_integrable_on s + ==> (\k. integral k f) has_bounded_setvariation_on s`, + REWRITE_TAC[has_bounded_setvariation_on] THEN REPEAT STRIP_TAC THEN + EXISTS_TAC + `drop(integral (s:real^M->bool) (\x. lift(norm(f x:real^N))))` THEN + X_GEN_TAC `d:(real^M->bool)->bool` THEN + X_GEN_TAC `t:real^M->bool` THEN STRIP_TAC THEN + SUBGOAL_THEN `(UNIONS d:real^M->bool) SUBSET s` ASSUME_TAC THENL + [ASM_MESON_TAC[SUBSET_TRANS; division_of]; ALL_TAC] THEN + MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC + `drop(integral (UNIONS d) (\x. lift(norm((f:real^M->real^N) x))))` THEN + CONJ_TAC THENL + [ALL_TAC; + MATCH_MP_TAC INTEGRAL_SUBSET_DROP_LE THEN + ASM_REWRITE_TAC[LIFT_DROP; NORM_POS_LE] THEN CONJ_TAC THENL + [MATCH_MP_TAC INTEGRABLE_ON_SUBDIVISION THEN + EXISTS_TAC `s:real^M->bool` THEN + EXISTS_TAC `d:(real^M->bool)->bool` THEN CONJ_TAC THENL + [ASM_MESON_TAC[DIVISION_OF_SUBSET; division_of]; ALL_TAC] THEN + ASM_REWRITE_TAC[]; + ALL_TAC] THEN + MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_IMP_INTEGRABLE THEN + MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_NORM THEN ASM_REWRITE_TAC[]] THEN + MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC + `drop(vsum d (\i. integral i (\x:real^M. lift(norm(f x:real^N)))))` THEN + CONJ_TAC THENL + [FIRST_ASSUM(ASSUME_TAC o MATCH_MP DIVISION_OF_FINITE) THEN + ASM_SIMP_TAC[DROP_VSUM] THEN MATCH_MP_TAC SUM_LE THEN + ASM_REWRITE_TAC[o_THM] THEN + FIRST_ASSUM(fun th -> REWRITE_TAC[MATCH_MP FORALL_IN_DIVISION th]) THEN + MAP_EVERY X_GEN_TAC [`a:real^M`; `b:real^M`] THEN DISCH_TAC THEN + MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_LE THEN + MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_ON_SUBINTERVAL THEN + EXISTS_TAC `s:real^M->bool` THEN ASM_MESON_TAC[division_of; SUBSET_TRANS]; + MATCH_MP_TAC REAL_EQ_IMP_LE THEN AP_TERM_TAC THEN + CONV_TAC SYM_CONV THEN MATCH_MP_TAC INTEGRAL_COMBINE_DIVISION_TOPDOWN THEN + CONJ_TAC THENL [ALL_TAC; ASM_MESON_TAC[DIVISION_OF_UNION_SELF]] THEN + MATCH_MP_TAC INTEGRABLE_ON_SUBDIVISION THEN + MAP_EVERY EXISTS_TAC [`s:real^M->bool`; `d:(real^M->bool)->bool`] THEN + CONJ_TAC THENL [ASM_MESON_TAC[DIVISION_OF_UNION_SELF]; ALL_TAC] THEN + ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_IMP_INTEGRABLE THEN + MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_NORM THEN ASM_REWRITE_TAC[]]);; + +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 BOUNDED_SETVARIATION_ABSOLUTELY_INTEGRABLE = prove + (`!f:real^M->real^N. + f integrable_on UNIV /\ + (\k. integral k f) has_bounded_setvariation_on (:real^M) + ==> f absolutely_integrable_on UNIV`, + REWRITE_TAC[HAS_BOUNDED_SETVARIATION_ON_UNIV] 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 (UNIONS d) }` + 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 (UNIONS d) })` THEN + ANTS_TAC THENL + [CONJ_TAC THENL [ALL_TAC; ASM_MESON_TAC[]] THEN + EXISTS_TAC `{}:(real^M->bool)->bool` THEN + REWRITE_TAC[UNIONS_0; DIVISION_OF_TRIVIAL]; + ALL_TAC] THEN + STRIP_TAC THEN REWRITE_TAC[integrable_on] THEN EXISTS_TAC `lift i` THEN + REWRITE_TAC[HAS_INTEGRAL_ALT; IN_UNIV] THEN + MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN CONJ_TAC THENL + [MAP_EVERY X_GEN_TAC [`a:real^M`; `b:real^M`] THEN + MP_TAC(ISPECL [`f:real^M->real^N`; `a:real^M`; `b:real^M`] + (REWRITE_RULE[HAS_BOUNDED_SETVARIATION_ON_INTERVAL] + BOUNDED_SETVARIATION_ABSOLUTELY_INTEGRABLE_INTERVAL)) THEN + ANTS_TAC THENL [ALL_TAC; SIMP_TAC[absolutely_integrable_on]] THEN + CONJ_TAC THENL + [MATCH_MP_TAC INTEGRABLE_ON_SUBINTERVAL THEN EXISTS_TAC `(:real^M)` THEN + ASM_REWRITE_TAC[SUBSET_UNIV]; + ALL_TAC] THEN + EXISTS_TAC `B:real` THEN REPEAT STRIP_TAC THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_MESON_TAC[DIVISION_OF_UNION_SELF]; + ALL_TAC] THEN + DISCH_TAC THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `i - e`) THEN + ASM_SIMP_TAC[REAL_ARITH `&0 < e ==> ~(i <= i - e)`] 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 + SUBGOAL_THEN `bounded(UNIONS d:real^M->bool)` MP_TAC THENL + [ASM_MESON_TAC[ELEMENTARY_BOUNDED]; ALL_TAC] THEN + REWRITE_TAC[BOUNDED_POS] THEN + DISCH_THEN(X_CHOOSE_THEN `K:real` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `K + &1` THEN ASM_SIMP_TAC[REAL_LT_ADD; REAL_LT_01] THEN + MAP_EVERY X_GEN_TAC [`a:real^M`; `b:real^M`] THEN DISCH_TAC THEN + REWRITE_TAC[ABS_DROP; DROP_SUB; LIFT_DROP] THEN + MATCH_MP_TAC(REAL_ARITH + `!s1. i - e < s1 /\ s1 <= s /\ s < i + e ==> abs(s - i) < e`) THEN + EXISTS_TAC `sum (d:(real^M->bool)->bool) (\k. norm (integral k + (f:real^M->real^N)))` THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP DIVISION_OF_FINITE) THEN + ASM_REWRITE_TAC[] THEN CONJ_TAC THENL + [MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `sum d + (\k. drop(integral k (\x. lift(norm((f:real^M->real^N) x)))))` THEN + CONJ_TAC THENL + [MATCH_MP_TAC SUM_LE THEN + FIRST_ASSUM(fun t -> ASM_REWRITE_TAC[MATCH_MP FORALL_IN_DIVISION t]) THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_LE THEN + ASM_REWRITE_TAC[absolutely_integrable_on] THEN + MATCH_MP_TAC INTEGRABLE_ON_SUBINTERVAL THEN + EXISTS_TAC `(:real^M)` THEN ASM_REWRITE_TAC[SUBSET_UNIV]; + ALL_TAC] THEN + MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `drop(integral (UNIONS d) + (\x. lift(norm((f:real^M->real^N) x))))` THEN + CONJ_TAC THENL + [MATCH_MP_TAC(MESON[REAL_LE_REFL; LIFT_DROP] + `lift x = y ==> x <= drop y`) THEN + ASM_SIMP_TAC[LIFT_SUM; o_DEF; LIFT_DROP] THEN CONV_TAC SYM_CONV THEN + MATCH_MP_TAC INTEGRAL_COMBINE_DIVISION_BOTTOMUP THEN + FIRST_ASSUM(fun t -> ASM_REWRITE_TAC[MATCH_MP FORALL_IN_DIVISION t]); + ALL_TAC] THEN + MATCH_MP_TAC INTEGRAL_SUBSET_DROP_LE THEN + ASM_REWRITE_TAC[LIFT_DROP; NORM_POS_LE] THEN + MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN CONJ_TAC THENL + [MATCH_MP_TAC SUBSET_TRANS THEN + EXISTS_TAC `ball(vec 0:real^M,K + &1)` THEN + ASM_REWRITE_TAC[] THEN REWRITE_TAC[SUBSET; IN_BALL] THEN + ASM_SIMP_TAC[NORM_ARITH `norm(x) <= K ==> dist(vec 0,x) < K + &1`]; + ALL_TAC] THEN + DISCH_TAC THEN MATCH_MP_TAC INTEGRABLE_ON_SUBDIVISION THEN + EXISTS_TAC `interval[a:real^M,b]` THEN + EXISTS_TAC `d:(real^M->bool)->bool` THEN ASM_REWRITE_TAC[]; + ALL_TAC] THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`a:real^M`; `b:real^M`]) THEN + REWRITE_TAC[HAS_INTEGRAL_INTEGRAL; has_integral] THEN + DISCH_THEN(MP_TAC o SPEC `e / &2`) THEN ASM_REWRITE_TAC[REAL_HALF] THEN + DISCH_THEN(X_CHOOSE_THEN `d1:real^M->real^M->bool` MP_TAC) THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC (LABEL_TAC "*")) THEN + MP_TAC(ISPECL [`f:real^M->real^N`; `a:real^M`; `b:real^M`] + HENSTOCK_LEMMA) THEN + ANTS_TAC THENL + [MATCH_MP_TAC INTEGRABLE_ON_SUBINTERVAL THEN + EXISTS_TAC `(:real^M)` THEN ASM_REWRITE_TAC[SUBSET_UNIV]; + ALL_TAC] THEN + DISCH_THEN(MP_TAC o SPEC `e / &2`) THEN ASM_REWRITE_TAC[REAL_HALF] THEN + DISCH_THEN(X_CHOOSE_THEN `d2:real^M->real^M->bool` MP_TAC) THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC (LABEL_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 + REMOVE_THEN "*" (MP_TAC o SPEC `p:(real^M#(real^M->bool)->bool)`) THEN + REMOVE_THEN "+" (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 + REWRITE_TAC[ABS_DROP; DROP_SUB] THEN + REWRITE_TAC[LAMBDA_PAIR] THEN DISCH_THEN(MP_TAC o MATCH_MP lemma) THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP TAGGED_DIVISION_OF_FINITE) THEN + ASM_SIMP_TAC[DROP_VSUM; o_DEF; SUM_SUB] THEN + REWRITE_TAC[LAMBDA_PAIR_THM; DROP_CMUL; NORM_MUL; LIFT_DROP] THEN + MATCH_MP_TAC(REAL_ARITH + `sf' = sf /\ si <= i + ==> abs(sf - si) < e / &2 + ==> abs(sf' - di) < e / &2 + ==> di < i + e`) THEN + CONJ_TAC THENL + [MATCH_MP_TAC SUM_EQ THEN REWRITE_TAC[FORALL_PAIR_THM; real_abs] THEN + ASM_MESON_TAC[CONTENT_POS_LE; TAGGED_DIVISION_OF]; + ALL_TAC] THEN + SUBGOAL_THEN + `sum p (\(x:real^M,k). norm(integral k f)) = + sum (IMAGE SND p) (\k. norm(integral k (f:real^M->real^N)))` + SUBST1_TAC THENL + [MATCH_MP_TAC SUM_OVER_TAGGED_DIVISION_LEMMA THEN + EXISTS_TAC `interval[a:real^M,b]` THEN ASM_REWRITE_TAC[] THEN + SIMP_TAC[INTEGRAL_NULL; NORM_0]; + ALL_TAC] THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN + MATCH_MP_TAC PARTIAL_DIVISION_OF_TAGGED_DIVISION THEN + EXISTS_TAC `interval[a:real^M,b]` THEN ASM_MESON_TAC[tagged_division_of]);; + +let ABSOLUTELY_INTEGRABLE_BOUNDED_SETVARIATION_UNIV_EQ = prove + (`!f:real^M->real^N. + f absolutely_integrable_on (:real^M) <=> + f integrable_on (:real^M) /\ + (\k. integral k f) has_bounded_setvariation_on (:real^M)`, + GEN_TAC THEN EQ_TAC THEN + SIMP_TAC[ABSOLUTELY_INTEGRABLE_BOUNDED_SETVARIATION; + BOUNDED_SETVARIATION_ABSOLUTELY_INTEGRABLE; + ABSOLUTELY_INTEGRABLE_IMP_INTEGRABLE]);; + +let ABSOLUTELY_INTEGRABLE_BOUNDED_SETVARIATION_EQ = prove + (`!f:real^M->real^N a b. + f absolutely_integrable_on interval[a,b] <=> + f integrable_on interval[a,b] /\ + (\k. integral k f) has_bounded_setvariation_on interval[a,b]`, + REPEAT GEN_TAC THEN EQ_TAC THEN + SIMP_TAC[ABSOLUTELY_INTEGRABLE_BOUNDED_SETVARIATION; + BOUNDED_SETVARIATION_ABSOLUTELY_INTEGRABLE_INTERVAL; + ABSOLUTELY_INTEGRABLE_IMP_INTEGRABLE]);; + +let ABSOLUTELY_INTEGRABLE_SET_VARIATION = prove + (`!f:real^M->real^N a b. + f absolutely_integrable_on interval[a,b] + ==> set_variation (interval[a,b]) (\k. integral k f) = + drop(integral (interval[a,b]) (\x. lift(norm(f x))))`, + REPEAT STRIP_TAC THEN REWRITE_TAC[set_variation] THEN + MATCH_MP_TAC REAL_SUP_UNIQUE THEN + REWRITE_TAC[FORALL_IN_GSPEC; EXISTS_IN_GSPEC] THEN CONJ_TAC THENL + [X_GEN_TAC `d:(real^M->bool)->bool` THEN + DISCH_THEN(X_CHOOSE_THEN `s:real^M->bool` STRIP_ASSUME_TAC) THEN + MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `drop(integral s (\x. lift(norm((f:real^M->real^N) x))))` THEN + CONJ_TAC THENL + [MP_TAC(ISPECL [`\x. lift(norm((f:real^M->real^N) x))`; + `d:(real^M->bool)->bool`; `s:real^M->bool`] + INTEGRAL_COMBINE_DIVISION_TOPDOWN) THEN + ASM_REWRITE_TAC[] THEN ANTS_TAC THENL + [RULE_ASSUM_TAC(REWRITE_RULE[absolutely_integrable_on]) THEN + ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC INTEGRABLE_ON_SUBDIVISION THEN + EXISTS_TAC `interval[a:real^M,b]` THEN ASM_MESON_TAC[]; + DISCH_THEN SUBST1_TAC] THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP DIVISION_OF_FINITE) THEN + ASM_SIMP_TAC[DROP_VSUM] THEN MATCH_MP_TAC SUM_LE THEN + ASM_REWRITE_TAC[o_THM] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC INTEGRAL_NORM_BOUND_INTEGRAL THEN + REWRITE_TAC[LIFT_DROP; REAL_LE_REFL; GSYM absolutely_integrable_on] THEN + RULE_ASSUM_TAC(REWRITE_RULE[division_of]) THEN + ASM_MESON_TAC[ABSOLUTELY_INTEGRABLE_ON_SUBINTERVAL; SUBSET_TRANS]; + MATCH_MP_TAC INTEGRAL_SUBSET_DROP_LE THEN + ASM_REWRITE_TAC[LIFT_DROP; NORM_POS_LE] THEN + RULE_ASSUM_TAC(REWRITE_RULE[absolutely_integrable_on]) THEN + ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC INTEGRABLE_ON_SUBDIVISION THEN + EXISTS_TAC `interval[a:real^M,b]` THEN ASM_MESON_TAC[]]; + X_GEN_TAC `B:real` THEN ONCE_REWRITE_TAC[GSYM REAL_SUB_LT] THEN + ABBREV_TAC `e = drop(integral (interval [a,b]) + (\x. lift(norm((f:real^M->real^N) x)))) - + B` THEN + DISCH_TAC THEN + FIRST_ASSUM(MP_TAC o MATCH_MP ABSOLUTELY_INTEGRABLE_IMP_INTEGRABLE) THEN + DISCH_THEN(MP_TAC o SPEC `e / &2` o MATCH_MP HENSTOCK_LEMMA) 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 + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [absolutely_integrable_on]) THEN + DISCH_THEN(MP_TAC o CONJUNCT2) THEN + REWRITE_TAC[HAS_INTEGRAL_INTEGRAL; has_integral] THEN + DISCH_THEN(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 "A"))) THEN + MP_TAC(ISPECL + [`\x. (d1:real^M->real^M->bool) x INTER d2 x`; + `a:real^M`; `b:real^M`] + FINE_DIVISION_EXISTS) THEN + ASM_SIMP_TAC[GAUGE_INTER; FINE_INTER] THEN + DISCH_THEN(X_CHOOSE_THEN `p:real^M#(real^M->bool)->bool` + STRIP_ASSUME_TAC) THEN + REMOVE_THEN "A" (MP_TAC o SPEC `p:real^M#(real^M->bool)->bool`) THEN + REMOVE_THEN "F" (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 + MP_TAC(ISPECL + [`\x. lift(norm((f:real^M->real^N) x))`; + `a:real^M`; `b:real^M`; `p:real^M#(real^M->bool)->bool`] + INTEGRAL_COMBINE_TAGGED_DIVISION_TOPDOWN) THEN + ANTS_TAC THENL + [RULE_ASSUM_TAC(REWRITE_RULE[absolutely_integrable_on]) THEN + ASM_REWRITE_TAC[]; + DISCH_THEN SUBST_ALL_TAC] THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP TAGGED_DIVISION_OF_FINITE) THEN + DISCH_TAC THEN + SUBGOAL_THEN + `abs(sum p (\(x,k). content k * norm((f:real^M->real^N) x)) - + sum p (\(x,k:real^M->bool). norm(integral k f))) < e / &2` + MP_TAC THENL + [FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ_ALT] + REAL_LET_TRANS)) THEN + ASM_SIMP_TAC[GSYM SUM_SUB] THEN MATCH_MP_TAC SUM_ABS_LE THEN + ASM_REWRITE_TAC[FORALL_PAIR_THM] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC(NORM_ARITH + `x = norm u ==> abs(x - norm v) <= norm(u - v:real^N)`) THEN + REWRITE_TAC[NORM_MUL; real_abs] THEN + ASM_MESON_TAC[CONTENT_POS_LE; TAGGED_DIVISION_OF]; + ALL_TAC] THEN + ONCE_REWRITE_TAC[GSYM NORM_LIFT] THEN + ASM_SIMP_TAC[LIFT_SUB; LIFT_SUM] THEN + REWRITE_TAC[LAMBDA_PAIR_THM; o_DEF; LIFT_CMUL; IMP_IMP] THEN + DISCH_THEN(MP_TAC o MATCH_MP (NORM_ARITH + `norm(x - y:real^N) < e / &2 /\ norm(x - z) < e / &2 + ==> norm(y - z) < e`)) THEN + REWRITE_TAC[NORM_1; DROP_SUB] THEN + DISCH_THEN(MP_TAC o SPEC `B:real` o MATCH_MP + (REAL_ARITH `!B. abs(x - y) < e ==> y - B = e ==> &0 < x - B`)) THEN + ASM_REWRITE_TAC[] THEN ASM_SIMP_TAC[DROP_VSUM; REAL_SUB_LT] THEN + REWRITE_TAC[o_DEF; LAMBDA_PAIR_THM; LIFT_DROP] THEN DISCH_TAC THEN + EXISTS_TAC `IMAGE SND (p:real^M#(real^M->bool)->bool)` THEN CONJ_TAC THENL + [EXISTS_TAC `interval[a:real^M,b]` THEN + ASM_SIMP_TAC[DIVISION_OF_TAGGED_DIVISION; SUBSET_REFL]; + FIRST_ASSUM(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 (rand o rand) th o rand o snd)) THEN + SIMP_TAC[INTEGRAL_NULL; NORM_0] THEN + DISCH_THEN(SUBST1_TAC o SYM) THEN ASM_REWRITE_TAC[]]]);; + +let ABSOLUTELY_INTEGRABLE_RESTRICT_UNIV = prove + (`!f s. (\x. if x IN s then f x else vec 0) + absolutely_integrable_on (:real^M) <=> + f absolutely_integrable_on s`, + REWRITE_TAC[absolutely_integrable_on; INTEGRABLE_RESTRICT_UNIV; + COND_RAND; NORM_0; LIFT_NUM]);; + +let ABSOLUTELY_INTEGRABLE_CONST = prove + (`!a b c. (\x. c) absolutely_integrable_on interval[a,b]`, + REWRITE_TAC[absolutely_integrable_on; INTEGRABLE_CONST]);; + +let ABSOLUTELY_INTEGRABLE_ADD = prove + (`!f:real^M->real^N g s. + f absolutely_integrable_on s /\ + g absolutely_integrable_on s + ==> (\x. f(x) + g(x)) absolutely_integrable_on s`, + SUBGOAL_THEN + `!f:real^M->real^N g. + f absolutely_integrable_on (:real^M) /\ + g absolutely_integrable_on (:real^M) + ==> (\x. f(x) + g(x)) absolutely_integrable_on (:real^M)` + ASSUME_TAC THENL + [ALL_TAC; + ONCE_REWRITE_TAC[GSYM ABSOLUTELY_INTEGRABLE_RESTRICT_UNIV] THEN + REPEAT GEN_TAC THEN DISCH_THEN(ANTE_RES_THEN MP_TAC) THEN + REWRITE_TAC[] THEN MATCH_MP_TAC EQ_IMP THEN + AP_THM_TAC THEN AP_TERM_TAC THEN REWRITE_TAC[FUN_EQ_THM] THEN + GEN_TAC THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[VECTOR_ADD_LID]] THEN + REPEAT STRIP_TAC THEN + EVERY_ASSUM(STRIP_ASSUME_TAC o + GEN_REWRITE_RULE I [absolutely_integrable_on]) THEN + MATCH_MP_TAC BOUNDED_SETVARIATION_ABSOLUTELY_INTEGRABLE THEN + ASM_SIMP_TAC[INTEGRABLE_ADD] THEN + MP_TAC(ISPECL [`g:real^M->real^N`; `(:real^M)`] + ABSOLUTELY_INTEGRABLE_BOUNDED_SETVARIATION) THEN + MP_TAC(ISPECL [`f:real^M->real^N`; `(:real^M)`] + ABSOLUTELY_INTEGRABLE_BOUNDED_SETVARIATION) THEN + ASM_REWRITE_TAC[HAS_BOUNDED_SETVARIATION_ON_UNIV] THEN + DISCH_THEN(X_CHOOSE_TAC `B1:real`) THEN + DISCH_THEN(X_CHOOSE_TAC `B2:real`) THEN EXISTS_TAC `B1 + B2:real` THEN + X_GEN_TAC `d:(real^M->bool)->bool` THEN DISCH_TAC THEN + REPEAT(FIRST_X_ASSUM(MP_TAC o SPEC `d:(real^M->bool)->bool`)) THEN + ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH + `a <= B1 ==> x <= a + B2 ==> x <= B1 + B2`)) THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH + `b <= B2 ==> x <= a + b ==> x <= a + B2`)) THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP DIVISION_OF_FINITE) THEN + ASM_SIMP_TAC[GSYM SUM_ADD] THEN MATCH_MP_TAC SUM_LE THEN + FIRST_ASSUM(fun t -> ASM_REWRITE_TAC[MATCH_MP FORALL_IN_DIVISION t]) THEN + MAP_EVERY X_GEN_TAC [`a:real^M`; `b:real^M`] THEN STRIP_TAC THEN + MATCH_MP_TAC(NORM_ARITH `x = y + z ==> norm(x) <= norm(y) + norm(z)`) THEN + MATCH_MP_TAC INTEGRAL_ADD THEN CONJ_TAC THEN + MATCH_MP_TAC INTEGRABLE_ON_SUBINTERVAL THEN + EXISTS_TAC `(:real^M)` THEN ASM_REWRITE_TAC[SUBSET_UNIV]);; + +let ABSOLUTELY_INTEGRABLE_SUB = prove + (`!f:real^M->real^N g s. + f absolutely_integrable_on s /\ + g absolutely_integrable_on s + ==> (\x. f(x) - g(x)) absolutely_integrable_on s`, + REWRITE_TAC[VECTOR_SUB] THEN + SIMP_TAC[ABSOLUTELY_INTEGRABLE_ADD; ABSOLUTELY_INTEGRABLE_NEG]);; + +let ABSOLUTELY_INTEGRABLE_LINEAR = prove + (`!f:real^M->real^N h:real^N->real^P s. + f absolutely_integrable_on s /\ linear h + ==> (h o f) absolutely_integrable_on s`, + SUBGOAL_THEN + `!f:real^M->real^N h:real^N->real^P. + f absolutely_integrable_on (:real^M) /\ linear h + ==> (h o f) absolutely_integrable_on (:real^M)` + ASSUME_TAC THENL + [ALL_TAC; + ONCE_REWRITE_TAC[GSYM ABSOLUTELY_INTEGRABLE_RESTRICT_UNIV] THEN + REPEAT GEN_TAC THEN DISCH_THEN(fun th -> + ANTE_RES_THEN MP_TAC th THEN + ASSUME_TAC(MATCH_MP LINEAR_0 (CONJUNCT2 th))) THEN + ASM_REWRITE_TAC[o_DEF; COND_RAND]] THEN + REPEAT STRIP_TAC THEN + MATCH_MP_TAC BOUNDED_SETVARIATION_ABSOLUTELY_INTEGRABLE THEN + FIRST_ASSUM(MP_TAC o + MATCH_MP ABSOLUTELY_INTEGRABLE_BOUNDED_SETVARIATION) THEN + RULE_ASSUM_TAC(REWRITE_RULE[absolutely_integrable_on]) THEN + ASM_SIMP_TAC[INTEGRABLE_LINEAR; HAS_BOUNDED_SETVARIATION_ON_UNIV] THEN + FIRST_ASSUM(X_CHOOSE_THEN `B:real` STRIP_ASSUME_TAC o MATCH_MP + LINEAR_BOUNDED_POS) THEN + DISCH_THEN(X_CHOOSE_TAC `b:real`) THEN EXISTS_TAC `B * b:real` THEN + X_GEN_TAC `d:(real^M->bool)->bool` THEN DISCH_TAC THEN + MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `B * sum d (\k. norm(integral k (f:real^M->real^N)))` THEN + ASM_SIMP_TAC[REAL_LE_LMUL_EQ] THEN REWRITE_TAC[GSYM SUM_LMUL] THEN + MATCH_MP_TAC SUM_LE THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP DIVISION_OF_FINITE) THEN + FIRST_ASSUM(fun t -> ASM_REWRITE_TAC[MATCH_MP FORALL_IN_DIVISION t]) THEN + MAP_EVERY X_GEN_TAC [`a:real^M`; `b:real^M`] THEN DISCH_TAC THEN + MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `norm(h(integral (interval[a,b]) (f:real^M->real^N)):real^P)` THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC REAL_EQ_IMP_LE THEN AP_TERM_TAC THEN + MATCH_MP_TAC INTEGRAL_UNIQUE THEN MATCH_MP_TAC HAS_INTEGRAL_LINEAR THEN + ASM_REWRITE_TAC[GSYM HAS_INTEGRAL_INTEGRAL] THEN + MATCH_MP_TAC INTEGRABLE_ON_SUBINTERVAL THEN + EXISTS_TAC `(:real^M)` THEN ASM_REWRITE_TAC[SUBSET_UNIV]);; + +let ABSOLUTELY_INTEGRABLE_VSUM = prove + (`!f:A->real^M->real^N s t. + FINITE t /\ + (!a. a IN t ==> (f a) absolutely_integrable_on s) + ==> (\x. vsum t (\a. f a x)) absolutely_integrable_on s`, + GEN_TAC THEN GEN_TAC THEN REWRITE_TAC[IMP_CONJ] THEN + MATCH_MP_TAC FINITE_INDUCT_STRONG THEN + SIMP_TAC[VSUM_CLAUSES; ABSOLUTELY_INTEGRABLE_0; IN_INSERT; + ABSOLUTELY_INTEGRABLE_ADD; ETA_AX]);; + +let ABSOLUTELY_INTEGRABLE_ABS = prove + (`!f:real^M->real^N s. + f absolutely_integrable_on s + ==> (\x. (lambda i. abs(f(x)$i)):real^N) absolutely_integrable_on s`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN + `(\x. (lambda i. abs(f(x)$i))):real^M->real^N = + (\x. vsum (1..dimindex(:N)) + (\i. (((\y. (lambda j. if j = i then drop y else &0)) o + (\x. lift(norm((lambda j. if j = i then x$i else &0):real^N))) o + (f:real^M->real^N)) x)))` + SUBST1_TAC THENL + [REWRITE_TAC[FUN_EQ_THM] THEN X_GEN_TAC `x:real^M` THEN + GEN_REWRITE_TAC I [CART_EQ] THEN + X_GEN_TAC `i:num` THEN STRIP_TAC THEN + ASM_SIMP_TAC[LAMBDA_BETA; VSUM_COMPONENT; o_THM] THEN + GEN_REWRITE_TAC (RAND_CONV o ONCE_DEPTH_CONV) [EQ_SYM_EQ] THEN + ASM_SIMP_TAC[SUM_DELTA; IN_NUMSEG; LIFT_DROP] THEN + GEN_REWRITE_TAC (RAND_CONV o ONCE_DEPTH_CONV) [EQ_SYM_EQ] THEN + REWRITE_TAC[vector_norm; dot] THEN MATCH_MP_TAC EQ_TRANS THEN + EXISTS_TAC `sqrt(sum (1..dimindex(:N)) + (\k. if k = i then ((f:real^M->real^N) x)$i pow 2 + else &0))` THEN + CONJ_TAC THENL + [ASM_REWRITE_TAC[SUM_DELTA; IN_NUMSEG; POW_2_SQRT_ABS]; ALL_TAC] THEN + AP_TERM_TAC THEN MATCH_MP_TAC SUM_EQ THEN + SIMP_TAC[IN_NUMSEG; LAMBDA_BETA] THEN + REPEAT STRIP_TAC THEN COND_CASES_TAC THEN + ASM_REWRITE_TAC[REAL_MUL_LZERO; REAL_POW_2]; + ALL_TAC] THEN + MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_VSUM THEN + REWRITE_TAC[IN_NUMSEG; FINITE_NUMSEG] THEN + REPEAT STRIP_TAC THEN REWRITE_TAC[ETA_AX] THEN + MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_LINEAR THEN CONJ_TAC THENL + [ALL_TAC; + SIMP_TAC[linear; CART_EQ; VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT; + LAMBDA_BETA] THEN + REPEAT STRIP_TAC THEN COND_CASES_TAC THEN + ASM_REWRITE_TAC[DROP_ADD; REAL_ADD_LID; DROP_CMUL; REAL_MUL_RZERO]] THEN + REWRITE_TAC[o_DEF] THEN MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_NORM THEN + SUBGOAL_THEN + `(\x. lambda j. if j = i then (f x:real^N)$i else &0):real^M->real^N = + (\x. lambda j. if j = i then x$i else &0) o f` + SUBST1_TAC THENL [REWRITE_TAC[o_DEF]; ALL_TAC] THEN + MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_LINEAR THEN ASM_REWRITE_TAC[] THEN + SIMP_TAC[linear; CART_EQ; VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT; + LAMBDA_BETA] THEN + REPEAT STRIP_TAC THEN COND_CASES_TAC THEN + ASM_REWRITE_TAC[REAL_MUL_RZERO; REAL_ADD_LID] THEN + FIRST_X_ASSUM SUBST_ALL_TAC THEN + ASM_SIMP_TAC[VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT]);; + +let ABSOLUTELY_INTEGRABLE_MAX = prove + (`!f:real^M->real^N g:real^M->real^N s. + f absolutely_integrable_on s /\ g absolutely_integrable_on s + ==> (\x. (lambda i. max (f(x)$i) (g(x)$i)):real^N) + absolutely_integrable_on s`, + REPEAT GEN_TAC THEN DISCH_TAC THEN + FIRST_ASSUM(MP_TAC o MATCH_MP ABSOLUTELY_INTEGRABLE_SUB) THEN + DISCH_THEN(MP_TAC o MATCH_MP ABSOLUTELY_INTEGRABLE_ABS) THEN + FIRST_ASSUM(MP_TAC o MATCH_MP ABSOLUTELY_INTEGRABLE_ADD) THEN + REWRITE_TAC[IMP_IMP] THEN + DISCH_THEN(MP_TAC o MATCH_MP ABSOLUTELY_INTEGRABLE_ADD) THEN + DISCH_THEN(MP_TAC o SPEC `inv(&2)` o + MATCH_MP ABSOLUTELY_INTEGRABLE_CMUL) THEN + MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_TERM_TAC THEN + REWRITE_TAC[FUN_EQ_THM; CART_EQ] THEN + SIMP_TAC[LAMBDA_BETA; VECTOR_MUL_COMPONENT; VECTOR_SUB_COMPONENT; + VECTOR_ADD_COMPONENT] THEN + REPEAT STRIP_TAC THEN REAL_ARITH_TAC);; + +let ABSOLUTELY_INTEGRABLE_MAX_1 = prove + (`!f:real^M->real g:real^M->real s. + (\x. lift(f x)) absolutely_integrable_on s /\ + (\x. lift(g x)) absolutely_integrable_on s + ==> (\x. lift(max (f x) (g x))) absolutely_integrable_on s`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN `(\x. (lambda i. max (lift(f x)$i) (lift(g x)$i)):real^1) + absolutely_integrable_on (s:real^M->bool)` + MP_TAC THENL [ASM_SIMP_TAC[ABSOLUTELY_INTEGRABLE_MAX]; ALL_TAC] THEN + MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_TERM_TAC THEN + REWRITE_TAC[FUN_EQ_THM; CART_EQ] THEN SIMP_TAC[LAMBDA_BETA; lift]);; + +let ABSOLUTELY_INTEGRABLE_MIN = prove + (`!f:real^M->real^N g:real^M->real^N s. + f absolutely_integrable_on s /\ g absolutely_integrable_on s + ==> (\x. (lambda i. min (f(x)$i) (g(x)$i)):real^N) + absolutely_integrable_on s`, + REPEAT GEN_TAC THEN DISCH_TAC THEN + FIRST_ASSUM(MP_TAC o MATCH_MP ABSOLUTELY_INTEGRABLE_SUB) THEN + DISCH_THEN(MP_TAC o MATCH_MP ABSOLUTELY_INTEGRABLE_ABS) THEN + FIRST_ASSUM(MP_TAC o MATCH_MP ABSOLUTELY_INTEGRABLE_ADD) THEN + REWRITE_TAC[IMP_IMP] THEN + DISCH_THEN(MP_TAC o MATCH_MP ABSOLUTELY_INTEGRABLE_SUB) THEN + DISCH_THEN(MP_TAC o SPEC `inv(&2)` o + MATCH_MP ABSOLUTELY_INTEGRABLE_CMUL) THEN + MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_TERM_TAC THEN + REWRITE_TAC[FUN_EQ_THM; CART_EQ] THEN + SIMP_TAC[LAMBDA_BETA; VECTOR_MUL_COMPONENT; VECTOR_SUB_COMPONENT; + VECTOR_ADD_COMPONENT] THEN + REPEAT STRIP_TAC THEN REAL_ARITH_TAC);; + +let ABSOLUTELY_INTEGRABLE_MIN_1 = prove + (`!f:real^M->real g:real^M->real s. + (\x. lift(f x)) absolutely_integrable_on s /\ + (\x. lift(g x)) absolutely_integrable_on s + ==> (\x. lift(min (f x) (g x))) absolutely_integrable_on s`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN `(\x. (lambda i. min (lift(f x)$i) (lift(g x)$i)):real^1) + absolutely_integrable_on (s:real^M->bool)` + MP_TAC THENL [ASM_SIMP_TAC[ABSOLUTELY_INTEGRABLE_MIN]; ALL_TAC] THEN + MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_TERM_TAC THEN + REWRITE_TAC[FUN_EQ_THM; CART_EQ] THEN SIMP_TAC[LAMBDA_BETA; lift]);; + +let ABSOLUTELY_INTEGRABLE_ABS_EQ = prove + (`!f:real^M->real^N s. + f absolutely_integrable_on s <=> + f integrable_on s /\ + (\x. (lambda i. abs(f(x)$i)):real^N) integrable_on s`, + REPEAT GEN_TAC THEN EQ_TAC THEN + SIMP_TAC[ABSOLUTELY_INTEGRABLE_ABS; + ABSOLUTELY_INTEGRABLE_IMP_INTEGRABLE] THEN + SUBGOAL_THEN + `!f:real^M->real^N. + f integrable_on (:real^M) /\ + (\x. (lambda i. abs(f(x)$i)):real^N) integrable_on (:real^M) + ==> f absolutely_integrable_on (:real^M)` + ASSUME_TAC THENL + [ALL_TAC; + ONCE_REWRITE_TAC[GSYM ABSOLUTELY_INTEGRABLE_RESTRICT_UNIV; + GSYM INTEGRABLE_RESTRICT_UNIV] THEN + DISCH_THEN(fun th -> FIRST_X_ASSUM MATCH_MP_TAC THEN MP_TAC th) THEN + MATCH_MP_TAC MONO_AND THEN REWRITE_TAC[] THEN MATCH_MP_TAC EQ_IMP THEN + AP_THM_TAC THEN AP_TERM_TAC THEN REWRITE_TAC[FUN_EQ_THM] THEN + REWRITE_TAC[CART_EQ] THEN REPEAT STRIP_TAC THEN + ASM_SIMP_TAC[LAMBDA_BETA; COND_COMPONENT; VEC_COMPONENT] THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[REAL_ABS_0]] THEN + REPEAT STRIP_TAC THEN + MATCH_MP_TAC BOUNDED_SETVARIATION_ABSOLUTELY_INTEGRABLE THEN + ASM_REWRITE_TAC[HAS_BOUNDED_SETVARIATION_ON_UNIV] THEN + EXISTS_TAC + `sum (1..dimindex(:N)) + (\i. integral (:real^M) + (\x. (lambda j. abs ((f:real^M->real^N) x$j)):real^N)$i)` THEN + X_GEN_TAC `d:(real^M->bool)->bool` THEN DISCH_TAC THEN + MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `sum d (\k. sum (1..dimindex(:N)) + (\i. integral k + (\x. (lambda j. abs ((f:real^M->real^N) x$j)):real^N)$i))` THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP DIVISION_OF_FINITE) THEN CONJ_TAC THENL + [MATCH_MP_TAC SUM_LE THEN + FIRST_ASSUM(fun t -> ASM_REWRITE_TAC[MATCH_MP FORALL_IN_DIVISION t]) THEN + MAP_EVERY X_GEN_TAC [`a:real^M`; `b:real^M`] THEN DISCH_TAC THEN + MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `sum (1..dimindex(:N)) + (\i. abs((integral (interval[a,b]) (f:real^M->real^N))$i))` THEN + REWRITE_TAC[NORM_LE_L1] THEN MATCH_MP_TAC SUM_LE_NUMSEG THEN + X_GEN_TAC `k:num` THEN STRIP_TAC THEN REWRITE_TAC[] THEN + MATCH_MP_TAC(REAL_ARITH `x <= y /\ --x <= y ==> abs(x) <= y`) THEN + ASM_SIMP_TAC[GSYM VECTOR_NEG_COMPONENT] THEN + SUBGOAL_THEN `(f:real^M->real^N) integrable_on interval[a,b] /\ + (\x. (lambda i. abs (f x$i)):real^N) integrable_on interval[a,b]` + STRIP_ASSUME_TAC THENL + [CONJ_TAC THEN MATCH_MP_TAC INTEGRABLE_ON_SUBINTERVAL THEN + EXISTS_TAC `(:real^M)` THEN ASM_REWRITE_TAC[SUBSET_UNIV]; + ALL_TAC] THEN + ASM_SIMP_TAC[GSYM INTEGRAL_NEG] THEN + CONJ_TAC THEN MATCH_MP_TAC INTEGRAL_COMPONENT_LE THEN + ASM_SIMP_TAC[INTEGRABLE_NEG; LAMBDA_BETA] THEN + ASM_SIMP_TAC[VECTOR_NEG_COMPONENT] THEN + REPEAT STRIP_TAC THEN REAL_ARITH_TAC; + ALL_TAC] THEN + W(MP_TAC o PART_MATCH (lhs o rand) SUM_SWAP o lhand o snd) THEN + ASM_REWRITE_TAC[FINITE_NUMSEG] THEN DISCH_THEN SUBST_ALL_TAC THEN + MATCH_MP_TAC SUM_LE_NUMSEG THEN X_GEN_TAC `k:num` THEN STRIP_TAC THEN + REWRITE_TAC[] THEN + MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC + `(integral (UNIONS d) + (\x. (lambda j. abs ((f:real^M->real^N) x$j)):real^N))$k` THEN + CONJ_TAC THENL + [ASM_SIMP_TAC[GSYM VSUM_COMPONENT] THEN + MATCH_MP_TAC REAL_EQ_IMP_LE THEN AP_THM_TAC THEN AP_TERM_TAC THEN + CONV_TAC SYM_CONV THEN MATCH_MP_TAC INTEGRAL_COMBINE_DIVISION_TOPDOWN THEN + ASM_REWRITE_TAC[]; + MATCH_MP_TAC INTEGRAL_SUBSET_COMPONENT_LE THEN + ASM_SIMP_TAC[LAMBDA_BETA; SUBSET_UNIV; REAL_ABS_POS]] THEN + MATCH_MP_TAC INTEGRABLE_ON_SUBDIVISION THEN + MAP_EVERY EXISTS_TAC [`(:real^M)`; `d:(real^M->bool)->bool`] THEN + ASM_REWRITE_TAC[SUBSET_UNIV]);; + +let NONNEGATIVE_ABSOLUTELY_INTEGRABLE = prove + (`!f:real^M->real^N s. + (!x i. x IN s /\ 1 <= i /\ i <= dimindex(:N) + ==> &0 <= f(x)$i) /\ + f integrable_on s + ==> f absolutely_integrable_on s`, + SIMP_TAC[ABSOLUTELY_INTEGRABLE_ABS_EQ] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC INTEGRABLE_EQ THEN + EXISTS_TAC `f:real^M->real^N` THEN + ASM_SIMP_TAC[CART_EQ; LAMBDA_BETA; real_abs]);; + +let ABSOLUTELY_INTEGRABLE_INTEGRABLE_BOUND = prove + (`!f:real^M->real^N g s. + (!x. x IN s ==> norm(f x) <= drop(g x)) /\ + f integrable_on s /\ g integrable_on s + ==> f absolutely_integrable_on s`, + SUBGOAL_THEN + `!f:real^M->real^N g. + (!x. norm(f x) <= drop(g x)) /\ + f integrable_on (:real^M) /\ g integrable_on (:real^M) + ==> f absolutely_integrable_on (:real^M)` + ASSUME_TAC THENL + [ALL_TAC; + ONCE_REWRITE_TAC[GSYM INTEGRABLE_RESTRICT_UNIV; GSYM + ABSOLUTELY_INTEGRABLE_RESTRICT_UNIV] THEN + REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + EXISTS_TAC `(\x. if x IN s then g x else vec 0):real^M->real^1` THEN + ASM_REWRITE_TAC[] THEN GEN_TAC THEN COND_CASES_TAC THEN + ASM_SIMP_TAC[REAL_LE_REFL; NORM_0; DROP_VEC]] THEN + REPEAT STRIP_TAC THEN + MATCH_MP_TAC BOUNDED_SETVARIATION_ABSOLUTELY_INTEGRABLE THEN + ASM_REWRITE_TAC[HAS_BOUNDED_SETVARIATION_ON_UNIV] THEN + EXISTS_TAC `drop(integral(:real^M) g)` THEN + X_GEN_TAC `d:(real^M->bool)->bool` THEN DISCH_TAC THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP DIVISION_OF_FINITE) THEN + MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `sum d (\k. drop(integral k (g:real^M->real^1)))` THEN + CONJ_TAC THENL + [MATCH_MP_TAC SUM_LE THEN ASM_REWRITE_TAC[] THEN + FIRST_ASSUM(fun th -> REWRITE_TAC[MATCH_MP FORALL_IN_DIVISION th]) THEN + REPEAT STRIP_TAC THEN + MATCH_MP_TAC INTEGRAL_NORM_BOUND_INTEGRAL THEN ASM_REWRITE_TAC[] THEN + CONJ_TAC THEN MATCH_MP_TAC INTEGRABLE_ON_SUBINTERVAL THEN + EXISTS_TAC `(:real^M)` THEN ASM_REWRITE_TAC[SUBSET_UNIV]; + ALL_TAC] THEN + MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `drop(integral (UNIONS d:real^M->bool) g)` THEN CONJ_TAC THENL + [MATCH_MP_TAC(REAL_ARITH `x = y ==> y <= x`) THEN + ASM_SIMP_TAC[GSYM LIFT_EQ; LIFT_DROP; LIFT_SUM; o_DEF] THEN + MATCH_MP_TAC INTEGRAL_COMBINE_DIVISION_BOTTOMUP THEN + FIRST_ASSUM(fun th -> ASM_REWRITE_TAC[MATCH_MP FORALL_IN_DIVISION th]) THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC INTEGRABLE_ON_SUBINTERVAL THEN + EXISTS_TAC `(:real^M)` THEN ASM_REWRITE_TAC[SUBSET_UNIV]; + MATCH_MP_TAC INTEGRAL_SUBSET_DROP_LE THEN + ASM_REWRITE_TAC[SUBSET_UNIV; IN_UNIV] THEN CONJ_TAC THENL + [ALL_TAC; ASM_MESON_TAC[NORM_ARITH `norm(x) <= y ==> &0 <= y`]] THEN + MATCH_MP_TAC INTEGRABLE_ON_SUBDIVISION THEN + MAP_EVERY EXISTS_TAC [`(:real^M)`; `d:(real^M->bool)->bool`] THEN + ASM_REWRITE_TAC[SUBSET_UNIV]]);; + +let ABSOLUTELY_INTEGRABLE_ABSOLUTELY_INTEGRABLE_BOUND = prove + (`!f:real^M->real^N g:real^M->real^P s. + (!x. x IN s ==> norm(f x) <= norm(g x)) /\ + f integrable_on s /\ g absolutely_integrable_on s + ==> f absolutely_integrable_on s`, + REPEAT STRIP_TAC THEN + FIRST_X_ASSUM(STRIP_ASSUME_TAC o GEN_REWRITE_RULE I + [absolutely_integrable_on]) THEN + MP_TAC(ISPECL + [`f:real^M->real^N`; `(\x. lift(norm((g:real^M->real^P) x)))`; + `s:real^M->bool`] ABSOLUTELY_INTEGRABLE_INTEGRABLE_BOUND) THEN + ASM_REWRITE_TAC[LIFT_DROP]);; + +let ABSOLUTELY_INTEGRABLE_INF_1 = prove + (`!fs s:real^N->bool k:A->bool. + FINITE k /\ ~(k = {}) /\ + (!i. i IN k ==> (\x. lift(fs x i)) absolutely_integrable_on s) + ==> (\x. lift(inf (IMAGE (fs x) k))) absolutely_integrable_on s`, + GEN_TAC THEN GEN_TAC THEN REWRITE_TAC[IMP_CONJ] THEN + MATCH_MP_TAC FINITE_INDUCT_STRONG THEN REWRITE_TAC[IMAGE_CLAUSES] THEN + SIMP_TAC[INF_INSERT_FINITE; FINITE_IMAGE; IMAGE_EQ_EMPTY] THEN + MAP_EVERY X_GEN_TAC [`a:A`; `k:A->bool`] THEN + ASM_CASES_TAC `k:A->bool = {}` THEN ASM_REWRITE_TAC[] THEN + SIMP_TAC[IN_SING; LEFT_FORALL_IMP_THM; EXISTS_REFL] THEN + REWRITE_TAC[IMP_IMP; GSYM CONJ_ASSOC] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_MIN_1 THEN + CONJ_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN REWRITE_TAC[IN_INSERT] THEN + REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_REWRITE_TAC[IN_INSERT]);; + +let ABSOLUTELY_INTEGRABLE_SUP_1 = prove + (`!fs s:real^N->bool k:A->bool. + FINITE k /\ ~(k = {}) /\ + (!i. i IN k ==> (\x. lift(fs x i)) absolutely_integrable_on s) + ==> (\x. lift(sup (IMAGE (fs x) k))) absolutely_integrable_on s`, + GEN_TAC THEN GEN_TAC THEN REWRITE_TAC[IMP_CONJ] THEN + MATCH_MP_TAC FINITE_INDUCT_STRONG THEN REWRITE_TAC[IMAGE_CLAUSES] THEN + SIMP_TAC[SUP_INSERT_FINITE; FINITE_IMAGE; IMAGE_EQ_EMPTY] THEN + MAP_EVERY X_GEN_TAC [`a:A`; `k:A->bool`] THEN + ASM_CASES_TAC `k:A->bool = {}` THEN ASM_REWRITE_TAC[] THEN + SIMP_TAC[IN_SING; LEFT_FORALL_IMP_THM; EXISTS_REFL] THEN + REWRITE_TAC[IMP_IMP; GSYM CONJ_ASSOC] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_MAX_1 THEN + CONJ_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN REWRITE_TAC[IN_INSERT] THEN + REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_REWRITE_TAC[IN_INSERT]);; + +let ABSOLUTELY_INTEGRABLE_CONTINUOUS = prove + (`!f:real^M->real^N a b. + f continuous_on interval[a,b] + ==> f absolutely_integrable_on interval[a,b]`, + REPEAT STRIP_TAC THEN + MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_INTEGRABLE_BOUND THEN + SUBGOAL_THEN `compact(IMAGE (f:real^M->real^N) (interval[a,b]))` MP_TAC THENL + [ASM_SIMP_TAC[COMPACT_CONTINUOUS_IMAGE; COMPACT_INTERVAL]; ALL_TAC] THEN + DISCH_THEN(MP_TAC o MATCH_MP COMPACT_IMP_BOUNDED) THEN + REWRITE_TAC[BOUNDED_POS; FORALL_IN_IMAGE] THEN + DISCH_THEN(X_CHOOSE_THEN `B:real` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `\x:real^M. lift(B)` THEN + ASM_SIMP_TAC[INTEGRABLE_CONST; LIFT_DROP; INTEGRABLE_CONTINUOUS]);; + +let INTEGRABLE_MIN_CONST_1 = prove + (`!f s t. + &0 <= t /\ (!x. x IN s ==> &0 <= f x) /\ + (\x:real^N. lift(f x)) integrable_on s + ==> (\x. lift(min (f x) t)) integrable_on s`, + REPEAT STRIP_TAC THEN + MATCH_MP_TAC INTEGRABLE_ON_ALL_INTERVALS_INTEGRABLE_BOUND THEN + EXISTS_TAC `\x:real^N. lift(f x)` THEN ASM_REWRITE_TAC[] THEN CONJ_TAC THENL + [REPEAT GEN_TAC THEN + MP_TAC(ISPECL + [`\x:real^N. if x IN s then f x else &0`; + `(\x. t):real^N->real`; + `interval[a:real^N,b]`] ABSOLUTELY_INTEGRABLE_MIN_1) THEN + REWRITE_TAC[] THEN ANTS_TAC THENL + [SIMP_TAC[ABSOLUTELY_INTEGRABLE_CONTINUOUS; CONTINUOUS_ON_CONST] THEN + MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_ON_SUBINTERVAL THEN + EXISTS_TAC `(:real^N)` THEN REWRITE_TAC[SUBSET_UNIV] THEN + REWRITE_TAC[COND_RAND; LIFT_DROP; LIFT_NUM] THEN + REWRITE_TAC[ABSOLUTELY_INTEGRABLE_RESTRICT_UNIV] THEN + MATCH_MP_TAC NONNEGATIVE_ABSOLUTELY_INTEGRABLE THEN + ASM_SIMP_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN + ASM_REWRITE_TAC[IMP_IMP; DIMINDEX_1; FORALL_1; LIFT_DROP; GSYM drop]; + DISCH_THEN(MP_TAC o MATCH_MP ABSOLUTELY_INTEGRABLE_IMP_INTEGRABLE) THEN + MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_TERM_TAC THEN + REWRITE_TAC[FUN_EQ_THM] THEN GEN_TAC THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN + REWRITE_TAC[GSYM DROP_EQ; DROP_VEC; LIFT_DROP] THEN ASM_REAL_ARITH_TAC]; + X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `x:real^N`) THEN + ASM_REWRITE_TAC[NORM_REAL; GSYM drop; LIFT_DROP] THEN + ASM_REAL_ARITH_TAC]);; + +let ABSOLUTELY_INTEGRABLE_ABSOLUTELY_INTEGRABLE_COMPONENT_UBOUND = prove + (`!f:real^M->real^N g:real^M->real^N s. + (!x i. x IN s /\ 1 <= i /\ i <= dimindex(:N) ==> f(x)$i <= g(x)$i) /\ + f integrable_on s /\ g absolutely_integrable_on s + ==> f absolutely_integrable_on s`, + REPEAT STRIP_TAC THEN SUBGOAL_THEN + `(\x. (g:real^M->real^N)(x) - (g(x) - f(x))) absolutely_integrable_on s` + MP_TAC THENL + [MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_SUB THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC NONNEGATIVE_ABSOLUTELY_INTEGRABLE THEN + ASM_REWRITE_TAC[REAL_SUB_LE; VECTOR_SUB_COMPONENT] THEN + MATCH_MP_TAC INTEGRABLE_SUB THEN + ASM_SIMP_TAC[ABSOLUTELY_INTEGRABLE_IMP_INTEGRABLE]; + REWRITE_TAC[VECTOR_ARITH `x - (x - y):real^N = y`; ETA_AX]]);; + +let ABSOLUTELY_INTEGRABLE_ABSOLUTELY_INTEGRABLE_COMPONENT_LBOUND = prove + (`!f:real^M->real^N g:real^M->real^N s. + (!x i. x IN s /\ 1 <= i /\ i <= dimindex(:N) ==> f(x)$i <= g(x)$i) /\ + f absolutely_integrable_on s /\ g integrable_on s + ==> g absolutely_integrable_on s`, + REPEAT STRIP_TAC THEN SUBGOAL_THEN + `(\x. (f:real^M->real^N)(x) + (g(x) - f(x))) absolutely_integrable_on s` + MP_TAC THENL + [MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_ADD THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC NONNEGATIVE_ABSOLUTELY_INTEGRABLE THEN + ASM_REWRITE_TAC[REAL_SUB_LE; VECTOR_SUB_COMPONENT] THEN + MATCH_MP_TAC INTEGRABLE_SUB THEN + ASM_SIMP_TAC[ABSOLUTELY_INTEGRABLE_IMP_INTEGRABLE]; + REWRITE_TAC[VECTOR_ARITH `y + (x - y):real^N = x`; ETA_AX]]);; + +let ABSOLUTELY_INTEGRABLE_ABSOLUTELY_INTEGRABLE_DROP_UBOUND = prove + (`!f:real^M->real^1 g:real^M->real^1 s. + (!x. x IN s ==> drop(f(x)) <= drop(g(x))) /\ + f integrable_on s /\ g absolutely_integrable_on s + ==> f absolutely_integrable_on s`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC + ABSOLUTELY_INTEGRABLE_ABSOLUTELY_INTEGRABLE_COMPONENT_UBOUND THEN + EXISTS_TAC `g:real^M->real^1` THEN + ASM_REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN + ASM_REWRITE_TAC[IMP_IMP; FORALL_1; DIMINDEX_1; GSYM drop]);; + +let ABSOLUTELY_INTEGRABLE_ABSOLUTELY_INTEGRABLE_DROP_LBOUND = prove + (`!f:real^M->real^1 g:real^M->real^1 s. + (!x. x IN s ==> drop(f(x)) <= drop(g(x))) /\ + f absolutely_integrable_on s /\ g integrable_on s + ==> g absolutely_integrable_on s`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC + ABSOLUTELY_INTEGRABLE_ABSOLUTELY_INTEGRABLE_COMPONENT_LBOUND THEN + EXISTS_TAC `f:real^M->real^1` THEN + ASM_REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN + ASM_REWRITE_TAC[IMP_IMP; FORALL_1; DIMINDEX_1; GSYM drop]);; + +(* ------------------------------------------------------------------------- *) +(* Relating vector integrals to integrals of components. *) +(* ------------------------------------------------------------------------- *) + +let HAS_INTEGRAL_COMPONENTWISE = prove + (`!f:real^M->real^N s y. + (f has_integral y) s <=> + !i. 1 <= i /\ i <= dimindex(:N) + ==> ((\x. lift((f x)$i)) has_integral (lift(y$i))) s`, + REPEAT GEN_TAC THEN EQ_TAC THEN REPEAT STRIP_TAC THENL + [FIRST_X_ASSUM(MP_TAC o ISPEC `\u:real^N. lift(u$i)` o + MATCH_MP (REWRITE_RULE[IMP_CONJ] HAS_INTEGRAL_LINEAR)) THEN + REWRITE_TAC[o_DEF] THEN DISCH_THEN MATCH_MP_TAC THEN + REWRITE_TAC[LINEAR_LIFT_COMPONENT]; + GEN_REWRITE_TAC (RATOR_CONV o LAND_CONV) [GSYM ETA_AX] THEN + GEN_REWRITE_TAC LAND_CONV [GSYM BASIS_EXPANSION] THEN + GEN_REWRITE_TAC (RATOR_CONV o LAND_CONV o BINDER_CONV) + [GSYM BASIS_EXPANSION] THEN + MATCH_MP_TAC HAS_INTEGRAL_VSUM THEN + REWRITE_TAC[FINITE_NUMSEG; IN_NUMSEG] THEN + X_GEN_TAC `i:num` THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `i:num`) THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(MP_TAC o ISPEC `\v. drop(v) % (basis i:real^N)` o + MATCH_MP (REWRITE_RULE[IMP_CONJ] HAS_INTEGRAL_LINEAR)) THEN + SIMP_TAC[o_DEF; LIFT_DROP; LINEAR_VMUL_DROP; LINEAR_ID]]);; + +let INTEGRABLE_COMPONENTWISE = prove + (`!f:real^M->real^N s. + f integrable_on s <=> + !i. 1 <= i /\ i <= dimindex(:N) + ==> (\x. lift((f x)$i)) integrable_on s`, + REPEAT GEN_TAC THEN REWRITE_TAC[integrable_on] THEN + GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) + [HAS_INTEGRAL_COMPONENTWISE] THEN + REWRITE_TAC[GSYM LAMBDA_SKOLEM; GSYM EXISTS_LIFT]);; + +let LIFT_INTEGRAL_COMPONENT = prove + (`!f:real^M->real^N. + f integrable_on s + ==> lift((integral s f)$k) = integral s (\x. lift((f x)$k))`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN `?j. 1 <= j /\ j <= dimindex(:N) /\ !z:real^N. z$k = z$j` + CHOOSE_TAC THENL [REWRITE_TAC[FINITE_INDEX_INRANGE]; ALL_TAC] THEN + ASM_REWRITE_TAC[] THEN CONV_TAC SYM_CONV THEN + MATCH_MP_TAC INTEGRAL_UNIQUE THEN + FIRST_X_ASSUM(MP_TAC o MATCH_MP INTEGRABLE_INTEGRAL) THEN + GEN_REWRITE_TAC LAND_CONV [HAS_INTEGRAL_COMPONENTWISE] THEN + ASM_SIMP_TAC[]);; + +let INTEGRAL_COMPONENT = prove + (`!f:real^M->real^N. + f integrable_on s + ==> (integral s f)$k = drop(integral s (\x. lift((f x)$k)))`, + SIMP_TAC[GSYM LIFT_INTEGRAL_COMPONENT; LIFT_DROP]);; + +let ABSOLUTELY_INTEGRABLE_COMPONENTWISE = prove + (`!f:real^M->real^N s. + f absolutely_integrable_on s <=> + (!i. 1 <= i /\ i <= dimindex(:N) + ==> (\x. lift(f x$i)) absolutely_integrable_on s)`, + REPEAT GEN_TAC THEN REWRITE_TAC[absolutely_integrable_on] THEN + MATCH_MP_TAC(MESON[] + `(p <=> !i. a i ==> P i) /\ + (p /\ (!i. a i ==> P i) ==> (q <=> (!i. a i ==> Q i))) + ==> (p /\ q <=> (!i. a i ==> P i /\ Q i))`) THEN + CONJ_TAC THENL [REWRITE_TAC[GSYM INTEGRABLE_COMPONENTWISE]; ALL_TAC] THEN + REPEAT(STRIP_TAC ORELSE EQ_TAC) THENL + [SUBGOAL_THEN + `(\x. lift((f:real^M->real^N) x$i)) absolutely_integrable_on s` + MP_TAC THENL [ALL_TAC; SIMP_TAC[absolutely_integrable_on]] THEN + MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_INTEGRABLE_BOUND THEN + EXISTS_TAC `\x. lift(norm((f:real^M->real^N) x))` THEN + ASM_SIMP_TAC[ABS_DROP; LIFT_DROP; COMPONENT_LE_NORM]; + SUBGOAL_THEN + `(f:real^M->real^N) absolutely_integrable_on s` + MP_TAC THENL [ALL_TAC; SIMP_TAC[absolutely_integrable_on]] THEN + MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_INTEGRABLE_BOUND THEN + EXISTS_TAC + `\x. vsum (1..dimindex(:N)) + (\i. lift(norm(lift((f:real^M->real^N)(x)$i))))` THEN + ASM_SIMP_TAC[INTEGRABLE_VSUM; IN_NUMSEG; FINITE_NUMSEG] THEN + SIMP_TAC[DROP_VSUM; FINITE_NUMSEG; o_DEF; LIFT_DROP] THEN + REWRITE_TAC[NORM_LIFT; NORM_LE_L1]]);; + +(* ------------------------------------------------------------------------- *) +(* Dominated convergence. *) +(* ------------------------------------------------------------------------- *) + +let DOMINATED_CONVERGENCE = prove + (`!f:num->real^M->real^N g h s. + (!k. (f k) integrable_on s) /\ h integrable_on s /\ + (!k x. x IN s ==> norm(f k x) <= drop(h x)) /\ + (!x. x IN s ==> ((\k. f k x) --> g x) sequentially) + ==> g integrable_on s /\ + ((\k. integral s (f k)) --> integral s g) sequentially`, + SUBGOAL_THEN + `!f:num->real^M->real^1 g h s. + (!k. (f k) integrable_on s) /\ h integrable_on s /\ + (!k x. x IN s ==> norm(f k x) <= drop(h x)) /\ + (!x. x IN s ==> ((\k. f k x) --> g x) sequentially) + ==> g integrable_on s /\ + ((\k. integral s (f k)) --> integral s g) sequentially` + ASSUME_TAC THENL + [ALL_TAC; + REPEAT GEN_TAC THEN STRIP_TAC THEN + SUBGOAL_THEN + `!j. 1 <= j /\ j <= dimindex(:N) + ==> (\x. lift((g x)$j)) integrable_on s /\ + ((\k. integral s (\x. lift (((f:num->real^M->real^N) k x)$j))) + --> integral s (\x. lift ((g x:real^N)$j))) sequentially` + STRIP_ASSUME_TAC THENL + [REPEAT GEN_TAC THEN STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + EXISTS_TAC `h:real^M->real^1` THEN ASM_REWRITE_TAC[] THEN + REPEAT CONJ_TAC THENL + [FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE BINDER_CONV + [INTEGRABLE_COMPONENTWISE]) THEN + ASM_SIMP_TAC[]; + MAP_EVERY X_GEN_TAC [`i:num`; `x:real^M`] THEN DISCH_TAC THEN + MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `norm((f:num->real^M->real^N) i x)` THEN + ASM_SIMP_TAC[NORM_LIFT; COMPONENT_LE_NORM]; + X_GEN_TAC `x:real^M` THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `x:real^M`) THEN ASM_REWRITE_TAC[] THEN + GEN_REWRITE_TAC LAND_CONV [LIM_COMPONENTWISE_LIFT] THEN + ASM_SIMP_TAC[]]; + MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN CONJ_TAC THENL + [GEN_REWRITE_TAC I [INTEGRABLE_COMPONENTWISE] THEN ASM_SIMP_TAC[]; + DISCH_TAC THEN ONCE_REWRITE_TAC[LIM_COMPONENTWISE_LIFT] THEN + ASM_SIMP_TAC[LIFT_INTEGRAL_COMPONENT]]]] THEN + REPEAT GEN_TAC THEN STRIP_TAC THEN + MP_TAC(MATCH_MP MONO_FORALL (GEN `m:num` + (ISPECL [`\k:num x:real^M. lift(inf {drop(f j x) | j IN m..(m+k)})`; + `\x:real^M. lift(inf {drop(f j x) | m:num <= j})`; + `s:real^M->bool`] + MONOTONE_CONVERGENCE_DECREASING))) THEN + REWRITE_TAC[LIFT_DROP] THEN ANTS_TAC THENL + [X_GEN_TAC `m:num` THEN REPEAT CONJ_TAC THENL + [GEN_TAC THEN MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_IMP_INTEGRABLE THEN + ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN + MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_INF_1 THEN + REWRITE_TAC[FINITE_NUMSEG; NUMSEG_EMPTY; NOT_LT; LE_ADD] THEN + ASM_REWRITE_TAC[LIFT_DROP; ETA_AX] THEN + REPEAT STRIP_TAC THEN + MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_INTEGRABLE_BOUND THEN + EXISTS_TAC `h:real^M->real^1` THEN ASM_REWRITE_TAC[]; + + REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN + MATCH_MP_TAC REAL_LE_INF_SUBSET THEN + REWRITE_TAC[IMAGE_EQ_EMPTY; NUMSEG_EMPTY; NOT_LT; LE_ADD] THEN + CONJ_TAC THENL + [MATCH_MP_TAC IMAGE_SUBSET THEN + REWRITE_TAC[SUBSET_NUMSEG] THEN ARITH_TAC; + ALL_TAC] THEN + REWRITE_TAC[FORALL_IN_IMAGE] THEN + MATCH_MP_TAC LOWER_BOUND_FINITE_SET_REAL THEN + REWRITE_TAC[FINITE_NUMSEG]; + + X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN + REWRITE_TAC[LIM_SEQUENTIALLY] THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN + REWRITE_TAC[dist; ABS_DROP; LIFT_DROP; DROP_SUB] THEN + MP_TAC(SPEC `{drop((f:num->real^M->real^1) j x) | m <= j}` INF) THEN + ABBREV_TAC `i = inf {drop((f:num->real^M->real^1) j x) | m <= j}` THEN + ONCE_REWRITE_TAC[SIMPLE_IMAGE_GEN] THEN + REWRITE_TAC[FORALL_IN_IMAGE; EXISTS_IN_IMAGE; IMAGE_EQ_EMPTY] THEN + REWRITE_TAC[IN_ELIM_THM; EXTENSION; NOT_IN_EMPTY] THEN ANTS_TAC THENL + [CONJ_TAC THENL [MESON_TAC[LE_REFL]; ALL_TAC] THEN + EXISTS_TAC `--drop(h(x:real^M))` THEN X_GEN_TAC `j:num` THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`j:num`; `x:real^M`]) THEN + ASM_REWRITE_TAC[ABS_DROP] THEN REAL_ARITH_TAC; + ALL_TAC] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC (MP_TAC o SPEC `i + e:real`)) THEN + ASM_SIMP_TAC[REAL_ARITH `&0 < e ==> ~(i + e <= i)`] THEN + REWRITE_TAC[NOT_FORALL_THM; NOT_IMP; REAL_NOT_LE] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `M:num` THEN STRIP_TAC THEN + X_GEN_TAC `n:num` THEN DISCH_TAC THEN + FIRST_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH + `y < i + e ==> i <= ix /\ ix <= y ==> abs(ix - i) < e`)) THEN + CONJ_TAC THENL + [EXPAND_TAC "i" THEN MATCH_MP_TAC REAL_LE_INF_SUBSET THEN + REWRITE_TAC[IMAGE_EQ_EMPTY; SET_RULE `{x | x IN s} = s`] THEN + REWRITE_TAC[NUMSEG_EMPTY; NOT_LT; LE_ADD] THEN + ONCE_REWRITE_TAC[SIMPLE_IMAGE_GEN] THEN CONJ_TAC THENL + [MATCH_MP_TAC IMAGE_SUBSET THEN + REWRITE_TAC[SUBSET; IN_NUMSEG; IN_ELIM_THM] THEN ARITH_TAC; + REWRITE_TAC[FORALL_IN_IMAGE; IN_ELIM_THM] THEN ASM_MESON_TAC[]]; + ALL_TAC] THEN + W(MP_TAC o C SPEC INF o rand o lhand o snd) THEN ANTS_TAC THENL + [REWRITE_TAC[IMAGE_EQ_EMPTY; SET_RULE `{x | x IN s} = s`] THEN + REWRITE_TAC[NUMSEG_EMPTY; NOT_LT; LE_ADD] THEN + REWRITE_TAC[FORALL_IN_IMAGE; IN_ELIM_THM] THEN + EXISTS_TAC `i:real` THEN GEN_TAC THEN REWRITE_TAC[IN_NUMSEG] THEN + DISCH_THEN(fun th -> FIRST_ASSUM MATCH_MP_TAC THEN MP_TAC th) THEN + ARITH_TAC; + ALL_TAC] THEN + REWRITE_TAC[FORALL_IN_IMAGE] THEN + DISCH_THEN(MATCH_MP_TAC o CONJUNCT1) THEN + REWRITE_TAC[IN_ELIM_THM; IN_NUMSEG] THEN + ASM_ARITH_TAC; + + REWRITE_TAC[bounded] THEN + EXISTS_TAC `drop(integral s (h:real^M->real^1))` THEN + ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN + REWRITE_TAC[FORALL_IN_IMAGE; IN_UNIV] THEN + X_GEN_TAC `p:num` THEN MATCH_MP_TAC INTEGRAL_NORM_BOUND_INTEGRAL THEN + ASM_REWRITE_TAC[] THEN CONJ_TAC THENL + [MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_IMP_INTEGRABLE THEN + ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN + MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_INF_1 THEN + REWRITE_TAC[FINITE_NUMSEG; NUMSEG_EMPTY; NOT_LT; LE_ADD] THEN + ASM_REWRITE_TAC[LIFT_DROP; ETA_AX] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_INTEGRABLE_BOUND THEN + EXISTS_TAC `h:real^M->real^1` THEN ASM_REWRITE_TAC[]; + ALL_TAC] THEN + X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN + REWRITE_TAC[ABS_DROP; LIFT_DROP] THEN + MATCH_MP_TAC REAL_ABS_INF_LE THEN ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN + REWRITE_TAC[FORALL_IN_IMAGE; IMAGE_EQ_EMPTY] THEN + ASM_SIMP_TAC[NUMSEG_EMPTY; NOT_LT; LE_ADD; GSYM ABS_DROP]]; + REWRITE_TAC[FORALL_AND_THM] THEN STRIP_TAC] THEN + MP_TAC(MATCH_MP MONO_FORALL (GEN `m:num` + (ISPECL [`\k:num x:real^M. lift(sup {drop(f j x) | j IN m..(m+k)})`; + `\x:real^M. lift(sup {drop(f j x) | m:num <= j})`; + `s:real^M->bool`] + MONOTONE_CONVERGENCE_INCREASING))) THEN + REWRITE_TAC[LIFT_DROP] THEN ANTS_TAC THENL + [X_GEN_TAC `m:num` THEN REPEAT CONJ_TAC THENL + [GEN_TAC THEN MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_IMP_INTEGRABLE THEN + ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN + MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_SUP_1 THEN + REWRITE_TAC[FINITE_NUMSEG; NUMSEG_EMPTY; NOT_LT; LE_ADD] THEN + ASM_REWRITE_TAC[LIFT_DROP; ETA_AX] THEN + REPEAT STRIP_TAC THEN + MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_INTEGRABLE_BOUND THEN + EXISTS_TAC `h:real^M->real^1` THEN ASM_REWRITE_TAC[]; + + REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN + MATCH_MP_TAC REAL_SUP_LE_SUBSET THEN + REWRITE_TAC[IMAGE_EQ_EMPTY; NUMSEG_EMPTY; NOT_LT; LE_ADD] THEN + CONJ_TAC THENL + [MATCH_MP_TAC IMAGE_SUBSET THEN + REWRITE_TAC[SUBSET_NUMSEG] THEN ARITH_TAC; + ALL_TAC] THEN + REWRITE_TAC[FORALL_IN_IMAGE] THEN + MATCH_MP_TAC UPPER_BOUND_FINITE_SET_REAL THEN + REWRITE_TAC[FINITE_NUMSEG]; + + X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN + REWRITE_TAC[LIM_SEQUENTIALLY] THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN + REWRITE_TAC[dist; ABS_DROP; LIFT_DROP; DROP_SUB] THEN + MP_TAC(SPEC `{drop((f:num->real^M->real^1) j x) | m <= j}` SUP) THEN + ABBREV_TAC `i = sup {drop((f:num->real^M->real^1) j x) | m <= j}` THEN + ONCE_REWRITE_TAC[SIMPLE_IMAGE_GEN] THEN + REWRITE_TAC[FORALL_IN_IMAGE; EXISTS_IN_IMAGE; IMAGE_EQ_EMPTY] THEN + REWRITE_TAC[IN_ELIM_THM; EXTENSION; NOT_IN_EMPTY] THEN ANTS_TAC THENL + [CONJ_TAC THENL [MESON_TAC[LE_REFL]; ALL_TAC] THEN + EXISTS_TAC `drop(h(x:real^M))` THEN X_GEN_TAC `j:num` THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`j:num`; `x:real^M`]) THEN + ASM_REWRITE_TAC[ABS_DROP] THEN REAL_ARITH_TAC; + ALL_TAC] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC (MP_TAC o SPEC `i - e:real`)) THEN + ASM_SIMP_TAC[REAL_ARITH `&0 < e ==> ~(i <= i - e)`] THEN + REWRITE_TAC[NOT_FORALL_THM; NOT_IMP; REAL_NOT_LE] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `M:num` THEN STRIP_TAC THEN + X_GEN_TAC `n:num` THEN DISCH_TAC THEN + FIRST_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH + `i - e < y ==> ix <= i /\ y <= ix ==> abs(ix - i) < e`)) THEN + CONJ_TAC THENL + [EXPAND_TAC "i" THEN MATCH_MP_TAC REAL_SUP_LE_SUBSET THEN + REWRITE_TAC[IMAGE_EQ_EMPTY; SET_RULE `{x | x IN s} = s`] THEN + REWRITE_TAC[NUMSEG_EMPTY; NOT_LT; LE_ADD] THEN + ONCE_REWRITE_TAC[SIMPLE_IMAGE_GEN] THEN CONJ_TAC THENL + [MATCH_MP_TAC IMAGE_SUBSET THEN + REWRITE_TAC[SUBSET; IN_NUMSEG; IN_ELIM_THM] THEN ARITH_TAC; + REWRITE_TAC[FORALL_IN_IMAGE; IN_ELIM_THM] THEN ASM_MESON_TAC[]]; + ALL_TAC] THEN + W(MP_TAC o C SPEC SUP o rand o rand o snd) THEN ANTS_TAC THENL + [REWRITE_TAC[IMAGE_EQ_EMPTY; SET_RULE `{x | x IN s} = s`] THEN + REWRITE_TAC[NUMSEG_EMPTY; NOT_LT; LE_ADD] THEN + REWRITE_TAC[FORALL_IN_IMAGE; IN_ELIM_THM] THEN + EXISTS_TAC `i:real` THEN GEN_TAC THEN REWRITE_TAC[IN_NUMSEG] THEN + DISCH_THEN(fun th -> FIRST_ASSUM MATCH_MP_TAC THEN MP_TAC th) THEN + ARITH_TAC; + ALL_TAC] THEN + REWRITE_TAC[FORALL_IN_IMAGE] THEN + DISCH_THEN(MATCH_MP_TAC o CONJUNCT1) THEN + REWRITE_TAC[IN_ELIM_THM; IN_NUMSEG] THEN + ASM_ARITH_TAC; + + REWRITE_TAC[bounded] THEN + EXISTS_TAC `drop(integral s (h:real^M->real^1))` THEN + ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN + REWRITE_TAC[FORALL_IN_IMAGE; IN_UNIV] THEN + X_GEN_TAC `p:num` THEN MATCH_MP_TAC INTEGRAL_NORM_BOUND_INTEGRAL THEN + ASM_REWRITE_TAC[] THEN CONJ_TAC THENL + [MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_IMP_INTEGRABLE THEN + ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN + MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_SUP_1 THEN + REWRITE_TAC[FINITE_NUMSEG; NUMSEG_EMPTY; NOT_LT; LE_ADD] THEN + ASM_REWRITE_TAC[LIFT_DROP; ETA_AX] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_INTEGRABLE_BOUND THEN + EXISTS_TAC `h:real^M->real^1` THEN ASM_REWRITE_TAC[]; + ALL_TAC] THEN + X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN + REWRITE_TAC[ABS_DROP; LIFT_DROP] THEN + MATCH_MP_TAC REAL_ABS_SUP_LE THEN ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN + REWRITE_TAC[FORALL_IN_IMAGE; IMAGE_EQ_EMPTY] THEN + ASM_SIMP_TAC[NUMSEG_EMPTY; NOT_LT; LE_ADD; GSYM ABS_DROP]]; + REWRITE_TAC[FORALL_AND_THM] THEN STRIP_TAC] THEN + MP_TAC(ISPECL + [`\k:num x:real^M. lift(inf {drop(f j x) | k <= j})`; + `g:real^M->real^1`; + `s:real^M->bool`] + MONOTONE_CONVERGENCE_INCREASING) THEN + ASM_REWRITE_TAC[LIFT_DROP] THEN ANTS_TAC THENL + [ONCE_REWRITE_TAC[SIMPLE_IMAGE_GEN] THEN CONJ_TAC THENL + [REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_LE_INF_SUBSET THEN + REWRITE_TAC[IMAGE_EQ_EMPTY; SET_RULE `{x | x IN s} = s`] THEN + REWRITE_TAC[EXTENSION; IN_ELIM_THM; NOT_IN_EMPTY; NOT_LE] THEN + CONJ_TAC THENL [MESON_TAC[LT_REFL]; ALL_TAC] THEN CONJ_TAC THENL + [MATCH_MP_TAC IMAGE_SUBSET THEN + REWRITE_TAC[SUBSET; IN_NUMSEG; IN_ELIM_THM] THEN ARITH_TAC; + ALL_TAC] THEN + REWRITE_TAC[FORALL_IN_IMAGE; IN_ELIM_THM] THEN + EXISTS_TAC `--drop(h(x:real^M))` THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC(REAL_ARITH `abs(x) <= a ==> --a <= x`) THEN + ASM_SIMP_TAC[GSYM ABS_DROP]; + ALL_TAC] THEN + CONJ_TAC THENL + [X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `x:real^M`) THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[LIM_SEQUENTIALLY] THEN + DISCH_THEN(fun th -> X_GEN_TAC `e:real` THEN DISCH_TAC THEN + MP_TAC(SPEC `e / &2` th)) THEN + ASM_REWRITE_TAC[REAL_HALF] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `M:num` THEN + REWRITE_TAC[dist; ABS_DROP; DROP_SUB; LIFT_DROP] THEN + STRIP_TAC THEN X_GEN_TAC `n:num` THEN DISCH_TAC THEN + MATCH_MP_TAC(REAL_ARITH `&0 < e /\ x <= e / &2 ==> x < e`) THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC REAL_INF_ASCLOSE THEN + REWRITE_TAC[IMAGE_EQ_EMPTY; FORALL_IN_IMAGE; IN_ELIM_THM] THEN + CONJ_TAC THENL [ALL_TAC; ASM_MESON_TAC[LE_TRANS; REAL_LT_IMP_LE]] THEN + REWRITE_TAC[EXTENSION; NOT_IN_EMPTY; IN_ELIM_THM; NOT_FORALL_THM] THEN + MESON_TAC[LE_REFL]; + ALL_TAC] THEN + REWRITE_TAC[bounded; FORALL_IN_IMAGE; IN_ELIM_THM; IN_UNIV] THEN + EXISTS_TAC `drop(integral s (h:real^M->real^1))` THEN + X_GEN_TAC `p:num` THEN MATCH_MP_TAC INTEGRAL_NORM_BOUND_INTEGRAL THEN + ASM_REWRITE_TAC[] THEN X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN + REWRITE_TAC[ABS_DROP; LIFT_DROP] THEN + MATCH_MP_TAC REAL_ABS_INF_LE THEN ONCE_REWRITE_TAC[SIMPLE_IMAGE_GEN] THEN + REWRITE_TAC[FORALL_IN_IMAGE; IMAGE_EQ_EMPTY] THEN + ASM_SIMP_TAC[GSYM ABS_DROP; IN_ELIM_THM] THEN + REWRITE_TAC[EXTENSION; NOT_IN_EMPTY; IN_ELIM_THM; NOT_FORALL_THM] THEN + MESON_TAC[LE_REFL]; + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC (LABEL_TAC "A"))] THEN + MP_TAC(ISPECL + [`\k:num x:real^M. lift(sup {drop(f j x) | k <= j})`; + `g:real^M->real^1`; + `s:real^M->bool`] + MONOTONE_CONVERGENCE_DECREASING) THEN + ASM_REWRITE_TAC[LIFT_DROP] THEN ANTS_TAC THENL + [ONCE_REWRITE_TAC[SIMPLE_IMAGE_GEN] THEN CONJ_TAC THENL + [REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_SUP_LE_SUBSET THEN + REWRITE_TAC[IMAGE_EQ_EMPTY; SET_RULE `{x | x IN s} = s`] THEN + REWRITE_TAC[EXTENSION; IN_ELIM_THM; NOT_IN_EMPTY; NOT_LE] THEN + CONJ_TAC THENL [MESON_TAC[LT_REFL]; ALL_TAC] THEN CONJ_TAC THENL + [MATCH_MP_TAC IMAGE_SUBSET THEN + REWRITE_TAC[SUBSET; IN_NUMSEG; IN_ELIM_THM] THEN ARITH_TAC; + ALL_TAC] THEN + REWRITE_TAC[FORALL_IN_IMAGE; IN_ELIM_THM] THEN + EXISTS_TAC `drop(h(x:real^M))` THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC(REAL_ARITH `abs(x) <= a ==> x <= a`) THEN + ASM_SIMP_TAC[GSYM ABS_DROP]; + ALL_TAC] THEN + CONJ_TAC THENL + [X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `x:real^M`) THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[LIM_SEQUENTIALLY] THEN + DISCH_THEN(fun th -> X_GEN_TAC `e:real` THEN DISCH_TAC THEN + MP_TAC(SPEC `e / &2` th)) THEN + ASM_REWRITE_TAC[REAL_HALF] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `M:num` THEN + REWRITE_TAC[dist; ABS_DROP; DROP_SUB; LIFT_DROP] THEN + STRIP_TAC THEN X_GEN_TAC `n:num` THEN DISCH_TAC THEN + MATCH_MP_TAC(REAL_ARITH `&0 < e /\ x <= e / &2 ==> x < e`) THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC REAL_SUP_ASCLOSE THEN + REWRITE_TAC[IMAGE_EQ_EMPTY; FORALL_IN_IMAGE; IN_ELIM_THM] THEN + CONJ_TAC THENL [ALL_TAC; ASM_MESON_TAC[LE_TRANS; REAL_LT_IMP_LE]] THEN + REWRITE_TAC[EXTENSION; NOT_IN_EMPTY; IN_ELIM_THM; NOT_FORALL_THM] THEN + MESON_TAC[LE_REFL]; + ALL_TAC] THEN + REWRITE_TAC[bounded; FORALL_IN_IMAGE; IN_ELIM_THM; IN_UNIV] THEN + EXISTS_TAC `drop(integral s (h:real^M->real^1))` THEN + X_GEN_TAC `p:num` THEN MATCH_MP_TAC INTEGRAL_NORM_BOUND_INTEGRAL THEN + ASM_REWRITE_TAC[] THEN X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN + REWRITE_TAC[ABS_DROP; LIFT_DROP] THEN + MATCH_MP_TAC REAL_ABS_SUP_LE THEN ONCE_REWRITE_TAC[SIMPLE_IMAGE_GEN] THEN + REWRITE_TAC[FORALL_IN_IMAGE; IMAGE_EQ_EMPTY] THEN + ASM_SIMP_TAC[GSYM ABS_DROP; IN_ELIM_THM] THEN + REWRITE_TAC[EXTENSION; NOT_IN_EMPTY; IN_ELIM_THM; NOT_FORALL_THM] THEN + MESON_TAC[LE_REFL]; + DISCH_THEN(LABEL_TAC "B")] THEN + ASM_REWRITE_TAC[LIM_SEQUENTIALLY] THEN + X_GEN_TAC `e:real` THEN DISCH_TAC THEN + REMOVE_THEN "A" (MP_TAC o REWRITE_RULE[LIM_SEQUENTIALLY]) THEN + DISCH_THEN(MP_TAC o SPEC `e:real`) THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `N1:num` (LABEL_TAC "N1")) THEN + REMOVE_THEN "B" (MP_TAC o REWRITE_RULE[LIM_SEQUENTIALLY]) THEN + DISCH_THEN(MP_TAC o SPEC `e:real`) THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `N2:num` (LABEL_TAC "N2")) THEN + EXISTS_TAC `N1 + N2:num` THEN X_GEN_TAC `n:num` THEN DISCH_TAC THEN + REMOVE_THEN "N1" (MP_TAC o SPEC `n:num`) THEN + ANTS_TAC THENL + [ASM_MESON_TAC[ARITH_RULE `N1 + N2 <= n ==> N1:num <= n`]; ALL_TAC] THEN + REMOVE_THEN "N2" (MP_TAC o SPEC `n:num`) THEN + ANTS_TAC THENL + [ASM_MESON_TAC[ARITH_RULE `N1 + N2 <= n ==> N2:num <= n`]; ALL_TAC] THEN + REWRITE_TAC[dist; ABS_DROP; DROP_SUB; LIFT_DROP] THEN + MATCH_MP_TAC(REAL_ARITH + `i0 <= i /\ i <= i1 + ==> abs(i1 - g) < e ==> abs(i0 - g) < e ==> abs(i - g) < e`) THEN + CONJ_TAC THEN MATCH_MP_TAC INTEGRAL_DROP_LE THEN + ASM_REWRITE_TAC[LIFT_DROP] THEN X_GEN_TAC `x:real^M` THEN DISCH_TAC THENL + [W(MP_TAC o C SPEC INF o rand o lhand o snd) THEN + REWRITE_TAC[] THEN ONCE_REWRITE_TAC[SIMPLE_IMAGE_GEN] THEN + REWRITE_TAC[IMAGE_EQ_EMPTY; FORALL_IN_IMAGE; IN_ELIM_THM] THEN + ANTS_TAC THENL + [REWRITE_TAC[EXTENSION; NOT_IN_EMPTY; IN_ELIM_THM; NOT_FORALL_THM] THEN + CONJ_TAC THENL [MESON_TAC[LE_REFL]; ALL_TAC] THEN + EXISTS_TAC `--drop(h(x:real^M))` THEN GEN_TAC THEN DISCH_TAC THEN + MATCH_MP_TAC(REAL_ARITH `abs(x) <= a ==> --a <= x`) THEN + REWRITE_TAC[GSYM ABS_DROP] THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_REWRITE_TAC[]; + DISCH_THEN(MATCH_MP_TAC o CONJUNCT1) THEN REWRITE_TAC[LE_REFL]]; + W(MP_TAC o C SPEC SUP o rand o rand o snd) THEN + REWRITE_TAC[] THEN ONCE_REWRITE_TAC[SIMPLE_IMAGE_GEN] THEN + REWRITE_TAC[IMAGE_EQ_EMPTY; FORALL_IN_IMAGE; IN_ELIM_THM] THEN + ANTS_TAC THENL + [REWRITE_TAC[EXTENSION; NOT_IN_EMPTY; IN_ELIM_THM; NOT_FORALL_THM] THEN + CONJ_TAC THENL [MESON_TAC[LE_REFL]; ALL_TAC] THEN + EXISTS_TAC `drop(h(x:real^M))` THEN GEN_TAC THEN DISCH_TAC THEN + MATCH_MP_TAC(REAL_ARITH `abs(x) <= a ==> x <= a`) THEN + REWRITE_TAC[GSYM ABS_DROP] THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_REWRITE_TAC[]; + DISCH_THEN(MATCH_MP_TAC o CONJUNCT1) THEN REWRITE_TAC[LE_REFL]]]);; + +let DOMINATED_CONVERGENCE_INTEGRABLE = prove + (`!f:num->real^M->real^N g h s. + (!k. f k absolutely_integrable_on s) /\ + h integrable_on s /\ + (!k x. x IN s ==> norm(g x) <= drop(h x)) /\ + (!x. x IN s ==> ((\k. f k x) --> g x) sequentially) + ==> g integrable_on s`, + let lemma = prove + (`!f:num->real^N->real^1 g h s. + (!k. f k absolutely_integrable_on s) /\ + h integrable_on s /\ + (!x. x IN s ==> norm(g x) <= drop(h x)) /\ + (!x. x IN s ==> ((\k. f k x) --> g x) sequentially) + ==> g integrable_on s`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN `(h:real^N->real^1) absolutely_integrable_on s` + ASSUME_TAC THENL + [MATCH_MP_TAC NONNEGATIVE_ABSOLUTELY_INTEGRABLE THEN + ASM_REWRITE_TAC[DIMINDEX_1; IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN + REWRITE_TAC[DIMINDEX_1; FORALL_1; GSYM drop; IMP_IMP] THEN + ASM_MESON_TAC[REAL_LE_TRANS; NORM_POS_LE]; + ALL_TAC] THEN + MP_TAC(ISPECL + [`\n:num x:real^N. + lift(min (max (--(drop(h x))) (drop(f n x))) (drop(h x)))`; + `g:real^N->real^1`; + `h:real^N->real^1`; + `s:real^N->bool`] DOMINATED_CONVERGENCE) THEN + ANTS_TAC THENL [ASM_REWRITE_TAC[]; SIMP_TAC[]] THEN REPEAT CONJ_TAC THENL + [X_GEN_TAC `n:num` THEN + MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_IMP_INTEGRABLE THEN + MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_MIN_1 THEN + ASM_REWRITE_TAC[LIFT_DROP; ETA_AX] THEN + MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_MAX_1 THEN + ASM_SIMP_TAC[LIFT_NEG; LIFT_DROP; ETA_AX; ABSOLUTELY_INTEGRABLE_NEG]; + MAP_EVERY X_GEN_TAC [`n:num`; `x:real^N`] THEN DISCH_TAC THEN + REWRITE_TAC[LIFT_DROP; ABS_DROP] THEN + SUBGOAL_THEN `&0 <= drop((h:real^N->real^1) x)` MP_TAC THENL + [ASM_MESON_TAC[REAL_LE_TRANS; NORM_POS_LE]; REAL_ARITH_TAC]; + X_GEN_TAC `x:real^N` THEN REWRITE_TAC[IN_DIFF] THEN STRIP_TAC THEN + UNDISCH_TAC + `!x. x IN s ==> ((\n. (f:num->real^N->real^1) n x) --> g x) + sequentially` THEN + DISCH_THEN(MP_TAC o SPEC `x:real^N`) THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[tendsto] THEN MATCH_MP_TAC MONO_FORALL THEN + X_GEN_TAC `e:real` THEN ASM_CASES_TAC `&0 < e` THEN + ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] EVENTUALLY_MONO) THEN + X_GEN_TAC `n:num` THEN REWRITE_TAC[] THEN + FIRST_X_ASSUM(MP_TAC o SPEC `x:real^N`) THEN + ASM_REWRITE_TAC[dist; ABS_DROP; DROP_SUB; LIFT_DROP] THEN + REAL_ARITH_TAC]) in + REPEAT GEN_TAC THEN + DISCH_THEN(CONJUNCTS_THEN2 MP_TAC STRIP_ASSUME_TAC) THEN + ONCE_REWRITE_TAC[ABSOLUTELY_INTEGRABLE_COMPONENTWISE; + INTEGRABLE_COMPONENTWISE] THEN + DISCH_TAC THEN X_GEN_TAC `k:num` THEN STRIP_TAC THEN + MATCH_MP_TAC lemma THEN + EXISTS_TAC `\i x. lift(((f:num->real^M->real^N) i x)$k)` THEN + EXISTS_TAC `h:real^M->real^1` THEN ASM_SIMP_TAC[] THEN CONJ_TAC THENL + [ASM_MESON_TAC[COMPONENT_LE_NORM; NORM_LIFT; REAL_LE_TRANS]; + RULE_ASSUM_TAC(ONCE_REWRITE_RULE[LIM_COMPONENTWISE_LIFT]) THEN + RULE_ASSUM_TAC BETA_RULE THEN ASM_SIMP_TAC[]]);; + +let DOMINATED_CONVERGENCE_ABSOLUTELY_INTEGRABLE = prove + (`!f:num->real^M->real^N g h s. + (!k. f k absolutely_integrable_on s) /\ + h integrable_on s /\ + (!k x. x IN s ==> norm(g x) <= drop(h x)) /\ + (!x. x IN s ==> ((\k. f k x) --> g x) sequentially) + ==> g absolutely_integrable_on s`, + REPEAT STRIP_TAC THEN + MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_INTEGRABLE_BOUND THEN + EXISTS_TAC `h:real^M->real^1` THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC DOMINATED_CONVERGENCE_INTEGRABLE THEN + EXISTS_TAC `f:num->real^M->real^N` THEN + EXISTS_TAC `h:real^M->real^1` THEN ASM_REWRITE_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* A few more properties of negligible sets. *) +(* ------------------------------------------------------------------------- *) + +let NEGLIGIBLE_ON_UNIV = prove + (`!s. negligible s <=> (indicator s has_integral vec 0) (:real^N)`, + GEN_TAC THEN EQ_TAC THENL [SIMP_TAC[NEGLIGIBLE]; ALL_TAC] THEN + DISCH_TAC THEN REWRITE_TAC[negligible] THEN + MAP_EVERY X_GEN_TAC [`a:real^N`; `b:real^N`] THEN + SUBGOAL_THEN `indicator s integrable_on interval[a:real^N,b]` + ASSUME_TAC THENL + [MATCH_MP_TAC INTEGRABLE_ON_SUBINTERVAL THEN + EXISTS_TAC `(:real^N)` THEN ASM_MESON_TAC[SUBSET_UNIV; integrable_on]; + ASM_SIMP_TAC[GSYM INTEGRAL_EQ_HAS_INTEGRAL] THEN + REWRITE_TAC[GSYM DROP_EQ; GSYM REAL_LE_ANTISYM] THEN + CONJ_TAC THENL + [FIRST_ASSUM(SUBST1_TAC o SYM o MATCH_MP INTEGRAL_UNIQUE) THEN + MATCH_MP_TAC INTEGRAL_SUBSET_DROP_LE; + REWRITE_TAC[DROP_VEC] THEN MATCH_MP_TAC INTEGRAL_DROP_POS] THEN + ASM_REWRITE_TAC[SUBSET_UNIV; DROP_INDICATOR_POS_LE] THEN + ASM_MESON_TAC[integrable_on]]);; + +let NEGLIGIBLE_COUNTABLE_UNIONS = prove + (`!s:num->real^N->bool. + (!n. negligible(s n)) ==> negligible(UNIONS {s(n) | n IN (:num)})`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`\n. indicator(UNIONS {(s:num->real^N->bool)(m) | m <= n})`; + `indicator(UNIONS {(s:num->real^N->bool)(m) | m IN (:num)})`; + `(:real^N)`] MONOTONE_CONVERGENCE_INCREASING) THEN + SUBGOAL_THEN + `!n. negligible(UNIONS {(s:num->real^N->bool)(m) | m <= n})` + ASSUME_TAC THENL + [GEN_TAC THEN MATCH_MP_TAC NEGLIGIBLE_UNIONS THEN + ONCE_REWRITE_TAC[SIMPLE_IMAGE_GEN] THEN + ASM_SIMP_TAC[FINITE_IMAGE; FINITE_NUMSEG_LE; FORALL_IN_IMAGE]; + ALL_TAC] THEN + SUBGOAL_THEN + `!n:num. (indicator (UNIONS {s m | m <= n})) integrable_on (:real^N)` + ASSUME_TAC THENL + [ASM_MESON_TAC[NEGLIGIBLE_ON_UNIV; integrable_on]; ALL_TAC] THEN + SUBGOAL_THEN + `!n:num. integral (:real^N) (indicator (UNIONS {s m | m <= n})) = vec 0` + ASSUME_TAC THENL + [ASM_MESON_TAC[NEGLIGIBLE_ON_UNIV; INTEGRAL_UNIQUE]; ALL_TAC] THEN + ASM_SIMP_TAC[NEGLIGIBLE_ON_UNIV; LIM_CONST_EQ; + TRIVIAL_LIMIT_SEQUENTIALLY] THEN + ANTS_TAC THENL [ALL_TAC; MESON_TAC[INTEGRAL_EQ_HAS_INTEGRAL]] THEN + REPEAT CONJ_TAC THENL + [MAP_EVERY X_GEN_TAC [`k:num`; `x:real^N`] THEN DISCH_TAC THEN + REWRITE_TAC[indicator] THEN + SUBGOAL_THEN + `x IN UNIONS {(s:num->real^N->bool) m | m <= k} + ==> x IN UNIONS {s m | m <= SUC k}` + MP_TAC THENL + [SPEC_TAC(`x:real^N`,`x:real^N`) THEN + REWRITE_TAC[GSYM SUBSET] THEN MATCH_MP_TAC SUBSET_UNIONS THEN + ONCE_REWRITE_TAC[SIMPLE_IMAGE_GEN] THEN MATCH_MP_TAC IMAGE_SUBSET THEN + REWRITE_TAC[SUBSET; IN_ELIM_THM] THEN ARITH_TAC; + REPEAT(COND_CASES_TAC THEN ASM_REWRITE_TAC[]) THEN + REWRITE_TAC[DROP_VEC; REAL_LE_REFL; REAL_POS]]; + X_GEN_TAC `x:real^N` THEN DISCH_THEN(K ALL_TAC) THEN + MATCH_MP_TAC LIM_EVENTUALLY THEN + REWRITE_TAC[EVENTUALLY_SEQUENTIALLY; indicator] THEN + ASM_CASES_TAC `x IN UNIONS {(s:num->real^N->bool) m | m IN (:num)}` THENL + [FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE RAND_CONV [UNIONS_GSPEC]) THEN + REWRITE_TAC[IN_ELIM_THM; IN_UNIV] THEN MATCH_MP_TAC MONO_EXISTS THEN + X_GEN_TAC `m:num` THEN DISCH_TAC THEN + X_GEN_TAC `n:num` THEN DISCH_TAC THEN + REWRITE_TAC[UNIONS_GSPEC; IN_ELIM_THM] THEN ASM_MESON_TAC[]; + EXISTS_TAC `0` THEN X_GEN_TAC `n:num` THEN DISCH_TAC THEN + ASM_REWRITE_TAC[] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE (RAND_CONV o RAND_CONV) + [UNIONS_GSPEC]) THEN + REWRITE_TAC[UNIONS_GSPEC; IN_ELIM_THM; IN_UNIV] THEN MESON_TAC[]]; + REWRITE_TAC[SET_RULE `{c | x | x IN UNIV} = {c}`; + BOUNDED_INSERT; BOUNDED_EMPTY]]);; + +let HAS_INTEGRAL_NEGLIGIBLE_EQ = prove + (`!f:real^M->real^N s. + (!x i. x IN s /\ 1 <= i /\ i <= dimindex(:N) ==> &0 <= f(x)$i) + ==> ((f has_integral vec 0) s <=> + negligible {x | x IN s /\ ~(f x = vec 0)})`, + let lemma = prove + (`!f:real^N->real^1 s. + (!x. x IN s ==> &0 <= drop(f x)) /\ (f has_integral vec 0) s + ==> negligible {x | x IN s /\ ~(f x = vec 0)}`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC NEGLIGIBLE_SUBSET THEN EXISTS_TAC + `UNIONS {{x | x IN s /\ norm((f:real^N->real^1) x) >= &1 / (&n + &1)} | + n IN (:num)}` THEN + CONJ_TAC THENL + [MATCH_MP_TAC NEGLIGIBLE_COUNTABLE_UNIONS THEN + X_GEN_TAC `n:num` THEN REWRITE_TAC[NEGLIGIBLE_ON_UNIV; indicator] THEN + MATCH_MP_TAC HAS_INTEGRAL_STRADDLE_NULL THEN + EXISTS_TAC `(\x. if x IN s then (&n + &1) % f(x) else vec 0): + real^N->real^1` THEN + CONJ_TAC THENL + [REWRITE_TAC[IN_UNIV; IN_ELIM_THM; real_ge] THEN + X_GEN_TAC `x:real^N` THEN COND_CASES_TAC THEN + ASM_SIMP_TAC[DROP_VEC; DROP_CMUL; REAL_POS] THENL + [ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN + ASM_SIMP_TAC[GSYM REAL_LE_LDIV_EQ; REAL_ARITH `&0 < &n + &1`] THEN + MATCH_MP_TAC(REAL_ARITH `&0 <= x /\ a <= abs x ==> a <= x`) THEN + ASM_SIMP_TAC[GSYM ABS_DROP]; + COND_CASES_TAC THEN REWRITE_TAC[DROP_VEC; REAL_POS; DROP_CMUL] THEN + ASM_SIMP_TAC[REAL_POS; REAL_LE_MUL; REAL_LE_ADD]]; + REWRITE_TAC[HAS_INTEGRAL_RESTRICT_UNIV] THEN + SUBST1_TAC(VECTOR_ARITH `vec 0:real^1 = (&n + &1) % vec 0`) THEN + MATCH_MP_TAC HAS_INTEGRAL_CMUL THEN ASM_REWRITE_TAC[]]; + REWRITE_TAC[SUBSET; IN_ELIM_THM] THEN X_GEN_TAC `x:real^N` THEN + REWRITE_TAC[GSYM NORM_POS_LT] THEN ONCE_REWRITE_TAC[REAL_ARCH_INV] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC (X_CHOOSE_THEN `n:num` + STRIP_ASSUME_TAC)) THEN + REWRITE_TAC[IN_UNIONS; EXISTS_IN_GSPEC] THEN + EXISTS_TAC `n - 1` THEN ASM_SIMP_TAC[IN_UNIV; IN_ELIM_THM; real_ge] THEN + ASM_SIMP_TAC[REAL_OF_NUM_ADD; SUB_ADD; LE_1] THEN + ASM_SIMP_TAC[real_div; REAL_MUL_LID; REAL_LT_IMP_LE]]) in + REPEAT STRIP_TAC THEN EQ_TAC THEN DISCH_TAC THENL + [ALL_TAC; + MATCH_MP_TAC HAS_INTEGRAL_NEGLIGIBLE THEN + EXISTS_TAC `{x | x IN s /\ ~((f:real^M->real^N) x = vec 0)}` THEN + ASM_REWRITE_TAC[IN_DIFF; IN_ELIM_THM] THEN MESON_TAC[]] THEN + MATCH_MP_TAC NEGLIGIBLE_SUBSET THEN + EXISTS_TAC `UNIONS {{x | x IN s /\ ~(((f:real^M->real^N) x)$k = &0)} | + k IN 1..dimindex(:N)}` THEN + CONJ_TAC THENL + [MATCH_MP_TAC NEGLIGIBLE_UNIONS THEN + SIMP_TAC[SIMPLE_IMAGE; FINITE_IMAGE; FINITE_NUMSEG; FORALL_IN_IMAGE] THEN + X_GEN_TAC `k:num` THEN REWRITE_TAC[IN_NUMSEG] THEN STRIP_TAC THEN + REWRITE_TAC[GSYM LIFT_EQ; LIFT_NUM] THEN MATCH_MP_TAC lemma THEN + ASM_SIMP_TAC[LIFT_DROP] THEN + FIRST_X_ASSUM(MP_TAC o ISPEC `\y:real^N. lift(y$k)` o + MATCH_MP(REWRITE_RULE[IMP_CONJ] HAS_INTEGRAL_LINEAR)) THEN + REWRITE_TAC[o_DEF; VEC_COMPONENT; LIFT_NUM] THEN + DISCH_THEN MATCH_MP_TAC THEN REWRITE_TAC[linear] THEN + SIMP_TAC[LIFT_ADD; VECTOR_ADD_COMPONENT; LIFT_CMUL; VECTOR_MUL_COMPONENT]; + REWRITE_TAC[SUBSET; IN_UNIONS; EXISTS_IN_GSPEC; CART_EQ; IN_NUMSEG] THEN + REWRITE_TAC[VEC_COMPONENT; IN_ELIM_THM] THEN MESON_TAC[]]);; + +let NEGLIGIBLE_COUNTABLE = prove + (`!s:real^N->bool. COUNTABLE s ==> negligible s`, + let lemma = prove + (`IMAGE f s = UNIONS {{f x} | x IN s}`, + REWRITE_TAC[EXTENSION; IN_IMAGE; IN_UNIONS; IN_SING; IN_ELIM_THM] THEN + MESON_TAC[IN_SING]) in + GEN_TAC THEN ASM_CASES_TAC `s:real^N->bool = {}` THEN + ASM_REWRITE_TAC[NEGLIGIBLE_EMPTY] THEN + POP_ASSUM MP_TAC THEN REWRITE_TAC[GSYM IMP_CONJ_ALT] THEN + DISCH_THEN(X_CHOOSE_THEN `f:num->real^N` SUBST1_TAC o + MATCH_MP COUNTABLE_AS_IMAGE) THEN + ONCE_REWRITE_TAC[lemma] THEN MATCH_MP_TAC NEGLIGIBLE_COUNTABLE_UNIONS THEN + REWRITE_TAC[NEGLIGIBLE_SING]);; + +(* ------------------------------------------------------------------------- *) +(* Beppo Levi theorem. *) +(* ------------------------------------------------------------------------- *) + +let BEPPO_LEVI_INCREASING = prove + (`!f:num->real^N->real^1 s. + (!k. (f k) integrable_on s) /\ + (!k x. x IN s ==> drop(f k x) <= drop(f (SUC k) x)) /\ + bounded {integral s (f k) | k IN (:num)} + ==> ?g k. negligible k /\ + !x. x IN (s DIFF k) ==> ((\k. f k x) --> g x) sequentially`, + SUBGOAL_THEN + `!f:num->real^N->real^1 s. + (!k x. x IN s ==> &0 <= drop(f k x)) /\ + (!k. (f k) integrable_on s) /\ + (!k x. x IN s ==> drop(f k x) <= drop(f (SUC k) x)) /\ + bounded {integral s (f k) | k IN (:num)} + ==> ?g k. negligible k /\ + !x. x IN (s DIFF k) ==> ((\k. f k x) --> g x) sequentially` + ASSUME_TAC THENL + [ALL_TAC; + REPEAT GEN_TAC THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o ISPECL + [`\n x:real^N. f(n:num) x - f 0 x:real^1`; `s:real^N->bool`]) THEN + REWRITE_TAC[] THEN ANTS_TAC THEN REPEAT CONJ_TAC THENL + [REPEAT STRIP_TAC THEN REWRITE_TAC[DROP_SUB; REAL_SUB_LE] THEN + MP_TAC(ISPEC + `\m n:num. drop (f m (x:real^N)) <= drop (f n x)` + TRANSITIVE_STEPWISE_LE) THEN + REWRITE_TAC[REAL_LE_TRANS; REAL_LE_REFL] THEN ASM_MESON_TAC[LE_0]; + GEN_TAC THEN MATCH_MP_TAC INTEGRABLE_SUB THEN ASM_REWRITE_TAC[ETA_AX]; + REPEAT STRIP_TAC THEN REWRITE_TAC[DROP_SUB; REAL_SUB_LE] THEN + ASM_SIMP_TAC[REAL_ARITH `x - a <= y - a <=> x <= y`]; + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [bounded]) THEN + ASM_SIMP_TAC[INTEGRAL_SUB; ETA_AX; bounded] THEN + ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN + REWRITE_TAC[FORALL_IN_IMAGE; IN_UNIV] THEN + DISCH_THEN(X_CHOOSE_THEN `B:real` + (fun th -> EXISTS_TAC `B + norm(integral s (f 0:real^N->real^1))` THEN + X_GEN_TAC `k:num` THEN MP_TAC(SPEC `k:num` th))) THEN + NORM_ARITH_TAC; + ONCE_REWRITE_TAC[SWAP_EXISTS_THM] THEN MATCH_MP_TAC MONO_EXISTS THEN + GEN_TAC THEN + DISCH_THEN(X_CHOOSE_THEN `g:real^N->real^1` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `(\x. g x + f 0 x):real^N->real^1` THEN + ASM_REWRITE_TAC[] THEN X_GEN_TAC `x:real^N` THEN + DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC `x:real^N`) THEN + ASM_REWRITE_TAC[LIM_SEQUENTIALLY; dist] THEN + REWRITE_TAC[VECTOR_ARITH `a - b - c:real^1 = a - (c + b)`]]] THEN + REPEAT STRIP_TAC THEN + ABBREV_TAC + `g = \i n:num x:real^N. lift(min (drop(f n x) / (&i + &1)) (&1))` THEN + SUBGOAL_THEN + `!i n. ((g:num->num->real^N->real^1) i n) integrable_on s` + ASSUME_TAC THENL + [REPEAT GEN_TAC THEN EXPAND_TAC "g" THEN + MATCH_MP_TAC INTEGRABLE_MIN_CONST_1 THEN + ASM_SIMP_TAC[REAL_POS; REAL_LE_DIV; REAL_LE_ADD] THEN + REWRITE_TAC[ONCE_REWRITE_RULE[REAL_MUL_SYM] real_div] THEN + ASM_SIMP_TAC[LIFT_CMUL; LIFT_DROP; INTEGRABLE_CMUL; ETA_AX]; + ALL_TAC] THEN + SUBGOAL_THEN + `!i:num k:num x:real^N. x IN s ==> drop(g i k x) <= drop(g i (SUC k) x)` + ASSUME_TAC THENL + [REPEAT STRIP_TAC THEN EXPAND_TAC "g" THEN REWRITE_TAC[LIFT_DROP] THEN + MATCH_MP_TAC(REAL_ARITH `x <= y ==> min x a <= min y a`) THEN + ASM_SIMP_TAC[REAL_LE_DIV2_EQ; REAL_ARITH `&0 < &n + &1`]; + ALL_TAC] THEN + SUBGOAL_THEN `!i:num k:num x:real^N. x IN s ==> norm(g i k x:real^1) <= &1` + ASSUME_TAC THENL + [REPEAT STRIP_TAC THEN EXPAND_TAC "g" THEN + REWRITE_TAC[LIFT_DROP; NORM_REAL; GSYM drop] THEN + MATCH_MP_TAC(REAL_ARITH `&0 <= x ==> abs(min x (&1)) <= &1`) THEN + ASM_SIMP_TAC[REAL_POS; REAL_LE_DIV; REAL_LE_ADD]; + ALL_TAC] THEN + SUBGOAL_THEN + `!i:num x:real^N. x IN s ==> ?h:real^1. ((\n. g i n x) --> h) sequentially` + MP_TAC THENL + [REPEAT STRIP_TAC THEN + MP_TAC(ISPECL + [`\n. drop(g (i:num) (n:num) (x:real^N))`; `&1`] + CONVERGENT_BOUNDED_MONOTONE) THEN + REWRITE_TAC[] THEN ANTS_TAC THENL + [ASM_SIMP_TAC[GSYM ABS_DROP] THEN DISJ1_TAC THEN + MATCH_MP_TAC TRANSITIVE_STEPWISE_LE THEN + ASM_SIMP_TAC[REAL_LE_REFL; REAL_LE_TRANS] THEN REAL_ARITH_TAC; + DISCH_THEN(X_CHOOSE_THEN `l:real` (fun th -> + EXISTS_TAC `lift l` THEN MP_TAC th)) THEN + REWRITE_TAC[LIM_SEQUENTIALLY; DIST_REAL; GSYM drop; LIFT_DROP]]; + GEN_REWRITE_TAC (LAND_CONV o REDEPTH_CONV) [RIGHT_IMP_EXISTS_THM] THEN + REWRITE_TAC[SKOLEM_THM; LEFT_IMP_EXISTS_THM]] THEN + X_GEN_TAC `h:num->real^N->real^1` THEN STRIP_TAC THEN + MP_TAC(GEN `i:num `(ISPECL + [`g(i:num):num->real^N->real^1`; `h(i:num):real^N->real^1`; + `s:real^N->bool`] MONOTONE_CONVERGENCE_INCREASING)) THEN + DISCH_THEN(MP_TAC o MATCH_MP MONO_FORALL) THEN + ASM_REWRITE_TAC[] THEN ANTS_TAC THENL + [GEN_TAC THEN REWRITE_TAC[bounded] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [bounded]) THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `K:real` THEN + REWRITE_TAC[FORALL_IN_GSPEC] THEN REWRITE_TAC[IN_UNIV] THEN + MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `k:num` THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] REAL_LE_TRANS) THEN + MATCH_MP_TAC(REAL_ARITH + `norm a = drop a /\ x <= drop a ==> x <= norm a`) THEN + CONJ_TAC THENL + [REWRITE_TAC[NORM_REAL; GSYM drop; REAL_ABS_REFL] THEN + MATCH_MP_TAC INTEGRAL_DROP_POS THEN ASM_SIMP_TAC[]; + MATCH_MP_TAC INTEGRAL_NORM_BOUND_INTEGRAL THEN + ASM_REWRITE_TAC[] THEN X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN + EXPAND_TAC "g" THEN REWRITE_TAC[NORM_REAL; GSYM drop; LIFT_DROP] THEN + MATCH_MP_TAC(REAL_ARITH + `&0 <= x /\ x <= y ==> abs(min x (&1)) <= y`) THEN + ASM_SIMP_TAC[REAL_LE_ADD; REAL_POS; REAL_LE_DIV] THEN + SIMP_TAC[REAL_LE_LDIV_EQ; REAL_ARITH `&0 < &i + &1`] THEN + REWRITE_TAC[REAL_ARITH `a <= a * (x + &1) <=> &0 <= a * x`] THEN + ASM_SIMP_TAC[REAL_LE_MUL; REAL_POS]]; + REWRITE_TAC[FORALL_AND_THM] THEN STRIP_TAC] THEN + ABBREV_TAC + `Z = + {x:real^N | x IN s /\ ~(?l:real^1. ((\k. f k x) --> l) sequentially)}` THEN + ONCE_REWRITE_TAC[SWAP_EXISTS_THM] THEN EXISTS_TAC `Z:real^N->bool` THEN + REWRITE_TAC[RIGHT_EXISTS_AND_THM; GSYM SKOLEM_THM; RIGHT_EXISTS_IMP_THM] THEN + CONJ_TAC THENL + [ALL_TAC; EXPAND_TAC "Z" THEN REWRITE_TAC[IN_ELIM_THM] THEN SET_TAC[]] THEN + MP_TAC(ISPECL + [`h:num->real^N->real^1`; + `(\x. if x IN Z then vec 1 else vec 0):real^N->real^1`; + `s:real^N->bool`] + MONOTONE_CONVERGENCE_DECREASING) THEN + ASM_REWRITE_TAC[] THEN + SUBGOAL_THEN + `!i x:real^N. x IN s ==> drop(h (SUC i) x) <= drop(h i x)` + ASSUME_TAC THENL + [MAP_EVERY X_GEN_TAC [`i:num`; `x:real^N`] THEN DISCH_TAC THEN + MATCH_MP_TAC(ISPEC `sequentially` LIM_DROP_LE) THEN + EXISTS_TAC `\n. (g:num->num->real^N->real^1) (SUC i) n x` THEN + EXISTS_TAC `\n. (g:num->num->real^N->real^1) i n x` THEN + ASM_SIMP_TAC[TRIVIAL_LIMIT_SEQUENTIALLY] THEN + MATCH_MP_TAC ALWAYS_EVENTUALLY THEN X_GEN_TAC `n:num` THEN + EXPAND_TAC "g" THEN REWRITE_TAC[LIFT_DROP] THEN + MATCH_MP_TAC(REAL_ARITH `x <= y ==> min x a <= min y a`) THEN + REWRITE_TAC[real_div] THEN MATCH_MP_TAC REAL_LE_LMUL THEN + ASM_SIMP_TAC[] THEN MATCH_MP_TAC REAL_LE_INV2 THEN + REWRITE_TAC[GSYM REAL_OF_NUM_SUC] THEN REAL_ARITH_TAC; + ASM_REWRITE_TAC[]] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [BOUNDED_POS]) THEN + REWRITE_TAC[FORALL_IN_GSPEC; IN_UNIV] THEN + DISCH_THEN(X_CHOOSE_THEN `B:real` STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN + `!i. norm(integral s ((h:num->real^N->real^1) i)) <= B / (&i + &1)` + ASSUME_TAC THENL + [X_GEN_TAC `i:num` THEN + MATCH_MP_TAC(ISPEC `sequentially` LIM_NORM_UBOUND) THEN + EXISTS_TAC `\k. integral s ((g:num->num->real^N->real^1) i k)` THEN + ASM_REWRITE_TAC[TRIVIAL_LIMIT_SEQUENTIALLY] THEN + MATCH_MP_TAC ALWAYS_EVENTUALLY THEN X_GEN_TAC `n:num` THEN + REWRITE_TAC[] THEN MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC + `drop(integral s (\x. inv(&i + &1) % (f:num->real^N->real^1) n x))` THEN + CONJ_TAC THENL + [MATCH_MP_TAC INTEGRAL_NORM_BOUND_INTEGRAL THEN + ASM_SIMP_TAC[INTEGRABLE_CMUL; ETA_AX] THEN + X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN EXPAND_TAC "g" THEN + REWRITE_TAC[NORM_REAL; GSYM drop; LIFT_DROP; DROP_CMUL] THEN + MATCH_MP_TAC(REAL_ARITH + `&0 <= x /\ x <= y ==> abs(min x (&1)) <= y`) THEN + ASM_SIMP_TAC[REAL_LE_ADD; REAL_POS; REAL_LE_DIV] THEN + REAL_ARITH_TAC; + ASM_SIMP_TAC[INTEGRAL_CMUL; ETA_AX; DROP_CMUL] THEN + ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN + ASM_SIMP_TAC[GSYM real_div; REAL_LE_DIV2_EQ; + REAL_ARITH `&0 < &n + &1`] THEN + MATCH_MP_TAC(REAL_ARITH `abs x <= a ==> x <= a`) THEN + ASM_REWRITE_TAC[GSYM ABS_DROP]]; + ALL_TAC] THEN + ANTS_TAC THENL + [REWRITE_TAC[bounded; FORALL_IN_GSPEC] THEN CONJ_TAC THENL + [ALL_TAC; + EXISTS_TAC `B:real` THEN X_GEN_TAC `i:num` THEN + MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `B / (&i + &1)` THEN ASM_REWRITE_TAC[] THEN + ASM_SIMP_TAC[REAL_LE_LDIV_EQ; REAL_ARITH `&0 < &i + &1`] THEN + REWRITE_TAC[REAL_ARITH `B <= B * (i + &1) <=> &0 <= i * B`] THEN + ASM_SIMP_TAC[REAL_LE_MUL; REAL_POS; REAL_LT_IMP_LE]] THEN + X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN + ASM_CASES_TAC `(x:real^N) IN Z` THEN ASM_REWRITE_TAC[] THENL + [MATCH_MP_TAC LIM_EVENTUALLY THEN + UNDISCH_TAC `(x:real^N) IN Z` THEN EXPAND_TAC "Z" THEN + REWRITE_TAC[IN_ELIM_THM] THEN ASM_REWRITE_TAC[] THEN DISCH_TAC THEN + MP_TAC(GEN `B:real` (ISPECL + [`\n. drop(f (n:num) (x:real^N))`; `B:real`] + CONVERGENT_BOUNDED_MONOTONE)) THEN + REWRITE_TAC[LEFT_FORALL_IMP_THM; LEFT_EXISTS_AND_THM] THEN + MATCH_MP_TAC(TAUT + `q /\ ~r /\ (q ==> ~p ==> s) + ==> (p /\ (q \/ q') ==> r) ==> s`) THEN + CONJ_TAC THENL + [MATCH_MP_TAC TRANSITIVE_STEPWISE_LE THEN + ASM_SIMP_TAC[REAL_LE_REFL; REAL_LE_TRANS] THEN REAL_ARITH_TAC; + ALL_TAC] THEN + CONJ_TAC THENL + [FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [NOT_EXISTS_THM]) THEN + ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `l:real` STRIP_ASSUME_TAC) THEN + DISCH_THEN(MP_TAC o SPEC `lift l`) THEN + REWRITE_TAC[LIM_SEQUENTIALLY] THEN + X_GEN_TAC `e:real` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `e:real`) THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[DIST_REAL; GSYM drop; DROP_SUB; LIFT_DROP]; + ALL_TAC] THEN + DISCH_TAC THEN REWRITE_TAC[NOT_FORALL_THM; EVENTUALLY_SEQUENTIALLY] THEN + REWRITE_TAC[NOT_EXISTS_THM; NOT_FORALL_THM; REAL_NOT_LE] THEN + DISCH_TAC THEN + EXISTS_TAC `0` THEN X_GEN_TAC `i:num` THEN DISCH_TAC THEN + MATCH_MP_TAC(ISPEC `sequentially` LIM_UNIQUE) THEN + EXISTS_TAC `(\n. (g:num->num->real^N->real^1) i n x)` THEN + ASM_SIMP_TAC[TRIVIAL_LIMIT_SEQUENTIALLY] THEN + MATCH_MP_TAC LIM_EVENTUALLY THEN + EXPAND_TAC "g" THEN REWRITE_TAC[EVENTUALLY_SEQUENTIALLY] THEN + FIRST_X_ASSUM(MP_TAC o SPEC `&i + &1`) THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `N:num` THEN + DISCH_TAC THEN X_GEN_TAC `n:num` THEN DISCH_TAC THEN + REWRITE_TAC[GSYM DROP_EQ; DROP_VEC; LIFT_DROP] THEN + REWRITE_TAC[REAL_ARITH `min a b = b <=> b <= a`] THEN + SIMP_TAC[REAL_LE_RDIV_EQ; REAL_ARITH `&0 < &i + &1`; REAL_MUL_LID] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH + `a < abs N ==> &0 <= N /\ N <= n ==> a <= n`)) THEN + ASM_SIMP_TAC[]; + UNDISCH_TAC `~((x:real^N) IN Z)` THEN EXPAND_TAC "Z" THEN + REWRITE_TAC[IN_ELIM_THM] THEN ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `l:real^1` THEN + DISCH_THEN(MP_TAC o MATCH_MP CONVERGENT_IMP_BOUNDED) THEN + REWRITE_TAC[BOUNDED_POS; FORALL_IN_IMAGE; IN_UNIV] THEN + DISCH_THEN(X_CHOOSE_THEN `C:real` STRIP_ASSUME_TAC) THEN + REWRITE_TAC[LIM_SEQUENTIALLY; DIST_0] THEN + X_GEN_TAC `e:real` THEN DISCH_TAC THEN + MP_TAC(ISPEC `e / C:real` REAL_ARCH_INV) THEN + ASM_SIMP_TAC[REAL_LT_DIV] THEN MATCH_MP_TAC MONO_EXISTS THEN + X_GEN_TAC `N:num` THEN ASM_SIMP_TAC[REAL_LT_RDIV_EQ] THEN STRIP_TAC THEN + X_GEN_TAC `i:num` THEN DISCH_TAC THEN + MATCH_MP_TAC REAL_LET_TRANS THEN EXISTS_TAC `inv(&N) * C` THEN + ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC `C / (&i + &1)` THEN + CONJ_TAC THENL + [ALL_TAC; + REWRITE_TAC[ONCE_REWRITE_RULE[REAL_MUL_SYM] real_div] THEN + ASM_SIMP_TAC[REAL_LE_RMUL_EQ] THEN MATCH_MP_TAC REAL_LE_INV2 THEN + ASM_REWRITE_TAC[REAL_OF_NUM_LT; REAL_OF_NUM_LE; REAL_OF_NUM_ADD] THEN + ASM_ARITH_TAC] THEN + MATCH_MP_TAC(ISPEC `sequentially` LIM_NORM_UBOUND) THEN + EXISTS_TAC `\n. (g:num->num->real^N->real^1) i n x` THEN + ASM_SIMP_TAC[TRIVIAL_LIMIT_SEQUENTIALLY] THEN + MATCH_MP_TAC ALWAYS_EVENTUALLY THEN X_GEN_TAC `n:num` THEN + EXPAND_TAC "g" THEN REWRITE_TAC[NORM_REAL; GSYM drop; LIFT_DROP] THEN + MATCH_MP_TAC(REAL_ARITH + `&0 <= x /\ x <= a ==> abs(min x (&1)) <= a`) THEN + ASM_SIMP_TAC[REAL_LE_DIV; REAL_LE_ADD; REAL_POS] THEN + ASM_SIMP_TAC[REAL_LE_DIV2_EQ; REAL_ARITH `&0 < &i + &1`] THEN + MATCH_MP_TAC(REAL_ARITH `abs x <= a ==> x <= a`) THEN + ASM_REWRITE_TAC[GSYM NORM_LIFT; LIFT_DROP]]; + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + MATCH_MP_TAC(MESON[LIM_UNIQUE; TRIVIAL_LIMIT_SEQUENTIALLY] + `(f --> vec 0) sequentially /\ (i = vec 0 ==> p) + ==> (f --> i) sequentially ==> p`) THEN + CONJ_TAC THENL + [MATCH_MP_TAC LIM_NULL_COMPARISON THEN + EXISTS_TAC `\i. B / (&i + &1)` THEN + ASM_SIMP_TAC[ALWAYS_EVENTUALLY] THEN + REWRITE_TAC[real_div; LIFT_CMUL] THEN + SUBST1_TAC(VECTOR_ARITH `vec 0:real^1 = B % vec 0`) THEN + MATCH_MP_TAC LIM_CMUL THEN + REWRITE_TAC[LIM_SEQUENTIALLY; DIST_0] THEN + X_GEN_TAC `e:real` THEN GEN_REWRITE_TAC LAND_CONV [REAL_ARCH_INV] 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_LIFT; GSYM drop; LIFT_DROP; REAL_ABS_INV] 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_ARITH `abs(&n + &1) = &n + &1`] THEN + REWRITE_TAC[REAL_OF_NUM_ADD; REAL_OF_NUM_LE; REAL_OF_NUM_LT] THEN + ASM_ARITH_TAC; + ASM_SIMP_TAC[INTEGRAL_EQ_HAS_INTEGRAL] THEN + W(MP_TAC o PART_MATCH (lhs o rand) HAS_INTEGRAL_NEGLIGIBLE_EQ o + lhand o snd) THEN + ANTS_TAC THENL + [REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN + REWRITE_TAC[IMP_IMP; DIMINDEX_1; FORALL_1; GSYM drop] THEN + REPEAT STRIP_TAC THEN COND_CASES_TAC THEN + REWRITE_TAC[DROP_VEC; REAL_POS]; + DISCH_THEN SUBST1_TAC THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] NEGLIGIBLE_SUBSET) THEN + SIMP_TAC[SUBSET; IN_ELIM_THM; VEC_EQ; ARITH_EQ] THEN + EXPAND_TAC "Z" THEN SIMP_TAC[IN_ELIM_THM]]]]);; + +let BEPPO_LEVI_DECREASING = prove + (`!f:num->real^N->real^1 s. + (!k. (f k) integrable_on s) /\ + (!k x. x IN s ==> drop(f (SUC k) x) <= drop(f k x)) /\ + bounded {integral s (f k) | k IN (:num)} + ==> ?g k. negligible k /\ + !x. x IN (s DIFF k) ==> ((\k. f k x) --> g x) sequentially`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`\n x. --((f:num->real^N->real^1) n x)`; `s:real^N->bool`] + BEPPO_LEVI_INCREASING) THEN + ASM_SIMP_TAC[INTEGRABLE_NEG; DROP_NEG; ETA_AX; REAL_LE_NEG2] THEN + ANTS_TAC THENL + [REWRITE_TAC[bounded] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [bounded]) THEN + REWRITE_TAC[FORALL_IN_GSPEC] THEN + ASM_SIMP_TAC[INTEGRAL_NEG; ETA_AX; NORM_NEG]; + ONCE_REWRITE_TAC[SWAP_EXISTS_THM] THEN MATCH_MP_TAC MONO_EXISTS THEN + X_GEN_TAC `k:real^N->bool` THEN + DISCH_THEN(X_CHOOSE_THEN `g:real^N->real^1` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `\x. --((g:real^N->real^1) x)` THEN + ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN + GEN_REWRITE_TAC (RATOR_CONV o LAND_CONV o ABS_CONV) + [GSYM VECTOR_NEG_NEG] THEN + ASM_SIMP_TAC[LIM_NEG_EQ]]);; + +let BEPPO_LEVI_MONOTONE_CONVERGENCE_INCREASING = prove + (`!f:num->real^N->real^1 s. + (!k. (f k) integrable_on s) /\ + (!k x. x IN s ==> drop(f k x) <= drop(f (SUC k) x)) /\ + bounded {integral s (f k) | k IN (:num)} + ==> ?g k. negligible k /\ + (!x. x IN (s DIFF k) + ==> ((\k. f k x) --> g x) sequentially) /\ + g integrable_on s /\ + ((\k. integral s (f k)) --> integral s g) sequentially`, + REPEAT GEN_TAC THEN DISCH_TAC THEN + FIRST_ASSUM(MP_TAC o MATCH_MP BEPPO_LEVI_INCREASING) THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `g:real^N->real^1` THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `k:real^N->bool` THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + SUBGOAL_THEN + `(g:real^N->real^1) integrable_on (s DIFF k) /\ + ((\i. integral (s DIFF k) (f i)) --> integral (s DIFF k) g) sequentially` + MP_TAC THENL + [MATCH_MP_TAC MONOTONE_CONVERGENCE_INCREASING THEN + ASM_REWRITE_TAC[] THEN + FIRST_X_ASSUM(MP_TAC o check (is_conj o concl)); + ALL_TAC] THEN + (SUBGOAL_THEN + `!f:real^N->real^1. integral (s DIFF k) f = integral s f /\ + (f integrable_on (s DIFF k) <=> f integrable_on s)` + (fun th -> SIMP_TAC[th; IN_DIFF]) THEN + GEN_TAC THEN CONJ_TAC THEN TRY EQ_TAC THEN + (MATCH_MP_TAC INTEGRABLE_SPIKE_SET ORELSE + MATCH_MP_TAC INTEGRAL_SPIKE_SET) THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + NEGLIGIBLE_SUBSET)) THEN + SET_TAC[]));; + +let BEPPO_LEVI_MONOTONE_CONVERGENCE_DECREASING = prove + (`!f:num->real^N->real^1 s. + (!k. (f k) integrable_on s) /\ + (!k x. x IN s ==> drop(f (SUC k) x) <= drop(f k x)) /\ + bounded {integral s (f k) | k IN (:num)} + ==> ?g k. negligible k /\ + (!x. x IN (s DIFF k) + ==> ((\k. f k x) --> g x) sequentially) /\ + g integrable_on s /\ + ((\k. integral s (f k)) --> integral s g) sequentially`, + REPEAT GEN_TAC THEN DISCH_TAC THEN + FIRST_ASSUM(MP_TAC o MATCH_MP BEPPO_LEVI_DECREASING) THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `g:real^N->real^1` THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `k:real^N->bool` THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + SUBGOAL_THEN + `(g:real^N->real^1) integrable_on (s DIFF k) /\ + ((\i. integral (s DIFF k) (f i)) --> integral (s DIFF k) g) sequentially` + MP_TAC THENL + [MATCH_MP_TAC MONOTONE_CONVERGENCE_DECREASING THEN + ASM_REWRITE_TAC[] THEN + FIRST_X_ASSUM(MP_TAC o check (is_conj o concl)); + ALL_TAC] THEN + (SUBGOAL_THEN + `!f:real^N->real^1. integral (s DIFF k) f = integral s f /\ + (f integrable_on (s DIFF k) <=> f integrable_on s)` + (fun th -> SIMP_TAC[th; IN_DIFF]) THEN + GEN_TAC THEN CONJ_TAC THEN TRY EQ_TAC THEN + (MATCH_MP_TAC INTEGRABLE_SPIKE_SET ORELSE + MATCH_MP_TAC INTEGRAL_SPIKE_SET) THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + NEGLIGIBLE_SUBSET)) THEN + SET_TAC[]));; + +(* ------------------------------------------------------------------------- *) +(* Fundamental theorem of calculus, starting with strong forms. *) +(* ------------------------------------------------------------------------- *) + +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 FUNDAMENTAL_THEOREM_OF_CALCULUS_INTERIOR_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)) + ==> (f' has_integral (f(b) - f(a))) (interval[a,b])`, + REPEAT STRIP_TAC THEN + MATCH_MP_TAC FUNDAMENTAL_THEOREM_OF_CALCULUS_STRONG THEN + EXISTS_TAC `(a:real^1) INSERT (b:real^1) INSERT s` THEN + ASM_REWRITE_TAC[COUNTABLE_INSERT; IN_INTERVAL_1; IN_DIFF] THEN + REWRITE_TAC[DE_MORGAN_THM; IN_INSERT] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_VECTOR_DERIVATIVE_AT_WITHIN THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_REWRITE_TAC[IN_INTERVAL_1; IN_DIFF; IN_INSERT] THEN + ASM_REWRITE_TAC[REAL_LT_LE; DROP_EQ]);; + +let FUNDAMENTAL_THEOREM_OF_CALCULUS = prove + (`!f:real^1->real^N f' a b. + drop a <= drop b /\ + (!x. x IN interval[a,b] + ==> (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 FUNDAMENTAL_THEOREM_OF_CALCULUS_STRONG THEN + EXISTS_TAC `{}:real^1->bool` THEN + ASM_REWRITE_TAC[COUNTABLE_EMPTY; DIFF_EMPTY] THEN + MATCH_MP_TAC DIFFERENTIABLE_IMP_CONTINUOUS_ON THEN + REWRITE_TAC[differentiable_on] THEN + ASM_MESON_TAC[has_vector_derivative; differentiable]);; + +let FUNDAMENTAL_THEOREM_OF_CALCULUS_INTERIOR = prove + (`!f:real^1->real^N f' a b. + drop a <= drop b /\ f continuous_on interval[a,b] /\ + (!x. x IN interval(a,b) + ==> (f has_vector_derivative f'(x)) (at x)) + ==> (f' has_integral (f(b) - f(a))) (interval[a,b])`, + REPEAT STRIP_TAC THEN + MATCH_MP_TAC FUNDAMENTAL_THEOREM_OF_CALCULUS_INTERIOR_STRONG THEN + EXISTS_TAC `{}:real^1->bool` THEN + ASM_REWRITE_TAC[COUNTABLE_EMPTY; DIFF_EMPTY]);; + +let ANTIDERIVATIVE_INTEGRAL_CONTINUOUS = prove + (`!f:real^1->real^N a b. + (f continuous_on interval[a,b]) + ==> ?g. !u v. u IN interval[a,b] /\ v IN interval[a,b] /\ drop u <= drop v + ==> (f has_integral (g(v) - g(u))) (interval[u,v])`, + REPEAT STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o MATCH_MP ANTIDERIVATIVE_CONTINUOUS) THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `g:real^1->real^N` THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC FUNDAMENTAL_THEOREM_OF_CALCULUS THEN + ASM_REWRITE_TAC[] THEN X_GEN_TAC `x:real^1` THEN + STRIP_TAC THEN MATCH_MP_TAC HAS_VECTOR_DERIVATIVE_WITHIN_SUBSET THEN + EXISTS_TAC `interval[a:real^1,b]` THEN CONJ_TAC THENL + [FIRST_X_ASSUM MATCH_MP_TAC; ALL_TAC] THEN + REPEAT(POP_ASSUM MP_TAC) THEN + REWRITE_TAC[SUBSET_INTERVAL_1; IN_INTERVAL_1] THEN REAL_ARITH_TAC);; + +(* ------------------------------------------------------------------------- *) +(* This doesn't directly involve integration, but that gives an easy proof. *) +(* ------------------------------------------------------------------------- *) + +let HAS_DERIVATIVE_ZERO_UNIQUE_STRONG_INTERVAL = prove + (`!f:real^1->real^N a b k y. + COUNTABLE k /\ f continuous_on interval[a,b] /\ f a = y /\ + (!x. x IN (interval[a,b] DIFF k) + ==> (f has_derivative (\h. vec 0)) (at x within interval[a,b])) + ==> !x. x IN interval[a,b] ==> f x = y`, + REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[GSYM VECTOR_SUB_EQ] THEN + MATCH_MP_TAC(ISPEC `(\x. vec 0):real^1->real^N` HAS_INTEGRAL_UNIQUE) THEN + EXISTS_TAC `interval[a:real^1,x]` THEN + REWRITE_TAC[HAS_INTEGRAL_0] THEN FIRST_X_ASSUM(SUBST_ALL_TAC o SYM) THEN + MATCH_MP_TAC FUNDAMENTAL_THEOREM_OF_CALCULUS_INTERIOR_STRONG THEN + EXISTS_TAC `k:real^1->bool` THEN ASM_REWRITE_TAC[] THEN REPEAT CONJ_TAC THENL + [REPEAT(FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_INTERVAL_1])) THEN + REAL_ARITH_TAC; + MATCH_MP_TAC CONTINUOUS_ON_SUBSET THEN + EXISTS_TAC `interval[a:real^1,b]` THEN + ASM_REWRITE_TAC[SUBSET_INTERVAL_1] THEN + REPEAT(FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_INTERVAL_1])) THEN + REAL_ARITH_TAC; + X_GEN_TAC `y:real^1` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `y:real^1`) THEN ANTS_TAC THENL + [REPEAT(POP_ASSUM MP_TAC) THEN + SIMP_TAC[IN_DIFF; IN_INTERVAL_1] THEN REAL_ARITH_TAC; + ALL_TAC] THEN + DISCH_THEN(MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + HAS_DERIVATIVE_WITHIN_SUBSET)) THEN + DISCH_THEN(MP_TAC o SPEC `interval(a:real^1,b)`) THEN + REWRITE_TAC[INTERVAL_OPEN_SUBSET_CLOSED] THEN + REWRITE_TAC[has_vector_derivative; VECTOR_MUL_RZERO] THEN + MATCH_MP_TAC EQ_IMP THEN MATCH_MP_TAC HAS_DERIVATIVE_WITHIN_OPEN THEN + REPEAT(POP_ASSUM MP_TAC) THEN + SIMP_TAC[OPEN_INTERVAL; IN_INTERVAL_1; IN_DIFF] THEN REAL_ARITH_TAC]);; + +(* ------------------------------------------------------------------------- *) +(* Generalize a bit to any convex set. *) +(* ------------------------------------------------------------------------- *) + +let HAS_DERIVATIVE_ZERO_UNIQUE_STRONG_CONVEX = prove + (`!f:real^M->real^N s k c y. + convex s /\ COUNTABLE k /\ f continuous_on s /\ c IN s /\ f c = y /\ + (!x. x IN (s DIFF k) ==> (f has_derivative (\h. vec 0)) (at x within s)) + ==> !x. x IN s ==> f x = y`, + GEN_TAC THEN GEN_TAC THEN GEN_TAC THEN + MAP_EVERY X_GEN_TAC [`x:real^M`; `z:real^N`] THEN STRIP_TAC THEN + FIRST_X_ASSUM(SUBST_ALL_TAC o SYM) THEN + X_GEN_TAC `y:real^M` THEN DISCH_TAC THEN + ASM_CASES_TAC `x:real^M = y` THEN ASM_REWRITE_TAC[] THEN + MP_TAC(ISPECL [`(f:real^M->real^N) o (\t. (&1 - drop t) % x + drop t % y)`; + `vec 0:real^1`; `vec 1:real^1`; + `{t | ((&1 - drop t) % (x:real^M) + drop t % y) IN k}`; + `(f:real^M->real^N) x`] + HAS_DERIVATIVE_ZERO_UNIQUE_STRONG_INTERVAL) THEN + REWRITE_TAC[o_THM] THEN ANTS_TAC THENL + [ALL_TAC; + DISCH_THEN(MP_TAC o SPEC `vec 1:real^1`) THEN + REWRITE_TAC[IN_INTERVAL_1; DROP_VEC; REAL_POS; REAL_LE_REFL] THEN + DISCH_THEN(SUBST1_TAC o SYM) THEN AP_TERM_TAC THEN VECTOR_ARITH_TAC] THEN + REPEAT CONJ_TAC THENL + [MATCH_MP_TAC COUNTABLE_IMAGE_INJ THEN ASM_REWRITE_TAC[] THEN + ASM_REWRITE_TAC[VECTOR_MUL_EQ_0; VECTOR_SUB_EQ; REAL_SUB_0; DROP_EQ; + VECTOR_ARITH `(&1 - t) % x + t % y = (&1 - u) % x + u % y <=> + (t - u) % (x - y) = vec 0`]; + MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN CONJ_TAC THENL + [MATCH_MP_TAC CONTINUOUS_ON_ADD THEN CONJ_TAC THEN + MATCH_MP_TAC CONTINUOUS_ON_VMUL THEN + REWRITE_TAC[o_DEF; LIFT_DROP; CONTINUOUS_ON_ID; LIFT_SUB] THEN + SIMP_TAC[CONTINUOUS_ON_SUB; CONTINUOUS_ON_CONST; CONTINUOUS_ON_ID]; + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET)) THEN + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; IN_INTERVAL_1; GSYM FORALL_DROP] THEN + REWRITE_TAC[DROP_VEC] THEN ASM_MESON_TAC[CONVEX_ALT]]; + AP_TERM_TAC THEN REWRITE_TAC[DROP_VEC] THEN VECTOR_ARITH_TAC; + ALL_TAC] THEN + X_GEN_TAC `t:real^1` THEN DISCH_TAC THEN + SUBGOAL_THEN `(\h. vec 0) = ((\h. vec 0):real^M->real^N) o + (\t. drop t % (y - x))` + SUBST1_TAC THENL [REWRITE_TAC[o_DEF]; ALL_TAC] THEN + MATCH_MP_TAC DIFF_CHAIN_WITHIN THEN CONJ_TAC THENL + [REWRITE_TAC[VECTOR_ARITH `t % (y - x) = ((&0 - t) % x) + t % y`] THEN + MATCH_MP_TAC HAS_DERIVATIVE_ADD THEN + REWRITE_TAC[GSYM DROP_NEG; GSYM DROP_VEC; GSYM DROP_SUB] THEN + SIMP_TAC[HAS_DERIVATIVE_VMUL_DROP; HAS_DERIVATIVE_ID] THEN + REWRITE_TAC[DROP_SUB; VECTOR_SUB_RDISTRIB] THEN + MATCH_MP_TAC HAS_DERIVATIVE_SUB THEN + REWRITE_TAC[VECTOR_MUL_LZERO; DROP_VEC; HAS_DERIVATIVE_CONST] THEN + SIMP_TAC[HAS_DERIVATIVE_VMUL_DROP; HAS_DERIVATIVE_ID]; + ALL_TAC] THEN + MATCH_MP_TAC HAS_DERIVATIVE_WITHIN_SUBSET THEN + EXISTS_TAC `s:real^M->bool` THEN REWRITE_TAC[SUBSET; FORALL_IN_IMAGE] THEN + REWRITE_TAC[IN_INTERVAL_1; GSYM FORALL_DROP; DROP_VEC] THEN + CONJ_TAC THENL [ALL_TAC; ASM_MESON_TAC[CONVEX_ALT]] THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_DIFF]) THEN + SIMP_TAC[IN_ELIM_THM; IN_DIFF] THEN REWRITE_TAC[SUBSET; FORALL_IN_IMAGE] THEN + REWRITE_TAC[IN_INTERVAL_1; GSYM FORALL_DROP; DROP_VEC] THEN + ASM_MESON_TAC[CONVEX_ALT]);; + +(* ------------------------------------------------------------------------- *) +(* Also to any open connected set with finite set of exceptions. Could *) +(* generalize to locally convex set with limpt-free set of exceptions. *) +(* ------------------------------------------------------------------------- *) + +let HAS_DERIVATIVE_ZERO_UNIQUE_STRONG_CONNECTED = prove + (`!f:real^M->real^N s k c y. + connected s /\ open s /\ COUNTABLE k /\ f continuous_on s /\ + c IN s /\ f c = y /\ + (!x. x IN (s DIFF k) ==> (f has_derivative (\h. vec 0)) (at x within s)) + ==> !x. x IN s ==> f x = y`, + REPEAT STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [CONNECTED_CLOPEN]) THEN + DISCH_THEN(MP_TAC o SPEC + `{x | x IN s /\ (f:real^M->real^N) x IN {y}}`) THEN + ANTS_TAC THENL [ALL_TAC; ASM SET_TAC[]] THEN CONJ_TAC THEN + ASM_SIMP_TAC[CONTINUOUS_CLOSED_IN_PREIMAGE; CLOSED_SING] THEN + MATCH_MP_TAC OPEN_OPEN_IN_TRANS THEN ASM_REWRITE_TAC[] THEN + CONJ_TAC THENL [ALL_TAC; SET_TAC[]] THEN + UNDISCH_TAC `open(s:real^M->bool)` THEN REWRITE_TAC[OPEN_CONTAINS_BALL] THEN + MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `u:real^M` THEN + REWRITE_TAC[SUBSET; IN_ELIM_THM; IN_SING] THEN + DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC MONO_EXISTS THEN + GEN_TAC THEN STRIP_TAC THEN ASM_SIMP_TAC[] THEN + MATCH_MP_TAC HAS_DERIVATIVE_ZERO_UNIQUE_STRONG_CONVEX THEN + MAP_EVERY EXISTS_TAC [`k:real^M->bool`; `u:real^M`] THEN + ASM_REWRITE_TAC[CONVEX_BALL; IN_DIFF; CENTRE_IN_BALL] THEN + CONJ_TAC THENL [ASM_MESON_TAC[SUBSET; CONTINUOUS_ON_SUBSET]; ALL_TAC] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_DERIVATIVE_WITHIN_SUBSET THEN + EXISTS_TAC `s:real^M->bool` THEN ASM_REWRITE_TAC[SUBSET] THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_SIMP_TAC[IN_DIFF]);; + +(* ------------------------------------------------------------------------- *) +(* Equiintegrability. The definition here only really makes sense for an *) +(* elementary set. We just use compact intervals in applications below. *) +(* ------------------------------------------------------------------------- *) + +parse_as_infix("equiintegrable_on",(12,"right"));; + +let equiintegrable_on = new_definition + `fs equiintegrable_on i <=> + (!f:real^M->real^N. f IN fs ==> f integrable_on i) /\ + (!e. &0 < e + ==> ?d. gauge d /\ + !f p. f IN fs /\ p tagged_division_of i /\ d fine p + ==> norm(vsum p (\(x,k). content(k) % f(x)) - + integral i f) < e)`;; + +let EQUIINTEGRABLE_ON_SING = prove + (`!f:real^M->real^N a b. + {f} equiintegrable_on interval[a,b] <=> + f integrable_on interval[a,b]`, + REPEAT GEN_TAC THEN REWRITE_TAC[equiintegrable_on] THEN + REWRITE_TAC[IN_SING; FORALL_UNWIND_THM2] THEN + ASM_CASES_TAC `(f:real^M->real^N) integrable_on interval[a,b]` THEN + ASM_REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_UNWIND_THM2] THEN + FIRST_ASSUM(MP_TAC o MATCH_MP INTEGRABLE_INTEGRAL) THEN + REWRITE_TAC[has_integral; IMP_IMP]);; + +(* ------------------------------------------------------------------------- *) +(* Basic combining theorems for the interval of integration. *) +(* ------------------------------------------------------------------------- *) + +let EQUIINTEGRABLE_ON_NULL = prove + (`!fs:(real^M->real^N)->bool a b. + content(interval[a,b]) = &0 ==> fs equiintegrable_on interval[a,b]`, + REPEAT STRIP_TAC THEN REWRITE_TAC[equiintegrable_on] THEN + ASM_SIMP_TAC[INTEGRABLE_ON_NULL] THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN + EXISTS_TAC `\x:real^M. ball(x,&1)` THEN REWRITE_TAC[GAUGE_TRIVIAL] THEN + FIRST_ASSUM(fun th -> SIMP_TAC[MATCH_MP (REWRITE_RULE[IMP_CONJ] + VSUM_CONTENT_NULL) th]) THEN + ASM_SIMP_TAC[INTEGRAL_NULL; VECTOR_SUB_REFL; NORM_0]);; + +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_DIVISION = prove + (`!fs:(real^M->real^N)->bool d a b. + d division_of interval[a,b] + ==> (fs equiintegrable_on interval[a,b] <=> + !i. i IN d ==> fs equiintegrable_on i)`, + REPEAT STRIP_TAC THEN CONV_TAC SYM_CONV THEN + MATCH_MP_TAC OPERATIVE_DIVISION_AND THEN + ASM_REWRITE_TAC[operative; NEUTRAL_AND] THEN + POP_ASSUM_LIST(K ALL_TAC) THEN CONJ_TAC THENL + [MAP_EVERY X_GEN_TAC [`a:real^M`; `b:real^M`] THEN DISCH_TAC THEN + ASM_SIMP_TAC[equiintegrable_on; INTEGRABLE_ON_NULL] THEN + GEN_TAC THEN DISCH_TAC THEN EXISTS_TAC `\x:real^M. ball(x,&1)` THEN + ASM_SIMP_TAC[GAUGE_TRIVIAL; INTEGRAL_NULL; VECTOR_SUB_RZERO] THEN + REPEAT STRIP_TAC THEN + FIRST_ASSUM(MATCH_MP_TAC o MATCH_MP (NORM_ARITH + `&0 < e ==> x = vec 0 ==> norm x < e`)) THEN + MATCH_MP_TAC VSUM_EQ_0 THEN REWRITE_TAC[FORALL_PAIR_THM] THEN + REPEAT STRIP_TAC THEN REWRITE_TAC[VECTOR_MUL_EQ_0] THEN DISJ1_TAC THEN + RULE_ASSUM_TAC(REWRITE_RULE[TAGGED_DIVISION_OF]) THEN + ASM_MESON_TAC[CONTENT_EQ_0_INTERIOR; SUBSET_INTERIOR; + SET_RULE `s = {} <=> s SUBSET {}`]; + ALL_TAC] THEN + MAP_EVERY X_GEN_TAC [`a:real^M`; `b:real^M`; `c:real`; `k:num`] THEN + STRIP_TAC THEN EQ_TAC THENL + [ALL_TAC; ASM_MESON_TAC[EQUIINTEGRABLE_ON_SPLIT]] THEN + ASM_SIMP_TAC[INTEGRABLE_SPLIT; equiintegrable_on] THEN + STRIP_TAC THEN CONJ_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 + ASM_CASES_TAC `gauge(d:real^M->real^M->bool)` THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `f:real^M->real^N` THEN + ASM_CASES_TAC `(f:real^M->real^N) IN fs` THEN ASM_REWRITE_TAC[] THEN + DISCH_TAC THEN + MP_TAC(ISPECL [`f:real^M->real^N`; `a:real^M`; `b:real^M`; + `d:real^M->real^M->bool`; `e / &2`] + HENSTOCK_LEMMA_PART1) THEN ASM_SIMP_TAC[REAL_HALF] 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 ANTS_TAC THENL + [ASM_REWRITE_TAC[] THEN MATCH_MP_TAC TAGGED_PARTIAL_DIVISION_OF_SUBSET THEN + RULE_ASSUM_TAC(REWRITE_RULE[tagged_division_of]) THEN + ASM_MESON_TAC[INTER_SUBSET]; + ALL_TAC] THEN + MATCH_MP_TAC(NORM_ARITH + `&0 < e /\ x:real^N = y ==> norm(x) <= e / &2 ==> norm(y) < e`) THEN + ASM_REWRITE_TAC[] THEN ASM_SIMP_TAC[INTERVAL_SPLIT] THEN + W(MP_TAC o PART_MATCH (lhand o rand) + INTEGRAL_COMBINE_TAGGED_DIVISION_TOPDOWN o rand o rand o snd) THEN + ASM_SIMP_TAC[GSYM INTERVAL_SPLIT; INTEGRABLE_SPLIT] THEN + DISCH_THEN SUBST1_TAC THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP TAGGED_DIVISION_OF_FINITE) THEN + ASM_SIMP_TAC[GSYM VSUM_SUB] THEN MATCH_MP_TAC VSUM_EQ THEN + REWRITE_TAC[FORALL_PAIR_THM]));; + +(* ------------------------------------------------------------------------- *) +(* Main limit theorem for an equiintegrable sequence. *) +(* ------------------------------------------------------------------------- *) + +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[]]);; + +(* ------------------------------------------------------------------------- *) +(* Combining theorems for the set of equiintegrable functions. *) +(* ------------------------------------------------------------------------- *) + +let EQUIINTEGRABLE_SUBSET = prove + (`!fs gs s. + fs equiintegrable_on s /\ gs SUBSET fs ==> gs equiintegrable_on s`, + REWRITE_TAC[equiintegrable_on; SUBSET] THEN 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_CMUL = prove + (`!fs:(real^M->real^N)->bool s k. + fs equiintegrable_on s + ==> {(\x. c % f x) | abs(c) <= k /\ f IN fs} equiintegrable_on s`, + REPEAT GEN_TAC THEN + SIMP_TAC[equiintegrable_on; INTEGRABLE_CMUL; FORALL_IN_GSPEC] THEN + STRIP_TAC 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_CMUL; IMP_IMP] THEN + FIRST_X_ASSUM(MP_TAC o SPEC `e / (abs(k) + &1)`) THEN + ASM_SIMP_TAC[REAL_LT_RDIV_EQ; REAL_MUL_LZERO; + REAL_ARITH `&0 < abs(k) + &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 [`c:real`; `f:real^M->real^N`; + `p:(real^M#(real^M->bool))->bool`] 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(REWRITE_RULE[IMP_CONJ] REAL_LET_TRANS) THEN + MATCH_MP_TAC(REAL_ARITH `&0 <= y /\ x <= c * y ==> x <= y * (c + &1)`) THEN + REWRITE_TAC[NORM_POS_LE] THEN MATCH_MP_TAC(REAL_ARITH + `!c. x = c * y /\ c * y <= k * y ==> x <= k * y`) THEN + EXISTS_TAC `abs c:real` THEN CONJ_TAC THENL + [REWRITE_TAC[GSYM NORM_MUL; GSYM VSUM_LMUL; VECTOR_SUB_LDISTRIB] THEN + REWRITE_TAC[LAMBDA_PAIR_THM; VECTOR_MUL_ASSOC; REAL_MUL_SYM]; + MATCH_MP_TAC REAL_LE_RMUL THEN REWRITE_TAC[NORM_POS_LE] THEN + ASM_REAL_ARITH_TAC]);; + +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_NEG = prove + (`!fs:(real^M->real^N)->bool s. + fs equiintegrable_on s + ==> {(\x. --(f x)) | f IN fs} equiintegrable_on s`, + REPEAT STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o SPEC `&1` o MATCH_MP EQUIINTEGRABLE_CMUL) THEN + MATCH_MP_TAC (REWRITE_RULE[IMP_CONJ_ALT] EQUIINTEGRABLE_SUBSET) THEN + REWRITE_TAC[SUBSET; FORALL_IN_GSPEC] THEN REWRITE_TAC[IN_ELIM_THM] THEN + X_GEN_TAC `f:real^M->real^N` THEN DISCH_TAC THEN EXISTS_TAC `-- &1` THEN + EXISTS_TAC `f:real^M->real^N` THEN + ASM_REWRITE_TAC[VECTOR_MUL_LNEG; VECTOR_MUL_LID] THEN REAL_ARITH_TAC);; + +let EQUIINTEGRABLE_SUB = 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 DISCH_THEN(CONJUNCTS_THEN2 + MP_TAC (MP_TAC o MATCH_MP EQUIINTEGRABLE_NEG)) THEN + REWRITE_TAC[GSYM IMP_CONJ_ALT] THEN + DISCH_THEN(MP_TAC o MATCH_MP EQUIINTEGRABLE_ADD) THEN + MATCH_MP_TAC (REWRITE_RULE[IMP_CONJ_ALT] EQUIINTEGRABLE_SUBSET) THEN + REWRITE_TAC[SUBSET; FORALL_IN_GSPEC] THEN REWRITE_TAC[IN_ELIM_THM] THEN + MAP_EVERY X_GEN_TAC [`f:real^M->real^N`; `g:real^M->real^N`] THEN + STRIP_TAC THEN EXISTS_TAC `f:real^M->real^N` THEN + EXISTS_TAC `\x. --((g:real^M->real^N) x)` THEN + ASM_REWRITE_TAC[VECTOR_SUB] THEN EXISTS_TAC `g:real^M->real^N` THEN + ASM_REWRITE_TAC[]);; + +let EQUIINTEGRABLE_SUM = prove + (`!fs:(real^M->real^N)->bool a b. + fs equiintegrable_on interval[a,b] + ==> {(\x. vsum t (\i. c i % f i x)) | + FINITE t /\ + (!i:A. i IN t ==> &0 <= c i /\ (f i) IN fs) /\ + sum t c = &1} + equiintegrable_on interval[a,b]`, + REPEAT GEN_TAC THEN REWRITE_TAC[equiintegrable_on] THEN + REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_GSPEC] THEN + REWRITE_TAC[IMP_IMP; GSYM CONJ_ASSOC; RIGHT_IMP_FORALL_THM] THEN + STRIP_TAC THEN + ASM (CONV_TAC o GEN_SIMPLIFY_CONV TOP_DEPTH_SQCONV (basic_ss []) 5) + [INTEGRABLE_CMUL; INTEGRABLE_VSUM; ETA_AX; INTEGRAL_VSUM] 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 + [`t:A->bool`; `c:A->real`; `f:A->real^M->real^N`; + `p:(real^M#(real^M->bool))->bool`] THEN + STRIP_TAC THEN + SUBGOAL_THEN + `!i:A. i IN t + ==> integral (interval[a,b]) (\x:real^M. c i % f i x:real^N) = + vsum p (\(x:real^M,k). + integral (k:real^M->bool) (\x:real^M. c i % f i x))` + (fun th -> SIMP_TAC[th]) + THENL + [REPEAT STRIP_TAC THEN + MATCH_MP_TAC INTEGRAL_COMBINE_TAGGED_DIVISION_TOPDOWN THEN + ASM_SIMP_TAC[INTEGRABLE_CMUL; ETA_AX]; + ALL_TAC] THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP TAGGED_DIVISION_OF_FINITE) THEN + SUBGOAL_THEN + `vsum p (\(x,k:real^M->bool). content k % vsum t (\i. c i % f i x)) = + vsum t (\i. c i % + vsum p (\(x,k). content k % (f:A->real^M->real^N) i x))` + SUBST1_TAC THENL + [REWRITE_TAC[GSYM VSUM_LMUL] THEN + W(MP_TAC o PART_MATCH (lhs o rand) VSUM_SWAP o + rand o snd) THEN + ASM_REWRITE_TAC[] THEN DISCH_THEN SUBST1_TAC THEN + MATCH_MP_TAC VSUM_EQ THEN REWRITE_TAC[FORALL_PAIR_THM] THEN + REWRITE_TAC[VECTOR_MUL_ASSOC; REAL_MUL_SYM]; + ALL_TAC] THEN + MATCH_MP_TAC REAL_LET_TRANS THEN + EXISTS_TAC `sum t (\i:A. c i * e / &2)` THEN CONJ_TAC THENL + [ALL_TAC; + ASM_SIMP_TAC[SUM_RMUL; ETA_AX; REAL_MUL_LID] THEN ASM_REAL_ARITH_TAC] THEN + ASM_SIMP_TAC[GSYM VSUM_SUB] THEN MATCH_MP_TAC VSUM_NORM_LE THEN + ASM_REWRITE_TAC[] THEN X_GEN_TAC `i:A` THEN DISCH_TAC THEN + ASM_SIMP_TAC[GSYM VSUM_LMUL; GSYM VSUM_SUB] THEN + REWRITE_TAC[LAMBDA_PAIR_THM] THEN FIRST_X_ASSUM(MP_TAC o SPECL + [`(f:A->real^M->real^N) i`; `p:(real^M#(real^M->bool))->bool`]) THEN + ASM_SIMP_TAC[] THEN DISCH_THEN(MP_TAC o MATCH_MP REAL_LT_IMP_LE) THEN + DISCH_THEN(MP_TAC o SPEC `abs((c:A->real) i)` o + MATCH_MP(REWRITE_RULE[IMP_CONJ_ALT] REAL_LE_LMUL)) THEN + ASM_REWRITE_TAC[REAL_ABS_POS; GSYM NORM_MUL] THEN + ASM_SIMP_TAC[GSYM VSUM_LMUL; VECTOR_SUB_LDISTRIB; real_abs] THEN + REWRITE_TAC[LAMBDA_PAIR_THM] THEN + MATCH_MP_TAC(REAL_ARITH `x = y ==> x <= a ==> y <= a`) THEN + AP_TERM_TAC THEN + SUBGOAL_THEN + `integral (interval[a,b]) ((f:A->real^M->real^N) i) = + vsum p (\(x:real^M,k). integral (k:real^M->bool) (f i))` + SUBST1_TAC THENL + [MATCH_MP_TAC INTEGRAL_COMBINE_TAGGED_DIVISION_TOPDOWN THEN ASM_SIMP_TAC[]; + ALL_TAC] THEN + ASM_SIMP_TAC[GSYM VSUM_LMUL; GSYM VSUM_SUB] THEN + 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 + AP_TERM_TAC THEN CONV_TAC SYM_CONV THEN MATCH_MP_TAC INTEGRAL_CMUL THEN + RULE_ASSUM_TAC(REWRITE_RULE[TAGGED_DIVISION_OF]) THEN + ASM_MESON_TAC[INTEGRABLE_SUBINTERVAL]);; + +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 EQUIINTEGRABLE_REFLECT = prove + (`!fs:(real^M->real^N)->bool a b. + fs equiintegrable_on interval[a,b] + ==> {(\x. f(--x)) | f IN fs} equiintegrable_on interval[--b,--a]`, + 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 GEN_TAC THEN REWRITE_TAC[equiintegrable_on] THEN + REWRITE_TAC[RIGHT_FORALL_IMP_THM; IMP_CONJ; FORALL_IN_GSPEC] THEN + DISCH_TAC THEN DISCH_TAC THEN + ASM_REWRITE_TAC[INTEGRABLE_REFLECT; INTEGRAL_REFLECT] THEN + X_GEN_TAC `e:real` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `e:real`) THEN ASM_REWRITE_TAC[] THEN + FIRST_X_ASSUM(K ALL_TAC o check (is_forall o concl)) THEN + DISCH_THEN(X_CHOOSE_THEN `d:real^M->real^M->bool` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `\x. IMAGE (--) ((d:real^M->real^M->bool) (--x))` THEN + CONJ_TAC THENL + [FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [gauge]) THEN + SIMP_TAC[gauge; OPEN_NEGATIONS] THEN DISCH_TAC THEN + GEN_TAC THEN GEN_REWRITE_TAC LAND_CONV [GSYM VECTOR_NEG_NEG] THEN + MATCH_MP_TAC FUN_IN_IMAGE THEN ASM_REWRITE_TAC[]; + ALL_TAC] THEN + X_GEN_TAC `f:real^M->real^N` THEN DISCH_TAC THEN + X_GEN_TAC `p:real^M#(real^M->bool)->bool` THEN REPEAT DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `f:real^M->real^N`) THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(MP_TAC o SPEC + `IMAGE (\(x,k). (--x:real^M,IMAGE (--) (k:real^M->bool))) p`) THEN + ANTS_TAC THENL + [FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [TAGGED_DIVISION_OF]) THEN + REWRITE_TAC[TAGGED_DIVISION_OF] THEN + STRIP_TAC THEN ASM_SIMP_TAC[FINITE_IMAGE] THEN + REWRITE_TAC[RIGHT_FORALL_IMP_THM; IMP_CONJ; lemma] THEN + REPEAT CONJ_TAC THENL + [MAP_EVERY X_GEN_TAC [`x:real^M`; `k:real^M->bool`] THEN DISCH_TAC THEN + ASM_SIMP_TAC[FUN_IN_IMAGE] THEN CONJ_TAC THENL + [REWRITE_TAC[SUBSET; FORALL_IN_IMAGE] THEN + ONCE_REWRITE_TAC[GSYM IN_INTERVAL_REFLECT] THEN + ASM_SIMP_TAC[VECTOR_NEG_NEG; GSYM SUBSET] THEN ASM_MESON_TAC[]; + REWRITE_TAC[EXTENSION; IN_IMAGE] THEN + REWRITE_TAC[VECTOR_ARITH `x:real^N = --y <=> --x = y`] THEN + ONCE_REWRITE_TAC[GSYM IN_INTERVAL_REFLECT] THEN + REWRITE_TAC[UNWIND_THM1] THEN + SUBGOAL_THEN `?u v:real^M. k = interval[u,v]` + (REPEAT_TCL CHOOSE_THEN SUBST_ALL_TAC) + THENL [ASM_MESON_TAC[TAGGED_DIVISION_OF]; ALL_TAC] THEN + ASM_MESON_TAC[VECTOR_NEG_NEG]]; + MAP_EVERY X_GEN_TAC [`x:real^M`; `k:real^M->bool`] THEN DISCH_TAC THEN + MAP_EVERY X_GEN_TAC [`y:real^M`; `l:real^M->bool`] THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPECL + [`x:real^M`; `k:real^M->bool`; + `y:real^M`; `l:real^M->bool`]) THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC MONO_IMP THEN + CONJ_TAC THENL [MESON_TAC[PAIR_EQ]; ALL_TAC] THEN + REWRITE_TAC[INTERIOR_NEGATIONS] THEN + MATCH_MP_TAC(SET_RULE + `(!x. f(f x) = x) + ==> s INTER t = {} ==> IMAGE f s INTER IMAGE f t = {}`) THEN + REWRITE_TAC[VECTOR_NEG_NEG]; + GEN_REWRITE_TAC I [EXTENSION] THEN + ONCE_REWRITE_TAC[GSYM IN_INTERVAL_REFLECT] THEN + FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN X_GEN_TAC `y:real^M` THEN + REWRITE_TAC[IN_UNIONS; IN_ELIM_THM] THEN + MATCH_MP_TAC(MESON[] + `!f. (!x. f(f x) = x) /\ (!x. P x <=> Q(f x)) + ==> ((?x. P x) <=> (?x. Q x))`) THEN + EXISTS_TAC `IMAGE ((--):real^M->real^M)` THEN CONJ_TAC THENL + [REWRITE_TAC[GSYM IMAGE_o; o_DEF; VECTOR_NEG_NEG; IMAGE_ID]; + ALL_TAC] THEN + X_GEN_TAC `t:real^M->bool` THEN BINOP_TAC THENL + [REWRITE_TAC[IN_IMAGE; EXISTS_PAIR_THM; PAIR_EQ] THEN + SUBGOAL_THEN `!k:real^M->bool. IMAGE (--) (IMAGE (--) k) = k` + MP_TAC THENL + [REWRITE_TAC[GSYM IMAGE_o; o_DEF; VECTOR_NEG_NEG; IMAGE_ID]; + MESON_TAC[]]; + MATCH_MP_TAC(SET_RULE + `(!x. f(f x) = x) ==> (y IN s <=> f y IN IMAGE f s)`) THEN + REWRITE_TAC[VECTOR_NEG_NEG]]]; + ANTS_TAC THENL + [FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [fine]) THEN + REWRITE_TAC[fine; lemma] THEN + REPEAT(MATCH_MP_TAC MONO_FORALL THEN GEN_TAC) THEN + MATCH_MP_TAC MONO_IMP THEN REWRITE_TAC[] THEN + MATCH_MP_TAC(SET_RULE + `(!x. f(f x) = x) ==> k SUBSET IMAGE f s ==> IMAGE f k SUBSET s`) THEN + REWRITE_TAC[VECTOR_NEG_NEG]; + ALL_TAC] THEN + MATCH_MP_TAC(NORM_ARITH + `x:real^N = y ==> norm(x - i) < e ==> norm(y - i) < e`) THEN + W(MP_TAC o PART_MATCH (lhs o rand) VSUM_IMAGE o lhs o snd) THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP TAGGED_DIVISION_OF_FINITE) THEN + ASM_REWRITE_TAC[] THEN ANTS_TAC THENL + [MATCH_MP_TAC(MESON[] + `(!x. f(f x) = x) + ==> !x y. x IN p /\ y IN p /\ f x = f y ==> x = y`) THEN + REWRITE_TAC[FORALL_PAIR_THM; GSYM IMAGE_o; o_DEF; VECTOR_NEG_NEG; + IMAGE_ID]; + DISCH_THEN SUBST1_TAC THEN MATCH_MP_TAC VSUM_EQ THEN + REWRITE_TAC[FORALL_PAIR_THM; o_THM] THEN + MAP_EVERY X_GEN_TAC [`x:real^M`; `k:real^M->bool`] THEN DISCH_TAC THEN + SUBGOAL_THEN `?u v:real^M. k = interval[u,v]` + (REPEAT_TCL CHOOSE_THEN SUBST_ALL_TAC) + THENL [ASM_MESON_TAC[TAGGED_DIVISION_OF]; ALL_TAC] THEN + AP_THM_TAC THEN AP_TERM_TAC THEN + SUBGOAL_THEN `(--):real^M->real^M = (\x. --(&1) % x + vec 0)` SUBST1_TAC + THENL [REWRITE_TAC[FUN_EQ_THM] THEN VECTOR_ARITH_TAC; ALL_TAC] THEN + REWRITE_TAC[CONTENT_IMAGE_AFFINITY_INTERVAL; REAL_ABS_NEG] THEN + REWRITE_TAC[REAL_POW_ONE; REAL_MUL_LID; REAL_ABS_NUM]]]);; + +(* ------------------------------------------------------------------------- *) +(* Some technical lemmas about minimizing a "flat" part of a sum over a *) +(* division, followed by subinterval resictions for equiintegrable family. *) +(* ------------------------------------------------------------------------- *) + +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"; "t"] THEN + SIMP_TAC[SUBSET; FORALL_PAIR_THM; IN_ELIM_PAIR_THM]; + ALL_TAC] THEN + SUBGOAL_THEN + `FINITE(s:(real^M#(real^M->bool))->bool) /\ + FINITE(t:(real^M#(real^M->bool))->bool)` + STRIP_ASSUME_TAC THENL [ASM_MESON_TAC[FINITE_SUBSET]; ALL_TAC] THEN + SUBGOAL_THEN `DISJOINT (s:(real^M#(real^M->bool))->bool) t` ASSUME_TAC THENL + [MAP_EVERY EXPAND_TAC ["s"; "t"] THEN + REWRITE_TAC[EXTENSION; DISJOINT; IN_INTER; FORALL_PAIR_THM; + IN_ELIM_PAIR_THM] THEN SET_TAC[]; + ALL_TAC] THEN + SUBGOAL_THEN `r:(real^M#(real^M->bool))->bool = s UNION t` SUBST1_TAC THENL + [MAP_EVERY EXPAND_TAC ["s"; "t"] THEN + REWRITE_TAC[EXTENSION; IN_UNION; FORALL_PAIR_THM; IN_ELIM_PAIR_THM] THEN + SET_TAC[]; + ALL_TAC] THEN + ASM_SIMP_TAC[SUM_UNION] THEN MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC + `sum s (\(x:real^M,k). norm + (integral k (h:real^M->real^N) - + integral k (\x. if x$i <= c then h x else vec 0))) + + sum t (\(x:real^M,k). norm + ((content k % (h:real^M->real^N) x - integral k h) + + integral k (\x. if x$i <= c then h x else vec 0)))` THEN + CONJ_TAC THENL + [MATCH_MP_TAC REAL_EQ_IMP_LE THEN BINOP_TAC THEN + MATCH_MP_TAC SUM_EQ THEN REWRITE_TAC[FORALL_PAIR_THM] THEN + MAP_EVERY X_GEN_TAC [`x:real^M`; `k:real^M->bool`] THEN + MAP_EVERY EXPAND_TAC ["s"; "t"] THEN + REWRITE_TAC[IN_ELIM_PAIR_THM] THEN REWRITE_TAC[IN_ELIM_THM] THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THENL + [MATCH_MP_TAC(NORM_ARITH `a:real^N = --b ==> norm a = norm b`) THEN + VECTOR_ARITH_TAC; + AP_TERM_TAC THEN VECTOR_ARITH_TAC]; + ALL_TAC] THEN + SUBGOAL_THEN `s tagged_partial_division_of interval[a:real^M,b] /\ + t tagged_partial_division_of interval[a:real^M,b] /\ + g0 fine s /\ g1 fine s /\ g0 fine t /\ g1 fine t` + STRIP_ASSUME_TAC THENL + [ASM_MESON_TAC[TAGGED_PARTIAL_DIVISION_SUBSET; FINE_SUBSET]; + ALL_TAC] THEN + MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC + `(sum s (\(x:real^M,k). norm(integral k (h:real^M->real^N))) + + sum (IMAGE (\(x,k). (x,k INTER {x | x$i <= c})) s) + (\(x:real^M,k). norm(integral k (h:real^M->real^N)))) + + (sum t (\(x:real^M,k). norm(content k % h x - integral k h)) + + sum t (\(x:real^M,k). norm(integral k (h:real^M->real^N))) + + sum (IMAGE (\(x,k). (x,k INTER {x | x$i >= c})) t) + (\(x:real^M,k). norm(integral k (h:real^M->real^N))))` THEN + CONJ_TAC THENL + [MATCH_MP_TAC REAL_LE_ADD2 THEN CONJ_TAC THENL + [W(MP_TAC o PART_MATCH (lhand o rand) SUM_IMAGE_NONZERO o + rand o rand o snd) THEN + ANTS_TAC THENL + [ASM_REWRITE_TAC[FORALL_PAIR_THM] THEN + MAP_EVERY X_GEN_TAC + [`x:real^M`; `k:real^M->bool`; `y:real^M`; `l:real^M->bool`] THEN + ASM_CASES_TAC `x:real^M = y` THEN ASM_REWRITE_TAC[PAIR_EQ] THEN + REPEAT STRIP_TAC THEN MP_TAC(ISPECL + [`s:real^M#(real^M->bool)->bool`; + `UNIONS(IMAGE SND (s:real^M#(real^M->bool)->bool))`; + `x:real^M`; `k:real^M->bool`; + `y:real^M`; `l:real^M->bool`; `i:num`; `c:real`] + TAGGED_DIVISION_SPLIT_LEFT_INJ) THEN + ASM_REWRITE_TAC[] THEN ANTS_TAC THENL + [ASM_MESON_TAC[TAGGED_PARTIAL_DIVISION_OF_UNION_SELF]; ALL_TAC] THEN + REWRITE_TAC[NORM_EQ_0] THEN + SUBGOAL_THEN `?u v:real^M. l = interval[u,v]` + (REPEAT_TCL CHOOSE_THEN SUBST1_TAC) + THENL [ASM_MESON_TAC[tagged_partial_division_of]; ALL_TAC] THEN + ASM_SIMP_TAC[INTERVAL_SPLIT; INTEGRAL_NULL]; + DISCH_THEN SUBST1_TAC THEN + ASM_SIMP_TAC[GSYM SUM_ADD] THEN MATCH_MP_TAC SUM_LE THEN + ASM_REWRITE_TAC[o_THM; FORALL_PAIR_THM] THEN + ONCE_REWRITE_TAC[SET_RULE + `x$i <= c <=> x IN {x:real^M | x$i <= c}`] THEN + REWRITE_TAC[INTEGRAL_RESTRICT_INTER] THEN + REWRITE_TAC[IN_ELIM_THM; INTER_COMM] THEN + REWRITE_TAC[NORM_ARITH `norm(a - b:real^N) <= norm a + norm b`]]; + W(MP_TAC o PART_MATCH (lhand o rand) SUM_IMAGE_NONZERO o + rand o rand o rand o snd) THEN + ANTS_TAC THENL + [ASM_REWRITE_TAC[FORALL_PAIR_THM] THEN + MAP_EVERY X_GEN_TAC + [`x:real^M`; `k:real^M->bool`; `y:real^M`; `l:real^M->bool`] THEN + ASM_CASES_TAC `x:real^M = y` THEN ASM_REWRITE_TAC[PAIR_EQ] THEN + REPEAT STRIP_TAC THEN MP_TAC(ISPECL + [`t:real^M#(real^M->bool)->bool`; + `UNIONS(IMAGE SND (t:real^M#(real^M->bool)->bool))`; + `x:real^M`; `k:real^M->bool`; + `y:real^M`; `l:real^M->bool`; `i:num`; `c:real`] + TAGGED_DIVISION_SPLIT_RIGHT_INJ) THEN + ASM_REWRITE_TAC[] THEN ANTS_TAC THENL + [ASM_MESON_TAC[TAGGED_PARTIAL_DIVISION_OF_UNION_SELF]; ALL_TAC] THEN + REWRITE_TAC[NORM_EQ_0] THEN + SUBGOAL_THEN `?u v:real^M. l = interval[u,v]` + (REPEAT_TCL CHOOSE_THEN SUBST1_TAC) + THENL [ASM_MESON_TAC[tagged_partial_division_of]; ALL_TAC] THEN + ASM_SIMP_TAC[INTERVAL_SPLIT; INTEGRAL_NULL]; + DISCH_THEN SUBST1_TAC THEN + ASM_SIMP_TAC[GSYM SUM_ADD] THEN MATCH_MP_TAC SUM_LE THEN + ASM_REWRITE_TAC[o_THM; FORALL_PAIR_THM] THEN + MAP_EVERY X_GEN_TAC [`x:real^M`; `k:real^M->bool`] THEN DISCH_TAC THEN + MATCH_MP_TAC(NORM_ARITH + `i = i1 + i2 + ==> norm(c + i1:real^N) <= norm(c) + norm(i) + norm(i2)`) THEN + ONCE_REWRITE_TAC[SET_RULE + `x$i <= c <=> x IN {x:real^M | x$i <= c}`] THEN + REWRITE_TAC[INTEGRAL_RESTRICT_INTER] THEN + ONCE_REWRITE_TAC[SET_RULE `{x | P x} INTER s = s INTER {x | P x}`] THEN + SUBGOAL_THEN `?u v:real^M. k = interval[u,v]` + (REPEAT_TCL CHOOSE_THEN SUBST_ALL_TAC) + THENL [ASM_MESON_TAC[tagged_partial_division_of]; ALL_TAC] THEN + ASM_SIMP_TAC[INTERVAL_SPLIT] THEN MATCH_MP_TAC INTEGRAL_SPLIT THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC INTEGRABLE_ON_SUBINTERVAL THEN + EXISTS_TAC `interval[a:real^M,b]` THEN + ASM_SIMP_TAC[] THEN ASM_MESON_TAC[tagged_partial_division_of]]]; + ALL_TAC] THEN + SUBGOAL_THEN + `!x:real^M k. (x,k) IN r ==> ~(k INTER {x:real^M | x$i = c} = {})` + ASSUME_TAC THENL + [REPEAT GEN_TAC THEN MAP_EVERY EXPAND_TAC ["r"; "q"] THEN + REWRITE_TAC[IN_ELIM_PAIR_THM] THEN + REWRITE_TAC[GSYM CONJ_ASSOC; SUBSET; EXTENSION; NOT_FORALL_THM] THEN + REWRITE_TAC[IN_ELIM_THM; NOT_IN_EMPTY; IN_INTER; NOT_IMP] THEN + DISCH_TAC THEN MATCH_MP_TAC CONNECTED_IVT_COMPONENT THEN + REWRITE_TAC[RIGHT_EXISTS_AND_THM] THEN + CONJ_TAC THENL [ALL_TAC; ASM_MESON_TAC[REAL_LE_TOTAL]] THEN + SUBGOAL_THEN `?u v:real^M. k = interval[u,v]` + (REPEAT_TCL CHOOSE_THEN SUBST_ALL_TAC) + THENL [ASM_MESON_TAC[TAGGED_DIVISION_OF]; ALL_TAC] THEN + MATCH_MP_TAC CONVEX_CONNECTED THEN REWRITE_TAC[CONVEX_INTERVAL]; + ALL_TAC] THEN + MATCH_MP_TAC(REAL_ARITH + `x <= e / &6 /\ y <= e / &2 ==> x + y <= &2 * e / &3`) THEN + CONJ_TAC THENL + [MATCH_MP_TAC(REAL_ARITH + `x < e / &12 /\ y < e / &12 ==> x + y <= e / &6`) THEN + CONJ_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + EXISTS_TAC `(lambda j. if j = i then c else (a:real^M)$j):real^M` THEN + EXISTS_TAC `i:num` THEN ASM_SIMP_TAC[LAMBDA_BETA; IN_INTERVAL] THENL + [CONJ_TAC THENL + [X_GEN_TAC `j:num` THEN COND_CASES_TAC THEN + ASM_SIMP_TAC[REAL_LT_IMP_LE; REAL_LE_REFL]; + EXPAND_TAC "s" THEN REWRITE_TAC[IN_ELIM_PAIR_THM] THEN + ASM_MESON_TAC[]]; + REPEAT CONJ_TAC THENL + [X_GEN_TAC `j:num` THEN COND_CASES_TAC THEN + ASM_SIMP_TAC[REAL_LT_IMP_LE; REAL_LE_REFL]; + UNDISCH_TAC `s tagged_partial_division_of interval[a:real^M,b]`; + UNDISCH_TAC `(g0:real^M->real^M->bool) fine s` THEN + REWRITE_TAC[fine; FORALL_IN_IMAGE; lemma] THEN SET_TAC[]; + REWRITE_TAC[lemma] THEN + REPEAT GEN_TAC THEN EXPAND_TAC "s" THEN REWRITE_TAC[IN_ELIM_THM] THEN + DISCH_TAC THEN MATCH_MP_TAC(SET_RULE + `~(k INTER t = {}) /\ t SUBSET s ==> ~((k INTER s) INTER t = {})`) THEN + SIMP_TAC[SUBSET; IN_ELIM_THM; REAL_LE_REFL] THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_MESON_TAC[]]]; + MATCH_MP_TAC(REAL_ARITH + `x < e / &3 /\ y < e / &12 /\ z < e / &12 ==> x + y + z <= e / &2`) THEN + REPEAT CONJ_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[] THEN + EXISTS_TAC `(lambda j. if j = i then c else (a:real^M)$j):real^M` THEN + EXISTS_TAC `i:num` THEN ASM_SIMP_TAC[LAMBDA_BETA; IN_INTERVAL] THENL + [CONJ_TAC THENL + [X_GEN_TAC `j:num` THEN COND_CASES_TAC THEN + ASM_SIMP_TAC[REAL_LT_IMP_LE; REAL_LE_REFL]; + EXPAND_TAC "t" THEN REWRITE_TAC[IN_ELIM_PAIR_THM] THEN + ASM_MESON_TAC[]]; + REPEAT CONJ_TAC THENL + [X_GEN_TAC `j:num` THEN COND_CASES_TAC THEN + ASM_SIMP_TAC[REAL_LT_IMP_LE; REAL_LE_REFL]; + UNDISCH_TAC `t tagged_partial_division_of interval[a:real^M,b]`; + UNDISCH_TAC `(g0:real^M->real^M->bool) fine t` THEN + REWRITE_TAC[fine; FORALL_IN_IMAGE; lemma] THEN SET_TAC[]; + REWRITE_TAC[lemma] THEN + REPEAT GEN_TAC THEN EXPAND_TAC "t" THEN REWRITE_TAC[IN_ELIM_THM] THEN + DISCH_TAC THEN MATCH_MP_TAC(SET_RULE + `~(k INTER t = {}) /\ t SUBSET s ==> ~((k INTER s) INTER t = {})`) THEN + SIMP_TAC[SUBSET; IN_ELIM_THM; REAL_LE_REFL; real_ge] THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_MESON_TAC[]]]] THEN + REWRITE_TAC[tagged_partial_division_of] THEN + (MATCH_MP_TAC MONO_AND THEN SIMP_TAC[FINITE_IMAGE] THEN + MATCH_MP_TAC MONO_AND THEN + REWRITE_TAC[RIGHT_FORALL_IMP_THM; IMP_CONJ; FORALL_IN_GSPEC] THEN + REWRITE_TAC[lemma] THEN CONJ_TAC THEN + MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `x:real^M` THEN + MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `k:real^M->bool` THEN + DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN ASM_REWRITE_TAC[] THENL + [MATCH_MP_TAC MONO_AND THEN CONJ_TAC THENL + [SIMP_TAC[real_ge; IN_INTER; IN_ELIM_THM] THEN ASM SET_TAC[REAL_LE_TOTAL]; + MATCH_MP_TAC MONO_AND THEN CONJ_TAC THENL + [SET_TAC[]; + STRIP_TAC THEN ASM_SIMP_TAC[INTERVAL_SPLIT] THEN MESON_TAC[]]]; + REPEAT(MATCH_MP_TAC MONO_FORALL THEN GEN_TAC) THEN + MATCH_MP_TAC MONO_IMP THEN REWRITE_TAC[] THEN + MATCH_MP_TAC MONO_IMP THEN SIMP_TAC[PAIR_EQ; CONTRAPOS_THM] 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 REWRITE_TAC[INTER_SUBSET]]));; + +let EQUIINTEGRABLE_HALFSPACE_RESTRICTIONS_GE = 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]`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL + [`{\x. (f:real^M->real^N) (--x) | f IN fs}`; + `\x. (f:real^M->real^N)(--x)`; + `--b:real^M`; `--a:real^M`] + EQUIINTEGRABLE_HALFSPACE_RESTRICTIONS_LE) THEN + ASM_SIMP_TAC[EQUIINTEGRABLE_REFLECT] THEN ANTS_TAC THENL + [ASM_SIMP_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_GSPEC] THEN + ONCE_REWRITE_TAC[GSYM IN_INTERVAL_REFLECT] THEN + ASM_SIMP_TAC[VECTOR_NEG_NEG] THEN + REWRITE_TAC[SIMPLE_IMAGE; IN_IMAGE] THEN + EXISTS_TAC `f:real^M->real^N` THEN ASM_REWRITE_TAC[]; + DISCH_THEN(MP_TAC o MATCH_MP EQUIINTEGRABLE_REFLECT) THEN + REWRITE_TAC[VECTOR_NEG_NEG] THEN MATCH_MP_TAC + (REWRITE_RULE[IMP_CONJ_ALT] EQUIINTEGRABLE_SUBSET) THEN + REWRITE_TAC[SUBSET; FORALL_IN_GSPEC] THEN + MAP_EVERY X_GEN_TAC [`i:num`; `c:real`; `h:real^M->real^N`] THEN + STRIP_TAC THEN REWRITE_TAC[IN_ELIM_THM] THEN EXISTS_TAC + `(\x. if (--x)$i >= c then (h:real^M->real^N)(--x) else vec 0)` THEN + REWRITE_TAC[VECTOR_NEG_NEG] THEN MAP_EVERY EXISTS_TAC + [`i:num`; `--c:real`; `\x. (h:real^M->real^N)(--x)`] THEN + ASM_REWRITE_TAC[IN_UNIV; VECTOR_NEG_COMPONENT] THEN + REWRITE_TAC[REAL_ARITH `--x >= c <=> x <= --c`] THEN + EXISTS_TAC `h:real^M->real^N` THEN ASM_REWRITE_TAC[]]);; + +let EQUIINTEGRABLE_HALFSPACE_RESTRICTIONS_LT = 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]`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`fs:(real^M->real^N)->bool`; `f:real^M->real^N`; + `a:real^M`; `b:real^M`] + EQUIINTEGRABLE_HALFSPACE_RESTRICTIONS_GE) THEN + ASM_REWRITE_TAC[] THEN UNDISCH_TAC + `(fs:(real^M->real^N)->bool) equiintegrable_on interval[a,b]` THEN + REWRITE_TAC[IMP_IMP] THEN + DISCH_THEN(MP_TAC o MATCH_MP EQUIINTEGRABLE_SUB) THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] EQUIINTEGRABLE_SUBSET) THEN + REWRITE_TAC[SUBSET; FORALL_IN_GSPEC] THEN + MAP_EVERY X_GEN_TAC [`i:num`; `c:real`; `h:real^M->real^N`] THEN + STRIP_TAC THEN REWRITE_TAC[IN_ELIM_THM] THEN + EXISTS_TAC `h:real^M->real^N` THEN + EXISTS_TAC `\x. if x$i >= c then (h:real^M->real^N) x else vec 0` THEN + ASM_REWRITE_TAC[] THEN CONJ_TAC THENL + [MAP_EVERY EXISTS_TAC [`i:num`; `c:real`; `h:real^M->real^N`] THEN + ASM_REWRITE_TAC[]; + REWRITE_TAC[FUN_EQ_THM; real_ge; GSYM REAL_NOT_LT] THEN + GEN_TAC THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN + VECTOR_ARITH_TAC]);; + +let EQUIINTEGRABLE_HALFSPACE_RESTRICTIONS_GT = 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]`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`fs:(real^M->real^N)->bool`; `f:real^M->real^N`; + `a:real^M`; `b:real^M`] + EQUIINTEGRABLE_HALFSPACE_RESTRICTIONS_LE) THEN + ASM_REWRITE_TAC[] THEN UNDISCH_TAC + `(fs:(real^M->real^N)->bool) equiintegrable_on interval[a,b]` THEN + REWRITE_TAC[IMP_IMP] THEN + DISCH_THEN(MP_TAC o MATCH_MP EQUIINTEGRABLE_SUB) THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] EQUIINTEGRABLE_SUBSET) THEN + REWRITE_TAC[SUBSET; FORALL_IN_GSPEC] THEN + MAP_EVERY X_GEN_TAC [`i:num`; `c:real`; `h:real^M->real^N`] THEN + STRIP_TAC THEN REWRITE_TAC[IN_ELIM_THM] THEN + EXISTS_TAC `h:real^M->real^N` THEN + EXISTS_TAC `\x. if x$i <= c then (h:real^M->real^N) x else vec 0` THEN + ASM_REWRITE_TAC[] THEN CONJ_TAC THENL + [MAP_EVERY EXISTS_TAC [`i:num`; `c:real`; `h:real^M->real^N`] THEN + ASM_REWRITE_TAC[]; + REWRITE_TAC[FUN_EQ_THM; real_gt; GSYM REAL_NOT_LE] THEN + GEN_TAC THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN + VECTOR_ARITH_TAC]);; + +let EQUIINTEGRABLE_OPEN_INTERVAL_RESTRICTIONS = prove + (`!f:real^M->real^N a b. + f integrable_on interval[a,b] + ==> { (\x. if x IN interval(c,d) then f x else vec 0) | + c IN (:real^M) /\ d IN (:real^M) } + equiintegrable_on interval[a,b]`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN + `!n. n <= dimindex(:M) + ==> f INSERT + { (\x. if !i. 1 <= i /\ i <= n ==> c$i < x$i /\ x$i < d$i + then (f:real^M->real^N) x else vec 0) | + c IN (:real^M) /\ d IN (:real^M) } + equiintegrable_on interval[a,b]` + MP_TAC THENL + [MATCH_MP_TAC num_INDUCTION THEN + REWRITE_TAC[ARITH_RULE `~(1 <= i /\ i <= 0)`] THEN + ASM_REWRITE_TAC[ETA_AX; EQUIINTEGRABLE_ON_SING; SET_RULE + `f INSERT {f |c,d| c IN UNIV /\ d IN UNIV} = {f}`] THEN + X_GEN_TAC `n:num` THEN ASM_CASES_TAC `SUC n <= dimindex(:M)` THEN + ASM_REWRITE_TAC[] THEN ANTS_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN + DISCH_THEN(MP_TAC o SPEC `f:real^M->real^N` o + MATCH_MP (REWRITE_RULE[IMP_CONJ] + EQUIINTEGRABLE_HALFSPACE_RESTRICTIONS_LT)) THEN + REWRITE_TAC[IN_INSERT] THEN ANTS_TAC THENL + [REWRITE_TAC[TAUT + `a \/ b ==> c ==> d <=> (a ==> c ==> d) /\ (b ==> c ==> d)`] THEN + SIMP_TAC[REAL_LE_REFL; RIGHT_FORALL_IMP_THM] THEN + REWRITE_TAC[FORALL_IN_GSPEC] THEN + REPEAT STRIP_TAC THEN COND_CASES_TAC THEN + ASM_SIMP_TAC[NORM_0; REAL_LE_REFL; NORM_POS_LE]; + ALL_TAC] THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM EQUIINTEGRABLE_ON_SING]) THEN + REWRITE_TAC[IMP_IMP] THEN + DISCH_THEN(MP_TAC o MATCH_MP EQUIINTEGRABLE_UNION) THEN + DISCH_THEN(MP_TAC o SPEC `f:real^M->real^N` o + MATCH_MP (REWRITE_RULE[IMP_CONJ] + EQUIINTEGRABLE_HALFSPACE_RESTRICTIONS_GT)) THEN + ASM_REWRITE_TAC[IN_UNION; IN_SING] THEN ANTS_TAC THENL + [REWRITE_TAC[TAUT + `a \/ b ==> c ==> d <=> (a ==> c ==> d) /\ (b ==> c ==> d)`] THEN + SIMP_TAC[REAL_LE_REFL; RIGHT_FORALL_IMP_THM] THEN + REWRITE_TAC[FORALL_IN_GSPEC; LEFT_OR_DISTRIB] THEN + REWRITE_TAC[TAUT `a \/ b ==> c <=> (a ==> c) /\ (b ==> c)`] THEN + SIMP_TAC[REAL_LE_REFL; RIGHT_FORALL_IMP_THM] THEN + REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_GSPEC; + FORALL_AND_THM] THEN + SIMP_TAC[IN_UNIV] THEN + REPEAT STRIP_TAC THEN + REPEAT(COND_CASES_TAC THEN + ASM_SIMP_TAC[NORM_0; REAL_LE_REFL; NORM_POS_LE]); + ALL_TAC] THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM EQUIINTEGRABLE_ON_SING]) THEN + REWRITE_TAC[IMP_IMP] THEN + DISCH_THEN(MP_TAC o MATCH_MP EQUIINTEGRABLE_UNION) THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] EQUIINTEGRABLE_SUBSET) THEN + MATCH_MP_TAC(SET_RULE + `s SUBSET t ==> (x INSERT s) SUBSET ({x} UNION t)`) THEN + REWRITE_TAC[SUBSET; real_gt; FORALL_IN_GSPEC; IN_UNIV] THEN + MAP_EVERY X_GEN_TAC [`c:real^M`; `d:real^M`] THEN + REWRITE_TAC[IN_ELIM_THM] THEN EXISTS_TAC `SUC n` THEN + ASM_REWRITE_TAC[IN_NUMSEG; ARITH_RULE `1 <= SUC n`] THEN + EXISTS_TAC `(c:real^M)$(SUC n)` THEN + MATCH_MP_TAC(MESON[] + `(?i c k. P i c k /\ Q (g i c k)) + ==> ?h. (h = f \/ ?i c k. P i c k /\ h = g i c k) /\ Q h`) THEN + EXISTS_TAC `SUC n` THEN + ASM_REWRITE_TAC[IN_NUMSEG; ARITH_RULE `1 <= SUC n`] THEN + EXISTS_TAC `(d:real^M)$(SUC n)` THEN + EXISTS_TAC + `\x. if !i. 1 <= i /\ i <= n ==> (c:real^M)$i < x$i /\ x$i < (d:real^M)$i + then (f:real^M->real^N) x else vec 0` THEN + REWRITE_TAC[] THEN CONJ_TAC THENL + [DISJ2_TAC THEN + MAP_EVERY EXISTS_TAC [`c:real^M`; `d:real^M`] THEN REWRITE_TAC[]; + REWRITE_TAC[FUN_EQ_THM; LE] THEN + ASM_MESON_TAC[ARITH_RULE `1 <= SUC n`]]; + DISCH_THEN(MP_TAC o SPEC `dimindex(:M)`) THEN + REWRITE_TAC[IN_INTERVAL; LE_REFL] THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] EQUIINTEGRABLE_SUBSET) THEN + SET_TAC[]]);; + +let EQUIINTEGRABLE_CLOSED_INTERVAL_RESTRICTIONS = prove + (`!f:real^M->real^N a b. + f integrable_on interval[a,b] + ==> { (\x. if x IN interval[c,d] then f x else vec 0) | + c IN (:real^M) /\ d IN (:real^M) } + equiintegrable_on interval[a,b]`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN + `!n. n <= dimindex(:M) + ==> f INSERT + { (\x. if !i. 1 <= i /\ i <= n ==> c$i <= x$i /\ x$i <= d$i + then (f:real^M->real^N) x else vec 0) | + c IN (:real^M) /\ d IN (:real^M) } + equiintegrable_on interval[a,b]` + MP_TAC THENL + [MATCH_MP_TAC num_INDUCTION THEN + REWRITE_TAC[ARITH_RULE `~(1 <= i /\ i <= 0)`] THEN + ASM_REWRITE_TAC[ETA_AX; EQUIINTEGRABLE_ON_SING; SET_RULE + `f INSERT {f |c,d| c IN UNIV /\ d IN UNIV} = {f}`] THEN + X_GEN_TAC `n:num` THEN ASM_CASES_TAC `SUC n <= dimindex(:M)` THEN + ASM_REWRITE_TAC[] THEN ANTS_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN + DISCH_THEN(MP_TAC o SPEC `f:real^M->real^N` o + MATCH_MP (REWRITE_RULE[IMP_CONJ] + EQUIINTEGRABLE_HALFSPACE_RESTRICTIONS_LE)) THEN + REWRITE_TAC[IN_INSERT] THEN ANTS_TAC THENL + [REWRITE_TAC[TAUT + `a \/ b ==> c ==> d <=> (a ==> c ==> d) /\ (b ==> c ==> d)`] THEN + SIMP_TAC[REAL_LE_REFL; RIGHT_FORALL_IMP_THM] THEN + REWRITE_TAC[FORALL_IN_GSPEC] THEN + REPEAT STRIP_TAC THEN COND_CASES_TAC THEN + ASM_SIMP_TAC[NORM_0; REAL_LE_REFL; NORM_POS_LE]; + ALL_TAC] THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM EQUIINTEGRABLE_ON_SING]) THEN + REWRITE_TAC[IMP_IMP] THEN + DISCH_THEN(MP_TAC o MATCH_MP EQUIINTEGRABLE_UNION) THEN + DISCH_THEN(MP_TAC o SPEC `f:real^M->real^N` o + MATCH_MP (REWRITE_RULE[IMP_CONJ] + EQUIINTEGRABLE_HALFSPACE_RESTRICTIONS_GE)) THEN + ASM_REWRITE_TAC[IN_UNION; IN_SING] THEN ANTS_TAC THENL + [REWRITE_TAC[TAUT + `a \/ b ==> c ==> d <=> (a ==> c ==> d) /\ (b ==> c ==> d)`] THEN + SIMP_TAC[REAL_LE_REFL; RIGHT_FORALL_IMP_THM] THEN + REWRITE_TAC[FORALL_IN_GSPEC; LEFT_OR_DISTRIB] THEN + REWRITE_TAC[TAUT `a \/ b ==> c <=> (a ==> c) /\ (b ==> c)`] THEN + SIMP_TAC[REAL_LE_REFL; RIGHT_FORALL_IMP_THM] THEN + REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_GSPEC; + FORALL_AND_THM] THEN + SIMP_TAC[IN_UNIV] THEN + REPEAT STRIP_TAC THEN + REPEAT(COND_CASES_TAC THEN + ASM_SIMP_TAC[NORM_0; REAL_LE_REFL; NORM_POS_LE]); + ALL_TAC] THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM EQUIINTEGRABLE_ON_SING]) THEN + REWRITE_TAC[IMP_IMP] THEN + DISCH_THEN(MP_TAC o MATCH_MP EQUIINTEGRABLE_UNION) THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] EQUIINTEGRABLE_SUBSET) THEN + MATCH_MP_TAC(SET_RULE + `s SUBSET t ==> (x INSERT s) SUBSET ({x} UNION t)`) THEN + REWRITE_TAC[SUBSET; real_ge; FORALL_IN_GSPEC; IN_UNIV] THEN + MAP_EVERY X_GEN_TAC [`c:real^M`; `d:real^M`] THEN + REWRITE_TAC[IN_ELIM_THM] THEN EXISTS_TAC `SUC n` THEN + ASM_REWRITE_TAC[IN_NUMSEG; ARITH_RULE `1 <= SUC n`] THEN + EXISTS_TAC `(c:real^M)$(SUC n)` THEN + MATCH_MP_TAC(MESON[] + `(?i c k. P i c k /\ Q (g i c k)) + ==> ?h. (h = f \/ ?i c k. P i c k /\ h = g i c k) /\ Q h`) THEN + EXISTS_TAC `SUC n` THEN + ASM_REWRITE_TAC[IN_NUMSEG; ARITH_RULE `1 <= SUC n`] THEN + EXISTS_TAC `(d:real^M)$(SUC n)` THEN + EXISTS_TAC + `\x. if !i. 1 <= i /\ i <= n ==> (c:real^M)$i <= x$i /\ x$i <= (d:real^M)$i + then (f:real^M->real^N) x else vec 0` THEN + REWRITE_TAC[] THEN CONJ_TAC THENL + [DISJ2_TAC THEN + MAP_EVERY EXISTS_TAC [`c:real^M`; `d:real^M`] THEN REWRITE_TAC[]; + REWRITE_TAC[FUN_EQ_THM; LE] THEN + ASM_MESON_TAC[ARITH_RULE `1 <= SUC n`]]; + DISCH_THEN(MP_TAC o SPEC `dimindex(:M)`) THEN + REWRITE_TAC[IN_INTERVAL; LE_REFL] THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] EQUIINTEGRABLE_SUBSET) THEN + SET_TAC[]]);; + +(* ------------------------------------------------------------------------- *) +(* Continuity of the indefinite integral. *) +(* ------------------------------------------------------------------------- *) + +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 INDEFINITE_INTEGRAL_CONTINUOUS_RIGHT = prove + (`!f:real^M->real^N a b. + f integrable_on interval[a,b] + ==> (\x. integral (interval[a,x]) f) continuous_on interval[a,b]`, + REPEAT STRIP_TAC THEN REWRITE_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN] THEN + X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN REWRITE_TAC[continuous_within] THEN + X_GEN_TAC `e:real` THEN DISCH_TAC THEN + MP_TAC(ISPECL [`f:real^M->real^N`; `a:real^M`; `b:real^M`; + `a:real^M`; `x:real^M`; `e:real`] + INDEFINITE_INTEGRAL_CONTINUOUS) THEN + ASM_REWRITE_TAC[ENDS_IN_INTERVAL] THEN + ANTS_TAC THENL [ASM SET_TAC[]; REWRITE_TAC[dist]] THEN + MATCH_MP_TAC MONO_EXISTS THEN REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_SIMP_TAC[ENDS_IN_INTERVAL; VECTOR_SUB_REFL; NORM_0; REAL_LT_IMP_LE] THEN + ASM SET_TAC[]);; + +let INDEFINITE_INTEGRAL_CONTINUOUS_LEFT = prove + (`!f:real^M->real^N a b. + f integrable_on interval[a,b] + ==> (\x. integral(interval[x,b]) f) continuous_on interval[a,b]`, + REPEAT STRIP_TAC THEN REWRITE_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN] THEN + X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN REWRITE_TAC[continuous_within] THEN + X_GEN_TAC `e:real` THEN DISCH_TAC THEN + MP_TAC(ISPECL [`f:real^M->real^N`; `a:real^M`; `b:real^M`; + `x:real^M`; `b:real^M`; `e:real`] + INDEFINITE_INTEGRAL_CONTINUOUS) THEN + ASM_REWRITE_TAC[ENDS_IN_INTERVAL] THEN + ANTS_TAC THENL [ASM SET_TAC[]; REWRITE_TAC[dist]] THEN + MATCH_MP_TAC MONO_EXISTS THEN REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_SIMP_TAC[ENDS_IN_INTERVAL; VECTOR_SUB_REFL; NORM_0; REAL_LT_IMP_LE] THEN + ASM SET_TAC[]);; + +let INDEFINITE_INTEGRAL_UNIFORMLY_CONTINUOUS = prove + (`!f:real^M->real^N a b. + f integrable_on interval[a,b] + ==> (\y. integral (interval[fstcart y,sndcart y]) f) + uniformly_continuous_on interval[pastecart a a,pastecart b b]`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC COMPACT_UNIFORMLY_CONTINUOUS THEN + REWRITE_TAC[COMPACT_INTERVAL; continuous_on] THEN + REWRITE_TAC[FORALL_PASTECART; GSYM PCROSS_INTERVAL; PCROSS] THEN + REWRITE_TAC[IN_ELIM_PASTECART_THM; FSTCART_PASTECART; SNDCART_PASTECART] THEN + MAP_EVERY X_GEN_TAC [`c:real^M`; `d:real^M`] THEN STRIP_TAC THEN + X_GEN_TAC `e:real` THEN DISCH_TAC THEN MP_TAC(ISPECL + [`f:real^M->real^N`; `a:real^M`; `b:real^M`; `c:real^M`; `d:real^M`; + `e:real`] INDEFINITE_INTEGRAL_CONTINUOUS) THEN + ASM_REWRITE_TAC[dist] THEN MATCH_MP_TAC MONO_EXISTS THEN + X_GEN_TAC `k:real` THEN STRIP_TAC THEN ASM_REWRITE_TAC[PASTECART_SUB] THEN + ASM_MESON_TAC[NORM_LE_PASTECART; REAL_LT_IMP_LE; REAL_LE_TRANS]);; + +let INDEFINITE_INTEGRAL_UNIFORMLY_CONTINUOUS_EXPLICIT = prove + (`!f:real^M->real^N a b e. + f integrable_on interval[a,b] /\ &0 < e + ==> ?k. &0 < k /\ + !c d c' d'. c IN interval[a,b] /\ d IN interval[a,b] /\ + 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 MP_TAC(ISPECL + [`f:real^M->real^N`; `a:real^M`; `b:real^M`] + INDEFINITE_INTEGRAL_UNIFORMLY_CONTINUOUS) THEN + ASM_REWRITE_TAC[uniformly_continuous_on] THEN + DISCH_THEN(MP_TAC o SPEC `e:real`) THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `k:real` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `k / &3` THEN CONJ_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN + MAP_EVERY X_GEN_TAC [`c:real^M`; `c':real^M`; `d:real^M`; `d':real^M`] THEN + STRIP_TAC THEN FIRST_X_ASSUM(MP_TAC o SPECL + [`pastecart (c:real^M) (c':real^M)`; + `pastecart (d:real^M) (d':real^M)`]) THEN + REWRITE_TAC[GSYM PCROSS_INTERVAL; PCROSS] THEN + REWRITE_TAC[IN_ELIM_PASTECART_THM; FSTCART_PASTECART; SNDCART_PASTECART] THEN + ASM_REWRITE_TAC[dist; PASTECART_SUB] THEN DISCH_THEN MATCH_MP_TAC THEN + ASM_MESON_TAC[NORM_PASTECART_LE; REAL_LET_TRANS; + REAL_ARITH `&0 < k /\ x <= k / &3 /\ y <= k / &3 ==> x + y < k`]);; + +(* ------------------------------------------------------------------------- *) +(* Second mean value theorem and corollaries. *) +(* ------------------------------------------------------------------------- *) + +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 = 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] /\ + integral (interval[a,b]) (\x. g x % f x) = + g(a) % integral (interval[a,c]) f + + g(b) % integral (interval[c,b]) f`, + REPEAT GEN_TAC THEN + DISCH_THEN(MP_TAC o MATCH_MP SECOND_MEAN_VALUE_THEOREM_FULL) THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `c:real^1` THEN + REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + FIRST_X_ASSUM(SUBST1_TAC o MATCH_MP INTEGRAL_UNIQUE) THEN REWRITE_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])`, + REPEAT STRIP_TAC THEN ASM_CASES_TAC `b:real^1 = a` THENL + [EXISTS_TAC `a:real^1` THEN ASM_REWRITE_TAC[INTERVAL_SING; IN_SING] THEN + ASM_SIMP_TAC[GSYM INTERVAL_SING; INTEGRAL_NULL; CONTENT_EQ_0_1; + VECTOR_ADD_LID; REAL_LE_REFL; VECTOR_MUL_RZERO; HAS_INTEGRAL_NULL]; + ALL_TAC] THEN + SUBGOAL_THEN `drop a < drop b` ASSUME_TAC THENL + [ASM_MESON_TAC[INTERVAL_EQ_EMPTY_1; REAL_NOT_LE; DROP_EQ; REAL_LT_LE]; + ALL_TAC] THEN + SUBGOAL_THEN `u <= v` ASSUME_TAC THENL + [ASM_MESON_TAC[INTERVAL_EQ_EMPTY_1; MEMBER_NOT_EMPTY; REAL_NOT_LT; + REAL_LE_TRANS]; + ALL_TAC] THEN + MP_TAC(ISPECL + [`f:real^1->real^1`; + `\x:real^1. if x = a then u else if x = b then v else g x:real`; + `a:real^1`; `b:real^1`] SECOND_MEAN_VALUE_THEOREM_FULL) THEN + ASM_REWRITE_TAC[VECTOR_MUL_LZERO; VECTOR_ADD_LID] THEN ANTS_TAC THENL + [MAP_EVERY X_GEN_TAC [`x:real^1`; `y:real^1`] THEN + ASM_CASES_TAC `x:real^1 = a` THEN ASM_REWRITE_TAC[] THENL + [ASM_MESON_TAC[REAL_LE_REFL; INTERVAL_CASES_1]; ALL_TAC] THEN + ASM_CASES_TAC `y:real^1 = b` THEN ASM_REWRITE_TAC[] THENL + [ASM_MESON_TAC[REAL_LE_REFL; INTERVAL_CASES_1]; ALL_TAC] THEN + REPEAT(COND_CASES_TAC THEN ASM_SIMP_TAC[]) THEN + RULE_ASSUM_TAC(REWRITE_RULE[GSYM DROP_EQ]) THEN + REWRITE_TAC[IN_INTERVAL_1] THEN ASM_REAL_ARITH_TAC; + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `c:real^1` THEN + MATCH_MP_TAC MONO_AND THEN REWRITE_TAC[] THEN MATCH_MP_TAC + (REWRITE_RULE[TAUT `a /\ b /\ c ==> d <=> a /\ b ==> c ==> d`] + HAS_INTEGRAL_SPIKE) THEN + EXISTS_TAC `{a:real^1,b}` THEN + SIMP_TAC[NEGLIGIBLE_EMPTY; NEGLIGIBLE_INSERT; IN_DIFF; IN_INSERT; + NOT_IN_EMPTY; DE_MORGAN_THM]]);; + +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`, + REPEAT GEN_TAC THEN + DISCH_THEN(MP_TAC o MATCH_MP SECOND_MEAN_VALUE_THEOREM_GEN_FULL) THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `c:real^1` THEN + REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + FIRST_X_ASSUM(SUBST1_TAC o MATCH_MP INTEGRAL_UNIQUE) THEN REWRITE_TAC[]);; + +let SECOND_MEAN_VALUE_THEOREM_BONNET_FULL = prove + (`!f:real^1->real^1 g a b. + ~(interval[a,b] = {}) /\ f integrable_on interval [a,b] /\ + (!x. x IN interval[a,b] ==> &0 <= g x) /\ + (!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(b) % integral (interval[c,b]) f)) (interval[a,b])`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL + [`f:real^1->real^1`; `g:real^1->real`; `a:real^1`; `b:real^1`; + `&0`; `(g:real^1->real) b`] SECOND_MEAN_VALUE_THEOREM_GEN_FULL) THEN + ASM_REWRITE_TAC[VECTOR_MUL_LZERO; VECTOR_ADD_LID] THEN + DISCH_THEN MATCH_MP_TAC THEN REWRITE_TAC[IN_INTERVAL_1] THEN + REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + REWRITE_TAC[IN_INTERVAL_1] THEN ASM_REAL_ARITH_TAC);; + +let SECOND_MEAN_VALUE_THEOREM_BONNET = prove + (`!f:real^1->real^1 g a b. + ~(interval[a,b] = {}) /\ f integrable_on interval[a,b] /\ + (!x. x IN interval[a,b] ==> &0 <= g x) /\ + (!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) = + g(b) % integral (interval[c,b]) f`, + REPEAT GEN_TAC THEN + DISCH_THEN(MP_TAC o MATCH_MP SECOND_MEAN_VALUE_THEOREM_BONNET_FULL) THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `c:real^1` THEN + REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + FIRST_X_ASSUM(SUBST1_TAC o MATCH_MP INTEGRAL_UNIQUE) THEN REWRITE_TAC[]);; + +let INTEGRABLE_INCREASING_PRODUCT = prove + (`!f:real^1->real^N g 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)) + ==> (\x. g(x) % f(x)) integrable_on interval[a,b]`, + REPEAT STRIP_TAC THEN ASM_CASES_TAC `interval[a:real^1,b] = {}` THEN + ASM_REWRITE_TAC[INTEGRABLE_ON_EMPTY] THEN + ONCE_REWRITE_TAC[INTEGRABLE_COMPONENTWISE] THEN + X_GEN_TAC `i:num` THEN STRIP_TAC THEN + MP_TAC(ISPECL [`\x. lift((f:real^1->real^N) x$i)`; + `g:real^1->real`; `a:real^1`; `b:real^1`] + SECOND_MEAN_VALUE_THEOREM_FULL) THEN + ASM_REWRITE_TAC[] THEN ANTS_TAC THENL + [RULE_ASSUM_TAC(ONCE_REWRITE_RULE[INTEGRABLE_COMPONENTWISE]) THEN + ASM_SIMP_TAC[]; + REWRITE_TAC[VECTOR_MUL_COMPONENT; LIFT_CMUL; integrable_on] THEN + MESON_TAC[]]);; + +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 INTEGRABLE_INCREASING = prove + (`!f:real^1->real^N a b. + (!x y i. x IN interval[a,b] /\ y IN interval[a,b] /\ + drop x <= drop y /\ 1 <= i /\ i <= dimindex(:N) + ==> f(x)$i <= f(y)$i) + ==> f integrable_on interval[a,b]`, + REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[INTEGRABLE_COMPONENTWISE] THEN + X_GEN_TAC `i:num` THEN STRIP_TAC THEN + ONCE_REWRITE_TAC[GSYM REAL_MUL_RID] THEN + REWRITE_TAC[LIFT_CMUL; LIFT_NUM] THEN + MATCH_MP_TAC INTEGRABLE_INCREASING_PRODUCT THEN + ASM_SIMP_TAC[INTEGRABLE_CONST]);; + +let INTEGRABLE_INCREASING_1 = prove + (`!f:real^1->real^1 a b. + (!x y. x IN interval[a,b] /\ y IN interval[a,b] /\ drop x <= drop y + ==> drop(f x) <= drop(f y)) + ==> f integrable_on interval[a,b]`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC INTEGRABLE_INCREASING THEN + REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN + ASM_SIMP_TAC[IMP_IMP; FORALL_1; DIMINDEX_1; GSYM drop]);; + +let INTEGRABLE_DECREASING_PRODUCT = prove + (`!f:real^1->real^N g 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(y) <= g(x)) + ==> (\x. g(x) % f(x)) integrable_on interval[a,b]`, + REPEAT STRIP_TAC THEN + ONCE_REWRITE_TAC[VECTOR_ARITH `x % y:real^N = --(--x % y)`] THEN + MATCH_MP_TAC INTEGRABLE_NEG THEN + MATCH_MP_TAC INTEGRABLE_INCREASING_PRODUCT THEN + ASM_REWRITE_TAC[REAL_LE_NEG2]);; + +let INTEGRABLE_DECREASING_PRODUCT_UNIV = prove + (`!f:real^1->real^N g B. + f integrable_on (:real^1) /\ + (!x y. drop x <= drop y ==> g y <= g x) /\ + (!x. abs(g x) <= B) + ==> (\x. g x % f x) integrable_on (:real^1)`, + REPEAT STRIP_TAC THEN + ONCE_REWRITE_TAC[VECTOR_ARITH `x % y:real^N = --(--x % y)`] THEN + MATCH_MP_TAC INTEGRABLE_NEG THEN + MATCH_MP_TAC INTEGRABLE_INCREASING_PRODUCT_UNIV THEN + EXISTS_TAC `B:real` THEN ASM_REWRITE_TAC[REAL_LE_NEG2; REAL_ABS_NEG]);; + +let INTEGRABLE_DECREASING = prove + (`!f:real^1->real^N a b. + (!x y i. x IN interval[a,b] /\ y IN interval[a,b] /\ + drop x <= drop y /\ 1 <= i /\ i <= dimindex(:N) + ==> f(y)$i <= f(x)$i) + ==> f integrable_on interval[a,b]`, + REPEAT STRIP_TAC THEN GEN_REWRITE_TAC LAND_CONV [GSYM ETA_AX] THEN + GEN_REWRITE_TAC (LAND_CONV o BINDER_CONV) [GSYM VECTOR_NEG_NEG] THEN + MATCH_MP_TAC INTEGRABLE_NEG THEN MATCH_MP_TAC INTEGRABLE_INCREASING THEN + ASM_SIMP_TAC[VECTOR_NEG_COMPONENT; REAL_LE_NEG2]);; + +let INTEGRABLE_DECREASING_1 = prove + (`!f:real^1->real^1 a b. + (!x y. x IN interval[a,b] /\ y IN interval[a,b] /\ drop x <= drop y + ==> drop(f y) <= drop(f x)) + ==> f integrable_on interval[a,b]`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC INTEGRABLE_DECREASING THEN + REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN + ASM_SIMP_TAC[IMP_IMP; FORALL_1; DIMINDEX_1; GSYM drop]);; + +(* ------------------------------------------------------------------------- *) +(* Bounded variation and variation function, for real^1->real^N functions. *) +(* ------------------------------------------------------------------------- *) + +parse_as_infix("has_bounded_variation_on",(12,"right"));; + +let has_bounded_variation_on = new_definition + `(f:real^1->real^N) has_bounded_variation_on s <=> + (\k. f(interval_upperbound k) - f(interval_lowerbound k)) + has_bounded_setvariation_on s`;; + +let vector_variation = new_definition + `vector_variation s (f:real^1->real^N) = + set_variation s (\k. f(interval_upperbound k) - f(interval_lowerbound k))`;; + +let HAS_BOUNDED_VARIATION_ON_EQ = prove + (`!f g:real^1->real^N s. + (!x. x IN s ==> f x = g x) /\ f has_bounded_variation_on s + ==> g has_bounded_variation_on s`, + REPEAT GEN_TAC THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + REWRITE_TAC[has_bounded_variation_on] THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] HAS_BOUNDED_SETVARIATION_ON_EQ) THEN + SIMP_TAC[INTERVAL_UPPERBOUND; INTERVAL_LOWERBOUND; + GSYM INTERVAL_NE_EMPTY] THEN + ASM_MESON_TAC[ENDS_IN_INTERVAL; SUBSET]);; + +let VECTOR_VARIATION_EQ = prove + (`!f g:real^1->real^N s. + (!x. x IN s ==> f x = g x) + ==> vector_variation s f = vector_variation s g`, + REPEAT STRIP_TAC THEN REWRITE_TAC[vector_variation] THEN + MATCH_MP_TAC SET_VARIATION_EQ THEN + SIMP_TAC[INTERVAL_UPPERBOUND; INTERVAL_LOWERBOUND; + GSYM INTERVAL_NE_EMPTY] THEN + ASM_MESON_TAC[ENDS_IN_INTERVAL; SUBSET]);; + +let HAS_BOUNDED_VARIATION_ON_COMPONENTWISE = prove + (`!f:real^1->real^N s. + f has_bounded_variation_on s <=> + !i. 1 <= i /\ i <= dimindex(:N) + ==> (\x. lift(f x$i)) has_bounded_variation_on s`, + REPEAT GEN_TAC THEN REWRITE_TAC[has_bounded_variation_on] THEN + GEN_REWRITE_TAC LAND_CONV [HAS_BOUNDED_SETVARIATION_ON_COMPONENTWISE] THEN + REWRITE_TAC[VECTOR_SUB_COMPONENT; LIFT_SUB]);; + +let VARIATION_EQUAL_LEMMA = prove + (`!ms ms'. + (!s. ms'(ms s) = s /\ ms(ms' s) = s) /\ + (!d t. d division_of t + ==> (IMAGE (IMAGE ms) d) division_of IMAGE ms t /\ + (IMAGE (IMAGE ms') d) division_of IMAGE ms' t) /\ + (!a b. ~(interval[a,b] = {}) + ==> IMAGE ms' (interval [a,b]) = interval[ms' a,ms' b] \/ + IMAGE ms' (interval [a,b]) = interval[ms' b,ms' a]) + ==> (!f:real^1->real^N s. + (\x. f(ms' x)) has_bounded_variation_on (IMAGE ms s) <=> + f has_bounded_variation_on s) /\ + (!f:real^1->real^N s. + vector_variation (IMAGE ms s) (\x. f(ms' x)) = + vector_variation s f)`, + REPEAT GEN_TAC THEN STRIP_TAC THEN + REWRITE_TAC[has_bounded_variation_on; vector_variation] THEN + GEN_REWRITE_TAC I [AND_FORALL_THM] THEN X_GEN_TAC `f:real^1->real^N` THEN + MP_TAC(ISPECL + [`\f k. (f:(real^1->bool)->real^N) (IMAGE (ms':real^1->real^1) k)`; + `IMAGE (ms:real^1->real^1)`; + `IMAGE (ms':real^1->real^1)`] + SETVARIATION_EQUAL_LEMMA) THEN + ANTS_TAC THENL + [ASM_SIMP_TAC[GSYM IMAGE_o; o_DEF; IMAGE_ID; IMAGE_SUBSET] THEN + MAP_EVERY X_GEN_TAC [`a:real^1`; `b:real^1`] THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`a:real^1`; `b:real^1`]) THEN + ASM_REWRITE_TAC[] THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + ASM_MESON_TAC[IMAGE_EQ_EMPTY]; + ALL_TAC] THEN + REWRITE_TAC[] THEN GEN_REWRITE_TAC LAND_CONV [AND_FORALL_THM] THEN + DISCH_THEN(fun th -> + MP_TAC(SPEC `\k. (f:real^1->real^N) (interval_upperbound k) - + f (interval_lowerbound k)` th)) THEN + REWRITE_TAC[] THEN DISCH_THEN(fun th -> ONCE_REWRITE_TAC[GSYM th]) THEN + GEN_REWRITE_TAC I [AND_FORALL_THM] THEN X_GEN_TAC `s:real^1->bool` THEN + REWRITE_TAC[has_bounded_setvariation_on; set_variation] THEN + CONJ_TAC THENL + [REPLICATE_TAC 3 (AP_TERM_TAC THEN ABS_TAC) THEN + REWRITE_TAC[TAUT `((p ==> q) <=> (p ==> r)) <=> p ==> (q <=> r)`] THEN + STRIP_TAC THEN AP_THM_TAC THEN AP_TERM_TAC; + AP_TERM_TAC THEN + MATCH_MP_TAC(SET_RULE + `(!x. P x ==> f x = g x) ==> {f x | P x} = {g x | P x}`) THEN + GEN_TAC THEN STRIP_TAC] THEN + MATCH_MP_TAC SUM_EQ THEN FIRST_ASSUM(fun th -> + GEN_REWRITE_TAC I [MATCH_MP FORALL_IN_DIVISION_NONEMPTY th]) THEN + MAP_EVERY X_GEN_TAC [`a:real^1`; `b:real^1`] THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`a:real^1`; `b:real^1`]) THEN + ASM_REWRITE_TAC[] THEN DISCH_THEN(DISJ_CASES_THEN MP_TAC) THEN + DISCH_THEN(MP_TAC o MATCH_MP (SET_RULE + `IMAGE f s = s' ==> ~(s = {}) ==> IMAGE f s = s' /\ ~(s' = {})`)) THEN + ASM_REWRITE_TAC[] THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + RULE_ASSUM_TAC(REWRITE_RULE[INTERVAL_NE_EMPTY_1]) THEN + ASM_SIMP_TAC[INTERVAL_UPPERBOUND_1; INTERVAL_LOWERBOUND_1] THEN + NORM_ARITH_TAC);; + +let HAS_BOUNDED_VARIATION_ON_SUBSET = prove + (`!f:real^1->real^N s t. + f has_bounded_variation_on s /\ t SUBSET s + ==> f has_bounded_variation_on t`, + REWRITE_TAC[HAS_BOUNDED_SETVARIATION_ON_SUBSET; has_bounded_variation_on]);; + +let HAS_BOUNDED_VARIATION_ON_CONST = prove + (`!s c:real^N. (\x. c) has_bounded_variation_on s`, + REWRITE_TAC[has_bounded_variation_on; VECTOR_SUB_REFL; + HAS_BOUNDED_SETVARIATION_ON_0]);; + +let VECTOR_VARIATION_CONST = prove + (`!s c:real^N. vector_variation s (\x. c) = &0`, + REWRITE_TAC[vector_variation; VECTOR_SUB_REFL; SET_VARIATION_0]);; + +let HAS_BOUNDED_VARIATION_ON_CMUL = prove + (`!f:real^1->real^N c s. + f has_bounded_variation_on s + ==> (\x. c % f x) has_bounded_variation_on s`, + REPEAT GEN_TAC THEN REWRITE_TAC[has_bounded_variation_on] THEN + REWRITE_TAC[GSYM VECTOR_SUB_LDISTRIB; HAS_BOUNDED_SETVARIATION_ON_CMUL]);; + +let HAS_BOUNDED_VARIATION_ON_NEG = prove + (`!f:real^1->real^N s. + f has_bounded_variation_on s + ==> (\x. --f x) has_bounded_variation_on s`, + REPEAT GEN_TAC THEN REWRITE_TAC[has_bounded_variation_on] THEN + REWRITE_TAC[VECTOR_ARITH `--a - --b:real^N = --(a - b)`; + HAS_BOUNDED_SETVARIATION_ON_NEG]);; + +let HAS_BOUNDED_VARIATION_ON_ADD = prove + (`!f g:real^1->real^N s. + f has_bounded_variation_on s /\ g has_bounded_variation_on s + ==> (\x. f x + g x) has_bounded_variation_on s`, + REPEAT GEN_TAC THEN REWRITE_TAC[has_bounded_variation_on] THEN + REWRITE_TAC[VECTOR_ARITH `(f + g) - (f' + g'):real^N = (f - f') + (g - g')`; + HAS_BOUNDED_SETVARIATION_ON_ADD]);; + +let HAS_BOUNDED_VARIATION_ON_SUB = prove + (`!f g:real^1->real^N s. + f has_bounded_variation_on s /\ g has_bounded_variation_on s + ==> (\x. f x - g x) has_bounded_variation_on s`, + REPEAT GEN_TAC THEN REWRITE_TAC[has_bounded_variation_on] THEN + REWRITE_TAC[VECTOR_ARITH `(f - g) - (f' - g'):real^N = (f - f') - (g - g')`; + HAS_BOUNDED_SETVARIATION_ON_SUB]);; + +let HAS_BOUNDED_VARIATION_ON_COMPOSE_LINEAR = prove + (`!f:real^1->real^M g:real^M->real^N s. + f has_bounded_variation_on s /\ linear g + ==> (g o f) has_bounded_variation_on s`, + REPEAT GEN_TAC THEN REWRITE_TAC[has_bounded_variation_on] THEN + SIMP_TAC[o_THM; GSYM LINEAR_SUB] THEN + DISCH_THEN(MP_TAC o MATCH_MP HAS_BOUNDED_SETVARIATION_ON_COMPOSE_LINEAR) THEN + REWRITE_TAC[o_DEF]);; + +let HAS_BOUNDED_VARIATION_ON_NULL = prove + (`!f:real^1->real^N s. + content s = &0 /\ bounded s ==> f has_bounded_variation_on s`, + REPEAT STRIP_TAC THEN REWRITE_TAC[has_bounded_variation_on] THEN + MATCH_MP_TAC HAS_BOUNDED_SETVARIATION_ON_NULL THEN + ASM_SIMP_TAC[INTERVAL_BOUNDS_NULL_1; VECTOR_SUB_REFL]);; + +let HAS_BOUNDED_VARIATION_ON_EMPTY = prove + (`!f:real^1->real^N. f has_bounded_variation_on {}`, + MESON_TAC[CONTENT_EMPTY; BOUNDED_EMPTY; HAS_BOUNDED_VARIATION_ON_NULL]);; + +let VECTOR_VARIATION_ON_NULL = prove + (`!f s. content s = &0 /\ bounded s ==> vector_variation s f = &0`, + REPEAT STRIP_TAC THEN REWRITE_TAC[vector_variation] THEN + MATCH_MP_TAC SET_VARIATION_ON_NULL THEN ASM_REWRITE_TAC[] THEN + SIMP_TAC[INTERVAL_BOUNDS_NULL_1; VECTOR_SUB_REFL]);; + +let HAS_BOUNDED_VARIATION_ON_NORM = prove + (`!f:real^1->real^N s. + f has_bounded_variation_on s + ==> (\x. lift(norm(f x))) has_bounded_variation_on s`, + REWRITE_TAC[has_bounded_variation_on; has_bounded_setvariation_on] THEN + REPEAT GEN_TAC THEN MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC THEN + REPEAT(MATCH_MP_TAC MONO_FORALL THEN GEN_TAC) THEN + DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] REAL_LE_TRANS) THEN + MATCH_MP_TAC SUM_LE THEN + REWRITE_TAC[NORM_REAL; GSYM drop; LIFT_DROP; DROP_SUB] THEN + CONJ_TAC THENL [ASM_MESON_TAC[DIVISION_OF_FINITE]; NORM_ARITH_TAC]);; + +let HAS_BOUNDED_VARIATION_ON_MAX = prove + (`!f g s. f has_bounded_variation_on s /\ g has_bounded_variation_on s + ==> (\x. lift(max (drop(f x)) (drop(g x)))) + has_bounded_variation_on s`, + REPEAT STRIP_TAC THEN + REWRITE_TAC[REAL_ARITH `max a b = inv(&2) * (a + b + abs(a - b))`] THEN + REWRITE_TAC[LIFT_CMUL; LIFT_ADD; LIFT_DROP; GSYM DROP_SUB] THEN + REWRITE_TAC[drop; GSYM NORM_REAL] THEN + MATCH_MP_TAC HAS_BOUNDED_VARIATION_ON_CMUL THEN + MATCH_MP_TAC HAS_BOUNDED_VARIATION_ON_ADD THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC HAS_BOUNDED_VARIATION_ON_ADD THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC HAS_BOUNDED_VARIATION_ON_NORM THEN + MATCH_MP_TAC HAS_BOUNDED_VARIATION_ON_SUB THEN ASM_REWRITE_TAC[]);; + +let HAS_BOUNDED_VARIATION_ON_MIN = prove + (`!f g s. f has_bounded_variation_on s /\ g has_bounded_variation_on s + ==> (\x. lift(min (drop(f x)) (drop(g x)))) + has_bounded_variation_on s`, + REPEAT STRIP_TAC THEN + REWRITE_TAC[REAL_ARITH `min a b = inv(&2) * ((a + b) - abs(a - b))`] THEN + REWRITE_TAC[LIFT_CMUL; LIFT_ADD; LIFT_DROP; LIFT_SUB; GSYM DROP_SUB] THEN + REWRITE_TAC[drop; GSYM NORM_REAL] THEN + MATCH_MP_TAC HAS_BOUNDED_VARIATION_ON_CMUL THEN + MATCH_MP_TAC HAS_BOUNDED_VARIATION_ON_SUB THEN + ASM_SIMP_TAC[HAS_BOUNDED_VARIATION_ON_ADD] THEN + MATCH_MP_TAC HAS_BOUNDED_VARIATION_ON_NORM THEN + MATCH_MP_TAC HAS_BOUNDED_VARIATION_ON_SUB THEN ASM_REWRITE_TAC[]);; + +let HAS_BOUNDED_VARIATION_ON_IMP_BOUNDED_ON_SUBINTERVALS = prove + (`!f:real^1->real^N s. + f has_bounded_variation_on s + ==> bounded { f(d) - f(c) | interval[c,d] SUBSET s /\ + ~(interval[c,d] = {})}`, + REPEAT GEN_TAC THEN REWRITE_TAC[has_bounded_variation_on] THEN + DISCH_THEN(MP_TAC o MATCH_MP + HAS_BOUNDED_SETVARIATION_ON_IMP_BOUNDED_ON_SUBINTERVALS) THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] BOUNDED_SUBSET) THEN + GEN_REWRITE_TAC I [SUBSET] THEN REWRITE_TAC[FORALL_IN_GSPEC] THEN + MAP_EVERY X_GEN_TAC [`d:real^1`; `c:real^1`] THEN + REWRITE_TAC[INTERVAL_EQ_EMPTY_1; REAL_NOT_LT] THEN STRIP_TAC THEN + REWRITE_TAC[IN_ELIM_THM] THEN + MAP_EVERY EXISTS_TAC [`c:real^1`; `d:real^1`] THEN + ASM_SIMP_TAC[INTERVAL_UPPERBOUND_1; INTERVAL_LOWERBOUND_1]);; + +let HAS_BOUNDED_VARIATION_ON_IMP_BOUNDED_ON_INTERVAL = prove + (`!f:real^1->real^N a b. + f has_bounded_variation_on interval[a,b] + ==> bounded(IMAGE f (interval[a,b]))`, + REPEAT GEN_TAC THEN DISCH_THEN(MP_TAC o MATCH_MP + HAS_BOUNDED_VARIATION_ON_IMP_BOUNDED_ON_SUBINTERVALS) THEN + REWRITE_TAC[BOUNDED_POS_LT; FORALL_IN_GSPEC; FORALL_IN_IMAGE] THEN + DISCH_THEN(X_CHOOSE_THEN `B:real` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `B + norm((f:real^1->real^N) a)` THEN + ASM_SIMP_TAC[NORM_ARITH `&0 < B ==> &0 < B + norm(x:real^N)`] THEN + X_GEN_TAC `x:real^1` THEN REWRITE_TAC[IN_INTERVAL_1] THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`x:real^1`; `a:real^1`]) THEN + REWRITE_TAC[SUBSET_INTERVAL_1; INTERVAL_EQ_EMPTY_1] THEN ANTS_TAC THENL + [ASM_REAL_ARITH_TAC; NORM_ARITH_TAC]);; + +let HAS_BOUNDED_VARIATION_ON_MUL = prove + (`!f g:real^1->real^N a b. + f has_bounded_variation_on interval[a,b] /\ + g has_bounded_variation_on interval[a,b] + ==> (\x. drop(f x) % g x) has_bounded_variation_on interval[a,b]`, + REPEAT GEN_TAC THEN DISCH_TAC THEN + SUBGOAL_THEN + `bounded(IMAGE (f:real^1->real^1) (interval[a,b])) /\ + bounded(IMAGE (g:real^1->real^N) (interval[a,b]))` + MP_TAC THENL + [ASM_SIMP_TAC[HAS_BOUNDED_VARIATION_ON_IMP_BOUNDED_ON_INTERVAL]; + REWRITE_TAC[BOUNDED_POS_LT; FORALL_IN_IMAGE]] THEN + DISCH_THEN(CONJUNCTS_THEN2 + (X_CHOOSE_THEN `B1:real` STRIP_ASSUME_TAC) + (X_CHOOSE_THEN `B2:real` STRIP_ASSUME_TAC)) THEN + FIRST_X_ASSUM(CONJUNCTS_THEN MP_TAC) THEN + REWRITE_TAC[HAS_BOUNDED_SETVARIATION_ON_INTERVAL; + has_bounded_variation_on] THEN + DISCH_THEN(X_CHOOSE_THEN `C2:real` (LABEL_TAC "G")) THEN + DISCH_THEN(X_CHOOSE_THEN `C1:real` (LABEL_TAC "F")) THEN + EXISTS_TAC `B1 * C2 + B2 * C1:real` THEN + X_GEN_TAC `d:(real^1->bool)->bool` THEN DISCH_TAC THEN + MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC + `B1 * sum d (\k. norm((g:real^1->real^N)(interval_upperbound k) - + g(interval_lowerbound k))) + + B2 * sum d (\k. norm((f:real^1->real^1)(interval_upperbound k) - + f(interval_lowerbound k)))` THEN + CONJ_TAC THENL + [ALL_TAC; MATCH_MP_TAC REAL_LE_ADD2 THEN ASM_SIMP_TAC[REAL_LE_LMUL_EQ]] THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP DIVISION_OF_FINITE) THEN + ASM_SIMP_TAC[GSYM SUM_LMUL; GSYM SUM_ADD] 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^1`; `v:real^1`] THEN DISCH_TAC THEN + ONCE_REWRITE_TAC[VECTOR_ARITH + `f' % g' - f % g:real^N = f' % (g' - g) + (f' - f) % g`] THEN + MATCH_MP_TAC(NORM_ARITH + `norm x <= a /\ norm y <= b ==> norm(x + y) <= a + b`) THEN + REWRITE_TAC[NORM_MUL; NORM_REAL] THEN + REWRITE_TAC[drop; GSYM NORM_REAL; GSYM VECTOR_SUB_COMPONENT] THEN + SUBGOAL_THEN `~(interval[u:real^1,v] = {})` MP_TAC THENL + [ASM_MESON_TAC[division_of]; ALL_TAC] THEN + REWRITE_TAC[INTERVAL_EQ_EMPTY_1; REAL_NOT_LT] THEN DISCH_TAC THEN + ASM_SIMP_TAC[INTERVAL_LOWERBOUND_1; INTERVAL_UPPERBOUND_1] THEN + SUBGOAL_THEN `interval[u:real^1,v] SUBSET interval[a,b]` MP_TAC THENL + [ASM_MESON_TAC[division_of]; ALL_TAC] THEN + ASM_REWRITE_TAC[SUBSET_INTERVAL_1; GSYM REAL_NOT_LE] THEN + STRIP_TAC THEN + GEN_REWRITE_TAC (RAND_CONV o LAND_CONV) [REAL_MUL_SYM] THEN + CONJ_TAC THEN MATCH_MP_TAC REAL_LE_RMUL THEN REWRITE_TAC[NORM_POS_LE] THEN + MATCH_MP_TAC REAL_LT_IMP_LE THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + REWRITE_TAC[IN_INTERVAL_1] THEN ASM_REAL_ARITH_TAC);; + +let VECTOR_VARIATION_POS_LE = prove + (`!f:real^1->real^N s. + f has_bounded_variation_on s ==> &0 <= vector_variation s f`, + REWRITE_TAC[has_bounded_variation_on; vector_variation] THEN + REWRITE_TAC[SET_VARIATION_POS_LE]);; + +let VECTOR_VARIATION_GE_NORM_FUNCTION = prove + (`!f:real^1->real^N s a b. + f has_bounded_variation_on s /\ segment[a,b] SUBSET s + ==> norm(f b - f a) <= vector_variation s f`, + REWRITE_TAC[FORALL_LIFT] THEN GEN_TAC THEN GEN_TAC THEN + MATCH_MP_TAC REAL_WLOG_LE THEN CONJ_TAC THENL + [MESON_TAC[SEGMENT_SYM; NORM_SUB]; ALL_TAC] THEN + REWRITE_TAC[FORALL_DROP; LIFT_DROP; has_bounded_variation_on] THEN + REPEAT STRIP_TAC THEN MP_TAC(ISPECL + [`\k. (f:real^1->real^N)(interval_upperbound k) - f(interval_lowerbound k)`; + `s:real^1->bool`; `a:real^1`; `b:real^1`] SET_VARIATION_GE_FUNCTION) THEN + ASM_REWRITE_TAC[vector_variation; INTERVAL_NE_EMPTY_1] THEN + ASM_SIMP_TAC[INTERVAL_UPPERBOUND_1; INTERVAL_LOWERBOUND_1] THEN + ASM_MESON_TAC[SEGMENT_1]);; + +let VECTOR_VARIATION_GE_DROP_FUNCTION = prove + (`!f s a b. + f has_bounded_variation_on s /\ segment[a,b] SUBSET s + ==> drop(f b) - drop(f a) <= vector_variation s f`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `norm((f:real^1->real^1) b - f a)` THEN + ASM_SIMP_TAC[VECTOR_VARIATION_GE_NORM_FUNCTION] THEN + REWRITE_TAC[NORM_REAL; DROP_SUB; GSYM drop] THEN REAL_ARITH_TAC);; + +let VECTOR_VARIATION_CONST_EQ = prove + (`!f:real^1->real^N s. + is_interval s /\ f has_bounded_variation_on s + ==> (vector_variation s f = &0 <=> ?c. !x. x IN s ==> f x = c)`, + REPEAT STRIP_TAC THEN EQ_TAC THENL + [DISCH_TAC THEN REWRITE_TAC[MESON[] + `(?c. !x. P x ==> f x = c) <=> !a b. P a /\ P b ==> f a = f b`] THEN + MAP_EVERY X_GEN_TAC [`a:real^1`; `b:real^1`] THEN STRIP_TAC THEN + MP_TAC(ISPECL [`f:real^1->real^N`; `s:real^1->bool`; + `a:real^1`; `b:real^1`] VECTOR_VARIATION_GE_NORM_FUNCTION) THEN + ANTS_TAC THENL + [ASM_MESON_TAC[IS_INTERVAL_CONVEX_1; CONVEX_CONTAINS_SEGMENT]; + ASM_REWRITE_TAC[] THEN CONV_TAC NORM_ARITH]; + DISCH_THEN(X_CHOOSE_TAC `c:real^N`) THEN + MP_TAC(ISPECL [`f:real^1->real^N`; `(\x. c):real^1->real^N`; + `s:real^1->bool`] VECTOR_VARIATION_EQ) THEN + ASM_SIMP_TAC[VECTOR_VARIATION_CONST]]);; + +let VECTOR_VARIATION_MONOTONE = prove + (`!f s t. f has_bounded_variation_on s /\ t SUBSET s + ==> vector_variation t f <= vector_variation s f`, + REWRITE_TAC[has_bounded_variation_on; vector_variation] THEN + REWRITE_TAC[SET_VARIATION_MONOTONE]);; + +let VECTOR_VARIATION_NEG = prove + (`!f:real^1->real^N s. + vector_variation s (\x. --(f x)) = vector_variation s f`, + REPEAT GEN_TAC THEN REWRITE_TAC[vector_variation; set_variation] THEN + REWRITE_TAC[NORM_ARITH `norm(--x - --y:real^N) = norm(x - y)`]);; + +let VECTOR_VARIATION_TRIANGLE = prove + (`!f g:real^1->real^N s. + f has_bounded_variation_on s /\ g has_bounded_variation_on s + ==> vector_variation s (\x. f x + g x) + <= vector_variation s f + vector_variation s g`, + REPEAT GEN_TAC THEN + REWRITE_TAC[has_bounded_variation_on; vector_variation] THEN + DISCH_THEN(MP_TAC o MATCH_MP SET_VARIATION_TRIANGLE) THEN + REWRITE_TAC[VECTOR_ARITH `(a + b) - (c + d):real^N = (a - c) + (b - d)`]);; + +let OPERATIVE_FUNCTION_ENDPOINT_DIFF = prove + (`!f:real^1->real^N. + operative (+) (\k. f (interval_upperbound k) - f (interval_lowerbound k))`, + GEN_TAC THEN + SIMP_TAC[operative; INTERVAL_BOUNDS_NULL_1; VECTOR_SUB_REFL] THEN + REWRITE_TAC[NEUTRAL_VECTOR_ADD; DIMINDEX_1; FORALL_1; GSYM drop] THEN + REWRITE_TAC[FORALL_DROP] THEN + MAP_EVERY X_GEN_TAC [`a:real^1`; `b:real^1`; `c:real^1`] THEN + ASM_CASES_TAC `interval[a:real^1,b] = {}` THENL + [ASM_REWRITE_TAC[INTER_EMPTY; INTERVAL_BOUNDS_EMPTY_1] THEN + VECTOR_ARITH_TAC; + ALL_TAC] THEN + ASM_CASES_TAC `interval[a,b] INTER {x | drop x <= drop c} = {}` THENL + [ASM_REWRITE_TAC[INTERVAL_BOUNDS_EMPTY_1; VECTOR_SUB_REFL] THEN + SUBGOAL_THEN `interval[a,b] INTER {x | drop x >= drop c} = interval[a,b]` + (fun th -> REWRITE_TAC[th; VECTOR_ADD_LID]) THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE + `i INTER s = {} ==> s UNION t = UNIV ==> i INTER t = i`)) THEN + REWRITE_TAC[EXTENSION; IN_UNIV; IN_UNION; IN_ELIM_THM] THEN + REAL_ARITH_TAC; + ALL_TAC] THEN + ASM_CASES_TAC `interval[a,b] INTER {x | drop x >= drop c} = {}` THENL + [ASM_REWRITE_TAC[INTERVAL_BOUNDS_EMPTY_1; VECTOR_SUB_REFL] THEN + SUBGOAL_THEN `interval[a,b] INTER {x | drop x <= drop c} = interval[a,b]` + (fun th -> REWRITE_TAC[th; VECTOR_ADD_RID]) THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE + `i INTER s = {} ==> s UNION t = UNIV ==> i INTER t = i`)) THEN + REWRITE_TAC[EXTENSION; IN_UNIV; IN_UNION; IN_ELIM_THM] THEN + REAL_ARITH_TAC; + ALL_TAC] THEN + POP_ASSUM_LIST(MP_TAC o end_itlist CONJ) THEN + SIMP_TAC[INTERVAL_SPLIT; drop; DIMINDEX_1; LE_REFL] THEN + REWRITE_TAC[INTERVAL_EQ_EMPTY_1; REAL_NOT_LT] THEN + SIMP_TAC[INTERVAL_UPPERBOUND_1; INTERVAL_LOWERBOUND_1] THEN + SIMP_TAC[drop; LAMBDA_BETA; DIMINDEX_1; LE_REFL] THEN STRIP_TAC THEN + MATCH_MP_TAC(VECTOR_ARITH + `fx:real^N = fy ==> fb - fa = fx - fa + fb - fy`) THEN + AP_TERM_TAC THEN REWRITE_TAC[GSYM DROP_EQ; drop] THEN + SIMP_TAC[LAMBDA_BETA; DIMINDEX_1; LE_REFL] THEN ASM_REAL_ARITH_TAC);; + +let OPERATIVE_REAL_FUNCTION_ENDPOINT_DIFF = prove + (`!f:real^1->real. + operative (+) (\k. f (interval_upperbound k) - f (interval_lowerbound k))`, + GEN_TAC THEN + MP_TAC(ISPEC `lift o (f:real^1->real)` OPERATIVE_FUNCTION_ENDPOINT_DIFF) THEN + REWRITE_TAC[operative; NEUTRAL_REAL_ADD; NEUTRAL_VECTOR_ADD] THEN + REWRITE_TAC[o_THM; GSYM LIFT_SUB; GSYM LIFT_ADD; GSYM LIFT_NUM] THEN + REWRITE_TAC[LIFT_EQ]);; + +let OPERATIVE_LIFTED_VECTOR_VARIATION = prove + (`!f:real^1->real^N. + operative (lifted(+)) + (\i. if f has_bounded_variation_on i + then SOME(vector_variation i f) else NONE)`, + GEN_TAC THEN REWRITE_TAC[has_bounded_variation_on; vector_variation] THEN + MATCH_MP_TAC OPERATIVE_LIFTED_SETVARIATION THEN + REWRITE_TAC[OPERATIVE_FUNCTION_ENDPOINT_DIFF]);; + +let HAS_BOUNDED_VARIATION_ON_DIVISION = prove + (`!f:real^1->real^N a b d. + d division_of interval[a,b] + ==> ((!k. k IN d ==> f has_bounded_variation_on k) <=> + f has_bounded_variation_on interval[a,b])`, + REPEAT STRIP_TAC THEN REWRITE_TAC[has_bounded_variation_on] THEN + MATCH_MP_TAC HAS_BOUNDED_SETVARIATION_ON_DIVISION THEN + ASM_REWRITE_TAC[OPERATIVE_FUNCTION_ENDPOINT_DIFF]);; + +let VECTOR_VARIATION_ON_DIVISION = prove + (`!f:real^1->real^N a b d. + d division_of interval[a,b] /\ + f has_bounded_variation_on interval[a,b] + ==> sum d (\k. vector_variation k f) = + vector_variation (interval[a,b]) f`, + REPEAT STRIP_TAC THEN REWRITE_TAC[vector_variation] THEN + MATCH_MP_TAC SET_VARIATION_ON_DIVISION THEN + ASM_REWRITE_TAC[OPERATIVE_FUNCTION_ENDPOINT_DIFF; GSYM + has_bounded_variation_on]);; + +let HAS_BOUNDED_VARIATION_ON_COMBINE = prove + (`!f:real^1->real^N a b c. + drop a <= drop c /\ drop c <= drop b + ==> (f has_bounded_variation_on interval[a,b] <=> + f has_bounded_variation_on interval[a,c] /\ + f has_bounded_variation_on interval[c,b])`, + REPEAT STRIP_TAC THEN MP_TAC + (ISPEC `f:real^1->real^N` OPERATIVE_LIFTED_VECTOR_VARIATION) THEN + REWRITE_TAC[operative; FORALL_1; FORALL_DROP; DIMINDEX_1] THEN + DISCH_THEN(MP_TAC o SPECL [`a:real^1`; `b:real^1`; `c:real^1`] o + CONJUNCT2) THEN ASM_REWRITE_TAC[] THEN + SUBGOAL_THEN + `interval[a,b] INTER {x:real^1 | x$1 <= drop c} = interval[a,c] /\ + interval[a,b] INTER {x:real^1 | x$1 >= drop c} = interval[c,b]` + (fun th -> REWRITE_TAC[th]) + THENL + [SIMP_TAC[EXTENSION; IN_INTER; GSYM drop; IN_INTERVAL_1; IN_ELIM_THM] THEN + ASM_REAL_ARITH_TAC; + REPEAT(COND_CASES_TAC THEN + ASM_REWRITE_TAC[distinctness "option"; lifted])]);; + +let VECTOR_VARIATION_COMBINE = prove + (`!f:real^1->real^N a b c. + drop a <= drop c /\ + drop c <= drop b /\ + f has_bounded_variation_on interval[a,b] + ==> vector_variation (interval[a,c]) f + + vector_variation (interval[c,b]) f = + vector_variation (interval[a,b]) f`, + REPEAT STRIP_TAC THEN MP_TAC + (ISPEC `f:real^1->real^N` OPERATIVE_LIFTED_VECTOR_VARIATION) THEN + REWRITE_TAC[operative; FORALL_1; FORALL_DROP; DIMINDEX_1] THEN + DISCH_THEN(MP_TAC o SPECL [`a:real^1`; `b:real^1`; `c:real^1`] o + CONJUNCT2) THEN ASM_REWRITE_TAC[] THEN REPEAT(COND_CASES_TAC THENL + [ALL_TAC; + ASM_MESON_TAC[HAS_BOUNDED_VARIATION_ON_SUBSET; INTER_SUBSET]]) THEN + REWRITE_TAC[lifted; injectivity "option"] THEN DISCH_THEN SUBST1_TAC THEN + SIMP_TAC[INTERVAL_SPLIT; DIMINDEX_1; LE_REFL] THEN + BINOP_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN + SIMP_TAC[EXTENSION; IN_INTERVAL_1; drop; LAMBDA_BETA; + DIMINDEX_1; LE_REFL] THEN + REWRITE_TAC[GSYM drop] THEN ASM_REAL_ARITH_TAC);; + +let VECTOR_VARIATION_MINUS_FUNCTION_MONOTONE = prove + (`!f a b c d. + f has_bounded_variation_on interval[a,b] /\ + interval[c,d] SUBSET interval[a,b] /\ ~(interval[c,d] = {}) + ==> vector_variation (interval[c,d]) f - drop(f d - f c) <= + vector_variation (interval[a,b]) f - drop(f b - f a)`, + REWRITE_TAC[SUBSET_INTERVAL_1; INTERVAL_EQ_EMPTY_1; REAL_NOT_LT] THEN + REPEAT STRIP_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN + `drop(f c) - drop(f a) <= vector_variation(interval[a,c]) f /\ + drop(f b) - drop(f d) <= vector_variation(interval[d,b]) f` + MP_TAC THENL + [CONJ_TAC THEN MATCH_MP_TAC VECTOR_VARIATION_GE_DROP_FUNCTION THEN + ASM_REWRITE_TAC[SEGMENT_1; SUBSET_INTERVAL_1; INTERVAL_EQ_EMPTY_1] THEN + (CONJ_TAC THENL [ALL_TAC; ASM_REAL_ARITH_TAC]) THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + HAS_BOUNDED_VARIATION_ON_SUBSET)) THEN + REWRITE_TAC[SUBSET_INTERVAL_1] THEN ASM_REAL_ARITH_TAC; + ALL_TAC] THEN + REWRITE_TAC[DROP_SUB] THEN + MP_TAC(ISPEC `f:real^1->real^1` VECTOR_VARIATION_COMBINE) THEN + DISCH_THEN(fun th -> + MP_TAC(SPECL [`a:real^1`; `b:real^1`; `d:real^1`] th) THEN + MP_TAC(SPECL [`a:real^1`; `d:real^1`; `c:real^1`] th)) THEN + ASM_REWRITE_TAC[] THEN ANTS_TAC THENL + [FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + HAS_BOUNDED_VARIATION_ON_SUBSET)) THEN + REWRITE_TAC[SUBSET_INTERVAL_1] THEN ASM_REAL_ARITH_TAC; + ASM_REAL_ARITH_TAC]);; + +let INCREASING_BOUNDED_VARIATION = prove + (`!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)) + ==> f has_bounded_variation_on interval[a,b]`, + REPEAT STRIP_TAC THEN + ASM_CASES_TAC `interval[a:real^1,b] = {}` THEN + ASM_REWRITE_TAC[HAS_BOUNDED_VARIATION_ON_EMPTY] THEN + REWRITE_TAC[has_bounded_variation_on; + HAS_BOUNDED_SETVARIATION_ON_INTERVAL] THEN + EXISTS_TAC `drop(f b) - drop(f(a:real^1))` THEN + MP_TAC(MATCH_MP (REWRITE_RULE + [TAUT `a /\ b /\ c ==> d <=> b ==> a /\ c ==> d`] + OPERATIVE_DIVISION) (SPEC `drop o (f:real^1->real^1)` + OPERATIVE_REAL_FUNCTION_ENDPOINT_DIFF)) THEN + MATCH_MP_TAC MONO_FORALL THEN GEN_TAC THEN + DISCH_THEN(MP_TAC o SPECL [`a:real^1`; `b:real^1`]) THEN + DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN + ASM_REWRITE_TAC[GSYM sum; MONOIDAL_REAL_ADD] THEN + RULE_ASSUM_TAC(REWRITE_RULE[INTERVAL_EQ_EMPTY_1; REAL_NOT_LT]) THEN + ASM_SIMP_TAC[o_THM; INTERVAL_LOWERBOUND_1; INTERVAL_UPPERBOUND_1] THEN + DISCH_THEN(SUBST1_TAC o SYM) THEN MATCH_MP_TAC REAL_EQ_IMP_LE THEN + MATCH_MP_TAC SUM_EQ THEN REWRITE_TAC[NORM_REAL; GSYM drop] THEN + FIRST_ASSUM(fun th -> REWRITE_TAC[MATCH_MP FORALL_IN_DIVISION th]) THEN + MAP_EVERY X_GEN_TAC [`u:real^1`; `v:real^1`] THEN DISCH_TAC THEN + SUBGOAL_THEN `~(interval[u:real^1,v] = {})` ASSUME_TAC THENL + [ASM_MESON_TAC[division_of]; ALL_TAC] THEN + RULE_ASSUM_TAC(REWRITE_RULE[INTERVAL_EQ_EMPTY_1; REAL_NOT_LT]) THEN + ASM_SIMP_TAC[DROP_SUB; INTERVAL_LOWERBOUND_1; INTERVAL_UPPERBOUND_1] THEN + MATCH_MP_TAC(REAL_ARITH `x <= y ==> abs(y - x) = y - x`) THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN REWRITE_TAC[IN_INTERVAL_1] THEN + SUBGOAL_THEN `interval[u:real^1,v] SUBSET interval[a,b]` MP_TAC THENL + [ASM_MESON_TAC[division_of]; REWRITE_TAC[SUBSET_INTERVAL_1]] THEN + ASM_REAL_ARITH_TAC);; + +let DECREASING_BOUNDED_VARIATION = prove + (`!f a b. + (!x y. x IN interval[a,b] /\ y IN interval[a,b] /\ drop x <= drop y + ==> drop(f y) <= drop(f x)) + ==> f has_bounded_variation_on interval[a,b]`, + REPEAT GEN_TAC THEN + GEN_REWRITE_TAC (LAND_CONV o BINDER_CONV o BINDER_CONV o RAND_CONV) + [GSYM REAL_LE_NEG2] THEN + REWRITE_TAC[GSYM DROP_NEG] THEN + DISCH_THEN(MP_TAC o MATCH_MP INCREASING_BOUNDED_VARIATION) THEN + DISCH_THEN(MP_TAC o MATCH_MP HAS_BOUNDED_VARIATION_ON_NEG) THEN + REWRITE_TAC[VECTOR_NEG_NEG; ETA_AX]);; + +let INCREASING_VECTOR_VARIATION = prove + (`!f a b. + ~(interval[a,b] = {}) /\ + (!x y. x IN interval[a,b] /\ y IN interval[a,b] /\ drop x <= drop y + ==> drop(f x) <= drop(f y)) + ==> vector_variation (interval[a,b]) f = drop(f b) - drop(f a)`, + REPEAT STRIP_TAC THEN REWRITE_TAC[vector_variation] THEN + REWRITE_TAC[SET_VARIATION_ON_INTERVAL] THEN + SUBGOAL_THEN + `{sum d (\k. norm (f (interval_upperbound k) - f (interval_lowerbound k))) | + d division_of interval[a:real^1,b]} = + {drop (f b) - drop(f a)}` + (fun th -> SIMP_TAC[SUP_INSERT_FINITE; FINITE_EMPTY; th]) THEN + MATCH_MP_TAC(SET_RULE + `(?x. P x) /\ (!x. P x ==> f x = a) ==> {f x | P x} = {a}`) THEN + CONJ_TAC THENL [ASM_MESON_TAC[DIVISION_OF_SELF]; ALL_TAC] THEN + MP_TAC(MATCH_MP (REWRITE_RULE + [TAUT `a /\ b /\ c ==> d <=> b ==> a /\ c ==> d`] + OPERATIVE_DIVISION) (SPEC `drop o (f:real^1->real^1)` + OPERATIVE_REAL_FUNCTION_ENDPOINT_DIFF)) THEN + MATCH_MP_TAC MONO_FORALL THEN GEN_TAC THEN + DISCH_THEN(MP_TAC o SPECL [`a:real^1`; `b:real^1`]) THEN + DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN + ASM_REWRITE_TAC[GSYM sum; MONOIDAL_REAL_ADD] THEN + RULE_ASSUM_TAC(REWRITE_RULE[INTERVAL_EQ_EMPTY_1; REAL_NOT_LT]) THEN + ASM_SIMP_TAC[o_THM; INTERVAL_LOWERBOUND_1; INTERVAL_UPPERBOUND_1] THEN + DISCH_THEN(SUBST1_TAC o SYM) THEN + MATCH_MP_TAC SUM_EQ THEN REWRITE_TAC[NORM_REAL; GSYM drop] THEN + FIRST_ASSUM(fun th -> REWRITE_TAC[MATCH_MP FORALL_IN_DIVISION th]) THEN + MAP_EVERY X_GEN_TAC [`u:real^1`; `v:real^1`] THEN DISCH_TAC THEN + SUBGOAL_THEN `~(interval[u:real^1,v] = {})` ASSUME_TAC THENL + [ASM_MESON_TAC[division_of]; ALL_TAC] THEN + RULE_ASSUM_TAC(REWRITE_RULE[INTERVAL_EQ_EMPTY_1; REAL_NOT_LT]) THEN + ASM_SIMP_TAC[DROP_SUB; INTERVAL_LOWERBOUND_1; INTERVAL_UPPERBOUND_1] THEN + MATCH_MP_TAC(REAL_ARITH `x <= y ==> abs(y - x) = y - x`) THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN REWRITE_TAC[IN_INTERVAL_1] THEN + SUBGOAL_THEN `interval[u:real^1,v] SUBSET interval[a,b]` MP_TAC THENL + [ASM_MESON_TAC[division_of]; REWRITE_TAC[SUBSET_INTERVAL_1]] THEN + ASM_REAL_ARITH_TAC);; + +let DECREASING_VECTOR_VARIATION = prove + (`!f a b. + ~(interval[a,b] = {}) /\ + (!x y. x IN interval[a,b] /\ y IN interval[a,b] /\ drop x <= drop y + ==> drop(f y) <= drop(f x)) + ==> vector_variation (interval[a,b]) f = drop(f a) - drop(f b)`, + REPEAT GEN_TAC THEN GEN_REWRITE_TAC + (LAND_CONV o RAND_CONV o BINDER_CONV o BINDER_CONV o RAND_CONV) + [GSYM REAL_LE_NEG2] THEN + REWRITE_TAC[GSYM DROP_NEG] THEN + DISCH_THEN(MP_TAC o MATCH_MP INCREASING_VECTOR_VARIATION) THEN + SIMP_TAC[VECTOR_VARIATION_NEG; DROP_NEG] THEN + DISCH_TAC THEN REAL_ARITH_TAC);; + +let HAS_BOUNDED_VARIATION_TRANSLATION2_EQ,VECTOR_VARIATION_TRANSLATION2 = + (CONJ_PAIR o prove) + (`(!a f:real^1->real^N s. + (\x. f(a + x)) has_bounded_variation_on (IMAGE (\x. --a + x) s) <=> + f has_bounded_variation_on s) /\ + (!a f:real^1->real^N s. + vector_variation (IMAGE (\x. --a + x) s) (\x. f(a + x)) = + vector_variation s f)`, + GEN_REWRITE_TAC I [AND_FORALL_THM] THEN X_GEN_TAC `a:real^1` THEN + MATCH_MP_TAC VARIATION_EQUAL_LEMMA THEN + REWRITE_TAC[] THEN CONJ_TAC THENL [VECTOR_ARITH_TAC; ALL_TAC] THEN + SIMP_TAC[DIVISION_OF_TRANSLATION; GSYM INTERVAL_TRANSLATION]);; + +let HAS_BOUNDED_VARIATION_AFFINITY2_EQ,VECTOR_VARIATION_AFFINITY2 = + (CONJ_PAIR o prove) + (`(!m c f:real^1->real^N s. + (\x. f (m % x + c)) has_bounded_variation_on + IMAGE (\x. inv m % x + --(inv m % c)) s <=> + m = &0 \/ f has_bounded_variation_on s) /\ + (!m c f:real^1->real^N s. + vector_variation (IMAGE (\x. inv m % x + --(inv m % c)) s) + (\x. f (m % x + c)) = + if m = &0 then &0 else vector_variation s f)`, + GEN_REWRITE_TAC I [AND_FORALL_THM] THEN X_GEN_TAC `m:real` THEN + GEN_REWRITE_TAC I [AND_FORALL_THM] THEN X_GEN_TAC `c:real^1` THEN + ASM_CASES_TAC `m = &0` THEN ASM_REWRITE_TAC[] THENL + [ASM_REWRITE_TAC[VECTOR_MUL_LZERO; HAS_BOUNDED_VARIATION_ON_CONST] THEN + REWRITE_TAC[VECTOR_VARIATION_CONST]; + MATCH_MP_TAC VARIATION_EQUAL_LEMMA THEN + ASM_SIMP_TAC[REWRITE_RULE[FUN_EQ_THM; o_DEF] AFFINITY_INVERSES; I_THM] THEN + ASM_SIMP_TAC[IMAGE_AFFINITY_INTERVAL] THEN + ASM_REWRITE_TAC[DIVISION_OF_AFFINITY; REAL_INV_EQ_0] THEN + MESON_TAC[]]);; + +let HAS_BOUNDED_VARIATION_AFFINITY_EQ,VECTOR_VARIATION_AFFINITY = + (CONJ_PAIR o prove) + (`(!m c f:real^1->real^N s. + (\x. f(m % x + c)) has_bounded_variation_on s <=> + m = &0 \/ f has_bounded_variation_on (IMAGE (\x. m % x + c) s)) /\ + (!m c f:real^1->real^N s. + vector_variation s (\x. f(m % x + c)) = + if m = &0 then &0 else vector_variation (IMAGE (\x. m % x + c) s) f)`, + REWRITE_TAC[AND_FORALL_THM] THEN REPEAT GEN_TAC THEN + ASM_CASES_TAC `m = &0` THEN + ASM_REWRITE_TAC[VECTOR_MUL_LZERO; HAS_BOUNDED_VARIATION_ON_CONST; + VECTOR_VARIATION_CONST] THEN + CONJ_TAC THENL + [MP_TAC(ISPECL[`m:real`; `c:real^1`; `f:real^1->real^N`; + `IMAGE (\x:real^1. m % x + c) s`] + HAS_BOUNDED_VARIATION_AFFINITY2_EQ); + MP_TAC(ISPECL[`m:real`; `c:real^1`; `f:real^1->real^N`; + `IMAGE (\x:real^1. m % x + c) s`] + VECTOR_VARIATION_AFFINITY2)] THEN + ASM_SIMP_TAC[AFFINITY_INVERSES; GSYM IMAGE_o; IMAGE_I]);; + +let HAS_BOUNDED_VARIATION_TRANSLATION_EQ,VECTOR_VARIATION_TRANSLATION = + (CONJ_PAIR o prove) + (`(!a f:real^1->real^N s. + (\x. f(a + x)) has_bounded_variation_on s <=> + f has_bounded_variation_on (IMAGE (\x. a + x) s)) /\ + (!a f:real^1->real^N s. + vector_variation s (\x. f(a + x)) = + vector_variation (IMAGE (\x. a + x) s) f)`, + REPEAT STRIP_TAC THENL + [MP_TAC(ISPECL[`a:real^1`; `f:real^1->real^N`; `IMAGE (\x:real^1. a + x) s`] + HAS_BOUNDED_VARIATION_TRANSLATION2_EQ); + MP_TAC(ISPECL[`a:real^1`; `f:real^1->real^N`; `IMAGE (\x:real^1. a + x) s`] + VECTOR_VARIATION_TRANSLATION2)] THEN + REWRITE_TAC[GSYM IMAGE_o; o_DEF] THEN + REWRITE_TAC[IMAGE_ID; VECTOR_ARITH `--a + a + x:real^N = x`; + VECTOR_ARITH `a + --a + x:real^N = x`]);; + +let HAS_BOUNDED_VARIATION_TRANSLATION_EQ_INTERVAL, + VECTOR_VARIATION_TRANSLATION_INTERVAL = + (CONJ_PAIR o prove) + (`(!a f:real^1->real^N u v. + (\x. f(a + x)) has_bounded_variation_on interval[u,v] <=> + f has_bounded_variation_on interval[a+u,a+v]) /\ + (!a f:real^1->real^N u v. + vector_variation (interval[u,v]) (\x. f(a + x)) = + vector_variation (interval[a+u,a+v]) f)`, + REWRITE_TAC[INTERVAL_TRANSLATION; HAS_BOUNDED_VARIATION_TRANSLATION_EQ; + VECTOR_VARIATION_TRANSLATION]);; + +let HAS_BOUNDED_VARIATION_TRANSLATION = prove + (`!f:real^1->real^N s a. + f has_bounded_variation_on s + ==> (\x. f(a + x)) has_bounded_variation_on (IMAGE (\x. --a + x) s)`, + REWRITE_TAC[HAS_BOUNDED_VARIATION_TRANSLATION2_EQ]);; + +let HAS_BOUNDED_VARIATION_REFLECT2_EQ,VECTOR_VARIATION_REFLECT2 = + (CONJ_PAIR o prove) + (`(!f:real^1->real^N s. + (\x. f(--x)) has_bounded_variation_on (IMAGE (--) s) <=> + f has_bounded_variation_on s) /\ + (!f:real^1->real^N s. + vector_variation (IMAGE (--) s) (\x. f(--x)) = + vector_variation s f)`, + MATCH_MP_TAC VARIATION_EQUAL_LEMMA THEN + REWRITE_TAC[] THEN CONJ_TAC THENL [VECTOR_ARITH_TAC; ALL_TAC] THEN + SIMP_TAC[DIVISION_OF_REFLECT; REFLECT_INTERVAL]);; + +let HAS_BOUNDED_VARIATION_REFLECT_EQ,VECTOR_VARIATION_REFLECT = + (CONJ_PAIR o prove) + (`(!f:real^1->real^N s. + (\x. f(--x)) has_bounded_variation_on s <=> + f has_bounded_variation_on (IMAGE (--) s)) /\ + (!f:real^1->real^N s. + vector_variation s (\x. f(--x)) = + vector_variation (IMAGE (--) s) f)`, + REPEAT STRIP_TAC THENL + [MP_TAC(ISPECL[`f:real^1->real^N`; `IMAGE (--) (s:real^1->bool)`] + HAS_BOUNDED_VARIATION_REFLECT2_EQ); + MP_TAC(ISPECL[`f:real^1->real^N`; `IMAGE (--) (s:real^1->bool)`] + VECTOR_VARIATION_REFLECT2)] THEN + REWRITE_TAC[GSYM IMAGE_o; o_DEF] THEN + REWRITE_TAC[IMAGE_ID; VECTOR_NEG_NEG]);; + +let HAS_BOUNDED_VARIATION_REFLECT_EQ_INTERVAL, + VECTOR_VARIATION_REFLECT_INTERVAL = + (CONJ_PAIR o prove) + (`(!f:real^1->real^N u v. + (\x. f(--x)) has_bounded_variation_on interval[u,v] <=> + f has_bounded_variation_on interval[--v,--u]) /\ + (!f:real^1->real^N u v. + vector_variation (interval[u,v]) (\x. f(--x)) = + vector_variation (interval[--v,--u]) f)`, + REWRITE_TAC[GSYM REFLECT_INTERVAL; HAS_BOUNDED_VARIATION_REFLECT_EQ; + VECTOR_VARIATION_REFLECT]);; + +let HAS_BOUNDED_VARIATION_DARBOUX = prove + (`!f a b. + f has_bounded_variation_on interval[a,b] <=> + ?g h. (!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. f x = g x - h x)`, + REPEAT GEN_TAC THEN EQ_TAC THEN STRIP_TAC THENL + [MAP_EVERY EXISTS_TAC + [`\x:real^1. lift(vector_variation (interval[a,x]) (f:real^1->real^1))`; + `\x:real^1. lift(vector_variation (interval[a,x]) f) - f x`] THEN + REWRITE_TAC[VECTOR_ARITH `a - (a - x):real^1 = x`] THEN + REWRITE_TAC[LIFT_DROP; DROP_SUB] THEN REPEAT STRIP_TAC THENL + [MATCH_MP_TAC VECTOR_VARIATION_MONOTONE; + MATCH_MP_TAC(REAL_ARITH + `!x. a - (b - x) <= c - (d - x) ==> a - b <= c - d`) THEN + EXISTS_TAC `drop(f(a:real^1))` THEN + REWRITE_TAC[GSYM DROP_SUB] THEN + MATCH_MP_TAC VECTOR_VARIATION_MINUS_FUNCTION_MONOTONE] THEN + (CONJ_TAC THENL + [FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + HAS_BOUNDED_VARIATION_ON_SUBSET)); + ALL_TAC] THEN + RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1]) THEN + REWRITE_TAC[SUBSET_INTERVAL_1; INTERVAL_EQ_EMPTY_1] THEN + ASM_REAL_ARITH_TAC); + GEN_REWRITE_TAC LAND_CONV [GSYM ETA_AX] THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC HAS_BOUNDED_VARIATION_ON_SUB THEN + CONJ_TAC THEN MATCH_MP_TAC INCREASING_BOUNDED_VARIATION THEN + ASM_REWRITE_TAC[]]);; + +let HAS_BOUNDED_VARIATION_DARBOUX_STRICT = prove + (`!f a b. + f has_bounded_variation_on interval[a,b] <=> + ?g h. (!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. f x = g x - h x)`, + REPEAT GEN_TAC THEN REWRITE_TAC[HAS_BOUNDED_VARIATION_DARBOUX] THEN + EQ_TAC 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 THENL + [MAP_EVERY EXISTS_TAC [`\x:real^1. g x + x`; `\x:real^1. h x + x`] THEN + ASM_REWRITE_TAC[VECTOR_ARITH `(a + x) - (b + x):real^1 = a - b`] THEN + REPEAT STRIP_TAC THEN REWRITE_TAC[DROP_ADD] THEN + MATCH_MP_TAC REAL_LET_ADD2 THEN ASM_REWRITE_TAC[] THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_SIMP_TAC[REAL_LT_IMP_LE]; + MAP_EVERY EXISTS_TAC [`g:real^1->real^1`; `h:real^1->real^1`] THEN + ASM_REWRITE_TAC[REAL_LE_LT; DROP_EQ] THEN ASM_MESON_TAC[]]);; + +let HAS_BOUNDED_VARIATION_COMPOSE_INCREASING = prove + (`!f g:real^1->real^N a b. + (!x y. x IN interval[a,b] /\ y IN interval[a,b] /\ drop x <= drop y + ==> drop(f x) <= drop(f y)) /\ + g has_bounded_variation_on interval[f a,f b] + ==> (g o f) has_bounded_variation_on interval[a,b]`, + REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + ONCE_REWRITE_TAC[HAS_BOUNDED_VARIATION_ON_COMPONENTWISE] THEN + MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `i:num` THEN + DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN + ASM_REWRITE_TAC[HAS_BOUNDED_VARIATION_DARBOUX; LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`h:real^1->real^1`; `k:real^1->real^1`] THEN + STRIP_TAC THEN + MAP_EVERY EXISTS_TAC [`(h:real^1->real^1) o (f:real^1->real^1)`; + `(k:real^1->real^1) o (f:real^1->real^1)`] THEN + ASM_REWRITE_TAC[o_THM] THEN + REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + REPEAT STRIP_TAC THEN TRY(FIRST_X_ASSUM MATCH_MP_TAC) THEN + ASM_REWRITE_TAC[] THEN + REWRITE_TAC[IN_INTERVAL_1] THEN CONJ_TAC THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[] THEN + RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1]) THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[IN_INTERVAL_1] THEN ASM_REAL_ARITH_TAC);; + +let HAS_BOUNDED_VARIATION_ON_REFLECT = prove + (`!f:real^1->real^N s. + f has_bounded_variation_on IMAGE (--) s + ==> (\x. f(--x)) has_bounded_variation_on s`, + REPEAT GEN_TAC THEN + REWRITE_TAC[has_bounded_variation_on] THEN + REWRITE_TAC[has_bounded_setvariation_on] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `B:real` THEN DISCH_TAC THEN + MAP_EVERY X_GEN_TAC [`d:(real^1->bool)->bool`; `t:real^1->bool`] THEN + STRIP_TAC THEN FIRST_X_ASSUM(MP_TAC o SPECL + [`IMAGE (IMAGE (--)) (d:(real^1->bool)->bool)`; + `IMAGE (--) (t:real^1->bool)`]) THEN + ASM_SIMP_TAC[DIVISION_OF_REFLECT] THEN + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE] THEN + ANTS_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + ASM_REWRITE_TAC[GSYM SUBSET] THEN + W(MP_TAC o PART_MATCH (lhs o rand) SUM_IMAGE o lhand o lhand o snd) THEN + ANTS_TAC THENL + [MESON_TAC[VECTOR_ARITH `--x:real^N = --y <=> x = y`; INJECTIVE_IMAGE]; + DISCH_THEN SUBST1_TAC THEN + MATCH_MP_TAC(REAL_ARITH `x = y ==> x <= d ==> y <= d`) THEN + MATCH_MP_TAC SUM_EQ THEN FIRST_ASSUM(fun th -> + GEN_REWRITE_TAC I [MATCH_MP FORALL_IN_DIVISION th]) THEN + MAP_EVERY X_GEN_TAC [`u:real^1`; `v:real^1`] THEN DISCH_TAC THEN + SUBGOAL_THEN `drop u <= drop v` ASSUME_TAC THENL + [ASM_MESON_TAC[INTERVAL_NE_EMPTY_1; division_of]; ALL_TAC] THEN + ASM_REWRITE_TAC[o_THM; REFLECT_INTERVAL] THEN + ASM_SIMP_TAC[INTERVAL_UPPERBOUND_1; INTERVAL_LOWERBOUND_1; + DROP_NEG; REAL_LE_NEG2] THEN + NORM_ARITH_TAC]);; + +let HAS_BOUNDED_VARIATION_ON_REFLECT_INTERVAL = prove + (`!f:real^1->real^N a b. + f has_bounded_variation_on interval[--b,--a] + ==> (\x. f(--x)) has_bounded_variation_on interval[a,b]`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_BOUNDED_VARIATION_ON_REFLECT THEN + ASM_REWRITE_TAC[REFLECT_INTERVAL]);; + +let VECTOR_VARIATION_REFLECT = prove + (`!f:real^1->real^N s. + vector_variation s (\x. f(--x)) = + vector_variation (IMAGE (--) s) f`, + REPEAT GEN_TAC THEN REWRITE_TAC[vector_variation; set_variation] THEN + AP_TERM_TAC THEN REWRITE_TAC[EXTENSION; IN_ELIM_THM] THEN + X_GEN_TAC `y:real` THEN EQ_TAC THEN + DISCH_THEN(X_CHOOSE_THEN `d:(real^1->bool)->bool` + (CONJUNCTS_THEN2 MP_TAC SUBST1_TAC)) THEN + DISCH_THEN(X_CHOOSE_THEN `t:real^1->bool` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `IMAGE (IMAGE (--)) (d:(real^1->bool)->bool)` THEN + (CONJ_TAC THENL + [EXISTS_TAC `IMAGE (--) (t:real^1->bool)` THEN + ASM_SIMP_TAC[DIVISION_OF_REFLECT] THEN + ASM_REWRITE_TAC[SUBSET; FORALL_IN_IMAGE] THEN + RULE_ASSUM_TAC(REWRITE_RULE[SUBSET; IN_IMAGE]) THEN + ASM_MESON_TAC[VECTOR_NEG_NEG; IN_IMAGE]; + ALL_TAC]) THEN + W(MP_TAC o PART_MATCH (lhs o rand) SUM_IMAGE o rand o snd) THEN + (ANTS_TAC THENL + [MESON_TAC[VECTOR_ARITH `--x:real^N = --y <=> x = y`; INJECTIVE_IMAGE]; + DISCH_THEN SUBST1_TAC]) THEN + MATCH_MP_TAC SUM_EQ THEN FIRST_ASSUM(fun th -> + GEN_REWRITE_TAC I [MATCH_MP FORALL_IN_DIVISION th]) THEN + MAP_EVERY X_GEN_TAC [`u:real^1`; `v:real^1`] THEN DISCH_TAC THEN + (SUBGOAL_THEN `drop u <= drop v` ASSUME_TAC THENL + [ASM_MESON_TAC[INTERVAL_NE_EMPTY_1; division_of]; ALL_TAC]) THEN + ASM_REWRITE_TAC[o_THM; REFLECT_INTERVAL] THEN + ASM_SIMP_TAC[INTERVAL_UPPERBOUND_1; INTERVAL_LOWERBOUND_1; + DROP_NEG; REAL_LE_NEG2; VECTOR_NEG_NEG] THEN + NORM_ARITH_TAC);; + +let VECTOR_VARIATION_REFLECT_INTERVAL = prove + (`!f:real^1->real^N a b. + vector_variation (interval[a,b]) (\x. f(--x)) = + vector_variation (interval[--b,--a]) f`, + REWRITE_TAC[VECTOR_VARIATION_REFLECT; REFLECT_INTERVAL]);; + +let HAS_BOUNDED_VARIATION_COMPOSE_DECREASING = prove + (`!f g:real^1->real^N a b. + (!x y. x IN interval[a,b] /\ y IN interval[a,b] /\ drop x <= drop y + ==> drop(f y) <= drop(f x)) /\ + g has_bounded_variation_on interval[f b,f a] + ==> (g o f) has_bounded_variation_on interval[a,b]`, + REPEAT GEN_TAC THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + DISCH_THEN(MP_TAC o MATCH_MP (REWRITE_RULE[VECTOR_NEG_NEG] + (ISPECL [`f:real^1->real^N`; `--b:real^1`; `--a:real^1`] + HAS_BOUNDED_VARIATION_ON_REFLECT_INTERVAL))) THEN + POP_ASSUM MP_TAC THEN + GEN_REWRITE_TAC (LAND_CONV o BINDER_CONV o BINDER_CONV o RAND_CONV) + [GSYM REAL_LE_NEG2] THEN + REWRITE_TAC[GSYM DROP_NEG; IMP_IMP] THEN + DISCH_THEN(MP_TAC o MATCH_MP HAS_BOUNDED_VARIATION_COMPOSE_INCREASING) THEN + REWRITE_TAC[o_DEF; VECTOR_NEG_NEG]);; + +let HAS_BOUNDED_VARIATION_ON_ID = prove + (`!a b. (\x. x) has_bounded_variation_on interval[a,b]`, + REPEAT GEN_TAC THEN MATCH_MP_TAC INCREASING_BOUNDED_VARIATION THEN + SIMP_TAC[]);; + +let HAS_BOUNDED_VARIATION_ON_LINEAR_IMAGE = prove + (`!f:real^1->real^1 g:real^1->real^N a b. + linear f /\ g has_bounded_variation_on IMAGE f (interval[a,b]) + ==> (g o f) has_bounded_variation_on interval[a,b]`, + REPEAT STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [LINEAR_1]) THEN + DISCH_THEN(X_CHOOSE_THEN `c:real` SUBST_ALL_TAC) THEN + REPEAT_TCL DISJ_CASES_THEN ASSUME_TAC (REAL_ARITH + `c = &0 \/ &0 <= c /\ &0 < c \/ ~(&0 <= c) /\ &0 < --c`) + THENL + [ASM_REWRITE_TAC[o_DEF; VECTOR_MUL_LZERO; HAS_BOUNDED_VARIATION_ON_CONST]; + MATCH_MP_TAC HAS_BOUNDED_VARIATION_COMPOSE_INCREASING THEN + REWRITE_TAC[DROP_CMUL]; + MATCH_MP_TAC HAS_BOUNDED_VARIATION_COMPOSE_DECREASING THEN + REWRITE_TAC[DROP_CMUL] THEN + ONCE_REWRITE_TAC[REAL_ARITH `c * y <= c * x <=> --c * x <= --c * y`]] THEN + ASM_SIMP_TAC[REAL_LE_LMUL; REAL_LT_IMP_LE] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP(MESON[] + `g has_bounded_variation_on s + ==> s = t ==> g has_bounded_variation_on t`)) THEN + ONCE_REWRITE_TAC[VECTOR_ARITH `c % x:real^N = c % x + vec 0`] THEN + ASM_REWRITE_TAC[IMAGE_AFFINITY_INTERVAL] THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[VECTOR_ADD_RID] THEN + CONV_TAC SYM_CONV THEN REWRITE_TAC[INTERVAL_EQ_EMPTY_1; DROP_CMUL] THENL + [ALL_TAC; + ONCE_REWRITE_TAC[REAL_ARITH `c * y < c * x <=> --c * x < --c * y`]] THEN + MATCH_MP_TAC REAL_LT_LMUL THEN + ASM_REWRITE_TAC[GSYM INTERVAL_EQ_EMPTY_1]);; + +let INCREASING_LEFT_LIMIT_1 = prove + (`!f a b c. + (!x y. x IN interval[a,b] /\ y IN interval[a,b] /\ drop x <= drop y + ==> drop(f x) <= drop(f y)) /\ + c IN interval[a,b] + ==> ?l. (f --> l) (at c within interval[a,c])`, + REPEAT STRIP_TAC THEN EXISTS_TAC + `lift(sup {drop(f x) | x IN interval[a,b] /\ drop x < drop c})` THEN + ONCE_REWRITE_TAC[SIMPLE_IMAGE_GEN] THEN REWRITE_TAC[LIM_WITHIN] THEN + REWRITE_TAC[DIST_REAL; GSYM drop] THEN + ASM_CASES_TAC `{x | x IN interval[a,b] /\ drop x < drop c} = {}` THENL + [GEN_TAC THEN DISCH_TAC THEN EXISTS_TAC `&1` THEN + REWRITE_TAC[REAL_LT_01] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [EXTENSION]) THEN + MATCH_MP_TAC MONO_FORALL THEN GEN_TAC THEN MATCH_MP_TAC(TAUT + `(a ==> ~b) ==> a ==> b ==> c`) THEN + REWRITE_TAC[NOT_IN_EMPTY; IN_ELIM_THM; IN_INTERVAL_1] THEN + RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1]) THEN ASM_REAL_ARITH_TAC; + ALL_TAC] THEN + X_GEN_TAC `e:real` THEN DISCH_TAC THEN + MP_TAC(ISPEC `{drop(f x) | x IN interval[a,b] /\ drop x < drop c}` SUP) THEN + ASM_REWRITE_TAC[FORALL_IN_GSPEC] THEN ANTS_TAC THENL + [CONJ_TAC THENL + [ONCE_REWRITE_TAC[SIMPLE_IMAGE_GEN] THEN ASM_SIMP_TAC[IMAGE_EQ_EMPTY]; + EXISTS_TAC `drop(f(b:real^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]; + ONCE_REWRITE_TAC[SIMPLE_IMAGE_GEN] THEN REWRITE_TAC[IMAGE_ID] THEN + ABBREV_TAC `s = sup (IMAGE (\x. drop(f x)) + {x | x IN interval[a,b] /\ drop x < drop c})` THEN + REWRITE_TAC[LIFT_DROP] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC (MP_TAC o SPEC `s - e:real`)) THEN + ASM_SIMP_TAC[REAL_ARITH `&0 < e ==> ~(s <= s - e)`; NOT_FORALL_THM] THEN + REWRITE_TAC[NOT_IMP; REAL_NOT_LE; IN_INTERVAL_1] THEN + DISCH_THEN(X_CHOOSE_THEN `d:real^1` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `drop c - drop d` THEN + RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1]) THEN + CONJ_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN + X_GEN_TAC `x:real^1` THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`d:real^1`; `x:real^1`]) THEN + FIRST_X_ASSUM(MP_TAC o SPEC `x:real^1`) THEN ASM_REAL_ARITH_TAC]);; + +let DECREASING_LEFT_LIMIT_1 = prove + (`!f a b c. + (!x y. x IN interval[a,b] /\ y IN interval[a,b] /\ drop x <= drop y + ==> drop(f y) <= drop(f x)) /\ + c IN interval[a,b] + ==> ?l. (f --> l) (at c within interval[a,c])`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL + [`\x. --((f:real^1->real^1) x)`; `a:real^1`; `b:real^1`; `c:real^1`] + INCREASING_LEFT_LIMIT_1) THEN + ASM_REWRITE_TAC[REAL_LE_NEG2; DROP_NEG] THEN + GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [GSYM LIM_NEG_EQ] THEN + REWRITE_TAC[VECTOR_NEG_NEG; ETA_AX] THEN MESON_TAC[]);; + +let INCREASING_RIGHT_LIMIT_1 = prove + (`!f a b c. + (!x y. x IN interval[a,b] /\ y IN interval[a,b] /\ drop x <= drop y + ==> drop(f x) <= drop(f y)) /\ + c IN interval[a,b] + ==> ?l. (f --> l) (at c within interval[c,b])`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`\x. (f:real^1->real^1) (--x)`; + `--b:real^1`; `--a:real^1`; `--c:real^1`] + DECREASING_LEFT_LIMIT_1) THEN + ASM_REWRITE_TAC[IN_INTERVAL_REFLECT] THEN + ONCE_REWRITE_TAC[MESON[VECTOR_NEG_NEG] + `(!x:real^1 y:real^1. P x y) <=> (!x y. P (--x) (--y))`] THEN + REWRITE_TAC[DROP_NEG; IN_INTERVAL_REFLECT; VECTOR_NEG_NEG] THEN + ASM_SIMP_TAC[REAL_LE_NEG2] THEN MATCH_MP_TAC MONO_EXISTS THEN + X_GEN_TAC `l:real^1` THEN REWRITE_TAC[LIM_WITHIN] THEN + GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) + [MESON[VECTOR_NEG_NEG] `(!x:real^1. P x) <=> (!x. P (--x))`] THEN + REWRITE_TAC[IN_INTERVAL_REFLECT; VECTOR_NEG_NEG; + NORM_ARITH `dist(--x:real^1,--y) = dist(x,y)`]);; + +let DECREASING_RIGHT_LIMIT_1 = prove + (`!f a b c. + (!x y. x IN interval[a,b] /\ y IN interval[a,b] /\ drop x <= drop y + ==> drop(f y) <= drop(f x)) /\ + c IN interval[a,b] + ==> ?l. (f --> l) (at c within interval[c,b])`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL + [`\x. --((f:real^1->real^1) x)`; `a:real^1`; `b:real^1`; `c:real^1`] + INCREASING_RIGHT_LIMIT_1) THEN + ASM_REWRITE_TAC[REAL_LE_NEG2; DROP_NEG] THEN + GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [GSYM LIM_NEG_EQ] THEN + REWRITE_TAC[VECTOR_NEG_NEG; ETA_AX] THEN MESON_TAC[]);; + +let HAS_BOUNDED_VECTOR_VARIATION_LEFT_LIMIT = prove + (`!f:real^1->real^N a b c. + f has_bounded_variation_on interval[a,b] /\ c IN interval[a,b] + ==> ?l. (f --> l) (at c within interval[a,c])`, + ONCE_REWRITE_TAC[LIM_COMPONENTWISE_LIFT; + HAS_BOUNDED_VARIATION_ON_COMPONENTWISE] THEN + REWRITE_TAC[GSYM LAMBDA_SKOLEM] THEN REPEAT GEN_TAC THEN STRIP_TAC THEN + X_GEN_TAC `i:num` THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `i:num`) THEN ASM_REWRITE_TAC[] THEN + SPEC_TAC(`\x. lift((f:real^1->real^N)x$i)`,`f:real^1->real^1`) THEN + UNDISCH_TAC `(c:real^1) IN interval[a,b]` THEN POP_ASSUM_LIST(K ALL_TAC) THEN + REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM EXISTS_LIFT] THEN + FIRST_X_ASSUM + (MP_TAC o GEN_REWRITE_RULE I [HAS_BOUNDED_VARIATION_DARBOUX]) THEN + REWRITE_TAC[LEFT_IMP_EXISTS_THM; CONJ_ASSOC] THEN REPEAT GEN_TAC THEN + DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN + REWRITE_TAC[GSYM CONJ_ASSOC] THEN DISCH_THEN(CONJUNCTS_THEN + (MP_TAC o SPEC `c:real^1` o MATCH_MP + (ONCE_REWRITE_RULE[IMP_CONJ] INCREASING_LEFT_LIMIT_1))) THEN + ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `l2:real^1` THEN DISCH_TAC THEN + X_GEN_TAC `l1:real^1` THEN DISCH_TAC THEN + EXISTS_TAC `l1 - l2:real^1` THEN + GEN_REWRITE_TAC (RATOR_CONV o LAND_CONV) [GSYM ETA_AX] THEN + ASM_SIMP_TAC[LIM_SUB]);; + +let HAS_BOUNDED_VECTOR_VARIATION_RIGHT_LIMIT = prove + (`!f:real^1->real^N a b c. + f has_bounded_variation_on interval[a,b] /\ c IN interval[a,b] + ==> ?l. (f --> l) (at c within interval[c,b])`, + ONCE_REWRITE_TAC[LIM_COMPONENTWISE_LIFT; + HAS_BOUNDED_VARIATION_ON_COMPONENTWISE] THEN + REWRITE_TAC[GSYM LAMBDA_SKOLEM] THEN REPEAT GEN_TAC THEN STRIP_TAC THEN + X_GEN_TAC `i:num` THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `i:num`) THEN ASM_REWRITE_TAC[] THEN + SPEC_TAC(`\x. lift((f:real^1->real^N)x$i)`,`f:real^1->real^1`) THEN + UNDISCH_TAC `(c:real^1) IN interval[a,b]` THEN POP_ASSUM_LIST(K ALL_TAC) THEN + REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM EXISTS_LIFT] THEN + FIRST_X_ASSUM + (MP_TAC o GEN_REWRITE_RULE I [HAS_BOUNDED_VARIATION_DARBOUX]) THEN + REWRITE_TAC[LEFT_IMP_EXISTS_THM; CONJ_ASSOC] THEN REPEAT GEN_TAC THEN + DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN + REWRITE_TAC[GSYM CONJ_ASSOC] THEN DISCH_THEN(CONJUNCTS_THEN + (MP_TAC o SPEC `c:real^1` o MATCH_MP + (ONCE_REWRITE_RULE[IMP_CONJ] INCREASING_RIGHT_LIMIT_1))) THEN + ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `l2:real^1` THEN DISCH_TAC THEN + X_GEN_TAC `l1:real^1` THEN DISCH_TAC THEN + EXISTS_TAC `l1 - l2:real^1` THEN + GEN_REWRITE_TAC (RATOR_CONV o LAND_CONV) [GSYM ETA_AX] THEN + ASM_SIMP_TAC[LIM_SUB]);; + +let VECTOR_VARIATION_CONTINUOUS_LEFT = prove + (`!f:real^1->real^1 a b c. + f has_bounded_variation_on interval[a,b] /\ c IN interval[a,b] + ==> ((\x. lift(vector_variation(interval[a,x]) f)) + continuous (at c within interval[a,c]) <=> + f continuous (at c within interval[a,c]))`, + REPEAT STRIP_TAC THEN EQ_TAC THENL + [REWRITE_TAC[continuous_within] THEN + REWRITE_TAC[DIST_LIFT; IN_ELIM_THM; DIST_REAL; GSYM drop] THEN + DISCH_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 + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `d:real` THEN STRIP_TAC THEN + ASM_REWRITE_TAC[] THEN X_GEN_TAC `x:real^1` THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `x:real^1`) THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] REAL_LET_TRANS) THEN + REWRITE_TAC[GSYM DROP_SUB] THEN + MP_TAC(ISPECL [`f:real^1->real^1`; `a:real^1`; `c:real^1`; `x:real^1`] + VECTOR_VARIATION_COMBINE) THEN + ANTS_TAC THENL + [RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1]) THEN + REPEAT(CONJ_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC]) THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + HAS_BOUNDED_VARIATION_ON_SUBSET)) THEN + REWRITE_TAC[SUBSET_INTERVAL_1] THEN ASM_REAL_ARITH_TAC; + ALL_TAC] THEN + DISCH_THEN(SUBST1_TAC o SYM) THEN + REWRITE_TAC[REAL_ARITH `abs(a - (a + b)) = abs b`] THEN + REWRITE_TAC[drop; GSYM NORM_REAL] THEN + MATCH_MP_TAC(REAL_ARITH `x <= a ==> x <= abs a`) THEN + ONCE_REWRITE_TAC[NORM_SUB] THEN + MATCH_MP_TAC VECTOR_VARIATION_GE_NORM_FUNCTION THEN CONJ_TAC THENL + [FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + HAS_BOUNDED_VARIATION_ON_SUBSET)); + REWRITE_TAC[SEGMENT_1] THEN COND_CASES_TAC] THEN + REWRITE_TAC[SUBSET_INTERVAL_1] THEN + RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1]) THEN ASM_REAL_ARITH_TAC; + ALL_TAC] THEN + DISCH_TAC THEN ASM_CASES_TAC `c limit_point_of interval[a:real^1,c]` THENL + [ALL_TAC; + ASM_REWRITE_TAC[CONTINUOUS_WITHIN; LIM; TRIVIAL_LIMIT_WITHIN]] THEN + FIRST_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 + MP_TAC(ISPECL [`h:real^1->real^1`; `a:real^1`; `b:real^1`; `c:real^1`] + INCREASING_LEFT_LIMIT_1) THEN + MP_TAC(ISPECL [`g:real^1->real^1`; `a:real^1`; `b:real^1`; `c:real^1`] + INCREASING_LEFT_LIMIT_1) THEN + ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `gc:real^1` THEN DISCH_TAC THEN + X_GEN_TAC `hc:real^1` THEN DISCH_TAC THEN + ABBREV_TAC `k = gc - (g:real^1->real^1) c` THEN + SUBGOAL_THEN `hc - (h:real^1->real^1) c = k` ASSUME_TAC THENL + [EXPAND_TAC "k" THEN + ONCE_REWRITE_TAC[VECTOR_ARITH + `hc' - hc:real^1 = gc' - gc <=> gc' - hc' = gc - hc`] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [CONTINUOUS_WITHIN]) THEN + ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC(REWRITE_RULE[TAUT `a /\ b /\ c ==> d <=> a /\ b ==> c ==> d`] + LIM_UNIQUE) THEN + ASM_REWRITE_TAC[TRIVIAL_LIMIT_WITHIN] THEN + GEN_REWRITE_TAC (RATOR_CONV o LAND_CONV) [GSYM ETA_AX] THEN + ASM_SIMP_TAC[LIM_SUB]; + ALL_TAC] THEN + MAP_EVERY ABBREV_TAC + [`g':real^1->real^1 = \x. if drop c <= drop x then g(x) + k else g(x)`; + `h':real^1->real^1 = \x. if drop c <= drop x then h(x) + k else h(x)`] THEN + SUBGOAL_THEN + `(!x y. x IN interval[a,c] /\ y IN interval[a,c] /\ drop x <= drop y + ==> drop(g' x) <= drop(g' y)) /\ + (!x y. x IN interval[a,c] /\ y IN interval[a,c] /\ drop x <= drop y + ==> drop(h' x) <= drop(h' y))` + STRIP_ASSUME_TAC THENL + [MAP_EVERY EXPAND_TAC ["g'"; "h'"] THEN REWRITE_TAC[] THEN CONJ_TAC THEN + MAP_EVERY X_GEN_TAC [`x:real^1`; `y:real^1`] THEN + REWRITE_TAC[IN_INTERVAL_1] THEN STRIP_TAC THEN + (ASM_CASES_TAC `drop c <= drop x` THENL + [SUBGOAL_THEN `drop c <= drop y` ASSUME_TAC THENL + [ASM_REAL_ARITH_TAC; ASM_REWRITE_TAC[]] THEN + REWRITE_TAC[DROP_ADD; REAL_LE_RADD] 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 + ASM_REWRITE_TAC[] THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[] THENL + [ALL_TAC; + 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] THEN + SUBGOAL_THEN `y:real^1 = c` SUBST_ALL_TAC THENL + [REWRITE_TAC[GSYM DROP_EQ] THEN ASM_REAL_ARITH_TAC; ALL_TAC] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (MESON[] + `gc - g c = k + ==> b <= drop(g c + (gc - g c)) ==> b <= drop(g c + k)`)) THEN + REWRITE_TAC[VECTOR_ARITH `a + b - a:real^1 = b`] THEN + MATCH_MP_TAC(ISPEC `at c within interval[a:real^1,c]` + LIM_DROP_LBOUND)) + THENL [EXISTS_TAC `g:real^1->real^1`; EXISTS_TAC `h:real^1->real^1`] THEN + ASM_REWRITE_TAC[TRIVIAL_LIMIT_WITHIN; EVENTUALLY_WITHIN] THEN + EXISTS_TAC `drop c - drop x` THEN + (CONJ_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC]) THEN + REWRITE_TAC[DIST_REAL; GSYM drop; IN_INTERVAL_1] THEN + REWRITE_TAC[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 + `(g':real^1->real^1) continuous (at c within interval[a,c]) /\ + (h':real^1->real^1) continuous (at c within interval[a,c])` + MP_TAC THENL + [MAP_EVERY EXPAND_TAC ["g'"; "h'"] THEN + REWRITE_TAC[CONTINUOUS_WITHIN; REAL_LE_REFL] THEN + RULE_ASSUM_TAC(REWRITE_RULE[VECTOR_ARITH + `g - g':real^1 = k <=> g' + k = g`]) THEN + ASM_REWRITE_TAC[] THEN CONJ_TAC THEN FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP + (REWRITE_RULE[IMP_CONJ_ALT] LIM_TRANSFORM)) THEN + MAP_EVERY EXPAND_TAC ["g'"; "h'"] THEN + REWRITE_TAC[LIM_WITHIN; DIST_REAL; GSYM drop; IN_INTERVAL_1] THEN + SIMP_TAC[REAL_ARITH `x <= c /\ &0 < abs(x - c) ==> ~(c <= x)`] THEN + REWRITE_TAC[VECTOR_SUB_REFL; DROP_VEC; REAL_SUB_REFL; REAL_ABS_NUM] THEN + MESON_TAC[REAL_LT_01]; + ALL_TAC] THEN + REWRITE_TAC[continuous_within] THEN + REWRITE_TAC[DIST_LIFT; IN_ELIM_THM; DIST_REAL; GSYM drop] THEN + DISCH_THEN(fun th -> + X_GEN_TAC `e:real` THEN DISCH_TAC THEN + CONJUNCTS_THEN (MP_TAC o SPEC `e / &2`) th) THEN + ASM_REWRITE_TAC[REAL_HALF] THEN + DISCH_THEN(X_CHOOSE_THEN `d2:real` STRIP_ASSUME_TAC) THEN + DISCH_THEN(X_CHOOSE_THEN `d1:real` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `min d1 d2:real` THEN ASM_REWRITE_TAC[REAL_LT_MIN] THEN + X_GEN_TAC `d:real^1` THEN STRIP_TAC THEN + MP_TAC(ISPECL [`f:real^1->real^1`; `a:real^1`; `c:real^1`; `d:real^1`] + VECTOR_VARIATION_COMBINE) THEN + ANTS_TAC THENL + [RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1]) THEN + REPEAT(CONJ_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC]) THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + HAS_BOUNDED_VARIATION_ON_SUBSET)) THEN + REWRITE_TAC[SUBSET_INTERVAL_1] THEN ASM_REAL_ARITH_TAC; + DISCH_THEN(SUBST1_TAC o SYM)] THEN + REWRITE_TAC[REAL_ARITH `abs(a - (a + b)) = abs b`] THEN + MATCH_MP_TAC(REAL_ARITH `&0 <= x /\ x < a ==> abs x < a`) THEN + CONJ_TAC THENL + [MATCH_MP_TAC VECTOR_VARIATION_POS_LE THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + HAS_BOUNDED_VARIATION_ON_SUBSET)) THEN + RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1]) THEN + REWRITE_TAC[SUBSET_INTERVAL_1] THEN ASM_REAL_ARITH_TAC; + ALL_TAC] THEN + SUBGOAL_THEN `f:real^1->real^1 = \x. g' x - h' x` SUBST1_TAC THENL + [MAP_EVERY EXPAND_TAC ["g'"; "h'"] THEN REWRITE_TAC[FUN_EQ_THM] THEN + GEN_TAC THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN VECTOR_ARITH_TAC; + ALL_TAC] THEN + MP_TAC(ISPECL + [`g':real^1->real^1`; `\x. --((h':real^1->real^1) x)`; + `interval[d:real^1,c]`] VECTOR_VARIATION_TRIANGLE) THEN + ANTS_TAC THENL + [CONJ_TAC THENL [ALL_TAC; MATCH_MP_TAC HAS_BOUNDED_VARIATION_ON_NEG] THEN + MATCH_MP_TAC HAS_BOUNDED_VARIATION_ON_SUBSET THEN + EXISTS_TAC `interval[a:real^1,c]` THEN + ASM_SIMP_TAC[INCREASING_BOUNDED_VARIATION; SUBSET_INTERVAL_1] THEN + RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1]) THEN ASM_REAL_ARITH_TAC; + ALL_TAC] THEN + REWRITE_TAC[VECTOR_SUB] THEN MATCH_MP_TAC(REAL_ARITH + `y < a / &2 /\ z < a / &2 ==> x <= y + z ==> x < a`) THEN + REWRITE_TAC[VECTOR_VARIATION_NEG] THEN CONJ_TAC THEN + W(MP_TAC o PART_MATCH (lhs o rand) + INCREASING_VECTOR_VARIATION o lhand o snd) THEN + (ANTS_TAC THENL + [RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1]) THEN + ASM_REWRITE_TAC[INTERVAL_EQ_EMPTY_1; IN_INTERVAL_1; REAL_NOT_LT] THEN + REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REAL_ARITH_TAC; + DISCH_THEN SUBST1_TAC]) THEN + MATCH_MP_TAC(REAL_ARITH `abs(x - y) < e ==> y - x < e`) THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[]);; + +let VECTOR_VARIATION_CONTINUOUS_RIGHT = prove + (`!f:real^1->real^1 a b c. + f has_bounded_variation_on interval[a,b] /\ c IN interval[a,b] + ==> ((\x. lift(vector_variation(interval[a,x]) f)) + continuous (at c within interval[c,b]) <=> + f continuous (at c within interval[c,b]))`, + REPEAT STRIP_TAC THEN EQ_TAC THENL + [REWRITE_TAC[continuous_within] THEN + REWRITE_TAC[DIST_LIFT; IN_ELIM_THM; DIST_REAL; GSYM drop] THEN + DISCH_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 + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `d:real` THEN STRIP_TAC THEN + ASM_REWRITE_TAC[] THEN X_GEN_TAC `x:real^1` THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `x:real^1`) THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] REAL_LET_TRANS) THEN + REWRITE_TAC[GSYM DROP_SUB] THEN + MP_TAC(ISPECL [`f:real^1->real^1`; `a:real^1`; `x:real^1`; `c:real^1`] + VECTOR_VARIATION_COMBINE) THEN + ANTS_TAC THENL + [RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1]) THEN + REPEAT(CONJ_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC]) THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + HAS_BOUNDED_VARIATION_ON_SUBSET)) THEN + REWRITE_TAC[SUBSET_INTERVAL_1] THEN ASM_REAL_ARITH_TAC; + ALL_TAC] THEN + DISCH_THEN(SUBST1_TAC o SYM) THEN + REWRITE_TAC[REAL_ARITH `abs((a + b) - a) = abs b`] THEN + REWRITE_TAC[drop; GSYM NORM_REAL] THEN + MATCH_MP_TAC(REAL_ARITH `x <= a ==> x <= abs a`) THEN + MATCH_MP_TAC VECTOR_VARIATION_GE_NORM_FUNCTION THEN CONJ_TAC THENL + [FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + HAS_BOUNDED_VARIATION_ON_SUBSET)); + REWRITE_TAC[SEGMENT_1] THEN COND_CASES_TAC] THEN + REWRITE_TAC[SUBSET_INTERVAL_1] THEN + RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1]) THEN ASM_REAL_ARITH_TAC; + ALL_TAC] THEN + DISCH_TAC THEN ASM_CASES_TAC `c limit_point_of interval[c:real^1,b]` THENL + [ALL_TAC; + ASM_REWRITE_TAC[CONTINUOUS_WITHIN; LIM; TRIVIAL_LIMIT_WITHIN]] THEN + FIRST_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 + MP_TAC(ISPECL [`h:real^1->real^1`; `a:real^1`; `b:real^1`; `c:real^1`] + INCREASING_RIGHT_LIMIT_1) THEN + MP_TAC(ISPECL [`g:real^1->real^1`; `a:real^1`; `b:real^1`; `c:real^1`] + INCREASING_RIGHT_LIMIT_1) THEN + ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `gc:real^1` THEN DISCH_TAC THEN + X_GEN_TAC `hc:real^1` THEN DISCH_TAC THEN + ABBREV_TAC `k = gc - (g:real^1->real^1) c` THEN + SUBGOAL_THEN `hc - (h:real^1->real^1) c = k` ASSUME_TAC THENL + [EXPAND_TAC "k" THEN + ONCE_REWRITE_TAC[VECTOR_ARITH + `hc' - hc:real^1 = gc' - gc <=> gc' - hc' = gc - hc`] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [CONTINUOUS_WITHIN]) THEN + ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC(REWRITE_RULE[TAUT `a /\ b /\ c ==> d <=> a /\ b ==> c ==> d`] + LIM_UNIQUE) THEN + ASM_REWRITE_TAC[TRIVIAL_LIMIT_WITHIN] THEN + GEN_REWRITE_TAC (RATOR_CONV o LAND_CONV) [GSYM ETA_AX] THEN + ASM_SIMP_TAC[LIM_SUB]; + ALL_TAC] THEN + MAP_EVERY ABBREV_TAC + [`g':real^1->real^1 = \x. if drop x <= drop c then g(x) + k else g(x)`; + `h':real^1->real^1 = \x. if drop x <= drop c then h(x) + k else h(x)`] THEN + SUBGOAL_THEN + `(!x y. x IN interval[c,b] /\ y IN interval[c,b] /\ drop x <= drop y + ==> drop(g' x) <= drop(g' y)) /\ + (!x y. x IN interval[c,b] /\ y IN interval[c,b] /\ drop x <= drop y + ==> drop(h' x) <= drop(h' y))` + STRIP_ASSUME_TAC THENL + [MAP_EVERY EXPAND_TAC ["g'"; "h'"] THEN REWRITE_TAC[] THEN CONJ_TAC THEN + MAP_EVERY X_GEN_TAC [`x:real^1`; `y:real^1`] THEN + REWRITE_TAC[IN_INTERVAL_1] THEN STRIP_TAC THEN + (ASM_CASES_TAC `drop y <= drop c` THENL + [SUBGOAL_THEN `drop x <= drop c` ASSUME_TAC THENL + [ASM_REAL_ARITH_TAC; ASM_REWRITE_TAC[]] THEN + REWRITE_TAC[DROP_ADD; REAL_LE_RADD] 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 + ASM_REWRITE_TAC[] THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[] THENL + [ALL_TAC; + 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] THEN + SUBGOAL_THEN `x:real^1 = c` SUBST_ALL_TAC THENL + [REWRITE_TAC[GSYM DROP_EQ] THEN ASM_REAL_ARITH_TAC; ALL_TAC] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (MESON[] + `gc - g c = k + ==> drop(g c + (gc - g c)) <= b ==> drop(g c + k) <= b`)) THEN + REWRITE_TAC[VECTOR_ARITH `a + b - a:real^1 = b`] THEN + MATCH_MP_TAC(ISPEC `at c within interval[c:real^1,b]` + LIM_DROP_UBOUND)) + THENL [EXISTS_TAC `g:real^1->real^1`; EXISTS_TAC `h:real^1->real^1`] THEN + ASM_REWRITE_TAC[TRIVIAL_LIMIT_WITHIN; EVENTUALLY_WITHIN] THEN + EXISTS_TAC `drop y - drop c` THEN + (CONJ_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC]) THEN + REWRITE_TAC[DIST_REAL; GSYM drop; IN_INTERVAL_1] THEN + REWRITE_TAC[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 + `(g':real^1->real^1) continuous (at c within interval[c,b]) /\ + (h':real^1->real^1) continuous (at c within interval[c,b])` + MP_TAC THENL + [MAP_EVERY EXPAND_TAC ["g'"; "h'"] THEN + REWRITE_TAC[CONTINUOUS_WITHIN; REAL_LE_REFL] THEN + RULE_ASSUM_TAC(REWRITE_RULE[VECTOR_ARITH + `g - g':real^1 = k <=> g' + k = g`]) THEN + ASM_REWRITE_TAC[] THEN CONJ_TAC THEN FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP + (REWRITE_RULE[IMP_CONJ_ALT] LIM_TRANSFORM)) THEN + MAP_EVERY EXPAND_TAC ["g'"; "h'"] THEN + REWRITE_TAC[LIM_WITHIN; DIST_REAL; GSYM drop; IN_INTERVAL_1] THEN + SIMP_TAC[REAL_ARITH `c <= x /\ &0 < abs(x - c) ==> ~(x <= c)`] THEN + REWRITE_TAC[VECTOR_SUB_REFL; DROP_VEC; REAL_SUB_REFL; REAL_ABS_NUM] THEN + MESON_TAC[REAL_LT_01]; + ALL_TAC] THEN + REWRITE_TAC[continuous_within] THEN + REWRITE_TAC[DIST_LIFT; IN_ELIM_THM; DIST_REAL; GSYM drop] THEN + DISCH_THEN(fun th -> + X_GEN_TAC `e:real` THEN DISCH_TAC THEN + CONJUNCTS_THEN (MP_TAC o SPEC `e / &2`) th) THEN + ASM_REWRITE_TAC[REAL_HALF] THEN + DISCH_THEN(X_CHOOSE_THEN `d2:real` STRIP_ASSUME_TAC) THEN + DISCH_THEN(X_CHOOSE_THEN `d1:real` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `min d1 d2:real` THEN ASM_REWRITE_TAC[REAL_LT_MIN] THEN + X_GEN_TAC `d:real^1` THEN STRIP_TAC THEN + MP_TAC(ISPECL [`f:real^1->real^1`; `a:real^1`; `d:real^1`; `c:real^1`] + VECTOR_VARIATION_COMBINE) THEN + ANTS_TAC THENL + [RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1]) THEN + REPEAT(CONJ_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC]) THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + HAS_BOUNDED_VARIATION_ON_SUBSET)) THEN + REWRITE_TAC[SUBSET_INTERVAL_1] THEN ASM_REAL_ARITH_TAC; + DISCH_THEN(SUBST1_TAC o SYM)] THEN + REWRITE_TAC[REAL_ARITH `(a + b) - a:real = b`] THEN + MATCH_MP_TAC(REAL_ARITH `&0 <= x /\ x < a ==> abs x < a`) THEN + CONJ_TAC THENL + [MATCH_MP_TAC VECTOR_VARIATION_POS_LE THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + HAS_BOUNDED_VARIATION_ON_SUBSET)) THEN + RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1]) THEN + REWRITE_TAC[SUBSET_INTERVAL_1] THEN ASM_REAL_ARITH_TAC; + ALL_TAC] THEN + SUBGOAL_THEN `f:real^1->real^1 = \x. g' x - h' x` SUBST1_TAC THENL + [MAP_EVERY EXPAND_TAC ["g'"; "h'"] THEN REWRITE_TAC[FUN_EQ_THM] THEN + GEN_TAC THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN VECTOR_ARITH_TAC; + ALL_TAC] THEN + MP_TAC(ISPECL + [`g':real^1->real^1`; `\x. --((h':real^1->real^1) x)`; + `interval[c:real^1,d]`] VECTOR_VARIATION_TRIANGLE) THEN + ANTS_TAC THENL + [CONJ_TAC THENL [ALL_TAC; MATCH_MP_TAC HAS_BOUNDED_VARIATION_ON_NEG] THEN + MATCH_MP_TAC HAS_BOUNDED_VARIATION_ON_SUBSET THEN + EXISTS_TAC `interval[c:real^1,b]` THEN + ASM_SIMP_TAC[INCREASING_BOUNDED_VARIATION; SUBSET_INTERVAL_1] THEN + RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1]) THEN ASM_REAL_ARITH_TAC; + ALL_TAC] THEN + REWRITE_TAC[VECTOR_SUB] THEN MATCH_MP_TAC(REAL_ARITH + `y < a / &2 /\ z < a / &2 ==> x <= y + z ==> x < a`) THEN + REWRITE_TAC[VECTOR_VARIATION_NEG] THEN CONJ_TAC THEN + W(MP_TAC o PART_MATCH (lhs o rand) + INCREASING_VECTOR_VARIATION o lhand o snd) THEN + (ANTS_TAC THENL + [RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1]) THEN + ASM_REWRITE_TAC[INTERVAL_EQ_EMPTY_1; IN_INTERVAL_1; REAL_NOT_LT] THEN + REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REAL_ARITH_TAC; + DISCH_THEN SUBST1_TAC]) THEN + MATCH_MP_TAC(REAL_ARITH `abs x < e ==> x < e`) THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[]);; + +let VECTOR_VARIATION_CONTINUOUS = prove + (`!f:real^1->real^1 a b c. + f has_bounded_variation_on interval[a,b] /\ c IN interval[a,b] + ==> ((\x. lift(vector_variation(interval[a,x]) f)) + continuous (at c within interval[a,b]) <=> + f continuous (at c within interval[a,b]))`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN + `!f:real^1->real^1. + f continuous (at c within interval[a,b]) <=> + f continuous (at c within interval[a,c]) /\ + f continuous (at c within interval[c,b])` + (fun th -> REWRITE_TAC[th] THEN + ASM_MESON_TAC[VECTOR_VARIATION_CONTINUOUS_LEFT; + VECTOR_VARIATION_CONTINUOUS_RIGHT]) THEN + GEN_TAC THEN REWRITE_TAC[CONTINUOUS_WITHIN] THEN EQ_TAC THENL + [DISCH_THEN(ASSUME_TAC o GEN_ALL o + MATCH_MP (REWRITE_RULE[IMP_CONJ] LIM_WITHIN_SUBSET)) THEN + CONJ_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC; + DISCH_THEN(MP_TAC o MATCH_MP LIM_UNION) THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] LIM_WITHIN_SUBSET)] THEN + REWRITE_TAC[SUBSET; IN_UNION; IN_INTERVAL_1] THEN + RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1]) THEN ASM_REAL_ARITH_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]))`, + REPEAT STRIP_TAC THEN + MAP_EVERY EXISTS_TAC + [`\x:real^1. x + lift(vector_variation (interval[a,x]) (f:real^1->real^1))`; + `\x:real^1. x + lift(vector_variation (interval[a,x]) f) - f x`] THEN + REWRITE_TAC[VECTOR_ARITH `(x + l) - (x + l - f):real^1 = f`] THEN + REWRITE_TAC[LIFT_DROP; DROP_SUB; DROP_ADD] THEN REPEAT STRIP_TAC THENL + [MATCH_MP_TAC REAL_LE_ADD2 THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC VECTOR_VARIATION_MONOTONE; + MATCH_MP_TAC REAL_LE_ADD2 THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC(REAL_ARITH + `!x. a - (b - x) <= c - (d - x) ==> a - b <= c - d`) THEN + EXISTS_TAC `drop(f(a:real^1))` THEN + REWRITE_TAC[GSYM DROP_SUB] THEN + MATCH_MP_TAC VECTOR_VARIATION_MINUS_FUNCTION_MONOTONE; + MATCH_MP_TAC REAL_LTE_ADD2 THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC VECTOR_VARIATION_MONOTONE; + MATCH_MP_TAC REAL_LTE_ADD2 THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC(REAL_ARITH + `!x. a - (b - x) <= c - (d - x) ==> a - b <= c - d`) THEN + EXISTS_TAC `drop(f(a:real^1))` THEN + REWRITE_TAC[GSYM DROP_SUB] THEN + MATCH_MP_TAC VECTOR_VARIATION_MINUS_FUNCTION_MONOTONE; + MATCH_MP_TAC CONTINUOUS_ADD THEN + REWRITE_TAC[CONTINUOUS_WITHIN_ID] THEN + MP_TAC(ISPECL [`f:real^1->real^1`; `a:real^1`; `b:real^1`; `x:real^1`] + VECTOR_VARIATION_CONTINUOUS_LEFT) THEN + ASM_REWRITE_TAC[]; + MATCH_MP_TAC CONTINUOUS_ADD THEN + REWRITE_TAC[CONTINUOUS_WITHIN_ID] THEN + MATCH_MP_TAC CONTINUOUS_SUB THEN ASM_REWRITE_TAC[] THEN + MP_TAC(ISPECL [`f:real^1->real^1`; `a:real^1`; `b:real^1`; `x:real^1`] + VECTOR_VARIATION_CONTINUOUS_LEFT) THEN + ASM_REWRITE_TAC[]; + MATCH_MP_TAC CONTINUOUS_ADD THEN + REWRITE_TAC[CONTINUOUS_WITHIN_ID] THEN + MP_TAC(ISPECL [`f:real^1->real^1`; `a:real^1`; `b:real^1`; `x:real^1`] + VECTOR_VARIATION_CONTINUOUS_RIGHT) THEN + ASM_REWRITE_TAC[]; + MATCH_MP_TAC CONTINUOUS_ADD THEN + REWRITE_TAC[CONTINUOUS_WITHIN_ID] THEN + MATCH_MP_TAC CONTINUOUS_SUB THEN ASM_REWRITE_TAC[] THEN + MP_TAC(ISPECL [`f:real^1->real^1`; `a:real^1`; `b:real^1`; `x:real^1`] + VECTOR_VARIATION_CONTINUOUS_RIGHT) THEN + ASM_REWRITE_TAC[]; + MATCH_MP_TAC CONTINUOUS_ADD THEN + REWRITE_TAC[CONTINUOUS_WITHIN_ID] THEN + MP_TAC(ISPECL [`f:real^1->real^1`; `a:real^1`; `b:real^1`; `x:real^1`] + VECTOR_VARIATION_CONTINUOUS) THEN + ASM_REWRITE_TAC[]; + MATCH_MP_TAC CONTINUOUS_ADD THEN + REWRITE_TAC[CONTINUOUS_WITHIN_ID] THEN + MATCH_MP_TAC CONTINUOUS_SUB THEN ASM_REWRITE_TAC[] THEN + MP_TAC(ISPECL [`f:real^1->real^1`; `a:real^1`; `b:real^1`; `x:real^1`] + VECTOR_VARIATION_CONTINUOUS) THEN + ASM_REWRITE_TAC[]] THEN + (CONJ_TAC THENL + [FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + HAS_BOUNDED_VARIATION_ON_SUBSET)); + ALL_TAC] THEN + RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1]) THEN + REWRITE_TAC[SUBSET_INTERVAL_1; INTERVAL_EQ_EMPTY_1] THEN + ASM_REAL_ARITH_TAC));; + +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 HAS_BOUNDED_VARIATION_ABSOLUTELY_INTEGRABLE_DERIVATIVE = prove + (`!f:real^1->real^N s a b. + COUNTABLE s /\ f continuous_on interval[a,b] /\ + (!x. x IN interval[a,b] DIFF s ==> f differentiable at x) + ==> (f has_bounded_variation_on interval[a,b] <=> + (\x. vector_derivative f (at x)) + absolutely_integrable_on interval[a,b])`, + REPEAT STRIP_TAC THEN + REWRITE_TAC[ABSOLUTELY_INTEGRABLE_BOUNDED_SETVARIATION_EQ] THEN + REWRITE_TAC[has_bounded_variation_on] THEN + MATCH_MP_TAC(TAUT `q /\ (p <=> r) ==> (p <=> q /\ r)`) THEN CONJ_TAC THENL + [ASM_CASES_TAC `interval[a:real^1,b] = {}` THEN + ASM_REWRITE_TAC[INTEGRABLE_ON_EMPTY] THEN + RULE_ASSUM_TAC(REWRITE_RULE[INTERVAL_NE_EMPTY_1]) THEN + MP_TAC(ISPECL [`f:real^1->real^N`; + `\x. vector_derivative (f:real^1->real^N) (at x)`; + `s:real^1->bool`; `a:real^1`; `b:real^1`] + FUNDAMENTAL_THEOREM_OF_CALCULUS_STRONG) THEN + ASM_MESON_TAC[VECTOR_DERIVATIVE_WORKS; integrable_on; + HAS_VECTOR_DERIVATIVE_AT_WITHIN]; + MATCH_MP_TAC(MESON[HAS_BOUNDED_SETVARIATION_ON_EQ] + `(!a b. ~(interval[a,b] = {}) /\ interval[a,b] SUBSET s + ==> f(interval[a,b]) = g(interval[a,b])) + ==> (f has_bounded_setvariation_on s <=> + g has_bounded_setvariation_on s)`) THEN + SIMP_TAC[INTERVAL_UPPERBOUND; INTERVAL_LOWERBOUND; + GSYM INTERVAL_NE_EMPTY] THEN + MAP_EVERY X_GEN_TAC [`u:real^1`; `v:real^1`] THEN + REWRITE_TAC[INTERVAL_NE_EMPTY_1] THEN STRIP_TAC THEN + MP_TAC(ISPECL [`f:real^1->real^N`; + `\x. vector_derivative (f:real^1->real^N) (at x)`; + `s:real^1->bool`; `u:real^1`; `v:real^1`] + FUNDAMENTAL_THEOREM_OF_CALCULUS_STRONG) THEN + ASM_REWRITE_TAC[GSYM VECTOR_DERIVATIVE_WORKS] THEN + ANTS_TAC THENL [ALL_TAC; MESON_TAC[INTEGRAL_UNIQUE]] THEN CONJ_TAC THENL + [ASM_MESON_TAC[CONTINUOUS_ON_SUBSET; IN_DIFF; SUBSET]; + REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_VECTOR_DERIVATIVE_AT_WITHIN THEN + ASM_SIMP_TAC[GSYM VECTOR_DERIVATIVE_WORKS] THEN ASM SET_TAC[]]]);; + +let HAS_BOUNDED_VARIATION_INTEGRABLE_NORM_DERIVATIVE = prove + (`!f:real^1->real^N s a b. + COUNTABLE s /\ f continuous_on interval[a,b] /\ + (!x. x IN interval[a,b] DIFF s ==> f differentiable at x) + ==> (f has_bounded_variation_on interval[a,b] <=> + (\x. lift(norm(vector_derivative f (at x)))) + integrable_on interval[a,b])`, + REPEAT GEN_TAC THEN DISCH_THEN(fun th -> + STRIP_ASSUME_TAC th THEN + REWRITE_TAC[MATCH_MP HAS_BOUNDED_VARIATION_ABSOLUTELY_INTEGRABLE_DERIVATIVE + th]) THEN + REWRITE_TAC[absolutely_integrable_on] THEN + MATCH_MP_TAC(TAUT `p ==> (p /\ q <=> q)`) THEN + ASM_CASES_TAC `interval[a:real^1,b] = {}` THEN + ASM_REWRITE_TAC[INTEGRABLE_ON_EMPTY] THEN + RULE_ASSUM_TAC(REWRITE_RULE[INTERVAL_NE_EMPTY_1]) THEN + MP_TAC(ISPECL [`f:real^1->real^N`; + `\x. vector_derivative (f:real^1->real^N) (at x)`; + `s:real^1->bool`; `a:real^1`; `b:real^1`] + FUNDAMENTAL_THEOREM_OF_CALCULUS_STRONG) THEN + ASM_MESON_TAC[VECTOR_DERIVATIVE_WORKS; integrable_on; + HAS_VECTOR_DERIVATIVE_AT_WITHIN]);; + +let VECTOR_VARIATION_INTEGRAL_NORM_DERIVATIVE = prove + (`!f:real^1->real^N s a b. + COUNTABLE s /\ f continuous_on interval[a,b] /\ + (!x. x IN interval[a,b] DIFF s ==> f differentiable at x) /\ + f has_bounded_variation_on interval[a,b] + ==> vector_variation (interval[a,b]) f = + drop(integral (interval[a,b]) + (\x. lift(norm(vector_derivative f (at x)))))`, + REPEAT STRIP_TAC THEN MP_TAC(ISPECL + [`f:real^1->real^N`; `s:real^1->bool`; `a:real^1`; `b:real^1`] + HAS_BOUNDED_VARIATION_ABSOLUTELY_INTEGRABLE_DERIVATIVE) THEN + ASM_REWRITE_TAC[] THEN DISCH_TAC THEN + FIRST_ASSUM(MP_TAC o MATCH_MP ABSOLUTELY_INTEGRABLE_SET_VARIATION) THEN + REWRITE_TAC[vector_variation] THEN DISCH_THEN(SUBST1_TAC o SYM) THEN + MATCH_MP_TAC SET_VARIATION_EQ THEN + MAP_EVERY X_GEN_TAC [`u:real^1`; `v:real^1`] THEN + SIMP_TAC[INTERVAL_NE_EMPTY_1; INTERVAL_LOWERBOUND_1; + INTERVAL_UPPERBOUND_1] THEN + STRIP_TAC THEN CONV_TAC SYM_CONV THEN MATCH_MP_TAC INTEGRAL_UNIQUE THEN + MATCH_MP_TAC FUNDAMENTAL_THEOREM_OF_CALCULUS_STRONG THEN + EXISTS_TAC `s:real^1->bool` THEN ASM_REWRITE_TAC[] THEN + CONJ_TAC THENL [ASM_MESON_TAC[CONTINUOUS_ON_SUBSET]; ALL_TAC] THEN + ASM_MESON_TAC[VECTOR_DERIVATIVE_WORKS; HAS_VECTOR_DERIVATIVE_AT_WITHIN; + IN_DIFF; SUBSET]);; + +(* ------------------------------------------------------------------------- *) +(* Baby Fubini theorems for continuous functions. Will be generalized. *) +(* ------------------------------------------------------------------------- *) + +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]]]]]);; + +let INTEGRAL_SWAP_CONTINUOUS = prove + (`!f:real^M->real^N->real^P a b c d. + (\z. f (fstcart z) (sndcart z)) + continuous_on interval[pastecart a c,pastecart b d] + ==> integral (interval[a,b]) (\x. integral (interval[c,d]) (f x)) = + integral (interval[c,d]) + (\y. integral (interval[a,b]) (\x. f x y))`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`\z. (f:real^M->real^N->real^P) (fstcart z) (sndcart z)`; + `a:real^M`; `b:real^M`; `c:real^N`; `d:real^N`] + INTEGRAL_PASTECART_CONTINUOUS) THEN + ASM_REWRITE_TAC[FSTCART_PASTECART; SNDCART_PASTECART; ETA_AX] THEN + DISCH_THEN(SUBST1_TAC o SYM) THEN + MP_TAC(ISPECL [`\z. (f:real^M->real^N->real^P) (sndcart z) (fstcart z)`; + `c:real^N`; `d:real^N`; `a:real^M`; `b:real^M`] + INTEGRAL_PASTECART_CONTINUOUS) THEN + ASM_REWRITE_TAC[FSTCART_PASTECART; SNDCART_PASTECART] THEN ANTS_TAC THENL + [SUBGOAL_THEN + `(\z. (f:real^M->real^N->real^P) (sndcart z) (fstcart z)) = + (\z. (f:real^M->real^N->real^P) (fstcart z) (sndcart z)) o + (\z. pastecart (sndcart z) (fstcart z))` + SUBST1_TAC THENL + [REWRITE_TAC[o_DEF; FSTCART_PASTECART; SNDCART_PASTECART]; + ALL_TAC] THEN + MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN + SIMP_TAC[CONTINUOUS_ON_PASTECART; LINEAR_CONTINUOUS_ON; + LINEAR_FSTCART; LINEAR_SNDCART] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET)) THEN + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; PCROSS; GSYM PCROSS_INTERVAL] THEN + REWRITE_TAC[FORALL_IN_GSPEC; IN_ELIM_PASTECART_THM] THEN + SIMP_TAC[FSTCART_PASTECART; SNDCART_PASTECART]; + DISCH_THEN(SUBST1_TAC o SYM)] THEN + CONV_TAC SYM_CONV THEN MATCH_MP_TAC INTEGRAL_UNIQUE THEN + MP_TAC(ISPECL + [`\z. (f:real^M->real^N->real^P) (fstcart z) (sndcart z)`; + `\z:real^(N,M)finite_sum. pastecart (sndcart z) (fstcart z)`; + `\z:real^(M,N)finite_sum. pastecart (sndcart z) (fstcart z)`; + `&1`; + `integral (interval[pastecart a c,pastecart b d]) + (\z. (f:real^M->real^N->real^P) (fstcart z) (sndcart z))`; + `pastecart (a:real^M) (c:real^N)`; + `pastecart (b:real^M) (d:real^N)`] + HAS_INTEGRAL_TWIDDLE) THEN + REWRITE_TAC[FSTCART_PASTECART; SNDCART_PASTECART; REAL_INV_1; REAL_LT_01; + PASTECART_FST_SND; VECTOR_MUL_LID; REAL_MUL_LID] THEN + ASM_SIMP_TAC[GSYM HAS_INTEGRAL_INTEGRAL; INTEGRABLE_CONTINUOUS] THEN + REWRITE_TAC[GSYM SIMPLE_IMAGE; FORALL_PASTECART; EXISTS_PASTECART; + FSTCART_PASTECART; SNDCART_PASTECART; PCROSS; + GSYM PCROSS_INTERVAL; IN_ELIM_PASTECART_THM] THEN + REWRITE_TAC[REWRITE_RULE[PCROSS] PCROSS_INTERVAL] THEN + CONV_TAC(ONCE_DEPTH_CONV + (fun t -> if fst(dest_const(fst(strip_comb + (snd(dest_exists(snd(dest_exists t))))))) = "SETSPEC" + then REWR_CONV SWAP_EXISTS_THM t else NO_CONV t)) THEN + ONCE_REWRITE_TAC[SET_RULE + `{pastecart (y:real^M) (x:real^N) | p x /\ q y} = + {pastecart x y | q x /\ p y}`] THEN + REWRITE_TAC[REWRITE_RULE[PCROSS] PCROSS_INTERVAL] THEN + DISCH_THEN MATCH_MP_TAC THEN + SIMP_TAC[CONTINUOUS_PASTECART; LINEAR_CONTINUOUS_AT; + LINEAR_FSTCART; LINEAR_SNDCART] THEN + REWRITE_TAC[CONTENT_PASTECART] THEN + REWRITE_TAC[REAL_MUL_SYM] THEN MESON_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* Rectifiable paths and path length defined using variation. *) +(* ------------------------------------------------------------------------- *) + +let rectifiable_path = new_definition + `rectifiable_path (g:real^1->real^N) <=> + path g /\ g has_bounded_variation_on interval[vec 0,vec 1]`;; + +let path_length = new_definition + `path_length (g:real^1->real^N) = + vector_variation (interval[vec 0,vec 1]) g`;; + +let BOUNDED_RECTIFIABLE_PATH_IMAGE = prove + (`!g:real^1->real^N. rectifiable_path g ==> bounded(path_image g)`, + SIMP_TAC[rectifiable_path; BOUNDED_PATH_IMAGE]);; + +let RECTIFIABLE_PATH_IMP_PATH = prove + (`!g:real^1->real^N. rectifiable_path g ==> path g`, + SIMP_TAC[rectifiable_path]);; + +let RECTIFIABLE_PATH_LINEPATH = prove + (`!a b:real^N. rectifiable_path(linepath(a,b))`, + REPEAT GEN_TAC THEN REWRITE_TAC[rectifiable_path; PATH_LINEPATH] THEN + REWRITE_TAC[linepath] THEN + MATCH_MP_TAC HAS_BOUNDED_VARIATION_ON_ADD THEN + REWRITE_TAC[GSYM DROP_VEC; GSYM DROP_SUB] THEN + CONJ_TAC THEN MATCH_MP_TAC HAS_BOUNDED_VARIATION_ON_MUL THEN + REWRITE_TAC[HAS_BOUNDED_VARIATION_ON_CONST] THEN + REWRITE_TAC[HAS_BOUNDED_VARIATION_ON_ID] THEN + MATCH_MP_TAC HAS_BOUNDED_VARIATION_ON_SUB THEN + REWRITE_TAC[HAS_BOUNDED_VARIATION_ON_CONST] THEN + REWRITE_TAC[HAS_BOUNDED_VARIATION_ON_ID]);; + +let RECTIFIABLE_PATH_REVERSEPATH = prove + (`!g:real^1->real^N. rectifiable_path(reversepath g) <=> rectifiable_path g`, + SUBGOAL_THEN + `!g:real^1->real^N. rectifiable_path g ==> rectifiable_path(reversepath g)` + (fun th -> MESON_TAC[th; REVERSEPATH_REVERSEPATH]) THEN + GEN_TAC THEN REWRITE_TAC[rectifiable_path] THEN + MATCH_MP_TAC MONO_AND THEN REWRITE_TAC[PATH_REVERSEPATH] THEN + REWRITE_TAC[reversepath] THEN DISCH_TAC THEN + GEN_REWRITE_TAC LAND_CONV [GSYM o_DEF] THEN + MATCH_MP_TAC HAS_BOUNDED_VARIATION_COMPOSE_DECREASING THEN + ASM_REWRITE_TAC[DROP_SUB; VECTOR_SUB_RZERO; VECTOR_SUB_REFL] THEN + REAL_ARITH_TAC);; + +let PATH_LENGTH_REVERSEPATH = prove + (`!g:real^1->real^N. path_length(reversepath g) = path_length g`, + GEN_TAC THEN REWRITE_TAC[path_length; reversepath] THEN + REWRITE_TAC[VECTOR_SUB; VECTOR_VARIATION_REFLECT] THEN + REWRITE_TAC[VECTOR_VARIATION_TRANSLATION] THEN + REWRITE_TAC[REFLECT_INTERVAL; GSYM INTERVAL_TRANSLATION] THEN + REWRITE_TAC[GSYM VECTOR_SUB; VECTOR_SUB_REFL; VECTOR_SUB_RZERO]);; + +let RECTIFIABLE_PATH_SUBPATH = prove + (`!u v g:real^1->real^N. + rectifiable_path g /\ + u IN interval[vec 0,vec 1] /\ + v IN interval[vec 0,vec 1] + ==> rectifiable_path(subpath u v g)`, + REPEAT GEN_TAC THEN SIMP_TAC[PATH_SUBPATH; rectifiable_path] THEN + STRIP_TAC THEN REWRITE_TAC[subpath] THEN + ONCE_REWRITE_TAC[VECTOR_ADD_SYM] THEN + REWRITE_TAC[HAS_BOUNDED_VARIATION_AFFINITY_EQ; IMAGE_AFFINITY_INTERVAL] THEN + REWRITE_TAC[UNIT_INTERVAL_NONEMPTY; DROP_SUB; REAL_SUB_LE; REAL_SUB_0] THEN + DISJ2_TAC THEN COND_CASES_TAC THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + HAS_BOUNDED_VARIATION_ON_SUBSET)) THEN + REWRITE_TAC[SUBSET_INTERVAL_1] THEN + REWRITE_TAC[DROP_ADD; DROP_CMUL; DROP_VEC] THEN + RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1; DROP_VEC]) THEN + ASM_REAL_ARITH_TAC);; + +let RECTIFIABLE_PATH_JOIN = prove + (`!g1 g2:real^1->real^N. + pathfinish g1 = pathstart g2 + ==> (rectifiable_path(g1 ++ g2) <=> + rectifiable_path g1 /\ rectifiable_path g2)`, + REPEAT GEN_TAC THEN SIMP_TAC[rectifiable_path; PATH_JOIN] THEN + REWRITE_TAC[pathfinish; pathstart] THEN DISCH_TAC THEN + ASM_CASES_TAC `path(g1:real^1->real^N)` THEN ASM_REWRITE_TAC[] THEN + ASM_CASES_TAC `path(g2:real^1->real^N)` THEN ASM_REWRITE_TAC[] THEN + MP_TAC(ISPECL [`g1 ++ g2:real^1->real^N`; `vec 0:real^1`; `vec 1:real^1`; + `lift(&1 / &2)`] + HAS_BOUNDED_VARIATION_ON_COMBINE) THEN + REWRITE_TAC[DROP_VEC; LIFT_DROP] THEN CONV_TAC REAL_RAT_REDUCE_CONV THEN + DISCH_THEN SUBST1_TAC THEN REWRITE_TAC[joinpaths] THEN BINOP_TAC THEN + MATCH_MP_TAC EQ_TRANS THENL + [EXISTS_TAC + `(\x. (g1:real^1->real^N)(&2 % x)) has_bounded_variation_on + interval [vec 0,lift(&1 / &2)]` THEN + ONCE_REWRITE_TAC[VECTOR_ARITH `&2 % x:real^N = &2 % x + vec 0`]; + EXISTS_TAC + `(\x. (g2:real^1->real^N)(&2 % x - vec 1)) has_bounded_variation_on + interval [lift (&1 / &2),vec 1]` THEN + ONCE_REWRITE_TAC[VECTOR_ARITH `&2 % x - v:real^N = &2 % x + --v`]] THEN + (CONJ_TAC THENL + [ALL_TAC; + REWRITE_TAC[HAS_BOUNDED_VARIATION_AFFINITY_EQ] THEN + REWRITE_TAC[IMAGE_AFFINITY_INTERVAL; INTERVAL_EQ_EMPTY_1] THEN + REWRITE_TAC[DROP_VEC; LIFT_DROP] THEN CONV_TAC REAL_RAT_REDUCE_CONV THEN + AP_TERM_TAC THEN AP_TERM_TAC THEN + REWRITE_TAC[CONS_11; PAIR_EQ; GSYM DROP_EQ] THEN + REWRITE_TAC[DROP_ADD; DROP_CMUL; LIFT_DROP; DROP_VEC; DROP_NEG] THEN + REAL_ARITH_TAC]) THEN + MATCH_MP_TAC(MESON[HAS_BOUNDED_VARIATION_ON_EQ] + `(!x. x IN s ==> f x = g x) + ==> (f has_bounded_variation_on s <=> + g has_bounded_variation_on s)`) THEN + SIMP_TAC[IN_INTERVAL_1; LIFT_DROP; DROP_VEC] THEN X_GEN_TAC `x:real^1` THEN + COND_CASES_TAC THEN REWRITE_TAC[] THEN STRIP_TAC THEN + SUBGOAL_THEN `&2 % x + --vec 1:real^1 = vec 0 /\ &2 % x = vec 1` + (fun th -> ASM_REWRITE_TAC[th]) THEN + REWRITE_TAC[VECTOR_SUB_EQ; GSYM VECTOR_SUB] THEN + REWRITE_TAC[GSYM DROP_EQ; DROP_CMUL; DROP_VEC] THEN ASM_REAL_ARITH_TAC);; + +let RECTIFIABLE_PATH_JOIN_IMP = prove + (`!g1 g2:real^1->real^N. + rectifiable_path g1 /\ rectifiable_path g2 /\ + pathfinish g1 = pathstart g2 + ==> rectifiable_path(g1 ++ g2)`, + SIMP_TAC[RECTIFIABLE_PATH_JOIN]);; + +let RECTIFIABLE_PATH_JOIN_EQ = prove + (`!g1 g2:real^1->real^N. + rectifiable_path g1 /\ rectifiable_path g2 + ==> (rectifiable_path (g1 ++ g2) <=> pathfinish g1 = pathstart g2)`, + REPEAT STRIP_TAC THEN EQ_TAC THEN + ASM_SIMP_TAC[RECTIFIABLE_PATH_JOIN_IMP] THEN + DISCH_TAC THEN MATCH_MP_TAC PATH_JOIN_PATH_ENDS THEN + ASM_SIMP_TAC[RECTIFIABLE_PATH_IMP_PATH]);; + +let PATH_LENGTH_JOIN = prove + (`!g1 g2:real^1->real^N. + rectifiable_path g1 /\ rectifiable_path g2 /\ + pathfinish g1 = pathstart g2 + ==> path_length(g1 ++ g2) = path_length g1 + path_length g2`, + REPEAT STRIP_TAC THEN REWRITE_TAC[path_length] THEN + MP_TAC(ISPECL [`g1 ++ g2:real^1->real^N`; `vec 0:real^1`; `vec 1:real^1`; + `lift(&1 / &2)`] + VECTOR_VARIATION_COMBINE) THEN + REWRITE_TAC[DROP_VEC; LIFT_DROP] THEN CONV_TAC REAL_RAT_REDUCE_CONV THEN + ANTS_TAC THENL + [ASM_MESON_TAC[rectifiable_path; RECTIFIABLE_PATH_JOIN_IMP]; + DISCH_THEN(SUBST1_TAC o SYM)] THEN + MATCH_MP_TAC EQ_TRANS THEN EXISTS_TAC + `vector_variation (interval [vec 0,lift (&1 / &2)]) + (\x. (g1:real^1->real^N)(&2 % x)) + + vector_variation (interval [lift (&1 / &2),vec 1]) + (\x. (g2:real^1->real^N)(&2 % x - vec 1))` THEN + CONJ_TAC THENL + [BINOP_TAC THEN MATCH_MP_TAC VECTOR_VARIATION_EQ THEN + SIMP_TAC[IN_INTERVAL_1; LIFT_DROP; DROP_VEC; joinpaths] THEN + RULE_ASSUM_TAC(REWRITE_RULE[pathfinish; pathstart]) THEN + X_GEN_TAC `x:real^1` THEN + REWRITE_TAC[IN_INTERVAL_1; DROP_VEC; LIFT_DROP] THEN + COND_CASES_TAC THEN REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN + SUBGOAL_THEN `&2 % x - vec 1:real^1 = vec 0 /\ &2 % x = vec 1` + (fun th -> ASM_REWRITE_TAC[th]) THEN + REWRITE_TAC[VECTOR_SUB_EQ] THEN + REWRITE_TAC[GSYM DROP_EQ; DROP_CMUL; DROP_VEC] THEN ASM_REAL_ARITH_TAC; + ONCE_REWRITE_TAC[VECTOR_ARITH `&2 % x:real^N = &2 % x + vec 0`] THEN + ONCE_REWRITE_TAC[VECTOR_ARITH + `(&2 % x + vec 0) - v:real^N = &2 % x + --v`] THEN + REWRITE_TAC[VECTOR_VARIATION_AFFINITY; IMAGE_AFFINITY_INTERVAL] THEN + REWRITE_TAC[INTERVAL_EQ_EMPTY_1; LIFT_DROP; DROP_VEC] THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN BINOP_TAC THEN + AP_THM_TAC THEN AP_TERM_TAC THEN AP_TERM_TAC THEN + REWRITE_TAC[CONS_11; PAIR_EQ; GSYM DROP_EQ] THEN + REWRITE_TAC[DROP_ADD; DROP_CMUL; LIFT_DROP; DROP_VEC; DROP_NEG] THEN + REAL_ARITH_TAC]);; + +(* ------------------------------------------------------------------------- *) +(* Useful equivalent formulations where the path is differentiable. *) +(* ------------------------------------------------------------------------- *) + +let RECTIFIABLE_PATH_DIFFERENTIABLE = prove + (`!g:real^1->real^N s. + COUNTABLE s /\ path g /\ + (!t. t IN interval[vec 0,vec 1] DIFF s ==> g differentiable at t) + ==> (rectifiable_path g <=> + (\t. vector_derivative g (at t)) + absolutely_integrable_on interval[vec 0,vec 1])`, + SIMP_TAC[rectifiable_path] THEN REWRITE_TAC[path] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC + HAS_BOUNDED_VARIATION_ABSOLUTELY_INTEGRABLE_DERIVATIVE THEN + EXISTS_TAC `s:real^1->bool` THEN ASM_REWRITE_TAC[]);; + +let PATH_LENGTH_DIFFERENTIABLE = prove + (`!g:real^1->real^N s. + COUNTABLE s /\ rectifiable_path g /\ + (!t. t IN interval[vec 0,vec 1] DIFF s ==> g differentiable at t) + ==> path_length g = + drop(integral (interval[vec 0,vec 1]) + (\t. lift(norm(vector_derivative g (at t)))))`, + REWRITE_TAC[rectifiable_path; path_length; path] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC VECTOR_VARIATION_INTEGRAL_NORM_DERIVATIVE THEN + EXISTS_TAC `s:real^1->bool` THEN ASM_REWRITE_TAC[]);; diff --git a/Multivariate/make_complex.ml b/Multivariate/make_complex.ml new file mode 100644 index 0000000..4d90065 --- /dev/null +++ b/Multivariate/make_complex.ml @@ -0,0 +1,48 @@ +(* ========================================================================= *) +(* Theory of multivariate calculus in Euclidean space. *) +(* ========================================================================= *) + +loadt "Library/card.ml";; (* For countable set theorems. *) +loadt "Library/permutations.ml";; (* For determinants *) +loadt "Library/products.ml";; (* For determinants and integrals *) +loadt "Library/floor.ml";; (* Useful here and there *) +loadt "Multivariate/misc.ml";; (* Background stuff *) +loadt "Library/binomial.ml";; (* For Leibniz deriv formula etc. *) +loadt "Library/iter.ml";; (* n-fold iteration of function *) + +(* ------------------------------------------------------------------------- *) +(* The main core theory. *) +(* ------------------------------------------------------------------------- *) + +loadt "Multivariate/vectors.ml";; (* Basic vectors, linear algebra *) +loadt "Multivariate/determinants.ml";; (* Determinant and trace *) +loadt "Multivariate/topology.ml";; (* Basic topological notions *) +loadt "Multivariate/convex.ml";; (* Convex sets and functions *) +loadt "Multivariate/paths.ml";; (* Paths, simple connectedness etc. *) +loadt "Multivariate/polytope.ml";; (* Faces, polytopes, polyhedra etc. *) +loadt "Multivariate/dimension.ml";; (* Dimensional theorems *) +loadt "Multivariate/derivatives.ml";; (* Derivatives *) + +(* ------------------------------------------------------------------------- *) +(* Work in progress. *) +(* ------------------------------------------------------------------------- *) + +loadt "Multivariate/clifford.ml";; (* Geometric (Clifford) algebra *) +loadt "Multivariate/integration.ml";; (* Integration *) +loadt "Multivariate/measure.ml";; (* Lebesgue measure *) + +(* ------------------------------------------------------------------------- *) +(* Complex numbers (as R^2) and complex analysis. *) +(* ------------------------------------------------------------------------- *) + +loadt "Multivariate/complexes.ml";; (* Complex numbers *) +loadt "Multivariate/canal.ml";; (* Complex analysis *) +loadt "Multivariate/transcendentals.ml";; (* Real & complex transcendentals *) +loadt "Multivariate/realanalysis.ml";; (* Some analytical stuff on R *) +loadt "Multivariate/cauchy.ml";; (* Complex line integrals *) + +(* ------------------------------------------------------------------------- *) +(* Updated database, for convenience where dynamic updating doesn't work. *) +(* ------------------------------------------------------------------------- *) + +loadt "Multivariate/complex_database.ml";; diff --git a/Multivariate/measure.ml b/Multivariate/measure.ml new file mode 100644 index 0000000..d2a685b --- /dev/null +++ b/Multivariate/measure.ml @@ -0,0 +1,9716 @@ +(* ========================================================================= *) +(* Lebsegue measure, measurable functions (defined via the gauge integral). *) +(* *) +(* (c) Copyright, John Harrison 1998-2008 *) +(* ========================================================================= *) + +needs "Library/card.ml";; +needs "Library/permutations.ml";; +needs "Multivariate/integration.ml";; +needs "Multivariate/determinants.ml";; +prioritize_real();; + +(* ------------------------------------------------------------------------- *) +(* Lebesgue measure in the case where the measure is finite. This is our *) +(* default notion of "measurable", but we also define "lebesgue_measurable" *) +(* further down. Note that in neither case do we assume the set is bounded. *) +(* ------------------------------------------------------------------------- *) + +parse_as_infix("has_measure",(12,"right"));; + +let has_measure = new_definition + `s has_measure m <=> ((\x. vec 1) has_integral (lift m)) s`;; + +let measurable = new_definition + `measurable s <=> ?m. s has_measure m`;; + +let measure = new_definition + `measure s = @m. s has_measure m`;; + +let HAS_MEASURE_MEASURE = prove + (`!s. measurable s <=> s has_measure (measure s)`, + REWRITE_TAC[measure; measurable] THEN MESON_TAC[]);; + +let HAS_MEASURE_UNIQUE = prove + (`!s m1 m2. s has_measure m1 /\ s has_measure m2 ==> m1 = m2`, + REWRITE_TAC[has_measure; GSYM LIFT_EQ] THEN MESON_TAC[HAS_INTEGRAL_UNIQUE]);; + +let MEASURE_UNIQUE = prove + (`!s m. s has_measure m ==> measure s = m`, + MESON_TAC[HAS_MEASURE_UNIQUE; HAS_MEASURE_MEASURE; measurable]);; + +let HAS_MEASURE_MEASURABLE_MEASURE = prove + (`!s m. s has_measure m <=> measurable s /\ measure s = m`, + REWRITE_TAC[HAS_MEASURE_MEASURE] THEN MESON_TAC[MEASURE_UNIQUE]);; + +let HAS_MEASURE_IMP_MEASURABLE = prove + (`!s m. s has_measure m ==> measurable s`, + REWRITE_TAC[measurable] THEN MESON_TAC[]);; + +let HAS_MEASURE = prove + (`!s m. s has_measure m <=> + ((\x. if x IN s then vec 1 else vec 0) has_integral (lift m)) + (:real^N)`, + SIMP_TAC[HAS_INTEGRAL_RESTRICT_UNIV; has_measure]);; + +let MEASURABLE = prove + (`!s. measurable s <=> (\x. vec 1:real^1) integrable_on s`, + REWRITE_TAC[measurable; integrable_on; + has_measure; EXISTS_DROP; LIFT_DROP]);; + +let MEASURABLE_INTEGRABLE = prove + (`measurable s <=> + (\x. if x IN s then vec 1 else vec 0:real^1) integrable_on UNIV`, + REWRITE_TAC[measurable; integrable_on; + HAS_MEASURE; EXISTS_DROP; LIFT_DROP]);; + +let MEASURE_INTEGRAL = prove + (`!s. measurable s ==> measure s = drop (integral s (\x. vec 1))`, + REPEAT STRIP_TAC THEN CONV_TAC SYM_CONV THEN + REWRITE_TAC[GSYM LIFT_EQ; LIFT_DROP] THEN + MATCH_MP_TAC INTEGRAL_UNIQUE THEN + ASM_REWRITE_TAC[GSYM has_measure; GSYM HAS_MEASURE_MEASURE]);; + +let MEASURE_INTEGRAL_UNIV = prove + (`!s. measurable s + ==> measure s = + drop(integral UNIV (\x. if x IN s then vec 1 else vec 0))`, + REPEAT STRIP_TAC THEN CONV_TAC SYM_CONV THEN + REWRITE_TAC[GSYM LIFT_EQ; LIFT_DROP] THEN + MATCH_MP_TAC INTEGRAL_UNIQUE THEN + ASM_REWRITE_TAC[GSYM HAS_MEASURE; GSYM HAS_MEASURE_MEASURE]);; + +let INTEGRAL_MEASURE = prove + (`!s. measurable s ==> integral s (\x. vec 1) = lift(measure s)`, + SIMP_TAC[GSYM DROP_EQ; LIFT_DROP; MEASURE_INTEGRAL]);; + +let INTEGRAL_MEASURE_UNIV = prove + (`!s. measurable s + ==> integral UNIV (\x. if x IN s then vec 1 else vec 0) = + lift(measure s)`, + SIMP_TAC[GSYM DROP_EQ; LIFT_DROP; MEASURE_INTEGRAL_UNIV]);; + +let HAS_MEASURE_INTERVAL = prove + (`(!a b:real^N. interval[a,b] has_measure content(interval[a,b])) /\ + (!a b:real^N. interval(a,b) has_measure content(interval[a,b]))`, + MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN CONJ_TAC THENL + [REWRITE_TAC[has_measure] THEN + ONCE_REWRITE_TAC[LIFT_EQ_CMUL] THEN REWRITE_TAC[HAS_INTEGRAL_CONST]; + ALL_TAC] THEN + REPEAT(MATCH_MP_TAC MONO_FORALL THEN GEN_TAC) THEN SIMP_TAC[HAS_MEASURE] THEN + MATCH_MP_TAC(REWRITE_RULE[TAUT `a /\ b /\ c ==> d <=> a /\ b ==> c ==> d`] + HAS_INTEGRAL_SPIKE) THEN + EXISTS_TAC `interval[a:real^N,b] DIFF interval(a,b)` THEN + REWRITE_TAC[NEGLIGIBLE_FRONTIER_INTERVAL] THEN + MP_TAC(ISPECL [`a:real^N`; `b:real^N`] INTERVAL_OPEN_SUBSET_CLOSED) THEN + SET_TAC[]);; + +let MEASURABLE_INTERVAL = prove + (`(!a b:real^N. measurable (interval[a,b])) /\ + (!a b:real^N. measurable (interval(a,b)))`, + REWRITE_TAC[measurable] THEN MESON_TAC[HAS_MEASURE_INTERVAL]);; + +let MEASURE_INTERVAL = prove + (`(!a b:real^N. measure(interval[a,b]) = content(interval[a,b])) /\ + (!a b:real^N. measure(interval(a,b)) = content(interval[a,b]))`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC MEASURE_UNIQUE THEN + REWRITE_TAC[HAS_MEASURE_INTERVAL]);; + +let MEASURE_INTERVAL_1 = prove + (`(!a b:real^1. measure(interval[a,b]) = + if drop a <= drop b then drop b - drop a else &0) /\ + (!a b:real^1. measure(interval(a,b)) = + if drop a <= drop b then drop b - drop a else &0)`, + REWRITE_TAC[MEASURE_INTERVAL; CONTENT_CLOSED_INTERVAL_CASES] THEN + REWRITE_TAC[DIMINDEX_1; FORALL_1; PRODUCT_1; drop]);; + +let MEASURE_INTERVAL_1_ALT = prove + (`(!a b:real^1. measure(interval[a,b]) = + if drop a < drop b then drop b - drop a else &0) /\ + (!a b:real^1. measure(interval(a,b)) = + if drop a < drop b then drop b - drop a else &0)`, + REWRITE_TAC[MEASURE_INTERVAL_1] THEN REAL_ARITH_TAC);; + +let MEASURE_INTERVAL_2 = prove + (`(!a b:real^2. measure(interval[a,b]) = + if a$1 <= b$1 /\ a$2 <= b$2 + then (b$1 - a$1) * (b$2 - a$2) + else &0) /\ + (!a b:real^2. measure(interval(a,b)) = + if a$1 <= b$1 /\ a$2 <= b$2 + then (b$1 - a$1) * (b$2 - a$2) + else &0)`, + REWRITE_TAC[MEASURE_INTERVAL; CONTENT_CLOSED_INTERVAL_CASES] THEN + REWRITE_TAC[DIMINDEX_2; FORALL_2; PRODUCT_2]);; + +let MEASURE_INTERVAL_2_ALT = prove + (`(!a b:real^2. measure(interval[a,b]) = + if a$1 < b$1 /\ a$2 < b$2 + then (b$1 - a$1) * (b$2 - a$2) + else &0) /\ + (!a b:real^2. measure(interval(a,b)) = + if a$1 < b$1 /\ a$2 < b$2 + then (b$1 - a$1) * (b$2 - a$2) + else &0)`, + REWRITE_TAC[MEASURE_INTERVAL_2] THEN REPEAT GEN_TAC THEN + MAP_EVERY ASM_CASES_TAC + [`(a:real^2)$1 = (b:real^2)$1`; `(a:real^2)$2 = (b:real^2)$2`] THEN + ASM_REWRITE_TAC[REAL_LT_REFL; REAL_MUL_LZERO; REAL_MUL_RZERO; + REAL_SUB_REFL; REAL_LE_REFL; REAL_ABS_NUM; COND_ID] THEN + ASM_REWRITE_TAC[REAL_LT_LE]);; + +let MEASURE_INTERVAL_3 = prove + (`(!a b:real^3. measure(interval[a,b]) = + if a$1 <= b$1 /\ a$2 <= b$2 /\ a$3 <= b$3 + then (b$1 - a$1) * (b$2 - a$2) * (b$3 - a$3) + else &0) /\ + (!a b:real^3. measure(interval(a,b)) = + if a$1 <= b$1 /\ a$2 <= b$2 /\ a$3 <= b$3 + then (b$1 - a$1) * (b$2 - a$2) * (b$3 - a$3) + else &0)`, + REWRITE_TAC[MEASURE_INTERVAL; CONTENT_CLOSED_INTERVAL_CASES] THEN + REWRITE_TAC[DIMINDEX_3; FORALL_3; PRODUCT_3]);; + +let MEASURE_INTERVAL_3_ALT = prove + (`(!a b:real^3. measure(interval[a,b]) = + if a$1 < b$1 /\ a$2 < b$2 /\ a$3 < b$3 + then (b$1 - a$1) * (b$2 - a$2) * (b$3 - a$3) + else &0) /\ + (!a b:real^3. measure(interval(a,b)) = + if a$1 < b$1 /\ a$2 < b$2 /\ a$3 < b$3 + then (b$1 - a$1) * (b$2 - a$2) * (b$3 - a$3) + else &0)`, + REWRITE_TAC[MEASURE_INTERVAL_3] THEN REPEAT GEN_TAC THEN + MAP_EVERY ASM_CASES_TAC + [`(a:real^3)$1 = (b:real^3)$1`; + `(a:real^3)$2 = (b:real^3)$2`; + `(a:real^3)$3 = (b:real^3)$3`] THEN + ASM_REWRITE_TAC[REAL_LT_REFL; REAL_MUL_LZERO; REAL_MUL_RZERO; + REAL_SUB_REFL; REAL_LE_REFL; REAL_ABS_NUM; COND_ID] THEN + ASM_REWRITE_TAC[REAL_LT_LE]);; + +let MEASURE_INTERVAL_4 = prove + (`(!a b:real^4. measure(interval[a,b]) = + if a$1 <= b$1 /\ a$2 <= b$2 /\ a$3 <= b$3 /\ a$4 <= b$4 + then (b$1 - a$1) * (b$2 - a$2) * (b$3 - a$3) * (b$4 - a$4) + else &0) /\ + (!a b:real^4. measure(interval(a,b)) = + if a$1 <= b$1 /\ a$2 <= b$2 /\ a$3 <= b$3 /\ a$4 <= b$4 + then (b$1 - a$1) * (b$2 - a$2) * (b$3 - a$3) * (b$4 - a$4) + else &0)`, + REWRITE_TAC[MEASURE_INTERVAL; CONTENT_CLOSED_INTERVAL_CASES] THEN + REWRITE_TAC[DIMINDEX_4; FORALL_4; PRODUCT_4]);; + +let MEASURE_INTERVAL_4_ALT = prove + (`(!a b:real^4. measure(interval[a,b]) = + if a$1 < b$1 /\ a$2 < b$2 /\ a$3 < b$3 /\ a$4 < b$4 + then (b$1 - a$1) * (b$2 - a$2) * (b$3 - a$3) * (b$4 - a$4) + else &0) /\ + (!a b:real^4. measure(interval(a,b)) = + if a$1 < b$1 /\ a$2 < b$2 /\ a$3 < b$3 /\ a$4 < b$4 + then (b$1 - a$1) * (b$2 - a$2) * (b$3 - a$3) * (b$4 - a$4) + else &0)`, + REWRITE_TAC[MEASURE_INTERVAL_4] THEN REPEAT GEN_TAC THEN + MAP_EVERY ASM_CASES_TAC + [`(a:real^4)$1 = (b:real^4)$1`; + `(a:real^4)$2 = (b:real^4)$2`; + `(a:real^4)$3 = (b:real^4)$3`; + `(a:real^4)$4 = (b:real^4)$4`] THEN + ASM_REWRITE_TAC[REAL_LT_REFL; REAL_MUL_LZERO; REAL_MUL_RZERO; + REAL_SUB_REFL; REAL_LE_REFL; REAL_ABS_NUM; COND_ID] THEN + ASM_REWRITE_TAC[REAL_LT_LE]);; + +let MEASURABLE_INTER = prove + (`!s t:real^N->bool. measurable s /\ measurable t ==> measurable (s INTER t)`, + REWRITE_TAC[MEASURABLE_INTEGRABLE] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_IMP_INTEGRABLE THEN + SUBGOAL_THEN + `(\x. if x IN s INTER t then vec 1 else vec 0):real^N->real^1 = + (\x. lambda i. min (((if x IN s then vec 1 else vec 0):real^1)$i) + (((if x IN t then vec 1 else vec 0):real^1)$i))` + SUBST1_TAC THENL + [SIMP_TAC[FUN_EQ_THM; CART_EQ; LAMBDA_BETA] THEN + X_GEN_TAC `x:real^N` THEN REPEAT STRIP_TAC THEN + MAP_EVERY ASM_CASES_TAC [`(x:real^N) IN s`; `(x:real^N) IN t`] THEN + ASM_SIMP_TAC[IN_INTER; VEC_COMPONENT] THEN REAL_ARITH_TAC; + ALL_TAC] THEN + MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_MIN THEN + CONJ_TAC THEN MATCH_MP_TAC NONNEGATIVE_ABSOLUTELY_INTEGRABLE THEN + ASM_SIMP_TAC[] THEN REPEAT STRIP_TAC THEN + COND_CASES_TAC THEN ASM_SIMP_TAC[VEC_COMPONENT; REAL_POS]);; + +let MEASURABLE_UNION = prove + (`!s t:real^N->bool. measurable s /\ measurable t ==> measurable (s UNION t)`, + REWRITE_TAC[MEASURABLE_INTEGRABLE] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_IMP_INTEGRABLE THEN + SUBGOAL_THEN + `(\x. if x IN s UNION t then vec 1 else vec 0):real^N->real^1 = + (\x. lambda i. max (((if x IN s then vec 1 else vec 0):real^1)$i) + (((if x IN t then vec 1 else vec 0):real^1)$i))` + SUBST1_TAC THENL + [SIMP_TAC[FUN_EQ_THM; CART_EQ; LAMBDA_BETA] THEN + X_GEN_TAC `x:real^N` THEN REPEAT STRIP_TAC THEN + MAP_EVERY ASM_CASES_TAC [`(x:real^N) IN s`; `(x:real^N) IN t`] THEN + ASM_SIMP_TAC[IN_UNION; VEC_COMPONENT] THEN REAL_ARITH_TAC; + ALL_TAC] THEN + MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_MAX THEN + CONJ_TAC THEN MATCH_MP_TAC NONNEGATIVE_ABSOLUTELY_INTEGRABLE THEN + ASM_SIMP_TAC[] THEN REPEAT STRIP_TAC THEN + COND_CASES_TAC THEN ASM_SIMP_TAC[VEC_COMPONENT; REAL_POS]);; + +let HAS_MEASURE_DISJOINT_UNION = prove + (`!s1 s2 m1 m2. s1 has_measure m1 /\ s2 has_measure m2 /\ DISJOINT s1 s2 + ==> (s1 UNION s2) has_measure (m1 + m2)`, + REPEAT GEN_TAC THEN REWRITE_TAC[HAS_MEASURE; CONJ_ASSOC] THEN + DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN + DISCH_THEN(MP_TAC o MATCH_MP HAS_INTEGRAL_ADD) THEN + REWRITE_TAC[LIFT_ADD] THEN MATCH_MP_TAC EQ_IMP THEN + AP_THM_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN + REWRITE_TAC[FUN_EQ_THM] THEN GEN_TAC THEN + REPEAT(COND_CASES_TAC THEN REWRITE_TAC[VECTOR_ADD_LID; VECTOR_ADD_RID]) THEN + ASM SET_TAC[]);; + +let MEASURE_DISJOINT_UNION = prove + (`!s t. measurable s /\ measurable t /\ DISJOINT s t + ==> measure(s UNION t) = measure s + measure t`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC MEASURE_UNIQUE THEN + ASM_SIMP_TAC[HAS_MEASURE_DISJOINT_UNION; GSYM HAS_MEASURE_MEASURE]);; + +let MEASURE_DISJOINT_UNION_EQ = prove + (`!s t u. + measurable s /\ measurable t /\ s UNION t = u /\ DISJOINT s t + ==> measure s + measure t = measure u`, + MESON_TAC[MEASURE_DISJOINT_UNION]);; + +let HAS_MEASURE_POS_LE = prove + (`!m s:real^N->bool. s has_measure m ==> &0 <= m`, + REWRITE_TAC[HAS_MEASURE] THEN REPEAT STRIP_TAC THEN + GEN_REWRITE_TAC RAND_CONV [GSYM(CONJUNCT2 LIFT_DROP)] THEN + REWRITE_TAC[drop] THEN MATCH_MP_TAC(ISPEC + `(\x. if x IN s then vec 1 else vec 0):real^N->real^1` + HAS_INTEGRAL_COMPONENT_POS) THEN + EXISTS_TAC `(:real^N)` THEN ASM_REWRITE_TAC[DIMINDEX_1; ARITH; IN_UNIV] THEN + GEN_TAC THEN COND_CASES_TAC THEN + REWRITE_TAC[GSYM drop; DROP_VEC; REAL_POS]);; + +let MEASURE_POS_LE = prove + (`!s. measurable s ==> &0 <= measure s`, + REWRITE_TAC[HAS_MEASURE_MEASURE; HAS_MEASURE_POS_LE]);; + +let HAS_MEASURE_SUBSET = prove + (`!s1 s2:real^N->bool m1 m2. + s1 has_measure m1 /\ s2 has_measure m2 /\ s1 SUBSET s2 + ==> m1 <= m2`, + REPEAT GEN_TAC THEN REWRITE_TAC[has_measure] THEN STRIP_TAC THEN + GEN_REWRITE_TAC BINOP_CONV [GSYM(CONJUNCT2 LIFT_DROP)] THEN + MATCH_MP_TAC(ISPEC `(\x. vec 1):real^N->real^1` + HAS_INTEGRAL_SUBSET_DROP_LE) THEN + MAP_EVERY EXISTS_TAC [`s1:real^N->bool`; `s2:real^N->bool`] THEN + ASM_REWRITE_TAC[DROP_VEC; REAL_POS]);; + +let MEASURE_SUBSET = prove + (`!s t. measurable s /\ measurable t /\ s SUBSET t + ==> measure s <= measure t`, + REWRITE_TAC[HAS_MEASURE_MEASURE] THEN MESON_TAC[HAS_MEASURE_SUBSET]);; + +let HAS_MEASURE_0 = prove + (`!s:real^N->bool. s has_measure &0 <=> negligible s`, + GEN_TAC THEN EQ_TAC THENL + [ALL_TAC; + REWRITE_TAC[NEGLIGIBLE; has_measure] THEN + DISCH_THEN(MP_TAC o SPEC `(:real^N)`) THEN + ONCE_REWRITE_TAC[GSYM HAS_INTEGRAL_RESTRICT_UNIV] THEN + REWRITE_TAC[IN_UNIV; indicator; LIFT_NUM]] THEN + REWRITE_TAC[negligible] THEN REWRITE_TAC[has_measure] THEN + ONCE_REWRITE_TAC[GSYM HAS_INTEGRAL_RESTRICT_UNIV] THEN + REWRITE_TAC[LIFT_NUM] THEN DISCH_TAC THEN + FIRST_ASSUM(MP_TAC o CONJUNCT1 o GEN_REWRITE_RULE I [HAS_INTEGRAL_ALT]) THEN + REPEAT(MATCH_MP_TAC MONO_FORALL THEN GEN_TAC) THEN + REWRITE_TAC[integrable_on; IN_UNIV] THEN + GEN_REWRITE_TAC (LAND_CONV o BINDER_CONV) + [GSYM HAS_INTEGRAL_RESTRICT_UNIV] THEN + REWRITE_TAC[indicator] THEN DISCH_THEN(X_CHOOSE_TAC `y:real^1`) THEN + SUBGOAL_THEN `y:real^1 = vec 0` (fun th -> ASM_MESON_TAC[th]) THEN + REWRITE_TAC[GSYM DROP_EQ; GSYM REAL_LE_ANTISYM] THEN CONJ_TAC THENL + [MATCH_MP_TAC(ISPEC + `(\x. if x IN interval [a,b] + then if x IN s then vec 1 else vec 0 else vec 0):real^N->real^1` + HAS_INTEGRAL_DROP_LE) THEN + EXISTS_TAC `(\x. if x IN s then vec 1 else vec 0):real^N->real^1`; + REWRITE_TAC[DROP_VEC] THEN MATCH_MP_TAC(ISPEC + `(\x. if x IN interval [a,b] + then if x IN s then vec 1 else vec 0 else vec 0):real^N->real^1` + HAS_INTEGRAL_DROP_POS)] THEN + EXISTS_TAC `(:real^N)` THEN ASM_REWRITE_TAC[] THEN + REPEAT STRIP_TAC THEN REPEAT(COND_CASES_TAC THEN ASM_REWRITE_TAC[]) THEN + REWRITE_TAC[DROP_VEC; REAL_POS; REAL_LE_REFL]);; + +let MEASURE_EQ_0 = prove + (`!s. negligible s ==> measure s = &0`, + MESON_TAC[MEASURE_UNIQUE; HAS_MEASURE_0]);; + +let NEGLIGIBLE_IMP_MEASURABLE = prove + (`!s:real^N->bool. negligible s ==> measurable s`, + MESON_TAC[HAS_MEASURE_0; measurable]);; + +let HAS_MEASURE_EMPTY = prove + (`{} has_measure &0`, + REWRITE_TAC[HAS_MEASURE_0; NEGLIGIBLE_EMPTY]);; + +let MEASURE_EMPTY = prove + (`measure {} = &0`, + SIMP_TAC[MEASURE_EQ_0; NEGLIGIBLE_EMPTY]);; + +let MEASURABLE_EMPTY = prove + (`measurable {}`, + REWRITE_TAC[measurable] THEN MESON_TAC[HAS_MEASURE_EMPTY]);; + +let MEASURABLE_MEASURE_EQ_0 = prove + (`!s. measurable s ==> (measure s = &0 <=> negligible s)`, + REWRITE_TAC[HAS_MEASURE_MEASURE; GSYM HAS_MEASURE_0] THEN + MESON_TAC[MEASURE_UNIQUE]);; + +let NEGLIGIBLE_EQ_MEASURE_0 = prove + (`!s:real^N->bool. + negligible s <=> measurable s /\ measure s = &0`, + MESON_TAC[NEGLIGIBLE_IMP_MEASURABLE; MEASURABLE_MEASURE_EQ_0]);; + +let MEASURABLE_MEASURE_POS_LT = prove + (`!s. measurable s ==> (&0 < measure s <=> ~negligible s)`, + SIMP_TAC[REAL_LT_LE; MEASURE_POS_LE; GSYM MEASURABLE_MEASURE_EQ_0] THEN + REWRITE_TAC[EQ_SYM_EQ]);; + +let NEGLIGIBLE_INTERVAL = prove + (`(!a b. negligible(interval[a,b]) <=> interval(a,b) = {}) /\ + (!a b. negligible(interval(a,b)) <=> interval(a,b) = {})`, + REWRITE_TAC[GSYM HAS_MEASURE_0] THEN + MESON_TAC[HAS_MEASURE_INTERVAL; CONTENT_EQ_0_INTERIOR; + INTERIOR_CLOSED_INTERVAL; HAS_MEASURE_UNIQUE]);; + +let MEASURABLE_UNIONS = prove + (`!f:(real^N->bool)->bool. + FINITE f /\ (!s. s IN f ==> measurable s) + ==> measurable (UNIONS f)`, + REWRITE_TAC[IMP_CONJ] THEN + MATCH_MP_TAC FINITE_INDUCT_STRONG THEN + SIMP_TAC[UNIONS_0; UNIONS_INSERT; MEASURABLE_EMPTY] THEN + REWRITE_TAC[IN_INSERT] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC MEASURABLE_UNION THEN ASM_SIMP_TAC[]);; + +let HAS_MEASURE_DIFF_SUBSET = prove + (`!s1 s2 m1 m2. s1 has_measure m1 /\ s2 has_measure m2 /\ s2 SUBSET s1 + ==> (s1 DIFF s2) has_measure (m1 - m2)`, + REPEAT GEN_TAC THEN REWRITE_TAC[HAS_MEASURE; CONJ_ASSOC] THEN + DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN + DISCH_THEN(MP_TAC o MATCH_MP HAS_INTEGRAL_SUB) THEN + REWRITE_TAC[LIFT_SUB] THEN MATCH_MP_TAC EQ_IMP THEN + AP_THM_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN + REWRITE_TAC[FUN_EQ_THM] THEN GEN_TAC THEN + REPEAT(COND_CASES_TAC THEN ASM_REWRITE_TAC[]) THEN + REWRITE_TAC[VECTOR_SUB_REFL; VECTOR_SUB_RZERO] THEN + ASM SET_TAC[]);; + +let MEASURABLE_DIFF = prove + (`!s t:real^N->bool. measurable s /\ measurable t ==> measurable (s DIFF t)`, + SUBGOAL_THEN + `!s t:real^N->bool. measurable s /\ measurable t /\ t SUBSET s + ==> measurable (s DIFF t)` + ASSUME_TAC THENL + [REWRITE_TAC[measurable] THEN MESON_TAC[HAS_MEASURE_DIFF_SUBSET]; + ONCE_REWRITE_TAC[SET_RULE `s DIFF t = s DIFF (s INTER t)`] THEN + REPEAT STRIP_TAC THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_SIMP_TAC[MEASURABLE_INTER] THEN + SET_TAC[]]);; + +let MEASURE_DIFF_SUBSET = prove + (`!s t. measurable s /\ measurable t /\ t SUBSET s + ==> measure(s DIFF t) = measure s - measure t`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC MEASURE_UNIQUE THEN + ASM_SIMP_TAC[HAS_MEASURE_DIFF_SUBSET; GSYM HAS_MEASURE_MEASURE]);; + +let HAS_MEASURE_UNION_NEGLIGIBLE = prove + (`!s t:real^N->bool m. + s has_measure m /\ negligible t ==> (s UNION t) has_measure m`, + REWRITE_TAC[HAS_MEASURE] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC HAS_INTEGRAL_SPIKE THEN + MAP_EVERY EXISTS_TAC + [`(\x. if x IN s then vec 1 else vec 0):real^N->real^1`; + `t:real^N->bool`] THEN + ASM_SIMP_TAC[IN_DIFF; IN_UNIV; IN_UNION]);; + +let HAS_MEASURE_DIFF_NEGLIGIBLE = prove + (`!s t:real^N->bool m. + s has_measure m /\ negligible t ==> (s DIFF t) has_measure m`, + REWRITE_TAC[HAS_MEASURE] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC HAS_INTEGRAL_SPIKE THEN + MAP_EVERY EXISTS_TAC + [`(\x. if x IN s then vec 1 else vec 0):real^N->real^1`; + `t:real^N->bool`] THEN + ASM_SIMP_TAC[IN_DIFF; IN_UNIV; IN_UNION]);; + +let HAS_MEASURE_UNION_NEGLIGIBLE_EQ = prove + (`!s t:real^N->bool m. + negligible t ==> ((s UNION t) has_measure m <=> s has_measure m)`, + REPEAT STRIP_TAC THEN EQ_TAC THEN DISCH_TAC THEN + ASM_SIMP_TAC[HAS_MEASURE_UNION_NEGLIGIBLE] THEN + SUBST1_TAC(SET_RULE `s:real^N->bool = (s UNION t) DIFF (t DIFF s)`) THEN + MATCH_MP_TAC HAS_MEASURE_DIFF_NEGLIGIBLE THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC NEGLIGIBLE_DIFF THEN ASM_REWRITE_TAC[]);; + +let HAS_MEASURE_DIFF_NEGLIGIBLE_EQ = prove + (`!s t:real^N->bool m. + negligible t ==> ((s DIFF t) has_measure m <=> s has_measure m)`, + REPEAT STRIP_TAC THEN EQ_TAC THEN DISCH_TAC THEN + ASM_SIMP_TAC[HAS_MEASURE_DIFF_NEGLIGIBLE] THEN + SUBST1_TAC(SET_RULE `s:real^N->bool = (s DIFF t) UNION (t INTER s)`) THEN + MATCH_MP_TAC HAS_MEASURE_UNION_NEGLIGIBLE THEN + ASM_SIMP_TAC[NEGLIGIBLE_INTER]);; + +let HAS_MEASURE_ALMOST = prove + (`!s s' t m. s has_measure m /\ negligible t /\ s UNION t = s' UNION t + ==> s' has_measure m`, + REPEAT STRIP_TAC THEN FIRST_X_ASSUM(SUBST1_TAC o MATCH_MP (SET_RULE + `s UNION t = s' UNION t ==> s' = (s UNION t) DIFF (t DIFF s')`)) THEN + ASM_SIMP_TAC[HAS_MEASURE_DIFF_NEGLIGIBLE; HAS_MEASURE_UNION_NEGLIGIBLE; + NEGLIGIBLE_DIFF]);; + +let HAS_MEASURE_ALMOST_EQ = prove + (`!s s' t. negligible t /\ s UNION t = s' UNION t + ==> (s has_measure m <=> s' has_measure m)`, + MESON_TAC[HAS_MEASURE_ALMOST]);; + +let MEASURABLE_ALMOST = prove + (`!s s' t. measurable s /\ negligible t /\ s UNION t = s' UNION t + ==> measurable s'`, + REWRITE_TAC[measurable] THEN MESON_TAC[HAS_MEASURE_ALMOST]);; + +let HAS_MEASURE_NEGLIGIBLE_UNION = prove + (`!s1 s2:real^N->bool m1 m2. + s1 has_measure m1 /\ s2 has_measure m2 /\ negligible(s1 INTER s2) + ==> (s1 UNION s2) has_measure (m1 + m2)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_MEASURE_ALMOST THEN + MAP_EVERY EXISTS_TAC + [`(s1 DIFF (s1 INTER s2)) UNION (s2 DIFF (s1 INTER s2)):real^N->bool`; + `s1 INTER s2:real^N->bool`] THEN + ASM_REWRITE_TAC[] THEN CONJ_TAC THENL + [ALL_TAC; SET_TAC[]] THEN + MATCH_MP_TAC HAS_MEASURE_DISJOINT_UNION THEN REPEAT CONJ_TAC THENL + [MATCH_MP_TAC HAS_MEASURE_ALMOST THEN EXISTS_TAC `s1:real^N->bool`; + MATCH_MP_TAC HAS_MEASURE_ALMOST THEN EXISTS_TAC `s2:real^N->bool`; + SET_TAC[]] THEN + EXISTS_TAC `s1 INTER s2:real^N->bool` THEN + ASM_REWRITE_TAC[] THEN SET_TAC[]);; + +let MEASURE_NEGLIGIBLE_UNION = prove + (`!s t. measurable s /\ measurable t /\ negligible(s INTER t) + ==> measure(s UNION t) = measure s + measure t`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC MEASURE_UNIQUE THEN + ASM_SIMP_TAC[HAS_MEASURE_NEGLIGIBLE_UNION; GSYM HAS_MEASURE_MEASURE]);; + +let MEASURE_NEGLIGIBLE_UNION_EQ = prove + (`!s t u. + measurable s /\ measurable t /\ s UNION t = u /\ negligible(s INTER t) + ==> measure s + measure t = measure u`, + MESON_TAC[MEASURE_NEGLIGIBLE_UNION]);; + +let HAS_MEASURE_NEGLIGIBLE_SYMDIFF = prove + (`!s t:real^N->bool m. + s has_measure m /\ + negligible((s DIFF t) UNION (t DIFF s)) + ==> t has_measure m`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_MEASURE_ALMOST THEN + MAP_EVERY EXISTS_TAC + [`s:real^N->bool`; `(s DIFF t) UNION (t DIFF s):real^N->bool`] THEN + ASM_REWRITE_TAC[] THEN SET_TAC[]);; + +let MEASURABLE_NEGLIGIBLE_SYMDIFF = prove + (`!s t:real^N->bool. + measurable s /\ negligible((s DIFF t) UNION (t DIFF s)) + ==> measurable t`, + REWRITE_TAC[measurable] THEN + MESON_TAC[HAS_MEASURE_NEGLIGIBLE_SYMDIFF]);; + +let MEASURABLE_NEGLIGIBLE_SYMDIFF_EQ = prove + (`!s t:real^N->bool. + negligible(s DIFF t UNION t DIFF s) + ==> (measurable s <=> measurable t)`, + MESON_TAC[MEASURABLE_NEGLIGIBLE_SYMDIFF; UNION_COMM]);; + +let MEASURE_NEGLIGIBLE_SYMDIFF = prove + (`!s t:real^N->bool. + negligible(s DIFF t UNION t DIFF s) ==> measure s = measure t`, + REPEAT STRIP_TAC THEN MAP_EVERY ASM_CASES_TAC + [`measurable(s:real^N->bool)`; `measurable(t:real^N->bool)`] + THENL + [ASM_MESON_TAC[HAS_MEASURE_NEGLIGIBLE_SYMDIFF; MEASURE_UNIQUE; + HAS_MEASURE_MEASURE]; + ASM_MESON_TAC[MEASURABLE_NEGLIGIBLE_SYMDIFF_EQ]; + ASM_MESON_TAC[MEASURABLE_NEGLIGIBLE_SYMDIFF_EQ]; + REWRITE_TAC[measure] THEN AP_TERM_TAC THEN ABS_TAC THEN + ASM_MESON_TAC[measurable]]);; + +let NEGLIGIBLE_SYMDIFF_EQ = prove + (`!s t:real^N->bool. + negligible (s DIFF t UNION t DIFF s) + ==> (negligible s <=> negligible t)`, + REPEAT STRIP_TAC THEN EQ_TAC THEN POP_ASSUM MP_TAC THEN + REWRITE_TAC[IMP_IMP; GSYM NEGLIGIBLE_UNION_EQ] THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] NEGLIGIBLE_SUBSET) THEN + SET_TAC[]);; + +let NEGLIGIBLE_DELETE = prove + (`!a:real^N. negligible(s DELETE a) <=> negligible s`, + GEN_TAC THEN MATCH_MP_TAC NEGLIGIBLE_SYMDIFF_EQ THEN + MATCH_MP_TAC NEGLIGIBLE_SUBSET THEN + EXISTS_TAC `{a:real^N}` THEN REWRITE_TAC[NEGLIGIBLE_SING] THEN SET_TAC[]);; + +let HAS_MEASURE_NEGLIGIBLE_UNIONS = prove + (`!m f:(real^N->bool)->bool. + FINITE f /\ + (!s. s IN f ==> s has_measure (m s)) /\ + (!s t. s IN f /\ t IN f /\ ~(s = t) ==> negligible(s INTER t)) + ==> (UNIONS f) has_measure (sum f m)`, + GEN_TAC THEN ONCE_REWRITE_TAC[IMP_CONJ] THEN + MATCH_MP_TAC FINITE_INDUCT_STRONG THEN + SIMP_TAC[SUM_CLAUSES; UNIONS_0; UNIONS_INSERT; HAS_MEASURE_EMPTY] THEN + REWRITE_TAC[IN_INSERT] THEN + MAP_EVERY X_GEN_TAC [`s:real^N->bool`; `f:(real^N->bool)->bool`] THEN + STRIP_TAC THEN STRIP_TAC THEN MATCH_MP_TAC HAS_MEASURE_NEGLIGIBLE_UNION THEN + REPEAT(CONJ_TAC THENL [ASM_MESON_TAC[]; ALL_TAC]) THEN + REWRITE_TAC[INTER_UNIONS] THEN MATCH_MP_TAC NEGLIGIBLE_UNIONS THEN + ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN + ASM_SIMP_TAC[FINITE_IMAGE; FORALL_IN_IMAGE] THEN REPEAT STRIP_TAC THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_MESON_TAC[]);; + +let MEASURE_NEGLIGIBLE_UNIONS = prove + (`!m f:(real^N->bool)->bool. + FINITE f /\ + (!s. s IN f ==> s has_measure (m s)) /\ + (!s t. s IN f /\ t IN f /\ ~(s = t) ==> negligible(s INTER t)) + ==> measure(UNIONS f) = sum f m`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC MEASURE_UNIQUE THEN + ASM_SIMP_TAC[HAS_MEASURE_NEGLIGIBLE_UNIONS]);; + +let HAS_MEASURE_DISJOINT_UNIONS = prove + (`!m f:(real^N->bool)->bool. + FINITE f /\ + (!s. s IN f ==> s has_measure (m s)) /\ + (!s t. s IN f /\ t IN f /\ ~(s = t) ==> DISJOINT s t) + ==> (UNIONS f) has_measure (sum f m)`, + REWRITE_TAC[DISJOINT] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC HAS_MEASURE_NEGLIGIBLE_UNIONS THEN + ASM_SIMP_TAC[NEGLIGIBLE_EMPTY]);; + +let MEASURE_DISJOINT_UNIONS = prove + (`!m f:(real^N->bool)->bool. + FINITE f /\ + (!s. s IN f ==> s has_measure (m s)) /\ + (!s t. s IN f /\ t IN f /\ ~(s = t) ==> DISJOINT s t) + ==> measure(UNIONS f) = sum f m`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC MEASURE_UNIQUE THEN + ASM_SIMP_TAC[HAS_MEASURE_DISJOINT_UNIONS]);; + +let HAS_MEASURE_NEGLIGIBLE_UNIONS_IMAGE = prove + (`!f:A->real^N->bool s. + FINITE s /\ + (!x. x IN s ==> measurable(f x)) /\ + (!x y. x IN s /\ y IN s /\ ~(x = y) ==> negligible((f x) INTER (f y))) + ==> (UNIONS (IMAGE f s)) has_measure (sum s (\x. measure(f x)))`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN + `sum s (\x. measure(f x)) = sum (IMAGE (f:A->real^N->bool) s) measure` + SUBST1_TAC THENL + [CONV_TAC SYM_CONV THEN ONCE_REWRITE_TAC[GSYM o_DEF] THEN + MATCH_MP_TAC SUM_IMAGE_NONZERO THEN ASM_REWRITE_TAC[] THEN + MAP_EVERY X_GEN_TAC [`x:A`; `y:A`] THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`x:A`; `y:A`]) THEN + ASM_SIMP_TAC[INTER_ACI; MEASURABLE_MEASURE_EQ_0]; + MATCH_MP_TAC HAS_MEASURE_NEGLIGIBLE_UNIONS THEN + ASM_SIMP_TAC[RIGHT_FORALL_IMP_THM; IMP_CONJ; FORALL_IN_IMAGE] THEN + ASM_MESON_TAC[FINITE_IMAGE; HAS_MEASURE_MEASURE]]);; + +let MEASURE_NEGLIGIBLE_UNIONS_IMAGE = prove + (`!f:A->real^N->bool s. + FINITE s /\ + (!x. x IN s ==> measurable(f x)) /\ + (!x y. x IN s /\ y IN s /\ ~(x = y) ==> negligible((f x) INTER (f y))) + ==> measure(UNIONS (IMAGE f s)) = sum s (\x. measure(f x))`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC MEASURE_UNIQUE THEN + ASM_SIMP_TAC[HAS_MEASURE_NEGLIGIBLE_UNIONS_IMAGE]);; + +let HAS_MEASURE_DISJOINT_UNIONS_IMAGE = prove + (`!f:A->real^N->bool s. + FINITE s /\ + (!x. x IN s ==> measurable(f x)) /\ + (!x y. x IN s /\ y IN s /\ ~(x = y) ==> DISJOINT (f x) (f y)) + ==> (UNIONS (IMAGE f s)) has_measure (sum s (\x. measure(f x)))`, + REWRITE_TAC[DISJOINT] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC HAS_MEASURE_NEGLIGIBLE_UNIONS_IMAGE THEN + ASM_SIMP_TAC[NEGLIGIBLE_EMPTY]);; + +let MEASURE_DISJOINT_UNIONS_IMAGE = prove + (`!f:A->real^N->bool s. + FINITE s /\ + (!x. x IN s ==> measurable(f x)) /\ + (!x y. x IN s /\ y IN s /\ ~(x = y) ==> DISJOINT (f x) (f y)) + ==> measure(UNIONS (IMAGE f s)) = sum s (\x. measure(f x))`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC MEASURE_UNIQUE THEN + ASM_SIMP_TAC[HAS_MEASURE_DISJOINT_UNIONS_IMAGE]);; + +let HAS_MEASURE_NEGLIGIBLE_UNIONS_IMAGE_STRONG = prove + (`!f:A->real^N->bool s. + FINITE {x | x IN s /\ ~(f x = {})} /\ + (!x. x IN s ==> measurable(f x)) /\ + (!x y. x IN s /\ y IN s /\ ~(x = y) ==> negligible((f x) INTER (f y))) + ==> (UNIONS (IMAGE f s)) has_measure (sum s (\x. measure(f x)))`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`f:A->real^N->bool`; + `{x | x IN s /\ ~((f:A->real^N->bool) x = {})}`] + HAS_MEASURE_NEGLIGIBLE_UNIONS_IMAGE) THEN + ASM_SIMP_TAC[IN_ELIM_THM; FINITE_RESTRICT] THEN + MATCH_MP_TAC EQ_IMP THEN BINOP_TAC THENL + [GEN_REWRITE_TAC I [EXTENSION] THEN + REWRITE_TAC[IN_UNIONS; IN_IMAGE; IN_ELIM_THM] THEN + MESON_TAC[NOT_IN_EMPTY]; + CONV_TAC SYM_CONV THEN MATCH_MP_TAC SUM_SUPERSET THEN + SIMP_TAC[SUBSET; IN_ELIM_THM; TAUT `a /\ ~(a /\ b) <=> a /\ ~b`] THEN + REWRITE_TAC[MEASURE_EMPTY]]);; + +let MEASURE_NEGLIGIBLE_UNIONS_IMAGE_STRONG = prove + (`!f:A->real^N->bool s. + FINITE {x | x IN s /\ ~(f x = {})} /\ + (!x. x IN s ==> measurable(f x)) /\ + (!x y. x IN s /\ y IN s /\ ~(x = y) ==> negligible((f x) INTER (f y))) + ==> measure(UNIONS (IMAGE f s)) = sum s (\x. measure(f x))`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC MEASURE_UNIQUE THEN + ASM_SIMP_TAC[HAS_MEASURE_NEGLIGIBLE_UNIONS_IMAGE_STRONG]);; + +let HAS_MEASURE_DISJOINT_UNIONS_IMAGE_STRONG = prove + (`!f:A->real^N->bool s. + FINITE {x | x IN s /\ ~(f x = {})} /\ + (!x. x IN s ==> measurable(f x)) /\ + (!x y. x IN s /\ y IN s /\ ~(x = y) ==> DISJOINT (f x) (f y)) + ==> (UNIONS (IMAGE f s)) has_measure (sum s (\x. measure(f x)))`, + REWRITE_TAC[DISJOINT] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC HAS_MEASURE_NEGLIGIBLE_UNIONS_IMAGE_STRONG THEN + ASM_SIMP_TAC[NEGLIGIBLE_EMPTY]);; + +let MEASURE_DISJOINT_UNIONS_IMAGE_STRONG = prove + (`!f:A->real^N->bool s. + FINITE {x | x IN s /\ ~(f x = {})} /\ + (!x. x IN s ==> measurable(f x)) /\ + (!x y. x IN s /\ y IN s /\ ~(x = y) ==> DISJOINT (f x) (f y)) + ==> measure(UNIONS (IMAGE f s)) = sum s (\x. measure(f x))`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC MEASURE_UNIQUE THEN + ASM_SIMP_TAC[HAS_MEASURE_DISJOINT_UNIONS_IMAGE_STRONG]);; + +let MEASURE_UNION = prove + (`!s t:real^N->bool. + measurable s /\ measurable t + ==> measure(s UNION t) = measure(s) + measure(t) - measure(s INTER t)`, + REPEAT STRIP_TAC THEN + ONCE_REWRITE_TAC[SET_RULE + `s UNION t = (s INTER t) UNION (s DIFF t) UNION (t DIFF s)`] THEN + ONCE_REWRITE_TAC[REAL_ARITH `a + b - c:real = c + (a - c) + (b - c)`] THEN + MP_TAC(ISPECL [`s DIFF t:real^N->bool`; `t DIFF s:real^N->bool`] + MEASURE_DISJOINT_UNION) THEN + ASM_SIMP_TAC[MEASURABLE_DIFF] THEN + ANTS_TAC THENL [SET_TAC[]; ALL_TAC] THEN + MP_TAC(ISPECL [`s INTER t:real^N->bool`; + `(s DIFF t) UNION (t DIFF s):real^N->bool`] + MEASURE_DISJOINT_UNION) THEN + ASM_SIMP_TAC[MEASURABLE_DIFF; MEASURABLE_UNION; MEASURABLE_INTER] THEN + ANTS_TAC THENL [SET_TAC[]; ALL_TAC] THEN + REPEAT(DISCH_THEN SUBST1_TAC) THEN AP_TERM_TAC THEN BINOP_TAC THEN + REWRITE_TAC[REAL_EQ_SUB_LADD] THEN MATCH_MP_TAC EQ_TRANS THENL + [EXISTS_TAC `measure((s DIFF t) UNION (s INTER t):real^N->bool)`; + EXISTS_TAC `measure((t DIFF s) UNION (s INTER t):real^N->bool)`] THEN + (CONJ_TAC THENL + [CONV_TAC SYM_CONV THEN MATCH_MP_TAC MEASURE_DISJOINT_UNION THEN + ASM_SIMP_TAC[MEASURABLE_DIFF; MEASURABLE_INTER]; + AP_TERM_TAC] THEN + SET_TAC[]));; + +let MEASURE_UNION_LE = prove + (`!s t:real^N->bool. + measurable s /\ measurable t + ==> measure(s UNION t) <= measure s + measure t`, + REPEAT STRIP_TAC THEN ASM_SIMP_TAC[MEASURE_UNION] THEN + REWRITE_TAC[REAL_ARITH `a + b - c <= a + b <=> &0 <= c`] THEN + MATCH_MP_TAC MEASURE_POS_LE THEN ASM_SIMP_TAC[MEASURABLE_INTER]);; + +let MEASURE_UNIONS_LE = prove + (`!f:(real^N->bool)->bool. + FINITE f /\ (!s. s IN f ==> measurable s) + ==> measure(UNIONS f) <= sum f (\s. measure s)`, + REWRITE_TAC[IMP_CONJ] THEN + MATCH_MP_TAC FINITE_INDUCT_STRONG THEN + SIMP_TAC[UNIONS_0; UNIONS_INSERT; SUM_CLAUSES] THEN + REWRITE_TAC[MEASURE_EMPTY; REAL_LE_REFL] THEN + MAP_EVERY X_GEN_TAC [`s:real^N->bool`; `f:(real^N->bool)->bool`] THEN + REWRITE_TAC[IN_INSERT] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `measure(s:real^N->bool) + measure(UNIONS f:real^N->bool)` THEN + ASM_SIMP_TAC[MEASURE_UNION_LE; MEASURABLE_UNIONS] THEN + REWRITE_TAC[REAL_LE_LADD] THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_SIMP_TAC[]);; + +let MEASURABLE_INSERT = prove + (`!x s:real^N->bool. measurable(x INSERT s) <=> measurable s`, + REPEAT GEN_TAC THEN MATCH_MP_TAC MEASURABLE_NEGLIGIBLE_SYMDIFF_EQ THEN + MATCH_MP_TAC NEGLIGIBLE_SUBSET THEN EXISTS_TAC `{x:real^N}` THEN + REWRITE_TAC[NEGLIGIBLE_SING] THEN SET_TAC[]);; + +let MEASURE_INSERT = prove + (`!x s:real^N->bool. measure(x INSERT s) = measure s`, + REPEAT GEN_TAC THEN MATCH_MP_TAC MEASURE_NEGLIGIBLE_SYMDIFF THEN + MATCH_MP_TAC NEGLIGIBLE_SUBSET THEN EXISTS_TAC `{x:real^N}` THEN + REWRITE_TAC[NEGLIGIBLE_SING] THEN SET_TAC[]);; + +let MEASURE_UNIONS_LE_IMAGE = prove + (`!f:A->bool s:A->(real^N->bool). + FINITE f /\ (!a. a IN f ==> measurable(s a)) + ==> measure(UNIONS (IMAGE s f)) <= sum f (\a. measure(s a))`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `sum (IMAGE s (f:A->bool)) (\k:real^N->bool. measure k)` THEN + ASM_SIMP_TAC[MEASURE_UNIONS_LE; FORALL_IN_IMAGE; FINITE_IMAGE] THEN + GEN_REWRITE_TAC (RAND_CONV o RAND_CONV) [GSYM o_DEF] THEN + REWRITE_TAC[ETA_AX] THEN MATCH_MP_TAC SUM_IMAGE_LE THEN + ASM_SIMP_TAC[MEASURE_POS_LE]);; + +let MEASURABLE_INNER_OUTER = prove + (`!s:real^N->bool. + measurable s <=> + !e. &0 < e + ==> ?t u. t SUBSET s /\ s SUBSET u /\ + measurable t /\ measurable u /\ + abs(measure t - measure u) < e`, + GEN_TAC THEN EQ_TAC THEN DISCH_TAC THENL + [GEN_TAC THEN DISCH_TAC THEN REPEAT(EXISTS_TAC `s:real^N->bool`) THEN + ASM_REWRITE_TAC[SUBSET_REFL; REAL_SUB_REFL; REAL_ABS_NUM]; + ALL_TAC] THEN + REWRITE_TAC[MEASURABLE_INTEGRABLE] THEN MATCH_MP_TAC INTEGRABLE_STRADDLE THEN + X_GEN_TAC `e:real` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `e:real`) THEN + ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`t:real^N->bool`; `u:real^N->bool`] THEN STRIP_TAC THEN + MAP_EVERY EXISTS_TAC + [`(\x. if x IN t then vec 1 else vec 0):real^N->real^1`; + `(\x. if x IN u then vec 1 else vec 0):real^N->real^1`; + `lift(measure(t:real^N->bool))`; + `lift(measure(u:real^N->bool))`] THEN + ASM_REWRITE_TAC[GSYM HAS_MEASURE; GSYM HAS_MEASURE_MEASURE] THEN + ASM_REWRITE_TAC[GSYM LIFT_SUB; NORM_LIFT] THEN REPEAT STRIP_TAC THEN + REPEAT(COND_CASES_TAC THEN + ASM_REWRITE_TAC[DROP_VEC; REAL_POS; REAL_LE_REFL]) THEN + ASM SET_TAC[]);; + +let HAS_MEASURE_INNER_OUTER = prove + (`!s:real^N->bool m. + s has_measure m <=> + (!e. &0 < e ==> ?t. t SUBSET s /\ measurable t /\ + m - e < measure t) /\ + (!e. &0 < e ==> ?u. s SUBSET u /\ measurable u /\ + measure u < m + e)`, + REPEAT GEN_TAC THEN + GEN_REWRITE_TAC LAND_CONV [HAS_MEASURE_MEASURABLE_MEASURE] THEN EQ_TAC THENL + [REPEAT STRIP_TAC THEN EXISTS_TAC `s:real^N->bool` THEN + ASM_REWRITE_TAC[SUBSET_REFL] THEN ASM_REAL_ARITH_TAC; + ALL_TAC] THEN + DISCH_THEN(CONJUNCTS_THEN2 (LABEL_TAC "t") (LABEL_TAC "u")) THEN + MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN CONJ_TAC THENL + [GEN_REWRITE_TAC I [MEASURABLE_INNER_OUTER] THEN + X_GEN_TAC `e:real` THEN DISCH_TAC THEN + REMOVE_THEN "u" (MP_TAC o SPEC `e / &2`) THEN + REMOVE_THEN "t" (MP_TAC o SPEC `e / &2`) THEN + ASM_SIMP_TAC[REAL_LT_DIV; REAL_OF_NUM_LT; ARITH] THEN + REWRITE_TAC[IMP_IMP; LEFT_AND_EXISTS_THM] THEN + REWRITE_TAC[RIGHT_AND_EXISTS_THM] THEN + REPEAT(MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC) THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN MATCH_MP_TAC(REAL_ARITH + `&0 < e /\ t <= u /\ m - e / &2 < t /\ u < m + e / &2 + ==> abs(t - u) < e`) THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC MEASURE_SUBSET THEN + ASM_REWRITE_TAC[] THEN ASM SET_TAC[]; + DISCH_TAC THEN MATCH_MP_TAC(REAL_ARITH + `~(&0 < x - y) /\ ~(&0 < y - x) ==> x = y`) THEN + CONJ_TAC THEN DISCH_TAC THENL + [REMOVE_THEN "u" (MP_TAC o SPEC `measure(s:real^N->bool) - m`) THEN + ASM_REWRITE_TAC[REAL_SUB_ADD2; GSYM REAL_NOT_LE]; + REMOVE_THEN "t" (MP_TAC o SPEC `m - measure(s:real^N->bool)`) THEN + ASM_REWRITE_TAC[REAL_SUB_SUB2; GSYM REAL_NOT_LE]] THEN + ASM_MESON_TAC[MEASURE_SUBSET]]);; + +let HAS_MEASURE_INNER_OUTER_LE = prove + (`!s:real^N->bool m. + s has_measure m <=> + (!e. &0 < e ==> ?t. t SUBSET s /\ measurable t /\ + m - e <= measure t) /\ + (!e. &0 < e ==> ?u. s SUBSET u /\ measurable u /\ + measure u <= m + e)`, + REWRITE_TAC[HAS_MEASURE_INNER_OUTER] THEN + MESON_TAC[REAL_ARITH `&0 < e /\ m - e / &2 <= t ==> m - e < t`; + REAL_ARITH `&0 < e /\ u <= m + e / &2 ==> u < m + e`; + REAL_ARITH `&0 < e <=> &0 < e / &2`; REAL_LT_IMP_LE]);; + +let NEGLIGIBLE_OUTER = prove + (`!s:real^N->bool. + negligible s <=> + !e. &0 < e ==> ?t. s SUBSET t /\ measurable t /\ measure t < e`, + GEN_TAC THEN REWRITE_TAC[GSYM HAS_MEASURE_0; HAS_MEASURE_INNER_OUTER] THEN + REWRITE_TAC[REAL_ADD_LID] THEN MATCH_MP_TAC(TAUT `a ==> (a /\ b <=> b)`) THEN + X_GEN_TAC `e:real` THEN DISCH_TAC THEN EXISTS_TAC `{}:real^N->bool` THEN + REWRITE_TAC[EMPTY_SUBSET; MEASURABLE_EMPTY; MEASURE_EMPTY] THEN + ASM_REAL_ARITH_TAC);; + +let NEGLIGIBLE_OUTER_LE = prove + (`!s:real^N->bool. + negligible s <=> + !e. &0 < e ==> ?t. s SUBSET t /\ measurable t /\ measure t <= e`, + REWRITE_TAC[NEGLIGIBLE_OUTER] THEN + MESON_TAC[REAL_LT_IMP_LE; REAL_ARITH + `&0 < e ==> &0 < e / &2 /\ (x <= e / &2 ==> x < e)`]);; + +let HAS_MEASURE_LIMIT = prove + (`!s. s has_measure m <=> + !e. &0 < e + ==> ?B. &0 < B /\ + !a b. ball(vec 0,B) SUBSET interval[a,b] + ==> ?z. (s INTER interval[a,b]) has_measure z /\ + abs(z - m) < e`, + GEN_TAC THEN REWRITE_TAC[HAS_MEASURE] THEN + GEN_REWRITE_TAC LAND_CONV [HAS_INTEGRAL] THEN + REWRITE_TAC[IN_UNIV] THEN + GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) + [GSYM HAS_INTEGRAL_RESTRICT_UNIV] THEN + REWRITE_TAC[MESON[IN_INTER] + `(if x IN k INTER s then a else b) = + (if x IN s then if x IN k then a else b else b)`] THEN + REWRITE_TAC[EXISTS_LIFT; GSYM LIFT_SUB; NORM_LIFT]);; + +let MEASURE_LIMIT = prove + (`!s:real^N->bool e. + measurable s /\ &0 < e + ==> ?B. &0 < B /\ + !a b. ball(vec 0,B) SUBSET interval[a,b] + ==> abs(measure(s INTER interval[a,b]) - + measure s) < e`, + REPEAT STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [HAS_MEASURE_MEASURE]) THEN + GEN_REWRITE_TAC LAND_CONV [HAS_MEASURE_LIMIT] THEN + DISCH_THEN(MP_TAC o SPEC `e:real`) THEN ASM_REWRITE_TAC[] THEN + ASM_MESON_TAC[MEASURE_UNIQUE]);; + +let INTEGRABLE_ON_CONST = prove + (`!c:real^N. (\x:real^M. c) integrable_on s <=> c = vec 0 \/ measurable s`, + GEN_TAC THEN ASM_CASES_TAC `c:real^N = vec 0` THEN + ASM_REWRITE_TAC[INTEGRABLE_0; MEASURABLE] THEN EQ_TAC THENL + [FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE RAND_CONV [CART_EQ]) THEN + REWRITE_TAC[NOT_FORALL_THM; NOT_IMP; VEC_COMPONENT] THEN + DISCH_THEN(X_CHOOSE_THEN `k:num` STRIP_ASSUME_TAC) THEN + DISCH_THEN(MP_TAC o + ISPEC `(\y. lambda i. y$k / (c:real^N)$k):real^N->real^1` o + MATCH_MP(REWRITE_RULE[IMP_CONJ] INTEGRABLE_LINEAR)) THEN + ASM_SIMP_TAC[vec; o_DEF; REAL_DIV_REFL] THEN DISCH_THEN MATCH_MP_TAC THEN + SIMP_TAC[linear; CART_EQ; VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT; + LAMBDA_BETA] THEN REAL_ARITH_TAC; + DISCH_THEN(MP_TAC o + ISPEC `(\y. lambda i. (c:real^N)$i * y$i):real^1->real^N` o + MATCH_MP(REWRITE_RULE[IMP_CONJ] INTEGRABLE_LINEAR)) THEN + ANTS_TAC THENL + [SIMP_TAC[linear; CART_EQ; VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT; + LAMBDA_BETA] THEN REAL_ARITH_TAC; + MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_TERM_TAC THEN + SIMP_TAC[FUN_EQ_THM; CART_EQ; o_THM; LAMBDA_BETA; VEC_COMPONENT] THEN + REWRITE_TAC[REAL_MUL_RID]]]);; + +let ABSOLUTELY_INTEGRABLE_ON_CONST = prove + (`!c. (\x. c) absolutely_integrable_on s <=> c = vec 0 \/ measurable s`, + REWRITE_TAC[absolutely_integrable_on; INTEGRABLE_ON_CONST] THEN + REWRITE_TAC[GSYM DROP_EQ; LIFT_DROP; DROP_VEC; NORM_EQ_0]);; + +let OPEN_NOT_NEGLIGIBLE = prove + (`!s:real^N->bool. open s /\ ~(s = {}) ==> ~(negligible s)`, + GEN_TAC THEN REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; RIGHT_AND_EXISTS_THM] THEN + REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN X_GEN_TAC `a:real^N` THEN + STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [OPEN_CONTAINS_CBALL]) THEN + DISCH_THEN(MP_TAC o SPEC `a:real^N`) THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `e:real` STRIP_ASSUME_TAC) THEN DISCH_TAC THEN + SUBGOAL_THEN `negligible(interval[a - e / (&(dimindex(:N))) % vec 1:real^N, + a + e / (&(dimindex(:N))) % vec 1])` + MP_TAC THENL + [MATCH_MP_TAC NEGLIGIBLE_SUBSET THEN + EXISTS_TAC `cball(a:real^N,e)` THEN + CONJ_TAC THENL [ASM_MESON_TAC[NEGLIGIBLE_SUBSET]; ALL_TAC] THEN + REWRITE_TAC[SUBSET; IN_INTERVAL; IN_CBALL; VECTOR_ADD_COMPONENT; + VECTOR_SUB_COMPONENT; VECTOR_MUL_COMPONENT; VEC_COMPONENT; REAL_MUL_RID; + REAL_ARITH `a - e <= x /\ x <= a + e <=> abs(x - a) <= e`; dist] THEN + X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN + W(MP_TAC o PART_MATCH lhand NORM_LE_L1 o lhand o snd) THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] REAL_LE_TRANS) THEN + MATCH_MP_TAC SUM_BOUND_GEN THEN + REWRITE_TAC[FINITE_NUMSEG; CARD_NUMSEG_1; NUMSEG_EMPTY; NOT_LT] THEN + REWRITE_TAC[IN_NUMSEG; VECTOR_SUB_COMPONENT; DIMINDEX_GE_1] THEN + ASM_MESON_TAC[REAL_ABS_SUB]; + REWRITE_TAC[NEGLIGIBLE_INTERVAL; INTERVAL_NE_EMPTY] THEN + REWRITE_TAC[VECTOR_ADD_COMPONENT; REAL_MUL_RID; + VECTOR_SUB_COMPONENT; VECTOR_MUL_COMPONENT; VEC_COMPONENT] THEN + REPEAT STRIP_TAC THEN + REWRITE_TAC[REAL_ARITH `a - e < a + e <=> &0 < e`] THEN + ASM_SIMP_TAC[REAL_LT_DIV; REAL_OF_NUM_LT; LE_1; DIMINDEX_GE_1]]);; + +let NOT_NEGLIGIBLE_UNIV = prove + (`~negligible(:real^N)`, + SIMP_TAC[OPEN_NOT_NEGLIGIBLE; OPEN_UNIV; UNIV_NOT_EMPTY]);; + +(* ------------------------------------------------------------------------- *) +(* Properties of measure under simple affine transformations. *) +(* ------------------------------------------------------------------------- *) + +let HAS_MEASURE_AFFINITY = prove + (`!s m c y. s has_measure y + ==> (IMAGE (\x:real^N. m % x + c) s) + has_measure abs(m) pow (dimindex(:N)) * y`, + REPEAT GEN_TAC THEN ASM_CASES_TAC `m = &0` THENL + [ASM_REWRITE_TAC[REAL_ABS_NUM; VECTOR_ADD_LID; VECTOR_MUL_LZERO] THEN + ONCE_REWRITE_TAC[MATCH_MP (ARITH_RULE `~(x = 0) ==> x = SUC(x - 1)`) + (SPEC_ALL DIMINDEX_NONZERO)] THEN DISCH_TAC THEN + REWRITE_TAC[real_pow; REAL_MUL_LZERO; HAS_MEASURE_0] THEN + MATCH_MP_TAC NEGLIGIBLE_SUBSET THEN EXISTS_TAC `{c:real^N}` THEN + SIMP_TAC[NEGLIGIBLE_FINITE; FINITE_RULES] THEN SET_TAC[]; + ALL_TAC] THEN + REWRITE_TAC[HAS_MEASURE] THEN + ONCE_REWRITE_TAC[HAS_INTEGRAL] THEN REWRITE_TAC[IN_UNIV] THEN + DISCH_TAC THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `e:real / abs(m) pow dimindex(:N)`) THEN + ASM_SIMP_TAC[REAL_LT_DIV; REAL_POW_LT; GSYM REAL_ABS_NZ; REAL_POW_LT] THEN + DISCH_THEN(X_CHOOSE_THEN `B:real` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `abs(m) * B + norm(c:real^N)` THEN + ASM_SIMP_TAC[REAL_ARITH `&0 < B /\ &0 <= x ==> &0 < B + x`; + NORM_POS_LE; REAL_LT_MUL; GSYM REAL_ABS_NZ; REAL_POW_LT] THEN + MAP_EVERY X_GEN_TAC [`u:real^N`; `v:real^N`] THEN DISCH_TAC THEN + REWRITE_TAC[IN_IMAGE] THEN + ASM_SIMP_TAC[VECTOR_EQ_AFFINITY; UNWIND_THM1] THEN + FIRST_X_ASSUM(MP_TAC o SPECL + [`if &0 <= m then inv m % u + --(inv m % c):real^N + else inv m % v + --(inv m % c)`; + `if &0 <= m then inv m % v + --(inv m % c):real^N + else inv m % u + --(inv m % c)`]) THEN + MATCH_MP_TAC(TAUT `a /\ (a ==> b ==> c) ==> (a ==> b) ==> c`) THEN + CONJ_TAC THENL + [REWRITE_TAC[SUBSET] THEN X_GEN_TAC `x:real^N` THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [SUBSET]) THEN + DISCH_THEN(MP_TAC o SPEC `m % x + c:real^N`) THEN + MATCH_MP_TAC MONO_IMP THEN REWRITE_TAC[IN_BALL; IN_INTERVAL] THEN + CONJ_TAC THENL + [REWRITE_TAC[NORM_ARITH `dist(vec 0,x) = norm(x:real^N)`] THEN + DISCH_TAC THEN MATCH_MP_TAC(NORM_ARITH + `norm(x:real^N) < a ==> norm(x + y) < a + norm(y)`) THEN + ASM_SIMP_TAC[NORM_MUL; REAL_LT_LMUL; GSYM REAL_ABS_NZ]; + ALL_TAC] THEN + SIMP_TAC[VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT; VECTOR_NEG_COMPONENT; + COND_COMPONENT] THEN + MATCH_MP_TAC MONO_FORALL THEN GEN_TAC THEN MATCH_MP_TAC MONO_IMP THEN + REWRITE_TAC[REAL_ARITH `m * u + --(m * c):real = (u - c) * m`] THEN + SUBST1_TAC(REAL_ARITH + `inv(m) = if &0 <= inv(m) then abs(inv m) else --(abs(inv m))`) THEN + SIMP_TAC[REAL_LE_INV_EQ] THEN + REWRITE_TAC[REAL_ARITH `(x - y:real) * --z = (y - x) * z`] THEN + REWRITE_TAC[REAL_ABS_INV; GSYM real_div] THEN COND_CASES_TAC THEN + ASM_SIMP_TAC[REAL_LE_LDIV_EQ; REAL_LE_RDIV_EQ; GSYM REAL_ABS_NZ] THEN + ASM_REWRITE_TAC[real_abs] THEN REAL_ARITH_TAC; + ALL_TAC] THEN + REWRITE_TAC[SUBSET] THEN DISCH_THEN(MP_TAC o SPEC `vec 0:real^N`) THEN + ASM_REWRITE_TAC[CENTRE_IN_BALL] THEN DISCH_TAC THEN + DISCH_THEN(X_CHOOSE_THEN `z:real^1` + (fun th -> EXISTS_TAC `(abs m pow dimindex (:N)) % z:real^1` THEN + MP_TAC th)) THEN + DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN + FIRST_ASSUM(MP_TAC o MATCH_MP(REAL_FIELD `~(x = &0) ==> ~(inv x = &0)`)) THEN + REWRITE_TAC[TAUT `a ==> b ==> c <=> b /\ a ==> c`] THEN + DISCH_THEN(MP_TAC o SPEC `--(inv m % c):real^N` o + MATCH_MP HAS_INTEGRAL_AFFINITY) THEN + ASM_REWRITE_TAC[IMAGE_AFFINITY_INTERVAL; REAL_INV_INV] THEN + SIMP_TAC[COND_ID] THEN COND_CASES_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + REWRITE_TAC[VECTOR_ADD_LDISTRIB; VECTOR_MUL_ASSOC; + VECTOR_MUL_LNEG; VECTOR_MUL_RNEG] THEN + ASM_SIMP_TAC[REAL_MUL_RINV; VECTOR_MUL_LID; VECTOR_NEG_NEG] THEN + REWRITE_TAC[VECTOR_ARITH `(u + --c) + c:real^N = u`] THEN + REWRITE_TAC[REAL_ABS_INV; REAL_INV_INV; GSYM REAL_POW_INV] THEN + DISCH_THEN(fun th -> REWRITE_TAC[th]) THEN + REWRITE_TAC[LIFT_CMUL; GSYM VECTOR_SUB_LDISTRIB] THEN + REWRITE_TAC[NORM_MUL; REAL_ABS_POW; REAL_ABS_ABS] THEN + ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN + ASM_SIMP_TAC[GSYM REAL_LT_RDIV_EQ; REAL_POW_LT; GSYM REAL_ABS_NZ]);; + +let STRETCH_GALOIS = prove + (`!x:real^N y:real^N m. + (!k. 1 <= k /\ k <= dimindex(:N) ==> ~(m k = &0)) + ==> ((y = (lambda k. m k * x$k)) <=> (lambda k. inv(m k) * y$k) = x)`, + REPEAT GEN_TAC THEN SIMP_TAC[CART_EQ; LAMBDA_BETA] THEN + MATCH_MP_TAC(MESON[] + `(!x. p x ==> (q x <=> r x)) + ==> (!x. p x) ==> ((!x. q x) <=> (!x. r x))`) THEN + GEN_TAC THEN ASM_CASES_TAC `1 <= k /\ k <= dimindex(:N)` THEN + ASM_REWRITE_TAC[] THEN CONV_TAC REAL_FIELD);; + +let HAS_MEASURE_STRETCH = prove + (`!s m y. s has_measure y + ==> (IMAGE (\x:real^N. lambda k. m k * x$k) s :real^N->bool) + has_measure abs(product (1..dimindex(:N)) m) * y`, + REPEAT STRIP_TAC THEN ASM_CASES_TAC + `!k. 1 <= k /\ k <= dimindex(:N) ==> ~(m k = &0)` + THENL + [ALL_TAC; + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [NOT_FORALL_THM]) THEN + REWRITE_TAC[NOT_IMP; GSYM CONJ_ASSOC; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `k:num` THEN STRIP_TAC THEN + SUBGOAL_THEN `product(1..dimindex (:N)) m = &0` SUBST1_TAC THENL + [ASM_MESON_TAC[PRODUCT_EQ_0_NUMSEG]; ALL_TAC] THEN + REWRITE_TAC[REAL_ABS_NUM; REAL_MUL_LZERO; HAS_MEASURE_0] THEN + MATCH_MP_TAC NEGLIGIBLE_SUBSET THEN + EXISTS_TAC `{x:real^N | x$k = &0}` THEN + ASM_SIMP_TAC[NEGLIGIBLE_STANDARD_HYPERPLANE; SUBSET; FORALL_IN_IMAGE] THEN + ASM_SIMP_TAC[IN_ELIM_THM; LAMBDA_BETA; REAL_MUL_LZERO]] THEN + UNDISCH_TAC `(s:real^N->bool) has_measure y` THEN + REWRITE_TAC[HAS_MEASURE] THEN + ONCE_REWRITE_TAC[HAS_INTEGRAL] THEN REWRITE_TAC[IN_UNIV] THEN + DISCH_TAC THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN + SUBGOAL_THEN `&0 < abs(product(1..dimindex(:N)) m)` ASSUME_TAC THENL + [ASM_MESON_TAC[REAL_ABS_NZ; REAL_LT_DIV; PRODUCT_EQ_0_NUMSEG]; + ALL_TAC] THEN + FIRST_X_ASSUM(MP_TAC o SPEC `e:real / abs(product(1..dimindex(:N)) m)`) THEN + ASM_SIMP_TAC[REAL_LT_DIV] THEN + DISCH_THEN(X_CHOOSE_THEN `B:real` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `sup(IMAGE (\k. abs(m k) * B) (1..dimindex(:N)))` THEN + MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN CONJ_TAC THENL + [ASM_SIMP_TAC[REAL_LT_SUP_FINITE; FINITE_IMAGE; NUMSEG_EMPTY; FINITE_NUMSEG; + IN_NUMSEG; GSYM NOT_LE; DIMINDEX_GE_1; IMAGE_EQ_EMPTY; + EXISTS_IN_IMAGE] THEN + ASM_MESON_TAC[IN_NUMSEG; DIMINDEX_GE_1; LE_REFL; REAL_LT_MUL; REAL_ABS_NZ]; + DISCH_TAC] THEN + MAP_EVERY X_GEN_TAC [`u:real^N`; `v:real^N`] THEN DISCH_TAC THEN + ASM_SIMP_TAC[IN_IMAGE; STRETCH_GALOIS; UNWIND_THM1] THEN + FIRST_X_ASSUM(MP_TAC o SPECL + [`(lambda k. min (inv(m k) * (u:real^N)$k) + (inv(m k) * (v:real^N)$k)):real^N`; + `(lambda k. max (inv(m k) * (u:real^N)$k) + (inv(m k) * (v:real^N)$k)):real^N`]) THEN + MATCH_MP_TAC(TAUT `a /\ (b ==> a ==> c) ==> (a ==> b) ==> c`) THEN + CONJ_TAC THENL + [ALL_TAC; + REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN X_GEN_TAC `z:real^1` THEN + DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN + SUBGOAL_THEN `!k. 1 <= k /\ k <= dimindex (:N) ==> ~(inv(m k) = &0)` + MP_TAC THENL [ASM_SIMP_TAC[REAL_INV_EQ_0]; ALL_TAC] THEN + ONCE_REWRITE_TAC[GSYM IMP_CONJ_ALT] THEN + DISCH_THEN(MP_TAC o MATCH_MP HAS_INTEGRAL_STRETCH)] THEN + (MP_TAC(ISPECL [`u:real^N`; `v:real^N`; `\i:num. inv(m i:real)`] + IMAGE_STRETCH_INTERVAL) THEN + SUBGOAL_THEN `~(interval[u:real^N,v] = {})` ASSUME_TAC THENL + [FIRST_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE + `s SUBSET t ==> ~(s = {}) ==> ~(t = {})`)) THEN + ASM_REWRITE_TAC[BALL_EQ_EMPTY; GSYM REAL_NOT_LT]; + ALL_TAC] THEN + ASM_REWRITE_TAC[] THEN DISCH_THEN(SUBST1_TAC o SYM)) + THENL + [FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE + `b SUBSET s ==> b' SUBSET IMAGE f b ==> b' SUBSET IMAGE f s`)) THEN + REWRITE_TAC[IN_BALL; SUBSET; NORM_ARITH `dist(vec 0:real^N,x) = norm x`; + IN_IMAGE] THEN + ASM_SIMP_TAC[STRETCH_GALOIS; REAL_INV_EQ_0; UNWIND_THM1; REAL_INV_INV] THEN + X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN + MATCH_MP_TAC REAL_LET_TRANS THEN + EXISTS_TAC + `norm(sup(IMAGE(\k. abs(m k)) (1..dimindex(:N))) % x:real^N)` THEN + CONJ_TAC THENL + [MATCH_MP_TAC NORM_LE_COMPONENTWISE THEN + SIMP_TAC[LAMBDA_BETA; VECTOR_MUL_COMPONENT; REAL_ABS_MUL] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_LE_RMUL THEN + REWRITE_TAC[REAL_ABS_POS] THEN + MATCH_MP_TAC(REAL_ARITH `x <= y ==> x <= abs y`) THEN + ASM_SIMP_TAC[REAL_LE_SUP_FINITE; FINITE_IMAGE; IMAGE_EQ_EMPTY; + NUMSEG_EMPTY; FINITE_NUMSEG; GSYM NOT_LE; DIMINDEX_GE_1] THEN + REWRITE_TAC[EXISTS_IN_IMAGE; IN_NUMSEG] THEN ASM_MESON_TAC[REAL_LE_REFL]; + ALL_TAC] THEN + REWRITE_TAC[NORM_MUL] THEN MATCH_MP_TAC REAL_LTE_TRANS THEN + EXISTS_TAC `abs(sup(IMAGE(\k. abs(m k)) (1..dimindex(:N)))) * B` THEN + SUBGOAL_THEN `&0 < sup(IMAGE(\k. abs(m k)) (1..dimindex(:N)))` + ASSUME_TAC THENL + [ASM_SIMP_TAC[REAL_LT_SUP_FINITE; FINITE_IMAGE; IMAGE_EQ_EMPTY; + NUMSEG_EMPTY; FINITE_NUMSEG; GSYM NOT_LE; DIMINDEX_GE_1] THEN + REWRITE_TAC[EXISTS_IN_IMAGE; GSYM REAL_ABS_NZ; IN_NUMSEG] THEN + ASM_MESON_TAC[DIMINDEX_GE_1; LE_REFL]; + ALL_TAC] THEN + ASM_SIMP_TAC[REAL_LT_LMUL_EQ; REAL_ARITH `&0 < x ==> &0 < abs x`] THEN + MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `sup(IMAGE(\k. abs(m k)) (1..dimindex(:N))) * B` THEN + ASM_SIMP_TAC[REAL_LE_RMUL_EQ; REAL_ARITH `&0 < x ==> abs x <= x`] THEN + ASM_SIMP_TAC[REAL_LE_SUP_FINITE; FINITE_IMAGE; IMAGE_EQ_EMPTY; + NUMSEG_EMPTY; FINITE_NUMSEG; GSYM NOT_LE; DIMINDEX_GE_1] THEN + ASM_SIMP_TAC[EXISTS_IN_IMAGE; REAL_LE_RMUL_EQ] THEN + ASM_SIMP_TAC[REAL_SUP_LE_FINITE; FINITE_IMAGE; IMAGE_EQ_EMPTY; + NUMSEG_EMPTY; FINITE_NUMSEG; GSYM NOT_LE; DIMINDEX_GE_1] THEN + MP_TAC(ISPEC `IMAGE (\k. abs (m k)) (1..dimindex(:N))` SUP_FINITE) THEN + REWRITE_TAC[FORALL_IN_IMAGE] THEN + ASM_SIMP_TAC[FINITE_IMAGE; FINITE_NUMSEG; IMAGE_EQ_EMPTY; NUMSEG_EMPTY; + GSYM NOT_LE; DIMINDEX_GE_1] THEN + REWRITE_TAC[IN_IMAGE] THEN MESON_TAC[]; + + MATCH_MP_TAC(MESON[] + `s = t /\ P z ==> (f has_integral z) s ==> Q + ==> ?w. (f has_integral w) t /\ P w`) THEN + SIMP_TAC[GSYM PRODUCT_INV; FINITE_NUMSEG; GSYM REAL_ABS_INV] THEN + REWRITE_TAC[REAL_INV_INV] THEN CONJ_TAC THENL + [REWRITE_TAC[GSYM IMAGE_o] THEN MATCH_MP_TAC(SET_RULE + `(!x. f x = x) ==> IMAGE f s = s`) THEN + SIMP_TAC[o_THM; LAMBDA_BETA; CART_EQ] THEN + ASM_SIMP_TAC[REAL_MUL_ASSOC; REAL_MUL_RINV; REAL_MUL_LID]; + REWRITE_TAC[ABS_DROP; DROP_SUB; LIFT_DROP; DROP_CMUL] THEN + REWRITE_TAC[GSYM REAL_SUB_LDISTRIB; ETA_AX] THEN + REWRITE_TAC[REAL_ABS_MUL; REAL_ABS_ABS] THEN + ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN + ASM_SIMP_TAC[GSYM REAL_LT_RDIV_EQ] THEN + ASM_MESON_TAC[ABS_DROP; DROP_SUB; LIFT_DROP]]]);; + +let HAS_MEASURE_TRANSLATION = prove + (`!s m a. s has_measure m ==> (IMAGE (\x:real^N. a + x) s) has_measure m`, + REPEAT GEN_TAC THEN + MP_TAC(ISPECL [`s:real^N->bool`; `&1`; `a:real^N`; `m:real`] + HAS_MEASURE_AFFINITY) THEN + REWRITE_TAC[VECTOR_MUL_LID; REAL_ABS_NUM; REAL_POW_ONE; REAL_MUL_LID] THEN + REWRITE_TAC[VECTOR_ADD_SYM]);; + +let NEGLIGIBLE_TRANSLATION = prove + (`!s a. negligible s ==> negligible (IMAGE (\x:real^N. a + x) s)`, + SIMP_TAC[GSYM HAS_MEASURE_0; HAS_MEASURE_TRANSLATION]);; + +let HAS_MEASURE_TRANSLATION_EQ = prove + (`!a s m. (IMAGE (\x:real^N. a + x) s) has_measure m <=> s has_measure m`, + REPEAT GEN_TAC THEN EQ_TAC THEN REWRITE_TAC[HAS_MEASURE_TRANSLATION] THEN + DISCH_THEN(MP_TAC o SPEC `--a:real^N` o + MATCH_MP HAS_MEASURE_TRANSLATION) THEN + MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_TERM_TAC THEN + REWRITE_TAC[GSYM IMAGE_o; o_DEF; VECTOR_ARITH `--a + a + b:real^N = b`] THEN + SET_TAC[]);; + +add_translation_invariants [HAS_MEASURE_TRANSLATION_EQ];; + +let MEASURE_TRANSLATION = prove + (`!a s. measure(IMAGE (\x:real^N. a + x) s) = measure s`, + REWRITE_TAC[measure; HAS_MEASURE_TRANSLATION_EQ]);; + +add_translation_invariants [MEASURE_TRANSLATION];; + +let NEGLIGIBLE_TRANSLATION_REV = prove + (`!s a. negligible (IMAGE (\x:real^N. a + x) s) ==> negligible s`, + SIMP_TAC[GSYM HAS_MEASURE_0; HAS_MEASURE_TRANSLATION_EQ]);; + +let NEGLIGIBLE_TRANSLATION_EQ = prove + (`!a s. negligible (IMAGE (\x:real^N. a + x) s) <=> negligible s`, + SIMP_TAC[GSYM HAS_MEASURE_0; HAS_MEASURE_TRANSLATION_EQ]);; + +add_translation_invariants [NEGLIGIBLE_TRANSLATION_EQ];; + +let MEASURABLE_TRANSLATION_EQ = prove + (`!a:real^N s. measurable (IMAGE (\x. a + x) s) <=> measurable s`, + REWRITE_TAC[measurable; HAS_MEASURE_TRANSLATION_EQ]);; + +add_translation_invariants [MEASURABLE_TRANSLATION_EQ];; + +let MEASURABLE_TRANSLATION = prove + (`!s a:real^N. measurable s ==> measurable (IMAGE (\x. a + x) s)`, + REWRITE_TAC[MEASURABLE_TRANSLATION_EQ]);; + +let HAS_MEASURE_SCALING = prove + (`!s m c. s has_measure m + ==> (IMAGE (\x:real^N. c % x) s) has_measure + (abs(c) pow dimindex(:N)) * m`, + REPEAT GEN_TAC THEN + MP_TAC(ISPECL [`s:real^N->bool`; `c:real`; `vec 0:real^N`; `m:real`] + HAS_MEASURE_AFFINITY) THEN + REWRITE_TAC[VECTOR_ADD_RID]);; + +let HAS_MEASURE_SCALING_EQ = prove + (`!s m c. ~(c = &0) + ==> (IMAGE (\x:real^N. c % x) s + has_measure (abs(c) pow dimindex(:N)) * m <=> + s has_measure m)`, + REPEAT STRIP_TAC THEN EQ_TAC THEN REWRITE_TAC[HAS_MEASURE_SCALING] THEN + DISCH_THEN(MP_TAC o SPEC `inv(c):real` o MATCH_MP HAS_MEASURE_SCALING) THEN + REWRITE_TAC[GSYM IMAGE_o; o_DEF; GSYM REAL_ABS_MUL] THEN + REWRITE_TAC[GSYM REAL_POW_MUL; VECTOR_MUL_ASSOC; REAL_MUL_ASSOC] THEN + ASM_SIMP_TAC[GSYM REAL_ABS_MUL; REAL_MUL_LINV] THEN + REWRITE_TAC[REAL_POW_ONE; REAL_ABS_NUM; REAL_MUL_LID; VECTOR_MUL_LID] THEN + MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_TERM_TAC THEN SET_TAC[]);; + +let MEASURABLE_SCALING = prove + (`!s c. measurable s ==> measurable (IMAGE (\x:real^N. c % x) s)`, + REWRITE_TAC[measurable] THEN MESON_TAC[HAS_MEASURE_SCALING]);; + +let MEASURABLE_SCALING_EQ = prove + (`!s c. ~(c = &0) + ==> (measurable (IMAGE (\x:real^N. c % x) s) <=> measurable s)`, + REPEAT STRIP_TAC THEN EQ_TAC THEN REWRITE_TAC[MEASURABLE_SCALING] THEN + DISCH_THEN(MP_TAC o SPEC `inv c:real` o MATCH_MP MEASURABLE_SCALING) THEN + REWRITE_TAC[GSYM IMAGE_o; o_DEF; GSYM REAL_ABS_MUL] THEN + MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN + ASM_SIMP_TAC[VECTOR_MUL_ASSOC; REAL_MUL_LINV; VECTOR_MUL_LID] THEN + SET_TAC[]);; + +let MEASURE_SCALING = prove + (`!s. measurable s + ==> measure(IMAGE (\x:real^N. c % x) s) = + (abs(c) pow dimindex(:N)) * measure s`, + REWRITE_TAC[HAS_MEASURE_MEASURE] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC MEASURE_UNIQUE THEN ASM_SIMP_TAC[HAS_MEASURE_SCALING]);; + +(* ------------------------------------------------------------------------- *) +(* Measurability of countable unions and intersections of various kinds. *) +(* ------------------------------------------------------------------------- *) + +let HAS_MEASURE_NESTED_UNIONS = prove + (`!s:num->real^N->bool B. + (!n. measurable(s n)) /\ + (!n. measure(s n) <= B) /\ + (!n. s(n) SUBSET s(SUC n)) + ==> measurable(UNIONS { s(n) | n IN (:num) }) /\ + ((\n. lift(measure(s n))) + --> lift(measure(UNIONS { s(n) | n IN (:num) }))) + sequentially`, + REPEAT GEN_TAC THEN + ONCE_REWRITE_TAC[TAUT `a ==> b /\ c <=> (a ==> b /\ (b ==> c))`] THEN + SIMP_TAC[MEASURE_INTEGRAL_UNIV; LIFT_DROP] THEN + REWRITE_TAC[MEASURABLE_INTEGRABLE] THEN + STRIP_TAC THEN MATCH_MP_TAC(TAUT `b /\ c ==> b /\ (b ==> c)`) THEN + MATCH_MP_TAC MONOTONE_CONVERGENCE_INCREASING THEN + ASM_REWRITE_TAC[] THEN REPEAT CONJ_TAC THENL + [REPEAT GEN_TAC THEN REPEAT(COND_CASES_TAC THEN ASM_REWRITE_TAC[]) THEN + REWRITE_TAC[DROP_VEC; REAL_POS; REAL_LE_REFL] THEN ASM SET_TAC[]; + X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN COND_CASES_TAC THENL + [MATCH_MP_TAC LIM_EVENTUALLY THEN + REWRITE_TAC[EVENTUALLY_SEQUENTIALLY] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_UNIONS]) THEN + ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN REWRITE_TAC[EXISTS_IN_IMAGE] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `N:num` THEN STRIP_TAC THEN + REPEAT STRIP_TAC THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN + FIRST_ASSUM(MP_TAC o PART_MATCH (rand o rand) + TRANSITIVE_STEPWISE_LE_EQ o concl) THEN + ASM_REWRITE_TAC[SUBSET_TRANS; SUBSET_REFL] THEN ASM SET_TAC[]; + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE RAND_CONV [IN_UNIONS]) THEN + ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN REWRITE_TAC[EXISTS_IN_IMAGE] THEN + SIMP_TAC[NOT_EXISTS_THM; IN_UNIV; LIM_CONST]]; + RULE_ASSUM_TAC(REWRITE_RULE[GSYM MEASURABLE_INTEGRABLE]) THEN + ASM_SIMP_TAC[INTEGRAL_MEASURE_UNIV] THEN + REWRITE_TAC[bounded; SIMPLE_IMAGE; FORALL_IN_IMAGE] THEN + EXISTS_TAC `B:real` THEN REWRITE_TAC[IN_UNIV; NORM_LIFT] THEN + REWRITE_TAC[real_abs] THEN ASM_MESON_TAC[MEASURE_POS_LE]]);; + +let MEASURABLE_NESTED_UNIONS = prove + (`!s:num->real^N->bool B. + (!n. measurable(s n)) /\ + (!n. measure(s n) <= B) /\ + (!n. s(n) SUBSET s(SUC n)) + ==> measurable(UNIONS { s(n) | n IN (:num) })`, + REPEAT GEN_TAC THEN + DISCH_THEN(MP_TAC o MATCH_MP HAS_MEASURE_NESTED_UNIONS) THEN + SIMP_TAC[]);; + +let HAS_MEASURE_COUNTABLE_NEGLIGIBLE_UNIONS = prove + (`!s:num->real^N->bool B. + (!n. measurable(s n)) /\ + (!m n. ~(m = n) ==> negligible(s m INTER s n)) /\ + (!n. sum (0..n) (\k. measure(s k)) <= B) + ==> measurable(UNIONS { s(n) | n IN (:num) }) /\ + ((\n. lift(measure(s n))) sums + lift(measure(UNIONS { s(n) | n IN (:num) }))) (from 0)`, + REPEAT GEN_TAC THEN STRIP_TAC THEN + MP_TAC(ISPECL [`\n. UNIONS (IMAGE s (0..n)):real^N->bool`; `B:real`] + HAS_MEASURE_NESTED_UNIONS) THEN + REWRITE_TAC[sums; FROM_0; INTER_UNIV] THEN + SUBGOAL_THEN + `!n. (UNIONS (IMAGE s (0..n)):real^N->bool) has_measure + (sum(0..n) (\k. measure(s k)))` + MP_TAC THENL + [GEN_TAC THEN MATCH_MP_TAC HAS_MEASURE_NEGLIGIBLE_UNIONS_IMAGE THEN + ASM_SIMP_TAC[FINITE_NUMSEG]; + ALL_TAC] THEN + DISCH_THEN(fun th -> ASSUME_TAC th THEN + ASSUME_TAC(GEN `n:num` (MATCH_MP MEASURE_UNIQUE (SPEC `n:num` th)))) THEN + ASM_REWRITE_TAC[] THEN ANTS_TAC THENL + [CONJ_TAC THENL [ASM_MESON_TAC[measurable]; ALL_TAC] THEN + GEN_TAC THEN MATCH_MP_TAC SUBSET_UNIONS THEN + MATCH_MP_TAC IMAGE_SUBSET THEN + REWRITE_TAC[SUBSET; IN_NUMSEG] THEN ARITH_TAC; + ALL_TAC] THEN + SIMP_TAC[LIFT_SUM; FINITE_NUMSEG; o_DEF] THEN + SUBGOAL_THEN + `UNIONS {UNIONS (IMAGE s (0..n)) | n IN (:num)}:real^N->bool = + UNIONS (IMAGE s (:num))` + (fun th -> REWRITE_TAC[th] THEN ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN + REWRITE_TAC[]) THEN + GEN_REWRITE_TAC I [EXTENSION] THEN X_GEN_TAC `x:real^N` THEN + REWRITE_TAC[IN_UNIONS] THEN ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN + REWRITE_TAC[EXISTS_IN_IMAGE; EXISTS_IN_UNIONS; IN_UNIV] THEN + REWRITE_TAC[IN_UNIONS; EXISTS_IN_IMAGE] THEN + REWRITE_TAC[IN_NUMSEG; LE_0] THEN MESON_TAC[LE_REFL]);; + +let NEGLIGIBLE_COUNTABLE_UNIONS_GEN = prove + (`!f. COUNTABLE f /\ (!s:real^N->bool. s IN f ==> negligible s) + ==> negligible(UNIONS f)`, + GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + ASM_CASES_TAC `f:(real^N->bool)->bool = {}` THEN + ASM_REWRITE_TAC[UNIONS_0; NEGLIGIBLE_EMPTY] THEN + MP_TAC(ISPEC `f:(real^N->bool)->bool` COUNTABLE_AS_IMAGE) THEN + ASM_SIMP_TAC[LEFT_IMP_EXISTS_THM; FORALL_IN_IMAGE; IN_UNIV] THEN + REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[GSYM SIMPLE_IMAGE] THEN + MATCH_MP_TAC NEGLIGIBLE_COUNTABLE_UNIONS THEN ASM_REWRITE_TAC[]);; + +let HAS_MEASURE_COUNTABLE_NEGLIGIBLE_UNIONS_BOUNDED = prove + (`!s:num->real^N->bool. + (!n. measurable(s n)) /\ + (!m n. ~(m = n) ==> negligible(s m INTER s n)) /\ + bounded(UNIONS { s(n) | n IN (:num) }) + ==> measurable(UNIONS { s(n) | n IN (:num) }) /\ + ((\n. lift(measure(s n))) sums + lift(measure(UNIONS { s(n) | n IN (:num) }))) (from 0)`, + REPEAT GEN_TAC THEN STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o MATCH_MP BOUNDED_SUBSET_CLOSED_INTERVAL) THEN + REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`a:real^N`; `b:real^N`] THEN DISCH_TAC THEN + MATCH_MP_TAC HAS_MEASURE_COUNTABLE_NEGLIGIBLE_UNIONS THEN + EXISTS_TAC `measure(interval[a:real^N,b])` THEN + ASM_REWRITE_TAC[] THEN X_GEN_TAC `n:num` THEN MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `measure(UNIONS (IMAGE (s:num->real^N->bool) (0..n)))` THEN + CONJ_TAC THENL + [MATCH_MP_TAC REAL_EQ_IMP_LE THEN CONV_TAC SYM_CONV THEN + MATCH_MP_TAC MEASURE_NEGLIGIBLE_UNIONS_IMAGE THEN + ASM_SIMP_TAC[FINITE_NUMSEG]; + MATCH_MP_TAC MEASURE_SUBSET THEN REWRITE_TAC[MEASURABLE_INTERVAL] THEN + CONJ_TAC THENL + [MATCH_MP_TAC MEASURABLE_UNIONS THEN + ASM_SIMP_TAC[FINITE_IMAGE; FINITE_NUMSEG; FORALL_IN_IMAGE]; + ASM SET_TAC[]]]);; + +let MEASURABLE_COUNTABLE_UNIONS_BOUNDED = prove + (`!s:num->real^N->bool. + (!n. measurable(s n)) /\ + bounded(UNIONS { s(n) | n IN (:num) }) + ==> measurable(UNIONS { s(n) | n IN (:num) })`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN + `UNIONS { s(n):real^N->bool | n IN (:num) } = + UNIONS { UNIONS {s(m) | m IN 0..n} | n IN (:num)}` + SUBST1_TAC THENL + [GEN_REWRITE_TAC I [EXTENSION] THEN REWRITE_TAC[IN_UNIONS; IN_ELIM_THM] THEN + REWRITE_TAC[LEFT_AND_EXISTS_THM] THEN + ONCE_REWRITE_TAC[SWAP_EXISTS_THM] THEN + REWRITE_TAC[GSYM CONJ_ASSOC] THEN ONCE_REWRITE_TAC[CONJ_SYM] THEN + REWRITE_TAC[GSYM CONJ_ASSOC; UNWIND_THM2; IN_UNIONS; IN_ELIM_THM] THEN + REWRITE_TAC[IN_NUMSEG; IN_UNIV; LE_0] THEN MESON_TAC[LE_REFL]; + MATCH_MP_TAC MEASURABLE_NESTED_UNIONS THEN + FIRST_X_ASSUM(MP_TAC o MATCH_MP BOUNDED_SUBSET_CLOSED_INTERVAL) THEN + REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`a:real^N`; `b:real^N`] THEN DISCH_TAC THEN + EXISTS_TAC `measure(interval[a:real^N,b])` THEN + MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN CONJ_TAC THENL + [GEN_TAC THEN MATCH_MP_TAC MEASURABLE_UNIONS THEN + ASM_SIMP_TAC[FORALL_IN_GSPEC] THEN ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN + SIMP_TAC[FINITE_IMAGE; FINITE_NUMSEG]; + DISCH_TAC] THEN + CONJ_TAC THENL + [GEN_TAC THEN MATCH_MP_TAC MEASURE_SUBSET THEN + ASM_REWRITE_TAC[MEASURABLE_INTERVAL] THEN ASM SET_TAC[]; + GEN_TAC THEN REWRITE_TAC[NUMSEG_CLAUSES; LE_0] THEN SET_TAC[]]]);; + +let MEASURE_COUNTABLE_UNIONS_LE_STRONG = prove + (`!d:num->(real^N->bool) B. + (!n. measurable(d n)) /\ + (!n. measure(UNIONS {d k | k <= n}) <= B) + ==> measurable(UNIONS {d n | n IN (:num)}) /\ + measure(UNIONS {d n | n IN (:num)}) <= B`, + REPEAT GEN_TAC THEN STRIP_TAC THEN + MP_TAC(ISPECL [`\n. UNIONS {(d:num->(real^N->bool)) k | k IN (0..n)}`; + `B:real`] + HAS_MEASURE_NESTED_UNIONS) THEN REWRITE_TAC[] THEN + SUBGOAL_THEN `UNIONS {UNIONS {d k | k IN (0..n)} | n IN (:num)} = + UNIONS {d n:real^N->bool | n IN (:num)}` + SUBST1_TAC THENL + [GEN_REWRITE_TAC I [EXTENSION] THEN + REWRITE_TAC[IN_UNIONS; EXISTS_IN_GSPEC; IN_UNIV; IN_NUMSEG; LE_0] THEN + MESON_TAC[LE_REFL]; + ALL_TAC] THEN + ANTS_TAC THENL + [REPEAT CONJ_TAC THENL + [GEN_TAC THEN MATCH_MP_TAC MEASURABLE_UNIONS THEN + SIMP_TAC[SIMPLE_IMAGE; FINITE_IMAGE; FINITE_NUMSEG] THEN + ASM_REWRITE_TAC[FORALL_IN_IMAGE]; + ASM_REWRITE_TAC[IN_NUMSEG; LE_0]; + GEN_TAC THEN REWRITE_TAC[SIMPLE_IMAGE] THEN + MATCH_MP_TAC SUBSET_UNIONS THEN MATCH_MP_TAC IMAGE_SUBSET THEN + REWRITE_TAC[SUBSET_NUMSEG] THEN ARITH_TAC]; + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + GEN_REWRITE_TAC LAND_CONV [GSYM(CONJUNCT2 LIFT_DROP)] THEN + MATCH_MP_TAC(ISPEC `sequentially` LIM_DROP_UBOUND) THEN + EXISTS_TAC `\n. lift(measure(UNIONS {d k | k IN 0..n} :real^N->bool))` THEN + ASM_REWRITE_TAC[TRIVIAL_LIMIT_SEQUENTIALLY; EVENTUALLY_SEQUENTIALLY] THEN + EXISTS_TAC `0` THEN X_GEN_TAC `n:num` THEN DISCH_TAC THEN + ASM_REWRITE_TAC[LIFT_DROP; IN_NUMSEG; LE_0]]);; + +let MEASURE_COUNTABLE_UNIONS_LE = prove + (`!d:num->(real^N->bool) B. + (!n. measurable(d n)) /\ + (!n. sum(0..n) (\k. measure(d k)) <= B) + ==> measurable(UNIONS {d n | n IN (:num)}) /\ + measure(UNIONS {d n | n IN (:num)}) <= B`, + REPEAT GEN_TAC THEN STRIP_TAC THEN + MATCH_MP_TAC MEASURE_COUNTABLE_UNIONS_LE_STRONG THEN + ASM_REWRITE_TAC[] THEN X_GEN_TAC `n:num` THEN + MP_TAC(ISPECL [`0..n`;`d:num->real^N->bool`] MEASURE_UNIONS_LE_IMAGE) THEN + ASM_REWRITE_TAC[FINITE_NUMSEG] THEN + REPEAT(FIRST_X_ASSUM (MP_TAC o SPEC `n:num`)) THEN + REWRITE_TAC[GSYM SIMPLE_IMAGE; numseg; LE_0; IN_ELIM_THM] THEN + MESON_TAC[REAL_LE_TRANS]);; + +let MEASURABLE_COUNTABLE_UNIONS_STRONG = prove + (`!s:num->real^N->bool B. + (!n. measurable(s n)) /\ + (!n. measure(UNIONS {s k | k <= n}) <= B) + ==> measurable(UNIONS { s(n) | n IN (:num) })`, + MESON_TAC[MEASURE_COUNTABLE_UNIONS_LE_STRONG; REAL_LE_REFL]);; + +let MEASURABLE_COUNTABLE_UNIONS = prove + (`!s:num->real^N->bool B. + (!n. measurable(s n)) /\ + (!n. sum (0..n) (\k. measure(s k)) <= B) + ==> measurable(UNIONS { s(n) | n IN (:num) })`, + MESON_TAC[MEASURE_COUNTABLE_UNIONS_LE; REAL_LE_REFL]);; + +let MEASURE_COUNTABLE_UNIONS_LE_STRONG_GEN = prove + (`!D B. COUNTABLE D /\ + (!d:real^N->bool. d IN D ==> measurable d) /\ + (!D'. D' SUBSET D /\ FINITE D' ==> measure(UNIONS D') <= B) + ==> measurable(UNIONS D) /\ measure(UNIONS D) <= B`, + REPEAT GEN_TAC THEN + ASM_CASES_TAC `D:(real^N->bool)->bool = {}` THENL + [ASM_SIMP_TAC[UNIONS_0; MEASURABLE_EMPTY; SUBSET_EMPTY] THEN + MESON_TAC[FINITE_EMPTY]; + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + MP_TAC(ISPEC `D:(real^N->bool)->bool` COUNTABLE_AS_IMAGE) THEN + ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `d:num->real^N->bool` SUBST1_TAC) THEN + REWRITE_TAC[IMP_CONJ; FORALL_IN_IMAGE; FORALL_SUBSET_IMAGE] THEN + REWRITE_TAC[IN_UNIV; SUBSET_UNIV] THEN REPEAT DISCH_TAC THEN + ONCE_REWRITE_TAC[GSYM SIMPLE_IMAGE] THEN + MATCH_MP_TAC MEASURE_COUNTABLE_UNIONS_LE_STRONG THEN + ASM_REWRITE_TAC[] THEN X_GEN_TAC `n:num` THEN + FIRST_X_ASSUM(MP_TAC o SPEC `{k:num | k <= n}`) THEN + SIMP_TAC[FINITE_NUMSEG_LE; FINITE_IMAGE] THEN + MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN + REPLICATE_TAC 3 AP_TERM_TAC THEN SET_TAC[]]);; + +let MEASURE_COUNTABLE_UNIONS_LE_GEN = prove + (`!D B. COUNTABLE D /\ + (!d:real^N->bool. d IN D ==> measurable d) /\ + (!D'. D' SUBSET D /\ FINITE D' ==> sum D' (\d. measure d) <= B) + ==> measurable(UNIONS D) /\ measure(UNIONS D) <= B`, + REPEAT GEN_TAC THEN STRIP_TAC THEN + MATCH_MP_TAC MEASURE_COUNTABLE_UNIONS_LE_STRONG_GEN THEN + ASM_REWRITE_TAC[] THEN X_GEN_TAC `D':(real^N->bool)->bool` THEN + STRIP_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC `D':(real^N->bool)->bool`) THEN + ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] REAL_LE_TRANS) THEN + MATCH_MP_TAC MEASURE_UNIONS_LE THEN ASM SET_TAC[]);; + +let MEASURABLE_COUNTABLE_INTERS = prove + (`!s:num->real^N->bool. + (!n. measurable(s n)) + ==> measurable(INTERS { s(n) | n IN (:num) })`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN `INTERS { s(n):real^N->bool | n IN (:num) } = + s 0 DIFF (UNIONS {s 0 DIFF s n | n IN (:num)})` + SUBST1_TAC THENL + [GEN_REWRITE_TAC I [EXTENSION] THEN + REWRITE_TAC[IN_INTERS; IN_DIFF; IN_UNIONS] THEN + REWRITE_TAC[SIMPLE_IMAGE; FORALL_IN_IMAGE; EXISTS_IN_IMAGE] THEN + ASM SET_TAC[]; + ALL_TAC] THEN + MATCH_MP_TAC MEASURABLE_DIFF THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC MEASURABLE_COUNTABLE_UNIONS_STRONG THEN + EXISTS_TAC `measure(s 0:real^N->bool)` THEN + ASM_SIMP_TAC[MEASURABLE_DIFF; LE_0] THEN + GEN_TAC THEN MATCH_MP_TAC MEASURE_SUBSET THEN + ASM_REWRITE_TAC[] THEN CONJ_TAC THENL + [ALL_TAC; + REWRITE_TAC[SUBSET; FORALL_IN_UNIONS; IN_ELIM_THM; IN_DIFF] THEN + MESON_TAC[IN_DIFF]] THEN + ONCE_REWRITE_TAC[GSYM IN_NUMSEG_0] THEN + ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN + ASM_SIMP_TAC[FORALL_IN_IMAGE; FINITE_IMAGE; FINITE_NUMSEG; + MEASURABLE_DIFF; MEASURABLE_UNIONS]);; + +let MEASURABLE_COUNTABLE_INTERS_GEN = prove + (`!D. COUNTABLE D /\ ~(D = {}) /\ + (!d:real^N->bool. d IN D ==> measurable d) + ==> measurable(INTERS D)`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPEC `D:(real^N->bool)->bool` COUNTABLE_AS_IMAGE) THEN + ASM_SIMP_TAC[LEFT_IMP_EXISTS_THM; FORALL_IN_IMAGE; IN_UNIV] THEN + GEN_TAC THEN DISCH_THEN SUBST_ALL_TAC THEN + ONCE_REWRITE_TAC[GSYM SIMPLE_IMAGE] THEN + MATCH_MP_TAC MEASURABLE_COUNTABLE_INTERS THEN ASM SET_TAC[]);; + +let MEASURE_COUNTABLE_UNIONS_APPROACHABLE = prove + (`!D B e. + COUNTABLE D /\ + (!d. d IN D ==> measurable d) /\ + (!D'. D' SUBSET D /\ FINITE D' ==> measure(UNIONS D') <= B) /\ + &0 < e + ==> ?D'. D' SUBSET D /\ FINITE D' /\ + measure(UNIONS D) - e < measure(UNIONS D':real^N->bool)`, + REPEAT GEN_TAC THEN + ASM_CASES_TAC `D:(real^N->bool)->bool = {}` THENL + [DISCH_TAC THEN EXISTS_TAC `{}:(real^N->bool)->bool` THEN + ASM_REWRITE_TAC[EMPTY_SUBSET; FINITE_EMPTY; UNIONS_0; MEASURE_EMPTY] THEN + ASM_REAL_ARITH_TAC; + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + MP_TAC(ISPEC `D:(real^N->bool)->bool` COUNTABLE_AS_IMAGE) THEN + ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `d:num->real^N->bool` SUBST1_TAC) THEN + REWRITE_TAC[IMP_CONJ; FORALL_IN_IMAGE; EXISTS_SUBSET_IMAGE; + FORALL_SUBSET_IMAGE] THEN + REWRITE_TAC[IN_UNIV; SUBSET_UNIV] THEN REPEAT DISCH_TAC THEN + MP_TAC(ISPECL + [`\n. UNIONS(IMAGE (d:num->real^N->bool) {k | k <= n})`; + `B:real`] HAS_MEASURE_NESTED_UNIONS) THEN + REWRITE_TAC[] THEN ANTS_TAC THENL + [ASM_SIMP_TAC[MEASURABLE_UNIONS; FORALL_IN_IMAGE; FINITE_IMAGE; + FINITE_NUMSEG_LE; IN_ELIM_THM] THEN + GEN_TAC THEN MATCH_MP_TAC SUBSET_UNIONS THEN + MATCH_MP_TAC IMAGE_SUBSET THEN + REWRITE_TAC[SUBSET; IN_ELIM_THM] THEN ARITH_TAC; + ALL_TAC] THEN + SUBGOAL_THEN + `UNIONS {UNIONS (IMAGE d {k | k <= n}) | n IN (:num)}:real^N->bool = + UNIONS (IMAGE d (:num))` + SUBST1_TAC THENL + [REWRITE_TAC[UNIONS_IMAGE] THEN REWRITE_TAC[UNIONS_GSPEC] THEN + REWRITE_TAC[IN_UNIV; IN_ELIM_THM; EXTENSION] THEN + MESON_TAC[LE_REFL]; + ALL_TAC] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + REWRITE_TAC[LIM_SEQUENTIALLY; DIST_REAL; GSYM drop; LIFT_DROP] 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] THEN DISCH_TAC THEN + EXISTS_TAC `{k:num | k <= n}` THEN + SIMP_TAC[FINITE_IMAGE; FINITE_NUMSEG_LE] THEN + ASM_SIMP_TAC[REAL_ARITH `abs(x - u) < e /\ &0 < e ==> u - e < x`]]);; + +let HAS_MEASURE_NESTED_INTERS = prove + (`!s:num->real^N->bool. + (!n. measurable(s n)) /\ + (!n. s(SUC n) SUBSET s(n)) + ==> measurable(INTERS {s n | n IN (:num)}) /\ + ((\n. lift(measure (s n))) --> + lift(measure (INTERS {s n | n IN (:num)}))) sequentially`, + GEN_TAC THEN STRIP_TAC THEN + MP_TAC(ISPECL + [`\n. (s:num->real^N->bool) 0 DIFF s n`; `measure(s 0:real^N->bool)`] + HAS_MEASURE_NESTED_UNIONS) THEN + ASM_SIMP_TAC[MEASURABLE_DIFF] THEN ANTS_TAC THENL + [CONJ_TAC THEN X_GEN_TAC `n:num` THENL + [MATCH_MP_TAC MEASURE_SUBSET THEN + ASM_SIMP_TAC[MEASURABLE_DIFF; SUBSET_DIFF] THEN SET_TAC[]; + REPEAT(FIRST_X_ASSUM(MP_TAC o SPEC `n:num`)) THEN SET_TAC[]]; + SUBGOAL_THEN + `UNIONS {s 0 DIFF s n | n IN (:num)} = + s 0 DIFF INTERS {s n :real^N->bool | n IN (:num)}` + (fun th -> REWRITE_TAC[th]) + THENL [REWRITE_TAC[DIFF_INTERS] THEN SET_TAC[]; ALL_TAC] THEN + MATCH_MP_TAC MONO_AND THEN CONJ_TAC THENL + [DISCH_TAC THEN + SUBGOAL_THEN + `measurable(s 0 DIFF (s 0 DIFF INTERS {s n | n IN (:num)}) + :real^N->bool)` + MP_TAC THENL [ASM_SIMP_TAC[MEASURABLE_DIFF]; ALL_TAC] THEN + MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN MATCH_MP_TAC(SET_RULE + `t SUBSET s ==> s DIFF (s DIFF t) = t`) THEN + REWRITE_TAC[SUBSET; INTERS_GSPEC; IN_ELIM_THM] THEN SET_TAC[]; + + MP_TAC(ISPECL [`sequentially`; `lift(measure(s 0:real^N->bool))`] + LIM_CONST) THEN REWRITE_TAC[IMP_IMP] THEN + DISCH_THEN(MP_TAC o MATCH_MP LIM_SUB) THEN + REWRITE_TAC[GSYM LIFT_SUB] THEN MATCH_MP_TAC EQ_IMP THEN + AP_THM_TAC THEN BINOP_TAC THEN REWRITE_TAC[LIFT_EQ; FUN_EQ_THM] THEN + REPEAT GEN_TAC THEN + REWRITE_TAC[REAL_ARITH `s - m:real = n <=> m = s - n`] THEN + MATCH_MP_TAC MEASURE_DIFF_SUBSET THEN + ASM_SIMP_TAC[MEASURABLE_COUNTABLE_INTERS] THENL + [ALL_TAC; SET_TAC[]] THEN + MP_TAC(ISPEC `\m n:num. (s n :real^N->bool) SUBSET (s m)` + TRANSITIVE_STEPWISE_LE) THEN + ASM_REWRITE_TAC[] THEN + ANTS_TAC THENL [SET_TAC[]; MESON_TAC[LE_0]]]]);; + +(* ------------------------------------------------------------------------- *) +(* Measurability of compact and bounded open sets. *) +(* ------------------------------------------------------------------------- *) + +let MEASURABLE_COMPACT = prove + (`!s:real^N->bool. compact s ==> measurable s`, + let lemma = prove + (`!f s:real^N->bool. + (!n. FINITE(f n)) /\ + (!n. s SUBSET UNIONS(f n)) /\ + (!x. ~(x IN s) ==> ?n. ~(x IN UNIONS(f n))) /\ + (!n a. a IN f(SUC n) ==> ?b. b IN f(n) /\ a SUBSET b) /\ + (!n a. a IN f(n) ==> measurable a) + ==> measurable s`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN `!n. UNIONS(f(SUC n):(real^N->bool)->bool) SUBSET UNIONS(f n)` + ASSUME_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + SUBGOAL_THEN `s = INTERS { UNIONS(f n) | n IN (:num) }:real^N->bool` + SUBST1_TAC THENL + [ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN + MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THEN + REWRITE_TAC[SUBSET; IN_INTERS; FORALL_IN_IMAGE; IN_UNIV] THEN + REWRITE_TAC[IN_IMAGE] THEN ASM SET_TAC[]; + MATCH_MP_TAC MEASURABLE_COUNTABLE_INTERS THEN + ASM_REWRITE_TAC[] THEN GEN_TAC THEN + MATCH_MP_TAC MEASURABLE_UNIONS THEN + ASM_MESON_TAC[]]) in + REPEAT STRIP_TAC THEN MATCH_MP_TAC lemma THEN + EXISTS_TAC + `\n. { k | ?u:real^N. (!i. 1 <= i /\ i <= dimindex(:N) + ==> integer(u$i)) /\ + k = { x:real^N | !i. 1 <= i /\ i <= dimindex(:N) + ==> u$i / &2 pow n <= x$i /\ + x$i < (u$i + &1) / &2 pow n } /\ + ~(s INTER k = {})}` THEN + REWRITE_TAC[IN_ELIM_THM] THEN REPEAT CONJ_TAC THENL + [X_GEN_TAC `n:num` THEN + SIMP_TAC[REAL_LE_LDIV_EQ; REAL_LT_RDIV_EQ; REAL_LT_POW2] THEN + SUBGOAL_THEN + `?N. !x:real^N i. x IN s /\ 1 <= i /\ i <= dimindex(:N) + ==> abs(x$i * &2 pow n) < &N` + STRIP_ASSUME_TAC THENL + [FIRST_ASSUM(MP_TAC o MATCH_MP COMPACT_IMP_BOUNDED) THEN + REWRITE_TAC[BOUNDED_POS; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `B:real` THEN STRIP_TAC THEN + MP_TAC(SPEC `B * &2 pow n` (MATCH_MP REAL_ARCH REAL_LT_01)) THEN + MATCH_MP_TAC MONO_EXISTS THEN REWRITE_TAC[REAL_MUL_RID] THEN + X_GEN_TAC `N:num` THEN + REWRITE_TAC[REAL_ABS_MUL; REAL_ABS_POW; REAL_ABS_NUM] THEN + SIMP_TAC[GSYM REAL_LT_RDIV_EQ; REAL_LT_POW2] THEN + ASM_MESON_TAC[COMPONENT_LE_NORM; REAL_LE_TRANS; REAL_LET_TRANS]; + ALL_TAC] THEN + MATCH_MP_TAC FINITE_SUBSET THEN + EXISTS_TAC + `IMAGE (\u. {x | !i. 1 <= i /\ i <= dimindex(:N) + ==> (u:real^N)$i <= (x:real^N)$i * &2 pow n /\ + x$i * &2 pow n < u$i + &1}) + {u | !i. 1 <= i /\ i <= dimindex(:N) ==> integer (u$i) /\ + abs(u$i) <= &N}` THEN + CONJ_TAC THENL + [MATCH_MP_TAC FINITE_IMAGE THEN MATCH_MP_TAC FINITE_CART THEN + REWRITE_TAC[GSYM REAL_BOUNDS_LE; FINITE_INTSEG]; + REWRITE_TAC[SUBSET; IN_ELIM_THM; IN_IMAGE] THEN + X_GEN_TAC `l:real^N->bool` THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `u:real^N` THEN + STRIP_TAC THEN FIRST_X_ASSUM SUBST_ALL_TAC THEN ASM_SIMP_TAC[] THEN + X_GEN_TAC `k:num` THEN STRIP_TAC THEN + MATCH_MP_TAC REAL_LE_REVERSE_INTEGERS THEN + ASM_SIMP_TAC[INTEGER_CLOSED] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN + DISCH_THEN(X_CHOOSE_THEN `x:real^N` MP_TAC) THEN + REWRITE_TAC[IN_INTER; IN_ELIM_THM] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC (MP_TAC o SPEC `k:num`)) THEN + ASM_REWRITE_TAC[] THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`x:real^N`; `k:num`]) THEN + ASM_REWRITE_TAC[] THEN REAL_ARITH_TAC]; + X_GEN_TAC `n:num` THEN REWRITE_TAC[SUBSET; IN_UNIONS; IN_ELIM_THM] THEN + X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN + REWRITE_TAC[LEFT_AND_EXISTS_THM] THEN + ONCE_REWRITE_TAC[SWAP_EXISTS_THM] THEN + EXISTS_TAC `(lambda i. floor(&2 pow n * (x:real^N)$i)):real^N` THEN + ONCE_REWRITE_TAC[TAUT `(a /\ b /\ c) /\ d <=> b /\ a /\ c /\ d`] THEN + REWRITE_TAC[UNWIND_THM2] THEN SIMP_TAC[LAMBDA_BETA; FLOOR] THEN + REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; IN_INTER] THEN + REWRITE_TAC[LEFT_AND_EXISTS_THM] THEN EXISTS_TAC `x:real^N` THEN + ASM_REWRITE_TAC[IN_ELIM_THM] THEN + SIMP_TAC[REAL_LE_LDIV_EQ; REAL_LT_RDIV_EQ; REAL_LT_POW2] THEN + REWRITE_TAC[REAL_MUL_SYM; FLOOR]; + X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN + FIRST_ASSUM(MP_TAC o MATCH_MP COMPACT_IMP_CLOSED) THEN + REWRITE_TAC[closed; open_def] THEN + DISCH_THEN(MP_TAC o SPEC `x:real^N`) THEN + ASM_REWRITE_TAC[IN_DIFF; IN_UNIV] THEN + DISCH_THEN(X_CHOOSE_THEN `e:real` STRIP_ASSUME_TAC) THEN + MP_TAC(SPECL [`inv(&2)`; `e / &(dimindex(:N))`] REAL_ARCH_POW_INV) THEN + ASM_SIMP_TAC[REAL_LT_DIV; REAL_LT_RDIV_EQ; REAL_OF_NUM_LT; + DIMINDEX_GE_1; ARITH_RULE `0 < x <=> 1 <= x`] THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `n:num` THEN DISCH_TAC THEN + REWRITE_TAC[IN_UNIONS; IN_ELIM_THM] THEN + REWRITE_TAC[LEFT_AND_EXISTS_THM] THEN + ONCE_REWRITE_TAC[SWAP_EXISTS_THM] THEN + ONCE_REWRITE_TAC[TAUT `(a /\ b /\ c) /\ d <=> b /\ a /\ c /\ d`] THEN + REWRITE_TAC[UNWIND_THM2] THEN REWRITE_TAC[NOT_EXISTS_THM] THEN + X_GEN_TAC `u:real^N` THEN REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN + REWRITE_TAC[IN_INTER; IN_ELIM_THM] THEN + DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC o CONJUNCT2) THEN + DISCH_THEN(X_CHOOSE_THEN `y:real^N` + (CONJUNCTS_THEN2 MP_TAC ASSUME_TAC)) THEN + REWRITE_TAC[] THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH + `d < e ==> x <= d ==> x < e`)) THEN + REWRITE_TAC[dist] THEN + W(MP_TAC o PART_MATCH lhand NORM_LE_L1 o lhand o snd) THEN + MATCH_MP_TAC(REAL_ARITH `a <= b ==> x <= a ==> x <= b`) THEN + GEN_REWRITE_TAC (funpow 3 RAND_CONV) [GSYM CARD_NUMSEG_1] THEN + ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN MATCH_MP_TAC SUM_BOUND THEN + SIMP_TAC[FINITE_NUMSEG; IN_NUMSEG; VECTOR_SUB_COMPONENT] THEN + X_GEN_TAC `k:num` THEN STRIP_TAC THEN + REPEAT(FIRST_X_ASSUM(MP_TAC o SPEC `k:num`)) THEN + ASM_REWRITE_TAC[real_div; REAL_ADD_RDISTRIB] THEN + REWRITE_TAC[REAL_MUL_LID; GSYM REAL_POW_INV] THEN REAL_ARITH_TAC; + MAP_EVERY X_GEN_TAC [`n:num`; `a:real^N->bool`] THEN + DISCH_THEN(X_CHOOSE_THEN `u:real^N` + (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + DISCH_THEN(CONJUNCTS_THEN2 (ASSUME_TAC o SYM) ASSUME_TAC) THEN + REWRITE_TAC[LEFT_AND_EXISTS_THM] THEN + ONCE_REWRITE_TAC[SWAP_EXISTS_THM] THEN + ONCE_REWRITE_TAC[TAUT `(a /\ b /\ c) /\ d <=> b /\ a /\ c /\ d`] THEN + REWRITE_TAC[UNWIND_THM2] THEN + EXISTS_TAC `(lambda i. floor((u:real^N)$i / &2)):real^N` THEN + ASM_SIMP_TAC[VECTOR_MUL_COMPONENT; LAMBDA_BETA; FLOOR] THEN + MATCH_MP_TAC(SET_RULE `~(s INTER a = {}) /\ a SUBSET b + ==> ~(s INTER b = {}) /\ a SUBSET b`) THEN + ASM_REWRITE_TAC[] THEN EXPAND_TAC "a" THEN REWRITE_TAC[SUBSET] THEN + X_GEN_TAC `x:real^N` THEN REWRITE_TAC[IN_ELIM_THM] THEN + MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `k:num` THEN + DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[real_pow; real_div; REAL_INV_MUL; REAL_MUL_ASSOC] THEN + REWRITE_TAC[GSYM real_div] THEN + SIMP_TAC[REAL_LE_LDIV_EQ; REAL_LT_RDIV_EQ; REAL_LT_POW2] THEN + MP_TAC(SPEC `(u:real^N)$k / &2` FLOOR) THEN + REWRITE_TAC[REAL_ARITH `u / &2 < floor(u / &2) + &1 <=> + u < &2 * floor(u / &2) + &2`] THEN + ASM_SIMP_TAC[REAL_LT_INTEGERS; INTEGER_CLOSED; FLOOR_FRAC] THEN + REAL_ARITH_TAC; + REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`n:num`; `a:real^N->bool`; `u:real^N`] THEN + DISCH_THEN(SUBST1_TAC o CONJUNCT1 o CONJUNCT2) THEN + ONCE_REWRITE_TAC[MEASURABLE_INNER_OUTER] THEN + GEN_TAC THEN DISCH_TAC THEN + EXISTS_TAC `interval(inv(&2 pow n) % u:real^N, + inv(&2 pow n) % (u + vec 1))` THEN + EXISTS_TAC `interval[inv(&2 pow n) % u:real^N, + inv(&2 pow n) % (u + vec 1)]` THEN + REWRITE_TAC[MEASURABLE_INTERVAL; MEASURE_INTERVAL] THEN + ASM_REWRITE_TAC[REAL_SUB_REFL; REAL_ABS_0] THEN + REWRITE_TAC[SUBSET; IN_INTERVAL; IN_ELIM_THM] THEN + CONJ_TAC THEN X_GEN_TAC `y:real^N` THEN + MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `k:num` THEN + DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN + ASM_SIMP_TAC[VECTOR_MUL_COMPONENT; VECTOR_ADD_COMPONENT; + VEC_COMPONENT] THEN + REAL_ARITH_TAC]);; + +let MEASURABLE_OPEN = prove + (`!s:real^N->bool. bounded s /\ open s ==> measurable s`, + REPEAT STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o MATCH_MP BOUNDED_SUBSET_CLOSED_INTERVAL) THEN + REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`a:real^N`; `b:real^N`] THEN DISCH_TAC THEN + FIRST_ASSUM(SUBST1_TAC o MATCH_MP (SET_RULE + `s SUBSET t ==> s = t DIFF (t DIFF s)`)) THEN + MATCH_MP_TAC MEASURABLE_DIFF THEN + REWRITE_TAC[MEASURABLE_INTERVAL] THEN + MATCH_MP_TAC MEASURABLE_COMPACT THEN + SIMP_TAC[COMPACT_EQ_BOUNDED_CLOSED; BOUNDED_DIFF; BOUNDED_INTERVAL] THEN + MATCH_MP_TAC CLOSED_DIFF THEN ASM_REWRITE_TAC[CLOSED_INTERVAL]);; + +let MEASURE_OPEN_POS_LT = prove + (`!s. open s /\ bounded s /\ ~(s = {}) ==> &0 < measure s`, + MESON_TAC[OPEN_NOT_NEGLIGIBLE; MEASURABLE_MEASURE_POS_LT; MEASURABLE_OPEN]);; + +let MEASURABLE_CLOSURE = prove + (`!s. bounded s ==> measurable(closure s)`, + SIMP_TAC[MEASURABLE_COMPACT; COMPACT_EQ_BOUNDED_CLOSED; CLOSED_CLOSURE; + BOUNDED_CLOSURE]);; + +let MEASURABLE_INTERIOR = prove + (`!s. bounded s ==> measurable(interior s)`, + SIMP_TAC[MEASURABLE_OPEN; OPEN_INTERIOR; BOUNDED_INTERIOR]);; + +let MEASURABLE_FRONTIER = prove + (`!s:real^N->bool. bounded s ==> measurable(frontier s)`, + REPEAT STRIP_TAC THEN REWRITE_TAC[frontier] THEN + MATCH_MP_TAC MEASURABLE_DIFF THEN + ASM_SIMP_TAC[MEASURABLE_CLOSURE; MEASURABLE_INTERIOR] THEN + MATCH_MP_TAC SUBSET_TRANS THEN EXISTS_TAC `s:real^N->bool` THEN + REWRITE_TAC[INTERIOR_SUBSET; CLOSURE_SUBSET]);; + +let MEASURE_FRONTIER = prove + (`!s:real^N->bool. + bounded s + ==> measure(frontier s) = measure(closure s) - measure(interior s)`, + REPEAT STRIP_TAC THEN REWRITE_TAC[frontier] THEN + MATCH_MP_TAC MEASURE_DIFF_SUBSET THEN + ASM_SIMP_TAC[MEASURABLE_CLOSURE; MEASURABLE_INTERIOR] THEN + MATCH_MP_TAC SUBSET_TRANS THEN EXISTS_TAC `s:real^N->bool` THEN + REWRITE_TAC[INTERIOR_SUBSET; CLOSURE_SUBSET]);; + +let MEASURE_CLOSURE = prove + (`!s:real^N->bool. + bounded s /\ negligible(frontier s) + ==> measure(closure s) = measure s`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC MEASURE_NEGLIGIBLE_SYMDIFF THEN + ASM_SIMP_TAC[MEASURABLE_CLOSURE] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + NEGLIGIBLE_SUBSET)) THEN + MP_TAC(ISPEC `s:real^N->bool` INTERIOR_SUBSET) THEN + MP_TAC(ISPEC `s:real^N->bool` CLOSURE_SUBSET) THEN + REWRITE_TAC[frontier] THEN SET_TAC[]);; + +let MEASURE_INTERIOR = prove + (`!s:real^N->bool. + bounded s /\ negligible(frontier s) + ==> measure(interior s) = measure s`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC MEASURE_NEGLIGIBLE_SYMDIFF THEN + ASM_SIMP_TAC[MEASURABLE_INTERIOR] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + NEGLIGIBLE_SUBSET)) THEN + MP_TAC(ISPEC `s:real^N->bool` INTERIOR_SUBSET) THEN + MP_TAC(ISPEC `s:real^N->bool` CLOSURE_SUBSET) THEN + REWRITE_TAC[frontier] THEN SET_TAC[]);; + +let MEASURABLE_JORDAN = prove + (`!s:real^N->bool. bounded s /\ negligible(frontier s) ==> measurable s`, + REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[MEASURABLE_INNER_OUTER] THEN + GEN_TAC THEN DISCH_TAC THEN + EXISTS_TAC `interior(s):real^N->bool` THEN + EXISTS_TAC `closure(s):real^N->bool` THEN + ASM_SIMP_TAC[MEASURABLE_INTERIOR; MEASURABLE_CLOSURE] THEN + REWRITE_TAC[INTERIOR_SUBSET; CLOSURE_SUBSET] THEN + ONCE_REWRITE_TAC[REAL_ABS_SUB] THEN + ASM_SIMP_TAC[GSYM MEASURE_FRONTIER; REAL_ABS_NUM; MEASURE_EQ_0]);; + +let HAS_MEASURE_ELEMENTARY = prove + (`!d s. d division_of s ==> s has_measure (sum d content)`, + REPEAT STRIP_TAC THEN REWRITE_TAC[has_measure] THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP DIVISION_OF_FINITE) THEN + ASM_SIMP_TAC[LIFT_SUM] THEN + MATCH_MP_TAC HAS_INTEGRAL_COMBINE_DIVISION THEN + ASM_REWRITE_TAC[o_THM] THEN REWRITE_TAC[GSYM has_measure] THEN + ASM_MESON_TAC[HAS_MEASURE_INTERVAL; division_of]);; + +let MEASURABLE_ELEMENTARY = prove + (`!d s. d division_of s ==> measurable s`, + REWRITE_TAC[measurable] THEN MESON_TAC[HAS_MEASURE_ELEMENTARY]);; + +let MEASURE_ELEMENTARY = prove + (`!d s. d division_of s ==> measure s = sum d content`, + MESON_TAC[HAS_MEASURE_ELEMENTARY; MEASURE_UNIQUE]);; + +let MEASURABLE_INTER_INTERVAL = prove + (`!s a b:real^N. measurable s ==> measurable (s INTER interval[a,b])`, + SIMP_TAC[MEASURABLE_INTER; MEASURABLE_INTERVAL]);; + +let MEASURABLE_INSIDE = prove + (`!s:real^N->bool. compact s ==> measurable(inside s)`, + SIMP_TAC[MEASURABLE_OPEN; BOUNDED_INSIDE; COMPACT_IMP_CLOSED; + OPEN_INSIDE; COMPACT_IMP_BOUNDED]);; + +(* ------------------------------------------------------------------------- *) +(* A nice lemma for negligibility proofs. *) +(* ------------------------------------------------------------------------- *) + +let STARLIKE_NEGLIGIBLE_BOUNDED_MEASURABLE = prove + (`!s. measurable s /\ bounded s /\ + (!c x:real^N. &0 <= c /\ x IN s /\ (c % x) IN s ==> c = &1) + ==> negligible s`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN `~(&0 < measure(s:real^N->bool))` + (fun th -> ASM_MESON_TAC[th; MEASURABLE_MEASURE_POS_LT]) THEN + DISCH_TAC THEN + MP_TAC(SPEC `(vec 0:real^N) INSERT s` + BOUNDED_SUBSET_CLOSED_INTERVAL_SYMMETRIC) THEN + ASM_SIMP_TAC[BOUNDED_INSERT; COMPACT_IMP_BOUNDED; NOT_EXISTS_THM] THEN + X_GEN_TAC `a:real^N` THEN REWRITE_TAC[INSERT_SUBSET] THEN STRIP_TAC THEN + SUBGOAL_THEN + `?N. EVEN N /\ &0 < &N /\ + measure(interval[--a:real^N,a]) + < (&N * measure(s:real^N->bool)) / &4 pow dimindex (:N)` + STRIP_ASSUME_TAC THENL + [FIRST_ASSUM(MP_TAC o SPEC + `measure(interval[--a:real^N,a]) * &4 pow (dimindex(:N))` o + MATCH_MP REAL_ARCH) THEN + SIMP_TAC[REAL_LT_RDIV_EQ; REAL_POW_LT; REAL_OF_NUM_LT; ARITH] THEN + SIMP_TAC[GSYM REAL_LT_LDIV_EQ; ASSUME `&0 < measure(s:real^N->bool)`] THEN + DISCH_THEN(X_CHOOSE_THEN `N:num` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `2 * (N DIV 2 + 1)` THEN REWRITE_TAC[EVEN_MULT; ARITH] THEN + CONJ_TAC THENL [ARITH_TAC; ALL_TAC] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH + `x < a ==> a <= b ==> x < b`)) THEN + REWRITE_TAC[REAL_OF_NUM_LE] THEN ARITH_TAC; + ALL_TAC] THEN + MP_TAC(ISPECL [`UNIONS (IMAGE (\m. IMAGE (\x:real^N. (&m / &N) % x) s) + (1..N))`; + `interval[--a:real^N,a]`] MEASURE_SUBSET) THEN + MP_TAC(ISPECL [`measure:(real^N->bool)->real`; + `IMAGE (\m. IMAGE (\x:real^N. (&m / &N) % x) s) (1..N)`] + HAS_MEASURE_DISJOINT_UNIONS) THEN + SIMP_TAC[FINITE_IMAGE; FINITE_NUMSEG; IMP_CONJ] THEN + REWRITE_TAC[RIGHT_FORALL_IMP_THM; FORALL_IN_IMAGE] THEN ANTS_TAC THENL + [REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM HAS_MEASURE_MEASURE] THEN + MATCH_MP_TAC MEASURABLE_SCALING THEN ASM_REWRITE_TAC[]; + ALL_TAC] THEN + REWRITE_TAC[RIGHT_IMP_FORALL_THM; IMP_IMP] THEN + ONCE_REWRITE_TAC[TAUT `(a /\ b) /\ ~c ==> d <=> a /\ b /\ ~d ==> c`] THEN + SUBGOAL_THEN + `!m n. m IN 1..N /\ n IN 1..N /\ + ~(DISJOINT (IMAGE (\x:real^N. &m / &N % x) s) + (IMAGE (\x. &n / &N % x) s)) + ==> m = n` + ASSUME_TAC THENL + [MAP_EVERY X_GEN_TAC [`m:num`; `n:num`] THEN + REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + REWRITE_TAC[DISJOINT; GSYM MEMBER_NOT_EMPTY] THEN + REWRITE_TAC[EXISTS_IN_IMAGE; IN_INTER] THEN + DISCH_THEN(X_CHOOSE_THEN `x:real^N` + (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + REWRITE_TAC[IN_IMAGE] THEN + DISCH_THEN(X_CHOOSE_THEN `y:real^N` + (CONJUNCTS_THEN2 MP_TAC ASSUME_TAC)) THEN + DISCH_THEN(MP_TAC o AP_TERM `(%) (&N / &m) :real^N->real^N`) THEN + SUBGOAL_THEN `~(&N = &0) /\ ~(&m = &0)` STRIP_ASSUME_TAC THENL + [REWRITE_TAC[REAL_OF_NUM_EQ] THEN + REPEAT(FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_NUMSEG])) THEN + ARITH_TAC; + ALL_TAC] THEN + FIRST_X_ASSUM(ASSUME_TAC o GEN_REWRITE_RULE (BINDER_CONV o BINDER_CONV) + [GSYM CONTRAPOS_THM]) THEN + ASM_SIMP_TAC[VECTOR_MUL_ASSOC; REAL_FIELD + `~(x = &0) /\ ~(y = &0) ==> x / y * y / x = &1`] THEN + ASM_SIMP_TAC[REAL_FIELD + `~(x = &0) /\ ~(y = &0) ==> x / y * z / x = z / y`] THEN + REWRITE_TAC[VECTOR_MUL_LID] THEN DISCH_THEN SUBST_ALL_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`&n / &m`; `y:real^N`]) THEN + ASM_SIMP_TAC[REAL_LE_DIV; REAL_POS; REAL_FIELD + `~(y = &0) ==> (x / y = &1 <=> x = y)`] THEN + REWRITE_TAC[REAL_OF_NUM_EQ; EQ_SYM_EQ]; + ALL_TAC] THEN + ANTS_TAC THENL [ASM_MESON_TAC[]; DISCH_TAC] THEN + REWRITE_TAC[NOT_IMP] THEN REPEAT CONJ_TAC THENL + [REWRITE_TAC[measurable] THEN ASM_MESON_TAC[]; + REWRITE_TAC[MEASURABLE_INTERVAL]; + REWRITE_TAC[UNIONS_SUBSET; FORALL_IN_IMAGE] THEN + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE] THEN + X_GEN_TAC `n:num` THEN DISCH_TAC THEN X_GEN_TAC `x:real^N` THEN + DISCH_TAC THEN + MP_TAC(ISPECL [`--a:real^N`; `a:real^N`] CONVEX_INTERVAL) THEN + DISCH_THEN(MP_TAC o REWRITE_RULE[CONVEX_ALT] o CONJUNCT1) THEN + DISCH_THEN(MP_TAC o SPECL [`vec 0:real^N`; `x:real^N`; `&n / &N`]) THEN + ASM_REWRITE_TAC[VECTOR_MUL_RZERO; VECTOR_ADD_LID] THEN + DISCH_THEN MATCH_MP_TAC THEN SIMP_TAC[REAL_LE_DIV; REAL_POS] THEN + CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_NUMSEG]) THEN + DISCH_THEN(MP_TAC o MATCH_MP (ARITH_RULE + `1 <= n /\ n <= N ==> 0 < N /\ n <= N`)) THEN + SIMP_TAC[GSYM REAL_OF_NUM_LE; GSYM REAL_OF_NUM_LT; REAL_LE_LDIV_EQ] THEN + SIMP_TAC[REAL_MUL_LID]; + ALL_TAC] THEN + FIRST_X_ASSUM(SUBST1_TAC o MATCH_MP MEASURE_UNIQUE) THEN + ASM_SIMP_TAC[MEASURE_SCALING; REAL_NOT_LE] THEN + FIRST_X_ASSUM(K ALL_TAC o SPEC `&0`) THEN + MATCH_MP_TAC REAL_LTE_TRANS THEN EXISTS_TAC + `sum (1..N) (measure o (\m. IMAGE (\x:real^N. &m / &N % x) s))` THEN + CONJ_TAC THENL + [ALL_TAC; + MATCH_MP_TAC REAL_EQ_IMP_LE THEN CONV_TAC SYM_CONV THEN + MATCH_MP_TAC SUM_IMAGE THEN REWRITE_TAC[] THEN + REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_REWRITE_TAC[SET_RULE `DISJOINT s s <=> s = {}`; IMAGE_EQ_EMPTY] THEN + DISCH_THEN SUBST_ALL_TAC THEN + ASM_MESON_TAC[REAL_LT_REFL; MEASURE_EMPTY]] THEN + FIRST_X_ASSUM(K ALL_TAC o SPEC `0`) THEN + ASM_SIMP_TAC[o_DEF; MEASURE_SCALING; SUM_RMUL] THEN + FIRST_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH + `x < a ==> a <= b ==> x < b`)) THEN + ASM_SIMP_TAC[REAL_LE_LDIV_EQ; REAL_POW_LT; REAL_OF_NUM_LT; ARITH] THEN + ONCE_REWRITE_TAC[REAL_ARITH `(a * b) * c:real = (a * c) * b`] THEN + ASM_SIMP_TAC[REAL_LE_RMUL_EQ] THEN REWRITE_TAC[GSYM SUM_RMUL] THEN + REWRITE_TAC[GSYM REAL_POW_MUL] THEN + REWRITE_TAC[REAL_ABS_DIV; REAL_ABS_NUM] THEN + FIRST_X_ASSUM(X_CHOOSE_THEN `M:num` SUBST_ALL_TAC o + GEN_REWRITE_RULE I [EVEN_EXISTS]) THEN + REWRITE_TAC[GSYM REAL_OF_NUM_MUL] THEN + RULE_ASSUM_TAC(REWRITE_RULE[GSYM REAL_OF_NUM_MUL]) THEN + RULE_ASSUM_TAC(REWRITE_RULE[REAL_ARITH `&0 < &2 * x <=> &0 < x`]) THEN + ASM_SIMP_TAC[REAL_FIELD `&0 < y ==> x / (&2 * y) * &4 = x * &2 / y`] THEN + MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `sum(M..(2*M)) (\i. (&i * &2 / &M) pow dimindex (:N))` THEN + CONJ_TAC THENL + [ALL_TAC; + MATCH_MP_TAC SUM_SUBSET_SIMPLE THEN + SIMP_TAC[REAL_POW_LE; REAL_LE_MUL; REAL_LE_DIV; REAL_POS] THEN + REWRITE_TAC[IN_NUMSEG; FINITE_NUMSEG; SUBSET] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [REAL_OF_NUM_LT]) THEN + ARITH_TAC] THEN + MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `sum(M..(2*M)) (\i. &2)` THEN CONJ_TAC THENL + [REWRITE_TAC[SUM_CONST_NUMSEG] THEN + REWRITE_TAC[ARITH_RULE `(2 * M + 1) - M = M + 1`] THEN + REWRITE_TAC[GSYM REAL_OF_NUM_ADD] THEN REAL_ARITH_TAC; + ALL_TAC] THEN + MATCH_MP_TAC SUM_LE THEN REWRITE_TAC[FINITE_NUMSEG; IN_NUMSEG] THEN + X_GEN_TAC `n:num` THEN STRIP_TAC THEN + MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC `&2 pow (dimindex(:N))` THEN + CONJ_TAC THENL + [GEN_REWRITE_TAC LAND_CONV [GSYM REAL_POW_1] THEN + MATCH_MP_TAC REAL_POW_MONO THEN REWRITE_TAC[DIMINDEX_GE_1] THEN + ARITH_TAC; + ALL_TAC] THEN + MATCH_MP_TAC REAL_POW_LE2 THEN + REWRITE_TAC[REAL_POS; ARITH; real_div; REAL_MUL_ASSOC] THEN + ASM_SIMP_TAC[GSYM real_div; REAL_LE_RDIV_EQ] THEN + REWRITE_TAC[REAL_OF_NUM_MUL; REAL_OF_NUM_LE] THEN + UNDISCH_TAC `M:num <= n` THEN ARITH_TAC);; + +let STARLIKE_NEGLIGIBLE_LEMMA = prove + (`!s. compact s /\ + (!c x:real^N. &0 <= c /\ x IN s /\ (c % x) IN s ==> c = &1) + ==> negligible s`, + REPEAT STRIP_TAC THEN + MATCH_MP_TAC STARLIKE_NEGLIGIBLE_BOUNDED_MEASURABLE THEN + ASM_MESON_TAC[MEASURABLE_COMPACT; COMPACT_IMP_BOUNDED]);; + +let STARLIKE_NEGLIGIBLE = prove + (`!s a. closed s /\ + (!c x:real^N. &0 <= c /\ (a + x) IN s /\ (a + c % x) IN s ==> c = &1) + ==> negligible s`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC NEGLIGIBLE_TRANSLATION_REV THEN + EXISTS_TAC `--a:real^N` THEN ONCE_REWRITE_TAC[NEGLIGIBLE_ON_INTERVALS] THEN + MAP_EVERY X_GEN_TAC [`u:real^N`; `v:real^N`] THEN + MATCH_MP_TAC STARLIKE_NEGLIGIBLE_LEMMA THEN CONJ_TAC THENL + [MATCH_MP_TAC CLOSED_INTER_COMPACT THEN REWRITE_TAC[COMPACT_INTERVAL] THEN + ASM_SIMP_TAC[CLOSED_TRANSLATION]; + REWRITE_TAC[IN_IMAGE; IN_INTER] THEN + ONCE_REWRITE_TAC[VECTOR_ARITH `x:real^N = --a + y <=> y = a + x`] THEN + REWRITE_TAC[UNWIND_THM2] THEN ASM MESON_TAC[]]);; + +let STARLIKE_NEGLIGIBLE_STRONG = prove + (`!s a. closed s /\ + (!c x:real^N. &0 <= c /\ c < &1 /\ (a + x) IN s + ==> ~((a + c % x) IN s)) + ==> negligible s`, + REPEAT GEN_TAC THEN STRIP_TAC THEN MATCH_MP_TAC STARLIKE_NEGLIGIBLE THEN + EXISTS_TAC `a:real^N` THEN ASM_REWRITE_TAC[] THEN + MAP_EVERY X_GEN_TAC [`c:real`; `x:real^N`] THEN STRIP_TAC THEN + MATCH_MP_TAC(REAL_ARITH `~(x < y) /\ ~(y < x) ==> x = y`) THEN + STRIP_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`inv c:real`; `c % x:real^N`]) THEN + ASM_REWRITE_TAC[REAL_LE_INV_EQ; VECTOR_MUL_ASSOC] THEN + ASM_SIMP_TAC[REAL_MUL_LINV; REAL_ARITH `&1 < c ==> ~(c = &0)`] THEN + ASM_REWRITE_TAC[VECTOR_MUL_LID] THEN + GEN_REWRITE_TAC RAND_CONV [GSYM REAL_INV_1] THEN + MATCH_MP_TAC REAL_LT_INV2 THEN ASM_REWRITE_TAC[REAL_LT_01]);; + +(* ------------------------------------------------------------------------- *) +(* In particular. *) +(* ------------------------------------------------------------------------- *) + +let NEGLIGIBLE_HYPERPLANE = prove + (`!a b. ~(a = vec 0 /\ b = &0) ==> negligible {x:real^N | a dot x = b}`, + REPEAT GEN_TAC THEN ASM_CASES_TAC `a:real^N = vec 0` THEN + ASM_SIMP_TAC[DOT_LZERO; SET_RULE `{x | F} = {}`; NEGLIGIBLE_EMPTY] THEN + MATCH_MP_TAC STARLIKE_NEGLIGIBLE THEN + SUBGOAL_THEN `?x:real^N. ~(a dot x = b)` MP_TAC THENL + [MATCH_MP_TAC(MESON[] `!a:real^N. P a \/ P(--a) ==> ?x. P x`) THEN + EXISTS_TAC `a:real^N` THEN REWRITE_TAC[DOT_RNEG] THEN + MATCH_MP_TAC(REAL_ARITH `~(a = &0) ==> ~(a = b) \/ ~(--a = b)`) THEN + ASM_REWRITE_TAC[DOT_EQ_0]; + ALL_TAC] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `c:real^N` THEN DISCH_TAC THEN + REWRITE_TAC[CLOSED_HYPERPLANE; IN_ELIM_THM; DOT_RADD; DOT_RMUL] THEN + MAP_EVERY X_GEN_TAC [`t:real`; `y:real^N`] THEN + DISCH_THEN(MP_TAC o MATCH_MP (REAL_ARITH + `&0 <= t /\ ac + ay = b /\ ac + t * ay = b + ==> ((ay = &0 ==> ac = b) /\ (t - &1) * ay = &0)`)) THEN + ASM_SIMP_TAC[REAL_ENTIRE; REAL_SUB_0] THEN CONV_TAC TAUT);; + +let NEGLIGIBLE_LOWDIM = prove + (`!s:real^N->bool. dim(s) < dimindex(:N) ==> negligible s`, + GEN_TAC THEN DISCH_THEN(MP_TAC o MATCH_MP LOWDIM_SUBSET_HYPERPLANE) THEN + DISCH_THEN(X_CHOOSE_THEN `a:real^N` STRIP_ASSUME_TAC) THEN + MATCH_MP_TAC NEGLIGIBLE_SUBSET THEN + EXISTS_TAC `span(s):real^N->bool` THEN REWRITE_TAC[SPAN_INC] THEN + MATCH_MP_TAC NEGLIGIBLE_SUBSET THEN + EXISTS_TAC `{x:real^N | a dot x = &0}` THEN + ASM_SIMP_TAC[NEGLIGIBLE_HYPERPLANE]);; + +let NEGLIGIBLE_AFFINE_HULL = prove + (`!s:real^N->bool. + FINITE s /\ CARD(s) <= dimindex(:N) ==> negligible(affine hull s)`, + REWRITE_TAC[IMP_CONJ] THEN MATCH_MP_TAC FINITE_INDUCT_STRONG THEN + REWRITE_TAC[AFFINE_HULL_EMPTY; NEGLIGIBLE_EMPTY] THEN + SUBGOAL_THEN + `!x s:real^N->bool n. + ~(x IN s) /\ (x INSERT s) HAS_SIZE n /\ n <= dimindex(:N) + ==> negligible(affine hull(x INSERT s))` + (fun th -> MESON_TAC[th; HAS_SIZE; FINITE_INSERT]) THEN + X_GEN_TAC `orig:real^N` THEN GEOM_ORIGIN_TAC `orig:real^N` THEN + SIMP_TAC[AFFINE_HULL_EQ_SPAN; IN_INSERT; SPAN_INSERT_0; HULL_INC] THEN + REWRITE_TAC[HAS_SIZE; FINITE_INSERT; IMP_CONJ] THEN + SIMP_TAC[CARD_CLAUSES] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC NEGLIGIBLE_LOWDIM THEN + MATCH_MP_TAC LET_TRANS THEN EXISTS_TAC `CARD(s:real^N->bool)` THEN + ASM_SIMP_TAC[DIM_LE_CARD; DIM_SPAN] THEN ASM_ARITH_TAC);; + +let NEGLIGIBLE_AFFINE_HULL_1 = prove + (`!a:real^1. negligible (affine hull {a})`, + REPEAT GEN_TAC THEN MATCH_MP_TAC NEGLIGIBLE_AFFINE_HULL THEN + SIMP_TAC[FINITE_INSERT; CARD_CLAUSES; FINITE_EMPTY; DIMINDEX_1] THEN + ARITH_TAC);; + +let NEGLIGIBLE_AFFINE_HULL_2 = prove + (`!a b:real^2. negligible (affine hull {a,b})`, + REPEAT GEN_TAC THEN MATCH_MP_TAC NEGLIGIBLE_AFFINE_HULL THEN + SIMP_TAC[FINITE_INSERT; CARD_CLAUSES; FINITE_EMPTY; DIMINDEX_2] THEN + ARITH_TAC);; + +let NEGLIGIBLE_AFFINE_HULL_3 = prove + (`!a b c:real^3. negligible (affine hull {a,b,c})`, + REPEAT GEN_TAC THEN MATCH_MP_TAC NEGLIGIBLE_AFFINE_HULL THEN + SIMP_TAC[FINITE_INSERT; CARD_CLAUSES; FINITE_EMPTY; DIMINDEX_3] THEN + ARITH_TAC);; + +let NEGLIGIBLE_CONVEX_HULL = prove + (`!s:real^N->bool. + FINITE s /\ CARD(s) <= dimindex(:N) ==> negligible(convex hull s)`, + REPEAT GEN_TAC THEN + DISCH_THEN(MP_TAC o MATCH_MP NEGLIGIBLE_AFFINE_HULL) THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] NEGLIGIBLE_SUBSET) THEN + REWRITE_TAC[CONVEX_HULL_SUBSET_AFFINE_HULL]);; + +let NEGLIGIBLE_CONVEX_HULL_1 = prove + (`!a:real^1. negligible (convex hull {a})`, + REPEAT GEN_TAC THEN MATCH_MP_TAC NEGLIGIBLE_CONVEX_HULL THEN + SIMP_TAC[FINITE_INSERT; CARD_CLAUSES; FINITE_EMPTY; DIMINDEX_1] THEN + ARITH_TAC);; + +let NEGLIGIBLE_CONVEX_HULL_2 = prove + (`!a b:real^2. negligible (convex hull {a,b})`, + REPEAT GEN_TAC THEN MATCH_MP_TAC NEGLIGIBLE_CONVEX_HULL THEN + SIMP_TAC[FINITE_INSERT; CARD_CLAUSES; FINITE_EMPTY; DIMINDEX_2] THEN + ARITH_TAC);; + +let NEGLIGIBLE_CONVEX_HULL_3 = prove + (`!a b c:real^3. negligible (convex hull {a,b,c})`, + REPEAT GEN_TAC THEN MATCH_MP_TAC NEGLIGIBLE_CONVEX_HULL THEN + SIMP_TAC[FINITE_INSERT; CARD_CLAUSES; FINITE_EMPTY; DIMINDEX_3] THEN + ARITH_TAC);; + +(* ------------------------------------------------------------------------- *) +(* Measurability of bounded convex sets. *) +(* ------------------------------------------------------------------------- *) + +let NEGLIGIBLE_CONVEX_FRONTIER = prove + (`!s:real^N->bool. convex s ==> negligible(frontier s)`, + SUBGOAL_THEN + `!s:real^N->bool. convex s /\ (vec 0) IN s ==> negligible(frontier s)` + ASSUME_TAC THENL + [ALL_TAC; + X_GEN_TAC `s:real^N->bool` THEN DISCH_TAC THEN + ASM_CASES_TAC `s:real^N->bool = {}` THEN + ASM_REWRITE_TAC[FRONTIER_EMPTY; NEGLIGIBLE_EMPTY] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN + DISCH_THEN(X_CHOOSE_TAC `a:real^N`) THEN + FIRST_X_ASSUM(MP_TAC o SPEC `IMAGE (\x:real^N. --a + x) s`) THEN + ASM_SIMP_TAC[CONVEX_TRANSLATION; IN_IMAGE] THEN + ASM_REWRITE_TAC[UNWIND_THM2; + VECTOR_ARITH `vec 0:real^N = --a + x <=> x = a`] THEN + REWRITE_TAC[FRONTIER_TRANSLATION; NEGLIGIBLE_TRANSLATION_EQ]] THEN + REPEAT STRIP_TAC THEN MP_TAC(ISPEC `s:real^N->bool` DIM_SUBSET_UNIV) THEN + REWRITE_TAC[ARITH_RULE `d:num <= e <=> d < e \/ d = e`] THEN STRIP_TAC THENL + [MATCH_MP_TAC NEGLIGIBLE_SUBSET THEN + EXISTS_TAC `closure s:real^N->bool` THEN + REWRITE_TAC[frontier; SUBSET_DIFF] THEN + MATCH_MP_TAC NEGLIGIBLE_LOWDIM THEN ASM_REWRITE_TAC[DIM_CLOSURE]; + ALL_TAC] THEN + SUBGOAL_THEN `?a:real^N. a IN interior s` CHOOSE_TAC THENL + [X_CHOOSE_THEN `b:real^N->bool` STRIP_ASSUME_TAC + (ISPEC `s:real^N->bool` BASIS_EXISTS) THEN + FIRST_X_ASSUM SUBST_ALL_TAC THEN + MP_TAC(ISPEC `b:real^N->bool` INTERIOR_SIMPLEX_NONEMPTY) THEN + ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC MONO_EXISTS THEN REWRITE_TAC[GSYM SUBSET] THEN + MATCH_MP_TAC SUBSET_INTERIOR THEN MATCH_MP_TAC HULL_MINIMAL THEN + ASM_REWRITE_TAC[INSERT_SUBSET]; + ALL_TAC] THEN + MATCH_MP_TAC STARLIKE_NEGLIGIBLE_STRONG THEN + EXISTS_TAC `a:real^N` THEN REWRITE_TAC[FRONTIER_CLOSED] THEN + REPEAT GEN_TAC THEN STRIP_TAC THEN + REWRITE_TAC[frontier; IN_DIFF; DE_MORGAN_THM] THEN DISJ2_TAC THEN + SIMP_TAC[VECTOR_ARITH + `a + c % x:real^N = (a + x) - (&1 - c) % ((a + x) - a)`] THEN + MATCH_MP_TAC IN_INTERIOR_CLOSURE_CONVEX_SHRINK THEN + RULE_ASSUM_TAC(REWRITE_RULE[frontier; IN_DIFF]) THEN + ASM_REWRITE_TAC[] THEN ASM_REAL_ARITH_TAC);; + +let MEASURABLE_CONVEX = prove + (`!s:real^N->bool. convex s /\ bounded s ==> measurable s`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC MEASURABLE_JORDAN THEN + ASM_SIMP_TAC[NEGLIGIBLE_CONVEX_FRONTIER]);; + +(* ------------------------------------------------------------------------- *) +(* Various special cases. *) +(* ------------------------------------------------------------------------- *) + +let NEGLIGIBLE_SPHERE = prove + (`!a:real^N r. negligible (sphere(a,e))`, + REWRITE_TAC[GSYM FRONTIER_CBALL] THEN + SIMP_TAC[NEGLIGIBLE_CONVEX_FRONTIER; CONVEX_CBALL]);; + +let MEASURABLE_BALL = prove + (`!a r. measurable(ball(a,r))`, + SIMP_TAC[MEASURABLE_OPEN; BOUNDED_BALL; OPEN_BALL]);; + +let MEASURABLE_CBALL = prove + (`!a r. measurable(cball(a,r))`, + SIMP_TAC[MEASURABLE_COMPACT; COMPACT_CBALL]);; + +let MEASURE_BALL_POS = prove + (`!x:real^N e. &0 < e ==> &0 < measure(ball(x,e))`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC MEASURE_OPEN_POS_LT THEN + REWRITE_TAC[OPEN_BALL; BOUNDED_BALL; BALL_EQ_EMPTY] THEN + ASM_REAL_ARITH_TAC);; + +let MEASURE_CBALL_POS = prove + (`!x:real^N e. &0 < e ==> &0 < measure(cball(x,e))`, + MESON_TAC[MEASURE_SUBSET; REAL_LTE_TRANS; MEASURABLE_BALL; MEASURABLE_CBALL; + BALL_SUBSET_CBALL; MEASURE_BALL_POS]);; + +let HAS_INTEGRAL_OPEN_INTERVAL = prove + (`!f a b y. (f has_integral y) (interval(a,b)) <=> + (f has_integral y) (interval[a,b])`, + REPEAT GEN_TAC THEN REWRITE_TAC[GSYM INTERIOR_CLOSED_INTERVAL] THEN + MATCH_MP_TAC HAS_INTEGRAL_INTERIOR THEN + MATCH_MP_TAC NEGLIGIBLE_CONVEX_FRONTIER THEN + REWRITE_TAC[CONVEX_INTERVAL]);; + +let INTEGRABLE_ON_OPEN_INTERVAL = prove + (`!f a b. f integrable_on interval(a,b) <=> + f integrable_on interval[a,b]`, + REWRITE_TAC[integrable_on; HAS_INTEGRAL_OPEN_INTERVAL]);; + +let INTEGRAL_OPEN_INTERVAL = prove + (`!f a b. integral(interval(a,b)) f = integral(interval[a,b]) f`, + REWRITE_TAC[integral; HAS_INTEGRAL_OPEN_INTERVAL]);; + +(* ------------------------------------------------------------------------- *) +(* Crude upper bounds for measure of balls. *) +(* ------------------------------------------------------------------------- *) + +let MEASURE_CBALL_BOUND = prove + (`!x:real^N d. + &0 <= d ==> measure(cball(x,d)) <= (&2 * d) pow (dimindex(:N))`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `measure(interval[x - d % vec 1:real^N,x + d % vec 1])` THEN + CONJ_TAC THENL + [MATCH_MP_TAC MEASURE_SUBSET THEN + REWRITE_TAC[MEASURABLE_CBALL; MEASURABLE_INTERVAL] THEN + REWRITE_TAC[SUBSET; IN_CBALL; IN_INTERVAL] THEN + REWRITE_TAC[VECTOR_ADD_COMPONENT; VECTOR_SUB_COMPONENT; dist] THEN + REWRITE_TAC[VECTOR_MUL_COMPONENT; VEC_COMPONENT] THEN + X_GEN_TAC `y:real^N` THEN DISCH_TAC THEN + X_GEN_TAC `i:num` THEN STRIP_TAC THEN + MP_TAC(ISPECL [`x - y:real^N`; `i:num`] COMPONENT_LE_NORM) THEN + ASM_REWRITE_TAC[VECTOR_SUB_COMPONENT] THEN ASM_REAL_ARITH_TAC; + SIMP_TAC[MEASURE_INTERVAL; CONTENT_CLOSED_INTERVAL_CASES] THEN + COND_CASES_TAC THEN + ASM_SIMP_TAC[REAL_POW_LE; REAL_LE_MUL; REAL_POS] THEN + REWRITE_TAC[VECTOR_ADD_COMPONENT; VECTOR_SUB_COMPONENT] THEN + REWRITE_TAC[REAL_ARITH `(x + a) - (x - a):real = &2 * a`] THEN + REWRITE_TAC[PRODUCT_CONST_NUMSEG; VECTOR_MUL_COMPONENT; VEC_COMPONENT] THEN + REWRITE_TAC[REAL_MUL_RID; ADD_SUB; REAL_LE_REFL]]);; + +let MEASURE_BALL_BOUND = prove + (`!x:real^N d. + &0 <= d ==> measure(ball(x,d)) <= (&2 * d) pow (dimindex(:N))`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `measure(cball(x:real^N,d))` THEN + ASM_SIMP_TAC[MEASURE_CBALL_BOUND] THEN MATCH_MP_TAC MEASURE_SUBSET THEN + REWRITE_TAC[BALL_SUBSET_CBALL; MEASURABLE_BALL; MEASURABLE_CBALL]);; + +(* ------------------------------------------------------------------------- *) +(* Negligibility of image under non-injective linear map. *) +(* ------------------------------------------------------------------------- *) + +let NEGLIGIBLE_LINEAR_SINGULAR_IMAGE = prove + (`!f:real^N->real^N s. + linear f /\ ~(!x y. f(x) = f(y) ==> x = y) + ==> negligible(IMAGE f s)`, + REPEAT GEN_TAC THEN + DISCH_THEN(MP_TAC o MATCH_MP LINEAR_SINGULAR_IMAGE_HYPERPLANE) THEN + DISCH_THEN(X_CHOOSE_THEN `a:real^N` STRIP_ASSUME_TAC) THEN + MATCH_MP_TAC NEGLIGIBLE_SUBSET THEN + EXISTS_TAC `{x:real^N | a dot x = &0}` THEN + ASM_SIMP_TAC[NEGLIGIBLE_HYPERPLANE]);; + +(* ------------------------------------------------------------------------- *) +(* Some technical lemmas used in the approximation results that follow. *) +(* Proof of the covering lemma is an obvious multidimensional generalization *) +(* of Lemma 3, p65 of Swartz's "Introduction to Gauge Integrals". *) +(* ------------------------------------------------------------------------- *) + +let COVERING_LEMMA = prove + (`!a b:real^N s g. + s SUBSET interval[a,b] /\ ~(interval(a,b) = {}) /\ gauge g + ==> ?d. COUNTABLE d /\ + (!k. k IN d ==> k SUBSET interval[a,b] /\ ~(interior k = {}) /\ + (?c d. k = interval[c,d])) /\ + (!k1 k2. k1 IN d /\ k2 IN d /\ ~(k1 = k2) + ==> interior k1 INTER interior k2 = {}) /\ + (!k. k IN d ==> ?x. x IN (s INTER k) /\ k SUBSET g(x)) /\ + (!u v. interval[u,v] IN d + ==> ?n. !i. 1 <= i /\ i <= dimindex(:N) + ==> v$i - u$i = (b$i - a$i) / &2 pow n) /\ + s SUBSET UNIONS d`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN + `?d. COUNTABLE d /\ + (!k. k IN d ==> k SUBSET interval[a,b] /\ ~(interior k = {}) /\ + (?c d:real^N. k = interval[c,d])) /\ + (!k1 k2. k1 IN d /\ k2 IN d + ==> k1 SUBSET k2 \/ k2 SUBSET k1 \/ + interior k1 INTER interior k2 = {}) /\ + (!x. x IN s ==> ?k. k IN d /\ x IN k /\ k SUBSET g(x)) /\ + (!u v. interval[u,v] IN d + ==> ?n. !i. 1 <= i /\ i <= dimindex(:N) + ==> v$i - u$i = (b$i - a$i) / &2 pow n) /\ + (!k. k IN d ==> FINITE {l | l IN d /\ k SUBSET l})` + ASSUME_TAC THENL + [EXISTS_TAC + `IMAGE (\(n,v). + interval[(lambda i. a$i + &(v$i) / &2 pow n * + ((b:real^N)$i - (a:real^N)$i)):real^N, + (lambda i. a$i + (&(v$i) + &1) / &2 pow n * (b$i - a$i))]) + {n,v | n IN (:num) /\ + v IN {v:num^N | !i. 1 <= i /\ i <= dimindex(:N) + ==> v$i < 2 EXP n}}` THEN + CONJ_TAC THENL + [MATCH_MP_TAC COUNTABLE_IMAGE THEN + MATCH_MP_TAC COUNTABLE_PRODUCT_DEPENDENT THEN + REWRITE_TAC[NUM_COUNTABLE; IN_UNIV] THEN + GEN_TAC THEN MATCH_MP_TAC FINITE_IMP_COUNTABLE THEN + MATCH_MP_TAC FINITE_CART THEN REWRITE_TAC[FINITE_NUMSEG_LT]; + ALL_TAC] THEN + CONJ_TAC THENL + [REWRITE_TAC[FORALL_IN_IMAGE; FORALL_PAIR_THM] THEN + MAP_EVERY X_GEN_TAC [`n:num`; `v:num^N`] THEN + REWRITE_TAC[IN_ELIM_PAIR_THM] THEN + REWRITE_TAC[IN_ELIM_THM; IN_UNIV] THEN DISCH_TAC THEN + REWRITE_TAC[CONJ_ASSOC] THEN CONJ_TAC THENL [ALL_TAC; MESON_TAC[]] THEN + REWRITE_TAC[INTERIOR_CLOSED_INTERVAL] THEN + SIMP_TAC[INTERVAL_NE_EMPTY; SUBSET_INTERVAL; LAMBDA_BETA] THEN + RULE_ASSUM_TAC(REWRITE_RULE[INTERVAL_NE_EMPTY]) THEN + ASM_SIMP_TAC[REAL_LE_LADD; REAL_LE_RMUL_EQ; REAL_SUB_LT; REAL_LE_MUL_EQ; + REAL_LT_LADD; REAL_LT_RMUL_EQ; REAL_LE_ADDR; REAL_ARITH + `a + x * (b - a) <= b <=> &0 <= (&1 - x) * (b - a)`] THEN + SIMP_TAC[REAL_LE_DIV2_EQ; REAL_LT_DIV2_EQ; REAL_LT_POW2] THEN + REWRITE_TAC[REAL_ARITH `x <= x + &1 /\ x < x + &1`] THEN + REWRITE_TAC[REAL_SUB_LE] THEN + SIMP_TAC[REAL_LE_LDIV_EQ; REAL_LE_RDIV_EQ; REAL_LT_POW2] THEN + REWRITE_TAC[REAL_MUL_LZERO; REAL_POS; REAL_MUL_LID] THEN + SIMP_TAC[REAL_OF_NUM_ADD; REAL_OF_NUM_POW; REAL_OF_NUM_LE] THEN + ASM_SIMP_TAC[ARITH_RULE `x + 1 <= y <=> x < y`; REAL_LT_IMP_LE]; + ALL_TAC] THEN + CONJ_TAC THENL + [ONCE_REWRITE_TAC[IMP_CONJ] THEN + REWRITE_TAC[FORALL_IN_IMAGE; FORALL_PAIR_THM; RIGHT_FORALL_IMP_THM] THEN + REWRITE_TAC[IN_ELIM_PAIR_THM; IN_UNIV] THEN REWRITE_TAC[IN_ELIM_THM] THEN + REWRITE_TAC[RIGHT_IMP_FORALL_THM] THEN + GEN_REWRITE_TAC BINDER_CONV [SWAP_FORALL_THM] THEN + MATCH_MP_TAC WLOG_LE THEN CONJ_TAC THENL + [REPEAT GEN_TAC THEN + GEN_REWRITE_TAC RAND_CONV [SWAP_FORALL_THM] THEN + REPEAT(AP_TERM_TAC THEN ABS_TAC) THEN SET_TAC[]; + ALL_TAC] THEN + MAP_EVERY X_GEN_TAC [`m:num`; `n:num`] THEN DISCH_TAC THEN + MAP_EVERY X_GEN_TAC [`v:num^N`; `w:num^N`] THEN REPEAT DISCH_TAC THEN + REWRITE_TAC[INTERIOR_CLOSED_INTERVAL; SUBSET_INTERVAL] THEN + SIMP_TAC[DISJOINT_INTERVAL; LAMBDA_BETA] THEN + MATCH_MP_TAC(TAUT `p \/ q \/ r ==> (a ==> p) \/ (b ==> q) \/ r`) THEN + ONCE_REWRITE_TAC[TAUT `a /\ b /\ c <=> ~(a /\ b ==> ~c)`] THEN + RULE_ASSUM_TAC(REWRITE_RULE[INTERVAL_NE_EMPTY]) THEN + ASM_SIMP_TAC[REAL_LE_LADD; REAL_LE_RMUL_EQ; REAL_SUB_LT; LAMBDA_BETA] THEN + REWRITE_TAC[NOT_IMP; REAL_LE_LADD] THEN + ASM_SIMP_TAC[REAL_LE_DIV2_EQ; REAL_LT_POW2] THEN + REWRITE_TAC[REAL_ARITH `~(x + &1 <= x)`] THEN DISJ2_TAC THEN + MATCH_MP_TAC(MESON[] + `(!i. ~P i ==> Q i) ==> (!i. Q i) \/ (?i. P i)`) THEN + X_GEN_TAC `i:num` THEN + DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN + ASM_REWRITE_TAC[DE_MORGAN_THM; REAL_NOT_LE] THEN + UNDISCH_TAC `m:num <= n` THEN REWRITE_TAC[LE_EXISTS] THEN + DISCH_THEN(X_CHOOSE_THEN `p:num` SUBST1_TAC) THEN + ONCE_REWRITE_TAC[ADD_SYM] THEN + REWRITE_TAC[REAL_POW_ADD; real_div; REAL_INV_MUL] THEN + REWRITE_TAC[REAL_MUL_ASSOC] THEN REWRITE_TAC[GSYM real_div] THEN + ASM_SIMP_TAC[REAL_LE_DIV2_EQ; REAL_LT_POW2; REAL_LT_DIV2_EQ] THEN + ASM_SIMP_TAC[REAL_LE_LDIV_EQ; REAL_LE_RDIV_EQ; REAL_LT_POW2; + REAL_LT_LDIV_EQ; REAL_LT_RDIV_EQ] THEN + SIMP_TAC[REAL_LT_INTEGERS; INTEGER_CLOSED] THEN REAL_ARITH_TAC; + ALL_TAC] THEN + CONJ_TAC THENL + [X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN + SUBGOAL_THEN + `?e. &0 < e /\ !y. (!i. 1 <= i /\ i <= dimindex(:N) + ==> abs((x:real^N)$i - (y:real^N)$i) <= e) + ==> y IN g(x)` + STRIP_ASSUME_TAC THENL + [FIRST_ASSUM(MP_TAC o SPEC `x:real^N` o GEN_REWRITE_RULE I [gauge]) THEN + STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [OPEN_CONTAINS_BALL]) THEN + DISCH_THEN(MP_TAC o SPEC `x:real^N`) THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `e:real` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `e / &2 / &(dimindex(:N))` THEN + ASM_SIMP_TAC[REAL_LT_DIV; REAL_OF_NUM_LT; LE_1; DIMINDEX_GE_1; + ARITH] THEN + X_GEN_TAC `y:real^N` THEN STRIP_TAC THEN + MATCH_MP_TAC(SET_RULE `!s. s SUBSET t /\ x IN s ==> x IN t`) THEN + EXISTS_TAC `ball(x:real^N,e)` THEN ASM_REWRITE_TAC[IN_BALL] THEN + MATCH_MP_TAC(REAL_ARITH `&0 < e /\ x <= e / &2 ==> x < e`) THEN + ASM_REWRITE_TAC[dist] THEN MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `sum(1..dimindex(:N)) (\i. abs((x - y:real^N)$i))` THEN + REWRITE_TAC[NORM_LE_L1] THEN MATCH_MP_TAC SUM_BOUND_GEN THEN + ASM_SIMP_TAC[IN_NUMSEG; FINITE_NUMSEG; NUMSEG_EMPTY; NOT_LT; + DIMINDEX_GE_1; VECTOR_SUB_COMPONENT; CARD_NUMSEG_1]; + ALL_TAC] THEN + REWRITE_TAC[EXISTS_IN_IMAGE; EXISTS_PAIR_THM; IN_ELIM_PAIR_THM] THEN + MP_TAC(SPECL [`&1 / &2`; `e / norm(b - a:real^N)`] + REAL_ARCH_POW_INV) THEN + SUBGOAL_THEN `&0 < norm(b - a:real^N)` ASSUME_TAC THENL + [ASM_MESON_TAC[VECTOR_SUB_EQ; NORM_POS_LT; INTERVAL_SING]; ALL_TAC] THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN ASM_SIMP_TAC[REAL_LT_DIV] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `n:num` THEN + REWRITE_TAC[real_div; REAL_MUL_LID; REAL_POW_INV] THEN DISCH_TAC THEN + SIMP_TAC[IN_ELIM_THM; IN_INTERVAL; SUBSET; LAMBDA_BETA] THEN + MATCH_MP_TAC(MESON[] + `(!x. Q x ==> R x) /\ (?x. P x /\ Q x) ==> ?x. P x /\ Q x /\ R x`) THEN + CONJ_TAC THENL + [REWRITE_TAC[RIGHT_IMP_FORALL_THM] THEN + MAP_EVERY X_GEN_TAC [`w:num^N`; `y:real^N`] THEN + REWRITE_TAC[IMP_IMP; AND_FORALL_THM] THEN + DISCH_THEN(fun th -> FIRST_X_ASSUM MATCH_MP_TAC THEN MP_TAC th) THEN + MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `i:num` THEN + DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN + ASM_REWRITE_TAC[] THEN DISCH_THEN(MP_TAC o MATCH_MP (REAL_ARITH + `(a + n <= x /\ x <= a + m) /\ + (a + n <= y /\ y <= a + m) ==> abs(x - y) <= m - n`)) THEN + MATCH_MP_TAC(REAL_ARITH + `y * z <= e + ==> a <= ((x + &1) * y) * z - ((x * y) * z) ==> a <= e`) THEN + RULE_ASSUM_TAC(REWRITE_RULE[INTERVAL_NE_EMPTY]) THEN + ASM_SIMP_TAC[GSYM REAL_LE_RDIV_EQ; REAL_SUB_LT] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP + (REAL_ARITH `n < e * x ==> &0 <= e * (inv y - x) ==> n <= e / y`)) THEN + MATCH_MP_TAC REAL_LE_MUL THEN ASM_SIMP_TAC[REAL_LT_IMP_LE] THEN + REWRITE_TAC[REAL_SUB_LE] THEN MATCH_MP_TAC REAL_LE_INV2 THEN + ASM_SIMP_TAC[REAL_SUB_LT] THEN + MP_TAC(SPECL [`b - a:real^N`; `i:num`] COMPONENT_LE_NORM) THEN + ASM_SIMP_TAC[VECTOR_SUB_COMPONENT] THEN REAL_ARITH_TAC; + ALL_TAC] THEN + REWRITE_TAC[IN_UNIV; AND_FORALL_THM] THEN + REWRITE_TAC[TAUT `(a ==> c) /\ (a ==> b) <=> a ==> b /\ c`] THEN + REWRITE_TAC[GSYM LAMBDA_SKOLEM] THEN X_GEN_TAC `i:num` THEN + STRIP_TAC THEN + SUBGOAL_THEN `(x:real^N) IN interval[a,b]` MP_TAC THENL + [ASM SET_TAC[]; ALL_TAC] THEN REWRITE_TAC[IN_INTERVAL] THEN + DISCH_THEN(MP_TAC o SPEC `i:num`) THEN ASM_REWRITE_TAC[] THEN + RULE_ASSUM_TAC(REWRITE_RULE[INTERVAL_NE_EMPTY]) THEN STRIP_TAC THEN + DISJ_CASES_TAC(MATCH_MP (REAL_ARITH `x <= y ==> x = y \/ x < y`) + (ASSUME `(x:real^N)$i <= (b:real^N)$i`)) + THENL + [EXISTS_TAC `2 EXP n - 1` THEN + SIMP_TAC[GSYM REAL_OF_NUM_SUB; GSYM REAL_OF_NUM_LT; + EXP_LT_0; LE_1; ARITH] THEN + ASM_REWRITE_TAC[REAL_SUB_ADD; REAL_ARITH `a - &1 < a`] THEN + MATCH_MP_TAC(REAL_ARITH + `&1 * (b - a) = x /\ y <= x ==> a + y <= b /\ b <= a + x`) THEN + ASM_SIMP_TAC[REAL_EQ_MUL_RCANCEL; REAL_LT_IMP_NZ; REAL_LE_RMUL_EQ; + REAL_SUB_LT; REAL_LT_INV_EQ; REAL_LT_POW2] THEN + SIMP_TAC[GSYM REAL_OF_NUM_POW; REAL_MUL_RINV; REAL_POW_EQ_0; + REAL_OF_NUM_EQ; ARITH_EQ] THEN REAL_ARITH_TAC; + ALL_TAC] THEN + MP_TAC(SPEC `&2 pow n * ((x:real^N)$i - (a:real^N)$i) / + ((b:real^N)$i - (a:real^N)$i)` FLOOR_POS) THEN + ANTS_TAC THENL + [ASM_MESON_TAC[REAL_LE_MUL; REAL_LE_MUL; REAL_POW_LE; REAL_POS; + REAL_SUB_LE; REAL_LT_IMP_LE; REAL_LE_DIV]; + ALL_TAC] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `m:num` THEN + REWRITE_TAC[GSYM REAL_OF_NUM_LT; GSYM REAL_OF_NUM_POW] THEN + DISCH_THEN(SUBST_ALL_TAC o SYM) THEN + REWRITE_TAC[REAL_ARITH `a + b * c <= x /\ x <= a + b' * c <=> + b * c <= x - a /\ x - a <= b' * c`] THEN + ASM_SIMP_TAC[GSYM REAL_LE_LDIV_EQ; GSYM REAL_LE_RDIV_EQ; + REAL_SUB_LT; GSYM real_div] THEN + ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN + SIMP_TAC[REAL_LE_LDIV_EQ; REAL_LE_RDIV_EQ; REAL_LT_POW2] THEN + SIMP_TAC[FLOOR; REAL_LT_IMP_LE] THEN MATCH_MP_TAC REAL_LET_TRANS THEN + EXISTS_TAC `((x:real^N)$i - (a:real^N)$i) / + ((b:real^N)$i - (a:real^N)$i) * + &2 pow n` THEN + REWRITE_TAC[FLOOR] THEN GEN_REWRITE_TAC RAND_CONV [GSYM REAL_MUL_LID] THEN + ASM_SIMP_TAC[REAL_LT_RMUL_EQ; REAL_LT_POW2] THEN + ASM_SIMP_TAC[REAL_LT_LDIV_EQ; REAL_MUL_LID; REAL_SUB_LT] THEN + ASM_REAL_ARITH_TAC; + ALL_TAC] THEN + CONJ_TAC THENL + [REPEAT GEN_TAC THEN REWRITE_TAC[IN_IMAGE; EXISTS_PAIR_THM] THEN + REWRITE_TAC[EQ_INTERVAL; IN_ELIM_PAIR_THM] THEN + REWRITE_TAC[INTERVAL_EQ_EMPTY; IN_UNIV; IN_ELIM_THM] THEN + SIMP_TAC[TAUT `a /\ b /\ c <=> ~(a /\ b ==> ~c)`; LAMBDA_BETA] THEN + RULE_ASSUM_TAC(REWRITE_RULE[INTERVAL_NE_EMPTY]) THEN + ASM_SIMP_TAC[REAL_LT_LADD; REAL_LT_RMUL_EQ; REAL_SUB_LT; + REAL_LT_DIV2_EQ; REAL_LT_POW2; + REAL_ARITH `~(v + &1 < v)`] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `n:num` THEN + STRIP_TAC THEN ASM_SIMP_TAC[LAMBDA_BETA] THEN REAL_ARITH_TAC; + ALL_TAC] THEN + REWRITE_TAC[FORALL_IN_IMAGE; FORALL_PAIR_THM; IN_ELIM_PAIR_THM] THEN + MAP_EVERY X_GEN_TAC [`n:num`; `v:num^N`] THEN + REWRITE_TAC[IN_ELIM_THM; IN_UNIV] THEN DISCH_TAC THEN + MATCH_MP_TAC FINITE_SUBSET THEN EXISTS_TAC + `IMAGE (\(n,v). + interval[(lambda i. a$i + &(v$i) / &2 pow n * + ((b:real^N)$i - (a:real^N)$i)):real^N, + (lambda i. a$i + (&(v$i) + &1) / &2 pow n * (b$i - a$i))]) + {m,v | m IN 0..n /\ + v IN {v:num^N | !i. 1 <= i /\ i <= dimindex(:N) + ==> v$i < 2 EXP m}}` THEN + CONJ_TAC THENL + [MATCH_MP_TAC FINITE_IMAGE THEN + MATCH_MP_TAC FINITE_PRODUCT_DEPENDENT THEN + REWRITE_TAC[FINITE_NUMSEG] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC FINITE_CART THEN REWRITE_TAC[FINITE_NUMSEG_LT]; + ALL_TAC] THEN + GEN_REWRITE_TAC I [SUBSET] THEN + REWRITE_TAC[IN_ELIM_THM] THEN ONCE_REWRITE_TAC[IMP_CONJ] THEN + REWRITE_TAC[FORALL_IN_IMAGE; FORALL_PAIR_THM; IN_ELIM_PAIR_THM] THEN + MAP_EVERY X_GEN_TAC [`m:num`; `w:num^N`] THEN DISCH_TAC THEN + DISCH_TAC THEN SIMP_TAC[IN_IMAGE; EXISTS_PAIR_THM; IN_ELIM_PAIR_THM] THEN + MAP_EVERY EXISTS_TAC [`m:num`; `w:num^N`] THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[IN_NUMSEG; GSYM NOT_LT; LT] THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [SUBSET_INTERVAL]) THEN + SIMP_TAC[NOT_IMP; LAMBDA_BETA] THEN + RULE_ASSUM_TAC(REWRITE_RULE[INTERVAL_NE_EMPTY]) THEN + ASM_SIMP_TAC[REAL_LE_LADD; REAL_LE_RMUL_EQ; REAL_SUB_LT] THEN + ASM_SIMP_TAC[REAL_LE_DIV2_EQ; REAL_LT_POW2] THEN + REWRITE_TAC[REAL_ARITH `x <= x + &1`] THEN + DISCH_THEN(MP_TAC o SPEC `1`) THEN + REWRITE_TAC[LE_REFL; DIMINDEX_GE_1] THEN + DISCH_THEN(MP_TAC o MATCH_MP (REAL_ARITH + `w / m <= v / n /\ (v + &1) / n <= (w + &1) / m + ==> inv n <= inv m`)) THEN + REWRITE_TAC[REAL_NOT_LE] THEN MATCH_MP_TAC REAL_LT_INV2 THEN + ASM_REWRITE_TAC[REAL_LT_POW2] THEN MATCH_MP_TAC REAL_POW_MONO_LT THEN + ASM_REWRITE_TAC[] THEN CONV_TAC REAL_RAT_REDUCE_CONV; + ALL_TAC] THEN + SUBGOAL_THEN + `?d. COUNTABLE d /\ + (!k. k IN d ==> k SUBSET interval[a,b] /\ ~(interior k = {}) /\ + (?c d:real^N. k = interval[c,d])) /\ + (!k1 k2. k1 IN d /\ k2 IN d + ==> k1 SUBSET k2 \/ k2 SUBSET k1 \/ + interior k1 INTER interior k2 = {}) /\ + (!k. k IN d ==> (?x. x IN s INTER k /\ k SUBSET g x)) /\ + (!u v. interval[u,v] IN d + ==> ?n. !i. 1 <= i /\ i <= dimindex(:N) + ==> v$i - u$i = (b$i - a$i) / &2 pow n) /\ + (!k. k IN d ==> FINITE {l | l IN d /\ k SUBSET l}) /\ + s SUBSET UNIONS d` + MP_TAC THENL + [FIRST_X_ASSUM(X_CHOOSE_THEN `d:(real^N->bool)->bool` STRIP_ASSUME_TAC) THEN + EXISTS_TAC + `{k:real^N->bool | k IN d /\ ?x. x IN (s INTER k) /\ k SUBSET g x}` THEN + ASM_SIMP_TAC[IN_ELIM_THM] THEN REPEAT CONJ_TAC THENL + [MATCH_MP_TAC COUNTABLE_SUBSET THEN + EXISTS_TAC `d:(real^N->bool)->bool` THEN + ASM_REWRITE_TAC[] THEN SET_TAC[]; + X_GEN_TAC `k:real^N->bool` THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC FINITE_SUBSET THEN + EXISTS_TAC `{l:real^N->bool | l IN d /\ k SUBSET l}` THEN + ASM_REWRITE_TAC[] THEN ASM SET_TAC[]; + ASM SET_TAC[]]; + ALL_TAC] THEN + DISCH_THEN(X_CHOOSE_THEN `d:(real^N->bool)->bool` STRIP_ASSUME_TAC) THEN + EXISTS_TAC + `{k:real^N->bool | k IN d /\ !k'. k' IN d /\ ~(k = k') + ==> ~(k SUBSET k')}` THEN + ASM_SIMP_TAC[IN_ELIM_THM] THEN REPEAT CONJ_TAC THENL + [MATCH_MP_TAC COUNTABLE_SUBSET THEN EXISTS_TAC `d:(real^N->bool)->bool` THEN + ASM_REWRITE_TAC[] THEN SET_TAC[]; + ASM SET_TAC[]; + ALL_TAC] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP + (REWRITE_RULE[IMP_CONJ] SUBSET_TRANS)) THEN + GEN_REWRITE_TAC I [SUBSET] THEN REWRITE_TAC[FORALL_IN_UNIONS] THEN + MAP_EVERY X_GEN_TAC [`k:real^N->bool`; `x:real^N`] THEN DISCH_TAC THEN + REWRITE_TAC[IN_UNIONS; IN_ELIM_THM] THEN + MP_TAC(ISPEC `\k l:real^N->bool. k IN d /\ l IN d /\ l SUBSET k /\ ~(k = l)` + WF_FINITE) THEN + REWRITE_TAC[WF] THEN ANTS_TAC THENL + [CONJ_TAC THENL [SET_TAC[]; ALL_TAC] THEN X_GEN_TAC `l:real^N->bool` THEN + ASM_CASES_TAC `(l:real^N->bool) IN d` THEN + ASM_REWRITE_TAC[EMPTY_GSPEC; FINITE_RULES] THEN + MATCH_MP_TAC FINITE_SUBSET THEN + EXISTS_TAC `{m:real^N->bool | m IN d /\ l SUBSET m}` THEN + ASM_SIMP_TAC[] THEN SET_TAC[]; + ALL_TAC] THEN + DISCH_THEN(MP_TAC o SPEC `\l:real^N->bool. l IN d /\ x IN l`) THEN + REWRITE_TAC[] THEN ANTS_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + MATCH_MP_TAC MONO_EXISTS THEN ASM SET_TAC[]);; + +let COUNTABLE_ELEMENTARY_DIVISION = prove + (`!d. COUNTABLE d /\ (!k. k IN d ==> ?a b:real^N. k = interval[a,b]) + ==> ?d'. COUNTABLE d' /\ + (!k. k IN d' ==> ~(k = {}) /\ ?a b. k = interval[a,b]) /\ + (!k l. k IN d' /\ l IN d' /\ ~(k = l) + ==> interior k INTER interior l = {}) /\ + UNIONS d' = UNIONS d`, + let lemma = prove + (`!s. UNIONS(s DELETE {}) = UNIONS s`, + REWRITE_TAC[EXTENSION; IN_UNIONS; IN_DELETE] THEN + MESON_TAC[NOT_IN_EMPTY]) in + REWRITE_TAC[IMP_CONJ; FORALL_COUNTABLE_AS_IMAGE] THEN + REWRITE_TAC[UNIONS_0; EMPTY_UNIONS] THEN CONJ_TAC THENL + [REPEAT STRIP_TAC THEN EXISTS_TAC `{}:(real^N->bool)->bool` THEN + REWRITE_TAC[NOT_IN_EMPTY; COUNTABLE_EMPTY]; + ALL_TAC] THEN + REWRITE_TAC[FORALL_IN_IMAGE; IN_UNIV; SKOLEM_THM; LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC + [`d:num->real^N->bool`; `a:num->real^N`; `b:num->real^N`] THEN + DISCH_TAC THEN + (CHOOSE_THEN MP_TAC o prove_recursive_functions_exist num_RECURSION) + `x 0 = ({}:(real^N->bool)->bool) /\ + (!n. x(SUC n) = @q. (x n) SUBSET q /\ + q division_of (d n) UNION UNIONS(x n))` THEN + ASM_REWRITE_TAC[] THEN STRIP_TAC THEN + SUBGOAL_THEN + `!n:num. (x n) division_of UNIONS {d k:real^N->bool | k < n}` + ASSUME_TAC THENL + [INDUCT_TAC THEN + ASM_REWRITE_TAC[LT; SET_RULE `UNIONS {f x |x| F} = {}`; + DIVISION_OF_TRIVIAL] THEN + FIRST_ASSUM(MP_TAC o SPECL [`(a:num->real^N) n`; `(b:num->real^N) n`] o + MATCH_MP ELEMENTARY_UNION_INTERVAL_STRONG o + MATCH_MP DIVISION_OF_UNION_SELF) THEN + DISCH_THEN(ASSUME_TAC o SELECT_RULE) THEN + REWRITE_TAC[SET_RULE `{f x | x = a \/ q x} = f a INSERT {f x | q x}`] THEN + REWRITE_TAC[UNIONS_INSERT] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [division_of]) THEN + ASM_REWRITE_TAC[] THEN DISCH_THEN(SUBST1_TAC o SYM o last o CONJUNCTS) THEN + ASM_REWRITE_TAC[]; + ALL_TAC] THEN + SUBGOAL_THEN + `!m n. m <= n ==> (x:num->(real^N->bool)->bool) m SUBSET x n` + ASSUME_TAC THENL + [MATCH_MP_TAC TRANSITIVE_STEPWISE_LE THEN + REPEAT(CONJ_TAC THENL [SET_TAC[]; ALL_TAC]) THEN + ASM_REWRITE_TAC[] THEN X_GEN_TAC `n:num` THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`(a:num->real^N) n`; `(b:num->real^N) n`] o + MATCH_MP ELEMENTARY_UNION_INTERVAL_STRONG o + MATCH_MP DIVISION_OF_UNION_SELF o SPEC `n:num`) THEN + DISCH_THEN(ASSUME_TAC o SELECT_RULE) THEN ASM_REWRITE_TAC[]; + ALL_TAC] THEN + EXISTS_TAC `UNIONS(IMAGE x (:num)) DELETE ({}:real^N->bool)` THEN + REWRITE_TAC[COUNTABLE_DELETE; IMP_CONJ; RIGHT_FORALL_IMP_THM; + FORALL_IN_UNIONS; FORALL_IN_IMAGE; IN_DELETE; IN_UNIV] THEN + REPEAT CONJ_TAC THENL + [MATCH_MP_TAC COUNTABLE_UNIONS THEN + SIMP_TAC[COUNTABLE_IMAGE; NUM_COUNTABLE; FORALL_IN_IMAGE; IN_UNIV] THEN + GEN_TAC THEN MATCH_MP_TAC FINITE_IMP_COUNTABLE THEN + ASM_MESON_TAC[DIVISION_OF_FINITE]; + MAP_EVERY X_GEN_TAC [`n:num`; `k:real^N->bool`] THEN + ASM_MESON_TAC[division_of]; + REWRITE_TAC[RIGHT_IMP_FORALL_THM; IMP_IMP] THEN + GEN_REWRITE_TAC BINDER_CONV [SWAP_FORALL_THM] THEN + MATCH_MP_TAC WLOG_LE THEN + CONJ_TAC THENL [MESON_TAC[INTER_COMM]; ALL_TAC] THEN + MAP_EVERY X_GEN_TAC [`m:num`; `n:num`] THEN DISCH_TAC THEN + MAP_EVERY X_GEN_TAC [`k:real^N->bool`; `l:real^N->bool`] THEN + STRIP_TAC THEN FIRST_X_ASSUM(MP_TAC o SPECL [`m:num`; `n:num`]) THEN + ASM_REWRITE_TAC[] THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [division_of] o + SPEC `n:num`) THEN ASM SET_TAC[]; + REWRITE_TAC[lemma] THEN MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THEN + REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_IMAGE; IN_UNIV; + FORALL_IN_UNIONS; SUBSET; IN_UNIONS; EXISTS_IN_IMAGE] + THENL + [X_GEN_TAC `k:real^N->bool` THEN DISCH_THEN(X_CHOOSE_TAC `n:num`) THEN + X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [division_of] o + SPEC `n:num`) THEN + DISCH_THEN(MP_TAC o last o CONJUNCTS) THEN ASM SET_TAC[]; + MAP_EVERY X_GEN_TAC [`n:num`; `y:real^N`] THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [division_of] o + SPEC `SUC n`) THEN + DISCH_THEN(MP_TAC o last o CONJUNCTS) THEN + REWRITE_TAC[EXTENSION; IN_UNIONS; EXISTS_IN_GSPEC] THEN + DISCH_THEN(MP_TAC o SPEC `y:real^N`) THEN + ASM_MESON_TAC[ARITH_RULE `n < SUC n`]]]);; + +let EXPAND_CLOSED_OPEN_INTERVAL = prove + (`!a b:real^N e. + &0 < e + ==> ?c d. interval[a,b] SUBSET interval(c,d) /\ + measure(interval(c,d)) <= measure(interval[a,b]) + e`, + let lemma = prove + (`!f n. (\x. lift(product(1..n) (\i. f i + drop x))) continuous at (vec 0)`, + GEN_TAC THEN INDUCT_TAC THEN + REWRITE_TAC[PRODUCT_CLAUSES_NUMSEG; ARITH_EQ; CONTINUOUS_CONST] THEN + REWRITE_TAC[ARITH_RULE `1 <= SUC n`] THEN + ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN REWRITE_TAC[LIFT_CMUL] THEN + MATCH_MP_TAC CONTINUOUS_MUL THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[o_DEF; LIFT_ADD; LIFT_DROP] THEN + SIMP_TAC[CONTINUOUS_ADD; CONTINUOUS_AT_ID; CONTINUOUS_CONST]) in + REPEAT GEN_TAC THEN ABBREV_TAC `m:real^N = midpoint(a,b)` THEN + POP_ASSUM MP_TAC THEN GEOM_ORIGIN_TAC `m:real^N` THEN + REWRITE_TAC[midpoint; VECTOR_ARITH + `inv(&2) % (a + b):real^N = vec 0 <=> a = --b`] THEN + REPEAT GEN_TAC THEN DISCH_THEN SUBST1_TAC THEN + DISCH_TAC THEN ASM_CASES_TAC `interval[--b:real^N,b] = {}` THENL + [MAP_EVERY EXISTS_TAC [`--b:real^N`; `b:real^N`] THEN + REWRITE_TAC[MEASURE_INTERVAL] THEN + ASM_REWRITE_TAC[CONTENT_EMPTY; EMPTY_SUBSET] THEN ASM_REAL_ARITH_TAC; + ALL_TAC] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [INTERVAL_NE_EMPTY]) THEN + REWRITE_TAC[VECTOR_NEG_COMPONENT; REAL_ARITH `--x <= x <=> &0 <= x`] THEN + DISCH_TAC THEN + MP_TAC(ISPECL [`\i. &2 * (b:real^N)$i`; `dimindex(:N)`] lemma) THEN + REWRITE_TAC[continuous_at; DIST_LIFT; FORALL_LIFT; DIST_0; DROP_VEC] THEN + REWRITE_TAC[NORM_LIFT; LIFT_DROP; REAL_ADD_RID] THEN + DISCH_THEN(MP_TAC o SPEC `e:real`) THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `k:real` STRIP_ASSUME_TAC) THEN + MAP_EVERY EXISTS_TAC + [`--(b + k / &4 % vec 1:real^N)`; `b + k / &4 % vec 1:real^N`] THEN + REWRITE_TAC[MEASURE_INTERVAL; SUBSET_INTERVAL; + CONTENT_CLOSED_INTERVAL_CASES] THEN + REWRITE_TAC[VECTOR_NEG_COMPONENT; VECTOR_ADD_COMPONENT; + VECTOR_MUL_COMPONENT; VEC_COMPONENT; REAL_MUL_RID] THEN + ASM_SIMP_TAC[REAL_ARITH `--x <= x <=> &0 <= x`; REAL_LT_ADDR; + REAL_ARITH `&0 < k / &4 <=> &0 < k`; + REAL_ARITH `&0 <= b /\ &0 < k ==> --(b + k) < b`; + REAL_ARITH `&0 <= b /\ &0 < k ==> --(b + k) < --b`; + REAL_ARITH `&0 <= b /\ &0 < k ==> &0 <= b + k`] THEN + REWRITE_TAC[REAL_ARITH `b - --b = &2 * b`; REAL_ADD_LDISTRIB] THEN + MATCH_MP_TAC(REAL_ARITH `abs(a - b) < e ==> a <= b + e`) THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REAL_ARITH_TAC);; + +(* ------------------------------------------------------------------------- *) +(* Outer and inner approximation of measurable set by well-behaved sets. *) +(* ------------------------------------------------------------------------- *) + +let MEASURABLE_OUTER_INTERVALS_BOUNDED = prove + (`!s a b:real^N e. + measurable s /\ s SUBSET interval[a,b] /\ &0 < e + ==> ?d. COUNTABLE d /\ + (!k. k IN d ==> k SUBSET interval[a,b] /\ ~(k = {}) /\ + (?c d. k = interval[c,d])) /\ + (!k1 k2. k1 IN d /\ k2 IN d /\ ~(k1 = k2) + ==> interior k1 INTER interior k2 = {}) /\ + (!u v. interval[u,v] IN d + ==> ?n. !i. 1 <= i /\ i <= dimindex(:N) + ==> v$i - u$i = (b$i - a$i) / &2 pow n) /\ + (!k. k IN d /\ ~(interval(a,b) = {}) ==> ~(interior k = {})) /\ + s SUBSET UNIONS d /\ + measurable (UNIONS d) /\ + measure (UNIONS d) <= measure s + e`, + let lemma = prove + (`(!x y. (x,y) IN IMAGE (\z. f z,g z) s ==> P x y) <=> + (!z. z IN s ==> P (f z) (g z))`, + REWRITE_TAC[IN_IMAGE; PAIR_EQ] THEN MESON_TAC[]) in + REPEAT GEN_TAC THEN + ASM_CASES_TAC `interval[a:real^N,b] = {}` THENL + [ASM_REWRITE_TAC[SUBSET_EMPTY] THEN STRIP_TAC THEN + EXISTS_TAC `{}:(real^N->bool)->bool` THEN + ASM_REWRITE_TAC[NOT_IN_EMPTY; UNIONS_0; MEASURE_EMPTY; REAL_ADD_LID; + SUBSET_REFL; COUNTABLE_EMPTY; MEASURABLE_EMPTY] THEN + ASM_SIMP_TAC[REAL_LT_IMP_LE]; + ALL_TAC] THEN + STRIP_TAC THEN ASM_CASES_TAC `interval(a:real^N,b) = {}` THEN + ASM_REWRITE_TAC[] THENL + [EXISTS_TAC `{interval[a:real^N,b]}` THEN + REWRITE_TAC[UNIONS_1; COUNTABLE_SING] THEN + ASM_REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_INSERT; + NOT_IN_EMPTY; SUBSET_REFL; MEASURABLE_INTERVAL] THEN + CONJ_TAC THENL [MESON_TAC[]; ALL_TAC] THEN CONJ_TAC THENL + [ASM_REWRITE_TAC[IN_SING; EQ_INTERVAL] THEN + REPEAT STRIP_TAC THEN EXISTS_TAC `0` THEN + ASM_REWRITE_TAC[real_pow; REAL_DIV_1]; + SUBGOAL_THEN + `measure(interval[a:real^N,b]) = &0 /\ measure(s:real^N->bool) = &0` + (fun th -> ASM_SIMP_TAC[th; REAL_LT_IMP_LE; REAL_ADD_LID]) THEN + SUBGOAL_THEN + `interval[a:real^N,b] has_measure &0 /\ + (s:real^N->bool) has_measure &0` + (fun th -> MESON_TAC[th; MEASURE_UNIQUE]) THEN + REWRITE_TAC[HAS_MEASURE_0] THEN + MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN CONJ_TAC THENL + [ASM_REWRITE_TAC[NEGLIGIBLE_INTERVAL]; + ASM_MESON_TAC[NEGLIGIBLE_SUBSET]]]; + ALL_TAC] THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [measurable]) THEN + DISCH_THEN(X_CHOOSE_TAC `m:real`) THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP MEASURE_UNIQUE) THEN + SUBGOAL_THEN + `((\x:real^N. if x IN s then vec 1 else vec 0) has_integral (lift m)) + (interval[a,b])` + ASSUME_TAC THENL + [ONCE_REWRITE_TAC[GSYM HAS_INTEGRAL_RESTRICT_UNIV] THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [HAS_MEASURE]) THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] HAS_INTEGRAL_EQ) THEN + ASM SET_TAC[]; + ALL_TAC] THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP HAS_INTEGRAL_INTEGRABLE) THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [has_integral]) THEN + DISCH_THEN(MP_TAC o SPEC `e:real`) THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `g:real^N->real^N->bool` STRIP_ASSUME_TAC) THEN + MP_TAC(SPECL [`a:real^N`; `b:real^N`; `s:real^N->bool`; + `g:real^N->real^N->bool`] COVERING_LEMMA) THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC MONO_EXISTS THEN + X_GEN_TAC `d:(real^N->bool)->bool` THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + CONJ_TAC THENL [ASM_MESON_TAC[INTERIOR_EMPTY]; ALL_TAC] THEN + CONJ_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN + MP_TAC(ISPECL [`(\x. if x IN s then vec 1 else vec 0):real^N->real^1`; + `a:real^N`; `b:real^N`; `g:real^N->real^N->bool`; + `e:real`] + HENSTOCK_LEMMA_PART1) THEN + ASM_REWRITE_TAC[] THEN + FIRST_ASSUM(SUBST1_TAC o MATCH_MP INTEGRAL_UNIQUE) THEN + ASM_REWRITE_TAC[] THEN DISCH_THEN(LABEL_TAC "*") THEN + SUBGOAL_THEN + `!k l:real^N->bool. k IN d /\ l IN d /\ ~(k = l) + ==> negligible(k INTER l)` + ASSUME_TAC THENL + [REPEAT STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`k:real^N->bool`; `l:real^N->bool`]) THEN + ASM_SIMP_TAC[] THEN + SUBGOAL_THEN + `?x y:real^N u v:real^N. k = interval[x,y] /\ l = interval[u,v]` + MP_TAC THENL [ASM_MESON_TAC[SUBSET]; ALL_TAC] THEN + DISCH_THEN(REPEAT_TCL CHOOSE_THEN (CONJUNCTS_THEN SUBST_ALL_TAC)) THEN + REWRITE_TAC[INTERIOR_CLOSED_INTERVAL] THEN DISCH_TAC THEN + MATCH_MP_TAC NEGLIGIBLE_SUBSET THEN + EXISTS_TAC `(interval[x:real^N,y] DIFF interval(x,y)) UNION + (interval[u:real^N,v] DIFF interval(u,v)) UNION + (interval (x,y) INTER interval (u,v))` THEN + CONJ_TAC THENL [ALL_TAC; SET_TAC[]] THEN + ASM_REWRITE_TAC[UNION_EMPTY] THEN + SIMP_TAC[NEGLIGIBLE_UNION; NEGLIGIBLE_FRONTIER_INTERVAL]; + ALL_TAC] THEN + SUBGOAL_THEN + `!D. FINITE D /\ D SUBSET d + ==> measurable(UNIONS D :real^N->bool) /\ measure(UNIONS D) <= m + e` + ASSUME_TAC THENL + [GEN_TAC THEN STRIP_TAC THEN + SUBGOAL_THEN + `?t:(real^N->bool)->real^N. !k. k IN D ==> t(k) IN (s INTER k) /\ + k SUBSET (g(t k))` + (CHOOSE_THEN (LABEL_TAC "+")) THENL + [REWRITE_TAC[GSYM SKOLEM_THM] THEN ASM SET_TAC[]; ALL_TAC] THEN + REMOVE_THEN "*" (MP_TAC o SPEC + `IMAGE (\k. (t:(real^N->bool)->real^N) k,k) D`) THEN + ASM_SIMP_TAC[VSUM_IMAGE; PAIR_EQ] THEN REWRITE_TAC[o_DEF] THEN + ANTS_TAC THENL + [REWRITE_TAC[tagged_partial_division_of; fine] THEN + ASM_SIMP_TAC[FINITE_IMAGE; FORALL_IN_IMAGE] THEN + REWRITE_TAC[lemma; RIGHT_FORALL_IMP_THM; IMP_CONJ; PAIR_EQ] THEN + ASM_SIMP_TAC[] THEN + CONJ_TAC THENL [ASM SET_TAC[]; ASM_MESON_TAC[SUBSET]]; + ALL_TAC] THEN + USE_THEN "+" (MP_TAC o REWRITE_RULE[IN_INTER]) THEN + SIMP_TAC[] THEN DISCH_THEN(K ALL_TAC) THEN + ASM_SIMP_TAC[VSUM_SUB] THEN + SUBGOAL_THEN `D division_of (UNIONS D:real^N->bool)` ASSUME_TAC THENL + [REWRITE_TAC[division_of] THEN ASM SET_TAC[]; ALL_TAC] THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP MEASURABLE_ELEMENTARY) THEN + SUBGOAL_THEN `vsum D (\k:real^N->bool. content k % vec 1) = + lift(measure(UNIONS D))` + SUBST1_TAC THENL + [ONCE_REWRITE_TAC[GSYM DROP_EQ] THEN + ASM_SIMP_TAC[LIFT_DROP; DROP_VSUM; o_DEF; DROP_CMUL; DROP_VEC] THEN + SIMP_TAC[REAL_MUL_RID; ETA_AX] THEN ASM_MESON_TAC[MEASURE_ELEMENTARY]; + ALL_TAC] THEN + SUBGOAL_THEN + `vsum D (\k. integral k (\x:real^N. if x IN s then vec 1 else vec 0)) = + lift(sum D (\k. measure(k INTER s)))` + SUBST1_TAC THENL + [ASM_SIMP_TAC[LIFT_SUM; o_DEF] THEN MATCH_MP_TAC VSUM_EQ THEN + X_GEN_TAC `k:real^N->bool` THEN DISCH_TAC THEN REWRITE_TAC[] THEN + SUBGOAL_THEN `measurable(k:real^N->bool)` ASSUME_TAC THENL + [ASM_MESON_TAC[SUBSET; MEASURABLE_INTERVAL]; ALL_TAC] THEN + ASM_SIMP_TAC[GSYM INTEGRAL_MEASURE_UNIV; MEASURABLE_INTER] THEN + REWRITE_TAC[MESON[IN_INTER] + `(if x IN k INTER s then a else b) = + (if x IN k then if x IN s then a else b else b)`] THEN + REWRITE_TAC[INTEGRAL_RESTRICT_UNIV]; + ALL_TAC] THEN + ASM_REWRITE_TAC[GSYM LIFT_SUB; NORM_LIFT] THEN + MATCH_MP_TAC(REAL_ARITH `y <= m ==> abs(x - y) <= e ==> x <= m + e`) THEN + MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `measure(UNIONS D INTER s:real^N->bool)` THEN + CONJ_TAC THENL + [ALL_TAC; + EXPAND_TAC "m" THEN MATCH_MP_TAC MEASURE_SUBSET THEN + ASM_REWRITE_TAC[] THEN CONJ_TAC THENL [ALL_TAC; SET_TAC[]] THEN + MATCH_MP_TAC MEASURABLE_INTER THEN ASM_REWRITE_TAC[]] THEN + REWRITE_TAC[INTER_UNIONS] THEN MATCH_MP_TAC REAL_EQ_IMP_LE THEN + ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN CONV_TAC SYM_CONV THEN + MATCH_MP_TAC MEASURE_NEGLIGIBLE_UNIONS_IMAGE_STRONG THEN + ASM_SIMP_TAC[FINITE_RESTRICT] THEN CONJ_TAC THENL + [ASM_MESON_TAC[SUBSET; MEASURABLE_INTERVAL; MEASURABLE_INTER]; + ALL_TAC] THEN + MAP_EVERY X_GEN_TAC [`k:real^N->bool`; `l:real^N->bool`] THEN + STRIP_TAC THEN MATCH_MP_TAC NEGLIGIBLE_SUBSET THEN + EXISTS_TAC `k INTER l:real^N->bool` THEN ASM_SIMP_TAC[] THEN ASM SET_TAC[]; + ALL_TAC] THEN + ASM_CASES_TAC `FINITE(d:(real^N->bool)->bool)` THENL + [ASM_MESON_TAC[SUBSET_REFL]; ALL_TAC] THEN + MP_TAC(ISPEC `d:(real^N->bool)->bool` COUNTABLE_AS_INJECTIVE_IMAGE) THEN + ASM_REWRITE_TAC[INFINITE] THEN + DISCH_THEN(X_CHOOSE_THEN `s:num->real^N->bool` + (CONJUNCTS_THEN2 SUBST_ALL_TAC ASSUME_TAC)) THEN + MP_TAC(ISPECL [`s:num->real^N->bool`; `m + e:real`] + HAS_MEASURE_COUNTABLE_NEGLIGIBLE_UNIONS) THEN + MATCH_MP_TAC(TAUT `a /\ (a /\ b ==> c) ==> (a ==> b) ==> c`) THEN + REWRITE_TAC[GSYM CONJ_ASSOC] THEN + RULE_ASSUM_TAC(REWRITE_RULE[IMP_CONJ; RIGHT_FORALL_IMP_THM; + FORALL_IN_IMAGE; IN_UNIV]) THEN + RULE_ASSUM_TAC(REWRITE_RULE[IMP_IMP; RIGHT_IMP_FORALL_THM]) THEN + REPEAT CONJ_TAC THENL + [ASM_MESON_TAC[MEASURABLE_INTERVAL; MEASURABLE_INTER]; + ASM_MESON_TAC[]; + X_GEN_TAC `n:num` THEN + FIRST_X_ASSUM(MP_TAC o SPEC `IMAGE (s:num->real^N->bool) (0..n)`) THEN + SIMP_TAC[FINITE_IMAGE; FINITE_NUMSEG; IMAGE_SUBSET; SUBSET_UNIV] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + MATCH_MP_TAC(REAL_ARITH `x = y ==> x <= e ==> y <= e`) THEN + MATCH_MP_TAC MEASURE_NEGLIGIBLE_UNIONS_IMAGE THEN + ASM_MESON_TAC[FINITE_NUMSEG; MEASURABLE_INTERVAL]; + ALL_TAC] THEN + ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + GEN_REWRITE_TAC LAND_CONV [GSYM(CONJUNCT2 LIFT_DROP)] THEN + REWRITE_TAC[drop] THEN + MATCH_MP_TAC(ISPEC `sequentially` LIM_COMPONENT_UBOUND) THEN + EXISTS_TAC + `\n. vsum(from 0 INTER (0..n)) (\n. lift(measure(s n:real^N->bool)))` THEN + ASM_REWRITE_TAC[GSYM sums; TRIVIAL_LIMIT_SEQUENTIALLY] THEN + REWRITE_TAC[DIMINDEX_1; ARITH; EVENTUALLY_SEQUENTIALLY] THEN + SIMP_TAC[VSUM_COMPONENT; ARITH; DIMINDEX_1] THEN + ASM_REWRITE_TAC[GSYM drop; LIFT_DROP; FROM_INTER_NUMSEG]);; + +let MEASURABLE_OUTER_CLOSED_INTERVALS = prove + (`!s:real^N->bool e. + measurable s /\ &0 < e + ==> ?d. COUNTABLE d /\ + (!k. k IN d ==> ~(k = {}) /\ (?a b. k = interval[a,b])) /\ + (!k l. k IN d /\ l IN d /\ ~(k = l) + ==> interior k INTER interior l = {}) /\ + s SUBSET UNIONS d /\ + measurable (UNIONS d) /\ + measure (UNIONS d) <= measure s + e`, + let lemma = prove + (`UNIONS (UNIONS {d n | n IN (:num)}) = + UNIONS {UNIONS(d n) | n IN (:num)}`, + REWRITE_TAC[SIMPLE_IMAGE; UNIONS_IMAGE] THEN + GEN_REWRITE_TAC I [EXTENSION] THEN + REWRITE_TAC[IN_UNIONS; IN_ELIM_THM; IN_UNIV] THEN MESON_TAC[]) in + REPEAT STRIP_TAC THEN + SUBGOAL_THEN + `?d. COUNTABLE d /\ + (!k. k IN d ==> ?a b:real^N. k = interval[a,b]) /\ + s SUBSET UNIONS d /\ + measurable (UNIONS d) /\ + measure (UNIONS d) <= measure s + e` + MP_TAC THENL + [ALL_TAC; + DISCH_THEN(X_CHOOSE_THEN `d1:(real^N->bool)->bool` STRIP_ASSUME_TAC) THEN + MP_TAC(ISPEC `d1:(real^N->bool)->bool` COUNTABLE_ELEMENTARY_DIVISION) THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC MONO_EXISTS THEN + X_GEN_TAC `d:(real^N->bool)->bool` THEN + STRIP_TAC THEN FIRST_X_ASSUM(SUBST_ALL_TAC o SYM) THEN + ASM_REWRITE_TAC[]] THEN + MP_TAC(ISPECL + [`\n. s INTER (ball(vec 0:real^N,&n + &1) DIFF ball(vec 0,&n))`; + `measure(s:real^N->bool)`] HAS_MEASURE_COUNTABLE_NEGLIGIBLE_UNIONS) THEN + ASM_SIMP_TAC[MEASURABLE_INTER; MEASURABLE_DIFF; MEASURABLE_BALL] THEN + SUBGOAL_THEN + `!m n. ~(m = n) + ==> (s INTER (ball(vec 0,&m + &1) DIFF ball(vec 0,&m))) INTER + (s INTER (ball(vec 0,&n + &1) DIFF ball(vec 0,&n))) = + ({}:real^N->bool)` + ASSUME_TAC THENL + [MATCH_MP_TAC WLOG_LT THEN REWRITE_TAC[] THEN + CONJ_TAC THENL [MESON_TAC[INTER_COMM]; ALL_TAC] THEN + MAP_EVERY X_GEN_TAC [`m:num`; `n:num`] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC(SET_RULE + `m1 SUBSET n + ==> (s INTER (m1 DIFF m)) INTER (s INTER (n1 DIFF n)) = {}`) THEN + MATCH_MP_TAC SUBSET_BALL THEN + REWRITE_TAC[REAL_OF_NUM_ADD; REAL_OF_NUM_LE] THEN ASM_ARITH_TAC; + ALL_TAC] THEN + ANTS_TAC THENL + [ASM_SIMP_TAC[NEGLIGIBLE_EMPTY] THEN X_GEN_TAC `n:num` THEN + W(MP_TAC o PART_MATCH (rand o rand) + MEASURE_DISJOINT_UNIONS_IMAGE o lhand o snd) THEN + ASM_SIMP_TAC[FINITE_NUMSEG; DISJOINT] THEN + ASM_SIMP_TAC[MEASURABLE_INTER; MEASURABLE_DIFF; MEASURABLE_BALL] THEN + DISCH_THEN(SUBST1_TAC o SYM) THEN MATCH_MP_TAC MEASURE_SUBSET THEN + SIMP_TAC[SUBSET; FORALL_IN_UNIONS; IMP_CONJ; FORALL_IN_IMAGE; + RIGHT_FORALL_IMP_THM; IN_INTER] THEN + ASM_SIMP_TAC[MEASURABLE_UNIONS; FINITE_NUMSEG; FORALL_IN_IMAGE; + FINITE_IMAGE; MEASURABLE_INTER; MEASURABLE_DIFF; MEASURABLE_BALL]; + ALL_TAC] THEN + SUBGOAL_THEN + `UNIONS {s INTER (ball(vec 0,&n + &1) DIFF ball(vec 0,&n)) | n IN (:num)} = + (s:real^N->bool)` + ASSUME_TAC THENL + [REWRITE_TAC[EXTENSION; IN_UNIONS; EXISTS_IN_GSPEC; IN_UNIV; IN_INTER] THEN + X_GEN_TAC `x:real^N` THEN + ASM_CASES_TAC `(x:real^N) IN s` THEN ASM_REWRITE_TAC[] THEN + SUBGOAL_THEN `?n. (x:real^N) IN ball(vec 0,&n)` MP_TAC THENL + [REWRITE_TAC[IN_BALL_0; REAL_ARCH_LT]; + GEN_REWRITE_TAC LAND_CONV [num_WOP] THEN + DISCH_THEN(X_CHOOSE_THEN `n:num` MP_TAC) THEN ASM_CASES_TAC `n = 0` THENL + [ASM_REWRITE_TAC[IN_BALL_0; GSYM REAL_NOT_LE; NORM_POS_LE]; + STRIP_TAC THEN EXISTS_TAC `n - 1` THEN REWRITE_TAC[IN_DIFF] THEN + ASM_SIMP_TAC[REAL_OF_NUM_ADD; SUB_ADD; LE_1] THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_ARITH_TAC]]; + ASM_REWRITE_TAC[] THEN DISCH_TAC] THEN + MP_TAC(MATCH_MP MONO_FORALL (GEN `n:num` + (ISPECL + [`s INTER (ball(vec 0:real^N,&n + &1) DIFF ball(vec 0,&n))`; + `--(vec(n + 1)):real^N`; `vec(n + 1):real^N`; + `e / &2 / &2 pow n`] + MEASURABLE_OUTER_INTERVALS_BOUNDED))) THEN + ANTS_TAC THENL + [ASM_SIMP_TAC[REAL_LT_DIV; REAL_HALF; REAL_LT_POW2] THEN + ASM_SIMP_TAC[MEASURABLE_INTER; MEASURABLE_DIFF; MEASURABLE_BALL] THEN + REWRITE_TAC[SUBSET; IN_INTER; IN_INTERVAL; IN_BALL_0; IN_DIFF; REAL_NOT_LT; + REAL_OF_NUM_ADD; VECTOR_NEG_COMPONENT; VEC_COMPONENT; REAL_BOUNDS_LE] THEN + MESON_TAC[COMPONENT_LE_NORM; REAL_LET_TRANS; REAL_LT_IMP_LE]; + REWRITE_TAC[SKOLEM_THM; LEFT_IMP_EXISTS_THM; FORALL_AND_THM]] THEN + X_GEN_TAC `d:num->(real^N->bool)->bool` THEN STRIP_TAC THEN + EXISTS_TAC `UNIONS {d n | n IN (:num)} :(real^N->bool)->bool` THEN + REWRITE_TAC[lemma] THEN CONJ_TAC THENL + [MATCH_MP_TAC COUNTABLE_UNIONS THEN + ASM_REWRITE_TAC[SIMPLE_IMAGE; FORALL_IN_IMAGE] THEN + SIMP_TAC[COUNTABLE_IMAGE; NUM_COUNTABLE]; + ALL_TAC] THEN + CONJ_TAC THENL + [REWRITE_TAC[FORALL_IN_UNIONS; IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN + ASM_SIMP_TAC[FORALL_IN_GSPEC; IN_UNIV] THEN ASM_MESON_TAC[]; + ALL_TAC] THEN + CONJ_TAC THENL + [FIRST_X_ASSUM(fun th -> GEN_REWRITE_TAC LAND_CONV [GSYM th]) THEN + REWRITE_TAC[SUBSET; FORALL_IN_UNIONS; IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN + ASM_SIMP_TAC[FORALL_IN_GSPEC; IN_UNIV; IN_UNIONS] THEN + REWRITE_TAC[EXISTS_IN_GSPEC] THEN ASM SET_TAC[]; + ALL_TAC] THEN + MATCH_MP_TAC MEASURE_COUNTABLE_UNIONS_LE THEN ASM_REWRITE_TAC[] THEN + X_GEN_TAC `n:num` THEN + MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC + `sum(0..n) (\k. measure(s INTER (ball(vec 0:real^N,&k + &1) DIFF + ball(vec 0,&k))) + e / &2 / &2 pow k)` THEN + ASM_SIMP_TAC[SUM_LE_NUMSEG] THEN REWRITE_TAC[SUM_ADD_NUMSEG] THEN + MATCH_MP_TAC REAL_LE_ADD2 THEN CONJ_TAC THENL + [W(MP_TAC o PART_MATCH (rand o rand) MEASURE_DISJOINT_UNIONS_IMAGE o + lhand o snd) THEN + ASM_SIMP_TAC[DISJOINT; FINITE_NUMSEG; MEASURABLE_DIFF; MEASURABLE_INTER; + MEASURABLE_BALL] THEN + DISCH_THEN(SUBST1_TAC o SYM) THEN MATCH_MP_TAC MEASURE_SUBSET THEN + ASM_SIMP_TAC[MEASURABLE_UNIONS; FORALL_IN_IMAGE; FINITE_NUMSEG; + FINITE_IMAGE; MEASURABLE_DIFF; MEASURABLE_INTER; MEASURABLE_BALL] THEN + FIRST_X_ASSUM(fun th -> GEN_REWRITE_TAC RAND_CONV [GSYM th]) THEN + MATCH_MP_TAC SUBSET_UNIONS THEN REWRITE_TAC[SIMPLE_IMAGE] THEN + MATCH_MP_TAC IMAGE_SUBSET THEN REWRITE_TAC[SUBSET_UNIV]; + REWRITE_TAC[real_div; SUM_LMUL; REAL_INV_POW; SUM_GP; LT] THEN + REWRITE_TAC[GSYM real_div] THEN CONV_TAC REAL_RAT_REDUCE_CONV THEN + REWRITE_TAC[REAL_ARITH `e / &2 * (&1 - x) / (&1 / &2) <= e <=> + &0 <= e * x`] THEN + MATCH_MP_TAC REAL_LE_MUL THEN ASM_SIMP_TAC[REAL_LT_IMP_LE] THEN + MATCH_MP_TAC REAL_POW_LE THEN CONV_TAC REAL_RAT_REDUCE_CONV]);; + +let MEASURABLE_OUTER_OPEN_INTERVALS = prove + (`!s:real^N->bool e. + measurable s /\ &0 < e + ==> ?d. COUNTABLE d /\ + (!k. k IN d ==> ~(k = {}) /\ (?a b. k = interval(a,b))) /\ + s SUBSET UNIONS d /\ + measurable (UNIONS d) /\ + measure (UNIONS d) <= measure s + e`, + let lemma = prove + (`!s. UNIONS(s DELETE {}) = UNIONS s`, + REWRITE_TAC[EXTENSION; IN_UNIONS; IN_DELETE] THEN + MESON_TAC[NOT_IN_EMPTY]) in + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`s:real^N->bool`; `e / &2`] + MEASURABLE_OUTER_CLOSED_INTERVALS) THEN + ASM_REWRITE_TAC[REAL_HALF; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `dset:(real^N->bool)->bool` THEN + ASM_CASES_TAC `dset:(real^N->bool)->bool = {}` THENL + [ASM_REWRITE_TAC[UNIONS_0; SUBSET_EMPTY] THEN STRIP_TAC THEN + EXISTS_TAC `{}:(real^N->bool)->bool` THEN + ASM_REWRITE_TAC[UNIONS_0; NOT_IN_EMPTY; MEASURE_EMPTY; SUBSET_REFL] THEN + ASM_REAL_ARITH_TAC; + ALL_TAC] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + SUBGOAL_THEN + `?f. dset = IMAGE (f:num->(real^N->bool)) (:num) DELETE {} /\ + (!m n. f m = f n ==> m = n \/ f n = {})` + MP_TAC THENL + [ASM_CASES_TAC `FINITE(dset:(real^N->bool)->bool)` THENL + [FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [FINITE_HAS_SIZE]) THEN + DISCH_THEN(MP_TAC o MATCH_MP HAS_SIZE_INDEX) THEN + ABBREV_TAC `m = CARD(dset:(real^N->bool)->bool)` THEN + DISCH_THEN(X_CHOOSE_THEN `f:num->real^N->bool` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `\i. if i < m then (f:num->real^N->bool) i else {}` THEN + REWRITE_TAC[] THEN CONJ_TAC THENL [ALL_TAC; ASM_MESON_TAC[]] THEN + GEN_REWRITE_TAC I [EXTENSION] THEN + REWRITE_TAC[IN_DELETE; IN_IMAGE; IN_UNIV] THEN ASM_MESON_TAC[]; + MP_TAC(ISPEC `dset:(real^N->bool)->bool` + COUNTABLE_AS_INJECTIVE_IMAGE) THEN + ASM_REWRITE_TAC[INFINITE] THEN MATCH_MP_TAC MONO_EXISTS THEN + GEN_TAC THEN STRIP_TAC THEN CONJ_TAC THENL + [ALL_TAC; ASM_MESON_TAC[]] THEN + ASM_REWRITE_TAC[SET_RULE `s = s DELETE a <=> ~(a IN s)`] THEN + ASM_MESON_TAC[]]; + ALL_TAC] THEN + REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `d:num->real^N->bool` THEN + DISCH_THEN(CONJUNCTS_THEN2 SUBST_ALL_TAC MP_TAC) THEN + FIRST_X_ASSUM(MP_TAC o check (is_forall o concl)) THEN + REWRITE_TAC[FORALL_IN_IMAGE; IN_UNIV; FORALL_AND_THM; SKOLEM_THM; + IMP_CONJ; RIGHT_FORALL_IMP_THM; IN_DELETE; lemma] THEN + DISCH_THEN(MP_TAC o MATCH_MP (MESON[] + `(!x. ~(P x) ==> ~(P x) /\ Q x) ==> (!x. P x ==> Q x) ==> !x. Q x`)) THEN + ANTS_TAC THENL [MESON_TAC[EMPTY_AS_INTERVAL]; ALL_TAC] THEN + REWRITE_TAC[SKOLEM_THM; LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`a:num->real^N`; `b:num->real^N`] THEN + DISCH_TAC THEN DISCH_TAC THEN + REWRITE_TAC[RIGHT_IMP_FORALL_THM; IMP_IMP; GSYM CONJ_ASSOC] THEN + GEN_REWRITE_TAC I [IMP_CONJ] THEN + DISCH_THEN(MP_TAC o MATCH_MP(MESON[] + `(!x y. ~(P x) /\ ~(P y) /\ ~(f x = f y) ==> Q x y) + ==> (!x y. P x ==> Q x y) /\ (!x y. P y ==> Q x y) + ==> (!x y. ~(f x = f y) ==> Q x y)`)) THEN + SIMP_TAC[INTERIOR_EMPTY; INTER_EMPTY] THEN + ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN + SUBGOAL_THEN + `?d. COUNTABLE d /\ + (!k. k IN d ==> ?a b:real^N. k = interval(a,b)) /\ + s SUBSET UNIONS d /\ + measurable (UNIONS d) /\ + measure (UNIONS d) <= measure s + e` + MP_TAC THENL + [ALL_TAC; + DISCH_THEN(X_CHOOSE_TAC `d:(real^N->bool)->bool`) THEN + EXISTS_TAC `d DELETE ({}:real^N->bool)` THEN + ASM_SIMP_TAC[lemma; COUNTABLE_DELETE; IN_DELETE]] THEN + MP_TAC(GEN `n:num` (ISPECL [`(a:num->real^N) n`; `(b:num->real^N) n`; + `e / &2 pow (n + 2)`] EXPAND_CLOSED_OPEN_INTERVAL)) THEN + ASM_SIMP_TAC[REAL_LT_DIV; REAL_LT_POW2; SKOLEM_THM] THEN + REWRITE_TAC[LEFT_IMP_EXISTS_THM; FORALL_AND_THM] THEN + MAP_EVERY X_GEN_TAC [`A:num->real^N`; `B:num->real^N`] THEN STRIP_TAC THEN + EXISTS_TAC `IMAGE (\n. interval(A n:real^N,B n)) (:num)` THEN + SIMP_TAC[COUNTABLE_IMAGE; NUM_COUNTABLE; FORALL_IN_IMAGE; IN_UNIV] THEN + CONJ_TAC THENL [MESON_TAC[]; ALL_TAC] THEN + CONJ_TAC THENL + [FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP + (REWRITE_RULE[IMP_CONJ] SUBSET_TRANS)) THEN + ASM_REWRITE_TAC[SUBSET; FORALL_IN_UNIONS] THEN + REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_IMAGE; IN_UNIV] THEN + MAP_EVERY X_GEN_TAC [`n:num`; `x:real^N`] THEN + ASM_REWRITE_TAC[IN_UNIONS; EXISTS_IN_IMAGE; IN_UNIV] THEN + ASM SET_TAC[]; + ALL_TAC] THEN + ONCE_REWRITE_TAC[GSYM SIMPLE_IMAGE] THEN + MATCH_MP_TAC MEASURE_COUNTABLE_UNIONS_LE THEN + REWRITE_TAC[MEASURABLE_INTERVAL] THEN X_GEN_TAC `n:num` THEN + MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC + `sum(0..n) (\i. measure(interval[a i:real^N,b i]) + e / &2 pow (i + 2))` THEN + ASM_SIMP_TAC[SUM_LE_NUMSEG] THEN REWRITE_TAC[SUM_ADD_NUMSEG] THEN + REWRITE_TAC[real_div; REAL_INV_MUL; SUM_LMUL; REAL_POW_ADD; SUM_RMUL] THEN + REWRITE_TAC[REAL_INV_POW; SUM_GP; LT] THEN CONV_TAC REAL_RAT_REDUCE_CONV THEN + MATCH_MP_TAC(REAL_ARITH + `s <= m + e / &2 /\ &0 <= e * x + ==> s + e * (&1 - x) / (&1 / &2) * &1 / &4 <= m + e`) THEN + ASM_SIMP_TAC[REAL_LE_MUL; REAL_POW_LE; REAL_LT_IMP_LE; + REAL_LE_DIV; REAL_POS] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP + (REWRITE_RULE[IMP_CONJ_ALT] REAL_LE_TRANS)) THEN + W(MP_TAC o PART_MATCH (rhs o rand) MEASURE_NEGLIGIBLE_UNIONS_IMAGE o + lhand o snd) THEN + REWRITE_TAC[FINITE_NUMSEG; MEASURABLE_INTERVAL] THEN ANTS_TAC THENL + [MAP_EVERY X_GEN_TAC [`i:num`; `j:num`] THEN STRIP_TAC THEN + ASM_CASES_TAC `interval[(a:num->real^N) i,b i] = interval[a j,b j]` THENL + [UNDISCH_TAC + `!m n. (d:num->real^N->bool) m = d n ==> m = n \/ d n = {}` THEN + DISCH_THEN(MP_TAC o SPECL [`i:num`; `j:num`]) THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN SUBST1_TAC THEN REWRITE_TAC[INTER_EMPTY; NEGLIGIBLE_EMPTY]; + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE + (BINDER_CONV o BINDER_CONV o RAND_CONV o LAND_CONV) + [GSYM INTERIOR_INTER]) THEN + DISCH_THEN(MP_TAC o SPECL [`i:num`; `j:num`]) THEN + ASM_REWRITE_TAC[] THEN + REWRITE_TAC[GSYM HAS_MEASURE_0; HAS_MEASURE_MEASURABLE_MEASURE] THEN + SIMP_TAC[MEASURABLE_INTER; MEASURABLE_INTERVAL] THEN + MATCH_MP_TAC(MESON[MEASURE_EMPTY] + `measure(interior s) = measure s + ==> interior s = {} ==> measure s = &0`) THEN + MATCH_MP_TAC MEASURE_INTERIOR THEN + SIMP_TAC[BOUNDED_INTER; BOUNDED_INTERVAL; NEGLIGIBLE_CONVEX_FRONTIER; + CONVEX_INTER; CONVEX_INTERVAL]]; + DISCH_THEN(SUBST1_TAC o SYM)] THEN + MATCH_MP_TAC MEASURE_SUBSET THEN CONJ_TAC THENL + [MATCH_MP_TAC MEASURABLE_UNIONS THEN + SIMP_TAC[FINITE_IMAGE; FORALL_IN_IMAGE; MEASURABLE_INTERVAL; + FINITE_NUMSEG]; + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC SUBSET_UNIONS THEN + ASM_REWRITE_TAC[SUBSET; FORALL_IN_IMAGE] THEN + ASM_REWRITE_TAC[IN_IMAGE; IN_UNIV] THEN MESON_TAC[]]);; + +let MEASURABLE_OUTER_OPEN = prove + (`!s:real^N->bool e. + measurable s /\ &0 < e + ==> ?t. open t /\ s SUBSET t /\ + measurable t /\ measure t < measure s + e`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`s:real^N->bool`; `e / &2`] + MEASURABLE_OUTER_OPEN_INTERVALS) THEN + ASM_REWRITE_TAC[REAL_HALF; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `d:(real^N->bool)->bool` THEN STRIP_TAC THEN + EXISTS_TAC `UNIONS d :real^N->bool` THEN + ASM_SIMP_TAC[REAL_ARITH `&0 < e /\ m <= s + e / &2 ==> m < s + e`] THEN + MATCH_MP_TAC OPEN_UNIONS THEN ASM_MESON_TAC[OPEN_INTERVAL]);; + +let MEASURABLE_INNER_COMPACT = prove + (`!s:real^N->bool e. + measurable s /\ &0 < e + ==> ?t. compact t /\ t SUBSET s /\ + measurable t /\ measure s < measure t + e`, + REPEAT STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [HAS_MEASURE_MEASURE]) THEN + GEN_REWRITE_TAC LAND_CONV [HAS_MEASURE_LIMIT] THEN + DISCH_THEN(MP_TAC o SPEC `e / &4`) THEN + ASM_SIMP_TAC[REAL_ARITH `&0 < e ==> &0 < e / &4`] THEN + DISCH_THEN(X_CHOOSE_THEN `B:real` (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + MP_TAC(ISPEC `ball(vec 0:real^N,B)` BOUNDED_SUBSET_CLOSED_INTERVAL) THEN + REWRITE_TAC[BOUNDED_BALL; LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`a:real^N`; `b:real^N`] THEN DISCH_TAC THEN + DISCH_THEN(MP_TAC o SPECL [`a:real^N`; `b:real^N`]) THEN + ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `z:real` THEN STRIP_TAC THEN + MP_TAC(ISPECL [`interval[a:real^N,b] DIFF s`; `e/ &4`] + MEASURABLE_OUTER_OPEN) THEN + ASM_SIMP_TAC[MEASURABLE_DIFF; MEASURABLE_INTERVAL; + REAL_ARITH `&0 < e ==> &0 < e / &4`] THEN + DISCH_THEN(X_CHOOSE_THEN `t:real^N->bool` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `interval[a:real^N,b] DIFF t` THEN REPEAT CONJ_TAC THENL + [REWRITE_TAC[COMPACT_EQ_BOUNDED_CLOSED] THEN + ASM_SIMP_TAC[CLOSED_DIFF; CLOSED_INTERVAL; BOUNDED_DIFF; BOUNDED_INTERVAL]; + ASM SET_TAC[]; + ASM_SIMP_TAC[MEASURABLE_DIFF; MEASURABLE_INTERVAL]; + MATCH_MP_TAC(REAL_ARITH + `&0 < e /\ + measure(s) < measure(interval[a,b] INTER s) + e / &4 /\ + measure(t) < measure(interval[a,b] DIFF s) + e / &4 /\ + measure(interval[a,b] INTER s) + + measure(interval[a,b] DIFF s) = measure(interval[a,b]) /\ + measure(interval[a,b] INTER t) + + measure(interval[a,b] DIFF t) = measure(interval[a,b]) /\ + measure(interval[a,b] INTER t) <= measure t + ==> measure s < measure(interval[a,b] DIFF t) + e`) THEN + ASM_SIMP_TAC[MEASURE_SUBSET; INTER_SUBSET; MEASURABLE_INTER; + MEASURABLE_INTERVAL] THEN + CONJ_TAC THENL + [FIRST_ASSUM(SUBST_ALL_TAC o SYM o MATCH_MP MEASURE_UNIQUE) THEN + ONCE_REWRITE_TAC[INTER_COMM] THEN ASM_REAL_ARITH_TAC; + CONJ_TAC THEN MATCH_MP_TAC MEASURE_DISJOINT_UNION_EQ THEN + ASM_SIMP_TAC[MEASURABLE_INTER; MEASURABLE_DIFF; MEASURABLE_INTERVAL] THEN + SET_TAC[]]]);; + +let OPEN_MEASURABLE_INNER_DIVISION = prove + (`!s:real^N->bool e. + open s /\ measurable s /\ &0 < e + ==> ?D. D division_of UNIONS D /\ + UNIONS D SUBSET s /\ + measure s < measure(UNIONS D) + e`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`s:real^N->bool`; `e / &2`] MEASURE_LIMIT) THEN + ASM_REWRITE_TAC[REAL_HALF; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `B:real` THEN STRIP_TAC THEN + MP_TAC(ISPEC `ball(vec 0:real^N,B)` BOUNDED_SUBSET_CLOSED_INTERVAL) THEN + ASM_REWRITE_TAC[BOUNDED_BALL; LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`a:real^N`; `b:real^N`] THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`a:real^N`; `b:real^N`]) THEN + ASM_REWRITE_TAC[] THEN DISCH_TAC THEN + MP_TAC(ISPEC `s INTER interval(a - vec 1:real^N,b + vec 1)` + OPEN_COUNTABLE_UNION_CLOSED_INTERVALS) THEN + ASM_SIMP_TAC[OPEN_INTER; OPEN_INTERVAL; SUBSET_INTER] THEN + DISCH_THEN(X_CHOOSE_THEN `D:(real^N->bool)->bool` STRIP_ASSUME_TAC) THEN + MP_TAC(ISPECL [`D:(real^N->bool)->bool`; `measure(s:real^N->bool)`; + `e / &2`] MEASURE_COUNTABLE_UNIONS_APPROACHABLE) THEN + ASM_REWRITE_TAC[REAL_HALF] THEN ANTS_TAC THENL + [CONJ_TAC THENL [ASM_MESON_TAC[MEASURABLE_INTERVAL]; ALL_TAC] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `measure(UNIONS D :real^N->bool)` THEN CONJ_TAC THENL + [MATCH_MP_TAC MEASURE_SUBSET THEN REPEAT CONJ_TAC THENL + [MATCH_MP_TAC MEASURABLE_UNIONS THEN + ASM_MESON_TAC[SUBSET; MEASURABLE_INTERVAL]; + ASM_SIMP_TAC[MEASURABLE_INTER; MEASURABLE_INTERVAL]; + ASM_SIMP_TAC[SUBSET_UNIONS]]; + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC MEASURE_SUBSET THEN + ASM_SIMP_TAC[MEASURABLE_INTER; MEASURABLE_INTERVAL; INTER_SUBSET]]; + DISCH_THEN(X_CHOOSE_THEN `d:(real^N->bool)->bool` STRIP_ASSUME_TAC) THEN + MP_TAC(ISPEC `d:(real^N->bool)->bool` ELEMENTARY_UNIONS_INTERVALS) THEN + ANTS_TAC THENL [ASM_MESON_TAC[MEASURABLE_INTERVAL; SUBSET]; ALL_TAC] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `p:(real^N->bool)->bool` THEN + DISCH_TAC THEN + SUBGOAL_THEN `UNIONS p :real^N->bool = UNIONS d` SUBST1_TAC THENL + [ASM_MESON_TAC[division_of]; ALL_TAC] THEN + ASM_REWRITE_TAC[] THEN CONJ_TAC THENL + [MATCH_MP_TAC SUBSET_TRANS THEN + EXISTS_TAC `UNIONS D :real^N->bool` THEN + ASM_SIMP_TAC[SUBSET_UNIONS; INTER_SUBSET]; + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH + `ms' - e / &2 < mud ==> ms < ms' + e / &2 ==> ms < mud + e`)) THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH + `abs(sc - s) < e / &2 + ==> sc <= so /\ sc <= s ==> s < so + e / &2`)) THEN + CONJ_TAC THEN MATCH_MP_TAC MEASURE_SUBSET THEN + ASM_SIMP_TAC[MEASURABLE_INTER; MEASURABLE_INTERVAL; INTER_SUBSET] THEN + MATCH_MP_TAC(SET_RULE `t SUBSET u ==> s INTER t SUBSET s INTER u`) THEN + REWRITE_TAC[SUBSET_INTERVAL; VECTOR_SUB_COMPONENT; VEC_COMPONENT; + VECTOR_ADD_COMPONENT] THEN + MATCH_MP_TAC MONO_FORALL THEN GEN_TAC THEN + MATCH_MP_TAC MONO_IMP THEN REWRITE_TAC[] THEN REAL_ARITH_TAC]]);; + +(* ------------------------------------------------------------------------- *) +(* Hence for linear transformation, suffices to check compact intervals. *) +(* ------------------------------------------------------------------------- *) + +let MEASURABLE_LINEAR_IMAGE_INTERVAL = prove + (`!f a b. linear f ==> measurable(IMAGE f (interval[a,b]))`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC MEASURABLE_CONVEX THEN CONJ_TAC THENL + [MATCH_MP_TAC CONVEX_LINEAR_IMAGE THEN + ASM_MESON_TAC[CONVEX_INTERVAL]; + MATCH_MP_TAC BOUNDED_LINEAR_IMAGE THEN + ASM_MESON_TAC[BOUNDED_INTERVAL]]);; + +let HAS_MEASURE_LINEAR_SUFFICIENT = prove + (`!f:real^N->real^N m. + linear f /\ + (!a b. IMAGE f (interval[a,b]) has_measure + (m * measure(interval[a,b]))) + ==> !s. measurable s ==> (IMAGE f s) has_measure (m * measure s)`, + REPEAT GEN_TAC THEN STRIP_TAC THEN + DISJ_CASES_TAC(REAL_ARITH `m < &0 \/ &0 <= m`) THENL + [FIRST_X_ASSUM(MP_TAC o SPECL [`vec 0:real^N`; `vec 1:real^N`]) THEN + DISCH_THEN(MP_TAC o MATCH_MP HAS_MEASURE_POS_LE) THEN + MATCH_MP_TAC(TAUT `~a ==> a ==> b`) THEN + MATCH_MP_TAC(REAL_ARITH `&0 < --m * x ==> ~(&0 <= m * x)`) THEN + MATCH_MP_TAC REAL_LT_MUL THEN ASM_REWRITE_TAC[REAL_NEG_GT0] THEN + REWRITE_TAC[MEASURE_INTERVAL] THEN MATCH_MP_TAC CONTENT_POS_LT THEN + SIMP_TAC[VEC_COMPONENT; REAL_LT_01]; + ALL_TAC] THEN + ASM_CASES_TAC `!x y. (f:real^N->real^N) x = f y ==> x = y` THENL + [ALL_TAC; + SUBGOAL_THEN `!s. negligible(IMAGE (f:real^N->real^N) s)` ASSUME_TAC THENL + [ASM_MESON_TAC[NEGLIGIBLE_LINEAR_SINGULAR_IMAGE]; ALL_TAC] THEN + SUBGOAL_THEN `m * measure(interval[vec 0:real^N,vec 1]) = &0` MP_TAC THENL + [MATCH_MP_TAC(ISPEC `IMAGE (f:real^N->real^N) (interval[vec 0,vec 1])` + HAS_MEASURE_UNIQUE) THEN + ASM_REWRITE_TAC[HAS_MEASURE_0]; + REWRITE_TAC[REAL_ENTIRE; MEASURE_INTERVAL] THEN + MATCH_MP_TAC(TAUT `~b /\ (a ==> c) ==> a \/ b ==> c`) THEN CONJ_TAC THENL + [SIMP_TAC[CONTENT_EQ_0_INTERIOR; INTERIOR_CLOSED_INTERVAL; + INTERVAL_NE_EMPTY; VEC_COMPONENT; REAL_LT_01]; + ASM_SIMP_TAC[REAL_MUL_LZERO; HAS_MEASURE_0]]]] THEN + MP_TAC(ISPEC `f:real^N->real^N` LINEAR_INJECTIVE_ISOMORPHISM) THEN + ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `h:real^N->real^N` STRIP_ASSUME_TAC) THEN + UNDISCH_THEN `!x y. (f:real^N->real^N) x = f y ==> x = y` (K ALL_TAC) THEN + SUBGOAL_THEN + `!s. bounded s /\ measurable s + ==> (IMAGE (f:real^N->real^N) s) has_measure (m * measure s)` + ASSUME_TAC THENL + [REPEAT STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o MATCH_MP BOUNDED_SUBSET_CLOSED_INTERVAL) THEN + REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`a:real^N`; `b:real^N`] THEN DISCH_TAC THEN + SUBGOAL_THEN + `!d. COUNTABLE d /\ + (!k. k IN d ==> k SUBSET interval[a,b] /\ ~(k = {}) /\ + (?c d. k = interval[c,d])) /\ + (!k1 k2. k1 IN d /\ k2 IN d /\ ~(k1 = k2) + ==> interior k1 INTER interior k2 = {}) + ==> IMAGE (f:real^N->real^N) (UNIONS d) has_measure + (m * measure(UNIONS d))` + ASSUME_TAC THENL + [REWRITE_TAC[IMAGE_UNIONS] THEN REPEAT STRIP_TAC THEN + SUBGOAL_THEN + `!g:real^N->real^N. + linear g + ==> !k l. k IN d /\ l IN d /\ ~(k = l) + ==> negligible((IMAGE g k) INTER (IMAGE g l))` + MP_TAC THENL + [REPEAT STRIP_TAC THEN + ASM_CASES_TAC `!x y. (g:real^N->real^N) x = g y ==> x = y` THENL + [ALL_TAC; + ASM_MESON_TAC[NEGLIGIBLE_LINEAR_SINGULAR_IMAGE; + NEGLIGIBLE_INTER]] THEN + MATCH_MP_TAC NEGLIGIBLE_SUBSET THEN + EXISTS_TAC `frontier(IMAGE (g:real^N->real^N) k INTER IMAGE g l) UNION + interior(IMAGE g k INTER IMAGE g l)` THEN + CONJ_TAC THENL + [ALL_TAC; + REWRITE_TAC[frontier] THEN MATCH_MP_TAC(SET_RULE + `s SUBSET t ==> s SUBSET (t DIFF u) UNION u`) THEN + REWRITE_TAC[CLOSURE_SUBSET]] THEN + MATCH_MP_TAC NEGLIGIBLE_UNION THEN CONJ_TAC THENL + [MATCH_MP_TAC NEGLIGIBLE_CONVEX_FRONTIER THEN + MATCH_MP_TAC CONVEX_INTER THEN CONJ_TAC THEN + MATCH_MP_TAC CONVEX_LINEAR_IMAGE THEN ASM_MESON_TAC[CONVEX_INTERVAL]; + ALL_TAC] THEN + REWRITE_TAC[INTERIOR_INTER] THEN MATCH_MP_TAC NEGLIGIBLE_SUBSET THEN + EXISTS_TAC `IMAGE (g:real^N->real^N) (interior k) INTER + IMAGE g (interior l)` THEN + CONJ_TAC THENL + [MATCH_MP_TAC NEGLIGIBLE_SUBSET THEN + EXISTS_TAC + `IMAGE (g:real^N->real^N) (interior k INTER interior l)` THEN + CONJ_TAC THENL + [ASM_SIMP_TAC[IMAGE_CLAUSES; NEGLIGIBLE_EMPTY]; ASM SET_TAC[]]; + MATCH_MP_TAC(SET_RULE + `s SUBSET u /\ t SUBSET v ==> (s INTER t) SUBSET (u INTER v)`) THEN + CONJ_TAC THEN MATCH_MP_TAC INTERIOR_IMAGE_SUBSET THEN + ASM_MESON_TAC[LINEAR_CONTINUOUS_AT]]; + ALL_TAC] THEN + DISCH_THEN(fun th -> MP_TAC(SPEC `f:real^N->real^N` th) THEN + MP_TAC(SPEC `\x:real^N. x` th)) THEN + ASM_REWRITE_TAC[LINEAR_ID; SET_RULE `IMAGE (\x. x) s = s`] THEN + REPEAT STRIP_TAC THEN ASM_CASES_TAC `FINITE(d:(real^N->bool)->bool)` THENL + [MP_TAC(ISPECL [`IMAGE (f:real^N->real^N)`; `d:(real^N->bool)->bool`] + HAS_MEASURE_NEGLIGIBLE_UNIONS_IMAGE) THEN + ANTS_TAC THENL [ASM_MESON_TAC[measurable]; ALL_TAC] THEN + MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN + MATCH_MP_TAC EQ_TRANS THEN + EXISTS_TAC `sum d (\k:real^N->bool. m * measure k)` THEN CONJ_TAC THENL + [MATCH_MP_TAC SUM_EQ THEN ASM_MESON_TAC[MEASURE_UNIQUE]; ALL_TAC] THEN + REWRITE_TAC[SUM_LMUL] THEN AP_TERM_TAC THEN + CONV_TAC SYM_CONV THEN MATCH_MP_TAC MEASURE_NEGLIGIBLE_UNIONS THEN + ASM_REWRITE_TAC[GSYM HAS_MEASURE_MEASURE] THEN + ASM_MESON_TAC[MEASURABLE_INTERVAL]; + ALL_TAC] THEN + MP_TAC(ISPEC `d:(real^N->bool)->bool` COUNTABLE_AS_INJECTIVE_IMAGE) THEN + ASM_REWRITE_TAC[INFINITE] THEN + DISCH_THEN(X_CHOOSE_THEN `s:num->real^N->bool` + (CONJUNCTS_THEN2 SUBST_ALL_TAC ASSUME_TAC)) THEN + MP_TAC(ISPEC `s:num->real^N->bool` + HAS_MEASURE_COUNTABLE_NEGLIGIBLE_UNIONS_BOUNDED) THEN + MP_TAC(ISPEC `\n:num. IMAGE (f:real^N->real^N) (s n)` + HAS_MEASURE_COUNTABLE_NEGLIGIBLE_UNIONS_BOUNDED) THEN + RULE_ASSUM_TAC(REWRITE_RULE[IMP_CONJ; RIGHT_FORALL_IMP_THM; + FORALL_IN_IMAGE; IN_UNIV]) THEN + RULE_ASSUM_TAC(REWRITE_RULE[IMP_IMP; RIGHT_IMP_FORALL_THM]) THEN + ASM_SIMP_TAC[] THEN ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN ANTS_TAC THENL + [REPEAT CONJ_TAC THENL + [ASM_MESON_TAC[MEASURABLE_LINEAR_IMAGE_INTERVAL]; + ASM_MESON_TAC[]; + ONCE_REWRITE_TAC[GSYM o_DEF] THEN + REWRITE_TAC[GSYM IMAGE_UNIONS; IMAGE_o] THEN + MATCH_MP_TAC BOUNDED_LINEAR_IMAGE THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC BOUNDED_SUBSET THEN REWRITE_TAC[UNIONS_SUBSET] THEN + EXISTS_TAC `interval[a:real^N,b]` THEN + REWRITE_TAC[BOUNDED_INTERVAL] THEN ASM SET_TAC[]]; + ALL_TAC] THEN + STRIP_TAC THEN ANTS_TAC THENL + [REPEAT CONJ_TAC THENL + [ASM_MESON_TAC[MEASURABLE_INTERVAL]; + ASM_MESON_TAC[]; + MATCH_MP_TAC BOUNDED_SUBSET THEN REWRITE_TAC[UNIONS_SUBSET] THEN + EXISTS_TAC `interval[a:real^N,b]` THEN + REWRITE_TAC[BOUNDED_INTERVAL] THEN ASM SET_TAC[]]; + ALL_TAC] THEN + STRIP_TAC THEN REWRITE_TAC[GSYM IMAGE_o; o_DEF] THEN + SUBGOAL_THEN `m * measure (UNIONS (IMAGE s (:num)):real^N->bool) = + measure(UNIONS (IMAGE (\x. IMAGE f (s x)) (:num)):real^N->bool)` + (fun th -> ASM_REWRITE_TAC[GSYM HAS_MEASURE_MEASURE; th]) THEN + ONCE_REWRITE_TAC[GSYM LIFT_EQ] THEN + MATCH_MP_TAC SERIES_UNIQUE THEN + EXISTS_TAC `\n:num. lift(measure(IMAGE (f:real^N->real^N) (s n)))` THEN + EXISTS_TAC `from 0` THEN ASM_REWRITE_TAC[] THEN MATCH_MP_TAC SUMS_EQ THEN + EXISTS_TAC `\n:num. m % lift(measure(s n:real^N->bool))` THEN + CONJ_TAC THENL + [REWRITE_TAC[GSYM LIFT_CMUL; LIFT_EQ] THEN + ASM_MESON_TAC[MEASURE_UNIQUE]; + REWRITE_TAC[LIFT_CMUL] THEN MATCH_MP_TAC SERIES_CMUL THEN + ASM_REWRITE_TAC[]]; + ALL_TAC] THEN + REWRITE_TAC[HAS_MEASURE_INNER_OUTER_LE] THEN CONJ_TAC THEN + X_GEN_TAC `e:real` THEN DISCH_TAC THENL + [MP_TAC(ISPECL [`interval[a,b] DIFF s:real^N->bool`; `a:real^N`; + `b:real^N`; `e / (&1 + abs m)`] MEASURABLE_OUTER_INTERVALS_BOUNDED) THEN + ANTS_TAC THENL + [ASM_SIMP_TAC[MEASURABLE_DIFF; MEASURABLE_INTERVAL] THEN + ASM_SIMP_TAC[REAL_ARITH `&0 < &1 + abs x`; REAL_LT_DIV] THEN SET_TAC[]; + ALL_TAC] THEN + DISCH_THEN(X_CHOOSE_THEN `d:(real^N->bool)->bool` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `IMAGE f (interval[a,b]) DIFF + IMAGE (f:real^N->real^N) (UNIONS d)` THEN + FIRST_X_ASSUM(MP_TAC o SPEC `d:(real^N->bool)->bool`) THEN + ASM_SIMP_TAC[IMAGE_SUBSET] THEN DISCH_TAC THEN + CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN CONJ_TAC THENL + [ASM_MESON_TAC[MEASURABLE_DIFF; measurable]; ALL_TAC] THEN + MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `measure(IMAGE f (interval[a,b])) - + measure(IMAGE (f:real^N->real^N) (UNIONS d))` THEN + CONJ_TAC THENL + [ALL_TAC; + MATCH_MP_TAC REAL_EQ_IMP_LE THEN CONV_TAC SYM_CONV THEN + MATCH_MP_TAC MEASURE_DIFF_SUBSET THEN + REPEAT(CONJ_TAC THENL [ASM_MESON_TAC[measurable]; ALL_TAC]) THEN + MATCH_MP_TAC IMAGE_SUBSET THEN ASM_SIMP_TAC[UNIONS_SUBSET]] THEN + UNDISCH_TAC `!a b. IMAGE (f:real^N->real^N) (interval [a,b]) + has_measure m * measure (interval [a,b])` THEN + DISCH_THEN(ASSUME_TAC o SPECL [`a:real^N`; `b:real^N`]) THEN + REPEAT(FIRST_X_ASSUM(SUBST1_TAC o MATCH_MP MEASURE_UNIQUE)) THEN + MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `m * measure(s:real^N->bool) - m * e / (&1 + abs m)` THEN + CONJ_TAC THENL + [REWRITE_TAC[REAL_ARITH `a - x <= a - y <=> y <= x`] THEN + REWRITE_TAC[real_div; REAL_MUL_ASSOC] THEN + REWRITE_TAC[GSYM real_div] THEN + ASM_SIMP_TAC[REAL_LE_LDIV_EQ; REAL_ARITH `&0 < &1 + abs x`] THEN + GEN_REWRITE_TAC RAND_CONV [REAL_MUL_SYM] THEN + ASM_SIMP_TAC[REAL_LE_RMUL_EQ] THEN REAL_ARITH_TAC; + ALL_TAC] THEN + REWRITE_TAC[GSYM REAL_SUB_LDISTRIB] THEN MATCH_MP_TAC REAL_LE_LMUL THEN + ASM_REWRITE_TAC[] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH + `d <= a + e ==> a = i - s ==> s - e <= i - d`)) THEN + MATCH_MP_TAC MEASURE_DIFF_SUBSET THEN + ASM_REWRITE_TAC[MEASURABLE_INTERVAL]; + MP_TAC(ISPECL [`s:real^N->bool`; `a:real^N`; `b:real^N`; + `e / (&1 + abs m)`] MEASURABLE_OUTER_INTERVALS_BOUNDED) THEN + ASM_SIMP_TAC[REAL_LT_DIV; REAL_ARITH `&0 < &1 + abs x`] THEN + DISCH_THEN(X_CHOOSE_THEN `d:(real^N->bool)->bool` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `IMAGE (f:real^N->real^N) (UNIONS d)` THEN + FIRST_X_ASSUM(MP_TAC o SPEC `d:(real^N->bool)->bool`) THEN + ASM_SIMP_TAC[IMAGE_SUBSET] THEN + SIMP_TAC[HAS_MEASURE_MEASURABLE_MEASURE] THEN STRIP_TAC THEN + MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `m * measure(s:real^N->bool) + m * e / (&1 + abs m)` THEN + CONJ_TAC THENL + [REWRITE_TAC[GSYM REAL_ADD_LDISTRIB] THEN ASM_SIMP_TAC[REAL_LE_LMUL]; + REWRITE_TAC[REAL_LE_LADD] THEN + REWRITE_TAC[real_div; REAL_MUL_ASSOC] THEN + REWRITE_TAC[GSYM real_div] THEN + ASM_SIMP_TAC[REAL_LE_LDIV_EQ; REAL_ARITH `&0 < &1 + abs x`] THEN + GEN_REWRITE_TAC RAND_CONV [REAL_MUL_SYM] THEN + ASM_SIMP_TAC[REAL_LE_RMUL_EQ] THEN REAL_ARITH_TAC]]; + ALL_TAC] THEN + REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[HAS_MEASURE_LIMIT] THEN + X_GEN_TAC `e:real` THEN DISCH_TAC THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [HAS_MEASURE_MEASURE]) THEN + GEN_REWRITE_TAC LAND_CONV [HAS_MEASURE_LIMIT] THEN + DISCH_THEN(MP_TAC o SPEC `e / (&1 + abs m)`) THEN + ASM_SIMP_TAC[REAL_LT_DIV; REAL_ARITH `&0 < &1 + abs x`] THEN + DISCH_THEN(X_CHOOSE_THEN `B:real` + (CONJUNCTS_THEN2 ASSUME_TAC (LABEL_TAC "*"))) THEN + MP_TAC(ISPEC `ball(vec 0:real^N,B)` BOUNDED_SUBSET_CLOSED_INTERVAL) THEN + REWRITE_TAC[BOUNDED_BALL; LEFT_IMP_EXISTS_THM] THEN + REMOVE_THEN "*" MP_TAC THEN + MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `c:real^N` THEN + MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `d:real^N` THEN + DISCH_THEN(fun th -> DISCH_TAC THEN MP_TAC th) THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `z:real` STRIP_ASSUME_TAC) THEN + MP_TAC(ISPECL [`interval[c:real^N,d]`; `vec 0:real^N`] + BOUNDED_SUBSET_BALL) THEN + REWRITE_TAC[BOUNDED_INTERVAL] THEN + DISCH_THEN(X_CHOOSE_THEN `D:real` STRIP_ASSUME_TAC) THEN + MP_TAC(ISPEC `f:real^N->real^N` LINEAR_BOUNDED_POS) THEN + ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `C:real` STRIP_ASSUME_TAC) THEN + + EXISTS_TAC `D * C:real` THEN ASM_SIMP_TAC[REAL_LT_MUL] THEN + MAP_EVERY X_GEN_TAC [`a:real^N`; `b:real^N`] THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC + `s INTER (IMAGE (h:real^N->real^N) (interval[a,b]))`) THEN + SUBGOAL_THEN + `IMAGE (f:real^N->real^N) (s INTER IMAGE h (interval [a,b])) = + (IMAGE f s) INTER interval[a,b]` + SUBST1_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN ANTS_TAC THENL + [ASM_SIMP_TAC[BOUNDED_INTER; BOUNDED_LINEAR_IMAGE; BOUNDED_INTERVAL] THEN + ASM_SIMP_TAC[MEASURABLE_INTER; MEASURABLE_LINEAR_IMAGE_INTERVAL]; + ALL_TAC] THEN + DISCH_TAC THEN EXISTS_TAC + `m * measure(s INTER (IMAGE (h:real^N->real^N) (interval[a,b])))` THEN + ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC REAL_LET_TRANS THEN EXISTS_TAC `m * e / (&1 + abs m)` THEN + CONJ_TAC THENL + [ALL_TAC; + REWRITE_TAC[real_div; REAL_MUL_ASSOC] THEN REWRITE_TAC[GSYM real_div] THEN + ASM_SIMP_TAC[REAL_LT_LDIV_EQ; REAL_ARITH `&0 < &1 + abs x`] THEN + GEN_REWRITE_TAC RAND_CONV [REAL_MUL_SYM] THEN + ASM_SIMP_TAC[REAL_LT_RMUL_EQ] THEN REAL_ARITH_TAC] THEN + REWRITE_TAC[GSYM REAL_SUB_LDISTRIB; REAL_ABS_MUL] THEN + GEN_REWRITE_TAC (LAND_CONV o LAND_CONV) [real_abs] THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC REAL_LE_LMUL THEN ASM_REWRITE_TAC[] THEN + FIRST_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH + `abs(z - m) < e ==> z <= w /\ w <= m ==> abs(w - m) <= e`)) THEN + SUBST1_TAC(SYM(MATCH_MP MEASURE_UNIQUE + (ASSUME `s INTER interval [c:real^N,d] has_measure z`))) THEN + CONJ_TAC THEN MATCH_MP_TAC MEASURE_SUBSET THEN + ASM_SIMP_TAC[MEASURABLE_INTER; MEASURABLE_LINEAR_IMAGE_INTERVAL; + MEASURABLE_INTERVAL; INTER_SUBSET] THEN + MATCH_MP_TAC(SET_RULE + `!v. t SUBSET v /\ v SUBSET u ==> s INTER t SUBSET s INTER u`) THEN + EXISTS_TAC `ball(vec 0:real^N,D)` THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC(SET_RULE + `!f. (!x. h(f x) = x) /\ IMAGE f s SUBSET t ==> s SUBSET IMAGE h t`) THEN + EXISTS_TAC `f:real^N->real^N` THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC SUBSET_TRANS THEN EXISTS_TAC `ball(vec 0:real^N,D * C)` THEN + ASM_REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; IN_BALL_0] THEN + X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN + MATCH_MP_TAC REAL_LET_TRANS THEN EXISTS_TAC `C * norm(x:real^N)` THEN + ASM_REWRITE_TAC[] THEN GEN_REWRITE_TAC RAND_CONV [REAL_MUL_SYM] THEN + ASM_SIMP_TAC[REAL_LT_LMUL_EQ]);; + +(* ------------------------------------------------------------------------- *) +(* Some inductions by expressing mapping in terms of elementary matrices. *) +(* ------------------------------------------------------------------------- *) + +let INDUCT_MATRIX_ROW_OPERATIONS = prove + (`!P:real^N^N->bool. + (!A i. 1 <= i /\ i <= dimindex(:N) /\ row i A = vec 0 ==> P A) /\ + (!A. (!i j. 1 <= i /\ i <= dimindex(:N) /\ + 1 <= j /\ j <= dimindex(:N) /\ ~(i = j) + ==> A$i$j = &0) ==> P A) /\ + (!A m n. P A /\ 1 <= m /\ m <= dimindex(:N) /\ + 1 <= n /\ n <= dimindex(:N) /\ ~(m = n) + ==> P(lambda i j. A$i$(swap(m,n) j))) /\ + (!A m n c. P A /\ 1 <= m /\ m <= dimindex(:N) /\ + 1 <= n /\ n <= dimindex(:N) /\ ~(m = n) + ==> P(lambda i. if i = m then row m A + c % row n A + else row i A)) + ==> !A. P A`, + GEN_TAC THEN + DISCH_THEN(CONJUNCTS_THEN2 (LABEL_TAC "zero_row") MP_TAC) THEN + DISCH_THEN(CONJUNCTS_THEN2 (LABEL_TAC "diagonal") MP_TAC) THEN + DISCH_THEN(CONJUNCTS_THEN2 (LABEL_TAC "swap_cols") (LABEL_TAC "row_op")) THEN + SUBGOAL_THEN + `!k A:real^N^N. + (!i j. 1 <= i /\ i <= dimindex(:N) /\ + k <= j /\ j <= dimindex(:N) /\ ~(i = j) + ==> A$i$j = &0) + ==> P A` + (fun th -> GEN_TAC THEN MATCH_MP_TAC th THEN + EXISTS_TAC `dimindex(:N) + 1` THEN ARITH_TAC) THEN + MATCH_MP_TAC num_INDUCTION THEN CONJ_TAC THENL + [REPEAT STRIP_TAC THEN USE_THEN "diagonal" MATCH_MP_TAC THEN + REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_REWRITE_TAC[LE_0]; + ALL_TAC] THEN + X_GEN_TAC `k:num` THEN DISCH_THEN(LABEL_TAC "ind_hyp") THEN + DISJ_CASES_THEN2 SUBST1_TAC ASSUME_TAC (ARITH_RULE `k = 0 \/ 1 <= k`) THEN + ASM_REWRITE_TAC[ARITH] THEN + ASM_CASES_TAC `k <= dimindex(:N)` THENL + [ALL_TAC; + REPEAT STRIP_TAC THEN REMOVE_THEN "ind_hyp" MATCH_MP_TAC THEN + ASM_ARITH_TAC] THEN + SUBGOAL_THEN + `!A:real^N^N. + ~(A$k$k = &0) /\ + (!i j. 1 <= i /\ i <= dimindex (:N) /\ + SUC k <= j /\ j <= dimindex (:N) /\ ~(i = j) + ==> A$i$j = &0) + ==> P A` + (LABEL_TAC "nonzero_hyp") THENL + [ALL_TAC; + X_GEN_TAC `A:real^N^N` THEN DISCH_TAC THEN + ASM_CASES_TAC `row k (A:real^N^N) = vec 0` THENL + [REMOVE_THEN "zero_row" MATCH_MP_TAC THEN ASM_MESON_TAC[]; + ALL_TAC] THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE RAND_CONV [CART_EQ]) THEN + SIMP_TAC[VEC_COMPONENT; row; LAMBDA_BETA] THEN + REWRITE_TAC[NOT_FORALL_THM; NOT_IMP; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `l:num` THEN STRIP_TAC THEN + ASM_CASES_TAC `l:num = k` THENL + [REMOVE_THEN "nonzero_hyp" MATCH_MP_TAC THEN ASM_MESON_TAC[]; + ALL_TAC] THEN + REMOVE_THEN "swap_cols" (MP_TAC o SPECL + [`(lambda i j. (A:real^N^N)$i$swap(k,l) j):real^N^N`; + `k:num`; `l:num`]) THEN + ASM_SIMP_TAC[LAMBDA_BETA] THEN ANTS_TAC THENL + [ALL_TAC; + MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN + SIMP_TAC[CART_EQ; LAMBDA_BETA] THEN + REPEAT STRIP_TAC THEN REWRITE_TAC[swap] THEN + REPEAT(COND_CASES_TAC THEN ASM_SIMP_TAC[LAMBDA_BETA])] THEN + REMOVE_THEN "nonzero_hyp" MATCH_MP_TAC THEN + ONCE_REWRITE_TAC[ARITH_RULE `SUC k <= i <=> 1 <= i /\ SUC k <= i`] THEN + ASM_SIMP_TAC[LAMBDA_BETA] THEN + ASM_REWRITE_TAC[swap] THEN MAP_EVERY X_GEN_TAC [`i:num`; `j:num`] THEN + STRIP_TAC THEN SUBGOAL_THEN `l:num <= k` ASSUME_TAC THENL + [FIRST_X_ASSUM(MP_TAC o SPECL [`k:num`; `l:num`]) THEN + ASM_REWRITE_TAC[] THEN ARITH_TAC; + ALL_TAC] THEN + REPEAT(COND_CASES_TAC THEN ASM_REWRITE_TAC[]) THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[] THEN + ASM_ARITH_TAC] THEN + SUBGOAL_THEN + `!l A:real^N^N. + ~(A$k$k = &0) /\ + (!i j. 1 <= i /\ i <= dimindex (:N) /\ + SUC k <= j /\ j <= dimindex (:N) /\ ~(i = j) + ==> A$i$j = &0) /\ + (!i. l <= i /\ i <= dimindex(:N) /\ ~(i = k) ==> A$i$k = &0) + ==> P A` + MP_TAC THENL + [ALL_TAC; + DISCH_THEN(MP_TAC o SPEC `dimindex(:N) + 1`) THEN + REWRITE_TAC[CONJ_ASSOC; ARITH_RULE `~(n + 1 <= i /\ i <= n)`]] THEN + MATCH_MP_TAC num_INDUCTION THEN CONJ_TAC THENL + [GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + DISCH_THEN(CONJUNCTS_THEN2 (LABEL_TAC "main") (LABEL_TAC "aux")) THEN + USE_THEN "ind_hyp" MATCH_MP_TAC THEN + MAP_EVERY X_GEN_TAC [`i:num`; `j:num`] THEN STRIP_TAC THEN + ASM_CASES_TAC `j:num = k` THENL + [ASM_REWRITE_TAC[] THEN USE_THEN "aux" MATCH_MP_TAC THEN ASM_ARITH_TAC; + REMOVE_THEN "main" MATCH_MP_TAC THEN ASM_ARITH_TAC]; + ALL_TAC] THEN + X_GEN_TAC `l:num` THEN DISCH_THEN(LABEL_TAC "inner_hyp") THEN + GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + DISCH_THEN(CONJUNCTS_THEN2 (LABEL_TAC "main") (LABEL_TAC "aux")) THEN + ASM_CASES_TAC `l:num = k` THENL + [REMOVE_THEN "inner_hyp" MATCH_MP_TAC THEN ASM_REWRITE_TAC[] THEN + REPEAT STRIP_TAC THEN REMOVE_THEN "aux" MATCH_MP_TAC THEN ASM_ARITH_TAC; + ALL_TAC] THEN + DISJ_CASES_TAC(ARITH_RULE `l = 0 \/ 1 <= l`) THENL + [REMOVE_THEN "ind_hyp" MATCH_MP_TAC THEN + MAP_EVERY X_GEN_TAC [`i:num`; `j:num`] THEN STRIP_TAC THEN + ASM_CASES_TAC `j:num = k` THENL + [ASM_REWRITE_TAC[] THEN REMOVE_THEN "aux" MATCH_MP_TAC THEN ASM_ARITH_TAC; + REMOVE_THEN "main" MATCH_MP_TAC THEN ASM_ARITH_TAC]; + ALL_TAC] THEN + ASM_CASES_TAC `l <= dimindex(:N)` THENL + [ALL_TAC; + REMOVE_THEN "inner_hyp" MATCH_MP_TAC THEN ASM_REWRITE_TAC[] THEN + ASM_ARITH_TAC] THEN + REMOVE_THEN "inner_hyp" (MP_TAC o SPECL + [`(lambda i. if i = l then row l (A:real^N^N) + --(A$l$k/A$k$k) % row k A + else row i A):real^N^N`]) THEN + ANTS_TAC THENL + [SUBGOAL_THEN `!i. l <= i ==> 1 <= i` ASSUME_TAC THENL + [ASM_ARITH_TAC; ALL_TAC] THEN + ONCE_REWRITE_TAC[ARITH_RULE `SUC k <= j <=> 1 <= j /\ SUC k <= j`] THEN + ASM_SIMP_TAC[LAMBDA_BETA; row; COND_COMPONENT; + VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT] THEN + ASM_SIMP_TAC[REAL_FIELD `~(y = &0) ==> x + --(x / y) * y = &0`] THEN + REWRITE_TAC[AND_FORALL_THM] THEN X_GEN_TAC `i:num` THEN + ASM_CASES_TAC `i:num = l` THEN ASM_REWRITE_TAC[] THENL + [REPEAT STRIP_TAC THEN + MATCH_MP_TAC(REAL_RING `x = &0 /\ y = &0 ==> x + z * y = &0`) THEN + CONJ_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_ARITH_TAC; + REPEAT STRIP_TAC THEN REMOVE_THEN "aux" MATCH_MP_TAC THEN ASM_ARITH_TAC]; + ALL_TAC] THEN + DISCH_TAC THEN REMOVE_THEN "row_op" (MP_TAC o SPECL + [`(lambda i. if i = l then row l A + --(A$l$k / A$k$k) % row k A + else row i (A:real^N^N)):real^N^N`; + `l:num`; `k:num`; `(A:real^N^N)$l$k / A$k$k`]) THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN + ASM_SIMP_TAC[CART_EQ; LAMBDA_BETA; VECTOR_ADD_COMPONENT; + VECTOR_MUL_COMPONENT; row; COND_COMPONENT] THEN + REPEAT STRIP_TAC THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN + REAL_ARITH_TAC);; + +let INDUCT_MATRIX_ELEMENTARY = prove + (`!P:real^N^N->bool. + (!A B. P A /\ P B ==> P(A ** B)) /\ + (!A i. 1 <= i /\ i <= dimindex(:N) /\ row i A = vec 0 ==> P A) /\ + (!A. (!i j. 1 <= i /\ i <= dimindex(:N) /\ + 1 <= j /\ j <= dimindex(:N) /\ ~(i = j) + ==> A$i$j = &0) ==> P A) /\ + (!m n. 1 <= m /\ m <= dimindex(:N) /\ + 1 <= n /\ n <= dimindex(:N) /\ ~(m = n) + ==> P(lambda i j. (mat 1:real^N^N)$i$(swap(m,n) j))) /\ + (!m n c. 1 <= m /\ m <= dimindex(:N) /\ + 1 <= n /\ n <= dimindex(:N) /\ ~(m = n) + ==> P(lambda i j. if i = m /\ j = n then c + else if i = j then &1 else &0)) + ==> !A. P A`, + GEN_TAC THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + DISCH_THEN(fun th -> + MATCH_MP_TAC INDUCT_MATRIX_ROW_OPERATIONS THEN MP_TAC th) THEN + REPEAT(MATCH_MP_TAC MONO_AND THEN CONJ_TAC) THEN REWRITE_TAC[] THEN + DISCH_THEN(fun th -> X_GEN_TAC `A:real^N^N` 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_REWRITE_TAC[] THEN + UNDISCH_TAC `(P:real^N^N->bool) A` THENL + [REWRITE_TAC[GSYM IMP_CONJ]; REWRITE_TAC[GSYM IMP_CONJ_ALT]] THEN + DISCH_THEN(ANTE_RES_THEN MP_TAC) THEN MATCH_MP_TAC EQ_IMP THEN + AP_TERM_TAC THEN REWRITE_TAC[CART_EQ] THEN + X_GEN_TAC `i:num` THEN STRIP_TAC THEN + X_GEN_TAC `j:num` THEN STRIP_TAC THEN + ASM_SIMP_TAC[CART_EQ; LAMBDA_BETA; matrix_mul; row] THENL + [ASM_SIMP_TAC[mat; IN_DIMINDEX_SWAP; LAMBDA_BETA] THEN + ONCE_REWRITE_TAC[COND_RAND] THEN + SIMP_TAC[SUM_DELTA; REAL_MUL_RZERO; REAL_MUL_RID] THEN + COND_CASES_TAC THEN REWRITE_TAC[] THEN + RULE_ASSUM_TAC(REWRITE_RULE[swap; IN_NUMSEG]) THEN ASM_ARITH_TAC; + ALL_TAC] THEN + ASM_CASES_TAC `i:num = m` THEN ASM_REWRITE_TAC[] THENL + [ALL_TAC; + ONCE_REWRITE_TAC[COND_RAND] THEN ONCE_REWRITE_TAC[COND_RATOR] THEN + REWRITE_TAC[REAL_MUL_LZERO] THEN + GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [EQ_SYM_EQ] THEN + ASM_SIMP_TAC[SUM_DELTA; LAMBDA_BETA; IN_NUMSEG; REAL_MUL_LID]] THEN + ASM_SIMP_TAC[VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT; LAMBDA_BETA] THEN + MATCH_MP_TAC EQ_TRANS THEN + EXISTS_TAC + `sum {m,n} (\k. (if k = n then c else if m = k then &1 else &0) * + (A:real^N^N)$k$j)` THEN + CONJ_TAC THENL + [MATCH_MP_TAC SUM_SUPERSET THEN + ASM_SIMP_TAC[SUBSET; IN_INSERT; NOT_IN_EMPTY; DE_MORGAN_THM; + IN_NUMSEG; REAL_MUL_LZERO] THEN + ASM_ARITH_TAC; + ASM_SIMP_TAC[SUM_CLAUSES; FINITE_RULES; IN_INSERT; NOT_IN_EMPTY] THEN + REAL_ARITH_TAC]);; + +let INDUCT_MATRIX_ELEMENTARY_ALT = prove + (`!P:real^N^N->bool. + (!A B. P A /\ P B ==> P(A ** B)) /\ + (!A i. 1 <= i /\ i <= dimindex(:N) /\ row i A = vec 0 ==> P A) /\ + (!A. (!i j. 1 <= i /\ i <= dimindex(:N) /\ + 1 <= j /\ j <= dimindex(:N) /\ ~(i = j) + ==> A$i$j = &0) ==> P A) /\ + (!m n. 1 <= m /\ m <= dimindex(:N) /\ + 1 <= n /\ n <= dimindex(:N) /\ ~(m = n) + ==> P(lambda i j. (mat 1:real^N^N)$i$(swap(m,n) j))) /\ + (!m n. 1 <= m /\ m <= dimindex(:N) /\ + 1 <= n /\ n <= dimindex(:N) /\ ~(m = n) + ==> P(lambda i j. if i = m /\ j = n \/ i = j then &1 else &0)) + ==> !A. P A`, + GEN_TAC THEN STRIP_TAC THEN MATCH_MP_TAC INDUCT_MATRIX_ELEMENTARY THEN + ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN + ASM_CASES_TAC `c = &0` THENL + [FIRST_X_ASSUM(fun th -> MATCH_MP_TAC th THEN + MAP_EVERY X_GEN_TAC [`i:num`; `j:num`]) THEN + ASM_SIMP_TAC[LAMBDA_BETA; COND_ID]; + ALL_TAC] THEN + SUBGOAL_THEN + `(lambda i j. if i = m /\ j = n then c else if i = j then &1 else &0) = + ((lambda i j. if i = j then if j = n then inv c else &1 else &0):real^N^N) ** + ((lambda i j. if i = m /\ j = n \/ i = j then &1 else &0):real^N^N) ** + ((lambda i j. if i = j then if j = n then c else &1 else &0):real^N^N)` + SUBST1_TAC THENL + [ALL_TAC; + REPEAT(MATCH_MP_TAC(ASSUME `!A B:real^N^N. P A /\ P B ==> P(A ** B)`) THEN + CONJ_TAC) THEN + ASM_SIMP_TAC[] THEN FIRST_X_ASSUM(fun th -> MATCH_MP_TAC th THEN + MAP_EVERY X_GEN_TAC [`i:num`; `j:num`]) THEN + ASM_SIMP_TAC[LAMBDA_BETA]] THEN + SIMP_TAC[CART_EQ; matrix_mul; LAMBDA_BETA] THEN + X_GEN_TAC `i:num` THEN STRIP_TAC THEN + X_GEN_TAC `j:num` THEN STRIP_TAC THEN + ASM_SIMP_TAC[SUM_DELTA; IN_NUMSEG; REAL_ARITH + `(if p then &1 else &0) * (if q then c else &0) = + if q then if p then c else &0 else &0`] THEN + REWRITE_TAC[REAL_ARITH + `(if p then x else &0) * y = (if p then x * y else &0)`] THEN + GEN_REWRITE_TAC (RAND_CONV o ONCE_DEPTH_CONV) [EQ_SYM_EQ] THEN + ASM_SIMP_TAC[SUM_DELTA; IN_NUMSEG] THEN + ASM_CASES_TAC `i:num = m` THEN ASM_REWRITE_TAC[] THEN + ASM_CASES_TAC `j:num = n` THEN ASM_REWRITE_TAC[REAL_MUL_LID; EQ_SYM_EQ] THEN + ASM_CASES_TAC `i:num = n` THEN + ASM_SIMP_TAC[REAL_MUL_LINV; REAL_MUL_LID; REAL_MUL_RZERO]);; + +(* ------------------------------------------------------------------------- *) +(* The same thing in mapping form (might have been easier all along). *) +(* ------------------------------------------------------------------------- *) + +let INDUCT_LINEAR_ELEMENTARY = prove + (`!P. (!f g. linear f /\ linear g /\ P f /\ P g ==> P(f o g)) /\ + (!f i. linear f /\ 1 <= i /\ i <= dimindex(:N) /\ (!x. (f x)$i = &0) + ==> P f) /\ + (!c. P(\x. lambda i. c i * x$i)) /\ + (!m n. 1 <= m /\ m <= dimindex(:N) /\ + 1 <= n /\ n <= dimindex(:N) /\ ~(m = n) + ==> P(\x. lambda i. x$swap(m,n) i)) /\ + (!m n. 1 <= m /\ m <= dimindex(:N) /\ + 1 <= n /\ n <= dimindex(:N) /\ ~(m = n) + ==> P(\x. lambda i. if i = m then x$m + x$n else x$i)) + ==> !f:real^N->real^N. linear f ==> P f`, + GEN_TAC THEN + MP_TAC(ISPEC `\A:real^N^N. P(\x:real^N. A ** x):bool` + INDUCT_MATRIX_ELEMENTARY_ALT) THEN + REWRITE_TAC[] THEN MATCH_MP_TAC MONO_IMP THEN CONJ_TAC THENL + [ALL_TAC; + DISCH_TAC THEN X_GEN_TAC `f:real^N->real^N` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `matrix(f:real^N->real^N)`) THEN + ASM_SIMP_TAC[MATRIX_WORKS] THEN REWRITE_TAC[ETA_AX]] THEN + MATCH_MP_TAC MONO_AND THEN CONJ_TAC THENL + [DISCH_TAC THEN MAP_EVERY X_GEN_TAC [`A:real^N^N`; `B:real^N^N`] THEN + STRIP_TAC THEN FIRST_X_ASSUM(MP_TAC o SPECL + [`\x:real^N. (A:real^N^N) ** x`; `\x:real^N. (B:real^N^N) ** x`]) THEN + ASM_REWRITE_TAC[MATRIX_VECTOR_MUL_LINEAR; o_DEF] THEN + REWRITE_TAC[MATRIX_VECTOR_MUL_ASSOC]; + ALL_TAC] THEN + MATCH_MP_TAC MONO_AND THEN CONJ_TAC THENL + [DISCH_TAC THEN MAP_EVERY X_GEN_TAC [`A:real^N^N`; `m:num`] THEN + STRIP_TAC THEN FIRST_X_ASSUM(MP_TAC o SPECL + [`\x:real^N. (A:real^N^N) ** x`; `m:num`]) THEN + ASM_REWRITE_TAC[MATRIX_VECTOR_MUL_LINEAR] THEN + DISCH_THEN MATCH_MP_TAC THEN + UNDISCH_TAC `row m (A:real^N^N) = vec 0` THEN + ASM_SIMP_TAC[CART_EQ; row; LAMBDA_BETA; VEC_COMPONENT; matrix_vector_mul; + REAL_MUL_LZERO; SUM_0]; + ALL_TAC] THEN + MATCH_MP_TAC MONO_AND THEN CONJ_TAC THENL + [DISCH_TAC THEN X_GEN_TAC `A:real^N^N` THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `\i. (A:real^N^N)$i$i`) THEN + MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN + ASM_SIMP_TAC[CART_EQ; matrix_vector_mul; FUN_EQ_THM; LAMBDA_BETA] THEN + MAP_EVERY X_GEN_TAC [`x:real^N`; `i:num`] THEN STRIP_TAC THEN + MATCH_MP_TAC EQ_TRANS THEN EXISTS_TAC + `sum(1..dimindex(:N)) (\j. if j = i then (A:real^N^N)$i$j * (x:real^N)$j + else &0)` THEN + CONJ_TAC THENL [ASM_SIMP_TAC[SUM_DELTA; IN_NUMSEG]; ALL_TAC] THEN + MATCH_MP_TAC SUM_EQ_NUMSEG THEN X_GEN_TAC `j:num` THEN STRIP_TAC THEN + ASM_SIMP_TAC[] THEN COND_CASES_TAC THEN ASM_SIMP_TAC[REAL_MUL_LZERO]; + ALL_TAC] THEN + MATCH_MP_TAC MONO_AND THEN CONJ_TAC 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 + DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN + ASM_SIMP_TAC[CART_EQ; matrix_vector_mul; FUN_EQ_THM; LAMBDA_BETA; + mat; IN_DIMINDEX_SWAP] + THENL + [ONCE_REWRITE_TAC[SWAP_GALOIS] THEN ONCE_REWRITE_TAC[COND_RAND] THEN + ONCE_REWRITE_TAC[COND_RATOR] THEN + SIMP_TAC[SUM_DELTA; REAL_MUL_LID; REAL_MUL_LZERO; IN_NUMSEG] THEN + REPEAT STRIP_TAC THEN REWRITE_TAC[swap] THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN ASM_ARITH_TAC; + MAP_EVERY X_GEN_TAC [`x:real^N`; `i:num`] THEN STRIP_TAC THEN + ASM_CASES_TAC `i:num = m` THEN ASM_REWRITE_TAC[] THEN + ONCE_REWRITE_TAC[COND_RAND] THEN ONCE_REWRITE_TAC[COND_RATOR] THEN + GEN_REWRITE_TAC (RAND_CONV o ONCE_DEPTH_CONV) [EQ_SYM_EQ] THEN + ASM_SIMP_TAC[SUM_DELTA; REAL_MUL_LZERO; REAL_MUL_LID; IN_NUMSEG] THEN + MATCH_MP_TAC EQ_TRANS THEN EXISTS_TAC + `sum {m,n} (\j. if n = j \/ j = m then (x:real^N)$j else &0)` THEN + CONJ_TAC THENL + [SIMP_TAC[SUM_CLAUSES; FINITE_RULES; IN_INSERT; NOT_IN_EMPTY] THEN + ASM_REWRITE_TAC[REAL_ADD_RID]; + CONV_TAC SYM_CONV THEN MATCH_MP_TAC SUM_SUPERSET THEN + ASM_SIMP_TAC[SUBSET; IN_INSERT; NOT_IN_EMPTY; DE_MORGAN_THM; + IN_NUMSEG; REAL_MUL_LZERO] THEN + ASM_ARITH_TAC]]);; + +(* ------------------------------------------------------------------------- *) +(* Hence the effect of an arbitrary linear map on a measurable set. *) +(* ------------------------------------------------------------------------- *) + +let LAMBDA_SWAP_GALOIS = prove + (`!x:real^N y:real^N. + 1 <= m /\ m <= dimindex(:N) /\ 1 <= n /\ n <= dimindex(:N) + ==> (x = (lambda i. y$swap(m,n) i) <=> + (lambda i. x$swap(m,n) i) = y)`, + SIMP_TAC[CART_EQ; LAMBDA_BETA; IN_DIMINDEX_SWAP] THEN + REPEAT GEN_TAC THEN STRIP_TAC THEN EQ_TAC THEN + DISCH_TAC THEN X_GEN_TAC `i:num` THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `swap(m,n) (i:num)`) THEN + ASM_SIMP_TAC[IN_DIMINDEX_SWAP] THEN + ASM_MESON_TAC[REWRITE_RULE[FUN_EQ_THM; o_THM; I_THM] SWAP_IDEMPOTENT]);; + +let LAMBDA_ADD_GALOIS = prove + (`!x:real^N y:real^N. + 1 <= m /\ m <= dimindex(:N) /\ 1 <= n /\ n <= dimindex(:N) /\ + ~(m = n) + ==> (x = (lambda i. if i = m then y$m + y$n else y$i) <=> + (lambda i. if i = m then x$m - x$n else x$i) = y)`, + SIMP_TAC[CART_EQ; LAMBDA_BETA] THEN + REPEAT GEN_TAC THEN STRIP_TAC THEN EQ_TAC THEN + DISCH_TAC THEN X_GEN_TAC `i:num` THEN STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o SPEC `n:num`) THEN + FIRST_X_ASSUM(MP_TAC o SPEC `i:num`) THEN + ASM_REWRITE_TAC[] THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN + REAL_ARITH_TAC);; + +let HAS_MEASURE_SHEAR_INTERVAL = prove + (`!a b:real^N m n. + 1 <= m /\ m <= dimindex(:N) /\ + 1 <= n /\ n <= dimindex(:N) /\ + ~(m = n) /\ ~(interval[a,b] = {}) /\ + &0 <= a$n + ==> (IMAGE (\x. (lambda i. if i = m then x$m + x$n else x$i)) + (interval[a,b]):real^N->bool) + has_measure measure (interval [a,b])`, + let lemma = prove + (`!s t u v:real^N->bool. + measurable s /\ measurable t /\ measurable u /\ + negligible(s INTER t) /\ negligible(s INTER u) /\ + negligible(t INTER u) /\ + s UNION t UNION u = v + ==> v has_measure (measure s) + (measure t) + (measure u)`, + REPEAT STRIP_TAC THEN + ASM_SIMP_TAC[HAS_MEASURE_MEASURABLE_MEASURE; MEASURABLE_UNION] THEN + FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN + ASM_SIMP_TAC[MEASURE_UNION; MEASURABLE_UNION] THEN + ASM_SIMP_TAC[MEASURE_EQ_0; UNION_OVER_INTER; MEASURE_UNION; + MEASURABLE_UNION; NEGLIGIBLE_INTER; MEASURABLE_INTER] THEN + REAL_ARITH_TAC) + and lemma' = prove + (`!s t u a:real^N. + measurable s /\ measurable t /\ + s UNION (IMAGE (\x. a + x) t) = u /\ + negligible(s INTER (IMAGE (\x. a + x) t)) + ==> measure s + measure t = measure u`, + REPEAT STRIP_TAC THEN FIRST_X_ASSUM(SUBST_ALL_TAC o SYM) THEN + ASM_SIMP_TAC[MEASURE_NEGLIGIBLE_UNION; MEASURABLE_TRANSLATION_EQ; + MEASURE_TRANSLATION]) in + REWRITE_TAC[INTERVAL_NE_EMPTY] THEN REPEAT STRIP_TAC THEN + SUBGOAL_THEN + `linear((\x. lambda i. if i = m then x$m + x$n else x$i):real^N->real^N)` + ASSUME_TAC THENL + [ASM_SIMP_TAC[linear; LAMBDA_BETA; VECTOR_ADD_COMPONENT; + VECTOR_MUL_COMPONENT; CART_EQ] THEN REAL_ARITH_TAC; + ALL_TAC] THEN + MP_TAC(ISPECL + [`IMAGE (\x. lambda i. if i = m then x$m + x$n else x$i) + (interval[a:real^N,b]):real^N->bool`; + `interval[a,(lambda i. if i = m then (b:real^N)$m + b$n else b$i)] INTER + {x:real^N | (basis m - basis n) dot x <= a$m}`; + `interval[a,(lambda i. if i = m then b$m + b$n else b$i)] INTER + {x:real^N | (basis m - basis n) dot x >= (b:real^N)$m}`; + `interval[a:real^N, + (lambda i. if i = m then (b:real^N)$m + b$n else b$i)]`] + lemma) THEN + ANTS_TAC THENL + [ASM_SIMP_TAC[CONVEX_LINEAR_IMAGE; CONVEX_INTERVAL; + CONVEX_HALFSPACE_LE; CONVEX_HALFSPACE_GE; + CONVEX_INTER; MEASURABLE_CONVEX; BOUNDED_INTER; + BOUNDED_LINEAR_IMAGE; BOUNDED_INTERVAL] THEN + REWRITE_TAC[INTER] THEN + REWRITE_TAC[EXTENSION; IN_UNION; IN_INTER; IN_IMAGE] THEN + ASM_SIMP_TAC[LAMBDA_ADD_GALOIS; UNWIND_THM1] THEN + ASM_SIMP_TAC[IN_INTERVAL; IN_ELIM_THM; LAMBDA_BETA; + DOT_BASIS; DOT_LSUB] THEN + ONCE_REWRITE_TAC[MESON[] + `(!i:num. P i) <=> P m /\ (!i. ~(i = m) ==> P i)`] THEN + ASM_SIMP_TAC[] THEN + REWRITE_TAC[TAUT `(p /\ x) /\ (q /\ x) /\ r <=> x /\ p /\ q /\ r`; + TAUT `(p /\ x) /\ q /\ (r /\ x) <=> x /\ p /\ q /\ r`; + TAUT `((p /\ x) /\ q) /\ (r /\ x) /\ s <=> + x /\ p /\ q /\ r /\ s`; + TAUT `(a /\ x \/ (b /\ x) /\ c \/ (d /\ x) /\ e <=> f /\ x) <=> + x ==> (a \/ b /\ c \/ d /\ e <=> f)`] THEN + ONCE_REWRITE_TAC[SET_RULE + `{x | P x /\ Q x} = {x | P x} INTER {x | Q x}`] THEN + REWRITE_TAC[CONJ_ASSOC] THEN CONJ_TAC THENL + [ALL_TAC; + GEN_TAC THEN DISCH_THEN(MP_TAC o SPEC `n:num`) THEN + ASM_REWRITE_TAC[] THEN ASM_REAL_ARITH_TAC] THEN + REWRITE_TAC[GSYM CONJ_ASSOC] THEN REPEAT CONJ_TAC THEN + MATCH_MP_TAC NEGLIGIBLE_INTER THEN DISJ2_TAC THEN + MATCH_MP_TAC NEGLIGIBLE_SUBSET THENL + [EXISTS_TAC `{x:real^N | (basis m - basis n) dot x = (a:real^N)$m}`; + EXISTS_TAC `{x:real^N | (basis m - basis n) dot x = (b:real^N)$m}`; + EXISTS_TAC `{x:real^N | (basis m - basis n) dot x = (b:real^N)$m}`] + THEN (CONJ_TAC THENL + [MATCH_MP_TAC NEGLIGIBLE_HYPERPLANE THEN + REWRITE_TAC[VECTOR_SUB_EQ] THEN + ASM_MESON_TAC[BASIS_INJ]; + ASM_SIMP_TAC[DOT_LSUB; DOT_BASIS; SUBSET; IN_ELIM_THM; + NOT_IN_EMPTY] THEN + FIRST_X_ASSUM(MP_TAC o SPEC `m:num`) THEN ASM_REWRITE_TAC[] THEN + ASM_REAL_ARITH_TAC]); + ALL_TAC] THEN + ASM_SIMP_TAC[HAS_MEASURE_MEASURABLE_MEASURE; + MEASURABLE_LINEAR_IMAGE_INTERVAL; + MEASURABLE_INTERVAL] THEN + MP_TAC(ISPECL + [`interval[a,(lambda i. if i = m then (b:real^N)$m + b$n else b$i)] INTER + {x:real^N | (basis m - basis n) dot x <= a$m}`; + `interval[a,(lambda i. if i = m then b$m + b$n else b$i)] INTER + {x:real^N | (basis m - basis n) dot x >= (b:real^N)$m}`; + `interval[a:real^N, + (lambda i. if i = m then (a:real^N)$m + b$n + else (b:real^N)$i)]`; + `(lambda i. if i = m then (a:real^N)$m - (b:real^N)$m + else &0):real^N`] + lemma') THEN + ANTS_TAC THENL + [ASM_SIMP_TAC[CONVEX_LINEAR_IMAGE; CONVEX_INTERVAL; + CONVEX_HALFSPACE_LE; CONVEX_HALFSPACE_GE; + CONVEX_INTER; MEASURABLE_CONVEX; BOUNDED_INTER; + BOUNDED_LINEAR_IMAGE; BOUNDED_INTERVAL] THEN + REWRITE_TAC[INTER] THEN + REWRITE_TAC[EXTENSION; IN_UNION; IN_INTER; IN_IMAGE] THEN + ONCE_REWRITE_TAC[VECTOR_ARITH `x:real^N = (lambda i. p i) + y <=> + x - (lambda i. p i) = y`] THEN + ASM_SIMP_TAC[IN_INTERVAL; IN_ELIM_THM; LAMBDA_BETA; + DOT_BASIS; DOT_LSUB; UNWIND_THM1; + VECTOR_SUB_COMPONENT] THEN + ONCE_REWRITE_TAC[MESON[] + `(!i:num. P i) <=> P m /\ (!i. ~(i = m) ==> P i)`] THEN + ASM_SIMP_TAC[REAL_SUB_RZERO] THEN CONJ_TAC THENL + [X_GEN_TAC `x:real^N` THEN + FIRST_ASSUM(MP_TAC o SPEC `n:num`) THEN + FIRST_X_ASSUM(MP_TAC o SPEC `m:num`) THEN + ASM_REWRITE_TAC[] THEN + ASM_CASES_TAC + `!i. ~(i = m) + ==> 1 <= i /\ i <= dimindex (:N) + ==> (a:real^N)$i <= (x:real^N)$i /\ + x$i <= (b:real^N)$i` THEN + ASM_REWRITE_TAC[] THEN + FIRST_X_ASSUM(MP_TAC o SPEC `n:num`) THEN + ASM_REWRITE_TAC[] THEN ASM_REAL_ARITH_TAC; + ONCE_REWRITE_TAC[TAUT `((a /\ b) /\ c) /\ (d /\ e) /\ f <=> + (b /\ e) /\ a /\ c /\ d /\ f`] THEN + ONCE_REWRITE_TAC[SET_RULE + `{x | P x /\ Q x} = {x | P x} INTER {x | Q x}`] THEN + MATCH_MP_TAC NEGLIGIBLE_INTER THEN DISJ2_TAC THEN + MATCH_MP_TAC NEGLIGIBLE_SUBSET THEN + EXISTS_TAC `{x:real^N | (basis m - basis n) dot x = (a:real^N)$m}` + THEN CONJ_TAC THENL + [MATCH_MP_TAC NEGLIGIBLE_HYPERPLANE THEN + REWRITE_TAC[VECTOR_SUB_EQ] THEN + ASM_MESON_TAC[BASIS_INJ]; + ASM_SIMP_TAC[DOT_LSUB; DOT_BASIS; SUBSET; IN_ELIM_THM; + NOT_IN_EMPTY] THEN + FIRST_ASSUM(MP_TAC o SPEC `n:num`) THEN + FIRST_X_ASSUM(MP_TAC o SPEC `m:num`) THEN + ASM_REWRITE_TAC[] THEN ASM_REAL_ARITH_TAC]]; + ALL_TAC] THEN + DISCH_THEN SUBST1_TAC THEN MATCH_MP_TAC(REAL_ARITH + `a:real = b + c ==> a = x + b ==> x = c`) THEN + ASM_SIMP_TAC[MEASURE_INTERVAL; CONTENT_CLOSED_INTERVAL_CASES; + LAMBDA_BETA] THEN + REPEAT(COND_CASES_TAC THENL + [ALL_TAC; + FIRST_X_ASSUM(MP_TAC o check (is_neg o concl)) THEN + MATCH_MP_TAC(TAUT `p ==> ~p ==> q`) THEN + X_GEN_TAC `i:num` THEN STRIP_TAC THEN + COND_CASES_TAC THEN ASM_SIMP_TAC[] THEN + FIRST_ASSUM(MP_TAC o SPEC `n:num`) THEN + FIRST_X_ASSUM(MP_TAC o SPEC `m:num`) THEN + ASM_REWRITE_TAC[] THEN ASM_REAL_ARITH_TAC]) THEN + SUBGOAL_THEN `1..dimindex(:N) = m INSERT ((1..dimindex(:N)) DELETE m)` + SUBST1_TAC THENL + [REWRITE_TAC[EXTENSION; IN_INSERT; IN_DELETE; IN_NUMSEG] THEN + ASM_ARITH_TAC; + ALL_TAC] THEN + SIMP_TAC[PRODUCT_CLAUSES; FINITE_DELETE; FINITE_NUMSEG] THEN + ASM_SIMP_TAC[IN_DELETE] THEN + MATCH_MP_TAC(REAL_RING + `s1:real = s3 /\ s2 = s3 + ==> ((bm + bn) - am) * s1 = + ((am + bn) - am) * s2 + (bm - am) * s3`) THEN + CONJ_TAC THEN MATCH_MP_TAC PRODUCT_EQ THEN + SIMP_TAC[IN_DELETE] THEN REAL_ARITH_TAC);; + +let HAS_MEASURE_LINEAR_IMAGE = prove + (`!f:real^N->real^N s. + linear f /\ measurable s + ==> (IMAGE f s) has_measure (abs(det(matrix f)) * measure s)`, + REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN + MATCH_MP_TAC INDUCT_LINEAR_ELEMENTARY THEN REPEAT CONJ_TAC THENL + [MAP_EVERY X_GEN_TAC [`f:real^N->real^N`; `g:real^N->real^N`] THEN + REPLICATE_TAC 2 (DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + DISCH_THEN(fun th -> REPEAT STRIP_TAC THEN MP_TAC th) THEN + DISCH_THEN(CONJUNCTS_THEN2 + (MP_TAC o SPEC `IMAGE (g:real^N->real^N) s`) + (MP_TAC o SPEC `s:real^N->bool`)) THEN + ASM_REWRITE_TAC[] THEN + GEN_REWRITE_TAC LAND_CONV [HAS_MEASURE_MEASURABLE_MEASURE] THEN + STRIP_TAC THEN ASM_SIMP_TAC[MATRIX_COMPOSE; DET_MUL; REAL_ABS_MUL] THEN + REWRITE_TAC[IMAGE_o; GSYM REAL_MUL_ASSOC]; + + MAP_EVERY X_GEN_TAC [`f:real^N->real^N`; `m:num`] THEN STRIP_TAC THEN + SUBGOAL_THEN `~(!x y. (f:real^N->real^N) x = f y ==> x = y)` + ASSUME_TAC THENL + [ASM_SIMP_TAC[LINEAR_SINGULAR_INTO_HYPERPLANE] THEN + EXISTS_TAC `basis m:real^N` THEN + ASM_SIMP_TAC[BASIS_NONZERO; DOT_BASIS]; + ALL_TAC] THEN + MP_TAC(ISPEC `matrix f:real^N^N` INVERTIBLE_DET_NZ) THEN + ASM_SIMP_TAC[INVERTIBLE_LEFT_INVERSE; MATRIX_LEFT_INVERTIBLE_INJECTIVE; + MATRIX_WORKS; REAL_ABS_NUM; REAL_MUL_LZERO] THEN + DISCH_THEN(K ALL_TAC) THEN REWRITE_TAC[HAS_MEASURE_0] THEN + ASM_SIMP_TAC[NEGLIGIBLE_LINEAR_SINGULAR_IMAGE]; + + MAP_EVERY X_GEN_TAC [`c:num->real`; `s:real^N->bool`] THEN + DISCH_TAC THEN + FIRST_ASSUM(ASSUME_TAC o REWRITE_RULE[HAS_MEASURE_MEASURE]) THEN + FIRST_ASSUM(MP_TAC o SPEC `c:num->real` o + MATCH_MP HAS_MEASURE_STRETCH) THEN + MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN + AP_THM_TAC THEN AP_TERM_TAC THEN AP_TERM_TAC THEN + SIMP_TAC[matrix; LAMBDA_BETA] THEN + W(MP_TAC o PART_MATCH (lhs o rand) DET_DIAGONAL o rand o snd) THEN + SIMP_TAC[LAMBDA_BETA; BASIS_COMPONENT; REAL_MUL_RZERO] THEN + DISCH_THEN(K ALL_TAC) THEN MATCH_MP_TAC PRODUCT_EQ_NUMSEG THEN + REWRITE_TAC[REAL_MUL_RID]; + + MAP_EVERY X_GEN_TAC [`m:num`; `n:num`] THEN STRIP_TAC THEN + MATCH_MP_TAC HAS_MEASURE_LINEAR_SUFFICIENT THEN + ASM_SIMP_TAC[linear; LAMBDA_BETA; IN_DIMINDEX_SWAP; VECTOR_ADD_COMPONENT; + VECTOR_MUL_COMPONENT; CART_EQ] THEN + MAP_EVERY X_GEN_TAC [`a:real^N`; `b:real^N`] THEN + SUBGOAL_THEN `matrix (\x:real^N. lambda i. x$swap (m,n) i):real^N^N = + transp(lambda i j. (mat 1:real^N^N)$i$swap (m,n) j)` + SUBST1_TAC THENL + [ASM_SIMP_TAC[MATRIX_EQ; LAMBDA_BETA; IN_DIMINDEX_SWAP; + matrix_vector_mul; CART_EQ; matrix; mat; basis; + COND_COMPONENT; transp] THEN + REWRITE_TAC[EQ_SYM_EQ]; + ALL_TAC] THEN + REWRITE_TAC[DET_TRANSP] THEN + W(MP_TAC o PART_MATCH (lhs o rand) DET_PERMUTE_COLUMNS o + rand o lhand o rand o snd) THEN + ASM_SIMP_TAC[PERMUTES_SWAP; IN_NUMSEG; ETA_AX] THEN + DISCH_THEN(K ALL_TAC) THEN + REWRITE_TAC[DET_I; REAL_ABS_SIGN; REAL_MUL_RID; REAL_MUL_LID] THEN + ASM_CASES_TAC `interval[a:real^N,b] = {}` THENL + [ASM_SIMP_TAC[IMAGE_CLAUSES; HAS_MEASURE_EMPTY; MEASURE_EMPTY]; + ALL_TAC] THEN + SUBGOAL_THEN + `~(IMAGE (\x:real^N. lambda i. x$swap (m,n) i) + (interval[a,b]):real^N->bool = {})` + MP_TAC THENL [ASM_REWRITE_TAC[IMAGE_EQ_EMPTY]; ALL_TAC] THEN + SUBGOAL_THEN + `IMAGE (\x:real^N. lambda i. x$swap (m,n) i) + (interval[a,b]):real^N->bool = + interval[(lambda i. a$swap (m,n) i), + (lambda i. b$swap (m,n) i)]` + SUBST1_TAC THENL + [REWRITE_TAC[EXTENSION; IN_INTERVAL; IN_IMAGE] THEN + ASM_SIMP_TAC[LAMBDA_SWAP_GALOIS; UNWIND_THM1] THEN + SIMP_TAC[LAMBDA_BETA] THEN GEN_TAC THEN EQ_TAC THEN + DISCH_TAC THEN X_GEN_TAC `i:num` THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `swap(m,n) (i:num)`) THEN + ASM_SIMP_TAC[IN_DIMINDEX_SWAP] THEN + ASM_MESON_TAC[REWRITE_RULE[FUN_EQ_THM; o_THM; I_THM] SWAP_IDEMPOTENT]; + ALL_TAC] THEN + REWRITE_TAC[HAS_MEASURE_MEASURABLE_MEASURE; MEASURABLE_INTERVAL] THEN + REWRITE_TAC[MEASURE_INTERVAL] THEN + ASM_SIMP_TAC[CONTENT_CLOSED_INTERVAL; GSYM INTERVAL_NE_EMPTY] THEN + DISCH_THEN(K ALL_TAC) THEN SIMP_TAC[LAMBDA_BETA] THEN + ASM_SIMP_TAC[GSYM VECTOR_SUB_COMPONENT; IN_DIMINDEX_SWAP] THEN + MP_TAC(ISPECL [`\i. (b - a:real^N)$i`; `swap(m:num,n)`; `1..dimindex(:N)`] + (GSYM PRODUCT_PERMUTE)) THEN + REWRITE_TAC[o_DEF] THEN DISCH_THEN MATCH_MP_TAC THEN + ASM_SIMP_TAC[PERMUTES_SWAP; IN_NUMSEG]; + + MAP_EVERY X_GEN_TAC [`m:num`; `n:num`] THEN STRIP_TAC THEN + MATCH_MP_TAC HAS_MEASURE_LINEAR_SUFFICIENT THEN + MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN CONJ_TAC THENL + [ASM_SIMP_TAC[linear; LAMBDA_BETA; VECTOR_ADD_COMPONENT; + VECTOR_MUL_COMPONENT; CART_EQ] THEN REAL_ARITH_TAC; + DISCH_TAC] THEN + MAP_EVERY X_GEN_TAC [`a:real^N`; `b:real^N`] THEN + SUBGOAL_THEN + `det(matrix(\x. lambda i. if i = m then (x:real^N)$m + x$n + else x$i):real^N^N) = &1` + SUBST1_TAC THENL + [ASM_SIMP_TAC[matrix; basis; COND_COMPONENT; LAMBDA_BETA] THEN + FIRST_ASSUM(DISJ_CASES_TAC o MATCH_MP (ARITH_RULE + `~(m:num = n) ==> m < n \/ n < m`)) + THENL + [W(MP_TAC o PART_MATCH (lhs o rand) DET_UPPERTRIANGULAR o lhs o snd); + W(MP_TAC o PART_MATCH (lhs o rand) DET_LOWERTRIANGULAR o lhs o snd)] + THEN ASM_SIMP_TAC[LAMBDA_BETA; BASIS_COMPONENT; COND_COMPONENT; + matrix; REAL_ADD_RID; COND_ID; + PRODUCT_CONST_NUMSEG; REAL_POW_ONE] THEN + DISCH_THEN MATCH_MP_TAC THEN + REPEAT GEN_TAC THEN REPEAT(COND_CASES_TAC THEN ASM_REWRITE_TAC[]) THEN + ASM_ARITH_TAC; + ALL_TAC] THEN + REWRITE_TAC[REAL_ABS_NUM; REAL_MUL_LID] THEN + ASM_CASES_TAC `interval[a:real^N,b] = {}` THENL + [ASM_SIMP_TAC[IMAGE_CLAUSES; HAS_MEASURE_EMPTY; MEASURE_EMPTY]; + ALL_TAC] THEN + SUBGOAL_THEN + `IMAGE (\x. lambda i. if i = m then x$m + x$n else x$i) (interval [a,b]) = + IMAGE (\x:real^N. (lambda i. if i = m \/ i = n then a$n else &0) + + x) + (IMAGE (\x:real^N. lambda i. if i = m then x$m + x$n else x$i) + (IMAGE (\x. (lambda i. if i = n then --(a$n) else &0) + x) + (interval[a,b])))` + SUBST1_TAC THENL + [REWRITE_TAC[GSYM IMAGE_o] THEN AP_THM_TAC THEN AP_TERM_TAC THEN + ASM_SIMP_TAC[FUN_EQ_THM; o_THM; VECTOR_ADD_COMPONENT; LAMBDA_BETA; + CART_EQ] THEN + MAP_EVERY X_GEN_TAC [`x:real^N`; `i:num`] THEN + STRIP_TAC THEN ASM_CASES_TAC `i:num = m` THEN ASM_REWRITE_TAC[] THEN + ASM_CASES_TAC `i:num = n` THEN ASM_REWRITE_TAC[] THEN REAL_ARITH_TAC; + ALL_TAC] THEN + MATCH_MP_TAC HAS_MEASURE_TRANSLATION THEN + SUBGOAL_THEN + `measure(interval[a,b]) = + measure(IMAGE (\x:real^N. (lambda i. if i = n then --(a$n) else &0) + x) + (interval[a,b]):real^N->bool)` + SUBST1_TAC THENL [REWRITE_TAC[MEASURE_TRANSLATION]; ALL_TAC] THEN + SUBGOAL_THEN + `~(IMAGE (\x:real^N. (lambda i. if i = n then --(a$n) else &0) + x) + (interval[a,b]):real^N->bool = {})` + MP_TAC THENL [ASM_SIMP_TAC[IMAGE_EQ_EMPTY]; ALL_TAC] THEN + ONCE_REWRITE_TAC[VECTOR_ARITH `c + x:real^N = &1 % x + c`] THEN + ASM_REWRITE_TAC[IMAGE_AFFINITY_INTERVAL; REAL_POS] THEN + DISCH_TAC THEN MATCH_MP_TAC HAS_MEASURE_SHEAR_INTERVAL THEN + ASM_SIMP_TAC[LAMBDA_BETA; VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT] THEN + REAL_ARITH_TAC]);; + +let MEASURABLE_LINEAR_IMAGE = prove + (`!f:real^N->real^N s. + linear f /\ measurable s ==> measurable(IMAGE f s)`, + REPEAT GEN_TAC THEN + DISCH_THEN(MP_TAC o MATCH_MP HAS_MEASURE_LINEAR_IMAGE) THEN + SIMP_TAC[HAS_MEASURE_MEASURABLE_MEASURE]);; + +let MEASURE_LINEAR_IMAGE = prove + (`!f:real^N->real^N s. + linear f /\ measurable s + ==> measure(IMAGE f s) = abs(det(matrix f)) * measure s`, + REPEAT GEN_TAC THEN + DISCH_THEN(MP_TAC o MATCH_MP HAS_MEASURE_LINEAR_IMAGE) THEN + SIMP_TAC[HAS_MEASURE_MEASURABLE_MEASURE]);; + +let HAS_MEASURE_LINEAR_IMAGE_ALT = prove + (`!f:real^N->real^N s m. + linear f /\ s has_measure m + ==> (IMAGE f s) has_measure (abs(det(matrix f)) * m)`, + MESON_TAC[MEASURE_UNIQUE; measurable; HAS_MEASURE_LINEAR_IMAGE]);; + +let HAS_MEASURE_LINEAR_IMAGE_SAME = prove + (`!f s. linear f /\ measurable s /\ abs(det(matrix f)) = &1 + ==> (IMAGE f s) has_measure (measure s)`, + MESON_TAC[HAS_MEASURE_LINEAR_IMAGE; REAL_MUL_LID]);; + +let MEASURE_LINEAR_IMAGE_SAME = prove + (`!f:real^N->real^N s. + linear f /\ measurable s /\ abs(det(matrix f)) = &1 + ==> measure(IMAGE f s) = measure s`, + REPEAT GEN_TAC THEN + DISCH_THEN(MP_TAC o MATCH_MP HAS_MEASURE_LINEAR_IMAGE_SAME) THEN + SIMP_TAC[HAS_MEASURE_MEASURABLE_MEASURE]);; + +let MEASURABLE_LINEAR_IMAGE_EQ = prove + (`!f:real^N->real^N s. + linear f /\ (!x y. f x = f y ==> x = y) + ==> (measurable (IMAGE f s) <=> measurable s)`, + MATCH_ACCEPT_TAC(LINEAR_INVARIANT_RULE MEASURABLE_LINEAR_IMAGE));; + +add_linear_invariants [MEASURABLE_LINEAR_IMAGE_EQ];; + +let NEGLIGIBLE_LINEAR_IMAGE = prove + (`!f:real^N->real^N s. linear f /\ negligible s ==> negligible(IMAGE f s)`, + REPEAT GEN_TAC THEN REWRITE_TAC[GSYM HAS_MEASURE_0] THEN DISCH_TAC THEN + FIRST_ASSUM(MP_TAC o MATCH_MP HAS_MEASURE_LINEAR_IMAGE_ALT) THEN + REWRITE_TAC[REAL_MUL_RZERO]);; + +let NEGLIGIBLE_LINEAR_IMAGE_EQ = prove + (`!f:real^N->real^N s. + linear f /\ (!x y. f x = f y ==> x = y) + ==> (negligible (IMAGE f s) <=> negligible s)`, + MATCH_ACCEPT_TAC(LINEAR_INVARIANT_RULE NEGLIGIBLE_LINEAR_IMAGE));; + +add_linear_invariants [NEGLIGIBLE_LINEAR_IMAGE_EQ];; + +let HAS_MEASURE_ORTHOGONAL_IMAGE = prove + (`!f:real^N->real^N s m. + orthogonal_transformation f /\ s has_measure m + ==> (IMAGE f s) has_measure m`, + REPEAT GEN_TAC THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + FIRST_ASSUM(MP_TAC o MATCH_MP ORTHOGONAL_TRANSFORMATION_LINEAR) THEN + REWRITE_TAC[IMP_IMP] THEN + DISCH_THEN(MP_TAC o MATCH_MP HAS_MEASURE_LINEAR_IMAGE_ALT) THEN + MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN + MATCH_MP_TAC(REAL_RING `x = &1 ==> x * m = m`) THEN + REWRITE_TAC[REAL_ARITH `abs x = &1 <=> x = &1 \/ x = -- &1`] THEN + MATCH_MP_TAC DET_ORTHOGONAL_MATRIX THEN + ASM_MESON_TAC[ORTHOGONAL_TRANSFORMATION_MATRIX]);; + +let HAS_MEASURE_ORTHOGONAL_IMAGE_EQ = prove + (`!f:real^N->real^N s m. + orthogonal_transformation f + ==> ((IMAGE f s) has_measure m <=> s has_measure m)`, + REPEAT STRIP_TAC THEN EQ_TAC THEN + ASM_SIMP_TAC[HAS_MEASURE_ORTHOGONAL_IMAGE] THEN + FIRST_ASSUM(MP_TAC o MATCH_MP ORTHOGONAL_TRANSFORMATION_INVERSE_o) THEN + DISCH_THEN(X_CHOOSE_THEN `g:real^N->real^N` MP_TAC) THEN + DISCH_THEN(CONJUNCTS_THEN2 MP_TAC STRIP_ASSUME_TAC) THEN + REWRITE_TAC[IMP_IMP] THEN + DISCH_THEN(MP_TAC o MATCH_MP HAS_MEASURE_ORTHOGONAL_IMAGE) THEN + ASM_SIMP_TAC[GSYM IMAGE_o; IMAGE_I]);; + +add_linear_invariants + [REWRITE_RULE[ORTHOGONAL_TRANSFORMATION] HAS_MEASURE_ORTHOGONAL_IMAGE_EQ];; + +let MEASURE_ORTHOGONAL_IMAGE_EQ = prove + (`!f:real^N->real^N s. + orthogonal_transformation f + ==> measure(IMAGE f s) = measure s`, + SIMP_TAC[measure; HAS_MEASURE_ORTHOGONAL_IMAGE_EQ]);; + +add_linear_invariants + [REWRITE_RULE[ORTHOGONAL_TRANSFORMATION] MEASURE_ORTHOGONAL_IMAGE_EQ];; + +(* ------------------------------------------------------------------------- *) +(* Measure of a standard simplex. *) +(* ------------------------------------------------------------------------- *) + +let CONGRUENT_IMAGE_STD_SIMPLEX = prove + (`!p. p permutes 1..dimindex(:N) + ==> {x:real^N | &0 <= x$(p 1) /\ x$(p(dimindex(:N))) <= &1 /\ + (!i. 1 <= i /\ i < dimindex(:N) + ==> x$(p i) <= x$(p(i + 1)))} = + IMAGE (\x:real^N. lambda i. sum(1..inverse p(i)) (\j. x$j)) + {x | (!i. 1 <= i /\ i <= dimindex (:N) ==> &0 <= x$i) /\ + sum (1..dimindex (:N)) (\i. x$i) <= &1}`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL + [ALL_TAC; + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE] THEN X_GEN_TAC `x:real^N` THEN + ASM_SIMP_TAC[IN_ELIM_THM; LAMBDA_BETA; LAMBDA_BETA_PERM; LE_REFL; + ARITH_RULE `i < n ==> i <= n /\ i + 1 <= n`; + ARITH_RULE `1 <= n + 1`; DIMINDEX_GE_1] THEN + STRIP_TAC THEN + FIRST_ASSUM(fun th -> REWRITE_TAC[MATCH_MP PERMUTES_INVERSES th]) THEN + ASM_SIMP_TAC[SUM_SING_NUMSEG; DIMINDEX_GE_1; LE_REFL] THEN + REWRITE_TAC[GSYM ADD1; SUM_CLAUSES_NUMSEG; ARITH_RULE `1 <= SUC n`] THEN + ASM_SIMP_TAC[REAL_LE_ADDR] THEN REPEAT STRIP_TAC THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_ARITH_TAC] THEN + REWRITE_TAC[SUBSET; IN_IMAGE; IN_ELIM_THM] THEN X_GEN_TAC `x:real^N` THEN + STRIP_TAC THEN + EXISTS_TAC `(lambda i. if i = 1 then x$(p 1) + else (x:real^N)$p(i) - x$p(i - 1)):real^N` THEN + ASM_SIMP_TAC[IN_ELIM_THM; LAMBDA_BETA; LAMBDA_BETA_PERM; LE_REFL; + ARITH_RULE `i < n ==> i <= n /\ i + 1 <= n`; + ARITH_RULE `1 <= n + 1`; DIMINDEX_GE_1; CART_EQ] THEN + REPEAT CONJ_TAC THENL + [X_GEN_TAC `i:num` THEN STRIP_TAC THEN + SUBGOAL_THEN `1 <= inverse (p:num->num) i /\ + !x. x <= inverse p i ==> x <= dimindex(:N)` + ASSUME_TAC THENL + [ASM_MESON_TAC[PERMUTES_INVERSE; IN_NUMSEG; LE_TRANS; PERMUTES_IN_IMAGE]; + ASM_SIMP_TAC[LAMBDA_BETA] THEN ASM_SIMP_TAC[SUM_CLAUSES_LEFT; ARITH]] THEN + SIMP_TAC[ARITH_RULE `2 <= n ==> ~(n = 1)`] THEN + GEN_REWRITE_TAC (RAND_CONV o RAND_CONV o BINDER_CONV) + [GSYM REAL_MUL_LID] THEN + ONCE_REWRITE_TAC[SUM_PARTIAL_PRE] THEN + REWRITE_TAC[REAL_SUB_REFL; REAL_MUL_RZERO; SUM_0; COND_ID] THEN + REWRITE_TAC[REAL_MUL_LID; ARITH; REAL_SUB_RZERO] THEN + FIRST_ASSUM(DISJ_CASES_TAC o MATCH_MP (ARITH_RULE + `1 <= p ==> p = 1 \/ 2 <= p`) o CONJUNCT1) THEN + ASM_SIMP_TAC[ARITH] THEN + FIRST_ASSUM(fun th -> REWRITE_TAC[MATCH_MP PERMUTES_INVERSES th]) THEN + REWRITE_TAC[REAL_ADD_RID] THEN TRY REAL_ARITH_TAC THEN + ASM_MESON_TAC[PERMUTES_INVERSE_EQ; PERMUTES_INVERSE]; + + X_GEN_TAC `i:num` THEN STRIP_TAC THEN COND_CASES_TAC THEN + ASM_REWRITE_TAC[REAL_SUB_LE] THEN + FIRST_X_ASSUM(MP_TAC o SPEC `i - 1`) THEN + ASM_SIMP_TAC[SUB_ADD] THEN DISCH_THEN MATCH_MP_TAC THEN ASM_ARITH_TAC; + + SIMP_TAC[SUM_CLAUSES_LEFT; DIMINDEX_GE_1; ARITH; + ARITH_RULE `2 <= n ==> ~(n = 1)`] THEN + GEN_REWRITE_TAC (LAND_CONV o RAND_CONV o RAND_CONV o BINDER_CONV) + [GSYM REAL_MUL_LID] THEN + ONCE_REWRITE_TAC[SUM_PARTIAL_PRE] THEN + REWRITE_TAC[REAL_SUB_REFL; REAL_MUL_RZERO; SUM_0; COND_ID] THEN + REWRITE_TAC[REAL_MUL_LID; ARITH; REAL_SUB_RZERO] THEN + COND_CASES_TAC THEN ASM_SIMP_TAC[REAL_ADD_RID] THEN + ASM_REWRITE_TAC[REAL_ARITH `x + y - x:real = y`] THEN + ASM_MESON_TAC[DIMINDEX_GE_1; + ARITH_RULE `1 <= n /\ ~(2 <= n) ==> n = 1`]]);; + +let HAS_MEASURE_IMAGE_STD_SIMPLEX = prove + (`!p. p permutes 1..dimindex(:N) + ==> {x:real^N | &0 <= x$(p 1) /\ x$(p(dimindex(:N))) <= &1 /\ + (!i. 1 <= i /\ i < dimindex(:N) + ==> x$(p i) <= x$(p(i + 1)))} + has_measure + (measure (convex hull + (vec 0 INSERT {basis i:real^N | 1 <= i /\ i <= dimindex(:N)})))`, + REPEAT STRIP_TAC THEN ASM_SIMP_TAC[CONGRUENT_IMAGE_STD_SIMPLEX] THEN + ASM_SIMP_TAC[GSYM STD_SIMPLEX] THEN + MATCH_MP_TAC HAS_MEASURE_LINEAR_IMAGE_SAME THEN + REPEAT CONJ_TAC THENL + [REWRITE_TAC[linear; CART_EQ] THEN + ASM_SIMP_TAC[LAMBDA_BETA; VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT; + GSYM SUM_ADD_NUMSEG; GSYM SUM_LMUL] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC SUM_EQ_NUMSEG THEN + REPEAT STRIP_TAC THEN REWRITE_TAC[]; + MATCH_MP_TAC MEASURABLE_CONVEX THEN REWRITE_TAC[CONVEX_CONVEX_HULL] THEN + MATCH_MP_TAC BOUNDED_CONVEX_HULL THEN REWRITE_TAC[BOUNDED_INSERT] THEN + ONCE_REWRITE_TAC[SIMPLE_IMAGE_GEN] THEN + MATCH_MP_TAC FINITE_IMP_BOUNDED THEN MATCH_MP_TAC FINITE_IMAGE THEN + REWRITE_TAC[GSYM numseg; FINITE_NUMSEG]; + MATCH_MP_TAC EQ_TRANS THEN EXISTS_TAC + `abs(det + ((lambda i. ((lambda i j. if j <= i then &1 else &0):real^N^N) + $inverse p i) + :real^N^N))` THEN + CONJ_TAC THENL + [AP_TERM_TAC THEN AP_TERM_TAC THEN REWRITE_TAC[CART_EQ] THEN + ASM_SIMP_TAC[matrix; LAMBDA_BETA; BASIS_COMPONENT; COND_COMPONENT; + LAMBDA_BETA_PERM; PERMUTES_INVERSE] THEN + X_GEN_TAC `i:num` THEN STRIP_TAC THEN + X_GEN_TAC `j:num` THEN STRIP_TAC THEN MATCH_MP_TAC EQ_TRANS THEN + EXISTS_TAC `sum (1..inverse (p:num->num) i) + (\k. if k = j then &1 else &0)` THEN + CONJ_TAC THENL + [MATCH_MP_TAC SUM_EQ THEN + ASM_SIMP_TAC[IN_NUMSEG; PERMUTES_IN_IMAGE; basis] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC LAMBDA_BETA THEN + ASM_MESON_TAC[PERMUTES_IN_IMAGE; IN_NUMSEG; LE_TRANS; + PERMUTES_INVERSE]; + ASM_SIMP_TAC[SUM_DELTA; IN_NUMSEG]]; + ALL_TAC] THEN + ASM_SIMP_TAC[PERMUTES_INVERSE; DET_PERMUTE_ROWS; ETA_AX] THEN + REWRITE_TAC[REAL_ABS_MUL; REAL_ABS_SIGN; REAL_MUL_LID] THEN + MATCH_MP_TAC(REAL_ARITH `x = &1 ==> abs x = &1`) THEN + ASM_SIMP_TAC[DET_LOWERTRIANGULAR; GSYM NOT_LT; LAMBDA_BETA] THEN + REWRITE_TAC[LT_REFL; PRODUCT_CONST_NUMSEG; REAL_POW_ONE]]);; + +let HAS_MEASURE_STD_SIMPLEX = prove + (`(convex hull (vec 0:real^N INSERT {basis i | 1 <= i /\ i <= dimindex(:N)})) + has_measure inv(&(FACT(dimindex(:N))))`, + let lemma = prove + (`!f:num->real. (!i. 1 <= i /\ i < n ==> f i <= f(i + 1)) <=> + (!i j. 1 <= i /\ i <= j /\ j <= n ==> f i <= f j)`, + GEN_TAC THEN EQ_TAC THEN DISCH_TAC THENL + [GEN_TAC THEN INDUCT_TAC THEN + SIMP_TAC[LE; REAL_LE_REFL] THEN + STRIP_TAC THEN ASM_SIMP_TAC[REAL_LE_REFL] THEN + MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC `(f:num->real) j` THEN + ASM_SIMP_TAC[ARITH_RULE `SUC x <= y ==> x <= y`] THEN + REWRITE_TAC[ADD1] THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_ARITH_TAC; + REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_ARITH_TAC]) in + MP_TAC(ISPECL + [`\p. {x:real^N | &0 <= x$(p 1) /\ x$(p(dimindex(:N))) <= &1 /\ + (!i. 1 <= i /\ i < dimindex(:N) + ==> x$(p i) <= x$(p(i + 1)))}`; + `{p | p permutes 1..dimindex(:N)}`] + HAS_MEASURE_NEGLIGIBLE_UNIONS_IMAGE) THEN + ASM_SIMP_TAC[REWRITE_RULE[HAS_MEASURE_MEASURABLE_MEASURE] + HAS_MEASURE_IMAGE_STD_SIMPLEX; IN_ELIM_THM] THEN + ASM_SIMP_TAC[SUM_CONST; FINITE_PERMUTATIONS; FINITE_NUMSEG; + CARD_PERMUTATIONS; CARD_NUMSEG_1] THEN + ANTS_TAC THENL + [MAP_EVERY X_GEN_TAC [`p:num->num`; `q:num->num`] THEN STRIP_TAC THEN + SUBGOAL_THEN `?i. i IN 1..dimindex(:N) /\ ~(p i:num = q i)` MP_TAC THENL + [ASM_MESON_TAC[permutes; FUN_EQ_THM]; ALL_TAC] THEN + GEN_REWRITE_TAC LAND_CONV [num_WOP] THEN + REWRITE_TAC[TAUT `a ==> ~(b /\ ~c) <=> a /\ b ==> c`] THEN + REWRITE_TAC[IN_NUMSEG] THEN + DISCH_THEN(X_CHOOSE_THEN `k:num` STRIP_ASSUME_TAC) THEN + MATCH_MP_TAC NEGLIGIBLE_SUBSET THEN + EXISTS_TAC `{x:real^N | (basis(p(k:num)) - basis(q k)) dot x = &0}` THEN + CONJ_TAC THENL + [MATCH_MP_TAC NEGLIGIBLE_HYPERPLANE THEN REWRITE_TAC[VECTOR_SUB_EQ] THEN + MATCH_MP_TAC BASIS_NE THEN ASM_MESON_TAC[PERMUTES_IN_IMAGE; IN_NUMSEG]; + ALL_TAC] THEN + REWRITE_TAC[SUBSET; IN_INTER; IN_ELIM_THM; DOT_LSUB; VECTOR_SUB_EQ] THEN + ASM_SIMP_TAC[DOT_BASIS; GSYM IN_NUMSEG; PERMUTES_IN_IMAGE] THEN + SUBGOAL_THEN `?l. (q:num->num) l = p(k:num)` STRIP_ASSUME_TAC THENL + [ASM_MESON_TAC[permutes]; ALL_TAC] THEN + SUBGOAL_THEN `1 <= l /\ l <= dimindex(:N)` STRIP_ASSUME_TAC THENL + [ASM_MESON_TAC[PERMUTES_IN_IMAGE; IN_NUMSEG]; ALL_TAC] THEN + SUBGOAL_THEN `k:num < l` ASSUME_TAC THENL + [REWRITE_TAC[GSYM NOT_LE] THEN REWRITE_TAC[LE_LT] THEN + ASM_MESON_TAC[PERMUTES_INJECTIVE; IN_NUMSEG]; + ALL_TAC] THEN + SUBGOAL_THEN `?m. (p:num->num) m = q(k:num)` STRIP_ASSUME_TAC THENL + [ASM_MESON_TAC[permutes]; ALL_TAC] THEN + SUBGOAL_THEN `1 <= m /\ m <= dimindex(:N)` STRIP_ASSUME_TAC THENL + [ASM_MESON_TAC[PERMUTES_IN_IMAGE; IN_NUMSEG]; ALL_TAC] THEN + SUBGOAL_THEN `k:num < m` ASSUME_TAC THENL + [REWRITE_TAC[GSYM NOT_LE] THEN REWRITE_TAC[LE_LT] THEN + ASM_MESON_TAC[PERMUTES_INJECTIVE; IN_NUMSEG]; + ALL_TAC] THEN + X_GEN_TAC `x:real^N` THEN REWRITE_TAC[lemma] THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`k:num`; `l:num`]) THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`k:num`; `m:num`]) THEN + ASM_SIMP_TAC[LT_IMP_LE; IMP_IMP; REAL_LE_ANTISYM; REAL_SUB_0] THEN + MATCH_MP_TAC EQ_IMP THEN BINOP_TAC THEN + ASM_MESON_TAC[PERMUTES_IN_IMAGE; IN_NUMSEG; DOT_BASIS]; + ALL_TAC] THEN + REWRITE_TAC[HAS_MEASURE_MEASURABLE_MEASURE] THEN + DISCH_THEN(ASSUME_TAC o CONJUNCT2) THEN CONJ_TAC THENL + [MATCH_MP_TAC MEASURABLE_CONVEX THEN REWRITE_TAC[CONVEX_CONVEX_HULL] THEN + MATCH_MP_TAC BOUNDED_CONVEX_HULL THEN REWRITE_TAC[BOUNDED_INSERT] THEN + ONCE_REWRITE_TAC[SIMPLE_IMAGE_GEN] THEN + MATCH_MP_TAC FINITE_IMP_BOUNDED THEN MATCH_MP_TAC FINITE_IMAGE THEN + REWRITE_TAC[GSYM numseg; FINITE_NUMSEG]; + ALL_TAC] THEN + ASM_SIMP_TAC[REAL_FIELD `~(y = &0) ==> (x = inv y <=> y * x = &1)`; + REAL_OF_NUM_EQ; FACT_NZ] THEN + FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN MATCH_MP_TAC EQ_TRANS THEN + EXISTS_TAC `measure(interval[vec 0:real^N,vec 1])` THEN CONJ_TAC THENL + [AP_TERM_TAC; REWRITE_TAC[MEASURE_INTERVAL; CONTENT_UNIT]] THEN + REWRITE_TAC[lemma] THEN MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL + [REWRITE_TAC[SUBSET; FORALL_IN_UNIONS; FORALL_IN_IMAGE; IMP_CONJ; + RIGHT_FORALL_IMP_THM; IN_ELIM_THM] THEN + SIMP_TAC[IMP_IMP; IN_INTERVAL; LAMBDA_BETA; VEC_COMPONENT] THEN + X_GEN_TAC `p:num->num` THEN STRIP_TAC THEN X_GEN_TAC `x:real^N` THEN + STRIP_TAC THEN X_GEN_TAC `i:num` THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC REAL_LE_TRANS THENL + [EXISTS_TAC `(x:real^N)$(p 1)`; + EXISTS_TAC `(x:real^N)$(p(dimindex(:N)))`] THEN + ASM_REWRITE_TAC[] THEN + FIRST_ASSUM(MP_TAC o SPEC `i:num` o MATCH_MP PERMUTES_SURJECTIVE) THEN + ASM_MESON_TAC[LE_REFL; PERMUTES_IN_IMAGE; IN_NUMSEG]; + ALL_TAC] THEN + REWRITE_TAC[SET_RULE `s SUBSET UNIONS(IMAGE f t) <=> + !x. x IN s ==> ?y. y IN t /\ x IN f y`] THEN + X_GEN_TAC `x:real^N` THEN REWRITE_TAC[IN_INTERVAL; IN_ELIM_THM] THEN + SIMP_TAC[VEC_COMPONENT] THEN DISCH_TAC THEN + MP_TAC(ISPEC `\i j. ~((x:real^N)$j <= x$i)` TOPOLOGICAL_SORT) THEN + REWRITE_TAC[REAL_NOT_LE; REAL_NOT_LT] THEN + ANTS_TAC THENL [REAL_ARITH_TAC; ALL_TAC] THEN + DISCH_THEN(MP_TAC o SPECL [`dimindex(:N)`; `1..dimindex(:N)`]) THEN + REWRITE_TAC[HAS_SIZE_NUMSEG_1; EXTENSION; IN_IMAGE; IN_NUMSEG] THEN + DISCH_THEN(X_CHOOSE_THEN `f:num->num` (CONJUNCTS_THEN2 + (ASSUME_TAC o GSYM) ASSUME_TAC)) THEN + EXISTS_TAC `\i. if i IN 1..dimindex(:N) then f(i) else i` THEN + REWRITE_TAC[] THEN ONCE_REWRITE_TAC[ARITH_RULE + `1 <= i /\ i <= j /\ j <= n <=> + 1 <= i /\ 1 <= j /\ i <= n /\ j <= n /\ i <= j`] THEN + ASM_SIMP_TAC[IN_NUMSEG; LE_REFL; DIMINDEX_GE_1] THEN + CONJ_TAC THENL + [ALL_TAC; + ASM_MESON_TAC[LE_REFL; DIMINDEX_GE_1; LE_LT; REAL_LE_LT]] THEN + SIMP_TAC[PERMUTES_FINITE_SURJECTIVE; FINITE_NUMSEG] THEN + SIMP_TAC[IN_NUMSEG] THEN ASM_MESON_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* Hence the measure of a general simplex. *) +(* ------------------------------------------------------------------------- *) + +let HAS_MEASURE_SIMPLEX_0 = prove + (`!l:(real^N)list. + LENGTH l = dimindex(:N) + ==> (convex hull (vec 0 INSERT set_of_list l)) has_measure + abs(det(vector l)) / &(FACT(dimindex(:N)))`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN + `vec 0 INSERT (set_of_list l) = + IMAGE (\x:real^N. transp(vector l:real^N^N) ** x) + (vec 0 INSERT {basis i:real^N | 1 <= i /\ i <= dimindex(:N)})` + SUBST1_TAC THENL + [ONCE_REWRITE_TAC[SIMPLE_IMAGE_GEN] THEN + REWRITE_TAC[IMAGE_CLAUSES; GSYM IMAGE_o; o_DEF] THEN + REWRITE_TAC[MATRIX_VECTOR_MUL_RZERO] THEN AP_TERM_TAC THEN + SIMP_TAC[matrix_vector_mul; vector; transp; LAMBDA_BETA; basis] THEN + ONCE_REWRITE_TAC[COND_RAND] THEN + SIMP_TAC[REAL_MUL_RZERO; SUM_DELTA] THEN + REWRITE_TAC[EXTENSION; IN_IMAGE; IN_ELIM_THM; IN_NUMSEG] THEN + ONCE_REWRITE_TAC[TAUT `a /\ b /\ c <=> ~(b /\ c ==> ~a)`] THEN + X_GEN_TAC `y:real^N` THEN SIMP_TAC[LAMBDA_BETA; REAL_MUL_RID] THEN + SIMP_TAC[CART_EQ; LAMBDA_BETA] THEN + REWRITE_TAC[NOT_IMP; REAL_MUL_RID; GSYM CART_EQ] THEN + ASM_REWRITE_TAC[IN_SET_OF_LIST; MEM_EXISTS_EL] THEN + EQ_TAC THEN DISCH_THEN(X_CHOOSE_THEN `i:num` STRIP_ASSUME_TAC) THENL + [EXISTS_TAC `SUC i`; EXISTS_TAC `i - 1`] THEN + ASM_REWRITE_TAC[SUC_SUB1] THEN ASM_ARITH_TAC; + ALL_TAC] THEN + ASM_SIMP_TAC[CONVEX_HULL_LINEAR_IMAGE; MATRIX_VECTOR_MUL_LINEAR] THEN + SUBGOAL_THEN + `det(vector l:real^N^N) = det(matrix(\x:real^N. transp(vector l) ** x))` + SUBST1_TAC THENL + [REWRITE_TAC[MATRIX_OF_MATRIX_VECTOR_MUL; DET_TRANSP]; ALL_TAC] THEN + REWRITE_TAC[real_div] THEN + ASM_SIMP_TAC[GSYM(REWRITE_RULE[HAS_MEASURE_MEASURABLE_MEASURE] + HAS_MEASURE_STD_SIMPLEX)] THEN + MATCH_MP_TAC HAS_MEASURE_LINEAR_IMAGE THEN + REWRITE_TAC[MATRIX_VECTOR_MUL_LINEAR] THEN + MATCH_MP_TAC MEASURABLE_CONVEX THEN REWRITE_TAC[CONVEX_CONVEX_HULL] THEN + MATCH_MP_TAC BOUNDED_CONVEX_HULL THEN REWRITE_TAC[BOUNDED_INSERT] THEN + ONCE_REWRITE_TAC[SIMPLE_IMAGE_GEN] THEN + MATCH_MP_TAC FINITE_IMP_BOUNDED THEN MATCH_MP_TAC FINITE_IMAGE THEN + REWRITE_TAC[GSYM numseg; FINITE_NUMSEG]);; + +let HAS_MEASURE_SIMPLEX = prove + (`!a l:(real^N)list. + LENGTH l = dimindex(:N) + ==> (convex hull (set_of_list(CONS a l))) has_measure + abs(det(vector(MAP (\x. x - a) l))) / &(FACT(dimindex(:N)))`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPEC `MAP (\x:real^N. x - a) l` HAS_MEASURE_SIMPLEX_0) THEN + ASM_REWRITE_TAC[LENGTH_MAP; set_of_list] THEN + DISCH_THEN(MP_TAC o SPEC `a:real^N` o MATCH_MP HAS_MEASURE_TRANSLATION) THEN + REWRITE_TAC[GSYM CONVEX_HULL_TRANSLATION] THEN + MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_TERM_TAC THEN + REWRITE_TAC[IMAGE_CLAUSES; VECTOR_ADD_RID; SET_OF_LIST_MAP] THEN + REWRITE_TAC[GSYM IMAGE_o; o_DEF; VECTOR_ARITH `a + x - a:real^N = x`; + SET_RULE `IMAGE (\x. x) s = s`]);; + +let MEASURABLE_CONVEX_HULL = prove + (`!s. bounded s ==> measurable(convex hull s)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC MEASURABLE_CONVEX THEN + ASM_SIMP_TAC[CONVEX_CONVEX_HULL; BOUNDED_CONVEX_HULL]);; + +let MEASURABLE_SIMPLEX = prove + (`!l. measurable(convex hull (set_of_list l))`, + GEN_TAC THEN MATCH_MP_TAC MEASURABLE_CONVEX_HULL THEN + MATCH_MP_TAC FINITE_IMP_BOUNDED THEN REWRITE_TAC[FINITE_SET_OF_LIST]);; + +let MEASURE_SIMPLEX = prove + (`!a l:(real^N)list. + LENGTH l = dimindex(:N) + ==> measure(convex hull (set_of_list(CONS a l))) = + abs(det(vector(MAP (\x. x - a) l))) / &(FACT(dimindex(:N)))`, + MESON_TAC[HAS_MEASURE_SIMPLEX; HAS_MEASURE_MEASURABLE_MEASURE]);; + +(* ------------------------------------------------------------------------- *) +(* Area of a triangle. *) +(* ------------------------------------------------------------------------- *) + +let HAS_MEASURE_TRIANGLE = prove + (`!a b c:real^2. + convex hull {a,b,c} has_measure + abs((b$1 - a$1) * (c$2 - a$2) - (b$2 - a$2) * (c$1 - a$1)) / &2`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`a:real^2`; `[b;c]:(real^2)list`] HAS_MEASURE_SIMPLEX) THEN + REWRITE_TAC[LENGTH; DIMINDEX_2; ARITH; set_of_list; MAP] THEN + CONV_TAC NUM_REDUCE_CONV THEN SIMP_TAC[DET_2; VECTOR_2] THEN + SIMP_TAC[VECTOR_SUB_COMPONENT; DIMINDEX_2; ARITH]);; + +let MEASURABLE_TRIANGLE = prove + (`!a b c:real^N. measurable(convex hull {a,b,c})`, + REPEAT GEN_TAC THEN + MATCH_MP_TAC MEASURABLE_CONVEX THEN REWRITE_TAC[CONVEX_CONVEX_HULL] THEN + MATCH_MP_TAC BOUNDED_CONVEX_HULL THEN MATCH_MP_TAC FINITE_IMP_BOUNDED THEN + REWRITE_TAC[FINITE_INSERT; FINITE_RULES]);; + +let MEASURE_TRIANGLE = prove + (`!a b c:real^2. + measure(convex hull {a,b,c}) = + abs((b$1 - a$1) * (c$2 - a$2) - (b$2 - a$2) * (c$1 - a$1)) / &2`, + REWRITE_TAC[REWRITE_RULE[HAS_MEASURE_MEASURABLE_MEASURE] + HAS_MEASURE_TRIANGLE]);; + +(* ------------------------------------------------------------------------- *) +(* Volume of a tetrahedron. *) +(* ------------------------------------------------------------------------- *) + +let HAS_MEASURE_TETRAHEDRON = prove + (`!a b c d:real^3. + convex hull {a,b,c,d} has_measure + abs((b$1 - a$1) * (c$2 - a$2) * (d$3 - a$3) + + (b$2 - a$2) * (c$3 - a$3) * (d$1 - a$1) + + (b$3 - a$3) * (c$1 - a$1) * (d$2 - a$2) - + (b$1 - a$1) * (c$3 - a$3) * (d$2 - a$2) - + (b$2 - a$2) * (c$1 - a$1) * (d$3 - a$3) - + (b$3 - a$3) * (c$2 - a$2) * (d$1 - a$1)) / + &6`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`a:real^3`; `[b;c;d]:(real^3)list`] HAS_MEASURE_SIMPLEX) THEN + REWRITE_TAC[LENGTH; DIMINDEX_3; ARITH; set_of_list; MAP] THEN + CONV_TAC NUM_REDUCE_CONV THEN SIMP_TAC[DET_3; VECTOR_3] THEN + SIMP_TAC[VECTOR_SUB_COMPONENT; DIMINDEX_3; ARITH]);; + +let MEASURABLE_TETRAHEDRON = prove + (`!a b c d:real^N. measurable(convex hull {a,b,c,d})`, + REPEAT GEN_TAC THEN + MATCH_MP_TAC MEASURABLE_CONVEX THEN REWRITE_TAC[CONVEX_CONVEX_HULL] THEN + MATCH_MP_TAC BOUNDED_CONVEX_HULL THEN MATCH_MP_TAC FINITE_IMP_BOUNDED THEN + REWRITE_TAC[FINITE_INSERT; FINITE_RULES]);; + +let MEASURE_TETRAHEDRON = prove + (`!a b c d:real^3. + measure(convex hull {a,b,c,d}) = + abs((b$1 - a$1) * (c$2 - a$2) * (d$3 - a$3) + + (b$2 - a$2) * (c$3 - a$3) * (d$1 - a$1) + + (b$3 - a$3) * (c$1 - a$1) * (d$2 - a$2) - + (b$1 - a$1) * (c$3 - a$3) * (d$2 - a$2) - + (b$2 - a$2) * (c$1 - a$1) * (d$3 - a$3) - + (b$3 - a$3) * (c$2 - a$2) * (d$1 - a$1)) / &6`, + REWRITE_TAC[REWRITE_RULE[HAS_MEASURE_MEASURABLE_MEASURE] + HAS_MEASURE_TETRAHEDRON]);; + +(* ------------------------------------------------------------------------- *) +(* Steinhaus's theorem. (Stromberg's proof as given on Wikipedia.) *) +(* ------------------------------------------------------------------------- *) + +let STEINHAUS = prove + (`!s:real^N->bool. + measurable s /\ &0 < measure s + ==> ?d. &0 < d /\ ball(vec 0,d) SUBSET {x - y | x IN s /\ y IN s}`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`s:real^N->bool`; `measure(s:real^N->bool) / &3`] + MEASURABLE_INNER_COMPACT) THEN + MP_TAC(ISPECL [`s:real^N->bool`; `measure(s:real^N->bool) / &3`] + MEASURABLE_OUTER_OPEN) THEN + ASM_REWRITE_TAC[REAL_ARITH `&0 < x / &3 <=> &0 < x`] THEN + DISCH_THEN(X_CHOOSE_THEN `u:real^N->bool` STRIP_ASSUME_TAC) THEN + DISCH_THEN(X_CHOOSE_THEN `k:real^N->bool` STRIP_ASSUME_TAC) THEN + MP_TAC(ISPECL [`k:real^N->bool`; `(:real^N) DIFF u`] + SEPARATE_COMPACT_CLOSED) THEN + ASM_REWRITE_TAC[GSYM OPEN_CLOSED] THEN + ANTS_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `d:real` THEN STRIP_TAC THEN + ASM_REWRITE_TAC[] THEN + REWRITE_TAC[SUBSET; IN_BALL_0; IN_ELIM_THM] THEN + X_GEN_TAC `v:real^N` THEN DISCH_TAC THEN + SUBGOAL_THEN `~((IMAGE (\x:real^N. v + x) k) INTER k = {})` MP_TAC THENL + [DISCH_TAC THEN + MP_TAC(ISPECL [`IMAGE (\x:real^N. v + x) k`; `k:real^N->bool`] + MEASURE_UNION) THEN + ASM_REWRITE_TAC[MEASURABLE_TRANSLATION_EQ; MEASURE_EMPTY] THEN + REWRITE_TAC[MEASURE_TRANSLATION; REAL_SUB_RZERO] THEN + MATCH_MP_TAC(REAL_ARITH + `!s:real^N->bool u:real^N->bool. + measure u < measure s + measure s / &3 /\ + measure s < measure k + measure s / &3 /\ + measure x <= measure u + ==> ~(measure x = measure k + measure k)`) THEN + MAP_EVERY EXISTS_TAC [`s:real^N->bool`; `u:real^N->bool`] THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC MEASURE_SUBSET THEN + ASM_SIMP_TAC[MEASURABLE_TRANSLATION_EQ; MEASURABLE_UNION] THEN + ASM_REWRITE_TAC[UNION_SUBSET] THEN + CONJ_TAC THENL [ALL_TAC; ASM SET_TAC[]] THEN + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE] THEN + X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`x:real^N`; `v + x:real^N`]) THEN + ASM_REWRITE_TAC[IN_DIFF; IN_UNIV; NORM_ARITH + `d <= dist(x:real^N,v + x) <=> ~(norm v < d)`]; + REWRITE_TAC[EXTENSION; IN_INTER; NOT_IN_EMPTY; IN_IMAGE] THEN + REWRITE_TAC[VECTOR_ARITH `v:real^N = x - y <=> x = v + y`] THEN + ASM SET_TAC[]]);; + +(* ------------------------------------------------------------------------- *) +(* A measurable set with cardinality less than c is negligible. *) +(* ------------------------------------------------------------------------- *) + +let MEASURABLE_NONNEGLIGIBLE_IMP_LARGE = prove + (`!s:real^N->bool. measurable s /\ &0 < measure s ==> s =_c (:real)`, + REPEAT GEN_TAC THEN ASM_CASES_TAC `FINITE(s:real^N->bool)` THENL + [ASM_MESON_TAC[NEGLIGIBLE_FINITE; MEASURABLE_MEASURE_POS_LT]; + ALL_TAC] THEN + DISCH_THEN(MP_TAC o MATCH_MP STEINHAUS) THEN + DISCH_THEN(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC) THEN + REWRITE_TAC[GSYM CARD_LE_ANTISYM] THEN CONJ_TAC THENL + [TRANS_TAC CARD_LE_TRANS `(:real^N)` THEN + REWRITE_TAC[CARD_LE_UNIV] THEN MATCH_MP_TAC CARD_EQ_IMP_LE THEN + REWRITE_TAC[CARD_EQ_EUCLIDEAN]; + ALL_TAC] THEN + TRANS_TAC CARD_LE_TRANS `(:real^N)` THEN CONJ_TAC THENL + [MESON_TAC[CARD_EQ_EUCLIDEAN; CARD_EQ_SYM; CARD_EQ_IMP_LE]; ALL_TAC] THEN + TRANS_TAC CARD_LE_TRANS `interval(vec 0:real^N,vec 1)` THEN CONJ_TAC THENL + [MATCH_MP_TAC CARD_EQ_IMP_LE THEN ONCE_REWRITE_TAC[CARD_EQ_SYM] THEN + MATCH_MP_TAC HOMEOMORPHIC_IMP_CARD_EQ THEN + MATCH_MP_TAC HOMEOMORPHIC_OPEN_INTERVAL_UNIV THEN + REWRITE_TAC[UNIT_INTERVAL_NONEMPTY]; + ALL_TAC] THEN + TRANS_TAC CARD_LE_TRANS `interval[vec 0:real^N,vec 1]` THEN + SIMP_TAC[INTERVAL_OPEN_SUBSET_CLOSED; CARD_LE_SUBSET] THEN + TRANS_TAC CARD_LE_TRANS `cball(vec 0:real^N,d / &2)` THEN CONJ_TAC THENL + [MATCH_MP_TAC CARD_EQ_IMP_LE THEN + MATCH_MP_TAC HOMEOMORPHIC_IMP_CARD_EQ THEN + MATCH_MP_TAC HOMEOMORPHIC_CONVEX_COMPACT THEN + REWRITE_TAC[CONVEX_INTERVAL; COMPACT_INTERVAL; INTERIOR_CLOSED_INTERVAL; + CONVEX_CBALL; COMPACT_CBALL; UNIT_INTERVAL_NONEMPTY; + INTERIOR_CBALL; BALL_EQ_EMPTY] THEN + ASM_REAL_ARITH_TAC; + ALL_TAC] THEN + TRANS_TAC CARD_LE_TRANS `ball(vec 0:real^N,d)` THEN CONJ_TAC THENL + [MATCH_MP_TAC CARD_LE_SUBSET THEN + REWRITE_TAC[SUBSET; IN_BALL; IN_CBALL] THEN ASM_REAL_ARITH_TAC; + ALL_TAC] THEN + TRANS_TAC CARD_LE_TRANS `IMAGE (\(x:real^N,y). x - y) (s *_c s)` THEN + CONJ_TAC THENL + [ASM_SIMP_TAC[mul_c; CARD_LE_SUBSET; SET_RULE + `IMAGE f {g x y | P x /\ Q y} = {f(g x y) | P x /\ Q y}`]; + ALL_TAC] THEN + TRANS_TAC CARD_LE_TRANS `((s:real^N->bool) *_c s)` THEN + REWRITE_TAC[CARD_LE_IMAGE] THEN + MATCH_MP_TAC CARD_EQ_IMP_LE THEN MATCH_MP_TAC CARD_SQUARE_INFINITE THEN + ASM_REWRITE_TAC[INFINITE]);; + +let MEASURABLE_SMALL_IMP_NEGLIGIBLE = prove + (`!s:real^N->bool. measurable s /\ s <_c (:real) ==> negligible s`, + GEN_TAC THEN ONCE_REWRITE_TAC[TAUT `a /\ b ==> c <=> a ==> ~c ==> ~b`] THEN + SIMP_TAC[GSYM MEASURABLE_MEASURE_POS_LT] THEN REWRITE_TAC[IMP_IMP] THEN + DISCH_THEN(MP_TAC o MATCH_MP MEASURABLE_NONNEGLIGIBLE_IMP_LARGE) THEN + REWRITE_TAC[lt_c] THEN MESON_TAC[CARD_EQ_IMP_LE; CARD_EQ_SYM]);; + +(* ------------------------------------------------------------------------- *) +(* Austin's Lemma. *) +(* ------------------------------------------------------------------------- *) + +let AUSTIN_LEMMA = prove + (`!D. FINITE D /\ + (!d. d IN D + ==> ?k a b. d = interval[a:real^N,b] /\ + (!i. 1 <= i /\ i <= dimindex(:N) ==> b$i - a$i = k)) + ==> ?D'. D' SUBSET D /\ pairwise DISJOINT D' /\ + measure(UNIONS D') >= + measure(UNIONS D) / &3 pow (dimindex(:N))`, + GEN_TAC THEN WF_INDUCT_TAC `CARD(D:(real^N->bool)->bool)` THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC (LABEL_TAC "*")) THEN + ASM_CASES_TAC `D:(real^N->bool)->bool = {}` THENL + [ASM_REWRITE_TAC[SUBSET_EMPTY; UNWIND_THM2; PAIRWISE_EMPTY] THEN + REWRITE_TAC[UNIONS_0; real_ge; MEASURE_EMPTY; NOT_IN_EMPTY] THEN + REWRITE_TAC[REAL_ARITH `&0 / x = &0`; REAL_LE_REFL]; + ALL_TAC] THEN + SUBGOAL_THEN + `?d:real^N->bool. d IN D /\ !d'. d' IN D ==> measure d' <= measure d` + STRIP_ASSUME_TAC THENL + [MP_TAC(ISPEC `IMAGE measure (D:(real^N->bool)->bool)` SUP_FINITE) THEN + ASM_SIMP_TAC[FINITE_IMAGE; IMAGE_EQ_EMPTY; FORALL_IN_IMAGE] THEN SET_TAC[]; + ALL_TAC] THEN + FIRST_X_ASSUM(MP_TAC o SPEC + `{c:real^N->bool | c IN (D DELETE d) /\ c INTER d = {}}`) THEN + ANTS_TAC THENL [MATCH_MP_TAC CARD_PSUBSET THEN ASM SET_TAC[]; ALL_TAC] THEN + ASM_SIMP_TAC[FINITE_DELETE; FINITE_RESTRICT; IN_ELIM_THM; real_ge] THEN + ANTS_TAC THENL [ASM_SIMP_TAC[IN_DELETE]; ALL_TAC] THEN + DISCH_THEN(X_CHOOSE_THEN `D':(real^N->bool)->bool` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `(d:real^N->bool) INSERT D'` THEN REPEAT CONJ_TAC THENL + [ASM SET_TAC[]; + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [pairwise]) THEN + REWRITE_TAC[pairwise; IN_INSERT] THEN ASM SET_TAC[]; + ALL_TAC] THEN + SUBGOAL_THEN + `?a3 b3:real^N. + measure(interval[a3,b3]) = &3 pow dimindex(:N) * measure d /\ + !c. c IN D /\ ~(c INTER d = {}) ==> c SUBSET interval[a3,b3]` + STRIP_ASSUME_TAC THENL + [USE_THEN "*" (MP_TAC o SPEC `d:real^N->bool`) THEN + ANTS_TAC THENL [ASM_REWRITE_TAC[]; ALL_TAC] THEN + ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`k:real`; `a:real^N`; `b:real^N`] THEN + DISCH_THEN(CONJUNCTS_THEN2 SUBST_ALL_TAC ASSUME_TAC) THEN + EXISTS_TAC `inv(&2) % (a + b) - &3 / &2 % (b - a):real^N` THEN + EXISTS_TAC `inv(&2) % (a + b) + &3 / &2 % (b - a):real^N` THEN + CONJ_TAC THENL + [REWRITE_TAC[MEASURE_INTERVAL; CONTENT_CLOSED_INTERVAL_CASES] THEN + REWRITE_TAC[VECTOR_ADD_COMPONENT; VECTOR_SUB_COMPONENT; + VECTOR_MUL_COMPONENT] THEN + REWRITE_TAC[REAL_ARITH `(x + &3 / &2 * a) - (x - &3 / &2 * a) = &3 * a`; + REAL_ARITH `x - a <= x + a <=> &0 <= a`] THEN + ASM_SIMP_TAC[] THEN ONCE_REWRITE_TAC[GSYM REAL_SUB_LE] THEN + ASM_SIMP_TAC[REAL_ARITH `&0 <= &3 / &2 * x - &0 <=> &0 <= x`] THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[REAL_MUL_RZERO] THEN + SIMP_TAC[PRODUCT_CONST; FINITE_NUMSEG; CARD_NUMSEG_1; REAL_POW_MUL]; + X_GEN_TAC `c:real^N->bool` THEN STRIP_TAC THEN + REMOVE_THEN "*" (MP_TAC o SPEC `c:real^N->bool`) THEN + ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`k':real`; `a':real^N`; `b':real^N`] THEN + DISCH_THEN(CONJUNCTS_THEN2 SUBST_ALL_TAC ASSUME_TAC) THEN + FIRST_X_ASSUM(MP_TAC o + GEN_REWRITE_RULE RAND_CONV [DISJOINT_INTERVAL]) THEN + REWRITE_TAC[NOT_EXISTS_THM; SUBSET_INTERVAL] THEN + REWRITE_TAC[IMP_IMP; AND_FORALL_THM] THEN + MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `i:num` THEN + ASM_CASES_TAC `1 <= i` THEN ASM_REWRITE_TAC[] THEN + ASM_CASES_TAC `i <= dimindex(:N)` THEN ASM_REWRITE_TAC[] THEN + FIRST_X_ASSUM(MP_TAC o SPEC `interval[a':real^N,b']`) THEN + ASM_REWRITE_TAC[MEASURE_INTERVAL; CONTENT_CLOSED_INTERVAL_CASES] THEN + REWRITE_TAC[DE_MORGAN_THM; REAL_NOT_LT] THEN + REWRITE_TAC[REAL_ARITH `a$k <= b$k <=> &0 <= b$k - a$k`] THEN + ASM_SIMP_TAC[IN_NUMSEG] THEN + ASM_CASES_TAC `&0 <= k` THEN ASM_REWRITE_TAC[] THEN + ASM_CASES_TAC `&0 <= k'` THEN ASM_REWRITE_TAC[] THEN + REPEAT(FIRST_X_ASSUM(fun th -> + SIMP_TAC[th] THEN MP_TAC(ISPEC `i:num` th))) THEN + ASM_SIMP_TAC[PRODUCT_CONST; CARD_NUMSEG_1; FINITE_NUMSEG] THEN + DISCH_TAC THEN DISCH_TAC THEN DISCH_THEN(MP_TAC o MATCH_MP + (REWRITE_RULE[TAUT `a /\ b /\ c ==> d <=> c ==> a /\ b ==> d`] + REAL_POW_LE2_REV)) THEN + ASM_SIMP_TAC[DIMINDEX_GE_1; LE_1] THEN + REWRITE_TAC[VECTOR_ADD_COMPONENT; VECTOR_SUB_COMPONENT; + VECTOR_MUL_COMPONENT] THEN + ASM_REAL_ARITH_TAC]; + ALL_TAC] THEN + REWRITE_TAC[UNIONS_INSERT] THEN + SUBGOAL_THEN `!d:real^N->bool. d IN D ==> measurable d` ASSUME_TAC THENL + [ASM_MESON_TAC[MEASURABLE_INTERVAL]; ALL_TAC] THEN + W(MP_TAC o PART_MATCH (lhand o rand) MEASURE_DISJOINT_UNION o + rand o snd) THEN + ANTS_TAC THENL + [ASM_SIMP_TAC[] THEN + CONJ_TAC THENL [ALL_TAC; ASM SET_TAC[]] THEN + MATCH_MP_TAC MEASURABLE_UNIONS THEN + CONJ_TAC THENL [ALL_TAC; ASM SET_TAC[]] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ_ALT] + FINITE_SUBSET)) THEN + ASM_SIMP_TAC[FINITE_RESTRICT; FINITE_DELETE]; + DISCH_THEN SUBST1_TAC] THEN + ASM_SIMP_TAC[REAL_LE_LDIV_EQ; REAL_POW_LT; REAL_OF_NUM_LT; ARITH] THEN + MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `measure(interval[a3:real^N,b3]) + + measure(UNIONS D DIFF interval[a3,b3])` THEN + CONJ_TAC THENL + [W(MP_TAC o PART_MATCH (rand o rand) MEASURE_DISJOINT_UNION o + rand o snd) THEN + ANTS_TAC THENL + [ASM_SIMP_TAC[MEASURABLE_UNIONS; MEASURABLE_DIFF; + MEASURABLE_INTERVAL] THEN SET_TAC[]; + DISCH_THEN(SUBST1_TAC o SYM) THEN + MATCH_MP_TAC MEASURE_SUBSET THEN REPEAT CONJ_TAC THENL + [ASM_SIMP_TAC[MEASURABLE_UNIONS]; + ASM_MESON_TAC[MEASURABLE_UNIONS; MEASURABLE_DIFF; + MEASURABLE_INTERVAL; MEASURABLE_UNION]; + SET_TAC[]]]; + ASM_REWRITE_TAC[REAL_ARITH `a * x + y <= (x + z) * a <=> y <= z * a`] THEN + ASM_SIMP_TAC[GSYM REAL_LE_LDIV_EQ; REAL_POW_LT; REAL_OF_NUM_LT; ARITH] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH + `y <= a ==> x <= y ==> x <= a`)) THEN + SIMP_TAC[REAL_LE_DIV2_EQ; REAL_POW_LT; REAL_OF_NUM_LT; ARITH] THEN + MATCH_MP_TAC MEASURE_SUBSET THEN + ASM_SIMP_TAC[MEASURABLE_DIFF; MEASURABLE_UNIONS; MEASURABLE_INTERVAL; + IN_ELIM_THM; IN_DELETE; FINITE_DELETE; FINITE_RESTRICT] THEN + ASM SET_TAC[]]);; + +(* ------------------------------------------------------------------------- *) +(* Some differentiability-like properties of the indefinite integral. *) +(* The first two proofs are minor variants of each other, but it was more *) +(* work to derive one from the other. *) +(* ------------------------------------------------------------------------- *) + +let INTEGRABLE_CCONTINUOUS_EXPLICIT = prove + (`!f:real^M->real^N. + (!a b. f integrable_on interval[a,b]) + ==> ?k. negligible k /\ + !x e. ~(x IN k) /\ &0 < e + ==> ?d. &0 < d /\ + !h. &0 < h /\ h < d + ==> norm(inv(content(interval[x,x + h % vec 1])) % + integral (interval[x,x + h % vec 1]) f - + f(x)) < e`, + REPEAT STRIP_TAC THEN REWRITE_TAC[IN_UNIV] THEN + MAP_EVERY ABBREV_TAC + [`box = \h x. interval[x:real^M,x + h % vec 1]`; + `box2 = \h x. interval[x:real^M - h % vec 1,x + h % vec 1]`; + `i = \h:real x:real^M. inv(content(box h x)) % + integral (box h x) (f:real^M->real^N)`] THEN + SUBGOAL_THEN + `?k. negligible k /\ + !x e. ~(x IN k) /\ &0 < e + ==> ?d. &0 < d /\ + !h. &0 < h /\ h < d + ==> norm(i h x - (f:real^M->real^N) x) < e` + MP_TAC THENL + [ALL_TAC; MAP_EVERY EXPAND_TAC ["i"; "box"] THEN REWRITE_TAC[]] THEN + EXISTS_TAC + `{x | ~(!e. &0 < e + ==> ?d. &0 < d /\ + !h. &0 < h /\ h < d + ==> norm(i h x - (f:real^M->real^N) x) < e)}` THEN + SIMP_TAC[IN_ELIM_THM] THEN + REWRITE_TAC[LIM_SEQUENTIALLY] THEN + REWRITE_TAC[NOT_FORALL_THM; NOT_IMP; NOT_EXISTS_THM] THEN + MATCH_MP_TAC NEGLIGIBLE_SUBSET THEN + EXISTS_TAC + `UNIONS {{x | !d. &0 < d + ==> ?h. &0 < h /\ h < d /\ + inv(&k + &1) <= dist(i h x,(f:real^M->real^N) x)} + | k IN (:num)}` THEN + CONJ_TAC THENL + [ALL_TAC; + REWRITE_TAC[SUBSET; IN_ELIM_THM; LEFT_IMP_EXISTS_THM] THEN + REWRITE_TAC[NOT_FORALL_THM; NOT_IMP; LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`y:real^M`; `e:real`] THEN STRIP_TAC THEN + REWRITE_TAC[SIMPLE_IMAGE; UNIONS_IMAGE] THEN + REWRITE_TAC[IN_ELIM_THM; IN_UNIV] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [REAL_ARCH_INV]) THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `k:num` THEN DISCH_TAC THEN + X_GEN_TAC `d:real` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `d:real`) THEN + ASM_REWRITE_TAC[NOT_FORALL_THM; NOT_IMP; REAL_NOT_LT] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `h:real` THEN + DISCH_THEN(CONJUNCTS_THEN2 STRIP_ASSUME_TAC MP_TAC) THEN + ASM_REWRITE_TAC[dist] THEN + MATCH_MP_TAC (REWRITE_RULE[IMP_CONJ] REAL_LE_TRANS) THEN + MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC `inv(&k)` THEN + CONJ_TAC THENL [ALL_TAC; ASM_REAL_ARITH_TAC] THEN + MATCH_MP_TAC REAL_LE_INV2 THEN + ASM_REWRITE_TAC[REAL_OF_NUM_ADD; REAL_OF_NUM_LE; REAL_OF_NUM_LT] THEN + ASM_ARITH_TAC] THEN + MATCH_MP_TAC NEGLIGIBLE_COUNTABLE_UNIONS THEN + X_GEN_TAC `jj:num` THEN + SUBGOAL_THEN `&0 < inv(&jj + &1)` MP_TAC THENL + [REWRITE_TAC[REAL_LT_INV_EQ] THEN REAL_ARITH_TAC; + SPEC_TAC(`inv(&jj + &1)`,`mu:real`) THEN GEN_TAC THEN DISCH_TAC] THEN + ONCE_REWRITE_TAC[NEGLIGIBLE_ON_INTERVALS] THEN + MAP_EVERY X_GEN_TAC [`a:real^M`; `b:real^M`] THEN + ASM_CASES_TAC `negligible(interval[a:real^M,b])` THENL + [ASM_MESON_TAC[NEGLIGIBLE_SUBSET; INTER_SUBSET]; ALL_TAC] THEN + RULE_ASSUM_TAC(REWRITE_RULE[NEGLIGIBLE_INTERVAL]) THEN + RULE_ASSUM_TAC(REWRITE_RULE[INTERVAL_NE_EMPTY]) THEN + REWRITE_TAC[NEGLIGIBLE_OUTER_LE] THEN + X_GEN_TAC `e:real` THEN DISCH_TAC THEN + MP_TAC(ISPECL [`f:real^M->real^N`; `a - vec 1:real^M`; `b + vec 1:real^M`] + HENSTOCK_LEMMA) THEN + ANTS_TAC THENL + [ASM_MESON_TAC[INTEGRABLE_ON_SUBINTERVAL; SUBSET_UNIV]; ALL_TAC] THEN + DISCH_THEN(MP_TAC o SPEC `(e * mu) / &2 / &6 pow (dimindex(:M))`) THEN + ASM_SIMP_TAC[REAL_HALF; REAL_LT_DIV; REAL_LT_MUL; + REAL_POW_LT; REAL_OF_NUM_LT; ARITH] THEN + DISCH_THEN(X_CHOOSE_THEN `g:real^M->real^M->bool` STRIP_ASSUME_TAC) THEN + REWRITE_TAC[SET_RULE `{x | P x} INTER s = {x | x IN s /\ P x}`] THEN + ABBREV_TAC + `E = {x | x IN interval[a,b] /\ + !d. &0 < d + ==> ?h. &0 < h /\ h < d /\ + mu <= dist(i h x,(f:real^M->real^N) x)}` THEN + SUBGOAL_THEN + `!x. x IN E + ==> ?h. &0 < h /\ + (box h x:real^M->bool) SUBSET (g x) /\ + (box h x:real^M->bool) SUBSET interval[a - vec 1,b + vec 1] /\ + mu <= dist(i h x,(f:real^M->real^N) x)` + MP_TAC THENL + [X_GEN_TAC `x:real^M` THEN EXPAND_TAC "E" THEN REWRITE_TAC[IN_ELIM_THM] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [gauge]) THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC o SPEC `x:real^M`) THEN + REWRITE_TAC[OPEN_CONTAINS_BALL] THEN + DISCH_THEN(MP_TAC o SPEC `x:real^M`) THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC) THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC + (MP_TAC o SPEC `min (&1) (d / &(dimindex(:M)))`)) THEN + REWRITE_TAC[REAL_LT_MIN; REAL_LT_01; GSYM CONJ_ASSOC] THEN + ASM_SIMP_TAC[REAL_LT_DIV; DIMINDEX_GE_1; LE_1; REAL_OF_NUM_LT] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `h:real` THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN CONJ_TAC THENL + [MATCH_MP_TAC SUBSET_TRANS THEN + EXISTS_TAC `ball(x:real^M,d)` THEN ASM_REWRITE_TAC[] THEN + EXPAND_TAC "box" THEN + REWRITE_TAC[SUBSET; IN_INTERVAL; IN_BALL] THEN + X_GEN_TAC `y:real^M` THEN + REWRITE_TAC[VECTOR_SUB_COMPONENT; VECTOR_ADD_COMPONENT; dist; + VECTOR_MUL_COMPONENT; VEC_COMPONENT; REAL_MUL_RID] THEN + DISCH_TAC THEN MATCH_MP_TAC REAL_LET_TRANS THEN + EXISTS_TAC `sum(1..dimindex(:M)) (\i. abs((x - y:real^M)$i))` THEN + REWRITE_TAC[NORM_LE_L1] THEN MATCH_MP_TAC SUM_BOUND_LT_GEN THEN + REWRITE_TAC[FINITE_NUMSEG; NUMSEG_EMPTY; IN_NUMSEG] THEN + SIMP_TAC[NOT_LT; DIMINDEX_GE_1; CARD_NUMSEG_1; VECTOR_SUB_COMPONENT] 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 ASM_REAL_ARITH_TAC; + UNDISCH_TAC `(x:real^M) IN interval[a,b]` THEN + EXPAND_TAC "box" THEN REWRITE_TAC[SUBSET; IN_INTERVAL] THEN + DISCH_THEN(fun th -> X_GEN_TAC `y:real^M` THEN MP_TAC th) THEN + REWRITE_TAC[IMP_IMP; AND_FORALL_THM] THEN MATCH_MP_TAC MONO_FORALL THEN + X_GEN_TAC `i:num` THEN + DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN + ASM_REWRITE_TAC[] THEN + REWRITE_TAC[VECTOR_SUB_COMPONENT; VECTOR_ADD_COMPONENT; dist; + VECTOR_MUL_COMPONENT; VEC_COMPONENT; REAL_MUL_RID] THEN + ASM_REAL_ARITH_TAC]; + ALL_TAC] THEN + GEN_REWRITE_TAC (LAND_CONV o TOP_DEPTH_CONV) [RIGHT_IMP_EXISTS_THM] THEN + REWRITE_TAC[SKOLEM_THM; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `uv:real^M->real` THEN + REWRITE_TAC[TAUT `(a ==> b /\ c) <=> (a ==> b) /\ (a ==> c)`] THEN + REWRITE_TAC[FORALL_AND_THM] THEN STRIP_TAC THEN + MP_TAC(ISPECL [`a:real^M`; `b:real^M`; `E:real^M->bool`; + `\x:real^M. if x IN E then ball(x,uv x) else g(x)`] + COVERING_LEMMA) THEN + REWRITE_TAC[] THEN ANTS_TAC THENL + [ASM_REWRITE_TAC[INTERVAL_NE_EMPTY] THEN CONJ_TAC THENL + [EXPAND_TAC "E" THEN SET_TAC[]; ALL_TAC] THEN + REWRITE_TAC[gauge] THEN GEN_TAC THEN + COND_CASES_TAC THEN ASM_SIMP_TAC[OPEN_BALL; CENTRE_IN_BALL] THEN + RULE_ASSUM_TAC(REWRITE_RULE[gauge]) THEN ASM_REWRITE_TAC[]; + ALL_TAC] THEN + DISCH_THEN(X_CHOOSE_TAC `D:(real^M->bool)->bool`) THEN + EXISTS_TAC `UNIONS D:real^M->bool` THEN ASM_REWRITE_TAC[] THEN + SUBGOAL_THEN + `measurable(UNIONS D:real^M->bool) /\ + measure(UNIONS D) <= measure(interval[a:real^M,b])` + STRIP_ASSUME_TAC THENL + [MATCH_MP_TAC MEASURE_COUNTABLE_UNIONS_LE_STRONG_GEN THEN + ASM_REWRITE_TAC[] THEN + CONJ_TAC THENL [ASM_MESON_TAC[SUBSET; MEASURABLE_INTERVAL]; ALL_TAC] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC MEASURE_SUBSET THEN + REWRITE_TAC[MEASURABLE_INTERVAL] THEN + CONJ_TAC THENL [ALL_TAC; ASM SET_TAC[]] THEN + MATCH_MP_TAC MEASURABLE_UNIONS THEN + ASM_MESON_TAC[SUBSET; MEASURABLE_INTERVAL]; + ALL_TAC] THEN + ASM_REWRITE_TAC[] THEN + SUBGOAL_THEN + `?d. d SUBSET D /\ FINITE d /\ + measure(UNIONS D:real^M->bool) <= &2 * measure(UNIONS d)` + STRIP_ASSUME_TAC THENL + [ASM_CASES_TAC `measure(UNIONS D:real^M->bool) = &0` THENL + [EXISTS_TAC `{}:(real^M->bool)->bool` THEN + ASM_REWRITE_TAC[FINITE_EMPTY; EMPTY_SUBSET; MEASURE_EMPTY; UNIONS_0] THEN + CONV_TAC REAL_RAT_REDUCE_CONV; + MP_TAC(ISPECL [`D:(real^M->bool)->bool`; `measure(interval[a:real^M,b])`; + `measure(UNIONS D:real^M->bool) / &2`] + MEASURE_COUNTABLE_UNIONS_APPROACHABLE) THEN + ASM_REWRITE_TAC[] THEN ANTS_TAC THENL + [ASM_SIMP_TAC[MEASURABLE_MEASURE_POS_LT; REAL_HALF] THEN + ASM_SIMP_TAC[GSYM MEASURABLE_MEASURE_EQ_0] THEN + CONJ_TAC THENL [ASM_MESON_TAC[MEASURABLE_INTERVAL]; ALL_TAC] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC MEASURE_SUBSET THEN + REPEAT(CONJ_TAC THENL + [ASM_MESON_TAC[SUBSET; MEASURABLE_INTERVAL; MEASURABLE_UNIONS]; + ALL_TAC]) THEN + ASM SET_TAC[]; + MATCH_MP_TAC MONO_EXISTS THEN SIMP_TAC[] THEN REAL_ARITH_TAC]]; + ALL_TAC] THEN + FIRST_ASSUM(MP_TAC o el 3 o CONJUNCTS) THEN + REWRITE_TAC[RIGHT_IMP_EXISTS_THM; SKOLEM_THM] THEN + ONCE_REWRITE_TAC[TAUT `a /\ b <=> ~(a ==> ~b)`] THEN + SIMP_TAC[IN_INTER] THEN REWRITE_TAC[NOT_IMP; GSYM CONJ_ASSOC] THEN + DISCH_THEN(X_CHOOSE_TAC `tag:(real^M->bool)->real^M`) THEN + FIRST_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH + `D <= &2 * d ==> d <= e / &2 ==> D <= e`)) THEN + MP_TAC(ISPEC + `IMAGE (\k:real^M->bool. (box2:real->real^M->real^M->bool) + (uv(tag k):real) ((tag k:real^M))) d` + AUSTIN_LEMMA) THEN + ASM_SIMP_TAC[FINITE_IMAGE; FORALL_IN_IMAGE] THEN ANTS_TAC THENL + [X_GEN_TAC `k:real^M->bool` THEN DISCH_TAC THEN EXPAND_TAC "box2" THEN + EXISTS_TAC `&2 * uv((tag:(real^M->bool)->real^M) k):real` THEN + EXISTS_TAC `(tag:(real^M->bool)->real^M) k - uv(tag k) % vec 1:real^M` THEN + EXISTS_TAC `(tag:(real^M->bool)->real^M) k + uv(tag k) % vec 1:real^M` THEN + REWRITE_TAC[VECTOR_SUB_COMPONENT; VECTOR_ADD_COMPONENT; dist; + VECTOR_MUL_COMPONENT; VEC_COMPONENT; REAL_MUL_RID] THEN + ASM_REAL_ARITH_TAC; + ALL_TAC] THEN + REWRITE_TAC[EXISTS_SUBSET_IMAGE; real_ge] THEN + SIMP_TAC[REAL_LE_LDIV_EQ; REAL_POW_LT; REAL_OF_NUM_LT; ARITH] THEN + DISCH_THEN(X_CHOOSE_THEN `p:(real^M->bool)->bool` MP_TAC) THEN + REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + MATCH_MP_TAC(REAL_ARITH + `d <= d' /\ p <= e ==> d' <= p ==> d <= e`) THEN + CONJ_TAC THENL + [MATCH_MP_TAC MEASURE_SUBSET THEN REPEAT CONJ_TAC THENL + [MATCH_MP_TAC MEASURABLE_UNIONS THEN + ASM_MESON_TAC[SUBSET; MEASURABLE_INTERVAL]; + MATCH_MP_TAC MEASURABLE_UNIONS THEN + ASM_SIMP_TAC[FINITE_IMAGE; FORALL_IN_IMAGE] THEN + EXPAND_TAC "box2" THEN REWRITE_TAC[MEASURABLE_INTERVAL]; + REWRITE_TAC[SUBSET; IN_UNIONS; EXISTS_IN_IMAGE] THEN + X_GEN_TAC `z:real^M` THEN MATCH_MP_TAC MONO_EXISTS THEN + X_GEN_TAC `k:real^M->bool` THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + UNDISCH_TAC `(z:real^M) IN k` THEN SPEC_TAC(`z:real^M`,`z:real^M`) THEN + REWRITE_TAC[GSYM SUBSET] THEN MATCH_MP_TAC SUBSET_TRANS THEN + EXISTS_TAC `ball(tag k:real^M,uv(tag(k:real^M->bool)))` THEN + CONJ_TAC THENL [ASM_MESON_TAC[SUBSET]; ALL_TAC] THEN + EXPAND_TAC "box2" THEN REWRITE_TAC[SUBSET; IN_BALL; IN_INTERVAL] THEN + X_GEN_TAC `z:real^M` THEN REWRITE_TAC[dist] THEN DISCH_TAC THEN + REWRITE_TAC[VECTOR_SUB_COMPONENT; VECTOR_ADD_COMPONENT; dist; + VECTOR_MUL_COMPONENT; VEC_COMPONENT; REAL_MUL_RID] THEN + + SIMP_TAC[REAL_ARITH `x - h <= y /\ y <= x + h <=> abs(x - y) <= h`] THEN + REWRITE_TAC[GSYM VECTOR_SUB_COMPONENT] THEN + ASM_MESON_TAC[COMPONENT_LE_NORM; REAL_LT_IMP_LE; REAL_LE_TRANS]]; + ALL_TAC] THEN + MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `measure(UNIONS (IMAGE (\k:real^M->bool. + (box:real->real^M->real^M->bool) + (uv(tag k):real) ((tag k:real^M))) p)) * + &6 pow dimindex (:M)` THEN + CONJ_TAC THENL + [SUBGOAL_THEN + `!box. IMAGE (\k:real^M->bool. (box:real->real^M->real^M->bool) + (uv(tag k):real) ((tag k:real^M))) p = + IMAGE (\t. box (uv t) t) (IMAGE tag p)` + (fun th -> REWRITE_TAC[th]) + THENL [REWRITE_TAC[GSYM IMAGE_o; o_DEF]; ALL_TAC] THEN + W(MP_TAC o PART_MATCH (lhs o rand) MEASURE_NEGLIGIBLE_UNIONS_IMAGE o + lhand o rand o snd) THEN + W(MP_TAC o PART_MATCH (lhs o rand) MEASURE_NEGLIGIBLE_UNIONS_IMAGE o + lhand o lhand o rand o snd) THEN + MATCH_MP_TAC(TAUT + `fp /\ (mb /\ mb') /\ (db /\ db') /\ (m1 /\ m2 ==> p) + ==> (fp /\ mb /\ db ==> m1) ==> (fp /\ mb' /\ db' ==> m2) ==> p`) THEN + SUBGOAL_THEN `FINITE(p:(real^M->bool)->bool)` ASSUME_TAC THENL + [ASM_MESON_TAC[FINITE_SUBSET]; ASM_SIMP_TAC[FINITE_IMAGE]] THEN + ASM_REWRITE_TAC[] THEN CONJ_TAC THENL + [MAP_EVERY EXPAND_TAC ["box"; "box2"] THEN + REWRITE_TAC[MEASURABLE_INTERVAL]; + ALL_TAC] THEN + CONJ_TAC THENL + [REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_IMAGE] THEN + REWRITE_TAC[IMP_IMP; RIGHT_IMP_FORALL_THM; AND_FORALL_THM] THEN + MAP_EVERY X_GEN_TAC [`k1:real^M->bool`; `k2:real^M->bool`] THEN + MATCH_MP_TAC(TAUT + `(q ==> r) /\ (p ==> q) ==> (p ==> q) /\ (p ==> r)`) THEN + CONJ_TAC THENL + [MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] NEGLIGIBLE_SUBSET) THEN + MATCH_MP_TAC(SET_RULE + `s SUBSET s' /\ t SUBSET t' ==> (s INTER t) SUBSET (s' INTER t')`) THEN + CONJ_TAC THEN MAP_EVERY EXPAND_TAC ["box"; "box2"] THEN + REWRITE_TAC[SUBSET_INTERVAL] THEN + REWRITE_TAC[VECTOR_SUB_COMPONENT; VECTOR_ADD_COMPONENT; dist; + VECTOR_MUL_COMPONENT; VEC_COMPONENT; REAL_MUL_RID] THEN + MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `i:num` THEN + DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN + ASM_REWRITE_TAC[] THEN REAL_ARITH_TAC; + ALL_TAC] THEN + STRIP_TAC THEN + MATCH_MP_TAC(MESON[NEGLIGIBLE_EMPTY] `s = {} ==> negligible s`) THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [pairwise]) THEN + REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_IMAGE] THEN + DISCH_THEN(MP_TAC o SPEC `k1:real^M->bool`) THEN + ASM_REWRITE_TAC[] THEN + DISCH_THEN(MP_TAC o SPEC `k2:real^M->bool`) THEN + ASM_REWRITE_TAC[] THEN ANTS_TAC THENL + [EXPAND_TAC "box2" THEN REWRITE_TAC[GSYM SUBSET_ANTISYM_EQ] THEN + REWRITE_TAC[SUBSET_INTERVAL] THEN + REWRITE_TAC[VECTOR_SUB_COMPONENT; VECTOR_ADD_COMPONENT; dist; + VECTOR_MUL_COMPONENT; VEC_COMPONENT; REAL_MUL_RID] THEN + REWRITE_TAC[REAL_ARITH `x - e <= x + e <=> &0 <= e`] THEN + SUBGOAL_THEN `&0 <= uv((tag:(real^M->bool)->real^M) k1) /\ + &0 <= uv((tag:(real^M->bool)->real^M) k2)` + STRIP_ASSUME_TAC THENL + [ASM_MESON_TAC[SUBSET; REAL_LT_IMP_LE]; ASM_REWRITE_TAC[]] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE RAND_CONV [CART_EQ]) THEN + MATCH_MP_TAC MONO_NOT THEN REWRITE_TAC[AND_FORALL_THM] THEN + MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `i:num` THEN + DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN + ASM_REWRITE_TAC[] THEN REAL_ARITH_TAC; + SET_TAC[]]; + ALL_TAC] THEN + DISCH_THEN(CONJUNCTS_THEN SUBST1_TAC) THEN + REWRITE_TAC[GSYM SUM_RMUL] THEN + MATCH_MP_TAC REAL_EQ_IMP_LE THEN MATCH_MP_TAC SUM_EQ THEN + X_GEN_TAC `t:real^M` THEN DISCH_THEN(K ALL_TAC) THEN + SUBST1_TAC(REAL_ARITH `&6 = &2 * &3`) THEN + REWRITE_TAC[REAL_POW_MUL; REAL_MUL_ASSOC] THEN + AP_THM_TAC THEN AP_TERM_TAC THEN + MAP_EVERY EXPAND_TAC ["box"; "box2"] THEN + REWRITE_TAC[MEASURE_INTERVAL; CONTENT_CLOSED_INTERVAL_CASES] THEN + REWRITE_TAC[VECTOR_SUB_COMPONENT; VECTOR_ADD_COMPONENT; dist; + VECTOR_MUL_COMPONENT; VEC_COMPONENT; REAL_MUL_RID] THEN + REWRITE_TAC[REAL_ARITH `a <= a + x <=> &0 <= x`; + REAL_ARITH `a - x <= a + x <=> &0 <= x`] THEN + COND_CASES_TAC THEN REWRITE_TAC[REAL_MUL_LZERO] THEN + REWRITE_TAC[REAL_ARITH `(t + h) - (t - h):real = &2 * h`; + REAL_ARITH `(t + h) - t:real = h`] THEN + REWRITE_TAC[PRODUCT_MUL_NUMSEG; PRODUCT_CONST_NUMSEG] THEN + REWRITE_TAC[ADD_SUB; REAL_MUL_AC]; + ALL_TAC] THEN + SIMP_TAC[GSYM REAL_LE_RDIV_EQ; REAL_POW_LT; REAL_OF_NUM_LT; ARITH] THEN + SUBGOAL_THEN `FINITE(p:(real^M->bool)->bool)` ASSUME_TAC THENL + [ASM_MESON_TAC[FINITE_SUBSET]; ALL_TAC] THEN + MATCH_MP_TAC REAL_LE_LCANCEL_IMP THEN + EXISTS_TAC `mu:real` THEN ASM_REWRITE_TAC[] THEN + FIRST_X_ASSUM(MP_TAC o SPEC + `IMAGE (\k. (tag:(real^M->bool)->real^M) k, + (box(uv(tag k):real) (tag k):real^M->bool)) p`) THEN + ANTS_TAC THENL + [REWRITE_TAC[tagged_partial_division_of; fine] THEN + REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN + REWRITE_TAC[IN_IMAGE; PAIR_EQ] THEN + REWRITE_TAC[MESON[] + `(!x j. (?k. (x = tag k /\ j = g k) /\ k IN d) ==> P x j) <=> + (!k. k IN d ==> P (tag k) (g k))`] THEN + ASM_SIMP_TAC[FINITE_IMAGE] THEN REPEAT CONJ_TAC THENL + [X_GEN_TAC `k:real^M->bool` THEN DISCH_TAC THEN REPEAT CONJ_TAC THENL + [EXPAND_TAC "box" THEN REWRITE_TAC[IN_INTERVAL] THEN + REWRITE_TAC[VECTOR_SUB_COMPONENT; VECTOR_ADD_COMPONENT; dist; + VECTOR_MUL_COMPONENT; VEC_COMPONENT; REAL_MUL_RID] THEN + GEN_TAC THEN STRIP_TAC THEN MATCH_MP_TAC(REAL_ARITH + `&0 < u ==> x <= x /\ x <= x + u`) THEN ASM_MESON_TAC[SUBSET]; + ASM_MESON_TAC[SUBSET]; + EXPAND_TAC "box" THEN MESON_TAC[]]; + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [pairwise]) THEN + REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_IMAGE] THEN + MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `k1:real^M->bool` THEN + ASM_CASES_TAC `(k1:real^M->bool) IN p` THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `k2:real^M->bool` THEN + ASM_CASES_TAC `(k2:real^M->bool) IN p` THEN ASM_REWRITE_TAC[] THEN + ASM_CASES_TAC `(tag:(real^M->bool)->real^M) k1 = tag k2` THEN + ASM_REWRITE_TAC[] THEN ANTS_TAC THENL + [EXPAND_TAC "box2" THEN REWRITE_TAC[GSYM SUBSET_ANTISYM_EQ] THEN + REWRITE_TAC[SUBSET_INTERVAL] THEN + REWRITE_TAC[VECTOR_SUB_COMPONENT; VECTOR_ADD_COMPONENT; dist; + VECTOR_MUL_COMPONENT; VEC_COMPONENT; REAL_MUL_RID] THEN + REWRITE_TAC[REAL_ARITH `x - e <= x + e <=> &0 <= e`] THEN + SUBGOAL_THEN `&0 <= uv((tag:(real^M->bool)->real^M) k1) /\ + &0 <= uv((tag:(real^M->bool)->real^M) k2)` + STRIP_ASSUME_TAC THENL + [ASM_MESON_TAC[SUBSET; REAL_LT_IMP_LE]; ASM_REWRITE_TAC[]] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE RAND_CONV [CART_EQ]) THEN + MATCH_MP_TAC MONO_NOT THEN REWRITE_TAC[AND_FORALL_THM] THEN + MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `i:num` THEN + DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN + ASM_REWRITE_TAC[] THEN REAL_ARITH_TAC; + MATCH_MP_TAC(SET_RULE + `i1 SUBSET s1 /\ i2 SUBSET s2 + ==> DISJOINT s1 s2 ==> i1 INTER i2 = {}`) THEN + CONJ_TAC THEN MATCH_MP_TAC(MESON[INTERIOR_SUBSET; SUBSET_TRANS] + `s SUBSET t ==> interior s SUBSET t`) THEN + MAP_EVERY EXPAND_TAC ["box"; "box2"] THEN + REWRITE_TAC[SUBSET_INTERVAL] THEN + REWRITE_TAC[VECTOR_SUB_COMPONENT; VECTOR_ADD_COMPONENT; dist; + VECTOR_MUL_COMPONENT; VEC_COMPONENT; REAL_MUL_RID] THEN + MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `i:num` THEN + DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN + ASM_REWRITE_TAC[] THEN REAL_ARITH_TAC]; + ASM_MESON_TAC[SUBSET]]; + ALL_TAC] THEN + MATCH_MP_TAC(REAL_ARITH `e = e' /\ y <= x ==> x < e ==> y <= e'`) THEN + CONJ_TAC THENL [REWRITE_TAC[real_div; REAL_MUL_AC]; ALL_TAC] THEN + ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN ASM_SIMP_TAC[GSYM REAL_LE_RDIV_EQ] THEN + W(MP_TAC o PART_MATCH (lhand o rand) MEASURE_UNIONS_LE o lhand o snd) THEN + ANTS_TAC THENL + [ASM_SIMP_TAC[FINITE_IMAGE; FORALL_IN_IMAGE] THEN + EXPAND_TAC "box" THEN REWRITE_TAC[MEASURABLE_INTERVAL]; + ALL_TAC] THEN + MATCH_MP_TAC(REAL_ARITH `a' <= e ==> a <= a' ==> a <= e`) THEN + ASM_SIMP_TAC[REAL_LE_RDIV_EQ; GSYM SUM_RMUL] THEN + MATCH_MP_TAC SUM_LE_INCLUDED THEN + ASM_SIMP_TAC[FORALL_IN_IMAGE; RIGHT_EXISTS_AND_THM; FINITE_IMAGE] THEN + REWRITE_TAC[NORM_POS_LE; EXISTS_IN_IMAGE] THEN + EXISTS_TAC `SND:real^M#(real^M->bool)->real^M->bool` THEN + X_GEN_TAC `k:real^M->bool` THEN DISCH_TAC THEN + EXISTS_TAC `k:real^M->bool` THEN ASM_REWRITE_TAC[] THEN + SUBGOAL_THEN + `&0 < uv(tag(k:real^M->bool):real^M):real` ASSUME_TAC + THENL [ASM_MESON_TAC[SUBSET]; ALL_TAC] THEN + SUBGOAL_THEN + `&0 < measure(box(uv(tag(k:real^M->bool):real^M):real) (tag k):real^M->bool)` + MP_TAC THENL + [EXPAND_TAC "box" THEN + REWRITE_TAC[MEASURE_INTERVAL; CONTENT_CLOSED_INTERVAL_CASES] THEN + REWRITE_TAC[VECTOR_SUB_COMPONENT; VECTOR_ADD_COMPONENT; dist; + VECTOR_MUL_COMPONENT; VEC_COMPONENT; REAL_MUL_RID] THEN + ASM_SIMP_TAC[REAL_ARITH `&0 < x ==> a <= a + x`] THEN + MATCH_MP_TAC PRODUCT_POS_LT_NUMSEG THEN + REWRITE_TAC[] THEN ASM_REAL_ARITH_TAC; + ALL_TAC] THEN + ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN SIMP_TAC[GSYM REAL_LE_RDIV_EQ] THEN + DISCH_THEN(fun th -> + GEN_REWRITE_TAC (funpow 2 RAND_CONV) + [MATCH_MP(REAL_ARITH `&0 < x ==> x = abs x`) th] THEN + ASSUME_TAC th) THEN + REWRITE_TAC[real_div; GSYM REAL_ABS_INV] THEN + ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN REWRITE_TAC[GSYM NORM_MUL] THEN + SUBGOAL_THEN + `mu <= dist(i (uv(tag(k:real^M->bool):real^M):real) (tag k):real^N, + f(tag k))` + MP_TAC THENL [ASM_MESON_TAC[SUBSET]; ALL_TAC] THEN + MATCH_MP_TAC(REAL_ARITH `x = y ==> m <= x ==> m <= y`) THEN + ONCE_REWRITE_TAC[DIST_SYM] THEN EXPAND_TAC "i" THEN + REWRITE_TAC[dist; VECTOR_SUB_LDISTRIB] THEN + UNDISCH_TAC + `&0 < measure(box(uv(tag(k:real^M->bool):real^M):real) + (tag k):real^M->bool)` THEN + EXPAND_TAC "box" THEN REWRITE_TAC[MEASURE_INTERVAL] THEN + SIMP_TAC[VECTOR_MUL_ASSOC; REAL_LT_IMP_NZ; REAL_MUL_LINV] THEN + REWRITE_TAC[VECTOR_MUL_LID]);; + +let INTEGRABLE_CCONTINUOUS_EXPLICIT_SYMMETRIC = prove + (`!f:real^M->real^N. + (!a b. f integrable_on interval[a,b]) + ==> ?k. negligible k /\ + !x e. ~(x IN k) /\ &0 < e + ==> ?d. &0 < d /\ + !h. &0 < h /\ h < d + ==> norm(inv(content(interval[x - h % vec 1,x + h % vec 1])) % + integral (interval[x - h % vec 1,x + h % vec 1]) f - + f(x)) < e`, + REPEAT STRIP_TAC THEN + MAP_EVERY ABBREV_TAC + [`box = \h x. interval[x - h % vec 1:real^M,x + h % vec 1]`; + `i = \h:real x:real^M. inv(content(box h x)) % + integral (box h x) (f:real^M->real^N)`] THEN + SUBGOAL_THEN + `?k. negligible k /\ + !x e. ~(x IN k) /\ &0 < e + ==> ?d. &0 < d /\ + !h. &0 < h /\ h < d + ==> norm(i h x - (f:real^M->real^N) x) < e` + MP_TAC THENL + [ALL_TAC; MAP_EVERY EXPAND_TAC ["i"; "box"] THEN REWRITE_TAC[]] THEN + EXISTS_TAC + `{x | ~(!e. &0 < e + ==> ?d. &0 < d /\ + !h. &0 < h /\ h < d + ==> norm(i h x - (f:real^M->real^N) x) < e)}` THEN + SIMP_TAC[IN_ELIM_THM] THEN + REWRITE_TAC[LIM_SEQUENTIALLY] THEN + REWRITE_TAC[NOT_FORALL_THM; NOT_IMP; NOT_EXISTS_THM] THEN + MATCH_MP_TAC NEGLIGIBLE_SUBSET THEN + EXISTS_TAC + `UNIONS {{x | !d. &0 < d + ==> ?h. &0 < h /\ h < d /\ + inv(&k + &1) <= dist(i h x,(f:real^M->real^N) x)} + | k IN (:num)}` THEN + CONJ_TAC THENL + [ALL_TAC; + REWRITE_TAC[SUBSET; IN_ELIM_THM; LEFT_IMP_EXISTS_THM] THEN + REWRITE_TAC[NOT_FORALL_THM; NOT_IMP; LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`y:real^M`; `e:real`] THEN STRIP_TAC THEN + REWRITE_TAC[SIMPLE_IMAGE; UNIONS_IMAGE] THEN + REWRITE_TAC[IN_ELIM_THM; IN_UNIV] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [REAL_ARCH_INV]) THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `k:num` THEN DISCH_TAC THEN + X_GEN_TAC `d:real` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `d:real`) THEN + ASM_REWRITE_TAC[NOT_FORALL_THM; NOT_IMP; REAL_NOT_LT] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `h:real` THEN + DISCH_THEN(CONJUNCTS_THEN2 STRIP_ASSUME_TAC MP_TAC) THEN + ASM_REWRITE_TAC[dist] THEN + MATCH_MP_TAC (REWRITE_RULE[IMP_CONJ] REAL_LE_TRANS) THEN + MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC `inv(&k)` THEN + CONJ_TAC THENL [ALL_TAC; ASM_REAL_ARITH_TAC] THEN + MATCH_MP_TAC REAL_LE_INV2 THEN + ASM_REWRITE_TAC[REAL_OF_NUM_ADD; REAL_OF_NUM_LE; REAL_OF_NUM_LT] THEN + ASM_ARITH_TAC] THEN + MATCH_MP_TAC NEGLIGIBLE_COUNTABLE_UNIONS THEN + X_GEN_TAC `jj:num` THEN + SUBGOAL_THEN `&0 < inv(&jj + &1)` MP_TAC THENL + [REWRITE_TAC[REAL_LT_INV_EQ] THEN REAL_ARITH_TAC; + SPEC_TAC(`inv(&jj + &1)`,`mu:real`) THEN GEN_TAC THEN DISCH_TAC] THEN + ONCE_REWRITE_TAC[NEGLIGIBLE_ON_INTERVALS] THEN + MAP_EVERY X_GEN_TAC [`a:real^M`; `b:real^M`] THEN + ASM_CASES_TAC `negligible(interval[a:real^M,b])` THENL + [ASM_MESON_TAC[NEGLIGIBLE_SUBSET; INTER_SUBSET]; ALL_TAC] THEN + RULE_ASSUM_TAC(REWRITE_RULE[NEGLIGIBLE_INTERVAL]) THEN + RULE_ASSUM_TAC(REWRITE_RULE[INTERVAL_NE_EMPTY]) THEN + REWRITE_TAC[NEGLIGIBLE_OUTER_LE] THEN + X_GEN_TAC `e:real` THEN DISCH_TAC THEN + MP_TAC(ISPECL [`f:real^M->real^N`; `a - vec 1:real^M`; `b + vec 1:real^M`] + HENSTOCK_LEMMA) THEN + ANTS_TAC THENL + [ASM_MESON_TAC[INTEGRABLE_ON_SUBINTERVAL; SUBSET_UNIV]; ALL_TAC] THEN + DISCH_THEN(MP_TAC o SPEC `(e * mu) / &2 / &3 pow (dimindex(:M))`) THEN + ASM_SIMP_TAC[REAL_HALF; REAL_LT_DIV; REAL_LT_MUL; + REAL_POW_LT; REAL_OF_NUM_LT; ARITH] THEN + DISCH_THEN(X_CHOOSE_THEN `g:real^M->real^M->bool` STRIP_ASSUME_TAC) THEN + REWRITE_TAC[SET_RULE `{x | P x} INTER s = {x | x IN s /\ P x}`] THEN + ABBREV_TAC + `E = {x | x IN interval[a,b] /\ + !d. &0 < d + ==> ?h. &0 < h /\ h < d /\ + mu <= dist(i h x,(f:real^M->real^N) x)}` THEN + SUBGOAL_THEN + `!x. x IN E + ==> ?h. &0 < h /\ + (box h x:real^M->bool) SUBSET (g x) /\ + (box h x:real^M->bool) SUBSET interval[a - vec 1,b + vec 1] /\ + mu <= dist(i h x,(f:real^M->real^N) x)` + MP_TAC THENL + [X_GEN_TAC `x:real^M` THEN EXPAND_TAC "E" THEN REWRITE_TAC[IN_ELIM_THM] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [gauge]) THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC o SPEC `x:real^M`) THEN + REWRITE_TAC[OPEN_CONTAINS_BALL] THEN + DISCH_THEN(MP_TAC o SPEC `x:real^M`) THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC) THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC + (MP_TAC o SPEC `min (&1) (d / &(dimindex(:M)))`)) THEN + REWRITE_TAC[REAL_LT_MIN; REAL_LT_01; GSYM CONJ_ASSOC] THEN + ASM_SIMP_TAC[REAL_LT_DIV; DIMINDEX_GE_1; LE_1; REAL_OF_NUM_LT] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `h:real` THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN CONJ_TAC THENL + [MATCH_MP_TAC SUBSET_TRANS THEN + EXISTS_TAC `ball(x:real^M,d)` THEN ASM_REWRITE_TAC[] THEN + EXPAND_TAC "box" THEN + REWRITE_TAC[SUBSET; IN_INTERVAL; IN_BALL] THEN + X_GEN_TAC `y:real^M` THEN + REWRITE_TAC[VECTOR_SUB_COMPONENT; VECTOR_ADD_COMPONENT; dist; + VECTOR_MUL_COMPONENT; VEC_COMPONENT; REAL_MUL_RID] THEN + SIMP_TAC[REAL_ARITH `x - h <= y /\ y <= x + h <=> abs(x - y) <= h`] THEN + DISCH_TAC THEN MATCH_MP_TAC REAL_LET_TRANS THEN + EXISTS_TAC `sum(1..dimindex(:M)) (\i. abs((x - y:real^M)$i))` THEN + REWRITE_TAC[NORM_LE_L1] THEN MATCH_MP_TAC SUM_BOUND_LT_GEN THEN + REWRITE_TAC[FINITE_NUMSEG; NUMSEG_EMPTY; IN_NUMSEG] THEN + SIMP_TAC[NOT_LT; DIMINDEX_GE_1; CARD_NUMSEG_1; VECTOR_SUB_COMPONENT] THEN + ASM_MESON_TAC[REAL_LET_TRANS]; + UNDISCH_TAC `(x:real^M) IN interval[a,b]` THEN + EXPAND_TAC "box" THEN REWRITE_TAC[SUBSET; IN_INTERVAL] THEN + DISCH_THEN(fun th -> X_GEN_TAC `y:real^M` THEN MP_TAC th) THEN + REWRITE_TAC[IMP_IMP; AND_FORALL_THM] THEN MATCH_MP_TAC MONO_FORALL THEN + X_GEN_TAC `i:num` THEN + DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN + ASM_REWRITE_TAC[] THEN + REWRITE_TAC[VECTOR_SUB_COMPONENT; VECTOR_ADD_COMPONENT; dist; + VECTOR_MUL_COMPONENT; VEC_COMPONENT; REAL_MUL_RID] THEN + ASM_REAL_ARITH_TAC]; + ALL_TAC] THEN + GEN_REWRITE_TAC (LAND_CONV o TOP_DEPTH_CONV) [RIGHT_IMP_EXISTS_THM] THEN + REWRITE_TAC[SKOLEM_THM; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `uv:real^M->real` THEN + REWRITE_TAC[TAUT `(a ==> b /\ c) <=> (a ==> b) /\ (a ==> c)`] THEN + REWRITE_TAC[FORALL_AND_THM] THEN STRIP_TAC THEN + MP_TAC(ISPECL [`a:real^M`; `b:real^M`; `E:real^M->bool`; + `\x:real^M. if x IN E then ball(x,uv x) else g(x)`] + COVERING_LEMMA) THEN + REWRITE_TAC[] THEN ANTS_TAC THENL + [ASM_REWRITE_TAC[INTERVAL_NE_EMPTY] THEN CONJ_TAC THENL + [EXPAND_TAC "E" THEN SET_TAC[]; ALL_TAC] THEN + REWRITE_TAC[gauge] THEN GEN_TAC THEN + COND_CASES_TAC THEN ASM_SIMP_TAC[OPEN_BALL; CENTRE_IN_BALL] THEN + RULE_ASSUM_TAC(REWRITE_RULE[gauge]) THEN ASM_REWRITE_TAC[]; + ALL_TAC] THEN + DISCH_THEN(X_CHOOSE_TAC `D:(real^M->bool)->bool`) THEN + EXISTS_TAC `UNIONS D:real^M->bool` THEN ASM_REWRITE_TAC[] THEN + SUBGOAL_THEN + `measurable(UNIONS D:real^M->bool) /\ + measure(UNIONS D) <= measure(interval[a:real^M,b])` + STRIP_ASSUME_TAC THENL + [MATCH_MP_TAC MEASURE_COUNTABLE_UNIONS_LE_STRONG_GEN THEN + ASM_REWRITE_TAC[] THEN + CONJ_TAC THENL [ASM_MESON_TAC[SUBSET; MEASURABLE_INTERVAL]; ALL_TAC] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC MEASURE_SUBSET THEN + REWRITE_TAC[MEASURABLE_INTERVAL] THEN + CONJ_TAC THENL [ALL_TAC; ASM SET_TAC[]] THEN + MATCH_MP_TAC MEASURABLE_UNIONS THEN + ASM_MESON_TAC[SUBSET; MEASURABLE_INTERVAL]; + ALL_TAC] THEN + ASM_REWRITE_TAC[] THEN + SUBGOAL_THEN + `?d. d SUBSET D /\ FINITE d /\ + measure(UNIONS D:real^M->bool) <= &2 * measure(UNIONS d)` + STRIP_ASSUME_TAC THENL + [ASM_CASES_TAC `measure(UNIONS D:real^M->bool) = &0` THENL + [EXISTS_TAC `{}:(real^M->bool)->bool` THEN + ASM_REWRITE_TAC[FINITE_EMPTY; EMPTY_SUBSET; MEASURE_EMPTY; UNIONS_0] THEN + CONV_TAC REAL_RAT_REDUCE_CONV; + MP_TAC(ISPECL [`D:(real^M->bool)->bool`; `measure(interval[a:real^M,b])`; + `measure(UNIONS D:real^M->bool) / &2`] + MEASURE_COUNTABLE_UNIONS_APPROACHABLE) THEN + ASM_REWRITE_TAC[] THEN ANTS_TAC THENL + [ASM_SIMP_TAC[MEASURABLE_MEASURE_POS_LT; REAL_HALF] THEN + ASM_SIMP_TAC[GSYM MEASURABLE_MEASURE_EQ_0] THEN + CONJ_TAC THENL [ASM_MESON_TAC[MEASURABLE_INTERVAL]; ALL_TAC] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC MEASURE_SUBSET THEN + REPEAT(CONJ_TAC THENL + [ASM_MESON_TAC[SUBSET; MEASURABLE_INTERVAL; MEASURABLE_UNIONS]; + ALL_TAC]) THEN + ASM SET_TAC[]; + MATCH_MP_TAC MONO_EXISTS THEN SIMP_TAC[] THEN REAL_ARITH_TAC]]; + ALL_TAC] THEN + FIRST_ASSUM(MP_TAC o el 3 o CONJUNCTS) THEN + REWRITE_TAC[RIGHT_IMP_EXISTS_THM; SKOLEM_THM] THEN + ONCE_REWRITE_TAC[TAUT `a /\ b <=> ~(a ==> ~b)`] THEN + SIMP_TAC[IN_INTER] THEN REWRITE_TAC[NOT_IMP; GSYM CONJ_ASSOC] THEN + DISCH_THEN(X_CHOOSE_TAC `tag:(real^M->bool)->real^M`) THEN + FIRST_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH + `D <= &2 * d ==> d <= e / &2 ==> D <= e`)) THEN + MP_TAC(ISPEC + `IMAGE (\k:real^M->bool. (box:real->real^M->real^M->bool) + (uv(tag k):real) ((tag k:real^M))) d` + AUSTIN_LEMMA) THEN + ASM_SIMP_TAC[FINITE_IMAGE; FORALL_IN_IMAGE] THEN ANTS_TAC THENL + [X_GEN_TAC `k:real^M->bool` THEN DISCH_TAC THEN EXPAND_TAC "box" THEN + EXISTS_TAC `&2 * uv((tag:(real^M->bool)->real^M) k):real` THEN + EXISTS_TAC `(tag:(real^M->bool)->real^M) k - uv(tag k) % vec 1:real^M` THEN + EXISTS_TAC `(tag:(real^M->bool)->real^M) k + uv(tag k) % vec 1:real^M` THEN + REWRITE_TAC[VECTOR_SUB_COMPONENT; VECTOR_ADD_COMPONENT; dist; + VECTOR_MUL_COMPONENT; VEC_COMPONENT; REAL_MUL_RID] THEN + ASM_REAL_ARITH_TAC; + ALL_TAC] THEN + REWRITE_TAC[EXISTS_SUBSET_IMAGE; real_ge] THEN + SIMP_TAC[REAL_LE_LDIV_EQ; REAL_POW_LT; REAL_OF_NUM_LT; ARITH] THEN + DISCH_THEN(X_CHOOSE_THEN `p:(real^M->bool)->bool` MP_TAC) THEN + REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + MATCH_MP_TAC(REAL_ARITH + `d <= d' /\ p <= e ==> d' <= p ==> d <= e`) THEN + CONJ_TAC THENL + [MATCH_MP_TAC MEASURE_SUBSET THEN REPEAT CONJ_TAC THENL + [MATCH_MP_TAC MEASURABLE_UNIONS THEN + ASM_MESON_TAC[SUBSET; MEASURABLE_INTERVAL]; + MATCH_MP_TAC MEASURABLE_UNIONS THEN + ASM_SIMP_TAC[FINITE_IMAGE; FORALL_IN_IMAGE] THEN + EXPAND_TAC "box" THEN REWRITE_TAC[MEASURABLE_INTERVAL]; + REWRITE_TAC[SUBSET; IN_UNIONS; EXISTS_IN_IMAGE] THEN + X_GEN_TAC `z:real^M` THEN MATCH_MP_TAC MONO_EXISTS THEN + X_GEN_TAC `k:real^M->bool` THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + UNDISCH_TAC `(z:real^M) IN k` THEN SPEC_TAC(`z:real^M`,`z:real^M`) THEN + REWRITE_TAC[GSYM SUBSET] THEN MATCH_MP_TAC SUBSET_TRANS THEN + EXISTS_TAC `ball(tag k:real^M,uv(tag(k:real^M->bool)))` THEN + CONJ_TAC THENL [ASM_MESON_TAC[SUBSET]; ALL_TAC] THEN + EXPAND_TAC "box" THEN REWRITE_TAC[SUBSET; IN_BALL; IN_INTERVAL] THEN + X_GEN_TAC `z:real^M` THEN REWRITE_TAC[dist] THEN DISCH_TAC THEN + REWRITE_TAC[VECTOR_SUB_COMPONENT; VECTOR_ADD_COMPONENT; dist; + VECTOR_MUL_COMPONENT; VEC_COMPONENT; REAL_MUL_RID] THEN + SIMP_TAC[REAL_ARITH `x - h <= y /\ y <= x + h <=> abs(x - y) <= h`] THEN + REWRITE_TAC[GSYM VECTOR_SUB_COMPONENT] THEN + ASM_MESON_TAC[COMPONENT_LE_NORM; REAL_LT_IMP_LE; REAL_LE_TRANS]]; + ALL_TAC] THEN + SIMP_TAC[GSYM REAL_LE_RDIV_EQ; REAL_POW_LT; REAL_OF_NUM_LT; ARITH] THEN + SUBGOAL_THEN `FINITE(p:(real^M->bool)->bool)` ASSUME_TAC THENL + [ASM_MESON_TAC[FINITE_SUBSET]; ALL_TAC] THEN + MATCH_MP_TAC REAL_LE_LCANCEL_IMP THEN + EXISTS_TAC `mu:real` THEN ASM_REWRITE_TAC[] THEN + FIRST_X_ASSUM(MP_TAC o SPEC + `IMAGE (\k. (tag:(real^M->bool)->real^M) k, + (box(uv(tag k):real) (tag k):real^M->bool)) p`) THEN + ANTS_TAC THENL + [REWRITE_TAC[tagged_partial_division_of; fine] THEN + REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN + REWRITE_TAC[IN_IMAGE; PAIR_EQ] THEN + REWRITE_TAC[MESON[] + `(!x j. (?k. (x = tag k /\ j = g k) /\ k IN d) ==> P x j) <=> + (!k. k IN d ==> P (tag k) (g k))`] THEN + ASM_SIMP_TAC[FINITE_IMAGE] THEN REPEAT CONJ_TAC THENL + [X_GEN_TAC `k:real^M->bool` THEN DISCH_TAC THEN REPEAT CONJ_TAC THENL + [EXPAND_TAC "box" THEN REWRITE_TAC[IN_INTERVAL] THEN + REWRITE_TAC[VECTOR_SUB_COMPONENT; VECTOR_ADD_COMPONENT; dist; + VECTOR_MUL_COMPONENT; VEC_COMPONENT; REAL_MUL_RID] THEN + GEN_TAC THEN STRIP_TAC THEN MATCH_MP_TAC(REAL_ARITH + `&0 < u ==> x - u <= x /\ x <= x + u`) THEN ASM_MESON_TAC[SUBSET]; + ASM_MESON_TAC[SUBSET]; + EXPAND_TAC "box" THEN MESON_TAC[]]; + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [pairwise]) THEN + REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_IMAGE] THEN + MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `k1:real^M->bool` THEN + ASM_CASES_TAC `(k1:real^M->bool) IN p` THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `k2:real^M->bool` THEN + ASM_CASES_TAC `(k2:real^M->bool) IN p` THEN ASM_REWRITE_TAC[] THEN + ASM_CASES_TAC `(tag:(real^M->bool)->real^M) k1 = tag k2` THEN + ASM_REWRITE_TAC[] THEN ANTS_TAC THENL + [EXPAND_TAC "box" THEN REWRITE_TAC[GSYM SUBSET_ANTISYM_EQ] THEN + REWRITE_TAC[SUBSET_INTERVAL] THEN + REWRITE_TAC[VECTOR_SUB_COMPONENT; VECTOR_ADD_COMPONENT; dist; + VECTOR_MUL_COMPONENT; VEC_COMPONENT; REAL_MUL_RID] THEN + REWRITE_TAC[REAL_ARITH `x - e <= x + e <=> &0 <= e`] THEN + SUBGOAL_THEN `&0 <= uv((tag:(real^M->bool)->real^M) k1) /\ + &0 <= uv((tag:(real^M->bool)->real^M) k2)` + STRIP_ASSUME_TAC THENL + [ASM_MESON_TAC[SUBSET; REAL_LT_IMP_LE]; ASM_REWRITE_TAC[]] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE RAND_CONV [CART_EQ]) THEN + MATCH_MP_TAC MONO_NOT THEN REWRITE_TAC[AND_FORALL_THM] THEN + MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `i:num` THEN + DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN + ASM_REWRITE_TAC[] THEN REAL_ARITH_TAC; + MATCH_MP_TAC(SET_RULE + `i1 SUBSET s1 /\ i2 SUBSET s2 + ==> DISJOINT s1 s2 ==> i1 INTER i2 = {}`) THEN + REWRITE_TAC[INTERIOR_SUBSET]]; + ASM_MESON_TAC[SUBSET]]; + ALL_TAC] THEN + MATCH_MP_TAC(REAL_ARITH `e = e' /\ y <= x ==> x < e ==> y <= e'`) THEN + CONJ_TAC THENL [REWRITE_TAC[real_div; REAL_MUL_AC]; ALL_TAC] THEN + ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN ASM_SIMP_TAC[GSYM REAL_LE_RDIV_EQ] THEN + W(MP_TAC o PART_MATCH (lhand o rand) MEASURE_UNIONS_LE o lhand o snd) THEN + ANTS_TAC THENL + [ASM_SIMP_TAC[FINITE_IMAGE; FORALL_IN_IMAGE] THEN + EXPAND_TAC "box" THEN REWRITE_TAC[MEASURABLE_INTERVAL]; + ALL_TAC] THEN + MATCH_MP_TAC(REAL_ARITH `a' <= e ==> a <= a' ==> a <= e`) THEN + ASM_SIMP_TAC[REAL_LE_RDIV_EQ; GSYM SUM_RMUL] THEN + MATCH_MP_TAC SUM_LE_INCLUDED THEN + ASM_SIMP_TAC[FORALL_IN_IMAGE; RIGHT_EXISTS_AND_THM; FINITE_IMAGE] THEN + REWRITE_TAC[NORM_POS_LE; EXISTS_IN_IMAGE] THEN + EXISTS_TAC `SND:real^M#(real^M->bool)->real^M->bool` THEN + X_GEN_TAC `k:real^M->bool` THEN DISCH_TAC THEN + EXISTS_TAC `k:real^M->bool` THEN ASM_REWRITE_TAC[] THEN + SUBGOAL_THEN + `&0 < uv(tag(k:real^M->bool):real^M):real` ASSUME_TAC + THENL [ASM_MESON_TAC[SUBSET]; ALL_TAC] THEN + SUBGOAL_THEN + `&0 < measure(box(uv(tag(k:real^M->bool):real^M):real) (tag +k):real^M->bool)` + MP_TAC THENL + [EXPAND_TAC "box" THEN + REWRITE_TAC[MEASURE_INTERVAL; CONTENT_CLOSED_INTERVAL_CASES] THEN + REWRITE_TAC[VECTOR_SUB_COMPONENT; VECTOR_ADD_COMPONENT; dist; + VECTOR_MUL_COMPONENT; VEC_COMPONENT; REAL_MUL_RID] THEN + ASM_SIMP_TAC[REAL_ARITH `&0 < x ==> a - x <= a + x`] THEN + MATCH_MP_TAC PRODUCT_POS_LT_NUMSEG THEN + REWRITE_TAC[] THEN ASM_REAL_ARITH_TAC; + ALL_TAC] THEN + ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN SIMP_TAC[GSYM REAL_LE_RDIV_EQ] THEN + DISCH_THEN(fun th -> + GEN_REWRITE_TAC (funpow 2 RAND_CONV) + [MATCH_MP(REAL_ARITH `&0 < x ==> x = abs x`) th] THEN + ASSUME_TAC th) THEN + REWRITE_TAC[real_div; GSYM REAL_ABS_INV] THEN + ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN REWRITE_TAC[GSYM NORM_MUL] THEN + SUBGOAL_THEN + `mu <= dist(i (uv(tag(k:real^M->bool):real^M):real) (tag k):real^N, + f(tag k))` + MP_TAC THENL [ASM_MESON_TAC[SUBSET]; ALL_TAC] THEN + MATCH_MP_TAC(REAL_ARITH `x = y ==> m <= x ==> m <= y`) THEN + ONCE_REWRITE_TAC[DIST_SYM] THEN EXPAND_TAC "i" THEN + REWRITE_TAC[dist; VECTOR_SUB_LDISTRIB] THEN + UNDISCH_TAC + `&0 < measure(box(uv(tag(k:real^M->bool):real^M):real) + (tag k):real^M->bool)` THEN + EXPAND_TAC "box" THEN REWRITE_TAC[MEASURE_INTERVAL] THEN + SIMP_TAC[VECTOR_MUL_ASSOC; REAL_LT_IMP_NZ; REAL_MUL_LINV] THEN + REWRITE_TAC[VECTOR_MUL_LID]);; + +let HAS_VECTOR_DERIVATIVE_INDEFINITE_INTEGRAL = prove + (`!f:real^1->real^N a b. + f integrable_on interval[a,b] + ==> ?k. negligible k /\ + !x. x IN interval[a,b] DIFF k + ==> ((\x. integral(interval[a,x]) f) has_vector_derivative + f(x)) (at x within interval[a,b])`, + SUBGOAL_THEN + `!f:real^1->real^N a b. + f integrable_on interval[a,b] + ==> ?k. negligible k /\ + !x e. x IN interval[a,b] DIFF k /\ & 0 < e + ==> ?d. &0 < d /\ + !x'. x' IN interval[a,b] /\ + drop x < drop x' /\ drop x' < drop x + d + ==> norm(integral(interval[x,x']) f - + drop(x' - x) % f x) / + norm(x' - x) < e` + ASSUME_TAC THENL + [REPEAT STRIP_TAC THEN MP_TAC(ISPEC + `(\x. if x IN interval[a,b] then f x else vec 0):real^1->real^N` + INTEGRABLE_CCONTINUOUS_EXPLICIT) THEN + REWRITE_TAC[] THEN ANTS_TAC THENL + [REPEAT GEN_TAC THEN MATCH_MP_TAC INTEGRABLE_ON_SUBINTERVAL THEN + EXISTS_TAC `(:real^1)` THEN + ASM_REWRITE_TAC[INTEGRABLE_RESTRICT_UNIV; SUBSET_UNIV]; + ALL_TAC] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `k:real^1->bool` THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + MAP_EVERY X_GEN_TAC [`x:real^1`; `e:real`] THEN + REWRITE_TAC[IN_DIFF] THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`x:real^1`; `e:real`]) THEN + ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `d:real` THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + X_GEN_TAC `y:real^1` THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `drop y - drop x`) THEN + ANTS_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `x + (drop y - drop x) % vec 1 = y` SUBST1_TAC THENL + [REWRITE_TAC[GSYM DROP_EQ; DROP_ADD; DROP_CMUL; DROP_VEC] THEN + REAL_ARITH_TAC; + ALL_TAC] THEN + ASM_SIMP_TAC[CONTENT_1; REAL_LT_IMP_LE] THEN + MATCH_MP_TAC(REAL_ARITH `x = y ==> x < e ==> y < e`) THEN + ASM_SIMP_TAC[REAL_EQ_RDIV_EQ; NORM_POS_LT; VECTOR_SUB_EQ; + GSYM DROP_EQ; REAL_LT_IMP_NE] THEN + SUBGOAL_THEN `norm(y - x) = abs(drop y - drop x)` SUBST1_TAC THENL + [REWRITE_TAC[NORM_REAL; GSYM drop; DROP_SUB]; ALL_TAC] THEN + REWRITE_TAC[ONCE_REWRITE_RULE[REAL_MUL_SYM] (GSYM NORM_MUL)] THEN + REWRITE_TAC[VECTOR_SUB_LDISTRIB; VECTOR_MUL_ASSOC] THEN + ASM_SIMP_TAC[REAL_FIELD `x < y ==> (y - x) * inv(y - x) = &1`] THEN + AP_TERM_TAC THEN REWRITE_TAC[DROP_SUB; VECTOR_MUL_LID] THEN + AP_THM_TAC THEN AP_TERM_TAC THEN MATCH_MP_TAC INTEGRAL_EQ THEN + X_GEN_TAC `z:real^1` THEN REWRITE_TAC[DIFF_EMPTY] THEN DISCH_TAC THEN + COND_CASES_TAC THEN REWRITE_TAC[] THEN + RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1]) THEN ASM_REAL_ARITH_TAC; + ALL_TAC] THEN + REPEAT STRIP_TAC THEN + FIRST_X_ASSUM(fun th -> + MP_TAC(ISPECL [`f:real^1->real^N`; `a:real^1`; `b:real^1`] th) THEN + MP_TAC(ISPECL [`\x. (f:real^1->real^N) (--x)`; `--b:real^1`; + `--a:real^1`] th)) THEN + ASM_REWRITE_TAC[INTEGRABLE_REFLECT] THEN + DISCH_THEN(X_CHOOSE_THEN `k2:real^1->bool` + (CONJUNCTS_THEN2 ASSUME_TAC (LABEL_TAC "2"))) THEN + DISCH_THEN(X_CHOOSE_THEN `k1:real^1->bool` + (CONJUNCTS_THEN2 ASSUME_TAC (LABEL_TAC "1"))) THEN + EXISTS_TAC `k1 UNION IMAGE (--) k2:real^1->bool` THEN CONJ_TAC THENL + [MATCH_MP_TAC NEGLIGIBLE_UNION THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC NEGLIGIBLE_LINEAR_IMAGE THEN ASM_REWRITE_TAC[linear] THEN + VECTOR_ARITH_TAC; + ALL_TAC] THEN + X_GEN_TAC `x:real^1` THEN REWRITE_TAC[IN_DIFF; IN_UNION; DE_MORGAN_THM] THEN + REWRITE_TAC[IN_IMAGE; VECTOR_ARITH `x:real^1 = --x' <=> --x = x'`] THEN + REWRITE_TAC[UNWIND_THM1] THEN STRIP_TAC THEN + REWRITE_TAC[has_vector_derivative; HAS_DERIVATIVE_WITHIN] THEN CONJ_TAC THENL + [REWRITE_TAC[linear; DROP_ADD; DROP_CMUL] THEN VECTOR_ARITH_TAC; + ALL_TAC] THEN + X_GEN_TAC `e:real` THEN DISCH_TAC THEN + REMOVE_THEN "2" (MP_TAC o SPECL [`--x:real^1`; `e:real`]) THEN + REMOVE_THEN "1" (MP_TAC o SPECL [`x:real^1`; `e:real`]) THEN + ASM_REWRITE_TAC[IN_DIFF; IN_INTERVAL_REFLECT] THEN + DISCH_THEN(X_CHOOSE_THEN `d1:real` + (CONJUNCTS_THEN2 ASSUME_TAC (LABEL_TAC "1"))) THEN + DISCH_THEN(X_CHOOSE_THEN `d2:real` + (CONJUNCTS_THEN2 ASSUME_TAC (LABEL_TAC "2"))) THEN + EXISTS_TAC `min d1 d2:real` THEN ASM_REWRITE_TAC[REAL_LT_MIN] THEN + X_GEN_TAC `y:real^1` THEN REWRITE_TAC[IN_INTERVAL_1] THEN + REWRITE_TAC[NORM_REAL; GSYM drop; DROP_SUB] THEN + RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1]) THEN STRIP_TAC THEN + SUBGOAL_THEN `drop x < drop y \/ drop y < drop x` DISJ_CASES_TAC THENL + [ASM_REAL_ARITH_TAC; + REMOVE_THEN "1" (MP_TAC o SPEC `y:real^1`) THEN + ANTS_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN + REWRITE_TAC[NORM_REAL; GSYM drop; DROP_SUB] THEN + MATCH_MP_TAC(REAL_ARITH `x = y ==> x < e ==> y < e`) THEN + AP_THM_TAC THEN AP_TERM_TAC THEN AP_TERM_TAC THEN + AP_THM_TAC THEN AP_TERM_TAC THEN + MATCH_MP_TAC(VECTOR_ARITH `c + a:real^N = b ==> a = b - c`) THEN + MATCH_MP_TAC INTEGRAL_COMBINE THEN + REPEAT(CONJ_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC]) THEN + MATCH_MP_TAC INTEGRABLE_SUBINTERVAL THEN + MAP_EVERY EXISTS_TAC [`a:real^1`; `b:real^1`] THEN + ASM_REWRITE_TAC[SUBSET_INTERVAL_1] THEN ASM_REAL_ARITH_TAC; + REMOVE_THEN "2" (MP_TAC o SPEC `--y:real^1`) THEN + ANTS_TAC THENL [SIMP_TAC[DROP_NEG] THEN ASM_REAL_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `norm(--y - --x) = abs(drop y - drop x)` SUBST1_TAC THENL + [REWRITE_TAC[NORM_REAL; GSYM drop; DROP_SUB; DROP_NEG] THEN + ASM_REAL_ARITH_TAC; + ALL_TAC] THEN + MATCH_MP_TAC(REAL_ARITH `x = y ==> x < e ==> y < e`) THEN + AP_THM_TAC THEN AP_TERM_TAC THEN REWRITE_TAC[INTEGRAL_REFLECT] THEN + REWRITE_TAC[VECTOR_NEG_NEG; DROP_SUB; DROP_NEG] THEN + ONCE_REWRITE_TAC[VECTOR_ARITH + `x - (--a - --b) % y:real^N = --(--x - (a - b) % y)`] THEN + REWRITE_TAC[NORM_NEG] THEN AP_TERM_TAC THEN + AP_THM_TAC THEN AP_TERM_TAC THEN + MATCH_MP_TAC(VECTOR_ARITH `b + a = c ==> --a:real^N = b - c`) THEN + MATCH_MP_TAC INTEGRAL_COMBINE THEN + REPEAT(CONJ_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC]) THEN + MATCH_MP_TAC INTEGRABLE_SUBINTERVAL THEN + MAP_EVERY EXISTS_TAC [`a:real^1`; `b:real^1`] THEN + ASM_REWRITE_TAC[SUBSET_INTERVAL_1] THEN ASM_REAL_ARITH_TAC]);; + +let ABSOLUTELY_INTEGRABLE_LEBESGUE_POINTS = prove + (`!f:real^M->real^N. + (!a b. f absolutely_integrable_on interval[a,b]) + ==> ?k. negligible k /\ + !x e. ~(x IN k) /\ &0 < e + ==> ?d. &0 < d /\ + !h. &0 < h /\ h < d + ==> norm(inv(content(interval[x - h % vec 1, + x + h % vec 1])) % + integral (interval[x - h % vec 1, + x + h % vec 1]) + (\t. lift(norm(f t - f x)))) + < e`, + REPEAT STRIP_TAC THEN + MP_TAC(GEN `r:real^N` (ISPEC `\t. lift(norm((f:real^M->real^N) t - r))` + INTEGRABLE_CCONTINUOUS_EXPLICIT_SYMMETRIC)) THEN + REWRITE_TAC[] THEN + DISCH_THEN(MP_TAC o MATCH_MP MONO_FORALL) THEN ANTS_TAC THENL + [REPEAT GEN_TAC THEN MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_IMP_INTEGRABLE THEN + MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_NORM THEN + MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_SUB THEN + ASM_REWRITE_TAC[ABSOLUTELY_INTEGRABLE_CONST]; + ALL_TAC] THEN + REWRITE_TAC[SKOLEM_THM; LEFT_IMP_EXISTS_THM; FORALL_AND_THM] THEN + X_GEN_TAC `k:real^N->real^M->bool` THEN STRIP_TAC THEN + EXISTS_TAC + `UNIONS (IMAGE (k:real^N->real^M->bool) + {x | !i. 1 <= i /\ i <= dimindex(:N) ==> rational(x$i)})` THEN + CONJ_TAC THENL + [MATCH_MP_TAC NEGLIGIBLE_COUNTABLE_UNIONS_GEN THEN + ASM_SIMP_TAC[COUNTABLE_IMAGE; COUNTABLE_RATIONAL_COORDINATES] THEN + ASM_REWRITE_TAC[FORALL_IN_IMAGE]; + ALL_TAC] THEN + MAP_EVERY X_GEN_TAC [`x:real^M`; `e:real`] THEN + REWRITE_TAC[UNIONS_IMAGE; IN_ELIM_THM; NOT_EXISTS_THM] THEN + REWRITE_TAC[TAUT `~(p /\ q) <=> p ==> ~q`] THEN STRIP_TAC THEN + MP_TAC(SET_RULE `(f:real^M->real^N) x IN (:real^N)`) THEN + REWRITE_TAC[GSYM CLOSURE_RATIONAL_COORDINATES] THEN + REWRITE_TAC[CLOSURE_APPROACHABLE; IN_ELIM_THM] THEN + DISCH_THEN(MP_TAC o SPEC `e / &3`) THEN + ASM_REWRITE_TAC[REAL_ARITH `&0 < e / &3 <=> &0 < e`] THEN + DISCH_THEN(X_CHOOSE_THEN `r:real^N` STRIP_ASSUME_TAC) THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`r:real^N`; `x:real^M`; `e / &3`]) THEN + ASM_SIMP_TAC[REAL_ARITH `&0 < e / &3 <=> &0 < e`] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `d:real` THEN STRIP_TAC THEN + ASM_REWRITE_TAC[] THEN X_GEN_TAC `h:real` THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `h:real`) THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC(NORM_ARITH + `norm(y1:real^N) < e / &3 /\ norm(i1 - i2) <= e / &3 + ==> norm(i1 - y1) < e / &3 ==> norm(i2) < e`) THEN + REWRITE_TAC[NORM_LIFT; REAL_ABS_NORM] THEN + CONJ_TAC THENL [ASM_MESON_TAC[dist; DIST_SYM]; ALL_TAC] THEN + REWRITE_TAC[GSYM VECTOR_SUB_LDISTRIB; NORM_MUL] THEN + MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC + `abs(inv(content(interval[x - h % vec 1,x + h % vec 1]))) * + drop(integral (interval[x - h % vec 1,x + h % vec 1]) + (\x:real^M. lift(e / &3)))` THEN + CONJ_TAC THENL + [MATCH_MP_TAC REAL_LE_LMUL THEN REWRITE_TAC[REAL_ABS_POS] THEN + W(MP_TAC o PART_MATCH (rand o rand) INTEGRAL_SUB o rand o lhand o snd) THEN + ANTS_TAC THENL + [CONJ_TAC THEN MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_IMP_INTEGRABLE THEN + MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_NORM THEN + MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_SUB THEN + ASM_REWRITE_TAC[ABSOLUTELY_INTEGRABLE_CONST]; + DISCH_THEN(SUBST1_TAC o SYM) THEN + MATCH_MP_TAC INTEGRAL_NORM_BOUND_INTEGRAL THEN + REWRITE_TAC[INTEGRABLE_CONST] THEN CONJ_TAC THENL + [MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_IMP_INTEGRABLE THEN + MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_SUB THEN CONJ_TAC THEN + MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_NORM THEN + MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_SUB THEN + ASM_REWRITE_TAC[ABSOLUTELY_INTEGRABLE_CONST]; + X_GEN_TAC `y:real^M` THEN STRIP_TAC THEN + REWRITE_TAC[NORM_LIFT; REAL_ABS_NORM; LIFT_DROP; GSYM LIFT_SUB] THEN + ASM_MESON_TAC[NORM_ARITH + `dist(r,x) < e / &3 + ==> abs(norm(y - r:real^N) - norm(y - x)) <= e / &3`]]]; + ASM_CASES_TAC + `content(interval[x - h % vec 1:real^M,x + h % vec 1]) = &0` + THENL + [ASM_REWRITE_TAC[REAL_INV_0; REAL_ABS_NUM; REAL_MUL_LZERO] THEN + ASM_REAL_ARITH_TAC; + REWRITE_TAC[REAL_ABS_INV] THEN ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN + ASM_SIMP_TAC[GSYM real_div; REAL_LE_LDIV_EQ; + GSYM REAL_ABS_NZ] THEN + REWRITE_TAC[INTEGRAL_CONST; DROP_CMUL; LIFT_DROP] THEN + SIMP_TAC[real_abs; CONTENT_POS_LE; REAL_MUL_SYM; REAL_LE_REFL]]]);; + +(* ------------------------------------------------------------------------- *) +(* Measurability of a function on a set (not necessarily itself measurable). *) +(* ------------------------------------------------------------------------- *) + +parse_as_infix("measurable_on",(12,"right"));; + +let measurable_on = new_definition + `(f:real^M->real^N) measurable_on s <=> + ?k g. negligible k /\ + (!n. (g n) continuous_on (:real^M)) /\ + (!x. ~(x IN k) + ==> ((\n. g n x) --> if x IN s then f(x) else vec 0) + sequentially)`;; + +let MEASURABLE_ON_UNIV = prove + (`(\x. if x IN s then f(x) else vec 0) measurable_on (:real^M) <=> + f measurable_on s`, + REWRITE_TAC[measurable_on; IN_UNIV; ETA_AX]);; + +(* ------------------------------------------------------------------------- *) +(* Lebesgue measurability (like "measurable" but allowing infinite measure) *) +(* ------------------------------------------------------------------------- *) + +let lebesgue_measurable = new_definition + `lebesgue_measurable s <=> (indicator s) measurable_on (:real^N)`;; + +(* ------------------------------------------------------------------------- *) +(* Relation between measurability and integrability. *) +(* ------------------------------------------------------------------------- *) + +let MEASURABLE_BOUNDED_BY_INTEGRABLE_IMP_INTEGRABLE = prove + (`!f:real^M->real^N g s. + f measurable_on s /\ + g integrable_on s /\ + (!x. x IN s ==> norm(f x) <= drop(g x)) + ==> f integrable_on s`, + let lemma = prove + (`!f:real^M->real^N g a b. + f measurable_on (:real^M) /\ + g integrable_on interval[a,b] /\ + (!x. x IN interval[a,b] ==> norm(f x) <= drop(g x)) + ==> f integrable_on interval[a,b]`, + REPEAT GEN_TAC THEN REWRITE_TAC[measurable_on; IN_UNIV] THEN + REWRITE_TAC[LEFT_AND_EXISTS_THM; LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`k:real^M->bool`; `h:num->real^M->real^N`] THEN + STRIP_TAC THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_IMP] INTEGRABLE_SPIKE_SET) THEN + EXISTS_TAC `interval[a:real^M,b] DIFF k` THEN CONJ_TAC THENL + [FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + NEGLIGIBLE_SUBSET)) THEN SET_TAC[]; + ALL_TAC] THEN + MATCH_MP_TAC DOMINATED_CONVERGENCE_INTEGRABLE THEN + MAP_EVERY EXISTS_TAC + [`h:num->real^M->real^N`; `g:real^M->real^1`] THEN + ASM_SIMP_TAC[IN_DIFF] THEN REWRITE_TAC[LEFT_AND_FORALL_THM] THEN + X_GEN_TAC `n:num` THEN + UNDISCH_TAC `(g:real^M->real^1) integrable_on interval [a,b]` THEN + SUBGOAL_THEN + `(h:num->real^M->real^N) n absolutely_integrable_on interval[a,b]` + MP_TAC THENL + [MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_CONTINUOUS THEN + ASM_MESON_TAC[CONTINUOUS_ON_SUBSET; SUBSET_UNIV]; + REWRITE_TAC[IMP_IMP; absolutely_integrable_on; GSYM CONJ_ASSOC] THEN + REPEAT(MATCH_MP_TAC MONO_AND THEN CONJ_TAC) THEN + MATCH_MP_TAC INTEGRABLE_SPIKE_SET THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + NEGLIGIBLE_SUBSET)) THEN SET_TAC[]]) in + ONCE_REWRITE_TAC[GSYM MEASURABLE_ON_UNIV] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC INTEGRABLE_ON_ALL_INTERVALS_INTEGRABLE_BOUND THEN + EXISTS_TAC `g:real^M->real^1` THEN ASM_REWRITE_TAC[] THEN + MAP_EVERY X_GEN_TAC [`a:real^M`; `b:real^M`] THEN + MATCH_MP_TAC lemma THEN + EXISTS_TAC `(\x. if x IN s then g x else vec 0):real^M->real^1` THEN + RULE_ASSUM_TAC(ONCE_REWRITE_RULE[INTEGRABLE_ALT]) THEN + ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN + COND_CASES_TAC THEN ASM_SIMP_TAC[NORM_0; DROP_VEC; REAL_POS]);; + +let MEASURABLE_BOUNDED_BY_INTEGRABLE_IMP_ABSOLUTELY_INTEGRABLE = prove + (`!f:real^M->real^N g s. + f measurable_on s /\ + g integrable_on s /\ + (!x. x IN s ==> norm(f x) <= drop(g x)) + ==> f absolutely_integrable_on s`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`f:real^M->real^N`; `g:real^M->real^1`] + ABSOLUTELY_INTEGRABLE_ABSOLUTELY_INTEGRABLE_BOUND) THEN + DISCH_THEN MATCH_MP_TAC THEN REPEAT CONJ_TAC THENL + [REWRITE_TAC[NORM_REAL; GSYM drop] THEN + ASM_MESON_TAC[REAL_ABS_LE; REAL_LE_TRANS]; + ASM_MESON_TAC[MEASURABLE_BOUNDED_BY_INTEGRABLE_IMP_INTEGRABLE]; + MATCH_MP_TAC NONNEGATIVE_ABSOLUTELY_INTEGRABLE THEN + REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN + ASM_REWRITE_TAC[IMP_IMP; DIMINDEX_1; FORALL_1; GSYM drop] THEN + ASM_MESON_TAC[NORM_ARITH `norm(x) <= a ==> &0 <= a`]]);; + +let INTEGRAL_DROP_LE_MEASURABLE = prove + (`!f g s:real^N->bool. + f measurable_on s /\ + g integrable_on s /\ + (!x. x IN s ==> &0 <= drop(f x) /\ drop(f x) <= drop(g x)) + ==> drop(integral s f) <= drop(integral s g)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC INTEGRAL_DROP_LE THEN ASM_SIMP_TAC[] THEN + MATCH_MP_TAC MEASURABLE_BOUNDED_BY_INTEGRABLE_IMP_INTEGRABLE THEN + EXISTS_TAC `g:real^N->real^1` THEN + ASM_SIMP_TAC[NORM_REAL; GSYM drop; real_abs]);; + +let INTEGRABLE_SUBINTERVALS_IMP_MEASURABLE = prove + (`!f:real^M->real^N. + (!a b. f integrable_on interval[a,b]) ==> f measurable_on (:real^M)`, + REPEAT STRIP_TAC THEN REWRITE_TAC[measurable_on; IN_UNIV] THEN + MAP_EVERY ABBREV_TAC + [`box = \h x. interval[x:real^M,x + h % vec 1]`; + `i = \h:real x:real^M. inv(content(box h x)) % + integral (box h x) (f:real^M->real^N)`] THEN + ONCE_REWRITE_TAC[SWAP_EXISTS_THM] THEN + EXISTS_TAC `(\n x. i (inv(&n + &1)) x):num->real^M->real^N` THEN + REWRITE_TAC[] THEN + ONCE_REWRITE_TAC[TAUT `a /\ b /\ c <=> b /\ a /\ c`] THEN + REWRITE_TAC[RIGHT_EXISTS_AND_THM] THEN CONJ_TAC THENL + [REWRITE_TAC[continuous_on; IN_UNIV] THEN + MAP_EVERY X_GEN_TAC [`n:num`; `x:real^M`; `e:real`] THEN + DISCH_TAC THEN EXPAND_TAC "i" THEN EXPAND_TAC "box" THEN + MP_TAC(ISPECL + [`f:real^M->real^N`; + `x - &2 % vec 1:real^M`; + `x + &2 % vec 1:real^M`; + `x:real^M`; + `x + inv(&n + &1) % vec 1:real^M`; + `e * (&1 / (&n + &1)) pow dimindex(:M)`] + INDEFINITE_INTEGRAL_CONTINUOUS) THEN + ANTS_TAC THENL + [ASM_REWRITE_TAC[IN_INTERVAL; VECTOR_SUB_COMPONENT; VECTOR_ADD_COMPONENT; + REAL_MUL_RID; VECTOR_MUL_COMPONENT; VEC_COMPONENT] THEN + REWRITE_TAC[CONJ_ASSOC] THEN CONJ_TAC THENL + [SUBGOAL_THEN `&0 <= inv(&n + &1) /\ inv(&n + &1) <= &1` MP_TAC THENL + [ALL_TAC; REAL_ARITH_TAC] THEN + ASM_REWRITE_TAC[REAL_LE_INV_EQ; REAL_ARITH `&0 <= &n + &1`] THEN + MATCH_MP_TAC REAL_INV_LE_1 THEN REAL_ARITH_TAC; + MATCH_MP_TAC REAL_LT_MUL THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC REAL_POW_LT THEN MATCH_MP_TAC REAL_LT_DIV THEN + REAL_ARITH_TAC]; + DISCH_THEN(X_CHOOSE_THEN `k:real` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `min k (&1)` THEN + ASM_REWRITE_TAC[REAL_LT_MIN; REAL_LT_01] THEN + ASM_REWRITE_TAC[dist] THEN X_GEN_TAC `y:real^M` THEN DISCH_TAC THEN + REWRITE_TAC[CONTENT_CLOSED_INTERVAL_CASES] THEN + REWRITE_TAC[VECTOR_SUB_COMPONENT; VECTOR_ADD_COMPONENT; dist; + VECTOR_MUL_COMPONENT; VEC_COMPONENT; REAL_MUL_RID] THEN + REWRITE_TAC[REAL_ARITH `a <= a + x <=> &0 <= x`] THEN + REWRITE_TAC[REAL_LE_INV_EQ; REAL_ARITH `&0 <= &n + &1`] THEN + REWRITE_TAC[REAL_ARITH `(x + inv y) - x = &1 / y`] THEN + REWRITE_TAC[PRODUCT_CONST_NUMSEG; ADD_SUB] THEN + REWRITE_TAC[GSYM VECTOR_SUB_LDISTRIB; NORM_MUL] THEN + REWRITE_TAC[REAL_ABS_INV; REAL_ABS_POW; REAL_ABS_DIV] THEN + REWRITE_TAC[REAL_ABS_NUM; REAL_ARITH `abs(&n + &1) = &n + &1`] THEN + ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN REWRITE_TAC[GSYM real_div] THEN + ASM_SIMP_TAC[REAL_LT_LDIV_EQ; REAL_LT_DIV; REAL_POW_LT; + REAL_ARITH `&0 < &1 /\ &0 < &n + &1`] THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN + REWRITE_TAC[VECTOR_ARITH `(y + i) - (x + i):real^N = y - x`; + VECTOR_ARITH `(y - i) - (x - i):real^N = y - x`] THEN + ASM_SIMP_TAC[IN_INTERVAL; REAL_LT_IMP_LE] THEN + REWRITE_TAC[VECTOR_SUB_COMPONENT; VECTOR_ADD_COMPONENT; dist; + VECTOR_MUL_COMPONENT; VEC_COMPONENT; REAL_MUL_RID] THEN + REWRITE_TAC[AND_FORALL_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 + `&0 <= i /\ i <= &1 /\ abs(x - y) <= &1 + ==> (x - &2 <= y /\ y <= x + &2) /\ + (x - &2 <= y + i /\ y + i <= x + &2)`) THEN + ASM_SIMP_TAC[REAL_LE_INV_EQ; REAL_INV_LE_1; + REAL_ARITH `&0 <= &n + &1 /\ &1 <= &n + &1`] THEN + REWRITE_TAC[GSYM VECTOR_SUB_COMPONENT] THEN + ASM_MESON_TAC[COMPONENT_LE_NORM; REAL_LT_IMP_LE; NORM_SUB; + REAL_LE_TRANS]]; + FIRST_ASSUM(MP_TAC o MATCH_MP INTEGRABLE_CCONTINUOUS_EXPLICIT) THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `k:real^M->bool` THEN + ASM_CASES_TAC `negligible(k:real^M->bool)` THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `x:real^M` THEN + DISCH_THEN(fun th -> DISCH_TAC THEN MP_TAC th) THEN + REWRITE_TAC[LIM_SEQUENTIALLY] THEN + MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `e:real` THEN + DISCH_THEN(fun th -> DISCH_TAC THEN MP_TAC th) THEN + ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `d:real` THEN STRIP_TAC THEN + MP_TAC(SPEC `d: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 + MAP_EVERY EXPAND_TAC ["i"; "box"] THEN REWRITE_TAC[dist] THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN + REWRITE_TAC[REAL_LT_INV_EQ; REAL_ARITH `&0 < &n + &1`] 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]);; + +let INTEGRABLE_IMP_MEASURABLE = prove + (`!f:real^M->real^N s. + f integrable_on s ==> f measurable_on s`, + REPEAT GEN_TAC THEN + ONCE_REWRITE_TAC[GSYM INTEGRABLE_RESTRICT_UNIV; GSYM MEASURABLE_ON_UNIV] THEN + SPEC_TAC(`\x. if x IN s then (f:real^M->real^N) x else vec 0`, + `f:real^M->real^N`) THEN + REPEAT STRIP_TAC THEN + MATCH_MP_TAC INTEGRABLE_SUBINTERVALS_IMP_MEASURABLE THEN + REPEAT GEN_TAC THEN MATCH_MP_TAC INTEGRABLE_ON_SUBINTERVAL THEN + EXISTS_TAC `(:real^M)` THEN ASM_REWRITE_TAC[SUBSET_UNIV]);; + +let ABSOLUTELY_INTEGRABLE_MEASURABLE = prove + (`!f:real^M->real^N s. + f absolutely_integrable_on s <=> + f measurable_on s /\ (\x. lift(norm(f x))) integrable_on s`, + REPEAT GEN_TAC THEN REWRITE_TAC[absolutely_integrable_on] THEN + MATCH_MP_TAC(TAUT `(a ==> b) /\ (b /\ c ==> a) ==> (a /\ c <=> b /\ c)`) THEN + REWRITE_TAC[INTEGRABLE_IMP_MEASURABLE] THEN STRIP_TAC THEN + MATCH_MP_TAC MEASURABLE_BOUNDED_BY_INTEGRABLE_IMP_INTEGRABLE THEN + EXISTS_TAC `\x. lift(norm((f:real^M->real^N) x))` THEN + ASM_REWRITE_TAC[LIFT_DROP; REAL_LE_REFL]);; + +(* ------------------------------------------------------------------------- *) +(* Composing continuous and measurable functions; a few variants. *) +(* ------------------------------------------------------------------------- *) + +let MEASURABLE_ON_COMPOSE_CONTINUOUS = prove + (`!f:real^M->real^N g:real^N->real^P. + f measurable_on (:real^M) /\ g continuous_on (:real^N) + ==> (g o f) measurable_on (:real^M)`, + REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN + REWRITE_TAC[measurable_on; IN_UNIV] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `k:real^M->bool` THEN + DISCH_THEN(X_CHOOSE_THEN `h:num->real^M->real^N` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `\n x. (g:real^N->real^P) ((h:num->real^M->real^N) n x)` THEN + ASM_REWRITE_TAC[] THEN CONJ_TAC THENL + [GEN_TAC THEN GEN_REWRITE_TAC LAND_CONV [GSYM o_DEF] THEN + MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN + ASM_REWRITE_TAC[ETA_AX] THEN + ASM_MESON_TAC[CONTINUOUS_ON_SUBSET; SUBSET_UNIV]; + X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I + [CONTINUOUS_ON_SEQUENTIALLY]) THEN + ASM_SIMP_TAC[o_DEF; IN_UNIV]]);; + +let MEASURABLE_ON_COMPOSE_CONTINUOUS_0 = prove + (`!f:real^M->real^N g:real^N->real^P s. + f measurable_on s /\ g continuous_on (:real^N) /\ g(vec 0) = vec 0 + ==> (g o f) measurable_on s`, + REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[GSYM MEASURABLE_ON_UNIV] THEN + ONCE_REWRITE_TAC[TAUT `a /\ b /\ c ==> d <=> c ==> a /\ b ==> d`] THEN + DISCH_TAC THEN + DISCH_THEN(MP_TAC o MATCH_MP MEASURABLE_ON_COMPOSE_CONTINUOUS) THEN + MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_TERM_TAC THEN + REWRITE_TAC[FUN_EQ_THM; o_DEF] THEN ASM_MESON_TAC[]);; + +let MEASURABLE_ON_COMPOSE_CONTINUOUS_OPEN_INTERVAL = prove + (`!f:real^M->real^N g:real^N->real^P a b. + f measurable_on (:real^M) /\ + (!x. f(x) IN interval(a,b)) /\ + g continuous_on interval(a,b) + ==> (g o f) measurable_on (:real^M)`, + REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN + REWRITE_TAC[measurable_on; IN_UNIV] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `k:real^M->bool` THEN + DISCH_THEN(X_CHOOSE_THEN `h:num->real^M->real^N` STRIP_ASSUME_TAC) THEN + EXISTS_TAC + `(\n x. (g:real^N->real^P) + (lambda i. max ((a:real^N)$i + (b$i - a$i) / (&n + &2)) + (min ((h n x:real^N)$i) + ((b:real^N)$i - (b$i - a$i) / (&n + &2))))) + :num->real^M->real^P` THEN + ASM_REWRITE_TAC[] THEN CONJ_TAC THENL + [X_GEN_TAC `n:num` THEN GEN_REWRITE_TAC LAND_CONV [GSYM o_DEF] THEN + MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN CONJ_TAC THENL + [MP_TAC(ISPECL + [`(:real^M)`; + `(lambda i. (b:real^N)$i - (b$i - (a:real^N)$i) / (&n + &2)):real^N`] + CONTINUOUS_ON_CONST) THEN + FIRST_X_ASSUM(MP_TAC o SPEC `n:num`) THEN + REWRITE_TAC[IMP_IMP] THEN + DISCH_THEN(MP_TAC o MATCH_MP CONTINUOUS_ON_MIN) THEN + MP_TAC(ISPECL + [`(:real^M)`; + `(lambda i. (a:real^N)$i + ((b:real^N)$i - a$i) / (&n + &2)):real^N`] + CONTINUOUS_ON_CONST) THEN + REWRITE_TAC[IMP_IMP] THEN + DISCH_THEN(MP_TAC o MATCH_MP CONTINUOUS_ON_MAX) THEN + MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_TERM_TAC THEN + SIMP_TAC[FUN_EQ_THM; CART_EQ; LAMBDA_BETA]; + MATCH_MP_TAC CONTINUOUS_ON_SUBSET THEN + EXISTS_TAC `interval(a:real^N,b)` THEN + ASM_REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; IN_UNIV] THEN + X_GEN_TAC `x:real^M` THEN + FIRST_X_ASSUM(MP_TAC o SPEC `x:real^M` o CONJUNCT1) THEN + SIMP_TAC[IN_INTERVAL; LAMBDA_BETA] THEN + MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `i:num` THEN + MATCH_MP_TAC MONO_IMP THEN REWRITE_TAC[] THEN DISCH_TAC THEN + SUBGOAL_THEN + `&0 < ((b:real^N)$i - (a:real^N)$i) / (&n + &2) /\ + ((b:real^N)$i - (a:real^N)$i) / (&n + &2) <= (b$i - a$i) / &2` MP_TAC + THENL [ALL_TAC; REAL_ARITH_TAC] THEN + ASM_SIMP_TAC[REAL_LT_RDIV_EQ; REAL_LT_LDIV_EQ; + REAL_ARITH `&0 < &n + &2`] THEN + CONJ_TAC THENL [ASM_REAL_ARITH_TAC; REWRITE_TAC[real_div]] THEN + MATCH_MP_TAC REAL_LE_LMUL THEN CONJ_TAC THENL + [ASM_REAL_ARITH_TAC; + MATCH_MP_TAC REAL_LE_INV2 THEN REAL_ARITH_TAC]]; + X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN + REWRITE_TAC[o_DEF] THEN MATCH_MP_TAC LIM_CONTINUOUS_FUNCTION THEN + CONJ_TAC THENL + [ASM_MESON_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_AT; OPEN_INTERVAL]; + ALL_TAC] THEN + SUBGOAL_THEN + `((\n. (lambda i. ((a:real^N)$i + ((b:real^N)$i - a$i) / (&n + &2)))) + --> a) sequentially /\ + ((\n. (lambda i. ((b:real^N)$i - ((b:real^N)$i - a$i) / (&n + &2)))) + --> b) sequentially` + MP_TAC THENL + [ONCE_REWRITE_TAC[LIM_COMPONENTWISE_LIFT] THEN + SIMP_TAC[LAMBDA_BETA] THEN + CONJ_TAC THEN X_GEN_TAC `j:num` THEN STRIP_TAC THEN + REWRITE_TAC[real_sub] THEN + GEN_REWRITE_TAC LAND_CONV [GSYM VECTOR_ADD_RID] THEN + REWRITE_TAC[LIFT_ADD] THEN MATCH_MP_TAC LIM_ADD THEN + REWRITE_TAC[LIM_CONST; LIFT_NEG; real_div; LIFT_CMUL] THEN + GEN_REWRITE_TAC LAND_CONV [GSYM VECTOR_NEG_0] THEN + TRY(MATCH_MP_TAC LIM_NEG) THEN REWRITE_TAC[VECTOR_NEG_0] THEN + SUBST1_TAC(VECTOR_ARITH + `vec 0:real^1 = ((b:real^N)$j + --((a:real^N)$j)) % vec 0`) THEN + MATCH_MP_TAC LIM_CMUL THEN + REWRITE_TAC[LIM_SEQUENTIALLY; DIST_0; NORM_LIFT] THEN + X_GEN_TAC `e:real` THEN + GEN_REWRITE_TAC LAND_CONV [REAL_ARCH_INV] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `N:num` THEN STRIP_TAC THEN + X_GEN_TAC `m:num` THEN DISCH_TAC THEN REWRITE_TAC[REAL_ABS_INV] THEN + MATCH_MP_TAC REAL_LET_TRANS THEN EXISTS_TAC `inv(&N)` THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC REAL_LE_INV2 THEN + ASM_SIMP_TAC[REAL_OF_NUM_ADD; REAL_OF_NUM_LT; LE_1; + REAL_OF_NUM_LE; REAL_ABS_NUM] THEN + ASM_ARITH_TAC; + ALL_TAC] THEN + FIRST_X_ASSUM(MP_TAC o SPEC `x:real^M`) THEN + ASM_REWRITE_TAC[TAUT `a ==> b /\ c ==> d <=> a /\ c ==> b ==> d`] THEN + DISCH_THEN(MP_TAC o MATCH_MP LIM_MIN) THEN + REWRITE_TAC[GSYM IMP_CONJ_ALT] THEN + DISCH_THEN(MP_TAC o MATCH_MP LIM_MAX) THEN + MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN BINOP_TAC THEN + SIMP_TAC[CART_EQ; LAMBDA_BETA; FUN_EQ_THM] THEN + RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL]) THEN + ASM_MESON_TAC[REAL_ARITH `a < x /\ x < b ==> max a (min x b) = x`]]);; + +let MEASURABLE_ON_COMPOSE_CONTINUOUS_CLOSED_SET = prove + (`!f:real^M->real^N g:real^N->real^P s. + closed s /\ + f measurable_on (:real^M) /\ + (!x. f(x) IN s) /\ + g continuous_on s + ==> (g o f) measurable_on (:real^M)`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`g:real^N->real^P`; `(:real^N)`; `s:real^N->bool`] + TIETZE_UNBOUNDED) THEN + ASM_REWRITE_TAC[SUBTOPOLOGY_UNIV; GSYM CLOSED_IN] THEN + ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN X_GEN_TAC `h:real^N->real^P` THEN + DISCH_TAC THEN SUBGOAL_THEN + `(g:real^N->real^P) o (f:real^M->real^N) = h o f` SUBST1_TAC + THENL [ASM_SIMP_TAC[FUN_EQ_THM; o_THM]; ALL_TAC] THEN + MATCH_MP_TAC MEASURABLE_ON_COMPOSE_CONTINUOUS THEN ASM_REWRITE_TAC[]);; + +let MEASURABLE_ON_COMPOSE_CONTINUOUS_CLOSED_SET_0 = prove + (`!f:real^M->real^N g:real^N->real^P s t. + closed s /\ + f measurable_on t /\ + (!x. f(x) IN s) /\ + g continuous_on s /\ + vec 0 IN s /\ g(vec 0) = vec 0 + ==> (g o f) measurable_on t`, + REPEAT STRIP_TAC THEN + ONCE_REWRITE_TAC[GSYM MEASURABLE_ON_UNIV] THEN + MP_TAC(ISPECL [`(\x. if x IN t then f x else vec 0):real^M->real^N`; + `g:real^N->real^P`; `s:real^N->bool`] + MEASURABLE_ON_COMPOSE_CONTINUOUS_CLOSED_SET) THEN + ANTS_TAC THENL + [ASM_REWRITE_TAC[MEASURABLE_ON_UNIV] THEN ASM_MESON_TAC[]; + MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_TERM_TAC THEN + REWRITE_TAC[FUN_EQ_THM; o_THM] THEN ASM_MESON_TAC[]]);; + +(* ------------------------------------------------------------------------- *) +(* Basic closure properties of measurable functions. *) +(* ------------------------------------------------------------------------- *) + +let CONTINUOUS_IMP_MEASURABLE_ON = prove + (`!f:real^M->real^N. f continuous_on (:real^M) ==> f measurable_on (:real^M)`, + REPEAT STRIP_TAC THEN REWRITE_TAC[measurable_on; IN_UNIV] THEN + EXISTS_TAC `{}:real^M->bool` THEN REWRITE_TAC[NEGLIGIBLE_EMPTY] THEN + EXISTS_TAC `\n:num. (f:real^M->real^N)` THEN + ASM_REWRITE_TAC[LIM_CONST]);; + +let MEASURABLE_ON_CONST = prove + (`!k:real^N. (\x. k) measurable_on (:real^M)`, + SIMP_TAC[CONTINUOUS_IMP_MEASURABLE_ON; CONTINUOUS_ON_CONST]);; + +let MEASURABLE_ON_0 = prove + (`!s. (\x. vec 0) measurable_on s`, + GEN_TAC THEN ONCE_REWRITE_TAC[GSYM MEASURABLE_ON_UNIV] THEN + REWRITE_TAC[MEASURABLE_ON_CONST; COND_ID]);; + +let MEASURABLE_ON_CMUL = prove + (`!c f:real^M->real^N s. + f measurable_on s ==> (\x. c % f x) measurable_on s`, + REPEAT STRIP_TAC THEN GEN_REWRITE_TAC LAND_CONV [GSYM o_DEF] THEN + MATCH_MP_TAC MEASURABLE_ON_COMPOSE_CONTINUOUS_0 THEN + ASM_REWRITE_TAC[VECTOR_MUL_RZERO] THEN + GEN_REWRITE_TAC LAND_CONV [GSYM ETA_AX] THEN + SIMP_TAC[CONTINUOUS_ON_CMUL; CONTINUOUS_ON_ID]);; + +let MEASURABLE_ON_NEG = prove + (`!f:real^M->real^N s. + f measurable_on s ==> (\x. --(f x)) measurable_on s`, + REWRITE_TAC[VECTOR_ARITH `--x:real^N = --(&1) % x`; + MEASURABLE_ON_CMUL]);; + +let MEASURABLE_ON_NEG_EQ = prove + (`!f:real^M->real^N s. (\x. --(f x)) measurable_on s <=> f measurable_on s`, + REPEAT GEN_TAC THEN EQ_TAC THEN + DISCH_THEN(MP_TAC o MATCH_MP MEASURABLE_ON_NEG) THEN + REWRITE_TAC[VECTOR_NEG_NEG; ETA_AX]);; + +let MEASURABLE_ON_NORM = prove + (`!f:real^M->real^N s. + f measurable_on s ==> (\x. lift(norm(f x))) measurable_on s`, + REPEAT GEN_TAC THEN + DISCH_THEN(MP_TAC o ISPEC `\x:real^N. lift(norm x)` o MATCH_MP + (REWRITE_RULE[IMP_CONJ] MEASURABLE_ON_COMPOSE_CONTINUOUS_0)) THEN + REWRITE_TAC[o_DEF; NORM_0; LIFT_NUM] THEN DISCH_THEN MATCH_MP_TAC THEN + REWRITE_TAC[continuous_on; IN_UNIV; DIST_LIFT] THEN + GEN_TAC THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN + EXISTS_TAC `e:real` THEN ASM_REWRITE_TAC[] THEN NORM_ARITH_TAC);; + +let MEASURABLE_ON_PASTECART = prove + (`!f:real^M->real^N g:real^M->real^P s. + f measurable_on s /\ g measurable_on s + ==> (\x. pastecart (f x) (g x)) measurable_on s`, + REPEAT GEN_TAC THEN REWRITE_TAC[measurable_on] THEN + DISCH_THEN(CONJUNCTS_THEN2 + (X_CHOOSE_THEN `k1:real^M->bool` MP_TAC) + (X_CHOOSE_THEN `k2:real^M->bool` MP_TAC)) THEN + DISCH_THEN(X_CHOOSE_THEN `g2:num->real^M->real^P` STRIP_ASSUME_TAC) THEN + DISCH_THEN(X_CHOOSE_THEN `g1:num->real^M->real^N` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `k1 UNION k2:real^M->bool` THEN + ASM_SIMP_TAC[NEGLIGIBLE_UNION] THEN + EXISTS_TAC `(\n x. pastecart (g1 n x) (g2 n x)) + :num->real^M->real^(N,P)finite_sum` THEN + ASM_SIMP_TAC[CONTINUOUS_ON_PASTECART; ETA_AX; IN_UNION; DE_MORGAN_THM] THEN + X_GEN_TAC `x:real^M` THEN STRIP_TAC THEN + REPEAT(FIRST_X_ASSUM(MP_TAC o SPEC `x:real^M`)) THEN + ASM_CASES_TAC `(x:real^M) IN s` THEN + REWRITE_TAC[GSYM PASTECART_VEC] THEN ASM_SIMP_TAC[LIM_PASTECART]);; + +let MEASURABLE_ON_COMBINE = prove + (`!h:real^N->real^P->real^Q f:real^M->real^N g:real^M->real^P s. + f measurable_on s /\ g measurable_on s /\ + (\x. h (fstcart x) (sndcart x)) continuous_on UNIV /\ + h (vec 0) (vec 0) = vec 0 + ==> (\x. h (f x) (g x)) measurable_on s`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN + `(\x:real^M. (h:real^N->real^P->real^Q) (f x) (g x)) = + (\x. h (fstcart x) (sndcart x)) o (\x. pastecart (f x) (g x))` + SUBST1_TAC THENL + [REWRITE_TAC[FUN_EQ_THM; FSTCART_PASTECART; SNDCART_PASTECART; o_THM]; + MATCH_MP_TAC MEASURABLE_ON_COMPOSE_CONTINUOUS_0 THEN + ASM_SIMP_TAC[MEASURABLE_ON_PASTECART; FSTCART_VEC; SNDCART_VEC]]);; + +let MEASURABLE_ON_ADD = prove + (`!f:real^M->real^N g:real^M->real^N s. + f measurable_on s /\ g measurable_on s + ==> (\x. f x + g x) measurable_on s`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC MEASURABLE_ON_COMBINE THEN + ASM_REWRITE_TAC[VECTOR_ADD_LID] THEN MATCH_MP_TAC CONTINUOUS_ON_ADD THEN + CONJ_TAC THEN MATCH_MP_TAC LINEAR_CONTINUOUS_ON THEN + REWRITE_TAC[LINEAR_FSTCART; LINEAR_SNDCART]);; + +let MEASURABLE_ON_SUB = prove + (`!f:real^M->real^N g:real^M->real^N s. + f measurable_on s /\ g measurable_on s + ==> (\x. f x - g x) measurable_on s`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC MEASURABLE_ON_COMBINE THEN + ASM_REWRITE_TAC[VECTOR_SUB_RZERO] THEN MATCH_MP_TAC CONTINUOUS_ON_SUB THEN + CONJ_TAC THEN MATCH_MP_TAC LINEAR_CONTINUOUS_ON THEN + REWRITE_TAC[LINEAR_FSTCART; LINEAR_SNDCART]);; + +let MEASURABLE_ON_MAX = prove + (`!f:real^M->real^N g:real^M->real^N s. + f measurable_on s /\ g measurable_on s + ==> (\x. (lambda i. max ((f x)$i) ((g x)$i)):real^N) + measurable_on s`, + let lemma = REWRITE_RULE[] + (ISPEC `(\x y. lambda i. max (x$i) (y$i)):real^N->real^N->real^N` + MEASURABLE_ON_COMBINE) in + REPEAT STRIP_TAC THEN MATCH_MP_TAC lemma THEN ASM_REWRITE_TAC[] THEN + ONCE_REWRITE_TAC[CONTINUOUS_ON_COMPONENTWISE_LIFT] THEN + REWRITE_TAC[REAL_ARITH `max x x = x`; LAMBDA_ETA] THEN + SIMP_TAC[continuous_on; LAMBDA_BETA; IN_UNIV; DIST_LIFT] THEN + GEN_TAC THEN STRIP_TAC THEN + MAP_EVERY X_GEN_TAC [`x:real^(N,N)finite_sum`; `e:real`] THEN + DISCH_TAC THEN EXISTS_TAC `e:real` THEN ASM_REWRITE_TAC[dist] THEN + X_GEN_TAC `y:real^(N,N)finite_sum` THEN DISCH_TAC THEN + MATCH_MP_TAC(REAL_ARITH + `abs(x - y) < e /\ abs(x' - y') < e + ==> abs(max x x' - max y y') < e`) THEN + REWRITE_TAC[GSYM VECTOR_SUB_COMPONENT] THEN CONJ_TAC THEN + MATCH_MP_TAC(REAL_ARITH + `norm(x) < e /\ abs(x$i) <= norm x ==> abs(x$i) < e`) THEN + ASM_SIMP_TAC[COMPONENT_LE_NORM; GSYM FSTCART_SUB; GSYM SNDCART_SUB] THEN + ASM_MESON_TAC[REAL_LET_TRANS; NORM_FSTCART; NORM_SNDCART]);; + +let MEASURABLE_ON_MIN = prove + (`!f:real^M->real^N g:real^M->real^N s. + f measurable_on s /\ g measurable_on s + ==> (\x. (lambda i. min ((f x)$i) ((g x)$i)):real^N) + measurable_on s`, + REPEAT GEN_TAC THEN + DISCH_THEN(CONJUNCTS_THEN(MP_TAC o MATCH_MP MEASURABLE_ON_NEG)) THEN + REWRITE_TAC[GSYM IMP_CONJ_ALT] THEN + DISCH_THEN(MP_TAC o MATCH_MP MEASURABLE_ON_MAX) THEN + DISCH_THEN(MP_TAC o MATCH_MP MEASURABLE_ON_NEG) THEN + MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_TERM_TAC THEN + REWRITE_TAC[FUN_EQ_THM] THEN + SIMP_TAC[CART_EQ; VECTOR_NEG_COMPONENT; LAMBDA_BETA] THEN REAL_ARITH_TAC);; + +let MEASURABLE_ON_DROP_MUL = prove + (`!f g:real^M->real^N s. + f measurable_on s /\ g measurable_on s + ==> (\x. drop(f x) % g x) measurable_on s`, + let lemma = REWRITE_RULE[] + (ISPEC `\x y. drop x % y :real^N` MEASURABLE_ON_COMBINE) in + REPEAT STRIP_TAC THEN MATCH_MP_TAC lemma THEN + ASM_REWRITE_TAC[VECTOR_MUL_RZERO] THEN MATCH_MP_TAC CONTINUOUS_ON_MUL THEN + REWRITE_TAC[o_DEF; ETA_AX; LIFT_DROP] THEN + CONJ_TAC THEN MATCH_MP_TAC LINEAR_CONTINUOUS_ON THEN + REWRITE_TAC[LINEAR_FSTCART; LINEAR_SNDCART]);; + +let MEASURABLE_ON_LIFT_MUL = prove + (`!f g s. (\x. lift(f x)) measurable_on s /\ + (\x. lift(g x)) measurable_on s + ==> (\x. lift(f x * g x)) measurable_on s`, + REPEAT GEN_TAC THEN + DISCH_THEN(MP_TAC o MATCH_MP MEASURABLE_ON_DROP_MUL) THEN + REWRITE_TAC[LIFT_CMUL; LIFT_DROP]);; + +let MEASURABLE_ON_VSUM = prove + (`!f:A->real^M->real^N t. + FINITE t /\ (!i. i IN t ==> (f i) measurable_on s) + ==> (\x. vsum t (\i. f i x)) measurable_on s`, + GEN_TAC THEN REWRITE_TAC[IMP_CONJ] THEN + MATCH_MP_TAC FINITE_INDUCT_STRONG THEN + SIMP_TAC[VSUM_CLAUSES; MEASURABLE_ON_0; MEASURABLE_ON_ADD; IN_INSERT; + ETA_AX]);; + +let MEASURABLE_ON_COMPONENTWISE = prove + (`!f:real^M->real^N. + f measurable_on (:real^M) <=> + (!i. 1 <= i /\ i <= dimindex(:N) + ==> (\x. lift(f x$i)) measurable_on (:real^M))`, + REPEAT GEN_TAC THEN EQ_TAC THENL + [REPEAT STRIP_TAC THEN FIRST_ASSUM(MP_TAC o + ISPEC `\x:real^N. lift(x$i)` o MATCH_MP + (REWRITE_RULE[IMP_CONJ] MEASURABLE_ON_COMPOSE_CONTINUOUS)) THEN + ASM_SIMP_TAC[CONTINUOUS_ON_LIFT_COMPONENT; o_DEF]; + ALL_TAC] THEN + REWRITE_TAC[measurable_on; IN_UNIV] THEN + GEN_REWRITE_TAC (LAND_CONV o TOP_DEPTH_CONV) [RIGHT_IMP_EXISTS_THM] THEN + REWRITE_TAC[SKOLEM_THM; LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC + [`k:num->real^M->bool`; `g:num->num->real^M->real^1`] THEN + DISCH_TAC THEN + EXISTS_TAC `UNIONS(IMAGE k (1..dimindex(:N))):real^M->bool` THEN + EXISTS_TAC `(\n x. lambda i. drop(g i n x)):num->real^M->real^N` THEN + REWRITE_TAC[] THEN REPEAT CONJ_TAC THENL + [MATCH_MP_TAC NEGLIGIBLE_UNIONS THEN + ASM_SIMP_TAC[FINITE_NUMSEG; IN_NUMSEG; FORALL_IN_IMAGE; FINITE_IMAGE]; + GEN_TAC THEN ONCE_REWRITE_TAC[CONTINUOUS_ON_COMPONENTWISE_LIFT] THEN + ASM_SIMP_TAC[LAMBDA_BETA; LIFT_DROP; ETA_AX]; + X_GEN_TAC `x:real^M` THEN REWRITE_TAC[IN_UNIONS; EXISTS_IN_IMAGE] THEN + REWRITE_TAC[NOT_EXISTS_THM; TAUT `~(a /\ b) <=> a ==> ~b`] THEN + REWRITE_TAC[IN_NUMSEG] THEN STRIP_TAC THEN + ONCE_REWRITE_TAC[LIM_COMPONENTWISE_LIFT] THEN + ASM_SIMP_TAC[LAMBDA_BETA; LIFT_DROP; ETA_AX]]);; + +let MEASURABLE_ON_SPIKE = prove + (`!f:real^M->real^N g s t. + negligible s /\ (!x. x IN t DIFF s ==> g x = f x) + ==> f measurable_on t ==> g measurable_on t`, + REPEAT GEN_TAC THEN REWRITE_TAC[IN_DIFF] THEN STRIP_TAC THEN + REWRITE_TAC[measurable_on] THEN ONCE_REWRITE_TAC[SWAP_EXISTS_THM] THEN + MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC THEN + DISCH_THEN(X_CHOOSE_THEN `k:real^M->bool` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `s UNION k:real^M->bool` THEN + ASM_SIMP_TAC[DE_MORGAN_THM; IN_UNION; NEGLIGIBLE_UNION]);; + +let MEASURABLE_ON_SPIKE_SET = prove + (`!f:real^M->real^N s t. + negligible (s DIFF t UNION t DIFF s) + ==> f measurable_on s + ==> f measurable_on t`, + REPEAT GEN_TAC THEN DISCH_TAC THEN REWRITE_TAC[measurable_on] THEN + ONCE_REWRITE_TAC[SWAP_EXISTS_THM] THEN MATCH_MP_TAC MONO_EXISTS THEN + X_GEN_TAC `g:num->real^M->real^N` THEN + DISCH_THEN(X_CHOOSE_THEN `k:real^M->bool` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `k UNION (s DIFF t UNION t DIFF s):real^M->bool` THEN + ASM_SIMP_TAC[NEGLIGIBLE_UNION; IN_UNION; DE_MORGAN_THM] THEN + X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `x:real^M`) THEN + MAP_EVERY ASM_CASES_TAC [`(x:real^M) IN s`; `(x:real^M) IN t`] THEN + ASM_REWRITE_TAC[] THEN ASM SET_TAC[]);; + +let MEASURABLE_ON_RESTRICT = prove + (`!f:real^M->real^N s. + f measurable_on (:real^M) /\ lebesgue_measurable s + ==> (\x. if x IN s then f(x) else vec 0) measurable_on (:real^M)`, + REPEAT GEN_TAC THEN REWRITE_TAC[lebesgue_measurable; indicator] THEN + ONCE_REWRITE_TAC[CONJ_SYM] THEN + DISCH_THEN(MP_TAC o MATCH_MP MEASURABLE_ON_DROP_MUL) THEN + MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_TERM_TAC THEN + REWRITE_TAC[FUN_EQ_THM] THEN GEN_TAC THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[DROP_VEC] THEN VECTOR_ARITH_TAC);; + +let MEASURABLE_ON_LEBESGUE_MEASURABLE_SUBSET = prove + (`!f s t. s SUBSET t /\ f measurable_on t /\ + lebesgue_measurable s + ==> f measurable_on s`, + REPEAT GEN_TAC THEN + ONCE_REWRITE_TAC[GSYM MEASURABLE_ON_UNIV] THEN + REWRITE_TAC[IN_UNIV] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + DISCH_THEN(MP_TAC o MATCH_MP MEASURABLE_ON_RESTRICT) THEN + MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_TERM_TAC THEN + REWRITE_TAC[FUN_EQ_THM] THEN ASM SET_TAC[]);; + +let MEASURABLE_ON_LIMIT = prove + (`!f:num->real^M->real^N g s k. + (!n. (f n) measurable_on s) /\ + negligible k /\ + (!x. x IN s DIFF k ==> ((\n. f n x) --> g x) sequentially) + ==> g measurable_on s`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`vec 0:real^N`; `vec 1:real^N`] + HOMEOMORPHIC_OPEN_INTERVAL_UNIV) THEN + REWRITE_TAC[INTERVAL_NE_EMPTY; VEC_COMPONENT; REAL_LT_01] THEN + REWRITE_TAC[homeomorphic; homeomorphism; LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`h':real^N->real^N`; `h:real^N->real^N`] THEN + REWRITE_TAC[IN_UNIV] THEN STRIP_TAC THEN + SUBGOAL_THEN + `((h':real^N->real^N) o (h:real^N->real^N) o + (\x. if x IN s then g x else vec 0)) measurable_on (:real^M)` + MP_TAC THENL + [ALL_TAC; ASM_REWRITE_TAC[o_DEF; MEASURABLE_ON_UNIV]] THEN + SUBGOAL_THEN `!y:real^N. norm(h y:real^N) <= &(dimindex(:N))` + ASSUME_TAC THENL + [FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE + `IMAGE h UNIV = s ==> (!z. z IN s ==> P z) ==> !y. P(h y)`)) THEN + X_GEN_TAC `y:real^N` THEN REWRITE_TAC[IN_INTERVAL] THEN + REWRITE_TAC[VEC_COMPONENT] THEN DISCH_TAC THEN + MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `sum(1..dimindex(:N)) (\i. abs((y:real^N)$i))` THEN + REWRITE_TAC[NORM_LE_L1] THEN + GEN_REWRITE_TAC (RAND_CONV o RAND_CONV) [GSYM CARD_NUMSEG_1] THEN + GEN_REWRITE_TAC RAND_CONV [GSYM REAL_MUL_RID] THEN + MATCH_MP_TAC SUM_BOUND THEN REWRITE_TAC[FINITE_NUMSEG; IN_NUMSEG] THEN + ASM_SIMP_TAC[REAL_ARITH `&0 < x /\ x < &1 ==> abs(x) <= &1`]; + ALL_TAC] THEN + MATCH_MP_TAC MEASURABLE_ON_COMPOSE_CONTINUOUS_OPEN_INTERVAL THEN + MAP_EVERY EXISTS_TAC [`vec 0:real^N`; `vec 1:real^N`] THEN + ASM_REWRITE_TAC[] THEN CONJ_TAC THENL + [MATCH_MP_TAC INTEGRABLE_SUBINTERVALS_IMP_MEASURABLE THEN + MAP_EVERY X_GEN_TAC [`a:real^M`; `b:real^M`] THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_IMP] INTEGRABLE_SPIKE_SET) THEN + EXISTS_TAC `interval[a:real^M,b] DIFF k` THEN CONJ_TAC THENL + [MATCH_MP_TAC NEGLIGIBLE_SUBSET THEN EXISTS_TAC `k:real^M->bool` THEN + ASM_REWRITE_TAC[] THEN SET_TAC[]; + ALL_TAC] THEN + MATCH_MP_TAC DOMINATED_CONVERGENCE_INTEGRABLE THEN + MAP_EVERY EXISTS_TAC + [`(\n x. h(if x IN s then f n x else vec 0:real^N)):num->real^M->real^N`; + `(\x. vec(dimindex(:N))):real^M->real^1`] THEN + REWRITE_TAC[o_DEF; INTEGRABLE_CONST] THEN REPEAT CONJ_TAC THENL + [X_GEN_TAC `n:num` THEN MATCH_MP_TAC + MEASURABLE_BOUNDED_BY_INTEGRABLE_IMP_ABSOLUTELY_INTEGRABLE THEN + EXISTS_TAC `(\x. vec(dimindex(:N))):real^M->real^1` THEN + ASM_REWRITE_TAC[ETA_AX; INTEGRABLE_CONST] THEN + ASM_SIMP_TAC[DROP_VEC] THEN CONJ_TAC THENL + [MATCH_MP_TAC(REWRITE_RULE[IMP_IMP] MEASURABLE_ON_SPIKE_SET) THEN + EXISTS_TAC `interval[a:real^M,b:real^M]` THEN CONJ_TAC THENL + [MATCH_MP_TAC NEGLIGIBLE_SUBSET THEN EXISTS_TAC `k:real^M->bool` THEN + ASM_REWRITE_TAC[] THEN SET_TAC[]; + ALL_TAC] THEN + ONCE_REWRITE_TAC[GSYM MEASURABLE_ON_UNIV] THEN + MATCH_MP_TAC(REWRITE_RULE[indicator; lebesgue_measurable] + MEASURABLE_ON_RESTRICT) THEN + REWRITE_TAC[MEASURABLE_ON_UNIV] THEN CONJ_TAC THENL + [MP_TAC(ISPECL + [`(\x. if x IN s then f (n:num) x else vec 0):real^M->real^N`; + `h:real^N->real^N`] MEASURABLE_ON_COMPOSE_CONTINUOUS) THEN + ASM_REWRITE_TAC[o_DEF] THEN DISCH_THEN MATCH_MP_TAC THEN + ASM_REWRITE_TAC[MEASURABLE_ON_UNIV; ETA_AX]; + MATCH_MP_TAC INTEGRABLE_IMP_MEASURABLE THEN + REWRITE_TAC[INTEGRABLE_CONST]]; + MATCH_MP_TAC(REWRITE_RULE[IMP_IMP] INTEGRABLE_SPIKE_SET) THEN + EXISTS_TAC `interval[a:real^M,b:real^M]` THEN + REWRITE_TAC[INTEGRABLE_CONST] THEN MATCH_MP_TAC NEGLIGIBLE_SUBSET THEN + EXISTS_TAC `k:real^M->bool` THEN ASM_REWRITE_TAC[] THEN SET_TAC[]]; + MATCH_MP_TAC(REWRITE_RULE[IMP_IMP] INTEGRABLE_SPIKE_SET) THEN + EXISTS_TAC `interval[a:real^M,b:real^M]` THEN + REWRITE_TAC[INTEGRABLE_CONST] THEN MATCH_MP_TAC NEGLIGIBLE_SUBSET THEN + EXISTS_TAC `k:real^M->bool` THEN ASM_REWRITE_TAC[] THEN SET_TAC[]; + ASM_SIMP_TAC[DROP_VEC]; + X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN + ASM_CASES_TAC `(x:real^M) IN s` THEN ASM_REWRITE_TAC[LIM_CONST] THEN + MATCH_MP_TAC LIM_CONTINUOUS_FUNCTION THEN CONJ_TAC THENL + [ASM_MESON_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_AT; OPEN_UNIV; IN_UNIV]; + FIRST_X_ASSUM MATCH_MP_TAC THEN ASM SET_TAC[]]]; + REWRITE_TAC[o_THM] THEN ASM SET_TAC[]]);; + +(* ------------------------------------------------------------------------- *) +(* Natural closure properties of measurable functions; the intersection *) +(* one is actually quite tedious since we end up reinventing cube roots *) +(* before they actually get introduced in transcendentals.ml *) +(* ------------------------------------------------------------------------- *) + +let MEASURABLE_ON_EMPTY = prove + (`!f:real^M->real^N. f measurable_on {}`, + ONCE_REWRITE_TAC[GSYM MEASURABLE_ON_UNIV] THEN + REWRITE_TAC[NOT_IN_EMPTY; MEASURABLE_ON_CONST]);; + +let MEASURABLE_ON_INTER = prove + (`!f:real^M->real^N s t. + f measurable_on s /\ f measurable_on t + ==> f measurable_on (s INTER t)`, + REPEAT GEN_TAC THEN + ONCE_REWRITE_TAC[GSYM MEASURABLE_ON_UNIV] THEN + ONCE_REWRITE_TAC[MEASURABLE_ON_COMPONENTWISE] THEN + REWRITE_TAC[AND_FORALL_THM] THEN + MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `i:num` THEN + DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN + ASM_REWRITE_TAC[] THEN + ONCE_REWRITE_TAC[TAUT `p /\ q ==> r <=> p /\ p ==> q ==> r`] THEN + DISCH_THEN(MP_TAC o MATCH_MP MEASURABLE_ON_LIFT_MUL) THEN + REWRITE_TAC[IMP_IMP] THEN + DISCH_THEN(MP_TAC o MATCH_MP MEASURABLE_ON_LIFT_MUL) THEN + ONCE_REWRITE_TAC[COND_RAND] THEN ONCE_REWRITE_TAC[COND_RATOR] THEN + REWRITE_TAC[VEC_COMPONENT; REAL_ARITH + `(if p then x else &0) * (if q then y else &0) = + if p /\ q then x * y else &0`] THEN + SUBGOAL_THEN `!s. (\x. lift (drop x pow 3)) continuous_on s` ASSUME_TAC THENL + [GEN_TAC THEN REWRITE_TAC[REAL_ARITH `(x:real) pow 3 = x * x * x`] THEN + REWRITE_TAC[LIFT_CMUL] THEN + REPEAT(MATCH_MP_TAC CONTINUOUS_ON_MUL THEN + ASM_REWRITE_TAC[o_DEF; LIFT_DROP; CONTINUOUS_ON_ID]); + ALL_TAC] THEN + SUBGOAL_THEN `?r. !x. lift(drop(r x) pow 3) = x` STRIP_ASSUME_TAC THENL + [REWRITE_TAC[GSYM SKOLEM_THM; FORALL_LIFT; GSYM EXISTS_DROP; LIFT_EQ] THEN + X_GEN_TAC `x:real` THEN MP_TAC(ISPECL + [`\x. lift (drop x pow 3)`; `lift(--(abs x + &1))`; + `lift(abs x + &1)`;`x:real`; `1`] IVT_INCREASING_COMPONENT_1) THEN + REWRITE_TAC[GSYM drop; LIFT_DROP; EXISTS_DROP] THEN + ANTS_TAC THENL [ALL_TAC; MESON_TAC[]] THEN + REWRITE_TAC[DIMINDEX_1; LE_REFL] THEN + CONJ_TAC THENL [REAL_ARITH_TAC; ALL_TAC] THEN CONJ_TAC THENL + [FIRST_X_ASSUM(MP_TAC o SPEC `(:real^1)`) THEN + ASM_SIMP_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_AT; OPEN_UNIV; IN_UNIV]; + REWRITE_TAC[REAL_BOUNDS_LE; REAL_POW_NEG; ARITH] THEN + MATCH_MP_TAC(REAL_ARITH + `&0 <= x /\ &0 <= x pow 2 /\ &0 <= x pow 3 ==> x <= (x + &1) pow 3`) THEN + SIMP_TAC[REAL_POW_LE; REAL_ABS_POS]]; + ALL_TAC] THEN + SUBGOAL_THEN `!x. r(lift(x pow 3)) = lift x` STRIP_ASSUME_TAC THENL + [REWRITE_TAC[GSYM DROP_EQ; LIFT_DROP] THEN GEN_TAC THEN + MATCH_MP_TAC REAL_POW_EQ_ODD THEN EXISTS_TAC `3` THEN + ASM_REWRITE_TAC[ARITH; GSYM LIFT_EQ; LIFT_DROP]; + ALL_TAC] THEN + SUBGOAL_THEN `(r:real^1->real^1) continuous_on (:real^1)` ASSUME_TAC THENL + [MATCH_MP_TAC CONTINUOUS_ON_INVERSE_OPEN_MAP THEN + MAP_EVERY EXISTS_TAC [`\x. lift(drop x pow 3)`; `(:real^1)`] THEN + ASM_REWRITE_TAC[LIFT_DROP] THEN + MATCH_MP_TAC(TAUT `p /\ (p ==> q) ==> p /\ q`) THEN CONJ_TAC THENL + [ASM SET_TAC[]; ALL_TAC] THEN + DISCH_THEN(fun th -> REPEAT STRIP_TAC THEN SUBST1_TAC(SYM th)) THEN + MATCH_MP_TAC INJECTIVE_INTO_1D_IMP_OPEN_MAP THEN + ASM_REWRITE_TAC[PATH_CONNECTED_UNIV; LIFT_EQ] THEN + SIMP_TAC[REAL_POW_EQ_ODD_EQ; ARITH; DROP_EQ]; + ONCE_REWRITE_TAC[REAL_ARITH `&0 = &0 pow 3`] THEN + REWRITE_TAC[REAL_ARITH `(x * x) * x:real = x pow 3`; IN_INTER] THEN + REWRITE_TAC[MESON[] `(if p then x pow 3 else y pow 3) = + (if p then x else y:real) pow 3`] THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN + DISCH_THEN(MP_TAC o ISPEC `r:real^1->real^1` o + MATCH_MP (REWRITE_RULE[IMP_CONJ] MEASURABLE_ON_COMPOSE_CONTINUOUS)) THEN + ASM_REWRITE_TAC[o_DEF]]);; + +let MEASURABLE_ON_DIFF = prove + (`!f:real^M->real^N s t. + f measurable_on s /\ f measurable_on t ==> f measurable_on (s DIFF t)`, + REPEAT GEN_TAC THEN DISCH_TAC THEN + FIRST_ASSUM(MP_TAC o MATCH_MP MEASURABLE_ON_INTER) THEN + FIRST_ASSUM(MP_TAC o CONJUNCT1) THEN REWRITE_TAC[IMP_IMP] THEN + ONCE_REWRITE_TAC[GSYM MEASURABLE_ON_UNIV] THEN + DISCH_THEN(MP_TAC o MATCH_MP MEASURABLE_ON_SUB) THEN + MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_TERM_TAC THEN + REWRITE_TAC[FUN_EQ_THM; IN_DIFF; IN_INTER] THEN + X_GEN_TAC `x:real^M` THEN + MAP_EVERY ASM_CASES_TAC [`(x:real^M) IN s`; `(x:real^M) IN t`] THEN + ASM_REWRITE_TAC[] THEN VECTOR_ARITH_TAC);; + +let MEASURABLE_ON_UNION = prove + (`!f:real^M->real^N s t. + f measurable_on s /\ f measurable_on t ==> f measurable_on (s UNION t)`, + REPEAT GEN_TAC THEN DISCH_TAC THEN + FIRST_ASSUM(MP_TAC o MATCH_MP MEASURABLE_ON_INTER) THEN + POP_ASSUM MP_TAC THEN ONCE_REWRITE_TAC[GSYM MEASURABLE_ON_UNIV] THEN + DISCH_THEN(MP_TAC o MATCH_MP MEASURABLE_ON_ADD) THEN + REWRITE_TAC[IMP_IMP] THEN + DISCH_THEN(MP_TAC o MATCH_MP MEASURABLE_ON_SUB) THEN + MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_TERM_TAC THEN + REWRITE_TAC[FUN_EQ_THM; IN_UNION; IN_INTER] THEN + X_GEN_TAC `x:real^M` THEN + MAP_EVERY ASM_CASES_TAC [`(x:real^M) IN s`; `(x:real^M) IN t`] THEN + ASM_REWRITE_TAC[] THEN VECTOR_ARITH_TAC);; + +let MEASURABLE_ON_UNIONS = prove + (`!f:real^M->real^N k. + FINITE k /\ (!s. s IN k ==> f measurable_on s) + ==> f measurable_on (UNIONS k)`, + GEN_TAC THEN REWRITE_TAC[IMP_CONJ] THEN + MATCH_MP_TAC FINITE_INDUCT_STRONG THEN + REWRITE_TAC[UNIONS_0; MEASURABLE_ON_EMPTY; UNIONS_INSERT] THEN + SIMP_TAC[FORALL_IN_INSERT; MEASURABLE_ON_UNION]);; + +let MEASURABLE_ON_COUNTABLE_UNIONS = prove + (`!f:real^M->real^N k. + COUNTABLE k /\ (!s. s IN k ==> f measurable_on s) + ==> f measurable_on (UNIONS k)`, + REPEAT STRIP_TAC THEN + ASM_CASES_TAC `k:(real^M->bool)->bool = {}` THEN + ASM_REWRITE_TAC[UNIONS_0; MEASURABLE_ON_EMPTY] THEN + MP_TAC(ISPEC `k:(real^M->bool)->bool` COUNTABLE_AS_IMAGE) THEN + ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `d:num->real^M->bool` THEN DISCH_THEN SUBST_ALL_TAC THEN + ONCE_REWRITE_TAC[GSYM MEASURABLE_ON_UNIV] THEN + MATCH_MP_TAC MEASURABLE_ON_LIMIT THEN + EXISTS_TAC `(\n x. if x IN UNIONS (IMAGE d (0..n)) then f x else vec 0): + num->real^M->real^N` THEN + EXISTS_TAC `{}:real^M->bool` THEN + ASM_REWRITE_TAC[NEGLIGIBLE_EMPTY; MEASURABLE_ON_UNIV] THEN CONJ_TAC THENL + [X_GEN_TAC `n:num` THEN MATCH_MP_TAC MEASURABLE_ON_UNIONS THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [FORALL_IN_IMAGE]) THEN + SIMP_TAC[FORALL_IN_IMAGE; IN_UNIV; FINITE_IMAGE; FINITE_NUMSEG]; + X_GEN_TAC `x:real^M` THEN DISCH_THEN(K ALL_TAC) THEN + ASM_CASES_TAC `(x:real^M) IN UNIONS (IMAGE d (:num))` THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC LIM_EVENTUALLY THENL + [FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_UNIONS]) THEN + REWRITE_TAC[EXISTS_IN_IMAGE; IN_UNIV; EVENTUALLY_SEQUENTIALLY] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `N:num` THEN DISCH_TAC THEN + X_GEN_TAC `n:num` THEN DISCH_TAC THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE RAND_CONV [IN_UNIONS]) THEN + ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN DISCH_TAC THEN + REWRITE_TAC[EXISTS_IN_IMAGE; IN_NUMSEG; LE_0] THEN ASM_MESON_TAC[]; + MATCH_MP_TAC ALWAYS_EVENTUALLY THEN ASM SET_TAC[]]]);; + +(* ------------------------------------------------------------------------- *) +(* Negligibility of a Lipschitz image of a negligible set. *) +(* ------------------------------------------------------------------------- *) + +let NEGLIGIBLE_LOCALLY_LIPSCHITZ_IMAGE = prove + (`!f:real^M->real^N s. + dimindex(:M) <= dimindex(:N) /\ negligible s /\ + (!x. x IN s + ==> ?t b. open t /\ x IN t /\ + !y. y IN s INTER t + ==> norm(f y - f x) <= b * norm(y - x)) + ==> negligible(IMAGE f s)`, + let lemma = prove + (`!f:real^M->real^N s B. + dimindex(:M) <= dimindex(:N) /\ bounded s /\ negligible s /\ &0 < B /\ + (!x. x IN s + ==> ?t. open t /\ x IN t /\ + !y. y IN s INTER t + ==> norm(f y - f x) <= B * norm(y - x)) + ==> negligible(IMAGE f s)`, + REPEAT STRIP_TAC THEN REWRITE_TAC[NEGLIGIBLE_OUTER] THEN + X_GEN_TAC `e:real` THEN DISCH_TAC THEN + MP_TAC(ISPECL [`s:real^M->bool`; + `e / &2 / (&2 * B * &(dimindex(:M))) pow (dimindex(:N))`] + MEASURABLE_OUTER_OPEN) THEN + ANTS_TAC THENL + [ASM_SIMP_TAC[NEGLIGIBLE_IMP_MEASURABLE] THEN + MATCH_MP_TAC REAL_LT_DIV THEN ASM_REWRITE_TAC[REAL_HALF] THEN + MATCH_MP_TAC REAL_POW_LT THEN + REPEAT(MATCH_MP_TAC REAL_LT_MUL THEN CONJ_TAC) THEN + ASM_SIMP_TAC[DIMINDEX_GE_1; REAL_OF_NUM_LT; ARITH; LE_1]; + ALL_TAC] THEN + ASM_SIMP_TAC[NEGLIGIBLE_IMP_MEASURABLE; REAL_HALF; MEASURE_EQ_0] THEN + REWRITE_TAC[REAL_ADD_LID] THEN + DISCH_THEN(X_CHOOSE_THEN `t:real^M->bool` STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN + `!x. ?r. &0 < r /\ r <= &1 / &2 /\ + (x IN s + ==> !y. norm(y - x:real^M) < r + ==> y IN t /\ + (y IN s + ==> norm(f y - f x:real^N) <= B * norm(y - x)))` + MP_TAC THENL + [X_GEN_TAC `x:real^M` THEN ASM_CASES_TAC `(x:real^M) IN s` THEN + ASM_REWRITE_TAC[] THENL + [ALL_TAC; EXISTS_TAC `&1 / &4` THEN REAL_ARITH_TAC] THEN + FIRST_X_ASSUM(MP_TAC o SPEC `x:real^M`) THEN + ASM_REWRITE_TAC[IN_INTER] THEN + DISCH_THEN(X_CHOOSE_THEN `u:real^M->bool` STRIP_ASSUME_TAC) THEN + MP_TAC(ISPEC `t INTER u :real^M->bool` open_def) THEN + ASM_SIMP_TAC[OPEN_INTER; OPEN_BALL] THEN + DISCH_THEN(MP_TAC o SPEC `x:real^M`) THEN + ANTS_TAC THENL [ASM SET_TAC[]; REWRITE_TAC[IN_INTER; dist]] THEN + DISCH_THEN(X_CHOOSE_THEN `r:real` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `min (&1 / &2) r` THEN + ASM_REWRITE_TAC[REAL_MIN_LE; REAL_LT_MIN] THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN ASM_MESON_TAC[]; + FIRST_X_ASSUM(K ALL_TAC o check (is_forall o concl)) THEN + REWRITE_TAC[SKOLEM_THM; LEFT_IMP_EXISTS_THM; FORALL_AND_THM] THEN + REWRITE_TAC[RIGHT_IMP_FORALL_THM; IMP_IMP] THEN + X_GEN_TAC `r:real^M->real` THEN STRIP_TAC] THEN + SUBGOAL_THEN + `?c. s SUBSET interval[--(vec c):real^M,vec c] /\ + ~(interval(--(vec c):real^M,vec c) = {})` + STRIP_ASSUME_TAC THENL + [FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [bounded]) THEN + DISCH_THEN(X_CHOOSE_THEN `c:real` STRIP_ASSUME_TAC) THEN + MP_TAC(SPEC `abs c + &1` REAL_ARCH_SIMPLE) THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `n:num` THEN + DISCH_TAC THEN REWRITE_TAC[SUBSET; INTERVAL_NE_EMPTY] THEN + REWRITE_TAC[IN_INTERVAL; VEC_COMPONENT; VECTOR_NEG_COMPONENT] THEN + CONJ_TAC THENL [ALL_TAC; ASM_REAL_ARITH_TAC] THEN + X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN X_GEN_TAC `i:num` THEN + STRIP_TAC THEN REWRITE_TAC[REAL_BOUNDS_LE] THEN W(MP_TAC o + PART_MATCH (lhand o rand) COMPONENT_LE_NORM o lhand o snd) THEN + REPEAT(FIRST_X_ASSUM(MP_TAC o SPEC `x:real^M`)) THEN + ASM_REWRITE_TAC[] THEN ASM_REAL_ARITH_TAC; + ALL_TAC] THEN + MP_TAC(ISPECL [`--(vec c):real^M`; `(vec c):real^M`; `s:real^M->bool`; + `\x:real^M. ball(x,r x)`] COVERING_LEMMA) THEN + ASM_REWRITE_TAC[gauge; OPEN_BALL; CENTRE_IN_BALL] THEN + + REWRITE_TAC[VEC_COMPONENT; VECTOR_NEG_COMPONENT] THEN + DISCH_THEN(X_CHOOSE_THEN `D:(real^M->bool)->bool` STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN + `!k. k IN D + ==> ?u v z. k = interval[u,v] /\ ~(interval(u,v) = {}) /\ + z IN s /\ z IN interval[u,v] /\ + interval[u:real^M,v] SUBSET ball(z,r z)` + MP_TAC THENL + [X_GEN_TAC `d:real^M->bool` THEN DISCH_TAC THEN + SUBGOAL_THEN `?u v:real^M. d = interval[u,v]` MP_TAC THENL + [ASM_MESON_TAC[]; ALL_TAC] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `u:real^M` THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `v:real^M` THEN + DISCH_THEN SUBST_ALL_TAC THEN + ASM_MESON_TAC[SUBSET; INTERIOR_CLOSED_INTERVAL; IN_INTER]; + ALL_TAC] THEN + GEN_REWRITE_TAC (LAND_CONV o TOP_DEPTH_CONV) [RIGHT_IMP_EXISTS_THM] THEN + REWRITE_TAC[SKOLEM_THM; LEFT_IMP_EXISTS_THM] THEN MAP_EVERY X_GEN_TAC + [`u:(real^M->bool)->real^M`; `v:(real^M->bool)->real^M`; + `z:(real^M->bool)->real^M`] THEN + DISCH_THEN(LABEL_TAC "*") THEN EXISTS_TAC + `UNIONS(IMAGE (\d:real^M->bool. + interval[(f:real^M->real^N)(z d) - + (B * &(dimindex(:M)) * + ((v(d):real^M)$1 - (u(d):real^M)$1)) % vec 1:real^N, + f(z d) + + (B * &(dimindex(:M)) * (v(d)$1 - u(d)$1)) % vec 1]) D)` THEN + CONJ_TAC THENL + [REWRITE_TAC[SUBSET; FORALL_IN_IMAGE] THEN + X_GEN_TAC `y:real^M` THEN DISCH_TAC THEN + SUBGOAL_THEN `(y:real^M) IN UNIONS D` MP_TAC THENL + [ASM_MESON_TAC[SUBSET]; REWRITE_TAC[UNIONS_IMAGE]] THEN + REWRITE_TAC[IN_UNIONS; IN_ELIM_THM] THEN MATCH_MP_TAC MONO_EXISTS THEN + X_GEN_TAC `d:real^M->bool` THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + SUBGOAL_THEN `(y:real^M) IN ball(z(d:real^M->bool),r(z d))` MP_TAC THENL + [ASM_MESON_TAC[SUBSET]; REWRITE_TAC[IN_BALL; dist]] THEN + ONCE_REWRITE_TAC[NORM_SUB] THEN DISCH_TAC THEN + SUBGOAL_THEN + `y IN t /\ + norm((f:real^M->real^N) y - f(z d)) <= B * norm(y - z(d:real^M->bool))` + STRIP_ASSUME_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN + REWRITE_TAC[IN_INTERVAL] THEN X_GEN_TAC `i:num` THEN STRIP_TAC THEN + REWRITE_TAC[VECTOR_ADD_COMPONENT; VECTOR_SUB_COMPONENT] THEN + REWRITE_TAC[REAL_ARITH + `z - b <= y /\ y <= z + b <=> abs(y - z) <= b`] THEN + REWRITE_TAC[GSYM VECTOR_SUB_COMPONENT] THEN W(MP_TAC o + PART_MATCH (lhand o rand) COMPONENT_LE_NORM o lhand o snd) THEN + ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] REAL_LE_TRANS) THEN + REWRITE_TAC[VECTOR_MUL_COMPONENT; VEC_COMPONENT; REAL_MUL_RID] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + REAL_LE_TRANS)) THEN + ASM_SIMP_TAC[REAL_LE_LMUL_EQ] THEN + W(MP_TAC o PART_MATCH lhand NORM_LE_L1 o lhand o snd) THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] REAL_LE_TRANS) THEN + GEN_REWRITE_TAC (RAND_CONV o LAND_CONV o RAND_CONV) + [GSYM CARD_NUMSEG_1] THEN + SIMP_TAC[GSYM SUM_CONST; FINITE_NUMSEG] THEN + MATCH_MP_TAC SUM_LE_NUMSEG THEN X_GEN_TAC `j:num` THEN STRIP_TAC THEN + MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `((v:(real^M->bool)->real^M) d - u d)$j` THEN + REWRITE_TAC[VECTOR_SUB_COMPONENT] THEN CONJ_TAC THENL + [SUBGOAL_THEN `y IN interval[(u:(real^M->bool)->real^M) d,v d] /\ + (z d) IN interval[u d,v d]` + MP_TAC THENL [ASM_MESON_TAC[]; REWRITE_TAC[IN_INTERVAL]] THEN + DISCH_THEN(CONJUNCTS_THEN (MP_TAC o SPEC `j:num`)) THEN + ASM_REWRITE_TAC[] THEN REAL_ARITH_TAC; + MATCH_MP_TAC REAL_EQ_IMP_LE THEN FIRST_X_ASSUM(MP_TAC o SPECL + [`(u:(real^M->bool)->real^M) d`; `(v:(real^M->bool)->real^M) d`]) THEN + ASM_MESON_TAC[DIMINDEX_GE_1; LE_REFL]]; + ALL_TAC] THEN + MATCH_MP_TAC(MESON[] + `(x <= e / &2 ==> x < e) /\ P /\ x <= e / &2 ==> P /\ x < e`) THEN + CONJ_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN + MATCH_MP_TAC MEASURE_COUNTABLE_UNIONS_LE_GEN THEN + ASM_SIMP_TAC[COUNTABLE_IMAGE; FORALL_IN_IMAGE; MEASURABLE_INTERVAL] THEN + ONCE_REWRITE_TAC[CONJ_SYM] THEN + REWRITE_TAC[FORALL_FINITE_SUBSET_IMAGE] THEN + X_GEN_TAC `D':(real^M->bool)->bool` THEN STRIP_TAC THEN + W(MP_TAC o PART_MATCH (lhand o rand) SUM_IMAGE_LE o lhand o snd) THEN + ASM_SIMP_TAC[MEASURE_POS_LE; MEASURABLE_INTERVAL] THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] REAL_LE_TRANS) THEN + REWRITE_TAC[o_DEF] THEN + MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `(&2 * B * &(dimindex(:M))) pow (dimindex(:N)) * + sum D' (\d:real^M->bool. measure d)` THEN + SUBGOAL_THEN `FINITE(D':(real^M->bool)->bool)` ASSUME_TAC THENL + [ASM_MESON_TAC[FINITE_SUBSET]; ALL_TAC] THEN + CONJ_TAC THENL + [REWRITE_TAC[GSYM SUM_LMUL] THEN MATCH_MP_TAC SUM_LE THEN + ASM_REWRITE_TAC[MEASURE_INTERVAL] THEN X_GEN_TAC `d:real^M->bool` THEN + DISCH_TAC THEN REWRITE_TAC[CONTENT_CLOSED_INTERVAL_CASES] THEN + REWRITE_TAC[VECTOR_ADD_COMPONENT; VECTOR_SUB_COMPONENT; REAL_ARITH + `(a - x <= a + x <=> &0 <= x) /\ (a + x) - (a - x) = &2 * x`] THEN + REWRITE_TAC[VECTOR_MUL_COMPONENT; VEC_COMPONENT; REAL_MUL_RID] THEN + ASM_SIMP_TAC[REAL_LE_MUL_EQ; REAL_OF_NUM_LT; LE_1; DIMINDEX_GE_1] THEN + SUBGOAL_THEN `d = interval[u d:real^M,v d]` + (fun th -> GEN_REWRITE_TAC (RAND_CONV o ONCE_DEPTH_CONV) [th]) + THENL [ASM_MESON_TAC[SUBSET]; ALL_TAC] THEN + REWRITE_TAC[MEASURE_INTERVAL; CONTENT_CLOSED_INTERVAL_CASES] THEN + SUBGOAL_THEN + `!i. 1 <= i /\ i <= dimindex(:M) + ==> ((u:(real^M->bool)->real^M) d)$i <= (v d:real^M)$i` + MP_TAC THENL + [ASM_MESON_TAC[SUBSET; INTERVAL_NE_EMPTY; REAL_LT_IMP_LE]; ALL_TAC] THEN + SIMP_TAC[REAL_SUB_LE; DIMINDEX_GE_1; LE_REFL] THEN DISCH_TAC THEN + REWRITE_TAC[PRODUCT_CONST_NUMSEG; REAL_POW_MUL] THEN + ASM_SIMP_TAC[REAL_LE_LMUL_EQ; REAL_POW_LT; REAL_OF_NUM_LT; ARITH; + GSYM REAL_MUL_ASSOC; ADD_SUB; DIMINDEX_GE_1; LE_1] THEN + MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `((v d:real^M)$1 - ((u:(real^M->bool)->real^M) d)$1) + pow (dimindex(:M))` THEN + CONJ_TAC THENL + [MATCH_MP_TAC REAL_POW_MONO_INV THEN + ASM_SIMP_TAC[REAL_SUB_LE; DIMINDEX_GE_1; LE_REFL] THEN + REWRITE_TAC[GSYM VECTOR_SUB_COMPONENT] THEN + MATCH_MP_TAC(REAL_ARITH `abs x <= a ==> x <= a`) THEN W(MP_TAC o + PART_MATCH (lhand o rand) COMPONENT_LE_NORM o lhand o snd) THEN + REWRITE_TAC[DIMINDEX_GE_1; LE_REFL] THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] REAL_LE_TRANS) THEN + MATCH_MP_TAC(NORM_ARITH + `!z r. norm(z - u) < r /\ norm(z - v) < r /\ r <= &1 / &2 + ==> norm(v - u:real^M) <= &1`) THEN + MAP_EVERY EXISTS_TAC + [`(z:(real^M->bool)->real^M) d`; + `r((z:(real^M->bool)->real^M) d):real`] THEN + ASM_REWRITE_TAC[GSYM dist; GSYM IN_BALL] THEN + SUBGOAL_THEN + `(u:(real^M->bool)->real^M) d IN interval[u d,v d] /\ + (v:(real^M->bool)->real^M) d IN interval[u d,v d]` + MP_TAC THENL [ALL_TAC; ASM_MESON_TAC[SUBSET]] THEN + ASM_REWRITE_TAC[ENDS_IN_INTERVAL; INTERVAL_NE_EMPTY]; + GEN_REWRITE_TAC (LAND_CONV o RAND_CONV) [GSYM CARD_NUMSEG_1] THEN + SIMP_TAC[GSYM PRODUCT_CONST; FINITE_NUMSEG] THEN + MATCH_MP_TAC REAL_EQ_IMP_LE THEN MATCH_MP_TAC PRODUCT_EQ_NUMSEG THEN + FIRST_X_ASSUM(MP_TAC o SPECL + [`(u:(real^M->bool)->real^M) d`; `(v:(real^M->bool)->real^M) d`]) THEN + ASM_MESON_TAC[DIMINDEX_GE_1; LE_REFL; SUBSET]]; + MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `(&2 * B * &(dimindex(:M))) pow dimindex(:N) * + measure(t:real^M->bool)` THEN + CONJ_TAC THENL + [MATCH_MP_TAC REAL_LE_LMUL THEN + CONJ_TAC THENL [MATCH_MP_TAC REAL_LT_IMP_LE; ALL_TAC]; + MATCH_MP_TAC REAL_LT_IMP_LE THEN ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN + W(MP_TAC o PART_MATCH (rand o rand) REAL_LT_RDIV_EQ o snd)] THEN + ASM_SIMP_TAC[REAL_POW_LT; REAL_LT_MUL; LE_1; DIMINDEX_GE_1; + REAL_ARITH `&0 < &2 * B <=> &0 < B`; REAL_OF_NUM_LT] THEN + MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `measure(UNIONS D':real^M->bool)` THEN CONJ_TAC THENL + [MP_TAC(ISPECL [`D':(real^M->bool)->bool`; `UNIONS D':real^M->bool`] + MEASURE_ELEMENTARY) THEN + ANTS_TAC THENL + [ASM_REWRITE_TAC[division_of] THEN + CONJ_TAC THENL [ALL_TAC; ASM_MESON_TAC[SUBSET]] THEN + GEN_TAC THEN DISCH_TAC THEN CONJ_TAC THENL + [ASM SET_TAC[]; ASM_MESON_TAC[SUBSET; INTERIOR_EMPTY]]; + DISCH_THEN SUBST1_TAC THEN MATCH_MP_TAC REAL_EQ_IMP_LE THEN + MATCH_MP_TAC SUM_EQ THEN ASM_MESON_TAC[MEASURE_INTERVAL; SUBSET]]; + MATCH_MP_TAC MEASURE_SUBSET THEN CONJ_TAC THENL + [MATCH_MP_TAC MEASURABLE_UNIONS THEN + ASM_MESON_TAC[MEASURABLE_INTERVAL; SUBSET]; + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC SUBSET_TRANS THEN + EXISTS_TAC `UNIONS D:real^M->bool` THEN + ASM_SIMP_TAC[SUBSET_UNIONS] THEN + REWRITE_TAC[SUBSET; FORALL_IN_UNIONS] THEN + X_GEN_TAC `d:real^M->bool` THEN + REWRITE_TAC[RIGHT_FORALL_IMP_THM; IMP_CONJ] THEN + DISCH_TAC THEN REWRITE_TAC[GSYM SUBSET] THEN + SUBGOAL_THEN `d SUBSET ball(z d:real^M,r(z d))` MP_TAC THENL + [ASM_MESON_TAC[]; + REWRITE_TAC[SUBSET; IN_BALL; dist] THEN + ASM_MESON_TAC[NORM_SUB]]]]]) in + REPEAT STRIP_TAC THEN + SUBGOAL_THEN + `s = UNIONS + {{x | x IN s /\ norm(x:real^M) <= &n /\ + ?t. open t /\ x IN t /\ + !y. y IN s INTER t + ==> norm(f y - f x:real^N) <= (&n + &1) * norm(y - x)} | + n IN (:num)}` + SUBST1_TAC THENL + [REWRITE_TAC[EXTENSION; UNIONS_GSPEC; IN_ELIM_THM; IN_UNIV] THEN + X_GEN_TAC `x:real^M` THEN + ASM_CASES_TAC `(x:real^M) IN s` THEN ASM_REWRITE_TAC[] THEN + FIRST_X_ASSUM(MP_TAC o SPEC `x:real^M`) THEN ASM_REWRITE_TAC[] THEN + ONCE_REWRITE_TAC[SWAP_EXISTS_THM] THEN + REWRITE_TAC[RIGHT_AND_EXISTS_THM] THEN + ONCE_REWRITE_TAC[SWAP_EXISTS_THM] THEN MATCH_MP_TAC MONO_EXISTS THEN + X_GEN_TAC `t:real^M->bool` THEN + DISCH_THEN(X_CHOOSE_THEN `b:real` STRIP_ASSUME_TAC) THEN + MP_TAC(SPEC `max (norm(x:real^M)) b` REAL_ARCH_SIMPLE) THEN + MATCH_MP_TAC MONO_EXISTS THEN REWRITE_TAC[REAL_MAX_LE] THEN + X_GEN_TAC `n:num` THEN REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `b * norm(y - x:real^M)` THEN ASM_SIMP_TAC[] THEN + MATCH_MP_TAC REAL_LE_RMUL THEN REWRITE_TAC[NORM_POS_LE] THEN + ASM_REAL_ARITH_TAC; + REWRITE_TAC[IMAGE_UNIONS] THEN + MATCH_MP_TAC NEGLIGIBLE_COUNTABLE_UNIONS_GEN THEN + REWRITE_TAC[FORALL_IN_IMAGE; FORALL_IN_GSPEC] THEN + ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN + ASM_SIMP_TAC[GSYM IMAGE_o; COUNTABLE_IMAGE; NUM_COUNTABLE] THEN + X_GEN_TAC `n:num` THEN REWRITE_TAC[IN_UNIV] THEN + MATCH_MP_TAC lemma THEN EXISTS_TAC `&n + &1` THEN ASM_REWRITE_TAC[] THEN + REPEAT CONJ_TAC THENL + [MATCH_MP_TAC BOUNDED_SUBSET THEN + EXISTS_TAC `cball(vec 0:real^M,&n)` THEN + SIMP_TAC[BOUNDED_CBALL; SUBSET; IN_CBALL_0; IN_ELIM_THM]; + MATCH_MP_TAC NEGLIGIBLE_SUBSET THEN EXISTS_TAC `s:real^M->bool` THEN + ASM_REWRITE_TAC[] THEN SET_TAC[]; + REAL_ARITH_TAC; + REWRITE_TAC[IN_ELIM_THM; IN_INTER] THEN MESON_TAC[]]]);; + +let NEGLIGIBLE_LIPSCHITZ_IMAGE_UNIV = prove + (`!f:real^N->real^N s B. + negligible s /\ (!x y. norm(f x - f y) <= B * norm(x - y)) + ==> negligible(IMAGE f s)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC NEGLIGIBLE_LOCALLY_LIPSCHITZ_IMAGE THEN + ASM_REWRITE_TAC[LE_REFL] THEN X_GEN_TAC `a:real^N` THEN DISCH_TAC THEN + MAP_EVERY EXISTS_TAC [`interval(a - vec 1:real^N,a + vec 1)`; `B:real`] THEN + ASM_REWRITE_TAC[OPEN_INTERVAL; IN_INTERVAL] THEN + REWRITE_TAC[VECTOR_SUB_COMPONENT; VECTOR_ADD_COMPONENT; VEC_COMPONENT] THEN + REAL_ARITH_TAC);; + +let NEGLIGIBLE_DIFFERENTIABLE_IMAGE_NEGLIGIBLE = prove + (`!f:real^M->real^N s. + dimindex(:M) <= dimindex(:N) /\ negligible s /\ f differentiable_on s + ==> negligible(IMAGE f s)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC NEGLIGIBLE_LOCALLY_LIPSCHITZ_IMAGE THEN + ASM_REWRITE_TAC[IN_INTER] THEN + X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [differentiable_on]) THEN + DISCH_THEN(MP_TAC o SPEC `x:real^M`) THEN + ASM_REWRITE_TAC[differentiable; HAS_DERIVATIVE_WITHIN_ALT] THEN + DISCH_THEN(X_CHOOSE_THEN `f':real^M->real^N` STRIP_ASSUME_TAC) THEN + FIRST_X_ASSUM(MP_TAC o SPEC `&1`) THEN + REWRITE_TAC[REAL_LT_01; REAL_MUL_RID] THEN + DISCH_THEN(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC) THEN + FIRST_X_ASSUM(MP_TAC o MATCH_MP LINEAR_BOUNDED_POS) THEN + DISCH_THEN(X_CHOOSE_THEN `B:real` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `ball(x:real^M,d)` THEN EXISTS_TAC `B + &1` THEN + ASM_REWRITE_TAC[OPEN_BALL; CENTRE_IN_BALL] THEN + REWRITE_TAC[IN_BALL; dist; REAL_ADD_RDISTRIB] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC(NORM_ARITH + `!d. norm(y - x - d:real^N) <= z /\ norm(d) <= b + ==> norm(y - x) <= b + z`) THEN + EXISTS_TAC `(f':real^M->real^N)(y - x)` THEN + ASM_MESON_TAC[NORM_SUB]);; + +let NEGLIGIBLE_DIFFERENTIABLE_IMAGE_LOWDIM = prove + (`!f:real^M->real^N s. + dimindex(:M) < dimindex(:N) /\ f differentiable_on s + ==> negligible(IMAGE f s)`, + REPEAT STRIP_TAC THEN FIRST_ASSUM(ASSUME_TAC o MATCH_MP + (ARITH_RULE `m < n ==> !x:num. x <= m ==> x <= n`)) THEN + SUBGOAL_THEN + `(f:real^M->real^N) = + (f o ((\x. lambda i. x$i):real^N->real^M)) o + ((\x. lambda i. if i <= dimindex(:M) then x$i else &0):real^M->real^N)` + SUBST1_TAC THENL + [SIMP_TAC[FUN_EQ_THM; o_THM] THEN GEN_TAC THEN AP_TERM_TAC THEN + ASM_SIMP_TAC[CART_EQ; LAMBDA_BETA]; + ONCE_REWRITE_TAC[IMAGE_o] THEN + MATCH_MP_TAC NEGLIGIBLE_DIFFERENTIABLE_IMAGE_NEGLIGIBLE THEN + REWRITE_TAC[LE_REFL] THEN CONJ_TAC THENL + [MATCH_MP_TAC NEGLIGIBLE_SUBSET THEN + EXISTS_TAC `{y:real^N | y$(dimindex(:N)) = &0}` THEN + SIMP_TAC[NEGLIGIBLE_STANDARD_HYPERPLANE; LE_REFL; DIMINDEX_GE_1] THEN + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; IN_ELIM_THM] THEN + SIMP_TAC[LAMBDA_BETA; LE_REFL; DIMINDEX_GE_1] THEN + ASM_REWRITE_TAC[GSYM NOT_LT]; + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [differentiable_on]) THEN + REWRITE_TAC[differentiable_on; FORALL_IN_IMAGE] THEN STRIP_TAC THEN + X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN + MATCH_MP_TAC DIFFERENTIABLE_CHAIN_WITHIN THEN CONJ_TAC THENL + [MATCH_MP_TAC DIFFERENTIABLE_LINEAR THEN + SIMP_TAC[linear; LAMBDA_BETA; CART_EQ; + VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT]; + FIRST_X_ASSUM(MP_TAC o SPEC `x:real^M`) THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN BINOP_TAC THENL + [AP_TERM_TAC; + MATCH_MP_TAC(SET_RULE + `(!x. f(g x) = x) ==> s = IMAGE f (IMAGE g s)`)] THEN + ASM_SIMP_TAC[CART_EQ; LAMBDA_BETA]]]]);; + +(* ------------------------------------------------------------------------- *) +(* Simplest case of Sard's theorem (we don't need continuity of derivative). *) +(* ------------------------------------------------------------------------- *) + +let BABY_SARD = prove + (`!f:real^M->real^N f' s. + dimindex(:M) <= dimindex(:N) /\ + (!x. x IN s + ==> (f has_derivative f' x) (at x within s) /\ + rank(matrix(f' x)) < dimindex(:N)) + ==> negligible(IMAGE f s)`, + let lemma = prove + (`!p w e m. + dim p < dimindex(:N) /\ &0 <= m /\ &0 <= e + ==> ?s. measurable s /\ + {z:real^N | norm(z - w) <= m /\ + ?t. t IN p /\ norm(z - w - t) <= e} + SUBSET s /\ + measure s <= (&2 * e) * (&2 * m) pow (dimindex(:N) - 1)`, + REPEAT GEN_TAC THEN GEN_GEOM_ORIGIN_TAC `w:real^N` ["t"; "p"] THEN + REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[IMP_CONJ] THEN + DISCH_THEN(MP_TAC o MATCH_MP LOWDIM_SUBSET_HYPERPLANE) THEN + REWRITE_TAC[VECTOR_SUB_RZERO; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `a:real^N` THEN GEOM_BASIS_MULTIPLE_TAC 1 `a:real^N` THEN + X_GEN_TAC `a:real` THEN GEN_REWRITE_TAC LAND_CONV [REAL_LE_LT] THEN + ASM_CASES_TAC `a = &0` THEN ASM_REWRITE_TAC[VECTOR_MUL_LZERO] THEN + REPEAT STRIP_TAC THEN + EXISTS_TAC + `interval[--(lambda i. if i = 1 then e else m):real^N, + (lambda i. if i = 1 then e else m)]` THEN + REWRITE_TAC[MEASURABLE_INTERVAL] THEN CONJ_TAC THENL + [REWRITE_TAC[SUBSET; IN_ELIM_THM; IN_INTERVAL] THEN + SIMP_TAC[VECTOR_NEG_COMPONENT; LAMBDA_BETA] THEN + X_GEN_TAC `x:real^N` THEN DISCH_THEN(CONJUNCTS_THEN ASSUME_TAC) THEN + REWRITE_TAC[REAL_BOUNDS_LE] THEN X_GEN_TAC `i:num` THEN STRIP_TAC THEN + COND_CASES_TAC THENL + [ALL_TAC; ASM_MESON_TAC[COMPONENT_LE_NORM; REAL_LE_TRANS]] THEN + FIRST_X_ASSUM(X_CHOOSE_THEN `y:real^N` STRIP_ASSUME_TAC) THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [SUBSET]) THEN + DISCH_THEN(MP_TAC o SPEC `y:real^N`) THEN + ASM_SIMP_TAC[SPAN_SUPERSET; IN_ELIM_THM; DOT_BASIS; DOT_LMUL; + DIMINDEX_GE_1; LE_REFL; REAL_ENTIRE; REAL_LT_IMP_NZ] THEN + MP_TAC(ISPECL [`x - y:real^N`; `1`] COMPONENT_LE_NORM) THEN + REWRITE_TAC[VECTOR_SUB_COMPONENT; ARITH; DIMINDEX_GE_1] THEN + ASM_REAL_ARITH_TAC; + REWRITE_TAC[MEASURE_INTERVAL; CONTENT_CLOSED_INTERVAL_CASES] THEN + SIMP_TAC[VECTOR_NEG_COMPONENT; LAMBDA_BETA] THEN + COND_CASES_TAC THEN ASM_SIMP_TAC[REAL_LE_MUL; REAL_POW_LE; REAL_POS] THEN + REWRITE_TAC[REAL_ARITH `x - --x = &2 * x`] THEN + SIMP_TAC[PRODUCT_CLAUSES_LEFT; DIMINDEX_GE_1] THEN + MATCH_MP_TAC REAL_LE_LMUL THEN ASM_SIMP_TAC[REAL_LE_MUL; REAL_POS] THEN + SIMP_TAC[ARITH; ARITH_RULE `2 <= n ==> ~(n = 1)`] THEN + SIMP_TAC[PRODUCT_CONST_NUMSEG; DIMINDEX_GE_1; REAL_LE_REFL; ARITH_RULE + `1 <= n ==> (n + 1) - 2 = n - 1`]]) in + let semma = prove + (`!f:real^M->real^N f' s B. + dimindex(:M) <= dimindex(:N) /\ &0 < B /\ bounded s /\ + (!x. x IN s ==> (f has_derivative f' x) (at x within s) /\ + rank(matrix(f' x)) < dimindex(:N) /\ onorm(f' x) <= B) + ==> negligible(IMAGE f s)`, + REWRITE_TAC[TAUT `p ==> q /\ r <=> (p ==> q) /\ (p ==> r)`] THEN + REWRITE_TAC[FORALL_AND_THM] THEN REPEAT STRIP_TAC THEN + SUBGOAL_THEN `!x. x IN s ==> linear((f':real^M->real^M->real^N) x)` + ASSUME_TAC THENL [ASM_MESON_TAC[has_derivative]; ALL_TAC] THEN + REPEAT STRIP_TAC THEN REWRITE_TAC[NEGLIGIBLE_OUTER_LE] THEN + X_GEN_TAC `e:real` THEN DISCH_TAC THEN + SUBGOAL_THEN + `?c. s SUBSET interval(--(vec c):real^M,vec c) /\ + ~(interval(--(vec c):real^M,vec c) = {})` + STRIP_ASSUME_TAC THENL + [FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [bounded]) THEN + DISCH_THEN(X_CHOOSE_THEN `c:real` STRIP_ASSUME_TAC) THEN + MP_TAC(SPEC `abs c + &1` REAL_ARCH_SIMPLE) THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `n:num` THEN + DISCH_TAC THEN REWRITE_TAC[SUBSET; INTERVAL_NE_EMPTY] THEN + REWRITE_TAC[IN_INTERVAL; VEC_COMPONENT; VECTOR_NEG_COMPONENT] THEN + CONJ_TAC THENL [ALL_TAC; ASM_REAL_ARITH_TAC] THEN + X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN X_GEN_TAC `i:num` THEN + STRIP_TAC THEN REWRITE_TAC[REAL_BOUNDS_LT] THEN W(MP_TAC o + PART_MATCH (lhand o rand) COMPONENT_LE_NORM o lhand o snd) THEN + REPEAT(FIRST_X_ASSUM(MP_TAC o SPEC `x:real^M`)) THEN + ASM_REWRITE_TAC[] THEN ASM_REAL_ARITH_TAC; + ALL_TAC] THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [INTERVAL_NE_EMPTY]) THEN + DISCH_THEN(MP_TAC o SPEC `1`) THEN + REWRITE_TAC[VEC_COMPONENT; DIMINDEX_GE_1; + LE_REFL; VECTOR_NEG_COMPONENT] THEN + REWRITE_TAC[REAL_ARITH `--x < x <=> &0 < &2 * x`; REAL_OF_NUM_MUL] THEN + DISCH_TAC THEN + SUBGOAL_THEN + `?d. &0 < d /\ d <= B /\ + (d * &2) * (&4 * B) pow (dimindex(:N) - 1) <= + e / &(2 * c) pow dimindex(:M) / &(dimindex(:M)) pow dimindex(:M)` + STRIP_ASSUME_TAC THENL + [EXISTS_TAC + `min B (e / &(2 * c) pow dimindex(:M) / + &(dimindex(:M)) pow dimindex(:M) / + (&4 * B) pow (dimindex(:N) - 1) / &2)` THEN + ASM_REWRITE_TAC[REAL_LT_MIN; REAL_ARITH `min x y <= x`] THEN + CONJ_TAC THENL + [REPEAT(MATCH_MP_TAC REAL_LT_DIV THEN CONJ_TAC) THEN + ASM_SIMP_TAC[REAL_POW_LT; REAL_OF_NUM_LT; DIMINDEX_GE_1; LE_1; + REAL_ARITH `&0 < &4 * B <=> &0 < B`; ARITH]; + ASM_SIMP_TAC[GSYM REAL_LE_RDIV_EQ; REAL_POW_LT; + REAL_ARITH `&0 < &4 * B <=> &0 < B`; ARITH] THEN + REAL_ARITH_TAC]; + ALL_TAC] THEN + SUBGOAL_THEN + `!x. ?r. &0 < r /\ r <= &1 / &2 /\ + (x IN s + ==> !y. y IN s /\ norm(y - x) < r + ==> norm((f:real^M->real^N) y - f x - f' x (y - x)) <= + d * norm(y - x))` + MP_TAC THENL + [X_GEN_TAC `x:real^M` THEN ASM_CASES_TAC `(x:real^M) IN s` THEN + ASM_REWRITE_TAC[] THENL + [ALL_TAC; EXISTS_TAC `&1 / &4` THEN REAL_ARITH_TAC] THEN + UNDISCH_THEN + `!x. x IN s ==> ((f:real^M->real^N) has_derivative f' x) (at x within s)` + (MP_TAC o REWRITE_RULE[HAS_DERIVATIVE_WITHIN_ALT]) THEN + ASM_SIMP_TAC[RIGHT_IMP_FORALL_THM] THEN + DISCH_THEN(MP_TAC o SPECL [`x:real^M`; `d:real`]) THEN + ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `r:real` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `min r (&1 / &2)` THEN + ASM_REWRITE_TAC[REAL_LT_MIN; REAL_MIN_LE; REAL_LE_REFL] THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN ASM_MESON_TAC[]; + REWRITE_TAC[SKOLEM_THM; LEFT_IMP_EXISTS_THM; FORALL_AND_THM] THEN + X_GEN_TAC `r:real^M->real` THEN REWRITE_TAC[RIGHT_IMP_FORALL_THM] THEN + REWRITE_TAC[IMP_IMP; GSYM CONJ_ASSOC] THEN + REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + DISCH_THEN(LABEL_TAC "*")] THEN + MP_TAC(ISPECL [`--(vec c):real^M`; `(vec c):real^M`; `s:real^M->bool`; + `\x:real^M. ball(x,r x)`] COVERING_LEMMA) THEN + ASM_REWRITE_TAC[gauge; OPEN_BALL; CENTRE_IN_BALL] THEN ANTS_TAC THENL + [ASM_MESON_TAC[SUBSET_TRANS; INTERVAL_OPEN_SUBSET_CLOSED]; ALL_TAC] THEN + REWRITE_TAC[VEC_COMPONENT; VECTOR_NEG_COMPONENT] THEN + DISCH_THEN(X_CHOOSE_THEN `D:(real^M->bool)->bool` STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN + `!k:real^M->bool. + k IN D + ==> ?t. measurable(t) /\ + IMAGE (f:real^M->real^N) (k INTER s) SUBSET t /\ + measure t <= e / &(2 * c) pow (dimindex(:M)) * measure(k)` + MP_TAC THENL + [X_GEN_TAC `k:real^M->bool` THEN DISCH_TAC THEN + SUBGOAL_THEN `?u v:real^M. k = interval[u,v]` + (REPEAT_TCL CHOOSE_THEN SUBST_ALL_TAC) + THENL [ASM_MESON_TAC[]; ALL_TAC] THEN + SUBGOAL_THEN `?x:real^M. x IN (s INTER interval[u,v]) /\ + interval[u,v] SUBSET ball(x,r x)` + MP_TAC THENL [ASM_MESON_TAC[]; REWRITE_TAC[IN_INTER]] THEN + DISCH_THEN(X_CHOOSE_THEN `x:real^M` STRIP_ASSUME_TAC) THEN + MP_TAC(ISPECL [`IMAGE ((f':real^M->real^M->real^N) x) (:real^M)`; + `(f:real^M->real^N) x`; + `d * norm(v - u:real^M)`; + `(&2 * B) * norm(v - u:real^M)`] + lemma) THEN + ANTS_TAC THENL + [ASM_SIMP_TAC[REAL_LE_MUL; REAL_POS; NORM_POS_LE; REAL_LT_IMP_LE] THEN + MP_TAC(ISPEC `matrix ((f':real^M->real^M->real^N) x)` + RANK_DIM_IM) THEN + ASM_SIMP_TAC[MATRIX_WORKS] THEN REWRITE_TAC[ETA_AX] THEN + ASM_MESON_TAC[]; + ALL_TAC] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `t:real^N->bool` THEN + REPEAT(MATCH_MP_TAC MONO_AND THEN REWRITE_TAC[]) THEN CONJ_TAC THENL + [MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] SUBSET_TRANS) THEN + REWRITE_TAC[FORALL_IN_IMAGE; SUBSET; IN_ELIM_THM] THEN + X_GEN_TAC `y:real^M` THEN + REWRITE_TAC[IN_INTER; EXISTS_IN_IMAGE; IN_UNIV] THEN + STRIP_TAC THEN REMOVE_THEN "*" + (MP_TAC o SPECL [`x:real^M`; `y:real^M`]) THEN + ANTS_TAC THENL + [ASM_MESON_TAC[IN_BALL; SUBSET; NORM_SUB; dist]; ALL_TAC] THEN + DISCH_THEN(fun th -> CONJ_TAC THEN MP_TAC th) THENL + [REWRITE_TAC[GSYM REAL_MUL_ASSOC] THEN MATCH_MP_TAC(NORM_ARITH + `norm(z) <= B /\ d <= B + ==> norm(y - x - z:real^N) <= d + ==> norm(y - x) <= &2 * B`) THEN + CONJ_TAC THENL + [MP_TAC(ISPEC `(f':real^M->real^M->real^N) x` ONORM) THEN + ASM_SIMP_TAC[] THEN + DISCH_THEN(MP_TAC o SPEC `y - x:real^M` o CONJUNCT1) THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] REAL_LE_TRANS) THEN + MATCH_MP_TAC REAL_LE_MUL2 THEN + ASM_SIMP_TAC[ONORM_POS_LE; NORM_POS_LE]; + MATCH_MP_TAC REAL_LE_MUL2 THEN + ASM_SIMP_TAC[REAL_LT_IMP_LE; NORM_POS_LE]]; + DISCH_THEN(fun th -> EXISTS_TAC `y - x:real^M` THEN MP_TAC th) THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] REAL_LE_TRANS) THEN + ASM_SIMP_TAC[REAL_LE_LMUL_EQ]] THEN + MATCH_MP_TAC NORM_LE_COMPONENTWISE THEN + REPEAT(FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_INTERVAL])) THEN + REWRITE_TAC[IMP_IMP; AND_FORALL_THM] THEN + MATCH_MP_TAC MONO_FORALL THEN GEN_TAC THEN + DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN + ASM_REWRITE_TAC[VECTOR_SUB_COMPONENT] THEN REAL_ARITH_TAC; + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] REAL_LE_TRANS) THEN + REWRITE_TAC[REAL_ARITH `&2 * (&2 * B) * n = (&4 * B) * n`] THEN + GEN_REWRITE_TAC (LAND_CONV o RAND_CONV) [REAL_POW_MUL] THEN + SIMP_TAC[REAL_ARITH `(&2 * d * n) * a * b = d * &2 * a * (n * b)`] THEN + REWRITE_TAC[GSYM(CONJUNCT2 real_pow)] THEN + SIMP_TAC[DIMINDEX_GE_1; ARITH_RULE `1 <= n ==> SUC(n - 1) = n`] THEN + MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `e / &(2 * c) pow (dimindex(:M)) / + (&(dimindex(:M)) pow dimindex(:M)) * + norm(v - u:real^M) pow dimindex(:N)` THEN + CONJ_TAC THENL + [REWRITE_TAC[REAL_MUL_ASSOC] THEN MATCH_MP_TAC REAL_LE_RMUL THEN + ASM_SIMP_TAC[NORM_POS_LE; REAL_POW_LE]; + ALL_TAC] THEN + GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [real_div] THEN + REWRITE_TAC[GSYM REAL_MUL_ASSOC] THEN MATCH_MP_TAC REAL_LE_LMUL THEN + ASM_SIMP_TAC[REAL_LE_DIV; REAL_POW_LE; REAL_LT_IMP_LE] THEN + REWRITE_TAC[ONCE_REWRITE_RULE[REAL_MUL_SYM] (GSYM real_div)] THEN + SIMP_TAC[REAL_LE_LDIV_EQ; REAL_POW_LT; REAL_OF_NUM_LT; + LE_1; DIMINDEX_GE_1] THEN + MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `norm(v - u:real^M) pow dimindex(:M)` THEN CONJ_TAC THENL + [MATCH_MP_TAC REAL_POW_MONO_INV THEN ASM_REWRITE_TAC[NORM_POS_LE] THEN + SUBGOAL_THEN `u IN ball(x:real^M,r x) /\ v IN ball(x,r x)` MP_TAC + THENL + [ASM_MESON_TAC[SUBSET; ENDS_IN_INTERVAL; INTERIOR_EMPTY]; + REWRITE_TAC[IN_BALL] THEN + SUBGOAL_THEN `(r:real^M->real) x <= &1 / &2` MP_TAC THENL + [ASM_REWRITE_TAC[]; CONV_TAC NORM_ARITH]]; + REMOVE_THEN "*" (K ALL_TAC) THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`u:real^M`; `v:real^M`]) THEN + ASM_REWRITE_TAC[REAL_ARITH `x - --x = &2 * x`] THEN + REWRITE_TAC[LEFT_IMP_EXISTS_THM; REAL_OF_NUM_MUL] THEN + X_GEN_TAC `p:num` THEN DISCH_TAC THEN + MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `(sum(1..dimindex(:M)) (\i. abs((v - u:real^M)$i))) + pow (dimindex(:M))` THEN + CONJ_TAC THENL + [MATCH_MP_TAC REAL_POW_LE2 THEN SIMP_TAC[NORM_POS_LE; NORM_LE_L1]; + REWRITE_TAC[MEASURE_INTERVAL; CONTENT_CLOSED_INTERVAL_CASES] THEN + GEN_REWRITE_TAC (RAND_CONV o ONCE_DEPTH_CONV) + [GSYM REAL_SUB_LE] THEN + ASM_SIMP_TAC[REAL_LT_IMP_LE; REAL_LT_DIV; REAL_LT_POW2] THEN + ASM_SIMP_TAC[SUM_CONST_NUMSEG; PRODUCT_CONST_NUMSEG; + VECTOR_SUB_COMPONENT; ADD_SUB] THEN + REWRITE_TAC[REAL_POW_MUL; REAL_MUL_SYM] THEN + MATCH_MP_TAC REAL_EQ_IMP_LE THEN BINOP_TAC THEN REWRITE_TAC[] THEN + AP_THM_TAC THEN AP_TERM_TAC THEN SIMP_TAC[REAL_ABS_REFL] THEN + ASM_SIMP_TAC[REAL_LT_IMP_LE; REAL_LT_DIV; REAL_LT_POW2]]]]; + GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [RIGHT_IMP_EXISTS_THM] THEN + REWRITE_TAC[SKOLEM_THM; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `g:(real^M->bool)->(real^N->bool)` THEN DISCH_TAC THEN + EXISTS_TAC `UNIONS (IMAGE (g:(real^M->bool)->(real^N->bool)) D)` THEN + CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + MATCH_MP_TAC MEASURE_COUNTABLE_UNIONS_LE_STRONG_GEN THEN + ASM_SIMP_TAC[COUNTABLE_IMAGE; FORALL_IN_IMAGE] THEN + ONCE_REWRITE_TAC[CONJ_SYM] THEN + REWRITE_TAC[FORALL_FINITE_SUBSET_IMAGE] THEN + X_GEN_TAC `D':(real^M->bool)->bool` THEN STRIP_TAC THEN + W(MP_TAC o PART_MATCH (lhand o rand) MEASURE_UNIONS_LE_IMAGE o + lhand o snd) THEN + ANTS_TAC THENL [ASM_MESON_TAC[SUBSET]; ALL_TAC] THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] REAL_LE_TRANS) THEN + MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC + `sum D' (\k:real^M->bool. + e / &(2 * c) pow (dimindex(:M)) * measure k)` THEN CONJ_TAC + THENL [MATCH_MP_TAC SUM_LE THEN ASM_MESON_TAC[SUBSET]; ALL_TAC] THEN + REWRITE_TAC[SUM_LMUL] THEN + REWRITE_TAC[REAL_ARITH `e / b * x:real = (e * x) / b`] THEN + ASM_SIMP_TAC[REAL_POW_LT; REAL_LE_LDIV_EQ; REAL_LE_LMUL_EQ] THEN + MP_TAC(ISPECL [`D':(real^M->bool)->bool`; `UNIONS D':real^M->bool`] + MEASURE_ELEMENTARY) THEN + ANTS_TAC THENL + [ASM_REWRITE_TAC[division_of] THEN + CONJ_TAC THENL [ALL_TAC; ASM_MESON_TAC[SUBSET]] THEN + GEN_TAC THEN DISCH_TAC THEN CONJ_TAC THENL + [ASM SET_TAC[]; ASM_MESON_TAC[SUBSET; INTERIOR_EMPTY]]; + ALL_TAC] THEN + MATCH_MP_TAC(REAL_ARITH `y = z /\ x <= e ==> x = y ==> z <= e`) THEN + CONJ_TAC THENL + [MATCH_MP_TAC SUM_EQ THEN ASM_MESON_TAC[MEASURE_INTERVAL; SUBSET]; + ALL_TAC] THEN + MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `measure(interval[--(vec c):real^M,vec c])` THEN CONJ_TAC THENL + [MATCH_MP_TAC MEASURE_SUBSET THEN REWRITE_TAC[MEASURABLE_INTERVAL] THEN + CONJ_TAC THENL [MATCH_MP_TAC MEASURABLE_UNIONS; ASM SET_TAC[]] THEN + ASM_MESON_TAC[SUBSET; MEASURABLE_INTERVAL]; + SIMP_TAC[MEASURE_INTERVAL; CONTENT_CLOSED_INTERVAL_CASES] THEN + REWRITE_TAC[VEC_COMPONENT; VECTOR_NEG_COMPONENT; REAL_ARITH + `x - --x = &2 * x /\ (--x <= x <=> &0 <= &2 * x)`] THEN + ASM_SIMP_TAC[REAL_OF_NUM_MUL; REAL_LT_IMP_LE] THEN + REWRITE_TAC[PRODUCT_CONST_NUMSEG; ADD_SUB; REAL_LE_REFL]]]) in + REPEAT STRIP_TAC THEN + SUBGOAL_THEN + `s = UNIONS + {{x | x IN s /\ norm(x:real^M) <= &n /\ + onorm((f':real^M->real^M->real^N) x) <= &n} | + n IN (:num)}` + SUBST1_TAC THENL + [REWRITE_TAC[EXTENSION; UNIONS_GSPEC; IN_ELIM_THM; IN_UNIV] THEN + X_GEN_TAC `x:real^M` THEN + ASM_CASES_TAC `(x:real^M) IN s` THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[GSYM REAL_MAX_LE; REAL_ARCH_SIMPLE]; + REWRITE_TAC[IMAGE_UNIONS] THEN + MATCH_MP_TAC NEGLIGIBLE_COUNTABLE_UNIONS_GEN THEN + REWRITE_TAC[FORALL_IN_IMAGE; FORALL_IN_GSPEC] THEN + ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN + ASM_SIMP_TAC[GSYM IMAGE_o; COUNTABLE_IMAGE; NUM_COUNTABLE] THEN + X_GEN_TAC `n:num` THEN REWRITE_TAC[IN_UNIV] THEN + MATCH_MP_TAC semma THEN + MAP_EVERY EXISTS_TAC [`f':real^M->real^M->real^N`; `&n + &1:real`] THEN + ASM_REWRITE_TAC[] THEN CONJ_TAC THENL [REAL_ARITH_TAC; ALL_TAC] THEN + CONJ_TAC THENL + [MATCH_MP_TAC BOUNDED_SUBSET THEN + EXISTS_TAC `cball(vec 0:real^M,&n)` THEN + SIMP_TAC[BOUNDED_CBALL; SUBSET; IN_CBALL_0; IN_ELIM_THM]; + X_GEN_TAC `x:real^M` THEN REWRITE_TAC[IN_ELIM_THM] THEN STRIP_TAC THEN + ASM_SIMP_TAC[REAL_ARITH `x <= n ==> x <= n + &1`] THEN + FIRST_X_ASSUM(MP_TAC o SPEC `x:real^M`) THEN ASM_REWRITE_TAC[] THEN + REPEAT STRIP_TAC THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + HAS_DERIVATIVE_WITHIN_SUBSET)) THEN SET_TAC[]]]);; + +(* ------------------------------------------------------------------------- *) +(* Also negligibility of BV low-dimensional image. *) +(* ------------------------------------------------------------------------- *) + +let NEGLIGIBLE_IMAGE_BOUNDED_VARIATION_INTERVAL = prove + (`!f:real^1->real^N a b. + 2 <= dimindex(:N) /\ f has_bounded_variation_on interval[a,b] + ==> negligible(IMAGE f (interval[a,b]))`, + REPEAT STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + HAS_BOUNDED_VECTOR_VARIATION_RIGHT_LIMIT)) THEN + FIRST_ASSUM(MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + HAS_BOUNDED_VECTOR_VARIATION_LEFT_LIMIT)) THEN + REWRITE_TAC[RIGHT_IMP_EXISTS_THM] THEN + REWRITE_TAC[SKOLEM_THM; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `l:real^1->real^N` THEN DISCH_TAC THEN + X_GEN_TAC `r:real^1->real^N` THEN DISCH_TAC THEN + REWRITE_TAC[NEGLIGIBLE_OUTER_LE] THEN X_GEN_TAC `ee:real` THEN DISCH_TAC THEN + ABBREV_TAC + `e = min (&1) (ee / + (&2 pow (dimindex(:N)) * + vector_variation (interval[a,b]) (f:real^1->real^N) + &1))` THEN + SUBGOAL_THEN `&0 < e` ASSUME_TAC THENL + [EXPAND_TAC "e" THEN + MATCH_MP_TAC(REAL_ARITH `&0 < x ==> &0 < min (&1) x`) THEN + MATCH_MP_TAC REAL_LT_DIV THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC(REAL_ARITH `&0 <= x ==> &0 < x + &1`) THEN + MATCH_MP_TAC REAL_LE_MUL THEN ASM_SIMP_TAC[VECTOR_VARIATION_POS_LE] THEN + MATCH_MP_TAC REAL_POW_LE THEN REAL_ARITH_TAC; + ALL_TAC] THEN + SUBGOAL_THEN + `!c. ?d. &0 < d /\ + (c IN interval[a,b] + ==> (!x. x IN interval[a,c] /\ ~(x = c) /\ dist(x,c) < d + ==> dist((f:real^1->real^N) x,l c) < e) /\ + (!x. x IN interval[c,b] /\ ~(x = c) /\ dist(x,c) < d + ==> dist(f x,r c) < e))` + MP_TAC THENL + [X_GEN_TAC `c:real^1` THEN ASM_CASES_TAC `(c:real^1) IN interval[a,b]` THENL + [ALL_TAC; EXISTS_TAC `&1` THEN ASM_REWRITE_TAC[REAL_LT_01]] THEN + REPEAT(FIRST_X_ASSUM(MP_TAC o SPEC `c:real^1`)) THEN + ASM_REWRITE_TAC[LIM_WITHIN; IMP_IMP; AND_FORALL_THM] THEN + DISCH_THEN(MP_TAC o SPEC `e:real`) THEN ASM_REWRITE_TAC[GSYM DIST_NZ] THEN + DISCH_THEN(CONJUNCTS_THEN2 + (X_CHOOSE_THEN `d1:real` STRIP_ASSUME_TAC) + (X_CHOOSE_THEN `d2:real` STRIP_ASSUME_TAC)) THEN + EXISTS_TAC `min d1 d2:real` THEN ASM_SIMP_TAC[REAL_LT_MIN]; + REWRITE_TAC[SKOLEM_THM; FORALL_AND_THM; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `d:real^1->real` THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC (LABEL_TAC "*"))] THEN + MP_TAC(ISPECL [`\x:real^1. ball(x,d x)`; `a:real^1`; `b:real^1`] + FINE_DIVISION_EXISTS) THEN + ASM_REWRITE_TAC[fine; gauge; OPEN_BALL; CENTRE_IN_BALL] THEN + DISCH_THEN(X_CHOOSE_THEN + `p:(real^1#(real^1->bool))->bool` STRIP_ASSUME_TAC) THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP TAGGED_DIVISION_OF_FINITE) THEN + EXISTS_TAC + `UNIONS(IMAGE (\(c,k). + (f c) INSERT + (cball((l:real^1->real^N) c, + min e (vector_variation (interval[interval_lowerbound k,c]) + (f:real^1->real^N))) UNION + cball((r:real^1->real^N) c, + min e (vector_variation (interval[c,interval_upperbound k]) + (f:real^1->real^N))))) p)` THEN + REPEAT CONJ_TAC THENL + [FIRST_ASSUM(SUBST1_TAC o MATCH_MP TAGGED_DIVISION_UNION_IMAGE_SND) THEN + REWRITE_TAC[IMAGE_UNIONS; GSYM IMAGE_o] THEN + MATCH_MP_TAC UNIONS_MONO_IMAGE THEN + REWRITE_TAC[FORALL_PAIR_THM; o_THM] THEN + MAP_EVERY X_GEN_TAC [`c:real^1`; `k:real^1->bool`] THEN DISCH_TAC THEN + SUBGOAL_THEN `?u v:real^1. k = interval[u,v]` + (REPEAT_TCL CHOOSE_THEN SUBST_ALL_TAC) + THENL [ASM_MESON_TAC[TAGGED_DIVISION_OF]; ALL_TAC] THEN + SUBGOAL_THEN `drop u <= drop v` ASSUME_TAC THENL + [ASM_MESON_TAC[TAGGED_DIVISION_OF; INTERVAL_NE_EMPTY_1; NOT_IN_EMPTY]; + ASM_SIMP_TAC[INTERVAL_LOWERBOUND_1; INTERVAL_UPPERBOUND_1]] THEN + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE] THEN + X_GEN_TAC `x:real^1` THEN REWRITE_TAC[IN_INTERVAL_1] THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`c:real^1`; `interval[u:real^1,v]`]) THEN + ASM_REWRITE_TAC[SUBSET; IN_INTERVAL_1; IN_CBALL] THEN DISCH_TAC THEN + REWRITE_TAC[IN_INSERT; IN_UNION] THEN ASM_CASES_TAC `x:real^1 = c` THEN + ASM_REWRITE_TAC[] THEN DISJ2_TAC THEN + SIMP_TAC[IN_CBALL; REAL_LE_MIN] THEN ASM_CASES_TAC `drop x <= drop c` THENL + [DISJ1_TAC THEN CONJ_TAC THENL + [ONCE_REWRITE_TAC[DIST_SYM] THEN MATCH_MP_TAC REAL_LT_IMP_LE THEN + REMOVE_THEN "*" (MP_TAC o SPEC `c:real^1`) THEN ANTS_TAC THENL + [ASM_MESON_TAC[TAGGED_DIVISION_OF; SUBSET]; ALL_TAC] THEN + DISCH_THEN(MATCH_MP_TAC o CONJUNCT1) THEN ASM_REWRITE_TAC[] THEN + ASM_SIMP_TAC[GSYM(ONCE_REWRITE_RULE[DIST_SYM] IN_BALL)] THEN + ASM_MESON_TAC[IN_INTERVAL_1; SUBSET; TAGGED_DIVISION_OF]; + ALL_TAC] THEN + SUBGOAL_THEN `drop a <= drop u /\ drop x < drop c /\ + drop c <= drop v /\ drop v <= drop b` + STRIP_ASSUME_TAC THENL + [ASM_REWRITE_TAC[REAL_LT_LE; DROP_EQ] THEN + ASM_MESON_TAC[IN_INTERVAL_1; SUBSET; TAGGED_DIVISION_OF; + REAL_LE_TOTAL]; + ALL_TAC] THEN + REWRITE_TAC[ONCE_REWRITE_RULE[NORM_SUB] dist] THEN + MATCH_MP_TAC + (REWRITE_RULE[LIFT_DROP; FORALL_LIFT] + (ISPEC `at c within interval [u:real^1,c]` LIM_DROP_UBOUND)) THEN + EXISTS_TAC `\y:real^1. lift(norm(f x - f y:real^N))` THEN + REWRITE_TAC[TRIVIAL_LIMIT_WITHIN; LIFT_DROP] THEN REPEAT CONJ_TAC THENL + [MATCH_MP_TAC LIM_NORM THEN MATCH_MP_TAC LIM_SUB THEN + ASM_SIMP_TAC[IN_INTERVAL_1; LIM_CONST] THEN + MATCH_MP_TAC LIM_WITHIN_SUBSET THEN + EXISTS_TAC `interval[a:real^1,c]` THEN CONJ_TAC THENL + [FIRST_X_ASSUM MATCH_MP_TAC THEN REWRITE_TAC[IN_INTERVAL_1] THEN + ASM_REAL_ARITH_TAC; + REWRITE_TAC[SUBSET_INTERVAL_1] THEN ASM_REAL_ARITH_TAC]; + W(MP_TAC o PART_MATCH (lhs o rand) LIMPT_OF_CONVEX o snd) THEN + ANTS_TAC THENL + [SIMP_TAC[CONVEX_INTERVAL; ENDS_IN_INTERVAL; + INTERVAL_NE_EMPTY_1] THEN + ASM_REAL_ARITH_TAC; + DISCH_THEN SUBST1_TAC THEN MATCH_MP_TAC(SET_RULE + `(?y. ~(y = x) /\ y IN s) ==> ~(s = {x})`) THEN + EXISTS_TAC `u:real^1` THEN + REWRITE_TAC[IN_INTERVAL_1; GSYM DROP_EQ] THEN ASM_REAL_ARITH_TAC]; + REWRITE_TAC[EVENTUALLY_WITHIN] THEN EXISTS_TAC `&1` THEN + REWRITE_TAC[REAL_LT_01] THEN X_GEN_TAC `y:real^1` THEN + REWRITE_TAC[IN_INTERVAL_1] THEN STRIP_TAC THEN + MATCH_MP_TAC VECTOR_VARIATION_GE_NORM_FUNCTION THEN CONJ_TAC THENL + [FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + HAS_BOUNDED_VARIATION_ON_SUBSET)) THEN + REWRITE_TAC[SUBSET_INTERVAL_1] THEN ASM_REAL_ARITH_TAC; + MATCH_MP_TAC(CONJUNCT1(SPEC_ALL + (REWRITE_RULE[CONVEX_CONTAINS_SEGMENT] CONVEX_INTERVAL))) THEN + REWRITE_TAC[IN_INTERVAL_1] THEN ASM_REAL_ARITH_TAC]]; + DISJ2_TAC THEN CONJ_TAC THENL + [ONCE_REWRITE_TAC[DIST_SYM] THEN MATCH_MP_TAC REAL_LT_IMP_LE THEN + REMOVE_THEN "*" (MP_TAC o SPEC `c:real^1`) THEN ANTS_TAC THENL + [ASM_MESON_TAC[TAGGED_DIVISION_OF; SUBSET]; ALL_TAC] THEN + DISCH_THEN(MATCH_MP_TAC o CONJUNCT2) THEN ASM_REWRITE_TAC[] THEN + ASM_SIMP_TAC[GSYM(ONCE_REWRITE_RULE[DIST_SYM] IN_BALL)] THEN + ASM_MESON_TAC[IN_INTERVAL_1; SUBSET; TAGGED_DIVISION_OF; + REAL_LE_TOTAL]; + ALL_TAC] THEN + SUBGOAL_THEN `drop a <= drop c /\ drop c < drop x /\ + drop x <= drop v /\ drop v <= drop b` + STRIP_ASSUME_TAC THENL + [ASM_REWRITE_TAC[GSYM REAL_NOT_LE] THEN + ASM_MESON_TAC[IN_INTERVAL_1; SUBSET; TAGGED_DIVISION_OF; + REAL_LE_TOTAL]; + ALL_TAC] THEN + REWRITE_TAC[ONCE_REWRITE_RULE[NORM_SUB] dist] THEN + MATCH_MP_TAC + (REWRITE_RULE[LIFT_DROP; FORALL_LIFT] + (ISPEC `at c within interval [c:real^1,v]` LIM_DROP_UBOUND)) THEN + EXISTS_TAC `\y:real^1. lift(norm(f x - f y:real^N))` THEN + REWRITE_TAC[TRIVIAL_LIMIT_WITHIN; LIFT_DROP] THEN REPEAT CONJ_TAC THENL + [MATCH_MP_TAC LIM_NORM THEN MATCH_MP_TAC LIM_SUB THEN + ASM_SIMP_TAC[IN_INTERVAL_1; LIM_CONST] THEN + MATCH_MP_TAC LIM_WITHIN_SUBSET THEN + EXISTS_TAC `interval[c:real^1,b]` THEN CONJ_TAC THENL + [FIRST_X_ASSUM MATCH_MP_TAC THEN REWRITE_TAC[IN_INTERVAL_1] THEN + ASM_REAL_ARITH_TAC; + REWRITE_TAC[SUBSET_INTERVAL_1] THEN ASM_REAL_ARITH_TAC]; + W(MP_TAC o PART_MATCH (lhs o rand) LIMPT_OF_CONVEX o snd) THEN + ANTS_TAC THENL + [SIMP_TAC[CONVEX_INTERVAL; ENDS_IN_INTERVAL; + INTERVAL_NE_EMPTY_1] THEN + ASM_REAL_ARITH_TAC; + DISCH_THEN SUBST1_TAC THEN MATCH_MP_TAC(SET_RULE + `(?y. ~(y = x) /\ y IN s) ==> ~(s = {x})`) THEN + EXISTS_TAC `v:real^1` THEN + REWRITE_TAC[IN_INTERVAL_1; GSYM DROP_EQ] THEN ASM_REAL_ARITH_TAC]; + REWRITE_TAC[EVENTUALLY_WITHIN] THEN EXISTS_TAC `&1` THEN + REWRITE_TAC[REAL_LT_01] THEN X_GEN_TAC `y:real^1` THEN + REWRITE_TAC[IN_INTERVAL_1] THEN STRIP_TAC THEN + MATCH_MP_TAC VECTOR_VARIATION_GE_NORM_FUNCTION THEN CONJ_TAC THENL + [FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + HAS_BOUNDED_VARIATION_ON_SUBSET)) THEN + REWRITE_TAC[SUBSET_INTERVAL_1] THEN ASM_REAL_ARITH_TAC; + MATCH_MP_TAC(CONJUNCT1(SPEC_ALL + (REWRITE_RULE[CONVEX_CONTAINS_SEGMENT] CONVEX_INTERVAL))) THEN + REWRITE_TAC[IN_INTERVAL_1] THEN ASM_REAL_ARITH_TAC]]]; + MATCH_MP_TAC MEASURABLE_UNIONS THEN ASM_SIMP_TAC[FINITE_IMAGE] THEN + REWRITE_TAC[FORALL_IN_IMAGE; FORALL_PAIR_THM] THEN + SIMP_TAC[MEASURABLE_CBALL; MEASURABLE_UNION; MEASURABLE_INSERT]; + W(MP_TAC o PART_MATCH (lhand o rand) MEASURE_UNIONS_LE_IMAGE o + lhand o snd) THEN + ANTS_TAC THENL + [ASM_REWRITE_TAC[FORALL_IN_IMAGE; FORALL_PAIR_THM] THEN + SIMP_TAC[MEASURABLE_CBALL; MEASURABLE_UNION; MEASURABLE_INSERT]; + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] REAL_LE_TRANS)] THEN + ONCE_REWRITE_TAC[LAMBDA_PAIR_THM] THEN REWRITE_TAC[MEASURE_INSERT] THEN + MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC + `&2 pow (dimindex(:N)) * + e * sum p (\(x:real^1,k). vector_variation k (f:real^1->real^N))` THEN + CONJ_TAC THENL + [REWRITE_TAC[GSYM SUM_LMUL] THEN MATCH_MP_TAC SUM_LE THEN + ASM_REWRITE_TAC[FORALL_PAIR_THM] THEN + MAP_EVERY X_GEN_TAC [`c:real^1`; `k:real^1->bool`] THEN DISCH_TAC THEN + SUBGOAL_THEN `?u v:real^1. k = interval[u,v]` + (REPEAT_TCL CHOOSE_THEN SUBST_ALL_TAC) + THENL [ASM_MESON_TAC[TAGGED_DIVISION_OF]; ALL_TAC] THEN + SUBGOAL_THEN `drop u <= drop v` ASSUME_TAC THENL + [ASM_MESON_TAC[TAGGED_DIVISION_OF; INTERVAL_NE_EMPTY_1; NOT_IN_EMPTY]; + ASM_SIMP_TAC[INTERVAL_LOWERBOUND_1; INTERVAL_UPPERBOUND_1]] THEN + SUBGOAL_THEN + `(f:real^1->real^N) has_bounded_variation_on interval[u,c] /\ + (f:real^1->real^N) has_bounded_variation_on interval[c,v]` + STRIP_ASSUME_TAC THENL + [CONJ_TAC THEN FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP + (REWRITE_RULE[IMP_CONJ] HAS_BOUNDED_VARIATION_ON_SUBSET)) THEN + MATCH_MP_TAC SUBSET_TRANS THEN EXISTS_TAC `interval[u:real^1,v]` THEN + (CONJ_TAC THENL [ALL_TAC; ASM_MESON_TAC[TAGGED_DIVISION_OF]]) THEN + REWRITE_TAC[SUBSET_INTERVAL_1; REAL_LE_REFL] THEN + REWRITE_TAC[GSYM IN_INTERVAL_1] THEN ASM_MESON_TAC[TAGGED_DIVISION_OF]; + ALL_TAC] THEN + SUBGOAL_THEN + `vector_variation (interval [u,v]) (f:real^1->real^N) = + vector_variation (interval [u,c]) f + + vector_variation (interval [c,v]) f` + SUBST1_TAC THENL + [CONV_TAC SYM_CONV THEN MATCH_MP_TAC VECTOR_VARIATION_COMBINE THEN + ASM_REWRITE_TAC[CONJ_ASSOC; GSYM IN_INTERVAL_1] THEN + CONJ_TAC THENL [ASM_MESON_TAC[TAGGED_DIVISION_OF]; ALL_TAC] THEN + ASM_MESON_TAC[TAGGED_DIVISION_OF; HAS_BOUNDED_VARIATION_ON_SUBSET]; + ALL_TAC] THEN + W(MP_TAC o PART_MATCH (lhand o rand) MEASURE_UNION_LE o lhand o snd) THEN + REWRITE_TAC[MEASURABLE_CBALL; REAL_ADD_LDISTRIB] THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] REAL_LE_TRANS) THEN + MATCH_MP_TAC REAL_LE_ADD2 THEN CONJ_TAC THEN + W(MP_TAC o PART_MATCH (lhand o rand) + MEASURE_CBALL_BOUND o lhand o snd) THEN + ASM_SIMP_TAC[REAL_LE_MIN; REAL_LT_IMP_LE; VECTOR_VARIATION_POS_LE] THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] REAL_LE_TRANS) THEN + REWRITE_TAC[REAL_POW_MUL] THEN MATCH_MP_TAC REAL_LE_LMUL THEN + SIMP_TAC[REAL_POW_LE; REAL_POS] THEN + (SUBGOAL_THEN `dimindex(:N) = (dimindex(:N) - 1) + 1` SUBST1_TAC THENL + [ASM_ARITH_TAC; REWRITE_TAC[REAL_POW_ADD; REAL_POW_1]]) THEN + MATCH_MP_TAC REAL_LE_MUL2 THEN + ASM_SIMP_TAC[REAL_LE_MIN; REAL_LT_IMP_LE; VECTOR_VARIATION_POS_LE; + REAL_POW_LE; REAL_ARITH `min e v <= v`] THEN + MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `(e:real) pow (dimindex(:N) - 1)` THEN + (CONJ_TAC THENL + [MATCH_MP_TAC REAL_POW_LE2 THEN + ASM_SIMP_TAC[REAL_LE_MIN; REAL_LT_IMP_LE; VECTOR_VARIATION_POS_LE] THEN + REAL_ARITH_TAC; + GEN_REWRITE_TAC RAND_CONV [GSYM REAL_POW_1] THEN + MATCH_MP_TAC REAL_POW_MONO_INV THEN + ASM_SIMP_TAC[REAL_LT_IMP_LE] THEN EXPAND_TAC "e" THEN CONJ_TAC THENL + [ASM_REAL_ARITH_TAC; ASM_ARITH_TAC]]); + MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC + `&2 pow dimindex (:N) * + (ee / (&2 pow (dimindex(:N)) * + vector_variation (interval[a,b]) (f:real^1->real^N) + &1)) * + sum p (\(x:real^1,k). vector_variation k f)` THEN + CONJ_TAC THENL + [MATCH_MP_TAC REAL_LE_LMUL THEN SIMP_TAC[REAL_POS; REAL_POW_LE] THEN + MATCH_MP_TAC REAL_LE_RMUL THEN CONJ_TAC THENL + [EXPAND_TAC "e" THEN REAL_ARITH_TAC; ALL_TAC] THEN + MATCH_MP_TAC SUM_POS_LE THEN ASM_REWRITE_TAC[FORALL_PAIR_THM] THEN + ASM_MESON_TAC[HAS_BOUNDED_VARIATION_ON_SUBSET; TAGGED_DIVISION_OF; + VECTOR_VARIATION_POS_LE]; + ALL_TAC] THEN + REWRITE_TAC[REAL_ARITH `a * b / c * d:real = (b * a * d) / c`] THEN + W(MP_TAC o PART_MATCH (lhand o rand) REAL_LE_LDIV_EQ o snd) THEN + ASM_SIMP_TAC[REAL_LE_MUL; REAL_POS; REAL_POW_LE; VECTOR_VARIATION_POS_LE; + REAL_ARITH `&0 <= x ==> &0 < x + &1`] THEN + DISCH_THEN SUBST1_TAC THEN + ASM_SIMP_TAC[REAL_LE_LMUL_EQ; GSYM REAL_MUL_ASSOC] THEN + MATCH_MP_TAC(REAL_ARITH `x <= y ==> x <= y + &1`) THEN + MATCH_MP_TAC REAL_LE_LMUL THEN SIMP_TAC[REAL_POW_LE; REAL_POS] THEN + FIRST_ASSUM(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 + SIMP_TAC[VECTOR_VARIATION_ON_NULL; BOUNDED_INTERVAL] THEN + DISCH_THEN SUBST1_TAC THEN REWRITE_TAC[ETA_AX] THEN + MATCH_MP_TAC REAL_EQ_IMP_LE THEN + MATCH_MP_TAC VECTOR_VARIATION_ON_DIVISION THEN + ASM_SIMP_TAC[DIVISION_OF_TAGGED_DIVISION]]]);; + +let NEGLIGIBLE_RECTIFIABLE_PATH_IMAGE = prove + (`!g:real^1->real^N. + 2 <= dimindex(:N) /\ rectifiable_path g ==> negligible(path_image g)`, + REWRITE_TAC[rectifiable_path; path_image] THEN + SIMP_TAC[NEGLIGIBLE_IMAGE_BOUNDED_VARIATION_INTERVAL]);; + +(* ------------------------------------------------------------------------- *) +(* Properties of Lebesgue measurable sets. *) +(* ------------------------------------------------------------------------- *) + +let MEASURABLE_IMP_LEBESGUE_MEASURABLE = prove + (`!s:real^N->bool. measurable s ==> lebesgue_measurable s`, + REPEAT STRIP_TAC THEN REWRITE_TAC[lebesgue_measurable] THEN + MATCH_MP_TAC INTEGRABLE_IMP_MEASURABLE THEN + ASM_REWRITE_TAC[indicator; GSYM MEASURABLE_INTEGRABLE]);; + +let NEGLIGIBLE_IMP_LEBESGUE_MEASURABLE = prove + (`!s:real^N->bool. negligible s ==> lebesgue_measurable s`, + SIMP_TAC[NEGLIGIBLE_IMP_MEASURABLE; MEASURABLE_IMP_LEBESGUE_MEASURABLE]);; + +let LEBESGUE_MEASURABLE_EMPTY = prove + (`lebesgue_measurable {}`, + SIMP_TAC[MEASURABLE_IMP_LEBESGUE_MEASURABLE; MEASURABLE_EMPTY]);; + +let LEBESGUE_MEASURABLE_UNIV = prove + (`lebesgue_measurable (:real^N)`, + REWRITE_TAC[lebesgue_measurable; indicator; IN_UNIV; MEASURABLE_ON_CONST]);; + +let LEBESGUE_MEASURABLE_COMPACT = prove + (`!s:real^N->bool. compact s ==> lebesgue_measurable s`, + SIMP_TAC[MEASURABLE_IMP_LEBESGUE_MEASURABLE; MEASURABLE_COMPACT]);; + +let LEBESGUE_MEASURABLE_INTERVAL = prove + (`(!a b:real^N. lebesgue_measurable(interval[a,b])) /\ + (!a b:real^N. lebesgue_measurable(interval(a,b)))`, + SIMP_TAC[MEASURABLE_IMP_LEBESGUE_MEASURABLE; MEASURABLE_INTERVAL]);; + +let LEBESGUE_MEASURABLE_INTER = prove + (`!s t:real^N->bool. + lebesgue_measurable s /\ lebesgue_measurable t + ==> lebesgue_measurable(s INTER t)`, + REWRITE_TAC[indicator; lebesgue_measurable; MEASURABLE_ON_UNIV] THEN + REWRITE_TAC[MEASURABLE_ON_INTER]);; + +let LEBESGUE_MEASURABLE_UNION = prove + (`!s t:real^N->bool. + lebesgue_measurable s /\ lebesgue_measurable t + ==> lebesgue_measurable(s UNION t)`, + REWRITE_TAC[indicator; lebesgue_measurable; MEASURABLE_ON_UNIV] THEN + REWRITE_TAC[MEASURABLE_ON_UNION]);; + +let LEBESGUE_MEASURABLE_DIFF = prove + (`!s t:real^N->bool. + lebesgue_measurable s /\ lebesgue_measurable t + ==> lebesgue_measurable(s DIFF t)`, + REWRITE_TAC[indicator; lebesgue_measurable; MEASURABLE_ON_UNIV] THEN + REWRITE_TAC[MEASURABLE_ON_DIFF]);; + +let LEBESGUE_MEASURABLE_COMPL = prove + (`!s. lebesgue_measurable((:real^N) DIFF s) <=> lebesgue_measurable s`, + MESON_TAC[LEBESGUE_MEASURABLE_DIFF; LEBESGUE_MEASURABLE_UNIV; + SET_RULE `UNIV DIFF (UNIV DIFF s) = s`]);; + +let LEBESGUE_MEASURABLE_ON_SUBINTERVALS = prove + (`!s. lebesgue_measurable s <=> + !a b:real^N. lebesgue_measurable(s INTER interval[a,b])`, + GEN_TAC THEN EQ_TAC THEN + SIMP_TAC[LEBESGUE_MEASURABLE_INTERVAL; LEBESGUE_MEASURABLE_INTER] THEN + REWRITE_TAC[lebesgue_measurable] THEN DISCH_TAC THEN + MATCH_MP_TAC INTEGRABLE_SUBINTERVALS_IMP_MEASURABLE THEN + MAP_EVERY X_GEN_TAC [`a:real^N`; `b:real^N`] THEN + MATCH_MP_TAC MEASURABLE_BOUNDED_BY_INTEGRABLE_IMP_INTEGRABLE THEN + EXISTS_TAC `(\x. vec 1):real^N->real^1` THEN + REWRITE_TAC[INTEGRABLE_CONST] THEN CONJ_TAC THENL + [ONCE_REWRITE_TAC[GSYM MEASURABLE_ON_UNIV] THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`a:real^N`; `b:real^N`]) THEN + MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_TERM_TAC THEN + REWRITE_TAC[FUN_EQ_THM; indicator; IN_INTER] THEN MESON_TAC[]; + REPEAT STRIP_TAC THEN REWRITE_TAC[indicator] THEN + COND_CASES_TAC THEN REWRITE_TAC[DROP_VEC; NORM_REAL; GSYM drop] THEN + REAL_ARITH_TAC]);; + +let LEBESGUE_MEASURABLE_CLOSED = prove + (`!s:real^N->bool. closed s ==> lebesgue_measurable s`, + REPEAT STRIP_TAC THEN + ONCE_REWRITE_TAC[LEBESGUE_MEASURABLE_ON_SUBINTERVALS] THEN + ASM_SIMP_TAC[CLOSED_INTER_COMPACT; LEBESGUE_MEASURABLE_COMPACT; + COMPACT_INTERVAL]);; + +let LEBESGUE_MEASURABLE_OPEN = prove + (`!s:real^N->bool. open s ==> lebesgue_measurable s`, + REWRITE_TAC[OPEN_CLOSED] THEN REPEAT STRIP_TAC THEN + ONCE_REWRITE_TAC[GSYM LEBESGUE_MEASURABLE_COMPL] THEN + ASM_SIMP_TAC[LEBESGUE_MEASURABLE_CLOSED]);; + +let LEBESGUE_MEASURABLE_UNIONS = prove + (`!f. FINITE f /\ (!s. s IN f ==> lebesgue_measurable s) + ==> lebesgue_measurable (UNIONS f)`, + REWRITE_TAC[indicator; lebesgue_measurable; MEASURABLE_ON_UNIV] THEN + REWRITE_TAC[MEASURABLE_ON_UNIONS]);; + +let LEBESGUE_MEASURABLE_COUNTABLE_UNIONS = prove + (`!f:(real^N->bool)->bool. + COUNTABLE f /\ (!s. s IN f ==> lebesgue_measurable s) + ==> lebesgue_measurable (UNIONS f)`, + REWRITE_TAC[indicator; lebesgue_measurable; MEASURABLE_ON_UNIV] THEN + REWRITE_TAC[MEASURABLE_ON_COUNTABLE_UNIONS]);; + +let LEBESGUE_MEASURABLE_COUNTABLE_UNIONS_EXPLICIT = prove + (`!s:num->real^N->bool. + (!n. lebesgue_measurable(s n)) + ==> lebesgue_measurable(UNIONS {s n | n IN (:num)})`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC LEBESGUE_MEASURABLE_COUNTABLE_UNIONS THEN + ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN + ASM_SIMP_TAC[COUNTABLE_IMAGE; FORALL_IN_IMAGE; IN_UNIV; NUM_COUNTABLE]);; + +let LEBESGUE_MEASURABLE_COUNTABLE_INTERS = prove + (`!f:(real^N->bool)->bool. + COUNTABLE f /\ (!s. s IN f ==> lebesgue_measurable s) + ==> lebesgue_measurable (INTERS f)`, + REPEAT STRIP_TAC THEN + REWRITE_TAC[INTERS_UNIONS; LEBESGUE_MEASURABLE_COMPL] THEN + MATCH_MP_TAC LEBESGUE_MEASURABLE_COUNTABLE_UNIONS THEN + ASM_SIMP_TAC[SIMPLE_IMAGE; FORALL_IN_IMAGE; COUNTABLE_IMAGE; + LEBESGUE_MEASURABLE_COMPL]);; + +let LEBESGUE_MEASURABLE_COUNTABLE_INTERS_EXPLICIT = prove + (`!s:num->real^N->bool. + (!n. lebesgue_measurable(s n)) + ==> lebesgue_measurable(INTERS {s n | n IN (:num)})`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC LEBESGUE_MEASURABLE_COUNTABLE_INTERS THEN + ASM_SIMP_TAC[SIMPLE_IMAGE; FORALL_IN_IMAGE; COUNTABLE_IMAGE; + NUM_COUNTABLE]);; + +let LEBESGUE_MEASURABLE_INTERS = prove + (`!f:(real^N->bool)->bool. + FINITE f /\ (!s. s IN f ==> lebesgue_measurable s) + ==> lebesgue_measurable (INTERS f)`, + SIMP_TAC[LEBESGUE_MEASURABLE_COUNTABLE_INTERS; FINITE_IMP_COUNTABLE]);; + +let LEBESGUE_MEASURABLE_IFF_MEASURABLE = prove + (`!s:real^N->bool. bounded s ==> (lebesgue_measurable s <=> measurable s)`, + REPEAT STRIP_TAC THEN EQ_TAC THEN + SIMP_TAC[MEASURABLE_IMP_LEBESGUE_MEASURABLE] THEN + REWRITE_TAC[lebesgue_measurable; indicator; MEASURABLE_INTEGRABLE] THEN + SUBGOAL_THEN `?a b:real^N. s = s INTER interval[a,b]` + (REPEAT_TCL CHOOSE_THEN SUBST1_TAC) + THENL [REWRITE_TAC[SET_RULE `s = s INTER t <=> s SUBSET t`] THEN + ASM_MESON_TAC[BOUNDED_SUBSET_CLOSED_INTERVAL]; ALL_TAC] THEN + REWRITE_TAC[IN_INTER; MESON[] + `(if P x /\ Q x then a else b) = + (if Q x then if P x then a else b else b)`] THEN + REWRITE_TAC[MEASURABLE_ON_UNIV; INTEGRABLE_RESTRICT_UNIV] THEN + STRIP_TAC THEN MATCH_MP_TAC + MEASURABLE_BOUNDED_BY_INTEGRABLE_IMP_INTEGRABLE THEN + EXISTS_TAC `(\x. vec 1):real^N->real^1` THEN + ASM_REWRITE_TAC[INTEGRABLE_CONST; NORM_REAL; DROP_VEC; GSYM drop] THEN + REPEAT STRIP_TAC THEN COND_CASES_TAC THEN SIMP_TAC[DROP_VEC] THEN + REAL_ARITH_TAC);; + +let MEASURABLE_ON_MEASURABLE_SUBSET = prove + (`!f s t. s SUBSET t /\ f measurable_on t /\ measurable s + ==> f measurable_on s`, + MESON_TAC[MEASURABLE_ON_LEBESGUE_MEASURABLE_SUBSET; + MEASURABLE_IMP_LEBESGUE_MEASURABLE]);; + +let MEASURABLE_ON_CASES = prove + (`!P f g:real^M->real^N s. + lebesgue_measurable {x | P x} /\ + f measurable_on s /\ g measurable_on s + ==> (\x. if P x then f x else g x) measurable_on s`, + REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[GSYM MEASURABLE_ON_UNIV] THEN + REPEAT STRIP_TAC THEN + SUBGOAL_THEN + `!x. (if x IN s then if P x then (f:real^M->real^N) x else g x else vec 0) = + (if x IN {x | P x} then if x IN s then f x else vec 0 else vec 0) + + (if x IN (:real^M) DIFF {x | P x} + then if x IN s then g x else vec 0 else vec 0)` + (fun th -> REWRITE_TAC[th]) + THENL + [GEN_TAC THEN REWRITE_TAC[IN_UNIV; IN_ELIM_THM; IN_DIFF] THEN + MESON_TAC[VECTOR_ADD_LID; VECTOR_ADD_RID]; + MATCH_MP_TAC MEASURABLE_ON_ADD THEN + CONJ_TAC THEN MATCH_MP_TAC MEASURABLE_ON_RESTRICT THEN + ASM_REWRITE_TAC[LEBESGUE_MEASURABLE_COMPL]]);; + +let LEBESGUE_MEASURABLE_JORDAN = prove + (`!s:real^N->bool. negligible(frontier s) ==> lebesgue_measurable s`, + REPEAT STRIP_TAC THEN + ONCE_REWRITE_TAC[LEBESGUE_MEASURABLE_ON_SUBINTERVALS] THEN + MAP_EVERY X_GEN_TAC [`a:real^N`; `b:real^N`] THEN + MATCH_MP_TAC MEASURABLE_IMP_LEBESGUE_MEASURABLE THEN + MATCH_MP_TAC MEASURABLE_JORDAN THEN + SIMP_TAC[BOUNDED_INTER; BOUNDED_INTERVAL] THEN + MATCH_MP_TAC NEGLIGIBLE_SUBSET THEN + EXISTS_TAC `frontier s UNION frontier(interval[a:real^N,b])` THEN + ASM_REWRITE_TAC[FRONTIER_INTER_SUBSET; NEGLIGIBLE_UNION_EQ] THEN + SIMP_TAC[NEGLIGIBLE_CONVEX_FRONTIER; CONVEX_INTERVAL]);; + +let LEBESGUE_MEASURABLE_CONVEX = prove + (`!s:real^N->bool. convex s ==> lebesgue_measurable s`, + SIMP_TAC[LEBESGUE_MEASURABLE_JORDAN; NEGLIGIBLE_CONVEX_FRONTIER]);; + +(* ------------------------------------------------------------------------- *) +(* Invariance theorems for Lebesgue measurability. *) +(* ------------------------------------------------------------------------- *) + +let MEASURABLE_ON_TRANSLATION = prove + (`!f:real^M->real^N s a. + f measurable_on (IMAGE (\x. a + x) s) + ==> (\x. f(a + x)) measurable_on s`, + REPEAT GEN_TAC THEN REWRITE_TAC[measurable_on; LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`k:real^M->bool`; `g:num->real^M->real^N`] THEN + STRIP_TAC THEN EXISTS_TAC `IMAGE (\x:real^M. --a + x) k` THEN + EXISTS_TAC `\n. (g:num->real^M->real^N) n o (\x. a + x)` THEN + ASM_REWRITE_TAC[NEGLIGIBLE_TRANSLATION_EQ] THEN CONJ_TAC THENL + [GEN_TAC THEN MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN + SIMP_TAC[CONTINUOUS_ON_ADD; CONTINUOUS_ON_CONST; CONTINUOUS_ON_ID] THEN + ASM_MESON_TAC[CONTINUOUS_ON_SUBSET; SUBSET_UNIV]; + X_GEN_TAC `x:real^M` THEN + FIRST_X_ASSUM(MP_TAC o SPEC `a + x:real^M`) THEN + REWRITE_TAC[o_DEF; IN_IMAGE] THEN + ONCE_REWRITE_TAC[VECTOR_ARITH `x:real^N = --a + y <=> a + x = y`] THEN + REWRITE_TAC[UNWIND_THM1; VECTOR_ARITH `a + x:real^N = a + y <=> x = y`]]);; + +let MEASURABLE_ON_TRANSLATION_EQ = prove + (`!f:real^M->real^N s a. + (\x. f(a + x)) measurable_on s <=> + f measurable_on (IMAGE (\x. a + x) s)`, + REPEAT GEN_TAC THEN EQ_TAC THEN REWRITE_TAC[MEASURABLE_ON_TRANSLATION] THEN + MP_TAC(ISPECL [`\x. (f:real^M->real^N) (a + x)`; + `IMAGE (\x:real^M. a + x) s`; `--a:real^M`] + MEASURABLE_ON_TRANSLATION) THEN + REWRITE_TAC[GSYM IMAGE_o; o_DEF; ETA_AX; IMAGE_ID; VECTOR_ARITH + `--a + a + x:real^N = x /\ a + --a + x = x`]);; + +let MEASURABLE_ON_LINEAR_IMAGE_EQ = prove + (`!f:real^N->real^N h:real^N->real^P s. + linear f /\ (!x y. f x = f y ==> x = y) + ==> ((h o f) measurable_on s <=> h measurable_on (IMAGE f s))`, + let lemma = prove + (`!f:real^N->real^P g:real^N->real^N h s. + linear g /\ linear h /\ (!x. h(g x) = x) /\ (!x. g(h x) = x) + ==> (f o g) measurable_on s ==> f measurable_on (IMAGE g s)`, + REPEAT GEN_TAC THEN REWRITE_TAC[measurable_on] THEN + STRIP_TAC THEN DISCH_THEN(X_CHOOSE_THEN `k:real^N->bool` + (X_CHOOSE_THEN `G:num->real^N->real^P` STRIP_ASSUME_TAC)) THEN + EXISTS_TAC `IMAGE (g:real^N->real^N) k` THEN + EXISTS_TAC `\n x. (G:num->real^N->real^P) n ((h:real^N->real^N) x)` THEN + ASM_SIMP_TAC[NEGLIGIBLE_LINEAR_IMAGE] THEN CONJ_TAC THENL + [GEN_TAC THEN GEN_REWRITE_TAC LAND_CONV [GSYM o_DEF] THEN + MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN + ASM_MESON_TAC[LINEAR_CONTINUOUS_ON; CONTINUOUS_ON_SUBSET; SUBSET_UNIV]; + X_GEN_TAC `y:real^N` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `(h:real^N->real^N) y`) THEN + ANTS_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_TERM_TAC THEN + ASM_REWRITE_TAC[o_THM] THEN + AP_THM_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN ASM SET_TAC[]]) in + REPEAT GEN_TAC THEN DISCH_TAC THEN + FIRST_ASSUM(MP_TAC o MATCH_MP LINEAR_INJECTIVE_IMP_SURJECTIVE) THEN + POP_ASSUM MP_TAC THEN REWRITE_TAC[IMP_IMP; GSYM CONJ_ASSOC] THEN + DISCH_TAC THEN + FIRST_ASSUM(X_CHOOSE_THEN `g:real^N->real^N` STRIP_ASSUME_TAC o + MATCH_MP LINEAR_BIJECTIVE_LEFT_RIGHT_INVERSE) THEN + EQ_TAC THENL [ASM_MESON_TAC[lemma]; DISCH_TAC] THEN + MP_TAC(ISPECL [`(h:real^N->real^P) o (f:real^N->real^N)`; + `g:real^N->real^N`; `f:real^N->real^N`; + `IMAGE (f:real^N->real^N) s`] lemma) THEN + ASM_REWRITE_TAC[GSYM IMAGE_o; o_DEF; IMAGE_ID; ETA_AX]);; + +let LEBESGUE_MEASURABLE_TRANSLATION = prove + (`!a:real^N s. + lebesgue_measurable (IMAGE (\x. a + x) s) <=> + lebesgue_measurable s`, + ONCE_REWRITE_TAC[LEBESGUE_MEASURABLE_ON_SUBINTERVALS] THEN + SIMP_TAC[LEBESGUE_MEASURABLE_IFF_MEASURABLE; + BOUNDED_INTER; BOUNDED_INTERVAL] THEN + GEOM_TRANSLATE_TAC[]);; + +add_translation_invariants [LEBESGUE_MEASURABLE_TRANSLATION];; + +let LEBESGUE_MEASURABLE_LINEAR_IMAGE_EQ = prove + (`!f:real^N->real^N s. + linear f /\ (!x y. f x = f y ==> x = y) + ==> (lebesgue_measurable (IMAGE f s) <=> + lebesgue_measurable s)`, + REPEAT GEN_TAC THEN DISCH_TAC THEN + FIRST_ASSUM(MP_TAC o MATCH_MP LINEAR_INJECTIVE_IMP_SURJECTIVE) THEN + POP_ASSUM MP_TAC THEN REWRITE_TAC[IMP_IMP; GSYM CONJ_ASSOC] THEN + DISCH_TAC THEN + FIRST_ASSUM(X_CHOOSE_THEN `g:real^N->real^N` STRIP_ASSUME_TAC o + MATCH_MP LINEAR_BIJECTIVE_LEFT_RIGHT_INVERSE) THEN + REWRITE_TAC[lebesgue_measurable] THEN MP_TAC(ISPECL + [`g:real^N->real^N`; `indicator(s:real^N->bool)`; `(:real^N)`] + MEASURABLE_ON_LINEAR_IMAGE_EQ) THEN + ASM_REWRITE_TAC[indicator; o_DEF] THEN + ANTS_TAC THENL [ASM_MESON_TAC[]; MATCH_MP_TAC EQ_IMP] THEN + BINOP_TAC THENL + [AP_THM_TAC THEN AP_TERM_TAC THEN ABS_TAC THEN + AP_THM_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN ASM SET_TAC[]; + AP_TERM_TAC THEN ASM SET_TAC[]]);; + +add_linear_invariants [LEBESGUE_MEASURABLE_LINEAR_IMAGE_EQ];; + +(* ------------------------------------------------------------------------- *) +(* Various common equivalent forms of function measurability. *) +(* ------------------------------------------------------------------------- *) + +let (MEASURABLE_ON_PREIMAGE_OPEN_HALFSPACE_COMPONENT_LT, + MEASURABLE_ON_SIMPLE_FUNCTION_LIMIT) = (CONJ_PAIR o prove) + (`(!f:real^M->real^N. + f measurable_on (:real^M) <=> + !a k. 1 <= k /\ k <= dimindex(:N) + ==> lebesgue_measurable {x | f(x)$k < a}) /\ + (!f:real^M->real^N. + f measurable_on (:real^M) <=> + ?g. (!n. (g n) measurable_on (:real^M)) /\ + (!n. FINITE(IMAGE (g n) (:real^M))) /\ + (!x. ((\n. g n x) --> f x) sequentially))`, + let lemma0 = prove + (`!f:real^M->real^1 n m. + integer m /\ + m / &2 pow n <= drop(f x) /\ + drop(f x) < (m + &1) / &2 pow n /\ + abs(m) <= &2 pow (2 * n) + ==> vsum {k | integer k /\ abs(k) <= &2 pow (2 * n)} + (\k. k / &2 pow n % + indicator {y:real^M | k / &2 pow n <= drop(f y) /\ + drop(f y) < (k + &1) / &2 pow n} + x) = + lift(m / &2 pow n)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC EQ_TRANS THEN + EXISTS_TAC + `vsum {m} (\k. k / &2 pow n % + indicator {y:real^M | k / &2 pow n <= drop(f y) /\ + drop(f y) < (k + &1) / &2 pow n} + x)` THEN + CONJ_TAC THENL + [MATCH_MP_TAC VSUM_SUPERSET THEN + ASM_REWRITE_TAC[SING_SUBSET; IN_ELIM_THM; IN_SING] THEN + X_GEN_TAC `k:real` THEN STRIP_TAC THEN + REWRITE_TAC[VECTOR_MUL_EQ_0] THEN DISJ2_TAC THEN + ASM_REWRITE_TAC[indicator; IN_ELIM_THM] THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC(TAUT `F ==> p`) THEN + UNDISCH_TAC `~(k:real = m)` THEN ASM_SIMP_TAC[REAL_EQ_INTEGERS] THEN + POP_ASSUM_LIST(MP_TAC o end_itlist CONJ) THEN + SIMP_TAC[REAL_LE_LDIV_EQ; REAL_LT_RDIV_EQ; REAL_LT_POW2] THEN + REAL_ARITH_TAC; + ASM_REWRITE_TAC[VSUM_SING; indicator; IN_ELIM_THM; LIFT_EQ_CMUL]]) in + let lemma1 = prove + (`!f:real^M->real^1. + (!a b. lebesgue_measurable {x | a <= drop(f x) /\ drop(f x) < b}) + ==> ?g. (!n. (g n) measurable_on (:real^M)) /\ + (!n. FINITE(IMAGE (g n) (:real^M))) /\ + (!x. ((\n. g n x) --> f x) sequentially)`, + REPEAT STRIP_TAC THEN + EXISTS_TAC + `\n x. vsum {k | integer k /\ abs(k) <= &2 pow (2 * n)} + (\k. k / &2 pow n % + indicator {y:real^M | k / &2 pow n <= drop(f y) /\ + drop(f y) < (k + &1) / &2 pow n} + x)` THEN + REWRITE_TAC[] THEN REPEAT CONJ_TAC THENL + [X_GEN_TAC `n:num` THEN MATCH_MP_TAC MEASURABLE_ON_VSUM THEN + REWRITE_TAC[REAL_ABS_BOUNDS; FINITE_INTSEG; IN_ELIM_THM] THEN + GEN_TAC THEN STRIP_TAC THEN MATCH_MP_TAC MEASURABLE_ON_CMUL THEN + ASM_REWRITE_TAC[GSYM lebesgue_measurable; ETA_AX]; + X_GEN_TAC `n:num` THEN + MATCH_MP_TAC FINITE_SUBSET THEN + EXISTS_TAC `IMAGE (\k. lift(k / &2 pow n)) + {k | integer k /\ abs(k) <= &2 pow (2 * n)}` THEN + CONJ_TAC THENL + [SIMP_TAC[REAL_ABS_BOUNDS; FINITE_INTSEG; FINITE_IMAGE]; + ALL_TAC] THEN + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; IN_UNIV] THEN + X_GEN_TAC `x:real^M` THEN REWRITE_TAC[IN_IMAGE] THEN + ASM_CASES_TAC + `?k. integer k /\ abs k <= &2 pow (2 * n) /\ + k / &2 pow n <= drop(f(x:real^M)) /\ + drop(f x) < (k + &1) / &2 pow n` + THENL + [FIRST_X_ASSUM(fun th -> MP_TAC th THEN MATCH_MP_TAC MONO_EXISTS) THEN + X_GEN_TAC `m:real` THEN STRIP_TAC THEN ASM_REWRITE_TAC[IN_ELIM_THM] THEN + MATCH_MP_TAC lemma0 THEN ASM_REWRITE_TAC[]; + EXISTS_TAC `&0` THEN + ASM_REWRITE_TAC[IN_ELIM_THM; INTEGER_CLOSED; REAL_ABS_NUM] THEN + SIMP_TAC[REAL_POW_LE; REAL_POS; real_div; REAL_MUL_LZERO] THEN + REWRITE_TAC[LIFT_NUM; GSYM real_div] THEN + MATCH_MP_TAC VSUM_EQ_0 THEN + X_GEN_TAC `k:real` THEN REWRITE_TAC[IN_ELIM_THM] THEN STRIP_TAC THEN + REWRITE_TAC[VECTOR_MUL_EQ_0] THEN DISJ2_TAC THEN + REWRITE_TAC[indicator; IN_ELIM_THM] THEN ASM_MESON_TAC[]]; + X_GEN_TAC `x:real^M` THEN REWRITE_TAC[LIM_SEQUENTIALLY] THEN + MP_TAC(ISPECL [`&2`; `abs(drop((f:real^M->real^1) x))`] + REAL_ARCH_POW) THEN + ANTS_TAC THENL [REAL_ARITH_TAC; DISCH_THEN(X_CHOOSE_TAC `N1:num`)] THEN + X_GEN_TAC `e:real` THEN DISCH_TAC THEN + MP_TAC(ISPECL [`inv(&2)`; `e:real`] REAL_ARCH_POW_INV) THEN + REWRITE_TAC[REAL_POW_INV] THEN + ANTS_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN + DISCH_THEN(X_CHOOSE_THEN `N2:num` MP_TAC) THEN + SUBST1_TAC(REAL_ARITH `inv(&2 pow N2) = &1 / &2 pow N2`) THEN + SIMP_TAC[REAL_LT_LDIV_EQ; REAL_LT_POW2] THEN DISCH_TAC THEN + EXISTS_TAC `MAX N1 N2` THEN X_GEN_TAC `n:num` THEN DISCH_TAC THEN + ABBREV_TAC `m = floor(&2 pow n * drop(f(x:real^M)))` THEN + SUBGOAL_THEN `dist(lift(m / &2 pow n),(f:real^M->real^1) x) < e` + MP_TAC THENL + [REWRITE_TAC[DIST_REAL; GSYM drop; LIFT_DROP] THEN + MATCH_MP_TAC REAL_LT_LCANCEL_IMP THEN EXISTS_TAC `abs(&2 pow n)` THEN + REWRITE_TAC[GSYM REAL_ABS_MUL; REAL_SUB_LDISTRIB] THEN + SIMP_TAC[REAL_DIV_LMUL; REAL_POW_EQ_0; GSYM REAL_ABS_NZ; + REAL_OF_NUM_EQ; ARITH] THEN + MATCH_MP_TAC(REAL_ARITH + `x <= y /\ y < x + &1 /\ &1 <= z ==> abs(x - y) < z`) THEN + EXPAND_TAC "m" THEN REWRITE_TAC[FLOOR] THEN + ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `e * &2 pow N2` THEN + ASM_SIMP_TAC[REAL_LT_IMP_LE; REAL_ABS_POW; REAL_ABS_NUM] THEN + MATCH_MP_TAC REAL_LE_LMUL THEN ASM_SIMP_TAC[REAL_LT_IMP_LE]; + MATCH_MP_TAC(NORM_ARITH + `x:real^1 = y ==> dist(y,z) < e ==> dist(x,z) < e`) THEN + MATCH_MP_TAC lemma0 THEN + SIMP_TAC[REAL_LE_LDIV_EQ; REAL_LT_RDIV_EQ; REAL_LT_POW2] THEN + ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN + EXPAND_TAC "m" THEN REWRITE_TAC[FLOOR] THEN + SIMP_TAC[REAL_ABS_BOUNDS; REAL_LE_FLOOR; REAL_FLOOR_LE; + INTEGER_CLOSED] THEN + MATCH_MP_TAC(REAL_ARITH `abs(x) <= e ==> --e <= x /\ x - &1 < e`) THEN + REWRITE_TAC[MULT_2; REAL_POW_ADD; REAL_ABS_MUL; REAL_ABS_POW; + REAL_ABS_NUM] THEN + MATCH_MP_TAC REAL_LE_LMUL THEN SIMP_TAC[REAL_POW_LE; REAL_POS] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH + `x < e ==> e <= d ==> x <= d`))] THEN + MATCH_MP_TAC REAL_POW_MONO THEN CONV_TAC REAL_RAT_REDUCE_CONV THEN + ASM_ARITH_TAC]) in + MATCH_MP_TAC(MESON[] + `(!f. P f ==> Q f) /\ (!f. Q f ==> R f) /\ (!f. R f ==> P f) + ==> (!f. P f <=> Q f) /\ (!f. P f <=> R f)`) THEN + REPEAT CONJ_TAC THENL + [X_GEN_TAC `g:real^M->real^N` THEN DISCH_TAC THEN + ABBREV_TAC `f:real^M->real^N = \x. --(g x)` THEN + SUBGOAL_THEN `(f:real^M->real^N) measurable_on (:real^M)` ASSUME_TAC THENL + [EXPAND_TAC "f" THEN MATCH_MP_TAC MEASURABLE_ON_NEG THEN ASM_SIMP_TAC[]; + ALL_TAC] THEN + ONCE_REWRITE_TAC[GSYM REAL_LT_NEG2] THEN X_GEN_TAC `a:real` THEN + SPEC_TAC(`--a:real`,`a:real`) THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [FUN_EQ_THM]) THEN + SIMP_TAC[GSYM VECTOR_NEG_COMPONENT] THEN DISCH_THEN(K ALL_TAC) THEN + REPEAT STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `k:num` o + GEN_REWRITE_RULE I [MEASURABLE_ON_COMPONENTWISE]) THEN + ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN + MP_TAC(GEN `d:real` (ISPECL + [`\x. lift ((f:real^M->real^N) x$k)`; + `(\x. lift a + (lambda i. d)):real^M->real^1`; + `(:real^M)`] MEASURABLE_ON_MIN)) THEN + ASM_REWRITE_TAC[MEASURABLE_ON_CONST] THEN + DISCH_THEN(fun th -> + MP_TAC(GEN `n:num` (ISPEC `&n + &1` (MATCH_MP MEASURABLE_ON_CMUL + (MATCH_MP MEASURABLE_ON_SUB + (CONJ (SPEC `inv(&n + &1)` th) (SPEC `&0` th))))))) THEN + REWRITE_TAC[lebesgue_measurable; indicator] THEN + DISCH_THEN(MATCH_MP_TAC o MATCH_MP (ONCE_REWRITE_RULE[IMP_CONJ] + MEASURABLE_ON_LIMIT)) THEN + EXISTS_TAC `{}:real^M->bool` THEN + REWRITE_TAC[NEGLIGIBLE_EMPTY; IN_DIFF; IN_UNIV; NOT_IN_EMPTY] THEN + X_GEN_TAC `x:real^M` THEN REWRITE_TAC[IN_ELIM_THM] THEN + SIMP_TAC[LIM_SEQUENTIALLY; DIST_REAL; VECTOR_MUL_COMPONENT; + VECTOR_ADD_COMPONENT; VECTOR_SUB_COMPONENT; + LAMBDA_BETA; DIMINDEX_1; ARITH] THEN + REWRITE_TAC[GSYM drop; LIFT_DROP; REAL_ADD_RID] THEN + SIMP_TAC[REAL_LT_INV_EQ; REAL_ARITH `&0 < &n + &1`; REAL_ARITH + `&0 < d ==> (min x (a + d) - min x a = + if x <= a then &0 else if x <= a + d then x - a else d)`] THEN + X_GEN_TAC `e:real` THEN DISCH_TAC THEN + ASM_CASES_TAC `a < (f:real^M->real^N) x $k` THEN ASM_REWRITE_TAC[] THEN + ASM_REWRITE_TAC[REAL_ARITH `(x:real^N)$k <= a <=> ~(a < x$k)`] THEN + ASM_REWRITE_TAC[REAL_MUL_RZERO; DROP_VEC; REAL_SUB_REFL; REAL_ABS_NUM] THEN + MP_TAC(SPEC `((f:real^M->real^N) x)$k - a` REAL_ARCH_INV) THEN + ASM_REWRITE_TAC[REAL_SUB_LT] 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 `a + inv(&n + &1) < ((f:real^M->real^N) x)$k` ASSUME_TAC THENL + [FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH + `N < f - a ==> n <= N ==> a + n < f`)) 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; + ASM_SIMP_TAC[REAL_MUL_RINV; REAL_ARITH `~(&n + &1 = &0)`] THEN + ASM_REAL_ARITH_TAC]; + REPEAT STRIP_TAC THEN + SUBGOAL_THEN + `!k. 1 <= k /\ k <= dimindex(:N) + ==> ?g. (!n. (g n) measurable_on (:real^M)) /\ + (!n. FINITE(IMAGE (g n) (:real^M))) /\ + (!x. ((\n. g n x) --> lift((f x:real^N)$k)) sequentially)` + MP_TAC THENL + [REPEAT STRIP_TAC THEN MATCH_MP_TAC lemma1 THEN + ASM_SIMP_TAC[LIFT_DROP] THEN + MAP_EVERY X_GEN_TAC [`a:real`; `b:real`] THEN + REWRITE_TAC[SET_RULE `{x | P x /\ Q x} = {x | Q x} DIFF {x | ~P x}`] THEN + MATCH_MP_TAC LEBESGUE_MEASURABLE_DIFF THEN + ASM_SIMP_TAC[REAL_NOT_LE]; + GEN_REWRITE_TAC (LAND_CONV o BINDER_CONV) [RIGHT_IMP_EXISTS_THM]] THEN + REWRITE_TAC[SKOLEM_THM] THEN + DISCH_THEN(X_CHOOSE_THEN `g:num->num->real^M->real^1` MP_TAC) THEN + REWRITE_TAC[TAUT `a ==> b /\ c <=> (a ==> b) /\ (a ==> c)`] THEN + REWRITE_TAC[FORALL_AND_THM] THEN STRIP_TAC THEN + EXISTS_TAC + `\n x. (lambda k. drop((g:num->num->real^M->real^1) k n x)):real^N` THEN + REWRITE_TAC[] THEN REPEAT CONJ_TAC THENL + [X_GEN_TAC `n:num` THEN ONCE_REWRITE_TAC[MEASURABLE_ON_COMPONENTWISE] THEN + X_GEN_TAC `k:num` THEN STRIP_TAC THEN + ASM_SIMP_TAC[LAMBDA_BETA; LIFT_DROP; ETA_AX]; + X_GEN_TAC `n:num` THEN MATCH_MP_TAC FINITE_SUBSET THEN + EXISTS_TAC `{x:real^N | !i. 1 <= i /\ i <= dimindex(:N) + ==> lift(x$i) IN IMAGE (g i (n:num)) (:real^M)}` THEN + ASM_SIMP_TAC[GSYM IN_IMAGE_LIFT_DROP; SET_RULE `{x | x IN s} = s`; + FINITE_IMAGE; FINITE_CART] THEN + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; IN_ELIM_THM; IN_UNIV] THEN + SIMP_TAC[IN_IMAGE; IN_UNIV; LAMBDA_BETA; DROP_EQ] THEN MESON_TAC[]; + X_GEN_TAC `x:real^M` THEN ONCE_REWRITE_TAC[LIM_COMPONENTWISE_LIFT] THEN + X_GEN_TAC `k:num` THEN STRIP_TAC THEN + ASM_SIMP_TAC[LAMBDA_BETA; LIFT_DROP; ETA_AX]]; + X_GEN_TAC `f:real^M->real^N` THEN + DISCH_THEN(X_CHOOSE_THEN `g:num->real^M->real^N` STRIP_ASSUME_TAC) THEN + MATCH_MP_TAC MEASURABLE_ON_LIMIT THEN + MAP_EVERY EXISTS_TAC [`g:num->real^M->real^N`; `{}:real^M->bool`] THEN + ASM_REWRITE_TAC[NEGLIGIBLE_EMPTY]]);; + +let MEASURABLE_ON_PREIMAGE_OPEN_HALFSPACE_COMPONENT_GE = prove + (`!f:real^M->real^N. + f measurable_on (:real^M) <=> + !a k. 1 <= k /\ k <= dimindex(:N) + ==> lebesgue_measurable {x | f(x)$k >= a}`, + GEN_TAC THEN REWRITE_TAC[REAL_ARITH `x >= a <=> ~(x < a)`] THEN + REWRITE_TAC[SET_RULE `{x | ~P x} = UNIV DIFF {x | P x}`] THEN + REWRITE_TAC[LEBESGUE_MEASURABLE_COMPL] THEN + REWRITE_TAC[MEASURABLE_ON_PREIMAGE_OPEN_HALFSPACE_COMPONENT_LT]);; + +let MEASURABLE_ON_PREIMAGE_OPEN_HALFSPACE_COMPONENT_GT = prove + (`!f:real^M->real^N. + f measurable_on (:real^M) <=> + !a k. 1 <= k /\ k <= dimindex(:N) + ==> lebesgue_measurable {x | f(x)$k > a}`, + GEN_TAC THEN GEN_REWRITE_TAC LAND_CONV [GSYM MEASURABLE_ON_NEG_EQ] THEN + REWRITE_TAC[MEASURABLE_ON_PREIMAGE_OPEN_HALFSPACE_COMPONENT_LT] THEN + GEN_REWRITE_TAC LAND_CONV + [MESON[REAL_NEG_NEG] `(!x. P x) <=> (!x:real. P(--x))`] THEN + REWRITE_TAC[real_gt; VECTOR_NEG_COMPONENT; REAL_LT_NEG2]);; + +let MEASURABLE_ON_PREIMAGE_OPEN_HALFSPACE_COMPONENT_LE = prove + (`!f:real^M->real^N. + f measurable_on (:real^M) <=> + !a k. 1 <= k /\ k <= dimindex(:N) + ==> lebesgue_measurable {x | f(x)$k <= a}`, + GEN_TAC THEN REWRITE_TAC[REAL_ARITH `x <= a <=> ~(x > a)`] THEN + REWRITE_TAC[SET_RULE `{x | ~P x} = UNIV DIFF {x | P x}`] THEN + REWRITE_TAC[LEBESGUE_MEASURABLE_COMPL] THEN + REWRITE_TAC[MEASURABLE_ON_PREIMAGE_OPEN_HALFSPACE_COMPONENT_GT]);; + +let (MEASURABLE_ON_PREIMAGE_OPEN_INTERVAL, + MEASURABLE_ON_PREIMAGE_OPEN) = (CONJ_PAIR o prove) + (`(!f:real^M->real^N. + f measurable_on (:real^M) <=> + !a b. lebesgue_measurable {x | f(x) IN interval(a,b)}) /\ + (!f:real^M->real^N. + f measurable_on (:real^M) <=> + !t. open t ==> lebesgue_measurable {x | f(x) IN t})`, + let ulemma = prove + (`{x | f x IN UNIONS D} = UNIONS {{x | f(x) IN s} | s IN D}`, + REWRITE_TAC[UNIONS_GSPEC] THEN SET_TAC[]) in + MATCH_MP_TAC(MESON[] + `(!f. P f ==> Q f) /\ (!f. Q f ==> R f) /\ (!f. R f ==> P f) + ==> (!f. P f <=> Q f) /\ (!f. P f <=> R f)`) THEN + REPEAT CONJ_TAC THENL + [REPEAT STRIP_TAC THEN SUBGOAL_THEN + `{x | (f:real^M->real^N) x IN interval(a,b)} = + INTERS {{x | a$k < f(x)$k} | k IN 1..dimindex(:N)} INTER + INTERS {{x | (--b)$k < --(f(x))$k} | k IN 1..dimindex(:N)}` + SUBST1_TAC THENL + [REWRITE_TAC[IN_INTERVAL; GSYM IN_NUMSEG] THEN + REWRITE_TAC[VECTOR_NEG_COMPONENT; REAL_LT_NEG2] THEN + REWRITE_TAC[INTERS_GSPEC] THEN SET_TAC[]; + MATCH_MP_TAC LEBESGUE_MEASURABLE_INTER THEN + CONJ_TAC THEN MATCH_MP_TAC LEBESGUE_MEASURABLE_INTERS THEN + SIMP_TAC[SIMPLE_IMAGE; FORALL_IN_IMAGE; FINITE_IMAGE; FINITE_NUMSEG] THEN + REWRITE_TAC[IN_NUMSEG] THEN REPEAT STRIP_TAC THENL + [FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I + [MEASURABLE_ON_PREIMAGE_OPEN_HALFSPACE_COMPONENT_GT]); + FIRST_X_ASSUM(MP_TAC o MATCH_MP MEASURABLE_ON_NEG) THEN + REWRITE_TAC[MEASURABLE_ON_PREIMAGE_OPEN_HALFSPACE_COMPONENT_GT]] THEN + ASM_SIMP_TAC[real_gt]]; + REPEAT STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o MATCH_MP OPEN_COUNTABLE_UNION_OPEN_INTERVALS) THEN + DISCH_THEN(X_CHOOSE_THEN `D:(real^N->bool)->bool` STRIP_ASSUME_TAC) THEN + FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN ONCE_REWRITE_TAC[ulemma] THEN + MATCH_MP_TAC LEBESGUE_MEASURABLE_COUNTABLE_UNIONS THEN + ASM_SIMP_TAC[SIMPLE_IMAGE; COUNTABLE_IMAGE; FORALL_IN_IMAGE] THEN + X_GEN_TAC `i:real^N->bool` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `i:real^N->bool`) THEN + ASM_REWRITE_TAC[] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + ASM_SIMP_TAC[LEFT_IMP_EXISTS_THM]; + REPEAT STRIP_TAC THEN + REWRITE_TAC[MEASURABLE_ON_PREIMAGE_OPEN_HALFSPACE_COMPONENT_LT] THEN + REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[SET_RULE + `{x:real^M | (f x)$k < a} = {x | f x IN {y:real^N | y$k < a}}`] THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN + REWRITE_TAC[OPEN_HALFSPACE_COMPONENT_LT]]);; + +let MEASURABLE_ON_PREIMAGE_CLOSED = prove + (`!f:real^M->real^N. + f measurable_on (:real^M) <=> + !t. closed t ==> lebesgue_measurable {x | f(x) IN t}`, + GEN_TAC THEN ONCE_REWRITE_TAC[GSYM LEBESGUE_MEASURABLE_COMPL; closed] THEN + REWRITE_TAC[SET_RULE + `UNIV DIFF {x | f x IN t} = {x | f x IN (UNIV DIFF t)}`] THEN + REWRITE_TAC[MESON[SET_RULE `UNIV DIFF (UNIV DIFF s) = s`] + `(!s. P(UNIV DIFF s)) <=> (!s. P s)`] THEN + REWRITE_TAC[MEASURABLE_ON_PREIMAGE_OPEN]);; + +let MEASURABLE_ON_PREIMAGE_CLOSED_INTERVAL = prove + (`!f:real^M->real^N. + f measurable_on (:real^M) <=> + !a b. lebesgue_measurable {x | f(x) IN interval[a,b]}`, + let ulemma = prove + (`{x | f x IN UNIONS D} = UNIONS {{x | f(x) IN s} | s IN D}`, + REWRITE_TAC[UNIONS_GSPEC] THEN SET_TAC[]) in + GEN_TAC THEN EQ_TAC THENL + [SIMP_TAC[MEASURABLE_ON_PREIMAGE_CLOSED; CLOSED_INTERVAL]; DISCH_TAC] THEN + REWRITE_TAC[MEASURABLE_ON_PREIMAGE_OPEN] THEN REPEAT STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o MATCH_MP OPEN_COUNTABLE_UNION_CLOSED_INTERVALS) THEN + DISCH_THEN(X_CHOOSE_THEN `D:(real^N->bool)->bool` STRIP_ASSUME_TAC) THEN + FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN ONCE_REWRITE_TAC[ulemma] THEN + MATCH_MP_TAC LEBESGUE_MEASURABLE_COUNTABLE_UNIONS THEN + ASM_SIMP_TAC[SIMPLE_IMAGE; COUNTABLE_IMAGE; FORALL_IN_IMAGE] THEN + X_GEN_TAC `i:real^N->bool` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `i:real^N->bool`) THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + ASM_SIMP_TAC[LEFT_IMP_EXISTS_THM]);; + +let LEBESGUE_MEASURABLE_PREIMAGE_OPEN = prove + (`!f:real^M->real^N t. + f measurable_on (:real^M) /\ open t + ==> lebesgue_measurable {x | f(x) IN t}`, + SIMP_TAC[MEASURABLE_ON_PREIMAGE_OPEN]);; + +let LEBESGUE_MEASURABLE_PREIMAGE_CLOSED = prove + (`!f:real^M->real^N t. + f measurable_on (:real^M) /\ closed t + ==> lebesgue_measurable {x | f(x) IN t}`, + SIMP_TAC[MEASURABLE_ON_PREIMAGE_CLOSED]);; + +(* ------------------------------------------------------------------------- *) +(* More connections with measure where Lebesgue measurability is useful. *) +(* ------------------------------------------------------------------------- *) + +let MEASURABLE_LEGESGUE_MEASURABLE_SUBSET = prove + (`!s t:real^N->bool. + lebesgue_measurable s /\ measurable t /\ s SUBSET t + ==> measurable s`, + REWRITE_TAC[lebesgue_measurable; MEASURABLE_INTEGRABLE] THEN + REWRITE_TAC[indicator] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC MEASURABLE_BOUNDED_BY_INTEGRABLE_IMP_INTEGRABLE THEN + EXISTS_TAC `(\x. if x IN t then vec 1 else vec 0):real^N->real^1` THEN + ASM_REWRITE_TAC[IN_UNIV] THEN GEN_TAC THEN + REPEAT(COND_CASES_TAC THEN + ASM_REWRITE_TAC[DROP_VEC; NORM_REAL; GSYM drop]) THEN + REWRITE_TAC[REAL_ABS_NUM; REAL_LE_REFL; REAL_POS] THEN ASM SET_TAC[]);; + +let MEASURABLE_LEGESGUE_MEASURABLE_INTER_MEASURABLE = prove + (`!s t:real^N->bool. + lebesgue_measurable s /\ measurable t ==> measurable(s INTER t)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC MEASURABLE_LEGESGUE_MEASURABLE_SUBSET THEN + EXISTS_TAC `t:real^N->bool` THEN + ASM_SIMP_TAC[LEBESGUE_MEASURABLE_INTER; MEASURABLE_IMP_LEBESGUE_MEASURABLE; + INTER_SUBSET]);; + +let MEASURABLE_MEASURABLE_INTER_LEGESGUE_MEASURABLE = prove + (`!s t:real^N->bool. + measurable s /\ lebesgue_measurable t ==> measurable(s INTER t)`, + MESON_TAC[INTER_COMM; MEASURABLE_LEGESGUE_MEASURABLE_INTER_MEASURABLE]);; + +let MEASURABLE_INTER_HALFSPACE_LE = prove + (`!s a i. measurable s ==> measurable(s INTER {x:real^N | x$i <= a})`, + REPEAT GEN_TAC THEN + SUBGOAL_THEN `?k. 1 <= k /\ k <= dimindex(:N) /\ !z:real^N. z$i = z$k` + CHOOSE_TAC THENL [REWRITE_TAC[FINITE_INDEX_INRANGE]; ALL_TAC] THEN + DISCH_TAC THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC MEASURABLE_MEASURABLE_INTER_LEGESGUE_MEASURABLE THEN + ASM_SIMP_TAC[CLOSED_HALFSPACE_COMPONENT_LE; LEBESGUE_MEASURABLE_CLOSED]);; + +let MEASURABLE_INTER_HALFSPACE_GE = prove + (`!s a i. measurable s ==> measurable(s INTER {x:real^N | x$i >= a})`, + REPEAT GEN_TAC THEN + SUBGOAL_THEN `?k. 1 <= k /\ k <= dimindex(:N) /\ !z:real^N. z$i = z$k` + CHOOSE_TAC THENL [REWRITE_TAC[FINITE_INDEX_INRANGE]; ALL_TAC] THEN + DISCH_TAC THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC MEASURABLE_MEASURABLE_INTER_LEGESGUE_MEASURABLE THEN + ASM_SIMP_TAC[CLOSED_HALFSPACE_COMPONENT_GE; LEBESGUE_MEASURABLE_CLOSED]);; + +let MEASURABLE_MEASURABLE_DIFF_LEGESGUE_MEASURABLE = prove + (`!s t. measurable s /\ lebesgue_measurable t ==> measurable(s DIFF t)`, + REPEAT STRIP_TAC THEN + ONCE_REWRITE_TAC[SET_RULE `s DIFF t = s INTER (UNIV DIFF t)`] THEN + ASM_SIMP_TAC[MEASURABLE_MEASURABLE_INTER_LEGESGUE_MEASURABLE; + LEBESGUE_MEASURABLE_COMPL]);; + +(* ------------------------------------------------------------------------- *) +(* Localized variants of function measurability equivalents. *) +(* ------------------------------------------------------------------------- *) + +let [MEASURABLE_ON_LEBESGUE_MEASURABLE_PREIMAGE_CLOSED; + MEASURABLE_ON_LEBESGUE_MEASURABLE_PREIMAGE_CLOSED_INTERVAL; + MEASURABLE_ON_LEBESGUE_MEASURABLE_PREIMAGE_OPEN; + MEASURABLE_ON_LEBESGUE_MEASURABLE_PREIMAGE_OPEN_HALFSPACE_COMPONENT_GE; + MEASURABLE_ON_LEBESGUE_MEASURABLE_PREIMAGE_OPEN_HALFSPACE_COMPONENT_GT; + MEASURABLE_ON_LEBESGUE_MEASURABLE_PREIMAGE_OPEN_HALFSPACE_COMPONENT_LE; + MEASURABLE_ON_LEBESGUE_MEASURABLE_PREIMAGE_OPEN_HALFSPACE_COMPONENT_LT; + MEASURABLE_ON_LEBESGUE_MEASURABLE_PREIMAGE_OPEN_INTERVAL] = + (CONJUNCTS o prove) + (`(!f:real^M->real^N s. + lebesgue_measurable s + ==> (f measurable_on s <=> + !t. closed t ==> lebesgue_measurable {x | x IN s /\ f x IN t})) /\ + (!f:real^M->real^N s. + lebesgue_measurable s + ==> (f measurable_on s <=> + !a b. lebesgue_measurable {x | x IN s /\ f x IN interval[a,b]})) /\ + (!f:real^M->real^N s. + lebesgue_measurable s + ==> (f measurable_on s <=> + !t. open t ==> lebesgue_measurable {x | x IN s /\ f x IN t})) /\ + (!f:real^M->real^N s. + lebesgue_measurable s + ==> (f measurable_on s <=> + !a k. 1 <= k /\ k <= dimindex(:N) + ==> lebesgue_measurable {x | x IN s /\ (f x)$k >= a})) /\ + (!f:real^M->real^N s. + lebesgue_measurable s + ==> (f measurable_on s <=> + !a k. 1 <= k /\ k <= dimindex(:N) + ==> lebesgue_measurable {x | x IN s /\ (f x)$k > a})) /\ + (!f:real^M->real^N s. + lebesgue_measurable s + ==> (f measurable_on s <=> + !a k. 1 <= k /\ k <= dimindex(:N) + ==> lebesgue_measurable {x | x IN s /\ (f x)$k <= a})) /\ + (!f:real^M->real^N s. + lebesgue_measurable s + ==> (f measurable_on s <=> + !a k. 1 <= k /\ k <= dimindex(:N) + ==> lebesgue_measurable {x | x IN s /\ (f x)$k < a})) /\ + (!f:real^M->real^N s. + lebesgue_measurable s + ==> (f measurable_on s <=> + !a b. lebesgue_measurable {x | x IN s /\ f x IN interval(a,b)}))`, + let lemma = prove + (`!f s P. {x | P(if x IN s then f x else vec 0)} = + if P(vec 0) then s INTER {x | P(f x)} UNION ((:real^M) DIFF s) + else {x | x IN s /\ P(f x)}`, + REPEAT GEN_TAC THEN + COND_CASES_TAC THEN REPEAT(POP_ASSUM MP_TAC) THEN SET_TAC[]) in + ONCE_REWRITE_TAC[GSYM MEASURABLE_ON_UNIV] THEN REPEAT STRIP_TAC THENL + [REWRITE_TAC[MEASURABLE_ON_PREIMAGE_CLOSED]; + REWRITE_TAC[MEASURABLE_ON_PREIMAGE_CLOSED_INTERVAL]; + REWRITE_TAC[MEASURABLE_ON_PREIMAGE_OPEN]; + REWRITE_TAC[MEASURABLE_ON_PREIMAGE_OPEN_HALFSPACE_COMPONENT_GE]; + REWRITE_TAC[MEASURABLE_ON_PREIMAGE_OPEN_HALFSPACE_COMPONENT_GT]; + REWRITE_TAC[MEASURABLE_ON_PREIMAGE_OPEN_HALFSPACE_COMPONENT_LE]; + REWRITE_TAC[MEASURABLE_ON_PREIMAGE_OPEN_HALFSPACE_COMPONENT_LT]; + REWRITE_TAC[MEASURABLE_ON_PREIMAGE_OPEN_INTERVAL]] THEN + MP_TAC(ISPECL [`f:real^M->real^N`; `s:real^M->bool`] lemma) THEN + DISCH_THEN(fun th -> REWRITE_TAC[th]) THEN + REPEAT(AP_TERM_TAC THEN ABS_TAC) THEN + TRY(MATCH_MP_TAC(TAUT `(q <=> q') ==> (p ==> q <=> p ==> q')`)) THEN + COND_CASES_TAC THEN REWRITE_TAC[] THEN + REWRITE_TAC[SET_RULE `{x | x IN s /\ P x} = s INTER {x | P x}`] THEN + EQ_TAC THEN + ASM_SIMP_TAC[LEBESGUE_MEASURABLE_UNION; LEBESGUE_MEASURABLE_COMPL] THEN + UNDISCH_TAC `lebesgue_measurable(s:real^M->bool)` THEN + REWRITE_TAC[IMP_IMP] THEN + DISCH_THEN(MP_TAC o MATCH_MP LEBESGUE_MEASURABLE_INTER) THEN + MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN SET_TAC[]);; + +let LEBESGUE_MEASURABLE_LEBESGUE_MEASURABLE_PREIMAGE_OPEN = prove + (`!f:real^M->real^N s t. + f measurable_on s /\ lebesgue_measurable s /\ open t + ==> lebesgue_measurable {x | x IN s /\ f(x) IN t}`, + MESON_TAC[MEASURABLE_ON_LEBESGUE_MEASURABLE_PREIMAGE_OPEN]);; + +let LEBESGUE_MEASURABLE_LEBESGUE_MEASURABLE_PREIMAGE_CLOSED = prove + (`!f:real^M->real^N s t. + f measurable_on s /\ lebesgue_measurable s /\ closed t + ==> lebesgue_measurable {x | x IN s /\ f(x) IN t}`, + MESON_TAC[MEASURABLE_ON_LEBESGUE_MEASURABLE_PREIMAGE_CLOSED]);; + +let MEASURABLE_ON_LEBESGUE_MEASURABLE_PREIMAGE_OPEN_EQ = prove + (`!f:real^M->real^N s. + f measurable_on s /\ lebesgue_measurable s <=> + !t. open t ==> lebesgue_measurable {x | x IN s /\ f(x) IN t}`, + REPEAT GEN_TAC THEN EQ_TAC THEN + SIMP_TAC[LEBESGUE_MEASURABLE_LEBESGUE_MEASURABLE_PREIMAGE_OPEN] THEN + DISCH_THEN(fun th -> MP_TAC th THEN MP_TAC(SPEC `(:real^N)` th)) THEN + REWRITE_TAC[OPEN_UNIV; SET_RULE `{x | x IN s /\ f x IN UNIV} = s`] THEN + SIMP_TAC[MEASURABLE_ON_LEBESGUE_MEASURABLE_PREIMAGE_OPEN]);; + +let MEASURABLE_ON_LEBESGUE_MEASURABLE_PREIMAGE_CLOSED_EQ = prove + (`!f:real^M->real^N s. + f measurable_on s /\ lebesgue_measurable s <=> + !t. closed t ==> lebesgue_measurable {x | x IN s /\ f(x) IN t}`, + REPEAT GEN_TAC THEN EQ_TAC THEN + SIMP_TAC[LEBESGUE_MEASURABLE_LEBESGUE_MEASURABLE_PREIMAGE_CLOSED] THEN + DISCH_THEN(fun th -> MP_TAC th THEN MP_TAC(SPEC `(:real^N)` th)) THEN + REWRITE_TAC[CLOSED_UNIV; SET_RULE `{x | x IN s /\ f x IN UNIV} = s`] THEN + SIMP_TAC[MEASURABLE_ON_LEBESGUE_MEASURABLE_PREIMAGE_CLOSED]);; + +let [MEASURABLE_ON_MEASURABLE_PREIMAGE_CLOSED; + MEASURABLE_ON_MEASURABLE_PREIMAGE_CLOSED_INTERVAL; + MEASURABLE_ON_MEASURABLE_PREIMAGE_OPEN; + MEASURABLE_ON_MEASURABLE_PREIMAGE_OPEN_HALFSPACE_COMPONENT_GE; + MEASURABLE_ON_MEASURABLE_PREIMAGE_OPEN_HALFSPACE_COMPONENT_GT; + MEASURABLE_ON_MEASURABLE_PREIMAGE_OPEN_HALFSPACE_COMPONENT_LE; + MEASURABLE_ON_MEASURABLE_PREIMAGE_OPEN_HALFSPACE_COMPONENT_LT; + MEASURABLE_ON_MEASURABLE_PREIMAGE_OPEN_INTERVAL] = + (CONJUNCTS o prove) + (`(!f:real^M->real^N s. + measurable s + ==> (f measurable_on s <=> + !t. closed t ==> measurable {x | x IN s /\ f x IN t})) /\ + (!f:real^M->real^N s. + measurable s + ==> (f measurable_on s <=> + !a b. measurable {x | x IN s /\ f x IN interval[a,b]})) /\ + (!f:real^M->real^N s. + measurable s + ==> (f measurable_on s <=> + !t. open t ==> measurable {x | x IN s /\ f x IN t})) /\ + (!f:real^M->real^N s. + measurable s + ==> (f measurable_on s <=> + !a k. 1 <= k /\ k <= dimindex(:N) + ==> measurable {x | x IN s /\ (f x)$k >= a})) /\ + (!f:real^M->real^N s. + measurable s + ==> (f measurable_on s <=> + !a k. 1 <= k /\ k <= dimindex(:N) + ==> measurable {x | x IN s /\ (f x)$k > a})) /\ + (!f:real^M->real^N s. + measurable s + ==> (f measurable_on s <=> + !a k. 1 <= k /\ k <= dimindex(:N) + ==> measurable {x | x IN s /\ (f x)$k <= a})) /\ + (!f:real^M->real^N s. + measurable s + ==> (f measurable_on s <=> + !a k. 1 <= k /\ k <= dimindex(:N) + ==> measurable {x | x IN s /\ (f x)$k < a})) /\ + (!f:real^M->real^N s. + measurable s + ==> (f measurable_on s <=> + !a b. measurable {x | x IN s /\ f x IN interval(a,b)}))`, + REPEAT STRIP_TAC THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP MEASURABLE_IMP_LEBESGUE_MEASURABLE) THENL + [ASM_SIMP_TAC[MEASURABLE_ON_LEBESGUE_MEASURABLE_PREIMAGE_CLOSED]; + ASM_SIMP_TAC[MEASURABLE_ON_LEBESGUE_MEASURABLE_PREIMAGE_CLOSED_INTERVAL]; + ASM_SIMP_TAC[MEASURABLE_ON_LEBESGUE_MEASURABLE_PREIMAGE_OPEN]; + ASM_SIMP_TAC + [MEASURABLE_ON_LEBESGUE_MEASURABLE_PREIMAGE_OPEN_HALFSPACE_COMPONENT_GE]; + ASM_SIMP_TAC + [MEASURABLE_ON_LEBESGUE_MEASURABLE_PREIMAGE_OPEN_HALFSPACE_COMPONENT_GT]; + ASM_SIMP_TAC + [MEASURABLE_ON_LEBESGUE_MEASURABLE_PREIMAGE_OPEN_HALFSPACE_COMPONENT_LE]; + ASM_SIMP_TAC + [MEASURABLE_ON_LEBESGUE_MEASURABLE_PREIMAGE_OPEN_HALFSPACE_COMPONENT_LT]; + ASM_SIMP_TAC + [MEASURABLE_ON_LEBESGUE_MEASURABLE_PREIMAGE_OPEN_INTERVAL]] THEN + EQ_TAC THEN SIMP_TAC[MEASURABLE_IMP_LEBESGUE_MEASURABLE] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC MEASURABLE_LEGESGUE_MEASURABLE_SUBSET THEN + EXISTS_TAC `s:real^M->bool` THEN ASM_SIMP_TAC[] THEN SET_TAC[]);; + +let MEASURABLE_MEASURABLE_PREIMAGE_OPEN = prove + (`!f:real^M->real^N s t. + f measurable_on s /\ measurable s /\ open t + ==> measurable {x | x IN s /\ f(x) IN t}`, + MESON_TAC[MEASURABLE_ON_MEASURABLE_PREIMAGE_OPEN]);; + +let MEASURABLE_MEASURABLE_PREIMAGE_CLOSED = prove + (`!f:real^M->real^N s t. + f measurable_on s /\ measurable s /\ closed t + ==> measurable {x | x IN s /\ f(x) IN t}`, + MESON_TAC[MEASURABLE_ON_MEASURABLE_PREIMAGE_CLOSED]);; + +let MEASURABLE_ON_MEASURABLE_PREIMAGE_OPEN_EQ = prove + (`!f:real^M->real^N s. + f measurable_on s /\ measurable s <=> + !t. open t ==> measurable {x | x IN s /\ f(x) IN t}`, + REPEAT GEN_TAC THEN EQ_TAC THEN + SIMP_TAC[MEASURABLE_MEASURABLE_PREIMAGE_OPEN] THEN + DISCH_THEN(fun th -> MP_TAC th THEN MP_TAC(SPEC `(:real^N)` th)) THEN + REWRITE_TAC[OPEN_UNIV; SET_RULE `{x | x IN s /\ f x IN UNIV} = s`] THEN + SIMP_TAC[MEASURABLE_ON_MEASURABLE_PREIMAGE_OPEN]);; + +let MEASURABLE_ON_MEASURABLE_PREIMAGE_CLOSED_EQ = prove + (`!f:real^M->real^N s. + f measurable_on s /\ measurable s <=> + !t. closed t ==> measurable {x | x IN s /\ f(x) IN t}`, + REPEAT GEN_TAC THEN EQ_TAC THEN + SIMP_TAC[MEASURABLE_MEASURABLE_PREIMAGE_CLOSED] THEN + DISCH_THEN(fun th -> MP_TAC th THEN MP_TAC(SPEC `(:real^N)` th)) THEN + REWRITE_TAC[CLOSED_UNIV; SET_RULE `{x | x IN s /\ f x IN UNIV} = s`] THEN + SIMP_TAC[MEASURABLE_ON_MEASURABLE_PREIMAGE_CLOSED]);; + +(* ------------------------------------------------------------------------- *) +(* Regularity properties and Steinhaus, this time for Lebesgue measure. *) +(* ------------------------------------------------------------------------- *) + +let LEBESGUE_MEASURABLE_OUTER_OPEN = prove + (`!s:real^N->bool e. + lebesgue_measurable s /\ &0 < e + ==> ?t. open t /\ + s SUBSET t /\ + measurable(t DIFF s) /\ + measure(t DIFF s) < e`, + REPEAT STRIP_TAC THEN MP_TAC(GEN `n:num` + (ISPECL [`s INTER ball(vec 0:real^N,&2 pow n)`; + `e / &4 / &2 pow n`] + MEASURABLE_OUTER_OPEN)) THEN + ASM_SIMP_TAC[MEASURABLE_LEGESGUE_MEASURABLE_INTER_MEASURABLE; REAL_LT_DIV; + MEASURABLE_BALL; REAL_LT_INV_EQ; REAL_LT_POW2; + REAL_ARITH `&0 < e / &4 <=> &0 < e`] THEN + REWRITE_TAC[SKOLEM_THM; LEFT_IMP_EXISTS_THM; FORALL_AND_THM] THEN + X_GEN_TAC `t:num->real^N->bool` THEN STRIP_TAC THEN + EXISTS_TAC `UNIONS(IMAGE t (:num)):real^N->bool` THEN + ASM_SIMP_TAC[OPEN_UNIONS; FORALL_IN_IMAGE] THEN CONJ_TAC THENL + [REWRITE_TAC[SUBSET; UNIONS_IMAGE; IN_ELIM_THM; IN_UNIV] THEN + X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN + MP_TAC(ISPEC `norm(x:real^N)` REAL_ARCH_POW2) THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `n:num` THEN + DISCH_TAC THEN RULE_ASSUM_TAC(REWRITE_RULE[SUBSET]) THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_SIMP_TAC[IN_BALL_0; IN_INTER]; + REWRITE_TAC[UNIONS_DIFF; SET_RULE + `{f x | x IN IMAGE g s} = {f(g(x)) | x IN s}`] THEN + MATCH_MP_TAC(MESON[REAL_ARITH `&0 < e /\ x <= e / &2 ==> x < e`] + `&0 < e /\ P /\ x <= e / &2 ==> P /\ x < e`) THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC MEASURE_COUNTABLE_UNIONS_LE THEN + ASM_SIMP_TAC[MEASURABLE_MEASURABLE_DIFF_LEGESGUE_MEASURABLE] THEN + X_GEN_TAC `n:num` THEN MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `sum(0..n) (\i. e / &4 / &2 pow i)` THEN CONJ_TAC THENL + [MATCH_MP_TAC SUM_LE_NUMSEG THEN X_GEN_TAC `i:num` THEN STRIP_TAC THEN + MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `measure(t i DIFF (s INTER ball(vec 0:real^N,&2 pow i)))` THEN + REWRITE_TAC[] THEN CONJ_TAC THENL + [MATCH_MP_TAC MEASURE_SUBSET THEN + ASM_SIMP_TAC[MEASURABLE_MEASURABLE_DIFF_LEGESGUE_MEASURABLE; + MEASURABLE_INTER; MEASURABLE_BALL; LEBESGUE_MEASURABLE_INTER; + MEASURABLE_IMP_LEBESGUE_MEASURABLE] THEN + SET_TAC[]; + ASM_SIMP_TAC[MEASURE_DIFF_SUBSET; MEASURABLE_DIFF; MEASURABLE_BALL; + MEASURABLE_LEGESGUE_MEASURABLE_INTER_MEASURABLE] THEN + ASM_SIMP_TAC[REAL_ARITH `t < s + e ==> t - s <= e`]]; + REWRITE_TAC[real_div; SUM_LMUL; REAL_INV_POW; SUM_GP] THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN REWRITE_TAC[CONJUNCT1 LT] THEN + ASM_SIMP_TAC[GSYM REAL_MUL_ASSOC; REAL_LE_LMUL_EQ] THEN + REWRITE_TAC[REAL_ARITH + `&1 / &4 * (&1 - x) * &2 <= &1 / &2 <=> &0 <= x`] THEN + MATCH_MP_TAC REAL_POW_LE THEN CONV_TAC REAL_RAT_REDUCE_CONV]]);; + +let LEBESGUE_MEASURABLE_INNER_CLOSED = prove + (`!s:real^N->bool e. + lebesgue_measurable s /\ &0 < e + ==> ?t. closed t /\ + t SUBSET s /\ + measurable(s DIFF t) /\ + measure(s DIFF t) < e`, + REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[GSYM LEBESGUE_MEASURABLE_COMPL] THEN + DISCH_THEN(X_CHOOSE_TAC `t:real^N->bool` o MATCH_MP + LEBESGUE_MEASURABLE_OUTER_OPEN) THEN + EXISTS_TAC `(:real^N) DIFF t` THEN POP_ASSUM MP_TAC THEN + REPEAT(MATCH_MP_TAC MONO_AND THEN CONJ_TAC) THEN + REWRITE_TAC[GSYM OPEN_CLOSED] THENL + [SET_TAC[]; + MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC; + MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_TERM_TAC THEN AP_TERM_TAC] THEN + SET_TAC[]);; + +let STEINHAUS_LEBESGUE = prove + (`!s:real^N->bool. + lebesgue_measurable s /\ ~negligible s + ==> ?d. &0 < d /\ ball(vec 0,d) SUBSET {x - y | x IN s /\ y IN s}`, + GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + ONCE_REWRITE_TAC[NEGLIGIBLE_ON_INTERVALS] THEN + REWRITE_TAC[NOT_FORALL_THM; LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`a:real^N`; `b:real^N`] THEN + MP_TAC(ISPEC `s INTER interval[a:real^N,b]` STEINHAUS) THEN + ASM_SIMP_TAC[GSYM MEASURABLE_MEASURE_POS_LT; MEASURABLE_INTERVAL; + MEASURABLE_LEGESGUE_MEASURABLE_INTER_MEASURABLE] THEN + SET_TAC[]);; + +let LEBESGUE_MEASURABLE_REGULAR_OUTER = prove + (`!s:real^N->bool. + lebesgue_measurable s + ==> ?k c. negligible k /\ (!n. open(c n)) /\ + s = INTERS {c n | n IN (:num)} DIFF k`, + REPEAT STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + LEBESGUE_MEASURABLE_OUTER_OPEN)) THEN + DISCH_THEN(MP_TAC o GEN `n:num` o SPEC `inv(&2 pow n)`) THEN + REWRITE_TAC[REAL_LT_POW2; SKOLEM_THM; REAL_LT_INV_EQ] THEN + REWRITE_TAC[LEFT_IMP_EXISTS_THM; FORALL_AND_THM] THEN + X_GEN_TAC `c:num->real^N->bool` THEN STRIP_TAC THEN + EXISTS_TAC `INTERS {c n | n IN (:num)} DIFF s:real^N->bool` THEN + EXISTS_TAC `c:num->real^N->bool` THEN + ASM_REWRITE_TAC[SET_RULE `s = t DIFF (t DIFF s) <=> s SUBSET t`] THEN + ASM_REWRITE_TAC[SUBSET_INTERS; FORALL_IN_GSPEC] THEN + REWRITE_TAC[NEGLIGIBLE_OUTER_LE] THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN + MP_TAC(ISPECL [`inv(&2)`; `e:real`] REAL_ARCH_POW_INV) THEN + ANTS_TAC THENL [ASM_REAL_ARITH_TAC; REWRITE_TAC[REAL_POW_INV]] THEN + DISCH_THEN(X_CHOOSE_TAC `n:num`) THEN + EXISTS_TAC `(c:num->real^N->bool) n DIFF s` THEN + ASM_REWRITE_TAC[] THEN CONJ_TAC THENL + [SET_TAC[]; ASM_MESON_TAC[REAL_LT_IMP_LE; REAL_LE_TRANS]]);; + +let LEBESGUE_MEASURABLE_REGULAR_INNER = prove + (`!s:real^N->bool. + lebesgue_measurable s + ==> ?k c. negligible k /\ (!n. compact(c n)) /\ + s = UNIONS {c n | n IN (:num)} UNION k`, + REPEAT STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + LEBESGUE_MEASURABLE_INNER_CLOSED)) THEN + DISCH_THEN(MP_TAC o GEN `n:num` o SPEC `inv(&2 pow n)`) THEN + REWRITE_TAC[REAL_LT_POW2; SKOLEM_THM; REAL_LT_INV_EQ] THEN + REWRITE_TAC[LEFT_IMP_EXISTS_THM; FORALL_AND_THM] THEN + X_GEN_TAC `c:num->real^N->bool` THEN STRIP_TAC THEN + EXISTS_TAC `s DIFF UNIONS {c n | n IN (:num)}:real^N->bool` THEN + REWRITE_TAC[RIGHT_EXISTS_AND_THM] THEN CONJ_TAC THENL + [REWRITE_TAC[NEGLIGIBLE_OUTER_LE] THEN X_GEN_TAC `e:real` THEN + DISCH_TAC THEN MP_TAC(ISPECL [`inv(&2)`; `e:real`] REAL_ARCH_POW_INV) THEN + ANTS_TAC THENL [ASM_REAL_ARITH_TAC; REWRITE_TAC[REAL_POW_INV]] THEN + DISCH_THEN(X_CHOOSE_TAC `n:num`) THEN + EXISTS_TAC `s DIFF (c:num->real^N->bool) n` THEN + ASM_REWRITE_TAC[] THEN CONJ_TAC THENL + [SET_TAC[]; ASM_MESON_TAC[REAL_LT_IMP_LE; REAL_LE_TRANS]]; + SUBGOAL_THEN + `?d. (!n. compact(d n:real^N->bool)) /\ + UNIONS {d n | n IN (:num)} = UNIONS {c n | n IN (:num)}` + MP_TAC THENL + [MP_TAC(GEN `n:num` (ISPEC + `(c:num->real^N->bool) n` CLOSED_UNION_COMPACT_SUBSETS)) THEN + ASM_REWRITE_TAC[SKOLEM_THM; FORALL_AND_THM] THEN DISCH_THEN + (X_CHOOSE_THEN `d:num->num->real^N->bool` STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN + `COUNTABLE {d n m:real^N->bool | n IN (:num) /\ m IN (:num)}` + MP_TAC THENL + [MATCH_MP_TAC COUNTABLE_PRODUCT_DEPENDENT THEN + REWRITE_TAC[NUM_COUNTABLE]; + DISCH_THEN(MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + COUNTABLE_AS_IMAGE)) THEN + ANTS_TAC THENL [SET_TAC[]; MATCH_MP_TAC MONO_EXISTS] THEN + ASM SET_TAC[]]; + MATCH_MP_TAC MONO_EXISTS THEN + REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + ASM_REWRITE_TAC[SET_RULE `s = t UNION (s DIFF t) <=> t SUBSET s`] THEN + ASM_REWRITE_TAC[UNIONS_SUBSET; FORALL_IN_GSPEC]]]);; + +(* ------------------------------------------------------------------------- *) +(* Existence of nonmeasurable subsets of any set of positive measure. *) +(* ------------------------------------------------------------------------- *) + +let NEGLIGIBLE_IFF_LEBESGUE_MEASURABLE_SUBSETS = prove + (`!s:real^N->bool. negligible s <=> !t. t SUBSET s ==> lebesgue_measurable t`, + let lemma = prove + (`!s:real^N->bool. + lebesgue_measurable s /\ + (!x y q. x IN s /\ y IN s /\ rational q /\ y = q % basis 1 + x ==> y = x) + ==> negligible s`, + SIMP_TAC[VECTOR_ARITH `q + x:real^N = x <=> q = vec 0`; VECTOR_MUL_EQ_0; + BASIS_NONZERO; DIMINDEX_GE_1; ARITH] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC(TAUT `(~p ==> F) ==> p`) THEN + DISCH_TAC THEN MP_TAC(ISPEC `s:real^N->bool` STEINHAUS_LEBESGUE) THEN + ASM_REWRITE_TAC[NOT_EXISTS_THM] THEN X_GEN_TAC `d:real` THEN STRIP_TAC THEN + FIRST_ASSUM(X_CHOOSE_TAC `q:real` o MATCH_MP RATIONAL_BETWEEN) THEN + FIRST_X_ASSUM + (MP_TAC o SPEC `q % basis 1:real^N` o GEN_REWRITE_RULE I [SUBSET]) THEN + SIMP_TAC[IN_BALL_0; NORM_MUL; NORM_BASIS; DIMINDEX_GE_1; + ARITH; NOT_IMP] THEN + CONJ_TAC THENL [ASM_REAL_ARITH_TAC; REWRITE_TAC[IN_ELIM_THM]] THEN + ASM_REWRITE_TAC[REAL_MUL_RID; IN_ELIM_THM; NOT_EXISTS_THM; + VECTOR_ARITH `q:real^N = x - y <=> x = q + y`] THEN + ASM_CASES_TAC `q = &0` THENL [ASM_REAL_ARITH_TAC; ASM_MESON_TAC[]]) in + GEN_TAC THEN EQ_TAC THENL + [MESON_TAC[NEGLIGIBLE_SUBSET; NEGLIGIBLE_IMP_LEBESGUE_MEASURABLE]; + DISCH_TAC] THEN + ABBREV_TAC + `(canonize:real^N->real^N) = + \x. @y. y IN s /\ ?q. rational q /\ q % basis 1 + y = x` THEN + SUBGOAL_THEN + `!x:real^N. x IN s + ==> canonize x IN s /\ + ?q. rational q /\ q % basis 1 + canonize x = x` + ASSUME_TAC THENL + [GEN_TAC THEN DISCH_TAC THEN EXPAND_TAC "canonize" THEN + CONV_TAC SELECT_CONV THEN EXISTS_TAC `x:real^N` THEN + ASM_REWRITE_TAC[] THEN EXISTS_TAC `&0` THEN + REWRITE_TAC[RATIONAL_CLOSED] THEN VECTOR_ARITH_TAC; + ALL_TAC] THEN + ABBREV_TAC `v = IMAGE (canonize:real^N->real^N) s` THEN + MATCH_MP_TAC NEGLIGIBLE_SUBSET THEN EXISTS_TAC + `UNIONS (IMAGE (\q. IMAGE (\x:real^N. q % basis 1 + x) v) rational)` THEN + CONJ_TAC THENL + [ALL_TAC; + REWRITE_TAC[UNIONS_IMAGE; SUBSET; IN_ELIM_THM] THEN ASM SET_TAC[]] THEN + MATCH_MP_TAC NEGLIGIBLE_COUNTABLE_UNIONS_GEN THEN + SIMP_TAC[COUNTABLE_RATIONAL; COUNTABLE_IMAGE; FORALL_IN_IMAGE] THEN + ASM_REWRITE_TAC[NEGLIGIBLE_TRANSLATION_EQ] THEN GEN_TAC THEN + DISCH_THEN(K ALL_TAC) THEN MATCH_MP_TAC lemma THEN + CONJ_TAC THENL [FIRST_ASSUM MATCH_MP_TAC THEN ASM SET_TAC[]; ALL_TAC] THEN + EXPAND_TAC "v" THEN + REWRITE_TAC[RIGHT_FORALL_IMP_THM; IMP_CONJ; FORALL_IN_IMAGE] THEN + X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN + X_GEN_TAC `y:real^N` THEN DISCH_TAC THEN + X_GEN_TAC `q:real` THEN REPEAT DISCH_TAC THEN + EXPAND_TAC "canonize" THEN AP_TERM_TAC THEN REWRITE_TAC[FUN_EQ_THM] THEN + X_GEN_TAC `z:real^N` THEN AP_TERM_TAC THEN FIRST_X_ASSUM(fun th -> + MP_TAC(SPEC `y:real^N` th) THEN MP_TAC(SPEC `x:real^N` th)) THEN + ASM_REWRITE_TAC[VECTOR_ARITH `q % b + x:real^N = y <=> x = y - q % b`] THEN + STRIP_TAC THEN + ASM_REWRITE_TAC[VECTOR_ARITH `x - q % b:real^N = y - r % b - s % b <=> + y + (q - r - s) % b = x /\ x + (r + s - q) % b = y`] THEN + STRIP_TAC THEN EQ_TAC THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + FIRST_X_ASSUM(fun th -> GEN_REWRITE_TAC + (BINDER_CONV o RAND_CONV o RAND_CONV o LAND_CONV) [SYM th]) THEN + SIMP_TAC[VECTOR_MUL_EQ_0; BASIS_NONZERO; DIMINDEX_GE_1; ARITH; VECTOR_ARITH + `y - q % b:real^N = (y + r % b) - s % b <=> (q + r - s) % b = vec 0`] THEN + ONCE_REWRITE_TAC[CONJ_SYM] THEN + REWRITE_TAC[REAL_ARITH `a + b - c = &0 <=> c = a + b`; UNWIND_THM2] THEN + ASM_SIMP_TAC[RATIONAL_CLOSED]);; + +let NEGLIGIBLE_IFF_MEASURABLE_SUBSETS = prove + (`!s:real^N->bool. negligible s <=> !t. t SUBSET s ==> measurable t`, + MESON_TAC[NEGLIGIBLE_SUBSET; NEGLIGIBLE_IMP_MEASURABLE; + MEASURABLE_IMP_LEBESGUE_MEASURABLE; + NEGLIGIBLE_IFF_LEBESGUE_MEASURABLE_SUBSETS]);; + +(* ------------------------------------------------------------------------- *) +(* Preserving Lebesgue measurability vs. preserving negligibility. *) +(* ------------------------------------------------------------------------- *) + +let PRESERVES_LEBESGUE_MEASURABLE_IMP_PRESERVES_NEGLIGIBLE = prove + (`!f s:real^N->bool. + (!t. negligible t /\ t SUBSET s ==> lebesgue_measurable(IMAGE f t)) + ==> (!t. negligible t /\ t SUBSET s ==> negligible(IMAGE f t))`, + REPEAT STRIP_TAC THEN + REWRITE_TAC[NEGLIGIBLE_IFF_LEBESGUE_MEASURABLE_SUBSETS] THEN + REWRITE_TAC[FORALL_SUBSET_IMAGE] THEN + ASM_MESON_TAC[NEGLIGIBLE_SUBSET; SUBSET_TRANS]);; + +let LEBESGUE_MEASURABLE_CONTINUOUS_IMAGE = prove + (`!f:real^M->real^N s. + f continuous_on s /\ + (!t. negligible t /\ t SUBSET s ==> negligible(IMAGE f t)) + ==> !t. lebesgue_measurable t /\ t SUBSET s + ==> lebesgue_measurable(IMAGE f t)`, + REPEAT STRIP_TAC THEN FIRST_ASSUM(STRIP_ASSUME_TAC o + MATCH_MP LEBESGUE_MEASURABLE_REGULAR_INNER) THEN + ASM_REWRITE_TAC[IMAGE_UNION; IMAGE_UNIONS] THEN + MATCH_MP_TAC LEBESGUE_MEASURABLE_UNION THEN + SUBGOAL_THEN `(k:real^M->bool) SUBSET s` ASSUME_TAC THENL + [ASM SET_TAC[]; ASM_SIMP_TAC[NEGLIGIBLE_IMP_LEBESGUE_MEASURABLE]] THEN + MATCH_MP_TAC LEBESGUE_MEASURABLE_COUNTABLE_UNIONS THEN + REWRITE_TAC[SIMPLE_IMAGE; GSYM IMAGE_o; FORALL_IN_IMAGE] THEN + SIMP_TAC[IN_UNIV; COUNTABLE_IMAGE; NUM_COUNTABLE] THEN + GEN_TAC THEN MATCH_MP_TAC LEBESGUE_MEASURABLE_COMPACT THEN + MATCH_MP_TAC COMPACT_CONTINUOUS_IMAGE THEN ASM_REWRITE_TAC[] THEN + FIRST_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET)) THEN ASM SET_TAC[]);; + +let LEBESGUE_MEASURABLE_DIFFERENTIABLE_IMAGE = prove + (`!f:real^M->real^N s. + dimindex(:M) <= dimindex(:N) /\ + f differentiable_on s /\ lebesgue_measurable s + ==> lebesgue_measurable(IMAGE f s)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC + (REWRITE_RULE[IMP_IMP; RIGHT_IMP_FORALL_THM] + LEBESGUE_MEASURABLE_CONTINUOUS_IMAGE) THEN + EXISTS_TAC `s:real^M->bool` THEN + ASM_SIMP_TAC[SUBSET_REFL; DIFFERENTIABLE_IMP_CONTINUOUS_ON] THEN + REPEAT STRIP_TAC THEN + MATCH_MP_TAC NEGLIGIBLE_DIFFERENTIABLE_IMAGE_NEGLIGIBLE THEN + ASM_MESON_TAC[DIFFERENTIABLE_ON_SUBSET]);; + +(* ------------------------------------------------------------------------- *) +(* Measurability of continuous functions. *) +(* ------------------------------------------------------------------------- *) + +let CONTINUOUS_IMP_MEASURABLE_ON_LEBESGUE_MEASURABLE_SUBSET = prove + (`!f:real^M->real^N s. + f continuous_on s /\ lebesgue_measurable s + ==> f measurable_on s`, + let lemma = prove + (`!s. lebesgue_measurable s + ==> ?u:num->real^M->bool. + (!n. closed(u n)) /\ (!n. u n SUBSET s) /\ + (!n. measurable(s DIFF u n) /\ + measure(s DIFF u n) < inv(&n + &1)) /\ + (!n. u(n) SUBSET u(SUC n))`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN + `!n t. closed t /\ t SUBSET s + ==> ?u:real^M->bool. + closed u /\ t SUBSET u /\ u SUBSET s /\ + measurable(s DIFF u) /\ measure(s DIFF u) < inv(&n + &1)` + MP_TAC THENL + [REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`s DIFF t:real^M->bool`; `inv(&n + &1)`] + LEBESGUE_MEASURABLE_INNER_CLOSED) THEN + ASM_SIMP_TAC[LEBESGUE_MEASURABLE_DIFF; LEBESGUE_MEASURABLE_CLOSED] THEN + REWRITE_TAC[REAL_LT_INV_EQ; REAL_ARITH `&0 < &n + &1`] THEN + DISCH_THEN(X_CHOOSE_THEN `u:real^M->bool` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `t UNION u:real^M->bool` THEN ASM_SIMP_TAC[CLOSED_UNION] THEN + CONJ_TAC THENL [SET_TAC[]; ALL_TAC] THEN + CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + ASM_REWRITE_TAC[SET_RULE `s DIFF (t UNION u) = s DIFF t DIFF u`]; + GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [RIGHT_IMP_EXISTS_THM] THEN + REWRITE_TAC[SKOLEM_THM; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `v:num->(real^M->bool)->(real^M->bool)` THEN DISCH_TAC THEN + MP_TAC(prove_recursive_functions_exist num_RECURSION + `(u:num->real^M->bool) 0 = v 0 {} /\ + (!n. u(SUC n) = v (SUC n) (u n))`) THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `u:num->real^M->bool` THEN + STRIP_TAC THEN + SUBGOAL_THEN + `!n. closed(u n) /\ (u:num->real^M->bool) n SUBSET s` + ASSUME_TAC THENL + [INDUCT_TAC THEN + ASM_SIMP_TAC[CLOSED_EMPTY; EMPTY_SUBSET]; + ASM_SIMP_TAC[]] THEN + INDUCT_TAC THEN ONCE_ASM_REWRITE_TAC[] THEN + ASM_SIMP_TAC[CLOSED_EMPTY; EMPTY_SUBSET]]) in + REPEAT STRIP_TAC THEN + FIRST_ASSUM(X_CHOOSE_THEN `u:num->real^M->bool` STRIP_ASSUME_TAC o + MATCH_MP lemma) THEN + SUBGOAL_THEN `lebesgue_measurable((:real^M) DIFF s)` MP_TAC THENL + [ASM_REWRITE_TAC[LEBESGUE_MEASURABLE_COMPL]; ALL_TAC] THEN + DISCH_THEN(X_CHOOSE_THEN `v:num->real^M->bool` STRIP_ASSUME_TAC o + MATCH_MP lemma) THEN + REWRITE_TAC[measurable_on] THEN + EXISTS_TAC `(:real^M) DIFF + (UNIONS {u n | n IN (:num)} UNION UNIONS {v n | n IN (:num)})` THEN + SUBGOAL_THEN + `!n. ?g. g continuous_on (:real^M) /\ + (!x. x IN u(n) UNION v(n:num) + ==> g x = if x IN s then (f:real^M->real^N)(x) else vec 0)` + MP_TAC THENL + [X_GEN_TAC `n:num` THEN MATCH_MP_TAC TIETZE_UNBOUNDED THEN + ASM_SIMP_TAC[SUBTOPOLOGY_UNIV; GSYM CLOSED_IN; CLOSED_UNION] THEN + MATCH_MP_TAC CONTINUOUS_ON_CASES THEN + ASM_SIMP_TAC[CONTINUOUS_ON_CONST] THEN + CONJ_TAC THENL [ASM_MESON_TAC[CONTINUOUS_ON_SUBSET]; ASM SET_TAC[]]; + REWRITE_TAC[SKOLEM_THM] THEN MATCH_MP_TAC MONO_EXISTS] THEN + X_GEN_TAC `g:num->real^M->real^N` THEN + REWRITE_TAC[FORALL_AND_THM] THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + CONJ_TAC THENL + [MATCH_MP_TAC NEGLIGIBLE_SUBSET THEN + EXISTS_TAC `(s DIFF UNIONS {u n | n IN (:num)}) UNION + ((:real^M) DIFF s DIFF UNIONS {v n | n IN (:num)})` THEN + CONJ_TAC THENL [ALL_TAC; SET_TAC[]] THEN + MATCH_MP_TAC NEGLIGIBLE_UNION THEN CONJ_TAC THEN + REWRITE_TAC[NEGLIGIBLE_OUTER] THEN + X_GEN_TAC `e:real` THEN DISCH_TAC THEN + MP_TAC(ISPEC `e:real` REAL_ARCH_INV) THEN + ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `n:num` STRIP_ASSUME_TAC) THENL + [EXISTS_TAC `s DIFF u(n:num):real^M->bool`; + EXISTS_TAC `(:real^M) DIFF s DIFF v(n:num):real^M->bool`] THEN + (CONJ_TAC THENL [SET_TAC[]; ASM_REWRITE_TAC[]] THEN + MATCH_MP_TAC REAL_LT_TRANS THEN + EXISTS_TAC `inv(&n + &1)` THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC REAL_LT_TRANS THEN + EXISTS_TAC `inv(&n)` THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC REAL_LT_INV2 THEN ASM_REWRITE_TAC[REAL_OF_NUM_LT] THEN + CONJ_TAC THENL [ASM_ARITH_TAC; REAL_ARITH_TAC]); + X_GEN_TAC `x:real^M` THEN REWRITE_TAC[SET_RULE + `~(x IN (UNIV DIFF (s UNION t))) <=> x IN s \/ x IN t`] THEN + REWRITE_TAC[UNIONS_GSPEC; IN_ELIM_THM; IN_UNIV] THEN + REWRITE_TAC[OR_EXISTS_THM] THEN + DISCH_THEN(X_CHOOSE_TAC `n:num`) THEN + MATCH_MP_TAC LIM_EVENTUALLY THEN + REWRITE_TAC[EVENTUALLY_SEQUENTIALLY] THEN + EXISTS_TAC `n:num` THEN X_GEN_TAC `m:num` THEN DISCH_TAC THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN REWRITE_TAC[IN_UNION] THEN + SUBGOAL_THEN + `!i j. i <= j ==> (u:num->real^M->bool)(i) SUBSET u(j) /\ + (v:num->real^M->bool)(i) SUBSET v(j)` + (fun th -> ASM_MESON_TAC[SUBSET; th]) THEN + MATCH_MP_TAC TRANSITIVE_STEPWISE_LE THEN + ASM_REWRITE_TAC[] THEN SET_TAC[]]);; + +let CONTINUOUS_IMP_MEASURABLE_ON_CLOSED_SUBSET = prove + (`!f:real^M->real^N s. + f continuous_on s /\ closed s ==> f measurable_on s`, + SIMP_TAC[CONTINUOUS_IMP_MEASURABLE_ON_LEBESGUE_MEASURABLE_SUBSET; + LEBESGUE_MEASURABLE_CLOSED]);; + +(* ------------------------------------------------------------------------- *) +(* Measurability of a.e. derivatives. *) +(* ------------------------------------------------------------------------- *) + +let MEASURABLE_ON_VECTOR_DERIVATIVE = prove + (`!f:real^1->real^N f' s k. + negligible k /\ negligible(frontier s) /\ + (!x. x IN (s DIFF k) ==> (f has_vector_derivative f'(x)) (at x)) + ==> f' measurable_on s`, + REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[GSYM MEASURABLE_ON_UNIV] THEN + ABBREV_TAC `g:real^1->real^N = \x. if x IN s then f(x) else vec 0` THEN + SUBGOAL_THEN `(g:real^1->real^N) measurable_on (:real^1)` ASSUME_TAC THENL + [EXPAND_TAC "g" THEN REWRITE_TAC[MEASURABLE_ON_UNIV] THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_IMP] MEASURABLE_ON_SPIKE_SET) THEN + EXISTS_TAC `s DIFF k:real^1->bool` THEN CONJ_TAC THENL + [MATCH_MP_TAC NEGLIGIBLE_SUBSET THEN + EXISTS_TAC `k:real^1->bool` THEN ASM_REWRITE_TAC[] THEN SET_TAC[]; + MATCH_MP_TAC CONTINUOUS_IMP_MEASURABLE_ON_LEBESGUE_MEASURABLE_SUBSET THEN + CONJ_TAC THENL + [MATCH_MP_TAC DIFFERENTIABLE_IMP_CONTINUOUS_ON THEN + MATCH_MP_TAC DIFFERENTIABLE_AT_IMP_DIFFERENTIABLE_ON THEN + ASM_MESON_TAC[differentiable; has_vector_derivative]; + MATCH_MP_TAC LEBESGUE_MEASURABLE_DIFF THEN + ASM_SIMP_TAC[NEGLIGIBLE_IMP_LEBESGUE_MEASURABLE] THEN + ASM_SIMP_TAC[LEBESGUE_MEASURABLE_JORDAN]]]; + ALL_TAC] THEN + MATCH_MP_TAC MEASURABLE_ON_LIMIT THEN + EXISTS_TAC `\n x. (&n + &1) % (g(x + lift(inv(&n + &1))) - g(x):real^N)` THEN + EXISTS_TAC `k UNION frontier s:real^1->bool` THEN + ASM_REWRITE_TAC[NEGLIGIBLE_UNION_EQ] THEN CONJ_TAC THENL + [X_GEN_TAC `n:num` THEN MATCH_MP_TAC MEASURABLE_ON_CMUL THEN + MATCH_MP_TAC MEASURABLE_ON_SUB THEN ASM_REWRITE_TAC[] THEN + ONCE_REWRITE_TAC[VECTOR_ADD_SYM] THEN + REWRITE_TAC[MEASURABLE_ON_TRANSLATION_EQ] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (MESON[] + `g measurable_on s ==> t = s ==> g measurable_on t`)) THEN + MATCH_MP_TAC(SET_RULE + `!g. (!x. f(g x) = x /\ g(f x) = x) ==> IMAGE f UNIV = UNIV`) THEN + EXISTS_TAC `\x. --(lift(inv(&n + &1))) + x` THEN VECTOR_ARITH_TAC; + + X_GEN_TAC `x:real^1` THEN + REWRITE_TAC[IN_UNIV; IN_DIFF; IN_UNION; DE_MORGAN_THM; frontier; + CLOSURE_INTERIOR] THEN + STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_INTERIOR]) THEN + REWRITE_TAC[LEFT_IMP_EXISTS_THM; SUBSET; IN_BALL; IN_DIFF; IN_UNIV] THEN + X_GEN_TAC `d:real` THEN ASM_SIMP_TAC[DIST_REFL] THEN STRIP_TAC THEN + MATCH_MP_TAC LIM_TRANSFORM_EVENTUALLY THENL + [EXISTS_TAC `(\n. vec 0):num->real^N`; + EXISTS_TAC `(\n. (&n + &1) % (f(x + lift (inv (&n + &1))) - f x)) + :num->real^N`] THEN + (CONJ_TAC THENL + [REWRITE_TAC[EVENTUALLY_SEQUENTIALLY] THEN + MP_TAC(SPEC `d: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 + SUBGOAL_THEN `dist(x,x + lift(inv(&n + &1))) < d` ASSUME_TAC THENL + [REWRITE_TAC[NORM_ARITH `dist(a:real^N,a + x) = norm x`] THEN + REWRITE_TAC[NORM_LIFT; REAL_ABS_INV] THEN + REWRITE_TAC[REAL_ARITH `abs(&n + &1) = &n + &1`] THEN + MATCH_MP_TAC REAL_LT_TRANS THEN EXISTS_TAC `inv(&N)` THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC REAL_LT_INV2 THEN + ASM_REWRITE_TAC[REAL_OF_NUM_ADD; REAL_OF_NUM_LT] THEN ASM_ARITH_TAC; + EXPAND_TAC "g" THEN REWRITE_TAC[] THEN ASM_SIMP_TAC[DIST_REFL] THEN + VECTOR_ARITH_TAC]; + ALL_TAC]) THEN + REWRITE_TAC[LIM_CONST] THEN + UNDISCH_THEN + `!x. x IN s DIFF k + ==> ((f:real^1->real^N) has_vector_derivative f' x) (at x)` + (MP_TAC o SPEC `x:real^1`) THEN + ASM_SIMP_TAC[IN_DIFF; DIST_REFL; has_vector_derivative] THEN + REWRITE_TAC[has_derivative; NETLIMIT_AT] THEN + DISCH_THEN(MP_TAC o CONJUNCT2) THEN + REWRITE_TAC[LIM_AT; LIM_SEQUENTIALLY] THEN DISCH_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 `k:real`) 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 + FIRST_X_ASSUM(MP_TAC o SPEC `x + lift(inv(&n + &1))` o CONJUNCT2) THEN + REWRITE_TAC[NORM_ARITH `dist(x + a:real^N,x) = norm a`] THEN + REWRITE_TAC[NORM_LIFT; REAL_ABS_INV; REAL_ARITH `abs(&n + &1) = &n + &1`; + VECTOR_ARITH `(x + e) - x:real^N = e`; LIFT_DROP] THEN + ANTS_TAC THENL + [REWRITE_TAC[REAL_LT_INV_EQ] THEN + CONJ_TAC THENL [REAL_ARITH_TAC; MATCH_MP_TAC REAL_LT_TRANS] THEN + EXISTS_TAC `inv(&N)` THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC REAL_LT_INV2 THEN + ASM_REWRITE_TAC[REAL_OF_NUM_ADD; REAL_OF_NUM_LT] THEN ASM_ARITH_TAC; + MATCH_MP_TAC(NORM_ARITH + `x - y:real^N = z ==> dist(z,vec 0) < e ==> dist(x,y) < e`) THEN + REWRITE_TAC[REAL_INV_INV; VECTOR_SUB_LDISTRIB; VECTOR_ADD_LDISTRIB] THEN + SIMP_TAC[VECTOR_MUL_ASSOC; REAL_MUL_RINV; VECTOR_MUL_LID; + REAL_ARITH `~(&n + &1 = &0)`] THEN + VECTOR_ARITH_TAC]]);; + +(* ------------------------------------------------------------------------- *) +(* Approximation of L_1 functions by bounded continuous ones. *) +(* Note that 100/fourier.ml has some generalizations to L_p spaces. *) +(* ------------------------------------------------------------------------- *) + +let ABSOLUTELY_INTEGRABLE_APPROXIMATE_CONTINUOUS = prove + (`!f:real^M->real^N s e. + measurable s /\ f absolutely_integrable_on s /\ &0 < e + ==> ?g. g absolutely_integrable_on s /\ + g continuous_on (:real^M) /\ + bounded (IMAGE g (:real^M)) /\ + norm(integral s (\x. lift(norm(f x - g x)))) < e`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN + `?h. h absolutely_integrable_on s /\ + bounded (IMAGE h (:real^M)) /\ + norm(integral s (\x. lift(norm(f x - h x:real^N)))) < e / &2` + STRIP_ASSUME_TAC THENL + [MP_TAC(ISPECL + [`\n x. lift(norm + (f x - (lambda i. max (--(&n)) (min (&n) ((f:real^M->real^N)(x)$i)))))`; + `(\x. vec 0):real^M->real^1`; + `\x. lift(norm((f:real^M->real^N)(x)))`; + `s:real^M->bool`] + DOMINATED_CONVERGENCE) THEN + ASM_REWRITE_TAC[] THEN + SUBGOAL_THEN + `!n. ((\x. lambda i. max (--(&n)) (min (&n) ((f x:real^N)$i))) + :real^M->real^N) absolutely_integrable_on s` + ASSUME_TAC THENL + [GEN_TAC THEN + FIRST_ASSUM(MP_TAC o SPEC `(\x. lambda i. &n):real^M->real^N` o + MATCH_MP (REWRITE_RULE[IMP_CONJ_ALT] ABSOLUTELY_INTEGRABLE_MIN)) THEN + ASM_REWRITE_TAC[ABSOLUTELY_INTEGRABLE_ON_CONST] THEN + DISCH_THEN(MP_TAC o SPEC `(\x. lambda i. --(&n)):real^M->real^N` o + MATCH_MP (REWRITE_RULE[IMP_CONJ_ALT] ABSOLUTELY_INTEGRABLE_MAX)) THEN + ASM_REWRITE_TAC[ABSOLUTELY_INTEGRABLE_ON_CONST] THEN + MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_TERM_TAC THEN ABS_TAC THEN + SIMP_TAC[CART_EQ; LAMBDA_BETA]; + ALL_TAC] THEN + ANTS_TAC THENL + [REPEAT CONJ_TAC THENL + [X_GEN_TAC `n:num` THEN + MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_IMP_INTEGRABLE THEN + MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_NORM THEN + ASM_SIMP_TAC[ABSOLUTELY_INTEGRABLE_SUB]; + ASM_SIMP_TAC[ABSOLUTELY_INTEGRABLE_NORM; + ABSOLUTELY_INTEGRABLE_IMP_INTEGRABLE]; + MAP_EVERY X_GEN_TAC [`n:num`; `x:real^M`] THEN DISCH_TAC THEN + REWRITE_TAC[LIFT_DROP; NORM_LIFT; REAL_ABS_NORM] THEN + MATCH_MP_TAC NORM_LE_COMPONENTWISE THEN + SIMP_TAC[LAMBDA_BETA; VECTOR_SUB_COMPONENT] THEN REAL_ARITH_TAC; + X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN + REWRITE_TAC[LIM_SEQUENTIALLY] THEN + X_GEN_TAC `d:real` THEN DISCH_TAC THEN + MP_TAC(SPEC `norm((f:real^M->real^N) x)` REAL_ARCH_SIMPLE) THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `N:num` THEN + DISCH_TAC THEN X_GEN_TAC `n:num` THEN DISCH_TAC THEN + REWRITE_TAC[DIST_0; NORM_LIFT; REAL_ABS_NORM; GSYM LIFT_SUB] THEN + MATCH_MP_TAC(NORM_ARITH + `&0 < d /\ x = y ==> norm(x:real^N - y) < d`) THEN + ASM_SIMP_TAC[CART_EQ; LAMBDA_BETA] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC(REAL_ARITH + `abs(x) <= n ==> x = max (--n) (min n x)`) THEN + ASM_MESON_TAC[COMPONENT_LE_NORM; REAL_LE_TRANS; REAL_OF_NUM_LE]]; + DISCH_THEN(MP_TAC o CONJUNCT2) THEN REWRITE_TAC[LIM_SEQUENTIALLY] THEN + DISCH_THEN(MP_TAC o SPEC `e / &2`) THEN ASM_REWRITE_TAC[REAL_HALF] THEN + DISCH_THEN(X_CHOOSE_THEN `n:num` (MP_TAC o SPEC `n:num`)) THEN + REWRITE_TAC[INTEGRAL_0; DIST_0; LE_REFL] THEN DISCH_TAC THEN + EXISTS_TAC `(\x. lambda i. max (--(&n)) (min (&n) + ((f:real^M->real^N)(x)$i))):real^M->real^N` THEN + ASM_REWRITE_TAC[] THEN + ONCE_REWRITE_TAC[BOUNDED_COMPONENTWISE] THEN + REWRITE_TAC[bounded; FORALL_IN_IMAGE] THEN + X_GEN_TAC `i:num` THEN STRIP_TAC THEN EXISTS_TAC `&n` THEN + X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN + ASM_SIMP_TAC[NORM_LIFT; LAMBDA_BETA] THEN REAL_ARITH_TAC]; + ALL_TAC] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [BOUNDED_POS]) THEN + REWRITE_TAC[FORALL_IN_IMAGE; IN_UNIV] THEN + DISCH_THEN(X_CHOOSE_THEN `B:real` STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN + `?k g. negligible k /\ + (!n. g n continuous_on (:real^M)) /\ + (!n x. norm(g n x:real^N) <= norm(B % vec 1:real^N)) /\ + (!x. x IN (s DIFF k) ==> ((\n. g n x) --> h x) sequentially)` + STRIP_ASSUME_TAC THENL + [SUBGOAL_THEN `(h:real^M->real^N) measurable_on s` MP_TAC THENL + [ASM_MESON_TAC[ABSOLUTELY_INTEGRABLE_MEASURABLE]; ALL_TAC] THEN + REWRITE_TAC[measurable_on] THEN MATCH_MP_TAC MONO_EXISTS THEN + X_GEN_TAC `k:real^M->bool` THEN + DISCH_THEN(X_CHOOSE_THEN `g:num->real^M->real^N` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `(\n x. lambda i. max (--B) (min B (((g n x):real^N)$i))): + num->real^M->real^N` THEN + ASM_REWRITE_TAC[] THEN REPEAT CONJ_TAC THENL + [X_GEN_TAC `n:num` THEN + FIRST_X_ASSUM(MP_TAC o SPEC `n:num`) THEN + MP_TAC(ISPECL [`(:real^M)`; `(lambda i. B):real^N`] + CONTINUOUS_ON_CONST) THEN + REWRITE_TAC[IMP_IMP] THEN + DISCH_THEN(MP_TAC o MATCH_MP CONTINUOUS_ON_MIN) THEN + MP_TAC(ISPECL [`(:real^M)`; `(lambda i. --B):real^N`] + CONTINUOUS_ON_CONST) THEN + REWRITE_TAC[IMP_IMP] THEN + DISCH_THEN(MP_TAC o MATCH_MP CONTINUOUS_ON_MAX) THEN + MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_TERM_TAC THEN + SIMP_TAC[FUN_EQ_THM; CART_EQ; LAMBDA_BETA]; + REPEAT STRIP_TAC THEN MATCH_MP_TAC NORM_LE_COMPONENTWISE THEN + SIMP_TAC[LAMBDA_BETA; VEC_COMPONENT; VECTOR_MUL_COMPONENT] THEN + REAL_ARITH_TAC; + X_GEN_TAC `x:real^M` THEN REWRITE_TAC[IN_DIFF] THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `x:real^M`) THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[LIM_SEQUENTIALLY] THEN + MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `ee:real` THEN + MATCH_MP_TAC MONO_IMP THEN REWRITE_TAC[] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `N:num` THEN + MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `n:num` THEN + MATCH_MP_TAC MONO_IMP THEN REWRITE_TAC[] THEN + MATCH_MP_TAC(NORM_ARITH + `norm(c - a:real^N) <= norm(b - a) + ==> dist(b,a) < ee ==> dist(c,a) < ee`) THEN + MATCH_MP_TAC NORM_LE_COMPONENTWISE THEN + SIMP_TAC[LAMBDA_BETA; VECTOR_SUB_COMPONENT] THEN + X_GEN_TAC `k:num` THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `x:real^M`) THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(MP_TAC o MATCH_MP NORM_BOUND_COMPONENT_LE) THEN + DISCH_THEN(MP_TAC o SPEC `k:num`) THEN ASM_REWRITE_TAC[] THEN + REAL_ARITH_TAC]; + ALL_TAC] THEN + SUBGOAL_THEN + `!n. (g:num->real^M->real^N) n absolutely_integrable_on s` + ASSUME_TAC THENL + [X_GEN_TAC `n:num` THEN MATCH_MP_TAC + MEASURABLE_BOUNDED_BY_INTEGRABLE_IMP_ABSOLUTELY_INTEGRABLE THEN + EXISTS_TAC `(\x. lift(norm(B % vec 1:real^N))):real^M->real^1` THEN + ASM_REWRITE_TAC[LIFT_DROP; INTEGRABLE_ON_CONST] THEN + ONCE_REWRITE_TAC[GSYM MEASURABLE_ON_UNIV] THEN + MATCH_MP_TAC(REWRITE_RULE[lebesgue_measurable; indicator] + MEASURABLE_ON_RESTRICT) THEN + ASM_SIMP_TAC[CONTINUOUS_IMP_MEASURABLE_ON; ETA_AX] THEN + MATCH_MP_TAC INTEGRABLE_IMP_MEASURABLE THEN + ASM_REWRITE_TAC[GSYM MEASURABLE_INTEGRABLE]; + ALL_TAC] THEN + MP_TAC(ISPECL + [`\n x. lift(norm((g:num->real^M->real^N) n x - h x))`; + `(\x. vec 0):real^M->real^1`; + `(\x. lift(B + norm(B % vec 1:real^N))):real^M->real^1`; + `s DIFF k:real^M->bool`] DOMINATED_CONVERGENCE) THEN + ASM_SIMP_TAC[INTEGRAL_0; INTEGRABLE_ON_CONST; MEASURABLE_DIFF; + NEGLIGIBLE_IMP_MEASURABLE] THEN + ANTS_TAC THENL + [REWRITE_TAC[NORM_LIFT; REAL_ABS_NORM] THEN REPEAT CONJ_TAC THENL + [GEN_TAC THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_IMP] INTEGRABLE_SPIKE_SET) THEN + EXISTS_TAC `s:real^M->bool` THEN + ASM_SIMP_TAC[ABSOLUTELY_INTEGRABLE_NORM; + ABSOLUTELY_INTEGRABLE_IMP_INTEGRABLE; + ABSOLUTELY_INTEGRABLE_SUB; ETA_AX] THEN + MATCH_MP_TAC NEGLIGIBLE_SUBSET THEN EXISTS_TAC `k:real^M->bool` THEN + ASM_REWRITE_TAC[] THEN SET_TAC[]; + REPEAT STRIP_TAC THEN REWRITE_TAC[LIFT_DROP] THEN + MATCH_MP_TAC(NORM_ARITH + `norm(g:real^N) <= b /\ norm(h) <= a ==> norm(g - h) <= a + b`) THEN + ASM_REWRITE_TAC[]; + ASM_REWRITE_TAC[GSYM LIM_NULL_NORM; GSYM LIM_NULL]]; + REWRITE_TAC[LIM_SEQUENTIALLY] THEN + DISCH_THEN(MP_TAC o SPEC `e / &2`) THEN ASM_REWRITE_TAC[REAL_HALF] THEN + DISCH_THEN(X_CHOOSE_THEN `n:num` (MP_TAC o SPEC `n:num`)) THEN + REWRITE_TAC[LE_REFL; DIST_0] THEN DISCH_TAC THEN + EXISTS_TAC `(g:num->real^M->real^N) n` THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[bounded; FORALL_IN_IMAGE; IN_UNIV] THEN + CONJ_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN + MATCH_MP_TAC REAL_LET_TRANS THEN + EXISTS_TAC `norm(integral s (\x. lift(norm(f x - h x)))) + + norm(integral s (\x. lift(norm((g:num->real^M->real^N) n x - h x))))` THEN + CONJ_TAC THENL + [MATCH_MP_TAC(NORM_ARITH + `norm(x:real^N) <= norm(y + z:real^N) + ==> norm(x) <= norm(y) + norm(z)`) THEN + W(MP_TAC o PART_MATCH (lhs o rand) (GSYM INTEGRAL_ADD) o + rand o rand o snd) THEN + ASM_SIMP_TAC[ABSOLUTELY_INTEGRABLE_NORM; + ABSOLUTELY_INTEGRABLE_IMP_INTEGRABLE; + ABSOLUTELY_INTEGRABLE_SUB; ETA_AX] THEN + DISCH_THEN SUBST1_TAC THEN MATCH_MP_TAC(MESON[] + `norm x = drop x /\ norm(a:real^N) <= drop x ==> norm a <= norm x`) THEN + CONJ_TAC THENL + [MATCH_MP_TAC NORM_1_POS THEN MATCH_MP_TAC INTEGRAL_DROP_POS THEN + SIMP_TAC[DROP_ADD; LIFT_DROP; NORM_POS_LE; REAL_LE_ADD] THEN + MATCH_MP_TAC INTEGRABLE_ADD THEN CONJ_TAC; + MATCH_MP_TAC INTEGRAL_NORM_BOUND_INTEGRAL THEN + REWRITE_TAC[DROP_ADD; LIFT_DROP; NORM_LIFT; REAL_ABS_NORM] THEN + REWRITE_TAC[NORM_ARITH + `norm(f - g:real^N) <= norm(f - h) + norm(g - h)`] THEN + CONJ_TAC THENL + [ALL_TAC; MATCH_MP_TAC INTEGRABLE_ADD THEN CONJ_TAC]] THEN + MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_IMP_INTEGRABLE THEN + ASM_SIMP_TAC[ABSOLUTELY_INTEGRABLE_NORM; + ABSOLUTELY_INTEGRABLE_SUB; ETA_AX]; + MATCH_MP_TAC(REAL_ARITH `a < e / &2 /\ b < e / &2 ==> a + b < e`) THEN + ASM_REWRITE_TAC[] THEN FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH + `x < e ==> x = y ==> y < e`)) THEN AP_TERM_TAC THEN + MATCH_MP_TAC INTEGRAL_SPIKE_SET THEN + MATCH_MP_TAC NEGLIGIBLE_SUBSET THEN EXISTS_TAC `k:real^M->bool` THEN + ASM_REWRITE_TAC[] THEN SET_TAC[]]]);; + +(* ------------------------------------------------------------------------- *) +(* Luzin's theorem (Talvila and Loeb's proof from Marius Junge's notes). *) +(* ------------------------------------------------------------------------- *) + +let LUZIN = prove + (`!f:real^M->real^N s e. + measurable s /\ f measurable_on s /\ &0 < e + ==> ?k. compact k /\ k SUBSET s /\ + measure(s DIFF k) < e /\ f continuous_on k`, + REPEAT STRIP_TAC THEN + X_CHOOSE_THEN `v:num->real^N->bool` STRIP_ASSUME_TAC + UNIV_SECOND_COUNTABLE_SEQUENCE THEN + MP_TAC(ISPECL [`f:real^M->real^N`; `s:real^M->bool`] + MEASURABLE_ON_MEASURABLE_PREIMAGE_OPEN) THEN + MP_TAC(ISPECL [`f:real^M->real^N`; `s:real^M->bool`] + MEASURABLE_ON_MEASURABLE_PREIMAGE_CLOSED) THEN + ASM_REWRITE_TAC[] THEN REPEAT DISCH_TAC THEN + SUBGOAL_THEN + `!n. ?k k'. + compact k /\ k SUBSET {x | x IN s /\ (f:real^M->real^N) x IN v n} /\ + compact k' /\ k' SUBSET {x | x IN s /\ f x IN ((:real^N) DIFF v n)} /\ + measure(s DIFF (k UNION k')) < e / &4 / &2 pow n` + MP_TAC THENL + [GEN_TAC THEN + MP_TAC(ISPECL [`{x:real^M | x IN s /\ f(x) IN (v:num->real^N->bool) n}`; + `e / &4 / &2 / &2 pow n`] MEASURABLE_INNER_COMPACT) THEN + ASM_SIMP_TAC[REAL_OF_NUM_LT; ARITH; REAL_LT_DIV; REAL_LT_POW2] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `k:real^M->bool` THEN + STRIP_TAC THEN + MP_TAC(ISPECL [`{x:real^M | x IN s /\ f(x) IN (:real^N) DIFF v(n:num)}`; + `e / &4 / &2 / &2 pow n`] MEASURABLE_INNER_COMPACT) THEN + ASM_SIMP_TAC[GSYM OPEN_CLOSED; REAL_LT_DIV; REAL_POW_LT; REAL_OF_NUM_LT; + ARITH] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `k':real^M->bool` THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC REAL_LET_TRANS THEN EXISTS_TAC + `measure(({x | x IN s /\ (f:real^M->real^N) x IN v n} DIFF k) UNION + ({x | x IN s /\ f x IN ((:real^N) DIFF v(n:num))} DIFF k'))` THEN + CONJ_TAC THENL + [MATCH_MP_TAC MEASURE_SUBSET THEN + ASM_SIMP_TAC[MEASURABLE_DIFF; MEASURABLE_UNION; MEASURABLE_COMPACT; + GSYM OPEN_CLOSED] THEN SET_TAC[]; + ASM_SIMP_TAC[MEASURE_UNION; MEASURABLE_DIFF; MEASURABLE_COMPACT; + GSYM OPEN_CLOSED; MEASURE_DIFF_SUBSET] THEN + MATCH_MP_TAC(REAL_ARITH + `s < k + e / &4 / &2 / d /\ s' < k' + e / &4 / &2 / d /\ m = &0 + ==> (s - k) + (s' - k') - m < e / &4 / d`) THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC(MESON[MEASURE_EMPTY] + `s = {} ==> measure s = &0`) THEN SET_TAC[]]; + REWRITE_TAC[SKOLEM_THM; LEFT_IMP_EXISTS_THM; IN_DIFF; IN_UNIV] THEN + MAP_EVERY X_GEN_TAC [`k:num->real^M->bool`; `k':num->real^M->bool`] THEN + REWRITE_TAC[FORALL_AND_THM] THEN STRIP_TAC] THEN + EXISTS_TAC `INTERS {k n UNION k' n | n IN (:num)} :real^M->bool` THEN + REPEAT CONJ_TAC THENL + [MATCH_MP_TAC COMPACT_INTERS THEN + ASM_SIMP_TAC[FORALL_IN_GSPEC; COMPACT_UNION] THEN SET_TAC[]; + REWRITE_TAC[INTERS_GSPEC] THEN ASM SET_TAC[]; + REWRITE_TAC[DIFF_INTERS; SET_RULE + `{f y | y IN {g x | x IN s}} = {f(g x) | x IN s}`] THEN + MATCH_MP_TAC(REAL_ARITH `&0 < e /\ x <= e / &2 ==> x < e`) THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC + (MESON[] `measurable s /\ measure s <= b ==> measure s <= b`) THEN + MATCH_MP_TAC MEASURE_COUNTABLE_UNIONS_LE THEN + ASM_SIMP_TAC[MEASURABLE_DIFF; MEASURABLE_UNION; MEASURABLE_COMPACT] THEN + X_GEN_TAC `n:num` THEN MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `sum(0..n) (\i. e / &4 / &2 pow i)` THEN CONJ_TAC THENL + [ASM_SIMP_TAC[SUM_LE_NUMSEG; REAL_LT_IMP_LE]; ALL_TAC] THEN + ASM_SIMP_TAC[real_div; SUM_LMUL; REAL_LE_LMUL_EQ; REAL_ARITH + `(e * inv(&4)) * s <= e * inv(&2) <=> e * s <= e * &2`] THEN + REWRITE_TAC[REAL_INV_POW; SUM_GP; LT] THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN REWRITE_TAC[REAL_ARITH + `(&1 - s) / (&1 / &2) <= &2 <=> &0 <= s`] THEN + MATCH_MP_TAC REAL_POW_LE THEN CONV_TAC REAL_RAT_REDUCE_CONV; + + REWRITE_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN] THEN + REWRITE_TAC[INTERS_GSPEC; IN_ELIM_THM; IN_UNIV] THEN + X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN + REWRITE_TAC[CONTINUOUS_WITHIN_OPEN; IN_ELIM_THM] THEN + X_GEN_TAC `t:real^N->bool` THEN STRIP_TAC THEN + SUBGOAL_THEN + `?n:num. (f:real^M->real^N)(x) IN v(n) /\ v(n) SUBSET t` + STRIP_ASSUME_TAC THENL + [UNDISCH_THEN + `!s. open s ==> (?k. s:real^N->bool = UNIONS {v(n:num) | n IN k})` + (MP_TAC o SPEC `t:real^N->bool`) THEN + ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM; UNIONS_GSPEC] THEN ASM SET_TAC[]; + EXISTS_TAC `(:real^M) DIFF k'(n:num)` THEN + ASM_SIMP_TAC[GSYM closed; COMPACT_IMP_CLOSED] THEN ASM SET_TAC[]]]);; + +let LUZIN_EQ,LUZIN_EQ_ALT = (CONJ_PAIR o prove) + (`(!f:real^M->real^N s. + measurable s + ==> (f measurable_on s <=> + !e. &0 < e + ==> ?k. compact k /\ k SUBSET s /\ + measure(s DIFF k) < e /\ f continuous_on k)) /\ + (!f:real^M->real^N s. + measurable s + ==> (f measurable_on s <=> + !e. &0 < e + ==> ?k g. compact k /\ k SUBSET s /\ + measure(s DIFF k) < e /\ + g continuous_on (:real^M) /\ + (!x. x IN k ==> g x = f x)))`, + REWRITE_TAC[AND_FORALL_THM] THEN REPEAT GEN_TAC THEN + ASM_CASES_TAC `measurable(s:real^M->bool)` THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC(TAUT + `(p ==> q) /\ (q ==> r) /\ (r ==> p) ==> (p <=> q) /\ (p <=> r)`) THEN + REPEAT CONJ_TAC THENL + [ASM_MESON_TAC[LUZIN]; + MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `e:real` THEN + ASM_CASES_TAC `&0 < e` THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `k:real^M->bool` THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN MATCH_MP_TAC TIETZE_UNBOUNDED THEN + ASM_SIMP_TAC[COMPACT_IMP_CLOSED; SUBTOPOLOGY_UNIV; GSYM CLOSED_IN]; + DISCH_THEN(MP_TAC o GEN `n:num` o SPEC `inv(&2 pow n)`) THEN + REWRITE_TAC[REAL_LT_INV_EQ; REAL_LT_POW2] THEN + REWRITE_TAC[SKOLEM_THM; LEFT_IMP_EXISTS_THM; FORALL_AND_THM] THEN + MAP_EVERY X_GEN_TAC [`k:num->real^M->bool`; `g:num->real^M->real^N`] THEN + STRIP_TAC THEN MATCH_MP_TAC MEASURABLE_ON_LIMIT THEN MAP_EVERY EXISTS_TAC + [`g:num->real^M->real^N`; + `s DIFF UNIONS {INTERS {k m | n <= m} | n IN (:num)}:real^M->bool`] THEN + REPEAT CONJ_TAC THENL + [X_GEN_TAC `n:num` THEN + MATCH_MP_TAC CONTINUOUS_IMP_MEASURABLE_ON_LEBESGUE_MEASURABLE_SUBSET THEN + ASM_MESON_TAC[MEASURABLE_IMP_LEBESGUE_MEASURABLE; CONTINUOUS_ON_SUBSET; + SUBSET_UNIV]; + SIMP_TAC[DIFF_UNIONS_NONEMPTY; SET_RULE `~({f x | x IN UNIV} = {})`] THEN + REWRITE_TAC[NEGLIGIBLE_OUTER] THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN + MP_TAC(SPECL [`inv(&2)`; `e / &4`] REAL_ARCH_POW_INV) THEN + ANTS_TAC THENL [ASM_REAL_ARITH_TAC; REWRITE_TAC[REAL_POW_INV]] THEN + DISCH_THEN(X_CHOOSE_THEN `n:num` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `s DIFF INTERS {k m | n:num <= m}:real^M->bool` THEN + REPEAT CONJ_TAC THENL + [REWRITE_TAC[INTERS_GSPEC; FORALL_IN_GSPEC] THEN ASM SET_TAC[]; + MATCH_MP_TAC MEASURABLE_DIFF THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC MEASURABLE_COUNTABLE_INTERS_GEN THEN + ASM_SIMP_TAC[FORALL_IN_GSPEC; MEASURABLE_COMPACT] THEN + CONJ_TAC THENL [ALL_TAC; ASM SET_TAC[LE_REFL]] THEN + ONCE_REWRITE_TAC[SIMPLE_IMAGE_GEN] THEN + MATCH_MP_TAC COUNTABLE_IMAGE THEN + MESON_TAC[NUM_COUNTABLE; COUNTABLE_SUBSET; SUBSET_UNIV]; + REWRITE_TAC[DIFF_INTERS] THEN + MATCH_MP_TAC(REAL_ARITH `&0 < e /\ x <= e / &2 ==> x < e`) THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC + (MESON[] `measurable s /\ measure s <= b ==> measure s <= b`) THEN + MATCH_MP_TAC MEASURE_COUNTABLE_UNIONS_LE_GEN THEN + ASM_SIMP_TAC[FORALL_IN_GSPEC; MEASURABLE_COMPACT; MEASURABLE_DIFF] THEN + CONJ_TAC THENL + [ONCE_REWRITE_TAC[SIMPLE_IMAGE_GEN] THEN + MATCH_MP_TAC COUNTABLE_IMAGE THEN + REWRITE_TAC[SET_RULE `{x | x IN s} = s`] THEN + ONCE_REWRITE_TAC[SIMPLE_IMAGE_GEN] THEN + MATCH_MP_TAC COUNTABLE_IMAGE THEN + MESON_TAC[NUM_COUNTABLE; COUNTABLE_SUBSET; SUBSET_UNIV]; + REWRITE_TAC[SIMPLE_IMAGE] THEN ONCE_REWRITE_TAC[CONJ_SYM] THEN + REWRITE_TAC[FORALL_FINITE_SUBSET_IMAGE] THEN + ONCE_REWRITE_TAC[SIMPLE_IMAGE_GEN] THEN + REWRITE_TAC[FORALL_FINITE_SUBSET_IMAGE] THEN + X_GEN_TAC `ns:num->bool` THEN REWRITE_TAC[SUBSET; IN_ELIM_THM] THEN + STRIP_TAC THEN REWRITE_TAC[GSYM IMAGE_o] THEN + W(MP_TAC o PART_MATCH (lhand o rand) SUM_IMAGE_LE o lhand o snd) THEN + ASM_SIMP_TAC[o_DEF; MEASURE_POS_LE; MEASURABLE_DIFF; + MEASURABLE_COMPACT] THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] REAL_LE_TRANS) THEN + FIRST_ASSUM(MP_TAC o SPEC `\x:num. x` o + MATCH_MP UPPER_BOUND_FINITE_SET) THEN + REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN X_GEN_TAC `m:num` THEN + STRIP_TAC THEN MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `sum (n..m) (\i. measure(s DIFF k i:real^M->bool))` THEN + CONJ_TAC THENL + [MATCH_MP_TAC SUM_SUBSET_SIMPLE THEN + ASM_SIMP_TAC[MEASURE_POS_LE; MEASURABLE_DIFF; MEASURABLE_COMPACT; + FINITE_NUMSEG; SUBSET; IN_NUMSEG]; + ALL_TAC] THEN + MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `sum (n..m) (\i. inv(&2 pow i))` THEN + ASM_SIMP_TAC[SUM_LE_NUMSEG; REAL_LT_IMP_LE] THEN + REWRITE_TAC[REAL_INV_POW; SUM_GP; LT] THEN + COND_CASES_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN MATCH_MP_TAC(REAL_ARITH + `a <= e / &4 /\ &0 <= b + ==> (a - b) / (&1 / &2) <= e / &2`) THEN + REWRITE_TAC[real_div; REAL_MUL_LID; REAL_POW_INV] THEN + ASM_SIMP_TAC[GSYM real_div; REAL_LT_IMP_LE; REAL_LE_INV_EQ; + REAL_LT_POW2]]]; + REWRITE_TAC[SET_RULE `s DIFF (s DIFF t) = s INTER t`] THEN + X_GEN_TAC `x:real^M` THEN REWRITE_TAC[UNIONS_GSPEC; IN_INTER] THEN + REWRITE_TAC[IN_UNIV; IN_ELIM_THM; INTERS_GSPEC] THEN + STRIP_TAC THEN MATCH_MP_TAC LIM_EVENTUALLY THEN + REWRITE_TAC[EVENTUALLY_SEQUENTIALLY] THEN ASM_MESON_TAC[]]]);; diff --git a/Multivariate/misc.ml b/Multivariate/misc.ml new file mode 100644 index 0000000..b6bc121 --- /dev/null +++ b/Multivariate/misc.ml @@ -0,0 +1,526 @@ +(* ========================================================================= *) +(* Various convenient background stuff. *) +(* *) +(* (c) Copyright, John Harrison 1998-2008 *) +(* ========================================================================= *) + +prioritize_real();; + +(* ------------------------------------------------------------------------- *) +(* A couple of extra tactics used in some proofs below. *) +(* ------------------------------------------------------------------------- *) + +let ASSERT_TAC tm = + SUBGOAL_THEN tm STRIP_ASSUME_TAC;; + +let EQ_TRANS_TAC tm = + MATCH_MP_TAC EQ_TRANS THEN EXISTS_TAC tm THEN CONJ_TAC;; + +(* ------------------------------------------------------------------------- *) +(* Miscellaneous lemmas. *) +(* ------------------------------------------------------------------------- *) + +let EXISTS_DIFF = prove + (`(?s:A->bool. P(UNIV DIFF s)) <=> (?s. P s)`, + MESON_TAC[prove(`UNIV DIFF (UNIV DIFF s) = s`,SET_TAC[])]);; + +let GE_REFL = prove + (`!n:num. n >= n`, + REWRITE_TAC[GE; LE_REFL]);; + +let FORALL_SUC = prove + (`(!n. ~(n = 0) ==> P n) <=> (!n. P(SUC n))`, + MESON_TAC[num_CASES; NOT_SUC]);; + +let SEQ_MONO_LEMMA = prove + (`!d e. (!n. n >= m ==> d(n) < e(n)) /\ (!n. n >= m ==> e(n) <= e(m)) + ==> !n:num. n >= m ==> d(n) < e(m)`, + MESON_TAC[GE; REAL_LTE_TRANS]);; + +let REAL_HALF = prove + (`(!e. &0 < e / &2 <=> &0 < e) /\ + (!e. e / &2 + e / &2 = e) /\ + (!e. &2 * (e / &2) = e)`, + REAL_ARITH_TAC);; + +let UPPER_BOUND_FINITE_SET = prove + (`!f:(A->num) s. FINITE(s) ==> ?a. !x. x IN s ==> f(x) <= a`, + GEN_TAC THEN MATCH_MP_TAC FINITE_INDUCT_STRONG THEN + REWRITE_TAC[IN_INSERT; NOT_IN_EMPTY] THEN + MESON_TAC[LE_CASES; LE_REFL; LE_TRANS]);; + +let UPPER_BOUND_FINITE_SET_REAL = prove + (`!f:(A->real) s. FINITE(s) ==> ?a. !x. x IN s ==> f(x) <= a`, + GEN_TAC THEN MATCH_MP_TAC FINITE_INDUCT_STRONG THEN + REWRITE_TAC[IN_INSERT; NOT_IN_EMPTY] THEN + MESON_TAC[REAL_LE_TOTAL; REAL_LE_REFL; REAL_LE_TRANS]);; + +let LOWER_BOUND_FINITE_SET = prove + (`!f:(A->num) s. FINITE(s) ==> ?a. !x. x IN s ==> a <= f(x)`, + GEN_TAC THEN MATCH_MP_TAC FINITE_INDUCT_STRONG THEN + REWRITE_TAC[IN_INSERT; NOT_IN_EMPTY] THEN + MESON_TAC[LE_CASES; LE_REFL; LE_TRANS]);; + +let LOWER_BOUND_FINITE_SET_REAL = prove + (`!f:(A->real) s. FINITE(s) ==> ?a. !x. x IN s ==> a <= f(x)`, + GEN_TAC THEN MATCH_MP_TAC FINITE_INDUCT_STRONG THEN + REWRITE_TAC[IN_INSERT; NOT_IN_EMPTY] THEN + MESON_TAC[REAL_LE_TOTAL; REAL_LE_REFL; REAL_LE_TRANS]);; + +let REAL_CONVEX_BOUND2_LT = prove + (`!x y a u v. x < a /\ y < b /\ &0 <= u /\ &0 <= v /\ u + v = &1 + ==> u * x + v * y < u * a + v * b`, + REPEAT GEN_TAC THEN ASM_CASES_TAC `u = &0` THENL + [ASM_REWRITE_TAC[REAL_MUL_LZERO; REAL_ADD_LID] THEN REPEAT STRIP_TAC; + REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_LTE_ADD2 THEN + ASM_SIMP_TAC[REAL_LE_LMUL; REAL_LT_IMP_LE]] THEN + MATCH_MP_TAC REAL_LT_LMUL THEN ASM_REAL_ARITH_TAC);; + +let REAL_CONVEX_BOUND_LT = prove + (`!x y a u v. x < a /\ y < a /\ &0 <= u /\ &0 <= v /\ (u + v = &1) + ==> u * x + v * y < a`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_LTE_TRANS THEN + EXISTS_TAC `u * a + v * a:real` THEN CONJ_TAC THENL + [ASM_SIMP_TAC[REAL_CONVEX_BOUND2_LT]; + MATCH_MP_TAC REAL_EQ_IMP_LE THEN + UNDISCH_TAC `u + v = &1` THEN CONV_TAC REAL_RING]);; + +let REAL_CONVEX_BOUND_LE = prove + (`!x y a u v. x <= a /\ y <= a /\ &0 <= u /\ &0 <= v /\ (u + v = &1) + ==> u * x + v * y <= a`, + REPEAT STRIP_TAC THEN + MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC `(u + v) * a` THEN + CONJ_TAC THENL [ALL_TAC; ASM_REWRITE_TAC[REAL_LE_REFL; REAL_MUL_LID]] THEN + ASM_SIMP_TAC[REAL_ADD_RDISTRIB; REAL_LE_ADD2; REAL_LE_LMUL]);; + +let INFINITE_ENUMERATE = prove + (`!s:num->bool. + INFINITE s + ==> ?r:num->num. (!m n. m < n ==> r(m) < r(n)) /\ (!n. r n IN s)`, + GEN_TAC THEN REWRITE_TAC[INFINITE; num_FINITE; NOT_EXISTS_THM] THEN + REWRITE_TAC[NOT_FORALL_THM; NOT_IMP; NOT_LE; SKOLEM_THM] THEN + DISCH_THEN(X_CHOOSE_TAC `next:num->num`) THEN + (MP_TAC o prove_recursive_functions_exist num_RECURSION) + `(f(0) = next 0) /\ (!n. f(SUC n) = next(f n))` THEN + MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC THEN STRIP_TAC THEN CONJ_TAC THENL + [GEN_TAC; ALL_TAC] THEN + INDUCT_TAC THEN ASM_REWRITE_TAC[LT] THEN ASM_MESON_TAC[LT_TRANS]);; + +let APPROACHABLE_LT_LE = prove + (`!P f. (?d. &0 < d /\ !x. f(x) < d ==> P x) = + (?d. &0 < d /\ !x. f(x) <= d ==> P x)`, + let lemma = prove + (`&0 < d ==> x <= d / &2 ==> x < d`, + SIMP_TAC[REAL_LE_RDIV_EQ; REAL_OF_NUM_LT; ARITH] THEN REAL_ARITH_TAC) in + MESON_TAC[REAL_LT_IMP_LE; lemma; REAL_HALF]);; + +let REAL_LE_BETWEEN = prove + (`!a b. a <= b <=> ?x. a <= x /\ x <= b`, + MESON_TAC[REAL_LE_TRANS; REAL_LE_REFL]);; + +let REAL_LT_BETWEEN = prove + (`!a b. a < b <=> ?x. a < x /\ x < b`, + REPEAT GEN_TAC THEN EQ_TAC THENL [ALL_TAC; MESON_TAC[REAL_LT_TRANS]] THEN + DISCH_TAC THEN EXISTS_TAC `(a + b) / &2` THEN + SIMP_TAC[REAL_LT_RDIV_EQ; REAL_LT_LDIV_EQ; REAL_OF_NUM_LT; ARITH] THEN + POP_ASSUM MP_TAC THEN REAL_ARITH_TAC);; + +let TRIANGLE_LEMMA = prove + (`!x y z. &0 <= x /\ &0 <= y /\ &0 <= z /\ x pow 2 <= y pow 2 + z pow 2 + ==> x <= y + z`, + REPEAT GEN_TAC THEN + REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN + REWRITE_TAC[REAL_NOT_LE] THEN DISCH_TAC THEN + MATCH_MP_TAC REAL_LET_TRANS THEN EXISTS_TAC `(y + z) pow 2` THEN + ASM_SIMP_TAC[REAL_POW_LT2; REAL_LE_ADD; ARITH_EQ] THEN + ASM_SIMP_TAC[REAL_LE_MUL; REAL_POW_2; REAL_ARITH + `x * x + y * y <= (x + y) * (x + y) <=> &0 <= x * y`]);; + +let LAMBDA_SKOLEM = prove + (`(!i. 1 <= i /\ i <= dimindex(:N) ==> ?x. P i x) = + (?x:A^N. !i. 1 <= i /\ i <= dimindex(:N) ==> P i (x$i))`, + REWRITE_TAC[RIGHT_IMP_EXISTS_THM; SKOLEM_THM] THEN EQ_TAC THENL + [DISCH_THEN(X_CHOOSE_TAC `x:num->A`) THEN + EXISTS_TAC `(lambda i. x i):A^N` THEN ASM_SIMP_TAC[LAMBDA_BETA]; + DISCH_THEN(X_CHOOSE_TAC `x:A^N`) THEN + EXISTS_TAC `\i. (x:A^N)$i` THEN ASM_REWRITE_TAC[]]);; + +let LAMBDA_PAIR = prove + (`(\(x,y). P x y) = (\p. P (FST p) (SND p))`, + REWRITE_TAC[FUN_EQ_THM; FORALL_PAIR_THM] THEN + CONV_TAC(ONCE_DEPTH_CONV GEN_BETA_CONV) THEN REWRITE_TAC[]);; + +let EPSILON_DELTA_MINIMAL = prove + (`!P:real->A->bool Q. + FINITE {x | Q x} /\ + (!d e x. Q x /\ &0 < e /\ e < d ==> P d x ==> P e x) /\ + (!x. Q x ==> ?d. &0 < d /\ P d x) + ==> ?d. &0 < d /\ !x. Q x ==> P d x`, + REWRITE_TAC[IMP_IMP] THEN REPEAT STRIP_TAC THEN + ASM_CASES_TAC `{x:A | Q x} = {}` THENL + [FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [EXTENSION]) THEN + REWRITE_TAC[NOT_IN_EMPTY; IN_ELIM_THM] THEN + DISCH_TAC THEN EXISTS_TAC `&1` THEN ASM_REWRITE_TAC[REAL_LT_01]; + FIRST_X_ASSUM(MP_TAC o + GEN_REWRITE_RULE BINDER_CONV [RIGHT_IMP_EXISTS_THM]) THEN + REWRITE_TAC[SKOLEM_THM; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `d:A->real` THEN DISCH_TAC THEN + EXISTS_TAC `inf(IMAGE d {x:A | Q x})` THEN + ASM_SIMP_TAC[REAL_LT_INF_FINITE; FINITE_IMAGE; IMAGE_EQ_EMPTY] THEN + ASM_SIMP_TAC[FORALL_IN_IMAGE; FORALL_IN_GSPEC] THEN + X_GEN_TAC `a:A` THEN DISCH_TAC THEN + SUBGOAL_THEN + `&0 < inf(IMAGE d {x:A | Q x}) /\ inf(IMAGE d {x | Q x}) <= d a` + MP_TAC THENL + [ASM_SIMP_TAC[REAL_LT_INF_FINITE; REAL_INF_LE_FINITE; + FINITE_IMAGE; IMAGE_EQ_EMPTY] THEN + REWRITE_TAC[EXISTS_IN_IMAGE; FORALL_IN_IMAGE; IN_ELIM_THM] THEN + ASM_MESON_TAC[REAL_LE_REFL]; + REWRITE_TAC[REAL_LE_LT] THEN STRIP_TAC THEN ASM_SIMP_TAC[] THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN + EXISTS_TAC `(d:A->real) a` THEN ASM_SIMP_TAC[]]]);; + +(* ------------------------------------------------------------------------- *) +(* A generic notion of "hull" (convex, affine, conic hull and closure). *) +(* ------------------------------------------------------------------------- *) + +parse_as_infix("hull",(21,"left"));; + +let hull = new_definition + `P hull s = INTERS {t | P t /\ s SUBSET t}`;; + +let HULL_P = prove + (`!P s. P s ==> (P hull s = s)`, + REWRITE_TAC[hull; EXTENSION; IN_INTERS; IN_ELIM_THM] THEN + MESON_TAC[SUBSET]);; + +let P_HULL = prove + (`!P s. (!f. (!s. s IN f ==> P s) ==> P(INTERS f)) ==> P(P hull s)`, + REWRITE_TAC[hull] THEN SIMP_TAC[IN_ELIM_THM]);; + +let HULL_EQ = prove + (`!P s. (!f. (!s. s IN f ==> P s) ==> P(INTERS f)) + ==> ((P hull s = s) <=> P s)`, + MESON_TAC[P_HULL; HULL_P]);; + +let HULL_HULL = prove + (`!P s. P hull (P hull s) = P hull s`, + REWRITE_TAC[hull; EXTENSION; IN_INTERS; IN_ELIM_THM; SUBSET] THEN + MESON_TAC[]);; + +let HULL_SUBSET = prove + (`!P s. s SUBSET (P hull s)`, + REWRITE_TAC[hull; SUBSET; IN_INTERS; IN_ELIM_THM] THEN MESON_TAC[]);; + +let HULL_MONO = prove + (`!P s t. s SUBSET t ==> (P hull s) SUBSET (P hull t)`, + REWRITE_TAC[hull; SUBSET; IN_INTERS; IN_ELIM_THM] THEN MESON_TAC[]);; + +let HULL_ANTIMONO = prove + (`!P Q s. P SUBSET Q ==> (Q hull s) SUBSET (P hull s)`, + REWRITE_TAC[SUBSET; hull; IN_INTERS; IN_ELIM_THM] THEN MESON_TAC[IN]);; + +let HULL_MINIMAL = prove + (`!P s t. s SUBSET t /\ P t ==> (P hull s) SUBSET t`, + REWRITE_TAC[hull; SUBSET; IN_INTERS; IN_ELIM_THM] THEN MESON_TAC[]);; + +let SUBSET_HULL = prove + (`!P s t. P t ==> ((P hull s) SUBSET t <=> s SUBSET t)`, + REWRITE_TAC[hull; SUBSET; IN_INTERS; IN_ELIM_THM] THEN MESON_TAC[]);; + +let HULL_UNIQUE = prove + (`!P s t. s SUBSET t /\ P t /\ (!t'. s SUBSET t' /\ P t' ==> t SUBSET t') + ==> (P hull s = t)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN + REWRITE_TAC[hull; SUBSET; IN_INTERS; IN_ELIM_THM] THEN + ASM_MESON_TAC[SUBSET_HULL; SUBSET]);; + +let HULL_UNION_SUBSET = prove + (`!P s t. (P hull s) UNION (P hull t) SUBSET (P hull (s UNION t))`, + SIMP_TAC[UNION_SUBSET; HULL_MONO; SUBSET_UNION]);; + +let HULL_UNION = prove + (`!P s t. P hull (s UNION t) = P hull (P hull s UNION P hull t)`, + REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[hull] THEN + AP_TERM_TAC THEN REWRITE_TAC[EXTENSION; IN_ELIM_THM; UNION_SUBSET] THEN + MESON_TAC[SUBSET_HULL]);; + +let HULL_UNION_LEFT = prove + (`!P s t:A->bool. + P hull (s UNION t) = P hull (P hull s UNION t)`, + REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[hull] THEN + AP_TERM_TAC THEN REWRITE_TAC[EXTENSION; IN_ELIM_THM; UNION_SUBSET] THEN + MESON_TAC[SUBSET_HULL]);; + +let HULL_UNION_RIGHT = prove + (`!P s t:A->bool. + P hull (s UNION t) = P hull (s UNION P hull t)`, + REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[hull] THEN + AP_TERM_TAC THEN REWRITE_TAC[EXTENSION; IN_ELIM_THM; UNION_SUBSET] THEN + MESON_TAC[SUBSET_HULL]);; + +let HULL_REDUNDANT_EQ = prove + (`!P a s. a IN (P hull s) <=> (P hull (a INSERT s) = P hull s)`, + REWRITE_TAC[hull] THEN SET_TAC[]);; + +let HULL_REDUNDANT = prove + (`!P a s. a IN (P hull s) ==> (P hull (a INSERT s) = P hull s)`, + REWRITE_TAC[HULL_REDUNDANT_EQ]);; + +let HULL_INDUCT = prove + (`!P p s. (!x:A. x IN s ==> p x) /\ P {x | p x} + ==> !x. x IN P hull s ==> p x`, + REPEAT GEN_TAC THEN + MP_TAC(ISPECL [`P:(A->bool)->bool`; `s:A->bool`; `{x:A | p x}`] + HULL_MINIMAL) THEN + REWRITE_TAC[SUBSET; IN_ELIM_THM]);; + +let HULL_INC = prove + (`!P s x. x IN s ==> x IN P hull s`, + MESON_TAC[REWRITE_RULE[SUBSET] HULL_SUBSET]);; + +let HULL_IMAGE_SUBSET = prove + (`!P f s. P(P hull s) /\ (!s. P s ==> P(IMAGE f s)) + ==> P hull (IMAGE f s) SUBSET (IMAGE f (P hull s))`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC HULL_MINIMAL THEN + ASM_SIMP_TAC[IMAGE_SUBSET; HULL_SUBSET]);; + +let HULL_IMAGE_GALOIS = prove + (`!P f g s. (!s. P(P hull s)) /\ + (!s. P s ==> P(IMAGE f s)) /\ (!s. P s ==> P(IMAGE g s)) /\ + (!s t. s SUBSET IMAGE g t <=> IMAGE f s SUBSET t) + ==> P hull (IMAGE f s) = IMAGE f (P hull s)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN + ASM_SIMP_TAC[HULL_IMAGE_SUBSET] THEN + FIRST_ASSUM(fun th -> GEN_REWRITE_TAC I [GSYM th]) THEN + MATCH_MP_TAC HULL_MINIMAL THEN + ASM_SIMP_TAC[HULL_SUBSET]);; + +let HULL_IMAGE = prove + (`!P f s. (!s. P(P hull s)) /\ (!s. P(IMAGE f s) <=> P s) /\ + (!x y:A. f x = f y ==> x = y) /\ (!y. ?x. f x = y) + ==> P hull (IMAGE f s) = IMAGE f (P hull s)`, + REPEAT GEN_TAC THEN + REPLICATE_TAC 2 (DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + REWRITE_TAC[BIJECTIVE_LEFT_RIGHT_INVERSE] THEN + DISCH_THEN(X_CHOOSE_THEN `g:A->A` STRIP_ASSUME_TAC) THEN + MATCH_MP_TAC HULL_IMAGE_GALOIS THEN EXISTS_TAC `g:A->A` THEN + ASM_REWRITE_TAC[] THEN CONJ_TAC THENL [ALL_TAC; ASM SET_TAC[]] THEN + X_GEN_TAC `s:A->bool` THEN + FIRST_X_ASSUM(fun th -> GEN_REWRITE_TAC RAND_CONV [GSYM th]) THEN + MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN ASM SET_TAC[]);; + +let IS_HULL = prove + (`!P s. (!f. (!s. s IN f ==> P s) ==> P(INTERS f)) + ==> (P s <=> ?t. s = P hull t)`, + MESON_TAC[HULL_P; P_HULL]);; + +let HULLS_EQ = prove + (`!P s t. + (!f. (!s. s IN f ==> P s) ==> P (INTERS f)) /\ + s SUBSET P hull t /\ t SUBSET P hull s + ==> P hull s = P hull t`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN + CONJ_TAC THEN MATCH_MP_TAC HULL_MINIMAL THEN + ASM_SIMP_TAC[P_HULL]);; + +let HULL_P_AND_Q = prove + (`!P Q. (!f. (!s. s IN f ==> P s) ==> P(INTERS f)) /\ + (!f. (!s. s IN f ==> Q s) ==> Q(INTERS f)) /\ + (!s. Q s ==> Q(P hull s)) + ==> (\x. P x /\ Q x) hull s = P hull (Q hull s)`, + REPEAT STRIP_TAC THEN + MATCH_MP_TAC HULL_UNIQUE THEN ASM_SIMP_TAC[HULL_INC; SUBSET_HULL] THEN + ASM_MESON_TAC[P_HULL; HULL_SUBSET; SUBSET_TRANS]);; + +(* ------------------------------------------------------------------------- *) +(* More variants of the Archimedian property and useful consequences. *) +(* ------------------------------------------------------------------------- *) + +let REAL_ARCH_INV = prove + (`!e. &0 < e <=> ?n. ~(n = 0) /\ &0 < inv(&n) /\ inv(&n) < e`, + GEN_TAC THEN EQ_TAC THENL [ALL_TAC; MESON_TAC[REAL_LT_TRANS]] THEN + DISCH_TAC THEN MP_TAC(SPEC `inv(e)` REAL_ARCH_LT) THEN + MATCH_MP_TAC MONO_EXISTS THEN + ASM_MESON_TAC[REAL_LT_INV2; REAL_INV_INV; REAL_LT_INV_EQ; REAL_LT_TRANS; + REAL_LT_ANTISYM]);; + +let REAL_POW_LBOUND = prove + (`!x n. &0 <= x ==> &1 + &n * x <= (&1 + x) pow n`, + GEN_TAC THEN REWRITE_TAC[RIGHT_FORALL_IMP_THM] THEN DISCH_TAC THEN + INDUCT_TAC THEN + REWRITE_TAC[real_pow; REAL_MUL_LZERO; REAL_ADD_RID; REAL_LE_REFL] THEN + REWRITE_TAC[GSYM REAL_OF_NUM_SUC] THEN + MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC `(&1 + x) * (&1 + &n * x)` THEN + ASM_SIMP_TAC[REAL_LE_LMUL; REAL_ARITH `&0 <= x ==> &0 <= &1 + x`] THEN + ASM_SIMP_TAC[REAL_LE_MUL; REAL_POS; REAL_ARITH + `&1 + (n + &1) * x <= (&1 + x) * (&1 + n * x) <=> &0 <= n * x * x`]);; + +let REAL_ARCH_POW = prove + (`!x y. &1 < x ==> ?n. y < x pow n`, + REPEAT STRIP_TAC THEN + MP_TAC(SPEC `x - &1` REAL_ARCH) THEN ASM_REWRITE_TAC[REAL_SUB_LT] THEN + DISCH_THEN(MP_TAC o SPEC `y:real`) THEN MATCH_MP_TAC MONO_EXISTS THEN + X_GEN_TAC `n:num` THEN DISCH_TAC THEN MATCH_MP_TAC REAL_LTE_TRANS THEN + EXISTS_TAC `&1 + &n * (x - &1)` THEN + ASM_SIMP_TAC[REAL_ARITH `x < y ==> x < &1 + y`] THEN + ASM_MESON_TAC[REAL_POW_LBOUND; REAL_SUB_ADD2; REAL_ARITH + `&1 < x ==> &0 <= x - &1`]);; + +let REAL_ARCH_POW2 = prove + (`!x. ?n. x < &2 pow n`, + SIMP_TAC[REAL_ARCH_POW; REAL_OF_NUM_LT; ARITH]);; + +let REAL_ARCH_POW_INV = prove + (`!x y. &0 < y /\ x < &1 ==> ?n. x pow n < y`, + REPEAT STRIP_TAC THEN ASM_CASES_TAC `&0 < x` THENL + [ALL_TAC; ASM_MESON_TAC[REAL_POW_1; REAL_LET_TRANS; REAL_NOT_LT]] THEN + SUBGOAL_THEN `inv(&1) < inv(x)` MP_TAC THENL + [ASM_SIMP_TAC[REAL_LT_INV2]; REWRITE_TAC[REAL_INV_1]] THEN + DISCH_THEN(MP_TAC o SPEC `inv(y)` o MATCH_MP REAL_ARCH_POW) THEN + MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC THEN DISCH_TAC THEN + GEN_REWRITE_TAC BINOP_CONV [GSYM REAL_INV_INV] THEN + ASM_SIMP_TAC[GSYM REAL_POW_INV; REAL_LT_INV; REAL_LT_INV2]);; + +let FORALL_POS_MONO = prove + (`!P. (!d e. d < e /\ P d ==> P e) /\ (!n. ~(n = 0) ==> P(inv(&n))) + ==> !e. &0 < e ==> P e`, + MESON_TAC[REAL_ARCH_INV; REAL_LT_TRANS]);; + +let FORALL_POS_MONO_1 = prove + (`!P. (!d e. d < e /\ P d ==> P e) /\ (!n. P(inv(&n + &1))) + ==> !e. &0 < e ==> P e`, + REWRITE_TAC[REAL_OF_NUM_SUC; GSYM FORALL_SUC; FORALL_POS_MONO]);; + +let REAL_ARCH_RDIV_EQ_0 = prove + (`!x c. &0 <= x /\ &0 <= c /\ (!m. 0 < m ==> &m * x <= c) ==> x = &0`, + SIMP_TAC [GSYM REAL_LE_ANTISYM; GSYM REAL_NOT_LT] THEN REPEAT STRIP_TAC THEN + POP_ASSUM (STRIP_ASSUME_TAC o SPEC `c:real` o MATCH_MP REAL_ARCH) THEN + ASM_CASES_TAC `n=0` THENL + [POP_ASSUM SUBST_ALL_TAC THEN + RULE_ASSUM_TAC (REWRITE_RULE [REAL_MUL_LZERO]) THEN + ASM_MESON_TAC [REAL_LET_ANTISYM]; + ASM_MESON_TAC [REAL_LET_ANTISYM; REAL_MUL_SYM; LT_NZ]]);; + +(* ------------------------------------------------------------------------- *) +(* Relate max and min to sup and inf. *) +(* ------------------------------------------------------------------------- *) + +let REAL_MAX_SUP = prove + (`!x y. max x y = sup {x,y}`, + SIMP_TAC[GSYM REAL_LE_ANTISYM; REAL_SUP_LE_FINITE; REAL_LE_SUP_FINITE; + FINITE_RULES; NOT_INSERT_EMPTY; REAL_MAX_LE; REAL_LE_MAX] THEN + REWRITE_TAC[IN_INSERT; NOT_IN_EMPTY] THEN MESON_TAC[REAL_LE_TOTAL]);; + +let REAL_MIN_INF = prove + (`!x y. min x y = inf {x,y}`, + SIMP_TAC[GSYM REAL_LE_ANTISYM; REAL_INF_LE_FINITE; REAL_LE_INF_FINITE; + FINITE_RULES; NOT_INSERT_EMPTY; REAL_MIN_LE; REAL_LE_MIN] THEN + REWRITE_TAC[IN_INSERT; NOT_IN_EMPTY] THEN MESON_TAC[REAL_LE_TOTAL]);; + +(* ------------------------------------------------------------------------- *) +(* Define square root here to decouple it from the existing analysis theory. *) +(* ------------------------------------------------------------------------- *) + +let sqrt = new_definition + `sqrt(x) = @y. &0 <= y /\ (y pow 2 = x)`;; + +let SQRT_UNIQUE = prove + (`!x y. &0 <= y /\ (y pow 2 = x) ==> (sqrt(x) = y)`, + REPEAT STRIP_TAC THEN REWRITE_TAC[sqrt] THEN MATCH_MP_TAC SELECT_UNIQUE THEN + FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN REWRITE_TAC[REAL_POW_2] THEN + REWRITE_TAC[REAL_ARITH `(x * x = y * y) <=> ((x + y) * (x - y) = &0)`] THEN + REWRITE_TAC[REAL_ENTIRE] THEN POP_ASSUM MP_TAC THEN REAL_ARITH_TAC);; + +let POW_2_SQRT = prove + (`!x. &0 <= x ==> (sqrt(x pow 2) = x)`, + MESON_TAC[SQRT_UNIQUE]);; + +let SQRT_0 = prove + (`sqrt(&0) = &0`, + MESON_TAC[SQRT_UNIQUE; REAL_POW_2; REAL_MUL_LZERO; REAL_POS]);; + +let SQRT_1 = prove + (`sqrt(&1) = &1`, + MESON_TAC[SQRT_UNIQUE; REAL_POW_2; REAL_MUL_LID; REAL_POS]);; + +let POW_2_SQRT_ABS = prove + (`!x. sqrt(x pow 2) = abs(x)`, + GEN_TAC THEN MATCH_MP_TAC SQRT_UNIQUE THEN + REWRITE_TAC[REAL_ABS_POS; REAL_POW_2; GSYM REAL_ABS_MUL] THEN + REWRITE_TAC[real_abs; REAL_LE_SQUARE]);; + +(* ------------------------------------------------------------------------- *) +(* Geometric progression. *) +(* ------------------------------------------------------------------------- *) + +let SUM_GP_BASIC = prove + (`!x n. (&1 - x) * sum(0..n) (\i. x pow i) = &1 - x pow (SUC n)`, + GEN_TAC THEN INDUCT_TAC THEN REWRITE_TAC[SUM_CLAUSES_NUMSEG] THEN + REWRITE_TAC[real_pow; REAL_MUL_RID; LE_0] THEN + ASM_REWRITE_TAC[REAL_ADD_LDISTRIB; real_pow] THEN REAL_ARITH_TAC);; + +let SUM_GP_MULTIPLIED = prove + (`!x m n. m <= n + ==> ((&1 - x) * sum(m..n) (\i. x pow i) = x pow m - x pow (SUC n))`, + REPEAT STRIP_TAC THEN ASM_SIMP_TAC + [SUM_OFFSET_0; REAL_POW_ADD; REAL_MUL_ASSOC; SUM_GP_BASIC; SUM_RMUL] THEN + REWRITE_TAC[REAL_SUB_RDISTRIB; GSYM REAL_POW_ADD; REAL_MUL_LID] THEN + ASM_SIMP_TAC[ARITH_RULE `m <= n ==> (SUC(n - m) + m = SUC n)`]);; + +let SUM_GP = prove + (`!x m n. + sum(m..n) (\i. x pow i) = + if n < m then &0 + else if x = &1 then &((n + 1) - m) + else (x pow m - x pow (SUC n)) / (&1 - x)`, + REPEAT GEN_TAC THEN + DISJ_CASES_TAC(ARITH_RULE `n < m \/ ~(n < m) /\ m <= n:num`) THEN + ASM_SIMP_TAC[SUM_TRIV_NUMSEG] THEN COND_CASES_TAC THENL + [ASM_REWRITE_TAC[REAL_POW_ONE; SUM_CONST_NUMSEG; REAL_MUL_RID]; ALL_TAC] THEN + MATCH_MP_TAC REAL_EQ_LCANCEL_IMP THEN EXISTS_TAC `&1 - x` THEN + ASM_SIMP_TAC[REAL_DIV_LMUL; REAL_SUB_0; SUM_GP_MULTIPLIED]);; + +let SUM_GP_OFFSET = prove + (`!x m n. sum(m..m+n) (\i. x pow i) = + if x = &1 then &n + &1 + else x pow m * (&1 - x pow (SUC n)) / (&1 - x)`, + REPEAT GEN_TAC THEN REWRITE_TAC[SUM_GP; ARITH_RULE `~(m + n < m:num)`] THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[] THENL + [REWRITE_TAC[REAL_OF_NUM_ADD] THEN AP_TERM_TAC THEN ARITH_TAC; + REWRITE_TAC[real_div; real_pow; REAL_POW_ADD] THEN REAL_ARITH_TAC]);; + +(* ------------------------------------------------------------------------- *) +(* Segment of natural numbers starting at a specific number. *) +(* ------------------------------------------------------------------------- *) + +let from = new_definition + `from n = {m:num | n <= m}`;; + +let FROM_0 = prove + (`from 0 = (:num)`, + REWRITE_TAC[from; LE_0] THEN SET_TAC[]);; + +let FROM_INTER_NUMSEG_GEN = prove + (`!k m n. (from k) INTER (m..n) = (if m < k then k..n else m..n)`, + REPEAT GEN_TAC THEN COND_CASES_TAC THEN POP_ASSUM MP_TAC THEN + REWRITE_TAC[from; IN_ELIM_THM; IN_INTER; IN_NUMSEG; EXTENSION] THEN + ARITH_TAC);; + +let FROM_INTER_NUMSEG = prove + (`!k n. (from k) INTER (0..n) = k..n`, + REWRITE_TAC[from; IN_ELIM_THM; IN_INTER; IN_NUMSEG; EXTENSION] THEN + ARITH_TAC);; + +let IN_FROM = prove + (`!m n. m IN from n <=> n <= m`, + REWRITE_TAC[from; IN_ELIM_THM]);; + +let INFINITE_FROM = prove + (`!n. INFINITE(from n)`, + GEN_TAC THEN + SUBGOAL_THEN `from n = (:num) DIFF {i | i < n}` + (fun th -> SIMP_TAC[th; INFINITE_DIFF_FINITE; FINITE_NUMSEG_LT; + num_INFINITE]) THEN + REWRITE_TAC[EXTENSION; from; IN_DIFF; IN_UNIV; IN_ELIM_THM] THEN ARITH_TAC);; diff --git a/Multivariate/multivariate_database.ml b/Multivariate/multivariate_database.ml new file mode 100644 index 0000000..5b85747 --- /dev/null +++ b/Multivariate/multivariate_database.ml @@ -0,0 +1,8226 @@ +needs "help.ml";; + +theorems := +[ +"ABSOLUTELY_INTEGRABLE_0",ABSOLUTELY_INTEGRABLE_0; +"ABSOLUTELY_INTEGRABLE_ABS",ABSOLUTELY_INTEGRABLE_ABS; +"ABSOLUTELY_INTEGRABLE_ABSOLUTELY_INTEGRABLE_BOUND",ABSOLUTELY_INTEGRABLE_ABSOLUTELY_INTEGRABLE_BOUND; +"ABSOLUTELY_INTEGRABLE_ABSOLUTELY_INTEGRABLE_COMPONENT_LBOUND",ABSOLUTELY_INTEGRABLE_ABSOLUTELY_INTEGRABLE_COMPONENT_LBOUND; +"ABSOLUTELY_INTEGRABLE_ABSOLUTELY_INTEGRABLE_COMPONENT_UBOUND",ABSOLUTELY_INTEGRABLE_ABSOLUTELY_INTEGRABLE_COMPONENT_UBOUND; +"ABSOLUTELY_INTEGRABLE_ABSOLUTELY_INTEGRABLE_DROP_LBOUND",ABSOLUTELY_INTEGRABLE_ABSOLUTELY_INTEGRABLE_DROP_LBOUND; +"ABSOLUTELY_INTEGRABLE_ABSOLUTELY_INTEGRABLE_DROP_UBOUND",ABSOLUTELY_INTEGRABLE_ABSOLUTELY_INTEGRABLE_DROP_UBOUND; +"ABSOLUTELY_INTEGRABLE_ABS_1",ABSOLUTELY_INTEGRABLE_ABS_1; +"ABSOLUTELY_INTEGRABLE_ABS_EQ",ABSOLUTELY_INTEGRABLE_ABS_EQ; +"ABSOLUTELY_INTEGRABLE_ADD",ABSOLUTELY_INTEGRABLE_ADD; +"ABSOLUTELY_INTEGRABLE_APPROXIMATE_CONTINUOUS",ABSOLUTELY_INTEGRABLE_APPROXIMATE_CONTINUOUS; +"ABSOLUTELY_INTEGRABLE_BOUNDED_SETVARIATION",ABSOLUTELY_INTEGRABLE_BOUNDED_SETVARIATION; +"ABSOLUTELY_INTEGRABLE_BOUNDED_SETVARIATION_EQ",ABSOLUTELY_INTEGRABLE_BOUNDED_SETVARIATION_EQ; +"ABSOLUTELY_INTEGRABLE_BOUNDED_SETVARIATION_UNIV_EQ",ABSOLUTELY_INTEGRABLE_BOUNDED_SETVARIATION_UNIV_EQ; +"ABSOLUTELY_INTEGRABLE_CMUL",ABSOLUTELY_INTEGRABLE_CMUL; +"ABSOLUTELY_INTEGRABLE_COMPONENTWISE",ABSOLUTELY_INTEGRABLE_COMPONENTWISE; +"ABSOLUTELY_INTEGRABLE_CONST",ABSOLUTELY_INTEGRABLE_CONST; +"ABSOLUTELY_INTEGRABLE_CONTINUOUS",ABSOLUTELY_INTEGRABLE_CONTINUOUS; +"ABSOLUTELY_INTEGRABLE_IMP_INTEGRABLE",ABSOLUTELY_INTEGRABLE_IMP_INTEGRABLE; +"ABSOLUTELY_INTEGRABLE_INF_1",ABSOLUTELY_INTEGRABLE_INF_1; +"ABSOLUTELY_INTEGRABLE_INTEGRABLE_BOUND",ABSOLUTELY_INTEGRABLE_INTEGRABLE_BOUND; +"ABSOLUTELY_INTEGRABLE_LE",ABSOLUTELY_INTEGRABLE_LE; +"ABSOLUTELY_INTEGRABLE_LEBESGUE_POINTS",ABSOLUTELY_INTEGRABLE_LEBESGUE_POINTS; +"ABSOLUTELY_INTEGRABLE_LINEAR",ABSOLUTELY_INTEGRABLE_LINEAR; +"ABSOLUTELY_INTEGRABLE_MAX",ABSOLUTELY_INTEGRABLE_MAX; +"ABSOLUTELY_INTEGRABLE_MAX_1",ABSOLUTELY_INTEGRABLE_MAX_1; +"ABSOLUTELY_INTEGRABLE_MEASURABLE",ABSOLUTELY_INTEGRABLE_MEASURABLE; +"ABSOLUTELY_INTEGRABLE_MIN",ABSOLUTELY_INTEGRABLE_MIN; +"ABSOLUTELY_INTEGRABLE_MIN_1",ABSOLUTELY_INTEGRABLE_MIN_1; +"ABSOLUTELY_INTEGRABLE_NEG",ABSOLUTELY_INTEGRABLE_NEG; +"ABSOLUTELY_INTEGRABLE_NORM",ABSOLUTELY_INTEGRABLE_NORM; +"ABSOLUTELY_INTEGRABLE_ON_CONST",ABSOLUTELY_INTEGRABLE_ON_CONST; +"ABSOLUTELY_INTEGRABLE_ON_SUBINTERVAL",ABSOLUTELY_INTEGRABLE_ON_SUBINTERVAL; +"ABSOLUTELY_INTEGRABLE_RESTRICT_UNIV",ABSOLUTELY_INTEGRABLE_RESTRICT_UNIV; +"ABSOLUTELY_INTEGRABLE_SET_VARIATION",ABSOLUTELY_INTEGRABLE_SET_VARIATION; +"ABSOLUTELY_INTEGRABLE_SUB",ABSOLUTELY_INTEGRABLE_SUB; +"ABSOLUTELY_INTEGRABLE_SUP_1",ABSOLUTELY_INTEGRABLE_SUP_1; +"ABSOLUTELY_INTEGRABLE_VSUM",ABSOLUTELY_INTEGRABLE_VSUM; +"ABSOLUTE_RETRACTION_CONVEX_CLOSED",ABSOLUTE_RETRACTION_CONVEX_CLOSED; +"ABSOLUTE_RETRACTION_CONVEX_CLOSED_RELATIVE",ABSOLUTE_RETRACTION_CONVEX_CLOSED_RELATIVE; +"ABSOLUTE_RETRACT_CONTRACTIBLE_ANR",ABSOLUTE_RETRACT_CONTRACTIBLE_ANR; +"ABSOLUTE_RETRACT_CONVEX_CLOSED",ABSOLUTE_RETRACT_CONVEX_CLOSED; +"ABSOLUTE_RETRACT_HOMEOMORPHIC_CONVEX_COMPACT",ABSOLUTE_RETRACT_HOMEOMORPHIC_CONVEX_COMPACT; +"ABSOLUTE_RETRACT_IMP_AR",ABSOLUTE_RETRACT_IMP_AR; +"ABSOLUTE_RETRACT_IMP_AR_GEN",ABSOLUTE_RETRACT_IMP_AR_GEN; +"ABSOLUTE_RETRACT_PATH_IMAGE_ARC",ABSOLUTE_RETRACT_PATH_IMAGE_ARC; +"ABSORPTION",ABSORPTION; +"ABS_DROP",ABS_DROP; +"ABS_SIMP",ABS_SIMP; +"ADD",ADD; +"ADD1",ADD1; +"ADDITIVE_CONTENT_DIVISION",ADDITIVE_CONTENT_DIVISION; +"ADDITIVE_CONTENT_TAGGED_DIVISION",ADDITIVE_CONTENT_TAGGED_DIVISION; +"ADDITIVE_TAGGED_DIVISION_1",ADDITIVE_TAGGED_DIVISION_1; +"ADD_0",ADD_0; +"ADD_AC",ADD_AC; +"ADD_ASSOC",ADD_ASSOC; +"ADD_CLAUSES",ADD_CLAUSES; +"ADD_EQ_0",ADD_EQ_0; +"ADD_SUB",ADD_SUB; +"ADD_SUB2",ADD_SUB2; +"ADD_SUBR",ADD_SUBR; +"ADD_SUBR2",ADD_SUBR2; +"ADD_SUC",ADD_SUC; +"ADD_SYM",ADD_SYM; +"ADJOINT_ADJOINT",ADJOINT_ADJOINT; +"ADJOINT_CLAUSES",ADJOINT_CLAUSES; +"ADJOINT_COMPOSE",ADJOINT_COMPOSE; +"ADJOINT_INJECTIVE",ADJOINT_INJECTIVE; +"ADJOINT_INJECTIVE_INJECTIVE",ADJOINT_INJECTIVE_INJECTIVE; +"ADJOINT_INJECTIVE_INJECTIVE_0",ADJOINT_INJECTIVE_INJECTIVE_0; +"ADJOINT_LINEAR",ADJOINT_LINEAR; +"ADJOINT_MATRIX",ADJOINT_MATRIX; +"ADJOINT_SURJECTIVE",ADJOINT_SURJECTIVE; +"ADJOINT_UNIQUE",ADJOINT_UNIQUE; +"ADJOINT_WORKS",ADJOINT_WORKS; +"ADMISSIBLE_BASE",ADMISSIBLE_BASE; +"ADMISSIBLE_COMB",ADMISSIBLE_COMB; +"ADMISSIBLE_COND",ADMISSIBLE_COND; +"ADMISSIBLE_CONST",ADMISSIBLE_CONST; +"ADMISSIBLE_GUARDED_PATTERN",ADMISSIBLE_GUARDED_PATTERN; +"ADMISSIBLE_IMP_SUPERADMISSIBLE",ADMISSIBLE_IMP_SUPERADMISSIBLE; +"ADMISSIBLE_LAMBDA",ADMISSIBLE_LAMBDA; +"ADMISSIBLE_MAP",ADMISSIBLE_MAP; +"ADMISSIBLE_MATCH",ADMISSIBLE_MATCH; +"ADMISSIBLE_MATCH_SEQPATTERN",ADMISSIBLE_MATCH_SEQPATTERN; +"ADMISSIBLE_NEST",ADMISSIBLE_NEST; +"ADMISSIBLE_NSUM",ADMISSIBLE_NSUM; +"ADMISSIBLE_RAND",ADMISSIBLE_RAND; +"ADMISSIBLE_SEQPATTERN",ADMISSIBLE_SEQPATTERN; +"ADMISSIBLE_SUM",ADMISSIBLE_SUM; +"ADMISSIBLE_UNGUARDED_PATTERN",ADMISSIBLE_UNGUARDED_PATTERN; +"AFFINE",AFFINE; +"AFFINE_AFFINE_HULL",AFFINE_AFFINE_HULL; +"AFFINE_AFFINITY",AFFINE_AFFINITY; +"AFFINE_ALT",AFFINE_ALT; +"AFFINE_BASIS_EXISTS",AFFINE_BASIS_EXISTS; +"AFFINE_BOUNDED_EQ_LOWDIM",AFFINE_BOUNDED_EQ_LOWDIM; +"AFFINE_BOUNDED_EQ_TRIVIAL",AFFINE_BOUNDED_EQ_TRIVIAL; +"AFFINE_DEPENDENT_BIGGERSET",AFFINE_DEPENDENT_BIGGERSET; +"AFFINE_DEPENDENT_BIGGERSET_GENERAL",AFFINE_DEPENDENT_BIGGERSET_GENERAL; +"AFFINE_DEPENDENT_CHOOSE",AFFINE_DEPENDENT_CHOOSE; +"AFFINE_DEPENDENT_EXPLICIT",AFFINE_DEPENDENT_EXPLICIT; +"AFFINE_DEPENDENT_EXPLICIT_FINITE",AFFINE_DEPENDENT_EXPLICIT_FINITE; +"AFFINE_DEPENDENT_IMP_COLLINEAR_3",AFFINE_DEPENDENT_IMP_COLLINEAR_3; +"AFFINE_DEPENDENT_IMP_DEPENDENT",AFFINE_DEPENDENT_IMP_DEPENDENT; +"AFFINE_DEPENDENT_LINEAR_IMAGE",AFFINE_DEPENDENT_LINEAR_IMAGE; +"AFFINE_DEPENDENT_LINEAR_IMAGE_EQ",AFFINE_DEPENDENT_LINEAR_IMAGE_EQ; +"AFFINE_DEPENDENT_MONO",AFFINE_DEPENDENT_MONO; +"AFFINE_DEPENDENT_TRANSLATION",AFFINE_DEPENDENT_TRANSLATION; +"AFFINE_DEPENDENT_TRANSLATION_EQ",AFFINE_DEPENDENT_TRANSLATION_EQ; +"AFFINE_DIFFERENCES",AFFINE_DIFFERENCES; +"AFFINE_DIFFS_SUBSPACE",AFFINE_DIFFS_SUBSPACE; +"AFFINE_EMPTY",AFFINE_EMPTY; +"AFFINE_EQ_SUBSPACE",AFFINE_EQ_SUBSPACE; +"AFFINE_EXPLICIT",AFFINE_EXPLICIT; +"AFFINE_HULLS_EQ",AFFINE_HULLS_EQ; +"AFFINE_HULL_2",AFFINE_HULL_2; +"AFFINE_HULL_2_ALT",AFFINE_HULL_2_ALT; +"AFFINE_HULL_3",AFFINE_HULL_3; +"AFFINE_HULL_3_IMP_COLLINEAR",AFFINE_HULL_3_IMP_COLLINEAR; +"AFFINE_HULL_AFFINE_INTER_NONEMPTY_INTERIOR",AFFINE_HULL_AFFINE_INTER_NONEMPTY_INTERIOR; +"AFFINE_HULL_AFFINE_INTER_OPEN",AFFINE_HULL_AFFINE_INTER_OPEN; +"AFFINE_HULL_AFFINE_INTER_OPEN_IN",AFFINE_HULL_AFFINE_INTER_OPEN_IN; +"AFFINE_HULL_CLOSURE",AFFINE_HULL_CLOSURE; +"AFFINE_HULL_CONVEX_HULL",AFFINE_HULL_CONVEX_HULL; +"AFFINE_HULL_CONVEX_INTER_NONEMPTY_INTERIOR",AFFINE_HULL_CONVEX_INTER_NONEMPTY_INTERIOR; +"AFFINE_HULL_CONVEX_INTER_OPEN",AFFINE_HULL_CONVEX_INTER_OPEN; +"AFFINE_HULL_CONVEX_INTER_OPEN_IN",AFFINE_HULL_CONVEX_INTER_OPEN_IN; +"AFFINE_HULL_EMPTY",AFFINE_HULL_EMPTY; +"AFFINE_HULL_EQ",AFFINE_HULL_EQ; +"AFFINE_HULL_EQ_EMPTY",AFFINE_HULL_EQ_EMPTY; +"AFFINE_HULL_EQ_SING",AFFINE_HULL_EQ_SING; +"AFFINE_HULL_EQ_SPAN",AFFINE_HULL_EQ_SPAN; +"AFFINE_HULL_EQ_SPAN_EQ",AFFINE_HULL_EQ_SPAN_EQ; +"AFFINE_HULL_EXPLICIT",AFFINE_HULL_EXPLICIT; +"AFFINE_HULL_EXPLICIT_ALT",AFFINE_HULL_EXPLICIT_ALT; +"AFFINE_HULL_EXPLICIT_UNIQUE",AFFINE_HULL_EXPLICIT_UNIQUE; +"AFFINE_HULL_FACE_OF_DISJOINT_RELATIVE_INTERIOR",AFFINE_HULL_FACE_OF_DISJOINT_RELATIVE_INTERIOR; +"AFFINE_HULL_FINITE",AFFINE_HULL_FINITE; +"AFFINE_HULL_FINITE_INTERSECTION_HYPERPLANES",AFFINE_HULL_FINITE_INTERSECTION_HYPERPLANES; +"AFFINE_HULL_FINITE_STEP",AFFINE_HULL_FINITE_STEP; +"AFFINE_HULL_FINITE_STEP_GEN",AFFINE_HULL_FINITE_STEP_GEN; +"AFFINE_HULL_HALFSPACE_GE",AFFINE_HULL_HALFSPACE_GE; +"AFFINE_HULL_HALFSPACE_GT",AFFINE_HULL_HALFSPACE_GT; +"AFFINE_HULL_HALFSPACE_LE",AFFINE_HULL_HALFSPACE_LE; +"AFFINE_HULL_HALFSPACE_LT",AFFINE_HULL_HALFSPACE_LT; +"AFFINE_HULL_INDEXED",AFFINE_HULL_INDEXED; +"AFFINE_HULL_INSERT_SPAN",AFFINE_HULL_INSERT_SPAN; +"AFFINE_HULL_INSERT_SUBSET_SPAN",AFFINE_HULL_INSERT_SUBSET_SPAN; +"AFFINE_HULL_INTER",AFFINE_HULL_INTER; +"AFFINE_HULL_INTERS",AFFINE_HULL_INTERS; +"AFFINE_HULL_LINEAR_IMAGE",AFFINE_HULL_LINEAR_IMAGE; +"AFFINE_HULL_NONEMPTY_INTERIOR",AFFINE_HULL_NONEMPTY_INTERIOR; +"AFFINE_HULL_OPEN",AFFINE_HULL_OPEN; +"AFFINE_HULL_OPEN_IN",AFFINE_HULL_OPEN_IN; +"AFFINE_HULL_PCROSS",AFFINE_HULL_PCROSS; +"AFFINE_HULL_RELATIVE_INTERIOR",AFFINE_HULL_RELATIVE_INTERIOR; +"AFFINE_HULL_SEGMENT",AFFINE_HULL_SEGMENT; +"AFFINE_HULL_SING",AFFINE_HULL_SING; +"AFFINE_HULL_SPAN",AFFINE_HULL_SPAN; +"AFFINE_HULL_SUBSET_SPAN",AFFINE_HULL_SUBSET_SPAN; +"AFFINE_HULL_TRANSLATION",AFFINE_HULL_TRANSLATION; +"AFFINE_HULL_UNIV",AFFINE_HULL_UNIV; +"AFFINE_HYPERPLANE",AFFINE_HYPERPLANE; +"AFFINE_HYPERPLANE_SUMS_EQ_UNIV",AFFINE_HYPERPLANE_SUMS_EQ_UNIV; +"AFFINE_IMP_CONVEX",AFFINE_IMP_CONVEX; +"AFFINE_IMP_POLYHEDRON",AFFINE_IMP_POLYHEDRON; +"AFFINE_IMP_SUBSPACE",AFFINE_IMP_SUBSPACE; +"AFFINE_INDEPENDENT_1",AFFINE_INDEPENDENT_1; +"AFFINE_INDEPENDENT_2",AFFINE_INDEPENDENT_2; +"AFFINE_INDEPENDENT_CARD_DIM_DIFFS",AFFINE_INDEPENDENT_CARD_DIM_DIFFS; +"AFFINE_INDEPENDENT_CARD_LE",AFFINE_INDEPENDENT_CARD_LE; +"AFFINE_INDEPENDENT_CONVEX_AFFINE_HULL",AFFINE_INDEPENDENT_CONVEX_AFFINE_HULL; +"AFFINE_INDEPENDENT_DELETE",AFFINE_INDEPENDENT_DELETE; +"AFFINE_INDEPENDENT_EMPTY",AFFINE_INDEPENDENT_EMPTY; +"AFFINE_INDEPENDENT_IFF_CARD",AFFINE_INDEPENDENT_IFF_CARD; +"AFFINE_INDEPENDENT_IMP_FINITE",AFFINE_INDEPENDENT_IMP_FINITE; +"AFFINE_INDEPENDENT_INSERT",AFFINE_INDEPENDENT_INSERT; +"AFFINE_INDEPENDENT_SPAN_EQ",AFFINE_INDEPENDENT_SPAN_EQ; +"AFFINE_INDEPENDENT_SPAN_GT",AFFINE_INDEPENDENT_SPAN_GT; +"AFFINE_INDEPENDENT_STDBASIS",AFFINE_INDEPENDENT_STDBASIS; +"AFFINE_INDEPENDENT_SUBSET",AFFINE_INDEPENDENT_SUBSET; +"AFFINE_INDEXED",AFFINE_INDEXED; +"AFFINE_INTER",AFFINE_INTER; +"AFFINE_INTERS",AFFINE_INTERS; +"AFFINE_LINEAR_IMAGE",AFFINE_LINEAR_IMAGE; +"AFFINE_LINEAR_IMAGE_EQ",AFFINE_LINEAR_IMAGE_EQ; +"AFFINE_NEGATIONS",AFFINE_NEGATIONS; +"AFFINE_PARALLEL_SLICE",AFFINE_PARALLEL_SLICE; +"AFFINE_PCROSS",AFFINE_PCROSS; +"AFFINE_PCROSS_EQ",AFFINE_PCROSS_EQ; +"AFFINE_SCALING",AFFINE_SCALING; +"AFFINE_SCALING_EQ",AFFINE_SCALING_EQ; +"AFFINE_SING",AFFINE_SING; +"AFFINE_SPAN",AFFINE_SPAN; +"AFFINE_STANDARD_HYPERPLANE",AFFINE_STANDARD_HYPERPLANE; +"AFFINE_SUMS",AFFINE_SUMS; +"AFFINE_TRANSLATION",AFFINE_TRANSLATION; +"AFFINE_TRANSLATION_EQ",AFFINE_TRANSLATION_EQ; +"AFFINE_TRANSLATION_SUBSPACE",AFFINE_TRANSLATION_SUBSPACE; +"AFFINE_TRANSLATION_SUBSPACE_EXPLICIT",AFFINE_TRANSLATION_SUBSPACE_EXPLICIT; +"AFFINE_TRANSLATION_UNIQUE_SUBSPACE",AFFINE_TRANSLATION_UNIQUE_SUBSPACE; +"AFFINE_UNIV",AFFINE_UNIV; +"AFFINE_VSUM",AFFINE_VSUM; +"AFFINITY_INVERSES",AFFINITY_INVERSES; +"AFF_DIM",AFF_DIM; +"AFF_DIM_2",AFF_DIM_2; +"AFF_DIM_AFFINE_HULL",AFF_DIM_AFFINE_HULL; +"AFF_DIM_AFFINE_INDEPENDENT",AFF_DIM_AFFINE_INDEPENDENT; +"AFF_DIM_AFFINE_INTER_HYPERPLANE",AFF_DIM_AFFINE_INTER_HYPERPLANE; +"AFF_DIM_BALL",AFF_DIM_BALL; +"AFF_DIM_CBALL",AFF_DIM_CBALL; +"AFF_DIM_CLOSURE",AFF_DIM_CLOSURE; +"AFF_DIM_CONVEX_HULL",AFF_DIM_CONVEX_HULL; +"AFF_DIM_CONVEX_INTER_NONEMPTY_INTERIOR",AFF_DIM_CONVEX_INTER_NONEMPTY_INTERIOR; +"AFF_DIM_CONVEX_INTER_OPEN",AFF_DIM_CONVEX_INTER_OPEN; +"AFF_DIM_DIM_0",AFF_DIM_DIM_0; +"AFF_DIM_DIM_AFFINE_DIFFS",AFF_DIM_DIM_AFFINE_DIFFS; +"AFF_DIM_DIM_SUBSPACE",AFF_DIM_DIM_SUBSPACE; +"AFF_DIM_EMPTY",AFF_DIM_EMPTY; +"AFF_DIM_EQ_0",AFF_DIM_EQ_0; +"AFF_DIM_EQ_AFFINE_HULL",AFF_DIM_EQ_AFFINE_HULL; +"AFF_DIM_EQ_FULL",AFF_DIM_EQ_FULL; +"AFF_DIM_EQ_HYPERPLANE",AFF_DIM_EQ_HYPERPLANE; +"AFF_DIM_EQ_MINUS1",AFF_DIM_EQ_MINUS1; +"AFF_DIM_GE",AFF_DIM_GE; +"AFF_DIM_HALFSPACE_GE",AFF_DIM_HALFSPACE_GE; +"AFF_DIM_HALFSPACE_GT",AFF_DIM_HALFSPACE_GT; +"AFF_DIM_HALFSPACE_LE",AFF_DIM_HALFSPACE_LE; +"AFF_DIM_HALFSPACE_LT",AFF_DIM_HALFSPACE_LT; +"AFF_DIM_HYPERPLANE",AFF_DIM_HYPERPLANE; +"AFF_DIM_INJECTIVE_LINEAR_IMAGE",AFF_DIM_INJECTIVE_LINEAR_IMAGE; +"AFF_DIM_INSERT",AFF_DIM_INSERT; +"AFF_DIM_INTERVAL",AFF_DIM_INTERVAL; +"AFF_DIM_LE_CARD",AFF_DIM_LE_CARD; +"AFF_DIM_LE_DIM",AFF_DIM_LE_DIM; +"AFF_DIM_LE_UNIV",AFF_DIM_LE_UNIV; +"AFF_DIM_LINEAR_IMAGE_LE",AFF_DIM_LINEAR_IMAGE_LE; +"AFF_DIM_LT_FULL",AFF_DIM_LT_FULL; +"AFF_DIM_NONEMPTY_INTERIOR",AFF_DIM_NONEMPTY_INTERIOR; +"AFF_DIM_NONEMPTY_INTERIOR_EQ",AFF_DIM_NONEMPTY_INTERIOR_EQ; +"AFF_DIM_OPEN",AFF_DIM_OPEN; +"AFF_DIM_OPEN_IN",AFF_DIM_OPEN_IN; +"AFF_DIM_POS_LE",AFF_DIM_POS_LE; +"AFF_DIM_PSUBSET",AFF_DIM_PSUBSET; +"AFF_DIM_SIMPLEX",AFF_DIM_SIMPLEX; +"AFF_DIM_SING",AFF_DIM_SING; +"AFF_DIM_SUBSET",AFF_DIM_SUBSET; +"AFF_DIM_SUMS_INTER",AFF_DIM_SUMS_INTER; +"AFF_DIM_TRANSLATION_EQ",AFF_DIM_TRANSLATION_EQ; +"AFF_DIM_UNIQUE",AFF_DIM_UNIQUE; +"AFF_DIM_UNIV",AFF_DIM_UNIV; +"AFF_LOWDIM_SUBSET_HYPERPLANE",AFF_LOWDIM_SUBSET_HYPERPLANE; +"ALL",ALL; +"ALL2",ALL2; +"ALL2_ALL",ALL2_ALL; +"ALL2_AND_RIGHT",ALL2_AND_RIGHT; +"ALL2_DEF",ALL2_DEF; +"ALL2_MAP",ALL2_MAP; +"ALL2_MAP2",ALL2_MAP2; +"ALL_APPEND",ALL_APPEND; +"ALL_EL",ALL_EL; +"ALL_FILTER",ALL_FILTER; +"ALL_IMP",ALL_IMP; +"ALL_MAP",ALL_MAP; +"ALL_MEM",ALL_MEM; +"ALL_MP",ALL_MP; +"ALL_T",ALL_T; +"ALWAYS_EVENTUALLY",ALWAYS_EVENTUALLY; +"AND_ALL",AND_ALL; +"AND_ALL2",AND_ALL2; +"AND_CLAUSES",AND_CLAUSES; +"AND_DEF",AND_DEF; +"AND_FORALL_THM",AND_FORALL_THM; +"ANR_RELATIVE_FRONTIER_CONVEX",ANR_RELATIVE_FRONTIER_CONVEX; +"ANTIDERIVATIVE_CONTINUOUS",ANTIDERIVATIVE_CONTINUOUS; +"ANTIDERIVATIVE_INTEGRAL_CONTINUOUS",ANTIDERIVATIVE_INTEGRAL_CONTINUOUS; +"ANY_CLOSEST_POINT_AFFINE_ORTHOGONAL",ANY_CLOSEST_POINT_AFFINE_ORTHOGONAL; +"ANY_CLOSEST_POINT_DOT",ANY_CLOSEST_POINT_DOT; +"ANY_CLOSEST_POINT_UNIQUE",ANY_CLOSEST_POINT_UNIQUE; +"APPEND",APPEND; +"APPEND_ASSOC",APPEND_ASSOC; +"APPEND_BUTLAST_LAST",APPEND_BUTLAST_LAST; +"APPEND_EQ_NIL",APPEND_EQ_NIL; +"APPEND_NIL",APPEND_NIL; +"APPEND_SING",APPEND_SING; +"APPROACHABLE_LT_LE",APPROACHABLE_LT_LE; +"APPROXIMABLE_ON_DIVISION",APPROXIMABLE_ON_DIVISION; +"ARC_ASSOC",ARC_ASSOC; +"ARC_CONNECTED_TRANS",ARC_CONNECTED_TRANS; +"ARC_DISTINCT_ENDS",ARC_DISTINCT_ENDS; +"ARC_IMP_PATH",ARC_IMP_PATH; +"ARC_IMP_SIMPLE_PATH",ARC_IMP_SIMPLE_PATH; +"ARC_JOIN",ARC_JOIN; +"ARC_JOIN_EQ",ARC_JOIN_EQ; +"ARC_JOIN_EQ_ALT",ARC_JOIN_EQ_ALT; +"ARC_LINEAR_IMAGE_EQ",ARC_LINEAR_IMAGE_EQ; +"ARC_LINEPATH",ARC_LINEPATH; +"ARC_LINEPATH_EQ",ARC_LINEPATH_EQ; +"ARC_REVERSEPATH",ARC_REVERSEPATH; +"ARC_SIMPLE_PATH",ARC_SIMPLE_PATH; +"ARC_SIMPLE_PATH_SUBPATH",ARC_SIMPLE_PATH_SUBPATH; +"ARC_SIMPLE_PATH_SUBPATH_INTERIOR",ARC_SIMPLE_PATH_SUBPATH_INTERIOR; +"ARC_SUBPATH_ARC",ARC_SUBPATH_ARC; +"ARC_SUBPATH_EQ",ARC_SUBPATH_EQ; +"ARC_TRANSLATION_EQ",ARC_TRANSLATION_EQ; +"ARITH",ARITH; +"ARITH_ADD",ARITH_ADD; +"ARITH_EQ",ARITH_EQ; +"ARITH_EVEN",ARITH_EVEN; +"ARITH_EXP",ARITH_EXP; +"ARITH_GE",ARITH_GE; +"ARITH_GT",ARITH_GT; +"ARITH_LE",ARITH_LE; +"ARITH_LT",ARITH_LT; +"ARITH_MULT",ARITH_MULT; +"ARITH_ODD",ARITH_ODD; +"ARITH_PRE",ARITH_PRE; +"ARITH_SUB",ARITH_SUB; +"ARITH_SUC",ARITH_SUC; +"ARITH_ZERO",ARITH_ZERO; +"ARZELA_ASCOLI",ARZELA_ASCOLI; +"ASSOC",ASSOC; +"AT",AT; +"AT_INFINITY",AT_INFINITY; +"AUSTIN_LEMMA",AUSTIN_LEMMA; +"BABY_SARD",BABY_SARD; +"BALL_1",BALL_1; +"BALL_EMPTY",BALL_EMPTY; +"BALL_EQ_EMPTY",BALL_EQ_EMPTY; +"BALL_INTERVAL",BALL_INTERVAL; +"BALL_INTERVAL_0",BALL_INTERVAL_0; +"BALL_LINEAR_IMAGE",BALL_LINEAR_IMAGE; +"BALL_MAX_UNION",BALL_MAX_UNION; +"BALL_MIN_INTER",BALL_MIN_INTER; +"BALL_SCALING",BALL_SCALING; +"BALL_SUBSET_CBALL",BALL_SUBSET_CBALL; +"BALL_SUBSET_OPEN_MAP_IMAGE",BALL_SUBSET_OPEN_MAP_IMAGE; +"BALL_TRANSLATION",BALL_TRANSLATION; +"BALL_TRIVIAL",BALL_TRIVIAL; +"BALL_UNION_SPHERE",BALL_UNION_SPHERE; +"BANACH_FIX",BANACH_FIX; +"BASIS_CARD_EQ_DIM",BASIS_CARD_EQ_DIM; +"BASIS_COMPONENT",BASIS_COMPONENT; +"BASIS_COORDINATES_CONTINUOUS",BASIS_COORDINATES_CONTINUOUS; +"BASIS_COORDINATES_LIPSCHITZ",BASIS_COORDINATES_LIPSCHITZ; +"BASIS_EQ_0",BASIS_EQ_0; +"BASIS_EXISTS",BASIS_EXISTS; +"BASIS_EXISTS_FINITE",BASIS_EXISTS_FINITE; +"BASIS_EXPANSION",BASIS_EXPANSION; +"BASIS_EXPANSION_UNIQUE",BASIS_EXPANSION_UNIQUE; +"BASIS_HAS_SIZE_DIM",BASIS_HAS_SIZE_DIM; +"BASIS_HAS_SIZE_UNIV",BASIS_HAS_SIZE_UNIV; +"BASIS_INJ",BASIS_INJ; +"BASIS_INJ_EQ",BASIS_INJ_EQ; +"BASIS_NE",BASIS_NE; +"BASIS_NONZERO",BASIS_NONZERO; +"BASIS_ORTHOGONAL",BASIS_ORTHOGONAL; +"BASIS_SUBSPACE_EXISTS",BASIS_SUBSPACE_EXISTS; +"BEPPO_LEVI_DECREASING",BEPPO_LEVI_DECREASING; +"BEPPO_LEVI_INCREASING",BEPPO_LEVI_INCREASING; +"BEPPO_LEVI_MONOTONE_CONVERGENCE_DECREASING",BEPPO_LEVI_MONOTONE_CONVERGENCE_DECREASING; +"BEPPO_LEVI_MONOTONE_CONVERGENCE_INCREASING",BEPPO_LEVI_MONOTONE_CONVERGENCE_INCREASING; +"BESSEL_INEQUALITY",BESSEL_INEQUALITY; +"BETA_THM",BETA_THM; +"BETWEEN_ANTISYM",BETWEEN_ANTISYM; +"BETWEEN_COLLINEAR_DIST_EQ",BETWEEN_COLLINEAR_DIST_EQ; +"BETWEEN_DIST_LE",BETWEEN_DIST_LE; +"BETWEEN_DIST_LT",BETWEEN_DIST_LT; +"BETWEEN_DOT",BETWEEN_DOT; +"BETWEEN_EXISTS_EXTENSION",BETWEEN_EXISTS_EXTENSION; +"BETWEEN_IMP_COLLINEAR",BETWEEN_IMP_COLLINEAR; +"BETWEEN_IN_CONVEX_HULL",BETWEEN_IN_CONVEX_HULL; +"BETWEEN_IN_SEGMENT",BETWEEN_IN_SEGMENT; +"BETWEEN_LINEAR_IMAGE_EQ",BETWEEN_LINEAR_IMAGE_EQ; +"BETWEEN_MIDPOINT",BETWEEN_MIDPOINT; +"BETWEEN_NORM",BETWEEN_NORM; +"BETWEEN_NORM_LE",BETWEEN_NORM_LE; +"BETWEEN_NORM_LT",BETWEEN_NORM_LT; +"BETWEEN_REFL",BETWEEN_REFL; +"BETWEEN_REFL_EQ",BETWEEN_REFL_EQ; +"BETWEEN_SYM",BETWEEN_SYM; +"BETWEEN_TRANS",BETWEEN_TRANS; +"BETWEEN_TRANSLATION",BETWEEN_TRANSLATION; +"BETWEEN_TRANS_2",BETWEEN_TRANS_2; +"BIJ",BIJ; +"BIJECTIONS_CARD_EQ",BIJECTIONS_CARD_EQ; +"BIJECTIONS_HAS_SIZE",BIJECTIONS_HAS_SIZE; +"BIJECTIONS_HAS_SIZE_EQ",BIJECTIONS_HAS_SIZE_EQ; +"BIJECTIVE_INJECTIVE_SURJECTIVE",BIJECTIVE_INJECTIVE_SURJECTIVE; +"BIJECTIVE_INVERSES",BIJECTIVE_INVERSES; +"BIJECTIVE_LEFT_RIGHT_INVERSE",BIJECTIVE_LEFT_RIGHT_INVERSE; +"BIJECTIVE_ON_LEFT_RIGHT_INVERSE",BIJECTIVE_ON_LEFT_RIGHT_INVERSE; +"BILINEAR_BOUNDED",BILINEAR_BOUNDED; +"BILINEAR_BOUNDED_POS",BILINEAR_BOUNDED_POS; +"BILINEAR_CONTINUOUS_COMPOSE",BILINEAR_CONTINUOUS_COMPOSE; +"BILINEAR_CONTINUOUS_ON_COMPOSE",BILINEAR_CONTINUOUS_ON_COMPOSE; +"BILINEAR_DIFFERENTIABLE_AT_COMPOSE",BILINEAR_DIFFERENTIABLE_AT_COMPOSE; +"BILINEAR_DIFFERENTIABLE_ON_COMPOSE",BILINEAR_DIFFERENTIABLE_ON_COMPOSE; +"BILINEAR_DIFFERENTIABLE_WITHIN_COMPOSE",BILINEAR_DIFFERENTIABLE_WITHIN_COMPOSE; +"BILINEAR_DOT",BILINEAR_DOT; +"BILINEAR_DROP_MUL",BILINEAR_DROP_MUL; +"BILINEAR_EQ",BILINEAR_EQ; +"BILINEAR_EQ_MBASIS",BILINEAR_EQ_MBASIS; +"BILINEAR_EQ_STDBASIS",BILINEAR_EQ_STDBASIS; +"BILINEAR_GEOM",BILINEAR_GEOM; +"BILINEAR_INNER",BILINEAR_INNER; +"BILINEAR_LADD",BILINEAR_LADD; +"BILINEAR_LMUL",BILINEAR_LMUL; +"BILINEAR_LNEG",BILINEAR_LNEG; +"BILINEAR_LSUB",BILINEAR_LSUB; +"BILINEAR_LZERO",BILINEAR_LZERO; +"BILINEAR_OUTER",BILINEAR_OUTER; +"BILINEAR_PRODUCT",BILINEAR_PRODUCT; +"BILINEAR_RADD",BILINEAR_RADD; +"BILINEAR_RMUL",BILINEAR_RMUL; +"BILINEAR_RNEG",BILINEAR_RNEG; +"BILINEAR_RSUB",BILINEAR_RSUB; +"BILINEAR_RZERO",BILINEAR_RZERO; +"BILINEAR_UNIFORMLY_CONTINUOUS_ON_COMPOSE",BILINEAR_UNIFORMLY_CONTINUOUS_ON_COMPOSE; +"BILINEAR_VSUM",BILINEAR_VSUM; +"BILINEAR_VSUM_PARTIAL_PRE",BILINEAR_VSUM_PARTIAL_PRE; +"BILINEAR_VSUM_PARTIAL_SUC",BILINEAR_VSUM_PARTIAL_SUC; +"BINARYSUM_BITSET",BINARYSUM_BITSET; +"BINARYSUM_BOUND",BINARYSUM_BOUND; +"BINARYSUM_BOUND_EQ",BINARYSUM_BOUND_EQ; +"BINARYSUM_BOUND_LEMMA",BINARYSUM_BOUND_LEMMA; +"BINARYSUM_DIV",BINARYSUM_DIV; +"BINARYSUM_DIV_DIVISIBLE",BINARYSUM_DIV_DIVISIBLE; +"BINARY_INDUCT",BINARY_INDUCT; +"BIT0",BIT0; +"BIT0_DEF",BIT0_DEF; +"BIT0_THM",BIT0_THM; +"BIT1",BIT1; +"BIT1_DEF",BIT1_DEF; +"BIT1_THM",BIT1_THM; +"BITSET_0",BITSET_0; +"BITSET_BINARYSUM",BITSET_BINARYSUM; +"BITSET_BOUND",BITSET_BOUND; +"BITSET_BOUND_EQ",BITSET_BOUND_EQ; +"BITSET_BOUND_LEMMA",BITSET_BOUND_LEMMA; +"BITSET_BOUND_WEAK",BITSET_BOUND_WEAK; +"BITSET_EQ",BITSET_EQ; +"BITSET_EQ_EMPTY",BITSET_EQ_EMPTY; +"BITSET_STEP",BITSET_STEP; +"BOLZANO_WEIERSTRASS",BOLZANO_WEIERSTRASS; +"BOLZANO_WEIERSTRASS_CONTRAPOS",BOLZANO_WEIERSTRASS_CONTRAPOS; +"BOLZANO_WEIERSTRASS_IMP_BOUNDED",BOLZANO_WEIERSTRASS_IMP_BOUNDED; +"BOLZANO_WEIERSTRASS_IMP_CLOSED",BOLZANO_WEIERSTRASS_IMP_CLOSED; +"BOOL_CASES_AX",BOOL_CASES_AX; +"BORSUK_HOMOTOPY_EXTENSION",BORSUK_HOMOTOPY_EXTENSION; +"BOTTOM",BOTTOM; +"BOUNDED_ARC_IMAGE",BOUNDED_ARC_IMAGE; +"BOUNDED_BALL",BOUNDED_BALL; +"BOUNDED_CBALL",BOUNDED_CBALL; +"BOUNDED_CLOSED_CHAIN",BOUNDED_CLOSED_CHAIN; +"BOUNDED_CLOSED_IMP_COMPACT",BOUNDED_CLOSED_IMP_COMPACT; +"BOUNDED_CLOSED_INTERVAL",BOUNDED_CLOSED_INTERVAL; +"BOUNDED_CLOSED_NEST",BOUNDED_CLOSED_NEST; +"BOUNDED_CLOSURE",BOUNDED_CLOSURE; +"BOUNDED_CLOSURE_EQ",BOUNDED_CLOSURE_EQ; +"BOUNDED_COMPONENTWISE",BOUNDED_COMPONENTWISE; +"BOUNDED_CONVEX_HULL",BOUNDED_CONVEX_HULL; +"BOUNDED_CONVEX_HULL_EQ",BOUNDED_CONVEX_HULL_EQ; +"BOUNDED_DECREASING_CONVERGENT",BOUNDED_DECREASING_CONVERGENT; +"BOUNDED_DIFF",BOUNDED_DIFF; +"BOUNDED_DIFFS",BOUNDED_DIFFS; +"BOUNDED_EMPTY",BOUNDED_EMPTY; +"BOUNDED_EQUIINTEGRAL_OVER_THIN_TAGGED_PARTIAL_DIVISION",BOUNDED_EQUIINTEGRAL_OVER_THIN_TAGGED_PARTIAL_DIVISION; +"BOUNDED_FINITE",BOUNDED_FINITE; +"BOUNDED_FRONTIER",BOUNDED_FRONTIER; +"BOUNDED_FUNCTIONS_BIJECTIONS_1",BOUNDED_FUNCTIONS_BIJECTIONS_1; +"BOUNDED_FUNCTIONS_BIJECTIONS_2",BOUNDED_FUNCTIONS_BIJECTIONS_2; +"BOUNDED_HALFSPACE_GE",BOUNDED_HALFSPACE_GE; +"BOUNDED_HALFSPACE_GT",BOUNDED_HALFSPACE_GT; +"BOUNDED_HALFSPACE_LE",BOUNDED_HALFSPACE_LE; +"BOUNDED_HALFSPACE_LT",BOUNDED_HALFSPACE_LT; +"BOUNDED_HAS_INF",BOUNDED_HAS_INF; +"BOUNDED_HAS_SUP",BOUNDED_HAS_SUP; +"BOUNDED_HYPERPLANE_EQ_TRIVIAL",BOUNDED_HYPERPLANE_EQ_TRIVIAL; +"BOUNDED_INCREASING_CONVERGENT",BOUNDED_INCREASING_CONVERGENT; +"BOUNDED_INSERT",BOUNDED_INSERT; +"BOUNDED_INSIDE",BOUNDED_INSIDE; +"BOUNDED_INTER",BOUNDED_INTER; +"BOUNDED_INTERIOR",BOUNDED_INTERIOR; +"BOUNDED_INTERS",BOUNDED_INTERS; +"BOUNDED_INTERVAL",BOUNDED_INTERVAL; +"BOUNDED_LIFT",BOUNDED_LIFT; +"BOUNDED_LINEAR_IMAGE",BOUNDED_LINEAR_IMAGE; +"BOUNDED_LINEAR_IMAGE_EQ",BOUNDED_LINEAR_IMAGE_EQ; +"BOUNDED_NEGATIONS",BOUNDED_NEGATIONS; +"BOUNDED_PARTIAL_SUMS",BOUNDED_PARTIAL_SUMS; +"BOUNDED_PATH_IMAGE",BOUNDED_PATH_IMAGE; +"BOUNDED_PCROSS",BOUNDED_PCROSS; +"BOUNDED_PCROSS_EQ",BOUNDED_PCROSS_EQ; +"BOUNDED_POS",BOUNDED_POS; +"BOUNDED_POS_LT",BOUNDED_POS_LT; +"BOUNDED_RECTIFIABLE_PATH_IMAGE",BOUNDED_RECTIFIABLE_PATH_IMAGE; +"BOUNDED_RELATIVE_FRONTIER",BOUNDED_RELATIVE_FRONTIER; +"BOUNDED_SCALING",BOUNDED_SCALING; +"BOUNDED_SEGMENT",BOUNDED_SEGMENT; +"BOUNDED_SETVARIATION_ABSOLUTELY_INTEGRABLE",BOUNDED_SETVARIATION_ABSOLUTELY_INTEGRABLE; +"BOUNDED_SETVARIATION_ABSOLUTELY_INTEGRABLE_INTERVAL",BOUNDED_SETVARIATION_ABSOLUTELY_INTEGRABLE_INTERVAL; +"BOUNDED_SIMPLE_PATH_IMAGE",BOUNDED_SIMPLE_PATH_IMAGE; +"BOUNDED_SING",BOUNDED_SING; +"BOUNDED_SPHERE",BOUNDED_SPHERE; +"BOUNDED_SUBSET",BOUNDED_SUBSET; +"BOUNDED_SUBSET_BALL",BOUNDED_SUBSET_BALL; +"BOUNDED_SUBSET_CBALL",BOUNDED_SUBSET_CBALL; +"BOUNDED_SUBSET_CLOSED_INTERVAL",BOUNDED_SUBSET_CLOSED_INTERVAL; +"BOUNDED_SUBSET_CLOSED_INTERVAL_SYMMETRIC",BOUNDED_SUBSET_CLOSED_INTERVAL_SYMMETRIC; +"BOUNDED_SUBSET_OPEN_INTERVAL",BOUNDED_SUBSET_OPEN_INTERVAL; +"BOUNDED_SUBSET_OPEN_INTERVAL_SYMMETRIC",BOUNDED_SUBSET_OPEN_INTERVAL_SYMMETRIC; +"BOUNDED_SUMS",BOUNDED_SUMS; +"BOUNDED_SUMS_IMAGE",BOUNDED_SUMS_IMAGE; +"BOUNDED_SUMS_IMAGES",BOUNDED_SUMS_IMAGES; +"BOUNDED_TRANSLATION",BOUNDED_TRANSLATION; +"BOUNDED_TRANSLATION_EQ",BOUNDED_TRANSLATION_EQ; +"BOUNDED_UNIFORMLY_CONTINUOUS_IMAGE",BOUNDED_UNIFORMLY_CONTINUOUS_IMAGE; +"BOUNDED_UNION",BOUNDED_UNION; +"BOUNDED_UNIONS",BOUNDED_UNIONS; +"BOUNDED_UNIQUE_OUTSIDE",BOUNDED_UNIQUE_OUTSIDE; +"BOUNDS_DIVIDED",BOUNDS_DIVIDED; +"BOUNDS_IGNORE",BOUNDS_IGNORE; +"BOUNDS_LINEAR",BOUNDS_LINEAR; +"BOUNDS_LINEAR_0",BOUNDS_LINEAR_0; +"BOUNDS_NOTZERO",BOUNDS_NOTZERO; +"BROUWER",BROUWER; +"BROUWER_BALL",BROUWER_BALL; +"BROUWER_COMPACTNESS_LEMMA",BROUWER_COMPACTNESS_LEMMA; +"BROUWER_CONTRACTIBLE_ANR",BROUWER_CONTRACTIBLE_ANR; +"BROUWER_CUBE",BROUWER_CUBE; +"BROUWER_INESSENTIAL_ANR",BROUWER_INESSENTIAL_ANR; +"BROUWER_REDUCTION_THEOREM",BROUWER_REDUCTION_THEOREM; +"BROUWER_REDUCTION_THEOREM_GEN",BROUWER_REDUCTION_THEOREM_GEN; +"BROUWER_SURJECTIVE",BROUWER_SURJECTIVE; +"BROUWER_SURJECTIVE_CBALL",BROUWER_SURJECTIVE_CBALL; +"BROUWER_WEAK",BROUWER_WEAK; +"BUTLAST",BUTLAST; +"CANTOR_THM",CANTOR_THM; +"CANTOR_THM_UNIV",CANTOR_THM_UNIV; +"CARATHEODORY",CARATHEODORY; +"CARATHEODORY_AFF_DIM",CARATHEODORY_AFF_DIM; +"CARD",CARD; +"CARD_ADD2_ABSORB_LE",CARD_ADD2_ABSORB_LE; +"CARD_ADD2_ABSORB_LT",CARD_ADD2_ABSORB_LT; +"CARD_ADD_ABSORB",CARD_ADD_ABSORB; +"CARD_ADD_ABSORB_LE",CARD_ADD_ABSORB_LE; +"CARD_ADD_ASSOC",CARD_ADD_ASSOC; +"CARD_ADD_C",CARD_ADD_C; +"CARD_ADD_CONG",CARD_ADD_CONG; +"CARD_ADD_FINITE",CARD_ADD_FINITE; +"CARD_ADD_FINITE_EQ",CARD_ADD_FINITE_EQ; +"CARD_ADD_LE_MUL_INFINITE",CARD_ADD_LE_MUL_INFINITE; +"CARD_ADD_SYM",CARD_ADD_SYM; +"CARD_ADD_SYMDIFF_INTER",CARD_ADD_SYMDIFF_INTER; +"CARD_BOOL",CARD_BOOL; +"CARD_CART_UNIV",CARD_CART_UNIV; +"CARD_CLAUSES",CARD_CLAUSES; +"CARD_COUNTABLE_CONG",CARD_COUNTABLE_CONG; +"CARD_CROSS",CARD_CROSS; +"CARD_DELETE",CARD_DELETE; +"CARD_DIFF",CARD_DIFF; +"CARD_DIFF_INTER",CARD_DIFF_INTER; +"CARD_DISJOINT_UNION",CARD_DISJOINT_UNION; +"CARD_EQ_0",CARD_EQ_0; +"CARD_EQ_ARC_IMAGE",CARD_EQ_ARC_IMAGE; +"CARD_EQ_BALL",CARD_EQ_BALL; +"CARD_EQ_BIJECTION",CARD_EQ_BIJECTION; +"CARD_EQ_BIJECTIONS",CARD_EQ_BIJECTIONS; +"CARD_EQ_CARD",CARD_EQ_CARD; +"CARD_EQ_CARD_IMP",CARD_EQ_CARD_IMP; +"CARD_EQ_CART",CARD_EQ_CART; +"CARD_EQ_CBALL",CARD_EQ_CBALL; +"CARD_EQ_CLOSED",CARD_EQ_CLOSED; +"CARD_EQ_CLOSED_SETS",CARD_EQ_CLOSED_SETS; +"CARD_EQ_COMPACT_SETS",CARD_EQ_COMPACT_SETS; +"CARD_EQ_CONDENSATION_POINTS",CARD_EQ_CONDENSATION_POINTS; +"CARD_EQ_CONDENSATION_POINTS_IN_SET",CARD_EQ_CONDENSATION_POINTS_IN_SET; +"CARD_EQ_CONG",CARD_EQ_CONG; +"CARD_EQ_CONNECTED",CARD_EQ_CONNECTED; +"CARD_EQ_CONVEX",CARD_EQ_CONVEX; +"CARD_EQ_COUNTABLE",CARD_EQ_COUNTABLE; +"CARD_EQ_COUNTABLE_SUBSETS_REAL",CARD_EQ_COUNTABLE_SUBSETS_REAL; +"CARD_EQ_COVERING_MAP_FIBRES",CARD_EQ_COVERING_MAP_FIBRES; +"CARD_EQ_DIM",CARD_EQ_DIM; +"CARD_EQ_EMPTY",CARD_EQ_EMPTY; +"CARD_EQ_EUCLIDEAN",CARD_EQ_EUCLIDEAN; +"CARD_EQ_FINITE",CARD_EQ_FINITE; +"CARD_EQ_FINITE_SUBSETS",CARD_EQ_FINITE_SUBSETS; +"CARD_EQ_IMAGE",CARD_EQ_IMAGE; +"CARD_EQ_IMP_LE",CARD_EQ_IMP_LE; +"CARD_EQ_INTEGER",CARD_EQ_INTEGER; +"CARD_EQ_INTERVAL",CARD_EQ_INTERVAL; +"CARD_EQ_LIST",CARD_EQ_LIST; +"CARD_EQ_LIST_GEN",CARD_EQ_LIST_GEN; +"CARD_EQ_NONEMPTY_INTERIOR",CARD_EQ_NONEMPTY_INTERIOR; +"CARD_EQ_NSUM",CARD_EQ_NSUM; +"CARD_EQ_OPEN",CARD_EQ_OPEN; +"CARD_EQ_OPEN_IN",CARD_EQ_OPEN_IN; +"CARD_EQ_OPEN_IN_AFFINE",CARD_EQ_OPEN_IN_AFFINE; +"CARD_EQ_OPEN_SETS",CARD_EQ_OPEN_SETS; +"CARD_EQ_PATH_CONNECTED",CARD_EQ_PATH_CONNECTED; +"CARD_EQ_PCROSS",CARD_EQ_PCROSS; +"CARD_EQ_RATIONAL",CARD_EQ_RATIONAL; +"CARD_EQ_REAL",CARD_EQ_REAL; +"CARD_EQ_REAL_IMP_UNCOUNTABLE",CARD_EQ_REAL_IMP_UNCOUNTABLE; +"CARD_EQ_REAL_SEQUENCES",CARD_EQ_REAL_SEQUENCES; +"CARD_EQ_REFL",CARD_EQ_REFL; +"CARD_EQ_SEGMENT",CARD_EQ_SEGMENT; +"CARD_EQ_SIMPLE_PATH_IMAGE",CARD_EQ_SIMPLE_PATH_IMAGE; +"CARD_EQ_SPHERE",CARD_EQ_SPHERE; +"CARD_EQ_SUM",CARD_EQ_SUM; +"CARD_EQ_SYM",CARD_EQ_SYM; +"CARD_EQ_TRANS",CARD_EQ_TRANS; +"CARD_FACES_OF_SIMPLEX",CARD_FACES_OF_SIMPLEX; +"CARD_FINITE_CONG",CARD_FINITE_CONG; +"CARD_FINITE_IMAGE",CARD_FINITE_IMAGE; +"CARD_FUNSPACE",CARD_FUNSPACE; +"CARD_FUNSPACE_CONG",CARD_FUNSPACE_CONG; +"CARD_FUNSPACE_CURRY",CARD_FUNSPACE_CURRY; +"CARD_FUNSPACE_LE",CARD_FUNSPACE_LE; +"CARD_FUNSPACE_UNIV",CARD_FUNSPACE_UNIV; +"CARD_GE_DIM_INDEPENDENT",CARD_GE_DIM_INDEPENDENT; +"CARD_HAS_SIZE_CONG",CARD_HAS_SIZE_CONG; +"CARD_IMAGE_EQ_INJ",CARD_IMAGE_EQ_INJ; +"CARD_IMAGE_INJ",CARD_IMAGE_INJ; +"CARD_IMAGE_INJ_EQ",CARD_IMAGE_INJ_EQ; +"CARD_IMAGE_LE",CARD_IMAGE_LE; +"CARD_INFINITE_CONG",CARD_INFINITE_CONG; +"CARD_INTSEG_INT",CARD_INTSEG_INT; +"CARD_LDISTRIB",CARD_LDISTRIB; +"CARD_LET_TOTAL",CARD_LET_TOTAL; +"CARD_LET_TRANS",CARD_LET_TRANS; +"CARD_LE_ADD",CARD_LE_ADD; +"CARD_LE_ADDL",CARD_LE_ADDL; +"CARD_LE_ADDR",CARD_LE_ADDR; +"CARD_LE_ANTISYM",CARD_LE_ANTISYM; +"CARD_LE_CARD",CARD_LE_CARD; +"CARD_LE_CARD_IMP",CARD_LE_CARD_IMP; +"CARD_LE_CONG",CARD_LE_CONG; +"CARD_LE_COUNTABLE",CARD_LE_COUNTABLE; +"CARD_LE_COUNTABLE_SUBSETS",CARD_LE_COUNTABLE_SUBSETS; +"CARD_LE_DIM_SPANNING",CARD_LE_DIM_SPANNING; +"CARD_LE_EMPTY",CARD_LE_EMPTY; +"CARD_LE_EQ_SUBSET",CARD_LE_EQ_SUBSET; +"CARD_LE_FINITE",CARD_LE_FINITE; +"CARD_LE_FINITE_SUBSETS",CARD_LE_FINITE_SUBSETS; +"CARD_LE_IMAGE",CARD_LE_IMAGE; +"CARD_LE_IMAGE_GEN",CARD_LE_IMAGE_GEN; +"CARD_LE_INFINITE",CARD_LE_INFINITE; +"CARD_LE_INJ",CARD_LE_INJ; +"CARD_LE_LIST",CARD_LE_LIST; +"CARD_LE_LT",CARD_LE_LT; +"CARD_LE_MUL",CARD_LE_MUL; +"CARD_LE_POWERSET",CARD_LE_POWERSET; +"CARD_LE_REFL",CARD_LE_REFL; +"CARD_LE_RELATIONAL",CARD_LE_RELATIONAL; +"CARD_LE_SQUARE",CARD_LE_SQUARE; +"CARD_LE_SUBPOWERSET",CARD_LE_SUBPOWERSET; +"CARD_LE_SUBSET",CARD_LE_SUBSET; +"CARD_LE_TOTAL",CARD_LE_TOTAL; +"CARD_LE_TRANS",CARD_LE_TRANS; +"CARD_LE_UNIV",CARD_LE_UNIV; +"CARD_LTE_TOTAL",CARD_LTE_TOTAL; +"CARD_LTE_TRANS",CARD_LTE_TRANS; +"CARD_LT_ADD",CARD_LT_ADD; +"CARD_LT_CARD",CARD_LT_CARD; +"CARD_LT_CONG",CARD_LT_CONG; +"CARD_LT_FINITE_INFINITE",CARD_LT_FINITE_INFINITE; +"CARD_LT_IMP_DISCONNECTED",CARD_LT_IMP_DISCONNECTED; +"CARD_LT_IMP_LE",CARD_LT_IMP_LE; +"CARD_LT_LE",CARD_LT_LE; +"CARD_LT_REFL",CARD_LT_REFL; +"CARD_LT_TOTAL",CARD_LT_TOTAL; +"CARD_LT_TRANS",CARD_LT_TRANS; +"CARD_MUL2_ABSORB_LE",CARD_MUL2_ABSORB_LE; +"CARD_MUL_ABSORB",CARD_MUL_ABSORB; +"CARD_MUL_ABSORB_LE",CARD_MUL_ABSORB_LE; +"CARD_MUL_ASSOC",CARD_MUL_ASSOC; +"CARD_MUL_CONG",CARD_MUL_CONG; +"CARD_MUL_FINITE",CARD_MUL_FINITE; +"CARD_MUL_LT_INFINITE",CARD_MUL_LT_INFINITE; +"CARD_MUL_LT_LEMMA",CARD_MUL_LT_LEMMA; +"CARD_MUL_SYM",CARD_MUL_SYM; +"CARD_NOT_LE",CARD_NOT_LE; +"CARD_NOT_LT",CARD_NOT_LT; +"CARD_NUMSEG",CARD_NUMSEG; +"CARD_NUMSEG_1",CARD_NUMSEG_1; +"CARD_NUMSEG_LE",CARD_NUMSEG_LE; +"CARD_NUMSEG_LEMMA",CARD_NUMSEG_LEMMA; +"CARD_NUMSEG_LT",CARD_NUMSEG_LT; +"CARD_PERMUTATIONS",CARD_PERMUTATIONS; +"CARD_POWERSET",CARD_POWERSET; +"CARD_PRODUCT",CARD_PRODUCT; +"CARD_PSUBSET",CARD_PSUBSET; +"CARD_RDISTRIB",CARD_RDISTRIB; +"CARD_SET_OF_LIST_LE",CARD_SET_OF_LIST_LE; +"CARD_SING",CARD_SING; +"CARD_SQUARE_INFINITE",CARD_SQUARE_INFINITE; +"CARD_SQUARE_NUM",CARD_SQUARE_NUM; +"CARD_STDBASIS",CARD_STDBASIS; +"CARD_SUBSET",CARD_SUBSET; +"CARD_SUBSET_EQ",CARD_SUBSET_EQ; +"CARD_SUBSET_IMAGE",CARD_SUBSET_IMAGE; +"CARD_SUBSET_LE",CARD_SUBSET_LE; +"CARD_UNION",CARD_UNION; +"CARD_UNIONS",CARD_UNIONS; +"CARD_UNIONS_LE",CARD_UNIONS_LE; +"CARD_UNION_EQ",CARD_UNION_EQ; +"CARD_UNION_GEN",CARD_UNION_GEN; +"CARD_UNION_LE",CARD_UNION_LE; +"CARD_UNION_LEMMA",CARD_UNION_LEMMA; +"CARD_UNION_OVERLAP",CARD_UNION_OVERLAP; +"CARD_UNION_OVERLAP_EQ",CARD_UNION_OVERLAP_EQ; +"CART_EQ",CART_EQ; +"CART_EQ_FULL",CART_EQ_FULL; +"CASEWISE",CASEWISE; +"CASEWISE_CASES",CASEWISE_CASES; +"CASEWISE_DEF",CASEWISE_DEF; +"CASEWISE_WORKS",CASEWISE_WORKS; +"CAUCHY",CAUCHY; +"CAUCHY_CONTINUOUS_EXTENDS_TO_CLOSURE",CAUCHY_CONTINUOUS_EXTENDS_TO_CLOSURE; +"CAUCHY_CONTINUOUS_IMP_CONTINUOUS",CAUCHY_CONTINUOUS_IMP_CONTINUOUS; +"CAUCHY_CONTINUOUS_UNIQUENESS_LEMMA",CAUCHY_CONTINUOUS_UNIQUENESS_LEMMA; +"CAUCHY_IMP_BOUNDED",CAUCHY_IMP_BOUNDED; +"CAUCHY_ISOMETRIC",CAUCHY_ISOMETRIC; +"CBALL_DIFF_BALL",CBALL_DIFF_BALL; +"CBALL_DIFF_SPHERE",CBALL_DIFF_SPHERE; +"CBALL_EMPTY",CBALL_EMPTY; +"CBALL_EQ_EMPTY",CBALL_EQ_EMPTY; +"CBALL_EQ_SING",CBALL_EQ_SING; +"CBALL_INTERVAL",CBALL_INTERVAL; +"CBALL_INTERVAL_0",CBALL_INTERVAL_0; +"CBALL_LINEAR_IMAGE",CBALL_LINEAR_IMAGE; +"CBALL_SCALING",CBALL_SCALING; +"CBALL_SING",CBALL_SING; +"CBALL_TRANSLATION",CBALL_TRANSLATION; +"CBALL_TRIVIAL",CBALL_TRIVIAL; +"CELL_COMPLEX_SUBDIVISION_EXISTS",CELL_COMPLEX_SUBDIVISION_EXISTS; +"CENTRE_IN_BALL",CENTRE_IN_BALL; +"CENTRE_IN_CBALL",CENTRE_IN_CBALL; +"CHAIN_SUBSET",CHAIN_SUBSET; +"CHARACTERISTIC_POLYNOMIAL",CHARACTERISTIC_POLYNOMIAL; +"CHOICE",CHOICE; +"CHOICE_DEF",CHOICE_DEF; +"CHOOSE_AFFINE_SUBSET",CHOOSE_AFFINE_SUBSET; +"CHOOSE_POLYTOPE",CHOOSE_POLYTOPE; +"CHOOSE_SIMPLEX",CHOOSE_SIMPLEX; +"CHOOSE_SUBSET",CHOOSE_SUBSET; +"CHOOSE_SUBSET_BETWEEN",CHOOSE_SUBSET_BETWEEN; +"CHOOSE_SUBSET_STRONG",CHOOSE_SUBSET_STRONG; +"CHOOSE_SUBSPACE_OF_SUBSPACE",CHOOSE_SUBSPACE_OF_SUBSPACE; +"CLOPEN",CLOPEN; +"CLOSED_AFFINE",CLOSED_AFFINE; +"CLOSED_AFFINE_HULL",CLOSED_AFFINE_HULL; +"CLOSED_APPROACHABLE",CLOSED_APPROACHABLE; +"CLOSED_ARC_IMAGE",CLOSED_ARC_IMAGE; +"CLOSED_AS_FRONTIER",CLOSED_AS_FRONTIER; +"CLOSED_AS_FRONTIER_OF_SUBSET",CLOSED_AS_FRONTIER_OF_SUBSET; +"CLOSED_BOUNDEDPREIM_CONTINUOUS_IMAGE",CLOSED_BOUNDEDPREIM_CONTINUOUS_IMAGE; +"CLOSED_CBALL",CLOSED_CBALL; +"CLOSED_CLOSED_IN_TRANS",CLOSED_CLOSED_IN_TRANS; +"CLOSED_CLOSURE",CLOSED_CLOSURE; +"CLOSED_COMPACT_DIFFERENCES",CLOSED_COMPACT_DIFFERENCES; +"CLOSED_COMPACT_PROJECTION",CLOSED_COMPACT_PROJECTION; +"CLOSED_COMPACT_SUMS",CLOSED_COMPACT_SUMS; +"CLOSED_COMPONENTS",CLOSED_COMPONENTS; +"CLOSED_CONDENSATION_POINTS",CLOSED_CONDENSATION_POINTS; +"CLOSED_CONNECTED_COMPONENT",CLOSED_CONNECTED_COMPONENT; +"CLOSED_CONTAINS_SEQUENTIAL_LIMIT",CLOSED_CONTAINS_SEQUENTIAL_LIMIT; +"CLOSED_CONVEX_CONE_HULL",CLOSED_CONVEX_CONE_HULL; +"CLOSED_DIFF",CLOSED_DIFF; +"CLOSED_DIFF_OPEN_INTERVAL_1",CLOSED_DIFF_OPEN_INTERVAL_1; +"CLOSED_EMPTY",CLOSED_EMPTY; +"CLOSED_FIP",CLOSED_FIP; +"CLOSED_FORALL",CLOSED_FORALL; +"CLOSED_FORALL_IN",CLOSED_FORALL_IN; +"CLOSED_HALFSPACE_COMPONENT_GE",CLOSED_HALFSPACE_COMPONENT_GE; +"CLOSED_HALFSPACE_COMPONENT_LE",CLOSED_HALFSPACE_COMPONENT_LE; +"CLOSED_HALFSPACE_GE",CLOSED_HALFSPACE_GE; +"CLOSED_HALFSPACE_LE",CLOSED_HALFSPACE_LE; +"CLOSED_HYPERPLANE",CLOSED_HYPERPLANE; +"CLOSED_IMP_LOCALLY_COMPACT",CLOSED_IMP_LOCALLY_COMPACT; +"CLOSED_IN",CLOSED_IN; +"CLOSED_INJECTIVE_IMAGE_SUBSET_SUBSPACE",CLOSED_INJECTIVE_IMAGE_SUBSET_SUBSPACE; +"CLOSED_INJECTIVE_IMAGE_SUBSPACE",CLOSED_INJECTIVE_IMAGE_SUBSPACE; +"CLOSED_INJECTIVE_LINEAR_IMAGE",CLOSED_INJECTIVE_LINEAR_IMAGE; +"CLOSED_INJECTIVE_LINEAR_IMAGE_EQ",CLOSED_INJECTIVE_LINEAR_IMAGE_EQ; +"CLOSED_INSERT",CLOSED_INSERT; +"CLOSED_INTER",CLOSED_INTER; +"CLOSED_INTERS",CLOSED_INTERS; +"CLOSED_INTERS_COMPACT",CLOSED_INTERS_COMPACT; +"CLOSED_INTERVAL",CLOSED_INTERVAL; +"CLOSED_INTERVAL_AS_CONVEX_HULL",CLOSED_INTERVAL_AS_CONVEX_HULL; +"CLOSED_INTERVAL_EQ",CLOSED_INTERVAL_EQ; +"CLOSED_INTERVAL_IMAGE_UNIT_INTERVAL",CLOSED_INTERVAL_IMAGE_UNIT_INTERVAL; +"CLOSED_INTERVAL_LEFT",CLOSED_INTERVAL_LEFT; +"CLOSED_INTERVAL_RIGHT",CLOSED_INTERVAL_RIGHT; +"CLOSED_INTER_COMPACT",CLOSED_INTER_COMPACT; +"CLOSED_IN_CLOSED",CLOSED_IN_CLOSED; +"CLOSED_IN_CLOSED_EQ",CLOSED_IN_CLOSED_EQ; +"CLOSED_IN_CLOSED_INTER",CLOSED_IN_CLOSED_INTER; +"CLOSED_IN_CLOSED_TRANS",CLOSED_IN_CLOSED_TRANS; +"CLOSED_IN_COMPACT",CLOSED_IN_COMPACT; +"CLOSED_IN_COMPACT_PROJECTION",CLOSED_IN_COMPACT_PROJECTION; +"CLOSED_IN_CONNECTED_COMPONENT",CLOSED_IN_CONNECTED_COMPONENT; +"CLOSED_IN_DIFF",CLOSED_IN_DIFF; +"CLOSED_IN_EMPTY",CLOSED_IN_EMPTY; +"CLOSED_IN_IMP_SUBSET",CLOSED_IN_IMP_SUBSET; +"CLOSED_IN_INJECTIVE_LINEAR_IMAGE",CLOSED_IN_INJECTIVE_LINEAR_IMAGE; +"CLOSED_IN_INTER",CLOSED_IN_INTER; +"CLOSED_IN_INTERS",CLOSED_IN_INTERS; +"CLOSED_IN_INTER_CLOSED",CLOSED_IN_INTER_CLOSED; +"CLOSED_IN_LIMPT",CLOSED_IN_LIMPT; +"CLOSED_IN_PATH_COMPONENT_LOCALLY_PATH_CONNECTED",CLOSED_IN_PATH_COMPONENT_LOCALLY_PATH_CONNECTED; +"CLOSED_IN_REFL",CLOSED_IN_REFL; +"CLOSED_IN_RETRACT",CLOSED_IN_RETRACT; +"CLOSED_IN_SING",CLOSED_IN_SING; +"CLOSED_IN_SUBSET",CLOSED_IN_SUBSET; +"CLOSED_IN_SUBSET_TRANS",CLOSED_IN_SUBSET_TRANS; +"CLOSED_IN_SUBTOPOLOGY",CLOSED_IN_SUBTOPOLOGY; +"CLOSED_IN_SUBTOPOLOGY_EMPTY",CLOSED_IN_SUBTOPOLOGY_EMPTY; +"CLOSED_IN_SUBTOPOLOGY_REFL",CLOSED_IN_SUBTOPOLOGY_REFL; +"CLOSED_IN_SUBTOPOLOGY_UNION",CLOSED_IN_SUBTOPOLOGY_UNION; +"CLOSED_IN_TOPSPACE",CLOSED_IN_TOPSPACE; +"CLOSED_IN_TRANS",CLOSED_IN_TRANS; +"CLOSED_IN_TRANSLATION_EQ",CLOSED_IN_TRANSLATION_EQ; +"CLOSED_IN_UNION",CLOSED_IN_UNION; +"CLOSED_IN_UNIONS",CLOSED_IN_UNIONS; +"CLOSED_IN_UNION_COMPLEMENT_COMPONENT",CLOSED_IN_UNION_COMPLEMENT_COMPONENT; +"CLOSED_LIFT",CLOSED_LIFT; +"CLOSED_LIMPT",CLOSED_LIMPT; +"CLOSED_LIMPTS",CLOSED_LIMPTS; +"CLOSED_MAP_FROM_COMPOSITION_INJECTIVE",CLOSED_MAP_FROM_COMPOSITION_INJECTIVE; +"CLOSED_MAP_FROM_COMPOSITION_SURJECTIVE",CLOSED_MAP_FROM_COMPOSITION_SURJECTIVE; +"CLOSED_MAP_IMP_OPEN_MAP",CLOSED_MAP_IMP_OPEN_MAP; +"CLOSED_MAP_IMP_QUOTIENT_MAP",CLOSED_MAP_IMP_QUOTIENT_MAP; +"CLOSED_NEGATIONS",CLOSED_NEGATIONS; +"CLOSED_OPEN_INTERVAL_1",CLOSED_OPEN_INTERVAL_1; +"CLOSED_PATH_IMAGE",CLOSED_PATH_IMAGE; +"CLOSED_PCROSS",CLOSED_PCROSS; +"CLOSED_PCROSS_EQ",CLOSED_PCROSS_EQ; +"CLOSED_POSITIVE_ORTHANT",CLOSED_POSITIVE_ORTHANT; +"CLOSED_RELATIVE_BOUNDARY",CLOSED_RELATIVE_BOUNDARY; +"CLOSED_RELATIVE_FRONTIER",CLOSED_RELATIVE_FRONTIER; +"CLOSED_SCALING",CLOSED_SCALING; +"CLOSED_SEGMENT",CLOSED_SEGMENT; +"CLOSED_SEGMENT_LINEAR_IMAGE",CLOSED_SEGMENT_LINEAR_IMAGE; +"CLOSED_SEQUENTIAL_LIMITS",CLOSED_SEQUENTIAL_LIMITS; +"CLOSED_SHIFTPATH",CLOSED_SHIFTPATH; +"CLOSED_SIMPLE_PATH_IMAGE",CLOSED_SIMPLE_PATH_IMAGE; +"CLOSED_SING",CLOSED_SING; +"CLOSED_SPAN",CLOSED_SPAN; +"CLOSED_SPHERE",CLOSED_SPHERE; +"CLOSED_STANDARD_HYPERPLANE",CLOSED_STANDARD_HYPERPLANE; +"CLOSED_SUBSET",CLOSED_SUBSET; +"CLOSED_SUBSET_EQ",CLOSED_SUBSET_EQ; +"CLOSED_SUBSPACE",CLOSED_SUBSPACE; +"CLOSED_SUBSTANDARD",CLOSED_SUBSTANDARD; +"CLOSED_TRANSLATION",CLOSED_TRANSLATION; +"CLOSED_TRANSLATION_EQ",CLOSED_TRANSLATION_EQ; +"CLOSED_UNION",CLOSED_UNION; +"CLOSED_UNIONS",CLOSED_UNIONS; +"CLOSED_UNION_COMPACT_SUBSETS",CLOSED_UNION_COMPACT_SUBSETS; +"CLOSED_UNION_COMPLEMENT_COMPONENT",CLOSED_UNION_COMPLEMENT_COMPONENT; +"CLOSED_UNIV",CLOSED_UNIV; +"CLOSER_POINTS_LEMMA",CLOSER_POINTS_LEMMA; +"CLOSER_POINT_LEMMA",CLOSER_POINT_LEMMA; +"CLOSEST_POINT_AFFINE_ORTHOGONAL",CLOSEST_POINT_AFFINE_ORTHOGONAL; +"CLOSEST_POINT_AFFINE_ORTHOGONAL_EQ",CLOSEST_POINT_AFFINE_ORTHOGONAL_EQ; +"CLOSEST_POINT_DOT",CLOSEST_POINT_DOT; +"CLOSEST_POINT_EXISTS",CLOSEST_POINT_EXISTS; +"CLOSEST_POINT_IN_FRONTIER",CLOSEST_POINT_IN_FRONTIER; +"CLOSEST_POINT_IN_INTERIOR",CLOSEST_POINT_IN_INTERIOR; +"CLOSEST_POINT_IN_RELATIVE_FRONTIER",CLOSEST_POINT_IN_RELATIVE_FRONTIER; +"CLOSEST_POINT_IN_RELATIVE_INTERIOR",CLOSEST_POINT_IN_RELATIVE_INTERIOR; +"CLOSEST_POINT_IN_SET",CLOSEST_POINT_IN_SET; +"CLOSEST_POINT_LE",CLOSEST_POINT_LE; +"CLOSEST_POINT_LIPSCHITZ",CLOSEST_POINT_LIPSCHITZ; +"CLOSEST_POINT_LT",CLOSEST_POINT_LT; +"CLOSEST_POINT_REFL",CLOSEST_POINT_REFL; +"CLOSEST_POINT_SELF",CLOSEST_POINT_SELF; +"CLOSEST_POINT_UNIQUE",CLOSEST_POINT_UNIQUE; +"CLOSURE_APPROACHABLE",CLOSURE_APPROACHABLE; +"CLOSURE_BALL",CLOSURE_BALL; +"CLOSURE_BOUNDED_LINEAR_IMAGE",CLOSURE_BOUNDED_LINEAR_IMAGE; +"CLOSURE_CLOSED",CLOSURE_CLOSED; +"CLOSURE_CLOSURE",CLOSURE_CLOSURE; +"CLOSURE_COCOUNTABLE_COORDINATES",CLOSURE_COCOUNTABLE_COORDINATES; +"CLOSURE_COMPLEMENT",CLOSURE_COMPLEMENT; +"CLOSURE_CONVEX_HULL",CLOSURE_CONVEX_HULL; +"CLOSURE_CONVEX_INTER_AFFINE",CLOSURE_CONVEX_INTER_AFFINE; +"CLOSURE_CONVEX_INTER_SUPERSET",CLOSURE_CONVEX_INTER_SUPERSET; +"CLOSURE_COSMALL_COORDINATES",CLOSURE_COSMALL_COORDINATES; +"CLOSURE_DYADIC_RATIONALS",CLOSURE_DYADIC_RATIONALS; +"CLOSURE_DYADIC_RATIONALS_IN_CONVEX_SET",CLOSURE_DYADIC_RATIONALS_IN_CONVEX_SET; +"CLOSURE_DYADIC_RATIONALS_IN_OPEN_SET",CLOSURE_DYADIC_RATIONALS_IN_OPEN_SET; +"CLOSURE_EMPTY",CLOSURE_EMPTY; +"CLOSURE_EQ",CLOSURE_EQ; +"CLOSURE_EQ_EMPTY",CLOSURE_EQ_EMPTY; +"CLOSURE_HALFSPACE_COMPONENT_GT",CLOSURE_HALFSPACE_COMPONENT_GT; +"CLOSURE_HALFSPACE_COMPONENT_LT",CLOSURE_HALFSPACE_COMPONENT_LT; +"CLOSURE_HALFSPACE_GT",CLOSURE_HALFSPACE_GT; +"CLOSURE_HALFSPACE_LT",CLOSURE_HALFSPACE_LT; +"CLOSURE_HULL",CLOSURE_HULL; +"CLOSURE_IMAGE_CLOSURE",CLOSURE_IMAGE_CLOSURE; +"CLOSURE_INJECTIVE_LINEAR_IMAGE",CLOSURE_INJECTIVE_LINEAR_IMAGE; +"CLOSURE_INSIDE_SUBSET",CLOSURE_INSIDE_SUBSET; +"CLOSURE_INTERIOR",CLOSURE_INTERIOR; +"CLOSURE_INTERIOR_IDEMP",CLOSURE_INTERIOR_IDEMP; +"CLOSURE_INTERS_CONVEX",CLOSURE_INTERS_CONVEX; +"CLOSURE_INTERS_CONVEX_OPEN",CLOSURE_INTERS_CONVEX_OPEN; +"CLOSURE_INTERS_SUBSET",CLOSURE_INTERS_SUBSET; +"CLOSURE_INTERVAL",CLOSURE_INTERVAL; +"CLOSURE_INTER_CONVEX",CLOSURE_INTER_CONVEX; +"CLOSURE_INTER_CONVEX_OPEN",CLOSURE_INTER_CONVEX_OPEN; +"CLOSURE_INTER_SUBSET",CLOSURE_INTER_SUBSET; +"CLOSURE_IRRATIONAL_COORDINATES",CLOSURE_IRRATIONAL_COORDINATES; +"CLOSURE_LINEAR_IMAGE_SUBSET",CLOSURE_LINEAR_IMAGE_SUBSET; +"CLOSURE_MINIMAL",CLOSURE_MINIMAL; +"CLOSURE_MINIMAL_EQ",CLOSURE_MINIMAL_EQ; +"CLOSURE_NEGATIONS",CLOSURE_NEGATIONS; +"CLOSURE_OPEN_INTERVAL",CLOSURE_OPEN_INTERVAL; +"CLOSURE_OPEN_INTER_SUPERSET",CLOSURE_OPEN_INTER_SUPERSET; +"CLOSURE_OUTSIDE_SUBSET",CLOSURE_OUTSIDE_SUBSET; +"CLOSURE_PCROSS",CLOSURE_PCROSS; +"CLOSURE_RATIONALS_IN_CONVEX_SET",CLOSURE_RATIONALS_IN_CONVEX_SET; +"CLOSURE_RATIONALS_IN_OPEN_SET",CLOSURE_RATIONALS_IN_OPEN_SET; +"CLOSURE_RATIONAL_COORDINATES",CLOSURE_RATIONAL_COORDINATES; +"CLOSURE_SEGMENT",CLOSURE_SEGMENT; +"CLOSURE_SEQUENTIAL",CLOSURE_SEQUENTIAL; +"CLOSURE_SING",CLOSURE_SING; +"CLOSURE_SUBSET",CLOSURE_SUBSET; +"CLOSURE_SUBSET_AFFINE_HULL",CLOSURE_SUBSET_AFFINE_HULL; +"CLOSURE_SUBSET_EQ",CLOSURE_SUBSET_EQ; +"CLOSURE_SURJECTIVE_LINEAR_IMAGE",CLOSURE_SURJECTIVE_LINEAR_IMAGE; +"CLOSURE_TRANSLATION",CLOSURE_TRANSLATION; +"CLOSURE_UNION",CLOSURE_UNION; +"CLOSURE_UNIONS",CLOSURE_UNIONS; +"CLOSURE_UNION_FRONTIER",CLOSURE_UNION_FRONTIER; +"CLOSURE_UNIQUE",CLOSURE_UNIQUE; +"CLOSURE_UNIV",CLOSURE_UNIV; +"COBOUNDED_HAS_BOUNDED_COMPONENT",COBOUNDED_HAS_BOUNDED_COMPONENT; +"COBOUNDED_IMP_UNBOUNDED",COBOUNDED_IMP_UNBOUNDED; +"COBOUNDED_INTER_UNBOUNDED",COBOUNDED_INTER_UNBOUNDED; +"COBOUNDED_OUTSIDE",COBOUNDED_OUTSIDE; +"COBOUNDED_UNBOUNDED_COMPONENT",COBOUNDED_UNBOUNDED_COMPONENT; +"COBOUNDED_UNBOUNDED_COMPONENTS",COBOUNDED_UNBOUNDED_COMPONENTS; +"COBOUNDED_UNIQUE_UNBOUNDED_COMPONENT",COBOUNDED_UNIQUE_UNBOUNDED_COMPONENT; +"COBOUNDED_UNIQUE_UNBOUNDED_COMPONENTS",COBOUNDED_UNIQUE_UNBOUNDED_COMPONENTS; +"COCOUNTABLE_APPROXIMATION",COCOUNTABLE_APPROXIMATION; +"CODESET_SETCODE_BIJECTIONS",CODESET_SETCODE_BIJECTIONS; +"COFACTOR_0",COFACTOR_0; +"COFACTOR_CMUL",COFACTOR_CMUL; +"COFACTOR_COFACTOR",COFACTOR_COFACTOR; +"COFACTOR_COLUMN",COFACTOR_COLUMN; +"COFACTOR_I",COFACTOR_I; +"COFACTOR_MATRIX_INV",COFACTOR_MATRIX_INV; +"COFACTOR_MATRIX_MUL",COFACTOR_MATRIX_MUL; +"COFACTOR_ROW",COFACTOR_ROW; +"COFACTOR_TRANSP",COFACTOR_TRANSP; +"COHOMOTOPICALLY_TRIVIAL_RETRACTION_GEN",COHOMOTOPICALLY_TRIVIAL_RETRACTION_GEN; +"COHOMOTOPICALLY_TRIVIAL_RETRACTION_NULL_GEN",COHOMOTOPICALLY_TRIVIAL_RETRACTION_NULL_GEN; +"COLLINEAR_1",COLLINEAR_1; +"COLLINEAR_2",COLLINEAR_2; +"COLLINEAR_3",COLLINEAR_3; +"COLLINEAR_3_2D",COLLINEAR_3_2D; +"COLLINEAR_3_AFFINE_HULL",COLLINEAR_3_AFFINE_HULL; +"COLLINEAR_3_DOT_MULTIPLES",COLLINEAR_3_DOT_MULTIPLES; +"COLLINEAR_3_EQ_AFFINE_DEPENDENT",COLLINEAR_3_EQ_AFFINE_DEPENDENT; +"COLLINEAR_3_EXPAND",COLLINEAR_3_EXPAND; +"COLLINEAR_3_IN_AFFINE_HULL",COLLINEAR_3_IN_AFFINE_HULL; +"COLLINEAR_3_TRANS",COLLINEAR_3_TRANS; +"COLLINEAR_4_3",COLLINEAR_4_3; +"COLLINEAR_AFFINE_HULL",COLLINEAR_AFFINE_HULL; +"COLLINEAR_AFFINE_HULL_COLLINEAR",COLLINEAR_AFFINE_HULL_COLLINEAR; +"COLLINEAR_AFF_DIM",COLLINEAR_AFF_DIM; +"COLLINEAR_BETWEEN_CASES",COLLINEAR_BETWEEN_CASES; +"COLLINEAR_CONVEX_HULL_COLLINEAR",COLLINEAR_CONVEX_HULL_COLLINEAR; +"COLLINEAR_DIST_BETWEEN",COLLINEAR_DIST_BETWEEN; +"COLLINEAR_DIST_IN_CLOSED_SEGMENT",COLLINEAR_DIST_IN_CLOSED_SEGMENT; +"COLLINEAR_DIST_IN_OPEN_SEGMENT",COLLINEAR_DIST_IN_OPEN_SEGMENT; +"COLLINEAR_EMPTY",COLLINEAR_EMPTY; +"COLLINEAR_EXTREME_POINTS",COLLINEAR_EXTREME_POINTS; +"COLLINEAR_IMP_COPLANAR",COLLINEAR_IMP_COPLANAR; +"COLLINEAR_LEMMA",COLLINEAR_LEMMA; +"COLLINEAR_LEMMA_ALT",COLLINEAR_LEMMA_ALT; +"COLLINEAR_LINEAR_IMAGE",COLLINEAR_LINEAR_IMAGE; +"COLLINEAR_LINEAR_IMAGE_EQ",COLLINEAR_LINEAR_IMAGE_EQ; +"COLLINEAR_MIDPOINT",COLLINEAR_MIDPOINT; +"COLLINEAR_SEGMENT",COLLINEAR_SEGMENT; +"COLLINEAR_SING",COLLINEAR_SING; +"COLLINEAR_SMALL",COLLINEAR_SMALL; +"COLLINEAR_SUBSET",COLLINEAR_SUBSET; +"COLLINEAR_TRANSLATION",COLLINEAR_TRANSLATION; +"COLLINEAR_TRANSLATION_EQ",COLLINEAR_TRANSLATION_EQ; +"COLLINEAR_TRIPLES",COLLINEAR_TRIPLES; +"COLUMNS_IMAGE_BASIS",COLUMNS_IMAGE_BASIS; +"COLUMNS_TRANSP",COLUMNS_TRANSP; +"COLUMN_TRANSP",COLUMN_TRANSP; +"COMMA_DEF",COMMA_DEF; +"COMPACT_AFFINITY",COMPACT_AFFINITY; +"COMPACT_ARC_IMAGE",COMPACT_ARC_IMAGE; +"COMPACT_ATTAINS_INF",COMPACT_ATTAINS_INF; +"COMPACT_ATTAINS_SUP",COMPACT_ATTAINS_SUP; +"COMPACT_CBALL",COMPACT_CBALL; +"COMPACT_CHAIN",COMPACT_CHAIN; +"COMPACT_CLOSED_DIFFERENCES",COMPACT_CLOSED_DIFFERENCES; +"COMPACT_CLOSED_SUMS",COMPACT_CLOSED_SUMS; +"COMPACT_CLOSURE",COMPACT_CLOSURE; +"COMPACT_CONTINUOUS_IMAGE",COMPACT_CONTINUOUS_IMAGE; +"COMPACT_CONTINUOUS_IMAGE_EQ",COMPACT_CONTINUOUS_IMAGE_EQ; +"COMPACT_CONVEX_COLLINEAR_SEGMENT",COMPACT_CONVEX_COLLINEAR_SEGMENT; +"COMPACT_CONVEX_COMBINATIONS",COMPACT_CONVEX_COMBINATIONS; +"COMPACT_CONVEX_HULL",COMPACT_CONVEX_HULL; +"COMPACT_DIFF",COMPACT_DIFF; +"COMPACT_DIFFERENCES",COMPACT_DIFFERENCES; +"COMPACT_EMPTY",COMPACT_EMPTY; +"COMPACT_EQ_BOLZANO_WEIERSTRASS",COMPACT_EQ_BOLZANO_WEIERSTRASS; +"COMPACT_EQ_BOUNDED_CLOSED",COMPACT_EQ_BOUNDED_CLOSED; +"COMPACT_EQ_HEINE_BOREL",COMPACT_EQ_HEINE_BOREL; +"COMPACT_EQ_HEINE_BOREL_SUBTOPOLOGY",COMPACT_EQ_HEINE_BOREL_SUBTOPOLOGY; +"COMPACT_FIP",COMPACT_FIP; +"COMPACT_FRONTIER",COMPACT_FRONTIER; +"COMPACT_FRONTIER_BOUNDED",COMPACT_FRONTIER_BOUNDED; +"COMPACT_FRONTIER_LINE_LEMMA",COMPACT_FRONTIER_LINE_LEMMA; +"COMPACT_IMP_BOUNDED",COMPACT_IMP_BOUNDED; +"COMPACT_IMP_CLOSED",COMPACT_IMP_CLOSED; +"COMPACT_IMP_COMPLETE",COMPACT_IMP_COMPLETE; +"COMPACT_IMP_FIP",COMPACT_IMP_FIP; +"COMPACT_IMP_HEINE_BOREL",COMPACT_IMP_HEINE_BOREL; +"COMPACT_IMP_TOTALLY_BOUNDED",COMPACT_IMP_TOTALLY_BOUNDED; +"COMPACT_INSERT",COMPACT_INSERT; +"COMPACT_INTER",COMPACT_INTER; +"COMPACT_INTERS",COMPACT_INTERS; +"COMPACT_INTERVAL",COMPACT_INTERVAL; +"COMPACT_INTERVAL_EQ",COMPACT_INTERVAL_EQ; +"COMPACT_INTER_CLOSED",COMPACT_INTER_CLOSED; +"COMPACT_LEMMA",COMPACT_LEMMA; +"COMPACT_LINEAR_IMAGE",COMPACT_LINEAR_IMAGE; +"COMPACT_LINEAR_IMAGE_EQ",COMPACT_LINEAR_IMAGE_EQ; +"COMPACT_NEGATIONS",COMPACT_NEGATIONS; +"COMPACT_NEST",COMPACT_NEST; +"COMPACT_OPEN",COMPACT_OPEN; +"COMPACT_PATH_IMAGE",COMPACT_PATH_IMAGE; +"COMPACT_PCROSS",COMPACT_PCROSS; +"COMPACT_PCROSS_EQ",COMPACT_PCROSS_EQ; +"COMPACT_REAL_LEMMA",COMPACT_REAL_LEMMA; +"COMPACT_RELATIVE_BOUNDARY",COMPACT_RELATIVE_BOUNDARY; +"COMPACT_RELATIVE_FRONTIER",COMPACT_RELATIVE_FRONTIER; +"COMPACT_RELATIVE_FRONTIER_BOUNDED",COMPACT_RELATIVE_FRONTIER_BOUNDED; +"COMPACT_SCALING",COMPACT_SCALING; +"COMPACT_SEGMENT",COMPACT_SEGMENT; +"COMPACT_SEQUENCE_WITH_LIMIT",COMPACT_SEQUENCE_WITH_LIMIT; +"COMPACT_SIMPLEX",COMPACT_SIMPLEX; +"COMPACT_SIMPLE_PATH_IMAGE",COMPACT_SIMPLE_PATH_IMAGE; +"COMPACT_SING",COMPACT_SING; +"COMPACT_SPHERE",COMPACT_SPHERE; +"COMPACT_SUBSET_FRONTIER_RETRACTION",COMPACT_SUBSET_FRONTIER_RETRACTION; +"COMPACT_SUMS",COMPACT_SUMS; +"COMPACT_SUP_MAXDISTANCE",COMPACT_SUP_MAXDISTANCE; +"COMPACT_TRANSLATION",COMPACT_TRANSLATION; +"COMPACT_TRANSLATION_EQ",COMPACT_TRANSLATION_EQ; +"COMPACT_UNIFORMLY_CONTINUOUS",COMPACT_UNIFORMLY_CONTINUOUS; +"COMPACT_UNIFORMLY_EQUICONTINUOUS",COMPACT_UNIFORMLY_EQUICONTINUOUS; +"COMPACT_UNION",COMPACT_UNION; +"COMPACT_UNIONS",COMPACT_UNIONS; +"COMPLETE_EQ_CLOSED",COMPLETE_EQ_CLOSED; +"COMPLETE_FACE_TOP",COMPLETE_FACE_TOP; +"COMPLETE_INJECTIVE_LINEAR_IMAGE",COMPLETE_INJECTIVE_LINEAR_IMAGE; +"COMPLETE_INJECTIVE_LINEAR_IMAGE_EQ",COMPLETE_INJECTIVE_LINEAR_IMAGE_EQ; +"COMPLETE_ISOMETRIC_IMAGE",COMPLETE_ISOMETRIC_IMAGE; +"COMPLETE_SUBSPACE",COMPLETE_SUBSPACE; +"COMPLETE_TRANSLATION_EQ",COMPLETE_TRANSLATION_EQ; +"COMPLETE_UNIV",COMPLETE_UNIV; +"COMPONENT",COMPONENT; +"COMPONENTS_EQ",COMPONENTS_EQ; +"COMPONENTS_EQ_EMPTY",COMPONENTS_EQ_EMPTY; +"COMPONENTS_EQ_SING",COMPONENTS_EQ_SING; +"COMPONENTS_EQ_SING_EXISTS",COMPONENTS_EQ_SING_EXISTS; +"COMPONENTS_LINEAR_IMAGE",COMPONENTS_LINEAR_IMAGE; +"COMPONENTS_MAXIMAL",COMPONENTS_MAXIMAL; +"COMPONENTS_NONOVERLAP",COMPONENTS_NONOVERLAP; +"COMPONENTS_OPEN_UNIQUE",COMPONENTS_OPEN_UNIQUE; +"COMPONENTS_TRANSLATION",COMPONENTS_TRANSLATION; +"COMPONENTS_UNIQUE",COMPONENTS_UNIQUE; +"COMPONENTS_UNIQUE_EQ",COMPONENTS_UNIQUE_EQ; +"COMPONENT_COMPLEMENT_CONNECTED",COMPONENT_COMPLEMENT_CONNECTED; +"COMPONENT_LE_INFNORM",COMPONENT_LE_INFNORM; +"COMPONENT_LE_NORM",COMPONENT_LE_NORM; +"CONDENSATION_POINTS_EQ_EMPTY",CONDENSATION_POINTS_EQ_EMPTY; +"CONDENSATION_POINT_IMP_LIMPT",CONDENSATION_POINT_IMP_LIMPT; +"CONDENSATION_POINT_INFINITE_BALL",CONDENSATION_POINT_INFINITE_BALL; +"CONDENSATION_POINT_INFINITE_CBALL",CONDENSATION_POINT_INFINITE_CBALL; +"COND_ABS",COND_ABS; +"COND_CLAUSES",COND_CLAUSES; +"COND_COMPONENT",COND_COMPONENT; +"COND_DEF",COND_DEF; +"COND_ELIM_THM",COND_ELIM_THM; +"COND_EXPAND",COND_EXPAND; +"COND_ID",COND_ID; +"COND_RAND",COND_RAND; +"COND_RATOR",COND_RATOR; +"CONGRUENT_IMAGE_STD_SIMPLEX",CONGRUENT_IMAGE_STD_SIMPLEX; +"CONIC_CONIC_HULL",CONIC_CONIC_HULL; +"CONIC_CONTAINS_0",CONIC_CONTAINS_0; +"CONIC_CONVEX_CONE_HULL",CONIC_CONVEX_CONE_HULL; +"CONIC_EMPTY",CONIC_EMPTY; +"CONIC_HALFSPACE_GE",CONIC_HALFSPACE_GE; +"CONIC_HALFSPACE_LE",CONIC_HALFSPACE_LE; +"CONIC_HULL_EMPTY",CONIC_HULL_EMPTY; +"CONIC_HULL_EQ",CONIC_HULL_EQ; +"CONIC_HULL_EQ_EMPTY",CONIC_HULL_EQ_EMPTY; +"CONIC_HULL_EXPLICIT",CONIC_HULL_EXPLICIT; +"CONIC_HULL_LINEAR_IMAGE",CONIC_HULL_LINEAR_IMAGE; +"CONIC_HULL_SUBSET_CONVEX_CONE_HULL",CONIC_HULL_SUBSET_CONVEX_CONE_HULL; +"CONIC_INTERS",CONIC_INTERS; +"CONIC_LINEAR_IMAGE",CONIC_LINEAR_IMAGE; +"CONIC_LINEAR_IMAGE_EQ",CONIC_LINEAR_IMAGE_EQ; +"CONIC_NEGATIONS",CONIC_NEGATIONS; +"CONIC_PCROSS",CONIC_PCROSS; +"CONIC_PCROSS_EQ",CONIC_PCROSS_EQ; +"CONIC_POSITIVE_ORTHANT",CONIC_POSITIVE_ORTHANT; +"CONIC_SPAN",CONIC_SPAN; +"CONIC_SUMS",CONIC_SUMS; +"CONIC_UNIV",CONIC_UNIV; +"CONJ_ACI",CONJ_ACI; +"CONJ_ASSOC",CONJ_ASSOC; +"CONJ_SYM",CONJ_SYM; +"CONNECTED_ANNULUS",CONNECTED_ANNULUS; +"CONNECTED_ARC_COMPLEMENT",CONNECTED_ARC_COMPLEMENT; +"CONNECTED_ARC_IMAGE",CONNECTED_ARC_IMAGE; +"CONNECTED_BALL",CONNECTED_BALL; +"CONNECTED_CARD_EQ_IFF_NONTRIVIAL",CONNECTED_CARD_EQ_IFF_NONTRIVIAL; +"CONNECTED_CBALL",CONNECTED_CBALL; +"CONNECTED_CHAIN",CONNECTED_CHAIN; +"CONNECTED_CHAIN_GEN",CONNECTED_CHAIN_GEN; +"CONNECTED_CLOPEN",CONNECTED_CLOPEN; +"CONNECTED_CLOSED",CONNECTED_CLOSED; +"CONNECTED_CLOSED_IN",CONNECTED_CLOSED_IN; +"CONNECTED_CLOSED_IN_EQ",CONNECTED_CLOSED_IN_EQ; +"CONNECTED_CLOSED_SET",CONNECTED_CLOSED_SET; +"CONNECTED_CLOSURE",CONNECTED_CLOSURE; +"CONNECTED_COMPACT_INTERVAL_1",CONNECTED_COMPACT_INTERVAL_1; +"CONNECTED_COMPLEMENT_ABSOLUTE_RETRACT",CONNECTED_COMPLEMENT_ABSOLUTE_RETRACT; +"CONNECTED_COMPLEMENT_BOUNDED_CONVEX",CONNECTED_COMPLEMENT_BOUNDED_CONVEX; +"CONNECTED_COMPLEMENT_HOMEOMORPHIC_CONVEX_COMPACT",CONNECTED_COMPLEMENT_HOMEOMORPHIC_CONVEX_COMPACT; +"CONNECTED_COMPONENT_1",CONNECTED_COMPONENT_1; +"CONNECTED_COMPONENT_1_GEN",CONNECTED_COMPONENT_1_GEN; +"CONNECTED_COMPONENT_DISJOINT",CONNECTED_COMPONENT_DISJOINT; +"CONNECTED_COMPONENT_EMPTY",CONNECTED_COMPONENT_EMPTY; +"CONNECTED_COMPONENT_EQ",CONNECTED_COMPONENT_EQ; +"CONNECTED_COMPONENT_EQUIVALENCE_RELATION",CONNECTED_COMPONENT_EQUIVALENCE_RELATION; +"CONNECTED_COMPONENT_EQ_EMPTY",CONNECTED_COMPONENT_EQ_EMPTY; +"CONNECTED_COMPONENT_EQ_EQ",CONNECTED_COMPONENT_EQ_EQ; +"CONNECTED_COMPONENT_EQ_SELF",CONNECTED_COMPONENT_EQ_SELF; +"CONNECTED_COMPONENT_EQ_UNIV",CONNECTED_COMPONENT_EQ_UNIV; +"CONNECTED_COMPONENT_IDEMP",CONNECTED_COMPONENT_IDEMP; +"CONNECTED_COMPONENT_IN",CONNECTED_COMPONENT_IN; +"CONNECTED_COMPONENT_LINEAR_IMAGE",CONNECTED_COMPONENT_LINEAR_IMAGE; +"CONNECTED_COMPONENT_MAXIMAL",CONNECTED_COMPONENT_MAXIMAL; +"CONNECTED_COMPONENT_MONO",CONNECTED_COMPONENT_MONO; +"CONNECTED_COMPONENT_NONOVERLAP",CONNECTED_COMPONENT_NONOVERLAP; +"CONNECTED_COMPONENT_OF_SUBSET",CONNECTED_COMPONENT_OF_SUBSET; +"CONNECTED_COMPONENT_OVERLAP",CONNECTED_COMPONENT_OVERLAP; +"CONNECTED_COMPONENT_REFL",CONNECTED_COMPONENT_REFL; +"CONNECTED_COMPONENT_REFL_EQ",CONNECTED_COMPONENT_REFL_EQ; +"CONNECTED_COMPONENT_SET",CONNECTED_COMPONENT_SET; +"CONNECTED_COMPONENT_SUBSET",CONNECTED_COMPONENT_SUBSET; +"CONNECTED_COMPONENT_SYM",CONNECTED_COMPONENT_SYM; +"CONNECTED_COMPONENT_SYM_EQ",CONNECTED_COMPONENT_SYM_EQ; +"CONNECTED_COMPONENT_TRANS",CONNECTED_COMPONENT_TRANS; +"CONNECTED_COMPONENT_TRANSLATION",CONNECTED_COMPONENT_TRANSLATION; +"CONNECTED_COMPONENT_UNIONS",CONNECTED_COMPONENT_UNIONS; +"CONNECTED_COMPONENT_UNIQUE",CONNECTED_COMPONENT_UNIQUE; +"CONNECTED_COMPONENT_UNIV",CONNECTED_COMPONENT_UNIV; +"CONNECTED_CONNECTED_COMPONENT",CONNECTED_CONNECTED_COMPONENT; +"CONNECTED_CONNECTED_COMPONENT_SET",CONNECTED_CONNECTED_COMPONENT_SET; +"CONNECTED_CONTINUOUS_IMAGE",CONNECTED_CONTINUOUS_IMAGE; +"CONNECTED_CONVEX_1",CONNECTED_CONVEX_1; +"CONNECTED_CONVEX_1_GEN",CONNECTED_CONVEX_1_GEN; +"CONNECTED_DIFF_BALL",CONNECTED_DIFF_BALL; +"CONNECTED_DIFF_OPEN_FROM_CLOSED",CONNECTED_DIFF_OPEN_FROM_CLOSED; +"CONNECTED_DISJOINT_UNIONS_OPEN_UNIQUE",CONNECTED_DISJOINT_UNIONS_OPEN_UNIQUE; +"CONNECTED_EMPTY",CONNECTED_EMPTY; +"CONNECTED_EQUIVALENCE_RELATION",CONNECTED_EQUIVALENCE_RELATION; +"CONNECTED_EQUIVALENCE_RELATION_GEN",CONNECTED_EQUIVALENCE_RELATION_GEN; +"CONNECTED_EQ_CONNECTED_COMPONENTS_EQ",CONNECTED_EQ_CONNECTED_COMPONENTS_EQ; +"CONNECTED_EQ_CONNECTED_COMPONENT_EQ",CONNECTED_EQ_CONNECTED_COMPONENT_EQ; +"CONNECTED_FINITE_IFF_COUNTABLE",CONNECTED_FINITE_IFF_COUNTABLE; +"CONNECTED_FINITE_IFF_SING",CONNECTED_FINITE_IFF_SING; +"CONNECTED_IFF_CONNECTED_COMPONENT",CONNECTED_IFF_CONNECTED_COMPONENT; +"CONNECTED_IMP_PERFECT",CONNECTED_IMP_PERFECT; +"CONNECTED_IMP_PERFECT_AFF_DIM",CONNECTED_IMP_PERFECT_AFF_DIM; +"CONNECTED_INDUCTION",CONNECTED_INDUCTION; +"CONNECTED_INDUCTION_SIMPLE",CONNECTED_INDUCTION_SIMPLE; +"CONNECTED_INFINITE_IFF_CARD_EQ",CONNECTED_INFINITE_IFF_CARD_EQ; +"CONNECTED_INTERMEDIATE_CLOSURE",CONNECTED_INTERMEDIATE_CLOSURE; +"CONNECTED_INTERVAL",CONNECTED_INTERVAL; +"CONNECTED_INTER_FRONTIER",CONNECTED_INTER_FRONTIER; +"CONNECTED_INTER_RELATIVE_FRONTIER",CONNECTED_INTER_RELATIVE_FRONTIER; +"CONNECTED_IVT_COMPONENT",CONNECTED_IVT_COMPONENT; +"CONNECTED_IVT_HYPERPLANE",CONNECTED_IVT_HYPERPLANE; +"CONNECTED_LINEAR_IMAGE",CONNECTED_LINEAR_IMAGE; +"CONNECTED_LINEAR_IMAGE_EQ",CONNECTED_LINEAR_IMAGE_EQ; +"CONNECTED_NEGATIONS",CONNECTED_NEGATIONS; +"CONNECTED_NEST",CONNECTED_NEST; +"CONNECTED_NEST_GEN",CONNECTED_NEST_GEN; +"CONNECTED_OPEN_ARC_CONNECTED",CONNECTED_OPEN_ARC_CONNECTED; +"CONNECTED_OPEN_DELETE",CONNECTED_OPEN_DELETE; +"CONNECTED_OPEN_DIFF_CARD_LT",CONNECTED_OPEN_DIFF_CARD_LT; +"CONNECTED_OPEN_DIFF_CBALL",CONNECTED_OPEN_DIFF_CBALL; +"CONNECTED_OPEN_DIFF_COUNTABLE",CONNECTED_OPEN_DIFF_COUNTABLE; +"CONNECTED_OPEN_IN",CONNECTED_OPEN_IN; +"CONNECTED_OPEN_IN_DIFF_CARD_LT",CONNECTED_OPEN_IN_DIFF_CARD_LT; +"CONNECTED_OPEN_IN_EQ",CONNECTED_OPEN_IN_EQ; +"CONNECTED_OPEN_PATH_CONNECTED",CONNECTED_OPEN_PATH_CONNECTED; +"CONNECTED_OPEN_SET",CONNECTED_OPEN_SET; +"CONNECTED_OUTSIDE",CONNECTED_OUTSIDE; +"CONNECTED_PATH_IMAGE",CONNECTED_PATH_IMAGE; +"CONNECTED_PCROSS",CONNECTED_PCROSS; +"CONNECTED_PCROSS_EQ",CONNECTED_PCROSS_EQ; +"CONNECTED_PUNCTURED_BALL",CONNECTED_PUNCTURED_BALL; +"CONNECTED_PUNCTURED_UNIVERSE",CONNECTED_PUNCTURED_UNIVERSE; +"CONNECTED_REAL_LEMMA",CONNECTED_REAL_LEMMA; +"CONNECTED_SCALING",CONNECTED_SCALING; +"CONNECTED_SEGMENT",CONNECTED_SEGMENT; +"CONNECTED_SEMIOPEN_SEGMENT",CONNECTED_SEMIOPEN_SEGMENT; +"CONNECTED_SIMPLE_PATH_ENDLESS",CONNECTED_SIMPLE_PATH_ENDLESS; +"CONNECTED_SIMPLE_PATH_IMAGE",CONNECTED_SIMPLE_PATH_IMAGE; +"CONNECTED_SING",CONNECTED_SING; +"CONNECTED_SPHERE",CONNECTED_SPHERE; +"CONNECTED_SPHERE_EQ",CONNECTED_SPHERE_EQ; +"CONNECTED_SUMS",CONNECTED_SUMS; +"CONNECTED_TRANSLATION",CONNECTED_TRANSLATION; +"CONNECTED_TRANSLATION_EQ",CONNECTED_TRANSLATION_EQ; +"CONNECTED_UNION",CONNECTED_UNION; +"CONNECTED_UNIONS",CONNECTED_UNIONS; +"CONNECTED_UNION_CLOPEN_IN_COMPLEMENT",CONNECTED_UNION_CLOPEN_IN_COMPLEMENT; +"CONNECTED_UNION_STRONG",CONNECTED_UNION_STRONG; +"CONNECTED_UNIV",CONNECTED_UNIV; +"CONNECTED_WITH_INSIDE",CONNECTED_WITH_INSIDE; +"CONNECTED_WITH_OUTSIDE",CONNECTED_WITH_OUTSIDE; +"CONSTR",CONSTR; +"CONSTR_BOT",CONSTR_BOT; +"CONSTR_IND",CONSTR_IND; +"CONSTR_INJ",CONSTR_INJ; +"CONSTR_REC",CONSTR_REC; +"CONS_11",CONS_11; +"CONS_HD_TL",CONS_HD_TL; +"CONTENT_0_SUBSET",CONTENT_0_SUBSET; +"CONTENT_0_SUBSET_GEN",CONTENT_0_SUBSET_GEN; +"CONTENT_1",CONTENT_1; +"CONTENT_CLOSED_INTERVAL",CONTENT_CLOSED_INTERVAL; +"CONTENT_CLOSED_INTERVAL_CASES",CONTENT_CLOSED_INTERVAL_CASES; +"CONTENT_DOUBLESPLIT",CONTENT_DOUBLESPLIT; +"CONTENT_EMPTY",CONTENT_EMPTY; +"CONTENT_EQ_0",CONTENT_EQ_0; +"CONTENT_EQ_0_1",CONTENT_EQ_0_1; +"CONTENT_EQ_0_GEN",CONTENT_EQ_0_GEN; +"CONTENT_EQ_0_INTERIOR",CONTENT_EQ_0_INTERIOR; +"CONTENT_IMAGE_AFFINITY_INTERVAL",CONTENT_IMAGE_AFFINITY_INTERVAL; +"CONTENT_IMAGE_STRETCH_INTERVAL",CONTENT_IMAGE_STRETCH_INTERVAL; +"CONTENT_LT_NZ",CONTENT_LT_NZ; +"CONTENT_PASTECART",CONTENT_PASTECART; +"CONTENT_POS_LE",CONTENT_POS_LE; +"CONTENT_POS_LT",CONTENT_POS_LT; +"CONTENT_POS_LT_1",CONTENT_POS_LT_1; +"CONTENT_POS_LT_EQ",CONTENT_POS_LT_EQ; +"CONTENT_SPLIT",CONTENT_SPLIT; +"CONTENT_SUBSET",CONTENT_SUBSET; +"CONTENT_UNIT",CONTENT_UNIT; +"CONTENT_UNIT_1",CONTENT_UNIT_1; +"CONTINUOUS_ABS",CONTINUOUS_ABS; +"CONTINUOUS_ADD",CONTINUOUS_ADD; +"CONTINUOUS_AGREE_ON_CLOSURE",CONTINUOUS_AGREE_ON_CLOSURE; +"CONTINUOUS_AT",CONTINUOUS_AT; +"CONTINUOUS_ATTAINS_INF",CONTINUOUS_ATTAINS_INF; +"CONTINUOUS_ATTAINS_SUP",CONTINUOUS_ATTAINS_SUP; +"CONTINUOUS_AT_AVOID",CONTINUOUS_AT_AVOID; +"CONTINUOUS_AT_BALL",CONTINUOUS_AT_BALL; +"CONTINUOUS_AT_CLOSEST_POINT",CONTINUOUS_AT_CLOSEST_POINT; +"CONTINUOUS_AT_COMPOSE",CONTINUOUS_AT_COMPOSE; +"CONTINUOUS_AT_COMPOSE_EQ",CONTINUOUS_AT_COMPOSE_EQ; +"CONTINUOUS_AT_DIST_CLOSEST_POINT",CONTINUOUS_AT_DIST_CLOSEST_POINT; +"CONTINUOUS_AT_ID",CONTINUOUS_AT_ID; +"CONTINUOUS_AT_IMP_CONTINUOUS_ON",CONTINUOUS_AT_IMP_CONTINUOUS_ON; +"CONTINUOUS_AT_INV",CONTINUOUS_AT_INV; +"CONTINUOUS_AT_LIFT_COMPONENT",CONTINUOUS_AT_LIFT_COMPONENT; +"CONTINUOUS_AT_LIFT_DIST",CONTINUOUS_AT_LIFT_DIST; +"CONTINUOUS_AT_LIFT_DOT",CONTINUOUS_AT_LIFT_DOT; +"CONTINUOUS_AT_LIFT_INFNORM",CONTINUOUS_AT_LIFT_INFNORM; +"CONTINUOUS_AT_LIFT_NORM",CONTINUOUS_AT_LIFT_NORM; +"CONTINUOUS_AT_LIFT_RANGE",CONTINUOUS_AT_LIFT_RANGE; +"CONTINUOUS_AT_LIFT_SETDIST",CONTINUOUS_AT_LIFT_SETDIST; +"CONTINUOUS_AT_LINEAR_IMAGE",CONTINUOUS_AT_LINEAR_IMAGE; +"CONTINUOUS_AT_OPEN",CONTINUOUS_AT_OPEN; +"CONTINUOUS_AT_SEQUENTIALLY",CONTINUOUS_AT_SEQUENTIALLY; +"CONTINUOUS_AT_SQRT",CONTINUOUS_AT_SQRT; +"CONTINUOUS_AT_SQRT_COMPOSE",CONTINUOUS_AT_SQRT_COMPOSE; +"CONTINUOUS_AT_TRANSLATION",CONTINUOUS_AT_TRANSLATION; +"CONTINUOUS_AT_WITHIN",CONTINUOUS_AT_WITHIN; +"CONTINUOUS_AT_WITHIN_INV",CONTINUOUS_AT_WITHIN_INV; +"CONTINUOUS_CARD_LT_RANGE_CONSTANT",CONTINUOUS_CARD_LT_RANGE_CONSTANT; +"CONTINUOUS_CARD_LT_RANGE_CONSTANT_EQ",CONTINUOUS_CARD_LT_RANGE_CONSTANT_EQ; +"CONTINUOUS_CLOSED_IMP_CAUCHY_CONTINUOUS",CONTINUOUS_CLOSED_IMP_CAUCHY_CONTINUOUS; +"CONTINUOUS_CLOSED_IN_PREIMAGE",CONTINUOUS_CLOSED_IN_PREIMAGE; +"CONTINUOUS_CLOSED_IN_PREIMAGE_CONSTANT",CONTINUOUS_CLOSED_IN_PREIMAGE_CONSTANT; +"CONTINUOUS_CLOSED_IN_PREIMAGE_EQ",CONTINUOUS_CLOSED_IN_PREIMAGE_EQ; +"CONTINUOUS_CLOSED_IN_PREIMAGE_GEN",CONTINUOUS_CLOSED_IN_PREIMAGE_GEN; +"CONTINUOUS_CLOSED_PREIMAGE",CONTINUOUS_CLOSED_PREIMAGE; +"CONTINUOUS_CLOSED_PREIMAGE_CONSTANT",CONTINUOUS_CLOSED_PREIMAGE_CONSTANT; +"CONTINUOUS_CLOSED_PREIMAGE_UNIV",CONTINUOUS_CLOSED_PREIMAGE_UNIV; +"CONTINUOUS_CMUL",CONTINUOUS_CMUL; +"CONTINUOUS_COMPONENTWISE_LIFT",CONTINUOUS_COMPONENTWISE_LIFT; +"CONTINUOUS_CONST",CONTINUOUS_CONST; +"CONTINUOUS_CONSTANT_ON_CLOSURE",CONTINUOUS_CONSTANT_ON_CLOSURE; +"CONTINUOUS_COUNTABLE_RANGE_CONSTANT",CONTINUOUS_COUNTABLE_RANGE_CONSTANT; +"CONTINUOUS_COUNTABLE_RANGE_CONSTANT_EQ",CONTINUOUS_COUNTABLE_RANGE_CONSTANT_EQ; +"CONTINUOUS_DISCONNECTED_RANGE_CONSTANT",CONTINUOUS_DISCONNECTED_RANGE_CONSTANT; +"CONTINUOUS_DISCONNECTED_RANGE_CONSTANT_EQ",CONTINUOUS_DISCONNECTED_RANGE_CONSTANT_EQ; +"CONTINUOUS_DISCRETE_RANGE_CONSTANT",CONTINUOUS_DISCRETE_RANGE_CONSTANT; +"CONTINUOUS_DISCRETE_RANGE_CONSTANT_EQ",CONTINUOUS_DISCRETE_RANGE_CONSTANT_EQ; +"CONTINUOUS_FINITE_RANGE_CONSTANT",CONTINUOUS_FINITE_RANGE_CONSTANT; +"CONTINUOUS_FINITE_RANGE_CONSTANT_EQ",CONTINUOUS_FINITE_RANGE_CONSTANT_EQ; +"CONTINUOUS_GE_ON_CLOSURE",CONTINUOUS_GE_ON_CLOSURE; +"CONTINUOUS_IMP_CLOSED_MAP",CONTINUOUS_IMP_CLOSED_MAP; +"CONTINUOUS_IMP_MEASURABLE_ON",CONTINUOUS_IMP_MEASURABLE_ON; +"CONTINUOUS_IMP_MEASURABLE_ON_CLOSED_SUBSET",CONTINUOUS_IMP_MEASURABLE_ON_CLOSED_SUBSET; +"CONTINUOUS_IMP_MEASURABLE_ON_LEBESGUE_MEASURABLE_SUBSET",CONTINUOUS_IMP_MEASURABLE_ON_LEBESGUE_MEASURABLE_SUBSET; +"CONTINUOUS_INJECTIVE_IFF_MONOTONIC",CONTINUOUS_INJECTIVE_IFF_MONOTONIC; +"CONTINUOUS_INJECTIVE_IMAGE_OPEN_SEGMENT_1",CONTINUOUS_INJECTIVE_IMAGE_OPEN_SEGMENT_1; +"CONTINUOUS_INJECTIVE_IMAGE_SEGMENT_1",CONTINUOUS_INJECTIVE_IMAGE_SEGMENT_1; +"CONTINUOUS_INTERVAL_BIJ",CONTINUOUS_INTERVAL_BIJ; +"CONTINUOUS_INV",CONTINUOUS_INV; +"CONTINUOUS_IVT_LOCAL_EXTREMUM",CONTINUOUS_IVT_LOCAL_EXTREMUM; +"CONTINUOUS_LEFT_INVERSE_IMP_QUOTIENT_MAP",CONTINUOUS_LEFT_INVERSE_IMP_QUOTIENT_MAP; +"CONTINUOUS_LEVELSET_OPEN",CONTINUOUS_LEVELSET_OPEN; +"CONTINUOUS_LEVELSET_OPEN_IN",CONTINUOUS_LEVELSET_OPEN_IN; +"CONTINUOUS_LEVELSET_OPEN_IN_CASES",CONTINUOUS_LEVELSET_OPEN_IN_CASES; +"CONTINUOUS_LE_ON_CLOSURE",CONTINUOUS_LE_ON_CLOSURE; +"CONTINUOUS_LIFT_COMPONENT_COMPOSE",CONTINUOUS_LIFT_COMPONENT_COMPOSE; +"CONTINUOUS_LIFT_DET",CONTINUOUS_LIFT_DET; +"CONTINUOUS_LIFT_DOT2",CONTINUOUS_LIFT_DOT2; +"CONTINUOUS_LIFT_NORM_COMPOSE",CONTINUOUS_LIFT_NORM_COMPOSE; +"CONTINUOUS_LIFT_POW",CONTINUOUS_LIFT_POW; +"CONTINUOUS_LIFT_PRODUCT",CONTINUOUS_LIFT_PRODUCT; +"CONTINUOUS_LINEPATH_AT",CONTINUOUS_LINEPATH_AT; +"CONTINUOUS_MAX",CONTINUOUS_MAX; +"CONTINUOUS_MIDPOINT_CONVEX",CONTINUOUS_MIDPOINT_CONVEX; +"CONTINUOUS_MIN",CONTINUOUS_MIN; +"CONTINUOUS_MUL",CONTINUOUS_MUL; +"CONTINUOUS_NEG",CONTINUOUS_NEG; +"CONTINUOUS_ON",CONTINUOUS_ON; +"CONTINUOUS_ON_ABS",CONTINUOUS_ON_ABS; +"CONTINUOUS_ON_ADD",CONTINUOUS_ON_ADD; +"CONTINUOUS_ON_AVOID",CONTINUOUS_ON_AVOID; +"CONTINUOUS_ON_CASES",CONTINUOUS_ON_CASES; +"CONTINUOUS_ON_CASES_1",CONTINUOUS_ON_CASES_1; +"CONTINUOUS_ON_CASES_LE",CONTINUOUS_ON_CASES_LE; +"CONTINUOUS_ON_CASES_LOCAL",CONTINUOUS_ON_CASES_LOCAL; +"CONTINUOUS_ON_CASES_LOCAL_OPEN",CONTINUOUS_ON_CASES_LOCAL_OPEN; +"CONTINUOUS_ON_CASES_OPEN",CONTINUOUS_ON_CASES_OPEN; +"CONTINUOUS_ON_CLOSED",CONTINUOUS_ON_CLOSED; +"CONTINUOUS_ON_CLOSED_GEN",CONTINUOUS_ON_CLOSED_GEN; +"CONTINUOUS_ON_CLOSEST_POINT",CONTINUOUS_ON_CLOSEST_POINT; +"CONTINUOUS_ON_CLOSURE",CONTINUOUS_ON_CLOSURE; +"CONTINUOUS_ON_CLOSURE_COMPONENT_GE",CONTINUOUS_ON_CLOSURE_COMPONENT_GE; +"CONTINUOUS_ON_CLOSURE_COMPONENT_LE",CONTINUOUS_ON_CLOSURE_COMPONENT_LE; +"CONTINUOUS_ON_CLOSURE_NORM_LE",CONTINUOUS_ON_CLOSURE_NORM_LE; +"CONTINUOUS_ON_CLOSURE_SEQUENTIALLY",CONTINUOUS_ON_CLOSURE_SEQUENTIALLY; +"CONTINUOUS_ON_CMUL",CONTINUOUS_ON_CMUL; +"CONTINUOUS_ON_COMPACT_SURFACE_PROJECTION",CONTINUOUS_ON_COMPACT_SURFACE_PROJECTION; +"CONTINUOUS_ON_COMPONENTS",CONTINUOUS_ON_COMPONENTS; +"CONTINUOUS_ON_COMPONENTS_CLOSED",CONTINUOUS_ON_COMPONENTS_CLOSED; +"CONTINUOUS_ON_COMPONENTS_CLOSED_GEN",CONTINUOUS_ON_COMPONENTS_CLOSED_GEN; +"CONTINUOUS_ON_COMPONENTS_EQ",CONTINUOUS_ON_COMPONENTS_EQ; +"CONTINUOUS_ON_COMPONENTS_GEN",CONTINUOUS_ON_COMPONENTS_GEN; +"CONTINUOUS_ON_COMPONENTWISE_LIFT",CONTINUOUS_ON_COMPONENTWISE_LIFT; +"CONTINUOUS_ON_COMPOSE",CONTINUOUS_ON_COMPOSE; +"CONTINUOUS_ON_CONST",CONTINUOUS_ON_CONST; +"CONTINUOUS_ON_DIST_CLOSEST_POINT",CONTINUOUS_ON_DIST_CLOSEST_POINT; +"CONTINUOUS_ON_EMPTY",CONTINUOUS_ON_EMPTY; +"CONTINUOUS_ON_EQ",CONTINUOUS_ON_EQ; +"CONTINUOUS_ON_EQ_CONTINUOUS_AT",CONTINUOUS_ON_EQ_CONTINUOUS_AT; +"CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN",CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN; +"CONTINUOUS_ON_FINITE",CONTINUOUS_ON_FINITE; +"CONTINUOUS_ON_ID",CONTINUOUS_ON_ID; +"CONTINUOUS_ON_IMP_CLOSED_IN",CONTINUOUS_ON_IMP_CLOSED_IN; +"CONTINUOUS_ON_IMP_OPEN_IN",CONTINUOUS_ON_IMP_OPEN_IN; +"CONTINUOUS_ON_INTERIOR",CONTINUOUS_ON_INTERIOR; +"CONTINUOUS_ON_INTERVAL_BIJ",CONTINUOUS_ON_INTERVAL_BIJ; +"CONTINUOUS_ON_INV",CONTINUOUS_ON_INV; +"CONTINUOUS_ON_INVERSE",CONTINUOUS_ON_INVERSE; +"CONTINUOUS_ON_INVERSE_CLOSED_MAP",CONTINUOUS_ON_INVERSE_CLOSED_MAP; +"CONTINUOUS_ON_INVERSE_OPEN_MAP",CONTINUOUS_ON_INVERSE_OPEN_MAP; +"CONTINUOUS_ON_LIFT_COMPONENT",CONTINUOUS_ON_LIFT_COMPONENT; +"CONTINUOUS_ON_LIFT_COMPONENT_COMPOSE",CONTINUOUS_ON_LIFT_COMPONENT_COMPOSE; +"CONTINUOUS_ON_LIFT_DET",CONTINUOUS_ON_LIFT_DET; +"CONTINUOUS_ON_LIFT_DIST",CONTINUOUS_ON_LIFT_DIST; +"CONTINUOUS_ON_LIFT_DOT",CONTINUOUS_ON_LIFT_DOT; +"CONTINUOUS_ON_LIFT_DOT2",CONTINUOUS_ON_LIFT_DOT2; +"CONTINUOUS_ON_LIFT_NORM",CONTINUOUS_ON_LIFT_NORM; +"CONTINUOUS_ON_LIFT_NORM_COMPOSE",CONTINUOUS_ON_LIFT_NORM_COMPOSE; +"CONTINUOUS_ON_LIFT_POW",CONTINUOUS_ON_LIFT_POW; +"CONTINUOUS_ON_LIFT_PRODUCT",CONTINUOUS_ON_LIFT_PRODUCT; +"CONTINUOUS_ON_LIFT_RANGE",CONTINUOUS_ON_LIFT_RANGE; +"CONTINUOUS_ON_LIFT_SETDIST",CONTINUOUS_ON_LIFT_SETDIST; +"CONTINUOUS_ON_LIFT_SQRT",CONTINUOUS_ON_LIFT_SQRT; +"CONTINUOUS_ON_LIFT_SQRT_COMPOSE",CONTINUOUS_ON_LIFT_SQRT_COMPOSE; +"CONTINUOUS_ON_LINEPATH",CONTINUOUS_ON_LINEPATH; +"CONTINUOUS_ON_MAX",CONTINUOUS_ON_MAX; +"CONTINUOUS_ON_MIN",CONTINUOUS_ON_MIN; +"CONTINUOUS_ON_MUL",CONTINUOUS_ON_MUL; +"CONTINUOUS_ON_NEG",CONTINUOUS_ON_NEG; +"CONTINUOUS_ON_NO_LIMPT",CONTINUOUS_ON_NO_LIMPT; +"CONTINUOUS_ON_OPEN",CONTINUOUS_ON_OPEN; +"CONTINUOUS_ON_OPEN_AVOID",CONTINUOUS_ON_OPEN_AVOID; +"CONTINUOUS_ON_OPEN_GEN",CONTINUOUS_ON_OPEN_GEN; +"CONTINUOUS_ON_PASTECART",CONTINUOUS_ON_PASTECART; +"CONTINUOUS_ON_SEQUENTIALLY",CONTINUOUS_ON_SEQUENTIALLY; +"CONTINUOUS_ON_SING",CONTINUOUS_ON_SING; +"CONTINUOUS_ON_SUB",CONTINUOUS_ON_SUB; +"CONTINUOUS_ON_SUBSET",CONTINUOUS_ON_SUBSET; +"CONTINUOUS_ON_UNION",CONTINUOUS_ON_UNION; +"CONTINUOUS_ON_UNION_LOCAL",CONTINUOUS_ON_UNION_LOCAL; +"CONTINUOUS_ON_UNION_LOCAL_OPEN",CONTINUOUS_ON_UNION_LOCAL_OPEN; +"CONTINUOUS_ON_UNION_OPEN",CONTINUOUS_ON_UNION_OPEN; +"CONTINUOUS_ON_VMUL",CONTINUOUS_ON_VMUL; +"CONTINUOUS_ON_VSUM",CONTINUOUS_ON_VSUM; +"CONTINUOUS_OPEN_IN_PREIMAGE",CONTINUOUS_OPEN_IN_PREIMAGE; +"CONTINUOUS_OPEN_IN_PREIMAGE_EQ",CONTINUOUS_OPEN_IN_PREIMAGE_EQ; +"CONTINUOUS_OPEN_IN_PREIMAGE_GEN",CONTINUOUS_OPEN_IN_PREIMAGE_GEN; +"CONTINUOUS_OPEN_PREIMAGE",CONTINUOUS_OPEN_PREIMAGE; +"CONTINUOUS_OPEN_PREIMAGE_UNIV",CONTINUOUS_OPEN_PREIMAGE_UNIV; +"CONTINUOUS_PASTECART",CONTINUOUS_PASTECART; +"CONTINUOUS_RIGHT_INVERSE_IMP_QUOTIENT_MAP",CONTINUOUS_RIGHT_INVERSE_IMP_QUOTIENT_MAP; +"CONTINUOUS_SUB",CONTINUOUS_SUB; +"CONTINUOUS_TRANSFORM_AT",CONTINUOUS_TRANSFORM_AT; +"CONTINUOUS_TRANSFORM_WITHIN",CONTINUOUS_TRANSFORM_WITHIN; +"CONTINUOUS_TRIVIAL_LIMIT",CONTINUOUS_TRIVIAL_LIMIT; +"CONTINUOUS_UNIFORM_LIMIT",CONTINUOUS_UNIFORM_LIMIT; +"CONTINUOUS_VMUL",CONTINUOUS_VMUL; +"CONTINUOUS_VSUM",CONTINUOUS_VSUM; +"CONTINUOUS_WITHIN",CONTINUOUS_WITHIN; +"CONTINUOUS_WITHIN_AVOID",CONTINUOUS_WITHIN_AVOID; +"CONTINUOUS_WITHIN_BALL",CONTINUOUS_WITHIN_BALL; +"CONTINUOUS_WITHIN_CLOSED_NONTRIVIAL",CONTINUOUS_WITHIN_CLOSED_NONTRIVIAL; +"CONTINUOUS_WITHIN_COMPOSE",CONTINUOUS_WITHIN_COMPOSE; +"CONTINUOUS_WITHIN_ID",CONTINUOUS_WITHIN_ID; +"CONTINUOUS_WITHIN_LIFT_SQRT",CONTINUOUS_WITHIN_LIFT_SQRT; +"CONTINUOUS_WITHIN_OPEN",CONTINUOUS_WITHIN_OPEN; +"CONTINUOUS_WITHIN_SEQUENTIALLY",CONTINUOUS_WITHIN_SEQUENTIALLY; +"CONTINUOUS_WITHIN_SQRT_COMPOSE",CONTINUOUS_WITHIN_SQRT_COMPOSE; +"CONTINUOUS_WITHIN_SUBSET",CONTINUOUS_WITHIN_SUBSET; +"CONTRACTIBLE_CONVEX_TWEAK_BOUNDARY_POINTS",CONTRACTIBLE_CONVEX_TWEAK_BOUNDARY_POINTS; +"CONTRACTIBLE_EMPTY",CONTRACTIBLE_EMPTY; +"CONTRACTIBLE_IMP_CONNECTED",CONTRACTIBLE_IMP_CONNECTED; +"CONTRACTIBLE_IMP_PATH_CONNECTED",CONTRACTIBLE_IMP_PATH_CONNECTED; +"CONTRACTIBLE_IMP_SIMPLY_CONNECTED",CONTRACTIBLE_IMP_SIMPLY_CONNECTED; +"CONTRACTIBLE_INJECTIVE_LINEAR_IMAGE",CONTRACTIBLE_INJECTIVE_LINEAR_IMAGE; +"CONTRACTIBLE_PCROSS",CONTRACTIBLE_PCROSS; +"CONTRACTIBLE_PCROSS_EQ",CONTRACTIBLE_PCROSS_EQ; +"CONTRACTIBLE_PUNCTURED_SPHERE",CONTRACTIBLE_PUNCTURED_SPHERE; +"CONTRACTIBLE_SING",CONTRACTIBLE_SING; +"CONTRACTIBLE_SPHERE",CONTRACTIBLE_SPHERE; +"CONTRACTIBLE_TRANSLATION",CONTRACTIBLE_TRANSLATION; +"CONTRACTIBLE_UNIV",CONTRACTIBLE_UNIV; +"CONTRACTION_IMP_CONTINUOUS_ON",CONTRACTION_IMP_CONTINUOUS_ON; +"CONTRAPOS_THM",CONTRAPOS_THM; +"CONVERGENT_BOUNDED_INCREASING",CONVERGENT_BOUNDED_INCREASING; +"CONVERGENT_BOUNDED_MONOTONE",CONVERGENT_BOUNDED_MONOTONE; +"CONVERGENT_EQ_CAUCHY",CONVERGENT_EQ_CAUCHY; +"CONVERGENT_IMP_BOUNDED",CONVERGENT_IMP_BOUNDED; +"CONVERGENT_IMP_CAUCHY",CONVERGENT_IMP_CAUCHY; +"CONVEX",CONVEX; +"CONVEX_ADD",CONVEX_ADD; +"CONVEX_AFFINITY",CONVEX_AFFINITY; +"CONVEX_ALT",CONVEX_ALT; +"CONVEX_AND_AFFINE_INTER_OPEN",CONVEX_AND_AFFINE_INTER_OPEN; +"CONVEX_BALL",CONVEX_BALL; +"CONVEX_BOUNDS_LEMMA",CONVEX_BOUNDS_LEMMA; +"CONVEX_CBALL",CONVEX_CBALL; +"CONVEX_CLOSED_CONTAINS_SAME_RAY",CONVEX_CLOSED_CONTAINS_SAME_RAY; +"CONVEX_CLOSURE",CONVEX_CLOSURE; +"CONVEX_CLOSURE_INTERIOR",CONVEX_CLOSURE_INTERIOR; +"CONVEX_CLOSURE_RELATIVE_INTERIOR",CONVEX_CLOSURE_RELATIVE_INTERIOR; +"CONVEX_CMUL",CONVEX_CMUL; +"CONVEX_CONE",CONVEX_CONE; +"CONVEX_CONE_CONTAINS_0",CONVEX_CONE_CONTAINS_0; +"CONVEX_CONE_CONVEX_CONE_HULL",CONVEX_CONE_CONVEX_CONE_HULL; +"CONVEX_CONE_HALFSPACE_GE",CONVEX_CONE_HALFSPACE_GE; +"CONVEX_CONE_HALFSPACE_LE",CONVEX_CONE_HALFSPACE_LE; +"CONVEX_CONE_HULL_ADD",CONVEX_CONE_HULL_ADD; +"CONVEX_CONE_HULL_CONTAINS_0",CONVEX_CONE_HULL_CONTAINS_0; +"CONVEX_CONE_HULL_CONVEX_HULL",CONVEX_CONE_HULL_CONVEX_HULL; +"CONVEX_CONE_HULL_CONVEX_HULL_NONEMPTY",CONVEX_CONE_HULL_CONVEX_HULL_NONEMPTY; +"CONVEX_CONE_HULL_EMPTY",CONVEX_CONE_HULL_EMPTY; +"CONVEX_CONE_HULL_LINEAR_IMAGE",CONVEX_CONE_HULL_LINEAR_IMAGE; +"CONVEX_CONE_HULL_MUL",CONVEX_CONE_HULL_MUL; +"CONVEX_CONE_HULL_NONEMPTY",CONVEX_CONE_HULL_NONEMPTY; +"CONVEX_CONE_HULL_SEPARATE",CONVEX_CONE_HULL_SEPARATE; +"CONVEX_CONE_HULL_SEPARATE_NONEMPTY",CONVEX_CONE_HULL_SEPARATE_NONEMPTY; +"CONVEX_CONE_HULL_UNION",CONVEX_CONE_HULL_UNION; +"CONVEX_CONE_INTERS",CONVEX_CONE_INTERS; +"CONVEX_CONE_LINEAR_IMAGE",CONVEX_CONE_LINEAR_IMAGE; +"CONVEX_CONE_LINEAR_IMAGE_EQ",CONVEX_CONE_LINEAR_IMAGE_EQ; +"CONVEX_CONE_NEGATIONS",CONVEX_CONE_NEGATIONS; +"CONVEX_CONE_PCROSS",CONVEX_CONE_PCROSS; +"CONVEX_CONE_PCROSS_EQ",CONVEX_CONE_PCROSS_EQ; +"CONVEX_CONE_SING",CONVEX_CONE_SING; +"CONVEX_CONE_SPAN",CONVEX_CONE_SPAN; +"CONVEX_CONE_SUMS",CONVEX_CONE_SUMS; +"CONVEX_CONIC_HULL",CONVEX_CONIC_HULL; +"CONVEX_CONNECTED",CONVEX_CONNECTED; +"CONVEX_CONNECTED_1",CONVEX_CONNECTED_1; +"CONVEX_CONNECTED_1_GEN",CONVEX_CONNECTED_1_GEN; +"CONVEX_CONTAINS_SEGMENT",CONVEX_CONTAINS_SEGMENT; +"CONVEX_CONTAINS_SEGMENT_EQ",CONVEX_CONTAINS_SEGMENT_EQ; +"CONVEX_CONTAINS_SEGMENT_IMP",CONVEX_CONTAINS_SEGMENT_IMP; +"CONVEX_CONVEX_CONE_HULL",CONVEX_CONVEX_CONE_HULL; +"CONVEX_CONVEX_HULL",CONVEX_CONVEX_HULL; +"CONVEX_DIFFERENCES",CONVEX_DIFFERENCES; +"CONVEX_DISTANCE",CONVEX_DISTANCE; +"CONVEX_EMPTY",CONVEX_EMPTY; +"CONVEX_EPIGRAPH",CONVEX_EPIGRAPH; +"CONVEX_EPIGRAPH_CONVEX",CONVEX_EPIGRAPH_CONVEX; +"CONVEX_EXPLICIT",CONVEX_EXPLICIT; +"CONVEX_FINITE",CONVEX_FINITE; +"CONVEX_HALFSPACE_COMPONENT_GE",CONVEX_HALFSPACE_COMPONENT_GE; +"CONVEX_HALFSPACE_COMPONENT_GT",CONVEX_HALFSPACE_COMPONENT_GT; +"CONVEX_HALFSPACE_COMPONENT_LE",CONVEX_HALFSPACE_COMPONENT_LE; +"CONVEX_HALFSPACE_COMPONENT_LT",CONVEX_HALFSPACE_COMPONENT_LT; +"CONVEX_HALFSPACE_GE",CONVEX_HALFSPACE_GE; +"CONVEX_HALFSPACE_GT",CONVEX_HALFSPACE_GT; +"CONVEX_HALFSPACE_INTERSECTION",CONVEX_HALFSPACE_INTERSECTION; +"CONVEX_HALFSPACE_LE",CONVEX_HALFSPACE_LE; +"CONVEX_HALFSPACE_LT",CONVEX_HALFSPACE_LT; +"CONVEX_HULLS_EQ",CONVEX_HULLS_EQ; +"CONVEX_HULL_2",CONVEX_HULL_2; +"CONVEX_HULL_2_ALT",CONVEX_HULL_2_ALT; +"CONVEX_HULL_3",CONVEX_HULL_3; +"CONVEX_HULL_3_ALT",CONVEX_HULL_3_ALT; +"CONVEX_HULL_AFFINITY",CONVEX_HULL_AFFINITY; +"CONVEX_HULL_CARATHEODORY",CONVEX_HULL_CARATHEODORY; +"CONVEX_HULL_CARATHEODORY_AFF_DIM",CONVEX_HULL_CARATHEODORY_AFF_DIM; +"CONVEX_HULL_EMPTY",CONVEX_HULL_EMPTY; +"CONVEX_HULL_EQ",CONVEX_HULL_EQ; +"CONVEX_HULL_EQ_EMPTY",CONVEX_HULL_EQ_EMPTY; +"CONVEX_HULL_EQ_SING",CONVEX_HULL_EQ_SING; +"CONVEX_HULL_EXCHANGE_INTER",CONVEX_HULL_EXCHANGE_INTER; +"CONVEX_HULL_EXCHANGE_UNION",CONVEX_HULL_EXCHANGE_UNION; +"CONVEX_HULL_EXPLICIT",CONVEX_HULL_EXPLICIT; +"CONVEX_HULL_FINITE",CONVEX_HULL_FINITE; +"CONVEX_HULL_FINITE_STEP",CONVEX_HULL_FINITE_STEP; +"CONVEX_HULL_INDEXED",CONVEX_HULL_INDEXED; +"CONVEX_HULL_INSERT",CONVEX_HULL_INSERT; +"CONVEX_HULL_INSERT_ALT",CONVEX_HULL_INSERT_ALT; +"CONVEX_HULL_INTER",CONVEX_HULL_INTER; +"CONVEX_HULL_INTERS",CONVEX_HULL_INTERS; +"CONVEX_HULL_LINEAR_IMAGE",CONVEX_HULL_LINEAR_IMAGE; +"CONVEX_HULL_PCROSS",CONVEX_HULL_PCROSS; +"CONVEX_HULL_SCALING",CONVEX_HULL_SCALING; +"CONVEX_HULL_SING",CONVEX_HULL_SING; +"CONVEX_HULL_SUBSET_AFFINE_HULL",CONVEX_HULL_SUBSET_AFFINE_HULL; +"CONVEX_HULL_SUBSET_CONVEX_CONE_HULL",CONVEX_HULL_SUBSET_CONVEX_CONE_HULL; +"CONVEX_HULL_SUBSET_SPAN",CONVEX_HULL_SUBSET_SPAN; +"CONVEX_HULL_SUMS",CONVEX_HULL_SUMS; +"CONVEX_HULL_TRANSLATION",CONVEX_HULL_TRANSLATION; +"CONVEX_HULL_UNION_EXPLICIT",CONVEX_HULL_UNION_EXPLICIT; +"CONVEX_HULL_UNION_NONEMPTY_EXPLICIT",CONVEX_HULL_UNION_NONEMPTY_EXPLICIT; +"CONVEX_HULL_UNION_UNIONS",CONVEX_HULL_UNION_UNIONS; +"CONVEX_HULL_UNIV",CONVEX_HULL_UNIV; +"CONVEX_HYPERPLANE",CONVEX_HYPERPLANE; +"CONVEX_IMP_CONTRACTIBLE",CONVEX_IMP_CONTRACTIBLE; +"CONVEX_IMP_LOCALLY_CONNECTED",CONVEX_IMP_LOCALLY_CONNECTED; +"CONVEX_IMP_LOCALLY_PATH_CONNECTED",CONVEX_IMP_LOCALLY_PATH_CONNECTED; +"CONVEX_IMP_PATH_CONNECTED",CONVEX_IMP_PATH_CONNECTED; +"CONVEX_IMP_SIMPLY_CONNECTED",CONVEX_IMP_SIMPLY_CONNECTED; +"CONVEX_IMP_STARLIKE",CONVEX_IMP_STARLIKE; +"CONVEX_INDEXED",CONVEX_INDEXED; +"CONVEX_INTER",CONVEX_INTER; +"CONVEX_INTERIOR",CONVEX_INTERIOR; +"CONVEX_INTERIOR_CLOSURE",CONVEX_INTERIOR_CLOSURE; +"CONVEX_INTERS",CONVEX_INTERS; +"CONVEX_INTERVAL",CONVEX_INTERVAL; +"CONVEX_LINEAR_IMAGE",CONVEX_LINEAR_IMAGE; +"CONVEX_LINEAR_IMAGE_EQ",CONVEX_LINEAR_IMAGE_EQ; +"CONVEX_LINEAR_PREIMAGE",CONVEX_LINEAR_PREIMAGE; +"CONVEX_LOCAL_GLOBAL_MINIMUM",CONVEX_LOCAL_GLOBAL_MINIMUM; +"CONVEX_LOWER",CONVEX_LOWER; +"CONVEX_LOWER_SEGMENT",CONVEX_LOWER_SEGMENT; +"CONVEX_MAX",CONVEX_MAX; +"CONVEX_NEGATIONS",CONVEX_NEGATIONS; +"CONVEX_NORM",CONVEX_NORM; +"CONVEX_ON_BOUNDED_CONTINUOUS",CONVEX_ON_BOUNDED_CONTINUOUS; +"CONVEX_ON_COMPOSE_LINEAR",CONVEX_ON_COMPOSE_LINEAR; +"CONVEX_ON_CONTINUOUS",CONVEX_ON_CONTINUOUS; +"CONVEX_ON_CONVEX_HULL_BOUND",CONVEX_ON_CONVEX_HULL_BOUND; +"CONVEX_ON_DERIVATIVES",CONVEX_ON_DERIVATIVES; +"CONVEX_ON_DERIVATIVES_IMP",CONVEX_ON_DERIVATIVES_IMP; +"CONVEX_ON_DERIVATIVE_SECANT",CONVEX_ON_DERIVATIVE_SECANT; +"CONVEX_ON_DERIVATIVE_SECANT_IMP",CONVEX_ON_DERIVATIVE_SECANT_IMP; +"CONVEX_ON_EPIGRAPH_SLICE_LE",CONVEX_ON_EPIGRAPH_SLICE_LE; +"CONVEX_ON_EPIGRAPH_SLICE_LT",CONVEX_ON_EPIGRAPH_SLICE_LT; +"CONVEX_ON_JENSEN",CONVEX_ON_JENSEN; +"CONVEX_ON_LEFT_SECANT",CONVEX_ON_LEFT_SECANT; +"CONVEX_ON_LEFT_SECANT_MUL",CONVEX_ON_LEFT_SECANT_MUL; +"CONVEX_ON_RIGHT_SECANT",CONVEX_ON_RIGHT_SECANT; +"CONVEX_ON_RIGHT_SECANT_MUL",CONVEX_ON_RIGHT_SECANT_MUL; +"CONVEX_ON_SECANT_DERIVATIVE",CONVEX_ON_SECANT_DERIVATIVE; +"CONVEX_ON_SECANT_DERIVATIVE_IMP",CONVEX_ON_SECANT_DERIVATIVE_IMP; +"CONVEX_ON_SUBSET",CONVEX_ON_SUBSET; +"CONVEX_ON_TRANSLATION",CONVEX_ON_TRANSLATION; +"CONVEX_PCROSS",CONVEX_PCROSS; +"CONVEX_PCROSS_EQ",CONVEX_PCROSS_EQ; +"CONVEX_POSITIVE_ORTHANT",CONVEX_POSITIVE_ORTHANT; +"CONVEX_RELATIVE_INTERIOR",CONVEX_RELATIVE_INTERIOR; +"CONVEX_RELATIVE_INTERIOR_CLOSURE",CONVEX_RELATIVE_INTERIOR_CLOSURE; +"CONVEX_SAME_RELATIVE_INTERIOR_CLOSURE",CONVEX_SAME_RELATIVE_INTERIOR_CLOSURE; +"CONVEX_SAME_RELATIVE_INTERIOR_CLOSURE_STRADDLE",CONVEX_SAME_RELATIVE_INTERIOR_CLOSURE_STRADDLE; +"CONVEX_SCALING",CONVEX_SCALING; +"CONVEX_SCALING_EQ",CONVEX_SCALING_EQ; +"CONVEX_SEGMENT",CONVEX_SEGMENT; +"CONVEX_SEMIOPEN_SEGMENT",CONVEX_SEMIOPEN_SEGMENT; +"CONVEX_SIMPLEX",CONVEX_SIMPLEX; +"CONVEX_SING",CONVEX_SING; +"CONVEX_SPAN",CONVEX_SPAN; +"CONVEX_STANDARD_HYPERPLANE",CONVEX_STANDARD_HYPERPLANE; +"CONVEX_SUMS",CONVEX_SUMS; +"CONVEX_TRANSLATION",CONVEX_TRANSLATION; +"CONVEX_TRANSLATION_EQ",CONVEX_TRANSLATION_EQ; +"CONVEX_UNIV",CONVEX_UNIV; +"CONVEX_VSUM",CONVEX_VSUM; +"CONVEX_VSUM_STRONG",CONVEX_VSUM_STRONG; +"COPLANAR_2",COPLANAR_2; +"COPLANAR_3",COPLANAR_3; +"COPLANAR_AFFINE_HULL_COPLANAR",COPLANAR_AFFINE_HULL_COPLANAR; +"COPLANAR_EMPTY",COPLANAR_EMPTY; +"COPLANAR_LINEAR_IMAGE",COPLANAR_LINEAR_IMAGE; +"COPLANAR_LINEAR_IMAGE_EQ",COPLANAR_LINEAR_IMAGE_EQ; +"COPLANAR_SING",COPLANAR_SING; +"COPLANAR_SMALL",COPLANAR_SMALL; +"COPLANAR_SUBSET",COPLANAR_SUBSET; +"COPLANAR_TRANSLATION",COPLANAR_TRANSLATION; +"COPLANAR_TRANSLATION_EQ",COPLANAR_TRANSLATION_EQ; +"COSMALL_APPROXIMATION",COSMALL_APPROXIMATION; +"COUNTABLE",COUNTABLE; +"COUNTABLE_ALT",COUNTABLE_ALT; +"COUNTABLE_AS_IMAGE",COUNTABLE_AS_IMAGE; +"COUNTABLE_AS_IMAGE_SUBSET",COUNTABLE_AS_IMAGE_SUBSET; +"COUNTABLE_AS_IMAGE_SUBSET_EQ",COUNTABLE_AS_IMAGE_SUBSET_EQ; +"COUNTABLE_AS_INJECTIVE_IMAGE",COUNTABLE_AS_INJECTIVE_IMAGE; +"COUNTABLE_CARD_MUL",COUNTABLE_CARD_MUL; +"COUNTABLE_CARD_MUL_EQ",COUNTABLE_CARD_MUL_EQ; +"COUNTABLE_CART",COUNTABLE_CART; +"COUNTABLE_CASES",COUNTABLE_CASES; +"COUNTABLE_COMPONENTS",COUNTABLE_COMPONENTS; +"COUNTABLE_CROSS",COUNTABLE_CROSS; +"COUNTABLE_DELETE",COUNTABLE_DELETE; +"COUNTABLE_DIFF_FINITE",COUNTABLE_DIFF_FINITE; +"COUNTABLE_DISJOINT_OPEN_SUBSETS",COUNTABLE_DISJOINT_OPEN_SUBSETS; +"COUNTABLE_ELEMENTARY_DIVISION",COUNTABLE_ELEMENTARY_DIVISION; +"COUNTABLE_EMPTY",COUNTABLE_EMPTY; +"COUNTABLE_EMPTY_INTERIOR",COUNTABLE_EMPTY_INTERIOR; +"COUNTABLE_FINITE_SUBSETS",COUNTABLE_FINITE_SUBSETS; +"COUNTABLE_IMAGE",COUNTABLE_IMAGE; +"COUNTABLE_IMAGE_INJ",COUNTABLE_IMAGE_INJ; +"COUNTABLE_IMAGE_INJ_EQ",COUNTABLE_IMAGE_INJ_EQ; +"COUNTABLE_IMAGE_INJ_GENERAL",COUNTABLE_IMAGE_INJ_GENERAL; +"COUNTABLE_IMP_CARD_LT_REAL",COUNTABLE_IMP_CARD_LT_REAL; +"COUNTABLE_IMP_DISCONNECTED",COUNTABLE_IMP_DISCONNECTED; +"COUNTABLE_INSERT",COUNTABLE_INSERT; +"COUNTABLE_INTEGER",COUNTABLE_INTEGER; +"COUNTABLE_INTEGER_COORDINATES",COUNTABLE_INTEGER_COORDINATES; +"COUNTABLE_INTER",COUNTABLE_INTER; +"COUNTABLE_LIST",COUNTABLE_LIST; +"COUNTABLE_LIST_GEN",COUNTABLE_LIST_GEN; +"COUNTABLE_NON_CONDENSATION_POINTS",COUNTABLE_NON_CONDENSATION_POINTS; +"COUNTABLE_OPEN_INTERVAL",COUNTABLE_OPEN_INTERVAL; +"COUNTABLE_PCROSS",COUNTABLE_PCROSS; +"COUNTABLE_PCROSS_EQ",COUNTABLE_PCROSS_EQ; +"COUNTABLE_PRODUCT_DEPENDENT",COUNTABLE_PRODUCT_DEPENDENT; +"COUNTABLE_RATIONAL",COUNTABLE_RATIONAL; +"COUNTABLE_RATIONAL_COORDINATES",COUNTABLE_RATIONAL_COORDINATES; +"COUNTABLE_RESTRICT",COUNTABLE_RESTRICT; +"COUNTABLE_SING",COUNTABLE_SING; +"COUNTABLE_SUBSET",COUNTABLE_SUBSET; +"COUNTABLE_SUBSET_IMAGE",COUNTABLE_SUBSET_IMAGE; +"COUNTABLE_UNION",COUNTABLE_UNION; +"COUNTABLE_UNIONS",COUNTABLE_UNIONS; +"COUNTABLE_UNION_IMP",COUNTABLE_UNION_IMP; +"COVERING_LEMMA",COVERING_LEMMA; +"COVERING_SPACE_CLOSED_MAP",COVERING_SPACE_CLOSED_MAP; +"COVERING_SPACE_COMPACT",COVERING_SPACE_COMPACT; +"COVERING_SPACE_COUNTABLE_SHEETS",COVERING_SPACE_COUNTABLE_SHEETS; +"COVERING_SPACE_FIBRE_NO_LIMPT",COVERING_SPACE_FIBRE_NO_LIMPT; +"COVERING_SPACE_FINITE_EQ_COMPACT_FIBRE",COVERING_SPACE_FINITE_EQ_COMPACT_FIBRE; +"COVERING_SPACE_FINITE_SHEETS",COVERING_SPACE_FINITE_SHEETS; +"COVERING_SPACE_FINITE_SHEETS_EQ_CLOSED_MAP",COVERING_SPACE_FINITE_SHEETS_EQ_CLOSED_MAP; +"COVERING_SPACE_FINITE_SHEETS_EQ_CLOSED_MAP_STRONG",COVERING_SPACE_FINITE_SHEETS_EQ_CLOSED_MAP_STRONG; +"COVERING_SPACE_FINITE_SHEETS_EQ_PROPER_MAP",COVERING_SPACE_FINITE_SHEETS_EQ_PROPER_MAP; +"COVERING_SPACE_HOMEOMORPHISM",COVERING_SPACE_HOMEOMORPHISM; +"COVERING_SPACE_IMP_CONTINUOUS",COVERING_SPACE_IMP_CONTINUOUS; +"COVERING_SPACE_IMP_SURJECTIVE",COVERING_SPACE_IMP_SURJECTIVE; +"COVERING_SPACE_INESSENTIAL_LOOP_LIFT_IS_LOOP",COVERING_SPACE_INESSENTIAL_LOOP_LIFT_IS_LOOP; +"COVERING_SPACE_INJECTIVE",COVERING_SPACE_INJECTIVE; +"COVERING_SPACE_LIFT",COVERING_SPACE_LIFT; +"COVERING_SPACE_LIFT_GENERAL",COVERING_SPACE_LIFT_GENERAL; +"COVERING_SPACE_LIFT_HOMOTOPIC_FUNCTION",COVERING_SPACE_LIFT_HOMOTOPIC_FUNCTION; +"COVERING_SPACE_LIFT_HOMOTOPIC_PATH",COVERING_SPACE_LIFT_HOMOTOPIC_PATH; +"COVERING_SPACE_LIFT_HOMOTOPIC_PATHS",COVERING_SPACE_LIFT_HOMOTOPIC_PATHS; +"COVERING_SPACE_LIFT_HOMOTOPY",COVERING_SPACE_LIFT_HOMOTOPY; +"COVERING_SPACE_LIFT_HOMOTOPY_ALT",COVERING_SPACE_LIFT_HOMOTOPY_ALT; +"COVERING_SPACE_LIFT_INESSENTIAL_FUNCTION",COVERING_SPACE_LIFT_INESSENTIAL_FUNCTION; +"COVERING_SPACE_LIFT_PATH",COVERING_SPACE_LIFT_PATH; +"COVERING_SPACE_LIFT_PATH_STRONG",COVERING_SPACE_LIFT_PATH_STRONG; +"COVERING_SPACE_LIFT_STRONG",COVERING_SPACE_LIFT_STRONG; +"COVERING_SPACE_LIFT_STRONGER",COVERING_SPACE_LIFT_STRONGER; +"COVERING_SPACE_LIFT_UNIQUE",COVERING_SPACE_LIFT_UNIQUE; +"COVERING_SPACE_LIFT_UNIQUE_GEN",COVERING_SPACE_LIFT_UNIQUE_GEN; +"COVERING_SPACE_LIFT_UNIQUE_IDENTITY",COVERING_SPACE_LIFT_UNIQUE_IDENTITY; +"COVERING_SPACE_LOCALLY",COVERING_SPACE_LOCALLY; +"COVERING_SPACE_LOCALLY_CONNECTED",COVERING_SPACE_LOCALLY_CONNECTED; +"COVERING_SPACE_LOCALLY_PATH_CONNECTED",COVERING_SPACE_LOCALLY_PATH_CONNECTED; +"COVERING_SPACE_LOCAL_HOMEOMORPHISM",COVERING_SPACE_LOCAL_HOMEOMORPHISM; +"COVERING_SPACE_LOCAL_HOMEOMORPHISM_ALT",COVERING_SPACE_LOCAL_HOMEOMORPHISM_ALT; +"COVERING_SPACE_MONODROMY",COVERING_SPACE_MONODROMY; +"COVERING_SPACE_OPEN_MAP",COVERING_SPACE_OPEN_MAP; +"COVERING_SPACE_QUOTIENT_MAP",COVERING_SPACE_QUOTIENT_MAP; +"COVERING_SPACE_SIMPLY_CONNECTED_LOOP_LIFT_IS_LOOP",COVERING_SPACE_SIMPLY_CONNECTED_LOOP_LIFT_IS_LOOP; +"CRAMER",CRAMER; +"CRAMER_LEMMA",CRAMER_LEMMA; +"CRAMER_LEMMA_TRANSP",CRAMER_LEMMA_TRANSP; +"CRAMER_MATRIX_LEFT",CRAMER_MATRIX_LEFT; +"CRAMER_MATRIX_LEFT_INVERSE",CRAMER_MATRIX_LEFT_INVERSE; +"CRAMER_MATRIX_RIGHT",CRAMER_MATRIX_RIGHT; +"CRAMER_MATRIX_RIGHT_INVERSE",CRAMER_MATRIX_RIGHT_INVERSE; +"CROSS",CROSS; +"CROSS_EQ_EMPTY",CROSS_EQ_EMPTY; +"CURRY_DEF",CURRY_DEF; +"DECIMAL",DECIMAL; +"DECOMPOSITION",DECOMPOSITION; +"DECREASING_BOUNDED_VARIATION",DECREASING_BOUNDED_VARIATION; +"DECREASING_CLOSED_NEST",DECREASING_CLOSED_NEST; +"DECREASING_CLOSED_NEST_SING",DECREASING_CLOSED_NEST_SING; +"DECREASING_LEFT_LIMIT_1",DECREASING_LEFT_LIMIT_1; +"DECREASING_RIGHT_LIMIT_1",DECREASING_RIGHT_LIMIT_1; +"DECREASING_VECTOR_VARIATION",DECREASING_VECTOR_VARIATION; +"DELETE",DELETE; +"DELETE_COMM",DELETE_COMM; +"DELETE_DELETE",DELETE_DELETE; +"DELETE_INSERT",DELETE_INSERT; +"DELETE_INTER",DELETE_INTER; +"DELETE_NON_ELEMENT",DELETE_NON_ELEMENT; +"DELETE_SUBSET",DELETE_SUBSET; +"DENSE_ACCESSIBLE_FRONTIER_POINTS",DENSE_ACCESSIBLE_FRONTIER_POINTS; +"DENSE_ACCESSIBLE_FRONTIER_POINTS_CONNECTED",DENSE_ACCESSIBLE_FRONTIER_POINTS_CONNECTED; +"DENSE_ACCESSIBLE_FRONTIER_POINT_PAIRS",DENSE_ACCESSIBLE_FRONTIER_POINT_PAIRS; +"DEPENDENT_2",DEPENDENT_2; +"DEPENDENT_3",DEPENDENT_3; +"DEPENDENT_AFFINE_DEPENDENT_CASES",DEPENDENT_AFFINE_DEPENDENT_CASES; +"DEPENDENT_BIGGERSET",DEPENDENT_BIGGERSET; +"DEPENDENT_BIGGERSET_GENERAL",DEPENDENT_BIGGERSET_GENERAL; +"DEPENDENT_EXPLICIT",DEPENDENT_EXPLICIT; +"DEPENDENT_FINITE",DEPENDENT_FINITE; +"DEPENDENT_IMP_AFFINE_DEPENDENT",DEPENDENT_IMP_AFFINE_DEPENDENT; +"DEPENDENT_LINEAR_IMAGE",DEPENDENT_LINEAR_IMAGE; +"DEPENDENT_LINEAR_IMAGE_EQ",DEPENDENT_LINEAR_IMAGE_EQ; +"DEPENDENT_MONO",DEPENDENT_MONO; +"DEPENDENT_SING",DEPENDENT_SING; +"DEST_MK_MULTIVECTOR",DEST_MK_MULTIVECTOR; +"DEST_REC_INJ",DEST_REC_INJ; +"DET_0",DET_0; +"DET_1",DET_1; +"DET_2",DET_2; +"DET_3",DET_3; +"DET_4",DET_4; +"DET_CMUL",DET_CMUL; +"DET_COFACTOR",DET_COFACTOR; +"DET_COFACTOR_EXPANSION",DET_COFACTOR_EXPANSION; +"DET_DEPENDENT_COLUMNS",DET_DEPENDENT_COLUMNS; +"DET_DEPENDENT_ROWS",DET_DEPENDENT_ROWS; +"DET_DIAGONAL",DET_DIAGONAL; +"DET_EQ_0",DET_EQ_0; +"DET_EQ_0_RANK",DET_EQ_0_RANK; +"DET_I",DET_I; +"DET_IDENTICAL_COLUMNS",DET_IDENTICAL_COLUMNS; +"DET_IDENTICAL_ROWS",DET_IDENTICAL_ROWS; +"DET_LINEAR_ROWS_VSUM",DET_LINEAR_ROWS_VSUM; +"DET_LINEAR_ROWS_VSUM_LEMMA",DET_LINEAR_ROWS_VSUM_LEMMA; +"DET_LINEAR_ROW_VSUM",DET_LINEAR_ROW_VSUM; +"DET_LOWERTRIANGULAR",DET_LOWERTRIANGULAR; +"DET_MATRIX_EQ_0",DET_MATRIX_EQ_0; +"DET_MATRIX_EQ_0_LEFT",DET_MATRIX_EQ_0_LEFT; +"DET_MATRIX_EQ_0_RIGHT",DET_MATRIX_EQ_0_RIGHT; +"DET_MATRIX_REFLECT_ALONG",DET_MATRIX_REFLECT_ALONG; +"DET_MUL",DET_MUL; +"DET_NEG",DET_NEG; +"DET_ORTHOGONAL_MATRIX",DET_ORTHOGONAL_MATRIX; +"DET_PERMUTE_COLUMNS",DET_PERMUTE_COLUMNS; +"DET_PERMUTE_ROWS",DET_PERMUTE_ROWS; +"DET_ROWS_MUL",DET_ROWS_MUL; +"DET_ROW_ADD",DET_ROW_ADD; +"DET_ROW_MUL",DET_ROW_MUL; +"DET_ROW_OPERATION",DET_ROW_OPERATION; +"DET_ROW_SPAN",DET_ROW_SPAN; +"DET_TRANSP",DET_TRANSP; +"DET_UPPERTRIANGULAR",DET_UPPERTRIANGULAR; +"DET_ZERO_COLUMN",DET_ZERO_COLUMN; +"DET_ZERO_ROW",DET_ZERO_ROW; +"DE_MORGAN_THM",DE_MORGAN_THM; +"DIAMETER_ATTAINED_FRONTIER",DIAMETER_ATTAINED_FRONTIER; +"DIAMETER_ATTAINED_RELATIVE_FRONTIER",DIAMETER_ATTAINED_RELATIVE_FRONTIER; +"DIAMETER_BALL",DIAMETER_BALL; +"DIAMETER_BOUNDED",DIAMETER_BOUNDED; +"DIAMETER_BOUNDED_BOUND",DIAMETER_BOUNDED_BOUND; +"DIAMETER_BOUNDED_BOUND_LT",DIAMETER_BOUNDED_BOUND_LT; +"DIAMETER_CBALL",DIAMETER_CBALL; +"DIAMETER_CLOSURE",DIAMETER_CLOSURE; +"DIAMETER_COMPACT_ATTAINED",DIAMETER_COMPACT_ATTAINED; +"DIAMETER_CONVEX_HULL",DIAMETER_CONVEX_HULL; +"DIAMETER_EMPTY",DIAMETER_EMPTY; +"DIAMETER_EQ_0",DIAMETER_EQ_0; +"DIAMETER_FRONTIER",DIAMETER_FRONTIER; +"DIAMETER_INTERVAL",DIAMETER_INTERVAL; +"DIAMETER_LE",DIAMETER_LE; +"DIAMETER_LINEAR_IMAGE",DIAMETER_LINEAR_IMAGE; +"DIAMETER_POS_LE",DIAMETER_POS_LE; +"DIAMETER_RELATIVE_FRONTIER",DIAMETER_RELATIVE_FRONTIER; +"DIAMETER_SIMPLEX",DIAMETER_SIMPLEX; +"DIAMETER_SING",DIAMETER_SING; +"DIAMETER_SPHERE",DIAMETER_SPHERE; +"DIAMETER_SUBSET",DIAMETER_SUBSET; +"DIAMETER_SUBSET_CBALL",DIAMETER_SUBSET_CBALL; +"DIAMETER_SUBSET_CBALL_NONEMPTY",DIAMETER_SUBSET_CBALL_NONEMPTY; +"DIAMETER_TRANSLATION",DIAMETER_TRANSLATION; +"DIFF",DIFF; +"DIFFERENTIABLE_ADD",DIFFERENTIABLE_ADD; +"DIFFERENTIABLE_AT_IMP_DIFFERENTIABLE_ON",DIFFERENTIABLE_AT_IMP_DIFFERENTIABLE_ON; +"DIFFERENTIABLE_AT_LIFT_DOT2",DIFFERENTIABLE_AT_LIFT_DOT2; +"DIFFERENTIABLE_AT_WITHIN",DIFFERENTIABLE_AT_WITHIN; +"DIFFERENTIABLE_BOUND",DIFFERENTIABLE_BOUND; +"DIFFERENTIABLE_CHAIN_AT",DIFFERENTIABLE_CHAIN_AT; +"DIFFERENTIABLE_CHAIN_WITHIN",DIFFERENTIABLE_CHAIN_WITHIN; +"DIFFERENTIABLE_CMUL",DIFFERENTIABLE_CMUL; +"DIFFERENTIABLE_COMPONENTWISE_AT",DIFFERENTIABLE_COMPONENTWISE_AT; +"DIFFERENTIABLE_COMPONENTWISE_WITHIN",DIFFERENTIABLE_COMPONENTWISE_WITHIN; +"DIFFERENTIABLE_CONST",DIFFERENTIABLE_CONST; +"DIFFERENTIABLE_ID",DIFFERENTIABLE_ID; +"DIFFERENTIABLE_IMP_CONTINUOUS_AT",DIFFERENTIABLE_IMP_CONTINUOUS_AT; +"DIFFERENTIABLE_IMP_CONTINUOUS_ON",DIFFERENTIABLE_IMP_CONTINUOUS_ON; +"DIFFERENTIABLE_IMP_CONTINUOUS_WITHIN",DIFFERENTIABLE_IMP_CONTINUOUS_WITHIN; +"DIFFERENTIABLE_LIFT_COMPONENT",DIFFERENTIABLE_LIFT_COMPONENT; +"DIFFERENTIABLE_LINEAR",DIFFERENTIABLE_LINEAR; +"DIFFERENTIABLE_MUL_AT",DIFFERENTIABLE_MUL_AT; +"DIFFERENTIABLE_MUL_WITHIN",DIFFERENTIABLE_MUL_WITHIN; +"DIFFERENTIABLE_NEG",DIFFERENTIABLE_NEG; +"DIFFERENTIABLE_ON_ADD",DIFFERENTIABLE_ON_ADD; +"DIFFERENTIABLE_ON_COMPOSE",DIFFERENTIABLE_ON_COMPOSE; +"DIFFERENTIABLE_ON_CONST",DIFFERENTIABLE_ON_CONST; +"DIFFERENTIABLE_ON_EMPTY",DIFFERENTIABLE_ON_EMPTY; +"DIFFERENTIABLE_ON_EQ_DIFFERENTIABLE_AT",DIFFERENTIABLE_ON_EQ_DIFFERENTIABLE_AT; +"DIFFERENTIABLE_ON_ID",DIFFERENTIABLE_ON_ID; +"DIFFERENTIABLE_ON_LIFT_DOT2",DIFFERENTIABLE_ON_LIFT_DOT2; +"DIFFERENTIABLE_ON_LINEAR",DIFFERENTIABLE_ON_LINEAR; +"DIFFERENTIABLE_ON_MUL",DIFFERENTIABLE_ON_MUL; +"DIFFERENTIABLE_ON_NEG",DIFFERENTIABLE_ON_NEG; +"DIFFERENTIABLE_ON_SQNORM",DIFFERENTIABLE_ON_SQNORM; +"DIFFERENTIABLE_ON_SUB",DIFFERENTIABLE_ON_SUB; +"DIFFERENTIABLE_ON_SUBSET",DIFFERENTIABLE_ON_SUBSET; +"DIFFERENTIABLE_SQNORM_AT",DIFFERENTIABLE_SQNORM_AT; +"DIFFERENTIABLE_SUB",DIFFERENTIABLE_SUB; +"DIFFERENTIABLE_TRANSFORM_AT",DIFFERENTIABLE_TRANSFORM_AT; +"DIFFERENTIABLE_TRANSFORM_WITHIN",DIFFERENTIABLE_TRANSFORM_WITHIN; +"DIFFERENTIABLE_VSUM",DIFFERENTIABLE_VSUM; +"DIFFERENTIABLE_VSUM_NUMSEG",DIFFERENTIABLE_VSUM_NUMSEG; +"DIFFERENTIABLE_WITHIN_LIFT_DOT2",DIFFERENTIABLE_WITHIN_LIFT_DOT2; +"DIFFERENTIABLE_WITHIN_OPEN",DIFFERENTIABLE_WITHIN_OPEN; +"DIFFERENTIABLE_WITHIN_SUBSET",DIFFERENTIABLE_WITHIN_SUBSET; +"DIFFERENTIAL_COMPONENT_NEG_AT_MAXIMUM",DIFFERENTIAL_COMPONENT_NEG_AT_MAXIMUM; +"DIFFERENTIAL_COMPONENT_POS_AT_MINIMUM",DIFFERENTIAL_COMPONENT_POS_AT_MINIMUM; +"DIFFERENTIAL_COMPONENT_ZERO_AT_MAXMIN",DIFFERENTIAL_COMPONENT_ZERO_AT_MAXMIN; +"DIFFERENTIAL_ZERO_MAXMIN",DIFFERENTIAL_ZERO_MAXMIN; +"DIFFERENTIAL_ZERO_MAXMIN_COMPONENT",DIFFERENTIAL_ZERO_MAXMIN_COMPONENT; +"DIFFERENT_NORM_3_COLLINEAR_POINTS",DIFFERENT_NORM_3_COLLINEAR_POINTS; +"DIFFS_AFFINE_HULL_SPAN",DIFFS_AFFINE_HULL_SPAN; +"DIFF_CHAIN_AT",DIFF_CHAIN_AT; +"DIFF_CHAIN_WITHIN",DIFF_CHAIN_WITHIN; +"DIFF_DIFF",DIFF_DIFF; +"DIFF_EMPTY",DIFF_EMPTY; +"DIFF_EQ_EMPTY",DIFF_EQ_EMPTY; +"DIFF_INSERT",DIFF_INSERT; +"DIFF_INTERS",DIFF_INTERS; +"DIFF_UNIONS",DIFF_UNIONS; +"DIFF_UNIONS_NONEMPTY",DIFF_UNIONS_NONEMPTY; +"DIFF_UNIV",DIFF_UNIV; +"DIMINDEX_1",DIMINDEX_1; +"DIMINDEX_2",DIMINDEX_2; +"DIMINDEX_3",DIMINDEX_3; +"DIMINDEX_4",DIMINDEX_4; +"DIMINDEX_FINITE_IMAGE",DIMINDEX_FINITE_IMAGE; +"DIMINDEX_FINITE_SUM",DIMINDEX_FINITE_SUM; +"DIMINDEX_GE_1",DIMINDEX_GE_1; +"DIMINDEX_HAS_SIZE_FINITE_SUM",DIMINDEX_HAS_SIZE_FINITE_SUM; +"DIMINDEX_MULTIVECTOR",DIMINDEX_MULTIVECTOR; +"DIMINDEX_NONZERO",DIMINDEX_NONZERO; +"DIMINDEX_UNIQUE",DIMINDEX_UNIQUE; +"DIMINDEX_UNIV",DIMINDEX_UNIV; +"DIM_CLOSURE",DIM_CLOSURE; +"DIM_EMPTY",DIM_EMPTY; +"DIM_EQ_0",DIM_EQ_0; +"DIM_EQ_CARD",DIM_EQ_CARD; +"DIM_EQ_FULL",DIM_EQ_FULL; +"DIM_EQ_HYPERPLANE",DIM_EQ_HYPERPLANE; +"DIM_EQ_SPAN",DIM_EQ_SPAN; +"DIM_HYPERPLANE",DIM_HYPERPLANE; +"DIM_IMAGE_KERNEL",DIM_IMAGE_KERNEL; +"DIM_IMAGE_KERNEL_GEN",DIM_IMAGE_KERNEL_GEN; +"DIM_INJECTIVE_LINEAR_IMAGE",DIM_INJECTIVE_LINEAR_IMAGE; +"DIM_INSERT",DIM_INSERT; +"DIM_INSERT_0",DIM_INSERT_0; +"DIM_KERNEL_COMPOSE",DIM_KERNEL_COMPOSE; +"DIM_LE_CARD",DIM_LE_CARD; +"DIM_LINEAR_IMAGE_LE",DIM_LINEAR_IMAGE_LE; +"DIM_OPEN",DIM_OPEN; +"DIM_OPEN_IN",DIM_OPEN_IN; +"DIM_ORTHOGONAL_SUM",DIM_ORTHOGONAL_SUM; +"DIM_PCROSS",DIM_PCROSS; +"DIM_PCROSS_STRONG",DIM_PCROSS_STRONG; +"DIM_PSUBSET",DIM_PSUBSET; +"DIM_ROWS_LE_DIM_COLUMNS",DIM_ROWS_LE_DIM_COLUMNS; +"DIM_SING",DIM_SING; +"DIM_SPAN",DIM_SPAN; +"DIM_SPECIAL_HYPERPLANE",DIM_SPECIAL_HYPERPLANE; +"DIM_SPECIAL_SUBSPACE",DIM_SPECIAL_SUBSPACE; +"DIM_SUBSET",DIM_SUBSET; +"DIM_SUBSET_UNIV",DIM_SUBSET_UNIV; +"DIM_SUBSPACE_ORTHOGONAL_TO_VECTORS",DIM_SUBSPACE_ORTHOGONAL_TO_VECTORS; +"DIM_SUBSTANDARD",DIM_SUBSTANDARD; +"DIM_SUMS_INTER",DIM_SUMS_INTER; +"DIM_UNIQUE",DIM_UNIQUE; +"DIM_UNIV",DIM_UNIV; +"DINI",DINI; +"DISCRETE_BOUNDED_IMP_FINITE",DISCRETE_BOUNDED_IMP_FINITE; +"DISCRETE_IMP_CLOSED",DISCRETE_IMP_CLOSED; +"DISCRETE_IMP_COUNTABLE",DISCRETE_IMP_COUNTABLE; +"DISJOINT",DISJOINT; +"DISJOINT_AFFINE_HULL",DISJOINT_AFFINE_HULL; +"DISJOINT_DELETE_SYM",DISJOINT_DELETE_SYM; +"DISJOINT_EMPTY",DISJOINT_EMPTY; +"DISJOINT_EMPTY_REFL",DISJOINT_EMPTY_REFL; +"DISJOINT_INSERT",DISJOINT_INSERT; +"DISJOINT_INTERVAL",DISJOINT_INTERVAL; +"DISJOINT_INTERVAL_1",DISJOINT_INTERVAL_1; +"DISJOINT_NUMSEG",DISJOINT_NUMSEG; +"DISJOINT_SYM",DISJOINT_SYM; +"DISJOINT_UNION",DISJOINT_UNION; +"DISJ_ACI",DISJ_ACI; +"DISJ_ASSOC",DISJ_ASSOC; +"DISJ_SYM",DISJ_SYM; +"DISTANCE_ATTAINS_INF",DISTANCE_ATTAINS_INF; +"DISTANCE_ATTAINS_SUP",DISTANCE_ATTAINS_SUP; +"DIST_0",DIST_0; +"DIST_ADD2",DIST_ADD2; +"DIST_ADD2_REV",DIST_ADD2_REV; +"DIST_ADDBOUND",DIST_ADDBOUND; +"DIST_CLOSEST_POINT_LIPSCHITZ",DIST_CLOSEST_POINT_LIPSCHITZ; +"DIST_ELIM_THM",DIST_ELIM_THM; +"DIST_EQ",DIST_EQ; +"DIST_EQ_0",DIST_EQ_0; +"DIST_FSTCART",DIST_FSTCART; +"DIST_INCREASES_ONLINE",DIST_INCREASES_ONLINE; +"DIST_IN_CLOSED_SEGMENT",DIST_IN_CLOSED_SEGMENT; +"DIST_IN_OPEN_SEGMENT",DIST_IN_OPEN_SEGMENT; +"DIST_LADD",DIST_LADD; +"DIST_LADD_0",DIST_LADD_0; +"DIST_LE_0",DIST_LE_0; +"DIST_LE_CASES",DIST_LE_CASES; +"DIST_LIFT",DIST_LIFT; +"DIST_LMUL",DIST_LMUL; +"DIST_LZERO",DIST_LZERO; +"DIST_MIDPOINT",DIST_MIDPOINT; +"DIST_MUL",DIST_MUL; +"DIST_NZ",DIST_NZ; +"DIST_PASTECART_CANCEL",DIST_PASTECART_CANCEL; +"DIST_POS_LE",DIST_POS_LE; +"DIST_POS_LT",DIST_POS_LT; +"DIST_RADD",DIST_RADD; +"DIST_RADD_0",DIST_RADD_0; +"DIST_REAL",DIST_REAL; +"DIST_REFL",DIST_REFL; +"DIST_RMUL",DIST_RMUL; +"DIST_RZERO",DIST_RZERO; +"DIST_SNDCART",DIST_SNDCART; +"DIST_SYM",DIST_SYM; +"DIST_TRIANGLE",DIST_TRIANGLE; +"DIST_TRIANGLES_LE",DIST_TRIANGLES_LE; +"DIST_TRIANGLE_ADD",DIST_TRIANGLE_ADD; +"DIST_TRIANGLE_ADD_HALF",DIST_TRIANGLE_ADD_HALF; +"DIST_TRIANGLE_ALT",DIST_TRIANGLE_ALT; +"DIST_TRIANGLE_EQ",DIST_TRIANGLE_EQ; +"DIST_TRIANGLE_HALF_L",DIST_TRIANGLE_HALF_L; +"DIST_TRIANGLE_HALF_R",DIST_TRIANGLE_HALF_R; +"DIST_TRIANGLE_LE",DIST_TRIANGLE_LE; +"DIST_TRIANGLE_LT",DIST_TRIANGLE_LT; +"DIVISION",DIVISION; +"DIVISION_0",DIVISION_0; +"DIVISION_COMMON_POINT_BOUND",DIVISION_COMMON_POINT_BOUND; +"DIVISION_CONTAINS",DIVISION_CONTAINS; +"DIVISION_DISJOINT_UNION",DIVISION_DISJOINT_UNION; +"DIVISION_DOUBLESPLIT",DIVISION_DOUBLESPLIT; +"DIVISION_INTER",DIVISION_INTER; +"DIVISION_INTER_1",DIVISION_INTER_1; +"DIVISION_OF",DIVISION_OF; +"DIVISION_OF_AFFINITY",DIVISION_OF_AFFINITY; +"DIVISION_OF_CLOSED",DIVISION_OF_CLOSED; +"DIVISION_OF_CONTENT_0",DIVISION_OF_CONTENT_0; +"DIVISION_OF_FINITE",DIVISION_OF_FINITE; +"DIVISION_OF_NONTRIVIAL",DIVISION_OF_NONTRIVIAL; +"DIVISION_OF_REFLECT",DIVISION_OF_REFLECT; +"DIVISION_OF_SELF",DIVISION_OF_SELF; +"DIVISION_OF_SING",DIVISION_OF_SING; +"DIVISION_OF_SUBSET",DIVISION_OF_SUBSET; +"DIVISION_OF_TAGGED_DIVISION",DIVISION_OF_TAGGED_DIVISION; +"DIVISION_OF_TRANSLATION",DIVISION_OF_TRANSLATION; +"DIVISION_OF_TRIVIAL",DIVISION_OF_TRIVIAL; +"DIVISION_OF_UNIONS",DIVISION_OF_UNIONS; +"DIVISION_OF_UNION_SELF",DIVISION_OF_UNION_SELF; +"DIVISION_POINTS_FINITE",DIVISION_POINTS_FINITE; +"DIVISION_POINTS_PSUBSET",DIVISION_POINTS_PSUBSET; +"DIVISION_POINTS_SUBSET",DIVISION_POINTS_SUBSET; +"DIVISION_SIMP",DIVISION_SIMP; +"DIVISION_SPLIT",DIVISION_SPLIT; +"DIVISION_SPLIT_LEFT_INJ",DIVISION_SPLIT_LEFT_INJ; +"DIVISION_SPLIT_RIGHT_INJ",DIVISION_SPLIT_RIGHT_INJ; +"DIVISION_UNION_INTERVALS_EXISTS",DIVISION_UNION_INTERVALS_EXISTS; +"DIVMOD_ELIM_THM",DIVMOD_ELIM_THM; +"DIVMOD_ELIM_THM'",DIVMOD_ELIM_THM'; +"DIVMOD_EXIST",DIVMOD_EXIST; +"DIVMOD_EXIST_0",DIVMOD_EXIST_0; +"DIVMOD_UNIQ",DIVMOD_UNIQ; +"DIVMOD_UNIQ_LEMMA",DIVMOD_UNIQ_LEMMA; +"DIV_0",DIV_0; +"DIV_1",DIV_1; +"DIV_ADD_MOD",DIV_ADD_MOD; +"DIV_DIV",DIV_DIV; +"DIV_EQ_0",DIV_EQ_0; +"DIV_EQ_EXCLUSION",DIV_EQ_EXCLUSION; +"DIV_LE",DIV_LE; +"DIV_LE_EXCLUSION",DIV_LE_EXCLUSION; +"DIV_LT",DIV_LT; +"DIV_MOD",DIV_MOD; +"DIV_MONO",DIV_MONO; +"DIV_MONO2",DIV_MONO2; +"DIV_MONO_LT",DIV_MONO_LT; +"DIV_MULT",DIV_MULT; +"DIV_MULT2",DIV_MULT2; +"DIV_MULT_ADD",DIV_MULT_ADD; +"DIV_MUL_LE",DIV_MUL_LE; +"DIV_REFL",DIV_REFL; +"DIV_UNIQ",DIV_UNIQ; +"DOMINATED_CONVERGENCE",DOMINATED_CONVERGENCE; +"DOMINATED_CONVERGENCE_ABSOLUTELY_INTEGRABLE",DOMINATED_CONVERGENCE_ABSOLUTELY_INTEGRABLE; +"DOMINATED_CONVERGENCE_INTEGRABLE",DOMINATED_CONVERGENCE_INTEGRABLE; +"DOT_1",DOT_1; +"DOT_2",DOT_2; +"DOT_3",DOT_3; +"DOT_4",DOT_4; +"DOT_BASIS",DOT_BASIS; +"DOT_BASIS_BASIS",DOT_BASIS_BASIS; +"DOT_BASIS_BASIS_UNEQUAL",DOT_BASIS_BASIS_UNEQUAL; +"DOT_CAUCHY_SCHWARZ_EQUAL",DOT_CAUCHY_SCHWARZ_EQUAL; +"DOT_EQ_0",DOT_EQ_0; +"DOT_LADD",DOT_LADD; +"DOT_LMUL",DOT_LMUL; +"DOT_LMUL_MATRIX",DOT_LMUL_MATRIX; +"DOT_LNEG",DOT_LNEG; +"DOT_LSUB",DOT_LSUB; +"DOT_LSUM",DOT_LSUM; +"DOT_LZERO",DOT_LZERO; +"DOT_MATRIX_PRODUCT",DOT_MATRIX_PRODUCT; +"DOT_MATRIX_VECTOR_MUL",DOT_MATRIX_VECTOR_MUL; +"DOT_NORM",DOT_NORM; +"DOT_NORM_NEG",DOT_NORM_NEG; +"DOT_NORM_SUB",DOT_NORM_SUB; +"DOT_PASTECART",DOT_PASTECART; +"DOT_POS_LE",DOT_POS_LE; +"DOT_POS_LT",DOT_POS_LT; +"DOT_RADD",DOT_RADD; +"DOT_RMUL",DOT_RMUL; +"DOT_RNEG",DOT_RNEG; +"DOT_ROWVECTOR_COLUMNVECTOR",DOT_ROWVECTOR_COLUMNVECTOR; +"DOT_RSUB",DOT_RSUB; +"DOT_RSUM",DOT_RSUM; +"DOT_RZERO",DOT_RZERO; +"DOT_SQUARE_NORM",DOT_SQUARE_NORM; +"DOT_SYM",DOT_SYM; +"DROP_ADD",DROP_ADD; +"DROP_CMUL",DROP_CMUL; +"DROP_DIFFERENTIAL_NEG_AT_MAXIMUM",DROP_DIFFERENTIAL_NEG_AT_MAXIMUM; +"DROP_DIFFERENTIAL_POS_AT_MINIMUM",DROP_DIFFERENTIAL_POS_AT_MINIMUM; +"DROP_EQ",DROP_EQ; +"DROP_EQ_0",DROP_EQ_0; +"DROP_INDICATOR",DROP_INDICATOR; +"DROP_INDICATOR_ABS_LE_1",DROP_INDICATOR_ABS_LE_1; +"DROP_INDICATOR_LE_1",DROP_INDICATOR_LE_1; +"DROP_INDICATOR_POS_LE",DROP_INDICATOR_POS_LE; +"DROP_IN_IMAGE_DROP",DROP_IN_IMAGE_DROP; +"DROP_LAMBDA",DROP_LAMBDA; +"DROP_NEG",DROP_NEG; +"DROP_SUB",DROP_SUB; +"DROP_VEC",DROP_VEC; +"DROP_VSUM",DROP_VSUM; +"DROP_WLOG_LE",DROP_WLOG_LE; +"DSUM_BOUND",DSUM_BOUND; +"EDELSTEIN_FIX",EDELSTEIN_FIX; +"EDGE_OF_IMP_SUBSET",EDGE_OF_IMP_SUBSET; +"EDGE_OF_LINEAR_IMAGE",EDGE_OF_LINEAR_IMAGE; +"EDGE_OF_TRANSLATION_EQ",EDGE_OF_TRANSLATION_EQ; +"EL",EL; +"ELEMENTARY_BOUNDED",ELEMENTARY_BOUNDED; +"ELEMENTARY_COMPACT",ELEMENTARY_COMPACT; +"ELEMENTARY_EMPTY",ELEMENTARY_EMPTY; +"ELEMENTARY_INTER",ELEMENTARY_INTER; +"ELEMENTARY_INTERS",ELEMENTARY_INTERS; +"ELEMENTARY_INTERVAL",ELEMENTARY_INTERVAL; +"ELEMENTARY_SUBSET_INTERVAL",ELEMENTARY_SUBSET_INTERVAL; +"ELEMENTARY_UNION",ELEMENTARY_UNION; +"ELEMENTARY_UNIONS_INTERVALS",ELEMENTARY_UNIONS_INTERVALS; +"ELEMENTARY_UNION_INTERVAL",ELEMENTARY_UNION_INTERVAL; +"ELEMENTARY_UNION_INTERVAL_STRONG",ELEMENTARY_UNION_INTERVAL_STRONG; +"EL_APPEND",EL_APPEND; +"EL_CONS",EL_CONS; +"EL_MAP",EL_MAP; +"EL_TL",EL_TL; +"EMPTY",EMPTY; +"EMPTY_AS_INTERVAL",EMPTY_AS_INTERVAL; +"EMPTY_DELETE",EMPTY_DELETE; +"EMPTY_DIFF",EMPTY_DIFF; +"EMPTY_DIVISION_OF",EMPTY_DIVISION_OF; +"EMPTY_EXPOSED_FACE_OF",EMPTY_EXPOSED_FACE_OF; +"EMPTY_FACE_OF",EMPTY_FACE_OF; +"EMPTY_GSPEC",EMPTY_GSPEC; +"EMPTY_INTERIOR_AFFINE_HULL",EMPTY_INTERIOR_AFFINE_HULL; +"EMPTY_INTERIOR_CONVEX_HULL",EMPTY_INTERIOR_CONVEX_HULL; +"EMPTY_INTERIOR_FINITE",EMPTY_INTERIOR_FINITE; +"EMPTY_INTERIOR_LOWDIM",EMPTY_INTERIOR_LOWDIM; +"EMPTY_INTERIOR_SUBSET_HYPERPLANE",EMPTY_INTERIOR_SUBSET_HYPERPLANE; +"EMPTY_NOT_UNIV",EMPTY_NOT_UNIV; +"EMPTY_SUBSET",EMPTY_SUBSET; +"EMPTY_UNION",EMPTY_UNION; +"EMPTY_UNIONS",EMPTY_UNIONS; +"ENDPOINTS_SHIFTPATH",ENDPOINTS_SHIFTPATH; +"ENDS_IN_INTERVAL",ENDS_IN_INTERVAL; +"ENDS_IN_SEGMENT",ENDS_IN_SEGMENT; +"ENDS_IN_UNIT_INTERVAL",ENDS_IN_UNIT_INTERVAL; +"ENDS_NOT_IN_SEGMENT",ENDS_NOT_IN_SEGMENT; +"EPSILON_DELTA_MINIMAL",EPSILON_DELTA_MINIMAL; +"EQUIINTEGRABLE_ADD",EQUIINTEGRABLE_ADD; +"EQUIINTEGRABLE_CLOSED_INTERVAL_RESTRICTIONS",EQUIINTEGRABLE_CLOSED_INTERVAL_RESTRICTIONS; +"EQUIINTEGRABLE_CMUL",EQUIINTEGRABLE_CMUL; +"EQUIINTEGRABLE_DIVISION",EQUIINTEGRABLE_DIVISION; +"EQUIINTEGRABLE_EQ",EQUIINTEGRABLE_EQ; +"EQUIINTEGRABLE_HALFSPACE_RESTRICTIONS_GE",EQUIINTEGRABLE_HALFSPACE_RESTRICTIONS_GE; +"EQUIINTEGRABLE_HALFSPACE_RESTRICTIONS_GT",EQUIINTEGRABLE_HALFSPACE_RESTRICTIONS_GT; +"EQUIINTEGRABLE_HALFSPACE_RESTRICTIONS_LE",EQUIINTEGRABLE_HALFSPACE_RESTRICTIONS_LE; +"EQUIINTEGRABLE_HALFSPACE_RESTRICTIONS_LT",EQUIINTEGRABLE_HALFSPACE_RESTRICTIONS_LT; +"EQUIINTEGRABLE_LIMIT",EQUIINTEGRABLE_LIMIT; +"EQUIINTEGRABLE_NEG",EQUIINTEGRABLE_NEG; +"EQUIINTEGRABLE_ON_NULL",EQUIINTEGRABLE_ON_NULL; +"EQUIINTEGRABLE_ON_SING",EQUIINTEGRABLE_ON_SING; +"EQUIINTEGRABLE_ON_SPLIT",EQUIINTEGRABLE_ON_SPLIT; +"EQUIINTEGRABLE_OPEN_INTERVAL_RESTRICTIONS",EQUIINTEGRABLE_OPEN_INTERVAL_RESTRICTIONS; +"EQUIINTEGRABLE_REFLECT",EQUIINTEGRABLE_REFLECT; +"EQUIINTEGRABLE_SUB",EQUIINTEGRABLE_SUB; +"EQUIINTEGRABLE_SUBSET",EQUIINTEGRABLE_SUBSET; +"EQUIINTEGRABLE_SUM",EQUIINTEGRABLE_SUM; +"EQUIINTEGRABLE_UNIFORM_LIMIT",EQUIINTEGRABLE_UNIFORM_LIMIT; +"EQUIINTEGRABLE_UNION",EQUIINTEGRABLE_UNION; +"EQ_ADD_LCANCEL",EQ_ADD_LCANCEL; +"EQ_ADD_LCANCEL_0",EQ_ADD_LCANCEL_0; +"EQ_ADD_RCANCEL",EQ_ADD_RCANCEL; +"EQ_ADD_RCANCEL_0",EQ_ADD_RCANCEL_0; +"EQ_BALLS",EQ_BALLS; +"EQ_C",EQ_C; +"EQ_CLAUSES",EQ_CLAUSES; +"EQ_C_BIJECTIONS",EQ_C_BIJECTIONS; +"EQ_EXP",EQ_EXP; +"EQ_EXT",EQ_EXT; +"EQ_IMP",EQ_IMP; +"EQ_IMP_LE",EQ_IMP_LE; +"EQ_INTERVAL",EQ_INTERVAL; +"EQ_INTERVAL_1",EQ_INTERVAL_1; +"EQ_MULT_LCANCEL",EQ_MULT_LCANCEL; +"EQ_MULT_RCANCEL",EQ_MULT_RCANCEL; +"EQ_REFL",EQ_REFL; +"EQ_SPAN_INSERT_EQ",EQ_SPAN_INSERT_EQ; +"EQ_SYM",EQ_SYM; +"EQ_SYM_EQ",EQ_SYM_EQ; +"EQ_TRANS",EQ_TRANS; +"EQ_UNIV",EQ_UNIV; +"ETA_AX",ETA_AX; +"EUCLIDEAN_SPACE_INFINITE",EUCLIDEAN_SPACE_INFINITE; +"EULER_ROTATION_THEOREM",EULER_ROTATION_THEOREM; +"EULER_ROTOINVERSION_THEOREM",EULER_ROTOINVERSION_THEOREM; +"EVEN",EVEN; +"EVENPERM_COMPOSE",EVENPERM_COMPOSE; +"EVENPERM_I",EVENPERM_I; +"EVENPERM_INVERSE",EVENPERM_INVERSE; +"EVENPERM_SWAP",EVENPERM_SWAP; +"EVENPERM_UNIQUE",EVENPERM_UNIQUE; +"EVENTUALLY_AND",EVENTUALLY_AND; +"EVENTUALLY_AT",EVENTUALLY_AT; +"EVENTUALLY_AT_INFINITY",EVENTUALLY_AT_INFINITY; +"EVENTUALLY_FALSE",EVENTUALLY_FALSE; +"EVENTUALLY_FORALL",EVENTUALLY_FORALL; +"EVENTUALLY_HAPPENS",EVENTUALLY_HAPPENS; +"EVENTUALLY_MONO",EVENTUALLY_MONO; +"EVENTUALLY_MP",EVENTUALLY_MP; +"EVENTUALLY_SEQUENTIALLY",EVENTUALLY_SEQUENTIALLY; +"EVENTUALLY_TRUE",EVENTUALLY_TRUE; +"EVENTUALLY_WITHIN",EVENTUALLY_WITHIN; +"EVENTUALLY_WITHIN_INTERIOR",EVENTUALLY_WITHIN_INTERIOR; +"EVENTUALLY_WITHIN_LE",EVENTUALLY_WITHIN_LE; +"EVEN_ADD",EVEN_ADD; +"EVEN_AND_ODD",EVEN_AND_ODD; +"EVEN_DOUBLE",EVEN_DOUBLE; +"EVEN_EXISTS",EVEN_EXISTS; +"EVEN_EXISTS_LEMMA",EVEN_EXISTS_LEMMA; +"EVEN_EXP",EVEN_EXP; +"EVEN_MOD",EVEN_MOD; +"EVEN_MULT",EVEN_MULT; +"EVEN_NSUM",EVEN_NSUM; +"EVEN_ODD_DECOMPOSITION",EVEN_ODD_DECOMPOSITION; +"EVEN_OR_ODD",EVEN_OR_ODD; +"EVEN_SUB",EVEN_SUB; +"EX",EX; +"EXCHANGE_LEMMA",EXCHANGE_LEMMA; +"EXCLUDED_MIDDLE",EXCLUDED_MIDDLE; +"EXISTS_ARC_PSUBSET_SIMPLE_PATH",EXISTS_ARC_PSUBSET_SIMPLE_PATH; +"EXISTS_BOOL_THM",EXISTS_BOOL_THM; +"EXISTS_COUNTABLE_SUBSET_IMAGE",EXISTS_COUNTABLE_SUBSET_IMAGE; +"EXISTS_CURRY",EXISTS_CURRY; +"EXISTS_DEF",EXISTS_DEF; +"EXISTS_DIFF",EXISTS_DIFF; +"EXISTS_DOUBLE_ARC",EXISTS_DOUBLE_ARC; +"EXISTS_DROP",EXISTS_DROP; +"EXISTS_DROP_FUN",EXISTS_DROP_FUN; +"EXISTS_DROP_IMAGE",EXISTS_DROP_IMAGE; +"EXISTS_EX",EXISTS_EX; +"EXISTS_FINITE_SUBSET_IMAGE",EXISTS_FINITE_SUBSET_IMAGE; +"EXISTS_IN_CLAUSES",EXISTS_IN_CLAUSES; +"EXISTS_IN_GSPEC",EXISTS_IN_GSPEC; +"EXISTS_IN_IMAGE",EXISTS_IN_IMAGE; +"EXISTS_IN_INSERT",EXISTS_IN_INSERT; +"EXISTS_IN_PCROSS",EXISTS_IN_PCROSS; +"EXISTS_IN_UNIONS",EXISTS_IN_UNIONS; +"EXISTS_LIFT",EXISTS_LIFT; +"EXISTS_LIFT_FUN",EXISTS_LIFT_FUN; +"EXISTS_LIFT_IMAGE",EXISTS_LIFT_IMAGE; +"EXISTS_NOT_THM",EXISTS_NOT_THM; +"EXISTS_ONE_REP",EXISTS_ONE_REP; +"EXISTS_OPTION",EXISTS_OPTION; +"EXISTS_OR_THM",EXISTS_OR_THM; +"EXISTS_PAIRED_THM",EXISTS_PAIRED_THM; +"EXISTS_PAIR_THM",EXISTS_PAIR_THM; +"EXISTS_PASTECART",EXISTS_PASTECART; +"EXISTS_PATH_SUBPATH_TO_FRONTIER",EXISTS_PATH_SUBPATH_TO_FRONTIER; +"EXISTS_PATH_SUBPATH_TO_FRONTIER_CLOSED",EXISTS_PATH_SUBPATH_TO_FRONTIER_CLOSED; +"EXISTS_REFL",EXISTS_REFL; +"EXISTS_SIMP",EXISTS_SIMP; +"EXISTS_SUBARC_OF_ARC_NOENDS",EXISTS_SUBARC_OF_ARC_NOENDS; +"EXISTS_SUBPATH_OF_ARC_NOENDS",EXISTS_SUBPATH_OF_ARC_NOENDS; +"EXISTS_SUBPATH_OF_PATH",EXISTS_SUBPATH_OF_PATH; +"EXISTS_SUBSET_IMAGE",EXISTS_SUBSET_IMAGE; +"EXISTS_SUBSET_UNION",EXISTS_SUBSET_UNION; +"EXISTS_SUM_THM",EXISTS_SUM_THM; +"EXISTS_SWAP",EXISTS_SWAP; +"EXISTS_THM",EXISTS_THM; +"EXISTS_TRIPLED_THM",EXISTS_TRIPLED_THM; +"EXISTS_UNCURRY",EXISTS_UNCURRY; +"EXISTS_UNIQUE",EXISTS_UNIQUE; +"EXISTS_UNIQUE_ALT",EXISTS_UNIQUE_ALT; +"EXISTS_UNIQUE_DEF",EXISTS_UNIQUE_DEF; +"EXISTS_UNIQUE_REFL",EXISTS_UNIQUE_REFL; +"EXISTS_UNIQUE_THM",EXISTS_UNIQUE_THM; +"EXISTS_VECTOR_1",EXISTS_VECTOR_1; +"EXISTS_VECTOR_2",EXISTS_VECTOR_2; +"EXISTS_VECTOR_3",EXISTS_VECTOR_3; +"EXISTS_VECTOR_4",EXISTS_VECTOR_4; +"EXP",EXP; +"EXPAND_CLOSED_OPEN_INTERVAL",EXPAND_CLOSED_OPEN_INTERVAL; +"EXPLICIT_SUBSET_INTERIOR_CONVEX_HULL",EXPLICIT_SUBSET_INTERIOR_CONVEX_HULL; +"EXPLICIT_SUBSET_INTERIOR_CONVEX_HULL_MINIMAL",EXPLICIT_SUBSET_INTERIOR_CONVEX_HULL_MINIMAL; +"EXPLICIT_SUBSET_RELATIVE_INTERIOR_CONVEX_HULL",EXPLICIT_SUBSET_RELATIVE_INTERIOR_CONVEX_HULL; +"EXPLICIT_SUBSET_RELATIVE_INTERIOR_CONVEX_HULL_MINIMAL",EXPLICIT_SUBSET_RELATIVE_INTERIOR_CONVEX_HULL_MINIMAL; +"EXPOSED_FACE_OF",EXPOSED_FACE_OF; +"EXPOSED_FACE_OF_INTER",EXPOSED_FACE_OF_INTER; +"EXPOSED_FACE_OF_INTERS",EXPOSED_FACE_OF_INTERS; +"EXPOSED_FACE_OF_INTER_SUPPORTING_HYPERPLANE_GE",EXPOSED_FACE_OF_INTER_SUPPORTING_HYPERPLANE_GE; +"EXPOSED_FACE_OF_INTER_SUPPORTING_HYPERPLANE_LE",EXPOSED_FACE_OF_INTER_SUPPORTING_HYPERPLANE_LE; +"EXPOSED_FACE_OF_LINEAR_IMAGE",EXPOSED_FACE_OF_LINEAR_IMAGE; +"EXPOSED_FACE_OF_PARALLEL",EXPOSED_FACE_OF_PARALLEL; +"EXPOSED_FACE_OF_POLYHEDRON",EXPOSED_FACE_OF_POLYHEDRON; +"EXPOSED_FACE_OF_REFL",EXPOSED_FACE_OF_REFL; +"EXPOSED_FACE_OF_REFL_EQ",EXPOSED_FACE_OF_REFL_EQ; +"EXPOSED_FACE_OF_SUMS",EXPOSED_FACE_OF_SUMS; +"EXPOSED_FACE_OF_TRANSLATION_EQ",EXPOSED_FACE_OF_TRANSLATION_EQ; +"EXPOSED_POINT_OF_FURTHEST_POINT",EXPOSED_POINT_OF_FURTHEST_POINT; +"EXPOSED_POINT_OF_INTER_SUPPORTING_HYPERPLANE_GE",EXPOSED_POINT_OF_INTER_SUPPORTING_HYPERPLANE_GE; +"EXPOSED_POINT_OF_INTER_SUPPORTING_HYPERPLANE_LE",EXPOSED_POINT_OF_INTER_SUPPORTING_HYPERPLANE_LE; +"EXP_1",EXP_1; +"EXP_2",EXP_2; +"EXP_ADD",EXP_ADD; +"EXP_EQ_0",EXP_EQ_0; +"EXP_EQ_1",EXP_EQ_1; +"EXP_LT_0",EXP_LT_0; +"EXP_MONO_EQ",EXP_MONO_EQ; +"EXP_MONO_LE",EXP_MONO_LE; +"EXP_MONO_LE_IMP",EXP_MONO_LE_IMP; +"EXP_MONO_LT",EXP_MONO_LT; +"EXP_MONO_LT_IMP",EXP_MONO_LT_IMP; +"EXP_MULT",EXP_MULT; +"EXP_ONE",EXP_ONE; +"EXP_ZERO",EXP_ZERO; +"EXTEND_FL",EXTEND_FL; +"EXTEND_INSEG",EXTEND_INSEG; +"EXTEND_LINSEG",EXTEND_LINSEG; +"EXTEND_TO_AFFINE_BASIS",EXTEND_TO_AFFINE_BASIS; +"EXTENSION",EXTENSION; +"EXTREME_POINTS_OF_CONVEX_HULL",EXTREME_POINTS_OF_CONVEX_HULL; +"EXTREME_POINTS_OF_CONVEX_HULL_EQ",EXTREME_POINTS_OF_CONVEX_HULL_EQ; +"EXTREME_POINTS_OF_LINEAR_IMAGE",EXTREME_POINTS_OF_LINEAR_IMAGE; +"EXTREME_POINTS_OF_TRANSLATION",EXTREME_POINTS_OF_TRANSLATION; +"EXTREME_POINT_EXISTS_CONVEX",EXTREME_POINT_EXISTS_CONVEX; +"EXTREME_POINT_NOT_IN_INTERIOR",EXTREME_POINT_NOT_IN_INTERIOR; +"EXTREME_POINT_NOT_IN_RELATIVE_INTERIOR",EXTREME_POINT_NOT_IN_RELATIVE_INTERIOR; +"EXTREME_POINT_OF_CONIC",EXTREME_POINT_OF_CONIC; +"EXTREME_POINT_OF_CONVEX_HULL",EXTREME_POINT_OF_CONVEX_HULL; +"EXTREME_POINT_OF_CONVEX_HULL_2",EXTREME_POINT_OF_CONVEX_HULL_2; +"EXTREME_POINT_OF_CONVEX_HULL_AFFINE_INDEPENDENT",EXTREME_POINT_OF_CONVEX_HULL_AFFINE_INDEPENDENT; +"EXTREME_POINT_OF_CONVEX_HULL_CONVEX_INDEPENDENT",EXTREME_POINT_OF_CONVEX_HULL_CONVEX_INDEPENDENT; +"EXTREME_POINT_OF_CONVEX_HULL_EQ",EXTREME_POINT_OF_CONVEX_HULL_EQ; +"EXTREME_POINT_OF_CONVEX_HULL_INSERT",EXTREME_POINT_OF_CONVEX_HULL_INSERT; +"EXTREME_POINT_OF_CONVEX_HULL_INSERT_EQ",EXTREME_POINT_OF_CONVEX_HULL_INSERT_EQ; +"EXTREME_POINT_OF_EMPTY",EXTREME_POINT_OF_EMPTY; +"EXTREME_POINT_OF_FACE",EXTREME_POINT_OF_FACE; +"EXTREME_POINT_OF_INTER",EXTREME_POINT_OF_INTER; +"EXTREME_POINT_OF_INTER_SUPPORTING_HYPERPLANE_GE",EXTREME_POINT_OF_INTER_SUPPORTING_HYPERPLANE_GE; +"EXTREME_POINT_OF_INTER_SUPPORTING_HYPERPLANE_LE",EXTREME_POINT_OF_INTER_SUPPORTING_HYPERPLANE_LE; +"EXTREME_POINT_OF_LINEAR_IMAGE",EXTREME_POINT_OF_LINEAR_IMAGE; +"EXTREME_POINT_OF_MIDPOINT",EXTREME_POINT_OF_MIDPOINT; +"EXTREME_POINT_OF_SEGMENT",EXTREME_POINT_OF_SEGMENT; +"EXTREME_POINT_OF_SING",EXTREME_POINT_OF_SING; +"EXTREME_POINT_OF_STILLCONVEX",EXTREME_POINT_OF_STILLCONVEX; +"EXTREME_POINT_OF_TRANSLATION_EQ",EXTREME_POINT_OF_TRANSLATION_EQ; +"EX_IMP",EX_IMP; +"EX_MAP",EX_MAP; +"EX_MEM",EX_MEM; +"FACES_OF_LINEAR_IMAGE",FACES_OF_LINEAR_IMAGE; +"FACES_OF_SIMPLEX",FACES_OF_SIMPLEX; +"FACES_OF_TRANSLATION",FACES_OF_TRANSLATION; +"FACETS_OF_POLYHEDRON_EXPLICIT_DISTINCT",FACETS_OF_POLYHEDRON_EXPLICIT_DISTINCT; +"FACET_OF_CONVEX_HULL_AFFINE_INDEPENDENT",FACET_OF_CONVEX_HULL_AFFINE_INDEPENDENT; +"FACET_OF_CONVEX_HULL_AFFINE_INDEPENDENT_ALT",FACET_OF_CONVEX_HULL_AFFINE_INDEPENDENT_ALT; +"FACET_OF_EMPTY",FACET_OF_EMPTY; +"FACET_OF_HALFSPACE_GE",FACET_OF_HALFSPACE_GE; +"FACET_OF_HALFSPACE_LE",FACET_OF_HALFSPACE_LE; +"FACET_OF_IMP_FACE_OF",FACET_OF_IMP_FACE_OF; +"FACET_OF_IMP_PROPER",FACET_OF_IMP_PROPER; +"FACET_OF_IMP_SUBSET",FACET_OF_IMP_SUBSET; +"FACET_OF_LINEAR_IMAGE",FACET_OF_LINEAR_IMAGE; +"FACET_OF_POLYHEDRON",FACET_OF_POLYHEDRON; +"FACET_OF_POLYHEDRON_EXPLICIT",FACET_OF_POLYHEDRON_EXPLICIT; +"FACET_OF_REFL",FACET_OF_REFL; +"FACET_OF_TRANSLATION_EQ",FACET_OF_TRANSLATION_EQ; +"FACE_OF_AFFINE_EQ",FACE_OF_AFFINE_EQ; +"FACE_OF_AFFINE_TRIVIAL",FACE_OF_AFFINE_TRIVIAL; +"FACE_OF_AFF_DIM_LT",FACE_OF_AFF_DIM_LT; +"FACE_OF_CONIC",FACE_OF_CONIC; +"FACE_OF_CONVEX_HULLS",FACE_OF_CONVEX_HULLS; +"FACE_OF_CONVEX_HULL_AFFINE_INDEPENDENT",FACE_OF_CONVEX_HULL_AFFINE_INDEPENDENT; +"FACE_OF_CONVEX_HULL_INSERT",FACE_OF_CONVEX_HULL_INSERT; +"FACE_OF_CONVEX_HULL_INSERT_EQ",FACE_OF_CONVEX_HULL_INSERT_EQ; +"FACE_OF_CONVEX_HULL_SUBSET",FACE_OF_CONVEX_HULL_SUBSET; +"FACE_OF_DISJOINT_INTERIOR",FACE_OF_DISJOINT_INTERIOR; +"FACE_OF_DISJOINT_RELATIVE_INTERIOR",FACE_OF_DISJOINT_RELATIVE_INTERIOR; +"FACE_OF_EMPTY",FACE_OF_EMPTY; +"FACE_OF_EQ",FACE_OF_EQ; +"FACE_OF_FACE",FACE_OF_FACE; +"FACE_OF_HALFSPACE_GE",FACE_OF_HALFSPACE_GE; +"FACE_OF_HALFSPACE_LE",FACE_OF_HALFSPACE_LE; +"FACE_OF_IMP_CLOSED",FACE_OF_IMP_CLOSED; +"FACE_OF_IMP_COMPACT",FACE_OF_IMP_COMPACT; +"FACE_OF_IMP_CONVEX",FACE_OF_IMP_CONVEX; +"FACE_OF_IMP_SUBSET",FACE_OF_IMP_SUBSET; +"FACE_OF_INTER",FACE_OF_INTER; +"FACE_OF_INTERS",FACE_OF_INTERS; +"FACE_OF_INTER_INTER",FACE_OF_INTER_INTER; +"FACE_OF_INTER_SUBFACE",FACE_OF_INTER_SUBFACE; +"FACE_OF_INTER_SUPPORTING_HYPERPLANE_GE",FACE_OF_INTER_SUPPORTING_HYPERPLANE_GE; +"FACE_OF_INTER_SUPPORTING_HYPERPLANE_GE_STRONG",FACE_OF_INTER_SUPPORTING_HYPERPLANE_GE_STRONG; +"FACE_OF_INTER_SUPPORTING_HYPERPLANE_LE",FACE_OF_INTER_SUPPORTING_HYPERPLANE_LE; +"FACE_OF_INTER_SUPPORTING_HYPERPLANE_LE_STRONG",FACE_OF_INTER_SUPPORTING_HYPERPLANE_LE_STRONG; +"FACE_OF_LINEAR_IMAGE",FACE_OF_LINEAR_IMAGE; +"FACE_OF_PCROSS",FACE_OF_PCROSS; +"FACE_OF_PCROSS_DECOMP",FACE_OF_PCROSS_DECOMP; +"FACE_OF_PCROSS_EQ",FACE_OF_PCROSS_EQ; +"FACE_OF_POLYHEDRON",FACE_OF_POLYHEDRON; +"FACE_OF_POLYHEDRON_EXPLICIT",FACE_OF_POLYHEDRON_EXPLICIT; +"FACE_OF_POLYHEDRON_POLYHEDRON",FACE_OF_POLYHEDRON_POLYHEDRON; +"FACE_OF_POLYHEDRON_SUBSET_EXPLICIT",FACE_OF_POLYHEDRON_SUBSET_EXPLICIT; +"FACE_OF_POLYHEDRON_SUBSET_FACET",FACE_OF_POLYHEDRON_SUBSET_FACET; +"FACE_OF_POLYTOPE_POLYTOPE",FACE_OF_POLYTOPE_POLYTOPE; +"FACE_OF_REFL",FACE_OF_REFL; +"FACE_OF_REFL_EQ",FACE_OF_REFL_EQ; +"FACE_OF_SIMPLEX_SUBSET",FACE_OF_SIMPLEX_SUBSET; +"FACE_OF_SING",FACE_OF_SING; +"FACE_OF_SLICE",FACE_OF_SLICE; +"FACE_OF_STILLCONVEX",FACE_OF_STILLCONVEX; +"FACE_OF_SUBSET",FACE_OF_SUBSET; +"FACE_OF_SUBSET_RELATIVE_BOUNDARY",FACE_OF_SUBSET_RELATIVE_BOUNDARY; +"FACE_OF_SUBSET_RELATIVE_FRONTIER",FACE_OF_SUBSET_RELATIVE_FRONTIER; +"FACE_OF_TRANS",FACE_OF_TRANS; +"FACE_OF_TRANSLATION_EQ",FACE_OF_TRANSLATION_EQ; +"FACT",FACT; +"FACT_LE",FACT_LE; +"FACT_LT",FACT_LT; +"FACT_MONO",FACT_MONO; +"FACT_NZ",FACT_NZ; +"FARKAS_LEMMA",FARKAS_LEMMA; +"FARKAS_LEMMA_ALT",FARKAS_LEMMA_ALT; +"FASHODA",FASHODA; +"FASHODA_INTERLACE",FASHODA_INTERLACE; +"FASHODA_UNIT",FASHODA_UNIT; +"FASHODA_UNIT_PATH",FASHODA_UNIT_PATH; +"FCONS",FCONS; +"FCONS_UNDO",FCONS_UNDO; +"FILTER",FILTER; +"FILTER_APPEND",FILTER_APPEND; +"FILTER_MAP",FILTER_MAP; +"FINE_DIVISION_EXISTS",FINE_DIVISION_EXISTS; +"FINE_INTER",FINE_INTER; +"FINE_INTERS",FINE_INTERS; +"FINE_SUBSET",FINE_SUBSET; +"FINE_UNION",FINE_UNION; +"FINE_UNIONS",FINE_UNIONS; +"FINITELY_GENERATED_CONIC_POLYHEDRON",FINITELY_GENERATED_CONIC_POLYHEDRON; +"FINITE_BALL",FINITE_BALL; +"FINITE_BITSET",FINITE_BITSET; +"FINITE_BOOL",FINITE_BOOL; +"FINITE_BOUNDED_FUNCTIONS",FINITE_BOUNDED_FUNCTIONS; +"FINITE_CARD_LT",FINITE_CARD_LT; +"FINITE_CART",FINITE_CART; +"FINITE_CART_SUBSET_LEMMA",FINITE_CART_SUBSET_LEMMA; +"FINITE_CART_UNIV",FINITE_CART_UNIV; +"FINITE_CASES",FINITE_CASES; +"FINITE_CBALL",FINITE_CBALL; +"FINITE_COLUMNS",FINITE_COLUMNS; +"FINITE_COMPONENTS",FINITE_COMPONENTS; +"FINITE_CROSS",FINITE_CROSS; +"FINITE_DELETE",FINITE_DELETE; +"FINITE_DELETE_IMP",FINITE_DELETE_IMP; +"FINITE_DIFF",FINITE_DIFF; +"FINITE_EMPTY",FINITE_EMPTY; +"FINITE_EMPTY_INTERIOR",FINITE_EMPTY_INTERIOR; +"FINITE_FACES_OF_SIMPLEX",FINITE_FACES_OF_SIMPLEX; +"FINITE_FINITE_IMAGE",FINITE_FINITE_IMAGE; +"FINITE_FINITE_PREIMAGE",FINITE_FINITE_PREIMAGE; +"FINITE_FINITE_PREIMAGE_GENERAL",FINITE_FINITE_PREIMAGE_GENERAL; +"FINITE_FINITE_UNIONS",FINITE_FINITE_UNIONS; +"FINITE_FUNSPACE",FINITE_FUNSPACE; +"FINITE_FUNSPACE_UNIV",FINITE_FUNSPACE_UNIV; +"FINITE_HAS_SIZE",FINITE_HAS_SIZE; +"FINITE_IMAGE",FINITE_IMAGE; +"FINITE_IMAGE_EXPAND",FINITE_IMAGE_EXPAND; +"FINITE_IMAGE_IMAGE",FINITE_IMAGE_IMAGE; +"FINITE_IMAGE_INJ",FINITE_IMAGE_INJ; +"FINITE_IMAGE_INJ_EQ",FINITE_IMAGE_INJ_EQ; +"FINITE_IMAGE_INJ_GENERAL",FINITE_IMAGE_INJ_GENERAL; +"FINITE_IMP_BOUNDED",FINITE_IMP_BOUNDED; +"FINITE_IMP_BOUNDED_CONVEX_HULL",FINITE_IMP_BOUNDED_CONVEX_HULL; +"FINITE_IMP_CLOSED",FINITE_IMP_CLOSED; +"FINITE_IMP_CLOSED_IN",FINITE_IMP_CLOSED_IN; +"FINITE_IMP_COMPACT",FINITE_IMP_COMPACT; +"FINITE_IMP_COMPACT_CONVEX_HULL",FINITE_IMP_COMPACT_CONVEX_HULL; +"FINITE_IMP_COUNTABLE",FINITE_IMP_COUNTABLE; +"FINITE_IMP_NOT_OPEN",FINITE_IMP_NOT_OPEN; +"FINITE_INDEX_INJ",FINITE_INDEX_INJ; +"FINITE_INDEX_INRANGE",FINITE_INDEX_INRANGE; +"FINITE_INDEX_INRANGE_2",FINITE_INDEX_INRANGE_2; +"FINITE_INDEX_NUMBERS",FINITE_INDEX_NUMBERS; +"FINITE_INDEX_NUMSEG",FINITE_INDEX_NUMSEG; +"FINITE_INDEX_NUMSEG_SPECIAL",FINITE_INDEX_NUMSEG_SPECIAL; +"FINITE_INDEX_WORKS",FINITE_INDEX_WORKS; +"FINITE_INDUCT",FINITE_INDUCT; +"FINITE_INDUCT_DELETE",FINITE_INDUCT_DELETE; +"FINITE_INDUCT_STRONG",FINITE_INDUCT_STRONG; +"FINITE_INSERT",FINITE_INSERT; +"FINITE_INTER",FINITE_INTER; +"FINITE_INTERVAL_1",FINITE_INTERVAL_1; +"FINITE_INTER_COLLINEAR_OPEN_SEGMENTS",FINITE_INTER_COLLINEAR_OPEN_SEGMENTS; +"FINITE_INTER_NUMSEG",FINITE_INTER_NUMSEG; +"FINITE_INTSEG",FINITE_INTSEG; +"FINITE_MULTIVECTOR",FINITE_MULTIVECTOR; +"FINITE_NUMSEG",FINITE_NUMSEG; +"FINITE_NUMSEG_LE",FINITE_NUMSEG_LE; +"FINITE_NUMSEG_LT",FINITE_NUMSEG_LT; +"FINITE_PCROSS",FINITE_PCROSS; +"FINITE_PCROSS_EQ",FINITE_PCROSS_EQ; +"FINITE_PERMUTATIONS",FINITE_PERMUTATIONS; +"FINITE_POLYHEDRON_EXPOSED_FACES",FINITE_POLYHEDRON_EXPOSED_FACES; +"FINITE_POLYHEDRON_EXTREME_POINTS",FINITE_POLYHEDRON_EXTREME_POINTS; +"FINITE_POLYHEDRON_FACES",FINITE_POLYHEDRON_FACES; +"FINITE_POLYHEDRON_FACETS",FINITE_POLYHEDRON_FACETS; +"FINITE_POLYTOPE_FACES",FINITE_POLYTOPE_FACES; +"FINITE_POLYTOPE_FACETS",FINITE_POLYTOPE_FACETS; +"FINITE_POWERSET",FINITE_POWERSET; +"FINITE_PRODUCT",FINITE_PRODUCT; +"FINITE_PRODUCT_DEPENDENT",FINITE_PRODUCT_DEPENDENT; +"FINITE_REAL_INTERVAL",FINITE_REAL_INTERVAL; +"FINITE_RECURSION",FINITE_RECURSION; +"FINITE_RECURSION_DELETE",FINITE_RECURSION_DELETE; +"FINITE_RESTRICT",FINITE_RESTRICT; +"FINITE_ROWS",FINITE_ROWS; +"FINITE_RULES",FINITE_RULES; +"FINITE_SEGMENT",FINITE_SEGMENT; +"FINITE_SET_AVOID",FINITE_SET_AVOID; +"FINITE_SET_OF_LIST",FINITE_SET_OF_LIST; +"FINITE_SIMPLICES",FINITE_SIMPLICES; +"FINITE_SING",FINITE_SING; +"FINITE_SPHERE",FINITE_SPHERE; +"FINITE_SPHERE_1",FINITE_SPHERE_1; +"FINITE_STDBASIS",FINITE_STDBASIS; +"FINITE_SUBSET",FINITE_SUBSET; +"FINITE_SUBSET_IMAGE",FINITE_SUBSET_IMAGE; +"FINITE_SUBSET_IMAGE_IMP",FINITE_SUBSET_IMAGE_IMP; +"FINITE_SUM_IMAGE",FINITE_SUM_IMAGE; +"FINITE_SUPPORT",FINITE_SUPPORT; +"FINITE_SUPPORT_DELTA",FINITE_SUPPORT_DELTA; +"FINITE_TRANSITIVITY_CHAIN",FINITE_TRANSITIVITY_CHAIN; +"FINITE_UNION",FINITE_UNION; +"FINITE_UNIONS",FINITE_UNIONS; +"FINITE_UNION_IMP",FINITE_UNION_IMP; +"FINREC",FINREC; +"FINREC_1_LEMMA",FINREC_1_LEMMA; +"FINREC_EXISTS_LEMMA",FINREC_EXISTS_LEMMA; +"FINREC_FUN",FINREC_FUN; +"FINREC_FUN_LEMMA",FINREC_FUN_LEMMA; +"FINREC_SUC_LEMMA",FINREC_SUC_LEMMA; +"FINREC_UNIQUE_LEMMA",FINREC_UNIQUE_LEMMA; +"FIXED_POINT_INESSENTIAL_SPHERE_MAP",FIXED_POINT_INESSENTIAL_SPHERE_MAP; +"FIXING_SWAPSEQ_DECREASE",FIXING_SWAPSEQ_DECREASE; +"FLATTEN_LEMMA",FLATTEN_LEMMA; +"FLOOR",FLOOR; +"FLOOR_DIV_DIV",FLOOR_DIV_DIV; +"FLOOR_DOUBLE",FLOOR_DOUBLE; +"FLOOR_EQ_0",FLOOR_EQ_0; +"FLOOR_FRAC",FLOOR_FRAC; +"FLOOR_MONO",FLOOR_MONO; +"FLOOR_NUM",FLOOR_NUM; +"FLOOR_POS",FLOOR_POS; +"FLOOR_POS_LE",FLOOR_POS_LE; +"FLOOR_UNIQUE",FLOOR_UNIQUE; +"FL_RESTRICT",FL_RESTRICT; +"FL_RESTRICTED_SUBSET",FL_RESTRICTED_SUBSET; +"FL_SUC",FL_SUC; +"FNIL",FNIL; +"FORALL_1",FORALL_1; +"FORALL_2",FORALL_2; +"FORALL_3",FORALL_3; +"FORALL_4",FORALL_4; +"FORALL_ALL",FORALL_ALL; +"FORALL_AND_THM",FORALL_AND_THM; +"FORALL_BOOL_THM",FORALL_BOOL_THM; +"FORALL_COUNTABLE_AS_IMAGE",FORALL_COUNTABLE_AS_IMAGE; +"FORALL_COUNTABLE_SUBSET_IMAGE",FORALL_COUNTABLE_SUBSET_IMAGE; +"FORALL_CURRY",FORALL_CURRY; +"FORALL_DEF",FORALL_DEF; +"FORALL_DIMINDEX_1",FORALL_DIMINDEX_1; +"FORALL_DOT_EQ_0",FORALL_DOT_EQ_0; +"FORALL_DROP",FORALL_DROP; +"FORALL_DROP_FUN",FORALL_DROP_FUN; +"FORALL_DROP_IMAGE",FORALL_DROP_IMAGE; +"FORALL_EVENTUALLY",FORALL_EVENTUALLY; +"FORALL_FINITE_INDEX",FORALL_FINITE_INDEX; +"FORALL_FINITE_SUBSET_IMAGE",FORALL_FINITE_SUBSET_IMAGE; +"FORALL_INTEGER",FORALL_INTEGER; +"FORALL_IN_CLAUSES",FORALL_IN_CLAUSES; +"FORALL_IN_CLOSURE",FORALL_IN_CLOSURE; +"FORALL_IN_DIVISION",FORALL_IN_DIVISION; +"FORALL_IN_DIVISION_NONEMPTY",FORALL_IN_DIVISION_NONEMPTY; +"FORALL_IN_GSPEC",FORALL_IN_GSPEC; +"FORALL_IN_IMAGE",FORALL_IN_IMAGE; +"FORALL_IN_INSERT",FORALL_IN_INSERT; +"FORALL_IN_PCROSS",FORALL_IN_PCROSS; +"FORALL_IN_UNIONS",FORALL_IN_UNIONS; +"FORALL_LIFT",FORALL_LIFT; +"FORALL_LIFT_FUN",FORALL_LIFT_FUN; +"FORALL_LIFT_IMAGE",FORALL_LIFT_IMAGE; +"FORALL_MULTIVECTOR",FORALL_MULTIVECTOR; +"FORALL_NOT_THM",FORALL_NOT_THM; +"FORALL_OF_DROP",FORALL_OF_DROP; +"FORALL_OF_PASTECART",FORALL_OF_PASTECART; +"FORALL_OPTION",FORALL_OPTION; +"FORALL_PAIRED_THM",FORALL_PAIRED_THM; +"FORALL_PAIR_THM",FORALL_PAIR_THM; +"FORALL_PASTECART",FORALL_PASTECART; +"FORALL_POS_MONO",FORALL_POS_MONO; +"FORALL_POS_MONO_1",FORALL_POS_MONO_1; +"FORALL_REAL_ONE",FORALL_REAL_ONE; +"FORALL_SETCODE",FORALL_SETCODE; +"FORALL_SIMP",FORALL_SIMP; +"FORALL_SUBSET_IMAGE",FORALL_SUBSET_IMAGE; +"FORALL_SUBSET_UNION",FORALL_SUBSET_UNION; +"FORALL_SUC",FORALL_SUC; +"FORALL_SUM_THM",FORALL_SUM_THM; +"FORALL_TRIPLED_THM",FORALL_TRIPLED_THM; +"FORALL_UNCURRY",FORALL_UNCURRY; +"FORALL_UNWIND_THM1",FORALL_UNWIND_THM1; +"FORALL_UNWIND_THM2",FORALL_UNWIND_THM2; +"FORALL_VECTOR_1",FORALL_VECTOR_1; +"FORALL_VECTOR_2",FORALL_VECTOR_2; +"FORALL_VECTOR_3",FORALL_VECTOR_3; +"FORALL_VECTOR_4",FORALL_VECTOR_4; +"FRAC_FLOOR",FRAC_FLOOR; +"FRAC_NUM",FRAC_NUM; +"FRAC_UNIQUE",FRAC_UNIQUE; +"FRECHET_DERIVATIVE_AT",FRECHET_DERIVATIVE_AT; +"FRECHET_DERIVATIVE_CONST_AT",FRECHET_DERIVATIVE_CONST_AT; +"FRECHET_DERIVATIVE_UNIQUE_AT",FRECHET_DERIVATIVE_UNIQUE_AT; +"FRECHET_DERIVATIVE_UNIQUE_WITHIN",FRECHET_DERIVATIVE_UNIQUE_WITHIN; +"FRECHET_DERIVATIVE_UNIQUE_WITHIN_CLOSED_INTERVAL",FRECHET_DERIVATIVE_UNIQUE_WITHIN_CLOSED_INTERVAL; +"FRECHET_DERIVATIVE_UNIQUE_WITHIN_OPEN_INTERVAL",FRECHET_DERIVATIVE_UNIQUE_WITHIN_OPEN_INTERVAL; +"FRECHET_DERIVATIVE_WITHIN_CLOSED_INTERVAL",FRECHET_DERIVATIVE_WITHIN_CLOSED_INTERVAL; +"FRECHET_DERIVATIVE_WORKS",FRECHET_DERIVATIVE_WORKS; +"FROM_0",FROM_0; +"FROM_INTER_NUMSEG",FROM_INTER_NUMSEG; +"FROM_INTER_NUMSEG_GEN",FROM_INTER_NUMSEG_GEN; +"FRONTIER_BALL",FRONTIER_BALL; +"FRONTIER_BIJECTIVE_LINEAR_IMAGE",FRONTIER_BIJECTIVE_LINEAR_IMAGE; +"FRONTIER_CBALL",FRONTIER_CBALL; +"FRONTIER_CLOSED",FRONTIER_CLOSED; +"FRONTIER_CLOSED_INTERVAL",FRONTIER_CLOSED_INTERVAL; +"FRONTIER_CLOSURES",FRONTIER_CLOSURES; +"FRONTIER_CLOSURE_CONVEX",FRONTIER_CLOSURE_CONVEX; +"FRONTIER_COMPLEMENT",FRONTIER_COMPLEMENT; +"FRONTIER_CONVEX_HULL_CASES",FRONTIER_CONVEX_HULL_CASES; +"FRONTIER_CONVEX_HULL_EXPLICIT",FRONTIER_CONVEX_HULL_EXPLICIT; +"FRONTIER_DISJOINT_EQ",FRONTIER_DISJOINT_EQ; +"FRONTIER_EMPTY",FRONTIER_EMPTY; +"FRONTIER_EQ_EMPTY",FRONTIER_EQ_EMPTY; +"FRONTIER_FRONTIER_FRONTIER",FRONTIER_FRONTIER_FRONTIER; +"FRONTIER_FRONTIER_SUBSET",FRONTIER_FRONTIER_SUBSET; +"FRONTIER_HALFSPACE_GE",FRONTIER_HALFSPACE_GE; +"FRONTIER_HALFSPACE_GT",FRONTIER_HALFSPACE_GT; +"FRONTIER_HALFSPACE_LE",FRONTIER_HALFSPACE_LE; +"FRONTIER_HALFSPACE_LT",FRONTIER_HALFSPACE_LT; +"FRONTIER_INJECTIVE_LINEAR_IMAGE",FRONTIER_INJECTIVE_LINEAR_IMAGE; +"FRONTIER_INSIDE_SUBSET",FRONTIER_INSIDE_SUBSET; +"FRONTIER_INTERIORS",FRONTIER_INTERIORS; +"FRONTIER_INTER_SUBSET",FRONTIER_INTER_SUBSET; +"FRONTIER_MINIMAL_SEPARATING_CLOSED",FRONTIER_MINIMAL_SEPARATING_CLOSED; +"FRONTIER_NOT_EMPTY",FRONTIER_NOT_EMPTY; +"FRONTIER_OF_COMPONENTS_CLOSED_COMPLEMENT",FRONTIER_OF_COMPONENTS_CLOSED_COMPLEMENT; +"FRONTIER_OF_COMPONENTS_SUBSET",FRONTIER_OF_COMPONENTS_SUBSET; +"FRONTIER_OF_CONNECTED_COMPONENT_SUBSET",FRONTIER_OF_CONNECTED_COMPONENT_SUBSET; +"FRONTIER_OF_CONVEX_HULL",FRONTIER_OF_CONVEX_HULL; +"FRONTIER_OF_TRIANGLE",FRONTIER_OF_TRIANGLE; +"FRONTIER_OPEN_INTERVAL",FRONTIER_OPEN_INTERVAL; +"FRONTIER_OUTSIDE_SUBSET",FRONTIER_OUTSIDE_SUBSET; +"FRONTIER_RETRACT_OF_PUNCTURED_UNIVERSE",FRONTIER_RETRACT_OF_PUNCTURED_UNIVERSE; +"FRONTIER_SING",FRONTIER_SING; +"FRONTIER_STRADDLE",FRONTIER_STRADDLE; +"FRONTIER_SUBSET_CLOSED",FRONTIER_SUBSET_CLOSED; +"FRONTIER_SUBSET_COMPACT",FRONTIER_SUBSET_COMPACT; +"FRONTIER_SUBSET_EQ",FRONTIER_SUBSET_EQ; +"FRONTIER_SUBSET_RETRACTION",FRONTIER_SUBSET_RETRACTION; +"FRONTIER_SURJECTIVE_LINEAR_IMAGE",FRONTIER_SURJECTIVE_LINEAR_IMAGE; +"FRONTIER_TRANSLATION",FRONTIER_TRANSLATION; +"FRONTIER_UNION",FRONTIER_UNION; +"FRONTIER_UNIONS_SUBSET_CLOSURE",FRONTIER_UNIONS_SUBSET_CLOSURE; +"FRONTIER_UNION_SUBSET",FRONTIER_UNION_SUBSET; +"FRONTIER_UNIV",FRONTIER_UNIV; +"FST",FST; +"FSTCART_ADD",FSTCART_ADD; +"FSTCART_CMUL",FSTCART_CMUL; +"FSTCART_NEG",FSTCART_NEG; +"FSTCART_PASTECART",FSTCART_PASTECART; +"FSTCART_SUB",FSTCART_SUB; +"FSTCART_VEC",FSTCART_VEC; +"FSTCART_VSUM",FSTCART_VSUM; +"FST_DEF",FST_DEF; +"FULL_RANK_INJECTIVE",FULL_RANK_INJECTIVE; +"FULL_RANK_SURJECTIVE",FULL_RANK_SURJECTIVE; +"FUNCTION_CONVERGENT_SUBSEQUENCE",FUNCTION_CONVERGENT_SUBSEQUENCE; +"FUNCTION_FACTORS_LEFT",FUNCTION_FACTORS_LEFT; +"FUNCTION_FACTORS_LEFT_GEN",FUNCTION_FACTORS_LEFT_GEN; +"FUNCTION_FACTORS_RIGHT",FUNCTION_FACTORS_RIGHT; +"FUNCTION_FACTORS_RIGHT_GEN",FUNCTION_FACTORS_RIGHT_GEN; +"FUNDAMENTAL_THEOREM_OF_CALCULUS",FUNDAMENTAL_THEOREM_OF_CALCULUS; +"FUNDAMENTAL_THEOREM_OF_CALCULUS_INTERIOR",FUNDAMENTAL_THEOREM_OF_CALCULUS_INTERIOR; +"FUNDAMENTAL_THEOREM_OF_CALCULUS_INTERIOR_STRONG",FUNDAMENTAL_THEOREM_OF_CALCULUS_INTERIOR_STRONG; +"FUNDAMENTAL_THEOREM_OF_CALCULUS_STRONG",FUNDAMENTAL_THEOREM_OF_CALCULUS_STRONG; +"FUN_EQ_THM",FUN_EQ_THM; +"FUN_IN_IMAGE",FUN_IN_IMAGE; +"F_DEF",F_DEF; +"GABS_DEF",GABS_DEF; +"GAUGE_BALL",GAUGE_BALL; +"GAUGE_BALL_DEPENDENT",GAUGE_BALL_DEPENDENT; +"GAUGE_EXISTENCE_LEMMA",GAUGE_EXISTENCE_LEMMA; +"GAUGE_INTER",GAUGE_INTER; +"GAUGE_INTERS",GAUGE_INTERS; +"GAUGE_MODIFY",GAUGE_MODIFY; +"GAUGE_TRIVIAL",GAUGE_TRIVIAL; +"GE",GE; +"GENERAL_CONNECTED_OPEN",GENERAL_CONNECTED_OPEN; +"GEOM_ASSOC",GEOM_ASSOC; +"GEOM_LADD",GEOM_LADD; +"GEOM_LMUL",GEOM_LMUL; +"GEOM_LNEG",GEOM_LNEG; +"GEOM_LZERO",GEOM_LZERO; +"GEOM_MBASIS",GEOM_MBASIS; +"GEOM_MBASIS_SING",GEOM_MBASIS_SING; +"GEOM_RADD",GEOM_RADD; +"GEOM_RMUL",GEOM_RMUL; +"GEOM_RNEG",GEOM_RNEG; +"GEOM_RZERO",GEOM_RZERO; +"GEQ_DEF",GEQ_DEF; +"GE_C",GE_C; +"GE_REFL",GE_REFL; +"GRADE_ADD",GRADE_ADD; +"GRADE_CMUL",GRADE_CMUL; +"GRAM_SCHMIDT_STEP",GRAM_SCHMIDT_STEP; +"GRASSMANN_PLUCKER_2",GRASSMANN_PLUCKER_2; +"GRASSMANN_PLUCKER_3",GRASSMANN_PLUCKER_3; +"GRASSMANN_PLUCKER_4",GRASSMANN_PLUCKER_4; +"GSPEC",GSPEC; +"GT",GT; +"HALFSPACE_EQ_EMPTY_GE",HALFSPACE_EQ_EMPTY_GE; +"HALFSPACE_EQ_EMPTY_GT",HALFSPACE_EQ_EMPTY_GT; +"HALFSPACE_EQ_EMPTY_LE",HALFSPACE_EQ_EMPTY_LE; +"HALFSPACE_EQ_EMPTY_LT",HALFSPACE_EQ_EMPTY_LT; +"HAS_ANTIDERIVATIVE_LIMIT",HAS_ANTIDERIVATIVE_LIMIT; +"HAS_ANTIDERIVATIVE_SEQUENCE",HAS_ANTIDERIVATIVE_SEQUENCE; +"HAS_BOUNDED_SETVARIATION_ON",HAS_BOUNDED_SETVARIATION_ON; +"HAS_BOUNDED_SETVARIATION_ON_0",HAS_BOUNDED_SETVARIATION_ON_0; +"HAS_BOUNDED_SETVARIATION_ON_ADD",HAS_BOUNDED_SETVARIATION_ON_ADD; +"HAS_BOUNDED_SETVARIATION_ON_CMUL",HAS_BOUNDED_SETVARIATION_ON_CMUL; +"HAS_BOUNDED_SETVARIATION_ON_COMPONENTWISE",HAS_BOUNDED_SETVARIATION_ON_COMPONENTWISE; +"HAS_BOUNDED_SETVARIATION_ON_COMPOSE_LINEAR",HAS_BOUNDED_SETVARIATION_ON_COMPOSE_LINEAR; +"HAS_BOUNDED_SETVARIATION_ON_DIVISION",HAS_BOUNDED_SETVARIATION_ON_DIVISION; +"HAS_BOUNDED_SETVARIATION_ON_ELEMENTARY",HAS_BOUNDED_SETVARIATION_ON_ELEMENTARY; +"HAS_BOUNDED_SETVARIATION_ON_EQ",HAS_BOUNDED_SETVARIATION_ON_EQ; +"HAS_BOUNDED_SETVARIATION_ON_IMP_BOUNDED_ON_SUBINTERVALS",HAS_BOUNDED_SETVARIATION_ON_IMP_BOUNDED_ON_SUBINTERVALS; +"HAS_BOUNDED_SETVARIATION_ON_INTERVAL",HAS_BOUNDED_SETVARIATION_ON_INTERVAL; +"HAS_BOUNDED_SETVARIATION_ON_NEG",HAS_BOUNDED_SETVARIATION_ON_NEG; +"HAS_BOUNDED_SETVARIATION_ON_NORM",HAS_BOUNDED_SETVARIATION_ON_NORM; +"HAS_BOUNDED_SETVARIATION_ON_NULL",HAS_BOUNDED_SETVARIATION_ON_NULL; +"HAS_BOUNDED_SETVARIATION_ON_SUB",HAS_BOUNDED_SETVARIATION_ON_SUB; +"HAS_BOUNDED_SETVARIATION_ON_SUBSET",HAS_BOUNDED_SETVARIATION_ON_SUBSET; +"HAS_BOUNDED_SETVARIATION_ON_UNIV",HAS_BOUNDED_SETVARIATION_ON_UNIV; +"HAS_BOUNDED_SETVARIATION_REFLECT2_EQ",HAS_BOUNDED_SETVARIATION_REFLECT2_EQ; +"HAS_BOUNDED_SETVARIATION_TRANSLATION",HAS_BOUNDED_SETVARIATION_TRANSLATION; +"HAS_BOUNDED_SETVARIATION_TRANSLATION2_EQ",HAS_BOUNDED_SETVARIATION_TRANSLATION2_EQ; +"HAS_BOUNDED_SETVARIATION_WORKS",HAS_BOUNDED_SETVARIATION_WORKS; +"HAS_BOUNDED_SETVARIATION_WORKS_ON_ELEMENTARY",HAS_BOUNDED_SETVARIATION_WORKS_ON_ELEMENTARY; +"HAS_BOUNDED_SETVARIATION_WORKS_ON_INTERVAL",HAS_BOUNDED_SETVARIATION_WORKS_ON_INTERVAL; +"HAS_BOUNDED_VARIATION_ABSOLUTELY_INTEGRABLE_DERIVATIVE",HAS_BOUNDED_VARIATION_ABSOLUTELY_INTEGRABLE_DERIVATIVE; +"HAS_BOUNDED_VARIATION_AFFINITY2_EQ",HAS_BOUNDED_VARIATION_AFFINITY2_EQ; +"HAS_BOUNDED_VARIATION_AFFINITY_EQ",HAS_BOUNDED_VARIATION_AFFINITY_EQ; +"HAS_BOUNDED_VARIATION_COMPOSE_DECREASING",HAS_BOUNDED_VARIATION_COMPOSE_DECREASING; +"HAS_BOUNDED_VARIATION_COMPOSE_INCREASING",HAS_BOUNDED_VARIATION_COMPOSE_INCREASING; +"HAS_BOUNDED_VARIATION_COUNTABLE_DISCONTINUITIES",HAS_BOUNDED_VARIATION_COUNTABLE_DISCONTINUITIES; +"HAS_BOUNDED_VARIATION_DARBOUX",HAS_BOUNDED_VARIATION_DARBOUX; +"HAS_BOUNDED_VARIATION_DARBOUX_STRICT",HAS_BOUNDED_VARIATION_DARBOUX_STRICT; +"HAS_BOUNDED_VARIATION_DARBOUX_STRONG",HAS_BOUNDED_VARIATION_DARBOUX_STRONG; +"HAS_BOUNDED_VARIATION_INTEGRABLE_NORM_DERIVATIVE",HAS_BOUNDED_VARIATION_INTEGRABLE_NORM_DERIVATIVE; +"HAS_BOUNDED_VARIATION_ON_ADD",HAS_BOUNDED_VARIATION_ON_ADD; +"HAS_BOUNDED_VARIATION_ON_CMUL",HAS_BOUNDED_VARIATION_ON_CMUL; +"HAS_BOUNDED_VARIATION_ON_COMBINE",HAS_BOUNDED_VARIATION_ON_COMBINE; +"HAS_BOUNDED_VARIATION_ON_COMPONENTWISE",HAS_BOUNDED_VARIATION_ON_COMPONENTWISE; +"HAS_BOUNDED_VARIATION_ON_COMPOSE_LINEAR",HAS_BOUNDED_VARIATION_ON_COMPOSE_LINEAR; +"HAS_BOUNDED_VARIATION_ON_CONST",HAS_BOUNDED_VARIATION_ON_CONST; +"HAS_BOUNDED_VARIATION_ON_DIVISION",HAS_BOUNDED_VARIATION_ON_DIVISION; +"HAS_BOUNDED_VARIATION_ON_EMPTY",HAS_BOUNDED_VARIATION_ON_EMPTY; +"HAS_BOUNDED_VARIATION_ON_EQ",HAS_BOUNDED_VARIATION_ON_EQ; +"HAS_BOUNDED_VARIATION_ON_ID",HAS_BOUNDED_VARIATION_ON_ID; +"HAS_BOUNDED_VARIATION_ON_IMP_BOUNDED_ON_INTERVAL",HAS_BOUNDED_VARIATION_ON_IMP_BOUNDED_ON_INTERVAL; +"HAS_BOUNDED_VARIATION_ON_IMP_BOUNDED_ON_SUBINTERVALS",HAS_BOUNDED_VARIATION_ON_IMP_BOUNDED_ON_SUBINTERVALS; +"HAS_BOUNDED_VARIATION_ON_LINEAR_IMAGE",HAS_BOUNDED_VARIATION_ON_LINEAR_IMAGE; +"HAS_BOUNDED_VARIATION_ON_MAX",HAS_BOUNDED_VARIATION_ON_MAX; +"HAS_BOUNDED_VARIATION_ON_MIN",HAS_BOUNDED_VARIATION_ON_MIN; +"HAS_BOUNDED_VARIATION_ON_MUL",HAS_BOUNDED_VARIATION_ON_MUL; +"HAS_BOUNDED_VARIATION_ON_NEG",HAS_BOUNDED_VARIATION_ON_NEG; +"HAS_BOUNDED_VARIATION_ON_NORM",HAS_BOUNDED_VARIATION_ON_NORM; +"HAS_BOUNDED_VARIATION_ON_NULL",HAS_BOUNDED_VARIATION_ON_NULL; +"HAS_BOUNDED_VARIATION_ON_REFLECT",HAS_BOUNDED_VARIATION_ON_REFLECT; +"HAS_BOUNDED_VARIATION_ON_REFLECT_INTERVAL",HAS_BOUNDED_VARIATION_ON_REFLECT_INTERVAL; +"HAS_BOUNDED_VARIATION_ON_SUB",HAS_BOUNDED_VARIATION_ON_SUB; +"HAS_BOUNDED_VARIATION_ON_SUBSET",HAS_BOUNDED_VARIATION_ON_SUBSET; +"HAS_BOUNDED_VARIATION_REFLECT2_EQ",HAS_BOUNDED_VARIATION_REFLECT2_EQ; +"HAS_BOUNDED_VARIATION_REFLECT_EQ",HAS_BOUNDED_VARIATION_REFLECT_EQ; +"HAS_BOUNDED_VARIATION_REFLECT_EQ_INTERVAL",HAS_BOUNDED_VARIATION_REFLECT_EQ_INTERVAL; +"HAS_BOUNDED_VARIATION_TRANSLATION",HAS_BOUNDED_VARIATION_TRANSLATION; +"HAS_BOUNDED_VARIATION_TRANSLATION2_EQ",HAS_BOUNDED_VARIATION_TRANSLATION2_EQ; +"HAS_BOUNDED_VARIATION_TRANSLATION_EQ",HAS_BOUNDED_VARIATION_TRANSLATION_EQ; +"HAS_BOUNDED_VARIATION_TRANSLATION_EQ_INTERVAL",HAS_BOUNDED_VARIATION_TRANSLATION_EQ_INTERVAL; +"HAS_BOUNDED_VECTOR_VARIATION_LEFT_LIMIT",HAS_BOUNDED_VECTOR_VARIATION_LEFT_LIMIT; +"HAS_BOUNDED_VECTOR_VARIATION_RIGHT_LIMIT",HAS_BOUNDED_VECTOR_VARIATION_RIGHT_LIMIT; +"HAS_DERIVATIVE_ADD",HAS_DERIVATIVE_ADD; +"HAS_DERIVATIVE_AT",HAS_DERIVATIVE_AT; +"HAS_DERIVATIVE_AT_ALT",HAS_DERIVATIVE_AT_ALT; +"HAS_DERIVATIVE_AT_WITHIN",HAS_DERIVATIVE_AT_WITHIN; +"HAS_DERIVATIVE_BILINEAR_AT",HAS_DERIVATIVE_BILINEAR_AT; +"HAS_DERIVATIVE_BILINEAR_WITHIN",HAS_DERIVATIVE_BILINEAR_WITHIN; +"HAS_DERIVATIVE_CMUL",HAS_DERIVATIVE_CMUL; +"HAS_DERIVATIVE_CMUL_EQ",HAS_DERIVATIVE_CMUL_EQ; +"HAS_DERIVATIVE_COMPONENTWISE_AT",HAS_DERIVATIVE_COMPONENTWISE_AT; +"HAS_DERIVATIVE_COMPONENTWISE_WITHIN",HAS_DERIVATIVE_COMPONENTWISE_WITHIN; +"HAS_DERIVATIVE_CONST",HAS_DERIVATIVE_CONST; +"HAS_DERIVATIVE_ID",HAS_DERIVATIVE_ID; +"HAS_DERIVATIVE_IMP_DIFFERENTIABLE",HAS_DERIVATIVE_IMP_DIFFERENTIABLE; +"HAS_DERIVATIVE_INVERSE",HAS_DERIVATIVE_INVERSE; +"HAS_DERIVATIVE_INVERSE_BASIC",HAS_DERIVATIVE_INVERSE_BASIC; +"HAS_DERIVATIVE_INVERSE_BASIC_X",HAS_DERIVATIVE_INVERSE_BASIC_X; +"HAS_DERIVATIVE_INVERSE_DIEUDONNE",HAS_DERIVATIVE_INVERSE_DIEUDONNE; +"HAS_DERIVATIVE_INVERSE_ON",HAS_DERIVATIVE_INVERSE_ON; +"HAS_DERIVATIVE_INVERSE_STRONG",HAS_DERIVATIVE_INVERSE_STRONG; +"HAS_DERIVATIVE_INVERSE_STRONG_X",HAS_DERIVATIVE_INVERSE_STRONG_X; +"HAS_DERIVATIVE_LIFT_COMPONENT",HAS_DERIVATIVE_LIFT_COMPONENT; +"HAS_DERIVATIVE_LIFT_DOT",HAS_DERIVATIVE_LIFT_DOT; +"HAS_DERIVATIVE_LINEAR",HAS_DERIVATIVE_LINEAR; +"HAS_DERIVATIVE_LOCALLY_INJECTIVE",HAS_DERIVATIVE_LOCALLY_INJECTIVE; +"HAS_DERIVATIVE_MUL_AT",HAS_DERIVATIVE_MUL_AT; +"HAS_DERIVATIVE_MUL_WITHIN",HAS_DERIVATIVE_MUL_WITHIN; +"HAS_DERIVATIVE_NEG",HAS_DERIVATIVE_NEG; +"HAS_DERIVATIVE_NEG_EQ",HAS_DERIVATIVE_NEG_EQ; +"HAS_DERIVATIVE_SEQUENCE",HAS_DERIVATIVE_SEQUENCE; +"HAS_DERIVATIVE_SEQUENCE_LIPSCHITZ",HAS_DERIVATIVE_SEQUENCE_LIPSCHITZ; +"HAS_DERIVATIVE_SERIES",HAS_DERIVATIVE_SERIES; +"HAS_DERIVATIVE_SQNORM_AT",HAS_DERIVATIVE_SQNORM_AT; +"HAS_DERIVATIVE_SUB",HAS_DERIVATIVE_SUB; +"HAS_DERIVATIVE_TRANSFORM_AT",HAS_DERIVATIVE_TRANSFORM_AT; +"HAS_DERIVATIVE_TRANSFORM_WITHIN",HAS_DERIVATIVE_TRANSFORM_WITHIN; +"HAS_DERIVATIVE_TRANSFORM_WITHIN_OPEN",HAS_DERIVATIVE_TRANSFORM_WITHIN_OPEN; +"HAS_DERIVATIVE_VMUL_COMPONENT",HAS_DERIVATIVE_VMUL_COMPONENT; +"HAS_DERIVATIVE_VMUL_DROP",HAS_DERIVATIVE_VMUL_DROP; +"HAS_DERIVATIVE_VSUM",HAS_DERIVATIVE_VSUM; +"HAS_DERIVATIVE_VSUM_NUMSEG",HAS_DERIVATIVE_VSUM_NUMSEG; +"HAS_DERIVATIVE_WITHIN",HAS_DERIVATIVE_WITHIN; +"HAS_DERIVATIVE_WITHIN_ALT",HAS_DERIVATIVE_WITHIN_ALT; +"HAS_DERIVATIVE_WITHIN_OPEN",HAS_DERIVATIVE_WITHIN_OPEN; +"HAS_DERIVATIVE_WITHIN_SUBSET",HAS_DERIVATIVE_WITHIN_SUBSET; +"HAS_DERIVATIVE_ZERO_CONNECTED_CONSTANT",HAS_DERIVATIVE_ZERO_CONNECTED_CONSTANT; +"HAS_DERIVATIVE_ZERO_CONNECTED_UNIQUE",HAS_DERIVATIVE_ZERO_CONNECTED_UNIQUE; +"HAS_DERIVATIVE_ZERO_CONSTANT",HAS_DERIVATIVE_ZERO_CONSTANT; +"HAS_DERIVATIVE_ZERO_UNIQUE",HAS_DERIVATIVE_ZERO_UNIQUE; +"HAS_DERIVATIVE_ZERO_UNIQUE_STRONG_CONNECTED",HAS_DERIVATIVE_ZERO_UNIQUE_STRONG_CONNECTED; +"HAS_DERIVATIVE_ZERO_UNIQUE_STRONG_CONVEX",HAS_DERIVATIVE_ZERO_UNIQUE_STRONG_CONVEX; +"HAS_DERIVATIVE_ZERO_UNIQUE_STRONG_INTERVAL",HAS_DERIVATIVE_ZERO_UNIQUE_STRONG_INTERVAL; +"HAS_FRECHET_DERIVATIVE_UNIQUE_AT",HAS_FRECHET_DERIVATIVE_UNIQUE_AT; +"HAS_INTEGRAL",HAS_INTEGRAL; +"HAS_INTEGRAL_0",HAS_INTEGRAL_0; +"HAS_INTEGRAL_0_EQ",HAS_INTEGRAL_0_EQ; +"HAS_INTEGRAL_ADD",HAS_INTEGRAL_ADD; +"HAS_INTEGRAL_AFFINITY",HAS_INTEGRAL_AFFINITY; +"HAS_INTEGRAL_ALT",HAS_INTEGRAL_ALT; +"HAS_INTEGRAL_BOUND",HAS_INTEGRAL_BOUND; +"HAS_INTEGRAL_CLOSURE",HAS_INTEGRAL_CLOSURE; +"HAS_INTEGRAL_CMUL",HAS_INTEGRAL_CMUL; +"HAS_INTEGRAL_COMBINE",HAS_INTEGRAL_COMBINE; +"HAS_INTEGRAL_COMBINE_DIVISION",HAS_INTEGRAL_COMBINE_DIVISION; +"HAS_INTEGRAL_COMBINE_DIVISION_TOPDOWN",HAS_INTEGRAL_COMBINE_DIVISION_TOPDOWN; +"HAS_INTEGRAL_COMBINE_TAGGED_DIVISION",HAS_INTEGRAL_COMBINE_TAGGED_DIVISION; +"HAS_INTEGRAL_COMBINE_TAGGED_DIVISION_TOPDOWN",HAS_INTEGRAL_COMBINE_TAGGED_DIVISION_TOPDOWN; +"HAS_INTEGRAL_COMPONENTWISE",HAS_INTEGRAL_COMPONENTWISE; +"HAS_INTEGRAL_COMPONENT_LBOUND",HAS_INTEGRAL_COMPONENT_LBOUND; +"HAS_INTEGRAL_COMPONENT_LE",HAS_INTEGRAL_COMPONENT_LE; +"HAS_INTEGRAL_COMPONENT_NEG",HAS_INTEGRAL_COMPONENT_NEG; +"HAS_INTEGRAL_COMPONENT_POS",HAS_INTEGRAL_COMPONENT_POS; +"HAS_INTEGRAL_COMPONENT_UBOUND",HAS_INTEGRAL_COMPONENT_UBOUND; +"HAS_INTEGRAL_CONST",HAS_INTEGRAL_CONST; +"HAS_INTEGRAL_DIFF",HAS_INTEGRAL_DIFF; +"HAS_INTEGRAL_DROP_LE",HAS_INTEGRAL_DROP_LE; +"HAS_INTEGRAL_DROP_NEG",HAS_INTEGRAL_DROP_NEG; +"HAS_INTEGRAL_DROP_POS",HAS_INTEGRAL_DROP_POS; +"HAS_INTEGRAL_EMPTY",HAS_INTEGRAL_EMPTY; +"HAS_INTEGRAL_EMPTY_EQ",HAS_INTEGRAL_EMPTY_EQ; +"HAS_INTEGRAL_EQ",HAS_INTEGRAL_EQ; +"HAS_INTEGRAL_EQ_EQ",HAS_INTEGRAL_EQ_EQ; +"HAS_INTEGRAL_FACTOR_CONTENT",HAS_INTEGRAL_FACTOR_CONTENT; +"HAS_INTEGRAL_INTEGRABLE",HAS_INTEGRAL_INTEGRABLE; +"HAS_INTEGRAL_INTEGRABLE_INTEGRAL",HAS_INTEGRAL_INTEGRABLE_INTEGRAL; +"HAS_INTEGRAL_INTEGRAL",HAS_INTEGRAL_INTEGRAL; +"HAS_INTEGRAL_INTERIOR",HAS_INTEGRAL_INTERIOR; +"HAS_INTEGRAL_IS_0",HAS_INTEGRAL_IS_0; +"HAS_INTEGRAL_LINEAR",HAS_INTEGRAL_LINEAR; +"HAS_INTEGRAL_NEG",HAS_INTEGRAL_NEG; +"HAS_INTEGRAL_NEGLIGIBLE",HAS_INTEGRAL_NEGLIGIBLE; +"HAS_INTEGRAL_NEGLIGIBLE_EQ",HAS_INTEGRAL_NEGLIGIBLE_EQ; +"HAS_INTEGRAL_NORM_BOUND_INTEGRAL_COMPONENT",HAS_INTEGRAL_NORM_BOUND_INTEGRAL_COMPONENT; +"HAS_INTEGRAL_NULL",HAS_INTEGRAL_NULL; +"HAS_INTEGRAL_NULL_EQ",HAS_INTEGRAL_NULL_EQ; +"HAS_INTEGRAL_ON_SUPERSET",HAS_INTEGRAL_ON_SUPERSET; +"HAS_INTEGRAL_OPEN_INTERVAL",HAS_INTEGRAL_OPEN_INTERVAL; +"HAS_INTEGRAL_REFL",HAS_INTEGRAL_REFL; +"HAS_INTEGRAL_REFLECT",HAS_INTEGRAL_REFLECT; +"HAS_INTEGRAL_REFLECT_LEMMA",HAS_INTEGRAL_REFLECT_LEMMA; +"HAS_INTEGRAL_RESTRICT",HAS_INTEGRAL_RESTRICT; +"HAS_INTEGRAL_RESTRICT_CLOSED_SUBINTERVAL",HAS_INTEGRAL_RESTRICT_CLOSED_SUBINTERVAL; +"HAS_INTEGRAL_RESTRICT_CLOSED_SUBINTERVALS_EQ",HAS_INTEGRAL_RESTRICT_CLOSED_SUBINTERVALS_EQ; +"HAS_INTEGRAL_RESTRICT_INTER",HAS_INTEGRAL_RESTRICT_INTER; +"HAS_INTEGRAL_RESTRICT_OPEN_SUBINTERVAL",HAS_INTEGRAL_RESTRICT_OPEN_SUBINTERVAL; +"HAS_INTEGRAL_RESTRICT_UNIV",HAS_INTEGRAL_RESTRICT_UNIV; +"HAS_INTEGRAL_SEPARATE_SIDES",HAS_INTEGRAL_SEPARATE_SIDES; +"HAS_INTEGRAL_SPIKE",HAS_INTEGRAL_SPIKE; +"HAS_INTEGRAL_SPIKE_EQ",HAS_INTEGRAL_SPIKE_EQ; +"HAS_INTEGRAL_SPIKE_FINITE",HAS_INTEGRAL_SPIKE_FINITE; +"HAS_INTEGRAL_SPIKE_FINITE_EQ",HAS_INTEGRAL_SPIKE_FINITE_EQ; +"HAS_INTEGRAL_SPIKE_INTERIOR",HAS_INTEGRAL_SPIKE_INTERIOR; +"HAS_INTEGRAL_SPIKE_INTERIOR_EQ",HAS_INTEGRAL_SPIKE_INTERIOR_EQ; +"HAS_INTEGRAL_SPIKE_SET",HAS_INTEGRAL_SPIKE_SET; +"HAS_INTEGRAL_SPIKE_SET_EQ",HAS_INTEGRAL_SPIKE_SET_EQ; +"HAS_INTEGRAL_SPLIT",HAS_INTEGRAL_SPLIT; +"HAS_INTEGRAL_STRADDLE_NULL",HAS_INTEGRAL_STRADDLE_NULL; +"HAS_INTEGRAL_STRETCH",HAS_INTEGRAL_STRETCH; +"HAS_INTEGRAL_SUB",HAS_INTEGRAL_SUB; +"HAS_INTEGRAL_SUBSET_COMPONENT_LE",HAS_INTEGRAL_SUBSET_COMPONENT_LE; +"HAS_INTEGRAL_SUBSET_DROP_LE",HAS_INTEGRAL_SUBSET_DROP_LE; +"HAS_INTEGRAL_TWIDDLE",HAS_INTEGRAL_TWIDDLE; +"HAS_INTEGRAL_UNION",HAS_INTEGRAL_UNION; +"HAS_INTEGRAL_UNIONS",HAS_INTEGRAL_UNIONS; +"HAS_INTEGRAL_UNIQUE",HAS_INTEGRAL_UNIQUE; +"HAS_INTEGRAL_VSUM",HAS_INTEGRAL_VSUM; +"HAS_MEASURE",HAS_MEASURE; +"HAS_MEASURE_0",HAS_MEASURE_0; +"HAS_MEASURE_AFFINITY",HAS_MEASURE_AFFINITY; +"HAS_MEASURE_ALMOST",HAS_MEASURE_ALMOST; +"HAS_MEASURE_ALMOST_EQ",HAS_MEASURE_ALMOST_EQ; +"HAS_MEASURE_COUNTABLE_NEGLIGIBLE_UNIONS",HAS_MEASURE_COUNTABLE_NEGLIGIBLE_UNIONS; +"HAS_MEASURE_COUNTABLE_NEGLIGIBLE_UNIONS_BOUNDED",HAS_MEASURE_COUNTABLE_NEGLIGIBLE_UNIONS_BOUNDED; +"HAS_MEASURE_DIFF_NEGLIGIBLE",HAS_MEASURE_DIFF_NEGLIGIBLE; +"HAS_MEASURE_DIFF_NEGLIGIBLE_EQ",HAS_MEASURE_DIFF_NEGLIGIBLE_EQ; +"HAS_MEASURE_DIFF_SUBSET",HAS_MEASURE_DIFF_SUBSET; +"HAS_MEASURE_DISJOINT_UNION",HAS_MEASURE_DISJOINT_UNION; +"HAS_MEASURE_DISJOINT_UNIONS",HAS_MEASURE_DISJOINT_UNIONS; +"HAS_MEASURE_DISJOINT_UNIONS_IMAGE",HAS_MEASURE_DISJOINT_UNIONS_IMAGE; +"HAS_MEASURE_DISJOINT_UNIONS_IMAGE_STRONG",HAS_MEASURE_DISJOINT_UNIONS_IMAGE_STRONG; +"HAS_MEASURE_ELEMENTARY",HAS_MEASURE_ELEMENTARY; +"HAS_MEASURE_EMPTY",HAS_MEASURE_EMPTY; +"HAS_MEASURE_IMAGE_STD_SIMPLEX",HAS_MEASURE_IMAGE_STD_SIMPLEX; +"HAS_MEASURE_IMP_MEASURABLE",HAS_MEASURE_IMP_MEASURABLE; +"HAS_MEASURE_INNER_OUTER",HAS_MEASURE_INNER_OUTER; +"HAS_MEASURE_INNER_OUTER_LE",HAS_MEASURE_INNER_OUTER_LE; +"HAS_MEASURE_INTERVAL",HAS_MEASURE_INTERVAL; +"HAS_MEASURE_LIMIT",HAS_MEASURE_LIMIT; +"HAS_MEASURE_LINEAR_IMAGE",HAS_MEASURE_LINEAR_IMAGE; +"HAS_MEASURE_LINEAR_IMAGE_ALT",HAS_MEASURE_LINEAR_IMAGE_ALT; +"HAS_MEASURE_LINEAR_IMAGE_SAME",HAS_MEASURE_LINEAR_IMAGE_SAME; +"HAS_MEASURE_LINEAR_SUFFICIENT",HAS_MEASURE_LINEAR_SUFFICIENT; +"HAS_MEASURE_MEASURABLE_MEASURE",HAS_MEASURE_MEASURABLE_MEASURE; +"HAS_MEASURE_MEASURE",HAS_MEASURE_MEASURE; +"HAS_MEASURE_NEGLIGIBLE_SYMDIFF",HAS_MEASURE_NEGLIGIBLE_SYMDIFF; +"HAS_MEASURE_NEGLIGIBLE_UNION",HAS_MEASURE_NEGLIGIBLE_UNION; +"HAS_MEASURE_NEGLIGIBLE_UNIONS",HAS_MEASURE_NEGLIGIBLE_UNIONS; +"HAS_MEASURE_NEGLIGIBLE_UNIONS_IMAGE",HAS_MEASURE_NEGLIGIBLE_UNIONS_IMAGE; +"HAS_MEASURE_NEGLIGIBLE_UNIONS_IMAGE_STRONG",HAS_MEASURE_NEGLIGIBLE_UNIONS_IMAGE_STRONG; +"HAS_MEASURE_NESTED_INTERS",HAS_MEASURE_NESTED_INTERS; +"HAS_MEASURE_NESTED_UNIONS",HAS_MEASURE_NESTED_UNIONS; +"HAS_MEASURE_ORTHOGONAL_IMAGE",HAS_MEASURE_ORTHOGONAL_IMAGE; +"HAS_MEASURE_ORTHOGONAL_IMAGE_EQ",HAS_MEASURE_ORTHOGONAL_IMAGE_EQ; +"HAS_MEASURE_POS_LE",HAS_MEASURE_POS_LE; +"HAS_MEASURE_SCALING",HAS_MEASURE_SCALING; +"HAS_MEASURE_SCALING_EQ",HAS_MEASURE_SCALING_EQ; +"HAS_MEASURE_SHEAR_INTERVAL",HAS_MEASURE_SHEAR_INTERVAL; +"HAS_MEASURE_SIMPLEX",HAS_MEASURE_SIMPLEX; +"HAS_MEASURE_SIMPLEX_0",HAS_MEASURE_SIMPLEX_0; +"HAS_MEASURE_STD_SIMPLEX",HAS_MEASURE_STD_SIMPLEX; +"HAS_MEASURE_STRETCH",HAS_MEASURE_STRETCH; +"HAS_MEASURE_SUBSET",HAS_MEASURE_SUBSET; +"HAS_MEASURE_TETRAHEDRON",HAS_MEASURE_TETRAHEDRON; +"HAS_MEASURE_TRANSLATION",HAS_MEASURE_TRANSLATION; +"HAS_MEASURE_TRANSLATION_EQ",HAS_MEASURE_TRANSLATION_EQ; +"HAS_MEASURE_TRIANGLE",HAS_MEASURE_TRIANGLE; +"HAS_MEASURE_UNION_NEGLIGIBLE",HAS_MEASURE_UNION_NEGLIGIBLE; +"HAS_MEASURE_UNION_NEGLIGIBLE_EQ",HAS_MEASURE_UNION_NEGLIGIBLE_EQ; +"HAS_MEASURE_UNIQUE",HAS_MEASURE_UNIQUE; +"HAS_SIZE",HAS_SIZE; +"HAS_SIZE_0",HAS_SIZE_0; +"HAS_SIZE_1",HAS_SIZE_1; +"HAS_SIZE_1_EXISTS",HAS_SIZE_1_EXISTS; +"HAS_SIZE_2",HAS_SIZE_2; +"HAS_SIZE_2_EXISTS",HAS_SIZE_2_EXISTS; +"HAS_SIZE_3",HAS_SIZE_3; +"HAS_SIZE_4",HAS_SIZE_4; +"HAS_SIZE_BOOL",HAS_SIZE_BOOL; +"HAS_SIZE_CARD",HAS_SIZE_CARD; +"HAS_SIZE_CART_UNIV",HAS_SIZE_CART_UNIV; +"HAS_SIZE_CLAUSES",HAS_SIZE_CLAUSES; +"HAS_SIZE_CROSS",HAS_SIZE_CROSS; +"HAS_SIZE_DIFF",HAS_SIZE_DIFF; +"HAS_SIZE_FACES_OF_SIMPLEX",HAS_SIZE_FACES_OF_SIMPLEX; +"HAS_SIZE_FINITE_IMAGE",HAS_SIZE_FINITE_IMAGE; +"HAS_SIZE_FUNSPACE",HAS_SIZE_FUNSPACE; +"HAS_SIZE_FUNSPACE_UNIV",HAS_SIZE_FUNSPACE_UNIV; +"HAS_SIZE_IMAGE_INJ",HAS_SIZE_IMAGE_INJ; +"HAS_SIZE_IMAGE_INJ_EQ",HAS_SIZE_IMAGE_INJ_EQ; +"HAS_SIZE_INDEX",HAS_SIZE_INDEX; +"HAS_SIZE_INTSEG_INT",HAS_SIZE_INTSEG_INT; +"HAS_SIZE_INTSEG_NUM",HAS_SIZE_INTSEG_NUM; +"HAS_SIZE_MULTIVECTOR",HAS_SIZE_MULTIVECTOR; +"HAS_SIZE_NUMSEG",HAS_SIZE_NUMSEG; +"HAS_SIZE_NUMSEG_1",HAS_SIZE_NUMSEG_1; +"HAS_SIZE_NUMSEG_LE",HAS_SIZE_NUMSEG_LE; +"HAS_SIZE_NUMSEG_LT",HAS_SIZE_NUMSEG_LT; +"HAS_SIZE_PCROSS",HAS_SIZE_PCROSS; +"HAS_SIZE_PERMUTATIONS",HAS_SIZE_PERMUTATIONS; +"HAS_SIZE_POWERSET",HAS_SIZE_POWERSET; +"HAS_SIZE_PRODUCT",HAS_SIZE_PRODUCT; +"HAS_SIZE_PRODUCT_DEPENDENT",HAS_SIZE_PRODUCT_DEPENDENT; +"HAS_SIZE_SET_OF_LIST",HAS_SIZE_SET_OF_LIST; +"HAS_SIZE_STDBASIS",HAS_SIZE_STDBASIS; +"HAS_SIZE_SUC",HAS_SIZE_SUC; +"HAS_SIZE_UNION",HAS_SIZE_UNION; +"HAS_SIZE_UNIONS",HAS_SIZE_UNIONS; +"HAS_VECTOR_DERIVATIVE_ADD",HAS_VECTOR_DERIVATIVE_ADD; +"HAS_VECTOR_DERIVATIVE_AT_WITHIN",HAS_VECTOR_DERIVATIVE_AT_WITHIN; +"HAS_VECTOR_DERIVATIVE_BILINEAR_AT",HAS_VECTOR_DERIVATIVE_BILINEAR_AT; +"HAS_VECTOR_DERIVATIVE_BILINEAR_WITHIN",HAS_VECTOR_DERIVATIVE_BILINEAR_WITHIN; +"HAS_VECTOR_DERIVATIVE_CMUL",HAS_VECTOR_DERIVATIVE_CMUL; +"HAS_VECTOR_DERIVATIVE_CMUL_EQ",HAS_VECTOR_DERIVATIVE_CMUL_EQ; +"HAS_VECTOR_DERIVATIVE_CONST",HAS_VECTOR_DERIVATIVE_CONST; +"HAS_VECTOR_DERIVATIVE_ID",HAS_VECTOR_DERIVATIVE_ID; +"HAS_VECTOR_DERIVATIVE_INDEFINITE_INTEGRAL",HAS_VECTOR_DERIVATIVE_INDEFINITE_INTEGRAL; +"HAS_VECTOR_DERIVATIVE_NEG",HAS_VECTOR_DERIVATIVE_NEG; +"HAS_VECTOR_DERIVATIVE_NEG_EQ",HAS_VECTOR_DERIVATIVE_NEG_EQ; +"HAS_VECTOR_DERIVATIVE_SUB",HAS_VECTOR_DERIVATIVE_SUB; +"HAS_VECTOR_DERIVATIVE_TRANSFORM_AT",HAS_VECTOR_DERIVATIVE_TRANSFORM_AT; +"HAS_VECTOR_DERIVATIVE_TRANSFORM_WITHIN",HAS_VECTOR_DERIVATIVE_TRANSFORM_WITHIN; +"HAS_VECTOR_DERIVATIVE_TRANSFORM_WITHIN_OPEN",HAS_VECTOR_DERIVATIVE_TRANSFORM_WITHIN_OPEN; +"HAS_VECTOR_DERIVATIVE_UNIQUE_AT",HAS_VECTOR_DERIVATIVE_UNIQUE_AT; +"HAS_VECTOR_DERIVATIVE_WITHIN_SUBSET",HAS_VECTOR_DERIVATIVE_WITHIN_SUBSET; +"HD",HD; +"HD_APPEND",HD_APPEND; +"HEINE_BOREL_IMP_BOLZANO_WEIERSTRASS",HEINE_BOREL_IMP_BOLZANO_WEIERSTRASS; +"HEINE_BOREL_LEMMA",HEINE_BOREL_LEMMA; +"HELLY",HELLY; +"HELLY_ALT",HELLY_ALT; +"HELLY_CLOSED",HELLY_CLOSED; +"HELLY_CLOSED_ALT",HELLY_CLOSED_ALT; +"HELLY_COMPACT",HELLY_COMPACT; +"HELLY_COMPACT_ALT",HELLY_COMPACT_ALT; +"HELLY_INDUCT",HELLY_INDUCT; +"HENSTOCK_LEMMA",HENSTOCK_LEMMA; +"HENSTOCK_LEMMA_PART1",HENSTOCK_LEMMA_PART1; +"HENSTOCK_LEMMA_PART2",HENSTOCK_LEMMA_PART2; +"HOMEOMORPHIC_AFFINE_SETS",HOMEOMORPHIC_AFFINE_SETS; +"HOMEOMORPHIC_AFFINITY",HOMEOMORPHIC_AFFINITY; +"HOMEOMORPHIC_ANRNESS",HOMEOMORPHIC_ANRNESS; +"HOMEOMORPHIC_ARC_IMAGES",HOMEOMORPHIC_ARC_IMAGES; +"HOMEOMORPHIC_ARC_IMAGE_INTERVAL",HOMEOMORPHIC_ARC_IMAGE_INTERVAL; +"HOMEOMORPHIC_ARC_IMAGE_SEGMENT",HOMEOMORPHIC_ARC_IMAGE_SEGMENT; +"HOMEOMORPHIC_BALLS",HOMEOMORPHIC_BALLS; +"HOMEOMORPHIC_BALL_UNIV",HOMEOMORPHIC_BALL_UNIV; +"HOMEOMORPHIC_CBALLS",HOMEOMORPHIC_CBALLS; +"HOMEOMORPHIC_CLOSED_INTERVALS",HOMEOMORPHIC_CLOSED_INTERVALS; +"HOMEOMORPHIC_COMPACT",HOMEOMORPHIC_COMPACT; +"HOMEOMORPHIC_COMPACTNESS",HOMEOMORPHIC_COMPACTNESS; +"HOMEOMORPHIC_COMPACT_ARNESS",HOMEOMORPHIC_COMPACT_ARNESS; +"HOMEOMORPHIC_CONNECTEDNESS",HOMEOMORPHIC_CONNECTEDNESS; +"HOMEOMORPHIC_CONTRACTIBLE",HOMEOMORPHIC_CONTRACTIBLE; +"HOMEOMORPHIC_CONTRACTIBLE_EQ",HOMEOMORPHIC_CONTRACTIBLE_EQ; +"HOMEOMORPHIC_CONVEX_COMPACT",HOMEOMORPHIC_CONVEX_COMPACT; +"HOMEOMORPHIC_CONVEX_COMPACT_CBALL",HOMEOMORPHIC_CONVEX_COMPACT_CBALL; +"HOMEOMORPHIC_CONVEX_COMPACT_SETS",HOMEOMORPHIC_CONVEX_COMPACT_SETS; +"HOMEOMORPHIC_EMPTY",HOMEOMORPHIC_EMPTY; +"HOMEOMORPHIC_FINITE",HOMEOMORPHIC_FINITE; +"HOMEOMORPHIC_FINITE_STRONG",HOMEOMORPHIC_FINITE_STRONG; +"HOMEOMORPHIC_FIXPOINT_PROPERTY",HOMEOMORPHIC_FIXPOINT_PROPERTY; +"HOMEOMORPHIC_HYPERPLANES",HOMEOMORPHIC_HYPERPLANES; +"HOMEOMORPHIC_HYPERPLANE_STANDARD_HYPERPLANE",HOMEOMORPHIC_HYPERPLANE_STANDARD_HYPERPLANE; +"HOMEOMORPHIC_HYPERPLANE_UNIV",HOMEOMORPHIC_HYPERPLANE_UNIV; +"HOMEOMORPHIC_IMP_CARD_EQ",HOMEOMORPHIC_IMP_CARD_EQ; +"HOMEOMORPHIC_IMP_HOMOTOPY_EQUIVALENT",HOMEOMORPHIC_IMP_HOMOTOPY_EQUIVALENT; +"HOMEOMORPHIC_INJECTIVE_LINEAR_IMAGE_LEFT_EQ",HOMEOMORPHIC_INJECTIVE_LINEAR_IMAGE_LEFT_EQ; +"HOMEOMORPHIC_INJECTIVE_LINEAR_IMAGE_RIGHT_EQ",HOMEOMORPHIC_INJECTIVE_LINEAR_IMAGE_RIGHT_EQ; +"HOMEOMORPHIC_INJECTIVE_LINEAR_IMAGE_SELF",HOMEOMORPHIC_INJECTIVE_LINEAR_IMAGE_SELF; +"HOMEOMORPHIC_LOCALLY",HOMEOMORPHIC_LOCALLY; +"HOMEOMORPHIC_LOCAL_COMPACTNESS",HOMEOMORPHIC_LOCAL_COMPACTNESS; +"HOMEOMORPHIC_LOCAL_CONNECTEDNESS",HOMEOMORPHIC_LOCAL_CONNECTEDNESS; +"HOMEOMORPHIC_LOCAL_PATH_CONNECTEDNESS",HOMEOMORPHIC_LOCAL_PATH_CONNECTEDNESS; +"HOMEOMORPHIC_MINIMAL",HOMEOMORPHIC_MINIMAL; +"HOMEOMORPHIC_MONOTONE_IMAGE_INTERVAL",HOMEOMORPHIC_MONOTONE_IMAGE_INTERVAL; +"HOMEOMORPHIC_ONE_POINT_COMPACTIFICATIONS",HOMEOMORPHIC_ONE_POINT_COMPACTIFICATIONS; +"HOMEOMORPHIC_OPEN_INTERVALS",HOMEOMORPHIC_OPEN_INTERVALS; +"HOMEOMORPHIC_OPEN_INTERVALS_1",HOMEOMORPHIC_OPEN_INTERVALS_1; +"HOMEOMORPHIC_OPEN_INTERVAL_UNIV",HOMEOMORPHIC_OPEN_INTERVAL_UNIV; +"HOMEOMORPHIC_OPEN_INTERVAL_UNIV_1",HOMEOMORPHIC_OPEN_INTERVAL_UNIV_1; +"HOMEOMORPHIC_PATH_CONNECTEDNESS",HOMEOMORPHIC_PATH_CONNECTEDNESS; +"HOMEOMORPHIC_PCROSS",HOMEOMORPHIC_PCROSS; +"HOMEOMORPHIC_PCROSS_ASSOC",HOMEOMORPHIC_PCROSS_ASSOC; +"HOMEOMORPHIC_PCROSS_SING",HOMEOMORPHIC_PCROSS_SING; +"HOMEOMORPHIC_PCROSS_SYM",HOMEOMORPHIC_PCROSS_SYM; +"HOMEOMORPHIC_PUNCTURED_AFFINE_SPHERE_AFFINE",HOMEOMORPHIC_PUNCTURED_AFFINE_SPHERE_AFFINE; +"HOMEOMORPHIC_PUNCTURED_SPHERE_AFFINE",HOMEOMORPHIC_PUNCTURED_SPHERE_AFFINE; +"HOMEOMORPHIC_PUNCTURED_SPHERE_AFFINE_GEN",HOMEOMORPHIC_PUNCTURED_SPHERE_AFFINE_GEN; +"HOMEOMORPHIC_PUNCTURED_SPHERE_HYPERPLANE",HOMEOMORPHIC_PUNCTURED_SPHERE_HYPERPLANE; +"HOMEOMORPHIC_PUNCTURED_SPHERE_UNIV",HOMEOMORPHIC_PUNCTURED_SPHERE_UNIV; +"HOMEOMORPHIC_REFL",HOMEOMORPHIC_REFL; +"HOMEOMORPHIC_RELATIVE_FRONTIERS_CONVEX_BOUNDED_SETS",HOMEOMORPHIC_RELATIVE_FRONTIERS_CONVEX_BOUNDED_SETS; +"HOMEOMORPHIC_SCALING",HOMEOMORPHIC_SCALING; +"HOMEOMORPHIC_SCALING_LEFT",HOMEOMORPHIC_SCALING_LEFT; +"HOMEOMORPHIC_SCALING_RIGHT",HOMEOMORPHIC_SCALING_RIGHT; +"HOMEOMORPHIC_SIMPLY_CONNECTED",HOMEOMORPHIC_SIMPLY_CONNECTED; +"HOMEOMORPHIC_SIMPLY_CONNECTED_EQ",HOMEOMORPHIC_SIMPLY_CONNECTED_EQ; +"HOMEOMORPHIC_SING",HOMEOMORPHIC_SING; +"HOMEOMORPHIC_SPHERES",HOMEOMORPHIC_SPHERES; +"HOMEOMORPHIC_STANDARD_HYPERPLANE_HYPERPLANE",HOMEOMORPHIC_STANDARD_HYPERPLANE_HYPERPLANE; +"HOMEOMORPHIC_SUBSPACES",HOMEOMORPHIC_SUBSPACES; +"HOMEOMORPHIC_SYM",HOMEOMORPHIC_SYM; +"HOMEOMORPHIC_TRANS",HOMEOMORPHIC_TRANS; +"HOMEOMORPHIC_TRANSLATION",HOMEOMORPHIC_TRANSLATION; +"HOMEOMORPHIC_TRANSLATION_LEFT_EQ",HOMEOMORPHIC_TRANSLATION_LEFT_EQ; +"HOMEOMORPHIC_TRANSLATION_RIGHT_EQ",HOMEOMORPHIC_TRANSLATION_RIGHT_EQ; +"HOMEOMORPHIC_TRANSLATION_SELF",HOMEOMORPHIC_TRANSLATION_SELF; +"HOMEOMORPHISM",HOMEOMORPHISM; +"HOMEOMORPHISM_ARC",HOMEOMORPHISM_ARC; +"HOMEOMORPHISM_COMPACT",HOMEOMORPHISM_COMPACT; +"HOMEOMORPHISM_COMPOSE",HOMEOMORPHISM_COMPOSE; +"HOMEOMORPHISM_FROM_COMPOSITION_INJECTIVE",HOMEOMORPHISM_FROM_COMPOSITION_INJECTIVE; +"HOMEOMORPHISM_FROM_COMPOSITION_SURJECTIVE",HOMEOMORPHISM_FROM_COMPOSITION_SURJECTIVE; +"HOMEOMORPHISM_GROUPING_POINTS_EXISTS",HOMEOMORPHISM_GROUPING_POINTS_EXISTS; +"HOMEOMORPHISM_GROUPING_POINTS_EXISTS_GEN",HOMEOMORPHISM_GROUPING_POINTS_EXISTS_GEN; +"HOMEOMORPHISM_I",HOMEOMORPHISM_I; +"HOMEOMORPHISM_ID",HOMEOMORPHISM_ID; +"HOMEOMORPHISM_IMP_CLOSED_MAP",HOMEOMORPHISM_IMP_CLOSED_MAP; +"HOMEOMORPHISM_IMP_COVERING_SPACE",HOMEOMORPHISM_IMP_COVERING_SPACE; +"HOMEOMORPHISM_IMP_OPEN_MAP",HOMEOMORPHISM_IMP_OPEN_MAP; +"HOMEOMORPHISM_IMP_QUOTIENT_MAP",HOMEOMORPHISM_IMP_QUOTIENT_MAP; +"HOMEOMORPHISM_INJECTIVE_CLOSED_MAP",HOMEOMORPHISM_INJECTIVE_CLOSED_MAP; +"HOMEOMORPHISM_INJECTIVE_CLOSED_MAP_EQ",HOMEOMORPHISM_INJECTIVE_CLOSED_MAP_EQ; +"HOMEOMORPHISM_INJECTIVE_OPEN_MAP",HOMEOMORPHISM_INJECTIVE_OPEN_MAP; +"HOMEOMORPHISM_INJECTIVE_OPEN_MAP_EQ",HOMEOMORPHISM_INJECTIVE_OPEN_MAP_EQ; +"HOMEOMORPHISM_LOCALLY",HOMEOMORPHISM_LOCALLY; +"HOMEOMORPHISM_MOVING_POINTS_EXISTS",HOMEOMORPHISM_MOVING_POINTS_EXISTS; +"HOMEOMORPHISM_MOVING_POINTS_EXISTS_GEN",HOMEOMORPHISM_MOVING_POINTS_EXISTS_GEN; +"HOMEOMORPHISM_MOVING_POINT_EXISTS",HOMEOMORPHISM_MOVING_POINT_EXISTS; +"HOMEOMORPHISM_OF_SUBSETS",HOMEOMORPHISM_OF_SUBSETS; +"HOMEOMORPHISM_SYM",HOMEOMORPHISM_SYM; +"HOMOGENEOUS_LINEAR_EQUATIONS_DET",HOMOGENEOUS_LINEAR_EQUATIONS_DET; +"HOMOTOPICALLY_TRIVIAL_RETRACTION_GEN",HOMOTOPICALLY_TRIVIAL_RETRACTION_GEN; +"HOMOTOPICALLY_TRIVIAL_RETRACTION_NULL_GEN",HOMOTOPICALLY_TRIVIAL_RETRACTION_NULL_GEN; +"HOMOTOPIC_COMPOSE_CONTINUOUS_LEFT",HOMOTOPIC_COMPOSE_CONTINUOUS_LEFT; +"HOMOTOPIC_COMPOSE_CONTINUOUS_RIGHT",HOMOTOPIC_COMPOSE_CONTINUOUS_RIGHT; +"HOMOTOPIC_CONSTANT_MAPS",HOMOTOPIC_CONSTANT_MAPS; +"HOMOTOPIC_FROM_CONTRACTIBLE",HOMOTOPIC_FROM_CONTRACTIBLE; +"HOMOTOPIC_INTO_CONTRACTIBLE",HOMOTOPIC_INTO_CONTRACTIBLE; +"HOMOTOPIC_JOIN_LEMMA",HOMOTOPIC_JOIN_LEMMA; +"HOMOTOPIC_JOIN_SUBPATHS",HOMOTOPIC_JOIN_SUBPATHS; +"HOMOTOPIC_LOOPS",HOMOTOPIC_LOOPS; +"HOMOTOPIC_LOOPS_ADD_SYM",HOMOTOPIC_LOOPS_ADD_SYM; +"HOMOTOPIC_LOOPS_CONJUGATE",HOMOTOPIC_LOOPS_CONJUGATE; +"HOMOTOPIC_LOOPS_CONTINUOUS_IMAGE",HOMOTOPIC_LOOPS_CONTINUOUS_IMAGE; +"HOMOTOPIC_LOOPS_EQ",HOMOTOPIC_LOOPS_EQ; +"HOMOTOPIC_LOOPS_IMP_HOMOTOPIC_PATHS_NULL",HOMOTOPIC_LOOPS_IMP_HOMOTOPIC_PATHS_NULL; +"HOMOTOPIC_LOOPS_IMP_LOOP",HOMOTOPIC_LOOPS_IMP_LOOP; +"HOMOTOPIC_LOOPS_IMP_PATH",HOMOTOPIC_LOOPS_IMP_PATH; +"HOMOTOPIC_LOOPS_IMP_PATH_COMPONENT_VALUE",HOMOTOPIC_LOOPS_IMP_PATH_COMPONENT_VALUE; +"HOMOTOPIC_LOOPS_IMP_SUBSET",HOMOTOPIC_LOOPS_IMP_SUBSET; +"HOMOTOPIC_LOOPS_LINEAR",HOMOTOPIC_LOOPS_LINEAR; +"HOMOTOPIC_LOOPS_NEARBY_EXPLICIT",HOMOTOPIC_LOOPS_NEARBY_EXPLICIT; +"HOMOTOPIC_LOOPS_REFL",HOMOTOPIC_LOOPS_REFL; +"HOMOTOPIC_LOOPS_SHIFTPATH",HOMOTOPIC_LOOPS_SHIFTPATH; +"HOMOTOPIC_LOOPS_SHIFTPATH_SELF",HOMOTOPIC_LOOPS_SHIFTPATH_SELF; +"HOMOTOPIC_LOOPS_SUBSET",HOMOTOPIC_LOOPS_SUBSET; +"HOMOTOPIC_LOOPS_SYM",HOMOTOPIC_LOOPS_SYM; +"HOMOTOPIC_LOOPS_TRANS",HOMOTOPIC_LOOPS_TRANS; +"HOMOTOPIC_NEARBY_LOOPS",HOMOTOPIC_NEARBY_LOOPS; +"HOMOTOPIC_NEARBY_PATHS",HOMOTOPIC_NEARBY_PATHS; +"HOMOTOPIC_NON_ANTIPODAL_SPHEREMAPS",HOMOTOPIC_NON_ANTIPODAL_SPHEREMAPS; +"HOMOTOPIC_NON_MIDPOINT_SPHEREMAPS",HOMOTOPIC_NON_MIDPOINT_SPHEREMAPS; +"HOMOTOPIC_PATHS",HOMOTOPIC_PATHS; +"HOMOTOPIC_PATHS_ASSOC",HOMOTOPIC_PATHS_ASSOC; +"HOMOTOPIC_PATHS_CONTINUOUS_IMAGE",HOMOTOPIC_PATHS_CONTINUOUS_IMAGE; +"HOMOTOPIC_PATHS_EQ",HOMOTOPIC_PATHS_EQ; +"HOMOTOPIC_PATHS_IMP_HOMOTOPIC_LOOPS",HOMOTOPIC_PATHS_IMP_HOMOTOPIC_LOOPS; +"HOMOTOPIC_PATHS_IMP_PATH",HOMOTOPIC_PATHS_IMP_PATH; +"HOMOTOPIC_PATHS_IMP_PATHFINISH",HOMOTOPIC_PATHS_IMP_PATHFINISH; +"HOMOTOPIC_PATHS_IMP_PATHSTART",HOMOTOPIC_PATHS_IMP_PATHSTART; +"HOMOTOPIC_PATHS_IMP_SUBSET",HOMOTOPIC_PATHS_IMP_SUBSET; +"HOMOTOPIC_PATHS_JOIN",HOMOTOPIC_PATHS_JOIN; +"HOMOTOPIC_PATHS_LID",HOMOTOPIC_PATHS_LID; +"HOMOTOPIC_PATHS_LINEAR",HOMOTOPIC_PATHS_LINEAR; +"HOMOTOPIC_PATHS_LINV",HOMOTOPIC_PATHS_LINV; +"HOMOTOPIC_PATHS_LOOP_PARTS",HOMOTOPIC_PATHS_LOOP_PARTS; +"HOMOTOPIC_PATHS_NEARBY_EXPLICIT",HOMOTOPIC_PATHS_NEARBY_EXPLICIT; +"HOMOTOPIC_PATHS_REFL",HOMOTOPIC_PATHS_REFL; +"HOMOTOPIC_PATHS_REPARAMETRIZE",HOMOTOPIC_PATHS_REPARAMETRIZE; +"HOMOTOPIC_PATHS_REVERSEPATH",HOMOTOPIC_PATHS_REVERSEPATH; +"HOMOTOPIC_PATHS_RID",HOMOTOPIC_PATHS_RID; +"HOMOTOPIC_PATHS_RINV",HOMOTOPIC_PATHS_RINV; +"HOMOTOPIC_PATHS_SUBSET",HOMOTOPIC_PATHS_SUBSET; +"HOMOTOPIC_PATHS_SYM",HOMOTOPIC_PATHS_SYM; +"HOMOTOPIC_PATHS_TRANS",HOMOTOPIC_PATHS_TRANS; +"HOMOTOPIC_POINTS_EQ_PATH_COMPONENT",HOMOTOPIC_POINTS_EQ_PATH_COMPONENT; +"HOMOTOPIC_THROUGH_CONTRACTIBLE",HOMOTOPIC_THROUGH_CONTRACTIBLE; +"HOMOTOPIC_TRIVIALITY",HOMOTOPIC_TRIVIALITY; +"HOMOTOPIC_WITH",HOMOTOPIC_WITH; +"HOMOTOPIC_WITH_COMPOSE_CONTINUOUS_LEFT",HOMOTOPIC_WITH_COMPOSE_CONTINUOUS_LEFT; +"HOMOTOPIC_WITH_COMPOSE_CONTINUOUS_RIGHT",HOMOTOPIC_WITH_COMPOSE_CONTINUOUS_RIGHT; +"HOMOTOPIC_WITH_EQ",HOMOTOPIC_WITH_EQ; +"HOMOTOPIC_WITH_EQUAL",HOMOTOPIC_WITH_EQUAL; +"HOMOTOPIC_WITH_IMP_CONTINUOUS",HOMOTOPIC_WITH_IMP_CONTINUOUS; +"HOMOTOPIC_WITH_IMP_PROPERTY",HOMOTOPIC_WITH_IMP_PROPERTY; +"HOMOTOPIC_WITH_IMP_SUBSET",HOMOTOPIC_WITH_IMP_SUBSET; +"HOMOTOPIC_WITH_LINEAR",HOMOTOPIC_WITH_LINEAR; +"HOMOTOPIC_WITH_MONO",HOMOTOPIC_WITH_MONO; +"HOMOTOPIC_WITH_PCROSS",HOMOTOPIC_WITH_PCROSS; +"HOMOTOPIC_WITH_REFL",HOMOTOPIC_WITH_REFL; +"HOMOTOPIC_WITH_SUBSET_LEFT",HOMOTOPIC_WITH_SUBSET_LEFT; +"HOMOTOPIC_WITH_SUBSET_RIGHT",HOMOTOPIC_WITH_SUBSET_RIGHT; +"HOMOTOPIC_WITH_SYM",HOMOTOPIC_WITH_SYM; +"HOMOTOPIC_WITH_TRANS",HOMOTOPIC_WITH_TRANS; +"HOMOTOPY_EQUIVALENT",HOMOTOPY_EQUIVALENT; +"HOMOTOPY_EQUIVALENT_COHOMOTOPIC_TRIVIALITY",HOMOTOPY_EQUIVALENT_COHOMOTOPIC_TRIVIALITY; +"HOMOTOPY_EQUIVALENT_COHOMOTOPIC_TRIVIALITY_NULL",HOMOTOPY_EQUIVALENT_COHOMOTOPIC_TRIVIALITY_NULL; +"HOMOTOPY_EQUIVALENT_CONNECTEDNESS",HOMOTOPY_EQUIVALENT_CONNECTEDNESS; +"HOMOTOPY_EQUIVALENT_CONTRACTIBILITY",HOMOTOPY_EQUIVALENT_CONTRACTIBILITY; +"HOMOTOPY_EQUIVALENT_CONTRACTIBLE_SETS",HOMOTOPY_EQUIVALENT_CONTRACTIBLE_SETS; +"HOMOTOPY_EQUIVALENT_EMPTY",HOMOTOPY_EQUIVALENT_EMPTY; +"HOMOTOPY_EQUIVALENT_HOMOTOPIC_TRIVIALITY",HOMOTOPY_EQUIVALENT_HOMOTOPIC_TRIVIALITY; +"HOMOTOPY_EQUIVALENT_HOMOTOPIC_TRIVIALITY_NULL",HOMOTOPY_EQUIVALENT_HOMOTOPIC_TRIVIALITY_NULL; +"HOMOTOPY_EQUIVALENT_INJECTIVE_LINEAR_IMAGE_LEFT_EQ",HOMOTOPY_EQUIVALENT_INJECTIVE_LINEAR_IMAGE_LEFT_EQ; +"HOMOTOPY_EQUIVALENT_INJECTIVE_LINEAR_IMAGE_RIGHT_EQ",HOMOTOPY_EQUIVALENT_INJECTIVE_LINEAR_IMAGE_RIGHT_EQ; +"HOMOTOPY_EQUIVALENT_INJECTIVE_LINEAR_IMAGE_SELF",HOMOTOPY_EQUIVALENT_INJECTIVE_LINEAR_IMAGE_SELF; +"HOMOTOPY_EQUIVALENT_PATH_CONNECTEDNESS",HOMOTOPY_EQUIVALENT_PATH_CONNECTEDNESS; +"HOMOTOPY_EQUIVALENT_REFL",HOMOTOPY_EQUIVALENT_REFL; +"HOMOTOPY_EQUIVALENT_SING",HOMOTOPY_EQUIVALENT_SING; +"HOMOTOPY_EQUIVALENT_SYM",HOMOTOPY_EQUIVALENT_SYM; +"HOMOTOPY_EQUIVALENT_TRANS",HOMOTOPY_EQUIVALENT_TRANS; +"HOMOTOPY_EQUIVALENT_TRANSLATION_LEFT_EQ",HOMOTOPY_EQUIVALENT_TRANSLATION_LEFT_EQ; +"HOMOTOPY_EQUIVALENT_TRANSLATION_RIGHT_EQ",HOMOTOPY_EQUIVALENT_TRANSLATION_RIGHT_EQ; +"HOMOTOPY_EQUIVALENT_TRANSLATION_SELF",HOMOTOPY_EQUIVALENT_TRANSLATION_SELF; +"HOMOTOPY_INVARIANT_CONNECTEDNESS",HOMOTOPY_INVARIANT_CONNECTEDNESS; +"HOMOTOPY_INVARIANT_PATH_CONNECTEDNESS",HOMOTOPY_INVARIANT_PATH_CONNECTEDNESS; +"HP",HP; +"HREAL_ADD_AC",HREAL_ADD_AC; +"HREAL_ADD_ASSOC",HREAL_ADD_ASSOC; +"HREAL_ADD_LCANCEL",HREAL_ADD_LCANCEL; +"HREAL_ADD_LDISTRIB",HREAL_ADD_LDISTRIB; +"HREAL_ADD_LID",HREAL_ADD_LID; +"HREAL_ADD_RDISTRIB",HREAL_ADD_RDISTRIB; +"HREAL_ADD_RID",HREAL_ADD_RID; +"HREAL_ADD_SYM",HREAL_ADD_SYM; +"HREAL_ARCH",HREAL_ARCH; +"HREAL_COMPLETE",HREAL_COMPLETE; +"HREAL_EQ_ADD_LCANCEL",HREAL_EQ_ADD_LCANCEL; +"HREAL_EQ_ADD_RCANCEL",HREAL_EQ_ADD_RCANCEL; +"HREAL_INV_0",HREAL_INV_0; +"HREAL_LE_ADD",HREAL_LE_ADD; +"HREAL_LE_ADD2",HREAL_LE_ADD2; +"HREAL_LE_ADD_LCANCEL",HREAL_LE_ADD_LCANCEL; +"HREAL_LE_ADD_RCANCEL",HREAL_LE_ADD_RCANCEL; +"HREAL_LE_ANTISYM",HREAL_LE_ANTISYM; +"HREAL_LE_EXISTS",HREAL_LE_EXISTS; +"HREAL_LE_EXISTS_DEF",HREAL_LE_EXISTS_DEF; +"HREAL_LE_MUL_RCANCEL_IMP",HREAL_LE_MUL_RCANCEL_IMP; +"HREAL_LE_REFL",HREAL_LE_REFL; +"HREAL_LE_TOTAL",HREAL_LE_TOTAL; +"HREAL_LE_TRANS",HREAL_LE_TRANS; +"HREAL_MUL_ASSOC",HREAL_MUL_ASSOC; +"HREAL_MUL_LID",HREAL_MUL_LID; +"HREAL_MUL_LINV",HREAL_MUL_LINV; +"HREAL_MUL_LZERO",HREAL_MUL_LZERO; +"HREAL_MUL_RZERO",HREAL_MUL_RZERO; +"HREAL_MUL_SYM",HREAL_MUL_SYM; +"HREAL_OF_NUM_ADD",HREAL_OF_NUM_ADD; +"HREAL_OF_NUM_EQ",HREAL_OF_NUM_EQ; +"HREAL_OF_NUM_LE",HREAL_OF_NUM_LE; +"HREAL_OF_NUM_MUL",HREAL_OF_NUM_MUL; +"HULLS_EQ",HULLS_EQ; +"HULL_ANTIMONO",HULL_ANTIMONO; +"HULL_EQ",HULL_EQ; +"HULL_HULL",HULL_HULL; +"HULL_IMAGE",HULL_IMAGE; +"HULL_IMAGE_GALOIS",HULL_IMAGE_GALOIS; +"HULL_IMAGE_SUBSET",HULL_IMAGE_SUBSET; +"HULL_INC",HULL_INC; +"HULL_INDUCT",HULL_INDUCT; +"HULL_MINIMAL",HULL_MINIMAL; +"HULL_MONO",HULL_MONO; +"HULL_P",HULL_P; +"HULL_P_AND_Q",HULL_P_AND_Q; +"HULL_REDUNDANT",HULL_REDUNDANT; +"HULL_REDUNDANT_EQ",HULL_REDUNDANT_EQ; +"HULL_SUBSET",HULL_SUBSET; +"HULL_UNION",HULL_UNION; +"HULL_UNION_LEFT",HULL_UNION_LEFT; +"HULL_UNION_RIGHT",HULL_UNION_RIGHT; +"HULL_UNION_SUBSET",HULL_UNION_SUBSET; +"HULL_UNIQUE",HULL_UNIQUE; +"HYPERPLANE_EQ_EMPTY",HYPERPLANE_EQ_EMPTY; +"HYPERPLANE_EQ_UNIV",HYPERPLANE_EQ_UNIV; +"HYPERPLANE_FACET_OF_HALFSPACE_GE",HYPERPLANE_FACET_OF_HALFSPACE_GE; +"HYPERPLANE_FACET_OF_HALFSPACE_LE",HYPERPLANE_FACET_OF_HALFSPACE_LE; +"HYPERPLANE_FACE_OF_HALFSPACE_GE",HYPERPLANE_FACE_OF_HALFSPACE_GE; +"HYPERPLANE_FACE_OF_HALFSPACE_LE",HYPERPLANE_FACE_OF_HALFSPACE_LE; +"IDEMPOTENT_IMP_RETRACTION",IDEMPOTENT_IMP_RETRACTION; +"IMAGE",IMAGE; +"IMAGE_AFFINITY_INTERVAL",IMAGE_AFFINITY_INTERVAL; +"IMAGE_CLAUSES",IMAGE_CLAUSES; +"IMAGE_CLOSURE_SUBSET",IMAGE_CLOSURE_SUBSET; +"IMAGE_COMPOSE_PERMUTATIONS_L",IMAGE_COMPOSE_PERMUTATIONS_L; +"IMAGE_COMPOSE_PERMUTATIONS_R",IMAGE_COMPOSE_PERMUTATIONS_R; +"IMAGE_CONST",IMAGE_CONST; +"IMAGE_DELETE_INJ",IMAGE_DELETE_INJ; +"IMAGE_DIFF_INJ",IMAGE_DIFF_INJ; +"IMAGE_DROP_UNIV",IMAGE_DROP_UNIV; +"IMAGE_EQ_EMPTY",IMAGE_EQ_EMPTY; +"IMAGE_FSTCART_PCROSS",IMAGE_FSTCART_PCROSS; +"IMAGE_I",IMAGE_I; +"IMAGE_ID",IMAGE_ID; +"IMAGE_IMP_INJECTIVE",IMAGE_IMP_INJECTIVE; +"IMAGE_IMP_INJECTIVE_GEN",IMAGE_IMP_INJECTIVE_GEN; +"IMAGE_INJECTIVE_IMAGE_OF_SUBSET",IMAGE_INJECTIVE_IMAGE_OF_SUBSET; +"IMAGE_INTER_INJ",IMAGE_INTER_INJ; +"IMAGE_INVERSE_PERMUTATIONS",IMAGE_INVERSE_PERMUTATIONS; +"IMAGE_LEMMA_0",IMAGE_LEMMA_0; +"IMAGE_LEMMA_1",IMAGE_LEMMA_1; +"IMAGE_LEMMA_2",IMAGE_LEMMA_2; +"IMAGE_LIFT_DROP",IMAGE_LIFT_DROP; +"IMAGE_LIFT_UNIV",IMAGE_LIFT_UNIV; +"IMAGE_SNDCART_PCROSS",IMAGE_SNDCART_PCROSS; +"IMAGE_STRETCH_INTERVAL",IMAGE_STRETCH_INTERVAL; +"IMAGE_SUBSET",IMAGE_SUBSET; +"IMAGE_UNION",IMAGE_UNION; +"IMAGE_UNIONS",IMAGE_UNIONS; +"IMAGE_o",IMAGE_o; +"IMP_CLAUSES",IMP_CLAUSES; +"IMP_CONJ",IMP_CONJ; +"IMP_CONJ_ALT",IMP_CONJ_ALT; +"IMP_DEF",IMP_DEF; +"IMP_IMP",IMP_IMP; +"IN",IN; +"INCREASING_BOUNDED_VARIATION",INCREASING_BOUNDED_VARIATION; +"INCREASING_LEFT_LIMIT_1",INCREASING_LEFT_LIMIT_1; +"INCREASING_RIGHT_LIMIT_1",INCREASING_RIGHT_LIMIT_1; +"INCREASING_VECTOR_VARIATION",INCREASING_VECTOR_VARIATION; +"INDEFINITE_INTEGRAL_CONTINUOUS",INDEFINITE_INTEGRAL_CONTINUOUS; +"INDEFINITE_INTEGRAL_CONTINUOUS_LEFT",INDEFINITE_INTEGRAL_CONTINUOUS_LEFT; +"INDEFINITE_INTEGRAL_CONTINUOUS_RIGHT",INDEFINITE_INTEGRAL_CONTINUOUS_RIGHT; +"INDEFINITE_INTEGRAL_UNIFORMLY_CONTINUOUS",INDEFINITE_INTEGRAL_UNIFORMLY_CONTINUOUS; +"INDEFINITE_INTEGRAL_UNIFORMLY_CONTINUOUS_EXPLICIT",INDEFINITE_INTEGRAL_UNIFORMLY_CONTINUOUS_EXPLICIT; +"INDEPENDENT_2",INDEPENDENT_2; +"INDEPENDENT_3",INDEPENDENT_3; +"INDEPENDENT_BOUND",INDEPENDENT_BOUND; +"INDEPENDENT_BOUND_GENERAL",INDEPENDENT_BOUND_GENERAL; +"INDEPENDENT_CARD_LE_DIM",INDEPENDENT_CARD_LE_DIM; +"INDEPENDENT_EMPTY",INDEPENDENT_EMPTY; +"INDEPENDENT_EXPLICIT",INDEPENDENT_EXPLICIT; +"INDEPENDENT_IMP_AFFINE_DEPENDENT_0",INDEPENDENT_IMP_AFFINE_DEPENDENT_0; +"INDEPENDENT_IMP_FINITE",INDEPENDENT_IMP_FINITE; +"INDEPENDENT_INJECTIVE_IMAGE",INDEPENDENT_INJECTIVE_IMAGE; +"INDEPENDENT_INJECTIVE_IMAGE_GEN",INDEPENDENT_INJECTIVE_IMAGE_GEN; +"INDEPENDENT_INSERT",INDEPENDENT_INSERT; +"INDEPENDENT_LINEAR_IMAGE_EQ",INDEPENDENT_LINEAR_IMAGE_EQ; +"INDEPENDENT_MONO",INDEPENDENT_MONO; +"INDEPENDENT_NONZERO",INDEPENDENT_NONZERO; +"INDEPENDENT_SING",INDEPENDENT_SING; +"INDEPENDENT_SPAN_BOUND",INDEPENDENT_SPAN_BOUND; +"INDEPENDENT_STDBASIS",INDEPENDENT_STDBASIS; +"INDUCT_LINEAR_ELEMENTARY",INDUCT_LINEAR_ELEMENTARY; +"INDUCT_MATRIX_ELEMENTARY",INDUCT_MATRIX_ELEMENTARY; +"INDUCT_MATRIX_ELEMENTARY_ALT",INDUCT_MATRIX_ELEMENTARY_ALT; +"INDUCT_MATRIX_ROW_OPERATIONS",INDUCT_MATRIX_ROW_OPERATIONS; +"IND_SUC_0",IND_SUC_0; +"IND_SUC_0_EXISTS",IND_SUC_0_EXISTS; +"IND_SUC_INJ",IND_SUC_INJ; +"IND_SUC_SPEC",IND_SUC_SPEC; +"INF",INF; +"INFINITE",INFINITE; +"INFINITE_ARC_IMAGE",INFINITE_ARC_IMAGE; +"INFINITE_CARD_LE",INFINITE_CARD_LE; +"INFINITE_DIFF_FINITE",INFINITE_DIFF_FINITE; +"INFINITE_ENUMERATE",INFINITE_ENUMERATE; +"INFINITE_FROM",INFINITE_FROM; +"INFINITE_IMAGE_INJ",INFINITE_IMAGE_INJ; +"INFINITE_INTEGER",INFINITE_INTEGER; +"INFINITE_NONEMPTY",INFINITE_NONEMPTY; +"INFINITE_OPEN_IN",INFINITE_OPEN_IN; +"INFINITE_RATIONAL",INFINITE_RATIONAL; +"INFINITE_SIMPLE_PATH_IMAGE",INFINITE_SIMPLE_PATH_IMAGE; +"INFINITE_SUPERSET",INFINITE_SUPERSET; +"INFINITY_AX",INFINITY_AX; +"INFNORM_0",INFNORM_0; +"INFNORM_2",INFNORM_2; +"INFNORM_EQ_0",INFNORM_EQ_0; +"INFNORM_EQ_1_2",INFNORM_EQ_1_2; +"INFNORM_EQ_1_IMP",INFNORM_EQ_1_IMP; +"INFNORM_LE_NORM",INFNORM_LE_NORM; +"INFNORM_MUL",INFNORM_MUL; +"INFNORM_MUL_LEMMA",INFNORM_MUL_LEMMA; +"INFNORM_NEG",INFNORM_NEG; +"INFNORM_POS_LE",INFNORM_POS_LE; +"INFNORM_POS_LT",INFNORM_POS_LT; +"INFNORM_SET_IMAGE",INFNORM_SET_IMAGE; +"INFNORM_SET_LEMMA",INFNORM_SET_LEMMA; +"INFNORM_SUB",INFNORM_SUB; +"INFNORM_TRIANGLE",INFNORM_TRIANGLE; +"INFSUM_0",INFSUM_0; +"INFSUM_ADD",INFSUM_ADD; +"INFSUM_CMUL",INFSUM_CMUL; +"INFSUM_EQ",INFSUM_EQ; +"INFSUM_LINEAR",INFSUM_LINEAR; +"INFSUM_NEG",INFSUM_NEG; +"INFSUM_RESTRICT",INFSUM_RESTRICT; +"INFSUM_SUB",INFSUM_SUB; +"INFSUM_UNIQUE",INFSUM_UNIQUE; +"INF_EQ",INF_EQ; +"INF_FINITE",INF_FINITE; +"INF_FINITE_LEMMA",INF_FINITE_LEMMA; +"INF_INSERT",INF_INSERT; +"INF_INSERT_FINITE",INF_INSERT_FINITE; +"INF_SING",INF_SING; +"INF_UNIQUE_FINITE",INF_UNIQUE_FINITE; +"INJ",INJ; +"INJA",INJA; +"INJA_INJ",INJA_INJ; +"INJECTIVE_ALT",INJECTIVE_ALT; +"INJECTIVE_IMAGE",INJECTIVE_IMAGE; +"INJECTIVE_IMP_ISOMETRIC",INJECTIVE_IMP_ISOMETRIC; +"INJECTIVE_INTO_1D_EQ_HOMEOMORPHISM",INJECTIVE_INTO_1D_EQ_HOMEOMORPHISM; +"INJECTIVE_INTO_1D_IMP_OPEN_MAP",INJECTIVE_INTO_1D_IMP_OPEN_MAP; +"INJECTIVE_INVERSE",INJECTIVE_INVERSE; +"INJECTIVE_INVERSE_o",INJECTIVE_INVERSE_o; +"INJECTIVE_LEFT_INVERSE",INJECTIVE_LEFT_INVERSE; +"INJECTIVE_LEFT_INVERSE_NONEMPTY",INJECTIVE_LEFT_INVERSE_NONEMPTY; +"INJECTIVE_MAP",INJECTIVE_MAP; +"INJECTIVE_MAP_OPEN_IFF_CLOSED",INJECTIVE_MAP_OPEN_IFF_CLOSED; +"INJECTIVE_ON_ALT",INJECTIVE_ON_ALT; +"INJECTIVE_ON_IMAGE",INJECTIVE_ON_IMAGE; +"INJECTIVE_ON_LEFT_INVERSE",INJECTIVE_ON_LEFT_INVERSE; +"INJECTIVE_SCALING",INJECTIVE_SCALING; +"INJF",INJF; +"INJF_INJ",INJF_INJ; +"INJN",INJN; +"INJN_INJ",INJN_INJ; +"INJP",INJP; +"INJP_INJ",INJP_INJ; +"INJ_INVERSE2",INJ_INVERSE2; +"INNER_LADD",INNER_LADD; +"INNER_LMUL",INNER_LMUL; +"INNER_LNEG",INNER_LNEG; +"INNER_LZERO",INNER_LZERO; +"INNER_RADD",INNER_RADD; +"INNER_RMUL",INNER_RMUL; +"INNER_RNEG",INNER_RNEG; +"INNER_RZERO",INNER_RZERO; +"INSEG_LINSEG",INSEG_LINSEG; +"INSEG_PROPER_SUBSET",INSEG_PROPER_SUBSET; +"INSEG_PROPER_SUBSET_FL",INSEG_PROPER_SUBSET_FL; +"INSEG_SUBSET",INSEG_SUBSET; +"INSEG_SUBSET_FL",INSEG_SUBSET_FL; +"INSEG_WOSET",INSEG_WOSET; +"INSERT",INSERT; +"INSERT_AC",INSERT_AC; +"INSERT_COMM",INSERT_COMM; +"INSERT_DEF",INSERT_DEF; +"INSERT_DELETE",INSERT_DELETE; +"INSERT_DIFF",INSERT_DIFF; +"INSERT_INSERT",INSERT_INSERT; +"INSERT_INTER",INSERT_INTER; +"INSERT_SUBSET",INSERT_SUBSET; +"INSERT_UNION",INSERT_UNION; +"INSERT_UNION_EQ",INSERT_UNION_EQ; +"INSERT_UNIV",INSERT_UNIV; +"INSIDE_ARC_EMPTY",INSIDE_ARC_EMPTY; +"INSIDE_BOUNDED_COMPLEMENT_CONNECTED_EMPTY",INSIDE_BOUNDED_COMPLEMENT_CONNECTED_EMPTY; +"INSIDE_COMPLEMENT_UNBOUNDED_CONNECTED_EMPTY",INSIDE_COMPLEMENT_UNBOUNDED_CONNECTED_EMPTY; +"INSIDE_CONNECTED_COMPONENT_LE",INSIDE_CONNECTED_COMPONENT_LE; +"INSIDE_CONNECTED_COMPONENT_LT",INSIDE_CONNECTED_COMPONENT_LT; +"INSIDE_CONVEX",INSIDE_CONVEX; +"INSIDE_EMPTY",INSIDE_EMPTY; +"INSIDE_EQ_OUTSIDE",INSIDE_EQ_OUTSIDE; +"INSIDE_FRONTIER_EQ_INTERIOR",INSIDE_FRONTIER_EQ_INTERIOR; +"INSIDE_INSIDE",INSIDE_INSIDE; +"INSIDE_INSIDE_COMPACT_CONNECTED",INSIDE_INSIDE_COMPACT_CONNECTED; +"INSIDE_INSIDE_EQ_EMPTY",INSIDE_INSIDE_EQ_EMPTY; +"INSIDE_INSIDE_SUBSET",INSIDE_INSIDE_SUBSET; +"INSIDE_INTER_OUTSIDE",INSIDE_INTER_OUTSIDE; +"INSIDE_IN_COMPONENTS",INSIDE_IN_COMPONENTS; +"INSIDE_LINEAR_IMAGE",INSIDE_LINEAR_IMAGE; +"INSIDE_MONO",INSIDE_MONO; +"INSIDE_NO_OVERLAP",INSIDE_NO_OVERLAP; +"INSIDE_OF_TRIANGLE",INSIDE_OF_TRIANGLE; +"INSIDE_OUTSIDE",INSIDE_OUTSIDE; +"INSIDE_OUTSIDE_INTERSECT_CONNECTED",INSIDE_OUTSIDE_INTERSECT_CONNECTED; +"INSIDE_OUTSIDE_UNIQUE",INSIDE_OUTSIDE_UNIQUE; +"INSIDE_SAME_COMPONENT",INSIDE_SAME_COMPONENT; +"INSIDE_SIMPLE_CURVE_IMP_CLOSED",INSIDE_SIMPLE_CURVE_IMP_CLOSED; +"INSIDE_SUBSET",INSIDE_SUBSET; +"INSIDE_TRANSLATION",INSIDE_TRANSLATION; +"INSIDE_UNION_OUTSIDE",INSIDE_UNION_OUTSIDE; +"INSIDE_UNIQUE",INSIDE_UNIQUE; +"INTEGER_ABS",INTEGER_ABS; +"INTEGER_ABS_MUL_EQ_1",INTEGER_ABS_MUL_EQ_1; +"INTEGER_ADD",INTEGER_ADD; +"INTEGER_ADD_EQ",INTEGER_ADD_EQ; +"INTEGER_CASES",INTEGER_CASES; +"INTEGER_CLOSED",INTEGER_CLOSED; +"INTEGER_DET",INTEGER_DET; +"INTEGER_EXISTS_BETWEEN",INTEGER_EXISTS_BETWEEN; +"INTEGER_EXISTS_BETWEEN_ABS",INTEGER_EXISTS_BETWEEN_ABS; +"INTEGER_EXISTS_BETWEEN_ABS_LT",INTEGER_EXISTS_BETWEEN_ABS_LT; +"INTEGER_EXISTS_BETWEEN_ALT",INTEGER_EXISTS_BETWEEN_ALT; +"INTEGER_EXISTS_BETWEEN_LT",INTEGER_EXISTS_BETWEEN_LT; +"INTEGER_MUL",INTEGER_MUL; +"INTEGER_NEG",INTEGER_NEG; +"INTEGER_POS",INTEGER_POS; +"INTEGER_POW",INTEGER_POW; +"INTEGER_PRODUCT",INTEGER_PRODUCT; +"INTEGER_ROUND",INTEGER_ROUND; +"INTEGER_SIGN",INTEGER_SIGN; +"INTEGER_SUB",INTEGER_SUB; +"INTEGER_SUB_EQ",INTEGER_SUB_EQ; +"INTEGER_SUM",INTEGER_SUM; +"INTEGRABLE_0",INTEGRABLE_0; +"INTEGRABLE_ADD",INTEGRABLE_ADD; +"INTEGRABLE_AFFINITY",INTEGRABLE_AFFINITY; +"INTEGRABLE_ALT",INTEGRABLE_ALT; +"INTEGRABLE_ALT_SUBSET",INTEGRABLE_ALT_SUBSET; +"INTEGRABLE_CAUCHY",INTEGRABLE_CAUCHY; +"INTEGRABLE_CCONTINUOUS_EXPLICIT",INTEGRABLE_CCONTINUOUS_EXPLICIT; +"INTEGRABLE_CCONTINUOUS_EXPLICIT_SYMMETRIC",INTEGRABLE_CCONTINUOUS_EXPLICIT_SYMMETRIC; +"INTEGRABLE_CMUL",INTEGRABLE_CMUL; +"INTEGRABLE_COMBINE",INTEGRABLE_COMBINE; +"INTEGRABLE_COMBINE_DIVISION",INTEGRABLE_COMBINE_DIVISION; +"INTEGRABLE_COMPONENTWISE",INTEGRABLE_COMPONENTWISE; +"INTEGRABLE_CONST",INTEGRABLE_CONST; +"INTEGRABLE_CONTINUOUS",INTEGRABLE_CONTINUOUS; +"INTEGRABLE_DECREASING",INTEGRABLE_DECREASING; +"INTEGRABLE_DECREASING_1",INTEGRABLE_DECREASING_1; +"INTEGRABLE_DECREASING_PRODUCT",INTEGRABLE_DECREASING_PRODUCT; +"INTEGRABLE_DECREASING_PRODUCT_UNIV",INTEGRABLE_DECREASING_PRODUCT_UNIV; +"INTEGRABLE_EQ",INTEGRABLE_EQ; +"INTEGRABLE_IMP_MEASURABLE",INTEGRABLE_IMP_MEASURABLE; +"INTEGRABLE_INCREASING",INTEGRABLE_INCREASING; +"INTEGRABLE_INCREASING_1",INTEGRABLE_INCREASING_1; +"INTEGRABLE_INCREASING_PRODUCT",INTEGRABLE_INCREASING_PRODUCT; +"INTEGRABLE_INCREASING_PRODUCT_UNIV",INTEGRABLE_INCREASING_PRODUCT_UNIV; +"INTEGRABLE_INTEGRAL",INTEGRABLE_INTEGRAL; +"INTEGRABLE_LINEAR",INTEGRABLE_LINEAR; +"INTEGRABLE_MIN_CONST_1",INTEGRABLE_MIN_CONST_1; +"INTEGRABLE_NEG",INTEGRABLE_NEG; +"INTEGRABLE_ON_ALL_INTERVALS_INTEGRABLE_BOUND",INTEGRABLE_ON_ALL_INTERVALS_INTEGRABLE_BOUND; +"INTEGRABLE_ON_CONST",INTEGRABLE_ON_CONST; +"INTEGRABLE_ON_EMPTY",INTEGRABLE_ON_EMPTY; +"INTEGRABLE_ON_LITTLE_SUBINTERVALS",INTEGRABLE_ON_LITTLE_SUBINTERVALS; +"INTEGRABLE_ON_NULL",INTEGRABLE_ON_NULL; +"INTEGRABLE_ON_OPEN_INTERVAL",INTEGRABLE_ON_OPEN_INTERVAL; +"INTEGRABLE_ON_REFL",INTEGRABLE_ON_REFL; +"INTEGRABLE_ON_SUBDIVISION",INTEGRABLE_ON_SUBDIVISION; +"INTEGRABLE_ON_SUBINTERVAL",INTEGRABLE_ON_SUBINTERVAL; +"INTEGRABLE_ON_SUPERSET",INTEGRABLE_ON_SUPERSET; +"INTEGRABLE_REFLECT",INTEGRABLE_REFLECT; +"INTEGRABLE_RESTRICT",INTEGRABLE_RESTRICT; +"INTEGRABLE_RESTRICT_INTER",INTEGRABLE_RESTRICT_INTER; +"INTEGRABLE_RESTRICT_UNIV",INTEGRABLE_RESTRICT_UNIV; +"INTEGRABLE_SPIKE",INTEGRABLE_SPIKE; +"INTEGRABLE_SPIKE_FINITE",INTEGRABLE_SPIKE_FINITE; +"INTEGRABLE_SPIKE_INTERIOR",INTEGRABLE_SPIKE_INTERIOR; +"INTEGRABLE_SPIKE_SET",INTEGRABLE_SPIKE_SET; +"INTEGRABLE_SPIKE_SET_EQ",INTEGRABLE_SPIKE_SET_EQ; +"INTEGRABLE_SPLIT",INTEGRABLE_SPLIT; +"INTEGRABLE_STRADDLE",INTEGRABLE_STRADDLE; +"INTEGRABLE_STRADDLE_INTERVAL",INTEGRABLE_STRADDLE_INTERVAL; +"INTEGRABLE_STRETCH",INTEGRABLE_STRETCH; +"INTEGRABLE_SUB",INTEGRABLE_SUB; +"INTEGRABLE_SUBINTERVAL",INTEGRABLE_SUBINTERVAL; +"INTEGRABLE_SUBINTERVALS_IMP_MEASURABLE",INTEGRABLE_SUBINTERVALS_IMP_MEASURABLE; +"INTEGRABLE_UNIFORM_LIMIT",INTEGRABLE_UNIFORM_LIMIT; +"INTEGRABLE_VSUM",INTEGRABLE_VSUM; +"INTEGRAL_0",INTEGRAL_0; +"INTEGRAL_ADD",INTEGRAL_ADD; +"INTEGRAL_CMUL",INTEGRAL_CMUL; +"INTEGRAL_COMBINE",INTEGRAL_COMBINE; +"INTEGRAL_COMBINE_DIVISION_BOTTOMUP",INTEGRAL_COMBINE_DIVISION_BOTTOMUP; +"INTEGRAL_COMBINE_DIVISION_TOPDOWN",INTEGRAL_COMBINE_DIVISION_TOPDOWN; +"INTEGRAL_COMBINE_TAGGED_DIVISION_BOTTOMUP",INTEGRAL_COMBINE_TAGGED_DIVISION_BOTTOMUP; +"INTEGRAL_COMBINE_TAGGED_DIVISION_TOPDOWN",INTEGRAL_COMBINE_TAGGED_DIVISION_TOPDOWN; +"INTEGRAL_COMPONENT",INTEGRAL_COMPONENT; +"INTEGRAL_COMPONENT_LBOUND",INTEGRAL_COMPONENT_LBOUND; +"INTEGRAL_COMPONENT_LE",INTEGRAL_COMPONENT_LE; +"INTEGRAL_COMPONENT_POS",INTEGRAL_COMPONENT_POS; +"INTEGRAL_COMPONENT_UBOUND",INTEGRAL_COMPONENT_UBOUND; +"INTEGRAL_CONST",INTEGRAL_CONST; +"INTEGRAL_DIFF",INTEGRAL_DIFF; +"INTEGRAL_DROP_LE",INTEGRAL_DROP_LE; +"INTEGRAL_DROP_LE_MEASURABLE",INTEGRAL_DROP_LE_MEASURABLE; +"INTEGRAL_DROP_POS",INTEGRAL_DROP_POS; +"INTEGRAL_EMPTY",INTEGRAL_EMPTY; +"INTEGRAL_EQ",INTEGRAL_EQ; +"INTEGRAL_EQ_0",INTEGRAL_EQ_0; +"INTEGRAL_EQ_HAS_INTEGRAL",INTEGRAL_EQ_HAS_INTEGRAL; +"INTEGRAL_HAS_VECTOR_DERIVATIVE",INTEGRAL_HAS_VECTOR_DERIVATIVE; +"INTEGRAL_INTERVALS_DIFF_INCLUSION_EXCLUSION",INTEGRAL_INTERVALS_DIFF_INCLUSION_EXCLUSION; +"INTEGRAL_INTERVALS_INCLUSION_EXCLUSION",INTEGRAL_INTERVALS_INCLUSION_EXCLUSION; +"INTEGRAL_INTERVALS_INCLUSION_EXCLUSION_LEFT",INTEGRAL_INTERVALS_INCLUSION_EXCLUSION_LEFT; +"INTEGRAL_INTERVALS_INCLUSION_EXCLUSION_RIGHT",INTEGRAL_INTERVALS_INCLUSION_EXCLUSION_RIGHT; +"INTEGRAL_LINEAR",INTEGRAL_LINEAR; +"INTEGRAL_MEASURE",INTEGRAL_MEASURE; +"INTEGRAL_MEASURE_UNIV",INTEGRAL_MEASURE_UNIV; +"INTEGRAL_NEG",INTEGRAL_NEG; +"INTEGRAL_NORM_BOUND_INTEGRAL",INTEGRAL_NORM_BOUND_INTEGRAL; +"INTEGRAL_NORM_BOUND_INTEGRAL_COMPONENT",INTEGRAL_NORM_BOUND_INTEGRAL_COMPONENT; +"INTEGRAL_NULL",INTEGRAL_NULL; +"INTEGRAL_OPEN_INTERVAL",INTEGRAL_OPEN_INTERVAL; +"INTEGRAL_PASTECART_CONST",INTEGRAL_PASTECART_CONST; +"INTEGRAL_PASTECART_CONTINUOUS",INTEGRAL_PASTECART_CONTINUOUS; +"INTEGRAL_REFL",INTEGRAL_REFL; +"INTEGRAL_REFLECT",INTEGRAL_REFLECT; +"INTEGRAL_RESTRICT",INTEGRAL_RESTRICT; +"INTEGRAL_RESTRICT_INTER",INTEGRAL_RESTRICT_INTER; +"INTEGRAL_RESTRICT_UNIV",INTEGRAL_RESTRICT_UNIV; +"INTEGRAL_SPIKE",INTEGRAL_SPIKE; +"INTEGRAL_SPIKE_SET",INTEGRAL_SPIKE_SET; +"INTEGRAL_SPLIT",INTEGRAL_SPLIT; +"INTEGRAL_SPLIT_SIGNED",INTEGRAL_SPLIT_SIGNED; +"INTEGRAL_SUB",INTEGRAL_SUB; +"INTEGRAL_SUBSET_COMPONENT_LE",INTEGRAL_SUBSET_COMPONENT_LE; +"INTEGRAL_SUBSET_DROP_LE",INTEGRAL_SUBSET_DROP_LE; +"INTEGRAL_SWAP_CONTINUOUS",INTEGRAL_SWAP_CONTINUOUS; +"INTEGRAL_UNION",INTEGRAL_UNION; +"INTEGRAL_UNIQUE",INTEGRAL_UNIQUE; +"INTEGRAL_VSUM",INTEGRAL_VSUM; +"INTER",INTER; +"INTERIOR_BIJECTIVE_LINEAR_IMAGE",INTERIOR_BIJECTIVE_LINEAR_IMAGE; +"INTERIOR_CBALL",INTERIOR_CBALL; +"INTERIOR_CLOSED_EQ_EMPTY_AS_FRONTIER",INTERIOR_CLOSED_EQ_EMPTY_AS_FRONTIER; +"INTERIOR_CLOSED_INTERVAL",INTERIOR_CLOSED_INTERVAL; +"INTERIOR_CLOSED_UNION_EMPTY_INTERIOR",INTERIOR_CLOSED_UNION_EMPTY_INTERIOR; +"INTERIOR_CLOSURE",INTERIOR_CLOSURE; +"INTERIOR_CLOSURE_IDEMP",INTERIOR_CLOSURE_IDEMP; +"INTERIOR_COMPLEMENT",INTERIOR_COMPLEMENT; +"INTERIOR_CONVEX_HULL_3",INTERIOR_CONVEX_HULL_3; +"INTERIOR_CONVEX_HULL_3_MINIMAL",INTERIOR_CONVEX_HULL_3_MINIMAL; +"INTERIOR_CONVEX_HULL_EQ_EMPTY",INTERIOR_CONVEX_HULL_EQ_EMPTY; +"INTERIOR_CONVEX_HULL_EXPLICIT",INTERIOR_CONVEX_HULL_EXPLICIT; +"INTERIOR_CONVEX_HULL_EXPLICIT_MINIMAL",INTERIOR_CONVEX_HULL_EXPLICIT_MINIMAL; +"INTERIOR_DIFF",INTERIOR_DIFF; +"INTERIOR_EMPTY",INTERIOR_EMPTY; +"INTERIOR_EQ",INTERIOR_EQ; +"INTERIOR_EQ_EMPTY",INTERIOR_EQ_EMPTY; +"INTERIOR_EQ_EMPTY_ALT",INTERIOR_EQ_EMPTY_ALT; +"INTERIOR_FINITE_INTERS",INTERIOR_FINITE_INTERS; +"INTERIOR_FRONTIER",INTERIOR_FRONTIER; +"INTERIOR_FRONTIER_EMPTY",INTERIOR_FRONTIER_EMPTY; +"INTERIOR_HALFSPACE_COMPONENT_GE",INTERIOR_HALFSPACE_COMPONENT_GE; +"INTERIOR_HALFSPACE_COMPONENT_LE",INTERIOR_HALFSPACE_COMPONENT_LE; +"INTERIOR_HALFSPACE_GE",INTERIOR_HALFSPACE_GE; +"INTERIOR_HALFSPACE_LE",INTERIOR_HALFSPACE_LE; +"INTERIOR_HYPERPLANE",INTERIOR_HYPERPLANE; +"INTERIOR_IMAGE_SUBSET",INTERIOR_IMAGE_SUBSET; +"INTERIOR_INJECTIVE_LINEAR_IMAGE",INTERIOR_INJECTIVE_LINEAR_IMAGE; +"INTERIOR_INSIDE_FRONTIER",INTERIOR_INSIDE_FRONTIER; +"INTERIOR_INTER",INTERIOR_INTER; +"INTERIOR_INTERIOR",INTERIOR_INTERIOR; +"INTERIOR_INTERS_SUBSET",INTERIOR_INTERS_SUBSET; +"INTERIOR_INTERVAL",INTERIOR_INTERVAL; +"INTERIOR_LIMIT_POINT",INTERIOR_LIMIT_POINT; +"INTERIOR_MAXIMAL",INTERIOR_MAXIMAL; +"INTERIOR_MAXIMAL_EQ",INTERIOR_MAXIMAL_EQ; +"INTERIOR_NEGATIONS",INTERIOR_NEGATIONS; +"INTERIOR_OF_TRIANGLE",INTERIOR_OF_TRIANGLE; +"INTERIOR_OPEN",INTERIOR_OPEN; +"INTERIOR_PCROSS",INTERIOR_PCROSS; +"INTERIOR_SEGMENT",INTERIOR_SEGMENT; +"INTERIOR_SIMPLEX_NONEMPTY",INTERIOR_SIMPLEX_NONEMPTY; +"INTERIOR_SING",INTERIOR_SING; +"INTERIOR_STANDARD_HYPERPLANE",INTERIOR_STANDARD_HYPERPLANE; +"INTERIOR_STD_SIMPLEX",INTERIOR_STD_SIMPLEX; +"INTERIOR_SUBSET",INTERIOR_SUBSET; +"INTERIOR_SUBSET_RELATIVE_INTERIOR",INTERIOR_SUBSET_RELATIVE_INTERIOR; +"INTERIOR_SUBSET_UNION_INTERVALS",INTERIOR_SUBSET_UNION_INTERVALS; +"INTERIOR_SURJECTIVE_LINEAR_IMAGE",INTERIOR_SURJECTIVE_LINEAR_IMAGE; +"INTERIOR_TRANSLATION",INTERIOR_TRANSLATION; +"INTERIOR_UNIONS_OPEN_SUBSETS",INTERIOR_UNIONS_OPEN_SUBSETS; +"INTERIOR_UNION_EQ_EMPTY",INTERIOR_UNION_EQ_EMPTY; +"INTERIOR_UNIQUE",INTERIOR_UNIQUE; +"INTERIOR_UNIV",INTERIOR_UNIV; +"INTERS",INTERS; +"INTERS_0",INTERS_0; +"INTERS_1",INTERS_1; +"INTERS_2",INTERS_2; +"INTERS_FACES_FINITE_ALTBOUND",INTERS_FACES_FINITE_ALTBOUND; +"INTERS_FACES_FINITE_BOUND",INTERS_FACES_FINITE_BOUND; +"INTERS_GSPEC",INTERS_GSPEC; +"INTERS_IMAGE",INTERS_IMAGE; +"INTERS_INSERT",INTERS_INSERT; +"INTERS_OVER_UNIONS",INTERS_OVER_UNIONS; +"INTERS_UNION",INTERS_UNION; +"INTERS_UNIONS",INTERS_UNIONS; +"INTERVAL_BIJ_AFFINE",INTERVAL_BIJ_AFFINE; +"INTERVAL_BIJ_BIJ",INTERVAL_BIJ_BIJ; +"INTERVAL_BISECTION",INTERVAL_BISECTION; +"INTERVAL_BISECTION_STEP",INTERVAL_BISECTION_STEP; +"INTERVAL_BOUNDS_EMPTY_1",INTERVAL_BOUNDS_EMPTY_1; +"INTERVAL_BOUNDS_NULL_1",INTERVAL_BOUNDS_NULL_1; +"INTERVAL_CASES_1",INTERVAL_CASES_1; +"INTERVAL_CONTAINS_COMPACT_NEIGHBOURHOOD",INTERVAL_CONTAINS_COMPACT_NEIGHBOURHOOD; +"INTERVAL_DOUBLESPLIT",INTERVAL_DOUBLESPLIT; +"INTERVAL_EQ_EMPTY",INTERVAL_EQ_EMPTY; +"INTERVAL_EQ_EMPTY_1",INTERVAL_EQ_EMPTY_1; +"INTERVAL_IMAGE_AFFINITY_INTERVAL",INTERVAL_IMAGE_AFFINITY_INTERVAL; +"INTERVAL_IMAGE_STRETCH_INTERVAL",INTERVAL_IMAGE_STRETCH_INTERVAL; +"INTERVAL_LOWERBOUND",INTERVAL_LOWERBOUND; +"INTERVAL_LOWERBOUND_1",INTERVAL_LOWERBOUND_1; +"INTERVAL_NE_EMPTY",INTERVAL_NE_EMPTY; +"INTERVAL_NE_EMPTY_1",INTERVAL_NE_EMPTY_1; +"INTERVAL_OPEN_SUBSET_CLOSED",INTERVAL_OPEN_SUBSET_CLOSED; +"INTERVAL_SING",INTERVAL_SING; +"INTERVAL_SPLIT",INTERVAL_SPLIT; +"INTERVAL_SUBDIVISION",INTERVAL_SUBDIVISION; +"INTERVAL_SUBSET_IS_INTERVAL",INTERVAL_SUBSET_IS_INTERVAL; +"INTERVAL_TRANSLATION",INTERVAL_TRANSLATION; +"INTERVAL_UPPERBOUND",INTERVAL_UPPERBOUND; +"INTERVAL_UPPERBOUND_1",INTERVAL_UPPERBOUND_1; +"INTER_ACI",INTER_ACI; +"INTER_ASSOC",INTER_ASSOC; +"INTER_COMM",INTER_COMM; +"INTER_EMPTY",INTER_EMPTY; +"INTER_IDEMPOT",INTER_IDEMPOT; +"INTER_INTERIOR_UNIONS_INTERVALS",INTER_INTERIOR_UNIONS_INTERVALS; +"INTER_INTERVAL",INTER_INTERVAL; +"INTER_INTERVAL_1",INTER_INTERVAL_1; +"INTER_INTERVAL_MIXED_EQ_EMPTY",INTER_INTERVAL_MIXED_EQ_EMPTY; +"INTER_OVER_UNION",INTER_OVER_UNION; +"INTER_SEGMENT",INTER_SEGMENT; +"INTER_SUBSET",INTER_SUBSET; +"INTER_UNIONS",INTER_UNIONS; +"INTER_UNIV",INTER_UNIV; +"INT_ABS",INT_ABS; +"INT_ABS_0",INT_ABS_0; +"INT_ABS_1",INT_ABS_1; +"INT_ABS_ABS",INT_ABS_ABS; +"INT_ABS_BETWEEN",INT_ABS_BETWEEN; +"INT_ABS_BETWEEN1",INT_ABS_BETWEEN1; +"INT_ABS_BETWEEN2",INT_ABS_BETWEEN2; +"INT_ABS_BOUND",INT_ABS_BOUND; +"INT_ABS_CASES",INT_ABS_CASES; +"INT_ABS_CIRCLE",INT_ABS_CIRCLE; +"INT_ABS_LE",INT_ABS_LE; +"INT_ABS_MUL",INT_ABS_MUL; +"INT_ABS_MUL_1",INT_ABS_MUL_1; +"INT_ABS_NEG",INT_ABS_NEG; +"INT_ABS_NUM",INT_ABS_NUM; +"INT_ABS_NZ",INT_ABS_NZ; +"INT_ABS_POS",INT_ABS_POS; +"INT_ABS_POW",INT_ABS_POW; +"INT_ABS_REFL",INT_ABS_REFL; +"INT_ABS_SGN",INT_ABS_SGN; +"INT_ABS_SIGN",INT_ABS_SIGN; +"INT_ABS_SIGN2",INT_ABS_SIGN2; +"INT_ABS_STILLNZ",INT_ABS_STILLNZ; +"INT_ABS_SUB",INT_ABS_SUB; +"INT_ABS_SUB_ABS",INT_ABS_SUB_ABS; +"INT_ABS_TRIANGLE",INT_ABS_TRIANGLE; +"INT_ABS_ZERO",INT_ABS_ZERO; +"INT_ADD2_SUB2",INT_ADD2_SUB2; +"INT_ADD_AC",INT_ADD_AC; +"INT_ADD_ASSOC",INT_ADD_ASSOC; +"INT_ADD_LDISTRIB",INT_ADD_LDISTRIB; +"INT_ADD_LID",INT_ADD_LID; +"INT_ADD_LINV",INT_ADD_LINV; +"INT_ADD_RDISTRIB",INT_ADD_RDISTRIB; +"INT_ADD_RID",INT_ADD_RID; +"INT_ADD_RINV",INT_ADD_RINV; +"INT_ADD_SUB",INT_ADD_SUB; +"INT_ADD_SUB2",INT_ADD_SUB2; +"INT_ADD_SYM",INT_ADD_SYM; +"INT_ARCH",INT_ARCH; +"INT_BOUNDS_LE",INT_BOUNDS_LE; +"INT_BOUNDS_LT",INT_BOUNDS_LT; +"INT_DIFFSQ",INT_DIFFSQ; +"INT_DIVISION",INT_DIVISION; +"INT_DIVISION_0",INT_DIVISION_0; +"INT_DIVMOD_EXIST_0",INT_DIVMOD_EXIST_0; +"INT_DIVMOD_UNIQ",INT_DIVMOD_UNIQ; +"INT_ENTIRE",INT_ENTIRE; +"INT_EQ_ADD_LCANCEL",INT_EQ_ADD_LCANCEL; +"INT_EQ_ADD_LCANCEL_0",INT_EQ_ADD_LCANCEL_0; +"INT_EQ_ADD_RCANCEL",INT_EQ_ADD_RCANCEL; +"INT_EQ_ADD_RCANCEL_0",INT_EQ_ADD_RCANCEL_0; +"INT_EQ_IMP_LE",INT_EQ_IMP_LE; +"INT_EQ_MUL_LCANCEL",INT_EQ_MUL_LCANCEL; +"INT_EQ_MUL_RCANCEL",INT_EQ_MUL_RCANCEL; +"INT_EQ_NEG2",INT_EQ_NEG2; +"INT_EQ_SQUARE_ABS",INT_EQ_SQUARE_ABS; +"INT_EQ_SUB_LADD",INT_EQ_SUB_LADD; +"INT_EQ_SUB_RADD",INT_EQ_SUB_RADD; +"INT_EXISTS_ABS",INT_EXISTS_ABS; +"INT_EXISTS_POS",INT_EXISTS_POS; +"INT_FORALL_ABS",INT_FORALL_ABS; +"INT_FORALL_POS",INT_FORALL_POS; +"INT_GCD_EXISTS",INT_GCD_EXISTS; +"INT_GCD_EXISTS_POS",INT_GCD_EXISTS_POS; +"INT_GE",INT_GE; +"INT_GT",INT_GT; +"INT_GT_DISCRETE",INT_GT_DISCRETE; +"INT_IMAGE",INT_IMAGE; +"INT_LET_ADD",INT_LET_ADD; +"INT_LET_ADD2",INT_LET_ADD2; +"INT_LET_ANTISYM",INT_LET_ANTISYM; +"INT_LET_TOTAL",INT_LET_TOTAL; +"INT_LET_TRANS",INT_LET_TRANS; +"INT_LE_01",INT_LE_01; +"INT_LE_ADD",INT_LE_ADD; +"INT_LE_ADD2",INT_LE_ADD2; +"INT_LE_ADDL",INT_LE_ADDL; +"INT_LE_ADDR",INT_LE_ADDR; +"INT_LE_ANTISYM",INT_LE_ANTISYM; +"INT_LE_DOUBLE",INT_LE_DOUBLE; +"INT_LE_LADD",INT_LE_LADD; +"INT_LE_LADD_IMP",INT_LE_LADD_IMP; +"INT_LE_LMUL",INT_LE_LMUL; +"INT_LE_LNEG",INT_LE_LNEG; +"INT_LE_LT",INT_LE_LT; +"INT_LE_MAX",INT_LE_MAX; +"INT_LE_MIN",INT_LE_MIN; +"INT_LE_MUL",INT_LE_MUL; +"INT_LE_MUL_EQ",INT_LE_MUL_EQ; +"INT_LE_NEG",INT_LE_NEG; +"INT_LE_NEG2",INT_LE_NEG2; +"INT_LE_NEGL",INT_LE_NEGL; +"INT_LE_NEGR",INT_LE_NEGR; +"INT_LE_NEGTOTAL",INT_LE_NEGTOTAL; +"INT_LE_POW2",INT_LE_POW2; +"INT_LE_RADD",INT_LE_RADD; +"INT_LE_REFL",INT_LE_REFL; +"INT_LE_RMUL",INT_LE_RMUL; +"INT_LE_RNEG",INT_LE_RNEG; +"INT_LE_SQUARE",INT_LE_SQUARE; +"INT_LE_SQUARE_ABS",INT_LE_SQUARE_ABS; +"INT_LE_SUB_LADD",INT_LE_SUB_LADD; +"INT_LE_SUB_RADD",INT_LE_SUB_RADD; +"INT_LE_TOTAL",INT_LE_TOTAL; +"INT_LE_TRANS",INT_LE_TRANS; +"INT_LNEG_UNIQ",INT_LNEG_UNIQ; +"INT_LT",INT_LT; +"INT_LTE_ADD",INT_LTE_ADD; +"INT_LTE_ADD2",INT_LTE_ADD2; +"INT_LTE_ANTISYM",INT_LTE_ANTISYM; +"INT_LTE_TOTAL",INT_LTE_TOTAL; +"INT_LTE_TRANS",INT_LTE_TRANS; +"INT_LT_01",INT_LT_01; +"INT_LT_ADD",INT_LT_ADD; +"INT_LT_ADD1",INT_LT_ADD1; +"INT_LT_ADD2",INT_LT_ADD2; +"INT_LT_ADDL",INT_LT_ADDL; +"INT_LT_ADDNEG",INT_LT_ADDNEG; +"INT_LT_ADDNEG2",INT_LT_ADDNEG2; +"INT_LT_ADDR",INT_LT_ADDR; +"INT_LT_ADD_SUB",INT_LT_ADD_SUB; +"INT_LT_ANTISYM",INT_LT_ANTISYM; +"INT_LT_DISCRETE",INT_LT_DISCRETE; +"INT_LT_GT",INT_LT_GT; +"INT_LT_IMP_LE",INT_LT_IMP_LE; +"INT_LT_IMP_NE",INT_LT_IMP_NE; +"INT_LT_LADD",INT_LT_LADD; +"INT_LT_LE",INT_LT_LE; +"INT_LT_LMUL_EQ",INT_LT_LMUL_EQ; +"INT_LT_MAX",INT_LT_MAX; +"INT_LT_MIN",INT_LT_MIN; +"INT_LT_MUL",INT_LT_MUL; +"INT_LT_MUL_EQ",INT_LT_MUL_EQ; +"INT_LT_NEG",INT_LT_NEG; +"INT_LT_NEG2",INT_LT_NEG2; +"INT_LT_NEGTOTAL",INT_LT_NEGTOTAL; +"INT_LT_POW2",INT_LT_POW2; +"INT_LT_RADD",INT_LT_RADD; +"INT_LT_REFL",INT_LT_REFL; +"INT_LT_RMUL_EQ",INT_LT_RMUL_EQ; +"INT_LT_SQUARE_ABS",INT_LT_SQUARE_ABS; +"INT_LT_SUB_LADD",INT_LT_SUB_LADD; +"INT_LT_SUB_RADD",INT_LT_SUB_RADD; +"INT_LT_TOTAL",INT_LT_TOTAL; +"INT_LT_TRANS",INT_LT_TRANS; +"INT_MAX",INT_MAX; +"INT_MAX_ACI",INT_MAX_ACI; +"INT_MAX_ASSOC",INT_MAX_ASSOC; +"INT_MAX_LE",INT_MAX_LE; +"INT_MAX_LT",INT_MAX_LT; +"INT_MAX_MAX",INT_MAX_MAX; +"INT_MAX_MIN",INT_MAX_MIN; +"INT_MAX_SYM",INT_MAX_SYM; +"INT_MIN",INT_MIN; +"INT_MIN_ACI",INT_MIN_ACI; +"INT_MIN_ASSOC",INT_MIN_ASSOC; +"INT_MIN_LE",INT_MIN_LE; +"INT_MIN_LT",INT_MIN_LT; +"INT_MIN_MAX",INT_MIN_MAX; +"INT_MIN_MIN",INT_MIN_MIN; +"INT_MIN_SYM",INT_MIN_SYM; +"INT_MUL_AC",INT_MUL_AC; +"INT_MUL_ASSOC",INT_MUL_ASSOC; +"INT_MUL_LID",INT_MUL_LID; +"INT_MUL_LNEG",INT_MUL_LNEG; +"INT_MUL_LZERO",INT_MUL_LZERO; +"INT_MUL_POS_LE",INT_MUL_POS_LE; +"INT_MUL_POS_LT",INT_MUL_POS_LT; +"INT_MUL_RID",INT_MUL_RID; +"INT_MUL_RNEG",INT_MUL_RNEG; +"INT_MUL_RZERO",INT_MUL_RZERO; +"INT_MUL_SYM",INT_MUL_SYM; +"INT_NEGNEG",INT_NEGNEG; +"INT_NEG_0",INT_NEG_0; +"INT_NEG_ADD",INT_NEG_ADD; +"INT_NEG_EQ",INT_NEG_EQ; +"INT_NEG_EQ_0",INT_NEG_EQ_0; +"INT_NEG_GE0",INT_NEG_GE0; +"INT_NEG_GT0",INT_NEG_GT0; +"INT_NEG_LE0",INT_NEG_LE0; +"INT_NEG_LMUL",INT_NEG_LMUL; +"INT_NEG_LT0",INT_NEG_LT0; +"INT_NEG_MINUS1",INT_NEG_MINUS1; +"INT_NEG_MUL2",INT_NEG_MUL2; +"INT_NEG_NEG",INT_NEG_NEG; +"INT_NEG_RMUL",INT_NEG_RMUL; +"INT_NEG_SUB",INT_NEG_SUB; +"INT_NOT_EQ",INT_NOT_EQ; +"INT_NOT_LE",INT_NOT_LE; +"INT_NOT_LT",INT_NOT_LT; +"INT_OF_NUM_ADD",INT_OF_NUM_ADD; +"INT_OF_NUM_EQ",INT_OF_NUM_EQ; +"INT_OF_NUM_EXISTS",INT_OF_NUM_EXISTS; +"INT_OF_NUM_GE",INT_OF_NUM_GE; +"INT_OF_NUM_GT",INT_OF_NUM_GT; +"INT_OF_NUM_LE",INT_OF_NUM_LE; +"INT_OF_NUM_LT",INT_OF_NUM_LT; +"INT_OF_NUM_MAX",INT_OF_NUM_MAX; +"INT_OF_NUM_MIN",INT_OF_NUM_MIN; +"INT_OF_NUM_MUL",INT_OF_NUM_MUL; +"INT_OF_NUM_OF_INT",INT_OF_NUM_OF_INT; +"INT_OF_NUM_POW",INT_OF_NUM_POW; +"INT_OF_NUM_SUB",INT_OF_NUM_SUB; +"INT_OF_NUM_SUC",INT_OF_NUM_SUC; +"INT_OF_REAL_OF_INT",INT_OF_REAL_OF_INT; +"INT_POS",INT_POS; +"INT_POS_NZ",INT_POS_NZ; +"INT_POW",INT_POW; +"INT_POW2_ABS",INT_POW2_ABS; +"INT_POW_1",INT_POW_1; +"INT_POW_1_LE",INT_POW_1_LE; +"INT_POW_1_LT",INT_POW_1_LT; +"INT_POW_2",INT_POW_2; +"INT_POW_ADD",INT_POW_ADD; +"INT_POW_EQ",INT_POW_EQ; +"INT_POW_EQ_0",INT_POW_EQ_0; +"INT_POW_EQ_ABS",INT_POW_EQ_ABS; +"INT_POW_LE",INT_POW_LE; +"INT_POW_LE2",INT_POW_LE2; +"INT_POW_LE2_ODD",INT_POW_LE2_ODD; +"INT_POW_LE2_REV",INT_POW_LE2_REV; +"INT_POW_LE_1",INT_POW_LE_1; +"INT_POW_LT",INT_POW_LT; +"INT_POW_LT2",INT_POW_LT2; +"INT_POW_LT2_REV",INT_POW_LT2_REV; +"INT_POW_LT_1",INT_POW_LT_1; +"INT_POW_MONO",INT_POW_MONO; +"INT_POW_MONO_LT",INT_POW_MONO_LT; +"INT_POW_MUL",INT_POW_MUL; +"INT_POW_NEG",INT_POW_NEG; +"INT_POW_NZ",INT_POW_NZ; +"INT_POW_ONE",INT_POW_ONE; +"INT_POW_POW",INT_POW_POW; +"INT_POW_ZERO",INT_POW_ZERO; +"INT_RNEG_UNIQ",INT_RNEG_UNIQ; +"INT_SGN",INT_SGN; +"INT_SGN_0",INT_SGN_0; +"INT_SGN_ABS",INT_SGN_ABS; +"INT_SGN_CASES",INT_SGN_CASES; +"INT_SGN_EQ",INT_SGN_EQ; +"INT_SGN_INEQS",INT_SGN_INEQS; +"INT_SGN_MUL",INT_SGN_MUL; +"INT_SGN_NEG",INT_SGN_NEG; +"INT_SOS_EQ_0",INT_SOS_EQ_0; +"INT_SUB",INT_SUB; +"INT_SUB_0",INT_SUB_0; +"INT_SUB_ABS",INT_SUB_ABS; +"INT_SUB_ADD",INT_SUB_ADD; +"INT_SUB_ADD2",INT_SUB_ADD2; +"INT_SUB_LDISTRIB",INT_SUB_LDISTRIB; +"INT_SUB_LE",INT_SUB_LE; +"INT_SUB_LNEG",INT_SUB_LNEG; +"INT_SUB_LT",INT_SUB_LT; +"INT_SUB_LZERO",INT_SUB_LZERO; +"INT_SUB_NEG2",INT_SUB_NEG2; +"INT_SUB_RDISTRIB",INT_SUB_RDISTRIB; +"INT_SUB_REFL",INT_SUB_REFL; +"INT_SUB_RNEG",INT_SUB_RNEG; +"INT_SUB_RZERO",INT_SUB_RZERO; +"INT_SUB_SUB",INT_SUB_SUB; +"INT_SUB_SUB2",INT_SUB_SUB2; +"INT_SUB_TRIANGLE",INT_SUB_TRIANGLE; +"INT_WOP",INT_WOP; +"INVERSE_I",INVERSE_I; +"INVERSE_SWAP",INVERSE_SWAP; +"INVERSE_UNIQUE_o",INVERSE_UNIQUE_o; +"INVERTIBLE_COFACTOR",INVERTIBLE_COFACTOR; +"INVERTIBLE_DET_NZ",INVERTIBLE_DET_NZ; +"INVERTIBLE_FIXPOINT_PROPERTY",INVERTIBLE_FIXPOINT_PROPERTY; +"INVERTIBLE_IMP_SQUARE_MATRIX",INVERTIBLE_IMP_SQUARE_MATRIX; +"INVERTIBLE_LEFT_INVERSE",INVERTIBLE_LEFT_INVERSE; +"INVERTIBLE_MATRIX_MUL",INVERTIBLE_MATRIX_MUL; +"INVERTIBLE_NEG",INVERTIBLE_NEG; +"INVERTIBLE_RIGHT_INVERSE",INVERTIBLE_RIGHT_INVERSE; +"INVERTIBLE_TRANSP",INVERTIBLE_TRANSP; +"IN_AFFINE_ADD_MUL",IN_AFFINE_ADD_MUL; +"IN_AFFINE_ADD_MUL_DIFF",IN_AFFINE_ADD_MUL_DIFF; +"IN_AFFINE_HULL_LINEAR_IMAGE",IN_AFFINE_HULL_LINEAR_IMAGE; +"IN_AFFINE_MUL_DIFF_ADD",IN_AFFINE_MUL_DIFF_ADD; +"IN_AFFINE_SUB_MUL_DIFF",IN_AFFINE_SUB_MUL_DIFF; +"IN_BALL",IN_BALL; +"IN_BALL_0",IN_BALL_0; +"IN_CARD_ADD",IN_CARD_ADD; +"IN_CARD_MUL",IN_CARD_MUL; +"IN_CBALL",IN_CBALL; +"IN_CBALL_0",IN_CBALL_0; +"IN_CLOSURE_CONNECTED_COMPONENT",IN_CLOSURE_CONNECTED_COMPONENT; +"IN_CLOSURE_DELETE",IN_CLOSURE_DELETE; +"IN_COMPONENTS",IN_COMPONENTS; +"IN_COMPONENTS_CONNECTED",IN_COMPONENTS_CONNECTED; +"IN_COMPONENTS_MAXIMAL",IN_COMPONENTS_MAXIMAL; +"IN_COMPONENTS_NONEMPTY",IN_COMPONENTS_NONEMPTY; +"IN_COMPONENTS_SELF",IN_COMPONENTS_SELF; +"IN_COMPONENTS_SUBSET",IN_COMPONENTS_SUBSET; +"IN_CONVEX_HULL_EXCHANGE",IN_CONVEX_HULL_EXCHANGE; +"IN_CONVEX_HULL_EXCHANGE_UNIQUE",IN_CONVEX_HULL_EXCHANGE_UNIQUE; +"IN_CONVEX_HULL_LINEAR_IMAGE",IN_CONVEX_HULL_LINEAR_IMAGE; +"IN_CONVEX_SET",IN_CONVEX_SET; +"IN_CROSS",IN_CROSS; +"IN_DELETE",IN_DELETE; +"IN_DELETE_EQ",IN_DELETE_EQ; +"IN_DIFF",IN_DIFF; +"IN_DIMINDEX_SWAP",IN_DIMINDEX_SWAP; +"IN_DIRECTION",IN_DIRECTION; +"IN_DISJOINT",IN_DISJOINT; +"IN_ELIM_PAIR_THM",IN_ELIM_PAIR_THM; +"IN_ELIM_PASTECART_THM",IN_ELIM_PASTECART_THM; +"IN_ELIM_THM",IN_ELIM_THM; +"IN_EPIGRAPH",IN_EPIGRAPH; +"IN_FROM",IN_FROM; +"IN_FRONTIER_CONVEX_HULL",IN_FRONTIER_CONVEX_HULL; +"IN_IMAGE",IN_IMAGE; +"IN_IMAGE_LIFT_DROP",IN_IMAGE_LIFT_DROP; +"IN_INSERT",IN_INSERT; +"IN_INTER",IN_INTER; +"IN_INTERIOR",IN_INTERIOR; +"IN_INTERIOR_CBALL",IN_INTERIOR_CBALL; +"IN_INTERIOR_CLOSURE_CONVEX_SEGMENT",IN_INTERIOR_CLOSURE_CONVEX_SEGMENT; +"IN_INTERIOR_CLOSURE_CONVEX_SHRINK",IN_INTERIOR_CLOSURE_CONVEX_SHRINK; +"IN_INTERIOR_CONVEX_SHRINK",IN_INTERIOR_CONVEX_SHRINK; +"IN_INTERIOR_LINEAR_IMAGE",IN_INTERIOR_LINEAR_IMAGE; +"IN_INTERS",IN_INTERS; +"IN_INTERVAL",IN_INTERVAL; +"IN_INTERVAL_1",IN_INTERVAL_1; +"IN_INTERVAL_INTERVAL_BIJ",IN_INTERVAL_INTERVAL_BIJ; +"IN_INTERVAL_REFLECT",IN_INTERVAL_REFLECT; +"IN_NUMSEG",IN_NUMSEG; +"IN_NUMSEG_0",IN_NUMSEG_0; +"IN_OPEN_SEGMENT",IN_OPEN_SEGMENT; +"IN_OPEN_SEGMENT_ALT",IN_OPEN_SEGMENT_ALT; +"IN_RELATIVE_INTERIOR",IN_RELATIVE_INTERIOR; +"IN_RELATIVE_INTERIOR_CBALL",IN_RELATIVE_INTERIOR_CBALL; +"IN_RELATIVE_INTERIOR_CLOSURE_CONVEX_SEGMENT",IN_RELATIVE_INTERIOR_CLOSURE_CONVEX_SEGMENT; +"IN_RELATIVE_INTERIOR_CLOSURE_CONVEX_SHRINK",IN_RELATIVE_INTERIOR_CLOSURE_CONVEX_SHRINK; +"IN_RELATIVE_INTERIOR_CONVEX_SHRINK",IN_RELATIVE_INTERIOR_CONVEX_SHRINK; +"IN_REST",IN_REST; +"IN_SEGMENT",IN_SEGMENT; +"IN_SEGMENT_COMPONENT",IN_SEGMENT_COMPONENT; +"IN_SET_OF_LIST",IN_SET_OF_LIST; +"IN_SING",IN_SING; +"IN_SPAN_DELETE",IN_SPAN_DELETE; +"IN_SPAN_IMAGE_BASIS",IN_SPAN_IMAGE_BASIS; +"IN_SPAN_INSERT",IN_SPAN_INSERT; +"IN_SPHERE",IN_SPHERE; +"IN_SPHERE_0",IN_SPHERE_0; +"IN_SUPPORT",IN_SUPPORT; +"IN_UNION",IN_UNION; +"IN_UNIONS",IN_UNIONS; +"IN_UNIV",IN_UNIV; +"IRRATIONAL_APPROXIMATION",IRRATIONAL_APPROXIMATION; +"ISO",ISO; +"ISOMETRIES_SUBSPACES",ISOMETRIES_SUBSPACES; +"ISOMETRY_IMP_AFFINITY",ISOMETRY_IMP_AFFINITY; +"ISOMETRY_LINEAR",ISOMETRY_LINEAR; +"ISOMETRY_ON_IMP_CONTINUOUS_ON",ISOMETRY_ON_IMP_CONTINUOUS_ON; +"ISOMETRY_SPHERE_EXTEND",ISOMETRY_SPHERE_EXTEND; +"ISOMETRY_SUBSET_SUBSPACE",ISOMETRY_SUBSET_SUBSPACE; +"ISOMETRY_SUBSPACES",ISOMETRY_SUBSPACES; +"ISOMETRY_UNIV_SUBSPACE",ISOMETRY_UNIV_SUBSPACE; +"ISOMETRY_UNIV_SUPERSET_SUBSPACE",ISOMETRY_UNIV_SUPERSET_SUBSPACE; +"ISOMETRY_UNIV_UNIV",ISOMETRY_UNIV_UNIV; +"ISOMORPHISMS_UNIV_UNIV",ISOMORPHISMS_UNIV_UNIV; +"ISOMORPHISM_EXPAND",ISOMORPHISM_EXPAND; +"ISO_FUN",ISO_FUN; +"ISO_REFL",ISO_REFL; +"ISO_USAGE",ISO_USAGE; +"ISTOPLOGY_SUBTOPOLOGY",ISTOPLOGY_SUBTOPOLOGY; +"ISTOPOLOGY_OPEN_IN",ISTOPOLOGY_OPEN_IN; +"IS_AFFINE_HULL",IS_AFFINE_HULL; +"IS_CONVEX_HULL",IS_CONVEX_HULL; +"IS_HULL",IS_HULL; +"IS_INTERVAL_1",IS_INTERVAL_1; +"IS_INTERVAL_1_CASES",IS_INTERVAL_1_CASES; +"IS_INTERVAL_COMPACT",IS_INTERVAL_COMPACT; +"IS_INTERVAL_CONNECTED",IS_INTERVAL_CONNECTED; +"IS_INTERVAL_CONNECTED_1",IS_INTERVAL_CONNECTED_1; +"IS_INTERVAL_CONTRACTIBLE_1",IS_INTERVAL_CONTRACTIBLE_1; +"IS_INTERVAL_CONVEX",IS_INTERVAL_CONVEX; +"IS_INTERVAL_CONVEX_1",IS_INTERVAL_CONVEX_1; +"IS_INTERVAL_EMPTY",IS_INTERVAL_EMPTY; +"IS_INTERVAL_IMP_LOCALLY_COMPACT",IS_INTERVAL_IMP_LOCALLY_COMPACT; +"IS_INTERVAL_INTER",IS_INTERVAL_INTER; +"IS_INTERVAL_INTERVAL",IS_INTERVAL_INTERVAL; +"IS_INTERVAL_PATH_CONNECTED",IS_INTERVAL_PATH_CONNECTED; +"IS_INTERVAL_PATH_CONNECTED_1",IS_INTERVAL_PATH_CONNECTED_1; +"IS_INTERVAL_PCROSS",IS_INTERVAL_PCROSS; +"IS_INTERVAL_PCROSS_EQ",IS_INTERVAL_PCROSS_EQ; +"IS_INTERVAL_POINTWISE",IS_INTERVAL_POINTWISE; +"IS_INTERVAL_SCALING",IS_INTERVAL_SCALING; +"IS_INTERVAL_SCALING_EQ",IS_INTERVAL_SCALING_EQ; +"IS_INTERVAL_SIMPLY_CONNECTED_1",IS_INTERVAL_SIMPLY_CONNECTED_1; +"IS_INTERVAL_SING",IS_INTERVAL_SING; +"IS_INTERVAL_SUMS",IS_INTERVAL_SUMS; +"IS_INTERVAL_TRANSLATION",IS_INTERVAL_TRANSLATION; +"IS_INTERVAL_TRANSLATION_EQ",IS_INTERVAL_TRANSLATION_EQ; +"IS_INTERVAL_UNIV",IS_INTERVAL_UNIV; +"ITERATE_AND",ITERATE_AND; +"ITERATE_BIJECTION",ITERATE_BIJECTION; +"ITERATE_CASES",ITERATE_CASES; +"ITERATE_CLAUSES",ITERATE_CLAUSES; +"ITERATE_CLAUSES_GEN",ITERATE_CLAUSES_GEN; +"ITERATE_CLAUSES_NUMSEG",ITERATE_CLAUSES_NUMSEG; +"ITERATE_CLOSED",ITERATE_CLOSED; +"ITERATE_DELETE",ITERATE_DELETE; +"ITERATE_DELTA",ITERATE_DELTA; +"ITERATE_DIFF",ITERATE_DIFF; +"ITERATE_DIFF_GEN",ITERATE_DIFF_GEN; +"ITERATE_EQ",ITERATE_EQ; +"ITERATE_EQ_GENERAL",ITERATE_EQ_GENERAL; +"ITERATE_EQ_GENERAL_INVERSES",ITERATE_EQ_GENERAL_INVERSES; +"ITERATE_EQ_NEUTRAL",ITERATE_EQ_NEUTRAL; +"ITERATE_EXPAND_CASES",ITERATE_EXPAND_CASES; +"ITERATE_IMAGE",ITERATE_IMAGE; +"ITERATE_IMAGE_NONZERO",ITERATE_IMAGE_NONZERO; +"ITERATE_INCL_EXCL",ITERATE_INCL_EXCL; +"ITERATE_INJECTION",ITERATE_INJECTION; +"ITERATE_ITERATE_PRODUCT",ITERATE_ITERATE_PRODUCT; +"ITERATE_NONZERO_IMAGE_LEMMA",ITERATE_NONZERO_IMAGE_LEMMA; +"ITERATE_OP",ITERATE_OP; +"ITERATE_OP_GEN",ITERATE_OP_GEN; +"ITERATE_PAIR",ITERATE_PAIR; +"ITERATE_PERMUTE",ITERATE_PERMUTE; +"ITERATE_RELATED",ITERATE_RELATED; +"ITERATE_SING",ITERATE_SING; +"ITERATE_SOME",ITERATE_SOME; +"ITERATE_SUPERSET",ITERATE_SUPERSET; +"ITERATE_SUPPORT",ITERATE_SUPPORT; +"ITERATE_UNION",ITERATE_UNION; +"ITERATE_UNION_GEN",ITERATE_UNION_GEN; +"ITERATE_UNION_NONZERO",ITERATE_UNION_NONZERO; +"ITLIST",ITLIST; +"ITLIST2",ITLIST2; +"ITLIST2_DEF",ITLIST2_DEF; +"ITLIST_APPEND",ITLIST_APPEND; +"ITLIST_EXTRA",ITLIST_EXTRA; +"ITSET",ITSET; +"ITSET_EQ",ITSET_EQ; +"IVT_DECREASING_COMPONENT_1",IVT_DECREASING_COMPONENT_1; +"IVT_DECREASING_COMPONENT_ON_1",IVT_DECREASING_COMPONENT_ON_1; +"IVT_INCREASING_COMPONENT_1",IVT_INCREASING_COMPONENT_1; +"IVT_INCREASING_COMPONENT_ON_1",IVT_INCREASING_COMPONENT_ON_1; +"I_DEF",I_DEF; +"I_O_ID",I_O_ID; +"I_THM",I_THM; +"JACOBIAN_WORKS",JACOBIAN_WORKS; +"JOINABLE_COMPONENTS_EQ",JOINABLE_COMPONENTS_EQ; +"JOINABLE_CONNECTED_COMPONENT_EQ",JOINABLE_CONNECTED_COMPONENT_EQ; +"JOINPATHS",JOINPATHS; +"JOINPATHS_LINEAR_IMAGE",JOINPATHS_LINEAR_IMAGE; +"JOINPATHS_TRANSLATION",JOINPATHS_TRANSLATION; +"JOIN_PATHS_EQ",JOIN_PATHS_EQ; +"JOIN_SUBPATHS_MIDDLE",JOIN_SUBPATHS_MIDDLE; +"JORDAN_CURVE_THEOREM",JORDAN_CURVE_THEOREM; +"JORDAN_DISCONNECTED",JORDAN_DISCONNECTED; +"JORDAN_INSIDE_OUTSIDE",JORDAN_INSIDE_OUTSIDE; +"JUNG",JUNG; +"KIRCHBERGER",KIRCHBERGER; +"KL",KL; +"KLE_ADJACENT",KLE_ADJACENT; +"KLE_ANTISYM",KLE_ANTISYM; +"KLE_BETWEEN_L",KLE_BETWEEN_L; +"KLE_BETWEEN_R",KLE_BETWEEN_R; +"KLE_IMP_POINTWISE",KLE_IMP_POINTWISE; +"KLE_MAXIMAL",KLE_MAXIMAL; +"KLE_MINIMAL",KLE_MINIMAL; +"KLE_RANGE_COMBINE",KLE_RANGE_COMBINE; +"KLE_RANGE_COMBINE_L",KLE_RANGE_COMBINE_L; +"KLE_RANGE_COMBINE_R",KLE_RANGE_COMBINE_R; +"KLE_RANGE_INDUCT",KLE_RANGE_INDUCT; +"KLE_REFL",KLE_REFL; +"KLE_STRICT",KLE_STRICT; +"KLE_STRICT_SET",KLE_STRICT_SET; +"KLE_SUC",KLE_SUC; +"KLE_TRANS",KLE_TRANS; +"KLE_TRANS_1",KLE_TRANS_1; +"KLE_TRANS_2",KLE_TRANS_2; +"KL_POSET_LEMMA",KL_POSET_LEMMA; +"KREIN_MILMAN",KREIN_MILMAN; +"KREIN_MILMAN_FRONTIER",KREIN_MILMAN_FRONTIER; +"KREIN_MILMAN_MINKOWSKI",KREIN_MILMAN_MINKOWSKI; +"KREIN_MILMAN_POLYTOPE",KREIN_MILMAN_POLYTOPE; +"KREIN_MILMAN_RELATIVE_FRONTIER",KREIN_MILMAN_RELATIVE_FRONTIER; +"KSIMPLEX_0",KSIMPLEX_0; +"KSIMPLEX_EXTREMA",KSIMPLEX_EXTREMA; +"KSIMPLEX_EXTREMA_STRONG",KSIMPLEX_EXTREMA_STRONG; +"KSIMPLEX_FIX_PLANE",KSIMPLEX_FIX_PLANE; +"KSIMPLEX_FIX_PLANE_0",KSIMPLEX_FIX_PLANE_0; +"KSIMPLEX_FIX_PLANE_P",KSIMPLEX_FIX_PLANE_P; +"KSIMPLEX_PREDECESSOR",KSIMPLEX_PREDECESSOR; +"KSIMPLEX_REPLACE_0",KSIMPLEX_REPLACE_0; +"KSIMPLEX_REPLACE_1",KSIMPLEX_REPLACE_1; +"KSIMPLEX_REPLACE_2",KSIMPLEX_REPLACE_2; +"KSIMPLEX_SUCCESSOR",KSIMPLEX_SUCCESSOR; +"KUHN_COMBINATORIAL",KUHN_COMBINATORIAL; +"KUHN_COMPLETE_LEMMA",KUHN_COMPLETE_LEMMA; +"KUHN_COUNTING_LEMMA",KUHN_COUNTING_LEMMA; +"KUHN_INDUCTION",KUHN_INDUCTION; +"KUHN_LABELLING_LEMMA",KUHN_LABELLING_LEMMA; +"KUHN_LEMMA",KUHN_LEMMA; +"KUHN_SIMPLEX_LEMMA",KUHN_SIMPLEX_LEMMA; +"L1_LE_NORM",L1_LE_NORM; +"LAMBDA_ADD_GALOIS",LAMBDA_ADD_GALOIS; +"LAMBDA_BETA",LAMBDA_BETA; +"LAMBDA_BETA_PERM",LAMBDA_BETA_PERM; +"LAMBDA_ETA",LAMBDA_ETA; +"LAMBDA_PAIR",LAMBDA_PAIR; +"LAMBDA_PAIR_THM",LAMBDA_PAIR_THM; +"LAMBDA_SKOLEM",LAMBDA_SKOLEM; +"LAMBDA_SWAP_GALOIS",LAMBDA_SWAP_GALOIS; +"LAMBDA_UNIQUE",LAMBDA_UNIQUE; +"LAST",LAST; +"LAST_APPEND",LAST_APPEND; +"LAST_CLAUSES",LAST_CLAUSES; +"LAST_EL",LAST_EL; +"LE",LE; +"LEBESGUE_COVERING_LEMMA",LEBESGUE_COVERING_LEMMA; +"LEBESGUE_MEASURABLE_CLOSED",LEBESGUE_MEASURABLE_CLOSED; +"LEBESGUE_MEASURABLE_COMPACT",LEBESGUE_MEASURABLE_COMPACT; +"LEBESGUE_MEASURABLE_COMPL",LEBESGUE_MEASURABLE_COMPL; +"LEBESGUE_MEASURABLE_CONTINUOUS_IMAGE",LEBESGUE_MEASURABLE_CONTINUOUS_IMAGE; +"LEBESGUE_MEASURABLE_CONVEX",LEBESGUE_MEASURABLE_CONVEX; +"LEBESGUE_MEASURABLE_COUNTABLE_INTERS",LEBESGUE_MEASURABLE_COUNTABLE_INTERS; +"LEBESGUE_MEASURABLE_COUNTABLE_INTERS_EXPLICIT",LEBESGUE_MEASURABLE_COUNTABLE_INTERS_EXPLICIT; +"LEBESGUE_MEASURABLE_COUNTABLE_UNIONS",LEBESGUE_MEASURABLE_COUNTABLE_UNIONS; +"LEBESGUE_MEASURABLE_COUNTABLE_UNIONS_EXPLICIT",LEBESGUE_MEASURABLE_COUNTABLE_UNIONS_EXPLICIT; +"LEBESGUE_MEASURABLE_DIFF",LEBESGUE_MEASURABLE_DIFF; +"LEBESGUE_MEASURABLE_DIFFERENTIABLE_IMAGE",LEBESGUE_MEASURABLE_DIFFERENTIABLE_IMAGE; +"LEBESGUE_MEASURABLE_EMPTY",LEBESGUE_MEASURABLE_EMPTY; +"LEBESGUE_MEASURABLE_IFF_MEASURABLE",LEBESGUE_MEASURABLE_IFF_MEASURABLE; +"LEBESGUE_MEASURABLE_INNER_CLOSED",LEBESGUE_MEASURABLE_INNER_CLOSED; +"LEBESGUE_MEASURABLE_INTER",LEBESGUE_MEASURABLE_INTER; +"LEBESGUE_MEASURABLE_INTERS",LEBESGUE_MEASURABLE_INTERS; +"LEBESGUE_MEASURABLE_INTERVAL",LEBESGUE_MEASURABLE_INTERVAL; +"LEBESGUE_MEASURABLE_JORDAN",LEBESGUE_MEASURABLE_JORDAN; +"LEBESGUE_MEASURABLE_LEBESGUE_MEASURABLE_PREIMAGE_CLOSED",LEBESGUE_MEASURABLE_LEBESGUE_MEASURABLE_PREIMAGE_CLOSED; +"LEBESGUE_MEASURABLE_LEBESGUE_MEASURABLE_PREIMAGE_OPEN",LEBESGUE_MEASURABLE_LEBESGUE_MEASURABLE_PREIMAGE_OPEN; +"LEBESGUE_MEASURABLE_LINEAR_IMAGE_EQ",LEBESGUE_MEASURABLE_LINEAR_IMAGE_EQ; +"LEBESGUE_MEASURABLE_ON_SUBINTERVALS",LEBESGUE_MEASURABLE_ON_SUBINTERVALS; +"LEBESGUE_MEASURABLE_OPEN",LEBESGUE_MEASURABLE_OPEN; +"LEBESGUE_MEASURABLE_OUTER_OPEN",LEBESGUE_MEASURABLE_OUTER_OPEN; +"LEBESGUE_MEASURABLE_PREIMAGE_CLOSED",LEBESGUE_MEASURABLE_PREIMAGE_CLOSED; +"LEBESGUE_MEASURABLE_PREIMAGE_OPEN",LEBESGUE_MEASURABLE_PREIMAGE_OPEN; +"LEBESGUE_MEASURABLE_REGULAR_INNER",LEBESGUE_MEASURABLE_REGULAR_INNER; +"LEBESGUE_MEASURABLE_REGULAR_OUTER",LEBESGUE_MEASURABLE_REGULAR_OUTER; +"LEBESGUE_MEASURABLE_TRANSLATION",LEBESGUE_MEASURABLE_TRANSLATION; +"LEBESGUE_MEASURABLE_UNION",LEBESGUE_MEASURABLE_UNION; +"LEBESGUE_MEASURABLE_UNIONS",LEBESGUE_MEASURABLE_UNIONS; +"LEBESGUE_MEASURABLE_UNIV",LEBESGUE_MEASURABLE_UNIV; +"LEFT_ADD_DISTRIB",LEFT_ADD_DISTRIB; +"LEFT_AND_EXISTS_THM",LEFT_AND_EXISTS_THM; +"LEFT_AND_FORALL_THM",LEFT_AND_FORALL_THM; +"LEFT_EXISTS_AND_THM",LEFT_EXISTS_AND_THM; +"LEFT_EXISTS_IMP_THM",LEFT_EXISTS_IMP_THM; +"LEFT_FORALL_IMP_THM",LEFT_FORALL_IMP_THM; +"LEFT_FORALL_OR_THM",LEFT_FORALL_OR_THM; +"LEFT_IMP_EXISTS_THM",LEFT_IMP_EXISTS_THM; +"LEFT_IMP_FORALL_THM",LEFT_IMP_FORALL_THM; +"LEFT_INVERSE_LINEAR",LEFT_INVERSE_LINEAR; +"LEFT_INVERTIBLE_TRANSP",LEFT_INVERTIBLE_TRANSP; +"LEFT_OR_DISTRIB",LEFT_OR_DISTRIB; +"LEFT_OR_EXISTS_THM",LEFT_OR_EXISTS_THM; +"LEFT_OR_FORALL_THM",LEFT_OR_FORALL_THM; +"LEFT_RIGHT_INVERSE_EQ",LEFT_RIGHT_INVERSE_EQ; +"LEFT_RIGHT_INVERSE_LINEAR",LEFT_RIGHT_INVERSE_LINEAR; +"LEFT_SUB_DISTRIB",LEFT_SUB_DISTRIB; +"LEMMA",LEMMA; +"LENGTH",LENGTH; +"LENGTH_APPEND",LENGTH_APPEND; +"LENGTH_EQ_CONS",LENGTH_EQ_CONS; +"LENGTH_EQ_NIL",LENGTH_EQ_NIL; +"LENGTH_LIST_OF_SET",LENGTH_LIST_OF_SET; +"LENGTH_MAP",LENGTH_MAP; +"LENGTH_MAP2",LENGTH_MAP2; +"LENGTH_REPLICATE",LENGTH_REPLICATE; +"LENGTH_TL",LENGTH_TL; +"LET_ADD2",LET_ADD2; +"LET_ANTISYM",LET_ANTISYM; +"LET_CASES",LET_CASES; +"LET_DEF",LET_DEF; +"LET_END_DEF",LET_END_DEF; +"LET_TRANS",LET_TRANS; +"LE_0",LE_0; +"LE_1",LE_1; +"LE_ADD",LE_ADD; +"LE_ADD2",LE_ADD2; +"LE_ADDR",LE_ADDR; +"LE_ADD_LCANCEL",LE_ADD_LCANCEL; +"LE_ADD_RCANCEL",LE_ADD_RCANCEL; +"LE_ANTISYM",LE_ANTISYM; +"LE_C",LE_C; +"LE_CASES",LE_CASES; +"LE_EXISTS",LE_EXISTS; +"LE_EXP",LE_EXP; +"LE_LDIV",LE_LDIV; +"LE_LDIV_EQ",LE_LDIV_EQ; +"LE_LT",LE_LT; +"LE_MULT2",LE_MULT2; +"LE_MULT_LCANCEL",LE_MULT_LCANCEL; +"LE_MULT_RCANCEL",LE_MULT_RCANCEL; +"LE_RDIV_EQ",LE_RDIV_EQ; +"LE_REFL",LE_REFL; +"LE_SQUARE_REFL",LE_SQUARE_REFL; +"LE_SUC",LE_SUC; +"LE_SUC_LT",LE_SUC_LT; +"LE_TRANS",LE_TRANS; +"LIFT_ADD",LIFT_ADD; +"LIFT_CMUL",LIFT_CMUL; +"LIFT_COMPONENT",LIFT_COMPONENT; +"LIFT_DROP",LIFT_DROP; +"LIFT_EQ",LIFT_EQ; +"LIFT_EQ_CMUL",LIFT_EQ_CMUL; +"LIFT_INTEGRAL_COMPONENT",LIFT_INTEGRAL_COMPONENT; +"LIFT_IN_IMAGE_LIFT",LIFT_IN_IMAGE_LIFT; +"LIFT_NEG",LIFT_NEG; +"LIFT_NUM",LIFT_NUM; +"LIFT_SUB",LIFT_SUB; +"LIFT_SUM",LIFT_SUM; +"LIM",LIM; +"LIMIT_POINT_FINITE",LIMIT_POINT_FINITE; +"LIMIT_POINT_OF_SPHERE",LIMIT_POINT_OF_SPHERE; +"LIMIT_POINT_UNION",LIMIT_POINT_UNION; +"LIMPT_APPROACHABLE",LIMPT_APPROACHABLE; +"LIMPT_APPROACHABLE_LE",LIMPT_APPROACHABLE_LE; +"LIMPT_APPROACHABLE_LIFT",LIMPT_APPROACHABLE_LIFT; +"LIMPT_BALL",LIMPT_BALL; +"LIMPT_EMPTY",LIMPT_EMPTY; +"LIMPT_INFINITE_BALL",LIMPT_INFINITE_BALL; +"LIMPT_INFINITE_CBALL",LIMPT_INFINITE_CBALL; +"LIMPT_INFINITE_OPEN",LIMPT_INFINITE_OPEN; +"LIMPT_INJECTIVE_LINEAR_IMAGE_EQ",LIMPT_INJECTIVE_LINEAR_IMAGE_EQ; +"LIMPT_INSERT",LIMPT_INSERT; +"LIMPT_OF_CLOSURE",LIMPT_OF_CLOSURE; +"LIMPT_OF_CONDENSATION_POINTS",LIMPT_OF_CONDENSATION_POINTS; +"LIMPT_OF_CONVEX",LIMPT_OF_CONVEX; +"LIMPT_OF_LIMPTS",LIMPT_OF_LIMPTS; +"LIMPT_OF_OPEN",LIMPT_OF_OPEN; +"LIMPT_OF_OPEN_IN",LIMPT_OF_OPEN_IN; +"LIMPT_OF_SEQUENCE_SUBSEQUENCE",LIMPT_OF_SEQUENCE_SUBSEQUENCE; +"LIMPT_OF_UNIV",LIMPT_OF_UNIV; +"LIMPT_PCROSS",LIMPT_PCROSS; +"LIMPT_SEQUENTIAL",LIMPT_SEQUENTIAL; +"LIMPT_SEQUENTIAL_INJ",LIMPT_SEQUENTIAL_INJ; +"LIMPT_SING",LIMPT_SING; +"LIMPT_SUBSET",LIMPT_SUBSET; +"LIMPT_TRANSLATION_EQ",LIMPT_TRANSLATION_EQ; +"LIMPT_UNIV",LIMPT_UNIV; +"LIM_ABS",LIM_ABS; +"LIM_ADD",LIM_ADD; +"LIM_AT",LIM_AT; +"LIM_AT_ID",LIM_AT_ID; +"LIM_AT_INFINITY",LIM_AT_INFINITY; +"LIM_AT_WITHIN",LIM_AT_WITHIN; +"LIM_AT_ZERO",LIM_AT_ZERO; +"LIM_BILINEAR",LIM_BILINEAR; +"LIM_CASES_COFINITE_SEQUENTIALLY",LIM_CASES_COFINITE_SEQUENTIALLY; +"LIM_CASES_FINITE_SEQUENTIALLY",LIM_CASES_FINITE_SEQUENTIALLY; +"LIM_CASES_SEQUENTIALLY",LIM_CASES_SEQUENTIALLY; +"LIM_CMUL",LIM_CMUL; +"LIM_CMUL_EQ",LIM_CMUL_EQ; +"LIM_COMPONENT",LIM_COMPONENT; +"LIM_COMPONENTWISE_LIFT",LIM_COMPONENTWISE_LIFT; +"LIM_COMPONENT_EQ",LIM_COMPONENT_EQ; +"LIM_COMPONENT_LBOUND",LIM_COMPONENT_LBOUND; +"LIM_COMPONENT_LE",LIM_COMPONENT_LE; +"LIM_COMPONENT_UBOUND",LIM_COMPONENT_UBOUND; +"LIM_COMPOSE_AT",LIM_COMPOSE_AT; +"LIM_COMPOSE_WITHIN",LIM_COMPOSE_WITHIN; +"LIM_CONG_AT",LIM_CONG_AT; +"LIM_CONG_WITHIN",LIM_CONG_WITHIN; +"LIM_CONST",LIM_CONST; +"LIM_CONST_EQ",LIM_CONST_EQ; +"LIM_CONTINUOUS_FUNCTION",LIM_CONTINUOUS_FUNCTION; +"LIM_DROP_LBOUND",LIM_DROP_LBOUND; +"LIM_DROP_LE",LIM_DROP_LE; +"LIM_DROP_UBOUND",LIM_DROP_UBOUND; +"LIM_EVENTUALLY",LIM_EVENTUALLY; +"LIM_INV",LIM_INV; +"LIM_IN_CLOSED_SET",LIM_IN_CLOSED_SET; +"LIM_LIFT_DOT",LIM_LIFT_DOT; +"LIM_LINEAR",LIM_LINEAR; +"LIM_MAX",LIM_MAX; +"LIM_MIN",LIM_MIN; +"LIM_MUL",LIM_MUL; +"LIM_MUL_NORM_WITHIN",LIM_MUL_NORM_WITHIN; +"LIM_NEG",LIM_NEG; +"LIM_NEG_EQ",LIM_NEG_EQ; +"LIM_NORM",LIM_NORM; +"LIM_NORM_LBOUND",LIM_NORM_LBOUND; +"LIM_NORM_UBOUND",LIM_NORM_UBOUND; +"LIM_NULL",LIM_NULL; +"LIM_NULL_CMUL_BOUNDED",LIM_NULL_CMUL_BOUNDED; +"LIM_NULL_CMUL_EQ",LIM_NULL_CMUL_EQ; +"LIM_NULL_COMPARISON",LIM_NULL_COMPARISON; +"LIM_NULL_NORM",LIM_NULL_NORM; +"LIM_NULL_VMUL_BOUNDED",LIM_NULL_VMUL_BOUNDED; +"LIM_PASTECART",LIM_PASTECART; +"LIM_PASTECART_EQ",LIM_PASTECART_EQ; +"LIM_SEQUENTIALLY",LIM_SEQUENTIALLY; +"LIM_SUB",LIM_SUB; +"LIM_SUBSEQUENCE",LIM_SUBSEQUENCE; +"LIM_TRANSFORM",LIM_TRANSFORM; +"LIM_TRANSFORM_AT",LIM_TRANSFORM_AT; +"LIM_TRANSFORM_AWAY_AT",LIM_TRANSFORM_AWAY_AT; +"LIM_TRANSFORM_AWAY_WITHIN",LIM_TRANSFORM_AWAY_WITHIN; +"LIM_TRANSFORM_BOUND",LIM_TRANSFORM_BOUND; +"LIM_TRANSFORM_EQ",LIM_TRANSFORM_EQ; +"LIM_TRANSFORM_EVENTUALLY",LIM_TRANSFORM_EVENTUALLY; +"LIM_TRANSFORM_WITHIN",LIM_TRANSFORM_WITHIN; +"LIM_TRANSFORM_WITHIN_OPEN",LIM_TRANSFORM_WITHIN_OPEN; +"LIM_TRANSFORM_WITHIN_SET",LIM_TRANSFORM_WITHIN_SET; +"LIM_UNION",LIM_UNION; +"LIM_UNION_UNIV",LIM_UNION_UNIV; +"LIM_UNIQUE",LIM_UNIQUE; +"LIM_VMUL",LIM_VMUL; +"LIM_VSUM",LIM_VSUM; +"LIM_WITHIN",LIM_WITHIN; +"LIM_WITHIN_CLOSED_TRIVIAL",LIM_WITHIN_CLOSED_TRIVIAL; +"LIM_WITHIN_EMPTY",LIM_WITHIN_EMPTY; +"LIM_WITHIN_ID",LIM_WITHIN_ID; +"LIM_WITHIN_INTERIOR",LIM_WITHIN_INTERIOR; +"LIM_WITHIN_LE",LIM_WITHIN_LE; +"LIM_WITHIN_OPEN",LIM_WITHIN_OPEN; +"LIM_WITHIN_SUBSET",LIM_WITHIN_SUBSET; +"LIM_WITHIN_UNION",LIM_WITHIN_UNION; +"LINDELOF",LINDELOF; +"LINDELOF_OPEN_IN",LINDELOF_OPEN_IN; +"LINEAR_0",LINEAR_0; +"LINEAR_1",LINEAR_1; +"LINEAR_ADD",LINEAR_ADD; +"LINEAR_BIJECTIVE_DIMINDEX_EQ",LINEAR_BIJECTIVE_DIMINDEX_EQ; +"LINEAR_BIJECTIVE_LEFT_RIGHT_INVERSE",LINEAR_BIJECTIVE_LEFT_RIGHT_INVERSE; +"LINEAR_BOUNDED",LINEAR_BOUNDED; +"LINEAR_BOUNDED_POS",LINEAR_BOUNDED_POS; +"LINEAR_CMUL",LINEAR_CMUL; +"LINEAR_COMPONENTWISE",LINEAR_COMPONENTWISE; +"LINEAR_COMPONENTWISE_EXPANSION",LINEAR_COMPONENTWISE_EXPANSION; +"LINEAR_COMPOSE",LINEAR_COMPOSE; +"LINEAR_COMPOSE_ADD",LINEAR_COMPOSE_ADD; +"LINEAR_COMPOSE_CMUL",LINEAR_COMPOSE_CMUL; +"LINEAR_COMPOSE_NEG",LINEAR_COMPOSE_NEG; +"LINEAR_COMPOSE_SUB",LINEAR_COMPOSE_SUB; +"LINEAR_COMPOSE_VSUM",LINEAR_COMPOSE_VSUM; +"LINEAR_CONTINUOUS_AT",LINEAR_CONTINUOUS_AT; +"LINEAR_CONTINUOUS_COMPOSE",LINEAR_CONTINUOUS_COMPOSE; +"LINEAR_CONTINUOUS_ON",LINEAR_CONTINUOUS_ON; +"LINEAR_CONTINUOUS_ON_COMPOSE",LINEAR_CONTINUOUS_ON_COMPOSE; +"LINEAR_CONTINUOUS_WITHIN",LINEAR_CONTINUOUS_WITHIN; +"LINEAR_EQ",LINEAR_EQ; +"LINEAR_EQ_0",LINEAR_EQ_0; +"LINEAR_EQ_0_SPAN",LINEAR_EQ_0_SPAN; +"LINEAR_EQ_MATRIX",LINEAR_EQ_MATRIX; +"LINEAR_EQ_MBASIS",LINEAR_EQ_MBASIS; +"LINEAR_EQ_STDBASIS",LINEAR_EQ_STDBASIS; +"LINEAR_FRECHET_DERIVATIVE",LINEAR_FRECHET_DERIVATIVE; +"LINEAR_FROM_REALS",LINEAR_FROM_REALS; +"LINEAR_FSTCART",LINEAR_FSTCART; +"LINEAR_I",LINEAR_I; +"LINEAR_ID",LINEAR_ID; +"LINEAR_IMAGE_SUBSET_INTERIOR",LINEAR_IMAGE_SUBSET_INTERIOR; +"LINEAR_INDEPENDENT_EXTEND",LINEAR_INDEPENDENT_EXTEND; +"LINEAR_INDEPENDENT_EXTEND_LEMMA",LINEAR_INDEPENDENT_EXTEND_LEMMA; +"LINEAR_INDEP_IMAGE_LEMMA",LINEAR_INDEP_IMAGE_LEMMA; +"LINEAR_INJECTIVE_0",LINEAR_INJECTIVE_0; +"LINEAR_INJECTIVE_0_SUBSPACE",LINEAR_INJECTIVE_0_SUBSPACE; +"LINEAR_INJECTIVE_BOUNDED_BELOW_POS",LINEAR_INJECTIVE_BOUNDED_BELOW_POS; +"LINEAR_INJECTIVE_DIMINDEX_LE",LINEAR_INJECTIVE_DIMINDEX_LE; +"LINEAR_INJECTIVE_IMP_SURJECTIVE",LINEAR_INJECTIVE_IMP_SURJECTIVE; +"LINEAR_INJECTIVE_ISOMORPHISM",LINEAR_INJECTIVE_ISOMORPHISM; +"LINEAR_INJECTIVE_LEFT_INVERSE",LINEAR_INJECTIVE_LEFT_INVERSE; +"LINEAR_INTERIOR_IMAGE_SUBSET",LINEAR_INTERIOR_IMAGE_SUBSET; +"LINEAR_INVERSE_LEFT",LINEAR_INVERSE_LEFT; +"LINEAR_INVERTIBLE_BOUNDED_BELOW",LINEAR_INVERTIBLE_BOUNDED_BELOW; +"LINEAR_INVERTIBLE_BOUNDED_BELOW_POS",LINEAR_INVERTIBLE_BOUNDED_BELOW_POS; +"LINEAR_LIFT_COMPONENT",LINEAR_LIFT_COMPONENT; +"LINEAR_LIFT_DOT",LINEAR_LIFT_DOT; +"LINEAR_LIM_0",LINEAR_LIM_0; +"LINEAR_MATRIX_EXISTS",LINEAR_MATRIX_EXISTS; +"LINEAR_NEG",LINEAR_NEG; +"LINEAR_NEGATION",LINEAR_NEGATION; +"LINEAR_OPEN_MAPPING",LINEAR_OPEN_MAPPING; +"LINEAR_PASTECART",LINEAR_PASTECART; +"LINEAR_PROPERTY",LINEAR_PROPERTY; +"LINEAR_REFLECT_ALONG",LINEAR_REFLECT_ALONG; +"LINEAR_SCALING",LINEAR_SCALING; +"LINEAR_SINGULAR_IMAGE_HYPERPLANE",LINEAR_SINGULAR_IMAGE_HYPERPLANE; +"LINEAR_SINGULAR_INTO_HYPERPLANE",LINEAR_SINGULAR_INTO_HYPERPLANE; +"LINEAR_SNDCART",LINEAR_SNDCART; +"LINEAR_SUB",LINEAR_SUB; +"LINEAR_SUBSPACE_GRAPH",LINEAR_SUBSPACE_GRAPH; +"LINEAR_SURJECTIVE_DIMINDEX_LE",LINEAR_SURJECTIVE_DIMINDEX_LE; +"LINEAR_SURJECTIVE_IFF_INJECTIVE",LINEAR_SURJECTIVE_IFF_INJECTIVE; +"LINEAR_SURJECTIVE_IMP_INJECTIVE",LINEAR_SURJECTIVE_IMP_INJECTIVE; +"LINEAR_SURJECTIVE_ISOMORPHISM",LINEAR_SURJECTIVE_ISOMORPHISM; +"LINEAR_SURJECTIVE_RIGHT_INVERSE",LINEAR_SURJECTIVE_RIGHT_INVERSE; +"LINEAR_TO_REALS",LINEAR_TO_REALS; +"LINEAR_UNIFORMLY_CONTINUOUS_ON",LINEAR_UNIFORMLY_CONTINUOUS_ON; +"LINEAR_VMUL_COMPONENT",LINEAR_VMUL_COMPONENT; +"LINEAR_VMUL_DROP",LINEAR_VMUL_DROP; +"LINEAR_VSUM",LINEAR_VSUM; +"LINEAR_VSUM_MUL",LINEAR_VSUM_MUL; +"LINEAR_ZERO",LINEAR_ZERO; +"LINEPATH_LINEAR_IMAGE",LINEPATH_LINEAR_IMAGE; +"LINEPATH_REFL",LINEPATH_REFL; +"LINEPATH_TRANSLATION",LINEPATH_TRANSLATION; +"LINSEG_FL",LINSEG_FL; +"LINSEG_INSEG",LINSEG_INSEG; +"LINSEG_WOSET",LINSEG_WOSET; +"LIST_OF_SET_PROPERTIES",LIST_OF_SET_PROPERTIES; +"LOCALLY_CLOSED",LOCALLY_CLOSED; +"LOCALLY_COMPACT",LOCALLY_COMPACT; +"LOCALLY_COMPACT_CLOSED_IN",LOCALLY_COMPACT_CLOSED_IN; +"LOCALLY_COMPACT_CLOSED_IN_OPEN",LOCALLY_COMPACT_CLOSED_IN_OPEN; +"LOCALLY_COMPACT_HOMEOMORPHIC_CLOSED",LOCALLY_COMPACT_HOMEOMORPHIC_CLOSED; +"LOCALLY_COMPACT_HOMEOMORPHISM_PROJECTION_CLOSED",LOCALLY_COMPACT_HOMEOMORPHISM_PROJECTION_CLOSED; +"LOCALLY_COMPACT_INTER",LOCALLY_COMPACT_INTER; +"LOCALLY_COMPACT_LINEAR_IMAGE_EQ",LOCALLY_COMPACT_LINEAR_IMAGE_EQ; +"LOCALLY_COMPACT_OPEN_IN",LOCALLY_COMPACT_OPEN_IN; +"LOCALLY_COMPACT_OPEN_INTER_CLOSURE",LOCALLY_COMPACT_OPEN_INTER_CLOSURE; +"LOCALLY_COMPACT_TRANSLATION_EQ",LOCALLY_COMPACT_TRANSLATION_EQ; +"LOCALLY_COMPACT_UNIV",LOCALLY_COMPACT_UNIV; +"LOCALLY_CONNECTED",LOCALLY_CONNECTED; +"LOCALLY_CONNECTED_COMPONENTS",LOCALLY_CONNECTED_COMPONENTS; +"LOCALLY_CONNECTED_CONNECTED_COMPONENT",LOCALLY_CONNECTED_CONNECTED_COMPONENT; +"LOCALLY_CONNECTED_CONTINUOUS_IMAGE_COMPACT",LOCALLY_CONNECTED_CONTINUOUS_IMAGE_COMPACT; +"LOCALLY_CONNECTED_IM_KLEINEN",LOCALLY_CONNECTED_IM_KLEINEN; +"LOCALLY_CONNECTED_LEFT_INVERTIBLE_IMAGE",LOCALLY_CONNECTED_LEFT_INVERTIBLE_IMAGE; +"LOCALLY_CONNECTED_LINEAR_IMAGE_EQ",LOCALLY_CONNECTED_LINEAR_IMAGE_EQ; +"LOCALLY_CONNECTED_OPEN_COMPONENT",LOCALLY_CONNECTED_OPEN_COMPONENT; +"LOCALLY_CONNECTED_OPEN_CONNECTED_COMPONENT",LOCALLY_CONNECTED_OPEN_CONNECTED_COMPONENT; +"LOCALLY_CONNECTED_PATH_IMAGE",LOCALLY_CONNECTED_PATH_IMAGE; +"LOCALLY_CONNECTED_PCROSS",LOCALLY_CONNECTED_PCROSS; +"LOCALLY_CONNECTED_PCROSS_EQ",LOCALLY_CONNECTED_PCROSS_EQ; +"LOCALLY_CONNECTED_QUOTIENT_IMAGE",LOCALLY_CONNECTED_QUOTIENT_IMAGE; +"LOCALLY_CONNECTED_RIGHT_INVERTIBLE_IMAGE",LOCALLY_CONNECTED_RIGHT_INVERTIBLE_IMAGE; +"LOCALLY_CONNECTED_SPHERE",LOCALLY_CONNECTED_SPHERE; +"LOCALLY_CONNECTED_SPHERE_GEN",LOCALLY_CONNECTED_SPHERE_GEN; +"LOCALLY_CONNECTED_TRANSLATION_EQ",LOCALLY_CONNECTED_TRANSLATION_EQ; +"LOCALLY_CONNECTED_UNIV",LOCALLY_CONNECTED_UNIV; +"LOCALLY_DIFF_CLOSED",LOCALLY_DIFF_CLOSED; +"LOCALLY_EMPTY",LOCALLY_EMPTY; +"LOCALLY_INJECTIVE_LINEAR_IMAGE",LOCALLY_INJECTIVE_LINEAR_IMAGE; +"LOCALLY_INTER",LOCALLY_INTER; +"LOCALLY_MONO",LOCALLY_MONO; +"LOCALLY_OPEN_MAP_IMAGE",LOCALLY_OPEN_MAP_IMAGE; +"LOCALLY_OPEN_SUBSET",LOCALLY_OPEN_SUBSET; +"LOCALLY_PATH_CONNECTED",LOCALLY_PATH_CONNECTED; +"LOCALLY_PATH_CONNECTED_COMPONENTS",LOCALLY_PATH_CONNECTED_COMPONENTS; +"LOCALLY_PATH_CONNECTED_CONNECTED_COMPONENT",LOCALLY_PATH_CONNECTED_CONNECTED_COMPONENT; +"LOCALLY_PATH_CONNECTED_CONTINUOUS_IMAGE_COMPACT",LOCALLY_PATH_CONNECTED_CONTINUOUS_IMAGE_COMPACT; +"LOCALLY_PATH_CONNECTED_IMP_LOCALLY_CONNECTED",LOCALLY_PATH_CONNECTED_IMP_LOCALLY_CONNECTED; +"LOCALLY_PATH_CONNECTED_IM_KLEINEN",LOCALLY_PATH_CONNECTED_IM_KLEINEN; +"LOCALLY_PATH_CONNECTED_LEFT_INVERTIBLE_IMAGE",LOCALLY_PATH_CONNECTED_LEFT_INVERTIBLE_IMAGE; +"LOCALLY_PATH_CONNECTED_LINEAR_IMAGE_EQ",LOCALLY_PATH_CONNECTED_LINEAR_IMAGE_EQ; +"LOCALLY_PATH_CONNECTED_OPEN_PATH_COMPONENT",LOCALLY_PATH_CONNECTED_OPEN_PATH_COMPONENT; +"LOCALLY_PATH_CONNECTED_PATH_COMPONENT",LOCALLY_PATH_CONNECTED_PATH_COMPONENT; +"LOCALLY_PATH_CONNECTED_PATH_IMAGE",LOCALLY_PATH_CONNECTED_PATH_IMAGE; +"LOCALLY_PATH_CONNECTED_PCROSS",LOCALLY_PATH_CONNECTED_PCROSS; +"LOCALLY_PATH_CONNECTED_PCROSS_EQ",LOCALLY_PATH_CONNECTED_PCROSS_EQ; +"LOCALLY_PATH_CONNECTED_QUOTIENT_IMAGE",LOCALLY_PATH_CONNECTED_QUOTIENT_IMAGE; +"LOCALLY_PATH_CONNECTED_RIGHT_INVERTIBLE_IMAGE",LOCALLY_PATH_CONNECTED_RIGHT_INVERTIBLE_IMAGE; +"LOCALLY_PATH_CONNECTED_SPHERE",LOCALLY_PATH_CONNECTED_SPHERE; +"LOCALLY_PATH_CONNECTED_SPHERE_GEN",LOCALLY_PATH_CONNECTED_SPHERE_GEN; +"LOCALLY_PATH_CONNECTED_TRANSLATION_EQ",LOCALLY_PATH_CONNECTED_TRANSLATION_EQ; +"LOCALLY_PATH_CONNECTED_UNIV",LOCALLY_PATH_CONNECTED_UNIV; +"LOCALLY_PCROSS",LOCALLY_PCROSS; +"LOCALLY_SING",LOCALLY_SING; +"LOCALLY_TRANSLATION",LOCALLY_TRANSLATION; +"LOWDIM_EQ_HYPERPLANE",LOWDIM_EQ_HYPERPLANE; +"LOWDIM_EXPAND_BASIS",LOWDIM_EXPAND_BASIS; +"LOWDIM_EXPAND_DIMENSION",LOWDIM_EXPAND_DIMENSION; +"LOWDIM_SUBSET_HYPERPLANE",LOWDIM_SUBSET_HYPERPLANE; +"LOWER_BOUND_FINITE_SET",LOWER_BOUND_FINITE_SET; +"LOWER_BOUND_FINITE_SET_REAL",LOWER_BOUND_FINITE_SET_REAL; +"LT",LT; +"LTE_ADD2",LTE_ADD2; +"LTE_ANTISYM",LTE_ANTISYM; +"LTE_CASES",LTE_CASES; +"LTE_TRANS",LTE_TRANS; +"LT_0",LT_0; +"LT_ADD",LT_ADD; +"LT_ADD2",LT_ADD2; +"LT_ADDR",LT_ADDR; +"LT_ADD_LCANCEL",LT_ADD_LCANCEL; +"LT_ADD_RCANCEL",LT_ADD_RCANCEL; +"LT_ANTISYM",LT_ANTISYM; +"LT_CASES",LT_CASES; +"LT_EXISTS",LT_EXISTS; +"LT_EXP",LT_EXP; +"LT_IMP_LE",LT_IMP_LE; +"LT_LE",LT_LE; +"LT_LMULT",LT_LMULT; +"LT_MULT",LT_MULT; +"LT_MULT2",LT_MULT2; +"LT_MULT_LCANCEL",LT_MULT_LCANCEL; +"LT_MULT_RCANCEL",LT_MULT_RCANCEL; +"LT_NZ",LT_NZ; +"LT_POW2_REFL",LT_POW2_REFL; +"LT_REFL",LT_REFL; +"LT_SUC",LT_SUC; +"LT_SUC_LE",LT_SUC_LE; +"LT_TRANS",LT_TRANS; +"LUZIN",LUZIN; +"LUZIN_EQ",LUZIN_EQ; +"LUZIN_EQ_ALT",LUZIN_EQ_ALT; +"MAP",MAP; +"MAP2",MAP2; +"MAP2_DEF",MAP2_DEF; +"MAP_APPEND",MAP_APPEND; +"MAP_EQ",MAP_EQ; +"MAP_EQ_ALL2",MAP_EQ_ALL2; +"MAP_EQ_DEGEN",MAP_EQ_DEGEN; +"MAP_EQ_NIL",MAP_EQ_NIL; +"MAP_FST_ZIP",MAP_FST_ZIP; +"MAP_I",MAP_I; +"MAP_ID",MAP_ID; +"MAP_REVERSE",MAP_REVERSE; +"MAP_SND_ZIP",MAP_SND_ZIP; +"MAP_o",MAP_o; +"MATCH_SEQPATTERN",MATCH_SEQPATTERN; +"MATRIX_ADD_AC",MATRIX_ADD_AC; +"MATRIX_ADD_ASSOC",MATRIX_ADD_ASSOC; +"MATRIX_ADD_COMPONENT",MATRIX_ADD_COMPONENT; +"MATRIX_ADD_LDISTRIB",MATRIX_ADD_LDISTRIB; +"MATRIX_ADD_LID",MATRIX_ADD_LID; +"MATRIX_ADD_LNEG",MATRIX_ADD_LNEG; +"MATRIX_ADD_RDISTRIB",MATRIX_ADD_RDISTRIB; +"MATRIX_ADD_RID",MATRIX_ADD_RID; +"MATRIX_ADD_RNEG",MATRIX_ADD_RNEG; +"MATRIX_ADD_SYM",MATRIX_ADD_SYM; +"MATRIX_ADJOINT",MATRIX_ADJOINT; +"MATRIX_CMUL_ADD_LDISTRIB",MATRIX_CMUL_ADD_LDISTRIB; +"MATRIX_CMUL_ADD_RDISTRIB",MATRIX_CMUL_ADD_RDISTRIB; +"MATRIX_CMUL_ASSOC",MATRIX_CMUL_ASSOC; +"MATRIX_CMUL_COMPONENT",MATRIX_CMUL_COMPONENT; +"MATRIX_CMUL_LID",MATRIX_CMUL_LID; +"MATRIX_CMUL_LZERO",MATRIX_CMUL_LZERO; +"MATRIX_CMUL_RZERO",MATRIX_CMUL_RZERO; +"MATRIX_CMUL_SUB_LDISTRIB",MATRIX_CMUL_SUB_LDISTRIB; +"MATRIX_CMUL_SUB_RDISTRIB",MATRIX_CMUL_SUB_RDISTRIB; +"MATRIX_COMPOSE",MATRIX_COMPOSE; +"MATRIX_EQ",MATRIX_EQ; +"MATRIX_EQUAL_COLUMNS",MATRIX_EQUAL_COLUMNS; +"MATRIX_EQUAL_ROWS",MATRIX_EQUAL_ROWS; +"MATRIX_FULL_LINEAR_EQUATIONS",MATRIX_FULL_LINEAR_EQUATIONS; +"MATRIX_I",MATRIX_I; +"MATRIX_ID",MATRIX_ID; +"MATRIX_INV",MATRIX_INV; +"MATRIX_INVERTIBLE",MATRIX_INVERTIBLE; +"MATRIX_INV_COFACTOR",MATRIX_INV_COFACTOR; +"MATRIX_INV_I",MATRIX_INV_I; +"MATRIX_INV_MUL",MATRIX_INV_MUL; +"MATRIX_INV_UNIQUE",MATRIX_INV_UNIQUE; +"MATRIX_INV_UNIQUE_LEFT",MATRIX_INV_UNIQUE_LEFT; +"MATRIX_INV_UNIQUE_RIGHT",MATRIX_INV_UNIQUE_RIGHT; +"MATRIX_LEFT_INVERSE_COFACTOR",MATRIX_LEFT_INVERSE_COFACTOR; +"MATRIX_LEFT_INVERTIBLE",MATRIX_LEFT_INVERTIBLE; +"MATRIX_LEFT_INVERTIBLE_INDEPENDENT_COLUMNS",MATRIX_LEFT_INVERTIBLE_INDEPENDENT_COLUMNS; +"MATRIX_LEFT_INVERTIBLE_INJECTIVE",MATRIX_LEFT_INVERTIBLE_INJECTIVE; +"MATRIX_LEFT_INVERTIBLE_KER",MATRIX_LEFT_INVERTIBLE_KER; +"MATRIX_LEFT_INVERTIBLE_SPAN_ROWS",MATRIX_LEFT_INVERTIBLE_SPAN_ROWS; +"MATRIX_LEFT_RIGHT_INVERSE",MATRIX_LEFT_RIGHT_INVERSE; +"MATRIX_MUL_ASSOC",MATRIX_MUL_ASSOC; +"MATRIX_MUL_COMPONENT",MATRIX_MUL_COMPONENT; +"MATRIX_MUL_DOT",MATRIX_MUL_DOT; +"MATRIX_MUL_LEFT_COFACTOR",MATRIX_MUL_LEFT_COFACTOR; +"MATRIX_MUL_LID",MATRIX_MUL_LID; +"MATRIX_MUL_LINV",MATRIX_MUL_LINV; +"MATRIX_MUL_LMUL",MATRIX_MUL_LMUL; +"MATRIX_MUL_LNEG",MATRIX_MUL_LNEG; +"MATRIX_MUL_LTRANSP_DOT_COLUMN",MATRIX_MUL_LTRANSP_DOT_COLUMN; +"MATRIX_MUL_LZERO",MATRIX_MUL_LZERO; +"MATRIX_MUL_RID",MATRIX_MUL_RID; +"MATRIX_MUL_RIGHT_COFACTOR",MATRIX_MUL_RIGHT_COFACTOR; +"MATRIX_MUL_RINV",MATRIX_MUL_RINV; +"MATRIX_MUL_RMUL",MATRIX_MUL_RMUL; +"MATRIX_MUL_RNEG",MATRIX_MUL_RNEG; +"MATRIX_MUL_RTRANSP_DOT_ROW",MATRIX_MUL_RTRANSP_DOT_ROW; +"MATRIX_MUL_RZERO",MATRIX_MUL_RZERO; +"MATRIX_MUL_VSUM",MATRIX_MUL_VSUM; +"MATRIX_MUL_VSUM_ALT",MATRIX_MUL_VSUM_ALT; +"MATRIX_NEG_0",MATRIX_NEG_0; +"MATRIX_NEG_ADD",MATRIX_NEG_ADD; +"MATRIX_NEG_COMPONENT",MATRIX_NEG_COMPONENT; +"MATRIX_NEG_EQ_0",MATRIX_NEG_EQ_0; +"MATRIX_NEG_MINUS1",MATRIX_NEG_MINUS1; +"MATRIX_NEG_NEG",MATRIX_NEG_NEG; +"MATRIX_NEG_SUB",MATRIX_NEG_SUB; +"MATRIX_NONFULL_LINEAR_EQUATIONS",MATRIX_NONFULL_LINEAR_EQUATIONS; +"MATRIX_NONFULL_LINEAR_EQUATIONS_EQ",MATRIX_NONFULL_LINEAR_EQUATIONS_EQ; +"MATRIX_OF_MATRIX_VECTOR_MUL",MATRIX_OF_MATRIX_VECTOR_MUL; +"MATRIX_REFLECT_ALONG_BASIS",MATRIX_REFLECT_ALONG_BASIS; +"MATRIX_RIGHT_INVERSE_COFACTOR",MATRIX_RIGHT_INVERSE_COFACTOR; +"MATRIX_RIGHT_INVERTIBLE",MATRIX_RIGHT_INVERTIBLE; +"MATRIX_RIGHT_INVERTIBLE_INDEPENDENT_ROWS",MATRIX_RIGHT_INVERTIBLE_INDEPENDENT_ROWS; +"MATRIX_RIGHT_INVERTIBLE_SPAN_COLUMNS",MATRIX_RIGHT_INVERTIBLE_SPAN_COLUMNS; +"MATRIX_RIGHT_INVERTIBLE_SURJECTIVE",MATRIX_RIGHT_INVERTIBLE_SURJECTIVE; +"MATRIX_SELF_ADJOINT",MATRIX_SELF_ADJOINT; +"MATRIX_SUB",MATRIX_SUB; +"MATRIX_SUB_COMPONENT",MATRIX_SUB_COMPONENT; +"MATRIX_SUB_LDISTRIB",MATRIX_SUB_LDISTRIB; +"MATRIX_SUB_LZERO",MATRIX_SUB_LZERO; +"MATRIX_SUB_RDISTRIB",MATRIX_SUB_RDISTRIB; +"MATRIX_SUB_REFL",MATRIX_SUB_REFL; +"MATRIX_SUB_RZERO",MATRIX_SUB_RZERO; +"MATRIX_TRANSP_MUL",MATRIX_TRANSP_MUL; +"MATRIX_TRIVIAL_LINEAR_EQUATIONS",MATRIX_TRIVIAL_LINEAR_EQUATIONS; +"MATRIX_VECTOR_COLUMN",MATRIX_VECTOR_COLUMN; +"MATRIX_VECTOR_MUL",MATRIX_VECTOR_MUL; +"MATRIX_VECTOR_MUL_ADD_LDISTRIB",MATRIX_VECTOR_MUL_ADD_LDISTRIB; +"MATRIX_VECTOR_MUL_ADD_RDISTRIB",MATRIX_VECTOR_MUL_ADD_RDISTRIB; +"MATRIX_VECTOR_MUL_ASSOC",MATRIX_VECTOR_MUL_ASSOC; +"MATRIX_VECTOR_MUL_BASIS",MATRIX_VECTOR_MUL_BASIS; +"MATRIX_VECTOR_MUL_COMPONENT",MATRIX_VECTOR_MUL_COMPONENT; +"MATRIX_VECTOR_MUL_INJECTIVE_ON_ROWSPACE",MATRIX_VECTOR_MUL_INJECTIVE_ON_ROWSPACE; +"MATRIX_VECTOR_MUL_IN_COLUMNSPACE",MATRIX_VECTOR_MUL_IN_COLUMNSPACE; +"MATRIX_VECTOR_MUL_LID",MATRIX_VECTOR_MUL_LID; +"MATRIX_VECTOR_MUL_LINEAR",MATRIX_VECTOR_MUL_LINEAR; +"MATRIX_VECTOR_MUL_LZERO",MATRIX_VECTOR_MUL_LZERO; +"MATRIX_VECTOR_MUL_RMUL",MATRIX_VECTOR_MUL_RMUL; +"MATRIX_VECTOR_MUL_RZERO",MATRIX_VECTOR_MUL_RZERO; +"MATRIX_VECTOR_MUL_SUB_LDISTRIB",MATRIX_VECTOR_MUL_SUB_LDISTRIB; +"MATRIX_VECTOR_MUL_SUB_RDISTRIB",MATRIX_VECTOR_MUL_SUB_RDISTRIB; +"MATRIX_VECTOR_MUL_TRANSP",MATRIX_VECTOR_MUL_TRANSP; +"MATRIX_WLOG_INVERTIBLE",MATRIX_WLOG_INVERTIBLE; +"MATRIX_WORKS",MATRIX_WORKS; +"MAT_0_COMPONENT",MAT_0_COMPONENT; +"MAT_COMPONENT",MAT_COMPONENT; +"MAX",MAX; +"MAXIMAL_AFFINE_INDEPENDENT_SUBSET",MAXIMAL_AFFINE_INDEPENDENT_SUBSET; +"MAXIMAL_AFFINE_INDEPENDENT_SUBSET_AFFINE",MAXIMAL_AFFINE_INDEPENDENT_SUBSET_AFFINE; +"MAXIMAL_INDEPENDENT_SUBSET",MAXIMAL_INDEPENDENT_SUBSET; +"MAXIMAL_INDEPENDENT_SUBSET_EXTEND",MAXIMAL_INDEPENDENT_SUBSET_EXTEND; +"MBASIS_COMPONENT",MBASIS_COMPONENT; +"MBASIS_EQ_0",MBASIS_EQ_0; +"MBASIS_EXPANSION",MBASIS_EXPANSION; +"MBASIS_EXTENSION",MBASIS_EXTENSION; +"MBASIS_NONZERO",MBASIS_NONZERO; +"MBASIS_SPLIT",MBASIS_SPLIT; +"MEASURABLE",MEASURABLE; +"MEASURABLE_ALMOST",MEASURABLE_ALMOST; +"MEASURABLE_BALL",MEASURABLE_BALL; +"MEASURABLE_BOUNDED_BY_INTEGRABLE_IMP_ABSOLUTELY_INTEGRABLE",MEASURABLE_BOUNDED_BY_INTEGRABLE_IMP_ABSOLUTELY_INTEGRABLE; +"MEASURABLE_BOUNDED_BY_INTEGRABLE_IMP_INTEGRABLE",MEASURABLE_BOUNDED_BY_INTEGRABLE_IMP_INTEGRABLE; +"MEASURABLE_CBALL",MEASURABLE_CBALL; +"MEASURABLE_CLOSURE",MEASURABLE_CLOSURE; +"MEASURABLE_COMPACT",MEASURABLE_COMPACT; +"MEASURABLE_CONVEX",MEASURABLE_CONVEX; +"MEASURABLE_CONVEX_HULL",MEASURABLE_CONVEX_HULL; +"MEASURABLE_COUNTABLE_INTERS",MEASURABLE_COUNTABLE_INTERS; +"MEASURABLE_COUNTABLE_INTERS_GEN",MEASURABLE_COUNTABLE_INTERS_GEN; +"MEASURABLE_COUNTABLE_UNIONS",MEASURABLE_COUNTABLE_UNIONS; +"MEASURABLE_COUNTABLE_UNIONS_BOUNDED",MEASURABLE_COUNTABLE_UNIONS_BOUNDED; +"MEASURABLE_COUNTABLE_UNIONS_STRONG",MEASURABLE_COUNTABLE_UNIONS_STRONG; +"MEASURABLE_DIFF",MEASURABLE_DIFF; +"MEASURABLE_ELEMENTARY",MEASURABLE_ELEMENTARY; +"MEASURABLE_EMPTY",MEASURABLE_EMPTY; +"MEASURABLE_FRONTIER",MEASURABLE_FRONTIER; +"MEASURABLE_IMP_LEBESGUE_MEASURABLE",MEASURABLE_IMP_LEBESGUE_MEASURABLE; +"MEASURABLE_INNER_COMPACT",MEASURABLE_INNER_COMPACT; +"MEASURABLE_INNER_OUTER",MEASURABLE_INNER_OUTER; +"MEASURABLE_INSERT",MEASURABLE_INSERT; +"MEASURABLE_INSIDE",MEASURABLE_INSIDE; +"MEASURABLE_INTEGRABLE",MEASURABLE_INTEGRABLE; +"MEASURABLE_INTER",MEASURABLE_INTER; +"MEASURABLE_INTERIOR",MEASURABLE_INTERIOR; +"MEASURABLE_INTERVAL",MEASURABLE_INTERVAL; +"MEASURABLE_INTER_HALFSPACE_GE",MEASURABLE_INTER_HALFSPACE_GE; +"MEASURABLE_INTER_HALFSPACE_LE",MEASURABLE_INTER_HALFSPACE_LE; +"MEASURABLE_INTER_INTERVAL",MEASURABLE_INTER_INTERVAL; +"MEASURABLE_JORDAN",MEASURABLE_JORDAN; +"MEASURABLE_LEGESGUE_MEASURABLE_INTER_MEASURABLE",MEASURABLE_LEGESGUE_MEASURABLE_INTER_MEASURABLE; +"MEASURABLE_LEGESGUE_MEASURABLE_SUBSET",MEASURABLE_LEGESGUE_MEASURABLE_SUBSET; +"MEASURABLE_LINEAR_IMAGE",MEASURABLE_LINEAR_IMAGE; +"MEASURABLE_LINEAR_IMAGE_EQ",MEASURABLE_LINEAR_IMAGE_EQ; +"MEASURABLE_LINEAR_IMAGE_INTERVAL",MEASURABLE_LINEAR_IMAGE_INTERVAL; +"MEASURABLE_MEASURABLE_DIFF_LEGESGUE_MEASURABLE",MEASURABLE_MEASURABLE_DIFF_LEGESGUE_MEASURABLE; +"MEASURABLE_MEASURABLE_INTER_LEGESGUE_MEASURABLE",MEASURABLE_MEASURABLE_INTER_LEGESGUE_MEASURABLE; +"MEASURABLE_MEASURABLE_PREIMAGE_CLOSED",MEASURABLE_MEASURABLE_PREIMAGE_CLOSED; +"MEASURABLE_MEASURABLE_PREIMAGE_OPEN",MEASURABLE_MEASURABLE_PREIMAGE_OPEN; +"MEASURABLE_MEASURE_EQ_0",MEASURABLE_MEASURE_EQ_0; +"MEASURABLE_MEASURE_POS_LT",MEASURABLE_MEASURE_POS_LT; +"MEASURABLE_NEGLIGIBLE_SYMDIFF",MEASURABLE_NEGLIGIBLE_SYMDIFF; +"MEASURABLE_NEGLIGIBLE_SYMDIFF_EQ",MEASURABLE_NEGLIGIBLE_SYMDIFF_EQ; +"MEASURABLE_NESTED_UNIONS",MEASURABLE_NESTED_UNIONS; +"MEASURABLE_NONNEGLIGIBLE_IMP_LARGE",MEASURABLE_NONNEGLIGIBLE_IMP_LARGE; +"MEASURABLE_ON_0",MEASURABLE_ON_0; +"MEASURABLE_ON_ADD",MEASURABLE_ON_ADD; +"MEASURABLE_ON_CASES",MEASURABLE_ON_CASES; +"MEASURABLE_ON_CMUL",MEASURABLE_ON_CMUL; +"MEASURABLE_ON_COMBINE",MEASURABLE_ON_COMBINE; +"MEASURABLE_ON_COMPONENTWISE",MEASURABLE_ON_COMPONENTWISE; +"MEASURABLE_ON_COMPOSE_CONTINUOUS",MEASURABLE_ON_COMPOSE_CONTINUOUS; +"MEASURABLE_ON_COMPOSE_CONTINUOUS_0",MEASURABLE_ON_COMPOSE_CONTINUOUS_0; +"MEASURABLE_ON_COMPOSE_CONTINUOUS_CLOSED_SET",MEASURABLE_ON_COMPOSE_CONTINUOUS_CLOSED_SET; +"MEASURABLE_ON_COMPOSE_CONTINUOUS_CLOSED_SET_0",MEASURABLE_ON_COMPOSE_CONTINUOUS_CLOSED_SET_0; +"MEASURABLE_ON_COMPOSE_CONTINUOUS_OPEN_INTERVAL",MEASURABLE_ON_COMPOSE_CONTINUOUS_OPEN_INTERVAL; +"MEASURABLE_ON_CONST",MEASURABLE_ON_CONST; +"MEASURABLE_ON_COUNTABLE_UNIONS",MEASURABLE_ON_COUNTABLE_UNIONS; +"MEASURABLE_ON_DIFF",MEASURABLE_ON_DIFF; +"MEASURABLE_ON_DROP_MUL",MEASURABLE_ON_DROP_MUL; +"MEASURABLE_ON_EMPTY",MEASURABLE_ON_EMPTY; +"MEASURABLE_ON_INTER",MEASURABLE_ON_INTER; +"MEASURABLE_ON_LEBESGUE_MEASURABLE_PREIMAGE_CLOSED",MEASURABLE_ON_LEBESGUE_MEASURABLE_PREIMAGE_CLOSED; +"MEASURABLE_ON_LEBESGUE_MEASURABLE_PREIMAGE_CLOSED_EQ",MEASURABLE_ON_LEBESGUE_MEASURABLE_PREIMAGE_CLOSED_EQ; +"MEASURABLE_ON_LEBESGUE_MEASURABLE_PREIMAGE_CLOSED_INTERVAL",MEASURABLE_ON_LEBESGUE_MEASURABLE_PREIMAGE_CLOSED_INTERVAL; +"MEASURABLE_ON_LEBESGUE_MEASURABLE_PREIMAGE_OPEN",MEASURABLE_ON_LEBESGUE_MEASURABLE_PREIMAGE_OPEN; +"MEASURABLE_ON_LEBESGUE_MEASURABLE_PREIMAGE_OPEN_EQ",MEASURABLE_ON_LEBESGUE_MEASURABLE_PREIMAGE_OPEN_EQ; +"MEASURABLE_ON_LEBESGUE_MEASURABLE_PREIMAGE_OPEN_HALFSPACE_COMPONENT_GE",MEASURABLE_ON_LEBESGUE_MEASURABLE_PREIMAGE_OPEN_HALFSPACE_COMPONENT_GE; +"MEASURABLE_ON_LEBESGUE_MEASURABLE_PREIMAGE_OPEN_HALFSPACE_COMPONENT_GT",MEASURABLE_ON_LEBESGUE_MEASURABLE_PREIMAGE_OPEN_HALFSPACE_COMPONENT_GT; +"MEASURABLE_ON_LEBESGUE_MEASURABLE_PREIMAGE_OPEN_HALFSPACE_COMPONENT_LE",MEASURABLE_ON_LEBESGUE_MEASURABLE_PREIMAGE_OPEN_HALFSPACE_COMPONENT_LE; +"MEASURABLE_ON_LEBESGUE_MEASURABLE_PREIMAGE_OPEN_HALFSPACE_COMPONENT_LT",MEASURABLE_ON_LEBESGUE_MEASURABLE_PREIMAGE_OPEN_HALFSPACE_COMPONENT_LT; +"MEASURABLE_ON_LEBESGUE_MEASURABLE_PREIMAGE_OPEN_INTERVAL",MEASURABLE_ON_LEBESGUE_MEASURABLE_PREIMAGE_OPEN_INTERVAL; +"MEASURABLE_ON_LEBESGUE_MEASURABLE_SUBSET",MEASURABLE_ON_LEBESGUE_MEASURABLE_SUBSET; +"MEASURABLE_ON_LIFT_MUL",MEASURABLE_ON_LIFT_MUL; +"MEASURABLE_ON_LIMIT",MEASURABLE_ON_LIMIT; +"MEASURABLE_ON_LINEAR_IMAGE_EQ",MEASURABLE_ON_LINEAR_IMAGE_EQ; +"MEASURABLE_ON_MAX",MEASURABLE_ON_MAX; +"MEASURABLE_ON_MEASURABLE_PREIMAGE_CLOSED",MEASURABLE_ON_MEASURABLE_PREIMAGE_CLOSED; +"MEASURABLE_ON_MEASURABLE_PREIMAGE_CLOSED_EQ",MEASURABLE_ON_MEASURABLE_PREIMAGE_CLOSED_EQ; +"MEASURABLE_ON_MEASURABLE_PREIMAGE_CLOSED_INTERVAL",MEASURABLE_ON_MEASURABLE_PREIMAGE_CLOSED_INTERVAL; +"MEASURABLE_ON_MEASURABLE_PREIMAGE_OPEN",MEASURABLE_ON_MEASURABLE_PREIMAGE_OPEN; +"MEASURABLE_ON_MEASURABLE_PREIMAGE_OPEN_EQ",MEASURABLE_ON_MEASURABLE_PREIMAGE_OPEN_EQ; +"MEASURABLE_ON_MEASURABLE_PREIMAGE_OPEN_HALFSPACE_COMPONENT_GE",MEASURABLE_ON_MEASURABLE_PREIMAGE_OPEN_HALFSPACE_COMPONENT_GE; +"MEASURABLE_ON_MEASURABLE_PREIMAGE_OPEN_HALFSPACE_COMPONENT_GT",MEASURABLE_ON_MEASURABLE_PREIMAGE_OPEN_HALFSPACE_COMPONENT_GT; +"MEASURABLE_ON_MEASURABLE_PREIMAGE_OPEN_HALFSPACE_COMPONENT_LE",MEASURABLE_ON_MEASURABLE_PREIMAGE_OPEN_HALFSPACE_COMPONENT_LE; +"MEASURABLE_ON_MEASURABLE_PREIMAGE_OPEN_HALFSPACE_COMPONENT_LT",MEASURABLE_ON_MEASURABLE_PREIMAGE_OPEN_HALFSPACE_COMPONENT_LT; +"MEASURABLE_ON_MEASURABLE_PREIMAGE_OPEN_INTERVAL",MEASURABLE_ON_MEASURABLE_PREIMAGE_OPEN_INTERVAL; +"MEASURABLE_ON_MEASURABLE_SUBSET",MEASURABLE_ON_MEASURABLE_SUBSET; +"MEASURABLE_ON_MIN",MEASURABLE_ON_MIN; +"MEASURABLE_ON_NEG",MEASURABLE_ON_NEG; +"MEASURABLE_ON_NEG_EQ",MEASURABLE_ON_NEG_EQ; +"MEASURABLE_ON_NORM",MEASURABLE_ON_NORM; +"MEASURABLE_ON_PASTECART",MEASURABLE_ON_PASTECART; +"MEASURABLE_ON_PREIMAGE_CLOSED",MEASURABLE_ON_PREIMAGE_CLOSED; +"MEASURABLE_ON_PREIMAGE_CLOSED_INTERVAL",MEASURABLE_ON_PREIMAGE_CLOSED_INTERVAL; +"MEASURABLE_ON_PREIMAGE_OPEN",MEASURABLE_ON_PREIMAGE_OPEN; +"MEASURABLE_ON_PREIMAGE_OPEN_HALFSPACE_COMPONENT_GE",MEASURABLE_ON_PREIMAGE_OPEN_HALFSPACE_COMPONENT_GE; +"MEASURABLE_ON_PREIMAGE_OPEN_HALFSPACE_COMPONENT_GT",MEASURABLE_ON_PREIMAGE_OPEN_HALFSPACE_COMPONENT_GT; +"MEASURABLE_ON_PREIMAGE_OPEN_HALFSPACE_COMPONENT_LE",MEASURABLE_ON_PREIMAGE_OPEN_HALFSPACE_COMPONENT_LE; +"MEASURABLE_ON_PREIMAGE_OPEN_HALFSPACE_COMPONENT_LT",MEASURABLE_ON_PREIMAGE_OPEN_HALFSPACE_COMPONENT_LT; +"MEASURABLE_ON_PREIMAGE_OPEN_INTERVAL",MEASURABLE_ON_PREIMAGE_OPEN_INTERVAL; +"MEASURABLE_ON_RESTRICT",MEASURABLE_ON_RESTRICT; +"MEASURABLE_ON_SIMPLE_FUNCTION_LIMIT",MEASURABLE_ON_SIMPLE_FUNCTION_LIMIT; +"MEASURABLE_ON_SPIKE",MEASURABLE_ON_SPIKE; +"MEASURABLE_ON_SPIKE_SET",MEASURABLE_ON_SPIKE_SET; +"MEASURABLE_ON_SUB",MEASURABLE_ON_SUB; +"MEASURABLE_ON_TRANSLATION",MEASURABLE_ON_TRANSLATION; +"MEASURABLE_ON_TRANSLATION_EQ",MEASURABLE_ON_TRANSLATION_EQ; +"MEASURABLE_ON_UNION",MEASURABLE_ON_UNION; +"MEASURABLE_ON_UNIONS",MEASURABLE_ON_UNIONS; +"MEASURABLE_ON_UNIV",MEASURABLE_ON_UNIV; +"MEASURABLE_ON_VECTOR_DERIVATIVE",MEASURABLE_ON_VECTOR_DERIVATIVE; +"MEASURABLE_ON_VSUM",MEASURABLE_ON_VSUM; +"MEASURABLE_OPEN",MEASURABLE_OPEN; +"MEASURABLE_OUTER_CLOSED_INTERVALS",MEASURABLE_OUTER_CLOSED_INTERVALS; +"MEASURABLE_OUTER_INTERVALS_BOUNDED",MEASURABLE_OUTER_INTERVALS_BOUNDED; +"MEASURABLE_OUTER_OPEN",MEASURABLE_OUTER_OPEN; +"MEASURABLE_OUTER_OPEN_INTERVALS",MEASURABLE_OUTER_OPEN_INTERVALS; +"MEASURABLE_SCALING",MEASURABLE_SCALING; +"MEASURABLE_SCALING_EQ",MEASURABLE_SCALING_EQ; +"MEASURABLE_SIMPLEX",MEASURABLE_SIMPLEX; +"MEASURABLE_SMALL_IMP_NEGLIGIBLE",MEASURABLE_SMALL_IMP_NEGLIGIBLE; +"MEASURABLE_TETRAHEDRON",MEASURABLE_TETRAHEDRON; +"MEASURABLE_TRANSLATION",MEASURABLE_TRANSLATION; +"MEASURABLE_TRANSLATION_EQ",MEASURABLE_TRANSLATION_EQ; +"MEASURABLE_TRIANGLE",MEASURABLE_TRIANGLE; +"MEASURABLE_UNION",MEASURABLE_UNION; +"MEASURABLE_UNIONS",MEASURABLE_UNIONS; +"MEASURE",MEASURE; +"MEASURE_BALL_BOUND",MEASURE_BALL_BOUND; +"MEASURE_BALL_POS",MEASURE_BALL_POS; +"MEASURE_CBALL_BOUND",MEASURE_CBALL_BOUND; +"MEASURE_CBALL_POS",MEASURE_CBALL_POS; +"MEASURE_CLOSURE",MEASURE_CLOSURE; +"MEASURE_COUNTABLE_UNIONS_APPROACHABLE",MEASURE_COUNTABLE_UNIONS_APPROACHABLE; +"MEASURE_COUNTABLE_UNIONS_LE",MEASURE_COUNTABLE_UNIONS_LE; +"MEASURE_COUNTABLE_UNIONS_LE_GEN",MEASURE_COUNTABLE_UNIONS_LE_GEN; +"MEASURE_COUNTABLE_UNIONS_LE_STRONG",MEASURE_COUNTABLE_UNIONS_LE_STRONG; +"MEASURE_COUNTABLE_UNIONS_LE_STRONG_GEN",MEASURE_COUNTABLE_UNIONS_LE_STRONG_GEN; +"MEASURE_DIFF_SUBSET",MEASURE_DIFF_SUBSET; +"MEASURE_DISJOINT_UNION",MEASURE_DISJOINT_UNION; +"MEASURE_DISJOINT_UNIONS",MEASURE_DISJOINT_UNIONS; +"MEASURE_DISJOINT_UNIONS_IMAGE",MEASURE_DISJOINT_UNIONS_IMAGE; +"MEASURE_DISJOINT_UNIONS_IMAGE_STRONG",MEASURE_DISJOINT_UNIONS_IMAGE_STRONG; +"MEASURE_DISJOINT_UNION_EQ",MEASURE_DISJOINT_UNION_EQ; +"MEASURE_ELEMENTARY",MEASURE_ELEMENTARY; +"MEASURE_EMPTY",MEASURE_EMPTY; +"MEASURE_EQ_0",MEASURE_EQ_0; +"MEASURE_FRONTIER",MEASURE_FRONTIER; +"MEASURE_INSERT",MEASURE_INSERT; +"MEASURE_INTEGRAL",MEASURE_INTEGRAL; +"MEASURE_INTEGRAL_UNIV",MEASURE_INTEGRAL_UNIV; +"MEASURE_INTERIOR",MEASURE_INTERIOR; +"MEASURE_INTERVAL",MEASURE_INTERVAL; +"MEASURE_INTERVAL_1",MEASURE_INTERVAL_1; +"MEASURE_INTERVAL_1_ALT",MEASURE_INTERVAL_1_ALT; +"MEASURE_INTERVAL_2",MEASURE_INTERVAL_2; +"MEASURE_INTERVAL_2_ALT",MEASURE_INTERVAL_2_ALT; +"MEASURE_INTERVAL_3",MEASURE_INTERVAL_3; +"MEASURE_INTERVAL_3_ALT",MEASURE_INTERVAL_3_ALT; +"MEASURE_INTERVAL_4",MEASURE_INTERVAL_4; +"MEASURE_INTERVAL_4_ALT",MEASURE_INTERVAL_4_ALT; +"MEASURE_LE",MEASURE_LE; +"MEASURE_LIMIT",MEASURE_LIMIT; +"MEASURE_LINEAR_IMAGE",MEASURE_LINEAR_IMAGE; +"MEASURE_LINEAR_IMAGE_SAME",MEASURE_LINEAR_IMAGE_SAME; +"MEASURE_NEGLIGIBLE_SYMDIFF",MEASURE_NEGLIGIBLE_SYMDIFF; +"MEASURE_NEGLIGIBLE_UNION",MEASURE_NEGLIGIBLE_UNION; +"MEASURE_NEGLIGIBLE_UNIONS",MEASURE_NEGLIGIBLE_UNIONS; +"MEASURE_NEGLIGIBLE_UNIONS_IMAGE",MEASURE_NEGLIGIBLE_UNIONS_IMAGE; +"MEASURE_NEGLIGIBLE_UNIONS_IMAGE_STRONG",MEASURE_NEGLIGIBLE_UNIONS_IMAGE_STRONG; +"MEASURE_NEGLIGIBLE_UNION_EQ",MEASURE_NEGLIGIBLE_UNION_EQ; +"MEASURE_OPEN_POS_LT",MEASURE_OPEN_POS_LT; +"MEASURE_ORTHOGONAL_IMAGE_EQ",MEASURE_ORTHOGONAL_IMAGE_EQ; +"MEASURE_POS_LE",MEASURE_POS_LE; +"MEASURE_SCALING",MEASURE_SCALING; +"MEASURE_SIMPLEX",MEASURE_SIMPLEX; +"MEASURE_SUBSET",MEASURE_SUBSET; +"MEASURE_TETRAHEDRON",MEASURE_TETRAHEDRON; +"MEASURE_TRANSLATION",MEASURE_TRANSLATION; +"MEASURE_TRIANGLE",MEASURE_TRIANGLE; +"MEASURE_UNION",MEASURE_UNION; +"MEASURE_UNIONS_LE",MEASURE_UNIONS_LE; +"MEASURE_UNIONS_LE_IMAGE",MEASURE_UNIONS_LE_IMAGE; +"MEASURE_UNION_LE",MEASURE_UNION_LE; +"MEASURE_UNIQUE",MEASURE_UNIQUE; +"MEM",MEM; +"MEMBER_NOT_EMPTY",MEMBER_NOT_EMPTY; +"MEM_APPEND",MEM_APPEND; +"MEM_APPEND_DECOMPOSE",MEM_APPEND_DECOMPOSE; +"MEM_APPEND_DECOMPOSE_LEFT",MEM_APPEND_DECOMPOSE_LEFT; +"MEM_ASSOC",MEM_ASSOC; +"MEM_EL",MEM_EL; +"MEM_EXISTS_EL",MEM_EXISTS_EL; +"MEM_FILTER",MEM_FILTER; +"MEM_LINEAR_IMAGE",MEM_LINEAR_IMAGE; +"MEM_LIST_OF_SET",MEM_LIST_OF_SET; +"MEM_MAP",MEM_MAP; +"MEM_TRANSLATION",MEM_TRANSLATION; +"MIDPOINT_BETWEEN",MIDPOINT_BETWEEN; +"MIDPOINT_COLLINEAR",MIDPOINT_COLLINEAR; +"MIDPOINT_CONVEX_DYADIC_RATIONALS",MIDPOINT_CONVEX_DYADIC_RATIONALS; +"MIDPOINT_EQ_ENDPOINT",MIDPOINT_EQ_ENDPOINT; +"MIDPOINT_IN_SEGMENT",MIDPOINT_IN_SEGMENT; +"MIDPOINT_LINEAR_IMAGE",MIDPOINT_LINEAR_IMAGE; +"MIDPOINT_REFL",MIDPOINT_REFL; +"MIDPOINT_SYM",MIDPOINT_SYM; +"MIN",MIN; +"MINIMAL",MINIMAL; +"MINIMAL_IN_INSERT",MINIMAL_IN_INSERT; +"MK_REC_INJ",MK_REC_INJ; +"MOD_0",MOD_0; +"MOD_1",MOD_1; +"MOD_ADD_MOD",MOD_ADD_MOD; +"MOD_EQ",MOD_EQ; +"MOD_EQ_0",MOD_EQ_0; +"MOD_EXISTS",MOD_EXISTS; +"MOD_EXP_MOD",MOD_EXP_MOD; +"MOD_LE",MOD_LE; +"MOD_LT",MOD_LT; +"MOD_MOD",MOD_MOD; +"MOD_MOD_EXP_MIN",MOD_MOD_EXP_MIN; +"MOD_MOD_REFL",MOD_MOD_REFL; +"MOD_MULT",MOD_MULT; +"MOD_MULT2",MOD_MULT2; +"MOD_MULT_ADD",MOD_MULT_ADD; +"MOD_MULT_LMOD",MOD_MULT_LMOD; +"MOD_MULT_MOD2",MOD_MULT_MOD2; +"MOD_MULT_RMOD",MOD_MULT_RMOD; +"MOD_NSUM_MOD",MOD_NSUM_MOD; +"MOD_NSUM_MOD_NUMSEG",MOD_NSUM_MOD_NUMSEG; +"MOD_UNIQ",MOD_UNIQ; +"MONOIDAL_AC",MONOIDAL_AC; +"MONOIDAL_ADD",MONOIDAL_ADD; +"MONOIDAL_AND",MONOIDAL_AND; +"MONOIDAL_LIFTED",MONOIDAL_LIFTED; +"MONOIDAL_MUL",MONOIDAL_MUL; +"MONOIDAL_REAL_ADD",MONOIDAL_REAL_ADD; +"MONOIDAL_REAL_MUL",MONOIDAL_REAL_MUL; +"MONOIDAL_VECTOR_ADD",MONOIDAL_VECTOR_ADD; +"MONOTONE_BIGGER",MONOTONE_BIGGER; +"MONOTONE_CONVERGENCE_DECREASING",MONOTONE_CONVERGENCE_DECREASING; +"MONOTONE_CONVERGENCE_INCREASING",MONOTONE_CONVERGENCE_INCREASING; +"MONOTONE_CONVERGENCE_INTERVAL",MONOTONE_CONVERGENCE_INTERVAL; +"MONOTONE_SUBSEQUENCE",MONOTONE_SUBSEQUENCE; +"MONO_ALL",MONO_ALL; +"MONO_ALL2",MONO_ALL2; +"MONO_AND",MONO_AND; +"MONO_COND",MONO_COND; +"MONO_EXISTS",MONO_EXISTS; +"MONO_FORALL",MONO_FORALL; +"MONO_IMP",MONO_IMP; +"MONO_NOT",MONO_NOT; +"MONO_OR",MONO_OR; +"MULT",MULT; +"MULTIVECTOR_ADD_COMPONENT",MULTIVECTOR_ADD_COMPONENT; +"MULTIVECTOR_BETA",MULTIVECTOR_BETA; +"MULTIVECTOR_EQ",MULTIVECTOR_EQ; +"MULTIVECTOR_ETA",MULTIVECTOR_ETA; +"MULTIVECTOR_GRADE",MULTIVECTOR_GRADE; +"MULTIVECTOR_IMAGE",MULTIVECTOR_IMAGE; +"MULTIVECTOR_MUL_COMPONENT",MULTIVECTOR_MUL_COMPONENT; +"MULTIVECTOR_UNIQUE",MULTIVECTOR_UNIQUE; +"MULTIVECTOR_VEC_COMPONENT",MULTIVECTOR_VEC_COMPONENT; +"MULTIVECTOR_VSUM",MULTIVECTOR_VSUM; +"MULTIVECTOR_VSUM_COMPONENT",MULTIVECTOR_VSUM_COMPONENT; +"MULT_0",MULT_0; +"MULT_2",MULT_2; +"MULT_AC",MULT_AC; +"MULT_ASSOC",MULT_ASSOC; +"MULT_CLAUSES",MULT_CLAUSES; +"MULT_DIV_LE",MULT_DIV_LE; +"MULT_EQ_0",MULT_EQ_0; +"MULT_EQ_1",MULT_EQ_1; +"MULT_EXP",MULT_EXP; +"MULT_SUC",MULT_SUC; +"MULT_SYM",MULT_SYM; +"MUL_C_UNIV",MUL_C_UNIV; +"MVT",MVT; +"MVT_GENERAL",MVT_GENERAL; +"MVT_SIMPLE",MVT_SIMPLE; +"MVT_VERY_SIMPLE",MVT_VERY_SIMPLE; +"NADD_ADD",NADD_ADD; +"NADD_ADDITIVE",NADD_ADDITIVE; +"NADD_ADD_ASSOC",NADD_ADD_ASSOC; +"NADD_ADD_LCANCEL",NADD_ADD_LCANCEL; +"NADD_ADD_LID",NADD_ADD_LID; +"NADD_ADD_SYM",NADD_ADD_SYM; +"NADD_ADD_WELLDEF",NADD_ADD_WELLDEF; +"NADD_ALTMUL",NADD_ALTMUL; +"NADD_ARCH",NADD_ARCH; +"NADD_ARCH_LEMMA",NADD_ARCH_LEMMA; +"NADD_ARCH_MULT",NADD_ARCH_MULT; +"NADD_ARCH_ZERO",NADD_ARCH_ZERO; +"NADD_BOUND",NADD_BOUND; +"NADD_CAUCHY",NADD_CAUCHY; +"NADD_COMPLETE",NADD_COMPLETE; +"NADD_DIST",NADD_DIST; +"NADD_DIST_LEMMA",NADD_DIST_LEMMA; +"NADD_EQ_IMP_LE",NADD_EQ_IMP_LE; +"NADD_EQ_REFL",NADD_EQ_REFL; +"NADD_EQ_SYM",NADD_EQ_SYM; +"NADD_EQ_TRANS",NADD_EQ_TRANS; +"NADD_INV",NADD_INV; +"NADD_INV_0",NADD_INV_0; +"NADD_INV_WELLDEF",NADD_INV_WELLDEF; +"NADD_LBOUND",NADD_LBOUND; +"NADD_LDISTRIB",NADD_LDISTRIB; +"NADD_LE_0",NADD_LE_0; +"NADD_LE_ADD",NADD_LE_ADD; +"NADD_LE_ANTISYM",NADD_LE_ANTISYM; +"NADD_LE_EXISTS",NADD_LE_EXISTS; +"NADD_LE_LADD",NADD_LE_LADD; +"NADD_LE_LMUL",NADD_LE_LMUL; +"NADD_LE_RADD",NADD_LE_RADD; +"NADD_LE_REFL",NADD_LE_REFL; +"NADD_LE_RMUL",NADD_LE_RMUL; +"NADD_LE_TOTAL",NADD_LE_TOTAL; +"NADD_LE_TOTAL_LEMMA",NADD_LE_TOTAL_LEMMA; +"NADD_LE_TRANS",NADD_LE_TRANS; +"NADD_LE_WELLDEF",NADD_LE_WELLDEF; +"NADD_LE_WELLDEF_LEMMA",NADD_LE_WELLDEF_LEMMA; +"NADD_MUL",NADD_MUL; +"NADD_MULTIPLICATIVE",NADD_MULTIPLICATIVE; +"NADD_MUL_ASSOC",NADD_MUL_ASSOC; +"NADD_MUL_LID",NADD_MUL_LID; +"NADD_MUL_LINV",NADD_MUL_LINV; +"NADD_MUL_LINV_LEMMA0",NADD_MUL_LINV_LEMMA0; +"NADD_MUL_LINV_LEMMA1",NADD_MUL_LINV_LEMMA1; +"NADD_MUL_LINV_LEMMA2",NADD_MUL_LINV_LEMMA2; +"NADD_MUL_LINV_LEMMA3",NADD_MUL_LINV_LEMMA3; +"NADD_MUL_LINV_LEMMA4",NADD_MUL_LINV_LEMMA4; +"NADD_MUL_LINV_LEMMA5",NADD_MUL_LINV_LEMMA5; +"NADD_MUL_LINV_LEMMA6",NADD_MUL_LINV_LEMMA6; +"NADD_MUL_LINV_LEMMA7",NADD_MUL_LINV_LEMMA7; +"NADD_MUL_LINV_LEMMA7a",NADD_MUL_LINV_LEMMA7a; +"NADD_MUL_LINV_LEMMA8",NADD_MUL_LINV_LEMMA8; +"NADD_MUL_SYM",NADD_MUL_SYM; +"NADD_MUL_WELLDEF",NADD_MUL_WELLDEF; +"NADD_MUL_WELLDEF_LEMMA",NADD_MUL_WELLDEF_LEMMA; +"NADD_NONZERO",NADD_NONZERO; +"NADD_OF_NUM",NADD_OF_NUM; +"NADD_OF_NUM_ADD",NADD_OF_NUM_ADD; +"NADD_OF_NUM_EQ",NADD_OF_NUM_EQ; +"NADD_OF_NUM_LE",NADD_OF_NUM_LE; +"NADD_OF_NUM_MUL",NADD_OF_NUM_MUL; +"NADD_OF_NUM_WELLDEF",NADD_OF_NUM_WELLDEF; +"NADD_RDISTRIB",NADD_RDISTRIB; +"NADD_SUC",NADD_SUC; +"NADD_UBOUND",NADD_UBOUND; +"NEARBY_INVERTIBLE_MATRIX",NEARBY_INVERTIBLE_MATRIX; +"NEGATIONS_BALL",NEGATIONS_BALL; +"NEGATIONS_CBALL",NEGATIONS_CBALL; +"NEGATIONS_SPHERE",NEGATIONS_SPHERE; +"NEGLIGIBLE",NEGLIGIBLE; +"NEGLIGIBLE_AFFINE_HULL",NEGLIGIBLE_AFFINE_HULL; +"NEGLIGIBLE_AFFINE_HULL_1",NEGLIGIBLE_AFFINE_HULL_1; +"NEGLIGIBLE_AFFINE_HULL_2",NEGLIGIBLE_AFFINE_HULL_2; +"NEGLIGIBLE_AFFINE_HULL_3",NEGLIGIBLE_AFFINE_HULL_3; +"NEGLIGIBLE_CONVEX_FRONTIER",NEGLIGIBLE_CONVEX_FRONTIER; +"NEGLIGIBLE_CONVEX_HULL",NEGLIGIBLE_CONVEX_HULL; +"NEGLIGIBLE_CONVEX_HULL_1",NEGLIGIBLE_CONVEX_HULL_1; +"NEGLIGIBLE_CONVEX_HULL_2",NEGLIGIBLE_CONVEX_HULL_2; +"NEGLIGIBLE_CONVEX_HULL_3",NEGLIGIBLE_CONVEX_HULL_3; +"NEGLIGIBLE_COUNTABLE",NEGLIGIBLE_COUNTABLE; +"NEGLIGIBLE_COUNTABLE_UNIONS",NEGLIGIBLE_COUNTABLE_UNIONS; +"NEGLIGIBLE_COUNTABLE_UNIONS_GEN",NEGLIGIBLE_COUNTABLE_UNIONS_GEN; +"NEGLIGIBLE_DELETE",NEGLIGIBLE_DELETE; +"NEGLIGIBLE_DIFF",NEGLIGIBLE_DIFF; +"NEGLIGIBLE_DIFFERENTIABLE_IMAGE_LOWDIM",NEGLIGIBLE_DIFFERENTIABLE_IMAGE_LOWDIM; +"NEGLIGIBLE_DIFFERENTIABLE_IMAGE_NEGLIGIBLE",NEGLIGIBLE_DIFFERENTIABLE_IMAGE_NEGLIGIBLE; +"NEGLIGIBLE_EMPTY",NEGLIGIBLE_EMPTY; +"NEGLIGIBLE_EQ_MEASURE_0",NEGLIGIBLE_EQ_MEASURE_0; +"NEGLIGIBLE_FINITE",NEGLIGIBLE_FINITE; +"NEGLIGIBLE_FRONTIER_INTERVAL",NEGLIGIBLE_FRONTIER_INTERVAL; +"NEGLIGIBLE_HYPERPLANE",NEGLIGIBLE_HYPERPLANE; +"NEGLIGIBLE_IFF_LEBESGUE_MEASURABLE_SUBSETS",NEGLIGIBLE_IFF_LEBESGUE_MEASURABLE_SUBSETS; +"NEGLIGIBLE_IFF_MEASURABLE_SUBSETS",NEGLIGIBLE_IFF_MEASURABLE_SUBSETS; +"NEGLIGIBLE_IMAGE_BOUNDED_VARIATION_INTERVAL",NEGLIGIBLE_IMAGE_BOUNDED_VARIATION_INTERVAL; +"NEGLIGIBLE_IMP_LEBESGUE_MEASURABLE",NEGLIGIBLE_IMP_LEBESGUE_MEASURABLE; +"NEGLIGIBLE_IMP_MEASURABLE",NEGLIGIBLE_IMP_MEASURABLE; +"NEGLIGIBLE_INSERT",NEGLIGIBLE_INSERT; +"NEGLIGIBLE_INTER",NEGLIGIBLE_INTER; +"NEGLIGIBLE_INTERVAL",NEGLIGIBLE_INTERVAL; +"NEGLIGIBLE_LINEAR_IMAGE",NEGLIGIBLE_LINEAR_IMAGE; +"NEGLIGIBLE_LINEAR_IMAGE_EQ",NEGLIGIBLE_LINEAR_IMAGE_EQ; +"NEGLIGIBLE_LINEAR_SINGULAR_IMAGE",NEGLIGIBLE_LINEAR_SINGULAR_IMAGE; +"NEGLIGIBLE_LIPSCHITZ_IMAGE_UNIV",NEGLIGIBLE_LIPSCHITZ_IMAGE_UNIV; +"NEGLIGIBLE_LOCALLY_LIPSCHITZ_IMAGE",NEGLIGIBLE_LOCALLY_LIPSCHITZ_IMAGE; +"NEGLIGIBLE_LOWDIM",NEGLIGIBLE_LOWDIM; +"NEGLIGIBLE_ON_INTERVALS",NEGLIGIBLE_ON_INTERVALS; +"NEGLIGIBLE_ON_UNIV",NEGLIGIBLE_ON_UNIV; +"NEGLIGIBLE_OUTER",NEGLIGIBLE_OUTER; +"NEGLIGIBLE_OUTER_LE",NEGLIGIBLE_OUTER_LE; +"NEGLIGIBLE_RECTIFIABLE_PATH_IMAGE",NEGLIGIBLE_RECTIFIABLE_PATH_IMAGE; +"NEGLIGIBLE_SING",NEGLIGIBLE_SING; +"NEGLIGIBLE_SPHERE",NEGLIGIBLE_SPHERE; +"NEGLIGIBLE_STANDARD_HYPERPLANE",NEGLIGIBLE_STANDARD_HYPERPLANE; +"NEGLIGIBLE_SUBSET",NEGLIGIBLE_SUBSET; +"NEGLIGIBLE_SYMDIFF_EQ",NEGLIGIBLE_SYMDIFF_EQ; +"NEGLIGIBLE_TRANSLATION",NEGLIGIBLE_TRANSLATION; +"NEGLIGIBLE_TRANSLATION_EQ",NEGLIGIBLE_TRANSLATION_EQ; +"NEGLIGIBLE_TRANSLATION_REV",NEGLIGIBLE_TRANSLATION_REV; +"NEGLIGIBLE_UNION",NEGLIGIBLE_UNION; +"NEGLIGIBLE_UNIONS",NEGLIGIBLE_UNIONS; +"NEGLIGIBLE_UNION_EQ",NEGLIGIBLE_UNION_EQ; +"NEIGHBOURHOOD_EXTENSION_INTO_ANR",NEIGHBOURHOOD_EXTENSION_INTO_ANR; +"NEIGHBOURHOOD_EXTENSION_INTO_ANR_LOCAL",NEIGHBOURHOOD_EXTENSION_INTO_ANR_LOCAL; +"NEIGHBOURHOOD_RETRACT_IMP_ANR",NEIGHBOURHOOD_RETRACT_IMP_ANR; +"NEIGHBOURHOOD_RETRACT_IMP_ANR_UNIV",NEIGHBOURHOOD_RETRACT_IMP_ANR_UNIV; +"NET",NET; +"NETLIMIT_AT",NETLIMIT_AT; +"NETLIMIT_WITHIN",NETLIMIT_WITHIN; +"NETLIMIT_WITHIN_INTERIOR",NETLIMIT_WITHIN_INTERIOR; +"NET_DILEMMA",NET_DILEMMA; +"NEUTRAL_ADD",NEUTRAL_ADD; +"NEUTRAL_AND",NEUTRAL_AND; +"NEUTRAL_LIFTED",NEUTRAL_LIFTED; +"NEUTRAL_MUL",NEUTRAL_MUL; +"NEUTRAL_OUTER",NEUTRAL_OUTER; +"NEUTRAL_REAL_ADD",NEUTRAL_REAL_ADD; +"NEUTRAL_REAL_MUL",NEUTRAL_REAL_MUL; +"NEUTRAL_VECTOR_ADD",NEUTRAL_VECTOR_ADD; +"NONEMPTY_SIMPLE_PATH_ENDLESS",NONEMPTY_SIMPLE_PATH_ENDLESS; +"NONNEGATIVE_ABSOLUTELY_INTEGRABLE",NONNEGATIVE_ABSOLUTELY_INTEGRABLE; +"NONTRIVIAL_LIMIT_WITHIN",NONTRIVIAL_LIMIT_WITHIN; +"NORM_0",NORM_0; +"NORM_1",NORM_1; +"NORM_1_POS",NORM_1_POS; +"NORM_ADD_PYTHAGOREAN",NORM_ADD_PYTHAGOREAN; +"NORM_BASIS",NORM_BASIS; +"NORM_BASIS_1",NORM_BASIS_1; +"NORM_BOUND_COMPONENT_LE",NORM_BOUND_COMPONENT_LE; +"NORM_BOUND_COMPONENT_LT",NORM_BOUND_COMPONENT_LT; +"NORM_BOUND_GENERALIZE",NORM_BOUND_GENERALIZE; +"NORM_CAUCHY_SCHWARZ",NORM_CAUCHY_SCHWARZ; +"NORM_CAUCHY_SCHWARZ_ABS",NORM_CAUCHY_SCHWARZ_ABS; +"NORM_CAUCHY_SCHWARZ_ABS_EQ",NORM_CAUCHY_SCHWARZ_ABS_EQ; +"NORM_CAUCHY_SCHWARZ_DIV",NORM_CAUCHY_SCHWARZ_DIV; +"NORM_CAUCHY_SCHWARZ_EQ",NORM_CAUCHY_SCHWARZ_EQ; +"NORM_CAUCHY_SCHWARZ_EQUAL",NORM_CAUCHY_SCHWARZ_EQUAL; +"NORM_CROSS_MULTIPLY",NORM_CROSS_MULTIPLY; +"NORM_EQ",NORM_EQ; +"NORM_EQ_0",NORM_EQ_0; +"NORM_EQ_0_DOT",NORM_EQ_0_DOT; +"NORM_EQ_0_IMP",NORM_EQ_0_IMP; +"NORM_EQ_1",NORM_EQ_1; +"NORM_EQ_SQUARE",NORM_EQ_SQUARE; +"NORM_FSTCART",NORM_FSTCART; +"NORM_GE_SQUARE",NORM_GE_SQUARE; +"NORM_GT_SQUARE",NORM_GT_SQUARE; +"NORM_INCREASES_ONLINE",NORM_INCREASES_ONLINE; +"NORM_LE",NORM_LE; +"NORM_LE_0",NORM_LE_0; +"NORM_LE_COMPONENTWISE",NORM_LE_COMPONENTWISE; +"NORM_LE_INFNORM",NORM_LE_INFNORM; +"NORM_LE_L1",NORM_LE_L1; +"NORM_LE_PASTECART",NORM_LE_PASTECART; +"NORM_LE_SQUARE",NORM_LE_SQUARE; +"NORM_LIFT",NORM_LIFT; +"NORM_LT",NORM_LT; +"NORM_LT_SQUARE",NORM_LT_SQUARE; +"NORM_LT_SQUARE_ALT",NORM_LT_SQUARE_ALT; +"NORM_MUL",NORM_MUL; +"NORM_NEG",NORM_NEG; +"NORM_PASTECART",NORM_PASTECART; +"NORM_PASTECART_0",NORM_PASTECART_0; +"NORM_PASTECART_LE",NORM_PASTECART_LE; +"NORM_POS_LE",NORM_POS_LE; +"NORM_POS_LT",NORM_POS_LT; +"NORM_POW_2",NORM_POW_2; +"NORM_REAL",NORM_REAL; +"NORM_SEGMENT_LOWERBOUND",NORM_SEGMENT_LOWERBOUND; +"NORM_SEGMENT_ORTHOGONAL_LOWERBOUND",NORM_SEGMENT_ORTHOGONAL_LOWERBOUND; +"NORM_SNDCART",NORM_SNDCART; +"NORM_SUB",NORM_SUB; +"NORM_TRIANGLE",NORM_TRIANGLE; +"NORM_TRIANGLE_EQ",NORM_TRIANGLE_EQ; +"NORM_TRIANGLE_LE",NORM_TRIANGLE_LE; +"NORM_TRIANGLE_LT",NORM_TRIANGLE_LT; +"NORM_TRIANGLE_SUB",NORM_TRIANGLE_SUB; +"NORM_VSUM_PYTHAGOREAN",NORM_VSUM_PYTHAGOREAN; +"NORM_VSUM_TRIVIAL_LEMMA",NORM_VSUM_TRIVIAL_LEMMA; +"NOT_ABSOLUTE_RETRACT_COBOUNDED",NOT_ABSOLUTE_RETRACT_COBOUNDED; +"NOT_ALL",NOT_ALL; +"NOT_BOUNDED_UNIV",NOT_BOUNDED_UNIV; +"NOT_CLAUSES",NOT_CLAUSES; +"NOT_CLAUSES_WEAK",NOT_CLAUSES_WEAK; +"NOT_CONS_NIL",NOT_CONS_NIL; +"NOT_DEF",NOT_DEF; +"NOT_EMPTY_INSERT",NOT_EMPTY_INSERT; +"NOT_EQUAL_SETS",NOT_EQUAL_SETS; +"NOT_EVEN",NOT_EVEN; +"NOT_EVENTUALLY",NOT_EVENTUALLY; +"NOT_EX",NOT_EX; +"NOT_EXISTS_THM",NOT_EXISTS_THM; +"NOT_FORALL_THM",NOT_FORALL_THM; +"NOT_IMP",NOT_IMP; +"NOT_INSERT_EMPTY",NOT_INSERT_EMPTY; +"NOT_INTERVAL_UNIV",NOT_INTERVAL_UNIV; +"NOT_IN_EMPTY",NOT_IN_EMPTY; +"NOT_IN_INTERIOR_CONVEX_HULL",NOT_IN_INTERIOR_CONVEX_HULL; +"NOT_IN_PATH_IMAGE_JOIN",NOT_IN_PATH_IMAGE_JOIN; +"NOT_LE",NOT_LE; +"NOT_LT",NOT_LT; +"NOT_NEGLIGIBLE_UNIV",NOT_NEGLIGIBLE_UNIV; +"NOT_ODD",NOT_ODD; +"NOT_ON_PATH_BALL",NOT_ON_PATH_BALL; +"NOT_ON_PATH_CBALL",NOT_ON_PATH_CBALL; +"NOT_OUTSIDE_CONNECTED_COMPONENT_LE",NOT_OUTSIDE_CONNECTED_COMPONENT_LE; +"NOT_OUTSIDE_CONNECTED_COMPONENT_LT",NOT_OUTSIDE_CONNECTED_COMPONENT_LT; +"NOT_PSUBSET_EMPTY",NOT_PSUBSET_EMPTY; +"NOT_SUC",NOT_SUC; +"NOT_UNIV_PSUBSET",NOT_UNIV_PSUBSET; +"NOWHERE_DENSE",NOWHERE_DENSE; +"NOWHERE_DENSE_UNION",NOWHERE_DENSE_UNION; +"NO_LIMIT_POINT_IMP_CLOSED",NO_LIMIT_POINT_IMP_CLOSED; +"NO_RETRACTION_CBALL",NO_RETRACTION_CBALL; +"NO_RETRACTION_FRONTIER_BOUNDED",NO_RETRACTION_FRONTIER_BOUNDED; +"NSUM_0",NSUM_0; +"NSUM_ADD",NSUM_ADD; +"NSUM_ADD_GEN",NSUM_ADD_GEN; +"NSUM_ADD_NUMSEG",NSUM_ADD_NUMSEG; +"NSUM_ADD_SPLIT",NSUM_ADD_SPLIT; +"NSUM_BIJECTION",NSUM_BIJECTION; +"NSUM_BOUND",NSUM_BOUND; +"NSUM_BOUND_GEN",NSUM_BOUND_GEN; +"NSUM_BOUND_LT",NSUM_BOUND_LT; +"NSUM_BOUND_LT_ALL",NSUM_BOUND_LT_ALL; +"NSUM_BOUND_LT_GEN",NSUM_BOUND_LT_GEN; +"NSUM_CASES",NSUM_CASES; +"NSUM_CLAUSES",NSUM_CLAUSES; +"NSUM_CLAUSES_LEFT",NSUM_CLAUSES_LEFT; +"NSUM_CLAUSES_NUMSEG",NSUM_CLAUSES_NUMSEG; +"NSUM_CLAUSES_RIGHT",NSUM_CLAUSES_RIGHT; +"NSUM_CLOSED",NSUM_CLOSED; +"NSUM_CONST",NSUM_CONST; +"NSUM_CONST_NUMSEG",NSUM_CONST_NUMSEG; +"NSUM_DELETE",NSUM_DELETE; +"NSUM_DELTA",NSUM_DELTA; +"NSUM_DIFF",NSUM_DIFF; +"NSUM_EQ",NSUM_EQ; +"NSUM_EQ_0",NSUM_EQ_0; +"NSUM_EQ_0_IFF",NSUM_EQ_0_IFF; +"NSUM_EQ_0_IFF_NUMSEG",NSUM_EQ_0_IFF_NUMSEG; +"NSUM_EQ_0_NUMSEG",NSUM_EQ_0_NUMSEG; +"NSUM_EQ_GENERAL",NSUM_EQ_GENERAL; +"NSUM_EQ_GENERAL_INVERSES",NSUM_EQ_GENERAL_INVERSES; +"NSUM_EQ_NUMSEG",NSUM_EQ_NUMSEG; +"NSUM_EQ_SUPERSET",NSUM_EQ_SUPERSET; +"NSUM_GROUP",NSUM_GROUP; +"NSUM_IMAGE",NSUM_IMAGE; +"NSUM_IMAGE_GEN",NSUM_IMAGE_GEN; +"NSUM_IMAGE_NONZERO",NSUM_IMAGE_NONZERO; +"NSUM_INCL_EXCL",NSUM_INCL_EXCL; +"NSUM_INJECTION",NSUM_INJECTION; +"NSUM_LE",NSUM_LE; +"NSUM_LE_NUMSEG",NSUM_LE_NUMSEG; +"NSUM_LMUL",NSUM_LMUL; +"NSUM_LT",NSUM_LT; +"NSUM_LT_ALL",NSUM_LT_ALL; +"NSUM_MULTICOUNT",NSUM_MULTICOUNT; +"NSUM_MULTICOUNT_GEN",NSUM_MULTICOUNT_GEN; +"NSUM_NSUM_PRODUCT",NSUM_NSUM_PRODUCT; +"NSUM_NSUM_RESTRICT",NSUM_NSUM_RESTRICT; +"NSUM_OFFSET",NSUM_OFFSET; +"NSUM_OFFSET_0",NSUM_OFFSET_0; +"NSUM_PAIR",NSUM_PAIR; +"NSUM_PERMUTE",NSUM_PERMUTE; +"NSUM_PERMUTE_NUMSEG",NSUM_PERMUTE_NUMSEG; +"NSUM_POS_BOUND",NSUM_POS_BOUND; +"NSUM_POS_LT",NSUM_POS_LT; +"NSUM_RESTRICT",NSUM_RESTRICT; +"NSUM_RESTRICT_SET",NSUM_RESTRICT_SET; +"NSUM_RMUL",NSUM_RMUL; +"NSUM_SING",NSUM_SING; +"NSUM_SING_NUMSEG",NSUM_SING_NUMSEG; +"NSUM_SUBSET",NSUM_SUBSET; +"NSUM_SUBSET_SIMPLE",NSUM_SUBSET_SIMPLE; +"NSUM_SUPERSET",NSUM_SUPERSET; +"NSUM_SUPPORT",NSUM_SUPPORT; +"NSUM_SWAP",NSUM_SWAP; +"NSUM_SWAP_NUMSEG",NSUM_SWAP_NUMSEG; +"NSUM_TRIV_NUMSEG",NSUM_TRIV_NUMSEG; +"NSUM_UNION",NSUM_UNION; +"NSUM_UNIONS_NONZERO",NSUM_UNIONS_NONZERO; +"NSUM_UNION_EQ",NSUM_UNION_EQ; +"NSUM_UNION_LZERO",NSUM_UNION_LZERO; +"NSUM_UNION_NONZERO",NSUM_UNION_NONZERO; +"NSUM_UNION_RZERO",NSUM_UNION_RZERO; +"NULL",NULL; +"NULLHOMOTOPIC_FROM_CONTRACTIBLE",NULLHOMOTOPIC_FROM_CONTRACTIBLE; +"NULLHOMOTOPIC_FROM_SPHERE_EXTENSION",NULLHOMOTOPIC_FROM_SPHERE_EXTENSION; +"NULLHOMOTOPIC_INTO_ANR_EXTENSION",NULLHOMOTOPIC_INTO_ANR_EXTENSION; +"NULLHOMOTOPIC_INTO_CONTRACTIBLE",NULLHOMOTOPIC_INTO_CONTRACTIBLE; +"NULLHOMOTOPIC_INTO_RELATIVE_FRONTIER_EXTENSION",NULLHOMOTOPIC_INTO_RELATIVE_FRONTIER_EXTENSION; +"NULLHOMOTOPIC_INTO_SPHERE_EXTENSION",NULLHOMOTOPIC_INTO_SPHERE_EXTENSION; +"NULLHOMOTOPIC_THROUGH_CONTRACTIBLE",NULLHOMOTOPIC_THROUGH_CONTRACTIBLE; +"NULLSPACE_INTER_ROWSPACE",NULLSPACE_INTER_ROWSPACE; +"NUMERAL",NUMERAL; +"NUMPAIR",NUMPAIR; +"NUMPAIR_DEST",NUMPAIR_DEST; +"NUMPAIR_INJ",NUMPAIR_INJ; +"NUMPAIR_INJ_LEMMA",NUMPAIR_INJ_LEMMA; +"NUMSEG_ADD_SPLIT",NUMSEG_ADD_SPLIT; +"NUMSEG_CLAUSES",NUMSEG_CLAUSES; +"NUMSEG_COMBINE_L",NUMSEG_COMBINE_L; +"NUMSEG_COMBINE_R",NUMSEG_COMBINE_R; +"NUMSEG_DIMINDEX_NONEMPTY",NUMSEG_DIMINDEX_NONEMPTY; +"NUMSEG_EMPTY",NUMSEG_EMPTY; +"NUMSEG_LE",NUMSEG_LE; +"NUMSEG_LREC",NUMSEG_LREC; +"NUMSEG_LT",NUMSEG_LT; +"NUMSEG_OFFSET_IMAGE",NUMSEG_OFFSET_IMAGE; +"NUMSEG_REC",NUMSEG_REC; +"NUMSEG_RREC",NUMSEG_RREC; +"NUMSEG_SING",NUMSEG_SING; +"NUMSUM",NUMSUM; +"NUMSUM_DEST",NUMSUM_DEST; +"NUMSUM_INJ",NUMSUM_INJ; +"NUM_COUNTABLE",NUM_COUNTABLE; +"NUM_GCD",NUM_GCD; +"NUM_OF_INT",NUM_OF_INT; +"NUM_OF_INT_OF_NUM",NUM_OF_INT_OF_NUM; +"NUM_REP_CASES",NUM_REP_CASES; +"NUM_REP_INDUCT",NUM_REP_INDUCT; +"NUM_REP_RULES",NUM_REP_RULES; +"ODD",ODD; +"ODD_ADD",ODD_ADD; +"ODD_DOUBLE",ODD_DOUBLE; +"ODD_EXISTS",ODD_EXISTS; +"ODD_EXP",ODD_EXP; +"ODD_MOD",ODD_MOD; +"ODD_MULT",ODD_MULT; +"ODD_SUB",ODD_SUB; +"OEP",OEP; +"OLDNET",OLDNET; +"ONE",ONE; +"ONE_ONE",ONE_ONE; +"ONORM",ONORM; +"ONORM_COMPOSE",ONORM_COMPOSE; +"ONORM_CONST",ONORM_CONST; +"ONORM_EQ_0",ONORM_EQ_0; +"ONORM_I",ONORM_I; +"ONORM_ID",ONORM_ID; +"ONORM_NEG",ONORM_NEG; +"ONORM_NEG_LEMMA",ONORM_NEG_LEMMA; +"ONORM_POS_LE",ONORM_POS_LE; +"ONORM_POS_LT",ONORM_POS_LT; +"ONORM_TRIANGLE",ONORM_TRIANGLE; +"ONORM_TRIANGLE_LE",ONORM_TRIANGLE_LE; +"ONORM_TRIANGLE_LT",ONORM_TRIANGLE_LT; +"ONTO",ONTO; +"OPEN_AFFINITY",OPEN_AFFINITY; +"OPEN_BALL",OPEN_BALL; +"OPEN_BIJECTIVE_LINEAR_IMAGE_EQ",OPEN_BIJECTIVE_LINEAR_IMAGE_EQ; +"OPEN_CLOSED",OPEN_CLOSED; +"OPEN_CLOSED_INTERVAL_1",OPEN_CLOSED_INTERVAL_1; +"OPEN_CLOSED_INTERVAL_CONVEX",OPEN_CLOSED_INTERVAL_CONVEX; +"OPEN_COMPONENTS",OPEN_COMPONENTS; +"OPEN_CONNECTED_COMPONENT",OPEN_CONNECTED_COMPONENT; +"OPEN_CONTAINS_BALL",OPEN_CONTAINS_BALL; +"OPEN_CONTAINS_BALL_EQ",OPEN_CONTAINS_BALL_EQ; +"OPEN_CONTAINS_CBALL",OPEN_CONTAINS_CBALL; +"OPEN_CONTAINS_CBALL_EQ",OPEN_CONTAINS_CBALL_EQ; +"OPEN_CONTAINS_INTERVAL",OPEN_CONTAINS_INTERVAL; +"OPEN_CONTAINS_OPEN_INTERVAL",OPEN_CONTAINS_OPEN_INTERVAL; +"OPEN_CONVEX_HULL",OPEN_CONVEX_HULL; +"OPEN_COUNTABLE_UNION_CLOSED_INTERVALS",OPEN_COUNTABLE_UNION_CLOSED_INTERVALS; +"OPEN_COUNTABLE_UNION_OPEN_INTERVALS",OPEN_COUNTABLE_UNION_OPEN_INTERVALS; +"OPEN_DELETE",OPEN_DELETE; +"OPEN_DIFF",OPEN_DIFF; +"OPEN_EMPTY",OPEN_EMPTY; +"OPEN_EXISTS",OPEN_EXISTS; +"OPEN_EXISTS_IN",OPEN_EXISTS_IN; +"OPEN_GENERAL_COMPONENT",OPEN_GENERAL_COMPONENT; +"OPEN_HALFSPACE_COMPONENT_GT",OPEN_HALFSPACE_COMPONENT_GT; +"OPEN_HALFSPACE_COMPONENT_LT",OPEN_HALFSPACE_COMPONENT_LT; +"OPEN_HALFSPACE_GT",OPEN_HALFSPACE_GT; +"OPEN_HALFSPACE_LT",OPEN_HALFSPACE_LT; +"OPEN_IMP_INFINITE",OPEN_IMP_INFINITE; +"OPEN_IMP_LOCALLY_COMPACT",OPEN_IMP_LOCALLY_COMPACT; +"OPEN_IMP_LOCALLY_CONNECTED",OPEN_IMP_LOCALLY_CONNECTED; +"OPEN_IMP_LOCALLY_PATH_CONNECTED",OPEN_IMP_LOCALLY_PATH_CONNECTED; +"OPEN_IN",OPEN_IN; +"OPEN_INSIDE",OPEN_INSIDE; +"OPEN_INTER",OPEN_INTER; +"OPEN_INTERIOR",OPEN_INTERIOR; +"OPEN_INTERS",OPEN_INTERS; +"OPEN_INTERVAL",OPEN_INTERVAL; +"OPEN_INTERVAL_EQ",OPEN_INTERVAL_EQ; +"OPEN_INTERVAL_LEMMA",OPEN_INTERVAL_LEMMA; +"OPEN_INTERVAL_MIDPOINT",OPEN_INTERVAL_MIDPOINT; +"OPEN_INTER_CLOSURE_EQ_EMPTY",OPEN_INTER_CLOSURE_EQ_EMPTY; +"OPEN_INTER_CLOSURE_SUBSET",OPEN_INTER_CLOSURE_SUBSET; +"OPEN_IN_CLAUSES",OPEN_IN_CLAUSES; +"OPEN_IN_CLOSED_IN",OPEN_IN_CLOSED_IN; +"OPEN_IN_CLOSED_IN_EQ",OPEN_IN_CLOSED_IN_EQ; +"OPEN_IN_COMPONENTS_LOCALLY_CONNECTED",OPEN_IN_COMPONENTS_LOCALLY_CONNECTED; +"OPEN_IN_CONNECTED_COMPONENT",OPEN_IN_CONNECTED_COMPONENT; +"OPEN_IN_CONNECTED_COMPONENTS",OPEN_IN_CONNECTED_COMPONENTS; +"OPEN_IN_CONNECTED_COMPONENT_LOCALLY_CONNECTED",OPEN_IN_CONNECTED_COMPONENT_LOCALLY_CONNECTED; +"OPEN_IN_CONTAINS_BALL",OPEN_IN_CONTAINS_BALL; +"OPEN_IN_CONTAINS_CBALL",OPEN_IN_CONTAINS_CBALL; +"OPEN_IN_DELETE",OPEN_IN_DELETE; +"OPEN_IN_DIFF",OPEN_IN_DIFF; +"OPEN_IN_EMPTY",OPEN_IN_EMPTY; +"OPEN_IN_IMP_SUBSET",OPEN_IN_IMP_SUBSET; +"OPEN_IN_INJECTIVE_LINEAR_IMAGE",OPEN_IN_INJECTIVE_LINEAR_IMAGE; +"OPEN_IN_INTER",OPEN_IN_INTER; +"OPEN_IN_INTERS",OPEN_IN_INTERS; +"OPEN_IN_INTER_OPEN",OPEN_IN_INTER_OPEN; +"OPEN_IN_OPEN",OPEN_IN_OPEN; +"OPEN_IN_OPEN_EQ",OPEN_IN_OPEN_EQ; +"OPEN_IN_OPEN_INTER",OPEN_IN_OPEN_INTER; +"OPEN_IN_OPEN_TRANS",OPEN_IN_OPEN_TRANS; +"OPEN_IN_PATH_COMPONENT_LOCALLY_PATH_CONNECTED",OPEN_IN_PATH_COMPONENT_LOCALLY_PATH_CONNECTED; +"OPEN_IN_PCROSS",OPEN_IN_PCROSS; +"OPEN_IN_PCROSS_EQ",OPEN_IN_PCROSS_EQ; +"OPEN_IN_REFL",OPEN_IN_REFL; +"OPEN_IN_RELATIVE_INTERIOR",OPEN_IN_RELATIVE_INTERIOR; +"OPEN_IN_SING",OPEN_IN_SING; +"OPEN_IN_SUBOPEN",OPEN_IN_SUBOPEN; +"OPEN_IN_SUBSET",OPEN_IN_SUBSET; +"OPEN_IN_SUBSET_RELATIVE_INTERIOR",OPEN_IN_SUBSET_RELATIVE_INTERIOR; +"OPEN_IN_SUBSET_TRANS",OPEN_IN_SUBSET_TRANS; +"OPEN_IN_SUBTOPOLOGY",OPEN_IN_SUBTOPOLOGY; +"OPEN_IN_SUBTOPOLOGY_EMPTY",OPEN_IN_SUBTOPOLOGY_EMPTY; +"OPEN_IN_SUBTOPOLOGY_INTER_SUBSET",OPEN_IN_SUBTOPOLOGY_INTER_SUBSET; +"OPEN_IN_SUBTOPOLOGY_REFL",OPEN_IN_SUBTOPOLOGY_REFL; +"OPEN_IN_SUBTOPOLOGY_UNION",OPEN_IN_SUBTOPOLOGY_UNION; +"OPEN_IN_TOPSPACE",OPEN_IN_TOPSPACE; +"OPEN_IN_TRANS",OPEN_IN_TRANS; +"OPEN_IN_TRANSLATION_EQ",OPEN_IN_TRANSLATION_EQ; +"OPEN_IN_UNION",OPEN_IN_UNION; +"OPEN_IN_UNIONS",OPEN_IN_UNIONS; +"OPEN_LIFT",OPEN_LIFT; +"OPEN_MAP_FROM_COMPOSITION_INJECTIVE",OPEN_MAP_FROM_COMPOSITION_INJECTIVE; +"OPEN_MAP_FROM_COMPOSITION_SURJECTIVE",OPEN_MAP_FROM_COMPOSITION_SURJECTIVE; +"OPEN_MAP_IMP_CLOSED_MAP",OPEN_MAP_IMP_CLOSED_MAP; +"OPEN_MAP_IMP_QUOTIENT_MAP",OPEN_MAP_IMP_QUOTIENT_MAP; +"OPEN_MEASURABLE_INNER_DIVISION",OPEN_MEASURABLE_INNER_DIVISION; +"OPEN_NEGATIONS",OPEN_NEGATIONS; +"OPEN_NON_GENERAL_COMPONENT",OPEN_NON_GENERAL_COMPONENT; +"OPEN_NON_PATH_COMPONENT",OPEN_NON_PATH_COMPONENT; +"OPEN_NOT_NEGLIGIBLE",OPEN_NOT_NEGLIGIBLE; +"OPEN_OPEN_IN_TRANS",OPEN_OPEN_IN_TRANS; +"OPEN_OPEN_LEFT_PROJECTION",OPEN_OPEN_LEFT_PROJECTION; +"OPEN_OPEN_RIGHT_PROJECTION",OPEN_OPEN_RIGHT_PROJECTION; +"OPEN_OUTSIDE",OPEN_OUTSIDE; +"OPEN_PATH_COMPONENT",OPEN_PATH_COMPONENT; +"OPEN_PATH_CONNECTED_COMPONENT",OPEN_PATH_CONNECTED_COMPONENT; +"OPEN_PCROSS",OPEN_PCROSS; +"OPEN_PCROSS_EQ",OPEN_PCROSS_EQ; +"OPEN_POSITIVE_MULTIPLES",OPEN_POSITIVE_MULTIPLES; +"OPEN_SCALING",OPEN_SCALING; +"OPEN_SEGMENT_1",OPEN_SEGMENT_1; +"OPEN_SEGMENT_ALT",OPEN_SEGMENT_ALT; +"OPEN_SEGMENT_LINEAR_IMAGE",OPEN_SEGMENT_LINEAR_IMAGE; +"OPEN_SET_COCOUNTABLE_COORDINATES",OPEN_SET_COCOUNTABLE_COORDINATES; +"OPEN_SET_COSMALL_COORDINATES",OPEN_SET_COSMALL_COORDINATES; +"OPEN_SET_IRRATIONAL_COORDINATES",OPEN_SET_IRRATIONAL_COORDINATES; +"OPEN_SET_RATIONAL_COORDINATES",OPEN_SET_RATIONAL_COORDINATES; +"OPEN_SUBOPEN",OPEN_SUBOPEN; +"OPEN_SUBSET",OPEN_SUBSET; +"OPEN_SUBSET_INTERIOR",OPEN_SUBSET_INTERIOR; +"OPEN_SUMS",OPEN_SUMS; +"OPEN_SURJECTIVE_LINEAR_IMAGE",OPEN_SURJECTIVE_LINEAR_IMAGE; +"OPEN_TRANSLATION",OPEN_TRANSLATION; +"OPEN_TRANSLATION_EQ",OPEN_TRANSLATION_EQ; +"OPEN_UNION",OPEN_UNION; +"OPEN_UNIONS",OPEN_UNIONS; +"OPEN_UNION_COMPACT_SUBSETS",OPEN_UNION_COMPACT_SUBSETS; +"OPEN_UNIV",OPEN_UNIV; +"OPERATIVE_1_LE",OPERATIVE_1_LE; +"OPERATIVE_1_LT",OPERATIVE_1_LT; +"OPERATIVE_APPROXIMABLE",OPERATIVE_APPROXIMABLE; +"OPERATIVE_CONTENT",OPERATIVE_CONTENT; +"OPERATIVE_DIVISION",OPERATIVE_DIVISION; +"OPERATIVE_DIVISION_AND",OPERATIVE_DIVISION_AND; +"OPERATIVE_EMPTY",OPERATIVE_EMPTY; +"OPERATIVE_FUNCTION_ENDPOINT_DIFF",OPERATIVE_FUNCTION_ENDPOINT_DIFF; +"OPERATIVE_INTEGRABLE",OPERATIVE_INTEGRABLE; +"OPERATIVE_INTEGRAL",OPERATIVE_INTEGRAL; +"OPERATIVE_LIFTED_SETVARIATION",OPERATIVE_LIFTED_SETVARIATION; +"OPERATIVE_LIFTED_VECTOR_VARIATION",OPERATIVE_LIFTED_VECTOR_VARIATION; +"OPERATIVE_REAL_FUNCTION_ENDPOINT_DIFF",OPERATIVE_REAL_FUNCTION_ENDPOINT_DIFF; +"OPERATIVE_TAGGED_DIVISION",OPERATIVE_TAGGED_DIVISION; +"OPERATIVE_TRIVIAL",OPERATIVE_TRIVIAL; +"ORDINAL_CHAINED",ORDINAL_CHAINED; +"ORDINAL_CHAINED_LEMMA",ORDINAL_CHAINED_LEMMA; +"ORDINAL_SUC",ORDINAL_SUC; +"ORDINAL_UNION",ORDINAL_UNION; +"ORDINAL_UNION_LEMMA",ORDINAL_UNION_LEMMA; +"ORDINAL_UP",ORDINAL_UP; +"ORTHGOONAL_TRANSFORMATION_REFLECT_ALONG",ORTHGOONAL_TRANSFORMATION_REFLECT_ALONG; +"ORTHOGONAL_0",ORTHOGONAL_0; +"ORTHOGONAL_ANY_CLOSEST_POINT",ORTHOGONAL_ANY_CLOSEST_POINT; +"ORTHOGONAL_BASIS",ORTHOGONAL_BASIS; +"ORTHOGONAL_BASIS_BASIS",ORTHOGONAL_BASIS_BASIS; +"ORTHOGONAL_BASIS_EXISTS",ORTHOGONAL_BASIS_EXISTS; +"ORTHOGONAL_BASIS_SUBSPACE",ORTHOGONAL_BASIS_SUBSPACE; +"ORTHOGONAL_CLAUSES",ORTHOGONAL_CLAUSES; +"ORTHOGONAL_EXTENSION",ORTHOGONAL_EXTENSION; +"ORTHOGONAL_EXTENSION_STRONG",ORTHOGONAL_EXTENSION_STRONG; +"ORTHOGONAL_LINEAR_IMAGE_EQ",ORTHOGONAL_LINEAR_IMAGE_EQ; +"ORTHOGONAL_LNEG",ORTHOGONAL_LNEG; +"ORTHOGONAL_LVSUM",ORTHOGONAL_LVSUM; +"ORTHOGONAL_MATRIX",ORTHOGONAL_MATRIX; +"ORTHOGONAL_MATRIX_2",ORTHOGONAL_MATRIX_2; +"ORTHOGONAL_MATRIX_2_ALT",ORTHOGONAL_MATRIX_2_ALT; +"ORTHOGONAL_MATRIX_ALT",ORTHOGONAL_MATRIX_ALT; +"ORTHOGONAL_MATRIX_EXISTS_BASIS",ORTHOGONAL_MATRIX_EXISTS_BASIS; +"ORTHOGONAL_MATRIX_ID",ORTHOGONAL_MATRIX_ID; +"ORTHOGONAL_MATRIX_INV",ORTHOGONAL_MATRIX_INV; +"ORTHOGONAL_MATRIX_MATRIX",ORTHOGONAL_MATRIX_MATRIX; +"ORTHOGONAL_MATRIX_MUL",ORTHOGONAL_MATRIX_MUL; +"ORTHOGONAL_MATRIX_ORTHOGONAL_EIGENVECTORS",ORTHOGONAL_MATRIX_ORTHOGONAL_EIGENVECTORS; +"ORTHOGONAL_MATRIX_ORTHONORMAL_COLUMNS",ORTHOGONAL_MATRIX_ORTHONORMAL_COLUMNS; +"ORTHOGONAL_MATRIX_ORTHONORMAL_COLUMNS_INDEXED",ORTHOGONAL_MATRIX_ORTHONORMAL_COLUMNS_INDEXED; +"ORTHOGONAL_MATRIX_ORTHONORMAL_COLUMNS_PAIRWISE",ORTHOGONAL_MATRIX_ORTHONORMAL_COLUMNS_PAIRWISE; +"ORTHOGONAL_MATRIX_ORTHONORMAL_COLUMNS_SPAN",ORTHOGONAL_MATRIX_ORTHONORMAL_COLUMNS_SPAN; +"ORTHOGONAL_MATRIX_ORTHONORMAL_ROWS",ORTHOGONAL_MATRIX_ORTHONORMAL_ROWS; +"ORTHOGONAL_MATRIX_ORTHONORMAL_ROWS_INDEXED",ORTHOGONAL_MATRIX_ORTHONORMAL_ROWS_INDEXED; +"ORTHOGONAL_MATRIX_ORTHONORMAL_ROWS_PAIRWISE",ORTHOGONAL_MATRIX_ORTHONORMAL_ROWS_PAIRWISE; +"ORTHOGONAL_MATRIX_ORTHONORMAL_ROWS_SPAN",ORTHOGONAL_MATRIX_ORTHONORMAL_ROWS_SPAN; +"ORTHOGONAL_MATRIX_TRANSFORMATION",ORTHOGONAL_MATRIX_TRANSFORMATION; +"ORTHOGONAL_MATRIX_TRANSP",ORTHOGONAL_MATRIX_TRANSP; +"ORTHOGONAL_MUL",ORTHOGONAL_MUL; +"ORTHOGONAL_NULLSPACE_ROWSPACE",ORTHOGONAL_NULLSPACE_ROWSPACE; +"ORTHOGONAL_REFL",ORTHOGONAL_REFL; +"ORTHOGONAL_RNEG",ORTHOGONAL_RNEG; +"ORTHOGONAL_ROTATION_OR_ROTOINVERSION",ORTHOGONAL_ROTATION_OR_ROTOINVERSION; +"ORTHOGONAL_RVSUM",ORTHOGONAL_RVSUM; +"ORTHOGONAL_SPANNINGSET_SUBSPACE",ORTHOGONAL_SPANNINGSET_SUBSPACE; +"ORTHOGONAL_SUBSPACE_DECOMP",ORTHOGONAL_SUBSPACE_DECOMP; +"ORTHOGONAL_SUBSPACE_DECOMP_EXISTS",ORTHOGONAL_SUBSPACE_DECOMP_EXISTS; +"ORTHOGONAL_SUBSPACE_DECOMP_UNIQUE",ORTHOGONAL_SUBSPACE_DECOMP_UNIQUE; +"ORTHOGONAL_SYM",ORTHOGONAL_SYM; +"ORTHOGONAL_TO_ORTHOGONAL_2D",ORTHOGONAL_TO_ORTHOGONAL_2D; +"ORTHOGONAL_TO_SPAN",ORTHOGONAL_TO_SPAN; +"ORTHOGONAL_TO_SPANS_EQ",ORTHOGONAL_TO_SPANS_EQ; +"ORTHOGONAL_TO_SPAN_EQ",ORTHOGONAL_TO_SPAN_EQ; +"ORTHOGONAL_TO_SUBSPACE_EXISTS",ORTHOGONAL_TO_SUBSPACE_EXISTS; +"ORTHOGONAL_TO_SUBSPACE_EXISTS_GEN",ORTHOGONAL_TO_SUBSPACE_EXISTS_GEN; +"ORTHOGONAL_TO_VECTOR_EXISTS",ORTHOGONAL_TO_VECTOR_EXISTS; +"ORTHOGONAL_TRANSFORMATION",ORTHOGONAL_TRANSFORMATION; +"ORTHOGONAL_TRANSFORMATION_BETWEEN_ORTHOGONAL_SETS",ORTHOGONAL_TRANSFORMATION_BETWEEN_ORTHOGONAL_SETS; +"ORTHOGONAL_TRANSFORMATION_COMPOSE",ORTHOGONAL_TRANSFORMATION_COMPOSE; +"ORTHOGONAL_TRANSFORMATION_EXISTS",ORTHOGONAL_TRANSFORMATION_EXISTS; +"ORTHOGONAL_TRANSFORMATION_EXISTS_1",ORTHOGONAL_TRANSFORMATION_EXISTS_1; +"ORTHOGONAL_TRANSFORMATION_GENERATED_BY_REFLECTIONS",ORTHOGONAL_TRANSFORMATION_GENERATED_BY_REFLECTIONS; +"ORTHOGONAL_TRANSFORMATION_I",ORTHOGONAL_TRANSFORMATION_I; +"ORTHOGONAL_TRANSFORMATION_ID",ORTHOGONAL_TRANSFORMATION_ID; +"ORTHOGONAL_TRANSFORMATION_INJECTIVE",ORTHOGONAL_TRANSFORMATION_INJECTIVE; +"ORTHOGONAL_TRANSFORMATION_INTO_SUBSPACE",ORTHOGONAL_TRANSFORMATION_INTO_SUBSPACE; +"ORTHOGONAL_TRANSFORMATION_INVERSE",ORTHOGONAL_TRANSFORMATION_INVERSE; +"ORTHOGONAL_TRANSFORMATION_INVERSE_o",ORTHOGONAL_TRANSFORMATION_INVERSE_o; +"ORTHOGONAL_TRANSFORMATION_ISOMETRY",ORTHOGONAL_TRANSFORMATION_ISOMETRY; +"ORTHOGONAL_TRANSFORMATION_LINEAR",ORTHOGONAL_TRANSFORMATION_LINEAR; +"ORTHOGONAL_TRANSFORMATION_LOWDIM_HORIZONTAL",ORTHOGONAL_TRANSFORMATION_LOWDIM_HORIZONTAL; +"ORTHOGONAL_TRANSFORMATION_MATRIX",ORTHOGONAL_TRANSFORMATION_MATRIX; +"ORTHOGONAL_TRANSFORMATION_ONTO_SUBSPACE",ORTHOGONAL_TRANSFORMATION_ONTO_SUBSPACE; +"ORTHOGONAL_TRANSFORMATION_ORTHOGONAL_EIGENVECTORS",ORTHOGONAL_TRANSFORMATION_ORTHOGONAL_EIGENVECTORS; +"ORTHOGONAL_TRANSFORMATION_SURJECTIVE",ORTHOGONAL_TRANSFORMATION_SURJECTIVE; +"ORTHONORMAL_BASIS_EXPAND",ORTHONORMAL_BASIS_EXPAND; +"ORTHONORMAL_BASIS_SUBSPACE",ORTHONORMAL_BASIS_SUBSPACE; +"ORTHONORMAL_EXTENSION",ORTHONORMAL_EXTENSION; +"OR_CLAUSES",OR_CLAUSES; +"OR_DEF",OR_DEF; +"OR_EXISTS_THM",OR_EXISTS_THM; +"OUTER",OUTER; +"OUTERMORPHISM_MBASIS",OUTERMORPHISM_MBASIS; +"OUTERMORPHISM_MBASIS_EMPTY",OUTERMORPHISM_MBASIS_EMPTY; +"OUTER_ACI",OUTER_ACI; +"OUTER_ASSOC",OUTER_ASSOC; +"OUTER_LADD",OUTER_LADD; +"OUTER_LMUL",OUTER_LMUL; +"OUTER_LNEG",OUTER_LNEG; +"OUTER_LZERO",OUTER_LZERO; +"OUTER_MBASIS",OUTER_MBASIS; +"OUTER_MBASIS_LSCALAR",OUTER_MBASIS_LSCALAR; +"OUTER_MBASIS_REFL",OUTER_MBASIS_REFL; +"OUTER_MBASIS_RSCALAR",OUTER_MBASIS_RSCALAR; +"OUTER_MBASIS_SING",OUTER_MBASIS_SING; +"OUTER_MBASIS_SKEWSYM",OUTER_MBASIS_SKEWSYM; +"OUTER_RADD",OUTER_RADD; +"OUTER_RMUL",OUTER_RMUL; +"OUTER_RNEG",OUTER_RNEG; +"OUTER_RZERO",OUTER_RZERO; +"OUTL",OUTL; +"OUTR",OUTR; +"OUTSIDE",OUTSIDE; +"OUTSIDE_BOUNDED_NONEMPTY",OUTSIDE_BOUNDED_NONEMPTY; +"OUTSIDE_COMPACT_IN_OPEN",OUTSIDE_COMPACT_IN_OPEN; +"OUTSIDE_CONNECTED_COMPONENT_LE",OUTSIDE_CONNECTED_COMPONENT_LE; +"OUTSIDE_CONNECTED_COMPONENT_LT",OUTSIDE_CONNECTED_COMPONENT_LT; +"OUTSIDE_CONVEX",OUTSIDE_CONVEX; +"OUTSIDE_EMPTY",OUTSIDE_EMPTY; +"OUTSIDE_FRONTIER_EQ_COMPLEMENT_CLOSURE",OUTSIDE_FRONTIER_EQ_COMPLEMENT_CLOSURE; +"OUTSIDE_FRONTIER_MISSES_CLOSURE",OUTSIDE_FRONTIER_MISSES_CLOSURE; +"OUTSIDE_INSIDE",OUTSIDE_INSIDE; +"OUTSIDE_IN_COMPONENTS",OUTSIDE_IN_COMPONENTS; +"OUTSIDE_LINEAR_IMAGE",OUTSIDE_LINEAR_IMAGE; +"OUTSIDE_MONO",OUTSIDE_MONO; +"OUTSIDE_NO_OVERLAP",OUTSIDE_NO_OVERLAP; +"OUTSIDE_SAME_COMPONENT",OUTSIDE_SAME_COMPONENT; +"OUTSIDE_SUBSET_CONVEX",OUTSIDE_SUBSET_CONVEX; +"OUTSIDE_TRANSLATION",OUTSIDE_TRANSLATION; +"OUTSIDE_UNION_OUTSIDE_UNION",OUTSIDE_UNION_OUTSIDE_UNION; +"PAIR",PAIR; +"PAIRED_ETA_THM",PAIRED_ETA_THM; +"PAIRED_EXT",PAIRED_EXT; +"PAIRWISE",PAIRWISE; +"PAIRWISE_DISJOINT_COMPONENTS",PAIRWISE_DISJOINT_COMPONENTS; +"PAIRWISE_EMPTY",PAIRWISE_EMPTY; +"PAIRWISE_IMAGE",PAIRWISE_IMAGE; +"PAIRWISE_INSERT",PAIRWISE_INSERT; +"PAIRWISE_MONO",PAIRWISE_MONO; +"PAIRWISE_ORTHOGONAL_IMP_FINITE",PAIRWISE_ORTHOGONAL_IMP_FINITE; +"PAIRWISE_ORTHOGONAL_INDEPENDENT",PAIRWISE_ORTHOGONAL_INDEPENDENT; +"PAIRWISE_SING",PAIRWISE_SING; +"PAIR_EQ",PAIR_EQ; +"PAIR_EXISTS_THM",PAIR_EXISTS_THM; +"PAIR_SURJECTIVE",PAIR_SURJECTIVE; +"PARTIAL_DIVISION_EXTEND",PARTIAL_DIVISION_EXTEND; +"PARTIAL_DIVISION_EXTEND_1",PARTIAL_DIVISION_EXTEND_1; +"PARTIAL_DIVISION_EXTEND_INTERVAL",PARTIAL_DIVISION_EXTEND_INTERVAL; +"PARTIAL_DIVISION_OF_TAGGED_DIVISION",PARTIAL_DIVISION_OF_TAGGED_DIVISION; +"PARTIAL_SUMS_COMPONENT_LE_INFSUM",PARTIAL_SUMS_COMPONENT_LE_INFSUM; +"PARTIAL_SUMS_DROP_LE_INFSUM",PARTIAL_SUMS_DROP_LE_INFSUM; +"PASSOC_DEF",PASSOC_DEF; +"PASTECART_ADD",PASTECART_ADD; +"PASTECART_AS_ORTHOGONAL_SUM",PASTECART_AS_ORTHOGONAL_SUM; +"PASTECART_CMUL",PASTECART_CMUL; +"PASTECART_EQ",PASTECART_EQ; +"PASTECART_EQ_VEC",PASTECART_EQ_VEC; +"PASTECART_FST_SND",PASTECART_FST_SND; +"PASTECART_INJ",PASTECART_INJ; +"PASTECART_IN_INTERIOR_SUBTOPOLOGY",PASTECART_IN_INTERIOR_SUBTOPOLOGY; +"PASTECART_IN_PCROSS",PASTECART_IN_PCROSS; +"PASTECART_NEG",PASTECART_NEG; +"PASTECART_SUB",PASTECART_SUB; +"PASTECART_VEC",PASTECART_VEC; +"PASTECART_VSUM",PASTECART_VSUM; +"PASTING_LEMMA",PASTING_LEMMA; +"PASTING_LEMMA_CLOSED",PASTING_LEMMA_CLOSED; +"PASTING_LEMMA_EXISTS",PASTING_LEMMA_EXISTS; +"PASTING_LEMMA_EXISTS_CLOSED",PASTING_LEMMA_EXISTS_CLOSED; +"PATHFINISH_COMPOSE",PATHFINISH_COMPOSE; +"PATHFINISH_IN_PATH_IMAGE",PATHFINISH_IN_PATH_IMAGE; +"PATHFINISH_JOIN",PATHFINISH_JOIN; +"PATHFINISH_LINEAR_IMAGE",PATHFINISH_LINEAR_IMAGE; +"PATHFINISH_LINEPATH",PATHFINISH_LINEPATH; +"PATHFINISH_REVERSEPATH",PATHFINISH_REVERSEPATH; +"PATHFINISH_SHIFTPATH",PATHFINISH_SHIFTPATH; +"PATHFINISH_SUBPATH",PATHFINISH_SUBPATH; +"PATHFINISH_TRANSLATION",PATHFINISH_TRANSLATION; +"PATHSTART_COMPOSE",PATHSTART_COMPOSE; +"PATHSTART_IN_PATH_IMAGE",PATHSTART_IN_PATH_IMAGE; +"PATHSTART_JOIN",PATHSTART_JOIN; +"PATHSTART_LINEAR_IMAGE_EQ",PATHSTART_LINEAR_IMAGE_EQ; +"PATHSTART_LINEPATH",PATHSTART_LINEPATH; +"PATHSTART_REVERSEPATH",PATHSTART_REVERSEPATH; +"PATHSTART_SHIFTPATH",PATHSTART_SHIFTPATH; +"PATHSTART_SUBPATH",PATHSTART_SUBPATH; +"PATHSTART_TRANSLATION",PATHSTART_TRANSLATION; +"PATH_ASSOC",PATH_ASSOC; +"PATH_COMPONENT",PATH_COMPONENT; +"PATH_COMPONENT_DISJOINT",PATH_COMPONENT_DISJOINT; +"PATH_COMPONENT_EMPTY",PATH_COMPONENT_EMPTY; +"PATH_COMPONENT_EQ",PATH_COMPONENT_EQ; +"PATH_COMPONENT_EQ_CONNECTED_COMPONENT",PATH_COMPONENT_EQ_CONNECTED_COMPONENT; +"PATH_COMPONENT_EQ_EMPTY",PATH_COMPONENT_EQ_EMPTY; +"PATH_COMPONENT_EQ_EQ",PATH_COMPONENT_EQ_EQ; +"PATH_COMPONENT_IMP_HOMOTOPIC_POINTS",PATH_COMPONENT_IMP_HOMOTOPIC_POINTS; +"PATH_COMPONENT_IN",PATH_COMPONENT_IN; +"PATH_COMPONENT_LINEAR_IMAGE",PATH_COMPONENT_LINEAR_IMAGE; +"PATH_COMPONENT_MAXIMAL",PATH_COMPONENT_MAXIMAL; +"PATH_COMPONENT_MONO",PATH_COMPONENT_MONO; +"PATH_COMPONENT_OF_SUBSET",PATH_COMPONENT_OF_SUBSET; +"PATH_COMPONENT_PATH_COMPONENT",PATH_COMPONENT_PATH_COMPONENT; +"PATH_COMPONENT_PATH_IMAGE_PATHSTART",PATH_COMPONENT_PATH_IMAGE_PATHSTART; +"PATH_COMPONENT_REFL",PATH_COMPONENT_REFL; +"PATH_COMPONENT_REFL_EQ",PATH_COMPONENT_REFL_EQ; +"PATH_COMPONENT_SET",PATH_COMPONENT_SET; +"PATH_COMPONENT_SUBSET",PATH_COMPONENT_SUBSET; +"PATH_COMPONENT_SUBSET_CONNECTED_COMPONENT",PATH_COMPONENT_SUBSET_CONNECTED_COMPONENT; +"PATH_COMPONENT_SYM",PATH_COMPONENT_SYM; +"PATH_COMPONENT_SYM_EQ",PATH_COMPONENT_SYM_EQ; +"PATH_COMPONENT_TRANS",PATH_COMPONENT_TRANS; +"PATH_COMPONENT_TRANSLATION",PATH_COMPONENT_TRANSLATION; +"PATH_COMPONENT_UNIV",PATH_COMPONENT_UNIV; +"PATH_COMPOSE_JOIN",PATH_COMPOSE_JOIN; +"PATH_COMPOSE_REVERSEPATH",PATH_COMPOSE_REVERSEPATH; +"PATH_CONNECTED_ANNULUS",PATH_CONNECTED_ANNULUS; +"PATH_CONNECTED_ARCWISE",PATH_CONNECTED_ARCWISE; +"PATH_CONNECTED_ARC_COMPLEMENT",PATH_CONNECTED_ARC_COMPLEMENT; +"PATH_CONNECTED_COMPLEMENT_ABSOLUTE_RETRACT",PATH_CONNECTED_COMPLEMENT_ABSOLUTE_RETRACT; +"PATH_CONNECTED_COMPLEMENT_BOUNDED_CONVEX",PATH_CONNECTED_COMPLEMENT_BOUNDED_CONVEX; +"PATH_CONNECTED_COMPLEMENT_CARD_LT",PATH_CONNECTED_COMPLEMENT_CARD_LT; +"PATH_CONNECTED_COMPLEMENT_HOMEOMORPHIC_CONVEX_COMPACT",PATH_CONNECTED_COMPLEMENT_HOMEOMORPHIC_CONVEX_COMPACT; +"PATH_CONNECTED_COMPONENT_SET",PATH_CONNECTED_COMPONENT_SET; +"PATH_CONNECTED_CONTINUOUS_IMAGE",PATH_CONNECTED_CONTINUOUS_IMAGE; +"PATH_CONNECTED_CONVEX_DIFF_CARD_LT",PATH_CONNECTED_CONVEX_DIFF_CARD_LT; +"PATH_CONNECTED_DIFF_BALL",PATH_CONNECTED_DIFF_BALL; +"PATH_CONNECTED_EMPTY",PATH_CONNECTED_EMPTY; +"PATH_CONNECTED_EQ_CONNECTED",PATH_CONNECTED_EQ_CONNECTED; +"PATH_CONNECTED_EQ_CONNECTED_LPC",PATH_CONNECTED_EQ_CONNECTED_LPC; +"PATH_CONNECTED_EQ_HOMOTOPIC_POINTS",PATH_CONNECTED_EQ_HOMOTOPIC_POINTS; +"PATH_CONNECTED_IFF_PATH_COMPONENT",PATH_CONNECTED_IFF_PATH_COMPONENT; +"PATH_CONNECTED_IMP_CONNECTED",PATH_CONNECTED_IMP_CONNECTED; +"PATH_CONNECTED_INTERVAL",PATH_CONNECTED_INTERVAL; +"PATH_CONNECTED_LINEAR_IMAGE",PATH_CONNECTED_LINEAR_IMAGE; +"PATH_CONNECTED_LINEAR_IMAGE_EQ",PATH_CONNECTED_LINEAR_IMAGE_EQ; +"PATH_CONNECTED_LINEPATH",PATH_CONNECTED_LINEPATH; +"PATH_CONNECTED_NEGATIONS",PATH_CONNECTED_NEGATIONS; +"PATH_CONNECTED_OPEN_DELETE",PATH_CONNECTED_OPEN_DELETE; +"PATH_CONNECTED_OPEN_DIFF_CARD_LT",PATH_CONNECTED_OPEN_DIFF_CARD_LT; +"PATH_CONNECTED_OPEN_DIFF_COUNTABLE",PATH_CONNECTED_OPEN_DIFF_COUNTABLE; +"PATH_CONNECTED_OPEN_IN_DIFF_CARD_LT",PATH_CONNECTED_OPEN_IN_DIFF_CARD_LT; +"PATH_CONNECTED_PATH_COMPONENT",PATH_CONNECTED_PATH_COMPONENT; +"PATH_CONNECTED_PATH_IMAGE",PATH_CONNECTED_PATH_IMAGE; +"PATH_CONNECTED_PCROSS",PATH_CONNECTED_PCROSS; +"PATH_CONNECTED_PCROSS_EQ",PATH_CONNECTED_PCROSS_EQ; +"PATH_CONNECTED_PUNCTURED_BALL",PATH_CONNECTED_PUNCTURED_BALL; +"PATH_CONNECTED_PUNCTURED_UNIVERSE",PATH_CONNECTED_PUNCTURED_UNIVERSE; +"PATH_CONNECTED_SCALING",PATH_CONNECTED_SCALING; +"PATH_CONNECTED_SEGMENT",PATH_CONNECTED_SEGMENT; +"PATH_CONNECTED_SEMIOPEN_SEGMENT",PATH_CONNECTED_SEMIOPEN_SEGMENT; +"PATH_CONNECTED_SING",PATH_CONNECTED_SING; +"PATH_CONNECTED_SPHERE",PATH_CONNECTED_SPHERE; +"PATH_CONNECTED_SPHERE_EQ",PATH_CONNECTED_SPHERE_EQ; +"PATH_CONNECTED_SUMS",PATH_CONNECTED_SUMS; +"PATH_CONNECTED_TRANSLATION",PATH_CONNECTED_TRANSLATION; +"PATH_CONNECTED_TRANSLATION_EQ",PATH_CONNECTED_TRANSLATION_EQ; +"PATH_CONNECTED_UNION",PATH_CONNECTED_UNION; +"PATH_CONNECTED_UNIV",PATH_CONNECTED_UNIV; +"PATH_CONTAINS_ARC",PATH_CONTAINS_ARC; +"PATH_CONTINUOUS_IMAGE",PATH_CONTINUOUS_IMAGE; +"PATH_EQ",PATH_EQ; +"PATH_IMAGE_COMPOSE",PATH_IMAGE_COMPOSE; +"PATH_IMAGE_JOIN",PATH_IMAGE_JOIN; +"PATH_IMAGE_JOIN_SUBSET",PATH_IMAGE_JOIN_SUBSET; +"PATH_IMAGE_LINEAR_IMAGE",PATH_IMAGE_LINEAR_IMAGE; +"PATH_IMAGE_LINEPATH",PATH_IMAGE_LINEPATH; +"PATH_IMAGE_NONEMPTY",PATH_IMAGE_NONEMPTY; +"PATH_IMAGE_REVERSEPATH",PATH_IMAGE_REVERSEPATH; +"PATH_IMAGE_SHIFTPATH",PATH_IMAGE_SHIFTPATH; +"PATH_IMAGE_SUBPATH",PATH_IMAGE_SUBPATH; +"PATH_IMAGE_SUBPATH_GEN",PATH_IMAGE_SUBPATH_GEN; +"PATH_IMAGE_SUBPATH_SUBSET",PATH_IMAGE_SUBPATH_SUBSET; +"PATH_IMAGE_SYM",PATH_IMAGE_SYM; +"PATH_IMAGE_TRANSLATION",PATH_IMAGE_TRANSLATION; +"PATH_JOIN",PATH_JOIN; +"PATH_JOIN_EQ",PATH_JOIN_EQ; +"PATH_JOIN_IMP",PATH_JOIN_IMP; +"PATH_JOIN_PATH_ENDS",PATH_JOIN_PATH_ENDS; +"PATH_LENGTH_DIFFERENTIABLE",PATH_LENGTH_DIFFERENTIABLE; +"PATH_LENGTH_JOIN",PATH_LENGTH_JOIN; +"PATH_LENGTH_REVERSEPATH",PATH_LENGTH_REVERSEPATH; +"PATH_LINEAR_IMAGE_EQ",PATH_LINEAR_IMAGE_EQ; +"PATH_LINEPATH",PATH_LINEPATH; +"PATH_REVERSEPATH",PATH_REVERSEPATH; +"PATH_SHIFTPATH",PATH_SHIFTPATH; +"PATH_SUBPATH",PATH_SUBPATH; +"PATH_SYM",PATH_SYM; +"PATH_TRANSLATION_EQ",PATH_TRANSLATION_EQ; +"PCROSS",PCROSS; +"PCROSS_AS_ORTHOGONAL_SUM",PCROSS_AS_ORTHOGONAL_SUM; +"PCROSS_EMPTY",PCROSS_EMPTY; +"PCROSS_EQ",PCROSS_EQ; +"PCROSS_EQ_EMPTY",PCROSS_EQ_EMPTY; +"PCROSS_INTER",PCROSS_INTER; +"PCROSS_INTERVAL",PCROSS_INTERVAL; +"PCROSS_MONO",PCROSS_MONO; +"PCROSS_UNION",PCROSS_UNION; +"PCROSS_UNIONS",PCROSS_UNIONS; +"PCROSS_UNIONS_UNIONS",PCROSS_UNIONS_UNIONS; +"PERMUTATION",PERMUTATION; +"PERMUTATION_BIJECTIVE",PERMUTATION_BIJECTIVE; +"PERMUTATION_COMPOSE",PERMUTATION_COMPOSE; +"PERMUTATION_COMPOSE_EQ",PERMUTATION_COMPOSE_EQ; +"PERMUTATION_COMPOSE_SWAP",PERMUTATION_COMPOSE_SWAP; +"PERMUTATION_FINITE_SUPPORT",PERMUTATION_FINITE_SUPPORT; +"PERMUTATION_I",PERMUTATION_I; +"PERMUTATION_INVERSE",PERMUTATION_INVERSE; +"PERMUTATION_INVERSE_COMPOSE",PERMUTATION_INVERSE_COMPOSE; +"PERMUTATION_INVERSE_WORKS",PERMUTATION_INVERSE_WORKS; +"PERMUTATION_LEMMA",PERMUTATION_LEMMA; +"PERMUTATION_PERMUTES",PERMUTATION_PERMUTES; +"PERMUTATION_SWAP",PERMUTATION_SWAP; +"PERMUTES_COMPOSE",PERMUTES_COMPOSE; +"PERMUTES_EMPTY",PERMUTES_EMPTY; +"PERMUTES_FINITE_INJECTIVE",PERMUTES_FINITE_INJECTIVE; +"PERMUTES_FINITE_SURJECTIVE",PERMUTES_FINITE_SURJECTIVE; +"PERMUTES_I",PERMUTES_I; +"PERMUTES_IMAGE",PERMUTES_IMAGE; +"PERMUTES_INDUCT",PERMUTES_INDUCT; +"PERMUTES_INJECTIVE",PERMUTES_INJECTIVE; +"PERMUTES_INSERT",PERMUTES_INSERT; +"PERMUTES_INSERT_LEMMA",PERMUTES_INSERT_LEMMA; +"PERMUTES_INVERSE",PERMUTES_INVERSE; +"PERMUTES_INVERSES",PERMUTES_INVERSES; +"PERMUTES_INVERSES_o",PERMUTES_INVERSES_o; +"PERMUTES_INVERSE_EQ",PERMUTES_INVERSE_EQ; +"PERMUTES_INVERSE_INVERSE",PERMUTES_INVERSE_INVERSE; +"PERMUTES_IN_IMAGE",PERMUTES_IN_IMAGE; +"PERMUTES_IN_NUMSEG",PERMUTES_IN_NUMSEG; +"PERMUTES_NUMSET_GE",PERMUTES_NUMSET_GE; +"PERMUTES_NUMSET_LE",PERMUTES_NUMSET_LE; +"PERMUTES_SING",PERMUTES_SING; +"PERMUTES_SUBSET",PERMUTES_SUBSET; +"PERMUTES_SUPERSET",PERMUTES_SUPERSET; +"PERMUTES_SURJECTIVE",PERMUTES_SURJECTIVE; +"PERMUTES_SWAP",PERMUTES_SWAP; +"PERMUTES_UNIV",PERMUTES_UNIV; +"POINTWISE_ANTISYM",POINTWISE_ANTISYM; +"POINTWISE_MAXIMAL",POINTWISE_MAXIMAL; +"POINTWISE_MINIMAL",POINTWISE_MINIMAL; +"POLYHEDRON_AFFINE_HULL",POLYHEDRON_AFFINE_HULL; +"POLYHEDRON_AS_CONE_PLUS_CONV",POLYHEDRON_AS_CONE_PLUS_CONV; +"POLYHEDRON_CONVEX_CONE_HULL",POLYHEDRON_CONVEX_CONE_HULL; +"POLYHEDRON_CONVEX_HULL",POLYHEDRON_CONVEX_HULL; +"POLYHEDRON_EMPTY",POLYHEDRON_EMPTY; +"POLYHEDRON_EQ_FINITE_EXPOSED_FACES",POLYHEDRON_EQ_FINITE_EXPOSED_FACES; +"POLYHEDRON_EQ_FINITE_FACES",POLYHEDRON_EQ_FINITE_FACES; +"POLYHEDRON_HALFSPACE_GE",POLYHEDRON_HALFSPACE_GE; +"POLYHEDRON_HALFSPACE_LE",POLYHEDRON_HALFSPACE_LE; +"POLYHEDRON_HYPERPLANE",POLYHEDRON_HYPERPLANE; +"POLYHEDRON_IMP_CLOSED",POLYHEDRON_IMP_CLOSED; +"POLYHEDRON_IMP_CONVEX",POLYHEDRON_IMP_CONVEX; +"POLYHEDRON_INTER",POLYHEDRON_INTER; +"POLYHEDRON_INTERS",POLYHEDRON_INTERS; +"POLYHEDRON_INTERVAL",POLYHEDRON_INTERVAL; +"POLYHEDRON_INTER_AFFINE",POLYHEDRON_INTER_AFFINE; +"POLYHEDRON_INTER_AFFINE_MINIMAL",POLYHEDRON_INTER_AFFINE_MINIMAL; +"POLYHEDRON_INTER_AFFINE_PARALLEL",POLYHEDRON_INTER_AFFINE_PARALLEL; +"POLYHEDRON_INTER_AFFINE_PARALLEL_MINIMAL",POLYHEDRON_INTER_AFFINE_PARALLEL_MINIMAL; +"POLYHEDRON_INTER_POLYTOPE",POLYHEDRON_INTER_POLYTOPE; +"POLYHEDRON_LINEAR_IMAGE",POLYHEDRON_LINEAR_IMAGE; +"POLYHEDRON_LINEAR_IMAGE_EQ",POLYHEDRON_LINEAR_IMAGE_EQ; +"POLYHEDRON_NEGATIONS",POLYHEDRON_NEGATIONS; +"POLYHEDRON_POLYTOPE_SUMS",POLYHEDRON_POLYTOPE_SUMS; +"POLYHEDRON_POSITIVE_ORTHANT",POLYHEDRON_POSITIVE_ORTHANT; +"POLYHEDRON_RIDGE_TWO_FACETS",POLYHEDRON_RIDGE_TWO_FACETS; +"POLYHEDRON_SUMS",POLYHEDRON_SUMS; +"POLYHEDRON_TRANSLATION_EQ",POLYHEDRON_TRANSLATION_EQ; +"POLYHEDRON_UNIV",POLYHEDRON_UNIV; +"POLYTOPE_CONVEX_HULL",POLYTOPE_CONVEX_HULL; +"POLYTOPE_EMPTY",POLYTOPE_EMPTY; +"POLYTOPE_EQ_BOUNDED_POLYHEDRON",POLYTOPE_EQ_BOUNDED_POLYHEDRON; +"POLYTOPE_FACET_EXISTS",POLYTOPE_FACET_EXISTS; +"POLYTOPE_FACET_LOWER_BOUND",POLYTOPE_FACET_LOWER_BOUND; +"POLYTOPE_IMP_BOUNDED",POLYTOPE_IMP_BOUNDED; +"POLYTOPE_IMP_CLOSED",POLYTOPE_IMP_CLOSED; +"POLYTOPE_IMP_COMPACT",POLYTOPE_IMP_COMPACT; +"POLYTOPE_IMP_CONVEX",POLYTOPE_IMP_CONVEX; +"POLYTOPE_IMP_POLYHEDRON",POLYTOPE_IMP_POLYHEDRON; +"POLYTOPE_INTER",POLYTOPE_INTER; +"POLYTOPE_INTERVAL",POLYTOPE_INTERVAL; +"POLYTOPE_INTER_POLYHEDRON",POLYTOPE_INTER_POLYHEDRON; +"POLYTOPE_LINEAR_IMAGE",POLYTOPE_LINEAR_IMAGE; +"POLYTOPE_LINEAR_IMAGE_EQ",POLYTOPE_LINEAR_IMAGE_EQ; +"POLYTOPE_NEGATIONS",POLYTOPE_NEGATIONS; +"POLYTOPE_PCROSS",POLYTOPE_PCROSS; +"POLYTOPE_PCROSS_EQ",POLYTOPE_PCROSS_EQ; +"POLYTOPE_SCALING",POLYTOPE_SCALING; +"POLYTOPE_SCALING_EQ",POLYTOPE_SCALING_EQ; +"POLYTOPE_SING",POLYTOPE_SING; +"POLYTOPE_SUMS",POLYTOPE_SUMS; +"POLYTOPE_TRANSLATION_EQ",POLYTOPE_TRANSLATION_EQ; +"POLYTOPE_UNION_CONVEX_HULL_FACETS",POLYTOPE_UNION_CONVEX_HULL_FACETS; +"POLYTOPE_VERTEX_LOWER_BOUND",POLYTOPE_VERTEX_LOWER_BOUND; +"POSET_ANTISYM",POSET_ANTISYM; +"POSET_FLEQ",POSET_FLEQ; +"POSET_REFL",POSET_REFL; +"POSET_RESTRICTED_SUBSET",POSET_RESTRICTED_SUBSET; +"POSET_TRANS",POSET_TRANS; +"POWERSET_CLAUSES",POWERSET_CLAUSES; +"POW_2_SQRT",POW_2_SQRT; +"POW_2_SQRT_ABS",POW_2_SQRT_ABS; +"PRE",PRE; +"PRESERVES_LEBESGUE_MEASURABLE_IMP_PRESERVES_NEGLIGIBLE",PRESERVES_LEBESGUE_MEASURABLE_IMP_PRESERVES_NEGLIGIBLE; +"PRESERVES_NORM_INJECTIVE",PRESERVES_NORM_INJECTIVE; +"PRESERVES_NORM_PRESERVES_DOT",PRESERVES_NORM_PRESERVES_DOT; +"PRE_ELIM_THM",PRE_ELIM_THM; +"PRE_ELIM_THM'",PRE_ELIM_THM'; +"PRODUCT_1",PRODUCT_1; +"PRODUCT_2",PRODUCT_2; +"PRODUCT_3",PRODUCT_3; +"PRODUCT_4",PRODUCT_4; +"PRODUCT_ABS",PRODUCT_ABS; +"PRODUCT_ADD_SPLIT",PRODUCT_ADD_SPLIT; +"PRODUCT_ASSOCIATIVE",PRODUCT_ASSOCIATIVE; +"PRODUCT_CLAUSES",PRODUCT_CLAUSES; +"PRODUCT_CLAUSES_LEFT",PRODUCT_CLAUSES_LEFT; +"PRODUCT_CLAUSES_NUMSEG",PRODUCT_CLAUSES_NUMSEG; +"PRODUCT_CLAUSES_RIGHT",PRODUCT_CLAUSES_RIGHT; +"PRODUCT_CLOSED",PRODUCT_CLOSED; +"PRODUCT_CONST",PRODUCT_CONST; +"PRODUCT_CONST_NUMSEG",PRODUCT_CONST_NUMSEG; +"PRODUCT_CONST_NUMSEG_1",PRODUCT_CONST_NUMSEG_1; +"PRODUCT_DIV",PRODUCT_DIV; +"PRODUCT_DIV_NUMSEG",PRODUCT_DIV_NUMSEG; +"PRODUCT_EQ",PRODUCT_EQ; +"PRODUCT_EQ_0",PRODUCT_EQ_0; +"PRODUCT_EQ_0_NUMSEG",PRODUCT_EQ_0_NUMSEG; +"PRODUCT_EQ_1",PRODUCT_EQ_1; +"PRODUCT_EQ_1_NUMSEG",PRODUCT_EQ_1_NUMSEG; +"PRODUCT_EQ_NUMSEG",PRODUCT_EQ_NUMSEG; +"PRODUCT_IMAGE",PRODUCT_IMAGE; +"PRODUCT_INV",PRODUCT_INV; +"PRODUCT_LADD",PRODUCT_LADD; +"PRODUCT_LE",PRODUCT_LE; +"PRODUCT_LE_1",PRODUCT_LE_1; +"PRODUCT_LE_NUMSEG",PRODUCT_LE_NUMSEG; +"PRODUCT_LMUL",PRODUCT_LMUL; +"PRODUCT_LNEG",PRODUCT_LNEG; +"PRODUCT_LZERO",PRODUCT_LZERO; +"PRODUCT_MBASIS",PRODUCT_MBASIS; +"PRODUCT_MBASIS_SING",PRODUCT_MBASIS_SING; +"PRODUCT_MUL",PRODUCT_MUL; +"PRODUCT_MUL_NUMSEG",PRODUCT_MUL_NUMSEG; +"PRODUCT_NEG",PRODUCT_NEG; +"PRODUCT_NEG_NUMSEG",PRODUCT_NEG_NUMSEG; +"PRODUCT_NEG_NUMSEG_1",PRODUCT_NEG_NUMSEG_1; +"PRODUCT_OFFSET",PRODUCT_OFFSET; +"PRODUCT_ONE",PRODUCT_ONE; +"PRODUCT_PERMUTE",PRODUCT_PERMUTE; +"PRODUCT_PERMUTE_NUMSEG",PRODUCT_PERMUTE_NUMSEG; +"PRODUCT_POS_LE",PRODUCT_POS_LE; +"PRODUCT_POS_LE_NUMSEG",PRODUCT_POS_LE_NUMSEG; +"PRODUCT_POS_LT",PRODUCT_POS_LT; +"PRODUCT_POS_LT_NUMSEG",PRODUCT_POS_LT_NUMSEG; +"PRODUCT_RADD",PRODUCT_RADD; +"PRODUCT_RMUL",PRODUCT_RMUL; +"PRODUCT_RNEG",PRODUCT_RNEG; +"PRODUCT_RZERO",PRODUCT_RZERO; +"PRODUCT_SING",PRODUCT_SING; +"PRODUCT_SING_NUMSEG",PRODUCT_SING_NUMSEG; +"PRODUCT_UNION",PRODUCT_UNION; +"PROPERTY_EMPTY_INTERVAL",PROPERTY_EMPTY_INTERVAL; +"PROPER_MAP",PROPER_MAP; +"PROPER_MAP_FROM_COMPACT",PROPER_MAP_FROM_COMPACT; +"PSUBSET",PSUBSET; +"PSUBSET_ALT",PSUBSET_ALT; +"PSUBSET_INSERT_SUBSET",PSUBSET_INSERT_SUBSET; +"PSUBSET_IRREFL",PSUBSET_IRREFL; +"PSUBSET_MEMBER",PSUBSET_MEMBER; +"PSUBSET_SUBSET_TRANS",PSUBSET_SUBSET_TRANS; +"PSUBSET_TRANS",PSUBSET_TRANS; +"PSUBSET_UNIV",PSUBSET_UNIV; +"P_HULL",P_HULL; +"Product_DEF",Product_DEF; +"QUANTIFY_SURJECTION_HIGHER_THM",QUANTIFY_SURJECTION_HIGHER_THM; +"QUANTIFY_SURJECTION_THM",QUANTIFY_SURJECTION_THM; +"QUOTIENT_MAP_OPEN_CLOSED",QUOTIENT_MAP_OPEN_CLOSED; +"RADON",RADON; +"RADON_EX_LEMMA",RADON_EX_LEMMA; +"RADON_PARTITION",RADON_PARTITION; +"RADON_S_LEMMA",RADON_S_LEMMA; +"RADON_V_LEMMA",RADON_V_LEMMA; +"RANK_0",RANK_0; +"RANK_BOUND",RANK_BOUND; +"RANK_DIM_IM",RANK_DIM_IM; +"RANK_EQ_0",RANK_EQ_0; +"RANK_GRAM",RANK_GRAM; +"RANK_I",RANK_I; +"RANK_MUL_LE_LEFT",RANK_MUL_LE_LEFT; +"RANK_MUL_LE_RIGHT",RANK_MUL_LE_RIGHT; +"RANK_NULLSPACE",RANK_NULLSPACE; +"RANK_ROW",RANK_ROW; +"RANK_SYLVESTER",RANK_SYLVESTER; +"RANK_TRANSP",RANK_TRANSP; +"RANK_TRIANGLE",RANK_TRIANGLE; +"RATIONAL_ABS",RATIONAL_ABS; +"RATIONAL_ADD",RATIONAL_ADD; +"RATIONAL_ALT",RATIONAL_ALT; +"RATIONAL_APPROXIMATION",RATIONAL_APPROXIMATION; +"RATIONAL_APPROXIMATION_STRADDLE",RATIONAL_APPROXIMATION_STRADDLE; +"RATIONAL_BETWEEN",RATIONAL_BETWEEN; +"RATIONAL_CLOSED",RATIONAL_CLOSED; +"RATIONAL_DIV",RATIONAL_DIV; +"RATIONAL_INTEGER",RATIONAL_INTEGER; +"RATIONAL_INV",RATIONAL_INV; +"RATIONAL_INV_EQ",RATIONAL_INV_EQ; +"RATIONAL_MUL",RATIONAL_MUL; +"RATIONAL_NEG",RATIONAL_NEG; +"RATIONAL_NEG_EQ",RATIONAL_NEG_EQ; +"RATIONAL_NUM",RATIONAL_NUM; +"RATIONAL_POW",RATIONAL_POW; +"RATIONAL_SUB",RATIONAL_SUB; +"RAT_LEMMA1",RAT_LEMMA1; +"RAT_LEMMA2",RAT_LEMMA2; +"RAT_LEMMA3",RAT_LEMMA3; +"RAT_LEMMA4",RAT_LEMMA4; +"RAT_LEMMA5",RAT_LEMMA5; +"RAY_TO_FRONTIER",RAY_TO_FRONTIER; +"RAY_TO_RELATIVE_FRONTIER",RAY_TO_RELATIVE_FRONTIER; +"REAL_ABS_0",REAL_ABS_0; +"REAL_ABS_1",REAL_ABS_1; +"REAL_ABS_ABS",REAL_ABS_ABS; +"REAL_ABS_BETWEEN",REAL_ABS_BETWEEN; +"REAL_ABS_BETWEEN1",REAL_ABS_BETWEEN1; +"REAL_ABS_BETWEEN2",REAL_ABS_BETWEEN2; +"REAL_ABS_BOUND",REAL_ABS_BOUND; +"REAL_ABS_BOUNDS",REAL_ABS_BOUNDS; +"REAL_ABS_CASES",REAL_ABS_CASES; +"REAL_ABS_CIRCLE",REAL_ABS_CIRCLE; +"REAL_ABS_DIV",REAL_ABS_DIV; +"REAL_ABS_INFNORM",REAL_ABS_INFNORM; +"REAL_ABS_INF_LE",REAL_ABS_INF_LE; +"REAL_ABS_INTEGER_LEMMA",REAL_ABS_INTEGER_LEMMA; +"REAL_ABS_INV",REAL_ABS_INV; +"REAL_ABS_LE",REAL_ABS_LE; +"REAL_ABS_MUL",REAL_ABS_MUL; +"REAL_ABS_NEG",REAL_ABS_NEG; +"REAL_ABS_NORM",REAL_ABS_NORM; +"REAL_ABS_NUM",REAL_ABS_NUM; +"REAL_ABS_NZ",REAL_ABS_NZ; +"REAL_ABS_POS",REAL_ABS_POS; +"REAL_ABS_POW",REAL_ABS_POW; +"REAL_ABS_REFL",REAL_ABS_REFL; +"REAL_ABS_SGN",REAL_ABS_SGN; +"REAL_ABS_SIGN",REAL_ABS_SIGN; +"REAL_ABS_SIGN2",REAL_ABS_SIGN2; +"REAL_ABS_STILLNZ",REAL_ABS_STILLNZ; +"REAL_ABS_SUB",REAL_ABS_SUB; +"REAL_ABS_SUB_ABS",REAL_ABS_SUB_ABS; +"REAL_ABS_SUB_INFNORM",REAL_ABS_SUB_INFNORM; +"REAL_ABS_SUB_NORM",REAL_ABS_SUB_NORM; +"REAL_ABS_SUP_LE",REAL_ABS_SUP_LE; +"REAL_ABS_TRIANGLE",REAL_ABS_TRIANGLE; +"REAL_ABS_TRIANGLE_LE",REAL_ABS_TRIANGLE_LE; +"REAL_ABS_TRIANGLE_LT",REAL_ABS_TRIANGLE_LT; +"REAL_ABS_ZERO",REAL_ABS_ZERO; +"REAL_ADD2_SUB2",REAL_ADD2_SUB2; +"REAL_ADD_AC",REAL_ADD_AC; +"REAL_ADD_ASSOC",REAL_ADD_ASSOC; +"REAL_ADD_LDISTRIB",REAL_ADD_LDISTRIB; +"REAL_ADD_LID",REAL_ADD_LID; +"REAL_ADD_LINV",REAL_ADD_LINV; +"REAL_ADD_RDISTRIB",REAL_ADD_RDISTRIB; +"REAL_ADD_RID",REAL_ADD_RID; +"REAL_ADD_RINV",REAL_ADD_RINV; +"REAL_ADD_SUB",REAL_ADD_SUB; +"REAL_ADD_SUB2",REAL_ADD_SUB2; +"REAL_ADD_SYM",REAL_ADD_SYM; +"REAL_AFFINITY_EQ",REAL_AFFINITY_EQ; +"REAL_AFFINITY_LE",REAL_AFFINITY_LE; +"REAL_AFFINITY_LT",REAL_AFFINITY_LT; +"REAL_ARCH",REAL_ARCH; +"REAL_ARCH_INV",REAL_ARCH_INV; +"REAL_ARCH_LT",REAL_ARCH_LT; +"REAL_ARCH_POW",REAL_ARCH_POW; +"REAL_ARCH_POW2",REAL_ARCH_POW2; +"REAL_ARCH_POW_INV",REAL_ARCH_POW_INV; +"REAL_ARCH_RDIV_EQ_0",REAL_ARCH_RDIV_EQ_0; +"REAL_ARCH_SIMPLE",REAL_ARCH_SIMPLE; +"REAL_BOUNDS_LE",REAL_BOUNDS_LE; +"REAL_BOUNDS_LT",REAL_BOUNDS_LT; +"REAL_CARD_INTSEG_INT",REAL_CARD_INTSEG_INT; +"REAL_COMPLETE",REAL_COMPLETE; +"REAL_COMPLETE_SOMEPOS",REAL_COMPLETE_SOMEPOS; +"REAL_CONVEX_BOUND2_LT",REAL_CONVEX_BOUND2_LT; +"REAL_CONVEX_BOUND_LE",REAL_CONVEX_BOUND_LE; +"REAL_CONVEX_BOUND_LT",REAL_CONVEX_BOUND_LT; +"REAL_DIFFSQ",REAL_DIFFSQ; +"REAL_DIV_1",REAL_DIV_1; +"REAL_DIV_EQ_0",REAL_DIV_EQ_0; +"REAL_DIV_LMUL",REAL_DIV_LMUL; +"REAL_DIV_POW2",REAL_DIV_POW2; +"REAL_DIV_POW2_ALT",REAL_DIV_POW2_ALT; +"REAL_DIV_REFL",REAL_DIV_REFL; +"REAL_DIV_RMUL",REAL_DIV_RMUL; +"REAL_DIV_SQRT",REAL_DIV_SQRT; +"REAL_DOWN",REAL_DOWN; +"REAL_DOWN2",REAL_DOWN2; +"REAL_ENTIRE",REAL_ENTIRE; +"REAL_EQ_ADD_LCANCEL",REAL_EQ_ADD_LCANCEL; +"REAL_EQ_ADD_LCANCEL_0",REAL_EQ_ADD_LCANCEL_0; +"REAL_EQ_ADD_RCANCEL",REAL_EQ_ADD_RCANCEL; +"REAL_EQ_ADD_RCANCEL_0",REAL_EQ_ADD_RCANCEL_0; +"REAL_EQ_AFFINITY",REAL_EQ_AFFINITY; +"REAL_EQ_IMP_LE",REAL_EQ_IMP_LE; +"REAL_EQ_INTEGERS",REAL_EQ_INTEGERS; +"REAL_EQ_INTEGERS_IMP",REAL_EQ_INTEGERS_IMP; +"REAL_EQ_INV2",REAL_EQ_INV2; +"REAL_EQ_LCANCEL_IMP",REAL_EQ_LCANCEL_IMP; +"REAL_EQ_LDIV_EQ",REAL_EQ_LDIV_EQ; +"REAL_EQ_MUL_LCANCEL",REAL_EQ_MUL_LCANCEL; +"REAL_EQ_MUL_RCANCEL",REAL_EQ_MUL_RCANCEL; +"REAL_EQ_NEG2",REAL_EQ_NEG2; +"REAL_EQ_RCANCEL_IMP",REAL_EQ_RCANCEL_IMP; +"REAL_EQ_RDIV_EQ",REAL_EQ_RDIV_EQ; +"REAL_EQ_SQUARE_ABS",REAL_EQ_SQUARE_ABS; +"REAL_EQ_SUB_LADD",REAL_EQ_SUB_LADD; +"REAL_EQ_SUB_RADD",REAL_EQ_SUB_RADD; +"REAL_FLOOR_ADD",REAL_FLOOR_ADD; +"REAL_FLOOR_EQ",REAL_FLOOR_EQ; +"REAL_FLOOR_LE",REAL_FLOOR_LE; +"REAL_FLOOR_LT",REAL_FLOOR_LT; +"REAL_FLOOR_REFL",REAL_FLOOR_REFL; +"REAL_FRAC_ADD",REAL_FRAC_ADD; +"REAL_FRAC_EQ",REAL_FRAC_EQ; +"REAL_FRAC_EQ_0",REAL_FRAC_EQ_0; +"REAL_FRAC_POS_LT",REAL_FRAC_POS_LT; +"REAL_FRAC_ZERO",REAL_FRAC_ZERO; +"REAL_HALF",REAL_HALF; +"REAL_HREAL_LEMMA1",REAL_HREAL_LEMMA1; +"REAL_HREAL_LEMMA2",REAL_HREAL_LEMMA2; +"REAL_INF_ASCLOSE",REAL_INF_ASCLOSE; +"REAL_INF_BOUNDS",REAL_INF_BOUNDS; +"REAL_INF_LE_FINITE",REAL_INF_LE_FINITE; +"REAL_INF_LT_FINITE",REAL_INF_LT_FINITE; +"REAL_INF_UNIQUE",REAL_INF_UNIQUE; +"REAL_INV_0",REAL_INV_0; +"REAL_INV_1",REAL_INV_1; +"REAL_INV_1_LE",REAL_INV_1_LE; +"REAL_INV_1_LT",REAL_INV_1_LT; +"REAL_INV_DIV",REAL_INV_DIV; +"REAL_INV_EQ_0",REAL_INV_EQ_0; +"REAL_INV_EQ_1",REAL_INV_EQ_1; +"REAL_INV_INV",REAL_INV_INV; +"REAL_INV_LE_1",REAL_INV_LE_1; +"REAL_INV_LT_1",REAL_INV_LT_1; +"REAL_INV_MUL",REAL_INV_MUL; +"REAL_INV_NEG",REAL_INV_NEG; +"REAL_INV_POW",REAL_INV_POW; +"REAL_LET_ADD",REAL_LET_ADD; +"REAL_LET_ADD2",REAL_LET_ADD2; +"REAL_LET_ANTISYM",REAL_LET_ANTISYM; +"REAL_LET_TOTAL",REAL_LET_TOTAL; +"REAL_LET_TRANS",REAL_LET_TRANS; +"REAL_LE_01",REAL_LE_01; +"REAL_LE_ADD",REAL_LE_ADD; +"REAL_LE_ADD2",REAL_LE_ADD2; +"REAL_LE_ADDL",REAL_LE_ADDL; +"REAL_LE_ADDR",REAL_LE_ADDR; +"REAL_LE_AFFINITY",REAL_LE_AFFINITY; +"REAL_LE_ANTISYM",REAL_LE_ANTISYM; +"REAL_LE_BETWEEN",REAL_LE_BETWEEN; +"REAL_LE_CASES_INTEGERS",REAL_LE_CASES_INTEGERS; +"REAL_LE_DIV",REAL_LE_DIV; +"REAL_LE_DIV2_EQ",REAL_LE_DIV2_EQ; +"REAL_LE_DOUBLE",REAL_LE_DOUBLE; +"REAL_LE_FLOOR",REAL_LE_FLOOR; +"REAL_LE_INF",REAL_LE_INF; +"REAL_LE_INF_FINITE",REAL_LE_INF_FINITE; +"REAL_LE_INF_SUBSET",REAL_LE_INF_SUBSET; +"REAL_LE_INTEGERS",REAL_LE_INTEGERS; +"REAL_LE_INV",REAL_LE_INV; +"REAL_LE_INV2",REAL_LE_INV2; +"REAL_LE_INV_EQ",REAL_LE_INV_EQ; +"REAL_LE_LADD",REAL_LE_LADD; +"REAL_LE_LADD_IMP",REAL_LE_LADD_IMP; +"REAL_LE_LCANCEL_IMP",REAL_LE_LCANCEL_IMP; +"REAL_LE_LDIV_EQ",REAL_LE_LDIV_EQ; +"REAL_LE_LINV",REAL_LE_LINV; +"REAL_LE_LMUL",REAL_LE_LMUL; +"REAL_LE_LMUL_EQ",REAL_LE_LMUL_EQ; +"REAL_LE_LNEG",REAL_LE_LNEG; +"REAL_LE_LSQRT",REAL_LE_LSQRT; +"REAL_LE_LT",REAL_LE_LT; +"REAL_LE_MAX",REAL_LE_MAX; +"REAL_LE_MIN",REAL_LE_MIN; +"REAL_LE_MUL",REAL_LE_MUL; +"REAL_LE_MUL2",REAL_LE_MUL2; +"REAL_LE_MUL_EQ",REAL_LE_MUL_EQ; +"REAL_LE_NEG",REAL_LE_NEG; +"REAL_LE_NEG2",REAL_LE_NEG2; +"REAL_LE_NEGL",REAL_LE_NEGL; +"REAL_LE_NEGR",REAL_LE_NEGR; +"REAL_LE_NEGTOTAL",REAL_LE_NEGTOTAL; +"REAL_LE_POW2",REAL_LE_POW2; +"REAL_LE_POW_2",REAL_LE_POW_2; +"REAL_LE_RADD",REAL_LE_RADD; +"REAL_LE_RCANCEL_IMP",REAL_LE_RCANCEL_IMP; +"REAL_LE_RDIV_EQ",REAL_LE_RDIV_EQ; +"REAL_LE_REFL",REAL_LE_REFL; +"REAL_LE_REVERSE_INTEGERS",REAL_LE_REVERSE_INTEGERS; +"REAL_LE_RINV",REAL_LE_RINV; +"REAL_LE_RMUL",REAL_LE_RMUL; +"REAL_LE_RMUL_EQ",REAL_LE_RMUL_EQ; +"REAL_LE_RNEG",REAL_LE_RNEG; +"REAL_LE_RSQRT",REAL_LE_RSQRT; +"REAL_LE_SETDIST",REAL_LE_SETDIST; +"REAL_LE_SETDIST_EQ",REAL_LE_SETDIST_EQ; +"REAL_LE_SQUARE",REAL_LE_SQUARE; +"REAL_LE_SQUARE_ABS",REAL_LE_SQUARE_ABS; +"REAL_LE_SUB_LADD",REAL_LE_SUB_LADD; +"REAL_LE_SUB_RADD",REAL_LE_SUB_RADD; +"REAL_LE_SUP_FINITE",REAL_LE_SUP_FINITE; +"REAL_LE_TOTAL",REAL_LE_TOTAL; +"REAL_LE_TRANS",REAL_LE_TRANS; +"REAL_LNEG_UNIQ",REAL_LNEG_UNIQ; +"REAL_LSQRT_LE",REAL_LSQRT_LE; +"REAL_LTE_ADD",REAL_LTE_ADD; +"REAL_LTE_ADD2",REAL_LTE_ADD2; +"REAL_LTE_ANTISYM",REAL_LTE_ANTISYM; +"REAL_LTE_TOTAL",REAL_LTE_TOTAL; +"REAL_LTE_TRANS",REAL_LTE_TRANS; +"REAL_LT_01",REAL_LT_01; +"REAL_LT_ADD",REAL_LT_ADD; +"REAL_LT_ADD1",REAL_LT_ADD1; +"REAL_LT_ADD2",REAL_LT_ADD2; +"REAL_LT_ADDL",REAL_LT_ADDL; +"REAL_LT_ADDNEG",REAL_LT_ADDNEG; +"REAL_LT_ADDNEG2",REAL_LT_ADDNEG2; +"REAL_LT_ADDR",REAL_LT_ADDR; +"REAL_LT_ADD_SUB",REAL_LT_ADD_SUB; +"REAL_LT_AFFINITY",REAL_LT_AFFINITY; +"REAL_LT_ANTISYM",REAL_LT_ANTISYM; +"REAL_LT_BETWEEN",REAL_LT_BETWEEN; +"REAL_LT_DIV",REAL_LT_DIV; +"REAL_LT_DIV2_EQ",REAL_LT_DIV2_EQ; +"REAL_LT_GT",REAL_LT_GT; +"REAL_LT_IMP_LE",REAL_LT_IMP_LE; +"REAL_LT_IMP_NE",REAL_LT_IMP_NE; +"REAL_LT_IMP_NZ",REAL_LT_IMP_NZ; +"REAL_LT_INF_FINITE",REAL_LT_INF_FINITE; +"REAL_LT_INTEGERS",REAL_LT_INTEGERS; +"REAL_LT_INV",REAL_LT_INV; +"REAL_LT_INV2",REAL_LT_INV2; +"REAL_LT_INV_EQ",REAL_LT_INV_EQ; +"REAL_LT_LADD",REAL_LT_LADD; +"REAL_LT_LADD_IMP",REAL_LT_LADD_IMP; +"REAL_LT_LCANCEL_IMP",REAL_LT_LCANCEL_IMP; +"REAL_LT_LDIV_EQ",REAL_LT_LDIV_EQ; +"REAL_LT_LE",REAL_LT_LE; +"REAL_LT_LINV",REAL_LT_LINV; +"REAL_LT_LMUL",REAL_LT_LMUL; +"REAL_LT_LMUL_EQ",REAL_LT_LMUL_EQ; +"REAL_LT_LNEG",REAL_LT_LNEG; +"REAL_LT_LSQRT",REAL_LT_LSQRT; +"REAL_LT_MAX",REAL_LT_MAX; +"REAL_LT_MIN",REAL_LT_MIN; +"REAL_LT_MUL",REAL_LT_MUL; +"REAL_LT_MUL2",REAL_LT_MUL2; +"REAL_LT_MUL_EQ",REAL_LT_MUL_EQ; +"REAL_LT_NEG",REAL_LT_NEG; +"REAL_LT_NEG2",REAL_LT_NEG2; +"REAL_LT_NEGTOTAL",REAL_LT_NEGTOTAL; +"REAL_LT_POW2",REAL_LT_POW2; +"REAL_LT_RADD",REAL_LT_RADD; +"REAL_LT_RCANCEL_IMP",REAL_LT_RCANCEL_IMP; +"REAL_LT_RDIV_EQ",REAL_LT_RDIV_EQ; +"REAL_LT_REFL",REAL_LT_REFL; +"REAL_LT_RINV",REAL_LT_RINV; +"REAL_LT_RMUL",REAL_LT_RMUL; +"REAL_LT_RMUL_EQ",REAL_LT_RMUL_EQ; +"REAL_LT_RNEG",REAL_LT_RNEG; +"REAL_LT_RSQRT",REAL_LT_RSQRT; +"REAL_LT_SQUARE",REAL_LT_SQUARE; +"REAL_LT_SQUARE_ABS",REAL_LT_SQUARE_ABS; +"REAL_LT_SUB_LADD",REAL_LT_SUB_LADD; +"REAL_LT_SUB_RADD",REAL_LT_SUB_RADD; +"REAL_LT_SUP_FINITE",REAL_LT_SUP_FINITE; +"REAL_LT_TOTAL",REAL_LT_TOTAL; +"REAL_LT_TRANS",REAL_LT_TRANS; +"REAL_MAX_ACI",REAL_MAX_ACI; +"REAL_MAX_ASSOC",REAL_MAX_ASSOC; +"REAL_MAX_LE",REAL_MAX_LE; +"REAL_MAX_LT",REAL_MAX_LT; +"REAL_MAX_MAX",REAL_MAX_MAX; +"REAL_MAX_MIN",REAL_MAX_MIN; +"REAL_MAX_SUP",REAL_MAX_SUP; +"REAL_MAX_SYM",REAL_MAX_SYM; +"REAL_MIN_ACI",REAL_MIN_ACI; +"REAL_MIN_ASSOC",REAL_MIN_ASSOC; +"REAL_MIN_INF",REAL_MIN_INF; +"REAL_MIN_LE",REAL_MIN_LE; +"REAL_MIN_LT",REAL_MIN_LT; +"REAL_MIN_MAX",REAL_MIN_MAX; +"REAL_MIN_MIN",REAL_MIN_MIN; +"REAL_MIN_SYM",REAL_MIN_SYM; +"REAL_MUL_2",REAL_MUL_2; +"REAL_MUL_AC",REAL_MUL_AC; +"REAL_MUL_ASSOC",REAL_MUL_ASSOC; +"REAL_MUL_LID",REAL_MUL_LID; +"REAL_MUL_LINV",REAL_MUL_LINV; +"REAL_MUL_LINV_UNIQ",REAL_MUL_LINV_UNIQ; +"REAL_MUL_LNEG",REAL_MUL_LNEG; +"REAL_MUL_LZERO",REAL_MUL_LZERO; +"REAL_MUL_POS_LE",REAL_MUL_POS_LE; +"REAL_MUL_POS_LT",REAL_MUL_POS_LT; +"REAL_MUL_RID",REAL_MUL_RID; +"REAL_MUL_RINV",REAL_MUL_RINV; +"REAL_MUL_RINV_UNIQ",REAL_MUL_RINV_UNIQ; +"REAL_MUL_RNEG",REAL_MUL_RNEG; +"REAL_MUL_RZERO",REAL_MUL_RZERO; +"REAL_MUL_SUM",REAL_MUL_SUM; +"REAL_MUL_SUM_NUMSEG",REAL_MUL_SUM_NUMSEG; +"REAL_MUL_SYM",REAL_MUL_SYM; +"REAL_NEGNEG",REAL_NEGNEG; +"REAL_NEG_0",REAL_NEG_0; +"REAL_NEG_ADD",REAL_NEG_ADD; +"REAL_NEG_EQ",REAL_NEG_EQ; +"REAL_NEG_EQ_0",REAL_NEG_EQ_0; +"REAL_NEG_GE0",REAL_NEG_GE0; +"REAL_NEG_GT0",REAL_NEG_GT0; +"REAL_NEG_LE0",REAL_NEG_LE0; +"REAL_NEG_LMUL",REAL_NEG_LMUL; +"REAL_NEG_LT0",REAL_NEG_LT0; +"REAL_NEG_MINUS1",REAL_NEG_MINUS1; +"REAL_NEG_MUL2",REAL_NEG_MUL2; +"REAL_NEG_NEG",REAL_NEG_NEG; +"REAL_NEG_RMUL",REAL_NEG_RMUL; +"REAL_NEG_SUB",REAL_NEG_SUB; +"REAL_NOT_EQ",REAL_NOT_EQ; +"REAL_NOT_LE",REAL_NOT_LE; +"REAL_NOT_LT",REAL_NOT_LT; +"REAL_OF_INT_OF_REAL",REAL_OF_INT_OF_REAL; +"REAL_OF_NUM_ADD",REAL_OF_NUM_ADD; +"REAL_OF_NUM_EQ",REAL_OF_NUM_EQ; +"REAL_OF_NUM_GE",REAL_OF_NUM_GE; +"REAL_OF_NUM_GT",REAL_OF_NUM_GT; +"REAL_OF_NUM_LE",REAL_OF_NUM_LE; +"REAL_OF_NUM_LT",REAL_OF_NUM_LT; +"REAL_OF_NUM_MAX",REAL_OF_NUM_MAX; +"REAL_OF_NUM_MIN",REAL_OF_NUM_MIN; +"REAL_OF_NUM_MUL",REAL_OF_NUM_MUL; +"REAL_OF_NUM_POW",REAL_OF_NUM_POW; +"REAL_OF_NUM_SUB",REAL_OF_NUM_SUB; +"REAL_OF_NUM_SUC",REAL_OF_NUM_SUC; +"REAL_OF_NUM_SUM",REAL_OF_NUM_SUM; +"REAL_OF_NUM_SUM_NUMSEG",REAL_OF_NUM_SUM_NUMSEG; +"REAL_POLYFUN_EQ_0",REAL_POLYFUN_EQ_0; +"REAL_POLYFUN_EQ_CONST",REAL_POLYFUN_EQ_CONST; +"REAL_POLYFUN_FINITE_ROOTS",REAL_POLYFUN_FINITE_ROOTS; +"REAL_POLYFUN_ROOTBOUND",REAL_POLYFUN_ROOTBOUND; +"REAL_POLY_CLAUSES",REAL_POLY_CLAUSES; +"REAL_POLY_NEG_CLAUSES",REAL_POLY_NEG_CLAUSES; +"REAL_POS",REAL_POS; +"REAL_POS_NZ",REAL_POS_NZ; +"REAL_POW2_ABS",REAL_POW2_ABS; +"REAL_POW_1",REAL_POW_1; +"REAL_POW_1_LE",REAL_POW_1_LE; +"REAL_POW_1_LT",REAL_POW_1_LT; +"REAL_POW_2",REAL_POW_2; +"REAL_POW_ADD",REAL_POW_ADD; +"REAL_POW_DIV",REAL_POW_DIV; +"REAL_POW_EQ",REAL_POW_EQ; +"REAL_POW_EQ_0",REAL_POW_EQ_0; +"REAL_POW_EQ_1",REAL_POW_EQ_1; +"REAL_POW_EQ_1_IMP",REAL_POW_EQ_1_IMP; +"REAL_POW_EQ_ABS",REAL_POW_EQ_ABS; +"REAL_POW_EQ_EQ",REAL_POW_EQ_EQ; +"REAL_POW_EQ_ODD",REAL_POW_EQ_ODD; +"REAL_POW_EQ_ODD_EQ",REAL_POW_EQ_ODD_EQ; +"REAL_POW_INV",REAL_POW_INV; +"REAL_POW_LBOUND",REAL_POW_LBOUND; +"REAL_POW_LE",REAL_POW_LE; +"REAL_POW_LE2",REAL_POW_LE2; +"REAL_POW_LE2_ODD",REAL_POW_LE2_ODD; +"REAL_POW_LE2_ODD_EQ",REAL_POW_LE2_ODD_EQ; +"REAL_POW_LE2_REV",REAL_POW_LE2_REV; +"REAL_POW_LE_1",REAL_POW_LE_1; +"REAL_POW_LT",REAL_POW_LT; +"REAL_POW_LT2",REAL_POW_LT2; +"REAL_POW_LT2_ODD",REAL_POW_LT2_ODD; +"REAL_POW_LT2_ODD_EQ",REAL_POW_LT2_ODD_EQ; +"REAL_POW_LT2_REV",REAL_POW_LT2_REV; +"REAL_POW_LT_1",REAL_POW_LT_1; +"REAL_POW_MONO",REAL_POW_MONO; +"REAL_POW_MONO_INV",REAL_POW_MONO_INV; +"REAL_POW_MONO_LT",REAL_POW_MONO_LT; +"REAL_POW_MUL",REAL_POW_MUL; +"REAL_POW_NEG",REAL_POW_NEG; +"REAL_POW_NZ",REAL_POW_NZ; +"REAL_POW_ONE",REAL_POW_ONE; +"REAL_POW_POW",REAL_POW_POW; +"REAL_POW_SUB",REAL_POW_SUB; +"REAL_POW_ZERO",REAL_POW_ZERO; +"REAL_RNEG_UNIQ",REAL_RNEG_UNIQ; +"REAL_RSQRT_LE",REAL_RSQRT_LE; +"REAL_SGN",REAL_SGN; +"REAL_SGN_0",REAL_SGN_0; +"REAL_SGN_ABS",REAL_SGN_ABS; +"REAL_SGN_CASES",REAL_SGN_CASES; +"REAL_SGN_DIV",REAL_SGN_DIV; +"REAL_SGN_EQ",REAL_SGN_EQ; +"REAL_SGN_INEQS",REAL_SGN_INEQS; +"REAL_SGN_INV",REAL_SGN_INV; +"REAL_SGN_MUL",REAL_SGN_MUL; +"REAL_SGN_NEG",REAL_SGN_NEG; +"REAL_SOS_EQ_0",REAL_SOS_EQ_0; +"REAL_SUB_0",REAL_SUB_0; +"REAL_SUB_ABS",REAL_SUB_ABS; +"REAL_SUB_ADD",REAL_SUB_ADD; +"REAL_SUB_ADD2",REAL_SUB_ADD2; +"REAL_SUB_INV",REAL_SUB_INV; +"REAL_SUB_LDISTRIB",REAL_SUB_LDISTRIB; +"REAL_SUB_LE",REAL_SUB_LE; +"REAL_SUB_LNEG",REAL_SUB_LNEG; +"REAL_SUB_LT",REAL_SUB_LT; +"REAL_SUB_LZERO",REAL_SUB_LZERO; +"REAL_SUB_NEG2",REAL_SUB_NEG2; +"REAL_SUB_POLYFUN",REAL_SUB_POLYFUN; +"REAL_SUB_POLYFUN_ALT",REAL_SUB_POLYFUN_ALT; +"REAL_SUB_POW",REAL_SUB_POW; +"REAL_SUB_POW_L1",REAL_SUB_POW_L1; +"REAL_SUB_POW_R1",REAL_SUB_POW_R1; +"REAL_SUB_RDISTRIB",REAL_SUB_RDISTRIB; +"REAL_SUB_REFL",REAL_SUB_REFL; +"REAL_SUB_RNEG",REAL_SUB_RNEG; +"REAL_SUB_RZERO",REAL_SUB_RZERO; +"REAL_SUB_SUB",REAL_SUB_SUB; +"REAL_SUB_SUB2",REAL_SUB_SUB2; +"REAL_SUB_TRIANGLE",REAL_SUB_TRIANGLE; +"REAL_SUP_ASCLOSE",REAL_SUP_ASCLOSE; +"REAL_SUP_BOUNDS",REAL_SUP_BOUNDS; +"REAL_SUP_EQ_INF",REAL_SUP_EQ_INF; +"REAL_SUP_LE",REAL_SUP_LE; +"REAL_SUP_LE_FINITE",REAL_SUP_LE_FINITE; +"REAL_SUP_LE_SUBSET",REAL_SUP_LE_SUBSET; +"REAL_SUP_LT_FINITE",REAL_SUP_LT_FINITE; +"REAL_SUP_UNIQUE",REAL_SUP_UNIQUE; +"REAL_TRUNCATE",REAL_TRUNCATE; +"REAL_TRUNCATE_POS",REAL_TRUNCATE_POS; +"REAL_WLOG_LE",REAL_WLOG_LE; +"REAL_WLOG_LT",REAL_WLOG_LT; +"RECTIFIABLE_PATH_DIFFERENTIABLE",RECTIFIABLE_PATH_DIFFERENTIABLE; +"RECTIFIABLE_PATH_IMP_PATH",RECTIFIABLE_PATH_IMP_PATH; +"RECTIFIABLE_PATH_JOIN",RECTIFIABLE_PATH_JOIN; +"RECTIFIABLE_PATH_JOIN_EQ",RECTIFIABLE_PATH_JOIN_EQ; +"RECTIFIABLE_PATH_JOIN_IMP",RECTIFIABLE_PATH_JOIN_IMP; +"RECTIFIABLE_PATH_LINEPATH",RECTIFIABLE_PATH_LINEPATH; +"RECTIFIABLE_PATH_REVERSEPATH",RECTIFIABLE_PATH_REVERSEPATH; +"RECTIFIABLE_PATH_SUBPATH",RECTIFIABLE_PATH_SUBPATH; +"RECURSION_CASEWISE",RECURSION_CASEWISE; +"RECURSION_CASEWISE_PAIRWISE",RECURSION_CASEWISE_PAIRWISE; +"RECURSION_SUPERADMISSIBLE",RECURSION_SUPERADMISSIBLE; +"REDUCED_LABELLING",REDUCED_LABELLING; +"REDUCED_LABELLING_0",REDUCED_LABELLING_0; +"REDUCED_LABELLING_1",REDUCED_LABELLING_1; +"REDUCED_LABELLING_SUC",REDUCED_LABELLING_SUC; +"REDUCED_LABELLING_UNIQUE",REDUCED_LABELLING_UNIQUE; +"REDUCE_LABELLING_0",REDUCE_LABELLING_0; +"REFLECT_ALONG_0",REFLECT_ALONG_0; +"REFLECT_ALONG_1D",REFLECT_ALONG_1D; +"REFLECT_ALONG_ADD",REFLECT_ALONG_ADD; +"REFLECT_ALONG_BASIS",REFLECT_ALONG_BASIS; +"REFLECT_ALONG_EQ_0",REFLECT_ALONG_EQ_0; +"REFLECT_ALONG_EQ_SELF",REFLECT_ALONG_EQ_SELF; +"REFLECT_ALONG_INVOLUTION",REFLECT_ALONG_INVOLUTION; +"REFLECT_ALONG_LINEAR_IMAGE",REFLECT_ALONG_LINEAR_IMAGE; +"REFLECT_ALONG_MUL",REFLECT_ALONG_MUL; +"REFLECT_ALONG_REFL",REFLECT_ALONG_REFL; +"REFLECT_ALONG_SCALE",REFLECT_ALONG_SCALE; +"REFLECT_ALONG_ZERO",REFLECT_ALONG_ZERO; +"REFLECT_INTERVAL",REFLECT_INTERVAL; +"REFL_CLAUSE",REFL_CLAUSE; +"RELATIVE_BOUNDARY_OF_CONVEX_HULL",RELATIVE_BOUNDARY_OF_CONVEX_HULL; +"RELATIVE_BOUNDARY_OF_POLYHEDRON",RELATIVE_BOUNDARY_OF_POLYHEDRON; +"RELATIVE_BOUNDARY_OF_TRIANGLE",RELATIVE_BOUNDARY_OF_TRIANGLE; +"RELATIVE_BOUNDARY_RETRACT_OF_PUNCTURED_AFFINE_HULL",RELATIVE_BOUNDARY_RETRACT_OF_PUNCTURED_AFFINE_HULL; +"RELATIVE_FRONTIER_BALL",RELATIVE_FRONTIER_BALL; +"RELATIVE_FRONTIER_CBALL",RELATIVE_FRONTIER_CBALL; +"RELATIVE_FRONTIER_CLOSURE",RELATIVE_FRONTIER_CLOSURE; +"RELATIVE_FRONTIER_CONVEX_HULL_CASES",RELATIVE_FRONTIER_CONVEX_HULL_CASES; +"RELATIVE_FRONTIER_CONVEX_HULL_EXPLICIT",RELATIVE_FRONTIER_CONVEX_HULL_EXPLICIT; +"RELATIVE_FRONTIER_CONVEX_INTER_AFFINE",RELATIVE_FRONTIER_CONVEX_INTER_AFFINE; +"RELATIVE_FRONTIER_EMPTY",RELATIVE_FRONTIER_EMPTY; +"RELATIVE_FRONTIER_EQ_EMPTY",RELATIVE_FRONTIER_EQ_EMPTY; +"RELATIVE_FRONTIER_FRONTIER",RELATIVE_FRONTIER_FRONTIER; +"RELATIVE_FRONTIER_INJECTIVE_LINEAR_IMAGE",RELATIVE_FRONTIER_INJECTIVE_LINEAR_IMAGE; +"RELATIVE_FRONTIER_NONEMPTY_INTERIOR",RELATIVE_FRONTIER_NONEMPTY_INTERIOR; +"RELATIVE_FRONTIER_NOT_SING",RELATIVE_FRONTIER_NOT_SING; +"RELATIVE_FRONTIER_OF_CONVEX_HULL",RELATIVE_FRONTIER_OF_CONVEX_HULL; +"RELATIVE_FRONTIER_OF_POLYHEDRON",RELATIVE_FRONTIER_OF_POLYHEDRON; +"RELATIVE_FRONTIER_OF_POLYHEDRON_ALT",RELATIVE_FRONTIER_OF_POLYHEDRON_ALT; +"RELATIVE_FRONTIER_OF_TRIANGLE",RELATIVE_FRONTIER_OF_TRIANGLE; +"RELATIVE_FRONTIER_RETRACT_OF_PUNCTURED_AFFINE_HULL",RELATIVE_FRONTIER_RETRACT_OF_PUNCTURED_AFFINE_HULL; +"RELATIVE_FRONTIER_SING",RELATIVE_FRONTIER_SING; +"RELATIVE_FRONTIER_TRANSLATION",RELATIVE_FRONTIER_TRANSLATION; +"RELATIVE_INTERIOR",RELATIVE_INTERIOR; +"RELATIVE_INTERIOR_AFFINE",RELATIVE_INTERIOR_AFFINE; +"RELATIVE_INTERIOR_CONVEX_CONTAINS_SAME_RAY",RELATIVE_INTERIOR_CONVEX_CONTAINS_SAME_RAY; +"RELATIVE_INTERIOR_CONVEX_HULL_EXPLICIT",RELATIVE_INTERIOR_CONVEX_HULL_EXPLICIT; +"RELATIVE_INTERIOR_CONVEX_INTER_AFFINE",RELATIVE_INTERIOR_CONVEX_INTER_AFFINE; +"RELATIVE_INTERIOR_CONVEX_PROLONG",RELATIVE_INTERIOR_CONVEX_PROLONG; +"RELATIVE_INTERIOR_EMPTY",RELATIVE_INTERIOR_EMPTY; +"RELATIVE_INTERIOR_EQ",RELATIVE_INTERIOR_EQ; +"RELATIVE_INTERIOR_EQ_CLOSURE",RELATIVE_INTERIOR_EQ_CLOSURE; +"RELATIVE_INTERIOR_EQ_EMPTY",RELATIVE_INTERIOR_EQ_EMPTY; +"RELATIVE_INTERIOR_INJECTIVE_LINEAR_IMAGE",RELATIVE_INTERIOR_INJECTIVE_LINEAR_IMAGE; +"RELATIVE_INTERIOR_INTERIOR",RELATIVE_INTERIOR_INTERIOR; +"RELATIVE_INTERIOR_LINEAR_IMAGE_CONVEX",RELATIVE_INTERIOR_LINEAR_IMAGE_CONVEX; +"RELATIVE_INTERIOR_MAXIMAL",RELATIVE_INTERIOR_MAXIMAL; +"RELATIVE_INTERIOR_NONEMPTY_INTERIOR",RELATIVE_INTERIOR_NONEMPTY_INTERIOR; +"RELATIVE_INTERIOR_OF_POLYHEDRON",RELATIVE_INTERIOR_OF_POLYHEDRON; +"RELATIVE_INTERIOR_OPEN",RELATIVE_INTERIOR_OPEN; +"RELATIVE_INTERIOR_OPEN_IN",RELATIVE_INTERIOR_OPEN_IN; +"RELATIVE_INTERIOR_PCROSS",RELATIVE_INTERIOR_PCROSS; +"RELATIVE_INTERIOR_POLYHEDRON_EXPLICIT",RELATIVE_INTERIOR_POLYHEDRON_EXPLICIT; +"RELATIVE_INTERIOR_PROLONG",RELATIVE_INTERIOR_PROLONG; +"RELATIVE_INTERIOR_SEGMENT",RELATIVE_INTERIOR_SEGMENT; +"RELATIVE_INTERIOR_SING",RELATIVE_INTERIOR_SING; +"RELATIVE_INTERIOR_SUBSET",RELATIVE_INTERIOR_SUBSET; +"RELATIVE_INTERIOR_TRANSLATION",RELATIVE_INTERIOR_TRANSLATION; +"RELATIVE_INTERIOR_UNBOUNDED_CONVEX_CONTAINS_RAY",RELATIVE_INTERIOR_UNBOUNDED_CONVEX_CONTAINS_RAY; +"RELATIVE_INTERIOR_UNBOUNDED_CONVEX_CONTAINS_RAYS",RELATIVE_INTERIOR_UNBOUNDED_CONVEX_CONTAINS_RAYS; +"RELATIVE_INTERIOR_UNIQUE",RELATIVE_INTERIOR_UNIQUE; +"RELATIVE_INTERIOR_UNIV",RELATIVE_INTERIOR_UNIV; +"REPLICATE",REPLICATE; +"REP_ABS_PAIR",REP_ABS_PAIR; +"REST",REST; +"RETRACTION",RETRACTION; +"RETRACTION_ARC",RETRACTION_ARC; +"RETRACTION_IDEMPOTENT",RETRACTION_IDEMPOTENT; +"RETRACTION_IMP_QUOTIENT_MAP",RETRACTION_IMP_QUOTIENT_MAP; +"RETRACTION_REFL",RETRACTION_REFL; +"RETRACTION_SUBSET",RETRACTION_SUBSET; +"RETRACTION_o",RETRACTION_o; +"RETRACT_FIXPOINT_PROPERTY",RETRACT_FIXPOINT_PROPERTY; +"RETRACT_OF_CLOSED",RETRACT_OF_CLOSED; +"RETRACT_OF_COHOMOTOPICALLY_TRIVIAL",RETRACT_OF_COHOMOTOPICALLY_TRIVIAL; +"RETRACT_OF_COHOMOTOPICALLY_TRIVIAL_NULL",RETRACT_OF_COHOMOTOPICALLY_TRIVIAL_NULL; +"RETRACT_OF_COMPACT",RETRACT_OF_COMPACT; +"RETRACT_OF_CONNECTED",RETRACT_OF_CONNECTED; +"RETRACT_OF_CONTRACTIBLE",RETRACT_OF_CONTRACTIBLE; +"RETRACT_OF_EMPTY",RETRACT_OF_EMPTY; +"RETRACT_OF_HOMOTOPICALLY_TRIVIAL",RETRACT_OF_HOMOTOPICALLY_TRIVIAL; +"RETRACT_OF_HOMOTOPICALLY_TRIVIAL_NULL",RETRACT_OF_HOMOTOPICALLY_TRIVIAL_NULL; +"RETRACT_OF_IMP_EXTENSIBLE",RETRACT_OF_IMP_EXTENSIBLE; +"RETRACT_OF_IMP_SUBSET",RETRACT_OF_IMP_SUBSET; +"RETRACT_OF_INJECTIVE_LINEAR_IMAGE",RETRACT_OF_INJECTIVE_LINEAR_IMAGE; +"RETRACT_OF_LINEAR_IMAGE_EQ",RETRACT_OF_LINEAR_IMAGE_EQ; +"RETRACT_OF_LOCALLY_COMPACT",RETRACT_OF_LOCALLY_COMPACT; +"RETRACT_OF_LOCALLY_CONNECTED",RETRACT_OF_LOCALLY_CONNECTED; +"RETRACT_OF_LOCALLY_PATH_CONNECTED",RETRACT_OF_LOCALLY_PATH_CONNECTED; +"RETRACT_OF_PATH_CONNECTED",RETRACT_OF_PATH_CONNECTED; +"RETRACT_OF_PCROSS",RETRACT_OF_PCROSS; +"RETRACT_OF_REFL",RETRACT_OF_REFL; +"RETRACT_OF_SIMPLY_CONNECTED",RETRACT_OF_SIMPLY_CONNECTED; +"RETRACT_OF_SING",RETRACT_OF_SING; +"RETRACT_OF_SUBSET",RETRACT_OF_SUBSET; +"RETRACT_OF_TRANS",RETRACT_OF_TRANS; +"RETRACT_OF_TRANSLATION",RETRACT_OF_TRANSLATION; +"RETRACT_OF_TRANSLATION_EQ",RETRACT_OF_TRANSLATION_EQ; +"REVERSE",REVERSE; +"REVERSEPATH_JOINPATHS",REVERSEPATH_JOINPATHS; +"REVERSEPATH_LINEAR_IMAGE",REVERSEPATH_LINEAR_IMAGE; +"REVERSEPATH_LINEPATH",REVERSEPATH_LINEPATH; +"REVERSEPATH_REVERSEPATH",REVERSEPATH_REVERSEPATH; +"REVERSEPATH_SUBPATH",REVERSEPATH_SUBPATH; +"REVERSEPATH_TRANSLATION",REVERSEPATH_TRANSLATION; +"REVERSE_APPEND",REVERSE_APPEND; +"REVERSE_REVERSE",REVERSE_REVERSE; +"RIGHT_ADD_DISTRIB",RIGHT_ADD_DISTRIB; +"RIGHT_AND_EXISTS_THM",RIGHT_AND_EXISTS_THM; +"RIGHT_AND_FORALL_THM",RIGHT_AND_FORALL_THM; +"RIGHT_EXISTS_AND_THM",RIGHT_EXISTS_AND_THM; +"RIGHT_EXISTS_IMP_THM",RIGHT_EXISTS_IMP_THM; +"RIGHT_FORALL_IMP_THM",RIGHT_FORALL_IMP_THM; +"RIGHT_FORALL_OR_THM",RIGHT_FORALL_OR_THM; +"RIGHT_IMP_EXISTS_THM",RIGHT_IMP_EXISTS_THM; +"RIGHT_IMP_FORALL_THM",RIGHT_IMP_FORALL_THM; +"RIGHT_INVERSE_LINEAR",RIGHT_INVERSE_LINEAR; +"RIGHT_INVERTIBLE_TRANSP",RIGHT_INVERTIBLE_TRANSP; +"RIGHT_OR_DISTRIB",RIGHT_OR_DISTRIB; +"RIGHT_OR_EXISTS_THM",RIGHT_OR_EXISTS_THM; +"RIGHT_OR_FORALL_THM",RIGHT_OR_FORALL_THM; +"RIGHT_SUB_DISTRIB",RIGHT_SUB_DISTRIB; +"RIGID_TRANSFORMATION_BETWEEN_2",RIGID_TRANSFORMATION_BETWEEN_2; +"RIGID_TRANSFORMATION_BETWEEN_3",RIGID_TRANSFORMATION_BETWEEN_3; +"RIGID_TRANSFORMATION_BETWEEN_CONGRUENT_SETS",RIGID_TRANSFORMATION_BETWEEN_CONGRUENT_SETS; +"RIGID_TRANSFORMATION_BETWEEN_CONGRUENT_SETS_STRONG",RIGID_TRANSFORMATION_BETWEEN_CONGRUENT_SETS_STRONG; +"ROLLE",ROLLE; +"ROTATION_EXISTS",ROTATION_EXISTS; +"ROTATION_EXISTS_1",ROTATION_EXISTS_1; +"ROTATION_LOWDIM_HORIZONTAL",ROTATION_LOWDIM_HORIZONTAL; +"ROTATION_MATRIX_2",ROTATION_MATRIX_2; +"ROTATION_MATRIX_EXISTS_BASIS",ROTATION_MATRIX_EXISTS_BASIS; +"ROTATION_RIGHTWARD_LINE",ROTATION_RIGHTWARD_LINE; +"ROTHE",ROTHE; +"ROTOINVERSION_MATRIX_REFLECT_ALONG",ROTOINVERSION_MATRIX_REFLECT_ALONG; +"ROWS_TRANSP",ROWS_TRANSP; +"ROW_TRANSP",ROW_TRANSP; +"RSUM_BOUND",RSUM_BOUND; +"RSUM_COMPONENT_LE",RSUM_COMPONENT_LE; +"RSUM_DIFF_BOUND",RSUM_DIFF_BOUND; +"SAME_DISTANCES_TO_AFFINE_HULL",SAME_DISTANCES_TO_AFFINE_HULL; +"SCALING_LINEAR",SCALING_LINEAR; +"SCHAUDER",SCHAUDER; +"SCHAUDER_PROJECTION",SCHAUDER_PROJECTION; +"SCHAUDER_UNIV",SCHAUDER_UNIV; +"SECOND_MEAN_VALUE_THEOREM",SECOND_MEAN_VALUE_THEOREM; +"SECOND_MEAN_VALUE_THEOREM_BONNET",SECOND_MEAN_VALUE_THEOREM_BONNET; +"SECOND_MEAN_VALUE_THEOREM_BONNET_FULL",SECOND_MEAN_VALUE_THEOREM_BONNET_FULL; +"SECOND_MEAN_VALUE_THEOREM_FULL",SECOND_MEAN_VALUE_THEOREM_FULL; +"SECOND_MEAN_VALUE_THEOREM_GEN",SECOND_MEAN_VALUE_THEOREM_GEN; +"SECOND_MEAN_VALUE_THEOREM_GEN_FULL",SECOND_MEAN_VALUE_THEOREM_GEN_FULL; +"SEGMENT_1",SEGMENT_1; +"SEGMENT_AS_BALL",SEGMENT_AS_BALL; +"SEGMENT_BOUND",SEGMENT_BOUND; +"SEGMENT_CLOSED_OPEN",SEGMENT_CLOSED_OPEN; +"SEGMENT_CONVEX_HULL",SEGMENT_CONVEX_HULL; +"SEGMENT_EDGE_OF",SEGMENT_EDGE_OF; +"SEGMENT_EQ",SEGMENT_EQ; +"SEGMENT_EQ_EMPTY",SEGMENT_EQ_EMPTY; +"SEGMENT_EQ_SING",SEGMENT_EQ_SING; +"SEGMENT_FACE_OF",SEGMENT_FACE_OF; +"SEGMENT_FURTHEST_LE",SEGMENT_FURTHEST_LE; +"SEGMENT_HORIZONTAL",SEGMENT_HORIZONTAL; +"SEGMENT_IMAGE_INTERVAL",SEGMENT_IMAGE_INTERVAL; +"SEGMENT_OPEN_SUBSET_CLOSED",SEGMENT_OPEN_SUBSET_CLOSED; +"SEGMENT_REFL",SEGMENT_REFL; +"SEGMENT_SCALAR_MULTIPLE",SEGMENT_SCALAR_MULTIPLE; +"SEGMENT_SYM",SEGMENT_SYM; +"SEGMENT_TO_CLOSEST_POINT",SEGMENT_TO_CLOSEST_POINT; +"SEGMENT_TO_POINT_EXISTS",SEGMENT_TO_POINT_EXISTS; +"SEGMENT_TRANSLATION",SEGMENT_TRANSLATION; +"SEGMENT_VERTICAL",SEGMENT_VERTICAL; +"SELECT_AX",SELECT_AX; +"SELECT_REFL",SELECT_REFL; +"SELECT_UNIQUE",SELECT_UNIQUE; +"SELF_ADJOINT_COMPOSE",SELF_ADJOINT_COMPOSE; +"SELF_ADJOINT_HAS_EIGENVECTOR",SELF_ADJOINT_HAS_EIGENVECTOR; +"SELF_ADJOINT_HAS_EIGENVECTOR_BASIS",SELF_ADJOINT_HAS_EIGENVECTOR_BASIS; +"SELF_ADJOINT_HAS_EIGENVECTOR_BASIS_OF_SUBSPACE",SELF_ADJOINT_HAS_EIGENVECTOR_BASIS_OF_SUBSPACE; +"SELF_ADJOINT_HAS_EIGENVECTOR_IN_SUBSPACE",SELF_ADJOINT_HAS_EIGENVECTOR_IN_SUBSPACE; +"SELF_ADJOINT_ORTHOGONAL_EIGENVECTORS",SELF_ADJOINT_ORTHOGONAL_EIGENVECTORS; +"SEPARABLE",SEPARABLE; +"SEPARATE_CLOSED_COMPACT",SEPARATE_CLOSED_COMPACT; +"SEPARATE_CLOSED_CONES",SEPARATE_CLOSED_CONES; +"SEPARATE_COMPACT_CLOSED",SEPARATE_COMPACT_CLOSED; +"SEPARATE_POINT_CLOSED",SEPARATE_POINT_CLOSED; +"SEPARATING_HYPERPLANE_CLOSED_0",SEPARATING_HYPERPLANE_CLOSED_0; +"SEPARATING_HYPERPLANE_CLOSED_0_INSET",SEPARATING_HYPERPLANE_CLOSED_0_INSET; +"SEPARATING_HYPERPLANE_CLOSED_COMPACT",SEPARATING_HYPERPLANE_CLOSED_COMPACT; +"SEPARATING_HYPERPLANE_CLOSED_POINT",SEPARATING_HYPERPLANE_CLOSED_POINT; +"SEPARATING_HYPERPLANE_CLOSED_POINT_INSET",SEPARATING_HYPERPLANE_CLOSED_POINT_INSET; +"SEPARATING_HYPERPLANE_COMPACT_CLOSED",SEPARATING_HYPERPLANE_COMPACT_CLOSED; +"SEPARATING_HYPERPLANE_COMPACT_CLOSED_NONZERO",SEPARATING_HYPERPLANE_COMPACT_CLOSED_NONZERO; +"SEPARATING_HYPERPLANE_COMPACT_COMPACT",SEPARATING_HYPERPLANE_COMPACT_COMPACT; +"SEPARATING_HYPERPLANE_POLYHEDRA",SEPARATING_HYPERPLANE_POLYHEDRA; +"SEPARATING_HYPERPLANE_RELATIVE_INTERIORS",SEPARATING_HYPERPLANE_RELATIVE_INTERIORS; +"SEPARATING_HYPERPLANE_SETS",SEPARATING_HYPERPLANE_SETS; +"SEPARATING_HYPERPLANE_SET_0",SEPARATING_HYPERPLANE_SET_0; +"SEPARATING_HYPERPLANE_SET_0_INSPAN",SEPARATING_HYPERPLANE_SET_0_INSPAN; +"SEPARATING_HYPERPLANE_SET_POINT_INAFF",SEPARATING_HYPERPLANE_SET_POINT_INAFF; +"SEPARATION_CLOSURES",SEPARATION_CLOSURES; +"SEPARATION_HAUSDORFF",SEPARATION_HAUSDORFF; +"SEPARATION_NORMAL",SEPARATION_NORMAL; +"SEPARATION_NORMAL_COMPACT",SEPARATION_NORMAL_COMPACT; +"SEPARATION_T0",SEPARATION_T0; +"SEPARATION_T1",SEPARATION_T1; +"SEPARATION_T2",SEPARATION_T2; +"SEQITERATE_CLAUSES",SEQITERATE_CLAUSES; +"SEQITERATE_ITERATE",SEQITERATE_ITERATE; +"SEQUENCE_CAUCHY_WLOG",SEQUENCE_CAUCHY_WLOG; +"SEQUENCE_INFINITE_LEMMA",SEQUENCE_INFINITE_LEMMA; +"SEQUENCE_UNIQUE_LIMPT",SEQUENCE_UNIQUE_LIMPT; +"SEQUENTIALLY",SEQUENTIALLY; +"SEQ_HARMONIC",SEQ_HARMONIC; +"SEQ_MONO_LEMMA",SEQ_MONO_LEMMA; +"SEQ_OFFSET",SEQ_OFFSET; +"SEQ_OFFSET_NEG",SEQ_OFFSET_NEG; +"SEQ_OFFSET_REV",SEQ_OFFSET_REV; +"SERIES_0",SERIES_0; +"SERIES_ADD",SERIES_ADD; +"SERIES_CAUCHY",SERIES_CAUCHY; +"SERIES_CAUCHY_UNIFORM",SERIES_CAUCHY_UNIFORM; +"SERIES_CMUL",SERIES_CMUL; +"SERIES_COMPARISON",SERIES_COMPARISON; +"SERIES_COMPARISON_UNIFORM",SERIES_COMPARISON_UNIFORM; +"SERIES_COMPONENT",SERIES_COMPONENT; +"SERIES_DIFFS",SERIES_DIFFS; +"SERIES_DIRICHLET",SERIES_DIRICHLET; +"SERIES_DIRICHLET_BILINEAR",SERIES_DIRICHLET_BILINEAR; +"SERIES_FINITE",SERIES_FINITE; +"SERIES_FINITE_SUPPORT",SERIES_FINITE_SUPPORT; +"SERIES_FROM",SERIES_FROM; +"SERIES_GOESTOZERO",SERIES_GOESTOZERO; +"SERIES_INJECTIVE_IMAGE",SERIES_INJECTIVE_IMAGE; +"SERIES_INJECTIVE_IMAGE_STRONG",SERIES_INJECTIVE_IMAGE_STRONG; +"SERIES_LIFT_ABSCONV_IMP_CONV",SERIES_LIFT_ABSCONV_IMP_CONV; +"SERIES_LINEAR",SERIES_LINEAR; +"SERIES_NEG",SERIES_NEG; +"SERIES_RATIO",SERIES_RATIO; +"SERIES_REARRANGE",SERIES_REARRANGE; +"SERIES_REARRANGE_EQ",SERIES_REARRANGE_EQ; +"SERIES_RESTRICT",SERIES_RESTRICT; +"SERIES_SUB",SERIES_SUB; +"SERIES_SUBSET",SERIES_SUBSET; +"SERIES_TRIVIAL",SERIES_TRIVIAL; +"SERIES_UNIQUE",SERIES_UNIQUE; +"SERIES_VSUM",SERIES_VSUM; +"SETCODE_BOUNDS",SETCODE_BOUNDS; +"SETDIST_CLOSED_COMPACT",SETDIST_CLOSED_COMPACT; +"SETDIST_CLOSEST_POINT",SETDIST_CLOSEST_POINT; +"SETDIST_CLOSURE",SETDIST_CLOSURE; +"SETDIST_COMPACT_CLOSED",SETDIST_COMPACT_CLOSED; +"SETDIST_DIFFERENCES",SETDIST_DIFFERENCES; +"SETDIST_EMPTY",SETDIST_EMPTY; +"SETDIST_EQ_0_BOUNDED",SETDIST_EQ_0_BOUNDED; +"SETDIST_EQ_0_CLOSED_COMPACT",SETDIST_EQ_0_CLOSED_COMPACT; +"SETDIST_EQ_0_COMPACT_CLOSED",SETDIST_EQ_0_COMPACT_CLOSED; +"SETDIST_EQ_0_SING",SETDIST_EQ_0_SING; +"SETDIST_LE_DIST",SETDIST_LE_DIST; +"SETDIST_LINEAR_IMAGE",SETDIST_LINEAR_IMAGE; +"SETDIST_LIPSCHITZ",SETDIST_LIPSCHITZ; +"SETDIST_POS_LE",SETDIST_POS_LE; +"SETDIST_REFL",SETDIST_REFL; +"SETDIST_SINGS",SETDIST_SINGS; +"SETDIST_SUBSET_LEFT",SETDIST_SUBSET_LEFT; +"SETDIST_SUBSET_RIGHT",SETDIST_SUBSET_RIGHT; +"SETDIST_SYM",SETDIST_SYM; +"SETDIST_TRANSLATION",SETDIST_TRANSLATION; +"SETDIST_TRIANGLE",SETDIST_TRIANGLE; +"SETDIST_UNIQUE",SETDIST_UNIQUE; +"SETSPEC",SETSPEC; +"SETVARIATION_EQUAL_LEMMA",SETVARIATION_EQUAL_LEMMA; +"SET_CASES",SET_CASES; +"SET_OF_LIST_APPEND",SET_OF_LIST_APPEND; +"SET_OF_LIST_EQ_EMPTY",SET_OF_LIST_EQ_EMPTY; +"SET_OF_LIST_MAP",SET_OF_LIST_MAP; +"SET_OF_LIST_OF_SET",SET_OF_LIST_OF_SET; +"SET_PAIR_THM",SET_PAIR_THM; +"SET_PROVE_CASES",SET_PROVE_CASES; +"SET_RECURSION_LEMMA",SET_RECURSION_LEMMA; +"SET_VARIATION",SET_VARIATION; +"SET_VARIATION_0",SET_VARIATION_0; +"SET_VARIATION_ELEMENTARY_LEMMA",SET_VARIATION_ELEMENTARY_LEMMA; +"SET_VARIATION_EQ",SET_VARIATION_EQ; +"SET_VARIATION_GE_FUNCTION",SET_VARIATION_GE_FUNCTION; +"SET_VARIATION_LBOUND",SET_VARIATION_LBOUND; +"SET_VARIATION_LBOUND_ON_INTERVAL",SET_VARIATION_LBOUND_ON_INTERVAL; +"SET_VARIATION_MONOTONE",SET_VARIATION_MONOTONE; +"SET_VARIATION_ON_DIVISION",SET_VARIATION_ON_DIVISION; +"SET_VARIATION_ON_ELEMENTARY",SET_VARIATION_ON_ELEMENTARY; +"SET_VARIATION_ON_INTERVAL",SET_VARIATION_ON_INTERVAL; +"SET_VARIATION_ON_NULL",SET_VARIATION_ON_NULL; +"SET_VARIATION_POS_LE",SET_VARIATION_POS_LE; +"SET_VARIATION_REFLECT2",SET_VARIATION_REFLECT2; +"SET_VARIATION_TRANSLATION2",SET_VARIATION_TRANSLATION2; +"SET_VARIATION_TRIANGLE",SET_VARIATION_TRIANGLE; +"SET_VARIATION_UBOUND",SET_VARIATION_UBOUND; +"SET_VARIATION_UBOUND_ON_INTERVAL",SET_VARIATION_UBOUND_ON_INTERVAL; +"SET_VARIATION_WORKS_ON_INTERVAL",SET_VARIATION_WORKS_ON_INTERVAL; +"SHIFTPATH_LINEAR_IMAGE",SHIFTPATH_LINEAR_IMAGE; +"SHIFTPATH_SHIFTPATH",SHIFTPATH_SHIFTPATH; +"SHIFTPATH_TRANSLATION",SHIFTPATH_TRANSLATION; +"SHIFTPATH_TRIVIAL",SHIFTPATH_TRIVIAL; +"SIGMA_COMPACT",SIGMA_COMPACT; +"SIGN_COMPOSE",SIGN_COMPOSE; +"SIGN_I",SIGN_I; +"SIGN_IDEMPOTENT",SIGN_IDEMPOTENT; +"SIGN_INVERSE",SIGN_INVERSE; +"SIGN_NZ",SIGN_NZ; +"SIGN_SWAP",SIGN_SWAP; +"SIMPLEX",SIMPLEX; +"SIMPLEX_DIM_GE",SIMPLEX_DIM_GE; +"SIMPLEX_EMPTY",SIMPLEX_EMPTY; +"SIMPLEX_EXPLICIT",SIMPLEX_EXPLICIT; +"SIMPLEX_EXTREMAL_LE",SIMPLEX_EXTREMAL_LE; +"SIMPLEX_EXTREMAL_LE_EXISTS",SIMPLEX_EXTREMAL_LE_EXISTS; +"SIMPLEX_EXTREME_POINTS",SIMPLEX_EXTREME_POINTS; +"SIMPLEX_FACE_OF_SIMPLEX",SIMPLEX_FACE_OF_SIMPLEX; +"SIMPLEX_FURTHEST_LE",SIMPLEX_FURTHEST_LE; +"SIMPLEX_FURTHEST_LE_EXISTS",SIMPLEX_FURTHEST_LE_EXISTS; +"SIMPLEX_FURTHEST_LT",SIMPLEX_FURTHEST_LT; +"SIMPLEX_IMP_POLYTOPE",SIMPLEX_IMP_POLYTOPE; +"SIMPLEX_MINUS_1",SIMPLEX_MINUS_1; +"SIMPLEX_TOP_FACE",SIMPLEX_TOP_FACE; +"SIMPLE_IMAGE",SIMPLE_IMAGE; +"SIMPLE_IMAGE_GEN",SIMPLE_IMAGE_GEN; +"SIMPLE_PATH_ASSOC",SIMPLE_PATH_ASSOC; +"SIMPLE_PATH_CASES",SIMPLE_PATH_CASES; +"SIMPLE_PATH_ENDLESS",SIMPLE_PATH_ENDLESS; +"SIMPLE_PATH_EQ_ARC",SIMPLE_PATH_EQ_ARC; +"SIMPLE_PATH_IMP_ARC",SIMPLE_PATH_IMP_ARC; +"SIMPLE_PATH_IMP_PATH",SIMPLE_PATH_IMP_PATH; +"SIMPLE_PATH_JOIN_IMP",SIMPLE_PATH_JOIN_IMP; +"SIMPLE_PATH_JOIN_LOOP",SIMPLE_PATH_JOIN_LOOP; +"SIMPLE_PATH_JOIN_LOOP_EQ",SIMPLE_PATH_JOIN_LOOP_EQ; +"SIMPLE_PATH_LINEAR_IMAGE_EQ",SIMPLE_PATH_LINEAR_IMAGE_EQ; +"SIMPLE_PATH_LINEPATH",SIMPLE_PATH_LINEPATH; +"SIMPLE_PATH_LINEPATH_EQ",SIMPLE_PATH_LINEPATH_EQ; +"SIMPLE_PATH_REVERSEPATH",SIMPLE_PATH_REVERSEPATH; +"SIMPLE_PATH_SHIFTPATH",SIMPLE_PATH_SHIFTPATH; +"SIMPLE_PATH_SUBPATH",SIMPLE_PATH_SUBPATH; +"SIMPLE_PATH_SUBPATH_EQ",SIMPLE_PATH_SUBPATH_EQ; +"SIMPLE_PATH_SYM",SIMPLE_PATH_SYM; +"SIMPLE_PATH_TRANSLATION_EQ",SIMPLE_PATH_TRANSLATION_EQ; +"SIMPLICIAL_COMPLEX_IMP_TRIANGULATION",SIMPLICIAL_COMPLEX_IMP_TRIANGULATION; +"SIMPLY_CONNECTED_EMPTY",SIMPLY_CONNECTED_EMPTY; +"SIMPLY_CONNECTED_EQ_CONTRACTIBLE_LOOP_ALL",SIMPLY_CONNECTED_EQ_CONTRACTIBLE_LOOP_ALL; +"SIMPLY_CONNECTED_EQ_CONTRACTIBLE_LOOP_ANY",SIMPLY_CONNECTED_EQ_CONTRACTIBLE_LOOP_ANY; +"SIMPLY_CONNECTED_EQ_CONTRACTIBLE_LOOP_SOME",SIMPLY_CONNECTED_EQ_CONTRACTIBLE_LOOP_SOME; +"SIMPLY_CONNECTED_EQ_CONTRACTIBLE_PATH",SIMPLY_CONNECTED_EQ_CONTRACTIBLE_PATH; +"SIMPLY_CONNECTED_EQ_HOMOTOPIC_PATHS",SIMPLY_CONNECTED_EQ_HOMOTOPIC_PATHS; +"SIMPLY_CONNECTED_IMP_CONNECTED",SIMPLY_CONNECTED_IMP_CONNECTED; +"SIMPLY_CONNECTED_IMP_PATH_CONNECTED",SIMPLY_CONNECTED_IMP_PATH_CONNECTED; +"SIMPLY_CONNECTED_INJECTIVE_LINEAR_IMAGE",SIMPLY_CONNECTED_INJECTIVE_LINEAR_IMAGE; +"SIMPLY_CONNECTED_PCROSS",SIMPLY_CONNECTED_PCROSS; +"SIMPLY_CONNECTED_PCROSS_EQ",SIMPLY_CONNECTED_PCROSS_EQ; +"SIMPLY_CONNECTED_RETRACTION_GEN",SIMPLY_CONNECTED_RETRACTION_GEN; +"SIMPLY_CONNECTED_SPHERE",SIMPLY_CONNECTED_SPHERE; +"SIMPLY_CONNECTED_TRANSLATION",SIMPLY_CONNECTED_TRANSLATION; +"SIMPLY_CONNECTED_UNION",SIMPLY_CONNECTED_UNION; +"SING",SING; +"SING_GSPEC",SING_GSPEC; +"SING_SUBSET",SING_SUBSET; +"SKOLEM_THM",SKOLEM_THM; +"SND",SND; +"SNDCART_ADD",SNDCART_ADD; +"SNDCART_CMUL",SNDCART_CMUL; +"SNDCART_NEG",SNDCART_NEG; +"SNDCART_PASTECART",SNDCART_PASTECART; +"SNDCART_SUB",SNDCART_SUB; +"SNDCART_VEC",SNDCART_VEC; +"SNDCART_VSUM",SNDCART_VSUM; +"SND_DEF",SND_DEF; +"SPANNING_SUBSET_INDEPENDENT",SPANNING_SUBSET_INDEPENDENT; +"SPANNING_SURJECTIVE_IMAGE",SPANNING_SURJECTIVE_IMAGE; +"SPANS_IMAGE",SPANS_IMAGE; +"SPAN_0",SPAN_0; +"SPAN_2",SPAN_2; +"SPAN_3",SPAN_3; +"SPAN_ADD",SPAN_ADD; +"SPAN_ADD_EQ",SPAN_ADD_EQ; +"SPAN_BREAKDOWN",SPAN_BREAKDOWN; +"SPAN_BREAKDOWN_EQ",SPAN_BREAKDOWN_EQ; +"SPAN_CARD_GE_DIM",SPAN_CARD_GE_DIM; +"SPAN_CLAUSES",SPAN_CLAUSES; +"SPAN_CONVEX_CONE_ALLSIGNS",SPAN_CONVEX_CONE_ALLSIGNS; +"SPAN_DELETE_0",SPAN_DELETE_0; +"SPAN_EMPTY",SPAN_EMPTY; +"SPAN_EQ",SPAN_EQ; +"SPAN_EQ_DIM",SPAN_EQ_DIM; +"SPAN_EQ_INSERT",SPAN_EQ_INSERT; +"SPAN_EQ_SELF",SPAN_EQ_SELF; +"SPAN_EXPLICIT",SPAN_EXPLICIT; +"SPAN_FINITE",SPAN_FINITE; +"SPAN_IMAGE_SCALE",SPAN_IMAGE_SCALE; +"SPAN_INC",SPAN_INC; +"SPAN_INDUCT",SPAN_INDUCT; +"SPAN_INDUCT_ALT",SPAN_INDUCT_ALT; +"SPAN_INSERT_0",SPAN_INSERT_0; +"SPAN_LINEAR_IMAGE",SPAN_LINEAR_IMAGE; +"SPAN_MBASIS",SPAN_MBASIS; +"SPAN_MONO",SPAN_MONO; +"SPAN_MUL",SPAN_MUL; +"SPAN_MUL_EQ",SPAN_MUL_EQ; +"SPAN_NEG",SPAN_NEG; +"SPAN_NEG_EQ",SPAN_NEG_EQ; +"SPAN_NOT_UNIV_ORTHOGONAL",SPAN_NOT_UNIV_ORTHOGONAL; +"SPAN_NOT_UNIV_SUBSET_HYPERPLANE",SPAN_NOT_UNIV_SUBSET_HYPERPLANE; +"SPAN_OF_SUBSPACE",SPAN_OF_SUBSPACE; +"SPAN_OPEN",SPAN_OPEN; +"SPAN_PCROSS",SPAN_PCROSS; +"SPAN_PCROSS_SUBSET",SPAN_PCROSS_SUBSET; +"SPAN_SING",SPAN_SING; +"SPAN_SPAN",SPAN_SPAN; +"SPAN_STDBASIS",SPAN_STDBASIS; +"SPAN_SUB",SPAN_SUB; +"SPAN_SUBSET_SUBSPACE",SPAN_SUBSET_SUBSPACE; +"SPAN_SUBSPACE",SPAN_SUBSPACE; +"SPAN_SUMS",SPAN_SUMS; +"SPAN_SUPERSET",SPAN_SUPERSET; +"SPAN_TRANS",SPAN_TRANS; +"SPAN_UNION",SPAN_UNION; +"SPAN_UNION_SUBSET",SPAN_UNION_SUBSET; +"SPAN_UNIV",SPAN_UNIV; +"SPAN_VSUM",SPAN_VSUM; +"SPECIAL_HYPERPLANE_SPAN",SPECIAL_HYPERPLANE_SPAN; +"SPHERE_1",SPHERE_1; +"SPHERE_EMPTY",SPHERE_EMPTY; +"SPHERE_EQ_EMPTY",SPHERE_EQ_EMPTY; +"SPHERE_EQ_SING",SPHERE_EQ_SING; +"SPHERE_LINEAR_IMAGE",SPHERE_LINEAR_IMAGE; +"SPHERE_RETRACT_OF_PUNCTURED_UNIVERSE",SPHERE_RETRACT_OF_PUNCTURED_UNIVERSE; +"SPHERE_RETRACT_OF_PUNCTURED_UNIVERSE_GEN",SPHERE_RETRACT_OF_PUNCTURED_UNIVERSE_GEN; +"SPHERE_SING",SPHERE_SING; +"SPHERE_SUBSET_CBALL",SPHERE_SUBSET_CBALL; +"SPHERE_TRANSLATION",SPHERE_TRANSLATION; +"SPHERE_UNION_BALL",SPHERE_UNION_BALL; +"SPLIT_INSIDE_SIMPLE_CLOSED_CURVE",SPLIT_INSIDE_SIMPLE_CLOSED_CURVE; +"SQNORM_PASTECART",SQNORM_PASTECART; +"SQRT_0",SQRT_0; +"SQRT_1",SQRT_1; +"SQRT_DIV",SQRT_DIV; +"SQRT_EQ_0",SQRT_EQ_0; +"SQRT_EVEN_POW2",SQRT_EVEN_POW2; +"SQRT_INJ",SQRT_INJ; +"SQRT_INV",SQRT_INV; +"SQRT_LT_0",SQRT_LT_0; +"SQRT_MONO_LE",SQRT_MONO_LE; +"SQRT_MONO_LE_EQ",SQRT_MONO_LE_EQ; +"SQRT_MONO_LT",SQRT_MONO_LT; +"SQRT_MONO_LT_EQ",SQRT_MONO_LT_EQ; +"SQRT_MUL",SQRT_MUL; +"SQRT_POS_LE",SQRT_POS_LE; +"SQRT_POS_LT",SQRT_POS_LT; +"SQRT_POW2",SQRT_POW2; +"SQRT_POW_2",SQRT_POW_2; +"SQRT_UNIQUE",SQRT_UNIQUE; +"SQRT_WORKS",SQRT_WORKS; +"SQUARE_BOUND_LEMMA",SQUARE_BOUND_LEMMA; +"SQUARE_CONTINUOUS",SQUARE_CONTINUOUS; +"STARLIKE_CLOSURE",STARLIKE_CLOSURE; +"STARLIKE_COMPACT_PROJECTIVE",STARLIKE_COMPACT_PROJECTIVE; +"STARLIKE_CONVEX_TWEAK_BOUNDARY_POINTS",STARLIKE_CONVEX_TWEAK_BOUNDARY_POINTS; +"STARLIKE_IMP_CONNECTED",STARLIKE_IMP_CONNECTED; +"STARLIKE_IMP_CONTRACTIBLE",STARLIKE_IMP_CONTRACTIBLE; +"STARLIKE_IMP_CONTRACTIBLE_GEN",STARLIKE_IMP_CONTRACTIBLE_GEN; +"STARLIKE_IMP_PATH_CONNECTED",STARLIKE_IMP_PATH_CONNECTED; +"STARLIKE_IMP_SIMPLY_CONNECTED",STARLIKE_IMP_SIMPLY_CONNECTED; +"STARLIKE_LINEAR_IMAGE",STARLIKE_LINEAR_IMAGE; +"STARLIKE_LINEAR_IMAGE_EQ",STARLIKE_LINEAR_IMAGE_EQ; +"STARLIKE_NEGLIGIBLE",STARLIKE_NEGLIGIBLE; +"STARLIKE_NEGLIGIBLE_BOUNDED_MEASURABLE",STARLIKE_NEGLIGIBLE_BOUNDED_MEASURABLE; +"STARLIKE_NEGLIGIBLE_LEMMA",STARLIKE_NEGLIGIBLE_LEMMA; +"STARLIKE_NEGLIGIBLE_STRONG",STARLIKE_NEGLIGIBLE_STRONG; +"STARLIKE_PCROSS",STARLIKE_PCROSS; +"STARLIKE_PCROSS_EQ",STARLIKE_PCROSS_EQ; +"STARLIKE_TRANSLATION_EQ",STARLIKE_TRANSLATION_EQ; +"STARLIKE_UNIV",STARLIKE_UNIV; +"STD_SIMPLEX",STD_SIMPLEX; +"STEINHAUS",STEINHAUS; +"STEINHAUS_LEBESGUE",STEINHAUS_LEBESGUE; +"STRETCH_GALOIS",STRETCH_GALOIS; +"SUB",SUB; +"SUBADDITIVE_CONTENT_DIVISION",SUBADDITIVE_CONTENT_DIVISION; +"SUBPATH_LINEAR_IMAGE",SUBPATH_LINEAR_IMAGE; +"SUBPATH_REFL",SUBPATH_REFL; +"SUBPATH_REVERSEPATH",SUBPATH_REVERSEPATH; +"SUBPATH_SCALING_LEMMA",SUBPATH_SCALING_LEMMA; +"SUBPATH_TO_FRONTIER",SUBPATH_TO_FRONTIER; +"SUBPATH_TO_FRONTIER_EXPLICIT",SUBPATH_TO_FRONTIER_EXPLICIT; +"SUBPATH_TO_FRONTIER_STRONG",SUBPATH_TO_FRONTIER_STRONG; +"SUBPATH_TRANSLATION",SUBPATH_TRANSLATION; +"SUBPATH_TRIVIAL",SUBPATH_TRIVIAL; +"SUBSEQUENCE_DIAGONALIZATION_LEMMA",SUBSEQUENCE_DIAGONALIZATION_LEMMA; +"SUBSET",SUBSET; +"SUBSET_ANTISYM",SUBSET_ANTISYM; +"SUBSET_ANTISYM_EQ",SUBSET_ANTISYM_EQ; +"SUBSET_BALL",SUBSET_BALL; +"SUBSET_BALLS",SUBSET_BALLS; +"SUBSET_CARD_EQ",SUBSET_CARD_EQ; +"SUBSET_CBALL",SUBSET_CBALL; +"SUBSET_CLOSURE",SUBSET_CLOSURE; +"SUBSET_CONTINUOUS_IMAGE_SEGMENT_1",SUBSET_CONTINUOUS_IMAGE_SEGMENT_1; +"SUBSET_DELETE",SUBSET_DELETE; +"SUBSET_DIFF",SUBSET_DIFF; +"SUBSET_DROP_IMAGE",SUBSET_DROP_IMAGE; +"SUBSET_EMPTY",SUBSET_EMPTY; +"SUBSET_FACE_OF_SIMPLEX",SUBSET_FACE_OF_SIMPLEX; +"SUBSET_HULL",SUBSET_HULL; +"SUBSET_HYPERPLANES",SUBSET_HYPERPLANES; +"SUBSET_IMAGE",SUBSET_IMAGE; +"SUBSET_INSERT",SUBSET_INSERT; +"SUBSET_INSERT_DELETE",SUBSET_INSERT_DELETE; +"SUBSET_INTER",SUBSET_INTER; +"SUBSET_INTERIOR",SUBSET_INTERIOR; +"SUBSET_INTERS",SUBSET_INTERS; +"SUBSET_INTERVAL",SUBSET_INTERVAL; +"SUBSET_INTERVAL_1",SUBSET_INTERVAL_1; +"SUBSET_INTERVAL_IMP",SUBSET_INTERVAL_IMP; +"SUBSET_INTER_ABSORPTION",SUBSET_INTER_ABSORPTION; +"SUBSET_LE_DIM",SUBSET_LE_DIM; +"SUBSET_LIFT_IMAGE",SUBSET_LIFT_IMAGE; +"SUBSET_NUMSEG",SUBSET_NUMSEG; +"SUBSET_OF_FACE_OF",SUBSET_OF_FACE_OF; +"SUBSET_PATH_IMAGE_JOIN",SUBSET_PATH_IMAGE_JOIN; +"SUBSET_PCROSS",SUBSET_PCROSS; +"SUBSET_PRED",SUBSET_PRED; +"SUBSET_PSUBSET_TRANS",SUBSET_PSUBSET_TRANS; +"SUBSET_REFL",SUBSET_REFL; +"SUBSET_RELATIVE_INTERIOR",SUBSET_RELATIVE_INTERIOR; +"SUBSET_RESTRICT",SUBSET_RESTRICT; +"SUBSET_SECOND_COUNTABLE",SUBSET_SECOND_COUNTABLE; +"SUBSET_SEGMENT",SUBSET_SEGMENT; +"SUBSET_SEGMENT_OPEN_CLOSED",SUBSET_SEGMENT_OPEN_CLOSED; +"SUBSET_TRANS",SUBSET_TRANS; +"SUBSET_UNION",SUBSET_UNION; +"SUBSET_UNIONS",SUBSET_UNIONS; +"SUBSET_UNION_ABSORPTION",SUBSET_UNION_ABSORPTION; +"SUBSET_UNIV",SUBSET_UNIV; +"SUBSPACE_0",SUBSPACE_0; +"SUBSPACE_ADD",SUBSPACE_ADD; +"SUBSPACE_BOUNDED_EQ_TRIVIAL",SUBSPACE_BOUNDED_EQ_TRIVIAL; +"SUBSPACE_CONVEX_CONE_SYMMETRIC",SUBSPACE_CONVEX_CONE_SYMMETRIC; +"SUBSPACE_HYPERPLANE",SUBSPACE_HYPERPLANE; +"SUBSPACE_IMP_AFFINE",SUBSPACE_IMP_AFFINE; +"SUBSPACE_IMP_CONIC",SUBSPACE_IMP_CONIC; +"SUBSPACE_IMP_CONVEX",SUBSPACE_IMP_CONVEX; +"SUBSPACE_IMP_CONVEX_CONE",SUBSPACE_IMP_CONVEX_CONE; +"SUBSPACE_IMP_NONEMPTY",SUBSPACE_IMP_NONEMPTY; +"SUBSPACE_INTER",SUBSPACE_INTER; +"SUBSPACE_INTERS",SUBSPACE_INTERS; +"SUBSPACE_ISOMORPHISM",SUBSPACE_ISOMORPHISM; +"SUBSPACE_KERNEL",SUBSPACE_KERNEL; +"SUBSPACE_LINEAR_FIXED_POINTS",SUBSPACE_LINEAR_FIXED_POINTS; +"SUBSPACE_LINEAR_IMAGE",SUBSPACE_LINEAR_IMAGE; +"SUBSPACE_LINEAR_IMAGE_EQ",SUBSPACE_LINEAR_IMAGE_EQ; +"SUBSPACE_LINEAR_PREIMAGE",SUBSPACE_LINEAR_PREIMAGE; +"SUBSPACE_MUL",SUBSPACE_MUL; +"SUBSPACE_NEG",SUBSPACE_NEG; +"SUBSPACE_ORTHOGONAL_TO_VECTOR",SUBSPACE_ORTHOGONAL_TO_VECTOR; +"SUBSPACE_ORTHOGONAL_TO_VECTORS",SUBSPACE_ORTHOGONAL_TO_VECTORS; +"SUBSPACE_PCROSS",SUBSPACE_PCROSS; +"SUBSPACE_PCROSS_EQ",SUBSPACE_PCROSS_EQ; +"SUBSPACE_SPAN",SUBSPACE_SPAN; +"SUBSPACE_SPECIAL_HYPERPLANE",SUBSPACE_SPECIAL_HYPERPLANE; +"SUBSPACE_SUB",SUBSPACE_SUB; +"SUBSPACE_SUBSTANDARD",SUBSPACE_SUBSTANDARD; +"SUBSPACE_SUMS",SUBSPACE_SUMS; +"SUBSPACE_TRANSLATION_SELF",SUBSPACE_TRANSLATION_SELF; +"SUBSPACE_TRANSLATION_SELF_EQ",SUBSPACE_TRANSLATION_SELF_EQ; +"SUBSPACE_TRIVIAL",SUBSPACE_TRIVIAL; +"SUBSPACE_UNION_CHAIN",SUBSPACE_UNION_CHAIN; +"SUBSPACE_UNIV",SUBSPACE_UNIV; +"SUBSPACE_VSUM",SUBSPACE_VSUM; +"SUBTOPOLOGY_SUPERSET",SUBTOPOLOGY_SUPERSET; +"SUBTOPOLOGY_TOPSPACE",SUBTOPOLOGY_TOPSPACE; +"SUBTOPOLOGY_UNIV",SUBTOPOLOGY_UNIV; +"SUB_0",SUB_0; +"SUB_ADD",SUB_ADD; +"SUB_ADD_LCANCEL",SUB_ADD_LCANCEL; +"SUB_ADD_RCANCEL",SUB_ADD_RCANCEL; +"SUB_ELIM_THM",SUB_ELIM_THM; +"SUB_ELIM_THM'",SUB_ELIM_THM'; +"SUB_EQ_0",SUB_EQ_0; +"SUB_PRESUC",SUB_PRESUC; +"SUB_REFL",SUB_REFL; +"SUB_SUC",SUB_SUC; +"SUC_DEF",SUC_DEF; +"SUC_INJ",SUC_INJ; +"SUC_SUB1",SUC_SUB1; +"SUMMABLE_0",SUMMABLE_0; +"SUMMABLE_ADD",SUMMABLE_ADD; +"SUMMABLE_BILINEAR_PARTIAL_PRE",SUMMABLE_BILINEAR_PARTIAL_PRE; +"SUMMABLE_CAUCHY",SUMMABLE_CAUCHY; +"SUMMABLE_CMUL",SUMMABLE_CMUL; +"SUMMABLE_COMPARISON",SUMMABLE_COMPARISON; +"SUMMABLE_COMPONENT",SUMMABLE_COMPONENT; +"SUMMABLE_EQ",SUMMABLE_EQ; +"SUMMABLE_EQ_COFINITE",SUMMABLE_EQ_COFINITE; +"SUMMABLE_EQ_EVENTUALLY",SUMMABLE_EQ_EVENTUALLY; +"SUMMABLE_FROM_ELSEWHERE",SUMMABLE_FROM_ELSEWHERE; +"SUMMABLE_IFF",SUMMABLE_IFF; +"SUMMABLE_IFF_COFINITE",SUMMABLE_IFF_COFINITE; +"SUMMABLE_IFF_EVENTUALLY",SUMMABLE_IFF_EVENTUALLY; +"SUMMABLE_IMP_BOUNDED",SUMMABLE_IMP_BOUNDED; +"SUMMABLE_IMP_SUMS_BOUNDED",SUMMABLE_IMP_SUMS_BOUNDED; +"SUMMABLE_IMP_TOZERO",SUMMABLE_IMP_TOZERO; +"SUMMABLE_LINEAR",SUMMABLE_LINEAR; +"SUMMABLE_NEG",SUMMABLE_NEG; +"SUMMABLE_REARRANGE",SUMMABLE_REARRANGE; +"SUMMABLE_REINDEX",SUMMABLE_REINDEX; +"SUMMABLE_RESTRICT",SUMMABLE_RESTRICT; +"SUMMABLE_SUB",SUMMABLE_SUB; +"SUMMABLE_SUBSET",SUMMABLE_SUBSET; +"SUMMABLE_SUBSET_ABSCONV",SUMMABLE_SUBSET_ABSCONV; +"SUMMABLE_TRIVIAL",SUMMABLE_TRIVIAL; +"SUMS_0",SUMS_0; +"SUMS_EQ",SUMS_EQ; +"SUMS_FINITE_DIFF",SUMS_FINITE_DIFF; +"SUMS_FINITE_UNION",SUMS_FINITE_UNION; +"SUMS_IFF",SUMS_IFF; +"SUMS_INFSUM",SUMS_INFSUM; +"SUMS_INTERVALS",SUMS_INTERVALS; +"SUMS_LIM",SUMS_LIM; +"SUMS_OFFSET",SUMS_OFFSET; +"SUMS_OFFSET_REV",SUMS_OFFSET_REV; +"SUMS_REINDEX",SUMS_REINDEX; +"SUMS_SUMMABLE",SUMS_SUMMABLE; +"SUM_0",SUM_0; +"SUM_1",SUM_1; +"SUM_2",SUM_2; +"SUM_3",SUM_3; +"SUM_4",SUM_4; +"SUM_ABS",SUM_ABS; +"SUM_ABS_BOUND",SUM_ABS_BOUND; +"SUM_ABS_LE",SUM_ABS_LE; +"SUM_ABS_NUMSEG",SUM_ABS_NUMSEG; +"SUM_ADD",SUM_ADD; +"SUM_ADD_GEN",SUM_ADD_GEN; +"SUM_ADD_NUMSEG",SUM_ADD_NUMSEG; +"SUM_ADD_SPLIT",SUM_ADD_SPLIT; +"SUM_BIJECTION",SUM_BIJECTION; +"SUM_BOUND",SUM_BOUND; +"SUM_BOUND_GEN",SUM_BOUND_GEN; +"SUM_BOUND_LT",SUM_BOUND_LT; +"SUM_BOUND_LT_ALL",SUM_BOUND_LT_ALL; +"SUM_BOUND_LT_GEN",SUM_BOUND_LT_GEN; +"SUM_CASES",SUM_CASES; +"SUM_CASES_1",SUM_CASES_1; +"SUM_CLAUSES",SUM_CLAUSES; +"SUM_CLAUSES_LEFT",SUM_CLAUSES_LEFT; +"SUM_CLAUSES_NUMSEG",SUM_CLAUSES_NUMSEG; +"SUM_CLAUSES_RIGHT",SUM_CLAUSES_RIGHT; +"SUM_CLOSED",SUM_CLOSED; +"SUM_COMBINE_L",SUM_COMBINE_L; +"SUM_COMBINE_R",SUM_COMBINE_R; +"SUM_CONST",SUM_CONST; +"SUM_CONST_NUMSEG",SUM_CONST_NUMSEG; +"SUM_CONTENT_AREA_OVER_THIN_DIVISION",SUM_CONTENT_AREA_OVER_THIN_DIVISION; +"SUM_DELETE",SUM_DELETE; +"SUM_DELETE_CASES",SUM_DELETE_CASES; +"SUM_DELTA",SUM_DELTA; +"SUM_DIFF",SUM_DIFF; +"SUM_DIFFS",SUM_DIFFS; +"SUM_DIFFS_ALT",SUM_DIFFS_ALT; +"SUM_EQ",SUM_EQ; +"SUM_EQ_0",SUM_EQ_0; +"SUM_EQ_0_NUMSEG",SUM_EQ_0_NUMSEG; +"SUM_EQ_GENERAL",SUM_EQ_GENERAL; +"SUM_EQ_GENERAL_INVERSES",SUM_EQ_GENERAL_INVERSES; +"SUM_EQ_NUMSEG",SUM_EQ_NUMSEG; +"SUM_EQ_SUPERSET",SUM_EQ_SUPERSET; +"SUM_GP",SUM_GP; +"SUM_GP_BASIC",SUM_GP_BASIC; +"SUM_GP_MULTIPLIED",SUM_GP_MULTIPLIED; +"SUM_GP_OFFSET",SUM_GP_OFFSET; +"SUM_GROUP",SUM_GROUP; +"SUM_IMAGE",SUM_IMAGE; +"SUM_IMAGE_GEN",SUM_IMAGE_GEN; +"SUM_IMAGE_LE",SUM_IMAGE_LE; +"SUM_IMAGE_NONZERO",SUM_IMAGE_NONZERO; +"SUM_INCL_EXCL",SUM_INCL_EXCL; +"SUM_INJECTION",SUM_INJECTION; +"SUM_LE",SUM_LE; +"SUM_LE_INCLUDED",SUM_LE_INCLUDED; +"SUM_LE_NUMSEG",SUM_LE_NUMSEG; +"SUM_LMUL",SUM_LMUL; +"SUM_LT",SUM_LT; +"SUM_LT_ALL",SUM_LT_ALL; +"SUM_MULTICOUNT",SUM_MULTICOUNT; +"SUM_MULTICOUNT_GEN",SUM_MULTICOUNT_GEN; +"SUM_NEG",SUM_NEG; +"SUM_OFFSET",SUM_OFFSET; +"SUM_OFFSET_0",SUM_OFFSET_0; +"SUM_OVER_PERMUTATIONS_INSERT",SUM_OVER_PERMUTATIONS_INSERT; +"SUM_OVER_PERMUTATIONS_NUMSEG",SUM_OVER_PERMUTATIONS_NUMSEG; +"SUM_OVER_TAGGED_DIVISION_LEMMA",SUM_OVER_TAGGED_DIVISION_LEMMA; +"SUM_OVER_TAGGED_PARTIAL_DIVISION_LEMMA",SUM_OVER_TAGGED_PARTIAL_DIVISION_LEMMA; +"SUM_PAIR",SUM_PAIR; +"SUM_PARTIAL_PRE",SUM_PARTIAL_PRE; +"SUM_PARTIAL_SUC",SUM_PARTIAL_SUC; +"SUM_PERMUTATIONS_COMPOSE_L",SUM_PERMUTATIONS_COMPOSE_L; +"SUM_PERMUTATIONS_COMPOSE_R",SUM_PERMUTATIONS_COMPOSE_R; +"SUM_PERMUTATIONS_INVERSE",SUM_PERMUTATIONS_INVERSE; +"SUM_PERMUTE",SUM_PERMUTE; +"SUM_PERMUTE_NUMSEG",SUM_PERMUTE_NUMSEG; +"SUM_POS_BOUND",SUM_POS_BOUND; +"SUM_POS_EQ_0",SUM_POS_EQ_0; +"SUM_POS_EQ_0_NUMSEG",SUM_POS_EQ_0_NUMSEG; +"SUM_POS_LE",SUM_POS_LE; +"SUM_POS_LE_NUMSEG",SUM_POS_LE_NUMSEG; +"SUM_POS_LT",SUM_POS_LT; +"SUM_RESTRICT",SUM_RESTRICT; +"SUM_RESTRICT_SET",SUM_RESTRICT_SET; +"SUM_RMUL",SUM_RMUL; +"SUM_SING",SUM_SING; +"SUM_SING_NUMSEG",SUM_SING_NUMSEG; +"SUM_SUB",SUM_SUB; +"SUM_SUBSET",SUM_SUBSET; +"SUM_SUBSET_SIMPLE",SUM_SUBSET_SIMPLE; +"SUM_SUB_NUMSEG",SUM_SUB_NUMSEG; +"SUM_SUM_PRODUCT",SUM_SUM_PRODUCT; +"SUM_SUM_RESTRICT",SUM_SUM_RESTRICT; +"SUM_SUPERSET",SUM_SUPERSET; +"SUM_SUPPORT",SUM_SUPPORT; +"SUM_SWAP",SUM_SWAP; +"SUM_SWAP_NUMSEG",SUM_SWAP_NUMSEG; +"SUM_TRIV_NUMSEG",SUM_TRIV_NUMSEG; +"SUM_UNION",SUM_UNION; +"SUM_UNIONS_NONZERO",SUM_UNIONS_NONZERO; +"SUM_UNION_EQ",SUM_UNION_EQ; +"SUM_UNION_LZERO",SUM_UNION_LZERO; +"SUM_UNION_NONZERO",SUM_UNION_NONZERO; +"SUM_UNION_RZERO",SUM_UNION_RZERO; +"SUM_VSUM",SUM_VSUM; +"SUM_ZERO_EXISTS",SUM_ZERO_EXISTS; +"SUP",SUP; +"SUPERADMISSIBLE_COND",SUPERADMISSIBLE_COND; +"SUPERADMISSIBLE_CONST",SUPERADMISSIBLE_CONST; +"SUPERADMISSIBLE_MATCH_GUARDED_PATTERN",SUPERADMISSIBLE_MATCH_GUARDED_PATTERN; +"SUPERADMISSIBLE_MATCH_SEQPATTERN",SUPERADMISSIBLE_MATCH_SEQPATTERN; +"SUPERADMISSIBLE_MATCH_UNGUARDED_PATTERN",SUPERADMISSIBLE_MATCH_UNGUARDED_PATTERN; +"SUPERADMISSIBLE_T",SUPERADMISSIBLE_T; +"SUPERADMISSIBLE_TAIL",SUPERADMISSIBLE_TAIL; +"SUPPORTING_HYPERPLANE_CLOSED_POINT",SUPPORTING_HYPERPLANE_CLOSED_POINT; +"SUPPORTING_HYPERPLANE_COMPACT_POINT_INF",SUPPORTING_HYPERPLANE_COMPACT_POINT_INF; +"SUPPORTING_HYPERPLANE_COMPACT_POINT_SUP",SUPPORTING_HYPERPLANE_COMPACT_POINT_SUP; +"SUPPORTING_HYPERPLANE_RELATIVE_BOUNDARY",SUPPORTING_HYPERPLANE_RELATIVE_BOUNDARY; +"SUPPORTING_HYPERPLANE_RELATIVE_FRONTIER",SUPPORTING_HYPERPLANE_RELATIVE_FRONTIER; +"SUPPORT_CLAUSES",SUPPORT_CLAUSES; +"SUPPORT_DELTA",SUPPORT_DELTA; +"SUPPORT_EMPTY",SUPPORT_EMPTY; +"SUPPORT_SUBSET",SUPPORT_SUBSET; +"SUPPORT_SUPPORT",SUPPORT_SUPPORT; +"SUP_EQ",SUP_EQ; +"SUP_FINITE",SUP_FINITE; +"SUP_FINITE_LEMMA",SUP_FINITE_LEMMA; +"SUP_INSERT",SUP_INSERT; +"SUP_INSERT_FINITE",SUP_INSERT_FINITE; +"SUP_SING",SUP_SING; +"SUP_UNIQUE_FINITE",SUP_UNIQUE_FINITE; +"SURA_BURA_CLOSED",SURA_BURA_CLOSED; +"SURA_BURA_COMPACT",SURA_BURA_COMPACT; +"SURJ",SURJ; +"SURJECTIVE_EXISTS_THM",SURJECTIVE_EXISTS_THM; +"SURJECTIVE_FORALL_THM",SURJECTIVE_FORALL_THM; +"SURJECTIVE_IFF_INJECTIVE",SURJECTIVE_IFF_INJECTIVE; +"SURJECTIVE_IFF_INJECTIVE_GEN",SURJECTIVE_IFF_INJECTIVE_GEN; +"SURJECTIVE_IMAGE",SURJECTIVE_IMAGE; +"SURJECTIVE_IMAGE_EQ",SURJECTIVE_IMAGE_EQ; +"SURJECTIVE_IMAGE_THM",SURJECTIVE_IMAGE_THM; +"SURJECTIVE_INVERSE",SURJECTIVE_INVERSE; +"SURJECTIVE_INVERSE_o",SURJECTIVE_INVERSE_o; +"SURJECTIVE_MAP",SURJECTIVE_MAP; +"SURJECTIVE_ON_IMAGE",SURJECTIVE_ON_IMAGE; +"SURJECTIVE_ON_RIGHT_INVERSE",SURJECTIVE_ON_RIGHT_INVERSE; +"SURJECTIVE_RIGHT_INVERSE",SURJECTIVE_RIGHT_INVERSE; +"SURJECTIVE_SCALING",SURJECTIVE_SCALING; +"SUSSMANN_OPEN_MAPPING",SUSSMANN_OPEN_MAPPING; +"SWAPSEQ_COMPOSE",SWAPSEQ_COMPOSE; +"SWAPSEQ_ENDSWAP",SWAPSEQ_ENDSWAP; +"SWAPSEQ_EVEN_EVEN",SWAPSEQ_EVEN_EVEN; +"SWAPSEQ_I",SWAPSEQ_I; +"SWAPSEQ_IDENTITY_EVEN",SWAPSEQ_IDENTITY_EVEN; +"SWAPSEQ_INVERSE",SWAPSEQ_INVERSE; +"SWAPSEQ_INVERSE_EXISTS",SWAPSEQ_INVERSE_EXISTS; +"SWAPSEQ_SWAP",SWAPSEQ_SWAP; +"SWAP_COMMON",SWAP_COMMON; +"SWAP_COMMON'",SWAP_COMMON'; +"SWAP_EXISTS_THM",SWAP_EXISTS_THM; +"SWAP_FORALL_THM",SWAP_FORALL_THM; +"SWAP_GALOIS",SWAP_GALOIS; +"SWAP_GENERAL",SWAP_GENERAL; +"SWAP_IDEMPOTENT",SWAP_IDEMPOTENT; +"SWAP_INDEPENDENT",SWAP_INDEPENDENT; +"SWAP_REFL",SWAP_REFL; +"SWAP_SYM",SWAP_SYM; +"SYLVESTER_DETERMINANT_IDENTITY",SYLVESTER_DETERMINANT_IDENTITY; +"SYMDIFF_PARITY_LEMMA",SYMDIFF_PARITY_LEMMA; +"SYMMETRIC_CLOSURE",SYMMETRIC_CLOSURE; +"SYMMETRIC_INTERIOR",SYMMETRIC_INTERIOR; +"SYMMETRIC_LINEAR_IMAGE",SYMMETRIC_LINEAR_IMAGE; +"SYMMETRIC_MATRIX",SYMMETRIC_MATRIX; +"SYMMETRIC_MATRIX_DIAGONALIZABLE_EXPLICIT",SYMMETRIC_MATRIX_DIAGONALIZABLE_EXPLICIT; +"SYMMETRIC_MATRIX_EQ_DIAGONALIZABLE",SYMMETRIC_MATRIX_EQ_DIAGONALIZABLE; +"SYMMETRIC_MATRIX_IMP_DIAGONALIZABLE",SYMMETRIC_MATRIX_IMP_DIAGONALIZABLE; +"SYMMETRIC_MATRIX_MUL",SYMMETRIC_MATRIX_MUL; +"SYMMETRIC_MATRIX_ORTHOGONAL_EIGENVECTORS",SYMMETRIC_MATRIX_ORTHOGONAL_EIGENVECTORS; +"SYMMETRIX_MATRIX_CONJUGATE",SYMMETRIX_MATRIX_CONJUGATE; +"SYMMETRY_LEMMA",SYMMETRY_LEMMA; +"TAGGED_DIVISION_FINER",TAGGED_DIVISION_FINER; +"TAGGED_DIVISION_OF",TAGGED_DIVISION_OF; +"TAGGED_DIVISION_OF_ALT",TAGGED_DIVISION_OF_ALT; +"TAGGED_DIVISION_OF_ANOTHER",TAGGED_DIVISION_OF_ANOTHER; +"TAGGED_DIVISION_OF_EMPTY",TAGGED_DIVISION_OF_EMPTY; +"TAGGED_DIVISION_OF_FINITE",TAGGED_DIVISION_OF_FINITE; +"TAGGED_DIVISION_OF_NONTRIVIAL",TAGGED_DIVISION_OF_NONTRIVIAL; +"TAGGED_DIVISION_OF_SELF",TAGGED_DIVISION_OF_SELF; +"TAGGED_DIVISION_OF_TRIVIAL",TAGGED_DIVISION_OF_TRIVIAL; +"TAGGED_DIVISION_OF_UNION_SELF",TAGGED_DIVISION_OF_UNION_SELF; +"TAGGED_DIVISION_SPLIT_LEFT_INJ",TAGGED_DIVISION_SPLIT_LEFT_INJ; +"TAGGED_DIVISION_SPLIT_RIGHT_INJ",TAGGED_DIVISION_SPLIT_RIGHT_INJ; +"TAGGED_DIVISION_UNION",TAGGED_DIVISION_UNION; +"TAGGED_DIVISION_UNIONS",TAGGED_DIVISION_UNIONS; +"TAGGED_DIVISION_UNIONS_EXISTS",TAGGED_DIVISION_UNIONS_EXISTS; +"TAGGED_DIVISION_UNION_IMAGE_SND",TAGGED_DIVISION_UNION_IMAGE_SND; +"TAGGED_DIVISION_UNION_INTERVAL",TAGGED_DIVISION_UNION_INTERVAL; +"TAGGED_PARTIAL_DIVISION_COMMON_POINT_BOUND",TAGGED_PARTIAL_DIVISION_COMMON_POINT_BOUND; +"TAGGED_PARTIAL_DIVISION_COMMON_TAGS",TAGGED_PARTIAL_DIVISION_COMMON_TAGS; +"TAGGED_PARTIAL_DIVISION_OF_SUBSET",TAGGED_PARTIAL_DIVISION_OF_SUBSET; +"TAGGED_PARTIAL_DIVISION_OF_TRIVIAL",TAGGED_PARTIAL_DIVISION_OF_TRIVIAL; +"TAGGED_PARTIAL_DIVISION_OF_UNION_SELF",TAGGED_PARTIAL_DIVISION_OF_UNION_SELF; +"TAGGED_PARTIAL_DIVISION_SUBSET",TAGGED_PARTIAL_DIVISION_SUBSET; +"TAG_IN_INTERVAL",TAG_IN_INTERVAL; +"TARSKI_SET",TARSKI_SET; +"TENDSTO_LIM",TENDSTO_LIM; +"TIETZE",TIETZE; +"TIETZE_CLOSED_INTERVAL",TIETZE_CLOSED_INTERVAL; +"TIETZE_CLOSED_INTERVAL_1",TIETZE_CLOSED_INTERVAL_1; +"TIETZE_OPEN_INTERVAL",TIETZE_OPEN_INTERVAL; +"TIETZE_OPEN_INTERVAL_1",TIETZE_OPEN_INTERVAL_1; +"TIETZE_STEP",TIETZE_STEP; +"TIETZE_UNBOUNDED",TIETZE_UNBOUNDED; +"TIETZE_UNBOUNDED_1",TIETZE_UNBOUNDED_1; +"TL",TL; +"TOPOLOGICAL_SORT",TOPOLOGICAL_SORT; +"TOPOLOGY_EQ",TOPOLOGY_EQ; +"TOPSPACE_EUCLIDEAN",TOPSPACE_EUCLIDEAN; +"TOPSPACE_EUCLIDEAN_SUBTOPOLOGY",TOPSPACE_EUCLIDEAN_SUBTOPOLOGY; +"TOPSPACE_SUBTOPOLOGY",TOPSPACE_SUBTOPOLOGY; +"TRACE_0",TRACE_0; +"TRACE_ADD",TRACE_ADD; +"TRACE_CONJUGATE",TRACE_CONJUGATE; +"TRACE_I",TRACE_I; +"TRACE_MUL_SYM",TRACE_MUL_SYM; +"TRACE_SUB",TRACE_SUB; +"TRACE_TRANSP",TRACE_TRANSP; +"TRANSITIVE_STEPWISE_LE",TRANSITIVE_STEPWISE_LE; +"TRANSITIVE_STEPWISE_LE_EQ",TRANSITIVE_STEPWISE_LE_EQ; +"TRANSITIVE_STEPWISE_LT",TRANSITIVE_STEPWISE_LT; +"TRANSITIVE_STEPWISE_LT_EQ",TRANSITIVE_STEPWISE_LT_EQ; +"TRANSLATION_DIFF",TRANSLATION_DIFF; +"TRANSLATION_EQ_IMP",TRANSLATION_EQ_IMP; +"TRANSLATION_GALOIS",TRANSLATION_GALOIS; +"TRANSLATION_UNIV",TRANSLATION_UNIV; +"TRANSP_COLUMNVECTOR",TRANSP_COLUMNVECTOR; +"TRANSP_COMPONENT",TRANSP_COMPONENT; +"TRANSP_DIAGONAL_MATRIX",TRANSP_DIAGONAL_MATRIX; +"TRANSP_EQ",TRANSP_EQ; +"TRANSP_MAT",TRANSP_MAT; +"TRANSP_MATRIX_ADD",TRANSP_MATRIX_ADD; +"TRANSP_MATRIX_CMUL",TRANSP_MATRIX_CMUL; +"TRANSP_MATRIX_NEG",TRANSP_MATRIX_NEG; +"TRANSP_MATRIX_SUB",TRANSP_MATRIX_SUB; +"TRANSP_ROWVECTOR",TRANSP_ROWVECTOR; +"TRANSP_TRANSP",TRANSP_TRANSP; +"TREAL_ADD_ASSOC",TREAL_ADD_ASSOC; +"TREAL_ADD_LDISTRIB",TREAL_ADD_LDISTRIB; +"TREAL_ADD_LID",TREAL_ADD_LID; +"TREAL_ADD_LINV",TREAL_ADD_LINV; +"TREAL_ADD_SYM",TREAL_ADD_SYM; +"TREAL_ADD_SYM_EQ",TREAL_ADD_SYM_EQ; +"TREAL_ADD_WELLDEF",TREAL_ADD_WELLDEF; +"TREAL_ADD_WELLDEFR",TREAL_ADD_WELLDEFR; +"TREAL_EQ_AP",TREAL_EQ_AP; +"TREAL_EQ_IMP_LE",TREAL_EQ_IMP_LE; +"TREAL_EQ_REFL",TREAL_EQ_REFL; +"TREAL_EQ_SYM",TREAL_EQ_SYM; +"TREAL_EQ_TRANS",TREAL_EQ_TRANS; +"TREAL_INV_0",TREAL_INV_0; +"TREAL_INV_WELLDEF",TREAL_INV_WELLDEF; +"TREAL_LE_ANTISYM",TREAL_LE_ANTISYM; +"TREAL_LE_LADD_IMP",TREAL_LE_LADD_IMP; +"TREAL_LE_MUL",TREAL_LE_MUL; +"TREAL_LE_REFL",TREAL_LE_REFL; +"TREAL_LE_TOTAL",TREAL_LE_TOTAL; +"TREAL_LE_TRANS",TREAL_LE_TRANS; +"TREAL_LE_WELLDEF",TREAL_LE_WELLDEF; +"TREAL_MUL_ASSOC",TREAL_MUL_ASSOC; +"TREAL_MUL_LID",TREAL_MUL_LID; +"TREAL_MUL_LINV",TREAL_MUL_LINV; +"TREAL_MUL_SYM",TREAL_MUL_SYM; +"TREAL_MUL_SYM_EQ",TREAL_MUL_SYM_EQ; +"TREAL_MUL_WELLDEF",TREAL_MUL_WELLDEF; +"TREAL_MUL_WELLDEFR",TREAL_MUL_WELLDEFR; +"TREAL_NEG_WELLDEF",TREAL_NEG_WELLDEF; +"TREAL_OF_NUM_ADD",TREAL_OF_NUM_ADD; +"TREAL_OF_NUM_EQ",TREAL_OF_NUM_EQ; +"TREAL_OF_NUM_LE",TREAL_OF_NUM_LE; +"TREAL_OF_NUM_MUL",TREAL_OF_NUM_MUL; +"TREAL_OF_NUM_WELLDEF",TREAL_OF_NUM_WELLDEF; +"TRIANGLE_LEMMA",TRIANGLE_LEMMA; +"TRIANGULATION_INTER_SIMPLEX",TRIANGULATION_INTER_SIMPLEX; +"TRIANGULATION_SIMPLICIAL_COMPLEX",TRIANGULATION_SIMPLICIAL_COMPLEX; +"TRIANGULATION_UNION",TRIANGULATION_UNION; +"TRIVIAL_LIMIT_AT",TRIVIAL_LIMIT_AT; +"TRIVIAL_LIMIT_AT_INFINITY",TRIVIAL_LIMIT_AT_INFINITY; +"TRIVIAL_LIMIT_SEQUENTIALLY",TRIVIAL_LIMIT_SEQUENTIALLY; +"TRIVIAL_LIMIT_WITHIN",TRIVIAL_LIMIT_WITHIN; +"TRIVIAL_LIMIT_WITHIN_CONVEX",TRIVIAL_LIMIT_WITHIN_CONVEX; +"TRIV_AND_EXISTS_THM",TRIV_AND_EXISTS_THM; +"TRIV_EXISTS_AND_THM",TRIV_EXISTS_AND_THM; +"TRIV_EXISTS_IMP_THM",TRIV_EXISTS_IMP_THM; +"TRIV_FORALL_IMP_THM",TRIV_FORALL_IMP_THM; +"TRIV_FORALL_OR_THM",TRIV_FORALL_OR_THM; +"TRIV_OR_FORALL_THM",TRIV_OR_FORALL_THM; +"TRUTH",TRUTH; +"TUBE_LEMMA",TUBE_LEMMA; +"TWO",TWO; +"T_DEF",T_DEF; +"UNBOUNDED_COMPONENTS_COMPLEMENT_ABSOLUTE_RETRACT",UNBOUNDED_COMPONENTS_COMPLEMENT_ABSOLUTE_RETRACT; +"UNBOUNDED_CONVEX_CLOSED_CONTAINS_RAY",UNBOUNDED_CONVEX_CLOSED_CONTAINS_RAY; +"UNBOUNDED_CONVEX_CLOSED_CONTAINS_RAYS",UNBOUNDED_CONVEX_CLOSED_CONTAINS_RAYS; +"UNBOUNDED_HALFSPACE_COMPONENT_GE",UNBOUNDED_HALFSPACE_COMPONENT_GE; +"UNBOUNDED_HALFSPACE_COMPONENT_GT",UNBOUNDED_HALFSPACE_COMPONENT_GT; +"UNBOUNDED_HALFSPACE_COMPONENT_LE",UNBOUNDED_HALFSPACE_COMPONENT_LE; +"UNBOUNDED_HALFSPACE_COMPONENT_LT",UNBOUNDED_HALFSPACE_COMPONENT_LT; +"UNBOUNDED_INTER_COBOUNDED",UNBOUNDED_INTER_COBOUNDED; +"UNBOUNDED_OUTSIDE",UNBOUNDED_OUTSIDE; +"UNCOUNTABLE_CONNECTED",UNCOUNTABLE_CONNECTED; +"UNCOUNTABLE_CONTAINS_LIMIT_POINT",UNCOUNTABLE_CONTAINS_LIMIT_POINT; +"UNCOUNTABLE_CONVEX",UNCOUNTABLE_CONVEX; +"UNCOUNTABLE_EUCLIDEAN",UNCOUNTABLE_EUCLIDEAN; +"UNCOUNTABLE_HAS_CONDENSATION_POINT",UNCOUNTABLE_HAS_CONDENSATION_POINT; +"UNCOUNTABLE_INTERVAL",UNCOUNTABLE_INTERVAL; +"UNCOUNTABLE_NONEMPTY_INTERIOR",UNCOUNTABLE_NONEMPTY_INTERIOR; +"UNCOUNTABLE_OPEN",UNCOUNTABLE_OPEN; +"UNCOUNTABLE_PATH_CONNECTED",UNCOUNTABLE_PATH_CONNECTED; +"UNCOUNTABLE_REAL",UNCOUNTABLE_REAL; +"UNCOUNTABLE_SEGMENT",UNCOUNTABLE_SEGMENT; +"UNCURRY_DEF",UNCURRY_DEF; +"UNIFORMLY_CAUCHY_IMP_UNIFORMLY_CONVERGENT",UNIFORMLY_CAUCHY_IMP_UNIFORMLY_CONVERGENT; +"UNIFORMLY_CONTINUOUS_EXTENDS_TO_CLOSURE",UNIFORMLY_CONTINUOUS_EXTENDS_TO_CLOSURE; +"UNIFORMLY_CONTINUOUS_IMP_CAUCHY_CONTINUOUS",UNIFORMLY_CONTINUOUS_IMP_CAUCHY_CONTINUOUS; +"UNIFORMLY_CONTINUOUS_IMP_CONTINUOUS",UNIFORMLY_CONTINUOUS_IMP_CONTINUOUS; +"UNIFORMLY_CONTINUOUS_ON_ADD",UNIFORMLY_CONTINUOUS_ON_ADD; +"UNIFORMLY_CONTINUOUS_ON_CLOSURE",UNIFORMLY_CONTINUOUS_ON_CLOSURE; +"UNIFORMLY_CONTINUOUS_ON_CMUL",UNIFORMLY_CONTINUOUS_ON_CMUL; +"UNIFORMLY_CONTINUOUS_ON_COMPOSE",UNIFORMLY_CONTINUOUS_ON_COMPOSE; +"UNIFORMLY_CONTINUOUS_ON_CONST",UNIFORMLY_CONTINUOUS_ON_CONST; +"UNIFORMLY_CONTINUOUS_ON_DIST_CLOSEST_POINT",UNIFORMLY_CONTINUOUS_ON_DIST_CLOSEST_POINT; +"UNIFORMLY_CONTINUOUS_ON_EQ",UNIFORMLY_CONTINUOUS_ON_EQ; +"UNIFORMLY_CONTINUOUS_ON_ID",UNIFORMLY_CONTINUOUS_ON_ID; +"UNIFORMLY_CONTINUOUS_ON_LIFT_SETDIST",UNIFORMLY_CONTINUOUS_ON_LIFT_SETDIST; +"UNIFORMLY_CONTINUOUS_ON_MUL",UNIFORMLY_CONTINUOUS_ON_MUL; +"UNIFORMLY_CONTINUOUS_ON_NEG",UNIFORMLY_CONTINUOUS_ON_NEG; +"UNIFORMLY_CONTINUOUS_ON_SEQUENTIALLY",UNIFORMLY_CONTINUOUS_ON_SEQUENTIALLY; +"UNIFORMLY_CONTINUOUS_ON_SUB",UNIFORMLY_CONTINUOUS_ON_SUB; +"UNIFORMLY_CONTINUOUS_ON_SUBSET",UNIFORMLY_CONTINUOUS_ON_SUBSET; +"UNIFORMLY_CONTINUOUS_ON_VMUL",UNIFORMLY_CONTINUOUS_ON_VMUL; +"UNIFORMLY_CONTINUOUS_ON_VSUM",UNIFORMLY_CONTINUOUS_ON_VSUM; +"UNIFORMLY_CONVERGENT_EQ_CAUCHY",UNIFORMLY_CONVERGENT_EQ_CAUCHY; +"UNIFORM_LIM_ADD",UNIFORM_LIM_ADD; +"UNIFORM_LIM_BILINEAR",UNIFORM_LIM_BILINEAR; +"UNIFORM_LIM_SUB",UNIFORM_LIM_SUB; +"UNION",UNION; +"UNIONS",UNIONS; +"UNIONS_0",UNIONS_0; +"UNIONS_1",UNIONS_1; +"UNIONS_2",UNIONS_2; +"UNIONS_COMPONENTS",UNIONS_COMPONENTS; +"UNIONS_CONNECTED_COMPONENT",UNIONS_CONNECTED_COMPONENT; +"UNIONS_DIFF",UNIONS_DIFF; +"UNIONS_GSPEC",UNIONS_GSPEC; +"UNIONS_IMAGE",UNIONS_IMAGE; +"UNIONS_INSERT",UNIONS_INSERT; +"UNIONS_INTERS",UNIONS_INTERS; +"UNIONS_MAXIMAL_SETS",UNIONS_MAXIMAL_SETS; +"UNIONS_MONO",UNIONS_MONO; +"UNIONS_MONO_IMAGE",UNIONS_MONO_IMAGE; +"UNIONS_PATH_COMPONENT",UNIONS_PATH_COMPONENT; +"UNIONS_PRED",UNIONS_PRED; +"UNIONS_SUBSET",UNIONS_SUBSET; +"UNIONS_UNION",UNIONS_UNION; +"UNION_ACI",UNION_ACI; +"UNION_ASSOC",UNION_ASSOC; +"UNION_COMM",UNION_COMM; +"UNION_EMPTY",UNION_EMPTY; +"UNION_FL",UNION_FL; +"UNION_IDEMPOT",UNION_IDEMPOT; +"UNION_INSEG",UNION_INSEG; +"UNION_INTERIOR_SUBSET",UNION_INTERIOR_SUBSET; +"UNION_LE_ADD_C",UNION_LE_ADD_C; +"UNION_OVER_INTER",UNION_OVER_INTER; +"UNION_SEGMENT",UNION_SEGMENT; +"UNION_SUBSET",UNION_SUBSET; +"UNION_UNIV",UNION_UNIV; +"UNION_WITH_INSIDE",UNION_WITH_INSIDE; +"UNION_WITH_OUTSIDE",UNION_WITH_OUTSIDE; +"UNIQUE_SKOLEM_ALT",UNIQUE_SKOLEM_ALT; +"UNIQUE_SKOLEM_THM",UNIQUE_SKOLEM_THM; +"UNIT_INTERVAL_CONVEX_HULL",UNIT_INTERVAL_CONVEX_HULL; +"UNIT_INTERVAL_NONEMPTY",UNIT_INTERVAL_NONEMPTY; +"UNIV",UNIV; +"UNIV_GSPEC",UNIV_GSPEC; +"UNIV_NOT_EMPTY",UNIV_NOT_EMPTY; +"UNIV_PCROSS_UNIV",UNIV_PCROSS_UNIV; +"UNIV_SECOND_COUNTABLE",UNIV_SECOND_COUNTABLE; +"UNIV_SECOND_COUNTABLE_SEQUENCE",UNIV_SECOND_COUNTABLE_SEQUENCE; +"UNIV_SUBSET",UNIV_SUBSET; +"UNWIND_THM1",UNWIND_THM1; +"UNWIND_THM2",UNWIND_THM2; +"UPPER_BOUND_FINITE_SET",UPPER_BOUND_FINITE_SET; +"UPPER_BOUND_FINITE_SET_REAL",UPPER_BOUND_FINITE_SET_REAL; +"URYSOHN",URYSOHN; +"URYSOHN_LOCAL",URYSOHN_LOCAL; +"URYSOHN_LOCAL_STRONG",URYSOHN_LOCAL_STRONG; +"URYSOHN_STRONG",URYSOHN_STRONG; +"VARIATION_EQUAL_LEMMA",VARIATION_EQUAL_LEMMA; +"VECTOR_1",VECTOR_1; +"VECTOR_2",VECTOR_2; +"VECTOR_3",VECTOR_3; +"VECTOR_4",VECTOR_4; +"VECTOR_ADD_AC",VECTOR_ADD_AC; +"VECTOR_ADD_ASSOC",VECTOR_ADD_ASSOC; +"VECTOR_ADD_COMPONENT",VECTOR_ADD_COMPONENT; +"VECTOR_ADD_LDISTRIB",VECTOR_ADD_LDISTRIB; +"VECTOR_ADD_LID",VECTOR_ADD_LID; +"VECTOR_ADD_LINV",VECTOR_ADD_LINV; +"VECTOR_ADD_RDISTRIB",VECTOR_ADD_RDISTRIB; +"VECTOR_ADD_RID",VECTOR_ADD_RID; +"VECTOR_ADD_RINV",VECTOR_ADD_RINV; +"VECTOR_ADD_SUB",VECTOR_ADD_SUB; +"VECTOR_ADD_SYM",VECTOR_ADD_SYM; +"VECTOR_AFFINITY_EQ",VECTOR_AFFINITY_EQ; +"VECTOR_CHOOSE_DIST",VECTOR_CHOOSE_DIST; +"VECTOR_CHOOSE_SIZE",VECTOR_CHOOSE_SIZE; +"VECTOR_COMPONENTWISE",VECTOR_COMPONENTWISE; +"VECTOR_DERIVATIVE_AT",VECTOR_DERIVATIVE_AT; +"VECTOR_DERIVATIVE_CONST_AT",VECTOR_DERIVATIVE_CONST_AT; +"VECTOR_DERIVATIVE_UNIQUE_AT",VECTOR_DERIVATIVE_UNIQUE_AT; +"VECTOR_DERIVATIVE_UNIQUE_WITHIN_CLOSED_INTERVAL",VECTOR_DERIVATIVE_UNIQUE_WITHIN_CLOSED_INTERVAL; +"VECTOR_DERIVATIVE_WITHIN_CLOSED_INTERVAL",VECTOR_DERIVATIVE_WITHIN_CLOSED_INTERVAL; +"VECTOR_DERIVATIVE_WORKS",VECTOR_DERIVATIVE_WORKS; +"VECTOR_DIFF_CHAIN_AT",VECTOR_DIFF_CHAIN_AT; +"VECTOR_DIFF_CHAIN_WITHIN",VECTOR_DIFF_CHAIN_WITHIN; +"VECTOR_EQ",VECTOR_EQ; +"VECTOR_EQ_ADDR",VECTOR_EQ_ADDR; +"VECTOR_EQ_AFFINITY",VECTOR_EQ_AFFINITY; +"VECTOR_EQ_DOT_SPAN",VECTOR_EQ_DOT_SPAN; +"VECTOR_EQ_LDOT",VECTOR_EQ_LDOT; +"VECTOR_EQ_NEG2",VECTOR_EQ_NEG2; +"VECTOR_EQ_RDOT",VECTOR_EQ_RDOT; +"VECTOR_EXPAND_1",VECTOR_EXPAND_1; +"VECTOR_EXPAND_2",VECTOR_EXPAND_2; +"VECTOR_EXPAND_3",VECTOR_EXPAND_3; +"VECTOR_EXPAND_4",VECTOR_EXPAND_4; +"VECTOR_IN_ORTHOGONAL_BASIS",VECTOR_IN_ORTHOGONAL_BASIS; +"VECTOR_IN_ORTHOGONAL_SPANNINGSET",VECTOR_IN_ORTHOGONAL_SPANNINGSET; +"VECTOR_IN_ORTHONORMAL_BASIS",VECTOR_IN_ORTHONORMAL_BASIS; +"VECTOR_MATRIX_MUL_TRANSP",VECTOR_MATRIX_MUL_TRANSP; +"VECTOR_MUL_ASSOC",VECTOR_MUL_ASSOC; +"VECTOR_MUL_COMPONENT",VECTOR_MUL_COMPONENT; +"VECTOR_MUL_EQ_0",VECTOR_MUL_EQ_0; +"VECTOR_MUL_LCANCEL",VECTOR_MUL_LCANCEL; +"VECTOR_MUL_LCANCEL_IMP",VECTOR_MUL_LCANCEL_IMP; +"VECTOR_MUL_LID",VECTOR_MUL_LID; +"VECTOR_MUL_LNEG",VECTOR_MUL_LNEG; +"VECTOR_MUL_LZERO",VECTOR_MUL_LZERO; +"VECTOR_MUL_RCANCEL",VECTOR_MUL_RCANCEL; +"VECTOR_MUL_RCANCEL_IMP",VECTOR_MUL_RCANCEL_IMP; +"VECTOR_MUL_RNEG",VECTOR_MUL_RNEG; +"VECTOR_MUL_RZERO",VECTOR_MUL_RZERO; +"VECTOR_NEG_0",VECTOR_NEG_0; +"VECTOR_NEG_COMPONENT",VECTOR_NEG_COMPONENT; +"VECTOR_NEG_EQ_0",VECTOR_NEG_EQ_0; +"VECTOR_NEG_MINUS1",VECTOR_NEG_MINUS1; +"VECTOR_NEG_NEG",VECTOR_NEG_NEG; +"VECTOR_NEG_SUB",VECTOR_NEG_SUB; +"VECTOR_ONE",VECTOR_ONE; +"VECTOR_SUB",VECTOR_SUB; +"VECTOR_SUB_ADD",VECTOR_SUB_ADD; +"VECTOR_SUB_ADD2",VECTOR_SUB_ADD2; +"VECTOR_SUB_COMPONENT",VECTOR_SUB_COMPONENT; +"VECTOR_SUB_EQ",VECTOR_SUB_EQ; +"VECTOR_SUB_LDISTRIB",VECTOR_SUB_LDISTRIB; +"VECTOR_SUB_LZERO",VECTOR_SUB_LZERO; +"VECTOR_SUB_PROJECT_ORTHOGONAL",VECTOR_SUB_PROJECT_ORTHOGONAL; +"VECTOR_SUB_RADD",VECTOR_SUB_RADD; +"VECTOR_SUB_RDISTRIB",VECTOR_SUB_RDISTRIB; +"VECTOR_SUB_REFL",VECTOR_SUB_REFL; +"VECTOR_SUB_RZERO",VECTOR_SUB_RZERO; +"VECTOR_VARIATION_AFFINITY",VECTOR_VARIATION_AFFINITY; +"VECTOR_VARIATION_AFFINITY2",VECTOR_VARIATION_AFFINITY2; +"VECTOR_VARIATION_COMBINE",VECTOR_VARIATION_COMBINE; +"VECTOR_VARIATION_CONST",VECTOR_VARIATION_CONST; +"VECTOR_VARIATION_CONST_EQ",VECTOR_VARIATION_CONST_EQ; +"VECTOR_VARIATION_CONTINUOUS",VECTOR_VARIATION_CONTINUOUS; +"VECTOR_VARIATION_CONTINUOUS_LEFT",VECTOR_VARIATION_CONTINUOUS_LEFT; +"VECTOR_VARIATION_CONTINUOUS_RIGHT",VECTOR_VARIATION_CONTINUOUS_RIGHT; +"VECTOR_VARIATION_EQ",VECTOR_VARIATION_EQ; +"VECTOR_VARIATION_GE_DROP_FUNCTION",VECTOR_VARIATION_GE_DROP_FUNCTION; +"VECTOR_VARIATION_GE_NORM_FUNCTION",VECTOR_VARIATION_GE_NORM_FUNCTION; +"VECTOR_VARIATION_INTEGRAL_NORM_DERIVATIVE",VECTOR_VARIATION_INTEGRAL_NORM_DERIVATIVE; +"VECTOR_VARIATION_MINUS_FUNCTION_MONOTONE",VECTOR_VARIATION_MINUS_FUNCTION_MONOTONE; +"VECTOR_VARIATION_MONOTONE",VECTOR_VARIATION_MONOTONE; +"VECTOR_VARIATION_NEG",VECTOR_VARIATION_NEG; +"VECTOR_VARIATION_ON_DIVISION",VECTOR_VARIATION_ON_DIVISION; +"VECTOR_VARIATION_ON_NULL",VECTOR_VARIATION_ON_NULL; +"VECTOR_VARIATION_POS_LE",VECTOR_VARIATION_POS_LE; +"VECTOR_VARIATION_REFLECT",VECTOR_VARIATION_REFLECT; +"VECTOR_VARIATION_REFLECT2",VECTOR_VARIATION_REFLECT2; +"VECTOR_VARIATION_REFLECT_INTERVAL",VECTOR_VARIATION_REFLECT_INTERVAL; +"VECTOR_VARIATION_TRANSLATION",VECTOR_VARIATION_TRANSLATION; +"VECTOR_VARIATION_TRANSLATION2",VECTOR_VARIATION_TRANSLATION2; +"VECTOR_VARIATION_TRANSLATION_INTERVAL",VECTOR_VARIATION_TRANSLATION_INTERVAL; +"VECTOR_VARIATION_TRIANGLE",VECTOR_VARIATION_TRIANGLE; +"VEC_COMPONENT",VEC_COMPONENT; +"VEC_EQ",VEC_EQ; +"VSUM",VSUM; +"VSUM_0",VSUM_0; +"VSUM_1",VSUM_1; +"VSUM_2",VSUM_2; +"VSUM_3",VSUM_3; +"VSUM_4",VSUM_4; +"VSUM_ADD",VSUM_ADD; +"VSUM_ADD_GEN",VSUM_ADD_GEN; +"VSUM_ADD_NUMSEG",VSUM_ADD_NUMSEG; +"VSUM_ADD_SPLIT",VSUM_ADD_SPLIT; +"VSUM_BIJECTION",VSUM_BIJECTION; +"VSUM_CASES",VSUM_CASES; +"VSUM_CASES_1",VSUM_CASES_1; +"VSUM_CLAUSES",VSUM_CLAUSES; +"VSUM_CLAUSES_LEFT",VSUM_CLAUSES_LEFT; +"VSUM_CLAUSES_NUMSEG",VSUM_CLAUSES_NUMSEG; +"VSUM_CLAUSES_RIGHT",VSUM_CLAUSES_RIGHT; +"VSUM_CMUL_NUMSEG",VSUM_CMUL_NUMSEG; +"VSUM_COMBINE_L",VSUM_COMBINE_L; +"VSUM_COMBINE_R",VSUM_COMBINE_R; +"VSUM_COMPONENT",VSUM_COMPONENT; +"VSUM_CONST",VSUM_CONST; +"VSUM_CONST_NUMSEG",VSUM_CONST_NUMSEG; +"VSUM_CONTENT_NULL",VSUM_CONTENT_NULL; +"VSUM_DELETE",VSUM_DELETE; +"VSUM_DELETE_CASES",VSUM_DELETE_CASES; +"VSUM_DELTA",VSUM_DELTA; +"VSUM_DIFF",VSUM_DIFF; +"VSUM_DIFFS",VSUM_DIFFS; +"VSUM_DIFFS_ALT",VSUM_DIFFS_ALT; +"VSUM_DIFF_LEMMA",VSUM_DIFF_LEMMA; +"VSUM_EQ",VSUM_EQ; +"VSUM_EQ_0",VSUM_EQ_0; +"VSUM_EQ_GENERAL",VSUM_EQ_GENERAL; +"VSUM_EQ_GENERAL_INVERSES",VSUM_EQ_GENERAL_INVERSES; +"VSUM_EQ_NUMSEG",VSUM_EQ_NUMSEG; +"VSUM_EQ_SUPERSET",VSUM_EQ_SUPERSET; +"VSUM_GROUP",VSUM_GROUP; +"VSUM_IMAGE",VSUM_IMAGE; +"VSUM_IMAGE_GEN",VSUM_IMAGE_GEN; +"VSUM_IMAGE_NONZERO",VSUM_IMAGE_NONZERO; +"VSUM_INCL_EXCL",VSUM_INCL_EXCL; +"VSUM_INJECTION",VSUM_INJECTION; +"VSUM_LMUL",VSUM_LMUL; +"VSUM_NEG",VSUM_NEG; +"VSUM_NONZERO_IMAGE_LEMMA",VSUM_NONZERO_IMAGE_LEMMA; +"VSUM_NORM",VSUM_NORM; +"VSUM_NORM_ALLSUBSETS_BOUND",VSUM_NORM_ALLSUBSETS_BOUND; +"VSUM_NORM_BOUND",VSUM_NORM_BOUND; +"VSUM_NORM_LE",VSUM_NORM_LE; +"VSUM_NORM_TRIANGLE",VSUM_NORM_TRIANGLE; +"VSUM_OFFSET",VSUM_OFFSET; +"VSUM_OFFSET_0",VSUM_OFFSET_0; +"VSUM_OVER_TAGGED_DIVISION_LEMMA",VSUM_OVER_TAGGED_DIVISION_LEMMA; +"VSUM_OVER_TAGGED_PARTIAL_DIVISION_LEMMA",VSUM_OVER_TAGGED_PARTIAL_DIVISION_LEMMA; +"VSUM_PAIR",VSUM_PAIR; +"VSUM_PAIR_0",VSUM_PAIR_0; +"VSUM_PARTIAL_PRE",VSUM_PARTIAL_PRE; +"VSUM_PARTIAL_SUC",VSUM_PARTIAL_SUC; +"VSUM_REAL",VSUM_REAL; +"VSUM_RESTRICT",VSUM_RESTRICT; +"VSUM_RESTRICT_SET",VSUM_RESTRICT_SET; +"VSUM_RMUL",VSUM_RMUL; +"VSUM_SING",VSUM_SING; +"VSUM_SING_NUMSEG",VSUM_SING_NUMSEG; +"VSUM_SUB",VSUM_SUB; +"VSUM_SUB_NUMSEG",VSUM_SUB_NUMSEG; +"VSUM_SUC",VSUM_SUC; +"VSUM_SUPERSET",VSUM_SUPERSET; +"VSUM_SWAP",VSUM_SWAP; +"VSUM_SWAP_NUMSEG",VSUM_SWAP_NUMSEG; +"VSUM_TRIV_NUMSEG",VSUM_TRIV_NUMSEG; +"VSUM_UNION",VSUM_UNION; +"VSUM_UNIONS_NONZERO",VSUM_UNIONS_NONZERO; +"VSUM_UNION_LZERO",VSUM_UNION_LZERO; +"VSUM_UNION_NONZERO",VSUM_UNION_NONZERO; +"VSUM_UNION_RZERO",VSUM_UNION_RZERO; +"VSUM_VMUL",VSUM_VMUL; +"VSUM_VSUM_PRODUCT",VSUM_VSUM_PRODUCT; +"WF",WF; +"WF_DCHAIN",WF_DCHAIN; +"WF_EQ",WF_EQ; +"WF_EREC",WF_EREC; +"WF_FALSE",WF_FALSE; +"WF_FINITE",WF_FINITE; +"WF_IND",WF_IND; +"WF_INT_MEASURE",WF_INT_MEASURE; +"WF_INT_MEASURE_2",WF_INT_MEASURE_2; +"WF_LEX",WF_LEX; +"WF_LEX_DEPENDENT",WF_LEX_DEPENDENT; +"WF_MEASURE",WF_MEASURE; +"WF_MEASURE_GEN",WF_MEASURE_GEN; +"WF_POINTWISE",WF_POINTWISE; +"WF_REC",WF_REC; +"WF_REC_CASES",WF_REC_CASES; +"WF_REC_CASES'",WF_REC_CASES'; +"WF_REC_INVARIANT",WF_REC_INVARIANT; +"WF_REC_TAIL",WF_REC_TAIL; +"WF_REC_TAIL_GENERAL",WF_REC_TAIL_GENERAL; +"WF_REC_TAIL_GENERAL'",WF_REC_TAIL_GENERAL'; +"WF_REC_WF",WF_REC_WF; +"WF_REC_num",WF_REC_num; +"WF_REFL",WF_REFL; +"WF_SUBSET",WF_SUBSET; +"WF_UREC",WF_UREC; +"WF_UREC_WF",WF_UREC_WF; +"WF_num",WF_num; +"WITHIN",WITHIN; +"WITHIN_UNIV",WITHIN_UNIV; +"WITHIN_WITHIN",WITHIN_WITHIN; +"WLOG_LE",WLOG_LE; +"WLOG_LINEAR_INJECTIVE_IMAGE",WLOG_LINEAR_INJECTIVE_IMAGE; +"WLOG_LINEAR_INJECTIVE_IMAGE_2",WLOG_LINEAR_INJECTIVE_IMAGE_2; +"WLOG_LINEAR_INJECTIVE_IMAGE_2_ALT",WLOG_LINEAR_INJECTIVE_IMAGE_2_ALT; +"WLOG_LINEAR_INJECTIVE_IMAGE_ALT",WLOG_LINEAR_INJECTIVE_IMAGE_ALT; +"WLOG_LT",WLOG_LT; +"WO",WO; +"WOSET",WOSET; +"WOSET_ANTISYM",WOSET_ANTISYM; +"WOSET_FLEQ",WOSET_FLEQ; +"WOSET_POSET",WOSET_POSET; +"WOSET_REFL",WOSET_REFL; +"WOSET_TOTAL",WOSET_TOTAL; +"WOSET_TOTAL_LE",WOSET_TOTAL_LE; +"WOSET_TOTAL_LT",WOSET_TOTAL_LT; +"WOSET_TRANS",WOSET_TRANS; +"WOSET_TRANS_LE",WOSET_TRANS_LE; +"WOSET_TRANS_LESS",WOSET_TRANS_LESS; +"WOSET_WELL",WOSET_WELL; +"WOSET_WELL_CONTRAPOS",WOSET_WELL_CONTRAPOS; +"ZBOT",ZBOT; +"ZCONSTR",ZCONSTR; +"ZCONSTR_ZBOT",ZCONSTR_ZBOT; +"ZERO_DEF",ZERO_DEF; +"ZIP",ZIP; +"ZIP_DEF",ZIP_DEF; +"ZL",ZL; +"ZL_SUBSETS",ZL_SUBSETS; +"ZL_SUBSETS_UNIONS",ZL_SUBSETS_UNIONS; +"ZL_SUBSETS_UNIONS_NONEMPTY",ZL_SUBSETS_UNIONS_NONEMPTY; +"ZRECSPACE_CASES",ZRECSPACE_CASES; +"ZRECSPACE_INDUCT",ZRECSPACE_INDUCT; +"ZRECSPACE_RULES",ZRECSPACE_RULES; +"_FALSITY_",_FALSITY_; +"_FUNCTION",_FUNCTION; +"_GUARDED_PATTERN",_GUARDED_PATTERN; +"_MATCH",_MATCH; +"_SEQPATTERN",_SEQPATTERN; +"_UNGUARDED_PATTERN",_UNGUARDED_PATTERN; +"absolutely_integrable_on",absolutely_integrable_on; +"add_c",add_c; +"adjoint",adjoint; +"admissible",admissible; +"aff_dim",aff_dim; +"affine",affine; +"affine_dependent",affine_dependent; +"arc",arc; +"at",at; +"at_infinity",at_infinity; +"ball",ball; +"basis",basis; +"between",between; +"bilinear",bilinear; +"binarysum",binarysum; +"bitset",bitset; +"bool_INDUCT",bool_INDUCT; +"bool_RECURSION",bool_RECURSION; +"bounded",bounded; +"cart_tybij",cart_tybij; +"cauchy",cauchy; +"cball",cball; +"chain",chain; +"char_INDUCT",char_INDUCT; +"char_RECURSION",char_RECURSION; +"closed",closed; +"closed_in",closed_in; +"closed_interval",closed_interval; +"closed_segment",closed_segment; +"closest_point",closest_point; +"closure",closure; +"codeset",codeset; +"cofactor",cofactor; +"collinear",collinear; +"column",column; +"columns",columns; +"columnvector",columnvector; +"compact",compact; +"complete",complete; +"components",components; +"condensation_point_of",condensation_point_of; +"cong",cong; +"conic",conic; +"connected",connected; +"connected_component",connected_component; +"content",content; +"continuous",continuous; +"continuous_at",continuous_at; +"continuous_on",continuous_on; +"continuous_within",continuous_within; +"contractible",contractible; +"convex",convex; +"convex_cone",convex_cone; +"convex_on",convex_on; +"coplanar",coplanar; +"covering_space",covering_space; +"dependent",dependent; +"dest_int_rep",dest_int_rep; +"det",det; +"diagonal_matrix",diagonal_matrix; +"diameter",diameter; +"differentiable",differentiable; +"differentiable_on",differentiable_on; +"dim",dim; +"dimindex",dimindex; +"dist",dist; +"division_of",division_of; +"division_points",division_points; +"dot",dot; +"drop",drop; +"edge_of",edge_of; +"epigraph",epigraph; +"eq_c",eq_c; +"equiintegrable_on",equiintegrable_on; +"euclidean",euclidean; +"evenperm",evenperm; +"eventually",eventually; +"exposed_face_of",exposed_face_of; +"extreme_point_of",extreme_point_of; +"face_of",face_of; +"facet_of",facet_of; +"fine",fine; +"finite_image_tybij",finite_image_tybij; +"finite_index",finite_index; +"finite_sum_tybij",finite_sum_tybij; +"fl",fl; +"frechet_derivative",frechet_derivative; +"from",from; +"frontier",frontier; +"fstcart",fstcart; +"gauge",gauge; +"ge_c",ge_c; +"geom_mul",geom_mul; +"grade",grade; +"gt_c",gt_c; +"has_bounded_setvariation_on",has_bounded_setvariation_on; +"has_bounded_variation_on",has_bounded_variation_on; +"has_derivative",has_derivative; +"has_derivative_at",has_derivative_at; +"has_derivative_within",has_derivative_within; +"has_integral",has_integral; +"has_integral_alt",has_integral_alt; +"has_integral_compact_interval",has_integral_compact_interval; +"has_integral_def",has_integral_def; +"has_measure",has_measure; +"has_vector_derivative",has_vector_derivative; +"homeomorphic",homeomorphic; +"homeomorphism",homeomorphism; +"homotopic_loops",homotopic_loops; +"homotopic_paths",homotopic_paths; +"homotopic_with",homotopic_with; +"homotopy_equivalent",homotopy_equivalent; +"hreal_add",hreal_add; +"hreal_add_th",hreal_add_th; +"hreal_inv",hreal_inv; +"hreal_inv_th",hreal_inv_th; +"hreal_le",hreal_le; +"hreal_le_th",hreal_le_th; +"hreal_mul",hreal_mul; +"hreal_mul_th",hreal_mul_th; +"hreal_of_num",hreal_of_num; +"hreal_of_num_th",hreal_of_num_th; +"hull",hull; +"in_direction",in_direction; +"independent",independent; +"indicator",indicator; +"inf",inf; +"infnorm",infnorm; +"infsum",infsum; +"inner",inner; +"inseg",inseg; +"inside",inside; +"int_abs",int_abs; +"int_abs_th",int_abs_th; +"int_abstr",int_abstr; +"int_add",int_add; +"int_add_th",int_add_th; +"int_congruent",int_congruent; +"int_coprime",int_coprime; +"int_divides",int_divides; +"int_eq",int_eq; +"int_gcd",int_gcd; +"int_ge",int_ge; +"int_gt",int_gt; +"int_le",int_le; +"int_lt",int_lt; +"int_max",int_max; +"int_max_th",int_max_th; +"int_min",int_min; +"int_min_th",int_min_th; +"int_mod",int_mod; +"int_mul",int_mul; +"int_mul_th",int_mul_th; +"int_neg",int_neg; +"int_neg_th",int_neg_th; +"int_of_num",int_of_num; +"int_of_num_th",int_of_num_th; +"int_pow",int_pow; +"int_pow_th",int_pow_th; +"int_rep",int_rep; +"int_sgn",int_sgn; +"int_sgn_th",int_sgn_th; +"int_sub",int_sub; +"int_sub_th",int_sub_th; +"int_tybij",int_tybij; +"integer",integer; +"integrable_on",integrable_on; +"integral",integral; +"interior",interior; +"interval",interval; +"interval_bij",interval_bij; +"interval_lowerbound",interval_lowerbound; +"interval_upperbound",interval_upperbound; +"inverse",inverse; +"invertible",invertible; +"is_int",is_int; +"is_interval",is_interval; +"is_nadd",is_nadd; +"is_nadd_0",is_nadd_0; +"istopology",istopology; +"iterate",iterate; +"jacobian",jacobian; +"joinpaths",joinpaths; +"kle",kle; +"ksimplex",ksimplex; +"lambda",lambda; +"lambdas",lambdas; +"le_c",le_c; +"lebesgue_measurable",lebesgue_measurable; +"lemma",lemma; +"less",less; +"lift",lift; +"lifted",lifted; +"lim",lim; +"limit_point_of",limit_point_of; +"linear",linear; +"linepath",linepath; +"linseg",linseg; +"list_CASES",list_CASES; +"list_INDUCT",list_INDUCT; +"list_RECURSION",list_RECURSION; +"list_of_set",list_of_set; +"locally",locally; +"lt_c",lt_c; +"mat",mat; +"matrix",matrix; +"matrix_add",matrix_add; +"matrix_cmul",matrix_cmul; +"matrix_inv",matrix_inv; +"matrix_mul",matrix_mul; +"matrix_neg",matrix_neg; +"matrix_sub",matrix_sub; +"matrix_vector_mul",matrix_vector_mul; +"mbasis",mbasis; +"measurable",measurable; +"measurable_on",measurable_on; +"measure",measure; +"midpoint",midpoint; +"minimal",minimal; +"mk_pair_def",mk_pair_def; +"monoidal",monoidal; +"mul_c",mul_c; +"multivec",multivec; +"multivector",multivector; +"multivector_tybij",multivector_tybij; +"multivector_tybij_th",multivector_tybij_th; +"nadd_abs",nadd_abs; +"nadd_add",nadd_add; +"nadd_eq",nadd_eq; +"nadd_inv",nadd_inv; +"nadd_le",nadd_le; +"nadd_mul",nadd_mul; +"nadd_of_num",nadd_of_num; +"nadd_rep",nadd_rep; +"nadd_rinv",nadd_rinv; +"negligible",negligible; +"net_tybij",net_tybij; +"netlimit",netlimit; +"neutral",neutral; +"nsum",nsum; +"num_Axiom",num_Axiom; +"num_CASES",num_CASES; +"num_FINITE",num_FINITE; +"num_FINITE_AVOID",num_FINITE_AVOID; +"num_INDUCTION",num_INDUCTION; +"num_INFINITE",num_INFINITE; +"num_MAX",num_MAX; +"num_RECURSION",num_RECURSION; +"num_RECURSION_STD",num_RECURSION_STD; +"num_WF",num_WF; +"num_WOP",num_WOP; +"num_congruent",num_congruent; +"num_coprime",num_coprime; +"num_divides",num_divides; +"num_gcd",num_gcd; +"num_mod",num_mod; +"num_of_int",num_of_int; +"numseg",numseg; +"o_ASSOC",o_ASSOC; +"o_DEF",o_DEF; +"o_THM",o_THM; +"one",one; +"one_Axiom",one_Axiom; +"one_DEF",one_DEF; +"one_INDUCT",one_INDUCT; +"one_RECURSION",one_RECURSION; +"one_axiom",one_axiom; +"one_tydef",one_tydef; +"onorm",onorm; +"open_def",open_def; +"open_in",open_in; +"open_interval",open_interval; +"open_segment",open_segment; +"operative",operative; +"option_INDUCT",option_INDUCT; +"option_RECURSION",option_RECURSION; +"ordinal",ordinal; +"orthogonal",orthogonal; +"orthogonal_matrix",orthogonal_matrix; +"orthogonal_transformation",orthogonal_transformation; +"outer",outer; +"outermorphism",outermorphism; +"outside",outside; +"pair_INDUCT",pair_INDUCT; +"pair_RECURSION",pair_RECURSION; +"pairwise",pairwise; +"pastecart",pastecart; +"path",path; +"path_component",path_component; +"path_connected",path_connected; +"path_image",path_image; +"path_length",path_length; +"pathfinish",pathfinish; +"pathstart",pathstart; +"permutation",permutation; +"permutes",permutes; +"polyhedron",polyhedron; +"polytope",polytope; +"poset",poset; +"prod_tybij",prod_tybij; +"product",product; +"rank",rank; +"rational",rational; +"real_INFINITE",real_INFINITE; +"real_abs",real_abs; +"real_add",real_add; +"real_add_th",real_add_th; +"real_div",real_div; +"real_ge",real_ge; +"real_gt",real_gt; +"real_inv",real_inv; +"real_inv_th",real_inv_th; +"real_le",real_le; +"real_le_th",real_le_th; +"real_lt",real_lt; +"real_max",real_max; +"real_min",real_min; +"real_mod",real_mod; +"real_mul",real_mul; +"real_mul_th",real_mul_th; +"real_neg",real_neg; +"real_neg_th",real_neg_th; +"real_of_num",real_of_num; +"real_of_num_th",real_of_num_th; +"real_pow",real_pow; +"real_sgn",real_sgn; +"real_sub",real_sub; +"rectifiable_path",rectifiable_path; +"reduced",reduced; +"reflect_along",reflect_along; +"relative_frontier",relative_frontier; +"relative_interior",relative_interior; +"retract_of",retract_of; +"retraction",retraction; +"reversepath",reversepath; +"reversion",reversion; +"rotation_matrix",rotation_matrix; +"rotoinversion_matrix",rotoinversion_matrix; +"row",row; +"rows",rows; +"rowvector",rowvector; +"segment",segment; +"seqiterate",seqiterate; +"seqiterate_EXISTS",seqiterate_EXISTS; +"sequentially",sequentially; +"set_of_list",set_of_list; +"set_variation",set_variation; +"setcode",setcode; +"setdist",setdist; +"shiftpath",shiftpath; +"sign",sign; +"simple_path",simple_path; +"simplex",simplex; +"simplicial_complex",simplicial_complex; +"simply_connected",simply_connected; +"sindex",sindex; +"sndcart",sndcart; +"span",span; +"sphere",sphere; +"sqrt",sqrt; +"starlike",starlike; +"string_INFINITE",string_INFINITE; +"subpath",subpath; +"subspace",subspace; +"subtopology",subtopology; +"sum",sum; +"sum_CASES",sum_CASES; +"sum_DISTINCT",sum_DISTINCT; +"sum_INDUCT",sum_INDUCT; +"sum_INJECTIVE",sum_INJECTIVE; +"sum_RECURSION",sum_RECURSION; +"summable",summable; +"sums",sums; +"sup",sup; +"superadmissible",superadmissible; +"support",support; +"swap",swap; +"swapseq_CASES",swapseq_CASES; +"swapseq_INDUCT",swapseq_INDUCT; +"swapseq_RULES",swapseq_RULES; +"tagged_division_of",tagged_division_of; +"tagged_partial_division_of",tagged_partial_division_of; +"tailadmissible",tailadmissible; +"tendsto",tendsto; +"topology_tybij",topology_tybij; +"topology_tybij_th",topology_tybij_th; +"topspace",topspace; +"toset",toset; +"trace",trace; +"transp",transp; +"treal_add",treal_add; +"treal_eq",treal_eq; +"treal_inv",treal_inv; +"treal_le",treal_le; +"treal_mul",treal_mul; +"treal_neg",treal_neg; +"treal_of_num",treal_of_num; +"triangulation",triangulation; +"trivial_limit",trivial_limit; +"uniformly_continuous_on",uniformly_continuous_on; +"vec",vec; +"vector",vector; +"vector_add",vector_add; +"vector_derivative",vector_derivative; +"vector_matrix_mul",vector_matrix_mul; +"vector_mul",vector_mul; +"vector_neg",vector_neg; +"vector_norm",vector_norm; +"vector_sub",vector_sub; +"vector_variation",vector_variation; +"vsum",vsum; +"within",within; +"woset",woset +];; diff --git a/Multivariate/paths.ml b/Multivariate/paths.ml new file mode 100644 index 0000000..53728d8 --- /dev/null +++ b/Multivariate/paths.ml @@ -0,0 +1,15949 @@ +(* ========================================================================= *) +(* Paths, connectedness, homotopy, simple connectedness & contractibility. *) +(* *) +(* (c) Copyright, John Harrison 1998-2008 *) +(* (c) Copyright, Valentina Bruno 2010 *) +(* ========================================================================= *) + +needs "Multivariate/convex.ml";; + +(* ------------------------------------------------------------------------- *) +(* Paths and arcs. *) +(* ------------------------------------------------------------------------- *) + +let path = new_definition + `!g:real^1->real^N. path g <=> g continuous_on interval[vec 0,vec 1]`;; + +let pathstart = new_definition + `pathstart (g:real^1->real^N) = g(vec 0)`;; + +let pathfinish = new_definition + `pathfinish (g:real^1->real^N) = g(vec 1)`;; + +let path_image = new_definition + `path_image (g:real^1->real^N) = IMAGE g (interval[vec 0,vec 1])`;; + +let reversepath = new_definition + `reversepath (g:real^1->real^N) = \x. g(vec 1 - x)`;; + +let joinpaths = new_definition + `(g1 ++ g2) = \x. if drop x <= &1 / &2 then g1(&2 % x) + else g2(&2 % x - vec 1)`;; + +let simple_path = new_definition + `simple_path (g:real^1->real^N) <=> + path g /\ + !x y. x IN interval[vec 0,vec 1] /\ + y IN interval[vec 0,vec 1] /\ + g x = g y + ==> x = y \/ x = vec 0 /\ y = vec 1 \/ x = vec 1 /\ y = vec 0`;; + +let arc = new_definition + `arc (g:real^1->real^N) <=> + path g /\ + !x y. x IN interval [vec 0,vec 1] /\ + y IN interval [vec 0,vec 1] /\ + g x = g y + ==> x = y`;; + +(* ------------------------------------------------------------------------- *) +(* Invariance theorems. *) +(* ------------------------------------------------------------------------- *) + +let PATH_EQ = prove + (`!p q. (!t. t IN interval[vec 0,vec 1] ==> p t = q t) /\ path p + ==> path q`, + REWRITE_TAC[path; CONTINUOUS_ON_EQ]);; + +let PATH_CONTINUOUS_IMAGE = prove + (`!f:real^M->real^N g. + path g /\ f continuous_on path_image g ==> path(f o g)`, + REWRITE_TAC[path; path_image; CONTINUOUS_ON_COMPOSE]);; + +let PATH_TRANSLATION_EQ = prove + (`!a g:real^1->real^N. path((\x. a + x) o g) <=> path g`, + REPEAT GEN_TAC THEN REWRITE_TAC[path] THEN EQ_TAC THEN DISCH_TAC THENL + [SUBGOAL_THEN `(g:real^1->real^N) = (\x. --a + x) o (\x. a + x) o g` + SUBST1_TAC THENL + [REWRITE_TAC[FUN_EQ_THM; o_THM] THEN VECTOR_ARITH_TAC; ALL_TAC]; + ALL_TAC] THEN + MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN + ASM_SIMP_TAC[CONTINUOUS_ON_ADD; CONTINUOUS_ON_ID; CONTINUOUS_ON_CONST]);; + +add_translation_invariants [PATH_TRANSLATION_EQ];; + +let PATH_LINEAR_IMAGE_EQ = prove + (`!f:real^M->real^N g. + linear f /\ (!x y. f x = f y ==> x = y) + ==> (path(f o g) <=> path g)`, + REPEAT GEN_TAC THEN DISCH_TAC THEN + FIRST_ASSUM(X_CHOOSE_THEN `h:real^N->real^M` STRIP_ASSUME_TAC o + MATCH_MP LINEAR_INJECTIVE_LEFT_INVERSE) THEN + REWRITE_TAC[path] THEN EQ_TAC THEN DISCH_TAC THENL + [SUBGOAL_THEN `g:real^1->real^M = h o (f:real^M->real^N) o g` + SUBST1_TAC THENL [ASM_REWRITE_TAC[o_ASSOC; I_O_ID]; ALL_TAC]; + ALL_TAC] THEN + MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN ASM_REWRITE_TAC[] THEN + ASM_SIMP_TAC[LINEAR_CONTINUOUS_ON]);; + +add_linear_invariants [PATH_LINEAR_IMAGE_EQ];; + +let PATHSTART_TRANSLATION = prove + (`!a g. pathstart((\x. a + x) o g) = a + pathstart g`, + REWRITE_TAC[pathstart; o_THM]);; + +add_translation_invariants [PATHSTART_TRANSLATION];; + +let PATHSTART_LINEAR_IMAGE_EQ = prove + (`!f g. linear f ==> pathstart(f o g) = f(pathstart g)`, + REWRITE_TAC[pathstart; o_THM]);; + +add_linear_invariants [PATHSTART_LINEAR_IMAGE_EQ];; + +let PATHFINISH_TRANSLATION = prove + (`!a g. pathfinish((\x. a + x) o g) = a + pathfinish g`, + REWRITE_TAC[pathfinish; o_THM]);; + +add_translation_invariants [PATHFINISH_TRANSLATION];; + +let PATHFINISH_LINEAR_IMAGE = prove + (`!f g. linear f ==> pathfinish(f o g) = f(pathfinish g)`, + REWRITE_TAC[pathfinish; o_THM]);; + +add_linear_invariants [PATHFINISH_LINEAR_IMAGE];; + +let PATH_IMAGE_TRANSLATION = prove + (`!a g. path_image((\x. a + x) o g) = IMAGE (\x. a + x) (path_image g)`, + REWRITE_TAC[path_image; IMAGE_o]);; + +add_translation_invariants [PATH_IMAGE_TRANSLATION];; + +let PATH_IMAGE_LINEAR_IMAGE = prove + (`!f g. linear f ==> path_image(f o g) = IMAGE f (path_image g)`, + REWRITE_TAC[path_image; IMAGE_o]);; + +add_linear_invariants [PATH_IMAGE_LINEAR_IMAGE];; + +let REVERSEPATH_TRANSLATION = prove + (`!a g. reversepath((\x. a + x) o g) = (\x. a + x) o reversepath g`, + REWRITE_TAC[FUN_EQ_THM; reversepath; o_THM]);; + +add_translation_invariants [REVERSEPATH_TRANSLATION];; + +let REVERSEPATH_LINEAR_IMAGE = prove + (`!f g. linear f ==> reversepath(f o g) = f o reversepath g`, + REWRITE_TAC[FUN_EQ_THM; reversepath; o_THM]);; + +add_linear_invariants [REVERSEPATH_LINEAR_IMAGE];; + +let JOINPATHS_TRANSLATION = prove + (`!a:real^N g1 g2. ((\x. a + x) o g1) ++ ((\x. a + x) o g2) = + (\x. a + x) o (g1 ++ g2)`, + REWRITE_TAC[joinpaths; FUN_EQ_THM] THEN REPEAT GEN_TAC THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[o_THM]);; + +add_translation_invariants [JOINPATHS_TRANSLATION];; + +let JOINPATHS_LINEAR_IMAGE = prove + (`!f g1 g2. linear f ==> (f o g1) ++ (f o g2) = f o (g1 ++ g2)`, + REWRITE_TAC[joinpaths; FUN_EQ_THM] THEN REPEAT STRIP_TAC THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[o_THM]);; + +add_linear_invariants [JOINPATHS_LINEAR_IMAGE];; + +let SIMPLE_PATH_TRANSLATION_EQ = prove + (`!a g:real^1->real^N. simple_path((\x. a + x) o g) <=> simple_path g`, + REPEAT GEN_TAC THEN REWRITE_TAC[simple_path; PATH_TRANSLATION_EQ] THEN + REWRITE_TAC[o_THM; VECTOR_ARITH `a + x:real^N = a + y <=> x = y`]);; + +add_translation_invariants [SIMPLE_PATH_TRANSLATION_EQ];; + +let SIMPLE_PATH_LINEAR_IMAGE_EQ = prove + (`!f:real^M->real^N g. + linear f /\ (!x y. f x = f y ==> x = y) + ==> (simple_path(f o g) <=> simple_path g)`, + REPEAT STRIP_TAC THEN REWRITE_TAC[simple_path; PATH_TRANSLATION_EQ] THEN + BINOP_TAC THENL [ASM_MESON_TAC[PATH_LINEAR_IMAGE_EQ]; ALL_TAC] THEN + REWRITE_TAC[o_THM] THEN ASM_MESON_TAC[]);; + +add_linear_invariants [SIMPLE_PATH_LINEAR_IMAGE_EQ];; + +let ARC_TRANSLATION_EQ = prove + (`!a g:real^1->real^N. arc((\x. a + x) o g) <=> arc g`, + REPEAT GEN_TAC THEN REWRITE_TAC[arc; PATH_TRANSLATION_EQ] THEN + REWRITE_TAC[o_THM; VECTOR_ARITH `a + x:real^N = a + y <=> x = y`]);; + +add_translation_invariants [ARC_TRANSLATION_EQ];; + +let ARC_LINEAR_IMAGE_EQ = prove + (`!f:real^M->real^N g. + linear f /\ (!x y. f x = f y ==> x = y) + ==> (arc(f o g) <=> arc g)`, + REPEAT STRIP_TAC THEN REWRITE_TAC[arc; PATH_TRANSLATION_EQ] THEN + BINOP_TAC THENL [ASM_MESON_TAC[PATH_LINEAR_IMAGE_EQ]; ALL_TAC] THEN + REWRITE_TAC[o_THM] THEN ASM_MESON_TAC[]);; + +add_linear_invariants [ARC_LINEAR_IMAGE_EQ];; + +(* ------------------------------------------------------------------------- *) +(* Basic lemmas about paths. *) +(* ------------------------------------------------------------------------- *) + +let ARC_IMP_SIMPLE_PATH = prove + (`!g. arc g ==> simple_path g`, + REWRITE_TAC[arc; simple_path] THEN MESON_TAC[]);; + +let ARC_IMP_PATH = prove + (`!g. arc g ==> path g`, + REWRITE_TAC[arc] THEN MESON_TAC[]);; + +let SIMPLE_PATH_IMP_PATH = prove + (`!g. simple_path g ==> path g`, + REWRITE_TAC[simple_path] THEN MESON_TAC[]);; + +let SIMPLE_PATH_CASES = prove + (`!g:real^1->real^N. simple_path g ==> arc g \/ pathfinish g = pathstart g`, + REWRITE_TAC[simple_path; arc; pathfinish; pathstart] THEN + REPEAT STRIP_TAC THEN + ASM_CASES_TAC `(g:real^1->real^N) (vec 0) = g(vec 1)` THEN + ASM_REWRITE_TAC[] THEN + MAP_EVERY X_GEN_TAC [`u:real^1`; `v:real^1`] THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`u:real^1`; `v:real^1`]) THEN + ASM_MESON_TAC[]);; + +let SIMPLE_PATH_IMP_ARC = prove + (`!g:real^1->real^N. + simple_path g /\ ~(pathfinish g = pathstart g) ==> arc g`, + MESON_TAC[SIMPLE_PATH_CASES]);; + +let ARC_DISTINCT_ENDS = prove + (`!g:real^1->real^N. arc g ==> ~(pathfinish g = pathstart g)`, + GEN_TAC THEN REWRITE_TAC[arc; pathfinish; pathstart] THEN + ONCE_REWRITE_TAC[TAUT `a /\ b /\ c ==> d <=> a /\ b /\ ~d ==> ~c`] THEN + DISCH_THEN(MATCH_MP_TAC o CONJUNCT2) THEN + REWRITE_TAC[GSYM DROP_EQ; IN_INTERVAL_1; DROP_VEC] THEN + CONV_TAC REAL_RAT_REDUCE_CONV);; + +let ARC_SIMPLE_PATH = prove + (`!g:real^1->real^N. + arc g <=> simple_path g /\ ~(pathfinish g = pathstart g)`, + MESON_TAC[SIMPLE_PATH_CASES; ARC_IMP_SIMPLE_PATH; ARC_DISTINCT_ENDS]);; + +let SIMPLE_PATH_EQ_ARC = prove + (`!g. ~(pathstart g = pathfinish g) ==> (simple_path g <=> arc g)`, + SIMP_TAC[ARC_SIMPLE_PATH]);; + +let PATH_IMAGE_NONEMPTY = prove + (`!g. ~(path_image g = {})`, + REWRITE_TAC[path_image; IMAGE_EQ_EMPTY; INTERVAL_EQ_EMPTY] THEN + SIMP_TAC[DIMINDEX_1; CONJ_ASSOC; LE_ANTISYM; UNWIND_THM1; VEC_COMPONENT; + ARITH; REAL_OF_NUM_LT]);; + +let PATHSTART_IN_PATH_IMAGE = prove + (`!g. (pathstart g) IN path_image g`, + GEN_TAC THEN REWRITE_TAC[pathstart; path_image] THEN + MATCH_MP_TAC FUN_IN_IMAGE THEN + REWRITE_TAC[IN_INTERVAL_1; DROP_VEC; REAL_POS]);; + +let PATHFINISH_IN_PATH_IMAGE = prove + (`!g. (pathfinish g) IN path_image g`, + GEN_TAC THEN REWRITE_TAC[pathfinish; path_image] THEN + MATCH_MP_TAC FUN_IN_IMAGE THEN + REWRITE_TAC[IN_INTERVAL_1; DROP_VEC] THEN REAL_ARITH_TAC);; + +let CONNECTED_PATH_IMAGE = prove + (`!g. path g ==> connected(path_image g)`, + REWRITE_TAC[path; path_image] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC CONNECTED_CONTINUOUS_IMAGE THEN + ASM_SIMP_TAC[CONVEX_CONNECTED; CONVEX_INTERVAL]);; + +let COMPACT_PATH_IMAGE = prove + (`!g. path g ==> compact(path_image g)`, + REWRITE_TAC[path; path_image] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC COMPACT_CONTINUOUS_IMAGE THEN + ASM_REWRITE_TAC[COMPACT_INTERVAL]);; + +let BOUNDED_PATH_IMAGE = prove + (`!g. path g ==> bounded(path_image g)`, + MESON_TAC[COMPACT_PATH_IMAGE; COMPACT_IMP_BOUNDED]);; + +let CLOSED_PATH_IMAGE = prove + (`!g. path g ==> closed(path_image g)`, + MESON_TAC[COMPACT_PATH_IMAGE; COMPACT_IMP_CLOSED]);; + +let CONNECTED_SIMPLE_PATH_IMAGE = prove + (`!g. simple_path g ==> connected(path_image g)`, + MESON_TAC[CONNECTED_PATH_IMAGE; SIMPLE_PATH_IMP_PATH]);; + +let COMPACT_SIMPLE_PATH_IMAGE = prove + (`!g. simple_path g ==> compact(path_image g)`, + MESON_TAC[COMPACT_PATH_IMAGE; SIMPLE_PATH_IMP_PATH]);; + +let BOUNDED_SIMPLE_PATH_IMAGE = prove + (`!g. simple_path g ==> bounded(path_image g)`, + MESON_TAC[BOUNDED_PATH_IMAGE; SIMPLE_PATH_IMP_PATH]);; + +let CLOSED_SIMPLE_PATH_IMAGE = prove + (`!g. simple_path g ==> closed(path_image g)`, + MESON_TAC[CLOSED_PATH_IMAGE; SIMPLE_PATH_IMP_PATH]);; + +let CONNECTED_ARC_IMAGE = prove + (`!g. arc g ==> connected(path_image g)`, + MESON_TAC[CONNECTED_PATH_IMAGE; ARC_IMP_PATH]);; + +let COMPACT_ARC_IMAGE = prove + (`!g. arc g ==> compact(path_image g)`, + MESON_TAC[COMPACT_PATH_IMAGE; ARC_IMP_PATH]);; + +let BOUNDED_ARC_IMAGE = prove + (`!g. arc g ==> bounded(path_image g)`, + MESON_TAC[BOUNDED_PATH_IMAGE; ARC_IMP_PATH]);; + +let CLOSED_ARC_IMAGE = prove + (`!g. arc g ==> closed(path_image g)`, + MESON_TAC[CLOSED_PATH_IMAGE; ARC_IMP_PATH]);; + +let PATHSTART_COMPOSE = prove + (`!f p. pathstart(f o p) = f(pathstart p)`, + REWRITE_TAC[pathstart; o_THM]);; + +let PATHFINISH_COMPOSE = prove + (`!f p. pathfinish(f o p) = f(pathfinish p)`, + REWRITE_TAC[pathfinish; o_THM]);; + +let PATH_IMAGE_COMPOSE = prove + (`!f p. path_image (f o p) = IMAGE f (path_image p)`, + REWRITE_TAC[path_image; IMAGE_o]);; + +let PATH_COMPOSE_JOIN = prove + (`!f p q. f o (p ++ q) = (f o p) ++ (f o q)`, + REWRITE_TAC[joinpaths; o_DEF; FUN_EQ_THM] THEN MESON_TAC[]);; + +let PATH_COMPOSE_REVERSEPATH = prove + (`!f p. f o reversepath p = reversepath(f o p)`, + REWRITE_TAC[reversepath; o_DEF; FUN_EQ_THM] THEN MESON_TAC[]);; + +let JOIN_PATHS_EQ = prove + (`!p q:real^1->real^N. + (!t. t IN interval[vec 0,vec 1] ==> p t = p' t) /\ + (!t. t IN interval[vec 0,vec 1] ==> q t = q' t) + ==> !t. t IN interval[vec 0,vec 1] ==> (p ++ q) t = (p' ++ q') t`, + REWRITE_TAC[joinpaths; IN_INTERVAL_1; DROP_VEC] THEN REPEAT STRIP_TAC THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + REWRITE_TAC[IN_INTERVAL_1; DROP_CMUL; DROP_SUB; DROP_VEC] THEN + ASM_REAL_ARITH_TAC);; + +let CARD_EQ_SIMPLE_PATH_IMAGE = prove + (`!g. simple_path g ==> path_image g =_c (:real)`, + SIMP_TAC[CONNECTED_CARD_EQ_IFF_NONTRIVIAL; CONNECTED_SIMPLE_PATH_IMAGE] THEN + GEN_TAC THEN REWRITE_TAC[simple_path; path_image] THEN MATCH_MP_TAC(SET_RULE + `(?u v. u IN s /\ v IN s /\ ~(u = a) /\ ~(v = a) /\ ~(u = v)) + ==> P /\ (!x y. x IN s /\ y IN s /\ f x = f y + ==> x = y \/ x = a /\ y = b \/ x = b /\ y = a) + ==> ~(?c. IMAGE f s SUBSET {c})`) THEN + MAP_EVERY EXISTS_TAC [`lift(&1 / &3)`; `lift(&1 / &2)`] THEN + REWRITE_TAC[IN_INTERVAL_1; LIFT_DROP; GSYM LIFT_NUM; LIFT_EQ] THEN + CONV_TAC REAL_RAT_REDUCE_CONV);; + +let INFINITE_SIMPLE_PATH_IMAGE = prove + (`!g. simple_path g ==> INFINITE(path_image g)`, + MESON_TAC[CARD_EQ_SIMPLE_PATH_IMAGE; INFINITE; FINITE_IMP_COUNTABLE; + UNCOUNTABLE_REAL; CARD_COUNTABLE_CONG]);; + +let CARD_EQ_ARC_IMAGE = prove + (`!g. arc g ==> path_image g =_c (:real)`, + MESON_TAC[ARC_IMP_SIMPLE_PATH; CARD_EQ_SIMPLE_PATH_IMAGE]);; + +let INFINITE_ARC_IMAGE = prove + (`!g. arc g ==> INFINITE(path_image g)`, + MESON_TAC[ARC_IMP_SIMPLE_PATH; INFINITE_SIMPLE_PATH_IMAGE]);; + +(* ------------------------------------------------------------------------- *) +(* Simple paths with the endpoints removed. *) +(* ------------------------------------------------------------------------- *) + +let SIMPLE_PATH_ENDLESS = prove + (`!c:real^1->real^N. + simple_path c + ==> path_image c DIFF {pathstart c,pathfinish c} = + IMAGE c (interval(vec 0,vec 1))`, + REWRITE_TAC[simple_path; path_image; pathstart; pathfinish] THEN + REWRITE_TAC[OPEN_CLOSED_INTERVAL_1; path] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC(SET_RULE + `(!x y. x IN s /\ y IN s /\ c x = c y + ==> x = y \/ x = a /\ y = b \/ x = b /\ y = a) /\ + a IN s /\ b IN s + ==> IMAGE c s DIFF {c a,c b} = IMAGE c (s DIFF {a,b})`) THEN + ASM_REWRITE_TAC[] THEN + REWRITE_TAC[IN_INTERVAL_1; DROP_VEC; REAL_POS; REAL_LE_REFL]);; + +let CONNECTED_SIMPLE_PATH_ENDLESS = prove + (`!c:real^1->real^N. + simple_path c + ==> connected(path_image c DIFF {pathstart c,pathfinish c})`, + REPEAT STRIP_TAC THEN ASM_SIMP_TAC[SIMPLE_PATH_ENDLESS] THEN + MATCH_MP_TAC CONNECTED_CONTINUOUS_IMAGE THEN + SIMP_TAC[CONVEX_INTERVAL; CONVEX_CONNECTED] THEN + MATCH_MP_TAC CONTINUOUS_ON_SUBSET THEN + EXISTS_TAC `interval[vec 0:real^1,vec 1]` THEN + RULE_ASSUM_TAC(REWRITE_RULE[simple_path; path]) THEN + ASM_REWRITE_TAC[INTERVAL_OPEN_SUBSET_CLOSED]);; + +let NONEMPTY_SIMPLE_PATH_ENDLESS = prove + (`!c:real^1->real^N. + simple_path c ==> ~(path_image c DIFF {pathstart c,pathfinish c} = {})`, + SIMP_TAC[SIMPLE_PATH_ENDLESS; IMAGE_EQ_EMPTY; INTERVAL_EQ_EMPTY_1] THEN + REWRITE_TAC[DROP_VEC] THEN REAL_ARITH_TAC);; + +(* ------------------------------------------------------------------------- *) +(* The operations on paths. *) +(* ------------------------------------------------------------------------- *) + +let JOINPATHS = prove + (`!g1 g2. pathfinish g1 = pathstart g2 + ==> g1 ++ g2 = \x. if drop x < &1 / &2 then g1(&2 % x) + else g2 (&2 % x - vec 1)`, + REWRITE_TAC[pathstart; pathfinish] THEN REPEAT STRIP_TAC THEN + REWRITE_TAC[joinpaths; FUN_EQ_THM] THEN + X_GEN_TAC `x:real^1` THEN ASM_CASES_TAC `drop x = &1 / &2` THENL + [FIRST_X_ASSUM(MP_TAC o AP_TERM `lift`) THEN + REWRITE_TAC[LIFT_DROP] THEN DISCH_THEN SUBST1_TAC THEN + REWRITE_TAC[LIFT_DROP; REAL_LE_REFL; GSYM LIFT_CMUL; REAL_LT_REFL] THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN + ASM_REWRITE_TAC[LIFT_NUM; VECTOR_SUB_REFL]; + REPEAT(COND_CASES_TAC THEN ASM_REWRITE_TAC[]) THEN ASM_REAL_ARITH_TAC]);; + +let REVERSEPATH_REVERSEPATH = prove + (`!g:real^1->real^N. reversepath(reversepath g) = g`, + REWRITE_TAC[reversepath; ETA_AX; + VECTOR_ARITH `vec 1 - (vec 1 - x):real^1 = x`]);; + +let PATHSTART_REVERSEPATH = prove + (`pathstart(reversepath g) = pathfinish g`, + REWRITE_TAC[pathstart; reversepath; pathfinish; VECTOR_SUB_RZERO]);; + +let PATHFINISH_REVERSEPATH = prove + (`pathfinish(reversepath g) = pathstart g`, + REWRITE_TAC[pathstart; reversepath; pathfinish; VECTOR_SUB_REFL]);; + +let PATHSTART_JOIN = prove + (`!g1 g2. pathstart(g1 ++ g2) = pathstart g1`, + REWRITE_TAC[joinpaths; pathstart; pathstart; DROP_VEC; VECTOR_MUL_RZERO] THEN + CONV_TAC REAL_RAT_REDUCE_CONV);; + +let PATHFINISH_JOIN = prove + (`!g1 g2. pathfinish(g1 ++ g2) = pathfinish g2`, + REPEAT GEN_TAC THEN REWRITE_TAC[joinpaths; pathfinish; DROP_VEC] THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN AP_TERM_TAC THEN VECTOR_ARITH_TAC);; + +let PATH_IMAGE_REVERSEPATH = prove + (`!g:real^1->real^N. path_image(reversepath g) = path_image g`, + SUBGOAL_THEN `!g:real^1->real^N. + path_image(reversepath g) SUBSET path_image g` + (fun th -> MESON_TAC[th; REVERSEPATH_REVERSEPATH; SUBSET_ANTISYM]) THEN + REWRITE_TAC[SUBSET; path_image; FORALL_IN_IMAGE] THEN + MAP_EVERY X_GEN_TAC [`g:real^1->real^N`; `x:real^1`] THEN + DISCH_TAC THEN REWRITE_TAC[reversepath; IN_IMAGE] THEN + EXISTS_TAC `vec 1 - x:real^1` THEN POP_ASSUM MP_TAC THEN + REWRITE_TAC[IN_INTERVAL_1; DROP_SUB; DROP_VEC] THEN REAL_ARITH_TAC);; + +let PATH_REVERSEPATH = prove + (`!g:real^1->real^N. path(reversepath g) <=> path g`, + SUBGOAL_THEN `!g:real^1->real^N. path g ==> path(reversepath g)` + (fun th -> MESON_TAC[th; REVERSEPATH_REVERSEPATH]) THEN + GEN_TAC THEN REWRITE_TAC[path; reversepath] THEN STRIP_TAC THEN + GEN_REWRITE_TAC LAND_CONV [GSYM o_DEF] THEN + MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN + SIMP_TAC[CONTINUOUS_ON_SUB; CONTINUOUS_ON_CONST; CONTINUOUS_ON_ID] THEN + MATCH_MP_TAC CONTINUOUS_ON_SUBSET THEN + EXISTS_TAC `interval[vec 0:real^1,vec 1]` THEN + ASM_REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; IN_INTERVAL_1] THEN + REWRITE_TAC[DROP_VEC; DROP_SUB] THEN REAL_ARITH_TAC);; + +let PATH_JOIN = prove + (`!g1 g2:real^1->real^N. + pathfinish g1 = pathstart g2 + ==> (path(g1 ++ g2) <=> path g1 /\ path g2)`, + REWRITE_TAC[path; pathfinish; pathstart] THEN + REPEAT STRIP_TAC THEN EQ_TAC THENL + [STRIP_TAC THEN CONJ_TAC THENL + [SUBGOAL_THEN + `(g1:real^1->real^N) = (\x. g1 (&2 % x)) o (\x. &1 / &2 % x)` + SUBST1_TAC THENL + [REWRITE_TAC[FUN_EQ_THM; o_THM] THEN GEN_TAC THEN AP_TERM_TAC THEN + VECTOR_ARITH_TAC; + ALL_TAC] THEN + MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN + SIMP_TAC[CONTINUOUS_ON_CMUL; CONTINUOUS_ON_ID] THEN + MATCH_MP_TAC CONTINUOUS_ON_EQ THEN + EXISTS_TAC `(g1 ++ g2):real^1->real^N` THEN CONJ_TAC THENL + [REWRITE_TAC[FORALL_IN_IMAGE; joinpaths; IN_INTERVAL_1; DROP_CMUL] THEN + SIMP_TAC[DROP_VEC; REAL_ARITH `&1 / &2 * x <= &1 / &2 <=> x <= &1`]; + ALL_TAC] THEN + MATCH_MP_TAC CONTINUOUS_ON_SUBSET THEN + EXISTS_TAC `interval[vec 0:real^1,vec 1]` THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; IN_INTERVAL_1; DROP_CMUL] THEN + REWRITE_TAC[DROP_VEC] THEN REAL_ARITH_TAC; + SUBGOAL_THEN + `(g2:real^1->real^N) = + (\x. g2 (&2 % x - vec 1)) o (\x. &1 / &2 % (x + vec 1))` + SUBST1_TAC THENL + [REWRITE_TAC[FUN_EQ_THM; o_THM] THEN GEN_TAC THEN AP_TERM_TAC THEN + VECTOR_ARITH_TAC; + ALL_TAC] THEN + MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN + SIMP_TAC[CONTINUOUS_ON_CMUL; CONTINUOUS_ON_ID; CONTINUOUS_ON_CONST; + CONTINUOUS_ON_ADD] THEN + MATCH_MP_TAC CONTINUOUS_ON_EQ THEN + EXISTS_TAC `(g1 ++ g2):real^1->real^N` THEN CONJ_TAC THENL + [REWRITE_TAC[FORALL_IN_IMAGE; joinpaths; IN_INTERVAL_1; DROP_CMUL] THEN + REWRITE_TAC[DROP_VEC; DROP_ADD; REAL_ARITH + `&1 / &2 * (x + &1) <= &1 / &2 <=> x <= &0`] THEN + SIMP_TAC[REAL_ARITH `&0 <= x ==> (x <= &0 <=> x = &0)`; LIFT_NUM; + VECTOR_MUL_ASSOC; GSYM LIFT_EQ; LIFT_DROP; GSYM LIFT_CMUL] THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN + ASM_REWRITE_TAC[VECTOR_ADD_LID; VECTOR_MUL_LID] THEN + REPEAT STRIP_TAC THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[VECTOR_ARITH `(x + vec 1) - vec 1 = x`]; + ALL_TAC] THEN + MATCH_MP_TAC CONTINUOUS_ON_SUBSET THEN + EXISTS_TAC `interval[vec 0:real^1,vec 1]` THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; IN_INTERVAL_1; DROP_CMUL] THEN + REWRITE_TAC[DROP_VEC; DROP_ADD] THEN REAL_ARITH_TAC]; + STRIP_TAC THEN + SUBGOAL_THEN `interval[vec 0,vec 1] = + interval[vec 0,lift(&1 / &2)] UNION + interval[lift(&1 / &2),vec 1]` + SUBST1_TAC THENL + [SIMP_TAC[EXTENSION; IN_UNION; IN_INTERVAL_1; LIFT_DROP; DROP_VEC] THEN + REAL_ARITH_TAC; + ALL_TAC] THEN + MATCH_MP_TAC CONTINUOUS_ON_UNION THEN REWRITE_TAC[CLOSED_INTERVAL] THEN + CONJ_TAC THEN MATCH_MP_TAC CONTINUOUS_ON_EQ THENL + [EXISTS_TAC `\x. (g1:real^1->real^N) (&2 % x)`; + EXISTS_TAC `\x. (g2:real^1->real^N) (&2 % x - vec 1)`] THEN + REWRITE_TAC[joinpaths] THEN SIMP_TAC[IN_INTERVAL_1; LIFT_DROP] THENL + [GEN_REWRITE_TAC LAND_CONV [GSYM o_DEF] THEN + MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN + SIMP_TAC[CONTINUOUS_ON_CMUL; CONTINUOUS_ON_ID] THEN + ONCE_REWRITE_TAC[VECTOR_ARITH `&2 % (x:real^1) = &2 % x + vec 0`] THEN + REWRITE_TAC[IMAGE_AFFINITY_INTERVAL] THEN + REWRITE_TAC[REAL_POS; INTERVAL_EQ_EMPTY_1; LIFT_DROP; DROP_VEC] THEN + REWRITE_TAC[GSYM LIFT_CMUL; VECTOR_ADD_RID; VECTOR_MUL_RZERO] THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN ASM_REWRITE_TAC[LIFT_NUM]; + ALL_TAC] THEN + CONJ_TAC THENL + [SIMP_TAC[REAL_ARITH `&1 / &2 <= x ==> (x <= &1 / &2 <=> x = &1 / &2)`; + GSYM LIFT_EQ; LIFT_DROP; GSYM LIFT_CMUL] THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN + RULE_ASSUM_TAC(REWRITE_RULE[pathstart; pathfinish]) THEN + ASM_REWRITE_TAC[LIFT_NUM] THEN + REPEAT STRIP_TAC THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[GSYM LIFT_CMUL] THEN CONV_TAC REAL_RAT_REDUCE_CONV THEN + REWRITE_TAC[LIFT_NUM; VECTOR_SUB_REFL]; + ALL_TAC] THEN + GEN_REWRITE_TAC LAND_CONV [GSYM o_DEF] THEN + MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN + SIMP_TAC[CONTINUOUS_ON_CMUL; CONTINUOUS_ON_SUB; CONTINUOUS_ON_CONST; + CONTINUOUS_ON_ID] THEN + ONCE_REWRITE_TAC[VECTOR_ARITH `&2 % x - vec 1 = &2 % x + --vec 1`] THEN + REWRITE_TAC[IMAGE_AFFINITY_INTERVAL] THEN + REWRITE_TAC[REAL_POS; INTERVAL_EQ_EMPTY_1; LIFT_DROP; DROP_VEC] THEN + REWRITE_TAC[GSYM LIFT_CMUL; VECTOR_ADD_RID; VECTOR_MUL_RZERO] THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN ASM_REWRITE_TAC[LIFT_NUM] THEN + ASM_REWRITE_TAC[VECTOR_ARITH `&2 % x + --x = x /\ x + --x = vec 0`]]);; + +let PATH_JOIN_IMP = prove + (`!g1 g2:real^1->real^N. + path g1 /\ path g2 /\ pathfinish g1 = pathstart g2 + ==> path(g1 ++ g2)`, + MESON_TAC[PATH_JOIN]);; + +let PATH_IMAGE_JOIN_SUBSET = prove + (`!g1 g2:real^1->real^N. + path_image(g1 ++ g2) SUBSET (path_image g1 UNION path_image g2)`, + REWRITE_TAC[path_image; FORALL_IN_IMAGE; SUBSET] THEN + GEN_TAC THEN GEN_TAC THEN X_GEN_TAC `x:real^1` THEN + REWRITE_TAC[IN_INTERVAL_1; IN_UNION; IN_IMAGE; DROP_VEC; joinpaths] THEN + STRIP_TAC THEN ASM_CASES_TAC `drop x <= &1 / &2` THEN ASM_REWRITE_TAC[] THENL + [DISJ1_TAC THEN EXISTS_TAC `&2 % x:real^1` THEN REWRITE_TAC[DROP_CMUL]; + DISJ2_TAC THEN EXISTS_TAC `&2 % x - vec 1:real^1` THEN + REWRITE_TAC[DROP_CMUL; DROP_SUB; DROP_VEC]] THEN + ASM_REAL_ARITH_TAC);; + +let SUBSET_PATH_IMAGE_JOIN = prove + (`!g1 g2:real^1->real^N s. + path_image g1 SUBSET s /\ path_image g2 SUBSET s + ==> path_image(g1 ++ g2) SUBSET s`, + MP_TAC PATH_IMAGE_JOIN_SUBSET THEN + REPEAT(MATCH_MP_TAC MONO_FORALL THEN GEN_TAC) THEN + SET_TAC[]);; + +let PATH_IMAGE_JOIN = prove + (`!g1 g2. pathfinish g1 = pathstart g2 + ==> path_image(g1 ++ g2) = path_image g1 UNION path_image g2`, + REWRITE_TAC[pathfinish; pathstart] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC SUBSET_ANTISYM THEN REWRITE_TAC[PATH_IMAGE_JOIN_SUBSET] THEN + REWRITE_TAC[path_image; SUBSET; FORALL_AND_THM; IN_UNION; TAUT + `a \/ b ==> c <=> (a ==> c) /\ (b ==> c)`] THEN + REWRITE_TAC[FORALL_IN_IMAGE; joinpaths] THEN + REWRITE_TAC[IN_INTERVAL_1; IN_IMAGE; DROP_VEC] THEN + CONJ_TAC THEN X_GEN_TAC `x:real^1` THEN REPEAT STRIP_TAC THENL + [EXISTS_TAC `(&1 / &2) % x:real^1` THEN + ASM_REWRITE_TAC[DROP_CMUL; REAL_ARITH + `&1 / &2 * x <= &1 / &2 <=> x <= &1`] THEN + REWRITE_TAC[VECTOR_MUL_ASSOC] THEN CONV_TAC REAL_RAT_REDUCE_CONV THEN + ASM_REWRITE_TAC[VECTOR_MUL_LID]; + EXISTS_TAC `(&1 / &2) % (x + vec 1):real^1` THEN + ASM_REWRITE_TAC[DROP_CMUL; DROP_ADD; DROP_VEC] THEN + REWRITE_TAC[VECTOR_MUL_ASSOC] THEN CONV_TAC REAL_RAT_REDUCE_CONV THEN + REWRITE_TAC[VECTOR_MUL_LID; VECTOR_ARITH `(x + vec 1) - vec 1 = x`] THEN + ASM_SIMP_TAC[REAL_ARITH `&0 <= x ==> (&1 / &2 * (x + &1) <= &1 / &2 <=> + x = &0)`] THEN + REWRITE_TAC[GSYM LIFT_EQ; LIFT_DROP; LIFT_NUM] THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[VECTOR_ADD_LID; DROP_VEC]] THEN + ASM_REAL_ARITH_TAC);; + +let NOT_IN_PATH_IMAGE_JOIN = prove + (`!g1 g2 x. ~(x IN path_image g1) /\ ~(x IN path_image g2) + ==> ~(x IN path_image(g1 ++ g2))`, + MESON_TAC[PATH_IMAGE_JOIN_SUBSET; SUBSET; IN_UNION]);; + +let ARC_REVERSEPATH = prove + (`!g. arc g ==> arc(reversepath g)`, + GEN_TAC THEN SIMP_TAC[arc; PATH_REVERSEPATH] THEN + REWRITE_TAC[arc; reversepath] THEN STRIP_TAC THEN + MAP_EVERY X_GEN_TAC [`x:real^1`; `y:real^1`] THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`vec 1 - x:real^1`; `vec 1 - y:real^1`]) THEN + ASM_REWRITE_TAC[] THEN REPEAT(POP_ASSUM MP_TAC) THEN + REWRITE_TAC[IN_INTERVAL_1; GSYM DROP_EQ; DROP_SUB; DROP_VEC] THEN + REAL_ARITH_TAC);; + +let SIMPLE_PATH_REVERSEPATH = prove + (`!g. simple_path g ==> simple_path (reversepath g)`, + GEN_TAC THEN SIMP_TAC[simple_path; PATH_REVERSEPATH] THEN + REWRITE_TAC[simple_path; reversepath] THEN STRIP_TAC THEN + MAP_EVERY X_GEN_TAC [`x:real^1`; `y:real^1`] THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`vec 1 - x:real^1`; `vec 1 - y:real^1`]) THEN + ASM_REWRITE_TAC[] THEN REPEAT(POP_ASSUM MP_TAC) THEN + REWRITE_TAC[IN_INTERVAL_1; GSYM DROP_EQ; DROP_SUB; DROP_VEC] THEN + REAL_ARITH_TAC);; + +let SIMPLE_PATH_JOIN_LOOP = prove + (`!g1 g2:real^1->real^N. + arc g1 /\ arc g2 /\ + pathfinish g1 = pathstart g2 /\ + pathfinish g2 = pathstart g1 /\ + (path_image g1 INTER path_image g2) SUBSET + {pathstart g1,pathstart g2} + ==> simple_path(g1 ++ g2)`, + REPEAT GEN_TAC THEN REWRITE_TAC[arc; simple_path] THEN + MATCH_MP_TAC(TAUT + `(a /\ b /\ c /\ d ==> f) /\ + (a' /\ b' /\ c /\ d /\ e ==> g) + ==> (a /\ a') /\ (b /\ b') /\ c /\ d /\ e ==> f /\ g`) THEN + CONJ_TAC THENL [MESON_TAC[PATH_JOIN]; ALL_TAC] THEN + REWRITE_TAC[arc; simple_path; SUBSET; IN_INTER; pathstart; + pathfinish; IN_INTERVAL_1; DROP_VEC; IN_INSERT; NOT_IN_EMPTY] THEN + DISCH_THEN(CONJUNCTS_THEN2 (LABEL_TAC "G1") MP_TAC) THEN + DISCH_THEN(CONJUNCTS_THEN2 (LABEL_TAC "G2") MP_TAC) THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC (LABEL_TAC "G0")) THEN + MATCH_MP_TAC DROP_WLOG_LE THEN CONJ_TAC THENL [MESON_TAC[]; ALL_TAC] THEN + REPEAT GEN_TAC THEN DISCH_TAC THEN REWRITE_TAC[joinpaths] THEN + MAP_EVERY ASM_CASES_TAC [`drop x <= &1 / &2`; `drop y <= &1 / &2`] THEN + ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THENL + [REMOVE_THEN "G1" (MP_TAC o SPECL [`&2 % x:real^1`; `&2 % y:real^1`]) THEN + ASM_REWRITE_TAC[DROP_CMUL; DROP_VEC; DROP_SUB] THEN + ANTS_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN + DISCH_THEN(fun th -> DISJ1_TAC THEN MP_TAC th) THEN VECTOR_ARITH_TAC; + ALL_TAC; + ASM_REAL_ARITH_TAC; + REMOVE_THEN "G2" (MP_TAC o SPECL + [`&2 % x:real^1 - vec 1`; `&2 % y:real^1 - vec 1`]) THEN + ASM_REWRITE_TAC[DROP_CMUL; DROP_VEC; DROP_SUB] THEN + ANTS_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN + DISCH_THEN(fun th -> DISJ1_TAC THEN MP_TAC th) THEN VECTOR_ARITH_TAC] THEN + REMOVE_THEN "G0" (MP_TAC o SPEC `(g1:real^1->real^N) (&2 % x)`) THEN + ANTS_TAC THENL + [CONJ_TAC THENL + [REWRITE_TAC[path_image; IN_IMAGE] THEN EXISTS_TAC `&2 % x:real^1` THEN + REWRITE_TAC[IN_INTERVAL_1; DROP_VEC; DROP_CMUL] THEN + ASM_REAL_ARITH_TAC; + ASM_REWRITE_TAC[path_image; IN_IMAGE] THEN + EXISTS_TAC `&2 % y:real^1 - vec 1` THEN + REWRITE_TAC[IN_INTERVAL_1; DROP_VEC; DROP_CMUL; DROP_SUB] THEN + ASM_REAL_ARITH_TAC]; + ALL_TAC] THEN + STRIP_TAC THENL + [DISJ2_TAC THEN DISJ1_TAC; + DISJ1_TAC THEN MATCH_MP_TAC EQ_TRANS THEN + EXISTS_TAC `&1 / &2 % vec 1:real^1`] THEN + MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN CONJ_TAC THENL + [SUBGOAL_THEN `&2 % x:real^1 = vec 0` MP_TAC THENL + [ALL_TAC; VECTOR_ARITH_TAC] THEN + REMOVE_THEN "G1" MATCH_MP_TAC; + DISCH_THEN SUBST_ALL_TAC THEN + RULE_ASSUM_TAC(REWRITE_RULE[VECTOR_MUL_RZERO]) THEN + UNDISCH_TAC `T` THEN REWRITE_TAC[] THEN + SUBGOAL_THEN `&2 % y:real^1 - vec 1 = vec 1` MP_TAC THENL + [ALL_TAC; VECTOR_ARITH_TAC] THEN + REMOVE_THEN "G2" MATCH_MP_TAC; + SUBGOAL_THEN `&2 % x:real^1 = vec 1` MP_TAC THENL + [ALL_TAC; VECTOR_ARITH_TAC] THEN + REMOVE_THEN "G1" MATCH_MP_TAC; + DISCH_THEN SUBST_ALL_TAC THEN + SUBGOAL_THEN `&2 % y:real^1 - vec 1 = vec 0` MP_TAC THENL + [ALL_TAC; VECTOR_ARITH_TAC] THEN + REMOVE_THEN "G2" MATCH_MP_TAC] THEN + (REWRITE_TAC[CONJ_ASSOC] THEN CONJ_TAC THENL + [ALL_TAC; ASM_MESON_TAC[]] THEN + ASM_REWRITE_TAC[DROP_CMUL; DROP_SUB; DROP_VEC] THEN + ASM_REAL_ARITH_TAC));; + +let ARC_JOIN = prove + (`!g1 g2:real^1->real^N. + arc g1 /\ arc g2 /\ + pathfinish g1 = pathstart g2 /\ + (path_image g1 INTER path_image g2) SUBSET {pathstart g2} + ==> arc(g1 ++ g2)`, + REPEAT GEN_TAC THEN REWRITE_TAC[arc; simple_path] THEN + MATCH_MP_TAC(TAUT + `(a /\ b /\ c /\ d ==> f) /\ + (a' /\ b' /\ c /\ d ==> g) + ==> (a /\ a') /\ (b /\ b') /\ c /\ d ==> f /\ g`) THEN + CONJ_TAC THENL [MESON_TAC[PATH_JOIN]; ALL_TAC] THEN + REWRITE_TAC[arc; simple_path; SUBSET; IN_INTER; pathstart; + pathfinish; IN_INTERVAL_1; DROP_VEC; IN_INSERT; NOT_IN_EMPTY] THEN + DISCH_THEN(CONJUNCTS_THEN2 (LABEL_TAC "G1") MP_TAC) THEN + DISCH_THEN(CONJUNCTS_THEN2 (LABEL_TAC "G2") MP_TAC) THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC (LABEL_TAC "G0")) THEN + MATCH_MP_TAC DROP_WLOG_LE THEN CONJ_TAC THENL [MESON_TAC[]; ALL_TAC] THEN + REPEAT GEN_TAC THEN DISCH_TAC THEN REWRITE_TAC[joinpaths] THEN + MAP_EVERY ASM_CASES_TAC [`drop x <= &1 / &2`; `drop y <= &1 / &2`] THEN + ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THENL + [REMOVE_THEN "G1" (MP_TAC o SPECL [`&2 % x:real^1`; `&2 % y:real^1`]) THEN + ASM_REWRITE_TAC[DROP_CMUL; DROP_VEC; DROP_SUB] THEN + ANTS_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN + VECTOR_ARITH_TAC; + ALL_TAC; + ASM_REAL_ARITH_TAC; + REMOVE_THEN "G2" (MP_TAC o SPECL + [`&2 % x:real^1 - vec 1`; `&2 % y:real^1 - vec 1`]) THEN + ASM_REWRITE_TAC[DROP_CMUL; DROP_VEC; DROP_SUB] THEN + ANTS_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN + VECTOR_ARITH_TAC] THEN + REMOVE_THEN "G0" (MP_TAC o SPEC `(g1:real^1->real^N) (&2 % x)`) THEN + ANTS_TAC THENL + [CONJ_TAC THENL + [REWRITE_TAC[path_image; IN_IMAGE] THEN EXISTS_TAC `&2 % x:real^1` THEN + REWRITE_TAC[IN_INTERVAL_1; DROP_VEC; DROP_CMUL] THEN + ASM_REAL_ARITH_TAC; + ASM_REWRITE_TAC[path_image; IN_IMAGE] THEN + EXISTS_TAC `&2 % y:real^1 - vec 1` THEN + REWRITE_TAC[IN_INTERVAL_1; DROP_VEC; DROP_CMUL; DROP_SUB] THEN + ASM_REAL_ARITH_TAC]; + ALL_TAC] THEN + STRIP_TAC THEN + SUBGOAL_THEN `x:real^1 = &1 / &2 % vec 1` SUBST_ALL_TAC THENL + [SUBGOAL_THEN `&2 % x:real^1 = vec 1` MP_TAC THENL + [ALL_TAC; VECTOR_ARITH_TAC] THEN + REMOVE_THEN "G1" MATCH_MP_TAC; + SUBGOAL_THEN `&2 % y:real^1 - vec 1 = vec 0` MP_TAC THENL + [ALL_TAC; VECTOR_ARITH_TAC] THEN + REMOVE_THEN "G2" MATCH_MP_TAC] THEN + (REWRITE_TAC[CONJ_ASSOC] THEN CONJ_TAC THENL + [ALL_TAC; ASM_MESON_TAC[]] THEN + ASM_REWRITE_TAC[DROP_CMUL; DROP_SUB; DROP_VEC] THEN + ASM_REAL_ARITH_TAC));; + +let REVERSEPATH_JOINPATHS = prove + (`!g1 g2. pathfinish g1 = pathstart g2 + ==> reversepath(g1 ++ g2) = reversepath g2 ++ reversepath g1`, + REPEAT GEN_TAC THEN + REWRITE_TAC[reversepath; joinpaths; pathfinish; pathstart; FUN_EQ_THM] THEN + DISCH_TAC THEN X_GEN_TAC `t:real^1` THEN + REWRITE_TAC[DROP_VEC; DROP_SUB; REAL_ARITH + `&1 - x <= &1 / &2 <=> &1 / &2 <= x`] THEN + ASM_CASES_TAC `t = lift(&1 / &2)` THENL + [ASM_REWRITE_TAC[LIFT_DROP; REAL_LE_REFL; GSYM LIFT_NUM; GSYM LIFT_SUB; + GSYM LIFT_CMUL] THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN ASM_REWRITE_TAC[LIFT_NUM]; + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE RAND_CONV [GSYM DROP_EQ]) THEN + REWRITE_TAC[LIFT_DROP] THEN DISCH_TAC THEN + ASM_SIMP_TAC[REAL_ARITH + `~(x = &1 / &2) ==> (&1 / &2 <= x <=> ~(x <= &1 / &2))`] THEN + ASM_CASES_TAC `drop t <= &1 / &2` THEN ASM_REWRITE_TAC[] THEN + AP_TERM_TAC THEN REWRITE_TAC[VECTOR_SUB_LDISTRIB] THEN VECTOR_ARITH_TAC]);; + +(* ------------------------------------------------------------------------- *) +(* Some reversed and "if and only if" versions of joining theorems. *) +(* ------------------------------------------------------------------------- *) + +let PATH_JOIN_PATH_ENDS = prove + (`!g1 g2:real^1->real^N. + path g2 /\ path(g1 ++ g2) ==> pathfinish g1 = pathstart g2`, + REPEAT GEN_TAC THEN DISJ_CASES_TAC(NORM_ARITH + `pathfinish g1:real^N = pathstart g2 \/ + &0 < dist(pathfinish g1,pathstart g2)`) THEN + ASM_REWRITE_TAC[path; continuous_on; joinpaths] THEN + RULE_ASSUM_TAC(REWRITE_RULE[pathstart; pathfinish]) THEN + REWRITE_TAC[pathstart; pathfinish] THEN + ABBREV_TAC `e = dist((g1:real^1->real^N)(vec 1),g2(vec 0:real^1))` THEN + DISCH_THEN(CONJUNCTS_THEN2 + (MP_TAC o SPEC `vec 0:real^1`) (MP_TAC o SPEC `lift(&1 / &2)`)) THEN + REWRITE_TAC[ENDS_IN_UNIT_INTERVAL; LIFT_DROP; REAL_LE_REFL] THEN + REWRITE_TAC[GSYM LIFT_CMUL; IN_INTERVAL_1; DROP_VEC; LIFT_DROP] THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN REWRITE_TAC[LIFT_NUM] THEN + DISCH_THEN(MP_TAC o SPEC `e / &2`) THEN ASM_REWRITE_TAC[REAL_HALF] THEN + DISCH_THEN(X_CHOOSE_THEN `d1:real` + (CONJUNCTS_THEN2 ASSUME_TAC (LABEL_TAC "1"))) THEN + DISCH_THEN(MP_TAC o SPEC `e / &2`) THEN ASM_REWRITE_TAC[REAL_HALF] THEN + DISCH_THEN(X_CHOOSE_THEN `d2:real` + (CONJUNCTS_THEN2 ASSUME_TAC (LABEL_TAC "2"))) THEN + REMOVE_THEN "2" (MP_TAC o SPEC `lift(min (&1 / &2) (min d1 d2) / &2)`) THEN + REWRITE_TAC[LIFT_DROP; DIST_LIFT; DIST_0; NORM_REAL; GSYM drop] THEN + ANTS_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN + REMOVE_THEN "1" (MP_TAC o SPEC + `lift(&1 / &2 + min (&1 / &2) (min d1 d2) / &4)`) THEN + REWRITE_TAC[LIFT_DROP; DIST_LIFT] THEN + ANTS_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN + COND_CASES_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN + REWRITE_TAC[GSYM LIFT_CMUL; LIFT_ADD; REAL_ADD_LDISTRIB] THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN REWRITE_TAC[LIFT_NUM] THEN + REWRITE_TAC[VECTOR_ADD_SUB; REAL_ARITH `&2 * x / &4 = x / &2`] THEN + REPEAT(POP_ASSUM MP_TAC) THEN NORM_ARITH_TAC);; + +let PATH_JOIN_EQ = prove + (`!g1 g2:real^1->real^N. + path g1 /\ path g2 + ==> (path(g1 ++ g2) <=> pathfinish g1 = pathstart g2)`, + MESON_TAC[PATH_JOIN_PATH_ENDS; PATH_JOIN_IMP]);; + +let SIMPLE_PATH_JOIN_IMP = prove + (`!g1 g2:real^1->real^N. + simple_path(g1 ++ g2) /\ pathfinish g1 = pathstart g2 + ==> arc g1 /\ arc g2 /\ + path_image g1 INTER path_image g2 SUBSET + {pathstart g1, pathstart g2}`, + REPEAT GEN_TAC THEN + ASM_CASES_TAC `path(g1:real^1->real^N) /\ path(g2:real^1->real^N)` THENL + [ALL_TAC; ASM_MESON_TAC[PATH_JOIN; SIMPLE_PATH_IMP_PATH]] THEN + REWRITE_TAC[simple_path; pathstart; pathfinish; arc] THEN + STRIP_TAC THEN REPEAT CONJ_TAC THEN ASM_REWRITE_TAC[] THENL + [MAP_EVERY X_GEN_TAC [`x:real^1`; `y:real^1`] THEN + REWRITE_TAC[IN_INTERVAL_1; DROP_VEC] THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPECL + [`&1 / &2 % x:real^1`; `&1 / &2 % y:real^1`]) THEN + REWRITE_TAC[IN_INTERVAL_1; DROP_VEC; joinpaths; DROP_CMUL] THEN + REPEAT(COND_CASES_TAC THEN TRY ASM_REAL_ARITH_TAC) THEN + REWRITE_TAC[VECTOR_MUL_ASSOC] THEN CONV_TAC REAL_RAT_REDUCE_CONV THEN + ASM_REWRITE_TAC[GSYM DROP_EQ; DROP_CMUL; VECTOR_MUL_LID; DROP_VEC] THEN + ASM_REAL_ARITH_TAC; + MAP_EVERY X_GEN_TAC [`x:real^1`; `y:real^1`] THEN + REWRITE_TAC[IN_INTERVAL_1; DROP_VEC] THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPECL + [`&1 / &2 % (x + vec 1):real^1`; `&1 / &2 % (y + vec 1):real^1`]) THEN + ASM_SIMP_TAC[JOINPATHS; pathstart; pathfinish] THEN + REWRITE_TAC[IN_INTERVAL_1; DROP_VEC; DROP_ADD; DROP_CMUL] THEN + REPEAT(COND_CASES_TAC THEN TRY ASM_REAL_ARITH_TAC) THEN + REWRITE_TAC[VECTOR_MUL_ASSOC] THEN CONV_TAC REAL_RAT_REDUCE_CONV THEN + ASM_REWRITE_TAC[VECTOR_MUL_LID; VECTOR_ARITH `(a + b) - b:real^N = a`] THEN + ASM_REWRITE_TAC[GSYM DROP_EQ; DROP_CMUL; VECTOR_MUL_LID; DROP_VEC; + DROP_ADD] THEN + ASM_REAL_ARITH_TAC; + REWRITE_TAC[SET_RULE + `s INTER t SUBSET u <=> !x. x IN s ==> x IN t ==> x IN u`] THEN + REWRITE_TAC[path_image; FORALL_IN_IMAGE] THEN X_GEN_TAC `x:real^1` THEN + REWRITE_TAC[IN_INTERVAL_1; DROP_VEC] THEN STRIP_TAC THEN + REWRITE_TAC[IN_IMAGE; LEFT_IMP_EXISTS_THM] THEN X_GEN_TAC `y:real^1` THEN + REWRITE_TAC[IN_INTERVAL_1; DROP_VEC] THEN STRIP_TAC THEN + SUBST1_TAC(SYM(ASSUME + `(g1:real^1->real^N)(vec 1) = g2(vec 0:real^1)`)) THEN + MATCH_MP_TAC(SET_RULE `x = a \/ x = b ==> f x IN {f a,f b}`) THEN + FIRST_X_ASSUM(MP_TAC o SPECL + [`&1 / &2 % x:real^1`; `&1 / &2 % (y + vec 1):real^1`]) THEN + ANTS_TAC THENL + [REWRITE_TAC[IN_INTERVAL_1; DROP_VEC; DROP_CMUL; DROP_ADD] THEN + REPEAT(CONJ_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC]) THEN + GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [joinpaths] THEN + ASM_SIMP_TAC[JOINPATHS; pathstart; pathfinish] THEN + REWRITE_TAC[DROP_ADD; DROP_CMUL; DROP_VEC] THEN + REPEAT(COND_CASES_TAC THEN TRY ASM_REAL_ARITH_TAC) THEN + REWRITE_TAC[VECTOR_ARITH `&2 % &1 / &2 % x:real^N = x`] THEN + ASM_REWRITE_TAC[VECTOR_ARITH `(a + b) - b:real^N = a`]; + REWRITE_TAC[GSYM DROP_EQ; DROP_CMUL; DROP_ADD; DROP_VEC] THEN + ASM_REAL_ARITH_TAC]]);; + +let SIMPLE_PATH_JOIN_LOOP_EQ = prove + (`!g1 g2:real^1->real^N. + pathfinish g2 = pathstart g1 /\ + pathfinish g1 = pathstart g2 + ==> (simple_path(g1 ++ g2) <=> + arc g1 /\ arc g2 /\ + path_image g1 INTER path_image g2 SUBSET + {pathstart g1, pathstart g2})`, + MESON_TAC[SIMPLE_PATH_JOIN_IMP; SIMPLE_PATH_JOIN_LOOP]);; + +let ARC_JOIN_EQ = prove + (`!g1 g2:real^1->real^N. + pathfinish g1 = pathstart g2 + ==> (arc(g1 ++ g2) <=> + arc g1 /\ arc g2 /\ + path_image g1 INTER path_image g2 SUBSET {pathstart g2})`, + REPEAT STRIP_TAC THEN EQ_TAC THEN ASM_SIMP_TAC[ARC_JOIN] THEN + GEN_REWRITE_TAC LAND_CONV [ARC_SIMPLE_PATH] THEN + REWRITE_TAC[PATHFINISH_JOIN; PATHSTART_JOIN] THEN STRIP_TAC THEN + MP_TAC(ISPECL [`g1:real^1->real^N`; `g2:real^1->real^N`] + SIMPLE_PATH_JOIN_IMP) THEN + ASM_REWRITE_TAC[] THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + SUBGOAL_THEN `~((pathstart g1:real^N) IN path_image g2)` + (fun th -> MP_TAC th THEN ASM SET_TAC[]) THEN + REWRITE_TAC[path_image; IN_IMAGE; IN_INTERVAL_1; DROP_VEC] THEN + DISCH_THEN(X_CHOOSE_THEN `u:real^1` STRIP_ASSUME_TAC) THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [simple_path]) THEN + DISCH_THEN(MP_TAC o SPECL [`vec 0:real^1`; `lift(&1 / &2) + inv(&2) % u`] o + CONJUNCT2) THEN + REWRITE_TAC[GSYM DROP_EQ; IN_INTERVAL_1; DROP_ADD; DROP_VEC; + DROP_CMUL; LIFT_DROP; joinpaths] THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN + ASM_SIMP_TAC[REAL_LT_IMP_LE; REAL_LT_IMP_NZ; + REAL_ARITH `&0 <= x ==> &0 < &1 / &2 + &1 / &2 * x`] THEN + REWRITE_TAC[REAL_ARITH `&1 / &2 + &1 / &2 * u = &1 <=> u = &1`] THEN + ASM_SIMP_TAC[REAL_ARITH + `&0 <= u ==> (&1 / &2 + &1 / &2 * u <= &1 / &2 <=> u = &0)`] THEN + RULE_ASSUM_TAC(REWRITE_RULE[pathstart; pathfinish]) THEN + ASM_REWRITE_TAC[VECTOR_MUL_RZERO] THEN + ASM_SIMP_TAC[REAL_ARITH `u <= &1 ==> &1 / &2 + &1 / &2 * u <= &1`] THEN + REWRITE_TAC[GSYM LIFT_EQ; LIFT_NUM; LIFT_DROP] THEN COND_CASES_TAC THENL + [ASM_REWRITE_TAC[VECTOR_MUL_RZERO; VECTOR_ADD_RID; GSYM LIFT_CMUL] THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN REWRITE_TAC[LIFT_NUM] THEN + ASM_REWRITE_TAC[VEC_EQ] THEN ARITH_TAC; + REWRITE_TAC[VECTOR_ADD_LDISTRIB; GSYM LIFT_CMUL] THEN + REWRITE_TAC[VECTOR_MUL_ASSOC] THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN + REWRITE_TAC[LIFT_NUM; VECTOR_MUL_LID; VECTOR_ADD_SUB] THEN + ASM_MESON_TAC[]]);; + +let ARC_JOIN_EQ_ALT = prove + (`!g1 g2:real^1->real^N. + pathfinish g1 = pathstart g2 + ==> (arc(g1 ++ g2) <=> + arc g1 /\ arc g2 /\ + path_image g1 INTER path_image g2 = {pathstart g2})`, + REPEAT STRIP_TAC THEN ASM_SIMP_TAC[ARC_JOIN_EQ] THEN + MP_TAC(ISPEC `g1:real^1->real^N` PATHFINISH_IN_PATH_IMAGE) THEN + MP_TAC(ISPEC `g2:real^1->real^N` PATHSTART_IN_PATH_IMAGE) THEN + ASM SET_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* Reassociating a joined path doesn't matter for various properties. *) +(* ------------------------------------------------------------------------- *) + +let PATH_ASSOC = prove + (`!p q r:real^1->real^N. + pathfinish p = pathstart q /\ pathfinish q = pathstart r + ==> (path(p ++ (q ++ r)) <=> path((p ++ q) ++ r))`, + SIMP_TAC[PATH_JOIN; PATHSTART_JOIN; PATHFINISH_JOIN] THEN CONV_TAC TAUT);; + +let SIMPLE_PATH_ASSOC = prove + (`!p q r:real^1->real^N. + pathfinish p = pathstart q /\ pathfinish q = pathstart r + ==> (simple_path(p ++ (q ++ r)) <=> simple_path((p ++ q) ++ r))`, + REPEAT STRIP_TAC THEN + ASM_CASES_TAC `pathstart(p:real^1->real^N) = pathfinish r` THENL + [ALL_TAC; + ASM_SIMP_TAC[SIMPLE_PATH_EQ_ARC; PATHSTART_JOIN; PATHFINISH_JOIN]] THEN + ASM_SIMP_TAC[SIMPLE_PATH_JOIN_LOOP_EQ; PATHSTART_JOIN; PATHFINISH_JOIN; + ARC_JOIN_EQ; PATH_IMAGE_JOIN] THEN + MAP_EVERY ASM_CASES_TAC + [`arc(p:real^1->real^N)`; `arc(q:real^1->real^N)`; + `arc(r:real^1->real^N)`] THEN + ASM_REWRITE_TAC[UNION_OVER_INTER; UNION_SUBSET; + ONCE_REWRITE_RULE[INTER_COMM] UNION_OVER_INTER] THEN + REPEAT(FIRST_X_ASSUM(MP_TAC o MATCH_MP ARC_DISTINCT_ENDS)) THEN + MAP_EVERY (fun t -> MP_TAC(ISPEC t PATHSTART_IN_PATH_IMAGE) THEN + MP_TAC(ISPEC t PATHFINISH_IN_PATH_IMAGE)) + [`p:real^1->real^N`; `q:real^1->real^N`; `r:real^1->real^N`] THEN + ASM SET_TAC[]);; + +let ARC_ASSOC = prove + (`!p q r:real^1->real^N. + pathfinish p = pathstart q /\ pathfinish q = pathstart r + ==> (arc(p ++ (q ++ r)) <=> arc((p ++ q) ++ r))`, + SIMP_TAC[ARC_SIMPLE_PATH; SIMPLE_PATH_ASSOC] THEN + SIMP_TAC[PATHSTART_JOIN; PATHFINISH_JOIN]);; + +(* ------------------------------------------------------------------------- *) +(* In the case of a loop, neither does symmetry. *) +(* ------------------------------------------------------------------------- *) + +let PATH_SYM = prove + (`!p q. pathfinish p = pathstart q /\ pathfinish q = pathstart p + ==> (path(p ++ q) <=> path(q ++ p))`, + SIMP_TAC[PATH_JOIN; CONJ_ACI]);; + +let SIMPLE_PATH_SYM = prove + (`!p q. pathfinish p = pathstart q /\ pathfinish q = pathstart p + ==> (simple_path(p ++ q) <=> simple_path(q ++ p))`, + SIMP_TAC[SIMPLE_PATH_JOIN_LOOP_EQ; INTER_ACI; CONJ_ACI; INSERT_AC]);; + +let PATH_IMAGE_SYM = prove + (`!p q. pathfinish p = pathstart q /\ pathfinish q = pathstart p + ==> path_image(p ++ q) = path_image(q ++ p)`, + SIMP_TAC[PATH_IMAGE_JOIN; UNION_ACI]);; + +(* ------------------------------------------------------------------------- *) +(* Reparametrizing a closed curve to start at some chosen point. *) +(* ------------------------------------------------------------------------- *) + +let shiftpath = new_definition + `shiftpath a (f:real^1->real^N) = + \x. if drop(a + x) <= &1 then f(a + x) + else f(a + x - vec 1)`;; + +let SHIFTPATH_TRANSLATION = prove + (`!a t g. shiftpath t ((\x. a + x) o g) = (\x. a + x) o shiftpath t g`, + REWRITE_TAC[FUN_EQ_THM; shiftpath; o_THM] THEN MESON_TAC[]);; + +add_translation_invariants [SHIFTPATH_TRANSLATION];; + +let SHIFTPATH_LINEAR_IMAGE = prove + (`!f t g. linear f ==> shiftpath t (f o g) = f o shiftpath t g`, + REWRITE_TAC[FUN_EQ_THM; shiftpath; o_THM] THEN MESON_TAC[]);; + +add_linear_invariants [SHIFTPATH_LINEAR_IMAGE];; + +let PATHSTART_SHIFTPATH = prove + (`!a g. drop a <= &1 ==> pathstart(shiftpath a g) = g(a)`, + SIMP_TAC[pathstart; shiftpath; VECTOR_ADD_RID]);; + +let PATHFINISH_SHIFTPATH = prove + (`!a g. &0 <= drop a /\ pathfinish g = pathstart g + ==> pathfinish(shiftpath a g) = g(a)`, + SIMP_TAC[pathfinish; shiftpath; pathstart; DROP_ADD; DROP_VEC] THEN + REWRITE_TAC[VECTOR_ARITH `a + vec 1 - vec 1 = a`] THEN + ASM_SIMP_TAC[REAL_ARITH `&0 <= x ==> (x + &1 <= &1 <=> x = &0)`] THEN + SIMP_TAC[DROP_EQ_0; VECTOR_ADD_LID] THEN MESON_TAC[]);; + +let ENDPOINTS_SHIFTPATH = prove + (`!a g. pathfinish g = pathstart g /\ a IN interval[vec 0,vec 1] + ==> pathfinish(shiftpath a g) = g a /\ + pathstart(shiftpath a g) = g a`, + SIMP_TAC[IN_INTERVAL_1; DROP_VEC; + PATHSTART_SHIFTPATH; PATHFINISH_SHIFTPATH]);; + +let CLOSED_SHIFTPATH = prove + (`!a g. pathfinish g = pathstart g /\ a IN interval[vec 0,vec 1] + ==> pathfinish(shiftpath a g) = pathstart(shiftpath a g)`, + SIMP_TAC[IN_INTERVAL_1; PATHSTART_SHIFTPATH; PATHFINISH_SHIFTPATH; + DROP_VEC]);; + +let PATH_SHIFTPATH = prove + (`!g a. path g /\ pathfinish g:real^N = pathstart g /\ + a IN interval[vec 0,vec 1] + ==> path(shiftpath a g)`, + REWRITE_TAC[shiftpath; path] THEN REPEAT STRIP_TAC THEN + SUBGOAL_THEN + `interval[vec 0,vec 1] = interval[vec 0,vec 1 - a:real^1] UNION + interval[vec 1 - a,vec 1]` + SUBST1_TAC THENL + [REWRITE_TAC[EXTENSION; IN_UNION; IN_INTERVAL_1] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_INTERVAL_1]) THEN + REWRITE_TAC[DROP_SUB; DROP_VEC] THEN REAL_ARITH_TAC; + ALL_TAC] THEN + MATCH_MP_TAC CONTINUOUS_ON_UNION THEN REWRITE_TAC[CLOSED_INTERVAL] THEN + CONJ_TAC THEN MATCH_MP_TAC CONTINUOUS_ON_EQ THENL + [EXISTS_TAC `(\x. g(a + x)):real^1->real^N` THEN + REWRITE_TAC[IN_INTERVAL_1; DROP_ADD; DROP_VEC; DROP_SUB] THEN + SIMP_TAC[REAL_ARITH `a + x <= &1 <=> x <= &1 - a`]; + EXISTS_TAC `(\x. g(a + x - vec 1)):real^1->real^N` THEN + REWRITE_TAC[IN_INTERVAL_1; DROP_ADD; DROP_VEC; DROP_SUB] THEN + SIMP_TAC[REAL_ARITH `&1 - a <= x ==> (a + x <= &1 <=> a + x = &1)`] THEN + ONCE_REWRITE_TAC[COND_RAND] THEN + REWRITE_TAC[VECTOR_ARITH `a + x - vec 1 = (a + x) - vec 1`] THEN + RULE_ASSUM_TAC(REWRITE_RULE[pathstart; pathfinish]) THEN + ASM_SIMP_TAC[GSYM LIFT_EQ; LIFT_ADD; LIFT_NUM; LIFT_DROP] THEN + REWRITE_TAC[VECTOR_SUB_REFL; COND_ID]] THEN + MATCH_MP_TAC(REWRITE_RULE[o_DEF] CONTINUOUS_ON_COMPOSE) THEN + SIMP_TAC[CONTINUOUS_ON_ADD; CONTINUOUS_ON_CONST; CONTINUOUS_ON_ID; + CONTINUOUS_ON_SUB] THEN + MATCH_MP_TAC CONTINUOUS_ON_SUBSET THEN + EXISTS_TAC `interval[vec 0:real^1,vec 1]` THEN + ASM_REWRITE_TAC[SUBSET; FORALL_IN_IMAGE] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_INTERVAL_1]) THEN + REWRITE_TAC[IN_INTERVAL_1; DROP_SUB; DROP_VEC; DROP_ADD] THEN + REAL_ARITH_TAC);; + +let SHIFTPATH_SHIFTPATH = prove + (`!g a x. a IN interval[vec 0,vec 1] /\ pathfinish g = pathstart g /\ + x IN interval[vec 0,vec 1] + ==> shiftpath (vec 1 - a) (shiftpath a g) x = g x`, + REWRITE_TAC[shiftpath; pathfinish; pathstart] THEN + REWRITE_TAC[DROP_ADD; DROP_SUB; DROP_VEC] THEN + REPEAT STRIP_TAC THEN REPEAT(COND_CASES_TAC THEN ASM_REWRITE_TAC[]) THEN + REPEAT(FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_INTERVAL_1])) THEN + REWRITE_TAC[DROP_VEC] THEN REPEAT STRIP_TAC THENL + [ALL_TAC; + AP_TERM_TAC THEN VECTOR_ARITH_TAC; + AP_TERM_TAC THEN VECTOR_ARITH_TAC; + ASM_REAL_ARITH_TAC] THEN + SUBGOAL_THEN `x:real^1 = vec 0` SUBST1_TAC THENL + [REWRITE_TAC[GSYM DROP_EQ; DROP_VEC] THEN + ASM_REAL_ARITH_TAC; + ASM_REWRITE_TAC[VECTOR_ARITH `a + vec 1 - a + vec 0:real^1 = vec 1`]]);; + +let PATH_IMAGE_SHIFTPATH = prove + (`!a g:real^1->real^N. + a IN interval[vec 0,vec 1] /\ pathfinish g = pathstart g + ==> path_image(shiftpath a g) = path_image g`, + REWRITE_TAC[IN_INTERVAL_1; pathfinish; pathstart] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THEN + REWRITE_TAC[path_image; shiftpath; FORALL_IN_IMAGE; SUBSET] THEN + REWRITE_TAC[IN_IMAGE] THEN REPEAT STRIP_TAC THEN + REPEAT COND_CASES_TAC THEN ASM_REWRITE_TAC[IN_IMAGE] THENL + [EXISTS_TAC `a + x:real^1`; + EXISTS_TAC `a + x - vec 1:real^1`; + ALL_TAC] THEN + REPEAT(POP_ASSUM MP_TAC) THEN + REWRITE_TAC[IN_INTERVAL_1; DROP_VEC; DROP_SUB; DROP_ADD] THEN + TRY REAL_ARITH_TAC THEN REPEAT STRIP_TAC THEN + ASM_CASES_TAC `drop a <= drop x` THENL + [EXISTS_TAC `x - a:real^1` THEN + REWRITE_TAC[VECTOR_ARITH `a + x - a:real^1 = x`; DROP_SUB] THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN + ASM_REAL_ARITH_TAC; + EXISTS_TAC `vec 1 + x - a:real^1` THEN + REWRITE_TAC[VECTOR_ARITH `a + (v + x - a) - v:real^1 = x`] THEN + REWRITE_TAC[DROP_ADD; DROP_SUB; DROP_VEC] THEN + ASM_CASES_TAC `x:real^1 = vec 0` THEN + ASM_REWRITE_TAC[VECTOR_ARITH `a + v + x - a:real^1 = v + x`] THEN + ASM_REWRITE_TAC[VECTOR_ADD_RID; DROP_VEC; COND_ID] THEN + ASM_REWRITE_TAC[REAL_ARITH `a + &1 + x - a <= &1 <=> x <= &0`] THEN + REPEAT(POP_ASSUM MP_TAC) THEN REWRITE_TAC[GSYM DROP_EQ; DROP_VEC] THEN + TRY(COND_CASES_TAC THEN POP_ASSUM MP_TAC) THEN REWRITE_TAC[] THEN + REAL_ARITH_TAC]);; + +let SIMPLE_PATH_SHIFTPATH = prove + (`!g a. simple_path g /\ pathfinish g = pathstart g /\ + a IN interval[vec 0,vec 1] + ==> simple_path(shiftpath a g)`, + REPEAT GEN_TAC THEN REWRITE_TAC[simple_path] THEN + MATCH_MP_TAC(TAUT + `(a /\ c /\ d ==> e) /\ (b /\ c /\ d ==> f) + ==> (a /\ b) /\ c /\ d ==> e /\ f`) THEN + CONJ_TAC THENL [MESON_TAC[PATH_SHIFTPATH]; ALL_TAC] THEN + REWRITE_TAC[simple_path; shiftpath; IN_INTERVAL_1; DROP_VEC; + DROP_ADD; DROP_SUB] THEN + REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN + ONCE_REWRITE_TAC[TAUT `a /\ b /\ c ==> d <=> c ==> a /\ b ==> d`] THEN + STRIP_TAC THEN REPEAT GEN_TAC THEN + REPEAT(COND_CASES_TAC THEN ASM_REWRITE_TAC[]) THEN + DISCH_THEN(fun th -> FIRST_X_ASSUM(MP_TAC o C MATCH_MP th)) THEN + REPEAT(POP_ASSUM MP_TAC) THEN + REWRITE_TAC[DROP_ADD; DROP_SUB; DROP_VEC; GSYM DROP_EQ] THEN + REAL_ARITH_TAC);; + +(* ------------------------------------------------------------------------- *) +(* Choosing a sub-path of an existing path. *) +(* ------------------------------------------------------------------------- *) + +let subpath = new_definition + `subpath u v g = \x. g(u + drop(v - u) % x)`;; + +let SUBPATH_SCALING_LEMMA = prove + (`!u v. + IMAGE (\x. u + drop(v - u) % x) (interval[vec 0,vec 1]) = segment[u,v]`, + REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[VECTOR_ADD_SYM] THEN + REWRITE_TAC[IMAGE_AFFINITY_INTERVAL; SEGMENT_1] THEN + REWRITE_TAC[DROP_SUB; REAL_SUB_LE; INTERVAL_EQ_EMPTY_1; DROP_VEC] THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN COND_CASES_TAC THEN + ASM_REWRITE_TAC[] THEN AP_TERM_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN + BINOP_TAC THEN REWRITE_TAC[GSYM LIFT_EQ_CMUL; VECTOR_MUL_RZERO] THEN + REWRITE_TAC[LIFT_DROP; LIFT_SUB] THEN VECTOR_ARITH_TAC);; + +let PATH_IMAGE_SUBPATH_GEN = prove + (`!u v g:real^1->real^N. path_image(subpath u v g) = IMAGE g (segment[u,v])`, + REPEAT GEN_TAC THEN REWRITE_TAC[path_image; subpath] THEN + ONCE_REWRITE_TAC[GSYM o_DEF] THEN + REWRITE_TAC[IMAGE_o; SUBPATH_SCALING_LEMMA]);; + +let PATH_IMAGE_SUBPATH = prove + (`!u v g:real^1->real^N. + drop u <= drop v + ==> path_image(subpath u v g) = IMAGE g (interval[u,v])`, + SIMP_TAC[PATH_IMAGE_SUBPATH_GEN; SEGMENT_1]);; + +let PATH_SUBPATH = prove + (`!u v g:real^1->real^N. + path g /\ u IN interval[vec 0,vec 1] /\ v IN interval[vec 0,vec 1] + ==> path(subpath u v g)`, + REWRITE_TAC[path; subpath] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC(REWRITE_RULE[o_DEF] CONTINUOUS_ON_COMPOSE) THEN + SIMP_TAC[CONTINUOUS_ON_ADD; CONTINUOUS_ON_CMUL; CONTINUOUS_ON_ID; + CONTINUOUS_ON_CONST] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET)) THEN + REWRITE_TAC[SUBPATH_SCALING_LEMMA; SEGMENT_1] THEN + COND_CASES_TAC THEN REWRITE_TAC[SUBSET_INTERVAL_1] THEN + REPEAT(POP_ASSUM MP_TAC) THEN REWRITE_TAC[IN_INTERVAL_1; DROP_VEC] THEN + REAL_ARITH_TAC);; + +let PATHSTART_SUBPATH = prove + (`!u v g:real^1->real^N. pathstart(subpath u v g) = g(u)`, + REWRITE_TAC[pathstart; subpath; VECTOR_MUL_RZERO; VECTOR_ADD_RID]);; + +let PATHFINISH_SUBPATH = prove + (`!u v g:real^1->real^N. pathfinish(subpath u v g) = g(v)`, + REWRITE_TAC[pathfinish; subpath; GSYM LIFT_EQ_CMUL] THEN + REWRITE_TAC[LIFT_DROP; VECTOR_ARITH `u + v - u:real^N = v`]);; + +let SUBPATH_TRIVIAL = prove + (`!g. subpath (vec 0) (vec 1) g = g`, + REWRITE_TAC[subpath; VECTOR_SUB_RZERO; DROP_VEC; VECTOR_MUL_LID; + VECTOR_ADD_LID; ETA_AX]);; + +let SUBPATH_REVERSEPATH = prove + (`!g. subpath (vec 1) (vec 0) g = reversepath g`, + REWRITE_TAC[subpath; reversepath; VECTOR_SUB_LZERO; DROP_NEG; DROP_VEC] THEN + REWRITE_TAC[VECTOR_ARITH `a + -- &1 % b:real^N = a - b`]);; + +let REVERSEPATH_SUBPATH = prove + (`!g u v. reversepath(subpath u v g) = subpath v u g`, + REWRITE_TAC[reversepath; subpath; FUN_EQ_THM] THEN REPEAT GEN_TAC THEN + AP_TERM_TAC THEN REWRITE_TAC[DROP_SUB; VECTOR_SUB_LDISTRIB] THEN + REWRITE_TAC[GSYM LIFT_EQ_CMUL; LIFT_SUB; LIFT_DROP] THEN + VECTOR_ARITH_TAC);; + +let SUBPATH_TRANSLATION = prove + (`!a g u v. subpath u v ((\x. a + x) o g) = (\x. a + x) o subpath u v g`, + REWRITE_TAC[FUN_EQ_THM; subpath; o_THM]);; + +add_translation_invariants [SUBPATH_TRANSLATION];; + +let SUBPATH_LINEAR_IMAGE = prove + (`!f g u v. linear f ==> subpath u v (f o g) = f o subpath u v g`, + REWRITE_TAC[FUN_EQ_THM; subpath; o_THM]);; + +add_linear_invariants [SUBPATH_LINEAR_IMAGE];; + +let SIMPLE_PATH_SUBPATH_EQ = prove + (`!g u v. simple_path(subpath u v g) <=> + path(subpath u v g) /\ ~(u = v) /\ + (!x y. x IN segment[u,v] /\ y IN segment[u,v] /\ g x = g y + ==> x = y \/ x = u /\ y = v \/ x = v /\ y = u)`, + REPEAT GEN_TAC THEN REWRITE_TAC[simple_path; subpath] THEN AP_TERM_TAC THEN + REWRITE_TAC[GSYM SUBPATH_SCALING_LEMMA] THEN + REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_IMAGE] THEN + REWRITE_TAC[VECTOR_ARITH `u + a % x = u <=> a % x = vec 0`; + VECTOR_ARITH `a + x:real^N = a + y <=> x = y`] THEN + REWRITE_TAC[VECTOR_MUL_EQ_0; VECTOR_MUL_LCANCEL] THEN + REWRITE_TAC[GSYM DROP_EQ; DROP_CMUL; DROP_ADD; DROP_SUB; + REAL_RING `u + (v - u) * y = v <=> v = u \/ y = &1`] THEN + REWRITE_TAC[REAL_SUB_0; DROP_EQ; GSYM DROP_VEC] THEN + ASM_CASES_TAC `v:real^1 = u` THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[REAL_SUB_REFL; DROP_VEC; VECTOR_MUL_LZERO] THEN + REWRITE_TAC[RIGHT_IMP_FORALL_THM] THEN + DISCH_THEN(MP_TAC o SPECL [`lift(&1 / &2)`; `lift(&3 / &4)`]) THEN + REWRITE_TAC[IN_INTERVAL_1; DROP_VEC; GSYM DROP_EQ; LIFT_DROP] THEN + CONV_TAC REAL_RAT_REDUCE_CONV);; + +let ARC_SUBPATH_EQ = prove + (`!g u v. arc(subpath u v g) <=> + path(subpath u v g) /\ ~(u = v) /\ + (!x y. x IN segment[u,v] /\ y IN segment[u,v] /\ g x = g y + ==> x = y)`, + REPEAT GEN_TAC THEN REWRITE_TAC[arc; subpath] THEN AP_TERM_TAC THEN + REWRITE_TAC[GSYM SUBPATH_SCALING_LEMMA] THEN + REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_IMAGE] THEN + REWRITE_TAC[VECTOR_ARITH `u + a % x = u + a % y <=> a % (x - y) = vec 0`; + VECTOR_MUL_EQ_0; DROP_EQ_0; VECTOR_SUB_EQ] THEN + ASM_CASES_TAC `v:real^1 = u` THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[VECTOR_SUB_REFL; DROP_VEC; VECTOR_MUL_LZERO] THEN + REWRITE_TAC[RIGHT_IMP_FORALL_THM] THEN + DISCH_THEN(MP_TAC o SPECL [`lift(&1 / &2)`; `lift(&3 / &4)`]) THEN + REWRITE_TAC[IN_INTERVAL_1; DROP_VEC; GSYM DROP_EQ; LIFT_DROP] THEN + CONV_TAC REAL_RAT_REDUCE_CONV);; + +let SIMPLE_PATH_SUBPATH = prove + (`!g u v. simple_path g /\ + u IN interval[vec 0,vec 1] /\ v IN interval[vec 0,vec 1] /\ + ~(u = v) + ==> simple_path(subpath u v g)`, + SIMP_TAC[SIMPLE_PATH_SUBPATH_EQ; PATH_SUBPATH; SIMPLE_PATH_IMP_PATH] THEN + REWRITE_TAC[simple_path] THEN GEN_TAC THEN + REWRITE_TAC[FORALL_LIFT] THEN MATCH_MP_TAC REAL_WLOG_LT THEN + REWRITE_TAC[FORALL_DROP; LIFT_DROP] THEN + CONJ_TAC THENL [MESON_TAC[SEGMENT_SYM]; ALL_TAC] THEN + SIMP_TAC[SEGMENT_1; REAL_LT_IMP_LE] THEN + MAP_EVERY X_GEN_TAC [`u:real^1`; `v:real^1`] THEN DISCH_TAC THEN + STRIP_TAC THEN MAP_EVERY X_GEN_TAC [`x:real^1`; `y:real^1`] THEN + STRIP_TAC THEN FIRST_X_ASSUM(MP_TAC o SPECL [`x:real^1`; `y:real^1`]) THEN + SUBGOAL_THEN + `!x:real^1. x IN interval[u,v] ==> x IN interval[vec 0,vec 1]` + ASSUME_TAC THENL + [REWRITE_TAC[GSYM SUBSET; SUBSET_INTERVAL_1] THEN + ASM_MESON_TAC[IN_INTERVAL_1; DROP_VEC; REAL_LE_TRANS]; + ASM_SIMP_TAC[]] THEN + REPEAT(FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_INTERVAL_1])) THEN + REWRITE_TAC[DROP_VEC; GSYM DROP_EQ] THEN ASM_REAL_ARITH_TAC);; + +let ARC_SIMPLE_PATH_SUBPATH = prove + (`!g u v. simple_path g /\ + u IN interval[vec 0,vec 1] /\ v IN interval[vec 0,vec 1] /\ + ~(g u = g v) + ==> arc(subpath u v g)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC SIMPLE_PATH_IMP_ARC THEN + ASM_REWRITE_TAC[PATHSTART_SUBPATH; PATHFINISH_SUBPATH] THEN + ASM_MESON_TAC[SIMPLE_PATH_SUBPATH]);; + +let ARC_SUBPATH_ARC = prove + (`!u v g. arc g /\ + u IN interval [vec 0,vec 1] /\ v IN interval [vec 0,vec 1] /\ + ~(u = v) + ==> arc(subpath u v g)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC ARC_SIMPLE_PATH_SUBPATH THEN + ASM_MESON_TAC[ARC_IMP_SIMPLE_PATH; arc]);; + +let ARC_SIMPLE_PATH_SUBPATH_INTERIOR = prove + (`!g u v. simple_path g /\ + u IN interval[vec 0,vec 1] /\ v IN interval[vec 0,vec 1] /\ + ~(u = v) /\ abs(drop u - drop v) < &1 + ==> arc(subpath u v g)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC ARC_SIMPLE_PATH_SUBPATH THEN + ASM_REWRITE_TAC[] THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [simple_path]) THEN + DISCH_THEN(MP_TAC o SPECL [`u:real^1`; `v:real^1`] o CONJUNCT2) THEN + ASM_REWRITE_TAC[] THEN POP_ASSUM_LIST(MP_TAC o end_itlist CONJ) THEN + ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN REWRITE_TAC[] THEN + STRIP_TAC THEN ASM_REWRITE_TAC[DROP_VEC] THEN REAL_ARITH_TAC);; + +let PATH_IMAGE_SUBPATH_SUBSET = prove + (`!u v g:real^1->real^N. + path g /\ u IN interval[vec 0,vec 1] /\ v IN interval[vec 0,vec 1] + ==> path_image(subpath u v g) SUBSET path_image g`, + SIMP_TAC[PATH_IMAGE_SUBPATH_GEN] THEN REPEAT STRIP_TAC THEN + REWRITE_TAC[path_image] THEN MATCH_MP_TAC IMAGE_SUBSET THEN + SIMP_TAC[SEGMENT_CONVEX_HULL; SUBSET_HULL; CONVEX_INTERVAL] THEN + ASM_REWRITE_TAC[INSERT_SUBSET; EMPTY_SUBSET]);; + +let JOIN_SUBPATHS_MIDDLE = prove + (`!p:real^1->real^N. + subpath (vec 0) (lift(&1 / &2)) p ++ subpath (lift(&1 / &2)) (vec 1) p = p`, + REWRITE_TAC[FUN_EQ_THM] THEN REPEAT GEN_TAC THEN + REWRITE_TAC[joinpaths; subpath] THEN COND_CASES_TAC THEN AP_TERM_TAC THEN + REWRITE_TAC[GSYM DROP_EQ; DROP_ADD; DROP_SUB; DROP_CMUL; LIFT_DROP; + DROP_VEC] THEN + REAL_ARITH_TAC);; + +(* ------------------------------------------------------------------------- *) +(* Some additional lemmas about choosing sub-paths. *) +(* ------------------------------------------------------------------------- *) + +let EXISTS_SUBPATH_OF_PATH = prove + (`!g a b:real^N. + path g /\ a IN path_image g /\ b IN path_image g + ==> ?h. path h /\ pathstart h = a /\ pathfinish h = b /\ + path_image h SUBSET path_image g`, + REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; path_image; FORALL_IN_IMAGE] THEN + GEN_TAC THEN DISCH_TAC THEN + X_GEN_TAC `u:real^1` THEN DISCH_TAC THEN + X_GEN_TAC `v:real^1` THEN DISCH_TAC THEN + EXISTS_TAC `subpath u v (g:real^1->real^N)` THEN + ASM_REWRITE_TAC[GSYM path_image; PATH_IMAGE_SUBPATH_GEN] THEN + ASM_SIMP_TAC[PATH_SUBPATH; PATHSTART_SUBPATH; PATHFINISH_SUBPATH] THEN + REWRITE_TAC[path_image] THEN MATCH_MP_TAC IMAGE_SUBSET THEN + SIMP_TAC[SEGMENT_CONVEX_HULL; SUBSET_HULL; CONVEX_INTERVAL] THEN + ASM_REWRITE_TAC[INSERT_SUBSET; EMPTY_SUBSET]);; + +let EXISTS_SUBPATH_OF_ARC_NOENDS = prove + (`!g a b:real^N. + arc g /\ a IN path_image g /\ b IN path_image g /\ + {a,b} INTER {pathstart g,pathfinish g} = {} + ==> ?h. path h /\ pathstart h = a /\ pathfinish h = b /\ + path_image h SUBSET + (path_image g) DIFF {pathstart g,pathfinish g}`, + REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; path_image; FORALL_IN_IMAGE] THEN + GEN_TAC THEN DISCH_TAC THEN + X_GEN_TAC `u:real^1` THEN DISCH_TAC THEN + X_GEN_TAC `v:real^1` THEN DISCH_TAC THEN DISCH_TAC THEN + EXISTS_TAC `subpath u v (g:real^1->real^N)` THEN + ASM_SIMP_TAC[PATH_SUBPATH; PATHSTART_SUBPATH; PATHFINISH_SUBPATH; + ARC_IMP_PATH; GSYM path_image; PATH_IMAGE_SUBPATH_GEN] THEN + REWRITE_TAC[path_image; pathstart; pathfinish] THEN + REWRITE_TAC[SET_RULE + `s SUBSET t DIFF {a,b} <=> s SUBSET t /\ ~(a IN s) /\ ~(b IN s)`] THEN + REWRITE_TAC[IN_IMAGE] THEN + SUBGOAL_THEN `~(vec 0 IN segment[u:real^1,v]) /\ ~(vec 1 IN segment[u,v])` + STRIP_ASSUME_TAC THENL + [REPEAT(FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_INTERVAL_1])) THEN + REWRITE_TAC[SEGMENT_1] THEN COND_CASES_TAC THEN + ASM_REWRITE_TAC[IN_INTERVAL_1; DROP_VEC] THEN + SIMP_TAC[REAL_ARITH `a <= b ==> (b <= a <=> a = b)`] THEN + REWRITE_TAC[GSYM DROP_VEC; DROP_EQ] THEN + RULE_ASSUM_TAC(REWRITE_RULE[arc; pathstart; pathfinish]) THEN + ASM SET_TAC[]; + ALL_TAC] THEN + SUBGOAL_THEN `segment[u:real^1,v] SUBSET interval[vec 0,vec 1]` MP_TAC THENL + [SIMP_TAC[SEGMENT_CONVEX_HULL; SUBSET_HULL; CONVEX_INTERVAL] THEN + ASM_REWRITE_TAC[INSERT_SUBSET; EMPTY_SUBSET]; + ALL_TAC] THEN + RULE_ASSUM_TAC(REWRITE_RULE[arc; pathstart; pathfinish]) THEN + SUBGOAL_THEN `(vec 0:real^1) IN interval[vec 0,vec 1] /\ + (vec 1:real^1) IN interval[vec 0,vec 1]` + MP_TAC THENL + [REWRITE_TAC[IN_INTERVAL_1; DROP_VEC; REAL_POS; REAL_LE_REFL]; + ASM SET_TAC[]]);; + +let EXISTS_SUBARC_OF_ARC_NOENDS = prove + (`!g a b:real^N. + arc g /\ a IN path_image g /\ b IN path_image g /\ ~(a = b) /\ + {a,b} INTER {pathstart g,pathfinish g} = {} + ==> ?h. arc h /\ pathstart h = a /\ pathfinish h = b /\ + path_image h SUBSET + (path_image g) DIFF {pathstart g,pathfinish g}`, + REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; path_image; FORALL_IN_IMAGE] THEN + GEN_TAC THEN DISCH_TAC THEN + X_GEN_TAC `u:real^1` THEN DISCH_TAC THEN + X_GEN_TAC `v:real^1` THEN REPEAT DISCH_TAC THEN + EXISTS_TAC `subpath u v (g:real^1->real^N)` THEN + ASM_SIMP_TAC[PATH_SUBPATH; PATHSTART_SUBPATH; PATHFINISH_SUBPATH; + ARC_IMP_PATH; GSYM path_image; PATH_IMAGE_SUBPATH_GEN] THEN + CONJ_TAC THENL + [MATCH_MP_TAC ARC_SIMPLE_PATH_SUBPATH THEN + ASM_SIMP_TAC[ARC_IMP_SIMPLE_PATH]; + ALL_TAC] THEN + REWRITE_TAC[path_image; pathstart; pathfinish] THEN + REWRITE_TAC[SET_RULE + `s SUBSET t DIFF {a,b} <=> s SUBSET t /\ ~(a IN s) /\ ~(b IN s)`] THEN + REWRITE_TAC[IN_IMAGE] THEN + SUBGOAL_THEN `~(vec 0 IN segment[u:real^1,v]) /\ ~(vec 1 IN segment[u,v])` + STRIP_ASSUME_TAC THENL + [REPEAT(FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_INTERVAL_1])) THEN + REWRITE_TAC[SEGMENT_1] THEN COND_CASES_TAC THEN + ASM_REWRITE_TAC[IN_INTERVAL_1; DROP_VEC] THEN + SIMP_TAC[REAL_ARITH `a <= b ==> (b <= a <=> a = b)`] THEN + REWRITE_TAC[GSYM DROP_VEC; DROP_EQ] THEN + RULE_ASSUM_TAC(REWRITE_RULE[arc; pathstart; pathfinish]) THEN + ASM SET_TAC[]; + ALL_TAC] THEN + SUBGOAL_THEN `segment[u:real^1,v] SUBSET interval[vec 0,vec 1]` MP_TAC THENL + [SIMP_TAC[SEGMENT_CONVEX_HULL; SUBSET_HULL; CONVEX_INTERVAL] THEN + ASM_REWRITE_TAC[INSERT_SUBSET; EMPTY_SUBSET]; + ALL_TAC] THEN + RULE_ASSUM_TAC(REWRITE_RULE[arc; pathstart; pathfinish]) THEN + SUBGOAL_THEN `(vec 0:real^1) IN interval[vec 0,vec 1] /\ + (vec 1:real^1) IN interval[vec 0,vec 1]` + MP_TAC THENL + [REWRITE_TAC[IN_INTERVAL_1; DROP_VEC; REAL_POS; REAL_LE_REFL]; + ASM SET_TAC[]]);; + +let EXISTS_ARC_PSUBSET_SIMPLE_PATH = prove + (`!g:real^1->real^N. + simple_path g /\ closed s /\ s PSUBSET path_image g + ==> ?h. arc h /\ + s SUBSET path_image h /\ + path_image h SUBSET path_image g`, + REPEAT STRIP_TAC THEN + FIRST_ASSUM(DISJ_CASES_TAC o MATCH_MP SIMPLE_PATH_CASES) THENL + [EXISTS_TAC `g:real^1->real^N` THEN ASM_REWRITE_TAC[] THEN ASM SET_TAC[]; + ALL_TAC] THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [PSUBSET_ALT]) THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [path_image] THEN + REWRITE_TAC[EXISTS_IN_IMAGE] THEN + DISCH_THEN(X_CHOOSE_THEN `u:real^1` STRIP_ASSUME_TAC) THEN + ABBREV_TAC `(h:real^1->real^N) = shiftpath u g` THEN + SUBGOAL_THEN + `simple_path(h:real^1->real^N) /\ + pathstart h = (g:real^1->real^N) u /\ + pathfinish h = (g:real^1->real^N) u /\ + path_image h = path_image g` + MP_TAC THENL + [EXPAND_TAC "h" THEN + ASM_MESON_TAC[SIMPLE_PATH_SHIFTPATH; PATH_IMAGE_SHIFTPATH; + PATHSTART_SHIFTPATH; PATHFINISH_SHIFTPATH; + IN_INTERVAL_1; DROP_VEC]; + REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + DISCH_THEN(SUBST_ALL_TAC o SYM) THEN + UNDISCH_THEN `pathstart(h:real^1->real^N) = (g:real^1->real^N) u` + (SUBST_ALL_TAC o SYM)] THEN + SUBGOAL_THEN + `open_in (subtopology euclidean (interval[vec 0,vec 1])) + {x:real^1 | x IN interval[vec 0,vec 1] /\ + (h x) IN ((:real^N) DIFF s)}` + MP_TAC THENL + [MATCH_MP_TAC CONTINUOUS_OPEN_IN_PREIMAGE THEN + ASM_SIMP_TAC[GSYM path; GSYM closed; SIMPLE_PATH_IMP_PATH]; + REWRITE_TAC[open_in] THEN DISCH_THEN(MP_TAC o CONJUNCT2)] THEN + REWRITE_TAC[IN_DIFF; IN_UNIV; IN_ELIM_THM] THEN + DISCH_THEN(fun th -> + MP_TAC(SPEC `vec 0:real^1` th) THEN MP_TAC(SPEC `vec 1:real^1` th)) THEN + REWRITE_TAC[IN_INTERVAL_1; DROP_VEC; REAL_POS; REAL_LE_REFL] THEN + REWRITE_TAC[DIST_REAL; VEC_COMPONENT; REAL_SUB_RZERO] THEN + SIMP_TAC[GSYM drop] THEN + ANTS_TAC THENL [ASM_MESON_TAC[pathfinish]; ALL_TAC] THEN + DISCH_THEN(X_CHOOSE_THEN `d2:real` STRIP_ASSUME_TAC) THEN + ANTS_TAC THENL [ASM_MESON_TAC[pathstart]; ALL_TAC] THEN + DISCH_THEN(X_CHOOSE_THEN `d1:real` STRIP_ASSUME_TAC) THEN + EXISTS_TAC + `subpath (lift(min d1 (&1 / &4))) (lift(&1 - min d2 (&1 / &4))) + (h:real^1->real^N)` THEN + REPEAT CONJ_TAC THENL + [MATCH_MP_TAC ARC_SIMPLE_PATH_SUBPATH_INTERIOR THEN + ASM_REWRITE_TAC[IN_INTERVAL_1; DROP_VEC; LIFT_DROP; LIFT_EQ] THEN + ASM_REAL_ARITH_TAC; + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE + `s SUBSET t ==> t INTER s SUBSET u ==> s SUBSET u`)) THEN + REWRITE_TAC[SUBSET; IN_INTER; IMP_CONJ] THEN + SIMP_TAC[PATH_IMAGE_SUBPATH; LIFT_DROP; + REAL_ARITH `min d1 (&1 / &4) <= &1 - min d2 (&1 / &4)`] THEN + REWRITE_TAC[FORALL_IN_IMAGE; path_image; IN_INTERVAL_1; DROP_VEC] THEN + X_GEN_TAC `x:real^1` THEN REPEAT STRIP_TAC THEN + REWRITE_TAC[IN_IMAGE] THEN EXISTS_TAC `x:real^1` THEN + ASM_REWRITE_TAC[IN_INTERVAL_1; LIFT_DROP] THEN + REPEAT(FIRST_X_ASSUM(MP_TAC o SPEC `x:real^1`)) THEN + ASM_REWRITE_TAC[] THEN ASM_REAL_ARITH_TAC; + MATCH_MP_TAC PATH_IMAGE_SUBPATH_SUBSET THEN + ASM_SIMP_TAC[SIMPLE_PATH_IMP_PATH; IN_INTERVAL_1; LIFT_DROP; DROP_VEC] THEN + ASM_REAL_ARITH_TAC]);; + +let EXISTS_DOUBLE_ARC = prove + (`!g:real^1->real^N a b. + simple_path g /\ pathfinish g = pathstart g /\ + a IN path_image g /\ b IN path_image g /\ ~(a = b) + ==> ?u d. arc u /\ arc d /\ + pathstart u = a /\ pathfinish u = b /\ + pathstart d = b /\ pathfinish d = a /\ + (path_image u) INTER (path_image d) = {a,b} /\ + (path_image u) UNION (path_image d) = path_image g`, + REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; path_image] THEN + ONCE_REWRITE_TAC[FORALL_IN_IMAGE] THEN GEN_TAC THEN REPEAT DISCH_TAC THEN + X_GEN_TAC `u:real^1` THEN DISCH_TAC THEN REWRITE_TAC[GSYM path_image] THEN + X_GEN_TAC `b:real^N` THEN DISCH_TAC THEN DISCH_TAC THEN + ABBREV_TAC `h = shiftpath u (g:real^1->real^N)` THEN + SUBGOAL_THEN + `simple_path(h:real^1->real^N) /\ + pathstart h = g u /\ + pathfinish h = g u /\ + path_image h = path_image g` + STRIP_ASSUME_TAC THENL + [EXPAND_TAC "h" THEN + ASM_SIMP_TAC[SIMPLE_PATH_SHIFTPATH; PATH_IMAGE_SHIFTPATH] THEN + RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1; DROP_VEC]) THEN + EXPAND_TAC "h" THEN + ASM_SIMP_TAC[PATHSTART_SHIFTPATH; PATHFINISH_SHIFTPATH]; + UNDISCH_THEN `path_image h :real^N->bool = path_image g` + (SUBST_ALL_TAC o SYM)] THEN + UNDISCH_TAC `(b:real^N) IN path_image h` THEN + REWRITE_TAC[IN_IMAGE; path_image; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `v:real^1` THEN STRIP_TAC THEN REWRITE_TAC[GSYM path_image] THEN + MAP_EVERY EXISTS_TAC + [`subpath (vec 0) v (h:real^1->real^N)`; + `subpath v (vec 1) (h:real^1->real^N)`] THEN + RULE_ASSUM_TAC(REWRITE_RULE[pathstart; pathfinish]) THEN + ASM_REWRITE_TAC[PATHSTART_SUBPATH; PATHFINISH_SUBPATH] THEN + UNDISCH_THEN `b = (h:real^1->real^N) v` SUBST_ALL_TAC THEN + STRIP_ASSUME_TAC(REWRITE_RULE[IN_INTERVAL_1; DROP_VEC] + (ASSUME `(v:real^1) IN interval[vec 0,vec 1]`)) THEN + ASM_SIMP_TAC[ARC_SIMPLE_PATH_SUBPATH; IN_INTERVAL_1; DROP_VEC; + REAL_LE_REFL; REAL_POS; PATH_IMAGE_SUBPATH] THEN + REWRITE_TAC[GSYM IMAGE_UNION; path_image] THEN + UNDISCH_THEN `(h:real^1->real^N)(vec 0) = (g:real^1->real^N) u` + (SUBST_ALL_TAC o SYM) THEN + SUBGOAL_THEN + `interval[vec 0,v] UNION interval[v,vec 1] = interval[vec 0:real^1,vec 1]` + ASSUME_TAC THENL + [ALL_TAC; + ASM_SIMP_TAC[IMAGE_SUBSET] THEN + MATCH_MP_TAC(SET_RULE + `(!x y. x IN (s UNION t) /\ y IN (s UNION t) /\ f x = f y + ==> x = y \/ x = vec 0 /\ y = vec 1 \/ x = vec 1 /\ y = vec 0) /\ + (f(vec 0) = f(vec 1)) /\ (vec 0) IN s /\ (vec 1) IN t /\ + s INTER t = {c} + ==> IMAGE f s INTER IMAGE f t = {f (vec 0), f c}`) THEN + RULE_ASSUM_TAC(REWRITE_RULE[simple_path]) THEN ASM_REWRITE_TAC[]] THEN + REWRITE_TAC[EXTENSION; IN_INSERT; NOT_IN_EMPTY; IN_INTER; IN_UNION] THEN + REPEAT(FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_INTERVAL_1])) THEN + REWRITE_TAC[IN_INTERVAL_1; GSYM DROP_EQ; DROP_VEC] THEN ASM_REAL_ARITH_TAC);; + +let SUBPATH_TO_FRONTIER_EXPLICIT = prove + (`!g:real^1->real^N s. + path g /\ pathstart g IN s /\ ~(pathfinish g IN s) + ==> ?u. u IN interval[vec 0,vec 1] /\ + (!x. &0 <= drop x /\ drop x < drop u ==> g x IN interior s) /\ + ~(g u IN interior s) /\ + (u = vec 0 \/ g u IN closure s)`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPEC `{u | lift u IN interval[vec 0,vec 1] /\ + g(lift u) IN closure((:real^N) DIFF s)}` + COMPACT_ATTAINS_INF) THEN + SIMP_TAC[LIFT_DROP; SET_RULE + `(!x. lift(drop x) = x) ==> IMAGE lift {x | P(lift x)} = {x | P x}`] THEN + ANTS_TAC THENL + [RULE_ASSUM_TAC(REWRITE_RULE[path; pathstart; pathfinish; SUBSET; + path_image; FORALL_IN_IMAGE]) THEN + CONJ_TAC THENL + [REWRITE_TAC[COMPACT_EQ_BOUNDED_CLOSED] THEN CONJ_TAC THENL + [MATCH_MP_TAC BOUNDED_SUBSET THEN + EXISTS_TAC `interval[vec 0:real^1,vec 1]` THEN + REWRITE_TAC[BOUNDED_INTERVAL] THEN SET_TAC[]; + MATCH_MP_TAC CONTINUOUS_CLOSED_PREIMAGE THEN + ASM_REWRITE_TAC[CLOSED_CLOSURE; CLOSED_INTERVAL]]; + REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; IN_ELIM_THM] THEN + EXISTS_TAC `&1` THEN REWRITE_TAC[LIFT_NUM] THEN + REWRITE_TAC[IN_INTERVAL_1; DROP_VEC; REAL_POS; REAL_LE_REFL] THEN + MATCH_MP_TAC(REWRITE_RULE[SUBSET] CLOSURE_SUBSET) THEN + ASM_REWRITE_TAC[IN_DIFF; IN_UNIV]]; + ALL_TAC] THEN + REWRITE_TAC[EXISTS_DROP; FORALL_DROP; IN_ELIM_THM; LIFT_DROP] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `u:real^1` THEN + REWRITE_TAC[CLOSURE_COMPLEMENT; IN_DIFF; IN_UNIV] THEN STRIP_TAC THEN + ASM_REWRITE_TAC[subpath; VECTOR_SUB_RZERO; VECTOR_ADD_LID] THEN + ASM_REWRITE_TAC[GSYM LIFT_EQ_CMUL; LIFT_DROP] THEN + RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1; DROP_VEC]) THEN + REWRITE_TAC[IN_INTERVAL_1; DROP_VEC; GSYM DROP_EQ] THEN + MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN CONJ_TAC THENL + [REPEAT STRIP_TAC THEN + FIRST_X_ASSUM(MATCH_MP_TAC o GEN_REWRITE_RULE BINDER_CONV + [TAUT `a /\ ~b ==> c <=> a /\ ~c ==> b`]) THEN + ASM_REAL_ARITH_TAC; + FIRST_X_ASSUM(K ALL_TAC o SPEC `x:real^1`) THEN DISCH_TAC] THEN + ASM_CASES_TAC `drop u = &0` THEN + ASM_REWRITE_TAC[frontier; IN_DIFF; CLOSURE_APPROACHABLE] THEN + X_GEN_TAC `e:real` THEN DISCH_TAC THEN + RULE_ASSUM_TAC(REWRITE_RULE[path; pathstart; pathfinish]) THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [continuous_on]) THEN + DISCH_THEN(MP_TAC o SPEC `u:real^1`) THEN + ASM_REWRITE_TAC[IN_INTERVAL_1; DROP_VEC] THEN + DISCH_THEN(MP_TAC o SPEC `e:real`) THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `d:real` (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + DISCH_THEN(MP_TAC o SPEC `lift(max (&0) (drop u - d / &2))`) THEN + REWRITE_TAC[LIFT_DROP; DIST_REAL; GSYM drop] THEN + ANTS_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN MATCH_MP_TAC + (MESON[] `P a ==> dist(a,y) < e ==> ?x. P x /\ dist(x,y) < e`) THEN + MATCH_MP_TAC(REWRITE_RULE[SUBSET] INTERIOR_SUBSET) THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN REWRITE_TAC[LIFT_DROP] THEN ASM_ARITH_TAC);; + +let SUBPATH_TO_FRONTIER_STRONG = prove + (`!g:real^1->real^N s. + path g /\ pathstart g IN s /\ ~(pathfinish g IN s) + ==> ?u. u IN interval[vec 0,vec 1] /\ + ~(pathfinish(subpath (vec 0) u g) IN interior s) /\ + (u = vec 0 \/ + (!x. x IN interval[vec 0,vec 1] /\ ~(x = vec 1) + ==> (subpath (vec 0) u g x) IN interior s) /\ + pathfinish(subpath (vec 0) u g) IN closure s)`, + REPEAT GEN_TAC THEN DISCH_TAC THEN + FIRST_ASSUM(MP_TAC o MATCH_MP SUBPATH_TO_FRONTIER_EXPLICIT) THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `u:real^1` THEN + REWRITE_TAC[subpath; pathfinish; VECTOR_SUB_RZERO; VECTOR_ADD_LID] THEN + ASM_CASES_TAC `u:real^1 = vec 0` THEN ASM_REWRITE_TAC[] THEN + STRIP_TAC THEN ASM_REWRITE_TAC[DROP_VEC; VECTOR_MUL_LZERO] THEN + ASM_REWRITE_TAC[GSYM LIFT_EQ_CMUL; LIFT_DROP] THEN + X_GEN_TAC `x:real^1` THEN + REWRITE_TAC[IN_INTERVAL_1; GSYM DROP_EQ; DROP_VEC] THEN STRIP_TAC THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN + RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1; DROP_VEC]) THEN + ASM_SIMP_TAC[DROP_CMUL; REAL_LE_MUL] THEN + REWRITE_TAC[REAL_ARITH `u * x < u <=> &0 < u * (&1 - x)`] THEN + MATCH_MP_TAC REAL_LT_MUL THEN REWRITE_TAC[REAL_SUB_LT] THEN + ASM_REWRITE_TAC[REAL_LT_LE] THEN + ASM_REWRITE_TAC[GSYM LIFT_EQ; LIFT_DROP; LIFT_NUM]);; + +let SUBPATH_TO_FRONTIER = prove + (`!g:real^1->real^N s. + path g /\ pathstart g IN s /\ ~(pathfinish g IN s) + ==> ?u. u IN interval[vec 0,vec 1] /\ + pathfinish(subpath (vec 0) u g) IN frontier s /\ + (path_image(subpath (vec 0) u g) DELETE + pathfinish(subpath (vec 0) u g)) + SUBSET interior s`, + REPEAT GEN_TAC THEN DISCH_TAC THEN REWRITE_TAC[frontier; IN_DIFF] THEN + FIRST_ASSUM(MP_TAC o MATCH_MP SUBPATH_TO_FRONTIER_STRONG) THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `u:real^1` THEN + ASM_CASES_TAC `u:real^1 = vec 0` THEN ASM_REWRITE_TAC[] THENL + [REWRITE_TAC[PATHSTART_SUBPATH; PATHFINISH_SUBPATH] THEN + RULE_ASSUM_TAC(REWRITE_RULE[pathstart]) THEN STRIP_TAC THEN + ASM_SIMP_TAC[REWRITE_RULE[SUBSET] CLOSURE_SUBSET] THEN + REWRITE_TAC[subpath; path_image; VECTOR_SUB_REFL; DROP_VEC; + VECTOR_MUL_LZERO; VECTOR_ADD_LID] THEN + SET_TAC[]; + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[SUBSET; path_image; FORALL_IN_IMAGE; IN_DELETE; IMP_CONJ] THEN + REWRITE_TAC[IN_INTERVAL_1; DROP_VEC; pathfinish] THEN + REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_REWRITE_TAC[IN_INTERVAL_1; DROP_VEC] THEN ASM_MESON_TAC[]]);; + +let EXISTS_PATH_SUBPATH_TO_FRONTIER = prove + (`!g:real^1->real^N s. + path g /\ pathstart g IN s /\ ~(pathfinish g IN s) + ==> ?h. path h /\ pathstart h = pathstart g /\ + (path_image h) SUBSET (path_image g) /\ + (path_image h DELETE (pathfinish h)) SUBSET interior s /\ + pathfinish h IN frontier s`, + REPEAT GEN_TAC THEN DISCH_TAC THEN + FIRST_ASSUM(STRIP_ASSUME_TAC o MATCH_MP SUBPATH_TO_FRONTIER) THEN + EXISTS_TAC `subpath (vec 0) u (g:real^1->real^N)` THEN + ASM_SIMP_TAC[PATH_SUBPATH; IN_INTERVAL_1; DROP_VEC; REAL_POS; REAL_LE_REFL; + PATHSTART_SUBPATH; PATH_IMAGE_SUBPATH_SUBSET] THEN + REWRITE_TAC[pathstart]);; + +let EXISTS_PATH_SUBPATH_TO_FRONTIER_CLOSED = prove + (`!g:real^1->real^N s. + closed s /\ path g /\ pathstart g IN s /\ ~(pathfinish g IN s) + ==> ?h. path h /\ pathstart h = pathstart g /\ + (path_image h) SUBSET (path_image g) INTER s /\ + pathfinish h IN frontier s`, + REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN ASSUME_TAC) THEN + FIRST_ASSUM(MP_TAC o MATCH_MP EXISTS_PATH_SUBPATH_TO_FRONTIER) THEN + MATCH_MP_TAC MONO_EXISTS THEN + REWRITE_TAC[SUBSET_INTER] THEN REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC SUBSET_TRANS THEN EXISTS_TAC + `(pathfinish h:real^N) INSERT (path_image h DELETE pathfinish h)` THEN + CONJ_TAC THENL [SET_TAC[]; REWRITE_TAC[INSERT_SUBSET]] THEN CONJ_TAC THENL + [ASM_MESON_TAC[frontier; CLOSURE_EQ; IN_DIFF]; + ASM_MESON_TAC[SUBSET_TRANS; INTERIOR_SUBSET]]);; + +(* ------------------------------------------------------------------------- *) +(* Special case of straight-line paths. *) +(* ------------------------------------------------------------------------- *) + +let linepath = new_definition + `linepath(a,b) = \x. (&1 - drop x) % a + drop x % b`;; + +let LINEPATH_TRANSLATION = prove + (`!a b c. linepath(a + b,a + c) = (\x. a + x) o linepath(b,c)`, + REWRITE_TAC[linepath; o_THM; FUN_EQ_THM] THEN VECTOR_ARITH_TAC);; + +add_translation_invariants [LINEPATH_TRANSLATION];; + +let LINEPATH_LINEAR_IMAGE = prove + (`!f. linear f ==> !b c. linepath(f b,f c) = f o linepath(b,c)`, + REWRITE_TAC[linepath; o_THM; FUN_EQ_THM] THEN REPEAT STRIP_TAC THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP LINEAR_ADD) THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP LINEAR_CMUL) THEN + ASM_REWRITE_TAC[] THEN VECTOR_ARITH_TAC);; + +add_linear_invariants [LINEPATH_LINEAR_IMAGE];; + +let PATHSTART_LINEPATH = prove + (`!a b. pathstart(linepath(a,b)) = a`, + REWRITE_TAC[linepath; pathstart; DROP_VEC] THEN VECTOR_ARITH_TAC);; + +let PATHFINISH_LINEPATH = prove + (`!a b. pathfinish(linepath(a,b)) = b`, + REWRITE_TAC[linepath; pathfinish; DROP_VEC] THEN VECTOR_ARITH_TAC);; + +let CONTINUOUS_LINEPATH_AT = prove + (`!a b x. linepath(a,b) continuous (at x)`, + REPEAT GEN_TAC THEN REWRITE_TAC[linepath] THEN + REWRITE_TAC[VECTOR_ARITH `(&1 - u) % x + y = x + u % --x + y`] THEN + MATCH_MP_TAC CONTINUOUS_ADD THEN REWRITE_TAC[CONTINUOUS_CONST] THEN + MATCH_MP_TAC CONTINUOUS_ADD THEN CONJ_TAC THEN + MATCH_MP_TAC CONTINUOUS_VMUL THEN + REWRITE_TAC[o_DEF; LIFT_DROP; CONTINUOUS_AT_ID]);; + +let CONTINUOUS_ON_LINEPATH = prove + (`!a b s. linepath(a,b) continuous_on s`, + MESON_TAC[CONTINUOUS_AT_IMP_CONTINUOUS_ON; CONTINUOUS_LINEPATH_AT]);; + +let PATH_LINEPATH = prove + (`!a b. path(linepath(a,b))`, + REWRITE_TAC[path; CONTINUOUS_ON_LINEPATH]);; + +let PATH_IMAGE_LINEPATH = prove + (`!a b. path_image(linepath (a,b)) = segment[a,b]`, + REWRITE_TAC[segment; path_image; linepath] THEN + REWRITE_TAC[EXTENSION; IN_IMAGE; IN_ELIM_THM; IN_INTERVAL] THEN + SIMP_TAC[DIMINDEX_1; FORALL_1; VEC_COMPONENT; ARITH] THEN + REWRITE_TAC[EXISTS_LIFT; GSYM drop; LIFT_DROP] THEN MESON_TAC[]);; + +let REVERSEPATH_LINEPATH = prove + (`!a b. reversepath(linepath(a,b)) = linepath(b,a)`, + REWRITE_TAC[reversepath; linepath; DROP_SUB; DROP_VEC; FUN_EQ_THM] THEN + VECTOR_ARITH_TAC);; + +let ARC_LINEPATH = prove + (`!a b. ~(a = b) ==> arc(linepath(a,b))`, + REWRITE_TAC[arc; PATH_LINEPATH] THEN REWRITE_TAC[linepath] THEN + REWRITE_TAC[VECTOR_ARITH + `(&1 - x) % a + x % b:real^N = (&1 - y) % a + y % b <=> + (x - y) % (a - b) = vec 0`] THEN + SIMP_TAC[VECTOR_MUL_EQ_0; VECTOR_SUB_EQ; DROP_EQ; REAL_SUB_0]);; + +let SIMPLE_PATH_LINEPATH = prove + (`!a b. ~(a = b) ==> simple_path(linepath(a,b))`, + MESON_TAC[ARC_IMP_SIMPLE_PATH; ARC_LINEPATH]);; + +let SIMPLE_PATH_LINEPATH_EQ = prove + (`!a b:real^N. simple_path(linepath(a,b)) <=> ~(a = b)`, + REPEAT GEN_TAC THEN EQ_TAC THEN REWRITE_TAC[SIMPLE_PATH_LINEPATH] THEN + ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN REWRITE_TAC[simple_path] THEN + DISCH_THEN SUBST1_TAC THEN DISCH_THEN(MP_TAC o CONJUNCT2) THEN + REWRITE_TAC[linepath; GSYM VECTOR_ADD_RDISTRIB] THEN + DISCH_THEN(MP_TAC o SPECL [`lift(&0)`; `lift(&1 / &2)`]) THEN + REWRITE_TAC[IN_INTERVAL_1; LIFT_DROP; GSYM DROP_EQ; DROP_VEC] THEN + CONV_TAC REAL_RAT_REDUCE_CONV);; + +let ARC_LINEPATH_EQ = prove + (`!a b. arc(linepath(a,b)) <=> ~(a = b)`, + REPEAT GEN_TAC THEN EQ_TAC THEN REWRITE_TAC[ARC_LINEPATH] THEN + MESON_TAC[SIMPLE_PATH_LINEPATH_EQ; ARC_IMP_SIMPLE_PATH]);; + +let LINEPATH_REFL = prove + (`!a. linepath(a,a) = \x. a`, + REWRITE_TAC[linepath; VECTOR_ARITH `(&1 - u) % x + u % x:real^N = x`]);; + +let SHIFTPATH_TRIVIAL = prove + (`!t a. shiftpath t (linepath(a,a)) = linepath(a,a)`, + REWRITE_TAC[shiftpath; LINEPATH_REFL; COND_ID]);; + +let SUBPATH_REFL = prove + (`!g a. subpath a a g = linepath(g a,g a)`, + REWRITE_TAC[subpath; linepath; VECTOR_SUB_REFL; DROP_VEC; VECTOR_MUL_LZERO; + FUN_EQ_THM; VECTOR_ADD_RID] THEN + VECTOR_ARITH_TAC);; + +(* ------------------------------------------------------------------------- *) +(* Bounding a point away from a path. *) +(* ------------------------------------------------------------------------- *) + +let NOT_ON_PATH_BALL = prove + (`!g z:real^N. + path g /\ ~(z IN path_image g) + ==> ?e. &0 < e /\ ball(z,e) INTER (path_image g) = {}`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`path_image g:real^N->bool`; `z:real^N`] + DISTANCE_ATTAINS_INF) THEN + REWRITE_TAC[PATH_IMAGE_NONEMPTY] THEN + ASM_SIMP_TAC[COMPACT_PATH_IMAGE; COMPACT_IMP_CLOSED] THEN + DISCH_THEN(X_CHOOSE_THEN `a:real^N` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `dist(z:real^N,a)` THEN + CONJ_TAC THENL [ASM_MESON_TAC[DIST_POS_LT]; ALL_TAC] THEN + REWRITE_TAC[EXTENSION; NOT_IN_EMPTY; IN_BALL; IN_INTER] THEN + ASM_MESON_TAC[REAL_NOT_LE]);; + +let NOT_ON_PATH_CBALL = prove + (`!g z:real^N. + path g /\ ~(z IN path_image g) + ==> ?e. &0 < e /\ cball(z,e) INTER (path_image g) = {}`, + REPEAT GEN_TAC THEN DISCH_THEN(MP_TAC o MATCH_MP NOT_ON_PATH_BALL) THEN + DISCH_THEN(X_CHOOSE_THEN `e:real` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `e / &2` THEN ASM_REWRITE_TAC[REAL_HALF] THEN + FIRST_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE + `s INTER u = {} ==> t SUBSET s ==> t INTER u = {}`)) THEN + REWRITE_TAC[SUBSET; IN_BALL; IN_CBALL] THEN + UNDISCH_TAC `&0 < e` THEN REAL_ARITH_TAC);; + +(* ------------------------------------------------------------------------- *) +(* Homeomorphisms of arc images. *) +(* ------------------------------------------------------------------------- *) + +let HOMEOMORPHISM_ARC = prove + (`!g:real^1->real^N. + arc g ==> ?h. homeomorphism (interval[vec 0,vec 1],path_image g) (g,h)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC HOMEOMORPHISM_COMPACT THEN + ASM_REWRITE_TAC[path_image; COMPACT_INTERVAL; GSYM path; GSYM arc]);; + +let HOMEOMORPHIC_ARC_IMAGE_INTERVAL = prove + (`!g:real^1->real^N a b:real^1. + arc g /\ drop a < drop b ==> (path_image g) homeomorphic interval[a,b]`, + REPEAT STRIP_TAC THEN + TRANS_TAC HOMEOMORPHIC_TRANS `interval[vec 0:real^1,vec 1]` THEN + CONJ_TAC THENL + [ONCE_REWRITE_TAC[HOMEOMORPHIC_SYM] THEN REWRITE_TAC[homeomorphic] THEN + EXISTS_TAC `g:real^1->real^N` THEN ASM_SIMP_TAC[HOMEOMORPHISM_ARC]; + MATCH_MP_TAC HOMEOMORPHIC_CLOSED_INTERVALS THEN + ASM_REWRITE_TAC[INTERVAL_NE_EMPTY_1; DROP_VEC; REAL_LT_01]]);; + +let HOMEOMORPHIC_ARC_IMAGES = prove + (`!g:real^1->real^M h:real^1->real^N. + arc g /\ arc h ==> (path_image g) homeomorphic (path_image h)`, + REPEAT STRIP_TAC THEN + TRANS_TAC HOMEOMORPHIC_TRANS `interval[vec 0:real^1,vec 1]` THEN + CONJ_TAC THENL [ALL_TAC; ONCE_REWRITE_TAC[HOMEOMORPHIC_SYM]] THEN + MATCH_MP_TAC HOMEOMORPHIC_ARC_IMAGE_INTERVAL THEN + ASM_REWRITE_TAC[DROP_VEC; REAL_LT_01]);; + +let HOMEOMORPHIC_ARC_IMAGE_SEGMENT = prove + (`!g:real^1->real^N a b:real^M. + arc g /\ ~(a = b) ==> (path_image g) homeomorphic segment[a,b]`, + REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM PATH_IMAGE_LINEPATH] THEN + MATCH_MP_TAC HOMEOMORPHIC_ARC_IMAGES THEN + ASM_REWRITE_TAC[ARC_LINEPATH_EQ]);; + +(* ------------------------------------------------------------------------- *) +(* Path component, considered as a "joinability" relation (from Tom Hales). *) +(* ------------------------------------------------------------------------- *) + +let path_component = new_definition + `path_component s x y <=> + ?g. path g /\ path_image g SUBSET s /\ + pathstart g = x /\ pathfinish g = y`;; + +let PATH_COMPONENT_IN = prove + (`!s x y. path_component s x y ==> x IN s /\ y IN s`, + REWRITE_TAC[path_component; path_image; pathstart; pathfinish] THEN + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE] THEN REPEAT STRIP_TAC THEN + REPEAT(FIRST_X_ASSUM(SUBST1_TAC o SYM)) THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN + REWRITE_TAC[IN_INTERVAL_1; DROP_VEC; REAL_LE_REFL; REAL_POS]);; + +let PATH_COMPONENT_REFL = prove + (`!s x:real^N. x IN s ==> path_component s x x`, + REPEAT STRIP_TAC THEN REWRITE_TAC[path_component] THEN + EXISTS_TAC `(\u. x):real^1->real^N` THEN + REWRITE_TAC[pathstart; pathfinish; path_image; path; + CONTINUOUS_ON_CONST; IMAGE; FORALL_IN_IMAGE] THEN + REWRITE_TAC[SUBSET; IN_ELIM_THM] THEN ASM_MESON_TAC[]);; + +let PATH_COMPONENT_REFL_EQ = prove + (`!s x:real^N. path_component s x x <=> x IN s`, + MESON_TAC[PATH_COMPONENT_IN; PATH_COMPONENT_REFL]);; + +let PATH_COMPONENT_SYM = prove + (`!s x y:real^N. path_component s x y ==> path_component s y x`, + REPEAT GEN_TAC THEN REWRITE_TAC[path_component] THEN + MESON_TAC[PATH_REVERSEPATH; PATH_IMAGE_REVERSEPATH; + PATHSTART_REVERSEPATH; PATHFINISH_REVERSEPATH]);; + +let PATH_COMPONENT_SYM_EQ = prove + (`!s x y. path_component s x y <=> path_component s y x`, + MESON_TAC[PATH_COMPONENT_SYM]);; + +let PATH_COMPONENT_TRANS = prove + (`!s x y:real^N. + path_component s x y /\ path_component s y z ==> path_component s x z`, + REPEAT GEN_TAC THEN REWRITE_TAC[path_component] THEN + DISCH_THEN(CONJUNCTS_THEN2 + (X_CHOOSE_TAC `g1:real^1->real^N`) (X_CHOOSE_TAC `g2:real^1->real^N`)) THEN + EXISTS_TAC `g1 ++ g2 :real^1->real^N` THEN + ASM_SIMP_TAC[PATH_JOIN; PATH_IMAGE_JOIN; UNION_SUBSET; + PATHSTART_JOIN; PATHFINISH_JOIN]);; + +let PATH_COMPONENT_OF_SUBSET = prove + (`!s t x. s SUBSET t /\ path_component s x y ==> path_component t x y`, + REWRITE_TAC[path_component] THEN SET_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* Can also consider it as a set, as the name suggests. *) +(* ------------------------------------------------------------------------- *) + +let PATH_COMPONENT_SET = prove + (`!s x. path_component s x = + { y | ?g. path g /\ path_image g SUBSET s /\ + pathstart g = x /\ pathfinish g = y }`, + REWRITE_TAC[EXTENSION; IN_ELIM_THM] THEN REWRITE_TAC[IN; path_component]);; + +let PATH_COMPONENT_SUBSET = prove + (`!s x. (path_component s x) SUBSET s`, + REWRITE_TAC[SUBSET; IN] THEN MESON_TAC[PATH_COMPONENT_IN; IN]);; + +let PATH_COMPONENT_EQ_EMPTY = prove + (`!s x. path_component s x = {} <=> ~(x IN s)`, + REWRITE_TAC[EXTENSION; NOT_IN_EMPTY] THEN + MESON_TAC[IN; PATH_COMPONENT_REFL; PATH_COMPONENT_IN]);; + +let PATH_COMPONENT_EMPTY = prove + (`!x. path_component {} x = {}`, + REWRITE_TAC[PATH_COMPONENT_EQ_EMPTY; NOT_IN_EMPTY]);; + +let UNIONS_PATH_COMPONENT = prove + (`!s:real^N->bool. UNIONS {path_component s x |x| x IN s} = s`, + GEN_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN + REWRITE_TAC[UNIONS_SUBSET; FORALL_IN_GSPEC; PATH_COMPONENT_SUBSET] THEN + REWRITE_TAC[SUBSET; UNIONS_GSPEC; IN_ELIM_THM] THEN + X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN EXISTS_TAC `x:real^N` THEN + ASM_REWRITE_TAC[] THEN REWRITE_TAC[IN] THEN + ASM_REWRITE_TAC[PATH_COMPONENT_REFL_EQ]);; + +let PATH_COMPONENT_TRANSLATION = prove + (`!a s x. path_component (IMAGE (\x. a + x) s) (a + x) = + IMAGE (\x. a + x) (path_component s x)`, + REWRITE_TAC[PATH_COMPONENT_SET] THEN GEOM_TRANSLATE_TAC[]);; + +add_translation_invariants [PATH_COMPONENT_TRANSLATION];; + +let PATH_COMPONENT_LINEAR_IMAGE = prove + (`!f s x. linear f /\ (!x y. f x = f y ==> x = y) /\ (!y. ?x. f x = y) + ==> path_component (IMAGE f s) (f x) = + IMAGE f (path_component s x)`, + REWRITE_TAC[PATH_COMPONENT_SET] THEN + GEOM_TRANSFORM_TAC[]);; + +add_linear_invariants [PATH_COMPONENT_LINEAR_IMAGE];; + +(* ------------------------------------------------------------------------- *) +(* Path connectedness of a space. *) +(* ------------------------------------------------------------------------- *) + +let path_connected = new_definition + `path_connected s <=> + !x y. x IN s /\ y IN s + ==> ?g. path g /\ (path_image g) SUBSET s /\ + pathstart g = x /\ pathfinish g = y`;; + +let PATH_CONNECTED_IFF_PATH_COMPONENT = prove + (`!s. path_connected s <=> !x y. x IN s /\ y IN s ==> path_component s x y`, + REWRITE_TAC[path_connected; path_component]);; + +let PATH_CONNECTED_COMPONENT_SET = prove + (`!s. path_connected s <=> !x. x IN s ==> path_component s x = s`, + REWRITE_TAC[PATH_CONNECTED_IFF_PATH_COMPONENT; GSYM SUBSET_ANTISYM_EQ] THEN + REWRITE_TAC[PATH_COMPONENT_SUBSET] THEN SET_TAC[]);; + +let PATH_COMPONENT_MONO = prove + (`!s t x. s SUBSET t ==> (path_component s x) SUBSET (path_component t x)`, + REWRITE_TAC[PATH_COMPONENT_SET] THEN SET_TAC[]);; + +let PATH_COMPONENT_MAXIMAL = prove + (`!s t x. x IN t /\ path_connected t /\ t SUBSET s + ==> t SUBSET (path_component s x)`, + REWRITE_TAC[path_connected; PATH_COMPONENT_SET; SUBSET; IN_ELIM_THM] THEN + MESON_TAC[]);; + +let PATH_COMPONENT_EQ = prove + (`!s x y. y IN path_component s x + ==> path_component s y = path_component s x`, + REWRITE_TAC[EXTENSION; IN] THEN + MESON_TAC[PATH_COMPONENT_SYM; PATH_COMPONENT_TRANS]);; + +let PATH_COMPONENT_PATH_IMAGE_PATHSTART = prove + (`!p x:real^N. + path p /\ x IN path_image p + ==> path_component (path_image p) (pathstart p) x`, + REWRITE_TAC[path_image; IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_IMAGE] THEN + REPEAT STRIP_TAC THEN ASM_CASES_TAC `x:real^1 = vec 0` THENL + [ASM_REWRITE_TAC[pathstart] THEN MATCH_MP_TAC PATH_COMPONENT_REFL THEN + MATCH_MP_TAC FUN_IN_IMAGE THEN REWRITE_TAC[IN_INTERVAL_1] THEN + REWRITE_TAC[DROP_VEC; REAL_POS]; + ALL_TAC] THEN + REWRITE_TAC[path_component] THEN + EXISTS_TAC `\y. (p:real^1->real^N)(drop x % y)` THEN + ASM_REWRITE_TAC[path; path_image; pathstart; pathfinish] THEN + REWRITE_TAC[VECTOR_MUL_RZERO] THEN REPEAT CONJ_TAC THENL + [MATCH_MP_TAC(REWRITE_RULE[o_DEF] CONTINUOUS_ON_COMPOSE) THEN + ASM_SIMP_TAC[CONTINUOUS_ON_CMUL; CONTINUOUS_ON_ID] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [path]) THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] CONTINUOUS_ON_SUBSET); + ONCE_REWRITE_TAC[GSYM o_DEF] THEN REWRITE_TAC[IMAGE_o] THEN + MATCH_MP_TAC IMAGE_SUBSET; + AP_TERM_TAC THEN REWRITE_TAC[GSYM DROP_EQ; DROP_CMUL; DROP_VEC] THEN + REWRITE_TAC[REAL_MUL_RID]] THEN + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_INTERVAL_1]) THEN + SIMP_TAC[IN_INTERVAL_1; DROP_CMUL; DROP_VEC; REAL_LE_MUL] THEN + REPEAT STRIP_TAC THEN GEN_REWRITE_TAC RAND_CONV [GSYM REAL_MUL_LID] THEN + MATCH_MP_TAC REAL_LE_MUL2 THEN ASM_REWRITE_TAC[]);; + +let PATH_CONNECTED_PATH_IMAGE = prove + (`!p:real^1->real^N. path p ==> path_connected(path_image p)`, + REPEAT STRIP_TAC THEN REWRITE_TAC[PATH_CONNECTED_IFF_PATH_COMPONENT] THEN + MAP_EVERY X_GEN_TAC [`x:real^N`; `y:real^N`] THEN STRIP_TAC THEN + MATCH_MP_TAC PATH_COMPONENT_TRANS THEN + EXISTS_TAC `pathstart p :real^N` THEN + ASM_MESON_TAC[PATH_COMPONENT_PATH_IMAGE_PATHSTART; PATH_COMPONENT_SYM]);; + +let PATH_CONNECTED_PATH_COMPONENT = prove + (`!s x:real^N. path_connected(path_component s x)`, + REPEAT GEN_TAC THEN REWRITE_TAC[path_connected; IN] THEN + MAP_EVERY X_GEN_TAC [`y:real^N`; `z:real^N`] THEN STRIP_TAC THEN + SUBGOAL_THEN `path_component s y (z:real^N)` MP_TAC THENL + [ASM_MESON_TAC[PATH_COMPONENT_SYM; PATH_COMPONENT_TRANS]; ALL_TAC] THEN + REWRITE_TAC[path_component] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `p:real^1->real^N` THEN + STRIP_TAC THEN ASM_REWRITE_TAC[SUBSET] THEN + X_GEN_TAC `w:real^N` THEN DISCH_TAC THEN + SUBGOAL_THEN `path_component s (x:real^N) = path_component s y` + SUBST1_TAC THENL [ASM_MESON_TAC[PATH_COMPONENT_EQ; IN]; ALL_TAC] THEN + MP_TAC(ISPECL [`p:real^1->real^N`; `w:real^N`] + PATH_COMPONENT_PATH_IMAGE_PATHSTART) THEN + ASM_REWRITE_TAC[] THEN REWRITE_TAC[IN] THEN + FIRST_ASSUM(MP_TAC o MATCH_MP PATH_COMPONENT_MONO) THEN + REWRITE_TAC[SUBSET; IN] THEN MESON_TAC[]);; + +let PATH_COMPONENT = prove + (`!s x y:real^N. + path_component s x y <=> + ?t. path_connected t /\ t SUBSET s /\ x IN t /\ y IN t`, + REPEAT GEN_TAC THEN EQ_TAC THEN STRIP_TAC THENL + [EXISTS_TAC `path_component s (x:real^N)` THEN + REWRITE_TAC[PATH_CONNECTED_PATH_COMPONENT; PATH_COMPONENT_SUBSET] THEN + FIRST_ASSUM(MP_TAC o MATCH_MP PATH_COMPONENT_IN) THEN + ASM_SIMP_TAC[IN; PATH_COMPONENT_REFL_EQ]; + REWRITE_TAC[path_component] THEN ASM_MESON_TAC[path_connected; SUBSET]]);; + +let PATH_COMPONENT_PATH_COMPONENT = prove + (`!s x:real^N. + path_component (path_component s x) x = path_component s x`, + REPEAT GEN_TAC THEN + ASM_CASES_TAC `(x:real^N) IN s` THENL + [MATCH_MP_TAC SUBSET_ANTISYM THEN + SIMP_TAC[PATH_COMPONENT_MONO; PATH_COMPONENT_SUBSET] THEN + MATCH_MP_TAC PATH_COMPONENT_MAXIMAL THEN + REWRITE_TAC[SUBSET_REFL; PATH_CONNECTED_PATH_COMPONENT] THEN + ASM_REWRITE_TAC[IN; PATH_COMPONENT_REFL_EQ]; + MATCH_MP_TAC(SET_RULE `s = {} /\ t = {} ==> s = t`) THEN + ASM_REWRITE_TAC[PATH_COMPONENT_EQ_EMPTY] THEN + ASM_MESON_TAC[SUBSET; PATH_COMPONENT_SUBSET]]);; + +let PATH_CONNECTED_LINEPATH = prove + (`!s a b:real^N. segment[a,b] SUBSET s ==> path_component s a b`, + REPEAT STRIP_TAC THEN REWRITE_TAC[path_component] THEN + EXISTS_TAC `linepath(a:real^N,b)` THEN + ASM_REWRITE_TAC[PATHSTART_LINEPATH; PATHFINISH_LINEPATH; PATH_LINEPATH] THEN + ASM_REWRITE_TAC[PATH_IMAGE_LINEPATH]);; + +let PATH_COMPONENT_DISJOINT = prove + (`!s a b. DISJOINT (path_component s a) (path_component s b) <=> + ~(a IN path_component s b)`, + REWRITE_TAC[DISJOINT; EXTENSION; IN_INTER; NOT_IN_EMPTY] THEN + REWRITE_TAC[IN] THEN MESON_TAC[PATH_COMPONENT_SYM; PATH_COMPONENT_TRANS]);; + +let PATH_COMPONENT_EQ_EQ = prove + (`!s x y:real^N. + path_component s x = path_component s y <=> + ~(x IN s) /\ ~(y IN s) \/ + x IN s /\ y IN s /\ path_component s x y`, + REPEAT GEN_TAC THEN ASM_CASES_TAC `(y:real^N) IN s` THENL + [ASM_CASES_TAC `(x:real^N) IN s` THEN ASM_REWRITE_TAC[] THENL + [REWRITE_TAC[FUN_EQ_THM] THEN + ASM_MESON_TAC[PATH_COMPONENT_TRANS; PATH_COMPONENT_REFL; + PATH_COMPONENT_SYM]; + ASM_MESON_TAC[PATH_COMPONENT_EQ_EMPTY]]; + RULE_ASSUM_TAC(REWRITE_RULE[GSYM PATH_COMPONENT_EQ_EMPTY]) THEN + ASM_REWRITE_TAC[PATH_COMPONENT_EQ_EMPTY] THEN + ONCE_REWRITE_TAC[PATH_COMPONENT_SYM_EQ] THEN + ASM_REWRITE_TAC[EMPTY] THEN ASM_MESON_TAC[PATH_COMPONENT_EQ_EMPTY]]);; + +(* ------------------------------------------------------------------------- *) +(* General "locally connected implies connected" type results. *) +(* ------------------------------------------------------------------------- *) + +let OPEN_GENERAL_COMPONENT = prove + (`!c. (!s x y. c s x y ==> x IN s /\ y IN s) /\ + (!s x y. c s x y ==> c s y x) /\ + (!s x y z. c s x y /\ c s y z ==> c s x z) /\ + (!s t x y. s SUBSET t /\ c s x y ==> c t x y) /\ + (!s x y e. y IN ball(x,e) /\ ball(x,e) SUBSET s + ==> c (ball(x,e)) x y) + ==> !s x:real^N. open s ==> open(c s x)`, + GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 (LABEL_TAC "IN") MP_TAC) THEN + DISCH_THEN(CONJUNCTS_THEN2 (LABEL_TAC "SYM") MP_TAC) THEN + DISCH_THEN(CONJUNCTS_THEN2 (LABEL_TAC "TRANS") MP_TAC) THEN + DISCH_THEN(CONJUNCTS_THEN2 (LABEL_TAC "SUBSET") (LABEL_TAC "BALL")) THEN + REPEAT GEN_TAC THEN REWRITE_TAC[OPEN_CONTAINS_BALL; SUBSET; IN_BALL] THEN + DISCH_TAC THEN X_GEN_TAC `y:real^N` THEN + REWRITE_TAC[SUBSET; IN] THEN STRIP_TAC THEN + SUBGOAL_THEN `(x:real^N) IN s /\ y IN s` STRIP_ASSUME_TAC THENL + [ASM_MESON_TAC[]; ALL_TAC] THEN + FIRST_X_ASSUM(MP_TAC o C MATCH_MP (ASSUME `(y:real^N) IN s`)) THEN + MATCH_MP_TAC MONO_EXISTS THEN + X_GEN_TAC `e:real` THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + X_GEN_TAC `z:real^N` THEN DISCH_TAC THEN + REMOVE_THEN "TRANS" MATCH_MP_TAC THEN EXISTS_TAC `y:real^N` THEN + ASM_REWRITE_TAC[] THEN REMOVE_THEN "SUBSET" MATCH_MP_TAC THEN + EXISTS_TAC `ball(y:real^N,e)` THEN ASM_REWRITE_TAC[SUBSET; IN_BALL] THEN + REMOVE_THEN "BALL" MATCH_MP_TAC THEN + REWRITE_TAC[SUBSET; IN_BALL] THEN ASM_MESON_TAC[]);; + +let OPEN_NON_GENERAL_COMPONENT = prove + (`!c. (!s x y. c s x y ==> x IN s /\ y IN s) /\ + (!s x y. c s x y ==> c s y x) /\ + (!s x y z. c s x y /\ c s y z ==> c s x z) /\ + (!s t x y. s SUBSET t /\ c s x y ==> c t x y) /\ + (!s x y e. y IN ball(x,e) /\ ball(x,e) SUBSET s + ==> c (ball(x,e)) x y) + ==> !s x:real^N. open s ==> open(s DIFF c s x)`, + GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 (LABEL_TAC "IN") MP_TAC) THEN + DISCH_THEN(CONJUNCTS_THEN2 (LABEL_TAC "SYM") MP_TAC) THEN + DISCH_THEN(CONJUNCTS_THEN2 (LABEL_TAC "TRANS") MP_TAC) THEN + DISCH_THEN(CONJUNCTS_THEN2 (LABEL_TAC "SUBSET") (LABEL_TAC "BALL")) THEN + REPEAT GEN_TAC THEN REWRITE_TAC[OPEN_CONTAINS_BALL; SUBSET; IN_BALL] THEN + DISCH_TAC THEN X_GEN_TAC `y:real^N` THEN REWRITE_TAC[IN_DIFF] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC (ASSUME_TAC o REWRITE_RULE[IN])) THEN + FIRST_X_ASSUM(MP_TAC o C MATCH_MP (ASSUME `(y:real^N) IN s`)) THEN + MATCH_MP_TAC MONO_EXISTS THEN + X_GEN_TAC `e:real` THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + X_GEN_TAC `z:real^N` THEN DISCH_TAC THEN ASM_SIMP_TAC[] THEN + REWRITE_TAC[IN] THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o check (is_neg o concl)) THEN REWRITE_TAC[] THEN + REMOVE_THEN "TRANS" MATCH_MP_TAC THEN EXISTS_TAC `z:real^N` THEN + ASM_REWRITE_TAC[] THEN REMOVE_THEN "SUBSET" MATCH_MP_TAC THEN + EXISTS_TAC `ball(y:real^N,e)` THEN ASM_REWRITE_TAC[SUBSET; IN_BALL] THEN + REMOVE_THEN "SYM" MATCH_MP_TAC THEN + REMOVE_THEN "BALL" MATCH_MP_TAC THEN + REWRITE_TAC[SUBSET; IN_BALL] THEN ASM_MESON_TAC[]);; + +let GENERAL_CONNECTED_OPEN = prove + (`!c. (!s x y. c s x y ==> x IN s /\ y IN s) /\ + (!s x y. c s x y ==> c s y x) /\ + (!s x y z. c s x y /\ c s y z ==> c s x z) /\ + (!s t x y. s SUBSET t /\ c s x y ==> c t x y) /\ + (!s x y e. y IN ball(x,e) /\ ball(x,e) SUBSET s + ==> c (ball(x,e)) x y) + ==> !s x y:real^N. open s /\ connected s /\ x IN s /\ y IN s + ==> c s x y`, + REPEAT STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [connected]) THEN + REWRITE_TAC[IN] THEN REWRITE_TAC[NOT_EXISTS_THM; LEFT_IMP_FORALL_THM] THEN + MAP_EVERY EXISTS_TAC + [`c (s:real^N->bool) (x:real^N):real^N->bool`; + `s DIFF (c (s:real^N->bool) (x:real^N))`] THEN + MATCH_MP_TAC(TAUT `a /\ b /\ c /\ d /\ e /\ (f ==> g) + ==> ~(a /\ b /\ c /\ d /\ e /\ ~f) ==> g`) THEN + REPEAT CONJ_TAC THENL + [MP_TAC(SPEC `c:(real^N->bool)->real^N->real^N->bool` + OPEN_GENERAL_COMPONENT) THEN ASM_MESON_TAC[]; + MP_TAC(SPEC `c:(real^N->bool)->real^N->real^N->bool` + OPEN_NON_GENERAL_COMPONENT) THEN ASM_MESON_TAC[]; + SET_TAC[]; + SET_TAC[]; + ALL_TAC; + ASM SET_TAC[]] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [OPEN_CONTAINS_BALL]) THEN + DISCH_THEN(MP_TAC o SPEC `x:real^N`) THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `e:real` STRIP_ASSUME_TAC) THEN + REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN EXISTS_TAC `x:real^N` THEN + ASM_REWRITE_TAC[IN_INTER] THEN REWRITE_TAC[IN] THEN + FIRST_ASSUM(MATCH_MP_TAC o + SPECL [`ball(x:real^N,e)`; `s:real^N->bool`]) THEN + ASM_MESON_TAC[CENTRE_IN_BALL]);; + +(* ------------------------------------------------------------------------- *) +(* Some useful lemmas about path-connectedness. *) +(* ------------------------------------------------------------------------- *) + +let CONVEX_IMP_PATH_CONNECTED = prove + (`!s:real^N->bool. convex s ==> path_connected s`, + REWRITE_TAC[CONVEX_ALT; path_connected] THEN REPEAT GEN_TAC THEN + DISCH_TAC THEN MAP_EVERY X_GEN_TAC [`x:real^N`; `y:real^N`] THEN + STRIP_TAC THEN EXISTS_TAC `\u. (&1 - drop u) % x + drop u % y:real^N` THEN + ASM_SIMP_TAC[pathstart; pathfinish; DROP_VEC; path; path_image; + SUBSET; FORALL_IN_IMAGE; IN_INTERVAL_1; GSYM FORALL_DROP] THEN + CONJ_TAC THENL [ALL_TAC; CONJ_TAC THEN VECTOR_ARITH_TAC] THEN + MATCH_MP_TAC CONTINUOUS_ON_ADD THEN CONJ_TAC THEN + MATCH_MP_TAC CONTINUOUS_ON_VMUL THEN + REWRITE_TAC[o_DEF; LIFT_SUB; LIFT_DROP; LIFT_NUM] THEN + SIMP_TAC[CONTINUOUS_ON_SUB; CONTINUOUS_ON_CONST; CONTINUOUS_ON_ID]);; + +let PATH_CONNECTED_UNIV = prove + (`path_connected(:real^N)`, + SIMP_TAC[CONVEX_IMP_PATH_CONNECTED; CONVEX_UNIV]);; + +let IS_INTERVAL_PATH_CONNECTED = prove + (`!s. is_interval s ==> path_connected s`, + SIMP_TAC[CONVEX_IMP_PATH_CONNECTED; IS_INTERVAL_CONVEX]);; + +let PATH_CONNECTED_INTERVAL = prove + (`(!a b:real^N. path_connected(interval[a,b])) /\ + (!a b:real^N. path_connected(interval(a,b)))`, + SIMP_TAC[IS_INTERVAL_PATH_CONNECTED; IS_INTERVAL_INTERVAL]);; + +let PATH_COMPONENT_UNIV = prove + (`!x. path_component(:real^N) x = (:real^N)`, + MESON_TAC[PATH_CONNECTED_COMPONENT_SET; PATH_CONNECTED_UNIV; IN_UNIV]);; + +let PATH_CONNECTED_IMP_CONNECTED = prove + (`!s:real^N->bool. path_connected s ==> connected s`, + GEN_TAC THEN + REWRITE_TAC[path_connected; CONNECTED_IFF_CONNECTED_COMPONENT] THEN + MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `x:real^N` THEN + MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `y:real^N` THEN + DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `g:real^1->real^N` STRIP_ASSUME_TAC) THEN + REWRITE_TAC[connected_component] THEN + EXISTS_TAC `path_image(g:real^1->real^N)` THEN + ASM_MESON_TAC[CONNECTED_PATH_IMAGE; PATHSTART_IN_PATH_IMAGE; + PATHFINISH_IN_PATH_IMAGE]);; + +let OPEN_PATH_COMPONENT = prove + (`!s x:real^N. open s ==> open(path_component s x)`, + MATCH_MP_TAC OPEN_GENERAL_COMPONENT THEN + REWRITE_TAC[PATH_COMPONENT_IN; PATH_COMPONENT_SYM; PATH_COMPONENT_TRANS; + PATH_COMPONENT_OF_SUBSET] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC(REWRITE_RULE[PATH_CONNECTED_IFF_PATH_COMPONENT] + (MATCH_MP CONVEX_IMP_PATH_CONNECTED (SPEC_ALL CONVEX_BALL))) THEN + ASM_MESON_TAC[CENTRE_IN_BALL; BALL_EQ_EMPTY; REAL_NOT_LE; NOT_IN_EMPTY]);; + +let OPEN_NON_PATH_COMPONENT = prove + (`!s x:real^N. open s ==> open(s DIFF path_component s x)`, + MATCH_MP_TAC OPEN_NON_GENERAL_COMPONENT THEN + REWRITE_TAC[PATH_COMPONENT_IN; PATH_COMPONENT_SYM; PATH_COMPONENT_TRANS; + PATH_COMPONENT_OF_SUBSET] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC(REWRITE_RULE[PATH_CONNECTED_IFF_PATH_COMPONENT] + (MATCH_MP CONVEX_IMP_PATH_CONNECTED (SPEC_ALL CONVEX_BALL))) THEN + ASM_MESON_TAC[CENTRE_IN_BALL; BALL_EQ_EMPTY; REAL_NOT_LE; NOT_IN_EMPTY]);; + +let PATH_CONNECTED_CONTINUOUS_IMAGE = prove + (`!f:real^M->real^N s. + f continuous_on s /\ path_connected s ==> path_connected (IMAGE f s)`, + REPEAT GEN_TAC THEN REWRITE_TAC[path_connected] THEN STRIP_TAC THEN + REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_IMAGE] THEN + X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN + X_GEN_TAC `y:real^M` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`x:real^M`; `y:real^M`]) THEN + ASM_REWRITE_TAC[path; path_image; pathstart; pathfinish] THEN + DISCH_THEN(X_CHOOSE_THEN `g:real^1->real^M` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `(f:real^M->real^N) o (g:real^1->real^M)` THEN CONJ_TAC THENL + [MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN ASM_REWRITE_TAC[] THEN + ASM_MESON_TAC[CONTINUOUS_ON_SUBSET]; + ASM_REWRITE_TAC[o_DEF] THEN ASM SET_TAC[]]);; + +let HOMEOMORPHIC_PATH_CONNECTEDNESS = prove + (`!s t. s homeomorphic t ==> (path_connected s <=> path_connected t)`, + REWRITE_TAC[homeomorphic; homeomorphism] THEN + MESON_TAC[PATH_CONNECTED_CONTINUOUS_IMAGE]);; + +let PATH_CONNECTED_LINEAR_IMAGE = prove + (`!f:real^M->real^N s. + path_connected s /\ linear f ==> path_connected(IMAGE f s)`, + SIMP_TAC[LINEAR_CONTINUOUS_ON; PATH_CONNECTED_CONTINUOUS_IMAGE]);; + +let PATH_CONNECTED_LINEAR_IMAGE_EQ = prove + (`!f s. linear f /\ (!x y. f x = f y ==> x = y) + ==> (path_connected (IMAGE f s) <=> path_connected s)`, + MATCH_ACCEPT_TAC(LINEAR_INVARIANT_RULE PATH_CONNECTED_LINEAR_IMAGE));; + +add_linear_invariants [PATH_CONNECTED_LINEAR_IMAGE_EQ];; + +let PATH_CONNECTED_EMPTY = prove + (`path_connected {}`, + REWRITE_TAC[path_connected; NOT_IN_EMPTY]);; + +let PATH_CONNECTED_SING = prove + (`!a:real^N. path_connected {a}`, + GEN_TAC THEN REWRITE_TAC[path_connected; IN_SING] THEN + REPEAT STRIP_TAC THEN EXISTS_TAC `linepath(a:real^N,a)` THEN + ASM_REWRITE_TAC[PATH_LINEPATH; PATHSTART_LINEPATH; PATHFINISH_LINEPATH] THEN + REWRITE_TAC[SEGMENT_REFL; PATH_IMAGE_LINEPATH; SUBSET_REFL]);; + +let PATH_CONNECTED_UNION = prove + (`!s t. path_connected s /\ path_connected t /\ ~(s INTER t = {}) + ==> path_connected (s UNION t)`, + REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; PATH_CONNECTED_IFF_PATH_COMPONENT] THEN + REWRITE_TAC[IN_INTER; IN_UNION] THEN + MESON_TAC[PATH_COMPONENT_OF_SUBSET; SUBSET_UNION; PATH_COMPONENT_TRANS]);; + +let PATH_CONNECTED_TRANSLATION = prove + (`!a s. path_connected s ==> path_connected (IMAGE (\x:real^N. a + x) s)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC PATH_CONNECTED_CONTINUOUS_IMAGE THEN + ASM_SIMP_TAC[CONTINUOUS_ON_ADD; CONTINUOUS_ON_ID; CONTINUOUS_ON_CONST]);; + +let PATH_CONNECTED_TRANSLATION_EQ = prove + (`!a s. path_connected (IMAGE (\x:real^N. a + x) s) <=> path_connected s`, + REWRITE_TAC[path_connected] THEN GEOM_TRANSLATE_TAC[]);; + +add_translation_invariants [PATH_CONNECTED_TRANSLATION_EQ];; + +let PATH_CONNECTED_PCROSS = prove + (`!s:real^M->bool t:real^N->bool. + path_connected s /\ path_connected t + ==> path_connected (s PCROSS t)`, + REPEAT GEN_TAC THEN REWRITE_TAC[PCROSS; path_connected] THEN DISCH_TAC THEN + REWRITE_TAC[FORALL_PASTECART; IN_ELIM_PASTECART_THM] THEN + MAP_EVERY X_GEN_TAC [`x1:real^M`; `y1:real^N`; `x2:real^M`; `y2:real^N`] THEN + STRIP_TAC THEN FIRST_X_ASSUM(CONJUNCTS_THEN2 + (MP_TAC o SPECL [`x1:real^M`; `x2:real^M`]) + (MP_TAC o SPECL [`y1:real^N`; `y2:real^N`])) THEN + ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `h:real^1->real^N` THEN STRIP_TAC THEN + X_GEN_TAC `g:real^1->real^M` THEN STRIP_TAC THEN + EXISTS_TAC `(\t. pastecart (x1:real^M) ((h:real^1->real^N) t)) ++ + (\t. pastecart ((g:real^1->real^M) t) (y2:real^N))` THEN + RULE_ASSUM_TAC(REWRITE_RULE[pathstart; pathfinish; path]) THEN + RULE_ASSUM_TAC(REWRITE_RULE[path_image; FORALL_IN_IMAGE; SUBSET]) THEN + REPEAT CONJ_TAC THENL + [MATCH_MP_TAC PATH_JOIN_IMP THEN REPEAT CONJ_TAC THENL + [REWRITE_TAC[path] THEN MATCH_MP_TAC CONTINUOUS_ON_PASTECART THEN + ASM_REWRITE_TAC[CONTINUOUS_ON_CONST]; + REWRITE_TAC[path] THEN MATCH_MP_TAC CONTINUOUS_ON_PASTECART THEN + ASM_REWRITE_TAC[CONTINUOUS_ON_CONST]; + ASM_REWRITE_TAC[pathstart; pathfinish]]; + MATCH_MP_TAC SUBSET_PATH_IMAGE_JOIN THEN + ASM_SIMP_TAC[path_image; FORALL_IN_IMAGE; SUBSET; IN_ELIM_PASTECART_THM]; + REWRITE_TAC[PATHSTART_JOIN] THEN ASM_REWRITE_TAC[pathstart]; + REWRITE_TAC[PATHFINISH_JOIN] THEN ASM_REWRITE_TAC[pathfinish]]);; + +let PATH_CONNECTED_PCROSS_EQ = prove + (`!s:real^M->bool t:real^N->bool. + path_connected(s PCROSS t) <=> + s = {} \/ t = {} \/ path_connected s /\ path_connected t`, + REPEAT GEN_TAC THEN + ASM_CASES_TAC `s:real^M->bool = {}` THEN + ASM_REWRITE_TAC[PCROSS_EMPTY; PATH_CONNECTED_EMPTY] THEN + ASM_CASES_TAC `t:real^N->bool = {}` THEN + ASM_REWRITE_TAC[PCROSS_EMPTY; PATH_CONNECTED_EMPTY] THEN + EQ_TAC THEN REWRITE_TAC[PATH_CONNECTED_PCROSS] THEN REPEAT STRIP_TAC THENL + [MP_TAC(ISPECL [`fstcart:real^(M,N)finite_sum->real^M`; + `(s:real^M->bool) PCROSS (t:real^N->bool)`] + PATH_CONNECTED_LINEAR_IMAGE) THEN + ASM_REWRITE_TAC[LINEAR_FSTCART]; + MP_TAC(ISPECL [`sndcart:real^(M,N)finite_sum->real^N`; + `(s:real^M->bool) PCROSS (t:real^N->bool)`] + PATH_CONNECTED_LINEAR_IMAGE) THEN + ASM_REWRITE_TAC[LINEAR_SNDCART]] THEN + MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN + REWRITE_TAC[EXTENSION; IN_IMAGE; EXISTS_PASTECART; PASTECART_IN_PCROSS; + FSTCART_PASTECART; SNDCART_PASTECART] THEN + ASM SET_TAC[]);; + +let PATH_CONNECTED_SCALING = prove + (`!s:real^N->bool c. + path_connected s ==> path_connected (IMAGE (\x. c % x) s)`, + REPEAT STRIP_TAC THEN + MATCH_MP_TAC PATH_CONNECTED_CONTINUOUS_IMAGE THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC CONTINUOUS_AT_IMP_CONTINUOUS_ON THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC LINEAR_CONTINUOUS_AT THEN + REWRITE_TAC[linear] THEN CONJ_TAC THEN VECTOR_ARITH_TAC);; + +let PATH_CONNECTED_NEGATIONS = prove + (`!s:real^N->bool. + path_connected s ==> path_connected (IMAGE (--) s)`, + REPEAT STRIP_TAC THEN + MATCH_MP_TAC PATH_CONNECTED_CONTINUOUS_IMAGE THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC CONTINUOUS_AT_IMP_CONTINUOUS_ON THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC LINEAR_CONTINUOUS_AT THEN + REWRITE_TAC[linear] THEN CONJ_TAC THEN VECTOR_ARITH_TAC);; + +let PATH_CONNECTED_SUMS = prove + (`!s t:real^N->bool. + path_connected s /\ path_connected t + ==> path_connected {x + y | x IN s /\ y IN t}`, + REPEAT GEN_TAC THEN + DISCH_THEN(MP_TAC o MATCH_MP PATH_CONNECTED_PCROSS) THEN + DISCH_THEN(MP_TAC o ISPEC + `\z. (fstcart z + sndcart z:real^N)` o + MATCH_MP (REWRITE_RULE[IMP_CONJ_ALT] + PATH_CONNECTED_CONTINUOUS_IMAGE)) THEN + SIMP_TAC[CONTINUOUS_ON_ADD; LINEAR_CONTINUOUS_ON; LINEAR_FSTCART; + LINEAR_SNDCART; PCROSS] THEN + MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN + REWRITE_TAC[EXTENSION; IN_IMAGE; IN_ELIM_THM; EXISTS_PASTECART] THEN + REWRITE_TAC[PASTECART_INJ; FSTCART_PASTECART; SNDCART_PASTECART] THEN + MESON_TAC[]);; + +let IS_INTERVAL_PATH_CONNECTED_1 = prove + (`!s:real^1->bool. is_interval s <=> path_connected s`, + MESON_TAC[CONVEX_IMP_PATH_CONNECTED; PATH_CONNECTED_IMP_CONNECTED; + IS_INTERVAL_CONNECTED_1; IS_INTERVAL_CONVEX_1]);; + +(* ------------------------------------------------------------------------- *) +(* More stuff about segments. *) +(* ------------------------------------------------------------------------- *) + +let SEGMENT_OPEN_SUBSET_CLOSED = prove + (`!a b. segment(a,b) SUBSET segment[a,b]`, + REWRITE_TAC[CONJUNCT2(SPEC_ALL segment)] THEN SET_TAC[]);; + +let CLOSED_SEGMENT = prove + (`!a b. closed(segment[a,b])`, + REPEAT GEN_TAC THEN REWRITE_TAC[SEGMENT_CONVEX_HULL] THEN + MATCH_MP_TAC COMPACT_IMP_CLOSED THEN MATCH_MP_TAC COMPACT_CONVEX_HULL THEN + MATCH_MP_TAC FINITE_IMP_COMPACT THEN SIMP_TAC[FINITE_RULES]);; + +let SEGMENT_IMAGE_INTERVAL = prove + (`(!a b. segment[a,b] = + IMAGE (\u. (&1 - drop u) % a + drop u % b) + (interval[vec 0,vec 1])) /\ + (!a b. ~(a = b) + ==> segment(a,b) = + IMAGE (\u. (&1 - drop u) % a + drop u % b) + (interval(vec 0,vec 1)))`, + REPEAT STRIP_TAC THEN + REWRITE_TAC[EXTENSION; IN_IMAGE; IN_INTERVAL_1; IN_SEGMENT] THEN + ASM_REWRITE_TAC[GSYM EXISTS_DROP; DROP_VEC] THEN MESON_TAC[]);; + +let CLOSURE_SEGMENT = prove + (`(!a b:real^N. closure(segment[a,b]) = segment[a,b]) /\ + (!a b:real^N. closure(segment(a,b)) = if a = b then {} else segment[a,b])`, + REWRITE_TAC[CLOSURE_EQ; CLOSED_SEGMENT] THEN + REPEAT GEN_TAC THEN COND_CASES_TAC THEN + ASM_REWRITE_TAC[SEGMENT_REFL; CLOSURE_EMPTY] THEN + ASM_SIMP_TAC[SEGMENT_IMAGE_INTERVAL] THEN + ASM_SIMP_TAC[CONV_RULE(RAND_CONV SYM_CONV) (SPEC_ALL CLOSURE_OPEN_INTERVAL); + INTERVAL_EQ_EMPTY_1; DROP_VEC; REAL_ARITH `~(&1 <= &0)`] THEN + SUBGOAL_THEN + `(\u. (&1 - drop u) % a + drop u % (b:real^N)) = + (\x. a + x) o (\u. drop u % (b - a))` + SUBST1_TAC THENL + [REWRITE_TAC[FUN_EQ_THM; o_THM] THEN VECTOR_ARITH_TAC; ALL_TAC] THEN + REWRITE_TAC[IMAGE_o; CLOSURE_TRANSLATION] THEN AP_TERM_TAC THEN + MATCH_MP_TAC CLOSURE_INJECTIVE_LINEAR_IMAGE THEN + ASM_REWRITE_TAC[VECTOR_MUL_RCANCEL; VECTOR_SUB_EQ; DROP_EQ] THEN + REWRITE_TAC[linear; DROP_ADD; DROP_CMUL] THEN VECTOR_ARITH_TAC);; + +let AFFINE_HULL_SEGMENT = prove + (`(!a b:real^N. affine hull (segment [a,b]) = affine hull {a,b}) /\ + (!a b:real^N. affine hull (segment(a,b)) = + if a = b then {} else affine hull {a,b})`, + REWRITE_TAC[SEGMENT_CONVEX_HULL; AFFINE_HULL_CONVEX_HULL] THEN + REPEAT GEN_TAC THEN GEN_REWRITE_TAC LAND_CONV [GSYM AFFINE_HULL_CLOSURE] THEN + REWRITE_TAC[CLOSURE_SEGMENT] THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[AFFINE_HULL_EMPTY] THEN + REWRITE_TAC[SEGMENT_CONVEX_HULL; AFFINE_HULL_CONVEX_HULL]);; + +let SEGMENT_AS_BALL = prove + (`(!a b. segment[a:real^N,b] = + affine hull {a,b} INTER cball(inv(&2) % (a + b),norm(b - a) / &2)) /\ + (!a b. segment(a:real^N,b) = + affine hull {a,b} INTER ball(inv(&2) % (a + b),norm(b - a) / &2))`, + REPEAT STRIP_TAC THEN + (ASM_CASES_TAC `b:real^N = a` THEN + ASM_REWRITE_TAC[SEGMENT_REFL; VECTOR_SUB_REFL; NORM_0] THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN + REWRITE_TAC[BALL_TRIVIAL; CBALL_TRIVIAL] THENL + [REWRITE_TAC[INTER_EMPTY; INSERT_AC] THEN + REWRITE_TAC[VECTOR_ARITH `&1 / &2 % (a + a) = a`] THEN + REWRITE_TAC[SET_RULE `a = b INTER a <=> a SUBSET b`; HULL_SUBSET]; + ASM_REWRITE_TAC[EXTENSION; IN_SEGMENT; IN_INTER; AFFINE_HULL_2] THEN + X_GEN_TAC `y:real^N` THEN REWRITE_TAC[IN_ELIM_THM] THEN + ONCE_REWRITE_TAC[SWAP_EXISTS_THM] THEN + REWRITE_TAC[REAL_ARITH `u + v:real = &1 <=> u = &1 - v`] THEN + REWRITE_TAC[UNWIND_THM2] THEN REWRITE_TAC[LEFT_AND_EXISTS_THM] THEN + AP_TERM_TAC THEN GEN_REWRITE_TAC I [FUN_EQ_THM] THEN + X_GEN_TAC `u:real` THEN REWRITE_TAC[] THEN + ASM_CASES_TAC `y:real^N = (&1 - u) % a + u % b` THEN + ASM_REWRITE_TAC[] THEN REWRITE_TAC[IN_BALL; IN_CBALL; dist; VECTOR_ARITH + `&1 / &2 % (a + b) - ((&1 - u) % a + u % b):real^N = + (&1 / &2 - u) % (b - a)`] THEN + ASM_SIMP_TAC[NORM_MUL; REAL_LT_MUL_EQ; REAL_LE_MUL_EQ; NORM_POS_LT; + VECTOR_SUB_EQ; REAL_ARITH `a * n < n / &2 <=> &0 < n * (inv(&2) - a)`; + REAL_ARITH `a * n <= n / &2 <=> &0 <= n * (inv(&2) - a)`] THEN + REAL_ARITH_TAC]));; + +let CONVEX_SEGMENT = prove + (`(!a b. convex(segment[a,b])) /\ (!a b. convex(segment(a,b)))`, + REWRITE_TAC[SEGMENT_AS_BALL] THEN + SIMP_TAC[CONVEX_INTER; CONVEX_BALL; CONVEX_CBALL; + AFFINE_IMP_CONVEX; AFFINE_AFFINE_HULL]);; + +let RELATIVE_INTERIOR_SEGMENT = prove + (`(!a b:real^N. + relative_interior(segment[a,b]) = if a = b then {a} else segment(a,b)) /\ + (!a b:real^N. relative_interior(segment(a,b)) = segment(a,b))`, + MATCH_MP_TAC(TAUT `b /\ (b ==> a) ==> a /\ b`) THEN CONJ_TAC THENL + [REPEAT GEN_TAC THEN ASM_CASES_TAC `a:real^N = b` THEN + ASM_REWRITE_TAC[SEGMENT_REFL; RELATIVE_INTERIOR_EMPTY] THEN + REWRITE_TAC[RELATIVE_INTERIOR_EQ; OPEN_IN_OPEN] THEN + ASM_REWRITE_TAC[AFFINE_HULL_SEGMENT] THEN + EXISTS_TAC `ball(inv(&2) % (a + b):real^N,norm(b - a) / &2)` THEN + REWRITE_TAC[OPEN_BALL; SEGMENT_AS_BALL]; + REPEAT STRIP_TAC THEN COND_CASES_TAC THEN + ASM_REWRITE_TAC[SEGMENT_REFL; RELATIVE_INTERIOR_SING] THEN + MP_TAC(ISPECL [`a:real^N`; `b:real^N`] (CONJUNCT2 CLOSURE_SEGMENT)) THEN + ASM_REWRITE_TAC[] THEN DISCH_THEN(SUBST1_TAC o SYM) THEN + FIRST_X_ASSUM(fun th -> GEN_REWRITE_TAC RAND_CONV [GSYM th]) THEN + MATCH_MP_TAC CONVEX_RELATIVE_INTERIOR_CLOSURE THEN + REWRITE_TAC[CONVEX_SEGMENT]]);; + +let PATH_CONNECTED_SEGMENT = prove + (`(!a b. path_connected(segment[a,b])) /\ + (!a b. path_connected(segment(a,b)))`, + SIMP_TAC[CONVEX_IMP_PATH_CONNECTED; CONVEX_SEGMENT]);; + +let CONNECTED_SEGMENT = prove + (`(!a b. connected(segment[a,b])) /\ (!a b. connected(segment(a,b)))`, + SIMP_TAC[CONVEX_CONNECTED; CONVEX_SEGMENT]);; + +let CONVEX_SEMIOPEN_SEGMENT = prove + (`(!a b:real^N. convex(segment[a,b] DELETE a)) /\ + (!a b:real^N. convex(segment[a,b] DELETE b))`, + MATCH_MP_TAC(TAUT `(a ==> b) /\ a ==> a /\ b`) THEN + CONJ_TAC THENL [MESON_TAC[SEGMENT_SYM]; ALL_TAC] THEN + REPEAT GEN_TAC THEN ASM_CASES_TAC `b:real^N = a` THEN + ASM_SIMP_TAC[SEGMENT_REFL; SET_RULE `{a} DELETE a = {}`; CONVEX_EMPTY] THEN + REWRITE_TAC[CONVEX_ALT; IN_DELETE] THEN + SIMP_TAC[REWRITE_RULE[CONVEX_ALT] CONVEX_SEGMENT] THEN + REWRITE_TAC[IN_SEGMENT] THEN REPEAT GEN_TAC THEN STRIP_TAC THEN + ASM_REWRITE_TAC[VECTOR_ADD_LDISTRIB; VECTOR_MUL_ASSOC; + GSYM VECTOR_ADD_ASSOC] THEN + ASM_REWRITE_TAC[VECTOR_ARITH + `x % a + y % b + z % a + w % b:real^N = a <=> + (&1 - x - z) % a = (w + y) % b`] THEN + ASM_REWRITE_TAC[VECTOR_MUL_LCANCEL; REAL_ARITH + `&1 - (&1 - u) * (&1 - v) - u * (&1 - w) = + u * w + (&1 - u) * v`] THEN + ASM_SIMP_TAC[REAL_LE_MUL; REAL_SUB_LE; REAL_ARITH + `&0 <= x /\ &0 <= y ==> (x + y = &0 <=> x = &0 /\ y = &0)`] THEN + REWRITE_TAC[REAL_ENTIRE; REAL_ARITH `&1 - x = &0 <=> x = &1`] THEN + DISCH_THEN(MP_TAC o MATCH_MP (REAL_ARITH + `(u = &0 \/ w = &0) /\ (u = &1 \/ v = &0) + ==> u = &0 /\ v = &0 \/ u = &1 /\ w = &0 \/ v = &0 /\ w = &0`)) THEN + DISCH_THEN(REPEAT_TCL DISJ_CASES_THEN (CONJUNCTS_THEN SUBST_ALL_TAC)) THEN + ASM_MESON_TAC[VECTOR_ARITH `(&1 - &0) % a + &0 % b:real^N = a`]);; + +let PATH_CONNECTED_SEMIOPEN_SEGMENT = prove + (`(!a b:real^N. path_connected(segment[a,b] DELETE a)) /\ + (!a b:real^N. path_connected(segment[a,b] DELETE b))`, + SIMP_TAC[CONVEX_IMP_PATH_CONNECTED; CONVEX_SEMIOPEN_SEGMENT]);; + +let CONNECTED_SEMIOPEN_SEGMENT = prove + (`(!a b:real^N. connected(segment[a,b] DELETE a)) /\ + (!a b:real^N. connected(segment[a,b] DELETE b))`, + SIMP_TAC[CONVEX_CONNECTED; CONVEX_SEMIOPEN_SEGMENT]);; + +let SEGMENT_EQ_EMPTY = prove + (`(!a b:real^N. ~(segment[a,b] = {})) /\ + (!a b:real^N. segment(a,b) = {} <=> a = b)`, + REWRITE_TAC[SEGMENT_CONVEX_HULL; CONVEX_HULL_EQ_EMPTY; NOT_INSERT_EMPTY] THEN + REPEAT GEN_TAC THEN ASM_CASES_TAC `a:real^N = b` THEN + ASM_REWRITE_TAC[SEGMENT_REFL] THEN + ASM_MESON_TAC[NOT_IN_EMPTY; MIDPOINT_IN_SEGMENT]);; + +let FINITE_SEGMENT = prove + (`(!a b:real^N. FINITE(segment[a,b]) <=> a = b) /\ + (!a b:real^N. FINITE(segment(a,b)) <=> a = b)`, + REWRITE_TAC[open_segment; SET_RULE `s DIFF {a,b} = s DELETE a DELETE b`] THEN + REWRITE_TAC[FINITE_DELETE] THEN REPEAT GEN_TAC THEN + ASM_CASES_TAC `a:real^N = b` THEN + ASM_REWRITE_TAC[SEGMENT_REFL; FINITE_SING] THEN + REWRITE_TAC[SEGMENT_IMAGE_INTERVAL] THEN + W(MP_TAC o PART_MATCH (lhs o rand) FINITE_IMAGE_INJ_EQ o rand o snd) THEN + ANTS_TAC THENL + [REWRITE_TAC[VECTOR_ARITH + `(&1 - u) % a + u % b:real^N = (&1 - v) % a + v % b <=> + (u - v) % (b - a) = vec 0`] THEN + ASM_SIMP_TAC[VECTOR_MUL_EQ_0; VECTOR_SUB_EQ; REAL_SUB_0; DROP_EQ]; + DISCH_THEN SUBST1_TAC THEN REWRITE_TAC[FINITE_INTERVAL_1] THEN + REWRITE_TAC[DROP_VEC] THEN REAL_ARITH_TAC]);; + +let SEGMENT_EQ_SING = prove + (`(!a b c:real^N. segment[a,b] = {c} <=> a = c /\ b = c) /\ + (!a b c:real^N. ~(segment(a,b) = {c}))`, + REWRITE_TAC[SEGMENT_CONVEX_HULL; CONVEX_HULL_EQ_SING] THEN + CONJ_TAC THENL [SET_TAC[]; REPEAT GEN_TAC] THEN + ASM_CASES_TAC `a:real^N = b` THEN + ASM_REWRITE_TAC[SEGMENT_REFL; NOT_INSERT_EMPTY] THEN + DISCH_TAC THEN + MP_TAC(ISPECL [`a:real^N`; `b:real^N`] (CONJUNCT2 FINITE_SEGMENT)) THEN + ASM_REWRITE_TAC[FINITE_SING]);; + +let SUBSET_SEGMENT_OPEN_CLOSED = prove + (`!a b c d:real^N. + segment(a,b) SUBSET segment(c,d) <=> + a = b \/ segment[a,b] SUBSET segment[c,d]`, + REPEAT GEN_TAC THEN EQ_TAC THENL + [ASM_CASES_TAC `a:real^N = b` THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(MP_TAC o MATCH_MP SUBSET_CLOSURE) THEN + ASM_REWRITE_TAC[CLOSURE_SEGMENT] THEN + COND_CASES_TAC THEN REWRITE_TAC[SUBSET_EMPTY; SEGMENT_EQ_EMPTY]; + ALL_TAC] THEN + DISCH_THEN(DISJ_CASES_THEN2 SUBST1_TAC MP_TAC) THEN + REWRITE_TAC[SEGMENT_REFL; EMPTY_SUBSET] THEN + ABBREV_TAC `m:real^N = d - c` THEN POP_ASSUM MP_TAC THEN + GEOM_NORMALIZE_TAC `m:real^N` THEN + SIMP_TAC[VECTOR_SUB_EQ; SEGMENT_REFL; SEGMENT_EQ_SING; SEGMENT_EQ_EMPTY; + SET_RULE `s SUBSET {a} <=> s = {a} \/ s = {}`; SUBSET_REFL] THEN + X_GEN_TAC `m:real^N` THEN DISCH_TAC THEN REPEAT GEN_TAC THEN + DISCH_THEN(SUBST_ALL_TAC o SYM) THEN POP_ASSUM MP_TAC THEN + GEOM_ORIGIN_TAC `c:real^N` THEN GEOM_BASIS_MULTIPLE_TAC 1 `d:real^N` THEN + X_GEN_TAC `d:real` THEN DISCH_TAC THEN + MAP_EVERY X_GEN_TAC [`x:real^N`; `y:real^N`] THEN + SIMP_TAC[VECTOR_SUB_RZERO; NORM_MUL; NORM_BASIS; DIMINDEX_GE_1; LE_REFL] THEN + ASM_REWRITE_TAC[real_abs; REAL_MUL_RID] THEN DISCH_THEN SUBST_ALL_TAC THEN + POP_ASSUM(K ALL_TAC) THEN DISCH_TAC THEN + SUBGOAL_THEN `collinear{vec 0:real^N,&1 % basis 1,x} /\ + collinear{vec 0:real^N,&1 % basis 1,y}` + MP_TAC THENL + [ONCE_REWRITE_TAC[SET_RULE `{a,b,c} = {a,c,b}`] THEN + CONJ_TAC THEN MATCH_MP_TAC BETWEEN_IMP_COLLINEAR THEN + REWRITE_TAC[BETWEEN_IN_SEGMENT] THEN + ASM_MESON_TAC[SUBSET; ENDS_IN_SEGMENT]; + ALL_TAC] THEN + SIMP_TAC[COLLINEAR_LEMMA_ALT; BASIS_NONZERO; DIMINDEX_GE_1; LE_REFL; + VECTOR_ARITH `&1 % x:real^N = vec 0 <=> x = vec 0`] THEN + REWRITE_TAC[IMP_CONJ; VECTOR_MUL_ASSOC; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `a:real` THEN REWRITE_TAC[REAL_MUL_RID] THEN + DISCH_THEN SUBST_ALL_TAC THEN X_GEN_TAC `b:real` THEN + DISCH_THEN SUBST_ALL_TAC THEN POP_ASSUM MP_TAC THEN + SUBST1_TAC(VECTOR_ARITH `vec 0:real^N = &0 % basis 1`) THEN + ASM_SIMP_TAC[SEGMENT_SCALAR_MULTIPLE; VECTOR_MUL_RCANCEL; BASIS_NONZERO; + DIMINDEX_GE_1; LE_REFL; SET_RULE + `(!x y. x % v = y % v <=> x = y) + ==> ({x % v | P x} SUBSET {x % v | Q x} <=> + {x | P x} SUBSET {x | Q x})`] THEN + REWRITE_TAC[REAL_ARITH `a <= x /\ x <= b \/ b <= x /\ x <= a <=> + min a b <= x /\ x <= max a b`; + REAL_ARITH `a < x /\ x < b \/ b < x /\ x < a <=> + min a b < x /\ x < max a b`] THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN + REWRITE_TAC[SUBSET; IN_ELIM_THM] THEN DISCH_TAC THEN + X_GEN_TAC `x:real` THEN + FIRST_X_ASSUM(fun th -> MAP_EVERY (MP_TAC o C SPEC th) + [`min (a:real) b`; `max (a:real) b`]) THEN + REAL_ARITH_TAC);; + +let SUBSET_SEGMENT = prove + (`(!a b c d:real^N. + segment[a,b] SUBSET segment[c,d] <=> + a IN segment[c,d] /\ b IN segment[c,d]) /\ + (!a b c d:real^N. + segment[a,b] SUBSET segment(c,d) <=> + a IN segment(c,d) /\ b IN segment(c,d)) /\ + (!a b c d:real^N. + segment(a,b) SUBSET segment[c,d] <=> + a = b \/ a IN segment[c,d] /\ b IN segment[c,d]) /\ + (!a b c d:real^N. + segment(a,b) SUBSET segment(c,d) <=> + a = b \/ a IN segment[c,d] /\ b IN segment[c,d])`, + MATCH_MP_TAC(TAUT `(a /\ b) /\ (a /\ b ==> c) ==> a /\ b /\ c`) THEN + CONJ_TAC THENL + [REPEAT STRIP_TAC THEN + GEN_REWRITE_TAC (LAND_CONV o LAND_CONV) [SEGMENT_CONVEX_HULL] THEN + SIMP_TAC[SUBSET_HULL; CONVEX_SEGMENT] THEN SET_TAC[]; + STRIP_TAC THEN ASM_REWRITE_TAC[SUBSET_SEGMENT_OPEN_CLOSED] THEN + REPEAT GEN_TAC THEN MATCH_MP_TAC EQ_TRANS THEN + EXISTS_TAC `closure(segment(a:real^N,b)) SUBSET segment[c,d]` THEN + CONJ_TAC THENL [SIMP_TAC[CLOSURE_MINIMAL_EQ; CLOSED_SEGMENT]; ALL_TAC] THEN + REWRITE_TAC[CLOSURE_SEGMENT] THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[EMPTY_SUBSET]]);; + +let INTERIOR_SEGMENT = prove + (`(!a b:real^N. interior(segment[a,b]) = + if 2 <= dimindex(:N) then {} else segment(a,b)) /\ + (!a b:real^N. interior(segment(a,b)) = + if 2 <= dimindex(:N) then {} else segment(a,b))`, + REWRITE_TAC[AND_FORALL_THM] THEN REPEAT GEN_TAC THEN + ASM_CASES_TAC `2 <= dimindex(:N)` THEN ASM_REWRITE_TAC[] THENL + [MATCH_MP_TAC(SET_RULE `t SUBSET s /\ s = {} ==> s = {} /\ t = {}`) THEN + SIMP_TAC[SEGMENT_OPEN_SUBSET_CLOSED; SUBSET_INTERIOR] THEN + REWRITE_TAC[SEGMENT_CONVEX_HULL] THEN + MATCH_MP_TAC EMPTY_INTERIOR_CONVEX_HULL THEN + REWRITE_TAC[FINITE_INSERT; FINITE_EMPTY] THEN FIRST_ASSUM + (MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ_ALT] LE_TRANS)) THEN + SIMP_TAC[CARD_CLAUSES; FINITE_INSERT; FINITE_EMPTY] THEN ARITH_TAC; + ASM_CASES_TAC `a:real^N = b` THEN + ASM_SIMP_TAC[SEGMENT_REFL; INTERIOR_EMPTY; EMPTY_INTERIOR_FINITE; + FINITE_SING] THEN + SUBGOAL_THEN + `affine hull (segment[a,b]) = (:real^N) /\ + affine hull (segment(a,b)) = (:real^N)` + (fun th -> ASM_SIMP_TAC[th; GSYM RELATIVE_INTERIOR_INTERIOR; + RELATIVE_INTERIOR_SEGMENT]) THEN + ASM_REWRITE_TAC[AFFINE_HULL_SEGMENT] THEN + MATCH_MP_TAC AFFINE_INDEPENDENT_SPAN_GT THEN + REWRITE_TAC[AFFINE_INDEPENDENT_2] THEN + ASM_SIMP_TAC[CARD_CLAUSES; FINITE_RULES; IN_INSERT; NOT_IN_EMPTY] THEN + ASM_ARITH_TAC]);; + +let SEGMENT_EQ = prove + (`(!a b c d:real^N. + segment[a,b] = segment[c,d] <=> {a,b} = {c,d}) /\ + (!a b c d:real^N. + ~(segment[a,b] = segment(c,d))) /\ + (!a b c d:real^N. + ~(segment(a,b) = segment[c,d])) /\ + (!a b c d:real^N. + segment(a,b) = segment(c,d) <=> a = b /\ c = d \/ {a,b} = {c,d})`, + MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN CONJ_TAC THENL + [REPEAT GEN_TAC THEN EQ_TAC THENL + [DISCH_THEN(fun th -> MP_TAC th THEN + MP_TAC(AP_TERM `\s:real^N->bool. s DIFF relative_interior s` th)) THEN + REWRITE_TAC[RELATIVE_INTERIOR_SEGMENT] THEN + REPEAT(COND_CASES_TAC THEN ASM_REWRITE_TAC[SEGMENT_REFL]) THEN + SIMP_TAC[ENDS_IN_SEGMENT; open_segment; SET_RULE + `a IN s /\ b IN s ==> s DIFF (s DIFF {a,b}) = {a,b}`] THEN + ASM SET_TAC[SEGMENT_EQ_SING]; + SIMP_TAC[SEGMENT_CONVEX_HULL]]; + DISCH_TAC] THEN + MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN CONJ_TAC THENL + [REPEAT STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o AP_TERM `closed:(real^N->bool)->bool`) THEN + REWRITE_TAC[CLOSED_SEGMENT] THEN + REWRITE_TAC[GSYM CLOSURE_EQ; CLOSURE_SEGMENT] THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[] THENL + [ASM SET_TAC[SEGMENT_EQ_EMPTY]; + REWRITE_TAC[open_segment; ENDS_IN_SEGMENT; SET_RULE + `s = s DIFF {a,b} <=> ~(a IN s) /\ ~(b IN s)`]]; + DISCH_TAC THEN CONJ_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN + REPEAT GEN_TAC THEN ASM_CASES_TAC `c:real^N = d` THEN + ASM_REWRITE_TAC[SEGMENT_EQ_EMPTY; SEGMENT_REFL] THENL + [ASM SET_TAC[]; ALL_TAC] THEN + CONV_TAC(BINOP_CONV SYM_CONV)THEN + ASM_CASES_TAC `a:real^N = b` THEN + ASM_REWRITE_TAC[SEGMENT_EQ_EMPTY; SEGMENT_REFL] THENL + [ASM SET_TAC[]; ALL_TAC] THEN + ASM_REWRITE_TAC[GSYM SUBSET_ANTISYM_EQ; SUBSET_SEGMENT_OPEN_CLOSED] THEN + ASM_REWRITE_TAC[SUBSET_ANTISYM_EQ]]);; + +let COMPACT_SEGMENT = prove + (`!a b. compact(segment[a,b])`, + SIMP_TAC[SEGMENT_CONVEX_HULL; COMPACT_CONVEX_HULL; FINITE_IMP_COMPACT; + FINITE_INSERT; FINITE_EMPTY]);; + +let BOUNDED_SEGMENT = prove + (`(!a b:real^N. bounded(segment[a,b])) /\ + (!a b:real^N. bounded(segment(a,b)))`, + REWRITE_TAC[AND_FORALL_THM] THEN REPEAT GEN_TAC THEN + MATCH_MP_TAC(MESON[BOUNDED_SUBSET] + `bounded s /\ t SUBSET s ==> bounded s /\ bounded t`) THEN + REWRITE_TAC[SEGMENT_OPEN_SUBSET_CLOSED] THEN + MESON_TAC[COMPACT_IMP_BOUNDED; COMPACT_SEGMENT]);; + +let COLLINEAR_SEGMENT = prove + (`(!a b:real^N. collinear(segment[a,b])) /\ + (!a b:real^N. collinear(segment(a,b)))`, + REWRITE_TAC[AND_FORALL_THM] THEN REPEAT GEN_TAC THEN + MATCH_MP_TAC(TAUT `p /\ (p ==> q) ==> p /\ q`) THEN CONJ_TAC THENL + [REWRITE_TAC[COLLINEAR_AFFINE_HULL] THEN + MAP_EVERY EXISTS_TAC [`a:real^N`; `b:real^N`] THEN + REWRITE_TAC[SEGMENT_CONVEX_HULL; CONVEX_HULL_SUBSET_AFFINE_HULL]; + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] COLLINEAR_SUBSET) THEN + REWRITE_TAC[SEGMENT_OPEN_SUBSET_CLOSED]]);; + +let UNION_SEGMENT = prove + (`!a b c:real^N. + b IN segment[a,c] + ==> segment[a,b] UNION segment[b,c] = segment[a,c]`, + REPEAT GEN_TAC THEN ASM_CASES_TAC `c:real^N = a` THENL + [ASM_SIMP_TAC[SEGMENT_REFL; IN_SING; UNION_IDEMPOT]; + ONCE_REWRITE_TAC[UNION_COMM] THEN REWRITE_TAC[SEGMENT_CONVEX_HULL] THEN + DISCH_THEN(SUBST1_TAC o MATCH_MP CONVEX_HULL_EXCHANGE_UNION) THEN + ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN + REWRITE_TAC[IMAGE_CLAUSES; UNIONS_2] THEN + BINOP_TAC THEN AP_TERM_TAC THEN ASM SET_TAC[]]);; + +let INTER_SEGMENT = prove + (`!a b c:real^N. + b IN segment[a,c] \/ ~collinear{a,b,c} + ==> segment[a,b] INTER segment[b,c] = {b}`, + REPEAT GEN_TAC THEN ASM_CASES_TAC `c:real^N = a` THENL + [ASM_SIMP_TAC[SEGMENT_REFL; IN_SING; INTER_IDEMPOT; INSERT_AC; COLLINEAR_2]; + ALL_TAC] THEN + DISCH_THEN(DISJ_CASES_THEN MP_TAC) THENL + [REWRITE_TAC[SEGMENT_CONVEX_HULL] THEN DISCH_TAC THEN + MP_TAC(ISPECL [`{a:real^N,c}`; `b:real^N`; `{a:real^N}`; `{c:real^N}`] + CONVEX_HULL_EXCHANGE_INTER) THEN + ASM_REWRITE_TAC[AFFINE_INDEPENDENT_2] THEN + ANTS_TAC THENL [ASM SET_TAC[]; REWRITE_TAC[INSERT_AC]] THEN + DISCH_THEN SUBST1_TAC THEN + ASM_SIMP_TAC[SET_RULE `~(a = c) ==> {a} INTER {c} = {}`] THEN + REWRITE_TAC[CONVEX_HULL_SING]; + ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN REWRITE_TAC[] THEN + DISCH_THEN(MP_TAC o MATCH_MP (SET_RULE + `~(s INTER t = {b}) + ==> b IN s /\ b IN t + ==> ?a. ~(a = b) /\ a IN s /\ b IN s /\ a IN t /\ b IN t`)) THEN + ANTS_TAC THENL [REWRITE_TAC[ENDS_IN_SEGMENT]; ALL_TAC] THEN + REWRITE_TAC[GSYM BETWEEN_IN_SEGMENT; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `d:real^N` THEN STRIP_TAC THEN + REPEAT(FIRST_X_ASSUM(ASSUME_TAC o MATCH_MP BETWEEN_IMP_COLLINEAR)) THEN + MATCH_MP_TAC COLLINEAR_3_TRANS THEN EXISTS_TAC `d:real^N` THEN + REPEAT(POP_ASSUM MP_TAC) THEN SIMP_TAC[INSERT_AC]]);; + +let SUBSET_CONTINUOUS_IMAGE_SEGMENT_1 = prove + (`!f:real^N->real^1 a b. + f continuous_on segment[a,b] + ==> segment[f a,f b] SUBSET IMAGE f (segment[a,b])`, + REPEAT STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONNECTED_CONTINUOUS_IMAGE)) THEN + REWRITE_TAC[CONNECTED_SEGMENT] THEN + REWRITE_TAC[GSYM IS_INTERVAL_CONNECTED_1; IS_INTERVAL_CONVEX_1] THEN + REWRITE_TAC[CONVEX_CONTAINS_SEGMENT] THEN + MESON_TAC[IN_IMAGE; ENDS_IN_SEGMENT]);; + +let CONTINUOUS_INJECTIVE_IMAGE_SEGMENT_1 = prove + (`!f:real^N->real^1 a b. + f continuous_on segment[a,b] /\ + (!x y. x IN segment[a,b] /\ y IN segment[a,b] /\ f x = f y ==> x = y) + ==> IMAGE f (segment[a,b]) = segment[f a,f b]`, + let lemma = prove + (`!a b c:real^1. + ~(a = b) /\ ~(a IN segment(c,b)) /\ ~(b IN segment(a,c)) + ==> c IN segment[a,b]`, + REWRITE_TAC[FORALL_LIFT; SEGMENT_1; LIFT_DROP] THEN + REPEAT GEN_TAC THEN REWRITE_TAC[SEGMENT_1; LIFT_EQ] THEN + REPEAT(COND_CASES_TAC THEN ASM_REWRITE_TAC[IN_INTERVAL_1; LIFT_DROP]) THEN + ASM_REAL_ARITH_TAC) in + REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + REWRITE_TAC[INJECTIVE_ON_LEFT_INVERSE; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `g:real^1->real^N` THEN DISCH_TAC THEN + MP_TAC(ISPECL [`f:real^N->real^1`; `g:real^1->real^N`; + `segment[a:real^N,b]`] + CONTINUOUS_ON_INVERSE) THEN + ASM_REWRITE_TAC[COMPACT_SEGMENT] THEN DISCH_TAC THEN + REWRITE_TAC[GSYM SUBSET_ANTISYM_EQ] THEN + MATCH_MP_TAC(TAUT `q /\ (q ==> p) ==> p /\ q`) THEN CONJ_TAC THENL + [ASM_SIMP_TAC[SUBSET_CONTINUOUS_IMAGE_SEGMENT_1]; DISCH_TAC] THEN + ASM_CASES_TAC `a:real^N = b` THEN + ASM_REWRITE_TAC[SEGMENT_REFL] THENL [SET_TAC[]; ALL_TAC] THEN + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE] THEN X_GEN_TAC `c:real^N` THEN + DISCH_TAC THEN MATCH_MP_TAC lemma THEN + MATCH_MP_TAC(TAUT `p /\ (p ==> q) ==> p /\ q`) THEN CONJ_TAC THENL + [ASM_MESON_TAC[ENDS_IN_SEGMENT]; DISCH_TAC] THEN + ONCE_REWRITE_TAC[segment] THEN + ASM_REWRITE_TAC[IN_DIFF; IN_INSERT; NOT_IN_EMPTY] THEN + REPEAT STRIP_TAC THENL + [MP_TAC(ISPECL [`f:real^N->real^1`; `c:real^N`; `b:real^N`] + SUBSET_CONTINUOUS_IMAGE_SEGMENT_1) THEN + SUBGOAL_THEN `segment[c:real^N,b] SUBSET segment[a,b]` ASSUME_TAC THENL + [ASM_REWRITE_TAC[SUBSET_SEGMENT; ENDS_IN_SEGMENT]; ALL_TAC] THEN + REWRITE_TAC[NOT_IMP] THEN CONJ_TAC THENL + [ASM_MESON_TAC[CONTINUOUS_ON_SUBSET]; REWRITE_TAC[SUBSET]] THEN + DISCH_THEN(MP_TAC o SPEC `(f:real^N->real^1) a`) THEN + ASM_REWRITE_TAC[IN_IMAGE; NOT_EXISTS_THM] THEN + X_GEN_TAC `d:real^N` THEN ASM_CASES_TAC `d:real^N = a` THENL + [ASM_MESON_TAC[BETWEEN_ANTISYM; BETWEEN_IN_SEGMENT]; + ASM_MESON_TAC[ENDS_IN_SEGMENT; SUBSET]]; + MP_TAC(ISPECL [`f:real^N->real^1`; `a:real^N`; `c:real^N`] + SUBSET_CONTINUOUS_IMAGE_SEGMENT_1) THEN + SUBGOAL_THEN `segment[a:real^N,c] SUBSET segment[a,b]` ASSUME_TAC THENL + [ASM_REWRITE_TAC[SUBSET_SEGMENT; ENDS_IN_SEGMENT]; ALL_TAC] THEN + REWRITE_TAC[NOT_IMP] THEN CONJ_TAC THENL + [ASM_MESON_TAC[CONTINUOUS_ON_SUBSET]; REWRITE_TAC[SUBSET]] THEN + DISCH_THEN(MP_TAC o SPEC `(f:real^N->real^1) b`) THEN + ASM_REWRITE_TAC[IN_IMAGE; NOT_EXISTS_THM] THEN + X_GEN_TAC `d:real^N` THEN ASM_CASES_TAC `d:real^N = b` THENL + [ASM_MESON_TAC[BETWEEN_ANTISYM; BETWEEN_IN_SEGMENT; BETWEEN_SYM]; + ASM_MESON_TAC[ENDS_IN_SEGMENT; SUBSET]]]);; + +let CONTINUOUS_INJECTIVE_IMAGE_OPEN_SEGMENT_1 = prove + (`!f:real^N->real^1 a b. + f continuous_on segment[a,b] /\ + (!x y. x IN segment[a,b] /\ y IN segment[a,b] /\ f x = f y ==> x = y) + ==> IMAGE f (segment(a,b)) = segment(f a,f b)`, + REPEAT GEN_TAC THEN DISCH_TAC THEN + ONCE_REWRITE_TAC[segment] THEN + FIRST_ASSUM(MP_TAC o MATCH_MP CONTINUOUS_INJECTIVE_IMAGE_SEGMENT_1) THEN + MP_TAC(ISPECL [`a:real^N`; `b:real^N`] ENDS_IN_SEGMENT) THEN + MP_TAC(ISPECL [`(f:real^N->real^1) a`; `(f:real^1->real^1) b`] + ENDS_IN_SEGMENT) THEN + ASM SET_TAC[]);; + +let CONTINUOUS_IVT_LOCAL_EXTREMUM = prove + (`!f:real^N->real^1 a b. + f continuous_on segment[a,b] /\ ~(a = b) /\ f(a) = f(b) + ==> ?z. z IN segment(a,b) /\ + ((!w. w IN segment[a,b] ==> drop(f w) <= drop(f z)) \/ + (!w. w IN segment[a,b] ==> drop(f z) <= drop(f w)))`, + REPEAT STRIP_TAC THEN + MAP_EVERY (MP_TAC o ISPECL + [`drop o (f:real^N->real^1)`; `segment[a:real^N,b]`]) + [CONTINUOUS_ATTAINS_SUP; CONTINUOUS_ATTAINS_INF] THEN + ASM_REWRITE_TAC[o_DEF; LIFT_DROP; ETA_AX] THEN + REWRITE_TAC[COMPACT_SEGMENT; SEGMENT_EQ_EMPTY] THEN + DISCH_THEN(X_CHOOSE_THEN `d:real^N` STRIP_ASSUME_TAC) THEN + ASM_CASES_TAC `(d:real^N) IN segment(a,b)` THENL + [ASM_MESON_TAC[]; ALL_TAC] THEN + DISCH_THEN(X_CHOOSE_THEN `c:real^N` STRIP_ASSUME_TAC) THEN + ASM_CASES_TAC `(c:real^N) IN segment(a,b)` THENL + [ASM_MESON_TAC[]; ALL_TAC] THEN + EXISTS_TAC `midpoint(a:real^N,b)` THEN + MATCH_MP_TAC(TAUT `p /\ (p ==> q) ==> p /\ q`) THEN CONJ_TAC THENL + [ASM_REWRITE_TAC[MIDPOINT_IN_SEGMENT]; DISCH_TAC] THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE RAND_CONV [CONJUNCT2 segment]) THEN + REPEAT(FIRST_X_ASSUM(MP_TAC o + GEN_REWRITE_RULE (RAND_CONV o RAND_CONV) [segment])) THEN + ASM_REWRITE_TAC[IN_DIFF; IN_INSERT; NOT_IN_EMPTY] THEN + REPEAT(DISCH_THEN(DISJ_CASES_THEN SUBST_ALL_TAC)) THEN + FIRST_X_ASSUM SUBST_ALL_TAC THEN ASM_MESON_TAC[REAL_LE_ANTISYM; DROP_EQ]);; + +let FRONTIER_UNIONS_SUBSET_CLOSURE = prove + (`!f:(real^N->bool)->bool. + frontier(UNIONS f) SUBSET closure(UNIONS {frontier t | t IN f})`, + GEN_TAC THEN GEN_REWRITE_TAC LAND_CONV [frontier] THEN + REWRITE_TAC[SUBSET; IN_DIFF; CLOSURE_APPROACHABLE] THEN + X_GEN_TAC `x:real^N` THEN STRIP_TAC THEN + X_GEN_TAC `e:real` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `e:real`) THEN + ASM_REWRITE_TAC[EXISTS_IN_UNIONS; EXISTS_IN_GSPEC; RIGHT_EXISTS_AND_THM] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `t:real^N->bool` THEN + ASM_CASES_TAC `(t:real^N->bool) IN f` THEN ASM_REWRITE_TAC[] THEN + ASM_CASES_TAC `(x:real^N) IN t` THENL + [DISCH_THEN(K ALL_TAC) THEN EXISTS_TAC `x:real^N` THEN + ASM_REWRITE_TAC[frontier; DIST_REFL; IN_DIFF] THEN + ASM_SIMP_TAC[REWRITE_RULE[SUBSET] CLOSURE_SUBSET] THEN + FIRST_X_ASSUM(MP_TAC o check (is_neg o concl)) THEN + SPEC_TAC(`x:real^N`,`z:real^N`) THEN + REWRITE_TAC[CONTRAPOS_THM; GSYM SUBSET] THEN + MATCH_MP_TAC SUBSET_INTERIOR THEN ASM SET_TAC[]; + DISCH_THEN(X_CHOOSE_THEN `y:real^N` STRIP_ASSUME_TAC) THEN + MP_TAC(ISPECL [`segment[x:real^N,y]`; `t:real^N->bool`] + CONNECTED_INTER_FRONTIER) THEN + SIMP_TAC[CONNECTED_SEGMENT; GSYM MEMBER_NOT_EMPTY; IN_INTER; IN_DIFF] THEN + ANTS_TAC THENL [ASM_MESON_TAC[ENDS_IN_SEGMENT]; ALL_TAC] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `z:real^N` THEN + ASM_MESON_TAC[DIST_IN_CLOSED_SEGMENT; DIST_SYM; REAL_LET_TRANS]]);; + +let CLOSURE_CONVEX_INTER_AFFINE = prove + (`!s t:real^N->bool. + convex s /\ affine t /\ ~(relative_interior s INTER t = {}) + ==> closure(s INTER t) = closure(s) INTER t`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN + REWRITE_TAC[SUBSET_INTER] THEN REPEAT CONJ_TAC THENL + [MATCH_MP_TAC SUBSET_CLOSURE THEN SET_TAC[]; + TRANS_TAC SUBSET_TRANS `closure t:real^N->bool` THEN + SIMP_TAC[SUBSET_CLOSURE; INTER_SUBSET] THEN + ASM_SIMP_TAC[CLOSURE_CLOSED; CLOSED_AFFINE; SUBSET_REFL]; + ALL_TAC] THEN + FIRST_X_ASSUM(X_CHOOSE_THEN `a:real^N` MP_TAC o + GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN + POP_ASSUM_LIST(MP_TAC o end_itlist CONJ) THEN + GEOM_ORIGIN_TAC `a:real^N` THEN REPEAT GEN_TAC THEN + REWRITE_TAC[IN_INTER] THEN + DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN + ASM_SIMP_TAC[AFFINE_EQ_SUBSPACE] THEN STRIP_TAC THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP(REWRITE_RULE[SUBSET] + RELATIVE_INTERIOR_SUBSET)) THEN + REWRITE_TAC[SUBSET; IN_INTER] THEN X_GEN_TAC `x:real^N` THEN + STRIP_TAC THEN ASM_CASES_TAC `x:real^N = vec 0` THENL + [MATCH_MP_TAC(REWRITE_RULE[SUBSET] CLOSURE_SUBSET) THEN + ASM_REWRITE_TAC[IN_INTER]; + ALL_TAC] THEN + SUBGOAL_THEN `x IN closure(segment(vec 0:real^N,x))` MP_TAC THENL + [ASM_REWRITE_TAC[CLOSURE_SEGMENT; ENDS_IN_SEGMENT]; ALL_TAC] THEN + MATCH_MP_TAC(SET_RULE `s SUBSET t ==> x IN s ==> x IN t`) THEN + MATCH_MP_TAC SUBSET_CLOSURE THEN REWRITE_TAC[SUBSET_INTER] THEN + CONJ_TAC THENL + [TRANS_TAC SUBSET_TRANS `relative_interior s:real^N->bool` THEN + REWRITE_TAC[RELATIVE_INTERIOR_SUBSET] THEN + MATCH_MP_TAC IN_RELATIVE_INTERIOR_CLOSURE_CONVEX_SEGMENT THEN + ASM_REWRITE_TAC[]; + ASM_SIMP_TAC[SUBSET; IN_SEGMENT; VECTOR_MUL_RZERO; VECTOR_ADD_LID; + SUBSPACE_MUL; LEFT_IMP_EXISTS_THM]]);; + +let RELATIVE_FRONTIER_CONVEX_INTER_AFFINE = prove + (`!s t:real^N->bool. + convex s /\ affine t /\ ~(interior s INTER t = {}) + ==> relative_frontier(s INTER t) = frontier s INTER t`, + SIMP_TAC[relative_frontier; RELATIVE_INTERIOR_CONVEX_INTER_AFFINE; + frontier] THEN + REPEAT STRIP_TAC THEN + SUBGOAL_THEN `~(relative_interior s INTER t:real^N->bool = {})` + ASSUME_TAC THENL + [MP_TAC(ISPEC `s:real^N->bool` INTERIOR_SUBSET_RELATIVE_INTERIOR) THEN + ASM SET_TAC[]; + ASM_SIMP_TAC[CLOSURE_CONVEX_INTER_AFFINE] THEN SET_TAC[]]);; + +let CONNECTED_COMPONENT_1_GEN = prove + (`!s a b:real^N. + dimindex(:N) = 1 + ==> (connected_component s a b <=> segment[a,b] SUBSET s)`, + SIMP_TAC[connected_component; GSYM CONNECTED_CONVEX_1_GEN] THEN + MESON_TAC[CONVEX_CONTAINS_SEGMENT; SUBSET; CONVEX_SEGMENT; + ENDS_IN_SEGMENT]);; + +let CONNECTED_COMPONENT_1 = prove + (`!s a b:real^1. connected_component s a b <=> segment[a,b] SUBSET s`, + SIMP_TAC[CONNECTED_COMPONENT_1_GEN; DIMINDEX_1]);; + +(* ------------------------------------------------------------------------- *) +(* An injective function into R is a homeomorphism and so an open map. *) +(* ------------------------------------------------------------------------- *) + +let INJECTIVE_INTO_1D_EQ_HOMEOMORPHISM = prove + (`!f:real^N->real^1 s. + f continuous_on s /\ path_connected s + ==> ((!x y. x IN s /\ y IN s /\ f x = f y ==> x = y) <=> + ?g. homeomorphism (s,IMAGE f s) (f,g))`, + REPEAT STRIP_TAC THEN EQ_TAC THENL + [REWRITE_TAC[INJECTIVE_ON_LEFT_INVERSE]; + REWRITE_TAC[homeomorphism] THEN MESON_TAC[]] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `g:real^1->real^N` THEN + STRIP_TAC THEN ASM_SIMP_TAC[homeomorphism; FORALL_IN_IMAGE] THEN + CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + SUBGOAL_THEN `is_interval (IMAGE (f:real^N->real^1) s)` ASSUME_TAC THENL + [REWRITE_TAC[IS_INTERVAL_PATH_CONNECTED_1] THEN + ASM_MESON_TAC[PATH_CONNECTED_CONTINUOUS_IMAGE]; + ALL_TAC] THEN + REWRITE_TAC[continuous_on; IMP_CONJ; FORALL_IN_IMAGE] THEN + X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN + ABBREV_TAC `y = (f:real^N->real^1) x` THEN + ABBREV_TAC `t = IMAGE (f:real^N->real^1) s` THEN + X_GEN_TAC `e:real` THEN DISCH_TAC THEN + SUBGOAL_THEN + `?a b d. a IN s /\ b IN s /\ &0 < d /\ + ball(y,d) INTER t SUBSET segment[(f:real^N->real^1) a,f b]` + STRIP_ASSUME_TAC THENL + [MP_TAC(ISPECL [`t:real^1->bool`; `y:real^1`] + INTERVAL_CONTAINS_COMPACT_NEIGHBOURHOOD) THEN + ANTS_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + ASM_SIMP_TAC[INTERVAL_SUBSET_IS_INTERVAL] THEN + REWRITE_TAC[SET_RULE + `P /\ y IN s /\ (s = {} \/ a IN t /\ b IN t) /\ R <=> + a IN t /\ b IN t /\ P /\ y IN s /\ R`] THEN + REWRITE_TAC[RIGHT_EXISTS_AND_THM] THEN + EXPAND_TAC "t" THEN REWRITE_TAC[EXISTS_IN_IMAGE] THEN + REWRITE_TAC[SEGMENT_1; IN_INTERVAL_1] THEN + MESON_TAC[REAL_LE_TRANS]; + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [path_connected]) THEN + DISCH_THEN(MP_TAC o SPECL [`a:real^N`; `b:real^N`]) THEN + ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `p:real^1->real^N` STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN + `(g:real^1->real^N) continuous_on segment[(f:real^N->real^1) a,f b]` + MP_TAC THENL + [MATCH_MP_TAC CONTINUOUS_ON_SUBSET THEN + EXISTS_TAC `IMAGE (f:real^N->real^1) (path_image p)` THEN CONJ_TAC THENL + [MATCH_MP_TAC CONTINUOUS_ON_INVERSE THEN + ASM_SIMP_TAC[COMPACT_PATH_IMAGE] THEN CONJ_TAC THENL + [ASM_MESON_TAC[CONTINUOUS_ON_SUBSET]; ASM SET_TAC[]]; + SUBGOAL_THEN `convex(IMAGE (f:real^N->real^1) (path_image p))` + MP_TAC THENL + [REWRITE_TAC[GSYM IS_INTERVAL_CONVEX_1; IS_INTERVAL_CONNECTED_1] THEN + MATCH_MP_TAC CONNECTED_CONTINUOUS_IMAGE THEN + ASM_SIMP_TAC[CONNECTED_PATH_IMAGE] THEN + ASM_MESON_TAC[CONTINUOUS_ON_SUBSET]; + REWRITE_TAC[CONVEX_CONTAINS_SEGMENT] THEN DISCH_THEN MATCH_MP_TAC THEN + CONJ_TAC THEN MATCH_MP_TAC FUN_IN_IMAGE THEN + ASM_MESON_TAC[PATHSTART_IN_PATH_IMAGE; PATHFINISH_IN_PATH_IMAGE]]]; + REWRITE_TAC[continuous_on] THEN + DISCH_THEN(MP_TAC o SPEC `y:real^1`) THEN ANTS_TAC THENL + [FIRST_X_ASSUM(MATCH_MP_TAC o GEN_REWRITE_RULE I [SUBSET]) THEN + ASM_REWRITE_TAC[IN_INTER; CENTRE_IN_BALL] THEN ASM SET_TAC[]; + ALL_TAC] THEN + DISCH_THEN(MP_TAC o SPEC `e:real`) THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `k:real` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `min d k` THEN ASM_REWRITE_TAC[REAL_LT_MIN] THEN + X_GEN_TAC `x':real^N` THEN REPEAT STRIP_TAC THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o GEN_REWRITE_RULE I [SUBSET]) THEN + ASM_REWRITE_TAC[IN_INTER; IN_BALL] THEN + ONCE_REWRITE_TAC[DIST_SYM] THEN ASM SET_TAC[]]]);; + +let INJECTIVE_INTO_1D_IMP_OPEN_MAP = prove + (`!f:real^N->real^1 s t. + f continuous_on s /\ path_connected s /\ + (!x y. x IN s /\ y IN s /\ f x = f y ==> x = y) /\ + open_in (subtopology euclidean s) t + ==> open_in (subtopology euclidean (IMAGE f s)) (IMAGE f t)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC HOMEOMORPHISM_IMP_OPEN_MAP THEN + ASM_MESON_TAC[INJECTIVE_INTO_1D_EQ_HOMEOMORPHISM]);; + +(* ------------------------------------------------------------------------- *) +(* Injective function on an interval is strictly increasing or decreasing. *) +(* ------------------------------------------------------------------------- *) + +let CONTINUOUS_INJECTIVE_IFF_MONOTONIC = prove + (`!f:real^1->real^1 s. + f continuous_on s /\ is_interval s + ==> ((!x y. x IN s /\ y IN s /\ f x = f y ==> x = y) <=> + (!x y. x IN s /\ y IN s /\ drop x < drop y + ==> drop(f x) < drop(f y)) \/ + (!x y. x IN s /\ y IN s /\ drop x < drop y + ==> drop(f y) < drop(f x)))`, + let lemma = prove + (`!s f:real^1->real^1. + f continuous_on s /\ is_interval s /\ + (!x y. x IN s /\ y IN s /\ f x = f y ==> x = y) + ==> !u v w. u IN s /\ v IN s /\ w IN s /\ + drop u < drop v /\ drop v < drop w /\ + drop(f u) <= drop(f v) /\ drop(f w) <= drop(f v) ==> F`, + REWRITE_TAC[IS_INTERVAL_CONVEX_1; CONVEX_CONTAINS_SEGMENT] THEN + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`f:real^1->real^1`; `u:real^1`; `w:real^1`] + CONTINUOUS_INJECTIVE_IMAGE_SEGMENT_1) THEN + ANTS_TAC THENL [ASM_MESON_TAC[CONTINUOUS_ON_SUBSET; SUBSET]; ALL_TAC] THEN + REWRITE_TAC[EXTENSION] THEN + DISCH_THEN(MP_TAC o SPEC `(f:real^1->real^1) v`) THEN + MATCH_MP_TAC(TAUT `p /\ ~q ==> (p <=> q) ==> F`) THEN CONJ_TAC THENL + [MATCH_MP_TAC FUN_IN_IMAGE THEN ASM_REWRITE_TAC[SEGMENT_1] THEN + COND_CASES_TAC THENL + [ASM_SIMP_TAC[IN_INTERVAL_1; REAL_LT_IMP_LE]; ASM_REAL_ARITH_TAC]; + REWRITE_TAC[SEGMENT_1] THEN COND_CASES_TAC THEN + ASM_REWRITE_TAC[IN_INTERVAL_1] THEN DISCH_TAC THENL + [SUBGOAL_THEN `drop(f(w:real^1)) = drop(f v)` ASSUME_TAC THENL + [ASM_REAL_ARITH_TAC; ASM_MESON_TAC[DROP_EQ; REAL_LT_REFL]]; + SUBGOAL_THEN `drop(f(u:real^1)) = drop(f v)` ASSUME_TAC THENL + [ASM_REAL_ARITH_TAC; ASM_MESON_TAC[DROP_EQ; REAL_LT_REFL]]]]) + and tac s1 s2 = + let [l1;l2] = map (map (fun x -> mk_var(x,`:real^1`)) o explode) [s1;s2] in + REPEAT(FIRST_X_ASSUM(fun th -> + MP_TAC(ISPECL l1 th) THEN MP_TAC(ISPECL l2 th))) THEN + ASM_REWRITE_TAC[] THEN ASM_REAL_ARITH_TAC in + REPEAT STRIP_TAC THEN EQ_TAC THENL + [ALL_TAC; + REWRITE_TAC[GSYM DROP_EQ] THEN + MESON_TAC[REAL_LT_TOTAL; REAL_LT_REFL]] THEN + DISCH_TAC THEN MATCH_MP_TAC(MESON[] + `(!a b c d. ~(~P a b /\ ~Q c d)) ==> (!x y. P x y) \/ (!x y. Q x y)`) THEN + MAP_EVERY X_GEN_TAC [`a:real^1`; `b:real^1`; `c:real^1`; `d:real^1`] THEN + REWRITE_TAC[NOT_IMP; REAL_NOT_LT] THEN STRIP_TAC THEN + REPEAT + (FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [REAL_LE_LT]) THEN + REWRITE_TAC[DROP_EQ] THEN STRIP_TAC THENL + [ALL_TAC; ASM_MESON_TAC[REAL_LT_REFL]]) THEN + MP_TAC(ISPEC `s:real^1->bool` lemma) THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(fun th -> + MP_TAC(SPEC `(--) o (f:real^1->real^1)` th) THEN + MP_TAC(SPEC `f:real^1->real^1` th)) THEN + ASM_REWRITE_TAC[o_THM; VECTOR_ARITH `--x:real^N = --y <=> x = y`] THEN + DISCH_TAC THEN REWRITE_TAC[NOT_IMP; DROP_NEG; REAL_LE_NEG2] THEN + CONJ_TAC THENL + [ASM_MESON_TAC[CONTINUOUS_ON_COMPOSE;LINEAR_CONTINUOUS_ON; LINEAR_NEGATION]; + DISCH_TAC] THEN + ASM_CASES_TAC `drop d <= drop a` THENL [tac "cab" "cdb"; ALL_TAC] THEN + ASM_CASES_TAC `drop b <= drop c` THENL [tac "abd" "acd"; ALL_TAC] THEN + ASM_CASES_TAC `c:real^1 = a /\ d:real^1 = b` THENL + [ASM_MESON_TAC[REAL_LT_ANTISYM]; ALL_TAC] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (MESON[] + `~(c = a /\ d = b) + ==> (c = a ==> d = b) /\ (d = b ==> c = a) /\ + (~(c = a) /\ ~(d = b) ==> F) ==> F`)) THEN + REPEAT CONJ_TAC THENL + [DISCH_THEN SUBST_ALL_TAC THEN SIMP_TAC[GSYM DROP_EQ] THEN tac "adb" "abd"; + DISCH_THEN SUBST_ALL_TAC THEN SIMP_TAC[GSYM DROP_EQ] THEN tac "acb" "cab"; + REWRITE_TAC[GSYM DROP_EQ] THEN STRIP_TAC] THEN + ASM_CASES_TAC `drop a <= drop c` THENL [tac "acb" "acd"; tac "cab" "cad"]);; + +(* ------------------------------------------------------------------------- *) +(* Some uncountability results for relevant sets. *) +(* ------------------------------------------------------------------------- *) + +let CARD_EQ_SEGMENT = prove + (`(!a b:real^N. ~(a = b) ==> segment[a,b] =_c (:real)) /\ + (!a b:real^N. ~(a = b) ==> segment(a,b) =_c (:real))`, + REPEAT STRIP_TAC THEN ASM_SIMP_TAC[SEGMENT_IMAGE_INTERVAL] THENL + [TRANS_TAC CARD_EQ_TRANS `interval[vec 0:real^1,vec 1]`; + TRANS_TAC CARD_EQ_TRANS `interval(vec 0:real^1,vec 1)`] THEN + SIMP_TAC[CARD_EQ_INTERVAL; UNIT_INTERVAL_NONEMPTY] THEN + MATCH_MP_TAC CARD_EQ_IMAGE THEN + ASM_REWRITE_TAC[VECTOR_MUL_EQ_0; VECTOR_SUB_EQ; VECTOR_ARITH + `(&1 - x) % a + x % b:real^N = (&1 - y) % a + y % b <=> + (x - y) % (a - b) = vec 0`] THEN + SIMP_TAC[REAL_SUB_0; DROP_EQ]);; + +let UNCOUNTABLE_SEGMENT = prove + (`(!a b:real^N. ~(a = b) ==> ~COUNTABLE(segment[a,b])) /\ + (!a b:real^N. ~(a = b) ==> ~COUNTABLE(segment(a,b)))`, + SIMP_TAC[CARD_EQ_REAL_IMP_UNCOUNTABLE; CARD_EQ_SEGMENT]);; + +let CARD_EQ_PATH_CONNECTED = prove + (`!s a b:real^N. + path_connected s /\ a IN s /\ b IN s /\ ~(a = b) ==> s =_c (:real)`, + MESON_TAC[CARD_EQ_CONNECTED; PATH_CONNECTED_IMP_CONNECTED]);; + +let UNCOUNTABLE_PATH_CONNECTED = prove + (`!s a b:real^N. + path_connected s /\ a IN s /\ b IN s /\ ~(a = b) ==> ~COUNTABLE s`, + REPEAT GEN_TAC THEN STRIP_TAC THEN + MATCH_MP_TAC CARD_EQ_REAL_IMP_UNCOUNTABLE THEN + MATCH_MP_TAC CARD_EQ_PATH_CONNECTED THEN + ASM_MESON_TAC[]);; + +let CARD_EQ_CONVEX = prove + (`!s a b:real^N. + convex s /\ a IN s /\ b IN s /\ ~(a = b) ==> s =_c (:real)`, + MESON_TAC[CARD_EQ_PATH_CONNECTED; CONVEX_IMP_PATH_CONNECTED]);; + +let UNCOUNTABLE_CONVEX = prove + (`!s a b:real^N. + convex s /\ a IN s /\ b IN s /\ ~(a = b) ==> ~COUNTABLE s`, + REPEAT GEN_TAC THEN STRIP_TAC THEN + MATCH_MP_TAC CARD_EQ_REAL_IMP_UNCOUNTABLE THEN + MATCH_MP_TAC CARD_EQ_CONVEX THEN + ASM_MESON_TAC[]);; + +let CARD_EQ_NONEMPTY_INTERIOR = prove + (`!s:real^N->bool. ~(interior s = {}) ==> s =_c (:real)`, + REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM CARD_LE_ANTISYM] THEN CONJ_TAC THENL + [TRANS_TAC CARD_LE_TRANS `(:real^N)` THEN + SIMP_TAC[CARD_LE_UNIV; CARD_EQ_IMP_LE; CARD_EQ_EUCLIDEAN]; + TRANS_TAC CARD_LE_TRANS `interior(s:real^N->bool)` THEN + SIMP_TAC[CARD_LE_SUBSET; INTERIOR_SUBSET] THEN + MATCH_MP_TAC(ONCE_REWRITE_RULE[CARD_EQ_SYM] CARD_EQ_IMP_LE) THEN + MATCH_MP_TAC CARD_EQ_OPEN THEN ASM_REWRITE_TAC[OPEN_INTERIOR]]);; + +let UNCOUNTABLE_NONEMPTY_INTERIOR = prove + (`!s:real^N->bool. ~(interior s = {}) ==> ~(COUNTABLE s)`, + SIMP_TAC[CARD_EQ_NONEMPTY_INTERIOR; CARD_EQ_REAL_IMP_UNCOUNTABLE]);; + +let COUNTABLE_EMPTY_INTERIOR = prove + (`!s:real^N->bool. COUNTABLE s ==> interior s = {}`, + MESON_TAC[UNCOUNTABLE_NONEMPTY_INTERIOR]);; + +let FINITE_EMPTY_INTERIOR = prove + (`!s:real^N->bool. FINITE s ==> interior s = {}`, + SIMP_TAC[COUNTABLE_EMPTY_INTERIOR; FINITE_IMP_COUNTABLE]);; + +let [CONNECTED_FINITE_IFF_SING; + CONNECTED_FINITE_IFF_COUNTABLE; + CONNECTED_INFINITE_IFF_CARD_EQ] = (CONJUNCTS o prove) + (`(!s:real^N->bool. connected s ==> (FINITE s <=> s = {} \/ ?a. s = {a})) /\ + (!s:real^N->bool. connected s ==> (FINITE s <=> COUNTABLE s)) /\ + (!s:real^N->bool. connected s ==> (INFINITE s <=> s =_c (:real)))`, + REWRITE_TAC[AND_FORALL_THM] THEN GEN_TAC THEN + ASM_CASES_TAC `connected(s:real^N->bool)` THEN + ASM_REWRITE_TAC[INFINITE] THEN MATCH_MP_TAC(TAUT + `(f ==> c) /\ (r ==> ~c) /\ (s ==> f) /\ (~s ==> r) + ==> (f <=> s) /\ (f <=> c) /\ (~f <=> r)`) THEN + REWRITE_TAC[FINITE_IMP_COUNTABLE] THEN + REPEAT CONJ_TAC THEN STRIP_TAC THEN + ASM_SIMP_TAC[CARD_EQ_REAL_IMP_UNCOUNTABLE; FINITE_INSERT; FINITE_EMPTY] THEN + MATCH_MP_TAC CARD_EQ_CONNECTED THEN ASM SET_TAC[]);; + +let CLOSED_AS_FRONTIER_OF_SUBSET = prove + (`!s:real^N->bool. closed s <=> ?t. t SUBSET s /\ s = frontier t`, + GEN_TAC THEN EQ_TAC THENL [ALL_TAC; MESON_TAC[FRONTIER_CLOSED]] THEN + DISCH_TAC THEN MP_TAC(ISPEC `s:real^N->bool` SEPARABLE) THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `t:real^N->bool` THEN + SIMP_TAC[frontier] THEN STRIP_TAC THEN MATCH_MP_TAC(SET_RULE + `s SUBSET c /\ c SUBSET s /\ i = {} ==> s = c DIFF i`) THEN + ASM_REWRITE_TAC[] THEN CONJ_TAC THENL + [ASM_MESON_TAC[SUBSET_CLOSURE; CLOSURE_CLOSED]; + ASM_MESON_TAC[UNCOUNTABLE_NONEMPTY_INTERIOR]]);; + +let CLOSED_AS_FRONTIER = prove + (`!s:real^N->bool. closed s <=> ?t. s = frontier t`, + GEN_TAC THEN EQ_TAC THENL + [MESON_TAC[CLOSED_AS_FRONTIER_OF_SUBSET]; MESON_TAC[FRONTIER_CLOSED]]);; + +let CARD_EQ_CLOSED = prove + (`!s:real^N->bool. closed s ==> s <=_c (:num) \/ s =_c (:real)`, + let slemma = prove + (`!s:real^N->bool. + ~COUNTABLE s + ==> ?x y. ~(x = y) /\ x IN s /\ y IN s /\ + x condensation_point_of s /\ + y condensation_point_of s`, + REPEAT STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o MATCH_MP CARD_EQ_CONDENSATION_POINTS_IN_SET) THEN + DISCH_THEN(MP_TAC o MATCH_MP CARD_INFINITE_CONG) THEN + REWRITE_TAC[INFINITE] THEN + MATCH_MP_TAC(TAUT `q /\ (p ==> s) ==> (p <=> q) ==> s`) THEN + CONJ_TAC THENL [ASM_MESON_TAC[FINITE_IMP_COUNTABLE]; ALL_TAC] THEN + DISCH_TAC THEN + MP_TAC(ISPECL [`2`; `{x:real^N | x IN s /\ x condensation_point_of s}`] + CHOOSE_SUBSET_STRONG) THEN + ASM_REWRITE_TAC[HAS_SIZE_CONV `s HAS_SIZE 2`; RIGHT_AND_EXISTS_THM] THEN + DISCH_THEN(CHOOSE_THEN MP_TAC) THEN REWRITE_TAC[SUBSET; IN_ELIM_THM] THEN + REPEAT(MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC) THEN + STRIP_TAC THEN FIRST_X_ASSUM SUBST_ALL_TAC THEN + RULE_ASSUM_TAC(REWRITE_RULE[FORALL_IN_INSERT; NOT_IN_EMPTY]) THEN + ASM_REWRITE_TAC[]) in + GEN_TAC THEN DISCH_TAC THEN REWRITE_TAC[GSYM COUNTABLE_ALT] THEN + ASM_CASES_TAC `COUNTABLE(s:real^N->bool)` THEN ASM_REWRITE_TAC[] THEN + SUBGOAL_THEN + `!n t:real^N->bool. + closed t /\ ~COUNTABLE t + ==> ?l r. (compact l /\ ~COUNTABLE l) /\ (compact r /\ ~COUNTABLE r) /\ + l INTER r = {} /\ l SUBSET t /\ r SUBSET t /\ + diameter l <= inv(&2 pow n) /\ + diameter r <= inv(&2 pow n)` + MP_TAC THENL + [REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC + (MP_TAC o MATCH_MP slemma)) THEN + REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`a:real^N`; `b:real^N`] THEN STRIP_TAC THEN + MAP_EVERY EXISTS_TAC + [`t INTER cball(a:real^N,min (inv(&2 pow (SUC n))) (dist(a,b) / &3))`; + `t INTER cball(b:real^N,min (inv(&2 pow (SUC n))) (dist(a,b) / &3))`] THEN + ASM_SIMP_TAC[CLOSED_INTER_COMPACT; COMPACT_CBALL] THEN + REPEAT CONJ_TAC THENL + [FIRST_X_ASSUM(MATCH_MP_TAC o GEN_REWRITE_RULE I + [CONDENSATION_POINT_INFINITE_CBALL]) THEN + REWRITE_TAC[REAL_LT_MIN; REAL_LT_INV_EQ; REAL_LT_POW2] THEN + UNDISCH_TAC `~(a:real^N = b)` THEN CONV_TAC NORM_ARITH; + FIRST_X_ASSUM(MATCH_MP_TAC o GEN_REWRITE_RULE I + [CONDENSATION_POINT_INFINITE_CBALL]) THEN + REWRITE_TAC[REAL_LT_MIN; REAL_LT_INV_EQ; REAL_LT_POW2] THEN + UNDISCH_TAC `~(a:real^N = b)` THEN CONV_TAC NORM_ARITH; + MATCH_MP_TAC(SET_RULE + `(!x. ~(x IN t /\ x IN u)) ==> (s INTER t) INTER (s INTER u) = {}`) THEN + REWRITE_TAC[IN_CBALL; REAL_LE_MIN] THEN + UNDISCH_TAC `~(a:real^N = b)` THEN CONV_TAC NORM_ARITH; + SET_TAC[]; + SET_TAC[]; + MATCH_MP_TAC DIAMETER_LE THEN + SIMP_TAC[REAL_LE_INV_EQ; REAL_LT_IMP_LE; REAL_LT_POW2] THEN + REWRITE_TAC[IN_INTER; IN_CBALL; REAL_LE_MIN; real_pow; REAL_INV_MUL] THEN + CONV_TAC NORM_ARITH; + MATCH_MP_TAC DIAMETER_LE THEN + SIMP_TAC[REAL_LE_INV_EQ; REAL_LT_IMP_LE; REAL_LT_POW2] THEN + REWRITE_TAC[IN_INTER; IN_CBALL; REAL_LE_MIN; real_pow; REAL_INV_MUL] THEN + CONV_TAC NORM_ARITH]; + REWRITE_TAC[RIGHT_IMP_EXISTS_THM; SKOLEM_THM; LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC + [`l:num->(real^N->bool)->(real^N->bool)`; + `r:num->(real^N->bool)->(real^N->bool)`] THEN + DISCH_TAC THEN + SUBGOAL_THEN + `!b. ?x:num->real^N->bool. + (x 0 = s) /\ (!n. x(SUC n) = if b(n) then r n (x n) else l n (x n))` + MP_TAC THENL + [GEN_TAC THEN + W(ACCEPT_TAC o prove_recursive_functions_exist num_RECURSION o + snd o dest_exists o snd); + REWRITE_TAC[SKOLEM_THM; LEFT_IMP_EXISTS_THM; FORALL_AND_THM]] THEN + X_GEN_TAC `x:(num->bool)->num->real^N->bool` THEN STRIP_TAC THEN + REWRITE_TAC[GSYM CARD_LE_ANTISYM] THEN CONJ_TAC THENL + [TRANS_TAC CARD_LE_TRANS `(:real^N)` THEN + SIMP_TAC[CARD_LE_UNIV; CARD_EQ_EUCLIDEAN; CARD_EQ_IMP_LE]; + TRANS_TAC CARD_LE_TRANS `(:num->bool)` THEN + SIMP_TAC[CARD_EQ_REAL; CARD_EQ_IMP_LE]] THEN + REWRITE_TAC[le_c; IN_UNIV] THEN + SUBGOAL_THEN + `!b n. closed((x:(num->bool)->num->real^N->bool) b n) /\ + ~COUNTABLE(x b n)` + MP_TAC THENL + [GEN_TAC THEN INDUCT_TAC THEN ASM_SIMP_TAC[] THEN + COND_CASES_TAC THEN ASM_SIMP_TAC[COMPACT_IMP_CLOSED]; + REWRITE_TAC[FORALL_AND_THM] THEN STRIP_TAC] THEN + MP_TAC(GEN `b:num->bool` (ISPEC `(x:(num->bool)->num->real^N->bool) b` + DECREASING_CLOSED_NEST_SING)) THEN + DISCH_THEN(MP_TAC o MATCH_MP MONO_FORALL) THEN ANTS_TAC THENL + [ASM_SIMP_TAC[FORALL_AND_THM] THEN REPEAT CONJ_TAC THENL + [ASM_MESON_TAC[COUNTABLE_EMPTY]; + GEN_TAC THEN MATCH_MP_TAC TRANSITIVE_STEPWISE_LE THEN + REWRITE_TAC[SUBSET_REFL] THEN ASM SET_TAC[]; + MAP_EVERY X_GEN_TAC [`b:num->bool`; `e:real`] THEN DISCH_TAC THEN + MP_TAC(ISPECL [`inv(&2)`; `e:real`] REAL_ARCH_POW_INV) THEN + ASM_REWRITE_TAC[REAL_POW_INV] THEN CONV_TAC REAL_RAT_REDUCE_CONV THEN + DISCH_THEN(X_CHOOSE_TAC `m:num`) THEN + EXISTS_TAC `SUC m` THEN ASM_SIMP_TAC[] THEN + REPEAT GEN_TAC THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(MP_TAC o MATCH_MP + (REWRITE_RULE[TAUT `p /\ q /\ r ==> s <=> q /\ r ==> p ==> s`] + DIAMETER_BOUNDED_BOUND)) THEN + ASM_SIMP_TAC[COMPACT_IMP_BOUNDED] THEN + UNDISCH_TAC `inv(&2 pow m) < e` THEN MATCH_MP_TAC(NORM_ARITH + `d <= i ==> i < e ==> norm(x - y) <= d ==> dist(x:real^N,y) < e`) THEN + ASM_SIMP_TAC[]]; + ALL_TAC] THEN + REWRITE_TAC[SKOLEM_THM] THEN MATCH_MP_TAC MONO_EXISTS THEN + X_GEN_TAC `f:(num->bool)->real^N` THEN STRIP_TAC THEN CONJ_TAC THENL + [X_GEN_TAC `b:num->bool` THEN + REWRITE_TAC[SET_RULE `x IN s <=> {x} SUBSET s`] THEN + FIRST_ASSUM(fun th -> GEN_REWRITE_TAC LAND_CONV [GSYM th]) THEN + REWRITE_TAC[SUBSET; INTERS_GSPEC; IN_ELIM_THM; LEFT_IMP_EXISTS_THM] THEN + ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN + SIMP_TAC[FORALL_UNWIND_THM2] THEN GEN_TAC THEN ASM SET_TAC[]; + MAP_EVERY X_GEN_TAC [`b:num->bool`; `c:num->bool`] THEN + ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN + GEN_REWRITE_TAC (LAND_CONV o RAND_CONV) [FUN_EQ_THM] THEN + REWRITE_TAC[NOT_FORALL_THM] THEN ONCE_REWRITE_TAC[num_WOP] THEN + SIMP_TAC[] THEN DISCH_THEN(X_CHOOSE_THEN `k:num` STRIP_ASSUME_TAC) THEN + MATCH_MP_TAC(SET_RULE + `!f g. INTERS f = {a} /\ INTERS g = {b} /\ + (?s t. s IN f /\ t IN g /\ s INTER t = {}) + ==> ~(a = b)`) THEN + EXISTS_TAC `{t | ?n. t = (x:(num->bool)->num->real^N->bool) b n}` THEN + EXISTS_TAC `{t | ?n. t = (x:(num->bool)->num->real^N->bool) c n}` THEN + ASM_REWRITE_TAC[IN_ELIM_THM] THEN + EXISTS_TAC `(x:(num->bool)->num->real^N->bool) b (SUC k)` THEN + EXISTS_TAC `(x:(num->bool)->num->real^N->bool) c (SUC k)` THEN + REPEAT(CONJ_TAC THENL [MESON_TAC[]; ALL_TAC]) THEN ASM_SIMP_TAC[] THEN + SUBGOAL_THEN + `!i. i <= k ==> (x:(num->bool)->num->real^N->bool) b i = x c i` + MP_TAC THENL + [INDUCT_TAC THEN ASM_SIMP_TAC[LE_SUC_LT; LT_IMP_LE]; + DISCH_THEN(MP_TAC o SPEC `k:num`)] THEN + REWRITE_TAC[LE_REFL] THEN DISCH_THEN SUBST1_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I + [TAUT `~(p <=> q) <=> (q <=> ~p)`]) THEN + REPEAT(COND_CASES_TAC THEN ASM_REWRITE_TAC[]) THEN + ASM_MESON_TAC[INTER_COMM]]]);; + +let CONDENSATION_POINTS_EQ_EMPTY,CARD_EQ_CONDENSATION_POINTS = + (CONJ_PAIR o prove) + (`(!s:real^N->bool. + {x | x condensation_point_of s} = {} <=> COUNTABLE s) /\ + (!s:real^N->bool. + {x | x condensation_point_of s} =_c (:real) <=> ~(COUNTABLE s))`, + REWRITE_TAC[AND_FORALL_THM] THEN GEN_TAC THEN MATCH_MP_TAC(TAUT + `(r ==> p) /\ (~r ==> q) /\ (p ==> ~q) + ==> (p <=> r) /\ (q <=> ~r)`) THEN + REPEAT CONJ_TAC THENL + [DISCH_TAC THEN REWRITE_TAC[EXTENSION; IN_ELIM_THM; NOT_IN_EMPTY] THEN + REWRITE_TAC[condensation_point_of] THEN + ASM_MESON_TAC[COUNTABLE_SUBSET; INTER_SUBSET; IN_UNIV; OPEN_UNIV]; + DISCH_TAC THEN MATCH_MP_TAC(REWRITE_RULE + [TAUT `p ==> q \/ r <=> p /\ ~q ==> r`] CARD_EQ_CLOSED) THEN + REWRITE_TAC[CLOSED_CONDENSATION_POINTS; GSYM COUNTABLE_ALT] THEN + FIRST_ASSUM(MP_TAC o MATCH_MP CARD_EQ_CONDENSATION_POINTS_IN_SET) THEN + DISCH_THEN(MP_TAC o MATCH_MP CARD_COUNTABLE_CONG) THEN + ASM_REWRITE_TAC[CONTRAPOS_THM] THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] COUNTABLE_SUBSET) THEN SET_TAC[]; + DISCH_THEN SUBST1_TAC THEN + DISCH_THEN(MP_TAC o MATCH_MP CARD_FINITE_CONG) THEN + REWRITE_TAC[FINITE_EMPTY; GSYM INFINITE; real_INFINITE]]);; + +let UNCOUNTABLE_HAS_CONDENSATION_POINT = prove + (`!s:real^N->bool. ~COUNTABLE s ==> ?x. x condensation_point_of s`, + REWRITE_TAC[GSYM CONDENSATION_POINTS_EQ_EMPTY] THEN SET_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* Density of sets with small complement, including irrationals. *) +(* ------------------------------------------------------------------------- *) + +let COSMALL_APPROXIMATION = prove + (`!s. ((:real) DIFF s) <_c (:real) + ==> !x e. &0 < e ==> ?y. y IN s /\ abs(y - x) < e`, + let lemma = prove + (`!s. ((:real^1) DIFF s) <_c (:real) + ==> !x e. &0 < e ==> ?y. y IN s /\ norm(y - x) < e`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC(SET_RULE + `~({x | P x} SUBSET UNIV DIFF s) ==> ?x. x IN s /\ P x`) THEN + MP_TAC(ISPEC `ball(x:real^1,e)` CARD_EQ_OPEN) THEN + ASM_REWRITE_TAC[OPEN_BALL; BALL_EQ_EMPTY; REAL_NOT_LE] THEN DISCH_TAC THEN + DISCH_THEN(MP_TAC o MATCH_MP CARD_LE_SUBSET) THEN + REWRITE_TAC[CARD_NOT_LE] THEN + REWRITE_TAC[GSYM(ONCE_REWRITE_RULE[DIST_SYM] dist); GSYM ball] THEN + TRANS_TAC CARD_LTE_TRANS `(:real)` THEN + ASM_SIMP_TAC[ONCE_REWRITE_RULE[CARD_EQ_SYM] CARD_EQ_IMP_LE]) in + REWRITE_TAC[FORALL_DROP_IMAGE; FORALL_DROP; EXISTS_DROP] THEN + REWRITE_TAC[GSYM IMAGE_DROP_UNIV; GSYM DROP_SUB; GSYM ABS_DROP] THEN + REWRITE_TAC[DROP_IN_IMAGE_DROP] THEN REWRITE_TAC[GSYM FORALL_DROP] THEN + SIMP_TAC[GSYM IMAGE_DIFF_INJ; DROP_EQ] THEN GEN_TAC THEN + DISCH_TAC THEN MATCH_MP_TAC lemma THEN POP_ASSUM MP_TAC THEN + MATCH_MP_TAC EQ_IMP THEN MATCH_MP_TAC CARD_LT_CONG THEN + REWRITE_TAC[IMAGE_DROP_UNIV; CARD_EQ_REFL] THEN + MATCH_MP_TAC CARD_EQ_IMAGE THEN SIMP_TAC[DROP_EQ]);; + +let COCOUNTABLE_APPROXIMATION = prove + (`!s. COUNTABLE((:real) DIFF s) + ==> !x e. &0 < e ==> ?y. y IN s /\ abs(y - x) < e`, + GEN_TAC THEN REWRITE_TAC[COUNTABLE; ge_c] THEN DISCH_TAC THEN + MATCH_MP_TAC COSMALL_APPROXIMATION THEN + TRANS_TAC CARD_LET_TRANS `(:num)` THEN ASM_REWRITE_TAC[] THEN + TRANS_TAC CARD_LTE_TRANS `(:num->bool)` THEN SIMP_TAC[CANTOR_THM_UNIV] THEN + MATCH_MP_TAC CARD_EQ_IMP_LE THEN ONCE_REWRITE_TAC[CARD_EQ_SYM] THEN + REWRITE_TAC[CARD_EQ_REAL]);; + +let IRRATIONAL_APPROXIMATION = prove + (`!x e. &0 < e ==> ?y. ~(rational y) /\ abs(y - x) < e`, + REWRITE_TAC[SET_RULE `~rational y <=> y IN UNIV DIFF rational`] THEN + MATCH_MP_TAC COCOUNTABLE_APPROXIMATION THEN + REWRITE_TAC[SET_RULE `UNIV DIFF (UNIV DIFF s) = s`; COUNTABLE_RATIONAL]);; + +let OPEN_SET_COSMALL_COORDINATES = prove + (`!P. (!i. 1 <= i /\ i <= dimindex(:N) + ==> (:real) DIFF {x | P i x} <_c (:real)) + ==> !s:real^N->bool. + open s /\ ~(s = {}) + ==> ?x. x IN s /\ !i. 1 <= i /\ i <= dimindex(:N) ==> P i (x$i)`, + REPEAT STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN + DISCH_THEN(X_CHOOSE_THEN `a:real^N` STRIP_ASSUME_TAC) THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [OPEN_CONTAINS_CBALL]) THEN + DISCH_THEN(MP_TAC o SPEC `a:real^N`) THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN + `!i. 1 <= i /\ i <= dimindex(:N) + ==> ?y:real. P i y /\ abs(y - (a:real^N)$i) < d / &(dimindex(:N))` + MP_TAC THENL + [X_GEN_TAC `i:num` THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `i:num`) THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(MP_TAC o MATCH_MP COSMALL_APPROXIMATION) THEN + REWRITE_TAC[IN_ELIM_THM] THEN DISCH_THEN MATCH_MP_TAC THEN + ASM_SIMP_TAC[REAL_LT_DIV; REAL_OF_NUM_LT; LE_1; DIMINDEX_GE_1]; + REWRITE_TAC[LAMBDA_SKOLEM] THEN MATCH_MP_TAC MONO_EXISTS THEN + REPEAT STRIP_TAC THEN ASM_SIMP_TAC[] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o GEN_REWRITE_RULE I [SUBSET]) THEN + REWRITE_TAC[IN_CBALL; dist] THEN + W(MP_TAC o PART_MATCH lhand NORM_LE_L1 o lhand o snd) THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] REAL_LE_TRANS) THEN + MATCH_MP_TAC SUM_BOUND_GEN THEN REWRITE_TAC[FINITE_NUMSEG; IN_NUMSEG] THEN + REWRITE_TAC[VECTOR_SUB_COMPONENT; NUMSEG_EMPTY; NOT_LT; DIMINDEX_GE_1] THEN + ONCE_REWRITE_TAC[REAL_ABS_SUB] THEN + ASM_SIMP_TAC[REAL_LT_IMP_LE; CARD_NUMSEG_1]]);; + +let OPEN_SET_COCOUNTABLE_COORDINATES = prove + (`!P. (!i. 1 <= i /\ i <= dimindex(:N) + ==> COUNTABLE((:real) DIFF {x | P i x})) + ==> !s:real^N->bool. + open s /\ ~(s = {}) + ==> ?x. x IN s /\ !i. 1 <= i /\ i <= dimindex(:N) ==> P i (x$i)`, + GEN_TAC THEN DISCH_TAC THEN MATCH_MP_TAC OPEN_SET_COSMALL_COORDINATES THEN + REPEAT STRIP_TAC THEN + TRANS_TAC CARD_LET_TRANS `(:num)` THEN ASM_SIMP_TAC[GSYM COUNTABLE_ALT] THEN + TRANS_TAC CARD_LTE_TRANS `(:num->bool)` THEN SIMP_TAC[CANTOR_THM_UNIV] THEN + MATCH_MP_TAC CARD_EQ_IMP_LE THEN ONCE_REWRITE_TAC[CARD_EQ_SYM] THEN + REWRITE_TAC[CARD_EQ_REAL]);; + +let OPEN_SET_IRRATIONAL_COORDINATES = prove + (`!s:real^N->bool. + open s /\ ~(s = {}) + ==> ?x. x IN s /\ !i. 1 <= i /\ i <= dimindex(:N) ==> ~rational(x$i)`, + MATCH_MP_TAC OPEN_SET_COCOUNTABLE_COORDINATES THEN + REWRITE_TAC[SET_RULE `UNIV DIFF {x | ~P x} = P`; COUNTABLE_RATIONAL]);; + +let CLOSURE_COSMALL_COORDINATES = prove + (`!P. (!i. 1 <= i /\ i <= dimindex(:N) + ==> (:real) DIFF {x | P i x} <_c (:real)) + ==> closure {x | !i. 1 <= i /\ i <= dimindex (:N) ==> P i (x$i)} = + (:real^N)`, + GEN_TAC THEN DISCH_TAC THEN + REWRITE_TAC[CLOSURE_APPROACHABLE; IN_UNIV; EXTENSION; IN_ELIM_THM] THEN + MAP_EVERY X_GEN_TAC [`x:real^N`; `e:real`] THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o MATCH_MP OPEN_SET_COSMALL_COORDINATES) THEN + DISCH_THEN(MP_TAC o SPEC `ball(x:real^N,e)`) THEN + ASM_REWRITE_TAC[OPEN_BALL; BALL_EQ_EMPTY; REAL_NOT_LE; IN_BALL] THEN + MESON_TAC[DIST_SYM]);; + +let CLOSURE_COCOUNTABLE_COORDINATES = prove + (`!P. (!i. 1 <= i /\ i <= dimindex(:N) + ==> COUNTABLE((:real) DIFF {x | P i x})) + ==> closure {x | !i. 1 <= i /\ i <= dimindex (:N) ==> P i (x$i)} = + (:real^N)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC CLOSURE_COSMALL_COORDINATES THEN + REPEAT STRIP_TAC THEN + TRANS_TAC CARD_LET_TRANS `(:num)` THEN ASM_SIMP_TAC[GSYM COUNTABLE_ALT] THEN + TRANS_TAC CARD_LTE_TRANS `(:num->bool)` THEN SIMP_TAC[CANTOR_THM_UNIV] THEN + MATCH_MP_TAC CARD_EQ_IMP_LE THEN ONCE_REWRITE_TAC[CARD_EQ_SYM] THEN + REWRITE_TAC[CARD_EQ_REAL]);; + +let CLOSURE_IRRATIONAL_COORDINATES = prove + (`closure {x | !i. 1 <= i /\ i <= dimindex (:N) ==> ~rational(x$i)} = + (:real^N)`, + MATCH_MP_TAC CLOSURE_COCOUNTABLE_COORDINATES THEN + REWRITE_TAC[SET_RULE `UNIV DIFF {x | ~P x} = P`; COUNTABLE_RATIONAL]);; + +(* ------------------------------------------------------------------------- *) +(* Every path between distinct points contains an arc, and hence *) +(* that path connection is equivalent to arcwise connection, for distinct *) +(* points. The proof is based on Whyburn's "Topological Analysis". *) +(* ------------------------------------------------------------------------- *) + +let HOMEOMORPHIC_MONOTONE_IMAGE_INTERVAL = prove + (`!f:real^1->real^N. + f continuous_on interval[vec 0,vec 1] /\ + (!y. connected {x | x IN interval[vec 0,vec 1] /\ f x = y}) /\ + ~(f(vec 1) = f(vec 0)) + ==> (IMAGE f (interval[vec 0,vec 1])) homeomorphic + (interval[vec 0:real^1,vec 1])`, + let closure_dyadic_rationals_in_convex_set_pos_1 = prove + (`!s. convex s /\ ~(interior s = {}) /\ (!x. x IN s ==> &0 <= drop x) + ==> closure(s INTER { lift(&m / &2 pow n) | + m IN (:num) /\ n IN (:num)}) = + closure s`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPEC `s:real^1->bool` CLOSURE_DYADIC_RATIONALS_IN_CONVEX_SET) THEN + ASM_REWRITE_TAC[] THEN DISCH_THEN(SUBST1_TAC o SYM) THEN AP_TERM_TAC THEN + MATCH_MP_TAC(SET_RULE + `(!x. x IN t ==> x IN u) /\ (!x. x IN u ==> x IN s ==> x IN t) + ==> s INTER t = s INTER u`) THEN + REWRITE_TAC[FORALL_IN_GSPEC; IN_UNIV; DIMINDEX_1; FORALL_1] THEN + REWRITE_TAC[IN_ELIM_THM; EXISTS_LIFT; GSYM drop; LIFT_DROP] THEN + REWRITE_TAC[REAL_ARITH `x / y:real = inv y * x`; LIFT_CMUL] THEN + CONJ_TAC THENL [MESON_TAC[INTEGER_CLOSED]; ALL_TAC] THEN + MAP_EVERY X_GEN_TAC [`n:num`; `x:real^1`] THEN REPEAT DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `inv(&2 pow n) % x:real^1`) THEN + ASM_SIMP_TAC[DROP_CMUL; REAL_LE_MUL_EQ; REAL_LT_POW2; REAL_LT_INV_EQ] THEN + ASM_MESON_TAC[INTEGER_POS; LIFT_DROP]) in + let function_on_dyadic_rationals = prove + (`!f:num->num->A. + (!m n. f (2 * m) (n + 1) = f m n) + ==> ?g. !m n. g(&m / &2 pow n) = f m n`, + REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[EQ_SYM_EQ] THEN MP_TAC(ISPECL + [`\(m,n). (f:num->num->A) m n`; `\(m,n). &m / &2 pow n`] + FUNCTION_FACTORS_LEFT) THEN + REWRITE_TAC[FORALL_PAIR_THM; FUN_EQ_THM; o_THM] THEN + DISCH_THEN (SUBST1_TAC o SYM) THEN + ONCE_REWRITE_TAC[MESON[] + `(!a b c d. P a b c d) <=> (!b d a c. P a b c d)`] THEN + MATCH_MP_TAC WLOG_LE THEN REPEAT CONJ_TAC THENL [MESON_TAC[]; ALL_TAC] THEN + SIMP_TAC[REAL_FIELD `~(y = &0) /\ ~(y' = &0) + ==> (x / y = x' / y' <=> y' / y * x = x')`; + REAL_POW_EQ_0; REAL_OF_NUM_EQ; REAL_DIV_POW2; ARITH_EQ] THEN + SIMP_TAC[LE_EXISTS; LEFT_IMP_EXISTS_THM] THEN + SIMP_TAC[ADD_SUB2; REAL_OF_NUM_MUL; REAL_OF_NUM_EQ; REAL_OF_NUM_POW] THEN + REWRITE_TAC[MESON[] + `(!n n' d. n' = f d n ==> !m m'. g d m = m' ==> P m m' n d) <=> + (!d m n. P m (g d m) n d)`] THEN + INDUCT_TAC THEN SIMP_TAC[EXP; MULT_CLAUSES; ADD_CLAUSES] THEN + REWRITE_TAC[GSYM MULT_ASSOC; ADD1] THEN ASM_MESON_TAC[]) in + let recursion_on_dyadic_rationals = prove + (`!b:num->A l r. + ?f. (!m. f(&m) = b m) /\ + (!m n. f(&(4 * m + 1) / &2 pow (n + 1)) = + l(f(&(2 * m + 1) / &2 pow n))) /\ + (!m n. f(&(4 * m + 3) / &2 pow (n + 1)) = + r(f(&(2 * m + 1) / &2 pow n)))`, + REPEAT GEN_TAC THEN + SUBGOAL_THEN + `?f:num->num->A. + (!m n. f (2 * m) (n + 1) = f m n) /\ + (!m. f m 0 = b m) /\ + (!m n. f (4 * m + 1) (n + 1) = l(f (2 * m + 1) n)) /\ + (!m n. f (4 * m + 3) (n + 1) = r(f (2 * m + 1) n))` + MP_TAC THENL + [MP_TAC(prove_recursive_functions_exist num_RECURSION + `(!m. f m 0 = (b:num->A) m) /\ + (!m n. f m (SUC n) = + if EVEN m then f (m DIV 2) n + else if EVEN(m DIV 2) + then l(f ((m + 1) DIV 2) n) + else r(f (m DIV 2) n))`) THEN + MATCH_MP_TAC MONO_EXISTS THEN + X_GEN_TAC `f:num->num->A` THEN STRIP_TAC THEN + RULE_ASSUM_TAC(REWRITE_RULE[ADD1]) THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[EVEN_MULT; ARITH_EVEN; ARITH_RULE `(2 * m) DIV 2 = m`] THEN + REWRITE_TAC[ARITH_RULE `(4 * m + 1) DIV 2 = 2 * m`; + ARITH_RULE `(4 * m + 3) DIV 2 = 2 * m + 1`; + ARITH_RULE `((4 * m + 1) + 1) DIV 2 = 2 * m + 1`; + ARITH_RULE `((4 * m + 3) + 1) DIV 2 = 2 * m + 2`] THEN + REWRITE_TAC[EVEN_ADD; EVEN_MULT; EVEN; ARITH_EVEN; SND]; + DISCH_THEN(X_CHOOSE_THEN `f:num->num->A` + (CONJUNCTS_THEN2 MP_TAC ASSUME_TAC)) THEN + DISCH_THEN(MP_TAC o MATCH_MP function_on_dyadic_rationals) THEN + MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC THEN + DISCH_THEN(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[GSYM th])) THEN + RULE_ASSUM_TAC(REWRITE_RULE[REAL_ARITH `x / &2 pow 0 = x`]) THEN + ASM_REWRITE_TAC[]]) in + let recursion_on_dyadic_rationals_1 = prove + (`!b:A l r. + ?f. (!m. f(&m / &2) = b) /\ + (!m n. 0 < n ==> f(&(4 * m + 1) / &2 pow (n + 1)) = + l(f(&(2 * m + 1) / &2 pow n))) /\ + (!m n. 0 < n ==> f(&(4 * m + 3) / &2 pow (n + 1)) = + r(f(&(2 * m + 1) / &2 pow n)))`, + REPEAT GEN_TAC THEN + MP_TAC(ISPECL [`(\n. b):num->A`; `l:A->A`; `r:A->A`] + recursion_on_dyadic_rationals) THEN + REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `f:real->A` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `\x. (f:real->A)(&2 * x)` THEN + ASM_REWRITE_TAC[REAL_ARITH `&2 * x / &2 = x`] THEN + CONJ_TAC THEN GEN_TAC THEN INDUCT_TAC THEN REWRITE_TAC[LT_REFL] THEN + ASM_SIMP_TAC[ADD_CLAUSES; real_pow; REAL_POW_EQ_0; REAL_OF_NUM_EQ; + ARITH_EQ; REAL_FIELD `~(y = &0) ==> &2 * x / (&2 * y) = x / y`]) in + let exists_function_unpair = prove + (`(?f:A->B#C. P f) <=> (?f1 f2. P(\x. (f1 x,f2 x)))`, + EQ_TAC THENL [ALL_TAC; MESON_TAC[]] THEN STRIP_TAC THEN + EXISTS_TAC `\x. FST((f:A->B#C) x)` THEN + EXISTS_TAC `\x. SND((f:A->B#C) x)` THEN + ASM_REWRITE_TAC[PAIR; ETA_AX]) in + let dyadics_in_open_unit_interval = prove + (`interval(vec 0,vec 1) INTER + {lift(&m / &2 pow n) | m IN (:num) /\ n IN (:num)} = + {lift(&m / &2 pow n) | 0 < m /\ m < 2 EXP n}`, + MATCH_MP_TAC(SET_RULE + `(!m n. (f m n) IN s <=> P m n) + ==> s INTER {f m n | m IN UNIV /\ n IN UNIV} = + {f m n | P m n}`) THEN + REWRITE_TAC[IN_INTERVAL_1; LIFT_DROP; DROP_VEC] THEN + SIMP_TAC[REAL_LT_RDIV_EQ; REAL_LT_LDIV_EQ; REAL_LT_POW2] THEN + SIMP_TAC[REAL_MUL_LZERO; REAL_MUL_LID; REAL_OF_NUM_POW; REAL_OF_NUM_LT]) in + REPEAT STRIP_TAC THEN + SUBGOAL_THEN + `!a b m. m IN interval[a,b] /\ interval[a,b] SUBSET interval[vec 0,vec 1] + ==> ?c d. drop a <= drop c /\ drop c <= drop m /\ + drop m <= drop d /\ drop d <= drop b /\ + (!x. x IN interval[c,d] ==> f x = f m) /\ + (!x. x IN interval[a,c] DELETE c ==> ~(f x = f m)) /\ + (!x. x IN interval[d,b] DELETE d ==> ~(f x = f m)) /\ + (!x y. x IN interval[a,c] DELETE c /\ + y IN interval[d,b] DELETE d + ==> ~((f:real^1->real^N) x = f y))` + MP_TAC THENL + [REWRITE_TAC[IN_INTERVAL_1; DROP_VEC; SUBSET_INTERVAL_1] THEN + REPEAT STRIP_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN + `?c d. {x | x IN interval[a,b] /\ (f:real^1->real^N) x = f m} = + interval[c,d]` + MP_TAC THENL + [SUBGOAL_THEN + `{x | x IN interval[a,b] /\ (f:real^1->real^N) x = f m} = + interval[a,b] INTER + {x | x IN interval[vec 0,vec 1] /\ (f:real^1->real^N) x = f m}` + SUBST1_TAC THENL + [REWRITE_TAC[EXTENSION; IN_INTER; IN_INTERVAL_1; IN_ELIM_THM; + DROP_VEC] THEN + GEN_TAC THEN EQ_TAC THEN SIMP_TAC[] THEN ASM_REAL_ARITH_TAC; + ALL_TAC] THEN + SUBGOAL_THEN + `?c d. {x | x IN interval[vec 0,vec 1] /\ (f:real^1->real^N) x = f m} = + interval[c,d]` + MP_TAC THENL + [ASM_REWRITE_TAC[GSYM CONNECTED_COMPACT_INTERVAL_1] THEN + ONCE_REWRITE_TAC[SET_RULE + `{x | x IN s /\ P x} = s INTER {x | x IN s /\ P x}`] THEN + MATCH_MP_TAC COMPACT_INTER_CLOSED THEN + REWRITE_TAC[COMPACT_INTERVAL] THEN + MATCH_MP_TAC CONTINUOUS_CLOSED_PREIMAGE_CONSTANT THEN + ASM_REWRITE_TAC[CLOSED_INTERVAL]; + STRIP_TAC THEN ASM_REWRITE_TAC[INTER_INTERVAL_1] THEN MESON_TAC[]]; + ALL_TAC] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `c:real^1` THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `d:real^1` THEN DISCH_TAC THEN + SUBGOAL_THEN `m IN interval[c:real^1,d]` MP_TAC THENL + [FIRST_X_ASSUM(fun th -> GEN_REWRITE_TAC RAND_CONV [GSYM th]) THEN + REWRITE_TAC[IN_ELIM_THM; IN_INTERVAL_1; DROP_VEC] THEN + ASM_REAL_ARITH_TAC; + REWRITE_TAC[IN_INTERVAL_1; IN_DELETE] THEN STRIP_TAC] THEN + SUBGOAL_THEN `{c:real^1,d} SUBSET interval[c,d]` MP_TAC THENL + [ASM_REWRITE_TAC[INSERT_SUBSET; EMPTY_SUBSET; IN_INTERVAL_1] THEN + ASM_REAL_ARITH_TAC; + FIRST_ASSUM(fun th -> GEN_REWRITE_TAC (LAND_CONV o RAND_CONV) + [GSYM th]) THEN + REWRITE_TAC[INSERT_SUBSET; EMPTY_SUBSET; IN_ELIM_THM; IN_INTERVAL_1] THEN + STRIP_TAC THEN ASM_REWRITE_TAC[]] THEN + CONJ_TAC THENL + [GEN_TAC THEN REWRITE_TAC[GSYM IN_INTERVAL_1] THEN + FIRST_X_ASSUM(fun th -> GEN_REWRITE_TAC (LAND_CONV o RAND_CONV) + [GSYM th]) THEN SIMP_TAC[IN_ELIM_THM]; + ALL_TAC] THEN + GEN_REWRITE_TAC I [CONJ_ASSOC] THEN CONJ_TAC THENL + [CONJ_TAC THEN FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE + `{x | x IN s /\ f x = a} = t + ==> (!x. P x ==> x IN s) /\ (!x. P x /\ Q x ==> ~(x IN t)) + ==> !x. P x /\ Q x ==> ~(f x = a)`)) THEN + REWRITE_TAC[IN_INTERVAL_1; GSYM DROP_EQ] THEN ASM_REAL_ARITH_TAC; + ALL_TAC] THEN + MAP_EVERY X_GEN_TAC [`x:real^1`; `y:real^1`] THEN + REWRITE_TAC[GSYM DROP_EQ] THEN STRIP_TAC THEN + SUBGOAL_THEN `{x:real^1,y} INTER interval[c,d] = {}` MP_TAC THENL + [REWRITE_TAC[SET_RULE `{a,b} INTER s = {} <=> ~(a IN s) /\ ~(b IN s)`; + IN_INTERVAL_1] THEN + ASM_REAL_ARITH_TAC; + FIRST_X_ASSUM(fun th -> GEN_REWRITE_TAC + (LAND_CONV o LAND_CONV o RAND_CONV) [GSYM th])] THEN + REWRITE_TAC[SET_RULE `{a,b} INTER s = {} <=> ~(a IN s) /\ ~(b IN s)`] THEN + REWRITE_TAC[IN_ELIM_THM; IN_INTERVAL_1] THEN + ASM_CASES_TAC `(f:real^1->real^N) x = f m` THENL + [ASM_REWRITE_TAC[] THEN ASM_REAL_ARITH_TAC; ALL_TAC] THEN + ASM_CASES_TAC `(f:real^1->real^N) y = f m` THENL + [ASM_REWRITE_TAC[] THEN ASM_REAL_ARITH_TAC; ALL_TAC] THEN + ASM_REWRITE_TAC[] THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM IS_INTERVAL_CONNECTED_1] o + SPEC `(f:real^1->real^N) y`) THEN + ASM_REWRITE_TAC[IS_INTERVAL_1] THEN DISCH_THEN(MP_TAC o SPECL + [`x:real^1`; `y:real^1`; `m:real^1`]) THEN + ASM_REWRITE_TAC[IN_ELIM_THM; IN_INTERVAL_1; DROP_VEC] THEN + ASM_REAL_ARITH_TAC; + REWRITE_TAC[RIGHT_IMP_EXISTS_THM; SKOLEM_THM; LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC + [`leftcut:real^1->real^1->real^1->real^1`; + `rightcut:real^1->real^1->real^1->real^1`] THEN + STRIP_TAC] THEN + FIRST_ASSUM(MP_TAC o SPECL + [`vec 0:real^1`; `vec 1:real^1`; `vec 0:real^1`]) THEN + REWRITE_TAC[SUBSET_REFL; ENDS_IN_UNIT_INTERVAL] THEN ABBREV_TAC + `u = (rightcut:real^1->real^1->real^1->real^1) (vec 0) (vec 1) (vec 0)` THEN + REWRITE_TAC[CONJ_ASSOC; REAL_LE_ANTISYM; DROP_EQ] THEN + REWRITE_TAC[GSYM CONJ_ASSOC] THEN ONCE_REWRITE_TAC[IMP_CONJ] THEN + DISCH_THEN(SUBST1_TAC o SYM) THEN + REWRITE_TAC[INTERVAL_SING; SET_RULE `~(x IN ({a} DELETE a))`] THEN + STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o SPECL + [`u:real^1`; `vec 1:real^1`; `vec 1:real^1`]) THEN + REWRITE_TAC[ENDS_IN_INTERVAL; SUBSET_INTERVAL_1; INTERVAL_NE_EMPTY_1] THEN + ASM_REWRITE_TAC[REAL_LE_REFL] THEN ABBREV_TAC + `v = (leftcut:real^1->real^1->real^1->real^1) u (vec 1) (vec 1)` THEN + ONCE_REWRITE_TAC[TAUT + `a /\ b /\ c /\ d /\ e <=> (c /\ d) /\ a /\ b /\ e`] THEN + REWRITE_TAC[REAL_LE_ANTISYM; DROP_EQ] THEN + ONCE_REWRITE_TAC[IMP_CONJ] THEN DISCH_THEN(SUBST1_TAC o SYM) THEN + REWRITE_TAC[INTERVAL_SING; SET_RULE `~(x IN ({a} DELETE a))`] THEN + STRIP_TAC THEN + SUBGOAL_THEN + `!x. x IN interval[vec 0,v] DELETE v + ==> ~((f:real^1->real^N) x = f(vec 1))` + ASSUME_TAC THENL + [X_GEN_TAC `t:real^1` THEN + REWRITE_TAC[IN_DELETE; IN_INTERVAL_1; GSYM DROP_EQ] THEN STRIP_TAC THEN + ASM_CASES_TAC `drop t < drop u` THENL + [FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (MESON[] + `~(f1 = f0) ==> ft = f0 ==> ~(ft = f1)`)); + ALL_TAC] THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_REWRITE_TAC[IN_INTERVAL_1; IN_DELETE; GSYM DROP_EQ] THEN + ASM_REAL_ARITH_TAC; + UNDISCH_THEN + `!x. x IN interval[u,v] DELETE v ==> ~((f:real^1->real^N) x = f (vec 1))` + (K ALL_TAC)] THEN + MP_TAC(ISPECL + [`(u:real^1,v:real^1)`; + `\(a,b). (a:real^1,leftcut a b (midpoint(a,b)):real^1)`; + `\(a,b). (rightcut a b (midpoint(a,b)):real^1,b:real^1)`] + recursion_on_dyadic_rationals_1) THEN + REWRITE_TAC[exists_function_unpair; PAIR_EQ] THEN + REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`a:real->real^1`; `b:real->real^1`] THEN + ABBREV_TAC `(c:real->real^1) x = midpoint(a x,b x)` THEN + REWRITE_TAC[TAUT `a ==> b /\ c <=> (a ==> b) /\ (a ==> c)`] THEN + REWRITE_TAC[FORALL_AND_THM] THEN STRIP_TAC THEN + SUBGOAL_THEN + `!m n. drop u <= drop(a(&m / &2 pow n)) /\ + drop(a(&m / &2 pow n)) <= drop(b(&m / &2 pow n)) /\ + drop(b(&m / &2 pow n)) <= drop v` + MP_TAC THENL + [GEN_REWRITE_TAC I [SWAP_FORALL_THM] THEN MATCH_MP_TAC num_INDUCTION THEN + CONJ_TAC THENL + [REWRITE_TAC[REAL_ARITH `x / &2 pow 0 = (&2 * x) / &2`] THEN + ASM_REWRITE_TAC[REAL_OF_NUM_MUL; REAL_LE_REFL]; + X_GEN_TAC `n:num` THEN DISCH_THEN(LABEL_TAC "*")] THEN + X_GEN_TAC `p:num` THEN DISJ_CASES_TAC(SPEC `p:num` EVEN_OR_ODD) THENL + [FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [EVEN_EXISTS]) THEN + DISCH_THEN(X_CHOOSE_THEN `m:num` SUBST1_TAC) THEN + REWRITE_TAC[GSYM REAL_OF_NUM_MUL; real_pow] THEN + ASM_SIMP_TAC[REAL_LT_POW2; REAL_FIELD + `&0 < y ==> (&2 * x) / (&2 * y) = x / y`]; + ALL_TAC] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [ODD_EXISTS]) THEN + DISCH_THEN(X_CHOOSE_THEN `m:num` SUBST1_TAC) THEN + DISJ_CASES_TAC(ARITH_RULE `n = 0 \/ 0 < n`) THENL + [ASM_REWRITE_TAC[real_pow; REAL_MUL_RID; REAL_LE_REFL]; + REWRITE_TAC[ADD1]] THEN + DISJ_CASES_TAC(SPEC `m:num` EVEN_OR_ODD) THENL + [FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [EVEN_EXISTS]) THEN + DISCH_THEN(X_CHOOSE_THEN `r:num` SUBST_ALL_TAC) THEN + ASM_SIMP_TAC[ARITH_RULE `2 * 2 * r = 4 * r`]; + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [ODD_EXISTS]) THEN + DISCH_THEN(X_CHOOSE_THEN `r:num` SUBST_ALL_TAC) THEN + ASM_SIMP_TAC[ARITH_RULE `2 * SUC(2 * r) + 1 = 4 * r + 3`]] THEN + (FIRST_X_ASSUM(MP_TAC o SPECL + [`a(&(2 * r + 1) / &2 pow n):real^1`; + `b(&(2 * r + 1) / &2 pow n):real^1`; + `c(&(2 * r + 1) / &2 pow n):real^1`]) THEN + ANTS_TAC THENL + [FIRST_X_ASSUM(fun th -> GEN_REWRITE_TAC (LAND_CONV o LAND_CONV) + [GSYM th]) THEN + REWRITE_TAC[midpoint; IN_INTERVAL_1; SUBSET_INTERVAL_1] THEN + REWRITE_TAC[DROP_CMUL; DROP_ADD] THEN + UNDISCH_TAC `drop(vec 0) <= drop u` THEN + UNDISCH_TAC `drop v <= drop (vec 1)`; + ALL_TAC] THEN + REMOVE_THEN "*" (MP_TAC o SPEC `2 * r + 1`) THEN REAL_ARITH_TAC); + REWRITE_TAC[FORALL_AND_THM] THEN STRIP_TAC] THEN + SUBGOAL_THEN `!m n. drop(vec 0) <= drop(a(&m / &2 pow n))` ASSUME_TAC THENL + [ASM_MESON_TAC[REAL_LE_TRANS]; ALL_TAC] THEN + SUBGOAL_THEN `!m n. drop(b(&m / &2 pow n)) <= drop(vec 1)` ASSUME_TAC THENL + [ASM_MESON_TAC[REAL_LE_TRANS]; ALL_TAC] THEN + SUBGOAL_THEN + `!m n. drop(a(&m / &2 pow n)) <= drop(c(&m / &2 pow n)) /\ + drop(c(&m / &2 pow n)) <= drop(b(&m / &2 pow n))` + MP_TAC THENL + [UNDISCH_THEN `!x:real. midpoint(a x:real^1,b x) = c x` + (fun th -> REWRITE_TAC[GSYM th]) THEN + REWRITE_TAC[midpoint; IN_INTERVAL_1; SUBSET_INTERVAL_1] THEN + ASM_REWRITE_TAC[DROP_CMUL; DROP_ADD; REAL_ARITH + `a <= inv(&2) * (a + b) /\ inv(&2) * (a + b) <= b <=> a <= b`]; + REWRITE_TAC[FORALL_AND_THM] THEN STRIP_TAC] THEN + SUBGOAL_THEN + `!i m n j. ODD j /\ + abs(&i / &2 pow m - &j / &2 pow n) < inv(&2 pow n) + ==> drop(a(&j / &2 pow n)) <= drop(c(&i / &2 pow m)) /\ + drop(c(&i / &2 pow m)) <= drop(b(&j / &2 pow n))` + ASSUME_TAC THENL + [REPLICATE_TAC 3 GEN_TAC THEN WF_INDUCT_TAC `m - n:num` THEN + DISJ_CASES_TAC(ARITH_RULE `m <= n \/ n:num < m`) THENL + [GEN_TAC THEN STRIP_TAC THEN + MP_TAC(SPEC `abs(&2 pow n) * abs(&i / &2 pow m - &j / &2 pow n)` + REAL_ABS_INTEGER_LEMMA) THEN + MATCH_MP_TAC(TAUT + `i /\ ~b /\ (n ==> p) ==> (i /\ ~n ==> b) ==> p`) THEN + REPEAT CONJ_TAC THENL + [REWRITE_TAC[GSYM REAL_ABS_MUL; INTEGER_ABS] THEN + REWRITE_TAC[REAL_ARITH + `n * (x / m - y / n):real = x * (n / m) - y * (n / n)`] THEN + ASM_SIMP_TAC[GSYM REAL_POW_SUB; LE_REFL; REAL_OF_NUM_EQ; ARITH_EQ] THEN + MESON_TAC[INTEGER_CLOSED]; + SIMP_TAC[REAL_ABS_MUL; REAL_ABS_ABS; REAL_ABS_POW; REAL_ABS_NUM] THEN + REWRITE_TAC[REAL_ARITH `~(&1 <= x * y) <=> y * x < &1`] THEN + SIMP_TAC[GSYM REAL_LT_RDIV_EQ; REAL_LT_POW2] THEN + ASM_REWRITE_TAC[REAL_ARITH `&1 / x = inv x`]; + ASM_SIMP_TAC[REAL_ABS_POW; REAL_ABS_NUM; REAL_ENTIRE; REAL_LT_IMP_NZ; + REAL_LT_POW2; REAL_ARITH `abs(x - y) = &0 <=> x = y`]]; + ALL_TAC] THEN + X_GEN_TAC `k:num` THEN REWRITE_TAC[IMP_CONJ; ODD_EXISTS] THEN + DISCH_THEN(X_CHOOSE_THEN `j:num` SUBST1_TAC) THEN + DISJ_CASES_TAC(ARITH_RULE `n = 0 \/ 0 < n`) THENL + [ASM_REWRITE_TAC[REAL_ARITH `x / &2 pow 0 = (&2 * x) / &2`] THEN + ASM_REWRITE_TAC[REAL_OF_NUM_MUL] THEN ASM_MESON_TAC[REAL_LE_TRANS]; + ALL_TAC] THEN + UNDISCH_THEN `n:num < m` + (fun th -> let th' = MATCH_MP + (ARITH_RULE `n < m ==> m - SUC n < m - n`) th in + FIRST_X_ASSUM(MP_TAC o C MATCH_MP th')) THEN + REPEAT_TCL DISJ_CASES_THEN ASSUME_TAC (REAL_ARITH + `&i / &2 pow m = &(2 * j + 1) / &2 pow n \/ + &i / &2 pow m < &(2 * j + 1) / &2 pow n \/ + &(2 * j + 1) / &2 pow n < &i / &2 pow m`) + THENL + [ASM_REWRITE_TAC[ADD1]; + DISCH_THEN(MP_TAC o SPEC `4 * j + 1`) THEN + REWRITE_TAC[ODD_ADD; ODD_MULT; ARITH] THEN ASM_SIMP_TAC[ADD1] THEN + MATCH_MP_TAC MONO_IMP THEN CONJ_TAC THENL + [MATCH_MP_TAC(REAL_ARITH + `x < i /\ &2 * n1 = n /\ j + n1 = i + ==> abs(x - i) < n ==> abs(x - j) < n1`) THEN + ASM_REWRITE_TAC[REAL_ARITH `a / b + inv b = (a + &1) / b`] THEN + REWRITE_TAC[real_div; REAL_POW_ADD; REAL_INV_MUL] THEN + REWRITE_TAC[GSYM REAL_OF_NUM_ADD; GSYM REAL_OF_NUM_MUL] THEN + REAL_ARITH_TAC; + MATCH_MP_TAC(REAL_ARITH + `b' <= b ==> a <= c /\ c <= b' ==> a <= c /\ c <= b`) THEN + FIRST_X_ASSUM(MP_TAC o SPECL + [`a(&(2 * j + 1) / &2 pow n):real^1`; + `b(&(2 * j + 1) / &2 pow n):real^1`; + `c(&(2 * j + 1) / &2 pow n):real^1`]) THEN + ANTS_TAC THENL [ALL_TAC; REAL_ARITH_TAC] THEN + FIRST_X_ASSUM(fun th -> GEN_REWRITE_TAC (LAND_CONV o LAND_CONV) + [GSYM th]) THEN + REWRITE_TAC[midpoint; IN_INTERVAL_1; SUBSET_INTERVAL_1] THEN + REWRITE_TAC[DROP_CMUL; DROP_ADD] THEN + ASM_REWRITE_TAC[DROP_CMUL; DROP_ADD; REAL_ARITH + `a <= inv(&2) * (a + b) /\ inv(&2) * (a + b) <= b <=> a <= b`]]; + DISCH_THEN(MP_TAC o SPEC `4 * j + 3`) THEN + REWRITE_TAC[ODD_ADD; ODD_MULT; ARITH] THEN ASM_SIMP_TAC[ADD1] THEN + MATCH_MP_TAC MONO_IMP THEN CONJ_TAC THENL + [MATCH_MP_TAC(REAL_ARITH + `i < x /\ &2 * n1 = n /\ j - n1 = i + ==> abs(x - i) < n ==> abs(x - j) < n1`) THEN + ASM_REWRITE_TAC[REAL_ARITH `a / b - inv b = (a - &1) / b`] THEN + REWRITE_TAC[real_div; REAL_POW_ADD; REAL_INV_MUL] THEN + REWRITE_TAC[GSYM REAL_OF_NUM_ADD; GSYM REAL_OF_NUM_MUL] THEN + REAL_ARITH_TAC; + MATCH_MP_TAC(REAL_ARITH + `a <= a' ==> a' <= c /\ c <= b ==> a <= c /\ c <= b`) THEN + FIRST_X_ASSUM(MP_TAC o SPECL + [`a(&(2 * j + 1) / &2 pow n):real^1`; + `b(&(2 * j + 1) / &2 pow n):real^1`; + `c(&(2 * j + 1) / &2 pow n):real^1`]) THEN + ANTS_TAC THENL [ALL_TAC; REAL_ARITH_TAC] THEN + FIRST_X_ASSUM(fun th -> GEN_REWRITE_TAC (LAND_CONV o LAND_CONV) + [GSYM th]) THEN + REWRITE_TAC[midpoint; IN_INTERVAL_1; SUBSET_INTERVAL_1] THEN + REWRITE_TAC[DROP_CMUL; DROP_ADD] THEN + ASM_REWRITE_TAC[DROP_CMUL; DROP_ADD; REAL_ARITH + `a <= inv(&2) * (a + b) /\ inv(&2) * (a + b) <= b <=> a <= b`]]]; + ALL_TAC] THEN + SUBGOAL_THEN + `!m n. ODD m ==> abs(drop(a(&m / &2 pow n)) - drop(b(&m / &2 pow n))) + <= &2 / &2 pow n` + ASSUME_TAC THENL + [ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN INDUCT_TAC THENL + [ASM_REWRITE_TAC[REAL_ARITH `x / &2 pow 0 = (&2 * x) / &2`] THEN + ASM_REWRITE_TAC[REAL_OF_NUM_MUL] THEN CONV_TAC NUM_REDUCE_CONV THEN + RULE_ASSUM_TAC(REWRITE_RULE[DROP_VEC]) THEN ASM_REAL_ARITH_TAC; + ALL_TAC] THEN + X_GEN_TAC `m:num` THEN REWRITE_TAC[ODD_EXISTS] THEN + DISCH_THEN(X_CHOOSE_THEN `k:num` SUBST1_TAC) THEN + DISJ_CASES_TAC(ARITH_RULE `n = 0 \/ 0 < n`) THENL + [ASM_REWRITE_TAC[ARITH; REAL_POW_1] THEN + RULE_ASSUM_TAC(REWRITE_RULE[DROP_VEC]) THEN ASM_REAL_ARITH_TAC; + ALL_TAC] THEN + DISJ_CASES_TAC(SPEC `k:num` EVEN_OR_ODD) THENL + [FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [EVEN_EXISTS]) THEN + DISCH_THEN(X_CHOOSE_THEN `j:num` SUBST1_TAC) THEN + REWRITE_TAC[ARITH_RULE `SUC(2 * 2 * j) = 4 * j + 1`] THEN + ASM_SIMP_TAC[ADD1] THEN + MATCH_MP_TAC(REAL_ARITH + `drop c = (drop a + drop b) / &2 /\ + abs(drop a - drop b) <= &2 * k /\ + drop a <= drop(leftcut a b c) /\ + drop(leftcut a b c) <= drop c + ==> abs(drop a - drop(leftcut a b c)) <= k`); + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [ODD_EXISTS]) THEN + DISCH_THEN(X_CHOOSE_THEN `j:num` SUBST1_TAC) THEN + REWRITE_TAC[ARITH_RULE `SUC(2 * SUC(2 * j)) = 4 * j + 3`] THEN + ASM_SIMP_TAC[ADD1] THEN + MATCH_MP_TAC(REAL_ARITH + `drop c = (drop a + drop b) / &2 /\ + abs(drop a - drop b) <= &2 * k /\ + drop c <= drop(rightcut a b c) /\ + drop(rightcut a b c) <= drop b + ==> abs(drop(rightcut a b c) - drop b) <= k`)] THEN + (CONJ_TAC THENL + [UNDISCH_THEN `!x:real. midpoint(a x:real^1,b x) = c x` + (fun th -> REWRITE_TAC[GSYM th]) THEN + REWRITE_TAC[midpoint; DROP_CMUL; DROP_ADD] THEN REAL_ARITH_TAC; + ALL_TAC] THEN + CONJ_TAC THENL + [REWRITE_TAC[real_div; REAL_POW_ADD; REAL_INV_MUL] THEN + REWRITE_TAC[REAL_ARITH `&2 * x * inv y * inv(&2 pow 1) = x / y`] THEN + ASM_SIMP_TAC[GSYM real_div; ODD_ADD; ODD_MULT; ARITH]; + ALL_TAC] THEN + FIRST_X_ASSUM(MP_TAC o SPECL + [`a(&(2 * j + 1) / &2 pow n):real^1`; + `b(&(2 * j + 1) / &2 pow n):real^1`; + `c(&(2 * j + 1) / &2 pow n):real^1`]) THEN + ANTS_TAC THENL [ALL_TAC; REAL_ARITH_TAC] THEN + FIRST_X_ASSUM(fun th -> GEN_REWRITE_TAC (LAND_CONV o LAND_CONV) + [GSYM th]) THEN + REWRITE_TAC[midpoint; IN_INTERVAL_1; SUBSET_INTERVAL_1] THEN + REWRITE_TAC[DROP_CMUL; DROP_ADD] THEN + ASM_REWRITE_TAC[DROP_CMUL; DROP_ADD; REAL_ARITH + `a <= inv(&2) * (a + b) /\ inv(&2) * (a + b) <= b <=> a <= b`]); + ALL_TAC] THEN + SUBGOAL_THEN + `!n j. 0 < 2 * j /\ 2 * j < 2 EXP n + ==> (f:real^1->real^N)(b(&(2 * j - 1) / &2 pow n)) = + f(a(&(2 * j + 1) / &2 pow n))` + ASSUME_TAC THENL + [MATCH_MP_TAC num_INDUCTION THEN CONJ_TAC THENL + [REWRITE_TAC[ARITH_RULE `0 < 2 * j <=> 0 < j`; + ARITH_RULE `2 * j < 2 <=> j < 1`] THEN + ARITH_TAC; + ALL_TAC] THEN + X_GEN_TAC `n:num` THEN DISCH_THEN(LABEL_TAC "+") THEN + DISJ_CASES_TAC(ARITH_RULE `n = 0 \/ 0 < n`) THENL + [ASM_REWRITE_TAC[] THEN CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[ARITH_RULE `0 < 2 * j <=> 0 < j`; + ARITH_RULE `2 * j < 2 <=> j < 1`] THEN + ARITH_TAC; + ALL_TAC] THEN + X_GEN_TAC `k:num` THEN DISJ_CASES_TAC(SPEC `k:num` EVEN_OR_ODD) THENL + [FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [EVEN_EXISTS]) THEN + DISCH_THEN(X_CHOOSE_THEN `j:num` SUBST1_TAC) THEN + REWRITE_TAC[EXP; ARITH_RULE `0 < 2 * j <=> 0 < j`; LT_MULT_LCANCEL] THEN + CONV_TAC NUM_REDUCE_CONV THEN + ASM_SIMP_TAC[ARITH_RULE `0 < j ==> 2 * 2 * j - 1 = 4 * (j - 1) + 3`; + ADD1; ARITH_RULE `2 * 2 * j + 1 = 4 * j + 1`] THEN + SIMP_TAC[ARITH_RULE `0 < j ==> 2 * (j - 1) + 1 = 2 * j - 1`] THEN + STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_ARITH_TAC; + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [ODD_EXISTS]) THEN + DISCH_THEN(X_CHOOSE_THEN `j:num` SUBST1_TAC) THEN + STRIP_TAC THEN + ASM_SIMP_TAC[ADD1; ARITH_RULE `2 * SUC(2 * j) - 1 = 4 * j + 1`; + ARITH_RULE `2 * SUC(2 * j) + 1 = 4 * j + 3`] THEN + FIRST_X_ASSUM(MP_TAC o SPECL + [`a(&(2 * j + 1) / &2 pow n):real^1`; + `b(&(2 * j + 1) / &2 pow n):real^1`; + `c(&(2 * j + 1) / &2 pow n):real^1`]) THEN + ANTS_TAC THENL + [FIRST_X_ASSUM(fun th -> GEN_REWRITE_TAC (LAND_CONV o LAND_CONV) + [GSYM th]) THEN + REWRITE_TAC[midpoint; IN_INTERVAL_1; SUBSET_INTERVAL_1] THEN + REWRITE_TAC[DROP_CMUL; DROP_ADD] THEN + ASM_REWRITE_TAC[DROP_CMUL; DROP_ADD; REAL_ARITH + `a <= inv(&2) * (a + b) /\ inv(&2) * (a + b) <= b <=> a <= b`]; + REPLICATE_TAC 4 (DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + DISCH_THEN(CONJUNCTS_THEN2 MP_TAC STRIP_ASSUME_TAC) THEN + MATCH_MP_TAC(MESON[] + `a IN s /\ b IN s ==> (!x. x IN s ==> f x = c) ==> f a = f b`) THEN + REWRITE_TAC[ENDS_IN_INTERVAL; INTERVAL_NE_EMPTY_1] THEN + ASM_MESON_TAC[REAL_LE_TRANS]]]; + ALL_TAC] THEN + SUBGOAL_THEN + `!n j. 0 < j /\ j < 2 EXP n + ==> (f:real^1->real^N)(b(&(2 * j - 1) / &2 pow (n + 1))) = + f(c(&j / &2 pow n)) /\ + f(a(&(2 * j + 1) / &2 pow (n + 1))) = f(c(&j / &2 pow n))` + ASSUME_TAC THENL + [MATCH_MP_TAC num_INDUCTION THEN + REWRITE_TAC[ARITH_RULE `~(0 < j /\ j < 2 EXP 0)`] THEN + X_GEN_TAC `n:num` THEN DISCH_THEN(LABEL_TAC "*") THEN + X_GEN_TAC `j:num` THEN + DISJ_CASES_TAC(SPEC `j:num` EVEN_OR_ODD) THENL + [FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [EVEN_EXISTS]) THEN + DISCH_THEN(X_CHOOSE_THEN `k:num` SUBST1_TAC) THEN + REWRITE_TAC[ADD_CLAUSES; EXP; ARITH_RULE `0 < 2 * k <=> 0 < k`; + ARITH_RULE `2 * x < 2 * y <=> x < y`] THEN STRIP_TAC THEN + REMOVE_THEN "*" (MP_TAC o SPEC `k:num`) THEN + ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC(MESON[] + `c' = c /\ a' = a /\ b' = b + ==> b = c /\ a = c ==> b' = c' /\ a' = c'`) THEN + REPEAT CONJ_TAC THEN AP_TERM_TAC THENL + [AP_TERM_TAC THEN + REWRITE_TAC[real_pow; real_div; REAL_INV_MUL; + GSYM REAL_OF_NUM_MUL] THEN + REAL_ARITH_TAC; + REWRITE_TAC[ADD1; ARITH_RULE `2 * 2 * n = 4 * n`] THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN ARITH_TAC; + SUBGOAL_THEN `k = PRE k + 1` SUBST1_TAC THENL + [ASM_ARITH_TAC; ALL_TAC] THEN + REWRITE_TAC[ARITH_RULE `2 * (k + 1) - 1 = 2 * k + 1`; + ARITH_RULE `2 * 2 * (k + 1) - 1 = 4 * k + 3`] THEN + REWRITE_TAC[ADD1] THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ARITH_TAC]; + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [ODD_EXISTS]) THEN + DISCH_THEN(X_CHOOSE_THEN `k:num` SUBST1_TAC) THEN + REWRITE_TAC[EXP; ARITH_RULE `SUC(2 * k) < 2 * n <=> k < n`] THEN + STRIP_TAC THEN FIRST_X_ASSUM(MP_TAC o SPECL + [`a(&(2 * k + 1) / &2 pow (SUC n)):real^1`; + `b(&(2 * k + 1) / &2 pow (SUC n)):real^1`; + `c(&(2 * k + 1) / &2 pow (SUC n)):real^1`]) THEN + ANTS_TAC THENL + [ASM_REWRITE_TAC[midpoint; IN_INTERVAL_1; SUBSET_INTERVAL_1]; + REPLICATE_TAC 4 (DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + DISCH_THEN(CONJUNCTS_THEN2 MP_TAC STRIP_ASSUME_TAC)] THEN + REWRITE_TAC[ARITH_RULE `SUC(2 * k) = 2 * k + 1`] THEN + DISCH_THEN(fun th -> CONJ_TAC THEN MATCH_MP_TAC th) THEN + ASM_SIMP_TAC[ARITH_RULE `2 * (2 * k + 1) - 1 = 4 * k + 1`; ADD1; + ARITH_RULE `2 * (2 * k + 1) + 1 = 4 * k + 3`; + ARITH_RULE `0 < n + 1`] THEN + ASM_REWRITE_TAC[IN_INTERVAL_1; GSYM ADD1] THEN + ASM_SIMP_TAC[ARITH_RULE `SUC(2 * k) = 2 * k + 1`] THEN + ASM_REAL_ARITH_TAC]; + ALL_TAC] THEN + ONCE_REWRITE_TAC[HOMEOMORPHIC_SYM] THEN + MATCH_MP_TAC HOMEOMORPHIC_COMPACT THEN + REWRITE_TAC[COMPACT_INTERVAL] THEN + MP_TAC(ISPECL [`\x. (f:real^1->real^N)(c(drop x))`; + `interval(vec 0,vec 1) INTER + {lift(&m / &2 pow n) | m IN (:num) /\ n IN (:num)}`] + UNIFORMLY_CONTINUOUS_EXTENDS_TO_CLOSURE) THEN + SIMP_TAC[closure_dyadic_rationals_in_convex_set_pos_1; + CONVEX_INTERVAL; INTERIOR_OPEN; OPEN_INTERVAL; + UNIT_INTERVAL_NONEMPTY; IN_INTERVAL_1; REAL_LT_IMP_LE; DROP_VEC; + CLOSURE_OPEN_INTERVAL] THEN + REWRITE_TAC[dyadics_in_open_unit_interval] THEN + ANTS_TAC THENL + [REWRITE_TAC[uniformly_continuous_on; FORALL_IN_GSPEC] THEN + X_GEN_TAC `e:real` THEN DISCH_TAC THEN SUBGOAL_THEN + `(f:real^1->real^N) uniformly_continuous_on interval[vec 0,vec 1]` + MP_TAC THENL + [ASM_SIMP_TAC[COMPACT_UNIFORMLY_CONTINUOUS; COMPACT_INTERVAL]; + REWRITE_TAC[uniformly_continuous_on]] THEN + DISCH_THEN(MP_TAC o SPEC `e / &2`) THEN ASM_REWRITE_TAC[REAL_HALF] THEN + DISCH_THEN(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC) THEN + MP_TAC(SPECL [`inv(&2)`; `min (d:real) (&1 / &4)`] REAL_ARCH_POW_INV) THEN + ASM_REWRITE_TAC[REAL_HALF; REAL_POW_INV; REAL_LT_MIN] THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN + DISCH_THEN(X_CHOOSE_THEN `n:num` MP_TAC) THEN + ASM_CASES_TAC `n = 0` THEN ASM_REWRITE_TAC[] THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN STRIP_TAC THEN + EXISTS_TAC `inv(&2 pow n)` THEN + REWRITE_TAC[REAL_LT_POW2; REAL_LT_INV_EQ] THEN + REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN + REWRITE_TAC[FORALL_IN_GSPEC] THEN + SUBGOAL_THEN + `!i j m. 0 < i /\ i < 2 EXP m /\ 0 < j /\ j < 2 EXP n /\ + abs(&i / &2 pow m - &j / &2 pow n) < inv(&2 pow n) + ==> norm((f:real^1->real^N)(c(&i / &2 pow m)) - + f(c(&j / &2 pow n))) < e / &2` + ASSUME_TAC THENL + [REPEAT GEN_TAC THEN + REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + DISCH_THEN(DISJ_CASES_THEN MP_TAC o MATCH_MP (REAL_ARITH + `abs(x - a) < e + ==> x = a \/ + abs(x - (a - e / &2)) < e / &2 \/ + abs(x - (a + e / &2)) < e / &2`)) + THENL + [DISCH_THEN SUBST1_TAC THEN + ASM_REWRITE_TAC[VECTOR_SUB_REFL; NORM_0; REAL_HALF]; + ALL_TAC] THEN + SUBGOAL_THEN + `&j / &2 pow n = &(2 * j) / &2 pow (n + 1)` + (fun th -> GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [th]) + THENL + [REWRITE_TAC[REAL_POW_ADD; real_div; REAL_INV_MUL; + GSYM REAL_OF_NUM_MUL] THEN + REAL_ARITH_TAC; + ALL_TAC] THEN + REWRITE_TAC[real_div; GSYM REAL_INV_MUL] THEN + REWRITE_TAC[GSYM real_div; + GSYM(ONCE_REWRITE_RULE[REAL_MUL_SYM] (CONJUNCT2 real_pow))] THEN + REWRITE_TAC[ADD1; REAL_ARITH `x / n + inv n = (x + &1) / n`; + REAL_ARITH `x / n - inv n = (x - &1) / n`] THEN + ASM_SIMP_TAC[REAL_OF_NUM_SUB; ARITH_RULE `0 < j ==> 1 <= 2 * j`] THEN + REWRITE_TAC[REAL_OF_NUM_ADD] THEN STRIP_TAC THENL + [SUBGOAL_THEN `(f:real^1->real^N)(c(&j / &2 pow n)) = + f(b (&(2 * j - 1) / &2 pow (n + 1)))` + SUBST1_TAC THENL [ASM_SIMP_TAC[]; ALL_TAC]; + SUBGOAL_THEN `(f:real^1->real^N)(c(&j / &2 pow n)) = + f(a (&(2 * j + 1) / &2 pow (n + 1)))` + SUBST1_TAC THENL [ASM_SIMP_TAC[]; ALL_TAC]] THEN + REWRITE_TAC[GSYM dist] THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + REWRITE_TAC[IN_INTERVAL_1] THEN + REPEAT(CONJ_TAC THENL [ASM_MESON_TAC[REAL_LE_TRANS]; ALL_TAC]) THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`i:num`; `m:num`; `n + 1`]) THENL + [DISCH_THEN(MP_TAC o SPEC `2 * j - 1`) THEN REWRITE_TAC[ODD_SUB]; + DISCH_THEN(MP_TAC o SPEC `2 * j + 1`) THEN REWRITE_TAC[ODD_ADD]] THEN + ASM_REWRITE_TAC[ODD_MULT; ARITH; ARITH_RULE `1 < 2 * j <=> 0 < j`] THEN + REWRITE_TAC[DIST_REAL; GSYM drop] THENL + [MATCH_MP_TAC(NORM_ARITH + `!t. abs(a - b) <= t /\ t < d + ==> a <= c /\ c <= b ==> abs(c - b) < d`); + MATCH_MP_TAC(NORM_ARITH + `!t. abs(a - b) <= t /\ t < d + ==> a <= c /\ c <= b ==> abs(c - a) < d`)] THEN + EXISTS_TAC `&2 / &2 pow (n + 1)` THEN + (CONJ_TAC THENL + [FIRST_X_ASSUM MATCH_MP_TAC THEN + REWRITE_TAC[ODD_SUB; ODD_ADD; ODD_MULT; ARITH_ODD] THEN + ASM_REWRITE_TAC[ARITH_RULE `1 < 2 * j <=> 0 < j`]; + REWRITE_TAC[REAL_POW_ADD; real_div; REAL_INV_MUL] THEN + ASM_REAL_ARITH_TAC]); + ALL_TAC] THEN + MAP_EVERY X_GEN_TAC [`i:num`; `m:num`] THEN STRIP_TAC THEN + MAP_EVERY X_GEN_TAC [`k:num`; `p:num`] THEN STRIP_TAC THEN + REWRITE_TAC[DIST_LIFT; LIFT_DROP] THEN STRIP_TAC THEN + SUBGOAL_THEN + `?j. 0 < j /\ j < 2 EXP n /\ + abs(&i / &2 pow m - &j / &2 pow n) < inv(&2 pow n) /\ + abs(&k / &2 pow p - &j / &2 pow n) < inv(&2 pow n)` + STRIP_ASSUME_TAC THENL + [MP_TAC(SPEC `max (&2 pow n * &i / &2 pow m) + (&2 pow n * &k / &2 pow p)` + FLOOR_POS) THEN + SIMP_TAC[REAL_LE_MUL; REAL_LE_MAX; REAL_LE_DIV; + REAL_POS; REAL_POW_LE] THEN + DISCH_THEN(X_CHOOSE_TAC `j:num`) THEN + MP_TAC(SPEC `max (&2 pow n * &i / &2 pow m) + (&2 pow n * &k / &2 pow p)` FLOOR) THEN + ASM_REWRITE_TAC[REAL_LE_MAX; REAL_MAX_LT] THEN + ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN + SIMP_TAC[GSYM REAL_LE_LDIV_EQ; GSYM REAL_LT_RDIV_EQ; REAL_LT_POW2] THEN + REWRITE_TAC[REAL_ARITH `(j + &1) / n = j / n + inv n`] THEN + ASM_CASES_TAC `j = 0` THENL + [ASM_REWRITE_TAC[REAL_ARITH `&0 / x = &0`; REAL_ADD_LID] THEN + DISCH_TAC THEN EXISTS_TAC `1` THEN CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[ARITH_RULE `1 < n <=> 2 EXP 1 <= n`] THEN + ASM_SIMP_TAC[LE_EXP; LE_1] THEN CONV_TAC NUM_REDUCE_CONV THEN + MATCH_MP_TAC(REAL_ARITH + `&0 < x /\ x < inv n /\ &0 < y /\ y < inv n + ==> abs(x - &1 / n) < inv n /\ abs(y - &1 / n) < inv n`) THEN + ASM_SIMP_TAC[REAL_LT_DIV; REAL_OF_NUM_LT; REAL_LT_POW2]; + DISCH_TAC THEN EXISTS_TAC `j:num` THEN ASM_SIMP_TAC[LE_1] THEN + REWRITE_TAC[GSYM REAL_OF_NUM_LT; GSYM REAL_OF_NUM_POW] THEN + CONJ_TAC THENL [ALL_TAC; ASM_REAL_ARITH_TAC] THEN + FIRST_X_ASSUM(fun th -> GEN_REWRITE_TAC LAND_CONV [GSYM th]) THEN + SIMP_TAC[GSYM REAL_NOT_LE; REAL_LE_FLOOR; INTEGER_CLOSED] THEN + REWRITE_TAC[REAL_NOT_LE; REAL_MAX_LT] THEN + REWRITE_TAC[REAL_ARITH `n * x < n <=> n * x < n * &1`] THEN + SIMP_TAC[REAL_LT_LMUL_EQ; REAL_LT_POW2; REAL_LT_LDIV_EQ] THEN + ASM_REWRITE_TAC[REAL_MUL_LID; REAL_OF_NUM_POW; REAL_OF_NUM_LT]]; + MATCH_MP_TAC(NORM_ARITH + `!u. dist(w:real^N,u) < e / &2 /\ dist(z,u) < e / &2 + ==> dist(w,z) < e`) THEN + EXISTS_TAC `(f:real^1->real^N)(c(&j / &2 pow n))` THEN + REWRITE_TAC[dist] THEN CONJ_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_REWRITE_TAC[]]; + ALL_TAC] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `h:real^1->real^N` THEN + REWRITE_TAC[FORALL_IN_GSPEC; LIFT_DROP] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC (MP_TAC o CONJUNCT1)) THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP UNIFORMLY_CONTINUOUS_IMP_CONTINUOUS) THEN + ONCE_REWRITE_TAC[MESON[] `h x = f(c(drop x)) <=> f(c(drop x)) = h x`] THEN + REWRITE_TAC[IN_INTER; IMP_CONJ_ALT; FORALL_IN_GSPEC] THEN + ASM_REWRITE_TAC[IN_UNIV; LIFT_DROP; IMP_IMP; GSYM CONJ_ASSOC] THEN + REWRITE_TAC[IN_INTERVAL_1; DROP_VEC; LIFT_DROP] THEN + SIMP_TAC[REAL_LT_RDIV_EQ; REAL_LT_LDIV_EQ; REAL_LT_POW2] THEN + REWRITE_TAC[REAL_MUL_LZERO; REAL_MUL_LID] THEN + REWRITE_TAC[REAL_OF_NUM_POW; REAL_OF_NUM_LT] THEN + REWRITE_TAC[GSYM REAL_OF_NUM_POW] THEN DISCH_TAC THEN + CONJ_TAC THENL + [MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL + [MP_TAC(ISPEC `interval(vec 0:real^1,vec 1)` + closure_dyadic_rationals_in_convex_set_pos_1) THEN + SIMP_TAC[CONVEX_INTERVAL; IN_INTERVAL_1; REAL_LT_IMP_LE; DROP_VEC; + INTERIOR_OPEN; OPEN_INTERVAL; INTERVAL_NE_EMPTY_1; REAL_LT_01; + CLOSURE_OPEN_INTERVAL] THEN + DISCH_THEN(fun th -> + GEN_REWRITE_TAC (LAND_CONV o RAND_CONV) [GSYM th]) THEN + MATCH_MP_TAC IMAGE_CLOSURE_SUBSET THEN REPEAT CONJ_TAC THENL + [FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET)) THEN + MATCH_MP_TAC CLOSURE_MINIMAL THEN REWRITE_TAC[CLOSED_INTERVAL] THEN + MATCH_MP_TAC(SET_RULE `s SUBSET u ==> s INTER t SUBSET u`) THEN + REWRITE_TAC[INTERVAL_OPEN_SUBSET_CLOSED]; + MATCH_MP_TAC COMPACT_IMP_CLOSED THEN + MATCH_MP_TAC COMPACT_CONTINUOUS_IMAGE THEN + ASM_REWRITE_TAC[COMPACT_INTERVAL]; + SIMP_TAC[dyadics_in_open_unit_interval; SUBSET; FORALL_IN_IMAGE] THEN + ASM_SIMP_TAC[FORALL_IN_GSPEC] THEN + MAP_EVERY X_GEN_TAC [`m:num`; `n:num`] THEN STRIP_TAC THEN + MATCH_MP_TAC FUN_IN_IMAGE THEN REWRITE_TAC[IN_INTERVAL_1] THEN + ASM_MESON_TAC[REAL_LE_TRANS]]; + MATCH_MP_TAC SUBSET_TRANS THEN + EXISTS_TAC `closure(IMAGE (h:real^1->real^N) + (interval (vec 0,vec 1) INTER + {lift (&m / &2 pow n) | m IN (:num) /\ n IN (:num)}))` THEN + CONJ_TAC THENL + [ALL_TAC; + MATCH_MP_TAC CLOSURE_MINIMAL THEN + ASM_SIMP_TAC[COMPACT_IMP_CLOSED; COMPACT_INTERVAL; + COMPACT_CONTINUOUS_IMAGE] THEN + MATCH_MP_TAC IMAGE_SUBSET THEN + MATCH_MP_TAC(SET_RULE `s SUBSET u ==> s INTER t SUBSET u`) THEN + REWRITE_TAC[INTERVAL_OPEN_SUBSET_CLOSED]] THEN + REWRITE_TAC[SUBSET; CLOSURE_APPROACHABLE; FORALL_IN_IMAGE] THEN + REWRITE_TAC[dyadics_in_open_unit_interval; + EXISTS_IN_IMAGE; EXISTS_IN_GSPEC] THEN + X_GEN_TAC `x:real^1` THEN DISCH_TAC THEN + X_GEN_TAC `e:real` THEN DISCH_TAC THEN UNDISCH_TAC + `(f:real^1->real^N) continuous_on interval [vec 0,vec 1]` THEN + DISCH_THEN(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 + DISCH_THEN(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN + `!n. ~(n = 0) + ==> ?m y. ODD m /\ 0 < m /\ m < 2 EXP n /\ + y IN interval[a(&m / &2 pow n),b(&m / &2 pow n)] /\ + (f:real^1->real^N) y = f x` + MP_TAC THENL + [ALL_TAC; + MP_TAC(SPECL [`inv(&2)`; `min (d / &2) (&1 / &4)`] + REAL_ARCH_POW_INV) THEN + ASM_REWRITE_TAC[REAL_HALF; REAL_POW_INV; REAL_LT_MIN] THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN + DISCH_THEN(X_CHOOSE_THEN `n:num` MP_TAC) THEN + ASM_CASES_TAC `n = 0` THEN ASM_REWRITE_TAC[] THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN STRIP_TAC THEN + DISCH_THEN(MP_TAC o SPEC `n:num`) THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `m:num` THEN + DISCH_THEN(X_CHOOSE_THEN `y:real^1` MP_TAC) THEN + REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + DISCH_THEN(SUBST1_TAC o SYM) THEN EXISTS_TAC `n:num` THEN + ASM_SIMP_TAC[] THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1]) THEN + REWRITE_TAC[DIST_REAL; GSYM drop; IN_INTERVAL_1] THEN + REPEAT(CONJ_TAC THENL [ASM_MESON_TAC[REAL_LE_TRANS]; ALL_TAC]) THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH + `a <= y /\ y <= b + ==> a <= c /\ c <= b /\ abs(a - b) < d + ==> abs(c - y) < d`)) THEN + REPEAT(CONJ_TAC THENL [ASM_MESON_TAC[REAL_LE_TRANS]; ALL_TAC]) THEN + MATCH_MP_TAC REAL_LET_TRANS THEN EXISTS_TAC `&2 / &2 pow n` THEN + ASM_SIMP_TAC[] THEN ASM_REAL_ARITH_TAC] THEN + MATCH_MP_TAC num_INDUCTION THEN REWRITE_TAC[NOT_SUC] THEN + X_GEN_TAC `n:num` THEN ASM_CASES_TAC `n = 0` THEN ASM_REWRITE_TAC[] THENL + [EXISTS_TAC `1` THEN CONV_TAC NUM_REDUCE_CONV THEN + ASM_REWRITE_TAC[REAL_POW_1] THEN + SUBGOAL_THEN + `x IN interval[vec 0:real^1,u] \/ + x IN interval[u,v] \/ + x IN interval[v,vec 1]` + STRIP_ASSUME_TAC THENL + [REWRITE_TAC[IN_INTERVAL_1] THEN + RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1]) THEN + ASM_REAL_ARITH_TAC; + EXISTS_TAC `u:real^1` THEN + ASM_MESON_TAC[ENDS_IN_INTERVAL; INTERVAL_NE_EMPTY_1]; + EXISTS_TAC `x:real^1` THEN ASM_MESON_TAC[]; + EXISTS_TAC `v:real^1` THEN + ASM_MESON_TAC[ENDS_IN_INTERVAL; INTERVAL_NE_EMPTY_1]]; + DISCH_THEN(X_CHOOSE_THEN `m:num` + (X_CHOOSE_THEN `y:real^1` MP_TAC)) THEN + REPLICATE_TAC 3 (DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + DISCH_THEN(CONJUNCTS_THEN2 MP_TAC (SUBST1_TAC o SYM)) THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [ODD_EXISTS]) THEN + DISCH_THEN(X_CHOOSE_THEN `j:num` SUBST_ALL_TAC) THEN + REWRITE_TAC[ADD1] THEN DISCH_TAC THEN + SUBGOAL_THEN + `y IN interval[a(&(2 * j + 1) / &2 pow n):real^1, + b(&(4 * j + 1) / &2 pow (n + 1))] \/ + y IN interval[b(&(4 * j + 1) / &2 pow (n + 1)), + a(&(4 * j + 3) / &2 pow (n + 1))] \/ + y IN interval[a(&(4 * j + 3) / &2 pow (n + 1)), + b(&(2 * j + 1) / &2 pow n)]` + STRIP_ASSUME_TAC THENL + [REWRITE_TAC[IN_INTERVAL_1] THEN + RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1]) THEN + ASM_REAL_ARITH_TAC; + EXISTS_TAC `4 * j + 1` THEN + EXISTS_TAC `y:real^1` THEN + REWRITE_TAC[ODD_ADD; ODD_MULT; ARITH; EXP_ADD] THEN + REPEAT(CONJ_TAC THENL [ASM_ARITH_TAC; ALL_TAC]) THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (MESON[] + `y IN interval[a,b] + ==> a = a' /\ b = b' ==> y IN interval[a',b']`)) THEN + ASM_MESON_TAC[LE_1]; + EXISTS_TAC `4 * j + 1` THEN + EXISTS_TAC `b(&(4 * j + 1) / &2 pow (n + 1)):real^1` THEN + REWRITE_TAC[ODD_ADD; ODD_MULT; ARITH; EXP_ADD] THEN + REPEAT(CONJ_TAC THENL [ASM_ARITH_TAC; ALL_TAC]) THEN + REWRITE_TAC[ENDS_IN_INTERVAL; INTERVAL_NE_EMPTY_1] THEN + CONJ_TAC THENL [ASM_MESON_TAC[REAL_LE_TRANS]; ALL_TAC] THEN + FIRST_X_ASSUM(MP_TAC o SPECL + [`a(&(2 * j + 1) / &2 pow n):real^1`; + `b(&(2 * j + 1) / &2 pow n):real^1`; + `c(&(2 * j + 1) / &2 pow n):real^1`]) THEN + ANTS_TAC THENL + [ASM_REWRITE_TAC[midpoint; IN_INTERVAL_1; SUBSET_INTERVAL_1]; + REPLICATE_TAC 4 + (DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + DISCH_THEN(CONJUNCTS_THEN2 MP_TAC STRIP_ASSUME_TAC)] THEN + MATCH_MP_TAC(MESON[] + `a IN s /\ b IN s ==> (!x. x IN s ==> f x = k) ==> f a = f b`) THEN + SUBGOAL_THEN + `leftcut (a (&(2 * j + 1) / &2 pow n)) + (b (&(2 * j + 1) / &2 pow n)) + (c (&(2 * j + 1) / &2 pow n):real^1):real^1 = + b(&(4 * j + 1) / &2 pow (n + 1)) /\ + rightcut (a (&(2 * j + 1) / &2 pow n)) + (b (&(2 * j + 1) / &2 pow n)) + (c (&(2 * j + 1) / &2 pow n)):real^1 = + a(&(4 * j + 3) / &2 pow (n + 1))` + (CONJUNCTS_THEN SUBST_ALL_TAC) THENL + [ASM_MESON_TAC[LE_1]; ALL_TAC] THEN + REWRITE_TAC[ENDS_IN_INTERVAL; INTERVAL_NE_EMPTY_1] THEN + CONJ_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (MESON[] + `y IN interval[a,b] + ==> a = a' /\ b = b' ==> y IN interval[a',b']`)) THEN + ASM_MESON_TAC[LE_1]; + EXISTS_TAC `4 * j + 3` THEN + EXISTS_TAC `y:real^1` THEN + REWRITE_TAC[ODD_ADD; ODD_MULT; ARITH; EXP_ADD] THEN + REPEAT(CONJ_TAC THENL [ASM_ARITH_TAC; ALL_TAC]) THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (MESON[] + `y IN interval[a,b] + ==> a = a' /\ b = b' ==> y IN interval[a',b']`)) THEN + ASM_MESON_TAC[LE_1]]]]; + ALL_TAC] THEN + SUBGOAL_THEN + `!n m. drop(a(&m / &2 pow n)) < drop(b(&m / &2 pow n)) /\ + (!x. drop(a(&m / &2 pow n)) < drop x /\ + drop x <= drop(b(&m / &2 pow n)) + ==> ~(f x = f(a(&m / &2 pow n)))) /\ + (!x. drop(a(&m / &2 pow n)) <= drop x /\ + drop x < drop(b(&m / &2 pow n)) + ==> ~(f x :real^N = f(b(&m / &2 pow n))))` + ASSUME_TAC THENL + [SUBGOAL_THEN `drop u < drop v` ASSUME_TAC THENL + [ASM_REWRITE_TAC[REAL_LT_LE; DROP_EQ] THEN DISCH_THEN SUBST_ALL_TAC THEN + RULE_ASSUM_TAC(REWRITE_RULE + [IN_DELETE; IN_INTERVAL_1; GSYM DROP_EQ; DROP_VEC]) THEN + ASM_MESON_TAC[DROP_EQ]; + ALL_TAC] THEN + SUBGOAL_THEN + `(!x. drop u < drop x /\ drop x <= drop v + ==> ~((f:real^1->real^N) x = f u)) /\ + (!x. drop u <= drop x /\ drop x < drop v + ==> ~(f x = f v))` + STRIP_ASSUME_TAC THENL + [SUBGOAL_THEN + `(f:real^1->real^N) u = f(vec 0) /\ + (f:real^1->real^N) v = f(vec 1)` + (CONJUNCTS_THEN SUBST1_TAC) + THENL + [CONJ_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_REWRITE_TAC[IN_INTERVAL_1; REAL_LE_REFL]; + ALL_TAC] THEN + CONJ_TAC THEN GEN_TAC THEN STRIP_TAC THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_REWRITE_TAC[IN_DELETE; IN_INTERVAL_1; GSYM DROP_EQ] THEN + ASM_REAL_ARITH_TAC; + ALL_TAC] THEN + MATCH_MP_TAC num_INDUCTION THEN + ASM_REWRITE_TAC[REAL_ARITH `&m / &2 pow 0 = (&2 * &m) / &2`] THEN + ASM_REWRITE_TAC[REAL_OF_NUM_MUL] THEN + X_GEN_TAC `n:num` THEN DISCH_THEN(LABEL_TAC "*") THEN + DISJ_CASES_TAC(ARITH_RULE `n = 0 \/ 0 < n`) THEN + ASM_REWRITE_TAC[ARITH; REAL_POW_1] THEN + X_GEN_TAC `j:num` THEN + DISJ_CASES_TAC(ISPEC `j:num` EVEN_OR_ODD) THENL + [FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [EVEN_EXISTS]) THEN + DISCH_THEN(X_CHOOSE_THEN `k:num` SUBST1_TAC) THEN + SIMP_TAC[GSYM REAL_OF_NUM_MUL; real_div; REAL_INV_MUL; real_pow] THEN + ASM_REWRITE_TAC[REAL_ARITH `(&2 * p) * inv(&2) * inv q = p / q`]; + ALL_TAC] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [ODD_EXISTS]) THEN + DISCH_THEN(X_CHOOSE_THEN `k:num` SUBST1_TAC) THEN + DISJ_CASES_TAC(ISPEC `k:num` EVEN_OR_ODD) THENL + [FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [EVEN_EXISTS]) THEN + DISCH_THEN(X_CHOOSE_THEN `m:num` SUBST1_TAC) THEN + ASM_SIMP_TAC[ARITH_RULE `2 * 2 * m = 4 * m`; ADD1] THEN + FIRST_X_ASSUM(MP_TAC o SPECL + [`a(&(2 * m + 1) / &2 pow n):real^1`; + `b(&(2 * m + 1) / &2 pow n):real^1`; + `c(&(2 * m + 1) / &2 pow n):real^1`]) THEN + ANTS_TAC THENL + [REWRITE_TAC[IN_INTERVAL_1; SUBSET_INTERVAL_1] THEN + ASM_MESON_TAC[REAL_LE_TRANS]; + REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + DISCH_THEN(K ALL_TAC)] THEN + SUBGOAL_THEN + `(f:real^1->real^N) + (leftcut (a (&(2 * m + 1) / &2 pow n):real^1) + (b (&(2 * m + 1) / &2 pow n):real^1) + (c (&(2 * m + 1) / &2 pow n):real^1)) = + (f:real^1->real^N) (c(&(2 * m + 1) / &2 pow n))` + ASSUME_TAC THENL + [FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_REWRITE_TAC[IN_INTERVAL_1; REAL_LE_REFL] THEN ASM_REAL_ARITH_TAC; + ASM_REWRITE_TAC[]] THEN + GEN_REWRITE_TAC LAND_CONV [REAL_LT_LE] THEN ASM_REWRITE_TAC[DROP_EQ] THEN + REPEAT CONJ_TAC THENL + [DISCH_THEN(SUBST_ALL_TAC o SYM) THEN + UNDISCH_THEN + `(f:real^1->real^N) (a (&(2 * m + 1) / &2 pow n)) = + f(c (&(2 * m + 1) / &2 pow n))` (MP_TAC o SYM) THEN + REWRITE_TAC[] THEN + FIRST_ASSUM(MATCH_MP_TAC o CONJUNCT1 o CONJUNCT2 o SPEC_ALL) THEN + REWRITE_TAC[GSYM(ASSUME `!x. midpoint ((a:real->real^1) x,b x) = c x`); + midpoint; DROP_CMUL; DROP_ADD] THEN + ASM_REWRITE_TAC[REAL_ARITH + `a < inv(&2) * (a + b) /\ inv(&2) * (a + b) <= b <=> a < b`]; + GEN_TAC THEN STRIP_TAC THEN + FIRST_ASSUM(MATCH_MP_TAC o CONJUNCT1 o CONJUNCT2 o SPEC_ALL) THEN + ASM_MESON_TAC[REAL_LE_TRANS]; + GEN_TAC THEN STRIP_TAC THEN FIRST_X_ASSUM + (fun th -> MATCH_MP_TAC th THEN + REWRITE_TAC[IN_INTERVAL_1; IN_DELETE; GSYM DROP_EQ] THEN + GEN_REWRITE_TAC I [REAL_ARITH + `(a <= x /\ x <= b) /\ ~(x = b) <=> a <= x /\ x < b`]) THEN + ASM_REWRITE_TAC[]]; + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [ODD_EXISTS]) THEN + DISCH_THEN(X_CHOOSE_THEN `m:num` SUBST1_TAC) THEN + ASM_SIMP_TAC[ARITH_RULE `2 * (2 * m + 1) + 1 = 4 * m + 3`; ADD1] THEN + FIRST_X_ASSUM(MP_TAC o SPECL + [`a(&(2 * m + 1) / &2 pow n):real^1`; + `b(&(2 * m + 1) / &2 pow n):real^1`; + `c(&(2 * m + 1) / &2 pow n):real^1`]) THEN + ANTS_TAC THENL + [REWRITE_TAC[IN_INTERVAL_1; SUBSET_INTERVAL_1] THEN + ASM_MESON_TAC[REAL_LE_TRANS]; + REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + DISCH_THEN(K ALL_TAC)] THEN + SUBGOAL_THEN + `(f:real^1->real^N) + (rightcut (a (&(2 * m + 1) / &2 pow n):real^1) + (b (&(2 * m + 1) / &2 pow n):real^1) + (c (&(2 * m + 1) / &2 pow n):real^1)) = + (f:real^1->real^N) (c(&(2 * m + 1) / &2 pow n))` + ASSUME_TAC THENL + [FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_REWRITE_TAC[IN_INTERVAL_1; REAL_LE_REFL] THEN ASM_REAL_ARITH_TAC; + ASM_REWRITE_TAC[]] THEN + GEN_REWRITE_TAC LAND_CONV [REAL_LT_LE] THEN ASM_REWRITE_TAC[DROP_EQ] THEN + REPEAT CONJ_TAC THENL + [DISCH_THEN SUBST_ALL_TAC THEN + UNDISCH_THEN + `(f:real^1->real^N) (b (&(2 * m + 1) / &2 pow n)) = + f(c (&(2 * m + 1) / &2 pow n))` (MP_TAC o SYM) THEN + REWRITE_TAC[] THEN + FIRST_ASSUM(MATCH_MP_TAC o CONJUNCT2 o CONJUNCT2 o SPEC_ALL) THEN + REWRITE_TAC[GSYM(ASSUME `!x. midpoint ((a:real->real^1) x,b x) = c x`); + midpoint; DROP_CMUL; DROP_ADD] THEN + ASM_REWRITE_TAC[REAL_ARITH + `a <= inv(&2) * (a + b) /\ inv(&2) * (a + b) < b <=> a < b`]; + GEN_TAC THEN STRIP_TAC THEN FIRST_X_ASSUM + (fun th -> MATCH_MP_TAC th THEN + REWRITE_TAC[IN_INTERVAL_1; IN_DELETE; GSYM DROP_EQ] THEN + GEN_REWRITE_TAC I [REAL_ARITH + `(a <= x /\ x <= b) /\ ~(x = a) <=> a < x /\ x <= b`]) THEN + ASM_REWRITE_TAC[]; + GEN_TAC THEN STRIP_TAC THEN + FIRST_ASSUM(MATCH_MP_TAC o CONJUNCT2 o CONJUNCT2 o SPEC_ALL) THEN + ASM_MESON_TAC[REAL_LE_TRANS]]]; + ALL_TAC] THEN + SUBGOAL_THEN + `!m i n j. 0 < i /\ i < 2 EXP m /\ 0 < j /\ j < 2 EXP n /\ + &i / &2 pow m < &j / &2 pow n + ==> drop(c(&i / &2 pow m)) <= drop(c(&j / &2 pow n))` + ASSUME_TAC THENL + [SUBGOAL_THEN + `!N m p i k. + 0 < i /\ i < 2 EXP m /\ 0 < k /\ k < 2 EXP p /\ + &i / &2 pow m < &k / &2 pow p /\ m + p = N + ==> ?j n. ODD(j) /\ ~(n = 0) /\ + &i / &2 pow m <= &j / &2 pow n /\ + &j / &2 pow n <= &k / &2 pow p /\ + abs(&i / &2 pow m - &j / &2 pow n) < inv(&2 pow n) /\ + abs(&k / &2 pow p - &j / &2 pow n) < inv(&2 pow n)` + MP_TAC THENL + [MATCH_MP_TAC num_WF THEN X_GEN_TAC `N:num` THEN + DISCH_THEN(LABEL_TAC "I") THEN + MAP_EVERY X_GEN_TAC [`m:num`; `p:num`; `i:num`; `k:num`] THEN + STRIP_TAC THEN + SUBGOAL_THEN + `&i / &2 pow m <= &1 / &2 pow 1 /\ + &1 / &2 pow 1 <= &k / &2 pow p \/ + &k / &2 pow p < &1 / &2 \/ + &1 / &2 < &i / &2 pow m` + (REPEAT_TCL DISJ_CASES_THEN STRIP_ASSUME_TAC) + THENL + [ASM_REAL_ARITH_TAC; + MAP_EVERY EXISTS_TAC [`1`; `1`] THEN ASM_REWRITE_TAC[ARITH] THEN + MATCH_MP_TAC(REAL_ARITH + `&0 < i /\ i <= &1 / &2 pow 1 /\ &1 / &2 pow 1 <= k /\ k < &1 + ==> abs(i - &1 / &2 pow 1) < inv(&2 pow 1) /\ + abs(k - &1 / &2 pow 1) < inv(&2 pow 1)`) THEN + ASM_SIMP_TAC[REAL_LT_RDIV_EQ; REAL_LT_LDIV_EQ; REAL_LT_POW2] THEN + REWRITE_TAC[MULT_CLAUSES; REAL_OF_NUM_POW; REAL_OF_NUM_MUL] THEN + ASM_REWRITE_TAC[REAL_OF_NUM_LT]; + REMOVE_THEN "I" MP_TAC THEN + POP_ASSUM_LIST(MP_TAC o end_itlist CONJ o rev) THEN + SPEC_TAC(`m:num`,`m:num`) THEN INDUCT_TAC THEN + REWRITE_TAC[ARITH_RULE `i < 2 EXP 0 <=> ~(0 < i)`] THEN + REWRITE_TAC[TAUT `p /\ ~p /\ q <=> F`] THEN POP_ASSUM(K ALL_TAC) THEN + SPEC_TAC(`p:num`,`p:num`) THEN INDUCT_TAC THEN + REWRITE_TAC[ARITH_RULE `i < 2 EXP 0 <=> ~(0 < i)`] THEN + REWRITE_TAC[TAUT `p /\ ~p /\ q <=> F`] THEN POP_ASSUM(K ALL_TAC) THEN + STRIP_TAC THEN DISCH_THEN(MP_TAC o SPEC `m + p:num`) THEN + ANTS_TAC THENL [EXPAND_TAC "N" THEN ARITH_TAC; ALL_TAC] THEN + DISCH_THEN(MP_TAC o SPECL [`m:num`; `p:num`; `i:num`; `k:num`]) THEN + ASM_REWRITE_TAC[] THEN ANTS_TAC THENL + [MAP_EVERY UNDISCH_TAC + [`&k / &2 pow SUC p < &1 / &2`; + `&i / &2 pow SUC m < &k / &2 pow SUC p`] THEN + REWRITE_TAC[real_div; real_pow; REAL_INV_MUL; + REAL_ARITH `x * inv(&2) * y = (x * y) * inv(&2)`] THEN + SIMP_TAC[GSYM real_div; REAL_LT_DIV2_EQ; REAL_OF_NUM_LT; ARITH] THEN + REWRITE_TAC[IMP_IMP] THEN DISCH_THEN(MP_TAC o MATCH_MP (REAL_ARITH + `x < y /\ y < &1 ==> x < &1 /\ y < &1`)) THEN + SIMP_TAC[REAL_LT_LDIV_EQ; REAL_LT_POW2; REAL_MUL_LID] THEN + REWRITE_TAC[REAL_OF_NUM_POW; REAL_OF_NUM_LT]; + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `j:num` THEN + DISCH_THEN(X_CHOOSE_THEN `n:num` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `SUC n` THEN ASM_REWRITE_TAC[NOT_SUC] THEN + REWRITE_TAC[real_div; real_pow; REAL_INV_MUL; + REAL_ARITH `inv(&2) * y = y * inv(&2)`] THEN + REWRITE_TAC[GSYM REAL_SUB_RDISTRIB; REAL_MUL_ASSOC; + REAL_ABS_MUL; REAL_ABS_INV; REAL_ABS_NUM] THEN + REWRITE_TAC[GSYM real_div; REAL_ABS_NUM] THEN + ASM_SIMP_TAC[REAL_LT_DIV2_EQ; REAL_LE_DIV2_EQ; + REAL_OF_NUM_LT; ARITH]]; + REMOVE_THEN "I" MP_TAC THEN + POP_ASSUM_LIST(MP_TAC o end_itlist CONJ o rev) THEN + SPEC_TAC(`m:num`,`m:num`) THEN INDUCT_TAC THEN + REWRITE_TAC[ARITH_RULE `i < 2 EXP 0 <=> ~(0 < i)`] THEN + REWRITE_TAC[TAUT `p /\ ~p /\ q <=> F`] THEN POP_ASSUM(K ALL_TAC) THEN + SPEC_TAC(`p:num`,`p:num`) THEN INDUCT_TAC THEN + REWRITE_TAC[ARITH_RULE `i < 2 EXP 0 <=> ~(0 < i)`] THEN + REWRITE_TAC[TAUT `p /\ ~p /\ q <=> F`] THEN POP_ASSUM(K ALL_TAC) THEN + STRIP_TAC THEN DISCH_THEN(MP_TAC o SPEC `m + p:num`) THEN + ANTS_TAC THENL [EXPAND_TAC "N" THEN ARITH_TAC; ALL_TAC] THEN + DISCH_THEN(MP_TAC o SPECL + [`m:num`; `p:num`; `i - 2 EXP m`; `k - 2 EXP p`]) THEN + ASM_REWRITE_TAC[] THEN + MAP_EVERY UNDISCH_TAC + [`&1 / &2 < &i / &2 pow SUC m`; + `&i / &2 pow SUC m < &k / &2 pow SUC p`] THEN + REWRITE_TAC[real_div; real_pow; REAL_INV_MUL; + REAL_ARITH `x * inv(&2) * y = (x * y) * inv(&2)`] THEN + SIMP_TAC[GSYM real_div; REAL_LT_DIV2_EQ; REAL_OF_NUM_LT; ARITH] THEN + GEN_REWRITE_TAC I [IMP_IMP] THEN DISCH_THEN(fun th -> + STRIP_ASSUME_TAC th THEN MP_TAC(MATCH_MP + (REAL_ARITH `i < k /\ &1 < i ==> &1 < i /\ &1 < k`) th)) THEN + SIMP_TAC[REAL_LT_RDIV_EQ; REAL_LT_POW2; REAL_MUL_LID] THEN + GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [REAL_OF_NUM_POW] THEN + SIMP_TAC[REAL_OF_NUM_LT; GSYM REAL_OF_NUM_SUB; LT_IMP_LE] THEN + STRIP_TAC THEN REWRITE_TAC[GSYM REAL_OF_NUM_POW] THEN ANTS_TAC THENL + [ASM_SIMP_TAC[ARITH_RULE `a < b ==> 0 < b - a`] THEN + ASM_SIMP_TAC[GSYM REAL_LT_RDIV_EQ; REAL_LT_POW2] THEN + REWRITE_TAC[real_div; REAL_SUB_RDISTRIB] THEN + ASM_SIMP_TAC[REAL_MUL_RINV; REAL_LT_IMP_NZ; REAL_LT_POW2] THEN + ASM_REWRITE_TAC[REAL_ARITH `u * inv v - &1 < w * inv z - &1 <=> + u / v < w / z`] THEN + CONJ_TAC THEN MATCH_MP_TAC(ARITH_RULE + `i < 2 * m ==> i - m < m`) THEN + ASM_REWRITE_TAC[GSYM(CONJUNCT2 EXP)]; + REWRITE_TAC[real_div; REAL_SUB_RDISTRIB] THEN + ASM_SIMP_TAC[REAL_MUL_RINV; REAL_LT_IMP_NZ; REAL_LT_POW2] THEN + REWRITE_TAC[GSYM real_div] THEN + DISCH_THEN(X_CHOOSE_THEN `j:num` (X_CHOOSE_THEN `n:num` + STRIP_ASSUME_TAC)) THEN + EXISTS_TAC `2 EXP n + j` THEN EXISTS_TAC `SUC n` THEN + ASM_REWRITE_TAC[NOT_SUC; ODD_ADD; ODD_EXP; ARITH] THEN + REWRITE_TAC[GSYM REAL_OF_NUM_ADD; GSYM REAL_OF_NUM_POW] THEN + REWRITE_TAC[real_div; real_pow; REAL_INV_MUL; + REAL_ARITH `inv(&2) * y = y * inv(&2)`] THEN + REWRITE_TAC[GSYM REAL_SUB_RDISTRIB; REAL_MUL_ASSOC; + REAL_ABS_MUL; REAL_ABS_INV; REAL_ABS_NUM] THEN + REWRITE_TAC[GSYM real_div; REAL_ABS_NUM] THEN + ASM_SIMP_TAC[REAL_LT_DIV2_EQ; REAL_LE_DIV2_EQ; + REAL_OF_NUM_LT; ARITH] THEN + REWRITE_TAC[real_div; REAL_ADD_RDISTRIB] THEN + ASM_SIMP_TAC[REAL_MUL_RINV; REAL_LT_IMP_NZ; REAL_LT_POW2] THEN + REWRITE_TAC[GSYM real_div] THEN ASM_REAL_ARITH_TAC]]; + DISCH_THEN(fun th -> + MAP_EVERY X_GEN_TAC [`m:num`; `i:num`; `p:num`; `k:num`] THEN + STRIP_TAC THEN MP_TAC(ISPECL + [`m + p:num`; `m:num`; `p:num`; `i:num`; `k:num`] th)) THEN + ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`j:num`; `n:num`] THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [ODD_EXISTS]) THEN + REWRITE_TAC[ADD1; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `q:num` THEN DISCH_THEN SUBST_ALL_TAC THEN + MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `drop(c(&(2 * q + 1) / &2 pow n))` THEN CONJ_TAC THENL + [ASM_CASES_TAC `&i / &2 pow m = &(2 * q + 1) / &2 pow n` THEN + ASM_REWRITE_TAC[REAL_LE_REFL] THEN + SUBGOAL_THEN + `drop(a(&(4 * q + 1) / &2 pow (n + 1))) <= drop(c(&i / &2 pow m)) /\ + drop(c(&i / &2 pow m)) <= drop(b(&(4 * q + 1) / &2 pow (n + 1)))` + MP_TAC THENL + [FIRST_X_ASSUM MATCH_MP_TAC THEN + REWRITE_TAC[ODD_ADD; ODD_MULT; ARITH] THEN + SIMP_TAC[real_div; REAL_POW_ADD; REAL_INV_MUL; REAL_MUL_ASSOC] THEN + REWRITE_TAC[GSYM real_div; REAL_POW_1] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH + `abs(i - q) < n + ==> i <= q /\ ~(i = q) /\ q = q' + n / &2 + ==> abs(i - q') < n / &2`)) THEN + ASM_REWRITE_TAC[] THEN + REWRITE_TAC[GSYM REAL_OF_NUM_ADD; GSYM REAL_OF_NUM_MUL] THEN + REAL_ARITH_TAC; + ASM_SIMP_TAC[LE_1] THEN MATCH_MP_TAC(REAL_ARITH + `l <= d ==> u <= v /\ c <= l ==> c <= d`) THEN + FIRST_X_ASSUM(MP_TAC o SPECL + [`a(&(2 * q + 1) / &2 pow n):real^1`; + `b(&(2 * q + 1) / &2 pow n):real^1`; + `c(&(2 * q + 1) / &2 pow n):real^1`]) THEN + ANTS_TAC THENL + [REWRITE_TAC[IN_INTERVAL_1; SUBSET_INTERVAL_1] THEN + ASM_MESON_TAC[REAL_LE_TRANS]; + DISCH_THEN(fun th -> REWRITE_TAC[th])]]; + ASM_CASES_TAC `&k / &2 pow p = &(2 * q + 1) / &2 pow n` THEN + ASM_REWRITE_TAC[REAL_LE_REFL] THEN + SUBGOAL_THEN + `drop(a(&(4 * q + 3) / &2 pow (n + 1))) <= drop(c(&k / &2 pow p)) /\ + drop(c(&k / &2 pow p)) <= drop(b(&(4 * q + 3) / &2 pow (n + 1)))` + MP_TAC THENL + [FIRST_X_ASSUM MATCH_MP_TAC THEN + REWRITE_TAC[ODD_ADD; ODD_MULT; ARITH] THEN + SIMP_TAC[real_div; REAL_POW_ADD; REAL_INV_MUL; REAL_MUL_ASSOC] THEN + REWRITE_TAC[GSYM real_div; REAL_POW_1] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH + `abs(i - q) < n + ==> q <= i /\ ~(i = q) /\ q' = q + n / &2 + ==> abs(i - q') < n / &2`)) THEN + ASM_REWRITE_TAC[] THEN + REWRITE_TAC[GSYM REAL_OF_NUM_ADD; GSYM REAL_OF_NUM_MUL] THEN + REAL_ARITH_TAC; + ASM_SIMP_TAC[LE_1] THEN MATCH_MP_TAC(REAL_ARITH + `d <= l ==> l <= c /\ u <= v ==> d <= c`) THEN + FIRST_X_ASSUM(MP_TAC o SPECL + [`a(&(2 * q + 1) / &2 pow n):real^1`; + `b(&(2 * q + 1) / &2 pow n):real^1`; + `c(&(2 * q + 1) / &2 pow n):real^1`]) THEN + ANTS_TAC THENL + [REWRITE_TAC[IN_INTERVAL_1; SUBSET_INTERVAL_1] THEN + ASM_MESON_TAC[REAL_LE_TRANS]; + DISCH_THEN(fun th -> REWRITE_TAC[th])]]]]; + ALL_TAC] THEN + REWRITE_TAC[FORALL_LIFT] THEN MATCH_MP_TAC REAL_WLOG_LT THEN + REWRITE_TAC[] THEN CONJ_TAC THENL [MESON_TAC[]; ALL_TAC] THEN + REWRITE_TAC[FORALL_DROP; LIFT_DROP; IN_INTERVAL_1; DROP_VEC] THEN + MAP_EVERY X_GEN_TAC [`x1:real^1`; `x2:real^1`] THEN REPEAT STRIP_TAC THEN + SUBGOAL_THEN + `?m n. 0 < m /\ m < 2 EXP n /\ + drop x1 < &m / &2 pow n /\ &m / &2 pow n < drop x2 /\ + ~(h(x1):real^N = h(lift(&m / &2 pow n)))` + STRIP_ASSUME_TAC THENL + [MP_TAC(ISPEC `interval(vec 0:real^1,vec 1)` + closure_dyadic_rationals_in_convex_set_pos_1) THEN + SIMP_TAC[CONVEX_INTERVAL; IN_INTERVAL_1; REAL_LT_IMP_LE; DROP_VEC; + INTERIOR_OPEN; OPEN_INTERVAL; INTERVAL_NE_EMPTY_1; REAL_LT_01; + CLOSURE_OPEN_INTERVAL] THEN + REWRITE_TAC[EXTENSION] THEN + DISCH_THEN(MP_TAC o SPEC `inv(&2) % (x1 + x2):real^1`) THEN + REWRITE_TAC[dyadics_in_open_unit_interval; IN_INTERVAL_1; DROP_VEC] THEN + REWRITE_TAC[DROP_CMUL; DROP_ADD] THEN + MATCH_MP_TAC(TAUT `p /\ (q ==> r) ==> (q <=> p) ==> r`) THEN + CONJ_TAC THENL [ASM_REAL_ARITH_TAC; REWRITE_TAC[CLOSURE_APPROACHABLE]] THEN + DISCH_THEN(MP_TAC o SPEC `(drop x2 - drop x1) / &64`) THEN + ANTS_TAC THENL [ASM_REAL_ARITH_TAC; REWRITE_TAC[EXISTS_IN_GSPEC]] THEN + REWRITE_TAC[DIST_REAL; GSYM drop; LIFT_DROP; DROP_CMUL; DROP_ADD] THEN + DISCH_TAC THEN + SUBGOAL_THEN + `?m n. (0 < m /\ m < 2 EXP n) /\ + abs(&m / &2 pow n - inv (&2) * (drop x1 + drop x2)) < + (drop x2 - drop x1) / &64 /\ + inv(&2 pow n) < (drop x2 - drop x1) / &128` + STRIP_ASSUME_TAC THENL + [MP_TAC(ISPECL [`inv(&2)`; `min (&1 / &4) ((drop x2 - drop x1) / &128)`] + REAL_ARCH_POW_INV) THEN ANTS_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN + DISCH_THEN(X_CHOOSE_THEN `N:num` MP_TAC) THEN + ASM_CASES_TAC `N = 0` THENL + [ASM_REWRITE_TAC[] THEN REAL_ARITH_TAC; ALL_TAC] THEN + REWRITE_TAC[REAL_INV_POW; REAL_LT_MIN; EXISTS_IN_GSPEC] THEN + STRIP_TAC THEN + FIRST_X_ASSUM(X_CHOOSE_THEN `m:num` (X_CHOOSE_THEN `n:num` + STRIP_ASSUME_TAC)) THEN + EXISTS_TAC `2 EXP N * m` THEN EXISTS_TAC `N + n:num` THEN + ASM_SIMP_TAC[EXP_ADD; LT_MULT; EXP_LT_0; LT_MULT_LCANCEL; LE_1; + ARITH_EQ] THEN + CONJ_TAC THENL + [REWRITE_TAC[REAL_POW_ADD; real_div; REAL_INV_MUL] THEN + REWRITE_TAC[GSYM REAL_OF_NUM_MUL; GSYM REAL_OF_NUM_POW; REAL_ARITH + `(N * n) * inv N * inv m:real = (N / N) * (n / m)`] THEN + ASM_SIMP_TAC[REAL_DIV_REFL; REAL_POW_EQ_0; REAL_OF_NUM_EQ; ARITH_EQ; + REAL_MUL_LID; GSYM real_div]; + MATCH_MP_TAC REAL_LET_TRANS THEN EXISTS_TAC `inv(&2) pow N` THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC REAL_POW_MONO_INV THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN REWRITE_TAC[LE_ADD]]; + REWRITE_TAC[CONJ_ASSOC] THEN MATCH_MP_TAC(MESON[] + `!m n m' n'. (P m n /\ P m' n') /\ + (P m n /\ P m' n' ==> ~(g m n = g m' n')) + ==> (?m n. P m n /\ ~(a = g m n))`) THEN + MAP_EVERY EXISTS_TAC + [`2 * m + 1`; `n + 1`; `4 * m + 3`; `n + 2`] THEN + CONJ_TAC THENL + [REWRITE_TAC[EXP_ADD] THEN CONV_TAC NUM_REDUCE_CONV THEN CONJ_TAC THEN + (REWRITE_TAC[GSYM CONJ_ASSOC] THEN + REPLICATE_TAC 2 (CONJ_TAC THENL [ASM_ARITH_TAC; ALL_TAC])) THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH + `abs(x - inv(&2) * (x1 + x2)) < (x2 - x1) / &64 + ==> abs(x - y) < (x2 - x1) / &4 + ==> x1 < y /\ y < x2`)) THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH + `n < x / &128 ==> &0 < x /\ y < &4 * n ==> y < x / &4`)) THEN + ASM_REWRITE_TAC[REAL_SUB_LT] THEN + REWRITE_TAC[GSYM REAL_OF_NUM_ADD; GSYM REAL_OF_NUM_MUL] THEN + MATCH_MP_TAC(REAL_ARITH + `a / y = x /\ abs(b / y) < z + ==> abs(x - (a + b) / y) < z`) THEN + ONCE_REWRITE_TAC[ADD_SYM] THEN REWRITE_TAC[REAL_POW_ADD] THEN + SIMP_TAC[REAL_ABS_DIV; REAL_ABS_NUM; REAL_ABS_MUL; REAL_ABS_POW] THEN + REWRITE_TAC[real_div; REAL_INV_MUL; REAL_MUL_ASSOC] THEN + SIMP_TAC[REAL_LT_RMUL_EQ; REAL_EQ_MUL_RCANCEL; REAL_LT_INV_EQ; + REAL_LT_POW2; REAL_INV_EQ_0; REAL_POW_EQ_0; ARITH_EQ; + REAL_OF_NUM_EQ] THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN REAL_ARITH_TAC; + ASM_SIMP_TAC[] THEN DISCH_THEN(K ALL_TAC) THEN + FIRST_X_ASSUM(MP_TAC o CONJUNCT1 o SPECL [`n + 2`; `4 * m + 3`]) THEN + UNDISCH_THEN `!x. midpoint ((a:real->real^1) x,b x) = c x` + (fun th -> REWRITE_TAC[GSYM th] THEN + ASM_SIMP_TAC[ARITH_RULE `n + 2 = (n + 1) + 1 /\ 0 < n + 1`] THEN + REWRITE_TAC[th] THEN ASSUME_TAC th) THEN + DISCH_TAC THEN + CONV_TAC(RAND_CONV SYM_CONV) THEN + FIRST_X_ASSUM(MP_TAC o SPECL + [`a(&(2 * m + 1) / &2 pow (n + 1)):real^1`; + `b(&(2 * m + 1) / &2 pow (n + 1)):real^1`; + `c(&(2 * m + 1) / &2 pow (n + 1)):real^1`]) THEN + ANTS_TAC THENL + [REWRITE_TAC[IN_INTERVAL_1; SUBSET_INTERVAL_1] THEN + ASM_MESON_TAC[REAL_LE_TRANS]; + REPLICATE_TAC 6 (DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + DISCH_THEN(MATCH_MP_TAC o CONJUNCT1)] THEN + REWRITE_TAC[IN_INTERVAL_1; IN_DELETE; GSYM DROP_EQ] THEN + REWRITE_TAC[REAL_ARITH + `(a <= b /\ b <= c) /\ ~(b = a) <=> a < b /\ b <= c`] THEN + REWRITE_TAC[midpoint; DROP_CMUL; DROP_ADD] THEN + ASM_REWRITE_TAC[REAL_ARITH + `a < inv(&2) * (a + b) /\ inv(&2) * (a + b) <= b <=> a < b`] THEN + ASM_REWRITE_TAC[REAL_LT_LE]]]; + ALL_TAC] THEN + SUBGOAL_THEN + `IMAGE h (interval[vec 0,lift(&m / &2 pow n)]) SUBSET + IMAGE (f:real^1->real^N) (interval[vec 0,c(&m / &2 pow n)]) /\ + IMAGE h (interval[lift(&m / &2 pow n),vec 1]) SUBSET + IMAGE (f:real^1->real^N) (interval[c(&m / &2 pow n),vec 1])` + MP_TAC THENL + [MP_TAC(ISPEC `interval(lift(&m / &2 pow n),vec 1)` + closure_dyadic_rationals_in_convex_set_pos_1) THEN + MP_TAC(ISPEC `interval(vec 0,lift(&m / &2 pow n))` + closure_dyadic_rationals_in_convex_set_pos_1) THEN + SUBGOAL_THEN `&0 < &m / &2 pow n /\ &m / &2 pow n < &1` + STRIP_ASSUME_TAC THENL + [ASM_SIMP_TAC[REAL_LT_DIV; REAL_LT_POW2; REAL_OF_NUM_LT; REAL_LT_LDIV_EQ; + REAL_OF_NUM_MUL; REAL_OF_NUM_LT; REAL_OF_NUM_POW; MULT_CLAUSES]; + ALL_TAC] THEN + MATCH_MP_TAC(TAUT + `(p1 /\ p2) /\ (q1 ==> r1) /\ (q2 ==> r2) + ==> (p1 ==> q1) ==> (p2 ==> q2) ==> r1 /\ r2`) THEN + ASM_SIMP_TAC[CONVEX_INTERVAL; IN_INTERVAL_1; REAL_LT_IMP_LE; DROP_VEC; + INTERIOR_OPEN; OPEN_INTERVAL; INTERVAL_NE_EMPTY_1; REAL_LT_01; + CLOSURE_OPEN_INTERVAL; LIFT_DROP] THEN + CONJ_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN + CONJ_TAC THEN DISCH_THEN(SUBST1_TAC o SYM) THEN + (MATCH_MP_TAC IMAGE_CLOSURE_SUBSET THEN REPEAT CONJ_TAC THENL + [FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET)) THEN + MATCH_MP_TAC CLOSURE_MINIMAL THEN REWRITE_TAC[CLOSED_INTERVAL] THEN + MATCH_MP_TAC(SET_RULE `s SUBSET u ==> s INTER t SUBSET u`) THEN + ASM_SIMP_TAC[SUBSET_INTERVAL_1; LIFT_DROP; REAL_LT_IMP_LE; DROP_VEC; + REAL_LE_REFL]; + MATCH_MP_TAC COMPACT_IMP_CLOSED THEN + MATCH_MP_TAC COMPACT_CONTINUOUS_IMAGE THEN + ASM_REWRITE_TAC[COMPACT_INTERVAL] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET)) THEN + REWRITE_TAC[SUBSET_INTERVAL_1; REAL_LE_REFL] THEN + ASM_MESON_TAC[REAL_LE_TRANS]; + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE] THEN + MATCH_MP_TAC(SET_RULE + `i SUBSET interval(vec 0,vec 1) /\ + (!x. x IN interval(vec 0,vec 1) INTER l ==> x IN i ==> P x) + ==> !x. x IN i INTER l ==> P x`) THEN + ASM_SIMP_TAC[SUBSET_INTERVAL_1; LIFT_DROP; DROP_VEC; + REAL_LT_IMP_LE; REAL_LE_REFL] THEN + REWRITE_TAC[dyadics_in_open_unit_interval; FORALL_IN_GSPEC] THEN + MAP_EVERY X_GEN_TAC [`k:num`; `p:num`] THEN STRIP_TAC THEN + REWRITE_TAC[IN_INTERVAL_1; DROP_VEC; LIFT_DROP] THEN + STRIP_TAC THEN ASM_SIMP_TAC[] THEN + MATCH_MP_TAC FUN_IN_IMAGE THEN REWRITE_TAC[IN_INTERVAL_1] THEN + ASM_SIMP_TAC[] THEN ASM_MESON_TAC[REAL_LE_TRANS]]); + DISCH_THEN(MP_TAC o MATCH_MP (SET_RULE + `IMAGE h s SUBSET t /\ IMAGE h s' SUBSET t' + ==> !x y. x IN s /\ y IN s' ==> h(x) IN t /\ h(y) IN t'`)) THEN + DISCH_THEN(MP_TAC o SPECL [`x1:real^1`; `x2:real^1`]) THEN + ASM_SIMP_TAC[IN_INTERVAL_1; LIFT_DROP; DROP_VEC; REAL_LT_IMP_LE] THEN + DISCH_THEN(MP_TAC o MATCH_MP (SET_RULE + `a IN IMAGE f s /\ a IN IMAGE f t + ==> ?x y. x IN s /\ y IN t /\ f x = a /\ f y = a`)) THEN + REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`t1:real^1`; `t2:real^1`] THEN + REWRITE_TAC[IN_INTERVAL_1; DROP_VEC] THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `(h:real^1->real^N) x2` o + GEN_REWRITE_RULE BINDER_CONV [GSYM IS_INTERVAL_CONNECTED_1]) THEN + REWRITE_TAC[IS_INTERVAL_1; IN_ELIM_THM] THEN + DISCH_THEN(MP_TAC o SPECL + [`t1:real^1`; `t2:real^1`; `c(&m / &2 pow n):real^1`]) THEN + UNDISCH_TAC `~(h x1:real^N = h(lift (&m / &2 pow n)))` THEN + ASM_SIMP_TAC[] THEN MATCH_MP_TAC(TAUT `q ==> p ==> ~q ==> r`) THEN + ASM_REWRITE_TAC[IN_INTERVAL_1; DROP_VEC] THEN + ASM_MESON_TAC[REAL_LE_TRANS]]);; + +let PATH_CONTAINS_ARC = prove + (`!p:real^1->real^N a b. + path p /\ pathstart p = a /\ pathfinish p = b /\ ~(a = b) + ==> ?q. arc q /\ path_image q SUBSET path_image p /\ + pathstart q = a /\ pathfinish q = b`, + REWRITE_TAC[pathstart; pathfinish; path] THEN + MAP_EVERY X_GEN_TAC [`f:real^1->real^N`; `a:real^N`; `b:real^N`] THEN + STRIP_TAC THEN MP_TAC(ISPECL + [`\s. s SUBSET interval[vec 0,vec 1] /\ + vec 0 IN s /\ vec 1 IN s /\ + (!x y. x IN s /\ y IN s /\ segment(x,y) INTER s = {} + ==> (f:real^1->real^N)(x) = f(y))`; + `interval[vec 0:real^1,vec 1]`] + BROUWER_REDUCTION_THEOREM_GEN) THEN + ASM_REWRITE_TAC[GSYM path_image; CLOSED_INTERVAL; SUBSET_REFL] THEN + ANTS_TAC THENL + [CONJ_TAC THENL + [ALL_TAC; + REWRITE_TAC[ENDS_IN_UNIT_INTERVAL] THEN + REPEAT GEN_TAC THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o MATCH_MP (SET_RULE + `s INTER i = {} ==> s SUBSET i ==> s = {}`)) THEN + REWRITE_TAC[SEGMENT_EQ_EMPTY] THEN + ANTS_TAC THENL [ONCE_REWRITE_TAC[segment]; MESON_TAC[]] THEN + MATCH_MP_TAC(SET_RULE `s SUBSET t ==> s DIFF i SUBSET t`) THEN + ASM_MESON_TAC[CONVEX_CONTAINS_SEGMENT; CONVEX_INTERVAL]] THEN + X_GEN_TAC `s:num->real^1->bool` THEN + REWRITE_TAC[FORALL_AND_THM] THEN STRIP_TAC THEN CONJ_TAC THENL + [REWRITE_TAC[INTERS_GSPEC; SUBSET; IN_ELIM_THM; IN_UNIV] THEN + ASM SET_TAC[]; + ALL_TAC] THEN + REPEAT(CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC]) THEN + REWRITE_TAC[FORALL_LIFT] THEN MATCH_MP_TAC REAL_WLOG_LT THEN + REWRITE_TAC[] THEN CONJ_TAC THENL + [REWRITE_TAC[SEGMENT_SYM] THEN MESON_TAC[]; + REWRITE_TAC[FORALL_DROP; LIFT_DROP]] THEN + MAP_EVERY X_GEN_TAC [`x:real^1`; `y:real^1`] THEN + REWRITE_TAC[INTERS_GSPEC; IN_UNIV; IN_ELIM_THM] THEN + SIMP_TAC[SEGMENT_1; REAL_LT_IMP_LE] THEN DISCH_TAC THEN STRIP_TAC THEN + MATCH_MP_TAC(TAUT `(~p ==> F) ==> p`) THEN DISCH_TAC THEN + FIRST_X_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 `norm((f:real^1->real^N) x - f y) / &2`) THEN + ASM_REWRITE_TAC[REAL_HALF; NORM_POS_LT; VECTOR_SUB_EQ] THEN + DISCH_THEN(X_CHOOSE_THEN `e:real` STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN + `?u v. u IN interval[vec 0,vec 1] /\ v IN interval[vec 0,vec 1] /\ + norm(u - x) < e /\ norm(v - y) < e /\ (f:real^1->real^N) u = f v` + STRIP_ASSUME_TAC THENL + [ALL_TAC; + FIRST_X_ASSUM(fun th -> + MP_TAC(ISPECL [`x:real^1`; `u:real^1`] th) THEN + MP_TAC(ISPECL [`y:real^1`; `v:real^1`] th)) THEN + ASM_REWRITE_TAC[dist] THEN + ANTS_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + MATCH_MP_TAC(TAUT `q /\ (p ==> ~r) ==> p ==> ~(q ==> r)`) THEN + CONJ_TAC THENL [ASM SET_TAC[]; CONV_TAC NORM_ARITH]] THEN + SUBGOAL_THEN + `?w z. w IN interval(x,y) /\ z IN interval(x,y) /\ drop w < drop z /\ + norm(w - x) < e /\ norm(z - y) < e` + STRIP_ASSUME_TAC THENL + [EXISTS_TAC `x + lift(min e (drop y - drop x) / &3)` THEN + EXISTS_TAC `y - lift(min e (drop y - drop x) / &3)` THEN + REWRITE_TAC[IN_INTERVAL_1; DROP_ADD; DROP_SUB; LIFT_DROP; + NORM_REAL; GSYM drop] THEN + ASM_REAL_ARITH_TAC; + ALL_TAC] THEN + MP_TAC(ISPECL [`interval[w:real^1,z]`; + `{s n :real^1->bool | n IN (:num)}`] COMPACT_IMP_FIP) THEN + ASM_REWRITE_TAC[COMPACT_INTERVAL; FORALL_IN_GSPEC] THEN + MATCH_MP_TAC(TAUT `q /\ (~p ==> r) ==> (p ==> ~q) ==> r`) THEN + CONJ_TAC THENL + [REWRITE_TAC[INTERS_GSPEC; IN_UNIV] THEN FIRST_X_ASSUM(MATCH_MP_TAC o + MATCH_MP (SET_RULE + `s INTER u = {} ==> t SUBSET s ==> t INTER u = {}`)) THEN + REWRITE_TAC[SUBSET_INTERVAL_1] THEN + RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1]) THEN + ASM_REAL_ARITH_TAC; + ALL_TAC] THEN + REWRITE_TAC[MESON[] `~(!x. P x /\ Q x ==> R x) <=> + (?x. P x /\ Q x /\ ~R x)`] THEN + ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN + REWRITE_TAC[EXISTS_FINITE_SUBSET_IMAGE] THEN + DISCH_THEN(X_CHOOSE_THEN `k:num->bool` STRIP_ASSUME_TAC) THEN + FIRST_X_ASSUM(MP_TAC o SPEC `\n:num. n` o MATCH_MP + UPPER_BOUND_FINITE_SET) THEN REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `n:num` THEN DISCH_TAC THEN + SUBGOAL_THEN + `interval[w,z] INTER (s:num->real^1->bool) n = {}` + ASSUME_TAC THENL + [FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE + `a INTER t = {} ==> s SUBSET t ==> a INTER s = {}`)) THEN + REWRITE_TAC[SUBSET; INTERS_IMAGE; IN_ELIM_THM] THEN + REWRITE_TAC[SET_RULE + `(!x. x IN s n ==> !i. i IN k ==> x IN s i) <=> + (!i. i IN k ==> s n SUBSET s i)`] THEN + SUBGOAL_THEN + `!i n. i <= n ==> (s:num->real^1->bool) n SUBSET s i` + (fun th -> ASM_MESON_TAC[th]) THEN + MATCH_MP_TAC TRANSITIVE_STEPWISE_LE THEN ASM_REWRITE_TAC[] THEN + SET_TAC[]; + ALL_TAC] THEN + SUBGOAL_THEN + `?u. u IN (s:num->real^1->bool) n /\ u IN interval[x,w] /\ + (interval[u,w] DELETE u) INTER (s n) = {}` + MP_TAC THENL + [ASM_CASES_TAC `w IN (s:num->real^1->bool) n` THENL + [EXISTS_TAC `w:real^1` THEN ASM_REWRITE_TAC[ENDS_IN_INTERVAL] THEN + REWRITE_TAC[INTERVAL_SING; SET_RULE `{a} DELETE a = {}`] THEN + REWRITE_TAC[INTER_EMPTY; INTERVAL_NE_EMPTY_1] THEN + RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1]) THEN ASM_REAL_ARITH_TAC; + ALL_TAC] THEN + MP_TAC(ISPECL [`(s:num->real^1->bool) n INTER interval[x,w]`; + `w:real^1`] SEGMENT_TO_POINT_EXISTS) THEN + ASM_SIMP_TAC[CLOSED_INTER; CLOSED_INTERVAL] THEN ANTS_TAC THENL + [REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN EXISTS_TAC `x:real^1` THEN + ASM_REWRITE_TAC[IN_INTER; IN_INTERVAL_1] THEN + RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1]) THEN ASM_REAL_ARITH_TAC; + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `u:real^1` THEN + REWRITE_TAC[IN_INTER] THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + FIRST_X_ASSUM(MP_TAC o MATCH_MP (SET_RULE + `s INTER t INTER u = {} ==> s SUBSET u ==> s INTER t = {}`)) THEN + REWRITE_TAC[SEGMENT_1] THEN COND_CASES_TAC THENL + [RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1]) THEN + ASM_MESON_TAC[DROP_EQ; REAL_LE_ANTISYM]; + ANTS_TAC THENL + [REWRITE_TAC[SUBSET_INTERVAL_1] THEN + RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1]) THEN + ASM_REAL_ARITH_TAC; + REWRITE_TAC[OPEN_CLOSED_INTERVAL_1] THEN ASM SET_TAC[]]]]; + ALL_TAC] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `u:real^1` THEN STRIP_TAC THEN + SUBGOAL_THEN + `?v. v IN (s:num->real^1->bool) n /\ v IN interval[z,y] /\ + (interval[z,v] DELETE v) INTER (s n) = {}` + MP_TAC THENL + [ASM_CASES_TAC `z IN (s:num->real^1->bool) n` THENL + [EXISTS_TAC `z:real^1` THEN ASM_REWRITE_TAC[ENDS_IN_INTERVAL] THEN + REWRITE_TAC[INTERVAL_SING; SET_RULE `{a} DELETE a = {}`] THEN + REWRITE_TAC[INTER_EMPTY; INTERVAL_NE_EMPTY_1] THEN + RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1]) THEN ASM_REAL_ARITH_TAC; + ALL_TAC] THEN + MP_TAC(ISPECL [`(s:num->real^1->bool) n INTER interval[z,y]`; + `z:real^1`] SEGMENT_TO_POINT_EXISTS) THEN + ASM_SIMP_TAC[CLOSED_INTER; CLOSED_INTERVAL] THEN ANTS_TAC THENL + [REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN EXISTS_TAC `y:real^1` THEN + ASM_REWRITE_TAC[IN_INTER; IN_INTERVAL_1] THEN + RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1]) THEN ASM_REAL_ARITH_TAC; + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `v:real^1` THEN + REWRITE_TAC[IN_INTER] THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + FIRST_X_ASSUM(MP_TAC o MATCH_MP (SET_RULE + `s INTER t INTER u = {} ==> s SUBSET u ==> s INTER t = {}`)) THEN + REWRITE_TAC[SEGMENT_1] THEN COND_CASES_TAC THENL + [ANTS_TAC THENL + [REWRITE_TAC[SUBSET_INTERVAL_1] THEN + RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1]) THEN + ASM_REAL_ARITH_TAC; + REWRITE_TAC[OPEN_CLOSED_INTERVAL_1] THEN ASM SET_TAC[]]; + RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1]) THEN + ASM_MESON_TAC[DROP_EQ; REAL_LE_ANTISYM]]]; + ALL_TAC] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `v:real^1` THEN STRIP_TAC THEN + REPEAT CONJ_TAC THENL + [ASM SET_TAC[]; + ASM SET_TAC[]; + RULE_ASSUM_TAC(REWRITE_RULE[NORM_REAL; GSYM drop; DROP_SUB]) THEN + REWRITE_TAC[NORM_REAL; GSYM drop; DROP_SUB] THEN + RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1]) THEN ASM_REAL_ARITH_TAC; + RULE_ASSUM_TAC(REWRITE_RULE[NORM_REAL; GSYM drop; DROP_SUB]) THEN + REWRITE_TAC[NORM_REAL; GSYM drop; DROP_SUB] THEN + RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1]) THEN ASM_REAL_ARITH_TAC; + FIRST_X_ASSUM MATCH_MP_TAC THEN EXISTS_TAC `n:num` THEN + ASM_REWRITE_TAC[SEGMENT_1] THEN COND_CASES_TAC THENL + [MAP_EVERY UNDISCH_TAC + [`interval[w,z] INTER (s:num->real^1->bool) n = {}`; + `interval[u,w] DELETE u INTER (s:num->real^1->bool) n = {}`; + `interval[z,v] DELETE v INTER (s:num->real^1->bool) n = {}`] THEN + REWRITE_TAC[IMP_IMP; SET_RULE + `s1 INTER t = {} /\ s2 INTER t = {} <=> + (s1 UNION s2) INTER t = {}`] THEN + MATCH_MP_TAC(SET_RULE + `t SUBSET s ==> s INTER u = {} ==> t INTER u = {}`) THEN + REWRITE_TAC[SUBSET; IN_UNION; IN_DELETE; + GSYM DROP_EQ; IN_INTERVAL_1] THEN + ASM_REAL_ARITH_TAC; + RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1]) THEN ASM_REAL_ARITH_TAC]]; + ALL_TAC] THEN + DISCH_THEN(X_CHOOSE_THEN `t:real^1->bool` STRIP_ASSUME_TAC) THEN + ASM_CASES_TAC `t:real^1->bool = {}` THENL + [ASM_MESON_TAC[IN_IMAGE; NOT_IN_EMPTY]; ALL_TAC] THEN + ABBREV_TAC + `h = \x. (f:real^1->real^N)(@y. y IN t /\ segment(x,y) INTER t = {})` THEN + SUBGOAL_THEN + `!x y. y IN t /\ segment(x,y) INTER t = {} ==> h(x) = (f:real^1->real^N)(y)` + ASSUME_TAC THENL + [SUBGOAL_THEN + `!x y z. y IN t /\ segment(x,y) INTER t = {} /\ + z IN t /\ segment(x,z) INTER t = {} + ==> (f:real^1->real^N)(y) = f(z)` + ASSUME_TAC THENL + [REPEAT GEN_TAC THEN ASM_CASES_TAC `(x:real^1) IN t` THENL + [ASM_MESON_TAC[]; UNDISCH_TAC `~((x:real^1) IN t)`] THEN + ONCE_REWRITE_TAC[TAUT `p ==> a /\ b /\ c /\ d ==> q <=> + (a /\ c) ==> p /\ b /\ d ==> q`] THEN + STRIP_TAC THEN + REWRITE_TAC[SET_RULE `~(x IN t) /\ s INTER t = {} /\ s' INTER t = {} <=> + (x INSERT (s UNION s')) INTER t = {}`] THEN + DISCH_THEN(fun th -> FIRST_X_ASSUM MATCH_MP_TAC THEN MP_TAC th) THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC(SET_RULE + `s SUBSET s' ==> s' INTER t = {} ==> s INTER t = {}`) THEN + REWRITE_TAC[SEGMENT_1; SUBSET; IN_UNION; IN_INSERT; IN_INTERVAL_1] THEN + GEN_TAC THEN REWRITE_TAC[GSYM DROP_EQ] THEN + REPEAT(COND_CASES_TAC THEN ASM_REWRITE_TAC[IN_INTERVAL_1]) THEN + ASM_REAL_ARITH_TAC; + REPEAT STRIP_TAC THEN EXPAND_TAC "h" THEN ASM_MESON_TAC[]]; + ALL_TAC] THEN + SUBGOAL_THEN `!x. x IN t ==> h(x) = (f:real^1->real^N)(x)` ASSUME_TAC THENL + [REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_REWRITE_TAC[SEGMENT_REFL; INTER_EMPTY]; + ALL_TAC] THEN + SUBGOAL_THEN `!x:real^1. ?y. y IN t /\ segment(x,y) INTER t = {}` + ASSUME_TAC THENL + [X_GEN_TAC `x:real^1` THEN + EXISTS_TAC `closest_point t (x:real^1)` THEN + ASM_SIMP_TAC[SEGMENT_TO_CLOSEST_POINT; CLOSEST_POINT_EXISTS]; + ALL_TAC] THEN + SUBGOAL_THEN + `!x y. segment(x,y) INTER t = {} ==> (h:real^1->real^N) x = h y` + ASSUME_TAC THENL + [MAP_EVERY X_GEN_TAC [`x:real^1`; `x':real^1`] THEN + ASM_CASES_TAC `(x:real^1) IN t` THENL + [ASM_MESON_TAC[SEGMENT_SYM]; ALL_TAC] THEN + ASM_CASES_TAC `(x':real^1) IN t` THENL + [ASM_MESON_TAC[]; ALL_TAC] THEN + SUBGOAL_THEN + `?y y'. y IN t /\ segment(x,y) INTER t = {} /\ h x = f y /\ + y' IN t /\ segment(x',y') INTER t = {} /\ + (h:real^1->real^N) x' = f y'` + STRIP_ASSUME_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_REWRITE_TAC[] THEN MAP_EVERY UNDISCH_TAC + [`~((x:real^1) IN t)`; `~((x':real^1) IN t)`; + `segment(x:real^1,y) INTER t = {}`; + `segment(x':real^1,y') INTER t = {}`; + `segment(x:real^1,x') INTER t = {}`] THEN + MATCH_MP_TAC(SET_RULE + `s SUBSET (x1 INSERT x2 INSERT (s0 UNION s1 UNION s2)) + ==> s0 INTER t = {} ==> s1 INTER t = {} ==> s2 INTER t = {} + ==> ~(x1 IN t) ==> ~(x2 IN t) ==> s INTER t = {}`) THEN + REWRITE_TAC[SEGMENT_1; SUBSET; IN_UNION; IN_INSERT; IN_INTERVAL_1] THEN + GEN_TAC THEN REWRITE_TAC[GSYM DROP_EQ] THEN + REPEAT(COND_CASES_TAC THEN ASM_REWRITE_TAC[IN_INTERVAL_1]) THEN + ASM_REAL_ARITH_TAC; + ALL_TAC] THEN + MP_TAC(ISPEC `h:real^1->real^N` HOMEOMORPHIC_MONOTONE_IMAGE_INTERVAL) THEN + ANTS_TAC THENL + [REPEAT CONJ_TAC THENL + [REWRITE_TAC[continuous_on] THEN X_GEN_TAC `u:real^1` THEN DISCH_TAC THEN + X_GEN_TAC `e:real` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [continuous_on]) THEN + DISCH_THEN(MP_TAC o SPEC `u:real^1`) THEN ASM_REWRITE_TAC[] 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` THEN STRIP_TAC THEN + ASM_REWRITE_TAC[] THEN X_GEN_TAC `v:real^1` THEN STRIP_TAC THEN + ASM_CASES_TAC `segment(u:real^1,v) INTER t = {}` THENL + [ASM_MESON_TAC[DIST_REFL]; ALL_TAC] THEN + SUBGOAL_THEN + `(?w:real^1. w IN t /\ w IN segment[u,v] /\ segment(u,w) INTER t = {}) /\ + (?z:real^1. z IN t /\ z IN segment[u,v] /\ segment(v,z) INTER t = {})` + STRIP_ASSUME_TAC THENL + [CONJ_TAC THENL + [MP_TAC(ISPECL [`segment[u:real^1,v] INTER t`; `u:real^1`] + SEGMENT_TO_POINT_EXISTS); + MP_TAC(ISPECL [`segment[u:real^1,v] INTER t`; `v:real^1`] + SEGMENT_TO_POINT_EXISTS)] THEN + (ASM_SIMP_TAC[CLOSED_INTER; CLOSED_SEGMENT] THEN ANTS_TAC THENL + [FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE + `~(segment(u,v) INTER t = {}) + ==> segment(u,v) SUBSET segment[u,v] + ==> ~(segment[u,v] INTER t = {})`)) THEN + REWRITE_TAC[SEGMENT_OPEN_SUBSET_CLOSED]; + ALL_TAC] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `w:real^1` THEN + SIMP_TAC[IN_INTER] THEN + MATCH_MP_TAC(SET_RULE + `(w IN uv ==> uw SUBSET uv) + ==> (w IN uv /\ w IN t) /\ (uw INTER uv INTER t = {}) + ==> uw INTER t = {}`) THEN + DISCH_TAC THEN REWRITE_TAC[open_segment] THEN + MATCH_MP_TAC(SET_RULE `s SUBSET t ==> s DIFF u SUBSET t`) THEN + REWRITE_TAC[SEGMENT_CONVEX_HULL] THEN MATCH_MP_TAC HULL_MINIMAL THEN + REWRITE_TAC[GSYM SEGMENT_CONVEX_HULL; CONVEX_SEGMENT] THEN + ASM_REWRITE_TAC[INSERT_SUBSET; EMPTY_SUBSET; ENDS_IN_SEGMENT]); + SUBGOAL_THEN `(h:real^1->real^N) u = (f:real^1->real^N) w /\ + (h:real^1->real^N) v = (f:real^1->real^N) z` + (fun th -> REWRITE_TAC[th]) THENL [ASM_MESON_TAC[]; ALL_TAC] THEN + MATCH_MP_TAC(NORM_ARITH + `!u. dist(w:real^N,u) < e / &2 /\ dist(z,u) < e / &2 + ==> dist(w,z) < e`) THEN + EXISTS_TAC `(f:real^1->real^N) u` THEN CONJ_TAC THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN + (CONJ_TAC THENL + [FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE + `x IN s ==> s SUBSET t ==> x IN t`)) THEN + REWRITE_TAC[SEGMENT_CONVEX_HULL] THEN MATCH_MP_TAC HULL_MINIMAL THEN + ASM_REWRITE_TAC[CONVEX_INTERVAL; INSERT_SUBSET; EMPTY_SUBSET]; + ASM_MESON_TAC[DIST_IN_CLOSED_SEGMENT; REAL_LET_TRANS; DIST_SYM]])]; + X_GEN_TAC `z:real^N` THEN + REWRITE_TAC[CONNECTED_IFF_CONNECTED_COMPONENT] THEN + MAP_EVERY X_GEN_TAC [`u:real^1`; `v:real^1`] THEN + REWRITE_TAC[IN_ELIM_THM] THEN STRIP_TAC THEN + REWRITE_TAC[connected_component] THEN + EXISTS_TAC `segment[u:real^1,v]` THEN + REWRITE_TAC[CONNECTED_SEGMENT; ENDS_IN_SEGMENT] THEN + ASM_CASES_TAC `segment(u:real^1,v) INTER t = {}` THENL + [REWRITE_TAC[SET_RULE `s SUBSET {x | x IN t /\ P x} <=> + s SUBSET t /\ !x. x IN s ==> P x`] THEN + CONJ_TAC THENL + [ASM_MESON_TAC[CONVEX_CONTAINS_SEGMENT; CONVEX_INTERVAL]; + X_GEN_TAC `x:real^1` THEN DISCH_TAC THEN + SUBGOAL_THEN `segment(u:real^1,x) INTER t = {}` + (fun th -> ASM_MESON_TAC[th]) THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE + `uv INTER t = {} ==> ux SUBSET uv ==> ux INTER t = {}`)) THEN + UNDISCH_TAC `(x:real^1) IN segment[u,v]` THEN + REWRITE_TAC[SEGMENT_1] THEN + REPEAT(COND_CASES_TAC THEN + ASM_REWRITE_TAC[IN_INTERVAL_1; SUBSET_INTERVAL_1]) THEN + ASM_REAL_ARITH_TAC]; + ALL_TAC] THEN + FIRST_X_ASSUM(MP_TAC o SPEC `t DIFF segment(u:real^1,v)`) THEN + ASM_REWRITE_TAC[SET_RULE `t DIFF s PSUBSET t <=> ~(s INTER t = {})`] THEN + MATCH_MP_TAC(TAUT `p ==> ~p ==> q`) THEN + REPEAT CONJ_TAC THENL + [ASM SET_TAC[]; + MATCH_MP_TAC CLOSED_DIFF THEN ASM_REWRITE_TAC[OPEN_SEGMENT_1]; + ASM SET_TAC[]; + ASM_REWRITE_TAC[IN_DIFF] THEN MAP_EVERY UNDISCH_TAC + [`(u:real^1) IN interval[vec 0,vec 1]`; + `(v:real^1) IN interval[vec 0,vec 1]`] THEN + REWRITE_TAC[SEGMENT_1] THEN + REPEAT(COND_CASES_TAC THEN ASM_REWRITE_TAC[IN_INTERVAL_1]) THEN + ASM_REAL_ARITH_TAC; + ASM_REWRITE_TAC[IN_DIFF] THEN MAP_EVERY UNDISCH_TAC + [`(u:real^1) IN interval[vec 0,vec 1]`; + `(v:real^1) IN interval[vec 0,vec 1]`] THEN + REWRITE_TAC[SEGMENT_1] THEN + REPEAT(COND_CASES_TAC THEN ASM_REWRITE_TAC[IN_INTERVAL_1]) THEN + ASM_REAL_ARITH_TAC; + MAP_EVERY X_GEN_TAC [`x:real^1`; `y:real^1`] THEN + REWRITE_TAC[IN_DIFF] THEN STRIP_TAC THEN + ASM_CASES_TAC `segment(x:real^1,y) INTER segment(u,v) = {}` THENL + [ASM SET_TAC[]; ALL_TAC] THEN + SUBGOAL_THEN + `(segment(x:real^1,u) SUBSET segment(x,y) DIFF segment(u,v) /\ + segment(y:real^1,v) SUBSET segment(x,y) DIFF segment(u,v)) \/ + (segment(y:real^1,u) SUBSET segment(x,y) DIFF segment(u,v) /\ + segment(x:real^1,v) SUBSET segment(x,y) DIFF segment(u,v))` + MP_TAC THENL + [MAP_EVERY UNDISCH_TAC + [`~(x IN segment(u:real^1,v))`; `~(y IN segment(u:real^1,v))`; + `~(segment(x:real^1,y) INTER segment (u,v) = {})`] THEN + POP_ASSUM_LIST(K ALL_TAC) THEN + MAP_EVERY (fun t -> SPEC_TAC(t,t)) + [`v:real^1`; `u:real^1`; `y:real^1`; `x:real^1`] THEN + REWRITE_TAC[FORALL_LIFT] THEN + MATCH_MP_TAC REAL_WLOG_LE THEN CONJ_TAC THENL + [REWRITE_TAC[SEGMENT_SYM] THEN MESON_TAC[]; ALL_TAC] THEN + REWRITE_TAC[FORALL_DROP; LIFT_DROP] THEN + MAP_EVERY X_GEN_TAC [`x:real^1`; `y:real^1`] THEN DISCH_TAC THEN + REWRITE_TAC[FORALL_LIFT] THEN + MATCH_MP_TAC REAL_WLOG_LE THEN CONJ_TAC THENL + [REWRITE_TAC[SEGMENT_SYM] THEN MESON_TAC[]; ALL_TAC] THEN + REWRITE_TAC[FORALL_DROP; LIFT_DROP] THEN + MAP_EVERY X_GEN_TAC [`u:real^1`; `v:real^1`] THEN DISCH_TAC THEN + ASM_REWRITE_TAC[SEGMENT_1] THEN + REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; IN_INTER] THEN + REPEAT(COND_CASES_TAC THEN ASM_REWRITE_TAC[]) THEN + REWRITE_TAC[IN_INTERVAL_1; SUBSET; IN_DIFF; AND_FORALL_THM] THEN + ASM_REAL_ARITH_TAC; + DISCH_THEN(DISJ_CASES_THEN(CONJUNCTS_THEN + (let sl = SET_RULE + `i SUBSET xy DIFF uv + ==> xy INTER (t DIFF uv) = {} ==> i INTER t = {}` in + fun th -> FIRST_ASSUM(MP_TAC o MATCH_MP (MATCH_MP sl th))))) THEN + ASM_MESON_TAC[]]]; + ASM_MESON_TAC[]]; + DISCH_TAC] THEN + SUBGOAL_THEN + `?q:real^1->real^N. + arc q /\ path_image q SUBSET path_image f /\ + a IN path_image q /\ b IN path_image q` + STRIP_ASSUME_TAC THENL + [FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [homeomorphic]) THEN + REWRITE_TAC[homeomorphism] THEN ONCE_REWRITE_TAC[SWAP_EXISTS_THM] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `q:real^1->real^N` THEN + REWRITE_TAC[arc; path; path_image] THEN + REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THENL + [ASM MESON_TAC[]; + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; path_image] THEN ASM SET_TAC[]; + REWRITE_TAC[IN_IMAGE] THEN EXISTS_TAC `vec 0:real^1` THEN + REWRITE_TAC[ENDS_IN_UNIT_INTERVAL] THEN ASM_MESON_TAC[]; + REWRITE_TAC[IN_IMAGE] THEN EXISTS_TAC `vec 1:real^1` THEN + REWRITE_TAC[ENDS_IN_UNIT_INTERVAL] THEN ASM_MESON_TAC[]]; + SUBGOAL_THEN + `?u v. u IN interval[vec 0,vec 1] /\ a = (q:real^1->real^N) u /\ + v IN interval[vec 0,vec 1] /\ b = (q:real^1->real^N) v` + STRIP_ASSUME_TAC THENL + [RULE_ASSUM_TAC(REWRITE_RULE[path_image]) THEN ASM SET_TAC[]; + ALL_TAC] THEN + EXISTS_TAC `subpath u v (q:real^1->real^N)` THEN REPEAT CONJ_TAC THENL + [MATCH_MP_TAC ARC_SIMPLE_PATH_SUBPATH THEN + ASM_MESON_TAC[ARC_IMP_SIMPLE_PATH]; + ASM_MESON_TAC[SUBSET_TRANS; PATH_IMAGE_SUBPATH_SUBSET; ARC_IMP_PATH]; + ASM_MESON_TAC[pathstart; PATHSTART_SUBPATH]; + ASM_MESON_TAC[pathfinish; PATHFINISH_SUBPATH]]]);; + +let PATH_CONNECTED_ARCWISE = prove + (`!s:real^N->bool. + path_connected s <=> + !x y. x IN s /\ y IN s /\ ~(x = y) + ==> ?g. arc g /\ + path_image g SUBSET s /\ + pathstart g = x /\ + pathfinish g = y`, + GEN_TAC THEN REWRITE_TAC[path_connected] THEN EQ_TAC THEN DISCH_TAC THEN + MAP_EVERY X_GEN_TAC [`x:real^N`; `y:real^N`] THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`x:real^N`; `y:real^N`]) THEN + ASM_REWRITE_TAC[] THENL + [DISCH_THEN(X_CHOOSE_THEN `g:real^1->real^N` STRIP_ASSUME_TAC) THEN + MP_TAC(ISPECL [`g:real^1->real^N`; `x:real^N`; `y:real^N`] + PATH_CONTAINS_ARC) THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC MONO_EXISTS THEN + ASM_MESON_TAC[SUBSET_TRANS]; + ASM_CASES_TAC `y:real^N = x` THEN ASM_REWRITE_TAC[] THENL + [EXISTS_TAC `linepath(y:real^N,y)` THEN + ASM_REWRITE_TAC[PATH_LINEPATH; PATHSTART_LINEPATH; PATHFINISH_LINEPATH; + PATH_IMAGE_LINEPATH; SEGMENT_REFL; SING_SUBSET]; + MATCH_MP_TAC MONO_EXISTS THEN SIMP_TAC[ARC_IMP_PATH]]]);; + +let ARC_CONNECTED_TRANS = prove + (`!g h:real^1->real^N. + arc g /\ arc h /\ + pathfinish g = pathstart h /\ ~(pathstart g = pathfinish h) + ==> ?i. arc i /\ + path_image i SUBSET (path_image g UNION path_image h) /\ + pathstart i = pathstart g /\ + pathfinish i = pathfinish h`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`g ++ h:real^1->real^N`; `pathstart(g):real^N`; + `pathfinish(h):real^N`] PATH_CONTAINS_ARC) THEN + ASM_SIMP_TAC[PATHSTART_JOIN; PATHFINISH_JOIN; PATH_JOIN_EQ; ARC_IMP_PATH; + PATH_IMAGE_JOIN]);; + +(* ------------------------------------------------------------------------- *) +(* Local versions of topological properties in general. *) +(* ------------------------------------------------------------------------- *) + +let locally = new_definition + `locally P (s:real^N->bool) <=> + !w x. open_in (subtopology euclidean s) w /\ x IN w + ==> ?u v. open_in (subtopology euclidean s) u /\ P v /\ + x IN u /\ u SUBSET v /\ v SUBSET w`;; + +let LOCALLY_MONO = prove + (`!P Q s. (!t. P t ==> Q t) /\ locally P s ==> locally Q s`, + REWRITE_TAC[locally] THEN MESON_TAC[]);; + +let LOCALLY_OPEN_SUBSET = prove + (`!P s t:real^N->bool. + locally P s /\ open_in (subtopology euclidean s) t + ==> locally P t`, + REPEAT GEN_TAC THEN REWRITE_TAC[locally] THEN STRIP_TAC THEN + MAP_EVERY X_GEN_TAC [`w:real^N->bool`; `x:real^N`] THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`w:real^N->bool`; `x:real^N`]) THEN + ANTS_TAC THENL [ASM_MESON_TAC[OPEN_IN_TRANS]; ALL_TAC] THEN + REPEAT(MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC) THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC OPEN_IN_SUBSET_TRANS THEN + EXISTS_TAC `s:real^N->bool` THEN ASM_MESON_TAC[open_in; SUBSET]);; + +let LOCALLY_DIFF_CLOSED = prove + (`!P s t:real^N->bool. + locally P s /\ closed_in (subtopology euclidean s) t + ==> locally P (s DIFF t)`, + REPEAT STRIP_TAC THEN + MATCH_MP_TAC LOCALLY_OPEN_SUBSET THEN + EXISTS_TAC `s:real^N->bool` THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC OPEN_IN_DIFF THEN + ASM_REWRITE_TAC[OPEN_IN_SUBTOPOLOGY_REFL; SUBSET_UNIV; TOPSPACE_EUCLIDEAN]);; + +let LOCALLY_EMPTY = prove + (`!P. locally P {}`, + REWRITE_TAC[locally] THEN MESON_TAC[open_in; SUBSET; NOT_IN_EMPTY]);; + +let LOCALLY_SING = prove + (`!P a. locally P {a} <=> P {a}`, + REWRITE_TAC[locally; open_in] THEN + REWRITE_TAC[SET_RULE + `(w SUBSET {a} /\ P) /\ x IN w <=> w = {a} /\ x = a /\ P`] THEN + SIMP_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_UNWIND_THM2; IN_SING] THEN + REWRITE_TAC[SET_RULE + `(u SUBSET {a} /\ P) /\ Q /\ a IN u /\ u SUBSET v /\ v SUBSET {a} <=> + u = {a} /\ v = {a} /\ P /\ Q`] THEN + REWRITE_TAC[RIGHT_EXISTS_AND_THM; UNWIND_THM2; IN_SING] THEN + REWRITE_TAC[FORALL_UNWIND_THM2; MESON[REAL_LT_01] `?x. &0 < x`]);; + +let LOCALLY_INTER = prove + (`!P:(real^N->bool)->bool. + (!s t. P s /\ P t ==> P(s INTER t)) + ==> !s t. locally P s /\ locally P t ==> locally P (s INTER t)`, + GEN_TAC THEN DISCH_TAC THEN REPEAT GEN_TAC THEN + REWRITE_TAC[locally; OPEN_IN_OPEN] THEN + REWRITE_TAC[LEFT_AND_EXISTS_THM; GSYM CONJ_ASSOC; MESON[] + `(!w x. (?t. P t /\ w = f t) /\ Q w x ==> R w x) <=> + (!t x. P t /\ Q (f t) x ==> R (f t) x)`] THEN + ONCE_REWRITE_TAC[MESON[] + `(?a b c. P a b c /\ Q a b c /\ R a b c) <=> + (?b c a. Q a b c /\ P a b c /\ R a b c)`] THEN + REWRITE_TAC[AND_FORALL_THM; UNWIND_THM2; IN_INTER] THEN + MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `w:real^N->bool` THEN + MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `x:real^N` THEN + DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN + ASM_REWRITE_TAC[] THEN DISCH_THEN(CONJUNCTS_THEN2 + (X_CHOOSE_THEN `u1:real^N->bool` (X_CHOOSE_THEN `v1:real^N->bool` + STRIP_ASSUME_TAC)) + (X_CHOOSE_THEN `u2:real^N->bool` (X_CHOOSE_THEN `v2:real^N->bool` + STRIP_ASSUME_TAC))) THEN + EXISTS_TAC `u1 INTER u2:real^N->bool` THEN + EXISTS_TAC `v1 INTER v2:real^N->bool` THEN + ASM_SIMP_TAC[OPEN_INTER] THEN ASM SET_TAC[]);; + +let HOMEOMORPHISM_LOCALLY = prove + (`!P Q f:real^N->real^M g. + (!s t. homeomorphism (s,t) (f,g) ==> (P s <=> Q t)) + ==> (!s t. homeomorphism (s,t) (f,g) + ==> (locally P s <=> locally Q t))`, + + let lemma = prove + (`!P Q f g. + (!s t. P s /\ homeomorphism (s,t) (f,g) ==> Q t) + ==> (!s:real^N->bool t:real^M->bool. + locally P s /\ homeomorphism (s,t) (f,g) ==> locally Q t)`, + REPEAT GEN_TAC THEN DISCH_TAC THEN REPEAT GEN_TAC THEN + REWRITE_TAC[locally] THEN STRIP_TAC THEN + FIRST_X_ASSUM(STRIP_ASSUME_TAC o GEN_REWRITE_RULE I [homeomorphism]) THEN + MAP_EVERY X_GEN_TAC [`w:real^M->bool`; `y:real^M`] THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPECL + [`IMAGE (g:real^M->real^N) w`; `(g:real^M->real^N) y`]) THEN + ANTS_TAC THENL + [CONJ_TAC THENL [ALL_TAC; ASM SET_TAC[]] THEN + SUBGOAL_THEN `IMAGE (g:real^M->real^N) w = + {x | x IN s /\ f(x) IN w}` + SUBST1_TAC THENL + [RULE_ASSUM_TAC(REWRITE_RULE[open_in]) THEN ASM SET_TAC[]; + MATCH_MP_TAC CONTINUOUS_ON_IMP_OPEN_IN THEN ASM_REWRITE_TAC[]]; + REWRITE_TAC[LEFT_IMP_EXISTS_THM]] THEN + MAP_EVERY X_GEN_TAC [`u:real^N->bool`; `v:real^N->bool`] THEN + STRIP_TAC THEN MAP_EVERY EXISTS_TAC + [`IMAGE (f:real^N->real^M) u`; `IMAGE (f:real^N->real^M) v`] THEN + CONJ_TAC THENL + [SUBGOAL_THEN `IMAGE (f:real^N->real^M) u = + {x | x IN t /\ g(x) IN u}` + SUBST1_TAC THENL + [RULE_ASSUM_TAC(REWRITE_RULE[open_in]) THEN ASM SET_TAC[]; + MATCH_MP_TAC CONTINUOUS_ON_IMP_OPEN_IN THEN ASM_REWRITE_TAC[]]; + ALL_TAC] THEN + CONJ_TAC THENL + [FIRST_X_ASSUM MATCH_MP_TAC THEN EXISTS_TAC `v:real^N->bool` THEN + ASM_REWRITE_TAC[homeomorphism] THEN + REWRITE_TAC[homeomorphism] THEN REPEAT CONJ_TAC THEN + TRY(FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET))); + ALL_TAC] THEN + RULE_ASSUM_TAC(REWRITE_RULE[open_in]) THEN ASM SET_TAC[]) in + REPEAT STRIP_TAC THEN EQ_TAC THEN + MATCH_MP_TAC(REWRITE_RULE[RIGHT_IMP_FORALL_THM; + TAUT `p ==> q /\ r ==> s <=> p /\ r ==> q ==> s`] lemma) THEN + ASM_MESON_TAC[HOMEOMORPHISM_SYM]);; + +let HOMEOMORPHIC_LOCALLY = prove + (`!P Q. (!s:real^N->bool t:real^M->bool. s homeomorphic t ==> (P s <=> Q t)) + ==> (!s t. s homeomorphic t ==> (locally P s <=> locally Q t))`, + REPEAT GEN_TAC THEN STRIP_TAC THEN + REWRITE_TAC[homeomorphic; LEFT_IMP_EXISTS_THM] THEN + ONCE_REWRITE_TAC[MESON[] + `(!a b c d. P a b c d) <=> (!c d a b. P a b c d)`] THEN + GEN_TAC THEN GEN_TAC THEN MATCH_MP_TAC HOMEOMORPHISM_LOCALLY THEN + ASM_MESON_TAC[homeomorphic]);; + +let LOCALLY_TRANSLATION = prove + (`!P:(real^N->bool)->bool. + (!a s. P (IMAGE (\x. a + x) s) <=> P s) + ==> (!a s. locally P (IMAGE (\x. a + x) s) <=> locally P s)`, + GEN_TAC THEN MATCH_MP_TAC MONO_FORALL THEN GEN_TAC THEN + MP_TAC(ISPECL + [`P:(real^N->bool)->bool`; `P:(real^N->bool)->bool`; + `\x:real^N. a + x`; `\x:real^N. --a + x`] + HOMEOMORPHISM_LOCALLY) THEN + REWRITE_TAC[homeomorphism] THEN + SIMP_TAC[CONTINUOUS_ON_ADD; CONTINUOUS_ON_CONST; CONTINUOUS_ON_ID] THEN + REWRITE_TAC[FORALL_UNWIND_THM1; IMP_CONJ; GSYM IMAGE_o; o_DEF; IMAGE_ID; + VECTOR_ARITH `--a + a + x:real^N = x /\ a + --a + x = x`] THEN + MESON_TAC[]);; + +let LOCALLY_INJECTIVE_LINEAR_IMAGE = prove + (`!P:(real^N->bool)->bool Q:(real^M->bool)->bool. + (!f s. linear f /\ (!x y. f x = f y ==> x = y) + ==> (P (IMAGE f s) <=> Q s)) + ==> (!f s. linear f /\ (!x y. f x = f y ==> x = y) + ==> (locally P (IMAGE f s) <=> locally Q s))`, + GEN_TAC THEN GEN_TAC THEN MATCH_MP_TAC MONO_FORALL THEN GEN_TAC THEN + ASM_CASES_TAC `linear(f:real^M->real^N) /\ (!x y. f x = f y ==> x = y)` THEN + ASM_REWRITE_TAC[] THEN + FIRST_ASSUM(MP_TAC o MATCH_MP LINEAR_INJECTIVE_LEFT_INVERSE) THEN + REWRITE_TAC[FUN_EQ_THM; o_THM; I_THM] THEN + DISCH_THEN(X_CHOOSE_THEN `g:real^N->real^M` STRIP_ASSUME_TAC) THEN + MP_TAC(ISPECL + [`Q:(real^M->bool)->bool`; `P:(real^N->bool)->bool`; + `f:real^M->real^N`; `g:real^N->real^M`] + HOMEOMORPHISM_LOCALLY) THEN + ASM_SIMP_TAC[homeomorphism; LINEAR_CONTINUOUS_ON] THEN + ASM_REWRITE_TAC[FORALL_UNWIND_THM1; IMP_CONJ; FORALL_IN_IMAGE] THEN + ASM_REWRITE_TAC[GSYM IMAGE_o; o_DEF; IMAGE_ID] THEN MESON_TAC[]);; + +let LOCALLY_OPEN_MAP_IMAGE = prove + (`!P Q f:real^M->real^N s. + f continuous_on s /\ + (!t. open_in (subtopology euclidean s) t + ==> open_in (subtopology euclidean (IMAGE f s)) (IMAGE f t)) /\ + (!t. t SUBSET s /\ P t ==> Q(IMAGE f t)) /\ + locally P s + ==> locally Q (IMAGE f s)`, + REPEAT GEN_TAC THEN + REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + REWRITE_TAC[locally] THEN DISCH_TAC THEN + MAP_EVERY X_GEN_TAC [`w:real^N->bool`; `y:real^N`] THEN + STRIP_TAC THEN + FIRST_ASSUM(ASSUME_TAC o CONJUNCT1 o GEN_REWRITE_RULE I [open_in]) THEN + FIRST_ASSUM(MP_TAC o SPEC `w:real^N->bool` o + GEN_REWRITE_RULE I [CONTINUOUS_ON_OPEN]) THEN + ASM_REWRITE_TAC[] THEN DISCH_TAC THEN + SUBGOAL_THEN `?x. x IN s /\ (f:real^M->real^N) x = y` STRIP_ASSUME_TAC THENL + [ASM SET_TAC[]; ALL_TAC] THEN + FIRST_X_ASSUM(MP_TAC o SPECL + [`{x | x IN s /\ (f:real^M->real^N) x IN w}`; `x:real^M`]) THEN + ASM_REWRITE_TAC[IN_ELIM_THM; LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`u:real^M->bool`; `v:real^M->bool`] THEN + STRIP_TAC THEN MAP_EVERY EXISTS_TAC + [`IMAGE (f:real^M->real^N) u`; `IMAGE (f:real^M->real^N) v`] THEN + ASM_SIMP_TAC[] THEN CONJ_TAC THENL [ALL_TAC; ASM SET_TAC[]] THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN ASM SET_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* Important special cases of local connectedness & path connectedness. *) +(* ------------------------------------------------------------------------- *) + +let LOCALLY_CONNECTED,LOCALLY_CONNECTED_OPEN_CONNECTED_COMPONENT = + (CONJ_PAIR o prove) + (`(!s:real^N->bool. + locally connected s <=> + !v x. open_in (subtopology euclidean s) v /\ x IN v + ==> ?u. open_in (subtopology euclidean s) u /\ + connected u /\ + x IN u /\ u SUBSET v) /\ + (!s:real^N->bool. + locally connected s <=> + !t x. open_in (subtopology euclidean s) t /\ x IN t + ==> open_in (subtopology euclidean s) + (connected_component t x))`, + REWRITE_TAC[AND_FORALL_THM; locally] THEN X_GEN_TAC `s:real^N->bool` THEN + MATCH_MP_TAC(TAUT + `(q ==> p) /\ (p ==> r) /\ (r ==> q) ==> (p <=> q) /\ (p <=> r)`) THEN + REPEAT CONJ_TAC THENL + [MESON_TAC[SUBSET_REFL]; + DISCH_TAC THEN + MAP_EVERY X_GEN_TAC [`u:real^N->bool`; `y:real^N`] THEN STRIP_TAC THEN + ONCE_REWRITE_TAC[OPEN_IN_SUBOPEN] THEN + X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN + FIRST_ASSUM(SUBST1_TAC o SYM o MATCH_MP CONNECTED_COMPONENT_EQ) THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`u:real^N->bool`; `x:real^N`]) THEN ANTS_TAC + THENL [ASM_MESON_TAC[CONNECTED_COMPONENT_SUBSET; SUBSET]; ALL_TAC] THEN + DISCH_THEN(X_CHOOSE_THEN `v:real^N->bool` (X_CHOOSE_THEN `a:real^N->bool` + STRIP_ASSUME_TAC)) THEN + EXISTS_TAC `v:real^N->bool` THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC SUBSET_TRANS THEN EXISTS_TAC `a:real^N->bool` THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC CONNECTED_COMPONENT_MAXIMAL THEN + ASM_REWRITE_TAC[] THEN ASM SET_TAC[]; + DISCH_TAC THEN + MAP_EVERY X_GEN_TAC [`u:real^N->bool`; `x:real^N`] THEN STRIP_TAC THEN + EXISTS_TAC `connected_component u (x:real^N)` THEN + REWRITE_TAC[CONNECTED_COMPONENT_SUBSET; CONNECTED_CONNECTED_COMPONENT] THEN + ASM_SIMP_TAC[IN; CONNECTED_COMPONENT_REFL]]);; + +let LOCALLY_PATH_CONNECTED,LOCALLY_PATH_CONNECTED_OPEN_PATH_COMPONENT = + (CONJ_PAIR o prove) + (`(!s:real^N->bool. + locally path_connected s <=> + !v x. open_in (subtopology euclidean s) v /\ x IN v + ==> ?u. open_in (subtopology euclidean s) u /\ + path_connected u /\ + x IN u /\ u SUBSET v) /\ + (!s:real^N->bool. + locally path_connected s <=> + !t x. open_in (subtopology euclidean s) t /\ x IN t + ==> open_in (subtopology euclidean s) + (path_component t x))`, + REWRITE_TAC[AND_FORALL_THM; locally] THEN X_GEN_TAC `s:real^N->bool` THEN + MATCH_MP_TAC(TAUT + `(q ==> p) /\ (p ==> r) /\ (r ==> q) ==> (p <=> q) /\ (p <=> r)`) THEN + REPEAT CONJ_TAC THENL + [MESON_TAC[SUBSET_REFL]; + DISCH_TAC THEN + MAP_EVERY X_GEN_TAC [`u:real^N->bool`; `y:real^N`] THEN STRIP_TAC THEN + ONCE_REWRITE_TAC[OPEN_IN_SUBOPEN] THEN + X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN + FIRST_ASSUM(SUBST1_TAC o SYM o MATCH_MP PATH_COMPONENT_EQ) THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`u:real^N->bool`; `x:real^N`]) THEN ANTS_TAC + THENL [ASM_MESON_TAC[PATH_COMPONENT_SUBSET; SUBSET]; ALL_TAC] THEN + DISCH_THEN(X_CHOOSE_THEN `v:real^N->bool` (X_CHOOSE_THEN `a:real^N->bool` + STRIP_ASSUME_TAC)) THEN + EXISTS_TAC `v:real^N->bool` THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC SUBSET_TRANS THEN EXISTS_TAC `a:real^N->bool` THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC PATH_COMPONENT_MAXIMAL THEN + ASM_REWRITE_TAC[] THEN ASM SET_TAC[]; + DISCH_TAC THEN + MAP_EVERY X_GEN_TAC [`u:real^N->bool`; `x:real^N`] THEN STRIP_TAC THEN + EXISTS_TAC `path_component u (x:real^N)` THEN + REWRITE_TAC[PATH_COMPONENT_SUBSET; PATH_CONNECTED_PATH_COMPONENT] THEN + ASM_SIMP_TAC[IN; PATH_COMPONENT_REFL]]);; + +let LOCALLY_CONNECTED_OPEN_COMPONENT = prove + (`!s:real^N->bool. + locally connected s <=> + !t c. open_in (subtopology euclidean s) t /\ c IN components t + ==> open_in (subtopology euclidean s) c`, + REWRITE_TAC[LOCALLY_CONNECTED_OPEN_CONNECTED_COMPONENT] THEN + REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; components; FORALL_IN_GSPEC]);; + +let LOCALLY_CONNECTED_IM_KLEINEN = prove + (`!s:real^N->bool. + locally connected s <=> + !v x. open_in (subtopology euclidean s) v /\ x IN v + ==> ?u. open_in (subtopology euclidean s) u /\ + x IN u /\ u SUBSET v /\ + !y. y IN u + ==> ?c. connected c /\ c SUBSET v /\ x IN c /\ y IN c`, + GEN_TAC THEN EQ_TAC THENL + [REWRITE_TAC[LOCALLY_CONNECTED] THEN MESON_TAC[SUBSET_REFL]; DISCH_TAC] THEN + REWRITE_TAC[LOCALLY_CONNECTED_OPEN_COMPONENT] THEN + MAP_EVERY X_GEN_TAC [`u:real^N->bool`; `c:real^N->bool`] THEN STRIP_TAC THEN + ONCE_REWRITE_TAC[OPEN_IN_SUBOPEN] THEN + X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`u:real^N->bool`; `x:real^N`]) THEN + ANTS_TAC THENL [ASM_MESON_TAC[IN_COMPONENTS_SUBSET; SUBSET]; ALL_TAC] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `v:real^N->bool` THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[SUBSET] THEN X_GEN_TAC `y:real^N` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `y:real^N`) THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `k:real^N->bool` STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN `(k:real^N->bool) SUBSET c` MP_TAC THENL + [ALL_TAC; ASM SET_TAC[]] THEN + MATCH_MP_TAC COMPONENTS_MAXIMAL THEN + EXISTS_TAC `u:real^N->bool` THEN ASM SET_TAC[]);; + +let LOCALLY_PATH_CONNECTED_IM_KLEINEN = prove + (`!s:real^N->bool. + locally path_connected s <=> + !v x. open_in (subtopology euclidean s) v /\ x IN v + ==> ?u. open_in (subtopology euclidean s) u /\ + x IN u /\ u SUBSET v /\ + !y. y IN u + ==> ?p. path p /\ path_image p SUBSET v /\ + pathstart p = x /\ pathfinish p = y`, + GEN_TAC THEN EQ_TAC THENL + [REWRITE_TAC[LOCALLY_PATH_CONNECTED] THEN + REWRITE_TAC[path_connected] 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 REPEAT STRIP_TAC THEN + ASM_REWRITE_TAC[] THEN ASM SET_TAC[]; + REWRITE_TAC[LOCALLY_PATH_CONNECTED_OPEN_PATH_COMPONENT] THEN DISCH_TAC THEN + MAP_EVERY X_GEN_TAC [`u:real^N->bool`; `z:real^N`] THEN STRIP_TAC THEN + ONCE_REWRITE_TAC[OPEN_IN_SUBOPEN] THEN + X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`u:real^N->bool`; `x:real^N`]) THEN + ANTS_TAC THENL [ASM_MESON_TAC[PATH_COMPONENT_SUBSET; SUBSET]; ALL_TAC] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `v:real^N->bool` THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[SUBSET] THEN X_GEN_TAC `y:real^N` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `y:real^N`) THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `p:real^1->real^N` STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN + `(path_image p) SUBSET path_component u (z:real^N)` MP_TAC + THENL [ALL_TAC; ASM_MESON_TAC[PATHFINISH_IN_PATH_IMAGE; SUBSET]] THEN + FIRST_ASSUM(SUBST1_TAC o SYM o MATCH_MP PATH_COMPONENT_EQ) THEN + MATCH_MP_TAC PATH_COMPONENT_MAXIMAL THEN + ASM_SIMP_TAC[PATH_CONNECTED_PATH_IMAGE] THEN + ASM_MESON_TAC[PATHSTART_IN_PATH_IMAGE]]);; + +let LOCALLY_PATH_CONNECTED_IMP_LOCALLY_CONNECTED = prove + (`!s:real^N->bool. locally path_connected s ==> locally connected s`, + MESON_TAC[LOCALLY_MONO; PATH_CONNECTED_IMP_CONNECTED]);; + +let LOCALLY_CONNECTED_COMPONENTS = prove + (`!s c:real^N->bool. + locally connected s /\ c IN components s ==> locally connected c`, + REPEAT STRIP_TAC THEN FIRST_ASSUM(MATCH_MP_TAC o MATCH_MP + (REWRITE_RULE[IMP_CONJ] LOCALLY_OPEN_SUBSET)) THEN + FIRST_X_ASSUM(MATCH_MP_TAC o + GEN_REWRITE_RULE I [LOCALLY_CONNECTED_OPEN_COMPONENT]) THEN + EXISTS_TAC `s:real^N->bool` THEN ASM_REWRITE_TAC[OPEN_IN_REFL]);; + +let LOCALLY_CONNECTED_CONNECTED_COMPONENT = prove + (`!s x:real^N. + locally connected s + ==> locally connected (connected_component s x)`, + REPEAT STRIP_TAC THEN + ASM_CASES_TAC `connected_component s (x:real^N) = {}` THEN + ASM_REWRITE_TAC[LOCALLY_EMPTY] THEN + MATCH_MP_TAC LOCALLY_CONNECTED_COMPONENTS THEN + EXISTS_TAC `s:real^N->bool` THEN ASM_REWRITE_TAC[IN_COMPONENTS] THEN + ASM_MESON_TAC[CONNECTED_COMPONENT_EQ_EMPTY]);; + +let LOCALLY_PATH_CONNECTED_COMPONENTS = prove + (`!s c:real^N->bool. + locally path_connected s /\ c IN components s + ==> locally path_connected c`, + REPEAT STRIP_TAC THEN FIRST_ASSUM(MATCH_MP_TAC o MATCH_MP + (REWRITE_RULE[IMP_CONJ] LOCALLY_OPEN_SUBSET)) THEN + FIRST_X_ASSUM(MATCH_MP_TAC o + GEN_REWRITE_RULE I [LOCALLY_CONNECTED_OPEN_COMPONENT] o + MATCH_MP LOCALLY_PATH_CONNECTED_IMP_LOCALLY_CONNECTED) THEN + EXISTS_TAC `s:real^N->bool` THEN ASM_REWRITE_TAC[OPEN_IN_REFL]);; + +let LOCALLY_PATH_CONNECTED_CONNECTED_COMPONENT = prove + (`!s x:real^N. + locally path_connected s + ==> locally path_connected (connected_component s x)`, + REPEAT STRIP_TAC THEN + ASM_CASES_TAC `connected_component s (x:real^N) = {}` THEN + ASM_REWRITE_TAC[LOCALLY_EMPTY] THEN + MATCH_MP_TAC LOCALLY_PATH_CONNECTED_COMPONENTS THEN + EXISTS_TAC `s:real^N->bool` THEN ASM_REWRITE_TAC[IN_COMPONENTS] THEN + ASM_MESON_TAC[CONNECTED_COMPONENT_EQ_EMPTY]);; + +let OPEN_IMP_LOCALLY_PATH_CONNECTED = prove + (`!s:real^N->bool. open s ==> locally path_connected s`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC LOCALLY_MONO THEN + EXISTS_TAC `convex:(real^N->bool)->bool` THEN + REWRITE_TAC[CONVEX_IMP_PATH_CONNECTED] THEN + ASM_SIMP_TAC[locally; OPEN_IN_OPEN_EQ] THEN + ASM_MESON_TAC[OPEN_CONTAINS_BALL; CENTRE_IN_BALL; OPEN_BALL; CONVEX_BALL; + SUBSET]);; + +let OPEN_IMP_LOCALLY_CONNECTED = prove + (`!s:real^N->bool. open s ==> locally connected s`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC LOCALLY_MONO THEN + EXISTS_TAC `path_connected:(real^N->bool)->bool` THEN + ASM_SIMP_TAC[OPEN_IMP_LOCALLY_PATH_CONNECTED; + PATH_CONNECTED_IMP_CONNECTED]);; + +let LOCALLY_PATH_CONNECTED_UNIV = prove + (`locally path_connected (:real^N)`, + SIMP_TAC[OPEN_IMP_LOCALLY_PATH_CONNECTED; OPEN_UNIV]);; + +let LOCALLY_CONNECTED_UNIV = prove + (`locally connected (:real^N)`, + SIMP_TAC[OPEN_IMP_LOCALLY_CONNECTED; OPEN_UNIV]);; + +let OPEN_IN_CONNECTED_COMPONENT_LOCALLY_CONNECTED = prove + (`!s x:real^N. + locally connected s + ==> open_in (subtopology euclidean s) (connected_component s x)`, + REWRITE_TAC[LOCALLY_CONNECTED_OPEN_CONNECTED_COMPONENT] THEN + REPEAT STRIP_TAC THEN ASM_CASES_TAC `(x:real^N) IN s` THENL + [FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_REWRITE_TAC[OPEN_IN_SUBTOPOLOGY_REFL; SUBSET_UNIV; TOPSPACE_EUCLIDEAN]; + ASM_MESON_TAC[OPEN_IN_EMPTY; CONNECTED_COMPONENT_EQ_EMPTY]]);; + +let OPEN_IN_COMPONENTS_LOCALLY_CONNECTED = prove + (`!s c:real^N->bool. + locally connected s /\ c IN components s + ==> open_in (subtopology euclidean s) c`, + MESON_TAC[LOCALLY_CONNECTED_OPEN_COMPONENT; OPEN_IN_REFL]);; + +let OPEN_IN_PATH_COMPONENT_LOCALLY_PATH_CONNECTED = prove + (`!s x:real^N. + locally path_connected s + ==> open_in (subtopology euclidean s) (path_component s x)`, + REWRITE_TAC[LOCALLY_PATH_CONNECTED_OPEN_PATH_COMPONENT] THEN + REPEAT STRIP_TAC THEN ASM_CASES_TAC `(x:real^N) IN s` THENL + [FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_REWRITE_TAC[OPEN_IN_SUBTOPOLOGY_REFL; SUBSET_UNIV; TOPSPACE_EUCLIDEAN]; + ASM_MESON_TAC[OPEN_IN_EMPTY; PATH_COMPONENT_EQ_EMPTY]]);; + +let CLOSED_IN_PATH_COMPONENT_LOCALLY_PATH_CONNECTED = prove + (`!s x:real^N. + locally path_connected s + ==> closed_in (subtopology euclidean s) (path_component s x)`, + REWRITE_TAC[closed_in; TOPSPACE_EUCLIDEAN_SUBTOPOLOGY; + PATH_COMPONENT_SUBSET] THEN + REPEAT STRIP_TAC THEN + SUBGOAL_THEN + `s DIFF path_component s (x:real^N) = + UNIONS({path_component s y | y | y IN s} DELETE (path_component s x))` + SUBST1_TAC THENL + [GEN_REWRITE_TAC (LAND_CONV o LAND_CONV) [GSYM UNIONS_PATH_COMPONENT] THEN + MATCH_MP_TAC(SET_RULE + `(!x. x IN s DELETE a ==> DISJOINT a x) + ==> UNIONS s DIFF a = UNIONS (s DELETE a)`) THEN + REWRITE_TAC[IMP_CONJ; FORALL_IN_GSPEC; IN_DELETE] THEN + SIMP_TAC[PATH_COMPONENT_DISJOINT; PATH_COMPONENT_EQ_EQ] THEN + MESON_TAC[IN; SUBSET; PATH_COMPONENT_SUBSET]; + MATCH_MP_TAC OPEN_IN_UNIONS THEN + REWRITE_TAC[IMP_CONJ; FORALL_IN_GSPEC; IN_DELETE] THEN + ASM_SIMP_TAC[OPEN_IN_PATH_COMPONENT_LOCALLY_PATH_CONNECTED]]);; + +let CONVEX_IMP_LOCALLY_PATH_CONNECTED = prove + (`!s:real^N->bool. convex s ==> locally path_connected s`, + REPEAT STRIP_TAC THEN REWRITE_TAC[LOCALLY_PATH_CONNECTED] THEN + MAP_EVERY X_GEN_TAC [`v:real^N->bool`; `x:real^N`] THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [OPEN_IN_OPEN]) THEN + DISCH_THEN(X_CHOOSE_THEN `t:real^N->bool` STRIP_ASSUME_TAC) THEN + FIRST_X_ASSUM SUBST_ALL_TAC THEN + RULE_ASSUM_TAC(REWRITE_RULE[IN_INTER]) THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [OPEN_CONTAINS_BALL]) THEN + DISCH_THEN(MP_TAC o SPEC `x:real^N`) THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `e:real` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `s INTER ball(x:real^N,e)` THEN REPEAT CONJ_TAC THENL + [REWRITE_TAC[OPEN_IN_OPEN] THEN MESON_TAC[OPEN_BALL]; + MATCH_MP_TAC CONVEX_IMP_PATH_CONNECTED THEN + ASM_SIMP_TAC[CONVEX_INTER; CONVEX_BALL]; + ASM_REWRITE_TAC[IN_INTER; CENTRE_IN_BALL]; + ASM SET_TAC[]]);; + +let OPEN_IN_CONNECTED_COMPONENTS = prove + (`!s c:real^N->bool. + FINITE(components s) /\ c IN components s + ==> open_in (subtopology euclidean s) c`, + REWRITE_TAC[components; IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_GSPEC] THEN + SIMP_TAC[OPEN_IN_CONNECTED_COMPONENT]);; + +let FINITE_COMPONENTS = prove + (`!s:real^N->bool. compact s /\ locally connected s ==> FINITE(components s)`, + REPEAT STRIP_TAC THEN FIRST_ASSUM + (MP_TAC o GEN_REWRITE_RULE I [COMPACT_EQ_HEINE_BOREL_SUBTOPOLOGY]) THEN + DISCH_THEN(MP_TAC o SPEC `components(s:real^N->bool)`) THEN + REWRITE_TAC[GSYM UNIONS_COMPONENTS; SUBSET_REFL] THEN ANTS_TAC THENL + [ASM_MESON_TAC[OPEN_IN_COMPONENTS_LOCALLY_CONNECTED]; ALL_TAC] THEN + DISCH_THEN(X_CHOOSE_THEN `f:(real^N->bool)->bool` STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN `components(s:real^N->bool) = f` + (fun th -> ASM_REWRITE_TAC[th]) THEN + ASM_CASES_TAC `?c:real^N->bool. c IN components s /\ ~(c IN f)` THENL + [FIRST_X_ASSUM(CHOOSE_THEN STRIP_ASSUME_TAC); ASM SET_TAC[]] THEN + SUBGOAL_THEN + `~(c:real^N->bool = {}) /\ c SUBSET UNIONS f /\ DISJOINT c (UNIONS f)` + MP_TAC THENL [ALL_TAC; SET_TAC[]] THEN REPEAT CONJ_TAC THENL + [ASM_MESON_TAC[IN_COMPONENTS_NONEMPTY]; + ASM_MESON_TAC[IN_COMPONENTS_SUBSET; SUBSET_TRANS]; + REWRITE_TAC[DISJOINT; INTER_UNIONS; EMPTY_UNIONS; FORALL_IN_GSPEC] THEN + REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM DISJOINT] THEN + MATCH_MP_TAC(REWRITE_RULE[pairwise] PAIRWISE_DISJOINT_COMPONENTS) THEN + ASM_MESON_TAC[SUBSET]]);; + +let CONVEX_IMP_LOCALLY_CONNECTED = prove + (`!s:real^N->bool. convex s ==> locally connected s`, + MESON_TAC[CONVEX_IMP_LOCALLY_PATH_CONNECTED; + LOCALLY_PATH_CONNECTED_IMP_LOCALLY_CONNECTED]);; + +let HOMEOMORPHIC_LOCAL_CONNECTEDNESS = prove + (`!s t. s homeomorphic t ==> (locally connected s <=> locally connected t)`, + MATCH_MP_TAC HOMEOMORPHIC_LOCALLY THEN + REWRITE_TAC[HOMEOMORPHIC_CONNECTEDNESS]);; + +let HOMEOMORPHIC_LOCAL_PATH_CONNECTEDNESS = prove + (`!s t. s homeomorphic t + ==> (locally path_connected s <=> locally path_connected t)`, + MATCH_MP_TAC HOMEOMORPHIC_LOCALLY THEN + REWRITE_TAC[HOMEOMORPHIC_PATH_CONNECTEDNESS]);; + +let LOCALLY_PATH_CONNECTED_TRANSLATION_EQ = prove + (`!a:real^N s. locally path_connected (IMAGE (\x. a + x) s) <=> + locally path_connected s`, + MATCH_MP_TAC LOCALLY_TRANSLATION THEN + REWRITE_TAC[PATH_CONNECTED_TRANSLATION_EQ]);; + +add_translation_invariants [LOCALLY_PATH_CONNECTED_TRANSLATION_EQ];; + +let LOCALLY_CONNECTED_TRANSLATION_EQ = prove + (`!a:real^N s. locally connected (IMAGE (\x. a + x) s) <=> + locally connected s`, + MATCH_MP_TAC LOCALLY_TRANSLATION THEN + REWRITE_TAC[CONNECTED_TRANSLATION_EQ]);; + +add_translation_invariants [LOCALLY_CONNECTED_TRANSLATION_EQ];; + +let LOCALLY_PATH_CONNECTED_LINEAR_IMAGE_EQ = prove + (`!f:real^M->real^N s. + linear f /\ (!x y. f x = f y ==> x = y) + ==> (locally path_connected (IMAGE f s) <=> locally path_connected s)`, + MATCH_MP_TAC LOCALLY_INJECTIVE_LINEAR_IMAGE THEN + REWRITE_TAC[PATH_CONNECTED_LINEAR_IMAGE_EQ]);; + +add_linear_invariants [LOCALLY_PATH_CONNECTED_LINEAR_IMAGE_EQ];; + +let LOCALLY_CONNECTED_LINEAR_IMAGE_EQ = prove + (`!f:real^M->real^N s. + linear f /\ (!x y. f x = f y ==> x = y) + ==> (locally connected (IMAGE f s) <=> locally connected s)`, + MATCH_MP_TAC LOCALLY_INJECTIVE_LINEAR_IMAGE THEN + REWRITE_TAC[CONNECTED_LINEAR_IMAGE_EQ]);; + +add_linear_invariants [LOCALLY_CONNECTED_LINEAR_IMAGE_EQ];; + +let LOCALLY_CONNECTED_QUOTIENT_IMAGE = prove + (`!f:real^M->real^N s. + (!t. t SUBSET IMAGE f s + ==> (open_in (subtopology euclidean s) {x | x IN s /\ f x IN t} <=> + open_in (subtopology euclidean (IMAGE f s)) t)) /\ + locally connected s + ==> locally connected (IMAGE f s)`, + REPEAT STRIP_TAC THEN + REWRITE_TAC[LOCALLY_CONNECTED_OPEN_COMPONENT] THEN + MAP_EVERY X_GEN_TAC [`u:real^N->bool`; `c:real^N->bool`] THEN + STRIP_TAC THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP IN_COMPONENTS_SUBSET) THEN + FIRST_ASSUM(ASSUME_TAC o CONJUNCT1 o GEN_REWRITE_RULE I [open_in]) THEN + FIRST_ASSUM(MP_TAC o SPEC `c:real^N->bool`) THEN + ANTS_TAC THENL [ASM SET_TAC[]; DISCH_THEN(SUBST1_TAC o SYM)] THEN + ONCE_REWRITE_TAC[OPEN_IN_SUBOPEN] THEN X_GEN_TAC `x:real^M` THEN + REWRITE_TAC[IN_ELIM_THM] THEN STRIP_TAC THEN EXISTS_TAC + `connected_component {w | w IN s /\ (f:real^M->real^N)(w) IN u} x` THEN + REPEAT CONJ_TAC THENL + [FIRST_X_ASSUM(MP_TAC o SPEC `u:real^N->bool`) THEN + ANTS_TAC THENL [ASM SET_TAC[]; ASM_REWRITE_TAC[]] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I + [LOCALLY_CONNECTED_OPEN_COMPONENT]) THEN + REWRITE_TAC[IMP_CONJ_ALT] THEN DISCH_THEN MATCH_MP_TAC THEN + REWRITE_TAC[IN_COMPONENTS; IN_ELIM_THM] THEN ASM SET_TAC[]; + ALL_TAC; + ASSUME_TAC(ISPECL [`{w | w IN s /\ (f:real^M->real^N) w IN u}`; `x:real^M`] + CONNECTED_COMPONENT_SUBSET) THEN + SUBGOAL_THEN + `IMAGE (f:real^M->real^N) (connected_component {w | w IN s /\ f w IN u} x) + SUBSET c` + MP_TAC THENL [ALL_TAC; ASM SET_TAC[]] THEN + MATCH_MP_TAC COMPONENTS_MAXIMAL THEN EXISTS_TAC `u:real^N->bool` THEN + ASM_REWRITE_TAC[] THEN REPEAT CONJ_TAC THENL + [MATCH_MP_TAC CONNECTED_CONTINUOUS_IMAGE THEN + REWRITE_TAC[CONNECTED_CONNECTED_COMPONENT] THEN + MATCH_MP_TAC CONTINUOUS_ON_SUBSET THEN EXISTS_TAC `s:real^M->bool` THEN + CONJ_TAC THENL + [REWRITE_TAC[CONTINUOUS_ON_OPEN] THEN ASM_MESON_TAC[open_in]; + ASM SET_TAC[]]; + ASM SET_TAC[]; + REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; IN_INTER] THEN + EXISTS_TAC `(f:real^M->real^N) x` THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC FUN_IN_IMAGE]] THEN + GEN_REWRITE_TAC I [IN] THEN REWRITE_TAC[CONNECTED_COMPONENT_REFL_EQ] THEN + ASM SET_TAC[]);; + +let LOCALLY_PATH_CONNECTED_QUOTIENT_IMAGE = prove + (`!f:real^M->real^N s. + (!t. t SUBSET IMAGE f s + ==> (open_in (subtopology euclidean s) {x | x IN s /\ f x IN t} <=> + open_in (subtopology euclidean (IMAGE f s)) t)) /\ + locally path_connected s + ==> locally path_connected (IMAGE f s)`, + REPEAT STRIP_TAC THEN + REWRITE_TAC[LOCALLY_PATH_CONNECTED_OPEN_PATH_COMPONENT] THEN + MAP_EVERY X_GEN_TAC [`u:real^N->bool`; `y:real^N`] THEN + STRIP_TAC THEN + ASSUME_TAC(ISPECL [`u:real^N->bool`; `y:real^N`] PATH_COMPONENT_SUBSET) THEN + FIRST_ASSUM(ASSUME_TAC o CONJUNCT1 o GEN_REWRITE_RULE I [open_in]) THEN + FIRST_ASSUM(MP_TAC o SPEC `path_component u (y:real^N)`) THEN + ANTS_TAC THENL [ASM SET_TAC[]; DISCH_THEN(SUBST1_TAC o SYM)] THEN + ONCE_REWRITE_TAC[OPEN_IN_SUBOPEN] THEN X_GEN_TAC `x:real^M` THEN + REWRITE_TAC[IN_ELIM_THM] THEN STRIP_TAC THEN EXISTS_TAC + `path_component {w | w IN s /\ (f:real^M->real^N)(w) IN u} x` THEN + REPEAT CONJ_TAC THENL + [FIRST_X_ASSUM(MP_TAC o SPEC `u:real^N->bool`) THEN + ANTS_TAC THENL [ASM SET_TAC[]; ASM_REWRITE_TAC[]] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I + [LOCALLY_PATH_CONNECTED_OPEN_PATH_COMPONENT]) THEN + REWRITE_TAC[IMP_CONJ_ALT] THEN DISCH_THEN MATCH_MP_TAC THEN ASM SET_TAC[]; + ALL_TAC; + ASSUME_TAC(ISPECL [`{w | w IN s /\ (f:real^M->real^N) w IN u}`; `x:real^M`] + PATH_COMPONENT_SUBSET) THEN + SUBGOAL_THEN + `IMAGE (f:real^M->real^N) (path_component {w | w IN s /\ f w IN u} x) + SUBSET path_component u y` + MP_TAC THENL [ALL_TAC; ASM SET_TAC[]] THEN + FIRST_ASSUM(SUBST1_TAC o SYM o MATCH_MP PATH_COMPONENT_EQ) THEN + MATCH_MP_TAC PATH_COMPONENT_MAXIMAL THEN + ASM_REWRITE_TAC[] THEN REPEAT CONJ_TAC THENL + [MATCH_MP_TAC FUN_IN_IMAGE; + MATCH_MP_TAC PATH_CONNECTED_CONTINUOUS_IMAGE THEN + REWRITE_TAC[PATH_CONNECTED_PATH_COMPONENT] THEN + MATCH_MP_TAC CONTINUOUS_ON_SUBSET THEN EXISTS_TAC `s:real^M->bool` THEN + CONJ_TAC THENL + [REWRITE_TAC[CONTINUOUS_ON_OPEN] THEN ASM_MESON_TAC[open_in]; + ASM SET_TAC[]]; + ASM SET_TAC[]]] THEN + GEN_REWRITE_TAC I [IN] THEN REWRITE_TAC[PATH_COMPONENT_REFL_EQ] THEN + ASM SET_TAC[]);; + +let LOCALLY_CONNECTED_CONTINUOUS_IMAGE_COMPACT = prove + (`!f:real^M->real^N s. + locally connected s /\ compact s /\ f continuous_on s + ==> locally connected (IMAGE f s)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC LOCALLY_CONNECTED_QUOTIENT_IMAGE THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC CLOSED_MAP_IMP_QUOTIENT_MAP THEN + ASM_SIMP_TAC[CLOSED_IN_CLOSED_EQ; COMPACT_IMP_CLOSED; + COMPACT_CONTINUOUS_IMAGE; IMAGE_SUBSET] THEN + ASM_MESON_TAC[COMPACT_IMP_CLOSED; COMPACT_CONTINUOUS_IMAGE; + CONTINUOUS_ON_SUBSET; BOUNDED_SUBSET; COMPACT_EQ_BOUNDED_CLOSED]);; + +let LOCALLY_PATH_CONNECTED_CONTINUOUS_IMAGE_COMPACT = prove + (`!f:real^M->real^N s. + locally path_connected s /\ compact s /\ f continuous_on s + ==> locally path_connected (IMAGE f s)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC LOCALLY_PATH_CONNECTED_QUOTIENT_IMAGE THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC CLOSED_MAP_IMP_QUOTIENT_MAP THEN + ASM_SIMP_TAC[CLOSED_IN_CLOSED_EQ; COMPACT_IMP_CLOSED; + COMPACT_CONTINUOUS_IMAGE; IMAGE_SUBSET] THEN + ASM_MESON_TAC[COMPACT_IMP_CLOSED; COMPACT_CONTINUOUS_IMAGE; + CONTINUOUS_ON_SUBSET; BOUNDED_SUBSET; COMPACT_EQ_BOUNDED_CLOSED]);; + +let LOCALLY_PATH_CONNECTED_PATH_IMAGE = prove + (`!p:real^1->real^N. path p ==> locally path_connected (path_image p)`, + REWRITE_TAC[path; path_image] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC LOCALLY_PATH_CONNECTED_CONTINUOUS_IMAGE_COMPACT THEN + ASM_SIMP_TAC[COMPACT_INTERVAL; CONVEX_INTERVAL; + CONVEX_IMP_LOCALLY_PATH_CONNECTED]);; + +let LOCALLY_CONNECTED_PATH_IMAGE = prove + (`!p:real^1->real^N. path p ==> locally connected (path_image p)`, + SIMP_TAC[LOCALLY_PATH_CONNECTED_PATH_IMAGE; + LOCALLY_PATH_CONNECTED_IMP_LOCALLY_CONNECTED]);; + +let LOCALLY_CONNECTED_LEFT_INVERTIBLE_IMAGE = prove + (`!f:real^M->real^N g s. + f continuous_on s /\ g continuous_on (IMAGE f s) /\ + (!x. x IN s ==> g(f x) = x) /\ + locally connected s + ==> locally connected (IMAGE f s)`, + REPEAT GEN_TAC THEN + REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] LOCALLY_CONNECTED_QUOTIENT_IMAGE) THEN + MATCH_MP_TAC CONTINUOUS_LEFT_INVERSE_IMP_QUOTIENT_MAP THEN ASM_MESON_TAC[]);; + +let LOCALLY_CONNECTED_RIGHT_INVERTIBLE_IMAGE = prove + (`!f:real^M->real^N g s. + f continuous_on s /\ g continuous_on (IMAGE f s) /\ + IMAGE g (IMAGE f s) SUBSET s /\ (!x. x IN IMAGE f s ==> f(g x) = x) /\ + locally connected s + ==> locally connected (IMAGE f s)`, + REPEAT GEN_TAC THEN + REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] LOCALLY_CONNECTED_QUOTIENT_IMAGE) THEN + MATCH_MP_TAC CONTINUOUS_RIGHT_INVERSE_IMP_QUOTIENT_MAP THEN + EXISTS_TAC `g:real^N->real^M` THEN ASM SET_TAC[]);; + +let LOCALLY_PATH_CONNECTED_LEFT_INVERTIBLE_IMAGE = prove + (`!f:real^M->real^N g s. + f continuous_on s /\ g continuous_on (IMAGE f s) /\ + (!x. x IN s ==> g(f x) = x) /\ + locally path_connected s + ==> locally path_connected (IMAGE f s)`, + REPEAT GEN_TAC THEN + REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] + LOCALLY_PATH_CONNECTED_QUOTIENT_IMAGE) THEN + MATCH_MP_TAC CONTINUOUS_LEFT_INVERSE_IMP_QUOTIENT_MAP THEN ASM_MESON_TAC[]);; + +let LOCALLY_PATH_CONNECTED_RIGHT_INVERTIBLE_IMAGE = prove + (`!f:real^M->real^N g s. + f continuous_on s /\ g continuous_on (IMAGE f s) /\ + IMAGE g (IMAGE f s) SUBSET s /\ (!x. x IN IMAGE f s ==> f(g x) = x) /\ + locally path_connected s + ==> locally path_connected (IMAGE f s)`, + REPEAT GEN_TAC THEN + REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] + LOCALLY_PATH_CONNECTED_QUOTIENT_IMAGE) THEN + MATCH_MP_TAC CONTINUOUS_RIGHT_INVERSE_IMP_QUOTIENT_MAP THEN + EXISTS_TAC `g:real^N->real^M` THEN ASM SET_TAC[]);; + +let LOCALLY_PCROSS = prove + (`!P Q R. + (!s:real^M->bool t:real^N->bool. P s /\ Q t ==> R(s PCROSS t)) + ==> (!s t. locally P s /\ locally Q t ==> locally R (s PCROSS t))`, + REPEAT STRIP_TAC THEN REWRITE_TAC[locally; FORALL_PASTECART] THEN + MAP_EVERY X_GEN_TAC + [`w:real^(M,N)finite_sum->bool`; `x:real^M`; `y:real^N`] THEN + DISCH_THEN(fun th -> STRIP_ASSUME_TAC th THEN + MP_TAC(MATCH_MP PASTECART_IN_INTERIOR_SUBTOPOLOGY + (ONCE_REWRITE_RULE[CONJ_SYM] th))) THEN + REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`u:real^M->bool`; `v:real^N->bool`] THEN + STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`u:real^M->bool`; `x:real^M`] o + GEN_REWRITE_RULE I [locally]) THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`v:real^N->bool`; `y:real^N`] o + GEN_REWRITE_RULE I [locally]) THEN + ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`v':real^N->bool`; `v'':real^N->bool`] THEN + STRIP_TAC THEN + MAP_EVERY X_GEN_TAC [`u':real^M->bool`; `u'':real^M->bool`] THEN + STRIP_TAC THEN + EXISTS_TAC `(u':real^M->bool) PCROSS (v':real^N->bool)` THEN + EXISTS_TAC `(u'':real^M->bool) PCROSS (v'':real^N->bool)` THEN + ASM_SIMP_TAC[PASTECART_IN_PCROSS; PCROSS_MONO; OPEN_IN_PCROSS] THEN + ASM_MESON_TAC[PCROSS_MONO; SUBSET_TRANS]);; + +let LOCALLY_CONNECTED_PCROSS = prove + (`!s:real^M->bool t:real^N->bool. + locally connected s /\ locally connected t + ==> locally connected (s PCROSS t)`, + MATCH_MP_TAC LOCALLY_PCROSS THEN REWRITE_TAC[CONNECTED_PCROSS]);; + +let LOCALLY_PATH_CONNECTED_PCROSS = prove + (`!s:real^M->bool t:real^N->bool. + locally path_connected s /\ locally path_connected t + ==> locally path_connected (s PCROSS t)`, + MATCH_MP_TAC LOCALLY_PCROSS THEN REWRITE_TAC[PATH_CONNECTED_PCROSS]);; + +let LOCALLY_CONNECTED_PCROSS_EQ = prove + (`!s:real^M->bool t:real^N->bool. + locally connected (s PCROSS t) <=> + s = {} \/ t = {} \/ locally connected s /\ locally connected t`, + REPEAT STRIP_TAC THEN + ASM_CASES_TAC `s:real^M->bool = {}` THEN + ASM_REWRITE_TAC[PCROSS_EMPTY; LOCALLY_EMPTY] THEN + ASM_CASES_TAC `t:real^N->bool = {}` THEN + ASM_REWRITE_TAC[PCROSS_EMPTY; LOCALLY_EMPTY] THEN + EQ_TAC THEN REWRITE_TAC[LOCALLY_CONNECTED_PCROSS] THEN + GEN_REWRITE_TAC LAND_CONV [LOCALLY_CONNECTED] THEN DISCH_TAC THEN + REWRITE_TAC[LOCALLY_CONNECTED_IM_KLEINEN] THEN CONJ_TAC THENL + [MAP_EVERY X_GEN_TAC [`u:real^M->bool`; `x:real^M`] THEN STRIP_TAC THEN + UNDISCH_TAC `~(t:real^N->bool = {})` THEN + REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN + DISCH_THEN(X_CHOOSE_TAC `y:real^N`) THEN + FIRST_X_ASSUM(MP_TAC o SPECL + [`(u:real^M->bool) PCROSS (t:real^N->bool)`; + `pastecart (x:real^M) (y:real^N)`]); + MAP_EVERY X_GEN_TAC [`v:real^N->bool`; `y:real^N`] THEN STRIP_TAC THEN + UNDISCH_TAC `~(s:real^M->bool = {})` THEN + REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN + DISCH_THEN(X_CHOOSE_TAC `x:real^M`) THEN + FIRST_X_ASSUM(MP_TAC o SPECL + [`(s:real^M->bool) PCROSS (v:real^N->bool)`; + `pastecart (x:real^M) (y:real^N)`])] THEN + ASM_SIMP_TAC[OPEN_IN_PCROSS_EQ; PASTECART_IN_PCROSS; SUBSET_UNIV; + OPEN_IN_SUBTOPOLOGY_REFL; TOPSPACE_EUCLIDEAN; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `w:real^(M,N)finite_sum->bool` THEN STRIP_TAC THEN + MP_TAC(ISPECL + [`s:real^M->bool`; `t:real^N->bool`; `w:real^(M,N)finite_sum->bool`; + `x:real^M`; `y:real^N`] PASTECART_IN_INTERIOR_SUBTOPOLOGY) THEN + ASM_REWRITE_TAC[] THENL + [MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `u':real^M->bool` THEN + DISCH_THEN(X_CHOOSE_THEN `v:real^N->bool` STRIP_ASSUME_TAC) THEN + ASM_REWRITE_TAC[] THEN CONJ_TAC THENL + [ALL_TAC; + X_GEN_TAC `z:real^M` THEN DISCH_TAC THEN + EXISTS_TAC `IMAGE fstcart (w:real^(M,N)finite_sum->bool)` THEN + ASM_SIMP_TAC[CONNECTED_LINEAR_IMAGE; LINEAR_FSTCART] THEN + REWRITE_TAC[SUBSET; IN_IMAGE; EXISTS_PASTECART; FSTCART_PASTECART]]; + DISCH_THEN(X_CHOOSE_THEN `u:real^M->bool` MP_TAC) THEN + MATCH_MP_TAC MONO_EXISTS THEN + X_GEN_TAC `v':real^N->bool` THEN STRIP_TAC THEN + ASM_REWRITE_TAC[] THEN CONJ_TAC THENL + [ALL_TAC; + X_GEN_TAC `z:real^N` THEN DISCH_TAC THEN + EXISTS_TAC `IMAGE sndcart (w:real^(M,N)finite_sum->bool)` THEN + ASM_SIMP_TAC[CONNECTED_LINEAR_IMAGE; LINEAR_SNDCART] THEN + REWRITE_TAC[SUBSET; IN_IMAGE; EXISTS_PASTECART; SNDCART_PASTECART]]] THEN + RULE_ASSUM_TAC(REWRITE_RULE + [SUBSET; FORALL_IN_PCROSS; PASTECART_IN_PCROSS; FORALL_PASTECART]) THEN + ASM SET_TAC[]);; + +let LOCALLY_PATH_CONNECTED_PCROSS_EQ = prove + (`!s:real^M->bool t:real^N->bool. + locally path_connected (s PCROSS t) <=> + s = {} \/ t = {} \/ + locally path_connected s /\ locally path_connected t`, + REPEAT STRIP_TAC THEN + ASM_CASES_TAC `s:real^M->bool = {}` THEN + ASM_REWRITE_TAC[PCROSS_EMPTY; LOCALLY_EMPTY] THEN + ASM_CASES_TAC `t:real^N->bool = {}` THEN + ASM_REWRITE_TAC[PCROSS_EMPTY; LOCALLY_EMPTY] THEN + EQ_TAC THEN REWRITE_TAC[LOCALLY_PATH_CONNECTED_PCROSS] THEN + GEN_REWRITE_TAC LAND_CONV [LOCALLY_PATH_CONNECTED] THEN DISCH_TAC THEN + REWRITE_TAC[LOCALLY_PATH_CONNECTED_IM_KLEINEN] THEN CONJ_TAC THENL + [MAP_EVERY X_GEN_TAC [`u:real^M->bool`; `x:real^M`] THEN STRIP_TAC THEN + UNDISCH_TAC `~(t:real^N->bool = {})` THEN + REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN + DISCH_THEN(X_CHOOSE_TAC `y:real^N`) THEN + FIRST_X_ASSUM(MP_TAC o SPECL + [`(u:real^M->bool) PCROSS (t:real^N->bool)`; + `pastecart (x:real^M) (y:real^N)`]); + MAP_EVERY X_GEN_TAC [`v:real^N->bool`; `y:real^N`] THEN STRIP_TAC THEN + UNDISCH_TAC `~(s:real^M->bool = {})` THEN + REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN + DISCH_THEN(X_CHOOSE_TAC `x:real^M`) THEN + FIRST_X_ASSUM(MP_TAC o SPECL + [`(s:real^M->bool) PCROSS (v:real^N->bool)`; + `pastecart (x:real^M) (y:real^N)`])] THEN + ASM_SIMP_TAC[OPEN_IN_PCROSS_EQ; PASTECART_IN_PCROSS; SUBSET_UNIV; + OPEN_IN_SUBTOPOLOGY_REFL; TOPSPACE_EUCLIDEAN; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `w:real^(M,N)finite_sum->bool` THEN STRIP_TAC THEN + MP_TAC(ISPECL + [`s:real^M->bool`; `t:real^N->bool`; `w:real^(M,N)finite_sum->bool`; + `x:real^M`; `y:real^N`] PASTECART_IN_INTERIOR_SUBTOPOLOGY) THEN + ASM_REWRITE_TAC[] THENL + [MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `u':real^M->bool` THEN + DISCH_THEN(X_CHOOSE_THEN `v:real^N->bool` STRIP_ASSUME_TAC) THEN + ASM_REWRITE_TAC[] THEN CONJ_TAC THENL + [ALL_TAC; + X_GEN_TAC `z:real^M` THEN DISCH_TAC THEN + MP_TAC(ISPECL [`fstcart:real^(M,N)finite_sum->real^M`; + `w:real^(M,N)finite_sum->bool`] + PATH_CONNECTED_LINEAR_IMAGE) THEN ASM_REWRITE_TAC[LINEAR_FSTCART] THEN + REWRITE_TAC[path_connected] THEN + DISCH_THEN(MP_TAC o SPECL [`x:real^M`; `z:real^M`]) THEN ANTS_TAC THENL + [REWRITE_TAC[IN_IMAGE; EXISTS_PASTECART; FSTCART_PASTECART]; + MATCH_MP_TAC MONO_EXISTS THEN + REWRITE_TAC[SUBSET; IN_IMAGE; EXISTS_PASTECART; FSTCART_PASTECART] THEN + REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[]]]; + DISCH_THEN(X_CHOOSE_THEN `u:real^M->bool` MP_TAC) THEN + MATCH_MP_TAC MONO_EXISTS THEN + X_GEN_TAC `v':real^N->bool` THEN STRIP_TAC THEN + ASM_REWRITE_TAC[] THEN CONJ_TAC THENL + [ALL_TAC; + X_GEN_TAC `z:real^N` THEN DISCH_TAC THEN + MP_TAC(ISPECL [`sndcart:real^(M,N)finite_sum->real^N`; + `w:real^(M,N)finite_sum->bool`] + PATH_CONNECTED_LINEAR_IMAGE) THEN ASM_REWRITE_TAC[LINEAR_SNDCART] THEN + REWRITE_TAC[path_connected] THEN + DISCH_THEN(MP_TAC o SPECL [`y:real^N`; `z:real^N`]) THEN ANTS_TAC THENL + [REWRITE_TAC[IN_IMAGE; EXISTS_PASTECART; SNDCART_PASTECART]; + MATCH_MP_TAC MONO_EXISTS THEN + REWRITE_TAC[SUBSET; IN_IMAGE; EXISTS_PASTECART; SNDCART_PASTECART] THEN + REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[]]]] THEN + RULE_ASSUM_TAC(REWRITE_RULE + [SUBSET; FORALL_IN_PCROSS; PASTECART_IN_PCROSS; FORALL_PASTECART]) THEN + ASM SET_TAC[]);; + +let CARD_EQ_OPEN_IN = prove + (`!u s:real^N->bool. + locally connected u /\ + open_in (subtopology euclidean u) s /\ + (?x. x IN s /\ x limit_point_of u) + ==> s =_c (:real)`, + REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM CARD_LE_ANTISYM] THEN CONJ_TAC THENL + [TRANS_TAC CARD_LE_TRANS `(:real^N)` THEN + SIMP_TAC[CARD_EQ_IMP_LE; CARD_EQ_EUCLIDEAN] THEN + MATCH_MP_TAC CARD_LE_SUBSET THEN REWRITE_TAC[SUBSET_UNIV]; + ALL_TAC] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [OPEN_IN_OPEN]) THEN + DISCH_THEN(X_CHOOSE_THEN `t:real^N->bool` STRIP_ASSUME_TAC) THEN + UNDISCH_TAC `(x:real^N) IN s` THEN ASM_REWRITE_TAC[IN_INTER] THEN + STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [LOCALLY_CONNECTED]) THEN + DISCH_THEN(MP_TAC o SPECL [`u INTER t:real^N->bool`; `x:real^N`]) THEN + ASM_SIMP_TAC[OPEN_IN_OPEN_INTER; IN_INTER] THEN + REWRITE_TAC[OPEN_IN_OPEN; GSYM CONJ_ASSOC; LEFT_AND_EXISTS_THM] THEN + ONCE_REWRITE_TAC[SWAP_EXISTS_THM] THEN + ONCE_REWRITE_TAC[TAUT `p /\ q /\ r <=> q /\ p /\ r`] THEN + REWRITE_TAC[UNWIND_THM2; IN_INTER] THEN + DISCH_THEN(X_CHOOSE_THEN `v:real^N->bool` STRIP_ASSUME_TAC) THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [limit_point_of]) THEN + DISCH_THEN(MP_TAC o SPEC `t INTER v:real^N->bool`) THEN + ASM_SIMP_TAC[IN_INTER; OPEN_INTER] THEN + DISCH_THEN(X_CHOOSE_THEN `y:real^N` STRIP_ASSUME_TAC) THEN + TRANS_TAC CARD_LE_TRANS `u INTER v:real^N->bool` THEN + ASM_SIMP_TAC[CARD_LE_SUBSET] THEN MATCH_MP_TAC CARD_EQ_IMP_LE THEN + ONCE_REWRITE_TAC[CARD_EQ_SYM] THEN MATCH_MP_TAC CARD_EQ_CONNECTED THEN + ASM SET_TAC[]);; + +let CARD_EQ_OPEN_IN_AFFINE = prove + (`!u s:real^N->bool. + affine u /\ ~(aff_dim u = &0) /\ + open_in (subtopology euclidean u) s /\ ~(s = {}) + ==> s =_c (:real)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC CARD_EQ_OPEN_IN THEN + EXISTS_TAC `u:real^N->bool` THEN + ASM_SIMP_TAC[CONVEX_IMP_LOCALLY_CONNECTED; AFFINE_IMP_CONVEX] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `x:real^N` THEN STRIP_TAC THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC CONNECTED_IMP_PERFECT_AFF_DIM THEN + ASM_SIMP_TAC[AFFINE_IMP_CONVEX; CONVEX_CONNECTED] THEN + FIRST_X_ASSUM(MP_TAC o MATCH_MP OPEN_IN_IMP_SUBSET) THEN ASM SET_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* Basic properties of local compactness. *) +(* ------------------------------------------------------------------------- *) + +let LOCALLY_COMPACT = prove + (`!s:real^N->bool. + locally compact s <=> + !x. x IN s ==> ?u v. x IN u /\ u SUBSET v /\ v SUBSET s /\ + open_in (subtopology euclidean s) u /\ + compact v`, + GEN_TAC THEN REWRITE_TAC[locally] THEN EQ_TAC THEN DISCH_TAC THENL + [X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN FIRST_X_ASSUM + (MP_TAC o SPECL [`s INTER ball(x:real^N,&1)`; `x:real^N`]) THEN + ASM_SIMP_TAC[OPEN_IN_OPEN_INTER; OPEN_BALL] THEN + ASM_REWRITE_TAC[IN_INTER; CENTRE_IN_BALL; REAL_LT_01] THEN + MESON_TAC[SUBSET_INTER]; + MAP_EVERY X_GEN_TAC [`w:real^N->bool`; `x:real^N`] THEN + REWRITE_TAC[IMP_CONJ] THEN GEN_REWRITE_TAC LAND_CONV [OPEN_IN_OPEN] THEN + DISCH_THEN(X_CHOOSE_THEN `t:real^N->bool` STRIP_ASSUME_TAC) THEN + ASM_REWRITE_TAC[IN_INTER] THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `x:real^N`) THEN + ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`u:real^N->bool`; `v:real^N->bool`] THEN + STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [OPEN_CONTAINS_CBALL]) THEN + DISCH_THEN(MP_TAC o SPEC `x:real^N`) THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `e:real` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `(s INTER ball(x:real^N,e)) INTER u` THEN + EXISTS_TAC `cball(x:real^N,e) INTER v` THEN + ASM_SIMP_TAC[OPEN_IN_INTER; OPEN_IN_OPEN_INTER; OPEN_BALL; CENTRE_IN_BALL; + COMPACT_INTER; COMPACT_CBALL; IN_INTER] THEN + MP_TAC(ISPECL [`x:real^N`; `e:real`] BALL_SUBSET_CBALL) THEN + ASM SET_TAC[]]);; + +let OPEN_IMP_LOCALLY_COMPACT = prove + (`!s:real^N->bool. open s ==> locally compact s`, + REPEAT STRIP_TAC THEN REWRITE_TAC[LOCALLY_COMPACT] THEN + X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN FIRST_ASSUM + (MP_TAC o GEN_REWRITE_RULE I [OPEN_CONTAINS_CBALL]) THEN + DISCH_THEN(MP_TAC o SPEC `x:real^N`) THEN + ANTS_TAC THENL [ASM_REWRITE_TAC[]; ALL_TAC] THEN + DISCH_THEN(X_CHOOSE_THEN `e:real` STRIP_ASSUME_TAC) THEN + MAP_EVERY EXISTS_TAC [`ball(x:real^N,e)`; `cball(x:real^N,e)`] THEN + ASM_REWRITE_TAC[BALL_SUBSET_CBALL; CENTRE_IN_BALL; COMPACT_CBALL] THEN + MATCH_MP_TAC OPEN_OPEN_IN_TRANS THEN ASM_REWRITE_TAC[OPEN_BALL] THEN + ASM_MESON_TAC[BALL_SUBSET_CBALL; SUBSET_TRANS]);; + +let CLOSED_IMP_LOCALLY_COMPACT = prove + (`!s:real^N->bool. closed s ==> locally compact s`, + REPEAT STRIP_TAC THEN REWRITE_TAC[LOCALLY_COMPACT] THEN + X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN MAP_EVERY EXISTS_TAC + [`s INTER ball(x:real^N,&1)`; `s INTER cball(x:real^N,&1)`] THEN + ASM_REWRITE_TAC[IN_INTER; CENTRE_IN_BALL; INTER_SUBSET; REAL_LT_01] THEN + ASM_SIMP_TAC[OPEN_IN_OPEN_INTER; OPEN_BALL] THEN + ASM_SIMP_TAC[CLOSED_INTER_COMPACT; COMPACT_CBALL] THEN + MP_TAC(ISPECL [`x:real^N`; `&1`] BALL_SUBSET_CBALL) THEN ASM SET_TAC[]);; + +let IS_INTERVAL_IMP_LOCALLY_COMPACT = prove + (`!s:real^N->bool. is_interval s ==> locally compact s`, + REPEAT STRIP_TAC THEN REWRITE_TAC[LOCALLY_COMPACT] THEN + X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN + MP_TAC(ISPECL [`s:real^N->bool`; `x:real^N`] + INTERVAL_CONTAINS_COMPACT_NEIGHBOURHOOD) THEN + ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`a:real^N`; `b:real^N`; `d:real`] THEN STRIP_TAC THEN + MAP_EVERY EXISTS_TAC + [`s INTER ball(x:real^N,d)`; `interval[a:real^N,b]`] THEN + ASM_SIMP_TAC[COMPACT_INTERVAL; OPEN_IN_OPEN_INTER; OPEN_BALL] THEN + ASM_REWRITE_TAC[CENTRE_IN_BALL; IN_INTER] THEN ASM SET_TAC[]);; + +let LOCALLY_COMPACT_UNIV = prove + (`locally compact (:real^N)`, + SIMP_TAC[OPEN_IMP_LOCALLY_COMPACT; OPEN_UNIV]);; + +let LOCALLY_COMPACT_INTER = prove + (`!s t:real^N->bool. + locally compact s /\ locally compact t + ==> locally compact (s INTER t)`, + MATCH_MP_TAC LOCALLY_INTER THEN REWRITE_TAC[COMPACT_INTER]);; + +let LOCALLY_COMPACT_OPEN_IN = prove + (`!s t:real^N->bool. + open_in (subtopology euclidean s) t /\ locally compact s + ==> locally compact t`, + REWRITE_TAC[OPEN_IN_OPEN] THEN REPEAT STRIP_TAC THEN + ASM_SIMP_TAC[LOCALLY_COMPACT_INTER; OPEN_IMP_LOCALLY_COMPACT]);; + +let LOCALLY_COMPACT_CLOSED_IN = prove + (`!s t:real^N->bool. + closed_in (subtopology euclidean s) t /\ locally compact s + ==> locally compact t`, + REWRITE_TAC[CLOSED_IN_CLOSED] THEN REPEAT STRIP_TAC THEN + ASM_SIMP_TAC[LOCALLY_COMPACT_INTER; CLOSED_IMP_LOCALLY_COMPACT]);; + +let SIGMA_COMPACT = prove + (`!s:real^N->bool. + locally compact s + ==> ?f. COUNTABLE f /\ (!t. t IN f ==> compact t) /\ UNIONS f = s`, + GEN_TAC THEN REWRITE_TAC[LOCALLY_COMPACT] THEN + GEN_REWRITE_TAC (LAND_CONV o TOP_DEPTH_CONV) [RIGHT_IMP_EXISTS_THM] THEN + REWRITE_TAC[SKOLEM_THM; LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`u:real^N->real^N->bool`; `c:real^N->real^N->bool`] THEN + DISCH_TAC THEN + MP_TAC(ISPECL [`IMAGE (u:real^N->real^N->bool) s`; `s:real^N->bool`] + LINDELOF_OPEN_IN) THEN + ASM_SIMP_TAC[FORALL_IN_IMAGE] THEN + ONCE_REWRITE_TAC[TAUT `p /\ q /\ r <=> q /\ p /\ r`] THEN + REWRITE_TAC[EXISTS_COUNTABLE_SUBSET_IMAGE] THEN + DISCH_THEN(X_CHOOSE_THEN `t:real^N->bool` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `IMAGE (c:real^N->real^N->bool) t` THEN + REWRITE_TAC[GSYM SUBSET_ANTISYM_EQ; FORALL_IN_IMAGE; FORALL_IN_UNIONS] THEN + ASM_SIMP_TAC[COUNTABLE_IMAGE] THEN ASM SET_TAC[]);; + +let HOMEOMORPHIC_LOCAL_COMPACTNESS = prove + (`!s t:real^N->bool. + s homeomorphic t ==> (locally compact s <=> locally compact t)`, + MATCH_MP_TAC HOMEOMORPHIC_LOCALLY THEN + REWRITE_TAC[HOMEOMORPHIC_COMPACTNESS]);; + +let LOCALLY_COMPACT_TRANSLATION_EQ = prove + (`!a:real^N s. locally compact (IMAGE (\x. a + x) s) <=> + locally compact s`, + MATCH_MP_TAC LOCALLY_TRANSLATION THEN + REWRITE_TAC[COMPACT_TRANSLATION_EQ]);; + +add_translation_invariants [LOCALLY_COMPACT_TRANSLATION_EQ];; + +let LOCALLY_COMPACT_LINEAR_IMAGE_EQ = prove + (`!f:real^M->real^N s. + linear f /\ (!x y. f x = f y ==> x = y) + ==> (locally compact (IMAGE f s) <=> locally compact s)`, + MATCH_MP_TAC LOCALLY_INJECTIVE_LINEAR_IMAGE THEN + REWRITE_TAC[COMPACT_LINEAR_IMAGE_EQ]);; + +add_linear_invariants [LOCALLY_COMPACT_LINEAR_IMAGE_EQ];; + +let LOCALLY_CLOSED = prove + (`!s:real^N->bool. locally closed s <=> locally compact s`, + GEN_TAC THEN EQ_TAC THENL + [ALL_TAC; MESON_TAC[LOCALLY_MONO; COMPACT_IMP_CLOSED]] THEN + REWRITE_TAC[locally] THEN DISCH_TAC THEN + MAP_EVERY X_GEN_TAC [`w:real^N->bool`; `x:real^N`] THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`w:real^N->bool`; `x:real^N`]) THEN + ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`u:real^N->bool`; `v:real^N->bool`] THEN + STRIP_TAC THEN + EXISTS_TAC `u INTER ball(x:real^N,&1)` THEN + EXISTS_TAC `v INTER cball(x:real^N,&1)` THEN + ASM_SIMP_TAC[OPEN_IN_INTER_OPEN; OPEN_BALL] THEN + ASM_SIMP_TAC[CLOSED_INTER_COMPACT; COMPACT_CBALL] THEN + ASM_REWRITE_TAC[IN_INTER; CENTRE_IN_BALL; REAL_LT_01] THEN + MP_TAC(ISPEC `x:real^N` BALL_SUBSET_CBALL) THEN ASM SET_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* Locally compact sets are closed in an open set and are homeomorphic *) +(* to an absolutely closed set if we have one more dimension to play with. *) +(* ------------------------------------------------------------------------- *) + +let LOCALLY_COMPACT_OPEN_INTER_CLOSURE = prove + (`!s:real^N->bool. locally compact s ==> ?t. open t /\ s = t INTER closure s`, + GEN_TAC THEN SIMP_TAC[LOCALLY_COMPACT; OPEN_IN_OPEN; CLOSED_IN_CLOSED] THEN + REWRITE_TAC[LEFT_AND_EXISTS_THM; RIGHT_AND_EXISTS_THM] THEN + REWRITE_TAC[GSYM CONJ_ASSOC; TAUT `p /\ x = y /\ q <=> x = y /\ p /\ q`] THEN + ONCE_REWRITE_TAC[MESON[] `(?a b c. P a b c) <=> (?c b a. P a b c)`] THEN + REWRITE_TAC[UNWIND_THM2] THEN + GEN_REWRITE_TAC (LAND_CONV o TOP_DEPTH_CONV) [RIGHT_IMP_EXISTS_THM] THEN + REWRITE_TAC[SKOLEM_THM; LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`u:real^N->real^N->bool`; `v:real^N->real^N->bool`] THEN + DISCH_TAC THEN EXISTS_TAC `UNIONS (IMAGE (u:real^N->real^N->bool) s)` THEN + ASM_SIMP_TAC[CLOSED_CLOSURE; OPEN_UNIONS; FORALL_IN_IMAGE] THEN + REWRITE_TAC[INTER_UNIONS] THEN MATCH_MP_TAC EQ_TRANS THEN EXISTS_TAC + `UNIONS {v INTER s | v | v IN IMAGE (u:real^N->real^N->bool) s}` THEN + CONJ_TAC THENL + [SIMP_TAC[UNIONS_GSPEC; EXISTS_IN_IMAGE] THEN ASM SET_TAC[]; ALL_TAC] THEN + AP_TERM_TAC THEN MATCH_MP_TAC(SET_RULE + `(!x. x IN s ==> f(g x) = f'(g x)) + ==> {f x | x IN IMAGE g s} = {f' x | x IN IMAGE g s}`) THEN + X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN + REWRITE_TAC[GSYM SUBSET_ANTISYM_EQ] THEN CONJ_TAC THENL + [MP_TAC(ISPEC `s:real^N->bool` CLOSURE_SUBSET) THEN ASM SET_TAC[]; + REWRITE_TAC[SUBSET_INTER; INTER_SUBSET] THEN MATCH_MP_TAC SUBSET_TRANS THEN + EXISTS_TAC `closure((u:real^N->real^N->bool) x INTER s)` THEN + ASM_SIMP_TAC[OPEN_INTER_CLOSURE_SUBSET] THEN MATCH_MP_TAC SUBSET_TRANS THEN + EXISTS_TAC `(v:real^N->real^N->bool) x` THEN + ASM_SIMP_TAC[] THEN MATCH_MP_TAC CLOSURE_MINIMAL THEN + ASM_SIMP_TAC[COMPACT_IMP_CLOSED] THEN ASM SET_TAC[]]);; + +let LOCALLY_COMPACT_CLOSED_IN_OPEN = prove + (`!s:real^N->bool. + locally compact s ==> ?t. open t /\ closed_in (subtopology euclidean t) s`, + GEN_TAC THEN + DISCH_THEN(MP_TAC o MATCH_MP LOCALLY_COMPACT_OPEN_INTER_CLOSURE) THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `t:real^N->bool` THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + FIRST_X_ASSUM SUBST1_TAC THEN + SIMP_TAC[CLOSED_IN_CLOSED_INTER; CLOSED_CLOSURE]);; + +let LOCALLY_COMPACT_HOMEOMORPHISM_PROJECTION_CLOSED = prove + (`!s:real^M->bool. + locally compact s + ==> ?t:real^(M,N)finite_sum->bool f. + closed t /\ homeomorphism (s,t) (f,fstcart)`, + REPEAT STRIP_TAC THEN ASM_CASES_TAC `closed(s:real^M->bool)` THENL + [EXISTS_TAC `(s:real^M->bool) PCROSS {vec 0:real^N}` THEN + EXISTS_TAC `\x. (pastecart x (vec 0):real^(M,N)finite_sum)` THEN + ASM_SIMP_TAC[CLOSED_PCROSS; CLOSED_SING; HOMEOMORPHISM] THEN + SIMP_TAC[CONTINUOUS_ON_PASTECART; CONTINUOUS_ON_CONST; CONTINUOUS_ON_ID; + LINEAR_FSTCART; LINEAR_CONTINUOUS_ON; SUBSET; FORALL_IN_IMAGE] THEN + REWRITE_TAC[FORALL_IN_PCROSS; PASTECART_IN_PCROSS; IN_SING] THEN + SIMP_TAC[FSTCART_PASTECART]; + ALL_TAC] THEN + FIRST_X_ASSUM(MP_TAC o MATCH_MP LOCALLY_COMPACT_OPEN_INTER_CLOSURE) THEN + DISCH_THEN(X_CHOOSE_THEN `t:real^M->bool` (STRIP_ASSUME_TAC o GSYM)) THEN + DISJ_CASES_TAC(SET_RULE `t = (:real^M) \/ ~((:real^M) DIFF t = {})`) THENL + [ASM_MESON_TAC[CLOSURE_EQ; INTER_UNIV]; ALL_TAC] THEN + ABBREV_TAC + `f:real^M->real^(M,N)finite_sum = + \x. pastecart x (inv(setdist({x},(:real^M) DIFF t)) % vec 1)` THEN + SUBGOAL_THEN + `homeomorphism (t,IMAGE (f:real^M->real^(M,N)finite_sum) t) (f,fstcart)` + ASSUME_TAC THENL + [SIMP_TAC[HOMEOMORPHISM; SUBSET_REFL; LINEAR_CONTINUOUS_ON; + LINEAR_FSTCART; FORALL_IN_IMAGE] THEN + MATCH_MP_TAC(TAUT `(r ==> q /\ s) /\ r /\ p ==> p /\ q /\ r /\ s`) THEN + CONJ_TAC THENL [SET_TAC[]; EXPAND_TAC "f"] THEN + SIMP_TAC[FSTCART_PASTECART] THEN MATCH_MP_TAC CONTINUOUS_ON_PASTECART THEN + REWRITE_TAC[CONTINUOUS_ON_ID] THEN MATCH_MP_TAC CONTINUOUS_ON_MUL THEN + REWRITE_TAC[o_DEF; CONTINUOUS_ON_CONST] THEN + MATCH_MP_TAC(REWRITE_RULE[o_DEF] CONTINUOUS_ON_INV) THEN + REWRITE_TAC[SETDIST_EQ_0_SING; CONTINUOUS_ON_LIFT_SETDIST] THEN + ASM_SIMP_TAC[CLOSURE_COMPLEMENT; IN_DIFF; IN_UNIV; INTERIOR_OPEN]; + ALL_TAC] THEN + EXISTS_TAC `IMAGE (f:real^M->real^(M,N)finite_sum) s` THEN + EXISTS_TAC `f:real^M->real^(M,N)finite_sum` THEN CONJ_TAC THENL + [MATCH_MP_TAC CLOSED_IN_CLOSED_TRANS THEN + EXISTS_TAC `IMAGE (f:real^M->real^(M,N)finite_sum) t` THEN CONJ_TAC THENL + [MATCH_MP_TAC HOMEOMORPHISM_IMP_CLOSED_MAP THEN MAP_EVERY EXISTS_TAC + [`fstcart:real^(M,N)finite_sum->real^M`; `t:real^M->bool`] THEN + ASM_REWRITE_TAC[] THEN EXPAND_TAC "s" THEN + SIMP_TAC[CLOSED_IN_CLOSED_INTER; CLOSED_CLOSURE]; + SUBGOAL_THEN + `IMAGE (f:real^M->real^(M,N)finite_sum) t = + {z | (setdist({fstcart z},(:real^M) DIFF t) % sndcart z) IN {vec 1}}` + SUBST1_TAC THENL + [EXPAND_TAC "f" THEN + REWRITE_TAC[EXTENSION; FORALL_PASTECART; IN_ELIM_THM; PASTECART_INJ; + FSTCART_PASTECART; SNDCART_PASTECART; IN_IMAGE; IN_INTER; + GSYM CONJ_ASSOC; UNWIND_THM1; IN_SING] THEN + REWRITE_TAC[CART_EQ; VECTOR_MUL_COMPONENT; VEC_COMPONENT] THEN + MAP_EVERY X_GEN_TAC [`x:real^M`; `y:real^N`] THEN + MP_TAC(ISPECL [`(:real^M) DIFF t`; `x:real^M`] + (CONJUNCT1 SETDIST_EQ_0_SING)) THEN + ASM_SIMP_TAC[CLOSURE_COMPLEMENT; IN_DIFF; IN_UNIV; INTERIOR_OPEN] THEN + ASM_CASES_TAC `(x:real^M) IN t` THEN ASM_SIMP_TAC[REAL_FIELD + `~(x = &0) ==> (y = inv x * &1 <=> x * y = &1)`] THEN + DISCH_TAC THEN DISCH_THEN(MP_TAC o SPEC `1`) THEN + REWRITE_TAC[LE_REFL; DIMINDEX_GE_1] THEN REAL_ARITH_TAC; + MATCH_MP_TAC CONTINUOUS_CLOSED_PREIMAGE_UNIV THEN + REWRITE_TAC[CLOSED_SING] THEN X_GEN_TAC `z:real^(M,N)finite_sum` THEN + MATCH_MP_TAC CONTINUOUS_MUL THEN + SIMP_TAC[LINEAR_CONTINUOUS_AT; LINEAR_SNDCART; o_DEF] THEN + SUBGOAL_THEN + `(\z:real^(M,N)finite_sum. + lift(setdist({fstcart z},(:real^M) DIFF t))) = + (\x. lift (setdist ({x},(:real^M) DIFF t))) o fstcart` + SUBST1_TAC THENL [REWRITE_TAC[o_DEF]; ALL_TAC] THEN + MATCH_MP_TAC CONTINUOUS_AT_COMPOSE THEN + SIMP_TAC[LINEAR_CONTINUOUS_AT; LINEAR_FSTCART] THEN + REWRITE_TAC[CONTINUOUS_AT_LIFT_SETDIST]]]; + MATCH_MP_TAC HOMEOMORPHISM_OF_SUBSETS THEN MAP_EVERY EXISTS_TAC + [`t:real^M->bool`; `IMAGE (f:real^M->real^(M,N)finite_sum) t`] THEN + ASM SET_TAC[]]);; + +let LOCALLY_COMPACT_HOMEOMORPHIC_CLOSED = prove + (`!s:real^M->bool. + locally compact s /\ dimindex(:M) < dimindex(:N) + ==> ?t:real^N->bool. closed t /\ s homeomorphic t`, + REPEAT STRIP_TAC THEN SUBGOAL_THEN + `?t:real^(M,1)finite_sum->bool h. + closed t /\ homeomorphism (s,t) (h,fstcart)` + STRIP_ASSUME_TAC THENL + [ASM_SIMP_TAC[LOCALLY_COMPACT_HOMEOMORPHISM_PROJECTION_CLOSED]; + ALL_TAC] THEN + ABBREV_TAC + `f:real^(M,1)finite_sum->real^N = + \x. lambda i. if i <= dimindex(:M) then x$i + else x$(dimindex(:M)+1)` THEN + ABBREV_TAC + `g:real^N->real^(M,1)finite_sum = (\x. lambda i. x$i)` THEN + EXISTS_TAC `IMAGE (f:real^(M,1)finite_sum->real^N) t` THEN + SUBGOAL_THEN `linear(f:real^(M,1)finite_sum->real^N)` ASSUME_TAC THENL + [EXPAND_TAC "f" THEN REWRITE_TAC[linear; CART_EQ] THEN + SIMP_TAC[LAMBDA_BETA; VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT] THEN + MESON_TAC[]; + ALL_TAC] THEN + SUBGOAL_THEN `linear(g:real^N->real^(M,1)finite_sum)` ASSUME_TAC THENL + [EXPAND_TAC "g" THEN REWRITE_TAC[linear; CART_EQ] THEN + SIMP_TAC[LAMBDA_BETA; VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT] THEN + MESON_TAC[]; + ALL_TAC] THEN + SUBGOAL_THEN + `!x. (g:real^N->real^(M,1)finite_sum)((f:real^(M,1)finite_sum->real^N) x) = + x` + ASSUME_TAC THENL + [MAP_EVERY EXPAND_TAC ["f"; "g"] THEN FIRST_ASSUM(MP_TAC o MATCH_MP + (ARITH_RULE `m < n ==> !i. i <= m + 1 ==> i <= n`)) THEN + SIMP_TAC[CART_EQ; LAMBDA_BETA; DIMINDEX_FINITE_SUM; DIMINDEX_1] THEN + REWRITE_TAC[ARITH_RULE `i <= n + 1 <=> i <= n \/ i = n + 1`] THEN + MESON_TAC[]; + ALL_TAC] THEN + CONJ_TAC THENL [ASM_MESON_TAC[CLOSED_INJECTIVE_LINEAR_IMAGE]; ALL_TAC] THEN + TRANS_TAC HOMEOMORPHIC_TRANS `t:real^(M,1)finite_sum->bool` THEN + CONJ_TAC THENL [ASM_MESON_TAC[homeomorphic]; ALL_TAC] THEN + REWRITE_TAC[homeomorphic; HOMEOMORPHISM] THEN MAP_EVERY EXISTS_TAC + [`f:real^(M,1)finite_sum->real^N`; `g:real^N->real^(M,1)finite_sum`] THEN + ASM_SIMP_TAC[LINEAR_CONTINUOUS_ON] THEN ASM SET_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* Relations between components and path components. *) +(* ------------------------------------------------------------------------- *) + +let OPEN_CONNECTED_COMPONENT = prove + (`!s x:real^N. open s ==> open(connected_component s x)`, + REPEAT GEN_TAC THEN REWRITE_TAC[OPEN_CONTAINS_BALL] THEN + DISCH_TAC THEN X_GEN_TAC `y:real^N` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `y:real^N`) THEN + ANTS_TAC THENL + [ASM_MESON_TAC[SUBSET; CONNECTED_COMPONENT_SUBSET]; ALL_TAC] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `e:real` THEN STRIP_TAC THEN + ASM_REWRITE_TAC[] THEN + SUBGOAL_THEN `connected_component s (x:real^N) = connected_component s y` + SUBST1_TAC THENL + [ASM_MESON_TAC[CONNECTED_COMPONENT_EQ]; + MATCH_MP_TAC CONNECTED_COMPONENT_MAXIMAL THEN + ASM_REWRITE_TAC[CENTRE_IN_BALL; CONNECTED_BALL]]);; + +let IN_CLOSURE_CONNECTED_COMPONENT = prove + (`!x y:real^N. + x IN s /\ open s + ==> (x IN closure(connected_component s y) <=> + x IN connected_component s y)`, + REPEAT STRIP_TAC THEN EQ_TAC THEN + REWRITE_TAC[REWRITE_RULE[SUBSET] CLOSURE_SUBSET] THEN + DISCH_TAC THEN SUBGOAL_THEN + `~((connected_component s (x:real^N)) INTER + closure(connected_component s y) = {})` + MP_TAC THENL + [REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN EXISTS_TAC `x:real^N` THEN + ASM_REWRITE_TAC[IN_INTER] THEN + ASM_REWRITE_TAC[IN; CONNECTED_COMPONENT_REFL_EQ]; + ASM_SIMP_TAC[OPEN_INTER_CLOSURE_EQ_EMPTY; OPEN_CONNECTED_COMPONENT] THEN + REWRITE_TAC[CONNECTED_COMPONENT_OVERLAP] THEN + STRIP_TAC THEN FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN + ASM_REWRITE_TAC[IN; CONNECTED_COMPONENT_REFL_EQ]]);; + +let PATH_COMPONENT_SUBSET_CONNECTED_COMPONENT = prove + (`!s x:real^N. (path_component s x) SUBSET (connected_component s x)`, + REPEAT STRIP_TAC THEN + ASM_CASES_TAC `(x:real^N) IN s` THENL + [MATCH_MP_TAC CONNECTED_COMPONENT_MAXIMAL THEN + ASM_REWRITE_TAC[PATH_COMPONENT_SUBSET; IN; PATH_COMPONENT_REFL_EQ] THEN + SIMP_TAC[PATH_CONNECTED_IMP_CONNECTED; PATH_CONNECTED_PATH_COMPONENT]; + ASM_MESON_TAC[PATH_COMPONENT_EQ_EMPTY; SUBSET_REFL; + CONNECTED_COMPONENT_EQ_EMPTY]]);; + +let PATH_COMPONENT_EQ_CONNECTED_COMPONENT = prove + (`!s x:real^N. + locally path_connected s + ==> (path_component s x = connected_component s x)`, + REPEAT STRIP_TAC THEN + ASM_CASES_TAC `(x:real^N) IN s` THENL + [ALL_TAC; + ASM_MESON_TAC[PATH_COMPONENT_EQ_EMPTY; CONNECTED_COMPONENT_EQ_EMPTY]] THEN + MP_TAC(ISPECL[`s:real^N->bool`; `x:real^N`] + CONNECTED_CONNECTED_COMPONENT) THEN REWRITE_TAC[CONNECTED_CLOPEN] THEN + REWRITE_TAC[TAUT `p ==> q \/ r <=> p /\ ~q ==> r`] THEN + DISCH_THEN MATCH_MP_TAC THEN + ASM_REWRITE_TAC[PATH_COMPONENT_EQ_EMPTY] THEN CONJ_TAC THENL + [MATCH_MP_TAC OPEN_IN_SUBSET_TRANS; + MATCH_MP_TAC CLOSED_IN_SUBSET_TRANS] THEN + EXISTS_TAC `s:real^N->bool` THEN + ASM_SIMP_TAC[OPEN_IN_PATH_COMPONENT_LOCALLY_PATH_CONNECTED; + CLOSED_IN_PATH_COMPONENT_LOCALLY_PATH_CONNECTED; + PATH_COMPONENT_SUBSET_CONNECTED_COMPONENT; + CONNECTED_COMPONENT_SUBSET]);; + +let LOCALLY_PATH_CONNECTED_PATH_COMPONENT = prove + (`!s x:real^N. + locally path_connected s + ==> locally path_connected (path_component s x)`, + MESON_TAC[LOCALLY_PATH_CONNECTED_CONNECTED_COMPONENT; + PATH_COMPONENT_EQ_CONNECTED_COMPONENT]);; + +let OPEN_PATH_CONNECTED_COMPONENT = prove + (`!s x:real^N. open s ==> path_component s x = connected_component s x`, + SIMP_TAC[PATH_COMPONENT_EQ_CONNECTED_COMPONENT; + OPEN_IMP_LOCALLY_PATH_CONNECTED]);; + +let PATH_CONNECTED_EQ_CONNECTED_LPC = prove + (`!s. locally path_connected s ==> (path_connected s <=> connected s)`, + REWRITE_TAC[PATH_CONNECTED_IFF_PATH_COMPONENT; + CONNECTED_IFF_CONNECTED_COMPONENT] THEN + SIMP_TAC[PATH_COMPONENT_EQ_CONNECTED_COMPONENT]);; + +let PATH_CONNECTED_EQ_CONNECTED = prove + (`!s. open s ==> (path_connected s <=> connected s)`, + SIMP_TAC[PATH_CONNECTED_EQ_CONNECTED_LPC; OPEN_IMP_LOCALLY_PATH_CONNECTED]);; + +let CONNECTED_OPEN_PATH_CONNECTED = prove + (`!s:real^N->bool. open s /\ connected s ==> path_connected s`, + SIMP_TAC[PATH_CONNECTED_EQ_CONNECTED]);; + +let CONNECTED_OPEN_ARC_CONNECTED = prove + (`!s:real^N->bool. + open s /\ connected s + ==> !x y. x IN s /\ y IN s + ==> x = y \/ + ?g. arc g /\ + path_image g SUBSET s /\ + pathstart g = x /\ + pathfinish g = y`, + GEN_TAC THEN DISCH_THEN(MP_TAC o MATCH_MP CONNECTED_OPEN_PATH_CONNECTED) THEN + REWRITE_TAC[PATH_CONNECTED_ARCWISE] THEN + REPEAT(MATCH_MP_TAC MONO_FORALL THEN GEN_TAC) THEN MESON_TAC[]);; + +let OPEN_COMPONENTS = prove + (`!u:real^N->bool s. open u /\ s IN components u ==> open s`, + REPEAT STRIP_TAC THEN STRIP_ASSUME_TAC (MESON[IN_COMPONENTS; + ASSUME `s:real^N->bool IN components u`] `?x. s:real^N->bool = + connected_component u x`) THEN ASM_SIMP_TAC [OPEN_CONNECTED_COMPONENT]);; + +let COMPONENTS_OPEN_UNIQUE = prove + (`!f:(real^N->bool)->bool s. + (!c. c IN f ==> open c /\ connected c /\ ~(c = {})) /\ + pairwise DISJOINT f /\ UNIONS f = s + ==> components s = f`, + REPEAT STRIP_TAC THEN + MATCH_MP_TAC CONNECTED_DISJOINT_UNIONS_OPEN_UNIQUE THEN + ASM_REWRITE_TAC[GSYM UNIONS_COMPONENTS; PAIRWISE_DISJOINT_COMPONENTS] THEN + ASM_MESON_TAC[OPEN_COMPONENTS; IN_COMPONENTS_NONEMPTY; + IN_COMPONENTS_CONNECTED; OPEN_UNIONS]);; + +let CONTINUOUS_ON_COMPONENTS = prove + (`!f:real^M->real^N s. + open s /\ (!c. c IN components s ==> f continuous_on c) + ==> f continuous_on s`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC CONTINUOUS_ON_COMPONENTS_GEN THEN + ASM_SIMP_TAC[] THEN REPEAT STRIP_TAC THEN MATCH_MP_TAC OPEN_SUBSET THEN + ASM_MESON_TAC[OPEN_COMPONENTS; IN_COMPONENTS_SUBSET]);; + +let CONTINUOUS_ON_COMPONENTS_EQ = prove + (`!f s. open s + ==> (f continuous_on s <=> + !c. c IN components s ==> f continuous_on c)`, + REPEAT STRIP_TAC THEN EQ_TAC THENL + [MESON_TAC[CONTINUOUS_ON_SUBSET; IN_COMPONENTS_SUBSET]; + ASM_MESON_TAC[CONTINUOUS_ON_COMPONENTS]]);; + +let CLOSED_IN_UNION_COMPLEMENT_COMPONENT = prove + (`!u s c:real^N->bool. + locally connected u /\ + closed_in (subtopology euclidean u) s /\ + c IN components(u DIFF s) + ==> closed_in (subtopology euclidean u) (s UNION c)`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN + `s UNION c:real^N->bool = u DIFF (UNIONS(components(u DIFF s) DELETE c))` + SUBST1_TAC THENL + [MP_TAC(ISPEC `(u:real^N->bool) DIFF s` UNIONS_COMPONENTS) THEN + ONCE_REWRITE_TAC [EXTENSION] THEN + REWRITE_TAC[IN_UNION; IN_UNIV; IN_UNIONS; IN_DELETE; IN_DIFF] THEN + MP_TAC(ISPEC `(u:real^N->bool) DIFF s` PAIRWISE_DISJOINT_COMPONENTS) THEN + REWRITE_TAC[pairwise; SET_RULE + `DISJOINT s t <=> !x. ~(x IN s /\ x IN t)`] THEN + FIRST_ASSUM(MP_TAC o MATCH_MP CLOSED_IN_IMP_SUBSET) THEN + FIRST_ASSUM(MP_TAC o MATCH_MP IN_COMPONENTS_SUBSET) THEN + REWRITE_TAC[SUBSET] THEN ASM_MESON_TAC[]; + REWRITE_TAC[closed_in; TOPSPACE_EUCLIDEAN_SUBTOPOLOGY; SUBSET_DIFF] THEN + MATCH_MP_TAC OPEN_IN_DIFF THEN REWRITE_TAC[OPEN_IN_REFL] THEN + MATCH_MP_TAC CLOSED_IN_DIFF THEN REWRITE_TAC[CLOSED_IN_REFL] THEN + MATCH_MP_TAC OPEN_IN_UNIONS THEN REWRITE_TAC[IN_DELETE] THEN + X_GEN_TAC `d:real^N->bool` THEN STRIP_TAC THEN + MATCH_MP_TAC OPEN_IN_TRANS THEN + EXISTS_TAC `u DIFF s:real^N->bool` THEN CONJ_TAC THENL + [MATCH_MP_TAC OPEN_IN_COMPONENTS_LOCALLY_CONNECTED THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC LOCALLY_OPEN_SUBSET THEN + EXISTS_TAC `u:real^N->bool` THEN ASM_REWRITE_TAC[]; + ALL_TAC] THEN + MATCH_MP_TAC OPEN_IN_DIFF THEN ASM_SIMP_TAC[OPEN_IN_REFL]]);; + +let CLOSED_UNION_COMPLEMENT_COMPONENT = prove + (`!s c. closed s /\ c IN components((:real^N) DIFF s) ==> closed(s UNION c)`, + ONCE_REWRITE_TAC[CLOSED_IN] THEN ONCE_REWRITE_TAC[GSYM SUBTOPOLOGY_UNIV] THEN + REPEAT STRIP_TAC THEN + MATCH_MP_TAC CLOSED_IN_UNION_COMPLEMENT_COMPONENT THEN + ASM_REWRITE_TAC[LOCALLY_CONNECTED_UNIV]);; + +let COUNTABLE_COMPONENTS = prove + (`!s:real^N->bool. open s ==> COUNTABLE(components s)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC COUNTABLE_DISJOINT_OPEN_SUBSETS THEN + REWRITE_TAC[PAIRWISE_DISJOINT_COMPONENTS] THEN + ASM_MESON_TAC[OPEN_COMPONENTS]);; + +let FRONTIER_MINIMAL_SEPARATING_CLOSED = prove + (`!s c. closed s /\ ~connected((:real^N) DIFF s) /\ + (!t. closed t /\ t PSUBSET s ==> connected((:real^N) DIFF t)) /\ + c IN components ((:real^N) DIFF s) + ==> frontier c = s`, + REPEAT STRIP_TAC THEN FIRST_ASSUM(MP_TAC o + GEN_REWRITE_RULE RAND_CONV [CONNECTED_EQ_CONNECTED_COMPONENTS_EQ]) THEN + DISCH_THEN(MP_TAC o MATCH_MP (MESON[] + `~(!x x'. x IN s /\ x' IN s ==> x = x') + ==> !x. x IN s ==> ?y. y IN s /\ ~(y = x)`)) THEN + DISCH_THEN(MP_TAC o SPEC `c:real^N->bool`) THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `d:real^N->bool` STRIP_ASSUME_TAC) THEN + FIRST_X_ASSUM(MP_TAC o SPEC `frontier c:real^N->bool`) THEN + REWRITE_TAC[SET_RULE `s PSUBSET t <=> s SUBSET t /\ ~(t SUBSET s)`; + GSYM SUBSET_ANTISYM_EQ] THEN + ASM_SIMP_TAC[FRONTIER_OF_COMPONENTS_CLOSED_COMPLEMENT; FRONTIER_CLOSED] THEN + MATCH_MP_TAC(TAUT `~r ==> (~p ==> r) ==> p`) THEN + REWRITE_TAC[connected] THEN + MAP_EVERY EXISTS_TAC [`c:real^N->bool`; `(:real^N) DIFF closure c`] THEN + REPEAT CONJ_TAC THENL + [ASM_MESON_TAC[OPEN_COMPONENTS; closed]; + REWRITE_TAC[GSYM closed; CLOSED_CLOSURE]; + MP_TAC(ISPEC `c:real^N->bool` INTERIOR_SUBSET) THEN + REWRITE_TAC[frontier] THEN SET_TAC[]; + MATCH_MP_TAC(SET_RULE + `c SUBSET c' ==> c INTER (UNIV DIFF c') INTER s = {}`) THEN + REWRITE_TAC[GSYM INTERIOR_COMPLEMENT; CLOSURE_SUBSET]; + REWRITE_TAC[frontier] THEN MATCH_MP_TAC(SET_RULE + `ci = c /\ ~(c = {}) + ==> ~(c INTER (UNIV DIFF (cc DIFF ci)) = {})`) THEN + ASM_MESON_TAC[IN_COMPONENTS_NONEMPTY; INTERIOR_OPEN; closed; + OPEN_COMPONENTS]; + REWRITE_TAC[frontier] THEN MATCH_MP_TAC(SET_RULE + `~(UNIV DIFF c = {}) + ==> ~((UNIV DIFF c) INTER (UNIV DIFF (c DIFF i)) = {})`) THEN + REWRITE_TAC[GSYM INTERIOR_COMPLEMENT] THEN + MATCH_MP_TAC(SET_RULE `!t. t SUBSET s /\ ~(t = {}) ==> ~(s = {})`) THEN + EXISTS_TAC `d:real^N->bool` THEN CONJ_TAC THENL + [ALL_TAC; ASM_MESON_TAC[IN_COMPONENTS_NONEMPTY]] THEN + MATCH_MP_TAC INTERIOR_MAXIMAL THEN + REWRITE_TAC[SET_RULE `s SUBSET UNIV DIFF t <=> s INTER t = {}`] THEN + ASM_MESON_TAC[COMPONENTS_NONOVERLAP; OPEN_COMPONENTS; GSYM closed]]);; + +(* ------------------------------------------------------------------------- *) +(* Lower bound on norms within segment between vectors. *) +(* Could have used these for connectedness results below, in fact. *) +(* ------------------------------------------------------------------------- *) + +let NORM_SEGMENT_LOWERBOUND = prove + (`!a b x:real^N r d. + &0 < r /\ + norm(a) = r /\ norm(b) = r /\ x IN segment[a,b] /\ + a dot b = d * r pow 2 + ==> sqrt((&1 - abs d) / &2) * r <= norm(x)`, + REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM real_ge] THEN + REWRITE_TAC[NORM_GE_SQUARE] THEN DISJ2_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_SEGMENT]) THEN + DISCH_THEN(X_CHOOSE_THEN `u:real` STRIP_ASSUME_TAC) THEN + ASM_REWRITE_TAC[real_ge; DOT_LMUL; DOT_RMUL; REAL_MUL_RZERO; VECTOR_ARITH + `(a + b) dot (a + b) = a dot a + b dot b + &2 * a dot b`] THEN + MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `(&1 - u) * (&1 - u) * r pow 2 + u * u * r pow 2 - + &2 * (&1 - u) * u * abs d * r pow 2` THEN + CONJ_TAC THENL + [REWRITE_TAC[REAL_POW_MUL; REAL_MUL_ASSOC] THEN + REWRITE_TAC[GSYM REAL_ADD_RDISTRIB; GSYM REAL_SUB_RDISTRIB] THEN + MATCH_MP_TAC REAL_LE_RMUL THEN REWRITE_TAC[REAL_POW_2; REAL_LE_SQUARE] THEN + REWRITE_TAC[GSYM REAL_POW_2; REAL_ARITH + `(&1 - u) pow 2 + u pow 2 - ((&2 * (&1 - u)) * u) * d = + (&1 + d) * (&1 - &2 * u + &2 * u pow 2) - d`] THEN + MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `(&1 + abs d) * &1 / &2 - abs d` THEN CONJ_TAC THENL + [REWRITE_TAC[REAL_ARITH `(&1 + d) * &1 / &2 - d = (&1 - d) / &2`] THEN + MATCH_MP_TAC REAL_EQ_IMP_LE THEN MATCH_MP_TAC SQRT_POW_2 THEN + MP_TAC(ISPECL [`a:real^N`; `b:real^N`] NORM_CAUCHY_SCHWARZ_ABS) THEN + ASM_REWRITE_TAC[REAL_ABS_MUL; REAL_ABS_POW; REAL_POW2_ABS] THEN + ASM_REWRITE_TAC[REAL_ARITH `r * r = &1 * r pow 2`] THEN + ASM_SIMP_TAC[REAL_LE_RMUL_EQ; REAL_POW_LT] THEN REAL_ARITH_TAC; + MATCH_MP_TAC(REAL_ARITH `x <= y ==> x - a <= y - a`) THEN + MATCH_MP_TAC REAL_LE_LMUL THEN CONJ_TAC THENL + [REAL_ARITH_TAC; + MATCH_MP_TAC(REAL_ARITH + `&0 <= (u - &1 / &2) * (u - &1 / &2) + ==> &1 / &2 <= &1 - &2 * u + &2 * u pow 2`) THEN + REWRITE_TAC[REAL_LE_SQUARE]]]; + ASM_REWRITE_TAC[GSYM NORM_POW_2; REAL_LE_LADD; real_sub] THEN + MATCH_MP_TAC(REAL_ARITH `abs(a) <= --x ==> x <= a`) THEN + ASM_REWRITE_TAC[REAL_ABS_MUL; REAL_MUL_LNEG; REAL_NEG_NEG] THEN + REWRITE_TAC[REAL_ABS_POW; REAL_POW2_ABS; REAL_ABS_NUM] THEN + REWRITE_TAC[REAL_MUL_ASSOC] THEN MATCH_MP_TAC REAL_LE_RMUL THEN + REWRITE_TAC[REAL_POW_2; REAL_LE_SQUARE] THEN + ASM_REWRITE_TAC[real_abs; GSYM real_sub; REAL_SUB_LE; REAL_POS] THEN + MATCH_MP_TAC REAL_LE_LMUL THEN CONJ_TAC THEN + REPEAT(MATCH_MP_TAC REAL_LE_MUL THEN + CONJ_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC]) THEN + ASM_REWRITE_TAC[] THEN REAL_ARITH_TAC]);; + +(* ------------------------------------------------------------------------- *) +(* Special case of orthogonality (could replace 2 by sqrt(2)). *) +(* ------------------------------------------------------------------------- *) + +let NORM_SEGMENT_ORTHOGONAL_LOWERBOUND = prove + (`!a b:real^N x r. + r <= norm(a) /\ r <= norm(b) /\ orthogonal a b /\ x IN segment[a,b] + ==> r / &2 <= norm(x)`, + REPEAT GEN_TAC THEN REWRITE_TAC[GSYM real_ge] THEN + REWRITE_TAC[NORM_GE_SQUARE] THEN REWRITE_TAC[real_ge] THEN + ASM_CASES_TAC `r <= &0` THEN ASM_REWRITE_TAC[] THENL + [ASM_REAL_ARITH_TAC; ALL_TAC] THEN + REWRITE_TAC[orthogonal] THEN STRIP_TAC THEN DISJ2_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_SEGMENT]) THEN + DISCH_THEN(X_CHOOSE_THEN `u:real` STRIP_ASSUME_TAC) THEN + ASM_REWRITE_TAC[DOT_LMUL; DOT_RMUL; REAL_MUL_RZERO; VECTOR_ARITH + `(a + b) dot (a + b) = a dot a + b dot b + &2 * a dot b`] THEN + MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `(&1 - u) * (&1 - u) * r pow 2 + u * u * r pow 2` THEN + CONJ_TAC THENL + [REWRITE_TAC[REAL_ARITH `(r / &2) pow 2 = &1 / &4 * r pow 2`] THEN + REWRITE_TAC[GSYM REAL_ADD_RDISTRIB; REAL_MUL_ASSOC] THEN + MATCH_MP_TAC REAL_LE_RMUL THEN REWRITE_TAC[REAL_POW_2; REAL_LE_SQUARE] THEN + MATCH_MP_TAC(REAL_ARITH + `&0 <= (u - &1 / &2) * (u - &1 / &2) + ==> &1 / &4 <= (&1 - u) * (&1 - u) + u * u`) THEN + REWRITE_TAC[REAL_LE_SQUARE]; + REWRITE_TAC[REAL_ADD_RID] THEN MATCH_MP_TAC REAL_LE_ADD2 THEN + CONJ_TAC THEN + REPEAT(MATCH_MP_TAC REAL_LE_LMUL THEN + CONJ_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC]) THEN + ASM_REWRITE_TAC[]]);; + +(* ------------------------------------------------------------------------- *) +(* Accessibility of frontier points. *) +(* ------------------------------------------------------------------------- *) + +let DENSE_ACCESSIBLE_FRONTIER_POINTS = prove + (`!s:real^N->bool v. + open s /\ open_in (subtopology euclidean (frontier s)) v /\ ~(v = {}) + ==> ?g. arc g /\ + IMAGE g (interval [vec 0,vec 1] DELETE vec 1) SUBSET s /\ + pathstart g IN s /\ pathfinish g IN v`, + REPEAT STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN + DISCH_THEN(X_CHOOSE_TAC `z:real^N`) THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [OPEN_IN_CONTAINS_BALL]) THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC (MP_TAC o SPEC `z:real^N`)) THEN + ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `r:real` THEN STRIP_TAC THEN + SUBGOAL_THEN `(z:real^N) IN frontier s` MP_TAC THENL + [ASM SET_TAC[]; + DISCH_THEN(fun th -> ASSUME_TAC th THEN MP_TAC th) THEN + REWRITE_TAC[frontier] THEN ASM_SIMP_TAC[IN_DIFF; INTERIOR_OPEN]] THEN + REWRITE_TAC[closure; IN_UNION; TAUT `(p \/ q) /\ ~p <=> ~p /\ q`] THEN + REWRITE_TAC[IN_ELIM_THM] THEN STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [LIMPT_INFINITE_BALL]) THEN + DISCH_THEN(MP_TAC o SPEC `r:real`) THEN ASM_REWRITE_TAC[] THEN + ASM_CASES_TAC `s INTER ball(z:real^N,r) = {}` THENL + [ASM_MESON_TAC[INFINITE; FINITE_EMPTY]; DISCH_THEN(K ALL_TAC)] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN + REWRITE_TAC[IN_INTER] THEN + DISCH_THEN(X_CHOOSE_THEN `y:real^N` STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN `~((y:real^N) IN frontier s)` ASSUME_TAC THENL + [ASM_SIMP_TAC[IN_DIFF; INTERIOR_OPEN; frontier]; ALL_TAC] THEN + SUBGOAL_THEN `path_connected(ball(z:real^N,r))` MP_TAC THENL + [ASM_SIMP_TAC[CONVEX_BALL; CONVEX_IMP_PATH_CONNECTED]; ALL_TAC] THEN + REWRITE_TAC[PATH_CONNECTED_ARCWISE] THEN + DISCH_THEN(MP_TAC o SPECL [`y:real^N`; `z:real^N`]) THEN + ASM_REWRITE_TAC[CENTRE_IN_BALL] THEN + ANTS_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN + DISCH_THEN(X_CHOOSE_THEN `g:real^1->real^N` STRIP_ASSUME_TAC) THEN + MP_TAC(ISPEC + `IMAGE drop {t | t IN interval[vec 0,vec 1] /\ + (g:real^1->real^N) t IN frontier s}` + COMPACT_ATTAINS_INF) THEN + REWRITE_TAC[EXISTS_IN_IMAGE; IMAGE_EQ_EMPTY; FORALL_IN_IMAGE; IMP_CONJ] THEN + REWRITE_TAC[IMP_IMP; FORALL_IN_GSPEC; EXISTS_IN_GSPEC; GSYM IMAGE_o] THEN + REWRITE_TAC[o_DEF; LIFT_DROP; IMAGE_ID] THEN + ANTS_TAC THENL + [CONJ_TAC THENL + [REWRITE_TAC[COMPACT_EQ_BOUNDED_CLOSED] THEN CONJ_TAC THENL + [MATCH_MP_TAC BOUNDED_SUBSET THEN + EXISTS_TAC `interval[vec 0:real^1,vec 1]` THEN + REWRITE_TAC[BOUNDED_INTERVAL; SUBSET_RESTRICT]; + MATCH_MP_TAC CONTINUOUS_CLOSED_PREIMAGE THEN + REWRITE_TAC[FRONTIER_CLOSED; CLOSED_INTERVAL; GSYM path] THEN + ASM_MESON_TAC[arc]]; + REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN EXISTS_TAC `vec 1:real^1` THEN + ASM_REWRITE_TAC[IN_ELIM_THM; ENDS_IN_UNIT_INTERVAL] THEN + ASM_MESON_TAC[pathfinish; SUBSET]]; + DISCH_THEN(X_CHOOSE_THEN `t:real^1` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `subpath (vec 0) t (g:real^1->real^N)` THEN + ASM_REWRITE_TAC[PATHSTART_SUBPATH; PATHFINISH_SUBPATH] THEN + MATCH_MP_TAC(TAUT `p /\ (p ==> q) ==> p /\ q`) THEN CONJ_TAC THENL + [MATCH_MP_TAC ARC_SUBPATH_ARC THEN + ASM_REWRITE_TAC[ENDS_IN_UNIT_INTERVAL] THEN + ASM_MESON_TAC[pathstart]; + REWRITE_TAC[arc] THEN STRIP_TAC] THEN + GEN_REWRITE_TAC (RAND_CONV o LAND_CONV o LAND_CONV) [GSYM pathstart] THEN + ASM_REWRITE_TAC[] THEN CONJ_TAC THENL + [ALL_TAC; RULE_ASSUM_TAC(SIMP_RULE[path_image]) THEN ASM SET_TAC[]] THEN + MATCH_MP_TAC(SET_RULE + `a IN s /\ IMAGE f s DELETE (f a) SUBSET t /\ + (!x y. x IN s /\ y IN s /\ f x = f y ==> x = y) + ==> IMAGE f (s DELETE a) SUBSET t`) THEN + ASM_REWRITE_TAC[ENDS_IN_UNIT_INTERVAL; GSYM path_image] THEN + W(MP_TAC o PART_MATCH (lhand o rand) PATH_IMAGE_SUBPATH o lhand o lhand o + snd) THEN + ANTS_TAC THENL [ASM_MESON_TAC[IN_INTERVAL_1]; DISCH_THEN SUBST1_TAC] THEN + REWRITE_TAC[REWRITE_RULE[pathfinish] PATHFINISH_SUBPATH] THEN + MATCH_MP_TAC(SET_RULE + `IMAGE f (s DELETE a) DIFF t = {} + ==> IMAGE f s DELETE f a SUBSET t`) THEN + MATCH_MP_TAC(REWRITE_RULE[TAUT + `p /\ q /\ ~r ==> ~s <=> p /\ q /\ s ==> r`] + CONNECTED_INTER_FRONTIER) THEN + REPEAT CONJ_TAC THENL + [MATCH_MP_TAC CONNECTED_CONTINUOUS_IMAGE THEN CONJ_TAC THENL + [FIRST_X_ASSUM(MP_TAC o CONJUNCT1 o GEN_REWRITE_RULE I [arc]) THEN + REWRITE_TAC[path] THEN MATCH_MP_TAC + (REWRITE_RULE[IMP_CONJ_ALT] CONTINUOUS_ON_SUBSET) THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_INTERVAL_1]) THEN + REWRITE_TAC[SUBSET; IN_DELETE; GSYM DROP_EQ; IN_INTERVAL_1] THEN + REAL_ARITH_TAC; + MATCH_MP_TAC CONNECTED_INTERMEDIATE_CLOSURE THEN + EXISTS_TAC `interval(vec 0:real^1,t)` THEN + REWRITE_TAC[CONNECTED_INTERVAL; CLOSURE_INTERVAL] THEN + REWRITE_TAC[INTERVAL_EQ_EMPTY_1] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_INTERVAL_1]) THEN + COND_CASES_TAC THEN + ASM_REWRITE_TAC[SUBSET; IN_DELETE; GSYM DROP_EQ; IN_INTERVAL_1] THEN + REWRITE_TAC[NOT_IN_EMPTY] THEN ASM_REAL_ARITH_TAC]; + REWRITE_TAC[SET_RULE + `~(IMAGE f s INTER t = {}) <=> ?x. x IN s /\ f x IN t`] THEN + EXISTS_TAC `vec 0:real^1` THEN + REWRITE_TAC[IN_INTERVAL_1; IN_DELETE; REAL_LE_REFL] THEN + RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1]) THEN + ASM SET_TAC[pathstart]; + REWRITE_TAC[SET_RULE + `IMAGE g i INTER s = {} <=> !x. x IN i ==> ~(g x IN s)`] THEN + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; IN_DELETE; IN_UNIV; IN_DIFF] THEN + X_GEN_TAC `z:real^1` THEN ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN + REWRITE_TAC[GSYM DROP_EQ; IN_INTERVAL_1] THEN DISCH_TAC THEN + DISCH_THEN(CONJUNCTS_THEN2 STRIP_ASSUME_TAC MP_TAC) THEN + ASM_REWRITE_TAC[GSYM REAL_LE_ANTISYM] THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[IN_INTERVAL_1] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_INTERVAL_1]) THEN + ASM_REAL_ARITH_TAC]]);; + +let DENSE_ACCESSIBLE_FRONTIER_POINTS_CONNECTED = prove + (`!s:real^N->bool v x. + open s /\ connected s /\ x IN s /\ + open_in (subtopology euclidean (frontier s)) v /\ ~(v = {}) + ==> ?g. arc g /\ + IMAGE g (interval [vec 0,vec 1] DELETE vec 1) SUBSET s /\ + pathstart g = x /\ pathfinish g IN v`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`s:real^N->bool`; `v:real^N->bool`] + DENSE_ACCESSIBLE_FRONTIER_POINTS) THEN + ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `g:real^1->real^N` STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN `path_connected(s:real^N->bool)` MP_TAC THENL + [ASM_MESON_TAC[CONNECTED_OPEN_PATH_CONNECTED]; ALL_TAC] THEN + REWRITE_TAC[PATH_CONNECTED_IFF_PATH_COMPONENT] THEN + DISCH_THEN(MP_TAC o SPECL [`x:real^N`; `pathstart g:real^N`]) THEN + ASM_REWRITE_TAC[path_component; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `f:real^1->real^N` THEN STRIP_TAC THEN + MP_TAC(ISPECL [`f ++ g:real^1->real^N`; `x:real^N`; `pathfinish g:real^N`] + PATH_CONTAINS_ARC) THEN + ASM_SIMP_TAC[PATH_JOIN_EQ; ARC_IMP_PATH; PATH_IMAGE_JOIN; + PATHSTART_JOIN; PATHFINISH_JOIN] THEN + FIRST_ASSUM(MP_TAC o MATCH_MP OPEN_IN_IMP_SUBSET) THEN + GEN_REWRITE_TAC LAND_CONV [SUBSET] THEN + ASM_SIMP_TAC[frontier; INTERIOR_OPEN; IN_DIFF] THEN + DISCH_TAC THEN ANTS_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `h:real^1->real^N` THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN MATCH_MP_TAC(SET_RULE + `a IN s /\ IMAGE f s DELETE (f a) SUBSET t /\ + (!x y. x IN s /\ y IN s /\ f x = f y ==> x = y) + ==> IMAGE f (s DELETE a) SUBSET t`) THEN + REWRITE_TAC[ENDS_IN_UNIT_INTERVAL] THEN + CONJ_TAC THENL [REWRITE_TAC[GSYM path_image]; ASM_MESON_TAC[arc]] THEN + FIRST_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE + `h SUBSET f UNION g + ==> f SUBSET s /\ g DELETE a SUBSET s ==> h DELETE a SUBSET s`)) THEN + ASM_REWRITE_TAC[] THEN + RULE_ASSUM_TAC(REWRITE_RULE[path_image; pathstart; pathfinish]) THEN + REWRITE_TAC[path_image] THEN ASM SET_TAC[]);; + +let DENSE_ACCESSIBLE_FRONTIER_POINT_PAIRS = prove + (`!s u v:real^N->bool. + open s /\ connected s /\ + open_in (subtopology euclidean (frontier s)) u /\ + open_in (subtopology euclidean (frontier s)) v /\ + ~(u = {}) /\ ~(v = {}) /\ ~(u = v) + ==> ?g. arc g /\ + pathstart g IN u /\ pathfinish g IN v /\ + IMAGE g (interval(vec 0,vec 1)) SUBSET s`, + GEN_TAC THEN REWRITE_TAC[CONJ_ASSOC] THEN + ONCE_REWRITE_TAC[IMP_CONJ_ALT] THEN + GEN_REWRITE_TAC (funpow 2 BINDER_CONV o LAND_CONV o RAND_CONV) + [GSYM SUBSET_ANTISYM_EQ] THEN + REWRITE_TAC[DE_MORGAN_THM; GSYM CONJ_ASSOC] THEN + MATCH_MP_TAC(MESON[] + `(!u v. R u v ==> R v u) /\ (!u v. P u v ==> R u v) + ==> !u v. P u v \/ P v u ==> R u v`) THEN + CONJ_TAC THENL + [REPEAT GEN_TAC THEN DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN + ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN X_GEN_TAC `g:real^1->real^N` THEN + STRIP_TAC THEN EXISTS_TAC `reversepath g:real^1->real^N` THEN + ASM_SIMP_TAC[ARC_REVERSEPATH; PATHSTART_REVERSEPATH; + PATHFINISH_REVERSEPATH] THEN + REWRITE_TAC[reversepath] THEN ONCE_REWRITE_TAC[GSYM o_DEF] THEN + REWRITE_TAC[IMAGE_o] THEN FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP + (SET_RULE `IMAGE f i SUBSET t + ==> IMAGE r i SUBSET i ==> IMAGE f (IMAGE r i) SUBSET t`)) THEN + SIMP_TAC[SUBSET; FORALL_IN_IMAGE; IN_INTERVAL_1; DROP_SUB; DROP_VEC] THEN + REAL_ARITH_TAC; + ALL_TAC] THEN + REPEAT GEN_TAC THEN DISCH_TAC THEN ASM_CASES_TAC `s:real^N->bool = {}` THEN + ASM_REWRITE_TAC[FRONTIER_EMPTY; OPEN_IN_SUBTOPOLOGY_EMPTY] THENL + [CONV_TAC TAUT; STRIP_TAC THEN UNDISCH_TAC `~(s:real^N->bool = {})`] THEN + REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN + MP_TAC(ISPECL + [`s:real^N->bool`; `v:real^N->bool`; `x:real^N`] + DENSE_ACCESSIBLE_FRONTIER_POINTS_CONNECTED) THEN + ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `g:real^1->real^N` THEN STRIP_TAC THEN + MP_TAC(ISPECL + [`s:real^N->bool`; `(u DELETE pathfinish g):real^N->bool`; `x:real^N`] + DENSE_ACCESSIBLE_FRONTIER_POINTS_CONNECTED) THEN + ASM_SIMP_TAC[OPEN_IN_DELETE; IN_DELETE; LEFT_IMP_EXISTS_THM] THEN + ANTS_TAC THENL [ASM SET_TAC[]; REWRITE_TAC[LEFT_IMP_EXISTS_THM]] THEN + X_GEN_TAC `h:real^1->real^N` THEN STRIP_TAC THEN + MP_TAC(ISPECL [`(reversepath h ++ g):real^1->real^N`; + `pathfinish h:real^N`; `pathfinish g:real^N`] + PATH_CONTAINS_ARC) THEN + ASM_SIMP_TAC[PATH_JOIN; PATHSTART_JOIN; PATHFINISH_JOIN; + PATHSTART_REVERSEPATH; PATHFINISH_REVERSEPATH; + PATH_REVERSEPATH; ARC_IMP_PATH; PATH_IMAGE_JOIN; + PATH_IMAGE_REVERSEPATH] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `q:real^1->real^N` THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[OPEN_CLOSED_INTERVAL_1] THEN + MATCH_MP_TAC(SET_RULE + `(!x y. x IN s /\ y IN s /\ f x = f y ==> x = y) /\ + t SUBSET s /\ IMAGE f s SUBSET u UNION IMAGE f t + ==> IMAGE f (s DIFF t) SUBSET u`) THEN + REWRITE_TAC[INSERT_SUBSET; EMPTY_SUBSET; ENDS_IN_UNIT_INTERVAL] THEN + CONJ_TAC THENL [ASM_MESON_TAC[arc]; REWRITE_TAC[GSYM path_image]] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + SUBSET_TRANS)) THEN + RULE_ASSUM_TAC(REWRITE_RULE[pathstart; pathfinish; path_image]) THEN + REWRITE_TAC[path_image] THEN ASM SET_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* Some simple positive connection theorems. *) +(* ------------------------------------------------------------------------- *) + +let PATH_CONNECTED_CONVEX_DIFF_CARD_LT = prove + (`!u s:real^N->bool. + convex u /\ ~(collinear u) /\ s <_c (:real) ==> path_connected(u DIFF s)`, + REPEAT STRIP_TAC THEN + REWRITE_TAC[path_connected; IN_DIFF; IN_UNIV] THEN + MAP_EVERY X_GEN_TAC [`a:real^N`; `b:real^N`] THEN STRIP_TAC THEN + ASM_CASES_TAC `a:real^N = b` THENL + [EXISTS_TAC `linepath(a:real^N,b)` THEN + REWRITE_TAC[PATHSTART_LINEPATH; PATHFINISH_LINEPATH; PATH_LINEPATH] THEN + ASM_REWRITE_TAC[PATH_IMAGE_LINEPATH; SEGMENT_REFL] THEN ASM SET_TAC[]; + ALL_TAC] THEN + ABBREV_TAC `m:real^N = midpoint(a,b)` THEN + SUBGOAL_THEN `~(m:real^N = a) /\ ~(m = b)` STRIP_ASSUME_TAC THENL + [ASM_MESON_TAC[MIDPOINT_EQ_ENDPOINT]; ALL_TAC] THEN + POP_ASSUM_LIST(MP_TAC o end_itlist CONJ o rev) THEN + GEOM_ORIGIN_TAC `m:real^N` THEN REPEAT GEN_TAC THEN + GEOM_NORMALIZE_TAC `b:real^N` THEN REWRITE_TAC[] THEN GEN_TAC THEN + GEOM_BASIS_MULTIPLE_TAC 1 `b:real^N` THEN X_GEN_TAC `bbb:real` THEN + DISCH_TAC THEN SIMP_TAC[NORM_MUL; NORM_BASIS; DIMINDEX_GE_1; LE_REFL] THEN + ASM_REWRITE_TAC[real_abs; REAL_MUL_RID] THEN + DISCH_THEN SUBST1_TAC THEN POP_ASSUM(K ALL_TAC) THEN + REPEAT GEN_TAC THEN REWRITE_TAC[midpoint; VECTOR_MUL_LID] THEN + REWRITE_TAC[VECTOR_ARITH `inv(&2) % (a + b):real^N = vec 0 <=> a = --b`] THEN + ASM_CASES_TAC `a:real^N = --(basis 1)` THEN ASM_REWRITE_TAC[] THEN + POP_ASSUM(K ALL_TAC) THEN + REPLICATE_TAC 7 (DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + DISCH_THEN(K ALL_TAC) THEN + SUBGOAL_THEN `segment[--basis 1:real^N,basis 1] SUBSET u` ASSUME_TAC THENL + [REWRITE_TAC[SEGMENT_CONVEX_HULL] THEN MATCH_MP_TAC HULL_MINIMAL THEN + ASM SET_TAC[]; + ALL_TAC] THEN + SUBGOAL_THEN `(vec 0:real^N) IN u` ASSUME_TAC THENL + [FIRST_X_ASSUM(MATCH_MP_TAC o GEN_REWRITE_RULE I [SUBSET]) THEN + REWRITE_TAC[IN_SEGMENT] THEN EXISTS_TAC `&1 / &2` THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN VECTOR_ARITH_TAC; + ALL_TAC] THEN + SUBGOAL_THEN `?c:real^N k. 1 <= k /\ ~(k = 1) /\ k <= dimindex(:N) /\ + c IN u /\ ~(c$k = &0)` + STRIP_ASSUME_TAC THENL + [REWRITE_TAC[GSYM NOT_FORALL_THM; TAUT + `a /\ ~b /\ c /\ d /\ ~e <=> ~(d ==> a /\ c ==> ~b ==> e)`] THEN + DISCH_TAC THEN UNDISCH_TAC `~collinear(u:real^N->bool)` THEN + REWRITE_TAC[COLLINEAR_AFFINE_HULL] THEN + MAP_EVERY EXISTS_TAC [`vec 0:real^N`; `basis 1:real^N`] THEN + SIMP_TAC[AFFINE_HULL_EQ_SPAN; HULL_INC; IN_INSERT; SPAN_INSERT_0] THEN + REWRITE_TAC[SPAN_SING; SUBSET; IN_ELIM_THM; IN_UNIV] THEN + X_GEN_TAC `c:real^N` THEN DISCH_TAC THEN EXISTS_TAC `(c:real^N)$1` THEN + SIMP_TAC[CART_EQ; VECTOR_MUL_COMPONENT; BASIS_COMPONENT] THEN + REPEAT STRIP_TAC THEN COND_CASES_TAC THEN + ASM_REWRITE_TAC[REAL_MUL_RID; REAL_MUL_RZERO] THEN + ASM_MESON_TAC[]; + ALL_TAC] THEN + SUBGOAL_THEN `~(c:real^N = vec 0)` ASSUME_TAC THENL + [ASM_SIMP_TAC[CART_EQ; VEC_COMPONENT] THEN ASM_MESON_TAC[]; ALL_TAC] THEN + SUBGOAL_THEN `segment[vec 0:real^N,c] SUBSET u` ASSUME_TAC THENL + [REWRITE_TAC[SEGMENT_CONVEX_HULL] THEN MATCH_MP_TAC HULL_MINIMAL THEN + ASM SET_TAC[]; + ALL_TAC] THEN + SUBGOAL_THEN + `?z:real^N. z IN segment[vec 0,c] /\ + (segment[--basis 1,z] UNION segment[z,basis 1]) INTER s = {}` + STRIP_ASSUME_TAC THENL + [ALL_TAC; + EXISTS_TAC `linepath(--basis 1:real^N,z) ++ linepath(z,basis 1)` THEN + ASM_SIMP_TAC[PATH_JOIN; PATHSTART_JOIN; PATHFINISH_JOIN; PATH_LINEPATH; + PATHSTART_LINEPATH; PATHFINISH_LINEPATH; PATH_IMAGE_JOIN] THEN + REWRITE_TAC[PATH_IMAGE_LINEPATH] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE + `(t UNION v) INTER s = {} + ==> t SUBSET u /\ v SUBSET u + ==> (t UNION v) SUBSET u DIFF s`)) THEN + REWRITE_TAC[SEGMENT_CONVEX_HULL] THEN + CONJ_TAC THEN MATCH_MP_TAC HULL_MINIMAL THEN ASM SET_TAC[]] THEN + MATCH_MP_TAC(SET_RULE + `~(s SUBSET {z | z IN s /\ ~P z}) ==> ?z. z IN s /\ P z`) THEN + DISCH_THEN(MP_TAC o MATCH_MP CARD_LE_SUBSET) THEN + REWRITE_TAC[CARD_NOT_LE; SET_RULE + `~((b UNION c) INTER s = {}) <=> + ~(b INTER s = {}) \/ ~(c INTER s = {})`] THEN + REWRITE_TAC[SET_RULE + `{x | P x /\ (Q x \/ R x)} = {x | P x /\ Q x} UNION {x | P x /\ R x}`] THEN + W(MP_TAC o PART_MATCH lhand UNION_LE_ADD_C o lhand o snd) THEN + MATCH_MP_TAC(ONCE_REWRITE_RULE[IMP_CONJ_ALT] CARD_LET_TRANS) THEN + TRANS_TAC CARD_LTE_TRANS `(:real)` THEN CONJ_TAC THENL + [MATCH_MP_TAC CARD_ADD2_ABSORB_LT THEN REWRITE_TAC[real_INFINITE]; + MATCH_MP_TAC CARD_EQ_IMP_LE THEN ONCE_REWRITE_TAC[CARD_EQ_SYM] THEN + ASM_SIMP_TAC[CARD_EQ_SEGMENT]] THEN + REWRITE_TAC[MESON[SEGMENT_SYM] `segment[--a:real^N,b] = segment[b,--a]`] THEN + SUBGOAL_THEN + `!b:real^N. + b IN u /\ ~(b IN s) /\ ~(b = vec 0) /\ b$k = &0 + ==> {z | z IN segment[vec 0,c] /\ ~(segment[z,b] INTER s = {})} <_c + (:real)` + (fun th -> CONJ_TAC THEN MATCH_MP_TAC th THEN + REWRITE_TAC[VECTOR_NEG_EQ_0; VECTOR_NEG_COMPONENT] THEN + ASM_SIMP_TAC[BASIS_NONZERO; DIMINDEX_GE_1; LE_REFL; + BASIS_COMPONENT] THEN + REWRITE_TAC[REAL_NEG_0]) THEN + REPEAT STRIP_TAC THEN TRANS_TAC CARD_LET_TRANS `s:real^N->bool` THEN + ASM_REWRITE_TAC[] THEN + REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; IN_INTER; RIGHT_AND_EXISTS_THM] THEN + ONCE_REWRITE_TAC[TAUT `p /\ q /\ r <=> r /\ p /\ q`] THEN + MATCH_MP_TAC CARD_LE_RELATIONAL THEN + MAP_EVERY X_GEN_TAC [`w:real^N`; `x1:real^N`; `x2:real^N`] THEN + REWRITE_TAC[SEGMENT_SYM] THEN STRIP_TAC THEN + ASM_CASES_TAC `x2:real^N = x1` THEN ASM_REWRITE_TAC[] THEN + MP_TAC(ISPECL + [`x1:real^N`; `b:real^N`; `x2:real^N`] INTER_SEGMENT) THEN + REWRITE_TAC[NOT_IMP; SEGMENT_SYM] THEN + CONJ_TAC THENL [DISJ2_TAC; REWRITE_TAC[SEGMENT_SYM] THEN ASM SET_TAC[]] THEN + ONCE_REWRITE_TAC[SET_RULE `{x1,b,x2} = {x1,x2,b}`] THEN + ASM_SIMP_TAC[COLLINEAR_3_AFFINE_HULL] THEN STRIP_TAC THEN + SUBGOAL_THEN `(b:real^N) IN affine hull {vec 0,c}` MP_TAC THENL + [FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE + `b IN s ==> s SUBSET t ==> b IN t`)) THEN + MATCH_MP_TAC HULL_MINIMAL THEN REWRITE_TAC[AFFINE_AFFINE_HULL] THEN + MATCH_MP_TAC SUBSET_TRANS THEN EXISTS_TAC `segment[c:real^N,vec 0]` THEN + CONJ_TAC THENL [ASM SET_TAC[]; ONCE_REWRITE_TAC[SEGMENT_SYM]] THEN + REWRITE_TAC[SEGMENT_CONVEX_HULL; CONVEX_HULL_SUBSET_AFFINE_HULL]; + REWRITE_TAC[AFFINE_HULL_2_ALT; IN_ELIM_THM; IN_UNIV] THEN + REWRITE_TAC[VECTOR_ADD_LID; VECTOR_SUB_RZERO; NOT_EXISTS_THM] THEN + X_GEN_TAC `r:real` THEN + ASM_CASES_TAC `r = &0` THEN ASM_REWRITE_TAC[VECTOR_MUL_LZERO] THEN + CONV_TAC(RAND_CONV SYM_CONV) THEN + DISCH_THEN(MP_TAC o AP_TERM `\x:real^N. x$k`) THEN + ASM_SIMP_TAC[VECTOR_MUL_COMPONENT; REAL_ENTIRE]]);; + +let PATH_CONNECTED_COMPLEMENT_CARD_LT = prove + (`!s. 2 <= dimindex(:N) /\ s <_c (:real) + ==> path_connected((:real^N) DIFF s)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC PATH_CONNECTED_CONVEX_DIFF_CARD_LT THEN + ASM_REWRITE_TAC[CONVEX_UNIV; COLLINEAR_AFF_DIM; AFF_DIM_UNIV] THEN + REWRITE_TAC[INT_OF_NUM_LE] THEN ASM_ARITH_TAC);; + +let PATH_CONNECTED_OPEN_IN_DIFF_CARD_LT = prove + (`!s t:real^N->bool. + connected s /\ open_in (subtopology euclidean (affine hull s)) s /\ + ~collinear s /\ t <_c (:real) + ==> path_connected(s DIFF t)`, + REPEAT STRIP_TAC THEN + REWRITE_TAC[PATH_CONNECTED_IFF_PATH_COMPONENT; IN_DIFF] THEN + REWRITE_TAC[TAUT `(p /\ q) /\ (r /\ s) <=> p /\ r /\ q /\ s`] THEN + MATCH_MP_TAC CONNECTED_EQUIVALENCE_RELATION_GEN THEN + ASM_REWRITE_TAC[IN_DIFF] THEN + REWRITE_TAC[PATH_COMPONENT_SYM; PATH_COMPONENT_TRANS] THEN CONJ_TAC THENL + [MAP_EVERY X_GEN_TAC [`u:real^N->bool`; `x:real^N`] THEN STRIP_TAC THEN + SUBGOAL_THEN + `open_in (subtopology euclidean (affine hull s)) (u:real^N->bool)` + MP_TAC THENL [ASM_MESON_TAC[OPEN_IN_TRANS]; ALL_TAC] THEN + REWRITE_TAC[OPEN_IN_CONTAINS_BALL] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC (MP_TAC o SPEC `x:real^N`)) THEN + ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `r:real` STRIP_ASSUME_TAC) THEN + MATCH_MP_TAC(SET_RULE `~(s SUBSET t) ==> ?x. x IN s /\ ~(x IN t)`) THEN + DISCH_THEN(MP_TAC o MATCH_MP CARD_LE_SUBSET) THEN + REWRITE_TAC[CARD_NOT_LE] THEN TRANS_TAC CARD_LTE_TRANS `(:real)` THEN + ASM_REWRITE_TAC[] THEN + TRANS_TAC CARD_LE_TRANS `ball(x:real^N,r) INTER affine hull s` THEN + ASM_SIMP_TAC[CARD_LE_SUBSET] THEN MATCH_MP_TAC CARD_EQ_IMP_LE THEN + ONCE_REWRITE_TAC[CARD_EQ_SYM] THEN MATCH_MP_TAC CARD_EQ_CONVEX THEN + EXISTS_TAC `x:real^N` THEN + ASM_SIMP_TAC[CONVEX_INTER; AFFINE_IMP_CONVEX; CONVEX_BALL; + AFFINE_AFFINE_HULL; IN_INTER; CENTRE_IN_BALL; HULL_INC] THEN + SUBGOAL_THEN `~(s SUBSET {x:real^N})` MP_TAC THENL + [ASM_MESON_TAC[COLLINEAR_SUBSET; COLLINEAR_SING]; ALL_TAC] THEN + REWRITE_TAC[SUBSET; IN_SING; NOT_FORALL_THM; NOT_IMP] THEN + DISCH_THEN(X_CHOOSE_THEN `y:real^N` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `x + r / &2 / norm(y - x) % (y - x):real^N` THEN + RULE_ASSUM_TAC(REWRITE_RULE[SUBSET]) THEN + ASM_SIMP_TAC[HULL_INC; IN_AFFINE_ADD_MUL_DIFF; AFFINE_AFFINE_HULL] THEN + REWRITE_TAC[IN_BALL; VECTOR_ARITH `x:real^N = x + y <=> y = vec 0`] THEN + ASM_SIMP_TAC[VECTOR_MUL_EQ_0; REAL_DIV_EQ_0; NORM_EQ_0; VECTOR_SUB_EQ; + REAL_LT_IMP_NZ; NORM_ARITH `dist(x:real^N,x + y) = norm y`] THEN + REWRITE_TAC[NORM_MUL; REAL_ABS_DIV; REAL_ABS_NUM; REAL_ABS_NORM] THEN + ASM_SIMP_TAC[REAL_DIV_RMUL; NORM_EQ_0; VECTOR_SUB_EQ] THEN + ASM_REAL_ARITH_TAC; + X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [OPEN_IN_CONTAINS_BALL]) THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC (MP_TAC o SPEC `x:real^N`)) THEN + ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `r:real` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `ball(x:real^N,r) INTER affine hull s` THEN + ASM_SIMP_TAC[IN_INTER; HULL_INC; CENTRE_IN_BALL] THEN CONJ_TAC THENL + [MATCH_MP_TAC OPEN_IN_SUBSET_TRANS THEN + EXISTS_TAC `affine hull s:real^N->bool` THEN + ASM_SIMP_TAC[ONCE_REWRITE_RULE[INTER_COMM]OPEN_IN_OPEN_INTER; OPEN_BALL]; + MAP_EVERY X_GEN_TAC [`y:real^N`; `z:real^N`] THEN STRIP_TAC THEN + MP_TAC(ISPECL [`ball(x:real^N,r) INTER affine hull s`; `t:real^N->bool`] + PATH_CONNECTED_CONVEX_DIFF_CARD_LT) THEN + ASM_SIMP_TAC[CONVEX_INTER; AFFINE_IMP_CONVEX; CONVEX_BALL; + AFFINE_AFFINE_HULL] THEN + ANTS_TAC THENL + [REWRITE_TAC[COLLINEAR_AFF_DIM] THEN ONCE_REWRITE_TAC[INTER_COMM] THEN + W(MP_TAC o PART_MATCH (lhs o rand) AFF_DIM_CONVEX_INTER_OPEN o + lhand o rand o snd) THEN + SIMP_TAC[AFFINE_IMP_CONVEX; AFFINE_AFFINE_HULL; OPEN_BALL] THEN + ANTS_TAC THENL [ASM SET_TAC[CENTRE_IN_BALL]; ALL_TAC] THEN + DISCH_THEN SUBST1_TAC THEN REWRITE_TAC[AFF_DIM_AFFINE_HULL] THEN + ASM_REWRITE_TAC[GSYM COLLINEAR_AFF_DIM]; + REWRITE_TAC[PATH_CONNECTED_IFF_PATH_COMPONENT] THEN + DISCH_THEN(MP_TAC o SPECL [`y:real^N`; `z:real^N`]) THEN + ASM_REWRITE_TAC[IN_INTER; IN_DIFF] THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] PATH_COMPONENT_OF_SUBSET) THEN + ASM SET_TAC[]]]]);; + +let CONNECTED_OPEN_IN_DIFF_CARD_LT = prove + (`!s t:real^N->bool. + connected s /\ open_in (subtopology euclidean (affine hull s)) s /\ + ~collinear s /\ t <_c (:real) + ==> connected(s DIFF t)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC PATH_CONNECTED_IMP_CONNECTED THEN + MATCH_MP_TAC PATH_CONNECTED_OPEN_IN_DIFF_CARD_LT THEN + ASM_REWRITE_TAC[]);; + +let PATH_CONNECTED_OPEN_DIFF_CARD_LT = prove + (`!s t:real^N->bool. + 2 <= dimindex(:N) /\ open s /\ connected s /\ t <_c (:real) + ==> path_connected(s DIFF t)`, + REPEAT STRIP_TAC THEN ASM_CASES_TAC `s:real^N->bool = {}` THEN + ASM_REWRITE_TAC[EMPTY_DIFF; PATH_CONNECTED_EMPTY] THEN + MATCH_MP_TAC PATH_CONNECTED_OPEN_IN_DIFF_CARD_LT THEN + ASM_REWRITE_TAC[COLLINEAR_AFF_DIM] THEN + ASM_SIMP_TAC[AFFINE_HULL_OPEN; AFF_DIM_OPEN] THEN + ASM_REWRITE_TAC[INT_OF_NUM_LE; SUBTOPOLOGY_UNIV; GSYM OPEN_IN] THEN + ASM_ARITH_TAC);; + +let CONNECTED_OPEN_DIFF_CARD_LT = prove + (`!s t:real^N->bool. + 2 <= dimindex(:N) /\ open s /\ connected s /\ t <_c (:real) + ==> connected(s DIFF t)`, + SIMP_TAC[PATH_CONNECTED_OPEN_DIFF_CARD_LT; PATH_CONNECTED_IMP_CONNECTED]);; + +let PATH_CONNECTED_OPEN_DIFF_COUNTABLE = prove + (`!s t:real^N->bool. + 2 <= dimindex(:N) /\ open s /\ connected s /\ COUNTABLE t + ==> path_connected(s DIFF t)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC PATH_CONNECTED_OPEN_DIFF_CARD_LT THEN + ASM_REWRITE_TAC[GSYM CARD_NOT_LE] THEN + ASM_MESON_TAC[UNCOUNTABLE_REAL; CARD_LE_COUNTABLE]);; + +let CONNECTED_OPEN_DIFF_COUNTABLE = prove + (`!s t:real^N->bool. + 2 <= dimindex(:N) /\ open s /\ connected s /\ COUNTABLE t + ==> connected(s DIFF t)`, + SIMP_TAC[PATH_CONNECTED_OPEN_DIFF_COUNTABLE; PATH_CONNECTED_IMP_CONNECTED]);; + +let PATH_CONNECTED_OPEN_DELETE = prove + (`!s a:real^N. 2 <= dimindex(:N) /\ open s /\ connected s + ==> path_connected(s DELETE a)`, + REPEAT STRIP_TAC THEN REWRITE_TAC[SET_RULE `s DELETE a = s DIFF {a}`] THEN + MATCH_MP_TAC PATH_CONNECTED_OPEN_DIFF_COUNTABLE THEN + ASM_REWRITE_TAC[COUNTABLE_SING]);; + +let CONNECTED_OPEN_DELETE = prove + (`!s a:real^N. 2 <= dimindex(:N) /\ open s /\ connected s + ==> connected(s DELETE a)`, + SIMP_TAC[PATH_CONNECTED_OPEN_DELETE; PATH_CONNECTED_IMP_CONNECTED]);; + +let PATH_CONNECTED_PUNCTURED_UNIVERSE = prove + (`!a. 2 <= dimindex(:N) ==> path_connected((:real^N) DIFF {a})`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC PATH_CONNECTED_OPEN_DIFF_COUNTABLE THEN + ASM_REWRITE_TAC[OPEN_UNIV; CONNECTED_UNIV; COUNTABLE_SING]);; + +let CONNECTED_PUNCTURED_UNIVERSE = prove + (`!a. 2 <= dimindex(:N) ==> connected((:real^N) DIFF {a})`, + SIMP_TAC[PATH_CONNECTED_PUNCTURED_UNIVERSE; PATH_CONNECTED_IMP_CONNECTED]);; + +let PATH_CONNECTED_PUNCTURED_BALL = prove + (`!a:real^N r. 2 <= dimindex(:N) ==> path_connected(ball(a,r) DELETE a)`, + SIMP_TAC[PATH_CONNECTED_OPEN_DELETE; OPEN_BALL; CONNECTED_BALL]);; + +let CONNECTED_PUNCTURED_BALL = prove + (`!a:real^N r. 2 <= dimindex(:N) ==> connected(ball(a,r) DELETE a)`, + SIMP_TAC[CONNECTED_OPEN_DELETE; OPEN_BALL; CONNECTED_BALL]);; + +let PATH_CONNECTED_SPHERE = prove + (`!a:real^N r. 2 <= dimindex(:N) ==> path_connected(sphere(a,r))`, + REPEAT GEN_TAC THEN + REWRITE_TAC[sphere; dist] THEN ONCE_REWRITE_TAC[NORM_SUB] THEN + GEOM_ORIGIN_TAC `a:real^N` THEN GEN_TAC THEN + REWRITE_TAC[VECTOR_SUB_RZERO] THEN DISCH_TAC THEN + REPEAT_TCL DISJ_CASES_THEN ASSUME_TAC + (REAL_ARITH `r < &0 \/ r = &0 \/ &0 < r`) + THENL + [ASM_SIMP_TAC[NORM_ARITH `r < &0 ==> ~(norm(x:real^N) = r)`] THEN + REWRITE_TAC[EMPTY_GSPEC; PATH_CONNECTED_EMPTY]; + ASM_REWRITE_TAC[NORM_EQ_0; SING_GSPEC; PATH_CONNECTED_SING]; + SUBGOAL_THEN + `{x:real^N | norm x = r} = + IMAGE (\x. r / norm x % x) ((:real^N) DIFF {vec 0})` + SUBST1_TAC THENL + [MATCH_MP_TAC SUBSET_ANTISYM THEN + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE] THEN + REWRITE_TAC[IN_IMAGE; IN_ELIM_THM; IN_DIFF; IN_SING; IN_UNIV] THEN + ASM_SIMP_TAC[NORM_MUL; REAL_ABS_DIV; REAL_ABS_NORM; REAL_DIV_RMUL; + NORM_EQ_0; REAL_ARITH `&0 < r ==> abs r = r`] THEN + X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN EXISTS_TAC `x:real^N` THEN + ASM_SIMP_TAC[REAL_DIV_REFL; REAL_LT_IMP_NZ; VECTOR_MUL_LID] THEN + ASM_MESON_TAC[NORM_0; REAL_LT_IMP_NZ]; + MATCH_MP_TAC PATH_CONNECTED_CONTINUOUS_IMAGE THEN + ASM_SIMP_TAC[PATH_CONNECTED_PUNCTURED_UNIVERSE] THEN + MATCH_MP_TAC CONTINUOUS_ON_MUL THEN REWRITE_TAC[CONTINUOUS_ON_ID] THEN + REWRITE_TAC[o_DEF; CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN] THEN + X_GEN_TAC `x:real^N` THEN REWRITE_TAC[IN_DIFF; IN_UNIV; IN_SING] THEN + DISCH_TAC THEN REWRITE_TAC[real_div; LIFT_CMUL] THEN + MATCH_MP_TAC CONTINUOUS_CMUL THEN + MATCH_MP_TAC(REWRITE_RULE[o_DEF] CONTINUOUS_AT_WITHIN_INV) THEN + ASM_REWRITE_TAC[NORM_EQ_0] THEN MATCH_MP_TAC CONTINUOUS_AT_WITHIN THEN + REWRITE_TAC[REWRITE_RULE[o_DEF] CONTINUOUS_AT_LIFT_NORM]]]);; + +let CONNECTED_SPHERE = prove + (`!a:real^N r. 2 <= dimindex(:N) ==> connected(sphere(a,r))`, + SIMP_TAC[PATH_CONNECTED_SPHERE; PATH_CONNECTED_IMP_CONNECTED]);; + +let CONNECTED_SPHERE_EQ = prove + (`!a:real^N r. connected(sphere(a,r)) <=> 2 <= dimindex(:N) \/ r <= &0`, + let lemma = prove + (`!a:real^1 r. &0 < r + ==> ?x y. ~(x = y) /\ dist(a,x) = r /\ dist(a,y) = r`, + MP_TAC SPHERE_1 THEN REPEAT(MATCH_MP_TAC MONO_FORALL THEN GEN_TAC) THEN + COND_CASES_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN + REWRITE_TAC[EXTENSION; IN_SPHERE; IN_INSERT; NOT_IN_EMPTY] THEN + REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THEN MATCH_MP_TAC(MESON[] + `~(a = b) ==> ?x y. ~(x = y) /\ (x = a \/ x = b) /\ (y = a \/ y = b)`) THEN + REWRITE_TAC[VECTOR_ARITH `a - r:real^1 = a + r <=> r = vec 0`] THEN + REWRITE_TAC[GSYM DROP_EQ; DROP_VEC; LIFT_DROP] THEN ASM_REAL_ARITH_TAC) in + REPEAT GEN_TAC THEN ASM_CASES_TAC `r < &0` THEN + ASM_SIMP_TAC[SPHERE_EMPTY; CONNECTED_EMPTY; REAL_LT_IMP_LE] THEN + ASM_CASES_TAC `r = &0` THEN + ASM_SIMP_TAC[SPHERE_SING; REAL_LE_REFL; CONNECTED_SING] THEN + SUBGOAL_THEN `&0 < r` ASSUME_TAC THENL + [ASM_REAL_ARITH_TAC; ASM_REWRITE_TAC[GSYM REAL_NOT_LT]] THEN + EQ_TAC THEN SIMP_TAC[CONNECTED_SPHERE] THEN + DISCH_THEN(MP_TAC o MATCH_MP CONNECTED_FINITE_IFF_SING) THEN + ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN + SIMP_TAC[DIMINDEX_GE_1; ARITH_RULE `1 <= n ==> (2 <= n <=> ~(n = 1))`] THEN + GEN_REWRITE_TAC (LAND_CONV o RAND_CONV) [GSYM DIMINDEX_1] THEN + DISCH_TAC THEN FIRST_ASSUM (fun th -> + REWRITE_TAC[GEOM_EQUAL_DIMENSION_RULE th FINITE_SPHERE_1]) THEN + REWRITE_TAC[SET_RULE + `~(s = {} \/ ?a. s = {a}) <=> ?x y. ~(x = y) /\ x IN s /\ y IN s`] THEN + REWRITE_TAC[IN_SPHERE] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o C GEOM_EQUAL_DIMENSION_RULE lemma) THEN + ASM_REWRITE_TAC[]);; + +let PATH_CONNECTED_SPHERE_EQ = prove + (`!a:real^N r. path_connected(sphere(a,r)) <=> 2 <= dimindex(:N) \/ r <= &0`, + REPEAT GEN_TAC THEN EQ_TAC THENL + [REWRITE_TAC[GSYM CONNECTED_SPHERE_EQ; PATH_CONNECTED_IMP_CONNECTED]; + STRIP_TAC THEN ASM_SIMP_TAC[PATH_CONNECTED_SPHERE]] THEN + ASM_CASES_TAC `r < &0` THEN + ASM_SIMP_TAC[SPHERE_EMPTY; PATH_CONNECTED_EMPTY] THEN + ASM_CASES_TAC `r = &0` THEN + ASM_SIMP_TAC[SPHERE_SING; PATH_CONNECTED_SING] THEN + ASM_REAL_ARITH_TAC);; + +let FINITE_SPHERE = prove + (`!a:real^N r. FINITE(sphere(a,r)) <=> r <= &0 \/ dimindex(:N) = 1`, + REPEAT GEN_TAC THEN ASM_CASES_TAC `dimindex(:N) = 1` THEN + ASM_REWRITE_TAC[] THENL + [RULE_ASSUM_TAC(REWRITE_RULE[GSYM DIMINDEX_1]) THEN + FIRST_ASSUM(MATCH_ACCEPT_TAC o C PROVE_HYP + (GEOM_EQUAL_DIMENSION_RULE(ASSUME `dimindex(:N) = dimindex(:1)`) + FINITE_SPHERE_1)); + ASM_SIMP_TAC[CONNECTED_SPHERE; ARITH_RULE `2 <= n <=> 1 <= n /\ ~(n = 1)`; + DIMINDEX_GE_1; CONNECTED_FINITE_IFF_SING] THEN + REWRITE_TAC[SET_RULE `(s = {} \/ ?a. s = {a}) <=> + (!a b. a IN s /\ b IN s ==> a = b)`] THEN + SIMP_TAC[IN_SPHERE] THEN EQ_TAC THENL [ALL_TAC; CONV_TAC NORM_ARITH] THEN + ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN + REWRITE_TAC[REAL_NOT_LE] THEN DISCH_TAC THEN + MP_TAC(ISPECL [`a:real^N`; `r:real`] VECTOR_CHOOSE_DIST) THEN + ASM_SIMP_TAC[REAL_LT_IMP_LE; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN + DISCH_THEN(MP_TAC o SPECL [`x:real^N`; `a - (x - a):real^N`]) THEN + FIRST_X_ASSUM(K ALL_TAC o check (is_neg o concl)) THEN + REPEAT(POP_ASSUM MP_TAC) THEN CONV_TAC NORM_ARITH]);; + +let LIMIT_POINT_OF_SPHERE = prove + (`!a r x:real^N. x limit_point_of sphere(a,r) <=> + &0 < r /\ 2 <= dimindex(:N) /\ x IN sphere(a,r)`, + REPEAT GEN_TAC THEN ASM_CASES_TAC `FINITE(sphere(a:real^N,r))` THENL + [ASM_SIMP_TAC[LIMIT_POINT_FINITE]; ALL_TAC] THEN + FIRST_ASSUM(MP_TAC o REWRITE_RULE[FINITE_SPHERE]) THEN + REWRITE_TAC[DE_MORGAN_THM] THEN + STRIP_TAC THEN ASM_REWRITE_TAC[REAL_NOT_LE; ARITH; REAL_NOT_LT] THEN + ASM_SIMP_TAC[GSYM REAL_NOT_LE; DIMINDEX_GE_1; + ARITH_RULE `1 <= n ==> (2 <= n <=> ~(n = 1))`] THEN + EQ_TAC THEN REWRITE_TAC[REWRITE_RULE[CLOSED_LIMPT] CLOSED_SPHERE] THEN + DISCH_TAC THEN MATCH_MP_TAC CONNECTED_IMP_PERFECT THEN + ASM_SIMP_TAC[CONNECTED_SPHERE_EQ; DIMINDEX_GE_1; + ARITH_RULE `1 <= n ==> (2 <= n <=> ~(n = 1))`] THEN + ASM_MESON_TAC[FINITE_SING]);; + +let CARD_EQ_SPHERE = prove + (`!a:real^N r. 2 <= dimindex(:N) /\ &0 < r ==> sphere(a,r) =_c (:real)`, + SIMP_TAC[CONNECTED_CARD_EQ_IFF_NONTRIVIAL; CONNECTED_SPHERE] THEN + REPEAT STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o MATCH_MP(REWRITE_RULE[IMP_CONJ_ALT] FINITE_SUBSET)) THEN + ASM_REWRITE_TAC[FINITE_SING; FINITE_SPHERE; REAL_NOT_LE; DE_MORGAN_THM] THEN + ASM_ARITH_TAC);; + +let PATH_CONNECTED_ANNULUS = prove + (`(!a:real^N r1 r2. + 2 <= dimindex(:N) + ==> path_connected {x | r1 < norm(x - a) /\ norm(x - a) < r2}) /\ + (!a:real^N r1 r2. + 2 <= dimindex(:N) + ==> path_connected {x | r1 < norm(x - a) /\ norm(x - a) <= r2}) /\ + (!a:real^N r1 r2. + 2 <= dimindex(:N) + ==> path_connected {x | r1 <= norm(x - a) /\ norm(x - a) < r2}) /\ + (!a:real^N r1 r2. + 2 <= dimindex(:N) + ==> path_connected {x | r1 <= norm(x - a) /\ norm(x - a) < r2})`, + let lemma = prove + (`!a:real^N P. + 2 <= dimindex(:N) /\ path_connected {lift r | &0 <= r /\ P r} + ==> path_connected {x | P(norm(x - a))}`, + REPEAT GEN_TAC THEN GEOM_ORIGIN_TAC `a:real^N` THEN + REWRITE_TAC[VECTOR_SUB_RZERO] THEN REPEAT STRIP_TAC THEN + SUBGOAL_THEN + `{x:real^N | P(norm(x))} = + IMAGE (\z. drop(fstcart z) % sndcart z) + {pastecart x y | x IN {lift x | &0 <= x /\ P x} /\ + y IN {y | norm y = &1}}` + SUBST1_TAC THENL + [REWRITE_TAC[EXTENSION; IN_IMAGE] THEN ONCE_REWRITE_TAC[CONJ_SYM] THEN + REWRITE_TAC[EXISTS_IN_GSPEC; FSTCART_PASTECART; SNDCART_PASTECART] THEN + X_GEN_TAC `z:real^N` THEN REWRITE_TAC[EXISTS_LIFT; LIFT_DROP] THEN + ONCE_REWRITE_TAC[SIMPLE_IMAGE_GEN] THEN + REWRITE_TAC[LIFT_IN_IMAGE_LIFT; IMAGE_ID] THEN + REWRITE_TAC[IN_ELIM_THM] THEN + EQ_TAC THEN STRIP_TAC THEN ASM_REWRITE_TAC[NORM_MUL; REAL_MUL_RID] THEN + ASM_REWRITE_TAC[real_abs] THEN ASM_CASES_TAC `z:real^N = vec 0` THENL + [MAP_EVERY EXISTS_TAC [`&0`; `basis 1:real^N`] THEN + ASM_SIMP_TAC[NORM_BASIS; DIMINDEX_GE_1; LE_REFL; VECTOR_MUL_LZERO] THEN + ASM_MESON_TAC[NORM_0; REAL_ABS_NUM; REAL_LE_REFL]; + MAP_EVERY EXISTS_TAC [`norm(z:real^N)`; `inv(norm z) % z:real^N`] THEN + ASM_SIMP_TAC[REAL_ABS_NORM; NORM_MUL; VECTOR_MUL_ASSOC; VECTOR_MUL_LID; + NORM_POS_LE; REAL_ABS_INV; REAL_MUL_RINV; REAL_MUL_LINV; NORM_EQ_0]]; + MATCH_MP_TAC PATH_CONNECTED_CONTINUOUS_IMAGE THEN CONJ_TAC THENL + [MATCH_MP_TAC CONTINUOUS_ON_MUL THEN + REWRITE_TAC[o_DEF; LIFT_DROP; ETA_AX] THEN + SIMP_TAC[LINEAR_CONTINUOUS_ON; LINEAR_FSTCART; LINEAR_SNDCART]; + REWRITE_TAC[GSYM PCROSS] THEN + MATCH_MP_TAC PATH_CONNECTED_PCROSS THEN ASM_REWRITE_TAC[] THEN + ONCE_REWRITE_TAC[NORM_ARITH `norm y = norm(y - vec 0:real^N)`] THEN + ONCE_REWRITE_TAC[NORM_SUB] THEN + REWRITE_TAC[REWRITE_RULE[dist] (GSYM sphere)] THEN + ASM_SIMP_TAC[PATH_CONNECTED_SPHERE]]]) in + REPEAT STRIP_TAC THEN + MP_TAC(ISPEC `a:real^N` lemma) THEN + DISCH_THEN MATCH_MP_TAC THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC CONVEX_IMP_PATH_CONNECTED THEN + MATCH_MP_TAC IS_INTERVAL_CONVEX THEN + REWRITE_TAC[is_interval] THEN + ONCE_REWRITE_TAC[SIMPLE_IMAGE_GEN] THEN + REWRITE_TAC[IN_IMAGE_LIFT_DROP; FORALL_1; DIMINDEX_1] THEN + REWRITE_TAC[IN_ELIM_THM; GSYM drop] THEN REAL_ARITH_TAC);; + +let CONNECTED_ANNULUS = prove + (`(!a:real^N r1 r2. + 2 <= dimindex(:N) + ==> connected {x | r1 < norm(x - a) /\ norm(x - a) < r2}) /\ + (!a:real^N r1 r2. + 2 <= dimindex(:N) + ==> connected {x | r1 < norm(x - a) /\ norm(x - a) <= r2}) /\ + (!a:real^N r1 r2. + 2 <= dimindex(:N) + ==> connected {x | r1 <= norm(x - a) /\ norm(x - a) < r2}) /\ + (!a:real^N r1 r2. + 2 <= dimindex(:N) + ==> connected {x | r1 <= norm(x - a) /\ norm(x - a) < r2})`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC PATH_CONNECTED_IMP_CONNECTED THEN + ASM_SIMP_TAC[PATH_CONNECTED_ANNULUS]);; + +let PATH_CONNECTED_COMPLEMENT_BOUNDED_CONVEX = prove + (`!s. 2 <= dimindex(:N) /\ bounded s /\ convex s + ==> path_connected((:real^N) DIFF s)`, + REPEAT STRIP_TAC THEN + ASM_CASES_TAC `s:real^N->bool = {}` THEN + ASM_SIMP_TAC[DIFF_EMPTY; CONVEX_IMP_PATH_CONNECTED; CONVEX_UNIV] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN + DISCH_THEN(X_CHOOSE_TAC `a:real^N`) THEN + REWRITE_TAC[PATH_CONNECTED_IFF_PATH_COMPONENT] THEN + MAP_EVERY X_GEN_TAC [`x:real^N`; `y:real^N`] THEN + REWRITE_TAC[IN_DIFF; IN_UNIV] THEN STRIP_TAC THEN + SUBGOAL_THEN `~(x:real^N = a) /\ ~(y = a)` STRIP_ASSUME_TAC THENL + [ASM_MESON_TAC[]; ALL_TAC] THEN + SUBGOAL_THEN `bounded((x:real^N) INSERT y INSERT s)` MP_TAC THENL + [ASM_REWRITE_TAC[BOUNDED_INSERT]; ALL_TAC] THEN + DISCH_THEN(MP_TAC o SPEC `a:real^N` o MATCH_MP BOUNDED_SUBSET_BALL) THEN + REWRITE_TAC[INSERT_SUBSET] THEN + DISCH_THEN(X_CHOOSE_THEN `B:real` STRIP_ASSUME_TAC) THEN + MATCH_MP_TAC PATH_COMPONENT_TRANS THEN + ABBREV_TAC `C = (B / norm(x - a:real^N))` THEN + EXISTS_TAC `a + C % (x - a):real^N` THEN CONJ_TAC THENL + [MATCH_MP_TAC PATH_CONNECTED_LINEPATH THEN + REWRITE_TAC[SUBSET; segment; FORALL_IN_GSPEC; IN_DIFF; IN_UNIV] THEN + REWRITE_TAC[VECTOR_ARITH + `(&1 - u) % x + u % (a + B % (x - a)):real^N = + a + (&1 + (B - &1) * u) % (x - a)`] THEN + X_GEN_TAC `u:real` THEN STRIP_TAC THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [CONVEX_ALT]) THEN + DISCH_THEN(MP_TAC o SPECL + [`a:real^N`; `a + (&1 + (C - &1) * u) % (x - a):real^N`; + `&1 / (&1 + (C - &1) * u)`]) THEN + SUBGOAL_THEN `&1 <= &1 + (C - &1) * u` ASSUME_TAC THENL + [REWRITE_TAC[REAL_LE_ADDR] THEN MATCH_MP_TAC REAL_LE_MUL THEN + ASM_REWRITE_TAC[REAL_SUB_LE] THEN + EXPAND_TAC "C" THEN + ASM_SIMP_TAC[REAL_LE_RDIV_EQ; NORM_POS_LT; VECTOR_SUB_EQ] THEN + RULE_ASSUM_TAC(REWRITE_RULE[IN_BALL; dist]) THEN + ASM_SIMP_TAC[REAL_LT_IMP_LE; NORM_ARITH `&1 * norm(x - a) = norm(a - x)`]; + FIRST_ASSUM(ASSUME_TAC o MATCH_MP + (REAL_ARITH `&1 <= a ==> &0 < a`))] THEN + ASM_REWRITE_TAC[NOT_IMP] THEN + ASM_SIMP_TAC[REAL_LE_DIV; REAL_POS; REAL_LT_IMP_LE; REAL_LE_LDIV_EQ; + REAL_MUL_LID] THEN + ASM_SIMP_TAC[VECTOR_ADD_LDISTRIB; VECTOR_MUL_ASSOC; REAL_DIV_RMUL; + REAL_LT_IMP_NZ] THEN + UNDISCH_TAC `~((x:real^N) IN s)` THEN + MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN + VECTOR_ARITH_TAC; + ALL_TAC] THEN + MATCH_MP_TAC PATH_COMPONENT_SYM THEN + MATCH_MP_TAC PATH_COMPONENT_TRANS THEN + ABBREV_TAC `D = (B / norm(y - a:real^N))` THEN + EXISTS_TAC `a + D % (y - a):real^N` THEN CONJ_TAC THENL + [MATCH_MP_TAC PATH_CONNECTED_LINEPATH THEN + REWRITE_TAC[SUBSET; segment; FORALL_IN_GSPEC; IN_DIFF; IN_UNIV] THEN + REWRITE_TAC[VECTOR_ARITH + `(&1 - u) % y + u % (a + B % (y - a)):real^N = + a + (&1 + (B - &1) * u) % (y - a)`] THEN + X_GEN_TAC `u:real` THEN STRIP_TAC THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [CONVEX_ALT]) THEN + DISCH_THEN(MP_TAC o SPECL + [`a:real^N`; `a + (&1 + (D - &1) * u) % (y - a):real^N`; + `&1 / (&1 + (D - &1) * u)`]) THEN + SUBGOAL_THEN `&1 <= &1 + (D - &1) * u` ASSUME_TAC THENL + [REWRITE_TAC[REAL_LE_ADDR] THEN MATCH_MP_TAC REAL_LE_MUL THEN + ASM_REWRITE_TAC[REAL_SUB_LE] THEN + EXPAND_TAC "D" THEN + ASM_SIMP_TAC[REAL_LE_RDIV_EQ; NORM_POS_LT; VECTOR_SUB_EQ] THEN + RULE_ASSUM_TAC(REWRITE_RULE[IN_BALL; dist]) THEN + ASM_SIMP_TAC[REAL_LT_IMP_LE; NORM_ARITH `&1 * norm(y - a) = norm(a - y)`]; + FIRST_ASSUM(ASSUME_TAC o MATCH_MP + (REAL_ARITH `&1 <= a ==> &0 < a`))] THEN + ASM_REWRITE_TAC[NOT_IMP] THEN + ASM_SIMP_TAC[REAL_LE_DIV; REAL_POS; REAL_LT_IMP_LE; REAL_LE_LDIV_EQ; + REAL_MUL_LID] THEN + ASM_SIMP_TAC[VECTOR_ADD_LDISTRIB; VECTOR_MUL_ASSOC; REAL_DIV_RMUL; + REAL_LT_IMP_NZ] THEN + UNDISCH_TAC `~((y:real^N) IN s)` THEN + MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN + VECTOR_ARITH_TAC; + ALL_TAC] THEN + MATCH_MP_TAC PATH_COMPONENT_OF_SUBSET THEN + EXISTS_TAC `{x:real^N | norm(x - a) = B}` THEN CONJ_TAC THENL + [UNDISCH_TAC `s SUBSET ball(a:real^N,B)` THEN + REWRITE_TAC[SUBSET; IN_ELIM_THM; IN_DIFF; IN_UNIV; IN_BALL; dist] THEN + MESON_TAC[NORM_SUB; REAL_LT_REFL]; + MP_TAC(ISPECL [`a:real^N`; `B:real`] PATH_CONNECTED_SPHERE) THEN + REWRITE_TAC[REWRITE_RULE[ONCE_REWRITE_RULE[DIST_SYM] dist] sphere] THEN + ASM_REWRITE_TAC[PATH_CONNECTED_IFF_PATH_COMPONENT] THEN + DISCH_THEN MATCH_MP_TAC THEN + REWRITE_TAC[IN_ELIM_THM; VECTOR_ADD_SUB; NORM_MUL] THEN + MAP_EVERY EXPAND_TAC ["C"; "D"] THEN + REWRITE_TAC[REAL_ABS_DIV; REAL_ABS_NORM] THEN + ASM_SIMP_TAC[REAL_DIV_RMUL; NORM_EQ_0; VECTOR_SUB_EQ] THEN + ASM_REAL_ARITH_TAC]);; + +let CONNECTED_COMPLEMENT_BOUNDED_CONVEX = prove + (`!s. 2 <= dimindex(:N) /\ bounded s /\ convex s + ==> connected((:real^N) DIFF s)`, + SIMP_TAC[PATH_CONNECTED_IMP_CONNECTED; + PATH_CONNECTED_COMPLEMENT_BOUNDED_CONVEX]);; + +let CONNECTED_DIFF_BALL = prove + (`!s a:real^N r. + 2 <= dimindex(:N) /\ connected s /\ cball(a,r) SUBSET s + ==> connected(s DIFF ball(a,r))`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC CONNECTED_DIFF_OPEN_FROM_CLOSED THEN + EXISTS_TAC `cball(a:real^N,r)` THEN + ASM_REWRITE_TAC[OPEN_BALL; CLOSED_CBALL; BALL_SUBSET_CBALL] THEN + REWRITE_TAC[CBALL_DIFF_BALL] THEN + REWRITE_TAC[ONCE_REWRITE_RULE[DIST_SYM] dist] THEN + ASM_SIMP_TAC[CONNECTED_SPHERE]);; + +let PATH_CONNECTED_DIFF_BALL = prove + (`!s a:real^N r. + 2 <= dimindex(:N) /\ path_connected s /\ cball(a,r) SUBSET s + ==> path_connected(s DIFF ball(a,r))`, + REPEAT STRIP_TAC THEN ASM_CASES_TAC `ball(a:real^N,r) = {}` THEN + ASM_SIMP_TAC[DIFF_EMPTY] THEN + RULE_ASSUM_TAC(REWRITE_RULE[BALL_EQ_EMPTY; REAL_NOT_LE]) THEN + REWRITE_TAC[path_connected] THEN + FIRST_ASSUM(MP_TAC o SPEC `a:real^N` o GEN_REWRITE_RULE I [SUBSET]) THEN + ASM_SIMP_TAC[CENTRE_IN_CBALL; REAL_LT_IMP_LE] THEN DISCH_TAC THEN + MAP_EVERY X_GEN_TAC [`x:real^N`; `y:real^N`] THEN + REWRITE_TAC[IN_DIFF] THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [path_connected]) THEN + DISCH_THEN(fun th -> + MP_TAC(SPECL [`x:real^N`; `a:real^N`] th) THEN + MP_TAC(SPECL [`y:real^N`; `a:real^N`] th)) THEN + ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `g2:real^1->real^N` STRIP_ASSUME_TAC) THEN + DISCH_THEN(X_CHOOSE_THEN `g1:real^1->real^N` STRIP_ASSUME_TAC) THEN + MP_TAC(ISPECL [`g2:real^1->real^N`; `(:real^N) DIFF ball(a,r)`] + EXISTS_PATH_SUBPATH_TO_FRONTIER) THEN + MP_TAC(ISPECL [`g1:real^1->real^N`; `(:real^N) DIFF ball(a,r)`] + EXISTS_PATH_SUBPATH_TO_FRONTIER) THEN + ASM_SIMP_TAC[CENTRE_IN_BALL; IN_DIFF; IN_UNIV; LEFT_IMP_EXISTS_THM] THEN + ASM_SIMP_TAC[FRONTIER_COMPLEMENT; INTERIOR_COMPLEMENT; CLOSURE_BALL] THEN + ASM_SIMP_TAC[FRONTIER_BALL; IN_SPHERE] THEN + X_GEN_TAC `h1:real^1->real^N` THEN STRIP_TAC THEN + X_GEN_TAC `h2:real^1->real^N` THEN STRIP_TAC THEN + MP_TAC(ISPECL [`a:real^N`; `r:real`] PATH_CONNECTED_SPHERE) THEN + ASM_REWRITE_TAC[path_connected] THEN + DISCH_THEN(MP_TAC o SPECL + [`pathfinish h1:real^N`; `pathfinish h2:real^N`]) THEN + ASM_SIMP_TAC[IN_SPHERE] THEN + DISCH_THEN(X_CHOOSE_THEN `h:real^1->real^N` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `h1 ++ h ++ reversepath h2:real^1->real^N` THEN + ASM_SIMP_TAC[PATHSTART_JOIN; PATHFINISH_JOIN; PATHSTART_REVERSEPATH; + PATHFINISH_REVERSEPATH; PATH_JOIN; PATH_REVERSEPATH; + PATH_IMAGE_JOIN; PATH_IMAGE_REVERSEPATH] THEN + REWRITE_TAC[UNION_SUBSET] THEN REPEAT CONJ_TAC THENL + [ALL_TAC; + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + SUBSET_TRANS)) THEN + UNDISCH_TAC `cball(a:real^N,r) SUBSET s` THEN + SIMP_TAC[SUBSET; IN_CBALL; IN_SPHERE; IN_BALL; IN_DIFF] THEN + MESON_TAC[REAL_LE_REFL; REAL_LT_REFL]; + ALL_TAC] THEN + MATCH_MP_TAC(SET_RULE + `s SUBSET t /\ s INTER u = {} ==> s SUBSET t DIFF u`) THEN + (CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC]) THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE + `s DELETE a SUBSET (UNIV DIFF t) ==> ~(a IN u) /\ u SUBSET t + ==> s INTER u = {}`)) THEN + ASM_REWRITE_TAC[BALL_SUBSET_CBALL; IN_BALL; REAL_LT_REFL]);; + +let CONNECTED_OPEN_DIFF_CBALL = prove + (`!s a:real^N r. + 2 <= dimindex (:N) /\ open s /\ connected s /\ cball(a,r) SUBSET s + ==> connected(s DIFF cball(a,r))`, + REPEAT STRIP_TAC THEN + ASM_CASES_TAC `cball(a:real^N,r) = {}` THEN ASM_REWRITE_TAC[DIFF_EMPTY] THEN + RULE_ASSUM_TAC(REWRITE_RULE[CBALL_EQ_EMPTY; REAL_NOT_LT]) THEN + SUBGOAL_THEN `?r'. r < r' /\ cball(a:real^N,r') SUBSET s` + STRIP_ASSUME_TAC THENL + [ASM_CASES_TAC `s = (:real^N)` THENL + [EXISTS_TAC `r + &1` THEN ASM_SIMP_TAC[SUBSET_UNIV] THEN REAL_ARITH_TAC; + ALL_TAC] THEN + MP_TAC(ISPECL [`cball(a:real^N,r)`; `(:real^N) DIFF s`] + SETDIST_POS_LE) THEN + REWRITE_TAC[REAL_ARITH `&0 <= x <=> &0 < x \/ x = &0`] THEN + ASM_SIMP_TAC[SETDIST_EQ_0_COMPACT_CLOSED; GSYM OPEN_CLOSED; + COMPACT_CBALL; CBALL_EQ_EMPTY] THEN + ASM_REWRITE_TAC[SET_RULE `UNIV DIFF s = {} <=> s = UNIV`] THEN + ASM_SIMP_TAC[SET_RULE `b INTER (UNIV DIFF s) = {} <=> b SUBSET s`; + REAL_ARITH `&0 <= r ==> ~(r < &0)`] THEN + STRIP_TAC THEN + EXISTS_TAC `r + setdist(cball(a,r),(:real^N) DIFF s) / &2` THEN + ASM_REWRITE_TAC[REAL_LT_ADDR; REAL_HALF; SUBSET; IN_CBALL] THEN + X_GEN_TAC `x:real^N` THEN ASM_CASES_TAC `x:real^N = a` THENL + [ASM_MESON_TAC[SUBSET; DIST_REFL; IN_CBALL]; ALL_TAC] THEN + ASM_CASES_TAC `(x:real^N) IN s` THEN ASM_REWRITE_TAC[REAL_NOT_LE] THEN + MP_TAC(ISPECL [`cball(a:real^N,r)`; `(:real^N) DIFF s`; + `a + r / dist(a,x) % (x - a):real^N`; `x:real^N`] + SETDIST_LE_DIST) THEN + ASM_REWRITE_TAC[IN_DIFF; IN_UNIV; IN_CBALL] THEN + REWRITE_TAC[NORM_ARITH `dist(a:real^N,a + x) = norm x`] THEN + ASM_SIMP_TAC[NORM_MUL; REAL_ABS_DIV; ONCE_REWRITE_RULE[DIST_SYM] dist; + REAL_ABS_NORM; REAL_DIV_RMUL; NORM_EQ_0; VECTOR_SUB_EQ] THEN + ASM_REWRITE_TAC[REAL_ARITH `abs r <= r <=> &0 <= r`] THEN + REWRITE_TAC[NORM_MUL; VECTOR_ARITH + `x - (a + d % (x - a)):real^N = (&1 - d) % (x - a)`] THEN + ONCE_REWRITE_TAC[GSYM REAL_ABS_NORM] THEN + REWRITE_TAC[GSYM REAL_ABS_MUL] THEN + REWRITE_TAC[REAL_ABS_NORM; REAL_SUB_RDISTRIB] THEN + ASM_SIMP_TAC[REAL_DIV_RMUL; NORM_EQ_0; VECTOR_SUB_EQ] THEN + FIRST_X_ASSUM(MP_TAC o SPEC `x:real^N` o REWRITE_RULE[SUBSET]) THEN + ASM_REWRITE_TAC[IN_CBALL; ONCE_REWRITE_RULE[DIST_SYM] dist] THEN + REAL_ARITH_TAC; + SUBGOAL_THEN `s DIFF cball(a:real^N,r) = + s DIFF ball(a,r') UNION + {x | r < norm(x - a) /\ norm(x - a) <= r'}` + SUBST1_TAC THENL + [REWRITE_TAC[ONCE_REWRITE_RULE[DIST_SYM] (GSYM dist)] THEN + REWRITE_TAC[GSYM REAL_NOT_LE; GSYM IN_CBALL] THEN MATCH_MP_TAC(SET_RULE + `b' SUBSET c' /\ c' SUBSET s /\ c SUBSET b' + ==> s DIFF c = (s DIFF b') UNION {x | ~(x IN c) /\ x IN c'}`) THEN + ASM_REWRITE_TAC[BALL_SUBSET_CBALL] THEN + REWRITE_TAC[SUBSET; IN_BALL; IN_CBALL] THEN ASM_REAL_ARITH_TAC; + MATCH_MP_TAC CONNECTED_UNION THEN + ASM_SIMP_TAC[CONNECTED_ANNULUS; PATH_CONNECTED_DIFF_BALL; + PATH_CONNECTED_IMP_CONNECTED; CONNECTED_OPEN_PATH_CONNECTED] THEN + REWRITE_TAC[ONCE_REWRITE_RULE[DIST_SYM] (GSYM dist)] THEN + REWRITE_TAC[GSYM REAL_NOT_LE; GSYM IN_CBALL] THEN MATCH_MP_TAC(SET_RULE + `c' SUBSET s /\ (?x. x IN c' /\ ~(x IN b') /\ ~(x IN c)) + ==> ~((s DIFF b') INTER {x | ~(x IN c) /\ x IN c'} = {})`) THEN + ASM_REWRITE_TAC[] THEN EXISTS_TAC `a + r' % basis 1:real^N` THEN + REWRITE_TAC[IN_BALL; IN_CBALL] THEN + REWRITE_TAC[NORM_ARITH `dist(a:real^N,a + x) = norm x`] THEN + SIMP_TAC[NORM_MUL; NORM_BASIS; DIMINDEX_GE_1; LE_REFL] THEN + ASM_REAL_ARITH_TAC]]);; + +(* ------------------------------------------------------------------------- *) +(* Existence of unbounded components. *) +(* ------------------------------------------------------------------------- *) + +let COBOUNDED_UNBOUNDED_COMPONENT = prove + (`!s. bounded((:real^N) DIFF s) + ==> ?x. x IN s /\ ~bounded(connected_component s x)`, + REPEAT STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o SPEC `vec 0:real^N` o MATCH_MP BOUNDED_SUBSET_BALL) THEN + DISCH_THEN(X_CHOOSE_THEN `B:real` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `B % basis 1:real^N` THEN CONJ_TAC THENL + [FIRST_X_ASSUM(MP_TAC o SPEC `B % basis 1:real^N` o + GEN_REWRITE_RULE I [SUBSET]) THEN + REWRITE_TAC[IN_UNIV; IN_DIFF; IN_BALL_0] THEN + SIMP_TAC[NORM_MUL; NORM_BASIS; DIMINDEX_GE_1; LE_REFL] THEN + ASM_SIMP_TAC[REAL_ARITH `&0 < B ==> ~(abs B * &1 < B)`]; + MP_TAC(ISPECL [`basis 1:real^N`; `B:real`] BOUNDED_HALFSPACE_GE) THEN + SIMP_TAC[BASIS_NONZERO; DIMINDEX_GE_1; LE_REFL; CONTRAPOS_THM] THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] BOUNDED_SUBSET) THEN + MATCH_MP_TAC CONNECTED_COMPONENT_MAXIMAL THEN + SIMP_TAC[CONVEX_HALFSPACE_GE; CONVEX_CONNECTED] THEN + ASM_SIMP_TAC[IN_ELIM_THM; DOT_RMUL; DOT_BASIS_BASIS; DIMINDEX_GE_1; + LE_REFL; real_ge; REAL_MUL_RID; REAL_LE_REFL] THEN + FIRST_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE + `UNIV DIFF s SUBSET b ==> (!x. x IN h ==> ~(x IN b)) ==> h SUBSET s`)) THEN + SIMP_TAC[IN_ELIM_THM; DOT_BASIS; IN_BALL_0; DIMINDEX_GE_1; LE_REFL] THEN + GEN_TAC THEN REWRITE_TAC[REAL_NOT_LT] THEN + MATCH_MP_TAC(REAL_ARITH `abs x <= n ==> b <= x ==> b <= n`) THEN + SIMP_TAC[COMPONENT_LE_NORM; DIMINDEX_GE_1; LE_REFL]]);; + +let COBOUNDED_UNIQUE_UNBOUNDED_COMPONENT = prove + (`!s x y:real^N. + 2 <= dimindex(:N) /\ bounded((:real^N) DIFF s) /\ + ~bounded(connected_component s x) /\ + ~bounded(connected_component s y) + ==> connected_component s x = connected_component s y`, + REPEAT STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o SPEC `vec 0:real^N` o MATCH_MP BOUNDED_SUBSET_BALL) THEN + DISCH_THEN(X_CHOOSE_THEN `B:real` STRIP_ASSUME_TAC) THEN + MP_TAC(ISPEC `ball(vec 0:real^N,B)` CONNECTED_COMPLEMENT_BOUNDED_CONVEX) THEN + ASM_REWRITE_TAC[BOUNDED_BALL; CONVEX_BALL] THEN DISCH_TAC THEN + MAP_EVERY + (MP_TAC o SPEC `B:real` o REWRITE_RULE[bounded; NOT_EXISTS_THM] o ASSUME) + [`~bounded(connected_component s (y:real^N))`; + `~bounded(connected_component s (x:real^N))`] THEN + REWRITE_TAC[NOT_FORALL_THM; IN; NOT_IMP] THEN + DISCH_THEN(X_CHOOSE_THEN `x':real^N` STRIP_ASSUME_TAC) THEN + DISCH_THEN(X_CHOOSE_THEN `y':real^N` STRIP_ASSUME_TAC) THEN + MATCH_MP_TAC CONNECTED_COMPONENT_EQ THEN REWRITE_TAC[IN] THEN + SUBGOAL_THEN `connected_component s (x':real^N) (y':real^N)` ASSUME_TAC THENL + [REWRITE_TAC[connected_component] THEN + EXISTS_TAC `(:real^N) DIFF ball (vec 0,B)` THEN ASM_REWRITE_TAC[] THEN + CONJ_TAC THENL [ASM SET_TAC[]; REWRITE_TAC[IN_DIFF; IN_UNIV]] THEN + REWRITE_TAC[IN_BALL_0] THEN ASM_MESON_TAC[REAL_LT_IMP_LE]; + ASM_MESON_TAC[CONNECTED_COMPONENT_SYM; CONNECTED_COMPONENT_TRANS]]);; + +let COBOUNDED_UNBOUNDED_COMPONENTS = prove + (`!s. bounded ((:real^N) DIFF s) ==> ?c. c IN components s /\ ~bounded c`, + REWRITE_TAC[components; EXISTS_IN_GSPEC; COBOUNDED_UNBOUNDED_COMPONENT]);; + +let COBOUNDED_UNIQUE_UNBOUNDED_COMPONENTS = prove + (`!s c c'. + 2 <= dimindex(:N) /\ + bounded ((:real^N) DIFF s) /\ + c IN components s /\ ~bounded c /\ + c' IN components s /\ ~bounded c' + ==> c' = c`, + REWRITE_TAC[components; IN_ELIM_THM] THEN + MESON_TAC[COBOUNDED_UNIQUE_UNBOUNDED_COMPONENT]);; + +let COBOUNDED_HAS_BOUNDED_COMPONENT = prove + (`!s. 2 <= dimindex(:N) /\ bounded((:real^N) DIFF s) /\ ~connected s + ==> ?c. c IN components s /\ bounded c`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN + `?c c':real^N->bool. c IN components s /\ c' IN components s /\ ~(c = c')` + STRIP_ASSUME_TAC THENL + [MATCH_MP_TAC(SET_RULE + `~(s = {}) /\ ~(?a. s = {a}) ==> ?x y. x IN s /\ y IN s /\ ~(x = y)`) THEN + ASM_REWRITE_TAC[COMPONENTS_EQ_SING_EXISTS; COMPONENTS_EQ_EMPTY] THEN + ASM_MESON_TAC[DIFF_EMPTY; NOT_BOUNDED_UNIV]; + ASM_MESON_TAC[COBOUNDED_UNIQUE_UNBOUNDED_COMPONENTS]]);; + +(* ------------------------------------------------------------------------- *) +(* Self-homeomorphisms shuffling points about in various ways. *) +(* ------------------------------------------------------------------------- *) + +let HOMEOMORPHISM_MOVING_POINT_EXISTS = prove + (`!s t a b:real^N. + open_in (subtopology euclidean (affine hull s)) s /\ + s SUBSET t /\ t SUBSET affine hull s /\ + connected s /\ a IN s /\ b IN s + ==> ?f g. homeomorphism (t,t) (f,g) /\ f a = b /\ + {x | ~(f x = x /\ g x = x)} SUBSET s /\ + bounded {x | ~(f x = x /\ g x = x)}`, + let lemma1 = prove + (`!a t r u:real^N. + affine t /\ a IN t /\ u IN ball(a,r) INTER t + ==> ?f g. homeomorphism (cball(a,r) INTER t,cball(a,r) INTER t) + (f,g) /\ + f(a) = u /\ (!x. x IN sphere(a,r) ==> f(x) = x)`, + REPEAT STRIP_TAC THEN + DISJ_CASES_TAC(REAL_ARITH `r <= &0 \/ &0 < r`) THENL + [ASM_MESON_TAC[BALL_EMPTY; INTER_EMPTY; NOT_IN_EMPTY]; ALL_TAC] THEN + EXISTS_TAC `\x:real^N. (&1 - norm(x - a) / r) % (u - a) + x` THEN + REWRITE_TAC[LEFT_EXISTS_AND_THM] THEN CONJ_TAC THENL + [MATCH_MP_TAC HOMEOMORPHISM_COMPACT THEN + ASM_SIMP_TAC[COMPACT_INTER_CLOSED; COMPACT_CBALL; CLOSED_AFFINE]; + ASM_SIMP_TAC[IN_SPHERE; ONCE_REWRITE_RULE[NORM_SUB] dist; + REAL_DIV_REFL; REAL_LT_IMP_NZ; IN_INTER] THEN + REWRITE_TAC[real_div; VECTOR_SUB_REFL; NORM_0; REAL_MUL_LZERO] THEN + REPEAT STRIP_TAC THEN VECTOR_ARITH_TAC] THEN + CONJ_TAC THENL + [MATCH_MP_TAC CONTINUOUS_ON_ADD THEN REWRITE_TAC[CONTINUOUS_ON_ID] THEN + MATCH_MP_TAC CONTINUOUS_ON_MUL THEN REWRITE_TAC[o_DEF; LIFT_SUB] THEN + SIMP_TAC[CONTINUOUS_ON_ID; CONTINUOUS_ON_CONST; CONTINUOUS_ON_SUB] THEN + MATCH_MP_TAC CONTINUOUS_ON_SUB THEN REWRITE_TAC[CONTINUOUS_ON_CONST] THEN + REWRITE_TAC[ONCE_REWRITE_RULE[REAL_MUL_SYM] real_div; LIFT_CMUL] THEN + MATCH_MP_TAC CONTINUOUS_ON_CMUL THEN + MATCH_MP_TAC CONTINUOUS_ON_LIFT_NORM_COMPOSE THEN + SIMP_TAC[CONTINUOUS_ON_ID; CONTINUOUS_ON_CONST; CONTINUOUS_ON_SUB]; + ALL_TAC] THEN + CONJ_TAC THENL + [MATCH_MP_TAC(SET_RULE + `(!x. x IN s ==> f x IN s) /\ (!y. y IN s ==> ?x. x IN s /\ f x = y) + ==> IMAGE f s = s`) THEN REWRITE_TAC[] THEN + ONCE_REWRITE_TAC[VECTOR_ARITH + `(&1 - n) % (u - a) + x:real^N = a + (&1 - n) % (u - a) + (x - a)`]; + ALL_TAC] THEN + REPEAT(POP_ASSUM MP_TAC) THEN GEOM_ORIGIN_TAC `a:real^N` THEN + REWRITE_TAC[IN_BALL_0; VECTOR_SUB_RZERO; IN_CBALL_0; IN_INTER] THEN + REWRITE_TAC[VECTOR_ADD_LID; VECTOR_ADD_RID; + VECTOR_ARITH `a + x:real^N = a + y <=> x = y`; + VECTOR_ARITH `(&1 - n) % u + a + x = (&1 - m) % u + a + y <=> + (n - m) % u:real^N = x - y`] THEN + REWRITE_TAC[REAL_ARITH `x / r - y / r:real = (x - y) / r`] THENL + [ALL_TAC; + REPEAT GEN_TAC THEN REPEAT DISCH_TAC THEN REPEAT GEN_TAC THEN + ASM_CASES_TAC `x:real^N = y` THEN ASM_REWRITE_TAC[] THEN + ASM_CASES_TAC `norm(x:real^N) = norm(y:real^N)` THEN + ASM_REWRITE_TAC[real_div; REAL_SUB_REFL; REAL_MUL_LZERO; VECTOR_MUL_LZERO; + VECTOR_ARITH `vec 0:real^N = x - y <=> x = y`] THEN + STRIP_TAC THEN FIRST_ASSUM(MP_TAC o AP_TERM `norm:real^N->real`) THEN + ASM_SIMP_TAC[NORM_MUL; REAL_ABS_MUL; REAL_ABS_INV] THEN + DISCH_THEN(MP_TAC o MATCH_MP (NORM_ARITH + `r = norm(x - y:real^N) ==> r < abs(norm x - norm y) * &1 ==> F`)) THEN + REWRITE_TAC[GSYM REAL_MUL_ASSOC] THEN MATCH_MP_TAC REAL_LT_LMUL THEN + CONJ_TAC THENL [ASM_REAL_ARITH_TAC; ONCE_REWRITE_TAC[REAL_MUL_SYM]] THEN + ASM_SIMP_TAC[GSYM real_div; REAL_LT_LDIV_EQ; + REAL_ARITH `&0 < r ==> &0 < abs r`] THEN + ASM_REAL_ARITH_TAC] THEN + REPEAT GEN_TAC THEN + ASM_CASES_TAC `subspace(t:real^N->bool)` THENL + [ALL_TAC; ASM_MESON_TAC[AFFINE_IMP_SUBSPACE]] THEN + ASM_SIMP_TAC[SUBSPACE_ADD; SUBSPACE_MUL] THEN + REPEAT STRIP_TAC THENL + [MATCH_MP_TAC(NORM_ARITH + `norm(x) + norm(y) <= &1 * r ==> norm(x + y:real^N) <= r`) THEN + ASM_SIMP_TAC[NORM_MUL; GSYM REAL_LE_LDIV_EQ; REAL_ARITH + `(a * u + x) / r:real = a * u / r + x / r`] THEN + MATCH_MP_TAC(REAL_ARITH + `x <= &1 /\ a <= abs(&1 - x) * &1 ==> a + x <= &1`) THEN + ASM_SIMP_TAC[REAL_LE_LDIV_EQ] THEN + CONJ_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN + MATCH_MP_TAC REAL_LE_LMUL THEN REWRITE_TAC[REAL_ABS_POS] THEN + ASM_SIMP_TAC[REAL_LE_LDIV_EQ; REAL_MUL_LID; REAL_LT_IMP_LE]; + ALL_TAC] THEN + MP_TAC(ISPECL + [`\a. lift((&1 - drop a) * r - norm(y - drop a % u:real^N))`; + `vec 0:real^1`; `vec 1:real^1`; `&0`; `1`] + IVT_DECREASING_COMPONENT_1) THEN + REWRITE_TAC[DIMINDEX_1; GSYM drop; LIFT_DROP; DROP_VEC] THEN + REWRITE_TAC[REAL_POS; LE_REFL; REAL_SUB_REFL; VECTOR_MUL_LZERO] THEN + REWRITE_TAC[REAL_SUB_RZERO; VECTOR_SUB_RZERO; REAL_MUL_LID] THEN + REWRITE_TAC[NORM_ARITH `&0 * r - norm(x:real^N) <= &0`] THEN + ASM_REWRITE_TAC[REAL_SUB_LE; GSYM EXISTS_DROP; IN_INTERVAL_1] THEN + ANTS_TAC THENL + [REPEAT STRIP_TAC THEN + REWRITE_TAC[REAL_ARITH `(&1 - x) * r - b:real = r - r * x - b`] THEN + REWRITE_TAC[LIFT_SUB; LIFT_CMUL; LIFT_DROP] THEN + REPEAT(MATCH_MP_TAC CONTINUOUS_SUB THEN CONJ_TAC THEN + REWRITE_TAC[CONTINUOUS_CONST]) THEN + SIMP_TAC[CONTINUOUS_CMUL; CONTINUOUS_AT_ID] THEN + MATCH_MP_TAC CONTINUOUS_LIFT_NORM_COMPOSE THEN + MATCH_MP_TAC CONTINUOUS_SUB THEN REWRITE_TAC[CONTINUOUS_CONST] THEN + MATCH_MP_TAC CONTINUOUS_MUL THEN + REWRITE_TAC[o_DEF; LIFT_DROP; CONTINUOUS_AT_ID; CONTINUOUS_CONST]; + + ASM_SIMP_TAC[DROP_VEC; REAL_FIELD + `&0 < r ==> ((&1 - x) * r - n = &0 <=> &1 - n / r = x)`] THEN + DISCH_THEN(X_CHOOSE_THEN `a:real` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `y - a % u:real^N` THEN ASM_REWRITE_TAC[] THEN + CONJ_TAC THENL [ALL_TAC; VECTOR_ARITH_TAC] THEN + ASM_SIMP_TAC[SUBSPACE_SUB; SUBSPACE_MUL] THEN + GEN_REWRITE_TAC RAND_CONV [GSYM REAL_MUL_LID] THEN + ASM_SIMP_TAC[GSYM REAL_LE_LDIV_EQ] THEN ASM_REAL_ARITH_TAC]) in + let lemma2 = prove + (`!a t u v:real^N r. + affine t /\ a IN t /\ + u IN ball(a,r) INTER t /\ v IN ball(a,r) INTER t + ==> ?f g. homeomorphism (cball(a,r) INTER t,cball(a,r) INTER t) + (f,g) /\ f(u) = v /\ + !x. x IN sphere(a,r) /\ x IN t ==> f(x) = x`, + REPEAT GEN_TAC THEN + DISJ_CASES_TAC(REAL_ARITH `r <= &0 \/ &0 < r`) THENL + [ASM_MESON_TAC[BALL_EMPTY; INTER_EMPTY; NOT_IN_EMPTY]; + REPLICATE_TAC 2 (DISCH_THEN (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + DISCH_TAC] THEN + MP_TAC(ISPECL [`a:real^N`; `t:real^N->bool`; `r:real`] lemma1) THEN + ASM_REWRITE_TAC[] THEN DISCH_THEN(fun th -> + FIRST_ASSUM(CONJUNCTS_THEN(MP_TAC o MATCH_MP th))) THEN + REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`f1:real^N->real^N`; `g1:real^N->real^N`] THEN + STRIP_TAC THEN + MAP_EVERY X_GEN_TAC [`f2:real^N->real^N`; `g2:real^N->real^N`] THEN + STRIP_TAC THEN + EXISTS_TAC `(f1:real^N->real^N) o (g2:real^N->real^N)` THEN + EXISTS_TAC `(f2:real^N->real^N) o (g1:real^N->real^N)` THEN + REWRITE_TAC[o_THM; SUBSET; IN_ELIM_THM] THEN CONJ_TAC THENL + [MATCH_MP_TAC HOMEOMORPHISM_COMPOSE THEN ASM_MESON_TAC[HOMEOMORPHISM_SYM]; + RULE_ASSUM_TAC(REWRITE_RULE[homeomorphism; IN_INTER]) THEN CONJ_TAC THENL + [MP_TAC(ISPECL [`a:real^N`; `r:real`] CENTRE_IN_CBALL) THEN + ASM_SIMP_TAC[REAL_LT_IMP_LE] THEN ASM SET_TAC[]; + MP_TAC(ISPECL [`a:real^N`; `r:real`] SPHERE_SUBSET_CBALL) THEN + ASM SET_TAC[]]]) in + let lemma3 = prove + (`!a t u v:real^N r s. + affine t /\ a IN t /\ ball(a,r) INTER t SUBSET s /\ s SUBSET t /\ + u IN ball(a,r) INTER t /\ v IN ball(a,r) INTER t + ==> ?f g. homeomorphism (s,s) (f,g) /\ f(u) = v /\ + {x | ~(f x = x /\ g x = x)} SUBSET ball(a,r) INTER t`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`a:real^N`; `t:real^N->bool`; `u:real^N`; `v:real^N`; + `r:real`] lemma2) THEN + ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`f:real^N->real^N`; `g:real^N->real^N`] THEN + STRIP_TAC THEN + EXISTS_TAC `\x:real^N. if x IN ball(a,r) INTER t then f x else x` THEN + EXISTS_TAC `\x:real^N. if x IN ball(a,r) INTER t then g x else x` THEN + ASM_REWRITE_TAC[] THEN CONJ_TAC THENL [ALL_TAC; SET_TAC[]] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [HOMEOMORPHISM]) THEN + REWRITE_TAC[HOMEOMORPHISM; SUBSET; FORALL_IN_IMAGE] THEN + STRIP_TAC THEN + SUBGOAL_THEN `(!x:real^N. x IN ball(a,r) INTER t ==> f x IN ball(a,r)) /\ + (!x:real^N. x IN ball(a,r) INTER t ==> g x IN ball(a,r))` + STRIP_ASSUME_TAC THENL + [REWRITE_TAC[GSYM CBALL_DIFF_SPHERE] THEN ASM SET_TAC[]; ALL_TAC] THEN + RULE_ASSUM_TAC(REWRITE_RULE[SUBSET]) THEN + REWRITE_TAC[IN_INTER] THEN REPEAT CONJ_TAC THEN + TRY(X_GEN_TAC `x:real^N` THEN + ASM_CASES_TAC `x IN ball(a:real^N,r)` THEN ASM_SIMP_TAC[] THEN + MP_TAC(ISPECL [`a:real^N`; `r:real`] BALL_SUBSET_CBALL) THEN + REPEAT(COND_CASES_TAC THEN ASM_SIMP_TAC[]) THEN + ASM SET_TAC[]) THEN + MATCH_MP_TAC CONTINUOUS_ON_SUBSET THEN + EXISTS_TAC `(cball(a,r) INTER t) UNION + ((t:real^N->bool) DIFF ball(a,r))` THEN + (CONJ_TAC THENL + [ALL_TAC; + MP_TAC(ISPECL [`a:real^N`; `r:real`] BALL_SUBSET_CBALL) THEN + ASM SET_TAC[]]) THEN + MATCH_MP_TAC CONTINUOUS_ON_CASES THEN + ASM_SIMP_TAC[CLOSED_CBALL; CLOSED_DIFF; OPEN_BALL; CONTINUOUS_ON_ID; + GSYM IN_DIFF; CBALL_DIFF_BALL; CLOSED_AFFINE; CLOSED_INTER] THEN + MP_TAC(ISPECL [`a:real^N`; `r:real`] SPHERE_SUBSET_CBALL) THEN + MP_TAC(ISPECL [`a:real^N`; `r:real`] CBALL_DIFF_BALL) THEN + ASM SET_TAC[]) in + REWRITE_TAC[TAUT `p /\ q /\ r /\ s /\ t ==> u <=> + p /\ q /\ r /\ s ==> t ==> u`] THEN + REWRITE_TAC[RIGHT_FORALL_IMP_THM] THEN REPEAT GEN_TAC THEN STRIP_TAC THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP OPEN_IN_IMP_SUBSET) THEN + ONCE_REWRITE_TAC[TAUT `p ==> q <=> p ==> p /\ q`] THEN + MATCH_MP_TAC CONNECTED_EQUIVALENCE_RELATION THEN ASM_REWRITE_TAC[] THEN + REPEAT CONJ_TAC THEN X_GEN_TAC `a:real^N` THENL + [X_GEN_TAC `b:real^N` THEN + REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + ASM_REWRITE_TAC[] THEN + GEN_REWRITE_TAC LAND_CONV [SWAP_EXISTS_THM] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `f:real^N->real^N` THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `g:real^N->real^N` THEN + REWRITE_TAC[HOMEOMORPHISM] THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + ONCE_REWRITE_TAC[TAUT `~(p /\ q) <=> ~(q /\ p)`] THEN + ASM_REWRITE_TAC[] THEN ASM SET_TAC[]; + MAP_EVERY X_GEN_TAC [`b:real^N`; `c:real^N`] THEN + MAP_EVERY (fun t -> ASM_CASES_TAC t THEN ASM_REWRITE_TAC[]) + [`(a:real^N) IN s`; `(b:real^N) IN s`; `(c:real^N) IN s`] THEN + ASM_REWRITE_TAC[] THEN ONCE_REWRITE_TAC[IMP_CONJ] THEN + REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`f1:real^N->real^N`; `g1:real^N->real^N`] THEN + STRIP_TAC THEN + MAP_EVERY X_GEN_TAC [`f2:real^N->real^N`; `g2:real^N->real^N`] THEN + STRIP_TAC THEN + EXISTS_TAC `(f2:real^N->real^N) o (f1:real^N->real^N)` THEN + EXISTS_TAC `(g1:real^N->real^N) o (g2:real^N->real^N)` THEN + ASM_REWRITE_TAC[o_THM] THEN CONJ_TAC THENL + [ASM_MESON_TAC[HOMEOMORPHISM_COMPOSE]; ALL_TAC] THEN + CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + MATCH_MP_TAC BOUNDED_SUBSET THEN + EXISTS_TAC `{x | ~(f1 x = x /\ g1 x = x)} UNION + {x:real^N | ~(f2 x = x /\ g2 x = x)}` THEN + ASM_REWRITE_TAC[BOUNDED_UNION] THEN ASM SET_TAC[]; + DISCH_TAC THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [OPEN_IN_CONTAINS_BALL]) THEN + DISCH_THEN(MP_TAC o SPEC `a:real^N` o CONJUNCT2) THEN ASM_SIMP_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `r:real` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `s INTER ball(a:real^N,r)` THEN + ASM_SIMP_TAC[IN_INTER; CENTRE_IN_BALL; OPEN_IN_OPEN_INTER; OPEN_BALL] THEN + X_GEN_TAC `b:real^N` THEN STRIP_TAC THEN + MP_TAC(ISPECL + [`a:real^N`; `affine hull s:real^N->bool`; + `a:real^N`; `b:real^N`; `r:real`; `t:real^N->bool`] + lemma3) THEN + ASM_SIMP_TAC[CENTRE_IN_BALL; AFFINE_AFFINE_HULL; HULL_INC; IN_INTER] THEN + ANTS_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + REPEAT(MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC) THEN + ASM_MESON_TAC[BOUNDED_SUBSET; BOUNDED_BALL; INTER_SUBSET; SUBSET_TRANS]]);; + +let HOMEOMORPHISM_MOVING_POINTS_EXISTS_GEN = prove + (`!s t x (y:A->real^N) k. + &2 <= aff_dim s /\ open_in (subtopology euclidean (affine hull s)) s /\ + s SUBSET t /\ t SUBSET affine hull s /\ connected s /\ + FINITE k /\ (!i. i IN k ==> x i IN s /\ y i IN s) /\ + pairwise (\i j. ~(x i = x j) /\ ~(y i = y j)) k + ==> ?f g. homeomorphism (t,t) (f,g) /\ + (!i. i IN k ==> f(x i) = y i) /\ + {x | ~(f x = x /\ g x = x)} SUBSET s /\ + bounded {x | ~(f x = x /\ g x = x)}`, + REPEAT GEN_TAC THEN + ASM_CASES_TAC `FINITE(k:A->bool)` THEN ASM_REWRITE_TAC[] THEN + SPEC_TAC(`s:real^N->bool`,`s:real^N->bool`) THEN POP_ASSUM MP_TAC THEN + SPEC_TAC(`k:A->bool`,`k:A->bool`) THEN MATCH_MP_TAC FINITE_INDUCT_STRONG THEN + CONJ_TAC THENL + [GEN_TAC THEN STRIP_TAC THEN REPEAT(EXISTS_TAC `I:real^N->real^N`) THEN + REWRITE_TAC[HOMEOMORPHISM_I; NOT_IN_EMPTY; I_THM; EMPTY_GSPEC] THEN + REWRITE_TAC[EMPTY_SUBSET; BOUNDED_EMPTY]; + ALL_TAC] THEN + MAP_EVERY X_GEN_TAC [`i:A`; `k:A->bool`] THEN STRIP_TAC THEN + X_GEN_TAC `s:real^N->bool` THEN + REWRITE_TAC[PAIRWISE_INSERT; FORALL_IN_INSERT] THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `s:real^N->bool`) THEN + ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`f:real^N->real^N`; `g:real^N->real^N`] THEN + STRIP_TAC THEN MP_TAC(ISPECL + [`s DIFF IMAGE (y:A->real^N) k`; `t:real^N->bool`; + `(f:real^N->real^N) ((x:A->real^N) i)`; `(y:A->real^N) i`] + HOMEOMORPHISM_MOVING_POINT_EXISTS) THEN + SUBGOAL_THEN + `affine hull (s DIFF (IMAGE (y:A->real^N) k)) = affine hull s` + SUBST1_TAC THENL + [MATCH_MP_TAC AFFINE_HULL_OPEN_IN THEN CONJ_TAC THENL + [TRANS_TAC OPEN_IN_TRANS `s:real^N->bool` THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC OPEN_IN_DIFF THEN REWRITE_TAC[OPEN_IN_REFL] THEN + MATCH_MP_TAC FINITE_IMP_CLOSED_IN THEN + ASM_SIMP_TAC[FINITE_IMAGE] THEN ASM SET_TAC[]; + + REWRITE_TAC[SET_RULE `s DIFF t = {} <=> s SUBSET t`] THEN + DISCH_THEN(MP_TAC o MATCH_MP (ONCE_REWRITE_RULE[IMP_CONJ_ALT] + FINITE_SUBSET)) THEN + ASM_SIMP_TAC[FINITE_IMAGE; CONNECTED_FINITE_IFF_SING] THEN + UNDISCH_TAC `&2 <= aff_dim(s:real^N->bool)` THEN + ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN + REWRITE_TAC[] THEN STRIP_TAC THEN + ASM_REWRITE_TAC[AFF_DIM_EMPTY; AFF_DIM_SING] THEN + CONV_TAC INT_REDUCE_CONV]; + ASM_REWRITE_TAC[]] THEN + ANTS_TAC THENL + [REPEAT CONJ_TAC THENL + [MATCH_MP_TAC OPEN_IN_DIFF THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC FINITE_IMP_CLOSED_IN THEN ASM_SIMP_TAC[FINITE_IMAGE] THEN + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC HULL_INC THEN ASM SET_TAC[]; + ASM SET_TAC[]; + MATCH_MP_TAC CONNECTED_OPEN_IN_DIFF_CARD_LT THEN + ASM_REWRITE_TAC[COLLINEAR_AFF_DIM; + INT_ARITH `~(s:int <= &1) <=> &2 <= s`] THEN + MATCH_MP_TAC CARD_LT_FINITE_INFINITE THEN + ASM_SIMP_TAC[FINITE_IMAGE; real_INFINITE]; + ALL_TAC; ALL_TAC] THEN + RULE_ASSUM_TAC(REWRITE_RULE[homeomorphism]) THEN REWRITE_TAC[IN_DIFF] THEN + (CONJ_TAC THENL [ASM SET_TAC[]; ASM_REWRITE_TAC[IN_DIFF]]) THEN + SIMP_TAC[SET_RULE `~(y IN IMAGE f s) <=> !x. x IN s ==> ~(f x = y)`] THEN + ASM SET_TAC[]; + REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`h:real^N->real^N`; `k:real^N->real^N`] THEN + STRIP_TAC THEN MAP_EVERY EXISTS_TAC + [`(h:real^N->real^N) o (f:real^N->real^N)`; + `(g:real^N->real^N) o (k:real^N->real^N)`] THEN + CONJ_TAC THENL [ASM_MESON_TAC[HOMEOMORPHISM_COMPOSE]; ALL_TAC] THEN + ASM_SIMP_TAC[o_THM] THEN + REPEAT(CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC]) THEN + MATCH_MP_TAC BOUNDED_SUBSET THEN + EXISTS_TAC `{x | ~(f x = x /\ g x = x)} UNION + {x:real^N | ~(h x = x /\ k x = x)}` THEN + ASM_REWRITE_TAC[BOUNDED_UNION] THEN ASM SET_TAC[]]);; + +let HOMEOMORPHISM_MOVING_POINTS_EXISTS = prove + (`!s t x (y:A->real^N) k. + 2 <= dimindex(:N) /\ open s /\ connected s /\ s SUBSET t /\ + FINITE k /\ (!i. i IN k ==> x i IN s /\ y i IN s) /\ + pairwise (\i j. ~(x i = x j) /\ ~(y i = y j)) k + ==> ?f g. homeomorphism (t,t) (f,g) /\ + (!i. i IN k ==> f(x i) = y i) /\ + {x | ~(f x = x /\ g x = x)} SUBSET s /\ + bounded {x | ~(f x = x /\ g x = x)}`, + REPEAT GEN_TAC THEN ASM_CASES_TAC `s:real^N->bool = {}` THENL + [STRIP_TAC THEN REPEAT(EXISTS_TAC `I:real^N->real^N`) THEN + REWRITE_TAC[HOMEOMORPHISM_I; NOT_IN_EMPTY; I_THM; EMPTY_GSPEC] THEN + REWRITE_TAC[EMPTY_SUBSET; BOUNDED_EMPTY] THEN ASM SET_TAC[]; + STRIP_TAC] THEN + MATCH_MP_TAC HOMEOMORPHISM_MOVING_POINTS_EXISTS_GEN THEN + ASM_REWRITE_TAC[] THEN + ONCE_REWRITE_TAC[GSYM AFF_DIM_AFFINE_HULL] THEN + SUBGOAL_THEN `affine hull s = (:real^N)` SUBST1_TAC THENL + [MATCH_MP_TAC AFFINE_HULL_OPEN THEN ASM SET_TAC[]; + ASM_REWRITE_TAC[SUBTOPOLOGY_UNIV; GSYM OPEN_IN; AFF_DIM_UNIV] THEN + ASM_REWRITE_TAC[INT_OF_NUM_LE; SUBSET_UNIV]]);; + +let HOMEOMORPHISM_GROUPING_POINTS_EXISTS = prove + (`!u s t k:real^N->bool. + open u /\ open s /\ connected s /\ ~(u = {}) /\ + FINITE k /\ k SUBSET s /\ u SUBSET s /\ s SUBSET t + ==> ?f g. homeomorphism (t,t) (f,g) /\ + {x | ~(f x = x /\ g x = x)} SUBSET s /\ + bounded {x | ~(f x = x /\ g x = x)} /\ + !x. x IN k ==> (f x) IN u`, + let lemma1 = prove + (`!a b:real^1 c d:real^1. + drop a < drop b /\ drop c < drop d + ==> ?f g. homeomorphism (interval[a,b],interval[c,d]) (f,g) /\ + f(a) = c /\ f(b) = d`, + REPEAT STRIP_TAC THEN EXISTS_TAC + `\x. c + (drop x - drop a) / (drop b - drop a) % (d - c:real^1)` THEN + ASM_SIMP_TAC[REAL_DIV_REFL; REAL_SUB_LT; REAL_LT_IMP_NZ; + REAL_ARITH `(a - a) / x = &0`; LEFT_EXISTS_AND_THM] THEN + CONJ_TAC THENL [ALL_TAC; VECTOR_ARITH_TAC] THEN + MATCH_MP_TAC HOMEOMORPHISM_COMPACT THEN + REWRITE_TAC[COMPACT_INTERVAL] THEN REPEAT CONJ_TAC THENL + [MATCH_MP_TAC CONTINUOUS_ON_ADD THEN REWRITE_TAC[CONTINUOUS_ON_CONST] THEN + MATCH_MP_TAC CONTINUOUS_ON_VMUL THEN + REWRITE_TAC[LIFT_CMUL; real_div; o_DEF] THEN + MATCH_MP_TAC CONTINUOUS_ON_VMUL THEN + REWRITE_TAC[o_DEF; LIFT_SUB; LIFT_DROP] THEN + SIMP_TAC[CONTINUOUS_ON_SUB; CONTINUOUS_ON_CONST; CONTINUOUS_ON_ID]; + REWRITE_TAC[EXTENSION; IN_INTERVAL_1; IN_IMAGE] THEN + ASM_SIMP_TAC[GSYM DROP_EQ; DROP_ADD; DROP_CMUL; DROP_SUB; REAL_FIELD + `a < b /\ c < d + ==> (x = c + (y - a) / (b - a) * (d - c) <=> + a + (x - c) / (d - c) * (b - a) = y)`] THEN + REWRITE_TAC[GSYM EXISTS_DROP; UNWIND_THM1] THEN + REWRITE_TAC[REAL_ARITH + `c <= c + x /\ c + x <= d <=> &0 <= x /\ x <= &1 * (d - c)`] THEN + ASM_SIMP_TAC[REAL_LE_MUL_EQ; REAL_LE_RMUL_EQ; REAL_SUB_LT] THEN + ASM_SIMP_TAC[REAL_LE_LDIV_EQ; REAL_LE_RDIV_EQ; REAL_SUB_LT] THEN + REAL_ARITH_TAC; + ASM_SIMP_TAC[VECTOR_ARITH `a + x:real^N = a + y <=> x = y`; + REAL_FIELD `a < b ==> (x / (b - a) = y / (b - a) <=> x = y)`; + REAL_ARITH `x - a:real = y - a <=> x = y`; + VECTOR_MUL_RCANCEL; DROP_EQ; VECTOR_SUB_EQ] THEN + ASM_MESON_TAC[REAL_LT_REFL]]) in + let lemma2 = prove + (`!a b c:real^1 u v w:real^1 f1 g1 f2 g2. + homeomorphism (interval[a,b],interval[u,v]) (f1,g1) /\ + homeomorphism (interval[b,c],interval[v,w]) (f2,g2) + ==> b IN interval[a,c] /\ v IN interval[u,w] /\ + f1 a = u /\ f1 b = v /\ f2 b = v /\ f2 c = w + ==> ?f g. homeomorphism(interval[a,c],interval[u,w]) (f,g) /\ + f a = u /\ f c = w /\ + (!x. x IN interval[a,b] ==> f x = f1 x) /\ + (!x. x IN interval[b,c] ==> f x = f2 x)`, + REWRITE_TAC[IN_INTERVAL_1] THEN REPEAT STRIP_TAC THEN REPEAT(FIRST_X_ASSUM + (STRIP_ASSUME_TAC o GEN_REWRITE_RULE I [homeomorphism])) THEN + EXISTS_TAC `\x. if drop x <= drop b then (f1:real^1->real^1) x + else f2 x` THEN + ASM_REWRITE_TAC[LEFT_EXISTS_AND_THM; REAL_LE_REFL] THEN + ASM_SIMP_TAC[DROP_EQ; REAL_ARITH `b <= c ==> (c <= b <=> c = b)`] THEN + CONJ_TAC THENL [REWRITE_TAC[GSYM CONJ_ASSOC]; ASM_MESON_TAC[]] THEN + MATCH_MP_TAC HOMEOMORPHISM_COMPACT THEN + REWRITE_TAC[COMPACT_INTERVAL] THEN REPEAT CONJ_TAC THENL + [MATCH_MP_TAC CONTINUOUS_ON_CASES_LE THEN + ASM_SIMP_TAC[o_DEF; LIFT_DROP; CONTINUOUS_ON_ID; DROP_EQ] THEN + CONJ_TAC THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET)) THEN + SIMP_TAC[SUBSET; FORALL_DROP; IN_ELIM_THM; IN_INTERVAL_1]; + SUBGOAL_THEN + `interval[a:real^1,c] = interval[a,b] UNION interval[b,c] /\ + interval[u:real^1,w] = interval[u,v] UNION interval[v,w]` + (CONJUNCTS_THEN SUBST1_TAC) THENL + [REWRITE_TAC[EXTENSION; IN_UNION; IN_INTERVAL_1] THEN + ASM_REAL_ARITH_TAC; + REWRITE_TAC[IMAGE_UNION] THEN BINOP_TAC THEN FIRST_X_ASSUM(fun th -> + GEN_REWRITE_TAC RAND_CONV [SYM th]) THEN + MATCH_MP_TAC(SET_RULE + `(!x. x IN s ==> f x = g x) ==> IMAGE f s = IMAGE g s`) THEN + SIMP_TAC[IN_INTERVAL_1; REAL_ARITH + `b <= c ==> (c <= b <=> c = b)`] THEN + ASM_MESON_TAC[DROP_EQ]]; + REWRITE_TAC[FORALL_LIFT] THEN MATCH_MP_TAC REAL_WLOG_LT THEN + REWRITE_TAC[] THEN CONJ_TAC THENL [MESON_TAC[]; ALL_TAC] THEN + REWRITE_TAC[FORALL_DROP; LIFT_DROP; IN_INTERVAL_1] THEN + MAP_EVERY X_GEN_TAC [`x:real^1`; `y:real^1`] THEN DISCH_TAC THEN + ASM_CASES_TAC `drop y <= drop b` THEN ASM_REWRITE_TAC[] THENL + [COND_CASES_TAC THENL [ALL_TAC; ASM_REAL_ARITH_TAC] THEN + RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1; REAL_NOT_LE]) THEN + ASM_MESON_TAC[]; + ALL_TAC] THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN + RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1; REAL_NOT_LE]) THENL + [ALL_TAC; ASM_MESON_TAC[REAL_LT_IMP_LE]] THEN + STRIP_TAC THEN + SUBGOAL_THEN `(f1:real^1->real^1) x IN interval[u,v] INTER interval[v,w]` + MP_TAC THENL + [REWRITE_TAC[IN_INTER] THEN CONJ_TAC THENL + [ALL_TAC; ASM_REWRITE_TAC[]] THEN + FIRST_X_ASSUM(fun th -> GEN_REWRITE_TAC RAND_CONV [SYM th]) THEN + MATCH_MP_TAC FUN_IN_IMAGE THEN ASM_REWRITE_TAC[IN_INTERVAL_1] THEN + ASM_REAL_ARITH_TAC; + ALL_TAC] THEN + REWRITE_TAC[IN_INTER; IN_INTERVAL_1] THEN DISCH_THEN(MP_TAC o MATCH_MP + (REAL_ARITH `(a <= x /\ x <= b) /\ (b <= x /\ x <= c) ==> x = b`)) THEN + REWRITE_TAC[DROP_EQ] THEN DISCH_TAC THEN + SUBGOAL_THEN + `(f1:real^1->real^1) x = f1 b /\ (f2:real^1->real^1) y = f2 b` + MP_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN + MATCH_MP_TAC(MESON[] + `!g1:real^1->real^1 g2:real^1->real^1. + g1(f1 x) = x /\ g1(f1 b) = b /\ g2(f2 y) = y /\ g2(f2 b) = b + ==> f1 x = f1 b /\ f2 y = f2 b ==> x = y`) THEN + MAP_EVERY EXISTS_TAC [`g1:real^1->real^1`; `g2:real^1->real^1`] THEN + REPEAT CONJ_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_REAL_ARITH_TAC]) in + let lemma3 = prove + (`!a b c d u v:real^1. + interval[c,d] SUBSET interval(a,b) /\ + interval[u,v] SUBSET interval(a,b) /\ + ~(interval(c,d) = {}) /\ ~(interval(u,v) = {}) + ==> ?f g. homeomorphism (interval[a,b],interval[a,b]) (f,g) /\ + f a = a /\ f b = b /\ + !x. x IN interval[c,d] ==> f(x) IN interval[u,v]`, + REPEAT GEN_TAC THEN + REWRITE_TAC[SUBSET_INTERVAL_1; INTERVAL_NE_EMPTY_1] THEN + ASM_CASES_TAC `drop u < drop v` THEN + ASM_SIMP_TAC[REAL_ARITH `u < v ==> ~(v < u)`] THEN + ASM_CASES_TAC `interval[c:real^1,d] = {}` THENL + [DISCH_TAC THEN ASM_REWRITE_TAC[] THEN + REPEAT(EXISTS_TAC `I:real^1->real^1`) THEN + REWRITE_TAC[HOMEOMORPHISM_I; NOT_IN_EMPTY; I_THM]; + RULE_ASSUM_TAC(REWRITE_RULE[INTERVAL_NE_EMPTY_1]) THEN + ASM_SIMP_TAC[REAL_ARITH `c <= d ==> ~(d < c)`] THEN STRIP_TAC] THEN + MP_TAC(ISPECL [`d:real^1`; `b:real^1`; `v:real^1`; `b:real^1`] lemma1) THEN + ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`f3:real^1->real^1`; `g3:real^1->real^1`] THEN + DISCH_THEN(CONJUNCTS_THEN2 MP_TAC STRIP_ASSUME_TAC) THEN + MP_TAC(ISPECL [`c:real^1`; `d:real^1`; `u:real^1`; `v:real^1`] lemma1) THEN + ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`f2:real^1->real^1`; `g2:real^1->real^1`] THEN + DISCH_THEN(CONJUNCTS_THEN2 MP_TAC STRIP_ASSUME_TAC) THEN + MP_TAC(ISPECL [`a:real^1`; `c:real^1`; `a:real^1`; `u:real^1`] lemma1) THEN + ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`f1:real^1->real^1`; `g1:real^1->real^1`] THEN + DISCH_THEN(CONJUNCTS_THEN2 MP_TAC STRIP_ASSUME_TAC) THEN + GEN_REWRITE_TAC I [IMP_IMP] THEN DISCH_THEN(fun th -> + ASSUME_TAC(CONJUNCT2 th) THEN MP_TAC(MATCH_MP lemma2 th)) THEN + ASM_SIMP_TAC[IN_INTERVAL_1; REAL_LT_IMP_LE; LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`f4:real^1->real^1`; `g4:real^1->real^1`] THEN + DISCH_THEN(CONJUNCTS_THEN2 MP_TAC STRIP_ASSUME_TAC) THEN + GEN_REWRITE_TAC I [IMP_IMP] THEN DISCH_THEN(MP_TAC o MATCH_MP lemma2) THEN + ASM_SIMP_TAC[IN_INTERVAL_1; REAL_LT_IMP_LE; LEFT_IMP_EXISTS_THM] THEN + ANTS_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN + REPEAT(MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC) THEN SIMP_TAC[] THEN + DISCH_THEN(STRIP_ASSUME_TAC o CONJUNCT2) THEN + X_GEN_TAC `x:real^1` THEN STRIP_TAC THEN + FIRST_X_ASSUM(STRIP_ASSUME_TAC o GEN_REWRITE_RULE I [HOMEOMORPHISM]) THEN + RULE_ASSUM_TAC(REWRITE_RULE[SUBSET; FORALL_IN_IMAGE; IN_INTERVAL_1]) THEN + SUBGOAL_THEN `drop a <= drop x` ASSUME_TAC THENL + [ASM_REAL_ARITH_TAC; ASM_SIMP_TAC[]]) in + let lemma4 = prove + (`!s k u t:real^1->bool. + open u /\ open s /\ connected s /\ ~(u = {}) /\ + FINITE k /\ k SUBSET s /\ u SUBSET s /\ s SUBSET t + ==> ?f g. homeomorphism (t,t) (f,g) /\ + (!x. x IN k ==> f(x) IN u) /\ + {x | ~(f x = x /\ g x = x)} SUBSET s /\ + bounded {x | ~(f x = x /\ g x = x)}`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN + `?c d:real^1. ~(interval(c,d) = {}) /\ interval[c,d] SUBSET u` + STRIP_ASSUME_TAC THENL + [UNDISCH_TAC `open(u:real^1->bool)` THEN + REWRITE_TAC[OPEN_CONTAINS_INTERVAL] THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN + DISCH_THEN(X_CHOOSE_TAC `y:real^1`) THEN + DISCH_THEN(MP_TAC o SPEC `y:real^1`) THEN + ASM_REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN MESON_TAC[]; + ALL_TAC] THEN + SUBGOAL_THEN + `?a b:real^1. ~(interval(a,b) = {}) /\ + k SUBSET interval[a,b] /\ + interval[a,b] SUBSET s` + STRIP_ASSUME_TAC THENL + [ASM_CASES_TAC `k:real^1->bool = {}` THENL + [ASM_MESON_TAC[SUBSET_TRANS; EMPTY_SUBSET]; ALL_TAC] THEN + MP_TAC(SPEC `IMAGE drop k` COMPACT_ATTAINS_SUP) THEN + MP_TAC(SPEC `IMAGE drop k` COMPACT_ATTAINS_INF) THEN + ASM_SIMP_TAC[GSYM IMAGE_o; o_DEF; LIFT_DROP; IMAGE_EQ_EMPTY; + IMAGE_ID; FINITE_IMP_COMPACT; EXISTS_IN_IMAGE; FORALL_IN_IMAGE] THEN + DISCH_THEN(X_CHOOSE_THEN `a:real^1` STRIP_ASSUME_TAC) THEN + DISCH_THEN(X_CHOOSE_THEN `b:real^1` STRIP_ASSUME_TAC) THEN + UNDISCH_TAC `open(s:real^1->bool)` THEN + REWRITE_TAC[OPEN_CONTAINS_INTERVAL] THEN + DISCH_THEN(MP_TAC o SPEC `b:real^1`) THEN + ANTS_TAC THENL [ASM SET_TAC[]; REWRITE_TAC[LEFT_IMP_EXISTS_THM]] THEN + MAP_EVERY X_GEN_TAC [`u:real^1`; `v:real^1`] THEN + REWRITE_TAC[SUBSET; IN_INTERVAL_1] THEN STRIP_TAC THEN + MAP_EVERY EXISTS_TAC [`a:real^1`; `v:real^1`] THEN + REWRITE_TAC[INTERVAL_NE_EMPTY_1] THEN FIRST_X_ASSUM(MP_TAC o + GEN_REWRITE_RULE I [GSYM IS_INTERVAL_CONNECTED_1]) THEN + REWRITE_TAC[IS_INTERVAL_1] THEN + ASM_MESON_TAC[GSYM MEMBER_NOT_EMPTY; REAL_LET_TRANS; REAL_LE_TRANS; + REAL_LT_IMP_LE; SUBSET; REAL_LE_TOTAL]; + ALL_TAC] THEN + SUBGOAL_THEN + `?w z:real^1. interval[w,z] SUBSET s /\ + interval[a,b] UNION interval[c,d] SUBSET interval(w,z)` + STRIP_ASSUME_TAC THENL + [SUBGOAL_THEN + `?w z:real^1. interval[w,z] SUBSET s /\ + interval[a,b] UNION interval[c,d] SUBSET interval[w,z]` + STRIP_ASSUME_TAC THENL + [EXISTS_TAC `lift(min (drop a) (drop c))` THEN + EXISTS_TAC `lift(max (drop b) (drop d))` THEN + REWRITE_TAC[UNION_SUBSET; SUBSET_INTERVAL_1; LIFT_DROP] THEN + CONJ_TAC THENL + [FIRST_X_ASSUM(MP_TAC o + GEN_REWRITE_RULE I [GSYM IS_INTERVAL_CONNECTED_1]) THEN + REWRITE_TAC[IS_INTERVAL_1; SUBSET; IN_INTERVAL_1; LIFT_DROP] THEN + REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + EXISTS_TAC `lift(min (drop a) (drop c))` THEN + EXISTS_TAC `lift(max (drop b) (drop d))` THEN + ASM_REWRITE_TAC[LIFT_DROP] THEN + REWRITE_TAC[real_min; real_max] THEN CONJ_TAC THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[LIFT_DROP] THEN + ASM_MESON_TAC[ENDS_IN_INTERVAL; SUBSET; INTERVAL_EQ_EMPTY_1; + REAL_LT_IMP_LE]; + ASM_REAL_ARITH_TAC]; + UNDISCH_TAC `open(s:real^1->bool)` THEN + REWRITE_TAC[OPEN_CONTAINS_INTERVAL] THEN DISCH_THEN(fun th -> + MP_TAC(SPEC `z:real^1` th) THEN MP_TAC(SPEC `w:real^1` th)) THEN + SUBGOAL_THEN `(w:real^1) IN interval[w,z] /\ z IN interval[w,z]` + STRIP_ASSUME_TAC THENL + [REWRITE_TAC[ENDS_IN_INTERVAL] THEN MP_TAC + (ISPECL [`a:real^1`; `b:real^1`] INTERVAL_OPEN_SUBSET_CLOSED) THEN + ASM SET_TAC[]; + REWRITE_TAC[UNION_SUBSET]] THEN + ANTS_TAC THENL [ASM SET_TAC[]; REWRITE_TAC[LEFT_IMP_EXISTS_THM]] THEN + MAP_EVERY X_GEN_TAC [`w0:real^1`; `w1:real^1`] THEN + REWRITE_TAC[IN_INTERVAL_1; SUBSET] THEN STRIP_TAC THEN + ANTS_TAC THENL [ASM SET_TAC[]; REWRITE_TAC[LEFT_IMP_EXISTS_THM]] THEN + MAP_EVERY X_GEN_TAC [`z0:real^1`; `z1:real^1`] THEN + STRIP_TAC THEN MAP_EVERY EXISTS_TAC [`w0:real^1`; `z1:real^1`] THEN + RULE_ASSUM_TAC + (REWRITE_RULE[ENDS_IN_UNIT_INTERVAL; INTERVAL_NE_EMPTY_1; + UNION_SUBSET; SUBSET_INTERVAL_1]) THEN + CONJ_TAC THENL [ALL_TAC; ASM_REAL_ARITH_TAC] THEN + RULE_ASSUM_TAC(REWRITE_RULE[SUBSET; IN_INTERVAL_1]) THEN + X_GEN_TAC `x:real^1` THEN + REPEAT(FIRST_X_ASSUM(MP_TAC o SPEC `x:real^1`)) THEN + ASM_CASES_TAC `(x:real^1) IN s` THEN ASM_REWRITE_TAC[] THEN + ASM_REAL_ARITH_TAC]; + ALL_TAC] THEN + FIRST_X_ASSUM(STRIP_ASSUME_TAC o GEN_REWRITE_RULE I [UNION_SUBSET]) THEN + MP_TAC(ISPECL + [`w:real^1`; `z:real^1`; `a:real^1`; `b:real^1`; `c:real^1`; `d:real^1`] + lemma3) THEN + ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`f:real^1->real^1`; `g:real^1->real^1`] THEN + REWRITE_TAC[homeomorphism] THEN STRIP_TAC THEN + EXISTS_TAC `\x:real^1. if x IN interval[w,z] then f x else x` THEN + EXISTS_TAC `\x:real^1. if x IN interval[w,z] then g x else x` THEN + ASSUME_TAC(ISPECL [`w:real^1`; `z:real^1`]INTERVAL_OPEN_SUBSET_CLOSED) THEN + REWRITE_TAC[] THEN REPEAT CONJ_TAC THENL + [ASM SET_TAC[]; + ASM SET_TAC[]; + ALL_TAC; + ASM SET_TAC[]; + ASM SET_TAC[]; + ALL_TAC; + ASM SET_TAC[]; + ASM SET_TAC[]; + MATCH_MP_TAC BOUNDED_SUBSET THEN EXISTS_TAC `interval[w:real^1,z]` THEN + REWRITE_TAC[BOUNDED_INTERVAL] THEN ASM SET_TAC[]] THEN + (SUBGOAL_THEN + `t = interval[w:real^1,z] UNION (t DIFF interval(w,z))` + (fun th -> SUBST1_TAC th THEN + MATCH_MP_TAC CONTINUOUS_ON_CASES_LOCAL THEN + ASSUME_TAC(SYM th)) + THENL [ASM SET_TAC[]; ASM_REWRITE_TAC[]] THEN + ASM_REWRITE_TAC[CONTINUOUS_ON_ID] THEN REPEAT CONJ_TAC THENL + [MATCH_MP_TAC CLOSED_SUBSET THEN REWRITE_TAC[CLOSED_INTERVAL] THEN + ASM SET_TAC[]; + MATCH_MP_TAC CLOSED_IN_DIFF THEN REWRITE_TAC[CLOSED_IN_REFL] THEN + MATCH_MP_TAC OPEN_SUBSET THEN REWRITE_TAC[OPEN_INTERVAL] THEN + ASM SET_TAC[]; + REWRITE_TAC[CLOSED_DIFF_OPEN_INTERVAL_1; SET_RULE + `p /\ ~p \/ x IN t DIFF s /\ x IN u <=> x IN t /\ x IN u DIFF s`] THEN + MAP_EVERY (MP_TAC o ISPECL [`w:real^1`; `z:real^1`]) + (CONJUNCTS ENDS_IN_INTERVAL) THEN + ASM SET_TAC[]])) in + REPEAT STRIP_TAC THEN ASM_CASES_TAC `2 <= dimindex(:N)` THENL + [MP_TAC(ISPECL + [`CARD(k:real^N->bool)`; `u:real^N->bool`] CHOOSE_SUBSET_STRONG) THEN + ANTS_TAC THENL [ASM_MESON_TAC[FINITE_IMP_NOT_OPEN]; ALL_TAC] THEN + REWRITE_TAC[HAS_SIZE; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `p:real^N->bool` THEN STRIP_TAC THEN + MP_TAC(ISPECL [`k:real^N->bool`; `p:real^N->bool`] CARD_EQ_BIJECTION) THEN + ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `y:real^N->real^N` THEN STRIP_TAC THEN + MP_TAC(ISPECL + [`s:real^N->bool`; `t:real^N->bool`; `\x:real^N. x`; + `y:real^N->real^N`; `k:real^N->bool`] + HOMEOMORPHISM_MOVING_POINTS_EXISTS) THEN + ASM_REWRITE_TAC[pairwise] THEN + ANTS_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + REPEAT(MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC) THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN ASM_REWRITE_TAC[] THEN + ASM SET_TAC[]; + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [NOT_LE]) THEN + SIMP_TAC[DIMINDEX_GE_1; ARITH_RULE `1 <= n ==> (n < 2 <=> n = 1)`] THEN + REWRITE_TAC[GSYM DIMINDEX_1] THEN + DISCH_THEN(MP_TAC o MATCH_MP ISOMORPHISMS_UNIV_UNIV) THEN + REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`h:real^N->real^1`; `j:real^1->real^N`] THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + MP_TAC(ISPECL + [`IMAGE (h:real^N->real^1) s`; + `IMAGE (h:real^N->real^1) k`; + `IMAGE (h:real^N->real^1) u`; + `IMAGE (h:real^N->real^1) t`] + lemma4) THEN + ASM_SIMP_TAC[FINITE_IMAGE; IMAGE_SUBSET; IMAGE_EQ_EMPTY; + CONNECTED_CONTINUOUS_IMAGE; LINEAR_CONTINUOUS_ON] THEN + ANTS_TAC THENL + [ASM_MESON_TAC[OPEN_BIJECTIVE_LINEAR_IMAGE_EQ]; + REWRITE_TAC[LEFT_IMP_EXISTS_THM; homeomorphism]] THEN + MAP_EVERY X_GEN_TAC [`f:real^1->real^1`; `g:real^1->real^1`] THEN + STRIP_TAC THEN MAP_EVERY EXISTS_TAC + [`(j:real^1->real^N) o (f:real^1->real^1) o (h:real^N->real^1)`; + `(j:real^1->real^N) o (g:real^1->real^1) o (h:real^N->real^1)`] THEN + ASM_REWRITE_TAC[o_THM; IMAGE_o] THEN + ASM_SIMP_TAC[CONTINUOUS_ON_COMPOSE; LINEAR_CONTINUOUS_ON] THEN + ASM_REWRITE_TAC[GSYM IMAGE_o; o_DEF; IMAGE_ID] THEN + CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + SUBGOAL_THEN + `{x | ~(j ((f:real^1->real^1) (h x)) = x /\ j (g (h x)) = x)} = + IMAGE (j:real^1->real^N) {x | ~(f x = x /\ g x = x)}` + SUBST1_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + CONJ_TAC THENL [ALL_TAC; ASM SET_TAC[]] THEN + ASM_SIMP_TAC[BOUNDED_LINEAR_IMAGE]]);; + +let HOMEOMORPHISM_GROUPING_POINTS_EXISTS_GEN = prove + (`!u s t k:real^N->bool. + open_in (subtopology euclidean (affine hull s)) s /\ + s SUBSET t /\ t SUBSET affine hull s /\ connected s /\ + FINITE k /\ k SUBSET s /\ + open_in (subtopology euclidean s) u /\ ~(u = {}) + ==> ?f g. homeomorphism (t,t) (f,g) /\ + (!x. x IN k ==> f(x) IN u) /\ + {x | ~(f x = x /\ g x = x)} SUBSET s /\ + bounded {x | ~(f x = x /\ g x = x)}`, + REPEAT STRIP_TAC THEN ASM_CASES_TAC `&2 <= aff_dim(s:real^N->bool)` THENL + [MP_TAC(ISPECL + [`CARD(k:real^N->bool)`; `u:real^N->bool`] CHOOSE_SUBSET_STRONG) THEN + ANTS_TAC THENL + [MATCH_MP_TAC(TAUT `~p ==> p ==> q`) THEN REWRITE_TAC[GSYM INFINITE] THEN + MATCH_MP_TAC INFINITE_OPEN_IN THEN + EXISTS_TAC `affine hull s:real^N->bool` THEN CONJ_TAC THENL + [ASM_MESON_TAC[OPEN_IN_TRANS]; ALL_TAC] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `y:real^N` THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC CONNECTED_IMP_PERFECT_AFF_DIM THEN + ASM_SIMP_TAC[CONVEX_CONNECTED; AFFINE_AFFINE_HULL; AFFINE_IMP_CONVEX; + AFF_DIM_AFFINE_HULL] THEN + CONJ_TAC THENL [ASM_INT_ARITH_TAC; ALL_TAC] THEN + ASM_MESON_TAC[OPEN_IN_IMP_SUBSET; SUBSET]; + REWRITE_TAC[HAS_SIZE; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `p:real^N->bool` THEN STRIP_TAC THEN MP_TAC + (ISPECL [`k:real^N->bool`; `p:real^N->bool`] CARD_EQ_BIJECTION) THEN + ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `y:real^N->real^N` THEN STRIP_TAC THEN + MP_TAC(ISPECL + [`s:real^N->bool`; `t:real^N->bool`; `\x:real^N. x`; + `y:real^N->real^N`; `k:real^N->bool`] + HOMEOMORPHISM_MOVING_POINTS_EXISTS_GEN) THEN + ASM_REWRITE_TAC[pairwise] THEN + REPEAT(FIRST_X_ASSUM(ASSUME_TAC o MATCH_MP OPEN_IN_IMP_SUBSET)) THEN + ANTS_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + REPEAT(MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC) THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN ASM_REWRITE_TAC[] THEN + ASM SET_TAC[]]; + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [INT_NOT_LE])] THEN + SIMP_TAC[AFF_DIM_GE; INT_ARITH + `--(&1):int <= x ==> (x < &2 <=> x = --(&1) \/ x = &0 \/ x = &1)`] THEN + REWRITE_TAC[AFF_DIM_EQ_MINUS1; AFF_DIM_EQ_0] THEN + SUBGOAL_THEN + `(u:real^N->bool) SUBSET s /\ s SUBSET affine hull s` + STRIP_ASSUME_TAC THENL [ASM_MESON_TAC[open_in]; ALL_TAC] THEN + DISCH_THEN(DISJ_CASES_THEN MP_TAC) THENL [ASM SET_TAC[]; ALL_TAC] THEN + STRIP_TAC THENL + [REPEAT(EXISTS_TAC `I:real^N->real^N`) THEN + REWRITE_TAC[HOMEOMORPHISM_I; I_THM; EMPTY_GSPEC; BOUNDED_EMPTY] THEN + ASM SET_TAC[]; + ALL_TAC] THEN + MP_TAC(ISPECL [`affine hull s:real^N->bool`; `(:real^1)`] + HOMEOMORPHIC_AFFINE_SETS) THEN + ASM_REWRITE_TAC[AFF_DIM_UNIV; AFFINE_AFFINE_HULL; AFFINE_UNIV] THEN + ASM_REWRITE_TAC[DIMINDEX_1; AFF_DIM_AFFINE_HULL] THEN + REWRITE_TAC[homeomorphic; homeomorphism; LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`h:real^N->real^1`; `j:real^1->real^N`] THEN + STRIP_TAC THEN MP_TAC(ISPECL + [`IMAGE (h:real^N->real^1) u`; `IMAGE (h:real^N->real^1) s`; + `IMAGE (h:real^N->real^1) t`; `IMAGE (h:real^N->real^1) k`] + HOMEOMORPHISM_GROUPING_POINTS_EXISTS) THEN + ASM_SIMP_TAC[FINITE_IMAGE; IMAGE_SUBSET; IMAGE_EQ_EMPTY] THEN + ANTS_TAC THENL + [MP_TAC(ISPECL + [`h:real^N->real^1`; `j:real^1->real^N`; + `affine hull s:real^N->bool`; `(:real^1)`] + HOMEOMORPHISM_IMP_OPEN_MAP) THEN + ASM_SIMP_TAC[homeomorphism; SUBTOPOLOGY_UNIV; GSYM OPEN_IN] THEN + REPEAT STRIP_TAC THENL [ASM_MESON_TAC[OPEN_IN_TRANS]; ALL_TAC] THEN + MATCH_MP_TAC CONNECTED_CONTINUOUS_IMAGE THEN + ASM_MESON_TAC[CONTINUOUS_ON_SUBSET]; + REWRITE_TAC[LEFT_IMP_EXISTS_THM; homeomorphism]] THEN + MAP_EVERY X_GEN_TAC [`f:real^1->real^1`; `g:real^1->real^1`] THEN + STRIP_TAC THEN MAP_EVERY EXISTS_TAC + [`\x. if x IN affine hull s + then ((j:real^1->real^N) o (f:real^1->real^1) o (h:real^N->real^1)) x + else x`; + `\x. if x IN affine hull s + then ((j:real^1->real^N) o (g:real^1->real^1) o (h:real^N->real^1)) x + else x`] THEN + ASM_SIMP_TAC[o_THM; IMAGE_o] THEN REPEAT CONJ_TAC THENL + [ASM SET_TAC[]; + ASM_SIMP_TAC[SET_RULE + `t SUBSET s ==> IMAGE (\x. if x IN s then f x else x) t = IMAGE f t`] THEN + REPLICATE_TAC 3 (ONCE_REWRITE_TAC[GSYM o_DEF]) THEN + ASM_REWRITE_TAC[IMAGE_o] THEN ASM SET_TAC[]; + MATCH_MP_TAC CONTINUOUS_ON_EQ THEN EXISTS_TAC + `(j:real^1->real^N) o (f:real^1->real^1) o (h:real^N->real^1)` THEN + REWRITE_TAC[o_THM] THEN CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + REPEAT(MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN CONJ_TAC) THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET)) THEN + ASM SET_TAC[]; + ASM SET_TAC[]; + ASM_SIMP_TAC[SET_RULE + `t SUBSET s ==> IMAGE (\x. if x IN s then f x else x) t = IMAGE f t`] THEN + REPLICATE_TAC 3 (ONCE_REWRITE_TAC[GSYM o_DEF]) THEN + ASM_REWRITE_TAC[IMAGE_o] THEN ASM SET_TAC[]; + MATCH_MP_TAC CONTINUOUS_ON_EQ THEN EXISTS_TAC + `(j:real^1->real^N) o (g:real^1->real^1) o (h:real^N->real^1)` THEN + REWRITE_TAC[o_THM] THEN CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + REPEAT(MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN CONJ_TAC) THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET)) THEN + ASM SET_TAC[]; + ASM SET_TAC[]; + ALL_TAC; + ALL_TAC] THEN + REWRITE_TAC[MESON[] `(if P then f x else x) = x <=> ~P \/ f x = x`] THEN + REWRITE_TAC[DE_MORGAN_THM; GSYM LEFT_OR_DISTRIB] THEN + (SUBGOAL_THEN + `{x | x IN affine hull s /\ (~(j (f (h x)) = x) \/ ~(j (g (h x)) = x))} = + IMAGE (j:real^1->real^N) {x | ~(f x = x /\ g x = x)}` + SUBST1_TAC THENL [ASM SET_TAC[]; ALL_TAC]) + THENL + [TRANS_TAC SUBSET_TRANS + `IMAGE (j:real^1->real^N) (IMAGE (h:real^N->real^1) s)` THEN + ASM SET_TAC[]; + MATCH_MP_TAC(MESON[CLOSURE_SUBSET; BOUNDED_SUBSET; IMAGE_SUBSET] + `bounded (IMAGE f (closure s)) ==> bounded (IMAGE f s)`) THEN + MATCH_MP_TAC COMPACT_IMP_BOUNDED THEN + MATCH_MP_TAC COMPACT_CONTINUOUS_IMAGE THEN + ASM_REWRITE_TAC[COMPACT_CLOSURE] THEN + ASM_MESON_TAC[CONTINUOUS_ON_SUBSET; SUBSET_UNIV]]);; + +(* ------------------------------------------------------------------------- *) +(* The "inside" and "outside" of a set, i.e. the points respectively in a *) +(* bounded or unbounded connected component of the set's complement. *) +(* ------------------------------------------------------------------------- *) + +let inside = new_definition + `inside s = {x | ~(x IN s) /\ + bounded(connected_component ((:real^N) DIFF s) x)}`;; + +let outside = new_definition + `outside s = {x | ~(x IN s) /\ + ~bounded(connected_component ((:real^N) DIFF s) x)}`;; + +let INSIDE_TRANSLATION = prove + (`!a s. inside(IMAGE (\x. a + x) s) = IMAGE (\x. a + x) (inside s)`, + REWRITE_TAC[inside] THEN GEOM_TRANSLATE_TAC[]);; + +let OUTSIDE_TRANSLATION = prove + (`!a s. outside(IMAGE (\x. a + x) s) = IMAGE (\x. a + x) (outside s)`, + REWRITE_TAC[outside] THEN GEOM_TRANSLATE_TAC[]);; + +add_translation_invariants [INSIDE_TRANSLATION; OUTSIDE_TRANSLATION];; + +let INSIDE_LINEAR_IMAGE = prove + (`!f s. linear f /\ (!x y. f x = f y ==> x = y) /\ (!y. ?x. f x = y) + ==> inside(IMAGE f s) = IMAGE f (inside s)`, + REWRITE_TAC[inside] THEN GEOM_TRANSFORM_TAC[]);; + +let OUTSIDE_LINEAR_IMAGE = prove + (`!f s. linear f /\ (!x y. f x = f y ==> x = y) /\ (!y. ?x. f x = y) + ==> outside(IMAGE f s) = IMAGE f (outside s)`, + REWRITE_TAC[outside] THEN GEOM_TRANSFORM_TAC[]);; + +add_linear_invariants [INSIDE_LINEAR_IMAGE; OUTSIDE_LINEAR_IMAGE];; + +let OUTSIDE = prove + (`!s. outside s = {x | ~bounded(connected_component((:real^N) DIFF s) x)}`, + GEN_TAC THEN REWRITE_TAC[outside; EXTENSION; IN_ELIM_THM] THEN + X_GEN_TAC `x:real^N` THEN ASM_CASES_TAC `(x:real^N) IN s` THEN + ASM_REWRITE_TAC[] THEN + ASM_MESON_TAC[BOUNDED_EMPTY; CONNECTED_COMPONENT_EQ_EMPTY; IN_DIFF]);; + +let INSIDE_NO_OVERLAP = prove + (`!s. inside s INTER s = {}`, + REWRITE_TAC[inside] THEN SET_TAC[]);; + +let OUTSIDE_NO_OVERLAP = prove + (`!s. outside s INTER s = {}`, + REWRITE_TAC[outside] THEN SET_TAC[]);; + +let INSIDE_INTER_OUTSIDE = prove + (`!s. inside s INTER outside s = {}`, + REWRITE_TAC[inside; outside] THEN SET_TAC[]);; + +let INSIDE_UNION_OUTSIDE = prove + (`!s. inside s UNION outside s = (:real^N) DIFF s`, + REWRITE_TAC[inside; outside] THEN SET_TAC[]);; + +let INSIDE_EQ_OUTSIDE = prove + (`!s. inside s = outside s <=> s = (:real^N)`, + REWRITE_TAC[inside; outside] THEN SET_TAC[]);; + +let INSIDE_OUTSIDE = prove + (`!s. inside s = (:real^N) DIFF (s UNION outside s)`, + GEN_TAC THEN MAP_EVERY (MP_TAC o ISPEC `s:real^N->bool`) + [INSIDE_INTER_OUTSIDE; INSIDE_UNION_OUTSIDE] THEN + SET_TAC[]);; + +let OUTSIDE_INSIDE = prove + (`!s. outside s = (:real^N) DIFF (s UNION inside s)`, + GEN_TAC THEN MAP_EVERY (MP_TAC o ISPEC `s:real^N->bool`) + [INSIDE_INTER_OUTSIDE; INSIDE_UNION_OUTSIDE] THEN + SET_TAC[]);; + +let UNION_WITH_INSIDE = prove + (`!s. s UNION inside s = (:real^N) DIFF outside s`, + REWRITE_TAC[OUTSIDE_INSIDE] THEN SET_TAC[]);; + +let UNION_WITH_OUTSIDE = prove + (`!s. s UNION outside s = (:real^N) DIFF inside s`, + REWRITE_TAC[INSIDE_OUTSIDE] THEN SET_TAC[]);; + +let OUTSIDE_MONO = prove + (`!s t. s SUBSET t ==> outside t SUBSET outside s`, + REPEAT GEN_TAC THEN REWRITE_TAC[OUTSIDE; SUBSET; IN_ELIM_THM] THEN + DISCH_TAC THEN GEN_TAC THEN REWRITE_TAC[CONTRAPOS_THM] THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] BOUNDED_SUBSET) THEN + MATCH_MP_TAC CONNECTED_COMPONENT_MONO THEN ASM SET_TAC[]);; + +let INSIDE_MONO = prove + (`!s t. s SUBSET t ==> inside s DIFF t SUBSET inside t`, + REPEAT STRIP_TAC THEN SIMP_TAC[SUBSET; IN_DIFF; inside; IN_ELIM_THM] THEN + GEN_TAC THEN + DISCH_THEN(CONJUNCTS_THEN2 (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) + ASSUME_TAC) THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] BOUNDED_SUBSET) THEN + MATCH_MP_TAC CONNECTED_COMPONENT_MONO THEN ASM SET_TAC[]);; + +let COBOUNDED_OUTSIDE = prove + (`!s:real^N->bool. bounded s ==> bounded((:real^N) DIFF outside s)`, + GEN_TAC THEN DISCH_TAC THEN REWRITE_TAC[outside] THEN + REWRITE_TAC[SET_RULE `UNIV DIFF {x | ~(x IN s) /\ ~P x} = + s UNION {x | P x}`] THEN + ASM_REWRITE_TAC[BOUNDED_UNION] THEN + FIRST_ASSUM(MP_TAC o SPEC `vec 0:real^N` o MATCH_MP BOUNDED_SUBSET_BALL) THEN + DISCH_THEN(X_CHOOSE_THEN `B:real` STRIP_ASSUME_TAC) THEN + MATCH_MP_TAC BOUNDED_SUBSET THEN EXISTS_TAC `ball(vec 0:real^N,B)` THEN + REWRITE_TAC[BOUNDED_BALL; SUBSET; IN_ELIM_THM; IN_BALL_0] THEN + X_GEN_TAC `x:real^N` THEN ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN + REWRITE_TAC[REAL_NOT_LT] THEN + ASM_CASES_TAC `x:real^N = vec 0` THENL + [ASM_REWRITE_TAC[NORM_0] THEN ASM_REAL_ARITH_TAC; DISCH_TAC] THEN + REWRITE_TAC[BOUNDED_POS] THEN + DISCH_THEN(X_CHOOSE_THEN `C:real` STRIP_ASSUME_TAC) THEN + FIRST_X_ASSUM(MP_TAC o SPEC `(B + C) / norm(x) % x:real^N`) THEN + REWRITE_TAC[NORM_MUL; REAL_ABS_DIV; REAL_ABS_NORM] THEN + ASM_SIMP_TAC[REAL_DIV_RMUL; NORM_EQ_0; NOT_IMP] THEN + CONJ_TAC THENL [ALL_TAC; ASM_REAL_ARITH_TAC] THEN + REWRITE_TAC[IN] THEN REWRITE_TAC[connected_component] THEN + EXISTS_TAC `segment[x:real^N,(B + C) / norm(x) % x]` THEN + REWRITE_TAC[ENDS_IN_SEGMENT; CONNECTED_SEGMENT] THEN + MATCH_MP_TAC SUBSET_TRANS THEN + EXISTS_TAC `(:real^N) DIFF ball(vec 0,B)` THEN + ASM_REWRITE_TAC[SET_RULE + `UNIV DIFF s SUBSET UNIV DIFF t <=> t SUBSET s`] THEN + REWRITE_TAC[SUBSET; IN_DIFF; IN_UNIV; IN_BALL_0] THEN + REWRITE_TAC[segment; FORALL_IN_GSPEC] THEN X_GEN_TAC `u:real` THEN + STRIP_TAC THEN REWRITE_TAC[REAL_NOT_LT] THEN + REWRITE_TAC[GSYM VECTOR_ADD_RDISTRIB; NORM_MUL; VECTOR_MUL_ASSOC] THEN + GEN_REWRITE_TAC (RAND_CONV o RAND_CONV) [GSYM REAL_ABS_NORM] THEN + REWRITE_TAC[GSYM REAL_ABS_MUL] THEN MATCH_MP_TAC(REAL_ARITH + `&0 < B /\ B <= x ==> B <= abs x`) THEN + ASM_SIMP_TAC[REAL_ADD_RDISTRIB; REAL_DIV_RMUL; NORM_EQ_0; GSYM + REAL_MUL_ASSOC] THEN + MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `(&1 - u) * B + u * (B + C)` THEN + ASM_SIMP_TAC[REAL_LE_RADD; REAL_LE_LMUL; REAL_SUB_LE] THEN + SIMP_TAC[REAL_ARITH `B <= (&1 - u) * B + u * (B + C) <=> &0 <= u * C`] THEN + MATCH_MP_TAC REAL_LE_MUL THEN ASM_REAL_ARITH_TAC);; + +let UNBOUNDED_OUTSIDE = prove + (`!s:real^N->bool. bounded s ==> ~bounded(outside s)`, + MESON_TAC[COBOUNDED_IMP_UNBOUNDED; COBOUNDED_OUTSIDE]);; + +let BOUNDED_INSIDE = prove + (`!s:real^N->bool. bounded s ==> bounded(inside s)`, + REPEAT STRIP_TAC THEN + MATCH_MP_TAC BOUNDED_SUBSET THEN + EXISTS_TAC `(:real^N) DIFF outside s` THEN + ASM_SIMP_TAC[COBOUNDED_OUTSIDE] THEN + MP_TAC(ISPEC `s:real^N->bool` INSIDE_INTER_OUTSIDE) THEN SET_TAC[]);; + +let CONNECTED_OUTSIDE = prove + (`!s:real^N->bool. 2 <= dimindex(:N) /\ bounded s ==> connected(outside s)`, + REPEAT STRIP_TAC THEN REWRITE_TAC[CONNECTED_IFF_CONNECTED_COMPONENT] THEN + MAP_EVERY X_GEN_TAC [`x:real^N`; `y:real^N`] THEN + REWRITE_TAC[outside; IN_ELIM_THM] THEN STRIP_TAC THEN + MATCH_MP_TAC CONNECTED_COMPONENT_OF_SUBSET THEN + EXISTS_TAC `connected_component ((:real^N) DIFF s) x` THEN + REWRITE_TAC[SUBSET; IN_UNIV; IN_DIFF; IN_ELIM_THM] THEN CONJ_TAC THENL + [X_GEN_TAC `z:real^N` THEN STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o MATCH_MP (REWRITE_RULE[SUBSET] + CONNECTED_COMPONENT_SUBSET)) THEN + REWRITE_TAC[IN_DIFF] THEN ASM_MESON_TAC[CONNECTED_COMPONENT_EQ]; + REWRITE_TAC[CONNECTED_COMPONENT_IDEMP] THEN + SUBGOAL_THEN `connected_component ((:real^N) DIFF s) x = + connected_component ((:real^N) DIFF s) y` + SUBST1_TAC THENL + [MATCH_MP_TAC COBOUNDED_UNIQUE_UNBOUNDED_COMPONENT THEN + ASM_REWRITE_TAC[SET_RULE `UNIV DIFF (UNIV DIFF s) = s`]; + ASM_REWRITE_TAC[CONNECTED_COMPONENT_REFL_EQ; IN_DIFF; IN_UNIV]]]);; + +let OUTSIDE_CONNECTED_COMPONENT_LT = prove + (`!s. outside s = + {x | !B. ?y. B < norm(y) /\ + connected_component((:real^N) DIFF s) x y}`, + REWRITE_TAC[OUTSIDE; bounded; EXTENSION; IN_ELIM_THM] THEN + REWRITE_TAC[IN] THEN ASM_MESON_TAC[REAL_NOT_LE]);; + +let OUTSIDE_CONNECTED_COMPONENT_LE = prove + (`!s. outside s = + {x | !B. ?y. B <= norm(y) /\ + connected_component((:real^N) DIFF s) x y}`, + GEN_TAC THEN REWRITE_TAC[OUTSIDE_CONNECTED_COMPONENT_LT] THEN + GEN_REWRITE_TAC I [EXTENSION] THEN X_GEN_TAC `x:real^N` THEN + REWRITE_TAC[IN_ELIM_THM] THEN + MESON_TAC[REAL_LT_IMP_LE; REAL_ARITH `B + &1 <= x ==> B < x`]);; + +let NOT_OUTSIDE_CONNECTED_COMPONENT_LT = prove + (`!s. 2 <= dimindex(:N) /\ bounded s + ==> (:real^N) DIFF (outside s) = + {x | !B. ?y. B < norm(y) /\ + ~(connected_component((:real^N) DIFF s) x y)}`, + REPEAT STRIP_TAC THEN REWRITE_TAC[OUTSIDE] THEN + REWRITE_TAC[EXTENSION; IN_DIFF; IN_UNIV; IN_ELIM_THM] THEN + X_GEN_TAC `x:real^N` THEN REWRITE_TAC[bounded] THEN EQ_TAC THENL + [DISCH_THEN(X_CHOOSE_TAC `C:real`) THEN X_GEN_TAC `B:real` THEN + EXISTS_TAC `(abs B + abs C + &1) % basis 1:real^N` THEN + RULE_ASSUM_TAC(ONCE_REWRITE_RULE[GSYM CONTRAPOS_THM]) THEN + RULE_ASSUM_TAC(REWRITE_RULE[IN]) THEN + CONJ_TAC THENL [ALL_TAC; FIRST_X_ASSUM MATCH_MP_TAC] THEN + SIMP_TAC[NORM_MUL; NORM_BASIS; DIMINDEX_GE_1; LE_REFL] THEN + REAL_ARITH_TAC; + DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [BOUNDED_POS]) THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `B:real` THEN STRIP_TAC THEN + X_GEN_TAC `y:real^N` THEN REWRITE_TAC[IN] THEN DISCH_TAC THEN + ONCE_REWRITE_TAC[GSYM REAL_NOT_LT] THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `B:real`) THEN DISCH_THEN + (X_CHOOSE_THEN `z:real^N` (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + REWRITE_TAC[] THEN MATCH_MP_TAC CONNECTED_COMPONENT_TRANS THEN + EXISTS_TAC `y:real^N` THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC CONNECTED_COMPONENT_OF_SUBSET THEN + EXISTS_TAC `(:real^N) DIFF cball(vec 0,B)` THEN + ASM_REWRITE_TAC[SUBSET; IN_DIFF; IN_CBALL_0; IN_UNIV; CONTRAPOS_THM] THEN + REWRITE_TAC[connected_component] THEN + EXISTS_TAC `(:real^N) DIFF cball(vec 0,B)` THEN + ASM_SIMP_TAC[SUBSET_REFL; IN_DIFF; IN_UNIV; IN_CBALL_0; REAL_NOT_LE] THEN + MATCH_MP_TAC CONNECTED_COMPLEMENT_BOUNDED_CONVEX THEN + ASM_SIMP_TAC[BOUNDED_CBALL; CONVEX_CBALL]]);; + +let NOT_OUTSIDE_CONNECTED_COMPONENT_LE = prove + (`!s. 2 <= dimindex(:N) /\ bounded s + ==> (:real^N) DIFF (outside s) = + {x | !B. ?y. B <= norm(y) /\ + ~(connected_component((:real^N) DIFF s) x y)}`, + REPEAT STRIP_TAC THEN ASM_SIMP_TAC[NOT_OUTSIDE_CONNECTED_COMPONENT_LT] THEN + GEN_REWRITE_TAC I [EXTENSION] THEN X_GEN_TAC `x:real^N` THEN + REWRITE_TAC[IN_ELIM_THM] THEN + MESON_TAC[REAL_LT_IMP_LE; REAL_ARITH `B + &1 <= x ==> B < x`]);; + +let INSIDE_CONNECTED_COMPONENT_LT = prove + (`!s. 2 <= dimindex(:N) /\ bounded s + ==> inside s = + {x:real^N | ~(x IN s) /\ + !B. ?y. B < norm(y) /\ + ~(connected_component((:real^N) DIFF s) x y)}`, + REPEAT STRIP_TAC THEN REWRITE_TAC[INSIDE_OUTSIDE] THEN + REWRITE_TAC[SET_RULE `UNIV DIFF (s UNION t) = (UNIV DIFF t) DIFF s`] THEN + ASM_SIMP_TAC[NOT_OUTSIDE_CONNECTED_COMPONENT_LT] THEN SET_TAC[]);; + +let INSIDE_CONNECTED_COMPONENT_LE = prove + (`!s. 2 <= dimindex(:N) /\ bounded s + ==> inside s = + {x:real^N | ~(x IN s) /\ + !B. ?y. B <= norm(y) /\ + ~(connected_component((:real^N) DIFF s) x y)}`, + REPEAT STRIP_TAC THEN REWRITE_TAC[INSIDE_OUTSIDE] THEN + REWRITE_TAC[SET_RULE `UNIV DIFF (s UNION t) = (UNIV DIFF t) DIFF s`] THEN + ASM_SIMP_TAC[NOT_OUTSIDE_CONNECTED_COMPONENT_LE] THEN SET_TAC[]);; + +let OUTSIDE_UNION_OUTSIDE_UNION = prove + (`!c c1 c2:real^N->bool. + c INTER outside(c1 UNION c2) = {} + ==> outside(c1 UNION c2) SUBSET outside(c1 UNION c)`, + REPEAT STRIP_TAC THEN REWRITE_TAC[SUBSET] THEN + X_GEN_TAC `x:real^N` THEN + DISCH_THEN(fun th -> ASSUME_TAC th THEN MP_TAC th) THEN + REWRITE_TAC[OUTSIDE_CONNECTED_COMPONENT_LT; IN_ELIM_THM] THEN + MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `B:real` THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `y:real^N` THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + ASM_REWRITE_TAC[connected_component] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `t:real^N->bool` THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + SUBGOAL_THEN `t SUBSET outside(c1 UNION c2:real^N->bool)` + MP_TAC THENL [ALL_TAC; ASM SET_TAC[]] THEN + MATCH_MP_TAC SUBSET_TRANS THEN + EXISTS_TAC `connected_component((:real^N) DIFF (c1 UNION c2)) x` THEN + CONJ_TAC THENL [ASM_MESON_TAC[CONNECTED_COMPONENT_MAXIMAL]; ALL_TAC] THEN + UNDISCH_TAC `(x:real^N) IN outside(c1 UNION c2)` THEN + REWRITE_TAC[OUTSIDE; IN_ELIM_THM; SUBSET] THEN + MESON_TAC[CONNECTED_COMPONENT_EQ]);; + +let INSIDE_SUBSET = prove + (`!s t u. connected u /\ ~bounded u /\ t UNION u = (:real^N) DIFF s + ==> inside s SUBSET t`, + REPEAT STRIP_TAC THEN REWRITE_TAC[SUBSET; inside; IN_ELIM_THM] THEN + X_GEN_TAC `x:real^N` THEN STRIP_TAC THEN + MATCH_MP_TAC(TAUT `(~p ==> F) ==> p`) THEN DISCH_TAC THEN + UNDISCH_TAC `~bounded(u:real^N->bool)` THEN REWRITE_TAC[] THEN + MATCH_MP_TAC BOUNDED_SUBSET THEN + EXISTS_TAC `connected_component((:real^N) DIFF s) x` THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC CONNECTED_COMPONENT_MAXIMAL THEN + ASM_REWRITE_TAC[] THEN ASM SET_TAC[]);; + +let INSIDE_UNIQUE = prove + (`!s t u. connected t /\ bounded t /\ + connected u /\ ~(bounded u) /\ + ~connected((:real^N) DIFF s) /\ + t UNION u = (:real^N) DIFF s + ==> inside s = t`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL + [ASM_MESON_TAC[INSIDE_SUBSET]; ALL_TAC] THEN + REWRITE_TAC[SUBSET; inside; IN_ELIM_THM] THEN + X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN + CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + MATCH_MP_TAC BOUNDED_SUBSET THEN EXISTS_TAC `t:real^N->bool` THEN + ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC(SET_RULE + `!s u. c INTER s = {} /\ c INTER u = {} /\ t UNION u = UNIV DIFF s + ==> c SUBSET t`) THEN + MAP_EVERY EXISTS_TAC [`s:real^N->bool`; `u:real^N->bool`] THEN + ASM_REWRITE_TAC[] THEN CONJ_TAC THENL + [REWRITE_TAC[SET_RULE `c INTER s = {} <=> c SUBSET (UNIV DIFF s)`] THEN + REWRITE_TAC[CONNECTED_COMPONENT_SUBSET]; + ALL_TAC] THEN + MATCH_MP_TAC(SET_RULE `(!x. x IN s /\ x IN t ==> F) ==> s INTER t = {}`) THEN + X_GEN_TAC `y:real^N` THEN + GEN_REWRITE_TAC (LAND_CONV o LAND_CONV) [IN] THEN STRIP_TAC THEN + UNDISCH_TAC `~connected((:real^N) DIFF s)` THEN + REWRITE_TAC[CONNECTED_IFF_CONNECTED_COMPONENT] THEN + MAP_EVERY X_GEN_TAC [`u:real^N`; `v:real^N`] THEN + SUBGOAL_THEN + `(!w. w IN t ==> connected_component ((:real^N) DIFF s) x w) /\ + (!w. w IN u ==> connected_component ((:real^N) DIFF s) y w)` + STRIP_ASSUME_TAC THENL + [CONJ_TAC THEN GEN_TAC THEN DISCH_TAC THEN + REWRITE_TAC[connected_component] THENL + [EXISTS_TAC `t:real^N->bool`; EXISTS_TAC `u:real^N->bool`] THEN + ASM_REWRITE_TAC[] THEN ASM SET_TAC[]; + FIRST_ASSUM(SUBST1_TAC o SYM) THEN REWRITE_TAC[IN_UNION] THEN + ASM_REWRITE_TAC[] THEN + ASM_MESON_TAC[CONNECTED_COMPONENT_TRANS; CONNECTED_COMPONENT_SYM]]);; + +let INSIDE_OUTSIDE_UNIQUE = prove + (`!s t u. connected t /\ bounded t /\ + connected u /\ ~(bounded u) /\ + ~connected((:real^N) DIFF s) /\ + t UNION u = (:real^N) DIFF s + ==> inside s = t /\ outside s = u`, + REPEAT GEN_TAC THEN STRIP_TAC THEN REWRITE_TAC[OUTSIDE_INSIDE] THEN + MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN CONJ_TAC THENL + [ASM_MESON_TAC[INSIDE_UNIQUE]; + MP_TAC(ISPEC `(:real^N) DIFF s` INSIDE_NO_OVERLAP) THEN + SUBGOAL_THEN `t INTER u:real^N->bool = {}` MP_TAC THENL + [ALL_TAC; ASM SET_TAC[]] THEN + UNDISCH_TAC `~connected ((:real^N) DIFF s)` THEN + ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN + FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN DISCH_TAC THEN + REWRITE_TAC[] THEN MATCH_MP_TAC CONNECTED_UNION THEN + ASM_REWRITE_TAC[]]);; + +let INTERIOR_INSIDE_FRONTIER = prove + (`!s:real^N->bool. bounded s ==> interior s SUBSET inside(frontier s)`, + REPEAT STRIP_TAC THEN REWRITE_TAC[inside; SUBSET; IN_ELIM_THM] THEN + X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN + MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN CONJ_TAC THENL + [ASM_REWRITE_TAC[frontier; IN_DIFF]; DISCH_TAC] THEN + MATCH_MP_TAC BOUNDED_SUBSET THEN EXISTS_TAC `s:real^N->bool` THEN + ASM_REWRITE_TAC[SUBSET] THEN X_GEN_TAC `y:real^N` THEN DISCH_TAC THEN + MATCH_MP_TAC(TAUT `(~p ==> F) ==> p`) THEN DISCH_TAC THEN + SUBGOAL_THEN `~(connected_component((:real^N) DIFF frontier s) x INTER + frontier s = {})` + MP_TAC THENL + [MATCH_MP_TAC CONNECTED_INTER_FRONTIER THEN + REWRITE_TAC[CONNECTED_CONNECTED_COMPONENT; GSYM MEMBER_NOT_EMPTY] THEN + CONJ_TAC THENL [REWRITE_TAC[IN_INTER]; ASM SET_TAC[]] THEN + EXISTS_TAC `x:real^N` THEN CONJ_TAC THENL + [REWRITE_TAC[IN; CONNECTED_COMPONENT_REFL_EQ] THEN + GEN_REWRITE_TAC I [GSYM IN] THEN ASM SET_TAC[]; + ASM_MESON_TAC[INTERIOR_SUBSET; SUBSET]]; + REWRITE_TAC[SET_RULE `s INTER t = {} <=> s SUBSET (UNIV DIFF t)`] THEN + REWRITE_TAC[CONNECTED_COMPONENT_SUBSET]]);; + +let INSIDE_EMPTY = prove + (`inside {} = {}`, + REWRITE_TAC[inside; NOT_IN_EMPTY; DIFF_EMPTY; CONNECTED_COMPONENT_UNIV] THEN + REWRITE_TAC[NOT_BOUNDED_UNIV; EMPTY_GSPEC]);; + +let OUTSIDE_EMPTY = prove + (`outside {} = (:real^N)`, + REWRITE_TAC[OUTSIDE_INSIDE; INSIDE_EMPTY] THEN SET_TAC[]);; + +let INSIDE_SAME_COMPONENT = prove + (`!s x y. connected_component((:real^N) DIFF s) x y /\ x IN inside s + ==> y IN inside s`, + REPEAT GEN_TAC THEN + DISCH_THEN(CONJUNCTS_THEN2 (ASSUME_TAC o GEN_REWRITE_RULE I [GSYM IN]) + MP_TAC) THEN + REWRITE_TAC[inside; IN_ELIM_THM] THEN + FIRST_ASSUM(SUBST1_TAC o MATCH_MP CONNECTED_COMPONENT_EQ) THEN + RULE_ASSUM_TAC(REWRITE_RULE[IN]) THEN + FIRST_ASSUM(MP_TAC o MATCH_MP CONNECTED_COMPONENT_IN) THEN + SIMP_TAC[IN_DIFF]);; + +let OUTSIDE_SAME_COMPONENT = prove + (`!s x y. connected_component((:real^N) DIFF s) x y /\ x IN outside s + ==> y IN outside s`, + REPEAT GEN_TAC THEN + DISCH_THEN(CONJUNCTS_THEN2 (ASSUME_TAC o GEN_REWRITE_RULE I [GSYM IN]) + MP_TAC) THEN + REWRITE_TAC[outside; IN_ELIM_THM] THEN + FIRST_ASSUM(SUBST1_TAC o MATCH_MP CONNECTED_COMPONENT_EQ) THEN + RULE_ASSUM_TAC(REWRITE_RULE[IN]) THEN + FIRST_ASSUM(MP_TAC o MATCH_MP CONNECTED_COMPONENT_IN) THEN + SIMP_TAC[IN_DIFF]);; + +let OUTSIDE_CONVEX = prove + (`!s. convex s ==> outside s = (:real^N) DIFF s`, + REWRITE_TAC[GSYM SUBSET_ANTISYM_EQ; + REWRITE_RULE[SET_RULE `t INTER s = {} <=> t SUBSET UNIV DIFF s`] + OUTSIDE_NO_OVERLAP] THEN + REWRITE_TAC[SUBSET; IN_UNIV; IN_DIFF] THEN + MATCH_MP_TAC SET_PROVE_CASES THEN REWRITE_TAC[OUTSIDE_EMPTY; IN_UNIV] THEN + X_GEN_TAC `a:real^N` THEN GEOM_ORIGIN_TAC `a:real^N` THEN + X_GEN_TAC `t:real^N->bool` THEN DISCH_THEN(K ALL_TAC) THEN + MP_TAC(SET_RULE `(vec 0:real^N) IN (vec 0 INSERT t)`) THEN + SPEC_TAC(`(vec 0:real^N) INSERT t`,`s:real^N->bool`) THEN + GEN_TAC THEN DISCH_TAC THEN DISCH_TAC THEN + X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN + ASM_REWRITE_TAC[outside; IN_ELIM_THM] THEN + SUBGOAL_THEN `~(x:real^N = vec 0)` ASSUME_TAC THENL + [ASM_MESON_TAC[]; ALL_TAC] THEN + REWRITE_TAC[BOUNDED_POS; NOT_EXISTS_THM] THEN X_GEN_TAC `B:real` THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + DISCH_THEN(MP_TAC o SPEC `(max (&2) ((B + &1) / norm(x))) % x:real^N`) THEN + REWRITE_TAC[NOT_IMP] THEN CONJ_TAC THENL + [REWRITE_TAC[IN] THEN REWRITE_TAC[connected_component] THEN + EXISTS_TAC `segment[x:real^N,(max (&2) ((B + &1) / norm(x))) % x]` THEN + REWRITE_TAC[ENDS_IN_SEGMENT; CONNECTED_SEGMENT] THEN + REWRITE_TAC[segment; SUBSET; FORALL_IN_GSPEC] THEN X_GEN_TAC `u:real` THEN + ASM_CASES_TAC `u = &0` THEN + ASM_REWRITE_TAC[VECTOR_MUL_LZERO; VECTOR_MUL_LID; REAL_SUB_RZERO; + VECTOR_ADD_RID; IN_DIFF; IN_UNIV] THEN + DISCH_TAC THEN + REWRITE_TAC[VECTOR_ARITH `a % x + b % c % x:real^N = (a + b * c) % x`] THEN + ABBREV_TAC `c = &1 - u + u * max (&2) ((B + &1) / norm(x:real^N))` THEN + DISCH_TAC THEN SUBGOAL_THEN `&1 < c` ASSUME_TAC THENL + [EXPAND_TAC "c" THEN + REWRITE_TAC[REAL_ARITH `&1 < &1 - u + u * x <=> &0 < u * (x - &1)`] THEN + MATCH_MP_TAC REAL_LT_MUL THEN ASM_REAL_ARITH_TAC; + UNDISCH_TAC `~((x:real^N) IN s)` THEN REWRITE_TAC[] THEN + SUBGOAL_THEN `x:real^N = (&1 - inv c) % vec 0 + inv c % c % x` + SUBST1_TAC THENL + [REWRITE_TAC[VECTOR_MUL_RZERO; VECTOR_ADD_LID; VECTOR_MUL_ASSOC] THEN + ASM_SIMP_TAC[REAL_MUL_LINV; REAL_ARITH `&1 < x ==> ~(x = &0)`] THEN + REWRITE_TAC[VECTOR_MUL_LID]; + MATCH_MP_TAC IN_CONVEX_SET THEN + ASM_SIMP_TAC[REAL_LE_INV_EQ; REAL_INV_LE_1; REAL_LT_IMP_LE] THEN + ASM_REAL_ARITH_TAC]]; + ASM_SIMP_TAC[NORM_MUL; REAL_NOT_LE; GSYM REAL_LT_LDIV_EQ; NORM_POS_LT] THEN + MATCH_MP_TAC(REAL_ARITH `&0 < b /\ b < c ==> b < abs(max (&2) c)`) THEN + ASM_SIMP_TAC[REAL_LT_DIV; NORM_POS_LT; REAL_LT_DIV2_EQ] THEN + REAL_ARITH_TAC]);; + +let INSIDE_CONVEX = prove + (`!s. convex s ==> inside s = {}`, + SIMP_TAC[INSIDE_OUTSIDE; OUTSIDE_CONVEX] THEN SET_TAC[]);; + +let OUTSIDE_SUBSET_CONVEX = prove + (`!s t. convex t /\ s SUBSET t ==> (:real^N) DIFF t SUBSET outside s`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC SUBSET_TRANS THEN + EXISTS_TAC `outside(t:real^N->bool)` THEN + ASM_SIMP_TAC[OUTSIDE_MONO] THEN + ASM_SIMP_TAC[OUTSIDE_CONVEX; SUBSET_REFL]);; + +let OUTSIDE_FRONTIER_MISSES_CLOSURE = prove + (`!s. bounded s ==> outside(frontier s) SUBSET (:real^N) DIFF closure s`, + REPEAT STRIP_TAC THEN REWRITE_TAC[OUTSIDE_INSIDE] THEN + SIMP_TAC[SET_RULE `(UNIV DIFF s) SUBSET (UNIV DIFF t) <=> t SUBSET s`] THEN + REWRITE_TAC[frontier] THEN + MATCH_MP_TAC(SET_RULE + `i SUBSET ins ==> c SUBSET (c DIFF i) UNION ins`) THEN + ASM_SIMP_TAC[GSYM frontier; INTERIOR_INSIDE_FRONTIER]);; + +let OUTSIDE_FRONTIER_EQ_COMPLEMENT_CLOSURE = prove + (`!s. bounded s /\ convex s + ==> outside(frontier s) = (:real^N) DIFF closure s`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN + ASM_SIMP_TAC[OUTSIDE_FRONTIER_MISSES_CLOSURE] THEN + MATCH_MP_TAC OUTSIDE_SUBSET_CONVEX THEN + ASM_SIMP_TAC[CONVEX_CLOSURE; frontier] THEN SET_TAC[]);; + +let INSIDE_FRONTIER_EQ_INTERIOR = prove + (`!s:real^N->bool. + bounded s /\ convex s ==> inside(frontier s) = interior s`, + REPEAT STRIP_TAC THEN + ASM_SIMP_TAC[INSIDE_OUTSIDE; OUTSIDE_FRONTIER_EQ_COMPLEMENT_CLOSURE] THEN + REWRITE_TAC[frontier] THEN + MAP_EVERY (MP_TAC o ISPEC `s:real^N->bool`) + [CLOSURE_SUBSET; INTERIOR_SUBSET] THEN + ASM SET_TAC[]);; + +let OPEN_INSIDE = prove + (`!s:real^N->bool. closed s ==> open(inside s)`, + REPEAT STRIP_TAC THEN REWRITE_TAC[OPEN_CONTAINS_BALL] THEN + X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN + SUBGOAL_THEN `open(connected_component ((:real^N) DIFF s) x)` MP_TAC THENL + [MATCH_MP_TAC OPEN_CONNECTED_COMPONENT THEN ASM_REWRITE_TAC[GSYM closed]; + REWRITE_TAC[open_def] THEN DISCH_THEN(MP_TAC o SPEC `x:real^N`) THEN + ANTS_TAC THENL + [REWRITE_TAC[IN; CONNECTED_COMPONENT_REFL_EQ] THEN + GEN_REWRITE_TAC I [GSYM IN] THEN + ASM_REWRITE_TAC[IN_DIFF; IN_UNIV] THEN + MP_TAC(ISPEC `s:real^N->bool` INSIDE_NO_OVERLAP) THEN + ASM SET_TAC[]; + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `e:real` THEN + STRIP_TAC THEN ASM_REWRITE_TAC[SUBSET; IN_BALL] THEN + X_GEN_TAC `y:real^N` THEN DISCH_TAC THEN + MATCH_MP_TAC INSIDE_SAME_COMPONENT THEN + EXISTS_TAC `x:real^N` THEN ASM_REWRITE_TAC[] THEN + RULE_ASSUM_TAC(REWRITE_RULE[IN]) THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_MESON_TAC[DIST_SYM]]]);; + +let OPEN_OUTSIDE = prove + (`!s:real^N->bool. closed s ==> open(outside s)`, + REPEAT STRIP_TAC THEN REWRITE_TAC[OPEN_CONTAINS_BALL] THEN + X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN + SUBGOAL_THEN `open(connected_component ((:real^N) DIFF s) x)` MP_TAC THENL + [MATCH_MP_TAC OPEN_CONNECTED_COMPONENT THEN ASM_REWRITE_TAC[GSYM closed]; + REWRITE_TAC[open_def] THEN DISCH_THEN(MP_TAC o SPEC `x:real^N`) THEN + ANTS_TAC THENL + [REWRITE_TAC[IN; CONNECTED_COMPONENT_REFL_EQ] THEN + GEN_REWRITE_TAC I [GSYM IN] THEN + ASM_REWRITE_TAC[IN_DIFF; IN_UNIV] THEN + MP_TAC(ISPEC `s:real^N->bool` OUTSIDE_NO_OVERLAP) THEN + ASM SET_TAC[]; + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `e:real` THEN + STRIP_TAC THEN ASM_REWRITE_TAC[SUBSET; IN_BALL] THEN + X_GEN_TAC `y:real^N` THEN DISCH_TAC THEN + MATCH_MP_TAC OUTSIDE_SAME_COMPONENT THEN + EXISTS_TAC `x:real^N` THEN ASM_REWRITE_TAC[] THEN + RULE_ASSUM_TAC(REWRITE_RULE[IN]) THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_MESON_TAC[DIST_SYM]]]);; + +let CLOSURE_INSIDE_SUBSET = prove + (`!s:real^N->bool. closed s ==> closure(inside s) SUBSET s UNION inside s`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC CLOSURE_MINIMAL THEN + ASM_SIMP_TAC[closed; GSYM OUTSIDE_INSIDE; OPEN_OUTSIDE] THEN SET_TAC[]);; + +let FRONTIER_INSIDE_SUBSET = prove + (`!s:real^N->bool. closed s ==> frontier(inside s) SUBSET s`, + REPEAT STRIP_TAC THEN + ASM_SIMP_TAC[frontier; OPEN_INSIDE; INTERIOR_OPEN] THEN + FIRST_ASSUM(MP_TAC o MATCH_MP CLOSURE_INSIDE_SUBSET) THEN SET_TAC[]);; + +let CLOSURE_OUTSIDE_SUBSET = prove + (`!s:real^N->bool. closed s ==> closure(outside s) SUBSET s UNION outside s`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC CLOSURE_MINIMAL THEN + ASM_SIMP_TAC[closed; GSYM INSIDE_OUTSIDE; OPEN_INSIDE] THEN SET_TAC[]);; + +let FRONTIER_OUTSIDE_SUBSET = prove + (`!s:real^N->bool. closed s ==> frontier(outside s) SUBSET s`, + REPEAT STRIP_TAC THEN + ASM_SIMP_TAC[frontier; OPEN_OUTSIDE; INTERIOR_OPEN] THEN + FIRST_ASSUM(MP_TAC o MATCH_MP CLOSURE_OUTSIDE_SUBSET) THEN SET_TAC[]);; + +let INSIDE_COMPLEMENT_UNBOUNDED_CONNECTED_EMPTY = prove + (`!s. connected((:real^N) DIFF s) /\ ~bounded((:real^N) DIFF s) + ==> inside s = {}`, + REWRITE_TAC[inside; CONNECTED_CONNECTED_COMPONENT_SET] THEN + REWRITE_TAC[SET_RULE `s = {} <=> !x. x IN s ==> F`] THEN + SIMP_TAC[IN_ELIM_THM; IN_DIFF; IN_UNIV; TAUT `~(a /\ b) <=> a ==> ~b`]);; + +let INSIDE_BOUNDED_COMPLEMENT_CONNECTED_EMPTY = prove + (`!s. connected((:real^N) DIFF s) /\ bounded s + ==> inside s = {}`, + MESON_TAC[INSIDE_COMPLEMENT_UNBOUNDED_CONNECTED_EMPTY; + COBOUNDED_IMP_UNBOUNDED]);; + +let INSIDE_INSIDE = prove + (`!s t:real^N->bool. + s SUBSET inside t ==> inside s DIFF t SUBSET inside t`, + REPEAT STRIP_TAC THEN SIMP_TAC[SUBSET; inside; IN_DIFF; IN_ELIM_THM] THEN + X_GEN_TAC `x:real^N` THEN STRIP_TAC THEN + ASM_CASES_TAC `s INTER connected_component ((:real^N) DIFF t) x = {}` THENL + [MATCH_MP_TAC BOUNDED_SUBSET THEN + EXISTS_TAC `connected_component ((:real^N) DIFF s) x` THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC CONNECTED_COMPONENT_MAXIMAL THEN + REWRITE_TAC[CONNECTED_CONNECTED_COMPONENT; IN] THEN + REWRITE_TAC[CONNECTED_COMPONENT_REFL_EQ] THEN ASM SET_TAC[]; + FIRST_X_ASSUM(MP_TAC o MATCH_MP (SET_RULE + `~(s INTER t = {}) ==> ?x. x IN s /\ x IN t`)) THEN + DISCH_THEN(X_CHOOSE_THEN `y:real^N` + (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + DISCH_THEN(SUBST_ALL_TAC o SYM o MATCH_MP CONNECTED_COMPONENT_EQ) THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [SUBSET]) THEN + DISCH_THEN(MP_TAC o SPEC `y:real^N`) THEN + ASM_SIMP_TAC[inside; IN_ELIM_THM]]);; + +let INSIDE_INSIDE_SUBSET = prove + (`!s:real^N->bool. inside(inside s) SUBSET s`, + GEN_TAC THEN MP_TAC + (ISPECL [`inside s:real^N->bool`; `s:real^N->bool`] INSIDE_INSIDE) THEN + REWRITE_TAC[SUBSET_REFL] THEN + MP_TAC(ISPEC `inside s:real^N->bool` INSIDE_NO_OVERLAP) THEN SET_TAC[]);; + +let INSIDE_OUTSIDE_INTERSECT_CONNECTED = prove + (`!s t:real^N->bool. + connected t /\ ~(inside s INTER t = {}) /\ ~(outside s INTER t = {}) + ==> ~(s INTER t = {})`, + REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + DISCH_THEN(fun th -> DISCH_TAC THEN MP_TAC th) THEN + REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; IN_INTER] THEN + REWRITE_TAC[inside; outside; IN_ELIM_THM] THEN + DISCH_THEN(CONJUNCTS_THEN2 + (X_CHOOSE_THEN `x:real^N` STRIP_ASSUME_TAC) + (X_CHOOSE_THEN `y:real^N` STRIP_ASSUME_TAC)) THEN + SUBGOAL_THEN + `connected_component ((:real^N) DIFF s) y = + connected_component ((:real^N) DIFF s) x` + (fun th -> ASM_MESON_TAC[th]) THEN + ASM_REWRITE_TAC[CONNECTED_COMPONENT_EQ_EQ; IN_DIFF; IN_UNIV] THEN + REWRITE_TAC[connected_component] THEN + EXISTS_TAC `t:real^N->bool` THEN ASM SET_TAC[]);; + +let OUTSIDE_BOUNDED_NONEMPTY = prove + (`!s:real^N->bool. bounded s ==> ~(outside s = {})`, + GEN_TAC THEN + DISCH_THEN(MP_TAC o SPEC `vec 0:real^N` o MATCH_MP BOUNDED_SUBSET_BALL) THEN + DISCH_THEN(X_CHOOSE_THEN `B:real` STRIP_ASSUME_TAC) THEN + FIRST_ASSUM(MP_TAC o MATCH_MP + (REWRITE_RULE[IMP_CONJ_ALT] OUTSIDE_SUBSET_CONVEX)) THEN + ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN + SIMP_TAC[CONVEX_BALL; SUBSET_EMPTY] THEN + REWRITE_TAC[SET_RULE `s DIFF t = {} <=> s SUBSET t`] THEN + MESON_TAC[BOUNDED_BALL; BOUNDED_SUBSET; NOT_BOUNDED_UNIV]);; + +let OUTSIDE_COMPACT_IN_OPEN = prove + (`!s t:real^N->bool. + compact s /\ open t /\ s SUBSET t /\ ~(t = {}) + ==> ~(outside s INTER t = {})`, + REPEAT GEN_TAC THEN STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o MATCH_MP OUTSIDE_BOUNDED_NONEMPTY o + MATCH_MP COMPACT_IMP_BOUNDED) THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN + REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; LEFT_IMP_EXISTS_THM; IN_INTER] THEN + X_GEN_TAC `b:real^N` THEN DISCH_TAC THEN + X_GEN_TAC `a:real^N` THEN DISCH_TAC THEN + ASM_CASES_TAC `(a:real^N) IN t` THENL [ASM_MESON_TAC[]; ALL_TAC] THEN + MP_TAC(ISPECL [`linepath(a:real^N,b)`; `(:real^N) DIFF t`] + EXISTS_PATH_SUBPATH_TO_FRONTIER) THEN + REWRITE_TAC[PATH_LINEPATH; PATHSTART_LINEPATH; PATHFINISH_LINEPATH] THEN + ASM_REWRITE_TAC[IN_DIFF; IN_UNIV; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `g:real^1->real^N` THEN REWRITE_TAC[FRONTIER_COMPLEMENT] THEN + REWRITE_TAC[PATH_IMAGE_LINEPATH; INTERIOR_DIFF; INTERIOR_UNIV] THEN + ABBREV_TAC `c:real^N = pathfinish g` THEN STRIP_TAC THEN + SUBGOAL_THEN `frontier t SUBSET (:real^N) DIFF s` MP_TAC THENL + [ONCE_REWRITE_TAC[GSYM FRONTIER_COMPLEMENT] THEN + REWRITE_TAC[frontier] THEN + ASM_SIMP_TAC[CLOSURE_CLOSED; GSYM OPEN_CLOSED] THEN ASM SET_TAC[]; + REWRITE_TAC[SUBSET; IN_DIFF; IN_UNIV]] THEN + DISCH_THEN(MP_TAC o SPEC `c:real^N`) THEN ASM_REWRITE_TAC[] THEN + DISCH_TAC THEN MP_TAC(ISPEC `(:real^N) DIFF s` OPEN_CONTAINS_CBALL) THEN + ASM_SIMP_TAC[GSYM closed; COMPACT_IMP_CLOSED; IN_DIFF; IN_UNIV] THEN + DISCH_THEN(MP_TAC o SPEC `c:real^N`) THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `e:real` STRIP_ASSUME_TAC) THEN + MP_TAC(ISPECL [`c:real^N`; `t:real^N->bool`] + CLOSURE_APPROACHABLE) THEN + RULE_ASSUM_TAC(REWRITE_RULE[frontier; IN_DIFF]) THEN + ASM_REWRITE_TAC[] THEN + DISCH_THEN(MP_TAC o SPEC `e:real`) THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `d:real^N` THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC OUTSIDE_SAME_COMPONENT THEN + EXISTS_TAC `a:real^N` THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[connected_component] THEN + EXISTS_TAC `path_image(g) UNION segment[c:real^N,d]` THEN + REWRITE_TAC[IN_UNION; ENDS_IN_SEGMENT] THEN CONJ_TAC THENL + [MATCH_MP_TAC CONNECTED_UNION THEN + ASM_SIMP_TAC[CONNECTED_SEGMENT; GSYM MEMBER_NOT_EMPTY; + CONNECTED_PATH_IMAGE] THEN + EXISTS_TAC `c:real^N` THEN REWRITE_TAC[ENDS_IN_SEGMENT; IN_INTER] THEN + ASM_MESON_TAC[PATHFINISH_IN_PATH_IMAGE; SUBSET]; + CONJ_TAC THENL [ALL_TAC; ASM_MESON_TAC[PATHSTART_IN_PATH_IMAGE]] THEN + REWRITE_TAC[UNION_SUBSET] THEN CONJ_TAC THENL + [FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE + `~(c IN s) + ==> (t DELETE c) SUBSET (UNIV DIFF s) + ==> t SUBSET (UNIV DIFF s)`)) THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + SUBSET_TRANS)) THEN + SIMP_TAC[SET_RULE `UNIV DIFF s SUBSET UNIV DIFF t <=> t SUBSET s`] THEN + ASM_MESON_TAC[SUBSET_TRANS; CLOSURE_SUBSET]; + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ_ALT] + SUBSET_TRANS)) THEN + REWRITE_TAC[SEGMENT_CONVEX_HULL] THEN MATCH_MP_TAC HULL_MINIMAL THEN + ASM_SIMP_TAC[CONVEX_CBALL; INSERT_SUBSET; REAL_LT_IMP_LE; + EMPTY_SUBSET; CENTRE_IN_CBALL] THEN + REWRITE_TAC[IN_CBALL] THEN + ASM_MESON_TAC[DIST_SYM; REAL_LT_IMP_LE]]]);; + +let INSIDE_INSIDE_COMPACT_CONNECTED = prove + (`!s t:real^N->bool. + closed s /\ compact t /\ s SUBSET inside t /\ connected t + ==> inside s SUBSET inside t`, + REPEAT GEN_TAC THEN + ASM_CASES_TAC `inside t:real^N->bool = {}` THEN + ASM_SIMP_TAC[INSIDE_EMPTY; SUBSET_EMPTY; EMPTY_SUBSET] THEN + SUBGOAL_THEN `1 <= dimindex(:N)` MP_TAC THENL + [REWRITE_TAC[DIMINDEX_GE_1]; + REWRITE_TAC[ARITH_RULE `1 <= n <=> n = 1 \/ 2 <= n`]] THEN + STRIP_TAC THEN ASM_SIMP_TAC[GSYM CONNECTED_CONVEX_1_GEN] THENL + [ASM_MESON_TAC[INSIDE_CONVEX]; ALL_TAC] THEN + STRIP_TAC THEN FIRST_ASSUM(MP_TAC o MATCH_MP INSIDE_INSIDE) THEN + MATCH_MP_TAC(SET_RULE + `s INTER t = {} ==> s DIFF t SUBSET u ==> s SUBSET u`) THEN + SUBGOAL_THEN `compact(s:real^N->bool)` ASSUME_TAC THENL + [ASM_MESON_TAC[COMPACT_EQ_BOUNDED_CLOSED; BOUNDED_SUBSET; BOUNDED_INSIDE]; + ALL_TAC] THEN + MP_TAC(ISPECL [`s:real^N->bool`; `t:real^N->bool`] + INSIDE_OUTSIDE_INTERSECT_CONNECTED) THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC(TAUT + `r /\ q ==> (~p /\ q ==> ~r) ==> p`) THEN + CONJ_TAC THENL + [MP_TAC(ISPEC `t:real^N->bool` INSIDE_NO_OVERLAP) THEN ASM SET_TAC[]; + ONCE_REWRITE_TAC[INTER_COMM]] THEN + MATCH_MP_TAC INSIDE_OUTSIDE_INTERSECT_CONNECTED THEN + ASM_SIMP_TAC[CONNECTED_OUTSIDE; COMPACT_IMP_BOUNDED] THEN CONJ_TAC THENL + [ONCE_REWRITE_TAC[INTER_COMM] THEN MATCH_MP_TAC OUTSIDE_COMPACT_IN_OPEN THEN + ASM_SIMP_TAC[OPEN_INSIDE; COMPACT_IMP_CLOSED]; + MP_TAC(ISPECL [`s UNION t:real^N->bool`; `vec 0:real^N`] + BOUNDED_SUBSET_BALL) THEN + ASM_SIMP_TAC[BOUNDED_UNION; COMPACT_IMP_BOUNDED] THEN + DISCH_THEN(X_CHOOSE_THEN `r:real` STRIP_ASSUME_TAC) THEN + MATCH_MP_TAC(SET_RULE + `!u. ~(u = UNIV) /\ UNIV DIFF u SUBSET s /\ UNIV DIFF u SUBSET t + ==> ~(s INTER t = {})`) THEN + EXISTS_TAC `ball(vec 0:real^N,r)` THEN CONJ_TAC THENL + [ASM_MESON_TAC[NOT_BOUNDED_UNIV; BOUNDED_BALL]; ALL_TAC] THEN + CONJ_TAC THEN MATCH_MP_TAC OUTSIDE_SUBSET_CONVEX THEN + REWRITE_TAC[CONVEX_BALL] THEN ASM SET_TAC[]]);; + +let CONNECTED_WITH_INSIDE = prove + (`!s:real^N->bool. closed s /\ connected s ==> connected(s UNION inside s)`, + GEN_TAC THEN ASM_CASES_TAC `s UNION inside s = (:real^N)` THEN + ASM_REWRITE_TAC[CONNECTED_UNIV] THEN + REWRITE_TAC[CONNECTED_IFF_CONNECTED_COMPONENT] THEN + REWRITE_TAC[CONNECTED_COMPONENT_SET; IN_ELIM_THM] THEN STRIP_TAC THEN + SUBGOAL_THEN + `!x. x IN (s UNION inside s) + ==> ?y:real^N t. y IN s /\ connected t /\ x IN t /\ y IN t /\ + t SUBSET (s UNION inside s)` + MP_TAC THENL + [X_GEN_TAC `a:real^N` THEN REWRITE_TAC[IN_UNION] THEN STRIP_TAC THENL + [MAP_EVERY EXISTS_TAC [`a:real^N`; `{a:real^N}`] THEN + ASM_REWRITE_TAC[IN_SING; CONNECTED_SING] THEN ASM SET_TAC[]; + FIRST_X_ASSUM(MP_TAC o MATCH_MP (SET_RULE + `~(s UNION t = UNIV) ==> ?b. ~(b IN s) /\ ~(b IN t)`)) THEN + DISCH_THEN(X_CHOOSE_THEN `b:real^N` STRIP_ASSUME_TAC) THEN + MP_TAC(ISPECL [`linepath(a:real^N,b)`; `inside s:real^N->bool`] + EXISTS_PATH_SUBPATH_TO_FRONTIER) THEN + ASM_SIMP_TAC[PATH_LINEPATH; PATHSTART_LINEPATH; PATHFINISH_LINEPATH; + IN_UNION; OPEN_INSIDE; INTERIOR_OPEN] THEN + DISCH_THEN(X_CHOOSE_THEN `g:real^1->real^N` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `pathfinish g :real^N` THEN + EXISTS_TAC `path_image g :real^N->bool` THEN + ASM_SIMP_TAC[PATHFINISH_IN_PATH_IMAGE; CONNECTED_PATH_IMAGE] THEN + MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN + REPEAT STRIP_TAC THENL + [ASM_MESON_TAC[FRONTIER_INSIDE_SUBSET; SUBSET]; + ASM_MESON_TAC[PATHSTART_IN_PATH_IMAGE]; + ASM SET_TAC[]]]; + DISCH_THEN(fun th -> + MAP_EVERY X_GEN_TAC [`x:real^N`; `y:real^N`] THEN STRIP_TAC THEN + MP_TAC(SPEC `y:real^N` th) THEN MP_TAC(SPEC `x:real^N` th)) THEN + ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`a:real^N`; `t:real^N->bool`] THEN STRIP_TAC THEN + MAP_EVERY X_GEN_TAC [`b:real^N`; `u:real^N->bool`] THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`a:real^N`; `b:real^N`]) THEN + ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `v:real^N->bool` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `t UNION v UNION u:real^N->bool` THEN + CONJ_TAC THENL [ALL_TAC; ASM SET_TAC[]] THEN + REPEAT(MATCH_MP_TAC CONNECTED_UNION THEN + ASM_REWRITE_TAC[] THEN REPEAT CONJ_TAC) THEN + ASM SET_TAC[]]);; + +let CONNECTED_WITH_OUTSIDE = prove + (`!s:real^N->bool. closed s /\ connected s ==> connected(s UNION outside s)`, + GEN_TAC THEN ASM_CASES_TAC `s UNION outside s = (:real^N)` THEN + ASM_REWRITE_TAC[CONNECTED_UNIV] THEN + REWRITE_TAC[CONNECTED_IFF_CONNECTED_COMPONENT] THEN + REWRITE_TAC[CONNECTED_COMPONENT_SET; IN_ELIM_THM] THEN STRIP_TAC THEN + SUBGOAL_THEN + `!x. x IN (s UNION outside s) + ==> ?y:real^N t. y IN s /\ connected t /\ x IN t /\ y IN t /\ + t SUBSET (s UNION outside s)` + MP_TAC THENL + [X_GEN_TAC `a:real^N` THEN REWRITE_TAC[IN_UNION] THEN STRIP_TAC THENL + [MAP_EVERY EXISTS_TAC [`a:real^N`; `{a:real^N}`] THEN + ASM_REWRITE_TAC[IN_SING; CONNECTED_SING] THEN ASM SET_TAC[]; + FIRST_X_ASSUM(MP_TAC o MATCH_MP (SET_RULE + `~(s UNION t = UNIV) ==> ?b. ~(b IN s) /\ ~(b IN t)`)) THEN + DISCH_THEN(X_CHOOSE_THEN `b:real^N` STRIP_ASSUME_TAC) THEN + MP_TAC(ISPECL [`linepath(a:real^N,b)`; `outside s:real^N->bool`] + EXISTS_PATH_SUBPATH_TO_FRONTIER) THEN + ASM_SIMP_TAC[PATH_LINEPATH; PATHSTART_LINEPATH; PATHFINISH_LINEPATH; + IN_UNION; OPEN_OUTSIDE; INTERIOR_OPEN] THEN + DISCH_THEN(X_CHOOSE_THEN `g:real^1->real^N` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `pathfinish g :real^N` THEN + EXISTS_TAC `path_image g :real^N->bool` THEN + ASM_SIMP_TAC[PATHFINISH_IN_PATH_IMAGE; CONNECTED_PATH_IMAGE] THEN + MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN + REPEAT STRIP_TAC THENL + [ASM_MESON_TAC[FRONTIER_OUTSIDE_SUBSET; SUBSET]; + ASM_MESON_TAC[PATHSTART_IN_PATH_IMAGE]; + ASM SET_TAC[]]]; + DISCH_THEN(fun th -> + MAP_EVERY X_GEN_TAC [`x:real^N`; `y:real^N`] THEN STRIP_TAC THEN + MP_TAC(SPEC `y:real^N` th) THEN MP_TAC(SPEC `x:real^N` th)) THEN + ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`a:real^N`; `t:real^N->bool`] THEN STRIP_TAC THEN + MAP_EVERY X_GEN_TAC [`b:real^N`; `u:real^N->bool`] THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`a:real^N`; `b:real^N`]) THEN + ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `v:real^N->bool` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `t UNION v UNION u:real^N->bool` THEN + CONJ_TAC THENL [ALL_TAC; ASM SET_TAC[]] THEN + REPEAT(MATCH_MP_TAC CONNECTED_UNION THEN + ASM_REWRITE_TAC[] THEN REPEAT CONJ_TAC) THEN + ASM SET_TAC[]]);; + +let INSIDE_INSIDE_EQ_EMPTY = prove + (`!s:real^N->bool. + closed s /\ connected s ==> inside(inside s) = {}`, + REPEAT STRIP_TAC THEN REWRITE_TAC[EXTENSION; NOT_IN_EMPTY] THEN + X_GEN_TAC `x:real^N` THEN ONCE_REWRITE_TAC[inside] THEN + REWRITE_TAC[IN_ELIM_THM] THEN + ONCE_REWRITE_TAC[INSIDE_OUTSIDE] THEN + REWRITE_TAC[SET_RULE `UNIV DIFF (UNIV DIFF s) = s`] THEN + REWRITE_TAC[IN_DIFF; IN_UNIV] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + ASM_SIMP_TAC[CONNECTED_COMPONENT_EQ_SELF; CONNECTED_WITH_OUTSIDE] THEN + REWRITE_TAC[BOUNDED_UNION] THEN MESON_TAC[UNBOUNDED_OUTSIDE]);; + +let INSIDE_IN_COMPONENTS = prove + (`!s. (inside s) IN components((:real^N) DIFF s) <=> + connected(inside s) /\ ~(inside s = {})`, + X_GEN_TAC `s:real^N->bool` THEN REWRITE_TAC[IN_COMPONENTS_MAXIMAL] THEN + ASM_CASES_TAC `inside s:real^N->bool = {}` THEN ASM_REWRITE_TAC[] THEN + ASM_CASES_TAC `connected(inside s:real^N->bool)` THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[SET_RULE `s SUBSET UNIV DIFF t <=> s INTER t = {}`] THEN + REWRITE_TAC[INSIDE_NO_OVERLAP] THEN + X_GEN_TAC `d:real^N->bool` THEN STRIP_TAC THEN + ASM_REWRITE_TAC[GSYM SUBSET_ANTISYM_EQ] THEN + REWRITE_TAC[SUBSET] THEN X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN + MATCH_MP_TAC INSIDE_SAME_COMPONENT THEN + UNDISCH_TAC `~(inside s:real^N->bool = {})` THEN + REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN MATCH_MP_TAC MONO_EXISTS THEN + X_GEN_TAC `a:real^N` THEN DISCH_TAC THEN + ASM_REWRITE_TAC[connected_component] THEN + EXISTS_TAC `d:real^N->bool` THEN ASM SET_TAC[]);; + +let OUTSIDE_IN_COMPONENTS = prove + (`!s. (outside s) IN components((:real^N) DIFF s) <=> + connected(outside s) /\ ~(outside s = {})`, + X_GEN_TAC `s:real^N->bool` THEN REWRITE_TAC[IN_COMPONENTS_MAXIMAL] THEN + ASM_CASES_TAC `outside s:real^N->bool = {}` THEN ASM_REWRITE_TAC[] THEN + ASM_CASES_TAC `connected(outside s:real^N->bool)` THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[SET_RULE `s SUBSET UNIV DIFF t <=> s INTER t = {}`] THEN + REWRITE_TAC[OUTSIDE_NO_OVERLAP] THEN + X_GEN_TAC `d:real^N->bool` THEN STRIP_TAC THEN + ASM_REWRITE_TAC[GSYM SUBSET_ANTISYM_EQ] THEN + REWRITE_TAC[SUBSET] THEN X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN + MATCH_MP_TAC OUTSIDE_SAME_COMPONENT THEN + UNDISCH_TAC `~(outside s:real^N->bool = {})` THEN + REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN MATCH_MP_TAC MONO_EXISTS THEN + X_GEN_TAC `a:real^N` THEN DISCH_TAC THEN + ASM_REWRITE_TAC[connected_component] THEN + EXISTS_TAC `d:real^N->bool` THEN ASM SET_TAC[]);; + +let BOUNDED_UNIQUE_OUTSIDE = prove + (`!c s. 2 <= dimindex(:N) /\ bounded s + ==> (c IN components ((:real^N) DIFF s) /\ ~bounded c <=> + c = outside s)`, + REPEAT STRIP_TAC THEN EQ_TAC THEN STRIP_TAC THENL + [MATCH_MP_TAC COBOUNDED_UNIQUE_UNBOUNDED_COMPONENTS THEN + EXISTS_TAC `(:real^N) DIFF s` THEN + ASM_REWRITE_TAC[SET_RULE `UNIV DIFF (UNIV DIFF s) = s`] THEN + ASM_REWRITE_TAC[OUTSIDE_IN_COMPONENTS]; + ASM_REWRITE_TAC[OUTSIDE_IN_COMPONENTS]] THEN + ASM_SIMP_TAC[UNBOUNDED_OUTSIDE; OUTSIDE_BOUNDED_NONEMPTY; + CONNECTED_OUTSIDE]);; + +(* ------------------------------------------------------------------------- *) +(* Homotopy of maps p,q : X->Y with property P of all intermediate maps. *) +(* We often just want to require that it fixes some subset, but to take in *) +(* the case of loop homotopy it's convenient to have a general property P. *) +(* ------------------------------------------------------------------------- *) + +let homotopic_with = new_definition + `homotopic_with P (X,Y) p q <=> + ?h:real^(1,M)finite_sum->real^N. + h continuous_on (interval[vec 0,vec 1] PCROSS X) /\ + IMAGE h (interval[vec 0,vec 1] PCROSS X) SUBSET Y /\ + (!x. h(pastecart (vec 0) x) = p x) /\ + (!x. h(pastecart (vec 1) x) = q x) /\ + (!t. t IN interval[vec 0,vec 1] ==> P(\x. h(pastecart t x)))`;; + +(* ------------------------------------------------------------------------- *) +(* We often want to just localize the ending function equality or whatever. *) +(* ------------------------------------------------------------------------- *) + +let HOMOTOPIC_WITH = prove + (`(!h k. (!x. x IN X ==> h x = k x) ==> (P h <=> P k)) + ==> (homotopic_with P (X,Y) p q <=> + ?h:real^(1,M)finite_sum->real^N. + h continuous_on (interval[vec 0,vec 1] PCROSS X) /\ + IMAGE h (interval[vec 0,vec 1] PCROSS X) SUBSET Y /\ + (!x. x IN X ==> h(pastecart (vec 0) x) = p x) /\ + (!x. x IN X ==> h(pastecart (vec 1) x) = q x) /\ + (!t. t IN interval[vec 0,vec 1] ==> P(\x. h(pastecart t x))))`, + REPEAT GEN_TAC THEN DISCH_TAC THEN EQ_TAC THENL + [REWRITE_TAC[homotopic_with; PCROSS] THEN + MATCH_MP_TAC MONO_EXISTS THEN SIMP_TAC[]; + REWRITE_TAC[homotopic_with; PCROSS] THEN + DISCH_THEN(X_CHOOSE_THEN `h:real^(1,M)finite_sum->real^N` + (fun th -> EXISTS_TAC + `\y. if sndcart(y) IN X then (h:real^(1,M)finite_sum->real^N) y + else if fstcart(y) = vec 0 then p(sndcart y) + else q(sndcart y)` THEN + MP_TAC th)) THEN + REWRITE_TAC[FSTCART_PASTECART; SNDCART_PASTECART; VEC_EQ; ARITH_EQ] THEN + REPEAT(MATCH_MP_TAC MONO_AND THEN CONJ_TAC) THENL + [MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] CONTINUOUS_ON_EQ) THEN + SIMP_TAC[FORALL_IN_GSPEC; SNDCART_PASTECART]; + SIMP_TAC[FORALL_IN_IMAGE; FORALL_IN_GSPEC; SUBSET] THEN + SIMP_TAC[FORALL_IN_GSPEC; SNDCART_PASTECART]; + ASM_MESON_TAC[]; + ASM_MESON_TAC[]; + MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `t:real^1` THEN + MATCH_MP_TAC MONO_IMP THEN REWRITE_TAC[] THEN + MATCH_MP_TAC EQ_IMP THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + SIMP_TAC[]]]);; + +let HOMOTOPIC_WITH_EQ = prove + (`!P X Y f g f' g':real^M->real^N. + homotopic_with P (X,Y) f g /\ + (!x. x IN X ==> f' x = f x /\ g' x = g x) /\ + (!h k. (!x. x IN X ==> h x = k x) ==> (P h <=> P k)) + ==> homotopic_with P (X,Y) f' g'`, + REPEAT GEN_TAC THEN + DISCH_THEN(CONJUNCTS_THEN2 MP_TAC STRIP_ASSUME_TAC) THEN + REWRITE_TAC[homotopic_with] THEN + DISCH_THEN(X_CHOOSE_THEN `h:real^(1,M)finite_sum->real^N` + (fun th -> EXISTS_TAC + `\y. if sndcart(y) IN X then (h:real^(1,M)finite_sum->real^N) y + else if fstcart(y) = vec 0 then f'(sndcart y) + else g'(sndcart y)` THEN + MP_TAC th)) THEN + REWRITE_TAC[FSTCART_PASTECART; SNDCART_PASTECART; VEC_EQ; ARITH_EQ] THEN + REPEAT(MATCH_MP_TAC MONO_AND THEN CONJ_TAC) THENL + [MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] CONTINUOUS_ON_EQ) THEN + SIMP_TAC[FORALL_IN_PCROSS; SNDCART_PASTECART]; + SIMP_TAC[FORALL_IN_IMAGE; FORALL_IN_PCROSS; SUBSET] THEN + SIMP_TAC[FORALL_IN_PCROSS; SNDCART_PASTECART]; + ASM_MESON_TAC[]; + ASM_MESON_TAC[]; + MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `t:real^1` THEN + MATCH_MP_TAC MONO_IMP THEN REWRITE_TAC[] THEN + MATCH_MP_TAC EQ_IMP THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + SIMP_TAC[]]);; + +let HOMOTOPIC_WITH_EQUAL = prove + (`!P f:real^M->real^N g s t. + P f /\ P g /\ + f continuous_on s /\ IMAGE f s SUBSET t /\ + (!x. x IN s ==> g x = f x) + ==> homotopic_with P (s,t) f g`, + REPEAT STRIP_TAC THEN REWRITE_TAC[homotopic_with] THEN + EXISTS_TAC `\z:real^(1,M)finite_sum. + if fstcart z = vec 1 then g(sndcart z):real^N else f(sndcart z)` THEN + REWRITE_TAC[VEC_EQ; ARITH_EQ; SNDCART_PASTECART; FSTCART_PASTECART] THEN + CONJ_TAC THENL + [MATCH_MP_TAC CONTINUOUS_ON_EQ THEN + EXISTS_TAC `\z:real^(1,M)finite_sum. (f:real^M->real^N)(sndcart z)` THEN + ASM_SIMP_TAC[FORALL_IN_PCROSS; FSTCART_PASTECART; SNDCART_PASTECART] THEN + REWRITE_TAC[COND_ID] THEN ONCE_REWRITE_TAC[GSYM o_DEF] THEN + MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN + SIMP_TAC[LINEAR_CONTINUOUS_ON; LINEAR_SNDCART; IMAGE_SNDCART_PCROSS] THEN + ASM_REWRITE_TAC[UNIT_INTERVAL_NONEMPTY]; + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; FORALL_IN_PCROSS] THEN + REWRITE_TAC[ FSTCART_PASTECART; SNDCART_PASTECART] THEN + CONJ_TAC THEN X_GEN_TAC `t:real^1` THEN REPEAT STRIP_TAC THEN + ASM_CASES_TAC `t:real^1 = vec 1` THEN ASM_REWRITE_TAC[ETA_AX] THEN + ASM SET_TAC[]]);; + +let HOMOTOPIC_CONSTANT_MAPS = prove + (`!s:real^M->bool t:real^N->bool a b. + homotopic_with (\x. T) (s,t) (\x. a) (\x. b) <=> + s = {} \/ path_component t a b`, + REPEAT GEN_TAC THEN SIMP_TAC[HOMOTOPIC_WITH; path_component] THEN + ASM_CASES_TAC `s:real^M->bool = {}` THEN + ASM_REWRITE_TAC[NOT_IN_EMPTY; PCROSS_EMPTY; IMAGE_CLAUSES] THEN + REWRITE_TAC[EMPTY_SUBSET; CONTINUOUS_ON_EMPTY] THEN + ASM_CASES_TAC `t:real^N->bool = {}` THEN + ASM_REWRITE_TAC[PATH_IMAGE_NONEMPTY; SUBSET_EMPTY; PCROSS_EQ_EMPTY; + IMAGE_EQ_EMPTY; UNIT_INTERVAL_NONEMPTY] THEN + EQ_TAC THENL + [DISCH_THEN(X_CHOOSE_THEN `h:real^(1,M)finite_sum->real^N` + STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN `?c:real^M. c IN s` STRIP_ASSUME_TAC THENL + [ASM SET_TAC[]; ALL_TAC] THEN + EXISTS_TAC `(h:real^(1,M)finite_sum->real^N) o (\t. pastecart t c)` THEN + ASM_SIMP_TAC[pathstart; pathfinish; o_THM; PATH_IMAGE_COMPOSE] THEN + CONJ_TAC THENL + [REWRITE_TAC[path] THEN MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN + SIMP_TAC[CONTINUOUS_ON_PASTECART; CONTINUOUS_ON_ID; + CONTINUOUS_ON_CONST] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET)); + REWRITE_TAC[path_image]] THEN + ASM_SIMP_TAC[SUBSET; FORALL_IN_IMAGE; PASTECART_IN_PCROSS] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [SUBSET]) THEN + ASM_SIMP_TAC[FORALL_IN_IMAGE; FORALL_IN_PCROSS]; + REWRITE_TAC[path; pathstart; path_image; pathfinish] THEN + DISCH_THEN(X_CHOOSE_THEN `g:real^1->real^N` STRIP_ASSUME_TAC) THEN + EXISTS_TAC + `(g:real^1->real^N) o (fstcart:real^(1,M)finite_sum->real^1)` THEN + ASM_SIMP_TAC[FSTCART_PASTECART; o_THM; IMAGE_o; IMAGE_FSTCART_PCROSS] THEN + MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN + ASM_SIMP_TAC[LINEAR_FSTCART; LINEAR_CONTINUOUS_ON; + IMAGE_FSTCART_PCROSS]]);; + +(* ------------------------------------------------------------------------- *) +(* Trivial properties. *) +(* ------------------------------------------------------------------------- *) + +let HOMOTOPIC_WITH_IMP_PROPERTY = prove + (`!P X Y (f:real^M->real^N) g. homotopic_with P (X,Y) f g ==> P f /\ P g`, + REPEAT GEN_TAC THEN REWRITE_TAC[homotopic_with] THEN + DISCH_THEN(X_CHOOSE_THEN `h:real^(1,M)finite_sum->real^N` MP_TAC) THEN + REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN DISCH_THEN + (fun th -> MP_TAC(SPEC `vec 0:real^1` th) THEN + MP_TAC(SPEC `vec 1:real^1` th)) THEN + ASM_SIMP_TAC[IN_INTERVAL_1; DROP_VEC; REAL_POS; REAL_LE_REFL; ETA_AX]);; + +let HOMOTOPIC_WITH_IMP_CONTINUOUS = prove + (`!P X Y (f:real^M->real^N) g. + homotopic_with P (X,Y) f g ==> f continuous_on X /\ g continuous_on X`, + REPEAT GEN_TAC THEN REWRITE_TAC[homotopic_with] THEN + DISCH_THEN(X_CHOOSE_THEN `h:real^(1,M)finite_sum->real^N` MP_TAC) THEN + STRIP_TAC THEN + SUBGOAL_THEN + `((h:real^(1,M)finite_sum->real^N) o (\x. pastecart (vec 0) x)) + continuous_on X /\ + ((h:real^(1,M)finite_sum->real^N) o (\x. pastecart (vec 1) x)) + continuous_on X` + MP_TAC THENL [ALL_TAC; ASM_REWRITE_TAC[o_DEF; ETA_AX]] THEN + CONJ_TAC 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 + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; PASTECART_IN_PCROSS] THEN + ONCE_REWRITE_TAC[CONJ_SYM] THEN + REWRITE_TAC[GSYM CONJ_ASSOC; FSTCART_PASTECART; SNDCART_PASTECART] THEN + SIMP_TAC[RIGHT_EXISTS_AND_THM; UNWIND_THM1; IN_INTERVAL_1] THEN + REWRITE_TAC[DROP_VEC; REAL_POS; REAL_LE_REFL]);; + +let HOMOTOPIC_WITH_IMP_SUBSET = prove + (`!P X Y (f:real^M->real^N) g. + homotopic_with P (X,Y) f g ==> IMAGE f X SUBSET Y /\ IMAGE g X SUBSET Y`, + REPEAT GEN_TAC THEN REWRITE_TAC[homotopic_with] THEN + DISCH_THEN(X_CHOOSE_THEN `h:real^(1,M)finite_sum->real^N` MP_TAC) THEN + STRIP_TAC THEN FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [SUBSET]) THEN + REWRITE_TAC[FORALL_IN_IMAGE; FORALL_IN_PCROSS; SUBSET] THEN DISCH_THEN + (fun th -> MP_TAC(SPEC `vec 0:real^1` th) THEN + MP_TAC(SPEC `vec 1:real^1` th)) THEN + ASM_SIMP_TAC[IN_INTERVAL_1; DROP_VEC; REAL_POS; REAL_LE_REFL]);; + +let HOMOTOPIC_WITH_MONO = prove + (`!P Q X Y f g:real^M->real^N. + homotopic_with P (X,Y) f g /\ + (!h. h continuous_on X /\ IMAGE h X SUBSET Y /\ P h ==> Q h) + ==> homotopic_with Q (X,Y) f g`, + REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN + REWRITE_TAC[homotopic_with; PCROSS] THEN + MATCH_MP_TAC MONO_EXISTS THEN REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_SIMP_TAC[] THEN CONJ_TAC THENL + [GEN_REWRITE_TAC LAND_CONV [GSYM o_DEF] THEN + MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN + SIMP_TAC[CONTINUOUS_ON_PASTECART; CONTINUOUS_ON_ID; + CONTINUOUS_ON_CONST] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET)) THEN + ASM SET_TAC[]; + ASM SET_TAC[]]);; + +let HOMOTOPIC_WITH_SUBSET_LEFT = prove + (`!P X Y Z f g. + homotopic_with P (X,Y) f g /\ Z SUBSET X + ==> homotopic_with P (Z,Y) f g`, + REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN + REWRITE_TAC[homotopic_with; PCROSS] THEN + MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN CONJ_TAC THENL + [FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET)) THEN + ASM SET_TAC[]; + ASM SET_TAC[]]);; + +let HOMOTOPIC_WITH_SUBSET_RIGHT = prove + (`!P X Y Z (f:real^M->real^N) g h. + homotopic_with P (X,Y) f g /\ Y SUBSET Z + ==> homotopic_with P (X,Z) f g`, + REPEAT GEN_TAC THEN + DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN + REWRITE_TAC[homotopic_with] THEN + MATCH_MP_TAC MONO_EXISTS THEN SIMP_TAC[] THEN + ASM_MESON_TAC[SUBSET_TRANS]);; + +let HOMOTOPIC_WITH_COMPOSE_CONTINUOUS_RIGHT = prove + (`!p f:real^N->real^P g h:real^M->real^N W X Y. + homotopic_with (\f. p(f o h)) (X,Y) f g /\ + h continuous_on W /\ IMAGE h W SUBSET X + ==> homotopic_with p (W,Y) (f o h) (g o h)`, + REPEAT GEN_TAC THEN + DISCH_THEN(CONJUNCTS_THEN2 MP_TAC STRIP_ASSUME_TAC) THEN + REWRITE_TAC[homotopic_with; o_DEF; PCROSS] THEN + DISCH_THEN(X_CHOOSE_THEN `k:real^(1,N)finite_sum->real^P` + STRIP_ASSUME_TAC) THEN + EXISTS_TAC `\y:real^(1,M)finite_sum. + (k:real^(1,N)finite_sum->real^P) + (pastecart (fstcart y) (h(sndcart y)))` THEN + ASM_REWRITE_TAC[o_THM; FSTCART_PASTECART; SNDCART_PASTECART] THEN + CONJ_TAC THENL + [GEN_REWRITE_TAC LAND_CONV [GSYM o_DEF] THEN + MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN CONJ_TAC THENL + [MATCH_MP_TAC CONTINUOUS_ON_PASTECART THEN + SIMP_TAC[LINEAR_CONTINUOUS_ON; LINEAR_FSTCART] THEN + GEN_REWRITE_TAC LAND_CONV [GSYM o_DEF] THEN + MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN + SIMP_TAC[LINEAR_CONTINUOUS_ON; LINEAR_SNDCART]; + ALL_TAC] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE [IMP_CONJ] + CONTINUOUS_ON_SUBSET)); + ALL_TAC] THEN + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; FORALL_IN_GSPEC] THEN + SIMP_TAC[IN_ELIM_PASTECART_THM; FSTCART_PASTECART; SNDCART_PASTECART] THEN + ASM SET_TAC[]);; + +let HOMOTOPIC_COMPOSE_CONTINUOUS_RIGHT = prove + (`!f:real^N->real^P g h:real^M->real^N W X Y. + homotopic_with (\f. T) (X,Y) f g /\ + h continuous_on W /\ IMAGE h W SUBSET X + ==> homotopic_with (\f. T) (W,Y) (f o h) (g o h)`, + REPEAT STRIP_TAC THEN + MATCH_MP_TAC HOMOTOPIC_WITH_COMPOSE_CONTINUOUS_RIGHT THEN + EXISTS_TAC `X:real^N->bool` THEN ASM_REWRITE_TAC[]);; + +let HOMOTOPIC_WITH_COMPOSE_CONTINUOUS_LEFT = prove + (`!p f:real^M->real^N g h:real^N->real^P X Y Z. + homotopic_with (\f. p(h o f)) (X,Y) f g /\ + h continuous_on Y /\ IMAGE h Y SUBSET Z + ==> homotopic_with p (X,Z) (h o f) (h o g)`, + REPEAT GEN_TAC THEN + DISCH_THEN(CONJUNCTS_THEN2 MP_TAC STRIP_ASSUME_TAC) THEN + REWRITE_TAC[homotopic_with; o_DEF] THEN + DISCH_THEN(X_CHOOSE_THEN `k:real^(1,M)finite_sum->real^N` + STRIP_ASSUME_TAC) THEN + EXISTS_TAC `(h:real^N->real^P) o (k:real^(1,M)finite_sum->real^N)` THEN + ASM_REWRITE_TAC[o_THM] THEN CONJ_TAC THENL + [MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN ASM_REWRITE_TAC[] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE [IMP_CONJ] + CONTINUOUS_ON_SUBSET)); + ALL_TAC] THEN + REWRITE_TAC[IMAGE_o] THEN ASM SET_TAC[]);; + +let HOMOTOPIC_COMPOSE_CONTINUOUS_LEFT = prove + (`!f:real^M->real^N g h:real^N->real^P X Y Z. + homotopic_with (\f. T) (X,Y) f g /\ + h continuous_on Y /\ IMAGE h Y SUBSET Z + ==> homotopic_with (\f. T) (X,Z) (h o f) (h o g)`, + REPEAT STRIP_TAC THEN + MATCH_MP_TAC HOMOTOPIC_WITH_COMPOSE_CONTINUOUS_LEFT THEN + EXISTS_TAC `Y:real^N->bool` THEN ASM_REWRITE_TAC[]);; + +let HOMOTOPIC_WITH_PCROSS = prove + (`!f:real^M->real^N f':real^P->real^Q g g' p p' q s s' t t'. + homotopic_with p (s,t) f g /\ + homotopic_with p' (s',t') f' g' /\ + (!f g. p f /\ p' g ==> q(\x. pastecart (f(fstcart x)) (g(sndcart x)))) + ==> homotopic_with q (s PCROSS s',t PCROSS t') + (\z. pastecart (f(fstcart z)) (f'(sndcart z))) + (\z. pastecart (g(fstcart z)) (g'(sndcart z)))`, + REPEAT GEN_TAC THEN REWRITE_TAC[homotopic_with] THEN + REWRITE_TAC[CONJ_ASSOC] THEN + DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN + REWRITE_TAC[GSYM CONJ_ASSOC] THEN + DISCH_THEN(CONJUNCTS_THEN2 + (X_CHOOSE_THEN `k:real^(1,M)finite_sum->real^N` STRIP_ASSUME_TAC) + (X_CHOOSE_THEN `k':real^(1,P)finite_sum->real^Q` STRIP_ASSUME_TAC)) THEN + EXISTS_TAC + `\z:real^(1,(M,P)finite_sum)finite_sum. + pastecart (k(pastecart (fstcart z) (fstcart(sndcart z))):real^N) + (k'(pastecart (fstcart z) (sndcart(sndcart z))):real^Q)` THEN + ASM_REWRITE_TAC[FSTCART_PASTECART; SNDCART_PASTECART] THEN + RULE_ASSUM_TAC(REWRITE_RULE[SUBSET; FORALL_IN_IMAGE; FORALL_IN_PCROSS]) THEN + ASM_SIMP_TAC[SUBSET; FORALL_IN_IMAGE; FORALL_IN_PCROSS; + FSTCART_PASTECART; SNDCART_PASTECART; PASTECART_IN_PCROSS; + IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN + MATCH_MP_TAC CONTINUOUS_ON_PASTECART THEN CONJ_TAC THEN + GEN_REWRITE_TAC LAND_CONV [GSYM o_DEF] THEN + MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN + (CONJ_TAC THENL + [MATCH_MP_TAC CONTINUOUS_ON_PASTECART THEN + SIMP_TAC[LINEAR_CONTINUOUS_ON; LINEAR_FSTCART] THEN + GEN_REWRITE_TAC LAND_CONV [GSYM o_DEF] THEN + MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN + SIMP_TAC[LINEAR_CONTINUOUS_ON; LINEAR_FSTCART; LINEAR_SNDCART]; + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET)) THEN + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; FORALL_IN_PCROSS; + IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN + ASM_SIMP_TAC[FSTCART_PASTECART; SNDCART_PASTECART; + PASTECART_IN_PCROSS]]));; + +(* ------------------------------------------------------------------------- *) +(* Homotopy with P is an equivalence relation (on continuous functions *) +(* mapping X into Y that satisfy P, though this only affects reflexivity). *) +(* ------------------------------------------------------------------------- *) + +let HOMOTOPIC_WITH_REFL = prove + (`!P X Y (f:real^M->real^N). + homotopic_with P (X,Y) f f <=> + f continuous_on X /\ IMAGE f X SUBSET Y /\ P f`, + REPEAT GEN_TAC THEN EQ_TAC THENL + [MESON_TAC[HOMOTOPIC_WITH_IMP_PROPERTY; HOMOTOPIC_WITH_IMP_CONTINUOUS; + HOMOTOPIC_WITH_IMP_SUBSET]; + STRIP_TAC THEN REWRITE_TAC[homotopic_with; PCROSS]] THEN + EXISTS_TAC `\y:real^(1,M)finite_sum. (f:real^M->real^N) (sndcart y)` THEN + RULE_ASSUM_TAC(REWRITE_RULE[SUBSET; FORALL_IN_IMAGE]) THEN + ASM_SIMP_TAC[SNDCART_PASTECART; ETA_AX; SUBSET; FORALL_IN_IMAGE; + FORALL_IN_GSPEC] THEN + GEN_REWRITE_TAC LAND_CONV [GSYM o_DEF] THEN + MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN + SIMP_TAC[LINEAR_CONTINUOUS_ON; LINEAR_SNDCART] 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; FORALL_IN_GSPEC; SNDCART_PASTECART]);; + +let HOMOTOPIC_WITH_SYM = prove + (`!P X Y (f:real^M->real^N) g. + homotopic_with P (X,Y) f g <=> homotopic_with P (X,Y) g f`, + REPLICATE_TAC 3 GEN_TAC THEN MATCH_MP_TAC(MESON[] + `(!x y. P x y ==> P y x) ==> (!x y. P x y <=> P y x)`) THEN + REPEAT GEN_TAC THEN REWRITE_TAC[homotopic_with; PCROSS] THEN + DISCH_THEN(X_CHOOSE_THEN `h:real^(1,M)finite_sum->real^N` + STRIP_ASSUME_TAC) THEN + EXISTS_TAC `\y:real^(1,M)finite_sum. + (h:real^(1,M)finite_sum->real^N) + (pastecart (vec 1 - fstcart y) (sndcart y))` THEN + REWRITE_TAC[FSTCART_PASTECART; SNDCART_PASTECART] THEN + ASM_REWRITE_TAC[VECTOR_SUB_REFL; VECTOR_SUB_RZERO] THEN REPEAT CONJ_TAC THENL + [GEN_REWRITE_TAC LAND_CONV [GSYM o_DEF] THEN + MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN + SIMP_TAC[CONTINUOUS_ON_PASTECART; CONTINUOUS_ON_SUB; CONTINUOUS_ON_CONST; + LINEAR_CONTINUOUS_ON; LINEAR_FSTCART; LINEAR_SNDCART] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET)); + GEN_REWRITE_TAC (LAND_CONV o LAND_CONV) [GSYM o_DEF] THEN + REWRITE_TAC[IMAGE_o] THEN FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE + `IMAGE h s SUBSET t ==> IMAGE g s SUBSET s + ==> IMAGE h (IMAGE g s) SUBSET t`)) THEN + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; FORALL_IN_GSPEC]; + REWRITE_TAC[IN_INTERVAL_1; DROP_VEC] THEN REPEAT STRIP_TAC THEN + FIRST_X_ASSUM MATCH_MP_TAC] THEN + SIMP_TAC[SUBSET; FORALL_IN_IMAGE; FORALL_IN_GSPEC] THEN + REWRITE_TAC[FSTCART_PASTECART; SNDCART_PASTECART; IN_ELIM_THM] THEN + ONCE_REWRITE_TAC[CONJ_SYM] THEN REWRITE_TAC[PASTECART_EQ] THEN + REWRITE_TAC[GSYM CONJ_ASSOC; FSTCART_PASTECART; SNDCART_PASTECART] THEN + SIMP_TAC[RIGHT_EXISTS_AND_THM; UNWIND_THM1; IN_INTERVAL_1] THEN + REWRITE_TAC[DROP_VEC; REAL_POS; REAL_LE_REFL; DROP_SUB] THEN + ASM_REAL_ARITH_TAC);; + +let HOMOTOPIC_WITH_TRANS = prove + (`!P X Y (f:real^M->real^N) g h. + homotopic_with P (X,Y) f g /\ homotopic_with P (X,Y) g h + ==> homotopic_with P (X,Y) f h`, + REPEAT GEN_TAC THEN REWRITE_TAC[homotopic_with; PCROSS] THEN + DISCH_THEN(CONJUNCTS_THEN2 + (X_CHOOSE_THEN `k1:real^(1,M)finite_sum->real^N` STRIP_ASSUME_TAC) + (X_CHOOSE_THEN `k2:real^(1,M)finite_sum->real^N` STRIP_ASSUME_TAC)) THEN + EXISTS_TAC `\y:real^(1,M)finite_sum. + if drop(fstcart y) <= &1 / &2 + then (k1:real^(1,M)finite_sum->real^N) + (pastecart (&2 % fstcart y) (sndcart y)) + else (k2:real^(1,M)finite_sum->real^N) + (pastecart (&2 % fstcart y - vec 1) (sndcart y))` THEN + REWRITE_TAC[FSTCART_PASTECART; DROP_VEC] THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN ASM_REWRITE_TAC[VECTOR_MUL_RZERO] THEN + ASM_REWRITE_TAC[VECTOR_ARITH `&2 % x - x:real^N = x`; SNDCART_PASTECART] THEN + REPEAT CONJ_TAC THENL + [SUBGOAL_THEN + `interval[vec 0:real^1,vec 1] = + interval[vec 0,lift(&1 / &2)] UNION interval[lift(&1 / &2),vec 1]` + SUBST1_TAC THENL + [REWRITE_TAC[EXTENSION; IN_UNION; IN_INTERVAL_1; LIFT_DROP; DROP_VEC] THEN + REAL_ARITH_TAC; + ALL_TAC] THEN + REWRITE_TAC[SET_RULE `{f x y | x IN s UNION t /\ y IN u} = + {f x y | x IN s /\ y IN u} UNION + {f x y | x IN t /\ y IN u}`] THEN + MATCH_MP_TAC CONTINUOUS_ON_CASES_LOCAL THEN + ONCE_REWRITE_TAC[TAUT + `a /\ b /\ c /\ d /\ e <=> (a /\ b) /\ (c /\ d) /\ e`] THEN + CONJ_TAC THENL + [REWRITE_TAC[CLOSED_IN_CLOSED] THEN CONJ_TAC THENL + [EXISTS_TAC `{ pastecart (t:real^1) (x:real^M) | + t IN interval[vec 0,lift(&1 / &2)] /\ x IN UNIV }`; + EXISTS_TAC `{ pastecart (t:real^1) (x:real^M) | + t IN interval[lift(&1 / &2),vec 1] /\ x IN UNIV}`] THEN + SIMP_TAC[REWRITE_RULE[PCROSS] CLOSED_PCROSS; + CLOSED_INTERVAL; CLOSED_UNIV] THEN + MATCH_MP_TAC SUBSET_ANTISYM THEN + REWRITE_TAC[SUBSET; FORALL_IN_GSPEC; IN_INTER; TAUT + `(x IN (s UNION t) /\ x IN u ==> x IN v) <=> + (x IN u ==> x IN (s UNION t) ==> x IN v)`] THEN + REWRITE_TAC[PASTECART_EQ; IN_ELIM_THM; IN_UNION] THEN + REWRITE_TAC[FSTCART_PASTECART; SNDCART_PASTECART; IN_UNIV] THEN + MESON_TAC[]; + ALL_TAC] THEN + CONJ_TAC THENL + [CONJ_TAC THEN GEN_REWRITE_TAC LAND_CONV [GSYM o_DEF] THEN + MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN + (CONV_TAC o GEN_SIMPLIFY_CONV TOP_DEPTH_SQCONV (basic_ss []) 5) + [CONTINUOUS_ON_PASTECART; CONTINUOUS_ON_CMUL; CONTINUOUS_ON_SUB; + CONTINUOUS_ON_CONST; LINEAR_CONTINUOUS_ON; LINEAR_FSTCART; + LINEAR_SNDCART] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET)) THEN + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; FORALL_IN_GSPEC] THEN + REWRITE_TAC[IN_ELIM_THM; PASTECART_EQ; FSTCART_PASTECART; + SNDCART_PASTECART] THEN + REWRITE_TAC[MESON[] `(?t x. P t x /\ a = t /\ b = x) <=> P a b`] THEN + SIMP_TAC[IN_INTERVAL_1; DROP_SUB; DROP_VEC; DROP_CMUL; LIFT_DROP] THEN + REAL_ARITH_TAC; + REWRITE_TAC[TAUT `p \/ q ==> r <=> (p ==> r) /\ (q ==> r)`] THEN + REWRITE_TAC[FORALL_AND_THM; IMP_CONJ; FORALL_IN_GSPEC] THEN + REWRITE_TAC[FSTCART_PASTECART; SNDCART_PASTECART; IN_INTERVAL_1] THEN + SIMP_TAC[LIFT_DROP; DROP_VEC; REAL_ARITH + `&1 / &2 <= t ==> (t <= &1 / &2 <=> t = &1 / &2)`] THEN + SIMP_TAC[GSYM LIFT_EQ; LIFT_DROP; GSYM LIFT_CMUL; GSYM LIFT_NUM] THEN + REWRITE_TAC[GSYM LIFT_SUB] THEN CONV_TAC REAL_RAT_REDUCE_CONV THEN + ASM_REWRITE_TAC[LIFT_NUM]]; + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; FORALL_IN_GSPEC] THEN + REWRITE_TAC[FSTCART_PASTECART; SNDCART_PASTECART] THEN + REWRITE_TAC[IN_INTERVAL_1; DROP_VEC; LIFT_DROP] THEN + REPEAT STRIP_TAC THEN COND_CASES_TAC THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE + `IMAGE k s SUBSET t ==> x IN s ==> k x IN t`)) THEN + ASM_REWRITE_TAC[IN_ELIM_PASTECART_THM; IN_INTERVAL_1; DROP_VEC; + DROP_CMUL; DROP_SUB] THEN + ASM_REAL_ARITH_TAC; + X_GEN_TAC `t:real^1` THEN REWRITE_TAC[IN_INTERVAL_1; DROP_VEC] THEN + STRIP_TAC THEN ASM_CASES_TAC `drop t <= &1 / &2` THEN ASM_SIMP_TAC[] THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN + REWRITE_TAC[IN_INTERVAL_1; DROP_VEC; DROP_CMUL; DROP_SUB] THEN + ASM_REAL_ARITH_TAC]);; + +(* ------------------------------------------------------------------------- *) +(* Two characterizations of homotopic triviality, one of which *) +(* implicitly incorporates path-connectedness. *) +(* ------------------------------------------------------------------------- *) + +let HOMOTOPIC_TRIVIALITY = prove + (`!s:real^M->bool t:real^N->bool. + (!f g. f continuous_on s /\ IMAGE f s SUBSET t /\ + g continuous_on s /\ IMAGE g s SUBSET t + ==> homotopic_with (\x. T) (s,t) f g) <=> + (s = {} \/ path_connected t) /\ + (!f. f continuous_on s /\ IMAGE f s SUBSET t + ==> ?c. homotopic_with (\x. T) (s,t) f (\x. c))`, + REPEAT GEN_TAC THEN ASM_CASES_TAC `s:real^M->bool = {}` THENL + [ASM_SIMP_TAC[CONTINUOUS_ON_EMPTY; HOMOTOPIC_WITH; NOT_IN_EMPTY; + PCROSS_EMPTY; IMAGE_CLAUSES; EMPTY_SUBSET]; + ASM_CASES_TAC `t:real^N->bool = {}` THEN + ASM_REWRITE_TAC[SUBSET_EMPTY; IMAGE_EQ_EMPTY; PATH_CONNECTED_EMPTY]] THEN + EQ_TAC THEN REPEAT STRIP_TAC THENL + [REWRITE_TAC[PATH_CONNECTED_IFF_PATH_COMPONENT] THEN + REPEAT STRIP_TAC THEN + W(MP_TAC o PART_MATCH (rand o rand) HOMOTOPIC_CONSTANT_MAPS o snd) THEN + ASM_REWRITE_TAC[] THEN DISCH_THEN(SUBST1_TAC o SYM) THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; CONTINUOUS_ON_CONST] THEN + ASM SET_TAC[]; + SUBGOAL_THEN `?c:real^N. c IN t` MP_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + MATCH_MP_TAC MONO_EXISTS THEN REPEAT STRIP_TAC THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; CONTINUOUS_ON_CONST]; + FIRST_X_ASSUM(fun th -> + MP_TAC(ISPEC `g:real^M->real^N` th) THEN + MP_TAC(ISPEC `f:real^M->real^N` th)) THEN + ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `c:real^N` THEN DISCH_TAC THEN + X_GEN_TAC `d:real^N` THEN DISCH_TAC THEN + TRANS_TAC HOMOTOPIC_WITH_TRANS `(\x. c):real^M->real^N` THEN + ASM_REWRITE_TAC[] THEN ONCE_REWRITE_TAC[HOMOTOPIC_WITH_SYM] THEN + TRANS_TAC HOMOTOPIC_WITH_TRANS `(\x. d):real^M->real^N` THEN + ASM_REWRITE_TAC[HOMOTOPIC_CONSTANT_MAPS] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o + REWRITE_RULE[PATH_CONNECTED_IFF_PATH_COMPONENT]) THEN + REPEAT(FIRST_X_ASSUM(MP_TAC o MATCH_MP HOMOTOPIC_WITH_IMP_SUBSET)) THEN + ASM SET_TAC[]]);; + +(* ------------------------------------------------------------------------- *) +(* Homotopy of paths, maintaining the same endpoints. *) +(* ------------------------------------------------------------------------- *) + +let homotopic_paths = new_definition + `homotopic_paths s p q = + homotopic_with + (\r. pathstart r = pathstart p /\ pathfinish r = pathfinish p) + (interval[vec 0:real^1,vec 1],s) + p q`;; + +let HOMOTOPIC_PATHS = prove + (`!s p q:real^1->real^N. + homotopic_paths s p q <=> + ?h. h continuous_on + interval[vec 0,vec 1] PCROSS interval[vec 0,vec 1] /\ + IMAGE h (interval[vec 0,vec 1] PCROSS interval[vec 0,vec 1]) + SUBSET s /\ + (!x. x IN interval[vec 0,vec 1] ==> h(pastecart (vec 0) x) = p x) /\ + (!x. x IN interval[vec 0,vec 1] ==> h(pastecart (vec 1) x) = q x) /\ + (!t. t IN interval[vec 0:real^1,vec 1] + ==> pathstart(h o pastecart t) = pathstart p /\ + pathfinish(h o pastecart t) = pathfinish p)`, + REPEAT GEN_TAC THEN + REWRITE_TAC[homotopic_paths] THEN + W(MP_TAC o PART_MATCH (lhand o rand) HOMOTOPIC_WITH o lhand o snd) THEN + ANTS_TAC THENL + [SIMP_TAC[pathstart; pathfinish; ENDS_IN_UNIT_INTERVAL]; + DISCH_THEN SUBST1_TAC THEN REWRITE_TAC[o_DEF]]);; + +let HOMOTOPIC_PATHS_IMP_PATHSTART = prove + (`!s p q. homotopic_paths s p q ==> pathstart p = pathstart q`, + REPEAT GEN_TAC THEN REWRITE_TAC[homotopic_paths] THEN + DISCH_THEN(MP_TAC o MATCH_MP HOMOTOPIC_WITH_IMP_PROPERTY) THEN + SIMP_TAC[]);; + +let HOMOTOPIC_PATHS_IMP_PATHFINISH = prove + (`!s p q. homotopic_paths s p q ==> pathfinish p = pathfinish q`, + REPEAT GEN_TAC THEN REWRITE_TAC[homotopic_paths] THEN + DISCH_THEN(MP_TAC o MATCH_MP HOMOTOPIC_WITH_IMP_PROPERTY) THEN + SIMP_TAC[]);; + +let HOMOTOPIC_PATHS_IMP_PATH = prove + (`!s p q. homotopic_paths s p q ==> path p /\ path q`, + REPEAT GEN_TAC THEN REWRITE_TAC[homotopic_paths] THEN + DISCH_THEN(MP_TAC o MATCH_MP HOMOTOPIC_WITH_IMP_CONTINUOUS) THEN + SIMP_TAC[path]);; + +let HOMOTOPIC_PATHS_IMP_SUBSET = prove + (`!s p q. + homotopic_paths s p q ==> path_image p SUBSET s /\ path_image q SUBSET s`, + REPEAT GEN_TAC THEN REWRITE_TAC[homotopic_paths] THEN + DISCH_THEN(MP_TAC o MATCH_MP HOMOTOPIC_WITH_IMP_SUBSET) THEN + SIMP_TAC[path_image]);; + +let HOMOTOPIC_PATHS_REFL = prove + (`!s p. homotopic_paths s p p <=> + path p /\ path_image p SUBSET s`, + REWRITE_TAC[homotopic_paths; HOMOTOPIC_WITH_REFL; path; path_image]);; + +let HOMOTOPIC_PATHS_SYM = prove + (`!s p q. homotopic_paths s p q <=> homotopic_paths s q p`, + REPEAT GEN_TAC THEN EQ_TAC THEN DISCH_TAC THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP HOMOTOPIC_PATHS_IMP_PATHSTART) THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP HOMOTOPIC_PATHS_IMP_PATHFINISH) THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [homotopic_paths]) THEN + ONCE_REWRITE_TAC[HOMOTOPIC_WITH_SYM] THEN ASM_SIMP_TAC[homotopic_paths]);; + +let HOMOTOPIC_PATHS_TRANS = prove + (`!s p q r. + homotopic_paths s p q /\ homotopic_paths s q r + ==> homotopic_paths s p r`, + REPEAT GEN_TAC THEN DISCH_TAC THEN + FIRST_ASSUM(CONJUNCTS_THEN + (fun th -> ASSUME_TAC(MATCH_MP HOMOTOPIC_PATHS_IMP_PATHSTART th) THEN + ASSUME_TAC(MATCH_MP HOMOTOPIC_PATHS_IMP_PATHFINISH th))) THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE BINOP_CONV [homotopic_paths]) THEN + ASM_REWRITE_TAC[HOMOTOPIC_WITH_TRANS; homotopic_paths]);; + +let HOMOTOPIC_PATHS_EQ = prove + (`!p:real^1->real^N q s. + path p /\ path_image p SUBSET s /\ + (!t. t IN interval[vec 0,vec 1] ==> p(t) = q(t)) + ==> homotopic_paths s p q`, + REPEAT STRIP_TAC THEN REWRITE_TAC[homotopic_paths] THEN + MATCH_MP_TAC HOMOTOPIC_WITH_EQ THEN + REPEAT(EXISTS_TAC `p:real^1->real^N`) THEN + ASM_SIMP_TAC[HOMOTOPIC_WITH_REFL] THEN + ASM_REWRITE_TAC[GSYM path; GSYM path_image] THEN + REWRITE_TAC[pathstart; pathfinish] THEN + MESON_TAC[ENDS_IN_UNIT_INTERVAL]);; + +let HOMOTOPIC_PATHS_REPARAMETRIZE = prove + (`!p:real^1->real^N q f:real^1->real^1. + path p /\ path_image p SUBSET s /\ + (?f. f continuous_on interval[vec 0,vec 1] /\ + IMAGE f (interval[vec 0,vec 1]) SUBSET interval[vec 0,vec 1] /\ + f(vec 0) = vec 0 /\ f(vec 1) = vec 1 /\ + !t. t IN interval[vec 0,vec 1] ==> q(t) = p(f t)) + ==> homotopic_paths s p q`, + REWRITE_TAC[path; path_image] THEN REPEAT STRIP_TAC THEN + ONCE_REWRITE_TAC[HOMOTOPIC_PATHS_SYM] THEN + MATCH_MP_TAC HOMOTOPIC_PATHS_TRANS THEN + EXISTS_TAC `(p:real^1->real^N) o (f:real^1->real^1)` THEN CONJ_TAC THENL + [MATCH_MP_TAC HOMOTOPIC_PATHS_EQ THEN + ASM_SIMP_TAC[o_THM; pathstart; pathfinish; o_THM; + IN_INTERVAL_1; DROP_VEC; REAL_POS; REAL_LE_REFL] THEN + REWRITE_TAC[path; path_image] THEN CONJ_TAC THENL + [MATCH_MP_TAC CONTINUOUS_ON_EQ THEN + EXISTS_TAC `(p:real^1->real^N) o (f:real^1->real^1)` THEN + ASM_SIMP_TAC[o_THM] THEN MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN + ASM_MESON_TAC[CONTINUOUS_ON_SUBSET]; + ASM SET_TAC[]]; + REWRITE_TAC[homotopic_paths; homotopic_with; PCROSS] THEN + EXISTS_TAC `(p:real^1->real^N) o + (\y. (&1 - drop(fstcart y)) % f(sndcart y) + + drop(fstcart y) % sndcart y)` THEN + ASM_REWRITE_TAC[o_THM; FSTCART_PASTECART; SNDCART_PASTECART; DROP_VEC; + pathstart; pathfinish] THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN + REWRITE_TAC[VECTOR_MUL_LZERO; VECTOR_MUL_RZERO; VECTOR_ADD_LID; + VECTOR_MUL_LID; VECTOR_ADD_RID] THEN + REWRITE_TAC[VECTOR_ARITH `(&1 - u) % x + u % x:real^N = x`] THEN + CONJ_TAC THENL + [MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN CONJ_TAC THENL + [MATCH_MP_TAC CONTINUOUS_ON_ADD THEN CONJ_TAC THEN + MATCH_MP_TAC CONTINUOUS_ON_MUL THEN + REWRITE_TAC[o_DEF; LIFT_DROP; ETA_AX; LIFT_SUB] THEN + SIMP_TAC[LINEAR_CONTINUOUS_ON; CONTINUOUS_ON_CONST; LINEAR_FSTCART; + LINEAR_SNDCART; CONTINUOUS_ON_SUB] THEN + MATCH_MP_TAC(REWRITE_RULE[o_DEF] CONTINUOUS_ON_COMPOSE) THEN + SIMP_TAC[LINEAR_CONTINUOUS_ON; LINEAR_SNDCART] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET)) THEN + SIMP_TAC[SUBSET; FORALL_IN_IMAGE; FORALL_IN_GSPEC; SNDCART_PASTECART]; + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET))]; + ONCE_REWRITE_TAC[IMAGE_o] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE + `IMAGE p i SUBSET s + ==> IMAGE f x SUBSET i + ==> IMAGE p (IMAGE f x) SUBSET s`))] THEN + SIMP_TAC[SUBSET; FORALL_IN_IMAGE; FORALL_IN_GSPEC; SNDCART_PASTECART; + FSTCART_PASTECART] THEN + REPEAT STRIP_TAC THEN + MATCH_MP_TAC(REWRITE_RULE[CONVEX_ALT] (CONJUNCT1(SPEC_ALL + CONVEX_INTERVAL))) THEN + ASM_MESON_TAC[IN_INTERVAL_1; DROP_VEC; SUBSET; IN_IMAGE]]);; + +let HOMOTOPIC_PATHS_SUBSET = prove + (`!s p q. + homotopic_paths s p q /\ s SUBSET t + ==> homotopic_paths t p q`, + REWRITE_TAC[homotopic_paths; HOMOTOPIC_WITH_SUBSET_RIGHT]);; + +(* ------------------------------------------------------------------------- *) +(* A slightly ad-hoc but useful lemma in constructing homotopies. *) +(* ------------------------------------------------------------------------- *) + +let HOMOTOPIC_JOIN_LEMMA = prove + (`!p q:real^1->real^1->real^N. + (\y. p (fstcart y) (sndcart y)) continuous_on + (interval[vec 0,vec 1] PCROSS interval[vec 0,vec 1]) /\ + (\y. q (fstcart y) (sndcart y)) continuous_on + (interval[vec 0,vec 1] PCROSS interval[vec 0,vec 1]) /\ + (!t. t IN interval[vec 0,vec 1] ==> pathfinish(p t) = pathstart(q t)) + ==> (\y. (p(fstcart y) ++ q(fstcart y)) (sndcart y)) continuous_on + (interval[vec 0,vec 1] PCROSS interval[vec 0,vec 1])`, + REWRITE_TAC[joinpaths; PCROSS] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC CONTINUOUS_ON_CASES_LE THEN REPEAT CONJ_TAC THENL + [SUBGOAL_THEN + `(\y. p (fstcart y) (&2 % sndcart y)):real^(1,1)finite_sum->real^N = + (\y. p (fstcart y) (sndcart y)) o + (\y. pastecart (fstcart y) (&2 % sndcart y))` + SUBST1_TAC THENL + [REWRITE_TAC[o_DEF; FSTCART_PASTECART; SNDCART_PASTECART]; ALL_TAC]; + SUBGOAL_THEN + `(\y. q (fstcart y) (&2 % sndcart y - vec 1)):real^(1,1)finite_sum->real^N = + (\y. q (fstcart y) (sndcart y)) o + (\y. pastecart (fstcart y) (&2 % sndcart y - vec 1))` + SUBST1_TAC THENL + [REWRITE_TAC[o_DEF; FSTCART_PASTECART; SNDCART_PASTECART]; ALL_TAC]; + SIMP_TAC[o_DEF; LIFT_DROP; LINEAR_CONTINUOUS_ON; LINEAR_SNDCART; ETA_AX]; + SIMP_TAC[IMP_CONJ; FORALL_IN_GSPEC; FSTCART_PASTECART; SNDCART_PASTECART; + GSYM LIFT_EQ; LIFT_DROP; GSYM LIFT_CMUL] THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN + RULE_ASSUM_TAC(REWRITE_RULE[pathstart; pathfinish]) THEN + ASM_SIMP_TAC[LIFT_NUM; VECTOR_SUB_REFL]] THEN + MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN + (CONJ_TAC THENL [MATCH_MP_TAC CONTINUOUS_ON_PASTECART; ALL_TAC]) THEN + SIMP_TAC[CONTINUOUS_ON_CMUL; LINEAR_CONTINUOUS_ON; CONTINUOUS_ON_SUB; + CONTINUOUS_ON_CONST; LINEAR_FSTCART; LINEAR_SNDCART] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET)) THEN + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; FORALL_IN_GSPEC; IMP_CONJ] THEN + SIMP_TAC[IN_ELIM_PASTECART_THM; FSTCART_PASTECART; SNDCART_PASTECART] THEN + REWRITE_TAC[IN_INTERVAL_1; DROP_CMUL; DROP_SUB; DROP_VEC] THEN + REAL_ARITH_TAC);; + +(* ------------------------------------------------------------------------- *) +(* Congruence properties of homotopy w.r.t. path-combining operations. *) +(* ------------------------------------------------------------------------- *) + +let HOMOTOPIC_PATHS_REVERSEPATH = prove + (`!s p q:real^1->real^N. + homotopic_paths s (reversepath p) (reversepath q) <=> + homotopic_paths s p q`, + GEN_TAC THEN MATCH_MP_TAC(MESON[] + `(!p. f(f p) = p) /\ + (!a b. homotopic_paths s a b ==> homotopic_paths s (f a) (f b)) + ==> !a b. homotopic_paths s (f a) (f b) <=> + homotopic_paths s a b`) THEN + REWRITE_TAC[REVERSEPATH_REVERSEPATH] THEN REPEAT GEN_TAC THEN + REWRITE_TAC[homotopic_paths; homotopic_with; PCROSS; o_DEF] THEN DISCH_THEN + (X_CHOOSE_THEN `h:real^(1,1)finite_sum->real^N` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `\y:real^(1,1)finite_sum. + (h:real^(1,1)finite_sum->real^N) + (pastecart(fstcart y) (vec 1 - sndcart y))` THEN + ASM_REWRITE_TAC[o_DEF; FSTCART_PASTECART; SNDCART_PASTECART] THEN + RULE_ASSUM_TAC(REWRITE_RULE[pathstart; pathfinish]) THEN + ASM_SIMP_TAC[reversepath; pathstart; pathfinish; VECTOR_SUB_REFL; + VECTOR_SUB_RZERO] THEN + CONJ_TAC THENL + [GEN_REWRITE_TAC LAND_CONV [GSYM o_DEF] THEN + MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN CONJ_TAC THENL + [MATCH_MP_TAC CONTINUOUS_ON_PASTECART THEN + SIMP_TAC[LINEAR_CONTINUOUS_ON; LINEAR_FSTCART; LINEAR_SNDCART; + CONTINUOUS_ON_SUB; CONTINUOUS_ON_CONST]; + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET)) THEN + SIMP_TAC[SUBSET; FORALL_IN_IMAGE; FORALL_IN_GSPEC; + IN_ELIM_PASTECART_THM; FSTCART_PASTECART; SNDCART_PASTECART] THEN + REWRITE_TAC[IN_INTERVAL_1; DROP_SUB; DROP_VEC] THEN REAL_ARITH_TAC]; + GEN_REWRITE_TAC (LAND_CONV o LAND_CONV) [GSYM o_DEF] THEN + REWRITE_TAC[IMAGE_o] THEN FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE + `IMAGE h s SUBSET t ==> IMAGE g s SUBSET s + ==> IMAGE h (IMAGE g s) SUBSET t`)) THEN + SIMP_TAC[SUBSET; FORALL_IN_IMAGE; FORALL_IN_GSPEC; + IN_ELIM_PASTECART_THM; FSTCART_PASTECART; SNDCART_PASTECART] THEN + REWRITE_TAC[IN_INTERVAL_1; DROP_SUB; DROP_VEC] THEN REAL_ARITH_TAC]);; + +let HOMOTOPIC_PATHS_JOIN = prove + (`!s p q p' q':real^1->real^N. + homotopic_paths s p p' /\ homotopic_paths s q q' /\ + pathfinish p = pathstart q + ==> homotopic_paths s (p ++ q) (p' ++ q')`, + REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[CONJ_ASSOC] THEN + DISCH_THEN(CONJUNCTS_THEN2 MP_TAC STRIP_ASSUME_TAC) THEN + REWRITE_TAC[homotopic_paths; homotopic_with; PCROSS] THEN + DISCH_THEN(CONJUNCTS_THEN2 + (X_CHOOSE_THEN `k1:real^(1,1)finite_sum->real^N` STRIP_ASSUME_TAC) + (X_CHOOSE_THEN `k2:real^(1,1)finite_sum->real^N` STRIP_ASSUME_TAC)) THEN + EXISTS_TAC `(\y. ((k1 o pastecart (fstcart y)) ++ + (k2 o pastecart (fstcart y))) (sndcart y)) + :real^(1,1)finite_sum->real^N` THEN + REPEAT CONJ_TAC THENL + [MATCH_MP_TAC(REWRITE_RULE[PCROSS] HOMOTOPIC_JOIN_LEMMA) THEN + ASM_REWRITE_TAC[o_DEF; PASTECART_FST_SND; ETA_AX] THEN + RULE_ASSUM_TAC(REWRITE_RULE[pathstart; pathfinish]) THEN + ASM_REWRITE_TAC[pathstart; pathfinish] THEN ASM_MESON_TAC[]; + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; FORALL_IN_GSPEC] THEN + REWRITE_TAC[FSTCART_PASTECART; SNDCART_PASTECART] THEN + REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN + REWRITE_TAC[ETA_AX; GSYM path_image; SET_RULE + `(!x. x IN i ==> f x IN s) <=> IMAGE f i SUBSET s`] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC SUBSET_PATH_IMAGE_JOIN THEN + REWRITE_TAC[path_image; SUBSET; FORALL_IN_IMAGE; o_DEF] THEN ASM SET_TAC[]; + ALL_TAC; ALL_TAC; ALL_TAC] THEN + REWRITE_TAC[FSTCART_PASTECART; SNDCART_PASTECART] THEN + ASM_REWRITE_TAC[joinpaths; o_DEF] THEN + RULE_ASSUM_TAC(REWRITE_RULE[pathstart; pathfinish]) THEN + REWRITE_TAC[pathstart; pathfinish; DROP_VEC] THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN + ASM_SIMP_TAC[VECTOR_ARITH `&2 % x - x:real^N = x`; VECTOR_MUL_RZERO]);; + +let HOMOTOPIC_PATHS_CONTINUOUS_IMAGE = prove + (`!f:real^1->real^M g h:real^M->real^N s t. + homotopic_paths s f g /\ + h continuous_on s /\ IMAGE h s SUBSET t + ==> homotopic_paths t (h o f) (h o g)`, + REWRITE_TAC[homotopic_paths] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC HOMOTOPIC_WITH_COMPOSE_CONTINUOUS_LEFT THEN + EXISTS_TAC `s:real^M->bool` THEN ASM_REWRITE_TAC[] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + HOMOTOPIC_WITH_MONO)) THEN + SIMP_TAC[pathstart; pathfinish; o_THM]);; + +(* ------------------------------------------------------------------------- *) +(* Group properties for homotopy of paths (so taking equivalence classes *) +(* under homotopy would give the fundamental group). *) +(* ------------------------------------------------------------------------- *) + +let HOMOTOPIC_PATHS_RID = prove + (`!s p. path p /\ path_image p SUBSET s + ==> homotopic_paths s (p ++ linepath(pathfinish p,pathfinish p)) p`, + REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[HOMOTOPIC_PATHS_SYM] THEN + MATCH_MP_TAC HOMOTOPIC_PATHS_REPARAMETRIZE THEN + ASM_REWRITE_TAC[joinpaths] THEN + EXISTS_TAC `\t. if drop t <= &1 / &2 then &2 % t else vec 1` THEN + ASM_REWRITE_TAC[DROP_VEC] THEN CONV_TAC REAL_RAT_REDUCE_CONV THEN + REWRITE_TAC[VECTOR_MUL_RZERO; linepath; pathfinish; + VECTOR_ARITH `(&1 - t) % x + t % x:real^N = x`] THEN + REWRITE_TAC[CONJ_ASSOC] THEN CONJ_TAC THENL [ALL_TAC; MESON_TAC[]] THEN + CONJ_TAC THENL + [SUBGOAL_THEN + `interval[vec 0:real^1,vec 1] = + interval[vec 0,lift(&1 / &2)] UNION interval[lift(&1 / &2),vec 1]` + SUBST1_TAC THENL + [REWRITE_TAC[EXTENSION; IN_UNION; IN_INTERVAL_1; LIFT_DROP; DROP_VEC] THEN + REAL_ARITH_TAC; + MATCH_MP_TAC CONTINUOUS_ON_CASES THEN + SIMP_TAC[CLOSED_INTERVAL; CONTINUOUS_ON_CMUL; CONTINUOUS_ON_ID; + CONTINUOUS_ON_CONST; IN_INTERVAL_1; DROP_VEC; LIFT_DROP; + GSYM DROP_EQ; DROP_CMUL] THEN + REAL_ARITH_TAC]; + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; IN_INTERVAL_1; DROP_VEC] THEN + GEN_TAC THEN COND_CASES_TAC THEN REWRITE_TAC[DROP_CMUL; DROP_VEC] THEN + ASM_REAL_ARITH_TAC]);; + +let HOMOTOPIC_PATHS_LID = prove + (`!s p:real^1->real^N. + path p /\ path_image p SUBSET s + ==> homotopic_paths s (linepath(pathstart p,pathstart p) ++ p) p`, + REPEAT STRIP_TAC THEN + ONCE_REWRITE_TAC[GSYM HOMOTOPIC_PATHS_REVERSEPATH] THEN + REWRITE_TAC[o_DEF; PATHSTART_REVERSEPATH; PATHFINISH_REVERSEPATH] THEN + SIMP_TAC[REVERSEPATH_JOINPATHS; REVERSEPATH_LINEPATH; + PATHFINISH_LINEPATH] THEN + ONCE_REWRITE_TAC[CONJ_SYM] THEN + MP_TAC(ISPECL [`s:real^N->bool`; `reversepath p :real^1->real^N`] + HOMOTOPIC_PATHS_RID) THEN + ASM_SIMP_TAC[PATH_REVERSEPATH; PATH_IMAGE_REVERSEPATH; + PATHSTART_REVERSEPATH; PATHFINISH_REVERSEPATH]);; + +let HOMOTOPIC_PATHS_ASSOC = prove + (`!s p q r:real^1->real^N. + path p /\ path_image p SUBSET s /\ + path q /\ path_image q SUBSET s /\ + path r /\ path_image r SUBSET s /\ + pathfinish p = pathstart q /\ pathfinish q = pathstart r + ==> homotopic_paths s (p ++ (q ++ r)) ((p ++ q) ++ r)`, + REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[HOMOTOPIC_PATHS_SYM] THEN + MATCH_MP_TAC HOMOTOPIC_PATHS_REPARAMETRIZE THEN + ASM_SIMP_TAC[PATH_JOIN; PATH_IMAGE_JOIN; UNION_SUBSET; + PATHSTART_JOIN; PATHFINISH_JOIN] THEN + REWRITE_TAC[joinpaths] THEN + EXISTS_TAC `\t. if drop t <= &1 / &2 then inv(&2) % t + else if drop t <= &3 / &4 then t - lift(&1 / &4) + else &2 % t - vec 1` THEN + REPEAT CONJ_TAC THENL + [MATCH_MP_TAC CONTINUOUS_ON_CASES_1 THEN + SIMP_TAC[CONTINUOUS_ON_CMUL; CONTINUOUS_ON_ID; LIFT_DROP] THEN + REWRITE_TAC[GSYM LIFT_SUB; GSYM LIFT_CMUL] THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN + MATCH_MP_TAC CONTINUOUS_ON_CASES_1 THEN + SIMP_TAC[CONTINUOUS_ON_CMUL; CONTINUOUS_ON_SUB; CONTINUOUS_ON_ID; + CONTINUOUS_ON_CONST] THEN + REWRITE_TAC[GSYM LIFT_SUB; GSYM LIFT_CMUL; GSYM LIFT_NUM] THEN + CONV_TAC REAL_RAT_REDUCE_CONV; + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; IN_INTERVAL_1; DROP_VEC] THEN + REPEAT STRIP_TAC THEN + REPEAT(COND_CASES_TAC THEN ASM_REWRITE_TAC[]) THEN + REWRITE_TAC[DROP_CMUL; DROP_VEC; LIFT_DROP; DROP_SUB] THEN + ASM_REAL_ARITH_TAC; + REWRITE_TAC[DROP_VEC] THEN CONV_TAC REAL_RAT_REDUCE_CONV THEN + REWRITE_TAC[VECTOR_MUL_RZERO]; + REWRITE_TAC[DROP_VEC] THEN CONV_TAC REAL_RAT_REDUCE_CONV THEN + VECTOR_ARITH_TAC; + X_GEN_TAC `t:real^1` THEN REWRITE_TAC[IN_INTERVAL_1; DROP_VEC] THEN + STRIP_TAC THEN + ASM_CASES_TAC `drop t <= &1 / &2` THEN ASM_REWRITE_TAC[DROP_CMUL] THEN + ASM_REWRITE_TAC[REAL_ARITH `inv(&2) * t <= &1 / &2 <=> t <= &1`] THEN + REWRITE_TAC[VECTOR_MUL_ASSOC; REAL_MUL_ASSOC] THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN ASM_REWRITE_TAC[REAL_MUL_LID] THEN + ASM_CASES_TAC `drop t <= &3 / &4` THEN + ASM_REWRITE_TAC[DROP_SUB; DROP_VEC; DROP_CMUL; LIFT_DROP; + REAL_ARITH `&2 * (t - &1 / &4) <= &1 / &2 <=> t <= &1 / &2`; + REAL_ARITH `&2 * t - &1 <= &1 / &2 <=> t <= &3 / &4`; + REAL_ARITH `t - &1 / &4 <= &1 / &2 <=> t <= &3 / &4`] THEN + REWRITE_TAC[VECTOR_SUB_LDISTRIB; VECTOR_MUL_ASSOC; GSYM LIFT_CMUL] THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN REWRITE_TAC[LIFT_NUM] THEN + REWRITE_TAC[VECTOR_ARITH `a - b - b:real^N = a - &2 % b`]]);; + +let HOMOTOPIC_PATHS_RINV = prove + (`!s p:real^1->real^N. + path p /\ path_image p SUBSET s + ==> homotopic_paths s + (p ++ reversepath p) (linepath(pathstart p,pathstart p))`, + REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[HOMOTOPIC_PATHS_SYM] THEN + REWRITE_TAC[homotopic_paths; homotopic_with; PCROSS] THEN + EXISTS_TAC `(\y. (subpath (vec 0) (fstcart y) p ++ + reversepath(subpath (vec 0) (fstcart y) p)) (sndcart y)) + : real^(1,1)finite_sum->real^N` THEN + REWRITE_TAC[FSTCART_PASTECART; SNDCART_PASTECART; SUBPATH_TRIVIAL] THEN + REWRITE_TAC[ETA_AX; PATHSTART_JOIN; PATHFINISH_JOIN] THEN + REWRITE_TAC[REVERSEPATH_SUBPATH; PATHSTART_SUBPATH; PATHFINISH_SUBPATH] THEN + REPEAT CONJ_TAC THENL + [REWRITE_TAC[joinpaths] THEN MATCH_MP_TAC CONTINUOUS_ON_CASES_LE THEN + RULE_ASSUM_TAC(REWRITE_RULE[path; path_image]) THEN REPEAT CONJ_TAC THENL + [REWRITE_TAC[subpath; VECTOR_ADD_LID; VECTOR_SUB_RZERO] THEN + GEN_REWRITE_TAC LAND_CONV [GSYM o_DEF] THEN + MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN CONJ_TAC THENL + [MATCH_MP_TAC CONTINUOUS_ON_MUL THEN + REWRITE_TAC[o_DEF; LIFT_DROP; ETA_AX] THEN + SIMP_TAC[LINEAR_CONTINUOUS_ON; LINEAR_FSTCART; LINEAR_SNDCART; + CONTINUOUS_ON_CMUL]; + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET)) THEN + REWRITE_TAC[FORALL_IN_IMAGE; SUBSET; FORALL_IN_GSPEC; IMP_CONJ] THEN + REWRITE_TAC[FSTCART_PASTECART; SNDCART_PASTECART] THEN + REWRITE_TAC[IN_INTERVAL_1; DROP_CMUL; DROP_VEC] THEN + REPEAT STRIP_TAC THEN ASM_SIMP_TAC[REAL_LE_MUL; REAL_POS] THEN + MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `drop x * &2 * &1 / &2` THEN CONJ_TAC THEN + REPEAT(MATCH_MP_TAC REAL_LE_LMUL THEN CONJ_TAC) THEN + ASM_REAL_ARITH_TAC]; + REWRITE_TAC[subpath; VECTOR_ADD_LID; VECTOR_SUB_RZERO] THEN + GEN_REWRITE_TAC LAND_CONV [GSYM o_DEF] THEN + MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN CONJ_TAC THENL + [MATCH_MP_TAC CONTINUOUS_ON_ADD THEN + SIMP_TAC[LINEAR_CONTINUOUS_ON; LINEAR_FSTCART] THEN + MATCH_MP_TAC CONTINUOUS_ON_MUL THEN + REWRITE_TAC[o_DEF; LIFT_DROP; ETA_AX] THEN + SIMP_TAC[LINEAR_CONTINUOUS_ON; LINEAR_FSTCART; LINEAR_SNDCART; + CONTINUOUS_ON_CMUL; CONTINUOUS_ON_SUB; CONTINUOUS_ON_CONST]; + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET)) THEN + REWRITE_TAC[FORALL_IN_IMAGE; SUBSET; FORALL_IN_GSPEC; IMP_CONJ] THEN + REWRITE_TAC[FSTCART_PASTECART; SNDCART_PASTECART] THEN + REWRITE_TAC[IN_INTERVAL_1; DROP_SUB; DROP_CMUL; DROP_VEC; DROP_ADD; + REAL_ARITH `t + (&0 - t) * (&2 * x - &1) = + t * &2 * (&1 - x)`] THEN + REPEAT STRIP_TAC THEN + ASM_SIMP_TAC[REAL_LE_MUL; REAL_POS; REAL_SUB_LE] THEN + MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `drop x * &2 * &1 / &2` THEN CONJ_TAC THEN + REPEAT(MATCH_MP_TAC REAL_LE_LMUL THEN CONJ_TAC) THEN + ASM_REAL_ARITH_TAC]; + SIMP_TAC[o_DEF; LIFT_DROP; ETA_AX; LINEAR_CONTINUOUS_ON; LINEAR_SNDCART]; + REWRITE_TAC[GSYM LIFT_EQ; LIFT_DROP] THEN + REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[subpath] THEN AP_TERM_TAC THEN + REWRITE_TAC[GSYM DROP_EQ; DROP_SUB; DROP_VEC; DROP_ADD; DROP_CMUL; + LIFT_DROP] THEN + REAL_ARITH_TAC]; + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; FORALL_IN_GSPEC] THEN + REWRITE_TAC[RIGHT_FORALL_IMP_THM; IMP_CONJ] THEN + X_GEN_TAC `t:real^1` THEN DISCH_TAC THEN + REWRITE_TAC[FSTCART_PASTECART; SNDCART_PASTECART; ETA_AX; + SET_RULE `(!x. x IN s ==> f x IN t) <=> IMAGE f s SUBSET t`] THEN + REWRITE_TAC[GSYM path_image] THEN MATCH_MP_TAC SUBSET_PATH_IMAGE_JOIN THEN + REWRITE_TAC[PATH_IMAGE_SUBPATH_GEN] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE LAND_CONV [path_image]) THEN + MATCH_MP_TAC(SET_RULE + `t SUBSET s /\ u SUBSET s + ==> IMAGE p s SUBSET v + ==> IMAGE p t SUBSET v /\ IMAGE p u SUBSET v`) THEN + REWRITE_TAC[SEGMENT_CONVEX_HULL] THEN CONJ_TAC THEN + MATCH_MP_TAC HULL_MINIMAL THEN REWRITE_TAC[CONVEX_INTERVAL] THEN + ASM_REWRITE_TAC[INSERT_SUBSET; EMPTY_SUBSET] THEN + REWRITE_TAC[IN_INTERVAL_1; DROP_VEC; REAL_POS; REAL_LE_REFL]; + REWRITE_TAC[subpath; linepath; pathstart; joinpaths] THEN + REWRITE_TAC[VECTOR_SUB_REFL; DROP_VEC; VECTOR_MUL_LZERO] THEN + REWRITE_TAC[VECTOR_ADD_RID; COND_ID] THEN VECTOR_ARITH_TAC; + REWRITE_TAC[pathstart; PATHFINISH_LINEPATH; PATHSTART_LINEPATH]]);; + +let HOMOTOPIC_PATHS_LINV = prove + (`!s p:real^1->real^N. + path p /\ path_image p SUBSET s + ==> homotopic_paths s + (reversepath p ++ p) (linepath(pathfinish p,pathfinish p))`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`s:real^N->bool`; `reversepath p:real^1->real^N`] + HOMOTOPIC_PATHS_RINV) THEN + ASM_SIMP_TAC[PATH_REVERSEPATH; PATH_IMAGE_REVERSEPATH] THEN + REWRITE_TAC[PATHSTART_REVERSEPATH; PATHFINISH_REVERSEPATH; + REVERSEPATH_REVERSEPATH]);; + +(* ------------------------------------------------------------------------- *) +(* Homotopy of loops without requiring preservation of endpoints. *) +(* ------------------------------------------------------------------------- *) + +let homotopic_loops = new_definition + `homotopic_loops s p q = + homotopic_with + (\r. pathfinish r = pathstart r) + (interval[vec 0:real^1,vec 1],s) + p q`;; + +let HOMOTOPIC_LOOPS = prove + (`!s p q:real^1->real^N. + homotopic_loops s p q <=> + ?h. h continuous_on + interval[vec 0,vec 1] PCROSS interval[vec 0,vec 1] /\ + IMAGE h (interval[vec 0,vec 1] PCROSS interval[vec 0,vec 1]) + SUBSET s /\ + (!x. x IN interval[vec 0,vec 1] ==> h(pastecart (vec 0) x) = p x) /\ + (!x. x IN interval[vec 0,vec 1] ==> h(pastecart (vec 1) x) = q x) /\ + (!t. t IN interval[vec 0:real^1,vec 1] + ==> pathfinish(h o pastecart t) = pathstart(h o pastecart t))`, + REPEAT GEN_TAC THEN + REWRITE_TAC[homotopic_loops] THEN + W(MP_TAC o PART_MATCH (lhand o rand) HOMOTOPIC_WITH o lhand o snd) THEN + ANTS_TAC THENL + [SIMP_TAC[pathstart; pathfinish; ENDS_IN_UNIT_INTERVAL]; + DISCH_THEN SUBST1_TAC THEN REWRITE_TAC[o_DEF]]);; + +let HOMOTOPIC_LOOPS_IMP_LOOP = prove + (`!s p q. homotopic_loops s p q + ==> pathfinish p = pathstart p /\ + pathfinish q = pathstart q`, + REPEAT GEN_TAC THEN REWRITE_TAC[homotopic_loops] THEN + DISCH_THEN(MP_TAC o MATCH_MP HOMOTOPIC_WITH_IMP_PROPERTY) THEN + SIMP_TAC[]);; + +let HOMOTOPIC_LOOPS_IMP_PATH = prove + (`!s p q. homotopic_loops s p q ==> path p /\ path q`, + REPEAT GEN_TAC THEN REWRITE_TAC[homotopic_loops] THEN + DISCH_THEN(MP_TAC o MATCH_MP HOMOTOPIC_WITH_IMP_CONTINUOUS) THEN + SIMP_TAC[path]);; + +let HOMOTOPIC_LOOPS_IMP_SUBSET = prove + (`!s p q. + homotopic_loops s p q ==> path_image p SUBSET s /\ path_image q SUBSET s`, + REPEAT GEN_TAC THEN REWRITE_TAC[homotopic_loops] THEN + DISCH_THEN(MP_TAC o MATCH_MP HOMOTOPIC_WITH_IMP_SUBSET) THEN + SIMP_TAC[path_image]);; + +let HOMOTOPIC_LOOPS_REFL = prove + (`!s p. homotopic_loops s p p <=> + path p /\ path_image p SUBSET s /\ pathfinish p = pathstart p`, + REWRITE_TAC[homotopic_loops; HOMOTOPIC_WITH_REFL; path; path_image]);; + +let HOMOTOPIC_LOOPS_SYM = prove + (`!s p q. homotopic_loops s p q <=> homotopic_loops s q p`, + REWRITE_TAC[homotopic_loops; HOMOTOPIC_WITH_SYM]);; + +let HOMOTOPIC_LOOPS_TRANS = prove + (`!s p q r. + homotopic_loops s p q /\ homotopic_loops s q r + ==> homotopic_loops s p r`, + REWRITE_TAC[homotopic_loops; HOMOTOPIC_WITH_TRANS]);; + +let HOMOTOPIC_LOOPS_SUBSET = prove + (`!s p q. + homotopic_loops s p q /\ s SUBSET t + ==> homotopic_loops t p q`, + REWRITE_TAC[homotopic_loops; HOMOTOPIC_WITH_SUBSET_RIGHT]);; + +let HOMOTOPIC_LOOPS_EQ = prove + (`!p:real^1->real^N q s. + path p /\ path_image p SUBSET s /\ pathfinish p = pathstart p /\ + (!t. t IN interval[vec 0,vec 1] ==> p(t) = q(t)) + ==> homotopic_loops s p q`, + REPEAT STRIP_TAC THEN REWRITE_TAC[homotopic_loops] THEN + MATCH_MP_TAC HOMOTOPIC_WITH_EQ THEN + REPEAT(EXISTS_TAC `p:real^1->real^N`) THEN + ASM_SIMP_TAC[HOMOTOPIC_WITH_REFL] THEN + ASM_REWRITE_TAC[GSYM path; GSYM path_image] THEN + REWRITE_TAC[pathstart; pathfinish] THEN + MESON_TAC[ENDS_IN_UNIT_INTERVAL]);; + +let HOMOTOPIC_LOOPS_CONTINUOUS_IMAGE = prove + (`!f:real^1->real^M g h:real^M->real^N s t. + homotopic_loops s f g /\ + h continuous_on s /\ IMAGE h s SUBSET t + ==> homotopic_loops t (h o f) (h o g)`, + REWRITE_TAC[homotopic_loops] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC HOMOTOPIC_WITH_COMPOSE_CONTINUOUS_LEFT THEN + EXISTS_TAC `s:real^M->bool` THEN ASM_REWRITE_TAC[] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + HOMOTOPIC_WITH_MONO)) THEN + SIMP_TAC[pathstart; pathfinish; o_THM]);; + +let HOMOTOPIC_LOOPS_SHIFTPATH_SELF = prove + (`!p:real^1->real^N t s. + path p /\ path_image p SUBSET s /\ pathfinish p = pathstart p /\ + t IN interval[vec 0,vec 1] + ==> homotopic_loops s p (shiftpath t p)`, + REPEAT STRIP_TAC THEN REWRITE_TAC[HOMOTOPIC_LOOPS] THEN EXISTS_TAC + `\z. shiftpath (drop t % fstcart z) (p:real^1->real^N) (sndcart z)` THEN + REWRITE_TAC[FSTCART_PASTECART; SNDCART_PASTECART; o_DEF] THEN + REWRITE_TAC[GSYM LIFT_EQ_CMUL; VECTOR_MUL_RZERO; ETA_AX] THEN + REPEAT CONJ_TAC THENL + [ALL_TAC; + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; FORALL_IN_PCROSS] THEN + REWRITE_TAC[FSTCART_PASTECART; SNDCART_PASTECART] THEN + MATCH_MP_TAC(SET_RULE + `IMAGE p t SUBSET u /\ + (!x. x IN s ==> IMAGE(shiftpath (f x) p) t = IMAGE p t) + ==> (!x y. x IN s /\ y IN t ==> shiftpath (f x) p y IN u)`) THEN + ASM_REWRITE_TAC[GSYM path_image] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC PATH_IMAGE_SHIFTPATH THEN + ASM_REWRITE_TAC[IN_INTERVAL_1; DROP_CMUL; DROP_VEC] THEN + RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1; DROP_VEC]) THEN + ASM_SIMP_TAC[REAL_LE_MUL] THEN + GEN_REWRITE_TAC RAND_CONV [GSYM REAL_MUL_RID] THEN + MATCH_MP_TAC REAL_LE_MUL2 THEN ASM_SIMP_TAC[]; + SIMP_TAC[shiftpath; VECTOR_ADD_LID; IN_INTERVAL_1; DROP_VEC]; + REWRITE_TAC[LIFT_DROP]; + X_GEN_TAC `x:real^1` THEN STRIP_TAC THEN MATCH_MP_TAC CLOSED_SHIFTPATH THEN + ASM_REWRITE_TAC[IN_INTERVAL_1; DROP_CMUL; DROP_VEC] THEN + RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1; DROP_VEC]) THEN + ASM_SIMP_TAC[REAL_LE_MUL] THEN + GEN_REWRITE_TAC RAND_CONV [GSYM REAL_MUL_RID] THEN + MATCH_MP_TAC REAL_LE_MUL2 THEN ASM_SIMP_TAC[]] THEN + REWRITE_TAC[shiftpath; DROP_ADD; DROP_CMUL] THEN + MATCH_MP_TAC CONTINUOUS_ON_CASES_LE THEN REPEAT CONJ_TAC THENL + [GEN_REWRITE_TAC LAND_CONV [GSYM o_DEF] THEN + MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN + SIMP_TAC[CONTINUOUS_ON_ADD; CONTINUOUS_ON_MUL; o_DEF; LIFT_DROP; + LINEAR_CONTINUOUS_ON; LINEAR_FSTCART; LINEAR_SNDCART; + CONTINUOUS_ON_CONST] THEN + RULE_ASSUM_TAC(REWRITE_RULE[path]) THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET)) THEN + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; FORALL_PASTECART] THEN + REWRITE_TAC[IN_ELIM_THM; PASTECART_IN_PCROSS] THEN + RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1; DROP_VEC]) THEN + ASM_SIMP_TAC[FSTCART_PASTECART; SNDCART_PASTECART; IN_INTERVAL_1; + DROP_ADD; DROP_CMUL; DROP_VEC; REAL_LE_ADD; REAL_LE_MUL]; + GEN_REWRITE_TAC LAND_CONV [GSYM o_DEF] THEN + MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN + SIMP_TAC[CONTINUOUS_ON_ADD; CONTINUOUS_ON_MUL; o_DEF; LIFT_DROP; + LINEAR_CONTINUOUS_ON; LINEAR_FSTCART; LINEAR_SNDCART; + CONTINUOUS_ON_CONST; CONTINUOUS_ON_SUB] THEN + RULE_ASSUM_TAC(REWRITE_RULE[path]) THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET)) THEN + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; FORALL_PASTECART] THEN + REWRITE_TAC[IN_ELIM_THM; PASTECART_IN_PCROSS] THEN + RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1; DROP_VEC]) THEN + ASM_SIMP_TAC[FSTCART_PASTECART; SNDCART_PASTECART; IN_INTERVAL_1; DROP_SUB; + DROP_ADD; DROP_CMUL; DROP_VEC; REAL_LE_ADD; REAL_LE_MUL] THEN + SIMP_TAC[REAL_ARITH `&0 <= x + y - &1 <=> &1 <= x + y`] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC(REAL_ARITH + `t * x <= &1 * &1 /\ y <= &1 ==> t * x + y - &1 <= &1`) THEN + ASM_SIMP_TAC[REAL_LE_MUL2; REAL_POS]; + REWRITE_TAC[o_DEF; LIFT_ADD; LIFT_CMUL; LIFT_DROP] THEN + SIMP_TAC[CONTINUOUS_ON_ADD; CONTINUOUS_ON_CMUL; LINEAR_CONTINUOUS_ON; + LINEAR_FSTCART; LINEAR_SNDCART]; + SIMP_TAC[GSYM LIFT_EQ; LIFT_ADD; LIFT_CMUL; LIFT_DROP; LIFT_NUM; + VECTOR_ARITH `a + b - c:real^1 = (a + b) - c`] THEN + ASM_MESON_TAC[VECTOR_SUB_REFL; pathstart; pathfinish]]);; + +(* ------------------------------------------------------------------------- *) +(* Relations between the two variants of homotopy. *) +(* ------------------------------------------------------------------------- *) + +let HOMOTOPIC_PATHS_IMP_HOMOTOPIC_LOOPS = prove + (`!s p q. homotopic_paths s p q /\ + pathfinish p = pathstart p /\ + pathfinish q = pathstart p + ==> homotopic_loops s p q`, + REPEAT GEN_TAC THEN + DISCH_THEN(CONJUNCTS_THEN2 MP_TAC STRIP_ASSUME_TAC) THEN + REWRITE_TAC[homotopic_paths; homotopic_loops] THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] HOMOTOPIC_WITH_MONO) THEN + ASM_SIMP_TAC[]);; + +let HOMOTOPIC_LOOPS_IMP_HOMOTOPIC_PATHS_NULL = prove + (`!s p a:real^N. + homotopic_loops s p (linepath(a,a)) + ==> homotopic_paths s p (linepath(pathstart p,pathstart p))`, + REPEAT STRIP_TAC THEN + FIRST_ASSUM(ASSUME_TAC o CONJUNCT1 o MATCH_MP HOMOTOPIC_LOOPS_IMP_LOOP) THEN + FIRST_ASSUM(STRIP_ASSUME_TAC o MATCH_MP HOMOTOPIC_LOOPS_IMP_PATH) THEN + FIRST_ASSUM(STRIP_ASSUME_TAC o MATCH_MP HOMOTOPIC_LOOPS_IMP_SUBSET) THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [homotopic_loops]) THEN + REWRITE_TAC[homotopic_with; PCROSS; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `h:real^(1,1)finite_sum->real^N` THEN STRIP_TAC THEN + MATCH_MP_TAC HOMOTOPIC_PATHS_TRANS THEN EXISTS_TAC + `(p:real^1->real^N) ++ linepath(pathfinish p,pathfinish p)` THEN + CONJ_TAC THENL + [ASM_MESON_TAC[HOMOTOPIC_PATHS_RID; HOMOTOPIC_PATHS_SYM]; ALL_TAC] THEN + MATCH_MP_TAC HOMOTOPIC_PATHS_TRANS THEN EXISTS_TAC + `linepath(pathstart p,pathstart p) ++ (p:real^1->real^N) ++ + linepath(pathfinish p,pathfinish p)` THEN + CONJ_TAC THENL + [ONCE_REWRITE_TAC[HOMOTOPIC_PATHS_SYM] THEN + MP_TAC(ISPECL [`s:real^N->bool`; + `(p:real^1->real^N) ++ linepath(pathfinish p,pathfinish p)`] + HOMOTOPIC_PATHS_LID) THEN + REWRITE_TAC[PATHSTART_JOIN] THEN DISCH_THEN MATCH_MP_TAC THEN + ASM_SIMP_TAC[PATH_JOIN; PATH_LINEPATH; PATHSTART_LINEPATH] THEN + MATCH_MP_TAC SUBSET_PATH_IMAGE_JOIN THEN + ASM_REWRITE_TAC[PATH_IMAGE_LINEPATH; SEGMENT_REFL] THEN + REWRITE_TAC[INSERT_SUBSET; EMPTY_SUBSET] THEN + ASM_MESON_TAC[PATHSTART_IN_PATH_IMAGE; SUBSET]; + ALL_TAC] THEN + MATCH_MP_TAC HOMOTOPIC_PATHS_TRANS THEN EXISTS_TAC + `((\u. (h:real^(1,1)finite_sum->real^N) (pastecart u (vec 0))) ++ + linepath(a,a) ++ + reversepath(\u. h (pastecart u (vec 0))))` THEN + CONJ_TAC THENL + [ALL_TAC; + MATCH_MP_TAC(MESON[HOMOTOPIC_PATHS_LID; HOMOTOPIC_PATHS_JOIN; + HOMOTOPIC_PATHS_TRANS; HOMOTOPIC_PATHS_SYM; + HOMOTOPIC_PATHS_RINV] + `(path p /\ path(reversepath p)) /\ + (path_image p SUBSET s /\ path_image(reversepath p) SUBSET s) /\ + (pathfinish p = pathstart(linepath(b,b) ++ reversepath p) /\ + pathstart(reversepath p) = b) /\ + pathstart p = a + ==> homotopic_paths s (p ++ linepath(b,b) ++ reversepath p) + (linepath(a,a))`) THEN + REWRITE_TAC[PATHSTART_REVERSEPATH; PATHSTART_JOIN; PATH_REVERSEPATH; + PATH_IMAGE_REVERSEPATH; PATHSTART_LINEPATH] THEN + ASM_REWRITE_TAC[path; path_image; pathstart; pathfinish; + LINEPATH_REFL] THEN + CONJ_TAC THENL + [GEN_REWRITE_TAC LAND_CONV [GSYM o_DEF] THEN + MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN + SIMP_TAC[CONTINUOUS_ON_PASTECART; CONTINUOUS_ON_ID; + CONTINUOUS_ON_CONST] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET)) THEN + SIMP_TAC[SUBSET; FORALL_IN_IMAGE; IN_ELIM_PASTECART_THM; + ENDS_IN_UNIT_INTERVAL]; + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ_ALT] + SUBSET_TRANS)) THEN + GEN_REWRITE_TAC (LAND_CONV o LAND_CONV) [GSYM o_DEF] THEN + REWRITE_TAC[IMAGE_o] THEN MATCH_MP_TAC IMAGE_SUBSET THEN + SIMP_TAC[SUBSET; FORALL_IN_IMAGE; IN_ELIM_PASTECART_THM; + ENDS_IN_UNIT_INTERVAL]]] THEN + REWRITE_TAC[homotopic_paths; homotopic_with; PCROSS] THEN + EXISTS_TAC + `\y:real^(1,1)finite_sum. + (subpath (vec 0) (fstcart y) (\u. h(pastecart u (vec 0))) ++ + (\u. (h:real^(1,1)finite_sum->real^N) (pastecart (fstcart y) u)) ++ + subpath (fstcart y) (vec 0) (\u. h(pastecart u (vec 0)))) + (sndcart y)` THEN + ASM_REWRITE_TAC[FSTCART_PASTECART; SNDCART_PASTECART; SUBPATH_TRIVIAL; + SUBPATH_REFL; SUBPATH_REVERSEPATH; ETA_AX; + PATHSTART_JOIN; PATHFINISH_JOIN; + PATHSTART_SUBPATH; PATHFINISH_SUBPATH; + PATHSTART_LINEPATH; PATHFINISH_LINEPATH] THEN + ONCE_REWRITE_TAC[CONJ_ASSOC] THEN CONJ_TAC THENL + [ALL_TAC; REWRITE_TAC[pathstart]] THEN + CONJ_TAC THENL + [MATCH_MP_TAC(REWRITE_RULE[PCROSS] HOMOTOPIC_JOIN_LEMMA) THEN + REWRITE_TAC[] THEN REPEAT CONJ_TAC THENL + [ALL_TAC; + MATCH_MP_TAC(REWRITE_RULE[PCROSS] HOMOTOPIC_JOIN_LEMMA) THEN + ASM_REWRITE_TAC[PASTECART_FST_SND; ETA_AX] THEN CONJ_TAC THENL + [ALL_TAC; + RULE_ASSUM_TAC(REWRITE_RULE[pathstart; pathfinish]) THEN + REWRITE_TAC[PATHSTART_SUBPATH] THEN + ASM_SIMP_TAC[pathstart; pathfinish]]; + RULE_ASSUM_TAC(REWRITE_RULE[pathstart; pathfinish]) THEN + REWRITE_TAC[PATHFINISH_SUBPATH; PATHSTART_JOIN] THEN + ASM_SIMP_TAC[pathstart]] THEN + REWRITE_TAC[subpath] THEN GEN_REWRITE_TAC LAND_CONV [GSYM o_DEF] THEN + MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN + REWRITE_TAC[VECTOR_SUB_RZERO; VECTOR_SUB_LZERO; VECTOR_ADD_LID] THEN + (CONV_TAC o GEN_SIMPLIFY_CONV TOP_DEPTH_SQCONV (basic_ss []) 5) + [CONTINUOUS_ON_PASTECART; CONTINUOUS_ON_ADD; CONTINUOUS_ON_MUL; + LIFT_DROP; CONTINUOUS_ON_NEG; DROP_NEG; CONTINUOUS_ON_CONST; + CONTINUOUS_ON_ID; LINEAR_CONTINUOUS_ON; LINEAR_FSTCART; LINEAR_SNDCART; + LIFT_NEG; o_DEF; ETA_AX] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET)) THEN + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; FORALL_IN_GSPEC] THEN + REWRITE_TAC[IN_ELIM_PASTECART_THM] THEN + REWRITE_TAC[FSTCART_PASTECART; SNDCART_PASTECART; IN_INTERVAL_1] THEN + REWRITE_TAC[DROP_ADD; DROP_NEG; DROP_VEC; DROP_CMUL; REAL_POS] THEN + SIMP_TAC[REAL_LE_MUL; REAL_SUB_LE; REAL_ARITH + `t + --t * x = t * (&1 - x)`] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC(REAL_ARITH + `t * x <= t * &1 /\ &1 * t <= &1 * &1 ==> t * x <= &1`) THEN + CONJ_TAC THEN MATCH_MP_TAC REAL_LE_LMUL THEN ASM_REAL_ARITH_TAC; + + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; FORALL_IN_GSPEC; IMP_CONJ; + RIGHT_FORALL_IMP_THM; FSTCART_PASTECART; SNDCART_PASTECART] THEN + X_GEN_TAC `t:real^1` THEN STRIP_TAC THEN + REWRITE_TAC[SET_RULE + `(!x. x IN s ==> f x IN t) <=> IMAGE f s SUBSET t`] THEN + REWRITE_TAC[GSYM path_image; ETA_AX] THEN + REPEAT(MATCH_MP_TAC SUBSET_PATH_IMAGE_JOIN THEN CONJ_TAC) THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ_ALT] + SUBSET_TRANS)) THEN + REWRITE_TAC[path_image; subpath] THEN + GEN_REWRITE_TAC (LAND_CONV o LAND_CONV) [GSYM o_DEF] THEN + REWRITE_TAC[IMAGE_o] THEN MATCH_MP_TAC IMAGE_SUBSET THEN + ASM_SIMP_TAC[SUBSET; FORALL_IN_IMAGE; IN_ELIM_PASTECART_THM] THEN + SIMP_TAC[IN_INTERVAL_1; DROP_SUB; DROP_VEC; DROP_CMUL; DROP_ADD] THEN + REWRITE_TAC[REAL_ADD_LID; REAL_SUB_RZERO; REAL_POS] THEN + REWRITE_TAC[REAL_ARITH `t + (&0 - t) * x = t * (&1 - x)`] THEN + RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1; DROP_VEC]) THEN + ASM_SIMP_TAC[REAL_LE_MUL; REAL_SUB_LE] THEN + REPEAT STRIP_TAC THEN + GEN_REWRITE_TAC RAND_CONV [GSYM REAL_MUL_RID] THEN + MATCH_MP_TAC REAL_LE_MUL2 THEN ASM_REAL_ARITH_TAC]);; + +let HOMOTOPIC_LOOPS_CONJUGATE = prove + (`!p q s:real^N->bool. + path p /\ path_image p SUBSET s /\ + path q /\ path_image q SUBSET s /\ + pathfinish p = pathstart q /\ pathfinish q = pathstart q + ==> homotopic_loops s (p ++ q ++ reversepath p) q`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC HOMOTOPIC_LOOPS_TRANS THEN EXISTS_TAC + `linepath(pathstart q,pathstart q) ++ (q:real^1->real^N) ++ + linepath(pathstart q,pathstart q)` THEN + CONJ_TAC THENL + [ALL_TAC; + MATCH_MP_TAC HOMOTOPIC_PATHS_IMP_HOMOTOPIC_LOOPS THEN + MP_TAC(ISPECL [`s:real^N->bool`; + `(q:real^1->real^N) ++ linepath(pathfinish q,pathfinish q)`] + HOMOTOPIC_PATHS_LID) THEN + ASM_SIMP_TAC[PATHSTART_JOIN; PATHFINISH_JOIN; UNION_SUBSET; SING_SUBSET; + PATHSTART_LINEPATH; PATHFINISH_LINEPATH; PATH_IMAGE_LINEPATH; + PATH_JOIN; PATH_IMAGE_JOIN; PATH_LINEPATH; SEGMENT_REFL] THEN + ANTS_TAC THENL + [ASM_MESON_TAC[PATHSTART_IN_PATH_IMAGE; SUBSET]; ALL_TAC] THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] HOMOTOPIC_PATHS_TRANS) THEN + ASM_MESON_TAC[HOMOTOPIC_PATHS_RID]] THEN + REWRITE_TAC[homotopic_loops; homotopic_with; PCROSS] THEN + EXISTS_TAC + `(\y. (subpath (fstcart y) (vec 1) p ++ q ++ subpath (vec 1) (fstcart y) p) + (sndcart y)):real^(1,1)finite_sum->real^N` THEN + ASM_REWRITE_TAC[FSTCART_PASTECART; SNDCART_PASTECART; SUBPATH_TRIVIAL; + SUBPATH_REFL; SUBPATH_REVERSEPATH; ETA_AX; + PATHSTART_JOIN; PATHFINISH_JOIN; + PATHSTART_SUBPATH; PATHFINISH_SUBPATH; + PATHSTART_LINEPATH; PATHFINISH_LINEPATH] THEN + RULE_ASSUM_TAC(REWRITE_RULE[pathstart; pathfinish]) THEN + ASM_REWRITE_TAC[pathstart; pathfinish] THEN CONJ_TAC THENL + [RULE_ASSUM_TAC(REWRITE_RULE[path; path_image]) THEN + MATCH_MP_TAC(REWRITE_RULE[PCROSS] HOMOTOPIC_JOIN_LEMMA) THEN + REPEAT CONJ_TAC THENL + [ALL_TAC; + MATCH_MP_TAC(REWRITE_RULE[PCROSS] HOMOTOPIC_JOIN_LEMMA) THEN + REPEAT CONJ_TAC THENL + [GEN_REWRITE_TAC LAND_CONV [GSYM o_DEF] THEN + MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN + SIMP_TAC[LINEAR_CONTINUOUS_ON; LINEAR_SNDCART] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET)) THEN + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; FORALL_IN_GSPEC] THEN + SIMP_TAC[SNDCART_PASTECART]; + ALL_TAC; + REWRITE_TAC[PATHSTART_SUBPATH] THEN ASM_REWRITE_TAC[pathfinish]]; + REWRITE_TAC[PATHSTART_JOIN; PATHFINISH_SUBPATH] THEN + ASM_REWRITE_TAC[pathstart]] THEN + REWRITE_TAC[subpath] THEN GEN_REWRITE_TAC LAND_CONV [GSYM o_DEF] THEN + MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN + (CONJ_TAC THENL + [REWRITE_TAC[DROP_SUB] THEN MATCH_MP_TAC CONTINUOUS_ON_ADD THEN + SIMP_TAC[LINEAR_CONTINUOUS_ON; CONTINUOUS_ON_CONST; LINEAR_FSTCART] THEN + MATCH_MP_TAC CONTINUOUS_ON_MUL THEN + SIMP_TAC[LINEAR_CONTINUOUS_ON; LINEAR_SNDCART] THEN + REWRITE_TAC[o_DEF; LIFT_SUB; LIFT_DROP] THEN + SIMP_TAC[CONTINUOUS_ON_SUB; CONTINUOUS_ON_CONST; LINEAR_CONTINUOUS_ON; + LINEAR_FSTCART]; + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET)) THEN + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; FORALL_IN_GSPEC] THEN + REWRITE_TAC[FSTCART_PASTECART; SNDCART_PASTECART; IN_INTERVAL_1] THEN + REWRITE_TAC[DROP_ADD; DROP_SUB; DROP_VEC; DROP_CMUL]]) + THENL + [REPEAT STRIP_TAC THENL + [MATCH_MP_TAC REAL_LE_ADD THEN CONJ_TAC THEN + TRY(MATCH_MP_TAC REAL_LE_MUL) THEN ASM_REAL_ARITH_TAC; + REWRITE_TAC[REAL_ARITH `t + (&1 - t) * x <= &1 <=> + (&1 - t) * x <= (&1 - t) * &1`] THEN + MATCH_MP_TAC REAL_LE_LMUL THEN ASM_REAL_ARITH_TAC]; + REPEAT STRIP_TAC THENL + [MATCH_MP_TAC(REAL_ARITH + `x * (&1 - t) <= x * &1 /\ x <= &1 + ==> &0 <= &1 + (t - &1) * x`) THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC REAL_LE_LMUL THEN + ASM_REAL_ARITH_TAC; + REWRITE_TAC[REAL_ARITH + `a + (t - &1) * x <= a <=> &0 <= (&1 - t) * x`] THEN + MATCH_MP_TAC REAL_LE_MUL THEN ASM_REAL_ARITH_TAC]]; + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; FORALL_IN_GSPEC] THEN + REWRITE_TAC[FSTCART_PASTECART; SNDCART_PASTECART] THEN + REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN + REWRITE_TAC[ETA_AX; GSYM path_image; SET_RULE + `(!x. x IN i ==> f x IN s) <=> IMAGE f i SUBSET s`] THEN + REPEAT STRIP_TAC THEN + REPEAT(MATCH_MP_TAC SUBSET_PATH_IMAGE_JOIN THEN CONJ_TAC) THEN + ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC SUBSET_TRANS THEN EXISTS_TAC `path_image p:real^N->bool` THEN + ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC PATH_IMAGE_SUBPATH_SUBSET THEN + ASM_REWRITE_TAC[ENDS_IN_UNIT_INTERVAL]]);; + +(* ------------------------------------------------------------------------- *) +(* Relating homotopy of trivial loops to path-connectedness. *) +(* ------------------------------------------------------------------------- *) + +let PATH_COMPONENT_IMP_HOMOTOPIC_POINTS = prove + (`!s a b:real^N. + path_component s a b + ==> homotopic_loops s (linepath(a,a)) (linepath(b,b))`, + REWRITE_TAC[path_component; homotopic_loops; homotopic_with; PCROSS] THEN + REPEAT GEN_TAC THEN REWRITE_TAC[pathstart; pathfinish; path_image; path] THEN + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; FORALL_IN_GSPEC] THEN + DISCH_THEN(X_CHOOSE_THEN `g:real^1->real^N` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `\y:real^(1,1)finite_sum. (g(fstcart y):real^N)` THEN + ASM_SIMP_TAC[FSTCART_PASTECART; linepath] THEN + REWRITE_TAC[VECTOR_ARITH `(&1 - x) % a + x % a:real^N = a`] THEN + MATCH_MP_TAC(REWRITE_RULE[o_DEF] CONTINUOUS_ON_COMPOSE) THEN + SIMP_TAC[LINEAR_CONTINUOUS_ON; LINEAR_FSTCART] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET)) THEN + SIMP_TAC[SUBSET; FORALL_IN_IMAGE; FORALL_IN_GSPEC; FSTCART_PASTECART]);; + +let HOMOTOPIC_LOOPS_IMP_PATH_COMPONENT_VALUE = prove + (`!s p q:real^1->real^N t. + homotopic_loops s p q /\ t IN interval[vec 0,vec 1] + ==> path_component s (p t) (q t)`, + REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN + REWRITE_TAC[path_component; homotopic_loops; homotopic_with; PCROSS] THEN + DISCH_THEN(X_CHOOSE_THEN `h:real^(1,1)finite_sum->real^N` MP_TAC) THEN + STRIP_TAC THEN + EXISTS_TAC `\u. (h:real^(1,1)finite_sum->real^N) (pastecart u t)` THEN + ASM_REWRITE_TAC[pathstart; pathfinish] THEN CONJ_TAC THENL + [REWRITE_TAC[path] THEN + MATCH_MP_TAC(REWRITE_RULE[o_DEF] CONTINUOUS_ON_COMPOSE) THEN + CONJ_TAC THENL + [MATCH_MP_TAC CONTINUOUS_ON_PASTECART THEN + REWRITE_TAC[CONTINUOUS_ON_CONST; CONTINUOUS_ON_ID]; + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET)) THEN + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; FORALL_IN_GSPEC] THEN + ASM SET_TAC[]]; + REWRITE_TAC[path_image] THEN ASM SET_TAC[]]);; + +let HOMOTOPIC_POINTS_EQ_PATH_COMPONENT = prove + (`!s a b:real^N. + homotopic_loops s (linepath(a,a)) (linepath(b,b)) <=> + path_component s a b`, + REPEAT GEN_TAC THEN EQ_TAC THEN + REWRITE_TAC[PATH_COMPONENT_IMP_HOMOTOPIC_POINTS] THEN + DISCH_THEN(MP_TAC o SPEC `vec 0:real^1` o MATCH_MP (REWRITE_RULE[IMP_CONJ] + HOMOTOPIC_LOOPS_IMP_PATH_COMPONENT_VALUE)) THEN + REWRITE_TAC[linepath; IN_INTERVAL_1; DROP_VEC; REAL_POS] THEN + REWRITE_TAC[VECTOR_ARITH `(&1 - &0) % a + &0 % b:real^N = a`]);; + +let PATH_CONNECTED_EQ_HOMOTOPIC_POINTS = prove + (`!s:real^N->bool. + path_connected s <=> + !a b. a IN s /\ b IN s + ==> homotopic_loops s (linepath(a,a)) (linepath(b,b))`, + GEN_TAC THEN REWRITE_TAC[HOMOTOPIC_POINTS_EQ_PATH_COMPONENT] THEN + REWRITE_TAC[path_connected; path_component]);; + +(* ------------------------------------------------------------------------- *) +(* Homotopy of "nearby" function, paths and loops. *) +(* ------------------------------------------------------------------------- *) + +let HOMOTOPIC_WITH_LINEAR = prove + (`!f g:real^M->real^N s t. + f continuous_on s /\ g continuous_on s /\ + (!x. x IN s ==> segment[f x,g x] SUBSET t) + ==> homotopic_with (\z. T) (s,t) f g`, + REPEAT STRIP_TAC THEN REWRITE_TAC[homotopic_with] THEN + EXISTS_TAC + `\y. ((&1 - drop(fstcart y)) % (f:real^M->real^N)(sndcart y) + + drop(fstcart y) % g(sndcart y):real^N)` THEN + REWRITE_TAC[FSTCART_PASTECART; SNDCART_PASTECART; DROP_VEC] THEN + ASM_REWRITE_TAC[REAL_SUB_REFL; REAL_SUB_RZERO] THEN + REWRITE_TAC[VECTOR_ARITH `(&1 - t) % a + t % a:real^N = a`] THEN + REWRITE_TAC[VECTOR_MUL_LZERO; VECTOR_MUL_LID] THEN + REWRITE_TAC[VECTOR_ADD_LID; VECTOR_ADD_RID] THEN CONJ_TAC THENL + [MATCH_MP_TAC CONTINUOUS_ON_ADD THEN CONJ_TAC THEN + MATCH_MP_TAC CONTINUOUS_ON_MUL THEN + REWRITE_TAC[o_DEF; LIFT_DROP; LIFT_SUB] THEN + SIMP_TAC[CONTINUOUS_ON_SUB; CONTINUOUS_ON_CONST; LINEAR_CONTINUOUS_ON; + LINEAR_FSTCART; ETA_AX] THEN + GEN_REWRITE_TAC LAND_CONV [GSYM o_DEF] THEN + MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN + SIMP_TAC[LINEAR_CONTINUOUS_ON; LINEAR_SNDCART] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET)) THEN + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; FORALL_IN_GSPEC] THEN + SIMP_TAC[SNDCART_PASTECART; FORALL_IN_PCROSS]; + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; FORALL_IN_PCROSS] THEN + MAP_EVERY X_GEN_TAC [`t:real^1`; `u:real^M`] THEN STRIP_TAC THEN + SIMP_TAC[FSTCART_PASTECART; SNDCART_PASTECART] THEN + RULE_ASSUM_TAC(REWRITE_RULE[SUBSET; RIGHT_IMP_FORALL_THM; IMP_IMP]) THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN EXISTS_TAC `u:real^M` THEN + ASM_REWRITE_TAC[IN_SEGMENT] THEN EXISTS_TAC `drop t` THEN + ASM_MESON_TAC[IN_INTERVAL_1; DROP_VEC]]);; + +let HOMOTOPIC_PATHS_LINEAR,HOMOTOPIC_LOOPS_LINEAR = (CONJ_PAIR o prove) + (`(!g s:real^N->bool h. + path g /\ path h /\ + pathstart h = pathstart g /\ pathfinish h = pathfinish g /\ + (!t x. t IN interval[vec 0,vec 1] ==> segment[g t,h t] SUBSET s) + ==> homotopic_paths s g h) /\ + (!g s:real^N->bool h. + path g /\ path h /\ + pathfinish g = pathstart g /\ pathfinish h = pathstart h /\ + (!t x. t IN interval[vec 0,vec 1] ==> segment[g t,h t] SUBSET s) + ==> homotopic_loops s g h)`, + CONJ_TAC THEN + (REWRITE_TAC[pathstart; pathfinish] THEN + REWRITE_TAC[SUBSET; RIGHT_IMP_FORALL_THM; IMP_IMP] THEN REPEAT STRIP_TAC THEN + REWRITE_TAC[homotopic_paths; homotopic_loops; homotopic_with; PCROSS] THEN + EXISTS_TAC + `\y:real^(1,1)finite_sum. + ((&1 - drop(fstcart y)) % g(sndcart y) + + drop(fstcart y) % h(sndcart y):real^N)` THEN + REWRITE_TAC[FSTCART_PASTECART; SNDCART_PASTECART; DROP_VEC] THEN + ASM_REWRITE_TAC[pathstart; pathfinish; REAL_SUB_REFL; REAL_SUB_RZERO] THEN + REWRITE_TAC[VECTOR_ARITH `(&1 - t) % a + t % a:real^N = a`] THEN + REWRITE_TAC[VECTOR_MUL_LZERO; VECTOR_MUL_LID] THEN + REWRITE_TAC[VECTOR_ADD_LID; VECTOR_ADD_RID] THEN CONJ_TAC THENL + [MATCH_MP_TAC CONTINUOUS_ON_ADD THEN CONJ_TAC THEN + MATCH_MP_TAC CONTINUOUS_ON_MUL THEN + REWRITE_TAC[o_DEF; LIFT_DROP; LIFT_SUB] THEN + SIMP_TAC[CONTINUOUS_ON_SUB; CONTINUOUS_ON_CONST; LINEAR_CONTINUOUS_ON; + LINEAR_FSTCART; ETA_AX] THEN + GEN_REWRITE_TAC LAND_CONV [GSYM o_DEF] THEN + MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN + SIMP_TAC[LINEAR_CONTINUOUS_ON; LINEAR_SNDCART] THEN + RULE_ASSUM_TAC(REWRITE_RULE[path]) THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET)) THEN + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; FORALL_IN_GSPEC] THEN + SIMP_TAC[SNDCART_PASTECART]; + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; FORALL_IN_GSPEC] THEN + MAP_EVERY X_GEN_TAC [`t:real^1`; `u:real^1`] THEN STRIP_TAC THEN + SIMP_TAC[FSTCART_PASTECART; SNDCART_PASTECART] THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN EXISTS_TAC `u:real^1` THEN + ASM_REWRITE_TAC[IN_SEGMENT] THEN EXISTS_TAC `drop t` THEN + ASM_MESON_TAC[IN_INTERVAL_1; DROP_VEC]]));; + +let HOMOTOPIC_PATHS_NEARBY_EXPLICIT, + HOMOTOPIC_LOOPS_NEARBY_EXPLICIT = (CONJ_PAIR o prove) + (`(!g s:real^N->bool h. + path g /\ path h /\ + pathstart h = pathstart g /\ pathfinish h = pathfinish g /\ + (!t x. t IN interval[vec 0,vec 1] /\ ~(x IN s) + ==> norm(h t - g t) < norm(g t - x)) + ==> homotopic_paths s g h) /\ + (!g s:real^N->bool h. + path g /\ path h /\ + pathfinish g = pathstart g /\ pathfinish h = pathstart h /\ + (!t x. t IN interval[vec 0,vec 1] /\ ~(x IN s) + ==> norm(h t - g t) < norm(g t - x)) + ==> homotopic_loops s g h)`, + ONCE_REWRITE_TAC[TAUT `p /\ ~q ==> r <=> p /\ ~r ==> q`] THEN + REPEAT STRIP_TAC THENL + [MATCH_MP_TAC HOMOTOPIC_PATHS_LINEAR; + MATCH_MP_TAC HOMOTOPIC_LOOPS_LINEAR] THEN + ASM_REWRITE_TAC[] THEN REWRITE_TAC[SUBSET; segment; FORALL_IN_GSPEC] THEN + X_GEN_TAC `t:real^1` THEN STRIP_TAC THEN + X_GEN_TAC `u:real` THEN STRIP_TAC THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN EXISTS_TAC `t:real^1` THEN + ASM_REWRITE_TAC[REAL_NOT_LT] THEN + MP_TAC(ISPECL [`(g:real^1->real^N) t`; `(h:real^1->real^N) t`] + DIST_IN_CLOSED_SEGMENT) THEN + RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1; DROP_VEC]) THEN + REWRITE_TAC[segment; FORALL_IN_GSPEC; + ONCE_REWRITE_RULE[DIST_SYM] dist] THEN + ASM_MESON_TAC[]);; + +let HOMOTOPIC_NEARBY_PATHS,HOMOTOPIC_NEARBY_LOOPS = (CONJ_PAIR o prove) + (`(!g s:real^N->bool. + path g /\ open s /\ path_image g SUBSET s + ==> ?e. &0 < e /\ + !h. path h /\ + pathstart h = pathstart g /\ + pathfinish h = pathfinish g /\ + (!t. t IN interval[vec 0,vec 1] ==> norm(h t - g t) < e) + ==> homotopic_paths s g h) /\ + (!g s:real^N->bool. + path g /\ pathfinish g = pathstart g /\ open s /\ path_image g SUBSET s + ==> ?e. &0 < e /\ + !h. path h /\ + pathfinish h = pathstart h /\ + (!t. t IN interval[vec 0,vec 1] ==> norm(h t - g t) < e) + ==> homotopic_loops s g h)`, + CONJ_TAC THEN + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`path_image g:real^N->bool`; `(:real^N) DIFF s`] + SEPARATE_COMPACT_CLOSED) THEN + ASM_SIMP_TAC[COMPACT_PATH_IMAGE; GSYM OPEN_CLOSED] THEN + (ANTS_TAC THENL [ASM SET_TAC[]; REWRITE_TAC[IN_DIFF; IN_UNIV; dist]]) THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `e:real` THEN + REWRITE_TAC[REAL_NOT_LE] THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + X_GEN_TAC `h:real^1->real^N` THEN STRIP_TAC THENL + [MATCH_MP_TAC HOMOTOPIC_PATHS_NEARBY_EXPLICIT; + MATCH_MP_TAC HOMOTOPIC_LOOPS_NEARBY_EXPLICIT] THEN + ASM_REWRITE_TAC[] THEN + MAP_EVERY X_GEN_TAC [`t:real^1`; `x:real^N`] THEN STRIP_TAC THEN + MATCH_MP_TAC REAL_LTE_TRANS THEN EXISTS_TAC `e:real` THEN + ASM_SIMP_TAC[] THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_REWRITE_TAC[path_image] THEN ASM SET_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* Homotopy of non-antipodal sphere maps. *) +(* ------------------------------------------------------------------------- *) + +let HOMOTOPIC_NON_MIDPOINT_SPHEREMAPS = prove + (`!f g:real^M->real^N s a r. + f continuous_on s /\ IMAGE f s SUBSET sphere(a,r) /\ + g continuous_on s /\ IMAGE g s SUBSET sphere(a,r) /\ + (!x. x IN s ==> ~(midpoint(f x,g x) = a)) + ==> homotopic_with (\x. T) (s,sphere(a,r)) f g`, + REPEAT GEN_TAC THEN ASM_CASES_TAC `r <= &0` THENL + [REPEAT STRIP_TAC THEN MATCH_MP_TAC HOMOTOPIC_WITH_EQ THEN + REPEAT(EXISTS_TAC `g:real^M->real^N`) THEN + ASM_REWRITE_TAC[HOMOTOPIC_WITH_REFL] THEN + SUBGOAL_THEN `?c:real^N. sphere(a,r) SUBSET {c}` MP_TAC THENL + [ALL_TAC; ASM SET_TAC[]] THEN + ASM_CASES_TAC `r = &0` THEN + ASM_SIMP_TAC[SPHERE_SING; SPHERE_EMPTY; REAL_LT_LE] THEN + MESON_TAC[SUBSET_REFL; EMPTY_SUBSET]; + RULE_ASSUM_TAC(REWRITE_RULE[REAL_NOT_LE]) THEN STRIP_TAC] THEN + SUBGOAL_THEN + `homotopic_with (\z. T) (s:real^M->bool,(:real^N) DELETE a) f g` + MP_TAC THENL + [MATCH_MP_TAC HOMOTOPIC_WITH_LINEAR THEN + ASM_REWRITE_TAC[SET_RULE `s SUBSET UNIV DELETE a <=> ~(a IN s)`] THEN + X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN + REPEAT(FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [SUBSET])) THEN + REWRITE_TAC[FORALL_IN_IMAGE; IN_SPHERE; IMP_IMP] THEN + REWRITE_TAC[AND_FORALL_THM] THEN DISCH_THEN(MP_TAC o SPEC `x:real^M`) THEN + FIRST_X_ASSUM(MP_TAC o GSYM o SPEC `x:real^M`) THEN + ASM_REWRITE_TAC[GSYM BETWEEN_IN_SEGMENT; MIDPOINT_BETWEEN] THEN + MESON_TAC[DIST_SYM]; + ALL_TAC] THEN + DISCH_THEN(MP_TAC o + ISPECL [`\y:real^N. a + r / norm(y - a) % (y - a)`; + `sphere(a:real^N,r)`] o + MATCH_MP (ONCE_REWRITE_RULE[IMP_CONJ] + HOMOTOPIC_COMPOSE_CONTINUOUS_LEFT)) THEN + REWRITE_TAC[o_DEF] THEN ANTS_TAC THENL + [CONJ_TAC THENL + [MATCH_MP_TAC CONTINUOUS_ON_ADD THEN REWRITE_TAC[CONTINUOUS_ON_CONST] THEN + MATCH_MP_TAC CONTINUOUS_ON_MUL THEN + SIMP_TAC[CONTINUOUS_ON_SUB; CONTINUOUS_ON_CONST; CONTINUOUS_ON_ID] THEN + REWRITE_TAC[real_div; o_DEF; LIFT_CMUL] THEN + MATCH_MP_TAC CONTINUOUS_ON_CMUL THEN + MATCH_MP_TAC(REWRITE_RULE[o_DEF] CONTINUOUS_ON_INV) THEN + SIMP_TAC[IN_DELETE; NORM_EQ_0; VECTOR_SUB_EQ] THEN + MATCH_MP_TAC CONTINUOUS_ON_LIFT_NORM_COMPOSE THEN + SIMP_TAC[CONTINUOUS_ON_SUB; CONTINUOUS_ON_CONST; CONTINUOUS_ON_ID]; + SIMP_TAC[SUBSET; FORALL_IN_IMAGE; IN_UNIV; IN_DELETE; IN_SPHERE] THEN + REWRITE_TAC[NORM_ARITH `dist(a:real^N,a + b) = norm b`] THEN + SIMP_TAC[NORM_MUL; REAL_ABS_DIV; REAL_ABS_NORM] THEN + ASM_SIMP_TAC[real_abs; REAL_LE_RMUL; REAL_DIV_RMUL; + NORM_EQ_0; VECTOR_SUB_EQ; REAL_LT_IMP_LE]]; + MATCH_MP_TAC(ONCE_REWRITE_RULE[IMP_CONJ_ALT] HOMOTOPIC_WITH_EQ) THEN + RULE_ASSUM_TAC(REWRITE_RULE[SUBSET; FORALL_IN_IMAGE; IN_SPHERE]) THEN + ASM_SIMP_TAC[NORM_ARITH `norm(a - b:real^N) = dist(b,a)`] THEN + ASM_SIMP_TAC[REAL_DIV_REFL; REAL_LT_IMP_NZ] THEN REPEAT STRIP_TAC THEN + VECTOR_ARITH_TAC]);; + +let HOMOTOPIC_NON_ANTIPODAL_SPHEREMAPS = prove + (`!f g:real^M->real^N s r. + f continuous_on s /\ IMAGE f s SUBSET sphere(vec 0,r) /\ + g continuous_on s /\ IMAGE g s SUBSET sphere(vec 0,r) /\ + (!x. x IN s ==> ~(f x = --g x)) + ==> homotopic_with (\x. T) (s,sphere(vec 0,r)) f g`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC HOMOTOPIC_NON_MIDPOINT_SPHEREMAPS THEN + ASM_REWRITE_TAC[midpoint; VECTOR_ARITH + `inv(&2) % (a + b):real^N = vec 0 <=> a = --b`]);; + +(* ------------------------------------------------------------------------- *) +(* Retracts, in a general sense, preserve (co)homotopic triviality. *) +(* ------------------------------------------------------------------------- *) + +let HOMOTOPICALLY_TRIVIAL_RETRACTION_GEN = prove + (`!P Q s:real^M->bool t:real^N->bool u:real^P->bool h k. + (h continuous_on s /\ IMAGE h s = t /\ + k continuous_on t /\ IMAGE k t SUBSET s /\ + (!y. y IN t ==> h(k y) = y) /\ + (!f. f continuous_on u /\ IMAGE f u SUBSET t /\ Q f ==> P(k o f)) /\ + (!f. f continuous_on u /\ IMAGE f u SUBSET s /\ P f ==> Q(h o f)) /\ + (!h k. (!x. x IN u ==> h x = k x) ==> (Q h <=> Q k))) /\ + (!f g. f continuous_on u /\ IMAGE f u SUBSET s /\ P f /\ + g continuous_on u /\ IMAGE g u SUBSET s /\ P g + ==> homotopic_with P (u,s) f g) + ==> (!f g. f continuous_on u /\ IMAGE f u SUBSET t /\ Q f /\ + g continuous_on u /\ IMAGE g u SUBSET t /\ Q g + ==> homotopic_with Q (u,t) f g)`, + REPEAT GEN_TAC THEN STRIP_TAC THEN + MAP_EVERY X_GEN_TAC [`p:real^P->real^N`; `q:real^P->real^N`] THEN + STRIP_TAC THEN FIRST_X_ASSUM(MP_TAC o SPECL + [`(k:real^N->real^M) o (p:real^P->real^N)`; + `(k:real^N->real^M) o (q:real^P->real^N)`]) THEN + ANTS_TAC THENL + [ASM_SIMP_TAC[IMAGE_o] THEN REPEAT CONJ_TAC THEN + TRY(MATCH_MP_TAC CONTINUOUS_ON_COMPOSE) THEN ASM_REWRITE_TAC[] THEN + TRY(FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET))) THEN + ASM SET_TAC[]; + DISCH_TAC] THEN + MATCH_MP_TAC HOMOTOPIC_WITH_EQ THEN MAP_EVERY EXISTS_TAC + [`(h:real^M->real^N) o (k:real^N->real^M) o (p:real^P->real^N)`; + `(h:real^M->real^N) o (k:real^N->real^M) o (q:real^P->real^N)`] THEN + ASM_REWRITE_TAC[o_THM] THEN CONJ_TAC THENL [ALL_TAC; ASM SET_TAC[]] THEN + MATCH_MP_TAC HOMOTOPIC_WITH_COMPOSE_CONTINUOUS_LEFT THEN + EXISTS_TAC `s:real^M->bool` THEN ASM_REWRITE_TAC[SUBSET_REFL] THEN + FIRST_ASSUM(MATCH_MP_TAC o MATCH_MP (ONCE_REWRITE_RULE[IMP_CONJ] + HOMOTOPIC_WITH_MONO)) THEN + ASM_SIMP_TAC[]);; + +let HOMOTOPICALLY_TRIVIAL_RETRACTION_NULL_GEN = prove + (`!P Q s:real^M->bool t:real^N->bool u:real^P->bool h k. + (h continuous_on s /\ IMAGE h s = t /\ + k continuous_on t /\ IMAGE k t SUBSET s /\ + (!y. y IN t ==> h(k y) = y) /\ + (!f. f continuous_on u /\ IMAGE f u SUBSET t /\ Q f ==> P(k o f)) /\ + (!f. f continuous_on u /\ IMAGE f u SUBSET s /\ P f ==> Q(h o f)) /\ + (!h k. (!x. x IN u ==> h x = k x) ==> (Q h <=> Q k))) /\ + (!f. f continuous_on u /\ IMAGE f u SUBSET s /\ P f + ==> ?c. homotopic_with P (u,s) f (\x. c)) + ==> (!f. f continuous_on u /\ IMAGE f u SUBSET t /\ Q f + ==> ?c. homotopic_with Q (u,t) f (\x. c))`, + REPEAT GEN_TAC THEN STRIP_TAC THEN X_GEN_TAC `p:real^P->real^N` THEN + STRIP_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC + `(k:real^N->real^M) o (p:real^P->real^N)`) THEN + ANTS_TAC THENL + [ASM_SIMP_TAC[IMAGE_o] THEN CONJ_TAC THEN + TRY(MATCH_MP_TAC CONTINUOUS_ON_COMPOSE) THEN ASM_REWRITE_TAC[] THEN + TRY(FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET))) THEN + ASM SET_TAC[]; + DISCH_THEN(X_CHOOSE_TAC `c:real^M`)] THEN + EXISTS_TAC `(h:real^M->real^N) c` THEN + MATCH_MP_TAC HOMOTOPIC_WITH_EQ THEN MAP_EVERY EXISTS_TAC + [`(h:real^M->real^N) o (k:real^N->real^M) o (p:real^P->real^N)`; + `(h:real^M->real^N) o ((\x. c):real^P->real^M)`] THEN + ASM_REWRITE_TAC[o_THM] THEN CONJ_TAC THENL [ALL_TAC; ASM SET_TAC[]] THEN + MATCH_MP_TAC HOMOTOPIC_WITH_COMPOSE_CONTINUOUS_LEFT THEN + EXISTS_TAC `s:real^M->bool` THEN ASM_REWRITE_TAC[SUBSET_REFL] THEN + FIRST_ASSUM(MATCH_MP_TAC o MATCH_MP (ONCE_REWRITE_RULE[IMP_CONJ] + HOMOTOPIC_WITH_MONO)) THEN + ASM_SIMP_TAC[]);; + +let COHOMOTOPICALLY_TRIVIAL_RETRACTION_GEN = prove + (`!P Q s:real^M->bool t:real^N->bool u:real^P->bool h k. + (h continuous_on s /\ IMAGE h s = t /\ + k continuous_on t /\ IMAGE k t SUBSET s /\ + (!y. y IN t ==> h(k y) = y) /\ + (!f. f continuous_on t /\ IMAGE f t SUBSET u /\ Q f ==> P(f o h)) /\ + (!f. f continuous_on s /\ IMAGE f s SUBSET u /\ P f ==> Q(f o k)) /\ + (!h k. (!x. x IN t ==> h x = k x) ==> (Q h <=> Q k))) /\ + (!f g. f continuous_on s /\ IMAGE f s SUBSET u /\ P f /\ + g continuous_on s /\ IMAGE g s SUBSET u /\ P g + ==> homotopic_with P (s,u) f g) + ==> (!f g. f continuous_on t /\ IMAGE f t SUBSET u /\ Q f /\ + g continuous_on t /\ IMAGE g t SUBSET u /\ Q g + ==> homotopic_with Q (t,u) f g)`, + REPEAT GEN_TAC THEN STRIP_TAC THEN + MAP_EVERY X_GEN_TAC [`p:real^N->real^P`; `q:real^N->real^P`] THEN + STRIP_TAC THEN FIRST_X_ASSUM(MP_TAC o SPECL + [`(p:real^N->real^P) o (h:real^M->real^N)`; + `(q:real^N->real^P) o (h:real^M->real^N)`]) THEN + ANTS_TAC THENL + [ASM_SIMP_TAC[IMAGE_o] THEN REPEAT CONJ_TAC THEN + TRY(MATCH_MP_TAC CONTINUOUS_ON_COMPOSE) THEN ASM_REWRITE_TAC[] THEN + TRY(FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET))) THEN + ASM SET_TAC[]; + DISCH_TAC] THEN + MATCH_MP_TAC HOMOTOPIC_WITH_EQ THEN MAP_EVERY EXISTS_TAC + [`((p:real^N->real^P) o (h:real^M->real^N)) o (k:real^N->real^M)`; + `((q:real^N->real^P) o (h:real^M->real^N)) o (k:real^N->real^M)`] THEN + ASM_REWRITE_TAC[o_THM] THEN CONJ_TAC THENL [ALL_TAC; ASM SET_TAC[]] THEN + MATCH_MP_TAC HOMOTOPIC_WITH_COMPOSE_CONTINUOUS_RIGHT THEN + EXISTS_TAC `s:real^M->bool` THEN ASM_REWRITE_TAC[SUBSET_REFL] THEN + FIRST_ASSUM(MATCH_MP_TAC o MATCH_MP (ONCE_REWRITE_RULE[IMP_CONJ] + HOMOTOPIC_WITH_MONO)) THEN + ASM_SIMP_TAC[]);; + +let COHOMOTOPICALLY_TRIVIAL_RETRACTION_NULL_GEN = prove + (`!P Q s:real^M->bool t:real^N->bool u:real^P->bool h k. + (h continuous_on s /\ IMAGE h s = t /\ + k continuous_on t /\ IMAGE k t SUBSET s /\ + (!y. y IN t ==> h(k y) = y) /\ + (!f. f continuous_on t /\ IMAGE f t SUBSET u /\ Q f ==> P(f o h)) /\ + (!f. f continuous_on s /\ IMAGE f s SUBSET u /\ P f ==> Q(f o k)) /\ + (!h k. (!x. x IN t ==> h x = k x) ==> (Q h <=> Q k))) /\ + (!f. f continuous_on s /\ IMAGE f s SUBSET u /\ P f + ==> ?c. homotopic_with P (s,u) f (\x. c)) + ==> (!f. f continuous_on t /\ IMAGE f t SUBSET u /\ Q f + ==> ?c. homotopic_with Q (t,u) f (\x. c))`, + REPEAT GEN_TAC THEN STRIP_TAC THEN X_GEN_TAC `p:real^N->real^P` THEN + STRIP_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC + `(p:real^N->real^P) o (h:real^M->real^N)`) THEN + ANTS_TAC THENL + [ASM_SIMP_TAC[IMAGE_o] THEN + TRY(MATCH_MP_TAC CONTINUOUS_ON_COMPOSE) THEN ASM_REWRITE_TAC[] THEN + TRY(FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET))) THEN + ASM SET_TAC[]; + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `c:real^P` THEN DISCH_TAC] THEN + MATCH_MP_TAC HOMOTOPIC_WITH_EQ THEN MAP_EVERY EXISTS_TAC + [`((p:real^N->real^P) o (h:real^M->real^N)) o (k:real^N->real^M)`; + `((\x. c):real^M->real^P) o (k:real^N->real^M)`] THEN + ASM_REWRITE_TAC[o_THM] THEN CONJ_TAC THENL [ALL_TAC; ASM SET_TAC[]] THEN + MATCH_MP_TAC HOMOTOPIC_WITH_COMPOSE_CONTINUOUS_RIGHT THEN + EXISTS_TAC `s:real^M->bool` THEN ASM_REWRITE_TAC[SUBSET_REFL] THEN + FIRST_ASSUM(MATCH_MP_TAC o MATCH_MP (ONCE_REWRITE_RULE[IMP_CONJ] + HOMOTOPIC_WITH_MONO)) THEN + ASM_SIMP_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* Another useful lemma. *) +(* ------------------------------------------------------------------------- *) + +let HOMOTOPIC_JOIN_SUBPATHS = prove + (`!g:real^1->real^N s. + path g /\ path_image g SUBSET s /\ + u IN interval[vec 0,vec 1] /\ + v IN interval[vec 0,vec 1] /\ + w IN interval[vec 0,vec 1] + ==> homotopic_paths s (subpath u v g ++ subpath v w g) (subpath u w g)`, + let lemma1 = prove + (`!g:real^1->real^N s. + drop u <= drop v /\ drop v <= drop w + ==> path g /\ path_image g SUBSET s /\ + u IN interval[vec 0,vec 1] /\ + v IN interval[vec 0,vec 1] /\ + w IN interval[vec 0,vec 1] /\ + drop u <= drop v /\ drop v <= drop w + ==> homotopic_paths s + (subpath u v g ++ subpath v w g) (subpath u w g)`, + REPEAT STRIP_TAC THEN + MATCH_MP_TAC HOMOTOPIC_PATHS_SUBSET THEN + EXISTS_TAC `path_image g:real^N->bool` THEN ASM_REWRITE_TAC[] THEN + ASM_CASES_TAC `w:real^1 = u` THENL + [MP_TAC(ISPECL + [`path_image g:real^N->bool`; + `subpath u v (g:real^1->real^N)`] HOMOTOPIC_PATHS_RINV) THEN + ASM_REWRITE_TAC[REVERSEPATH_SUBPATH; SUBPATH_REFL] THEN + REWRITE_TAC[LINEPATH_REFL; PATHSTART_SUBPATH] THEN + ASM_SIMP_TAC[PATH_SUBPATH; PATH_IMAGE_SUBPATH_SUBSET]; + ALL_TAC] THEN + ONCE_REWRITE_TAC[HOMOTOPIC_PATHS_SYM] THEN + MATCH_MP_TAC HOMOTOPIC_PATHS_REPARAMETRIZE THEN + ASM_SIMP_TAC[PATH_SUBPATH; PATH_IMAGE_SUBPATH_SUBSET] THEN + EXISTS_TAC + `\t. if drop t <= &1 / &2 + then inv(drop(w - u)) % (&2 * drop(v - u)) % t + else inv(drop(w - u)) % + ((v - u) + drop(w - v) % (&2 % t - vec 1))` THEN + REWRITE_TAC[DROP_VEC] THEN CONV_TAC REAL_RAT_REDUCE_CONV THEN + REWRITE_TAC[VECTOR_MUL_RZERO] THEN REPEAT CONJ_TAC THENL + [MATCH_MP_TAC CONTINUOUS_ON_CASES_1 THEN + REWRITE_TAC[GSYM DROP_EQ; DROP_CMUL; LIFT_DROP; GSYM LIFT_NUM; + DROP_ADD; DROP_SUB] THEN + (CONV_TAC o GEN_SIMPLIFY_CONV TOP_DEPTH_SQCONV (basic_ss []) 5) + [CONTINUOUS_ON_MUL; o_DEF; CONTINUOUS_ON_CONST; CONTINUOUS_ON_ID; + CONTINUOUS_ON_SUB; CONTINUOUS_ON_ADD] THEN + REPEAT STRIP_TAC THEN REAL_ARITH_TAC; + SUBGOAL_THEN `drop u < drop w` ASSUME_TAC THENL + [ASM_SIMP_TAC[REAL_LT_LE; DROP_EQ] THEN ASM_REAL_ARITH_TAC; + ALL_TAC] THEN + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE] THEN + X_GEN_TAC `t:real^1` THEN STRIP_TAC THEN COND_CASES_TAC THEN + REWRITE_TAC[IN_INTERVAL_1; DROP_CMUL; DROP_VEC; DROP_ADD; DROP_SUB] THEN + ONCE_REWRITE_TAC[ONCE_REWRITE_RULE[REAL_MUL_SYM] (GSYM real_div)] THEN + ASM_SIMP_TAC[REAL_LE_LDIV_EQ; REAL_LE_RDIV_EQ; REAL_SUB_LT] THEN + REWRITE_TAC[REAL_MUL_LZERO; REAL_MUL_LID] THEN + RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1; DROP_VEC]) THEN + (CONJ_TAC THENL + [REPEAT(MATCH_MP_TAC REAL_LE_ADD THEN CONJ_TAC) THEN + REPEAT(MATCH_MP_TAC REAL_LE_MUL THEN CONJ_TAC) THEN + ASM_REAL_ARITH_TAC; + ALL_TAC]) THEN + REWRITE_TAC[REAL_ARITH `v - u + x * t <= w - u <=> x * t <= w - v`; + REAL_ARITH `(&2 * x) * t = x * &2 * t`] THEN + MATCH_MP_TAC(REAL_ARITH `a * t <= a * &1 /\ a <= b ==> a * t <= b`) THEN + (CONJ_TAC THENL [MATCH_MP_TAC REAL_LE_LMUL; ALL_TAC]) THEN + ASM_REAL_ARITH_TAC; + REWRITE_TAC[GSYM DROP_EQ; DROP_VEC; DROP_ADD; DROP_CMUL; DROP_SUB] THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN + REWRITE_TAC[REAL_ARITH `(v - u) + (w - v) * &1 = w - u`] THEN + ASM_SIMP_TAC[REAL_SUB_0; DROP_EQ; REAL_MUL_LINV]; + X_GEN_TAC `t:real^1` THEN DISCH_TAC THEN + REWRITE_TAC[subpath; joinpaths] THEN COND_CASES_TAC THEN + ASM_SIMP_TAC[VECTOR_MUL_ASSOC; REAL_MUL_ASSOC] THEN + ASM_SIMP_TAC[REAL_MUL_RINV; DROP_EQ_0; VECTOR_SUB_EQ] THEN + AP_TERM_TAC THEN + REWRITE_TAC[GSYM DROP_EQ; DROP_VEC; DROP_ADD; DROP_CMUL; DROP_SUB] THEN + REAL_ARITH_TAC]) in + let lemma2 = prove + (`path g /\ path_image g SUBSET s /\ + u IN interval[vec 0,vec 1] /\ + v IN interval[vec 0,vec 1] /\ + w IN interval[vec 0,vec 1] /\ + homotopic_paths s (subpath u v g ++ subpath v w g) (subpath u w g) + ==> homotopic_paths s (subpath w v g ++ subpath v u g) (subpath w u g)`, + REPEAT STRIP_TAC THEN + ONCE_REWRITE_TAC[GSYM HOMOTOPIC_PATHS_REVERSEPATH] THEN + SIMP_TAC[REVERSEPATH_JOINPATHS; PATHSTART_SUBPATH; PATHFINISH_SUBPATH] THEN + ASM_REWRITE_TAC[REVERSEPATH_SUBPATH]) in + let lemma3 = prove + (`path (g:real^1->real^N) /\ path_image g SUBSET s /\ + u IN interval[vec 0,vec 1] /\ + v IN interval[vec 0,vec 1] /\ + w IN interval[vec 0,vec 1] /\ + homotopic_paths s (subpath u v g ++ subpath v w g) (subpath u w g) + ==> homotopic_paths s (subpath v w g ++ subpath w u g) (subpath v u g)`, + let tac = + ASM_MESON_TAC[PATHSTART_SUBPATH; PATHFINISH_SUBPATH; PATH_SUBPATH; + HOMOTOPIC_PATHS_REFL; PATH_IMAGE_SUBPATH_SUBSET; SUBSET_TRANS; + PATHSTART_JOIN; PATHFINISH_JOIN] in + REPEAT STRIP_TAC THEN + ONCE_REWRITE_TAC[GSYM HOMOTOPIC_PATHS_REVERSEPATH] THEN + SIMP_TAC[REVERSEPATH_JOINPATHS; PATHSTART_SUBPATH; PATHFINISH_SUBPATH] THEN + ASM_REWRITE_TAC[REVERSEPATH_SUBPATH] THEN + MATCH_MP_TAC HOMOTOPIC_PATHS_TRANS THEN + EXISTS_TAC + `(subpath u v g ++ subpath v w g) ++ subpath w v g:real^1->real^N` THEN + CONJ_TAC THENL + [MATCH_MP_TAC HOMOTOPIC_PATHS_JOIN THEN + ONCE_REWRITE_TAC[HOMOTOPIC_PATHS_SYM] THEN + ASM_REWRITE_TAC[HOMOTOPIC_PATHS_REFL] THEN tac; + ALL_TAC] THEN + MATCH_MP_TAC HOMOTOPIC_PATHS_TRANS THEN + EXISTS_TAC + `subpath u v g ++ (subpath v w g ++ subpath w v g):real^1->real^N` THEN + CONJ_TAC THENL + [ONCE_REWRITE_TAC[HOMOTOPIC_PATHS_SYM] THEN + MATCH_MP_TAC HOMOTOPIC_PATHS_ASSOC THEN tac; + ALL_TAC] THEN + MATCH_MP_TAC HOMOTOPIC_PATHS_TRANS THEN + EXISTS_TAC + `(subpath u v g :real^1->real^N) ++ + linepath(pathfinish(subpath u v g),pathfinish(subpath u v g))` THEN + CONJ_TAC THENL [ALL_TAC; MATCH_MP_TAC HOMOTOPIC_PATHS_RID THEN tac] THEN + MATCH_MP_TAC HOMOTOPIC_PATHS_JOIN THEN + REPEAT CONJ_TAC THENL [tac; ALL_TAC; tac] THEN + MATCH_MP_TAC HOMOTOPIC_PATHS_TRANS THEN + EXISTS_TAC + `linepath(pathstart(subpath v w g):real^N,pathstart(subpath v w g))` THEN + CONJ_TAC THENL + [GEN_REWRITE_TAC (LAND_CONV o RAND_CONV) [GSYM REVERSEPATH_SUBPATH] THEN + MATCH_MP_TAC HOMOTOPIC_PATHS_RINV THEN tac; + ALL_TAC] THEN + REWRITE_TAC[PATHSTART_SUBPATH; PATHFINISH_SUBPATH; HOMOTOPIC_PATHS_REFL; + PATH_LINEPATH; PATH_IMAGE_LINEPATH; SEGMENT_REFL; + INSERT_SUBSET; EMPTY_SUBSET] THEN + ASM_MESON_TAC[path_image; IN_IMAGE; SUBSET]) in + REPEAT STRIP_TAC THEN + REPEAT_TCL DISJ_CASES_THEN ASSUME_TAC + (REAL_ARITH `(drop u <= drop v /\ drop v <= drop w \/ + drop w <= drop v /\ drop v <= drop u) \/ + (drop u <= drop w /\ drop w <= drop v \/ + drop v <= drop w /\ drop w <= drop u) \/ + (drop v <= drop u /\ drop u <= drop w \/ + drop w <= drop u /\ drop u <= drop v)`) THEN + FIRST_ASSUM(MP_TAC o SPECL [`g:real^1->real^N`; `s:real^N->bool`] o + MATCH_MP lemma1) THEN + ASM_MESON_TAC[lemma2; lemma3]);; + +let HOMOTOPIC_LOOPS_SHIFTPATH = prove + (`!s:real^N->bool p q u. + homotopic_loops s p q /\ u IN interval[vec 0,vec 1] + ==> homotopic_loops s (shiftpath u p) (shiftpath u q)`, + REPEAT GEN_TAC THEN REWRITE_TAC[homotopic_loops; homotopic_with; PCROSS] THEN + DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN DISCH_THEN( + (X_CHOOSE_THEN `h:real^(1,1)finite_sum->real^N` STRIP_ASSUME_TAC)) THEN + EXISTS_TAC + `\z. shiftpath u (\t. (h:real^(1,1)finite_sum->real^N) + (pastecart (fstcart z) t)) (sndcart z)` THEN + ASM_REWRITE_TAC[FSTCART_PASTECART; SNDCART_PASTECART; ETA_AX] THEN + ASM_SIMP_TAC[CLOSED_SHIFTPATH] THEN CONJ_TAC THENL + [REWRITE_TAC[shiftpath; DROP_ADD; REAL_ARITH + `u + z <= &1 <=> z <= &1 - u`] THEN + SUBGOAL_THEN + `{ pastecart (t:real^1) (x:real^1) | + t IN interval[vec 0,vec 1] /\ x IN interval[vec 0,vec 1]} = + { pastecart (t:real^1) (x:real^1) | + t IN interval[vec 0,vec 1] /\ x IN interval[vec 0,vec 1 - u]} UNION + { pastecart (t:real^1) (x:real^1) | + t IN interval[vec 0,vec 1] /\ x IN interval[vec 1 - u,vec 1]}` + SUBST1_TAC THENL + [MATCH_MP_TAC(SET_RULE `s UNION s' = u + ==> {f t x | t IN i /\ x IN u} = + {f t x | t IN i /\ x IN s} UNION + {f t x | t IN i /\ x IN s'}`) THEN + UNDISCH_TAC `(u:real^1) IN interval[vec 0,vec 1]` THEN + REWRITE_TAC[EXTENSION; IN_INTERVAL_1; IN_UNION; DROP_SUB; DROP_VEC] THEN + REAL_ARITH_TAC; + ALL_TAC] THEN + MATCH_MP_TAC CONTINUOUS_ON_CASES THEN + SIMP_TAC[REWRITE_RULE[PCROSS] CLOSED_PCROSS; CLOSED_INTERVAL] THEN + REWRITE_TAC[FORALL_AND_THM; FORALL_IN_GSPEC; TAUT + `p /\ q \/ r /\ s ==> t <=> (p ==> q ==> t) /\ (r ==> s ==> t)`] THEN + SIMP_TAC[SNDCART_PASTECART; IN_INTERVAL_1; DROP_SUB; DROP_VEC] THEN + SIMP_TAC[REAL_ARITH `&1 - u <= x ==> (x <= &1 - u <=> x = &1 - u)`] THEN + SIMP_TAC[GSYM LIFT_EQ; LIFT_SUB; LIFT_DROP; LIFT_NUM] THEN + REWRITE_TAC[FSTCART_PASTECART; VECTOR_ARITH `u + v - u:real^N = v`; + VECTOR_ARITH `u + v - u - v:real^N = vec 0`] THEN + RULE_ASSUM_TAC(REWRITE_RULE[pathstart; pathfinish]) THEN + ASM_SIMP_TAC[GSYM IN_INTERVAL_1; GSYM DROP_VEC] THEN CONJ_TAC THEN + GEN_REWRITE_TAC LAND_CONV [GSYM o_DEF] THEN + MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN + SIMP_TAC[CONTINUOUS_ON_PASTECART; CONTINUOUS_ON_ADD; CONTINUOUS_ON_CONST; + LINEAR_CONTINUOUS_ON; LINEAR_FSTCART; LINEAR_SNDCART; + VECTOR_ARITH `u + z - v:real^N = (u - v) + z`] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET)) THEN + UNDISCH_TAC `(u:real^1) IN interval[vec 0,vec 1]` THEN + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; FORALL_IN_GSPEC] THEN + REWRITE_TAC[FSTCART_PASTECART; SNDCART_PASTECART; IN_INTERVAL_1; + IN_ELIM_PASTECART_THM; DROP_ADD; DROP_SUB; DROP_VEC] THEN + REAL_ARITH_TAC; + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; FORALL_IN_GSPEC] THEN + REWRITE_TAC[FSTCART_PASTECART; SNDCART_PASTECART; SET_RULE + `(!t x. t IN i /\ x IN i ==> f t x IN s) <=> + (!t. t IN i ==> IMAGE (f t) i SUBSET s)`] THEN + X_GEN_TAC `t:real^1` THEN STRIP_TAC THEN REWRITE_TAC[GSYM path_image] THEN + ASM_SIMP_TAC[PATH_IMAGE_SHIFTPATH; ETA_AX] THEN + REWRITE_TAC[path_image] THEN ASM SET_TAC[]]);; + +let HOMOTOPIC_PATHS_LOOP_PARTS = prove + (`!s p q a:real^N. + homotopic_loops s (p ++ reversepath q) (linepath(a,a)) /\ path q + ==> homotopic_paths s p q`, + REPEAT STRIP_TAC THEN FIRST_X_ASSUM(MP_TAC o + MATCH_MP HOMOTOPIC_LOOPS_IMP_HOMOTOPIC_PATHS_NULL) THEN + REWRITE_TAC[PATHSTART_JOIN] THEN STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o CONJUNCT1 o MATCH_MP HOMOTOPIC_PATHS_IMP_PATH) THEN + ASM_CASES_TAC `pathfinish p:real^N = pathstart(reversepath q)` THENL + [ASM_SIMP_TAC[PATH_JOIN; PATH_REVERSEPATH] THEN STRIP_TAC; + ASM_MESON_TAC[PATH_JOIN_PATH_ENDS; PATH_REVERSEPATH]] THEN + RULE_ASSUM_TAC(REWRITE_RULE[PATHSTART_REVERSEPATH]) THEN + FIRST_ASSUM(MP_TAC o MATCH_MP HOMOTOPIC_PATHS_IMP_SUBSET) THEN + ASM_SIMP_TAC[PATH_IMAGE_JOIN; PATHSTART_JOIN; PATHFINISH_JOIN; + PATHSTART_REVERSEPATH; PATHFINISH_REVERSEPATH; UNION_SUBSET; SING_SUBSET; + PATH_IMAGE_REVERSEPATH; PATH_IMAGE_LINEPATH; SEGMENT_REFL] THEN + STRIP_TAC THEN + MATCH_MP_TAC HOMOTOPIC_PATHS_TRANS THEN + EXISTS_TAC `p ++ (linepath(pathfinish p:real^N,pathfinish p))` THEN + CONJ_TAC THENL + [ONCE_REWRITE_TAC[HOMOTOPIC_PATHS_SYM] THEN + MATCH_MP_TAC HOMOTOPIC_PATHS_RID THEN ASM_REWRITE_TAC[]; + ALL_TAC] THEN + MATCH_MP_TAC HOMOTOPIC_PATHS_TRANS THEN + EXISTS_TAC `p ++ (reversepath q ++ q):real^1->real^N` THEN CONJ_TAC THENL + [ONCE_REWRITE_TAC[HOMOTOPIC_PATHS_SYM] THEN + MATCH_MP_TAC HOMOTOPIC_PATHS_JOIN THEN + ASM_SIMP_TAC[HOMOTOPIC_PATHS_LINV; PATHSTART_JOIN; PATHSTART_REVERSEPATH; + HOMOTOPIC_PATHS_REFL]; + ALL_TAC] THEN + MATCH_MP_TAC HOMOTOPIC_PATHS_TRANS THEN + EXISTS_TAC `(p ++ reversepath q) ++ q:real^1->real^N` THEN CONJ_TAC THENL + [MATCH_MP_TAC HOMOTOPIC_PATHS_ASSOC THEN + ASM_REWRITE_TAC[PATHSTART_REVERSEPATH; PATHFINISH_REVERSEPATH; + PATH_IMAGE_REVERSEPATH; PATH_REVERSEPATH]; + ALL_TAC] THEN + MATCH_MP_TAC HOMOTOPIC_PATHS_TRANS THEN + EXISTS_TAC `linepath(pathstart p:real^N,pathstart p) ++ q` THEN + CONJ_TAC THENL + [MATCH_MP_TAC HOMOTOPIC_PATHS_JOIN THEN + ASM_REWRITE_TAC[HOMOTOPIC_PATHS_REFL] THEN + REWRITE_TAC[PATHFINISH_JOIN; PATHFINISH_REVERSEPATH]; + FIRST_ASSUM(MP_TAC o MATCH_MP HOMOTOPIC_PATHS_IMP_PATHFINISH) THEN + REWRITE_TAC[PATHFINISH_JOIN; PATHFINISH_LINEPATH; + PATHFINISH_REVERSEPATH] THEN + DISCH_THEN(SUBST1_TAC o SYM) THEN + MATCH_MP_TAC HOMOTOPIC_PATHS_LID THEN ASM_REWRITE_TAC[]]);; + +let HOMOTOPIC_LOOPS_ADD_SYM = prove + (`!p q:real^1->real^N. + path p /\ path_image p SUBSET s /\ pathfinish p = pathstart p /\ + path q /\ path_image q SUBSET s /\ pathfinish q = pathstart q /\ + pathstart q = pathstart p + ==> homotopic_loops s (p ++ q) (q ++ p)`, + REPEAT STRIP_TAC THEN + MATCH_MP_TAC HOMOTOPIC_LOOPS_TRANS THEN + SUBGOAL_THEN `lift(&1 / &2) IN interval[vec 0,vec 1]` ASSUME_TAC THENL + [REWRITE_TAC[IN_INTERVAL_1; DROP_VEC; LIFT_DROP] THEN + CONV_TAC REAL_RAT_REDUCE_CONV; + ALL_TAC] THEN + EXISTS_TAC `shiftpath (lift(&1 / &2)) (p ++ q:real^1->real^N)` THEN + CONJ_TAC THENL + [MATCH_MP_TAC HOMOTOPIC_LOOPS_SHIFTPATH_SELF; + MATCH_MP_TAC HOMOTOPIC_LOOPS_EQ] THEN + ASM_SIMP_TAC[PATH_JOIN; PATH_IMAGE_JOIN; PATHSTART_JOIN; PATHFINISH_JOIN; + UNION_SUBSET; IN_INTERVAL_1; DROP_VEC; LIFT_DROP; + PATH_SHIFTPATH; PATH_IMAGE_SHIFTPATH; CLOSED_SHIFTPATH] THEN + SIMP_TAC[shiftpath; joinpaths; LIFT_DROP; DROP_ADD; DROP_SUB; DROP_VEC; + REAL_ARITH `&0 <= t ==> (a + t <= a <=> t = &0)`; + REAL_ARITH `t <= &1 ==> &1 / &2 + t - &1 <= &1 / &2`; + REAL_ARITH `&1 / &2 + t <= &1 <=> t <= &1 / &2`] THEN + X_GEN_TAC `t:real^1` THEN STRIP_TAC THEN + ASM_CASES_TAC `drop t <= &1 / &2` THEN ASM_REWRITE_TAC[] THENL + [REWRITE_TAC[GSYM LIFT_EQ; LIFT_NUM; LIFT_DROP] THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[VECTOR_ADD_RID] THENL + [REWRITE_TAC[GSYM LIFT_CMUL; VECTOR_MUL_RZERO] THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN + ASM_MESON_TAC[LIFT_NUM; pathstart; pathfinish]; + ALL_TAC]; + ALL_TAC] THEN + AP_TERM_TAC THEN + REWRITE_TAC[GSYM DROP_EQ; DROP_SUB; DROP_ADD; DROP_VEC; DROP_CMUL; + LIFT_DROP] THEN REAL_ARITH_TAC);; + +(* ------------------------------------------------------------------------- *) +(* Simply connected sets defined as "all loops are homotopic (as loops)". *) +(* ------------------------------------------------------------------------- *) + +let simply_connected = new_definition + `simply_connected(s:real^N->bool) <=> + !p q. path p /\ pathfinish p = pathstart p /\ path_image p SUBSET s /\ + path q /\ pathfinish q = pathstart q /\ path_image q SUBSET s + ==> homotopic_loops s p q`;; + +let SIMPLY_CONNECTED_EMPTY = prove + (`simply_connected {}`, + REWRITE_TAC[simply_connected; SUBSET_EMPTY] THEN + MESON_TAC[PATH_IMAGE_NONEMPTY]);; + +let SIMPLY_CONNECTED_IMP_PATH_CONNECTED = prove + (`!s:real^N->bool. simply_connected s ==> path_connected s`, + REWRITE_TAC[simply_connected; PATH_CONNECTED_EQ_HOMOTOPIC_POINTS] THEN + REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_REWRITE_TAC[PATH_LINEPATH; PATHSTART_LINEPATH; PATHFINISH_LINEPATH; + PATH_IMAGE_LINEPATH; SEGMENT_REFL] THEN + ASM SET_TAC[]);; + +let SIMPLY_CONNECTED_IMP_CONNECTED = prove + (`!s:real^N->bool. simply_connected s ==> connected s`, + SIMP_TAC[SIMPLY_CONNECTED_IMP_PATH_CONNECTED; + PATH_CONNECTED_IMP_CONNECTED]);; + +let SIMPLY_CONNECTED_EQ_CONTRACTIBLE_LOOP_ANY = prove + (`!s:real^N->bool. + simply_connected s <=> + !p a. path p /\ path_image p SUBSET s /\ + pathfinish p = pathstart p /\ a IN s + ==> homotopic_loops s p (linepath(a,a))`, + GEN_TAC THEN REWRITE_TAC[simply_connected] THEN EQ_TAC THEN DISCH_TAC THENL + [REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_SIMP_TAC[PATH_LINEPATH; PATHSTART_LINEPATH; PATHFINISH_LINEPATH] THEN + ASM_REWRITE_TAC[PATH_IMAGE_LINEPATH; SEGMENT_REFL; SING_SUBSET]; + MAP_EVERY X_GEN_TAC [`p:real^1->real^N`; `q:real^1->real^N`] THEN + STRIP_TAC THEN MATCH_MP_TAC HOMOTOPIC_LOOPS_TRANS THEN + EXISTS_TAC `linepath(pathstart p:real^N,pathstart p)` THEN + CONJ_TAC THENL [ALL_TAC; ONCE_REWRITE_TAC[HOMOTOPIC_LOOPS_SYM]] THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[] THEN + ASM_MESON_TAC[PATHSTART_IN_PATH_IMAGE; SUBSET]]);; + +let SIMPLY_CONNECTED_EQ_CONTRACTIBLE_LOOP_SOME = prove + (`!s:real^N->bool. + simply_connected s <=> + path_connected s /\ + !p. path p /\ path_image p SUBSET s /\ pathfinish p = pathstart p + ==> ?a. a IN s /\ homotopic_loops s p (linepath(a,a))`, + GEN_TAC THEN EQ_TAC THEN STRIP_TAC THEN + ASM_SIMP_TAC[SIMPLY_CONNECTED_IMP_PATH_CONNECTED] THENL + [FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I + [SIMPLY_CONNECTED_EQ_CONTRACTIBLE_LOOP_ANY]) THEN + MESON_TAC[SUBSET; PATHSTART_IN_PATH_IMAGE]; + REWRITE_TAC[SIMPLY_CONNECTED_EQ_CONTRACTIBLE_LOOP_ANY] THEN + MAP_EVERY X_GEN_TAC [`p:real^1->real^N`; `a:real^N`] THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `p:real^1->real^N`) THEN + ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN X_GEN_TAC `b:real^N` THEN + STRIP_TAC THEN MATCH_MP_TAC HOMOTOPIC_LOOPS_TRANS THEN + EXISTS_TAC `linepath(b:real^N,b)` THEN + ASM_REWRITE_TAC[HOMOTOPIC_POINTS_EQ_PATH_COMPONENT] THEN + ASM_MESON_TAC[PATH_CONNECTED_IFF_PATH_COMPONENT]]);; + +let SIMPLY_CONNECTED_EQ_CONTRACTIBLE_LOOP_ALL = prove + (`!s:real^N->bool. + simply_connected s <=> + s = {} \/ + ?a. a IN s /\ + !p. path p /\ path_image p SUBSET s /\ pathfinish p = pathstart p + ==> homotopic_loops s p (linepath(a,a))`, + GEN_TAC THEN ASM_CASES_TAC `s:real^N->bool = {}` THEN + ASM_REWRITE_TAC[SIMPLY_CONNECTED_EMPTY] THEN + REWRITE_TAC[SIMPLY_CONNECTED_EQ_CONTRACTIBLE_LOOP_SOME] THEN + EQ_TAC THENL + [STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `a:real^N` THEN STRIP_TAC THEN + ASM_REWRITE_TAC[] THEN X_GEN_TAC `p:real^1->real^N` THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `p:real^1->real^N`) THEN + ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN X_GEN_TAC `b:real^N` THEN + STRIP_TAC THEN MATCH_MP_TAC HOMOTOPIC_LOOPS_TRANS THEN + EXISTS_TAC `linepath(b:real^N,b)` THEN + ASM_REWRITE_TAC[HOMOTOPIC_POINTS_EQ_PATH_COMPONENT] THEN + ASM_MESON_TAC[PATH_CONNECTED_IFF_PATH_COMPONENT]; + DISCH_THEN(X_CHOOSE_THEN `a:real^N` STRIP_ASSUME_TAC) THEN + CONJ_TAC THENL [ALL_TAC; ASM_MESON_TAC[]] THEN + REWRITE_TAC[PATH_CONNECTED_EQ_HOMOTOPIC_POINTS] THEN + MAP_EVERY X_GEN_TAC [`b:real^N`; `c:real^N`] THEN STRIP_TAC THEN + MATCH_MP_TAC HOMOTOPIC_LOOPS_TRANS THEN + EXISTS_TAC `linepath(a:real^N,a)` THEN + GEN_REWRITE_TAC RAND_CONV [HOMOTOPIC_LOOPS_SYM] THEN + CONJ_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + REWRITE_TAC[PATH_LINEPATH; PATH_IMAGE_LINEPATH; SEGMENT_REFL; + PATHSTART_LINEPATH; PATHFINISH_LINEPATH] THEN + ASM SET_TAC[]]);; + +let SIMPLY_CONNECTED_EQ_CONTRACTIBLE_PATH = prove + (`!s:real^N->bool. + simply_connected s <=> + path_connected s /\ + !p. path p /\ path_image p SUBSET s /\ pathfinish p = pathstart p + ==> homotopic_paths s p (linepath(pathstart p,pathstart p))`, + GEN_TAC THEN EQ_TAC THEN STRIP_TAC THENL + [ASM_SIMP_TAC[SIMPLY_CONNECTED_IMP_PATH_CONNECTED] THEN + REPEAT STRIP_TAC THEN + MATCH_MP_TAC HOMOTOPIC_LOOPS_IMP_HOMOTOPIC_PATHS_NULL THEN + EXISTS_TAC `pathstart p :real^N` THEN + FIRST_X_ASSUM(MATCH_MP_TAC o + REWRITE_RULE[SIMPLY_CONNECTED_EQ_CONTRACTIBLE_LOOP_ANY]) THEN + ASM_MESON_TAC[PATHSTART_IN_PATH_IMAGE; SUBSET]; + REWRITE_TAC[SIMPLY_CONNECTED_EQ_CONTRACTIBLE_LOOP_ANY] THEN + MAP_EVERY X_GEN_TAC [`p:real^1->real^N`; `a:real^N`] THEN + STRIP_TAC THEN MATCH_MP_TAC HOMOTOPIC_LOOPS_TRANS THEN + EXISTS_TAC `linepath(pathstart p:real^N,pathfinish p)` THEN + CONJ_TAC THENL + [MATCH_MP_TAC HOMOTOPIC_PATHS_IMP_HOMOTOPIC_LOOPS THEN + ASM_SIMP_TAC[PATHFINISH_LINEPATH]; + ASM_REWRITE_TAC[HOMOTOPIC_POINTS_EQ_PATH_COMPONENT] THEN + RULE_ASSUM_TAC(REWRITE_RULE[PATH_CONNECTED_IFF_PATH_COMPONENT]) THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_MESON_TAC[PATHSTART_IN_PATH_IMAGE; SUBSET]]]);; + +let SIMPLY_CONNECTED_EQ_HOMOTOPIC_PATHS = prove + (`!s:real^N->bool. + simply_connected s <=> + path_connected s /\ + !p q. path p /\ path_image p SUBSET s /\ + path q /\ path_image q SUBSET s /\ + pathstart q = pathstart p /\ pathfinish q = pathfinish p + ==> homotopic_paths s p q`, + REPEAT GEN_TAC THEN REWRITE_TAC[SIMPLY_CONNECTED_EQ_CONTRACTIBLE_PATH] THEN + EQ_TAC THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + X_GEN_TAC `p:real^1->real^N` THENL + [X_GEN_TAC `q:real^1->real^N` THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `p ++ reversepath q :real^1->real^N`) THEN + ASM_SIMP_TAC[PATH_JOIN; PATHSTART_REVERSEPATH; PATH_REVERSEPATH; + PATHSTART_JOIN; PATHFINISH_JOIN; PATHFINISH_REVERSEPATH; + PATH_IMAGE_JOIN; UNION_SUBSET; PATH_IMAGE_REVERSEPATH] THEN + DISCH_TAC THEN + MATCH_MP_TAC HOMOTOPIC_PATHS_TRANS THEN + EXISTS_TAC `p ++ linepath(pathfinish p,pathfinish p):real^1->real^N` THEN + GEN_REWRITE_TAC LAND_CONV [HOMOTOPIC_PATHS_SYM] THEN + ASM_SIMP_TAC[HOMOTOPIC_PATHS_RID] THEN + MATCH_MP_TAC HOMOTOPIC_PATHS_TRANS THEN + EXISTS_TAC `p ++ (reversepath q ++ q):real^1->real^N` THEN + CONJ_TAC THENL + [MATCH_MP_TAC HOMOTOPIC_PATHS_JOIN THEN + ASM_REWRITE_TAC[HOMOTOPIC_PATHS_REFL; PATHSTART_LINEPATH] THEN + ASM_MESON_TAC[HOMOTOPIC_PATHS_LINV; HOMOTOPIC_PATHS_SYM]; + ALL_TAC] THEN + MATCH_MP_TAC HOMOTOPIC_PATHS_TRANS THEN + EXISTS_TAC `(p ++ reversepath q) ++ q:real^1->real^N` THEN + CONJ_TAC THENL + [MATCH_MP_TAC HOMOTOPIC_PATHS_ASSOC THEN + ASM_SIMP_TAC[PATH_REVERSEPATH; PATH_IMAGE_REVERSEPATH] THEN + ASM_REWRITE_TAC[PATHSTART_REVERSEPATH; PATHFINISH_REVERSEPATH]; + ALL_TAC] THEN + MATCH_MP_TAC HOMOTOPIC_PATHS_TRANS THEN + EXISTS_TAC `linepath(pathstart q,pathstart q) ++ q:real^1->real^N` THEN + CONJ_TAC THENL + [MATCH_MP_TAC HOMOTOPIC_PATHS_JOIN THEN + ASM_SIMP_TAC[HOMOTOPIC_PATHS_RINV; HOMOTOPIC_PATHS_REFL] THEN + ASM_REWRITE_TAC[PATHFINISH_JOIN; PATHFINISH_REVERSEPATH]; + ASM_MESON_TAC[HOMOTOPIC_PATHS_LID]]; + STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_SIMP_TAC[PATHSTART_LINEPATH; PATHFINISH_LINEPATH; PATH_LINEPATH] THEN + REWRITE_TAC[PATH_IMAGE_LINEPATH; SEGMENT_REFL; SING_SUBSET] THEN + ASM_MESON_TAC[PATHSTART_IN_PATH_IMAGE; SUBSET]]);; + +let SIMPLY_CONNECTED_RETRACTION_GEN = prove + (`!s:real^M->bool t:real^N->bool h k. + h continuous_on s /\ IMAGE h s = t /\ + k continuous_on t /\ IMAGE k t SUBSET s /\ + (!y. y IN t ==> h(k y) = y) /\ + simply_connected s + ==> simply_connected t`, + REPEAT GEN_TAC THEN + REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + REWRITE_TAC[simply_connected; path; path_image; homotopic_loops] THEN + ONCE_REWRITE_TAC[TAUT + `a /\ b /\ c /\ a' /\ b' /\ c' <=> a /\ c /\ b /\ a' /\ c' /\ b'`] THEN + MATCH_MP_TAC(ONCE_REWRITE_RULE[IMP_CONJ] + HOMOTOPICALLY_TRIVIAL_RETRACTION_GEN) THEN + MAP_EVERY EXISTS_TAC [`h:real^M->real^N`; `k:real^N->real^M`] THEN + ASM_SIMP_TAC[PATHSTART_COMPOSE; PATHFINISH_COMPOSE] THEN + REWRITE_TAC[pathfinish; pathstart] THEN MESON_TAC[ENDS_IN_UNIT_INTERVAL]);; + +let HOMEOMORPHIC_SIMPLY_CONNECTED = prove + (`!s:real^M->bool t:real^N->bool. + s homeomorphic t /\ simply_connected s + ==> simply_connected t`, + REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + MATCH_MP_TAC(ONCE_REWRITE_RULE[IMP_CONJ] + (REWRITE_RULE[CONJ_ASSOC] SIMPLY_CONNECTED_RETRACTION_GEN)) THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [homeomorphic]) THEN + REPEAT(MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC) THEN + SIMP_TAC[homeomorphism; SUBSET_REFL]);; + +let HOMEOMORPHIC_SIMPLY_CONNECTED_EQ = prove + (`!s:real^M->bool t:real^N->bool. + s homeomorphic t + ==> (simply_connected s <=> simply_connected t)`, + REPEAT STRIP_TAC THEN EQ_TAC THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] HOMEOMORPHIC_SIMPLY_CONNECTED) THEN + ASM_REWRITE_TAC[] THEN ONCE_REWRITE_TAC[HOMEOMORPHIC_SYM] THEN + ASM_REWRITE_TAC[]);; + +let SIMPLY_CONNECTED_TRANSLATION = prove + (`!a:real^N s. simply_connected (IMAGE (\x. a + x) s) <=> simply_connected s`, + REPEAT GEN_TAC THEN MATCH_MP_TAC HOMEOMORPHIC_SIMPLY_CONNECTED_EQ THEN + ONCE_REWRITE_TAC[HOMEOMORPHIC_SYM] THEN + REWRITE_TAC[HOMEOMORPHIC_TRANSLATION]);; + +add_translation_invariants [SIMPLY_CONNECTED_TRANSLATION];; + +let SIMPLY_CONNECTED_INJECTIVE_LINEAR_IMAGE = prove + (`!f:real^M->real^N s. + linear f /\ (!x y. f x = f y ==> x = y) + ==> (simply_connected (IMAGE f s) <=> simply_connected s)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC HOMEOMORPHIC_SIMPLY_CONNECTED_EQ THEN + ASM_MESON_TAC[HOMEOMORPHIC_INJECTIVE_LINEAR_IMAGE_LEFT_EQ; + HOMEOMORPHIC_REFL]);; + +add_linear_invariants [SIMPLY_CONNECTED_INJECTIVE_LINEAR_IMAGE];; + +let SIMPLY_CONNECTED_PCROSS = prove + (`!s:real^M->bool t:real^N->bool. + simply_connected s /\ simply_connected t + ==> simply_connected(s PCROSS t)`, + REPEAT GEN_TAC THEN + REWRITE_TAC[SIMPLY_CONNECTED_EQ_CONTRACTIBLE_LOOP_ANY] THEN + REWRITE_TAC[path; path_image; pathstart; pathfinish; FORALL_PASTECART] THEN + DISCH_TAC THEN + MAP_EVERY X_GEN_TAC + [`p:real^1->real^(M,N)finite_sum`; `a:real^M`; `b:real^N`] THEN + REWRITE_TAC[PASTECART_IN_PCROSS; FORALL_IN_IMAGE; SUBSET] THEN STRIP_TAC THEN + FIRST_X_ASSUM(CONJUNCTS_THEN2 + (MP_TAC o SPECL [`fstcart o (p:real^1->real^(M,N)finite_sum)`; `a:real^M`]) + (MP_TAC o SPECL [`sndcart o (p:real^1->real^(M,N)finite_sum)`; + `b:real^N`])) THEN + ASM_SIMP_TAC[CONTINUOUS_ON_COMPOSE; LINEAR_FSTCART; LINEAR_SNDCART; + LINEAR_CONTINUOUS_ON; homotopic_loops; homotopic_with; + pathfinish; pathstart; IMAGE_o; o_THM] THEN + ASM_SIMP_TAC[SUBSET; FORALL_IN_IMAGE] THEN ANTS_TAC THENL + [RULE_ASSUM_TAC(REWRITE_RULE[PCROSS; IN_ELIM_THM]) THEN + ASM_MESON_TAC[SNDCART_PASTECART]; + DISCH_THEN(X_CHOOSE_THEN + `k:real^(1,1)finite_sum->real^N` STRIP_ASSUME_TAC)] THEN + ANTS_TAC THENL + [RULE_ASSUM_TAC(REWRITE_RULE[PCROSS; IN_ELIM_THM]) THEN + ASM_MESON_TAC[FSTCART_PASTECART]; + DISCH_THEN(X_CHOOSE_THEN + `h:real^(1,1)finite_sum->real^M` STRIP_ASSUME_TAC)] THEN + EXISTS_TAC + `(\z. pastecart (h z) (k z)) + :real^(1,1)finite_sum->real^(M,N)finite_sum` THEN + ASM_SIMP_TAC[CONTINUOUS_ON_PASTECART; ETA_AX] THEN + REWRITE_TAC[LINEPATH_REFL; PASTECART_FST_SND] THEN + ASM_SIMP_TAC[PASTECART_IN_PCROSS]);; + +let SIMPLY_CONNECTED_PCROSS_EQ = prove + (`!s:real^M->bool t:real^N->bool. + simply_connected(s PCROSS t) <=> + s = {} \/ t = {} \/ simply_connected s /\ simply_connected t`, + REPEAT GEN_TAC THEN + ASM_CASES_TAC `s:real^M->bool = {}` THEN + ASM_REWRITE_TAC[PCROSS_EMPTY; SIMPLY_CONNECTED_EMPTY] THEN + ASM_CASES_TAC `t:real^N->bool = {}` THEN + ASM_REWRITE_TAC[PCROSS_EMPTY; SIMPLY_CONNECTED_EMPTY] THEN + EQ_TAC THEN REWRITE_TAC[SIMPLY_CONNECTED_PCROSS] THEN REPEAT STRIP_TAC THENL + [REWRITE_TAC[SIMPLY_CONNECTED_EQ_CONTRACTIBLE_LOOP_ANY] THEN + MAP_EVERY X_GEN_TAC [`p:real^1->real^M`; `a:real^M`] THEN + REWRITE_TAC[path; path_image; pathstart; pathfinish; SUBSET; + FORALL_IN_IMAGE] THEN + STRIP_TAC THEN UNDISCH_TAC `~(t:real^N->bool = {})` THEN + REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN + DISCH_THEN(X_CHOOSE_THEN `b:real^N` STRIP_ASSUME_TAC) THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I + [SIMPLY_CONNECTED_EQ_CONTRACTIBLE_LOOP_ANY]) THEN + DISCH_THEN(MP_TAC o SPECL + [`(\t. pastecart (p t) (b)):real^1->real^(M,N)finite_sum`; + `pastecart (a:real^M) (b:real^N)`]) THEN + ASM_REWRITE_TAC[PASTECART_IN_PCROSS] THEN + ASM_SIMP_TAC[path; path_image; pathstart; pathfinish; SUBSET; + FORALL_IN_IMAGE; PASTECART_IN_PCROSS; PASTECART_INJ; + CONTINUOUS_ON_PASTECART; ETA_AX; CONTINUOUS_ON_CONST] THEN + STRIP_TAC THEN + MP_TAC(ISPECL + [`(\t. pastecart (p t) b):real^1->real^(M,N)finite_sum`; + `linepath (pastecart (a:real^M) (b:real^N),pastecart a b)`; + `fstcart:real^(M,N)finite_sum->real^M`; + `(s:real^M->bool) PCROSS (t:real^N->bool)`; `s:real^M->bool`] + HOMOTOPIC_LOOPS_CONTINUOUS_IMAGE) THEN + ASM_SIMP_TAC[LINEAR_CONTINUOUS_ON; LINEAR_FSTCART] THEN + SIMP_TAC[o_DEF; LINEPATH_REFL; FSTCART_PASTECART; ETA_AX; + SUBSET; FORALL_IN_PCROSS; FORALL_IN_IMAGE]; + REWRITE_TAC[SIMPLY_CONNECTED_EQ_CONTRACTIBLE_LOOP_ANY] THEN + MAP_EVERY X_GEN_TAC [`p:real^1->real^N`; `b:real^N`] THEN + REWRITE_TAC[path; path_image; pathstart; pathfinish; SUBSET; + FORALL_IN_IMAGE] THEN + STRIP_TAC THEN UNDISCH_TAC `~(s:real^M->bool = {})` THEN + REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN + DISCH_THEN(X_CHOOSE_THEN `a:real^M` STRIP_ASSUME_TAC) THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I + [SIMPLY_CONNECTED_EQ_CONTRACTIBLE_LOOP_ANY]) THEN + DISCH_THEN(MP_TAC o SPECL + [`(\t. pastecart a (p t)):real^1->real^(M,N)finite_sum`; + `pastecart (a:real^M) (b:real^N)`]) THEN + ASM_REWRITE_TAC[PASTECART_IN_PCROSS] THEN + ASM_SIMP_TAC[path; path_image; pathstart; pathfinish; SUBSET; + FORALL_IN_IMAGE; PASTECART_IN_PCROSS; PASTECART_INJ; + CONTINUOUS_ON_PASTECART; ETA_AX; CONTINUOUS_ON_CONST] THEN + STRIP_TAC THEN + MP_TAC(ISPECL + [`(\t. pastecart a (p t)):real^1->real^(M,N)finite_sum`; + `linepath (pastecart (a:real^M) (b:real^N),pastecart a b)`; + `sndcart:real^(M,N)finite_sum->real^N`; + `(s:real^M->bool) PCROSS (t:real^N->bool)`; `t:real^N->bool`] + HOMOTOPIC_LOOPS_CONTINUOUS_IMAGE) THEN + ASM_SIMP_TAC[LINEAR_CONTINUOUS_ON; LINEAR_SNDCART] THEN + SIMP_TAC[o_DEF; LINEPATH_REFL; SNDCART_PASTECART; ETA_AX; + SUBSET; FORALL_IN_PCROSS; FORALL_IN_IMAGE]]);; + +(* ------------------------------------------------------------------------- *) +(* A mapping out of a sphere is nullhomotopic iff it extends to the ball. *) +(* This even works out in the degenerate cases when the radius is <= 0, and *) +(* we also don't need to explicitly assume continuity since it's already *) +(* implicit in both sides of the equivalence. *) +(* ------------------------------------------------------------------------- *) + +let NULLHOMOTOPIC_FROM_SPHERE_EXTENSION = prove + (`!f:real^M->real^N s a r. + (?c. homotopic_with (\x. T) (sphere(a,r),s) f (\x. c)) <=> + (?g. g continuous_on cball(a,r) /\ IMAGE g (cball(a,r)) SUBSET s /\ + !x. x IN sphere(a,r) ==> g x = f x)`, + let lemma = prove + (`!f:real^M->real^N g a r. + (!e. &0 < e + ==> ?d. &0 < d /\ + !x. ~(x = a) /\ norm(x - a) < d ==> norm(g x - f a) < e) /\ + g continuous_on (cball(a,r) DELETE a) /\ + (!x. x IN cball(a,r) /\ ~(x = a) ==> f x = g x) + ==> f continuous_on cball(a,r)`, + REPEAT STRIP_TAC THEN REWRITE_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN] THEN + X_GEN_TAC `x:real^M` THEN REWRITE_TAC[IN_CBALL; dist] THEN STRIP_TAC THEN + ASM_CASES_TAC `x:real^M = a` THENL + [ASM_REWRITE_TAC[continuous_within; IN_CBALL; dist] THEN + RULE_ASSUM_TAC(REWRITE_RULE[IN_CBALL; dist]) THEN + 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 + GEN_TAC THEN DISCH_TAC THEN ASM_REWRITE_TAC[] THEN + X_GEN_TAC `y:real^M` THEN ASM_CASES_TAC `y:real^M = a` THEN + ASM_MESON_TAC[VECTOR_SUB_REFL; NORM_0]; + MATCH_MP_TAC CONTINUOUS_TRANSFORM_WITHIN THEN + EXISTS_TAC `g:real^M->real^N` THEN EXISTS_TAC `norm(x - a:real^M)` THEN + ASM_SIMP_TAC[NORM_POS_LT; VECTOR_SUB_EQ; IN_CBALL; dist] THEN + CONJ_TAC THENL + [RULE_ASSUM_TAC(REWRITE_RULE[IN_CBALL; dist]); + UNDISCH_TAC + `(g:real^M->real^N) continuous_on (cball(a,r) DELETE a)` THEN + REWRITE_TAC[continuous_on; continuous_within] THEN + DISCH_THEN(MP_TAC o SPEC `x:real^M`) THEN + ASM_REWRITE_TAC[IN_DELETE; IN_CBALL; dist] THEN + MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `e:real` THEN + ASM_CASES_TAC `&0 < e` THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `min d (norm(x - a:real^M))` THEN + ASM_REWRITE_TAC[REAL_LT_MIN; NORM_POS_LT; VECTOR_SUB_EQ]] THEN + ASM_MESON_TAC[NORM_SUB; NORM_ARITH + `norm(y - x:real^N) < norm(x - a) ==> ~(y = a)`]]) in + REWRITE_TAC[sphere; ONCE_REWRITE_RULE[DIST_SYM] dist] THEN + REPEAT GEN_TAC THEN REPEAT_TCL DISJ_CASES_THEN ASSUME_TAC + (REAL_ARITH `r < &0 \/ r = &0 \/ &0 < r`) + THENL + [ASM_SIMP_TAC[NORM_ARITH `r < &0 ==> ~(norm x = r)`] THEN + FIRST_ASSUM(ASSUME_TAC o GEN_REWRITE_RULE I [GSYM CBALL_EQ_EMPTY]) THEN + ASM_SIMP_TAC[HOMOTOPIC_WITH; IMAGE_CLAUSES; EMPTY_GSPEC; NOT_IN_EMPTY; + PCROSS; SET_RULE `{f t x |x,t| F} = {}`; EMPTY_SUBSET] THEN + REWRITE_TAC[CONTINUOUS_ON_EMPTY]; + ASM_SIMP_TAC[NORM_EQ_0; VECTOR_SUB_EQ; CBALL_SING] THEN + SIMP_TAC[HOMOTOPIC_WITH; PCROSS; FORALL_IN_GSPEC; FORALL_UNWIND_THM2] THEN + ASM_CASES_TAC `(f:real^M->real^N) a IN s` THENL + [MATCH_MP_TAC(TAUT `p /\ q ==> (p <=> q)`) THEN CONJ_TAC THENL + [EXISTS_TAC `(f:real^M->real^N) a` THEN + EXISTS_TAC `\y:real^(1,M)finite_sum. (f:real^M->real^N) a` THEN + ASM_REWRITE_TAC[CONTINUOUS_ON_CONST; SUBSET; FORALL_IN_IMAGE]; + EXISTS_TAC `f:real^M->real^N` THEN REWRITE_TAC[CONTINUOUS_ON_SING] THEN + ASM SET_TAC[]]; + MATCH_MP_TAC(TAUT `~q /\ ~p ==> (p <=> q)`) THEN CONJ_TAC THENL + [ASM SET_TAC[]; STRIP_TAC] THEN + UNDISCH_TAC `~((f:real^M->real^N) a IN s)` THEN REWRITE_TAC[] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE + `IMAGE h t SUBSET s ==> (?y. y IN t /\ z = h y) ==> z IN s`)) THEN + REWRITE_TAC[EXISTS_IN_GSPEC] THEN + EXISTS_TAC `vec 0:real^1` THEN ASM_SIMP_TAC[ENDS_IN_UNIT_INTERVAL] THEN + ASM_REWRITE_TAC[EXISTS_IN_GSPEC; UNWIND_THM2]]; + ALL_TAC] THEN + MATCH_MP_TAC(TAUT + `!p. (q ==> p) /\ (r ==> p) /\ (p ==> (q <=> r)) ==> (q <=> r)`) THEN + EXISTS_TAC + `(f:real^M->real^N) continuous_on {x | norm(x - a) = r} /\ + IMAGE f {x | norm(x - a) = r} SUBSET s` THEN + REPEAT CONJ_TAC THENL + [STRIP_TAC THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP HOMOTOPIC_WITH_IMP_SUBSET) THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP HOMOTOPIC_WITH_IMP_CONTINUOUS) THEN + ASM_REWRITE_TAC[]; + DISCH_THEN(X_CHOOSE_THEN `g:real^M->real^N` STRIP_ASSUME_TAC) THEN + CONJ_TAC THENL + [MATCH_MP_TAC CONTINUOUS_ON_EQ THEN EXISTS_TAC `g:real^M->real^N` THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC CONTINUOUS_ON_SUBSET THEN + EXISTS_TAC `cball(a:real^M,r)`; + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE + `IMAGE g t SUBSET s + ==> u SUBSET t /\ (!x. x IN u ==> f x = g x) + ==> IMAGE f u SUBSET s`)) THEN + ASM_SIMP_TAC[]] THEN + ASM_SIMP_TAC[SUBSET; IN_CBALL; dist; IN_ELIM_THM] THEN + MESON_TAC[REAL_LE_REFL; NORM_SUB]; + STRIP_TAC] THEN + ONCE_REWRITE_TAC[HOMOTOPIC_WITH_SYM] THEN EQ_TAC THENL + [REWRITE_TAC[homotopic_with; PCROSS; LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`c:real^N`; `h:real^(1,M)finite_sum->real^N`] THEN + STRIP_TAC THEN + EXISTS_TAC `\x. (h:real^(1,M)finite_sum->real^N) + (pastecart (lift(inv(r) * norm(x - a))) + (a + (if x = a then r % basis 1 + else r / norm(x - a) % (x - a))))` THEN + ASM_SIMP_TAC[IN_ELIM_THM; REAL_MUL_LINV; REAL_DIV_REFL; REAL_LT_IMP_NZ; + LIFT_NUM; VECTOR_ARITH `a + &1 % (x - a):real^N = x`] THEN + REPEAT CONJ_TAC THENL + [MATCH_MP_TAC lemma THEN + EXISTS_TAC `\x. (h:real^(1,M)finite_sum->real^N) + (pastecart (lift(inv(r) * norm(x - a))) + (a + r / norm(x - a) % (x - a)))` THEN + SIMP_TAC[] THEN CONJ_TAC THENL + [X_GEN_TAC `e:real` THEN DISCH_TAC THEN + ASM_REWRITE_TAC[VECTOR_SUB_REFL; NORM_0; REAL_MUL_RZERO; LIFT_NUM] THEN + FIRST_X_ASSUM(MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + COMPACT_UNIFORMLY_CONTINUOUS)) THEN + SIMP_TAC[REWRITE_RULE[PCROSS] COMPACT_PCROSS; + REWRITE_RULE[REWRITE_RULE[ONCE_REWRITE_RULE[DIST_SYM] dist] sphere] + COMPACT_SPHERE; COMPACT_INTERVAL] THEN + REWRITE_TAC[uniformly_continuous_on] THEN + DISCH_THEN(MP_TAC o SPEC `e:real`) THEN ASM_REWRITE_TAC[REAL_HALF] THEN + REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_GSPEC] THEN + DISCH_THEN(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `min r (d * r):real` THEN + ASM_SIMP_TAC[REAL_LT_MUL; REAL_LT_MIN] THEN + X_GEN_TAC `x:real^M` THEN REPEAT STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `vec 0:real^1`) THEN + REWRITE_TAC[ENDS_IN_UNIT_INTERVAL; RIGHT_IMP_FORALL_THM] THEN + ASM_REWRITE_TAC[IMP_IMP; GSYM CONJ_ASSOC] THEN + DISCH_THEN(MP_TAC o MATCH_MP (MESON[] + `(!x t y. P x t y) ==> (!t x. P x t x)`)) THEN + REWRITE_TAC[dist] THEN DISCH_THEN MATCH_MP_TAC THEN + REWRITE_TAC[IN_INTERVAL_1; LIFT_DROP; DROP_VEC] THEN + REWRITE_TAC[ONCE_REWRITE_RULE[REAL_MUL_SYM] (GSYM real_div)] THEN + ASM_SIMP_TAC[REAL_LE_RDIV_EQ; REAL_LE_LDIV_EQ] THEN + ASM_SIMP_TAC[REAL_MUL_LID; REAL_MUL_LZERO; NORM_POS_LE] THEN + ASM_SIMP_TAC[REAL_LT_IMP_LE; CONJ_ASSOC] THEN + REWRITE_TAC[VECTOR_ADD_SUB; NORM_MUL; REAL_ABS_DIV; REAL_ABS_NORM] THEN + ASM_SIMP_TAC[REAL_DIV_RMUL; NORM_EQ_0; VECTOR_SUB_EQ] THEN + ASM_SIMP_TAC[REAL_ARITH `&0 < r ==> abs r = r`] THEN + REWRITE_TAC[PASTECART_SUB; VECTOR_SUB_REFL; NORM_PASTECART] THEN + REWRITE_TAC[NORM_0; VECTOR_SUB_RZERO] THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN REWRITE_TAC[REAL_ADD_RID] THEN + REWRITE_TAC[POW_2_SQRT_ABS; REAL_ABS_NORM; NORM_LIFT] THEN + ASM_SIMP_TAC[REAL_ABS_DIV; REAL_LT_LDIV_EQ; REAL_ABS_NORM; + REAL_ARITH `&0 < r ==> abs r = r`]; + GEN_REWRITE_TAC LAND_CONV [GSYM o_DEF] THEN + MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN CONJ_TAC THENL + [MATCH_MP_TAC CONTINUOUS_ON_PASTECART THEN + SIMP_TAC[CONTINUOUS_ON_CMUL; LIFT_CMUL; CONTINUOUS_ON_SUB; + CONTINUOUS_ON_ID; CONTINUOUS_ON_CONST; + CONTINUOUS_ON_LIFT_NORM_COMPOSE] THEN + MATCH_MP_TAC CONTINUOUS_ON_ADD THEN + REWRITE_TAC[CONTINUOUS_ON_CONST] THEN + MATCH_MP_TAC CONTINUOUS_ON_MUL THEN + SIMP_TAC[CONTINUOUS_ON_SUB; CONTINUOUS_ON_ID; CONTINUOUS_ON_CONST; + o_DEF; real_div; LIFT_CMUL] THEN + MATCH_MP_TAC CONTINUOUS_ON_CMUL THEN + REWRITE_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN] THEN + GEN_TAC THEN REWRITE_TAC[IN_DELETE] THEN DISCH_TAC THEN + MATCH_MP_TAC CONTINUOUS_AT_WITHIN THEN + MATCH_MP_TAC(REWRITE_RULE[o_DEF] CONTINUOUS_INV) THEN + ASM_SIMP_TAC[NETLIMIT_AT; NORM_EQ_0; VECTOR_SUB_EQ] THEN + MATCH_MP_TAC CONTINUOUS_LIFT_NORM_COMPOSE THEN + SIMP_TAC[CONTINUOUS_SUB; CONTINUOUS_AT_ID; CONTINUOUS_CONST]; + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET)) THEN + REWRITE_TAC[FORALL_IN_IMAGE; FORALL_IN_GSPEC; SUBSET] THEN + REWRITE_TAC[IN_ELIM_PASTECART_THM; IN_DELETE; IN_ELIM_THM] THEN + SIMP_TAC[IN_CBALL; NORM_ARITH `dist(a:real^M,a + x) = norm x`] THEN + REWRITE_TAC[ONCE_REWRITE_RULE[DIST_SYM] dist] THEN + REWRITE_TAC[IN_INTERVAL_1; LIFT_DROP; DROP_VEC] THEN + REWRITE_TAC[ONCE_REWRITE_RULE[REAL_MUL_SYM] (GSYM real_div)] THEN + ASM_SIMP_TAC[REAL_LE_RDIV_EQ; REAL_LE_LDIV_EQ] THEN + ASM_SIMP_TAC[REAL_MUL_LID; REAL_MUL_LZERO; NORM_POS_LE] THEN + SIMP_TAC[VECTOR_ADD_SUB; NORM_MUL; REAL_ABS_DIV; REAL_ABS_NORM; + REAL_DIV_RMUL; NORM_EQ_0; VECTOR_SUB_EQ] THEN + ASM_REAL_ARITH_TAC]]; + GEN_REWRITE_TAC (LAND_CONV o LAND_CONV) [GSYM o_DEF] THEN + REWRITE_TAC[IMAGE_o] THEN FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE + `IMAGE g s SUBSET u ==> t SUBSET s ==> IMAGE g t SUBSET u`)) THEN + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; FORALL_IN_GSPEC] THEN + REWRITE_TAC[IN_ELIM_PASTECART_THM; IN_CBALL; IN_ELIM_THM] THEN + X_GEN_TAC `x:real^M` THEN + REWRITE_TAC[ONCE_REWRITE_RULE[DIST_SYM] dist] THEN REPEAT STRIP_TAC THENL + [REWRITE_TAC[IN_INTERVAL_1; LIFT_DROP; DROP_VEC] THEN + REWRITE_TAC[ONCE_REWRITE_RULE[REAL_MUL_SYM] (GSYM real_div)] THEN + ASM_SIMP_TAC[REAL_LE_RDIV_EQ; REAL_LE_LDIV_EQ] THEN + ASM_REWRITE_TAC[REAL_MUL_LID; REAL_MUL_LZERO; NORM_POS_LE]; + REWRITE_TAC[VECTOR_ADD_SUB] THEN COND_CASES_TAC THEN + ASM_SIMP_TAC[NORM_MUL; NORM_BASIS; DIMINDEX_GE_1; LE_REFL; + REAL_ABS_DIV; REAL_ABS_NORM; + REAL_MUL_RID; REAL_ARITH `&0 < r ==> abs r = r`] THEN + ASM_SIMP_TAC[REAL_DIV_RMUL; NORM_EQ_0; VECTOR_SUB_EQ]]; + GEN_TAC THEN COND_CASES_TAC THEN + ASM_SIMP_TAC[VECTOR_SUB_REFL; NORM_0; REAL_LT_IMP_NZ] THEN + REWRITE_TAC[VECTOR_ARITH `a + &1 % (x - a):real^N = x`]]; + DISCH_THEN(X_CHOOSE_THEN `g:real^M->real^N` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `(g:real^M->real^N) a` THEN + ASM_SIMP_TAC[HOMOTOPIC_WITH; PCROSS] THEN + EXISTS_TAC `\y:real^(1,M)finite_sum. + (g:real^M->real^N) + (a + drop(fstcart y) % (sndcart y - a))` THEN + REWRITE_TAC[FSTCART_PASTECART; SNDCART_PASTECART; DROP_VEC] THEN + REWRITE_TAC[VECTOR_MUL_LZERO; VECTOR_ADD_RID; VECTOR_MUL_LID] THEN + ASM_SIMP_TAC[VECTOR_SUB_ADD2] THEN CONJ_TAC THENL + [GEN_REWRITE_TAC LAND_CONV [GSYM o_DEF] THEN + MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN CONJ_TAC THENL + [MATCH_MP_TAC CONTINUOUS_ON_ADD THEN SIMP_TAC[CONTINUOUS_ON_CONST] THEN + MATCH_MP_TAC CONTINUOUS_ON_MUL THEN + SIMP_TAC[o_DEF; LIFT_DROP; CONTINUOUS_ON_SUB; CONTINUOUS_ON_CONST; + LINEAR_CONTINUOUS_ON; LINEAR_SNDCART; LINEAR_FSTCART; ETA_AX]; + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET))]; + GEN_REWRITE_TAC (LAND_CONV o LAND_CONV) [GSYM o_DEF] THEN + REWRITE_TAC[IMAGE_o] THEN FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE + `IMAGE g s SUBSET u ==> t SUBSET s ==> IMAGE g t SUBSET u`))] THEN + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; FORALL_IN_GSPEC] THEN + REWRITE_TAC[FSTCART_PASTECART; SNDCART_PASTECART; IN_ELIM_THM] THEN + REWRITE_TAC[IN_CBALL; NORM_ARITH `dist(a:real^M,a + x) = norm x`] THEN + ASM_SIMP_TAC[NORM_MUL; IN_INTERVAL_1; DROP_VEC; REAL_LE_RMUL_EQ; + REAL_ARITH `x * r <= r <=> x * r <= &1 * r`] THEN + REAL_ARITH_TAC]);; + +(* ------------------------------------------------------------------------- *) +(* Homotopy equivalence. *) +(* ------------------------------------------------------------------------- *) + +parse_as_infix("homotopy_equivalent",(12,"right"));; + +let homotopy_equivalent = new_definition + `(s:real^M->bool) homotopy_equivalent (t:real^N->bool) <=> + ?f g. f continuous_on s /\ IMAGE f s SUBSET t /\ + g continuous_on t /\ IMAGE g t SUBSET s /\ + homotopic_with (\x. T) (s,s) (g o f) I /\ + homotopic_with (\x. T) (t,t) (f o g) I`;; + +let HOMOTOPY_EQUIVALENT = prove + (`!s:real^M->bool t:real^N->bool. + s homotopy_equivalent t <=> + ?f g h. f continuous_on s /\ IMAGE f s SUBSET t /\ + g continuous_on t /\ IMAGE g t SUBSET s /\ + h continuous_on t /\ IMAGE h t SUBSET s /\ + homotopic_with (\x. T) (s,s) (g o f) I /\ + homotopic_with (\x. T) (t,t) (f o h) I`, + REPEAT GEN_TAC THEN REWRITE_TAC[homotopy_equivalent] THEN + MATCH_MP_TAC(MESON[] `(!x. P x <=> Q x) ==> ((?x. P x) <=> (?x. Q x))`) THEN + X_GEN_TAC `f:real^M->real^N` THEN + EQ_TAC THENL [MESON_TAC[]; STRIP_TAC] THEN + EXISTS_TAC `(g:real^N->real^M) o f o (h:real^N->real^M)` THEN + ASM_REWRITE_TAC[IMAGE_o] THEN REPEAT CONJ_TAC THENL + [REPEAT(MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN CONJ_TAC) THEN + REWRITE_TAC[IMAGE_o] THEN FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP + (REWRITE_RULE[IMP_CONJ] CONTINUOUS_ON_SUBSET)) THEN ASM SET_TAC[]; + ASM SET_TAC[]; + TRANS_TAC HOMOTOPIC_WITH_TRANS + `((g:real^N->real^M) o I) o (f:real^M->real^N)` THEN + CONJ_TAC THENL [ALL_TAC; ASM_REWRITE_TAC[I_O_ID]] THEN + MATCH_MP_TAC HOMOTOPIC_WITH_COMPOSE_CONTINUOUS_RIGHT THEN + EXISTS_TAC `t:real^N->bool` THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC HOMOTOPIC_WITH_COMPOSE_CONTINUOUS_LEFT THEN + EXISTS_TAC `t:real^N->bool` THEN ASM_REWRITE_TAC[]; + TRANS_TAC HOMOTOPIC_WITH_TRANS + `(f:real^M->real^N) o I o (h:real^N->real^M)` THEN + CONJ_TAC THENL [ALL_TAC; ASM_REWRITE_TAC[I_O_ID]] THEN + MATCH_MP_TAC HOMOTOPIC_WITH_COMPOSE_CONTINUOUS_LEFT THEN + EXISTS_TAC `s:real^M->bool` THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[o_ASSOC] THEN + MATCH_MP_TAC HOMOTOPIC_WITH_COMPOSE_CONTINUOUS_RIGHT THEN + EXISTS_TAC `s:real^M->bool` THEN ASM_REWRITE_TAC[]]);; + +let HOMEOMORPHIC_IMP_HOMOTOPY_EQUIVALENT = prove + (`!s:real^M->bool t:real^N->bool. + s homeomorphic t ==> s homotopy_equivalent t`, + REPEAT GEN_TAC THEN + REWRITE_TAC[homeomorphic; homotopy_equivalent; homeomorphism] THEN + REPEAT(MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC) THEN + STRIP_TAC THEN ASM_REWRITE_TAC[SUBSET_REFL] THEN + CONJ_TAC THEN MATCH_MP_TAC HOMOTOPIC_WITH_EQUAL THEN + ASM_SIMP_TAC[CONTINUOUS_ON_COMPOSE; IMAGE_o; o_THM; I_THM; SUBSET_REFL]);; + +let HOMOTOPY_EQUIVALENT_REFL = prove + (`!s:real^N->bool. s homotopy_equivalent s`, + SIMP_TAC[HOMEOMORPHIC_IMP_HOMOTOPY_EQUIVALENT; HOMEOMORPHIC_REFL]);; + +let HOMOTOPY_EQUIVALENT_SYM = prove + (`!s:real^M->bool t:real^N->bool. + s homotopy_equivalent t <=> t homotopy_equivalent s`, + REPEAT GEN_TAC THEN REWRITE_TAC[homotopy_equivalent] THEN + GEN_REWRITE_TAC RAND_CONV [SWAP_EXISTS_THM] THEN + REPEAT(AP_TERM_TAC THEN ABS_TAC) THEN CONV_TAC TAUT);; + +let HOMOTOPY_EQUIVALENT_TRANS = prove + (`!s:real^M->bool t:real^N->bool u:real^P->bool. + s homotopy_equivalent t /\ t homotopy_equivalent u + ==> s homotopy_equivalent u`, + REPEAT GEN_TAC THEN + SIMP_TAC[homotopy_equivalent; LEFT_AND_EXISTS_THM; LEFT_IMP_EXISTS_THM] THEN + SIMP_TAC[RIGHT_AND_EXISTS_THM; LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC + [`f1:real^M->real^N`; `g1:real^N->real^M`; + `f2:real^N->real^P`; `g2:real^P->real^N`] THEN + STRIP_TAC THEN + MAP_EVERY EXISTS_TAC + [`(f2:real^N->real^P) o (f1:real^M->real^N)`; + `(g1:real^N->real^M) o (g2:real^P->real^N)`] THEN + REWRITE_TAC[IMAGE_o] THEN + REPLICATE_TAC 2 + (CONJ_TAC THENL + [ASM_MESON_TAC[CONTINUOUS_ON_COMPOSE; CONTINUOUS_ON_SUBSET];ALL_TAC] THEN + CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC]) THEN + CONJ_TAC THEN MATCH_MP_TAC HOMOTOPIC_WITH_TRANS THENL + [EXISTS_TAC `(g1:real^N->real^M) o I o (f1:real^M->real^N)`; + EXISTS_TAC `(f2:real^N->real^P) o I o (g2:real^P->real^N)`] THEN + (CONJ_TAC THENL [ALL_TAC; ASM_REWRITE_TAC[I_O_ID]]) THEN + REWRITE_TAC[GSYM o_ASSOC] THEN + MATCH_MP_TAC HOMOTOPIC_WITH_COMPOSE_CONTINUOUS_LEFT THEN + EXISTS_TAC `t:real^N->bool` THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[o_ASSOC] THEN + MATCH_MP_TAC HOMOTOPIC_WITH_COMPOSE_CONTINUOUS_RIGHT THEN + EXISTS_TAC `t:real^N->bool` THEN ASM_REWRITE_TAC[]);; + +let HOMOTOPY_EQUIVALENT_INJECTIVE_LINEAR_IMAGE_SELF = prove + (`!f:real^M->real^N s. + linear f /\ (!x y. f x = f y ==> x = y) + ==> (IMAGE f s) homotopy_equivalent s`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC HOMEOMORPHIC_IMP_HOMOTOPY_EQUIVALENT THEN + MATCH_MP_TAC HOMEOMORPHIC_INJECTIVE_LINEAR_IMAGE_SELF THEN + ASM_REWRITE_TAC[]);; + +let HOMOTOPY_EQUIVALENT_INJECTIVE_LINEAR_IMAGE_LEFT_EQ = prove + (`!f:real^M->real^N s t. + linear f /\ (!x y. f x = f y ==> x = y) + ==> ((IMAGE f s) homotopy_equivalent t <=> s homotopy_equivalent t)`, + REPEAT GEN_TAC THEN DISCH_THEN(ASSUME_TAC o SPEC `s:real^M->bool` o + MATCH_MP HOMOTOPY_EQUIVALENT_INJECTIVE_LINEAR_IMAGE_SELF) THEN + EQ_TAC THENL + [FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [HOMOTOPY_EQUIVALENT_SYM]); + POP_ASSUM MP_TAC] THEN + REWRITE_TAC[IMP_IMP; HOMOTOPY_EQUIVALENT_TRANS]);; + +let HOMOTOPY_EQUIVALENT_INJECTIVE_LINEAR_IMAGE_RIGHT_EQ = prove + (`!f:real^M->real^N s t. + linear f /\ (!x y. f x = f y ==> x = y) + ==> (s homotopy_equivalent (IMAGE f t) <=> s homotopy_equivalent t)`, + ONCE_REWRITE_TAC[HOMOTOPY_EQUIVALENT_SYM] THEN + REWRITE_TAC[HOMOTOPY_EQUIVALENT_INJECTIVE_LINEAR_IMAGE_LEFT_EQ]);; + +add_linear_invariants + [HOMOTOPY_EQUIVALENT_INJECTIVE_LINEAR_IMAGE_LEFT_EQ; + HOMOTOPY_EQUIVALENT_INJECTIVE_LINEAR_IMAGE_RIGHT_EQ];; + +let HOMOTOPY_EQUIVALENT_TRANSLATION_SELF = prove + (`!a:real^N s. (IMAGE (\x. a + x) s) homotopy_equivalent s`, + REPEAT GEN_TAC THEN MATCH_MP_TAC HOMEOMORPHIC_IMP_HOMOTOPY_EQUIVALENT THEN + REWRITE_TAC[HOMEOMORPHIC_TRANSLATION_SELF]);; + +let HOMOTOPY_EQUIVALENT_TRANSLATION_LEFT_EQ = prove + (`!a:real^N s t. + (IMAGE (\x. a + x) s) homotopy_equivalent t <=> s homotopy_equivalent t`, + MESON_TAC[HOMOTOPY_EQUIVALENT_TRANSLATION_SELF; + HOMOTOPY_EQUIVALENT_SYM; HOMOTOPY_EQUIVALENT_TRANS]);; + +let HOMOTOPY_EQUIVALENT_TRANSLATION_RIGHT_EQ = prove + (`!a:real^N s t. + s homotopy_equivalent (IMAGE (\x. a + x) t) <=> s homotopy_equivalent t`, + ONCE_REWRITE_TAC[HOMOTOPY_EQUIVALENT_SYM] THEN + REWRITE_TAC[HOMOTOPY_EQUIVALENT_TRANSLATION_LEFT_EQ]);; + +add_translation_invariants + [HOMOTOPY_EQUIVALENT_TRANSLATION_LEFT_EQ; + HOMOTOPY_EQUIVALENT_TRANSLATION_RIGHT_EQ];; + +let HOMOTOPY_EQUIVALENT_HOMOTOPIC_TRIVIALITY = prove + (`!s:real^M->bool t:real^N->bool u:real^P->bool. + s homotopy_equivalent t + ==> ((!f g. f continuous_on u /\ IMAGE f u SUBSET s /\ + g continuous_on u /\ IMAGE g u SUBSET s + ==> homotopic_with (\x. T) (u,s) f g) <=> + (!f g. f continuous_on u /\ IMAGE f u SUBSET t /\ + g continuous_on u /\ IMAGE g u SUBSET t + ==> homotopic_with (\x. T) (u,t) f g))`, + let lemma = prove + (`!s:real^M->bool t:real^N->bool u:real^P->bool. + s homotopy_equivalent t /\ + (!f g. f continuous_on u /\ IMAGE f u SUBSET s /\ + g continuous_on u /\ IMAGE g u SUBSET s + ==> homotopic_with (\x. T) (u,s) f g) + ==> (!f g. f continuous_on u /\ IMAGE f u SUBSET t /\ + g continuous_on u /\ IMAGE g u SUBSET t + ==> homotopic_with (\x. T) (u,t) f g)`, + REPEAT STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [homotopy_equivalent]) THEN + DISCH_THEN(X_CHOOSE_THEN `h:real^M->real^N` + (X_CHOOSE_THEN `k:real^N->real^M` STRIP_ASSUME_TAC)) THEN + SUBGOAL_THEN + `homotopic_with (\x. T) (u,t) + ((h:real^M->real^N) o (k:real^N->real^M) o (f:real^P->real^N)) + (h o k o g)` + MP_TAC THENL + [MATCH_MP_TAC HOMOTOPIC_WITH_COMPOSE_CONTINUOUS_LEFT THEN + EXISTS_TAC `s:real^M->bool` THEN ASM_REWRITE_TAC[] THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN REWRITE_TAC[IMAGE_o] THEN + REPEAT CONJ_TAC THEN TRY(MATCH_MP_TAC CONTINUOUS_ON_COMPOSE) THEN + ASM_REWRITE_TAC[] THEN + TRY(FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET))) THEN + ASM SET_TAC[]; + MATCH_MP_TAC(MESON[HOMOTOPIC_WITH_TRANS; HOMOTOPIC_WITH_SYM] + `homotopic_with P (u,t) f f' /\ homotopic_with P (u,t) g g' + ==> homotopic_with P (u,t) f g ==> homotopic_with P (u,t) f' g'`) THEN + CONJ_TAC THEN + GEN_REWRITE_TAC RAND_CONV [GSYM(CONJUNCT1(SPEC_ALL I_O_ID))] THEN + REWRITE_TAC[o_ASSOC] THEN + MATCH_MP_TAC HOMOTOPIC_WITH_COMPOSE_CONTINUOUS_RIGHT THEN + EXISTS_TAC `t:real^N->bool` THEN ASM_REWRITE_TAC[]]) in + REPEAT STRIP_TAC THEN EQ_TAC THEN + MATCH_MP_TAC(ONCE_REWRITE_RULE[IMP_CONJ] lemma) THEN + ASM_MESON_TAC[HOMOTOPY_EQUIVALENT_SYM]);; + +let HOMOTOPY_EQUIVALENT_COHOMOTOPIC_TRIVIALITY = prove + (`!s:real^M->bool t:real^N->bool u:real^P->bool. + s homotopy_equivalent t + ==> ((!f g. f continuous_on s /\ IMAGE f s SUBSET u /\ + g continuous_on s /\ IMAGE g s SUBSET u + ==> homotopic_with (\x. T) (s,u) f g) <=> + (!f g. f continuous_on t /\ IMAGE f t SUBSET u /\ + g continuous_on t /\ IMAGE g t SUBSET u + ==> homotopic_with (\x. T) (t,u) f g))`, + let lemma = prove + (`!s:real^M->bool t:real^N->bool u:real^P->bool. + s homotopy_equivalent t /\ + (!f g. f continuous_on s /\ IMAGE f s SUBSET u /\ + g continuous_on s /\ IMAGE g s SUBSET u + ==> homotopic_with (\x. T) (s,u) f g) + ==> (!f g. f continuous_on t /\ IMAGE f t SUBSET u /\ + g continuous_on t /\ IMAGE g t SUBSET u + ==> homotopic_with (\x. T) (t,u) f g)`, + REPEAT STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [homotopy_equivalent]) THEN + DISCH_THEN(X_CHOOSE_THEN `h:real^M->real^N` + (X_CHOOSE_THEN `k:real^N->real^M` STRIP_ASSUME_TAC)) THEN + SUBGOAL_THEN + `homotopic_with (\x. T) (t,u) + (((f:real^N->real^P) o h) o (k:real^N->real^M)) ((g o h) o k)` + MP_TAC THENL + [MATCH_MP_TAC HOMOTOPIC_WITH_COMPOSE_CONTINUOUS_RIGHT THEN + EXISTS_TAC `s:real^M->bool` THEN ASM_REWRITE_TAC[] THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN REWRITE_TAC[IMAGE_o] THEN + REPEAT CONJ_TAC THEN TRY(MATCH_MP_TAC CONTINUOUS_ON_COMPOSE) THEN + ASM_REWRITE_TAC[] THEN + TRY(FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET))) THEN + ASM SET_TAC[]; + MATCH_MP_TAC(MESON[HOMOTOPIC_WITH_TRANS; HOMOTOPIC_WITH_SYM] + `homotopic_with P (u,t) f f' /\ homotopic_with P (u,t) g g' + ==> homotopic_with P (u,t) f g ==> homotopic_with P (u,t) f' g'`) THEN + CONJ_TAC THEN + GEN_REWRITE_TAC RAND_CONV [GSYM(CONJUNCT2(SPEC_ALL I_O_ID))] THEN + REWRITE_TAC[GSYM o_ASSOC] THEN + MATCH_MP_TAC HOMOTOPIC_WITH_COMPOSE_CONTINUOUS_LEFT THEN + EXISTS_TAC `t:real^N->bool` THEN ASM_REWRITE_TAC[]]) in + REPEAT STRIP_TAC THEN EQ_TAC THEN + MATCH_MP_TAC(ONCE_REWRITE_RULE[IMP_CONJ] lemma) THEN + ASM_MESON_TAC[HOMOTOPY_EQUIVALENT_SYM]);; + +let HOMOTOPY_EQUIVALENT_HOMOTOPIC_TRIVIALITY_NULL = prove + (`!s:real^M->bool t:real^N->bool u:real^P->bool. + s homotopy_equivalent t + ==> ((!f. f continuous_on u /\ IMAGE f u SUBSET s + ==> ?c. homotopic_with (\x. T) (u,s) f (\x. c)) <=> + (!f. f continuous_on u /\ IMAGE f u SUBSET t + ==> ?c. homotopic_with (\x. T) (u,t) f (\x. c)))`, + let lemma = prove + (`!s:real^M->bool t:real^N->bool u:real^P->bool. + s homotopy_equivalent t /\ + (!f. f continuous_on u /\ IMAGE f u SUBSET s + ==> ?c. homotopic_with (\x. T) (u,s) f (\x. c)) + ==> (!f. f continuous_on u /\ IMAGE f u SUBSET t + ==> ?c. homotopic_with (\x. T) (u,t) f (\x. c))`, + REPEAT STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [homotopy_equivalent]) THEN + DISCH_THEN(X_CHOOSE_THEN `h:real^M->real^N` + (X_CHOOSE_THEN `k:real^N->real^M` STRIP_ASSUME_TAC)) THEN + FIRST_X_ASSUM(MP_TAC o SPEC `(k:real^N->real^M) o (f:real^P->real^N)`) THEN + REWRITE_TAC[IMAGE_o] THEN ANTS_TAC THENL + [CONJ_TAC THENL [MATCH_MP_TAC CONTINUOUS_ON_COMPOSE; ASM SET_TAC[]] THEN + ASM_MESON_TAC[CONTINUOUS_ON_SUBSET]; + DISCH_THEN(X_CHOOSE_TAC `c:real^M`) THEN + EXISTS_TAC `(h:real^M->real^N) c`] THEN + SUBGOAL_THEN + `homotopic_with (\x. T) (u,t) + ((h:real^M->real^N) o (k:real^N->real^M) o (f:real^P->real^N)) + (h o (\x. c))` + MP_TAC THENL + [MATCH_MP_TAC HOMOTOPIC_WITH_COMPOSE_CONTINUOUS_LEFT THEN + EXISTS_TAC `s:real^M->bool` THEN ASM_REWRITE_TAC[]; + GEN_REWRITE_TAC (LAND_CONV o RAND_CONV) [o_DEF] THEN + REWRITE_TAC[] THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] HOMOTOPIC_WITH_TRANS) THEN + GEN_REWRITE_TAC LAND_CONV [GSYM(CONJUNCT1(SPEC_ALL I_O_ID))] THEN + REWRITE_TAC[o_ASSOC] THEN ONCE_REWRITE_TAC[HOMOTOPIC_WITH_SYM] THEN + MATCH_MP_TAC HOMOTOPIC_WITH_COMPOSE_CONTINUOUS_RIGHT THEN + EXISTS_TAC `t:real^N->bool` THEN + ASM_REWRITE_TAC[]]) in + REPEAT STRIP_TAC THEN EQ_TAC THEN + MATCH_MP_TAC(ONCE_REWRITE_RULE[IMP_CONJ] lemma) THEN + ASM_MESON_TAC[HOMOTOPY_EQUIVALENT_SYM]);; + +let HOMOTOPY_EQUIVALENT_COHOMOTOPIC_TRIVIALITY_NULL = prove + (`!s:real^M->bool t:real^N->bool u:real^P->bool. + s homotopy_equivalent t + ==> ((!f. f continuous_on s /\ IMAGE f s SUBSET u + ==> ?c. homotopic_with (\x. T) (s,u) f (\x. c)) <=> + (!f. f continuous_on t /\ IMAGE f t SUBSET u + ==> ?c. homotopic_with (\x. T) (t,u) f (\x. c)))`, + let lemma = prove + (`!s:real^M->bool t:real^N->bool u:real^P->bool. + s homotopy_equivalent t /\ + (!f. f continuous_on s /\ IMAGE f s SUBSET u + ==> ?c. homotopic_with (\x. T) (s,u) f (\x. c)) + ==> (!f. f continuous_on t /\ IMAGE f t SUBSET u + ==> ?c. homotopic_with (\x. T) (t,u) f (\x. c))`, + REPEAT STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [homotopy_equivalent]) THEN + DISCH_THEN(X_CHOOSE_THEN `h:real^M->real^N` + (X_CHOOSE_THEN `k:real^N->real^M` STRIP_ASSUME_TAC)) THEN + FIRST_X_ASSUM(MP_TAC o SPEC `(f:real^N->real^P) o (h:real^M->real^N)`) THEN + REWRITE_TAC[IMAGE_o] THEN ANTS_TAC THENL + [CONJ_TAC THENL [MATCH_MP_TAC CONTINUOUS_ON_COMPOSE; ASM SET_TAC[]] THEN + ASM_MESON_TAC[CONTINUOUS_ON_SUBSET]; + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `c:real^P` THEN DISCH_TAC] THEN + SUBGOAL_THEN + `homotopic_with (\x. T) (t,u) + (((f:real^N->real^P) o h) o (k:real^N->real^M)) ((\x. c) o k)` + MP_TAC THENL + [MATCH_MP_TAC HOMOTOPIC_WITH_COMPOSE_CONTINUOUS_RIGHT THEN + EXISTS_TAC `s:real^M->bool` THEN ASM_REWRITE_TAC[]; + GEN_REWRITE_TAC (LAND_CONV o RAND_CONV) [o_DEF] THEN + REWRITE_TAC[] THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] HOMOTOPIC_WITH_TRANS) THEN + GEN_REWRITE_TAC LAND_CONV [GSYM(CONJUNCT2(SPEC_ALL I_O_ID))] THEN + REWRITE_TAC[GSYM o_ASSOC] THEN ONCE_REWRITE_TAC[HOMOTOPIC_WITH_SYM] THEN + MATCH_MP_TAC HOMOTOPIC_WITH_COMPOSE_CONTINUOUS_LEFT THEN + EXISTS_TAC `t:real^N->bool` THEN + ASM_REWRITE_TAC[]]) in + REPEAT STRIP_TAC THEN EQ_TAC THEN + MATCH_MP_TAC(ONCE_REWRITE_RULE[IMP_CONJ] lemma) THEN + ASM_MESON_TAC[HOMOTOPY_EQUIVALENT_SYM]);; + +let HOMOTOPY_INVARIANT_CONNECTEDNESS = prove + (`!f:real^M->real^N g s t. + f continuous_on s /\ IMAGE f s SUBSET t /\ + g continuous_on t /\ IMAGE g t SUBSET s /\ + homotopic_with (\x. T) (t,t) (f o g) I /\ + connected s + ==> connected t`, + REPEAT STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [homotopic_with]) THEN + REWRITE_TAC[o_THM; I_THM] THEN + DISCH_THEN(X_CHOOSE_THEN `h:real^(1,N)finite_sum->real^N` + STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN + `t = IMAGE (h:real^(1,N)finite_sum->real^N) (interval[vec 0,vec 1] PCROSS t)` + SUBST1_TAC THENL + [MATCH_MP_TAC SUBSET_ANTISYM THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[SUBSET; IN_IMAGE] THEN X_GEN_TAC `x:real^N` THEN + DISCH_TAC THEN ONCE_REWRITE_TAC[CONJ_SYM] THEN + REWRITE_TAC[EXISTS_IN_PCROSS] THEN + ASM_MESON_TAC[ENDS_IN_UNIT_INTERVAL]; + ALL_TAC] THEN + REWRITE_TAC[CONNECTED_IFF_CONNECTED_COMPONENT; IMP_CONJ] THEN + REWRITE_TAC[RIGHT_FORALL_IMP_THM; FORALL_IN_IMAGE; FORALL_IN_PCROSS] THEN + MAP_EVERY X_GEN_TAC [`t1:real^1`; `x1:real^N`] THEN STRIP_TAC THEN + MAP_EVERY X_GEN_TAC [`t2:real^1`; `x2:real^N`] THEN STRIP_TAC THEN + MATCH_MP_TAC(MESON[CONNECTED_COMPONENT_TRANS; CONNECTED_COMPONENT_SYM] + `!a b. (connected_component t a a' /\ connected_component t b b') /\ + connected_component t a b + ==> connected_component t a' b'`) THEN + MAP_EVERY EXISTS_TAC + [`(h:real^(1,N)finite_sum->real^N) (pastecart (vec 0) x1)`; + `(h:real^(1,N)finite_sum->real^N) (pastecart (vec 0) x2)`] THEN + CONJ_TAC THENL + [REWRITE_TAC[connected_component] THEN CONJ_TAC THENL + [EXISTS_TAC + `IMAGE ((h:real^(1,N)finite_sum->real^N) o (\s. pastecart s x1)) + (interval[vec 0,vec 1])`; + EXISTS_TAC + `IMAGE ((h:real^(1,N)finite_sum->real^N) o (\s. pastecart s x2)) + (interval[vec 0,vec 1])`] THEN + (CONJ_TAC THENL + [MATCH_MP_TAC CONNECTED_CONTINUOUS_IMAGE THEN + REWRITE_TAC[CONNECTED_INTERVAL] THEN + MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN + SIMP_TAC[CONTINUOUS_ON_PASTECART; CONTINUOUS_ON_ID; + CONTINUOUS_ON_CONST] 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; PASTECART_IN_PCROSS]; + REWRITE_TAC[IMAGE_o] THEN CONJ_TAC THENL + [MATCH_MP_TAC IMAGE_SUBSET THEN + ASM_SIMP_TAC[SUBSET; FORALL_IN_IMAGE; PASTECART_IN_PCROSS]; + CONJ_TAC THEN MATCH_MP_TAC FUN_IN_IMAGE] THEN + REWRITE_TAC[IN_IMAGE] THEN ASM_MESON_TAC[ENDS_IN_UNIT_INTERVAL]]); + ASM_REWRITE_TAC[connected_component] THEN + EXISTS_TAC `IMAGE (f:real^M->real^N) s` THEN + ASM_SIMP_TAC[CONNECTED_CONTINUOUS_IMAGE] THEN + CONJ_TAC THENL [ALL_TAC; ASM SET_TAC[]] THEN + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; IN_IMAGE] THEN + REWRITE_TAC[EXISTS_PASTECART; PASTECART_IN_PCROSS] THEN + X_GEN_TAC `y:real^M` THEN STRIP_TAC THEN + MAP_EVERY EXISTS_TAC [`vec 1:real^1`; `(f:real^M->real^N) y`] THEN + ASM_REWRITE_TAC[ENDS_IN_UNIT_INTERVAL] THEN ASM SET_TAC[]]);; + +let HOMOTOPY_INVARIANT_PATH_CONNECTEDNESS = prove + (`!f:real^M->real^N g s t. + f continuous_on s /\ IMAGE f s SUBSET t /\ + g continuous_on t /\ IMAGE g t SUBSET s /\ + homotopic_with (\x. T) (t,t) (f o g) I /\ + path_connected s + ==> path_connected t`, + REPEAT STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [homotopic_with]) THEN + REWRITE_TAC[o_THM; I_THM] THEN + DISCH_THEN(X_CHOOSE_THEN `h:real^(1,N)finite_sum->real^N` + STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN + `t = IMAGE (h:real^(1,N)finite_sum->real^N) (interval[vec 0,vec 1] PCROSS t)` + SUBST1_TAC THENL + [MATCH_MP_TAC SUBSET_ANTISYM THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[SUBSET; IN_IMAGE] THEN X_GEN_TAC `x:real^N` THEN + DISCH_TAC THEN ONCE_REWRITE_TAC[CONJ_SYM] THEN + REWRITE_TAC[EXISTS_IN_PCROSS] THEN + ASM_MESON_TAC[ENDS_IN_UNIT_INTERVAL]; + ALL_TAC] THEN + REWRITE_TAC[PATH_CONNECTED_IFF_PATH_COMPONENT; IMP_CONJ] THEN + REWRITE_TAC[RIGHT_FORALL_IMP_THM; FORALL_IN_IMAGE; FORALL_IN_PCROSS] THEN + MAP_EVERY X_GEN_TAC [`t1:real^1`; `x1:real^N`] THEN STRIP_TAC THEN + MAP_EVERY X_GEN_TAC [`t2:real^1`; `x2:real^N`] THEN STRIP_TAC THEN + MATCH_MP_TAC(MESON[PATH_COMPONENT_TRANS; PATH_COMPONENT_SYM] + `!a b. (path_component t a a' /\ path_component t b b') /\ + path_component t a b + ==> path_component t a' b'`) THEN + MAP_EVERY EXISTS_TAC + [`(h:real^(1,N)finite_sum->real^N) (pastecart (vec 0) x1)`; + `(h:real^(1,N)finite_sum->real^N) (pastecart (vec 0) x2)`] THEN + CONJ_TAC THENL + [REWRITE_TAC[PATH_COMPONENT] THEN CONJ_TAC THENL + [EXISTS_TAC + `IMAGE ((h:real^(1,N)finite_sum->real^N) o (\s. pastecart s x1)) + (interval[vec 0,vec 1])`; + EXISTS_TAC + `IMAGE ((h:real^(1,N)finite_sum->real^N) o (\s. pastecart s x2)) + (interval[vec 0,vec 1])`] THEN + (CONJ_TAC THENL + [MATCH_MP_TAC PATH_CONNECTED_CONTINUOUS_IMAGE THEN + REWRITE_TAC[PATH_CONNECTED_INTERVAL] THEN + MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN + SIMP_TAC[CONTINUOUS_ON_PASTECART; CONTINUOUS_ON_ID; + CONTINUOUS_ON_CONST] 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; PASTECART_IN_PCROSS]; + REWRITE_TAC[IMAGE_o] THEN CONJ_TAC THENL + [MATCH_MP_TAC IMAGE_SUBSET THEN + ASM_SIMP_TAC[SUBSET; FORALL_IN_IMAGE; PASTECART_IN_PCROSS]; + CONJ_TAC THEN MATCH_MP_TAC FUN_IN_IMAGE] THEN + REWRITE_TAC[IN_IMAGE] THEN ASM_MESON_TAC[ENDS_IN_UNIT_INTERVAL]]); + ASM_REWRITE_TAC[PATH_COMPONENT] THEN + EXISTS_TAC `IMAGE (f:real^M->real^N) s` THEN + ASM_SIMP_TAC[PATH_CONNECTED_CONTINUOUS_IMAGE] THEN + CONJ_TAC THENL [ALL_TAC; ASM SET_TAC[]] THEN + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; IN_IMAGE] THEN + REWRITE_TAC[EXISTS_PASTECART; PASTECART_IN_PCROSS] THEN + X_GEN_TAC `y:real^M` THEN STRIP_TAC THEN + MAP_EVERY EXISTS_TAC [`vec 1:real^1`; `(f:real^M->real^N) y`] THEN + ASM_REWRITE_TAC[ENDS_IN_UNIT_INTERVAL] THEN ASM SET_TAC[]]);; + +let HOMOTOPY_EQUIVALENT_CONNECTEDNESS = prove + (`!s:real^M->bool t:real^N->bool. + s homotopy_equivalent t ==> (connected s <=> connected t)`, + REWRITE_TAC[homotopy_equivalent] THEN REPEAT STRIP_TAC THEN + EQ_TAC THEN MATCH_MP_TAC(ONCE_REWRITE_RULE[IMP_CONJ] + (REWRITE_RULE[CONJ_ASSOC] HOMOTOPY_INVARIANT_CONNECTEDNESS)) THEN + ASM_MESON_TAC[]);; + +let HOMOTOPY_EQUIVALENT_PATH_CONNECTEDNESS = prove + (`!s:real^M->bool t:real^N->bool. + s homotopy_equivalent t ==> (path_connected s <=> path_connected t)`, + REWRITE_TAC[homotopy_equivalent] THEN REPEAT STRIP_TAC THEN + EQ_TAC THEN MATCH_MP_TAC(ONCE_REWRITE_RULE[IMP_CONJ] + (REWRITE_RULE[CONJ_ASSOC] HOMOTOPY_INVARIANT_PATH_CONNECTEDNESS)) THEN + ASM_MESON_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* Contractible sets. *) +(* ------------------------------------------------------------------------- *) + +let contractible = new_definition + `contractible s <=> ?a. homotopic_with (\x. T) (s,s) (\x. x) (\x. a)`;; + +let CONTRACTIBLE_IMP_SIMPLY_CONNECTED = prove + (`!s:real^N->bool. contractible s ==> simply_connected s`, + GEN_TAC THEN REWRITE_TAC[contractible] THEN + ASM_CASES_TAC `s:real^N->bool = {}` THEN + ASM_REWRITE_TAC[SIMPLY_CONNECTED_EMPTY] THEN + ASM_REWRITE_TAC[SIMPLY_CONNECTED_EQ_CONTRACTIBLE_LOOP_ALL] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `a:real^N` THEN + DISCH_TAC THEN REWRITE_TAC[homotopic_loops; PCROSS] THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP HOMOTOPIC_WITH_IMP_SUBSET) THEN + MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN + CONJ_TAC THENL [ASM SET_TAC[]; DISCH_TAC] THEN + X_GEN_TAC `p:real^1->real^N` THEN + REWRITE_TAC[path; path_image; pathfinish; pathstart] THEN + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE] THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [homotopic_with]) THEN + REWRITE_TAC[homotopic_with; SUBSET; FORALL_IN_IMAGE; PCROSS] THEN + REWRITE_TAC[FORALL_IN_GSPEC] THEN + DISCH_THEN(X_CHOOSE_THEN `h:real^(1,N)finite_sum->real^N` + STRIP_ASSUME_TAC) THEN + EXISTS_TAC `(h o (\y. pastecart (fstcart y) (p(sndcart y):real^N))) + :real^(1,1)finite_sum->real^N` THEN + ASM_SIMP_TAC[FSTCART_PASTECART; SNDCART_PASTECART; linepath; o_THM] THEN + CONJ_TAC THENL [ALL_TAC; CONV_TAC VECTOR_ARITH] THEN + MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN CONJ_TAC THENL + [MATCH_MP_TAC CONTINUOUS_ON_PASTECART THEN + SIMP_TAC[LINEAR_CONTINUOUS_ON; LINEAR_FSTCART] THEN + GEN_REWRITE_TAC LAND_CONV [GSYM o_DEF] THEN + MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN + SIMP_TAC[LINEAR_CONTINUOUS_ON; LINEAR_SNDCART]; + ALL_TAC] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE [IMP_CONJ] + CONTINUOUS_ON_SUBSET)) THEN + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; FORALL_IN_GSPEC] THEN + ASM_SIMP_TAC[IN_ELIM_PASTECART_THM; FSTCART_PASTECART; SNDCART_PASTECART]);; + +let CONTRACTIBLE_IMP_CONNECTED = prove + (`!s:real^N->bool. contractible s ==> connected s`, + SIMP_TAC[CONTRACTIBLE_IMP_SIMPLY_CONNECTED; + SIMPLY_CONNECTED_IMP_CONNECTED]);; + +let CONTRACTIBLE_IMP_PATH_CONNECTED = prove + (`!s:real^N->bool. contractible s ==> path_connected s`, + SIMP_TAC[CONTRACTIBLE_IMP_SIMPLY_CONNECTED; + SIMPLY_CONNECTED_IMP_PATH_CONNECTED]);; + +let NULLHOMOTOPIC_THROUGH_CONTRACTIBLE = prove + (`!f:real^M->real^N g:real^N->real^P s t u. + f continuous_on s /\ IMAGE f s SUBSET t /\ + g continuous_on t /\ IMAGE g t SUBSET u /\ + contractible t + ==> ?c. homotopic_with (\h. T) (s,u) (g o f) (\x. c)`, + REPEAT STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [contractible]) THEN + DISCH_THEN(X_CHOOSE_THEN `b:real^N` MP_TAC) THEN + DISCH_THEN(MP_TAC o ISPECL [`g:real^N->real^P`; `u:real^P->bool`] o MATCH_MP + (ONCE_REWRITE_RULE[IMP_CONJ] HOMOTOPIC_COMPOSE_CONTINUOUS_LEFT)) THEN + ASM_REWRITE_TAC[] THEN + DISCH_THEN(MP_TAC o ISPECL [`f:real^M->real^N`; `s:real^M->bool`] o MATCH_MP + (ONCE_REWRITE_RULE[IMP_CONJ] HOMOTOPIC_COMPOSE_CONTINUOUS_RIGHT)) THEN + ASM_REWRITE_TAC[o_DEF] THEN DISCH_TAC THEN + EXISTS_TAC `(g:real^N->real^P) b` THEN ASM_REWRITE_TAC[]);; + +let NULLHOMOTOPIC_INTO_CONTRACTIBLE = prove + (`!f:real^M->real^N s t. + f continuous_on s /\ IMAGE f s SUBSET t /\ contractible t + ==> ?c. homotopic_with (\h. T) (s,t) f (\x. c)`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN `(f:real^M->real^N) = (\x. x) o f` SUBST1_TAC THENL + [REWRITE_TAC[o_THM; FUN_EQ_THM]; + MATCH_MP_TAC NULLHOMOTOPIC_THROUGH_CONTRACTIBLE THEN + EXISTS_TAC `t:real^N->bool` THEN ASM_REWRITE_TAC[CONTINUOUS_ON_ID] THEN + SET_TAC[]]);; + +let NULLHOMOTOPIC_FROM_CONTRACTIBLE = prove + (`!f:real^M->real^N s t. + f continuous_on s /\ IMAGE f s SUBSET t /\ contractible s + ==> ?c. homotopic_with (\h. T) (s,t) f (\x. c)`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN `(f:real^M->real^N) = f o (\x. x)` SUBST1_TAC THENL + [REWRITE_TAC[o_THM; FUN_EQ_THM]; + MATCH_MP_TAC NULLHOMOTOPIC_THROUGH_CONTRACTIBLE THEN + EXISTS_TAC `s:real^M->bool` THEN ASM_REWRITE_TAC[CONTINUOUS_ON_ID] THEN + SET_TAC[]]);; + +let HOMOTOPIC_THROUGH_CONTRACTIBLE = prove + (`!f1:real^M->real^N g1:real^N->real^P f2 g2 s t u. + f1 continuous_on s /\ IMAGE f1 s SUBSET t /\ + g1 continuous_on t /\ IMAGE g1 t SUBSET u /\ + f2 continuous_on s /\ IMAGE f2 s SUBSET t /\ + g2 continuous_on t /\ IMAGE g2 t SUBSET u /\ + contractible t /\ path_connected u + ==> homotopic_with (\h. T) (s,u) (g1 o f1) (g2 o f2)`, + REPEAT STRIP_TAC THEN MP_TAC(ISPECL + [`f1:real^M->real^N`; `g1:real^N->real^P`; `s:real^M->bool`; + `t:real^N->bool`; `u:real^P->bool`] + NULLHOMOTOPIC_THROUGH_CONTRACTIBLE) THEN + ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN X_GEN_TAC `c1:real^P` THEN + DISCH_THEN(fun th -> ASSUME_TAC(MATCH_MP HOMOTOPIC_WITH_IMP_SUBSET th) THEN + MP_TAC th) THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] HOMOTOPIC_WITH_TRANS) THEN + ONCE_REWRITE_TAC[HOMOTOPIC_WITH_SYM] THEN MP_TAC(ISPECL + [`f2:real^M->real^N`; `g2:real^N->real^P`; `s:real^M->bool`; + `t:real^N->bool`; `u:real^P->bool`] + NULLHOMOTOPIC_THROUGH_CONTRACTIBLE) THEN + ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN X_GEN_TAC `c2:real^P` THEN + DISCH_THEN(fun th -> ASSUME_TAC(MATCH_MP HOMOTOPIC_WITH_IMP_SUBSET th) THEN + MP_TAC th) THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] HOMOTOPIC_WITH_TRANS) THEN + REWRITE_TAC[HOMOTOPIC_CONSTANT_MAPS] THEN FIRST_X_ASSUM + (MP_TAC o GEN_REWRITE_RULE I [PATH_CONNECTED_IFF_PATH_COMPONENT]) THEN + ASM SET_TAC[]);; + +let HOMOTOPIC_INTO_CONTRACTIBLE = prove + (`!f:real^M->real^N g s t. + f continuous_on s /\ IMAGE f s SUBSET t /\ + g continuous_on s /\ IMAGE g s SUBSET t /\ + contractible t + ==> homotopic_with (\h. T) (s,t) f g`, + REPEAT STRIP_TAC THEN SUBGOAL_THEN + `(f:real^M->real^N) = (\x. x) o f /\ (g:real^M->real^N) = (\x. x) o g` + (CONJUNCTS_THEN SUBST1_TAC) + THENL [REWRITE_TAC[o_THM; FUN_EQ_THM]; ALL_TAC] THEN + MATCH_MP_TAC HOMOTOPIC_THROUGH_CONTRACTIBLE THEN + EXISTS_TAC `t:real^N->bool` THEN ASM_REWRITE_TAC[CONTINUOUS_ON_ID] THEN + ASM_SIMP_TAC[IMAGE_ID; SUBSET_REFL; CONTRACTIBLE_IMP_PATH_CONNECTED]);; + +let HOMOTOPIC_FROM_CONTRACTIBLE = prove + (`!f:real^M->real^N g s t. + f continuous_on s /\ IMAGE f s SUBSET t /\ + g continuous_on s /\ IMAGE g s SUBSET t /\ + contractible s /\ path_connected t + ==> homotopic_with (\h. T) (s,t) f g`, + REPEAT STRIP_TAC THEN + REPEAT STRIP_TAC THEN SUBGOAL_THEN + `(f:real^M->real^N) = f o (\x. x) /\ (g:real^M->real^N) = g o (\x. x)` + (CONJUNCTS_THEN SUBST1_TAC) + THENL [REWRITE_TAC[o_THM; FUN_EQ_THM]; ALL_TAC] THEN + MATCH_MP_TAC HOMOTOPIC_THROUGH_CONTRACTIBLE THEN + EXISTS_TAC `s:real^M->bool` THEN ASM_REWRITE_TAC[CONTINUOUS_ON_ID] THEN + ASM_REWRITE_TAC[IMAGE_ID; SUBSET_REFL]);; + +let HOMOTOPY_EQUIVALENT_CONTRACTIBLE_SETS = prove + (`!s:real^M->bool t:real^N->bool. + contractible s /\ contractible t /\ (s = {} <=> t = {}) + ==> s homotopy_equivalent t`, + REPEAT GEN_TAC THEN ASM_CASES_TAC `t:real^N->bool = {}` THEN + ASM_SIMP_TAC[HOMEOMORPHIC_IMP_HOMOTOPY_EQUIVALENT; HOMEOMORPHIC_EMPTY] THEN + FIRST_X_ASSUM(X_CHOOSE_TAC `b:real^N` o + GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN + STRIP_TAC THEN REWRITE_TAC[homotopy_equivalent] THEN + FIRST_X_ASSUM(X_CHOOSE_TAC `a:real^M` o + GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN + EXISTS_TAC `(\x. b):real^M->real^N` THEN + EXISTS_TAC `(\y. a):real^N->real^M` THEN + REWRITE_TAC[CONTINUOUS_ON_CONST] THEN + REPLICATE_TAC 2 (CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC]) THEN + CONJ_TAC THEN MATCH_MP_TAC HOMOTOPIC_INTO_CONTRACTIBLE THEN + ASM_REWRITE_TAC[o_DEF; IMAGE_ID; I_DEF; SUBSET_REFL; CONTINUOUS_ON_ID; + CONTINUOUS_ON_CONST] THEN + ASM SET_TAC[]);; + +let STARLIKE_IMP_CONTRACTIBLE_GEN = prove + (`!P s. + (!a t. a IN s /\ &0 <= t /\ t <= &1 ==> P(\x. (&1 - t) % x + t % a)) /\ + starlike s + ==> ?a:real^N. homotopic_with P (s,s) (\x. x) (\x. a)`, + REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + REWRITE_TAC[starlike] THEN ONCE_REWRITE_TAC[SEGMENT_SYM] THEN + REWRITE_TAC[segment; SUBSET; FORALL_IN_GSPEC] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `a:real^N` THEN STRIP_TAC THEN + REWRITE_TAC[homotopic_with; PCROSS] THEN + EXISTS_TAC `\y:real^(1,N)finite_sum. + (&1 - drop(fstcart y)) % sndcart y + + drop(fstcart y) % a` THEN + ASM_SIMP_TAC[FSTCART_PASTECART; SNDCART_PASTECART; DROP_VEC; IN_INTERVAL_1; + SUBSET; FORALL_IN_IMAGE; REAL_SUB_RZERO; REAL_SUB_REFL; FORALL_IN_GSPEC; + VECTOR_MUL_LZERO; VECTOR_MUL_LID; VECTOR_ADD_LID; VECTOR_ADD_RID] THEN + MATCH_MP_TAC CONTINUOUS_ON_ADD THEN CONJ_TAC THEN + MATCH_MP_TAC CONTINUOUS_ON_MUL THEN + SIMP_TAC[o_DEF; LIFT_DROP; ETA_AX; LIFT_SUB; CONTINUOUS_ON_SUB; + CONTINUOUS_ON_CONST; LINEAR_CONTINUOUS_ON; ETA_AX; + LINEAR_FSTCART; LINEAR_SNDCART]);; + +let STARLIKE_IMP_CONTRACTIBLE = prove + (`!s:real^N->bool. starlike s ==> contractible s`, + SIMP_TAC[contractible; STARLIKE_IMP_CONTRACTIBLE_GEN]);; + +let CONTRACTIBLE_UNIV = prove + (`contractible(:real^N)`, + SIMP_TAC[STARLIKE_IMP_CONTRACTIBLE; STARLIKE_UNIV]);; + +let STARLIKE_IMP_SIMPLY_CONNECTED = prove + (`!s:real^N->bool. starlike s ==> simply_connected s`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC CONTRACTIBLE_IMP_SIMPLY_CONNECTED THEN + MATCH_MP_TAC STARLIKE_IMP_CONTRACTIBLE THEN ASM_REWRITE_TAC[]);; + +let CONVEX_IMP_SIMPLY_CONNECTED = prove + (`!s:real^N->bool. convex s ==> simply_connected s`, + MESON_TAC[CONVEX_IMP_STARLIKE; STARLIKE_IMP_SIMPLY_CONNECTED; + SIMPLY_CONNECTED_EMPTY]);; + +let STARLIKE_IMP_PATH_CONNECTED = prove + (`!s:real^N->bool. starlike s ==> path_connected s`, + MESON_TAC[STARLIKE_IMP_SIMPLY_CONNECTED; + SIMPLY_CONNECTED_IMP_PATH_CONNECTED]);; + +let STARLIKE_IMP_CONNECTED = prove + (`!s:real^N->bool. starlike s ==> connected s`, + MESON_TAC[STARLIKE_IMP_PATH_CONNECTED; PATH_CONNECTED_IMP_CONNECTED]);; + +let IS_INTERVAL_SIMPLY_CONNECTED_1 = prove + (`!s:real^1->bool. is_interval s <=> simply_connected s`, + MESON_TAC[SIMPLY_CONNECTED_IMP_PATH_CONNECTED; IS_INTERVAL_PATH_CONNECTED_1; + CONVEX_IMP_SIMPLY_CONNECTED; IS_INTERVAL_CONVEX_1]);; + +let CONTRACTIBLE_EMPTY = prove + (`contractible {}`, + SIMP_TAC[contractible; HOMOTOPIC_WITH; PCROSS_EMPTY; NOT_IN_EMPTY] THEN + REWRITE_TAC[CONTINUOUS_ON_EMPTY] THEN SET_TAC[]);; + +let CONTRACTIBLE_CONVEX_TWEAK_BOUNDARY_POINTS = prove + (`!s t:real^N->bool. + convex s /\ relative_interior s SUBSET t /\ t SUBSET closure s + ==> contractible t`, + REPEAT GEN_TAC THEN ASM_CASES_TAC `s:real^N->bool = {}` THEN + ASM_SIMP_TAC[SUBSET_EMPTY; CLOSURE_EMPTY; CONTRACTIBLE_EMPTY] THEN + STRIP_TAC THEN MATCH_MP_TAC STARLIKE_IMP_CONTRACTIBLE THEN + MATCH_MP_TAC STARLIKE_CONVEX_TWEAK_BOUNDARY_POINTS THEN ASM_MESON_TAC[]);; + +let CONVEX_IMP_CONTRACTIBLE = prove + (`!s:real^N->bool. convex s ==> contractible s`, + MESON_TAC[CONVEX_IMP_STARLIKE; CONTRACTIBLE_EMPTY; + STARLIKE_IMP_CONTRACTIBLE]);; + +let CONTRACTIBLE_SING = prove + (`!a:real^N. contractible {a}`, + SIMP_TAC[CONVEX_IMP_CONTRACTIBLE; CONVEX_SING]);; + +let IS_INTERVAL_CONTRACTIBLE_1 = prove + (`!s:real^1->bool. is_interval s <=> contractible s`, + MESON_TAC[CONTRACTIBLE_IMP_PATH_CONNECTED; IS_INTERVAL_PATH_CONNECTED_1; + CONVEX_IMP_CONTRACTIBLE; IS_INTERVAL_CONVEX_1]);; + +let CONTRACTIBLE_PCROSS = prove + (`!s:real^M->bool t:real^N->bool. + contractible s /\ contractible t ==> contractible(s PCROSS t)`, + REPEAT GEN_TAC THEN REWRITE_TAC[contractible; homotopic_with] THEN + REWRITE_TAC[IMP_CONJ; LEFT_IMP_EXISTS_THM] THEN + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; FORALL_IN_PCROSS] THEN + MAP_EVERY X_GEN_TAC [`a:real^M`; `h:real^(1,M)finite_sum->real^M`] THEN + REPEAT DISCH_TAC THEN + MAP_EVERY X_GEN_TAC [`b:real^N`; `k:real^(1,N)finite_sum->real^N`] THEN + REPEAT DISCH_TAC THEN + EXISTS_TAC `pastecart (a:real^M) (b:real^N)` THEN + EXISTS_TAC `\z. pastecart + ((h:real^(1,M)finite_sum->real^M) + (pastecart (fstcart z) (fstcart(sndcart z)))) + ((k:real^(1,N)finite_sum->real^N) + (pastecart (fstcart z) (sndcart(sndcart z))))` THEN + ASM_SIMP_TAC[FORALL_IN_IMAGE; FORALL_PASTECART; PASTECART_IN_PCROSS; + FSTCART_PASTECART; SNDCART_PASTECART] THEN + MATCH_MP_TAC CONTINUOUS_ON_PASTECART THEN CONJ_TAC THEN + GEN_REWRITE_TAC LAND_CONV [GSYM o_DEF] THEN + MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN + SIMP_TAC[CONTINUOUS_ON_PASTECART; LINEAR_CONTINUOUS_ON; + LINEAR_FSTCART; LINEAR_SNDCART; CONTINUOUS_ON_ID; + GSYM o_DEF; CONTINUOUS_ON_COMPOSE] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET)) THEN + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; FORALL_PASTECART] THEN + SIMP_TAC[PASTECART_IN_PCROSS; FSTCART_PASTECART; SNDCART_PASTECART]);; + +let CONTRACTIBLE_PCROSS_EQ = prove + (`!s:real^M->bool t:real^N->bool. + contractible(s PCROSS t) <=> + s = {} \/ t = {} \/ contractible s /\ contractible t`, + REPEAT GEN_TAC THEN + ASM_CASES_TAC `s:real^M->bool = {}` THEN + ASM_REWRITE_TAC[PCROSS_EMPTY; CONTRACTIBLE_EMPTY] THEN + ASM_CASES_TAC `t:real^N->bool = {}` THEN + ASM_REWRITE_TAC[PCROSS_EMPTY; CONTRACTIBLE_EMPTY] THEN + EQ_TAC THEN REWRITE_TAC[CONTRACTIBLE_PCROSS] THEN + REWRITE_TAC[contractible; homotopic_with; LEFT_IMP_EXISTS_THM] THEN + SIMP_TAC[SUBSET; FORALL_IN_IMAGE; FORALL_PASTECART; PASTECART_IN_PCROSS] THEN + MAP_EVERY X_GEN_TAC + [`a:real^M`; `b:real^N`; + `h:real^(1,(M,N)finite_sum)finite_sum->real^(M,N)finite_sum`] THEN + STRIP_TAC THEN + SUBGOAL_THEN `(a:real^M) IN s /\ (b:real^N) IN t` STRIP_ASSUME_TAC THENL + [REWRITE_TAC[GSYM PASTECART_IN_PCROSS] THEN + RULE_ASSUM_TAC(REWRITE_RULE[GSYM MEMBER_NOT_EMPTY]) THEN + ASM_MESON_TAC[ENDS_IN_UNIT_INTERVAL]; + ALL_TAC] THEN + CONJ_TAC THENL + [EXISTS_TAC `a:real^M` THEN + EXISTS_TAC + `fstcart o + (h:real^(1,(M,N)finite_sum)finite_sum->real^(M,N)finite_sum) o + (\z. pastecart (fstcart z) (pastecart (sndcart z) b))`; + EXISTS_TAC `b:real^N` THEN + EXISTS_TAC + `sndcart o + (h:real^(1,(M,N)finite_sum)finite_sum->real^(M,N)finite_sum) o + (\z. pastecart (fstcart z) (pastecart a (sndcart z)))`] THEN + ASM_REWRITE_TAC[o_THM; FSTCART_PASTECART; SNDCART_PASTECART; + SUBSET; FORALL_IN_IMAGE; FORALL_IN_PCROSS; o_THM] THEN + (CONJ_TAC THENL + [ALL_TAC; ASM_MESON_TAC[PASTECART_FST_SND; PASTECART_IN_PCROSS]]) THEN + MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN + SIMP_TAC[LINEAR_CONTINUOUS_ON; LINEAR_FSTCART; LINEAR_SNDCART] THEN + MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN + SIMP_TAC[CONTINUOUS_ON_PASTECART; CONTINUOUS_ON_CONST; + LINEAR_CONTINUOUS_ON; LINEAR_FSTCART; LINEAR_SNDCART] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET)) THEN + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; FORALL_IN_PCROSS] THEN + ASM_SIMP_TAC[FSTCART_PASTECART; SNDCART_PASTECART; PASTECART_IN_PCROSS]);; + +let HOMOTOPY_EQUIVALENT_EMPTY = prove + (`(!s. (s:real^M->bool) homotopy_equivalent ({}:real^N->bool) <=> s = {}) /\ + (!t. ({}:real^M->bool) homotopy_equivalent (t:real^N->bool) <=> t = {})`, + REPEAT STRIP_TAC THEN EQ_TAC THEN + SIMP_TAC[HOMOTOPY_EQUIVALENT_CONTRACTIBLE_SETS; CONTRACTIBLE_EMPTY] THEN + REWRITE_TAC[homotopy_equivalent] THEN SET_TAC[]);; + +let HOMOTOPY_EQUIVALENT_CONTRACTIBILITY = prove + (`!s:real^M->bool t:real^N->bool. + s homotopy_equivalent t ==> (contractible s <=> contractible t)`, + let lemma = prove + (`!s:real^M->bool t:real^N->bool. + s homotopy_equivalent t /\ contractible s ==> contractible t`, + REPEAT GEN_TAC THEN SIMP_TAC[homotopy_equivalent; contractible; I_DEF] THEN + DISCH_THEN(CONJUNCTS_THEN2 + (X_CHOOSE_THEN `f:real^M->real^N` (X_CHOOSE_THEN `g:real^N->real^M` + STRIP_ASSUME_TAC)) + (X_CHOOSE_TAC `a:real^M`)) THEN + MP_TAC(ISPECL [`f:real^M->real^N`; `s:real^M->bool`; `t:real^N->bool`] + NULLHOMOTOPIC_FROM_CONTRACTIBLE) THEN + ASM_REWRITE_TAC[contractible; I_DEF] THEN + ANTS_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `b:real^N` THEN + ONCE_REWRITE_TAC[HOMOTOPIC_WITH_SYM] THEN DISCH_TAC THEN + MATCH_MP_TAC HOMOTOPIC_WITH_TRANS THEN + EXISTS_TAC `(f:real^M->real^N) o (g:real^N->real^M)` THEN + ASM_REWRITE_TAC[] THEN + SUBGOAL_THEN `(\x. (b:real^N)) = (\x. b) o (g:real^N->real^M)` + SUBST1_TAC THENL [REWRITE_TAC[o_DEF]; ALL_TAC] THEN + MATCH_MP_TAC HOMOTOPIC_WITH_COMPOSE_CONTINUOUS_RIGHT THEN + EXISTS_TAC `s:real^M->bool` THEN ASM_REWRITE_TAC[]) in + REPEAT STRIP_TAC THEN EQ_TAC THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] lemma) THEN + ASM_MESON_TAC[HOMOTOPY_EQUIVALENT_SYM]);; + +let HOMOTOPY_EQUIVALENT_SING = prove + (`!s:real^M->bool a:real^N. + s homotopy_equivalent {a} <=> ~(s = {}) /\ contractible s`, + REPEAT GEN_TAC THEN ASM_CASES_TAC `s:real^M->bool = {}` THEN + ASM_REWRITE_TAC[HOMOTOPY_EQUIVALENT_EMPTY; NOT_INSERT_EMPTY] THEN + EQ_TAC THENL + [DISCH_THEN(MP_TAC o MATCH_MP HOMOTOPY_EQUIVALENT_CONTRACTIBILITY) THEN + REWRITE_TAC[CONTRACTIBLE_SING]; + DISCH_TAC THEN MATCH_MP_TAC HOMOTOPY_EQUIVALENT_CONTRACTIBLE_SETS THEN + ASM_REWRITE_TAC[CONTRACTIBLE_SING; NOT_INSERT_EMPTY]]);; + +let HOMEOMORPHIC_CONTRACTIBLE_EQ = prove + (`!s:real^M->bool t:real^N->bool. + s homeomorphic t ==> (contractible s <=> contractible t)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC HOMOTOPY_EQUIVALENT_CONTRACTIBILITY THEN + ASM_SIMP_TAC[HOMEOMORPHIC_IMP_HOMOTOPY_EQUIVALENT]);; + +let HOMEOMORPHIC_CONTRACTIBLE = prove + (`!s:real^M->bool t:real^N->bool. + s homeomorphic t /\ contractible s ==> contractible t`, + MESON_TAC[HOMEOMORPHIC_CONTRACTIBLE_EQ]);; + +let CONTRACTIBLE_TRANSLATION = prove + (`!a:real^N s. contractible (IMAGE (\x. a + x) s) <=> contractible s`, + REPEAT GEN_TAC THEN MATCH_MP_TAC HOMEOMORPHIC_CONTRACTIBLE_EQ THEN + ONCE_REWRITE_TAC[HOMEOMORPHIC_SYM] THEN + REWRITE_TAC[HOMEOMORPHIC_TRANSLATION]);; + +add_translation_invariants [CONTRACTIBLE_TRANSLATION];; + +let CONTRACTIBLE_INJECTIVE_LINEAR_IMAGE = prove + (`!f:real^M->real^N s. + linear f /\ (!x y. f x = f y ==> x = y) + ==> (contractible (IMAGE f s) <=> contractible s)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC HOMEOMORPHIC_CONTRACTIBLE_EQ THEN + ASM_MESON_TAC[HOMEOMORPHIC_INJECTIVE_LINEAR_IMAGE_LEFT_EQ; + HOMEOMORPHIC_REFL]);; + +add_linear_invariants [CONTRACTIBLE_INJECTIVE_LINEAR_IMAGE];; + +(* ------------------------------------------------------------------------- *) +(* Homeomorphisms between punctured spheres and affine sets. *) +(* ------------------------------------------------------------------------- *) + +let HOMEOMORPHIC_PUNCTURED_AFFINE_SPHERE_AFFINE = prove + (`!a r b t:real^N->bool p:real^M->bool. + &0 < r /\ b IN sphere(a,r) /\ affine t /\ a IN t /\ b IN t /\ + affine p /\ aff_dim t = aff_dim p + &1 + ==> ((sphere(a:real^N,r) INTER t) DELETE b) homeomorphic p`, + GEOM_ORIGIN_TAC `a:real^N` THEN REWRITE_TAC[INSERT_SUBSET; EMPTY_SUBSET] THEN + REWRITE_TAC[sphere; DIST_0; IN_ELIM_THM] THEN + SIMP_TAC[CONJ_ASSOC; NORM_ARITH + `&0 < r /\ norm(b:real^N) = r <=> norm(b) = r /\ ~(b = vec 0)`] THEN + GEOM_NORMALIZE_TAC `b:real^N` THEN REWRITE_TAC[] THEN + GEOM_BASIS_MULTIPLE_TAC 1 `b:real^N` THEN + SIMP_TAC[NORM_MUL; real_abs; NORM_BASIS; LE_REFL; DIMINDEX_GE_1] THEN + X_GEN_TAC `b:real` THEN REWRITE_TAC[REAL_MUL_RID; VECTOR_MUL_EQ_0] THEN + DISCH_THEN(K ALL_TAC) THEN DISCH_THEN SUBST1_TAC THEN + REPEAT GEN_TAC THEN REWRITE_TAC[VECTOR_MUL_LID] THEN + ASM_CASES_TAC `r = &1` THEN ASM_REWRITE_TAC[] THEN POP_ASSUM(K ALL_TAC) THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN + SIMP_TAC[BASIS_NONZERO; DIMINDEX_GE_1; LE_REFL] THEN STRIP_TAC THEN + SUBGOAL_THEN `subspace(t:real^N->bool)` ASSUME_TAC THENL + [ASM_MESON_TAC[AFFINE_EQ_SUBSPACE]; ALL_TAC] THEN + TRANS_TAC HOMEOMORPHIC_TRANS `{x:real^N | x$1 = &0} INTER t` THEN + CONJ_TAC THENL + [ALL_TAC; + MATCH_MP_TAC HOMEOMORPHIC_AFFINE_SETS THEN + ASM_SIMP_TAC[AFFINE_INTER; AFFINE_STANDARD_HYPERPLANE] THEN + ONCE_REWRITE_TAC[INTER_COMM] THEN + MP_TAC(ISPECL [`basis 1:real^N`; `&0`; `t:real^N->bool`] + AFF_DIM_AFFINE_INTER_HYPERPLANE) THEN + ASM_SIMP_TAC[DOT_BASIS; DIMINDEX_GE_1; LE_REFL] THEN + DISCH_THEN SUBST1_TAC THEN + SUBGOAL_THEN `~(t INTER {x:real^N | x$1 = &0} = {})` ASSUME_TAC THENL + [REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; IN_INTER; IN_ELIM_THM] THEN + EXISTS_TAC `vec 0:real^N` THEN ASM_REWRITE_TAC[VEC_COMPONENT]; + ALL_TAC] THEN + SUBGOAL_THEN `~(t SUBSET {v:real^N | v$1 = &0})` ASSUME_TAC THENL + [REWRITE_TAC[SUBSET] THEN DISCH_THEN(MP_TAC o SPEC `basis 1:real^N`) THEN + ASM_SIMP_TAC[IN_ELIM_THM; BASIS_COMPONENT; DIMINDEX_GE_1; LE_REFL] THEN + REAL_ARITH_TAC; + ASM_REWRITE_TAC[] THEN INT_ARITH_TAC]] THEN + SUBGOAL_THEN + `({x:real^N | norm x = &1} INTER t) DELETE (basis 1) = + {x | norm x = &1 /\ ~(x$1 = &1)} INTER t` + SUBST1_TAC THENL + [MATCH_MP_TAC(SET_RULE + `s DELETE a = s' ==> (s INTER t) DELETE a = s' INTER t`) THEN + MATCH_MP_TAC(SET_RULE + `Q a /\ (!x. P x /\ Q x ==> x = a) + ==> {x | P x} DELETE a = {x | P x /\ ~Q x}`) THEN + SIMP_TAC[BASIS_COMPONENT; CART_EQ; DIMINDEX_GE_1; LE_REFL] THEN + REWRITE_TAC[NORM_EQ_SQUARE; REAL_POS; REAL_POW_ONE] THEN + X_GEN_TAC `x:real^N` THEN + DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN + ASM_SIMP_TAC[dot; SUM_CLAUSES_LEFT; DIMINDEX_GE_1] THEN + REWRITE_TAC[REAL_ARITH `&1 * &1 + s = &1 <=> s = &0`] THEN + DISCH_THEN(MP_TAC o MATCH_MP (ONCE_REWRITE_RULE[IMP_CONJ_ALT] + SUM_POS_EQ_0_NUMSEG)) THEN + REWRITE_TAC[REAL_LE_SQUARE; REAL_ENTIRE] THEN + REPEAT STRIP_TAC THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_ARITH_TAC; + ALL_TAC] THEN + REWRITE_TAC[homeomorphic; HOMEOMORPHISM] THEN MAP_EVERY ABBREV_TAC + [`f = \x:real^N. &2 % basis 1 + &2 / (&1 - x$1) % (x - basis 1)`; + `g = \y:real^N. + basis 1 + &4 / (norm y pow 2 + &4) % (y - &2 % basis 1)`] THEN + MAP_EVERY EXISTS_TAC [`f:real^N->real^N`; `g:real^N->real^N`] THEN + REPEAT CONJ_TAC THENL + [MATCH_MP_TAC(MESON[CONTINUOUS_ON_SUBSET; INTER_SUBSET] + `f continuous_on s ==> f continuous_on (s INTER t)`) THEN + EXPAND_TAC "f" THEN MATCH_MP_TAC CONTINUOUS_ON_ADD THEN + REWRITE_TAC[CONTINUOUS_ON_CONST] THEN + MATCH_MP_TAC CONTINUOUS_ON_MUL THEN + SIMP_TAC[CONTINUOUS_ON_SUB; CONTINUOUS_ON_CONST; CONTINUOUS_ON_ID] THEN + REWRITE_TAC[o_DEF; real_div; LIFT_CMUL] THEN + MATCH_MP_TAC CONTINUOUS_ON_CMUL THEN + MATCH_MP_TAC(REWRITE_RULE[o_DEF] CONTINUOUS_ON_INV) THEN + SIMP_TAC[REAL_SUB_0; IN_ELIM_THM] THEN + REWRITE_TAC[LIFT_SUB] THEN MATCH_MP_TAC CONTINUOUS_ON_SUB THEN + REWRITE_TAC[CONTINUOUS_ON_CONST] THEN + MATCH_MP_TAC CONTINUOUS_ON_LIFT_COMPONENT THEN + REWRITE_TAC[LE_REFL; DIMINDEX_GE_1]; + MATCH_MP_TAC(SET_RULE + `IMAGE f s SUBSET s' /\ IMAGE f t SUBSET t + ==> IMAGE f (s INTER t) SUBSET (s' INTER t)`) THEN + EXPAND_TAC "f" THEN REWRITE_TAC[SUBSET; FORALL_IN_IMAGE] THEN + ASM_SIMP_TAC[SUBSPACE_ADD; SUBSPACE_MUL; SUBSPACE_SUB] THEN + REWRITE_TAC[IN_ELIM_THM; IN_DELETE] THEN + SIMP_TAC[VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT; BASIS_COMPONENT; + LE_REFL; DIMINDEX_GE_1; VECTOR_SUB_COMPONENT] THEN + CONV_TAC REAL_FIELD; + MATCH_MP_TAC(MESON[CONTINUOUS_ON_SUBSET; INTER_SUBSET] + `f continuous_on s ==> f continuous_on (s INTER t)`) THEN + EXPAND_TAC "g" THEN MATCH_MP_TAC CONTINUOUS_ON_ADD THEN + REWRITE_TAC[CONTINUOUS_ON_CONST] THEN + MATCH_MP_TAC CONTINUOUS_ON_MUL THEN + SIMP_TAC[CONTINUOUS_ON_SUB; CONTINUOUS_ON_CONST; CONTINUOUS_ON_ID] THEN + REWRITE_TAC[o_DEF; real_div; LIFT_CMUL] THEN + MATCH_MP_TAC CONTINUOUS_ON_CMUL THEN + MATCH_MP_TAC(REWRITE_RULE[o_DEF] CONTINUOUS_ON_INV) THEN + SIMP_TAC[LIFT_ADD; REAL_POW_LE; NORM_POS_LE; REAL_ARITH + `&0 <= x ==> ~(x + &4 = &0)`] THEN + MATCH_MP_TAC CONTINUOUS_ON_ADD THEN + REWRITE_TAC[REAL_POW_2; LIFT_CMUL; CONTINUOUS_ON_CONST] THEN + MATCH_MP_TAC CONTINUOUS_ON_MUL THEN + REWRITE_TAC[CONTINUOUS_ON_LIFT_NORM; GSYM o_DEF]; + MATCH_MP_TAC(SET_RULE + `IMAGE f s SUBSET s' /\ IMAGE f t SUBSET t + ==> IMAGE f (s INTER t) SUBSET (s' INTER t)`) THEN + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; IN_ELIM_THM] THEN + REWRITE_TAC[NORM_EQ_SQUARE; REAL_POS] THEN EXPAND_TAC "g" THEN + CONJ_TAC THENL + [ALL_TAC; ASM_MESON_TAC[SUBSPACE_ADD; SUBSPACE_MUL; SUBSPACE_SUB]] THEN + X_GEN_TAC `y:real^N` THEN DISCH_TAC THEN + REWRITE_TAC[VECTOR_ARITH + `b + a % (y - &2 % b):real^N = (&1 - &2 * a) % b + a % y`] THEN + REWRITE_TAC[NORM_POW_2; VECTOR_ARITH + `(a + b:real^N) dot (a + b) = (a dot a + b dot b) + &2 * a dot b`] THEN + ASM_SIMP_TAC[DOT_LMUL; DOT_RMUL; DOT_BASIS; BASIS_COMPONENT; LE_REFL; + VECTOR_ADD_COMPONENT; DIMINDEX_GE_1; VECTOR_MUL_COMPONENT] THEN + REWRITE_TAC[REAL_MUL_RZERO; REAL_MUL_RID; GSYM REAL_POW_2] THEN + SUBGOAL_THEN `~((y:real^N) dot y + &4 = &0)` MP_TAC THENL + [MESON_TAC[DOT_POS_LE; REAL_ARITH `&0 <= x ==> ~(x + &4 = &0)`]; + CONV_TAC REAL_FIELD]; + SUBGOAL_THEN + `!x. norm x = &1 /\ ~(x$1 = &1) + ==> norm((f:real^N->real^N) x) pow 2 = &4 * (&1 + x$1) / (&1 - x$1)` + ASSUME_TAC THENL + [REPEAT STRIP_TAC THEN EXPAND_TAC "f" THEN + REWRITE_TAC[VECTOR_ARITH + `a % b + m % (x - b):real^N = (a - m) % b + m % x`] THEN + REWRITE_TAC[NORM_POW_2; VECTOR_ARITH + `(a + b:real^N) dot (a + b) = (a dot a + b dot b) + &2 * a dot b`] THEN + SIMP_TAC[DOT_LMUL; DOT_RMUL; DOT_BASIS; BASIS_COMPONENT; + DIMINDEX_GE_1; LE_REFL; VECTOR_MUL_COMPONENT] THEN + ASM_REWRITE_TAC[GSYM NORM_POW_2; GSYM REAL_POW_2; REAL_MUL_RID; + REAL_POW_ONE] THEN + UNDISCH_TAC `~((x:real^N)$1 = &1)` THEN CONV_TAC REAL_FIELD; + ALL_TAC] THEN + EXPAND_TAC "g" THEN REWRITE_TAC[IN_INTER; IN_ELIM_THM] THEN + ASM_SIMP_TAC[] THEN X_GEN_TAC `x:real^N` THEN STRIP_TAC THEN + ASM_SIMP_TAC[REAL_FIELD + `~(x = &1) + ==> &4 * (&1 + x) / (&1 - x) + &4 = &8 / (&1 - x)`] THEN + REWRITE_TAC[real_div; REAL_INV_MUL; REAL_INV_INV] THEN + REWRITE_TAC[REAL_ARITH `&4 * inv(&8) * x = x / &2`] THEN + EXPAND_TAC "f" THEN + REWRITE_TAC[VECTOR_ARITH `(a + x) - a:real^N = x`] THEN + REWRITE_TAC[VECTOR_MUL_ASSOC; VECTOR_ARITH + `b + a % (x - b):real^N = x <=> (&1 - a) % (x - b) = vec 0`] THEN + REWRITE_TAC[VECTOR_MUL_EQ_0] THEN DISJ1_TAC THEN + UNDISCH_TAC `~((x:real^N)$1 = &1)` THEN CONV_TAC REAL_FIELD; + X_GEN_TAC `y:real^N` THEN REWRITE_TAC[IN_INTER; IN_ELIM_THM] THEN + DISCH_TAC THEN + SUBGOAL_THEN `~((y:real^N) dot y + &4 = &0)` ASSUME_TAC THENL + [MESON_TAC[DOT_POS_LE; REAL_ARITH `&0 <= x ==> ~(x + &4 = &0)`]; + ALL_TAC] THEN + SUBGOAL_THEN `((g:real^N->real^N) y)$1 = + (y dot y - &4) / (y dot y + &4)` ASSUME_TAC THENL + [EXPAND_TAC "g" THEN REWRITE_TAC[VECTOR_ADD_COMPONENT] THEN + REWRITE_TAC[VECTOR_MUL_COMPONENT; VECTOR_SUB_COMPONENT] THEN + ASM_SIMP_TAC[BASIS_COMPONENT; LE_REFL; NORM_POW_2; DIMINDEX_GE_1] THEN + UNDISCH_TAC `~((y:real^N) dot y + &4 = &0)` THEN + CONV_TAC REAL_FIELD; + ALL_TAC] THEN + EXPAND_TAC "f" THEN REWRITE_TAC[] THEN ASM_REWRITE_TAC[] THEN + EXPAND_TAC "g" THEN SIMP_TAC[VECTOR_ARITH `(a + x) - a:real^N = x`] THEN + REWRITE_TAC[VECTOR_MUL_ASSOC; VECTOR_ARITH + `b + a % (x - b):real^N = x <=> (&1 - a) % (x - b) = vec 0`] THEN + REWRITE_TAC[VECTOR_MUL_EQ_0; NORM_POW_2] THEN DISJ1_TAC THEN + UNDISCH_TAC `~((y:real^N) dot y + &4 = &0)` THEN CONV_TAC REAL_FIELD]);; + +let HOMEOMORPHIC_PUNCTURED_SPHERE_AFFINE_GEN = prove + (`!s:real^N->bool t:real^M->bool a. + convex s /\ bounded s /\ a IN relative_frontier s /\ + affine t /\ aff_dim s = aff_dim t + &1 + ==> (relative_frontier s DELETE a) homeomorphic t`, + REPEAT GEN_TAC THEN ASM_CASES_TAC `s:real^N->bool = {}` THEN + ASM_SIMP_TAC[AFF_DIM_EMPTY; AFF_DIM_GE; INT_ARITH + `--(&1):int <= s ==> ~(--(&1) = s + &1)`] THEN + MP_TAC(ISPECL [`(:real^N)`; `aff_dim(s:real^N->bool)`] + CHOOSE_AFFINE_SUBSET) THEN REWRITE_TAC[SUBSET_UNIV] THEN + REWRITE_TAC[AFF_DIM_GE; AFF_DIM_LE_UNIV; AFF_DIM_UNIV; AFFINE_UNIV] THEN + DISCH_THEN(X_CHOOSE_THEN `t:real^N->bool` STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN `~(t:real^N->bool = {})` MP_TAC THENL + [ASM_MESON_TAC[AFF_DIM_EQ_MINUS1]; ALL_TAC] THEN + GEN_REWRITE_TAC LAND_CONV [GSYM MEMBER_NOT_EMPTY] THEN + DISCH_THEN(X_CHOOSE_TAC `z:real^N`) THEN STRIP_TAC THEN + MP_TAC(ISPECL + [`s:real^N->bool`; `ball(z:real^N,&1) INTER t`] + HOMEOMORPHIC_RELATIVE_FRONTIERS_CONVEX_BOUNDED_SETS) THEN + MP_TAC(ISPECL [`t:real^N->bool`; `ball(z:real^N,&1)`] + (ONCE_REWRITE_RULE[INTER_COMM] AFF_DIM_CONVEX_INTER_OPEN)) THEN + MP_TAC(ISPECL [`ball(z:real^N,&1)`; `t:real^N->bool`] + RELATIVE_FRONTIER_CONVEX_INTER_AFFINE) THEN + ASM_SIMP_TAC[CONVEX_INTER; BOUNDED_INTER; BOUNDED_BALL; CONVEX_BALL; + AFFINE_IMP_CONVEX; INTERIOR_OPEN; OPEN_BALL; + FRONTIER_BALL; REAL_LT_01] THEN + SUBGOAL_THEN `~(ball(z:real^N,&1) INTER t = {})` ASSUME_TAC THENL + [REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; IN_INTER] THEN + EXISTS_TAC `z:real^N` THEN ASM_REWRITE_TAC[CENTRE_IN_BALL; REAL_LT_01]; + ASM_REWRITE_TAC[] THEN REPEAT(DISCH_THEN SUBST1_TAC) THEN SIMP_TAC[]] THEN + REWRITE_TAC[homeomorphic; LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`h:real^N->real^N`; `k:real^N->real^N`] THEN + STRIP_TAC THEN REWRITE_TAC[GSYM homeomorphic] THEN + TRANS_TAC HOMEOMORPHIC_TRANS + `(sphere(z,&1) INTER t) DELETE (h:real^N->real^N) a` THEN + CONJ_TAC THENL + [REWRITE_TAC[homeomorphic] THEN + MAP_EVERY EXISTS_TAC [`h:real^N->real^N`; `k:real^N->real^N`] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [HOMEOMORPHISM]) THEN + REWRITE_TAC[HOMEOMORPHISM] THEN STRIP_TAC THEN REPEAT CONJ_TAC THENL + [ASM_MESON_TAC[CONTINUOUS_ON_SUBSET; DELETE_SUBSET]; + ASM SET_TAC[]; + ASM_MESON_TAC[CONTINUOUS_ON_SUBSET; DELETE_SUBSET]; + ASM SET_TAC[]; + ASM SET_TAC[]; + ASM SET_TAC[]]; + MATCH_MP_TAC HOMEOMORPHIC_PUNCTURED_AFFINE_SPHERE_AFFINE THEN + ASM_REWRITE_TAC[REAL_LT_01; GSYM IN_INTER] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [HOMEOMORPHISM]) THEN + ASM SET_TAC[]]);; + +let HOMEOMORPHIC_PUNCTURED_SPHERE_AFFINE = prove + (`!a r b:real^N t:real^M->bool. + &0 < r /\ b IN sphere(a,r) /\ affine t /\ aff_dim(t) + &1 = &(dimindex(:N)) + ==> (sphere(a:real^N,r) DELETE b) homeomorphic t`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`cball(a:real^N,r)`; `t:real^M->bool`; `b:real^N`] + HOMEOMORPHIC_PUNCTURED_SPHERE_AFFINE_GEN) THEN + ASM_SIMP_TAC[RELATIVE_FRONTIER_CBALL; REAL_LT_IMP_NZ; AFF_DIM_CBALL; + CONVEX_CBALL; BOUNDED_CBALL]);; + +let HOMEOMORPHIC_PUNCTURED_SPHERE_HYPERPLANE = prove + (`!a r b c d. + &0 < r /\ b IN sphere(a,r) /\ ~(c = vec 0) + ==> (sphere(a:real^N,r) DELETE b) homeomorphic + {x:real^N | c dot x = d}`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC HOMEOMORPHIC_PUNCTURED_SPHERE_AFFINE THEN + ASM_SIMP_TAC[AFFINE_HYPERPLANE; AFF_DIM_HYPERPLANE] THEN INT_ARITH_TAC);; + +let HOMEOMORPHIC_PUNCTURED_SPHERE_UNIV = prove + (`!a r b. + &0 < r /\ b IN sphere(a,r) /\ dimindex(:N) = dimindex(:M) + 1 + ==> (sphere(a:real^N,r) DELETE b) homeomorphic (:real^M)`, + REPEAT STRIP_TAC THEN + TRANS_TAC HOMEOMORPHIC_TRANS `{x:real^N | basis 1 dot x = &0}` THEN + ASM_SIMP_TAC[HOMEOMORPHIC_HYPERPLANE_UNIV; BASIS_NONZERO; LE_REFL; + DIMINDEX_GE_1; HOMEOMORPHIC_PUNCTURED_SPHERE_HYPERPLANE]);; + +let CONTRACTIBLE_PUNCTURED_SPHERE = prove + (`!a r b:real^N. + &0 < r /\ b IN sphere(a,r) ==> contractible(sphere(a,r) DELETE b)`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN `contractible {x:real^N | basis 1 dot x = &0}` MP_TAC THENL + [SIMP_TAC[CONVEX_IMP_CONTRACTIBLE; CONVEX_HYPERPLANE]; + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] HOMEOMORPHIC_CONTRACTIBLE) THEN + ONCE_REWRITE_TAC[HOMEOMORPHIC_SYM] THEN + MATCH_MP_TAC HOMEOMORPHIC_PUNCTURED_SPHERE_HYPERPLANE THEN + ASM_SIMP_TAC[BASIS_NONZERO; LE_REFL; DIMINDEX_GE_1]]);; + +(* ------------------------------------------------------------------------- *) +(* Simple connectedness of a union. This is essentially a stripped-down *) +(* version of the Seifert - Van Kampen theorem. *) +(* ------------------------------------------------------------------------- *) + +let SIMPLY_CONNECTED_UNION = prove + (`!s t:real^N->bool. + open_in (subtopology euclidean (s UNION t)) s /\ + open_in (subtopology euclidean (s UNION t)) t /\ + simply_connected s /\ simply_connected t /\ + path_connected (s INTER t) /\ ~(s INTER t = {}) + ==> simply_connected (s UNION t)`, + REPEAT GEN_TAC THEN REWRITE_TAC[OPEN_IN_OPEN] THEN + DISCH_THEN(CONJUNCTS_THEN2 (X_CHOOSE_THEN `u:real^N->bool` + (STRIP_ASSUME_TAC o GSYM)) MP_TAC) THEN + DISCH_THEN(CONJUNCTS_THEN2 (X_CHOOSE_THEN `v:real^N->bool` + (STRIP_ASSUME_TAC o GSYM)) MP_TAC) THEN + SIMP_TAC[SIMPLY_CONNECTED_EQ_CONTRACTIBLE_PATH; PATH_CONNECTED_UNION] THEN + REPEAT STRIP_TAC THEN + SUBGOAL_THEN `(pathstart p:real^N) IN s UNION t` MP_TAC THENL + [ASM_MESON_TAC[PATHSTART_IN_PATH_IMAGE; SUBSET]; REWRITE_TAC[IN_UNION]] THEN + POP_ASSUM_LIST(MP_TAC o end_itlist CONJ o rev) THEN + ONCE_REWRITE_TAC[TAUT `p ==> q ==> r <=> q ==> p ==> r`] THEN + MAP_EVERY (fun s -> let x = mk_var(s,`:real^N->bool`) in SPEC_TAC(x,x)) + ["v"; "u"; "t"; "s"] THEN + MATCH_MP_TAC(MESON[] + `(!s t u v. x IN s ==> P x s t u v) /\ + (!x s t u v. P x s t u v ==> P x t s v u) + ==> (!s t u v. x IN s \/ x IN t ==> P x s t u v)`) THEN + CONJ_TAC THENL + [REPEAT STRIP_TAC; + REPEAT GEN_TAC THEN REWRITE_TAC[UNION_COMM; INTER_COMM] THEN + MATCH_MP_TAC MONO_IMP THEN SIMP_TAC[]] THEN + SUBGOAL_THEN + `?e. &0 < e /\ + !x y. x IN interval[vec 0,vec 1] /\ y IN interval[vec 0,vec 1] /\ + norm(x - y) < e + ==> path_image(subpath x y p) SUBSET (s:real^N->bool) \/ + path_image(subpath x y p) SUBSET t` + STRIP_ASSUME_TAC THENL + [MP_TAC(ISPEC `path_image(p:real^1->real^N)` HEINE_BOREL_LEMMA) THEN + ASM_SIMP_TAC[COMPACT_PATH_IMAGE] THEN + DISCH_THEN(MP_TAC o SPEC `{u:real^N->bool,v}`) THEN + SIMP_TAC[UNIONS_2; EXISTS_IN_INSERT; FORALL_IN_INSERT; NOT_IN_EMPTY] THEN + ANTS_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + DISCH_THEN(X_CHOOSE_THEN `e:real` STRIP_ASSUME_TAC) THEN + MP_TAC(ISPECL [`p:real^1->real^N`; `interval[vec 0:real^1,vec 1]`] + COMPACT_UNIFORMLY_CONTINUOUS) THEN + ASM_REWRITE_TAC[GSYM path; COMPACT_INTERVAL; uniformly_continuous_on] THEN + DISCH_THEN(MP_TAC o SPEC `e:real`) THEN ASM_REWRITE_TAC[dist] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `d:real` THEN STRIP_TAC THEN + ASM_REWRITE_TAC[] THEN + MAP_EVERY X_GEN_TAC [`x:real^1`; `y:real^1`] THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `(p:real^1->real^N) x`) THEN + ANTS_TAC THENL [REWRITE_TAC[path_image] THEN ASM SET_TAC[]; ALL_TAC] THEN + MATCH_MP_TAC(SET_RULE + `!p'. p SUBSET b /\ + (s UNION t) INTER u = s /\ (s UNION t) INTER v = t /\ + p SUBSET p' /\ p' SUBSET s UNION t + ==> (b SUBSET u \/ b SUBSET v) ==> p SUBSET s \/ p SUBSET t`) THEN + EXISTS_TAC `path_image(p:real^1->real^N)` THEN + ASM_SIMP_TAC[PATH_IMAGE_SUBPATH_SUBSET] THEN + REWRITE_TAC[PATH_IMAGE_SUBPATH_GEN; SUBSET; FORALL_IN_IMAGE] THEN + SUBGOAL_THEN `segment[x,y] SUBSET ball(x:real^1,d)` MP_TAC THENL + [REWRITE_TAC[SEGMENT_CONVEX_HULL] THEN MATCH_MP_TAC HULL_MINIMAL THEN + ASM_REWRITE_TAC[INSERT_SUBSET; CENTRE_IN_BALL] THEN + ASM_REWRITE_TAC[IN_BALL; EMPTY_SUBSET; CONVEX_BALL; dist]; + REWRITE_TAC[IN_BALL; dist; SUBSET] THEN STRIP_TAC THEN + X_GEN_TAC `z:real^1` THEN DISCH_TAC THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_SIMP_TAC[] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE RAND_CONV [SEGMENT_1]) THEN + REPEAT(FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_INTERVAL_1])) THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[IN_INTERVAL_1; DROP_VEC] THEN + ASM_REAL_ARITH_TAC]; + MP_TAC(SPEC `e:real` REAL_ARCH_INV) THEN + ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `N:num` THEN STRIP_TAC] THEN + SUBGOAL_THEN + `!n. n <= N /\ p(lift(&n / &N)) IN s + ==> ?q. path(q:real^1->real^N) /\ path_image q SUBSET s /\ + homotopic_paths (s UNION t) + (subpath (vec 0) (lift(&n / &N)) p) q` + MP_TAC THENL + [ALL_TAC; + DISCH_THEN(MP_TAC o SPEC `N:num`) THEN + ASM_SIMP_TAC[REAL_DIV_REFL; REAL_OF_NUM_EQ; LE_REFL; LIFT_NUM] THEN + ANTS_TAC THENL [ASM_MESON_TAC[pathfinish]; ALL_TAC] THEN + DISCH_THEN(X_CHOOSE_THEN `q:real^1->real^N` MP_TAC) THEN + REWRITE_TAC[SUBPATH_TRIVIAL] THEN + REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + DISCH_THEN(fun th -> ASSUME_TAC th THEN MP_TAC th) THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] HOMOTOPIC_PATHS_TRANS) THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP HOMOTOPIC_PATHS_IMP_PATHSTART) THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP HOMOTOPIC_PATHS_IMP_PATHFINISH) THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC HOMOTOPIC_PATHS_SUBSET THEN + EXISTS_TAC `s:real^N->bool` THEN + ASM_MESON_TAC[SUBSET_UNION]] THEN + SUBGOAL_THEN + `!n. n < N + ==> path_image(subpath (lift(&n / &N)) (lift(&(SUC n) / &N)) p) + SUBSET (s:real^N->bool) \/ + path_image(subpath (lift(&n / &N)) (lift(&(SUC n) / &N)) p) + SUBSET t` + ASSUME_TAC THENL + [REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + REWRITE_TAC[IN_INTERVAL_1; LIFT_DROP; GSYM LIFT_SUB; DROP_VEC; + NORM_REAL; GSYM drop; + REAL_ARITH `abs(a / c - b / c) = abs((b - a) / c)`] THEN + ASM_SIMP_TAC[GSYM REAL_OF_NUM_SUC; REAL_LE_LDIV_EQ; REAL_LE_RDIV_EQ; + REAL_OF_NUM_LT; LE_1; REAL_ARITH `(x + &1) - x = &1`] THEN + ASM_REWRITE_TAC[real_div; REAL_MUL_LID; REAL_MUL_LZERO; REAL_ABS_INV; + REAL_ABS_NUM; REAL_OF_NUM_ADD; REAL_OF_NUM_LE; REAL_OF_NUM_LT] THEN + ASM_ARITH_TAC; + ALL_TAC] THEN + MATCH_MP_TAC num_WF THEN X_GEN_TAC `n:num` THEN + REWRITE_TAC[IMP_IMP; GSYM CONJ_ASSOC] THEN STRIP_TAC THEN + ASM_CASES_TAC `n = 0` THENL + [ASM_REWRITE_TAC[REAL_ARITH `&0 / x = &0`; LIFT_NUM] THEN + EXISTS_TAC `linepath((p:real^1->real^N)(vec 0),p(vec 0))` THEN + REWRITE_TAC[SUBPATH_REFL; HOMOTOPIC_PATHS_REFL] THEN + REWRITE_TAC[PATH_LINEPATH; PATH_IMAGE_LINEPATH; SEGMENT_REFL] THEN + UNDISCH_TAC `(pathstart p:real^N) IN s` THEN REWRITE_TAC[pathstart] THEN + SET_TAC[]; + ALL_TAC] THEN + MP_TAC(ISPEC `\m. m < n /\ (p(lift(&m / &N)):real^N) IN s` num_MAX) THEN + REWRITE_TAC[] THEN + MATCH_MP_TAC(TAUT `p /\ (q ==> r) ==> (p <=> q) ==> r`) THEN + CONJ_TAC THENL + [CONJ_TAC THENL [EXISTS_TAC `0`; MESON_TAC[LT_IMP_LE]] THEN + ASM_SIMP_TAC[REAL_ARITH `&0 / x = &0`; LIFT_NUM; LE_1] THEN + ASM_MESON_TAC[pathstart]; + DISCH_THEN(X_CHOOSE_THEN `m:num` STRIP_ASSUME_TAC)] THEN + SUBGOAL_THEN + `?q. path q /\ + path_image(q:real^1->real^N) SUBSET s /\ + homotopic_paths (s UNION t) (subpath (vec 0) (lift (&m / &N)) p) q` + STRIP_ASSUME_TAC THENL + [FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[] THEN ASM_ARITH_TAC; + ALL_TAC] THEN + SUBGOAL_THEN + `!i. m < i /\ i <= n + ==> path_image(subpath (lift(&m / &N)) (lift(&i / &N)) p) SUBSET s \/ + path_image(subpath (lift(&m / &N)) (lift(&i / &N)) p) SUBSET + (t:real^N->bool)` + MP_TAC THENL + [MATCH_MP_TAC num_INDUCTION THEN REWRITE_TAC[CONJUNCT1 LT] THEN + X_GEN_TAC `i:num` THEN DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN + ASM_CASES_TAC `i:num = m` THENL + [DISCH_THEN(K ALL_TAC) THEN ASM_REWRITE_TAC[] THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_ARITH_TAC; + ANTS_TAC THENL [ASM_ARITH_TAC; ALL_TAC]] THEN + SUBGOAL_THEN + `p(lift(&i / &N)) IN t /\ ~((p(lift(&i / &N)):real^N) IN s)` + STRIP_ASSUME_TAC THENL + [MATCH_MP_TAC(SET_RULE + `x IN s UNION t /\ ~(x IN s) ==> x IN t /\ ~(x IN s)`) THEN + CONJ_TAC THENL + [FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE + `s SUBSET t ==> x IN s ==> x IN t`)) THEN + REWRITE_TAC[path_image] THEN MATCH_MP_TAC FUN_IN_IMAGE THEN + REWRITE_TAC[IN_INTERVAL_1; DROP_VEC; LIFT_DROP] THEN + ASM_SIMP_TAC[REAL_LE_RDIV_EQ; REAL_LE_LDIV_EQ; REAL_OF_NUM_LT; + LE_1; REAL_MUL_LZERO; REAL_MUL_LID; REAL_OF_NUM_LE] THEN + ASM_ARITH_TAC; + SUBGOAL_THEN `i < n /\ ~(i:num <= m)` MP_TAC THENL + [ASM_ARITH_TAC; ASM_MESON_TAC[]]]; + ALL_TAC] THEN + SUBGOAL_THEN + `path_image(subpath (lift(&i / &N)) (lift (&(SUC i) / &N)) p) SUBSET s \/ + path_image(subpath (lift(&i / &N)) (lift (&(SUC i) / &N)) p) SUBSET + (t:real^N->bool)` + MP_TAC THENL [FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_ARITH_TAC; ALL_TAC] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE + `~(x IN s) + ==> (x IN p /\ x IN q) /\ (q UNION p = r) + ==> p SUBSET s \/ p SUBSET t + ==> q SUBSET s \/ q SUBSET t + ==> r SUBSET s \/ r SUBSET t`)) THEN + SIMP_TAC[PATH_IMAGE_SUBPATH_GEN; FUN_IN_IMAGE; ENDS_IN_SEGMENT] THEN + REWRITE_TAC[GSYM IMAGE_UNION] THEN AP_TERM_TAC THEN + MATCH_MP_TAC UNION_SEGMENT THEN + ASM_SIMP_TAC[SEGMENT_1; LIFT_DROP; REAL_LE_DIV2_EQ; REAL_OF_NUM_LT; + LE_1; REAL_OF_NUM_LE; LT_IMP_LE; IN_INTERVAL_1] THEN + ASM_ARITH_TAC; + DISCH_THEN(MP_TAC o SPEC `n:num`) THEN ASM_REWRITE_TAC[LE_REFL]] THEN + STRIP_TAC THENL + [EXISTS_TAC `(q:real^1->real^N) ++ + subpath (lift(&m / &N)) (lift (&n / &N)) p` THEN + REPEAT CONJ_TAC THENL + [MATCH_MP_TAC PATH_JOIN_IMP THEN + FIRST_ASSUM(MP_TAC o MATCH_MP HOMOTOPIC_PATHS_IMP_PATHFINISH) THEN + ASM_SIMP_TAC[PATHSTART_SUBPATH; PATHFINISH_SUBPATH] THEN + DISCH_TAC THEN MATCH_MP_TAC PATH_SUBPATH THEN + ASM_REWRITE_TAC[IN_INTERVAL_1; DROP_VEC; LIFT_DROP] THEN + ASM_SIMP_TAC[REAL_LE_RDIV_EQ; REAL_LE_LDIV_EQ; REAL_OF_NUM_LT; + LE_1; REAL_MUL_LZERO; REAL_MUL_LID; REAL_OF_NUM_LE] THEN + ASM_ARITH_TAC; + MATCH_MP_TAC SUBSET_PATH_IMAGE_JOIN THEN ASM_REWRITE_TAC[]; + MATCH_MP_TAC HOMOTOPIC_PATHS_TRANS THEN + EXISTS_TAC `subpath (vec 0) (lift(&m / &N)) (p:real^1->real^N) ++ + subpath (lift(&m / &N)) (lift(&n / &N)) p` THEN + CONJ_TAC THENL + [ONCE_REWRITE_TAC[HOMOTOPIC_PATHS_SYM] THEN + MATCH_MP_TAC HOMOTOPIC_JOIN_SUBPATHS THEN + ASM_REWRITE_TAC[ENDS_IN_UNIT_INTERVAL]; + MATCH_MP_TAC HOMOTOPIC_PATHS_JOIN THEN + ASM_REWRITE_TAC[PATHSTART_SUBPATH; PATHFINISH_SUBPATH] THEN + MATCH_MP_TAC HOMOTOPIC_PATHS_SUBSET THEN + EXISTS_TAC `s:real^N->bool` THEN ASM_REWRITE_TAC[SUBSET_UNION] THEN + ASM_REWRITE_TAC[HOMOTOPIC_PATHS_REFL] THEN + MATCH_MP_TAC PATH_SUBPATH] THEN + ASM_REWRITE_TAC[IN_INTERVAL_1; DROP_VEC; LIFT_DROP] THEN + ASM_SIMP_TAC[REAL_LE_RDIV_EQ; REAL_LE_LDIV_EQ; REAL_OF_NUM_LT; + LE_1; REAL_MUL_LZERO; REAL_MUL_LID; REAL_OF_NUM_LE] THEN + ASM_ARITH_TAC]; + SUBGOAL_THEN + `(p(lift(&m / &N)):real^N) IN t /\ (p(lift(&n / &N)):real^N) IN t` + STRIP_ASSUME_TAC THENL + [ASM_MESON_TAC[PATHSTART_IN_PATH_IMAGE; PATHFINISH_IN_PATH_IMAGE; + PATHSTART_SUBPATH; PATHFINISH_SUBPATH; SUBSET]; + ALL_TAC] THEN + UNDISCH_TAC `path_connected(s INTER t:real^N->bool)` THEN + REWRITE_TAC[path_connected] THEN DISCH_THEN(MP_TAC o SPECL + [`p(lift(&m / &N)):real^N`; `p(lift(&n / &N)):real^N`]) THEN + ASM_REWRITE_TAC[IN_INTER; SUBSET_INTER] THEN + DISCH_THEN(X_CHOOSE_THEN `r:real^1->real^N` STRIP_ASSUME_TAC) THEN + UNDISCH_THEN + `!p. path p /\ path_image p SUBSET t /\ pathfinish p:real^N = pathstart p + ==> homotopic_paths t p (linepath (pathstart p,pathstart p))` + (MP_TAC o SPEC `subpath (lift(&m / &N)) (lift(&n / &N)) p ++ + reversepath(r:real^1->real^N)`) THEN + ASM_REWRITE_TAC[PATHSTART_SUBPATH; PATHFINISH_SUBPATH; + PATHSTART_JOIN; PATHFINISH_JOIN; PATHFINISH_REVERSEPATH] THEN + ANTS_TAC THENL + [ASM_SIMP_TAC[SUBSET_PATH_IMAGE_JOIN; PATH_IMAGE_REVERSEPATH] THEN + MATCH_MP_TAC PATH_JOIN_IMP THEN + ASM_SIMP_TAC[PATH_REVERSEPATH; PATHFINISH_SUBPATH; + PATHSTART_REVERSEPATH] THEN + MATCH_MP_TAC PATH_SUBPATH THEN + ASM_REWRITE_TAC[IN_INTERVAL_1; DROP_VEC; LIFT_DROP] THEN + ASM_SIMP_TAC[REAL_LE_RDIV_EQ; REAL_LE_LDIV_EQ; REAL_OF_NUM_LT; + LE_1; REAL_MUL_LZERO; REAL_MUL_LID; REAL_OF_NUM_LE] THEN + ASM_ARITH_TAC; + ALL_TAC] THEN + DISCH_THEN(MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + HOMOTOPIC_PATHS_IMP_HOMOTOPIC_LOOPS)) THEN + ASM_REWRITE_TAC[PATHFINISH_LINEPATH; PATHSTART_SUBPATH; + PATHSTART_JOIN; PATHFINISH_JOIN; PATHFINISH_REVERSEPATH] THEN + DISCH_THEN(MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + HOMOTOPIC_PATHS_LOOP_PARTS)) THEN + FIRST_ASSUM(MP_TAC o MATCH_MP HOMOTOPIC_PATHS_IMP_PATHSTART) THEN + FIRST_ASSUM(MP_TAC o MATCH_MP HOMOTOPIC_PATHS_IMP_PATHFINISH) THEN + REWRITE_TAC[PATHSTART_SUBPATH; PATHFINISH_SUBPATH] THEN + REPLICATE_TAC 2 (DISCH_THEN(ASSUME_TAC o SYM)) THEN + ASM_REWRITE_TAC[] THEN DISCH_TAC THEN + EXISTS_TAC `(q:real^1->real^N) ++ r` THEN + ASM_SIMP_TAC[PATH_JOIN; PATH_IMAGE_JOIN; UNION_SUBSET] THEN + MATCH_MP_TAC HOMOTOPIC_PATHS_TRANS THEN + EXISTS_TAC `subpath (vec 0) (lift(&m / &N)) (p:real^1->real^N) ++ + subpath (lift(&m / &N)) (lift(&n / &N)) p` THEN + CONJ_TAC THENL + [ONCE_REWRITE_TAC[HOMOTOPIC_PATHS_SYM] THEN + MATCH_MP_TAC HOMOTOPIC_JOIN_SUBPATHS THEN + ASM_REWRITE_TAC[ENDS_IN_UNIT_INTERVAL] THEN + ASM_REWRITE_TAC[IN_INTERVAL_1; DROP_VEC; LIFT_DROP] THEN + ASM_SIMP_TAC[REAL_LE_RDIV_EQ; REAL_LE_LDIV_EQ; REAL_OF_NUM_LT; + LE_1; REAL_MUL_LZERO; REAL_MUL_LID; REAL_OF_NUM_LE] THEN + ASM_ARITH_TAC; + MATCH_MP_TAC HOMOTOPIC_PATHS_JOIN THEN + ASM_REWRITE_TAC[PATHSTART_SUBPATH; PATHFINISH_SUBPATH] THEN + MATCH_MP_TAC HOMOTOPIC_PATHS_SUBSET THEN + EXISTS_TAC `t:real^N->bool` THEN ASM_REWRITE_TAC[SUBSET_UNION]]]);; + +let SIMPLY_CONNECTED_SPHERE = prove + (`!a:real^N r. 3 <= dimindex(:N) ==> simply_connected(sphere(a,r))`, + REPEAT GEN_TAC THEN REWRITE_TAC[sphere] THEN GEOM_ORIGIN_TAC `a:real^N` THEN + REPEAT STRIP_TAC THEN REWRITE_TAC[DIST_0] THEN + ASM_CASES_TAC `r < &0` THENL + [ASM_SIMP_TAC[NORM_ARITH `r < &0 ==> ~(norm(x:real^N) = r)`] THEN + REWRITE_TAC[EMPTY_GSPEC; SIMPLY_CONNECTED_EMPTY]; + RULE_ASSUM_TAC(REWRITE_RULE[REAL_NOT_LT])] THEN + FIRST_ASSUM(X_CHOOSE_THEN `b:real^N` (SUBST1_TAC o SYM) o + MATCH_MP VECTOR_CHOOSE_SIZE) THEN + UNDISCH_THEN `&0 <= r` (K ALL_TAC) THEN POP_ASSUM MP_TAC THEN + GEOM_NORMALIZE_TAC `b:real^N` THEN REWRITE_TAC[] THEN + REWRITE_TAC[NORM_EQ_0; SING_GSPEC; NORM_0] THEN + SIMP_TAC[CONVEX_SING; CONVEX_IMP_SIMPLY_CONNECTED] THEN + X_GEN_TAC `bbb:real^N` THEN DISCH_THEN(K ALL_TAC) THEN DISCH_TAC THEN + SUBGOAL_THEN + `{x:real^N | norm x = &1} = + {x | norm x = &1} DELETE (basis 1) UNION + {x | norm x = &1} DELETE (--(basis 1))` + (fun th -> SUBST1_TAC th THEN ASSUME_TAC(SYM th)) + THENL + [MATCH_MP_TAC(SET_RULE + `~(x = y) ==> s = s DELETE x UNION s DELETE y`) THEN + REWRITE_TAC[VECTOR_ARITH `x:real^N = --x <=> x = vec 0`] THEN + ASM_SIMP_TAC[VECTOR_MUL_EQ_0; REAL_LT_IMP_NZ; BASIS_NONZERO; + DIMINDEX_GE_1; LE_REFL]; + ALL_TAC] THEN + MATCH_MP_TAC SIMPLY_CONNECTED_UNION THEN + ASM_SIMP_TAC[TAUT `p /\ q /\ r /\ s /\ t <=> (p /\ q) /\ (r /\ s) /\ t`] THEN + CONJ_TAC THENL + [ONCE_REWRITE_TAC[SET_RULE `s DELETE x = s INTER (UNIV DELETE x)`] THEN + CONJ_TAC THEN MATCH_MP_TAC OPEN_IN_INTER_OPEN THEN + SIMP_TAC[OPEN_DELETE; OPEN_UNIV; OPEN_IN_SUBTOPOLOGY_REFL] THEN + REWRITE_TAC[SUBSET_UNIV; TOPSPACE_EUCLIDEAN]; + ALL_TAC] THEN + CONJ_TAC THENL + [CONJ_TAC THEN MATCH_MP_TAC CONTRACTIBLE_IMP_SIMPLY_CONNECTED THEN + ONCE_REWRITE_TAC[NORM_ARITH `norm(x:real^N) = dist(vec 0,x)`] THEN + REWRITE_TAC[GSYM sphere] THEN + MATCH_MP_TAC CONTRACTIBLE_PUNCTURED_SPHERE THEN + SIMP_TAC[IN_SPHERE; DIST_0; NORM_BASIS; DIMINDEX_GE_1; + LE_REFL; REAL_LT_01; NORM_NEG]; + ALL_TAC] THEN + CONJ_TAC THENL + [ALL_TAC; + REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; IN_INTER; IN_DELETE] THEN + EXISTS_TAC `basis 2:real^N` THEN + ASM_SIMP_TAC[IN_ELIM_THM; NORM_MUL; NORM_BASIS; ARITH; + ARITH_RULE `3 <= n ==> 2 <= n`] THEN + ASM_SIMP_TAC[REAL_ARITH `&0 < r ==> abs r * &1 = r`] THEN + CONJ_TAC THEN DISCH_THEN(MP_TAC o AP_TERM `\x:real^N. x$1`) THEN + ASM_SIMP_TAC[VECTOR_MUL_COMPONENT; VECTOR_NEG_COMPONENT; BASIS_COMPONENT; + ARITH; DIMINDEX_GE_1] THEN + ASM_REAL_ARITH_TAC] THEN + SUBGOAL_THEN + `({x:real^N | norm x = &1} DELETE basis 1) INTER + ({x | norm x = &1} DELETE --basis 1) = + ({x:real^N | norm x = &1} DELETE basis 1) INTER {x | &0 <= x$1} UNION + ({x:real^N | norm x = &1} DELETE --basis 1) INTER {x | x$1 <= &0}` + SUBST1_TAC THENL + [MATCH_MP_TAC(SET_RULE + `t UNION u = UNIV /\ ~(b IN u) /\ ~(c IN t) + ==> (s DELETE b) INTER (s DELETE c) = + (s DELETE b) INTER t UNION (s DELETE c) INTER u`) THEN + SIMP_TAC[IN_ELIM_THM; EXTENSION; IN_UNION; IN_UNIV; BASIS_COMPONENT; + DIMINDEX_GE_1; LE_REFL; VECTOR_NEG_COMPONENT] THEN + REAL_ARITH_TAC; + ALL_TAC] THEN + MATCH_MP_TAC PATH_CONNECTED_UNION THEN + REWRITE_TAC[CONJ_ASSOC] THEN CONJ_TAC THENL + [ALL_TAC; + REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN EXISTS_TAC `basis 2:real^N` THEN + ASM_SIMP_TAC[IN_INTER; IN_DELETE; IN_ELIM_THM; NORM_BASIS; BASIS_NE; ARITH; + BASIS_COMPONENT; ARITH_RULE `3 <= n ==> 1 <= n /\ 2 <= n`] THEN + REWRITE_TAC[REAL_LE_REFL] THEN + DISCH_THEN(MP_TAC o AP_TERM `\x:real^N. x$1`) THEN + ASM_SIMP_TAC[VECTOR_NEG_COMPONENT; BASIS_COMPONENT; + ARITH; ARITH_RULE `3 <= n ==> 1 <= n /\ 2 <= n`] THEN + CONV_TAC REAL_RAT_REDUCE_CONV] THEN + SUBGOAL_THEN + `path_connected((cball(vec 0,&1) INTER {x:real^N | x$1 = &0}) DELETE + (vec 0))` + MP_TAC THENL + [REWRITE_TAC[SET_RULE `s DELETE a = s DIFF {a}`] THEN + MATCH_MP_TAC PATH_CONNECTED_CONVEX_DIFF_CARD_LT THEN + SIMP_TAC[CARD_LT_FINITE_INFINITE; FINITE_SING; real_INFINITE] THEN + SIMP_TAC[CONVEX_INTER; CONVEX_CBALL; CONVEX_STANDARD_HYPERPLANE] THEN + DISCH_THEN(MP_TAC o + SPEC `{vec 0:real^N,basis 2,basis 3}` o + MATCH_MP (REWRITE_RULE [IMP_CONJ] COLLINEAR_SUBSET)) THEN + REWRITE_TAC[INSERT_SUBSET; EMPTY_SUBSET; IN_INTER; IN_CBALL_0; + IN_ELIM_THM; NORM_0; VEC_COMPONENT; REAL_POS] THEN + ASM_SIMP_TAC[NORM_BASIS; BASIS_COMPONENT; ARITH; REAL_LE_REFL; + ARITH_RULE `3 <= n ==> 1 <= n /\ 2 <= n`; + COLLINEAR_3_AFFINE_HULL; BASIS_NONZERO] THEN + REWRITE_TAC[AFFINE_HULL_2_ALT; VECTOR_ADD_LID; VECTOR_SUB_RZERO] THEN + REWRITE_TAC[IN_ELIM_THM; IN_UNIV] THEN DISCH_THEN(CHOOSE_THEN MP_TAC) THEN + DISCH_THEN(MP_TAC o AP_TERM `\x:real^N. x$3`) THEN + ASM_SIMP_TAC[BASIS_COMPONENT; VECTOR_MUL_COMPONENT; + ARITH; ARITH_RULE `3 <= n ==> 1 <= n /\ 2 <= n`] THEN + REAL_ARITH_TAC; + ALL_TAC] THEN + MATCH_MP_TAC(MESON[PATH_CONNECTED_CONTINUOUS_IMAGE] + `(?f g. f continuous_on s /\ g continuous_on s /\ + IMAGE f s = t /\ IMAGE g s = u) + ==> path_connected s ==> path_connected t /\ path_connected u`) THEN + EXISTS_TAC `\x:real^N. x + sqrt(&1 - norm(x) pow 2) % basis 1` THEN + EXISTS_TAC `\x:real^N. x - sqrt(&1 - norm(x) pow 2) % basis 1` THEN + REPEAT CONJ_TAC THENL + [MATCH_MP_TAC CONTINUOUS_ON_ADD THEN REWRITE_TAC[CONTINUOUS_ON_ID] THEN + MATCH_MP_TAC CONTINUOUS_ON_MUL THEN REWRITE_TAC[CONTINUOUS_ON_CONST] THEN + REWRITE_TAC[o_DEF] THEN MATCH_MP_TAC(REWRITE_RULE[o_DEF] + CONTINUOUS_ON_LIFT_SQRT_COMPOSE) THEN + SIMP_TAC[IN_INTER; IN_DELETE; IN_CBALL_0; REAL_SUB_LE; + REAL_POW_1_LE; NORM_POS_LE; LIFT_SUB] THEN + MATCH_MP_TAC CONTINUOUS_ON_SUB THEN + REWRITE_TAC[CONTINUOUS_ON_CONST] THEN + REWRITE_TAC[REAL_POW_2; LIFT_CMUL] THEN + MATCH_MP_TAC CONTINUOUS_ON_MUL THEN + REWRITE_TAC[o_DEF; LIFT_DROP; ETA_AX] THEN + REWRITE_TAC[REWRITE_RULE[o_DEF] CONTINUOUS_ON_LIFT_NORM]; + MATCH_MP_TAC CONTINUOUS_ON_SUB THEN REWRITE_TAC[CONTINUOUS_ON_ID] THEN + MATCH_MP_TAC CONTINUOUS_ON_MUL THEN REWRITE_TAC[CONTINUOUS_ON_CONST] THEN + REWRITE_TAC[o_DEF] THEN MATCH_MP_TAC(REWRITE_RULE[o_DEF] + CONTINUOUS_ON_LIFT_SQRT_COMPOSE) THEN + SIMP_TAC[IN_INTER; IN_DELETE; IN_CBALL_0; REAL_SUB_LE; + REAL_POW_1_LE; NORM_POS_LE; LIFT_SUB] THEN + MATCH_MP_TAC CONTINUOUS_ON_SUB THEN + REWRITE_TAC[CONTINUOUS_ON_CONST] THEN + REWRITE_TAC[REAL_POW_2; LIFT_CMUL] THEN + MATCH_MP_TAC CONTINUOUS_ON_MUL THEN + REWRITE_TAC[o_DEF; LIFT_DROP; ETA_AX] THEN + REWRITE_TAC[REWRITE_RULE[o_DEF] CONTINUOUS_ON_LIFT_NORM]; + REWRITE_TAC[EXTENSION; IN_IMAGE; IN_INTER; IN_DELETE; IN_CBALL_0; + IN_ELIM_THM] THEN + X_GEN_TAC `y:real^N` THEN EQ_TAC THENL + [DISCH_THEN(X_CHOOSE_THEN `x:real^N` STRIP_ASSUME_TAC) THEN + ASM_REWRITE_TAC[VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT] THEN + SIMP_TAC[BASIS_COMPONENT; DIMINDEX_GE_1; LE_REFL] THEN + REWRITE_TAC[NORM_EQ_SQUARE; REAL_ADD_LID; REAL_MUL_RID; REAL_POS] THEN + REWRITE_TAC[VECTOR_ARITH + `(x + y:real^N) dot (x + y) = (x dot x + y dot y) + &2 * x dot y`] THEN + ASM_SIMP_TAC[DOT_BASIS; DIMINDEX_GE_1; LE_REFL; DOT_RMUL; + VECTOR_MUL_COMPONENT; BASIS_COMPONENT] THEN + REWRITE_TAC[REAL_MUL_RZERO; REAL_MUL_RID; REAL_ADD_RID] THEN + REWRITE_TAC[GSYM REAL_POW_2] THEN + ASM_SIMP_TAC[SQRT_POW_2; SQRT_POS_LE; REAL_SUB_LE; REAL_POW_1_LE; + NORM_POS_LE] THEN + CONJ_TAC THENL [REWRITE_TAC[NORM_POW_2] THEN REAL_ARITH_TAC; ALL_TAC] THEN + DISCH_THEN(MP_TAC o AP_TERM `\x:real^N. x$1`) THEN + ASM_SIMP_TAC[VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT; + BASIS_COMPONENT; DIMINDEX_GE_1; LE_REFL] THEN + REWRITE_TAC[REAL_ADD_LID; REAL_MUL_RID] THEN + DISCH_THEN(MP_TAC o AP_TERM `\x:real. x pow 2`) THEN + ASM_SIMP_TAC[SQRT_POW_2; SQRT_POS_LE; REAL_SUB_LE; REAL_POW_1_LE; + NORM_POS_LE] THEN + REWRITE_TAC[REAL_RING `&1 - x pow 2 = &1 pow 2 <=> x = &0`] THEN + ASM_REWRITE_TAC[NORM_EQ_0]; + STRIP_TAC THEN EXISTS_TAC `y - y$1 % basis 1:real^N` THEN + REPEAT CONJ_TAC THENL + [REWRITE_TAC[VECTOR_MUL_EQ_0; REAL_SUB_0; VECTOR_ARITH + `y:real^N = y - r % b + s % b <=> (s - r) % b = vec 0`] THEN + DISJ1_TAC THEN MATCH_MP_TAC SQRT_UNIQUE THEN + ASM_REWRITE_TAC[NORM_POW_2; VECTOR_ARITH + `(x - y:real^N) dot (x - y) = (x dot x + y dot y) - &2 * x dot y`] THEN + SIMP_TAC[DOT_RMUL] THEN + SIMP_TAC[DOT_LMUL; DOT_BASIS; DIMINDEX_GE_1; LE_REFL; + BASIS_COMPONENT] THEN + ASM_REWRITE_TAC[GSYM NORM_POW_2] THEN REAL_ARITH_TAC; + FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN + MATCH_MP_TAC NORM_LE_COMPONENTWISE THEN + SIMP_TAC[VECTOR_SUB_COMPONENT; VECTOR_MUL_COMPONENT; + BASIS_COMPONENT; DIMINDEX_GE_1; LE_REFL] THEN + REPEAT STRIP_TAC THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN + REAL_ARITH_TAC; + SIMP_TAC[VECTOR_SUB_COMPONENT; VECTOR_MUL_COMPONENT; + BASIS_COMPONENT; DIMINDEX_GE_1; LE_REFL] THEN + REAL_ARITH_TAC; + REWRITE_TAC[VECTOR_SUB_EQ] THEN DISCH_THEN SUBST_ALL_TAC THEN + MAP_EVERY UNDISCH_TAC + [`~((y:real^N)$1 % basis 1:real^N = basis 1)`; + `norm((y:real^N)$1 % basis 1:real^N) = &1`; + `&0 <= ((y:real^N)$1 % basis 1:real^N)$1`] THEN + SIMP_TAC[NORM_MUL; VECTOR_MUL_COMPONENT; BASIS_COMPONENT; NORM_BASIS; + DIMINDEX_GE_1; LE_REFL; REAL_MUL_RID; real_abs; VECTOR_MUL_LID]]]; + REWRITE_TAC[EXTENSION; IN_IMAGE; IN_INTER; IN_DELETE; IN_CBALL_0; + IN_ELIM_THM] THEN + X_GEN_TAC `y:real^N` THEN EQ_TAC THENL + [DISCH_THEN(X_CHOOSE_THEN `x:real^N` STRIP_ASSUME_TAC) THEN + ASM_REWRITE_TAC[VECTOR_SUB_COMPONENT; VECTOR_MUL_COMPONENT] THEN + SIMP_TAC[BASIS_COMPONENT; DIMINDEX_GE_1; LE_REFL] THEN + REWRITE_TAC[NORM_EQ_SQUARE; REAL_ADD_LID; REAL_MUL_RID; REAL_POS] THEN + REWRITE_TAC[VECTOR_ARITH + `(x - y:real^N) dot (x - y) = (x dot x + y dot y) - &2 * x dot y`] THEN + ASM_SIMP_TAC[DOT_BASIS; DIMINDEX_GE_1; LE_REFL; DOT_RMUL; + VECTOR_MUL_COMPONENT; BASIS_COMPONENT] THEN + REWRITE_TAC[REAL_MUL_RZERO; REAL_MUL_RID; REAL_SUB_RZERO] THEN + REWRITE_TAC[GSYM REAL_POW_2] THEN + REWRITE_TAC[REAL_ARITH `&0 - x <= &0 <=> &0 <= x`] THEN + ASM_SIMP_TAC[SQRT_POW_2; SQRT_POS_LE; REAL_SUB_LE; REAL_POW_1_LE; + NORM_POS_LE] THEN + CONJ_TAC THENL [REWRITE_TAC[NORM_POW_2] THEN REAL_ARITH_TAC; ALL_TAC] THEN + DISCH_THEN(MP_TAC o AP_TERM `\x:real^N. x$1`) THEN + ASM_SIMP_TAC[VECTOR_SUB_COMPONENT; VECTOR_MUL_COMPONENT; + VECTOR_NEG_COMPONENT; BASIS_COMPONENT; DIMINDEX_GE_1; LE_REFL] THEN + REWRITE_TAC[REAL_ARITH `&0 - x * &1 = -- &1 <=> x = &1`] THEN + DISCH_THEN(MP_TAC o AP_TERM `\x:real. x pow 2`) THEN + ASM_SIMP_TAC[SQRT_POW_2; SQRT_POS_LE; REAL_SUB_LE; REAL_POW_1_LE; + NORM_POS_LE] THEN + REWRITE_TAC[REAL_RING `&1 - x pow 2 = &1 pow 2 <=> x = &0`] THEN + ASM_REWRITE_TAC[NORM_EQ_0]; + STRIP_TAC THEN EXISTS_TAC `y - y$1 % basis 1:real^N` THEN + REPEAT CONJ_TAC THENL + [REWRITE_TAC[VECTOR_MUL_EQ_0; REAL_SUB_0; VECTOR_ARITH + `y:real^N = y - r % b - s % b <=> (s + r) % b = vec 0`] THEN + DISJ1_TAC THEN REWRITE_TAC[REAL_ARITH `x + y = &0 <=> x = --y`] THEN + MATCH_MP_TAC SQRT_UNIQUE THEN + ASM_REWRITE_TAC[REAL_NEG_GE0; NORM_POW_2; VECTOR_ARITH + `(x - y:real^N) dot (x - y) = (x dot x + y dot y) - &2 * x dot y`] THEN + SIMP_TAC[DOT_RMUL] THEN + SIMP_TAC[DOT_LMUL; DOT_BASIS; DIMINDEX_GE_1; LE_REFL; + BASIS_COMPONENT] THEN + ASM_REWRITE_TAC[GSYM NORM_POW_2] THEN REAL_ARITH_TAC; + FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN + MATCH_MP_TAC NORM_LE_COMPONENTWISE THEN + SIMP_TAC[VECTOR_SUB_COMPONENT; VECTOR_MUL_COMPONENT; + BASIS_COMPONENT; DIMINDEX_GE_1; LE_REFL] THEN + REPEAT STRIP_TAC THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN + REAL_ARITH_TAC; + SIMP_TAC[VECTOR_SUB_COMPONENT; VECTOR_MUL_COMPONENT; + BASIS_COMPONENT; DIMINDEX_GE_1; LE_REFL] THEN + REAL_ARITH_TAC; + REWRITE_TAC[VECTOR_SUB_EQ] THEN DISCH_THEN SUBST_ALL_TAC THEN + MAP_EVERY UNDISCH_TAC + [`~((y:real^N)$1 % basis 1:real^N = --basis 1)`; + `norm((y:real^N)$1 % basis 1:real^N) = &1`; + `((y:real^N)$1 % basis 1:real^N)$1 <= &0`] THEN + SIMP_TAC[NORM_MUL; VECTOR_MUL_COMPONENT; BASIS_COMPONENT; NORM_BASIS; + DIMINDEX_GE_1; LE_REFL; REAL_MUL_RID; VECTOR_MUL_LID; + REAL_ARITH `y <= &0 ==> abs y = --y`; + REAL_ARITH `--x = &1 <=> x = -- &1`] THEN + REPEAT DISCH_TAC THEN VECTOR_ARITH_TAC]]]);; + +(* ------------------------------------------------------------------------- *) +(* Covering spaces and lifting results for them. *) +(* ------------------------------------------------------------------------- *) + +let covering_space = new_definition + `covering_space(c,(p:real^M->real^N)) s <=> + p continuous_on c /\ IMAGE p c = s /\ + !x. x IN s + ==> ?t. x IN t /\ open_in (subtopology euclidean s) t /\ + ?v. UNIONS v = {x | x IN c /\ p(x) IN t} /\ + (!u. u IN v ==> open_in (subtopology euclidean c) u) /\ + pairwise DISJOINT v /\ + (!u. u IN v ==> ?q. homeomorphism (u,t) (p,q))`;; + +let COVERING_SPACE_IMP_CONTINUOUS = prove + (`!p:real^M->real^N c s. covering_space (c,p) s ==> p continuous_on c`, + SIMP_TAC[covering_space]);; + +let COVERING_SPACE_IMP_SURJECTIVE = prove + (`!p:real^M->real^N c s. covering_space (c,p) s ==> IMAGE p c = s`, + SIMP_TAC[covering_space]);; + +let HOMEOMORPHISM_IMP_COVERING_SPACE = prove + (`!f:real^M->real^N g s t. + homeomorphism (s,t) (f,g) ==> covering_space (s,f) t`, + REWRITE_TAC[homeomorphism] THEN REPEAT STRIP_TAC THEN + ASM_REWRITE_TAC[covering_space] THEN X_GEN_TAC `y:real^N` THEN DISCH_TAC THEN + EXISTS_TAC `t:real^N->bool` THEN + ASM_SIMP_TAC[OPEN_IN_SUBTOPOLOGY_REFL; TOPSPACE_EUCLIDEAN; SUBSET_UNIV] THEN + EXISTS_TAC `{s:real^M->bool}` THEN + REWRITE_TAC[FORALL_IN_INSERT; NOT_IN_EMPTY; UNIONS_1; PAIRWISE_SING] THEN + ASM_SIMP_TAC[OPEN_IN_SUBTOPOLOGY_REFL; TOPSPACE_EUCLIDEAN; SUBSET_UNIV] THEN + CONJ_TAC THENL [ASM SET_TAC[]; EXISTS_TAC `g:real^N->real^M`] THEN + ASM_REWRITE_TAC[homeomorphism]);; + +let COVERING_SPACE_LOCAL_HOMEOMORPHISM = prove + (`!p:real^M->real^N c s. + covering_space (c,p) s + ==> !x. x IN c + ==> ?t u. x IN t /\ open_in (subtopology euclidean c) t /\ + p(x) IN u /\ open_in (subtopology euclidean s) u /\ + ?q. homeomorphism (t,u) (p,q)`, + REWRITE_TAC[covering_space] THEN REPEAT STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `(p:real^M->real^N) x`) THEN + ANTS_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + DISCH_THEN(X_CHOOSE_THEN `t:real^N->bool` MP_TAC) THEN + REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + DISCH_THEN(X_CHOOSE_THEN `v:(real^M->bool)->bool` STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN `(x:real^M) IN UNIONS v` MP_TAC THENL + [ASM SET_TAC[]; REWRITE_TAC[IN_UNIONS]] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `u:real^M->bool` THEN + STRIP_TAC THEN EXISTS_TAC `t:real^N->bool` THEN ASM_SIMP_TAC[]);; + +let COVERING_SPACE_LOCAL_HOMEOMORPHISM_ALT = prove + (`!p:real^M->real^N c s. + covering_space (c,p) s + ==> !y. y IN s + ==> ?x t u. p(x) = y /\ + x IN t /\ open_in (subtopology euclidean c) t /\ + y IN u /\ open_in (subtopology euclidean s) u /\ + ?q. homeomorphism (t,u) (p,q)`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN `?x. x IN c /\ (p:real^M->real^N) x = y` MP_TAC THENL + [FIRST_X_ASSUM(MP_TAC o MATCH_MP COVERING_SPACE_IMP_SURJECTIVE) THEN + ASM SET_TAC[]; + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `x:real^M` THEN STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o SPEC `x:real^M` o MATCH_MP + COVERING_SPACE_LOCAL_HOMEOMORPHISM) THEN + ASM_MESON_TAC[]]);; + +let COVERING_SPACE_OPEN_MAP = prove + (`!p:real^M->real^N c s t. + covering_space (c,p) s /\ + open_in (subtopology euclidean c) t + ==> open_in (subtopology euclidean s) (IMAGE p t)`, + REWRITE_TAC[covering_space] THEN REPEAT STRIP_TAC THEN + FIRST_ASSUM(ASSUME_TAC o CONJUNCT1 o GEN_REWRITE_RULE I [open_in]) THEN + ONCE_REWRITE_TAC[OPEN_IN_SUBOPEN] THEN X_GEN_TAC `y:real^N` THEN + DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC `y:real^N`) THEN + ANTS_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + DISCH_THEN(X_CHOOSE_THEN `u:real^N->bool` MP_TAC) THEN + REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + DISCH_THEN(X_CHOOSE_THEN `vs:(real^M->bool)->bool` + (STRIP_ASSUME_TAC o GSYM)) THEN + SUBGOAL_THEN + `?x. x IN {x | x IN c /\ (p:real^M->real^N) x IN u} /\ x IN t /\ p x = y` + MP_TAC THENL [ASM SET_TAC[]; ASM_REWRITE_TAC[]] THEN + DISCH_THEN(X_CHOOSE_THEN `x:real^M` STRIP_ASSUME_TAC) THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_UNIONS]) THEN + DISCH_THEN(X_CHOOSE_THEN `v:real^M->bool` STRIP_ASSUME_TAC) THEN + REPEAT(FIRST_X_ASSUM(MP_TAC o SPEC `v:real^M->bool`)) THEN + ASM_REWRITE_TAC[homeomorphism] THEN REPEAT DISCH_TAC THEN + FIRST_X_ASSUM(X_CHOOSE_THEN `q:real^N->real^M` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `IMAGE (p:real^M->real^N) (t INTER v)` THEN CONJ_TAC THENL + [ALL_TAC; ASM SET_TAC[]] THEN + SUBGOAL_THEN + `IMAGE (p:real^M->real^N) (t INTER v) = + {z | z IN u /\ q z IN (t INTER v)}` + SUBST1_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + MATCH_MP_TAC OPEN_IN_TRANS THEN EXISTS_TAC `u:real^N->bool` THEN + ASM_REWRITE_TAC[] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o GEN_REWRITE_RULE I [CONTINUOUS_ON_OPEN]) THEN + ASM_REWRITE_TAC[] THEN ONCE_REWRITE_TAC[INTER_COMM] THEN + MATCH_MP_TAC OPEN_IN_SUBTOPOLOGY_INTER_SUBSET THEN + EXISTS_TAC `c:real^M->bool` THEN + CONJ_TAC THENL [MATCH_MP_TAC OPEN_IN_INTER; ASM_MESON_TAC[open_in]] THEN + ASM_REWRITE_TAC[OPEN_IN_SUBTOPOLOGY_REFL; TOPSPACE_EUCLIDEAN; SUBSET_UNIV]);; + +let COVERING_SPACE_QUOTIENT_MAP = prove + (`!p:real^M->real^N c s. + covering_space (c,p) s + ==> !u. u SUBSET s + ==> (open_in (subtopology euclidean c) {x | x IN c /\ p x IN u} <=> + open_in (subtopology euclidean s) u)`, + REPEAT GEN_TAC THEN DISCH_TAC THEN + FIRST_ASSUM(SUBST1_TAC o SYM o MATCH_MP COVERING_SPACE_IMP_SURJECTIVE) THEN + MATCH_MP_TAC OPEN_MAP_IMP_QUOTIENT_MAP THEN + CONJ_TAC THENL [ASM_MESON_TAC[COVERING_SPACE_IMP_CONTINUOUS]; ALL_TAC] THEN + FIRST_ASSUM(SUBST1_TAC o MATCH_MP COVERING_SPACE_IMP_SURJECTIVE) THEN + ASM_MESON_TAC[COVERING_SPACE_OPEN_MAP]);; + +let COVERING_SPACE_LOCALLY = prove + (`!P Q p:real^M->real^N c s. + covering_space (c,p) s /\ (!t. t SUBSET c /\ P t ==> Q(IMAGE p t)) /\ + locally P c + ==> locally Q s`, + REPEAT STRIP_TAC THEN + FIRST_ASSUM(SUBST1_TAC o SYM o MATCH_MP COVERING_SPACE_IMP_SURJECTIVE) THEN + MATCH_MP_TAC LOCALLY_OPEN_MAP_IMAGE THEN + EXISTS_TAC `P:(real^M->bool)->bool` THEN + CONJ_TAC THENL [ASM_MESON_TAC[COVERING_SPACE_IMP_CONTINUOUS]; ALL_TAC] THEN + ASM_SIMP_TAC[] THEN + FIRST_ASSUM(SUBST1_TAC o MATCH_MP COVERING_SPACE_IMP_SURJECTIVE) THEN + ASM_MESON_TAC[COVERING_SPACE_OPEN_MAP]);; + +let COVERING_SPACE_LOCALLY_CONNECTED = prove + (`!p:real^M->real^N c s. + covering_space (c,p) s /\ locally connected c ==> locally connected s`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC COVERING_SPACE_LOCALLY THEN + MAP_EVERY EXISTS_TAC + [`connected:(real^M->bool)->bool`; + `p:real^M->real^N`; `c:real^M->bool`] THEN + REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC CONNECTED_CONTINUOUS_IMAGE THEN + ASM_REWRITE_TAC[] THEN + ASM_MESON_TAC[COVERING_SPACE_IMP_CONTINUOUS; CONTINUOUS_ON_SUBSET]);; + +let COVERING_SPACE_LOCALLY_PATH_CONNECTED = prove + (`!p:real^M->real^N c s. + covering_space (c,p) s /\ locally path_connected c + ==> locally path_connected s`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC COVERING_SPACE_LOCALLY THEN + MAP_EVERY EXISTS_TAC + [`path_connected:(real^M->bool)->bool`; + `p:real^M->real^N`; `c:real^M->bool`] THEN + REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC PATH_CONNECTED_CONTINUOUS_IMAGE THEN + ASM_REWRITE_TAC[] THEN + ASM_MESON_TAC[COVERING_SPACE_IMP_CONTINUOUS; CONTINUOUS_ON_SUBSET]);; + +let COVERING_SPACE_LIFT_UNIQUE_GEN = prove + (`!p:real^M->real^N f:real^P->real^N g1 g2 c s t u a x. + covering_space (c,p) s /\ + f continuous_on t /\ IMAGE f t SUBSET s /\ + g1 continuous_on t /\ IMAGE g1 t SUBSET c /\ + (!x. x IN t ==> f(x) = p(g1 x)) /\ + g2 continuous_on t /\ IMAGE g2 t SUBSET c /\ + (!x. x IN t ==> f(x) = p(g2 x)) /\ + u IN components t /\ a IN u /\ g1(a) = g2(a) /\ x IN u + ==> g1(x) = g2(x)`, + REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[GSYM VECTOR_SUB_EQ] THEN + UNDISCH_TAC `(x:real^P) IN u` THEN SPEC_TAC(`x:real^P`,`x:real^P`) THEN + MATCH_MP_TAC(SET_RULE + `(?a. a IN u /\ g a = z) /\ + ({x | x IN u /\ g x = z} = {} \/ {x | x IN u /\ g x = z} = u) + ==> !x. x IN u ==> g x = z`) THEN + CONJ_TAC THENL [ASM_MESON_TAC[VECTOR_SUB_EQ]; ALL_TAC] THEN + FIRST_ASSUM(MP_TAC o MATCH_MP IN_COMPONENTS_CONNECTED) THEN + REWRITE_TAC[CONNECTED_CLOPEN] THEN DISCH_THEN MATCH_MP_TAC THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP IN_COMPONENTS_SUBSET) THEN CONJ_TAC THENL + [ONCE_REWRITE_TAC[OPEN_IN_SUBOPEN] THEN REWRITE_TAC[IN_ELIM_THM] THEN + X_GEN_TAC `x:real^P` THEN STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o SPEC `(g1:real^P->real^M) x` o + MATCH_MP COVERING_SPACE_LOCAL_HOMEOMORPHISM) THEN + ANTS_TAC THENL [ASM SET_TAC[]; SIMP_TAC[LEFT_IMP_EXISTS_THM]] THEN + MAP_EVERY X_GEN_TAC [`v:real^M->bool`; `w:real^N->bool`] THEN + RULE_ASSUM_TAC(REWRITE_RULE[VECTOR_SUB_EQ]) THEN + REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + REWRITE_TAC[homeomorphism] THEN + DISCH_THEN(X_CHOOSE_THEN `q:real^N->real^M` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `{x | x IN u /\ (g1:real^P->real^M) x IN v} INTER + {x | x IN u /\ (g2:real^P->real^M) x IN v}` THEN + CONJ_TAC THENL + [MATCH_MP_TAC OPEN_IN_INTER THEN ONCE_REWRITE_TAC[SET_RULE + `{x | x IN u /\ g x IN v} = + {x | x IN u /\ g x IN (v INTER IMAGE g u)}`] THEN + CONJ_TAC THEN MATCH_MP_TAC CONTINUOUS_ON_IMP_OPEN_IN THEN + (CONJ_TAC THENL [ASM_MESON_TAC[CONTINUOUS_ON_SUBSET]; ALL_TAC]) THEN + UNDISCH_TAC `open_in (subtopology euclidean c) (v:real^M->bool)` THEN + REWRITE_TAC[OPEN_IN_OPEN] THEN + MATCH_MP_TAC MONO_EXISTS THEN SIMP_TAC[] THEN ASM SET_TAC[]; + REWRITE_TAC[SUBSET; IN_ELIM_THM; IN_INTER; VECTOR_SUB_EQ] THEN + ASM SET_TAC[]]; + MATCH_MP_TAC CONTINUOUS_CLOSED_IN_PREIMAGE_CONSTANT THEN + MATCH_MP_TAC CONTINUOUS_ON_SUB THEN + ASM_MESON_TAC[CONTINUOUS_ON_SUBSET]]);; + +let COVERING_SPACE_LIFT_UNIQUE = prove + (`!p:real^M->real^N f:real^P->real^N g1 g2 c s t a x. + covering_space (c,p) s /\ + f continuous_on t /\ IMAGE f t SUBSET s /\ + g1 continuous_on t /\ IMAGE g1 t SUBSET c /\ + (!x. x IN t ==> f(x) = p(g1 x)) /\ + g2 continuous_on t /\ IMAGE g2 t SUBSET c /\ + (!x. x IN t ==> f(x) = p(g2 x)) /\ + connected t /\ a IN t /\ g1(a) = g2(a) /\ x IN t + ==> g1(x) = g2(x)`, + REPEAT STRIP_TAC THEN MP_TAC(ISPECL + [`p:real^M->real^N`; `f:real^P->real^N`; + `g1:real^P->real^M`; `g2:real^P->real^M`; + `c:real^M->bool`; `s:real^N->bool`; `t:real^P->bool`; `t:real^P->bool`; + `a:real^P`; `x:real^P`] COVERING_SPACE_LIFT_UNIQUE_GEN) THEN + ASM_REWRITE_TAC[IN_COMPONENTS_SELF] THEN ASM SET_TAC[]);; + +let COVERING_SPACE_LIFT_UNIQUE_IDENTITY = prove + (`!p:real^M->real^N c f s a. + covering_space (c,p) s /\ + path_connected c /\ + f continuous_on c /\ IMAGE f c SUBSET c /\ + (!x. x IN c ==> p(f x) = p x) /\ + a IN c /\ f(a) = a + ==> !x. x IN c ==> f x = x`, + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE] THEN REPEAT STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [path_connected]) THEN + DISCH_THEN(MP_TAC o SPECL [`a:real^M`; `x:real^M`]) THEN + ASM_REWRITE_TAC[path; path_image; pathstart; pathfinish] THEN + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE] THEN + DISCH_THEN(X_CHOOSE_THEN `g:real^1->real^M` STRIP_ASSUME_TAC) THEN + MP_TAC(ISPECL + [`p:real^M->real^N`; `(p:real^M->real^N) o (g:real^1->real^M)`; + `(f:real^M->real^M) o (g:real^1->real^M)`; `g:real^1->real^M`; + `c:real^M->bool`; `s:real^N->bool`; + `interval[vec 0:real^1,vec 1]`; + `vec 0:real^1`; `vec 1:real^1`] + COVERING_SPACE_LIFT_UNIQUE) THEN + ASM_REWRITE_TAC[o_THM; IMAGE_o] THEN DISCH_THEN MATCH_MP_TAC THEN + ASM_REWRITE_TAC[ENDS_IN_UNIT_INTERVAL; CONNECTED_INTERVAL] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [covering_space]) THEN + STRIP_TAC THEN FIRST_ASSUM(ASSUME_TAC o MATCH_MP (SET_RULE + `IMAGE p c = s ==> !x. x IN c ==> p(x) IN s`)) THEN + ASM_SIMP_TAC[SUBSET; FORALL_IN_IMAGE] THEN + CONJ_TAC THEN MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN + ASM_REWRITE_TAC[] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET)) THEN + ASM_REWRITE_TAC[SUBSET; FORALL_IN_IMAGE]);; + +let COVERING_SPACE_LIFT_HOMOTOPY = prove + (`!p:real^M->real^N c s (h:real^(1,P)finite_sum->real^N) f u. + covering_space (c,p) s /\ + h continuous_on (interval[vec 0,vec 1] PCROSS u) /\ + IMAGE h (interval[vec 0,vec 1] PCROSS u) SUBSET s /\ + (!y. y IN u ==> h (pastecart (vec 0) y) = p(f y)) /\ + f continuous_on u /\ IMAGE f u SUBSET c + ==> ?k. k continuous_on (interval[vec 0,vec 1] PCROSS u) /\ + IMAGE k (interval[vec 0,vec 1] PCROSS u) SUBSET c /\ + (!y. y IN u ==> k(pastecart (vec 0) y) = f y) /\ + (!z. z IN interval[vec 0,vec 1] PCROSS u ==> h z = p(k z))`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN + `!y. y IN u + ==> ?v. open_in (subtopology euclidean u) v /\ y IN v /\ + ?k:real^(1,P)finite_sum->real^M. + k continuous_on (interval[vec 0,vec 1] PCROSS v) /\ + IMAGE k (interval[vec 0,vec 1] PCROSS v) SUBSET c /\ + (!y. y IN v ==> k(pastecart (vec 0) y) = f y) /\ + (!z. z IN interval[vec 0,vec 1] PCROSS v + ==> h z :real^N = p(k z))` + MP_TAC THENL + [ALL_TAC; + GEN_REWRITE_TAC (LAND_CONV o TOP_DEPTH_CONV) + [RIGHT_IMP_EXISTS_THM; RIGHT_AND_EXISTS_THM] THEN + REWRITE_TAC[SKOLEM_THM; LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC + [`v:real^P->real^P->bool`; `fs:real^P->real^(1,P)finite_sum->real^M`] THEN + DISCH_THEN(LABEL_TAC "*") THEN + MP_TAC(ISPECL + [`fs:real^P->real^(1,P)finite_sum->real^M`; + `(\x. interval[vec 0,vec 1] PCROSS (v x)) + :real^P->real^(1,P)finite_sum->bool`; + `(interval[vec 0,vec 1] PCROSS u):real^(1,P)finite_sum->bool`; + `u:real^P->bool`] + PASTING_LEMMA_EXISTS) THEN + ASM_SIMP_TAC[] THEN ANTS_TAC THENL + [ALL_TAC; + MATCH_MP_TAC MONO_EXISTS THEN + X_GEN_TAC `k:real^(1,P)finite_sum->real^M` THEN STRIP_TAC THEN + ASM_REWRITE_TAC[FORALL_IN_IMAGE; FORALL_IN_PCROSS; SUBSET] THEN + REPEAT CONJ_TAC THEN TRY(X_GEN_TAC `t:real^1`) THEN + X_GEN_TAC `y:real^P` THEN STRIP_TAC THENL + [FIRST_X_ASSUM(MP_TAC o SPECL + [`pastecart (t:real^1) (y:real^P)`; `y:real^P`]); + FIRST_X_ASSUM(MP_TAC o SPECL + [`pastecart (vec 0:real^1) (y:real^P)`; `y:real^P`]); + FIRST_X_ASSUM(MP_TAC o SPECL + [`pastecart (t:real^1) (y:real^P)`; `y:real^P`])] THEN + ASM_SIMP_TAC[PASTECART_IN_PCROSS; IN_INTER; ENDS_IN_UNIT_INTERVAL] THEN + DISCH_THEN SUBST1_TAC THEN + REMOVE_THEN "*" (MP_TAC o SPEC `y:real^P`) THEN + ASM_REWRITE_TAC[SUBSET; FORALL_IN_IMAGE] THEN + REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_REWRITE_TAC[PASTECART_IN_PCROSS]] THEN + REPEAT CONJ_TAC THENL + [REWRITE_TAC[SUBSET; FORALL_IN_PCROSS; UNIONS_GSPEC; IN_ELIM_THM] THEN + MAP_EVERY X_GEN_TAC [`t:real^1`; `y:real^P`] THEN STRIP_TAC THEN + EXISTS_TAC `y:real^P` THEN ASM_SIMP_TAC[PASTECART_IN_PCROSS]; + X_GEN_TAC `y:real^P` THEN DISCH_TAC THEN + REMOVE_THEN "*" (MP_TAC o SPEC `y:real^P`) THEN + ASM_REWRITE_TAC[] THEN DISCH_THEN(MP_TAC o CONJUNCT1) THEN + REWRITE_TAC[OPEN_IN_OPEN] THEN + DISCH_THEN(X_CHOOSE_THEN `t:real^P->bool` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `(:real^1) PCROSS (t:real^P->bool)` THEN + ASM_SIMP_TAC[REWRITE_RULE[GSYM PCROSS] OPEN_PCROSS; OPEN_UNIV] THEN + REWRITE_TAC[EXTENSION; FORALL_PASTECART; PASTECART_IN_PCROSS; + IN_INTER; IN_UNIV] THEN + REPEAT GEN_TAC THEN CONV_TAC TAUT; + REWRITE_TAC[FORALL_PASTECART; IN_INTER; PASTECART_IN_PCROSS] THEN + MAP_EVERY X_GEN_TAC + [`x:real^P`; `z:real^P`; `t:real^1`; `y:real^P`] THEN + REWRITE_TAC[CONJ_ACI] THEN STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o + ISPECL [`h:real^(1,P)finite_sum->real^N`; + `(fs:real^P->real^(1,P)finite_sum->real^M) x`; + `(fs:real^P->real^(1,P)finite_sum->real^M) z`; + `interval[vec 0:real^1,vec 1] PCROSS {y:real^P}`; + `pastecart (vec 0:real^1) (y:real^P)`; + `pastecart (t:real^1) (y:real^P)`] o + MATCH_MP (ONCE_REWRITE_RULE[IMP_CONJ] COVERING_SPACE_LIFT_UNIQUE)) THEN + DISCH_THEN MATCH_MP_TAC THEN + ASM_SIMP_TAC[PASTECART_IN_PCROSS; IN_SING; ENDS_IN_UNIT_INTERVAL] THEN + SIMP_TAC[REWRITE_RULE[GSYM PCROSS] CONNECTED_PCROSS; + CONNECTED_INTERVAL; CONNECTED_SING] THEN + CONJ_TAC THENL + [FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET)) THEN + REWRITE_TAC[FORALL_PASTECART; SUBSET; PASTECART_IN_PCROSS] THEN + ASM_SIMP_TAC[IN_SING]; + ALL_TAC] THEN + CONJ_TAC THENL + [FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP + (REWRITE_RULE[IMP_CONJ_ALT] SUBSET_TRANS)) THEN + MATCH_MP_TAC IMAGE_SUBSET THEN + REWRITE_TAC[FORALL_PASTECART; SUBSET; PASTECART_IN_PCROSS] THEN + ASM_SIMP_TAC[IN_SING]; + ALL_TAC] THEN + ONCE_REWRITE_TAC[TAUT `p /\ q /\ r /\ s <=> (p /\ q /\ r) /\ s`] THEN + CONJ_TAC THENL + [REMOVE_THEN "*" (MP_TAC o SPEC `x:real^P`); + REMOVE_THEN "*" (MP_TAC o SPEC `z:real^P`)] THEN + ASM_REWRITE_TAC[FORALL_IN_GSPEC; SUBSET; FORALL_IN_IMAGE] THEN + ASM_SIMP_TAC[FORALL_PASTECART; PASTECART_IN_PCROSS; IN_SING] THEN + STRIP_TAC THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET)) THEN + REWRITE_TAC[FORALL_PASTECART; SUBSET; PASTECART_IN_PCROSS] THEN + ASM_SIMP_TAC[IN_SING]]] THEN + X_GEN_TAC `y:real^P` THEN DISCH_TAC THEN + FIRST_ASSUM(MP_TAC o last o CONJUNCTS o + GEN_REWRITE_RULE I [covering_space]) THEN + GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [RIGHT_IMP_EXISTS_THM] THEN + REWRITE_TAC[SKOLEM_THM; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `uu:real^N->real^N->bool` THEN DISCH_TAC THEN + SUBGOAL_THEN + `!t. t IN interval[vec 0,vec 1] + ==> ?k n i:real^N. + open_in (subtopology euclidean (interval[vec 0,vec 1])) k /\ + open_in (subtopology euclidean u) n /\ + t IN k /\ y IN n /\ i IN s /\ + IMAGE (h:real^(1,P)finite_sum->real^N) (k PCROSS n) SUBSET uu i` + MP_TAC THENL + [X_GEN_TAC `t:real^1` THEN DISCH_TAC THEN + SUBGOAL_THEN `(h:real^(1,P)finite_sum->real^N) (pastecart t y) IN s` + ASSUME_TAC THENL + [FIRST_X_ASSUM(MATCH_MP_TAC o ONCE_REWRITE_RULE[FORALL_IN_IMAGE] o + GEN_REWRITE_RULE I [SUBSET]) THEN + ASM_REWRITE_TAC[PASTECART_IN_PCROSS]; + ALL_TAC] THEN + SUBGOAL_THEN + `open_in (subtopology euclidean (interval[vec 0,vec 1] PCROSS u)) + {z | z IN (interval[vec 0,vec 1] PCROSS u) /\ + (h:real^(1,P)finite_sum->real^N) z IN + uu(h(pastecart t y))}` + MP_TAC THENL + [MATCH_MP_TAC CONTINUOUS_OPEN_IN_PREIMAGE_GEN THEN + EXISTS_TAC `s:real^N->bool` THEN ASM_SIMP_TAC[]; + ALL_TAC] THEN + DISCH_THEN(MP_TAC o MATCH_MP (ONCE_REWRITE_RULE[IMP_CONJ_ALT] + PASTECART_IN_INTERIOR_SUBTOPOLOGY)) THEN + DISCH_THEN(MP_TAC o SPECL [`t:real^1`; `y:real^P`]) THEN + ASM_SIMP_TAC[IN_ELIM_THM; PASTECART_IN_PCROSS] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `k:real^1->bool` THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `n:real^P->bool` THEN + STRIP_TAC THEN + EXISTS_TAC `(h:real^(1,P)finite_sum->real^N) (pastecart t y)` THEN + ASM_REWRITE_TAC[] THEN ASM SET_TAC[]; + ALL_TAC] THEN + GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [OPEN_IN_OPEN] THEN + REWRITE_TAC[RIGHT_EXISTS_AND_THM] THEN + REWRITE_TAC[LEFT_AND_EXISTS_THM] THEN + REWRITE_TAC[MESON[] + `(?x y. (P y /\ x = f y) /\ Q x) <=> ?y. P y /\ Q(f y)`] THEN + REWRITE_TAC[RIGHT_AND_EXISTS_THM] THEN + GEN_REWRITE_TAC (LAND_CONV o TOP_DEPTH_CONV) [RIGHT_IMP_EXISTS_THM] THEN + REWRITE_TAC[SKOLEM_THM; LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC + [`kk:real^1->real^1->bool`; `nn:real^1->real^P->bool`; + `xx:real^1->real^N`] THEN + DISCH_THEN(LABEL_TAC "+") THEN + MP_TAC(ISPEC `interval[vec 0:real^1,vec 1] PCROSS {y:real^P}` + COMPACT_IMP_HEINE_BOREL) THEN + SIMP_TAC[COMPACT_PCROSS; COMPACT_INTERVAL; COMPACT_SING] THEN + DISCH_THEN(MP_TAC o SPEC + `IMAGE ((\i. kk i PCROSS nn i):real^1->real^(1,P)finite_sum->bool) + (interval[vec 0,vec 1])`) THEN + ASM_SIMP_TAC[FORALL_IN_IMAGE; OPEN_PCROSS] THEN ANTS_TAC THENL + [REWRITE_TAC[SUBSET; FORALL_IN_PCROSS; IN_SING] THEN + MAP_EVERY X_GEN_TAC [`t:real^1`; `z:real^P`] THEN STRIP_TAC THEN + ASM_REWRITE_TAC[UNIONS_IMAGE; IN_ELIM_THM; PASTECART_IN_PCROSS] THEN + ASM_MESON_TAC[IN_INTER]; + GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) + [TAUT `p /\ q /\ r <=> q /\ p /\ r`] THEN + REWRITE_TAC[EXISTS_FINITE_SUBSET_IMAGE] THEN + DISCH_THEN(X_CHOOSE_THEN `tk:real^1->bool` STRIP_ASSUME_TAC)] THEN + ABBREV_TAC `n = INTERS (IMAGE (nn:real^1->real^P->bool) tk)` THEN + SUBGOAL_THEN `(y:real^P) IN n /\ open n` STRIP_ASSUME_TAC THENL + [EXPAND_TAC "n" THEN CONJ_TAC THENL + [REWRITE_TAC[INTERS_IMAGE; IN_ELIM_THM]; + MATCH_MP_TAC OPEN_INTERS THEN REWRITE_TAC[FORALL_IN_IMAGE] THEN + ASM_SIMP_TAC[FINITE_IMAGE]] THEN + X_GEN_TAC `t:real^1` THEN DISCH_TAC THEN + REMOVE_THEN "+" (MP_TAC o SPEC `t:real^1`) THEN + (ANTS_TAC THENL [ASM SET_TAC[]; SIMP_TAC[IN_INTER]]); + ALL_TAC] THEN + MP_TAC(ISPECL + [`interval[vec 0:real^1,vec 1]`; `IMAGE (kk:real^1->real^1->bool) tk`] + LEBESGUE_COVERING_LEMMA) THEN + REWRITE_TAC[COMPACT_INTERVAL; FORALL_IN_IMAGE; IMAGE_EQ_EMPTY] THEN + MATCH_MP_TAC(TAUT + `q /\ (p ==> ~q) /\ (q ==> (r ==> s) ==> t) + ==> (~p /\ q /\ r ==> s) ==> t`) THEN + SIMP_TAC[UNIONS_0; IMAGE_CLAUSES; SUBSET_EMPTY; UNIT_INTERVAL_NONEMPTY] THEN + CONJ_TAC THENL + [FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE RAND_CONV [UNIONS_IMAGE]) THEN + REWRITE_TAC[SUBSET; FORALL_IN_PCROSS; IMP_CONJ; IN_SING] THEN + REWRITE_TAC[RIGHT_FORALL_IMP_THM; FORALL_UNWIND_THM2] THEN + REWRITE_TAC[UNIONS_IMAGE; IN_ELIM_THM; PASTECART_IN_PCROSS] THEN + MESON_TAC[]; + DISCH_TAC] THEN + ANTS_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + DISCH_THEN(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC) THEN + MP_TAC(ISPEC `d:real` REAL_ARCH_INV) THEN + ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `N:num` STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN + `!n. n <= N + ==> ?v k:real^(1,P)finite_sum->real^M. + open_in (subtopology euclidean u) v /\ + y IN v /\ + k continuous_on interval[vec 0,lift(&n / &N)] PCROSS v /\ + IMAGE k (interval[vec 0,lift(&n / &N)] PCROSS v) SUBSET c /\ + (!y. y IN v ==> k (pastecart (vec 0) y) = f y) /\ + (!z. z IN interval[vec 0,lift(&n / &N)] PCROSS v + ==> h z:real^N = p (k z))` + MP_TAC THENL + [ALL_TAC; + DISCH_THEN(MP_TAC o SPEC `N:num`) THEN REWRITE_TAC[LE_REFL] THEN + ASM_SIMP_TAC[REAL_DIV_REFL; REAL_OF_NUM_EQ; LIFT_NUM]] THEN + MATCH_MP_TAC num_INDUCTION THEN CONJ_TAC THENL + [DISCH_TAC THEN REWRITE_TAC[real_div; REAL_MUL_LZERO; LIFT_NUM] THEN + EXISTS_TAC `u:real^P->bool` THEN + EXISTS_TAC `(f o sndcart):real^(1,P)finite_sum->real^M` THEN + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; FORALL_IN_PCROSS; INTERVAL_SING] THEN + REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; IN_SING; o_THM] THEN + ASM_REWRITE_TAC[FORALL_UNWIND_THM2; SNDCART_PASTECART] THEN + REWRITE_TAC[OPEN_IN_SUBTOPOLOGY_REFL; TOPSPACE_EUCLIDEAN; SUBSET_UNIV] THEN + CONJ_TAC THENL [ALL_TAC; ASM SET_TAC[]] THEN + MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN + SIMP_TAC[LINEAR_CONTINUOUS_ON; LINEAR_SNDCART] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET)) THEN + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; FORALL_IN_PCROSS] THEN + SIMP_TAC[SNDCART_PASTECART]; + ALL_TAC] THEN + X_GEN_TAC `m:num` THEN ASM_CASES_TAC `SUC m <= N` THEN + ASM_SIMP_TAC[ARITH_RULE `SUC m <= N ==> m <= N`; LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC + [`v:real^P->bool`; `k:real^(1,P)finite_sum->real^M`] THEN + STRIP_TAC THEN FIRST_X_ASSUM + (MP_TAC o SPEC `interval[lift(&m / &N),lift(&(SUC m) / &N)]`) THEN + ANTS_TAC THENL + [REWRITE_TAC[DIAMETER_INTERVAL; SUBSET_INTERVAL_1] THEN + REWRITE_TAC[LIFT_DROP; DROP_VEC; INTERVAL_EQ_EMPTY_1; + GSYM LIFT_SUB; NORM_LIFT] THEN + ASM_SIMP_TAC[REAL_LT_DIV2_EQ; REAL_LE_DIV2_EQ; REAL_OF_NUM_LT; LE_1; + REAL_FIELD `&0 < x ==> a / x - b / x = (a - b) / x`] THEN + SIMP_TAC[GSYM NOT_LE; ARITH_RULE `m <= SUC m`; REAL_OF_NUM_SUB] THEN + ASM_SIMP_TAC[REAL_ABS_DIV; REAL_ABS_NUM; REAL_LE_DIV; REAL_POS; + REAL_ABS_NUM; ARITH_RULE `SUC m - m = 1`] THEN + ASM_SIMP_TAC[REAL_ARITH `&1 / n = inv(n)`; REAL_LT_IMP_LE] THEN + ASM_SIMP_TAC[REAL_LE_LDIV_EQ; REAL_OF_NUM_LT; LE_1] THEN + ASM_REWRITE_TAC[REAL_MUL_LID; REAL_OF_NUM_LE] THEN ARITH_TAC; + ALL_TAC] THEN + REWRITE_TAC[EXISTS_IN_IMAGE] THEN + DISCH_THEN(X_CHOOSE_THEN `t:real^1` STRIP_ASSUME_TAC) THEN + REMOVE_THEN "+" (MP_TAC o SPEC `t:real^1`) THEN + ANTS_TAC THENL [ASM SET_TAC[]; STRIP_TAC] THEN + FIRST_X_ASSUM(MP_TAC o SPEC `(xx:real^1->real^N) t`) THEN + ASM_REWRITE_TAC[] THEN + REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + DISCH_THEN(X_CHOOSE_THEN `vv:(real^M->bool)->bool` MP_TAC) THEN + ONCE_REWRITE_TAC[IMP_CONJ] THEN + GEN_REWRITE_TAC LAND_CONV [EXTENSION] THEN + DISCH_THEN(MP_TAC o SPEC + `(k:real^(1,P)finite_sum->real^M) (pastecart (lift(&m / &N)) y)`) THEN + REWRITE_TAC[IN_ELIM_THM] THEN MATCH_MP_TAC(TAUT + `q /\ (p ==> r) ==> (p <=> q) ==> r`) THEN + REPEAT(FIRST_X_ASSUM(STRIP_ASSUME_TAC o GEN_REWRITE_RULE I [IN_INTER])) THEN + SUBGOAL_THEN + `lift(&m / &N) IN interval[vec 0,lift (&m / &N)] /\ + lift(&m / &N) IN interval[lift(&m / &N),lift(&(SUC m) / &N)]` + STRIP_ASSUME_TAC THENL + [REWRITE_TAC[IN_INTERVAL_1; LIFT_DROP; DROP_VEC] THEN + SIMP_TAC[REAL_LE_DIV; REAL_POS; REAL_LE_REFL] THEN + ASM_SIMP_TAC[REAL_LE_DIV2_EQ; LE_1; REAL_OF_NUM_LT; REAL_OF_NUM_LE] THEN + ARITH_TAC; + ALL_TAC] THEN + REPEAT CONJ_TAC THENL + [FIRST_X_ASSUM(MATCH_MP_TAC o GEN_REWRITE_RULE I [SUBSET]) THEN + MATCH_MP_TAC FUN_IN_IMAGE THEN + ASM_REWRITE_TAC[PASTECART_IN_PCROSS]; + FIRST_X_ASSUM(MP_TAC o SPEC `pastecart(lift(&m / &N)) (y:real^P)`) THEN + ASM_REWRITE_TAC[PASTECART_IN_PCROSS] THEN + DISCH_THEN(SUBST1_TAC o SYM) THEN FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP + (SET_RULE `IMAGE h s SUBSET t ==> x IN s ==> h x IN t`)) THEN + ASM_REWRITE_TAC[PASTECART_IN_PCROSS; IN_INTER] THEN + ASM_SIMP_TAC[IN_INTERVAL_1; LIFT_DROP; REAL_LE_DIV; REAL_LE_LDIV_EQ; + REAL_POS; REAL_OF_NUM_LT; LE_1; DROP_VEC] THEN + REWRITE_TAC[REAL_MUL_LID; REAL_OF_NUM_LE] THEN + CONJ_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o GEN_REWRITE_RULE I [SUBSET]) THEN + ASM_REWRITE_TAC[]; + GEN_REWRITE_TAC LAND_CONV [IN_UNIONS] THEN + DISCH_THEN(X_CHOOSE_THEN `w:real^M->bool` STRIP_ASSUME_TAC) THEN + DISCH_THEN(CONJUNCTS_THEN2 (MP_TAC o SPEC `w:real^M->bool`) MP_TAC) THEN + DISCH_THEN(MP_TAC o SPEC `w:real^M->bool` o CONJUNCT2) THEN + ASM_REWRITE_TAC[] THEN DISCH_THEN(X_CHOOSE_TAC `p':real^N->real^M`) THEN + DISCH_TAC THEN UNDISCH_THEN `(w:real^M->bool) IN vv` (K ALL_TAC)] THEN + ABBREV_TAC `w' = (uu:real^N->real^N->bool)(xx(t:real^1))` THEN + SUBGOAL_THEN + `?n'. open_in (subtopology euclidean u) n' /\ y IN n' /\ + IMAGE (k:real^(1,P)finite_sum->real^M) ({lift(&m / &N)} PCROSS n') + SUBSET w` + STRIP_ASSUME_TAC THENL + [EXISTS_TAC + `{z | z IN v /\ ((k:real^(1,P)finite_sum->real^M) o + pastecart (lift(&m / &N))) z IN w}` THEN + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; FORALL_IN_PCROSS] THEN + ASM_SIMP_TAC[IN_ELIM_THM; IN_SING; o_THM] THEN + MATCH_MP_TAC OPEN_IN_TRANS THEN EXISTS_TAC `v:real^P->bool` THEN + ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC CONTINUOUS_OPEN_IN_PREIMAGE_GEN THEN + EXISTS_TAC `c:real^M->bool` THEN ASM_REWRITE_TAC[] THEN + ONCE_REWRITE_TAC[GSYM o_DEF] THEN CONJ_TAC THENL + [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)); + REWRITE_TAC[IMAGE_o] THEN FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE + `IMAGE k s SUBSET c ==> t SUBSET s ==> IMAGE k t SUBSET c`))] THEN + ASM_SIMP_TAC[SUBSET; FORALL_IN_IMAGE; PASTECART_IN_PCROSS]; + ALL_TAC] THEN + SUBGOAL_THEN + `?q q':real^P->bool. + open_in (subtopology euclidean u) q /\ + closed_in (subtopology euclidean u) q' /\ + y IN q /\ y IN q' /\ q SUBSET q' /\ + q SUBSET (u INTER nn(t:real^1)) INTER n' INTER v /\ + q' SUBSET (u INTER nn(t:real^1)) INTER n' INTER v` + STRIP_ASSUME_TAC THENL + [REWRITE_TAC[SET_RULE + `y IN q /\ y IN q' /\ q SUBSET q' /\ q SUBSET s /\ q' SUBSET s <=> + y IN q /\ q SUBSET q' /\ q' SUBSET s`] THEN + UNDISCH_TAC `open_in (subtopology euclidean u) (v:real^P->bool)` THEN + UNDISCH_TAC `open_in (subtopology euclidean u) (n':real^P->bool)` THEN + REWRITE_TAC[OPEN_IN_OPEN] THEN + DISCH_THEN(X_CHOOSE_THEN `vo:real^P->bool` STRIP_ASSUME_TAC) THEN + DISCH_THEN(X_CHOOSE_THEN `vx:real^P->bool` STRIP_ASSUME_TAC) THEN + MP_TAC(ISPEC `nn(t:real^1) INTER vo INTER vx:real^P->bool` + OPEN_CONTAINS_CBALL) THEN + ASM_SIMP_TAC[OPEN_INTER] THEN DISCH_THEN(MP_TAC o SPEC `y:real^P`) THEN + ASM_REWRITE_TAC[IN_INTER] THEN + ANTS_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + DISCH_THEN(X_CHOOSE_THEN `e:real` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `u INTER ball(y:real^P,e)` THEN + EXISTS_TAC `u INTER cball(y:real^P,e)` THEN + REWRITE_TAC[CLOSED_IN_CLOSED] THEN + CONJ_TAC THENL [MESON_TAC[OPEN_BALL]; ALL_TAC] THEN + CONJ_TAC THENL [MESON_TAC[CLOSED_CBALL]; ALL_TAC] THEN + ASM_REWRITE_TAC[IN_INTER; CENTRE_IN_BALL] THEN + MP_TAC(ISPECL [`y:real^P`; `e:real`] BALL_SUBSET_CBALL) THEN + ASM SET_TAC[]; + ALL_TAC] THEN + FIRST_X_ASSUM(STRIP_ASSUME_TAC o GEN_REWRITE_RULE I [homeomorphism]) THEN + EXISTS_TAC `q:real^P->bool` THEN ASM_REWRITE_TAC[] THEN + MP_TAC(ISPECL + [`\x:real^(1,P)finite_sum. + x IN interval[vec 0,lift(&m / &N)] PCROSS (q':real^P->bool)`; + `k:real^(1,P)finite_sum->real^M`; + `(p':real^N->real^M) o (h:real^(1,P)finite_sum->real^N)`; + `interval[vec 0,lift(&m / &N)] PCROSS (q':real^P->bool)`; + `interval[lift(&m / &N),lift(&(SUC m) / &N)] PCROSS (q':real^P->bool)`] + CONTINUOUS_ON_CASES_LOCAL) THEN + REWRITE_TAC[TAUT `~(p /\ ~p)`] THEN ANTS_TAC THENL + [REPEAT CONJ_TAC THENL + [REWRITE_TAC[CLOSED_IN_CLOSED] THEN + EXISTS_TAC `interval[vec 0,lift(&m / &N)] PCROSS (:real^P)` THEN + SIMP_TAC[CLOSED_PCROSS; CLOSED_INTERVAL; CLOSED_UNIV] THEN + REWRITE_TAC[EXTENSION; IN_INTER; IN_UNION; FORALL_PASTECART] THEN + REWRITE_TAC[PASTECART_IN_PCROSS; IN_UNIV] THEN CONV_TAC TAUT; + REWRITE_TAC[CLOSED_IN_CLOSED] THEN EXISTS_TAC + `interval[lift(&m / &N),lift(&(SUC m) / &N)] PCROSS (:real^P)` THEN + SIMP_TAC[CLOSED_PCROSS; CLOSED_INTERVAL; CLOSED_UNIV] THEN + REWRITE_TAC[EXTENSION; IN_INTER; IN_UNION; FORALL_PASTECART] THEN + REWRITE_TAC[PASTECART_IN_PCROSS; IN_UNIV] THEN CONV_TAC TAUT; + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET)) THEN + REWRITE_TAC[SUBSET; FORALL_PASTECART; PASTECART_IN_PCROSS] THEN + ASM SET_TAC[]; + MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN CONJ_TAC THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET)) + THENL + [ALL_TAC; + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE + `IMAGE k s SUBSET c ==> t SUBSET s ==> IMAGE k t SUBSET c`))] THEN + MATCH_MP_TAC PCROSS_MONO THEN + (CONJ_TAC THENL [ALL_TAC; ASM SET_TAC[]]) THEN + ASM_REWRITE_TAC[SUBSET_INTERVAL_1; LIFT_DROP; DROP_VEC; + SUBSET_INTER] THEN + REWRITE_TAC[SUBSET_INTERVAL_1; LIFT_DROP; DROP_VEC] THEN + ASM_SIMP_TAC[REAL_LE_MUL; REAL_POS; REAL_LE_DIV2_EQ; REAL_OF_NUM_LT; + LE_1] THEN + ASM_SIMP_TAC[REAL_LE_LDIV_EQ; REAL_LE_RDIV_EQ; REAL_OF_NUM_LT; LE_1; + REAL_MUL_LZERO; REAL_MUL_LID; REAL_OF_NUM_LE] THEN + DISJ2_TAC THEN ARITH_TAC; + REWRITE_TAC[FORALL_PASTECART; PASTECART_IN_PCROSS] THEN + MAP_EVERY X_GEN_TAC [`r:real^1`; `z:real^P`] THEN + ASM_CASES_TAC `(z:real^P) IN q'` THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[IN_INTERVAL_1; DROP_VEC] THEN DISCH_THEN(MP_TAC o MATCH_MP + (REAL_ARITH `(b <= x /\ x <= c) /\ (a <= x /\ x <= b) ==> x = b`)) THEN + REWRITE_TAC[DROP_EQ; o_THM] THEN DISCH_THEN SUBST1_TAC THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (MESON[] + `(!x. x IN w ==> p' (p x) = x) + ==> h z = p(k z) /\ k z IN w + ==> k z = p' (h z)`)) THEN + CONJ_TAC THENL + [FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_REWRITE_TAC[PASTECART_IN_PCROSS] THEN ASM SET_TAC[]; + FIRST_X_ASSUM(MATCH_MP_TAC o GEN_REWRITE_RULE I [SUBSET]) THEN + MATCH_MP_TAC FUN_IN_IMAGE THEN + REWRITE_TAC[PASTECART_IN_PCROSS; IN_SING] THEN ASM SET_TAC[]]]; + SUBGOAL_THEN + `interval[vec 0,lift(&m / &N)] UNION + interval [lift(&m / &N),lift(&(SUC m) / &N)] = + interval[vec 0,lift(&(SUC m) / &N)]` + ASSUME_TAC THENL + [REWRITE_TAC[EXTENSION; IN_UNION; IN_INTERVAL_1] THEN GEN_TAC THEN + MATCH_MP_TAC(REAL_ARITH `a <= b /\ b <= c ==> + (a <= x /\ x <= b \/ b <= x /\ x <= c <=> a <= x /\ x <= c)`) THEN + SIMP_TAC[LIFT_DROP; DROP_VEC; REAL_LE_DIV; REAL_POS] THEN + ASM_SIMP_TAC[REAL_LE_DIV2_EQ; REAL_OF_NUM_LT; REAL_OF_NUM_LE; LE_1] THEN + ARITH_TAC; + ALL_TAC] THEN + SUBGOAL_THEN + `interval[vec 0,lift(&m / &N)] PCROSS (q':real^P->bool) UNION + interval [lift(&m / &N),lift(&(SUC m) / &N)] PCROSS q' = + interval[vec 0,lift(&(SUC m) / &N)] PCROSS q'` + SUBST1_TAC THENL + [SIMP_TAC[EXTENSION; IN_UNION; FORALL_PASTECART; PASTECART_IN_PCROSS] THEN + ASM SET_TAC[]; + ALL_TAC] THEN + MATCH_MP_TAC(MESON[CONTINUOUS_ON_SUBSET] + `t SUBSET s /\ (f continuous_on s ==> P f) + ==> f continuous_on s ==> ?g. g continuous_on t /\ P g`) THEN + ASM_SIMP_TAC[PCROSS_MONO; SUBSET_REFL] THEN DISCH_TAC THEN + REPEAT CONJ_TAC THENL + [REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; FORALL_IN_PCROSS] THEN + MAP_EVERY X_GEN_TAC [`r:real^1`; `z:real^P`] THEN STRIP_TAC THEN + SUBGOAL_THEN `(z:real^P) IN q'` ASSUME_TAC THENL + [ASM SET_TAC[]; ASM_REWRITE_TAC[PASTECART_IN_PCROSS]] THEN + COND_CASES_TAC THEN REWRITE_TAC[o_THM] THENL + [FIRST_X_ASSUM(MATCH_MP_TAC o GEN_REWRITE_RULE I [SUBSET]) THEN + MATCH_MP_TAC FUN_IN_IMAGE THEN + REWRITE_TAC[PASTECART_IN_PCROSS; IN_SING] THEN ASM SET_TAC[]; + FIRST_X_ASSUM(MATCH_MP_TAC o REWRITE_RULE[SUBSET] o + CONJUNCT1 o GEN_REWRITE_RULE I [open_in]) THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE + `IMAGE p w' = w ==> x IN w' ==> p x IN w`))]; + X_GEN_TAC `z:real^P` THEN REWRITE_TAC[PASTECART_IN_PCROSS] THEN + DISCH_TAC THEN REWRITE_TAC[IN_INTERVAL_1; REAL_LE_REFL] THEN + SUBGOAL_THEN `(z:real^P) IN q'` ASSUME_TAC THENL + [ASM SET_TAC[]; ASM_REWRITE_TAC[LIFT_DROP; DROP_VEC]] THEN + SIMP_TAC[REAL_LE_DIV; REAL_POS] THEN ASM SET_TAC[]; + REWRITE_TAC[FORALL_PASTECART; PASTECART_IN_PCROSS] THEN + MAP_EVERY X_GEN_TAC [`r:real^1`; `z:real^P`] THEN STRIP_TAC THEN + SUBGOAL_THEN `(z:real^P) IN q'` ASSUME_TAC THENL + [ASM SET_TAC[]; ASM_REWRITE_TAC[]] THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[] THENL + [FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_REWRITE_TAC[PASTECART_IN_PCROSS] THEN ASM SET_TAC[]; + REWRITE_TAC[o_THM] THEN CONV_TAC SYM_CONV THEN + FIRST_X_ASSUM MATCH_MP_TAC]] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP + (SET_RULE `IMAGE h s SUBSET t ==> x IN s ==> h x IN t`)) THEN + ASM_REWRITE_TAC[PASTECART_IN_PCROSS; IN_INTER] THEN + REPEAT(CONJ_TAC THENL [ALL_TAC; ASM SET_TAC[]]) THEN + RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1]) THEN + REWRITE_TAC[IN_INTERVAL_1] THEN FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP + (REAL_ARITH `a <= x /\ x <= b ==> b <= c ==> a <= x /\ x <= c`)) THEN + ASM_SIMP_TAC[LIFT_DROP; REAL_LE_LDIV_EQ; REAL_OF_NUM_LT; LE_1] THEN + ASM_REWRITE_TAC[DROP_VEC; REAL_MUL_LID; REAL_OF_NUM_LE]]);; + +let COVERING_SPACE_LIFT_HOMOTOPIC_FUNCTION = prove + (`!p:real^M->real^N c s f f' g u:real^P->bool. + covering_space (c,p) s /\ + g continuous_on u /\ IMAGE g u SUBSET c /\ + (!y. y IN u ==> p(g y) = f y) /\ + homotopic_with (\x. T) (u,s) f f' + ==> ?g'. g' continuous_on u /\ IMAGE g' u SUBSET c /\ + (!y. y IN u ==> p(g' y) = f' y)`, + REPEAT STRIP_TAC THEN + FIRST_X_ASSUM(X_CHOOSE_THEN `h:real^(1,P)finite_sum->real^N` + STRIP_ASSUME_TAC o GEN_REWRITE_RULE I [homotopic_with]) THEN + FIRST_ASSUM(MP_TAC o + ISPECL [`h:real^(1,P)finite_sum->real^N`; + `g:real^P->real^M`; `u:real^P->bool`] o + MATCH_MP(ONCE_REWRITE_RULE[IMP_CONJ] COVERING_SPACE_LIFT_HOMOTOPY)) THEN + ASM_SIMP_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `k:real^(1,P)finite_sum->real^M` + STRIP_ASSUME_TAC) THEN + EXISTS_TAC `(k:real^(1,P)finite_sum->real^M) o + (\x. pastecart (vec 1) x)` THEN + ASM_REWRITE_TAC[IMAGE_o; o_THM] THEN REPEAT CONJ_TAC THENL + [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 + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; PASTECART_IN_PCROSS; + ENDS_IN_UNIT_INTERVAL]; + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE + `IMAGE k s SUBSET c ==> t SUBSET s ==> IMAGE k t SUBSET c`)) THEN + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; PASTECART_IN_PCROSS; + ENDS_IN_UNIT_INTERVAL]; + ASM_MESON_TAC[PASTECART_IN_PCROSS; ENDS_IN_UNIT_INTERVAL]]);; + +let COVERING_SPACE_LIFT_INESSENTIAL_FUNCTION = prove + (`!p:real^M->real^N c s f a u:real^P->bool. + covering_space (c,p) s /\ homotopic_with (\x. T) (u,s) f (\x. a) + ==> ?g. g continuous_on u /\ IMAGE g u SUBSET c /\ + (!y. y IN u ==> p(g y) = f y)`, + ONCE_REWRITE_TAC[HOMOTOPIC_WITH_SYM] THEN REPEAT GEN_TAC THEN DISCH_TAC THEN + ASM_CASES_TAC `u:real^P->bool = {}` THEN + ASM_REWRITE_TAC[NOT_IN_EMPTY; IMAGE_CLAUSES; EMPTY_SUBSET; + CONTINUOUS_ON_EMPTY] THEN + FIRST_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE + [TAUT `a /\ b /\ c /\ d /\ e ==> f <=> a /\ e ==> b /\ c /\ d ==> f`] + COVERING_SPACE_LIFT_HOMOTOPIC_FUNCTION)) THEN + FIRST_X_ASSUM(CONJUNCTS_THEN ASSUME_TAC) THEN + FIRST_X_ASSUM(ASSUME_TAC o MATCH_MP HOMOTOPIC_WITH_IMP_SUBSET) THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP COVERING_SPACE_IMP_SURJECTIVE) THEN + SUBGOAL_THEN `?b. b IN c /\ (p:real^M->real^N) b = a` CHOOSE_TAC THENL + [ASM SET_TAC[]; + EXISTS_TAC `(\x. b):real^P->real^M`] THEN + REWRITE_TAC[CONTINUOUS_ON_CONST] THEN ASM SET_TAC[]);; + +let COVERING_SPACE_LIFT_HOMOTOPY_ALT = prove + (`!p:real^M->real^N c s (h:real^(P,1)finite_sum->real^N) f u. + covering_space (c,p) s /\ + h continuous_on (u PCROSS interval[vec 0,vec 1]) /\ + IMAGE h (u PCROSS interval[vec 0,vec 1]) SUBSET s /\ + (!y. y IN u ==> h (pastecart y (vec 0)) = p(f y)) /\ + f continuous_on u /\ IMAGE f u SUBSET c + ==> ?k. k continuous_on (u PCROSS interval[vec 0,vec 1]) /\ + IMAGE k (u PCROSS interval[vec 0,vec 1]) SUBSET c /\ + (!y. y IN u ==> k(pastecart y (vec 0)) = f y) /\ + (!z. z IN u PCROSS interval[vec 0,vec 1] ==> h z = p(k z))`, + REPEAT STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o ISPECL + [`(h:real^(P,1)finite_sum->real^N) o + (\z. pastecart (sndcart z) (fstcart z))`; + `f:real^P->real^M`; `u:real^P->bool`] o + MATCH_MP(ONCE_REWRITE_RULE[IMP_CONJ] COVERING_SPACE_LIFT_HOMOTOPY)) THEN + ASM_SIMP_TAC[o_THM; FSTCART_PASTECART; SNDCART_PASTECART] THEN ANTS_TAC THENL + [CONJ_TAC THENL + [MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN + SIMP_TAC[CONTINUOUS_ON_PASTECART; LINEAR_CONTINUOUS_ON; + LINEAR_FSTCART; LINEAR_SNDCART] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET)); + REWRITE_TAC[IMAGE_o] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE + `IMAGE k s SUBSET c ==> t SUBSET s ==> IMAGE k t SUBSET c`))] THEN + SIMP_TAC[SUBSET; FORALL_IN_IMAGE; PASTECART_IN_PCROSS; FORALL_IN_PCROSS; + FSTCART_PASTECART; SNDCART_PASTECART]; + DISCH_THEN(X_CHOOSE_THEN `k:real^(1,P)finite_sum->real^M` + STRIP_ASSUME_TAC) THEN + EXISTS_TAC `(k:real^(1,P)finite_sum->real^M) o + (\z. pastecart (sndcart z) (fstcart z))` THEN + ASM_SIMP_TAC[o_THM; FSTCART_PASTECART; SNDCART_PASTECART; + FORALL_IN_PCROSS; PASTECART_IN_PCROSS] THEN + REPEAT CONJ_TAC THENL + [MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN + SIMP_TAC[CONTINUOUS_ON_PASTECART; LINEAR_CONTINUOUS_ON; + LINEAR_FSTCART; LINEAR_SNDCART] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET)); + REWRITE_TAC[IMAGE_o] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE + `IMAGE k s SUBSET c ==> t SUBSET s ==> IMAGE k t SUBSET c`)); + MAP_EVERY X_GEN_TAC [`x:real^P`; `t:real^1`] THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `pastecart (t:real^1) (x:real^P)`)] THEN + ASM_SIMP_TAC[SUBSET; FORALL_IN_IMAGE; PASTECART_IN_PCROSS; + FSTCART_PASTECART; SNDCART_PASTECART; FORALL_IN_PCROSS]]);; + +let COVERING_SPACE_LIFT_PATH_STRONG = prove + (`!p:real^M->real^N c s g a. + covering_space (c,p) s /\ + path g /\ path_image g SUBSET s /\ pathstart g = p(a) /\ a IN c + ==> ?h. path h /\ path_image h SUBSET c /\ pathstart h = a /\ + !t. t IN interval[vec 0,vec 1] ==> p(h t) = g t`, + REWRITE_TAC[path_image; path; pathstart] THEN + REPEAT STRIP_TAC THEN FIRST_ASSUM(MP_TAC o + ISPECL [`(g:real^1->real^N) o (fstcart:real^(1,P)finite_sum->real^1)`; + `(\y. a):real^P->real^M`; `{arb:real^P}`] o + MATCH_MP(ONCE_REWRITE_RULE[IMP_CONJ] COVERING_SPACE_LIFT_HOMOTOPY)) THEN + REWRITE_TAC[FORALL_IN_INSERT; NOT_IN_EMPTY; o_THM; FSTCART_PASTECART] THEN + ANTS_TAC THENL + [ASM_REWRITE_TAC[IMAGE_o; CONTINUOUS_ON_CONST] THEN + ASM_REWRITE_TAC[SET_RULE `IMAGE (\y. a) {b} SUBSET s <=> a IN s`] THEN + CONJ_TAC THENL + [MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN + SIMP_TAC[LINEAR_FSTCART; LINEAR_CONTINUOUS_ON] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET)); + ALL_TAC] THEN + ASM_REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; FORALL_IN_PCROSS] THEN + SIMP_TAC[FSTCART_PASTECART] THEN ASM SET_TAC[]; + DISCH_THEN(X_CHOOSE_THEN `k:real^(1,P)finite_sum->real^M` + STRIP_ASSUME_TAC) THEN + EXISTS_TAC `(k:real^(1,P)finite_sum->real^M) o (\t. pastecart t arb)` THEN + ASM_REWRITE_TAC[o_THM; IMAGE_o] THEN REPEAT CONJ_TAC THENL + [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 + SIMP_TAC[SUBSET; FORALL_IN_IMAGE; PASTECART_IN_PCROSS; IN_SING]; + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE + `IMAGE k s SUBSET c ==> t SUBSET s ==> IMAGE k t SUBSET c`)) THEN + SIMP_TAC[SUBSET; FORALL_IN_IMAGE; PASTECART_IN_PCROSS; IN_SING]; + X_GEN_TAC `t:real^1` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `pastecart (t:real^1) (arb:real^P)`) THEN + ASM_SIMP_TAC[PASTECART_IN_PCROSS; FSTCART_PASTECART; IN_SING]]]);; + +let COVERING_SPACE_LIFT_PATH = prove + (`!p:real^M->real^N c s g. + covering_space (c,p) s /\ path g /\ path_image g SUBSET s + ==> ?h. path h /\ path_image h SUBSET c /\ + !t. t IN interval[vec 0,vec 1] ==> p(h t) = g t`, + REPEAT STRIP_TAC THEN FIRST_ASSUM(MP_TAC o MATCH_MP (SET_RULE + `IMAGE g i SUBSET s ==> vec 0 IN i ==> g(vec 0) IN s`) o + GEN_REWRITE_RULE LAND_CONV [path_image]) THEN + REWRITE_TAC[ENDS_IN_UNIT_INTERVAL] THEN + FIRST_ASSUM(SUBST1_TAC o SYM o MATCH_MP COVERING_SPACE_IMP_SURJECTIVE) THEN + REWRITE_TAC[IN_IMAGE; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `a:real^M` THEN STRIP_TAC THEN + MP_TAC(ISPECL [`p:real^M->real^N`; `c:real^M->bool`; `s:real^N->bool`; + `g:real^1->real^N`; `a:real^M`] + COVERING_SPACE_LIFT_PATH_STRONG) THEN + ASM_REWRITE_TAC[pathstart] THEN MATCH_MP_TAC MONO_EXISTS THEN + REPEAT STRIP_TAC THEN ASM_SIMP_TAC[]);; + +let COVERING_SPACE_LIFT_HOMOTOPIC_PATHS = prove + (`!p:real^M->real^N c s g1 g2 h1 h2. + covering_space (c,p) s /\ + path g1 /\ path_image g1 SUBSET s /\ + path g2 /\ path_image g2 SUBSET s /\ + homotopic_paths s g1 g2 /\ + path h1 /\ path_image h1 SUBSET c /\ + (!t. t IN interval[vec 0,vec 1] ==> p(h1 t) = g1 t) /\ + path h2 /\ path_image h2 SUBSET c /\ + (!t. t IN interval[vec 0,vec 1] ==> p(h2 t) = g2 t) /\ + pathstart h1 = pathstart h2 + ==> homotopic_paths c h1 h2`, + REPEAT STRIP_TAC THEN REWRITE_TAC[HOMOTOPIC_PATHS] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [homotopic_paths]) THEN + REWRITE_TAC[homotopic_with; pathstart; pathfinish] THEN + DISCH_THEN(X_CHOOSE_THEN + `h:real^(1,1)finite_sum->real^N` STRIP_ASSUME_TAC) THEN + FIRST_ASSUM(MP_TAC o ISPECL + [`h:real^(1,1)finite_sum->real^N`; `(\x. pathstart h2):real^1->real^M`; + `interval[vec 0:real^1,vec 1]`] o + MATCH_MP(ONCE_REWRITE_RULE[IMP_CONJ] COVERING_SPACE_LIFT_HOMOTOPY_ALT)) THEN + ASM_SIMP_TAC[] THEN ANTS_TAC THENL + [REWRITE_TAC[CONTINUOUS_ON_CONST; SUBSET; FORALL_IN_IMAGE] THEN + ASM_MESON_TAC[pathstart; ENDS_IN_UNIT_INTERVAL; PATHSTART_IN_PATH_IMAGE; + SUBSET]; + ALL_TAC] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `k:real^(1,1)finite_sum->real^M` THEN + STRIP_TAC THEN ASM_SIMP_TAC[o_DEF] THEN + MATCH_MP_TAC(TAUT `(p /\ q) /\ (p /\ q ==> r) ==> p /\ q /\ r`) THEN + CONJ_TAC THENL + [CONJ_TAC THEN + FIRST_ASSUM(MATCH_MP_TAC o + REWRITE_RULE[RIGHT_FORALL_IMP_THM] o + ONCE_REWRITE_RULE[IMP_CONJ] o + REWRITE_RULE[CONJ_ASSOC] o MATCH_MP + (ONCE_REWRITE_RULE[IMP_CONJ] COVERING_SPACE_LIFT_UNIQUE)) THEN + REWRITE_TAC[GSYM CONJ_ASSOC] THENL + [MAP_EVERY EXISTS_TAC [`g1:real^1->real^N`; `vec 0:real^1`]; + MAP_EVERY EXISTS_TAC [`g2:real^1->real^N`; `vec 0:real^1`]] THEN + ASM_SIMP_TAC[ENDS_IN_UNIT_INTERVAL; UNIT_INTERVAL_NONEMPTY] THEN + RULE_ASSUM_TAC(REWRITE_RULE[path_image; pathstart; pathfinish; path]) THEN + ASM_REWRITE_TAC[CONNECTED_INTERVAL; pathstart; pathfinish] THEN + REWRITE_TAC[CONJ_ASSOC] THEN + (REPEAT CONJ_TAC THENL + [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)); + GEN_REWRITE_TAC (LAND_CONV o LAND_CONV) [GSYM o_DEF] THEN + REWRITE_TAC[IMAGE_o] THEN FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE + `IMAGE k s SUBSET c ==> t SUBSET s ==> IMAGE k t SUBSET c`)); + ASM_MESON_TAC[PASTECART_IN_PCROSS; ENDS_IN_UNIT_INTERVAL]] THEN + SIMP_TAC[SUBSET; FORALL_IN_IMAGE; PASTECART_IN_PCROSS; FORALL_IN_PCROSS; + FSTCART_PASTECART; SNDCART_PASTECART; ENDS_IN_UNIT_INTERVAL]); + STRIP_TAC THEN + REWRITE_TAC[TAUT `p ==> q /\ r <=> (p ==> q) /\ (p ==> r)`] THEN + REWRITE_TAC[FORALL_AND_THM] THEN CONJ_TAC THENL + [ASM_MESON_TAC[pathstart; ENDS_IN_UNIT_INTERVAL]; ALL_TAC] THEN + FIRST_ASSUM(MATCH_MP_TAC o + REWRITE_RULE[RIGHT_FORALL_IMP_THM] o + ONCE_REWRITE_RULE[IMP_CONJ] o + REWRITE_RULE[CONJ_ASSOC] o MATCH_MP + (ONCE_REWRITE_RULE[IMP_CONJ] COVERING_SPACE_LIFT_UNIQUE)) THEN + MAP_EVERY EXISTS_TAC + [`(\x. pathfinish g1):real^1->real^N`; `vec 0:real^1`] THEN + ASM_SIMP_TAC[ENDS_IN_UNIT_INTERVAL; CONNECTED_INTERVAL] THEN + REWRITE_TAC[CONTINUOUS_ON_CONST; pathfinish] THEN + REPEAT CONJ_TAC THENL + [REWRITE_TAC[SUBSET; FORALL_IN_IMAGE] THEN + ASM_MESON_TAC[SUBSET; pathfinish; PATHFINISH_IN_PATH_IMAGE]; + 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 + SIMP_TAC[SUBSET; FORALL_IN_IMAGE; PASTECART_IN_PCROSS; FORALL_IN_PCROSS; + FSTCART_PASTECART; SNDCART_PASTECART; ENDS_IN_UNIT_INTERVAL]; + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE] THEN + X_GEN_TAC `t:real^1` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `pastecart (t:real^1) (vec 1:real^1)` o + REWRITE_RULE[FORALL_IN_IMAGE] o GEN_REWRITE_RULE I [SUBSET]) THEN + ASM_REWRITE_TAC[PASTECART_IN_PCROSS; ENDS_IN_UNIT_INTERVAL]; + ASM_MESON_TAC[PASTECART_IN_PCROSS; ENDS_IN_UNIT_INTERVAL]; + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE] THEN + ASM_MESON_TAC[SUBSET; pathfinish; PATHFINISH_IN_PATH_IMAGE]]]);; + +let COVERING_SPACE_MONODROMY = prove + (`!p:real^M->real^N c s g1 g2 h1 h2. + covering_space (c,p) s /\ + path g1 /\ path_image g1 SUBSET s /\ + path g2 /\ path_image g2 SUBSET s /\ + homotopic_paths s g1 g2 /\ + path h1 /\ path_image h1 SUBSET c /\ + (!t. t IN interval[vec 0,vec 1] ==> p(h1 t) = g1 t) /\ + path h2 /\ path_image h2 SUBSET c /\ + (!t. t IN interval[vec 0,vec 1] ==> p(h2 t) = g2 t) /\ + pathstart h1 = pathstart h2 + ==> pathfinish h1 = pathfinish h2`, + REPEAT GEN_TAC THEN + DISCH_THEN(MP_TAC o MATCH_MP COVERING_SPACE_LIFT_HOMOTOPIC_PATHS) THEN + REWRITE_TAC[HOMOTOPIC_PATHS_IMP_PATHFINISH]);; + +let COVERING_SPACE_LIFT_HOMOTOPIC_PATH = prove + (`!p:real^M->real^N c s f f' g a b. + covering_space (c,p) s /\ + homotopic_paths s f f' /\ + path g /\ path_image g SUBSET c /\ + pathstart g = a /\ pathfinish g = b /\ + (!t. t IN interval[vec 0,vec 1] ==> p(g t) = f t) + ==> ?g'. path g' /\ path_image g' SUBSET c /\ + pathstart g' = a /\ pathfinish g' = b /\ + (!t. t IN interval[vec 0,vec 1] ==> p(g' t) = f' t)`, + ONCE_REWRITE_TAC[HOMOTOPIC_PATHS_SYM] THEN REPEAT STRIP_TAC THEN + FIRST_ASSUM(STRIP_ASSUME_TAC o MATCH_MP HOMOTOPIC_PATHS_IMP_PATH) THEN + FIRST_ASSUM(STRIP_ASSUME_TAC o MATCH_MP HOMOTOPIC_PATHS_IMP_SUBSET) THEN + FIRST_ASSUM(MP_TAC o ISPECL [`f':real^1->real^N`; `a:real^M`] o + MATCH_MP(ONCE_REWRITE_RULE[IMP_CONJ] COVERING_SPACE_LIFT_PATH_STRONG)) THEN + ANTS_TAC THENL + [ASM_REWRITE_TAC[] THEN CONJ_TAC THENL + [ASM_MESON_TAC[pathstart; ENDS_IN_UNIT_INTERVAL; + HOMOTOPIC_PATHS_IMP_PATHSTART]; + ASM_MESON_TAC[PATHSTART_IN_PATH_IMAGE; SUBSET]]; + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `g':real^1->real^M` THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + SUBST1_TAC(SYM(ASSUME `pathfinish g:real^M = b`)) THEN + FIRST_ASSUM(MATCH_MP_TAC o + MATCH_MP(ONCE_REWRITE_RULE[IMP_CONJ] COVERING_SPACE_MONODROMY)) THEN + MAP_EVERY EXISTS_TAC [`f':real^1->real^N`; `f:real^1->real^N`] THEN + ASM_REWRITE_TAC[]]);; + +let COVERING_SPACE_INESSENTIAL_LOOP_LIFT_IS_LOOP = prove + (`!p:real^M->real^N c s g h a. + covering_space (c,p) s /\ + path g /\ path_image g SUBSET s /\ pathfinish g = pathstart g /\ + homotopic_paths s g (linepath(a,a)) /\ + path h /\ path_image h SUBSET c /\ + (!t. t IN interval[vec 0,vec 1] ==> p(h t) = g t) + ==> pathfinish h = pathstart h`, + REPEAT STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o MATCH_MP HOMOTOPIC_PATHS_IMP_SUBSET) THEN + REWRITE_TAC[PATH_IMAGE_LINEPATH; SEGMENT_REFL; SING_SUBSET] THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP COVERING_SPACE_IMP_SURJECTIVE) THEN + FIRST_ASSUM(MP_TAC o MATCH_MP HOMOTOPIC_PATHS_IMP_PATHSTART) THEN + REWRITE_TAC[PATHSTART_LINEPATH] THEN REPEAT STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o + ISPECL [`g:real^1->real^N`; `linepath(a:real^N,a)`; + `h:real^1->real^M`; `linepath(pathstart h:real^M,pathstart h)`] o + MATCH_MP (ONCE_REWRITE_RULE[IMP_CONJ] + COVERING_SPACE_MONODROMY)) THEN + ASM_REWRITE_TAC[PATH_LINEPATH; PATH_IMAGE_LINEPATH; SEGMENT_REFL] THEN + ASM_REWRITE_TAC[SING_SUBSET; PATHSTART_LINEPATH; PATHFINISH_LINEPATH] THEN + DISCH_THEN MATCH_MP_TAC THEN REWRITE_TAC[LINEPATH_REFL] THEN CONJ_TAC THENL + [ASM_MESON_TAC[PATHSTART_IN_PATH_IMAGE; SUBSET]; + REPEAT STRIP_TAC THEN + FIRST_X_ASSUM(fun th -> GEN_REWRITE_TAC RAND_CONV [SYM th]) THEN + REWRITE_TAC[pathstart] THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + REWRITE_TAC[ENDS_IN_UNIT_INTERVAL]]);; + +let COVERING_SPACE_SIMPLY_CONNECTED_LOOP_LIFT_IS_LOOP = prove + (`!p:real^M->real^N c s g h. + covering_space (c,p) s /\ simply_connected s /\ + path g /\ path_image g SUBSET s /\ pathfinish g = pathstart g /\ + path h /\ path_image h SUBSET c /\ + (!t. t IN interval[vec 0,vec 1] ==> p(h t) = g t) + ==> pathfinish h = pathstart h`, + REPEAT STRIP_TAC THEN + FIRST_X_ASSUM(MATCH_MP_TAC o + MATCH_MP (ONCE_REWRITE_RULE[IMP_CONJ] + COVERING_SPACE_INESSENTIAL_LOOP_LIFT_IS_LOOP)) THEN + EXISTS_TAC `g:real^1->real^N` THEN ASM_REWRITE_TAC[] THEN + ASM_MESON_TAC[SIMPLY_CONNECTED_EQ_CONTRACTIBLE_PATH]);; + +(* ------------------------------------------------------------------------- *) +(* Lifting of general functions to covering space *) +(* ------------------------------------------------------------------------- *) + +let COVERING_SPACE_LIFT_GENERAL = prove + (`!p:real^M->real^N c s f:real^P->real^N u a z. + covering_space (c,p) s /\ a IN c /\ z IN u /\ + path_connected u /\ locally path_connected u /\ + f continuous_on u /\ IMAGE f u SUBSET s /\ f z = p a /\ + (!r. path r /\ path_image r SUBSET u /\ + pathstart r = z /\ pathfinish r = z + ==> ?q. path q /\ path_image q SUBSET c /\ + pathstart q = a /\ pathfinish q = a /\ + homotopic_paths s (f o r) (p o q)) + ==> ?g. g continuous_on u /\ IMAGE g u SUBSET c /\ g z = a /\ + (!y. y IN u ==> p(g y) = f y)`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN + `!y. y IN u + ==> ?g h. path g /\ path_image g SUBSET u /\ + pathstart g = z /\ pathfinish g = y /\ + path h /\ path_image h SUBSET c /\ pathstart h = a /\ + (!t. t IN interval[vec 0,vec 1] + ==> (p:real^M->real^N)(h t) = (f:real^P->real^N)(g t))` + (LABEL_TAC "*") + THENL + [X_GEN_TAC `y:real^P` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [path_connected]) THEN + DISCH_THEN(MP_TAC o SPECL [`z:real^P`; `y:real^P`]) THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC MONO_EXISTS THEN + X_GEN_TAC `g:real^1->real^P` THEN STRIP_TAC THEN + ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC COVERING_SPACE_LIFT_PATH_STRONG THEN + EXISTS_TAC `s:real^N->bool` THEN ASM_REWRITE_TAC[GSYM o_DEF] THEN + ASM_REWRITE_TAC[PATH_IMAGE_COMPOSE; PATHSTART_COMPOSE] THEN + CONJ_TAC THENL + [MATCH_MP_TAC PATH_CONTINUOUS_IMAGE THEN + ASM_MESON_TAC[CONTINUOUS_ON_SUBSET]; + ASM SET_TAC[]]; + ALL_TAC] THEN + SUBGOAL_THEN + `?l. !y g h. path g /\ path_image g SUBSET u /\ + pathstart g = z /\ pathfinish g = y /\ + path h /\ path_image h SUBSET c /\ pathstart h = a /\ + (!t. t IN interval[vec 0,vec 1] + ==> (p:real^M->real^N)(h t) = (f:real^P->real^N)(g t)) + ==> pathfinish h = l y` + MP_TAC THENL + [REWRITE_TAC[GSYM SKOLEM_THM] THEN X_GEN_TAC `y:real^P` THEN + MATCH_MP_TAC(MESON[] + `(!g h g' h'. P g h /\ P g' h' ==> f h = f h') + ==> ?z. !g h. P g h ==> f h = z`) THEN + REPEAT STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `(g ++ reversepath g'):real^1->real^P`) THEN + ASM_SIMP_TAC[PATH_JOIN; PATHSTART_JOIN; PATHFINISH_JOIN; + PATH_REVERSEPATH; PATHSTART_REVERSEPATH; PATHFINISH_REVERSEPATH; + SUBSET_PATH_IMAGE_JOIN; PATH_IMAGE_REVERSEPATH] THEN + DISCH_THEN(X_CHOOSE_THEN `q:real^1->real^M` STRIP_ASSUME_TAC) THEN + FIRST_ASSUM(MP_TAC o + ISPECL [`(p:real^M->real^N) o (q:real^1->real^M)`; + `(f:real^P->real^N) o (g ++ reversepath g')`; + `q:real^1->real^M`; `pathstart q:real^M`; `pathfinish q:real^M`] o + MATCH_MP(ONCE_REWRITE_RULE[IMP_CONJ] + (ONCE_REWRITE_RULE[HOMOTOPIC_PATHS_SYM] + COVERING_SPACE_LIFT_HOMOTOPIC_PATH))) THEN + ASM_REWRITE_TAC[o_THM] THEN + DISCH_THEN(X_CHOOSE_THEN `q':real^1->real^M` STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN `path(h ++ reversepath h':real^1->real^M)` MP_TAC THENL + [ALL_TAC; + ASM_SIMP_TAC[PATH_JOIN_EQ; PATH_REVERSEPATH; PATHSTART_REVERSEPATH]] THEN + MATCH_MP_TAC PATH_EQ THEN EXISTS_TAC `q':real^1->real^M` THEN + ASM_REWRITE_TAC[] THEN + X_GEN_TAC `t:real^1` THEN REWRITE_TAC[IN_INTERVAL_1; DROP_VEC] THEN + STRIP_TAC THEN REWRITE_TAC[joinpaths] THEN COND_CASES_TAC THENL + [FIRST_ASSUM(MP_TAC o + ISPECL [`(f:real^P->real^N) o (g:real^1->real^P) o (\t. &2 % t)`; + `q':real^1->real^M`; + `(h:real^1->real^M) o (\t. &2 % t)`; + `interval[vec 0,lift(&1 / &2)]`; + `vec 0:real^1`; `t:real^1`] o + MATCH_MP (ONCE_REWRITE_RULE[IMP_CONJ] COVERING_SPACE_LIFT_UNIQUE)) THEN + REWRITE_TAC[o_THM] THEN DISCH_THEN MATCH_MP_TAC THEN + REPEAT CONJ_TAC THENL + [MATCH_MP_TAC CONTINUOUS_ON_EQ THEN + EXISTS_TAC `(f:real^P->real^N) o (g ++ reversepath g')` THEN + CONJ_TAC THENL + [SIMP_TAC[IN_INTERVAL_1; LIFT_DROP; joinpaths; o_THM]; + ALL_TAC] THEN + MATCH_MP_TAC CONTINUOUS_ON_SUBSET THEN + EXISTS_TAC `interval[vec 0:real^1,vec 1]` THEN CONJ_TAC THENL + [ASM_MESON_TAC[HOMOTOPIC_PATHS_IMP_PATH; path]; + REWRITE_TAC[SUBSET_INTERVAL_1; LIFT_DROP; DROP_VEC] THEN + REAL_ARITH_TAC]; + MATCH_MP_TAC SUBSET_TRANS THEN EXISTS_TAC + `path_image ((f:real^P->real^N) o (g ++ reversepath g'))` THEN + CONJ_TAC THENL[ALL_TAC; ASM_MESON_TAC[HOMOTOPIC_PATHS_IMP_SUBSET]] THEN + REWRITE_TAC[path_image] THEN MATCH_MP_TAC(SET_RULE + `(!x. x IN s ==> f x = g x) /\ s SUBSET t + ==> IMAGE f s SUBSET IMAGE g t`) THEN + REWRITE_TAC[SUBSET_INTERVAL_1; LIFT_DROP; DROP_VEC; IN_INTERVAL_1] THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN SIMP_TAC[joinpaths; o_THM]; + MATCH_MP_TAC CONTINUOUS_ON_SUBSET THEN + EXISTS_TAC `interval[vec 0:real^1,vec 1]` THEN + ASM_REWRITE_TAC[GSYM path] THEN + REWRITE_TAC[SUBSET_INTERVAL_1; LIFT_DROP; DROP_VEC] THEN + REAL_ARITH_TAC; + MATCH_MP_TAC SUBSET_TRANS THEN EXISTS_TAC + `path_image(q':real^1->real^M)` THEN + ASM_REWRITE_TAC[] THEN REWRITE_TAC[path_image] THEN + MATCH_MP_TAC IMAGE_SUBSET THEN + REWRITE_TAC[SUBSET_INTERVAL_1; LIFT_DROP; DROP_VEC] THEN + REAL_ARITH_TAC; + X_GEN_TAC `t':real^1` THEN + REWRITE_TAC[IN_INTERVAL_1; DROP_VEC; LIFT_DROP] THEN STRIP_TAC THEN + FIRST_X_ASSUM(fun th -> + W(MP_TAC o PART_MATCH (lhand o rand) th o rand o snd)) THEN + ASM_SIMP_TAC[IN_INTERVAL_1; joinpaths; DROP_VEC] THEN + ANTS_TAC THENL [ASM_REAL_ARITH_TAC; SIMP_TAC[]]; + MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN + SIMP_TAC[CONTINUOUS_ON_CMUL; CONTINUOUS_ON_ID] THEN + MATCH_MP_TAC CONTINUOUS_ON_SUBSET THEN + EXISTS_TAC `interval[vec 0:real^1,vec 1]` THEN + ASM_SIMP_TAC[GSYM path] THEN + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE] THEN + REWRITE_TAC[IN_INTERVAL_1; DROP_VEC; DROP_CMUL; LIFT_DROP] THEN + REAL_ARITH_TAC; + MATCH_MP_TAC SUBSET_TRANS THEN + EXISTS_TAC `path_image(h:real^1->real^M)` THEN + CONJ_TAC THENL [ALL_TAC; ASM_SIMP_TAC[]] THEN + REWRITE_TAC[path_image; IMAGE_o] THEN MATCH_MP_TAC IMAGE_SUBSET THEN + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; IN_INTERVAL_1] THEN + REWRITE_TAC[DROP_VEC; DROP_CMUL; LIFT_DROP] THEN + REAL_ARITH_TAC; + X_GEN_TAC `t':real^1` THEN + REWRITE_TAC[IN_INTERVAL_1; DROP_VEC; LIFT_DROP] THEN STRIP_TAC THEN + CONV_TAC SYM_CONV THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + REWRITE_TAC[IN_INTERVAL_1; DROP_VEC; DROP_CMUL] THEN + ASM_REAL_ARITH_TAC; + REWRITE_TAC[CONNECTED_INTERVAL]; + REWRITE_TAC[IN_INTERVAL_1; DROP_VEC; LIFT_DROP] THEN REAL_ARITH_TAC; + GEN_REWRITE_TAC LAND_CONV [GSYM pathstart] THEN + ASM_REWRITE_TAC[] THEN + SUBST1_TAC(SYM(ASSUME `pathstart h:real^M = a`)) THEN + REWRITE_TAC[pathstart] THEN AP_TERM_TAC THEN + REWRITE_TAC[VECTOR_MUL_RZERO]; + REWRITE_TAC[IN_INTERVAL_1; DROP_VEC; LIFT_DROP] THEN + ASM_REAL_ARITH_TAC]; + FIRST_ASSUM(MP_TAC o + ISPECL [`(f:real^P->real^N) o reversepath(g':real^1->real^P) o + (\t. &2 % t - vec 1)`; + `q':real^1->real^M`; + `reversepath(h':real^1->real^M) o (\t. &2 % t - vec 1)`; + `{t | &1 / &2 < drop t /\ drop t <= &1}`; + `vec 1:real^1`; `t:real^1`] o + MATCH_MP (ONCE_REWRITE_RULE[IMP_CONJ] COVERING_SPACE_LIFT_UNIQUE)) THEN + REWRITE_TAC[o_THM] THEN DISCH_THEN MATCH_MP_TAC THEN + REPEAT CONJ_TAC THENL + [MATCH_MP_TAC CONTINUOUS_ON_EQ THEN + EXISTS_TAC `(f:real^P->real^N) o (g ++ reversepath g')` THEN + CONJ_TAC THENL + [SIMP_TAC[IN_ELIM_THM; GSYM REAL_NOT_LE; joinpaths; o_THM]; + ALL_TAC] THEN + MATCH_MP_TAC CONTINUOUS_ON_SUBSET THEN + EXISTS_TAC `interval[vec 0:real^1,vec 1]` THEN CONJ_TAC THENL + [ASM_MESON_TAC[HOMOTOPIC_PATHS_IMP_PATH; path]; + REWRITE_TAC[SUBSET; IN_ELIM_THM; IN_INTERVAL_1; DROP_VEC] THEN + REAL_ARITH_TAC]; + MATCH_MP_TAC SUBSET_TRANS THEN EXISTS_TAC + `path_image ((f:real^P->real^N) o (g ++ reversepath g'))` THEN + CONJ_TAC THENL[ALL_TAC; ASM_MESON_TAC[HOMOTOPIC_PATHS_IMP_SUBSET]] THEN + REWRITE_TAC[path_image] THEN MATCH_MP_TAC(SET_RULE + `(!x. x IN s ==> f x = g x) /\ s SUBSET t + ==> IMAGE f s SUBSET IMAGE g t`) THEN + SIMP_TAC[IN_ELIM_THM; GSYM REAL_NOT_LE; joinpaths; o_THM] THEN + REWRITE_TAC[SUBSET; IN_ELIM_THM; IN_INTERVAL_1; DROP_VEC] THEN + REAL_ARITH_TAC; + MATCH_MP_TAC CONTINUOUS_ON_SUBSET THEN + EXISTS_TAC `interval[vec 0:real^1,vec 1]` THEN + ASM_REWRITE_TAC[GSYM path] THEN + REWRITE_TAC[SUBSET; IN_ELIM_THM; IN_INTERVAL_1; DROP_VEC] THEN + REAL_ARITH_TAC; + MATCH_MP_TAC SUBSET_TRANS THEN EXISTS_TAC + `path_image(q':real^1->real^M)` THEN + ASM_REWRITE_TAC[] THEN REWRITE_TAC[path_image] THEN + MATCH_MP_TAC IMAGE_SUBSET THEN + REWRITE_TAC[SUBSET; IN_ELIM_THM; IN_INTERVAL_1; DROP_VEC] THEN + REAL_ARITH_TAC; + X_GEN_TAC `t':real^1` THEN REWRITE_TAC[IN_ELIM_THM] THEN STRIP_TAC THEN + FIRST_X_ASSUM(fun th -> + W(MP_TAC o PART_MATCH (lhand o rand) th o rand o snd)) THEN + ASM_SIMP_TAC[IN_INTERVAL_1; joinpaths; DROP_VEC; GSYM REAL_NOT_LT] THEN + ANTS_TAC THENL [ASM_REAL_ARITH_TAC; SIMP_TAC[]]; + MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN + SIMP_TAC[CONTINUOUS_ON_SUB; CONTINUOUS_ON_CMUL; CONTINUOUS_ON_ID; + CONTINUOUS_ON_CONST] THEN + MATCH_MP_TAC CONTINUOUS_ON_SUBSET THEN + EXISTS_TAC `interval[vec 0:real^1,vec 1]` THEN + ASM_SIMP_TAC[GSYM path; PATH_REVERSEPATH] THEN + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; IN_ELIM_THM] THEN + REWRITE_TAC[IN_INTERVAL_1; DROP_VEC; DROP_CMUL; DROP_SUB] THEN + REAL_ARITH_TAC; + MATCH_MP_TAC SUBSET_TRANS THEN + EXISTS_TAC `path_image(reversepath h':real^1->real^M)` THEN + CONJ_TAC THENL [ALL_TAC; ASM_SIMP_TAC[PATH_IMAGE_REVERSEPATH]] THEN + REWRITE_TAC[path_image; IMAGE_o] THEN MATCH_MP_TAC IMAGE_SUBSET THEN + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; IN_ELIM_THM] THEN + REWRITE_TAC[IN_INTERVAL_1; DROP_VEC; DROP_CMUL; DROP_SUB] THEN + REAL_ARITH_TAC; + X_GEN_TAC `t':real^1` THEN REWRITE_TAC[IN_ELIM_THM] THEN STRIP_TAC THEN + REWRITE_TAC[reversepath] THEN CONV_TAC SYM_CONV THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN + REWRITE_TAC[IN_INTERVAL_1; DROP_SUB; DROP_VEC; DROP_CMUL] THEN + ASM_REAL_ARITH_TAC; + REWRITE_TAC[GSYM IS_INTERVAL_CONNECTED_1; IS_INTERVAL_1] THEN + REWRITE_TAC[IN_ELIM_THM] THEN REAL_ARITH_TAC; + REWRITE_TAC[IN_ELIM_THM; DROP_VEC] THEN REAL_ARITH_TAC; + GEN_REWRITE_TAC LAND_CONV [GSYM pathfinish] THEN + ASM_REWRITE_TAC[reversepath] THEN + SUBST1_TAC(SYM(ASSUME `pathstart h':real^M = a`)) THEN + REWRITE_TAC[pathstart] THEN AP_TERM_TAC THEN + REWRITE_TAC[GSYM DROP_EQ; DROP_SUB; DROP_CMUL; DROP_VEC] THEN + REAL_ARITH_TAC; + REWRITE_TAC[IN_ELIM_THM] THEN ASM_REAL_ARITH_TAC]]; + ALL_TAC] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `l:real^P->real^M` THEN + DISCH_THEN(LABEL_TAC "+") THEN + MATCH_MP_TAC(TAUT `(q ==> p) /\ q ==> p /\ q`) THEN REPEAT CONJ_TAC THENL + [STRIP_TAC; + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE] THEN + X_GEN_TAC `y:real^P` THEN DISCH_TAC THEN + REMOVE_THEN "*" (MP_TAC o SPEC `y:real^P`) THEN + ASM_MESON_TAC[PATHFINISH_IN_PATH_IMAGE; SUBSET]; + FIRST_ASSUM(MP_TAC o SPECL + [`z:real^P`; `linepath(z:real^P,z)`; `linepath(a:real^M,a)`]) THEN + REWRITE_TAC[PATH_LINEPATH; PATH_IMAGE_LINEPATH; SEGMENT_REFL] THEN + REWRITE_TAC[PATHSTART_LINEPATH; PATHFINISH_LINEPATH] THEN + ASM_SIMP_TAC[LINEPATH_REFL; SING_SUBSET]; + X_GEN_TAC `y:real^P` THEN DISCH_TAC THEN + REMOVE_THEN "*" (MP_TAC o SPEC `y:real^P`) THEN + ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`g:real^1->real^P`; `h:real^1->real^M`] THEN + STRIP_TAC THEN FIRST_X_ASSUM(MP_TAC o SPECL + [`y:real^P`; `g:real^1->real^P`; `h:real^1->real^M`]) THEN + ASM_MESON_TAC[pathfinish; ENDS_IN_UNIT_INTERVAL]] THEN + FIRST_ASSUM(fun th -> + GEN_REWRITE_TAC I [MATCH_MP CONTINUOUS_ON_OPEN_GEN th]) THEN + X_GEN_TAC `n:real^M->bool` THEN DISCH_TAC THEN + ONCE_REWRITE_TAC[OPEN_IN_SUBOPEN] THEN X_GEN_TAC `y:real^P` THEN + REWRITE_TAC[IN_ELIM_THM] THEN STRIP_TAC THEN + FIRST_ASSUM(ASSUME_TAC o CONJUNCT1 o GEN_REWRITE_RULE I [open_in]) THEN + FIRST_ASSUM(MP_TAC o SPEC `(f:real^P->real^N) y` o last o CONJUNCTS o + GEN_REWRITE_RULE I [covering_space]) THEN + ANTS_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + DISCH_THEN(X_CHOOSE_THEN `w:real^N->bool` MP_TAC) THEN + REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + DISCH_THEN(X_CHOOSE_THEN `vv:(real^M->bool)->bool` MP_TAC) THEN + ONCE_REWRITE_TAC[IMP_CONJ] THEN + GEN_REWRITE_TAC LAND_CONV [EXTENSION] THEN + DISCH_THEN(MP_TAC o SPEC `(l:real^P->real^M) y`) THEN + MATCH_MP_TAC(TAUT `q /\ (p ==> r) ==> (p <=> q) ==> r`) THEN + CONJ_TAC THENL [ASM SET_TAC[]; REWRITE_TAC[IN_UNIONS]] THEN + DISCH_THEN(X_CHOOSE_THEN `w':real^M->bool` STRIP_ASSUME_TAC) THEN + DISCH_THEN(CONJUNCTS_THEN2 (MP_TAC o SPEC `w':real^M->bool`) MP_TAC) THEN + DISCH_THEN(MP_TAC o SPEC `w':real^M->bool` o CONJUNCT2) THEN + ASM_REWRITE_TAC[] THEN DISCH_THEN(X_CHOOSE_TAC `p':real^N->real^M`) THEN + DISCH_TAC THEN UNDISCH_THEN `(w':real^M->bool) IN vv` (K ALL_TAC) THEN + SUBGOAL_THEN + `?v. y IN v /\ y IN u /\ IMAGE (f:real^P->real^N) v SUBSET w /\ + v SUBSET u /\ path_connected v /\ open_in (subtopology euclidean u) v` + STRIP_ASSUME_TAC THENL + [FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [LOCALLY_PATH_CONNECTED]) THEN + DISCH_THEN(MP_TAC o SPECL + [`{x | x IN u /\ (f:real^P->real^N) x IN w}`; `y:real^P`]) THEN + ANTS_TAC THENL [ALL_TAC; MATCH_MP_TAC MONO_EXISTS THEN ASM SET_TAC[]] THEN + CONJ_TAC THENL [ALL_TAC; ASM SET_TAC[]] THEN + MATCH_MP_TAC CONTINUOUS_OPEN_IN_PREIMAGE_GEN THEN + EXISTS_TAC `s:real^N->bool` THEN ASM_REWRITE_TAC[]; + ALL_TAC] THEN + FIRST_X_ASSUM(STRIP_ASSUME_TAC o + GEN_REWRITE_RULE I [homeomorphism]) THEN + SUBGOAL_THEN `(w':real^M->bool) SUBSET c /\ (w:real^N->bool) SUBSET s` + STRIP_ASSUME_TAC THENL [ASM_MESON_TAC[open_in]; ALL_TAC] THEN + EXISTS_TAC + `v INTER + {x | x IN u /\ (f:real^P->real^N) x IN + {x | x IN w /\ (p':real^N->real^M) x IN w' INTER n}}` THEN + REPEAT CONJ_TAC THENL + [MATCH_MP_TAC OPEN_IN_INTER THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC CONTINUOUS_OPEN_IN_PREIMAGE_GEN THEN + EXISTS_TAC `s:real^N->bool` THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC OPEN_IN_TRANS THEN EXISTS_TAC `w:real^N->bool` THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC CONTINUOUS_OPEN_IN_PREIMAGE_GEN THEN + EXISTS_TAC `w':real^M->bool` THEN ASM_REWRITE_TAC[SUBSET_REFL] THEN + UNDISCH_TAC `open_in (subtopology euclidean c) (n:real^M->bool)` THEN + REWRITE_TAC[OPEN_IN_OPEN] THEN MATCH_MP_TAC MONO_EXISTS THEN ASM SET_TAC[]; + ASM SET_TAC[]; + ALL_TAC] THEN + SIMP_TAC[SUBSET; IN_INTER; IN_ELIM_THM] THEN + X_GEN_TAC `y':real^P` THEN STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [path_connected]) THEN + DISCH_THEN(MP_TAC o SPECL [`y:real^P`; `y':real^P`]) THEN + ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `r:real^1->real^P` STRIP_ASSUME_TAC) THEN + REMOVE_THEN "*" (MP_TAC o SPEC `y:real^P`) THEN + ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`pp:real^1->real^P`; `qq:real^1->real^M`] THEN + STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o SPECL + [`y':real^P`; `(pp:real^1->real^P) ++ r`; + `(qq:real^1->real^M) ++ ((p':real^N->real^M) o (f:real^P->real^N) o + (r:real^1->real^P))`]) THEN + FIRST_X_ASSUM(MP_TAC o SPECL + [`y:real^P`; `pp:real^1->real^P`; `qq:real^1->real^M`]) THEN + ASM_SIMP_TAC[o_THM; PATHSTART_JOIN; PATHFINISH_JOIN] THEN DISCH_TAC THEN + SUBGOAL_THEN + `path_image ((pp:real^1->real^P) ++ r) SUBSET u` + ASSUME_TAC THENL + [MATCH_MP_TAC SUBSET_PATH_IMAGE_JOIN THEN ASM SET_TAC[]; ALL_TAC] THEN + ANTS_TAC THENL + [ALL_TAC; + ASM_REWRITE_TAC[PATHFINISH_COMPOSE] THEN ASM_MESON_TAC[]] THEN + REPEAT CONJ_TAC THENL + [ASM_SIMP_TAC[PATH_JOIN]; + ASM_SIMP_TAC[SUBSET_PATH_IMAGE_JOIN]; + MATCH_MP_TAC PATH_JOIN_IMP THEN ASM_SIMP_TAC[PATHSTART_COMPOSE] THEN + CONJ_TAC THENL + [REWRITE_TAC[o_ASSOC] THEN MATCH_MP_TAC PATH_CONTINUOUS_IMAGE THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN + CONJ_TAC THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET)) THEN + ASM SET_TAC[]; + REWRITE_TAC[pathfinish] THEN ASM SET_TAC[]]; + MATCH_MP_TAC SUBSET_PATH_IMAGE_JOIN THEN ASM_SIMP_TAC[] THEN + REWRITE_TAC[PATH_IMAGE_COMPOSE] THEN ASM SET_TAC[]; + X_GEN_TAC `tt:real^1` THEN REWRITE_TAC[IN_INTERVAL_1; DROP_VEC] THEN + STRIP_TAC THEN REWRITE_TAC[joinpaths; o_THM] THEN COND_CASES_TAC THEN + ASM_REWRITE_TAC[] THENL + [ABBREV_TAC `t:real^1 = &2 % tt`; + ABBREV_TAC `t:real^1 = &2 % tt - vec 1`] THEN + (SUBGOAL_THEN `t IN interval[vec 0:real^1,vec 1]` ASSUME_TAC THENL + [EXPAND_TAC "t" THEN + REWRITE_TAC[IN_INTERVAL_1; DROP_VEC; DROP_CMUL; DROP_SUB] THEN + ASM_REAL_ARITH_TAC; + ALL_TAC]) THEN + ASM_SIMP_TAC[] THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + RULE_ASSUM_TAC(REWRITE_RULE[path_image]) THEN ASM SET_TAC[]]);; + +let COVERING_SPACE_LIFT_STRONGER = prove + (`!p:real^M->real^N c s f:real^P->real^N u a z. + covering_space (c,p) s /\ a IN c /\ z IN u /\ + path_connected u /\ locally path_connected u /\ + f continuous_on u /\ IMAGE f u SUBSET s /\ f z = p a /\ + (!r. path r /\ path_image r SUBSET u /\ + pathstart r = z /\ pathfinish r = z + ==> ?b. homotopic_paths s (f o r) (linepath(b,b))) + ==> ?g. g continuous_on u /\ IMAGE g u SUBSET c /\ g z = a /\ + (!y. y IN u ==> p(g y) = f y)`, + REPEAT STRIP_TAC THEN + FIRST_ASSUM(MATCH_MP_TAC o MATCH_MP (ONCE_REWRITE_RULE[IMP_CONJ] + COVERING_SPACE_LIFT_GENERAL)) THEN ASM_REWRITE_TAC[] THEN + X_GEN_TAC `r:real^1->real^P` THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `r:real^1->real^P`) THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_TAC `b:real^N`) THEN + FIRST_ASSUM(MP_TAC o MATCH_MP HOMOTOPIC_PATHS_IMP_PATHSTART) THEN + ASM_REWRITE_TAC[PATHSTART_COMPOSE; PATHSTART_LINEPATH] THEN + DISCH_THEN(SUBST_ALL_TAC o SYM) THEN + EXISTS_TAC `linepath(a:real^M,a)` THEN + REWRITE_TAC[PATH_LINEPATH; PATHSTART_LINEPATH; PATHFINISH_LINEPATH] THEN + ASM_REWRITE_TAC[PATH_IMAGE_LINEPATH; SEGMENT_REFL; SING_SUBSET] THEN + RULE_ASSUM_TAC(REWRITE_RULE[o_DEF; LINEPATH_REFL]) THEN + ASM_REWRITE_TAC[o_DEF; LINEPATH_REFL]);; + +let COVERING_SPACE_LIFT_STRONG = prove + (`!p:real^M->real^N c s f:real^P->real^N u a z. + covering_space (c,p) s /\ a IN c /\ z IN u /\ + simply_connected u /\ locally path_connected u /\ + f continuous_on u /\ IMAGE f u SUBSET s /\ f z = p a + ==> ?g. g continuous_on u /\ IMAGE g u SUBSET c /\ g z = a /\ + (!y. y IN u ==> p(g y) = f y)`, + REPEAT STRIP_TAC THEN + FIRST_ASSUM(MATCH_MP_TAC o MATCH_MP (ONCE_REWRITE_RULE[IMP_CONJ] + COVERING_SPACE_LIFT_STRONGER)) THEN + ASM_SIMP_TAC[SIMPLY_CONNECTED_IMP_PATH_CONNECTED] THEN + X_GEN_TAC `r:real^1->real^P` THEN STRIP_TAC THEN + EXISTS_TAC `(f:real^P->real^N) z` THEN + SUBGOAL_THEN + `linepath(f z,f z) = (f:real^P->real^N) o linepath(z,z)` + SUBST1_TAC THENL [REWRITE_TAC[o_DEF; LINEPATH_REFL]; ALL_TAC] THEN + MATCH_MP_TAC HOMOTOPIC_PATHS_CONTINUOUS_IMAGE THEN + EXISTS_TAC `u:real^P->bool` THEN ASM_REWRITE_TAC[] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o CONJUNCT2 o GEN_REWRITE_RULE I + [SIMPLY_CONNECTED_EQ_HOMOTOPIC_PATHS]) THEN + ASM_REWRITE_TAC[PATH_LINEPATH; PATHSTART_LINEPATH; PATHFINISH_LINEPATH] THEN + ASM_REWRITE_TAC[PATH_IMAGE_LINEPATH; SEGMENT_REFL; SING_SUBSET]);; + +let COVERING_SPACE_LIFT = prove + (`!p:real^M->real^N c s f:real^P->real^N u. + covering_space (c,p) s /\ + simply_connected u /\ locally path_connected u /\ + f continuous_on u /\ IMAGE f u SUBSET s + ==> ?g. g continuous_on u /\ IMAGE g u SUBSET c /\ + (!y. y IN u ==> p(g y) = f y)`, + MP_TAC COVERING_SPACE_LIFT_STRONG THEN + REPEAT(MATCH_MP_TAC MONO_FORALL THEN GEN_TAC) THEN + DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th THEN ASM_REWRITE_TAC[]) THEN + ASM_CASES_TAC `u:real^P->bool = {}` THEN + ASM_REWRITE_TAC[CONTINUOUS_ON_EMPTY; IMAGE_CLAUSES; EMPTY_SUBSET; + NOT_IN_EMPTY] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN + DISCH_THEN(X_CHOOSE_TAC `a:real^P`) THEN + FIRST_ASSUM(MP_TAC o MATCH_MP COVERING_SPACE_IMP_SURJECTIVE) THEN + GEN_REWRITE_TAC LAND_CONV [EXTENSION] THEN + DISCH_THEN(MP_TAC o SPEC `(f:real^P->real^N) a`) THEN + MATCH_MP_TAC(TAUT `q /\ (p ==> r) ==> (p <=> q) ==> r`) THEN + CONJ_TAC THENL [ASM SET_TAC[]; REWRITE_TAC[IN_IMAGE]] THEN + ASM_MESON_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* Some additional lemmas about covering spaces. *) +(* ------------------------------------------------------------------------- *) + +let CARD_EQ_COVERING_MAP_FIBRES = prove + (`!p:real^M->real^N c s a b. + covering_space (c,p) s /\ path_connected s /\ a IN s /\ b IN s + ==> {x | x IN c /\ p(x) = a} =_c {x | x IN c /\ p(x) = b}`, + REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN + REPEAT GEN_TAC THEN REPEAT DISCH_TAC THEN + REWRITE_TAC[GSYM CARD_LE_ANTISYM] THEN + REWRITE_TAC[RIGHT_IMP_FORALL_THM; IMP_IMP; FORALL_AND_THM; + TAUT `p ==> q /\ r <=> (p ==> q) /\ (p ==> r)`] THEN + GEN_REWRITE_TAC (LAND_CONV o funpow 2 BINDER_CONV o LAND_CONV) + [CONJ_SYM] THEN + MATCH_MP_TAC(MESON[] + `(!a b. P a b) ==> (!a b. P a b) /\ (!a b. P b a)`) THEN + REPEAT STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`a:real^N`; `b:real^N`] o + GEN_REWRITE_RULE I [path_connected]) THEN + ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `g:real^1->real^N` THEN STRIP_TAC THEN + SUBGOAL_THEN + `!z. ?h. z IN c /\ p z = a + ==> path h /\ path_image h SUBSET c /\ pathstart h = z /\ + !t. t IN interval[vec 0,vec 1] + ==> (p:real^M->real^N)(h t) = g t` + MP_TAC THENL + [REWRITE_TAC[RIGHT_EXISTS_IMP_THM] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC COVERING_SPACE_LIFT_PATH_STRONG THEN + REWRITE_TAC[ETA_AX] THEN ASM_MESON_TAC[]; + REWRITE_TAC[SKOLEM_THM; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `h:real^M->real^1->real^M` THEN DISCH_TAC] THEN + REWRITE_TAC[le_c; IN_ELIM_THM] THEN + EXISTS_TAC `\z. pathfinish((h:real^M->real^1->real^M) z)` THEN + ASM_REWRITE_TAC[pathfinish] THEN CONJ_TAC THENL + [X_GEN_TAC `x:real^M` THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `x:real^M`) THEN + ASM_REWRITE_TAC[SUBSET; path_image; pathstart; FORALL_IN_IMAGE] THEN + ASM_MESON_TAC[pathfinish; ENDS_IN_UNIT_INTERVAL]; + MAP_EVERY X_GEN_TAC [`x:real^M`; `y:real^M`] THEN STRIP_TAC THEN + MP_TAC(ISPECL + [`p:real^M->real^N`; `c:real^M->bool`; `s:real^N->bool`; + `reversepath(g:real^1->real^N)`; `reversepath(g:real^1->real^N)`; + `reversepath((h:real^M->real^1->real^M) x)`; + `reversepath((h:real^M->real^1->real^M) y)`] + COVERING_SPACE_MONODROMY) THEN + ASM_SIMP_TAC[PATHSTART_REVERSEPATH; PATHFINISH_REVERSEPATH] THEN + DISCH_THEN MATCH_MP_TAC THEN + ASM_SIMP_TAC[PATH_REVERSEPATH; PATH_IMAGE_REVERSEPATH; + HOMOTOPIC_PATHS_REFL] THEN + ASM_REWRITE_TAC[pathfinish; reversepath; IN_INTERVAL_1; DROP_VEC] THEN + REPEAT STRIP_TAC THENL + [FIRST_X_ASSUM(MP_TAC o SPEC `x:real^M`); + FIRST_X_ASSUM(MP_TAC o SPEC `y:real^M`)] THEN + ASM_REWRITE_TAC[] THEN DISCH_THEN(MATCH_MP_TAC o last o CONJUNCTS) THEN + REWRITE_TAC[IN_INTERVAL_1; DROP_SUB; DROP_VEC] THEN ASM_REAL_ARITH_TAC]);; + +let COVERING_SPACE_INJECTIVE = prove + (`!p:real^M->real^N c s. + covering_space (c,p) s /\ path_connected c /\ simply_connected s + ==> (!x y. x IN c /\ y IN c /\ p x = p y ==> x = y)`, + REPEAT STRIP_TAC THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP COVERING_SPACE_IMP_SURJECTIVE) THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP COVERING_SPACE_IMP_CONTINUOUS) THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [path_connected]) THEN + DISCH_THEN(MP_TAC o SPECL [`x:real^M`; `y:real^M`]) THEN + ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `g:real^1->real^M` STRIP_ASSUME_TAC) THEN + FIRST_ASSUM(MP_TAC o MATCH_MP (ONCE_REWRITE_RULE[IMP_CONJ] + COVERING_SPACE_LIFT_PATH_STRONG)) THEN + GEN_REWRITE_TAC LAND_CONV [SWAP_FORALL_THM] THEN + DISCH_THEN(MP_TAC o SPEC `x:real^M`) THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(fun th -> + MP_TAC(SPEC `(p:real^M->real^N) o (g:real^1->real^M)` th) THEN + MP_TAC(SPEC `(p:real^M->real^N) o linepath(x:real^M,x)` th)) THEN + SUBGOAL_THEN + `(path ((p:real^M->real^N) o linepath(x,x)) /\ + path (p o g)) /\ + (path_image (p o linepath(x:real^M,x)) SUBSET s /\ + path_image (p o g) SUBSET s)` + STRIP_ASSUME_TAC THENL + [CONJ_TAC THENL + [CONJ_TAC THEN MATCH_MP_TAC PATH_CONTINUOUS_IMAGE THEN + REWRITE_TAC[PATH_LINEPATH; PATH_IMAGE_LINEPATH] THEN + ASM_REWRITE_TAC[CONTINUOUS_ON_SING; SEGMENT_REFL] THEN + ASM_MESON_TAC[CONTINUOUS_ON_SUBSET]; + REWRITE_TAC[PATH_IMAGE_COMPOSE; PATH_IMAGE_LINEPATH] THEN + REWRITE_TAC[SEGMENT_REFL] THEN ASM SET_TAC[]]; + ALL_TAC] THEN + ASM_REWRITE_TAC[PATHSTART_COMPOSE; PATHSTART_LINEPATH] THEN + DISCH_THEN(X_CHOOSE_THEN `h1:real^1->real^M` STRIP_ASSUME_TAC) THEN + DISCH_THEN(X_CHOOSE_THEN `h2:real^1->real^M` STRIP_ASSUME_TAC) THEN + FIRST_ASSUM(MP_TAC o + SPECL [`(p:real^M->real^N) o linepath(x:real^M,x)`; + `(p:real^M->real^N) o (g:real^1->real^M)`; + `h1:real^1->real^M`; `h2:real^1->real^M`] o + MATCH_MP (ONCE_REWRITE_RULE[IMP_CONJ] + COVERING_SPACE_MONODROMY)) THEN + ASM_SIMP_TAC[] THEN ANTS_TAC THENL + [FIRST_X_ASSUM(MATCH_MP_TAC o CONJUNCT2 o + GEN_REWRITE_RULE I [SIMPLY_CONNECTED_EQ_HOMOTOPIC_PATHS]) THEN + ASM_REWRITE_TAC[PATHSTART_COMPOSE; PATHFINISH_COMPOSE] THEN + ASM_REWRITE_TAC[PATHSTART_LINEPATH; PATHFINISH_LINEPATH]; + ALL_TAC] THEN + MATCH_MP_TAC EQ_IMP THEN BINOP_TAC THENL + [MATCH_MP_TAC EQ_TRANS THEN + EXISTS_TAC `pathfinish(linepath(x:real^M,x))` THEN + CONJ_TAC THENL [ALL_TAC; REWRITE_TAC[PATHFINISH_LINEPATH]]; + FIRST_X_ASSUM(fun th -> GEN_REWRITE_TAC RAND_CONV [SYM th])] THEN + REWRITE_TAC[pathfinish] THEN + FIRST_ASSUM(MATCH_MP_TAC o MATCH_MP (ONCE_REWRITE_RULE[IMP_CONJ] + COVERING_SPACE_LIFT_UNIQUE)) + THENL + [EXISTS_TAC `(p:real^M->real^N) o (h1:real^1->real^M)`; + EXISTS_TAC `(p:real^M->real^N) o (h2:real^1->real^M)`] THEN + MAP_EVERY EXISTS_TAC [`interval[vec 0:real^1,vec 1]`; `vec 0:real^1`] THEN + REWRITE_TAC[CONNECTED_INTERVAL; ENDS_IN_UNIT_INTERVAL] THEN + ASM_REWRITE_TAC[GSYM path; PATH_LINEPATH; GSYM path_image] THEN + RULE_ASSUM_TAC(REWRITE_RULE[o_THM]) THEN ASM_REWRITE_TAC[o_THM] THEN + ASM_REWRITE_TAC[PATH_IMAGE_LINEPATH; SEGMENT_REFL; SING_SUBSET] THEN + RULE_ASSUM_TAC(REWRITE_RULE[pathstart]) THEN + ASM_REWRITE_TAC[LINEPATH_REFL; PATH_IMAGE_COMPOSE] THEN + (CONJ_TAC THENL + [ASM_MESON_TAC[PATH_CONTINUOUS_IMAGE; CONTINUOUS_ON_SUBSET]; + ASM SET_TAC[]]));; + +let COVERING_SPACE_HOMEOMORPHISM = prove + (`!p:real^M->real^N c s. + covering_space (c,p) s /\ path_connected c /\ simply_connected s + ==> ?q. homeomorphism (c,s) (p,q)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC HOMEOMORPHISM_INJECTIVE_OPEN_MAP THEN + REPEAT CONJ_TAC THENL + [ASM_MESON_TAC[COVERING_SPACE_IMP_CONTINUOUS]; + ASM_MESON_TAC[COVERING_SPACE_IMP_SURJECTIVE]; + ASM_MESON_TAC[COVERING_SPACE_INJECTIVE]; + ASM_MESON_TAC[COVERING_SPACE_OPEN_MAP]]);; + +(* ------------------------------------------------------------------------- *) +(* Results on finiteness of the number of sheets in a covering space. *) +(* ------------------------------------------------------------------------- *) + +let COVERING_SPACE_FIBRE_NO_LIMPT = prove + (`!p:real^M->real^N c s a b. + covering_space (c,p) s /\ a IN c + ==> ~(a limit_point_of {x | x IN c /\ p x = b})`, + REPEAT STRIP_TAC THEN + FIRST_ASSUM(STRIP_ASSUME_TAC o GEN_REWRITE_RULE I [covering_space]) THEN + FIRST_X_ASSUM(MP_TAC o SPEC `(p:real^M->real^N) a`) THEN + ANTS_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + DISCH_THEN(X_CHOOSE_THEN `u:real^N->bool` MP_TAC) THEN + REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + DISCH_THEN(X_CHOOSE_THEN `vv:(real^M->bool)->bool` MP_TAC) THEN + GEN_REWRITE_TAC I [IMP_CONJ] THEN + REWRITE_TAC[EXTENSION; IN_UNIONS; IN_ELIM_THM] THEN + DISCH_THEN(MP_TAC o SPEC `a:real^M`) THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `t:real^M->bool` STRIP_ASSUME_TAC) THEN + STRIP_TAC THEN + REPEAT(FIRST_X_ASSUM(MP_TAC o SPEC `t:real^M->bool`)) THEN + ASM_REWRITE_TAC[] THEN REPEAT DISCH_TAC THEN + FIRST_X_ASSUM(X_CHOOSE_THEN `q:real^N->real^M` MP_TAC) THEN + REWRITE_TAC[homeomorphism] THEN STRIP_TAC THEN + UNDISCH_TAC `open_in (subtopology euclidean c) (t:real^M->bool)` THEN + REWRITE_TAC[OPEN_IN_OPEN] THEN + DISCH_THEN(X_CHOOSE_THEN `v:real^M->bool` STRIP_ASSUME_TAC) THEN + FIRST_X_ASSUM(MP_TAC o SPEC `v:real^M->bool` o + GEN_REWRITE_RULE I [LIMPT_INFINITE_OPEN]) THEN + ANTS_TAC THENL [ASM SET_TAC[]; REWRITE_TAC[INFINITE]] THEN + MATCH_MP_TAC(MESON[FINITE_SING; FINITE_SUBSET] + `(?a. s SUBSET {a}) ==> FINITE s`) THEN + ASM SET_TAC[]);; + +let COVERING_SPACE_COUNTABLE_SHEETS = prove + (`!p:real^M->real^N c s b. + covering_space (c,p) s ==> COUNTABLE {x | x IN c /\ p x = b}`, + REPEAT STRIP_TAC THEN + MATCH_MP_TAC(REWRITE_RULE[] (ONCE_REWRITE_RULE[GSYM CONTRAPOS_THM] + UNCOUNTABLE_CONTAINS_LIMIT_POINT)) THEN + REWRITE_TAC[IN_ELIM_THM] THEN ASM_MESON_TAC[COVERING_SPACE_FIBRE_NO_LIMPT]);; + +let COVERING_SPACE_FINITE_EQ_COMPACT_FIBRE = prove + (`!p:real^M->real^N c s b. + covering_space (c,p) s + ==> (FINITE {x | x IN c /\ p x = b} <=> + compact {x | x IN c /\ p x = b})`, + REPEAT STRIP_TAC THEN EQ_TAC THEN SIMP_TAC[FINITE_IMP_COMPACT] THEN + DISCH_TAC THEN ASM_CASES_TAC `(b:real^N) IN s` THENL + [ONCE_REWRITE_TAC[TAUT `p <=> (~p ==> F)`] THEN DISCH_TAC THEN + FIRST_ASSUM(MP_TAC o + SPEC `{x | x IN c /\ (p:real^M->real^N) x = b}` o + GEN_REWRITE_RULE I [COMPACT_EQ_BOLZANO_WEIERSTRASS]) THEN + ASM_REWRITE_TAC[INFINITE; SUBSET_REFL; IN_ELIM_THM] THEN + DISCH_THEN(X_CHOOSE_THEN `a:real^M` STRIP_ASSUME_TAC) THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`a:real^M`; `b:real^N`] o + MATCH_MP (ONCE_REWRITE_RULE[IMP_CONJ] + COVERING_SPACE_FIBRE_NO_LIMPT)) THEN + ASM_REWRITE_TAC[]; + SUBGOAL_THEN `{x | x IN c /\ (p:real^M->real^N) x = b} = {}` + (fun th -> REWRITE_TAC[th; FINITE_EMPTY]) THEN + FIRST_ASSUM(MP_TAC o MATCH_MP COVERING_SPACE_IMP_SURJECTIVE) THEN + ASM SET_TAC[]]);; + +let COVERING_SPACE_CLOSED_MAP = prove + (`!p:real^M->real^N c s t. + covering_space (c,p) s /\ + (!b. b IN s ==> FINITE {x | x IN c /\ p x = b}) /\ + closed_in (subtopology euclidean c) t + ==> closed_in (subtopology euclidean s) (IMAGE p t)`, + REPEAT STRIP_TAC THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP CLOSED_IN_IMP_SUBSET) THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP COVERING_SPACE_IMP_SURJECTIVE) THEN + REWRITE_TAC[closed_in; TOPSPACE_EUCLIDEAN_SUBTOPOLOGY] THEN CONJ_TAC THENL + [ASM SET_TAC[]; ONCE_REWRITE_TAC[OPEN_IN_SUBOPEN]] THEN + X_GEN_TAC `y:real^N` THEN REWRITE_TAC[IN_DIFF] THEN STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o SPEC `y:real^N` o last o CONJUNCTS o + GEN_REWRITE_RULE I [covering_space]) THEN + ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN X_GEN_TAC `v:real^N->bool` THEN + REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + FIRST_X_ASSUM(MP_TAC o SPEC `y:real^N`) THEN ASM_REWRITE_TAC[] THEN + DISCH_TAC THEN + DISCH_THEN(X_CHOOSE_THEN `uu:(real^M->bool)->bool` STRIP_ASSUME_TAC) THEN + ASM_CASES_TAC `uu:(real^M->bool)->bool = {}` THENL + [ASM_REWRITE_TAC[UNIONS_0; NOT_IN_EMPTY] THEN ASM SET_TAC[]; ALL_TAC] THEN + EXISTS_TAC `INTERS {IMAGE (p:real^M->real^N) (u DIFF t) | u IN uu}` THEN + REPEAT CONJ_TAC THENL + [MATCH_MP_TAC OPEN_IN_INTERS THEN + ASM_REWRITE_TAC[SIMPLE_IMAGE; FORALL_IN_IMAGE; IMAGE_EQ_EMPTY] THEN + CONJ_TAC THENL + [MATCH_MP_TAC FINITE_IMAGE THEN + SUBGOAL_THEN + `!u. u IN uu ==> ?x. x IN u /\ (p:real^M->real^N) x = y` + ASSUME_TAC THENL + [RULE_ASSUM_TAC(REWRITE_RULE[homeomorphism]) THEN ASM SET_TAC[]; + ALL_TAC] THEN + SUBGOAL_THEN + `FINITE (IMAGE (\u. @x. x IN u /\ (p:real^M->real^N) x = y) uu)` + MP_TAC THENL + [FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + FINITE_SUBSET)) THEN ASM SET_TAC[]; + MATCH_MP_TAC EQ_IMP THEN MATCH_MP_TAC FINITE_IMAGE_INJ_EQ THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [pairwise]) THEN + REPEAT(MATCH_MP_TAC MONO_FORALL THEN GEN_TAC) THEN ASM SET_TAC[]]; + X_GEN_TAC `u:real^M->bool` THEN DISCH_TAC THEN + MATCH_MP_TAC OPEN_IN_TRANS THEN EXISTS_TAC `v:real^N->bool` THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC HOMEOMORPHISM_IMP_OPEN_MAP THEN + ONCE_REWRITE_TAC[SWAP_EXISTS_THM] THEN EXISTS_TAC `u:real^M->bool` THEN + ASM_SIMP_TAC[LEFT_EXISTS_AND_THM] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [CLOSED_IN_CLOSED]) THEN + DISCH_THEN(X_CHOOSE_THEN `k:real^M->bool` STRIP_ASSUME_TAC) THEN + ASM_REWRITE_TAC[OPEN_IN_OPEN] THEN + EXISTS_TAC `(:real^M) DIFF k` THEN + ASM_REWRITE_TAC[GSYM closed] THEN ASM SET_TAC[]]; + REWRITE_TAC[IN_INTERS; FORALL_IN_GSPEC] THEN + X_GEN_TAC `u:real^M->bool` THEN DISCH_TAC THEN + REPEAT(FIRST_X_ASSUM(MP_TAC o SPEC `u:real^M->bool`)) THEN + ASM_REWRITE_TAC[homeomorphism] THEN ASM SET_TAC[]; + REWRITE_TAC[SUBSET; INTERS_GSPEC; IN_DIFF; IN_ELIM_THM] THEN + X_GEN_TAC `z:real^N` THEN DISCH_TAC THEN + CONJ_TAC THENL [ASM SET_TAC[]; REWRITE_TAC[IN_IMAGE]] THEN + DISCH_THEN(X_CHOOSE_THEN `w:real^M` STRIP_ASSUME_TAC) THEN + FIRST_X_ASSUM SUBST_ALL_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [EXTENSION]) THEN + DISCH_THEN(MP_TAC o SPEC `w:real^M`) THEN + REWRITE_TAC[IN_ELIM_THM] THEN + MATCH_MP_TAC(TAUT `q /\ r /\ ~s ==> ~(s <=> q /\ r)`) THEN + RULE_ASSUM_TAC(REWRITE_RULE[homeomorphism]) THEN + REPEAT(CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC]) THEN + REWRITE_TAC[IN_UNIONS] THEN ASM SET_TAC[]]);; + +let COVERING_SPACE_FINITE_SHEETS_EQ_CLOSED_MAP_STRONG = prove + (`!p:real^M->real^N c s. + covering_space (c,p) s /\ (!b. b IN s ==> b limit_point_of s) + ==> ((!b. b IN s ==> FINITE {x | x IN c /\ p x = b}) <=> + (!t. closed_in (subtopology euclidean c) t + ==> closed_in (subtopology euclidean s) (IMAGE p t)))`, + let lemma = prove + (`!f:num->real^N. + (!n. ~(s = v n) ==> DISJOINT s (v n)) + ==> (!n. f n IN v n) /\ + (!m n. v m = v n <=> m = n) + ==> ?n. IMAGE f (:num) INTER s SUBSET {f n}`, + ASM_CASES_TAC `?n. s = (v:num->real^N->bool) n` THENL + [REPEAT STRIP_TAC THEN FIRST_X_ASSUM(fun th -> + MP_TAC th THEN MATCH_MP_TAC MONO_EXISTS); + RULE_ASSUM_TAC(REWRITE_RULE[NOT_EXISTS_THM]) THEN + ASM_REWRITE_TAC[]] THEN + ASM SET_TAC[]) in + REPEAT STRIP_TAC THEN EQ_TAC THEN REPEAT STRIP_TAC THENL + [MATCH_MP_TAC COVERING_SPACE_CLOSED_MAP THEN + EXISTS_TAC `c:real^M->bool` THEN ASM_REWRITE_TAC[]; + ALL_TAC] THEN + REWRITE_TAC[MESON[INFINITE] `FINITE s <=> ~INFINITE s`] THEN DISCH_TAC THEN + FIRST_ASSUM(MP_TAC o SPEC `b:real^N` o last o CONJUNCTS o + GEN_REWRITE_RULE I [covering_space]) THEN + ASM_REWRITE_TAC[NOT_EXISTS_THM] THEN X_GEN_TAC `t:real^N->bool` THEN + REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + DISCH_THEN(X_CHOOSE_THEN `vv:(real^M->bool)->bool` STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN `(b:real^N) limit_point_of t` MP_TAC THENL + [MATCH_MP_TAC LIMPT_OF_OPEN_IN THEN ASM_MESON_TAC[]; + PURE_REWRITE_TAC[LIMPT_SEQUENTIAL_INJ]] THEN + DISCH_THEN(X_CHOOSE_THEN `y:num->real^N` STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN `INFINITE(vv:(real^M->bool)->bool)` MP_TAC THENL + [FIRST_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CARD_LE_INFINITE)) THEN REWRITE_TAC[le_c] THEN + SUBGOAL_THEN + `!x. ?v. x IN c /\ (p:real^M->real^N) x = b ==> v IN vv /\ x IN v` + MP_TAC THENL [ASM SET_TAC[]; REWRITE_TAC[SKOLEM_THM]] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `f:real^M->real^M->bool` THEN + REWRITE_TAC[IN_ELIM_THM] THEN DISCH_TAC THEN CONJ_TAC THENL + [ASM SET_TAC[]; ALL_TAC] THEN + MAP_EVERY X_GEN_TAC [`x:real^M`; `y:real^M`] THEN STRIP_TAC THEN + FIRST_X_ASSUM(fun th -> + MP_TAC(SPEC `x:real^M` th) THEN MP_TAC(SPEC `y:real^M` th)) THEN + ASM_REWRITE_TAC[] THEN + RULE_ASSUM_TAC(REWRITE_RULE[homeomorphism]) THEN ASM SET_TAC[]; + ALL_TAC] THEN + REWRITE_TAC[INFINITE_CARD_LE; le_c; INJECTIVE_ON_ALT] THEN + REWRITE_TAC[IN_UNIV] THEN + DISCH_THEN(X_CHOOSE_THEN `v:num->real^M->bool` STRIP_ASSUME_TAC) THEN + UNDISCH_THEN + `!u. u IN vv ==> ?q:real^N->real^M. homeomorphism (u,t) (p,q)` + (MP_TAC o GEN `n:num` o SPEC `(v:num->real^M->bool) n`) THEN + ASM_REWRITE_TAC[SKOLEM_THM; homeomorphism; FORALL_AND_THM] THEN + DISCH_THEN(X_CHOOSE_THEN `q:num->real^N->real^M` STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN + `closed_in (subtopology euclidean s) + (IMAGE (p:real^M->real^N) (IMAGE (\n. q n (y n:real^N)) (:num)))` + MP_TAC THENL + [FIRST_X_ASSUM MATCH_MP_TAC THEN + REWRITE_TAC[CLOSED_IN_LIMPT; SUBSET; FORALL_IN_IMAGE] THEN + CONJ_TAC THENL [ASM SET_TAC[]; X_GEN_TAC `a:real^M`] THEN STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o MATCH_MP LIMPT_OF_SEQUENCE_SUBSEQUENCE) THEN + DISCH_THEN(X_CHOOSE_THEN `r:num->num` STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN `(p:real^M->real^N) a = b` ASSUME_TAC THENL + [MATCH_MP_TAC(ISPEC `sequentially` LIM_UNIQUE) THEN + EXISTS_TAC + `(p:real^M->real^N) o (\n:num. q n (y n :real^N)) o (r:num->num)` THEN + REWRITE_TAC[TRIVIAL_LIMIT_SEQUENTIALLY] THEN CONJ_TAC THENL + [MATCH_MP_TAC(GEN_ALL(REWRITE_RULE[RIGHT_IMP_FORALL_THM; IMP_IMP] + (fst(EQ_IMP_RULE(SPEC_ALL CONTINUOUS_ON_SEQUENTIALLY))))) THEN + EXISTS_TAC `c:real^M->bool` THEN ASM_REWRITE_TAC[] THEN CONJ_TAC THENL + [ASM_MESON_TAC[COVERING_SPACE_IMP_CONTINUOUS]; + REWRITE_TAC[o_DEF] THEN ASM SET_TAC[]]; + REWRITE_TAC[o_ASSOC] THEN MATCH_MP_TAC LIM_SUBSEQUENCE THEN + ASM_REWRITE_TAC[] THEN FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP + (REWRITE_RULE[IMP_CONJ_ALT] LIM_TRANSFORM_EVENTUALLY)) THEN + MATCH_MP_TAC ALWAYS_EVENTUALLY THEN REWRITE_TAC[o_DEF] THEN + ASM SET_TAC[]]; + SUBGOAL_THEN `?u. u IN vv /\ (a:real^M) IN u` STRIP_ASSUME_TAC THENL + [ASM SET_TAC[]; ALL_TAC] THEN + SUBGOAL_THEN `?w:real^M->bool. open w /\ u = c INTER w` + (CHOOSE_THEN (CONJUNCTS_THEN2 ASSUME_TAC SUBST_ALL_TAC)) + THENL [ASM_MESON_TAC[OPEN_IN_OPEN]; ALL_TAC] THEN + RULE_ASSUM_TAC(REWRITE_RULE[IN_INTER]) THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [LIMPT_INFINITE_OPEN]) THEN + DISCH_THEN(MP_TAC o SPEC `w:real^M->bool`) THEN + ASM_REWRITE_TAC[] THEN DISCH_THEN(MP_TAC o MATCH_MP (MESON[] + `INFINITE s ==> !k. s INTER k = s ==> INFINITE(s INTER k)`)) THEN + DISCH_THEN(MP_TAC o SPEC `c:real^M->bool`) THEN ANTS_TAC THENL + [ASM SET_TAC[]; REWRITE_TAC[INTER_ASSOC]] THEN + ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN + REWRITE_TAC[INFINITE] THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [pairwise]) THEN + DISCH_THEN(MP_TAC o SPEC `c INTER w:real^M->bool`) THEN + ASM_REWRITE_TAC[] THEN + DISCH_THEN(MP_TAC o GEN `n:num` o SPEC `(v:num->real^M->bool) n`) THEN + ASM_REWRITE_TAC[] THEN + DISCH_THEN(MP_TAC o SPEC `\n. (q:num->real^N->real^M) n (y n)` o + MATCH_MP lemma) THEN + ASM_REWRITE_TAC[] THEN ANTS_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + MESON_TAC[FINITE_SUBSET; FINITE_SING; INTER_COMM]]; + SUBGOAL_THEN + `IMAGE (p:real^M->real^N) (IMAGE (\n. q n (y n:real^N)) (:num)) = + IMAGE y (:num)` + SUBST1_TAC THENL + [REWRITE_TAC[GSYM IMAGE_o; o_DEF] THEN ASM SET_TAC[]; ALL_TAC] THEN + REWRITE_TAC[CLOSED_IN_LIMPT] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC (MP_TAC o SPEC `b:real^N`)) THEN + ASM_REWRITE_TAC[NOT_IMP] THEN CONJ_TAC THENL [ALL_TAC; ASM SET_TAC[]] THEN + REWRITE_TAC[LIMPT_SEQUENTIAL_INJ] THEN + EXISTS_TAC `y:num->real^N` THEN ASM SET_TAC[]]);; + +let COVERING_SPACE_FINITE_SHEETS_EQ_CLOSED_MAP = prove + (`!p:real^M->real^N c s. + covering_space (c,p) s /\ connected s /\ ~(?a. s = {a}) + ==> ((!b. b IN s ==> FINITE {x | x IN c /\ p x = b}) <=> + (!t. closed_in (subtopology euclidean c) t + ==> closed_in (subtopology euclidean s) (IMAGE p t)))`, + REPEAT STRIP_TAC THEN ASM_CASES_TAC `s:real^N->bool = {}` THENL + [SUBGOAL_THEN `c:real^M->bool = {}` ASSUME_TAC THENL + [FIRST_ASSUM(MP_TAC o MATCH_MP COVERING_SPACE_IMP_SURJECTIVE) THEN + ASM_REWRITE_TAC[IMAGE_EQ_EMPTY]; + ASM_REWRITE_TAC[OPEN_IN_SUBTOPOLOGY_EMPTY; CLOSED_IN_SUBTOPOLOGY_EMPTY; + IMAGE_EQ_EMPTY; NOT_IN_EMPTY]]; + MATCH_MP_TAC COVERING_SPACE_FINITE_SHEETS_EQ_CLOSED_MAP_STRONG THEN + ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC CONNECTED_IMP_PERFECT THEN ASM SET_TAC[]]);; + +let COVERING_SPACE_FINITE_SHEETS_EQ_PROPER_MAP = prove + (`!p:real^M->real^N c s. + covering_space (c,p) s + ==> ((!b. b IN s ==> FINITE {x | x IN c /\ p x = b}) <=> + (!k. k SUBSET s /\ compact k + ==> compact {x | x IN c /\ p(x) IN k}))`, + REPEAT STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o MATCH_MP COVERING_SPACE_IMP_SURJECTIVE) THEN + DISCH_THEN(MP_TAC o MATCH_MP (SET_RULE `s = t ==> s SUBSET t`)) THEN + DISCH_THEN(fun th -> REWRITE_TAC[MATCH_MP PROPER_MAP th]) THEN + FIRST_ASSUM(fun th -> REWRITE_TAC + [GSYM(MATCH_MP COVERING_SPACE_FINITE_EQ_COMPACT_FIBRE th)]) THEN + REWRITE_TAC[TAUT `(p <=> q /\ p) <=> (p ==> q)`] THEN + ASM_MESON_TAC[COVERING_SPACE_CLOSED_MAP]);; + +(* ------------------------------------------------------------------------- *) +(* Special cases where one or both of the sets is compact. *) +(* ------------------------------------------------------------------------- *) + +let COVERING_SPACE_FINITE_SHEETS = prove + (`!p:real^M->real^N c s b. + covering_space (c,p) s /\ compact c ==> FINITE {x | x IN c /\ p x = b}`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC BOLZANO_WEIERSTRASS_CONTRAPOS THEN + EXISTS_TAC `c:real^M->bool` THEN ASM_REWRITE_TAC[SUBSET_RESTRICT] THEN + ASM_MESON_TAC[COVERING_SPACE_FIBRE_NO_LIMPT]);; + +let COVERING_SPACE_COMPACT = prove + (`!p:real^M->real^N c s. + covering_space (c,p) s + ==> (compact c <=> + compact s /\ (!b. b IN s ==> FINITE {x | x IN c /\ p x = b}))`, + REPEAT STRIP_TAC THEN EQ_TAC THEN REPEAT STRIP_TAC THENL + [ASM_MESON_TAC[covering_space; COMPACT_CONTINUOUS_IMAGE]; + MATCH_MP_TAC COVERING_SPACE_FINITE_SHEETS THEN ASM_MESON_TAC[]; + FIRST_ASSUM(MP_TAC o + MATCH_MP COVERING_SPACE_FINITE_SHEETS_EQ_PROPER_MAP) THEN + ASM_REWRITE_TAC[] THEN DISCH_THEN(MP_TAC o SPEC `s:real^N->bool`) THEN + ASM_REWRITE_TAC[SUBSET_REFL] THEN MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN + FIRST_ASSUM(MP_TAC o MATCH_MP COVERING_SPACE_IMP_SURJECTIVE) THEN + SET_TAC[]]);; diff --git a/Multivariate/polytope.ml b/Multivariate/polytope.ml new file mode 100644 index 0000000..97c3d47 --- /dev/null +++ b/Multivariate/polytope.ml @@ -0,0 +1,5640 @@ +(* ========================================================================= *) +(* Faces, extreme points, polytopes, polyhedra etc. *) +(* ========================================================================= *) + +needs "Multivariate/paths.ml";; + +(* ------------------------------------------------------------------------- *) +(* Faces of a (usually convex) set. *) +(* ------------------------------------------------------------------------- *) + +parse_as_infix("face_of",(12,"right"));; + +let face_of = new_definition + `t face_of s <=> + t SUBSET s /\ convex t /\ + !a b x. a IN s /\ b IN s /\ x IN t /\ x IN segment(a,b) + ==> a IN t /\ b IN t`;; + +let FACE_OF_TRANSLATION_EQ = prove + (`!a f s:real^N->bool. + (IMAGE (\x. a + x) f) face_of (IMAGE (\x. a + x) s) <=> f face_of s`, + REWRITE_TAC[face_of] THEN GEOM_TRANSLATE_TAC[]);; + +add_translation_invariants [FACE_OF_TRANSLATION_EQ];; + +let FACE_OF_LINEAR_IMAGE = prove + (`!f:real^M->real^N c s. + linear f /\ (!x y. f x = f y ==> x = y) + ==> ((IMAGE f c) face_of (IMAGE f s) <=> c face_of s)`, + REWRITE_TAC[face_of; IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_IMAGE] THEN + REPEAT STRIP_TAC THEN MP_TAC(end_itlist CONJ + (mapfilter (ISPEC `f:real^M->real^N`) (!invariant_under_linear))) THEN + ASM_REWRITE_TAC[] THEN DISCH_TAC THEN ASM_REWRITE_TAC[]);; + +add_linear_invariants [FACE_OF_LINEAR_IMAGE];; + +let FACE_OF_REFL = prove + (`!s. convex s ==> s face_of s`, + SIMP_TAC[face_of] THEN SET_TAC[]);; + +let FACE_OF_REFL_EQ = prove + (`!s. s face_of s <=> convex s`, + SIMP_TAC[face_of] THEN SET_TAC[]);; + +let EMPTY_FACE_OF = prove + (`!s. {} face_of s`, + REWRITE_TAC[face_of; CONVEX_EMPTY] THEN SET_TAC[]);; + +let FACE_OF_EMPTY = prove + (`!s. s face_of {} <=> s = {}`, + REWRITE_TAC[face_of; SUBSET_EMPTY; NOT_IN_EMPTY] THEN + MESON_TAC[CONVEX_EMPTY]);; + +let FACE_OF_TRANS = prove + (`!s t u. s face_of t /\ t face_of u + ==> s face_of u`, + REWRITE_TAC[face_of] THEN SET_TAC[]);; + +let FACE_OF_FACE = prove + (`!f s t. + t face_of s + ==> (f face_of t <=> f face_of s /\ f SUBSET t)`, + REWRITE_TAC[face_of] THEN SET_TAC[]);; + +let FACE_OF_SUBSET = prove + (`!f s t. f face_of s /\ f SUBSET t /\ t SUBSET s ==> f face_of t`, + REWRITE_TAC[face_of] THEN SET_TAC[]);; + +let FACE_OF_SLICE = prove + (`!f s t. + f face_of s /\ convex t + ==> (f INTER t) face_of (s INTER t)`, + REPEAT GEN_TAC THEN REWRITE_TAC[face_of; IN_INTER] THEN STRIP_TAC THEN + REPEAT CONJ_TAC THENL + [ASM SET_TAC[]; + ASM_MESON_TAC[CONVEX_INTER]; + ASM_MESON_TAC[]]);; + +let FACE_OF_INTER = prove + (`!s t1 t2. t1 face_of s /\ t2 face_of s + ==> (t1 INTER t2) face_of s`, + SIMP_TAC[face_of; CONVEX_INTER] THEN SET_TAC[]);; + +let FACE_OF_INTERS = prove + (`!P s. ~(P = {}) /\ (!t. t IN P ==> t face_of s) + ==> (INTERS P) face_of s`, + REWRITE_TAC[face_of] THEN REPEAT STRIP_TAC THENL + [ASM SET_TAC[]; ASM_SIMP_TAC[CONVEX_INTERS]; ASM SET_TAC[]; ASM SET_TAC[]]);; + +let FACE_OF_INTER_INTER = prove + (`!f t f' t'. + f face_of t /\ f' face_of t' ==> (f INTER f') face_of (t INTER t')`, + REWRITE_TAC[face_of; SUBSET; IN_INTER] THEN MESON_TAC[CONVEX_INTER]);; + +let FACE_OF_STILLCONVEX = prove + (`!s t:real^N->bool. + convex s + ==> (t face_of s <=> + t SUBSET s /\ + convex(s DIFF t) /\ + t = (affine hull t) INTER s)`, + REPEAT STRIP_TAC THEN REWRITE_TAC[face_of] THEN + ASM_CASES_TAC `(t:real^N->bool) SUBSET s` THEN ASM_REWRITE_TAC[] THEN + EQ_TAC THEN STRIP_TAC THENL + [CONJ_TAC THENL + [REPEAT(POP_ASSUM MP_TAC) THEN + REWRITE_TAC[CONVEX_CONTAINS_SEGMENT; open_segment; IN_DIFF] THEN + REWRITE_TAC[IN_INSERT; NOT_IN_EMPTY; SUBSET_DIFF] THEN SET_TAC[]; + ALL_TAC] THEN + REWRITE_TAC[EXTENSION] THEN X_GEN_TAC `x:real^N` THEN EQ_TAC THENL + [ASM MESON_TAC[HULL_INC; SUBSET; IN_INTER]; ALL_TAC] THEN + ASM_CASES_TAC `t:real^N -> bool = {}` THEN + ASM_REWRITE_TAC[IN_INTER; AFFINE_HULL_EMPTY; NOT_IN_EMPTY] THEN + MP_TAC(ISPEC `t:real^N->bool` RELATIVE_INTERIOR_EQ_EMPTY) THEN + ASM_REWRITE_TAC[] THEN + REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `y:real^N` THEN REWRITE_TAC[IN_RELATIVE_INTERIOR_CBALL] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + DISCH_THEN(X_CHOOSE_THEN `e:real` STRIP_ASSUME_TAC) THEN + STRIP_TAC THEN ASM_CASES_TAC `x:real^N = y` THEN ASM_REWRITE_TAC[] THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`x:real^N`; `y:real^N`]) THEN + REWRITE_TAC[] THEN ONCE_REWRITE_TAC[SEGMENT_SYM] THEN + ASM_SIMP_TAC[LEFT_FORALL_IMP_THM; OPEN_SEGMENT_ALT] THEN + ANTS_TAC THENL [ALL_TAC; SIMP_TAC[]] THEN + RULE_ASSUM_TAC(REWRITE_RULE[SUBSET]) THEN ASM_SIMP_TAC[] THEN + ASM_REWRITE_TAC[] THEN ONCE_REWRITE_TAC[CONJ_SYM] THEN + REWRITE_TAC[EXISTS_IN_GSPEC] THEN + EXISTS_TAC `min (&1 / &2) (e / norm(x - y:real^N))` THEN + REWRITE_TAC[REAL_LT_MIN; REAL_MIN_LT] THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN + ASM_SIMP_TAC[REAL_LT_DIV; NORM_POS_LT; VECTOR_SUB_EQ] THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN REWRITE_TAC[IN_INTER; IN_CBALL; dist] THEN + CONJ_TAC THENL + [REWRITE_TAC[NORM_MUL; VECTOR_ARITH + `y - ((&1 - u) % y + u % x):real^N = u % (y - x)`] THEN + ASM_SIMP_TAC[GSYM REAL_LE_RDIV_EQ; NORM_POS_LT; VECTOR_SUB_EQ] THEN + REWRITE_TAC[NORM_SUB] THEN + MATCH_MP_TAC(REAL_ARITH `&0 < e ==> abs(min (&1 / &2) e) <= e`) THEN + ASM_SIMP_TAC[REAL_LT_DIV; NORM_POS_LT; VECTOR_SUB_EQ]; + MATCH_MP_TAC(REWRITE_RULE[AFFINE_ALT] AFFINE_AFFINE_HULL) THEN + ASM_SIMP_TAC[HULL_INC]]; + CONJ_TAC THENL + [ONCE_ASM_REWRITE_TAC[] THEN MATCH_MP_TAC CONVEX_INTER THEN + ASM_SIMP_TAC[AFFINE_IMP_CONVEX; AFFINE_AFFINE_HULL]; + ALL_TAC] THEN + MAP_EVERY X_GEN_TAC [`a:real^N`; `b:real^N`; `x:real^N`] THEN + SUBGOAL_THEN + `!a b x:real^N. a IN s /\ b IN s /\ x IN t /\ x IN segment(a,b) /\ + (a IN affine hull t ==> b IN affine hull t) + ==> a IN t /\ b IN t` + (fun th -> MESON_TAC[th; SEGMENT_SYM]) THEN + REPEAT GEN_TAC THEN ASM_CASES_TAC `(a:real^N) IN affine hull t` THEN + ASM_REWRITE_TAC[] THENL [ASM SET_TAC[]; STRIP_TAC] THEN + ASM_CASES_TAC `a:real^N = b` THENL + [ASM_MESON_TAC[SEGMENT_REFL; NOT_IN_EMPTY]; ALL_TAC] THEN + SUBGOAL_THEN `(a:real^N) IN (s DIFF t) /\ b IN (s DIFF t)` + STRIP_ASSUME_TAC THENL + [ASM_REWRITE_TAC[IN_DIFF] THEN ONCE_ASM_REWRITE_TAC[] THEN + ASM_REWRITE_TAC[IN_INTER] THEN + UNDISCH_TAC `~((a:real^N) IN affine hull t)` THEN + UNDISCH_TAC `(x:real^N) IN segment(a,b)` THEN + ASM_SIMP_TAC[OPEN_SEGMENT_ALT; CONTRAPOS_THM; IN_ELIM_THM] THEN + DISCH_THEN(X_CHOOSE_THEN `u:real` STRIP_ASSUME_TAC) THEN + FIRST_X_ASSUM(MP_TAC o AP_TERM `(%) (inv(&1 - u)) :real^N->real^N`) THEN + REWRITE_TAC[VECTOR_ADD_LDISTRIB; VECTOR_MUL_ASSOC] THEN + ASM_SIMP_TAC[REAL_MUL_LINV; REAL_ARITH `x < &1 ==> ~(&1 - x = &0)`] THEN + REWRITE_TAC[VECTOR_ARITH + `x:real^N = &1 % a + u % b <=> a = x + --u % b`] THEN + DISCH_THEN SUBST1_TAC THEN DISCH_TAC THEN + MATCH_MP_TAC(REWRITE_RULE[affine] AFFINE_AFFINE_HULL) THEN + ASM_SIMP_TAC[HULL_INC] THEN + UNDISCH_TAC `u < &1` THEN CONV_TAC REAL_FIELD; + MP_TAC(ISPEC `s DIFF t:real^N->bool` CONVEX_CONTAINS_SEGMENT) THEN + ASM_REWRITE_TAC[] THEN + DISCH_THEN(MP_TAC o SPECL [`a:real^N`; `b:real^N`]) THEN + ASM_REWRITE_TAC[SUBSET; IN_DIFF] THEN + DISCH_THEN(MP_TAC o SPEC `x:real^N`) THEN + ASM_MESON_TAC[segment; IN_DIFF]]]);; + +let FACE_OF_INTER_SUPPORTING_HYPERPLANE_LE_STRONG = prove + (`!s a:real^N b. + convex(s INTER {x | a dot x = b}) /\ (!x. x IN s ==> a dot x <= b) + ==> (s INTER {x | a dot x = b}) face_of s`, + MAP_EVERY X_GEN_TAC [`s:real^N->bool`; `c:real^N`; `d:real`] THEN + SIMP_TAC[face_of; INTER_SUBSET] THEN + STRIP_TAC THEN REWRITE_TAC[IN_INTER; IN_ELIM_THM] THEN + MAP_EVERY X_GEN_TAC [`a:real^N`; `b:real^N`; `x:real^N`] THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC(REAL_ARITH + `a <= x /\ b <= x /\ ~(a < x) /\ ~(b < x) ==> a = x /\ b = x`) THEN + ASM_SIMP_TAC[] THEN UNDISCH_TAC `(x:real^N) IN segment(a,b)` THEN + ASM_CASES_TAC `a:real^N = b` THEN + ASM_REWRITE_TAC[SEGMENT_REFL; NOT_IN_EMPTY] THEN + ASM_SIMP_TAC[OPEN_SEGMENT_ALT; IN_ELIM_THM] THEN + DISCH_THEN(X_CHOOSE_THEN `u:real` STRIP_ASSUME_TAC) THEN + CONJ_TAC THEN DISCH_TAC THEN UNDISCH_TAC `(c:real^N) dot x = d` THEN + MATCH_MP_TAC(REAL_ARITH `x < a ==> x = a ==> F`) THEN + SUBST1_TAC(REAL_ARITH `d = (&1 - u) * d + u * d`) THEN + ASM_REWRITE_TAC[DOT_RADD; DOT_RMUL] THENL + [MATCH_MP_TAC REAL_LTE_ADD2; MATCH_MP_TAC REAL_LET_ADD2] THEN + ASM_SIMP_TAC[REAL_LE_LMUL_EQ; REAL_LT_LMUL_EQ; REAL_SUB_LT]);; + +let FACE_OF_INTER_SUPPORTING_HYPERPLANE_GE_STRONG = prove + (`!s a:real^N b. + convex(s INTER {x | a dot x = b}) /\ (!x. x IN s ==> a dot x >= b) + ==> (s INTER {x | a dot x = b}) face_of s`, + REWRITE_TAC[real_ge] THEN REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`s:real^N->bool`; `--a:real^N`; `--b:real`] + FACE_OF_INTER_SUPPORTING_HYPERPLANE_LE_STRONG) THEN + ASM_REWRITE_TAC[DOT_LNEG; REAL_EQ_NEG2; REAL_LE_NEG2]);; + +let FACE_OF_INTER_SUPPORTING_HYPERPLANE_LE = prove + (`!s a:real^N b. + convex s /\ (!x. x IN s ==> a dot x <= b) + ==> (s INTER {x | a dot x = b}) face_of s`, + SIMP_TAC[FACE_OF_INTER_SUPPORTING_HYPERPLANE_LE_STRONG; + CONVEX_INTER; CONVEX_HYPERPLANE]);; + +let FACE_OF_INTER_SUPPORTING_HYPERPLANE_GE = prove + (`!s a:real^N b. + convex s /\ (!x. x IN s ==> a dot x >= b) + ==> (s INTER {x | a dot x = b}) face_of s`, + SIMP_TAC[FACE_OF_INTER_SUPPORTING_HYPERPLANE_GE_STRONG; + CONVEX_INTER; CONVEX_HYPERPLANE]);; + +let FACE_OF_IMP_SUBSET = prove + (`!s t. t face_of s ==> t SUBSET s`, + SIMP_TAC[face_of]);; + +let FACE_OF_IMP_CONVEX = prove + (`!s t. t face_of s ==> convex t`, + SIMP_TAC[face_of]);; + +let FACE_OF_IMP_CLOSED = prove + (`!s t. convex s /\ closed s /\ t face_of s ==> closed t`, + REPEAT GEN_TAC THEN + REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + ASM_SIMP_TAC[FACE_OF_STILLCONVEX] THEN + STRIP_TAC THEN ONCE_ASM_REWRITE_TAC[] THEN + ASM_SIMP_TAC[CLOSED_AFFINE; AFFINE_AFFINE_HULL; CLOSED_INTER]);; + +let FACE_OF_IMP_COMPACT = prove + (`!s t. convex s /\ compact s /\ t face_of s ==> compact t`, + SIMP_TAC[COMPACT_EQ_BOUNDED_CLOSED] THEN + ASM_MESON_TAC[BOUNDED_SUBSET; FACE_OF_IMP_SUBSET; FACE_OF_IMP_CLOSED]);; + +let FACE_OF_INTER_SUBFACE = prove + (`!c1 c2 d1 d2:real^N->bool. + (c1 INTER c2) face_of c1 /\ (c1 INTER c2) face_of c2 /\ + d1 face_of c1 /\ d2 face_of c2 + ==> (d1 INTER d2) face_of d1 /\ (d1 INTER d2) face_of d2`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC FACE_OF_SUBSET THENL + [EXISTS_TAC `c1:real^N->bool`; EXISTS_TAC `c2:real^N->bool`] THEN + ASM_SIMP_TAC[FACE_OF_IMP_SUBSET; INTER_SUBSET] THEN + TRANS_TAC FACE_OF_TRANS `c1 INTER c2:real^N->bool` THEN + ASM_SIMP_TAC[FACE_OF_INTER_INTER]);; + +let SUBSET_OF_FACE_OF = prove + (`!s t u:real^N->bool. + t face_of s /\ u SUBSET s /\ + ~(DISJOINT t (relative_interior u)) + ==> u SUBSET t`, + REWRITE_TAC[DISJOINT] THEN REPEAT STRIP_TAC THEN + REWRITE_TAC[SUBSET] THEN X_GEN_TAC `c:real^N` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN + REWRITE_TAC[IN_INTER; LEFT_IMP_EXISTS_THM] THEN X_GEN_TAC `b:real^N` THEN + REWRITE_TAC[IN_RELATIVE_INTERIOR_CBALL] THEN + REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + DISCH_THEN(X_CHOOSE_THEN `e:real` MP_TAC) THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + REWRITE_TAC[SUBSET; IN_CBALL; IN_INTER] THEN + ASM_CASES_TAC `c:real^N = b` THEN ASM_REWRITE_TAC[] THEN + ABBREV_TAC `d:real^N = b + e / norm(b - c) % (b - c)` THEN + DISCH_THEN(MP_TAC o SPEC `d:real^N`) THEN ANTS_TAC THENL + [EXPAND_TAC "d" THEN CONJ_TAC THENL + [REWRITE_TAC[NORM_ARITH `dist(b:real^N,b + e) = norm e`] THEN + REWRITE_TAC[NORM_MUL; REAL_ABS_DIV; REAL_ABS_NORM] THEN + ASM_SIMP_TAC[REAL_DIV_RMUL; NORM_EQ_0; VECTOR_SUB_EQ] THEN + ASM_REAL_ARITH_TAC; + REWRITE_TAC[VECTOR_ARITH + `b + u % (b - c):real^N = (&1 - --u) % b + --u % c`] THEN + MATCH_MP_TAC(REWRITE_RULE[AFFINE_ALT] AFFINE_AFFINE_HULL) THEN + ASM_SIMP_TAC[HULL_INC]]; + STRIP_TAC THEN + SUBGOAL_THEN `(d:real^N) IN t /\ c IN t` (fun th -> MESON_TAC[th]) THEN + FIRST_ASSUM(STRIP_ASSUME_TAC o GEN_REWRITE_RULE I [face_of]) THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN EXISTS_TAC `b:real^N` THEN + REPEAT(CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC]) THEN + SUBGOAL_THEN `~(b:real^N = d)` ASSUME_TAC THENL + [EXPAND_TAC "d" THEN + REWRITE_TAC[VECTOR_ARITH `b:real^N = b + e <=> e = vec 0`] THEN + ASM_SIMP_TAC[REAL_LT_DIV; NORM_POS_LT; VECTOR_SUB_EQ; + VECTOR_MUL_EQ_0; REAL_LT_IMP_NZ]; + ASM_REWRITE_TAC[segment; IN_DIFF; IN_INSERT; NOT_IN_EMPTY] THEN + REWRITE_TAC[IN_ELIM_THM] THEN + EXISTS_TAC `(e / norm(b - c:real^N)) / (&1 + e / norm(b - c))` THEN + ASM_SIMP_TAC[REAL_LT_DIV; NORM_POS_LT; VECTOR_SUB_EQ; + REAL_ARITH `&0 < x ==> &0 < &1 + x`; + REAL_LE_RDIV_EQ; REAL_LE_LDIV_EQ; REAL_MUL_LID] THEN + REWRITE_TAC[REAL_MUL_LZERO; REAL_MUL_LID] THEN + ASM_SIMP_TAC[REAL_FIELD `&0 < n ==> (&1 + e / n) * n = n + e`; + NORM_POS_LT; VECTOR_SUB_EQ; REAL_LE_ADDL] THEN + ASM_SIMP_TAC[NORM_POS_LT; REAL_LT_IMP_LE; VECTOR_SUB_EQ] THEN + EXPAND_TAC "d" THEN REWRITE_TAC[VECTOR_ARITH + `b:real^N = (&1 - u) % (b + e % (b - c)) + u % c <=> + (u - e * (&1 - u)) % (b - c) = vec 0`] THEN + ASM_REWRITE_TAC[VECTOR_MUL_EQ_0; VECTOR_SUB_EQ] THEN + MATCH_MP_TAC(REAL_FIELD + `&0 < e ==> e / (&1 + e) - e * (&1 - e / (&1 + e)) = &0`) THEN + ASM_SIMP_TAC[REAL_LT_DIV; NORM_POS_LT; VECTOR_SUB_EQ]]]);; + +let FACE_OF_EQ = prove + (`!s t u:real^N->bool. + t face_of s /\ u face_of s /\ + ~(DISJOINT (relative_interior t) (relative_interior u)) + ==> t = u`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN + CONJ_TAC THEN MATCH_MP_TAC SUBSET_OF_FACE_OF THEN + EXISTS_TAC `s:real^N->bool` THEN ASM_SIMP_TAC[FACE_OF_IMP_SUBSET] THENL + [MP_TAC(ISPEC `u:real^N->bool` RELATIVE_INTERIOR_SUBSET); + MP_TAC(ISPEC `t:real^N->bool` RELATIVE_INTERIOR_SUBSET)] THEN + ASM SET_TAC[]);; + +let FACE_OF_DISJOINT_RELATIVE_INTERIOR = prove + (`!f s:real^N->bool. + f face_of s /\ ~(f = s) ==> f INTER relative_interior s = {}`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`s:real^N->bool`; `f:real^N->bool`; `s:real^N->bool`] + SUBSET_OF_FACE_OF) THEN + FIRST_ASSUM(MP_TAC o MATCH_MP FACE_OF_IMP_SUBSET) THEN + ASM SET_TAC[]);; + +let FACE_OF_DISJOINT_INTERIOR = prove + (`!f s:real^N->bool. + f face_of s /\ ~(f = s) ==> f INTER interior s = {}`, + REPEAT GEN_TAC THEN + DISCH_THEN(MP_TAC o MATCH_MP FACE_OF_DISJOINT_RELATIVE_INTERIOR) THEN + MP_TAC(ISPEC `s:real^N->bool` INTERIOR_SUBSET_RELATIVE_INTERIOR) THEN + SET_TAC[]);; + +let AFFINE_HULL_FACE_OF_DISJOINT_RELATIVE_INTERIOR = prove + (`!s f:real^N->bool. + convex s /\ f face_of s /\ ~(f = s) + ==> affine hull f INTER relative_interior s = {}`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC(SET_RULE + `!s f. a INTER s = f /\ r SUBSET s /\ f INTER r = {} + ==> a INTER r = {}`) THEN + MAP_EVERY EXISTS_TAC [`s:real^N->bool`; `f:real^N->bool`] THEN + ASM_SIMP_TAC[FACE_OF_DISJOINT_RELATIVE_INTERIOR; + RELATIVE_INTERIOR_SUBSET] THEN + UNDISCH_TAC `(f:real^N->bool) face_of s` THEN + ASM_SIMP_TAC[FACE_OF_STILLCONVEX] THEN MESON_TAC[]);; + +let FACE_OF_SUBSET_RELATIVE_BOUNDARY = prove + (`!s f:real^N->bool. + f face_of s /\ ~(f = s) ==> f SUBSET (s DIFF relative_interior s)`, + ASM_SIMP_TAC[SET_RULE `s SUBSET u DIFF t <=> s SUBSET u /\ s INTER t = {}`; + FACE_OF_DISJOINT_RELATIVE_INTERIOR; FACE_OF_IMP_SUBSET]);; + +let FACE_OF_SUBSET_RELATIVE_FRONTIER = prove + (`!s f:real^N->bool. + f face_of s /\ ~(f = s) ==> f SUBSET relative_frontier s`, + REPEAT GEN_TAC THEN + DISCH_THEN(MP_TAC o MATCH_MP FACE_OF_SUBSET_RELATIVE_BOUNDARY) THEN + REWRITE_TAC[relative_frontier] THEN + MP_TAC(ISPEC `s:real^N->bool` CLOSURE_SUBSET) THEN SET_TAC[]);; + +let FACE_OF_AFF_DIM_LT = prove + (`!f s:real^N->bool. + convex s /\ f face_of s /\ ~(f = s) ==> aff_dim f < aff_dim s`, + REPEAT GEN_TAC THEN + SIMP_TAC[INT_LT_LE; FACE_OF_IMP_SUBSET; AFF_DIM_SUBSET] THEN + REWRITE_TAC[IMP_CONJ; CONTRAPOS_THM] THEN + ASM_CASES_TAC `f:real^N->bool = {}` THENL + [CONV_TAC(ONCE_DEPTH_CONV SYM_CONV) THEN + ASM_REWRITE_TAC[AFF_DIM_EQ_MINUS1; AFF_DIM_EMPTY]; + REPEAT STRIP_TAC THEN MATCH_MP_TAC FACE_OF_EQ THEN + EXISTS_TAC `s:real^N->bool` THEN ASM_SIMP_TAC[FACE_OF_REFL] THEN + MATCH_MP_TAC(SET_RULE `~(f = {}) /\ f SUBSET s ==> ~DISJOINT f s`) THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP FACE_OF_IMP_CONVEX) THEN + ASM_SIMP_TAC[RELATIVE_INTERIOR_EQ_EMPTY] THEN + MATCH_MP_TAC SUBSET_RELATIVE_INTERIOR THEN + ASM_MESON_TAC[FACE_OF_IMP_SUBSET; AFF_DIM_EQ_AFFINE_HULL; INT_LE_REFL]]);; + +let FACE_OF_CONVEX_HULLS = prove + (`!f s:real^N->bool. + FINITE s /\ f SUBSET s /\ + DISJOINT (affine hull f) (convex hull (s DIFF f)) + ==> (convex hull f) face_of (convex hull s)`, + let lemma = prove + (`!s x y:real^N. + affine s /\ ~(k = &0) /\ ~(k = &1) /\ x IN s /\ inv(&1 - k) % y IN s + ==> inv(k) % (x - y) IN s`, + REWRITE_TAC[AFFINE_ALT] THEN REPEAT STRIP_TAC THEN + SUBGOAL_THEN + `inv(k) % (x - y):real^N = (&1 - inv k) % inv(&1 - k) % y + inv(k) % x` + (fun th -> ASM_SIMP_TAC[th]) THEN + REWRITE_TAC[VECTOR_MUL_EQ_0; VECTOR_ARITH + `k % (x - y):real^N = a % b % y + k % x <=> (a * b + k) % y = vec 0`] THEN + DISJ1_TAC THEN MAP_EVERY UNDISCH_TAC [`~(k = &0)`; `~(k = &1)`] THEN + CONV_TAC REAL_FIELD) in + REPEAT STRIP_TAC THEN REWRITE_TAC[face_of] THEN + SUBGOAL_THEN `FINITE(f:real^N->bool)` ASSUME_TAC THENL + [ASM_MESON_TAC[FINITE_SUBSET]; ALL_TAC] THEN + FIRST_ASSUM(ASSUME_TAC o GEN_REWRITE_RULE I [SUBSET]) THEN + ASM_SIMP_TAC[HULL_MONO; CONVEX_CONVEX_HULL] THEN + MAP_EVERY X_GEN_TAC [`x:real^N`; `y:real^N`; `w:real^N`] THEN + STRIP_TAC THEN FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_SEGMENT]) THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC + (X_CHOOSE_THEN `u:real` STRIP_ASSUME_TAC)) THEN + SUBGOAL_THEN `(w:real^N) IN affine hull f` ASSUME_TAC THENL + [ASM_MESON_TAC[CONVEX_HULL_SUBSET_AFFINE_HULL; SUBSET]; ALL_TAC] THEN + MAP_EVERY UNDISCH_TAC + [`(y:real^N) IN convex hull s`; `(x:real^N) IN convex hull s`] THEN + REWRITE_TAC[CONVEX_HULL_FINITE; IN_ELIM_THM] THEN + DISCH_THEN(X_CHOOSE_THEN `a:real^N->real` STRIP_ASSUME_TAC) THEN + DISCH_THEN(X_CHOOSE_THEN `b:real^N->real` STRIP_ASSUME_TAC) THEN + ABBREV_TAC `(c:real^N->real) = \x. (&1 - u) * a x + u * b x` THEN + SUBGOAL_THEN `!x:real^N. x IN s ==> &0 <= c x` ASSUME_TAC THENL + [REPEAT STRIP_TAC THEN EXPAND_TAC "c" THEN REWRITE_TAC[] THEN + MATCH_MP_TAC REAL_LE_ADD THEN CONJ_TAC THEN MATCH_MP_TAC REAL_LE_MUL THEN + ASM_SIMP_TAC[] THEN ASM_REAL_ARITH_TAC; + ALL_TAC] THEN + ASM_CASES_TAC `sum (s DIFF f:real^N->bool) c = &0` THENL + [SUBGOAL_THEN `!x:real^N. x IN (s DIFF f) ==> c x = &0` MP_TAC THENL + [MATCH_MP_TAC SUM_POS_EQ_0 THEN ASM_MESON_TAC[FINITE_DIFF; IN_DIFF]; + ALL_TAC] THEN + EXPAND_TAC "c" THEN + ASM_SIMP_TAC[IN_DIFF; REAL_LE_MUL; REAL_LT_IMP_LE; REAL_SUB_LT; + REAL_ARITH `&0 <= x /\ &0 <= y ==> (x + y = &0 <=> x = &0 /\ y = &0)`; + REAL_ENTIRE; REAL_SUB_0; REAL_LT_IMP_NE] THEN + STRIP_TAC THEN CONJ_TAC THENL + [EXISTS_TAC `a:real^N->real`; EXISTS_TAC `b:real^N->real`] THEN + ASM_SIMP_TAC[] THEN CONJ_TAC THEN FIRST_X_ASSUM(fun th g -> + (GEN_REWRITE_TAC RAND_CONV [GSYM th] THEN CONV_TAC SYM_CONV THEN + (MATCH_MP_TAC SUM_SUPERSET ORELSE MATCH_MP_TAC VSUM_SUPERSET)) g) THEN + ASM_SIMP_TAC[VECTOR_MUL_LZERO]; + ALL_TAC] THEN + ABBREV_TAC `k = sum (s DIFF f:real^N->bool) c` THEN + SUBGOAL_THEN `&0 < k` ASSUME_TAC THENL + [ASM_REWRITE_TAC[REAL_LT_LE] THEN EXPAND_TAC "k" THEN + MATCH_MP_TAC SUM_POS_LE THEN ASM_SIMP_TAC[FINITE_DIFF; IN_DIFF]; + ALL_TAC] THEN + ASM_CASES_TAC `k = &1` THENL + [FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_DISJOINT]) THEN + MATCH_MP_TAC(TAUT `b ==> ~b ==> c`) THEN + EXISTS_TAC `w:real^N` THEN + ASM_REWRITE_TAC[CONVEX_HULL_FINITE; IN_ELIM_THM] THEN + EXISTS_TAC `c:real^N->real` THEN + ASM_SIMP_TAC[IN_DIFF; SUM_DIFF; VSUM_DIFF] THEN + SUBGOAL_THEN `vsum f (\x:real^N. c x % x) = vec 0` SUBST1_TAC THENL + [ALL_TAC; + EXPAND_TAC "c" THEN REWRITE_TAC[VECTOR_ADD_RDISTRIB] THEN + ASM_SIMP_TAC[VSUM_ADD; GSYM VECTOR_MUL_ASSOC; VSUM_LMUL] THEN + REWRITE_TAC[VECTOR_SUB_RZERO]] THEN + SUBGOAL_THEN `sum(s DIFF f) c = sum s c - sum f (c:real^N->real)` + MP_TAC THENL [ASM_MESON_TAC[SUM_DIFF]; ALL_TAC] THEN ASM_REWRITE_TAC[] THEN + SUBGOAL_THEN `sum s (c:real^N->real) = &1` SUBST1_TAC THENL + [EXPAND_TAC "c" THEN REWRITE_TAC[VECTOR_ADD_RDISTRIB] THEN + ASM_SIMP_TAC[SUM_ADD; GSYM REAL_MUL_ASSOC; SUM_LMUL] THEN + REAL_ARITH_TAC; + ALL_TAC] THEN + REWRITE_TAC[REAL_ARITH `&1 = &1 - x <=> x = &0`] THEN DISCH_TAC THEN + MP_TAC(ISPECL [`c:real^N->real`;`f:real^N->bool`] SUM_POS_EQ_0) THEN + ANTS_TAC THENL [ASM_MESON_TAC[FINITE_SUBSET; SUBSET]; ALL_TAC] THEN + SIMP_TAC[VECTOR_MUL_LZERO; VSUM_0]; + ALL_TAC] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_DISJOINT]) THEN + MATCH_MP_TAC(TAUT `b ==> ~b ==> c`) THEN + EXISTS_TAC `inv(k) % (w - vsum f (\x:real^N. c x % x))` THEN CONJ_TAC THENL + [ALL_TAC; + SUBGOAL_THEN `w = vsum f (\x:real^N. c x % x) + + vsum (s DIFF f) (\x:real^N. c x % x)` + SUBST1_TAC THENL + [ASM_SIMP_TAC[VSUM_DIFF; VECTOR_ARITH `a + b - a:real^N = b`] THEN + EXPAND_TAC "c" THEN REWRITE_TAC[VECTOR_ADD_RDISTRIB] THEN + ASM_SIMP_TAC[VSUM_ADD; GSYM VECTOR_MUL_ASSOC; VSUM_LMUL]; + REWRITE_TAC[VECTOR_ADD_SUB]] THEN + ASM_SIMP_TAC[GSYM VSUM_LMUL; FINITE_DIFF] THEN + REWRITE_TAC[CONVEX_HULL_FINITE; IN_ELIM_THM] THEN + EXISTS_TAC `\x. inv k * (c:real^N->real) x` THEN + ASM_REWRITE_TAC[VECTOR_MUL_ASSOC] THEN + ASM_SIMP_TAC[IN_DIFF; REAL_LE_MUL; REAL_LE_INV_EQ; REAL_LT_IMP_LE] THEN + ASM_SIMP_TAC[SUM_LMUL; ETA_AX; REAL_MUL_LINV]] THEN + MATCH_MP_TAC lemma THEN REPEAT CONJ_TAC THENL + [REWRITE_TAC[AFFINE_AFFINE_HULL]; + ASM_REWRITE_TAC[]; + ASM_REWRITE_TAC[]; + ASM_MESON_TAC[CONVEX_HULL_SUBSET_AFFINE_HULL; SUBSET]; + ALL_TAC] THEN + ASM_SIMP_TAC[GSYM VSUM_LMUL; AFFINE_HULL_FINITE; IN_ELIM_THM] THEN + EXISTS_TAC `(\x. inv(&1 - k) * c x):real^N->real` THEN + REWRITE_TAC[VECTOR_MUL_ASSOC; SUM_LMUL] THEN + MATCH_MP_TAC(REAL_FIELD + `~(k = &1) /\ f = &1 - k ==> inv(&1 - k) * f = &1`) THEN + ASM_REWRITE_TAC[] THEN + SUBGOAL_THEN `sum(s DIFF f) c = sum s c - sum f (c:real^N->real)` + MP_TAC THENL [ASM_MESON_TAC[SUM_DIFF]; ALL_TAC] THEN ASM_REWRITE_TAC[] THEN + SUBGOAL_THEN `sum s (c:real^N->real) = &1` SUBST1_TAC THENL + [EXPAND_TAC "c" THEN REWRITE_TAC[VECTOR_ADD_RDISTRIB] THEN + ASM_SIMP_TAC[SUM_ADD; GSYM REAL_MUL_ASSOC; SUM_LMUL]; + ALL_TAC] THEN + REAL_ARITH_TAC);; + +let FACE_OF_CONVEX_HULL_INSERT = prove + (`!f s a:real^N. + FINITE s /\ ~(a IN affine hull s) /\ f face_of (convex hull s) + ==> f face_of (convex hull (a INSERT s))`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC FACE_OF_TRANS THEN + EXISTS_TAC `convex hull s:real^N->bool` THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC FACE_OF_CONVEX_HULLS THEN + ASM_REWRITE_TAC[FINITE_INSERT; SET_RULE `s SUBSET a INSERT s`] THEN + FIRST_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE + `~(a IN s) ==> t SUBSET {a} ==> DISJOINT s t`)) THEN + MATCH_MP_TAC HULL_MINIMAL THEN REWRITE_TAC[CONVEX_SING] THEN SET_TAC[]);; + +let FACE_OF_AFFINE_TRIVIAL = prove + (`!s f:real^N->bool. + affine s /\ f face_of s ==> f = {} \/ f = s`, + REPEAT STRIP_TAC THEN + ASM_CASES_TAC `f:real^N->bool = {}` THEN ASM_REWRITE_TAC[] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN + DISCH_THEN(X_CHOOSE_TAC `a:real^N`) THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP FACE_OF_IMP_SUBSET) THEN + MATCH_MP_TAC SUBSET_ANTISYM THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[SUBSET] THEN X_GEN_TAC `b:real^N` THEN DISCH_TAC THEN + ASM_CASES_TAC `(b:real^N) IN f` THEN ASM_REWRITE_TAC[] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [face_of]) THEN + DISCH_THEN(MP_TAC o SPECL [`&2 % a - b:real^N`; `b:real^N`; `a:real^N`] o + CONJUNCT2 o CONJUNCT2) THEN + SUBGOAL_THEN `~(a:real^N = b)` ASSUME_TAC THENL + [ASM_MESON_TAC[]; ALL_TAC] THEN + ASM_SIMP_TAC[IN_SEGMENT; VECTOR_ARITH `&2 % a - b:real^N = b <=> a = b`] THEN + CONJ_TAC THENL + [REWRITE_TAC[VECTOR_ARITH `&2 % a - b:real^N = a + &1 % (a - b)`] THEN + MATCH_MP_TAC IN_AFFINE_ADD_MUL_DIFF THEN ASM SET_TAC[]; + EXISTS_TAC `&1 / &2` THEN CONV_TAC REAL_RAT_REDUCE_CONV THEN + VECTOR_ARITH_TAC]);; + +let FACE_OF_AFFINE_EQ = prove + (`!s:real^N->bool f. affine s ==> (f face_of s <=> f = {} \/ f = s)`, + MESON_TAC[FACE_OF_AFFINE_TRIVIAL; EMPTY_FACE_OF; FACE_OF_REFL; + AFFINE_IMP_CONVEX]);; + +let INTERS_FACES_FINITE_BOUND = prove + (`!s f:(real^N->bool)->bool. + convex s /\ (!c. c IN f ==> c face_of s) + ==> ?f'. FINITE f' /\ f' SUBSET f /\ CARD f' <= dimindex(:N) + 1 /\ + INTERS f' = INTERS f`, + SUBGOAL_THEN + `!s f:(real^N->bool)->bool. + convex s /\ (!c. c IN f ==> c face_of s /\ ~(c = s)) + ==> ?f'. FINITE f' /\ f' SUBSET f /\ CARD f' <= dimindex(:N) + 1 /\ + INTERS f' = INTERS f` + ASSUME_TAC THENL + [ALL_TAC; + REPEAT STRIP_TAC THEN + ASM_CASES_TAC `(s:real^N->bool) IN f` THENL + [ALL_TAC; FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_MESON_TAC[]] THEN + FIRST_ASSUM(DISJ_CASES_THEN2 SUBST1_TAC MP_TAC o MATCH_MP (SET_RULE + `s IN f ==> f = {s} \/ ?t. ~(t = s) /\ t IN f`)) THENL + [EXISTS_TAC `{s:real^N->bool}` THEN + SIMP_TAC[FINITE_INSERT; FINITE_EMPTY; SUBSET_REFL; CARD_CLAUSES] THEN + ARITH_TAC; + DISCH_THEN(X_CHOOSE_THEN `t:real^N->bool` STRIP_ASSUME_TAC)] THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`s:real^N->bool`; `f DELETE + (s:real^N->bool)`]) THEN + ASM_SIMP_TAC[IN_DELETE; SUBSET_DELETE] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `f':(real^N->bool)->bool` THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + SUBGOAL_THEN `f = (s:real^N->bool) INSERT (f DELETE s)` MP_TAC THENL + [ASM SET_TAC[]; + DISCH_THEN(fun th -> GEN_REWRITE_TAC (funpow 2 RAND_CONV) [th])] THEN + REWRITE_TAC[INTERS_INSERT] THEN + MATCH_MP_TAC(SET_RULE `t SUBSET s ==> t = s INTER t`) THEN + FIRST_X_ASSUM(MP_TAC o SPEC `t:real^N->bool`) THEN + ASM_REWRITE_TAC[] THEN + DISCH_THEN(ASSUME_TAC o MATCH_MP FACE_OF_IMP_SUBSET) THEN + MATCH_MP_TAC SUBSET_TRANS THEN EXISTS_TAC `t:real^N->bool` THEN + ASM_REWRITE_TAC[] THEN REWRITE_TAC[SUBSET; IN_INTERS; IN_DELETE] THEN + ASM SET_TAC[]] THEN + REPEAT STRIP_TAC THEN ASM_CASES_TAC + `!f':(real^N->bool)->bool. + FINITE f' /\ f' SUBSET f /\ CARD f' <= dimindex(:N) + 1 + ==> ?c. c IN f /\ c INTER (INTERS f') PSUBSET (INTERS f')` + THENL + [ALL_TAC; + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [NOT_FORALL_THM]) THEN + MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC THEN + SIMP_TAC[NOT_IMP; GSYM CONJ_ASSOC] THEN + REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + ASM_REWRITE_TAC[PSUBSET; INTER_SUBSET] THEN ASM SET_TAC[]] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE BINDER_CONV + [RIGHT_IMP_EXISTS_THM]) THEN + REWRITE_TAC[SKOLEM_THM; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `c:((real^N->bool)->bool)->real^N->bool` THEN DISCH_TAC THEN + CHOOSE_TAC(prove_recursive_functions_exist num_RECURSION + `d 0 = {c {} :real^N->bool} /\ !n. d(SUC n) = c(d n) INSERT d n`) THEN + SUBGOAL_THEN `!n:num. ~(d n:(real^N->bool)->bool = {})` ASSUME_TAC THENL + [INDUCT_TAC THEN ASM_REWRITE_TAC[] THEN SET_TAC[]; ALL_TAC] THEN + SUBGOAL_THEN + `!n. n <= dimindex(:N) + 1 + ==> (d n) SUBSET (f:(real^N->bool)->bool) /\ + FINITE(d n) /\ CARD(d n) <= n + 1` + ASSUME_TAC THENL + [INDUCT_TAC THEN ASM_REWRITE_TAC[] THEN + ASM_SIMP_TAC[INSERT_SUBSET; CARD_CLAUSES; FINITE_INSERT; FINITE_EMPTY; + EMPTY_SUBSET; ARITH_RULE `SUC n <= m + 1 ==> n <= m + 1`] THEN + REPEAT STRIP_TAC THEN TRY ASM_ARITH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `(d:num->(real^N->bool)->bool) n`) THEN + FIRST_X_ASSUM(MP_TAC o check (is_imp o concl)) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; STRIP_TAC] THEN ASM_REWRITE_TAC[] THEN + ANTS_TAC THENL [ASM_ARITH_TAC; SIMP_TAC[]]; + ALL_TAC] THEN + SUBGOAL_THEN + `!n. n <= dimindex(:N) + ==> (INTERS(d(SUC n)):real^N->bool) PSUBSET INTERS(d n)` + ASSUME_TAC THENL + [REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[INTERS_INSERT] THEN + FIRST_X_ASSUM(MP_TAC o SPEC `(d:num->(real^N->bool)->bool) n`) THEN + ANTS_TAC THENL [ALL_TAC; SIMP_TAC[]] THEN + REPEAT(FIRST_X_ASSUM(MP_TAC o SPEC `n:num`)) THEN + ASM_SIMP_TAC[ARITH_RULE `n <= N ==> n <= N + 1`] THEN + ASM_ARITH_TAC; + ALL_TAC] THEN + FIRST_X_ASSUM(CONJUNCTS_THEN(K ALL_TAC)) THEN + SUBGOAL_THEN + `!n. n <= dimindex(:N) + 1 + ==> aff_dim(INTERS(d n):real^N->bool) < &(dimindex(:N)) - &n` + MP_TAC THENL + [INDUCT_TAC THENL + [DISCH_TAC THEN REWRITE_TAC[INT_SUB_RZERO] THEN + MATCH_MP_TAC INT_LTE_TRANS THEN + EXISTS_TAC `aff_dim(s:real^N->bool)` THEN + REWRITE_TAC[AFF_DIM_LE_UNIV] THEN + MATCH_MP_TAC FACE_OF_AFF_DIM_LT THEN + ASM_REWRITE_TAC[] THEN CONJ_TAC THENL + [MATCH_MP_TAC FACE_OF_INTERS THEN ASM_REWRITE_TAC[] THEN ASM SET_TAC[]; + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY] o + SPEC `0`) THEN + DISCH_THEN(X_CHOOSE_TAC `e:real^N->bool`) THEN + FIRST_X_ASSUM(MP_TAC o SPEC `e:real^N->bool`) THEN + ANTS_TAC THENL [ASM SET_TAC[]; STRIP_TAC] THEN + MATCH_MP_TAC(SET_RULE + `!t. t PSUBSET s /\ u SUBSET t ==> ~(u = s)`) THEN + EXISTS_TAC `e:real^N->bool` THEN + FIRST_X_ASSUM(ASSUME_TAC o MATCH_MP FACE_OF_IMP_SUBSET) THEN + ASM SET_TAC[]]; + DISCH_TAC THEN REWRITE_TAC[GSYM INT_OF_NUM_SUC] THEN + MATCH_MP_TAC(INT_ARITH + `!d':int. d < d' /\ d' < m - n ==> d < m - (n + &1)`) THEN + EXISTS_TAC `aff_dim(INTERS(d(n:num)):real^N->bool)` THEN + ASM_SIMP_TAC[ARITH_RULE `SUC n <= k + 1 ==> n <= k + 1`] THEN + MATCH_MP_TAC FACE_OF_AFF_DIM_LT THEN + ASM_SIMP_TAC[ARITH_RULE `SUC n <= m + 1 ==> n <= m`; + SET_RULE `s PSUBSET t ==> ~(s = t)`] THEN + CONJ_TAC THENL + [MATCH_MP_TAC CONVEX_INTERS THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC FACE_OF_IMP_CONVEX THEN + EXISTS_TAC `s:real^N->bool` THEN + ASM_MESON_TAC[SUBSET; ARITH_RULE `SUC n <= m + 1 ==> n <= m + 1`]; + ALL_TAC] THEN + MP_TAC(ISPECL [`INTERS(d(SUC n)):real^N->bool`;`s:real^N->bool`; + `INTERS(d(n:num)):real^N->bool`] FACE_OF_FACE) THEN + ASM_SIMP_TAC[SET_RULE `s PSUBSET t ==> s SUBSET t`; + ARITH_RULE `SUC n <= m + 1 ==> n <= m`] THEN + MATCH_MP_TAC(TAUT `a /\ b ==> (a ==> (c <=> b)) ==> c`) THEN + CONJ_TAC THEN MATCH_MP_TAC FACE_OF_INTERS THEN ASM_REWRITE_TAC[] THEN + ASM_MESON_TAC[SUBSET; ARITH_RULE `SUC n <= m + 1 ==> n <= m + 1`]]; + ALL_TAC] THEN + DISCH_THEN(MP_TAC o SPEC `dimindex(:N) + 1`) THEN REWRITE_TAC[LE_REFL] THEN + MATCH_MP_TAC(TAUT `~p ==> p ==> q`) THEN REWRITE_TAC[INT_NOT_LT] THEN + REWRITE_TAC[GSYM INT_OF_NUM_ADD; INT_ARITH `d - (d + &1):int = -- &1`] THEN + REWRITE_TAC[AFF_DIM_GE]);; + +let INTERS_FACES_FINITE_ALTBOUND = prove + (`!s f:(real^N->bool)->bool. + (!c. c IN f ==> c face_of s) + ==> ?f'. FINITE f' /\ f' SUBSET f /\ CARD f' <= dimindex(:N) + 2 /\ + INTERS f' = INTERS f`, + REPEAT STRIP_TAC THEN ASM_CASES_TAC + `!f':(real^N->bool)->bool. + FINITE f' /\ f' SUBSET f /\ CARD f' <= dimindex(:N) + 2 + ==> ?c. c IN f /\ c INTER (INTERS f') PSUBSET (INTERS f')` + THENL + [ALL_TAC; + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [NOT_FORALL_THM]) THEN + MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC THEN + SIMP_TAC[NOT_IMP; GSYM CONJ_ASSOC] THEN + REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + ASM_REWRITE_TAC[PSUBSET; INTER_SUBSET] THEN ASM SET_TAC[]] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE BINDER_CONV + [RIGHT_IMP_EXISTS_THM]) THEN + REWRITE_TAC[SKOLEM_THM; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `c:((real^N->bool)->bool)->real^N->bool` THEN DISCH_TAC THEN + CHOOSE_TAC(prove_recursive_functions_exist num_RECURSION + `d 0 = {c {} :real^N->bool} /\ !n. d(SUC n) = c(d n) INSERT d n`) THEN + SUBGOAL_THEN `!n:num. ~(d n:(real^N->bool)->bool = {})` ASSUME_TAC THENL + [INDUCT_TAC THEN ASM_REWRITE_TAC[] THEN SET_TAC[]; ALL_TAC] THEN + SUBGOAL_THEN + `!n. n <= dimindex(:N) + 2 + ==> (d n) SUBSET (f:(real^N->bool)->bool) /\ + FINITE(d n) /\ CARD(d n) <= n + 1` + ASSUME_TAC THENL + [INDUCT_TAC THEN ASM_REWRITE_TAC[] THEN + ASM_SIMP_TAC[INSERT_SUBSET; CARD_CLAUSES; FINITE_INSERT; FINITE_EMPTY; + EMPTY_SUBSET; ARITH_RULE `SUC n <= m + 2 ==> n <= m + 2`] THEN + REPEAT STRIP_TAC THEN TRY ASM_ARITH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `(d:num->(real^N->bool)->bool) n`) THEN + FIRST_X_ASSUM(MP_TAC o check (is_imp o concl)) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; STRIP_TAC] THEN ASM_REWRITE_TAC[] THEN + ANTS_TAC THENL [ASM_ARITH_TAC; SIMP_TAC[]]; + ALL_TAC] THEN + SUBGOAL_THEN + `!n. n <= dimindex(:N) + 1 + ==> (INTERS(d(SUC n)):real^N->bool) PSUBSET INTERS(d n)` + ASSUME_TAC THENL + [REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[INTERS_INSERT] THEN + FIRST_X_ASSUM(MP_TAC o SPEC `(d:num->(real^N->bool)->bool) n`) THEN + ANTS_TAC THENL [ALL_TAC; SIMP_TAC[]] THEN + REPEAT(FIRST_X_ASSUM(MP_TAC o SPEC `n:num`)) THEN + ASM_SIMP_TAC[ARITH_RULE `n <= N + 1 ==> n <= N + 2`] THEN + ASM_ARITH_TAC; + ALL_TAC] THEN + FIRST_X_ASSUM(CONJUNCTS_THEN(K ALL_TAC)) THEN + SUBGOAL_THEN + `!n. n <= dimindex(:N) + 2 + ==> aff_dim(INTERS(d n):real^N->bool) <= &(dimindex(:N)) - &n` + MP_TAC THENL + [INDUCT_TAC THEN REWRITE_TAC[INT_SUB_RZERO; AFF_DIM_LE_UNIV] THEN + DISCH_TAC THEN REWRITE_TAC[GSYM INT_OF_NUM_SUC] THEN + MATCH_MP_TAC(INT_ARITH + `!d':int. d < d' /\ d' <= m - n ==> d <= m - (n + &1)`) THEN + EXISTS_TAC `aff_dim(INTERS(d(n:num)):real^N->bool)` THEN + ASM_SIMP_TAC[ARITH_RULE `SUC n <= k + 2 ==> n <= k + 2`] THEN + MATCH_MP_TAC FACE_OF_AFF_DIM_LT THEN + ASM_SIMP_TAC[ARITH_RULE `SUC n <= m + 2 ==> n <= m + 1`; + SET_RULE `s PSUBSET t ==> ~(s = t)`] THEN + CONJ_TAC THENL + [MATCH_MP_TAC CONVEX_INTERS THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC FACE_OF_IMP_CONVEX THEN + EXISTS_TAC `s:real^N->bool` THEN + ASM_MESON_TAC[SUBSET; ARITH_RULE `SUC n <= m + 2 ==> n <= m + 2`]; + ALL_TAC] THEN + MP_TAC(ISPECL [`INTERS(d(SUC n)):real^N->bool`;`s:real^N->bool`; + `INTERS(d(n:num)):real^N->bool`] FACE_OF_FACE) THEN + ASM_SIMP_TAC[SET_RULE `s PSUBSET t ==> s SUBSET t`; + ARITH_RULE `SUC n <= m + 2 ==> n <= m + 1`] THEN + MATCH_MP_TAC(TAUT `a /\ b ==> (a ==> (c <=> b)) ==> c`) THEN + CONJ_TAC THEN MATCH_MP_TAC FACE_OF_INTERS THEN ASM_REWRITE_TAC[] THEN + ASM_MESON_TAC[SUBSET; ARITH_RULE `SUC n <= m + 2 ==> n <= m + 2`]; + ALL_TAC] THEN + DISCH_THEN(MP_TAC o SPEC `dimindex(:N) + 2`) THEN REWRITE_TAC[LE_REFL] THEN + MATCH_MP_TAC(TAUT `~p ==> p ==> q`) THEN REWRITE_TAC[INT_NOT_LE] THEN + REWRITE_TAC[GSYM INT_OF_NUM_ADD; INT_ARITH + `d - (d + &2):int < i <=> -- &1 <= i`] THEN + REWRITE_TAC[AFF_DIM_GE]);; + +let FACES_OF_TRANSLATION = prove + (`!s a:real^N. + {f | f face_of IMAGE (\x. a + x) s} = + IMAGE (IMAGE (\x. a + x)) {f | f face_of s}`, + REPEAT GEN_TAC THEN CONV_TAC SYM_CONV THEN + MATCH_MP_TAC SURJECTIVE_IMAGE_EQ THEN + REWRITE_TAC[IN_ELIM_THM; FACE_OF_TRANSLATION_EQ] THEN + REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[EQ_SYM_EQ] THEN + ONCE_REWRITE_TAC[TRANSLATION_GALOIS] THEN + REWRITE_TAC[EXISTS_REFL]);; + +let FACES_OF_LINEAR_IMAGE = prove + (`!f:real^M->real^N s. + linear f /\ (!x y. f x = f y ==> x = y) + ==> {t | t face_of (IMAGE f s)} = IMAGE (IMAGE f) {t | t face_of s}`, + REPEAT GEN_TAC THEN DISCH_TAC THEN + REWRITE_TAC[face_of; SUBSET_IMAGE; SET_RULE + `{y | (?x. P x /\ y = f x) /\ Q y} = {f x |x| P x /\ Q(f x)}`] THEN + REWRITE_TAC[SET_RULE `IMAGE f {x | P x} = {f x | P x}`] THEN + REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_IMAGE] THEN + FIRST_ASSUM(fun th -> + REWRITE_TAC[MATCH_MP CONVEX_LINEAR_IMAGE_EQ th; + MATCH_MP OPEN_SEGMENT_LINEAR_IMAGE th; + MATCH_MP (SET_RULE + `(!x y. f x = f y ==> x = y) ==> (!s x. f x IN IMAGE f s <=> x IN s)`) + (CONJUNCT2 th)]));; + +let FACE_OF_CONIC = prove + (`!s f:real^N->bool. conic s /\ f face_of s ==> conic f`, + REPEAT GEN_TAC THEN REWRITE_TAC[face_of; conic] THEN STRIP_TAC THEN + MAP_EVERY X_GEN_TAC [`x:real^N`; `c:real`] THEN STRIP_TAC THEN + ASM_CASES_TAC `x:real^N = vec 0` THENL + [ASM_MESON_TAC[VECTOR_MUL_RZERO]; ALL_TAC] THEN + ASM_CASES_TAC `c = &1` THENL + [ASM_MESON_TAC[VECTOR_MUL_LID]; ALL_TAC] THEN + SUBGOAL_THEN `?d e. &0 <= d /\ &0 <= e /\ d < &1 /\ &1 < e /\ d < e /\ + (d = c \/ e = c)` + MP_TAC THENL + [FIRST_X_ASSUM(DISJ_CASES_TAC o MATCH_MP (REAL_ARITH + `~(c = &1) ==> c < &1 \/ &1 < c`)) + THENL + [MAP_EVERY EXISTS_TAC [`c:real`; `&2`] THEN ASM_REAL_ARITH_TAC; + MAP_EVERY EXISTS_TAC [`&1 / &2`; `c:real`] THEN ASM_REAL_ARITH_TAC]; + DISCH_THEN(REPEAT_TCL CHOOSE_THEN + (REPEAT_TCL CONJUNCTS_THEN ASSUME_TAC)) THEN + FIRST_X_ASSUM(MP_TAC o SPECL + [`d % x :real^N`; `e % x:real^N`; `x:real^N`]) THEN + ANTS_TAC THENL [ALL_TAC; ASM_MESON_TAC[]] THEN + SUBGOAL_THEN `(x:real^N) IN s` ASSUME_TAC THENL + [ASM SET_TAC[]; ASM_SIMP_TAC[IN_SEGMENT]] THEN + ASM_SIMP_TAC[VECTOR_MUL_RCANCEL; REAL_LT_IMP_NE] THEN + EXISTS_TAC `(&1 - d) / (e - d)` THEN + ASM_SIMP_TAC[REAL_LT_LDIV_EQ; REAL_LT_RDIV_EQ; REAL_SUB_LT] THEN + REPEAT(CONJ_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC]) THEN + REWRITE_TAC[VECTOR_MUL_ASSOC; GSYM VECTOR_ADD_RDISTRIB] THEN + REWRITE_TAC[VECTOR_ARITH `x:real^N = a % x <=> (a - &1) % x = vec 0`] THEN + ASM_REWRITE_TAC[VECTOR_MUL_EQ_0] THEN + UNDISCH_TAC `d:real < e` THEN CONV_TAC REAL_FIELD]);; + +let FACE_OF_PCROSS = prove + (`!f s:real^M->bool f' s':real^N->bool. + f face_of s /\ f' face_of s' ==> (f PCROSS f') face_of (s PCROSS s')`, + REPEAT GEN_TAC THEN SIMP_TAC[face_of; CONVEX_PCROSS; PCROSS_MONO] THEN + REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN + REWRITE_TAC[IN_SEGMENT; FORALL_IN_PCROSS] THEN + REWRITE_TAC[RIGHT_IMP_FORALL_THM; IMP_IMP; GSYM CONJ_ASSOC] THEN + REWRITE_TAC[GSYM PASTECART_CMUL; PASTECART_ADD; PASTECART_INJ] THEN + REWRITE_TAC[PASTECART_IN_PCROSS] THEN + MAP_EVERY X_GEN_TAC + [`a:real^M`; `a':real^N`; `b:real^M`; `b':real^N`] THEN + MAP_EVERY ASM_CASES_TAC [`b:real^M = a`; `b':real^N = a'`] THEN + ASM_REWRITE_TAC[VECTOR_ARITH `(&1 - u) % a + u % a:real^N = a`] THEN + ASM_MESON_TAC[]);; + +let FACE_OF_PCROSS_DECOMP = prove + (`!s:real^M->bool s':real^N->bool c. + c face_of (s PCROSS s') <=> + ?f f'. f face_of s /\ f' face_of s' /\ c = f PCROSS f'`, + REPEAT GEN_TAC THEN EQ_TAC THENL + [ALL_TAC; STRIP_TAC THEN ASM_SIMP_TAC[FACE_OF_PCROSS]] THEN + ASM_CASES_TAC `c:real^(M,N)finite_sum->bool = {}` THENL + [ASM_MESON_TAC[EMPTY_FACE_OF; PCROSS_EMPTY]; DISCH_TAC] THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP FACE_OF_IMP_CONVEX) THEN + MAP_EVERY EXISTS_TAC + [`IMAGE fstcart (c:real^(M,N)finite_sum->bool)`; + `IMAGE sndcart (c:real^(M,N)finite_sum->bool)`] THEN + MATCH_MP_TAC(TAUT `(p /\ q ==> r) /\ p /\ q ==> p /\ q /\ r`) THEN + CONJ_TAC THENL + [STRIP_TAC THEN MATCH_MP_TAC FACE_OF_EQ THEN + EXISTS_TAC `(s:real^M->bool) PCROSS (s':real^N->bool)` THEN + ASM_SIMP_TAC[FACE_OF_PCROSS; RELATIVE_INTERIOR_PCROSS] THEN + ASM_SIMP_TAC[RELATIVE_INTERIOR_LINEAR_IMAGE_CONVEX; + LINEAR_FSTCART; LINEAR_SNDCART] THEN + MATCH_MP_TAC(SET_RULE `~(s = {}) /\ s SUBSET t ==> ~DISJOINT s t`) THEN + ASM_SIMP_TAC[RELATIVE_INTERIOR_EQ_EMPTY] THEN + REWRITE_TAC[SUBSET; FORALL_PASTECART; PASTECART_IN_PCROSS; IN_IMAGE] THEN + REWRITE_TAC[EXISTS_PASTECART; FSTCART_PASTECART; SNDCART_PASTECART] THEN + MESON_TAC[]; + ALL_TAC] THEN + FIRST_X_ASSUM(STRIP_ASSUME_TAC o GEN_REWRITE_RULE I [face_of]) THEN + REWRITE_TAC[face_of] THEN + ASM_SIMP_TAC[CONVEX_LINEAR_IMAGE; LINEAR_FSTCART; LINEAR_SNDCART] THEN + FIRST_ASSUM(MP_TAC o ISPEC `fstcart:real^(M,N)finite_sum->real^M` o + MATCH_MP IMAGE_SUBSET) THEN + FIRST_ASSUM(MP_TAC o ISPEC `sndcart:real^(M,N)finite_sum->real^N` o + MATCH_MP IMAGE_SUBSET) THEN + REWRITE_TAC[IMAGE_FSTCART_PCROSS; IMAGE_SNDCART_PCROSS] THEN + REPEAT(DISCH_THEN(ASSUME_TAC o MATCH_MP (SET_RULE + `s SUBSET (if p then {} else t) ==> s SUBSET t`))) THEN + ASM_REWRITE_TAC[] THEN CONJ_TAC THENL + [MAP_EVERY X_GEN_TAC [`a:real^M`; `b:real^M`; `x:real^M`] THEN + STRIP_TAC THEN FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_IMAGE]) THEN + REWRITE_TAC[EXISTS_PASTECART; FSTCART_PASTECART] THEN + REWRITE_TAC[RIGHT_EXISTS_AND_THM; UNWIND_THM1] THEN + DISCH_THEN(X_CHOOSE_TAC `y:real^N`) THEN FIRST_X_ASSUM(MP_TAC o SPECL + [`pastecart (a:real^M) (y:real^N)`; + `pastecart (b:real^M) (y:real^N)`; + `pastecart (x:real^M) (y:real^N)`]) THEN + ASM_REWRITE_TAC[PASTECART_IN_PCROSS; IN_IMAGE; EXISTS_PASTECART] THEN + REWRITE_TAC[FSTCART_PASTECART; RIGHT_EXISTS_AND_THM; UNWIND_THM1] THEN + ANTS_TAC THENL [ALL_TAC; MESON_TAC[]] THEN + UNDISCH_TAC `(c:real^(M,N)finite_sum->bool) SUBSET s PCROSS s'` THEN + REWRITE_TAC[SUBSET] THEN + DISCH_THEN(MP_TAC o SPEC `pastecart (x:real^M) (y:real^N)`); + MAP_EVERY X_GEN_TAC [`a:real^N`; `b:real^N`; `x:real^N`] THEN + STRIP_TAC THEN FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_IMAGE]) THEN + REWRITE_TAC[EXISTS_PASTECART; SNDCART_PASTECART] THEN + REWRITE_TAC[RIGHT_EXISTS_AND_THM; UNWIND_THM1] THEN + DISCH_THEN(X_CHOOSE_TAC `y:real^M`) THEN FIRST_X_ASSUM(MP_TAC o SPECL + [`pastecart (y:real^M) (a:real^N)`; + `pastecart (y:real^M) (b:real^N)`; + `pastecart (y:real^M) (x:real^N)`]) THEN + ASM_REWRITE_TAC[PASTECART_IN_PCROSS; IN_IMAGE; EXISTS_PASTECART] THEN + REWRITE_TAC[SNDCART_PASTECART; RIGHT_EXISTS_AND_THM; UNWIND_THM1] THEN + ANTS_TAC THENL [ALL_TAC; MESON_TAC[]] THEN + UNDISCH_TAC `(c:real^(M,N)finite_sum->bool) SUBSET s PCROSS s'` THEN + REWRITE_TAC[SUBSET] THEN + DISCH_THEN(MP_TAC o SPEC `pastecart (y:real^M) (x:real^N)`)] THEN + ASM_REWRITE_TAC[PASTECART_IN_PCROSS] THEN STRIP_TAC THEN + ASM_REWRITE_TAC[] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_SEGMENT]) THEN + REWRITE_TAC[IN_SEGMENT; PASTECART_INJ] THEN + REWRITE_TAC[PASTECART_ADD; GSYM PASTECART_CMUL; + VECTOR_ARITH `(&1 - u) % a + u % a:real^N = a`] THEN + MESON_TAC[]);; + +let FACE_OF_PCROSS_EQ = prove + (`!f s:real^M->bool f' s':real^N->bool. + (f PCROSS f') face_of (s PCROSS s') <=> + f = {} \/ f' = {} \/ f face_of s /\ f' face_of s'`, + REPEAT GEN_TAC THEN MAP_EVERY ASM_CASES_TAC + [`f:real^M->bool = {}`; `f':real^N->bool = {}`] THEN + ASM_REWRITE_TAC[PCROSS_EMPTY; EMPTY_FACE_OF] THEN + ASM_REWRITE_TAC[FACE_OF_PCROSS_DECOMP; PCROSS_EQ] THEN MESON_TAC[]);; + +let HYPERPLANE_FACE_OF_HALFSPACE_LE = prove + (`!a:real^N b. {x | a dot x = b} face_of {x | a dot x <= b}`, + REPEAT GEN_TAC THEN + ONCE_REWRITE_TAC[REAL_ARITH `a:real = b <=> a <= b /\ a = b`] THEN + REWRITE_TAC[SET_RULE `{x | P x /\ Q x} = {x | P x} INTER {x | Q x}`] THEN + MATCH_MP_TAC FACE_OF_INTER_SUPPORTING_HYPERPLANE_LE THEN + REWRITE_TAC[IN_ELIM_THM; CONVEX_HALFSPACE_LE]);; + +let HYPERPLANE_FACE_OF_HALFSPACE_GE = prove + (`!a:real^N b. {x | a dot x = b} face_of {x | a dot x >= b}`, + REPEAT GEN_TAC THEN + ONCE_REWRITE_TAC[REAL_ARITH `a:real = b <=> a >= b /\ a = b`] THEN + REWRITE_TAC[SET_RULE `{x | P x /\ Q x} = {x | P x} INTER {x | Q x}`] THEN + MATCH_MP_TAC FACE_OF_INTER_SUPPORTING_HYPERPLANE_GE THEN + REWRITE_TAC[IN_ELIM_THM; CONVEX_HALFSPACE_GE]);; + +let FACE_OF_HALFSPACE_LE = prove + (`!f a:real^N b. + f face_of {x | a dot x <= b} <=> + f = {} \/ f = {x | a dot x = b} \/ f = {x | a dot x <= b}`, + REPEAT GEN_TAC THEN ASM_CASES_TAC `a:real^N = vec 0` THENL + [ASM_SIMP_TAC[DOT_LZERO; SET_RULE `{x | p} = if p then UNIV else {}`] THEN + REPEAT(COND_CASES_TAC THEN ASM_REWRITE_TAC[FACE_OF_EMPTY]) THEN + ASM_SIMP_TAC[FACE_OF_AFFINE_EQ; AFFINE_UNIV; DISJ_ACI] THEN + ASM_REAL_ARITH_TAC; + ALL_TAC] THEN + EQ_TAC THEN STRIP_TAC THEN + ASM_SIMP_TAC[EMPTY_FACE_OF; FACE_OF_REFL; CONVEX_HALFSPACE_LE; + HYPERPLANE_FACE_OF_HALFSPACE_LE] THEN + MATCH_MP_TAC(TAUT `(~r ==> p \/ q) ==> p \/ q \/ r`) THEN DISCH_TAC THEN + SUBGOAL_THEN `f face_of {x:real^N | a dot x = b}` MP_TAC THENL + [ASM_SIMP_TAC[GSYM FRONTIER_HALFSPACE_LE] THEN + ASM_SIMP_TAC[CONV_RULE(RAND_CONV SYM_CONV) + (SPEC_ALL RELATIVE_FRONTIER_NONEMPTY_INTERIOR); + INTERIOR_HALFSPACE_LE; HALFSPACE_EQ_EMPTY_LT] THEN + MATCH_MP_TAC FACE_OF_SUBSET THEN + EXISTS_TAC `{x:real^N | a dot x <= b}` THEN + ASM_SIMP_TAC[FACE_OF_SUBSET_RELATIVE_FRONTIER] THEN + ASM_SIMP_TAC[relative_frontier; CLOSURE_CLOSED; CLOSED_HALFSPACE_LE] THEN + SET_TAC[]; + ASM_SIMP_TAC[FACE_OF_AFFINE_EQ; AFFINE_HYPERPLANE]]);; + +let FACE_OF_HALFSPACE_GE = prove + (`!f a:real^N b. + f face_of {x | a dot x >= b} <=> + f = {} \/ f = {x | a dot x = b} \/ f = {x | a dot x >= b}`, + REPEAT GEN_TAC THEN + MP_TAC(ISPECL [`f:real^N->bool`; `--a:real^N`; `--b:real`] + FACE_OF_HALFSPACE_LE) THEN + REWRITE_TAC[DOT_LNEG; REAL_LE_NEG2; REAL_EQ_NEG2; real_ge]);; + +(* ------------------------------------------------------------------------- *) +(* Exposed faces (faces that are intersection with supporting hyperplane). *) +(* ------------------------------------------------------------------------- *) + +parse_as_infix("exposed_face_of",(12,"right"));; + +let exposed_face_of = new_definition + `t exposed_face_of s <=> + t face_of s /\ + ?a b. s SUBSET {x | a dot x <= b} /\ t = s INTER {x | a dot x = b}`;; + +let EMPTY_EXPOSED_FACE_OF = prove + (`!s:real^N->bool. {} exposed_face_of s`, + GEN_TAC THEN REWRITE_TAC[exposed_face_of; EMPTY_FACE_OF] THEN + MAP_EVERY EXISTS_TAC [`vec 0:real^N`; `&1:real`] THEN + REWRITE_TAC[DOT_LZERO] THEN CONV_TAC REAL_RAT_REDUCE_CONV THEN SET_TAC[]);; + +let EXPOSED_FACE_OF_REFL_EQ = prove + (`!s:real^N->bool. s exposed_face_of s <=> convex s`, + GEN_TAC THEN REWRITE_TAC[exposed_face_of; FACE_OF_REFL_EQ] THEN + ASM_CASES_TAC `convex(s:real^N->bool)` THEN ASM_REWRITE_TAC[] THEN + MAP_EVERY EXISTS_TAC [`vec 0:real^N`; `&0:real`] THEN + REWRITE_TAC[DOT_LZERO] THEN CONV_TAC REAL_RAT_REDUCE_CONV THEN SET_TAC[]);; + +let EXPOSED_FACE_OF_REFL = prove + (`!s:real^N->bool. convex s ==> s exposed_face_of s`, + REWRITE_TAC[EXPOSED_FACE_OF_REFL_EQ]);; + +let EXPOSED_FACE_OF = prove + (`!s t. t exposed_face_of s <=> + t face_of s /\ + (t = {} \/ t = s \/ + ?a b. ~(a = vec 0) /\ + s SUBSET {x:real^N | a dot x <= b} /\ + t = s INTER {x | a dot x = b})`, + REPEAT GEN_TAC THEN ASM_CASES_TAC `t:real^N->bool = {}` THEN + ASM_REWRITE_TAC[EMPTY_EXPOSED_FACE_OF; EMPTY_FACE_OF] THEN + ASM_CASES_TAC `t:real^N->bool = s` THEN + ASM_REWRITE_TAC[EXPOSED_FACE_OF_REFL_EQ; FACE_OF_REFL_EQ] THEN + REWRITE_TAC[exposed_face_of] THEN AP_TERM_TAC THEN + EQ_TAC THENL [REWRITE_TAC[LEFT_IMP_EXISTS_THM]; MESON_TAC[]] THEN + MAP_EVERY X_GEN_TAC [`a:real^N`; `b:real`] THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + MAP_EVERY EXISTS_TAC [`a:real^N`; `b:real`] THEN + ASM_CASES_TAC `a:real^N = vec 0` THEN ASM_REWRITE_TAC[] THEN + FIRST_X_ASSUM SUBST_ALL_TAC THEN REPEAT(POP_ASSUM MP_TAC) THEN + REWRITE_TAC[DOT_LZERO] THEN SET_TAC[]);; + +let EXPOSED_FACE_OF_TRANSLATION_EQ = prove + (`!a f s:real^N->bool. + (IMAGE (\x. a + x) f) exposed_face_of (IMAGE (\x. a + x) s) <=> + f exposed_face_of s`, + REPEAT GEN_TAC THEN REWRITE_TAC[exposed_face_of; FACE_OF_TRANSLATION_EQ] THEN + MP_TAC(ISPEC `\x:real^N. a + x` QUANTIFY_SURJECTION_THM) THEN + REWRITE_TAC[] THEN ANTS_TAC THENL + [MESON_TAC[VECTOR_ARITH `y + (x - y):real^N = x`]; ALL_TAC] THEN + DISCH_THEN(fun th -> GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) + [last(CONJUNCTS th)]) THEN + REWRITE_TAC[end_itlist CONJ (!invariant_under_translation)] THEN + REWRITE_TAC[DOT_RADD] THEN ONCE_REWRITE_TAC[REAL_ADD_SYM] THEN + REWRITE_TAC[GSYM REAL_LE_SUB_LADD; GSYM REAL_EQ_SUB_LADD] THEN + AP_TERM_TAC THEN AP_TERM_TAC THEN GEN_REWRITE_TAC I [FUN_EQ_THM] THEN + X_GEN_TAC `c:real^N` THEN REWRITE_TAC[] THEN + EQ_TAC THEN DISCH_THEN(X_CHOOSE_THEN `b:real` STRIP_ASSUME_TAC) THENL + [EXISTS_TAC `b - (c:real^N) dot a`; + EXISTS_TAC `b + (c:real^N) dot a`] THEN + ASM_REWRITE_TAC[REAL_ARITH `(x + y) - y:real = x`]);; + +add_translation_invariants [EXPOSED_FACE_OF_TRANSLATION_EQ];; + +let EXPOSED_FACE_OF_LINEAR_IMAGE = prove + (`!f:real^M->real^N c s. + linear f /\ (!x y. f x = f y ==> x = y) /\ (!y. ?x. f x = y) + ==> ((IMAGE f c) exposed_face_of (IMAGE f s) <=> c exposed_face_of s)`, + REPEAT STRIP_TAC THEN REWRITE_TAC[exposed_face_of] THEN + BINOP_TAC THENL [ASM_MESON_TAC[FACE_OF_LINEAR_IMAGE]; ALL_TAC] THEN + MP_TAC(ISPEC `f:real^M->real^N` QUANTIFY_SURJECTION_THM) THEN + ASM_REWRITE_TAC[] THEN + DISCH_THEN(fun th -> GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) + [last(CONJUNCTS th)]) THEN + ONCE_REWRITE_TAC[DOT_SYM] THEN ASM_SIMP_TAC[ADJOINT_WORKS] THEN + MP_TAC(end_itlist CONJ + (mapfilter (ISPEC `f:real^M->real^N`) (!invariant_under_linear))) THEN + ASM_REWRITE_TAC[] THEN DISCH_TAC THEN ASM_REWRITE_TAC[] THEN + ONCE_REWRITE_TAC[SWAP_EXISTS_THM] THEN AP_TERM_TAC THEN ABS_TAC THEN + EQ_TAC THENL + [DISCH_THEN(X_CHOOSE_THEN `a:real^N` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `adjoint(f:real^M->real^N) a` THEN ASM_REWRITE_TAC[]; + DISCH_THEN(X_CHOOSE_THEN `a:real^M` STRIP_ASSUME_TAC) THEN + MP_TAC(ISPEC `adjoint(f:real^M->real^N)` + LINEAR_SURJECTIVE_RIGHT_INVERSE) THEN + ASM_SIMP_TAC[ADJOINT_SURJECTIVE; ADJOINT_LINEAR] THEN + REWRITE_TAC[FUN_EQ_THM; o_THM; I_THM; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `g:real^M->real^N` THEN STRIP_TAC THEN + EXISTS_TAC `(g:real^M->real^N) a` THEN ASM_REWRITE_TAC[]]);; + +let EXPOSED_FACE_OF_INTER_SUPPORTING_HYPERPLANE_LE = prove + (`!s a:real^N b. + convex s /\ (!x. x IN s ==> a dot x <= b) + ==> (s INTER {x | a dot x = b}) exposed_face_of s`, + SIMP_TAC[FACE_OF_INTER_SUPPORTING_HYPERPLANE_LE; exposed_face_of] THEN + SET_TAC[]);; + +let EXPOSED_FACE_OF_INTER_SUPPORTING_HYPERPLANE_GE = prove + (`!s a:real^N b. + convex s /\ (!x. x IN s ==> a dot x >= b) + ==> (s INTER {x | a dot x = b}) exposed_face_of s`, + REWRITE_TAC[real_ge] THEN REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`s:real^N->bool`; `--a:real^N`; `--b:real`] + EXPOSED_FACE_OF_INTER_SUPPORTING_HYPERPLANE_LE) THEN + ASM_REWRITE_TAC[DOT_LNEG; REAL_EQ_NEG2; REAL_LE_NEG2]);; + +let EXPOSED_FACE_OF_INTER = prove + (`!s t u:real^N->bool. + t exposed_face_of s /\ u exposed_face_of s + ==> (t INTER u) exposed_face_of s`, + REPEAT GEN_TAC THEN SIMP_TAC[exposed_face_of; FACE_OF_INTER] THEN + REWRITE_TAC[RIGHT_AND_EXISTS_THM] THEN + REWRITE_TAC[LEFT_AND_EXISTS_THM; LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC + [`a':real^N`; `b':real`; `a:real^N`; `b:real`] THEN + REWRITE_TAC[SUBSET; IN_ELIM_THM] THEN STRIP_TAC THEN + ASM_REWRITE_TAC[] THEN + MAP_EVERY EXISTS_TAC [`a + a':real^N`; `b + b':real`] THEN + REWRITE_TAC[SET_RULE + `(s INTER t1) INTER (s INTER t2) = s INTER u <=> + !x. x IN s ==> (x IN t1 /\ x IN t2 <=> x IN u)`] THEN + ASM_SIMP_TAC[DOT_LADD; REAL_LE_ADD2; IN_ELIM_THM] THEN + X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN + REPEAT(FIRST_X_ASSUM(MP_TAC o SPEC `x:real^N`)) THEN + ASM_REWRITE_TAC[] THEN REAL_ARITH_TAC);; + +let EXPOSED_FACE_OF_INTERS = prove + (`!P s:real^N->bool. + ~(P = {}) /\ (!t. t IN P ==> t exposed_face_of s) + ==> INTERS P exposed_face_of s`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`s:real^N->bool`; `P:(real^N->bool)->bool`] + INTERS_FACES_FINITE_ALTBOUND) THEN + ANTS_TAC THENL [ASM_MESON_TAC[exposed_face_of]; ALL_TAC] THEN + DISCH_THEN(X_CHOOSE_THEN `Q:(real^N->bool)->bool` STRIP_ASSUME_TAC) THEN + FIRST_X_ASSUM(MP_TAC o SYM) THEN + ASM_CASES_TAC `Q:(real^N->bool)->bool = {}` THENL + [ASM_SIMP_TAC[INTERS_0] THEN + REWRITE_TAC[SET_RULE `INTERS s = UNIV <=> !t. t IN s ==> t = UNIV`] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN + ASM_MESON_TAC[]; + DISCH_THEN SUBST1_TAC THEN + FIRST_X_ASSUM(MP_TAC o check (is_neg o concl)) THEN + SUBGOAL_THEN `!t:real^N->bool. t IN Q ==> t exposed_face_of s` MP_TAC THENL + [ASM SET_TAC[]; UNDISCH_TAC `FINITE(Q:(real^N->bool)->bool)`] THEN + SPEC_TAC(`Q:(real^N->bool)->bool`,`Q:(real^N->bool)->bool`) THEN + POP_ASSUM_LIST(K ALL_TAC) THEN + MATCH_MP_TAC FINITE_INDUCT_STRONG THEN REWRITE_TAC[FORALL_IN_INSERT] THEN + MAP_EVERY X_GEN_TAC [`t:real^N->bool`; `P:(real^N->bool)->bool`] THEN + DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[INTERS_INSERT] THEN + ASM_CASES_TAC `P:(real^N->bool)->bool = {}` THEN + ASM_SIMP_TAC[INTERS_0; INTER_UNIV; EXPOSED_FACE_OF_INTER]]);; + +let EXPOSED_FACE_OF_SUMS = prove + (`!s t f:real^N->bool. + convex s /\ convex t /\ + f exposed_face_of {x + y | x IN s /\ y IN t} + ==> ?k l. k exposed_face_of s /\ l exposed_face_of t /\ + f = {x + y | x IN k /\ y IN l}`, + REPEAT STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [EXPOSED_FACE_OF]) THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + ASM_CASES_TAC `f:real^N->bool = {}` THENL + [DISCH_TAC THEN REPEAT (EXISTS_TAC `{}:real^N->bool`) THEN + ASM_REWRITE_TAC[EMPTY_EXPOSED_FACE_OF] THEN SET_TAC[]; + ALL_TAC] THEN + ASM_CASES_TAC `f = {x + y :real^N | x IN s /\ y IN t}` THENL + [DISCH_TAC THEN + MAP_EVERY EXISTS_TAC [`s:real^N->bool`; `t:real^N->bool`] THEN + ASM_SIMP_TAC[EXPOSED_FACE_OF_REFL]; + ALL_TAC] THEN + ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`u:real^N`; `z:real`] THEN + REWRITE_TAC[SUBSET; FORALL_IN_GSPEC; IN_ELIM_THM] THEN + REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + DISCH_THEN SUBST_ALL_TAC THEN + RULE_ASSUM_TAC(REWRITE_RULE[GSYM SUBSET_INTER_ABSORPTION]) THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN + REWRITE_TAC[EXISTS_IN_GSPEC; IN_INTER] THEN + REWRITE_TAC[IN_ELIM_THM; LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`a0:real^N`; `b0:real^N`] THEN STRIP_TAC THEN + FIRST_X_ASSUM(SUBST_ALL_TAC o SYM) THEN + EXISTS_TAC `s INTER {x:real^N | u dot x = u dot a0}` THEN + EXISTS_TAC `t INTER {y:real^N | u dot y = u dot b0}` THEN + REPEAT CONJ_TAC THENL + [MATCH_MP_TAC EXPOSED_FACE_OF_INTER_SUPPORTING_HYPERPLANE_LE THEN + ASM_REWRITE_TAC[] THEN X_GEN_TAC `a:real^N` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`a:real^N`; `b0:real^N`]) THEN + ASM_REWRITE_TAC[DOT_RADD] THEN REAL_ARITH_TAC; + MATCH_MP_TAC EXPOSED_FACE_OF_INTER_SUPPORTING_HYPERPLANE_LE THEN + ASM_REWRITE_TAC[] THEN X_GEN_TAC `b:real^N` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`a0:real^N`; `b:real^N`]) THEN + ASM_REWRITE_TAC[DOT_RADD] THEN REAL_ARITH_TAC; + ALL_TAC] THEN + MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THEN + REWRITE_TAC[SUBSET; FORALL_IN_GSPEC; IN_INTER; IMP_CONJ] THENL + [ALL_TAC; SIMP_TAC[IN_INTER; IN_ELIM_THM; DOT_RADD] THEN MESON_TAC[]] THEN + MAP_EVERY X_GEN_TAC [`a:real^N`; `b:real^N`] THEN + DISCH_TAC THEN DISCH_TAC THEN REWRITE_TAC[IN_ELIM_THM; DOT_RADD] THEN + DISCH_TAC THEN MAP_EVERY EXISTS_TAC [`a:real^N`; `b:real^N`] THEN + ASM_REWRITE_TAC[] THEN + FIRST_ASSUM(MP_TAC o SPECL [`a:real^N`; `b0:real^N`]) THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`a0:real^N`; `b:real^N`]) THEN + ASM_REWRITE_TAC[DOT_RADD] THEN ASM_REAL_ARITH_TAC);; + +let EXPOSED_FACE_OF_PARALLEL = prove + (`!t s. t exposed_face_of s <=> + t face_of s /\ + ?a b. s SUBSET {x:real^N | a dot x <= b} /\ + t = s INTER {x | a dot x = b} /\ + (~(t = {}) /\ ~(t = s) ==> ~(a = vec 0)) /\ + (!w. w IN affine hull s /\ ~(t = s) + ==> (w + a) IN affine hull s)`, + REPEAT GEN_TAC THEN REWRITE_TAC[exposed_face_of] THEN + AP_TERM_TAC THEN EQ_TAC THENL + [REWRITE_TAC[LEFT_IMP_EXISTS_THM]; + REPEAT(MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC) THEN SIMP_TAC[]] THEN + MAP_EVERY X_GEN_TAC [`a:real^N`; `b:real`] THEN STRIP_TAC THEN + MP_TAC(ISPECL [`affine hull s:real^N->bool`; `--a:real^N`; `--b:real`] + AFFINE_PARALLEL_SLICE) THEN + SIMP_TAC[AFFINE_AFFINE_HULL; DOT_LNEG; REAL_LE_NEG2; REAL_EQ_NEG2] THEN + DISCH_THEN(REPEAT_TCL DISJ_CASES_THEN ASSUME_TAC) THENL + [MAP_EVERY EXISTS_TAC [`vec 0:real^N`; `&1`] THEN + REWRITE_TAC[DOT_LZERO; REAL_POS; SET_RULE `{x | T} = UNIV`] THEN + SIMP_TAC[SUBSET_UNIV; VECTOR_ADD_RID; REAL_ARITH `~(&0 = &1)`] THEN + REWRITE_TAC[EMPTY_GSPEC] THEN ASM_REWRITE_TAC[INTER_EMPTY] THEN + MATCH_MP_TAC(TAUT `p ==> p /\ ~(~p /\ q)`) THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE + `s' INTER t' = {} + ==> s SUBSET s' /\ t SUBSET t' ==> s INTER t = {}`)) THEN + REWRITE_TAC[HULL_SUBSET] THEN SIMP_TAC[SUBSET; IN_ELIM_THM; REAL_LE_REFL]; + SUBGOAL_THEN `t:real^N->bool = s` SUBST1_TAC THENL + [FIRST_X_ASSUM SUBST1_TAC THEN REWRITE_TAC[GSYM REAL_LE_ANTISYM] THEN + SUBGOAL_THEN `s SUBSET affine hull (s:real^N->bool)` MP_TAC THENL + [REWRITE_TAC[HULL_SUBSET]; ASM SET_TAC[]]; + MAP_EVERY EXISTS_TAC [`vec 0:real^N`; `&0`] THEN + REWRITE_TAC[DOT_LZERO; SET_RULE `{x | T} = UNIV`; REAL_LE_REFL] THEN + SET_TAC[]]; + FIRST_X_ASSUM(X_CHOOSE_THEN `a':real^N` MP_TAC) THEN + DISCH_THEN(X_CHOOSE_THEN `b':real` STRIP_ASSUME_TAC) THEN + MAP_EVERY EXISTS_TAC [`--a':real^N`; `--b':real`] THEN + ASM_REWRITE_TAC[DOT_LNEG; REAL_LE_NEG2; REAL_EQ_NEG2] THEN + REPEAT CONJ_TAC THENL + [ONCE_REWRITE_TAC[REAL_ARITH `b <= a <=> ~(a <= b) \/ a = b`] THEN + MATCH_MP_TAC(SET_RULE + `!s'. s SUBSET s' /\ + s SUBSET (UNIV DIFF (s' INTER {x | P x})) UNION + (s' INTER {x | Q x}) + ==> s SUBSET {x | ~P x \/ Q x}`) THEN + EXISTS_TAC `affine hull s:real^N->bool` THEN + ASM_REWRITE_TAC[HULL_SUBSET] THEN + MATCH_MP_TAC(SET_RULE + `s SUBSET s' /\ s SUBSET (UNIV DIFF {x | P x}) UNION {x | Q x} + ==> s SUBSET (UNIV DIFF (s' INTER {x | P x})) UNION + (s' INTER {x | Q x})`) THEN + REWRITE_TAC[HULL_SUBSET] THEN MATCH_MP_TAC SUBSET_TRANS THEN + EXISTS_TAC `{x:real^N | a dot x <= b}` THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[SUBSET; IN_DIFF; IN_UNIV; IN_UNION; IN_ELIM_THM] THEN + REAL_ARITH_TAC; + FIRST_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE + `s' INTER a = s' INTER b + ==> s SUBSET s' ==> s INTER b = s INTER a`)) THEN + REWRITE_TAC[HULL_SUBSET]; + ASM_REWRITE_TAC[VECTOR_NEG_EQ_0]; + ONCE_REWRITE_TAC[VECTOR_ARITH + `w + --a:real^N = w + &1 % (w - (w + a))`] THEN + ASM_SIMP_TAC[IN_AFFINE_ADD_MUL_DIFF; AFFINE_AFFINE_HULL]]]);; + +(* ------------------------------------------------------------------------- *) +(* Extreme points of a set, which are its singleton faces. *) +(* ------------------------------------------------------------------------- *) + +parse_as_infix("extreme_point_of",(12,"right"));; + +let extreme_point_of = new_definition + `x extreme_point_of s <=> + x IN s /\ !a b. a IN s /\ b IN s ==> ~(x IN segment(a,b))`;; + +let EXTREME_POINT_OF_STILLCONVEX = prove + (`!s x:real^N. + convex s ==> (x extreme_point_of s <=> x IN s /\ convex(s DELETE x))`, + REWRITE_TAC[CONVEX_CONTAINS_SEGMENT; extreme_point_of; open_segment] THEN + REWRITE_TAC[IN_DIFF; IN_DELETE; IN_INSERT; NOT_IN_EMPTY; SUBSET_DELETE] THEN + SET_TAC[]);; + +let FACE_OF_SING = prove + (`!x s. {x} face_of s <=> x extreme_point_of s`, + SIMP_TAC[face_of; extreme_point_of; SING_SUBSET; CONVEX_SING; IN_SING] THEN + MESON_TAC[SEGMENT_REFL; NOT_IN_EMPTY]);; + +let EXTREME_POINT_NOT_IN_RELATIVE_INTERIOR = prove + (`!s x:real^N. + x extreme_point_of s /\ ~(s = {x}) + ==> ~(x IN relative_interior s)`, + REPEAT GEN_TAC THEN CONV_TAC(ONCE_DEPTH_CONV SYM_CONV) THEN + REWRITE_TAC[GSYM FACE_OF_SING] THEN + DISCH_THEN(MP_TAC o MATCH_MP FACE_OF_DISJOINT_RELATIVE_INTERIOR) THEN + SET_TAC[]);; + +let EXTREME_POINT_NOT_IN_INTERIOR = prove + (`!s x:real^N. x extreme_point_of s ==> ~(x IN interior s)`, + REPEAT GEN_TAC THEN DISCH_TAC THEN ASM_CASES_TAC `s = {x:real^N}` THEN + ASM_SIMP_TAC[EMPTY_INTERIOR_FINITE; FINITE_SING; NOT_IN_EMPTY] THEN + DISCH_THEN(MP_TAC o MATCH_MP (REWRITE_RULE[SUBSET] + INTERIOR_SUBSET_RELATIVE_INTERIOR)) THEN + ASM_SIMP_TAC[EXTREME_POINT_NOT_IN_RELATIVE_INTERIOR]);; + +let EXTREME_POINT_OF_FACE = prove + (`!f s v. f face_of s + ==> (v extreme_point_of f <=> v extreme_point_of s /\ v IN f)`, + REWRITE_TAC[GSYM FACE_OF_SING; GSYM SING_SUBSET; FACE_OF_FACE]);; + +let EXTREME_POINT_OF_MIDPOINT = prove + (`!s x:real^N. + convex s + ==> (x extreme_point_of s <=> + x IN s /\ + !a b. a IN s /\ b IN s /\ x = midpoint(a,b) ==> x = a /\ x = b)`, + REPEAT STRIP_TAC THEN REWRITE_TAC[extreme_point_of] THEN + AP_TERM_TAC THEN EQ_TAC THEN + DISCH_TAC THEN MAP_EVERY X_GEN_TAC [`a:real^N`; `b:real^N`] THEN + DISCH_TAC THENL + [FIRST_X_ASSUM(MP_TAC o SPECL [`a:real^N`; `b:real^N`]) THEN + ASM_SIMP_TAC[MIDPOINT_IN_SEGMENT; MIDPOINT_REFL]; + ALL_TAC] THEN + REWRITE_TAC[IN_SEGMENT] THEN DISCH_THEN(CONJUNCTS_THEN2 + ASSUME_TAC (X_CHOOSE_THEN `u:real` STRIP_ASSUME_TAC)) THEN + ABBREV_TAC `d = min (&1 - u) u` THEN + FIRST_X_ASSUM(MP_TAC o SPECL + [`x - d / &2 % (b - a):real^N`; `x + d / &2 % (b - a):real^N`]) THEN + REWRITE_TAC[NOT_IMP] THEN REPEAT CONJ_TAC THENL + [FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [CONVEX_ALT]) THEN + ASM_REWRITE_TAC[VECTOR_ARITH + `((&1 - u) % a + u % b) - d / &2 % (b - a):real^N = + (&1 - (u - d / &2)) % a + (u - d / &2) % b`] THEN + DISCH_THEN MATCH_MP_TAC THEN ASM_REWRITE_TAC[] THEN ASM_REAL_ARITH_TAC; + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [CONVEX_ALT]) THEN + ASM_REWRITE_TAC[VECTOR_ARITH + `((&1 - u) % a + u % b) + d / &2 % (b - a):real^N = + (&1 - (u + d / &2)) % a + (u + d / &2) % b`] THEN + DISCH_THEN MATCH_MP_TAC THEN ASM_REWRITE_TAC[] THEN ASM_REAL_ARITH_TAC; + REWRITE_TAC[midpoint] THEN VECTOR_ARITH_TAC; + REWRITE_TAC[VECTOR_ARITH `x:real^N = x - d <=> d = vec 0`; + VECTOR_ARITH `x:real^N = x + d <=> d = vec 0`] THEN + ASM_REWRITE_TAC[VECTOR_MUL_EQ_0; VECTOR_SUB_EQ] THEN ASM_REAL_ARITH_TAC]);; + +let EXTREME_POINT_OF_CONVEX_HULL = prove + (`!x:real^N s. x extreme_point_of (convex hull s) ==> x IN s`, + REPEAT GEN_TAC THEN + SIMP_TAC[EXTREME_POINT_OF_STILLCONVEX; CONVEX_CONVEX_HULL] THEN + MP_TAC(ISPECL [`convex:(real^N->bool)->bool`; `s:real^N->bool`; + `(convex hull s) DELETE (x:real^N)`] HULL_MINIMAL) THEN + MP_TAC(ISPECL [`convex:(real^N->bool)->bool`; `s:real^N->bool`] + HULL_SUBSET) THEN + ASM SET_TAC[]);; + +let EXTREME_POINTS_OF_CONVEX_HULL = prove + (`!s. {x | x extreme_point_of (convex hull s)} SUBSET s`, + REWRITE_TAC[SUBSET; IN_ELIM_THM; EXTREME_POINT_OF_CONVEX_HULL]);; + +let EXTREME_POINT_OF_EMPTY = prove + (`!x. ~(x extreme_point_of {})`, + REWRITE_TAC[extreme_point_of; NOT_IN_EMPTY]);; + +let EXTREME_POINT_OF_SING = prove + (`!a x. x extreme_point_of {a} <=> x = a`, + REWRITE_TAC[extreme_point_of; IN_SING] THEN + MESON_TAC[SEGMENT_REFL; NOT_IN_EMPTY]);; + +let EXTREME_POINT_OF_TRANSLATION_EQ = prove + (`!a:real^N x s. + (a + x) extreme_point_of (IMAGE (\x. a + x) s) <=> + x extreme_point_of s`, + REWRITE_TAC[extreme_point_of] THEN GEOM_TRANSLATE_TAC[]);; + +add_translation_invariants [EXTREME_POINT_OF_TRANSLATION_EQ];; + +let EXTREME_POINT_OF_LINEAR_IMAGE = prove + (`!f:real^M->real^N. + linear f /\ (!x y. f x = f y ==> x = y) + ==> ((f x) extreme_point_of (IMAGE f s) <=> x extreme_point_of s)`, + REWRITE_TAC[GSYM FACE_OF_SING] THEN GEOM_TRANSFORM_TAC[]);; + +add_linear_invariants [EXTREME_POINT_OF_LINEAR_IMAGE];; + +let EXTREME_POINTS_OF_TRANSLATION = prove + (`!a s. {x:real^N | x extreme_point_of (IMAGE (\x. a + x) s)} = + IMAGE (\x. a + x) {x | x extreme_point_of s}`, + REPEAT GEN_TAC THEN CONV_TAC SYM_CONV THEN + MATCH_MP_TAC SURJECTIVE_IMAGE_EQ THEN + REWRITE_TAC[VECTOR_ARITH `a + x:real^N = y <=> x = y - a`; EXISTS_REFL] THEN + REWRITE_TAC[IN_ELIM_THM; EXTREME_POINT_OF_TRANSLATION_EQ]);; + +let EXTREME_POINT_OF_INTER = prove + (`!x s t. x extreme_point_of s /\ x extreme_point_of t + ==> x extreme_point_of (s INTER t)`, + REWRITE_TAC[extreme_point_of; IN_INTER] THEN MESON_TAC[]);; + +let EXTREME_POINTS_OF_LINEAR_IMAGE = prove + (`!f:real^M->real^N. + linear f /\ (!x y. f x = f y ==> x = y) + ==> {y | y extreme_point_of (IMAGE f s)} = + IMAGE f {x | x extreme_point_of s}`, + + REPEAT GEN_TAC THEN DISCH_TAC THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP OPEN_SEGMENT_LINEAR_IMAGE) THEN + MATCH_MP_TAC SUBSET_ANTISYM THEN + REWRITE_TAC[FORALL_IN_IMAGE; FORALL_IN_GSPEC; SUBSET; + extreme_point_of; IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN + ASM_SIMP_TAC[FUN_IN_IMAGE; IN_ELIM_THM; IMP_IMP; GSYM CONJ_ASSOC] THEN + ASM SET_TAC[]);; + +let EXTREME_POINT_OF_INTER_SUPPORTING_HYPERPLANE_LE = prove + (`!s a b c. (!x. x IN s ==> a dot x <= b) /\ + s INTER {x | a dot x = b} = {c} + ==> c extreme_point_of s`, + REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM FACE_OF_SING] THEN + FIRST_ASSUM(SUBST1_TAC o SYM) THEN + MATCH_MP_TAC FACE_OF_INTER_SUPPORTING_HYPERPLANE_LE_STRONG THEN + ASM_REWRITE_TAC[CONVEX_SING]);; + +let EXTREME_POINT_OF_INTER_SUPPORTING_HYPERPLANE_GE = prove + (`!s a b c. (!x. x IN s ==> a dot x >= b) /\ + s INTER {x | a dot x = b} = {c} + ==> c extreme_point_of s`, + REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM FACE_OF_SING] THEN + FIRST_ASSUM(SUBST1_TAC o SYM) THEN + MATCH_MP_TAC FACE_OF_INTER_SUPPORTING_HYPERPLANE_GE_STRONG THEN + ASM_REWRITE_TAC[CONVEX_SING]);; + +let EXPOSED_POINT_OF_INTER_SUPPORTING_HYPERPLANE_LE = prove + (`!s a b c:real^N. + (!x. x IN s ==> a dot x <= b) /\ + s INTER {x | a dot x = b} = {c} + ==> {c} exposed_face_of s`, + REPEAT STRIP_TAC THEN REWRITE_TAC[exposed_face_of] THEN CONJ_TAC THENL + [REWRITE_TAC[FACE_OF_SING] THEN + MATCH_MP_TAC EXTREME_POINT_OF_INTER_SUPPORTING_HYPERPLANE_LE; + ALL_TAC] THEN + MAP_EVERY EXISTS_TAC [`a:real^N`; `b:real`] THEN ASM SET_TAC[]);; + +let EXPOSED_POINT_OF_INTER_SUPPORTING_HYPERPLANE_GE = prove + (`!s a b c:real^N. + (!x. x IN s ==> a dot x >= b) /\ + s INTER {x | a dot x = b} = {c} + ==> {c} exposed_face_of s`, + REWRITE_TAC[real_ge] THEN REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`s:real^N->bool`; `--a:real^N`; `--b:real`; `c:real^N`] + EXPOSED_POINT_OF_INTER_SUPPORTING_HYPERPLANE_LE) THEN + ASM_REWRITE_TAC[DOT_LNEG; REAL_EQ_NEG2; REAL_LE_NEG2]);; + +let EXPOSED_POINT_OF_FURTHEST_POINT = prove + (`!s a b:real^N. + b IN s /\ (!x. x IN s ==> dist(a,x) <= dist(a,b)) + ==> {b} exposed_face_of s`, + REPEAT GEN_TAC THEN GEOM_ORIGIN_TAC `a:real^N` THEN + REWRITE_TAC[DIST_0; NORM_LE] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC EXPOSED_POINT_OF_INTER_SUPPORTING_HYPERPLANE_LE THEN + MAP_EVERY EXISTS_TAC [`b:real^N`; `(b:real^N) dot b`] THEN CONJ_TAC THENL + [X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `x:real^N`) THEN + ASM_REWRITE_TAC[]; + MATCH_MP_TAC SUBSET_ANTISYM THEN + ASM_REWRITE_TAC[IN_INTER; SING_SUBSET; IN_ELIM_THM] THEN + REWRITE_TAC[SUBSET; IN_SING; IN_INTER; IN_ELIM_THM] THEN + X_GEN_TAC `x:real^N` THEN STRIP_TAC THEN + CONV_TAC SYM_CONV THEN ASM_REWRITE_TAC[VECTOR_EQ] THEN + ASM_SIMP_TAC[GSYM REAL_LE_ANTISYM] THEN + UNDISCH_TAC `(b:real^N) dot x = b dot b`] THEN + MP_TAC(ISPEC `b - x:real^N` DOT_POS_LE) THEN + REWRITE_TAC[DOT_LSUB; DOT_RSUB; DOT_SYM] THEN REAL_ARITH_TAC);; + +let COLLINEAR_EXTREME_POINTS = prove + (`!s. collinear s + ==> FINITE {x:real^N | x extreme_point_of s} /\ + CARD {x | x extreme_point_of s} <= 2`, + REWRITE_TAC[GSYM NOT_LT; TAUT `a /\ ~b <=> ~(a ==> b)`] THEN + REWRITE_TAC[ARITH_RULE `2 < n <=> 3 <= n`] THEN REPEAT STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o MATCH_MP CHOOSE_SUBSET_STRONG) THEN + CONV_TAC(ONCE_DEPTH_CONV HAS_SIZE_CONV) THEN + REWRITE_TAC[RIGHT_AND_EXISTS_THM] THEN REWRITE_TAC[NOT_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC + [`t:real^N->bool`; `a:real^N`; `b:real^N`; `c:real^N`] THEN + REPEAT STRIP_TAC THEN FIRST_X_ASSUM SUBST_ALL_TAC THEN + SUBGOAL_THEN + `(a:real^N) extreme_point_of s /\ + b extreme_point_of s /\ c extreme_point_of s` + STRIP_ASSUME_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + SUBGOAL_THEN `(a:real^N) IN s /\ b IN s /\ c IN s` STRIP_ASSUME_TAC THENL + [ASM_MESON_TAC[extreme_point_of]; ALL_TAC] THEN + SUBGOAL_THEN `collinear {a:real^N,b,c}` MP_TAC THENL + [MATCH_MP_TAC COLLINEAR_SUBSET THEN EXISTS_TAC `s:real^N->bool` THEN + ASM SET_TAC[]; + REWRITE_TAC[COLLINEAR_BETWEEN_CASES; BETWEEN_IN_SEGMENT] THEN + ASM_SIMP_TAC[SEGMENT_CLOSED_OPEN; IN_INSERT; NOT_IN_EMPTY; IN_UNION] THEN + ASM_MESON_TAC[extreme_point_of]]);; + +let EXTREME_POINT_OF_CONIC = prove + (`!s x:real^N. + conic s /\ x extreme_point_of s ==> x = vec 0`, + REPEAT GEN_TAC THEN REWRITE_TAC[GSYM FACE_OF_SING] THEN + DISCH_THEN(MP_TAC o MATCH_MP FACE_OF_CONIC) THEN + SIMP_TAC[conic; IN_SING; VECTOR_MUL_EQ_0; REAL_SUB_0; VECTOR_ARITH + `c % x:real^N = x <=> (c - &1) % x = vec 0`] THEN + MESON_TAC[REAL_ARITH `&0 <= &0 /\ ~(&1 = &0)`]);; + +let EXTREME_POINT_OF_CONVEX_HULL_INSERT = prove + (`!s a:real^N. + FINITE s /\ ~(a IN convex hull s) + ==> a extreme_point_of (convex hull (a INSERT s))`, + REPEAT GEN_TAC THEN + ASM_CASES_TAC `(a:real^N) IN s` THEN ASM_SIMP_TAC[HULL_INC] THEN + STRIP_TAC THEN MP_TAC(ISPECL [`{a:real^N}`; `(a:real^N) INSERT s`] + FACE_OF_CONVEX_HULLS) THEN + ASM_REWRITE_TAC[FINITE_INSERT; AFFINE_HULL_SING; CONVEX_HULL_SING] THEN + REWRITE_TAC[FACE_OF_SING] THEN DISCH_THEN MATCH_MP_TAC THEN + ASM_SIMP_TAC[SET_RULE `~(a IN s) ==> a INSERT s DIFF {a} = s`] THEN + ASM SET_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* Facets. *) +(* ------------------------------------------------------------------------- *) + +parse_as_infix("facet_of",(12, "right"));; + +let facet_of = new_definition + `f facet_of s <=> f face_of s /\ ~(f = {}) /\ aff_dim f = aff_dim s - &1`;; + +let FACET_OF_EMPTY = prove + (`!s. ~(s facet_of {})`, + REWRITE_TAC[facet_of; FACE_OF_EMPTY] THEN CONV_TAC TAUT);; + +let FACET_OF_REFL = prove + (`!s. ~(s facet_of s)`, + REWRITE_TAC[facet_of; INT_ARITH `~(x:int = x - &1)`]);; + +let FACET_OF_IMP_FACE_OF = prove + (`!f s. f facet_of s ==> f face_of s`, + SIMP_TAC[facet_of]);; + +let FACET_OF_IMP_SUBSET = prove + (`!f s. f facet_of s ==> f SUBSET s`, + SIMP_TAC[FACET_OF_IMP_FACE_OF; FACE_OF_IMP_SUBSET]);; + +let FACET_OF_IMP_PROPER = prove + (`!f s. f facet_of s ==> ~(f = {}) /\ ~(f = s)`, + REWRITE_TAC[facet_of] THEN MESON_TAC[INT_ARITH `~(x - &1:int = x)`]);; + +let FACET_OF_TRANSLATION_EQ = prove + (`!a:real^N f s. + (IMAGE (\x. a + x) f) facet_of (IMAGE (\x. a + x) s) <=> f facet_of s`, + REWRITE_TAC[facet_of] THEN GEOM_TRANSLATE_TAC[]);; + +add_translation_invariants [FACET_OF_TRANSLATION_EQ];; + +let FACET_OF_LINEAR_IMAGE = prove + (`!f:real^M->real^N c s. + linear f /\ (!x y. f x = f y ==> x = y) + ==> ((IMAGE f c) facet_of (IMAGE f s) <=> c facet_of s)`, + REWRITE_TAC[facet_of] THEN GEOM_TRANSFORM_TAC[]);; + +add_linear_invariants [FACET_OF_LINEAR_IMAGE];; + +let HYPERPLANE_FACET_OF_HALFSPACE_LE = prove + (`!a:real^N b. + ~(a = vec 0) ==> {x | a dot x = b} facet_of {x | a dot x <= b}`, + SIMP_TAC[facet_of; HYPERPLANE_FACE_OF_HALFSPACE_LE; HYPERPLANE_EQ_EMPTY; + AFF_DIM_HYPERPLANE; AFF_DIM_HALFSPACE_LE]);; + +let HYPERPLANE_FACET_OF_HALFSPACE_GE = prove + (`!a:real^N b. + ~(a = vec 0) ==> {x | a dot x = b} facet_of {x | a dot x >= b}`, + SIMP_TAC[facet_of; HYPERPLANE_FACE_OF_HALFSPACE_GE; HYPERPLANE_EQ_EMPTY; + AFF_DIM_HYPERPLANE; AFF_DIM_HALFSPACE_GE]);; + +let FACET_OF_HALFSPACE_LE = prove + (`!f a:real^N b. + f facet_of {x | a dot x <= b} <=> + ~(a = vec 0) /\ f = {x | a dot x = b}`, + REPEAT GEN_TAC THEN + EQ_TAC THEN ASM_SIMP_TAC[HYPERPLANE_FACET_OF_HALFSPACE_LE] THEN + SIMP_TAC[AFF_DIM_HALFSPACE_LE; facet_of; FACE_OF_HALFSPACE_LE] THEN + REWRITE_TAC[TAUT `(p \/ q) /\ ~p /\ r <=> (~p /\ q) /\ r`] THEN + ASM_CASES_TAC `a:real^N = vec 0` THENL + [ASM_REWRITE_TAC[DOT_LZERO; SET_RULE + `{x | p} = if p then UNIV else {}`] THEN + REPEAT(COND_CASES_TAC THEN ASM_REWRITE_TAC[TAUT `~(~p /\ p)`]) THEN + TRY ASM_REAL_ARITH_TAC THEN + DISCH_THEN(CONJUNCTS_THEN2 STRIP_ASSUME_TAC MP_TAC) THEN + ASM_REWRITE_TAC[AFF_DIM_UNIV] THEN TRY INT_ARITH_TAC THEN ASM SET_TAC[]; + DISCH_THEN(CONJUNCTS_THEN2 STRIP_ASSUME_TAC MP_TAC) THEN + ASM_REWRITE_TAC[AFF_DIM_HALFSPACE_LE] THEN INT_ARITH_TAC]);; + +let FACET_OF_HALFSPACE_GE = prove + (`!f a:real^N b. + f facet_of {x | a dot x >= b} <=> + ~(a = vec 0) /\ f = {x | a dot x = b}`, + REPEAT GEN_TAC THEN + MP_TAC(ISPECL [`f:real^N->bool`; `--a:real^N`; `--b:real`] + FACET_OF_HALFSPACE_LE) THEN + SIMP_TAC[DOT_LNEG; REAL_LE_NEG2; REAL_EQ_NEG2; VECTOR_NEG_EQ_0; real_ge]);; + +(* ------------------------------------------------------------------------- *) +(* Edges, i.e. faces of affine dimension 1. *) +(* ------------------------------------------------------------------------- *) + +parse_as_infix("edge_of",(12, "right"));; + +let edge_of = new_definition + `e edge_of s <=> e face_of s /\ aff_dim e = &1`;; + +let EDGE_OF_TRANSLATION_EQ = prove + (`!a:real^N f s. + (IMAGE (\x. a + x) f) edge_of (IMAGE (\x. a + x) s) <=> f edge_of s`, + REWRITE_TAC[edge_of] THEN GEOM_TRANSLATE_TAC[]);; + +add_translation_invariants [EDGE_OF_TRANSLATION_EQ];; + +let EDGE_OF_LINEAR_IMAGE = prove + (`!f:real^M->real^N c s. + linear f /\ (!x y. f x = f y ==> x = y) + ==> ((IMAGE f c) edge_of (IMAGE f s) <=> c edge_of s)`, + REWRITE_TAC[edge_of] THEN GEOM_TRANSFORM_TAC[]);; + +add_linear_invariants [EDGE_OF_LINEAR_IMAGE];; + +let EDGE_OF_IMP_SUBSET = prove + (`!s t. s edge_of t ==> s SUBSET t`, + SIMP_TAC[edge_of; face_of]);; + +(* ------------------------------------------------------------------------- *) +(* Existence of extreme points. *) +(* ------------------------------------------------------------------------- *) + +let DIFFERENT_NORM_3_COLLINEAR_POINTS = prove + (`!a b x:real^N. + ~(x IN segment(a,b) /\ norm(a) = norm(b) /\ norm(x) = norm(b))`, + REPEAT GEN_TAC THEN ASM_CASES_TAC `a:real^N = b` THEN + ASM_SIMP_TAC[SEGMENT_REFL; NOT_IN_EMPTY; OPEN_SEGMENT_ALT] THEN + REWRITE_TAC[IN_ELIM_THM] THEN DISCH_THEN + (CONJUNCTS_THEN2 (X_CHOOSE_THEN `u:real` STRIP_ASSUME_TAC) MP_TAC) THEN + ASM_REWRITE_TAC[NORM_EQ] THEN REWRITE_TAC[VECTOR_ARITH + `(x + y:real^N) dot (x + y) = x dot x + &2 * x dot y + y dot y`] THEN + REWRITE_TAC[DOT_LMUL; DOT_RMUL] THEN + DISCH_THEN(CONJUNCTS_THEN2 (ASSUME_TAC o SYM) MP_TAC) THEN + UNDISCH_TAC `~(a:real^N = b)` THEN + GEN_REWRITE_TAC (LAND_CONV o RAND_CONV) [GSYM VECTOR_SUB_EQ] THEN + REWRITE_TAC[GSYM DOT_EQ_0; VECTOR_ARITH + `(a - b:real^N) dot (a - b) = a dot a + b dot b - &2 * a dot b`] THEN + ASM_REWRITE_TAC[REAL_RING `a + a - &2 * ab = &0 <=> ab = a`] THEN + SIMP_TAC[REAL_RING + `(&1 - u) * (&1 - u) * a + &2 * (&1 - u) * u * x + u * u * a = a <=> + x = a \/ u = &0 \/ u = &1`] THEN + ASM_REAL_ARITH_TAC);; + +let EXTREME_POINT_EXISTS_CONVEX = prove + (`!s:real^N->bool. + compact s /\ convex s /\ ~(s = {}) ==> ?x. x extreme_point_of s`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`s:real^N->bool`; `vec 0:real^N`] DISTANCE_ATTAINS_SUP) THEN + ASM_REWRITE_TAC[DIST_0; extreme_point_of] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `x:real^N` THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + MAP_EVERY X_GEN_TAC [`a:real^N`; `b:real^N`] THEN + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`a:real^N`; `b:real^N`; `x:real^N`] + DIFFERENT_NORM_3_COLLINEAR_POINTS) THEN + ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC(REAL_ARITH + `a <= x /\ b <= x /\ (a < x ==> x < x) /\ (b < x ==> x < x) + ==> a = b /\ x = b`) THEN + ASM_SIMP_TAC[] THEN + UNDISCH_TAC `(x:real^N) IN segment(a,b)` THEN + ASM_CASES_TAC `a:real^N = b` THEN + ASM_REWRITE_TAC[SEGMENT_REFL; NOT_IN_EMPTY] THEN + ASM_SIMP_TAC[OPEN_SEGMENT_ALT; IN_ELIM_THM] THEN + DISCH_THEN(X_CHOOSE_THEN `u:real` STRIP_ASSUME_TAC) THEN + CONJ_TAC THEN DISCH_TAC THEN + FIRST_X_ASSUM(fun th -> GEN_REWRITE_TAC (LAND_CONV o RAND_CONV) [th]) THEN + MATCH_MP_TAC NORM_TRIANGLE_LT THEN REWRITE_TAC[NORM_MUL] THEN + ASM_SIMP_TAC[REAL_ARITH + `&0 < u /\ u < &1 ==> abs u = u /\ abs(&1 - u) = &1 - u`] THEN + SUBST1_TAC(REAL_RING `norm(x:real^N) = (&1 - u) * norm x + u * norm x`) THENL + [MATCH_MP_TAC REAL_LTE_ADD2; MATCH_MP_TAC REAL_LET_ADD2] THEN + ASM_SIMP_TAC[REAL_LE_LMUL_EQ; REAL_LT_LMUL_EQ; REAL_SUB_LT]);; + +(* ------------------------------------------------------------------------- *) +(* Krein-Milman, the weaker form as in more general spaces first. *) +(* ------------------------------------------------------------------------- *) + +let KREIN_MILMAN = prove + (`!s:real^N->bool. + convex s /\ compact s + ==> s = closure(convex hull {x | x extreme_point_of s})`, + GEN_TAC THEN + ASM_CASES_TAC `s:real^N->bool = {}` THENL + [ASM_REWRITE_TAC[extreme_point_of; NOT_IN_EMPTY; EMPTY_GSPEC] THEN + REWRITE_TAC[CONVEX_HULL_EMPTY; CLOSURE_EMPTY]; + ALL_TAC] THEN + STRIP_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL + [ALL_TAC; + MATCH_MP_TAC CLOSURE_MINIMAL THEN ASM_SIMP_TAC[COMPACT_IMP_CLOSED] THEN + MATCH_MP_TAC HULL_MINIMAL THEN + ASM_SIMP_TAC[SUBSET; IN_ELIM_THM; extreme_point_of]] THEN + REWRITE_TAC[SUBSET; IN_ELIM_THM] THEN + X_GEN_TAC `u:real^N` THEN DISCH_TAC THEN + MATCH_MP_TAC(TAUT `(~p ==> F) ==> p`) THEN DISCH_TAC THEN + MP_TAC(ISPECL [`closure(convex hull {x:real^N | x extreme_point_of s})`; + `u:real^N`] SEPARATING_HYPERPLANE_CLOSED_POINT) THEN + ASM_SIMP_TAC[CONVEX_CLOSURE; CLOSED_CLOSURE; CONVEX_CONVEX_HULL] THEN + REWRITE_TAC[NOT_EXISTS_THM; TAUT `~(a /\ b) <=> a ==> ~b`] THEN + MAP_EVERY X_GEN_TAC [`a:real^N`; `b:real`] THEN REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`\x:real^N. a dot x`; `s:real^N->bool`] + CONTINUOUS_ATTAINS_INF) THEN + ASM_REWRITE_TAC[CONTINUOUS_ON_LIFT_DOT] THEN + DISCH_THEN(X_CHOOSE_THEN `m:real^N` STRIP_ASSUME_TAC) THEN + ABBREV_TAC `t = {x:real^N | x IN s /\ a dot x = a dot m}` THEN + SUBGOAL_THEN `?x:real^N. x extreme_point_of t` (X_CHOOSE_TAC `v:real^N`) + THENL + [MATCH_MP_TAC EXTREME_POINT_EXISTS_CONVEX THEN + EXPAND_TAC "t" THEN REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; IN_ELIM_THM] THEN + REWRITE_TAC[SET_RULE `{x | x IN s /\ P x} = s INTER {x | P x}`] THEN + ASM_SIMP_TAC[CONVEX_INTER; CONVEX_HYPERPLANE; COMPACT_INTER_CLOSED; + CLOSED_HYPERPLANE] THEN + ASM SET_TAC[]; + ALL_TAC] THEN + SUBGOAL_THEN `(v:real^N) extreme_point_of s` ASSUME_TAC THENL + [REWRITE_TAC[GSYM FACE_OF_SING] THEN MATCH_MP_TAC FACE_OF_TRANS THEN + EXISTS_TAC `t:real^N->bool` THEN ASM_SIMP_TAC[FACE_OF_SING] THEN + EXPAND_TAC "t" THEN + REWRITE_TAC[SET_RULE `{x | x IN s /\ P x} = s INTER {x | P x}`] THEN + MATCH_MP_TAC FACE_OF_INTER_SUPPORTING_HYPERPLANE_GE THEN + ASM_SIMP_TAC[real_ge]; + SUBGOAL_THEN `(a:real^N) dot v > b` MP_TAC THENL + [FIRST_X_ASSUM MATCH_MP_TAC THEN + MATCH_MP_TAC(REWRITE_RULE[SUBSET] CLOSURE_SUBSET) THEN + MATCH_MP_TAC HULL_INC THEN ASM_REWRITE_TAC[IN_ELIM_THM]; + ALL_TAC] THEN + REWRITE_TAC[real_gt; REAL_NOT_LT] THEN + MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC `(a:real^N) dot u` THEN + ASM_SIMP_TAC[REAL_LT_IMP_LE] THEN + MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC `(a:real^N) dot m` THEN + ASM_SIMP_TAC[] THEN + UNDISCH_TAC `(v:real^N) extreme_point_of t` THEN EXPAND_TAC "t" THEN + SIMP_TAC[extreme_point_of; IN_ELIM_THM; REAL_LE_REFL]]);; + +(* ------------------------------------------------------------------------- *) +(* Now the sharper form. *) +(* ------------------------------------------------------------------------- *) + +let KREIN_MILMAN_MINKOWSKI = prove + (`!s:real^N->bool. + convex s /\ compact s + ==> s = convex hull {x | x extreme_point_of s}`, + SUBGOAL_THEN + `!s:real^N->bool. + convex s /\ compact s /\ (vec 0) IN s + ==> (vec 0) IN convex hull {x | x extreme_point_of s}` + ASSUME_TAC THENL + [GEN_TAC THEN WF_INDUCT_TAC `dim(s:real^N->bool)` THEN STRIP_TAC THEN + ASM_CASES_TAC `(vec 0:real^N) IN relative_interior s` THENL + [MP_TAC(ISPEC `s:real^N->bool` KREIN_MILMAN) THEN + ASM_REWRITE_TAC[] THEN DISCH_TAC THEN + UNDISCH_TAC `(vec 0:real^N) IN relative_interior s` THEN + FIRST_X_ASSUM(fun th -> GEN_REWRITE_TAC + (LAND_CONV o RAND_CONV o RAND_CONV) [th]) THEN + SIMP_TAC[CONVEX_RELATIVE_INTERIOR_CLOSURE; CONVEX_CONVEX_HULL] THEN + MESON_TAC[RELATIVE_INTERIOR_SUBSET; SUBSET]; + ALL_TAC] THEN + SUBGOAL_THEN `~(relative_interior(s:real^N->bool) = {})` ASSUME_TAC THENL + [ASM_SIMP_TAC[RELATIVE_INTERIOR_EQ_EMPTY] THEN ASM SET_TAC[]; + ALL_TAC] THEN + MP_TAC(ISPECL [`s:real^N->bool`; `vec 0:real^N`] + SUPPORTING_HYPERPLANE_RELATIVE_BOUNDARY) THEN + ASM_REWRITE_TAC[DOT_RZERO] THEN + DISCH_THEN(X_CHOOSE_THEN `a:real^N` STRIP_ASSUME_TAC) THEN + MP_TAC(ISPECL [`s:real^N->bool`; `a:real^N`; `&0`] + FACE_OF_INTER_SUPPORTING_HYPERPLANE_GE) THEN + ASM_REWRITE_TAC[real_ge] THEN DISCH_TAC THEN + SUBGOAL_THEN + `(vec 0:real^N) IN convex hull + {x | x extreme_point_of (s INTER {x | a dot x = &0})}` + MP_TAC THENL + [ALL_TAC; + MATCH_MP_TAC(SET_RULE `s SUBSET t ==> x IN s ==> x IN t`) THEN + MATCH_MP_TAC HULL_MONO THEN REWRITE_TAC[SUBSET] THEN + GEN_TAC THEN REWRITE_TAC[IN_ELIM_THM; GSYM FACE_OF_SING] THEN + ASM_MESON_TAC[FACE_OF_TRANS]] THEN + RULE_ASSUM_TAC(REWRITE_RULE[IMP_IMP]) THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_SIMP_TAC[CONVEX_INTER; CONVEX_HYPERPLANE; COMPACT_INTER_CLOSED; + CLOSED_HYPERPLANE; IN_INTER; IN_ELIM_THM; DOT_RZERO] THEN + REWRITE_TAC[GSYM NOT_LE] THEN DISCH_TAC THEN + MP_TAC(ISPECL + [`s INTER {x:real^N | a dot x = &0}`; `s:real^N->bool`] + DIM_EQ_SPAN) THEN + ASM_REWRITE_TAC[INTER_SUBSET; EXTENSION; NOT_FORALL_THM] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `c:real^N` THEN DISCH_TAC THEN + MATCH_MP_TAC(TAUT `b /\ ~a ==> ~(a <=> b)`) THEN CONJ_TAC THENL + [ASM_MESON_TAC[SUBSET; SPAN_INC; RELATIVE_INTERIOR_SUBSET]; ALL_TAC] THEN + SUBGOAL_THEN + `!x:real^N. x IN span (s INTER {x | a dot x = &0}) ==> a dot x = &0` + (fun th -> ASM_MESON_TAC[th; REAL_LT_REFL]) THEN + MATCH_MP_TAC SPAN_INDUCT THEN SIMP_TAC[IN_INTER; IN_ELIM_THM] THEN + REWRITE_TAC[subspace; DOT_RZERO; DOT_RADD; DOT_RMUL; IN_ELIM_THM] THEN + CONV_TAC REAL_RING; + ALL_TAC] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL + [REWRITE_TAC[SUBSET] THEN X_GEN_TAC `a:real^N` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `IMAGE (\x:real^N. --a + x) s`) THEN + ASM_SIMP_TAC[CONVEX_TRANSLATION_EQ; COMPACT_TRANSLATION_EQ] THEN + REWRITE_TAC[IN_IMAGE; VECTOR_ARITH `vec 0:real^N = --a + x <=> x = a`] THEN + ASM_REWRITE_TAC[UNWIND_THM2] THEN + REWRITE_TAC[EXTREME_POINTS_OF_TRANSLATION; CONVEX_HULL_TRANSLATION] THEN + REWRITE_TAC[IN_IMAGE; VECTOR_ARITH `vec 0:real^N = --a + x <=> x = a`] THEN + REWRITE_TAC[UNWIND_THM2]; + MATCH_MP_TAC HULL_MINIMAL THEN + ASM_SIMP_TAC[SUBSET; extreme_point_of; IN_ELIM_THM]]);; + +(* ------------------------------------------------------------------------- *) +(* Applying it to convex hulls of explicitly indicated finite sets. *) +(* ------------------------------------------------------------------------- *) + +let KREIN_MILMAN_POLYTOPE = prove + (`!s. FINITE s + ==> convex hull s = + convex hull {x | x extreme_point_of (convex hull s)}`, + SIMP_TAC[KREIN_MILMAN_MINKOWSKI; CONVEX_CONVEX_HULL; + COMPACT_CONVEX_HULL; FINITE_IMP_COMPACT]);; + +let EXTREME_POINTS_OF_CONVEX_HULL_EQ = prove + (`!s:real^N->bool. + compact s /\ + (!t. t PSUBSET s ==> ~(convex hull t = convex hull s)) + ==> {x | x extreme_point_of (convex hull s)} = s`, + REPEAT STRIP_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC + `{x:real^N | x extreme_point_of (convex hull s)}`) THEN + MATCH_MP_TAC(SET_RULE + `P /\ t SUBSET s ==> (t PSUBSET s ==> ~P) ==> t = s`) THEN + REWRITE_TAC[EXTREME_POINTS_OF_CONVEX_HULL] THEN + CONV_TAC SYM_CONV THEN MATCH_MP_TAC KREIN_MILMAN_MINKOWSKI THEN + ASM_SIMP_TAC[CONVEX_CONVEX_HULL; COMPACT_CONVEX_HULL]);; + +let EXTREME_POINT_OF_CONVEX_HULL_EQ = prove + (`!s x:real^N. + compact s /\ + (!t. t PSUBSET s ==> ~(convex hull t = convex hull s)) + ==> (x extreme_point_of (convex hull s) <=> x IN s)`, + REPEAT GEN_TAC THEN + DISCH_THEN(MP_TAC o MATCH_MP EXTREME_POINTS_OF_CONVEX_HULL_EQ) THEN + SET_TAC[]);; + +let EXTREME_POINT_OF_CONVEX_HULL_CONVEX_INDEPENDENT = prove + (`!s x:real^N. + compact s /\ + (!a. a IN s ==> ~(a IN convex hull (s DELETE a))) + ==> (x extreme_point_of (convex hull s) <=> x IN s)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC EXTREME_POINT_OF_CONVEX_HULL_EQ THEN + ASM_REWRITE_TAC[PSUBSET_MEMBER] THEN X_GEN_TAC `t:real^N->bool` THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC (X_CHOOSE_TAC `a:real^N`)) THEN + DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC `a:real^N`) THEN + ASM_REWRITE_TAC[] THEN + SUBGOAL_THEN `s SUBSET convex hull (s DELETE (a:real^N))` MP_TAC THENL + [ALL_TAC; ASM SET_TAC[]] THEN + MATCH_MP_TAC SUBSET_TRANS THEN EXISTS_TAC `convex hull t:real^N->bool` THEN + CONJ_TAC THENL + [ASM_REWRITE_TAC[HULL_SUBSET]; + MATCH_MP_TAC HULL_MONO THEN ASM SET_TAC[]]);; + +let EXTREME_POINT_OF_CONVEX_HULL_AFFINE_INDEPENDENT = prove + (`!s x. ~affine_dependent s + ==> (x extreme_point_of (convex hull s) <=> x IN s)`, + REPEAT STRIP_TAC THEN + MATCH_MP_TAC EXTREME_POINT_OF_CONVEX_HULL_CONVEX_INDEPENDENT THEN + ASM_SIMP_TAC[AFFINE_INDEPENDENT_IMP_FINITE; FINITE_IMP_COMPACT] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE RAND_CONV [affine_dependent]) THEN + MESON_TAC[SUBSET; CONVEX_HULL_SUBSET_AFFINE_HULL]);; + +let EXTREME_POINT_OF_CONVEX_HULL_2 = prove + (`!a b x. x extreme_point_of (convex hull {a,b}) <=> x = a \/ x = b`, + REWRITE_TAC[SET_RULE `x = a \/ x = b <=> x IN {a,b}`] THEN + SIMP_TAC[EXTREME_POINT_OF_CONVEX_HULL_AFFINE_INDEPENDENT; + AFFINE_INDEPENDENT_2]);; + +let EXTREME_POINT_OF_SEGMENT = prove + (`!a b x:real^N. x extreme_point_of segment[a,b] <=> x = a \/ x = b`, + REWRITE_TAC[SEGMENT_CONVEX_HULL; EXTREME_POINT_OF_CONVEX_HULL_2]);; + +let FACE_OF_CONVEX_HULL_SUBSET = prove + (`!s t:real^N->bool. + compact s /\ t face_of (convex hull s) + ==> ?s'. s' SUBSET s /\ t = convex hull s'`, + REPEAT STRIP_TAC THEN EXISTS_TAC `{x:real^N | x extreme_point_of t}` THEN + REWRITE_TAC[SUBSET; IN_ELIM_THM] THEN CONJ_TAC THENL + [X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN + MATCH_MP_TAC EXTREME_POINT_OF_CONVEX_HULL THEN + ASM_MESON_TAC[FACE_OF_SING; FACE_OF_TRANS]; + MATCH_MP_TAC KREIN_MILMAN_MINKOWSKI THEN + ASM_MESON_TAC[FACE_OF_IMP_CONVEX; FACE_OF_IMP_COMPACT; + COMPACT_CONVEX_HULL; CONVEX_CONVEX_HULL]]);; + +let FACE_OF_CONVEX_HULL_AFFINE_INDEPENDENT = prove + (`!s t:real^N->bool. + ~affine_dependent s + ==> (t face_of (convex hull s) <=> + ?c. c SUBSET s /\ t = convex hull c)`, + REPEAT STRIP_TAC THEN EQ_TAC THENL + [ASM_MESON_TAC[AFFINE_INDEPENDENT_IMP_FINITE; FINITE_IMP_COMPACT; + FACE_OF_CONVEX_HULL_SUBSET]; + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC FACE_OF_CONVEX_HULLS THEN + ASM_SIMP_TAC[AFFINE_INDEPENDENT_IMP_FINITE] THEN + MATCH_MP_TAC(SET_RULE ` + !t. u SUBSET t /\ DISJOINT s t ==> DISJOINT s u`) THEN + EXISTS_TAC `affine hull (s DIFF c:real^N->bool)` THEN + REWRITE_TAC[CONVEX_HULL_SUBSET_AFFINE_HULL] THEN + MATCH_MP_TAC DISJOINT_AFFINE_HULL THEN + EXISTS_TAC `s:real^N->bool` THEN ASM SET_TAC[]]);; + +let FACET_OF_CONVEX_HULL_AFFINE_INDEPENDENT = prove + (`!s t:real^N->bool. + ~affine_dependent s + ==> (t facet_of (convex hull s) <=> + ~(t = {}) /\ ?u. u IN s /\ t = convex hull (s DELETE u))`, + REPEAT STRIP_TAC THEN + ASM_SIMP_TAC[facet_of; FACE_OF_CONVEX_HULL_AFFINE_INDEPENDENT] THEN + REWRITE_TAC[AFF_DIM_CONVEX_HULL] THEN EQ_TAC THENL + [DISCH_THEN(CONJUNCTS_THEN2 MP_TAC STRIP_ASSUME_TAC) THEN + DISCH_THEN(X_CHOOSE_THEN `c:real^N->bool` MP_TAC) THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC SUBST_ALL_TAC) THEN + UNDISCH_TAC + `aff_dim(convex hull c:real^N->bool) = aff_dim(s:real^N->bool) - &1` THEN + SUBGOAL_THEN `~affine_dependent(c:real^N->bool)` ASSUME_TAC THENL + [ASM_MESON_TAC[AFFINE_INDEPENDENT_SUBSET]; + ASM_SIMP_TAC[AFF_DIM_AFFINE_INDEPENDENT; AFF_DIM_CONVEX_HULL]] THEN + REWRITE_TAC[INT_ARITH `x - &1:int = y - &1 - &1 <=> y = x + &1`] THEN + REWRITE_TAC[INT_OF_NUM_ADD; INT_OF_NUM_EQ] THEN DISCH_TAC THEN + SUBGOAL_THEN `(s DIFF c:real^N->bool) HAS_SIZE 1` MP_TAC THENL + [ASM_SIMP_TAC[HAS_SIZE; FINITE_DIFF; CARD_DIFF; + AFFINE_INDEPENDENT_IMP_FINITE] THEN ARITH_TAC; + CONV_TAC(LAND_CONV HAS_SIZE_CONV) THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `u:real^N` THEN + DISCH_THEN(MP_TAC o MATCH_MP (SET_RULE + `s DIFF t = {a} ==> t SUBSET s ==> s = a INSERT t`)) THEN + ASM_REWRITE_TAC[] THEN DISCH_THEN SUBST_ALL_TAC THEN + UNDISCH_TAC `CARD((u:real^N) INSERT c) = CARD c + 1` THEN + ASM_SIMP_TAC[CARD_CLAUSES; AFFINE_INDEPENDENT_IMP_FINITE] THEN + COND_CASES_TAC THENL [ARITH_TAC; DISCH_THEN(K ALL_TAC)] THEN + CONJ_TAC THENL [ALL_TAC; AP_TERM_TAC] THEN ASM SET_TAC[]]; + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `u:real^N` MP_TAC) THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC SUBST1_TAC) THEN + CONJ_TAC THENL [MESON_TAC[DELETE_SUBSET]; ALL_TAC] THEN + ASM_SIMP_TAC[AFF_DIM_CONVEX_HULL] THEN + SUBGOAL_THEN `~affine_dependent(s DELETE (u:real^N))` ASSUME_TAC THENL + [ASM_MESON_TAC[AFFINE_INDEPENDENT_SUBSET; DELETE_SUBSET]; + ASM_SIMP_TAC[AFF_DIM_AFFINE_INDEPENDENT]] THEN + REWRITE_TAC[INT_ARITH `x - &1:int = y - &1 - &1 <=> y = x + &1`] THEN + REWRITE_TAC[INT_OF_NUM_ADD; INT_OF_NUM_EQ] THEN + ASM_SIMP_TAC[CARD_DELETE; AFFINE_INDEPENDENT_IMP_FINITE] THEN + MATCH_MP_TAC(ARITH_RULE `~(s = 0) ==> s = s - 1 + 1`) THEN + ASM_SIMP_TAC[CARD_EQ_0; AFFINE_INDEPENDENT_IMP_FINITE] THEN + ASM SET_TAC[]]);; + +let FACET_OF_CONVEX_HULL_AFFINE_INDEPENDENT_ALT = prove + (`!s t:real^N->bool. + ~affine_dependent s + ==> (t facet_of (convex hull s) <=> + 2 <= CARD s /\ ?u. u IN s /\ t = convex hull (s DELETE u))`, + REPEAT STRIP_TAC THEN + ASM_SIMP_TAC[FACET_OF_CONVEX_HULL_AFFINE_INDEPENDENT] THEN + REWRITE_TAC[RIGHT_AND_EXISTS_THM] THEN AP_TERM_TAC THEN + GEN_REWRITE_TAC I [FUN_EQ_THM] THEN + X_GEN_TAC `u:real^N` THEN + ASM_CASES_TAC `t = convex hull (s DELETE (u:real^N))` THEN + ASM_REWRITE_TAC[CONVEX_HULL_EQ_EMPTY] THEN + ASM_CASES_TAC `(u:real^N) IN s` THEN ASM_REWRITE_TAC[] THEN + SUBGOAL_THEN `CARD s = 1 + CARD(s DELETE (u:real^N))` SUBST1_TAC THENL + [ASM_SIMP_TAC[CARD_DELETE; AFFINE_INDEPENDENT_IMP_FINITE] THEN + MATCH_MP_TAC(ARITH_RULE `~(s = 0) ==> s = 1 + s - 1`) THEN + ASM_SIMP_TAC[CARD_EQ_0; AFFINE_INDEPENDENT_IMP_FINITE] THEN + ASM SET_TAC[]; + REWRITE_TAC[ARITH_RULE `2 <= 1 + x <=> ~(x = 0)`] THEN + ASM_SIMP_TAC[CARD_EQ_0; AFFINE_INDEPENDENT_IMP_FINITE; FINITE_DELETE]]);; + +let SEGMENT_FACE_OF = prove + (`!s a b:real^N. + segment[a,b] face_of s ==> a extreme_point_of s /\ b extreme_point_of s`, + REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM FACE_OF_SING] THEN + MATCH_MP_TAC FACE_OF_TRANS THEN EXISTS_TAC `segment[a:real^N,b]` THEN + ASM_REWRITE_TAC[] THEN REWRITE_TAC[FACE_OF_SING; EXTREME_POINT_OF_SEGMENT]);; + +let SEGMENT_EDGE_OF = prove + (`!s a b:real^N. + segment[a,b] edge_of s + ==> ~(a = b) /\ a extreme_point_of s /\ b extreme_point_of s`, + REPEAT GEN_TAC THEN DISCH_TAC THEN CONJ_TAC THENL + [ALL_TAC; ASM_MESON_TAC[edge_of; SEGMENT_FACE_OF]] THEN + POP_ASSUM MP_TAC THEN ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN + SIMP_TAC[SEGMENT_REFL; edge_of; AFF_DIM_SING] THEN INT_ARITH_TAC);; + +let COMPACT_CONVEX_COLLINEAR_SEGMENT = prove + (`!s:real^N->bool. + ~(s = {}) /\ compact s /\ convex s /\ collinear s + ==> ?a b. s = segment[a,b]`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPEC `s:real^N->bool` KREIN_MILMAN_MINKOWSKI) THEN + FIRST_ASSUM(MP_TAC o MATCH_MP COLLINEAR_EXTREME_POINTS) THEN + REWRITE_TAC[ARITH_RULE `n <= 2 <=> n = 0 \/ n = 1 \/ n = 2`] THEN + REWRITE_TAC[LEFT_OR_DISTRIB; GSYM HAS_SIZE] THEN + CONV_TAC(ONCE_DEPTH_CONV HAS_SIZE_CONV) THEN + STRIP_TAC THEN ASM_REWRITE_TAC[CONVEX_HULL_EMPTY; SEGMENT_CONVEX_HULL] THEN + DISCH_THEN SUBST1_TAC THEN MESON_TAC[SET_RULE `{a} = {a,a}`]);; + +let KREIN_MILMAN_RELATIVE_FRONTIER = prove + (`!s:real^N->bool. + convex s /\ compact s /\ ~(?a. s = {a}) + ==> s = convex hull (s DIFF relative_interior s)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL + [MATCH_MP_TAC SUBSET_TRANS THEN + EXISTS_TAC `convex hull {x:real^N | x extreme_point_of s}` THEN + CONJ_TAC THENL + [ASM_SIMP_TAC[GSYM KREIN_MILMAN_MINKOWSKI; SUBSET_REFL]; + MATCH_MP_TAC HULL_MONO THEN SIMP_TAC[SUBSET; IN_ELIM_THM; IN_DIFF] THEN + ASM_MESON_TAC[EXTREME_POINT_NOT_IN_RELATIVE_INTERIOR; extreme_point_of]]; + MATCH_MP_TAC SUBSET_TRANS THEN + EXISTS_TAC `convex hull s:real^N->bool` THEN CONJ_TAC THENL + [MATCH_MP_TAC HULL_MONO THEN SET_TAC[]; + ASM_SIMP_TAC[HULL_P; SUBSET_REFL]]]);; + +let KREIN_MILMAN_FRONTIER = prove + (`!s:real^N->bool. + convex s /\ compact s + ==> s = convex hull (frontier s)`, + REPEAT STRIP_TAC THEN + ASM_SIMP_TAC[frontier; COMPACT_IMP_CLOSED; CLOSURE_CLOSED] THEN + MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL + [MATCH_MP_TAC SUBSET_TRANS THEN + EXISTS_TAC `convex hull {x:real^N | x extreme_point_of s}` THEN + CONJ_TAC THENL + [ASM_SIMP_TAC[GSYM KREIN_MILMAN_MINKOWSKI; SUBSET_REFL]; + MATCH_MP_TAC HULL_MONO THEN SIMP_TAC[SUBSET; IN_ELIM_THM; IN_DIFF] THEN + ASM_MESON_TAC[EXTREME_POINT_NOT_IN_INTERIOR; extreme_point_of]]; + MATCH_MP_TAC SUBSET_TRANS THEN + EXISTS_TAC `convex hull s:real^N->bool` THEN CONJ_TAC THENL + [MATCH_MP_TAC HULL_MONO THEN SET_TAC[]; + ASM_SIMP_TAC[HULL_P; SUBSET_REFL]]]);; + +let EXTREME_POINT_OF_CONVEX_HULL_INSERT_EQ = prove + (`!s a x:real^N. + FINITE s /\ ~(a IN affine hull s) + ==> (x extreme_point_of (convex hull (a INSERT s)) <=> + x = a \/ x extreme_point_of (convex hull s))`, + REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[GSYM AFFINE_HULL_CONVEX_HULL] THEN + STRIP_TAC THEN ONCE_REWRITE_TAC[SET_RULE `a INSERT s = {a} UNION s`] THEN + ONCE_REWRITE_TAC[HULL_UNION_RIGHT] THEN + MP_TAC(ISPEC `convex hull s:real^N->bool` KREIN_MILMAN_MINKOWSKI) THEN + ANTS_TAC THENL + [ASM_SIMP_TAC[CONVEX_CONVEX_HULL; COMPACT_CONVEX_HULL; FINITE_IMP_COMPACT]; + ALL_TAC] THEN + FIRST_X_ASSUM(MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] FINITE_SUBSET)) THEN + DISCH_THEN(MP_TAC o SPEC + `{x:real^N | x extreme_point_of convex hull s}`) THEN + REWRITE_TAC[EXTREME_POINTS_OF_CONVEX_HULL] THEN + ABBREV_TAC `v = {x:real^N | x extreme_point_of (convex hull s)}` THEN + DISCH_TAC THEN DISCH_THEN SUBST_ALL_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE (RAND_CONV o RAND_CONV) + [AFFINE_HULL_CONVEX_HULL]) THEN + ASM_CASES_TAC `(a:real^N) IN v` THEN ASM_SIMP_TAC[HULL_INC] THEN + STRIP_TAC THEN REWRITE_TAC[GSYM HULL_UNION_RIGHT] THEN + REWRITE_TAC[SET_RULE `{a} UNION s = a INSERT s`] THEN EQ_TAC THENL + [DISCH_THEN(MP_TAC o MATCH_MP EXTREME_POINT_OF_CONVEX_HULL) THEN + ASM SET_TAC[]; + STRIP_TAC THENL + [ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC EXTREME_POINT_OF_CONVEX_HULL_INSERT THEN + ASM_MESON_TAC[CONVEX_HULL_SUBSET_AFFINE_HULL; SUBSET]; + REWRITE_TAC[GSYM FACE_OF_SING] THEN + MATCH_MP_TAC FACE_OF_TRANS THEN + EXISTS_TAC `convex hull v:real^N->bool` THEN + ASM_REWRITE_TAC[FACE_OF_SING] THEN + MATCH_MP_TAC FACE_OF_CONVEX_HULLS THEN + ASM_SIMP_TAC[FINITE_INSERT; AFFINE_HULL_SING; CONVEX_HULL_SING; + SET_RULE `~(a IN s) ==> a INSERT s DIFF s = {a}`] THEN + ASM SET_TAC[]]]);; + +let FACE_OF_CONVEX_HULL_INSERT_EQ = prove + (`!f s a:real^N. + FINITE s /\ ~(a IN affine hull s) + ==> (f face_of (convex hull (a INSERT s)) <=> + f face_of (convex hull s) \/ + ?f'. f' face_of (convex hull s) /\ + f = convex hull (a INSERT f'))`, + let lemma = prove + (`!a b c p:real^N u v w x. + x % p = u % a + v % b + w % c + ==> !s. u + v + w = x /\ ~(x = &0) /\ affine s /\ + a IN s /\ b IN s /\ c IN s + ==> p IN s`, + REPEAT STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o AP_TERM `(%) (inv x):real^N->real^N`) THEN + ASM_SIMP_TAC[VECTOR_MUL_ASSOC; REAL_MUL_LINV; VECTOR_MUL_LID] THEN + DISCH_THEN SUBST1_TAC THEN + REWRITE_TAC[VECTOR_ADD_LDISTRIB; VECTOR_MUL_ASSOC] THEN + MATCH_MP_TAC(SET_RULE `!t. x IN t /\ t SUBSET s ==> x IN s`) THEN + EXISTS_TAC `affine hull {a:real^N,b,c}` THEN + ASM_SIMP_TAC[HULL_MINIMAL; INSERT_SUBSET; EMPTY_SUBSET] THEN + REWRITE_TAC[AFFINE_HULL_3; IN_ELIM_THM] THEN MAP_EVERY EXISTS_TAC + [`inv x * u:real`; `inv x * v:real`; `inv x * w:real`] THEN + REWRITE_TAC[] THEN UNDISCH_TAC `u + v + w:real = x` THEN + UNDISCH_TAC `~(x = &0)` THEN CONV_TAC REAL_FIELD) in + REPEAT STRIP_TAC THEN EQ_TAC THENL + [DISCH_TAC THEN FIRST_ASSUM(MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ_ALT] + FACE_OF_CONVEX_HULL_SUBSET)) THEN + ASM_SIMP_TAC[COMPACT_INSERT; FINITE_IMP_COMPACT] THEN + DISCH_THEN(X_CHOOSE_THEN `t:real^N->bool` STRIP_ASSUME_TAC) THEN + FIRST_X_ASSUM SUBST_ALL_TAC THEN ASM_CASES_TAC `(a:real^N) IN t` THENL + [ALL_TAC; + DISJ1_TAC THEN MATCH_MP_TAC FACE_OF_SUBSET THEN + EXISTS_TAC `convex hull ((a:real^N) INSERT s)` THEN + ASM_REWRITE_TAC[] THEN CONJ_TAC THEN MATCH_MP_TAC HULL_MONO THEN + ASM SET_TAC[]] THEN + DISJ2_TAC THEN + EXISTS_TAC `(convex hull t) INTER (convex hull s):real^N->bool` THEN + CONJ_TAC THENL + [MATCH_MP_TAC FACE_OF_SUBSET THEN + EXISTS_TAC `convex hull ((a:real^N) INSERT s)` THEN + SIMP_TAC[INTER_SUBSET; HULL_MONO; SET_RULE `s SUBSET (a INSERT s)`] THEN + MATCH_MP_TAC FACE_OF_INTER THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC FACE_OF_CONVEX_HULL_INSERT THEN + ASM_REWRITE_TAC[FACE_OF_REFL_EQ; CONVEX_CONVEX_HULL]; + MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THEN + MATCH_MP_TAC HULL_MINIMAL THEN REWRITE_TAC[CONVEX_CONVEX_HULL] THEN + ASM_SIMP_TAC[INSERT_SUBSET; HULL_INC; INTER_SUBSET] THEN + REWRITE_TAC[SUBSET] THEN REPEAT STRIP_TAC THEN MATCH_MP_TAC HULL_INC THEN + ASM_CASES_TAC `x:real^N = a` THEN ASM_REWRITE_TAC[IN_INSERT] THEN + REWRITE_TAC[IN_INTER] THEN CONJ_TAC THEN MATCH_MP_TAC HULL_INC THEN + ASM SET_TAC[]]; + ALL_TAC] THEN + DISCH_THEN(DISJ_CASES_THEN ASSUME_TAC) THENL + [MATCH_MP_TAC FACE_OF_CONVEX_HULL_INSERT THEN ASM_REWRITE_TAC[]; + FIRST_X_ASSUM(X_CHOOSE_THEN `f':real^N->bool` MP_TAC)] THEN + DISCH_THEN(CONJUNCTS_THEN2 MP_TAC SUBST1_TAC) THEN + SPEC_TAC(`f':real^N->bool`,`f:real^N->bool`) THEN REPEAT STRIP_TAC THEN + ASM_CASES_TAC `s:real^N->bool = {}` THENL + [UNDISCH_TAC `(f:real^N->bool) face_of convex hull s` THEN + ASM_SIMP_TAC[FACE_OF_EMPTY; CONVEX_HULL_EMPTY; FACE_OF_REFL_EQ] THEN + REWRITE_TAC[CONVEX_CONVEX_HULL]; + ALL_TAC] THEN + ASM_CASES_TAC `f:real^N->bool = {}` THENL + [ASM_REWRITE_TAC[CONVEX_HULL_SING; FACE_OF_SING] THEN + MATCH_MP_TAC EXTREME_POINT_OF_CONVEX_HULL_INSERT THEN + ASM_REWRITE_TAC[] THEN + ASM_MESON_TAC[CONVEX_HULL_SUBSET_AFFINE_HULL; SUBSET]; + ALL_TAC] THEN + REWRITE_TAC[face_of; CONVEX_CONVEX_HULL] THEN CONJ_TAC THENL + [MATCH_MP_TAC HULL_MINIMAL THEN + SIMP_TAC[INSERT_SUBSET; HULL_INC; IN_INSERT; CONVEX_CONVEX_HULL] THEN + MATCH_MP_TAC SUBSET_TRANS THEN + EXISTS_TAC `convex hull s:real^N->bool` THEN + ASM_SIMP_TAC[HULL_MONO; SET_RULE `s SUBSET (a INSERT s)`] THEN + ASM_MESON_TAC[FACE_OF_IMP_SUBSET]; + ALL_TAC] THEN + ASM_REWRITE_TAC[CONVEX_HULL_INSERT_ALT] THEN + REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_GSPEC] THEN + REWRITE_TAC[IMP_IMP; GSYM CONJ_ASSOC] THEN + X_GEN_TAC `ub:real` THEN STRIP_TAC THEN + X_GEN_TAC `b:real^N` THEN STRIP_TAC THEN + X_GEN_TAC `uc:real` THEN STRIP_TAC THEN + X_GEN_TAC `c:real^N` THEN STRIP_TAC THEN + X_GEN_TAC `ux:real` THEN STRIP_TAC THEN + X_GEN_TAC `x:real^N` THEN STRIP_TAC THEN + FIRST_X_ASSUM(STRIP_ASSUME_TAC o GEN_REWRITE_RULE I [face_of]) THEN + SUBGOAL_THEN `convex hull f:real^N->bool = f` SUBST_ALL_TAC THENL + [ASM_MESON_TAC[CONVEX_HULL_EQ]; ALL_TAC] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_SEGMENT]) THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC (X_CHOOSE_THEN `v:real` MP_TAC)) THEN + REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + REWRITE_TAC[VECTOR_ARITH + `(&1 - ux) % a + ux % x:real^N = + (&1 - v) % ((&1 - ub) % a + ub % b) + v % ((&1 - uc) % a + uc % c) <=> + ((&1 - ux) - ((&1 - v) * (&1 - ub) + v * (&1 - uc))) % a + + (ux % x - (((&1 - v) * ub) % b + (v * uc) % c)) = vec 0`] THEN + ASM_CASES_TAC `&1 - ux - ((&1 - v) * (&1 - ub) + v * (&1 - uc)) = &0` THENL + [ASM_REWRITE_TAC[VECTOR_MUL_LZERO; VECTOR_ADD_LID] THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP (REAL_RING + `(&1 - ux) - ((&1 - v) * (&1 - ub) + v * (&1 - uc)) = &0 + ==> (&1 - v) * ub + v * uc = ux`)) THEN + ASM_CASES_TAC `uc = &0` THENL + [UNDISCH_THEN `uc = &0` SUBST_ALL_TAC THEN + FIRST_X_ASSUM(SUBST_ALL_TAC o MATCH_MP (REAL_ARITH + `a + v * &0 = b ==> b = a`)) THEN + REWRITE_TAC[REAL_MUL_RZERO; VECTOR_MUL_LZERO; VECTOR_ADD_RID] THEN + REWRITE_TAC[VECTOR_SUB_EQ; VECTOR_MUL_LCANCEL; REAL_ENTIRE] THEN + STRIP_TAC THENL + [ASM_REAL_ARITH_TAC; + ASM_MESON_TAC[VECTOR_MUL_LZERO]; + ASM_REWRITE_TAC[] THEN CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + REWRITE_TAC[IN_ELIM_THM] THEN + MAP_EVERY EXISTS_TAC [`&0`; `x:real^N`] THEN + ASM_REWRITE_TAC[] THEN CONV_TAC VECTOR_ARITH]; + ALL_TAC] THEN + ASM_CASES_TAC `ub = &0` THENL + [UNDISCH_THEN `ub = &0` SUBST_ALL_TAC THEN + FIRST_X_ASSUM(SUBST_ALL_TAC o MATCH_MP (REAL_ARITH + `v * &0 + a = b ==> b = a`)) THEN + REWRITE_TAC[REAL_MUL_RZERO; VECTOR_MUL_LZERO; VECTOR_ADD_LID] THEN + REWRITE_TAC[VECTOR_SUB_EQ; VECTOR_MUL_LCANCEL; REAL_ENTIRE] THEN + STRIP_TAC THENL + [ASM_REAL_ARITH_TAC; + ASM_MESON_TAC[VECTOR_MUL_LZERO]; + ASM_REWRITE_TAC[] THEN CONJ_TAC THENL [ALL_TAC; ASM SET_TAC[]] THEN + REWRITE_TAC[IN_ELIM_THM] THEN + MAP_EVERY EXISTS_TAC [`&0`; `x:real^N`] THEN + ASM_REWRITE_TAC[] THEN CONV_TAC VECTOR_ARITH]; + ALL_TAC] THEN + DISCH_THEN(fun th -> + SUBGOAL_THEN + `(b:real^N) IN f /\ (c:real^N) IN f` + MP_TAC THENL [ALL_TAC; ASM SET_TAC[]] THEN MP_TAC th) THEN + ASM_CASES_TAC `ux = &0` THENL + [DISCH_THEN(K ALL_TAC) THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + EXISTS_TAC `x:real^N` THEN ASM_REWRITE_TAC[] THEN + FIRST_X_ASSUM(MP_TAC o MATCH_MP (REAL_ARITH + `&1 - ux - a = &0 ==> ux = &0 ==> ~(a < &1)`)) THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC(TAUT `p ==> ~p ==> q`) THEN + MATCH_MP_TAC REAL_LTE_TRANS THEN + EXISTS_TAC `(&1 - v) * &1 + v * &1` THEN + CONJ_TAC THENL [ALL_TAC; REAL_ARITH_TAC] THEN + MATCH_MP_TAC(REAL_ARITH + `x <= y /\ w <= z /\ ~(x = y /\ w = z) ==> x + w < y + z`) THEN + ASM_SIMP_TAC[REAL_LE_LMUL_EQ; REAL_SUB_LT; REAL_EQ_MUL_LCANCEL] THEN + REPEAT(CONJ_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC]) THEN + ASM_SIMP_TAC[REAL_SUB_0; REAL_LT_IMP_NE] THEN + REWRITE_TAC[REAL_ARITH `&1 - x = &1 <=> x = &0`] THEN + DISCH_THEN(CONJUNCTS_THEN SUBST_ALL_TAC) THEN + ASM_MESON_TAC[VECTOR_MUL_LZERO]; + ALL_TAC] THEN + REWRITE_TAC[VECTOR_SUB_EQ] THEN ASM_CASES_TAC `c:real^N = b` THENL + [ASM_REWRITE_TAC[GSYM VECTOR_ADD_RDISTRIB; VECTOR_MUL_LCANCEL] THEN + ASM_MESON_TAC[]; + ALL_TAC] THEN + DISCH_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + EXISTS_TAC `x:real^N` THEN ASM_REWRITE_TAC[IN_SEGMENT] THEN + EXISTS_TAC `(v * uc) / ux:real` THEN + ASM_SIMP_TAC[REAL_LT_RDIV_EQ; REAL_LT_LDIV_EQ; REAL_ARITH + `&0 <= x /\ ~(x = &0) ==> &0 < x`] THEN + REWRITE_TAC[REAL_MUL_LZERO; REAL_MUL_LID] THEN REPEAT CONJ_TAC THENL + [MATCH_MP_TAC REAL_LT_MUL THEN ASM_REAL_ARITH_TAC; + EXPAND_TAC "ux" THEN REWRITE_TAC[REAL_ARITH `b < a + b <=> &0 < a`] THEN + MATCH_MP_TAC REAL_LT_MUL THEN ASM_REAL_ARITH_TAC; + FIRST_X_ASSUM(MP_TAC o AP_TERM `(%) (inv ux) :real^N->real^N`) THEN + ASM_SIMP_TAC[VECTOR_MUL_ASSOC; REAL_MUL_LINV] THEN + REWRITE_TAC[VECTOR_MUL_LID] THEN DISCH_THEN SUBST1_TAC THEN + REWRITE_TAC[VECTOR_ADD_LDISTRIB; VECTOR_MUL_ASSOC] THEN + BINOP_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN + REWRITE_TAC[REAL_ARITH `inv u * v * uc:real = (v * uc) / u`] THEN + UNDISCH_TAC `(&1 - v) * ub + v * uc = ux` THEN + UNDISCH_TAC `~(ux = &0)` THEN CONV_TAC REAL_FIELD]; + DISCH_THEN(MP_TAC o MATCH_MP (VECTOR_ARITH + `a + (b - c):real^N = vec 0 ==> a = c + --b`)) THEN + REWRITE_TAC[GSYM VECTOR_ADD_ASSOC; GSYM VECTOR_MUL_LNEG] THEN + DISCH_THEN(MP_TAC o SPEC `affine hull s:real^N->bool` o + MATCH_MP lemma) THEN + ASM_REWRITE_TAC[AFFINE_AFFINE_HULL] THEN + MATCH_MP_TAC(TAUT `p ==> ~p ==> q`) THEN + CONJ_TAC THENL [CONV_TAC REAL_RING; REPEAT CONJ_TAC] THEN + MATCH_MP_TAC(REWRITE_RULE[SUBSET] CONVEX_HULL_SUBSET_AFFINE_HULL) THEN + ASM_REWRITE_TAC[] THEN ASM SET_TAC[]]);; + +(* ------------------------------------------------------------------------- *) +(* Polytopes. *) +(* ------------------------------------------------------------------------- *) + +let polytope = new_definition + `polytope s <=> ?v. FINITE v /\ s = convex hull v`;; + +let POLYTOPE_TRANSLATION_EQ = prove + (`!a s. polytope (IMAGE (\x:real^N. a + x) s) <=> polytope s`, + REWRITE_TAC[polytope] THEN GEOM_TRANSLATE_TAC[]);; + +add_translation_invariants [POLYTOPE_TRANSLATION_EQ];; + +let POLYTOPE_LINEAR_IMAGE = prove + (`!f:real^M->real^N p. + linear f /\ polytope p ==> polytope(IMAGE f p)`, + REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + REWRITE_TAC[polytope] THEN + DISCH_THEN(X_CHOOSE_THEN `s:real^M->bool` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `IMAGE (f:real^M->real^N) s` THEN + ASM_SIMP_TAC[CONVEX_HULL_LINEAR_IMAGE; FINITE_IMAGE]);; + +let POLYTOPE_LINEAR_IMAGE_EQ = prove + (`!f:real^M->real^N s. + linear f /\ (!x y. f x = f y ==> x = y) /\ (!y. ?x. f x = y) + ==> (polytope (IMAGE f s) <=> polytope s)`, + REPEAT STRIP_TAC THEN REWRITE_TAC[polytope] THEN + MP_TAC(ISPEC `f:real^M->real^N` QUANTIFY_SURJECTION_THM) THEN + ASM_REWRITE_TAC[] THEN + DISCH_THEN(fun th -> GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV)[th]) THEN + MP_TAC(end_itlist CONJ + (mapfilter (ISPEC `f:real^M->real^N`) (!invariant_under_linear))) THEN + ASM_REWRITE_TAC[] THEN DISCH_TAC THEN ASM_REWRITE_TAC[]);; + +let POLYTOPE_EMPTY = prove + (`polytope {}`, + REWRITE_TAC[polytope] THEN MESON_TAC[FINITE_EMPTY; CONVEX_HULL_EMPTY]);; + +let POLYTOPE_NEGATIONS = prove + (`!s:real^N->bool. polytope s ==> polytope(IMAGE (--) s)`, + SIMP_TAC[POLYTOPE_LINEAR_IMAGE; LINEAR_NEGATION]);; + +let POLYTOPE_CONVEX_HULL = prove + (`!s. FINITE s ==> polytope(convex hull s)`, + REWRITE_TAC[polytope] THEN MESON_TAC[]);; + +let POLYTOPE_PCROSS = prove + (`!s:real^M->bool t:real^N->bool. + polytope s /\ polytope t ==> polytope(s PCROSS t)`, + REPEAT GEN_TAC THEN REWRITE_TAC[polytope] THEN + MESON_TAC[CONVEX_HULL_PCROSS; FINITE_PCROSS]);; + +let POLYTOPE_PCROSS_EQ = prove + (`!s:real^M->bool t:real^N->bool. + polytope(s PCROSS t) <=> + s = {} \/ t = {} \/ polytope s /\ polytope t`, + REPEAT GEN_TAC THEN + ASM_CASES_TAC `s:real^M->bool = {}` THEN + ASM_REWRITE_TAC[PCROSS_EMPTY; POLYTOPE_EMPTY] THEN + ASM_CASES_TAC `t:real^N->bool = {}` THEN + ASM_REWRITE_TAC[PCROSS_EMPTY; POLYTOPE_EMPTY] THEN + EQ_TAC THEN REWRITE_TAC[POLYTOPE_PCROSS] THEN REPEAT STRIP_TAC THENL + [MP_TAC(ISPECL [`fstcart:real^(M,N)finite_sum->real^M`; + `(s:real^M->bool) PCROSS (t:real^N->bool)`] + POLYTOPE_LINEAR_IMAGE) THEN + ASM_REWRITE_TAC[LINEAR_FSTCART]; + MP_TAC(ISPECL [`sndcart:real^(M,N)finite_sum->real^N`; + `(s:real^M->bool) PCROSS (t:real^N->bool)`] + POLYTOPE_LINEAR_IMAGE) THEN + ASM_REWRITE_TAC[LINEAR_SNDCART]] THEN + MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN + REWRITE_TAC[EXTENSION; IN_IMAGE; EXISTS_PASTECART; PASTECART_IN_PCROSS; + FSTCART_PASTECART; SNDCART_PASTECART] THEN + ASM SET_TAC[]);; + +let FACE_OF_POLYTOPE_POLYTOPE = prove + (`!f s:real^N->bool. polytope s /\ f face_of s ==> polytope f`, + REWRITE_TAC[polytope] THEN + MESON_TAC[FINITE_SUBSET; FACE_OF_CONVEX_HULL_SUBSET; FINITE_IMP_COMPACT]);; + +let FINITE_POLYTOPE_FACES = prove + (`!s:real^N->bool. polytope s ==> FINITE {f | f face_of s}`, + GEN_TAC THEN REWRITE_TAC[polytope; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `v:real^N->bool` THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC FINITE_SUBSET THEN + EXISTS_TAC `IMAGE ((hull) convex) {t:real^N->bool | t SUBSET v}` THEN + ASM_SIMP_TAC[FINITE_POWERSET; FINITE_IMAGE] THEN + GEN_REWRITE_TAC I [SUBSET] THEN + REWRITE_TAC[FORALL_IN_GSPEC; IN_IMAGE; IN_ELIM_THM] THEN + ASM_MESON_TAC[FACE_OF_CONVEX_HULL_SUBSET; FINITE_IMP_COMPACT]);; + +let FINITE_POLYTOPE_FACETS = prove + (`!s:real^N->bool. polytope s ==> FINITE {f | f facet_of s}`, + REWRITE_TAC[facet_of] THEN ONCE_REWRITE_TAC[SET_RULE + `{x | P x /\ Q x} = {x | x IN {x | P x} /\ Q x}`] THEN + SIMP_TAC[FINITE_RESTRICT; FINITE_POLYTOPE_FACES]);; + +let POLYTOPE_SCALING = prove + (`!c s:real^N->bool. polytope s ==> polytope (IMAGE (\x. c % x) s)`, + REPEAT GEN_TAC THEN REWRITE_TAC[polytope] THEN DISCH_THEN + (X_CHOOSE_THEN `u:real^N->bool` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `IMAGE (\x:real^N. c % x) u` THEN + ASM_SIMP_TAC[CONVEX_HULL_SCALING; FINITE_IMAGE]);; + +let POLYTOPE_SCALING_EQ = prove + (`!c s:real^N->bool. + ~(c = &0) ==> (polytope (IMAGE (\x. c % x) s) <=> polytope s)`, + REPEAT STRIP_TAC THEN EQ_TAC THEN REWRITE_TAC[POLYTOPE_SCALING] THEN + DISCH_THEN(MP_TAC o SPEC `inv c:real` o MATCH_MP POLYTOPE_SCALING) THEN + ASM_SIMP_TAC[GSYM IMAGE_o; o_DEF; VECTOR_MUL_ASSOC; + REAL_MUL_LINV; VECTOR_MUL_LID; IMAGE_ID]);; + +let POLYTOPE_SUMS = prove + (`!s t:real^N->bool. + polytope s /\ polytope t ==> polytope {x + y | x IN s /\ y IN t}`, + REPEAT GEN_TAC THEN REWRITE_TAC[polytope] THEN DISCH_THEN(CONJUNCTS_THEN2 + (X_CHOOSE_THEN `u:real^N->bool` STRIP_ASSUME_TAC) + (X_CHOOSE_THEN `v:real^N->bool` STRIP_ASSUME_TAC)) THEN + EXISTS_TAC `{x + y:real^N | x IN u /\ y IN v}` THEN + ASM_SIMP_TAC[FINITE_PRODUCT_DEPENDENT; CONVEX_HULL_SUMS]);; + +let POLYTOPE_IMP_COMPACT = prove + (`!s. polytope s ==> compact s`, + SIMP_TAC[polytope; LEFT_IMP_EXISTS_THM; COMPACT_CONVEX_HULL; + FINITE_IMP_COMPACT; FINITE_INSERT; FINITE_EMPTY]);; + +let POLYTOPE_IMP_CONVEX = prove + (`!s. polytope s ==> convex s`, + SIMP_TAC[polytope; LEFT_IMP_EXISTS_THM; CONVEX_CONVEX_HULL]);; + +let POLYTOPE_IMP_CLOSED = prove + (`!s. polytope s ==> closed s`, + SIMP_TAC[POLYTOPE_IMP_COMPACT; COMPACT_IMP_CLOSED]);; + +let POLYTOPE_IMP_BOUNDED = prove + (`!s. polytope s ==> bounded s`, + SIMP_TAC[POLYTOPE_IMP_COMPACT; COMPACT_IMP_BOUNDED]);; + +let POLYTOPE_INTERVAL = prove + (`!a b. polytope(interval[a,b])`, + REWRITE_TAC[polytope] THEN MESON_TAC[CLOSED_INTERVAL_AS_CONVEX_HULL]);; + +let POLYTOPE_SING = prove + (`!a. polytope {a}`, + MESON_TAC[POLYTOPE_INTERVAL; INTERVAL_SING]);; + +(* ------------------------------------------------------------------------- *) +(* Polyhedra. *) +(* ------------------------------------------------------------------------- *) + +let polyhedron = new_definition + `polyhedron s <=> + ?f. FINITE f /\ + s = INTERS f /\ + (!h. h IN f ==> ?a b. ~(a = vec 0) /\ h = {x | a dot x <= b})`;; + +let POLYHEDRON_INTER = prove + (`!s t:real^N->bool. + polyhedron s /\ polyhedron t ==> polyhedron (s INTER t)`, + REPEAT GEN_TAC THEN REWRITE_TAC[polyhedron] THEN + DISCH_THEN(CONJUNCTS_THEN2 + (X_CHOOSE_TAC `f:(real^N->bool)->bool`) + (X_CHOOSE_TAC `g:(real^N->bool)->bool`)) THEN + EXISTS_TAC `f UNION g:(real^N->bool)->bool` THEN + ASM_REWRITE_TAC[SET_RULE `INTERS(f UNION g) = INTERS f INTER INTERS g`] THEN + REWRITE_TAC[FINITE_UNION; IN_UNION] THEN + REPEAT STRIP_TAC THEN ASM_SIMP_TAC[]);; + +let POLYHEDRON_UNIV = prove + (`polyhedron(:real^N)`, + REWRITE_TAC[polyhedron] THEN EXISTS_TAC `{}:(real^N->bool)->bool` THEN + REWRITE_TAC[INTERS_0; NOT_IN_EMPTY; FINITE_RULES]);; + +let POLYHEDRON_POSITIVE_ORTHANT = prove + (`polyhedron {x:real^N | !i. 1 <= i /\ i <= dimindex(:N) ==> &0 <= x$i}`, + REWRITE_TAC[polyhedron] THEN + EXISTS_TAC `IMAGE (\i. {x:real^N | &0 <= x$i}) (1..dimindex(:N))` THEN + SIMP_TAC[FINITE_IMAGE; FINITE_NUMSEG; FORALL_IN_IMAGE] THEN CONJ_TAC THENL + [GEN_REWRITE_TAC I [EXTENSION] THEN REWRITE_TAC[INTERS_IMAGE] THEN + REWRITE_TAC[IN_ELIM_THM; IN_NUMSEG]; + X_GEN_TAC `k:num` THEN REWRITE_TAC[IN_NUMSEG] THEN STRIP_TAC THEN + MAP_EVERY EXISTS_TAC [`--basis k:real^N`; `&0`] THEN + ASM_SIMP_TAC[VECTOR_NEG_EQ_0; DOT_LNEG; DOT_BASIS; BASIS_NONZERO] THEN + REWRITE_TAC[REAL_ARITH `--x <= &0 <=> &0 <= x`]]);; + +let POLYHEDRON_INTERS = prove + (`!f:(real^N->bool)->bool. + FINITE f /\ (!s. s IN f ==> polyhedron s) ==> polyhedron(INTERS f)`, + REWRITE_TAC[IMP_CONJ] THEN MATCH_MP_TAC FINITE_INDUCT_STRONG THEN + REWRITE_TAC[NOT_IN_EMPTY; INTERS_0; POLYHEDRON_UNIV] THEN + ASM_SIMP_TAC[INTERS_INSERT; FORALL_IN_INSERT; POLYHEDRON_INTER]);; + +let POLYHEDRON_EMPTY = prove + (`polyhedron({}:real^N->bool)`, + REWRITE_TAC[polyhedron] THEN + EXISTS_TAC `{{x:real^N | basis 1 dot x <= -- &1}, + {x | --(basis 1) dot x <= -- &1}}` THEN + REWRITE_TAC[FINITE_INSERT; FINITE_EMPTY; INTERS_2; FORALL_IN_INSERT] THEN + REWRITE_TAC[NOT_IN_EMPTY; INTER; IN_ELIM_THM; DOT_LNEG] THEN + REWRITE_TAC[REAL_ARITH `~(a <= -- &1 /\ --a <= -- &1)`; EMPTY_GSPEC] THEN + CONJ_TAC THENL + [MAP_EVERY EXISTS_TAC [`basis 1:real^N`; `-- &1`]; + MAP_EVERY EXISTS_TAC [`--(basis 1):real^N`; `-- &1`]] THEN + SIMP_TAC[VECTOR_NEG_EQ_0; BASIS_NONZERO; DOT_LNEG; + DIMINDEX_GE_1; LE_REFL]);; + +let POLYHEDRON_HALFSPACE_LE = prove + (`!a b. polyhedron {x:real^N | a dot x <= b}`, + REPEAT GEN_TAC THEN ASM_CASES_TAC `a:real^N = vec 0` THENL + [ASM_SIMP_TAC[DOT_LZERO; SET_RULE `{x | p} = if p then UNIV else {}`] THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[POLYHEDRON_EMPTY; POLYHEDRON_UNIV]; + REWRITE_TAC[polyhedron] THEN EXISTS_TAC `{{x:real^N | a dot x <= b}}` THEN + REWRITE_TAC[FINITE_SING; INTERS_1; FORALL_IN_INSERT; NOT_IN_EMPTY] THEN + MAP_EVERY EXISTS_TAC [`a:real^N`; `b:real`] THEN ASM_REWRITE_TAC[]]);; + +let POLYHEDRON_HALFSPACE_GE = prove + (`!a b. polyhedron {x:real^N | a dot x >= b}`, + REWRITE_TAC[REAL_ARITH `a:real >= b <=> --a <= --b`] THEN + REWRITE_TAC[GSYM DOT_LNEG; POLYHEDRON_HALFSPACE_LE]);; + +let POLYHEDRON_HYPERPLANE = prove + (`!a b. polyhedron {x:real^N | a dot x = b}`, + REWRITE_TAC[REAL_ARITH `x:real = b <=> x <= b /\ x >= b`] THEN + REWRITE_TAC[SET_RULE `{x | P x /\ Q x} = {x | P x} INTER {x | Q x}`] THEN + SIMP_TAC[POLYHEDRON_INTER; POLYHEDRON_HALFSPACE_LE; + POLYHEDRON_HALFSPACE_GE]);; + +let AFFINE_IMP_POLYHEDRON = prove + (`!s:real^N->bool. affine s ==> polyhedron s`, + REPEAT STRIP_TAC THEN MP_TAC(ISPEC `s:real^N->bool` + AFFINE_HULL_FINITE_INTERSECTION_HYPERPLANES) THEN + ASM_SIMP_TAC[HULL_P; RIGHT_IMP_EXISTS_THM; SKOLEM_THM] THEN + STRIP_TAC THEN ASM_SIMP_TAC[] THEN + MATCH_MP_TAC POLYHEDRON_INTERS THEN ASM_REWRITE_TAC[] THEN + X_GEN_TAC `h:real^N->bool` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `h:real^N->bool`) THEN + ASM_REWRITE_TAC[] THEN DISCH_THEN(SUBST1_TAC o CONJUNCT2) THEN + REWRITE_TAC[POLYHEDRON_HYPERPLANE]);; + +let POLYHEDRON_IMP_CLOSED = prove + (`!s:real^N->bool. polyhedron s ==> closed s`, + REWRITE_TAC[polyhedron; RIGHT_IMP_EXISTS_THM; SKOLEM_THM] THEN + REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC CLOSED_INTERS THEN + X_GEN_TAC `h:real^N->bool` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `h:real^N->bool`) THEN + ASM_REWRITE_TAC[] THEN DISCH_THEN(SUBST1_TAC o CONJUNCT2) THEN + REWRITE_TAC[CLOSED_HALFSPACE_LE]);; + +let POLYHEDRON_IMP_CONVEX = prove + (`!s:real^N->bool. polyhedron s ==> convex s`, + REWRITE_TAC[polyhedron; RIGHT_IMP_EXISTS_THM; SKOLEM_THM] THEN + REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC CONVEX_INTERS THEN + X_GEN_TAC `h:real^N->bool` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `h:real^N->bool`) THEN + ASM_REWRITE_TAC[] THEN DISCH_THEN(SUBST1_TAC o CONJUNCT2) THEN + REWRITE_TAC[CONVEX_HALFSPACE_LE]);; + +let POLYHEDRON_AFFINE_HULL = prove + (`!s. polyhedron(affine hull s)`, + SIMP_TAC[AFFINE_IMP_POLYHEDRON; AFFINE_AFFINE_HULL]);; + +(* ------------------------------------------------------------------------- *) +(* Canonical polyedron representation making facial structure explicit. *) +(* ------------------------------------------------------------------------- *) + +let POLYHEDRON_INTER_AFFINE = prove + (`!s. polyhedron s <=> + ?f. FINITE f /\ + s = (affine hull s) INTER (INTERS f) /\ + (!h. h IN f + ==> ?a b. ~(a = vec 0) /\ h = {x:real^N | a dot x <= b})`, + GEN_TAC THEN EQ_TAC THENL + [REWRITE_TAC[polyhedron] THEN MATCH_MP_TAC MONO_EXISTS THEN + GEN_TAC THEN STRIP_TAC THEN REPEAT CONJ_TAC THEN + TRY(FIRST_ASSUM ACCEPT_TAC) THEN + MATCH_MP_TAC(SET_RULE `s = t /\ s SUBSET u ==> s = u INTER t`) THEN + REWRITE_TAC[HULL_SUBSET] THEN ASM_REWRITE_TAC[]; + STRIP_TAC THEN ONCE_ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC POLYHEDRON_INTER THEN REWRITE_TAC[POLYHEDRON_AFFINE_HULL] THEN + MATCH_MP_TAC POLYHEDRON_INTERS THEN ASM_REWRITE_TAC[] THEN + ASM_MESON_TAC[POLYHEDRON_HALFSPACE_LE]]);; + +let POLYHEDRON_INTER_AFFINE_PARALLEL = prove + (`!s:real^N->bool. + polyhedron s <=> + ?f. FINITE f /\ + s = (affine hull s) INTER (INTERS f) /\ + (!h. h IN f + ==> ?a b. ~(a = vec 0) /\ h = {x:real^N | a dot x <= b} /\ + (!x. x IN affine hull s + ==> (x + a) IN affine hull s))`, + GEN_TAC THEN REWRITE_TAC[POLYHEDRON_INTER_AFFINE] THEN EQ_TAC THENL + [ALL_TAC; MATCH_MP_TAC MONO_EXISTS THEN MESON_TAC[]] THEN + DISCH_THEN(X_CHOOSE_THEN `f:(real^N->bool)->bool` MP_TAC) THEN + ASM_CASES_TAC `s:real^N->bool = {}` THENL + [DISCH_THEN(K ALL_TAC) THEN EXISTS_TAC `{}:(real^N->bool)->bool` THEN + ASM_SIMP_TAC[AFFINE_HULL_EMPTY; INTER_EMPTY; NOT_IN_EMPTY; FINITE_EMPTY]; + ALL_TAC] THEN + ASM_CASES_TAC `f:(real^N->bool)->bool = {}` THENL + [ASM_REWRITE_TAC[NOT_IN_EMPTY; INTERS_0; INTER_UNIV] THEN + DISCH_THEN(ASSUME_TAC o SYM o CONJUNCT2) THEN + EXISTS_TAC `{}:(real^N->bool)->bool` THEN + ASM_REWRITE_TAC[NOT_IN_EMPTY; INTERS_0; INTER_UNIV; FINITE_EMPTY]; + ALL_TAC] THEN + REPEAT(DISCH_THEN(CONJUNCTS_THEN2 (ASSUME_TAC o GSYM) MP_TAC)) THEN + GEN_REWRITE_TAC (LAND_CONV o TOP_DEPTH_CONV) + [RIGHT_IMP_EXISTS_THM] THEN + REWRITE_TAC[LEFT_IMP_EXISTS_THM; SKOLEM_THM] THEN + MAP_EVERY X_GEN_TAC + [`a:(real^N->bool)->real^N`; `b:(real^N->bool)->real`] THEN + DISCH_THEN(ASSUME_TAC o GSYM) THEN + SUBGOAL_THEN + `!h. h IN f /\ ~(affine hull s SUBSET h) + ==> ?a' b'. ~(a' = vec 0) /\ + affine hull s INTER {x:real^N | a' dot x <= b'} = + affine hull s INTER h /\ + !w. w IN affine hull s ==> (w + a') IN affine hull s` + MP_TAC THENL + [GEN_TAC THEN STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o SPEC `h:real^N->bool`) THEN + REWRITE_TAC[ASSUME `(h:real^N->bool) IN f`] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC SUBST1_TAC o GSYM) THEN + MP_TAC(ISPECL [`affine hull s:real^N->bool`; + `(a:(real^N->bool)->real^N) h`; + `(b:(real^N->bool)->real) h`] + AFFINE_PARALLEL_SLICE) THEN + REWRITE_TAC[AFFINE_AFFINE_HULL] THEN MATCH_MP_TAC(TAUT + `~p /\ ~q /\ (r ==> r') ==> (p \/ q \/ r ==> r')`) THEN + ASM_SIMP_TAC[] THEN CONJ_TAC THENL [ALL_TAC; MESON_TAC[]] THEN + DISCH_TAC THEN + UNDISCH_TAC `~(s:real^N->bool = {})` THEN + EXPAND_TAC "s" THEN REWRITE_TAC[GSYM INTERS_INSERT] THEN + MATCH_MP_TAC(SET_RULE + `!t. t SUBSET s /\ INTERS t = {} ==> INTERS s = {}`) THEN + EXISTS_TAC `{affine hull s,h:real^N->bool}` THEN + ASM_REWRITE_TAC[INTERS_2] THEN ASM SET_TAC[]; + ALL_TAC] THEN + GEN_REWRITE_TAC (LAND_CONV o TOP_DEPTH_CONV) [RIGHT_IMP_EXISTS_THM] THEN + REWRITE_TAC[SKOLEM_THM; LEFT_IMP_EXISTS_THM] THEN + FIRST_X_ASSUM(K ALL_TAC o SPEC `{}:real^N->bool`) THEN + MAP_EVERY X_GEN_TAC + [`a:(real^N->bool)->real^N`; `b:(real^N->bool)->real`] THEN + DISCH_TAC THEN + EXISTS_TAC `IMAGE (\h:real^N->bool. {x:real^N | a h dot x <= b h}) + {h | h IN f /\ ~(affine hull s SUBSET h)}` THEN + ASM_SIMP_TAC[FINITE_IMAGE; FINITE_RESTRICT; FORALL_IN_IMAGE] THEN + REWRITE_TAC[FORALL_IN_GSPEC] THEN CONJ_TAC THENL + [ALL_TAC; + X_GEN_TAC `h:real^N->bool` THEN STRIP_TAC THEN + MAP_EVERY EXISTS_TAC + [`(a:(real^N->bool)->real^N) h`; `(b:(real^N->bool)->real) h`] THEN + ASM_MESON_TAC[]] THEN + FIRST_X_ASSUM(fun th -> GEN_REWRITE_TAC LAND_CONV [GSYM th]) THEN + GEN_REWRITE_TAC I [EXTENSION] THEN X_GEN_TAC `x:real^N` THEN + REWRITE_TAC[INTERS_IMAGE; IN_INTER; IN_ELIM_THM] THEN + ASM_CASES_TAC `(x:real^N) IN affine hull s` THEN + ASM_REWRITE_TAC[IN_INTERS] THEN AP_TERM_TAC THEN ABS_TAC THEN + ASM SET_TAC[]);; + +let POLYHEDRON_INTER_AFFINE_PARALLEL_MINIMAL = prove + (`!s. polyhedron s <=> + ?f. FINITE f /\ + s = (affine hull s) INTER (INTERS f) /\ + (!h. h IN f + ==> ?a b. ~(a = vec 0) /\ h = {x:real^N | a dot x <= b} /\ + (!x. x IN affine hull s + ==> (x + a) IN affine hull s)) /\ + !f'. f' PSUBSET f ==> s PSUBSET (affine hull s) INTER (INTERS f')`, + GEN_TAC THEN REWRITE_TAC[POLYHEDRON_INTER_AFFINE_PARALLEL] THEN + EQ_TAC THENL [ALL_TAC; MATCH_MP_TAC MONO_EXISTS THEN MESON_TAC[]] THEN + GEN_REWRITE_TAC LAND_CONV + [MESON[HAS_SIZE] + `(?f. FINITE f /\ P f) <=> (?n f. f HAS_SIZE n /\ P f)`] THEN + GEN_REWRITE_TAC LAND_CONV [num_WOP] THEN + DISCH_THEN(X_CHOOSE_THEN `n:num` (CONJUNCTS_THEN2 MP_TAC ASSUME_TAC)) THEN + MATCH_MP_TAC MONO_EXISTS THEN REWRITE_TAC[HAS_SIZE] THEN + X_GEN_TAC `f:(real^N->bool)->bool` THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + CONJ_TAC THENL [FIRST_ASSUM ACCEPT_TAC; ALL_TAC] THEN + X_GEN_TAC `f':(real^N->bool)->bool` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `CARD(f':(real^N->bool)->bool)`) THEN + ANTS_TAC THENL [ASM_MESON_TAC[CARD_PSUBSET]; ALL_TAC] THEN + REWRITE_TAC[NOT_EXISTS_THM; HAS_SIZE] THEN + DISCH_THEN(MP_TAC o SPEC `f':(real^N->bool)->bool`) THEN + MATCH_MP_TAC(TAUT `a /\ c /\ (~b ==> d) ==> ~(a /\ b /\ c) ==> d`) THEN + CONJ_TAC THENL [ASM_MESON_TAC[PSUBSET; FINITE_SUBSET]; ALL_TAC] THEN + CONJ_TAC THENL + [REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM SET_TAC[]; + MATCH_MP_TAC(SET_RULE `s SUBSET t ==> ~(s = t) ==> s PSUBSET t`) THEN + FIRST_X_ASSUM(fun th -> GEN_REWRITE_TAC LAND_CONV [th]) THEN + ASM SET_TAC[]]);; + +let POLYHEDRON_INTER_AFFINE_MINIMAL = prove + (`!s. polyhedron s <=> + ?f. FINITE f /\ + s = (affine hull s) INTER (INTERS f) /\ + (!h. h IN f + ==> ?a b. ~(a = vec 0) /\ h = {x:real^N | a dot x <= b}) /\ + !f'. f' PSUBSET f ==> s PSUBSET (affine hull s) INTER (INTERS f')`, + GEN_TAC THEN EQ_TAC THENL + [REWRITE_TAC[POLYHEDRON_INTER_AFFINE_PARALLEL_MINIMAL]; + REWRITE_TAC[POLYHEDRON_INTER_AFFINE]] THEN + MATCH_MP_TAC MONO_EXISTS THEN SIMP_TAC[] THEN MESON_TAC[]);; + +let RELATIVE_INTERIOR_POLYHEDRON_EXPLICIT = prove + (`!s:real^N->bool f a b. + FINITE f /\ + s = affine hull s INTER INTERS f /\ + (!h. h IN f ==> ~(a h = vec 0) /\ h = {x | a h dot x <= b h}) /\ + (!f'. f' PSUBSET f ==> s PSUBSET affine hull s INTER INTERS f') + ==> relative_interior s = + {x | x IN s /\ !h. h IN f ==> a h dot x < b h}`, + REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + DISCH_THEN(CONJUNCTS_THEN2 (ASSUME_TAC o SYM) STRIP_ASSUME_TAC) THEN + GEN_REWRITE_TAC I [EXTENSION] THEN REWRITE_TAC[IN_ELIM_THM] THEN + X_GEN_TAC `x:real^N` THEN EQ_TAC THENL + [ALL_TAC; + STRIP_TAC THEN ASM_REWRITE_TAC[RELATIVE_INTERIOR; IN_ELIM_THM] THEN + EXISTS_TAC `INTERS {interior h | (h:real^N->bool) IN f}` THEN + ASM_SIMP_TAC[SIMPLE_IMAGE; OPEN_INTERS; FINITE_IMAGE; OPEN_INTERIOR; + FORALL_IN_IMAGE; IN_INTERS] THEN + CONJ_TAC THENL + [X_GEN_TAC `h:real^N->bool` THEN DISCH_TAC THEN + REPEAT(FIRST_X_ASSUM(MP_TAC o SPEC `h:real^N->bool`)) THEN + ASM_REWRITE_TAC[] THEN REPEAT DISCH_TAC THEN + FIRST_ASSUM(SUBST1_TAC o CONJUNCT2) THEN + ASM_SIMP_TAC[INTERIOR_HALFSPACE_LE; IN_ELIM_THM]; + FIRST_X_ASSUM(fun th -> GEN_REWRITE_TAC RAND_CONV [SYM th]) THEN + MATCH_MP_TAC(SET_RULE + `(!s. s IN f ==> i s SUBSET s) + ==> INTERS (IMAGE i f) INTER t SUBSET t INTER INTERS f`) THEN + REWRITE_TAC[INTERIOR_SUBSET]]] THEN + DISCH_TAC THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_RELATIVE_INTERIOR]) THEN + DISCH_TAC THEN ASM_REWRITE_TAC[] THEN X_GEN_TAC `i:real^N->bool` THEN + DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `f DELETE (i:real^N->bool)`) THEN ANTS_TAC THENL + [ASM SET_TAC[]; + REWRITE_TAC[PSUBSET_ALT; IN_INTER; IN_INTERS; IN_DELETE]] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + DISCH_THEN(X_CHOOSE_THEN `z:real^N` STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN `(a:(real^N->bool)->real^N) i dot z > b i` ASSUME_TAC THENL + [UNDISCH_TAC `~((z:real^N) IN s)` THEN + FIRST_ASSUM(SUBST1_TAC o SYM) THEN REWRITE_TAC[IN_INTER; IN_INTERS] THEN + ASM_REWRITE_TAC[REAL_ARITH `a:real > b <=> ~(a <= b)`] THEN ASM SET_TAC[]; + ALL_TAC] THEN + SUBGOAL_THEN `~(z:real^N = x)` ASSUME_TAC THENL + [ASM_MESON_TAC[]; ALL_TAC] THEN + SUBGOAL_THEN + `?l. &0 < l /\ l < &1 /\ (l % z + (&1 - l) % x:real^N) IN s` + STRIP_ASSUME_TAC THENL + [FIRST_ASSUM(X_CHOOSE_THEN `e:real` MP_TAC o CONJUNCT2) THEN + REWRITE_TAC[SUBSET; IN_INTER; IN_BALL; dist] THEN STRIP_TAC THEN + EXISTS_TAC `min (&1 / &2) (e / &2 / norm(z - x:real^N))` THEN + REWRITE_TAC[REAL_MIN_LT; REAL_LT_MIN] THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN + ASM_SIMP_TAC[REAL_HALF; REAL_LT_DIV; NORM_POS_LT; VECTOR_SUB_EQ] THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN CONJ_TAC THENL + [REWRITE_TAC[VECTOR_ARITH + `x - (l % z + (&1 - l) % x):real^N = --l % (z - x)`] THEN + REWRITE_TAC[NORM_MUL; REAL_ABS_NEG] THEN + ASM_SIMP_TAC[GSYM REAL_LT_RDIV_EQ; NORM_POS_LT; VECTOR_SUB_EQ] THEN + MATCH_MP_TAC(REAL_ARITH + `&0 < a /\ &0 < b /\ b < c ==> abs(min a b) < c`) THEN + ASM_SIMP_TAC[REAL_HALF; REAL_LT_DIV; NORM_POS_LT; VECTOR_SUB_EQ] THEN + REWRITE_TAC[REAL_LT_01; real_div; REAL_MUL_ASSOC] THEN + MATCH_MP_TAC REAL_LT_RMUL THEN + ASM_REWRITE_TAC[REAL_LT_INV_EQ; NORM_POS_LT; VECTOR_SUB_EQ] THEN + UNDISCH_TAC `&0 < e` THEN REAL_ARITH_TAC; + ONCE_REWRITE_TAC[VECTOR_ADD_SYM] THEN + MATCH_MP_TAC(REWRITE_RULE[AFFINE_ALT] AFFINE_AFFINE_HULL) THEN + ASM SET_TAC[]]; + ALL_TAC] THEN + MATCH_MP_TAC REAL_LT_RCANCEL_IMP THEN EXISTS_TAC `&1 - l` THEN + ASM_REWRITE_TAC[REAL_SUB_LT] THEN + REWRITE_TAC[REAL_ARITH `a < b * (&1 - l) <=> l * b + a < b`] THEN + MATCH_MP_TAC REAL_LTE_TRANS THEN EXISTS_TAC + `l * (a:(real^N->bool)->real^N) i dot z + (a i dot x) * (&1 - l)` THEN + ASM_SIMP_TAC[REAL_LT_RADD; REAL_LT_LMUL_EQ; GSYM real_gt] THEN + ONCE_REWRITE_TAC[REAL_ARITH `a * (&1 - b) = (&1 - b) * a`] THEN + REWRITE_TAC[GSYM DOT_RMUL; GSYM DOT_RADD] THEN ASM SET_TAC[]);; + +let FACET_OF_POLYHEDRON_EXPLICIT = prove + (`!s:real^N->bool f a b. + FINITE f /\ + s = affine hull s INTER INTERS f /\ + (!h. h IN f ==> ~(a h = vec 0) /\ h = {x | a h dot x <= b h}) /\ + (!f'. f' PSUBSET f ==> s PSUBSET affine hull s INTER INTERS f') + ==> !c. c facet_of s <=> + ?h. h IN f /\ c = s INTER {x | a h dot x = b h}`, + REPEAT GEN_TAC THEN ASM_CASES_TAC `s:real^N->bool = {}` THENL + [ASM_REWRITE_TAC[INTER_EMPTY; AFFINE_HULL_EMPTY; SET_RULE `~(s PSUBSET s)`; + FACET_OF_EMPTY] THEN + ASM_CASES_TAC `f:(real^N->bool)->bool = {}` THEN + ASM_REWRITE_TAC[NOT_IN_EMPTY] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN + DISCH_THEN(X_CHOOSE_TAC `h:real^N->bool`) THEN DISCH_THEN + (MP_TAC o SPEC `f DELETE (h:real^N->bool)` o last o CONJUNCTS) THEN + ASM SET_TAC[]; + STRIP_TAC] THEN + SUBGOAL_THEN `polyhedron(s:real^N->bool)` ASSUME_TAC THENL + [REWRITE_TAC[POLYHEDRON_INTER_AFFINE] THEN + REWRITE_TAC[RIGHT_IMP_EXISTS_THM; SKOLEM_THM] THEN ASM_MESON_TAC[]; + ALL_TAC] THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP POLYHEDRON_IMP_CONVEX) THEN + SUBGOAL_THEN + `!h:real^N->bool. + h IN f ==> (s INTER {x:real^N | a h dot x = b h}) facet_of s` + (LABEL_TAC "face") THENL + [REPEAT STRIP_TAC THEN REWRITE_TAC[facet_of] THEN CONJ_TAC THENL + [MATCH_MP_TAC FACE_OF_INTER_SUPPORTING_HYPERPLANE_LE THEN + CONJ_TAC THENL + [MATCH_MP_TAC POLYHEDRON_IMP_CONVEX THEN + REWRITE_TAC[POLYHEDRON_INTER_AFFINE] THEN + REWRITE_TAC[RIGHT_IMP_EXISTS_THM; SKOLEM_THM] THEN ASM_MESON_TAC[]; + X_GEN_TAC `x:real^N` THEN FIRST_X_ASSUM SUBST1_TAC THEN + REWRITE_TAC[IN_INTER; IN_INTERS] THEN + DISCH_THEN(MP_TAC o SPEC `h:real^N->bool` o CONJUNCT2) THEN + ASM_REWRITE_TAC[] THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `h:real^N->bool`) THEN + ASM_REWRITE_TAC[] THEN ASM SET_TAC[]]; + ALL_TAC] THEN + MP_TAC(ISPEC `s:real^N->bool` RELATIVE_INTERIOR_EQ_EMPTY) THEN + ASM_SIMP_TAC[] THEN REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN + DISCH_THEN(X_CHOOSE_TAC `x:real^N`) THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_RELATIVE_INTERIOR]) THEN + DISCH_TAC THEN + FIRST_ASSUM(MP_TAC o SPEC `f DELETE (h:real^N->bool)`) THEN + ANTS_TAC THENL + [ASM SET_TAC[]; + REWRITE_TAC[PSUBSET_ALT; IN_INTER; IN_INTERS; IN_DELETE]] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + DISCH_THEN(X_CHOOSE_THEN `z:real^N` STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN `(a:(real^N->bool)->real^N) h dot z > b h` ASSUME_TAC THENL + [UNDISCH_TAC `~((z:real^N) IN s)` THEN + FIRST_ASSUM(SUBST1_TAC o SYM) THEN + REWRITE_TAC[IN_INTER; IN_INTERS] THEN + ASM_REWRITE_TAC[REAL_ARITH `a:real > b <=> ~(a <= b)`] THEN + ASM SET_TAC[]; + ALL_TAC] THEN + SUBGOAL_THEN `~(z:real^N = x)` ASSUME_TAC THENL + [ASM_MESON_TAC[]; ALL_TAC] THEN + MP_TAC(ISPECL [`s:real^N->bool`; `f:(real^N->bool)->bool`; + `a:(real^N->bool)->real^N`; `b:(real^N->bool)->real`] + RELATIVE_INTERIOR_POLYHEDRON_EXPLICIT) THEN + ASM_REWRITE_TAC[] THEN ANTS_TAC THENL + [FIRST_ASSUM ACCEPT_TAC; ALL_TAC] THEN + GEN_REWRITE_TAC LAND_CONV [EXTENSION] THEN + DISCH_THEN(MP_TAC o SPEC `x:real^N`) THEN + ASM_REWRITE_TAC[IN_ELIM_THM] THEN + DISCH_THEN(fun th -> + MP_TAC(SPEC `h:real^N->bool` th) THEN ASM_REWRITE_TAC[] THEN + DISCH_TAC THEN ASSUME_TAC th) THEN + SUBGOAL_THEN `(a:(real^N->bool)->real^N) h dot x < a h dot z` + ASSUME_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN + ABBREV_TAC `l = (b h - (a:(real^N->bool)->real^N) h dot x) / + (a h dot z - a h dot x)` THEN + SUBGOAL_THEN `&0 < l /\ l < &1` STRIP_ASSUME_TAC THENL + [EXPAND_TAC "l" THEN + ASM_SIMP_TAC[REAL_LT_LDIV_EQ; REAL_LT_RDIV_EQ; REAL_SUB_LT] THEN + ASM_REAL_ARITH_TAC; + ALL_TAC] THEN + ABBREV_TAC `w:real^N = (&1 - l) % x + l % z:real^N` THEN + SUBGOAL_THEN + `!i. i IN f /\ ~(i = h) ==> (a:(real^N->bool)->real^N) i dot w < b i` + ASSUME_TAC THENL + [X_GEN_TAC `i:real^N->bool` THEN STRIP_TAC THEN EXPAND_TAC "w" THEN + REWRITE_TAC[DOT_RADD; DOT_RMUL] THEN + MATCH_MP_TAC(REAL_ARITH + `(&1 - l) * x < (&1 - l) * z /\ l * y <= l * z + ==> (&1 - l) * x + l * y < z`) THEN + ASM_SIMP_TAC[REAL_LE_LMUL_EQ; REAL_LT_IMP_LE; + REAL_LT_LMUL_EQ; REAL_SUB_LT] THEN + UNDISCH_TAC `!t:real^N->bool. t IN f /\ ~(t = h) ==> z IN t` THEN + DISCH_THEN(MP_TAC o SPEC `i:real^N->bool`) THEN ASM SET_TAC[]; + ALL_TAC] THEN + SUBGOAL_THEN `(a:(real^N->bool)->real^N) h dot w = b h` ASSUME_TAC THENL + [EXPAND_TAC "w" THEN REWRITE_TAC[VECTOR_ARITH + `(&1 - l) % x + l % z:real^N = x + l % (z - x)`] THEN + EXPAND_TAC "l" THEN REWRITE_TAC[DOT_RADD; DOT_RSUB; DOT_RMUL] THEN + ASM_SIMP_TAC[REAL_DIV_RMUL; REAL_LT_IMP_NE; REAL_SUB_0] THEN + REAL_ARITH_TAC; + ALL_TAC] THEN + SUBGOAL_THEN `(w:real^N) IN s` ASSUME_TAC THENL + [FIRST_ASSUM(fun th -> GEN_REWRITE_TAC RAND_CONV [th]) THEN + REWRITE_TAC[IN_INTER; IN_INTERS] THEN CONJ_TAC THENL + [EXPAND_TAC "w" THEN + MATCH_MP_TAC(REWRITE_RULE[AFFINE_ALT] AFFINE_AFFINE_HULL) THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC HULL_INC THEN + ASM_MESON_TAC[RELATIVE_INTERIOR_SUBSET; SUBSET]; + ALL_TAC] THEN + X_GEN_TAC `i:real^N->bool` THEN DISCH_TAC THEN + ASM_CASES_TAC `i:real^N->bool = h` THENL + [ASM SET_TAC[REAL_LE_REFL]; ALL_TAC] THEN + SUBGOAL_THEN `convex(i:real^N->bool)` MP_TAC THENL + [REPEAT(FIRST_X_ASSUM(MP_TAC o C MATCH_MP + (ASSUME `(i:real^N->bool) IN f`))) THEN + REPEAT(DISCH_THEN(fun th -> ONCE_REWRITE_TAC[th])) THEN + REWRITE_TAC[CONVEX_HALFSPACE_LE]; + ALL_TAC] THEN + REWRITE_TAC[CONVEX_ALT] THEN EXPAND_TAC "w" THEN + DISCH_THEN MATCH_MP_TAC THEN + ASM_SIMP_TAC[] THEN FIRST_X_ASSUM(MP_TAC o CONJUNCT1) THEN + FIRST_ASSUM(fun t -> GEN_REWRITE_TAC (LAND_CONV o RAND_CONV) [t]) THEN + REWRITE_TAC[IN_INTER; IN_INTERS] THEN ASM_SIMP_TAC[REAL_LT_IMP_LE]; + ALL_TAC] THEN + CONJ_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN + ONCE_REWRITE_TAC[GSYM AFF_DIM_AFFINE_HULL] THEN + SUBGOAL_THEN + `affine hull (s INTER {x | (a:(real^N->bool)->real^N) h dot x = b h}) = + (affine hull s) INTER {x | a h dot x = b h}` + SUBST1_TAC THENL + [ALL_TAC; + SIMP_TAC[AFF_DIM_AFFINE_INTER_HYPERPLANE; AFFINE_AFFINE_HULL] THEN + COND_CASES_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + COND_CASES_TAC THENL [ASM SET_TAC[REAL_LT_REFL]; REFL_TAC]] THEN + MATCH_MP_TAC SUBSET_ANTISYM THEN REWRITE_TAC[SUBSET_INTER] THEN + REPEAT CONJ_TAC THENL + [MATCH_MP_TAC HULL_MONO THEN SET_TAC[]; + MATCH_MP_TAC(SET_RULE + `s SUBSET affine hull t /\ affine hull t = t ==> s SUBSET t`) THEN + REWRITE_TAC[AFFINE_HULL_EQ; AFFINE_HYPERPLANE] THEN + MATCH_MP_TAC HULL_MONO THEN SET_TAC[]; + ALL_TAC] THEN + REWRITE_TAC[SUBSET; IN_INTER; IN_ELIM_THM] THEN + X_GEN_TAC `y:real^N` THEN STRIP_TAC THEN + SUBGOAL_THEN + `?t. &0 < t /\ + !j. j IN f /\ ~(j:real^N->bool = h) + ==> t * (a j dot y - a j dot w) <= b j - a j dot (w:real^N)` + STRIP_ASSUME_TAC THENL + [ASM_CASES_TAC `f DELETE (h:real^N->bool) = {}` THENL + [ASM_REWRITE_TAC[GSYM IN_DELETE; NOT_IN_EMPTY] THEN + EXISTS_TAC `&1` THEN REWRITE_TAC[REAL_LT_01]; + ALL_TAC] THEN + EXISTS_TAC `inf (IMAGE + (\j. if &0 < a j dot y - a j dot (w:real^N) + then (b j - a j dot w) / (a j dot y - a j dot w) + else &1) (f DELETE (h:real^N->bool)))` THEN + MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN CONJ_TAC THENL + [ASM_SIMP_TAC[REAL_LT_INF_FINITE; FINITE_IMAGE; FINITE_DELETE; + IMAGE_EQ_EMPTY; FORALL_IN_IMAGE; IN_DELETE] THEN + ONCE_REWRITE_TAC[COND_RAND] THEN ONCE_REWRITE_TAC[COND_RATOR] THEN + ASM_SIMP_TAC[REAL_LT_DIV; REAL_SUB_LT; REAL_LT_01; COND_ID]; + REWRITE_TAC[REAL_SUB_LT] THEN DISCH_TAC] THEN + X_GEN_TAC `j:real^N->bool` THEN STRIP_TAC THEN + ASM_CASES_TAC `a j dot (w:real^N) < a(j:real^N->bool) dot y` THENL + [ASM_SIMP_TAC[GSYM REAL_LE_RDIV_EQ; REAL_INF_LE_FINITE; REAL_SUB_LT; + FINITE_IMAGE; FINITE_DELETE; IMAGE_EQ_EMPTY] THEN + REWRITE_TAC[EXISTS_IN_IMAGE] THEN EXISTS_TAC `j:real^N->bool` THEN + ASM_REWRITE_TAC[IN_DELETE; REAL_LE_REFL]; + MATCH_MP_TAC(REAL_ARITH `&0 <= --x /\ &0 < y ==> x <= y`) THEN + ASM_SIMP_TAC[REAL_SUB_LT; GSYM REAL_MUL_RNEG; REAL_LE_MUL_EQ] THEN + ASM_REAL_ARITH_TAC]; + ALL_TAC] THEN + ABBREV_TAC `c:real^N = (&1 - t) % w + t % y` THEN + SUBGOAL_THEN `y:real^N = (&1 - inv t) % w + inv(t) % c` SUBST1_TAC THENL + [EXPAND_TAC "c" THEN + REWRITE_TAC[VECTOR_ADD_LDISTRIB; VECTOR_MUL_ASSOC] THEN + ASM_SIMP_TAC[REAL_MUL_LINV; REAL_LT_IMP_NZ; + REAL_FIELD `&0 < x ==> inv x * (&1 - x) = inv x - &1`] THEN + VECTOR_ARITH_TAC; + ALL_TAC] THEN + MATCH_MP_TAC(REWRITE_RULE[AFFINE_ALT] AFFINE_AFFINE_HULL) THEN + CONJ_TAC THEN MATCH_MP_TAC HULL_INC THEN + ASM_REWRITE_TAC[IN_INTER; IN_ELIM_THM] THEN + MATCH_MP_TAC(TAUT `b /\ (b ==> a) ==> a /\ b`) THEN CONJ_TAC THENL + [EXPAND_TAC "c" THEN REWRITE_TAC[DOT_RADD; DOT_RMUL] THEN + ASM_REWRITE_TAC[] THEN CONV_TAC REAL_RING; + DISCH_TAC] THEN + FIRST_ASSUM(fun t -> GEN_REWRITE_TAC RAND_CONV [t]) THEN + REWRITE_TAC[IN_INTER; IN_INTERS] THEN CONJ_TAC THENL + [EXPAND_TAC "c" THEN + MATCH_MP_TAC(REWRITE_RULE[AFFINE_ALT] AFFINE_AFFINE_HULL) THEN + ASM_SIMP_TAC[HULL_INC]; + ALL_TAC] THEN + X_GEN_TAC `j:real^N->bool` THEN DISCH_TAC THEN + FIRST_X_ASSUM(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC o C MATCH_MP + (ASSUME `(j:real^N->bool) IN f`)) THEN + DISCH_THEN SUBST1_TAC THEN REWRITE_TAC[IN_ELIM_THM] THEN + ASM_CASES_TAC `j:real^N->bool = h` THEN ASM_SIMP_TAC[REAL_EQ_IMP_LE] THEN + EXPAND_TAC "c" THEN REWRITE_TAC[DOT_RADD; DOT_RMUL] THEN + REWRITE_TAC[REAL_ARITH + `(&1 - t) * x + t * y <= z <=> t * (y - x) <= z - x`] THEN + ASM_SIMP_TAC[]; + ALL_TAC] THEN + X_GEN_TAC `c:real^N->bool` THEN EQ_TAC THENL + [ALL_TAC; STRIP_TAC THEN ASM_SIMP_TAC[]] THEN + REWRITE_TAC[facet_of] THEN STRIP_TAC THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP FACE_OF_IMP_CONVEX) THEN + SUBGOAL_THEN `~(relative_interior(c:real^N->bool) = {})` MP_TAC THENL + [ASM_SIMP_TAC[RELATIVE_INTERIOR_EQ_EMPTY]; ALL_TAC] THEN + REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN + DISCH_THEN(X_CHOOSE_TAC `x:real^N`) THEN + MP_TAC(ISPECL [`s:real^N->bool`; `f:(real^N->bool)->bool`; + `a:(real^N->bool)->real^N`; `b:(real^N->bool)->real`] + RELATIVE_INTERIOR_POLYHEDRON_EXPLICIT) THEN + ASM_REWRITE_TAC[] THEN ANTS_TAC THENL [FIRST_ASSUM ACCEPT_TAC; ALL_TAC] THEN + GEN_REWRITE_TAC LAND_CONV [EXTENSION] THEN + DISCH_THEN(MP_TAC o SPEC `x:real^N`) THEN ASM_REWRITE_TAC[IN_ELIM_THM] THEN + SUBGOAL_THEN `~(c:real^N->bool = s)` ASSUME_TAC THENL + [ASM_MESON_TAC[INT_ARITH`~(i:int = i - &1)`]; ALL_TAC] THEN + SUBGOAL_THEN `~((x:real^N) IN relative_interior s)` ASSUME_TAC THENL + [UNDISCH_TAC `~(c:real^N->bool = s)` THEN REWRITE_TAC[CONTRAPOS_THM] THEN + DISCH_TAC THEN MATCH_MP_TAC FACE_OF_EQ THEN + EXISTS_TAC `s:real^N->bool` THEN ASM_SIMP_TAC[FACE_OF_REFL] THEN + ASM SET_TAC[]; + ALL_TAC] THEN + SUBGOAL_THEN `(x:real^N) IN s` MP_TAC THENL + [FIRST_X_ASSUM(MATCH_MP_TAC o REWRITE_RULE[SUBSET] o MATCH_MP + FACE_OF_IMP_SUBSET) THEN + ASM_SIMP_TAC[REWRITE_RULE[SUBSET] RELATIVE_INTERIOR_SUBSET]; + ALL_TAC] THEN + ASM_SIMP_TAC[] THEN DISCH_THEN(fun th -> ASSUME_TAC th THEN MP_TAC th) THEN + FIRST_ASSUM(fun t -> GEN_REWRITE_TAC (LAND_CONV o RAND_CONV) [t]) THEN + REWRITE_TAC[IN_INTER; IN_INTERS] THEN STRIP_TAC THEN + REWRITE_TAC[NOT_FORALL_THM] THEN MATCH_MP_TAC MONO_EXISTS THEN + X_GEN_TAC `i:real^N->bool` THEN REWRITE_TAC[NOT_IMP] THEN STRIP_TAC THEN + ASM_REWRITE_TAC[] THEN + SUBGOAL_THEN `(a:(real^N->bool)->real^N) i dot x = b i` ASSUME_TAC THENL + [MATCH_MP_TAC(REAL_ARITH `x <= y /\ ~(x < y) ==> x = y`) THEN + ASM_REWRITE_TAC[] THEN UNDISCH_THEN + `!t:real^N->bool. t IN f ==> x IN t` (MP_TAC o SPEC `i:real^N->bool`) THEN + ASM_REWRITE_TAC[] THEN FIRST_X_ASSUM(MP_TAC o CONJUNCT2 o C MATCH_MP + (ASSUME `(i:real^N->bool) IN f`)) THEN SET_TAC[]; + ALL_TAC] THEN + SUBGOAL_THEN `c SUBSET (s INTER {x:real^N | a(i:real^N->bool) dot x = b i})` + ASSUME_TAC THENL + [MATCH_MP_TAC SUBSET_OF_FACE_OF THEN EXISTS_TAC `s:real^N->bool` THEN + ASM_SIMP_TAC[FACE_OF_IMP_SUBSET] THEN + RULE_ASSUM_TAC(REWRITE_RULE[facet_of]) THEN ASM_SIMP_TAC[] THEN + REWRITE_TAC[DISJOINT; GSYM MEMBER_NOT_EMPTY] THEN + EXISTS_TAC `x:real^N` THEN ASM_REWRITE_TAC[IN_INTER; IN_ELIM_THM]; + ALL_TAC] THEN + SUBGOAL_THEN `c face_of (s INTER {x:real^N | a(i:real^N->bool) dot x = b i})` + ASSUME_TAC THENL + [MP_TAC(ISPECL [`c:real^N->bool`; `s:real^N->bool`; + `s INTER {x:real^N | a(i:real^N->bool) dot x = b i}`] + FACE_OF_FACE) THEN + RULE_ASSUM_TAC(REWRITE_RULE[facet_of]) THEN ASM_SIMP_TAC[]; + ALL_TAC] THEN + MATCH_MP_TAC(TAUT `(~p ==> F) ==> p`) THEN DISCH_TAC THEN + SUBGOAL_THEN + `aff_dim(c:real^N->bool) < + aff_dim(s INTER {x:real^N | a(i:real^N->bool) dot x = b i})` + MP_TAC THENL + [MATCH_MP_TAC FACE_OF_AFF_DIM_LT THEN + ASM_SIMP_TAC[CONVEX_INTER; CONVEX_HYPERPLANE]; + RULE_ASSUM_TAC(REWRITE_RULE[facet_of]) THEN ASM_SIMP_TAC[INT_LT_REFL]]);; + +let FACE_OF_POLYHEDRON_SUBSET_EXPLICIT = prove + (`!s:real^N->bool f a b. + FINITE f /\ + s = affine hull s INTER INTERS f /\ + (!h. h IN f ==> ~(a h = vec 0) /\ h = {x | a h dot x <= b h}) /\ + (!f'. f' PSUBSET f ==> s PSUBSET affine hull s INTER INTERS f') + ==> !c. c face_of s /\ ~(c = {}) /\ ~(c = s) + ==> ?h. h IN f /\ c SUBSET (s INTER {x | a h dot x = b h})`, + REPEAT GEN_TAC THEN ASM_CASES_TAC `f:(real^N->bool)->bool = {}` THENL + [DISCH_THEN(MP_TAC o SYM o CONJUNCT1 o CONJUNCT2) THEN + ASM_REWRITE_TAC[INTERS_0; INTER_UNIV; AFFINE_HULL_EQ] THEN + MESON_TAC[FACE_OF_AFFINE_TRIVIAL]; + ALL_TAC] THEN + DISCH_THEN(fun th -> STRIP_ASSUME_TAC th THEN MP_TAC th) THEN + DISCH_THEN(ASSUME_TAC o MATCH_MP FACET_OF_POLYHEDRON_EXPLICIT) THEN + REPEAT STRIP_TAC THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP FACE_OF_IMP_CONVEX) THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP FACE_OF_IMP_SUBSET) THEN + SUBGOAL_THEN `polyhedron(s:real^N->bool)` ASSUME_TAC THENL + [REWRITE_TAC[POLYHEDRON_INTER_AFFINE] THEN + REWRITE_TAC[RIGHT_IMP_EXISTS_THM; SKOLEM_THM] THEN ASM_MESON_TAC[]; + ALL_TAC] THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP POLYHEDRON_IMP_CONVEX) THEN + SUBGOAL_THEN + `!h:real^N->bool. + h IN f ==> (s INTER {x:real^N | a h dot x = b h}) face_of s` + ASSUME_TAC THENL + [REPEAT STRIP_TAC THEN + MATCH_MP_TAC FACE_OF_INTER_SUPPORTING_HYPERPLANE_LE THEN CONJ_TAC THENL + [MATCH_MP_TAC POLYHEDRON_IMP_CONVEX THEN + REWRITE_TAC[POLYHEDRON_INTER_AFFINE] THEN + REWRITE_TAC[RIGHT_IMP_EXISTS_THM; SKOLEM_THM] THEN ASM_MESON_TAC[]; + X_GEN_TAC `x:real^N` THEN FIRST_X_ASSUM SUBST1_TAC THEN + REWRITE_TAC[IN_INTER; IN_INTERS] THEN + DISCH_THEN(MP_TAC o SPEC `h:real^N->bool` o CONJUNCT2) THEN + ASM_REWRITE_TAC[] THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `h:real^N->bool`) THEN + ASM_REWRITE_TAC[] THEN ASM SET_TAC[]]; + ALL_TAC] THEN + SUBGOAL_THEN `~(relative_interior(c:real^N->bool) = {})` MP_TAC THENL + [ASM_SIMP_TAC[RELATIVE_INTERIOR_EQ_EMPTY]; ALL_TAC] THEN + REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN + DISCH_THEN(X_CHOOSE_TAC `x:real^N`) THEN + MP_TAC(ISPECL [`s:real^N->bool`; `f:(real^N->bool)->bool`; + `a:(real^N->bool)->real^N`; `b:(real^N->bool)->real`] + RELATIVE_INTERIOR_POLYHEDRON_EXPLICIT) THEN + ASM_REWRITE_TAC[] THEN ANTS_TAC THENL [FIRST_ASSUM ACCEPT_TAC; ALL_TAC] THEN + GEN_REWRITE_TAC LAND_CONV [EXTENSION] THEN + DISCH_THEN(MP_TAC o SPEC `x:real^N`) THEN ASM_REWRITE_TAC[IN_ELIM_THM] THEN + SUBGOAL_THEN `~((x:real^N) IN relative_interior s)` ASSUME_TAC THENL + [UNDISCH_TAC `~(c:real^N->bool = s)` THEN REWRITE_TAC[CONTRAPOS_THM] THEN + DISCH_TAC THEN MATCH_MP_TAC FACE_OF_EQ THEN + EXISTS_TAC `s:real^N->bool` THEN ASM_SIMP_TAC[FACE_OF_REFL] THEN + ASM SET_TAC[]; + ALL_TAC] THEN + SUBGOAL_THEN `(x:real^N) IN s` MP_TAC THENL + [FIRST_X_ASSUM(MATCH_MP_TAC o REWRITE_RULE[SUBSET] o MATCH_MP + FACE_OF_IMP_SUBSET) THEN + ASM_SIMP_TAC[REWRITE_RULE[SUBSET] RELATIVE_INTERIOR_SUBSET]; + ALL_TAC] THEN + ASM_SIMP_TAC[] THEN DISCH_THEN(fun th -> ASSUME_TAC th THEN MP_TAC th) THEN + FIRST_ASSUM(fun t -> GEN_REWRITE_TAC (LAND_CONV o RAND_CONV) [t]) THEN + REWRITE_TAC[IN_INTER; IN_INTERS] THEN STRIP_TAC THEN + REWRITE_TAC[NOT_FORALL_THM] THEN MATCH_MP_TAC MONO_EXISTS THEN + X_GEN_TAC `i:real^N->bool` THEN REWRITE_TAC[NOT_IMP] THEN STRIP_TAC THEN + ASM_REWRITE_TAC[] THEN + SUBGOAL_THEN `(a:(real^N->bool)->real^N) i dot x = b i` ASSUME_TAC THENL + [MATCH_MP_TAC(REAL_ARITH `x <= y /\ ~(x < y) ==> x = y`) THEN + ASM_REWRITE_TAC[] THEN UNDISCH_THEN + `!t:real^N->bool. t IN f ==> x IN t` (MP_TAC o SPEC `i:real^N->bool`) THEN + ASM_REWRITE_TAC[] THEN FIRST_X_ASSUM(MP_TAC o CONJUNCT2 o C MATCH_MP + (ASSUME `(i:real^N->bool) IN f`)) THEN SET_TAC[]; + ALL_TAC] THEN + MATCH_MP_TAC SUBSET_OF_FACE_OF THEN EXISTS_TAC `s:real^N->bool` THEN + ASM_SIMP_TAC[FACE_OF_IMP_SUBSET] THEN + RULE_ASSUM_TAC(REWRITE_RULE[facet_of]) THEN ASM_SIMP_TAC[] THEN + REWRITE_TAC[DISJOINT; GSYM MEMBER_NOT_EMPTY] THEN + EXISTS_TAC `x:real^N` THEN ASM_REWRITE_TAC[IN_INTER; IN_ELIM_THM]);; + +let FACE_OF_POLYHEDRON_EXPLICIT = prove + (`!s:real^N->bool f a b. + FINITE f /\ + s = affine hull s INTER INTERS f /\ + (!h. h IN f ==> ~(a h = vec 0) /\ h = {x | a h dot x <= b h}) /\ + (!f'. f' PSUBSET f ==> s PSUBSET affine hull s INTER INTERS f') + ==> !c. c face_of s /\ ~(c = {}) /\ ~(c = s) + ==> c = INTERS {s INTER {x | a h dot x = b h} |h| + h IN f /\ + c SUBSET (s INTER {x | a h dot x = b h})}`, + let lemma = prove + (`!t s. (!a. P a ==> t SUBSET s INTER INTERS {f x | P x}) + ==> t SUBSET INTERS {s INTER f x | P x}`, + ONCE_REWRITE_TAC[SIMPLE_IMAGE_GEN] THEN + REWRITE_TAC[INTERS_IMAGE] THEN SET_TAC[]) in + REPEAT GEN_TAC THEN + DISCH_THEN(fun th -> STRIP_ASSUME_TAC th THEN MP_TAC th) THEN + DISCH_THEN(ASSUME_TAC o MATCH_MP FACET_OF_POLYHEDRON_EXPLICIT) THEN + REPEAT STRIP_TAC THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP FACE_OF_IMP_CONVEX) THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP FACE_OF_IMP_SUBSET) THEN + SUBGOAL_THEN `polyhedron(s:real^N->bool)` ASSUME_TAC THENL + [REWRITE_TAC[POLYHEDRON_INTER_AFFINE] THEN + REWRITE_TAC[RIGHT_IMP_EXISTS_THM; SKOLEM_THM] THEN ASM_MESON_TAC[]; + ALL_TAC] THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP POLYHEDRON_IMP_CONVEX) THEN + SUBGOAL_THEN + `!h:real^N->bool. + h IN f ==> (s INTER {x:real^N | a h dot x = b h}) face_of s` + ASSUME_TAC THENL + [REPEAT STRIP_TAC THEN + MATCH_MP_TAC FACE_OF_INTER_SUPPORTING_HYPERPLANE_LE THEN CONJ_TAC THENL + [MATCH_MP_TAC POLYHEDRON_IMP_CONVEX THEN + REWRITE_TAC[POLYHEDRON_INTER_AFFINE] THEN + REWRITE_TAC[RIGHT_IMP_EXISTS_THM; SKOLEM_THM] THEN ASM_MESON_TAC[]; + X_GEN_TAC `x:real^N` THEN FIRST_X_ASSUM SUBST1_TAC THEN + REWRITE_TAC[IN_INTER; IN_INTERS] THEN + DISCH_THEN(MP_TAC o SPEC `h:real^N->bool` o CONJUNCT2) THEN + ASM_REWRITE_TAC[] THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `h:real^N->bool`) THEN + ASM_REWRITE_TAC[] THEN ASM SET_TAC[]]; + ALL_TAC] THEN + SUBGOAL_THEN `~(relative_interior(c:real^N->bool) = {})` MP_TAC THENL + [ASM_SIMP_TAC[RELATIVE_INTERIOR_EQ_EMPTY]; ALL_TAC] THEN + REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `z:real^N` THEN DISCH_TAC THEN + SUBGOAL_THEN `(z:real^N) IN s` ASSUME_TAC THENL + [FIRST_X_ASSUM(MATCH_MP_TAC o REWRITE_RULE[SUBSET]) THEN + MATCH_MP_TAC(REWRITE_RULE[SUBSET] RELATIVE_INTERIOR_SUBSET) THEN + ASM_REWRITE_TAC[]; + ALL_TAC] THEN + MATCH_MP_TAC FACE_OF_EQ THEN EXISTS_TAC `s:real^N->bool` THEN + ASM_REWRITE_TAC[] THEN CONJ_TAC THENL + [MATCH_MP_TAC FACE_OF_INTERS THEN ASM_SIMP_TAC[FORALL_IN_GSPEC] THEN + ONCE_REWRITE_TAC[SIMPLE_IMAGE_GEN] THEN REWRITE_TAC[IMAGE_EQ_EMPTY] THEN + REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; IN_ELIM_THM] THEN + MP_TAC(ISPECL [`s:real^N->bool`; `f:(real^N->bool)->bool`; + `a:(real^N->bool)->real^N`; `b:(real^N->bool)->real`] + FACE_OF_POLYHEDRON_SUBSET_EXPLICIT) THEN + ASM_REWRITE_TAC[] THEN ANTS_TAC THENL[FIRST_ASSUM ACCEPT_TAC; ALL_TAC] THEN + DISCH_THEN MATCH_MP_TAC THEN ASM_REWRITE_TAC[]; + ALL_TAC] THEN + SUBGOAL_THEN + `{s INTER {x | a(h:real^N->bool) dot x = b h} |h| + h IN f /\ c SUBSET (s INTER {x:real^N | a h dot x = b h})} = + {s INTER {x | a(h:real^N->bool) dot x = b h} |h| + h IN f /\ z IN s INTER {x:real^N | a h dot x = b h}}` + SUBST1_TAC THENL + [MATCH_MP_TAC(SET_RULE + `(!x. P x <=> Q x) ==> {f x | P x} = {f x | Q x}`) THEN + X_GEN_TAC `h:real^N->bool` THEN EQ_TAC THEN STRIP_TAC THEN + ASM_REWRITE_TAC[] THENL + [FIRST_X_ASSUM(MATCH_MP_TAC o REWRITE_RULE[SUBSET]) THEN + MATCH_MP_TAC(REWRITE_RULE[SUBSET] RELATIVE_INTERIOR_SUBSET) THEN + ASM_REWRITE_TAC[]; + MATCH_MP_TAC SUBSET_OF_FACE_OF THEN EXISTS_TAC `s:real^N->bool` THEN + ASM_SIMP_TAC[] THEN ASM SET_TAC[]]; + ALL_TAC] THEN + REWRITE_TAC[DISJOINT; GSYM MEMBER_NOT_EMPTY; IN_INTER] THEN + EXISTS_TAC `z:real^N` THEN ASM_REWRITE_TAC[IN_ELIM_THM] THEN + SUBGOAL_THEN + `?e. &0 < e /\ !h. h IN f /\ a(h:real^N->bool) dot z < b h + ==> ball(z,e) SUBSET {w:real^N | a h dot w < b h}` + (CHOOSE_THEN (CONJUNCTS_THEN2 ASSUME_TAC (LABEL_TAC "*"))) THENL + [REWRITE_TAC[SET_RULE + `(!h. P h ==> s SUBSET t h) <=> s SUBSET INTERS (IMAGE t {h | P h})`] THEN + MATCH_MP_TAC(MESON[OPEN_CONTAINS_BALL] + `open s /\ x IN s ==> ?e. &0 < e /\ ball(x,e) SUBSET s`) THEN + SIMP_TAC[IN_INTERS; FORALL_IN_IMAGE; IN_ELIM_THM] THEN + MATCH_MP_TAC OPEN_INTERS THEN + ASM_SIMP_TAC[FORALL_IN_IMAGE; FINITE_IMAGE; FINITE_RESTRICT] THEN + REWRITE_TAC[OPEN_HALFSPACE_LT]; + ALL_TAC] THEN + ASM_REWRITE_TAC[IN_RELATIVE_INTERIOR] THEN + ASM_SIMP_TAC[IN_INTERS; FORALL_IN_GSPEC; IN_ELIM_THM; IN_INTER] THEN + EXISTS_TAC `e:real` THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC lemma THEN X_GEN_TAC `i:real^N->bool` THEN STRIP_TAC THEN + FIRST_ASSUM(fun th -> GEN_REWRITE_TAC (RAND_CONV o LAND_CONV) [th]) THEN + MATCH_MP_TAC(SET_RULE + `ae SUBSET as /\ ae SUBSET hs /\ + b INTER hs SUBSET fs + ==> (b INTER ae) SUBSET (as INTER fs) INTER hs`) THEN + REPEAT CONJ_TAC THENL + [MATCH_MP_TAC HULL_MONO THEN + REWRITE_TAC[SUBSET; IN_INTERS; FORALL_IN_GSPEC] THEN ASM SET_TAC[]; + SIMP_TAC[SET_RULE `s SUBSET INTERS f <=> !t. t IN f ==> s SUBSET t`] THEN + REWRITE_TAC[FORALL_IN_GSPEC] THEN X_GEN_TAC `j:real^N->bool` THEN + STRIP_TAC THEN MATCH_MP_TAC HULL_MINIMAL THEN + REWRITE_TAC[AFFINE_HYPERPLANE] THEN + REWRITE_TAC[SUBSET; IN_INTERS; FORALL_IN_GSPEC] THEN ASM SET_TAC[]; + ALL_TAC] THEN + REWRITE_TAC[SET_RULE `s SUBSET INTERS f <=> !t. t IN f ==> s SUBSET t`] THEN + X_GEN_TAC `j:real^N->bool` THEN DISCH_TAC THEN + SUBGOAL_THEN `(a:(real^N->bool)->real^N) j dot z <= b j` MP_TAC THENL + [ASM SET_TAC[]; REWRITE_TAC[REAL_LE_LT]] THEN + STRIP_TAC THENL [ASM SET_TAC[REAL_LT_IMP_LE]; ALL_TAC] THEN + MATCH_MP_TAC(SET_RULE + `(?s. s IN f /\ s SUBSET t) ==> u INTER INTERS f SUBSET t`) THEN + REWRITE_TAC[EXISTS_IN_GSPEC] THEN EXISTS_TAC `j:real^N->bool` THEN + ASM SET_TAC[REAL_LE_REFL]);; + +(* ------------------------------------------------------------------------- *) +(* More general corollaries from the explicit representation. *) +(* ------------------------------------------------------------------------- *) + +let FACET_OF_POLYHEDRON = prove + (`!s:real^N->bool c. + polyhedron s /\ c facet_of s + ==> ?a b. ~(a = vec 0) /\ + s SUBSET {x | a dot x <= b} /\ + c = s INTER {x | a dot x = b}`, + REPEAT STRIP_TAC THEN FIRST_ASSUM + (MP_TAC o GEN_REWRITE_RULE I [POLYHEDRON_INTER_AFFINE_MINIMAL]) THEN + GEN_REWRITE_TAC (LAND_CONV o TOP_DEPTH_CONV) + [RIGHT_IMP_EXISTS_THM; SKOLEM_THM] THEN + SIMP_TAC[LEFT_IMP_EXISTS_THM; RIGHT_AND_EXISTS_THM; LEFT_AND_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC + [`f:(real^N->bool)->bool`; `a:(real^N->bool)->real^N`; + `b:(real^N->bool)->real`] THEN + STRIP_TAC THEN + MP_TAC(ISPECL [`s:real^N->bool`; `f:(real^N->bool)->bool`; + `a:(real^N->bool)->real^N`; `b:(real^N->bool)->real`] + FACET_OF_POLYHEDRON_EXPLICIT) THEN + ANTS_TAC THENL [ASM_REWRITE_TAC[] THEN ASM_MESON_TAC[]; ALL_TAC] THEN + DISCH_THEN(MP_TAC o SPEC `c:real^N->bool`) THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `i:real^N->bool` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `(a:(real^N->bool)->real^N) i` THEN + EXISTS_TAC `(b:(real^N->bool)->real) i` THEN ASM_SIMP_TAC[] THEN + FIRST_X_ASSUM(fun th -> GEN_REWRITE_TAC LAND_CONV [th]) THEN + MATCH_MP_TAC(SET_RULE `t SUBSET u ==> (s INTER t) SUBSET u`) THEN + MATCH_MP_TAC(SET_RULE `t IN f ==> INTERS f SUBSET t`) THEN ASM_MESON_TAC[]);; + +let FACE_OF_POLYHEDRON = prove + (`!s:real^N->bool c. + polyhedron s /\ c face_of s /\ ~(c = {}) /\ ~(c = s) + ==> c = INTERS {f | f facet_of s /\ c SUBSET f}`, + REPEAT STRIP_TAC THEN FIRST_ASSUM + (MP_TAC o GEN_REWRITE_RULE I [POLYHEDRON_INTER_AFFINE_MINIMAL]) THEN + REWRITE_TAC[RIGHT_IMP_EXISTS_THM; SKOLEM_THM] THEN + SIMP_TAC[LEFT_IMP_EXISTS_THM; RIGHT_AND_EXISTS_THM; LEFT_AND_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC + [`f:(real^N->bool)->bool`; `a:(real^N->bool)->real^N`; + `b:(real^N->bool)->real`] THEN + STRIP_TAC THEN + MP_TAC(ISPECL [`s:real^N->bool`; `f:(real^N->bool)->bool`; + `a:(real^N->bool)->real^N`; `b:(real^N->bool)->real`] + FACET_OF_POLYHEDRON_EXPLICIT) THEN + ANTS_TAC THENL [ASM_REWRITE_TAC[] THEN ASM_MESON_TAC[]; ALL_TAC] THEN + DISCH_THEN(fun th -> REWRITE_TAC[th]) THEN + MP_TAC(ISPECL [`s:real^N->bool`; `f:(real^N->bool)->bool`; + `a:(real^N->bool)->real^N`; `b:(real^N->bool)->real`] + FACE_OF_POLYHEDRON_EXPLICIT) THEN + ANTS_TAC THENL [ASM_REWRITE_TAC[] THEN ASM_MESON_TAC[]; ALL_TAC] THEN + DISCH_THEN(MP_TAC o SPEC `c:real^N->bool`) THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(fun th -> GEN_REWRITE_TAC LAND_CONV [th]) THEN + AP_TERM_TAC THEN GEN_REWRITE_TAC I [EXTENSION] THEN + X_GEN_TAC `h:real^N->bool` THEN REWRITE_TAC[IN_ELIM_THM] THEN MESON_TAC[]);; + +let FACE_OF_POLYHEDRON_SUBSET_FACET = prove + (`!s:real^N->bool c. + polyhedron s /\ c face_of s /\ ~(c = {}) /\ ~(c = s) + ==> ?f. f facet_of s /\ c SUBSET f`, + REPEAT STRIP_TAC THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP FACE_OF_IMP_SUBSET) THEN + MP_TAC(ISPECL [`s:real^N->bool`; `c:real^N->bool`] FACE_OF_POLYHEDRON) THEN + ASM_CASES_TAC `{f:real^N->bool | f facet_of s /\ c SUBSET f} = {}` THEN + ASM SET_TAC[]);; + +let EXPOSED_FACE_OF_POLYHEDRON = prove + (`!s f:real^N->bool. polyhedron s ==> (f exposed_face_of s <=> f face_of s)`, + REPEAT STRIP_TAC THEN EQ_TAC THENL [SIMP_TAC[exposed_face_of]; ALL_TAC] THEN + DISCH_TAC THEN ASM_CASES_TAC `f:real^N->bool = {}` THEN + ASM_REWRITE_TAC[EMPTY_EXPOSED_FACE_OF] THEN + ASM_CASES_TAC `f:real^N->bool = s` THEN + ASM_SIMP_TAC[EXPOSED_FACE_OF_REFL; POLYHEDRON_IMP_CONVEX] THEN + MP_TAC(ISPECL [`s:real^N->bool`; `f:real^N->bool`] FACE_OF_POLYHEDRON) THEN + ASM_REWRITE_TAC[] THEN DISCH_THEN SUBST1_TAC THEN + MATCH_MP_TAC EXPOSED_FACE_OF_INTERS THEN + REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; FORALL_IN_GSPEC] THEN + ASM_SIMP_TAC[FACE_OF_POLYHEDRON_SUBSET_FACET; IN_ELIM_THM] THEN + ASM_SIMP_TAC[exposed_face_of; FACET_OF_IMP_FACE_OF] THEN + ASM_MESON_TAC[FACET_OF_POLYHEDRON]);; + +let FACE_OF_POLYHEDRON_POLYHEDRON = prove + (`!s:real^N->bool c. polyhedron s /\ c face_of s ==> polyhedron c`, + REPEAT STRIP_TAC THEN FIRST_ASSUM + (MP_TAC o GEN_REWRITE_RULE I [POLYHEDRON_INTER_AFFINE_MINIMAL]) THEN + REWRITE_TAC[RIGHT_IMP_EXISTS_THM; SKOLEM_THM] THEN + SIMP_TAC[LEFT_IMP_EXISTS_THM; RIGHT_AND_EXISTS_THM; LEFT_AND_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC + [`f:(real^N->bool)->bool`; `a:(real^N->bool)->real^N`; + `b:(real^N->bool)->real`] THEN + STRIP_TAC THEN + MP_TAC(ISPECL [`s:real^N->bool`; `f:(real^N->bool)->bool`; + `a:(real^N->bool)->real^N`; `b:(real^N->bool)->real`] + FACE_OF_POLYHEDRON_EXPLICIT) THEN + ANTS_TAC THENL [ASM_REWRITE_TAC[] THEN ASM_MESON_TAC[]; ALL_TAC] THEN + DISCH_THEN(MP_TAC o SPEC `c:real^N->bool`) THEN ASM_REWRITE_TAC[] THEN + ASM_CASES_TAC `c:real^N->bool = {}` THEN + ASM_REWRITE_TAC[POLYHEDRON_EMPTY] THEN + ASM_CASES_TAC `c:real^N->bool = s` THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN SUBST1_TAC THEN MATCH_MP_TAC POLYHEDRON_INTERS THEN + REWRITE_TAC[FORALL_IN_GSPEC] THEN + ONCE_REWRITE_TAC[SIMPLE_IMAGE_GEN] THEN + ASM_SIMP_TAC[FINITE_IMAGE; FINITE_RESTRICT] THEN + REPEAT STRIP_TAC THEN REWRITE_TAC[IMAGE_ID] THEN + MATCH_MP_TAC POLYHEDRON_INTER THEN + ASM_REWRITE_TAC[POLYHEDRON_HYPERPLANE]);; + +let FINITE_POLYHEDRON_FACES = prove + (`!s:real^N->bool. polyhedron s ==> FINITE {f | f face_of s}`, + REPEAT STRIP_TAC THEN FIRST_ASSUM + (MP_TAC o GEN_REWRITE_RULE I [POLYHEDRON_INTER_AFFINE_MINIMAL]) THEN + REWRITE_TAC[RIGHT_IMP_EXISTS_THM; SKOLEM_THM] THEN + SIMP_TAC[LEFT_IMP_EXISTS_THM; RIGHT_AND_EXISTS_THM; LEFT_AND_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC + [`f:(real^N->bool)->bool`; `a:(real^N->bool)->real^N`; + `b:(real^N->bool)->real`] THEN + STRIP_TAC THEN + MATCH_MP_TAC(MESON[FINITE_DELETE] + `!a b. FINITE (s DELETE a DELETE b) ==> FINITE s`) THEN + MAP_EVERY EXISTS_TAC [`{}:real^N->bool`; `s:real^N->bool`] THEN + MATCH_MP_TAC FINITE_SUBSET THEN + EXISTS_TAC + `{INTERS {s INTER {x:real^N | a(h:real^N->bool) dot x = b h} | h | h IN f'} + |f'| f' SUBSET f}` THEN + GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [SIMPLE_IMAGE_GEN] THEN + ASM_SIMP_TAC[FINITE_POWERSET; FINITE_IMAGE] THEN + GEN_REWRITE_TAC I [SUBSET] THEN REWRITE_TAC[IN_DELETE; IN_ELIM_THM] THEN + MP_TAC(ISPECL [`s:real^N->bool`; `f:(real^N->bool)->bool`; + `a:(real^N->bool)->real^N`; `b:(real^N->bool)->real`] + FACE_OF_POLYHEDRON_EXPLICIT) THEN + ANTS_TAC THENL [ASM_REWRITE_TAC[] THEN ASM_MESON_TAC[]; ALL_TAC] THEN + MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `c:real^N->bool` THEN + DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN ASM_REWRITE_TAC[] THEN + DISCH_TAC THEN EXISTS_TAC + `{h:real^N->bool | + h IN f /\ c SUBSET s INTER {x:real^N | a h dot x = b h}}` THEN + CONJ_TAC THENL [SET_TAC[]; ALL_TAC] THEN + ASM_REWRITE_TAC[IN_ELIM_THM] THEN FIRST_ASSUM ACCEPT_TAC);; + +let FINITE_POLYHEDRON_EXPOSED_FACES = prove + (`!s:real^N->bool. polyhedron s ==> FINITE {f | f exposed_face_of s}`, + SIMP_TAC[EXPOSED_FACE_OF_POLYHEDRON; FINITE_POLYHEDRON_FACES]);; + +let FINITE_POLYHEDRON_EXTREME_POINTS = prove + (`!s:real^N->bool. polyhedron s ==> FINITE {v | v extreme_point_of s}`, + REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM FACE_OF_SING] THEN + ONCE_REWRITE_TAC[SET_RULE `{v} face_of s <=> {v} IN {f | f face_of s}`] THEN + MATCH_MP_TAC FINITE_FINITE_PREIMAGE THEN + ASM_SIMP_TAC[FINITE_POLYHEDRON_FACES] THEN X_GEN_TAC `f:real^N->bool` THEN + DISCH_TAC THEN ASM_CASES_TAC `!a:real^N. ~({a} = f)` THEN + ASM_REWRITE_TAC[EMPTY_GSPEC; FINITE_EMPTY] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [NOT_FORALL_THM]) THEN + REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + GEN_TAC THEN DISCH_THEN(SUBST1_TAC o SYM) THEN + REWRITE_TAC[SET_RULE `{v | {v} = {a}} = {a}`; FINITE_SING]);; + +let FINITE_POLYHEDRON_FACETS = prove + (`!s:real^N->bool. polyhedron s ==> FINITE {f | f facet_of s}`, + REWRITE_TAC[facet_of] THEN ONCE_REWRITE_TAC[SET_RULE + `{x | P x /\ Q x} = {x | x IN {x | P x} /\ Q x}`] THEN + SIMP_TAC[FINITE_RESTRICT; FINITE_POLYHEDRON_FACES]);; + +let RELATIVE_INTERIOR_OF_POLYHEDRON = prove + (`!s:real^N->bool. + polyhedron s + ==> relative_interior s = s DIFF UNIONS {f | f facet_of s}`, + REPEAT STRIP_TAC THEN FIRST_ASSUM + (MP_TAC o GEN_REWRITE_RULE I [POLYHEDRON_INTER_AFFINE_MINIMAL]) THEN + GEN_REWRITE_TAC (LAND_CONV o TOP_DEPTH_CONV) + [RIGHT_IMP_EXISTS_THM; SKOLEM_THM] THEN + SIMP_TAC[LEFT_IMP_EXISTS_THM; RIGHT_AND_EXISTS_THM; LEFT_AND_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC + [`f:(real^N->bool)->bool`; `a:(real^N->bool)->real^N`; + `b:(real^N->bool)->real`] THEN + STRIP_TAC THEN + MP_TAC(ISPECL [`s:real^N->bool`; `f:(real^N->bool)->bool`; + `a:(real^N->bool)->real^N`; `b:(real^N->bool)->real`] + FACET_OF_POLYHEDRON_EXPLICIT) THEN + MP_TAC(ISPECL [`s:real^N->bool`; `f:(real^N->bool)->bool`; + `a:(real^N->bool)->real^N`; `b:(real^N->bool)->real`] + RELATIVE_INTERIOR_POLYHEDRON_EXPLICIT) THEN + ASM_REWRITE_TAC[] THEN + ANTS_TAC THENL [ASM_MESON_TAC[]; DISCH_THEN SUBST1_TAC] THEN + ANTS_TAC THENL [ASM_MESON_TAC[]; DISCH_TAC] THEN + ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC(SET_RULE + `(!x. x IN s ==> P x \/ x IN t) /\ (!x. x IN t ==> ~P x) + ==> {x | x IN s /\ P x} = s DIFF t`) THEN + REWRITE_TAC[FORALL_IN_UNIONS] THEN + REWRITE_TAC[RIGHT_FORALL_IMP_THM; IMP_CONJ; FORALL_IN_GSPEC] THEN + CONJ_TAC THENL + [X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN + REWRITE_TAC[IN_UNIONS; IN_ELIM_THM] THEN + REWRITE_TAC[LEFT_AND_EXISTS_THM; TAUT `(a /\ b) /\ c <=> b /\ a /\ c`] THEN + ONCE_REWRITE_TAC[SWAP_EXISTS_THM] THEN + ASM_REWRITE_TAC[UNWIND_THM2; IN_ELIM_THM; IN_INTER] THEN + MATCH_MP_TAC(SET_RULE + `(!x. P x ==> Q x \/ R x) ==> (!x. P x ==> Q x) \/ (?x. P x /\ R x)`) THEN + X_GEN_TAC `h:real^N->bool` THEN DISCH_TAC THEN + REWRITE_TAC[GSYM REAL_LE_LT] THEN + SUBGOAL_THEN `(x:real^N) IN INTERS f` MP_TAC THENL + [ASM SET_TAC[]; ALL_TAC] THEN + REWRITE_TAC[IN_INTERS] THEN + DISCH_THEN(MP_TAC o SPEC `h:real^N->bool`) THEN + SUBGOAL_THEN `h = {x:real^N | a h dot x <= b h}` MP_TAC THENL + [ASM_MESON_TAC[]; ASM_REWRITE_TAC[] THEN SET_TAC[]]; + X_GEN_TAC `h:real^N->bool` THEN + DISCH_THEN(X_CHOOSE_THEN `g:real^N->bool` STRIP_ASSUME_TAC) THEN + X_GEN_TAC `x:real^N` THEN ASM_REWRITE_TAC[IN_INTER; IN_ELIM_THM] THEN + ASM_MESON_TAC[REAL_LT_REFL]]);; + +let RELATIVE_BOUNDARY_OF_POLYHEDRON = prove + (`!s:real^N->bool. + polyhedron s + ==> s DIFF relative_interior s = UNIONS {f | f facet_of s}`, + REPEAT STRIP_TAC THEN ASM_SIMP_TAC[RELATIVE_INTERIOR_OF_POLYHEDRON] THEN + MATCH_MP_TAC(SET_RULE `f SUBSET s ==> s DIFF (s DIFF f) = f`) THEN + REWRITE_TAC[SUBSET; FORALL_IN_UNIONS; IN_ELIM_THM] THEN + MESON_TAC[FACET_OF_IMP_SUBSET; SUBSET]);; + +let RELATIVE_FRONTIER_OF_POLYHEDRON = prove + (`!s:real^N->bool. + polyhedron s ==> relative_frontier s = UNIONS {f | f facet_of s}`, + SIMP_TAC[relative_frontier; POLYHEDRON_IMP_CLOSED; CLOSURE_CLOSED] THEN + REWRITE_TAC[RELATIVE_BOUNDARY_OF_POLYHEDRON]);; + +let RELATIVE_FRONTIER_OF_POLYHEDRON_ALT = prove + (`!s:real^N->bool. + polyhedron s + ==> relative_frontier s = UNIONS {f | f face_of s /\ ~(f = s)}`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL + [ASM_SIMP_TAC[RELATIVE_FRONTIER_OF_POLYHEDRON; facet_of] THEN + MATCH_MP_TAC SUBSET_UNIONS THEN SIMP_TAC[SUBSET; IN_ELIM_THM] THEN + MESON_TAC[INT_ARITH `~(f - &1:int = f)`]; + REWRITE_TAC[SUBSET; FORALL_IN_UNIONS; IN_ELIM_THM] THEN + MESON_TAC[REWRITE_RULE[SUBSET] FACE_OF_SUBSET_RELATIVE_FRONTIER]]);; + +let FACETS_OF_POLYHEDRON_EXPLICIT_DISTINCT = prove + (`!s:real^N->bool f a b. + FINITE f /\ + s = affine hull s INTER INTERS f /\ + (!h. h IN f ==> ~(a h = vec 0) /\ h = {x | a h dot x <= b h}) /\ + (!f'. f' PSUBSET f ==> s PSUBSET affine hull s INTER INTERS f') + ==> !h1 h2. h1 IN f /\ h2 IN f /\ + s INTER {x | a h1 dot x = b h1} = + s INTER {x | a h2 dot x = b h2} + ==> h1 = h2`, + REPEAT GEN_TAC THEN ASM_CASES_TAC `s:real^N->bool = {}` THENL + [ASM_REWRITE_TAC[AFFINE_HULL_EMPTY; INTER_EMPTY; PSUBSET_IRREFL] THEN + ASM_CASES_TAC `f:(real^N->bool)->bool = {}` THEN + ASM_REWRITE_TAC[NOT_IN_EMPTY] THEN + ASM_MESON_TAC[SET_RULE `~(s = {}) ==> {} PSUBSET s`]; + STRIP_TAC] THEN + SUBGOAL_THEN `polyhedron(s:real^N->bool)` ASSUME_TAC THENL + [REWRITE_TAC[POLYHEDRON_INTER_AFFINE] THEN + REWRITE_TAC[RIGHT_IMP_EXISTS_THM; SKOLEM_THM] THEN ASM_MESON_TAC[]; + ALL_TAC] THEN + SUBGOAL_THEN `~(relative_interior s:real^N->bool = {})` MP_TAC THENL + [ASM_SIMP_TAC[RELATIVE_INTERIOR_EQ_EMPTY; POLYHEDRON_IMP_CONVEX]; + REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; IN_ELIM_THM] THEN + DISCH_THEN(X_CHOOSE_THEN `z:real^N` MP_TAC)] THEN + DISCH_THEN(fun th -> ASSUME_TAC th THEN MP_TAC th) THEN + MP_TAC(ISPECL + [`s:real^N->bool`; `f:(real^N->bool)->bool`; `a:(real^N->bool)->real^N`; + `b:(real^N->bool)->real`] RELATIVE_INTERIOR_POLYHEDRON_EXPLICIT) THEN + ANTS_TAC THENL + [ASM_SIMP_TAC[] THEN ASM_MESON_TAC[]; DISCH_THEN SUBST1_TAC] THEN + REWRITE_TAC[IN_ELIM_THM] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC(TAUT `(~p ==> F) ==> p`) THEN DISCH_TAC THEN + FIRST_ASSUM(MP_TAC o SPEC `f DELETE (h2:real^N->bool)`) THEN + ANTS_TAC THENL [ASM SET_TAC[]; REWRITE_TAC[PSUBSET_ALT]] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC (X_CHOOSE_THEN `x:real^N` MP_TAC)) THEN + REWRITE_TAC[IN_INTER; IN_INTERS; IN_DELETE] THEN STRIP_TAC THEN + MP_TAC(ISPECL [`segment[x:real^N,z]`; `s:real^N->bool`] + CONNECTED_INTER_RELATIVE_FRONTIER) THEN + PURE_REWRITE_TAC[relative_frontier] THEN ANTS_TAC THENL + [REWRITE_TAC[CONNECTED_SEGMENT; GSYM MEMBER_NOT_EMPTY] THEN + REPEAT CONJ_TAC THENL + [ASM_MESON_TAC[CONVEX_CONTAINS_SEGMENT; AFFINE_AFFINE_HULL; + HULL_INC; AFFINE_IMP_CONVEX]; + EXISTS_TAC `z:real^N` THEN ASM_REWRITE_TAC[IN_INTER; ENDS_IN_SEGMENT]; + EXISTS_TAC `x:real^N` THEN ASM_REWRITE_TAC[IN_DIFF; ENDS_IN_SEGMENT]]; + ALL_TAC] THEN + PURE_REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN + ASM_SIMP_TAC[POLYHEDRON_IMP_CLOSED; CLOSURE_CLOSED; + LEFT_IMP_EXISTS_THM; IN_INTER] THEN + X_GEN_TAC `y:real^N` THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + DISCH_THEN(fun th -> STRIP_ASSUME_TAC(REWRITE_RULE[IN_DIFF] th) THEN + MP_TAC th) THEN + ASM_SIMP_TAC[RELATIVE_BOUNDARY_OF_POLYHEDRON] THEN + MP_TAC(ISPECL + [`s:real^N->bool`; `f:(real^N->bool)->bool`; `a:(real^N->bool)->real^N`; + `b:(real^N->bool)->real`] FACET_OF_POLYHEDRON_EXPLICIT) THEN + ANTS_TAC THENL + [ASM_SIMP_TAC[] THEN ASM_MESON_TAC[]; + DISCH_THEN(fun th -> ONCE_REWRITE_TAC[th])] THEN + REWRITE_TAC[SET_RULE `{y | ?x. x IN s /\ y = f x} = IMAGE f s`] THEN + REWRITE_TAC[UNIONS_IMAGE; IN_ELIM_THM; IN_INTER] THEN + DISCH_THEN(X_CHOOSE_THEN `h:real^N->bool` STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN + `?k:real^N->bool. k IN f /\ ~(k = h2) /\ a k dot (y:real^N) = b k` + STRIP_ASSUME_TAC THENL + [ASM_CASES_TAC `h:real^N->bool = h2` THENL + [EXISTS_TAC `h1:real^N->bool` THEN ASM_REWRITE_TAC[] THEN + UNDISCH_TAC `s INTER {x:real^N | a(h1:real^N->bool) dot x = b h1} = + s INTER {x | a h2 dot x = b h2}` THEN + REWRITE_TAC[EXTENSION; IN_INTER; IN_ELIM_THM] THEN ASM_MESON_TAC[]; + ASM_MESON_TAC[]]; + ALL_TAC] THEN + SUBGOAL_THEN + `(a:(real^N->bool)->real^N) k dot z < b k /\ a k dot x <= b k` + STRIP_ASSUME_TAC THENL [ASM_SIMP_TAC[] THEN ASM SET_TAC[]; ALL_TAC] THEN + SUBGOAL_THEN `y IN segment(x:real^N,z)` MP_TAC THENL + [ASM_REWRITE_TAC[IN_OPEN_SEGMENT_ALT] THEN ASM_MESON_TAC[]; + REWRITE_TAC[IN_SEGMENT] THEN STRIP_TAC] THEN + UNDISCH_TAC `(a:(real^N->bool)->real^N) k dot y = b k` THEN + ASM_REWRITE_TAC[DOT_RADD; DOT_RMUL] THEN + MATCH_MP_TAC(REAL_ARITH + `(&1 - u) * x <= (&1 - u) * b /\ u * y < u * b + ==> ~((&1 - u) * x + u * y = b)`) THEN + ASM_SIMP_TAC[REAL_LT_LMUL_EQ; REAL_LE_LMUL_EQ; REAL_SUB_LT]);; + +(* ------------------------------------------------------------------------- *) +(* A characterization of polyhedra as having finitely many faces. *) +(* ------------------------------------------------------------------------- *) + +let POLYHEDRON_EQ_FINITE_EXPOSED_FACES = prove + (`!s:real^N->bool. + polyhedron s <=> closed s /\ convex s /\ FINITE {f | f exposed_face_of s}`, + GEN_TAC THEN EQ_TAC THEN STRIP_TAC THEN + ASM_SIMP_TAC[POLYHEDRON_IMP_CLOSED; POLYHEDRON_IMP_CONVEX; + FINITE_POLYHEDRON_EXPOSED_FACES] THEN + ASM_CASES_TAC `s:real^N->bool = {}` THEN + ASM_REWRITE_TAC[POLYHEDRON_EMPTY] THEN + ABBREV_TAC + `f = {h:real^N->bool | h exposed_face_of s /\ ~(h = {}) /\ ~(h = s)}` THEN + SUBGOAL_THEN `FINITE(f:(real^N->bool)->bool)` ASSUME_TAC THENL + [EXPAND_TAC "f" THEN + ONCE_REWRITE_TAC[SET_RULE + `{x | P x /\ Q x} = {x | x IN {x | P x} /\ Q x}`] THEN + ASM_SIMP_TAC[FINITE_RESTRICT]; + ALL_TAC] THEN + SUBGOAL_THEN + `!h:real^N->bool. + h IN f + ==> h face_of s /\ + ?a b. ~(a = vec 0) /\ + s SUBSET {x | a dot x <= b} /\ + h = s INTER {x | a dot x = b}` + MP_TAC THENL + [EXPAND_TAC "f" THEN REWRITE_TAC[EXPOSED_FACE_OF; IN_ELIM_THM] THEN + MESON_TAC[]; + ALL_TAC] THEN + REWRITE_TAC[RIGHT_IMP_EXISTS_THM; SKOLEM_THM; FORALL_AND_THM; + TAUT `a ==> b /\ c <=> (a ==> b) /\ (a ==> c)`] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + DISCH_THEN(X_CHOOSE_THEN `a:(real^N->bool)->real^N` MP_TAC) THEN + DISCH_THEN(X_CHOOSE_THEN `b:(real^N->bool)->real` STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN + `s = affine hull s INTER + INTERS {{x:real^N | a(h:real^N->bool) dot x <= b h} | h IN f}` + SUBST1_TAC THENL + [ALL_TAC; + MATCH_MP_TAC POLYHEDRON_INTER THEN REWRITE_TAC[POLYHEDRON_AFFINE_HULL] THEN + MATCH_MP_TAC POLYHEDRON_INTERS THEN ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN + ASM_SIMP_TAC[FINITE_IMAGE; FORALL_IN_IMAGE; POLYHEDRON_HALFSPACE_LE]] THEN + MATCH_MP_TAC SUBSET_ANTISYM THEN + REWRITE_TAC[SUBSET_INTER; HULL_SUBSET; + SET_RULE `s SUBSET INTERS f <=> !h. h IN f ==> s SUBSET h`] THEN + ASM_REWRITE_TAC[FORALL_IN_GSPEC] THEN + REWRITE_TAC[SUBSET; IN_INTER; IN_INTERS; FORALL_IN_GSPEC] THEN + X_GEN_TAC `p:real^N` THEN REWRITE_TAC[IN_ELIM_THM] THEN DISCH_TAC THEN + MATCH_MP_TAC(TAUT `(~p ==> F) ==> p`) THEN DISCH_TAC THEN + SUBGOAL_THEN `~(relative_interior(s:real^N->bool) = {})` MP_TAC THENL + [ASM_SIMP_TAC[RELATIVE_INTERIOR_EQ_EMPTY]; + GEN_REWRITE_TAC LAND_CONV [GSYM MEMBER_NOT_EMPTY] THEN + DISCH_THEN(X_CHOOSE_TAC `c:real^N`)] THEN + SUBGOAL_THEN + `?x:real^N. x IN segment[c,p] /\ x IN (s DIFF relative_interior s)` + MP_TAC THENL + [MP_TAC(ISPEC `segment[c:real^N,p]` CONNECTED_OPEN_IN) THEN + REWRITE_TAC[CONNECTED_SEGMENT; NOT_EXISTS_THM] THEN + DISCH_THEN(MP_TAC o SPECL + [`segment[c:real^N,p] INTER relative_interior s`; + `segment[c:real^N,p] INTER (UNIV DIFF s)`]) THEN + ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN + REWRITE_TAC[IN_DIFF; NOT_EXISTS_THM] THEN DISCH_TAC THEN + REPEAT CONJ_TAC THENL + [MATCH_MP_TAC OPEN_IN_SUBTOPOLOGY_INTER_SUBSET THEN + EXISTS_TAC `affine hull s:real^N->bool` THEN + SIMP_TAC[OPEN_IN_RELATIVE_INTERIOR; TOPSPACE_EUCLIDEAN_SUBTOPOLOGY; + OPEN_IN_SUBTOPOLOGY_REFL; SUBSET_UNIV; OPEN_IN_INTER; + TOPSPACE_EUCLIDEAN] THEN + REWRITE_TAC[SEGMENT_CONVEX_HULL] THEN MATCH_MP_TAC HULL_MINIMAL THEN + SIMP_TAC[AFFINE_IMP_CONVEX; AFFINE_AFFINE_HULL] THEN + ASM_REWRITE_TAC[INSERT_SUBSET; EMPTY_SUBSET] THEN + ASM_MESON_TAC[RELATIVE_INTERIOR_SUBSET; HULL_INC; SUBSET]; + REWRITE_TAC[OPEN_IN_OPEN] THEN EXISTS_TAC `(:real^N) DIFF s` THEN + ASM_REWRITE_TAC[GSYM closed]; + MP_TAC(ISPEC `s:real^N->bool` RELATIVE_INTERIOR_SUBSET) THEN ASM SET_TAC[]; + MP_TAC(ISPEC `s:real^N->bool` RELATIVE_INTERIOR_SUBSET) THEN SET_TAC[]; + REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; IN_INTER] THEN + ASM_MESON_TAC[ENDS_IN_SEGMENT]; + REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; IN_DIFF; IN_INTER; IN_UNIV] THEN + ASM_MESON_TAC[ENDS_IN_SEGMENT]]; + REWRITE_TAC[IN_SEGMENT; LEFT_AND_EXISTS_THM] THEN + ONCE_REWRITE_TAC[SWAP_EXISTS_THM] THEN + REWRITE_TAC[GSYM CONJ_ASSOC; RIGHT_EXISTS_AND_THM; UNWIND_THM2] THEN + DISCH_THEN(X_CHOOSE_THEN `l:real` MP_TAC) THEN + ASM_CASES_TAC `l = &0` THEN + ASM_REWRITE_TAC[VECTOR_ADD_RID; VECTOR_MUL_LZERO; REAL_SUB_RZERO; + VECTOR_MUL_LID; IN_DIFF] THEN + ASM_CASES_TAC `l = &1` THEN + ASM_REWRITE_TAC[VECTOR_ADD_LID; VECTOR_MUL_LZERO; REAL_SUB_REFL; + VECTOR_MUL_LID; IN_DIFF] THEN + ASM_REWRITE_TAC[REAL_LE_LT] THEN STRIP_TAC] THEN + ABBREV_TAC `x:real^N = (&1 - l) % c + l % p` THEN + SUBGOAL_THEN `?h:real^N->bool. h IN f /\ x IN h` STRIP_ASSUME_TAC THENL + [MP_TAC(ISPECL [`s:real^N->bool`; `(&1 - l) % c + l % p:real^N`] + SUPPORTING_HYPERPLANE_RELATIVE_FRONTIER) THEN + ASM_SIMP_TAC[REWRITE_RULE[SUBSET] CLOSURE_SUBSET] THEN + DISCH_THEN(X_CHOOSE_THEN `d:real^N` STRIP_ASSUME_TAC) THEN + EXPAND_TAC "f" THEN + EXISTS_TAC `s INTER {y:real^N | d dot y = d dot x}` THEN + ASM_REWRITE_TAC[IN_INTER; IN_ELIM_THM] THEN REPEAT CONJ_TAC THENL + [MATCH_MP_TAC EXPOSED_FACE_OF_INTER_SUPPORTING_HYPERPLANE_GE THEN + ASM_SIMP_TAC[real_ge; REWRITE_RULE[SUBSET] CLOSURE_SUBSET]; + ASM SET_TAC[]; + REWRITE_TAC[EXTENSION; IN_INTER; IN_ELIM_THM] THEN + DISCH_THEN(MP_TAC o SPEC `c:real^N`) THEN + ASM_MESON_TAC[SUBSET; REAL_LT_REFL; RELATIVE_INTERIOR_SUBSET]]; + ALL_TAC] THEN + SUBGOAL_THEN `{y:real^N | a(h:real^N->bool) dot y = b h} face_of + {y | a h dot y <= b h}` + MP_TAC THENL + [MATCH_MP_TAC(MESON[] + `(t INTER s) face_of t /\ t INTER s = s ==> s face_of t`) THEN + CONJ_TAC THENL + [MATCH_MP_TAC FACE_OF_INTER_SUPPORTING_HYPERPLANE_LE THEN + REWRITE_TAC[IN_ELIM_THM; CONVEX_HALFSPACE_LE]; + SET_TAC[REAL_LE_REFL]]; + ALL_TAC] THEN + REWRITE_TAC[face_of] THEN + DISCH_THEN(MP_TAC o SPECL [`c:real^N`; `p:real^N`; `x:real^N`] o + CONJUNCT2 o CONJUNCT2) THEN + ASM_SIMP_TAC[IN_ELIM_THM; NOT_IMP; GSYM CONJ_ASSOC] THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP (REWRITE_RULE[SUBSET] + RELATIVE_INTERIOR_SUBSET)) THEN + REPEAT CONJ_TAC THENL + [ASM SET_TAC[]; + ASM SET_TAC[]; + REWRITE_TAC[IN_SEGMENT] THEN ASM SET_TAC[]; + STRIP_TAC] THEN + MP_TAC(ISPECL [`s:real^N->bool`; `h:real^N->bool`; `s:real^N->bool`] + SUBSET_OF_FACE_OF) THEN + ASM SET_TAC[]);; + +let POLYHEDRON_EQ_FINITE_FACES = prove + (`!s:real^N->bool. + polyhedron s <=> + closed s /\ convex s /\ FINITE {f | f face_of s}`, + GEN_TAC THEN EQ_TAC THEN STRIP_TAC THEN + ASM_SIMP_TAC[POLYHEDRON_IMP_CLOSED; POLYHEDRON_IMP_CONVEX; + FINITE_POLYHEDRON_FACES] THEN + REWRITE_TAC[POLYHEDRON_EQ_FINITE_EXPOSED_FACES] THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC FINITE_SUBSET THEN + EXISTS_TAC `{f:real^N->bool | f face_of s}` THEN + ASM_REWRITE_TAC[] THEN + SIMP_TAC[SUBSET; IN_ELIM_THM; exposed_face_of]);; + +let POLYHEDRON_TRANSLATION_EQ = prove + (`!a s. polyhedron (IMAGE (\x:real^N. a + x) s) <=> polyhedron s`, + REPEAT STRIP_TAC THEN REWRITE_TAC[POLYHEDRON_EQ_FINITE_FACES] THEN + REWRITE_TAC[CLOSED_TRANSLATION_EQ] THEN AP_TERM_TAC THEN + REWRITE_TAC[CONVEX_TRANSLATION_EQ] THEN AP_TERM_TAC THEN + MP_TAC(ISPEC `IMAGE (\x:real^N. a + x)` QUANTIFY_SURJECTION_THM) THEN + REWRITE_TAC[SURJECTIVE_IMAGE; EXISTS_REFL; + VECTOR_ARITH `a + x:real^N = y <=> x = y - a`] THEN + DISCH_THEN(fun th -> GEN_REWRITE_TAC (LAND_CONV o RAND_CONV) [th]) THEN + REWRITE_TAC[FACE_OF_TRANSLATION_EQ] THEN + MATCH_MP_TAC FINITE_IMAGE_INJ_EQ THEN + MATCH_MP_TAC(MESON[] + `(!x y. Q x y ==> R x y) ==> (!x y. P x /\ P y /\ Q x y ==> R x y)`) THEN + REWRITE_TAC[INJECTIVE_IMAGE] THEN VECTOR_ARITH_TAC);; + +add_translation_invariants [POLYHEDRON_TRANSLATION_EQ];; + +let POLYHEDRON_LINEAR_IMAGE_EQ = prove + (`!f:real^M->real^N s. + linear f /\ (!x y. f x = f y ==> x = y) /\ (!y. ?x. f x = y) + ==> (polyhedron (IMAGE f s) <=> polyhedron s)`, + REPEAT STRIP_TAC THEN REWRITE_TAC[POLYHEDRON_EQ_FINITE_FACES] THEN + BINOP_TAC THENL + [ASM_MESON_TAC[CLOSED_INJECTIVE_LINEAR_IMAGE_EQ]; ALL_TAC] THEN + BINOP_TAC THENL [ASM_MESON_TAC[CONVEX_LINEAR_IMAGE_EQ]; ALL_TAC] THEN + MP_TAC(ISPEC `IMAGE (f:real^M->real^N)` QUANTIFY_SURJECTION_THM) THEN + ASM_REWRITE_TAC[SURJECTIVE_IMAGE] THEN + DISCH_THEN(fun th -> GEN_REWRITE_TAC (LAND_CONV o RAND_CONV) [th]) THEN + MP_TAC(ISPEC `f:real^M->real^N` FACE_OF_LINEAR_IMAGE) THEN + ASM_REWRITE_TAC[] THEN DISCH_TAC THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC FINITE_IMAGE_INJ_EQ THEN + FIRST_ASSUM(ASSUME_TAC o GEN_REWRITE_RULE I [GSYM INJECTIVE_IMAGE]) THEN + ASM_REWRITE_TAC[IMP_CONJ]);; + +add_linear_invariants [POLYHEDRON_LINEAR_IMAGE_EQ];; + +let POLYHEDRON_NEGATIONS = prove + (`!s:real^N->bool. polyhedron s ==> polyhedron(IMAGE (--) s)`, + GEN_TAC THEN MATCH_MP_TAC EQ_IMP THEN CONV_TAC SYM_CONV THEN + MATCH_MP_TAC POLYHEDRON_LINEAR_IMAGE_EQ THEN + REWRITE_TAC[VECTOR_ARITH `--x:real^N = y <=> x = --y`; EXISTS_REFL] THEN + REWRITE_TAC[LINEAR_NEGATION] THEN VECTOR_ARITH_TAC);; + +(* ------------------------------------------------------------------------- *) +(* Relation between polytopes and polyhedra. *) +(* ------------------------------------------------------------------------- *) + +let POLYTOPE_EQ_BOUNDED_POLYHEDRON = prove + (`!s:real^N->bool. polytope s <=> polyhedron s /\ bounded s`, + GEN_TAC THEN EQ_TAC THENL + [SIMP_TAC[FINITE_POLYTOPE_FACES; POLYHEDRON_EQ_FINITE_FACES; + POLYTOPE_IMP_CLOSED; POLYTOPE_IMP_CONVEX; POLYTOPE_IMP_BOUNDED]; + STRIP_TAC THEN REWRITE_TAC[polytope] THEN + EXISTS_TAC `{v:real^N | v extreme_point_of s}` THEN + ASM_SIMP_TAC[FINITE_POLYHEDRON_EXTREME_POINTS] THEN + MATCH_MP_TAC KREIN_MILMAN_MINKOWSKI THEN + ASM_SIMP_TAC[COMPACT_EQ_BOUNDED_CLOSED; POLYHEDRON_IMP_CLOSED; + POLYHEDRON_IMP_CONVEX]]);; + +let POLYTOPE_INTER = prove + (`!s t. polytope s /\ polytope t ==> polytope(s INTER t)`, + SIMP_TAC[POLYTOPE_EQ_BOUNDED_POLYHEDRON; POLYHEDRON_INTER; BOUNDED_INTER]);; + +let POLYTOPE_INTER_POLYHEDRON = prove + (`!s t:real^N->bool. polytope s /\ polyhedron t ==> polytope(s INTER t)`, + SIMP_TAC[POLYTOPE_EQ_BOUNDED_POLYHEDRON; POLYHEDRON_INTER] THEN + MESON_TAC[BOUNDED_SUBSET; INTER_SUBSET]);; + +let POLYHEDRON_INTER_POLYTOPE = prove + (`!s t:real^N->bool. polyhedron s /\ polytope t ==> polytope(s INTER t)`, + SIMP_TAC[POLYTOPE_EQ_BOUNDED_POLYHEDRON; POLYHEDRON_INTER] THEN + MESON_TAC[BOUNDED_SUBSET; INTER_SUBSET]);; + +let POLYTOPE_IMP_POLYHEDRON = prove + (`!p. polytope p ==> polyhedron p`, + SIMP_TAC[POLYTOPE_EQ_BOUNDED_POLYHEDRON]);; + +let POLYTOPE_FACET_EXISTS = prove + (`!p:real^N->bool. polytope p /\ &0 < aff_dim p ==> ?f. f facet_of p`, + GEN_TAC THEN ASM_CASES_TAC `p:real^N->bool = {}` THEN + ASM_REWRITE_TAC[AFF_DIM_EMPTY] THEN CONV_TAC INT_REDUCE_CONV THEN + STRIP_TAC THEN + MP_TAC(ISPEC `p:real^N->bool` EXTREME_POINT_EXISTS_CONVEX) THEN + ASM_SIMP_TAC[POLYTOPE_IMP_COMPACT; POLYTOPE_IMP_CONVEX] THEN + DISCH_THEN(X_CHOOSE_TAC `v:real^N`) THEN + MP_TAC(ISPECL [`p:real^N->bool`; `{v:real^N}`] + FACE_OF_POLYHEDRON_SUBSET_FACET) THEN + ANTS_TAC THENL [ALL_TAC; MESON_TAC[]] THEN + ASM_SIMP_TAC[POLYTOPE_IMP_POLYHEDRON; FACE_OF_SING; NOT_INSERT_EMPTY] THEN + ASM_MESON_TAC[AFF_DIM_SING; INT_LT_REFL]);; + +let POLYHEDRON_INTERVAL = prove + (`!a b. polyhedron(interval[a,b])`, + MESON_TAC[POLYTOPE_IMP_POLYHEDRON; POLYTOPE_INTERVAL]);; + +let POLYHEDRON_CONVEX_HULL = prove + (`!s. FINITE s ==> polyhedron(convex hull s)`, + SIMP_TAC[POLYTOPE_CONVEX_HULL; POLYTOPE_IMP_POLYHEDRON]);; + +(* ------------------------------------------------------------------------- *) +(* Polytope is union of convex hulls of facets plus any point inside. *) +(* ------------------------------------------------------------------------- *) + +let POLYTOPE_UNION_CONVEX_HULL_FACETS = prove + (`!s p:real^N->bool. + polytope p /\ &0 < aff_dim p /\ ~(s = {}) /\ s SUBSET p + ==> p = UNIONS { convex hull (s UNION f) | f facet_of p}`, + let lemma = SET_RULE `{f x | p x} = {y | ?x. p x /\ y = f x}` in + MATCH_MP_TAC SET_PROVE_CASES THEN REWRITE_TAC[] THEN + X_GEN_TAC `a:real^N` THEN ONCE_REWRITE_TAC[lemma] THEN + GEOM_ORIGIN_TAC `a:real^N` THEN ONCE_REWRITE_TAC[GSYM lemma] THEN + X_GEN_TAC `s:real^N->bool` THEN DISCH_THEN(K ALL_TAC) THEN + MP_TAC(SET_RULE `(vec 0:real^N) IN (vec 0 INSERT s)`) THEN + SPEC_TAC(`(vec 0:real^N) INSERT s`,`s:real^N->bool`) THEN + X_GEN_TAC `s:real^N->bool` THEN DISCH_TAC THEN + X_GEN_TAC `p:real^N->bool` THEN STRIP_TAC THEN + FIRST_ASSUM(STRIP_ASSUME_TAC o + GEN_REWRITE_RULE I [POLYTOPE_EQ_BOUNDED_POLYHEDRON]) THEN + MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL + [ALL_TAC; + REWRITE_TAC[SUBSET; FORALL_IN_UNIONS; IMP_CONJ] THEN + REWRITE_TAC[FORALL_IN_GSPEC; RIGHT_FORALL_IMP_THM] THEN + X_GEN_TAC `f:real^N->bool` THEN DISCH_TAC THEN + REWRITE_TAC[GSYM SUBSET] THEN MATCH_MP_TAC SUBSET_TRANS THEN + EXISTS_TAC `convex hull p:real^N->bool` THEN CONJ_TAC THENL + [MATCH_MP_TAC HULL_MONO THEN + FIRST_ASSUM(MP_TAC o MATCH_MP FACET_OF_IMP_SUBSET) THEN ASM SET_TAC[]; + ASM_MESON_TAC[CONVEX_HULL_EQ; POLYHEDRON_IMP_CONVEX; SUBSET_REFL]]] THEN + REWRITE_TAC[SUBSET] THEN X_GEN_TAC `v:real^N` THEN DISCH_TAC THEN + ASM_CASES_TAC `v:real^N = vec 0` THENL + [MP_TAC(ISPEC `p:real^N->bool` POLYTOPE_FACET_EXISTS) THEN + ASM_REWRITE_TAC[IN_UNIONS; EXISTS_IN_GSPEC] THEN + MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC THEN DISCH_TAC THEN + ASM_REWRITE_TAC[] THEN ASM_MESON_TAC[HULL_INC; IN_UNION]; + ALL_TAC] THEN + SUBGOAL_THEN `?t. &1 < t /\ ~((t % v:real^N) IN p)` STRIP_ASSUME_TAC THENL + [FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [BOUNDED_POS]) THEN + DISCH_THEN(X_CHOOSE_THEN `B:real` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `max (&2) ((B + &1) / norm (v:real^N))` THEN + CONJ_TAC THENL [REAL_ARITH_TAC; ALL_TAC] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o + GEN_REWRITE_RULE BINDER_CONV [GSYM CONTRAPOS_THM]) THEN + ASM_SIMP_TAC[NORM_MUL; GSYM REAL_LE_RDIV_EQ; NORM_POS_LT] THEN + MATCH_MP_TAC(REAL_ARITH `a < b ==> ~(abs(max (&2) b) <= a)`) THEN + ASM_SIMP_TAC[REAL_LT_DIV2_EQ; NORM_POS_LT] THEN REAL_ARITH_TAC; + ALL_TAC] THEN + SUBGOAL_THEN `(vec 0:real^N) IN p` ASSUME_TAC THENL + [ASM SET_TAC[]; ALL_TAC] THEN + MP_TAC(ISPECL [`segment[vec 0,t % v:real^N] INTER p`; `vec 0:real^N`] + DISTANCE_ATTAINS_SUP) THEN + ANTS_TAC THENL + [ASM_SIMP_TAC[COMPACT_INTER_CLOSED; POLYHEDRON_IMP_CLOSED; COMPACT_SEGMENT; + GSYM MEMBER_NOT_EMPTY; IN_INTER] THEN + ASM_MESON_TAC[ENDS_IN_SEGMENT]; + REWRITE_TAC[IN_INTER; GSYM CONJ_ASSOC; IMP_CONJ] THEN + REWRITE_TAC[segment; FORALL_IN_GSPEC; EXISTS_IN_GSPEC] THEN + REWRITE_TAC[VECTOR_MUL_RZERO; VECTOR_ADD_LID; DIST_0] THEN + REWRITE_TAC[IMP_IMP; GSYM CONJ_ASSOC; NORM_MUL; REAL_MUL_ASSOC] THEN + ASM_SIMP_TAC[REAL_LE_RMUL_EQ; NORM_POS_LT; LEFT_IMP_EXISTS_THM; + REAL_ARITH `&1 < t ==> &0 < abs t`] THEN + X_GEN_TAC `u:real` THEN + ASM_CASES_TAC `u = &1` THEN ASM_REWRITE_TAC[VECTOR_MUL_LID] THEN + REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + ASM_SIMP_TAC[real_abs] THEN DISCH_TAC] THEN + SUBGOAL_THEN `inv(t) <= u` ASSUME_TAC THENL + [FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_SIMP_TAC[REAL_INV_LE_1; REAL_LT_IMP_LE; REAL_LE_INV_EQ; + REAL_ARITH `&1 < t ==> &0 <= t`] THEN + ASM_SIMP_TAC[VECTOR_MUL_ASSOC; REAL_MUL_LINV; VECTOR_MUL_LID; + REAL_ARITH `&1 < t ==> ~(t = &0)`]; + ALL_TAC] THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP (REAL_ARITH `&1 < t ==> &0 < t`)) THEN + SUBGOAL_THEN `&0 < u /\ u < &1` STRIP_ASSUME_TAC THENL + [ASM_REWRITE_TAC[REAL_LT_LE] THEN + DISCH_THEN(SUBST_ALL_TAC o SYM) THEN + UNDISCH_TAC `inv t <= &0` THEN REWRITE_TAC[REAL_NOT_LE] THEN + ASM_REWRITE_TAC[REAL_LT_INV_EQ]; + ALL_TAC] THEN + MATCH_MP_TAC(SET_RULE `!t. t SUBSET s /\ x IN t ==> x IN s`) THEN + EXISTS_TAC `convex hull {vec 0:real^N,u % t % v}` THEN CONJ_TAC THENL + [ALL_TAC; + REWRITE_TAC[CONVEX_HULL_2; VECTOR_MUL_RZERO; VECTOR_ADD_LID] THEN + REWRITE_TAC[IN_ELIM_THM] THEN + MAP_EVERY EXISTS_TAC [`&1 - inv(u * t)`; `inv(u * t):real`] THEN + REWRITE_TAC[REAL_ARITH `&1 - x + x = &1`; REAL_SUB_LE; REAL_LE_INV_EQ] THEN + ASM_SIMP_TAC[REAL_LE_MUL; REAL_LT_IMP_LE; VECTOR_MUL_ASSOC] THEN + ASM_SIMP_TAC[GSYM REAL_MUL_ASSOC; REAL_ENTIRE; REAL_MUL_LINV; + REAL_LT_IMP_NZ; VECTOR_MUL_LID] THEN + MATCH_MP_TAC REAL_INV_LE_1 THEN ASM_SIMP_TAC[GSYM REAL_LE_LDIV_EQ] THEN + ASM_REWRITE_TAC[real_div; REAL_MUL_LID]] THEN + SUBGOAL_THEN + `(u % t % v:real^N) IN (p DIFF relative_interior p)` + MP_TAC THENL + [ALL_TAC; + ASM_SIMP_TAC[RELATIVE_INTERIOR_OF_POLYHEDRON] THEN + DISCH_THEN(MP_TAC o MATCH_MP (SET_RULE + `x IN s DIFF (s DIFF t) ==> x IN t`)) THEN + REWRITE_TAC[IN_UNIONS; EXISTS_IN_GSPEC] THEN + DISCH_THEN(X_CHOOSE_THEN `f:real^N->bool` STRIP_ASSUME_TAC) THEN + MATCH_MP_TAC(SET_RULE + `(?s. s IN f /\ t SUBSET s) ==> t SUBSET UNIONS f`) THEN + REWRITE_TAC[EXISTS_IN_GSPEC] THEN EXISTS_TAC `f:real^N->bool` THEN + ASM_SIMP_TAC[SUBSET_HULL; CONVEX_CONVEX_HULL] THEN + ASM_SIMP_TAC[HULL_INC; IN_UNION; INSERT_SUBSET; EMPTY_SUBSET]] THEN + ASM_REWRITE_TAC[IN_DIFF; IN_RELATIVE_INTERIOR] THEN + DISCH_THEN(X_CHOOSE_THEN `e:real` (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + REWRITE_TAC[SUBSET; IN_BALL; IN_INTER; dist] THEN + ABBREV_TAC `k = min (e / &2 / norm(t % v:real^N)) (&1 - u)` THEN + SUBGOAL_THEN `&0 < k` ASSUME_TAC THENL + [EXPAND_TAC "k" THEN REWRITE_TAC[REAL_LT_MIN] THEN + ASM_REWRITE_TAC[REAL_SUB_LT] THEN MATCH_MP_TAC REAL_LT_DIV THEN + ASM_SIMP_TAC[REAL_HALF; NORM_POS_LT; VECTOR_MUL_EQ_0; REAL_LT_IMP_NZ]; + ALL_TAC] THEN + DISCH_THEN(MP_TAC o SPEC `(u + k) % t % v:real^N`) THEN + REWRITE_TAC[VECTOR_ARITH `u % x - (u + k) % x:real^N = --k % x`] THEN + ONCE_REWRITE_TAC[NORM_MUL] THEN REWRITE_TAC[REAL_ABS_NEG; NOT_IMP] THEN + REPEAT CONJ_TAC THENL + [MATCH_MP_TAC(REAL_ARITH `&0 < e /\ x <= e / &2 ==> x < e`) THEN + ASM_SIMP_TAC[GSYM REAL_LE_RDIV_EQ; NORM_POS_LT; VECTOR_MUL_EQ_0; + REAL_LT_IMP_NZ] THEN + ASM_SIMP_TAC[real_abs; REAL_LT_IMP_LE] THEN + EXPAND_TAC "k" THEN REAL_ARITH_TAC; + ASM_SIMP_TAC[AFFINE_HULL_EQ_SPAN; HULL_INC] THEN + REPEAT(MATCH_MP_TAC SPAN_MUL) THEN ASM_SIMP_TAC[SPAN_SUPERSET]; + DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `u + k:real`) THEN + ASM_REWRITE_TAC[NOT_IMP] THEN + MATCH_MP_TAC(REAL_ARITH + `&0 <= u /\ &0 < x /\ x <= &1 - u + ==> (&0 <= u + x /\ u + x <= &1) /\ ~(u + x <= u)`) THEN + ASM_REWRITE_TAC[] THEN EXPAND_TAC "k" THEN REAL_ARITH_TAC]);; + +(* ------------------------------------------------------------------------- *) +(* Finitely generated cone is polyhedral, and hence closed. *) +(* ------------------------------------------------------------------------- *) + +let POLYHEDRON_CONVEX_CONE_HULL = prove + (`!s:real^N->bool. FINITE s ==> polyhedron(convex_cone hull s)`, + GEN_TAC THEN ASM_CASES_TAC `s:real^N->bool = {}` THEN DISCH_TAC THENL + [ASM_REWRITE_TAC[CONVEX_CONE_HULL_EMPTY] THEN + ASM_SIMP_TAC[POLYTOPE_IMP_POLYHEDRON; POLYTOPE_SING]; + ALL_TAC] THEN + SUBGOAL_THEN + `polyhedron(convex hull ((vec 0:real^N) INSERT s))` + MP_TAC THENL + [MATCH_MP_TAC POLYTOPE_IMP_POLYHEDRON THEN + REWRITE_TAC[polytope] THEN ASM_MESON_TAC[FINITE_INSERT]; + REWRITE_TAC[polyhedron] THEN + DISCH_THEN(X_CHOOSE_THEN `f:(real^N->bool)->bool` STRIP_ASSUME_TAC) THEN + RULE_ASSUM_TAC(REWRITE_RULE[SKOLEM_THM; RIGHT_IMP_EXISTS_THM]) THEN + FIRST_X_ASSUM(X_CHOOSE_THEN `a:(real^N->bool)->real^N` MP_TAC) THEN + DISCH_THEN(X_CHOOSE_TAC `b:(real^N->bool)->real`)] THEN + SUBGOAL_THEN `~(f:(real^N->bool)->bool = {})` ASSUME_TAC THENL + [DISCH_THEN SUBST_ALL_TAC THEN FIRST_X_ASSUM(MP_TAC o + GEN_REWRITE_RULE RAND_CONV [INTERS_0]) THEN + DISCH_THEN(MP_TAC o AP_TERM `bounded:(real^N->bool)->bool`) THEN + ASM_SIMP_TAC[NOT_BOUNDED_UNIV; BOUNDED_CONVEX_HULL; FINITE_IMP_BOUNDED; + FINITE_INSERT; FINITE_EMPTY]; + ALL_TAC] THEN + EXISTS_TAC `{h:real^N->bool | h IN f /\ b h = &0}` THEN + ASM_SIMP_TAC[FINITE_RESTRICT; IN_ELIM_THM] THEN CONJ_TAC THENL + [ALL_TAC; + X_GEN_TAC `h:real^N->bool` THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `h:real^N->bool`) THEN + ASM_REWRITE_TAC[] THEN DISCH_TAC THEN ONCE_ASM_REWRITE_TAC[] THEN + MAP_EVERY EXISTS_TAC + [`(a:(real^N->bool)->real^N) h`; `(b:(real^N->bool)->real) h`] THEN + ASM_REWRITE_TAC[]] THEN + MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL + [MATCH_MP_TAC HULL_MINIMAL THEN CONJ_TAC THENL + [MATCH_MP_TAC SUBSET_TRANS THEN + EXISTS_TAC `convex hull ((vec 0:real^N) INSERT s)` THEN CONJ_TAC THENL + [SIMP_TAC[SUBSET; HULL_INC; IN_INSERT]; ASM_REWRITE_TAC[]] THEN + MATCH_MP_TAC(SET_RULE `s SUBSET t ==> INTERS t SUBSET INTERS s`) THEN + SET_TAC[]; + MATCH_MP_TAC CONVEX_CONE_INTERS THEN + X_GEN_TAC `h:real^N->bool` THEN REWRITE_TAC[IN_ELIM_THM] THEN + STRIP_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC `h:real^N->bool`) THEN + ASM_REWRITE_TAC[] THEN DISCH_THEN(SUBST1_TAC o CONJUNCT2) THEN + REWRITE_TAC[CONVEX_CONE_HALFSPACE_LE]]; + ALL_TAC] THEN + REWRITE_TAC[SUBSET; IN_INTERS; IN_ELIM_THM] THEN X_GEN_TAC `x:real^N` THEN + DISCH_TAC THEN + SUBGOAL_THEN `!h:real^N->bool. h IN f ==> ?t. &0 < t /\ (t % x) IN h` + MP_TAC THENL + [X_GEN_TAC `h:real^N->bool` THEN DISCH_TAC THEN + ASM_CASES_TAC `(b:(real^N->bool)->real) h = &0` THENL + [EXISTS_TAC `&1` THEN ASM_SIMP_TAC[REAL_LT_01; VECTOR_MUL_LID]; + ALL_TAC] THEN + SUBGOAL_THEN `&0 < (b:(real^N->bool)->real) h` ASSUME_TAC THENL + [ASM_REWRITE_TAC[REAL_LT_LE] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [EXTENSION]) THEN + DISCH_THEN(MP_TAC o SPEC `vec 0:real^N`) THEN + SIMP_TAC[HULL_INC; IN_INSERT; IN_INTERS] THEN + DISCH_THEN(MP_TAC o SPEC `h:real^N->bool`) THEN ASM_REWRITE_TAC[] THEN + SUBGOAL_THEN `h = {x:real^N | a h dot x <= b h}` + (fun th -> GEN_REWRITE_TAC (LAND_CONV o RAND_CONV) [th]) + THENL [ASM_MESON_TAC[]; REWRITE_TAC[IN_ELIM_THM; DOT_RZERO]]; + ALL_TAC] THEN + SUBGOAL_THEN `(vec 0:real^N) IN interior h` MP_TAC THENL + [SUBGOAL_THEN `h = {x:real^N | a h dot x <= b h}` SUBST1_TAC THENL + [ASM_MESON_TAC[]; + ASM_SIMP_TAC[INTERIOR_HALFSPACE_LE; IN_ELIM_THM; DOT_RZERO]]; + REWRITE_TAC[IN_INTERIOR; SUBSET; IN_BALL_0; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `e:real` THEN STRIP_TAC THEN + ASM_CASES_TAC `x:real^N = vec 0` THENL + [EXISTS_TAC `&1` THEN + ASM_SIMP_TAC[VECTOR_MUL_RZERO; REAL_LT_01; NORM_0]; + EXISTS_TAC `e / &2 / norm(x:real^N)` THEN + ASM_SIMP_TAC[REAL_HALF; REAL_LT_DIV; NORM_POS_LT] THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN + REWRITE_TAC[NORM_MUL; REAL_ABS_DIV; REAL_ABS_NUM; REAL_ABS_NORM] THEN + ASM_SIMP_TAC[REAL_DIV_RMUL; NORM_EQ_0] THEN ASM_REAL_ARITH_TAC]]; + ALL_TAC] THEN + REWRITE_TAC[RIGHT_IMP_EXISTS_THM; SKOLEM_THM; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `t:(real^N->bool)->real` THEN DISCH_TAC THEN + SUBGOAL_THEN `x:real^N = inv(inf(IMAGE t (f:(real^N->bool)->bool))) % + inf(IMAGE t f) % x` + SUBST1_TAC THENL + [GEN_REWRITE_TAC LAND_CONV [GSYM VECTOR_MUL_LID] THEN + REWRITE_TAC[VECTOR_MUL_ASSOC] THEN AP_THM_TAC THEN AP_TERM_TAC THEN + CONV_TAC SYM_CONV THEN MATCH_MP_TAC REAL_MUL_LINV THEN + MATCH_MP_TAC REAL_LT_IMP_NZ THEN + ASM_SIMP_TAC[REAL_LT_INF_FINITE; FINITE_IMAGE; IMAGE_EQ_EMPTY] THEN + ASM_SIMP_TAC[FORALL_IN_IMAGE]; + ALL_TAC] THEN + MATCH_MP_TAC(REWRITE_RULE[conic] CONIC_CONVEX_CONE_HULL) THEN + ASM_SIMP_TAC[REAL_LE_INV_EQ; REAL_LE_INF_FINITE; FINITE_IMAGE; + IMAGE_EQ_EMPTY; REAL_LT_IMP_LE; FORALL_IN_IMAGE] THEN + MATCH_MP_TAC(SET_RULE `!s t. s SUBSET t /\ x IN s ==> x IN t`) THEN + EXISTS_TAC `convex hull ((vec 0:real^N) INSERT s)` THEN CONJ_TAC THENL + [MATCH_MP_TAC HULL_MINIMAL THEN + REWRITE_TAC[CONVEX_CONVEX_CONE_HULL] THEN + ASM_SIMP_TAC[INSERT_SUBSET; HULL_SUBSET; CONVEX_CONE_HULL_CONTAINS_0]; + ASM_REWRITE_TAC[IN_INTERS] THEN X_GEN_TAC `h:real^N->bool` THEN + DISCH_TAC THEN + SUBGOAL_THEN `inf(IMAGE (t:(real^N->bool)->real) f) % x:real^N = + (&1 - inf(IMAGE t f) / t h) % vec 0 + + (inf(IMAGE t f) / t h) % t h % x` + SUBST1_TAC THENL + [ASM_SIMP_TAC[VECTOR_MUL_ASSOC; VECTOR_MUL_RZERO; VECTOR_ADD_LID; + REAL_DIV_RMUL; REAL_LT_IMP_NZ]; + ALL_TAC] THEN + MATCH_MP_TAC IN_CONVEX_SET THEN + ASM_SIMP_TAC[REAL_LE_RDIV_EQ; REAL_LE_LDIV_EQ] THEN + REWRITE_TAC[REAL_MUL_LZERO; REAL_MUL_LID] THEN + ASM_SIMP_TAC[REAL_INF_LE_FINITE; REAL_LE_INF_FINITE; + FINITE_IMAGE; IMAGE_EQ_EMPTY] THEN + ASM_REWRITE_TAC[FORALL_IN_IMAGE; EXISTS_IN_IMAGE] THEN + ASM_SIMP_TAC[REAL_LT_IMP_LE] THEN REPEAT CONJ_TAC THENL + [SUBGOAL_THEN `h = {x:real^N | a h dot x <= b h}` SUBST1_TAC THENL + [ASM_MESON_TAC[]; ASM_SIMP_TAC[CONVEX_HALFSPACE_LE]]; + SUBGOAL_THEN `(vec 0:real^N) IN convex hull (vec 0 INSERT s)` MP_TAC + THENL [SIMP_TAC[HULL_INC; IN_INSERT]; ALL_TAC] THEN + ASM_REWRITE_TAC[IN_INTERS] THEN ASM_MESON_TAC[]; + ASM SET_TAC[REAL_LE_REFL]]]);; + +let CLOSED_CONVEX_CONE_HULL = prove + (`!s:real^N->bool. FINITE s ==> closed(convex_cone hull s)`, + MESON_TAC[POLYHEDRON_IMP_CLOSED; POLYHEDRON_CONVEX_CONE_HULL]);; + +(* ------------------------------------------------------------------------- *) +(* And conversely, a polyhedral cone is finitely generated. *) +(* ------------------------------------------------------------------------- *) + +let FINITELY_GENERATED_CONIC_POLYHEDRON = prove + (`!s:real^N->bool. + polyhedron s /\ conic s /\ ~(s = {}) + ==> ?c. FINITE c /\ s = convex_cone hull c`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN `?p:real^N->bool. polytope p /\ vec 0 IN interior p` + STRIP_ASSUME_TAC THENL + [EXISTS_TAC `interval[--vec 1:real^N,vec 1:real^N]` THEN + REWRITE_TAC[POLYTOPE_INTERVAL; INTERIOR_CLOSED_INTERVAL] THEN + SIMP_TAC[IN_INTERVAL; VECTOR_NEG_COMPONENT; VEC_COMPONENT] THEN + CONV_TAC REAL_RAT_REDUCE_CONV; + ALL_TAC] THEN + SUBGOAL_THEN `polytope(s INTER p:real^N->bool)` MP_TAC THENL + [REWRITE_TAC[POLYTOPE_EQ_BOUNDED_POLYHEDRON] THEN + ASM_SIMP_TAC[BOUNDED_INTER; POLYTOPE_IMP_BOUNDED]THEN + ASM_SIMP_TAC[POLYHEDRON_INTER; POLYTOPE_IMP_POLYHEDRON]; + REWRITE_TAC[polytope] THEN MATCH_MP_TAC MONO_EXISTS] THEN + X_GEN_TAC `c:real^N->bool` THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL + [ALL_TAC; + ASM_SIMP_TAC[SUBSET_HULL; POLYHEDRON_IMP_CONVEX; convex_cone] THEN + MATCH_MP_TAC SUBSET_TRANS THEN EXISTS_TAC `s INTER p:real^N->bool` THEN + REWRITE_TAC[INTER_SUBSET] THEN ASM_REWRITE_TAC[HULL_SUBSET]] THEN + REWRITE_TAC[SUBSET] THEN X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN + SUBGOAL_THEN `?t. &0 < t /\ (t % x:real^N) IN p` STRIP_ASSUME_TAC THENL + [FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_INTERIOR]) THEN + REWRITE_TAC[SUBSET; IN_BALL_0; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `e:real` THEN STRIP_TAC THEN + ASM_CASES_TAC `x:real^N = vec 0` THENL + [EXISTS_TAC `&1` THEN ASM_REWRITE_TAC[VECTOR_MUL_RZERO; REAL_LT_01] THEN + ASM_SIMP_TAC[NORM_0]; + EXISTS_TAC `e / &2 / norm(x:real^N)` THEN + ASM_SIMP_TAC[REAL_HALF; REAL_LT_DIV; NORM_POS_LT] THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN + REWRITE_TAC[NORM_MUL; REAL_ABS_DIV; REAL_ABS_NORM; REAL_ABS_NUM] THEN + ASM_SIMP_TAC[REAL_DIV_RMUL; NORM_EQ_0] THEN ASM_REAL_ARITH_TAC]; + ALL_TAC] THEN + SUBGOAL_THEN `x:real^N = inv t % t % x` SUBST1_TAC THENL + [ASM_SIMP_TAC[VECTOR_MUL_ASSOC; REAL_MUL_LINV; VECTOR_MUL_LID; + REAL_LT_IMP_NZ]; + ALL_TAC] THEN + MATCH_MP_TAC(REWRITE_RULE[conic] CONIC_CONVEX_CONE_HULL) THEN + ASM_SIMP_TAC[REAL_LE_INV_EQ; REAL_LT_IMP_LE] THEN + MATCH_MP_TAC(SET_RULE `!s. x IN s /\ s SUBSET t ==> x IN t`) THEN + EXISTS_TAC `convex hull c:real^N->bool` THEN + REWRITE_TAC[CONVEX_HULL_SUBSET_CONVEX_CONE_HULL] THEN + FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN ASM_REWRITE_TAC[IN_INTER] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o GEN_REWRITE_RULE I [conic]) THEN + ASM_SIMP_TAC[REAL_LT_IMP_LE]);; + +(* ------------------------------------------------------------------------- *) +(* Decomposition of polyhedron into cone plus polytope and more corollaries. *) +(* ------------------------------------------------------------------------- *) + +let POLYHEDRON_POLYTOPE_SUMS = prove + (`!s t:real^N->bool. + polyhedron s /\ polytope t ==> polyhedron {x + y | x IN s /\ y IN t}`, + REPEAT STRIP_TAC THEN + REWRITE_TAC[POLYHEDRON_EQ_FINITE_EXPOSED_FACES] THEN REPEAT CONJ_TAC THENL + [MATCH_MP_TAC CLOSED_COMPACT_SUMS THEN + ASM_SIMP_TAC[POLYHEDRON_IMP_CLOSED; POLYTOPE_IMP_COMPACT]; + MATCH_MP_TAC CONVEX_SUMS THEN + ASM_SIMP_TAC[POLYHEDRON_IMP_CONVEX; POLYTOPE_IMP_CONVEX]; + MATCH_MP_TAC FINITE_SUBSET THEN + EXISTS_TAC `{ {x + y:real^N | x IN k /\ y IN l} | + k exposed_face_of s /\ l exposed_face_of t}` THEN + CONJ_TAC THENL + [ONCE_REWRITE_TAC[SET_RULE `k exposed_face_of s <=> + k IN {f | f exposed_face_of s}`] THEN + MATCH_MP_TAC FINITE_PRODUCT_DEPENDENT THEN + ASM_SIMP_TAC[FINITE_POLYHEDRON_EXPOSED_FACES; + POLYTOPE_IMP_POLYHEDRON]; + REWRITE_TAC[SUBSET; IN_ELIM_THM; GSYM CONJ_ASSOC] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC EXPOSED_FACE_OF_SUMS THEN + ASM_SIMP_TAC[POLYHEDRON_IMP_CONVEX; POLYTOPE_IMP_CONVEX]]]);; + +let POLYHEDRON_AS_CONE_PLUS_CONV = prove + (`!s:real^N->bool. + polyhedron s <=> ?t u. FINITE t /\ FINITE u /\ + s = {x + y | x IN convex_cone hull t /\ + y IN convex hull u}`, + REPEAT GEN_TAC THEN EQ_TAC THENL + [REWRITE_TAC[polyhedron; LEFT_IMP_EXISTS_THM]; + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC POLYHEDRON_POLYTOPE_SUMS THEN + ASM_SIMP_TAC[POLYTOPE_CONVEX_HULL; POLYHEDRON_CONVEX_CONE_HULL]] THEN + REWRITE_TAC[polyhedron; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `f:(real^N->bool)->bool` THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + DISCH_THEN(CONJUNCTS_THEN2 (ASSUME_TAC o SYM) MP_TAC) THEN + GEN_REWRITE_TAC (LAND_CONV o REDEPTH_CONV) [RIGHT_IMP_EXISTS_THM] THEN + REWRITE_TAC[SKOLEM_THM; LEFT_IMP_EXISTS_THM] THEN MAP_EVERY X_GEN_TAC + [`a:(real^N->bool)->real^N`; `b:(real^N->bool)->real`] THEN + ONCE_REWRITE_TAC[MESON[] `h = {x | P x} <=> {x | P x} = h`] THEN + DISCH_TAC THEN + ABBREV_TAC + `s':real^(N,1)finite_sum->bool = + {x | &0 <= drop(sndcart x) /\ + !h:real^N->bool. + h IN f ==> a h dot (fstcart x) <= b h * drop(sndcart x)}` THEN + SUBGOAL_THEN + `?t u. FINITE t /\ FINITE u /\ + (!y:real^(N,1)finite_sum. y IN t ==> drop(sndcart y) = &0) /\ + (!y. y IN u ==> drop(sndcart y) = &1) /\ + s' = convex_cone hull (t UNION u)` + STRIP_ASSUME_TAC THENL + [MP_TAC(ISPEC `s':real^(N,1)finite_sum->bool` + FINITELY_GENERATED_CONIC_POLYHEDRON) THEN + ANTS_TAC THENL + [EXPAND_TAC "s'" THEN REPEAT CONJ_TAC THENL + [REWRITE_TAC[polyhedron] THEN + EXISTS_TAC + `{ x:real^(N,1)finite_sum | + pastecart (vec 0) (--vec 1) dot x <= &0} INSERT + { {x | pastecart (a h) (--lift(b h)) dot x <= &0} | + (h:real^N->bool) IN f}` THEN + REWRITE_TAC[FINITE_INSERT; INTERS_INSERT; SIMPLE_IMAGE] THEN + ASM_SIMP_TAC[FINITE_IMAGE; FORALL_IN_INSERT; FORALL_IN_IMAGE] THEN + REPEAT CONJ_TAC THENL + [EXPAND_TAC "s'" THEN + REWRITE_TAC[EXTENSION; IN_ELIM_THM; FORALL_PASTECART; IN_INTER; + DOT_PASTECART; INTERS_IMAGE; FSTCART_PASTECART; + SNDCART_PASTECART; DOT_1; GSYM drop; DROP_NEG; LIFT_DROP] THEN + REWRITE_TAC[DROP_VEC; DOT_LZERO; REAL_MUL_LNEG; GSYM real_sub] THEN + REWRITE_TAC[REAL_MUL_LID; REAL_ARITH `x - y <= &0 <=> x <= y`]; + EXISTS_TAC `pastecart (vec 0) (--vec 1):real^(N,1)finite_sum` THEN + EXISTS_TAC `&0` THEN + REWRITE_TAC[PASTECART_EQ_VEC; VECTOR_NEG_EQ_0; VEC_EQ] THEN + ARITH_TAC; + X_GEN_TAC `h:real^N->bool` THEN DISCH_TAC THEN MAP_EVERY EXISTS_TAC + [`pastecart (a(h:real^N->bool)) (--lift(b h)):real^(N,1)finite_sum`; + `&0`] THEN + ASM_SIMP_TAC[PASTECART_EQ_VEC]]; + REWRITE_TAC[conic; IN_ELIM_THM; FSTCART_CMUL; SNDCART_CMUL] THEN + SIMP_TAC[DROP_CMUL; DOT_RMUL; REAL_LE_MUL] THEN + MESON_TAC[REAL_LE_LMUL; REAL_MUL_AC]; + REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN + EXISTS_TAC `vec 0:real^(N,1)finite_sum` THEN + REWRITE_TAC[IN_ELIM_THM; FSTCART_VEC; SNDCART_VEC] THEN + REWRITE_TAC[DROP_VEC; DOT_RZERO; REAL_LE_REFL; REAL_MUL_RZERO]]; + DISCH_THEN(X_CHOOSE_THEN `c:real^(N,1)finite_sum->bool` + STRIP_ASSUME_TAC) THEN + MAP_EVERY EXISTS_TAC + [`{x:real^(N,1)finite_sum | x IN c /\ drop(sndcart x) = &0}`; + `IMAGE (\x. inv(drop(sndcart x)) % x) + {x:real^(N,1)finite_sum | x IN c /\ ~(drop(sndcart x) = &0)}`] THEN + ASM_SIMP_TAC[FINITE_IMAGE; FINITE_RESTRICT; FORALL_IN_IMAGE] THEN + SIMP_TAC[IN_ELIM_THM; SNDCART_CMUL; DROP_CMUL; REAL_MUL_LINV] THEN + SUBGOAL_THEN + `!x:real^(N,1)finite_sum. x IN c ==> &0 <= drop(sndcart x)` + ASSUME_TAC THENL + [GEN_TAC THEN DISCH_TAC THEN + SUBGOAL_THEN `(x:real^(N,1)finite_sum) IN s'` MP_TAC THENL + [ASM_MESON_TAC[HULL_INC]; EXPAND_TAC "s'"] THEN + SIMP_TAC[IN_ELIM_THM]; + ALL_TAC] THEN + MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THEN + MATCH_MP_TAC HULL_MINIMAL THEN + REWRITE_TAC[CONVEX_CONE_CONVEX_CONE_HULL; UNION_SUBSET] THEN + SIMP_TAC[SUBSET; IN_ELIM_THM; HULL_INC; FORALL_IN_IMAGE] THEN + X_GEN_TAC `x:real^(N,1)finite_sum` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `x:real^(N,1)finite_sum`) THEN + ASM_SIMP_TAC[CONVEX_CONE_HULL_MUL; HULL_INC; REAL_LE_INV_EQ] THEN + ASM_REWRITE_TAC[REAL_ARITH `&0 <= x <=> x = &0 \/ &0 < x`] THEN + STRIP_TAC THENL + [MATCH_MP_TAC HULL_INC THEN ASM_REWRITE_TAC[IN_UNION; IN_ELIM_THM]; + SUBGOAL_THEN + `x:real^(N,1)finite_sum = + drop(sndcart x) % inv(drop(sndcart x)) % x` + SUBST1_TAC THENL + [ASM_SIMP_TAC[VECTOR_MUL_ASSOC; REAL_MUL_RINV; REAL_LT_IMP_NZ] THEN + REWRITE_TAC[VECTOR_MUL_LID]; + MATCH_MP_TAC CONVEX_CONE_HULL_MUL THEN + ASM_SIMP_TAC[REAL_LT_IMP_LE] THEN MATCH_MP_TAC HULL_INC THEN + REWRITE_TAC[IN_UNION] THEN DISJ2_TAC THEN + REWRITE_TAC[IN_IMAGE] THEN EXISTS_TAC `x:real^(N,1)finite_sum` THEN + ASM_SIMP_TAC[IN_ELIM_THM; REAL_LT_IMP_NZ]]]]; + EXISTS_TAC `IMAGE fstcart (t:real^(N,1)finite_sum->bool)` THEN + EXISTS_TAC `IMAGE fstcart (u:real^(N,1)finite_sum->bool)` THEN + ASM_SIMP_TAC[FINITE_IMAGE] THEN + SUBGOAL_THEN `s = {x:real^N | pastecart x (vec 1:real^1) IN s'}` + SUBST1_TAC THENL + [MAP_EVERY EXPAND_TAC ["s"; "s'"] THEN + REWRITE_TAC[IN_ELIM_THM; SNDCART_PASTECART; DROP_VEC; REAL_POS] THEN + GEN_REWRITE_TAC I [EXTENSION] THEN + REWRITE_TAC[FSTCART_PASTECART; IN_ELIM_THM; IN_INTERS; REAL_MUL_RID] THEN + ASM SET_TAC[]; + ASM_REWRITE_TAC[CONVEX_CONE_HULL_UNION]] THEN + REWRITE_TAC[EXTENSION; IN_ELIM_THM] THEN X_GEN_TAC `z:real^N` THEN + SIMP_TAC[CONVEX_CONE_HULL_LINEAR_IMAGE; CONVEX_HULL_LINEAR_IMAGE; + LINEAR_FSTCART] THEN + REWRITE_TAC[GSYM CONJ_ASSOC; RIGHT_EXISTS_AND_THM] THEN + REWRITE_TAC[EXISTS_IN_IMAGE] THEN + AP_TERM_TAC THEN GEN_REWRITE_TAC I [FUN_EQ_THM] THEN + X_GEN_TAC `a:real^(N,1)finite_sum` THEN REWRITE_TAC[] THEN + MATCH_MP_TAC(TAUT `(p ==> (q <=> r)) ==> (p /\ q <=> p /\ r)`) THEN + DISCH_TAC THEN AP_TERM_TAC THEN GEN_REWRITE_TAC I [FUN_EQ_THM] THEN + X_GEN_TAC `b:real^(N,1)finite_sum` THEN REWRITE_TAC[PASTECART_EQ] THEN + REWRITE_TAC[FSTCART_PASTECART; SNDCART_PASTECART; FSTCART_ADD; + SNDCART_ADD] THEN + ASM_CASES_TAC `fstcart(a:real^(N,1)finite_sum) + + fstcart(b:real^(N,1)finite_sum) = z` THEN + ASM_REWRITE_TAC[] THEN + SUBGOAL_THEN `sndcart(a:real^(N,1)finite_sum) = vec 0` SUBST1_TAC THENL + [UNDISCH_TAC `(a:real^(N,1)finite_sum) IN convex_cone hull t` THEN + SPEC_TAC(`a:real^(N,1)finite_sum`,`a:real^(N,1)finite_sum`) THEN + MATCH_MP_TAC HULL_INDUCT THEN ASM_SIMP_TAC[GSYM DROP_EQ; DROP_VEC] THEN + REWRITE_TAC[convex_cone; convex; conic; IN_ELIM_THM] THEN + SIMP_TAC[SNDCART_ADD; SNDCART_CMUL; DROP_ADD; DROP_CMUL] THEN + REWRITE_TAC[REAL_MUL_RZERO; REAL_ADD_RID; GSYM MEMBER_NOT_EMPTY] THEN + EXISTS_TAC `vec 0:real^(N,1)finite_sum` THEN + REWRITE_TAC[IN_ELIM_THM; SNDCART_VEC; DROP_VEC]; + REWRITE_TAC[VECTOR_ADD_LID]] THEN + ASM_CASES_TAC `u:real^(N,1)finite_sum->bool = {}` THENL + [ASM_REWRITE_TAC[CONVEX_CONE_HULL_EMPTY; CONVEX_HULL_EMPTY] THEN + REWRITE_TAC[IN_SING; NOT_IN_EMPTY] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + ASM_REWRITE_TAC[SNDCART_VEC; VEC_EQ] THEN ARITH_TAC; + ALL_TAC] THEN + ASM_SIMP_TAC[CONVEX_CONE_HULL_CONVEX_HULL_NONEMPTY; IN_ELIM_THM] THEN + SUBGOAL_THEN + `!y:real^(N,1)finite_sum. y IN convex hull u ==> sndcart y = vec 1` + (LABEL_TAC "*") + THENL + [MATCH_MP_TAC HULL_INDUCT THEN ASM_SIMP_TAC[GSYM DROP_EQ; DROP_VEC] THEN + REWRITE_TAC[convex; IN_ELIM_THM] THEN + SIMP_TAC[SNDCART_ADD; SNDCART_CMUL; DROP_ADD; DROP_CMUL] THEN + SIMP_TAC[REAL_MUL_RID]; + ALL_TAC] THEN + EQ_TAC THEN REWRITE_TAC[LEFT_AND_EXISTS_THM; LEFT_IMP_EXISTS_THM] THENL + [MAP_EVERY X_GEN_TAC [`c:real`; `d:real^(N,1)finite_sum`] THEN + DISCH_THEN(CONJUNCTS_THEN2 STRIP_ASSUME_TAC MP_TAC) THEN + ASM_SIMP_TAC[SNDCART_CMUL; VECTOR_MUL_EQ_0; VECTOR_ARITH + `x:real^N = c % x <=> (c - &1) % x = vec 0`] THEN + ASM_SIMP_TAC[REAL_SUB_0; VEC_EQ; ARITH_EQ; VECTOR_MUL_LID]; + DISCH_TAC THEN ASM_SIMP_TAC[] THEN EXISTS_TAC `&1` THEN + ASM_REWRITE_TAC[REAL_POS; VECTOR_MUL_LID] THEN ASM_MESON_TAC[]]]);; + +let POLYHEDRON_LINEAR_IMAGE = prove + (`!f:real^M->real^N s. + linear f /\ polyhedron s ==> polyhedron(IMAGE f s)`, + REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + REWRITE_TAC[POLYHEDRON_AS_CONE_PLUS_CONV; LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`t:real^M->bool`; `u:real^M->bool`] THEN STRIP_TAC THEN + EXISTS_TAC `IMAGE (f:real^M->real^N) t` THEN + EXISTS_TAC `IMAGE (f:real^M->real^N) u` THEN + ASM_SIMP_TAC[FINITE_IMAGE] THEN + ASM_SIMP_TAC[CONVEX_CONE_HULL_LINEAR_IMAGE; CONVEX_HULL_LINEAR_IMAGE] THEN + REWRITE_TAC[EXTENSION; IN_IMAGE; IN_ELIM_THM] THEN + FIRST_X_ASSUM(MP_TAC o MATCH_MP LINEAR_ADD) THEN MESON_TAC[]);; + +let POLYHEDRON_SUMS = prove + (`!s t:real^N->bool. + polyhedron s /\ polyhedron t ==> polyhedron {x + y | x IN s /\ y IN t}`, + REPEAT GEN_TAC THEN REWRITE_TAC[POLYHEDRON_AS_CONE_PLUS_CONV] THEN + REWRITE_TAC[LEFT_AND_EXISTS_THM; LEFT_IMP_EXISTS_THM] THEN + REWRITE_TAC[RIGHT_AND_EXISTS_THM; LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC + [`t1:real^N->bool`; `u1:real^N->bool`; + `t2:real^N->bool`; `u2:real^N->bool`] THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + EXISTS_TAC `t1 UNION t2:real^N->bool` THEN + EXISTS_TAC `{u + v:real^N | u IN u1 /\ v IN u2}` THEN + REWRITE_TAC[CONVEX_CONE_HULL_UNION; CONVEX_HULL_SUMS] THEN + ASM_SIMP_TAC[FINITE_PRODUCT_DEPENDENT; FINITE_UNION] THEN + REWRITE_TAC[SET_RULE + `{h x y | x IN {f a b | P a /\ Q b} /\ + y IN {g a b | R a /\ S b}} = + {h (f a b) (g c d) | P a /\ Q b /\ R c /\ S d}`] THEN + REWRITE_TAC[EXTENSION; IN_ELIM_THM] THEN MESON_TAC[VECTOR_ADD_AC]);; + +(* ------------------------------------------------------------------------- *) +(* Farkas's lemma (2 variants) and stronger separation for polyhedra. *) +(* ------------------------------------------------------------------------- *) + +let FARKAS_LEMMA = prove + (`!A:real^N^M b. + (?x:real^N. + A ** x = b /\ + (!i. 1 <= i /\ i <= dimindex(:N) ==> &0 <= x$i)) <=> + ~(?y:real^M. + b dot y < &0 /\ + (!i. 1 <= i /\ i <= dimindex(:N) ==> &0 <= (transp A ** y)$i))`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC(TAUT + `(q ==> ~p) /\ (~p ==> q) ==> (p <=> ~q)`) THEN + CONJ_TAC THENL + [REPEAT STRIP_TAC THEN + SUBGOAL_THEN `y dot ((A:real^N^M) ** x - b) = &0` MP_TAC THENL + [ASM_REWRITE_TAC[VECTOR_SUB_REFL; DOT_RZERO]; ALL_TAC] THEN + RULE_ASSUM_TAC(ONCE_REWRITE_RULE[DOT_SYM]) THEN + REWRITE_TAC[DOT_RSUB; REAL_SUB_0] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH + `y < &0 ==> &0 <= x ==> ~(x = y)`)) THEN + ONCE_REWRITE_TAC[GSYM DOT_LMUL_MATRIX] THEN + REWRITE_TAC[VECTOR_MATRIX_MUL_TRANSP; dot] THEN + MATCH_MP_TAC SUM_POS_LE THEN + ASM_SIMP_TAC[REAL_LE_MUL; IN_NUMSEG; FINITE_NUMSEG]; + DISCH_TAC THEN MP_TAC(ISPECL + [`{(A:real^N^M) ** (x:real^N) | + !i. 1 <= i /\ i <= dimindex(:N) ==> &0 <= x$i}`; + `b:real^M`] SEPARATING_HYPERPLANE_CLOSED_POINT) THEN + REWRITE_TAC[FORALL_IN_GSPEC] THEN ANTS_TAC THENL + [REWRITE_TAC[IN_ELIM_THM; CONJ_ASSOC] THEN + CONJ_TAC THENL [ALL_TAC; ASM_MESON_TAC[]] THEN + ONCE_REWRITE_TAC[SIMPLE_IMAGE_GEN] THEN + SIMP_TAC[CONVEX_POSITIVE_ORTHANT; CONVEX_LINEAR_IMAGE; + MATRIX_VECTOR_MUL_LINEAR] THEN + MATCH_MP_TAC POLYHEDRON_IMP_CLOSED THEN + MATCH_MP_TAC POLYHEDRON_LINEAR_IMAGE THEN + REWRITE_TAC[MATRIX_VECTOR_MUL_LINEAR; POLYHEDRON_POSITIVE_ORTHANT]; + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `y:real^M` THEN + DISCH_THEN(X_CHOOSE_THEN `c:real` STRIP_ASSUME_TAC) THEN + ONCE_REWRITE_TAC[DOT_SYM] THEN + FIRST_ASSUM(MP_TAC o SPEC `vec 0:real^N`) THEN + REWRITE_TAC[MATRIX_VECTOR_MUL_RZERO; DOT_RZERO] THEN + REWRITE_TAC[real_gt; VEC_COMPONENT; REAL_LE_REFL] THEN + DISCH_TAC THEN CONJ_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN + X_GEN_TAC `k:num` THEN STRIP_TAC THEN + ONCE_REWRITE_TAC[GSYM REAL_NOT_LT] THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC + `c / (transp(A:real^N^M) ** (y:real^M))$k % basis k:real^N`) THEN + ASM_SIMP_TAC[VECTOR_MUL_COMPONENT; BASIS_COMPONENT] THEN + ONCE_REWRITE_TAC[GSYM DOT_LMUL_MATRIX] THEN + ASM_SIMP_TAC[DOT_RMUL; DOT_BASIS; VECTOR_MATRIX_MUL_TRANSP] THEN + ASM_SIMP_TAC[REAL_FIELD `y < &0 ==> x / y * y = x`] THEN + REWRITE_TAC[REAL_LT_REFL; real_gt] THEN + GEN_TAC THEN COND_CASES_TAC THEN + ASM_REWRITE_TAC[REAL_MUL_RZERO; REAL_LE_REFL; REAL_MUL_RID] THEN + ONCE_REWRITE_TAC[REAL_ARITH `x / y:real = --x * -- inv y`] THEN + MATCH_MP_TAC REAL_LE_MUL THEN + REWRITE_TAC[REAL_ARITH `&0 <= --x <=> ~(&0 < x)`; REAL_LT_INV_EQ] THEN + ASM_REAL_ARITH_TAC]]);; + +let FARKAS_LEMMA_ALT = prove + (`!A:real^N^M b. + (?x:real^N. + (!i. 1 <= i /\ i <= dimindex(:M) ==> (A ** x)$i <= b$i)) <=> + ~(?y:real^M. + (!i. 1 <= i /\ i <= dimindex(:M) ==> &0 <= y$i) /\ + y ** A = vec 0 /\ b dot y < &0)`, + REPEAT GEN_TAC THEN + MATCH_MP_TAC(TAUT `~(p /\ q) /\ (~p ==> q) ==> (p <=> ~q)`) THEN + REPEAT STRIP_TAC THENL + [SUBGOAL_THEN `&0 <= (b - (A:real^N^M) ** x) dot y` MP_TAC THENL + [REWRITE_TAC[dot] THEN MATCH_MP_TAC SUM_POS_LE THEN + REWRITE_TAC[FINITE_NUMSEG; IN_NUMSEG] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_LE_MUL THEN + ASM_SIMP_TAC[VECTOR_SUB_COMPONENT; REAL_SUB_LE]; + REWRITE_TAC[DOT_LSUB; REAL_SUB_LE] THEN REWRITE_TAC[REAL_NOT_LE] THEN + GEN_REWRITE_TAC RAND_CONV [DOT_SYM] THEN + REWRITE_TAC[GSYM DOT_LMUL_MATRIX] THEN + ASM_REWRITE_TAC[DOT_LZERO]]; + MP_TAC(ISPECL + [`{(A:real^N^M) ** (x:real^N) + s |x,s| + !i. 1 <= i /\ i <= dimindex(:M) ==> &0 <= s$i}`; + `b:real^M`] SEPARATING_HYPERPLANE_CLOSED_POINT) THEN + REWRITE_TAC[FORALL_IN_GSPEC] THEN ANTS_TAC THENL + [REWRITE_TAC[IN_ELIM_THM; CONJ_ASSOC] THEN CONJ_TAC THENL + [ONCE_REWRITE_TAC[SET_RULE + `{f x + y | x,y | P y} = + {z + y | z,y | z IN IMAGE (f:real^M->real^N) (:real^M) /\ + y IN {w | P w}}`] THEN + SIMP_TAC[CONVEX_SUMS; CONVEX_POSITIVE_ORTHANT; CONVEX_LINEAR_IMAGE; + MATRIX_VECTOR_MUL_LINEAR; CONVEX_UNIV] THEN + MATCH_MP_TAC POLYHEDRON_IMP_CLOSED THEN + MATCH_MP_TAC POLYHEDRON_SUMS THEN + ASM_SIMP_TAC[POLYHEDRON_LINEAR_IMAGE; POLYHEDRON_UNIV; + MATRIX_VECTOR_MUL_LINEAR; POLYHEDRON_POSITIVE_ORTHANT]; + POP_ASSUM MP_TAC THEN REWRITE_TAC[CONTRAPOS_THM] THEN + MATCH_MP_TAC MONO_EXISTS THEN REPEAT STRIP_TAC THEN + ASM_SIMP_TAC[VECTOR_ADD_COMPONENT; REAL_LE_ADDR]]; + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `y:real^M` THEN + DISCH_THEN(X_CHOOSE_THEN `c:real` STRIP_ASSUME_TAC) THEN + ONCE_REWRITE_TAC[DOT_SYM] THEN + FIRST_ASSUM(MP_TAC o SPECL [`vec 0:real^N`; `vec 0:real^M`]) THEN + REWRITE_TAC[MATRIX_VECTOR_MUL_RZERO; VECTOR_ADD_RID; DOT_RZERO] THEN + REWRITE_TAC[real_gt; VEC_COMPONENT; REAL_LE_REFL] THEN + DISCH_TAC THEN REWRITE_TAC[CONJ_ASSOC] THEN + CONJ_TAC THENL [ALL_TAC; ASM_REAL_ARITH_TAC] THEN CONJ_TAC THENL + [X_GEN_TAC `k:num` THEN STRIP_TAC THEN + ONCE_REWRITE_TAC[GSYM REAL_NOT_LT] THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPECL + [`vec 0:real^N`; `--c / --((y:real^M)$k) % basis k:real^M`]) THEN + ASM_SIMP_TAC[MATRIX_VECTOR_MUL_RZERO; VECTOR_ADD_LID; + DOT_RMUL; DOT_BASIS; REAL_FIELD + `y < &0 ==> c / --y * y = --c`] THEN + SIMP_TAC[REAL_NEG_NEG; REAL_LT_REFL; VECTOR_MUL_COMPONENT; real_gt] THEN + ASM_SIMP_TAC[BASIS_COMPONENT] THEN REPEAT STRIP_TAC THEN + COND_CASES_TAC THEN + ASM_REWRITE_TAC[REAL_MUL_RZERO; REAL_MUL_RID; REAL_LE_REFL] THEN + MATCH_MP_TAC REAL_LE_DIV THEN ASM_REAL_ARITH_TAC; + FIRST_X_ASSUM(MP_TAC o SPECL + [`c / norm((y:real^M) ** (A:real^N^M)) pow 2 % + (transp A ** y)`; `vec 0:real^M`]) THEN + SIMP_TAC[VEC_COMPONENT; REAL_LE_REFL; VECTOR_ADD_RID] THEN + ONCE_REWRITE_TAC[GSYM DOT_LMUL_MATRIX] THEN + REWRITE_TAC[GSYM VECTOR_MATRIX_MUL_TRANSP; DOT_RMUL] THEN + ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN DISCH_TAC THEN + ASM_SIMP_TAC[REAL_DIV_RMUL; NORM_POW_2; DOT_EQ_0] THEN + REAL_ARITH_TAC]]]);; + +let SEPARATING_HYPERPLANE_POLYHEDRA = prove + (`!s t:real^N->bool. + polyhedron s /\ polyhedron t /\ ~(s = {}) /\ ~(t = {}) /\ DISJOINT s t + ==> ?a b. ~(a = vec 0) /\ + (!x. x IN s ==> a dot x < b) /\ + (!x. x IN t ==> a dot x > b)`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPEC `{x + y:real^N | x IN s /\ y IN IMAGE (--) t}` + SEPARATING_HYPERPLANE_CLOSED_0) THEN + ANTS_TAC THENL + [ASM_SIMP_TAC[CONVEX_SUMS; CONVEX_NEGATIONS; POLYHEDRON_IMP_CONVEX] THEN + CONJ_TAC THENL + [MATCH_MP_TAC POLYHEDRON_IMP_CLOSED THEN + MATCH_MP_TAC POLYHEDRON_SUMS THEN ASM_SIMP_TAC[POLYHEDRON_NEGATIONS]; + REWRITE_TAC[IN_IMAGE; IN_ELIM_THM] THEN + REWRITE_TAC[VECTOR_ARITH `y = --x:real^N <=> --y = x`] THEN + REWRITE_TAC[UNWIND_THM1] THEN ONCE_REWRITE_TAC[CONJ_SYM] THEN + REWRITE_TAC[VECTOR_ARITH `vec 0:real^N = x + y <=> y = --x`] THEN + REWRITE_TAC[UNWIND_THM2; VECTOR_NEG_NEG] THEN ASM SET_TAC[]]; + REWRITE_TAC[FORALL_IN_GSPEC; IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN + REWRITE_TAC[FORALL_IN_IMAGE; GSYM VECTOR_SUB; LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`a:real^N`; `k:real`] THEN + REWRITE_TAC[RIGHT_IMP_FORALL_THM; IMP_IMP; DOT_RSUB] THEN STRIP_TAC THEN + EXISTS_TAC `--a:real^N` THEN ASM_REWRITE_TAC[VECTOR_NEG_EQ_0] THEN + MP_TAC(ISPEC `IMAGE (\x:real^N. a dot x) s` INF) THEN + MP_TAC(ISPEC `IMAGE (\x:real^N. a dot x) t` SUP) THEN + ASM_REWRITE_TAC[FORALL_IN_IMAGE; IMAGE_EQ_EMPTY] THEN + MAP_EVERY ABBREV_TAC + [`u = inf(IMAGE (\x:real^N. a dot x) s)`; + `v = sup(IMAGE (\x:real^N. a dot x) t)`] THEN + ANTS_TAC THENL + [MP_TAC(GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY] + (ASSUME `~(s:real^N->bool = {})`)) THEN + DISCH_THEN(X_CHOOSE_TAC `z:real^N`) THEN + EXISTS_TAC `a dot (z:real^N) - k` THEN + X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`z:real^N`; `x:real^N`]) THEN + ASM_REWRITE_TAC[] THEN REAL_ARITH_TAC; + STRIP_TAC] THEN + ANTS_TAC THENL + [MP_TAC(GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY] + (ASSUME `~(t:real^N->bool = {})`)) THEN + DISCH_THEN(X_CHOOSE_TAC `z:real^N`) THEN + EXISTS_TAC `a dot (z:real^N) + k` THEN + X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`x:real^N`; `z:real^N`]) THEN + ASM_REWRITE_TAC[] THEN REAL_ARITH_TAC; + STRIP_TAC] THEN + SUBGOAL_THEN `k <= u - v` ASSUME_TAC THENL + [REWRITE_TAC[REAL_LE_SUB_LADD] THEN EXPAND_TAC "u" THEN + MATCH_MP_TAC REAL_LE_INF THEN + ASM_REWRITE_TAC[IMAGE_EQ_EMPTY; FORALL_IN_IMAGE] THEN + GEN_TAC THEN DISCH_TAC THEN + ONCE_REWRITE_TAC[REAL_ARITH `k + v <= u <=> v <= u - k`] THEN + EXPAND_TAC "v" THEN MATCH_MP_TAC REAL_SUP_LE THEN + ASM_REWRITE_TAC[IMAGE_EQ_EMPTY; FORALL_IN_IMAGE] THEN + ASM_MESON_TAC[REAL_ARITH `x - y > k ==> y <= x - k`]; + EXISTS_TAC `--((u + v) / &2)` THEN REWRITE_TAC[real_gt] THEN + REWRITE_TAC[DOT_LNEG; REAL_LT_NEG2] THEN REPEAT STRIP_TAC THENL + [MATCH_MP_TAC REAL_LTE_TRANS THEN EXISTS_TAC `u:real`; + MATCH_MP_TAC REAL_LET_TRANS THEN EXISTS_TAC `v:real`] THEN + ASM_SIMP_TAC[] THEN ASM_REAL_ARITH_TAC]]);; + +(* ------------------------------------------------------------------------- *) +(* Relative and absolute frontier of a polytope. *) +(* ------------------------------------------------------------------------- *) + +let RELATIVE_BOUNDARY_OF_CONVEX_HULL = prove + (`!s:real^N->bool. + ~affine_dependent s + ==> (convex hull s) DIFF relative_interior(convex hull s) = + UNIONS { convex hull (s DELETE a) | a | a IN s}`, + REPEAT STRIP_TAC THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP AFFINE_INDEPENDENT_IMP_FINITE) THEN + REPEAT_TCL DISJ_CASES_THEN MP_TAC (ARITH_RULE + `CARD(s:real^N->bool) = 0 \/ CARD s = 1 \/ 2 <= CARD s`) + THENL + [ASM_SIMP_TAC[CARD_EQ_0; CONVEX_HULL_EMPTY] THEN SET_TAC[]; + DISCH_TAC THEN MP_TAC(HAS_SIZE_CONV `(s:real^N->bool) HAS_SIZE 1`) THEN + ASM_SIMP_TAC[HAS_SIZE; LEFT_IMP_EXISTS_THM; CONVEX_HULL_SING] THEN + REWRITE_TAC[RELATIVE_INTERIOR_SING; DIFF_EQ_EMPTY] THEN + REPEAT STRIP_TAC THEN CONV_TAC SYM_CONV THEN REWRITE_TAC[EMPTY_UNIONS] THEN + REWRITE_TAC[FORALL_IN_GSPEC; IN_SING; FORALL_UNWIND_THM2] THEN + REWRITE_TAC[CONVEX_HULL_EQ_EMPTY] THEN SET_TAC[]; + DISCH_TAC THEN + ASM_SIMP_TAC[POLYHEDRON_CONVEX_HULL; RELATIVE_BOUNDARY_OF_POLYHEDRON] THEN + ASM_SIMP_TAC[FACET_OF_CONVEX_HULL_AFFINE_INDEPENDENT_ALT] THEN + SET_TAC[]]);; + +let RELATIVE_FRONTIER_OF_CONVEX_HULL = prove + (`!s:real^N->bool. + ~affine_dependent s + ==> relative_frontier(convex hull s) = + UNIONS { convex hull (s DELETE a) | a | a IN s}`, + REPEAT STRIP_TAC THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP AFFINE_INDEPENDENT_IMP_FINITE) THEN + ASM_SIMP_TAC[relative_frontier; GSYM RELATIVE_BOUNDARY_OF_CONVEX_HULL] THEN + AP_THM_TAC THEN AP_TERM_TAC THEN MATCH_MP_TAC CLOSURE_CLOSED THEN + ASM_SIMP_TAC[COMPACT_IMP_CLOSED; FINITE_IMP_COMPACT; COMPACT_CONVEX_HULL]);; + +let FRONTIER_OF_CONVEX_HULL = prove + (`!s:real^N->bool. + s HAS_SIZE (dimindex(:N) + 1) + ==> frontier(convex hull s) = + UNIONS { convex hull (s DELETE a) | a | a IN s}`, + REWRITE_TAC[HAS_SIZE] THEN REPEAT STRIP_TAC THEN + ASM_CASES_TAC `affine_dependent(s:real^N->bool)` THENL + [REWRITE_TAC[frontier] THEN MATCH_MP_TAC EQ_TRANS THEN + EXISTS_TAC `(convex hull s:real^N->bool) DIFF {}` THEN CONJ_TAC THENL + [BINOP_TAC THEN + ASM_SIMP_TAC[INTERIOR_CONVEX_HULL_EQ_EMPTY; frontier; HAS_SIZE] THEN + MATCH_MP_TAC CLOSURE_CLOSED THEN + ASM_SIMP_TAC[CLOSURE_CLOSED; COMPACT_IMP_CLOSED; COMPACT_CONVEX_HULL; + FINITE_IMP_COMPACT; FINITE_INSERT; FINITE_EMPTY]; + REWRITE_TAC[DIFF_EMPTY] THEN MATCH_MP_TAC SUBSET_ANTISYM THEN + CONJ_TAC THENL + [GEN_REWRITE_TAC LAND_CONV [CARATHEODORY_AFF_DIM] THEN + ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN + GEN_REWRITE_TAC I [SUBSET] THEN + REWRITE_TAC[IN_ELIM_THM; UNIONS_IMAGE] THEN + X_GEN_TAC `x:real^N` THEN + DISCH_THEN(X_CHOOSE_THEN `t:real^N->bool` STRIP_ASSUME_TAC) THEN + MP_TAC(ISPEC `s:real^N->bool` AFFINE_INDEPENDENT_IFF_CARD) THEN + ASM_REWRITE_TAC[GSYM INT_OF_NUM_ADD] THEN + REWRITE_TAC[INT_ARITH `(x + &1) - &1:int = x`] THEN DISCH_TAC THEN + SUBGOAL_THEN `(t:real^N->bool) PSUBSET s` ASSUME_TAC THENL + [ASM_REWRITE_TAC[PSUBSET] THEN + DISCH_THEN(MP_TAC o AP_TERM `CARD:(real^N->bool)->num`) THEN + MATCH_MP_TAC(ARITH_RULE `t:num < s ==> t = s ==> F`) THEN + ASM_REWRITE_TAC[ARITH_RULE `x < n + 1 <=> x <= n`] THEN + REWRITE_TAC[GSYM INT_OF_NUM_LE] THEN MATCH_MP_TAC INT_LE_TRANS THEN + EXISTS_TAC `aff_dim(s:real^N->bool) + &1` THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC(INT_ARITH + `s:int <= n /\ ~(s = n) ==> s + &1 <= n`) THEN + ASM_REWRITE_TAC[AFF_DIM_LE_UNIV]; + SUBGOAL_THEN `?a:real^N. a IN s /\ ~(a IN t)` MP_TAC THENL + [ASM SET_TAC[]; MATCH_MP_TAC MONO_EXISTS] THEN + X_GEN_TAC `a:real^N` THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + SUBGOAL_THEN + `(convex hull t) SUBSET convex hull (s DELETE (a:real^N))` + MP_TAC THENL + [MATCH_MP_TAC HULL_MONO THEN ASM SET_TAC[]; ASM SET_TAC[]]]; + ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN REWRITE_TAC[UNIONS_IMAGE] THEN + REWRITE_TAC[SUBSET; IN_ELIM_THM; LEFT_IMP_EXISTS_THM] THEN + ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN + REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; GSYM SUBSET] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC HULL_MONO THEN SET_TAC[]]]; + MATCH_MP_TAC EQ_TRANS THEN + EXISTS_TAC + `(convex hull s) DIFF relative_interior(convex hull s):real^N->bool` THEN + CONJ_TAC THENL + [ASM_SIMP_TAC[GSYM RELATIVE_BOUNDARY_OF_CONVEX_HULL; frontier] THEN + BINOP_TAC THENL + [MATCH_MP_TAC CLOSURE_CLOSED THEN + ASM_SIMP_TAC[CLOSURE_CLOSED; COMPACT_IMP_CLOSED; COMPACT_CONVEX_HULL; + FINITE_IMP_COMPACT; FINITE_INSERT; FINITE_EMPTY]; + CONV_TAC SYM_CONV THEN MATCH_MP_TAC RELATIVE_INTERIOR_INTERIOR THEN + REWRITE_TAC[AFFINE_HULL_CONVEX_HULL] THEN + REWRITE_TAC[GSYM AFF_DIM_EQ_FULL] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I + [AFFINE_INDEPENDENT_IFF_CARD]) THEN + ASM_REWRITE_TAC[GSYM INT_OF_NUM_ADD] THEN INT_ARITH_TAC]; + ASM_SIMP_TAC[RELATIVE_BOUNDARY_OF_POLYHEDRON; + POLYHEDRON_CONVEX_HULL; FINITE_INSERT; FINITE_EMPTY] THEN + ASM_SIMP_TAC[FACET_OF_CONVEX_HULL_AFFINE_INDEPENDENT_ALT] THEN + REWRITE_TAC[ARITH_RULE `2 <= n + 1 <=> 1 <= n`; DIMINDEX_GE_1] THEN + ASM SET_TAC[]]]);; + +(* ------------------------------------------------------------------------- *) +(* Special case of a triangle. *) +(* ------------------------------------------------------------------------- *) + +let RELATIVE_BOUNDARY_OF_TRIANGLE = prove + (`!a b c:real^N. + ~collinear {a,b,c} + ==> convex hull {a,b,c} DIFF relative_interior(convex hull {a,b,c}) = + segment[a,b] UNION segment[b,c] UNION segment[c,a]`, + REPEAT STRIP_TAC THEN + ONCE_REWRITE_TAC[SET_RULE `s UNION t UNION u = t UNION u UNION s`] THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE RAND_CONV + [COLLINEAR_3_EQ_AFFINE_DEPENDENT]) THEN + REWRITE_TAC[DE_MORGAN_THM; SEGMENT_CONVEX_HULL] THEN STRIP_TAC THEN + ASM_SIMP_TAC[RELATIVE_BOUNDARY_OF_CONVEX_HULL] THEN + ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN + REWRITE_TAC[IMAGE_CLAUSES; UNIONS_INSERT; UNIONS_0; UNION_EMPTY] THEN + REPEAT BINOP_TAC THEN REWRITE_TAC[] THEN ASM SET_TAC[]);; + +let RELATIVE_FRONTIER_OF_TRIANGLE = prove + (`!a b c:real^N. + ~collinear {a,b,c} + ==> relative_frontier(convex hull {a,b,c}) = + segment[a,b] UNION segment[b,c] UNION segment[c,a]`, + REPEAT STRIP_TAC THEN + ASM_SIMP_TAC[GSYM RELATIVE_BOUNDARY_OF_TRIANGLE; relative_frontier] THEN + AP_THM_TAC THEN AP_TERM_TAC THEN MATCH_MP_TAC CLOSURE_CLOSED THEN + ASM_SIMP_TAC[COMPACT_IMP_CLOSED; FINITE_IMP_COMPACT; COMPACT_CONVEX_HULL; + FINITE_INSERT; FINITE_EMPTY]);; + +let FRONTIER_OF_TRIANGLE = prove + (`!a b c:real^2. + frontier(convex hull {a,b,c}) = + segment[a,b] UNION segment[b,c] UNION segment[c,a]`, + REPEAT STRIP_TAC THEN REWRITE_TAC[SEGMENT_CONVEX_HULL] THEN + ONCE_REWRITE_TAC[SET_RULE `s UNION t UNION u = t UNION u UNION s`] THEN + MAP_EVERY (fun t -> ASM_CASES_TAC t THENL + [ASM_REWRITE_TAC[INSERT_AC; UNION_ACI] THEN + SIMP_TAC[GSYM SEGMENT_CONVEX_HULL; frontier; CLOSURE_SEGMENT; + INTERIOR_SEGMENT; DIMINDEX_2; LE_REFL; DIFF_EMPTY] THEN + REWRITE_TAC[CONVEX_HULL_SING] THEN + REWRITE_TAC[SET_RULE `s = s UNION {a} <=> a IN s`; + SET_RULE `s = {a} UNION s <=> a IN s`] THEN + REWRITE_TAC[ENDS_IN_SEGMENT]; + ALL_TAC]) + [`b:real^2 = a`; `c:real^2 = a`; `c:real^2 = b`] THEN + SUBGOAL_THEN `{a:real^2,b,c} HAS_SIZE (dimindex(:2) + 1)` ASSUME_TAC THENL + [SIMP_TAC[HAS_SIZE; CARD_CLAUSES; FINITE_INSERT; FINITE_EMPTY] THEN + ASM_REWRITE_TAC[IN_INSERT; NOT_IN_EMPTY; DIMINDEX_2] THEN + CONV_TAC NUM_REDUCE_CONV; + ASM_SIMP_TAC[FRONTIER_OF_CONVEX_HULL] THEN + ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN + REWRITE_TAC[IMAGE_CLAUSES; UNIONS_INSERT; UNIONS_0; UNION_EMPTY] THEN + REPEAT BINOP_TAC THEN REWRITE_TAC[] THEN ASM SET_TAC[]]);; + +let INSIDE_OF_TRIANGLE = prove + (`!a b c:real^2. + inside(segment[a,b] UNION segment[b,c] UNION segment[c,a]) = + interior(convex hull {a,b,c})`, + REPEAT GEN_TAC THEN REWRITE_TAC[GSYM FRONTIER_OF_TRIANGLE] THEN + MATCH_MP_TAC INSIDE_FRONTIER_EQ_INTERIOR THEN + REWRITE_TAC[CONVEX_CONVEX_HULL] THEN MATCH_MP_TAC BOUNDED_CONVEX_HULL THEN + MATCH_MP_TAC FINITE_IMP_BOUNDED THEN + REWRITE_TAC[FINITE_INSERT; FINITE_EMPTY]);; + +let INTERIOR_OF_TRIANGLE = prove + (`!a b c:real^2. + interior(convex hull {a,b,c}) = + (convex hull {a,b,c}) DIFF + (segment[a,b] UNION segment[b,c] UNION segment[c,a])`, + REPEAT GEN_TAC THEN REWRITE_TAC[GSYM FRONTIER_OF_TRIANGLE; frontier] THEN + MATCH_MP_TAC(SET_RULE `i SUBSET s /\ c = s ==> i = s DIFF (c DIFF i)`) THEN + REWRITE_TAC[INTERIOR_SUBSET] THEN MATCH_MP_TAC CLOSURE_CONVEX_HULL THEN + SIMP_TAC[FINITE_IMP_COMPACT; FINITE_INSERT; FINITE_EMPTY]);; + +(* ------------------------------------------------------------------------- *) +(* A ridge is the intersection of precisely two facets. *) +(* ------------------------------------------------------------------------- *) + +let POLYHEDRON_RIDGE_TWO_FACETS = prove + (`!p:real^N->bool r. + polyhedron p /\ r face_of p /\ ~(r = {}) /\ aff_dim r = aff_dim p - &2 + ==> ?f1 f2. f1 face_of p /\ aff_dim f1 = aff_dim p - &1 /\ + f2 face_of p /\ aff_dim f2 = aff_dim p - &1 /\ + ~(f1 = f2) /\ r SUBSET f1 /\ r SUBSET f2 /\ f1 INTER f2 = r /\ + !f. f face_of p /\ aff_dim f = aff_dim p - &1 /\ r SUBSET f + ==> f = f1 \/ f = f2`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`p:real^N->bool`; `r:real^N->bool`] FACE_OF_POLYHEDRON) THEN + ANTS_TAC THENL [ASM_MESON_TAC[INT_ARITH `~(p:int = p - &2)`]; ALL_TAC] THEN + SUBGOAL_THEN `&2 <= aff_dim(p:real^N->bool)` ASSUME_TAC THENL + [MP_TAC(ISPEC `r:real^N->bool` AFF_DIM_GE) THEN + MP_TAC(ISPEC `r:real^N->bool` AFF_DIM_EQ_MINUS1) THEN + ASM_REWRITE_TAC[] THEN INT_ARITH_TAC; + ALL_TAC] THEN + SUBGOAL_THEN + `{f:real^N->bool | f facet_of p /\ r SUBSET f} = + {f | f face_of p /\ aff_dim f = aff_dim p - &1 /\ r SUBSET f}` + SUBST1_TAC THENL + [GEN_REWRITE_TAC I [EXTENSION] THEN + ASM_REWRITE_TAC[IN_ELIM_THM; facet_of] THEN + X_GEN_TAC `f:real^N->bool` THEN + ASM_CASES_TAC `f:real^N->bool = {}` THEN + ASM_REWRITE_TAC[AFF_DIM_EMPTY; GSYM CONJ_ASSOC] THEN ASM_INT_ARITH_TAC; + DISCH_THEN(MP_TAC o SYM)] THEN + ASM_CASES_TAC + `{f:real^N->bool | f face_of p /\ aff_dim f = aff_dim p - &1 /\ r SUBSET f} + = {}` + THENL + [ASM_REWRITE_TAC[INTERS_0] THEN DISCH_THEN(ASSUME_TAC o SYM) THEN + UNDISCH_TAC `aff_dim(r:real^N->bool) = aff_dim(p:real^N->bool) - &2` THEN + ASM_REWRITE_TAC[AFF_DIM_UNIV; DIMINDEX_3] THEN + MP_TAC(ISPEC `p:real^N->bool` AFF_DIM_LE_UNIV) THEN INT_ARITH_TAC; + ALL_TAC] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN + REWRITE_TAC[LEFT_IMP_EXISTS_THM; IN_ELIM_THM] THEN + X_GEN_TAC `f1:real^N->bool` THEN STRIP_TAC THEN + ASM_CASES_TAC + `{f:real^N->bool | f face_of p /\ aff_dim f = aff_dim p - &1 /\ r SUBSET f} + = {f1}` + THENL + [ASM_REWRITE_TAC[INTERS_1] THEN + ASM_MESON_TAC[INT_ARITH `~(x - &2:int = x - &1)`]; + ALL_TAC] THEN + FIRST_X_ASSUM(MP_TAC o MATCH_MP (SET_RULE + `~(s = {a}) ==> a IN s ==> ?b. ~(b = a) /\ b IN s`)) THEN + ASM_REWRITE_TAC[IN_ELIM_THM; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `f2:real^N->bool` THEN STRIP_TAC THEN + ASM_CASES_TAC + `{f:real^N->bool | f face_of p /\ aff_dim f = aff_dim p - &1 /\ r SUBSET f} + = {f1,f2}` + THENL + [ASM_REWRITE_TAC[INTERS_2] THEN DISCH_TAC THEN + MAP_EVERY EXISTS_TAC [`f1:real^N->bool`; `f2:real^N->bool`] THEN + ASM_REWRITE_TAC[] THEN ASM SET_TAC[]; + ALL_TAC] THEN + FIRST_X_ASSUM(MP_TAC o MATCH_MP (SET_RULE + `~(s = {a,b}) + ==> a IN s /\ b IN s ==> ?c. ~(c = a) /\ ~(c = b) /\ c IN s`)) THEN + ASM_REWRITE_TAC[IN_ELIM_THM; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `f3:real^N->bool` THEN STRIP_TAC THEN DISCH_TAC THEN + UNDISCH_TAC `aff_dim(r:real^N->bool) = aff_dim(p:real^N->bool) - &2` THEN + MATCH_MP_TAC(TAUT `~p ==> p ==> q`) THEN + MATCH_MP_TAC(INT_ARITH `~(p - &2:int <= x:int) ==> ~(x = p - &2)`) THEN + DISCH_TAC THEN SUBGOAL_THEN + `~(f1:real^N->bool = {}) /\ + ~(f2:real^N->bool = {}) /\ + ~(f3:real^N->bool = {})` + STRIP_ASSUME_TAC THENL + [REPEAT CONJ_TAC THEN DISCH_THEN SUBST_ALL_TAC THEN + RULE_ASSUM_TAC(REWRITE_RULE[AFF_DIM_EMPTY]) THEN ASM_INT_ARITH_TAC; + ALL_TAC] THEN + MP_TAC(ISPEC `p:real^N->bool` POLYHEDRON_INTER_AFFINE_PARALLEL_MINIMAL) THEN + REWRITE_TAC[RIGHT_IMP_EXISTS_THM; SKOLEM_THM] THEN + REWRITE_TAC[RIGHT_AND_EXISTS_THM; LEFT_AND_EXISTS_THM] THEN + ASM_REWRITE_TAC[NOT_EXISTS_THM] THEN MAP_EVERY X_GEN_TAC + [`f:(real^N->bool)->bool`; `a:(real^N->bool)->real^N`; + `b:(real^N->bool)->real`] THEN + ONCE_REWRITE_TAC[EQ_SYM_EQ] THEN + REWRITE_TAC[VECTOR_ARITH `vec 0:real^N = v <=> v = vec 0`] THEN + STRIP_TAC THEN MP_TAC(ISPECL + [`p:real^N->bool`; `f:(real^N->bool)->bool`; `a:(real^N->bool)->real^N`; + `b:(real^N->bool)->real`] FACET_OF_POLYHEDRON_EXPLICIT) THEN + ASM_SIMP_TAC[] THEN DISCH_THEN(fun th -> + MP_TAC(SPEC `f1:real^N->bool` th) THEN + MP_TAC(SPEC `f2:real^N->bool` th) THEN + MP_TAC(SPEC `f3:real^N->bool` th)) THEN + ASM_REWRITE_TAC[facet_of] THEN + DISCH_THEN(X_CHOOSE_THEN `h3:real^N->bool` (STRIP_ASSUME_TAC o GSYM)) THEN + DISCH_THEN(X_CHOOSE_THEN `h2:real^N->bool` (STRIP_ASSUME_TAC o GSYM)) THEN + DISCH_THEN(X_CHOOSE_THEN `h1:real^N->bool` (STRIP_ASSUME_TAC o GSYM)) THEN + SUBGOAL_THEN `~((a:(real^N->bool)->real^N) h1 = a h2) /\ + ~(a h2 = a h3) /\ ~(a h1 = a h3)` + STRIP_ASSUME_TAC THENL + [REPEAT CONJ_TAC THENL + [DISJ_CASES_TAC(REAL_ARITH + `b(h1:real^N->bool) <= b h2 \/ b h2 <= b h1`) + THENL + [FIRST_X_ASSUM(MP_TAC o SPEC `f DELETE (h2:real^N->bool)`); + FIRST_X_ASSUM(MP_TAC o SPEC `f DELETE (h1:real^N->bool)`)] THEN + (ANTS_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + MATCH_MP_TAC(SET_RULE `(p ==> s = t) ==> s PSUBSET t ==> ~p`) THEN + DISCH_TAC THEN + FIRST_X_ASSUM(fun th -> GEN_REWRITE_TAC LAND_CONV [SYM th]) THEN + AP_TERM_TAC) + THENL + [SUBGOAL_THEN `f DELETE h2 = h1 INSERT (f DIFF {h1,h2}) /\ + f = (h2:real^N->bool) INSERT h1 INSERT (f DIFF {h1,h2})` + (fun th -> ONCE_REWRITE_TAC[th]) THENL [ASM SET_TAC[]; ALL_TAC]; + SUBGOAL_THEN `f DELETE h1 = h2 INSERT (f DIFF {h1,h2}) /\ + f = (h1:real^N->bool) INSERT h2 INSERT (f DIFF {h1,h2})` + (fun th -> ONCE_REWRITE_TAC[th]) THENL [ASM SET_TAC[]; ALL_TAC]] THEN + REWRITE_TAC[INTERS_INSERT] THEN MATCH_MP_TAC(SET_RULE + `b SUBSET a ==> a INTER b INTER s = b INTER s`) THEN + FIRST_X_ASSUM(fun th -> + MP_TAC(SPEC `h1:real^N->bool` th) THEN + MP_TAC(SPEC `h2:real^N->bool` th)) THEN + ASM_REWRITE_TAC[IMP_IMP] THEN + DISCH_THEN(fun th -> ONCE_REWRITE_TAC[GSYM th]) THEN + REWRITE_TAC[SUBSET; IN_ELIM_THM] THEN ASM_REAL_ARITH_TAC; + DISJ_CASES_TAC(REAL_ARITH + `b(h2:real^N->bool) <= b h3 \/ b h3 <= b h2`) + THENL + [FIRST_X_ASSUM(MP_TAC o SPEC `f DELETE (h3:real^N->bool)`); + FIRST_X_ASSUM(MP_TAC o SPEC `f DELETE (h2:real^N->bool)`)] THEN + (ANTS_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + MATCH_MP_TAC(SET_RULE `(p ==> s = t) ==> s PSUBSET t ==> ~p`) THEN + DISCH_TAC THEN + FIRST_X_ASSUM(fun th -> GEN_REWRITE_TAC LAND_CONV [SYM th]) THEN + AP_TERM_TAC) + THENL + [SUBGOAL_THEN `f DELETE h3 = h2 INSERT (f DIFF {h2,h3}) /\ + f = (h3:real^N->bool) INSERT h2 INSERT (f DIFF {h2,h3})` + (fun th -> ONCE_REWRITE_TAC[th]) THENL [ASM SET_TAC[]; ALL_TAC]; + SUBGOAL_THEN `f DELETE h2 = h3 INSERT (f DIFF {h2,h3}) /\ + f = (h2:real^N->bool) INSERT h3 INSERT (f DIFF {h2,h3})` + (fun th -> ONCE_REWRITE_TAC[th]) THENL [ASM SET_TAC[]; ALL_TAC]] THEN + REWRITE_TAC[INTERS_INSERT] THEN MATCH_MP_TAC(SET_RULE + `b SUBSET a ==> a INTER b INTER s = b INTER s`) THEN + FIRST_X_ASSUM(fun th -> + MP_TAC(SPEC `h2:real^N->bool` th) THEN + MP_TAC(SPEC `h3:real^N->bool` th)) THEN + ASM_REWRITE_TAC[IMP_IMP] THEN + DISCH_THEN(fun th -> ONCE_REWRITE_TAC[GSYM th]) THEN + REWRITE_TAC[SUBSET; IN_ELIM_THM] THEN ASM_REAL_ARITH_TAC; + DISJ_CASES_TAC(REAL_ARITH + `b(h1:real^N->bool) <= b h3 \/ b h3 <= b h1`) + THENL + [FIRST_X_ASSUM(MP_TAC o SPEC `f DELETE (h3:real^N->bool)`); + FIRST_X_ASSUM(MP_TAC o SPEC `f DELETE (h1:real^N->bool)`)] THEN + (ANTS_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + MATCH_MP_TAC(SET_RULE `(p ==> s = t) ==> s PSUBSET t ==> ~p`) THEN + DISCH_TAC THEN + FIRST_X_ASSUM(fun th -> GEN_REWRITE_TAC LAND_CONV [SYM th]) THEN + AP_TERM_TAC) + THENL + [SUBGOAL_THEN `f DELETE h3 = h1 INSERT (f DIFF {h1,h3}) /\ + f = (h3:real^N->bool) INSERT h1 INSERT (f DIFF {h1,h3})` + (fun th -> ONCE_REWRITE_TAC[th]) THENL [ASM SET_TAC[]; ALL_TAC]; + SUBGOAL_THEN `f DELETE h1 = h3 INSERT (f DIFF {h1,h3}) /\ + f = (h1:real^N->bool) INSERT h3 INSERT (f DIFF {h1,h3})` + (fun th -> ONCE_REWRITE_TAC[th]) THENL [ASM SET_TAC[]; ALL_TAC]] THEN + REWRITE_TAC[INTERS_INSERT] THEN MATCH_MP_TAC(SET_RULE + `b SUBSET a ==> a INTER b INTER s = b INTER s`) THEN + FIRST_X_ASSUM(fun th -> + MP_TAC(SPEC `h1:real^N->bool` th) THEN + MP_TAC(SPEC `h3:real^N->bool` th)) THEN + ASM_REWRITE_TAC[IMP_IMP] THEN + DISCH_THEN(fun th -> ONCE_REWRITE_TAC[GSYM th]) THEN + REWRITE_TAC[SUBSET; IN_ELIM_THM] THEN ASM_REAL_ARITH_TAC]; + ALL_TAC] THEN + SUBGOAL_THEN + `~({x | a h1 dot x <= b h1} INTER {x | a h2 dot x <= b h2} + SUBSET {x | a h3 dot x <= b h3}) /\ + ~({x | a h1 dot x <= b h1} INTER {x | a h3 dot x <= b h3} + SUBSET {x | a h2 dot x <= b h2}) /\ + ~({x | a h2 dot x <= b h2} INTER {x | a h3 dot x <= b h3} + SUBSET {x:real^N | a(h1:real^N->bool) dot x <= b h1})` + MP_TAC THENL + [ASM_SIMP_TAC[] THEN REPEAT STRIP_TAC THENL + [FIRST_X_ASSUM(MP_TAC o SPEC `f DELETE (h3:real^N->bool)`); + FIRST_X_ASSUM(MP_TAC o SPEC `f DELETE (h2:real^N->bool)`); + FIRST_X_ASSUM(MP_TAC o SPEC `f DELETE (h1:real^N->bool)`)] THEN + (ANTS_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + FIRST_X_ASSUM(fun th -> GEN_REWRITE_TAC + (LAND_CONV o LAND_CONV) [SYM th]) THEN + MATCH_MP_TAC(SET_RULE `s = t ==> s PSUBSET t ==> F`) THEN + AP_TERM_TAC) + THENL + [SUBGOAL_THEN + `f DELETE (h3:real^N->bool) = h1 INSERT h2 INSERT (f DELETE h3) /\ + f = h1 INSERT h2 INSERT h3 INSERT (f DELETE h3)` + (fun th -> ONCE_REWRITE_TAC[th]) THENL [ASM SET_TAC[]; ALL_TAC]; + SUBGOAL_THEN + `f DELETE (h2:real^N->bool) = h1 INSERT h3 INSERT (f DELETE h2) /\ + f = h2 INSERT h1 INSERT h3 INSERT (f DELETE h2)` + (fun th -> ONCE_REWRITE_TAC[th]) THENL [ASM SET_TAC[]; ALL_TAC]; + SUBGOAL_THEN + `f DELETE (h1:real^N->bool) = h2 INSERT h3 INSERT (f DELETE h1) /\ + f = h1 INSERT h2 INSERT h3 INSERT (f DELETE h1)` + (fun th -> ONCE_REWRITE_TAC[th]) THENL [ASM SET_TAC[]; ALL_TAC]] THEN + REWRITE_TAC[INTERS_INSERT] THEN REWRITE_TAC[GSYM INTER_ASSOC] THEN + AP_THM_TAC THEN AP_TERM_TAC THEN ASM SET_TAC[]; + ALL_TAC] THEN + SUBGOAL_THEN + `?w. (a:(real^N->bool)->real^N) h1 dot w < b h1 /\ + a h2 dot w < b h2 /\ a h3 dot w < b h3` + (CHOOSE_THEN MP_TAC) + THENL + [SUBGOAL_THEN `~(relative_interior p :real^N->bool = {})` MP_TAC THENL + [ASM_SIMP_TAC[RELATIVE_INTERIOR_EQ_EMPTY; POLYHEDRON_IMP_CONVEX] THEN + ASM SET_TAC[]; + ALL_TAC] THEN + MP_TAC(ISPECL + [`p:real^N->bool`; `f:(real^N->bool)->bool`; `a:(real^N->bool)->real^N`; + `b:(real^N->bool)->real`] RELATIVE_INTERIOR_POLYHEDRON_EXPLICIT) THEN + ASM_SIMP_TAC[] THEN DISCH_THEN(K ALL_TAC) THEN + REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; IN_ELIM_THM] THEN + MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC THEN + DISCH_THEN(MP_TAC o CONJUNCT2) THEN ASM_SIMP_TAC[]; + ALL_TAC] THEN + SUBGOAL_THEN + `!x. x IN r ==> (a h1) dot (x:real^N) = b h1 /\ + (a h2) dot x = b h2 /\ + (a (h3:real^N->bool)) dot x = b h3` + MP_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + SUBGOAL_THEN `?z:real^N. z IN r` CHOOSE_TAC THENL + [ASM SET_TAC[]; ALL_TAC] THEN + MAP_EVERY UNDISCH_TAC + [`~((a:(real^N->bool)->real^N) h1 = a h2)`; + `~((a:(real^N->bool)->real^N) h1 = a h3)`; + `~((a:(real^N->bool)->real^N) h2 = a h3)`; + `aff_dim(p:real^N->bool) - &2 <= aff_dim(r:real^N->bool)`] THEN + MAP_EVERY (fun t -> + FIRST_X_ASSUM(fun th -> MP_TAC(SPEC t th) THEN ASM_REWRITE_TAC[] THEN + ASSUME_TAC th) THEN + DISCH_THEN(MP_TAC o SPEC `z:real^N` o CONJUNCT2 o CONJUNCT2)) + [`h1:real^N->bool`; `h2:real^N->bool`; `h3:real^N->bool`] THEN + SUBGOAL_THEN `(z:real^N) IN (affine hull p)` ASSUME_TAC THENL + [MATCH_MP_TAC HULL_INC THEN ASM SET_TAC[]; + ASM_REWRITE_TAC[]] THEN + UNDISCH_TAC `(z:real^N) IN (affine hull p)` THEN + SUBGOAL_THEN `(a h1) dot (z:real^N) = b h1 /\ + (a h2) dot z = b h2 /\ + (a (h3:real^N->bool)) dot z = b h3` + (REPEAT_TCL CONJUNCTS_THEN (SUBST1_TAC o SYM)) + THENL [ASM SET_TAC[]; ALL_TAC] THEN + SUBGOAL_THEN `(r:real^N->bool) SUBSET affine hull p` MP_TAC THENL + [ASM_MESON_TAC[FACE_OF_IMP_SUBSET; HULL_SUBSET; SUBSET_TRANS]; ALL_TAC] THEN + SUBGOAL_THEN + `~((a:(real^N->bool)->real^N) h1 = vec 0) /\ + ~((a:(real^N->bool)->real^N) h2 = vec 0) /\ + ~((a:(real^N->bool)->real^N) h3 = vec 0)` + MP_TAC THENL [ASM_SIMP_TAC[]; ALL_TAC] THEN + UNDISCH_TAC `(z:real^N) IN r` THEN POP_ASSUM_LIST(K ALL_TAC) THEN + MAP_EVERY SPEC_TAC + [`(a:(real^N->bool)->real^N) h1`,`a1:real^N`; + `(a:(real^N->bool)->real^N) h2`,`a2:real^N`; + `(a:(real^N->bool)->real^N) h3`,`a3:real^N`] THEN + REPEAT GEN_TAC THEN + GEN_GEOM_ORIGIN_TAC `z:real^N` ["a1"; "a2"; "a3"] THEN + REWRITE_TAC[VECTOR_ADD_RID; VECTOR_ADD_LID] THEN + REWRITE_TAC[DOT_RADD; IMAGE_CLAUSES; + REAL_ARITH `a + b:real <= a <=> b <= &0`; + REAL_ARITH `a + b:real < a <=> b < &0`; + REAL_ARITH `a + b:real = a <=> b = &0`] THEN + + REPEAT STRIP_TAC THEN + SUBGOAL_THEN `aff_dim(p:real^N->bool) = &(dim p)` SUBST_ALL_TAC THENL + [ASM_SIMP_TAC[AFF_DIM_DIM_0; HULL_INC]; ALL_TAC] THEN + SUBGOAL_THEN `aff_dim(r:real^N->bool) = &(dim r)` SUBST_ALL_TAC THENL + [ASM_SIMP_TAC[AFF_DIM_DIM_0; HULL_INC]; ALL_TAC] THEN + RULE_ASSUM_TAC(REWRITE_RULE[INT_OF_NUM_ADD; INT_OF_NUM_LE; + INT_ARITH `p - &2:int <= q <=> p <= q + &2`]) THEN + MP_TAC(ISPECL + [`{a1:real^N,a2,a3}`; `r:real^N->bool`] DIM_ORTHOGONAL_SUM) THEN + REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN + ASM_SIMP_TAC[FORALL_IN_INSERT; NOT_IN_EMPTY] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (ARITH_RULE + `p <= r + 2 ==> u <= p /\ 3 <= t ==> ~(u = t + r)`)) THEN + SUBGOAL_THEN `affine hull p :real^N->bool = span p` SUBST_ALL_TAC THENL + [ASM_MESON_TAC[AFFINE_HULL_EQ_SPAN]; ALL_TAC] THEN + CONJ_TAC THENL + [GEN_REWRITE_TAC RAND_CONV [GSYM DIM_SPAN] THEN + MATCH_MP_TAC DIM_SUBSET THEN ASM SET_TAC[]; + ALL_TAC] THEN + MP_TAC(ISPEC `{a1:real^N,a2,a3}` DEPENDENT_BIGGERSET_GENERAL) THEN + SIMP_TAC[CARD_CLAUSES; FINITE_INSERT; FINITE_EMPTY; ARITH] THEN + ASM_REWRITE_TAC[IN_INSERT; NOT_IN_EMPTY; ARITH] THEN + GEN_REWRITE_TAC LAND_CONV [GSYM CONTRAPOS_THM] THEN + REWRITE_TAC[ARITH_RULE `~(3 > x) <=> 3 <= x`] THEN + DISCH_THEN MATCH_MP_TAC THEN + REWRITE_TAC[dependent; EXISTS_IN_INSERT; NOT_IN_EMPTY] THEN + ASM_REWRITE_TAC[DELETE_INSERT; EMPTY_DELETE] THEN + REWRITE_TAC[SPAN_2; IN_ELIM_THM; IN_UNIV] THEN + POP_ASSUM_LIST(MP_TAC o end_itlist CONJ o rev) THEN + W(fun (asl,w) -> let fv = frees w + and av = [`a1:real^N`; `a2:real^N`; `a3:real^N`] in + MAP_EVERY (fun t -> SPEC_TAC(t,t)) (subtract fv av @ av)) THEN + REWRITE_TAC[LEFT_FORALL_IMP_THM] THEN + MATCH_MP_TAC(MESON[] + `(!a1 a2 a3. P a1 a2 a3 ==> P a2 a1 a3 /\ P a3 a1 a2) /\ + (!a1 a2 a3. Q a1 a2 a3 ==> ~(P a1 a2 a3)) + ==> !a3 a2 a1. P a1 a2 a3 + ==> ~(Q a1 a2 a3 \/ Q a2 a1 a3 \/ Q a3 a1 a2)`) THEN + CONJ_TAC THENL + [REPEAT GEN_TAC THEN MATCH_MP_TAC(TAUT + `(p ==> q) /\ (p ==> r) ==> p ==> q /\ r`) THEN + CONJ_TAC THEN REPEAT(MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC) THEN + REWRITE_TAC[CONJ_ACI] THEN DISCH_TAC THEN ASM_REWRITE_TAC[] THEN + ASM SET_TAC[]; + ALL_TAC] THEN + REPEAT GEN_TAC THEN DISCH_THEN + (X_CHOOSE_THEN `u:real` (X_CHOOSE_TAC `v:real`)) THEN + REWRITE_TAC[NOT_EXISTS_THM] THEN REPEAT GEN_TAC THEN + ASM_CASES_TAC `u = &0` THENL + [ASM_REWRITE_TAC[VECTOR_ADD_LID; VECTOR_MUL_LZERO] THEN + REPEAT_TCL DISJ_CASES_THEN ASSUME_TAC (REAL_ARITH + `v = &0 \/ &0 < v \/ &0 < --v`) + THENL + [ASM_REWRITE_TAC[VECTOR_MUL_LZERO]; + REWRITE_TAC[DOT_LMUL; REAL_ARITH `a * b <= &0 <=> &0 <= a * --b`] THEN + ASM_SIMP_TAC[REAL_LE_MUL_EQ] THEN + REWRITE_TAC[SUBSET; IN_ELIM_THM; IN_INTER] THEN REAL_ARITH_TAC; + REWRITE_TAC[DOT_LMUL; REAL_ARITH `a * b < &0 <=> &0 < --a * b`] THEN + ASM_SIMP_TAC[REAL_LT_MUL_EQ] THEN REAL_ARITH_TAC]; + ALL_TAC] THEN + ASM_CASES_TAC `v = &0` THENL + [ASM_REWRITE_TAC[VECTOR_ADD_RID; VECTOR_MUL_LZERO] THEN + REPEAT_TCL DISJ_CASES_THEN ASSUME_TAC (REAL_ARITH + `u = &0 \/ &0 < u \/ &0 < --u`) + THENL + [ASM_REWRITE_TAC[VECTOR_MUL_LZERO]; + REWRITE_TAC[DOT_LMUL; REAL_ARITH `a * b <= &0 <=> &0 <= a * --b`] THEN + ASM_SIMP_TAC[REAL_LE_MUL_EQ] THEN + REWRITE_TAC[SUBSET; IN_ELIM_THM; IN_INTER] THEN REAL_ARITH_TAC; + REWRITE_TAC[DOT_LMUL; REAL_ARITH `a * b < &0 <=> &0 < --a * b`] THEN + ASM_SIMP_TAC[REAL_LT_MUL_EQ] THEN REAL_ARITH_TAC]; + ALL_TAC] THEN + STRIP_TAC THEN + SUBGOAL_THEN + `&0 < u /\ &0 < v \/ &0 < u /\ &0 < --v \/ + &0 < --u /\ &0 < v \/ &0 < --u /\ &0 < --v` + STRIP_ASSUME_TAC THENL + [ASM_REAL_ARITH_TAC; + UNDISCH_TAC + `~({x | a2 dot x <= &0} INTER {x | a3 dot x <= &0} SUBSET + {x:real^N | a1 dot x <= &0})` THEN + ASM_REWRITE_TAC[SUBSET; IN_INTER; IN_ELIM_THM] THEN + REWRITE_TAC[DOT_LADD; DOT_LMUL] THEN + REWRITE_TAC[REAL_ARITH `x <= &0 <=> &0 <= --x`] THEN + REWRITE_TAC[REAL_NEG_ADD; GSYM REAL_MUL_RNEG] THEN + ASM_SIMP_TAC[REAL_LE_MUL; REAL_LE_ADD; REAL_LT_IMP_LE]; + UNDISCH_TAC + `~({x | a1 dot x <= &0} INTER {x | a3 dot x <= &0} SUBSET + {x:real^N | a2 dot x <= &0})` THEN + ASM_REWRITE_TAC[SUBSET; IN_INTER; IN_ELIM_THM] THEN + GEN_TAC THEN REWRITE_TAC[DOT_LADD; DOT_LMUL] THEN + MATCH_MP_TAC(REAL_ARITH + `(&0 < u * a2 <=> &0 < a2) /\ (&0 < --v * a3 <=> &0 < a3) + ==> u * a2 + v * a3 <= &0 /\ a3 <= &0 ==> a2 <= &0`) THEN + ASM_SIMP_TAC[REAL_LT_MUL_EQ]; + UNDISCH_TAC + `~({x | a1 dot x <= &0} INTER {x | a2 dot x <= &0} SUBSET + {x:real^N | a3 dot x <= &0})` THEN + ASM_REWRITE_TAC[SUBSET; IN_INTER; IN_ELIM_THM] THEN + GEN_TAC THEN REWRITE_TAC[DOT_LADD; DOT_LMUL] THEN + MATCH_MP_TAC(REAL_ARITH + `(&0 < --u * a2 <=> &0 < a2) /\ (&0 < v * a3 <=> &0 < a3) + ==> u * a2 + v * a3 <= &0 /\ a2 <= &0 ==> a3 <= &0`) THEN + ASM_SIMP_TAC[REAL_LT_MUL_EQ]; + UNDISCH_TAC `(a1:real^N) dot w < &0` THEN + ASM_REWRITE_TAC[DOT_LADD; DOT_LMUL] THEN + MATCH_MP_TAC(REAL_ARITH + `&0 < --u * --a /\ &0 < --v * --b ==> ~(u * a + v * b < &0)`) THEN + CONJ_TAC THEN MATCH_MP_TAC REAL_LT_MUL THEN ASM_REAL_ARITH_TAC]);; + +(* ------------------------------------------------------------------------- *) +(* Lower bounds on then number of 0 and n-1 dimensional faces. *) +(* ------------------------------------------------------------------------- *) + +let POLYTOPE_VERTEX_LOWER_BOUND = prove + (`!p:real^N->bool. + polytope p ==> aff_dim p + &1 <= &(CARD {v | v extreme_point_of p})`, + REPEAT STRIP_TAC THEN + MATCH_MP_TAC INT_LE_TRANS THEN + EXISTS_TAC `aff_dim(convex hull {v:real^N | v extreme_point_of p}) + &1` THEN + CONJ_TAC THENL + [ASM_SIMP_TAC[GSYM KREIN_MILMAN_MINKOWSKI; POLYTOPE_IMP_CONVEX; + POLYTOPE_IMP_COMPACT; INT_LE_REFL]; + REWRITE_TAC[AFF_DIM_CONVEX_HULL; GSYM INT_LE_SUB_LADD] THEN + MATCH_MP_TAC AFF_DIM_LE_CARD THEN + MATCH_MP_TAC FINITE_POLYHEDRON_EXTREME_POINTS THEN + ASM_SIMP_TAC[POLYTOPE_IMP_POLYHEDRON]]);; + +let POLYTOPE_FACET_LOWER_BOUND = prove + (`!p:real^N->bool. + polytope p /\ ~(aff_dim p = &0) + ==> aff_dim p + &1 <= &(CARD {f | f facet_of p})`, + GEN_TAC THEN ASM_CASES_TAC `p:real^N->bool = {}` THEN + ASM_SIMP_TAC[AFF_DIM_EMPTY; FACET_OF_EMPTY; EMPTY_GSPEC; CARD_CLAUSES] THEN + CONV_TAC INT_REDUCE_CONV THEN STRIP_TAC THEN + SUBGOAL_THEN + `?n. {f:real^N->bool | f facet_of p} HAS_SIZE n /\ aff_dim p + &1 <= &n` + (fun th -> MESON_TAC[th; HAS_SIZE]) THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN + DISCH_THEN(X_CHOOSE_THEN `z:real^N` MP_TAC) THEN + POP_ASSUM_LIST(MP_TAC o end_itlist CONJ o rev) THEN + GEOM_ORIGIN_TAC `z:real^N` THEN REPEAT GEN_TAC THEN REPEAT STRIP_TAC THEN + EXISTS_TAC `CARD {f:real^N->bool | f facet_of p}` THEN + ASM_SIMP_TAC[FINITE_POLYTOPE_FACETS; HAS_SIZE] THEN + UNDISCH_TAC `~(aff_dim(p:real^N->bool) = &0)` THEN + ASM_SIMP_TAC[AFF_DIM_DIM_0; HULL_INC; INT_OF_NUM_ADD; INT_OF_NUM_LE] THEN + REWRITE_TAC[INT_OF_NUM_EQ] THEN DISCH_TAC THEN + MP_TAC(ISPEC `p:real^N->bool` POLYHEDRON_INTER_AFFINE_PARALLEL_MINIMAL) THEN + ASM_SIMP_TAC[POLYTOPE_IMP_POLYHEDRON] THEN + REWRITE_TAC[RIGHT_IMP_EXISTS_THM; SKOLEM_THM] THEN + REWRITE_TAC[RIGHT_AND_EXISTS_THM; LEFT_AND_EXISTS_THM] THEN + ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN MAP_EVERY X_GEN_TAC + [`H:(real^N->bool)->bool`; `a:(real^N->bool)->real^N`; + `b:(real^N->bool)->real`] THEN + ONCE_REWRITE_TAC[EQ_SYM_EQ] THEN + REWRITE_TAC[VECTOR_ARITH `vec 0:real^N = v <=> v = vec 0`] THEN + ASM_SIMP_TAC[AFFINE_HULL_EQ_SPAN; HULL_INC] THEN + STRIP_TAC THEN MP_TAC(ISPECL + [`p:real^N->bool`; `H:(real^N->bool)->bool`; `a:(real^N->bool)->real^N`; + `b:(real^N->bool)->real`] FACET_OF_POLYHEDRON_EXPLICIT) THEN + ASM_SIMP_TAC[AFFINE_HULL_EQ_SPAN; HULL_INC] THEN DISCH_THEN(K ALL_TAC) THEN + SUBGOAL_THEN `!h:real^N->bool. h IN H ==> &0 <= b h` ASSUME_TAC THENL + [UNDISCH_TAC `(vec 0:real^N) IN p` THEN EXPAND_TAC "p" THEN + REWRITE_TAC[IN_INTER; IN_INTERS] THEN DISCH_THEN(MP_TAC o CONJUNCT2) THEN + MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `h:real^N->bool` THEN + ASM_CASES_TAC `(h:real^N->bool) IN H` THEN ASM_REWRITE_TAC[] THEN + FIRST_X_ASSUM(MP_TAC o SPEC `h:real^N->bool`) THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(fun t -> GEN_REWRITE_TAC (LAND_CONV o RAND_CONV) [GSYM t]) THEN + REWRITE_TAC[IN_ELIM_THM; DOT_RZERO]; + ALL_TAC] THEN + MATCH_MP_TAC LE_TRANS THEN + EXISTS_TAC `(CARD(H:(real^N->bool)->bool))` THEN CONJ_TAC THENL + [MATCH_MP_TAC(ARITH_RULE `~(h <= a) ==> a + 1 <= h`) THEN DISCH_TAC THEN + ASM_CASES_TAC `H:(real^N->bool)->bool = {}` THENL + [UNDISCH_THEN `H:(real^N->bool)->bool = {}` SUBST_ALL_TAC THEN + RULE_ASSUM_TAC(REWRITE_RULE[INTERS_0; INTER_UNIV]) THEN + UNDISCH_TAC `~(dim(p:real^N->bool) = 0)` THEN + REWRITE_TAC[DIM_EQ_0] THEN EXPAND_TAC "p" THEN + REWRITE_TAC[ASSUME `H:(real^N->bool)->bool = {}`; INTERS_0] THEN + REWRITE_TAC[INTER_UNIV] THEN + ASM_CASES_TAC `?n:real^N. n IN span p /\ ~(n = vec 0)` THENL + [ALL_TAC; ASM SET_TAC[]] THEN + FIRST_X_ASSUM(CHOOSE_THEN STRIP_ASSUME_TAC) THEN + FIRST_ASSUM(MP_TAC o MATCH_MP POLYTOPE_IMP_BOUNDED) THEN + REWRITE_TAC[BOUNDED_POS] THEN DISCH_THEN(X_CHOOSE_THEN `B:real` + (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + DISCH_THEN(MP_TAC o SPEC `(B + &1) / norm n % n:real^N`) THEN + ANTS_TAC THENL [ASM_MESON_TAC[SPAN_MUL]; ALL_TAC] THEN + REWRITE_TAC[NORM_MUL; REAL_ABS_DIV; REAL_ABS_NORM] THEN + ASM_SIMP_TAC[REAL_DIV_RMUL; NORM_EQ_0] THEN REAL_ARITH_TAC; + ALL_TAC] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN + DISCH_THEN(X_CHOOSE_TAC `h:real^N->bool`) THEN + SUBGOAL_THEN + `span(IMAGE (a:(real^N->bool)->real^N) (H DELETE h)) + PSUBSET span(p)` + MP_TAC THENL + [REWRITE_TAC[PSUBSET] THEN CONJ_TAC THENL + [MATCH_MP_TAC SPAN_SUBSET_SUBSPACE THEN + REWRITE_TAC[SUBSPACE_SPAN; SUBSET; FORALL_IN_IMAGE; IN_DELETE] THEN + ASM_MESON_TAC[SPAN_ADD; SPAN_SUPERSET; VECTOR_ADD_LID]; + DISCH_THEN(MP_TAC o AP_TERM `dim:(real^N->bool)->num`) THEN + REWRITE_TAC[DIM_SPAN] THEN FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP + (ARITH_RULE `h <= p ==> h':num < h ==> ~(h' = p)`)) THEN + MATCH_MP_TAC LET_TRANS THEN + EXISTS_TAC `CARD(IMAGE (a:(real^N->bool)->real^N) (H DELETE h))` THEN + ASM_SIMP_TAC[DIM_LE_CARD; FINITE_DELETE; FINITE_IMAGE] THEN + MATCH_MP_TAC LET_TRANS THEN + EXISTS_TAC `CARD(H DELETE (h:real^N->bool))` THEN + ASM_SIMP_TAC[CARD_IMAGE_LE; FINITE_DELETE] THEN + ASM_SIMP_TAC[CARD_DELETE; ARITH_RULE `n - 1 < n <=> ~(n = 0)`] THEN + ASM_SIMP_TAC[CARD_EQ_0] THEN ASM SET_TAC[]]; + DISCH_THEN(MP_TAC o MATCH_MP ORTHOGONAL_TO_SUBSPACE_EXISTS_GEN)] THEN + REWRITE_TAC[NOT_EXISTS_THM] THEN X_GEN_TAC `n:real^N` THEN STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o MATCH_MP POLYTOPE_IMP_BOUNDED) THEN + REWRITE_TAC[BOUNDED_POS] THEN + DISCH_THEN(X_CHOOSE_THEN `B:real` (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + DISJ_CASES_TAC(REAL_ARITH + `&0 <= (a:(real^N->bool)->real^N) h dot n \/ + &0 <= --((a:(real^N->bool)->real^N) h dot n)`) + THENL + [DISCH_THEN(MP_TAC o SPEC `--(B + &1) / norm(n) % n:real^N`); + DISCH_THEN(MP_TAC o SPEC `(B + &1) / norm(n) % n:real^N`)] THEN + (ASM_SIMP_TAC[NORM_MUL; REAL_ABS_DIV; REAL_ABS_NORM; + REAL_DIV_RMUL; NORM_EQ_0; REAL_ABS_NEG; + REAL_ARITH `~(abs(B + &1) <= B)`] THEN + EXPAND_TAC "p" THEN REWRITE_TAC[IN_INTER; IN_INTERS] THEN + ASM_SIMP_TAC[SPAN_MUL] THEN X_GEN_TAC `k:real^N->bool` THEN + DISCH_TAC THEN + SUBGOAL_THEN `k = {x:real^N | a k dot x <= b k}` SUBST1_TAC THENL + [ASM_SIMP_TAC[]; ALL_TAC] THEN + ASM_CASES_TAC `k:real^N->bool = h` THEN + ASM_REWRITE_TAC[IN_ELIM_THM; DOT_RMUL] THENL + [ALL_TAC; + MATCH_MP_TAC(REAL_ARITH `x = &0 /\ &0 <= y ==> x <= y`) THEN + ASM_SIMP_TAC[REAL_ENTIRE] THEN DISJ2_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `(a:(real^N->bool)->real^N) k`) THEN + REWRITE_TAC[orthogonal; DOT_SYM] THEN DISCH_THEN MATCH_MP_TAC THEN + MATCH_MP_TAC SPAN_SUPERSET THEN ASM SET_TAC[]]) THENL + [MATCH_MP_TAC(REAL_ARITH `&0 <= --x * y /\ &0 <= z ==> x * y <= z`); + MATCH_MP_TAC(REAL_ARITH `&0 <= x * --y /\ &0 <= z ==> x * y <= z`)] THEN + ASM_SIMP_TAC[] THEN MATCH_MP_TAC REAL_LE_MUL THEN + REWRITE_TAC[REAL_ARITH `--a / b:real = --(a / b)`; REAL_NEG_NEG] THEN + ASM_SIMP_TAC[REAL_LE_RDIV_EQ; NORM_POS_LT] THEN ASM_REAL_ARITH_TAC; + REWRITE_TAC[SET_RULE `{f | ?h. h IN s /\ f = g h} = IMAGE g s`] THEN + MATCH_MP_TAC(ARITH_RULE `m:num = n ==> n <= m`) THEN + MATCH_MP_TAC CARD_IMAGE_INJ THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC FACETS_OF_POLYHEDRON_EXPLICIT_DISTINCT THEN + ASM_SIMP_TAC[AFFINE_HULL_EQ_SPAN; HULL_INC]]);; + +(* ------------------------------------------------------------------------- *) +(* The notion of n-simplex where n is an integer >= -1. *) +(* ------------------------------------------------------------------------- *) + +parse_as_infix("simplex",(12,"right"));; + +let simplex = new_definition + `n simplex s <=> ?c. ~(affine_dependent c) /\ + &(CARD c):int = n + &1 /\ + s = convex hull c`;; + +let SIMPLEX = prove + (`n simplex s <=> ?c. FINITE c /\ + ~(affine_dependent c) /\ + &(CARD c):int = n + &1 /\ + s = convex hull c`, + REWRITE_TAC[simplex] THEN MESON_TAC[AFFINE_INDEPENDENT_IMP_FINITE]);; + +let CONVEX_SIMPLEX = prove + (`!n s. n simplex s ==> convex s`, + REWRITE_TAC[simplex] THEN MESON_TAC[CONVEX_CONVEX_HULL]);; + +let COMPACT_SIMPLEX = prove + (`!n s. n simplex s ==> compact s`, + REWRITE_TAC[SIMPLEX] THEN + MESON_TAC[FINITE_IMP_COMPACT; COMPACT_CONVEX_HULL]);; + +let SIMPLEX_IMP_POLYTOPE = prove + (`!n s. n simplex s ==> polytope s`, + REWRITE_TAC[simplex; polytope] THEN + MESON_TAC[AFFINE_INDEPENDENT_IMP_FINITE]);; + +let SIMPLEX_DIM_GE = prove + (`!n s. n simplex s ==> -- &1 <= n`, + REWRITE_TAC[simplex] THEN INT_ARITH_TAC);; + +let SIMPLEX_EMPTY = prove + (`!n. n simplex {} <=> n = -- &1`, + GEN_TAC THEN REWRITE_TAC[SIMPLEX] THEN + GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [EQ_SYM_EQ] THEN + REWRITE_TAC[CONVEX_HULL_EQ_EMPTY; CONJ_ASSOC] THEN + ONCE_REWRITE_TAC[CONJ_SYM] THEN REWRITE_TAC[UNWIND_THM2] THEN + REWRITE_TAC[FINITE_EMPTY; CARD_CLAUSES; AFFINE_INDEPENDENT_EMPTY] THEN + INT_ARITH_TAC);; + +let SIMPLEX_MINUS_1 = prove + (`!s. (-- &1) simplex s <=> s = {}`, + GEN_TAC THEN REWRITE_TAC[SIMPLEX; INT_ADD_LINV; INT_OF_NUM_EQ] THEN + ONCE_REWRITE_TAC[TAUT `a /\ b <=> ~(a ==> ~b)`] THEN + SIMP_TAC[CARD_EQ_0] THEN REWRITE_TAC[NOT_IMP] THEN + ONCE_REWRITE_TAC[TAUT `a /\ b /\ c /\ d <=> c /\ a /\ b /\ d`] THEN + REWRITE_TAC[UNWIND_THM2; FINITE_EMPTY; AFFINE_INDEPENDENT_EMPTY] THEN + REWRITE_TAC[CONVEX_HULL_EMPTY]);; + +let AFF_DIM_SIMPLEX = prove + (`!s n. n simplex s ==> aff_dim s = n`, + REWRITE_TAC[simplex; INT_ARITH `x:int = n + &1 <=> n = x - &1`] THEN + REPEAT STRIP_TAC THEN + ASM_SIMP_TAC[AFF_DIM_CONVEX_HULL; AFF_DIM_AFFINE_INDEPENDENT]);; + +let SIMPLEX_EXTREME_POINTS = prove + (`!n s:real^N->bool. + n simplex s + ==> FINITE {v | v extreme_point_of s} /\ + ~(affine_dependent {v | v extreme_point_of s}) /\ + &(CARD {v | v extreme_point_of s}) = n + &1 /\ + s = convex hull {v | v extreme_point_of s}`, + REPEAT GEN_TAC THEN REWRITE_TAC[SIMPLEX; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `c:real^N->bool` THEN DISCH_THEN(STRIP_ASSUME_TAC o GSYM) THEN + SUBGOAL_THEN `{v:real^N | v extreme_point_of s} = c` + (fun th -> ASM_REWRITE_TAC[th]) THEN + FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN + MATCH_MP_TAC(SET_RULE `s SUBSET t /\ ~(s PSUBSET t) ==> s = t`) THEN + REWRITE_TAC[SUBSET; IN_ELIM_THM; EXTREME_POINT_OF_CONVEX_HULL] THEN + ABBREV_TAC `c' = {v:real^N | v extreme_point_of (convex hull c)}` THEN + DISCH_TAC THEN + SUBGOAL_THEN `convex hull c:real^N->bool = convex hull c'` ASSUME_TAC THENL + [EXPAND_TAC "c'" THEN MATCH_MP_TAC KREIN_MILMAN_MINKOWSKI THEN + REWRITE_TAC[CONVEX_CONVEX_HULL] THEN MATCH_MP_TAC COMPACT_CONVEX_HULL THEN + ASM_MESON_TAC[HAS_SIZE; FINITE_IMP_COMPACT]; + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [PSUBSET_MEMBER]) THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + DISCH_THEN(X_CHOOSE_THEN `a:real^N` STRIP_ASSUME_TAC) THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE RAND_CONV [affine_dependent]) THEN + REWRITE_TAC[] THEN EXISTS_TAC `a:real^N` THEN ASM_REWRITE_TAC[] THEN + SUBGOAL_THEN `(a:real^N) IN convex hull c'` MP_TAC THENL + [ASM_MESON_TAC[HULL_INC]; ALL_TAC] THEN + DISCH_THEN(MP_TAC o MATCH_MP (REWRITE_RULE[SUBSET] + CONVEX_HULL_SUBSET_AFFINE_HULL)) THEN + SUBGOAL_THEN `c' SUBSET (c DELETE (a:real^N))` MP_TAC THENL + [ASM SET_TAC[]; ASM_MESON_TAC[HULL_MONO; SUBSET]]]);; + +let SIMPLEX_FACE_OF_SIMPLEX = prove + (`!n s f:real^N->bool. + n simplex s /\ f face_of s ==> ?m. m <= n /\ m simplex f`, + REPEAT STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [SIMPLEX]) THEN + REWRITE_TAC[HAS_SIZE; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `c:real^N->bool` THEN STRIP_TAC THEN + FIRST_X_ASSUM SUBST_ALL_TAC THEN + SUBGOAL_THEN `?c':real^N->bool. c' SUBSET c /\ f = convex hull c'` + STRIP_ASSUME_TAC THENL + [ASM_SIMP_TAC[FACE_OF_CONVEX_HULL_SUBSET; FINITE_IMP_COMPACT]; ALL_TAC] THEN + EXISTS_TAC `&(CARD(c':real^N->bool)) - &1:int` THEN ASM_REWRITE_TAC[] THEN + CONJ_TAC THENL + [FIRST_X_ASSUM(MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] CARD_SUBSET)) THEN + ASM_REWRITE_TAC[GSYM INT_OF_NUM_LE] THEN INT_ARITH_TAC; + REWRITE_TAC[simplex] THEN EXISTS_TAC `c':real^N->bool` THEN + ASM_REWRITE_TAC[INT_ARITH `a - &1 + &1:int = a`] THEN + ASM_MESON_TAC[AFFINE_DEPENDENT_MONO]]);; + +let FACE_OF_SIMPLEX_SUBSET = prove + (`!n s f:real^N->bool. + n simplex s /\ f face_of s + ==> ?c. c SUBSET {x | x extreme_point_of s} /\ f = convex hull c`, + REPEAT STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o MATCH_MP SIMPLEX_EXTREME_POINTS) THEN + ABBREV_TAC `c = {x:real^N | x extreme_point_of s}` THEN + REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + DISCH_THEN SUBST_ALL_TAC THEN + RULE_ASSUM_TAC(REWRITE_RULE[HAS_SIZE]) THEN + ASM_MESON_TAC[FACE_OF_CONVEX_HULL_SUBSET; FINITE_IMP_COMPACT]);; + +let SUBSET_FACE_OF_SIMPLEX = prove + (`!s n c:real^N->bool. + n simplex s /\ c SUBSET {x | x extreme_point_of s} + ==> (convex hull c) face_of s`, + REPEAT STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o MATCH_MP SIMPLEX_EXTREME_POINTS) THEN + REWRITE_TAC[HAS_SIZE] THEN + REPEAT(DISCH_THEN(CONJUNCTS_THEN2 STRIP_ASSUME_TAC MP_TAC)) THEN + DISCH_THEN SUBST1_TAC THEN MATCH_MP_TAC FACE_OF_CONVEX_HULLS THEN + ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC(SET_RULE `!t. u SUBSET t /\ DISJOINT s t ==> DISJOINT s u`) THEN + EXISTS_TAC `affine hull ({v:real^N | v extreme_point_of s} DIFF c)` THEN + REWRITE_TAC[CONVEX_HULL_SUBSET_AFFINE_HULL] THEN + MATCH_MP_TAC DISJOINT_AFFINE_HULL THEN + EXISTS_TAC `{v:real^N | v extreme_point_of s}` THEN + ASM_REWRITE_TAC[] THEN SET_TAC[]);; + +let FACES_OF_SIMPLEX = prove + (`!n s. n simplex s + ==> {f | f face_of s} = + {convex hull c | c SUBSET {v | v extreme_point_of s}}`, + REPEAT STRIP_TAC THEN GEN_REWRITE_TAC I [EXTENSION] THEN + REWRITE_TAC[IN_ELIM_THM] THEN + ASM_MESON_TAC[FACE_OF_SIMPLEX_SUBSET; SUBSET_FACE_OF_SIMPLEX]);; + +let HAS_SIZE_FACES_OF_SIMPLEX = prove + (`!n s:real^N->bool. + n simplex s + ==> {f | f face_of s} HAS_SIZE 2 EXP (num_of_int(n + &1))`, + REPEAT GEN_TAC THEN DISCH_TAC THEN + FIRST_ASSUM(SUBST1_TAC o MATCH_MP FACES_OF_SIMPLEX) THEN + FIRST_X_ASSUM(STRIP_ASSUME_TAC o GSYM o MATCH_MP SIMPLEX_EXTREME_POINTS) THEN + ONCE_REWRITE_TAC[SIMPLE_IMAGE_GEN] THEN MATCH_MP_TAC HAS_SIZE_IMAGE_INJ THEN + REWRITE_TAC[IN_ELIM_THM] THEN CONJ_TAC THENL + [REWRITE_TAC[GSYM SUBSET_ANTISYM_EQ]; + MATCH_MP_TAC HAS_SIZE_POWERSET THEN + ASM_REWRITE_TAC[HAS_SIZE; NUM_OF_INT_OF_NUM]] THEN + SUBGOAL_THEN + `!a b. a SUBSET {v:real^N | v extreme_point_of s} /\ + b SUBSET {v | v extreme_point_of s} /\ + convex hull a SUBSET convex hull b + ==> a SUBSET b` + (fun th -> MESON_TAC[th]) THEN + REPEAT STRIP_TAC THEN REWRITE_TAC[SUBSET] THEN X_GEN_TAC `x:real^N` THEN + DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE RAND_CONV [affine_dependent]) THEN + REWRITE_TAC[NOT_EXISTS_THM] THEN DISCH_THEN(MP_TAC o SPEC `x:real^N`) THEN + ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN DISCH_TAC THEN REWRITE_TAC[] THEN + CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + MATCH_MP_TAC(SET_RULE + `!s t u. x IN s /\ s SUBSET t /\ t SUBSET u /\ u SUBSET v ==> x IN v`) THEN + MAP_EVERY EXISTS_TAC + [`convex hull a:real^N->bool`; `convex hull b:real^N->bool`; + `affine hull b:real^N->bool`] THEN + ASM_SIMP_TAC[HULL_INC; CONVEX_HULL_SUBSET_AFFINE_HULL] THEN + MATCH_MP_TAC HULL_MONO THEN ASM SET_TAC[]);; + +let FINITE_FACES_OF_SIMPLEX = prove + (`!n s. n simplex s ==> FINITE {f | f face_of s}`, + REPEAT GEN_TAC THEN + DISCH_THEN(MP_TAC o MATCH_MP HAS_SIZE_FACES_OF_SIMPLEX) THEN + SIMP_TAC[HAS_SIZE]);; + +let CARD_FACES_OF_SIMPLEX = prove + (`!n s. n simplex s ==> CARD {f | f face_of s} = 2 EXP (num_of_int(n + &1))`, + REPEAT GEN_TAC THEN + DISCH_THEN(MP_TAC o MATCH_MP HAS_SIZE_FACES_OF_SIMPLEX) THEN + SIMP_TAC[HAS_SIZE]);; + +let CHOOSE_SIMPLEX = prove + (`!n. --(&1) <= n /\ n <= &(dimindex(:N)) ==> ?s:real^N->bool. n simplex s`, + X_GEN_TAC `d:int` THEN + REWRITE_TAC[INT_ARITH `--(&1):int <= n <=> n = --(&1) \/ &0 <= n`] THEN + DISCH_THEN(CONJUNCTS_THEN2 DISJ_CASES_TAC MP_TAC) THENL + [ASM_MESON_TAC[SIMPLEX_EMPTY]; ALL_TAC] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM INT_OF_NUM_EXISTS]) THEN + DISCH_THEN(X_CHOOSE_THEN `n:num` SUBST1_TAC) THEN + REWRITE_TAC[INT_OF_NUM_LE; GSYM DIM_UNIV] THEN DISCH_TAC THEN + FIRST_ASSUM(MP_TAC o MATCH_MP CHOOSE_SUBSPACE_OF_SUBSPACE) THEN + DISCH_THEN(X_CHOOSE_THEN `s:real^N->bool` STRIP_ASSUME_TAC) THEN + MP_TAC(ISPEC `s:real^N->bool` BASIS_EXISTS) THEN + ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `c:real^N->bool` THEN STRIP_TAC THEN + EXISTS_TAC `convex hull ((vec 0:real^N) INSERT c)` THEN + REWRITE_TAC[simplex] THEN EXISTS_TAC `(vec 0:real^N) INSERT c` THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP INDEPENDENT_NONZERO) THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP INDEPENDENT_IMP_FINITE) THEN + ASM_SIMP_TAC[CARD_CLAUSES; GSYM INT_OF_NUM_SUC] THEN + ASM_SIMP_TAC[INDEPENDENT_IMP_AFFINE_DEPENDENT_0] THEN + ASM_MESON_TAC[HAS_SIZE]);; + +let CHOOSE_POLYTOPE = prove + (`!n. --(&1) <= n /\ n <= &(dimindex(:N)) + ==> ?s:real^N->bool. polytope s /\ aff_dim s = n`, + MESON_TAC[CHOOSE_SIMPLEX; SIMPLEX_IMP_POLYTOPE; AFF_DIM_SIMPLEX]);; + +(* ------------------------------------------------------------------------- *) +(* Simplicial complexes and triangulations. *) +(* ------------------------------------------------------------------------- *) + +let simplicial_complex = new_definition + `simplicial_complex c <=> + FINITE c /\ + (!s. s IN c ==> ?n. n simplex s) /\ + (!f s. s IN c /\ f face_of s ==> f IN c) /\ + (!s s'. s IN c /\ s' IN c + ==> (s INTER s') face_of s /\ (s INTER s') face_of s')`;; + +let triangulation = new_definition + `triangulation(tr:(real^N->bool)->bool) <=> + FINITE tr /\ + (!t. t IN tr ==> ?n. n simplex t) /\ + (!t t'. t IN tr /\ t' IN tr + ==> (t INTER t') face_of t /\ (t INTER t') face_of t')`;; + +let SIMPLICIAL_COMPLEX_IMP_TRIANGULATION = prove + (`!tr. simplicial_complex tr ==> triangulation tr`, + REWRITE_TAC[triangulation; simplicial_complex] THEN MESON_TAC[]);; + +let TRIANGULATION_UNION = prove + (`!tr1 tr2. + triangulation(tr1 UNION tr2) <=> + triangulation tr1 /\ triangulation tr2 /\ + (!s t. s IN tr1 /\ t IN tr2 + ==> s INTER t face_of s /\ s INTER t face_of t)`, + REWRITE_TAC[triangulation; FINITE_UNION; IN_UNION] THEN + MESON_TAC[INTER_COMM]);; + +let TRIANGULATION_INTER_SIMPLEX = prove + (`!tr t t':real^N->bool. + triangulation tr /\ t IN tr /\ t' IN tr + ==> t INTER t' = convex hull ({x | x extreme_point_of t} INTER + {x | x extreme_point_of t'})`, + REWRITE_TAC[triangulation] THEN REPEAT STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`t:real^N->bool`; `t':real^N->bool`]) THEN + ASM_REWRITE_TAC[] THEN STRIP_TAC THEN + FIRST_X_ASSUM(fun th -> MAP_EVERY (MP_TAC o C SPEC th) + [`t:real^N->bool`; `t':real^N->bool`]) THEN + ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `m:int` THEN DISCH_TAC THEN X_GEN_TAC `n:int` THEN DISCH_TAC THEN + MP_TAC(ISPECL [`m:int`; `t':real^N->bool`; + `t INTER t':real^N->bool`] FACE_OF_SIMPLEX_SUBSET) THEN + MP_TAC(ISPECL [`n:int`; `t:real^N->bool`; + `t INTER t':real^N->bool`] FACE_OF_SIMPLEX_SUBSET) THEN + ASM_SIMP_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `d:real^N->bool` (STRIP_ASSUME_TAC o GSYM)) THEN + DISCH_THEN(X_CHOOSE_THEN `d':real^N->bool` (STRIP_ASSUME_TAC o GSYM)) THEN + MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL + [ALL_TAC; + MATCH_MP_TAC HULL_MINIMAL THEN + CONJ_TAC THENL [ALL_TAC; ASM_MESON_TAC[CONVEX_INTER; CONVEX_SIMPLEX]] THEN + SIMP_TAC[SUBSET; IN_INTER; IN_ELIM_THM; extreme_point_of]] THEN + MATCH_MP_TAC SUBSET_TRANS THEN + EXISTS_TAC `convex hull {x:real^N | x extreme_point_of (t INTER t')}` THEN + CONJ_TAC THENL + [MATCH_MP_TAC(SET_RULE `s = t ==> s SUBSET t`) THEN + MATCH_MP_TAC KREIN_MILMAN_MINKOWSKI THEN + ASM_MESON_TAC[COMPACT_INTER; CONVEX_INTER; COMPACT_SIMPLEX; CONVEX_SIMPLEX]; + MATCH_MP_TAC HULL_MONO THEN REWRITE_TAC[SUBSET_INTER] THEN CONJ_TAC THENL + [SUBST1_TAC(SYM(ASSUME `convex hull d:real^N->bool = t INTER t'`)); + SUBST1_TAC(SYM(ASSUME `convex hull d':real^N->bool = t INTER t'`))] THEN + REWRITE_TAC[SUBSET; IN_ELIM_THM] THEN GEN_TAC THEN + DISCH_THEN(MP_TAC o MATCH_MP EXTREME_POINT_OF_CONVEX_HULL) THEN + ASM SET_TAC[]]);; + +let TRIANGULATION_SIMPLICIAL_COMPLEX = prove + (`!tr. triangulation tr + ==> simplicial_complex {f:real^N->bool | ?t. t IN tr /\ f face_of t}`, + let lemma = prove + (`{f | ?t. t IN tr /\ P f t} = UNIONS (IMAGE (\t. {f | P f t}) tr)`, + GEN_REWRITE_TAC I [EXTENSION] THEN + REWRITE_TAC[IN_ELIM_THM; IN_UNIONS; IN_IMAGE; LEFT_AND_EXISTS_THM] THEN + ONCE_REWRITE_TAC[SWAP_EXISTS_THM] THEN + REWRITE_TAC[GSYM CONJ_ASSOC; UNWIND_THM2; IN_ELIM_THM]) in + REWRITE_TAC[triangulation; simplicial_complex] THEN + REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_GSPEC] THEN + REWRITE_TAC[IN_ELIM_THM] THEN GEN_TAC THEN + REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + REWRITE_TAC[RIGHT_IMP_FORALL_THM; IMP_IMP] THEN STRIP_TAC THEN + REPEAT CONJ_TAC THENL + [REWRITE_TAC[lemma] THEN ASM_SIMP_TAC[FINITE_UNIONS; FINITE_IMAGE] THEN + ASM_REWRITE_TAC[FORALL_IN_IMAGE] THEN + ASM_MESON_TAC[FINITE_FACES_OF_SIMPLEX]; + ASM_MESON_TAC[SIMPLEX_FACE_OF_SIMPLEX]; + ASM_MESON_TAC[FACE_OF_TRANS]; + ASM_MESON_TAC[FACE_OF_INTER_SUBFACE]]);; + +(* ------------------------------------------------------------------------- *) +(* Subdividing a cell complex (not necessarily simplicial). *) +(* ------------------------------------------------------------------------- *) + +let CELL_COMPLEX_SUBDIVISION_EXISTS = prove + (`!m:(real^N->bool)->bool d e. + &0 < e /\ + FINITE m /\ + (!c. c IN m ==> polytope c) /\ + (!c. c IN m ==> aff_dim c <= d) /\ + (!c1 c2. c1 IN m /\ c2 IN m + ==> c1 INTER c2 face_of c1 /\ c1 INTER c2 face_of c2) + ==> ?m'. (!c. c IN m' ==> diameter c < e) /\ + UNIONS m' = UNIONS m /\ + FINITE m' /\ + (!c. c IN m' ==> polytope c) /\ + (!c. c IN m' ==> aff_dim c <= d) /\ + (!c1 c2. c1 IN m' /\ c2 IN m' + ==> c1 INTER c2 face_of c1 /\ c1 INTER c2 face_of c2)`, + let lemma1 = prove + (`a < abs(x - y) + ==> &0 < a + ==> ?n. integer n /\ (x < n * a /\ n * a < y \/ + y < n * a /\ n * a < x)`, + REPEAT STRIP_TAC THEN + ASM_SIMP_TAC[GSYM REAL_LT_LDIV_EQ; GSYM REAL_LT_RDIV_EQ] THEN + MATCH_MP_TAC INTEGER_EXISTS_BETWEEN_ABS_LT THEN + REWRITE_TAC[real_div; GSYM REAL_SUB_RDISTRIB; REAL_ABS_MUL] THEN + ASM_SIMP_TAC[REAL_ABS_INV; REAL_ARITH `&0 < x ==> abs x = x`] THEN + ASM_SIMP_TAC[GSYM real_div; REAL_LT_RDIV_EQ; + REAL_MUL_LID; REAL_LT_IMP_LE]) + and lemma2 = prove + (`!m:(real^N->bool)->bool d. + FINITE m /\ + (!c. c IN m ==> polytope c) /\ + (!c. c IN m ==> aff_dim c <= d) /\ + (!c1 c2. c1 IN m /\ c2 IN m + ==> c1 INTER c2 face_of c1 /\ c1 INTER c2 face_of c2) + ==> !i. FINITE i + ==> ?m'. UNIONS m' = UNIONS m /\ + FINITE m' /\ + (!c. c IN m' ==> polytope c) /\ + (!c. c IN m' ==> aff_dim c <= d) /\ + (!c1 c2. c1 IN m' /\ c2 IN m' + ==> c1 INTER c2 face_of c1 /\ + c1 INTER c2 face_of c2) /\ + (!c x y. c IN m' /\ x IN c /\ y IN c + ==> !a b. (a,b) IN i + ==> a dot x <= b /\ a dot y <= b \/ + a dot x >= b /\ a dot y >= b)`, + REPEAT GEN_TAC THEN STRIP_TAC THEN MATCH_MP_TAC FINITE_INDUCT_STRONG THEN + REWRITE_TAC[NOT_IN_EMPTY; FORALL_PAIR_THM] THEN CONJ_TAC THENL + [EXISTS_TAC `m:(real^N->bool)->bool` THEN ASM_REWRITE_TAC[]; ALL_TAC] THEN + MAP_EVERY X_GEN_TAC [`a:real^N`; `b:real`; `i:(real^N#real)->bool`] THEN + GEN_REWRITE_TAC I [IMP_CONJ] THEN + DISCH_THEN(X_CHOOSE_THEN `n:(real^N->bool)->bool` MP_TAC) THEN + DISCH_THEN(CONJUNCTS_THEN2 (SUBST1_TAC o SYM) MP_TAC) THEN + POP_ASSUM_LIST(K ALL_TAC) THEN REPEAT STRIP_TAC THEN + EXISTS_TAC `{c INTER {x:real^N | a dot x <= b} | c IN n} UNION + {c INTER {x:real^N | a dot x >= b} | c IN n}` THEN + REPEAT CONJ_TAC THENL + [REWRITE_TAC[UNIONS_UNION; GSYM INTER_UNIONS; GSYM UNION_OVER_INTER] THEN + MATCH_MP_TAC(SET_RULE `(!x. x IN s) ==> t INTER s = t`) THEN + REWRITE_TAC[IN_UNION; IN_ELIM_THM] THEN REAL_ARITH_TAC; + ASM_SIMP_TAC[FINITE_UNION; SIMPLE_IMAGE; FINITE_IMAGE]; + REWRITE_TAC[IN_UNION; IN_ELIM_THM] THEN REPEAT STRIP_TAC THEN + ASM_SIMP_TAC[POLYTOPE_INTER_POLYHEDRON; POLYHEDRON_HALFSPACE_LE; + POLYHEDRON_HALFSPACE_GE]; + REWRITE_TAC[IN_UNION; IN_ELIM_THM] THEN REPEAT STRIP_TAC THEN + ASM_MESON_TAC[INT_LE_TRANS; AFF_DIM_SUBSET; INTER_SUBSET]; + REWRITE_TAC[IN_UNION; IN_ELIM_THM] THEN REPEAT STRIP_TAC THEN + ASM_REWRITE_TAC[] THEN + ONCE_REWRITE_TAC[SET_RULE + `(s INTER t) INTER (s' INTER t') = (s INTER s') INTER (t INTER t')`] THEN + MATCH_MP_TAC FACE_OF_INTER_INTER THEN ASM_SIMP_TAC[] THEN + SIMP_TAC[SET_RULE `s INTER s = s`; FACE_OF_REFL; CONVEX_HALFSPACE_LE; + CONVEX_HALFSPACE_GE] THEN + REWRITE_TAC[INTER; IN_ELIM_THM; HYPERPLANE_FACE_OF_HALFSPACE_LE; + HYPERPLANE_FACE_OF_HALFSPACE_GE; + REAL_ARITH `a <= b /\ a >= b <=> a = b`; + REAL_ARITH `a >= b /\ a <= b <=> a = b`]; + REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; IN_UNION; FORALL_AND_THM; + IN_INSERT; + TAUT `p \/ q ==> r <=> (p ==> r) /\ (q ==> r)`] THEN + REWRITE_TAC[FORALL_IN_GSPEC; IN_INTER; IN_ELIM_THM; PAIR_EQ] THEN + SIMP_TAC[] THEN ASM_MESON_TAC[]]) in + REPEAT STRIP_TAC THEN + SUBGOAL_THEN `bounded(UNIONS m:real^N->bool)` MP_TAC THENL + [ASM_SIMP_TAC[BOUNDED_UNIONS; POLYTOPE_IMP_BOUNDED]; ALL_TAC] THEN + REWRITE_TAC[BOUNDED_POS_LT; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `B:real` THEN REWRITE_TAC[] THEN STRIP_TAC THEN + MP_TAC(ISPECL [`--B / (e / &2 / &(dimindex(:N)))`; + `B / (e / &2 / &(dimindex(:N)))`] FINITE_INTSEG) THEN + ASM_SIMP_TAC[REAL_LE_LDIV_EQ; REAL_LE_RDIV_EQ; REAL_HALF; + REAL_LT_DIV; REAL_OF_NUM_LT; DIMINDEX_GE_1; LE_1] THEN + REWRITE_TAC[REAL_BOUNDS_LE] THEN ABBREV_TAC + `k = {i | integer i /\ abs(i * e / &2 / &(dimindex(:N))) <= B}` THEN + DISCH_TAC THEN + MP_TAC(ISPECL [`m:(real^N->bool)->bool`; `d:int`] lemma2) THEN + ASM_REWRITE_TAC[] THEN DISCH_THEN(MP_TAC o SPEC + `{ (basis i:real^N,j * e / &2 / &(dimindex(:N))) | + i IN 1..dimindex(:N) /\ j IN k}`) THEN + ASM_SIMP_TAC[FINITE_PRODUCT_DEPENDENT; FINITE_NUMSEG] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `n:(real^N->bool)->bool` THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + X_GEN_TAC `c:real^N->bool` THEN DISCH_TAC THEN + MATCH_MP_TAC(REAL_ARITH `&0 < e /\ x <= e / &2 ==> x < e`) THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC DIAMETER_LE THEN + CONJ_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN + MAP_EVERY X_GEN_TAC [`x:real^N`; `y:real^N`] THEN STRIP_TAC THEN + W(MP_TAC o PART_MATCH lhand NORM_LE_L1 o lhand o snd) THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] REAL_LE_TRANS) THEN + MATCH_MP_TAC SUM_BOUND_GEN THEN + REWRITE_TAC[FINITE_NUMSEG; CARD_NUMSEG_1; NUMSEG_EMPTY] THEN + REWRITE_TAC[NOT_LT; DIMINDEX_GE_1; IN_NUMSEG; VECTOR_SUB_COMPONENT] THEN + X_GEN_TAC `i:num` THEN STRIP_TAC THEN REWRITE_TAC[GSYM REAL_NOT_LT] THEN + DISCH_THEN(MP_TAC o MATCH_MP lemma1) THEN + ASM_SIMP_TAC[REAL_HALF; REAL_LT_DIV; + REAL_OF_NUM_LT; DIMINDEX_GE_1; LE_1] THEN + DISCH_THEN(X_CHOOSE_THEN `j:real` (CONJUNCTS_THEN ASSUME_TAC)) THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`c:real^N->bool`; `x:real^N`; `y:real^N`]) THEN + ASM_REWRITE_TAC[] THEN DISCH_THEN(MP_TAC o + SPECL [`basis i:real^N`; `j * e / &2 / &(dimindex(:N))`]) THEN + ASM_SIMP_TAC[DOT_BASIS; IN_ELIM_THM; NOT_IMP] THEN + CONJ_TAC THENL [ALL_TAC; ASM_REAL_ARITH_TAC] THEN + MAP_EVERY EXISTS_TAC [`i:num`; `j:real`] THEN ASM_REWRITE_TAC[IN_NUMSEG] THEN + EXPAND_TAC "k" THEN ASM_REWRITE_TAC[IN_ELIM_THM] THEN + FIRST_X_ASSUM DISJ_CASES_TAC THEN FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP + (REAL_ARITH `a < x /\ x < b + ==> abs a <= c /\ abs b <= c ==> abs x <= c`)) THEN + CONJ_TAC THEN + W(MP_TAC o PART_MATCH (lhand o rand) COMPONENT_LE_NORM o lhand o snd) THEN + ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] REAL_LE_TRANS) THEN + MATCH_MP_TAC REAL_LT_IMP_LE THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM SET_TAC[]);; diff --git a/Multivariate/realanalysis.ml b/Multivariate/realanalysis.ml new file mode 100644 index 0000000..33509f8 --- /dev/null +++ b/Multivariate/realanalysis.ml @@ -0,0 +1,18887 @@ +(* ========================================================================= *) +(* Some analytic concepts for R instead of R^1. *) +(* *) +(* (c) Copyright, John Harrison 1998-2008 *) +(* ========================================================================= *) + +needs "Library/binomial.ml";; +needs "Multivariate/measure.ml";; +needs "Multivariate/polytope.ml";; +needs "Multivariate/transcendentals.ml";; + +(* ------------------------------------------------------------------------- *) +(* Open-ness and closedness of a set of reals. *) +(* ------------------------------------------------------------------------- *) + +let real_open = new_definition + `real_open s <=> + !x. x IN s ==> ?e. &0 < e /\ !x'. abs(x' - x) < e ==> x' IN s`;; + +let real_closed = new_definition + `real_closed s <=> real_open((:real) DIFF s)`;; + +let euclideanreal = new_definition + `euclideanreal = topology real_open`;; + +let REAL_OPEN_EMPTY = prove + (`real_open {}`, + REWRITE_TAC[real_open; NOT_IN_EMPTY]);; + +let REAL_OPEN_UNIV = prove + (`real_open(:real)`, + REWRITE_TAC[real_open; IN_UNIV] THEN MESON_TAC[REAL_LT_01]);; + +let REAL_OPEN_INTER = prove + (`!s t. real_open s /\ real_open t ==> real_open (s INTER t)`, + REPEAT GEN_TAC THEN REWRITE_TAC[real_open; AND_FORALL_THM; IN_INTER] THEN + MATCH_MP_TAC MONO_FORALL THEN GEN_TAC THEN + DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN + ASM_REWRITE_TAC[] THEN DISCH_THEN(CONJUNCTS_THEN2 + (X_CHOOSE_TAC `d1:real`) (X_CHOOSE_TAC `d2:real`)) THEN + MP_TAC(SPECL [`d1:real`; `d2:real`] REAL_DOWN2) THEN + ASM_MESON_TAC[REAL_LT_TRANS]);; + +let REAL_OPEN_UNIONS = prove + (`(!s. s IN f ==> real_open s) ==> real_open(UNIONS f)`, + REWRITE_TAC[real_open; IN_UNIONS] THEN MESON_TAC[]);; + +let REAL_OPEN_IN = prove + (`!s. real_open s <=> open_in euclideanreal s`, + GEN_TAC THEN REWRITE_TAC[euclideanreal] THEN CONV_TAC SYM_CONV THEN + AP_THM_TAC THEN REWRITE_TAC[GSYM(CONJUNCT2 topology_tybij)] THEN + REWRITE_TAC[REWRITE_RULE[IN] istopology] THEN + REWRITE_TAC[REAL_OPEN_EMPTY; REAL_OPEN_INTER; SUBSET] THEN + MESON_TAC[IN; REAL_OPEN_UNIONS]);; + +let TOPSPACE_EUCLIDEANREAL = prove + (`topspace euclideanreal = (:real)`, + REWRITE_TAC[topspace; EXTENSION; IN_UNIV; IN_UNIONS; IN_ELIM_THM] THEN + MESON_TAC[REAL_OPEN_UNIV; IN_UNIV; REAL_OPEN_IN]);; + +let TOPSPACE_EUCLIDEANREAL_SUBTOPOLOGY = prove + (`!s. topspace (subtopology euclideanreal s) = s`, + REWRITE_TAC[TOPSPACE_EUCLIDEANREAL; TOPSPACE_SUBTOPOLOGY; INTER_UNIV]);; + +let REAL_CLOSED_IN = prove + (`!s. real_closed s <=> closed_in euclideanreal s`, + REWRITE_TAC[real_closed; closed_in; TOPSPACE_EUCLIDEANREAL; + REAL_OPEN_IN; SUBSET_UNIV]);; + +let REAL_OPEN_UNION = prove + (`!s t. real_open s /\ real_open t ==> real_open(s UNION t)`, + REWRITE_TAC[REAL_OPEN_IN; OPEN_IN_UNION]);; + +let REAL_OPEN_SUBREAL_OPEN = prove + (`!s. real_open s <=> !x. x IN s ==> ?t. real_open t /\ x IN t /\ t SUBSET s`, + REWRITE_TAC[REAL_OPEN_IN; GSYM OPEN_IN_SUBOPEN]);; + +let REAL_CLOSED_EMPTY = prove + (`real_closed {}`, + REWRITE_TAC[REAL_CLOSED_IN; CLOSED_IN_EMPTY]);; + +let REAL_CLOSED_UNIV = prove + (`real_closed(:real)`, + REWRITE_TAC[REAL_CLOSED_IN; GSYM TOPSPACE_EUCLIDEANREAL; CLOSED_IN_TOPSPACE]);; + +let REAL_CLOSED_UNION = prove + (`!s t. real_closed s /\ real_closed t ==> real_closed(s UNION t)`, + REWRITE_TAC[REAL_CLOSED_IN; CLOSED_IN_UNION]);; + +let REAL_CLOSED_INTER = prove + (`!s t. real_closed s /\ real_closed t ==> real_closed(s INTER t)`, + REWRITE_TAC[REAL_CLOSED_IN; CLOSED_IN_INTER]);; + +let REAL_CLOSED_INTERS = prove + (`!f. (!s. s IN f ==> real_closed s) ==> real_closed(INTERS f)`, + REWRITE_TAC[REAL_CLOSED_IN] THEN REPEAT STRIP_TAC THEN + ASM_CASES_TAC `f:(real->bool)->bool = {}` THEN + ASM_SIMP_TAC[CLOSED_IN_INTERS; INTERS_0] THEN + REWRITE_TAC[GSYM TOPSPACE_EUCLIDEANREAL; CLOSED_IN_TOPSPACE]);; + +let REAL_OPEN_REAL_CLOSED = prove + (`!s. real_open s <=> real_closed(UNIV DIFF s)`, + SIMP_TAC[REAL_OPEN_IN; REAL_CLOSED_IN; TOPSPACE_EUCLIDEANREAL; SUBSET_UNIV; + OPEN_IN_CLOSED_IN_EQ]);; + +let REAL_OPEN_DIFF = prove + (`!s t. real_open s /\ real_closed t ==> real_open(s DIFF t)`, + REWRITE_TAC[REAL_OPEN_IN; REAL_CLOSED_IN; OPEN_IN_DIFF]);; + +let REAL_CLOSED_DIFF = prove + (`!s t. real_closed s /\ real_open t ==> real_closed(s DIFF t)`, + REWRITE_TAC[REAL_OPEN_IN; REAL_CLOSED_IN; CLOSED_IN_DIFF]);; + +let REAL_OPEN_INTERS = prove + (`!s. FINITE s /\ (!t. t IN s ==> real_open t) ==> real_open(INTERS s)`, + REWRITE_TAC[IMP_CONJ] THEN MATCH_MP_TAC FINITE_INDUCT_STRONG THEN + REWRITE_TAC[INTERS_INSERT; INTERS_0; REAL_OPEN_UNIV; IN_INSERT] THEN + MESON_TAC[REAL_OPEN_INTER]);; + +let REAL_CLOSED_UNIONS = prove + (`!s. FINITE s /\ (!t. t IN s ==> real_closed t) ==> real_closed(UNIONS s)`, + REWRITE_TAC[IMP_CONJ] THEN MATCH_MP_TAC FINITE_INDUCT_STRONG THEN + REWRITE_TAC[UNIONS_INSERT; UNIONS_0; REAL_CLOSED_EMPTY; IN_INSERT] THEN + MESON_TAC[REAL_CLOSED_UNION]);; + +let REAL_OPEN = prove + (`!s. real_open s <=> open(IMAGE lift s)`, + REWRITE_TAC[real_open; open_def; FORALL_IN_IMAGE; FORALL_LIFT; DIST_LIFT; + LIFT_IN_IMAGE_LIFT]);; + +let REAL_CLOSED = prove + (`!s. real_closed s <=> closed(IMAGE lift s)`, + GEN_TAC THEN REWRITE_TAC[real_closed; REAL_OPEN; closed] THEN + AP_TERM_TAC THEN REWRITE_TAC[EXTENSION; IN_IMAGE; IN_DIFF; IN_UNIV] THEN + MESON_TAC[LIFT_DROP]);; + +let REAL_CLOSED_HALFSPACE_LE = prove + (`!a. real_closed {x | x <= a}`, + GEN_TAC THEN SUBGOAL_THEN `closed {x | drop x <= a}` MP_TAC THENL + [REWRITE_TAC[drop; CLOSED_HALFSPACE_COMPONENT_LE]; ALL_TAC] THEN + MATCH_MP_TAC EQ_IMP THEN REWRITE_TAC[REAL_CLOSED] THEN AP_TERM_TAC THEN + REWRITE_TAC[EXTENSION; IN_IMAGE; IN_ELIM_THM] THEN MESON_TAC[LIFT_DROP]);; + +let REAL_CLOSED_HALFSPACE_GE = prove + (`!a. real_closed {x | x >= a}`, + GEN_TAC THEN SUBGOAL_THEN `closed {x | drop x >= a}` MP_TAC THENL + [REWRITE_TAC[drop; CLOSED_HALFSPACE_COMPONENT_GE]; ALL_TAC] THEN + MATCH_MP_TAC EQ_IMP THEN REWRITE_TAC[REAL_CLOSED] THEN AP_TERM_TAC THEN + REWRITE_TAC[EXTENSION; IN_IMAGE; IN_ELIM_THM] THEN MESON_TAC[LIFT_DROP]);; + +let REAL_OPEN_HALFSPACE_LT = prove + (`!a. real_open {x | x < a}`, + GEN_TAC THEN SUBGOAL_THEN `open {x | drop x < a}` MP_TAC THENL + [REWRITE_TAC[drop; OPEN_HALFSPACE_COMPONENT_LT]; ALL_TAC] THEN + MATCH_MP_TAC EQ_IMP THEN REWRITE_TAC[REAL_OPEN] THEN AP_TERM_TAC THEN + REWRITE_TAC[EXTENSION; IN_IMAGE; IN_ELIM_THM] THEN MESON_TAC[LIFT_DROP]);; + +let REAL_OPEN_HALFSPACE_GT = prove + (`!a. real_open {x | x > a}`, + GEN_TAC THEN SUBGOAL_THEN `open {x | drop x > a}` MP_TAC THENL + [REWRITE_TAC[drop; OPEN_HALFSPACE_COMPONENT_GT]; ALL_TAC] THEN + MATCH_MP_TAC EQ_IMP THEN REWRITE_TAC[REAL_OPEN] THEN AP_TERM_TAC THEN + REWRITE_TAC[EXTENSION; IN_IMAGE; IN_ELIM_THM] THEN MESON_TAC[LIFT_DROP]);; + +(* ------------------------------------------------------------------------- *) +(* Compactness of a set of reals. *) +(* ------------------------------------------------------------------------- *) + +let real_bounded = new_definition + `real_bounded s <=> ?B. !x. x IN s ==> abs(x) <= B`;; + +let REAL_BOUNDED = prove + (`real_bounded s <=> bounded(IMAGE lift s)`, + REWRITE_TAC[BOUNDED_LIFT; real_bounded]);; + +let REAL_BOUNDED_POS = prove + (`!s. real_bounded s <=> ?B. &0 < B /\ !x. x IN s ==> abs(x) <= B`, + REWRITE_TAC[real_bounded] THEN + MESON_TAC[REAL_ARITH `&0 < &1 + abs B /\ (x <= B ==> x <= &1 + abs B)`]);; + +let REAL_BOUNDED_POS_LT = prove + (`!s. real_bounded s <=> ?b. &0 < b /\ !x. x IN s ==> abs(x) < b`, + REWRITE_TAC[real_bounded] THEN + MESON_TAC[REAL_LT_IMP_LE; + REAL_ARITH `&0 < &1 + abs(y) /\ (x <= y ==> x < &1 + abs(y))`]);; + +let REAL_BOUNDED_SUBSET = prove + (`!s t. real_bounded t /\ s SUBSET t ==> real_bounded s`, + MESON_TAC[REAL_BOUNDED; BOUNDED_SUBSET; IMAGE_SUBSET]);; + +let REAL_BOUNDED_UNION = prove + (`!s t. real_bounded(s UNION t) <=> real_bounded s /\ real_bounded t`, + REWRITE_TAC[REAL_BOUNDED; IMAGE_UNION; BOUNDED_UNION]);; + +let real_compact = new_definition + `real_compact s <=> compact(IMAGE lift s)`;; + +let REAL_COMPACT_IMP_BOUNDED = prove + (`!s. real_compact s ==> real_bounded s`, + REWRITE_TAC[real_compact; REAL_BOUNDED; COMPACT_IMP_BOUNDED]);; + +let REAL_COMPACT_IMP_CLOSED = prove + (`!s. real_compact s ==> real_closed s`, + REWRITE_TAC[real_compact; REAL_CLOSED; COMPACT_IMP_CLOSED]);; + +let REAL_COMPACT_EQ_BOUNDED_CLOSED = prove + (`!s. real_compact s <=> real_bounded s /\ real_closed s`, + REWRITE_TAC[real_compact; REAL_BOUNDED; REAL_CLOSED] THEN + REWRITE_TAC[COMPACT_EQ_BOUNDED_CLOSED]);; + +let REAL_COMPACT_UNION = prove + (`!s t. real_compact s /\ real_compact t ==> real_compact(s UNION t)`, + REWRITE_TAC[real_compact; IMAGE_UNION; COMPACT_UNION]);; + +let REAL_COMPACT_ATTAINS_INF = prove + (`!s. real_compact s /\ ~(s = {}) ==> ?x. x IN s /\ !y. y IN s ==> x <= y`, + REWRITE_TAC[real_compact; COMPACT_ATTAINS_INF]);; + +let REAL_COMPACT_ATTAINS_SUP = prove + (`!s. real_compact s /\ ~(s = {}) ==> ?x. x IN s /\ !y. y IN s ==> y <= x`, + REWRITE_TAC[real_compact; COMPACT_ATTAINS_SUP]);; + +(* ------------------------------------------------------------------------- *) +(* Limits of functions with real range. *) +(* ------------------------------------------------------------------------- *) + +parse_as_infix("--->",(12,"right"));; + +let tendsto_real = new_definition + `(f ---> l) net <=> !e. &0 < e ==> eventually (\x. abs(f(x) - l) < e) net`;; + +let reallim = new_definition + `reallim net f = @l. (f ---> l) net`;; + +let TENDSTO_REAL = prove + (`(s ---> l) = ((lift o s) --> lift l)`, + REWRITE_TAC[FUN_EQ_THM; tendsto; tendsto_real; o_THM; DIST_LIFT]);; + +let REAL_TENDSTO = prove + (`(s --> l) = (drop o s ---> drop l)`, + REWRITE_TAC[TENDSTO_REAL; o_DEF; LIFT_DROP; ETA_AX]);; + +let REALLIM_COMPLEX = prove + (`(s ---> l) = ((Cx o s) --> Cx(l))`, + REWRITE_TAC[FUN_EQ_THM; tendsto; tendsto_real; o_THM; dist; + GSYM CX_SUB; COMPLEX_NORM_CX]);; + +let REALLIM_UNIQUE = prove + (`!net f l l'. + ~trivial_limit net /\ (f ---> l) net /\ (f ---> l') net ==> l = l'`, + REPEAT GEN_TAC THEN REWRITE_TAC[TENDSTO_REAL] THEN + DISCH_THEN(MP_TAC o MATCH_MP LIM_UNIQUE) THEN REWRITE_TAC[LIFT_EQ]);; + +let REALLIM_CONST = prove + (`!net a. ((\x. a) ---> a) net`, + REWRITE_TAC[TENDSTO_REAL; o_DEF; LIM_CONST]);; + +let REALLIM_LMUL = prove + (`!f l c. (f ---> l) net ==> ((\x. c * f x) ---> c * l) net`, + REWRITE_TAC[TENDSTO_REAL; o_DEF; LIFT_CMUL; LIM_CMUL]);; + +let REALLIM_RMUL = prove + (`!f l c. (f ---> l) net ==> ((\x. f x * c) ---> l * c) net`, + ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN REWRITE_TAC[REALLIM_LMUL]);; + +let REALLIM_LMUL_EQ = prove + (`!net f l c. + ~(c = &0) ==> (((\x. c * f x) ---> c * l) net <=> (f ---> l) net)`, + REPEAT STRIP_TAC THEN EQ_TAC THEN SIMP_TAC[REALLIM_LMUL] THEN + DISCH_THEN(MP_TAC o SPEC `inv c:real` o MATCH_MP REALLIM_LMUL) THEN + ASM_SIMP_TAC[REAL_MUL_ASSOC; REAL_MUL_LINV; REAL_MUL_LID; ETA_AX]);; + +let REALLIM_RMUL_EQ = prove + (`!net f l c. + ~(c = &0) ==> (((\x. f x * c) ---> l * c) net <=> (f ---> l) net)`, + ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN REWRITE_TAC[REALLIM_LMUL_EQ]);; + +let REALLIM_NEG = prove + (`!net f l. (f ---> l) net ==> ((\x. --(f x)) ---> --l) net`, + REWRITE_TAC[TENDSTO_REAL; o_DEF; LIFT_NEG; LIM_NEG]);; + +let REALLIM_NEG_EQ = prove + (`!net f l. ((\x. --(f x)) ---> --l) net <=> (f ---> l) net`, + REWRITE_TAC[TENDSTO_REAL; o_DEF; LIFT_NEG; LIM_NEG_EQ]);; + +let REALLIM_ADD = prove + (`!net:(A)net f g l m. + (f ---> l) net /\ (g ---> m) net ==> ((\x. f(x) + g(x)) ---> l + m) net`, + REWRITE_TAC[TENDSTO_REAL; o_DEF; LIFT_ADD; LIM_ADD]);; + +let REALLIM_SUB = prove + (`!net:(A)net f g l m. + (f ---> l) net /\ (g ---> m) net ==> ((\x. f(x) - g(x)) ---> l - m) net`, + REWRITE_TAC[TENDSTO_REAL; o_DEF; LIFT_SUB; LIM_SUB]);; + +let REALLIM_MUL = prove + (`!net:(A)net f g l m. + (f ---> l) net /\ (g ---> m) net ==> ((\x. f(x) * g(x)) ---> l * m) net`, + REWRITE_TAC[REALLIM_COMPLEX; o_DEF; CX_MUL; LIM_COMPLEX_MUL]);; + +let REALLIM_INV = prove + (`!net f l. + (f ---> l) net /\ ~(l = &0) ==> ((\x. inv(f x)) ---> inv l) net`, + REWRITE_TAC[REALLIM_COMPLEX; o_DEF; CX_INV; LIM_COMPLEX_INV; GSYM CX_INJ]);; + +let REALLIM_DIV = prove + (`!net:(A)net f g l m. + (f ---> l) net /\ (g ---> m) net /\ ~(m = &0) + ==> ((\x. f(x) / g(x)) ---> l / m) net`, + SIMP_TAC[real_div; REALLIM_MUL; REALLIM_INV]);; + +let REALLIM_ABS = prove + (`!net f l. (f ---> l) net ==> ((\x. abs(f x)) ---> abs l) net`, + REPEAT GEN_TAC THEN REWRITE_TAC[tendsto_real] THEN + MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `e:real` THEN + DISCH_THEN(fun th -> DISCH_TAC THEN MP_TAC th) THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] EVENTUALLY_MONO) THEN + REWRITE_TAC[] THEN REAL_ARITH_TAC);; + +let REALLIM_POW = prove + (`!net f l n. (f ---> l) net ==> ((\x. f x pow n) ---> l pow n) net`, + REPLICATE_TAC 3 GEN_TAC THEN + INDUCT_TAC THEN ASM_SIMP_TAC[real_pow; REALLIM_CONST; REALLIM_MUL]);; + +let REALLIM_MAX = prove + (`!net:(A)net f g l m. + (f ---> l) net /\ (g ---> m) net + ==> ((\x. max (f x) (g x)) ---> max l m) net`, + REWRITE_TAC[REAL_ARITH `max x y = inv(&2) * ((x + y) + abs(x - y))`] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC REALLIM_LMUL THEN + ASM_SIMP_TAC[REALLIM_ADD; REALLIM_ABS; REALLIM_SUB]);; + +let REALLIM_MIN = prove + (`!net:(A)net f g l m. + (f ---> l) net /\ (g ---> m) net + ==> ((\x. min (f x) (g x)) ---> min l m) net`, + REWRITE_TAC[REAL_ARITH `min x y = inv(&2) * ((x + y) - abs(x - y))`] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC REALLIM_LMUL THEN + ASM_SIMP_TAC[REALLIM_ADD; REALLIM_ABS; REALLIM_SUB]);; + +let REALLIM_NULL = prove + (`!net f l. (f ---> l) net <=> ((\x. f(x) - l) ---> &0) net`, + REWRITE_TAC[tendsto_real; REAL_SUB_RZERO]);; + +let REALLIM_NULL_ADD = prove + (`!net:(A)net f g. + (f ---> &0) net /\ (g ---> &0) net ==> ((\x. f(x) + g(x)) ---> &0) net`, + REPEAT GEN_TAC THEN DISCH_THEN(MP_TAC o MATCH_MP REALLIM_ADD) THEN + REWRITE_TAC[REAL_ADD_LID]);; + +let REALLIM_NULL_LMUL = prove + (`!net f c. (f ---> &0) net ==> ((\x. c * f x) ---> &0) net`, + REPEAT GEN_TAC THEN + DISCH_THEN(MP_TAC o SPEC `c:real` o MATCH_MP REALLIM_LMUL) THEN + REWRITE_TAC[REAL_MUL_RZERO]);; + +let REALLIM_NULL_RMUL = prove + (`!net f c. (f ---> &0) net ==> ((\x. f x * c) ---> &0) net`, + REPEAT GEN_TAC THEN + DISCH_THEN(MP_TAC o SPEC `c:real` o MATCH_MP REALLIM_RMUL) THEN + REWRITE_TAC[REAL_MUL_LZERO]);; + +let REALLIM_NULL_POW = prove + (`!net f n. (f ---> &0) net /\ ~(n = 0) ==> ((\x. f x pow n) ---> &0) net`, + REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 + (MP_TAC o SPEC `n:num` o MATCH_MP REALLIM_POW) ASSUME_TAC) THEN + ASM_REWRITE_TAC[REAL_POW_ZERO]);; + +let REALLIM_NULL_LMUL_EQ = prove + (`!net f c. + ~(c = &0) ==> (((\x. c * f x) ---> &0) net <=> (f ---> &0) net)`, + MESON_TAC[REALLIM_LMUL_EQ; REAL_MUL_RZERO]);; + +let REALLIM_NULL_RMUL_EQ = prove + (`!net f c. + ~(c = &0) ==> (((\x. f x * c) ---> &0) net <=> (f ---> &0) net)`, + MESON_TAC[REALLIM_RMUL_EQ; REAL_MUL_LZERO]);; + +let REALLIM_RE = prove + (`!net f l. (f --> l) net ==> ((Re o f) ---> Re l) net`, + REWRITE_TAC[REALLIM_COMPLEX] THEN + REWRITE_TAC[tendsto; dist; o_THM; GSYM CX_SUB; COMPLEX_NORM_CX] THEN + REWRITE_TAC[GSYM RE_SUB; eventually] THEN + MESON_TAC[REAL_LET_TRANS; COMPLEX_NORM_GE_RE_IM]);; + +let REALLIM_IM = prove + (`!net f l. (f --> l) net ==> ((Im o f) ---> Im l) net`, + REWRITE_TAC[REALLIM_COMPLEX] THEN + REWRITE_TAC[tendsto; dist; o_THM; GSYM CX_SUB; COMPLEX_NORM_CX] THEN + REWRITE_TAC[GSYM IM_SUB; eventually] THEN + MESON_TAC[REAL_LET_TRANS; COMPLEX_NORM_GE_RE_IM]);; + +let REALLIM_TRANSFORM_EVENTUALLY = prove + (`!net f g l. + eventually (\x. f x = g x) net /\ (f ---> l) net ==> (g ---> l) net`, + REPEAT GEN_TAC THEN REWRITE_TAC[TENDSTO_REAL] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] LIM_TRANSFORM_EVENTUALLY) THEN + POP_ASSUM MP_TAC THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] EVENTUALLY_MONO) THEN + SIMP_TAC[o_THM]);; + +let REALLIM_TRANSFORM = prove + (`!net f g l. + ((\x. f x - g x) ---> &0) net /\ (f ---> l) net ==> (g ---> l) net`, + REPEAT GEN_TAC THEN REWRITE_TAC[TENDSTO_REAL] THEN + REWRITE_TAC[o_DEF; LIFT_NUM; LIFT_SUB; LIM_TRANSFORM]);; + +let REALLIM_TRANSFORM_EQ = prove + (`!net f:A->real g l. + ((\x. f x - g x) ---> &0) net ==> ((f ---> l) net <=> (g ---> l) net)`, + REPEAT GEN_TAC THEN REWRITE_TAC[TENDSTO_REAL] THEN + REWRITE_TAC[o_DEF; LIFT_NUM; LIFT_SUB; LIM_TRANSFORM_EQ]);; + +let REAL_SEQ_OFFSET = prove + (`!f l k. (f ---> l) sequentially ==> ((\i. f (i + k)) ---> l) sequentially`, + REPEAT GEN_TAC THEN SIMP_TAC[TENDSTO_REAL; o_DEF] THEN + DISCH_THEN(MP_TAC o MATCH_MP SEQ_OFFSET) THEN SIMP_TAC[]);; + +let REAL_SEQ_OFFSET_REV = prove + (`!f l k. ((\i. f (i + k)) ---> l) sequentially ==> (f ---> l) sequentially`, + SIMP_TAC[TENDSTO_REAL; o_DEF] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC SEQ_OFFSET_REV THEN EXISTS_TAC `k:num` THEN ASM_SIMP_TAC[]);; + +let REALLIM_TRANSFORM_STRADDLE = prove + (`!f g h a. + eventually (\n. f(n) <= g(n)) net /\ (f ---> a) net /\ + eventually (\n. g(n) <= h(n)) net /\ (h ---> a) net + ==> (g ---> a) net`, + REPEAT GEN_TAC THEN + REWRITE_TAC[RIGHT_AND_FORALL_THM; tendsto_real; AND_FORALL_THM] THEN + MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `e:real` THEN + ASM_CASES_TAC `&0 < e` THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[GSYM EVENTUALLY_AND] THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] EVENTUALLY_MONO) THEN + REAL_ARITH_TAC);; + +let REALLIM_TRANSFORM_BOUND = prove + (`!f g. eventually (\n. abs(f n) <= g n) net /\ (g ---> &0) net + ==> (f ---> &0) net`, + REPEAT GEN_TAC THEN + REWRITE_TAC[RIGHT_AND_FORALL_THM; tendsto_real; AND_FORALL_THM] THEN + MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `e:real` THEN + ASM_CASES_TAC `&0 < e` THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[GSYM EVENTUALLY_AND] THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] EVENTUALLY_MONO) THEN + REAL_ARITH_TAC);; + +let REAL_CONVERGENT_IMP_BOUNDED = prove + (`!s l. (s ---> l) sequentially ==> real_bounded (IMAGE s (:num))`, + REPEAT GEN_TAC THEN REWRITE_TAC[REAL_BOUNDED; TENDSTO_REAL] THEN + DISCH_THEN(MP_TAC o MATCH_MP CONVERGENT_IMP_BOUNDED) THEN + REWRITE_TAC[BOUNDED_POS; FORALL_IN_IMAGE; IN_UNIV] THEN + REWRITE_TAC[o_DEF; NORM_LIFT]);; + +let REALLIM = prove + (`(f ---> l) net <=> + trivial_limit net \/ + !e. &0 < e ==> ?y. (?x. netord(net) x y) /\ + !x. netord(net) x y ==> abs(f(x) -l) < e`, + REWRITE_TAC[tendsto_real; eventually] THEN MESON_TAC[]);; + +let REALLIM_NULL_ABS = prove + (`!net f. ((\x. abs(f x)) ---> &0) net <=> (f ---> &0) net`, + REWRITE_TAC[REALLIM; REAL_SUB_RZERO; REAL_ABS_ABS]);; + +let REALLIM_WITHIN_LE = prove + (`!f:real^N->real l a s. + (f ---> l) (at a within s) <=> + !e. &0 < e ==> ?d. &0 < d /\ + !x. x IN s /\ &0 < dist(x,a) /\ dist(x,a) <= d + ==> abs(f(x) - l) < e`, + REWRITE_TAC[tendsto_real; EVENTUALLY_WITHIN_LE]);; + +let REALLIM_WITHIN = prove + (`!f:real^N->real l a s. + (f ---> l) (at a within s) <=> + !e. &0 < e + ==> ?d. &0 < d /\ + !x. x IN s /\ &0 < dist(x,a) /\ dist(x,a) < d + ==> abs(f(x) - l) < e`, + REWRITE_TAC[tendsto_real; EVENTUALLY_WITHIN] THEN MESON_TAC[]);; + +let REALLIM_AT = prove + (`!f l a:real^N. + (f ---> l) (at a) <=> + !e. &0 < e + ==> ?d. &0 < d /\ !x. &0 < dist(x,a) /\ dist(x,a) < d + ==> abs(f(x) - l) < e`, + REWRITE_TAC[tendsto_real; EVENTUALLY_AT] THEN MESON_TAC[]);; + +let REALLIM_AT_INFINITY = prove + (`!f l. (f ---> l) at_infinity <=> + !e. &0 < e ==> ?b. !x. norm(x) >= b ==> abs(f(x) - l) < e`, + REWRITE_TAC[tendsto_real; EVENTUALLY_AT_INFINITY] THEN MESON_TAC[]);; + +let REALLIM_SEQUENTIALLY = prove + (`!s l. (s ---> l) sequentially <=> + !e. &0 < e ==> ?N. !n. N <= n ==> abs(s(n) - l) < e`, + REWRITE_TAC[tendsto_real; EVENTUALLY_SEQUENTIALLY] THEN MESON_TAC[]);; + +let REALLIM_EVENTUALLY = prove + (`!net f l. eventually (\x. f x = l) net ==> (f ---> l) net`, + REWRITE_TAC[eventually; REALLIM] THEN + MESON_TAC[REAL_ARITH `abs(x - x) = &0`]);; + +let LIM_COMPONENTWISE = prove + (`!net f:A->real^N. + (f --> l) net <=> + !i. 1 <= i /\ i <= dimindex(:N) ==> ((\x. (f x)$i) ---> l$i) net`, + ONCE_REWRITE_TAC[LIM_COMPONENTWISE_LIFT] THEN + REWRITE_TAC[TENDSTO_REAL; o_DEF]);; + +let REALLIM_UBOUND = prove + (`!(net:A net) f l b. + (f ---> l) net /\ + ~trivial_limit net /\ + eventually (\x. f x <= b) net + ==> l <= b`, + REWRITE_TAC[FORALL_DROP; TENDSTO_REAL; LIFT_DROP] THEN + REPEAT STRIP_TAC THEN + MATCH_MP_TAC(ISPEC `net:A net` LIM_DROP_UBOUND) THEN + EXISTS_TAC `lift o (f:A->real)` THEN + ASM_REWRITE_TAC[o_THM; LIFT_DROP]);; + +let REALLIM_LBOUND = prove + (`!(net:A net) f l b. + (f ---> l) net /\ + ~trivial_limit net /\ + eventually (\x. b <= f x) net + ==> b <= l`, + ONCE_REWRITE_TAC[GSYM REAL_LE_NEG2] THEN + REPEAT STRIP_TAC THEN + MATCH_MP_TAC(ISPEC `net:A net` REALLIM_UBOUND) THEN + EXISTS_TAC `\a:A. --(f a:real)` THEN + ASM_REWRITE_TAC[REALLIM_NEG_EQ]);; + +let REALLIM_LE = prove + (`!net f g l m. + (f ---> l) net /\ (g ---> m) net /\ + ~trivial_limit net /\ + eventually (\x. f x <= g x) net + ==> l <= m`, + REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[CONJ_ASSOC] THEN + DISCH_THEN(CONJUNCTS_THEN2 + (MP_TAC o MATCH_MP REALLIM_SUB o ONCE_REWRITE_RULE[CONJ_SYM]) MP_TAC) THEN + ONCE_REWRITE_TAC[GSYM REAL_SUB_LE] THEN + REWRITE_TAC[GSYM IMP_CONJ_ALT; GSYM CONJ_ASSOC] THEN + DISCH_THEN(ACCEPT_TAC o MATCH_MP REALLIM_LBOUND));; + +let REALLIM_CONST_EQ = prove + (`!net:(A net) c d. ((\x. c) ---> d) net <=> trivial_limit net \/ c = d`, + REWRITE_TAC[TENDSTO_REAL; LIM_CONST_EQ; o_DEF; LIFT_EQ]);; + +let REALLIM_SUM = prove + (`!f:A->B->real s. + FINITE s /\ (!i. i IN s ==> ((f i) ---> (l i)) net) + ==> ((\x. sum s (\i. f i x)) ---> sum s l) net`, + GEN_TAC THEN REWRITE_TAC[IMP_CONJ] THEN + MATCH_MP_TAC FINITE_INDUCT_STRONG THEN + SIMP_TAC[SUM_CLAUSES; REALLIM_CONST; REALLIM_ADD; IN_INSERT; ETA_AX]);; + +let REALLIM_NULL_COMPARISON = prove + (`!net:(A)net f g. + eventually (\x. abs(f x) <= g x) net /\ (g ---> &0) net + ==> (f ---> &0) net`, + REWRITE_TAC[TENDSTO_REAL; LIFT_NUM; o_DEF] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC LIM_NULL_COMPARISON THEN + EXISTS_TAC `g:A->real` THEN ASM_REWRITE_TAC[NORM_LIFT]);; + +(* ------------------------------------------------------------------------- *) +(* Real series. *) +(* ------------------------------------------------------------------------- *) + +parse_as_infix("real_sums",(12,"right"));; + +let real_sums = new_definition + `(f real_sums l) s <=> ((\n. sum (s INTER (0..n)) f) ---> l) sequentially`;; + +let real_infsum = new_definition + `real_infsum s f = @l. (f real_sums l) s`;; + +let real_summable = new_definition + `real_summable s f = ?l. (f real_sums l) s`;; + +let REAL_SUMS = prove + (`(f real_sums l) = ((lift o f) sums (lift l))`, + REWRITE_TAC[FUN_EQ_THM; sums; real_sums; TENDSTO_REAL] THEN + SIMP_TAC[LIFT_SUM; FINITE_INTER_NUMSEG; o_DEF]);; + +let REAL_SUMS_RE = prove + (`!f l s. (f sums l) s ==> ((Re o f) real_sums (Re l)) s`, + REPEAT GEN_TAC THEN REWRITE_TAC[real_sums; sums] THEN + DISCH_THEN(MP_TAC o MATCH_MP REALLIM_RE) THEN + SIMP_TAC[o_DEF; RE_VSUM; FINITE_INTER_NUMSEG]);; + +let REAL_SUMS_IM = prove + (`!f l s. (f sums l) s ==> ((Im o f) real_sums (Im l)) s`, + REPEAT GEN_TAC THEN REWRITE_TAC[real_sums; sums] THEN + DISCH_THEN(MP_TAC o MATCH_MP REALLIM_IM) THEN + SIMP_TAC[o_DEF; IM_VSUM; FINITE_INTER_NUMSEG]);; + +let REAL_SUMS_COMPLEX = prove + (`!f l s. (f real_sums l) s <=> ((Cx o f) sums (Cx l)) s`, + REWRITE_TAC[real_sums; sums; REALLIM_COMPLEX] THEN + SIMP_TAC[o_DEF; VSUM_CX; FINITE_INTER; FINITE_NUMSEG]);; + +let REAL_SUMMABLE = prove + (`real_summable s f <=> summable s (lift o f)`, + REWRITE_TAC[real_summable; summable; REAL_SUMS; GSYM EXISTS_LIFT]);; + +let REAL_SUMMABLE_COMPLEX = prove + (`real_summable s f <=> summable s (Cx o f)`, + REWRITE_TAC[real_summable; summable; REAL_SUMS_COMPLEX] THEN + EQ_TAC THENL [MESON_TAC[]; ALL_TAC] THEN + DISCH_THEN(X_CHOOSE_TAC `l:complex`) THEN EXISTS_TAC `Re l` THEN + SUBGOAL_THEN `Cx(Re l) = l` (fun th -> ASM_REWRITE_TAC[th]) THEN + REWRITE_TAC[GSYM REAL] THEN MATCH_MP_TAC REAL_SERIES THEN + MAP_EVERY EXISTS_TAC [`Cx o (f:num->real)`; `s:num->bool`] THEN + ASM_REWRITE_TAC[o_THM; REAL_CX]);; + +let REAL_SERIES_CAUCHY = prove + (`(?l. (f real_sums l) s) <=> + (!e. &0 < e ==> ?N. !m n. m >= N ==> abs(sum(s INTER (m..n)) f) < e)`, + REWRITE_TAC[REAL_SUMS; SERIES_CAUCHY; GSYM EXISTS_LIFT] THEN + SIMP_TAC[NORM_REAL; GSYM drop; DROP_VSUM; FINITE_INTER_NUMSEG] THEN + REWRITE_TAC[o_DEF; LIFT_DROP; ETA_AX]);; + +let REAL_SUMS_SUMMABLE = prove + (`!f l s. (f real_sums l) s ==> real_summable s f`, + REWRITE_TAC[real_summable] THEN MESON_TAC[]);; + +let REAL_SUMS_INFSUM = prove + (`!f s. (f real_sums (real_infsum s f)) s <=> real_summable s f`, + REWRITE_TAC[real_infsum; real_summable] THEN MESON_TAC[]);; + +let REAL_INFSUM_COMPLEX = prove + (`!f s. real_summable s f ==> real_infsum s f = Re(infsum s (Cx o f))`, + REPEAT GEN_TAC THEN + REWRITE_TAC[GSYM REAL_SUMS_INFSUM; REAL_SUMS_COMPLEX] THEN + DISCH_THEN(MP_TAC o MATCH_MP INFSUM_UNIQUE) THEN + MESON_TAC[RE_CX]);; + +let REAL_SERIES_FROM = prove + (`!f l k. (f real_sums l) (from k) = ((\n. sum(k..n) f) ---> l) sequentially`, + REPEAT GEN_TAC THEN REWRITE_TAC[real_sums] THEN + AP_THM_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN ABS_TAC THEN + AP_THM_TAC THEN AP_TERM_TAC THEN + REWRITE_TAC[EXTENSION; numseg; from; IN_ELIM_THM; IN_INTER] THEN ARITH_TAC);; + +let REAL_SERIES_UNIQUE = prove + (`!f l l' s. (f real_sums l) s /\ (f real_sums l') s ==> l = l'`, + REWRITE_TAC[real_sums] THEN + MESON_TAC[TRIVIAL_LIMIT_SEQUENTIALLY; REALLIM_UNIQUE]);; + +let REAL_INFSUM_UNIQUE = prove + (`!f l s. (f real_sums l) s ==> real_infsum s f = l`, + MESON_TAC[REAL_SERIES_UNIQUE; REAL_SUMS_INFSUM; real_summable]);; + +let REAL_SERIES_FINITE = prove + (`!f s. FINITE s ==> (f real_sums (sum s f)) s`, + REPEAT GEN_TAC THEN REWRITE_TAC[num_FINITE; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `n:num` THEN REWRITE_TAC[real_sums; REALLIM_SEQUENTIALLY] THEN + DISCH_TAC THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN EXISTS_TAC `n:num` THEN + X_GEN_TAC `m:num` THEN DISCH_TAC THEN + SUBGOAL_THEN `s INTER (0..m) = s` + (fun th -> ASM_REWRITE_TAC[th; REAL_SUB_REFL; REAL_ABS_NUM]) THEN + REWRITE_TAC[EXTENSION; IN_INTER; IN_NUMSEG; LE_0] THEN + ASM_MESON_TAC[LE_TRANS]);; + +let REAL_SUMMABLE_IFF_EVENTUALLY = prove + (`!f g k. (?N. !n. N <= n /\ n IN k ==> f n = g n) + ==> (real_summable k f <=> real_summable k g)`, + REWRITE_TAC[REAL_SUMMABLE] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC SUMMABLE_IFF_EVENTUALLY THEN REWRITE_TAC[o_THM] THEN + ASM_MESON_TAC[]);; + +let REAL_SUMMABLE_EQ_EVENTUALLY = prove + (`!f g k. (?N. !n. N <= n /\ n IN k ==> f n = g n) /\ real_summable k f + ==> real_summable k g`, + MESON_TAC[REAL_SUMMABLE_IFF_EVENTUALLY]);; + +let REAL_SUMMABLE_IFF_COFINITE = prove + (`!f s t. FINITE((s DIFF t) UNION (t DIFF s)) + ==> (real_summable s f <=> real_summable t f)`, + SIMP_TAC[REAL_SUMMABLE] THEN MESON_TAC[SUMMABLE_IFF_COFINITE]);; + +let REAL_SUMMABLE_EQ_COFINITE = prove + (`!f s t. FINITE((s DIFF t) UNION (t DIFF s)) /\ real_summable s f + ==> real_summable t f`, + MESON_TAC[REAL_SUMMABLE_IFF_COFINITE]);; + +let REAL_SUMMABLE_FROM_ELSEWHERE = prove + (`!f m n. real_summable (from m) f ==> real_summable (from n) f`, + REPEAT GEN_TAC THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] REAL_SUMMABLE_EQ_COFINITE) THEN + MATCH_MP_TAC FINITE_SUBSET THEN EXISTS_TAC `0..(m+n)` THEN + SIMP_TAC[FINITE_NUMSEG; SUBSET; IN_NUMSEG; IN_UNION; IN_DIFF; IN_FROM] THEN + ARITH_TAC);; + +let REAL_SERIES_GOESTOZERO = prove + (`!s x. real_summable s x + ==> !e. &0 < e + ==> eventually (\n. n IN s ==> abs(x n) < e) sequentially`, + REPEAT GEN_TAC THEN REWRITE_TAC[REAL_SUMMABLE] THEN + DISCH_THEN(MP_TAC o MATCH_MP SERIES_GOESTOZERO) THEN + REWRITE_TAC[o_THM; NORM_LIFT]);; + +let REAL_SUMMABLE_IMP_TOZERO = prove + (`!f:num->real k. + real_summable k f + ==> ((\n. if n IN k then f(n) else &0) ---> &0) sequentially`, + REPEAT GEN_TAC THEN REWRITE_TAC[REAL_SUMMABLE] THEN + DISCH_THEN(MP_TAC o MATCH_MP SUMMABLE_IMP_TOZERO) THEN + REWRITE_TAC[TENDSTO_REAL] THEN + REWRITE_TAC[o_DEF; GSYM LIFT_NUM; GSYM COND_RAND]);; + +let REAL_SUMMABLE_IMP_BOUNDED = prove + (`!f:num->real k. real_summable k f ==> real_bounded (IMAGE f k)`, + REWRITE_TAC[REAL_BOUNDED; REAL_SUMMABLE; GSYM IMAGE_o; + SUMMABLE_IMP_BOUNDED]);; + +let REAL_SUMMABLE_IMP_REAL_SUMS_BOUNDED = prove + (`!f:num->real k. + real_summable (from k) f ==> real_bounded { sum(k..n) f | n IN (:num) }`, + REWRITE_TAC[real_summable; real_sums; LEFT_IMP_EXISTS_THM] THEN + REPEAT GEN_TAC THEN + DISCH_THEN(MP_TAC o MATCH_MP REAL_CONVERGENT_IMP_BOUNDED) THEN + REWRITE_TAC[FROM_INTER_NUMSEG; SIMPLE_IMAGE]);; + +let REAL_SERIES_0 = prove + (`!s. ((\n. &0) real_sums (&0)) s`, + REWRITE_TAC[real_sums; SUM_0; REALLIM_CONST]);; + +let REAL_SERIES_ADD = prove + (`!x x0 y y0 s. + (x real_sums x0) s /\ (y real_sums y0) s + ==> ((\n. x n + y n) real_sums (x0 + y0)) s`, + SIMP_TAC[real_sums; FINITE_INTER_NUMSEG; SUM_ADD; REALLIM_ADD]);; + +let REAL_SERIES_SUB = prove + (`!x x0 y y0 s. + (x real_sums x0) s /\ (y real_sums y0) s + ==> ((\n. x n - y n) real_sums (x0 - y0)) s`, + SIMP_TAC[real_sums; FINITE_INTER_NUMSEG; SUM_SUB; REALLIM_SUB]);; + +let REAL_SERIES_LMUL = prove + (`!x x0 c s. (x real_sums x0) s ==> ((\n. c * x n) real_sums (c * x0)) s`, + SIMP_TAC[real_sums; FINITE_INTER_NUMSEG; SUM_LMUL; REALLIM_LMUL]);; + +let REAL_SERIES_RMUL = prove + (`!x x0 c s. (x real_sums x0) s ==> ((\n. x n * c) real_sums (x0 * c)) s`, + SIMP_TAC[real_sums; FINITE_INTER_NUMSEG; SUM_RMUL; REALLIM_RMUL]);; + +let REAL_SERIES_NEG = prove + (`!x x0 s. (x real_sums x0) s ==> ((\n. --(x n)) real_sums (--x0)) s`, + SIMP_TAC[real_sums; FINITE_INTER_NUMSEG; SUM_NEG; REALLIM_NEG]);; + +let REAL_SUMS_IFF = prove + (`!f g k. (!x. x IN k ==> f x = g x) + ==> ((f real_sums l) k <=> (g real_sums l) k)`, + REPEAT STRIP_TAC THEN REWRITE_TAC[real_sums] THEN + AP_THM_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN ABS_TAC THEN + MATCH_MP_TAC SUM_EQ THEN ASM_SIMP_TAC[IN_INTER]);; + +let REAL_SUMS_EQ = prove + (`!f g k. (!x. x IN k ==> f x = g x) /\ (f real_sums l) k + ==> (g real_sums l) k`, + MESON_TAC[REAL_SUMS_IFF]);; + +let REAL_SERIES_FINITE_SUPPORT = prove + (`!f s k. + FINITE (s INTER k) /\ (!x. ~(x IN s INTER k) ==> f x = &0) + ==> (f real_sums sum(s INTER k) f) k`, + REWRITE_TAC[real_sums; REALLIM_SEQUENTIALLY] THEN REPEAT STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o ISPEC `\x:num. x` o MATCH_MP UPPER_BOUND_FINITE_SET) THEN + 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 `sum (k INTER (0..n)) (f:num->real) = sum(s INTER k) f` + (fun th -> ASM_REWRITE_TAC[REAL_SUB_REFL; REAL_ABS_NUM; th]) THEN + MATCH_MP_TAC SUM_SUPERSET THEN + ASM_SIMP_TAC[SUBSET; IN_INTER; IN_NUMSEG; LE_0] THEN + ASM_MESON_TAC[IN_INTER; LE_TRANS]);; + +let REAL_SERIES_DIFFS = prove + (`!f k. (f ---> &0) sequentially + ==> ((\n. f(n) - f(n + 1)) real_sums f(k)) (from k)`, + REWRITE_TAC[real_sums; FROM_INTER_NUMSEG; SUM_DIFFS] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC REALLIM_TRANSFORM_EVENTUALLY THEN + EXISTS_TAC `\n. (f:num->real) k - f(n + 1)` THEN CONJ_TAC THENL + [REWRITE_TAC[EVENTUALLY_SEQUENTIALLY] THEN EXISTS_TAC `k:num` THEN + SIMP_TAC[]; + GEN_REWRITE_TAC LAND_CONV [GSYM REAL_SUB_RZERO] THEN + MATCH_MP_TAC REALLIM_SUB THEN REWRITE_TAC[REALLIM_CONST] THEN + MATCH_MP_TAC REAL_SEQ_OFFSET THEN ASM_REWRITE_TAC[]]);; + +let REAL_SERIES_TRIVIAL = prove + (`!f. (f real_sums &0) {}`, + REWRITE_TAC[real_sums; INTER_EMPTY; SUM_CLAUSES; REALLIM_CONST]);; + +let REAL_SERIES_RESTRICT = prove + (`!f k l:real. + ((\n. if n IN k then f(n) else &0) real_sums l) (:num) <=> + (f real_sums l) k`, + REPEAT GEN_TAC THEN REWRITE_TAC[real_sums] THEN + AP_THM_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN + REWRITE_TAC[FUN_EQ_THM; INTER_UNIV] THEN GEN_TAC THEN + MATCH_MP_TAC(MESON[] `sum s f = sum t f /\ sum t f = sum t g + ==> sum s f = sum t g`) THEN + CONJ_TAC THENL + [MATCH_MP_TAC SUM_SUPERSET THEN SET_TAC[]; + MATCH_MP_TAC SUM_EQ THEN SIMP_TAC[IN_INTER]]);; + +let REAL_SERIES_SUM = prove + (`!f l k s. FINITE s /\ s SUBSET k /\ (!x. ~(x IN s) ==> f x = &0) /\ + sum s f = l ==> (f real_sums l) k`, + REPEAT STRIP_TAC THEN EXPAND_TAC "l" THEN + SUBGOAL_THEN `s INTER k = s:num->bool` ASSUME_TAC THENL + [ASM SET_TAC[]; ASM_MESON_TAC [REAL_SERIES_FINITE_SUPPORT]]);; + +let REAL_SUMS_LE2 = prove + (`!f g s y z. + (f real_sums y) s /\ (g real_sums z) s /\ + (!i. i IN s ==> f(i) <= g(i)) + ==> y <= z`, + REPEAT GEN_TAC THEN REWRITE_TAC[real_sums] THEN + ONCE_REWRITE_TAC[CONJ_ASSOC] THEN + DISCH_THEN(CONJUNCTS_THEN2 + (MATCH_MP_TAC o MATCH_MP + (ONCE_REWRITE_RULE[IMP_CONJ] + (ONCE_REWRITE_RULE[CONJ_ASSOC] REALLIM_LE))) + ASSUME_TAC) THEN + ASM_SIMP_TAC[TRIVIAL_LIMIT_SEQUENTIALLY] THEN + ASM_SIMP_TAC[SUM_LE; FINITE_INTER; IN_INTER; FINITE_NUMSEG] THEN + REWRITE_TAC[EVENTUALLY_TRUE]);; + +let REAL_SUMS_REINDEX = prove + (`!k a l n. + ((\x. a(x + k)) real_sums l) (from n) <=> (a real_sums l) (from(n + k))`, + REPEAT GEN_TAC THEN REWRITE_TAC[real_sums; FROM_INTER_NUMSEG] THEN + REPEAT GEN_TAC THEN REWRITE_TAC[GSYM SUM_OFFSET] THEN + REWRITE_TAC[REALLIM_SEQUENTIALLY] THEN + ASM_MESON_TAC[ARITH_RULE `N + k:num <= n ==> n = (n - k) + k /\ N <= n - k`; + ARITH_RULE `N + k:num <= n ==> N <= n + k`]);; + +let REAL_INFSUM = prove + (`!f s. real_summable s f ==> real_infsum s f = drop(infsum s (lift o f))`, + REPEAT GEN_TAC THEN + REWRITE_TAC[GSYM REAL_SUMS_INFSUM; REAL_SUMS] THEN + DISCH_THEN(MP_TAC o MATCH_MP INFSUM_UNIQUE) THEN + MESON_TAC[LIFT_DROP]);; + +let REAL_PARTIAL_SUMS_LE_INFSUM = prove + (`!f s n. + (!i. i IN s ==> &0 <= f i) /\ real_summable s f + ==> sum (s INTER (0..n)) f <= real_infsum s f`, + REPEAT GEN_TAC THEN SIMP_TAC[REAL_INFSUM] THEN + REWRITE_TAC[REAL_SUMMABLE] THEN + GEN_REWRITE_TAC (LAND_CONV o LAND_CONV o BINDER_CONV o RAND_CONV o RAND_CONV) + [GSYM LIFT_DROP] THEN + REWRITE_TAC[o_DEF] THEN DISCH_THEN(MP_TAC o MATCH_MP + PARTIAL_SUMS_DROP_LE_INFSUM) THEN + SIMP_TAC[DROP_VSUM; FINITE_INTER; FINITE_NUMSEG; o_DEF; LIFT_DROP; ETA_AX]);; + +(* ------------------------------------------------------------------------- *) +(* Similar combining theorems just for summability. *) +(* ------------------------------------------------------------------------- *) + +let REAL_SUMMABLE_0 = prove + (`!s. real_summable s (\n. &0)`, + REWRITE_TAC[real_summable] THEN MESON_TAC[REAL_SERIES_0]);; + +let REAL_SUMMABLE_ADD = prove + (`!x y s. real_summable s x /\ real_summable s y + ==> real_summable s (\n. x n + y n)`, + REWRITE_TAC[real_summable] THEN MESON_TAC[REAL_SERIES_ADD]);; + +let REAL_SUMMABLE_SUB = prove + (`!x y s. real_summable s x /\ real_summable s y + ==> real_summable s (\n. x n - y n)`, + REWRITE_TAC[real_summable] THEN MESON_TAC[REAL_SERIES_SUB]);; + +let REAL_SUMMABLE_LMUL = prove + (`!s x c. real_summable s x ==> real_summable s (\n. c * x n)`, + REWRITE_TAC[real_summable] THEN MESON_TAC[REAL_SERIES_LMUL]);; + +let REAL_SUMMABLE_RMUL = prove + (`!s x c. real_summable s x ==> real_summable s (\n. x n * c)`, + REWRITE_TAC[real_summable] THEN MESON_TAC[REAL_SERIES_RMUL]);; + +let REAL_SUMMABLE_NEG = prove + (`!x s. real_summable s x ==> real_summable s (\n. --(x n))`, + REWRITE_TAC[real_summable] THEN MESON_TAC[REAL_SERIES_NEG]);; + +let REAL_SUMMABLE_IFF = prove + (`!f g k. (!x. x IN k ==> f x = g x) + ==> (real_summable k f <=> real_summable k g)`, + REWRITE_TAC[real_summable] THEN MESON_TAC[REAL_SUMS_IFF]);; + +let REAL_SUMMABLE_EQ = prove + (`!f g k. (!x. x IN k ==> f x = g x) /\ real_summable k f + ==> real_summable k g`, + REWRITE_TAC[real_summable] THEN MESON_TAC[REAL_SUMS_EQ]);; + +let REAL_SERIES_SUBSET = prove + (`!x s t l. + s SUBSET t /\ + ((\i. if i IN s then x i else &0) real_sums l) t + ==> (x real_sums l) s`, + REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + REWRITE_TAC[real_sums] THEN MATCH_MP_TAC EQ_IMP THEN + AP_THM_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN ABS_TAC THEN + ASM_SIMP_TAC[GSYM SUM_RESTRICT_SET; FINITE_INTER_NUMSEG] THEN + AP_THM_TAC THEN AP_TERM_TAC THEN POP_ASSUM MP_TAC THEN SET_TAC[]);; + +let REAL_SUMMABLE_SUBSET = prove + (`!x s t. + s SUBSET t /\ + real_summable t (\i. if i IN s then x i else &0) + ==> real_summable s x`, + REWRITE_TAC[real_summable] THEN MESON_TAC[REAL_SERIES_SUBSET]);; + +let REAL_SUMMABLE_TRIVIAL = prove + (`!f. real_summable {} f`, + GEN_TAC THEN REWRITE_TAC[real_summable] THEN EXISTS_TAC `&0` THEN + REWRITE_TAC[REAL_SERIES_TRIVIAL]);; + +let REAL_SUMMABLE_RESTRICT = prove + (`!f k. + real_summable (:num) (\n. if n IN k then f(n) else &0) <=> + real_summable k f`, + REWRITE_TAC[real_summable; REAL_SERIES_RESTRICT]);; + +let REAL_SUMS_FINITE_DIFF = prove + (`!f t s l. + t SUBSET s /\ FINITE t /\ (f real_sums l) s + ==> (f real_sums (l - sum t f)) (s DIFF t)`, + REPEAT GEN_TAC THEN + REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + FIRST_ASSUM(MP_TAC o ISPEC `f:num->real` o MATCH_MP REAL_SERIES_FINITE) THEN + ONCE_REWRITE_TAC[GSYM REAL_SERIES_RESTRICT] THEN + REWRITE_TAC[IMP_IMP] THEN ONCE_REWRITE_TAC[CONJ_SYM] THEN + DISCH_THEN(MP_TAC o MATCH_MP REAL_SERIES_SUB) THEN + MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN + REWRITE_TAC[FUN_EQ_THM] THEN X_GEN_TAC `x:num` THEN REWRITE_TAC[IN_DIFF] THEN + FIRST_ASSUM(MP_TAC o SPEC `x:num` o GEN_REWRITE_RULE I [SUBSET]) THEN + MAP_EVERY ASM_CASES_TAC [`(x:num) IN s`; `(x:num) IN t`] THEN + ASM_REWRITE_TAC[] THEN REAL_ARITH_TAC);; + +let REAL_SUMS_FINITE_UNION = prove + (`!f s t l. + FINITE t /\ (f real_sums l) s + ==> (f real_sums (l + sum (t DIFF s) f)) (s UNION t)`, + REPEAT GEN_TAC THEN + REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + FIRST_ASSUM(MP_TAC o SPEC `s:num->bool` o MATCH_MP FINITE_DIFF) THEN + DISCH_THEN(MP_TAC o ISPEC `f:num->real` o MATCH_MP REAL_SERIES_FINITE) THEN + ONCE_REWRITE_TAC[GSYM REAL_SERIES_RESTRICT] THEN + REWRITE_TAC[IMP_IMP] THEN ONCE_REWRITE_TAC[CONJ_SYM] THEN + DISCH_THEN(MP_TAC o MATCH_MP REAL_SERIES_ADD) THEN + MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN + REWRITE_TAC[FUN_EQ_THM] THEN X_GEN_TAC `x:num` THEN + REWRITE_TAC[IN_DIFF; IN_UNION] THEN + MAP_EVERY ASM_CASES_TAC [`(x:num) IN s`; `(x:num) IN t`] THEN + ASM_REWRITE_TAC[] THEN REAL_ARITH_TAC);; + +let REAL_SUMS_OFFSET = prove + (`!f l m n. + (f real_sums l) (from m) /\ m < n + ==> (f real_sums (l - sum(m..(n-1)) f)) (from n)`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN `from n = from m DIFF (m..(n-1))` SUBST1_TAC THENL + [REWRITE_TAC[EXTENSION; IN_FROM; IN_DIFF; IN_NUMSEG] THEN ASM_ARITH_TAC; + MATCH_MP_TAC REAL_SUMS_FINITE_DIFF THEN ASM_REWRITE_TAC[FINITE_NUMSEG] THEN + SIMP_TAC[SUBSET; IN_FROM; IN_NUMSEG]]);; + +let REAL_SUMS_OFFSET_REV = prove + (`!f l m n. + (f real_sums l) (from m) /\ n < m + ==> (f real_sums (l + sum(n..m-1) f)) (from n)`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`f:num->real`; `from m`; `n..m-1`; `l:real`] + REAL_SUMS_FINITE_UNION) THEN + ASM_REWRITE_TAC[FINITE_NUMSEG] THEN MATCH_MP_TAC EQ_IMP THEN + BINOP_TAC THENL [AP_TERM_TAC THEN AP_THM_TAC THEN AP_TERM_TAC; ALL_TAC] THEN + REWRITE_TAC[EXTENSION; IN_DIFF; IN_UNION; IN_FROM; IN_NUMSEG] THEN + ASM_ARITH_TAC);; + +(* ------------------------------------------------------------------------- *) +(* Similar combining theorems for infsum. *) +(* ------------------------------------------------------------------------- *) + +let REAL_INFSUM_0 = prove + (`real_infsum s (\i. &0) = &0`, + MATCH_MP_TAC REAL_INFSUM_UNIQUE THEN REWRITE_TAC[REAL_SERIES_0]);; + +let REAL_INFSUM_ADD = prove + (`!x y s. real_summable s x /\ real_summable s y + ==> real_infsum s (\i. x i + y i) = + real_infsum s x + real_infsum s y`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_INFSUM_UNIQUE THEN + MATCH_MP_TAC REAL_SERIES_ADD THEN ASM_REWRITE_TAC[REAL_SUMS_INFSUM]);; + +let REAL_INFSUM_SUB = prove + (`!x y s. real_summable s x /\ real_summable s y + ==> real_infsum s (\i. x i - y i) = + real_infsum s x - real_infsum s y`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_INFSUM_UNIQUE THEN + MATCH_MP_TAC REAL_SERIES_SUB THEN ASM_REWRITE_TAC[REAL_SUMS_INFSUM]);; + +let REAL_INFSUM_LMUL = prove + (`!s x c. real_summable s x + ==> real_infsum s (\n. c * x n) = c * real_infsum s x`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_INFSUM_UNIQUE THEN + MATCH_MP_TAC REAL_SERIES_LMUL THEN ASM_REWRITE_TAC[REAL_SUMS_INFSUM]);; + +let REAL_INFSUM_RMUL = prove + (`!s x c. real_summable s x + ==> real_infsum s (\n. x n * c) = real_infsum s x * c`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_INFSUM_UNIQUE THEN + MATCH_MP_TAC REAL_SERIES_RMUL THEN ASM_REWRITE_TAC[REAL_SUMS_INFSUM]);; + +let REAL_INFSUM_NEG = prove + (`!s x. real_summable s x + ==> real_infsum s (\n. --(x n)) = --(real_infsum s x)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_INFSUM_UNIQUE THEN + MATCH_MP_TAC REAL_SERIES_NEG THEN ASM_REWRITE_TAC[REAL_SUMS_INFSUM]);; + +let REAL_INFSUM_EQ = prove + (`!f g k. real_summable k f /\ real_summable k g /\ + (!x. x IN k ==> f x = g x) + ==> real_infsum k f = real_infsum k g`, + REPEAT STRIP_TAC THEN REWRITE_TAC[real_infsum] THEN AP_TERM_TAC THEN + ABS_TAC THEN ASM_MESON_TAC[REAL_SUMS_EQ; REAL_SUMS_INFSUM]);; + +let REAL_INFSUM_RESTRICT = prove + (`!k a. real_infsum (:num) (\n. if n IN k then a n else &0) = + real_infsum k a`, + REPEAT GEN_TAC THEN + MP_TAC(ISPECL [`a:num->real`; `k:num->bool`] REAL_SUMMABLE_RESTRICT) THEN + ASM_CASES_TAC `real_summable k a` THEN ASM_REWRITE_TAC[] THEN + STRIP_TAC THENL + [MATCH_MP_TAC REAL_INFSUM_UNIQUE THEN + ASM_REWRITE_TAC[REAL_SERIES_RESTRICT; REAL_SUMS_INFSUM]; + RULE_ASSUM_TAC(REWRITE_RULE[real_summable; NOT_EXISTS_THM]) THEN + ASM_REWRITE_TAC[real_infsum]]);; + +(* ------------------------------------------------------------------------- *) +(* Convergence tests for real series. *) +(* ------------------------------------------------------------------------- *) + +let REAL_SERIES_CAUCHY_UNIFORM = prove + (`!P:A->bool f k. + (?l. !e. &0 < e + ==> ?N. !n x. N <= n /\ P x + ==> abs(sum(k INTER (0..n)) (f x) - + l x) < e) <=> + (!e. &0 < e ==> ?N. !m n x. N <= m /\ P x + ==> abs(sum(k INTER (m..n)) (f x)) < e)`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`P:A->bool`; `\x:A n:num. lift(f x n)`; `k:num->bool`] + SERIES_CAUCHY_UNIFORM) THEN + SIMP_TAC[VSUM_REAL; FINITE_INTER; FINITE_NUMSEG] THEN + REWRITE_TAC[NORM_LIFT; o_DEF; LIFT_DROP; ETA_AX] THEN + DISCH_THEN(SUBST1_TAC o SYM) THEN EQ_TAC THENL + [DISCH_THEN(X_CHOOSE_TAC `l:A->real`) THEN + EXISTS_TAC `lift o (l:A->real)` THEN + ASM_SIMP_TAC[o_THM; DIST_LIFT]; + DISCH_THEN(X_CHOOSE_TAC `l:A->real^1`) THEN + EXISTS_TAC `drop o (l:A->real^1)` THEN + ASM_SIMP_TAC[SUM_VSUM; FINITE_INTER; FINITE_NUMSEG] THEN + REWRITE_TAC[o_THM; GSYM DROP_SUB; GSYM ABS_DROP] THEN + SIMP_TAC[GSYM dist; VSUM_REAL; FINITE_INTER; FINITE_NUMSEG] THEN + ASM_REWRITE_TAC[o_DEF; LIFT_DROP; ETA_AX]]);; + +let REAL_SERIES_COMPARISON = prove + (`!f g s. (?l. (g real_sums l) s) /\ + (?N. !n. n >= N /\ n IN s ==> abs(f n) <= g n) + ==> ?l. (f real_sums l) s`, + REWRITE_TAC[REAL_SUMS; GSYM EXISTS_LIFT] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC SERIES_COMPARISON THEN + EXISTS_TAC `g:num->real` THEN + REWRITE_TAC[NORM_LIFT; o_THM] THEN ASM_MESON_TAC[]);; + +let REAL_SUMMABLE_COMPARISON = prove + (`!f g s. real_summable s g /\ + (?N. !n. n >= N /\ n IN s ==> abs(f n) <= g n) + ==> real_summable s f`, + REWRITE_TAC[real_summable; REAL_SERIES_COMPARISON]);; + +let REAL_SERIES_COMPARISON_UNIFORM = prove + (`!f g P s. (?l. (g real_sums l) s) /\ + (?N. !n x. N <= n /\ n IN s /\ P x ==> abs(f x n) <= g n) + ==> ?l:A->real. + !e. &0 < e + ==> ?N. !n x. N <= n /\ P x + ==> abs(sum(s INTER (0..n)) (f x) - + l x) < e`, + REPEAT GEN_TAC THEN + SIMP_TAC[GE; REAL_SERIES_CAUCHY; REAL_SERIES_CAUCHY_UNIFORM] THEN + DISCH_THEN(CONJUNCTS_THEN2 MP_TAC (X_CHOOSE_TAC `N1:num`)) THEN + MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `e:real` THEN + MATCH_MP_TAC MONO_IMP THEN REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_TAC `N2:num`) THEN + EXISTS_TAC `N1 + N2:num` THEN + MAP_EVERY X_GEN_TAC [`m:num`; `n:num`; `x:A`] THEN DISCH_TAC THEN + MATCH_MP_TAC REAL_LET_TRANS THEN + EXISTS_TAC `abs (sum (s INTER (m .. n)) g)` THEN CONJ_TAC THENL + [SIMP_TAC[GSYM LIFT_SUM; FINITE_INTER_NUMSEG; NORM_LIFT] THEN + MATCH_MP_TAC(REAL_ARITH `x <= a ==> x <= abs(a)`) THEN + MATCH_MP_TAC SUM_ABS_LE THEN + REWRITE_TAC[FINITE_INTER_NUMSEG; IN_INTER; IN_NUMSEG] THEN + ASM_MESON_TAC[ARITH_RULE `N1 + N2:num <= m /\ m <= x ==> N1 <= x`]; + ASM_MESON_TAC[ARITH_RULE `N1 + N2:num <= m ==> N2 <= m`]]);; + +let REAL_SERIES_RATIO = prove + (`!c a s N. + c < &1 /\ + (!n. n >= N ==> abs(a(SUC n)) <= c * abs(a(n))) + ==> ?l:real. (a real_sums l) s`, + REWRITE_TAC[REAL_SUMS; GSYM EXISTS_LIFT] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC SERIES_RATIO THEN + REWRITE_TAC[o_THM; NORM_LIFT] THEN ASM_MESON_TAC[]);; + +let BOUNDED_PARTIAL_REAL_SUMS = prove + (`!f:num->real k. + real_bounded { sum(k..n) f | n IN (:num) } + ==> real_bounded { sum(m..n) f | m IN (:num) /\ n IN (:num) }`, + REWRITE_TAC[REAL_BOUNDED] THEN + REWRITE_TAC[SET_RULE `IMAGE f {g x | P x} = {f(g x) | P x}`; + SET_RULE `IMAGE f {g x y | P x /\ Q y} = {f(g x y) | P x /\ Q y}`] THEN + SIMP_TAC[LIFT_SUM; FINITE_INTER; FINITE_NUMSEG] THEN + REWRITE_TAC[BOUNDED_PARTIAL_SUMS]);; + +let REAL_SERIES_DIRICHLET = prove + (`!f:num->real g N k m. + real_bounded { sum (m..n) f | n IN (:num)} /\ + (!n. N <= n ==> g(n + 1) <= g(n)) /\ + (g ---> &0) sequentially + ==> real_summable (from k) (\n. g(n) * f(n))`, + REWRITE_TAC[REAL_SUMMABLE; REAL_BOUNDED; TENDSTO_REAL] THEN + REWRITE_TAC[LIFT_NUM; LIFT_CMUL; o_DEF] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC SERIES_DIRICHLET THEN + MAP_EVERY EXISTS_TAC [`N:num`; `m:num`] THEN + ASM_REWRITE_TAC[o_DEF] THEN + SIMP_TAC[VSUM_REAL; FINITE_INTER; FINITE_NUMSEG] THEN + ASM_REWRITE_TAC[o_DEF; LIFT_DROP; ETA_AX] THEN + ASM_REWRITE_TAC[SET_RULE `{lift(f x) | P x} = IMAGE lift {f x | P x}`]);; + +let REAL_SERIES_ABSCONV_IMP_CONV = prove + (`!x:num->real k. real_summable k (\n. abs(x n)) ==> real_summable k x`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_SUMMABLE_COMPARISON THEN + EXISTS_TAC `\n:num. abs(x n)` THEN ASM_REWRITE_TAC[REAL_LE_REFL]);; + +let REAL_SUMS_GP = prove + (`!n x. abs(x) < &1 + ==> ((\k. x pow k) real_sums (x pow n / (&1 - x))) (from n)`, + REPEAT STRIP_TAC THEN MP_TAC(SPECL [`n:num`; `Cx x`] SUMS_GP) THEN + ASM_REWRITE_TAC[REAL_SUMS_COMPLEX; GSYM CX_SUB; GSYM CX_POW; GSYM CX_DIV; + o_DEF; COMPLEX_NORM_CX]);; + +let REAL_SUMMABLE_GP = prove + (`!x k. abs(x) < &1 ==> real_summable k (\n. x pow n)`, + REPEAT STRIP_TAC THEN MP_TAC(SPECL [`Cx x`; `k:num->bool`] SUMMABLE_GP) THEN + ASM_REWRITE_TAC[REAL_SUMMABLE_COMPLEX] THEN + ASM_REWRITE_TAC[COMPLEX_NORM_CX; o_DEF; CX_POW]);; + +let REAL_ABEL_LEMMA = prove + (`!a M r r0. + &0 <= r /\ r < r0 /\ + (!n. n IN k ==> abs(a n) * r0 pow n <= M) + ==> real_summable k (\n. abs(a(n)) * r pow n)`, + REWRITE_TAC[REAL_SUMMABLE_COMPLEX] THEN + REWRITE_TAC[o_DEF; CX_MUL; CX_ABS] THEN REWRITE_TAC[GSYM CX_MUL] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC ABEL_LEMMA THEN + REWRITE_TAC[COMPLEX_NORM_CX] THEN ASM_MESON_TAC[]);; + +let REAL_POWER_SERIES_CONV_IMP_ABSCONV = prove + (`!a k w z. + real_summable k (\n. a(n) * z pow n) /\ abs(w) < abs(z) + ==> real_summable k (\n. abs(a(n) * w pow n))`, + REWRITE_TAC[REAL_SUMMABLE_COMPLEX; o_DEF; CX_MUL; CX_ABS; CX_POW] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC POWER_SERIES_CONV_IMP_ABSCONV THEN + EXISTS_TAC `Cx z` THEN ASM_REWRITE_TAC[COMPLEX_NORM_CX]);; + +let POWER_REAL_SERIES_CONV_IMP_ABSCONV_WEAK = prove + (`!a k w z. + real_summable k (\n. a(n) * z pow n) /\ abs(w) < abs(z) + ==> real_summable k (\n. abs(a n) * w pow n)`, + REWRITE_TAC[REAL_SUMMABLE_COMPLEX; o_DEF; CX_MUL; CX_ABS; CX_POW] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC POWER_SERIES_CONV_IMP_ABSCONV_WEAK THEN + EXISTS_TAC `Cx z` THEN ASM_REWRITE_TAC[COMPLEX_NORM_CX]);; + +(* ------------------------------------------------------------------------- *) +(* Some real limits involving transcendentals. *) +(* ------------------------------------------------------------------------- *) + +let REALLIM_1_OVER_N = prove + (`((\n. inv(&n)) ---> &0) sequentially`, + REWRITE_TAC[REALLIM_COMPLEX; o_DEF; CX_INV; LIM_INV_N]);; + +let REALLIM_LOG_OVER_N = prove + (`((\n. log(&n) / &n) ---> &0) sequentially`, + REWRITE_TAC[REALLIM_COMPLEX] THEN MP_TAC LIM_LOG_OVER_N THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] LIM_TRANSFORM_EVENTUALLY) THEN + REWRITE_TAC[EVENTUALLY_SEQUENTIALLY] THEN EXISTS_TAC `1` THEN + SIMP_TAC[o_DEF; CX_DIV; CX_LOG; REAL_OF_NUM_LT; + ARITH_RULE `1 <= n ==> 0 < n`]);; + +let REALLIM_1_OVER_LOG = prove + (`((\n. inv(log(&n))) ---> &0) sequentially`, + REWRITE_TAC[REALLIM_COMPLEX] THEN MP_TAC LIM_1_OVER_LOG THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] LIM_TRANSFORM_EVENTUALLY) THEN + REWRITE_TAC[o_DEF; complex_div; COMPLEX_MUL_LID; CX_INV] THEN + REWRITE_TAC[EVENTUALLY_SEQUENTIALLY] THEN EXISTS_TAC `1` THEN + SIMP_TAC[CX_LOG; REAL_OF_NUM_LT; ARITH_RULE `1 <= n ==> 0 < n`]);; + +let REALLIM_POWN = prove + (`!z. abs(z) < &1 ==> ((\n. z pow n) ---> &0) sequentially`, + REWRITE_TAC[REALLIM_COMPLEX; o_DEF; CX_POW] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC LIM_POWN THEN + ASM_REWRITE_TAC[COMPLEX_NORM_CX]);; + +(* ------------------------------------------------------------------------- *) +(* Nets for real limit. *) +(* ------------------------------------------------------------------------- *) + +let atreal = new_definition + `atreal a = mk_net(\x y. &0 < abs(x - a) /\ abs(x - a) <= abs(y - a))`;; + +let at_posinfinity = new_definition + `at_posinfinity = mk_net(\x y:real. x >= y)`;; + +let at_neginfinity = new_definition + `at_neginfinity = mk_net(\x y:real. x <= y)`;; + +let ATREAL = prove + (`!a x y. + netord(atreal a) x y <=> &0 < abs(x - a) /\ abs(x - a) <= abs(y - a)`, + GEN_TAC THEN NET_PROVE_TAC[atreal] THEN + MESON_TAC[REAL_LE_TOTAL; REAL_LE_REFL; REAL_LE_TRANS; REAL_LET_TRANS]);; + +let AT_POSINFINITY = prove + (`!x y. netord at_posinfinity x y <=> x >= y`, + NET_PROVE_TAC[at_posinfinity] THEN + REWRITE_TAC[real_ge; REAL_LE_REFL] THEN + MESON_TAC[REAL_LE_TOTAL; REAL_LE_REFL; REAL_LE_TRANS]);; + +let AT_NEGINFINITY = prove + (`!x y. netord at_neginfinity x y <=> x <= y`, + NET_PROVE_TAC[at_neginfinity] THEN + REWRITE_TAC[real_ge; REAL_LE_REFL] THEN + MESON_TAC[REAL_LE_TOTAL; REAL_LE_REFL; REAL_LE_TRANS]);; + +let WITHINREAL_UNIV = prove + (`!x. atreal x within (:real) = atreal x`, + REWRITE_TAC[within; atreal; IN_UNIV] THEN REWRITE_TAC[ETA_AX; net_tybij]);; + +let TRIVIAL_LIMIT_ATREAL = prove + (`!a. ~(trivial_limit (atreal a))`, + X_GEN_TAC `a:real` THEN SIMP_TAC[trivial_limit; ATREAL; DE_MORGAN_THM] THEN + CONJ_TAC THENL + [DISCH_THEN(MP_TAC o SPECL [`&0`; `&1`]) THEN REAL_ARITH_TAC; ALL_TAC] THEN + REWRITE_TAC[NOT_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`b:real`; `c:real`] THEN + ASM_CASES_TAC `b:real = c` THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[GSYM DE_MORGAN_THM; GSYM NOT_EXISTS_THM] THEN + SUBGOAL_THEN `~(b:real = a) \/ ~(c = a)` DISJ_CASES_TAC THENL + [ASM_MESON_TAC[]; + EXISTS_TAC `(a + b) / &2` THEN ASM_REAL_ARITH_TAC; + EXISTS_TAC `(a + c) / &2` THEN ASM_REAL_ARITH_TAC]);; + +let TRIVIAL_LIMIT_AT_POSINFINITY = prove + (`~(trivial_limit at_posinfinity)`, + REWRITE_TAC[trivial_limit; AT_POSINFINITY; DE_MORGAN_THM] THEN + CONJ_TAC THENL + [DISCH_THEN(MP_TAC o SPECL [`&0`; `&1`]) THEN REAL_ARITH_TAC; ALL_TAC] THEN + REWRITE_TAC[DE_MORGAN_THM; NOT_EXISTS_THM; real_ge; REAL_NOT_LE] THEN + MESON_TAC[REAL_LT_TOTAL; REAL_LT_ANTISYM]);; + +let TRIVIAL_LIMIT_AT_NEGINFINITY = prove + (`~(trivial_limit at_neginfinity)`, + REWRITE_TAC[trivial_limit; AT_NEGINFINITY; DE_MORGAN_THM] THEN + CONJ_TAC THENL + [DISCH_THEN(MP_TAC o SPECL [`&0`; `&1`]) THEN REAL_ARITH_TAC; ALL_TAC] THEN + REWRITE_TAC[DE_MORGAN_THM; NOT_EXISTS_THM; real_ge; REAL_NOT_LE] THEN + MESON_TAC[REAL_LT_TOTAL; REAL_LT_ANTISYM]);; + +let NETLIMIT_WITHINREAL = prove + (`!a s. ~(trivial_limit (atreal a within s)) + ==> (netlimit (atreal a within s) = a)`, + REWRITE_TAC[trivial_limit; netlimit; ATREAL; WITHIN; DE_MORGAN_THM] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC SELECT_UNIQUE THEN REWRITE_TAC[] THEN + SUBGOAL_THEN + `!x. ~(&0 < abs(x - a) /\ abs(x - a) <= abs(a - a) /\ x IN s)` + ASSUME_TAC THENL [REAL_ARITH_TAC; ASM_MESON_TAC[]]);; + +let NETLIMIT_ATREAL = prove + (`!a. netlimit(atreal a) = a`, + GEN_TAC THEN ONCE_REWRITE_TAC[GSYM WITHINREAL_UNIV] THEN + MATCH_MP_TAC NETLIMIT_WITHINREAL THEN + SIMP_TAC[TRIVIAL_LIMIT_ATREAL; WITHINREAL_UNIV]);; + +let EVENTUALLY_WITHINREAL_LE = prove + (`!s a p. + eventually p (atreal a within s) <=> + ?d. &0 < d /\ + !x. x IN s /\ &0 < abs(x - a) /\ abs(x - a) <= d ==> p(x)`, + REWRITE_TAC[eventually; ATREAL; WITHIN; trivial_limit] THEN + REWRITE_TAC[MESON[REAL_LT_01; REAL_LT_REFL] `~(!a b:real. a = b)`] THEN + REPEAT GEN_TAC THEN EQ_TAC THENL + [DISCH_THEN(DISJ_CASES_THEN(X_CHOOSE_THEN `b:real` MP_TAC)) THENL + [DISCH_THEN(X_CHOOSE_THEN `c:real` STRIP_ASSUME_TAC) THEN + FIRST_X_ASSUM(DISJ_CASES_TAC o MATCH_MP (REAL_ARITH + `~(b = c) ==> &0 < abs(b - a) \/ &0 < abs(c - a)`)) THEN + ASM_MESON_TAC[]; + MESON_TAC[REAL_LTE_TRANS]]; + DISCH_THEN(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC) THEN + ASM_CASES_TAC `?x. x IN s /\ &0 < abs(x - a) /\ abs(x - a) <= d` THENL + [DISJ2_TAC THEN FIRST_X_ASSUM(X_CHOOSE_TAC `b:real`) THEN + EXISTS_TAC `b:real` THEN ASM_MESON_TAC[REAL_LE_TRANS; REAL_LE_REFL]; + DISJ1_TAC THEN MAP_EVERY EXISTS_TAC [`a + d:real`; `a:real`] THEN + ASM_SIMP_TAC[REAL_ADD_SUB; REAL_EQ_ADD_LCANCEL_0; REAL_LT_IMP_NZ] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [NOT_EXISTS_THM]) THEN + MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `x:real` THEN + ASM_CASES_TAC `(x:real) IN s` THEN ASM_REWRITE_TAC[] THEN + ASM_REAL_ARITH_TAC]]);; + +let EVENTUALLY_WITHINREAL = prove + (`!s a p. + eventually p (atreal a within s) <=> + ?d. &0 < d /\ !x. x IN s /\ &0 < abs(x - a) /\ abs(x - a) < d ==> p(x)`, + REWRITE_TAC[EVENTUALLY_WITHINREAL_LE] THEN + ONCE_REWRITE_TAC[TAUT `a /\ b /\ c ==> d <=> c ==> a /\ b ==> d`] THEN + REWRITE_TAC[APPROACHABLE_LT_LE]);; + +let EVENTUALLY_ATREAL = prove + (`!a p. eventually p (atreal a) <=> + ?d. &0 < d /\ !x. &0 < abs(x - a) /\ abs(x - a) < d ==> p(x)`, + ONCE_REWRITE_TAC[GSYM WITHINREAL_UNIV] THEN + REWRITE_TAC[EVENTUALLY_WITHINREAL; IN_UNIV]);; + +let EVENTUALLY_AT_POSINFINITY = prove + (`!p. eventually p at_posinfinity <=> ?b. !x. x >= b ==> p x`, + REWRITE_TAC[eventually; TRIVIAL_LIMIT_AT_POSINFINITY; AT_POSINFINITY] THEN + MESON_TAC[REAL_ARITH `x >= x`]);; + +let EVENTUALLY_AT_NEGINFINITY = prove + (`!p. eventually p at_neginfinity <=> ?b. !x. x <= b ==> p x`, + REWRITE_TAC[eventually; TRIVIAL_LIMIT_AT_NEGINFINITY; AT_NEGINFINITY] THEN + MESON_TAC[REAL_LE_REFL]);; + +(* ------------------------------------------------------------------------- *) +(* Usual limit results with real domain and either vector or real range. *) +(* ------------------------------------------------------------------------- *) + +let LIM_WITHINREAL_LE = prove + (`!f:real->real^N l a s. + (f --> l) (atreal a within s) <=> + !e. &0 < e ==> ?d. &0 < d /\ + !x. x IN s /\ &0 < abs(x - a) /\ abs(x - a) <= d + ==> dist(f(x),l) < e`, + REWRITE_TAC[tendsto; EVENTUALLY_WITHINREAL_LE]);; + +let LIM_WITHINREAL = prove + (`!f:real->real^N l a s. + (f --> l) (atreal a within s) <=> + !e. &0 < e + ==> ?d. &0 < d /\ + !x. x IN s /\ &0 < abs(x - a) /\ abs(x - a) < d + ==> dist(f(x),l) < e`, + REWRITE_TAC[tendsto; EVENTUALLY_WITHINREAL] THEN MESON_TAC[]);; + +let LIM_ATREAL = prove + (`!f l:real^N a. + (f --> l) (atreal a) <=> + !e. &0 < e + ==> ?d. &0 < d /\ !x. &0 < abs(x - a) /\ abs(x - a) < d + ==> dist(f(x),l) < e`, + REWRITE_TAC[tendsto; EVENTUALLY_ATREAL] THEN MESON_TAC[]);; + +let LIM_AT_POSINFINITY = prove + (`!f l. (f --> l) at_posinfinity <=> + !e. &0 < e ==> ?b. !x. x >= b ==> dist(f(x),l) < e`, + REWRITE_TAC[tendsto; EVENTUALLY_AT_POSINFINITY] THEN MESON_TAC[]);; + +let LIM_AT_NEGINFINITY = prove + (`!f l. (f --> l) at_neginfinity <=> + !e. &0 < e ==> ?b. !x. x <= b ==> dist(f(x),l) < e`, + REWRITE_TAC[tendsto; EVENTUALLY_AT_NEGINFINITY] THEN MESON_TAC[]);; + +let REALLIM_WITHINREAL_LE = prove + (`!f l a s. + (f ---> l) (atreal a within s) <=> + !e. &0 < e ==> ?d. &0 < d /\ + !x. x IN s /\ &0 < abs(x - a) /\ abs(x - a) <= d + ==> abs(f(x) - l) < e`, + REWRITE_TAC[tendsto_real; EVENTUALLY_WITHINREAL_LE]);; + +let REALLIM_WITHINREAL = prove + (`!f l a s. + (f ---> l) (atreal a within s) <=> + !e. &0 < e + ==> ?d. &0 < d /\ + !x. x IN s /\ &0 < abs(x - a) /\ abs(x - a) < d + ==> abs(f(x) - l) < e`, + REWRITE_TAC[tendsto_real; EVENTUALLY_WITHINREAL] THEN MESON_TAC[]);; + +let REALLIM_ATREAL = prove + (`!f l a. + (f ---> l) (atreal a) <=> + !e. &0 < e + ==> ?d. &0 < d /\ !x. &0 < abs(x - a) /\ abs(x - a) < d + ==> abs(f(x) - l) < e`, + REWRITE_TAC[tendsto_real; EVENTUALLY_ATREAL] THEN MESON_TAC[]);; + +let REALLIM_AT_POSINFINITY = prove + (`!f l. (f ---> l) at_posinfinity <=> + !e. &0 < e ==> ?b. !x. x >= b ==> abs(f(x) - l) < e`, + REWRITE_TAC[tendsto_real; EVENTUALLY_AT_POSINFINITY] THEN MESON_TAC[]);; + +let REALLIM_AT_NEGINFINITY = prove + (`!f l. (f ---> l) at_neginfinity <=> + !e. &0 < e ==> ?b. !x. x <= b ==> abs(f(x) - l) < e`, + REWRITE_TAC[tendsto_real; EVENTUALLY_AT_NEGINFINITY] THEN MESON_TAC[]);; + +let LIM_ATREAL_WITHINREAL = prove + (`!f l a s. (f --> l) (atreal a) ==> (f --> l) (atreal a within s)`, + REWRITE_TAC[LIM_ATREAL; LIM_WITHINREAL] THEN MESON_TAC[]);; + +let REALLIM_ATREAL_WITHINREAL = prove + (`!f l a s. (f ---> l) (atreal a) ==> (f ---> l) (atreal a within s)`, + REWRITE_TAC[REALLIM_ATREAL; REALLIM_WITHINREAL] THEN MESON_TAC[]);; + +let REALLIM_WITHIN_SUBSET = prove + (`!f l a s t. (f ---> l) (at a within s) /\ t SUBSET s + ==> (f ---> l) (at a within t)`, + REWRITE_TAC[REALLIM_WITHIN; SUBSET] THEN MESON_TAC[]);; + +let REALLIM_WITHINREAL_SUBSET = prove + (`!f l a s t. (f ---> l) (atreal a within s) /\ t SUBSET s + ==> (f ---> l) (atreal a within t)`, + REWRITE_TAC[REALLIM_WITHINREAL; SUBSET] THEN MESON_TAC[]);; + +let LIM_WITHINREAL_SUBSET = prove + (`!f l a s t. (f --> l) (atreal a within s) /\ t SUBSET s + ==> (f --> l) (atreal a within t)`, + REWRITE_TAC[LIM_WITHINREAL; SUBSET] THEN MESON_TAC[]);; + +let REALLIM_ATREAL_ID = prove + (`((\x. x) ---> a) (atreal a)`, + REWRITE_TAC[REALLIM_ATREAL] THEN MESON_TAC[]);; + +let REALLIM_WITHINREAL_ID = prove + (`!a. ((\x. x) ---> a) (atreal a within s)`, + REWRITE_TAC[REALLIM_WITHINREAL] THEN MESON_TAC[]);; + +let LIM_TRANSFORM_WITHINREAL_SET = prove + (`!f a s t. + eventually (\x. x IN s <=> x IN t) (atreal a) + ==> ((f --> l) (atreal a within s) <=> (f --> l) (atreal a within t))`, + REPEAT GEN_TAC THEN REWRITE_TAC[EVENTUALLY_ATREAL; LIM_WITHINREAL] THEN + DISCH_THEN(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC) THEN + EQ_TAC THEN DISCH_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_THEN `k:real` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `min d k:real` THEN ASM_REWRITE_TAC[REAL_LT_MIN] THEN + ASM_MESON_TAC[]);; + +let REALLIM_TRANSFORM_WITHIN_SET = prove + (`!f a s t. + eventually (\x. x IN s <=> x IN t) (at a) + ==> ((f ---> l) (at a within s) <=> (f ---> l) (at a within t))`, + REPEAT GEN_TAC THEN REWRITE_TAC[EVENTUALLY_AT; REALLIM_WITHIN] THEN + DISCH_THEN(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC) THEN + EQ_TAC THEN DISCH_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_THEN `k:real` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `min d k:real` THEN ASM_REWRITE_TAC[REAL_LT_MIN] THEN + ASM_MESON_TAC[]);; + +let REALLIM_TRANSFORM_WITHINREAL_SET = prove + (`!f a s t. + eventually (\x. x IN s <=> x IN t) (atreal a) + ==> ((f ---> l) (atreal a within s) <=> + (f ---> l) (atreal a within t))`, + REPEAT GEN_TAC THEN REWRITE_TAC[EVENTUALLY_ATREAL; REALLIM_WITHINREAL] THEN + DISCH_THEN(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC) THEN + EQ_TAC THEN DISCH_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_THEN `k:real` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `min d k:real` THEN ASM_REWRITE_TAC[REAL_LT_MIN] THEN + ASM_MESON_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* Relations between limits at real and complex limit points. *) +(* ------------------------------------------------------------------------- *) + +let TRIVIAL_LIMIT_WITHINREAL_WITHIN = prove + (`trivial_limit(atreal x within s) <=> + trivial_limit(at (lift x) within (IMAGE lift s))`, + REWRITE_TAC[trivial_limit; AT; WITHIN; ATREAL] THEN + REWRITE_TAC[FORALL_LIFT; EXISTS_LIFT; LIFT_EQ; DIST_LIFT] THEN + REWRITE_TAC[IN_IMAGE_LIFT_DROP; LIFT_DROP]);; + +let TRIVIAL_LIMIT_WITHINREAL_WITHINCOMPLEX = prove + (`trivial_limit(atreal x within s) <=> + trivial_limit(at (Cx x) within (real INTER IMAGE Cx s))`, + REWRITE_TAC[trivial_limit; AT; WITHIN; ATREAL] THEN + REWRITE_TAC[SET_RULE `x IN real INTER s <=> real x /\ x IN s`] THEN + REWRITE_TAC[TAUT `~(p /\ x /\ q) /\ ~(r /\ x /\ s) <=> + x ==> ~(p /\ q) /\ ~(r /\ s)`] THEN + REWRITE_TAC[FORALL_REAL; + MESON[IN_IMAGE; CX_INJ] `Cx x IN IMAGE Cx s <=> x IN s`] THEN + REWRITE_TAC[dist; GSYM CX_SUB; o_THM; RE_CX; COMPLEX_NORM_CX] THEN + MATCH_MP_TAC(TAUT `~p /\ ~q /\ (r <=> s) ==> (p \/ r <=> q \/ s)`) THEN + REPEAT CONJ_TAC THEN TRY EQ_TAC THEN REWRITE_TAC[LEFT_IMP_EXISTS_THM] THENL + [DISCH_THEN(MP_TAC o SPECL [`&0`; `&1`]) THEN CONV_TAC REAL_RING; + DISCH_THEN(MP_TAC o SPECL [`Cx(&0)`; `Cx(&1)`]) THEN + CONV_TAC COMPLEX_RING; + MAP_EVERY X_GEN_TAC [`a:real`; `b:real`] THEN STRIP_TAC THEN + MAP_EVERY EXISTS_TAC [`Cx a`; `Cx b`] THEN ASM_REWRITE_TAC[CX_INJ] THEN + ASM_REWRITE_TAC[GSYM CX_SUB; COMPLEX_NORM_CX]; + MAP_EVERY X_GEN_TAC [`a:complex`; `b:complex`] THEN STRIP_TAC THEN + SUBGOAL_THEN + `?d. &0 < d /\ + !z. &0 < abs(z - x) /\ abs(z - x) <= d ==> ~(z IN s)` + STRIP_ASSUME_TAC THENL + [MATCH_MP_TAC(MESON[] `!a b. P a \/ P b ==> ?x. P x`) THEN + MAP_EVERY EXISTS_TAC [`norm(a - Cx x)`; `norm(b - Cx x)`] THEN + ASM_REWRITE_TAC[TAUT `a ==> ~b <=> ~(a /\ b)`] THEN + UNDISCH_TAC `~(a:complex = b)` THEN NORM_ARITH_TAC; + ALL_TAC] THEN + MAP_EVERY EXISTS_TAC [`x + d:real`; `x - d:real`] THEN + ASM_SIMP_TAC[REAL_ARITH `&0 < d ==> ~(x + d = x - d)`; + REAL_ARITH `&0 < d ==> abs((x + d) - x) = d`; + REAL_ARITH `&0 < d ==> abs(x - d - x) = d`] THEN + ASM_MESON_TAC[]]);; + +let LIM_WITHINREAL_WITHINCOMPLEX = prove + (`(f --> a) (atreal x within s) <=> + ((f o Re) --> a) (at(Cx x) within (real INTER IMAGE Cx s))`, + REWRITE_TAC[LIM_WITHINREAL; LIM_WITHIN] THEN + REWRITE_TAC[SET_RULE `x IN real INTER s <=> real x /\ x IN s`] THEN + REWRITE_TAC[IMP_CONJ; FORALL_REAL; + MESON[IN_IMAGE; CX_INJ] `Cx x IN IMAGE Cx s <=> x IN s`] THEN + REWRITE_TAC[dist; GSYM CX_SUB; o_THM; RE_CX; COMPLEX_NORM_CX]);; + +let LIM_ATREAL_ATCOMPLEX = prove + (`(f --> a) (atreal x) <=> ((f o Re) --> a) (at (Cx x) within real)`, + REWRITE_TAC[LIM_ATREAL; LIM_WITHIN] THEN + REWRITE_TAC[IMP_CONJ; FORALL_REAL; IN; dist; GSYM CX_SUB; COMPLEX_NORM_CX; + o_THM; RE_CX]);; + +(* ------------------------------------------------------------------------- *) +(* Simpler theorems relating limits in real and real^1. *) +(* ------------------------------------------------------------------------- *) + +let LIM_WITHINREAL_WITHIN = prove + (`(f --> a) (atreal x within s) <=> + ((f o drop) --> a) (at (lift x) within (IMAGE lift s))`, + REWRITE_TAC[LIM_WITHINREAL; LIM_WITHIN] THEN + REWRITE_TAC[IMP_CONJ; FORALL_IN_IMAGE; DIST_LIFT; o_THM; LIFT_DROP]);; + +let LIM_ATREAL_AT = prove + (`(f --> a) (atreal x) <=> ((f o drop) --> a) (at (lift x))`, + REWRITE_TAC[LIM_ATREAL; LIM_AT; FORALL_LIFT] THEN + REWRITE_TAC[IMP_CONJ; FORALL_IN_IMAGE; DIST_LIFT; o_THM; LIFT_DROP]);; + +let REALLIM_WITHINREAL_WITHIN = prove + (`(f ---> a) (atreal x within s) <=> + ((f o drop) ---> a) (at (lift x) within (IMAGE lift s))`, + REWRITE_TAC[REALLIM_WITHINREAL; REALLIM_WITHIN] THEN + REWRITE_TAC[IMP_CONJ; FORALL_IN_IMAGE; DIST_LIFT; o_THM; LIFT_DROP]);; + +let REALLIM_ATREAL_AT = prove + (`(f ---> a) (atreal x) <=> ((f o drop) ---> a) (at (lift x))`, + REWRITE_TAC[REALLIM_ATREAL; REALLIM_AT; FORALL_LIFT] THEN + REWRITE_TAC[IMP_CONJ; FORALL_IN_IMAGE; DIST_LIFT; o_THM; LIFT_DROP]);; + +let REALLIM_WITHIN_OPEN = prove + (`!f:real^N->real l a s. + a IN s /\ open s + ==> ((f ---> l) (at a within s) <=> (f ---> l) (at a))`, + REWRITE_TAC[TENDSTO_REAL; LIM_WITHIN_OPEN]);; + +let LIM_WITHIN_REAL_OPEN = prove + (`!f:real->real^N l a s. + a IN s /\ real_open s + ==> ((f --> l) (atreal a within s) <=> (f --> l) (atreal a))`, + REWRITE_TAC[LIM_WITHINREAL_WITHIN; LIM_ATREAL_AT; REAL_OPEN] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC LIM_WITHIN_OPEN THEN ASM SET_TAC[]);; + +let REALLIM_WITHIN_REAL_OPEN = prove + (`!f l a s. + a IN s /\ real_open s + ==> ((f ---> l) (atreal a within s) <=> (f ---> l) (atreal a))`, + REWRITE_TAC[TENDSTO_REAL; LIM_WITHIN_REAL_OPEN]);; + +(* ------------------------------------------------------------------------- *) +(* Additional congruence rules for simplifying limits. *) +(* ------------------------------------------------------------------------- *) + +let LIM_CONG_WITHINREAL = prove + (`(!x. ~(x = a) ==> f x = g x) + ==> (((\x. f x) --> l) (atreal a within s) <=> + ((g --> l) (atreal a within s)))`, + SIMP_TAC[LIM_WITHINREAL; GSYM REAL_ABS_NZ; REAL_SUB_0]);; + +let LIM_CONG_ATREAL = prove + (`(!x. ~(x = a) ==> f x = g x) + ==> (((\x. f x) --> l) (atreal a) <=> ((g --> l) (atreal a)))`, + SIMP_TAC[LIM_ATREAL; GSYM REAL_ABS_NZ; REAL_SUB_0]);; + +extend_basic_congs [LIM_CONG_WITHINREAL; LIM_CONG_ATREAL];; + +let REALLIM_CONG_WITHIN = prove + (`(!x. ~(x = a) ==> f x = g x) + ==> (((\x. f x) ---> l) (at a within s) <=> ((g ---> l) (at a within s)))`, + REWRITE_TAC[REALLIM_WITHIN; GSYM DIST_NZ] THEN SIMP_TAC[]);; + +let REALLIM_CONG_AT = prove + (`(!x. ~(x = a) ==> f x = g x) + ==> (((\x. f x) ---> l) (at a) <=> ((g ---> l) (at a)))`, + REWRITE_TAC[REALLIM_AT; GSYM DIST_NZ] THEN SIMP_TAC[]);; + +extend_basic_congs [REALLIM_CONG_WITHIN; REALLIM_CONG_AT];; + +let REALLIM_CONG_WITHINREAL = prove + (`(!x. ~(x = a) ==> f x = g x) + ==> (((\x. f x) ---> l) (atreal a within s) <=> + ((g ---> l) (atreal a within s)))`, + SIMP_TAC[REALLIM_WITHINREAL; GSYM REAL_ABS_NZ; REAL_SUB_0]);; + +let REALLIM_CONG_ATREAL = prove + (`(!x. ~(x = a) ==> f x = g x) + ==> (((\x. f x) ---> l) (atreal a) <=> ((g ---> l) (atreal a)))`, + SIMP_TAC[REALLIM_ATREAL; GSYM REAL_ABS_NZ; REAL_SUB_0]);; + +extend_basic_congs [REALLIM_CONG_WITHINREAL; REALLIM_CONG_ATREAL];; + +(* ------------------------------------------------------------------------- *) +(* Real version of Abel limit theorem. *) +(* ------------------------------------------------------------------------- *) + +let REAL_ABEL_LIMIT_THEOREM = prove + (`!s a. real_summable s a + ==> (!r. abs(r) < &1 ==> real_summable s (\i. a i * r pow i)) /\ + ((\r. real_infsum s (\i. a i * r pow i)) ---> real_infsum s a) + (atreal (&1) within {z | z <= &1})`, + REPEAT GEN_TAC THEN STRIP_TAC THEN + MP_TAC(ISPECL [`&1`; `s:num->bool`; `Cx o (a:num->real)`] + ABEL_LIMIT_THEOREM) THEN + ASM_REWRITE_TAC[GSYM REAL_SUMMABLE_COMPLEX; REAL_LT_01] THEN STRIP_TAC THEN + MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN CONJ_TAC THENL + [X_GEN_TAC `r:real` THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `Cx r`) THEN + ASM_REWRITE_TAC[COMPLEX_NORM_CX; REAL_SUMMABLE_COMPLEX] THEN + REWRITE_TAC[o_DEF; CX_MUL; CX_POW]; + DISCH_TAC] THEN + REWRITE_TAC[REALLIM_COMPLEX; LIM_WITHINREAL_WITHINCOMPLEX] THEN + MATCH_MP_TAC LIM_TRANSFORM_WITHIN THEN + EXISTS_TAC `\z. infsum s (\i. (Cx o a) i * z pow i)` THEN + EXISTS_TAC `&1` THEN REWRITE_TAC[REAL_LT_01] THEN CONJ_TAC THENL + [REWRITE_TAC[IMP_CONJ; IN_INTER; IN_ELIM_THM; IN_IMAGE] THEN + REWRITE_TAC[IN; FORALL_REAL] THEN X_GEN_TAC `r:real` THEN + REWRITE_TAC[CX_INJ; UNWIND_THM1; dist; GSYM CX_SUB; COMPLEX_NORM_CX] THEN + DISCH_TAC THEN + ASM_SIMP_TAC[REAL_ARITH `r <= &1 ==> (&0 < abs(r - &1) <=> r < &1)`] THEN + REPEAT DISCH_TAC THEN SUBGOAL_THEN `abs(r) < &1` ASSUME_TAC THENL + [ASM_REAL_ARITH_TAC; ALL_TAC] THEN + ASM_SIMP_TAC[REAL_INFSUM_COMPLEX; o_THM; RE_CX] THEN + CONV_TAC SYM_CONV THEN REWRITE_TAC[GSYM REAL; o_DEF; CX_MUL; CX_POW] THEN + MATCH_MP_TAC(ISPEC `sequentially` REAL_LIM) THEN + EXISTS_TAC `\n. vsum(s INTER (0..n)) (\i. Cx(a i) * Cx r pow i)` THEN + REWRITE_TAC[SEQUENTIALLY; TRIVIAL_LIMIT_SEQUENTIALLY; GSYM sums] THEN + SIMP_TAC[GSYM CX_POW; GSYM CX_MUL; REAL_VSUM; FINITE_INTER; FINITE_NUMSEG; + SUMS_INFSUM; REAL_CX; GE] THEN + CONJ_TAC THENL [ALL_TAC; MESON_TAC[LE_REFL]] THEN + ONCE_REWRITE_TAC[GSYM o_DEF] THEN + ASM_SIMP_TAC[GSYM REAL_SUMMABLE_COMPLEX]; + ALL_TAC] THEN + ASM_SIMP_TAC[REAL_INFSUM_COMPLEX] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [LIM_WITHIN]) THEN + REWRITE_TAC[LIM_WITHIN] THEN + MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `e:real` THEN + ASM_CASES_TAC `&0 < e` THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[REAL_MUL_LID; IN_ELIM_THM; IN_INTER; IN_IMAGE] THEN + DISCH_THEN(X_CHOOSE_THEN `d:real` + (CONJUNCTS_THEN2 ASSUME_TAC (LABEL_TAC "*"))) THEN + EXISTS_TAC `min d (&1)` THEN ASM_REWRITE_TAC[REAL_LT_MIN; REAL_LT_01] THEN + REWRITE_TAC[IMP_CONJ; IN; FORALL_REAL] THEN + REWRITE_TAC[CX_INJ; UNWIND_THM1; dist; GSYM CX_SUB; COMPLEX_NORM_CX] THEN + X_GEN_TAC `r:real` THEN DISCH_TAC THEN + ASM_SIMP_TAC[REAL_ARITH `r <= &1 ==> (&0 < abs(r - &1) <=> r < &1)`] THEN + REPEAT DISCH_TAC THEN SUBGOAL_THEN `abs(r) < &1` ASSUME_TAC THENL + [ASM_REAL_ARITH_TAC; ALL_TAC] THEN + REMOVE_THEN "*" (MP_TAC o SPEC `Cx r`) THEN + REWRITE_TAC[CX_INJ; UNWIND_THM1; dist; GSYM CX_SUB; COMPLEX_NORM_CX] THEN + ANTS_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN + MATCH_MP_TAC(NORM_ARITH `b = a ==> norm(x - a) < e ==> norm(x - b) < e`) THEN + REWRITE_TAC[GSYM REAL] THEN + MATCH_MP_TAC(ISPEC `sequentially` REAL_LIM) THEN + EXISTS_TAC `\n. vsum(s INTER (0..n)) (Cx o a)` THEN + REWRITE_TAC[SEQUENTIALLY; TRIVIAL_LIMIT_SEQUENTIALLY; GSYM sums] THEN + SIMP_TAC[GSYM CX_POW; GSYM CX_MUL; REAL_VSUM; FINITE_INTER; FINITE_NUMSEG; + SUMS_INFSUM; REAL_CX; GE; o_DEF] THEN + CONJ_TAC THENL [ALL_TAC; MESON_TAC[LE_REFL]] THEN + ONCE_REWRITE_TAC[GSYM o_DEF] THEN + ASM_SIMP_TAC[GSYM REAL_SUMMABLE_COMPLEX]);; + +(* ------------------------------------------------------------------------- *) +(* Continuity of a function into the reals. *) +(* ------------------------------------------------------------------------- *) + +parse_as_infix ("real_continuous",(12,"right"));; + +let real_continuous = new_definition + `f real_continuous net <=> (f ---> f(netlimit net)) net`;; + +let REAL_CONTINUOUS_TRIVIAL_LIMIT = prove + (`!f net. trivial_limit net ==> f real_continuous net`, + SIMP_TAC[real_continuous; REALLIM]);; + +let REAL_CONTINUOUS_WITHIN = prove + (`!f x:real^N s. + f real_continuous (at x within s) <=> + (f ---> f(x)) (at x within s)`, + REPEAT GEN_TAC THEN REWRITE_TAC[real_continuous] THEN + ASM_CASES_TAC `trivial_limit(at(x:real^N) within s)` THENL + [ASM_REWRITE_TAC[REALLIM]; ASM_SIMP_TAC[NETLIMIT_WITHIN]]);; + +let REAL_CONTINUOUS_AT = prove + (`!f x. f real_continuous (at x) <=> (f ---> f(x)) (at x)`, + ONCE_REWRITE_TAC[GSYM WITHIN_UNIV] THEN + REWRITE_TAC[REAL_CONTINUOUS_WITHIN; IN_UNIV]);; + +let REAL_CONTINUOUS_WITHINREAL = prove + (`!f x s. f real_continuous (atreal x within s) <=> + (f ---> f(x)) (atreal x within s)`, + REPEAT GEN_TAC THEN REWRITE_TAC[real_continuous] THEN + ASM_CASES_TAC `trivial_limit(atreal x within s)` THENL + [ASM_REWRITE_TAC[REALLIM]; ASM_SIMP_TAC[NETLIMIT_WITHINREAL]]);; + +let REAL_CONTINUOUS_ATREAL = prove + (`!f x. f real_continuous (atreal x) <=> (f ---> f(x)) (atreal x)`, + ONCE_REWRITE_TAC[GSYM WITHINREAL_UNIV] THEN + REWRITE_TAC[REAL_CONTINUOUS_WITHINREAL; IN_UNIV]);; + +let CONTINUOUS_WITHINREAL = prove + (`!f x s. f continuous (atreal x within s) <=> + (f --> f(x)) (atreal x within s)`, + REPEAT GEN_TAC THEN REWRITE_TAC[continuous] THEN + ASM_CASES_TAC `trivial_limit(atreal x within s)` THENL + [ASM_REWRITE_TAC[LIM]; ASM_SIMP_TAC[NETLIMIT_WITHINREAL]]);; + +let CONTINUOUS_ATREAL = prove + (`!f x. f continuous (atreal x) <=> (f --> f(x)) (atreal x)`, + ONCE_REWRITE_TAC[GSYM WITHINREAL_UNIV] THEN + REWRITE_TAC[CONTINUOUS_WITHINREAL; IN_UNIV]);; + +let real_continuous_within = prove + (`f real_continuous (at x within s) <=> + !e. &0 < e + ==> ?d. &0 < d /\ + (!x'. x' IN s /\ dist(x',x) < d ==> abs(f x' - f x) < e)`, + REWRITE_TAC[REAL_CONTINUOUS_WITHIN; REALLIM_WITHIN] THEN + REWRITE_TAC[GSYM DIST_NZ] THEN + EQ_TAC THEN MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `e:real` THEN + ASM_CASES_TAC `&0 < e` THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC THEN + MATCH_MP_TAC MONO_AND THEN REWRITE_TAC[] THEN MATCH_MP_TAC MONO_FORALL THEN + ASM_MESON_TAC[REAL_ARITH `abs(x - x) = &0`]);; + +let real_continuous_at = prove + (`f real_continuous (at x) <=> + !e. &0 < e + ==> ?d. &0 < d /\ + (!x'. dist(x',x) < d ==> abs(f x' - f x) < e)`, + ONCE_REWRITE_TAC[GSYM WITHIN_UNIV] THEN + REWRITE_TAC[real_continuous_within; IN_UNIV]);; + +let real_continuous_withinreal = prove + (`f real_continuous (atreal x within s) <=> + !e. &0 < e + ==> ?d. &0 < d /\ + (!x'. x' IN s /\ abs(x' - x) < d ==> abs(f x' - f x) < e)`, + REWRITE_TAC[REAL_CONTINUOUS_WITHINREAL; REALLIM_WITHINREAL] THEN + REWRITE_TAC[REAL_ARITH `&0 < abs(x - y) <=> ~(x = y)`] THEN + EQ_TAC THEN MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `e:real` THEN + ASM_CASES_TAC `&0 < e` THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC THEN + MATCH_MP_TAC MONO_AND THEN REWRITE_TAC[] THEN MATCH_MP_TAC MONO_FORALL THEN + ASM_MESON_TAC[REAL_ARITH `abs(x - x) = &0`]);; + +let real_continuous_atreal = prove + (`f real_continuous (atreal x) <=> + !e. &0 < e + ==> ?d. &0 < d /\ + (!x'. abs(x' - x) < d ==> abs(f x' - f x) < e)`, + ONCE_REWRITE_TAC[GSYM WITHINREAL_UNIV] THEN + REWRITE_TAC[real_continuous_withinreal; IN_UNIV]);; + +let REAL_CONTINUOUS_AT_WITHIN = prove + (`!f s x. f real_continuous (at x) + ==> f real_continuous (at x within s)`, + REWRITE_TAC[real_continuous_within; real_continuous_at] THEN + MESON_TAC[]);; + +let REAL_CONTINUOUS_ATREAL_WITHINREAL = prove + (`!f s x. f real_continuous (atreal x) + ==> f real_continuous (atreal x within s)`, + REWRITE_TAC[real_continuous_withinreal; real_continuous_atreal] THEN + MESON_TAC[]);; + +let REAL_CONTINUOUS_WITHINREAL_SUBSET = prove + (`!f s t. f real_continuous (atreal x within s) /\ t SUBSET s + ==> f real_continuous (atreal x within t)`, + REWRITE_TAC[REAL_CONTINUOUS_WITHINREAL; REALLIM_WITHINREAL_SUBSET]);; + +let REAL_CONTINUOUS_WITHIN_SUBSET = prove + (`!f s t. f real_continuous (at x within s) /\ t SUBSET s + ==> f real_continuous (at x within t)`, + REWRITE_TAC[REAL_CONTINUOUS_WITHIN; REALLIM_WITHIN_SUBSET]);; + +let CONTINUOUS_WITHINREAL_SUBSET = prove + (`!f s t. f continuous (atreal x within s) /\ t SUBSET s + ==> f continuous (atreal x within t)`, + REWRITE_TAC[CONTINUOUS_WITHINREAL; LIM_WITHINREAL_SUBSET]);; + +let continuous_withinreal = prove + (`f continuous (atreal x within s) <=> + !e. &0 < e + ==> ?d. &0 < d /\ + (!x'. x' IN s /\ abs(x' - x) < d ==> dist(f x',f x) < e)`, + REWRITE_TAC[CONTINUOUS_WITHINREAL; LIM_WITHINREAL] THEN + REWRITE_TAC[REAL_ARITH `&0 < abs(x - y) <=> ~(x = y)`] THEN + AP_TERM_TAC THEN REWRITE_TAC[FUN_EQ_THM] THEN X_GEN_TAC `e:real` THEN + ASM_CASES_TAC `&0 < e` THEN ASM_REWRITE_TAC[] THEN + AP_TERM_TAC THEN REWRITE_TAC[FUN_EQ_THM] THEN X_GEN_TAC `d:real` THEN + ASM_CASES_TAC `&0 < d` THEN ASM_REWRITE_TAC[] THEN + AP_TERM_TAC THEN ABS_TAC THEN ASM_MESON_TAC[DIST_REFL]);; + +let continuous_atreal = prove + (`f continuous (atreal x) <=> + !e. &0 < e + ==> ?d. &0 < d /\ + (!x'. abs(x' - x) < d ==> dist(f x',f x) < e)`, + ONCE_REWRITE_TAC[GSYM WITHINREAL_UNIV] THEN + REWRITE_TAC[continuous_withinreal; IN_UNIV]);; + +let CONTINUOUS_ATREAL_WITHINREAL = prove + (`!f x s. f continuous (atreal x) ==> f continuous (atreal x within s)`, + SIMP_TAC[continuous_atreal; continuous_withinreal] THEN MESON_TAC[]);; + +let CONTINUOUS_CX_ATREAL = prove + (`!x. Cx continuous (atreal x)`, + GEN_TAC THEN REWRITE_TAC[continuous_atreal; dist] THEN + REWRITE_TAC[COMPLEX_NORM_CX; GSYM CX_SUB] THEN MESON_TAC[]);; + +let CONTINUOUS_CX_WITHINREAL = prove + (`!s x. Cx continuous (atreal x within s)`, + SIMP_TAC[CONTINUOUS_ATREAL_WITHINREAL; CONTINUOUS_CX_ATREAL]);; + +(* ------------------------------------------------------------------------- *) +(* Arithmetic combining theorems. *) +(* ------------------------------------------------------------------------- *) + +let REAL_CONTINUOUS_CONST = prove + (`!net c. (\x. c) real_continuous net`, + REWRITE_TAC[real_continuous; REALLIM_CONST]);; + +let REAL_CONTINUOUS_LMUL = prove + (`!f c net. f real_continuous net ==> (\x. c * f(x)) real_continuous net`, + REWRITE_TAC[real_continuous; REALLIM_LMUL]);; + +let REAL_CONTINUOUS_RMUL = prove + (`!f c net. f real_continuous net ==> (\x. f(x) * c) real_continuous net`, + REWRITE_TAC[real_continuous; REALLIM_RMUL]);; + +let REAL_CONTINUOUS_NEG = prove + (`!f net. f real_continuous net ==> (\x. --(f x)) real_continuous net`, + REWRITE_TAC[real_continuous; REALLIM_NEG]);; + +let REAL_CONTINUOUS_ADD = prove + (`!f g net. f real_continuous net /\ g real_continuous net + ==> (\x. f(x) + g(x)) real_continuous net`, + REWRITE_TAC[real_continuous; REALLIM_ADD]);; + +let REAL_CONTINUOUS_SUB = prove + (`!f g net. f real_continuous net /\ g real_continuous net + ==> (\x. f(x) - g(x)) real_continuous net`, + REWRITE_TAC[real_continuous; REALLIM_SUB]);; + +let REAL_CONTINUOUS_MUL = prove + (`!net f g. + f real_continuous net /\ g real_continuous net + ==> (\x. f(x) * g(x)) real_continuous net`, + SIMP_TAC[real_continuous; REALLIM_MUL]);; + +let REAL_CONTINUOUS_INV = prove + (`!net f. + f real_continuous net /\ ~(f(netlimit net) = &0) + ==> (\x. inv(f x)) real_continuous net`, + SIMP_TAC[real_continuous; REALLIM_INV]);; + +let REAL_CONTINUOUS_DIV = prove + (`!net f g. + f real_continuous net /\ g real_continuous net /\ ~(g(netlimit net) = &0) + ==> (\x. f(x) / g(x)) real_continuous net`, + SIMP_TAC[real_continuous; REALLIM_DIV]);; + +let REAL_CONTINUOUS_POW = prove + (`!net f n. f real_continuous net ==> (\x. f(x) pow n) real_continuous net`, + SIMP_TAC[real_continuous; REALLIM_POW]);; + +let REAL_CONTINUOUS_ABS = prove + (`!net f. f real_continuous net ==> (\x. abs(f(x))) real_continuous net`, + REWRITE_TAC[real_continuous; REALLIM_ABS]);; + +let REAL_CONTINUOUS_MAX = prove + (`!f g net. f real_continuous net /\ g real_continuous net + ==> (\x. max (f x) (g x)) real_continuous net`, + REWRITE_TAC[real_continuous; REALLIM_MAX]);; + +let REAL_CONTINUOUS_MIN = prove + (`!f g net. f real_continuous net /\ g real_continuous net + ==> (\x. min (f x) (g x)) real_continuous net`, + REWRITE_TAC[real_continuous; REALLIM_MIN]);; + +(* ------------------------------------------------------------------------- *) +(* Some of these without netlimit, but with many different cases. *) +(* ------------------------------------------------------------------------- *) + +let REAL_CONTINUOUS_WITHIN_ID = prove + (`!x s. (\x. x) real_continuous (atreal x within s)`, + REWRITE_TAC[real_continuous_withinreal] THEN MESON_TAC[]);; + +let REAL_CONTINUOUS_AT_ID = prove + (`!x. (\x. x) real_continuous (atreal x)`, + REWRITE_TAC[real_continuous_atreal] THEN MESON_TAC[]);; + +let REAL_CONTINUOUS_INV_WITHIN = prove + (`!f s a. f real_continuous (at a within s) /\ ~(f a = &0) + ==> (\x. inv(f x)) real_continuous (at a within s)`, + MESON_TAC[REAL_CONTINUOUS_INV; REAL_CONTINUOUS_TRIVIAL_LIMIT; + NETLIMIT_WITHIN]);; + +let REAL_CONTINUOUS_INV_AT = prove + (`!f a. f real_continuous (at a) /\ ~(f a = &0) + ==> (\x. inv(f x)) real_continuous (at a)`, + ONCE_REWRITE_TAC[GSYM WITHIN_UNIV] THEN + REWRITE_TAC[REAL_CONTINUOUS_INV_WITHIN]);; + +let REAL_CONTINUOUS_INV_WITHINREAL = prove + (`!f s a. f real_continuous (atreal a within s) /\ ~(f a = &0) + ==> (\x. inv(f x)) real_continuous (atreal a within s)`, + MESON_TAC[REAL_CONTINUOUS_INV; REAL_CONTINUOUS_TRIVIAL_LIMIT; + NETLIMIT_WITHINREAL]);; + +let REAL_CONTINUOUS_INV_ATREAL = prove + (`!f a. f real_continuous (atreal a) /\ ~(f a = &0) + ==> (\x. inv(f x)) real_continuous (atreal a)`, + ONCE_REWRITE_TAC[GSYM WITHINREAL_UNIV] THEN + REWRITE_TAC[REAL_CONTINUOUS_INV_WITHINREAL]);; + +let REAL_CONTINUOUS_DIV_WITHIN = prove + (`!f s a. f real_continuous (at a within s) /\ + g real_continuous (at a within s) /\ ~(g a = &0) + ==> (\x. f x / g x) real_continuous (at a within s)`, + MESON_TAC[REAL_CONTINUOUS_DIV; REAL_CONTINUOUS_TRIVIAL_LIMIT; + NETLIMIT_WITHIN]);; + +let REAL_CONTINUOUS_DIV_AT = prove + (`!f a. f real_continuous (at a) /\ + g real_continuous (at a) /\ ~(g a = &0) + ==> (\x. f x / g x) real_continuous (at a)`, + ONCE_REWRITE_TAC[GSYM WITHIN_UNIV] THEN + REWRITE_TAC[REAL_CONTINUOUS_DIV_WITHIN]);; + +let REAL_CONTINUOUS_DIV_WITHINREAL = prove + (`!f s a. f real_continuous (atreal a within s) /\ + g real_continuous (atreal a within s) /\ ~(g a = &0) + ==> (\x. f x / g x) real_continuous (atreal a within s)`, + MESON_TAC[REAL_CONTINUOUS_DIV; REAL_CONTINUOUS_TRIVIAL_LIMIT; + NETLIMIT_WITHINREAL]);; + +let REAL_CONTINUOUS_DIV_ATREAL = prove + (`!f a. f real_continuous (atreal a) /\ + g real_continuous (atreal a) /\ ~(g a = &0) + ==> (\x. f x / g x) real_continuous (atreal a)`, + ONCE_REWRITE_TAC[GSYM WITHINREAL_UNIV] THEN + REWRITE_TAC[REAL_CONTINUOUS_DIV_WITHINREAL]);; + +(* ------------------------------------------------------------------------- *) +(* Composition of (real->real) o (real->real) functions. *) +(* ------------------------------------------------------------------------- *) + +let REAL_CONTINUOUS_WITHINREAL_COMPOSE = prove + (`!f g x s. f real_continuous (atreal x within s) /\ + g real_continuous (atreal (f x) within IMAGE f s) + ==> (g o f) real_continuous (atreal x within s)`, + REPEAT GEN_TAC THEN + REWRITE_TAC[real_continuous_withinreal; o_THM; IN_IMAGE] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `e:real` THEN + ASM_MESON_TAC[]);; + +let REAL_CONTINUOUS_ATREAL_COMPOSE = prove + (`!f g x. f real_continuous (atreal x) /\ g real_continuous (atreal (f x)) + ==> (g o f) real_continuous (atreal x)`, + REPEAT GEN_TAC THEN + REWRITE_TAC[real_continuous_atreal; o_THM; IN_IMAGE] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `e:real` THEN + ASM_MESON_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* Composition of (real->real) o (real^N->real) functions. *) +(* ------------------------------------------------------------------------- *) + +let REAL_CONTINUOUS_WITHIN_COMPOSE = prove + (`!f g x s. f real_continuous (at x within s) /\ + g real_continuous (atreal (f x) within IMAGE f s) + ==> (g o f) real_continuous (at x within s)`, + REPEAT GEN_TAC THEN + REWRITE_TAC[real_continuous_withinreal; real_continuous_within; + o_THM; IN_IMAGE] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `e:real` THEN + ASM_MESON_TAC[]);; + +let REAL_CONTINUOUS_AT_COMPOSE = prove + (`!f g x. f real_continuous (at x) /\ + g real_continuous (atreal (f x) within IMAGE f (:real^N)) + ==> (g o f) real_continuous (at x)`, + ONCE_REWRITE_TAC[GSYM WITHIN_UNIV] THEN + REWRITE_TAC[REAL_CONTINUOUS_WITHIN_COMPOSE]);; + +(* ------------------------------------------------------------------------- *) +(* Composition of (real^N->real) o (real^M->real^N) functions. *) +(* ------------------------------------------------------------------------- *) + +let REAL_CONTINUOUS_CONTINUOUS_WITHIN_COMPOSE = prove + (`!f g x s. f continuous (at x within s) /\ + g real_continuous (at (f x) within IMAGE f s) + ==> (g o f) real_continuous (at x within s)`, + REPEAT GEN_TAC THEN + REWRITE_TAC[real_continuous_within; continuous_within; o_THM; IN_IMAGE] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `e:real` THEN + ASM_MESON_TAC[]);; + +let REAL_CONTINUOUS_CONTINUOUS_AT_COMPOSE = prove + (`!f g x. f continuous (at x) /\ + g real_continuous (at (f x) within IMAGE f (:real^N)) + ==> (g o f) real_continuous (at x)`, + REPEAT GEN_TAC THEN + ONCE_REWRITE_TAC[GSYM WITHIN_UNIV] THEN + REWRITE_TAC[WITHIN_WITHIN; INTER_UNIV] THEN + REWRITE_TAC[REAL_CONTINUOUS_CONTINUOUS_WITHIN_COMPOSE]);; + +(* ------------------------------------------------------------------------- *) +(* Composition of (real^N->real) o (real->real^N) functions. *) +(* ------------------------------------------------------------------------- *) + +let REAL_CONTINUOUS_CONTINUOUS_WITHINREAL_COMPOSE = prove + (`!f g x s. f continuous (atreal x within s) /\ + g real_continuous (at (f x) within IMAGE f s) + ==> (g o f) real_continuous (atreal x within s)`, + REPEAT GEN_TAC THEN + REWRITE_TAC[real_continuous_within; continuous_withinreal; + real_continuous_withinreal; o_THM; IN_IMAGE] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `e:real` THEN + ASM_MESON_TAC[]);; + +let REAL_CONTINUOUS_CONTINUOUS_ATREAL_COMPOSE = prove + (`!f g x. f continuous (atreal x) /\ + g real_continuous (at (f x) within IMAGE f (:real)) + ==> (g o f) real_continuous (atreal x)`, + REPEAT GEN_TAC THEN + ONCE_REWRITE_TAC[GSYM WITHINREAL_UNIV] THEN + REWRITE_TAC[REAL_CONTINUOUS_CONTINUOUS_WITHINREAL_COMPOSE]);; + +(* ------------------------------------------------------------------------- *) +(* Composition of (real->real^N) o (real->real) functions. *) +(* ------------------------------------------------------------------------- *) + +let CONTINUOUS_REAL_CONTINUOUS_WITHINREAL_COMPOSE = prove + (`!f g x s. f real_continuous (atreal x within s) /\ + g continuous (atreal (f x) within IMAGE f s) + ==> (g o f) continuous (atreal x within s)`, + REPEAT GEN_TAC THEN + REWRITE_TAC[real_continuous_within; continuous_withinreal; + real_continuous_withinreal; o_THM; IN_IMAGE] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `e:real` THEN + ASM_MESON_TAC[]);; + +let CONTINUOUS_REAL_CONTINUOUS_ATREAL_COMPOSE = prove + (`!f g x. f real_continuous (atreal x) /\ + g continuous (atreal (f x) within IMAGE f (:real)) + ==> (g o f) continuous (atreal x)`, + REPEAT GEN_TAC THEN + ONCE_REWRITE_TAC[GSYM WITHINREAL_UNIV] THEN + REWRITE_TAC[WITHIN_WITHIN; INTER_UNIV] THEN + REWRITE_TAC[CONTINUOUS_REAL_CONTINUOUS_WITHINREAL_COMPOSE]);; + +(* ------------------------------------------------------------------------- *) +(* Composition of (real^M->real^N) o (real->real^M) functions. *) +(* ------------------------------------------------------------------------- *) + +let CONTINUOUS_WITHINREAL_COMPOSE = prove + (`!f g x s. f continuous (atreal x within s) /\ + g continuous (at (f x) within IMAGE f s) + ==> (g o f) continuous (atreal x within s)`, + REPEAT GEN_TAC THEN + REWRITE_TAC[continuous_within; continuous_withinreal; o_THM; IN_IMAGE] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `e:real` THEN + ASM_MESON_TAC[]);; + +let CONTINUOUS_ATREAL_COMPOSE = prove + (`!f g x. f continuous (atreal x) /\ + g continuous (at (f x) within IMAGE f (:real)) + ==> (g o f) continuous (atreal x)`, + REPEAT GEN_TAC THEN + ONCE_REWRITE_TAC[GSYM WITHINREAL_UNIV] THEN + REWRITE_TAC[WITHIN_WITHIN; INTER_UNIV] THEN + REWRITE_TAC[CONTINUOUS_WITHINREAL_COMPOSE]);; + +(* ------------------------------------------------------------------------- *) +(* Composition of (real->real^N) o (real^M->real) functions. *) +(* ------------------------------------------------------------------------- *) + +let CONTINUOUS_REAL_CONTINUOUS_WITHIN_COMPOSE = prove + (`!f g x s. f real_continuous (at x within s) /\ + g continuous (atreal (f x) within IMAGE f s) + ==> (g o f) continuous (at x within s)`, + REPEAT GEN_TAC THEN + REWRITE_TAC[continuous_within; real_continuous_within; continuous_withinreal; + o_THM; IN_IMAGE] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `e:real` THEN + ASM_MESON_TAC[]);; + +let CONTINUOUS_REAL_CONTINUOUS_AT_COMPOSE = prove + (`!f g x. f real_continuous (at x) /\ + g continuous (atreal (f x) within IMAGE f (:real^M)) + ==> (g o f) continuous (at x)`, + REPEAT GEN_TAC THEN + ONCE_REWRITE_TAC[GSYM WITHIN_UNIV] THEN + REWRITE_TAC[WITHIN_WITHIN; INTER_UNIV] THEN + REWRITE_TAC[CONTINUOUS_REAL_CONTINUOUS_WITHIN_COMPOSE]);; + +(* ------------------------------------------------------------------------- *) +(* Continuity of a real->real function on a set. *) +(* ------------------------------------------------------------------------- *) + +parse_as_infix ("real_continuous_on",(12,"right"));; + +let real_continuous_on = new_definition + `f real_continuous_on s <=> + !x. x IN s ==> !e. &0 < e + ==> ?d. &0 < d /\ + !x'. x' IN s /\ abs(x' - x) < d + ==> abs(f(x') - f(x)) < e`;; + +let REAL_CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN = prove + (`!f s. f real_continuous_on s <=> + !x. x IN s ==> f real_continuous (atreal x within s)`, + REWRITE_TAC[real_continuous_on; real_continuous_withinreal]);; + +let REAL_CONTINUOUS_ON_SUBSET = prove + (`!f s t. f real_continuous_on s /\ t SUBSET s ==> f real_continuous_on t`, + REWRITE_TAC[real_continuous_on; SUBSET] THEN MESON_TAC[]);; + +let REAL_CONTINUOUS_ON_COMPOSE = prove + (`!f g s. f real_continuous_on s /\ g real_continuous_on (IMAGE f s) + ==> (g o f) real_continuous_on s`, + REWRITE_TAC[REAL_CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN] THEN + MESON_TAC[IN_IMAGE; REAL_CONTINUOUS_WITHINREAL_COMPOSE]);; + +let REAL_CONTINUOUS_ON = prove + (`!f s. f real_continuous_on s <=> + (lift o f o drop) continuous_on (IMAGE lift s)`, + REWRITE_TAC[REAL_CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN; + CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN; + REAL_CONTINUOUS_WITHINREAL; CONTINUOUS_WITHIN; + FORALL_IN_IMAGE; REALLIM_WITHINREAL_WITHIN; TENDSTO_REAL] THEN + REWRITE_TAC[o_THM; LIFT_DROP]);; + +let REAL_CONTINUOUS_ON_CONST = prove + (`!s c. (\x. c) real_continuous_on s`, + SIMP_TAC[REAL_CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN; REAL_CONTINUOUS_CONST]);; + +let REAL_CONTINUOUS_ON_ID = prove + (`!s. (\x. x) real_continuous_on s`, + REWRITE_TAC[REAL_CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN; + REAL_CONTINUOUS_WITHIN_ID]);; + +let REAL_CONTINUOUS_ON_LMUL = prove + (`!f c s. f real_continuous_on s ==> (\x. c * f(x)) real_continuous_on s`, + SIMP_TAC[REAL_CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN; REAL_CONTINUOUS_LMUL]);; + +let REAL_CONTINUOUS_ON_RMUL = prove + (`!f c s. f real_continuous_on s ==> (\x. f(x) * c) real_continuous_on s`, + SIMP_TAC[REAL_CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN; REAL_CONTINUOUS_RMUL]);; + +let REAL_CONTINUOUS_ON_NEG = prove + (`!f s. f real_continuous_on s + ==> (\x. --(f x)) real_continuous_on s`, + SIMP_TAC[REAL_CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN; REAL_CONTINUOUS_NEG]);; + +let REAL_CONTINUOUS_ON_ADD = prove + (`!f g s. f real_continuous_on s /\ g real_continuous_on s + ==> (\x. f(x) + g(x)) real_continuous_on s`, + SIMP_TAC[REAL_CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN; REAL_CONTINUOUS_ADD]);; + +let REAL_CONTINUOUS_ON_SUB = prove + (`!f g s. f real_continuous_on s /\ g real_continuous_on s + ==> (\x. f(x) - g(x)) real_continuous_on s`, + SIMP_TAC[REAL_CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN; REAL_CONTINUOUS_SUB]);; + +let REAL_CONTINUOUS_ON_MUL = prove + (`!f g s. f real_continuous_on s /\ g real_continuous_on s + ==> (\x. f(x) * g(x)) real_continuous_on s`, + SIMP_TAC[REAL_CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN; REAL_CONTINUOUS_MUL]);; + +let REAL_CONTINUOUS_ON_POW = prove + (`!f n s. f real_continuous_on s + ==> (\x. f(x) pow n) real_continuous_on s`, + SIMP_TAC[REAL_CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN; REAL_CONTINUOUS_POW]);; + +let REAL_CONTINUOUS_ON_EQ = prove + (`!f g s. (!x. x IN s ==> f(x) = g(x)) /\ f real_continuous_on s + ==> g real_continuous_on s`, + SIMP_TAC[real_continuous_on; IMP_CONJ]);; + +let REAL_CONTINUOUS_ON_UNION = prove + (`!f s t. + real_closed s /\ real_closed t /\ + f real_continuous_on s /\ f real_continuous_on t + ==> f real_continuous_on (s UNION t)`, + REWRITE_TAC[REAL_CLOSED; REAL_CONTINUOUS_ON; IMAGE_UNION; + CONTINUOUS_ON_UNION]);; + +let REAL_CONTINUOUS_ON_UNION_OPEN = prove + (`!f s t. + real_open s /\ real_open t /\ + f real_continuous_on s /\ f real_continuous_on t + ==> f real_continuous_on (s UNION t)`, + REWRITE_TAC[REAL_OPEN; REAL_CONTINUOUS_ON; IMAGE_UNION; + CONTINUOUS_ON_UNION_OPEN]);; + +let REAL_CONTINUOUS_ON_CASES = prove + (`!P f g s t. + real_closed s /\ real_closed t /\ + f real_continuous_on s /\ g real_continuous_on t /\ + (!x. x IN s /\ ~P x \/ x IN t /\ P x ==> f x = g x) + ==> (\x. if P x then f x else g x) real_continuous_on (s UNION t)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_CONTINUOUS_ON_UNION THEN + ASM_REWRITE_TAC[] THEN CONJ_TAC THEN MATCH_MP_TAC REAL_CONTINUOUS_ON_EQ THENL + [EXISTS_TAC `f:real->real`; EXISTS_TAC `g:real->real`] THEN + ASM_REWRITE_TAC[] THEN ASM_MESON_TAC[]);; + +let REAL_CONTINUOUS_ON_CASES_OPEN = prove + (`!P f g s t. + real_open s /\ real_open t /\ + f real_continuous_on s /\ g real_continuous_on t /\ + (!x. x IN s /\ ~P x \/ x IN t /\ P x ==> f x = g x) + ==> (\x. if P x then f x else g x) real_continuous_on (s UNION t)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_CONTINUOUS_ON_UNION_OPEN THEN + ASM_REWRITE_TAC[] THEN CONJ_TAC THEN MATCH_MP_TAC REAL_CONTINUOUS_ON_EQ THENL + [EXISTS_TAC `f:real->real`; EXISTS_TAC `g:real->real`] THEN + ASM_REWRITE_TAC[] THEN ASM_MESON_TAC[]);; + +let REAL_CONTINUOUS_ON_SUM = prove + (`!t f s. + FINITE s /\ (!a. a IN s ==> f a real_continuous_on t) + ==> (\x. sum s (\a. f a x)) real_continuous_on t`, + REPEAT GEN_TAC THEN SIMP_TAC[REAL_CONTINUOUS_ON; o_DEF; LIFT_SUM] THEN + DISCH_THEN(MP_TAC o MATCH_MP CONTINUOUS_ON_VSUM) THEN + REWRITE_TAC[]);; + +let REALLIM_CONTINUOUS_FUNCTION = prove + (`!f net g l. + f continuous (atreal l) /\ (g ---> l) net + ==> ((\x. f(g x)) --> f l) net`, + REWRITE_TAC[tendsto_real; tendsto; continuous_atreal; eventually] THEN + MESON_TAC[]);; + +let LIM_REAL_CONTINUOUS_FUNCTION = prove + (`!f net g l. + f real_continuous (at l) /\ (g --> l) net + ==> ((\x. f(g x)) ---> f l) net`, + REWRITE_TAC[tendsto_real; tendsto; real_continuous_at; eventually] THEN + MESON_TAC[]);; + +let REALLIM_REAL_CONTINUOUS_FUNCTION = prove + (`!f net g l. + f real_continuous (atreal l) /\ (g ---> l) net + ==> ((\x. f(g x)) ---> f l) net`, + REWRITE_TAC[tendsto_real; real_continuous_atreal; eventually] THEN + MESON_TAC[]);; + +let REAL_CONTINUOUS_ON_EQ_REAL_CONTINUOUS_AT = prove + (`!f s. real_open s + ==> (f real_continuous_on s <=> + !x. x IN s ==> f real_continuous atreal x)`, + SIMP_TAC[REAL_CONTINUOUS_ATREAL; REAL_CONTINUOUS_WITHINREAL; + REAL_CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN; REALLIM_WITHIN_REAL_OPEN]);; + +let REAL_CONTINUOUS_ATTAINS_SUP = prove + (`!f s. real_compact s /\ ~(s = {}) /\ f real_continuous_on s + ==> ?x. x IN s /\ (!y. y IN s ==> f y <= f x)`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`(f:real->real) o drop`; `IMAGE lift s`] + CONTINUOUS_ATTAINS_SUP) THEN + ASM_REWRITE_TAC[GSYM REAL_CONTINUOUS_ON; GSYM real_compact] THEN + ASM_REWRITE_TAC[IMAGE_EQ_EMPTY; EXISTS_IN_IMAGE; FORALL_IN_IMAGE] THEN + REWRITE_TAC[o_THM; LIFT_DROP]);; + +let REAL_CONTINUOUS_ATTAINS_INF = prove + (`!f s. real_compact s /\ ~(s = {}) /\ f real_continuous_on s + ==> ?x. x IN s /\ (!y. y IN s ==> f x <= f y)`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`(f:real->real) o drop`; `IMAGE lift s`] + CONTINUOUS_ATTAINS_INF) THEN + ASM_REWRITE_TAC[GSYM REAL_CONTINUOUS_ON; GSYM real_compact] THEN + ASM_REWRITE_TAC[IMAGE_EQ_EMPTY; EXISTS_IN_IMAGE; FORALL_IN_IMAGE] THEN + REWRITE_TAC[o_THM; LIFT_DROP]);; + +(* ------------------------------------------------------------------------- *) +(* Real version of uniform continuity. *) +(* ------------------------------------------------------------------------- *) + +parse_as_infix ("real_uniformly_continuous_on",(12,"right"));; + +let real_uniformly_continuous_on = new_definition + `f real_uniformly_continuous_on s <=> + !e. &0 < e + ==> ?d. &0 < d /\ + !x x'. x IN s /\ x' IN s /\ abs(x' - x) < d + ==> abs(f x' - f x) < e`;; + +let REAL_UNIFORMLY_CONTINUOUS_ON = prove + (`!f s. f real_uniformly_continuous_on s <=> + (lift o f o drop) uniformly_continuous_on (IMAGE lift s)`, + REWRITE_TAC[real_uniformly_continuous_on; uniformly_continuous_on] THEN + REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_IMAGE] THEN + REWRITE_TAC[o_THM; DIST_LIFT; LIFT_DROP]);; + +let REAL_UNIFORMLY_CONTINUOUS_IMP_REAL_CONTINUOUS = prove + (`!f s. f real_uniformly_continuous_on s ==> f real_continuous_on s`, + REWRITE_TAC[real_uniformly_continuous_on; real_continuous_on] THEN + MESON_TAC[]);; + +let REAL_UNIFORMLY_CONTINUOUS_ON_SEQUENTIALLY = prove + (`!f s. f real_uniformly_continuous_on s <=> + !x y. (!n. x(n) IN s) /\ (!n. y(n) IN s) /\ + ((\n. x(n) - y(n)) ---> &0) sequentially + ==> ((\n. f(x(n)) - f(y(n))) ---> &0) sequentially`, + REWRITE_TAC[REAL_UNIFORMLY_CONTINUOUS_ON] THEN + REWRITE_TAC[UNIFORMLY_CONTINUOUS_ON_SEQUENTIALLY; REAL_TENDSTO] THEN + REWRITE_TAC[o_DEF; LIFT_DROP; IN_IMAGE_LIFT_DROP; DROP_SUB; DROP_VEC] THEN + REWRITE_TAC[FORALL_LIFT_FUN; o_THM; LIFT_DROP]);; + +let REAL_UNIFORMLY_CONTINUOUS_ON_SUBSET = prove + (`!f s t. f real_uniformly_continuous_on s /\ t SUBSET s + ==> f real_uniformly_continuous_on t`, + REWRITE_TAC[real_uniformly_continuous_on; SUBSET] THEN MESON_TAC[]);; + +let REAL_UNIFORMLY_CONTINUOUS_ON_COMPOSE = prove + (`!f g s. f real_uniformly_continuous_on s /\ + g real_uniformly_continuous_on (IMAGE f s) + ==> (g o f) real_uniformly_continuous_on s`, + REPEAT GEN_TAC THEN REWRITE_TAC[REAL_UNIFORMLY_CONTINUOUS_ON] THEN + SUBGOAL_THEN + `IMAGE lift (IMAGE f s) = IMAGE (lift o f o drop) (IMAGE lift s)` + SUBST1_TAC THENL + [ALL_TAC; + DISCH_THEN(MP_TAC o MATCH_MP UNIFORMLY_CONTINUOUS_ON_COMPOSE)] THEN + REWRITE_TAC[GSYM IMAGE_o; o_DEF; LIFT_DROP]);; + +let REAL_UNIFORMLY_CONTINUOUS_ON_CONST = prove + (`!s c. (\x. c) real_uniformly_continuous_on s`, + REWRITE_TAC[REAL_UNIFORMLY_CONTINUOUS_ON_SEQUENTIALLY; o_DEF; + REAL_SUB_REFL; REALLIM_CONST]);; + +let REAL_UNIFORMLY_CONTINUOUS_ON_LMUL = prove + (`!f c s. f real_uniformly_continuous_on s + ==> (\x. c * f(x)) real_uniformly_continuous_on s`, + REWRITE_TAC[REAL_UNIFORMLY_CONTINUOUS_ON] THEN + REWRITE_TAC[o_DEF; LIFT_CMUL; UNIFORMLY_CONTINUOUS_ON_CMUL]);; + +let REAL_UNIFORMLY_CONTINUOUS_ON_RMUL = prove + (`!f c s. f real_uniformly_continuous_on s + ==> (\x. f(x) * c) real_uniformly_continuous_on s`, + ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN + REWRITE_TAC[REAL_UNIFORMLY_CONTINUOUS_ON_LMUL]);; + +let REAL_UNIFORMLY_CONTINUOUS_ON_ID = prove + (`!s. (\x. x) real_uniformly_continuous_on s`, + REWRITE_TAC[real_uniformly_continuous_on] THEN MESON_TAC[]);; + +let REAL_UNIFORMLY_CONTINUOUS_ON_NEG = prove + (`!f s. f real_uniformly_continuous_on s + ==> (\x. --(f x)) real_uniformly_continuous_on s`, + ONCE_REWRITE_TAC[REAL_ARITH `--x = -- &1 * x`] THEN + REWRITE_TAC[REAL_UNIFORMLY_CONTINUOUS_ON_LMUL]);; + +let REAL_UNIFORMLY_CONTINUOUS_ON_ADD = prove + (`!f g s. f real_uniformly_continuous_on s /\ + g real_uniformly_continuous_on s + ==> (\x. f(x) + g(x)) real_uniformly_continuous_on s`, + REWRITE_TAC[REAL_UNIFORMLY_CONTINUOUS_ON; o_DEF; LIFT_ADD] THEN + REWRITE_TAC[UNIFORMLY_CONTINUOUS_ON_ADD]);; + +let REAL_UNIFORMLY_CONTINUOUS_ON_SUB = prove + (`!f g s. f real_uniformly_continuous_on s /\ + g real_uniformly_continuous_on s + ==> (\x. f(x) - g(x)) real_uniformly_continuous_on s`, + REWRITE_TAC[REAL_UNIFORMLY_CONTINUOUS_ON; o_DEF; LIFT_SUB] THEN + REWRITE_TAC[UNIFORMLY_CONTINUOUS_ON_SUB]);; + +let REAL_UNIFORMLY_CONTINUOUS_ON_SUM = prove + (`!t f s. + FINITE s /\ (!a. a IN s ==> f a real_uniformly_continuous_on t) + ==> (\x. sum s (\a. f a x)) real_uniformly_continuous_on t`, + REPEAT GEN_TAC THEN + SIMP_TAC[REAL_UNIFORMLY_CONTINUOUS_ON; o_DEF; LIFT_SUM] THEN + DISCH_THEN(MP_TAC o MATCH_MP UNIFORMLY_CONTINUOUS_ON_VSUM) THEN + REWRITE_TAC[]);; + +let REAL_COMPACT_UNIFORMLY_CONTINUOUS = prove + (`!f s. f real_continuous_on s /\ real_compact s + ==> f real_uniformly_continuous_on s`, + REWRITE_TAC[real_compact; REAL_CONTINUOUS_ON; REAL_UNIFORMLY_CONTINUOUS_ON; + COMPACT_UNIFORMLY_CONTINUOUS]);; + +let REAL_COMPACT_CONTINUOUS_IMAGE = prove + (`!f s. f real_continuous_on s /\ real_compact s + ==> real_compact (IMAGE f s)`, + REPEAT GEN_TAC THEN REWRITE_TAC[real_compact; REAL_CONTINUOUS_ON] THEN + DISCH_THEN(MP_TAC o MATCH_MP COMPACT_CONTINUOUS_IMAGE) THEN + REWRITE_TAC[GSYM IMAGE_o; o_DEF; LIFT_DROP]);; + +let REAL_DINI = prove + (`!f g s. + real_compact s /\ (!n. (f n) real_continuous_on s) /\ + g real_continuous_on s /\ + (!x. x IN s ==> ((\n. (f n x)) ---> g x) sequentially) /\ + (!n x. x IN s ==> f n x <= f (n + 1) x) + ==> !e. &0 < e + ==> eventually (\n. !x. x IN s ==> abs(f n x - g x) < e) + sequentially`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`\n:num. lift o f n o drop`; `lift o g o drop`; + `IMAGE lift s`] DINI) THEN + ASM_REWRITE_TAC[GSYM real_compact; GSYM REAL_CONTINUOUS_ON] THEN + ASM_REWRITE_TAC[FORALL_IN_IMAGE; o_DEF; LIFT_DROP; REAL_TENDSTO] THEN + ASM_SIMP_TAC[GSYM LIFT_SUB; NORM_LIFT]);; + +(* ------------------------------------------------------------------------- *) +(* Continuity versus componentwise continuity. *) +(* ------------------------------------------------------------------------- *) + +let CONTINUOUS_COMPONENTWISE = prove + (`!net f:A->real^N. + f continuous net <=> + !i. 1 <= i /\ i <= dimindex(:N) + ==> (\x. (f x)$i) real_continuous net`, + REWRITE_TAC[real_continuous; continuous; LIM_COMPONENTWISE]);; + +let REAL_CONTINUOUS_COMPLEX_COMPONENTS_AT = prove + (`!z. Re real_continuous (at z) /\ Im real_continuous (at z)`, + GEN_TAC THEN MP_TAC(ISPECL + [`at(z:complex)`; `\z:complex. z`] CONTINUOUS_COMPONENTWISE) THEN + REWRITE_TAC[CONTINUOUS_AT_ID; DIMINDEX_2; FORALL_2] THEN + REWRITE_TAC[GSYM RE_DEF; GSYM IM_DEF; ETA_AX]);; + +let REAL_CONTINUOUS_COMPLEX_COMPONENTS_WITHIN = prove + (`!s z. Re real_continuous (at z within s) /\ + Im real_continuous (at z within s)`, + MESON_TAC[REAL_CONTINUOUS_COMPLEX_COMPONENTS_AT; + REAL_CONTINUOUS_AT_WITHIN]);; + +let REAL_CONTINUOUS_NORM_AT = prove + (`!z. norm real_continuous (at z)`, + REWRITE_TAC[real_continuous_at; dist] THEN + GEN_TAC THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN + EXISTS_TAC `e:real` THEN ASM_REWRITE_TAC[] THEN NORM_ARITH_TAC);; + +let REAL_CONTINUOUS_NORM_WITHIN = prove + (`!s z. norm real_continuous (at z within s)`, + MESON_TAC[REAL_CONTINUOUS_NORM_AT; REAL_CONTINUOUS_AT_WITHIN]);; + +let REAL_CONTINUOUS_DIST_AT = prove + (`!a z. (\x. dist(a,x)) real_continuous (at z)`, + REWRITE_TAC[real_continuous_at; dist] THEN + GEN_TAC THEN GEN_TAC THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN + EXISTS_TAC `e:real` THEN ASM_REWRITE_TAC[] THEN NORM_ARITH_TAC);; + +let REAL_CONTINUOUS_DIST_WITHIN = prove + (`!a s z. (\x. dist(a,x)) real_continuous (at z within s)`, + MESON_TAC[REAL_CONTINUOUS_DIST_AT; REAL_CONTINUOUS_AT_WITHIN]);; + +(* ------------------------------------------------------------------------- *) +(* Derivative of real->real function. *) +(* ------------------------------------------------------------------------- *) + +parse_as_infix ("has_real_derivative",(12,"right"));; +parse_as_infix ("real_differentiable",(12,"right"));; +parse_as_infix ("real_differentiable_on",(12,"right"));; + +let has_real_derivative = new_definition + `(f has_real_derivative f') net <=> + ((\x. inv(x - netlimit net) * + (f x - (f(netlimit net) + f' * (x - netlimit net)))) + ---> &0) net`;; + +let real_differentiable = new_definition + `f real_differentiable net <=> ?f'. (f has_real_derivative f') net`;; + +let real_derivative = new_definition + `real_derivative f x = @f'. (f has_real_derivative f') (atreal x)`;; + +let higher_real_derivative = define + `higher_real_derivative 0 f = f /\ + (!n. higher_real_derivative (SUC n) f = + real_derivative (higher_real_derivative n f))`;; + +let real_differentiable_on = new_definition + `f real_differentiable_on s <=> + !x. x IN s ==> ?f'. (f has_real_derivative f') (atreal x within s)`;; + +(* ------------------------------------------------------------------------- *) +(* Basic limit definitions in the useful cases. *) +(* ------------------------------------------------------------------------- *) + +let HAS_REAL_DERIVATIVE_WITHINREAL = prove + (`(f has_real_derivative f') (atreal a within s) <=> + ((\x. (f x - f a) / (x - a)) ---> f') (atreal a within s)`, + REWRITE_TAC[has_real_derivative] THEN + ASM_CASES_TAC `trivial_limit(atreal a within s)` THENL + [ASM_REWRITE_TAC[REALLIM]; ALL_TAC] THEN + ASM_SIMP_TAC[NETLIMIT_WITHINREAL] THEN + GEN_REWRITE_TAC RAND_CONV [REALLIM_NULL] THEN + REWRITE_TAC[REALLIM_WITHINREAL; REAL_SUB_RZERO] THEN + SIMP_TAC[REAL_FIELD + `&0 < abs(x - a) ==> (fy - fa) / (x - a) - f' = + inv(x - a) * (fy - (fa + f' * (x - a)))`]);; + +let HAS_REAL_DERIVATIVE_ATREAL = prove + (`(f has_real_derivative f') (atreal a) <=> + ((\x. (f x - f a) / (x - a)) ---> f') (atreal a)`, + ONCE_REWRITE_TAC[GSYM WITHINREAL_UNIV] THEN + REWRITE_TAC[HAS_REAL_DERIVATIVE_WITHINREAL]);; + +(* ------------------------------------------------------------------------- *) +(* Relation to Frechet derivative. *) +(* ------------------------------------------------------------------------- *) + +let HAS_REAL_FRECHET_DERIVATIVE_WITHIN = prove + (`(f has_real_derivative f') (atreal x within s) <=> + ((lift o f o drop) has_derivative (\x. f' % x)) + (at (lift x) within (IMAGE lift s))`, + REWRITE_TAC[has_derivative_within; HAS_REAL_DERIVATIVE_WITHINREAL] THEN + REWRITE_TAC[o_THM; LIFT_DROP; LIM_WITHIN; REALLIM_WITHINREAL] THEN + SIMP_TAC[LINEAR_COMPOSE_CMUL; LINEAR_ID; IMP_CONJ] THEN + REWRITE_TAC[FORALL_IN_IMAGE; DIST_LIFT; GSYM LIFT_SUB; LIFT_DROP; + NORM_ARITH `dist(x,vec 0) = norm x`; GSYM LIFT_CMUL; GSYM LIFT_ADD; + NORM_LIFT] THEN + SIMP_TAC[REAL_FIELD + `&0 < abs(y - x) + ==> fy - (fx + f' * (y - x)) = (y - x) * ((fy - fx) / (y - x) - f')`] THEN + REWRITE_TAC[REAL_ABS_MUL; REAL_MUL_ASSOC; REAL_ABS_INV; REAL_ABS_ABS] THEN + SIMP_TAC[REAL_LT_IMP_NZ; REAL_MUL_LINV; REAL_MUL_LID]);; + +let HAS_REAL_FRECHET_DERIVATIVE_AT = prove + (`(f has_real_derivative f') (atreal x) <=> + ((lift o f o drop) has_derivative (\x. f' % x)) (at (lift x))`, + ONCE_REWRITE_TAC[GSYM WITHINREAL_UNIV; GSYM WITHIN_UNIV] THEN + REWRITE_TAC[HAS_REAL_FRECHET_DERIVATIVE_WITHIN] THEN + REWRITE_TAC[IMAGE_LIFT_UNIV]);; + +let HAS_REAL_VECTOR_DERIVATIVE_WITHIN = prove + (`(f has_real_derivative f') (atreal x within s) <=> + ((lift o f o drop) has_vector_derivative (lift f')) + (at (lift x) within (IMAGE lift s))`, + REWRITE_TAC[has_vector_derivative; HAS_REAL_FRECHET_DERIVATIVE_WITHIN] THEN + AP_THM_TAC THEN AP_TERM_TAC THEN + REWRITE_TAC[FUN_EQ_THM; FORALL_LIFT; GSYM LIFT_CMUL] THEN + REWRITE_TAC[LIFT_DROP; LIFT_EQ; REAL_MUL_SYM]);; + +let HAS_REAL_VECTOR_DERIVATIVE_AT = prove + (`(f has_real_derivative f') (atreal x) <=> + ((lift o f o drop) has_vector_derivative (lift f')) (at (lift x))`, + REWRITE_TAC[has_vector_derivative; HAS_REAL_FRECHET_DERIVATIVE_AT] THEN + AP_THM_TAC THEN AP_TERM_TAC THEN + REWRITE_TAC[FUN_EQ_THM; FORALL_LIFT; GSYM LIFT_CMUL] THEN + REWRITE_TAC[LIFT_DROP; LIFT_EQ; REAL_MUL_SYM]);; + +let REAL_DIFFERENTIABLE_AT = prove + (`!f a. f real_differentiable (atreal x) <=> + (lift o f o drop) differentiable (at(lift x))`, + REWRITE_TAC[real_differentiable; HAS_REAL_FRECHET_DERIVATIVE_AT] THEN + REWRITE_TAC[differentiable; has_derivative; LINEAR_SCALING] THEN + REWRITE_TAC[LINEAR_1; LEFT_AND_EXISTS_THM] THEN + ONCE_REWRITE_TAC[SWAP_EXISTS_THM] THEN REWRITE_TAC[UNWIND_THM2]);; + +let REAL_DIFFERENTIABLE_WITHIN = prove + (`!f a s. + f real_differentiable (atreal x within s) <=> + (lift o f o drop) differentiable (at(lift x) within IMAGE lift s)`, + REWRITE_TAC[real_differentiable; HAS_REAL_FRECHET_DERIVATIVE_WITHIN] THEN + REWRITE_TAC[differentiable; has_derivative; LINEAR_SCALING] THEN + REWRITE_TAC[LINEAR_1; LEFT_AND_EXISTS_THM] THEN + ONCE_REWRITE_TAC[SWAP_EXISTS_THM] THEN REWRITE_TAC[UNWIND_THM2]);; + +(* ------------------------------------------------------------------------- *) +(* Relation to complex derivative. *) +(* ------------------------------------------------------------------------- *) + +let HAS_REAL_COMPLEX_DERIVATIVE_WITHIN = prove + (`(f has_real_derivative f') (atreal a within s) <=> + ((Cx o f o Re) has_complex_derivative (Cx f')) + (at (Cx a) within {z | real z /\ Re z IN s})`, + REWRITE_TAC[HAS_REAL_DERIVATIVE_WITHINREAL; HAS_COMPLEX_DERIVATIVE_WITHIN; + LIM_WITHIN; IN_ELIM_THM; IMP_CONJ; FORALL_REAL] THEN + REWRITE_TAC[RE_CX; dist; GSYM CX_SUB; COMPLEX_NORM_CX; o_THM; GSYM CX_DIV; + REALLIM_WITHINREAL] THEN + MESON_TAC[]);; + +let HAS_REAL_COMPLEX_DERIVATIVE_AT = prove + (`(f has_real_derivative f') (atreal a) <=> + ((Cx o f o Re) has_complex_derivative (Cx f')) (at (Cx a) within real)`, + ONCE_REWRITE_TAC[GSYM WITHINREAL_UNIV] THEN + REWRITE_TAC[HAS_REAL_COMPLEX_DERIVATIVE_WITHIN] THEN + AP_TERM_TAC THEN AP_TERM_TAC THEN SET_TAC[]);; + +let REAL_DIFFERENTIABLE_ON_DIFFERENTIABLE = prove + (`!f s. f real_differentiable_on s <=> + !x. x IN s ==> f real_differentiable (atreal x within s)`, + REWRITE_TAC[real_differentiable_on; real_differentiable]);; + +let REAL_DIFFERENTIABLE_ON_REAL_OPEN = prove + (`!f s. real_open s + ==> (f real_differentiable_on s <=> + !x. x IN s ==> ?f'. (f has_real_derivative f') (atreal x))`, + REWRITE_TAC[real_differentiable_on; HAS_REAL_DERIVATIVE_WITHINREAL; + HAS_REAL_DERIVATIVE_ATREAL] THEN + SIMP_TAC[REALLIM_WITHIN_REAL_OPEN]);; + +let REAL_DIFFERENTIABLE_ON_IMP_DIFFERENTIABLE_WITHIN = prove + (`!f s x. f real_differentiable_on s /\ x IN s + ==> f real_differentiable (atreal x within s)`, + MESON_TAC[REAL_DIFFERENTIABLE_ON_DIFFERENTIABLE]);; + +let REAL_DIFFERENTIABLE_ON_IMP_DIFFERENTIABLE_ATREAL = prove + (`!f s x. f real_differentiable_on s /\ real_open s /\ x IN s + ==> f real_differentiable (atreal x)`, + MESON_TAC[REAL_DIFFERENTIABLE_ON_REAL_OPEN; real_differentiable]);; + +let HAS_COMPLEX_REAL_DERIVATIVE_WITHIN_GEN = prove + (`!f g h s d. + &0 < d /\ x IN s /\ + (h has_complex_derivative Cx(g)) + (at (Cx x) within {z | real z /\ Re(z) IN s}) /\ + (!y. y IN s /\ abs(y - x) < d ==> h(Cx y) = Cx(f y)) + ==> (f has_real_derivative g) (atreal x within s)`, + REPEAT STRIP_TAC THEN REWRITE_TAC[HAS_REAL_COMPLEX_DERIVATIVE_WITHIN] THEN + MATCH_MP_TAC HAS_COMPLEX_DERIVATIVE_TRANSFORM_WITHIN THEN + MAP_EVERY EXISTS_TAC [`h:complex->complex`; `d:real`] THEN + ASM_REWRITE_TAC[IN_ELIM_THM; o_THM; REAL_CX; RE_CX; dist] THEN + X_GEN_TAC `w:complex` THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `Re w`) THEN + FIRST_X_ASSUM(SUBST_ALL_TAC o SYM o GEN_REWRITE_RULE I [REAL]) THEN + RULE_ASSUM_TAC(REWRITE_RULE[GSYM CX_SUB; COMPLEX_NORM_CX]) THEN + ASM_REWRITE_TAC[RE_CX]);; + +let HAS_COMPLEX_REAL_DERIVATIVE_AT_GEN = prove + (`!f g h d. + &0 < d /\ + (h has_complex_derivative Cx(g)) (at (Cx x) within real) /\ + (!y. abs(y - x) < d ==> h(Cx y) = Cx(f y)) + ==> (f has_real_derivative g) (atreal x)`, + REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[GSYM WITHINREAL_UNIV] THEN + MATCH_MP_TAC HAS_COMPLEX_REAL_DERIVATIVE_WITHIN_GEN THEN + MAP_EVERY EXISTS_TAC [`h:complex->complex`; `d:real`] THEN + ASM_REWRITE_TAC[IN_UNIV; ETA_AX; SET_RULE `{x | r x} = r`]);; + +let HAS_COMPLEX_REAL_DERIVATIVE_WITHIN = prove + (`!f g h s. + x IN s /\ + (h has_complex_derivative Cx(g)) + (at (Cx x) within {z | real z /\ Re(z) IN s}) /\ + (!y. y IN s ==> h(Cx y) = Cx(f y)) + ==> (f has_real_derivative g) (atreal x within s)`, + REPEAT STRIP_TAC THEN + MATCH_MP_TAC HAS_COMPLEX_REAL_DERIVATIVE_WITHIN_GEN THEN + MAP_EVERY EXISTS_TAC [`h:complex->complex`; `&1`] THEN + ASM_SIMP_TAC[REAL_LT_01]);; + +let HAS_COMPLEX_REAL_DERIVATIVE_AT = prove + (`!f g h. + (h has_complex_derivative Cx(g)) (at (Cx x) within real) /\ + (!y. h(Cx y) = Cx(f y)) + ==> (f has_real_derivative g) (atreal x)`, + REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[GSYM WITHINREAL_UNIV] THEN + MATCH_MP_TAC HAS_COMPLEX_REAL_DERIVATIVE_WITHIN THEN + EXISTS_TAC `h:complex->complex` THEN + ASM_REWRITE_TAC[IN_UNIV; ETA_AX; SET_RULE `{x | r x} = r`]);; + +(* ------------------------------------------------------------------------- *) +(* Caratheodory characterization. *) +(* ------------------------------------------------------------------------- *) + +let HAS_REAL_DERIVATIVE_CARATHEODORY_ATREAL = prove + (`!f f' z. + (f has_real_derivative f') (atreal z) <=> + ?g. (!w. f(w) - f(z) = g(w) * (w - z)) /\ + g real_continuous atreal z /\ g(z) = f'`, + REPEAT GEN_TAC THEN + REWRITE_TAC[REAL_RING `w' - z':real = a <=> w' = z' + a`] THEN + SIMP_TAC[GSYM FUN_EQ_THM; HAS_REAL_DERIVATIVE_ATREAL; + REAL_CONTINUOUS_ATREAL] THEN + EQ_TAC THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THENL + [EXISTS_TAC `\w. if w = z then f':real else (f(w) - f(z)) / (w - z)` THEN + ASM_SIMP_TAC[FUN_EQ_THM; COND_RAND; COND_RATOR; REAL_SUB_REFL] THEN + CONV_TAC REAL_FIELD; + FIRST_X_ASSUM SUBST_ALL_TAC THEN FIRST_X_ASSUM SUBST1_TAC THEN + ASM_SIMP_TAC[REAL_RING `(z + a) - (z + b * (w - w)):real = a`] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ_ALT] + REALLIM_TRANSFORM)) THEN + SIMP_TAC[REALLIM_CONST; REAL_FIELD + `~(w = z) ==> x - (x * (w - z)) / (w - z) = &0`]]);; + +let HAS_REAL_DERIVATIVE_CARATHEODORY_WITHINREAL = prove + (`!f f' z s. + (f has_real_derivative f') (atreal z within s) <=> + ?g. (!w. f(w) - f(z) = g(w) * (w - z)) /\ + g real_continuous (atreal z within s) /\ g(z) = f'`, + REPEAT GEN_TAC THEN + REWRITE_TAC[REAL_RING `w' - z':real = a <=> w' = z' + a`] THEN + SIMP_TAC[GSYM FUN_EQ_THM; HAS_REAL_DERIVATIVE_WITHINREAL; + REAL_CONTINUOUS_WITHINREAL] THEN + EQ_TAC THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THENL + [EXISTS_TAC `\w. if w = z then f':real else (f(w) - f(z)) / (w - z)` THEN + ASM_SIMP_TAC[FUN_EQ_THM; COND_RAND; COND_RATOR; REAL_SUB_REFL] THEN + CONV_TAC REAL_FIELD; + FIRST_X_ASSUM SUBST_ALL_TAC THEN FIRST_X_ASSUM SUBST1_TAC THEN + ASM_SIMP_TAC[REAL_RING `(z + a) - (z + b * (w - w)):real = a`] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ_ALT] + REALLIM_TRANSFORM)) THEN + SIMP_TAC[REALLIM_CONST; REAL_FIELD + `~(w = z) ==> x - (x * (w - z)) / (w - z) = &0`]]);; + +let REAL_DIFFERENTIABLE_CARATHEODORY_ATREAL = prove + (`!f z. f real_differentiable atreal z <=> + ?g. (!w. f(w) - f(z) = g(w) * (w - z)) /\ g real_continuous atreal z`, + SIMP_TAC[real_differentiable; HAS_REAL_DERIVATIVE_CARATHEODORY_ATREAL] THEN + MESON_TAC[]);; + +let REAL_DIFFERENTIABLE_CARATHEODORY_WITHINREAL = prove + (`!f z s. + f real_differentiable (atreal z within s) <=> + ?g. (!w. f(w) - f(z) = g(w) * (w - z)) /\ + g real_continuous (atreal z within s)`, + SIMP_TAC[real_differentiable; + HAS_REAL_DERIVATIVE_CARATHEODORY_WITHINREAL] THEN + MESON_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* Property of being an interval (equivalent to convex or connected). *) +(* ------------------------------------------------------------------------- *) + +let is_realinterval = new_definition + `is_realinterval s <=> + !a b c. a IN s /\ b IN s /\ a <= c /\ c <= b ==> c IN s`;; + +let IS_REALINTERVAL_IS_INTERVAL = prove + (`!s. is_realinterval s <=> is_interval(IMAGE lift s)`, + REWRITE_TAC[IS_INTERVAL_1; is_realinterval] THEN + REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_IMAGE] THEN + REWRITE_TAC[LIFT_DROP; IN_IMAGE; EXISTS_DROP; UNWIND_THM1] THEN + REWRITE_TAC[GSYM FORALL_DROP]);; + +let IS_REALINTERVAL_CONVEX = prove + (`!s. is_realinterval s <=> convex(IMAGE lift s)`, + REWRITE_TAC[IS_REALINTERVAL_IS_INTERVAL; IS_INTERVAL_CONVEX_1]);; + +let IS_REALINTERVAL_CONNECTED = prove + (`!s. is_realinterval s <=> connected(IMAGE lift s)`, + REWRITE_TAC[IS_REALINTERVAL_IS_INTERVAL; IS_INTERVAL_CONNECTED_1]);; + +let TRIVIAL_LIMIT_WITHIN_REALINTERVAL = prove + (`!s x. is_realinterval s /\ x IN s + ==> (trivial_limit(atreal x within s) <=> s = {x})`, + REWRITE_TAC[TRIVIAL_LIMIT_WITHINREAL_WITHIN; IS_REALINTERVAL_CONVEX] THEN + REWRITE_TAC[FORALL_DROP; GSYM IN_IMAGE_LIFT_DROP; LIFT_DROP] THEN + SIMP_TAC[TRIVIAL_LIMIT_WITHIN_CONVEX] THEN REPEAT STRIP_TAC THEN + REWRITE_TAC[EXTENSION; IN_IMAGE_LIFT_DROP; IN_SING] THEN + MESON_TAC[LIFT_DROP]);; + +let IS_REALINTERVAL_EMPTY = prove + (`is_realinterval {}`, + REWRITE_TAC[is_realinterval; NOT_IN_EMPTY]);; + +let IS_REALINTERVAL_UNION = prove + (`!s t. is_realinterval s /\ is_realinterval t /\ ~(s INTER t = {}) + ==> is_realinterval(s UNION t)`, + REWRITE_TAC[is_realinterval; IN_UNION; IN_INTER; + NOT_IN_EMPTY; EXTENSION] THEN + MESON_TAC[REAL_LE_TRANS; REAL_LE_TOTAL]);; + +let IS_REALINTERVAL_UNIV = prove + (`is_realinterval (:real)`, + REWRITE_TAC[is_realinterval; IN_UNIV]);; + +let IS_REAL_INTERVAL_CASES = prove + (`!s. is_realinterval s <=> + s = {} \/ + s = (:real) \/ + (?a. s = {x | a < x}) \/ + (?a. s = {x | a <= x}) \/ + (?b. s = {x | x <= b}) \/ + (?b. s = {x | x < b}) \/ + (?a b. s = {x | a < x /\ x < b}) \/ + (?a b. s = {x | a < x /\ x <= b}) \/ + (?a b. s = {x | a <= x /\ x < b}) \/ + (?a b. s = {x | a <= x /\ x <= b})`, + REWRITE_TAC[IS_REALINTERVAL_IS_INTERVAL; IS_INTERVAL_1_CASES] THEN + REWRITE_TAC[EXTENSION; IN_IMAGE_LIFT_DROP; IN_ELIM_THM] THEN + REWRITE_TAC[GSYM FORALL_DROP; IN_UNIV; NOT_IN_EMPTY]);; + +(* ------------------------------------------------------------------------- *) +(* Some relations with the complex numbers can also be useful. *) +(* ------------------------------------------------------------------------- *) + +let IS_REALINTERVAL_CONVEX_COMPLEX = prove + (`!s. is_realinterval s <=> convex {z | real z /\ Re z IN s}`, + GEN_TAC THEN + REWRITE_TAC[GSYM IMAGE_CX; IS_REALINTERVAL_CONVEX] THEN EQ_TAC THENL + [DISCH_THEN(MP_TAC o ISPEC `Cx o drop` o MATCH_MP + (REWRITE_RULE[IMP_CONJ] CONVEX_LINEAR_IMAGE)) THEN + REWRITE_TAC[GSYM IMAGE_o; GSYM o_ASSOC] THEN + ONCE_REWRITE_TAC[IMAGE_o] THEN REWRITE_TAC[IMAGE_LIFT_DROP] THEN + DISCH_THEN MATCH_MP_TAC THEN + REWRITE_TAC[linear; o_THM; CX_ADD; CX_MUL; DROP_ADD; DROP_CMUL; + COMPLEX_CMUL]; + DISCH_THEN(MP_TAC o ISPEC `lift o Re` o MATCH_MP + (REWRITE_RULE[IMP_CONJ] CONVEX_LINEAR_IMAGE)) THEN + REWRITE_TAC[GSYM IMAGE_o; GSYM o_ASSOC] THEN + ONCE_REWRITE_TAC[IMAGE_o] THEN + REWRITE_TAC[o_DEF; RE_CX; SET_RULE `IMAGE (\x. x) s = s`] THEN + DISCH_THEN MATCH_MP_TAC THEN + REWRITE_TAC[linear; o_THM; RE_CMUL; + RE_ADD; RE_MUL_CX; LIFT_ADD; LIFT_CMUL]]);; + +(* ------------------------------------------------------------------------- *) +(* The same tricks to define closed and open intervals. *) +(* ------------------------------------------------------------------------- *) + +let open_real_interval = new_definition + `open_real_interval(a:real,b:real) = {x:real | a < x /\ x < b}`;; + +let closed_real_interval = define + `closed_real_interval[a:real,b:real] = {x:real | a <= x /\ x <= b}`;; + +make_overloadable "real_interval" `:A`;; + +overload_interface("real_interval",`open_real_interval`);; +overload_interface("real_interval",`closed_real_interval`);; + +let real_interval = prove + (`real_interval(a,b) = {x | a < x /\ x < b} /\ + real_interval[a,b] = {x | a <= x /\ x <= b}`, + REWRITE_TAC[open_real_interval; closed_real_interval]);; + +let IN_REAL_INTERVAL = prove + (`!a b x. (x IN real_interval[a,b] <=> a <= x /\ x <= b) /\ + (x IN real_interval(a,b) <=> a < x /\ x < b)`, + REWRITE_TAC[real_interval; IN_ELIM_THM]);; + +let REAL_INTERVAL_INTERVAL = prove + (`real_interval[a,b] = IMAGE drop (interval[lift a,lift b]) /\ + real_interval(a,b) = IMAGE drop (interval(lift a,lift b))`, + REWRITE_TAC[EXTENSION; IN_IMAGE; IN_INTERVAL_1; IN_REAL_INTERVAL] THEN + REWRITE_TAC[EXISTS_LIFT; LIFT_DROP; UNWIND_THM1]);; + +let INTERVAL_REAL_INTERVAL = prove + (`interval[a,b] = IMAGE lift (real_interval[drop a,drop b]) /\ + interval(a,b) = IMAGE lift (real_interval(drop a,drop b))`, + REWRITE_TAC[EXTENSION; IN_IMAGE; IN_INTERVAL_1; IN_REAL_INTERVAL] THEN + REWRITE_TAC[EXISTS_DROP; LIFT_DROP; UNWIND_THM1]);; + +let EMPTY_AS_REAL_INTERVAL = prove + (`{} = real_interval[&1,&0]`, + REWRITE_TAC[REAL_INTERVAL_INTERVAL; LIFT_NUM; GSYM EMPTY_AS_INTERVAL] THEN + REWRITE_TAC[IMAGE_CLAUSES]);; + +let IMAGE_LIFT_REAL_INTERVAL = prove + (`IMAGE lift (real_interval[a,b]) = interval[lift a,lift b] /\ + IMAGE lift (real_interval(a,b)) = interval(lift a,lift b)`, + REWRITE_TAC[REAL_INTERVAL_INTERVAL; GSYM IMAGE_o; o_DEF; LIFT_DROP] THEN + SET_TAC[]);; + +let IMAGE_DROP_INTERVAL = prove + (`IMAGE drop (interval[a,b]) = real_interval[drop a,drop b] /\ + IMAGE drop (interval(a,b)) = real_interval(drop a,drop b)`, + REWRITE_TAC[INTERVAL_REAL_INTERVAL; GSYM IMAGE_o; o_DEF; LIFT_DROP] THEN + SET_TAC[]);; + +let SUBSET_REAL_INTERVAL = prove + (`!a b c d. + (real_interval[a,b] SUBSET real_interval[c,d] <=> + b < a \/ c <= a /\ a <= b /\ b <= d) /\ + (real_interval[a,b] SUBSET real_interval(c,d) <=> + b < a \/ c < a /\ a <= b /\ b < d) /\ + (real_interval(a,b) SUBSET real_interval[c,d] <=> + b <= a \/ c <= a /\ a < b /\ b <= d) /\ + (real_interval(a,b) SUBSET real_interval(c,d) <=> + b <= a \/ c <= a /\ a < b /\ b <= d)`, + let lemma = prove + (`IMAGE drop s SUBSET IMAGE drop t <=> s SUBSET t`, + SET_TAC[LIFT_DROP]) in + REWRITE_TAC[REAL_INTERVAL_INTERVAL; lemma; SUBSET_INTERVAL_1] THEN + REWRITE_TAC[LIFT_DROP]);; + +let REAL_INTERVAL_OPEN_SUBSET_CLOSED = prove + (`!a b. real_interval(a,b) SUBSET real_interval[a,b]`, + REWRITE_TAC[SUBSET; IN_REAL_INTERVAL] THEN REAL_ARITH_TAC);; + +let REAL_INTERVAL_EQ_EMPTY = prove + (`(!a b. real_interval[a,b] = {} <=> b < a) /\ + (!a b. real_interval(a,b) = {} <=> b <= a)`, + REWRITE_TAC[REAL_INTERVAL_INTERVAL; IMAGE_EQ_EMPTY] THEN + REWRITE_TAC[INTERVAL_EQ_EMPTY_1; LIFT_DROP]);; + +let REAL_INTERVAL_NE_EMPTY = prove + (`(!a b. ~(real_interval[a,b] = {}) <=> a <= b) /\ + (!a b. ~(real_interval(a,b) = {}) <=> a < b)`, + REWRITE_TAC[REAL_INTERVAL_EQ_EMPTY; REAL_NOT_LE; REAL_NOT_LT]);; + +let REAL_OPEN_CLOSED_INTERVAL = prove + (`!a b. real_interval(a,b) = real_interval[a,b] DIFF {a,b}`, + SIMP_TAC[EXTENSION; IN_DIFF; IN_REAL_INTERVAL; IN_INSERT; NOT_IN_EMPTY] THEN + REAL_ARITH_TAC);; + +let REAL_CLOSED_OPEN_INTERVAL = prove + (`!a b. a <= b ==> real_interval[a,b] = real_interval(a,b) UNION {a,b}`, + SIMP_TAC[EXTENSION; IN_UNION; IN_REAL_INTERVAL; IN_INSERT; NOT_IN_EMPTY] THEN + REAL_ARITH_TAC);; + +let REAL_CLOSED_REAL_INTERVAL = prove + (`!a b. real_closed(real_interval[a,b])`, + REWRITE_TAC[REAL_CLOSED; IMAGE_LIFT_REAL_INTERVAL; CLOSED_INTERVAL]);; + +let REAL_OPEN_REAL_INTERVAL = prove + (`!a b. real_open(real_interval(a,b))`, + REWRITE_TAC[REAL_OPEN; IMAGE_LIFT_REAL_INTERVAL; OPEN_INTERVAL]);; + +let REAL_INTERVAL_SING = prove + (`!a. real_interval[a,a] = {a} /\ real_interval(a,a) = {}`, + REWRITE_TAC[EXTENSION; IN_SING; NOT_IN_EMPTY; IN_REAL_INTERVAL] THEN + REAL_ARITH_TAC);; + +let REAL_COMPACT_INTERVAL = prove + (`!a b. real_compact(real_interval[a,b])`, + REWRITE_TAC[REAL_INTERVAL_INTERVAL; real_compact] THEN + REWRITE_TAC[GSYM IMAGE_o; o_DEF; LIFT_DROP; IMAGE_ID; COMPACT_INTERVAL]);; + +let IS_REALINTERVAL_INTERVAL = prove + (`!a b. is_realinterval(real_interval(a,b)) /\ + is_realinterval(real_interval[a,b])`, + REWRITE_TAC[is_realinterval; IN_REAL_INTERVAL] THEN REAL_ARITH_TAC);; + +let REAL_BOUNDED_REAL_INTERVAL = prove + (`(!a b. real_bounded(real_interval[a,b])) /\ + (!a b. real_bounded(real_interval(a,b)))`, + REWRITE_TAC[IMAGE_LIFT_REAL_INTERVAL; REAL_BOUNDED; BOUNDED_INTERVAL]);; + +let ENDS_IN_REAL_INTERVAL = prove + (`(!a b. a IN real_interval[a,b] <=> ~(real_interval[a,b] = {})) /\ + (!a b. b IN real_interval[a,b] <=> ~(real_interval[a,b] = {})) /\ + (!a b. ~(a IN real_interval(a,b))) /\ + (!a b. ~(b IN real_interval(a,b)))`, + REWRITE_TAC[IN_REAL_INTERVAL; REAL_INTERVAL_EQ_EMPTY] THEN REAL_ARITH_TAC);; + +let IMAGE_AFFINITY_REAL_INTERVAL = prove + (`!a b m c. + IMAGE (\x. m * x + c) (real_interval[a,b]) = + (if real_interval[a,b] = {} + then {} + else if &0 <= m + then real_interval[m * a + c,m * b + c] + else real_interval[m * b + c,m * a + c])`, + REWRITE_TAC[REAL_INTERVAL_INTERVAL; GSYM IMAGE_o; o_DEF; IMAGE_EQ_EMPTY] THEN + REWRITE_TAC[FORALL_DROP; LIFT_DROP; GSYM DROP_CMUL; GSYM DROP_ADD] THEN + REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[GSYM o_DEF] THEN + REWRITE_TAC[IMAGE_o; IMAGE_AFFINITY_INTERVAL] THEN + MESON_TAC[IMAGE_CLAUSES]);; + +let IMAGE_STRETCH_REAL_INTERVAL = prove + (`!a b m. + IMAGE (\x. m * x) (real_interval[a,b]) = + (if real_interval[a,b] = {} + then {} + else if &0 <= m + then real_interval[m * a,m * b] + else real_interval[m * b,m * a])`, + ONCE_REWRITE_TAC[REAL_ARITH `m * x = m * x + &0`] THEN + REWRITE_TAC[IMAGE_AFFINITY_REAL_INTERVAL]);; + +let REAL_INTERVAL_TRANSLATION = prove + (`(!c a b. real_interval[c + a,c + b] = + IMAGE (\x. c + x) (real_interval[a,b])) /\ + (!c a b. real_interval(c + a,c + b) = + IMAGE (\x. c + x) (real_interval(a,b)))`, + REPEAT STRIP_TAC THEN CONV_TAC SYM_CONV THEN + MATCH_MP_TAC SURJECTIVE_IMAGE_EQ THEN + REWRITE_TAC[REAL_ARITH `c + x:real = y <=> x = y - c`; EXISTS_REFL] THEN + REWRITE_TAC[IN_REAL_INTERVAL] THEN REAL_ARITH_TAC);; + +let IN_REAL_INTERVAL_REFLECT = prove + (`(!a b x. --x IN real_interval[--b,--a] <=> x IN real_interval[a,b]) /\ + (!a b x. --x IN real_interval(--b,--a) <=> x IN real_interval(a,b))`, + REWRITE_TAC[IN_REAL_INTERVAL] THEN REAL_ARITH_TAC);; + +let REFLECT_REAL_INTERVAL = prove + (`(!a b. IMAGE (--) (real_interval[a,b]) = real_interval[--b,--a]) /\ + (!a b. IMAGE (--) (real_interval(a,b)) = real_interval(--b,--a))`, + REWRITE_TAC[EXTENSION; IN_ELIM_THM; IN_IMAGE; IN_REAL_INTERVAL] THEN + ONCE_REWRITE_TAC[REAL_ARITH `x:real = --y <=> --x = y`] THEN + REWRITE_TAC[UNWIND_THM1] THEN REAL_ARITH_TAC);; + +(* ------------------------------------------------------------------------- *) +(* Real continuity and differentiability. *) +(* ------------------------------------------------------------------------- *) + +let REAL_CONTINUOUS_CONTINUOUS = prove + (`f real_continuous net <=> (Cx o f) continuous net`, + REWRITE_TAC[real_continuous; continuous; REALLIM_COMPLEX; o_THM]);; + +let REAL_CONTINUOUS_CONTINUOUS1 = prove + (`f real_continuous net <=> (lift o f) continuous net`, + REWRITE_TAC[real_continuous; continuous; TENDSTO_REAL; o_THM]);; + +let REAL_CONTINUOUS_CONTINUOUS_ATREAL = prove + (`f real_continuous (atreal x) <=> (lift o f o drop) continuous (at(lift x))`, + REWRITE_TAC[REAL_CONTINUOUS_ATREAL; REALLIM_ATREAL_AT; CONTINUOUS_AT; + TENDSTO_REAL; o_THM; LIFT_DROP]);; + +let REAL_CONTINUOUS_CONTINUOUS_WITHINREAL = prove + (`f real_continuous (atreal x within s) <=> + (lift o f o drop) continuous (at(lift x) within IMAGE lift s)`, + REWRITE_TAC[REAL_CONTINUOUS_WITHINREAL; REALLIM_WITHINREAL_WITHIN] THEN + REWRITE_TAC[TENDSTO_REAL; CONTINUOUS_WITHIN; o_THM; LIFT_DROP]);; + +let REAL_COMPLEX_CONTINUOUS_WITHINREAL = prove + (`f real_continuous (atreal x within s) <=> + (Cx o f o Re) continuous (at (Cx x) within (real INTER IMAGE Cx s))`, + REWRITE_TAC[real_continuous; continuous; REALLIM_COMPLEX; + LIM_WITHINREAL_WITHINCOMPLEX; NETLIMIT_WITHINREAL; GSYM o_ASSOC] THEN + ASM_CASES_TAC `trivial_limit(at(Cx x) within (real INTER IMAGE Cx s))` THENL + [ASM_REWRITE_TAC[LIM]; + ASM_SIMP_TAC[TRIVIAL_LIMIT_WITHINREAL_WITHINCOMPLEX; + NETLIMIT_WITHIN; NETLIMIT_WITHINREAL; RE_CX; o_THM]]);; + +let REAL_COMPLEX_CONTINUOUS_ATREAL = prove + (`f real_continuous (atreal x) <=> + (Cx o f o Re) continuous (at (Cx x) within real)`, + REWRITE_TAC[real_continuous; continuous; REALLIM_COMPLEX; + LIM_ATREAL_ATCOMPLEX; NETLIMIT_ATREAL; GSYM o_ASSOC] THEN + ASM_CASES_TAC `trivial_limit(at(Cx x) within real)` THENL + [ASM_REWRITE_TAC[LIM]; + ASM_SIMP_TAC[NETLIMIT_WITHIN; RE_CX; o_THM]]);; + +let CONTINUOUS_CONTINUOUS_WITHINREAL = prove + (`!f x s. f continuous (atreal x within s) <=> + (f o drop) continuous (at (lift x) within IMAGE lift s)`, + REWRITE_TAC[REALLIM_WITHINREAL_WITHIN; CONTINUOUS_WITHIN; + CONTINUOUS_WITHINREAL; o_DEF; LIFT_DROP; LIM_WITHINREAL_WITHIN]);; + +let CONTINUOUS_CONTINUOUS_ATREAL = prove + (`!f x. f continuous (atreal x) <=> (f o drop) continuous (at (lift x))`, + REWRITE_TAC[REALLIM_ATREAL_AT; CONTINUOUS_AT; + CONTINUOUS_ATREAL; o_DEF; LIFT_DROP; LIM_ATREAL_AT]);; + +let REAL_CONTINUOUS_REAL_CONTINUOUS_WITHINREAL = prove + (`!f x s. f real_continuous (atreal x within s) <=> + (f o drop) real_continuous (at (lift x) within IMAGE lift s)`, + REWRITE_TAC[REALLIM_WITHINREAL_WITHIN; REAL_CONTINUOUS_WITHIN; + REAL_CONTINUOUS_WITHINREAL; o_DEF; LIFT_DROP; + LIM_WITHINREAL_WITHIN]);; + +let REAL_CONTINUOUS_REAL_CONTINUOUS_ATREAL = prove + (`!f x. f real_continuous (atreal x) <=> + (f o drop) real_continuous (at (lift x))`, + REWRITE_TAC[REALLIM_ATREAL_AT; REAL_CONTINUOUS_AT; + REAL_CONTINUOUS_ATREAL; o_DEF; LIFT_DROP; LIM_ATREAL_AT]);; +let HAS_REAL_DERIVATIVE_IMP_CONTINUOUS_WITHINREAL = prove + (`!f f' x s. (f has_real_derivative f') (atreal x within s) + ==> f real_continuous (atreal x within s)`, + REPEAT GEN_TAC THEN + REWRITE_TAC[HAS_REAL_COMPLEX_DERIVATIVE_WITHIN; + REAL_COMPLEX_CONTINUOUS_WITHINREAL] THEN + DISCH_THEN(MP_TAC o + MATCH_MP HAS_COMPLEX_DERIVATIVE_IMP_CONTINUOUS_WITHIN) THEN + MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN AP_TERM_TAC THEN + REWRITE_TAC[EXTENSION; IN_ELIM_THM; IN_INTER; IN_IMAGE] THEN + MESON_TAC[REAL; RE_CX; REAL_CX; IN]);; + +let REAL_DIFFERENTIABLE_IMP_CONTINUOUS_WITHINREAL = prove + (`!f x s. f real_differentiable (atreal x within s) + ==> f real_continuous (atreal x within s)`, + MESON_TAC[HAS_REAL_DERIVATIVE_IMP_CONTINUOUS_WITHINREAL; + real_differentiable]);; + +let HAS_REAL_DERIVATIVE_IMP_CONTINUOUS_ATREAL = prove + (`!f f' x. (f has_real_derivative f') (atreal x) + ==> f real_continuous (atreal x)`, + REWRITE_TAC[HAS_REAL_COMPLEX_DERIVATIVE_AT; + REAL_COMPLEX_CONTINUOUS_ATREAL; + HAS_COMPLEX_DERIVATIVE_IMP_CONTINUOUS_WITHIN]);; + +let REAL_DIFFERENTIABLE_IMP_CONTINUOUS_ATREAL = prove + (`!f x. f real_differentiable atreal x ==> f real_continuous atreal x`, + MESON_TAC[HAS_REAL_DERIVATIVE_IMP_CONTINUOUS_ATREAL; real_differentiable]);; + +let REAL_DIFFERENTIABLE_ON_IMP_REAL_CONTINUOUS_ON = prove + (`!f s. f real_differentiable_on s ==> f real_continuous_on s`, + REWRITE_TAC[real_differentiable_on; + REAL_CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN] THEN + MESON_TAC[REAL_DIFFERENTIABLE_IMP_CONTINUOUS_WITHINREAL; + real_differentiable]);; + +let REAL_CONTINUOUS_AT_COMPONENT = prove + (`!i a. 1 <= i /\ i <= dimindex(:N) + ==> (\x:real^N. x$i) real_continuous at a`, + REWRITE_TAC[REAL_CONTINUOUS_CONTINUOUS1; o_DEF; + CONTINUOUS_AT_LIFT_COMPONENT]);; + +let REAL_CONTINUOUS_AT_TRANSLATION = prove + (`!a z f:real^N->real. + f real_continuous at (a + z) <=> (\x. f(a + x)) real_continuous at z`, + REWRITE_TAC[REAL_CONTINUOUS_CONTINUOUS1; o_DEF; CONTINUOUS_AT_TRANSLATION]);; + +add_translation_invariants [REAL_CONTINUOUS_AT_TRANSLATION];; + +let REAL_CONTINUOUS_AT_LINEAR_IMAGE = prove + (`!h:real^N->real^N z f:real^N->real. + linear h /\ (!x. norm(h x) = norm x) + ==> (f real_continuous at (h z) <=> (\x. f(h x)) real_continuous at z)`, + REWRITE_TAC[REAL_CONTINUOUS_CONTINUOUS1; o_DEF; + CONTINUOUS_AT_LINEAR_IMAGE]);; + +add_linear_invariants [REAL_CONTINUOUS_AT_LINEAR_IMAGE];; + +let REAL_CONTINUOUS_AT_ARG = prove + (`!z. ~(real z /\ &0 <= Re z) ==> Arg real_continuous (at z)`, + REWRITE_TAC[REAL_CONTINUOUS_CONTINUOUS; CONTINUOUS_AT_ARG]);; + +(* ------------------------------------------------------------------------- *) +(* More basics about real derivatives. *) +(* ------------------------------------------------------------------------- *) + +let HAS_REAL_DERIVATIVE_WITHIN_SUBSET = prove + (`!f s t x. (f has_real_derivative f') (atreal x within s) /\ t SUBSET s + ==> (f has_real_derivative f') (atreal x within t)`, + REPEAT GEN_TAC THEN REWRITE_TAC[HAS_REAL_COMPLEX_DERIVATIVE_WITHIN] THEN + DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] + HAS_COMPLEX_DERIVATIVE_WITHIN_SUBSET) THEN ASM SET_TAC[]);; + +let REAL_DIFFERENTIABLE_ON_SUBSET = prove + (`!f s t. f real_differentiable_on s /\ t SUBSET s + ==> f real_differentiable_on t`, + REWRITE_TAC[real_differentiable_on] THEN + MESON_TAC[SUBSET; HAS_REAL_DERIVATIVE_WITHIN_SUBSET]);; + +let REAL_DIFFERENTIABLE_WITHIN_SUBSET = prove + (`!f s t. f real_differentiable (atreal x within s) /\ t SUBSET s + ==> f real_differentiable (atreal x within t)`, + REWRITE_TAC[real_differentiable] THEN + MESON_TAC[HAS_REAL_DERIVATIVE_WITHIN_SUBSET]);; + +let HAS_REAL_DERIVATIVE_ATREAL_WITHIN = prove + (`!f f' x s. (f has_real_derivative f') (atreal x) + ==> (f has_real_derivative f') (atreal x within s)`, + REPEAT GEN_TAC THEN + REWRITE_TAC[HAS_REAL_COMPLEX_DERIVATIVE_WITHIN; + HAS_REAL_COMPLEX_DERIVATIVE_AT] THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] + HAS_COMPLEX_DERIVATIVE_WITHIN_SUBSET) THEN ASM SET_TAC[]);; + +let HAS_REAL_DERIVATIVE_WITHIN_REAL_OPEN = prove + (`!f f' a s. + a IN s /\ real_open s + ==> ((f has_real_derivative f') (atreal a within s) <=> + (f has_real_derivative f') (atreal a))`, + REPEAT GEN_TAC THEN + ASM_SIMP_TAC[HAS_REAL_DERIVATIVE_WITHINREAL; HAS_REAL_DERIVATIVE_ATREAL; + REALLIM_WITHIN_REAL_OPEN]);; + +let REAL_DIFFERENTIABLE_ATREAL_WITHIN = prove + (`!f s z. f real_differentiable (atreal z) + ==> f real_differentiable (atreal z within s)`, + REWRITE_TAC[real_differentiable] THEN + MESON_TAC[HAS_REAL_DERIVATIVE_ATREAL_WITHIN]);; + +let HAS_REAL_DERIVATIVE_TRANSFORM_WITHIN = prove + (`!f f' g x s d. + &0 < d /\ x IN s /\ + (!x'. x' IN s /\ abs(x' - x) < d ==> f x' = g x') /\ + (f has_real_derivative f') (atreal x within s) + ==> (g has_real_derivative f') (atreal x within s)`, + REPEAT GEN_TAC THEN + REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + REWRITE_TAC[HAS_REAL_COMPLEX_DERIVATIVE_WITHIN] THEN + MATCH_MP_TAC(ONCE_REWRITE_RULE + [TAUT `a /\ b /\ c /\ d ==> e <=> a /\ b /\ c ==> d ==> e`] + HAS_COMPLEX_DERIVATIVE_TRANSFORM_WITHIN) THEN + EXISTS_TAC `d:real` THEN ASM_REWRITE_TAC[IN_ELIM_THM; REAL_CX; RE_CX] THEN + REPEAT STRIP_TAC THEN REWRITE_TAC[o_THM] THEN AP_TERM_TAC THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (NORM_ARITH + `dist(a,b) < d ==> z <= norm(a - b) ==> z < d`)) THEN + W(MP_TAC o PART_MATCH (rand o rand) COMPLEX_NORM_GE_RE_IM o rand o snd) THEN + SIMP_TAC[RE_SUB; RE_CX]);; + +let HAS_REAL_DERIVATIVE_TRANSFORM_ATREAL = prove + (`!f f' g x d. + &0 < d /\ (!x'. abs(x' - x) < d ==> f x' = g x') /\ + (f has_real_derivative f') (atreal x) + ==> (g has_real_derivative f') (atreal x)`, + ONCE_REWRITE_TAC[GSYM WITHINREAL_UNIV] THEN + MESON_TAC[HAS_REAL_DERIVATIVE_TRANSFORM_WITHIN; IN_UNIV]);; + +let HAS_REAL_DERIVATIVE_ZERO_CONSTANT = prove + (`!f s. + is_realinterval s /\ + (!x. x IN s ==> (f has_real_derivative (&0)) (atreal x within s)) + ==> ?c. !x. x IN s ==> f(x) = c`, + REWRITE_TAC[HAS_REAL_COMPLEX_DERIVATIVE_WITHIN] THEN + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`Cx o f o Re`; `{z | real z /\ Re z IN s}`] + HAS_COMPLEX_DERIVATIVE_ZERO_CONSTANT) THEN + ASM_REWRITE_TAC[IN_ELIM_THM; IMP_CONJ; FORALL_REAL; RE_CX; o_THM] THEN + ASM_REWRITE_TAC[GSYM IS_REALINTERVAL_CONVEX_COMPLEX] THEN MESON_TAC[RE_CX]);; + +let HAS_REAL_DERIVATIVE_ZERO_UNIQUE = prove + (`!f s c a. + is_realinterval s /\ a IN s /\ f a = c /\ + (!x. x IN s ==> (f has_real_derivative (&0)) (atreal x within s)) + ==> !x. x IN s ==> f(x) = c`, + MESON_TAC[HAS_REAL_DERIVATIVE_ZERO_CONSTANT]);; + +let REAL_DIFF_CHAIN_WITHIN = prove + (`!f g f' g' x s. + (f has_real_derivative f') (atreal x within s) /\ + (g has_real_derivative g') (atreal (f x) within (IMAGE f s)) + ==> ((g o f) has_real_derivative (g' * f'))(atreal x within s)`, + REWRITE_TAC[HAS_REAL_COMPLEX_DERIVATIVE_WITHIN] THEN REPEAT STRIP_TAC THEN + SUBGOAL_THEN `Cx o (g o f) o Re = (Cx o g o Re) o (Cx o f o Re)` + SUBST1_TAC THENL [REWRITE_TAC[FUN_EQ_THM; o_DEF; RE_CX]; ALL_TAC] THEN + REWRITE_TAC[CX_MUL] THEN MATCH_MP_TAC COMPLEX_DIFF_CHAIN_WITHIN THEN + ASM_REWRITE_TAC[o_THM; RE_CX] THEN + FIRST_ASSUM(MATCH_MP_TAC o MATCH_MP + (REWRITE_RULE[IMP_CONJ] HAS_COMPLEX_DERIVATIVE_WITHIN_SUBSET)) THEN + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE] THEN + REWRITE_TAC[IN_ELIM_THM; o_THM; REAL_CX; RE_CX] THEN SET_TAC[]);; + +let REAL_DIFF_CHAIN_ATREAL = prove + (`!f g f' g' x. + (f has_real_derivative f') (atreal x) /\ + (g has_real_derivative g') (atreal (f x)) + ==> ((g o f) has_real_derivative (g' * f')) (atreal x)`, + ONCE_REWRITE_TAC[GSYM WITHINREAL_UNIV] THEN + ASM_MESON_TAC[REAL_DIFF_CHAIN_WITHIN; SUBSET_UNIV; + HAS_REAL_DERIVATIVE_WITHIN_SUBSET]);; + +let HAS_REAL_DERIVATIVE_CHAIN = prove + (`!P f g. + (!x. P x ==> (g has_real_derivative g'(x)) (atreal x)) + ==> (!x s. (f has_real_derivative f') (atreal x within s) /\ P(f x) + ==> ((\x. g(f x)) has_real_derivative f' * g'(f x)) + (atreal x within s)) /\ + (!x. (f has_real_derivative f') (atreal x) /\ P(f x) + ==> ((\x. g(f x)) has_real_derivative f' * g'(f x)) + (atreal x))`, + REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM o_DEF] THEN + ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN + ASM_MESON_TAC[REAL_DIFF_CHAIN_WITHIN; REAL_DIFF_CHAIN_ATREAL; + HAS_REAL_DERIVATIVE_ATREAL_WITHIN]);; + +let HAS_REAL_DERIVATIVE_CHAIN_UNIV = prove + (`!f g. (!x. (g has_real_derivative g'(x)) (atreal x)) + ==> (!x s. (f has_real_derivative f') (atreal x within s) + ==> ((\x. g(f x)) has_real_derivative f' * g'(f x)) + (atreal x within s)) /\ + (!x. (f has_real_derivative f') (atreal x) + ==> ((\x. g(f x)) has_real_derivative f' * g'(f x)) + (atreal x))`, + MP_TAC(SPEC `\x:real. T` HAS_REAL_DERIVATIVE_CHAIN) THEN SIMP_TAC[]);; + +let REAL_DERIVATIVE_UNIQUE_ATREAL = prove + (`!f z f' f''. + (f has_real_derivative f') (atreal z) /\ + (f has_real_derivative f'') (atreal z) + ==> f' = f''`, + REPEAT GEN_TAC THEN REWRITE_TAC[HAS_REAL_FRECHET_DERIVATIVE_AT] THEN + DISCH_THEN(MP_TAC o MATCH_MP FRECHET_DERIVATIVE_UNIQUE_AT) THEN + DISCH_THEN(MP_TAC o C AP_THM `vec 1:real^1`) THEN + REWRITE_TAC[VECTOR_MUL_RCANCEL; VEC_EQ; ARITH_EQ]);; + +(* ------------------------------------------------------------------------- *) +(* Some handy theorems about the actual differentition function. *) +(* ------------------------------------------------------------------------- *) + +let HAS_REAL_DERIVATIVE_DERIVATIVE = prove + (`!f f' x. (f has_real_derivative f') (atreal x) + ==> real_derivative f x = f'`, + REWRITE_TAC[real_derivative] THEN + MESON_TAC[REAL_DERIVATIVE_UNIQUE_ATREAL]);; + +let HAS_REAL_DERIVATIVE_DIFFERENTIABLE = prove + (`!f x. (f has_real_derivative (real_derivative f x)) (atreal x) <=> + f real_differentiable atreal x`, + REWRITE_TAC[real_differentiable; real_derivative] THEN MESON_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* Arithmetical combining theorems. *) +(* ------------------------------------------------------------------------- *) + +let HAS_REAL_DERIVATIVE_LMUL_WITHIN = prove + (`!f f' c x s. + (f has_real_derivative f') (atreal x within s) + ==> ((\x. c * f(x)) has_real_derivative (c * f')) (atreal x within s)`, + REWRITE_TAC[HAS_REAL_COMPLEX_DERIVATIVE_WITHIN] THEN + REWRITE_TAC[o_DEF; CX_MUL; HAS_COMPLEX_DERIVATIVE_LMUL_WITHIN]);; + +let HAS_REAL_DERIVATIVE_LMUL_ATREAL = prove + (`!f f' c x. + (f has_real_derivative f') (atreal x) + ==> ((\x. c * f(x)) has_real_derivative (c * f')) (atreal x)`, + ONCE_REWRITE_TAC[GSYM WITHINREAL_UNIV] THEN + REWRITE_TAC[HAS_REAL_DERIVATIVE_LMUL_WITHIN]);; + +let HAS_REAL_DERIVATIVE_RMUL_WITHIN = prove + (`!f f' c x s. + (f has_real_derivative f') (atreal x within s) + ==> ((\x. f(x) * c) has_real_derivative (f' * c)) (atreal x within s)`, + ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN + REWRITE_TAC[HAS_REAL_DERIVATIVE_LMUL_WITHIN]);; + +let HAS_REAL_DERIVATIVE_RMUL_ATREAL = prove + (`!f f' c x. + (f has_real_derivative f') (atreal x) + ==> ((\x. f(x) * c) has_real_derivative (f' * c)) (atreal x)`, + ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN + REWRITE_TAC[HAS_REAL_DERIVATIVE_LMUL_ATREAL]);; + +let HAS_REAL_DERIVATIVE_CDIV_WITHIN = prove + (`!f f' c x s. + (f has_real_derivative f') (atreal x within s) + ==> ((\x. f(x) / c) has_real_derivative (f' / c)) (atreal x within s)`, + SIMP_TAC[real_div; HAS_REAL_DERIVATIVE_RMUL_WITHIN]);; + +let HAS_REAL_DERIVATIVE_CDIV_ATREAL = prove + (`!f f' c x. + (f has_real_derivative f') (atreal x) + ==> ((\x. f(x) / c) has_real_derivative (f' / c)) (atreal x)`, + SIMP_TAC[real_div; HAS_REAL_DERIVATIVE_RMUL_ATREAL]);; + +let HAS_REAL_DERIVATIVE_ID = prove + (`!net. ((\x. x) has_real_derivative &1) net`, + REWRITE_TAC[has_real_derivative; TENDSTO_REAL; + REAL_ARITH `x - (a + &1 * (x - a)) = &0`] THEN + REWRITE_TAC[REAL_MUL_RZERO; LIM_CONST; o_DEF]);; + +let HAS_REAL_DERIVATIVE_CONST = prove + (`!c net. ((\x. c) has_real_derivative &0) net`, + REWRITE_TAC[has_real_derivative; REAL_MUL_LZERO; REAL_ADD_RID; REAL_SUB_REFL; + REAL_MUL_RZERO; REALLIM_CONST]);; + +let HAS_REAL_DERIVATIVE_NEG = prove + (`!f f' net. (f has_real_derivative f') net + ==> ((\x. --(f(x))) has_real_derivative (--f')) net`, + REPEAT GEN_TAC THEN REWRITE_TAC[has_real_derivative] THEN + DISCH_THEN(MP_TAC o MATCH_MP REALLIM_NEG) THEN + REWRITE_TAC[REAL_NEG_0; REAL_ARITH + `a * (--b - (--c + --d * e:real)) = --(a * (b - (c + d * e)))`]);; + +let HAS_REAL_DERIVATIVE_ADD = prove + (`!f f' g g' net. + (f has_real_derivative f') net /\ (g has_real_derivative g') net + ==> ((\x. f(x) + g(x)) has_real_derivative (f' + g')) net`, + REPEAT GEN_TAC THEN REWRITE_TAC[has_real_derivative] THEN + DISCH_THEN(MP_TAC o MATCH_MP REALLIM_ADD) THEN + REWRITE_TAC[GSYM REAL_ADD_LDISTRIB; REAL_ADD_RID] THEN + REWRITE_TAC[REAL_ARITH + `(fx - (fa + f' * (x - a))) + (gx - (ga + g' * (x - a))):real = + (fx + gx) - ((fa + ga) + (f' + g') * (x - a))`]);; + +let HAS_REAL_DERIVATIVE_SUB = prove + (`!f f' g g' net. + (f has_real_derivative f') net /\ (g has_real_derivative g') net + ==> ((\x. f(x) - g(x)) has_real_derivative (f' - g')) net`, + SIMP_TAC[real_sub; HAS_REAL_DERIVATIVE_ADD; HAS_REAL_DERIVATIVE_NEG]);; + +let HAS_REAL_DERIVATIVE_MUL_WITHIN = prove + (`!f f' g g' x s. + (f has_real_derivative f') (atreal x within s) /\ + (g has_real_derivative g') (atreal x within s) + ==> ((\x. f(x) * g(x)) has_real_derivative + (f(x) * g' + f' * g(x))) (atreal x within s)`, + REPEAT GEN_TAC THEN REWRITE_TAC[HAS_REAL_COMPLEX_DERIVATIVE_WITHIN] THEN + DISCH_THEN(MP_TAC o MATCH_MP HAS_COMPLEX_DERIVATIVE_MUL_WITHIN) THEN + REWRITE_TAC[o_DEF; CX_MUL; CX_ADD; RE_CX]);; + +let HAS_REAL_DERIVATIVE_MUL_ATREAL = prove + (`!f f' g g' x. + (f has_real_derivative f') (atreal x) /\ + (g has_real_derivative g') (atreal x) + ==> ((\x. f(x) * g(x)) has_real_derivative + (f(x) * g' + f' * g(x))) (atreal x)`, + ONCE_REWRITE_TAC[GSYM WITHINREAL_UNIV] THEN + REWRITE_TAC[HAS_REAL_DERIVATIVE_MUL_WITHIN]);; + +let HAS_REAL_DERIVATIVE_POW_WITHIN = prove + (`!f f' x s n. (f has_real_derivative f') (atreal x within s) + ==> ((\x. f(x) pow n) has_real_derivative + (&n * f(x) pow (n - 1) * f')) (atreal x within s)`, + REPEAT GEN_TAC THEN REWRITE_TAC[HAS_REAL_COMPLEX_DERIVATIVE_WITHIN] THEN + DISCH_THEN(MP_TAC o SPEC `n:num` o + MATCH_MP HAS_COMPLEX_DERIVATIVE_POW_WITHIN) THEN + REWRITE_TAC[o_DEF; CX_MUL; CX_POW; RE_CX]);; + +let HAS_REAL_DERIVATIVE_POW_ATREAL = prove + (`!f f' x n. (f has_real_derivative f') (atreal x) + ==> ((\x. f(x) pow n) has_real_derivative + (&n * f(x) pow (n - 1) * f')) (atreal x)`, + ONCE_REWRITE_TAC[GSYM WITHINREAL_UNIV] THEN + REWRITE_TAC[HAS_REAL_DERIVATIVE_POW_WITHIN]);; + +let HAS_REAL_DERIVATIVE_INV_BASIC = prove + (`!x. ~(x = &0) + ==> ((inv) has_real_derivative (--inv(x pow 2))) (atreal x)`, + REPEAT STRIP_TAC THEN + REWRITE_TAC[HAS_REAL_COMPLEX_DERIVATIVE_AT] THEN + MATCH_MP_TAC HAS_COMPLEX_DERIVATIVE_TRANSFORM_WITHIN THEN + EXISTS_TAC `inv:complex->complex` THEN + ASM_SIMP_TAC[HAS_COMPLEX_DERIVATIVE_INV_BASIC; CX_INJ; CX_NEG; CX_INV; + CX_POW; HAS_COMPLEX_DERIVATIVE_AT_WITHIN] THEN + SIMP_TAC[IN; FORALL_REAL; IMP_CONJ; o_DEF; REAL_CX; RE_CX; CX_INV] THEN + MESON_TAC[REAL_LT_01]);; + +let HAS_REAL_DERIVATIVE_INV_WITHIN = prove + (`!f f' x s. (f has_real_derivative f') (atreal x within s) /\ + ~(f x = &0) + ==> ((\x. inv(f(x))) has_real_derivative (--f' / f(x) pow 2)) + (atreal x within s)`, + REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[GSYM o_DEF] THEN + ASM_SIMP_TAC[REAL_FIELD + `~(g = &0) ==> --f / g pow 2 = --inv(g pow 2) * f`] THEN + MATCH_MP_TAC REAL_DIFF_CHAIN_WITHIN THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC HAS_REAL_DERIVATIVE_ATREAL_WITHIN THEN + ASM_SIMP_TAC[HAS_REAL_DERIVATIVE_INV_BASIC]);; + +let HAS_REAL_DERIVATIVE_INV_ATREAL = prove + (`!f f' x. (f has_real_derivative f') (atreal x) /\ + ~(f x = &0) + ==> ((\x. inv(f(x))) has_real_derivative (--f' / f(x) pow 2)) + (atreal x)`, + ONCE_REWRITE_TAC[GSYM WITHINREAL_UNIV] THEN + REWRITE_TAC[HAS_REAL_DERIVATIVE_INV_WITHIN]);; + +let HAS_REAL_DERIVATIVE_DIV_WITHIN = prove + (`!f f' g g' x s. + (f has_real_derivative f') (atreal x within s) /\ + (g has_real_derivative g') (atreal x within s) /\ + ~(g(x) = &0) + ==> ((\x. f(x) / g(x)) has_real_derivative + (f' * g(x) - f(x) * g') / g(x) pow 2) (atreal x within s)`, + REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + DISCH_THEN(fun th -> ASSUME_TAC(CONJUNCT2 th) THEN MP_TAC th) THEN + DISCH_THEN(MP_TAC o MATCH_MP HAS_REAL_DERIVATIVE_INV_WITHIN) THEN + UNDISCH_TAC `(f has_real_derivative f') (atreal x within s)` THEN + REWRITE_TAC[IMP_IMP] THEN + DISCH_THEN(MP_TAC o MATCH_MP HAS_REAL_DERIVATIVE_MUL_WITHIN) THEN + REWRITE_TAC[GSYM real_div] THEN MATCH_MP_TAC EQ_IMP THEN + AP_THM_TAC THEN AP_TERM_TAC THEN + POP_ASSUM MP_TAC THEN CONV_TAC REAL_FIELD);; + +let HAS_REAL_DERIVATIVE_DIV_ATREAL = prove + (`!f f' g g' x. + (f has_real_derivative f') (atreal x) /\ + (g has_real_derivative g') (atreal x) /\ + ~(g(x) = &0) + ==> ((\x. f(x) / g(x)) has_real_derivative + (f' * g(x) - f(x) * g') / g(x) pow 2) (atreal x)`, + ONCE_REWRITE_TAC[GSYM WITHINREAL_UNIV] THEN + REWRITE_TAC[HAS_REAL_DERIVATIVE_DIV_WITHIN]);; + +let HAS_REAL_DERIVATIVE_SUM = prove + (`!f net s. + FINITE s /\ (!a. a IN s ==> (f a has_real_derivative f' a) net) + ==> ((\x. sum s (\a. f a x)) has_real_derivative (sum s f')) + net`, + GEN_TAC THEN GEN_TAC THEN REWRITE_TAC[IMP_CONJ] THEN + MATCH_MP_TAC FINITE_INDUCT_STRONG THEN + SIMP_TAC[FORALL_IN_INSERT; NOT_IN_EMPTY; SUM_CLAUSES] THEN + SIMP_TAC[HAS_REAL_DERIVATIVE_CONST; HAS_REAL_DERIVATIVE_ADD; ETA_AX]);; + +(* ------------------------------------------------------------------------- *) +(* Same thing just for real differentiability. *) +(* ------------------------------------------------------------------------- *) + +let REAL_DIFFERENTIABLE_CONST = prove + (`!c net. (\z. c) real_differentiable net`, + REWRITE_TAC[real_differentiable] THEN + MESON_TAC[HAS_REAL_DERIVATIVE_CONST]);; + +let REAL_DIFFERENTIABLE_ID = prove + (`!net. (\z. z) real_differentiable net`, + REWRITE_TAC[real_differentiable] THEN + MESON_TAC[HAS_REAL_DERIVATIVE_ID]);; + +let REAL_DIFFERENTIABLE_NEG = prove + (`!f net. + f real_differentiable net + ==> (\z. --(f z)) real_differentiable net`, + REWRITE_TAC[real_differentiable] THEN + MESON_TAC[HAS_REAL_DERIVATIVE_NEG]);; + +let REAL_DIFFERENTIABLE_ADD = prove + (`!f g net. + f real_differentiable net /\ + g real_differentiable net + ==> (\z. f z + g z) real_differentiable net`, + REWRITE_TAC[real_differentiable] THEN + MESON_TAC[HAS_REAL_DERIVATIVE_ADD]);; + +let REAL_DIFFERENTIABLE_SUB = prove + (`!f g net. + f real_differentiable net /\ + g real_differentiable net + ==> (\z. f z - g z) real_differentiable net`, + REWRITE_TAC[real_differentiable] THEN + MESON_TAC[HAS_REAL_DERIVATIVE_SUB]);; + +let REAL_DIFFERENTIABLE_INV_WITHIN = prove + (`!f z s. + f real_differentiable (atreal z within s) /\ ~(f z = &0) + ==> (\z. inv(f z)) real_differentiable (atreal z within s)`, + REWRITE_TAC[real_differentiable] THEN + MESON_TAC[HAS_REAL_DERIVATIVE_INV_WITHIN]);; + +let REAL_DIFFERENTIABLE_MUL_WITHIN = prove + (`!f g z s. + f real_differentiable (atreal z within s) /\ + g real_differentiable (atreal z within s) + ==> (\z. f z * g z) real_differentiable (atreal z within s)`, + REWRITE_TAC[real_differentiable] THEN + MESON_TAC[HAS_REAL_DERIVATIVE_MUL_WITHIN]);; + +let REAL_DIFFERENTIABLE_DIV_WITHIN = prove + (`!f g z s. + f real_differentiable (atreal z within s) /\ + g real_differentiable (atreal z within s) /\ + ~(g z = &0) + ==> (\z. f z / g z) real_differentiable (atreal z within s)`, + REWRITE_TAC[real_differentiable] THEN + MESON_TAC[HAS_REAL_DERIVATIVE_DIV_WITHIN]);; + +let REAL_DIFFERENTIABLE_POW_WITHIN = prove + (`!f n z s. + f real_differentiable (atreal z within s) + ==> (\z. f z pow n) real_differentiable (atreal z within s)`, + REWRITE_TAC[real_differentiable] THEN + MESON_TAC[HAS_REAL_DERIVATIVE_POW_WITHIN]);; + +let REAL_DIFFERENTIABLE_TRANSFORM_WITHIN = prove + (`!f g x s d. + &0 < d /\ + x IN s /\ + (!x'. x' IN s /\ abs(x' - x) < d ==> f x' = g x') /\ + f real_differentiable (atreal x within s) + ==> g real_differentiable (atreal x within s)`, + REWRITE_TAC[real_differentiable] THEN + MESON_TAC[HAS_REAL_DERIVATIVE_TRANSFORM_WITHIN]);; + +let REAL_DIFFERENTIABLE_TRANSFORM = prove + (`!f g s. (!x. x IN s ==> f x = g x) /\ f real_differentiable_on s + ==> g real_differentiable_on s`, + REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + REWRITE_TAC[real_differentiable_on; GSYM real_differentiable] THEN + MATCH_MP_TAC MONO_FORALL THEN GEN_TAC THEN + DISCH_THEN(fun th -> DISCH_TAC THEN MP_TAC th) THEN + ASM_REWRITE_TAC[] THEN DISCH_TAC THEN + MATCH_MP_TAC REAL_DIFFERENTIABLE_TRANSFORM_WITHIN THEN + MAP_EVERY EXISTS_TAC [`f:real->real`; `&1`] THEN + ASM_SIMP_TAC[REAL_LT_01]);; + +let REAL_DIFFERENTIABLE_EQ = prove + (`!f g s. (!x. x IN s ==> f x = g x) + ==> (f real_differentiable_on s <=> g real_differentiable_on s)`, + MESON_TAC[REAL_DIFFERENTIABLE_TRANSFORM]);; + +let REAL_DIFFERENTIABLE_INV_ATREAL = prove + (`!f z. + f real_differentiable atreal z /\ ~(f z = &0) + ==> (\z. inv(f z)) real_differentiable atreal z`, + REWRITE_TAC[real_differentiable] THEN + MESON_TAC[HAS_REAL_DERIVATIVE_INV_ATREAL]);; + +let REAL_DIFFERENTIABLE_MUL_ATREAL = prove + (`!f g z. + f real_differentiable atreal z /\ + g real_differentiable atreal z + ==> (\z. f z * g z) real_differentiable atreal z`, + REWRITE_TAC[real_differentiable] THEN + MESON_TAC[HAS_REAL_DERIVATIVE_MUL_ATREAL]);; + +let REAL_DIFFERENTIABLE_DIV_ATREAL = prove + (`!f g z. + f real_differentiable atreal z /\ + g real_differentiable atreal z /\ + ~(g z = &0) + ==> (\z. f z / g z) real_differentiable atreal z`, + REWRITE_TAC[real_differentiable] THEN + MESON_TAC[HAS_REAL_DERIVATIVE_DIV_ATREAL]);; + +let REAL_DIFFERENTIABLE_POW_ATREAL = prove + (`!f n z. + f real_differentiable atreal z + ==> (\z. f z pow n) real_differentiable atreal z`, + REWRITE_TAC[real_differentiable] THEN + MESON_TAC[HAS_REAL_DERIVATIVE_POW_ATREAL]);; + +let REAL_DIFFERENTIABLE_TRANSFORM_ATREAL = prove + (`!f g x d. + &0 < d /\ + (!x'. abs(x' - x) < d ==> f x' = g x') /\ + f real_differentiable atreal x + ==> g real_differentiable atreal x`, + REWRITE_TAC[real_differentiable] THEN + MESON_TAC[HAS_REAL_DERIVATIVE_TRANSFORM_ATREAL]);; + +let REAL_DIFFERENTIABLE_COMPOSE_WITHIN = prove + (`!f g x s. + f real_differentiable (atreal x within s) /\ + g real_differentiable (atreal (f x) within IMAGE f s) + ==> (g o f) real_differentiable (atreal x within s)`, + REWRITE_TAC[real_differentiable] THEN + MESON_TAC[REAL_DIFF_CHAIN_WITHIN]);; + +let REAL_DIFFERENTIABLE_COMPOSE_ATREAL = prove + (`!f g x. + f real_differentiable (atreal x) /\ + g real_differentiable (atreal (f x)) + ==> (g o f) real_differentiable (atreal x)`, + REWRITE_TAC[real_differentiable] THEN + MESON_TAC[REAL_DIFF_CHAIN_ATREAL]);; + +(* ------------------------------------------------------------------------- *) +(* Same again for being differentiable on a set. *) +(* ------------------------------------------------------------------------- *) + +let REAL_DIFFERENTIABLE_ON_CONST = prove + (`!c s. (\z. c) real_differentiable_on s`, + REWRITE_TAC[REAL_DIFFERENTIABLE_ON_DIFFERENTIABLE; + REAL_DIFFERENTIABLE_CONST]);; + +let REAL_DIFFERENTIABLE_ON_ID = prove + (`!s. (\z. z) real_differentiable_on s`, + REWRITE_TAC[REAL_DIFFERENTIABLE_ON_DIFFERENTIABLE; REAL_DIFFERENTIABLE_ID]);; + +let REAL_DIFFERENTIABLE_ON_COMPOSE = prove + (`!f g s. f real_differentiable_on s /\ g real_differentiable_on (IMAGE f s) + ==> (g o f) real_differentiable_on s`, + SIMP_TAC[real_differentiable_on; GSYM real_differentiable; + FORALL_IN_IMAGE] THEN + MESON_TAC[REAL_DIFFERENTIABLE_COMPOSE_WITHIN]);; + +let REAL_DIFFERENTIABLE_ON_NEG = prove + (`!f s. f real_differentiable_on s ==> (\z. --(f z)) real_differentiable_on s`, + SIMP_TAC[REAL_DIFFERENTIABLE_ON_DIFFERENTIABLE; REAL_DIFFERENTIABLE_NEG]);; + +let REAL_DIFFERENTIABLE_ON_ADD = prove + (`!f g s. + f real_differentiable_on s /\ g real_differentiable_on s + ==> (\z. f z + g z) real_differentiable_on s`, + SIMP_TAC[REAL_DIFFERENTIABLE_ON_DIFFERENTIABLE; REAL_DIFFERENTIABLE_ADD]);; + +let REAL_DIFFERENTIABLE_ON_SUB = prove + (`!f g s. + f real_differentiable_on s /\ g real_differentiable_on s + ==> (\z. f z - g z) real_differentiable_on s`, + SIMP_TAC[REAL_DIFFERENTIABLE_ON_DIFFERENTIABLE; REAL_DIFFERENTIABLE_SUB]);; + +let REAL_DIFFERENTIABLE_ON_MUL = prove + (`!f g s. + f real_differentiable_on s /\ g real_differentiable_on s + ==> (\z. f z * g z) real_differentiable_on s`, + SIMP_TAC[REAL_DIFFERENTIABLE_ON_DIFFERENTIABLE; + REAL_DIFFERENTIABLE_MUL_WITHIN]);; + +let REAL_DIFFERENTIABLE_ON_INV = prove + (`!f s. f real_differentiable_on s /\ (!z. z IN s ==> ~(f z = &0)) + ==> (\z. inv(f z)) real_differentiable_on s`, + SIMP_TAC[REAL_DIFFERENTIABLE_ON_DIFFERENTIABLE; + REAL_DIFFERENTIABLE_INV_WITHIN]);; + +let REAL_DIFFERENTIABLE_ON_DIV = prove + (`!f g s. + f real_differentiable_on s /\ g real_differentiable_on s /\ + (!z. z IN s ==> ~(g z = &0)) + ==> (\z. f z / g z) real_differentiable_on s`, + SIMP_TAC[REAL_DIFFERENTIABLE_ON_DIFFERENTIABLE; + REAL_DIFFERENTIABLE_DIV_WITHIN]);; + +let REAL_DIFFERENTIABLE_ON_POW = prove + (`!f s n. f real_differentiable_on s + ==> (\z. (f z) pow n) real_differentiable_on s`, + SIMP_TAC[REAL_DIFFERENTIABLE_ON_DIFFERENTIABLE; + REAL_DIFFERENTIABLE_POW_WITHIN]);; + +let REAL_DIFFERENTIABLE_ON_SUM = prove + (`!f s k. FINITE k /\ (!a. a IN k ==> (f a) real_differentiable_on s) + ==> (\x. sum k (\a. f a x)) real_differentiable_on s`, + GEN_TAC THEN GEN_TAC THEN REWRITE_TAC[IMP_CONJ] THEN + MATCH_MP_TAC FINITE_INDUCT_STRONG THEN SIMP_TAC[SUM_CLAUSES] THEN + SIMP_TAC[REAL_DIFFERENTIABLE_ON_CONST; IN_INSERT; NOT_IN_EMPTY] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_DIFFERENTIABLE_ON_ADD THEN + ASM_SIMP_TAC[ETA_AX]);; + +(* ------------------------------------------------------------------------- *) +(* Derivative (and continuity) theorems for real transcendental functions. *) +(* ------------------------------------------------------------------------- *) + +let HAS_REAL_DERIVATIVE_EXP = prove + (`!x. (exp has_real_derivative exp(x)) (atreal x)`, + GEN_TAC THEN MATCH_MP_TAC HAS_COMPLEX_REAL_DERIVATIVE_AT THEN + EXISTS_TAC `cexp` THEN + ASM_SIMP_TAC[HAS_COMPLEX_DERIVATIVE_AT_WITHIN; + HAS_COMPLEX_DERIVATIVE_CEXP; CX_EXP]);; + +let REAL_DIFFERENTIABLE_AT_EXP = prove + (`!x. exp real_differentiable (atreal x)`, + REWRITE_TAC[real_differentiable] THEN + MESON_TAC[HAS_REAL_DERIVATIVE_EXP]);; + +let REAL_DIFFERENTIABLE_WITHIN_EXP = prove + (`!s x. exp real_differentiable (atreal x within s)`, + MESON_TAC[REAL_DIFFERENTIABLE_ATREAL_WITHIN; + REAL_DIFFERENTIABLE_AT_EXP]);; + +let REAL_CONTINUOUS_AT_EXP = prove + (`!x. exp real_continuous (atreal x)`, + MESON_TAC[HAS_REAL_DERIVATIVE_EXP; + HAS_REAL_DERIVATIVE_IMP_CONTINUOUS_ATREAL]);; + +let REAL_CONTINUOUS_WITHIN_EXP = prove + (`!s x. exp real_continuous (atreal x within s)`, + MESON_TAC[REAL_CONTINUOUS_ATREAL_WITHINREAL; + REAL_CONTINUOUS_AT_EXP]);; + +let REAL_CONTINUOUS_ON_EXP = prove + (`!s. exp real_continuous_on s`, + REWRITE_TAC[REAL_CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN; + REAL_CONTINUOUS_WITHIN_EXP]);; + +let HAS_REAL_DERIVATIVE_SIN = prove + (`!x. (sin has_real_derivative cos(x)) (atreal x)`, + GEN_TAC THEN MATCH_MP_TAC HAS_COMPLEX_REAL_DERIVATIVE_AT THEN + EXISTS_TAC `csin` THEN + ASM_SIMP_TAC[HAS_COMPLEX_DERIVATIVE_AT_WITHIN; + HAS_COMPLEX_DERIVATIVE_CSIN; CX_SIN; CX_COS]);; + +let REAL_DIFFERENTIABLE_AT_SIN = prove + (`!x. sin real_differentiable (atreal x)`, + REWRITE_TAC[real_differentiable] THEN + MESON_TAC[HAS_REAL_DERIVATIVE_SIN]);; + +let REAL_DIFFERENTIABLE_WITHIN_SIN = prove + (`!s x. sin real_differentiable (atreal x within s)`, + MESON_TAC[REAL_DIFFERENTIABLE_ATREAL_WITHIN; + REAL_DIFFERENTIABLE_AT_SIN]);; + +let REAL_CONTINUOUS_AT_SIN = prove + (`!x. sin real_continuous (atreal x)`, + MESON_TAC[HAS_REAL_DERIVATIVE_SIN; + HAS_REAL_DERIVATIVE_IMP_CONTINUOUS_ATREAL]);; + +let REAL_CONTINUOUS_WITHIN_SIN = prove + (`!s x. sin real_continuous (atreal x within s)`, + MESON_TAC[REAL_CONTINUOUS_ATREAL_WITHINREAL; + REAL_CONTINUOUS_AT_SIN]);; + +let REAL_CONTINUOUS_ON_SIN = prove + (`!s. sin real_continuous_on s`, + REWRITE_TAC[REAL_CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN; + REAL_CONTINUOUS_WITHIN_SIN]);; + +let HAS_REAL_DERIVATIVE_COS = prove + (`!x. (cos has_real_derivative --sin(x)) (atreal x)`, + GEN_TAC THEN MATCH_MP_TAC HAS_COMPLEX_REAL_DERIVATIVE_AT THEN + EXISTS_TAC `ccos` THEN + ASM_SIMP_TAC[HAS_COMPLEX_DERIVATIVE_AT_WITHIN; + HAS_COMPLEX_DERIVATIVE_CCOS; CX_SIN; CX_COS; CX_NEG]);; + +let REAL_DIFFERENTIABLE_AT_COS = prove + (`!x. cos real_differentiable (atreal x)`, + REWRITE_TAC[real_differentiable] THEN + MESON_TAC[HAS_REAL_DERIVATIVE_COS]);; + +let REAL_DIFFERENTIABLE_WITHIN_COS = prove + (`!s x. cos real_differentiable (atreal x within s)`, + MESON_TAC[REAL_DIFFERENTIABLE_ATREAL_WITHIN; + REAL_DIFFERENTIABLE_AT_COS]);; + +let REAL_CONTINUOUS_AT_COS = prove + (`!x. cos real_continuous (atreal x)`, + MESON_TAC[HAS_REAL_DERIVATIVE_COS; + HAS_REAL_DERIVATIVE_IMP_CONTINUOUS_ATREAL]);; + +let REAL_CONTINUOUS_WITHIN_COS = prove + (`!s x. cos real_continuous (atreal x within s)`, + MESON_TAC[REAL_CONTINUOUS_ATREAL_WITHINREAL; + REAL_CONTINUOUS_AT_COS]);; + +let REAL_CONTINUOUS_ON_COS = prove + (`!s. cos real_continuous_on s`, + REWRITE_TAC[REAL_CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN; + REAL_CONTINUOUS_WITHIN_COS]);; + +let HAS_REAL_DERIVATIVE_TAN = prove + (`!x. ~(cos x = &0) + ==> (tan has_real_derivative inv(cos(x) pow 2)) (atreal x)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_COMPLEX_REAL_DERIVATIVE_AT THEN + EXISTS_TAC `ctan` THEN REWRITE_TAC[CX_INV; CX_POW; CX_COS] THEN + ASM_SIMP_TAC[HAS_COMPLEX_DERIVATIVE_AT_WITHIN; + HAS_COMPLEX_DERIVATIVE_CTAN; GSYM CX_COS; CX_INJ; CX_TAN]);; + +let REAL_DIFFERENTIABLE_AT_TAN = prove + (`!x. ~(cos x = &0) ==> tan real_differentiable (atreal x)`, + REWRITE_TAC[real_differentiable] THEN + MESON_TAC[HAS_REAL_DERIVATIVE_TAN]);; + +let REAL_DIFFERENTIABLE_WITHIN_TAN = prove + (`!s x. ~(cos x = &0) ==> tan real_differentiable (atreal x within s)`, + MESON_TAC[REAL_DIFFERENTIABLE_ATREAL_WITHIN; + REAL_DIFFERENTIABLE_AT_TAN]);; + +let REAL_CONTINUOUS_AT_TAN = prove + (`!x. ~(cos x = &0) ==> tan real_continuous (atreal x)`, + MESON_TAC[HAS_REAL_DERIVATIVE_TAN; + HAS_REAL_DERIVATIVE_IMP_CONTINUOUS_ATREAL]);; + +let REAL_CONTINUOUS_WITHIN_TAN = prove + (`!s x. ~(cos x = &0) ==> tan real_continuous (atreal x within s)`, + MESON_TAC[REAL_CONTINUOUS_ATREAL_WITHINREAL; + REAL_CONTINUOUS_AT_TAN]);; + +let REAL_CONTINUOUS_ON_TAN = prove + (`!s. (!x. x IN s ==> ~(cos x = &0)) ==> tan real_continuous_on s`, + MESON_TAC[REAL_CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN; + REAL_CONTINUOUS_WITHIN_TAN]);; + +let HAS_REAL_DERIVATIVE_LOG = prove + (`!x. &0 < x ==> (log has_real_derivative inv(x)) (atreal x)`, + REPEAT STRIP_TAC THEN + MATCH_MP_TAC HAS_COMPLEX_REAL_DERIVATIVE_AT_GEN THEN + MAP_EVERY EXISTS_TAC [`clog`; `x:real`] THEN ASM_REWRITE_TAC[] THEN + REPEAT STRIP_TAC THENL + [REWRITE_TAC[CX_INV] THEN MATCH_MP_TAC HAS_COMPLEX_DERIVATIVE_AT_WITHIN THEN + MATCH_MP_TAC HAS_COMPLEX_DERIVATIVE_CLOG THEN ASM_REWRITE_TAC[RE_CX]; + MATCH_MP_TAC(GSYM CX_LOG) THEN ASM_REAL_ARITH_TAC]);; + +let REAL_DIFFERENTIABLE_AT_LOG = prove + (`!x. &0 < x ==> log real_differentiable (atreal x)`, + REWRITE_TAC[real_differentiable] THEN + MESON_TAC[HAS_REAL_DERIVATIVE_LOG]);; + +let REAL_DIFFERENTIABLE_WITHIN_LOG = prove + (`!s x. &0 < x ==> log real_differentiable (atreal x within s)`, + MESON_TAC[REAL_DIFFERENTIABLE_ATREAL_WITHIN; + REAL_DIFFERENTIABLE_AT_LOG]);; + +let REAL_CONTINUOUS_AT_LOG = prove + (`!x. &0 < x ==> log real_continuous (atreal x)`, + MESON_TAC[HAS_REAL_DERIVATIVE_LOG; + HAS_REAL_DERIVATIVE_IMP_CONTINUOUS_ATREAL]);; + +let REAL_CONTINUOUS_WITHIN_LOG = prove + (`!s x. &0 < x ==> log real_continuous (atreal x within s)`, + MESON_TAC[REAL_CONTINUOUS_ATREAL_WITHINREAL; + REAL_CONTINUOUS_AT_LOG]);; + +let REAL_CONTINUOUS_ON_LOG = prove + (`!s. (!x. x IN s ==> &0 < x) ==> log real_continuous_on s`, + MESON_TAC[REAL_CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN; + REAL_CONTINUOUS_WITHIN_LOG]);; + +let HAS_REAL_DERIVATIVE_SQRT = prove + (`!x. &0 < x ==> (sqrt has_real_derivative inv(&2 * sqrt x)) (atreal x)`, + REPEAT STRIP_TAC THEN + MATCH_MP_TAC HAS_COMPLEX_REAL_DERIVATIVE_AT_GEN THEN + MAP_EVERY EXISTS_TAC [`csqrt`; `x:real`] THEN ASM_REWRITE_TAC[] THEN + REPEAT STRIP_TAC THENL + [ASM_SIMP_TAC[CX_INV; CX_MUL; CX_SQRT; REAL_LT_IMP_LE] THEN + MATCH_MP_TAC HAS_COMPLEX_DERIVATIVE_AT_WITHIN THEN + MATCH_MP_TAC HAS_COMPLEX_DERIVATIVE_CSQRT THEN + ASM_SIMP_TAC[RE_CX]; + MATCH_MP_TAC(GSYM CX_SQRT) THEN ASM_REAL_ARITH_TAC]);; + +let REAL_DIFFERENTIABLE_AT_SQRT = prove + (`!x. &0 < x ==> sqrt real_differentiable (atreal x)`, + REWRITE_TAC[real_differentiable] THEN + MESON_TAC[HAS_REAL_DERIVATIVE_SQRT]);; + +let REAL_DIFFERENTIABLE_WITHIN_SQRT = prove + (`!s x. &0 < x ==> sqrt real_differentiable (atreal x within s)`, + MESON_TAC[REAL_DIFFERENTIABLE_ATREAL_WITHIN; + REAL_DIFFERENTIABLE_AT_SQRT]);; + +let REAL_CONTINUOUS_AT_SQRT = prove + (`!x. &0 < x ==> sqrt real_continuous (atreal x)`, + MESON_TAC[HAS_REAL_DERIVATIVE_SQRT; + HAS_REAL_DERIVATIVE_IMP_CONTINUOUS_ATREAL]);; + +let REAL_CONTINUOUS_WITHIN_SQRT = prove + (`!s x. &0 < x ==> sqrt real_continuous (atreal x within s)`, + MESON_TAC[REAL_CONTINUOUS_ATREAL_WITHINREAL; + REAL_CONTINUOUS_AT_SQRT]);; + +let REAL_CONTINUOUS_WITHIN_SQRT_COMPOSE = prove + (`!f s a:real^N. + f real_continuous (at a within s) /\ + (&0 < f a \/ !x. x IN s ==> &0 <= f x) + ==> (\x. sqrt(f x)) real_continuous (at a within s)`, + REWRITE_TAC[REAL_CONTINUOUS_CONTINUOUS1; o_DEF] THEN + REWRITE_TAC[CONTINUOUS_WITHIN_SQRT_COMPOSE]);; + +let REAL_CONTINUOUS_AT_SQRT_COMPOSE = prove + (`!f a:real^N. + f real_continuous (at a) /\ + (&0 < f a \/ !x. &0 <= f x) + ==> (\x. sqrt(f x)) real_continuous (at a)`, + REWRITE_TAC[REAL_CONTINUOUS_CONTINUOUS1; o_DEF] THEN + REWRITE_TAC[CONTINUOUS_AT_SQRT_COMPOSE]);; + +let CONTINUOUS_WITHINREAL_SQRT_COMPOSE = prove + (`!f s a. (\x. lift(f x)) continuous (atreal a within s) /\ + (&0 < f a \/ !x. x IN s ==> &0 <= f x) + ==> (\x. lift(sqrt(f x))) continuous (atreal a within s)`, + REWRITE_TAC[CONTINUOUS_CONTINUOUS_WITHINREAL] THEN + REWRITE_TAC[o_DEF] THEN REPEAT GEN_TAC THEN DISCH_TAC THEN + MATCH_MP_TAC CONTINUOUS_WITHIN_SQRT_COMPOSE THEN + ASM_REWRITE_TAC[FORALL_IN_IMAGE; LIFT_DROP]);; + +let CONTINUOUS_ATREAL_SQRT_COMPOSE = prove + (`!f a. (\x. lift(f x)) continuous (atreal a) /\ (&0 < f a \/ !x. &0 <= f x) + ==> (\x. lift(sqrt(f x))) continuous (atreal a)`, + REPEAT GEN_TAC THEN + MP_TAC(ISPECL [`f:real->real`; `(:real)`; `a:real`] + CONTINUOUS_WITHINREAL_SQRT_COMPOSE) THEN + REWRITE_TAC[WITHINREAL_UNIV; IN_UNIV]);; + +let REAL_CONTINUOUS_WITHINREAL_SQRT_COMPOSE = prove + (`!f s a. f real_continuous (atreal a within s) /\ + (&0 < f a \/ !x. x IN s ==> &0 <= f x) + ==> (\x. sqrt(f x)) real_continuous (atreal a within s)`, + REWRITE_TAC[REAL_CONTINUOUS_CONTINUOUS1; o_DEF] THEN + REWRITE_TAC[CONTINUOUS_WITHINREAL_SQRT_COMPOSE]);; + +let REAL_CONTINUOUS_ATREAL_SQRT_COMPOSE = prove + (`!f a. f real_continuous (atreal a) /\ + (&0 < f a \/ !x. &0 <= f x) + ==> (\x. sqrt(f x)) real_continuous (atreal a)`, + REWRITE_TAC[REAL_CONTINUOUS_CONTINUOUS1; o_DEF] THEN + REWRITE_TAC[CONTINUOUS_ATREAL_SQRT_COMPOSE]);; + +let HAS_REAL_DERIVATIVE_ATN = prove + (`!x. (atn has_real_derivative inv(&1 + x pow 2)) (atreal x)`, + GEN_TAC THEN MATCH_MP_TAC HAS_COMPLEX_REAL_DERIVATIVE_AT THEN + EXISTS_TAC `catn` THEN REWRITE_TAC[CX_INV; CX_ADD; CX_ATN; CX_POW] THEN + ASM_SIMP_TAC[HAS_COMPLEX_DERIVATIVE_AT_WITHIN; HAS_COMPLEX_DERIVATIVE_CATN; + IM_CX; REAL_ABS_NUM; REAL_LT_01]);; + +let REAL_DIFFERENTIABLE_AT_ATN = prove + (`!x. atn real_differentiable (atreal x)`, + REWRITE_TAC[real_differentiable] THEN + MESON_TAC[HAS_REAL_DERIVATIVE_ATN]);; + +let REAL_DIFFERENTIABLE_WITHIN_ATN = prove + (`!s x. atn real_differentiable (atreal x within s)`, + MESON_TAC[REAL_DIFFERENTIABLE_ATREAL_WITHIN; + REAL_DIFFERENTIABLE_AT_ATN]);; + +let REAL_CONTINUOUS_AT_ATN = prove + (`!x. atn real_continuous (atreal x)`, + MESON_TAC[HAS_REAL_DERIVATIVE_ATN; + HAS_REAL_DERIVATIVE_IMP_CONTINUOUS_ATREAL]);; + +let REAL_CONTINUOUS_WITHIN_ATN = prove + (`!s x. atn real_continuous (atreal x within s)`, + MESON_TAC[REAL_CONTINUOUS_ATREAL_WITHINREAL; + REAL_CONTINUOUS_AT_ATN]);; + +let REAL_CONTINUOUS_ON_ATN = prove + (`!s. atn real_continuous_on s`, + REWRITE_TAC[REAL_CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN; + REAL_CONTINUOUS_WITHIN_ATN]);; + +let HAS_REAL_DERIVATIVE_ASN_COS = prove + (`!x. abs(x) < &1 ==> (asn has_real_derivative inv(cos(asn x))) (atreal x)`, + REPEAT STRIP_TAC THEN + MATCH_MP_TAC HAS_COMPLEX_REAL_DERIVATIVE_AT_GEN THEN + MAP_EVERY EXISTS_TAC [`casn`; `&1 - abs x`] THEN + ASM_REWRITE_TAC[REAL_SUB_LT] THEN REPEAT STRIP_TAC THENL + [ASM_SIMP_TAC[CX_INV; CX_COS; CX_ASN; REAL_LT_IMP_LE] THEN + MATCH_MP_TAC HAS_COMPLEX_DERIVATIVE_AT_WITHIN THEN + MATCH_MP_TAC HAS_COMPLEX_DERIVATIVE_CASN THEN ASM_REWRITE_TAC[RE_CX]; + MATCH_MP_TAC(GSYM CX_ASN) THEN ASM_REAL_ARITH_TAC]);; + +let HAS_REAL_DERIVATIVE_ASN = prove + (`!x. abs(x) < &1 + ==> (asn has_real_derivative inv(sqrt(&1 - x pow 2))) (atreal x)`, + REPEAT STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o MATCH_MP HAS_REAL_DERIVATIVE_ASN_COS) THEN + MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_TERM_TAC THEN + AP_TERM_TAC THEN MATCH_MP_TAC COS_ASN THEN ASM_REAL_ARITH_TAC);; + +let REAL_DIFFERENTIABLE_AT_ASN = prove + (`!x. abs(x) < &1 ==> asn real_differentiable (atreal x)`, + REWRITE_TAC[real_differentiable] THEN + MESON_TAC[HAS_REAL_DERIVATIVE_ASN]);; + +let REAL_DIFFERENTIABLE_WITHIN_ASN = prove + (`!s x. abs(x) < &1 ==> asn real_differentiable (atreal x within s)`, + MESON_TAC[REAL_DIFFERENTIABLE_ATREAL_WITHIN; + REAL_DIFFERENTIABLE_AT_ASN]);; + +let REAL_CONTINUOUS_AT_ASN = prove + (`!x. abs(x) < &1 ==> asn real_continuous (atreal x)`, + MESON_TAC[HAS_REAL_DERIVATIVE_ASN; + HAS_REAL_DERIVATIVE_IMP_CONTINUOUS_ATREAL]);; + +let REAL_CONTINUOUS_WITHIN_ASN = prove + (`!s x. abs(x) < &1 ==> asn real_continuous (atreal x within s)`, + MESON_TAC[REAL_CONTINUOUS_ATREAL_WITHINREAL; + REAL_CONTINUOUS_AT_ASN]);; + +let HAS_REAL_DERIVATIVE_ACS_SIN = prove + (`!x. abs(x) < &1 ==> (acs has_real_derivative --inv(sin(acs x))) (atreal x)`, + REPEAT STRIP_TAC THEN + MATCH_MP_TAC HAS_COMPLEX_REAL_DERIVATIVE_AT_GEN THEN + MAP_EVERY EXISTS_TAC [`cacs`; `&1 - abs x`] THEN + ASM_REWRITE_TAC[REAL_SUB_LT] THEN REPEAT STRIP_TAC THENL + [ASM_SIMP_TAC[CX_INV; CX_SIN; CX_ACS; CX_NEG; REAL_LT_IMP_LE] THEN + MATCH_MP_TAC HAS_COMPLEX_DERIVATIVE_AT_WITHIN THEN + MATCH_MP_TAC HAS_COMPLEX_DERIVATIVE_CACS THEN ASM_REWRITE_TAC[RE_CX]; + MATCH_MP_TAC(GSYM CX_ACS) THEN ASM_REAL_ARITH_TAC]);; + +let HAS_REAL_DERIVATIVE_ACS = prove + (`!x. abs(x) < &1 + ==> (acs has_real_derivative --inv(sqrt(&1 - x pow 2))) (atreal x)`, + REPEAT STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o MATCH_MP HAS_REAL_DERIVATIVE_ACS_SIN) THEN + MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_TERM_TAC THEN + AP_TERM_TAC THEN AP_TERM_TAC THEN + MATCH_MP_TAC SIN_ACS THEN ASM_REAL_ARITH_TAC);; + +let REAL_DIFFERENTIABLE_AT_ACS = prove + (`!x. abs(x) < &1 ==> acs real_differentiable (atreal x)`, + REWRITE_TAC[real_differentiable] THEN + MESON_TAC[HAS_REAL_DERIVATIVE_ACS]);; + +let REAL_DIFFERENTIABLE_WITHIN_ACS = prove + (`!s x. abs(x) < &1 ==> acs real_differentiable (atreal x within s)`, + MESON_TAC[REAL_DIFFERENTIABLE_ATREAL_WITHIN; + REAL_DIFFERENTIABLE_AT_ACS]);; + +let REAL_CONTINUOUS_AT_ACS = prove + (`!x. abs(x) < &1 ==> acs real_continuous (atreal x)`, + MESON_TAC[HAS_REAL_DERIVATIVE_ACS; + HAS_REAL_DERIVATIVE_IMP_CONTINUOUS_ATREAL]);; + +let REAL_CONTINUOUS_WITHIN_ACS = prove + (`!s x. abs(x) < &1 ==> acs real_continuous (atreal x within s)`, + MESON_TAC[REAL_CONTINUOUS_ATREAL_WITHINREAL; + REAL_CONTINUOUS_AT_ACS]);; + +(* ------------------------------------------------------------------------- *) +(* Hence differentiation of the norm. *) +(* ------------------------------------------------------------------------- *) + +let DIFFERENTIABLE_NORM_AT = prove + (`!a:real^N. ~(a = vec 0) ==> (\x. lift(norm x)) differentiable (at a)`, + REPEAT STRIP_TAC THEN REWRITE_TAC[vector_norm] THEN + SUBGOAL_THEN + `(\x:real^N. lift(sqrt(x dot x))) = + (lift o sqrt o drop) o (\x. lift(x dot x))` + SUBST1_TAC THENL [REWRITE_TAC[o_DEF; LIFT_DROP]; ALL_TAC] THEN + MATCH_MP_TAC DIFFERENTIABLE_CHAIN_AT THEN + REWRITE_TAC[DIFFERENTIABLE_SQNORM_AT; GSYM NORM_POW_2] THEN + MP_TAC(ISPEC `norm(a:real^N) pow 2` REAL_DIFFERENTIABLE_AT_SQRT) THEN + ASM_SIMP_TAC[REAL_POW_LT; NORM_POS_LT; REAL_DIFFERENTIABLE_AT]);; + +let DIFFERENTIABLE_ON_NORM = prove + (`!s:real^N->bool. ~(vec 0 IN s) ==> (\x. lift(norm x)) differentiable_on s`, + REPEAT STRIP_TAC THEN + MATCH_MP_TAC DIFFERENTIABLE_AT_IMP_DIFFERENTIABLE_ON THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC DIFFERENTIABLE_NORM_AT THEN + ASM_MESON_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* Some somewhat sharper continuity theorems including endpoints. *) +(* ------------------------------------------------------------------------- *) + +let REAL_CONTINUOUS_WITHIN_SQRT_STRONG = prove + (`!x. sqrt real_continuous (atreal x within {t | &0 <= t})`, + GEN_TAC THEN REWRITE_TAC[REAL_COMPLEX_CONTINUOUS_WITHINREAL] THEN + ASM_CASES_TAC `x IN {t | &0 <= t}` THENL + [MATCH_MP_TAC CONTINUOUS_TRANSFORM_WITHIN THEN + MAP_EVERY EXISTS_TAC [`csqrt`; `&1`] THEN + REWRITE_TAC[IMAGE_CX; IN_ELIM_THM; REAL_LT_01; + CONTINUOUS_WITHIN_CSQRT_POSREAL; + SET_RULE `real INTER {z | real z /\ P z} = {z | real z /\ P z}`] THEN + RULE_ASSUM_TAC(REWRITE_RULE[IN_ELIM_THM]) THEN + ASM_REWRITE_TAC[REAL_CX; RE_CX; IMP_CONJ; FORALL_REAL; o_THM] THEN + SIMP_TAC[CX_SQRT]; + MATCH_MP_TAC CONTINUOUS_WITHIN_CLOSED_NONTRIVIAL THEN CONJ_TAC THENL + [SUBGOAL_THEN `real INTER IMAGE Cx {t | &0 <= t} = + real INTER {t | Re t >= &0}` + (fun th -> SIMP_TAC[th; CLOSED_INTER; CLOSED_REAL; + CLOSED_HALFSPACE_RE_GE]) THEN + REWRITE_TAC[EXTENSION; IMAGE_CX; IN_ELIM_THM; IN_CBALL; IN_INTER] THEN + REWRITE_TAC[real_ge; IN; CONJ_ACI]; + MATCH_MP_TAC(SET_RULE + `(!x y. f x = f y ==> x = y) /\ ~(x IN s) + ==> ~(f x IN t INTER IMAGE f s)`) THEN + ASM_REWRITE_TAC[CX_INJ]]]);; + +let REAL_CONTINUOUS_ON_SQRT = prove + (`!s. (!x. x IN s ==> &0 <= x) ==> sqrt real_continuous_on s`, + REWRITE_TAC[REAL_CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_CONTINUOUS_WITHINREAL_SUBSET THEN + EXISTS_TAC `{x | &0 <= x}` THEN + ASM_REWRITE_TAC[SUBSET; IN_ELIM_THM; REAL_CONTINUOUS_WITHIN_SQRT_STRONG]);; + +let REAL_CONTINUOUS_WITHIN_ASN_STRONG = prove + (`!x. asn real_continuous (atreal x within {t | abs(t) <= &1})`, + GEN_TAC THEN REWRITE_TAC[REAL_COMPLEX_CONTINUOUS_WITHINREAL] THEN + ASM_CASES_TAC `x IN {t | abs(t) <= &1}` THENL + [MATCH_MP_TAC CONTINUOUS_TRANSFORM_WITHIN THEN + MAP_EVERY EXISTS_TAC [`casn`; `&1`] THEN + REWRITE_TAC[IMAGE_CX; IN_ELIM_THM; CONTINUOUS_WITHIN_CASN_REAL; REAL_LT_01; + SET_RULE `real INTER {z | real z /\ P z} = {z | real z /\ P z}`] THEN + RULE_ASSUM_TAC(REWRITE_RULE[IN_ELIM_THM]) THEN + ASM_REWRITE_TAC[REAL_CX; RE_CX; IMP_CONJ; FORALL_REAL; o_THM] THEN + SIMP_TAC[CX_ASN]; + MATCH_MP_TAC CONTINUOUS_WITHIN_CLOSED_NONTRIVIAL THEN CONJ_TAC THENL + [SUBGOAL_THEN `real INTER IMAGE Cx {t | abs t <= &1} = + real INTER cball(Cx(&0),&1)` + (fun th -> SIMP_TAC[th; CLOSED_INTER; CLOSED_REAL; CLOSED_CBALL]) THEN + REWRITE_TAC[EXTENSION; IMAGE_CX; IN_ELIM_THM; IN_CBALL; IN_INTER] THEN + REWRITE_TAC[dist; COMPLEX_SUB_LZERO; NORM_NEG; IN] THEN + MESON_TAC[REAL_NORM]; + MATCH_MP_TAC(SET_RULE + `(!x y. f x = f y ==> x = y) /\ ~(x IN s) + ==> ~(f x IN t INTER IMAGE f s)`) THEN + ASM_REWRITE_TAC[CX_INJ]]]);; + +let REAL_CONTINUOUS_ON_ASN = prove + (`!s. (!x. x IN s ==> abs(x) <= &1) ==> asn real_continuous_on s`, + REWRITE_TAC[REAL_CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_CONTINUOUS_WITHINREAL_SUBSET THEN + EXISTS_TAC `{x | abs(x) <= &1}` THEN + ASM_REWRITE_TAC[SUBSET; IN_ELIM_THM; REAL_CONTINUOUS_WITHIN_ASN_STRONG]);; + +let REAL_CONTINUOUS_WITHIN_ACS_STRONG = prove + (`!x. acs real_continuous (atreal x within {t | abs(t) <= &1})`, + GEN_TAC THEN REWRITE_TAC[REAL_COMPLEX_CONTINUOUS_WITHINREAL] THEN + ASM_CASES_TAC `x IN {t | abs(t) <= &1}` THENL + [MATCH_MP_TAC CONTINUOUS_TRANSFORM_WITHIN THEN + MAP_EVERY EXISTS_TAC [`cacs`; `&1`] THEN + REWRITE_TAC[IMAGE_CX; IN_ELIM_THM; CONTINUOUS_WITHIN_CACS_REAL; REAL_LT_01; + SET_RULE `real INTER {z | real z /\ P z} = {z | real z /\ P z}`] THEN + RULE_ASSUM_TAC(REWRITE_RULE[IN_ELIM_THM]) THEN + ASM_REWRITE_TAC[REAL_CX; RE_CX; IMP_CONJ; FORALL_REAL; o_THM] THEN + SIMP_TAC[CX_ACS]; + MATCH_MP_TAC CONTINUOUS_WITHIN_CLOSED_NONTRIVIAL THEN CONJ_TAC THENL + [SUBGOAL_THEN `real INTER IMAGE Cx {t | abs t <= &1} = + real INTER cball(Cx(&0),&1)` + (fun th -> SIMP_TAC[th; CLOSED_INTER; CLOSED_REAL; CLOSED_CBALL]) THEN + REWRITE_TAC[EXTENSION; IMAGE_CX; IN_ELIM_THM; IN_CBALL; IN_INTER] THEN + REWRITE_TAC[dist; COMPLEX_SUB_LZERO; NORM_NEG; IN] THEN + MESON_TAC[REAL_NORM]; + MATCH_MP_TAC(SET_RULE + `(!x y. f x = f y ==> x = y) /\ ~(x IN s) + ==> ~(f x IN t INTER IMAGE f s)`) THEN + ASM_REWRITE_TAC[CX_INJ]]]);; + +let REAL_CONTINUOUS_ON_ACS = prove + (`!s. (!x. x IN s ==> abs(x) <= &1) ==> acs real_continuous_on s`, + REWRITE_TAC[REAL_CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_CONTINUOUS_WITHINREAL_SUBSET THEN + EXISTS_TAC `{x | abs(x) <= &1}` THEN + ASM_REWRITE_TAC[SUBSET; IN_ELIM_THM; REAL_CONTINUOUS_WITHIN_ACS_STRONG]);; + +(* ------------------------------------------------------------------------- *) +(* Differentiation conversion. *) +(* ------------------------------------------------------------------------- *) + +let real_differentiation_theorems = ref [];; + +let add_real_differentiation_theorems = + let ETA_THM = prove + (`(f has_real_derivative f') net <=> + ((\x. f x) has_real_derivative f') net`, + REWRITE_TAC[ETA_AX]) in + let ETA_TWEAK = + PURE_REWRITE_RULE [IMP_CONJ] o + GEN_REWRITE_RULE (LAND_CONV o ONCE_DEPTH_CONV) [ETA_THM] o + SPEC_ALL in + fun l -> real_differentiation_theorems := + !real_differentiation_theorems @ map ETA_TWEAK l;; + +add_real_differentiation_theorems + ([HAS_REAL_DERIVATIVE_LMUL_WITHIN; HAS_REAL_DERIVATIVE_LMUL_ATREAL; + HAS_REAL_DERIVATIVE_RMUL_WITHIN; HAS_REAL_DERIVATIVE_RMUL_ATREAL; + HAS_REAL_DERIVATIVE_CDIV_WITHIN; HAS_REAL_DERIVATIVE_CDIV_ATREAL; + HAS_REAL_DERIVATIVE_ID; + HAS_REAL_DERIVATIVE_CONST; + HAS_REAL_DERIVATIVE_NEG; + HAS_REAL_DERIVATIVE_ADD; + HAS_REAL_DERIVATIVE_SUB; + HAS_REAL_DERIVATIVE_MUL_WITHIN; HAS_REAL_DERIVATIVE_MUL_ATREAL; + HAS_REAL_DERIVATIVE_DIV_WITHIN; HAS_REAL_DERIVATIVE_DIV_ATREAL; + HAS_REAL_DERIVATIVE_POW_WITHIN; HAS_REAL_DERIVATIVE_POW_ATREAL; + HAS_REAL_DERIVATIVE_INV_WITHIN; HAS_REAL_DERIVATIVE_INV_ATREAL] @ + (CONJUNCTS(REWRITE_RULE[FORALL_AND_THM] + (MATCH_MP HAS_REAL_DERIVATIVE_CHAIN_UNIV + HAS_REAL_DERIVATIVE_EXP))) @ + (CONJUNCTS(REWRITE_RULE[FORALL_AND_THM] + (MATCH_MP HAS_REAL_DERIVATIVE_CHAIN_UNIV + HAS_REAL_DERIVATIVE_SIN))) @ + (CONJUNCTS(REWRITE_RULE[FORALL_AND_THM] + (MATCH_MP HAS_REAL_DERIVATIVE_CHAIN_UNIV + HAS_REAL_DERIVATIVE_COS))) @ + (CONJUNCTS(REWRITE_RULE[FORALL_AND_THM] + (MATCH_MP HAS_REAL_DERIVATIVE_CHAIN + HAS_REAL_DERIVATIVE_TAN))) @ + (CONJUNCTS(REWRITE_RULE[FORALL_AND_THM] + (MATCH_MP HAS_REAL_DERIVATIVE_CHAIN + HAS_REAL_DERIVATIVE_LOG))) @ + (CONJUNCTS(REWRITE_RULE[FORALL_AND_THM] + (MATCH_MP HAS_REAL_DERIVATIVE_CHAIN + HAS_REAL_DERIVATIVE_SQRT))) @ + (CONJUNCTS(REWRITE_RULE[FORALL_AND_THM] + (MATCH_MP HAS_REAL_DERIVATIVE_CHAIN_UNIV + HAS_REAL_DERIVATIVE_ATN))) @ + (CONJUNCTS(REWRITE_RULE[FORALL_AND_THM] + (MATCH_MP HAS_REAL_DERIVATIVE_CHAIN + HAS_REAL_DERIVATIVE_ASN))) @ + (CONJUNCTS(REWRITE_RULE[FORALL_AND_THM] + (MATCH_MP HAS_REAL_DERIVATIVE_CHAIN + HAS_REAL_DERIVATIVE_ACS))));; + +let rec REAL_DIFF_CONV = + let partfn tm = let l,r = dest_comb tm in mk_pair(lhand l,r) + and is_deriv = can (term_match [] `(f has_real_derivative f') net`) in + let rec REAL_DIFF_CONV tm = + try tryfind (fun th -> PART_MATCH partfn th (partfn tm)) + (!real_differentiation_theorems) + with Failure _ -> + let ith = tryfind (fun th -> + PART_MATCH (partfn o repeat (snd o dest_imp)) th (partfn tm)) + (!real_differentiation_theorems) in + REAL_DIFF_ELIM ith + and REAL_DIFF_ELIM th = + let tm = concl th in + if not(is_imp tm) then th else + let t = lhand tm in + if not(is_deriv t) then UNDISCH th + else REAL_DIFF_ELIM (MATCH_MP th (REAL_DIFF_CONV t)) in + REAL_DIFF_CONV;; + +(* ------------------------------------------------------------------------- *) +(* Hence a tactic. *) +(* ------------------------------------------------------------------------- *) + +let REAL_DIFF_TAC = + let pth = MESON[] + `(f has_real_derivative f') net + ==> f' = g' + ==> (f has_real_derivative g') net` in + W(fun (asl,w) -> let th = MATCH_MP pth (REAL_DIFF_CONV w) in + MATCH_MP_TAC(repeat (GEN_REWRITE_RULE I [IMP_IMP]) (DISCH_ALL th)));; + +let REAL_DIFFERENTIABLE_TAC = + let DISCH_FIRST th = DISCH (hd(hyp th)) th in + GEN_REWRITE_TAC I [real_differentiable] THEN + W(fun (asl,w) -> + let th = REAL_DIFF_CONV(snd(dest_exists w)) in + let f' = rand(rator(concl th)) in + EXISTS_TAC f' THEN + (if hyp th = [] then MATCH_ACCEPT_TAC th else + let th' = repeat (GEN_REWRITE_RULE I [IMP_IMP] o DISCH_FIRST) + (DISCH_FIRST th) in + MATCH_MP_TAC th'));; + +(* ------------------------------------------------------------------------- *) +(* Analytic results for real power function. *) +(* ------------------------------------------------------------------------- *) + +let HAS_REAL_DERIVATIVE_RPOW = prove + (`!x y. + &0 < x + ==> ((\x. x rpow y) has_real_derivative y * x rpow (y - &1)) (atreal x)`, + REPEAT STRIP_TAC THEN + MATCH_MP_TAC HAS_REAL_DERIVATIVE_TRANSFORM_ATREAL THEN + EXISTS_TAC `\x. exp(y * log x)` THEN EXISTS_TAC `x:real` THEN + ASM_SIMP_TAC[rpow; REAL_ARITH + `&0 < x ==> (abs(y - x) < x <=> &0 < y /\ y < &2 * x)`] THEN + REAL_DIFF_TAC THEN + ASM_SIMP_TAC[REAL_SUB_RDISTRIB; REAL_EXP_SUB; REAL_MUL_LID; EXP_LOG] THEN + REAL_ARITH_TAC);; + +add_real_differentiation_theorems + (CONJUNCTS(REWRITE_RULE[FORALL_AND_THM] + (GEN `y:real` (MATCH_MP HAS_REAL_DERIVATIVE_CHAIN + (SPEC `y:real` + (ONCE_REWRITE_RULE[SWAP_FORALL_THM] HAS_REAL_DERIVATIVE_RPOW))))));; + +let REAL_DIFFERENTIABLE_AT_RPOW = prove + (`!x y. ~(x = &0) ==> (\x. x rpow y) real_differentiable atreal x`, + REPEAT GEN_TAC THEN + REWRITE_TAC[REAL_ARITH `~(x = &0) <=> &0 < x \/ &0 < --x`] THEN + STRIP_TAC THEN MATCH_MP_TAC REAL_DIFFERENTIABLE_TRANSFORM_ATREAL THEN + REWRITE_TAC[] THEN ONCE_REWRITE_TAC[SWAP_EXISTS_THM] THEN + EXISTS_TAC `abs x` THENL + [EXISTS_TAC `\x. exp(y * log x)` THEN + ASM_SIMP_TAC[REAL_ARITH `&0 < x ==> &0 < abs x`] THEN CONJ_TAC THENL + [X_GEN_TAC `z:real` THEN DISCH_TAC THEN + SUBGOAL_THEN `&0 < z` (fun th -> REWRITE_TAC[rpow; th]) THEN + ASM_REAL_ARITH_TAC; + REAL_DIFFERENTIABLE_TAC THEN ASM_REAL_ARITH_TAC]; + ASM_CASES_TAC `?m n. ODD m /\ ODD n /\ abs y = &m / &n` THENL + [EXISTS_TAC `\x. --(exp(y * log(--x)))`; + EXISTS_TAC `\x. exp(y * log(--x))`] THEN + (ASM_SIMP_TAC[REAL_ARITH `&0 < --x ==> &0 < abs x`] THEN CONJ_TAC THENL + [X_GEN_TAC `z:real` THEN DISCH_TAC THEN + SUBGOAL_THEN `~(&0 < z) /\ ~(z = &0)` + (fun th -> ASM_REWRITE_TAC[rpow; th]) THEN + ASM_REAL_ARITH_TAC; + REAL_DIFFERENTIABLE_TAC THEN ASM_REAL_ARITH_TAC])]);; + +let REAL_CONTINUOUS_AT_RPOW = prove + (`!x y. (x = &0 ==> &0 <= y) + ==> (\x. x rpow y) real_continuous (atreal x)`, + REPEAT GEN_TAC THEN ASM_CASES_TAC `y = &0` THEN + ASM_REWRITE_TAC[RPOW_POW; real_pow; REAL_CONTINUOUS_CONST] THEN + ASM_CASES_TAC `x = &0` THENL + [ASM_REWRITE_TAC[real_continuous_atreal; RPOW_ZERO] THEN + REWRITE_TAC[REAL_SUB_RZERO; REAL_ABS_RPOW] THEN STRIP_TAC THEN + X_GEN_TAC `e:real` THEN DISCH_TAC THEN EXISTS_TAC `e rpow inv(y)` THEN + ASM_SIMP_TAC[RPOW_POS_LT] THEN X_GEN_TAC `z:real` THEN DISCH_TAC THEN + MATCH_MP_TAC REAL_LTE_TRANS THEN + EXISTS_TAC `e rpow inv y rpow y` THEN CONJ_TAC THENL + [MATCH_MP_TAC RPOW_LT2 THEN ASM_REAL_ARITH_TAC; + ASM_SIMP_TAC[RPOW_RPOW; REAL_LT_IMP_LE; REAL_MUL_LINV] THEN + REWRITE_TAC[RPOW_POW; REAL_POW_1; REAL_LE_REFL]]; + ASM_SIMP_TAC[REAL_DIFFERENTIABLE_IMP_CONTINUOUS_ATREAL; + REAL_DIFFERENTIABLE_AT_RPOW]]);; + +let REAL_CONTINUOUS_WITHIN_RPOW = prove + (`!s x y. (x = &0 ==> &0 <= y) + ==> (\x. x rpow y) real_continuous (atreal x within s)`, + MESON_TAC[REAL_CONTINUOUS_ATREAL_WITHINREAL; + REAL_CONTINUOUS_AT_RPOW]);; + +let REAL_CONTINUOUS_ON_RPOW = prove + (`!s y. (&0 IN s ==> &0 <= y) ==> (\x. x rpow y) real_continuous_on s`, + REWRITE_TAC[REAL_CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_CONTINUOUS_WITHIN_RPOW THEN + ASM_MESON_TAC[]);; + +let REALLIM_RPOW = prove + (`!net f l n. + (f ---> l) net /\ (l = &0 ==> &0 <= n) + ==> ((\x. f x rpow n) ---> l rpow n) net`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC + (REWRITE_RULE[] (ISPEC `\x. x rpow n` REALLIM_REAL_CONTINUOUS_FUNCTION)) THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC REAL_CONTINUOUS_AT_RPOW THEN + ASM_REWRITE_TAC[]);; + +let REALLIM_NULL_POW_EQ = prove + (`!net f n. + ~(n = 0) + ==> (((\x. f x pow n) ---> &0) net <=> (f ---> &0) net)`, + REPEAT STRIP_TAC THEN EQ_TAC THEN ASM_SIMP_TAC[REALLIM_NULL_POW] THEN + DISCH_THEN(MP_TAC o ISPEC `(\x. x rpow (inv(&n))) o abs` o + MATCH_MP(REWRITE_RULE[IMP_CONJ_ALT] REALLIM_REAL_CONTINUOUS_FUNCTION)) THEN + REWRITE_TAC[o_THM] THEN + ASM_REWRITE_TAC[RPOW_ZERO; REAL_INV_EQ_0; REAL_OF_NUM_EQ; REAL_ABS_NUM] THEN + SIMP_TAC[GSYM RPOW_POW; RPOW_RPOW; REAL_ABS_POS; REAL_ABS_RPOW] THEN + ASM_SIMP_TAC[REAL_MUL_RINV; REAL_OF_NUM_EQ] THEN + REWRITE_TAC[REALLIM_NULL_ABS; RPOW_POW; REAL_POW_1] THEN + DISCH_THEN MATCH_MP_TAC THEN + ONCE_REWRITE_TAC[GSYM WITHINREAL_UNIV] THEN + MATCH_MP_TAC REAL_CONTINUOUS_WITHINREAL_COMPOSE THEN CONJ_TAC THENL + [GEN_REWRITE_TAC LAND_CONV [GSYM ETA_AX] THEN + MATCH_MP_TAC REAL_CONTINUOUS_ABS THEN + REWRITE_TAC[REAL_CONTINUOUS_WITHIN_ID]; + MATCH_MP_TAC REAL_CONTINUOUS_WITHIN_RPOW THEN + REWRITE_TAC[REAL_LE_INV_EQ; REAL_POS]]);; + +let LIM_NULL_COMPLEX_POW_EQ = prove + (`!net f n. + ~(n = 0) + ==> (((\x. f x pow n) --> Cx(&0)) net <=> (f --> Cx(&0)) net)`, + REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM COMPLEX_VEC_0] THEN + ONCE_REWRITE_TAC[LIM_NULL_NORM] THEN + REWRITE_TAC[COMPLEX_NORM_POW; REAL_TENDSTO; o_DEF; LIFT_DROP] THEN + ASM_SIMP_TAC[REALLIM_NULL_POW_EQ; DROP_VEC]);; + +(* ------------------------------------------------------------------------- *) +(* Intermediate Value Theorem. *) +(* ------------------------------------------------------------------------- *) + +let REAL_IVT_INCREASING = prove + (`!f a b y. + a <= b /\ f real_continuous_on real_interval[a,b] /\ + f a <= y /\ y <= f b + ==> ?x. x IN real_interval [a,b] /\ f x = y`, + REWRITE_TAC[REAL_CONTINUOUS_ON; IMAGE_LIFT_REAL_INTERVAL] THEN + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`lift o f o drop`; `lift a`; `lift b`; `y:real`; `1`] + IVT_INCREASING_COMPONENT_ON_1) THEN + ASM_REWRITE_TAC[GSYM drop; o_THM; LIFT_DROP; DIMINDEX_1; LE_REFL] THEN + REWRITE_TAC[GSYM IMAGE_LIFT_REAL_INTERVAL; EXISTS_IN_IMAGE; LIFT_DROP]);; + +let REAL_IVT_DECREASING = prove + (`!f a b y. + a <= b /\ f real_continuous_on real_interval[a,b] /\ + f b <= y /\ y <= f a + ==> ?x. x IN real_interval [a,b] /\ f x = y`, + REWRITE_TAC[REAL_CONTINUOUS_ON; IMAGE_LIFT_REAL_INTERVAL] THEN + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`lift o f o drop`; `lift a`; `lift b`; `y:real`; `1`] + IVT_DECREASING_COMPONENT_ON_1) THEN + ASM_REWRITE_TAC[GSYM drop; o_THM; LIFT_DROP; DIMINDEX_1; LE_REFL] THEN + REWRITE_TAC[GSYM IMAGE_LIFT_REAL_INTERVAL; EXISTS_IN_IMAGE; LIFT_DROP]);; + +let IS_REALINTERVAL_CONTINUOUS_IMAGE = prove + (`!s. f real_continuous_on s /\ is_realinterval s + ==> is_realinterval(IMAGE f s)`, + GEN_TAC THEN REWRITE_TAC[REAL_CONTINUOUS_ON; IS_REALINTERVAL_CONNECTED] THEN + DISCH_THEN(MP_TAC o MATCH_MP CONNECTED_CONTINUOUS_IMAGE) THEN + REWRITE_TAC[IMAGE_o; REWRITE_RULE[IMAGE_o] IMAGE_LIFT_DROP]);; + +(* ------------------------------------------------------------------------- *) +(* Zeroness (or sign at boundary) of derivative at local extremum. *) +(* ------------------------------------------------------------------------- *) + +let REAL_DERIVATIVE_POS_LEFT_MINIMUM = prove + (`!f f' a b e. + a < b /\ &0 < e /\ + (f has_real_derivative f') (atreal a within real_interval[a,b]) /\ + (!x. x IN real_interval[a,b] /\ abs(x - a) < e ==> f a <= f x) + ==> &0 <= f'`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`lift o f o drop`; `\x:real^1. f' % x`; + `lift a`; `interval[lift a,lift b]`; `e:real`] + DROP_DIFFERENTIAL_POS_AT_MINIMUM) THEN + ASM_REWRITE_TAC[ENDS_IN_INTERVAL; CONVEX_INTERVAL; IN_INTER; IMP_CONJ] THEN + ASM_REWRITE_TAC[GSYM IMAGE_LIFT_REAL_INTERVAL; IMAGE_EQ_EMPTY; + GSYM HAS_REAL_FRECHET_DERIVATIVE_WITHIN] THEN + ASM_SIMP_TAC[FORALL_IN_IMAGE; o_THM; LIFT_DROP; IN_BALL; DIST_LIFT; + REAL_INTERVAL_NE_EMPTY; REAL_LT_IMP_LE] THEN + ANTS_TAC THENL [ASM_MESON_TAC[REAL_ABS_SUB]; ALL_TAC] THEN + DISCH_THEN(MP_TAC o SPEC `b:real`) THEN + ASM_SIMP_TAC[ENDS_IN_REAL_INTERVAL; REAL_INTERVAL_NE_EMPTY; + REAL_LT_IMP_LE] THEN + ASM_SIMP_TAC[DROP_CMUL; DROP_SUB; LIFT_DROP; REAL_LE_MUL_EQ; + REAL_SUB_LT]);; + +let REAL_DERIVATIVE_NEG_LEFT_MAXIMUM = prove + (`!f f' a b e. + a < b /\ &0 < e /\ + (f has_real_derivative f') (atreal a within real_interval[a,b]) /\ + (!x. x IN real_interval[a,b] /\ abs(x - a) < e ==> f x <= f a) + ==> f' <= &0`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`lift o f o drop`; `\x:real^1. f' % x`; + `lift a`; `interval[lift a,lift b]`; `e:real`] + DROP_DIFFERENTIAL_NEG_AT_MAXIMUM) THEN + ASM_REWRITE_TAC[ENDS_IN_INTERVAL; CONVEX_INTERVAL; IN_INTER; IMP_CONJ] THEN + ASM_REWRITE_TAC[GSYM IMAGE_LIFT_REAL_INTERVAL; IMAGE_EQ_EMPTY; + GSYM HAS_REAL_FRECHET_DERIVATIVE_WITHIN] THEN + ASM_SIMP_TAC[FORALL_IN_IMAGE; o_THM; LIFT_DROP; IN_BALL; DIST_LIFT; + REAL_INTERVAL_NE_EMPTY; REAL_LT_IMP_LE] THEN + ANTS_TAC THENL [ASM_MESON_TAC[REAL_ABS_SUB]; ALL_TAC] THEN + DISCH_THEN(MP_TAC o SPEC `b:real`) THEN + ASM_SIMP_TAC[ENDS_IN_REAL_INTERVAL; REAL_INTERVAL_NE_EMPTY; + REAL_LT_IMP_LE] THEN + ASM_SIMP_TAC[DROP_CMUL; DROP_SUB; LIFT_DROP; REAL_LE_MUL_EQ; + REAL_SUB_LT; REAL_ARITH `f * ba <= &0 <=> &0 <= --f * ba`] THEN + REAL_ARITH_TAC);; + +let REAL_DERIVATIVE_POS_RIGHT_MAXIMUM = prove + (`!f f' a b e. + a < b /\ &0 < e /\ + (f has_real_derivative f') (atreal b within real_interval[a,b]) /\ + (!x. x IN real_interval[a,b] /\ abs(x - b) < e ==> f x <= f b) + ==> &0 <= f'`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`lift o f o drop`; `\x:real^1. f' % x`; + `lift b`; `interval[lift a,lift b]`; `e:real`] + DROP_DIFFERENTIAL_NEG_AT_MAXIMUM) THEN + ASM_REWRITE_TAC[ENDS_IN_INTERVAL; CONVEX_INTERVAL; IN_INTER; IMP_CONJ] THEN + ASM_REWRITE_TAC[GSYM IMAGE_LIFT_REAL_INTERVAL; IMAGE_EQ_EMPTY; + GSYM HAS_REAL_FRECHET_DERIVATIVE_WITHIN] THEN + ASM_SIMP_TAC[FORALL_IN_IMAGE; o_THM; LIFT_DROP; IN_BALL; DIST_LIFT; + REAL_INTERVAL_NE_EMPTY; REAL_LT_IMP_LE] THEN + ANTS_TAC THENL [ASM_MESON_TAC[REAL_ABS_SUB]; ALL_TAC] THEN + DISCH_THEN(MP_TAC o SPEC `a:real`) THEN + ASM_SIMP_TAC[ENDS_IN_REAL_INTERVAL; REAL_INTERVAL_NE_EMPTY; + REAL_LT_IMP_LE] THEN + ASM_SIMP_TAC[DROP_CMUL; DROP_SUB; LIFT_DROP; REAL_LE_MUL_EQ; REAL_SUB_LT; + REAL_ARITH `f * (a - b) <= &0 <=> &0 <= f * (b - a)`]);; + +let REAL_DERIVATIVE_NEG_RIGHT_MINIMUM = prove + (`!f f' a b e. + a < b /\ &0 < e /\ + (f has_real_derivative f') (atreal b within real_interval[a,b]) /\ + (!x. x IN real_interval[a,b] /\ abs(x - b) < e ==> f b <= f x) + ==> f' <= &0`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`lift o f o drop`; `\x:real^1. f' % x`; + `lift b`; `interval[lift a,lift b]`; `e:real`] + DROP_DIFFERENTIAL_POS_AT_MINIMUM) THEN + ASM_REWRITE_TAC[ENDS_IN_INTERVAL; CONVEX_INTERVAL; IN_INTER; IMP_CONJ] THEN + ASM_REWRITE_TAC[GSYM IMAGE_LIFT_REAL_INTERVAL; IMAGE_EQ_EMPTY; + GSYM HAS_REAL_FRECHET_DERIVATIVE_WITHIN] THEN + ASM_SIMP_TAC[FORALL_IN_IMAGE; o_THM; LIFT_DROP; IN_BALL; DIST_LIFT; + REAL_INTERVAL_NE_EMPTY; REAL_LT_IMP_LE] THEN + ANTS_TAC THENL [ASM_MESON_TAC[REAL_ABS_SUB]; ALL_TAC] THEN + DISCH_THEN(MP_TAC o SPEC `a:real`) THEN + ASM_SIMP_TAC[ENDS_IN_REAL_INTERVAL; REAL_INTERVAL_NE_EMPTY; + REAL_LT_IMP_LE] THEN + ASM_SIMP_TAC[DROP_CMUL; DROP_SUB; LIFT_DROP] THEN + ONCE_REWRITE_TAC[REAL_ARITH `&0 <= f * (a - b) <=> &0 <= --f * (b - a)`] THEN + ASM_SIMP_TAC[REAL_LE_MUL_EQ; REAL_SUB_LT] THEN REAL_ARITH_TAC);; + +let REAL_DERIVATIVE_ZERO_MAXMIN = prove + (`!f f' x s. + x IN s /\ real_open s /\ + (f has_real_derivative f') (atreal x) /\ + ((!y. y IN s ==> f y <= f x) \/ (!y. y IN s ==> f x <= f y)) + ==> f' = &0`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`lift o f o drop`; `\x:real^1. f' % x`; + `lift x`; `IMAGE lift s`] + DIFFERENTIAL_ZERO_MAXMIN) THEN + ASM_REWRITE_TAC[GSYM HAS_REAL_FRECHET_DERIVATIVE_AT; GSYM REAL_OPEN] THEN + ASM_SIMP_TAC[FUN_IN_IMAGE; FORALL_IN_IMAGE] THEN + ASM_REWRITE_TAC[o_DEF; LIFT_DROP] THEN + DISCH_THEN(MP_TAC o C AP_THM `vec 1:real^1`) THEN + REWRITE_TAC[GSYM DROP_EQ; DROP_CMUL; DROP_VEC; REAL_MUL_RID]);; + +(* ------------------------------------------------------------------------- *) +(* Rolle and Mean Value Theorem. *) +(* ------------------------------------------------------------------------- *) + +let REAL_ROLLE = prove + (`!f f' a b. + a < b /\ f a = f b /\ + f real_continuous_on real_interval[a,b] /\ + (!x. x IN real_interval(a,b) + ==> (f has_real_derivative f'(x)) (atreal x)) + ==> ?x. x IN real_interval(a,b) /\ f'(x) = &0`, + REWRITE_TAC[REAL_INTERVAL_INTERVAL; FORALL_IN_IMAGE; EXISTS_IN_IMAGE] THEN + REWRITE_TAC[REAL_CONTINUOUS_ON; HAS_REAL_VECTOR_DERIVATIVE_AT] THEN + REWRITE_TAC[GSYM IMAGE_o; IMAGE_LIFT_DROP; has_vector_derivative] THEN + REWRITE_TAC[LIFT_DROP] THEN REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`lift o f o drop`; `\x:real^1 h:real^1. f'(drop x) % h`; + `lift a`; `lift b`] ROLLE) THEN + ASM_REWRITE_TAC[o_THM; LIFT_DROP] THEN ANTS_TAC THENL + [X_GEN_TAC `t:real^1` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `t:real^1`) THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC EQ_IMP THEN + AP_THM_TAC THEN AP_TERM_TAC THEN + REWRITE_TAC[FUN_EQ_THM; FORALL_LIFT; LIFT_DROP; GSYM LIFT_CMUL] THEN + REWRITE_TAC[REAL_MUL_AC]; + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `t:real^1` THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + FIRST_X_ASSUM(MP_TAC o C AP_THM `lift(&1)`) THEN + REWRITE_TAC[GSYM LIFT_CMUL; GSYM LIFT_NUM; LIFT_EQ; REAL_MUL_RID]]);; + +let REAL_MVT = prove + (`!f f' a b. + a < b /\ + f real_continuous_on real_interval[a,b] /\ + (!x. x IN real_interval(a,b) + ==> (f has_real_derivative f'(x)) (atreal x)) + ==> ?x. x IN real_interval(a,b) /\ f(b) - f(a) = f'(x) * (b - a)`, + REPEAT STRIP_TAC THEN + MP_TAC(SPECL [`\x:real. f(x) - (f b - f a) / (b - a) * x`; + `(\x. f'(x) - (f b - f a) / (b - a)):real->real`; + `a:real`; `b:real`] + REAL_ROLLE) THEN + ASM_SIMP_TAC[REAL_FIELD + `a < b ==> (fx - fba / (b - a) = &0 <=> fba = fx * (b - a))`] THEN + DISCH_THEN MATCH_MP_TAC THEN + ASM_SIMP_TAC[REAL_CONTINUOUS_ON_SUB; REAL_CONTINUOUS_ON_LMUL; + REAL_CONTINUOUS_ON_ID] THEN + CONJ_TAC THENL [UNDISCH_TAC `a < b` THEN CONV_TAC REAL_FIELD; ALL_TAC] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_REAL_DERIVATIVE_SUB THEN + ASM_SIMP_TAC[] THEN GEN_REWRITE_TAC LAND_CONV [GSYM REAL_MUL_RID] THEN + ASM_SIMP_TAC[HAS_REAL_DERIVATIVE_LMUL_ATREAL; HAS_REAL_DERIVATIVE_ID]);; + +let REAL_MVT_SIMPLE = prove + (`!f f' a b. + a < b /\ + (!x. x IN real_interval[a,b] + ==> (f has_real_derivative f'(x)) + (atreal x within real_interval[a,b])) + ==> ?x. x IN real_interval(a,b) /\ f(b) - f(a) = f'(x) * (b - a)`, + MP_TAC REAL_MVT THEN + REPEAT(MATCH_MP_TAC MONO_FORALL THEN GEN_TAC) THEN + REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[] THEN + CONJ_TAC THENL + [MATCH_MP_TAC REAL_DIFFERENTIABLE_ON_IMP_REAL_CONTINUOUS_ON THEN + ASM_MESON_TAC[real_differentiable_on; real_differentiable]; + ASM_MESON_TAC[HAS_REAL_DERIVATIVE_WITHIN_REAL_OPEN; REAL_OPEN_REAL_INTERVAL; + REAL_INTERVAL_OPEN_SUBSET_CLOSED; + HAS_REAL_DERIVATIVE_WITHIN_SUBSET; SUBSET]]);; + +let REAL_MVT_VERY_SIMPLE = prove + (`!f f' a b. + a <= b /\ + (!x. x IN real_interval[a,b] + ==> (f has_real_derivative f'(x)) + (atreal x within real_interval[a,b])) + ==> ?x. x IN real_interval[a,b] /\ f(b) - f(a) = f'(x) * (b - a)`, + REPEAT GEN_TAC THEN ASM_CASES_TAC `b:real = a` THENL + [ASM_REWRITE_TAC[REAL_SUB_REFL; REAL_MUL_RZERO] THEN + REWRITE_TAC[REAL_INTERVAL_SING; IN_SING; EXISTS_REFL]; + ASM_REWRITE_TAC[REAL_LE_LT] THEN + DISCH_THEN(MP_TAC o MATCH_MP REAL_MVT_SIMPLE) THEN + MATCH_MP_TAC MONO_EXISTS THEN + SIMP_TAC[REWRITE_RULE[SUBSET] REAL_INTERVAL_OPEN_SUBSET_CLOSED]]);; + +let REAL_ROLLE_SIMPLE = prove + (`!f f' a b. + a < b /\ f a = f b /\ + (!x. x IN real_interval[a,b] + ==> (f has_real_derivative f'(x)) + (atreal x within real_interval[a,b])) + ==> ?x. x IN real_interval(a,b) /\ f'(x) = &0`, + MP_TAC REAL_MVT_SIMPLE THEN + REPEAT(MATCH_MP_TAC MONO_FORALL THEN GEN_TAC) THEN + DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC THEN MATCH_MP_TAC MONO_AND THEN + REWRITE_TAC[REAL_RING `a - a = b * (c - d) <=> b = &0 \/ c = d`] THEN + ASM_MESON_TAC[REAL_LT_REFL]);; + +(* ------------------------------------------------------------------------- *) +(* Cauchy MVT and l'Hospital's rule. *) +(* ------------------------------------------------------------------------- *) + +let REAL_MVT_CAUCHY = prove + (`!f g f' g' a b. + a < b /\ + f real_continuous_on real_interval[a,b] /\ + g real_continuous_on real_interval[a,b] /\ + (!x. x IN real_interval(a,b) + ==> (f has_real_derivative f' x) (atreal x) /\ + (g has_real_derivative g' x) (atreal x)) + ==> ?x. x IN real_interval(a,b) /\ + (f b - f a) * g'(x) = (g b - g a) * f'(x)`, + REPEAT STRIP_TAC THEN MP_TAC(SPECL + [`\x. (f:real->real)(x) * (g(b:real) - g(a)) - g(x) * (f(b) - f(a))`; + `\x. (f':real->real)(x) * (g(b:real) - g(a)) - g'(x) * (f(b) - f(a))`; + `a:real`; `b:real`] REAL_MVT) THEN + ASM_SIMP_TAC[REAL_CONTINUOUS_ON_SUB; REAL_CONTINUOUS_ON_RMUL; + HAS_REAL_DERIVATIVE_SUB; HAS_REAL_DERIVATIVE_RMUL_ATREAL] THEN + MATCH_MP_TAC MONO_EXISTS THEN SIMP_TAC[] THEN + UNDISCH_TAC `a < b` THEN CONV_TAC REAL_FIELD);; + +let LHOSPITAL = prove + (`!f g f' g' c l d. + &0 < d /\ + (!x. &0 < abs(x - c) /\ abs(x - c) < d + ==> (f has_real_derivative f'(x)) (atreal x) /\ + (g has_real_derivative g'(x)) (atreal x) /\ + ~(g'(x) = &0)) /\ + (f ---> &0) (atreal c) /\ (g ---> &0) (atreal c) /\ + ((\x. f'(x) / g'(x)) ---> l) (atreal c) + ==> ((\x. f(x) / g(x)) ---> l) (atreal c)`, + SUBGOAL_THEN + `!f g f' g' c l d. + &0 < d /\ + (!x. &0 < abs(x - c) /\ abs(x - c) < d + ==> (f has_real_derivative f'(x)) (atreal x) /\ + (g has_real_derivative g'(x)) (atreal x) /\ + ~(g'(x) = &0)) /\ + f(c) = &0 /\ g(c) = &0 /\ + (f ---> &0) (atreal c) /\ (g ---> &0) (atreal c) /\ + ((\x. f'(x) / g'(x)) ---> l) (atreal c) + ==> ((\x. f(x) / g(x)) ---> l) (atreal c)` + ASSUME_TAC THENL + [REWRITE_TAC[TAUT `a ==> b /\ c <=> (a ==> b) /\ (a ==> c)`] THEN + REWRITE_TAC[FORALL_AND_THM] THEN REPEAT STRIP_TAC THEN + SUBGOAL_THEN + `(!x. abs(x - c) < d ==> f real_continuous atreal x) /\ + (!x. abs(x - c) < d ==> g real_continuous atreal x)` + STRIP_ASSUME_TAC THENL + [REWRITE_TAC[AND_FORALL_THM] THEN X_GEN_TAC `x:real` THEN + DISJ_CASES_TAC(REAL_ARITH `x = c \/ &0 < abs(x - c)`) THENL + [ASM_REWRITE_TAC[REAL_CONTINUOUS_ATREAL]; ALL_TAC] THEN + REPEAT STRIP_TAC THEN + MATCH_MP_TAC REAL_DIFFERENTIABLE_IMP_CONTINUOUS_ATREAL THEN + REWRITE_TAC[real_differentiable] THEN ASM_MESON_TAC[]; + ALL_TAC] THEN + SUBGOAL_THEN + `!x. &0 < abs(x - c) /\ abs(x - c) < d ==> ~(g x = &0)` + STRIP_ASSUME_TAC THENL + [REPEAT STRIP_TAC THEN + SUBGOAL_THEN `c < x \/ x < c` DISJ_CASES_TAC THENL + [ASM_REAL_ARITH_TAC; + MP_TAC(ISPECL [`g:real->real`; `g':real->real`; `c:real`; `x:real`] + REAL_ROLLE); + MP_TAC(ISPECL [`g:real->real`; `g':real->real`; `x:real`; `c:real`] + REAL_ROLLE)] THEN + ASM_REWRITE_TAC[NOT_IMP; NOT_EXISTS_THM] THEN + (REPEAT CONJ_TAC THENL + [REWRITE_TAC[REAL_CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN] THEN + REWRITE_TAC[IN_REAL_INTERVAL] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC REAL_CONTINUOUS_ATREAL_WITHINREAL; + REWRITE_TAC[IN_REAL_INTERVAL] THEN REPEAT STRIP_TAC; + X_GEN_TAC `y:real` THEN REWRITE_TAC[IN_REAL_INTERVAL] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + REWRITE_TAC[]] THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REAL_ARITH_TAC); + ALL_TAC] THEN + UNDISCH_TAC `((\x. f' x / g' x) ---> l) (atreal c)` THEN + REWRITE_TAC[REALLIM_ATREAL] THEN MATCH_MP_TAC MONO_FORALL THEN + X_GEN_TAC `e:real` THEN ASM_CASES_TAC `&0 < e` THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `k:real` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `min d k:real` THEN ASM_REWRITE_TAC[REAL_LT_MIN] THEN + X_GEN_TAC `x:real` THEN STRIP_TAC THEN + SUBGOAL_THEN + `?y. &0 < abs(y - c) /\ abs(y - c) < abs(x - c) /\ + (f:real->real) x / g x = f' y / g' y` + STRIP_ASSUME_TAC THENL + [ALL_TAC; ASM_REWRITE_TAC[] THEN ASM_MESON_TAC[REAL_LT_TRANS]] THEN + SUBGOAL_THEN `c < x \/ x < c` DISJ_CASES_TAC THENL + [ASM_REAL_ARITH_TAC; + MP_TAC(ISPECL + [`f:real->real`; `g:real->real`; `f':real->real`; `g':real->real`; + `c:real`; `x:real`] REAL_MVT_CAUCHY); + MP_TAC(ISPECL + [`f:real->real`; `g:real->real`; `f':real->real`; `g':real->real`; + `x:real`; `c:real`] REAL_MVT_CAUCHY)] THEN + (ASM_REWRITE_TAC[IN_REAL_INTERVAL] THEN ANTS_TAC THENL + [REWRITE_TAC[CONJ_ASSOC] THEN CONJ_TAC THENL + [CONJ_TAC THEN + REWRITE_TAC[REAL_CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN] THEN + REWRITE_TAC[IN_REAL_INTERVAL] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC REAL_CONTINUOUS_ATREAL_WITHINREAL; + REPEAT STRIP_TAC] THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REAL_ARITH_TAC; + MATCH_MP_TAC MONO_EXISTS THEN REWRITE_TAC[REAL_SUB_RZERO] THEN + GEN_TAC THEN STRIP_TAC THEN + REPEAT(CONJ_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC]) THEN + MATCH_MP_TAC(REAL_FIELD + `f * g' = g * f' /\ ~(g = &0) /\ ~(g' = &0) ==> f / g = f' / g'`) THEN + CONJ_TAC THENL [ASM_REAL_ARITH_TAC; CONJ_TAC] THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REAL_ARITH_TAC]); + REPEAT GEN_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPECL + [`\x:real. if x = c then &0 else f(x)`; + `\x:real. if x = c then &0 else g(x)`; + `f':real->real`; `g':real->real`; + `c:real`; `l:real`; `d:real`]) THEN + REWRITE_TAC[] THEN MATCH_MP_TAC MONO_IMP THEN CONJ_TAC THEN + REPEAT(MATCH_MP_TAC MONO_AND THEN CONJ_TAC) THEN + TRY(SIMP_TAC[REALLIM_ATREAL;REAL_ARITH `&0 < abs(x - c) ==> ~(x = c)`] THEN + NO_TAC) THEN + DISCH_TAC THEN X_GEN_TAC `x:real` THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `x:real`) THEN ASM_REWRITE_TAC[] THEN + REPEAT(MATCH_MP_TAC MONO_AND THEN CONJ_TAC) THEN REWRITE_TAC[] THEN + MATCH_MP_TAC(REWRITE_RULE[TAUT `a /\ b /\ c ==> d <=> a /\ b ==> c ==> d`] + HAS_REAL_DERIVATIVE_TRANSFORM_ATREAL) THEN + EXISTS_TAC `abs(x - c)` THEN ASM_REAL_ARITH_TAC]);; + +(* ------------------------------------------------------------------------- *) +(* Darboux's theorem (intermediate value property for derivatives). *) +(* ------------------------------------------------------------------------- *) + +let REAL_DERIVATIVE_IVT_INCREASING = prove + (`!f f' a b. + a <= b /\ + (!x. x IN real_interval[a,b] + ==> (f has_real_derivative f'(x)) (atreal x within real_interval[a,b])) + ==> !t. f'(a) <= t /\ t <= f'(b) + ==> ?x. x IN real_interval[a,b] /\ f' x = t`, + REPEAT GEN_TAC THEN STRIP_TAC THEN GEN_TAC THEN + ASM_CASES_TAC `(f':real->real) a = t` THENL + [ASM_MESON_TAC[ENDS_IN_REAL_INTERVAL; REAL_INTERVAL_NE_EMPTY]; + ALL_TAC] THEN + ASM_CASES_TAC `(f':real->real) b = t` THENL + [ASM_MESON_TAC[ENDS_IN_REAL_INTERVAL; REAL_INTERVAL_NE_EMPTY]; + ALL_TAC] THEN + ASM_CASES_TAC `b:real = a` THEN ASM_REWRITE_TAC[REAL_LE_ANTISYM] THEN + SUBGOAL_THEN `a < b` ASSUME_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN + ASM_REWRITE_TAC[REAL_LE_LT] THEN STRIP_TAC THEN + MP_TAC(ISPECL [`\x:real. f x - t * x`; `real_interval[a,b]`] + REAL_CONTINUOUS_ATTAINS_INF) THEN + ASM_REWRITE_TAC[REAL_INTERVAL_NE_EMPTY; REAL_COMPACT_INTERVAL] THEN + ANTS_TAC THENL + [MATCH_MP_TAC REAL_DIFFERENTIABLE_ON_IMP_REAL_CONTINUOUS_ON THEN + MATCH_MP_TAC REAL_DIFFERENTIABLE_ON_SUB THEN + SIMP_TAC[REAL_DIFFERENTIABLE_ON_MUL; REAL_DIFFERENTIABLE_ON_ID; + REAL_DIFFERENTIABLE_ON_CONST] THEN + ASM_MESON_TAC[real_differentiable_on]; + ALL_TAC] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `x:real` THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + MP_TAC(SPECL + [`\x:real. f x - t * x`; `(f':real->real) x - t:real`; + `x:real`; `real_interval(a,b)`] + REAL_DERIVATIVE_ZERO_MAXMIN) THEN + ASM_REWRITE_TAC[REAL_SUB_0] THEN DISCH_THEN MATCH_MP_TAC THEN + REWRITE_TAC[REAL_OPEN_REAL_INTERVAL] THEN + ASM_SIMP_TAC[REAL_OPEN_CLOSED_INTERVAL; IN_DIFF] THEN + ASM_CASES_TAC `x:real = a` THENL + [FIRST_X_ASSUM SUBST_ALL_TAC THEN + MP_TAC(ISPECL[`\x:real. f x - t * x`; `(f':real->real) a - t:real`; + `a:real`; `b:real`; `&1`] + REAL_DERIVATIVE_POS_LEFT_MINIMUM) THEN + ASM_SIMP_TAC[REAL_LT_01; REAL_SUB_LE] THEN + MATCH_MP_TAC(TAUT `~q /\ p ==> (p ==> q) ==> r`) THEN + ASM_REWRITE_TAC[REAL_NOT_LE] THEN + MATCH_MP_TAC HAS_REAL_DERIVATIVE_SUB THEN + CONJ_TAC THENL [ALL_TAC; REAL_DIFF_TAC THEN REWRITE_TAC[REAL_MUL_RID]] THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_REWRITE_TAC[ENDS_IN_INTERVAL; INTERVAL_NE_EMPTY]; + ALL_TAC] THEN + ASM_CASES_TAC `x:real = b` THENL + [FIRST_X_ASSUM SUBST_ALL_TAC THEN + MP_TAC(ISPECL[`\x:real. f x - t * x`; `(f':real->real) b - t:real`; + `a:real`; `b:real`; `&1`] + REAL_DERIVATIVE_NEG_RIGHT_MINIMUM) THEN + ASM_SIMP_TAC[REAL_LT_01; REAL_SUB_LE] THEN + MATCH_MP_TAC(TAUT `~q /\ p ==> (p ==> q) ==> r`) THEN + ASM_REWRITE_TAC[REAL_NOT_LE; REAL_SUB_LT] THEN + MATCH_MP_TAC HAS_REAL_DERIVATIVE_SUB THEN + CONJ_TAC THENL [ALL_TAC; REAL_DIFF_TAC THEN REWRITE_TAC[REAL_MUL_RID]] THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_REWRITE_TAC[ENDS_IN_INTERVAL; INTERVAL_NE_EMPTY]; + ALL_TAC] THEN + ASM_REWRITE_TAC[IN_INSERT; NOT_IN_EMPTY] THEN + MATCH_MP_TAC HAS_REAL_DERIVATIVE_SUB THEN + CONJ_TAC THENL [ALL_TAC; REAL_DIFF_TAC THEN REWRITE_TAC[REAL_MUL_RID]] THEN + SUBGOAL_THEN + `(f has_real_derivative f' x) (atreal x within real_interval(a,b))` + MP_TAC THENL + [MATCH_MP_TAC HAS_REAL_DERIVATIVE_WITHIN_SUBSET THEN + EXISTS_TAC `real_interval[a,b]` THEN + ASM_SIMP_TAC[REAL_INTERVAL_OPEN_SUBSET_CLOSED]; + MATCH_MP_TAC EQ_IMP THEN + MATCH_MP_TAC HAS_REAL_DERIVATIVE_WITHIN_REAL_OPEN THEN + REWRITE_TAC[REAL_OPEN_REAL_INTERVAL] THEN + ASM_REWRITE_TAC[REAL_OPEN_CLOSED_INTERVAL] THEN ASM SET_TAC[]]);; + +let REAL_DERIVATIVE_IVT_DECREASING = prove + (`!f f' a b t. + a <= b /\ + (!x. x IN real_interval[a,b] + ==> (f has_real_derivative f'(x)) (atreal x within real_interval[a,b])) + ==> !t. f'(b) <= t /\ t <= f'(a) + ==> ?x. x IN real_interval[a,b] /\ f' x = t`, + REPEAT STRIP_TAC THEN MP_TAC(SPECL + [`\x. --((f:real->real) x)`; `\x. --((f':real->real) x)`; + `a:real`; `b:real`] REAL_DERIVATIVE_IVT_INCREASING) THEN + ASM_SIMP_TAC[HAS_REAL_DERIVATIVE_NEG] THEN + DISCH_THEN(MP_TAC o SPEC `--t:real`) THEN + ASM_REWRITE_TAC[REAL_LE_NEG2; REAL_EQ_NEG2]);; + +(* ------------------------------------------------------------------------- *) +(* Continuity and differentiability of inverse functions. *) +(* ------------------------------------------------------------------------- *) + +let HAS_REAL_DERIVATIVE_INVERSE_BASIC = prove + (`!f g f' t y. + (f has_real_derivative f') (atreal (g y)) /\ + ~(f' = &0) /\ + g real_continuous atreal y /\ + real_open t /\ + y IN t /\ + (!z. z IN t ==> f (g z) = z) + ==> (g has_real_derivative inv(f')) (atreal y)`, + REWRITE_TAC[HAS_REAL_FRECHET_DERIVATIVE_AT; REAL_OPEN; + REAL_CONTINUOUS_CONTINUOUS_ATREAL] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_DERIVATIVE_INVERSE_BASIC THEN + MAP_EVERY EXISTS_TAC + [`lift o f o drop`; `\x:real^1. f' % x`; `IMAGE lift t`] THEN + ASM_REWRITE_TAC[o_THM; LIFT_DROP; LIFT_IN_IMAGE_LIFT] THEN + ASM_SIMP_TAC[FORALL_IN_IMAGE; LIFT_DROP; LINEAR_COMPOSE_CMUL; LINEAR_ID] THEN + REWRITE_TAC[FUN_EQ_THM; I_THM; o_THM; VECTOR_MUL_ASSOC] THEN + ASM_SIMP_TAC[REAL_MUL_LINV; VECTOR_MUL_LID]);; + +let HAS_REAL_DERIVATIVE_INVERSE_STRONG = prove + (`!f g f' s x. + real_open s /\ + x IN s /\ + f real_continuous_on s /\ + (!x. x IN s ==> g (f x) = x) /\ + (f has_real_derivative f') (atreal x) /\ + ~(f' = &0) + ==> (g has_real_derivative inv(f')) (atreal (f x))`, + REWRITE_TAC[HAS_REAL_FRECHET_DERIVATIVE_AT; REAL_OPEN; + REAL_CONTINUOUS_ON] THEN + REPEAT STRIP_TAC THEN + MP_TAC(ISPEC `lift o f o drop` HAS_DERIVATIVE_INVERSE_STRONG) THEN + REWRITE_TAC[FORALL_LIFT; o_THM; LIFT_DROP] THEN + DISCH_THEN MATCH_MP_TAC THEN + MAP_EVERY EXISTS_TAC [`\x:real^1. f' % x`; `IMAGE lift s`] THEN + ASM_REWRITE_TAC[o_THM; LIFT_DROP; LIFT_IN_IMAGE_LIFT] THEN + ASM_SIMP_TAC[FUN_EQ_THM; I_THM; o_THM; VECTOR_MUL_ASSOC] THEN + ASM_SIMP_TAC[REAL_MUL_RINV; VECTOR_MUL_LID]);; + +let HAS_REAL_DERIVATIVE_INVERSE_STRONG_X = prove + (`!f g f' s y. + real_open s /\ (g y) IN s /\ f real_continuous_on s /\ + (!x. x IN s ==> (g(f(x)) = x)) /\ + (f has_real_derivative f') (atreal (g y)) /\ ~(f' = &0) /\ + f(g y) = y + ==> (g has_real_derivative inv(f')) (atreal y)`, + REWRITE_TAC[HAS_REAL_FRECHET_DERIVATIVE_AT; REAL_OPEN; + REAL_CONTINUOUS_ON] THEN + REPEAT STRIP_TAC THEN + MP_TAC(ISPEC `lift o f o drop` HAS_DERIVATIVE_INVERSE_STRONG_X) THEN + REWRITE_TAC[FORALL_LIFT; o_THM; LIFT_DROP] THEN + DISCH_THEN MATCH_MP_TAC THEN + MAP_EVERY EXISTS_TAC [`\x:real^1. f' % x`; `IMAGE lift s`] THEN + ASM_REWRITE_TAC[o_THM; LIFT_DROP; LIFT_IN_IMAGE_LIFT] THEN + ASM_SIMP_TAC[FUN_EQ_THM; I_THM; o_THM; VECTOR_MUL_ASSOC] THEN + ASM_SIMP_TAC[REAL_MUL_RINV; VECTOR_MUL_LID]);; + +(* ------------------------------------------------------------------------- *) +(* Real differentiation of sequences and series. *) +(* ------------------------------------------------------------------------- *) + +let HAS_REAL_DERIVATIVE_SEQUENCE = prove + (`!s f f' g'. + is_realinterval s /\ + (!n x. x IN s + ==> (f n has_real_derivative f' n x) (atreal x within s)) /\ + (!e. &0 < e + ==> ?N. !n x. n >= N /\ x IN s ==> abs(f' n x - g' x) <= e) /\ + (?x l. x IN s /\ ((\n. f n x) ---> l) sequentially) + ==> ?g. !x. x IN s + ==> ((\n. f n x) ---> g x) sequentially /\ + (g has_real_derivative g' x) (atreal x within s)`, + REWRITE_TAC[HAS_REAL_FRECHET_DERIVATIVE_WITHIN; IS_REALINTERVAL_CONVEX; + TENDSTO_REAL] THEN REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`IMAGE lift s`; + `\n:num. lift o f n o drop`; + `\n:num x:real^1 h:real^1. f' n (drop x) % h`; + `\x:real^1 h:real^1. g' (drop x) % h`] + HAS_DERIVATIVE_SEQUENCE) THEN + ASM_REWRITE_TAC[FORALL_IN_IMAGE; LIFT_DROP] THEN ANTS_TAC THENL + [REWRITE_TAC[IMP_CONJ; RIGHT_EXISTS_AND_THM; RIGHT_FORALL_IMP_THM; + EXISTS_IN_IMAGE; FORALL_IN_IMAGE] THEN + REWRITE_TAC[EXISTS_LIFT; o_THM; LIFT_DROP] THEN + RULE_ASSUM_TAC(REWRITE_RULE[o_DEF]) THEN + CONJ_TAC THENL [ALL_TAC; ASM_MESON_TAC[]] THEN + REWRITE_TAC[GSYM VECTOR_SUB_RDISTRIB; NORM_MUL] THEN + ASM_MESON_TAC[REAL_LE_RMUL; NORM_POS_LE]; + REWRITE_TAC[o_DEF; LIFT_DROP] THEN + DISCH_THEN(X_CHOOSE_TAC `g:real^1->real^1`) THEN + EXISTS_TAC `drop o g o lift` THEN + RULE_ASSUM_TAC(REWRITE_RULE[ETA_AX]) THEN + ASM_REWRITE_TAC[o_DEF; LIFT_DROP; ETA_AX]]);; + +let HAS_REAL_DERIVATIVE_SERIES = prove + (`!s f f' g' k. + is_realinterval s /\ + (!n x. x IN s + ==> (f n has_real_derivative f' n x) (atreal x within s)) /\ + (!e. &0 < e + ==> ?N. !n x. n >= N /\ x IN s + ==> abs(sum (k INTER (0..n)) (\i. f' i x) - g' x) + <= e) /\ + (?x l. x IN s /\ ((\n. f n x) real_sums l) k) + ==> ?g. !x. x IN s + ==> ((\n. f n x) real_sums g x) k /\ + (g has_real_derivative g' x) (atreal x within s)`, + REPEAT GEN_TAC THEN REWRITE_TAC[real_sums] THEN + DISCH_THEN(REPEAT_TCL CONJUNCTS_THEN ASSUME_TAC) THEN + MATCH_MP_TAC HAS_REAL_DERIVATIVE_SEQUENCE THEN EXISTS_TAC + `\n:num x:real. sum(k INTER (0..n)) (\n. f' n x):real` THEN + ASM_SIMP_TAC[ETA_AX; FINITE_INTER_NUMSEG; HAS_REAL_DERIVATIVE_SUM]);; + +let REAL_DIFFERENTIABLE_BOUND = prove + (`!f f' s B. + is_realinterval s /\ + (!x. x IN s ==> (f has_real_derivative f'(x)) (atreal x within s) /\ + abs(f' x) <= B) + ==> !x y. x IN s /\ y IN s ==> abs(f x - f y) <= B * abs(x - y)`, + REWRITE_TAC[HAS_REAL_FRECHET_DERIVATIVE_WITHIN; IS_REALINTERVAL_CONVEX; + o_DEF] THEN REPEAT STRIP_TAC THEN + MP_TAC(ISPECL + [`lift o f o drop`; `\x h:real^1. f' (drop x) % h`; + `IMAGE lift s`; `B:real`] + DIFFERENTIABLE_BOUND) THEN + ASM_SIMP_TAC[o_DEF; FORALL_IN_IMAGE; LIFT_DROP] THEN ANTS_TAC THENL + [X_GEN_TAC `v:real` THEN DISCH_TAC THEN + MP_TAC(ISPEC `\h:real^1. f' (v:real) % h` ONORM) THEN + SIMP_TAC[LINEAR_COMPOSE_CMUL; LINEAR_ID] THEN + DISCH_THEN(MATCH_MP_TAC o CONJUNCT2) THEN + ASM_SIMP_TAC[NORM_MUL; REAL_LE_RMUL; NORM_POS_LE]; + SIMP_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_IMAGE; LIFT_DROP] THEN + ASM_SIMP_TAC[RIGHT_IMP_FORALL_THM; IMP_IMP; GSYM LIFT_SUB; NORM_LIFT]]);; + +let REAL_TAYLOR_MVT_POS = prove + (`!f a x n. + a < x /\ + (!i t. t IN real_interval[a,x] /\ i <= n + ==> ((f i) has_real_derivative f (i + 1) t) + (atreal t within real_interval[a,x])) + ==> ?t. t IN real_interval(a,x) /\ + f 0 x = + sum (0..n) (\i. f i a * (x - a) pow i / &(FACT i)) + + f (n + 1) t * (x - a) pow (n + 1) / &(FACT(n + 1))`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN + `?B. sum (0..n) (\i. f i a * (x - a) pow i / &(FACT i)) + + B * (x - a) pow (n + 1) = f 0 x` + STRIP_ASSUME_TAC THENL + [MATCH_MP_TAC(MESON[] + `a + (y - a) / x * x:real = y ==> ?b. a + b * x = y`) THEN + MATCH_MP_TAC(REAL_FIELD `~(x = &0) ==> a + (y - a) / x * x = y`) THEN + ASM_REWRITE_TAC[REAL_POW_EQ_0; REAL_SUB_0] THEN ASM_REAL_ARITH_TAC; + ALL_TAC] THEN + MP_TAC(SPECL [`\t. sum(0..n) (\i. f i t * (x - t) pow i / &(FACT i)) + + B * (x - t) pow (n + 1)`; + `\t. (f (n + 1) t * (x - t) pow n / &(FACT n)) - + B * &(n + 1) * (x - t) pow n`; + `a:real`; `x:real`] + REAL_ROLLE_SIMPLE) THEN + ASM_REWRITE_TAC[] THEN ANTS_TAC THENL + [CONJ_TAC THENL + [SIMP_TAC[SUM_CLAUSES_LEFT; LE_0] THEN + REWRITE_TAC[GSYM ADD1; real_pow; REAL_SUB_REFL; REAL_POW_ZERO; + REAL_MUL_LZERO; REAL_MUL_RZERO; REAL_ADD_RID] THEN + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[NOT_SUC; REAL_MUL_RZERO; REAL_DIV_1; REAL_MUL_RID] THEN + REWRITE_TAC[REAL_ARITH `x = (x + y) + &0 <=> y = &0`] THEN + MATCH_MP_TAC SUM_EQ_0_NUMSEG THEN + SIMP_TAC[ARITH; ARITH_RULE `1 <= i ==> ~(i = 0)`] THEN + REWRITE_TAC[real_div; REAL_MUL_LZERO; REAL_MUL_RZERO]; + ALL_TAC] THEN + X_GEN_TAC `t:real` THEN DISCH_TAC THEN REWRITE_TAC[real_sub] THEN + MATCH_MP_TAC HAS_REAL_DERIVATIVE_ADD THEN CONJ_TAC THENL + [ALL_TAC; + REAL_DIFF_TAC THEN REWRITE_TAC[ADD_SUB] THEN CONV_TAC REAL_RING] THEN + REWRITE_TAC[GSYM real_sub] THEN + MATCH_MP_TAC(MESON[] + `!g'. f' = g' /\ (f has_real_derivative g') net + ==> (f has_real_derivative f') net`) THEN + EXISTS_TAC + `sum (0..n) (\i. f i t * --(&i * (x - t) pow (i - 1)) / &(FACT i) + + f (i + 1) t * (x - t) pow i / &(FACT i))` THEN + REWRITE_TAC[] THEN CONJ_TAC THENL + [ALL_TAC; + MATCH_MP_TAC HAS_REAL_DERIVATIVE_SUM THEN + REWRITE_TAC[FINITE_NUMSEG; IN_NUMSEG] THEN + X_GEN_TAC `m:num` THEN STRIP_TAC THEN + MATCH_MP_TAC HAS_REAL_DERIVATIVE_MUL_WITHIN THEN + ASM_SIMP_TAC[ETA_AX] THEN REAL_DIFF_TAC THEN REAL_ARITH_TAC] THEN + SIMP_TAC[SUM_CLAUSES_LEFT; LE_0; ARITH; FACT; REAL_DIV_1; + real_pow; REAL_MUL_LZERO; REAL_NEG_0; REAL_MUL_RZERO; + REAL_MUL_RID; REAL_ADD_LID] THEN + ASM_CASES_TAC `n = 0` THENL + [ASM_REWRITE_TAC[SUM_CLAUSES_NUMSEG; ARITH; FACT] THEN REAL_ARITH_TAC; + ALL_TAC] THEN + ASM_SIMP_TAC[SPECL [`f:num->real`; `1`] SUM_OFFSET_0; LE_1] THEN + REWRITE_TAC[ADD_SUB] THEN + REWRITE_TAC[GSYM ADD1; FACT; GSYM REAL_OF_NUM_MUL; GSYM REAL_OF_NUM_ADD; + GSYM REAL_OF_NUM_SUC] THEN + REWRITE_TAC[real_div; REAL_INV_MUL] THEN + REWRITE_TAC[REAL_ARITH `--(n * x) * (inv n * inv y):real = + --(n / n) * x / y`] THEN + REWRITE_TAC[REAL_FIELD `--((&n + &1) / (&n + &1)) * x = --x`] THEN + REWRITE_TAC[GSYM REAL_INV_MUL; REAL_OF_NUM_MUL; REAL_OF_NUM_SUC] THEN + REWRITE_TAC[GSYM(CONJUNCT2 FACT)] THEN + REWRITE_TAC[REAL_ARITH `a * --b + c:real = c - a * b`] THEN + REWRITE_TAC[ADD1; GSYM real_div; SUM_DIFFS_ALT; LE_0] THEN + ASM_SIMP_TAC[ARITH_RULE `~(n = 0) ==> n - 1 + 1 = n`; FACT] THEN + REWRITE_TAC[ADD_CLAUSES] THEN REAL_ARITH_TAC; + ALL_TAC] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `t:real` THEN STRIP_TAC THEN + ASM_REWRITE_TAC[] THEN + FIRST_X_ASSUM(fun th -> GEN_REWRITE_TAC LAND_CONV [GSYM th]) THEN + REWRITE_TAC[REAL_EQ_ADD_LCANCEL] THEN + REWRITE_TAC[REAL_ARITH `a * b / c:real = a / c * b`] THEN + AP_THM_TAC THEN AP_TERM_TAC THEN + FIRST_X_ASSUM(MP_TAC o MATCH_MP (REAL_ARITH + `a * x / f - B * k * x = &0 ==> (B * k - a / f) * x = &0`)) THEN + REWRITE_TAC[REAL_ENTIRE; REAL_POW_EQ_0; REAL_SUB_0] THEN + ASM_CASES_TAC `x:real = t` THENL + [ASM_MESON_TAC[IN_REAL_INTERVAL; REAL_LT_REFL]; ALL_TAC] THEN + ASM_REWRITE_TAC[GSYM ADD1; FACT] THEN + REWRITE_TAC[GSYM REAL_OF_NUM_MUL; GSYM REAL_OF_NUM_ADD; ADD1] THEN + SUBGOAL_THEN `~(&(FACT n) = &0)` MP_TAC THENL + [REWRITE_TAC[REAL_OF_NUM_EQ; FACT_NZ]; CONV_TAC REAL_FIELD]);; + +let REAL_TAYLOR_MVT_NEG = prove + (`!f a x n. + x < a /\ + (!i t. t IN real_interval[x,a] /\ i <= n + ==> ((f i) has_real_derivative f (i + 1) t) + (atreal t within real_interval[x,a])) + ==> ?t. t IN real_interval(x,a) /\ + f 0 x = + sum (0..n) (\i. f i a * (x - a) pow i / &(FACT i)) + + f (n + 1) t * (x - a) pow (n + 1) / &(FACT(n + 1))`, + REWRITE_TAC[IN_REAL_INTERVAL] THEN REPEAT STRIP_TAC THEN + ONCE_REWRITE_TAC[MESON[REAL_NEG_NEG] `(?x:real. P x) <=> (?x. P(--x))`] THEN + MP_TAC(SPECL [`\n x. (-- &1) pow n * (f:num->real->real) n (--x)`; + `--a:real`; ` --x:real`; `n:num`] + REAL_TAYLOR_MVT_POS) THEN + REWRITE_TAC[REAL_NEG_NEG] THEN + ONCE_REWRITE_TAC[REAL_ARITH `(x * y) * z / w:real = y * (x * z) / w`] THEN + REWRITE_TAC[GSYM REAL_POW_MUL] THEN + REWRITE_TAC[REAL_ARITH `-- &1 * (--x - --a) = x - a`] THEN + REWRITE_TAC[IN_REAL_INTERVAL; real_pow; REAL_MUL_LID] THEN + REWRITE_TAC[REAL_ARITH `--a < t /\ t < --x <=> x < --t /\ --t < a`] THEN + DISCH_THEN MATCH_MP_TAC THEN ASM_REWRITE_TAC[REAL_LT_NEG2] THEN + MAP_EVERY X_GEN_TAC [`m:num`; `t:real`] THEN STRIP_TAC THEN + REWRITE_TAC[REAL_POW_ADD; GSYM REAL_MUL_ASSOC] THEN + MATCH_MP_TAC HAS_REAL_DERIVATIVE_LMUL_WITHIN THEN + ONCE_REWRITE_TAC[REAL_ARITH `y pow 1 * x:real = x * y`] THEN + ONCE_REWRITE_TAC[GSYM o_DEF] THEN + MATCH_MP_TAC REAL_DIFF_CHAIN_WITHIN THEN CONJ_TAC THENL + [GEN_REWRITE_TAC (RATOR_CONV o LAND_CONV) [GSYM ETA_AX] THEN + REAL_DIFF_TAC THEN REFL_TAC; + ALL_TAC] THEN + SUBGOAL_THEN `IMAGE (--) (real_interval[--a,--x]) = real_interval[x,a]` + SUBST1_TAC THENL + [REWRITE_TAC[EXTENSION; IN_IMAGE; IN_REAL_INTERVAL] THEN + REWRITE_TAC[REAL_ARITH `x:real = --y <=> --x = y`; UNWIND_THM1] THEN + REAL_ARITH_TAC; + FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_REWRITE_TAC[] THEN ASM_REAL_ARITH_TAC]);; + +let REAL_TAYLOR = prove + (`!f n s B. + is_realinterval s /\ + (!i x. x IN s /\ i <= n + ==> ((f i) has_real_derivative f (i + 1) x) (atreal x within s)) /\ + (!x. x IN s ==> abs(f (n + 1) x) <= B) + ==> !w z. w IN s /\ z IN s + ==> abs(f 0 z - + sum (0..n) (\i. f i w * (z - w) pow i / &(FACT i))) + <= B * abs(z - w) pow (n + 1) / &(FACT(n + 1))`, + REPEAT STRIP_TAC THEN + REPEAT_TCL DISJ_CASES_THEN ASSUME_TAC + (REAL_ARITH `w = z \/ w < z \/ z < w`) + THENL + [ASM_SIMP_TAC[SUM_CLAUSES_LEFT; LE_0; REAL_SUB_REFL; REAL_POW_ZERO; + REAL_ABS_0; ARITH; ADD_EQ_0; real_div] THEN + REWRITE_TAC[REAL_MUL_LZERO; FACT; REAL_INV_1; REAL_MUL_RZERO] THEN + MATCH_MP_TAC(REAL_ARITH `y = &0 ==> abs(x - (x * &1 * &1 + y)) <= &0`) THEN + MATCH_MP_TAC SUM_EQ_0_NUMSEG THEN + SIMP_TAC[ARITH; LE_1; REAL_MUL_RZERO; REAL_MUL_LZERO]; + MP_TAC(ISPECL [`f:num->real->real`; `w:real`; `z:real`; `n:num`] + REAL_TAYLOR_MVT_POS) THEN + ASM_REWRITE_TAC[] THEN + SUBGOAL_THEN `real_interval[w,z] SUBSET s` ASSUME_TAC THENL + [SIMP_TAC[SUBSET; IN_REAL_INTERVAL] THEN ASM_MESON_TAC[is_realinterval]; + ALL_TAC]; + MP_TAC(ISPECL [`f:num->real->real`; `w:real`; `z:real`; `n:num`] + REAL_TAYLOR_MVT_NEG) THEN + ASM_REWRITE_TAC[] THEN + SUBGOAL_THEN `real_interval[z,w] SUBSET s` ASSUME_TAC THENL + [SIMP_TAC[SUBSET; IN_REAL_INTERVAL] THEN ASM_MESON_TAC[is_realinterval]; + ALL_TAC]] THEN + (ANTS_TAC THENL + [MAP_EVERY X_GEN_TAC [`m:num`; `t:real`] THEN STRIP_TAC THEN + MATCH_MP_TAC HAS_REAL_DERIVATIVE_WITHIN_SUBSET THEN + EXISTS_TAC `s:real->bool` THEN ASM_REWRITE_TAC[] THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_MESON_TAC[SUBSET]; + ALL_TAC] THEN + DISCH_THEN(X_CHOOSE_THEN `t:real` + (CONJUNCTS_THEN2 ASSUME_TAC SUBST1_TAC)) THEN + REWRITE_TAC[REAL_ADD_SUB; REAL_ABS_MUL; REAL_ABS_DIV] THEN + REWRITE_TAC[REAL_ABS_POW; REAL_ABS_NUM] THEN + MATCH_MP_TAC REAL_LE_RMUL THEN + SIMP_TAC[REAL_LE_DIV; REAL_POS; REAL_POW_LE; REAL_ABS_POS] THEN + ASM_MESON_TAC[REAL_INTERVAL_OPEN_SUBSET_CLOSED; SUBSET]));; + +(* ------------------------------------------------------------------------- *) +(* Comparing sums and "integrals" via real antiderivatives. *) +(* ------------------------------------------------------------------------- *) + +let REAL_SUM_INTEGRAL_UBOUND_INCREASING = prove + (`!f g m n. + m <= n /\ + (!x. x IN real_interval[&m,&n + &1] + ==> (g has_real_derivative f(x)) + (atreal x within real_interval[&m,&n + &1])) /\ + (!x y. &m <= x /\ x <= y /\ y <= &n + &1 ==> f x <= f y) + ==> sum(m..n) (\k. f(&k)) <= g(&n + &1) - g(&m)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `sum(m..n) (\k. g(&(k + 1)) - g(&k))` THEN CONJ_TAC THENL + [ALL_TAC; ASM_SIMP_TAC[SUM_DIFFS_ALT; REAL_OF_NUM_ADD; REAL_LE_REFL]] THEN + MATCH_MP_TAC SUM_LE_NUMSEG THEN X_GEN_TAC `k:num` THEN STRIP_TAC THEN + MP_TAC(ISPECL [`g:real->real`; `f:real->real`; `&k`; `&(k + 1)`] + REAL_MVT_SIMPLE) THEN + ASM_REWRITE_TAC[REAL_OF_NUM_LT; ARITH_RULE `k < k + 1`] THEN + ASM_REWRITE_TAC[GSYM REAL_OF_NUM_ADD; REAL_ADD_SUB] THEN ANTS_TAC THENL + [REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_REAL_DERIVATIVE_WITHIN_SUBSET THEN + EXISTS_TAC `real_interval[&m,&n + &1]` THEN CONJ_TAC THENL + [FIRST_X_ASSUM MATCH_MP_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_REAL_INTERVAL]); + REWRITE_TAC[SUBSET] THEN GEN_TAC] THEN + REWRITE_TAC[IN_REAL_INTERVAL] THEN + RULE_ASSUM_TAC(REWRITE_RULE[GSYM REAL_OF_NUM_LE]) THEN ASM_REAL_ARITH_TAC; + DISCH_THEN(X_CHOOSE_THEN `t:real` + (CONJUNCTS_THEN2 ASSUME_TAC SUBST1_TAC)) THEN + REWRITE_TAC[REAL_MUL_RID] THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_REAL_INTERVAL]) THEN + RULE_ASSUM_TAC(REWRITE_RULE[GSYM REAL_OF_NUM_LE]) THEN + ASM_REAL_ARITH_TAC]);; + +let REAL_SUM_INTEGRAL_UBOUND_DECREASING = prove + (`!f g m n. + m <= n /\ + (!x. x IN real_interval[&m - &1,&n] + ==> (g has_real_derivative f(x)) + (atreal x within real_interval[&m - &1,&n])) /\ + (!x y. &m - &1 <= x /\ x <= y /\ y <= &n ==> f y <= f x) + ==> sum(m..n) (\k. f(&k)) <= g(&n) - g(&m - &1)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `sum(m..n) (\k. g(&(k + 1) - &1) - g(&k - &1))` THEN + CONJ_TAC THENL + [ALL_TAC; + ASM_REWRITE_TAC[SUM_DIFFS_ALT] THEN + ASM_REWRITE_TAC[GSYM REAL_OF_NUM_ADD; REAL_ARITH `(x + &1) - &1 = x`] THEN + REWRITE_TAC[REAL_LE_REFL]] THEN + MATCH_MP_TAC SUM_LE_NUMSEG THEN X_GEN_TAC `k:num` THEN STRIP_TAC THEN + MP_TAC(ISPECL [`g:real->real`; `f:real->real`; `&k - &1`; `&k`] + REAL_MVT_SIMPLE) THEN + ASM_REWRITE_TAC[REAL_ARITH `k - &1 < k`] THEN ANTS_TAC THENL + [REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_REAL_DERIVATIVE_WITHIN_SUBSET THEN + EXISTS_TAC `real_interval[&m - &1,&n]` THEN CONJ_TAC THENL + [FIRST_X_ASSUM MATCH_MP_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_REAL_INTERVAL]); + REWRITE_TAC[SUBSET] THEN GEN_TAC] THEN + REWRITE_TAC[IN_REAL_INTERVAL] THEN + RULE_ASSUM_TAC(REWRITE_RULE[GSYM REAL_OF_NUM_LE]) THEN ASM_REAL_ARITH_TAC; + REWRITE_TAC[GSYM REAL_OF_NUM_ADD; REAL_ARITH `(a + &1) - &1 = a`] THEN + DISCH_THEN(X_CHOOSE_THEN `t:real` + (CONJUNCTS_THEN2 ASSUME_TAC SUBST1_TAC)) THEN + REWRITE_TAC[REAL_ARITH `a * (x - (x - &1)) = a`] THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_REAL_INTERVAL]) THEN + RULE_ASSUM_TAC(REWRITE_RULE[GSYM REAL_OF_NUM_LE]) THEN + ASM_REAL_ARITH_TAC]);; + +let REAL_SUM_INTEGRAL_LBOUND_INCREASING = prove + (`!f g m n. + m <= n /\ + (!x. x IN real_interval[&m - &1,&n] + ==> (g has_real_derivative f(x)) + (atreal x within real_interval[&m - &1,&n])) /\ + (!x y. &m - &1 <= x /\ x <= y /\ y <= &n ==> f x <= f y) + ==> g(&n) - g(&m - &1) <= sum(m..n) (\k. f(&k))`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`\z. --((f:real->real) z)`; + `\z. --((g:real->real) z)`; + `m:num`; `n:num`] REAL_SUM_INTEGRAL_UBOUND_DECREASING) THEN + REWRITE_TAC[RE_NEG; RE_SUB; SUM_NEG; REAL_LE_NEG2; + REAL_ARITH `--x - --y:real = --(x - y)`] THEN + ASM_SIMP_TAC[HAS_REAL_DERIVATIVE_NEG]);; + +let REAL_SUM_INTEGRAL_LBOUND_DECREASING = prove + (`!f g m n. + m <= n /\ + (!x. x IN real_interval[&m,&n + &1] + ==> (g has_real_derivative f(x)) + (atreal x within real_interval[&m,&n + &1])) /\ + (!x y. &m <= x /\ x <= y /\ y <= &n + &1 ==> f y <= f x) + ==> g(&n + &1) - g(&m) <= sum(m..n) (\k. f(&k))`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`\z. --((f:real->real) z)`; + `\z. --((g:real->real) z)`; + `m:num`; `n:num`] REAL_SUM_INTEGRAL_UBOUND_INCREASING) THEN + REWRITE_TAC[RE_NEG; RE_SUB; SUM_NEG; REAL_LE_NEG2; + REAL_ARITH `--x - --y:real = --(x - y)`] THEN + ASM_SIMP_TAC[HAS_REAL_DERIVATIVE_NEG]);; + +let REAL_SUM_INTEGRAL_BOUNDS_INCREASING = prove + (`!f g m n. + m <= n /\ + (!x. x IN real_interval[&m - &1,&n + &1] + ==> (g has_real_derivative f x) + (atreal x within real_interval[&m - &1,&n + &1])) /\ + (!x y. &m - &1 <= x /\ x <= y /\ y <= &n + &1 ==> f x <= f y) + ==> g(&n) - g(&m - &1) <= sum(m..n) (\k. f(&k)) /\ + sum (m..n) (\k. f(&k)) <= g(&n + &1) - g(&m)`, + REPEAT STRIP_TAC THENL + [MATCH_MP_TAC REAL_SUM_INTEGRAL_LBOUND_INCREASING; + MATCH_MP_TAC REAL_SUM_INTEGRAL_UBOUND_INCREASING] THEN + REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + TRY(MATCH_MP_TAC HAS_REAL_DERIVATIVE_WITHIN_SUBSET THEN + EXISTS_TAC `real_interval[&m - &1,&n + &1]` THEN CONJ_TAC) THEN + TRY(FIRST_X_ASSUM MATCH_MP_TAC) THEN + TRY(FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_REAL_INTERVAL])) THEN + REWRITE_TAC[SUBSET; IN_REAL_INTERVAL] THEN + RULE_ASSUM_TAC(REWRITE_RULE[GSYM REAL_OF_NUM_LE]) THEN ASM_REAL_ARITH_TAC);; + +let REAL_SUM_INTEGRAL_BOUNDS_DECREASING = prove + (`!f g m n. + m <= n /\ + (!x. x IN real_interval[&m - &1,&n + &1] + ==> (g has_real_derivative f(x)) + (atreal x within real_interval[&m - &1,&n + &1])) /\ + (!x y. &m - &1 <= x /\ x <= y /\ y <= &n + &1 ==> f y <= f x) + ==> g(&n + &1) - g(&m) <= sum(m..n) (\k. f(&k)) /\ + sum(m..n) (\k. f(&k)) <= g(&n) - g(&m - &1)`, + REPEAT STRIP_TAC THENL + [MATCH_MP_TAC REAL_SUM_INTEGRAL_LBOUND_DECREASING; + MATCH_MP_TAC REAL_SUM_INTEGRAL_UBOUND_DECREASING] THEN + REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + TRY(MATCH_MP_TAC HAS_REAL_DERIVATIVE_WITHIN_SUBSET THEN + EXISTS_TAC `real_interval[&m - &1,&n + &1]` THEN CONJ_TAC) THEN + TRY(FIRST_X_ASSUM MATCH_MP_TAC) THEN + TRY(FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_REAL_INTERVAL])) THEN + REWRITE_TAC[SUBSET; IN_REAL_INTERVAL] THEN + RULE_ASSUM_TAC(REWRITE_RULE[GSYM REAL_OF_NUM_LE]) THEN ASM_REAL_ARITH_TAC);; + +(* ------------------------------------------------------------------------- *) +(* Relating different kinds of real limits. *) +(* ------------------------------------------------------------------------- *) + +let LIM_POSINFINITY_SEQUENTIALLY = prove + (`!f l. (f --> l) at_posinfinity ==> ((\n. f(&n)) --> l) sequentially`, + REPEAT GEN_TAC THEN + REWRITE_TAC[LIM_AT_POSINFINITY; LIM_SEQUENTIALLY] THEN + DISCH_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 `B:real`) THEN + MP_TAC(ISPEC `B:real` REAL_ARCH_SIMPLE) THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `N:num` THEN + REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + RULE_ASSUM_TAC(REWRITE_RULE[GSYM REAL_OF_NUM_LE]) THEN ASM_REAL_ARITH_TAC);; + +let REALLIM_POSINFINITY_SEQUENTIALLY = prove + (`!f l. (f ---> l) at_posinfinity ==> ((\n. f(&n)) ---> l) sequentially`, + REPEAT GEN_TAC THEN REWRITE_TAC[TENDSTO_REAL] THEN + DISCH_THEN(MP_TAC o MATCH_MP LIM_POSINFINITY_SEQUENTIALLY) THEN + REWRITE_TAC[o_DEF]);; + +let LIM_ZERO_POSINFINITY = prove + (`!f l. ((\x. f(&1 / x)) --> l) (atreal (&0)) ==> (f --> l) at_posinfinity`, + REPEAT GEN_TAC THEN REWRITE_TAC[LIM_ATREAL; LIM_AT_POSINFINITY] THEN + DISCH_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 + REWRITE_TAC[dist; REAL_SUB_RZERO; real_ge] THEN + DISCH_THEN(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `&2 / d` THEN X_GEN_TAC `z:real` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `inv(z):real`) THEN + REWRITE_TAC[real_div; REAL_MUL_LINV; REAL_INV_INV] THEN + REWRITE_TAC[REAL_MUL_LID] THEN DISCH_THEN MATCH_MP_TAC THEN + ASM_REWRITE_TAC[REAL_ABS_INV; REAL_LT_INV_EQ] THEN CONJ_TAC THENL + [FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH + `a <= z ==> &0 < a ==> &0 < abs z`)); + GEN_REWRITE_TAC RAND_CONV [GSYM REAL_INV_INV] THEN + MATCH_MP_TAC REAL_LT_INV2 THEN ASM_REWRITE_TAC[REAL_LT_INV_EQ] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH + `&2 / d <= z ==> &0 < &2 / d ==> inv d < abs z`))] THEN + ASM_SIMP_TAC[REAL_LT_DIV; REAL_OF_NUM_LT; ARITH]);; + +let LIM_ZERO_NEGINFINITY = prove + (`!f l. ((\x. f(&1 / x)) --> l) (atreal (&0)) ==> (f --> l) at_neginfinity`, + REPEAT GEN_TAC THEN REWRITE_TAC[LIM_ATREAL; LIM_AT_NEGINFINITY] THEN + DISCH_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 + REWRITE_TAC[dist; REAL_SUB_RZERO; real_ge] THEN + DISCH_THEN(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `--(&2 / d)` THEN X_GEN_TAC `z:real` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `inv(z):real`) THEN + REWRITE_TAC[real_div; REAL_MUL_LINV; REAL_INV_INV] THEN + REWRITE_TAC[REAL_MUL_LID] THEN DISCH_THEN MATCH_MP_TAC THEN + ASM_REWRITE_TAC[REAL_ABS_INV; REAL_LT_INV_EQ] THEN CONJ_TAC THENL + [FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH + `z <= --a ==> &0 < a ==> &0 < abs z`)); + GEN_REWRITE_TAC RAND_CONV [GSYM REAL_INV_INV] THEN + MATCH_MP_TAC REAL_LT_INV2 THEN ASM_REWRITE_TAC[REAL_LT_INV_EQ] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH + `z <= --(&2 / d) ==> &0 < &2 / d ==> inv d < abs z`))] THEN + ASM_SIMP_TAC[REAL_LT_DIV; REAL_OF_NUM_LT; ARITH]);; + +let REALLIM_ZERO_POSINFINITY = prove + (`!f l. ((\x. f(&1 / x)) ---> l) (atreal (&0)) ==> (f ---> l) at_posinfinity`, + REPEAT GEN_TAC THEN REWRITE_TAC[TENDSTO_REAL] THEN + REWRITE_TAC[o_DEF; LIM_ZERO_POSINFINITY]);; + +let REALLIM_ZERO_NEGINFINITY = prove + (`!f l. ((\x. f(&1 / x)) ---> l) (atreal (&0)) ==> (f ---> l) at_neginfinity`, + REPEAT GEN_TAC THEN REWRITE_TAC[TENDSTO_REAL] THEN + REWRITE_TAC[o_DEF; LIM_ZERO_NEGINFINITY]);; + +(* ------------------------------------------------------------------------- *) +(* Real segments (bidirectional intervals). *) +(* ------------------------------------------------------------------------- *) + +let closed_real_segment = define + `closed_real_segment[a,b] = {(&1 - u) * a + u * b | &0 <= u /\ u <= &1}`;; + +let open_real_segment = new_definition + `open_real_segment(a,b) = closed_real_segment[a,b] DIFF {a,b}`;; + +make_overloadable "real_segment" `:A`;; + +overload_interface("real_segment",`open_real_segment`);; +overload_interface("real_segment",`closed_real_segment`);; + +let real_segment = prove + (`real_segment[a,b] = {(&1 - u) * a + u * b | &0 <= u /\ u <= &1} /\ + real_segment(a,b) = real_segment[a,b] DIFF {a,b}`, + REWRITE_TAC[open_real_segment; closed_real_segment]);; + +let REAL_SEGMENT_SEGMENT = prove + (`(!a b. real_segment[a,b] = IMAGE drop (segment[lift a,lift b])) /\ + (!a b. real_segment(a,b) = IMAGE drop (segment(lift a,lift b)))`, + REWRITE_TAC[segment; real_segment] THEN + SIMP_TAC[IMAGE_DIFF_INJ; DROP_EQ; IMAGE_CLAUSES; LIFT_DROP] THEN + ONCE_REWRITE_TAC[SIMPLE_IMAGE_GEN] THEN + REWRITE_TAC[GSYM IMAGE_o; o_DEF; DROP_ADD; DROP_CMUL; LIFT_DROP]);; + +let SEGMENT_REAL_SEGMENT = prove + (`(!a b. segment[a,b] = IMAGE lift (real_segment[drop a,drop b])) /\ + (!a b. segment(a,b) = IMAGE lift (real_segment(drop a,drop b)))`, + REWRITE_TAC[REAL_SEGMENT_SEGMENT; GSYM IMAGE_o] THEN + REWRITE_TAC[o_DEF; IMAGE_ID; LIFT_DROP]);; + +let IMAGE_LIFT_REAL_SEGMENT = prove + (`(!a b. IMAGE lift (real_segment[a,b]) = segment[lift a,lift b]) /\ + (!a b. IMAGE lift (real_segment(a,b)) = segment(lift a,lift b))`, + REWRITE_TAC[SEGMENT_REAL_SEGMENT; LIFT_DROP]);; + +let REAL_SEGMENT_INTERVAL = prove + (`(!a b. real_segment[a,b] = + if a <= b then real_interval[a,b] else real_interval[b,a]) /\ + (!a b. real_segment(a,b) = + if a <= b then real_interval(a,b) else real_interval(b,a))`, + REWRITE_TAC[REAL_SEGMENT_SEGMENT; SEGMENT_1; LIFT_DROP] THEN + REWRITE_TAC[REAL_INTERVAL_INTERVAL] THEN + CONJ_TAC THEN REPEAT GEN_TAC THEN COND_CASES_TAC THEN REWRITE_TAC[]);; + +let REAL_CONTINUOUS_INJECTIVE_IFF_MONOTONIC = prove + (`!f s. + f real_continuous_on s /\ is_realinterval s + ==> ((!x y. x IN s /\ y IN s /\ f x = f y ==> x = y) <=> + (!x y. x IN s /\ y IN s /\ x < y ==> f x < f y) \/ + (!x y. x IN s /\ y IN s /\ x < y ==> f y < f x))`, + REPEAT GEN_TAC THEN + REWRITE_TAC[REAL_CONTINUOUS_ON; IS_REALINTERVAL_IS_INTERVAL] THEN + DISCH_THEN(MP_TAC o MATCH_MP CONTINUOUS_INJECTIVE_IFF_MONOTONIC) THEN + REWRITE_TAC[FORALL_LIFT; LIFT_IN_IMAGE_LIFT; o_THM; LIFT_DROP; LIFT_EQ]);; + +(* ------------------------------------------------------------------------- *) +(* Convex real->real functions. *) +(* ------------------------------------------------------------------------- *) + +parse_as_infix ("real_convex_on",(12,"right"));; + +let real_convex_on = new_definition + `(f:real->real) real_convex_on s <=> + !x y u v. x IN s /\ y IN s /\ &0 <= u /\ &0 <= v /\ (u + v = &1) + ==> f(u * x + v * y) <= u * f(x) + v * f(y)`;; + +let REAL_CONVEX_ON = prove + (`!f s. f real_convex_on s <=> (f o drop) convex_on (IMAGE lift s)`, + REWRITE_TAC[real_convex_on; convex_on] THEN + REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_IMAGE] THEN + REWRITE_TAC[o_THM; LIFT_DROP; DROP_ADD; DROP_CMUL]);; + +let REAL_CONVEX_ON_SUBSET = prove + (`!f s t. f real_convex_on t /\ s SUBSET t ==> f real_convex_on s`, + REWRITE_TAC[REAL_CONVEX_ON] THEN + MESON_TAC[CONVEX_ON_SUBSET; IMAGE_SUBSET]);; + +let REAL_CONVEX_ADD = prove + (`!s f g. f real_convex_on s /\ g real_convex_on s + ==> (\x. f(x) + g(x)) real_convex_on s`, + REWRITE_TAC[REAL_CONVEX_ON; o_DEF; CONVEX_ADD]);; + +let REAL_CONVEX_LMUL = prove + (`!s c f. &0 <= c /\ f real_convex_on s ==> (\x. c * f(x)) real_convex_on s`, + REPEAT GEN_TAC THEN REWRITE_TAC[REAL_CONVEX_ON; o_DEF] THEN + DISCH_THEN(MP_TAC o MATCH_MP CONVEX_CMUL) THEN REWRITE_TAC[]);; + +let REAL_CONVEX_RMUL = prove + (`!s c f. &0 <= c /\ f real_convex_on s ==> (\x. f(x) * c) real_convex_on s`, + ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN REWRITE_TAC[REAL_CONVEX_LMUL]);; + +let REAL_CONVEX_LOWER = prove + (`!f s x y. f real_convex_on s /\ + x IN s /\ y IN s /\ &0 <= u /\ &0 <= v /\ u + v = &1 + ==> f(u * x + v * y) <= max (f(x)) (f(y))`, + REWRITE_TAC[REAL_CONVEX_ON] THEN + REWRITE_TAC[FORALL_DROP; GSYM IN_IMAGE_LIFT_DROP] THEN + REPEAT GEN_TAC THEN DISCH_THEN(MP_TAC o MATCH_MP CONVEX_LOWER) THEN + REWRITE_TAC[o_THM; DROP_ADD; DROP_CMUL]);; + +let REAL_CONVEX_LOCAL_GLOBAL_MINIMUM = prove + (`!f s t x. + f real_convex_on s /\ x IN t /\ real_open t /\ t SUBSET s /\ + (!y. y IN t ==> f(x) <= f(y)) + ==> !y. y IN s ==> f(x) <= f(y)`, + REWRITE_TAC[REAL_CONVEX_ON; REAL_OPEN] THEN + REWRITE_TAC[FORALL_DROP; GSYM IN_IMAGE_LIFT_DROP] THEN + REWRITE_TAC[FORALL_IN_IMAGE; LIFT_DROP] THEN + REPEAT GEN_TAC THEN STRIP_TAC THEN + MP_TAC(ISPECL [`(f:real->real) o drop`; `IMAGE lift s`; + `IMAGE lift t`; `x:real^1`] CONVEX_LOCAL_GLOBAL_MINIMUM) THEN + ASM_SIMP_TAC[FORALL_IN_IMAGE; LIFT_DROP; o_THM; IMAGE_SUBSET]);; + +let REAL_CONVEX_DISTANCE = prove + (`!s a. (\x. abs(a - x)) real_convex_on s`, + REWRITE_TAC[REAL_CONVEX_ON; o_DEF; FORALL_DROP; GSYM DROP_SUB] THEN + REWRITE_TAC[drop; GSYM NORM_REAL; GSYM dist; CONVEX_DISTANCE]);; + +let REAL_CONVEX_ON_JENSEN = prove + (`!f s. is_realinterval s + ==> (f real_convex_on s <=> + !k u x. + (!i:num. 1 <= i /\ i <= k ==> &0 <= u(i) /\ x(i) IN s) /\ + (sum (1..k) u = &1) + ==> f(sum (1..k) (\i. u(i) * x(i))) + <= sum (1..k) (\i. u(i) * f(x(i))))`, + REWRITE_TAC[IS_REALINTERVAL_CONVEX; REAL_CONVEX_ON] THEN + SIMP_TAC[CONVEX_ON_JENSEN] THEN REPEAT STRIP_TAC THEN + SIMP_TAC[o_DEF; DROP_VSUM; FINITE_NUMSEG] THEN + AP_TERM_TAC THEN GEN_REWRITE_TAC I [FUN_EQ_THM] THEN + X_GEN_TAC `k:num` THEN REWRITE_TAC[] THEN + AP_TERM_TAC THEN GEN_REWRITE_TAC I [FUN_EQ_THM] THEN + X_GEN_TAC `u:num->real` THEN REWRITE_TAC[] THEN EQ_TAC THEN DISCH_TAC THENL + [X_GEN_TAC `x:num->real` THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `lift o (x:num->real)`) THEN + ASM_REWRITE_TAC[o_DEF; LIFT_DROP; IN_IMAGE_LIFT_DROP] THEN + REWRITE_TAC[DROP_CMUL; LIFT_DROP]; + X_GEN_TAC `x:num->real^1` THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `drop o (x:num->real^1)`) THEN + ASM_REWRITE_TAC[o_DEF; LIFT_DROP; IN_IMAGE_LIFT_DROP] THEN + ASM_REWRITE_TAC[DROP_CMUL; LIFT_DROP; GSYM IN_IMAGE_LIFT_DROP]]);; + +let REAL_CONVEX_ON_CONTINUOUS = prove + (`!f s. real_open s /\ f real_convex_on s ==> f real_continuous_on s`, + REWRITE_TAC[REAL_CONVEX_ON; REAL_OPEN; REAL_CONTINUOUS_ON] THEN + REWRITE_TAC[CONVEX_ON_CONTINUOUS]);; + +let REAL_CONVEX_ON_LEFT_SECANT_MUL = prove + (`!f s. f real_convex_on s <=> + !a b x. a IN s /\ b IN s /\ x IN real_segment[a,b] + ==> (f x - f a) * abs(b - a) <= (f b - f a) * abs(x - a)`, + REWRITE_TAC[REAL_CONVEX_ON; CONVEX_ON_LEFT_SECANT_MUL] THEN + REWRITE_TAC[REAL_SEGMENT_SEGMENT] THEN + REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_IMAGE] THEN + REWRITE_TAC[o_DEF; LIFT_DROP] THEN + REWRITE_TAC[NORM_REAL; GSYM drop; DROP_SUB; LIFT_DROP]);; + +let REAL_CONVEX_ON_RIGHT_SEQUENT_MUL = prove + (`!f s. f real_convex_on s <=> + !a b x. a IN s /\ b IN s /\ x IN real_segment[a,b] + ==> (f b - f a) * abs(b - x) <= (f b - f x) * abs(b - a)`, + REWRITE_TAC[REAL_CONVEX_ON; CONVEX_ON_RIGHT_SECANT_MUL] THEN + REWRITE_TAC[REAL_SEGMENT_SEGMENT] THEN + REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_IMAGE] THEN + REWRITE_TAC[o_DEF; LIFT_DROP] THEN + REWRITE_TAC[NORM_REAL; GSYM drop; DROP_SUB; LIFT_DROP]);; + +let REAL_CONVEX_ON_LEFT_SECANT = prove + (`!f s. + f real_convex_on s <=> + !a b x. a IN s /\ b IN s /\ x IN real_segment(a,b) + ==> (f x - f a) / abs(x - a) <= (f b - f a) / abs(b - a)`, + REWRITE_TAC[REAL_CONVEX_ON; CONVEX_ON_LEFT_SECANT] THEN + REWRITE_TAC[REAL_SEGMENT_SEGMENT] THEN + REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_IMAGE] THEN + REWRITE_TAC[o_DEF; LIFT_DROP] THEN + REWRITE_TAC[NORM_REAL; GSYM drop; DROP_SUB; LIFT_DROP]);; + +let REAL_CONVEX_ON_RIGHT_SEQUENT = prove + (`!f s. + f real_convex_on s <=> + !a b x. a IN s /\ b IN s /\ x IN real_segment(a,b) + ==> (f b - f a) / abs(b - a) <= (f b - f x) / abs(b - x)`, + REWRITE_TAC[REAL_CONVEX_ON; CONVEX_ON_RIGHT_SECANT] THEN + REWRITE_TAC[REAL_SEGMENT_SEGMENT] THEN + REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_IMAGE] THEN + REWRITE_TAC[o_DEF; LIFT_DROP] THEN + REWRITE_TAC[NORM_REAL; GSYM drop; DROP_SUB; LIFT_DROP]);; + +let REAL_CONVEX_ON_DERIVATIVE_SECANT_IMP = prove + (`!f f' s x y. + f real_convex_on s /\ real_segment[x,y] SUBSET s /\ + (f has_real_derivative f') (atreal x within s) + ==> f' * (y - x) <= f y - f x`, + REWRITE_TAC[HAS_REAL_FRECHET_DERIVATIVE_WITHIN; + REAL_CONVEX_ON; REAL_SEGMENT_SEGMENT] THEN + REWRITE_TAC[SUBSET; IN_IMAGE_LIFT_DROP] THEN + REPEAT GEN_TAC THEN REWRITE_TAC[FORALL_DROP] THEN + REWRITE_TAC[LIFT_DROP] THEN + REWRITE_TAC[GSYM IN_IMAGE_LIFT_DROP; GSYM SUBSET] THEN + ONCE_REWRITE_TAC[GSYM(REWRITE_CONV[LIFT_DROP] + `\x. lift(drop(f % x))`)] THEN + REWRITE_TAC[GSYM o_DEF] THEN + DISCH_THEN(MP_TAC o MATCH_MP CONVEX_ON_DERIVATIVE_SECANT_IMP) THEN + REWRITE_TAC[o_THM; DROP_CMUL; DROP_SUB; LIFT_DROP]);; + +let REAL_CONVEX_ON_SECANT_DERIVATIVE_IMP = prove + (`!f f' s x y. + f real_convex_on s /\ real_segment[x,y] SUBSET s /\ + (f has_real_derivative f') (atreal y within s) + ==> f y - f x <= f' * (y - x)`, + REWRITE_TAC[HAS_REAL_FRECHET_DERIVATIVE_WITHIN; + REAL_CONVEX_ON; REAL_SEGMENT_SEGMENT] THEN + REWRITE_TAC[SUBSET; IN_IMAGE_LIFT_DROP] THEN + REPEAT GEN_TAC THEN REWRITE_TAC[FORALL_DROP] THEN + REWRITE_TAC[LIFT_DROP] THEN + REWRITE_TAC[GSYM IN_IMAGE_LIFT_DROP; GSYM SUBSET] THEN + ONCE_REWRITE_TAC[GSYM(REWRITE_CONV[LIFT_DROP] + `\x. lift(drop(f % x))`)] THEN + REWRITE_TAC[GSYM o_DEF] THEN + DISCH_THEN(MP_TAC o MATCH_MP CONVEX_ON_SECANT_DERIVATIVE_IMP) THEN + REWRITE_TAC[o_THM; DROP_CMUL; DROP_SUB; LIFT_DROP]);; + +let REAL_CONVEX_ON_DERIVATIVES_IMP = prove + (`!f f'x f'y s x y. + f real_convex_on s /\ real_segment[x,y] SUBSET s /\ + (f has_real_derivative f'x) (atreal x within s) /\ + (f has_real_derivative f'y) (atreal y within s) + ==> f'x * (y - x) <= f'y * (y - x)`, + REWRITE_TAC[HAS_REAL_FRECHET_DERIVATIVE_WITHIN; + REAL_CONVEX_ON; REAL_SEGMENT_SEGMENT] THEN + REWRITE_TAC[SUBSET; IN_IMAGE_LIFT_DROP] THEN + REPEAT GEN_TAC THEN REWRITE_TAC[FORALL_DROP] THEN + REWRITE_TAC[LIFT_DROP] THEN + REWRITE_TAC[GSYM IN_IMAGE_LIFT_DROP; GSYM SUBSET] THEN + ONCE_REWRITE_TAC[GSYM(REWRITE_CONV[LIFT_DROP] + `\x. lift(drop(f % x))`)] THEN + REWRITE_TAC[GSYM o_DEF] THEN + DISCH_THEN(MP_TAC o MATCH_MP CONVEX_ON_DERIVATIVES_IMP) THEN + REWRITE_TAC[o_THM; DROP_CMUL; DROP_SUB; LIFT_DROP]);; + +let REAL_CONVEX_ON_DERIVATIVE_INCREASING_IMP = prove + (`!f f'x f'y s x y. + f real_convex_on s /\ real_interval[x,y] SUBSET s /\ + (f has_real_derivative f'x) (atreal x within s) /\ + (f has_real_derivative f'y) (atreal y within s) /\ + x < y + ==> f'x <= f'y`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`f:real->real`; `f'x:real`; `f'y:real`; `s:real->bool`; + `x:real`; `y:real`] REAL_CONVEX_ON_DERIVATIVES_IMP) THEN + ASM_REWRITE_TAC[REAL_SEGMENT_INTERVAL] THEN + ASM_SIMP_TAC[REAL_LT_IMP_LE; REAL_LE_RMUL_EQ; REAL_SUB_LT]);; + +let REAL_CONVEX_ON_DERIVATIVE_SECANT = prove + (`!f f' s. + is_realinterval s /\ + (!x. x IN s ==> (f has_real_derivative f'(x)) (atreal x within s)) + ==> (f real_convex_on s <=> + !x y. x IN s /\ y IN s ==> f'(x) * (y - x) <= f y - f x)`, + REWRITE_TAC[HAS_REAL_FRECHET_DERIVATIVE_WITHIN; + REAL_CONVEX_ON; IS_REALINTERVAL_CONVEX] THEN + REPEAT GEN_TAC THEN + REWRITE_TAC[FORALL_DROP; GSYM IN_IMAGE_LIFT_DROP; LIFT_DROP] THEN + ONCE_REWRITE_TAC[GSYM(REWRITE_CONV[LIFT_DROP; o_DEF] + `lift o (\x. drop(f % x))`)] THEN + DISCH_THEN(SUBST1_TAC o MATCH_MP CONVEX_ON_DERIVATIVE_SECANT) THEN + REWRITE_TAC[DROP_CMUL; DROP_SUB; o_THM]);; + +let REAL_CONVEX_ON_SECANT_DERIVATIVE = prove + (`!f f' s. + is_realinterval s /\ + (!x. x IN s ==> (f has_real_derivative f'(x)) (atreal x within s)) + ==> (f real_convex_on s <=> + !x y. x IN s /\ y IN s ==> f y - f x <= f'(y) * (y - x))`, + REWRITE_TAC[HAS_REAL_FRECHET_DERIVATIVE_WITHIN; + REAL_CONVEX_ON; IS_REALINTERVAL_CONVEX] THEN + REPEAT GEN_TAC THEN + REWRITE_TAC[FORALL_DROP; GSYM IN_IMAGE_LIFT_DROP; LIFT_DROP] THEN + ONCE_REWRITE_TAC[GSYM(REWRITE_CONV[LIFT_DROP; o_DEF] + `lift o (\x. drop(f % x))`)] THEN + DISCH_THEN(SUBST1_TAC o MATCH_MP CONVEX_ON_SECANT_DERIVATIVE) THEN + REWRITE_TAC[DROP_CMUL; DROP_SUB; o_THM]);; + +let REAL_CONVEX_ON_DERIVATIVES = prove + (`!f f' s. + is_realinterval s /\ + (!x. x IN s ==> (f has_real_derivative f'(x)) (atreal x within s)) + ==> (f real_convex_on s <=> + !x y. x IN s /\ y IN s ==> f'(x) * (y - x) <= f'(y) * (y - x))`, + REWRITE_TAC[HAS_REAL_FRECHET_DERIVATIVE_WITHIN; + REAL_CONVEX_ON; IS_REALINTERVAL_CONVEX] THEN + REPEAT GEN_TAC THEN + REWRITE_TAC[FORALL_DROP; GSYM IN_IMAGE_LIFT_DROP; LIFT_DROP] THEN + ONCE_REWRITE_TAC[GSYM(REWRITE_CONV[LIFT_DROP; o_DEF] + `lift o (\x. drop(f % x))`)] THEN + DISCH_THEN(SUBST1_TAC o MATCH_MP CONVEX_ON_DERIVATIVES) THEN + REWRITE_TAC[DROP_CMUL; DROP_SUB; o_THM]);; + +let REAL_CONVEX_ON_DERIVATIVE_INCREASING = prove + (`!f f' s. + is_realinterval s /\ + (!x. x IN s ==> (f has_real_derivative f'(x)) (atreal x within s)) + ==> (f real_convex_on s <=> + !x y. x IN s /\ y IN s /\ x <= y ==> f'(x) <= f'(y))`, + REPEAT GEN_TAC THEN DISCH_TAC THEN + FIRST_ASSUM(SUBST1_TAC o MATCH_MP REAL_CONVEX_ON_DERIVATIVES) THEN + EQ_TAC THEN DISCH_TAC THEN MAP_EVERY X_GEN_TAC [`x:real`; `y:real`] THEN + STRIP_TAC THENL + [FIRST_X_ASSUM(MP_TAC o SPECL [`x:real`; `y:real`]) THEN + ASM_CASES_TAC `x:real = y` THEN ASM_REWRITE_TAC[REAL_LE_REFL] THEN + ASM_SIMP_TAC[REAL_LE_RMUL_EQ; REAL_SUB_LT; REAL_LT_LE]; + DISJ_CASES_TAC(REAL_ARITH `x <= y \/ y <= x`) THENL + [FIRST_X_ASSUM(MP_TAC o SPECL [`x:real`; `y:real`]); + FIRST_X_ASSUM(MP_TAC o SPECL [`y:real`; `x:real`])] THEN + ASM_CASES_TAC `x:real = y` THEN ASM_REWRITE_TAC[REAL_LE_REFL] THEN + ASM_SIMP_TAC[REAL_LE_RMUL_EQ; REAL_SUB_LT; REAL_LT_LE] THEN + ONCE_REWRITE_TAC[REAL_ARITH + `a * (y - x) <= b * (y - x) <=> b * (x - y) <= a * (x - y)`] THEN + ASM_SIMP_TAC[REAL_LE_RMUL_EQ; REAL_SUB_LT; REAL_LT_LE]]);; + +let HAS_REAL_DERIVATIVE_INCREASING_IMP = prove + (`!f f' s a b. + is_realinterval s /\ + (!x. x IN s ==> (f has_real_derivative f'(x)) (atreal x within s)) /\ + (!x. x IN s ==> &0 <= f'(x)) /\ + a IN s /\ b IN s /\ a <= b + ==> f(a) <= f(b)`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN `real_interval[a,b] SUBSET s` ASSUME_TAC THENL + [REWRITE_TAC[SUBSET; IN_REAL_INTERVAL] THEN REPEAT STRIP_TAC THEN + FIRST_X_ASSUM(MATCH_MP_TAC o GEN_REWRITE_RULE I [is_realinterval]) THEN + MAP_EVERY EXISTS_TAC [`a:real`; `b:real`] THEN ASM_REWRITE_TAC[]; + ALL_TAC] THEN + MP_TAC(ISPECL [`f:real->real`; `f':real->real`; `a:real`; `b:real`] + REAL_MVT_VERY_SIMPLE) THEN + ANTS_TAC THENL + [ASM_REWRITE_TAC[] THEN X_GEN_TAC `z:real` THEN DISCH_TAC THEN + MATCH_MP_TAC HAS_REAL_DERIVATIVE_WITHIN_SUBSET THEN + EXISTS_TAC `s:real->bool` THEN ASM SET_TAC[]; + DISCH_THEN(X_CHOOSE_THEN `z:real` MP_TAC) THEN STRIP_TAC THEN + GEN_REWRITE_TAC I [GSYM REAL_SUB_LE] THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC REAL_LE_MUL THEN + CONJ_TAC THENL [ASM SET_TAC[]; ASM_REAL_ARITH_TAC]]);; + +let HAS_REAL_DERIVATIVE_INCREASING = prove + (`!f f' s. is_realinterval s /\ ~(?a. s = {a}) /\ + (!x. x IN s ==> (f has_real_derivative f'(x)) (atreal x within s)) + ==> ((!x. x IN s ==> &0 <= f'(x)) <=> + (!x y. x IN s /\ y IN s /\ x <= y ==> f(x) <= f(y)))`, + REWRITE_TAC[NOT_EXISTS_THM] THEN REPEAT STRIP_TAC THEN EQ_TAC THENL + [ASM_MESON_TAC[HAS_REAL_DERIVATIVE_INCREASING_IMP]; ALL_TAC] THEN + DISCH_TAC THEN X_GEN_TAC `x:real` THEN DISCH_TAC THEN + MATCH_MP_TAC(ISPEC `atreal x within s` REALLIM_LBOUND) THEN + EXISTS_TAC `\y:real. (f y - f x) / (y - x)` THEN + ASM_SIMP_TAC[GSYM HAS_REAL_DERIVATIVE_WITHINREAL] THEN + ASM_SIMP_TAC[TRIVIAL_LIMIT_WITHIN_REALINTERVAL] THEN + REWRITE_TAC[EVENTUALLY_WITHINREAL] THEN + EXISTS_TAC `&1` THEN REWRITE_TAC[REAL_LT_01] THEN + X_GEN_TAC `y:real` THEN + REWRITE_TAC[REAL_ARITH `&0 < abs(y - x) <=> ~(y = x)`] THEN STRIP_TAC THEN + FIRST_ASSUM(DISJ_CASES_TAC o MATCH_MP (REAL_ARITH + `~(y:real = x) ==> x < y \/ y < x`)) + THENL + [ALL_TAC; + ONCE_REWRITE_TAC[GSYM REAL_NEG_SUB] THEN + REWRITE_TAC[real_div; REAL_INV_NEG; REAL_MUL_LNEG; REAL_MUL_RNEG] THEN + REWRITE_TAC[REAL_NEG_NEG; GSYM real_div]] THEN + MATCH_MP_TAC REAL_LE_DIV THEN + ASM_SIMP_TAC[REAL_SUB_LE; REAL_LT_IMP_LE]);; + +let REAL_CONVEX_ON_SECOND_DERIVATIVE = prove + (`!f f' f'' s. + is_realinterval s /\ ~(?a. s = {a}) /\ + (!x. x IN s ==> (f has_real_derivative f'(x)) (atreal x within s)) /\ + (!x. x IN s ==> (f' has_real_derivative f''(x)) (atreal x within s)) + ==> (f real_convex_on s <=> !x. x IN s ==> &0 <= f''(x))`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC EQ_TRANS THEN EXISTS_TAC + `!x y. x IN s /\ y IN s /\ x <= y ==> (f':real->real)(x) <= f'(y)` THEN + CONJ_TAC THENL + [MATCH_MP_TAC REAL_CONVEX_ON_DERIVATIVE_INCREASING; + CONV_TAC SYM_CONV THEN MATCH_MP_TAC HAS_REAL_DERIVATIVE_INCREASING] THEN + ASM_REWRITE_TAC[]);; + +let REAL_CONVEX_ON_ASYM = prove + (`!s f. f real_convex_on s <=> + !x y u v. + x IN s /\ y IN s /\ x < y /\ &0 <= u /\ &0 <= v /\ u + v = &1 + ==> f (u * x + v * y) <= u * f x + v * f y`, + REPEAT GEN_TAC THEN REWRITE_TAC[real_convex_on] THEN + EQ_TAC THEN STRIP_TAC THEN ASM_SIMP_TAC[] THEN + MATCH_MP_TAC REAL_WLOG_LT THEN + SIMP_TAC[GSYM REAL_ADD_RDISTRIB; REAL_MUL_LID; REAL_LE_REFL] THEN + ASM_MESON_TAC[REAL_ADD_SYM]);; + +let REAL_CONVEX_ON_EXP = prove + (`!s. exp real_convex_on s`, + GEN_TAC THEN MATCH_MP_TAC REAL_CONVEX_ON_SUBSET THEN + EXISTS_TAC `(:real)` THEN REWRITE_TAC[SUBSET_UNIV] THEN + MP_TAC(ISPECL [`exp`; `exp`; `exp`; `(:real)`] + REAL_CONVEX_ON_SECOND_DERIVATIVE) THEN + SIMP_TAC[HAS_REAL_DERIVATIVE_EXP; REAL_EXP_POS_LE; + HAS_REAL_DERIVATIVE_ATREAL_WITHIN; IS_REALINTERVAL_UNIV] THEN + DISCH_THEN MATCH_MP_TAC THEN + MATCH_MP_TAC(SET_RULE + `&0 IN s /\ &1 IN s /\ ~(&1 = &0) ==> ~(?a. s = {a})`) THEN + REWRITE_TAC[IN_UNIV] THEN REAL_ARITH_TAC);; + +let REAL_CONVEX_ON_RPOW = prove + (`!s t. s SUBSET {x | &0 <= x} /\ &1 <= t + ==> (\x. x rpow t) real_convex_on s`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_CONVEX_ON_SUBSET THEN + EXISTS_TAC `{x | &0 <= x}` THEN ASM_REWRITE_TAC[] THEN + SUBGOAL_THEN `(\x. x rpow t) real_convex_on {x | &0 < x}` MP_TAC THENL + [MP_TAC(ISPECL + [`\x. x rpow t`; `\x. t * x rpow (t - &1)`; + `\x. t * (t - &1) * x rpow (t - &2)`; `{x | &0 < x}`] + REAL_CONVEX_ON_SECOND_DERIVATIVE) THEN + ASM_REWRITE_TAC[IN_ELIM_THM] THEN ANTS_TAC THENL + [REPEAT CONJ_TAC THENL + [REWRITE_TAC[is_realinterval; IN_ELIM_THM] THEN REAL_ARITH_TAC; + MATCH_MP_TAC(SET_RULE + `&1 IN s /\ &2 IN s /\ ~(&1 = &2) ==> ~(?a. s = {a})`) THEN + REWRITE_TAC[IN_ELIM_THM] THEN REAL_ARITH_TAC; + REPEAT STRIP_TAC THEN REAL_DIFF_TAC THEN ASM_REAL_ARITH_TAC; + REPEAT STRIP_TAC THEN REAL_DIFF_TAC THEN + ASM_REWRITE_TAC[REAL_ARITH `t - &1 - &1 = t - &2`] THEN + ASM_REAL_ARITH_TAC]; + DISCH_THEN SUBST1_TAC THEN REPEAT STRIP_TAC THEN + REPEAT(MATCH_MP_TAC REAL_LE_MUL THEN CONJ_TAC THENL + [ASM_REAL_ARITH_TAC; ALL_TAC]) THEN + MATCH_MP_TAC RPOW_POS_LE THEN ASM_SIMP_TAC[REAL_LT_IMP_LE]]; + REWRITE_TAC[REAL_CONVEX_ON_ASYM] THEN + MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `x:real` THEN + REWRITE_TAC[IN_ELIM_THM] THEN ASM_CASES_TAC `x = &0` THENL + [DISCH_THEN(K ALL_TAC) THEN ASM_REWRITE_TAC[REAL_MUL_RZERO] THEN + REPEAT STRIP_TAC THEN + ASM_SIMP_TAC[RPOW_ZERO; REAL_ARITH `&1 <= t ==> ~(t = &0)`] THEN + REWRITE_TAC[REAL_MUL_RZERO; REAL_ADD_LID] THEN + ASM_CASES_TAC `v = &0` THEN + ASM_SIMP_TAC[RPOW_ZERO; REAL_ARITH `&1 <= t ==> ~(t = &0)`; + REAL_MUL_LZERO; REAL_LE_REFL] THEN + ASM_SIMP_TAC[RPOW_MUL; REAL_LT_LE] THEN + MATCH_MP_TAC REAL_LE_RMUL THEN + ASM_SIMP_TAC[RPOW_POS_LE; REAL_LT_IMP_LE] THEN + MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC `exp(&1 * log v)` THEN + CONJ_TAC THENL + [ASM_SIMP_TAC[rpow; REAL_LT_LE; REAL_EXP_MONO_LE] THEN + ONCE_REWRITE_TAC[REAL_ARITH + `a * l <= b * l <=> --l * b <= --l * a`] THEN + MATCH_MP_TAC REAL_LE_LMUL THEN ASM_REWRITE_TAC[] THEN + ASM_SIMP_TAC[GSYM LOG_INV; REAL_LT_LE] THEN MATCH_MP_TAC LOG_POS THEN + MATCH_MP_TAC REAL_INV_1_LE THEN ASM_REAL_ARITH_TAC; + ASM_SIMP_TAC[REAL_MUL_LID; EXP_LOG; REAL_LT_LE; REAL_LE_REFL]]; + ASM_MESON_TAC[REAL_LT_LE; REAL_LET_TRANS]]]);; + +(* ------------------------------------------------------------------------- *) +(* A couple of simple bounds that it's convenient to get this way. *) +(* ------------------------------------------------------------------------- *) + +let REAL_LE_X_SINH = prove + (`!x. &0 <= x ==> x <= (exp x - inv(exp x)) / &2`, + SUBGOAL_THEN + `!a b. a <= b + ==> exp a - inv(exp a) - &2 * a <= exp b - inv(exp b) - &2 * b` + (MP_TAC o SPEC `&0`) + THENL + [MP_TAC(ISPECL + [`\x. exp x - exp(--x) - &2 * x`; `\x. exp x + exp(--x) - &2`; `(:real)`] + HAS_REAL_DERIVATIVE_INCREASING) THEN + REWRITE_TAC[IN_ELIM_THM; IS_REALINTERVAL_UNIV; IN_UNIV] THEN ANTS_TAC THENL + [CONJ_TAC THENL [SET_TAC[REAL_ARITH `~(&1 = &0)`]; ALL_TAC] THEN + GEN_TAC THEN REAL_DIFF_TAC THEN REAL_ARITH_TAC; + SIMP_TAC[REAL_EXP_NEG] THEN DISCH_THEN(fun th -> SIMP_TAC[GSYM th]) THEN + X_GEN_TAC `x:real` THEN + SIMP_TAC[REAL_EXP_NZ; REAL_FIELD + `~(e = &0) ==> e + inv e - &2 = (e - &1) pow 2 / e`] THEN + SIMP_TAC[REAL_EXP_POS_LE; REAL_LE_DIV; REAL_LE_POW_2]]; + MATCH_MP_TAC MONO_FORALL THEN REWRITE_TAC[REAL_EXP_0] THEN + REAL_ARITH_TAC]);; + +let REAL_LE_ABS_SINH = prove + (`!x. abs x <= abs((exp x - inv(exp x)) / &2)`, + GEN_TAC THEN ASM_CASES_TAC `&0 <= x` THENL + [MATCH_MP_TAC(REAL_ARITH `&0 <= x /\ x <= y ==> abs x <= abs y`) THEN + ASM_SIMP_TAC[REAL_LE_X_SINH]; + MATCH_MP_TAC(REAL_ARITH `~(&0 <= x) /\ --x <= --y ==> abs x <= abs y`) THEN + ASM_REWRITE_TAC[REAL_ARITH `--((a - b) / &2) = (b - a) / &2`] THEN + MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `(exp(--x) - inv(exp(--x))) / &2` THEN + ASM_SIMP_TAC[REAL_LE_X_SINH; REAL_ARITH `~(&0 <= x) ==> &0 <= --x`] THEN + REWRITE_TAC[REAL_EXP_NEG; REAL_INV_INV] THEN REAL_ARITH_TAC]);; + +(* ------------------------------------------------------------------------- *) +(* Integrals of real->real functions; measures of real sets. *) +(* ------------------------------------------------------------------------- *) + +parse_as_infix("has_real_integral",(12,"right"));; +parse_as_infix("real_integrable_on",(12,"right"));; +parse_as_infix("absolutely_real_integrable_on",(12,"right"));; +parse_as_infix("has_real_measure",(12,"right"));; + +let has_real_integral = new_definition + `(f has_real_integral y) s <=> + ((lift o f o drop) has_integral (lift y)) (IMAGE lift s)`;; + +let real_integrable_on = new_definition + `f real_integrable_on i <=> ?y. (f has_real_integral y) i`;; + +let real_integral = new_definition + `real_integral i f = @y. (f has_real_integral y) i`;; + +let real_negligible = new_definition + `real_negligible s <=> negligible (IMAGE lift s)`;; + +let absolutely_real_integrable_on = new_definition + `f absolutely_real_integrable_on s <=> + f real_integrable_on s /\ (\x. abs(f x)) real_integrable_on s`;; + +let has_real_measure = new_definition + `s has_real_measure m <=> ((\x. &1) has_real_integral m) s`;; + +let real_measurable = new_definition + `real_measurable s <=> ?m. s has_real_measure m`;; + +let real_measure = new_definition + `real_measure s = @m. s has_real_measure m`;; + +let HAS_REAL_INTEGRAL = prove + (`(f has_real_integral y) (real_interval[a,b]) <=> + ((lift o f o drop) has_integral (lift y)) (interval[lift a,lift b])`, + REWRITE_TAC[has_real_integral; IMAGE_LIFT_REAL_INTERVAL]);; + +let REAL_INTEGRABLE_INTEGRAL = prove + (`!f i. f real_integrable_on i + ==> (f has_real_integral (real_integral i f)) i`, + REPEAT GEN_TAC THEN REWRITE_TAC[real_integrable_on; real_integral] THEN + CONV_TAC(RAND_CONV SELECT_CONV) THEN REWRITE_TAC[]);; + +let HAS_REAL_INTEGRAL_INTEGRABLE = prove + (`!f i s. (f has_real_integral i) s ==> f real_integrable_on s`, + REWRITE_TAC[real_integrable_on] THEN MESON_TAC[]);; + +let HAS_REAL_INTEGRAL_INTEGRAL = prove + (`!f s. f real_integrable_on s <=> + (f has_real_integral (real_integral s f)) s`, + MESON_TAC[REAL_INTEGRABLE_INTEGRAL; HAS_REAL_INTEGRAL_INTEGRABLE]);; + +let HAS_REAL_INTEGRAL_UNIQUE = prove + (`!f i k1 k2. + (f has_real_integral k1) i /\ (f has_real_integral k2) i ==> k1 = k2`, + REPEAT GEN_TAC THEN REWRITE_TAC[has_real_integral] THEN + DISCH_THEN(MP_TAC o MATCH_MP HAS_INTEGRAL_UNIQUE) THEN + REWRITE_TAC[LIFT_EQ]);; + +let REAL_INTEGRAL_UNIQUE = prove + (`!f y k. + (f has_real_integral y) k ==> real_integral k f = y`, + REPEAT STRIP_TAC THEN REWRITE_TAC[real_integral] THEN + MATCH_MP_TAC SELECT_UNIQUE THEN ASM_MESON_TAC[HAS_REAL_INTEGRAL_UNIQUE]);; + +let HAS_REAL_INTEGRAL_INTEGRABLE_INTEGRAL = prove + (`!f i s. + (f has_real_integral i) s <=> + f real_integrable_on s /\ real_integral s f = i`, + MESON_TAC[REAL_INTEGRABLE_INTEGRAL; REAL_INTEGRAL_UNIQUE; + real_integrable_on]);; + +let REAL_INTEGRAL_EQ_HAS_INTEGRAL = prove + (`!s f y. f real_integrable_on s + ==> (real_integral s f = y <=> (f has_real_integral y) s)`, + MESON_TAC[REAL_INTEGRABLE_INTEGRAL; REAL_INTEGRAL_UNIQUE]);; + +let REAL_INTEGRABLE_ON = prove + (`f real_integrable_on s <=> + (lift o f o drop) integrable_on (IMAGE lift s)`, + REWRITE_TAC[real_integrable_on; has_real_integral; EXISTS_DROP; + integrable_on; LIFT_DROP]);; + +let ABSOLUTELY_REAL_INTEGRABLE_ON = prove + (`f absolutely_real_integrable_on s <=> + (lift o f o drop) absolutely_integrable_on (IMAGE lift s)`, + REWRITE_TAC[absolutely_real_integrable_on; REAL_INTEGRABLE_ON; + absolutely_integrable_on] THEN + REWRITE_TAC[o_DEF; LIFT_DROP; NORM_LIFT]);; + +let REAL_INTEGRAL = prove + (`f real_integrable_on s + ==> real_integral s f = drop(integral (IMAGE lift s) (lift o f o drop))`, + REWRITE_TAC[REAL_INTEGRABLE_ON] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC REAL_INTEGRAL_UNIQUE THEN + REWRITE_TAC[has_real_integral; LIFT_DROP] THEN + ASM_REWRITE_TAC[GSYM HAS_INTEGRAL_INTEGRAL]);; + +let HAS_REAL_INTEGRAL_IS_0 = prove + (`!f s. (!x. x IN s ==> f(x) = &0) ==> (f has_real_integral &0) s`, + REPEAT STRIP_TAC THEN REWRITE_TAC[has_real_integral; LIFT_NUM] THEN + MATCH_MP_TAC HAS_INTEGRAL_IS_0 THEN + ASM_REWRITE_TAC[LIFT_EQ; FORALL_IN_IMAGE; o_THM; LIFT_DROP; GSYM LIFT_NUM]);; + +let HAS_REAL_INTEGRAL_0 = prove + (`!s. ((\x. &0) has_real_integral &0) s`, + SIMP_TAC[HAS_REAL_INTEGRAL_IS_0]);; + +let HAS_REAL_INTEGRAL_0_EQ = prove + (`!i s. ((\x. &0) has_real_integral i) s <=> i = &0`, + MESON_TAC[HAS_REAL_INTEGRAL_UNIQUE; HAS_REAL_INTEGRAL_0]);; + +let HAS_REAL_INTEGRAL_LINEAR = prove + (`!f:real->real y s h:real->real. + (f has_real_integral y) s /\ linear(lift o h o drop) + ==> ((h o f) has_real_integral h(y)) s`, + REPEAT GEN_TAC THEN REWRITE_TAC[has_real_integral] THEN + DISCH_THEN(MP_TAC o MATCH_MP HAS_INTEGRAL_LINEAR) THEN + REWRITE_TAC[o_DEF; LIFT_DROP]);; + +let HAS_REAL_INTEGRAL_LMUL = prove + (`!(f:real->real) k s c. + (f has_real_integral k) s + ==> ((\x. c * f(x)) has_real_integral (c * k)) s`, + REPEAT GEN_TAC THEN REWRITE_TAC[has_real_integral] THEN + DISCH_THEN(MP_TAC o SPEC `c:real` o MATCH_MP HAS_INTEGRAL_CMUL) THEN + REWRITE_TAC[GSYM LIFT_CMUL; o_DEF]);; + +let HAS_REAL_INTEGRAL_RMUL = prove + (`!(f:real->real) k s c. + (f has_real_integral k) s + ==> ((\x. f(x) * c) has_real_integral (k * c)) s`, + ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN + REWRITE_TAC[HAS_REAL_INTEGRAL_LMUL]);; + +let HAS_REAL_INTEGRAL_NEG = prove + (`!f k s. (f has_real_integral k) s + ==> ((\x. --(f x)) has_real_integral (--k)) s`, + REPEAT GEN_TAC THEN REWRITE_TAC[has_real_integral] THEN + DISCH_THEN(MP_TAC o MATCH_MP HAS_INTEGRAL_NEG) THEN + REWRITE_TAC[o_DEF; LIFT_NEG]);; + +let HAS_REAL_INTEGRAL_ADD = prove + (`!f:real->real g k l s. + (f has_real_integral k) s /\ (g has_real_integral l) s + ==> ((\x. f(x) + g(x)) has_real_integral (k + l)) s`, + REPEAT GEN_TAC THEN REWRITE_TAC[has_real_integral] THEN + DISCH_THEN(MP_TAC o MATCH_MP HAS_INTEGRAL_ADD) THEN + REWRITE_TAC[o_DEF; LIFT_ADD]);; + +let HAS_REAL_INTEGRAL_SUB = prove + (`!f:real->real g k l s. + (f has_real_integral k) s /\ (g has_real_integral l) s + ==> ((\x. f(x) - g(x)) has_real_integral (k - l)) s`, + REPEAT GEN_TAC THEN REWRITE_TAC[has_real_integral] THEN + DISCH_THEN(MP_TAC o MATCH_MP HAS_INTEGRAL_SUB) THEN + REWRITE_TAC[o_DEF; LIFT_SUB]);; + +let REAL_INTEGRAL_0 = prove + (`!s. real_integral s (\x. &0) = &0`, + MESON_TAC[REAL_INTEGRAL_UNIQUE; HAS_REAL_INTEGRAL_0]);; + +let REAL_INTEGRAL_ADD = prove + (`!f:real->real g s. + f real_integrable_on s /\ g real_integrable_on s + ==> real_integral s (\x. f x + g x) = + real_integral s f + real_integral s g`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_INTEGRAL_UNIQUE THEN + MATCH_MP_TAC HAS_REAL_INTEGRAL_ADD THEN + ASM_SIMP_TAC[REAL_INTEGRABLE_INTEGRAL]);; + +let REAL_INTEGRAL_LMUL = prove + (`!f:real->real c s. + f real_integrable_on s + ==> real_integral s (\x. c * f(x)) = c * real_integral s f`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_INTEGRAL_UNIQUE THEN + MATCH_MP_TAC HAS_REAL_INTEGRAL_LMUL THEN + ASM_SIMP_TAC[REAL_INTEGRABLE_INTEGRAL]);; + +let REAL_INTEGRAL_RMUL = prove + (`!f:real->real c s. + f real_integrable_on s + ==> real_integral s (\x. f(x) * c) = real_integral s f * c`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_INTEGRAL_UNIQUE THEN + MATCH_MP_TAC HAS_REAL_INTEGRAL_RMUL THEN + ASM_SIMP_TAC[REAL_INTEGRABLE_INTEGRAL]);; + +let REAL_INTEGRAL_NEG = prove + (`!f:real->real s. + f real_integrable_on s + ==> real_integral s (\x. --f(x)) = --real_integral s f`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_INTEGRAL_UNIQUE THEN + MATCH_MP_TAC HAS_REAL_INTEGRAL_NEG THEN + ASM_SIMP_TAC[REAL_INTEGRABLE_INTEGRAL]);; + +let REAL_INTEGRAL_SUB = prove + (`!f:real->real g s. + f real_integrable_on s /\ g real_integrable_on s + ==> real_integral s (\x. f x - g x) = + real_integral s f - real_integral s g`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_INTEGRAL_UNIQUE THEN + MATCH_MP_TAC HAS_REAL_INTEGRAL_SUB THEN + ASM_SIMP_TAC[REAL_INTEGRABLE_INTEGRAL]);; + +let REAL_INTEGRABLE_0 = prove + (`!s. (\x. &0) real_integrable_on s`, + REWRITE_TAC[real_integrable_on] THEN MESON_TAC[HAS_REAL_INTEGRAL_0]);; + +let REAL_INTEGRABLE_ADD = prove + (`!f:real->real g s. + f real_integrable_on s /\ g real_integrable_on s + ==> (\x. f x + g x) real_integrable_on s`, + REWRITE_TAC[real_integrable_on] THEN MESON_TAC[HAS_REAL_INTEGRAL_ADD]);; + +let REAL_INTEGRABLE_LMUL = prove + (`!f:real->real c s. + f real_integrable_on s + ==> (\x. c * f(x)) real_integrable_on s`, + REWRITE_TAC[real_integrable_on] THEN MESON_TAC[HAS_REAL_INTEGRAL_LMUL]);; + +let REAL_INTEGRABLE_RMUL = prove + (`!f:real->real c s. + f real_integrable_on s + ==> (\x. f(x) * c) real_integrable_on s`, + REWRITE_TAC[real_integrable_on] THEN MESON_TAC[HAS_REAL_INTEGRAL_RMUL]);; + +let REAL_INTEGRABLE_NEG = prove + (`!f:real->real s. + f real_integrable_on s ==> (\x. --f(x)) real_integrable_on s`, + REWRITE_TAC[real_integrable_on] THEN MESON_TAC[HAS_REAL_INTEGRAL_NEG]);; + +let REAL_INTEGRABLE_SUB = prove + (`!f:real->real g s. + f real_integrable_on s /\ g real_integrable_on s + ==> (\x. f x - g x) real_integrable_on s`, + REWRITE_TAC[real_integrable_on] THEN MESON_TAC[HAS_REAL_INTEGRAL_SUB]);; + +let REAL_INTEGRABLE_LINEAR = prove + (`!f h s. f real_integrable_on s /\ + linear(lift o h o drop) ==> (h o f) real_integrable_on s`, + REWRITE_TAC[real_integrable_on] THEN MESON_TAC[HAS_REAL_INTEGRAL_LINEAR]);; + +let REAL_INTEGRAL_LINEAR = prove + (`!f:real->real s h:real->real. + f real_integrable_on s /\ linear(lift o h o drop) + ==> real_integral s (h o f) = h(real_integral s f)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_REAL_INTEGRAL_UNIQUE THEN + MAP_EVERY EXISTS_TAC + [`(h:real->real) o (f:real->real)`; `s:real->bool`] THEN + CONJ_TAC THENL [ALL_TAC; MATCH_MP_TAC HAS_REAL_INTEGRAL_LINEAR] THEN + ASM_SIMP_TAC[GSYM HAS_REAL_INTEGRAL_INTEGRAL; REAL_INTEGRABLE_LINEAR]);; + +let HAS_REAL_INTEGRAL_SUM = prove + (`!f:A->real->real s t. + FINITE t /\ + (!a. a IN t ==> ((f a) has_real_integral (i a)) s) + ==> ((\x. sum t (\a. f a x)) has_real_integral (sum t i)) s`, + GEN_TAC THEN GEN_TAC THEN REWRITE_TAC[IMP_CONJ] THEN + MATCH_MP_TAC FINITE_INDUCT_STRONG THEN + SIMP_TAC[SUM_CLAUSES; HAS_REAL_INTEGRAL_0; IN_INSERT] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_REAL_INTEGRAL_ADD THEN + ASM_REWRITE_TAC[ETA_AX] THEN CONJ_TAC THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_SIMP_TAC[]);; + +let REAL_INTEGRAL_SUM = prove + (`!f:A->real->real s t. + FINITE t /\ + (!a. a IN t ==> (f a) real_integrable_on s) + ==> real_integral s (\x. sum t (\a. f a x)) = + sum t (\a. real_integral s (f a))`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_INTEGRAL_UNIQUE THEN + MATCH_MP_TAC HAS_REAL_INTEGRAL_SUM THEN + ASM_SIMP_TAC[REAL_INTEGRABLE_INTEGRAL]);; + +let REAL_INTEGRABLE_SUM = prove + (`!f:A->real->real s t. + FINITE t /\ + (!a. a IN t ==> (f a) real_integrable_on s) + ==> (\x. sum t (\a. f a x)) real_integrable_on s`, + REWRITE_TAC[real_integrable_on] THEN MESON_TAC[HAS_REAL_INTEGRAL_SUM]);; + +let HAS_REAL_INTEGRAL_EQ = prove + (`!f:real->real g k s. + (!x. x IN s ==> (f(x) = g(x))) /\ + (f has_real_integral k) s + ==> (g has_real_integral k) s`, + REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[GSYM REAL_SUB_0] THEN + DISCH_THEN(CONJUNCTS_THEN2 + (MP_TAC o MATCH_MP HAS_REAL_INTEGRAL_IS_0) MP_TAC) THEN + REWRITE_TAC[IMP_IMP] THEN DISCH_THEN + (MP_TAC o MATCH_MP HAS_REAL_INTEGRAL_SUB) THEN + SIMP_TAC[REAL_ARITH `x - (x - y:real) = y`; ETA_AX; REAL_SUB_RZERO]);; + +let REAL_INTEGRABLE_EQ = prove + (`!f:real->real g s. + (!x. x IN s ==> (f(x) = g(x))) /\ + f real_integrable_on s + ==> g real_integrable_on s`, + REWRITE_TAC[real_integrable_on] THEN MESON_TAC[HAS_REAL_INTEGRAL_EQ]);; + +let HAS_REAL_INTEGRAL_EQ_EQ = prove + (`!f:real->real g k s. + (!x. x IN s ==> (f(x) = g(x))) + ==> ((f has_real_integral k) s <=> (g has_real_integral k) s)`, + MESON_TAC[HAS_REAL_INTEGRAL_EQ]);; + +let HAS_REAL_INTEGRAL_NULL = prove + (`!f:real->real a b. + b <= a ==> (f has_real_integral &0) (real_interval[a,b])`, + REPEAT STRIP_TAC THEN + REWRITE_TAC[has_real_integral; REAL_INTERVAL_INTERVAL] THEN + REWRITE_TAC[GSYM IMAGE_o; o_DEF; LIFT_DROP; LIFT_NUM] THEN + REWRITE_TAC[SET_RULE `IMAGE (\x. x) s = s`] THEN + MATCH_MP_TAC HAS_INTEGRAL_NULL THEN + ASM_REWRITE_TAC[CONTENT_EQ_0_1; LIFT_DROP]);; + +let HAS_REAL_INTEGRAL_NULL_EQ = prove + (`!f a b i. b <= a + ==> ((f has_real_integral i) (real_interval[a,b]) <=> i = &0)`, + ASM_MESON_TAC[REAL_INTEGRAL_UNIQUE; HAS_REAL_INTEGRAL_NULL]);; + +let REAL_INTEGRAL_NULL = prove + (`!f a b. b <= a + ==> real_integral(real_interval[a,b]) f = &0`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_INTEGRAL_UNIQUE THEN + ASM_MESON_TAC[HAS_REAL_INTEGRAL_NULL]);; + +let REAL_INTEGRABLE_ON_NULL = prove + (`!f a b. b <= a + ==> f real_integrable_on real_interval[a,b]`, + REWRITE_TAC[real_integrable_on] THEN MESON_TAC[HAS_REAL_INTEGRAL_NULL]);; + +let HAS_REAL_INTEGRAL_EMPTY = prove + (`!f. (f has_real_integral &0) {}`, + GEN_TAC THEN REWRITE_TAC[EMPTY_AS_REAL_INTERVAL] THEN + MATCH_MP_TAC HAS_REAL_INTEGRAL_NULL THEN REWRITE_TAC[REAL_POS]);; + +let HAS_REAL_INTEGRAL_EMPTY_EQ = prove + (`!f i. (f has_real_integral i) {} <=> i = &0`, + MESON_TAC[HAS_REAL_INTEGRAL_UNIQUE; HAS_REAL_INTEGRAL_EMPTY]);; + +let REAL_INTEGRABLE_ON_EMPTY = prove + (`!f. f real_integrable_on {}`, + REWRITE_TAC[real_integrable_on] THEN MESON_TAC[HAS_REAL_INTEGRAL_EMPTY]);; + +let REAL_INTEGRAL_EMPTY = prove + (`!f. real_integral {} f = &0`, + MESON_TAC[EMPTY_AS_REAL_INTERVAL; REAL_INTEGRAL_UNIQUE; + HAS_REAL_INTEGRAL_EMPTY]);; + +let HAS_REAL_INTEGRAL_REFL = prove + (`!f a. (f has_real_integral &0) (real_interval[a,a])`, + REPEAT GEN_TAC THEN MATCH_MP_TAC HAS_REAL_INTEGRAL_NULL THEN + REWRITE_TAC[REAL_LE_REFL]);; + +let REAL_INTEGRABLE_ON_REFL = prove + (`!f a. f real_integrable_on real_interval[a,a]`, + REWRITE_TAC[real_integrable_on] THEN MESON_TAC[HAS_REAL_INTEGRAL_REFL]);; + +let REAL_INTEGRAL_REFL = prove + (`!f a. real_integral (real_interval[a,a]) f = &0`, + MESON_TAC[REAL_INTEGRAL_UNIQUE; HAS_REAL_INTEGRAL_REFL]);; + +let HAS_REAL_INTEGRAL_CONST = prove + (`!a b c. + a <= b + ==> ((\x. c) has_real_integral (c * (b - a))) (real_interval[a,b])`, + REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN + REWRITE_TAC[has_real_integral; IMAGE_LIFT_REAL_INTERVAL] THEN + MP_TAC(ISPECL [`lift a`; `lift b`; `lift c`] HAS_INTEGRAL_CONST) THEN + ASM_SIMP_TAC[o_DEF; CONTENT_1; LIFT_DROP; LIFT_CMUL]);; + +let REAL_INTEGRABLE_CONST = prove + (`!a b c. (\x. c) real_integrable_on real_interval[a,b]`, + REWRITE_TAC[REAL_INTEGRABLE_ON; IMAGE_LIFT_REAL_INTERVAL; + o_DEF; INTEGRABLE_CONST]);; + +let REAL_INTEGRAL_CONST = prove + (`!a b c. + a <= b + ==> real_integral (real_interval [a,b]) (\x. c) = c * (b - a)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_INTEGRAL_UNIQUE THEN + ASM_SIMP_TAC[HAS_REAL_INTEGRAL_CONST]);; + +let HAS_REAL_INTEGRAL_BOUND = prove + (`!f:real->real a b i B. + &0 <= B /\ a <= b /\ + (f has_real_integral i) (real_interval[a,b]) /\ + (!x. x IN real_interval[a,b] ==> abs(f x) <= B) + ==> abs i <= B * (b - a)`, + REWRITE_TAC[HAS_REAL_INTEGRAL; REAL_INTERVAL_INTERVAL; GSYM NORM_LIFT] THEN + REWRITE_TAC[FORALL_IN_IMAGE; LIFT_DROP] THEN REPEAT STRIP_TAC THEN + GEN_REWRITE_TAC (RAND_CONV o RAND_CONV o BINOP_CONV) [GSYM LIFT_DROP] THEN + ASM_SIMP_TAC[GSYM CONTENT_1; LIFT_DROP] THEN + MATCH_MP_TAC HAS_INTEGRAL_BOUND THEN + EXISTS_TAC `lift o f o drop` THEN ASM_REWRITE_TAC[o_THM]);; + +let HAS_REAL_INTEGRAL_LE = prove + (`!f g s i j. + (f has_real_integral i) s /\ (g has_real_integral j) s /\ + (!x. x IN s ==> f x <= g x) + ==> i <= j`, + REWRITE_TAC[has_real_integral] THEN REPEAT STRIP_TAC THEN + GEN_REWRITE_TAC BINOP_CONV [GSYM LIFT_DROP] THEN + REWRITE_TAC[drop] THEN MATCH_MP_TAC + (ISPECL [`lift o f o drop`; `lift o g o drop`; `IMAGE lift s`] + HAS_INTEGRAL_COMPONENT_LE) THEN + ASM_REWRITE_TAC[FORALL_IN_IMAGE; DIMINDEX_1; LE_REFL; o_THM; LIFT_DROP; + GSYM drop]);; + +let REAL_INTEGRAL_LE = prove + (`!f:real->real g:real->real s. + f real_integrable_on s /\ g real_integrable_on s /\ + (!x. x IN s ==> f x <= g x) + ==> real_integral s f <= real_integral s g`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_REAL_INTEGRAL_LE THEN + ASM_MESON_TAC[REAL_INTEGRABLE_INTEGRAL]);; + +let HAS_REAL_INTEGRAL_POS = prove + (`!f:real->real s i. + (f has_real_integral i) s /\ + (!x. x IN s ==> &0 <= f x) + ==> &0 <= i`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`(\x. &0):real->real`; `f:real->real`; + `s:real->bool`; `&0:real`; + `i:real`] HAS_REAL_INTEGRAL_LE) THEN + ASM_SIMP_TAC[HAS_REAL_INTEGRAL_0]);; + +let REAL_INTEGRAL_POS = prove + (`!f:real->real s. + f real_integrable_on s /\ + (!x. x IN s ==> &0 <= f x) + ==> &0 <= real_integral s f`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_REAL_INTEGRAL_POS THEN + ASM_MESON_TAC[REAL_INTEGRABLE_INTEGRAL]);; + +let HAS_REAL_INTEGRAL_ISNEG = prove + (`!f:real->real s i. + (f has_real_integral i) s /\ + (!x. x IN s ==> f x <= &0) + ==> i <= &0`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`f:real->real`; `(\x. &0):real->real`; + `s:real->bool`; `i:real`; `&0:real`; + ] HAS_REAL_INTEGRAL_LE) THEN + ASM_SIMP_TAC[HAS_REAL_INTEGRAL_0]);; + +let HAS_REAL_INTEGRAL_LBOUND = prove + (`!f:real->real a b i. + a <= b /\ + (f has_real_integral i) (real_interval[a,b]) /\ + (!x. x IN real_interval[a,b] ==> B <= f(x)) + ==> B * (b - a) <= i`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`(\x. B):real->real`; `f:real->real`; + `real_interval[a,b]`; + `B * (b - a):real`; + `i:real`] + HAS_REAL_INTEGRAL_LE) THEN + ASM_SIMP_TAC[HAS_REAL_INTEGRAL_CONST]);; + +let HAS_REAL_INTEGRAL_UBOUND = prove + (`!f:real->real a b i. + a <= b /\ + (f has_real_integral i) (real_interval[a,b]) /\ + (!x. x IN real_interval[a,b] ==> f(x) <= B) + ==> i <= B * (b - a)`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`f:real->real`; `(\x. B):real->real`; + `real_interval[a,b]`; `i:real`; + `B * (b - a):real`] + HAS_REAL_INTEGRAL_LE) THEN + ASM_SIMP_TAC[HAS_REAL_INTEGRAL_CONST]);; + +let REAL_INTEGRAL_LBOUND = prove + (`!f:real->real a b. + a <= b /\ + f real_integrable_on real_interval[a,b] /\ + (!x. x IN real_interval[a,b] ==> B <= f(x)) + ==> B * (b - a) <= real_integral(real_interval[a,b]) f`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_REAL_INTEGRAL_LBOUND THEN + EXISTS_TAC `f:real->real` THEN + ASM_REWRITE_TAC[GSYM HAS_REAL_INTEGRAL_INTEGRAL]);; + +let REAL_INTEGRAL_UBOUND = prove + (`!f:real->real a b. + a <= b /\ + f real_integrable_on real_interval[a,b] /\ + (!x. x IN real_interval[a,b] ==> f(x) <= B) + ==> real_integral(real_interval[a,b]) f <= B * (b - a)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_REAL_INTEGRAL_UBOUND THEN + EXISTS_TAC `f:real->real` THEN + ASM_REWRITE_TAC[GSYM HAS_REAL_INTEGRAL_INTEGRAL]);; + +let REAL_INTEGRABLE_UNIFORM_LIMIT = prove + (`!f a b. (!e. &0 < e + ==> ?g. (!x. x IN real_interval[a,b] ==> abs(f x - g x) <= e) /\ + g real_integrable_on real_interval[a,b] ) + ==> f real_integrable_on real_interval[a,b]`, + REWRITE_TAC[real_integrable_on; HAS_REAL_INTEGRAL; GSYM EXISTS_LIFT] THEN + REWRITE_TAC[GSYM integrable_on] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC INTEGRABLE_UNIFORM_LIMIT 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 `g:real->real` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `lift o g o drop` THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[GSYM IMAGE_LIFT_REAL_INTERVAL; FORALL_IN_IMAGE] THEN + ASM_SIMP_TAC[o_THM; LIFT_DROP; GSYM LIFT_SUB; NORM_LIFT]);; + +let HAS_REAL_INTEGRAL_NEGLIGIBLE = prove + (`!f s t. + real_negligible s /\ (!x. x IN (t DIFF s) ==> f x = &0) + ==> (f has_real_integral (&0)) t`, + REWRITE_TAC[has_real_integral; real_negligible; LIFT_NUM] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_INTEGRAL_NEGLIGIBLE THEN + EXISTS_TAC `IMAGE lift s` THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[o_THM; IN_DIFF; IMP_CONJ; FORALL_IN_IMAGE] THEN + REWRITE_TAC[LIFT_IN_IMAGE_LIFT; LIFT_DROP] THEN ASM SET_TAC[LIFT_NUM]);; + +let HAS_REAL_INTEGRAL_SPIKE = prove + (`!f g s t y. + real_negligible s /\ (!x. x IN (t DIFF s) ==> g x = f x) /\ + (f has_real_integral y) t + ==> (g has_real_integral y) t`, + REWRITE_TAC[has_real_integral; real_negligible] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_INTEGRAL_SPIKE THEN + MAP_EVERY EXISTS_TAC [`lift o f o drop`; `IMAGE lift s`] THEN + ASM_REWRITE_TAC[] THEN + REWRITE_TAC[o_THM; IN_DIFF; IMP_CONJ; FORALL_IN_IMAGE] THEN + REWRITE_TAC[LIFT_IN_IMAGE_LIFT; LIFT_DROP] THEN ASM SET_TAC[LIFT_NUM]);; + +let HAS_REAL_INTEGRAL_SPIKE_EQ = prove + (`!f g s t y. + real_negligible s /\ (!x. x IN (t DIFF s) ==> g x = f x) + ==> ((f has_real_integral y) t <=> (g has_real_integral y) t)`, + REPEAT STRIP_TAC THEN EQ_TAC THEN DISCH_TAC THEN + MATCH_MP_TAC HAS_REAL_INTEGRAL_SPIKE THENL + [EXISTS_TAC `f:real->real`; EXISTS_TAC `g:real->real`] THEN + EXISTS_TAC `s:real->bool` THEN ASM_REWRITE_TAC[] THEN + ASM_MESON_TAC[REAL_ABS_SUB]);; + +let REAL_INTEGRABLE_SPIKE = prove + (`!f g s t. + real_negligible s /\ (!x. x IN (t DIFF s) ==> g x = f x) + ==> f real_integrable_on t ==> g real_integrable_on t`, + REPEAT GEN_TAC THEN DISCH_TAC THEN REWRITE_TAC[real_integrable_on] THEN + MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC THEN + MP_TAC(SPEC_ALL HAS_REAL_INTEGRAL_SPIKE) THEN ASM_REWRITE_TAC[]);; + +let REAL_INTEGRAL_SPIKE = prove + (`!f:real->real g s t. + real_negligible s /\ (!x. x IN (t DIFF s) ==> g x = f x) + ==> real_integral t f = real_integral t g`, + REPEAT STRIP_TAC THEN REWRITE_TAC[real_integral] THEN + AP_TERM_TAC THEN ABS_TAC THEN MATCH_MP_TAC HAS_REAL_INTEGRAL_SPIKE_EQ THEN + ASM_MESON_TAC[]);; + +let REAL_NEGLIGIBLE_SUBSET = prove + (`!s:real->bool t:real->bool. + real_negligible s /\ t SUBSET s ==> real_negligible t`, + REWRITE_TAC[real_negligible] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC NEGLIGIBLE_SUBSET THEN + EXISTS_TAC `IMAGE lift s` THEN ASM_SIMP_TAC[IMAGE_SUBSET]);; + +let REAL_NEGLIGIBLE_DIFF = prove + (`!s t:real->bool. real_negligible s ==> real_negligible(s DIFF t)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_NEGLIGIBLE_SUBSET THEN + EXISTS_TAC `s:real->bool` THEN ASM_REWRITE_TAC[SUBSET_DIFF]);; + +let REAL_NEGLIGIBLE_INTER = prove + (`!s t. real_negligible s \/ real_negligible t ==> real_negligible(s INTER t)`, + MESON_TAC[REAL_NEGLIGIBLE_SUBSET; INTER_SUBSET]);; + +let REAL_NEGLIGIBLE_UNION = prove + (`!s t:real->bool. + real_negligible s /\ real_negligible t ==> real_negligible (s UNION t)`, + SIMP_TAC[NEGLIGIBLE_UNION; IMAGE_UNION; real_negligible]);; + +let REAL_NEGLIGIBLE_UNION_EQ = prove + (`!s t:real->bool. + real_negligible (s UNION t) <=> real_negligible s /\ real_negligible t`, + MESON_TAC[REAL_NEGLIGIBLE_UNION; SUBSET_UNION; REAL_NEGLIGIBLE_SUBSET]);; + +let REAL_NEGLIGIBLE_SING = prove + (`!a:real. real_negligible {a}`, + REWRITE_TAC[real_negligible; NEGLIGIBLE_SING; IMAGE_CLAUSES]);; + +let REAL_NEGLIGIBLE_INSERT = prove + (`!a:real s. real_negligible(a INSERT s) <=> real_negligible s`, + REWRITE_TAC[real_negligible; NEGLIGIBLE_INSERT; IMAGE_CLAUSES]);; + +let REAL_NEGLIGIBLE_EMPTY = prove + (`real_negligible {}`, + REWRITE_TAC[real_negligible; NEGLIGIBLE_EMPTY; IMAGE_CLAUSES]);; + +let REAL_NEGLIGIBLE_FINITE = prove + (`!s. FINITE s ==> real_negligible s`, + MATCH_MP_TAC FINITE_INDUCT_STRONG THEN + SIMP_TAC[REAL_NEGLIGIBLE_EMPTY; REAL_NEGLIGIBLE_INSERT]);; + +let REAL_NEGLIGIBLE_UNIONS = prove + (`!s. FINITE s /\ (!t. t IN s ==> real_negligible t) + ==> real_negligible(UNIONS s)`, + REWRITE_TAC[IMP_CONJ] THEN MATCH_MP_TAC FINITE_INDUCT_STRONG THEN + REWRITE_TAC[UNIONS_0; UNIONS_INSERT; REAL_NEGLIGIBLE_EMPTY; IN_INSERT] THEN + SIMP_TAC[REAL_NEGLIGIBLE_UNION]);; + +let HAS_REAL_INTEGRAL_SPIKE_FINITE = prove + (`!f:real->real g s t y. + FINITE s /\ (!x. x IN (t DIFF s) ==> g x = f x) /\ + (f has_real_integral y) t + ==> (g has_real_integral y) t`, + MESON_TAC[HAS_REAL_INTEGRAL_SPIKE; REAL_NEGLIGIBLE_FINITE]);; + +let HAS_REAL_INTEGRAL_SPIKE_FINITE_EQ = prove + (`!f:real->real g s y. + FINITE s /\ (!x. x IN (t DIFF s) ==> g x = f x) + ==> ((f has_real_integral y) t <=> (g has_real_integral y) t)`, + MESON_TAC[HAS_REAL_INTEGRAL_SPIKE_FINITE]);; + +let REAL_INTEGRABLE_SPIKE_FINITE = prove + (`!f:real->real g s. + FINITE s /\ (!x. x IN (t DIFF s) ==> g x = f x) + ==> f real_integrable_on t + ==> g real_integrable_on t`, + REPEAT GEN_TAC THEN DISCH_TAC THEN REWRITE_TAC[real_integrable_on] THEN + MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC THEN + MP_TAC(SPEC_ALL HAS_REAL_INTEGRAL_SPIKE_FINITE) THEN ASM_REWRITE_TAC[]);; + +let REAL_NEGLIGIBLE_FRONTIER_INTERVAL = prove + (`!a b:real. real_negligible(real_interval[a,b] DIFF real_interval(a,b))`, + REPEAT GEN_TAC THEN REWRITE_TAC[real_interval; DIFF; IN_ELIM_THM] THEN + MATCH_MP_TAC REAL_NEGLIGIBLE_SUBSET THEN EXISTS_TAC `{(a:real),b}` THEN + ASM_SIMP_TAC[REAL_NEGLIGIBLE_FINITE; FINITE_RULES] THEN + REWRITE_TAC[SUBSET; IN_ELIM_THM; IN_INSERT; NOT_IN_EMPTY] THEN + REAL_ARITH_TAC);; + +let HAS_REAL_INTEGRAL_SPIKE_INTERIOR = prove + (`!f:real->real g a b y. + (!x. x IN real_interval(a,b) ==> g x = f x) /\ + (f has_real_integral y) (real_interval[a,b]) + ==> (g has_real_integral y) (real_interval[a,b])`, + REPEAT GEN_TAC THEN REWRITE_TAC[IMP_CONJ] THEN DISCH_TAC THEN + MATCH_MP_TAC(REWRITE_RULE[TAUT `a /\ b /\ c ==> d <=> a /\ b ==> c ==> d`] + HAS_REAL_INTEGRAL_SPIKE) THEN + EXISTS_TAC `real_interval[a:real,b] DIFF real_interval(a,b)` THEN + REWRITE_TAC[REAL_NEGLIGIBLE_FRONTIER_INTERVAL] THEN ASM SET_TAC[]);; + +let HAS_REAL_INTEGRAL_SPIKE_INTERIOR_EQ = prove + (`!f:real->real g a b y. + (!x. x IN real_interval(a,b) ==> g x = f x) + ==> ((f has_real_integral y) (real_interval[a,b]) <=> + (g has_real_integral y) (real_interval[a,b]))`, + MESON_TAC[HAS_REAL_INTEGRAL_SPIKE_INTERIOR]);; + +let REAL_INTEGRABLE_SPIKE_INTERIOR = prove + (`!f:real->real g a b. + (!x. x IN real_interval(a,b) ==> g x = f x) + ==> f real_integrable_on (real_interval[a,b]) + ==> g real_integrable_on (real_interval[a,b])`, + REPEAT GEN_TAC THEN DISCH_TAC THEN REWRITE_TAC[real_integrable_on] THEN + MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC THEN + MP_TAC(SPEC_ALL HAS_REAL_INTEGRAL_SPIKE_INTERIOR) THEN ASM_REWRITE_TAC[]);; + +let REAL_INTEGRAL_EQ = prove + (`!f g s. + (!x. x IN s ==> f x = g x) ==> real_integral s f = real_integral s g`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_INTEGRAL_SPIKE THEN + EXISTS_TAC `{}:real->bool` THEN + ASM_SIMP_TAC[REAL_NEGLIGIBLE_EMPTY; IN_DIFF]);; + +let REAL_INTEGRAL_EQ_0 = prove + (`!f s. (!x. x IN s ==> f x = &0) ==> real_integral s f = &0`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC EQ_TRANS THEN + EXISTS_TAC `real_integral s (\x. &0)` THEN + CONJ_TAC THENL + [MATCH_MP_TAC REAL_INTEGRAL_EQ THEN ASM_REWRITE_TAC[]; + REWRITE_TAC[REAL_INTEGRAL_0]]);; + +let REAL_INTEGRABLE_CONTINUOUS = prove + (`!f a b. + f real_continuous_on real_interval[a,b] + ==> f real_integrable_on real_interval[a,b]`, + REWRITE_TAC[REAL_CONTINUOUS_ON; real_integrable_on; has_real_integral; + GSYM integrable_on; GSYM EXISTS_LIFT] THEN + REWRITE_TAC[IMAGE_LIFT_REAL_INTERVAL; INTEGRABLE_CONTINUOUS]);; + +let REAL_FUNDAMENTAL_THEOREM_OF_CALCULUS = prove + (`!f f' a b. + a <= b /\ + (!x. x IN real_interval[a,b] + ==> (f has_real_derivative f'(x)) + (atreal x within real_interval[a,b])) + ==> (f' has_real_integral (f(b) - f(a))) (real_interval[a,b])`, + REWRITE_TAC[has_real_integral; HAS_REAL_VECTOR_DERIVATIVE_WITHIN] THEN + REPEAT GEN_TAC THEN REWRITE_TAC[IMAGE_LIFT_REAL_INTERVAL; LIFT_SUB] THEN + REWRITE_TAC[REAL_INTERVAL_INTERVAL; FORALL_IN_IMAGE; LIFT_DROP] THEN + GEN_REWRITE_TAC (LAND_CONV o LAND_CONV o BINOP_CONV) [GSYM LIFT_DROP] THEN + DISCH_THEN(MP_TAC o MATCH_MP FUNDAMENTAL_THEOREM_OF_CALCULUS) THEN + REWRITE_TAC[o_DEF; LIFT_DROP]);; + +let REAL_INTEGRABLE_SUBINTERVAL = prove + (`!f:real->real a b c d. + f real_integrable_on real_interval[a,b] /\ + real_interval[c,d] SUBSET real_interval[a,b] + ==> f real_integrable_on real_interval[c,d]`, + REWRITE_TAC[real_integrable_on; HAS_REAL_INTEGRAL] THEN + REWRITE_TAC[EXISTS_DROP; GSYM integrable_on; LIFT_DROP] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC INTEGRABLE_SUBINTERVAL THEN + MAP_EVERY EXISTS_TAC [`lift a`; `lift b`] THEN + ASM_REWRITE_TAC[GSYM IMAGE_LIFT_REAL_INTERVAL] THEN + ASM_SIMP_TAC[IMAGE_SUBSET]);; + +let HAS_REAL_INTEGRAL_COMBINE = prove + (`!f i j a b c. + a <= c /\ c <= b /\ + (f has_real_integral i) (real_interval[a,c]) /\ + (f has_real_integral j) (real_interval[c,b]) + ==> (f has_real_integral (i + j)) (real_interval[a,b])`, + REPEAT GEN_TAC THEN REWRITE_TAC[HAS_REAL_INTEGRAL; LIFT_ADD] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_INTEGRAL_COMBINE THEN + EXISTS_TAC `lift c` THEN ASM_REWRITE_TAC[LIFT_DROP]);; + +let REAL_INTEGRAL_COMBINE = prove + (`!f a b c. + a <= c /\ c <= b /\ f real_integrable_on (real_interval[a,b]) + ==> real_integral(real_interval[a,c]) f + + real_integral(real_interval[c,b]) f = + real_integral(real_interval[a,b]) f`, + REPEAT STRIP_TAC THEN CONV_TAC SYM_CONV THEN + MATCH_MP_TAC REAL_INTEGRAL_UNIQUE THEN + MATCH_MP_TAC HAS_REAL_INTEGRAL_COMBINE THEN + EXISTS_TAC `c:real` THEN ASM_REWRITE_TAC[] THEN CONJ_TAC THEN + MATCH_MP_TAC REAL_INTEGRABLE_INTEGRAL THEN + MATCH_MP_TAC REAL_INTEGRABLE_SUBINTERVAL THEN + MAP_EVERY EXISTS_TAC [`a:real`; `b:real`] THEN + ASM_REWRITE_TAC[SUBSET_REAL_INTERVAL; REAL_LE_REFL]);; + +let REAL_INTEGRABLE_COMBINE = prove + (`!f a b c. + a <= c /\ c <= b /\ + f real_integrable_on real_interval[a,c] /\ + f real_integrable_on real_interval[c,b] + ==> f real_integrable_on real_interval[a,b]`, + REWRITE_TAC[real_integrable_on] THEN MESON_TAC[HAS_REAL_INTEGRAL_COMBINE]);; + +let REAL_INTEGRABLE_ON_LITTLE_SUBINTERVALS = prove + (`!f:real->real a b. + (!x. x IN real_interval[a,b] + ==> ?d. &0 < d /\ + !u v. x IN real_interval[u,v] /\ + (!y. y IN real_interval[u,v] + ==> abs(y - x) < d /\ y IN real_interval[a,b]) + ==> f real_integrable_on real_interval[u,v]) + ==> f real_integrable_on real_interval[a,b]`, + REPEAT GEN_TAC THEN + REWRITE_TAC[real_integrable_on; HAS_REAL_INTEGRAL; EXISTS_DROP; + GSYM integrable_on; LIFT_DROP] THEN + DISCH_TAC THEN MATCH_MP_TAC INTEGRABLE_ON_LITTLE_SUBINTERVALS THEN + REWRITE_TAC[GSYM IMAGE_LIFT_REAL_INTERVAL; FORALL_IN_IMAGE] THEN + X_GEN_TAC `x:real` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `x:real`) THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[GSYM EXISTS_DROP; FORALL_LIFT] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `d:real` THEN + REWRITE_TAC[IMAGE_LIFT_REAL_INTERVAL] THEN + REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + CONJ_TAC THENL + [ASM_MESON_TAC[IMAGE_LIFT_REAL_INTERVAL; LIFT_IN_IMAGE_LIFT]; + REWRITE_TAC[REAL_INTERVAL_INTERVAL; FORALL_IN_IMAGE] THEN + X_GEN_TAC `y:real^1` THEN DISCH_TAC THEN + REPEAT(FIRST_X_ASSUM(MP_TAC o SPEC `y:real^1` o REWRITE_RULE[SUBSET])) THEN + ASM_SIMP_TAC[IN_BALL; FUN_IN_IMAGE; dist; NORM_REAL] THEN + REWRITE_TAC[GSYM drop; DROP_SUB; LIFT_DROP] THEN SIMP_TAC[REAL_ABS_SUB]]);; + +let REAL_INTEGRAL_HAS_REAL_DERIVATIVE = prove + (`!f:real->real a b. + (f real_continuous_on real_interval[a,b]) + ==> !x. x IN real_interval[a,b] + ==> ((\u. real_integral(real_interval[a,u]) f) + has_real_derivative f(x)) + (atreal x within real_interval[a,b])`, + REPEAT GEN_TAC THEN + REWRITE_TAC[REAL_CONTINUOUS_ON; IMAGE_LIFT_REAL_INTERVAL] THEN + DISCH_TAC THEN + FIRST_ASSUM(MP_TAC o MATCH_MP INTEGRAL_HAS_VECTOR_DERIVATIVE) THEN + REWRITE_TAC[HAS_REAL_VECTOR_DERIVATIVE_WITHIN] THEN + REWRITE_TAC[REAL_INTERVAL_INTERVAL; FORALL_IN_IMAGE] THEN + REWRITE_TAC[GSYM IMAGE_o; o_DEF; LIFT_DROP] THEN + DISCH_TAC THEN X_GEN_TAC `x:real^1` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `x:real^1`) THEN + ASM_REWRITE_TAC[SET_RULE `IMAGE (\x. x) s = s`] THEN + MATCH_MP_TAC(REWRITE_RULE[TAUT + `a /\ b /\ c /\ d ==> e <=> a /\ b /\ c ==> d ==> e`] + HAS_VECTOR_DERIVATIVE_TRANSFORM_WITHIN) THEN + EXISTS_TAC `&1` THEN ASM_REWRITE_TAC[REAL_LT_01] THEN + X_GEN_TAC `y:real^1` THEN STRIP_TAC THEN + ONCE_REWRITE_TAC[GSYM DROP_EQ] THEN + REWRITE_TAC[LIFT_DROP] THEN CONV_TAC SYM_CONV THEN + REWRITE_TAC[INTERVAL_REAL_INTERVAL; GSYM IMAGE_o; LIFT_DROP; o_DEF] THEN + REWRITE_TAC[GSYM o_DEF; SET_RULE `IMAGE (\x. x) s = s`] THEN + MATCH_MP_TAC REAL_INTEGRAL THEN + MATCH_MP_TAC REAL_INTEGRABLE_SUBINTERVAL THEN + MAP_EVERY EXISTS_TAC [`a:real`; `b:real`] THEN CONJ_TAC THENL + [REWRITE_TAC[REAL_INTEGRABLE_ON; IMAGE_LIFT_REAL_INTERVAL] THEN + MATCH_MP_TAC INTEGRABLE_CONTINUOUS THEN ASM_REWRITE_TAC[]; + ASM_REWRITE_TAC[SUBSET_REAL_INTERVAL] THEN + REPEAT(FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_INTERVAL_1])) THEN + REWRITE_TAC[LIFT_DROP] THEN REAL_ARITH_TAC]);; + +let REAL_ANTIDERIVATIVE_CONTINUOUS = prove + (`!f a b. + (f real_continuous_on real_interval[a,b]) + ==> ?g. !x. x IN real_interval[a,b] + ==> (g has_real_derivative f(x)) + (atreal x within real_interval[a,b])`, + MESON_TAC[REAL_INTEGRAL_HAS_REAL_DERIVATIVE]);; + +let REAL_ANTIDERIVATIVE_INTEGRAL_CONTINUOUS = prove + (`!f a b. + (f real_continuous_on real_interval[a,b]) + ==> ?g. !u v. u IN real_interval[a,b] /\ + v IN real_interval[a,b] /\ u <= v + ==> (f has_real_integral (g(v) - g(u))) + (real_interval[u,v])`, + REPEAT STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o MATCH_MP REAL_ANTIDERIVATIVE_CONTINUOUS) THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `g:real->real` THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_FUNDAMENTAL_THEOREM_OF_CALCULUS THEN + ASM_REWRITE_TAC[] THEN X_GEN_TAC `x:real` THEN + STRIP_TAC THEN MATCH_MP_TAC HAS_REAL_DERIVATIVE_WITHIN_SUBSET THEN + EXISTS_TAC `real_interval[a:real,b]` THEN CONJ_TAC THENL + [FIRST_X_ASSUM MATCH_MP_TAC; ALL_TAC] THEN + REPEAT(POP_ASSUM MP_TAC) THEN + REWRITE_TAC[SUBSET_REAL_INTERVAL; IN_REAL_INTERVAL] THEN REAL_ARITH_TAC);; + +let HAS_REAL_INTEGRAL_AFFINITY = prove + (`!f:real->real i a b m c. + (f has_real_integral i) (real_interval[a,b]) /\ ~(m = &0) + ==> ((\x. f(m * x + c)) has_real_integral (inv(abs(m)) * i)) + (IMAGE (\x. inv m * (x - c)) (real_interval[a,b]))`, + REPEAT GEN_TAC THEN REWRITE_TAC[HAS_REAL_INTEGRAL] THEN + DISCH_THEN(MP_TAC o SPEC `lift c` o MATCH_MP HAS_INTEGRAL_AFFINITY) THEN + REWRITE_TAC[DIMINDEX_1; REAL_POW_1; has_real_integral] THEN + REWRITE_TAC[o_DEF; DROP_ADD; DROP_CMUL; LIFT_DROP; LIFT_CMUL] THEN + MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN + REWRITE_TAC[INTERVAL_REAL_INTERVAL; GSYM IMAGE_o; LIFT_DROP] THEN + AP_THM_TAC THEN AP_TERM_TAC THEN + REWRITE_TAC[FUN_EQ_THM; o_DEF; LIFT_CMUL; LIFT_SUB] THEN VECTOR_ARITH_TAC);; + +let REAL_INTEGRABLE_AFFINITY = prove + (`!f a b m c. + f real_integrable_on real_interval[a,b] /\ ~(m = &0) + ==> (\x. f(m * x + c)) real_integrable_on + (IMAGE (\x. inv m * (x - c)) (real_interval[a,b]))`, + REWRITE_TAC[real_integrable_on] THEN MESON_TAC[HAS_REAL_INTEGRAL_AFFINITY]);; + +let HAS_REAL_INTEGRAL_STRETCH = prove + (`!f:real->real i a b m. + (f has_real_integral i) (real_interval[a,b]) /\ ~(m = &0) + ==> ((\x. f(m * x)) has_real_integral (inv(abs(m)) * i)) + (IMAGE (\x. inv m * x) (real_interval[a,b]))`, + MP_TAC HAS_REAL_INTEGRAL_AFFINITY THEN + REPEAT(MATCH_MP_TAC MONO_FORALL THEN GEN_TAC) THEN + DISCH_THEN(MP_TAC o SPEC `&0`) THEN + REWRITE_TAC[REAL_ADD_RID; REAL_SUB_RZERO]);; + +let REAL_INTEGRABLE_STRETCH = prove + (`!f a b m. + f real_integrable_on real_interval[a,b] /\ ~(m = &0) + ==> (\x. f(m * x)) real_integrable_on + (IMAGE (\x. inv m * x) (real_interval[a,b]))`, + REWRITE_TAC[real_integrable_on] THEN MESON_TAC[HAS_REAL_INTEGRAL_STRETCH]);; + +let HAS_REAL_INTEGRAL_REFLECT_LEMMA = prove + (`!f:real->real i a b. + (f has_real_integral i) (real_interval[a,b]) + ==> ((\x. f(--x)) has_real_integral i) (real_interval[--b,--a])`, + REPEAT GEN_TAC THEN REWRITE_TAC[HAS_REAL_INTEGRAL] THEN + DISCH_THEN(MP_TAC o MATCH_MP HAS_INTEGRAL_REFLECT_LEMMA) THEN + REWRITE_TAC[LIFT_NEG; o_DEF; DROP_NEG]);; + +let HAS_REAL_INTEGRAL_REFLECT = prove + (`!f:real->real i a b. + ((\x. f(--x)) has_real_integral i) (real_interval[--b,--a]) <=> + (f has_real_integral i) (real_interval[a,b])`, + REPEAT GEN_TAC THEN EQ_TAC THEN + DISCH_THEN(MP_TAC o MATCH_MP HAS_REAL_INTEGRAL_REFLECT_LEMMA) THEN + REWRITE_TAC[REAL_NEG_NEG; ETA_AX]);; + +let REAL_INTEGRABLE_REFLECT = prove + (`!f:real->real a b. + (\x. f(--x)) real_integrable_on (real_interval[--b,--a]) <=> + f real_integrable_on (real_interval[a,b])`, + REWRITE_TAC[real_integrable_on; HAS_REAL_INTEGRAL_REFLECT]);; + +let REAL_INTEGRAL_REFLECT = prove + (`!f:real->real a b. + real_integral (real_interval[--b,--a]) (\x. f(--x)) = + real_integral (real_interval[a,b]) f`, + REWRITE_TAC[real_integral; HAS_REAL_INTEGRAL_REFLECT]);; + +let REAL_FUNDAMENTAL_THEOREM_OF_CALCULUS_INTERIOR = prove + (`!f:real->real f' a b. + a <= b /\ f real_continuous_on real_interval[a,b] /\ + (!x. x IN real_interval(a,b) + ==> (f has_real_derivative f'(x)) (atreal x)) + ==> (f' has_real_integral (f(b) - f(a))) (real_interval[a,b])`, + REWRITE_TAC[has_real_integral; HAS_REAL_VECTOR_DERIVATIVE_AT] THEN + REPEAT GEN_TAC THEN REWRITE_TAC[IMAGE_LIFT_REAL_INTERVAL; LIFT_SUB] THEN + REWRITE_TAC[REAL_INTERVAL_INTERVAL; FORALL_IN_IMAGE; LIFT_DROP] THEN + GEN_REWRITE_TAC (LAND_CONV o LAND_CONV o BINOP_CONV) [GSYM LIFT_DROP] THEN + REWRITE_TAC[REAL_CONTINUOUS_ON; GSYM IMAGE_o; IMAGE_LIFT_DROP] THEN + DISCH_THEN(MP_TAC o MATCH_MP FUNDAMENTAL_THEOREM_OF_CALCULUS_INTERIOR) THEN + REWRITE_TAC[o_DEF; LIFT_DROP]);; + +let REAL_FUNDAMENTAL_THEOREM_OF_CALCULUS_INTERIOR_STRONG = prove + (`!f f' s a b. + COUNTABLE s /\ + a <= b /\ f real_continuous_on real_interval[a,b] /\ + (!x. x IN real_interval(a,b) DIFF s + ==> (f has_real_derivative f'(x)) (atreal x)) + ==> (f' has_real_integral (f(b) - f(a))) (real_interval[a,b])`, + REWRITE_TAC[has_real_integral; HAS_REAL_VECTOR_DERIVATIVE_AT] THEN + REPEAT GEN_TAC THEN REWRITE_TAC[IMAGE_LIFT_REAL_INTERVAL; LIFT_SUB] THEN + REWRITE_TAC[REAL_INTERVAL_INTERVAL; FORALL_IN_IMAGE; IMP_CONJ; IN_DIFF] THEN + SUBGOAL_THEN `!x. drop x IN s <=> x IN IMAGE lift s` + (fun th -> REWRITE_TAC[th]) THENL [SET_TAC[LIFT_DROP]; ALL_TAC] THEN + SUBGOAL_THEN `COUNTABLE s <=> COUNTABLE(IMAGE lift s)` SUBST1_TAC THENL + [EQ_TAC THEN SIMP_TAC[COUNTABLE_IMAGE] THEN + DISCH_THEN(MP_TAC o ISPEC `drop` o MATCH_MP COUNTABLE_IMAGE) THEN + REWRITE_TAC[GSYM IMAGE_o; IMAGE_LIFT_DROP]; + ALL_TAC] THEN + REWRITE_TAC[IMP_IMP; GSYM IN_DIFF; GSYM CONJ_ASSOC] THEN + REWRITE_TAC[REAL_CONTINUOUS_ON; GSYM IMAGE_o; IMAGE_LIFT_DROP] THEN + REWRITE_TAC[LIFT_DROP] THEN + GEN_REWRITE_TAC (LAND_CONV o RAND_CONV o LAND_CONV o BINOP_CONV) + [GSYM LIFT_DROP] THEN + DISCH_THEN(MP_TAC o + MATCH_MP FUNDAMENTAL_THEOREM_OF_CALCULUS_INTERIOR_STRONG) THEN + REWRITE_TAC[o_DEF; LIFT_DROP]);; + +let REAL_FUNDAMENTAL_THEOREM_OF_CALCULUS_STRONG = prove + (`!f f' s a b. + COUNTABLE s /\ + a <= b /\ f real_continuous_on real_interval[a,b] /\ + (!x. x IN real_interval[a,b] DIFF s + ==> (f has_real_derivative f'(x)) (atreal x)) + ==> (f' has_real_integral (f(b) - f(a))) (real_interval[a,b])`, + REPEAT STRIP_TAC THEN + MATCH_MP_TAC REAL_FUNDAMENTAL_THEOREM_OF_CALCULUS_INTERIOR_STRONG THEN + EXISTS_TAC `s:real->bool` THEN ASM_REWRITE_TAC[] THEN GEN_TAC THEN + DISCH_THEN(fun th -> FIRST_X_ASSUM MATCH_MP_TAC THEN MP_TAC th) THEN + SIMP_TAC[IN_REAL_INTERVAL; IN_DIFF] THEN REAL_ARITH_TAC);; + +let REAL_INDEFINITE_INTEGRAL_CONTINUOUS_RIGHT = prove + (`!f:real->real a b. + f real_integrable_on real_interval[a,b] + ==> (\x. real_integral (real_interval[a,x]) f) + real_continuous_on real_interval[a,b]`, + REPEAT STRIP_TAC THEN REWRITE_TAC[REAL_CONTINUOUS_ON] THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [REAL_INTEGRABLE_ON]) THEN + REWRITE_TAC[IMAGE_LIFT_REAL_INTERVAL] THEN + DISCH_THEN(MP_TAC o MATCH_MP INDEFINITE_INTEGRAL_CONTINUOUS_RIGHT) THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] CONTINUOUS_ON_EQ) THEN + GEN_TAC THEN DISCH_TAC THEN REWRITE_TAC[o_DEF] THEN + GEN_REWRITE_TAC I [GSYM DROP_EQ] THEN + REWRITE_TAC[INTERVAL_REAL_INTERVAL; LIFT_DROP; GSYM o_DEF] THEN + CONV_TAC SYM_CONV THEN MATCH_MP_TAC REAL_INTEGRAL THEN + MATCH_MP_TAC REAL_INTEGRABLE_SUBINTERVAL THEN + MAP_EVERY EXISTS_TAC [`a:real`; `b:real`] THEN + ASM_REWRITE_TAC[SUBSET_REAL_INTERVAL] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_INTERVAL_1]) THEN + REWRITE_TAC[LIFT_DROP] THEN REAL_ARITH_TAC);; + +let REAL_INDEFINITE_INTEGRAL_CONTINUOUS_LEFT = prove + (`!f:real->real a b. + f real_integrable_on real_interval[a,b] + ==> (\x. real_integral (real_interval[x,b]) f) + real_continuous_on real_interval[a,b]`, + REPEAT STRIP_TAC THEN REWRITE_TAC[REAL_CONTINUOUS_ON] THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [REAL_INTEGRABLE_ON]) THEN + REWRITE_TAC[IMAGE_LIFT_REAL_INTERVAL] THEN + DISCH_THEN(MP_TAC o MATCH_MP INDEFINITE_INTEGRAL_CONTINUOUS_LEFT) THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] CONTINUOUS_ON_EQ) THEN + GEN_TAC THEN DISCH_TAC THEN REWRITE_TAC[o_DEF] THEN + GEN_REWRITE_TAC I [GSYM DROP_EQ] THEN + REWRITE_TAC[INTERVAL_REAL_INTERVAL; LIFT_DROP; GSYM o_DEF] THEN + CONV_TAC SYM_CONV THEN MATCH_MP_TAC REAL_INTEGRAL THEN + MATCH_MP_TAC REAL_INTEGRABLE_SUBINTERVAL THEN + MAP_EVERY EXISTS_TAC [`a:real`; `b:real`] THEN + ASM_REWRITE_TAC[SUBSET_REAL_INTERVAL] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_INTERVAL_1]) THEN + REWRITE_TAC[LIFT_DROP] THEN REAL_ARITH_TAC);; + +let HAS_REAL_DERIVATIVE_ZERO_UNIQUE_STRONG_INTERVAL = prove + (`!f:real->real a b k y. + COUNTABLE k /\ f real_continuous_on real_interval[a,b] /\ f a = y /\ + (!x. x IN (real_interval[a,b] DIFF k) + ==> (f has_real_derivative &0) + (atreal x within real_interval[a,b])) + ==> !x. x IN real_interval[a,b] ==> f x = y`, + REWRITE_TAC[has_real_integral; HAS_REAL_VECTOR_DERIVATIVE_WITHIN] THEN + REPEAT GEN_TAC THEN REWRITE_TAC[IMAGE_LIFT_REAL_INTERVAL; LIFT_SUB] THEN + REWRITE_TAC[REAL_INTERVAL_INTERVAL; FORALL_IN_IMAGE; IMP_CONJ; IN_DIFF] THEN + REWRITE_TAC[REAL_CONTINUOUS_ON; IMP_IMP; GSYM IMAGE_o; IMAGE_LIFT_DROP] THEN + REWRITE_TAC[GSYM IMP_CONJ; LIFT_DROP; has_vector_derivative] THEN + REWRITE_TAC[LIFT_NUM; VECTOR_MUL_RZERO] THEN STRIP_TAC THEN + MP_TAC(ISPECL + [`lift o f o drop`; `lift a`; `lift b`; `IMAGE lift k`; `lift y`] + HAS_DERIVATIVE_ZERO_UNIQUE_STRONG_INTERVAL) THEN + ASM_SIMP_TAC[COUNTABLE_IMAGE; o_THM; LIFT_DROP; LIFT_EQ; IN_DIFF] THEN + DISCH_THEN MATCH_MP_TAC THEN REPEAT STRIP_TAC THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN ASM SET_TAC[LIFT_DROP]);; + +let HAS_REAL_DERIVATIVE_ZERO_UNIQUE_STRONG_CONVEX = prove + (`!f:real->real s k c y. + is_realinterval s /\ COUNTABLE k /\ f real_continuous_on s /\ + c IN s /\ f c = y /\ + (!x. x IN (s DIFF k) ==> (f has_real_derivative &0) (atreal x within s)) + ==> !x. x IN s ==> f x = y`, + REWRITE_TAC[has_real_integral; HAS_REAL_VECTOR_DERIVATIVE_WITHIN] THEN + REWRITE_TAC[IS_REALINTERVAL_CONVEX; REAL_CONTINUOUS_ON] THEN + REPEAT GEN_TAC THEN REWRITE_TAC[IMAGE_LIFT_REAL_INTERVAL; LIFT_SUB] THEN + REWRITE_TAC[REAL_INTERVAL_INTERVAL; FORALL_IN_IMAGE; IMP_CONJ; IN_DIFF] THEN + REWRITE_TAC[REAL_CONTINUOUS_ON; IMP_IMP; GSYM IMAGE_o; IMAGE_LIFT_DROP] THEN + REWRITE_TAC[GSYM IMP_CONJ; LIFT_DROP; has_vector_derivative] THEN + REWRITE_TAC[LIFT_NUM; VECTOR_MUL_RZERO] THEN STRIP_TAC THEN + MP_TAC(ISPECL + [`lift o f o drop`; `IMAGE lift s`; `IMAGE lift k`; `lift c`; `lift y`] + HAS_DERIVATIVE_ZERO_UNIQUE_STRONG_CONVEX) THEN + ASM_SIMP_TAC[COUNTABLE_IMAGE; o_THM; LIFT_DROP; LIFT_EQ; IN_DIFF] THEN + ASM_REWRITE_TAC[LIFT_IN_IMAGE_LIFT; FORALL_IN_IMAGE; LIFT_DROP] THEN + ASM_SIMP_TAC[IMP_CONJ; FORALL_IN_IMAGE; LIFT_IN_IMAGE_LIFT]);; + +let HAS_REAL_DERIVATIVE_INDEFINITE_INTEGRAL = prove + (`!f a b. + f real_integrable_on real_interval[a,b] + ==> ?k. real_negligible k /\ + !x. x IN real_interval[a,b] DIFF k + ==> ((\x. real_integral(real_interval[a,x]) f) + has_real_derivative + f(x)) (atreal x within real_interval[a,b])`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`lift o f o drop`; `lift a`; `lift b`] + HAS_VECTOR_DERIVATIVE_INDEFINITE_INTEGRAL) THEN + ASM_REWRITE_TAC[GSYM REAL_INTEGRABLE_ON; GSYM IMAGE_LIFT_REAL_INTERVAL] THEN + REWRITE_TAC[IN_DIFF; FORALL_IN_IMAGE; IMP_CONJ] THEN + DISCH_THEN(X_CHOOSE_THEN `k:real^1->bool` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `IMAGE drop k` THEN + ASM_REWRITE_TAC[real_negligible; HAS_REAL_VECTOR_DERIVATIVE_WITHIN] THEN + ASM_REWRITE_TAC[GSYM IMAGE_o; IMAGE_LIFT_DROP] THEN + REWRITE_TAC[IN_IMAGE; GSYM LIFT_EQ; LIFT_DROP; UNWIND_THM1] THEN + X_GEN_TAC `x:real` THEN REPEAT DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `x:real`) THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[o_THM; LIFT_DROP] THEN MATCH_MP_TAC(REWRITE_RULE + [TAUT `a /\ b /\ c /\ d ==> e <=> a /\ b /\ c ==> d ==> e`] + HAS_VECTOR_DERIVATIVE_TRANSFORM_WITHIN) THEN + EXISTS_TAC `&1` THEN ASM_SIMP_TAC[FUN_IN_IMAGE; REAL_LT_01] THEN + REWRITE_TAC[IMP_CONJ; FORALL_IN_IMAGE] THEN + X_GEN_TAC `y:real` THEN REPEAT DISCH_TAC THEN + REWRITE_TAC[GSYM DROP_EQ; LIFT_DROP; o_THM] THEN + REWRITE_TAC[GSYM IMAGE_LIFT_REAL_INTERVAL] THEN CONV_TAC SYM_CONV THEN + MATCH_MP_TAC REAL_INTEGRAL THEN + MATCH_MP_TAC REAL_INTEGRABLE_SUBINTERVAL THEN + MAP_EVERY EXISTS_TAC [`a:real`; `b:real`] THEN + ASM_REWRITE_TAC[SUBSET_REAL_INTERVAL] THEN + RULE_ASSUM_TAC(REWRITE_RULE[IN_REAL_INTERVAL]) THEN + ASM_REAL_ARITH_TAC);; + +let HAS_REAL_INTEGRAL_RESTRICT = prove + (`!f:real->real s t. + s SUBSET t + ==> (((\x. if x IN s then f x else &0) has_real_integral i) t <=> + (f has_real_integral i) s)`, + REPEAT STRIP_TAC THEN REWRITE_TAC[has_real_integral; o_DEF] THEN + MP_TAC(ISPECL [`lift o f o drop`; `IMAGE lift s`; `IMAGE lift t`; `lift i`] + HAS_INTEGRAL_RESTRICT) THEN + ASM_SIMP_TAC[IMAGE_SUBSET; IN_IMAGE_LIFT_DROP; o_DEF] THEN + DISCH_THEN(SUBST1_TAC o SYM) THEN + ONCE_REWRITE_TAC[COND_RAND] THEN REWRITE_TAC[LIFT_NUM]);; + +let HAS_REAL_INTEGRAL_RESTRICT_UNIV = prove + (`!f:real->real s i. + ((\x. if x IN s then f x else &0) has_real_integral i) (:real) <=> + (f has_real_integral i) s`, + SIMP_TAC[HAS_REAL_INTEGRAL_RESTRICT; SUBSET_UNIV]);; + +let HAS_REAL_INTEGRAL_SPIKE_SET_EQ = prove + (`!f s t y. + real_negligible(s DIFF t UNION t DIFF s) + ==> ((f has_real_integral y) s <=> (f has_real_integral y) t)`, + REPEAT STRIP_TAC THEN + ONCE_REWRITE_TAC[GSYM HAS_REAL_INTEGRAL_RESTRICT_UNIV] THEN + MATCH_MP_TAC HAS_REAL_INTEGRAL_SPIKE_EQ THEN + EXISTS_TAC `s DIFF t UNION t DIFF s:real->bool` THEN + ASM_REWRITE_TAC[] THEN SET_TAC[]);; + +let HAS_REAL_INTEGRAL_SPIKE_SET = prove + (`!f s t y. + real_negligible(s DIFF t UNION t DIFF s) /\ + (f has_real_integral y) s + ==> (f has_real_integral y) t`, + MESON_TAC[HAS_REAL_INTEGRAL_SPIKE_SET_EQ]);; + +let REAL_INTEGRABLE_SPIKE_SET = prove + (`!f s t. + real_negligible(s DIFF t UNION t DIFF s) + ==> f real_integrable_on s ==> f real_integrable_on t`, + REWRITE_TAC[real_integrable_on] THEN + MESON_TAC[HAS_REAL_INTEGRAL_SPIKE_SET_EQ]);; + +let REAL_INTEGRABLE_SPIKE_SET_EQ = prove + (`!f s t. + real_negligible(s DIFF t UNION t DIFF s) + ==> (f real_integrable_on s <=> f real_integrable_on t)`, + MESON_TAC[REAL_INTEGRABLE_SPIKE_SET; UNION_COMM]);; + +let REAL_INTEGRAL_SPIKE_SET = prove + (`!f s t. + real_negligible(s DIFF t UNION t DIFF s) + ==> real_integral s f = real_integral t f`, + REPEAT STRIP_TAC THEN REWRITE_TAC[real_integral] THEN + AP_TERM_TAC THEN ABS_TAC THEN MATCH_MP_TAC HAS_REAL_INTEGRAL_SPIKE_SET_EQ THEN + ASM_MESON_TAC[]);; + +let HAS_REAL_INTEGRAL_OPEN_INTERVAL = prove + (`!f a b y. (f has_real_integral y) (real_interval(a,b)) <=> + (f has_real_integral y) (real_interval[a,b])`, + REWRITE_TAC[has_real_integral; IMAGE_LIFT_REAL_INTERVAL] THEN + REWRITE_TAC[HAS_INTEGRAL_OPEN_INTERVAL]);; + +let REAL_INTEGRABLE_ON_OPEN_INTERVAL = prove + (`!f a b. f real_integrable_on real_interval(a,b) <=> + f real_integrable_on real_interval[a,b]`, + REWRITE_TAC[real_integrable_on; HAS_REAL_INTEGRAL_OPEN_INTERVAL]);; + +let REAL_INTEGRAL_OPEN_INTERVAL = prove + (`!f a b. real_integral(real_interval(a,b)) f = + real_integral(real_interval[a,b]) f`, + REWRITE_TAC[real_integral; HAS_REAL_INTEGRAL_OPEN_INTERVAL]);; + +let HAS_REAL_INTEGRAL_ON_SUPERSET = prove + (`!f s t. + (!x. ~(x IN s) ==> f x = &0) /\ s SUBSET t /\ (f has_real_integral i) s + ==> (f has_real_integral i) t`, + REPEAT GEN_TAC THEN REWRITE_TAC[SUBSET] THEN + REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + ONCE_REWRITE_TAC[GSYM HAS_REAL_INTEGRAL_RESTRICT_UNIV] THEN + MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_THM_TAC THEN + AP_TERM_TAC THEN ABS_TAC THEN ASM_MESON_TAC[]);; + +let REAL_INTEGRABLE_ON_SUPERSET = prove + (`!f s t. + (!x. ~(x IN s) ==> f x = &0) /\ s SUBSET t /\ f real_integrable_on s + ==> f real_integrable_on t`, + REWRITE_TAC[real_integrable_on] THEN + MESON_TAC[HAS_REAL_INTEGRAL_ON_SUPERSET]);; + +let REAL_INTEGRABLE_RESTRICT_UNIV = prove + (`!f s. (\x. if x IN s then f x else &0) real_integrable_on (:real) <=> + f real_integrable_on s`, + REWRITE_TAC[real_integrable_on; HAS_REAL_INTEGRAL_RESTRICT_UNIV]);; + +let REAL_INTEGRAL_RESTRICT_UNIV = prove + (`!f s. + real_integral (:real) (\x. if x IN s then f x else &0) = + real_integral s f`, + REWRITE_TAC[real_integral; HAS_REAL_INTEGRAL_RESTRICT_UNIV]);; + +let REAL_INTEGRAL_RESTRICT = prove + (`!f s t. + s SUBSET t + ==> real_integral t (\x. if x IN s then f x else &0) = + real_integral s f`, + SIMP_TAC[real_integral; HAS_REAL_INTEGRAL_RESTRICT]);; + +let HAS_REAL_INTEGRAL_RESTRICT_INTER = prove + (`!f s t. + ((\x. if x IN s then f x else &0) has_real_integral i) t <=> + (f has_real_integral i) (s INTER t)`, + REPEAT GEN_TAC THEN + ONCE_REWRITE_TAC[GSYM HAS_REAL_INTEGRAL_RESTRICT_UNIV] THEN + REWRITE_TAC[IN_INTER] THEN AP_THM_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN + REWRITE_TAC[FUN_EQ_THM] THEN MESON_TAC[]);; + +let REAL_INTEGRAL_RESTRICT_INTER = prove + (`!f s t. + real_integral t (\x. if x IN s then f x else &0) = + real_integral (s INTER t) f`, + REWRITE_TAC[real_integral; HAS_REAL_INTEGRAL_RESTRICT_INTER]);; + +let REAL_INTEGRABLE_RESTRICT_INTER = prove + (`!f s t. + (\x. if x IN s then f x else &0) real_integrable_on t <=> + f real_integrable_on (s INTER t)`, + REWRITE_TAC[real_integrable_on; HAS_REAL_INTEGRAL_RESTRICT_INTER]);; + +let REAL_NEGLIGIBLE_ON_INTERVALS = prove + (`!s. real_negligible s <=> + !a b:real. real_negligible(s INTER real_interval[a,b])`, + GEN_TAC THEN REWRITE_TAC[real_negligible] THEN + GEN_REWRITE_TAC LAND_CONV [NEGLIGIBLE_ON_INTERVALS] THEN + REWRITE_TAC[FORALL_LIFT; GSYM IMAGE_LIFT_REAL_INTERVAL] THEN + REPEAT(AP_TERM_TAC THEN ABS_TAC) THEN AP_TERM_TAC THEN SET_TAC[LIFT_DROP]);; + +let HAS_REAL_INTEGRAL_SUBSET_LE = prove + (`!f:real->real s t i j. + s SUBSET t /\ (f has_real_integral i) s /\ (f has_real_integral j) t /\ + (!x. x IN t ==> &0 <= f x) + ==> i <= j`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_REAL_INTEGRAL_LE THEN + MAP_EVERY EXISTS_TAC + [`\x:real. if x IN s then f(x) else &0`; + `\x:real. if x IN t then f(x) else &0`; `(:real)`] THEN + ASM_REWRITE_TAC[HAS_REAL_INTEGRAL_RESTRICT_UNIV; IN_UNIV] THEN + X_GEN_TAC `x:real` THEN + REPEAT(COND_CASES_TAC THEN ASM_SIMP_TAC[REAL_LE_REFL]) THEN + ASM SET_TAC[]);; + +let REAL_INTEGRAL_SUBSET_LE = prove + (`!f:real->real s t. + s SUBSET t /\ f real_integrable_on s /\ f real_integrable_on t /\ + (!x. x IN t ==> &0 <= f(x)) + ==> real_integral s f <= real_integral t f`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_REAL_INTEGRAL_SUBSET_LE THEN + ASM_MESON_TAC[REAL_INTEGRABLE_INTEGRAL]);; + +let REAL_INTEGRABLE_ON_SUBINTERVAL = prove + (`!f:real->real s a b. + f real_integrable_on s /\ real_interval[a,b] SUBSET s + ==> f real_integrable_on real_interval[a,b]`, + REWRITE_TAC[REAL_INTEGRABLE_ON; IMAGE_LIFT_REAL_INTERVAL] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC INTEGRABLE_ON_SUBINTERVAL THEN + EXISTS_TAC `IMAGE lift s` THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[GSYM IMAGE_LIFT_REAL_INTERVAL] THEN + ASM_SIMP_TAC[IMAGE_SUBSET]);; + +let REAL_INTEGRABLE_STRADDLE = prove + (`!f s. + (!e. &0 < e + ==> ?g h i j. (g has_real_integral i) s /\ + (h has_real_integral j) s /\ + abs(i - j) < e /\ + !x. x IN s ==> g x <= f x /\ f x <= h x) + ==> f real_integrable_on s`, + REWRITE_TAC[REAL_INTEGRABLE_ON; has_real_integral] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC INTEGRABLE_STRADDLE THEN + X_GEN_TAC `e:real` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `e:real`) THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[EXISTS_DROP; FORALL_IN_IMAGE] THEN + SIMP_TAC[LEFT_IMP_EXISTS_THM; GSYM DROP_SUB; LIFT_DROP; GSYM ABS_DROP] THEN + MAP_EVERY X_GEN_TAC + [`g:real->real`; `h:real->real`; `i:real^1`; `j:real^1`] THEN + STRIP_TAC THEN MAP_EVERY EXISTS_TAC + [`lift o g o drop`; `lift o h o drop`; `i:real^1`; `j:real^1`] THEN + ASM_REWRITE_TAC[o_THM; LIFT_DROP]);; + +let HAS_REAL_INTEGRAL_STRADDLE_NULL = prove + (`!f g s. (!x. x IN s ==> &0 <= f x /\ f x <= g x) /\ + (g has_real_integral &0) s + ==> (f has_real_integral &0) s`, + REPEAT STRIP_TAC THEN REWRITE_TAC[HAS_REAL_INTEGRAL_INTEGRABLE_INTEGRAL] THEN + MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN CONJ_TAC THENL + [MATCH_MP_TAC REAL_INTEGRABLE_STRADDLE THEN + GEN_TAC THEN DISCH_TAC THEN + MAP_EVERY EXISTS_TAC + [`(\x. &0):real->real`; `g:real->real`; + `&0:real`; `&0:real`] THEN + ASM_REWRITE_TAC[HAS_REAL_INTEGRAL_0; REAL_SUB_REFL; REAL_ABS_NUM]; + DISCH_TAC THEN REWRITE_TAC[GSYM REAL_LE_ANTISYM] THEN CONJ_TAC THENL + [MATCH_MP_TAC(ISPECL [`f:real->real`; `g:real->real`] + HAS_REAL_INTEGRAL_LE); + MATCH_MP_TAC(ISPECL [`(\x. &0):real->real`; `f:real->real`] + HAS_REAL_INTEGRAL_LE)] THEN + EXISTS_TAC `s:real->bool` THEN + ASM_SIMP_TAC[GSYM HAS_REAL_INTEGRAL_INTEGRAL; HAS_REAL_INTEGRAL_0]]);; + +let HAS_REAL_INTEGRAL_UNION = prove + (`!f i j s t. + (f has_real_integral i) s /\ (f has_real_integral j) t /\ + real_negligible(s INTER t) + ==> (f has_real_integral (i + j)) (s UNION t)`, + REPEAT GEN_TAC THEN + REWRITE_TAC[has_real_integral; real_negligible; LIFT_ADD; IMAGE_UNION] THEN + DISCH_TAC THEN MATCH_MP_TAC HAS_INTEGRAL_UNION THEN POP_ASSUM MP_TAC THEN + REPEAT(MATCH_MP_TAC MONO_AND THEN CONJ_TAC) THEN REWRITE_TAC[] THEN + MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN SET_TAC[LIFT_DROP]);; + +let HAS_REAL_INTEGRAL_UNIONS = prove + (`!f:real->real i t. + FINITE t /\ + (!s. s IN t ==> (f has_real_integral (i s)) s) /\ + (!s s'. s IN t /\ s' IN t /\ ~(s = s') ==> real_negligible(s INTER s')) + ==> (f has_real_integral (sum t i)) (UNIONS t)`, + REPEAT GEN_TAC THEN + REWRITE_TAC[has_real_integral; real_negligible; LIFT_ADD; IMAGE_UNIONS] THEN + SIMP_TAC[LIFT_SUM] THEN DISCH_TAC THEN + MP_TAC(ISPECL [`lift o f o drop`; `\s. lift(i(IMAGE drop s))`; + `IMAGE (IMAGE lift) t`] + HAS_INTEGRAL_UNIONS) THEN + ASM_SIMP_TAC[FINITE_IMAGE; FORALL_IN_IMAGE; IMP_CONJ; RIGHT_FORALL_IMP_THM; + IMAGE_LIFT_DROP; GSYM IMAGE_o] THEN + ASM_SIMP_TAC[LIFT_EQ; SET_RULE + `(!x y. f x = f y <=> x = y) + ==> (IMAGE f s = IMAGE f t <=> s = t) /\ + (IMAGE f s INTER IMAGE f t = IMAGE f (s INTER t))`] THEN + MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_TERM_TAC THEN + W(MP_TAC o PART_MATCH (lhs o rand) VSUM_IMAGE o lhand o snd) THEN + ANTS_TAC THENL [ASM SET_TAC[LIFT_DROP]; ALL_TAC] THEN + DISCH_THEN SUBST1_TAC THEN + REWRITE_TAC[o_DEF; GSYM IMAGE_o; IMAGE_LIFT_DROP]);; + +let REAL_MONOTONE_CONVERGENCE_INCREASING = prove + (`!f:num->real->real g s. + (!k. (f k) real_integrable_on s) /\ + (!k x. x IN s ==> f k x <= f (SUC k) x) /\ + (!x. x IN s ==> ((\k. f k x) ---> g x) sequentially) /\ + real_bounded {real_integral s (f k) | k IN (:num)} + ==> g real_integrable_on s /\ + ((\k. real_integral s (f k)) ---> real_integral s g) sequentially`, + REPEAT GEN_TAC THEN REWRITE_TAC[REAL_INTEGRABLE_ON; TENDSTO_REAL] THEN + REWRITE_TAC[o_DEF] THEN STRIP_TAC THEN + MP_TAC(ISPECL [`\n x. lift(f (n:num) (drop x))`; + `lift o g o drop`; `IMAGE lift s`] + MONOTONE_CONVERGENCE_INCREASING) THEN + ASM_REWRITE_TAC[FORALL_IN_IMAGE; LIFT_DROP; o_DEF] THEN + SUBGOAL_THEN + `!k:num. real_integral s (f k) = + drop(integral (IMAGE lift s) (lift o f k o drop))` + (fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th]) THEN REWRITE_TAC[th]) + THENL + [GEN_TAC THEN MATCH_MP_TAC REAL_INTEGRAL THEN + ASM_REWRITE_TAC[REAL_INTEGRABLE_ON; o_DEF]; + ALL_TAC] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [real_bounded]) THEN + REWRITE_TAC[FORALL_IN_GSPEC; IN_UNIV; GSYM ABS_DROP] THEN + DISCH_THEN(X_CHOOSE_TAC `B:real`) THEN ANTS_TAC THENL + [REWRITE_TAC[bounded] THEN EXISTS_TAC `B:real` THEN + RULE_ASSUM_TAC(REWRITE_RULE[o_DEF]) THEN + ASM_REWRITE_TAC[FORALL_IN_GSPEC; IN_UNIV]; + ALL_TAC] THEN + REWRITE_TAC[o_DEF; LIFT_DROP] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_TERM_TAC THEN + ONCE_REWRITE_TAC[GSYM DROP_EQ] THEN REWRITE_TAC[LIFT_DROP] THEN + CONV_TAC SYM_CONV THEN REWRITE_TAC[GSYM o_DEF] THEN + MATCH_MP_TAC REAL_INTEGRAL THEN ASM_REWRITE_TAC[REAL_INTEGRABLE_ON; o_DEF]);; + +let REAL_MONOTONE_CONVERGENCE_DECREASING = prove + (`!f:num->real->real g s. + (!k. (f k) real_integrable_on s) /\ + (!k x. x IN s ==> f (SUC k) x <= f k x) /\ + (!x. x IN s ==> ((\k. f k x) ---> g x) sequentially) /\ + real_bounded {real_integral s (f k) | k IN (:num)} + ==> g real_integrable_on s /\ + ((\k. real_integral s (f k)) ---> real_integral s g) sequentially`, + REPEAT GEN_TAC THEN REWRITE_TAC[REAL_INTEGRABLE_ON; TENDSTO_REAL] THEN + REWRITE_TAC[o_DEF] THEN STRIP_TAC THEN + MP_TAC(ISPECL [`\n x. lift(f (n:num) (drop x))`; + `lift o g o drop`; `IMAGE lift s`] + MONOTONE_CONVERGENCE_DECREASING) THEN + ASM_REWRITE_TAC[FORALL_IN_IMAGE; LIFT_DROP; o_DEF] THEN + SUBGOAL_THEN + `!k:num. real_integral s (f k) = + drop(integral (IMAGE lift s) (lift o f k o drop))` + (fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th]) THEN REWRITE_TAC[th]) + THENL + [GEN_TAC THEN MATCH_MP_TAC REAL_INTEGRAL THEN + ASM_REWRITE_TAC[REAL_INTEGRABLE_ON; o_DEF]; + ALL_TAC] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [real_bounded]) THEN + REWRITE_TAC[FORALL_IN_GSPEC; IN_UNIV; GSYM ABS_DROP] THEN + DISCH_THEN(X_CHOOSE_TAC `B:real`) THEN ANTS_TAC THENL + [REWRITE_TAC[bounded] THEN EXISTS_TAC `B:real` THEN + RULE_ASSUM_TAC(REWRITE_RULE[o_DEF]) THEN + ASM_REWRITE_TAC[FORALL_IN_GSPEC; IN_UNIV]; + ALL_TAC] THEN + REWRITE_TAC[o_DEF; LIFT_DROP] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_TERM_TAC THEN + ONCE_REWRITE_TAC[GSYM DROP_EQ] THEN REWRITE_TAC[LIFT_DROP] THEN + CONV_TAC SYM_CONV THEN REWRITE_TAC[GSYM o_DEF] THEN + MATCH_MP_TAC REAL_INTEGRAL THEN ASM_REWRITE_TAC[REAL_INTEGRABLE_ON; o_DEF]);; + +let REAL_BEPPO_LEVI_INCREASING = prove + (`!f s. (!k. (f k) real_integrable_on s) /\ + (!k x. x IN s ==> f k x <= f (SUC k) x) /\ + real_bounded {real_integral s (f k) | k IN (:num)} + ==> ?g k. real_negligible k /\ + !x. x IN (s DIFF k) ==> ((\k. f k x) ---> g x) sequentially`, + REPEAT GEN_TAC THEN REWRITE_TAC[REAL_INTEGRABLE_ON; TENDSTO_REAL] THEN + REWRITE_TAC[o_DEF] THEN STRIP_TAC THEN + MP_TAC(ISPECL [`\n x. lift(f (n:num) (drop x))`; + `IMAGE lift s`] + BEPPO_LEVI_INCREASING) THEN + ASM_REWRITE_TAC[FORALL_IN_IMAGE; LIFT_DROP; o_DEF] THEN + SUBGOAL_THEN + `!k:num. real_integral s (f k) = + drop(integral (IMAGE lift s) (lift o f k o drop))` + (fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th]) THEN REWRITE_TAC[th]) + THENL + [GEN_TAC THEN MATCH_MP_TAC REAL_INTEGRAL THEN + ASM_REWRITE_TAC[REAL_INTEGRABLE_ON; o_DEF]; + ALL_TAC] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [real_bounded]) THEN + REWRITE_TAC[FORALL_IN_GSPEC; IN_UNIV; GSYM ABS_DROP] THEN + DISCH_THEN(X_CHOOSE_TAC `B:real`) THEN ANTS_TAC THENL + [REWRITE_TAC[bounded] THEN EXISTS_TAC `B:real` THEN + RULE_ASSUM_TAC(REWRITE_RULE[o_DEF]) THEN + ASM_REWRITE_TAC[FORALL_IN_GSPEC; IN_UNIV]; + ALL_TAC] THEN + REWRITE_TAC[LEFT_IMP_EXISTS_THM; IN_DIFF; IMP_CONJ; FORALL_IN_IMAGE] THEN + MAP_EVERY X_GEN_TAC [`g:real^1->real^1`; `k:real^1->bool`] THEN + REWRITE_TAC[IMP_IMP; LIFT_DROP] THEN STRIP_TAC THEN + MAP_EVERY EXISTS_TAC [`drop o g o lift`; `IMAGE drop k`] THEN + ASM_REWRITE_TAC[real_negligible; GSYM IMAGE_o; IMAGE_LIFT_DROP] THEN + ASM_REWRITE_TAC[IN_IMAGE_LIFT_DROP; o_THM; LIFT_DROP]);; + +let REAL_BEPPO_LEVI_DECREASING = prove + (`!f s. (!k. (f k) real_integrable_on s) /\ + (!k x. x IN s ==> f (SUC k) x <= f k x) /\ + real_bounded {real_integral s (f k) | k IN (:num)} + ==> ?g k. real_negligible k /\ + !x. x IN (s DIFF k) ==> ((\k. f k x) ---> g x) sequentially`, + REPEAT GEN_TAC THEN REWRITE_TAC[REAL_INTEGRABLE_ON; TENDSTO_REAL] THEN + REWRITE_TAC[o_DEF] THEN STRIP_TAC THEN + MP_TAC(ISPECL [`\n x. lift(f (n:num) (drop x))`; + `IMAGE lift s`] + BEPPO_LEVI_DECREASING) THEN + ASM_REWRITE_TAC[FORALL_IN_IMAGE; LIFT_DROP; o_DEF] THEN + SUBGOAL_THEN + `!k:num. real_integral s (f k) = + drop(integral (IMAGE lift s) (lift o f k o drop))` + (fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th]) THEN REWRITE_TAC[th]) + THENL + [GEN_TAC THEN MATCH_MP_TAC REAL_INTEGRAL THEN + ASM_REWRITE_TAC[REAL_INTEGRABLE_ON; o_DEF]; + ALL_TAC] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [real_bounded]) THEN + REWRITE_TAC[FORALL_IN_GSPEC; IN_UNIV; GSYM ABS_DROP] THEN + DISCH_THEN(X_CHOOSE_TAC `B:real`) THEN ANTS_TAC THENL + [REWRITE_TAC[bounded] THEN EXISTS_TAC `B:real` THEN + RULE_ASSUM_TAC(REWRITE_RULE[o_DEF]) THEN + ASM_REWRITE_TAC[FORALL_IN_GSPEC; IN_UNIV]; + ALL_TAC] THEN + REWRITE_TAC[LEFT_IMP_EXISTS_THM; IN_DIFF; IMP_CONJ; FORALL_IN_IMAGE] THEN + MAP_EVERY X_GEN_TAC [`g:real^1->real^1`; `k:real^1->bool`] THEN + REWRITE_TAC[IMP_IMP; LIFT_DROP] THEN STRIP_TAC THEN + MAP_EVERY EXISTS_TAC [`drop o g o lift`; `IMAGE drop k`] THEN + ASM_REWRITE_TAC[real_negligible; GSYM IMAGE_o; IMAGE_LIFT_DROP] THEN + ASM_REWRITE_TAC[IN_IMAGE_LIFT_DROP; o_THM; LIFT_DROP]);; + +let REAL_BEPPO_LEVI_MONOTONE_CONVERGENCE_INCREASING = prove + (`!f s. + (!k. (f k) real_integrable_on s) /\ + (!k x. x IN s ==> f k x <= f (SUC k) x) /\ + real_bounded {real_integral s (f k) | k IN (:num)} + ==> ?g k. real_negligible k /\ + (!x. x IN (s DIFF k) ==> ((\k. f k x) ---> g x) sequentially) /\ + g real_integrable_on s /\ + ((\k. real_integral s (f k)) ---> real_integral s g) + sequentially`, + REPEAT GEN_TAC THEN REWRITE_TAC[REAL_INTEGRABLE_ON; TENDSTO_REAL] THEN + REWRITE_TAC[o_DEF] THEN STRIP_TAC THEN + MP_TAC(ISPECL [`\n x. lift(f (n:num) (drop x))`; + `IMAGE lift s`] + BEPPO_LEVI_MONOTONE_CONVERGENCE_INCREASING) THEN + ASM_REWRITE_TAC[FORALL_IN_IMAGE; LIFT_DROP; o_DEF] THEN + SUBGOAL_THEN + `!k:num. real_integral s (f k) = + drop(integral (IMAGE lift s) (lift o f k o drop))` + (fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th]) THEN REWRITE_TAC[th]) + THENL + [GEN_TAC THEN MATCH_MP_TAC REAL_INTEGRAL THEN + ASM_REWRITE_TAC[REAL_INTEGRABLE_ON; o_DEF]; + ALL_TAC] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [real_bounded]) THEN + REWRITE_TAC[FORALL_IN_GSPEC; IN_UNIV; GSYM ABS_DROP] THEN + DISCH_THEN(X_CHOOSE_TAC `B:real`) THEN ANTS_TAC THENL + [REWRITE_TAC[bounded] THEN EXISTS_TAC `B:real` THEN + RULE_ASSUM_TAC(REWRITE_RULE[o_DEF]) THEN + ASM_REWRITE_TAC[FORALL_IN_GSPEC; IN_UNIV]; + ALL_TAC] THEN + REWRITE_TAC[LEFT_IMP_EXISTS_THM; IN_DIFF; IMP_CONJ; FORALL_IN_IMAGE] THEN + MAP_EVERY X_GEN_TAC [`g:real^1->real^1`; `k:real^1->bool`] THEN + REWRITE_TAC[IMP_IMP; LIFT_DROP] THEN STRIP_TAC THEN + MAP_EVERY EXISTS_TAC [`drop o g o lift`; `IMAGE drop k`] THEN + ASM_REWRITE_TAC[real_negligible; GSYM IMAGE_o; IMAGE_LIFT_DROP] THEN + ASM_REWRITE_TAC[IN_IMAGE_LIFT_DROP; o_THM; LIFT_DROP; ETA_AX] THEN + SUBGOAL_THEN + `real_integral s (drop o g o lift) = + drop(integral (IMAGE lift s) (lift o (drop o g o lift) o drop))` + SUBST1_TAC THENL + [MATCH_MP_TAC REAL_INTEGRAL THEN + ASM_REWRITE_TAC[REAL_INTEGRABLE_ON; o_DEF; LIFT_DROP; ETA_AX]; + ASM_REWRITE_TAC[o_DEF; LIFT_DROP; ETA_AX]]);; + +let REAL_BEPPO_LEVI_MONOTONE_CONVERGENCE_DECREASING = prove + (`!f s. + (!k. (f k) real_integrable_on s) /\ + (!k x. x IN s ==> f (SUC k) x <= f k x) /\ + real_bounded {real_integral s (f k) | k IN (:num)} + ==> ?g k. real_negligible k /\ + (!x. x IN (s DIFF k) ==> ((\k. f k x) ---> g x) sequentially) /\ + g real_integrable_on s /\ + ((\k. real_integral s (f k)) ---> real_integral s g) + sequentially`, + REPEAT GEN_TAC THEN REWRITE_TAC[REAL_INTEGRABLE_ON; TENDSTO_REAL] THEN + REWRITE_TAC[o_DEF] THEN STRIP_TAC THEN + MP_TAC(ISPECL [`\n x. lift(f (n:num) (drop x))`; + `IMAGE lift s`] + BEPPO_LEVI_MONOTONE_CONVERGENCE_DECREASING) THEN + ASM_REWRITE_TAC[FORALL_IN_IMAGE; LIFT_DROP; o_DEF] THEN + SUBGOAL_THEN + `!k:num. real_integral s (f k) = + drop(integral (IMAGE lift s) (lift o f k o drop))` + (fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th]) THEN REWRITE_TAC[th]) + THENL + [GEN_TAC THEN MATCH_MP_TAC REAL_INTEGRAL THEN + ASM_REWRITE_TAC[REAL_INTEGRABLE_ON; o_DEF]; + ALL_TAC] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [real_bounded]) THEN + REWRITE_TAC[FORALL_IN_GSPEC; IN_UNIV; GSYM ABS_DROP] THEN + DISCH_THEN(X_CHOOSE_TAC `B:real`) THEN ANTS_TAC THENL + [REWRITE_TAC[bounded] THEN EXISTS_TAC `B:real` THEN + RULE_ASSUM_TAC(REWRITE_RULE[o_DEF]) THEN + ASM_REWRITE_TAC[FORALL_IN_GSPEC; IN_UNIV]; + ALL_TAC] THEN + REWRITE_TAC[LEFT_IMP_EXISTS_THM; IN_DIFF; IMP_CONJ; FORALL_IN_IMAGE] THEN + MAP_EVERY X_GEN_TAC [`g:real^1->real^1`; `k:real^1->bool`] THEN + REWRITE_TAC[IMP_IMP; LIFT_DROP] THEN STRIP_TAC THEN + MAP_EVERY EXISTS_TAC [`drop o g o lift`; `IMAGE drop k`] THEN + ASM_REWRITE_TAC[real_negligible; GSYM IMAGE_o; IMAGE_LIFT_DROP] THEN + ASM_REWRITE_TAC[IN_IMAGE_LIFT_DROP; o_THM; LIFT_DROP; ETA_AX] THEN + SUBGOAL_THEN + `real_integral s (drop o g o lift) = + drop(integral (IMAGE lift s) (lift o (drop o g o lift) o drop))` + SUBST1_TAC THENL + [MATCH_MP_TAC REAL_INTEGRAL THEN + ASM_REWRITE_TAC[REAL_INTEGRABLE_ON; o_DEF; LIFT_DROP; ETA_AX]; + ASM_REWRITE_TAC[o_DEF; LIFT_DROP; ETA_AX]]);; + +let REAL_INTEGRAL_ABS_BOUND_INTEGRAL = prove + (`!f:real->real g s. + f real_integrable_on s /\ g real_integrable_on s /\ + (!x. x IN s ==> abs(f x) <= g x) + ==> abs(real_integral s f) <= real_integral s g`, + SIMP_TAC[REAL_INTEGRAL; GSYM ABS_DROP] THEN + SIMP_TAC[REAL_INTEGRABLE_ON; INTEGRAL_NORM_BOUND_INTEGRAL] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC INTEGRAL_NORM_BOUND_INTEGRAL THEN + ASM_SIMP_TAC[FORALL_IN_IMAGE; o_THM; LIFT_DROP; NORM_LIFT]);; + +let ABSOLUTELY_REAL_INTEGRABLE_LE = prove + (`!f:real->real s. + f absolutely_real_integrable_on s + ==> abs(real_integral s f) <= real_integral s (\x. abs(f x))`, + SIMP_TAC[absolutely_real_integrable_on] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_INTEGRAL_ABS_BOUND_INTEGRAL THEN + ASM_REWRITE_TAC[REAL_LE_REFL]);; + +let ABSOLUTELY_REAL_INTEGRABLE_0 = prove + (`!s. (\x. &0) absolutely_real_integrable_on s`, + REWRITE_TAC[absolutely_real_integrable_on; REAL_ABS_NUM; + REAL_INTEGRABLE_0]);; + +let ABSOLUTELY_REAL_INTEGRABLE_CONST = prove + (`!a b c. (\x. c) absolutely_real_integrable_on real_interval[a,b]`, + REWRITE_TAC[absolutely_real_integrable_on; REAL_INTEGRABLE_CONST]);; + +let ABSOLUTELY_REAL_INTEGRABLE_LMUL = prove + (`!f s c. f absolutely_real_integrable_on s + ==> (\x. c * f(x)) absolutely_real_integrable_on s`, + SIMP_TAC[absolutely_real_integrable_on; + REAL_INTEGRABLE_LMUL; REAL_ABS_MUL]);; + +let ABSOLUTELY_REAL_INTEGRABLE_RMUL = prove + (`!f s c. f absolutely_real_integrable_on s + ==> (\x. f(x) * c) absolutely_real_integrable_on s`, + SIMP_TAC[absolutely_real_integrable_on; + REAL_INTEGRABLE_RMUL; REAL_ABS_MUL]);; + +let ABSOLUTELY_REAL_INTEGRABLE_NEG = prove + (`!f s. f absolutely_real_integrable_on s + ==> (\x. --f(x)) absolutely_real_integrable_on s`, + SIMP_TAC[absolutely_real_integrable_on; REAL_INTEGRABLE_NEG; REAL_ABS_NEG]);; + +let ABSOLUTELY_REAL_INTEGRABLE_ABS = prove + (`!f s. f absolutely_real_integrable_on s + ==> (\x. abs(f x)) absolutely_real_integrable_on s`, + SIMP_TAC[absolutely_real_integrable_on; REAL_ABS_ABS]);; + +let ABSOLUTELY_REAL_INTEGRABLE_ON_SUBINTERVAL = prove + (`!f:real->real s a b. + f absolutely_real_integrable_on s /\ real_interval[a,b] SUBSET s + ==> f absolutely_real_integrable_on real_interval[a,b]`, + REWRITE_TAC[absolutely_real_integrable_on] THEN + MESON_TAC[REAL_INTEGRABLE_ON_SUBINTERVAL]);; + +let ABSOLUTELY_REAL_INTEGRABLE_RESTRICT_UNIV = prove + (`!f s. (\x. if x IN s then f x else &0) + absolutely_real_integrable_on (:real) <=> + f absolutely_real_integrable_on s`, + REWRITE_TAC[absolutely_real_integrable_on; REAL_INTEGRABLE_RESTRICT_UNIV; + COND_RAND; REAL_ABS_NUM]);; + +let ABSOLUTELY_REAL_INTEGRABLE_ADD = prove + (`!f:real->real g s. + f absolutely_real_integrable_on s /\ + g absolutely_real_integrable_on s + ==> (\x. f(x) + g(x)) absolutely_real_integrable_on s`, + REWRITE_TAC[ABSOLUTELY_REAL_INTEGRABLE_ON] THEN + SIMP_TAC[o_DEF; LIFT_ADD; ABSOLUTELY_INTEGRABLE_ADD]);; + +let ABSOLUTELY_REAL_INTEGRABLE_SUB = prove + (`!f:real->real g s. + f absolutely_real_integrable_on s /\ + g absolutely_real_integrable_on s + ==> (\x. f(x) - g(x)) absolutely_real_integrable_on s`, + REWRITE_TAC[ABSOLUTELY_REAL_INTEGRABLE_ON] THEN + SIMP_TAC[o_DEF; LIFT_SUB; ABSOLUTELY_INTEGRABLE_SUB]);; + +let ABSOLUTELY_REAL_INTEGRABLE_LINEAR = prove + (`!f h s. + f absolutely_real_integrable_on s /\ linear(lift o h o drop) + ==> (h o f) absolutely_real_integrable_on s`, + REPEAT GEN_TAC THEN REWRITE_TAC[ABSOLUTELY_REAL_INTEGRABLE_ON] THEN + DISCH_THEN(MP_TAC o MATCH_MP ABSOLUTELY_INTEGRABLE_LINEAR) THEN + REWRITE_TAC[o_DEF; LIFT_DROP]);; + +let ABSOLUTELY_REAL_INTEGRABLE_SUM = prove + (`!f:A->real->real s t. + FINITE t /\ + (!a. a IN t ==> (f a) absolutely_real_integrable_on s) + ==> (\x. sum t (\a. f a x)) absolutely_real_integrable_on s`, + GEN_TAC THEN GEN_TAC THEN REWRITE_TAC[IMP_CONJ] THEN + MATCH_MP_TAC FINITE_INDUCT_STRONG THEN + SIMP_TAC[SUM_CLAUSES; ABSOLUTELY_REAL_INTEGRABLE_0; IN_INSERT; + ABSOLUTELY_REAL_INTEGRABLE_ADD; ETA_AX]);; + +let ABSOLUTELY_REAL_INTEGRABLE_MAX = prove + (`!f:real->real g:real->real s. + f absolutely_real_integrable_on s /\ g absolutely_real_integrable_on s + ==> (\x. max (f x) (g x)) + absolutely_real_integrable_on s`, + REPEAT STRIP_TAC THEN + REWRITE_TAC[REAL_ARITH `max a b = &1 / &2 * ((a + b) + abs(a - b))`] THEN + MATCH_MP_TAC ABSOLUTELY_REAL_INTEGRABLE_LMUL THEN + ASM_SIMP_TAC[ABSOLUTELY_REAL_INTEGRABLE_SUB; ABSOLUTELY_REAL_INTEGRABLE_ADD; + ABSOLUTELY_REAL_INTEGRABLE_ABS]);; + +let ABSOLUTELY_REAL_INTEGRABLE_MIN = prove + (`!f:real->real g:real->real s. + f absolutely_real_integrable_on s /\ g absolutely_real_integrable_on s + ==> (\x. min (f x) (g x)) + absolutely_real_integrable_on s`, + REPEAT STRIP_TAC THEN + REWRITE_TAC[REAL_ARITH `min a b = &1 / &2 * ((a + b) - abs(a - b))`] THEN + MATCH_MP_TAC ABSOLUTELY_REAL_INTEGRABLE_LMUL THEN + ASM_SIMP_TAC[ABSOLUTELY_REAL_INTEGRABLE_SUB; ABSOLUTELY_REAL_INTEGRABLE_ADD; + ABSOLUTELY_REAL_INTEGRABLE_ABS]);; + +let ABSOLUTELY_REAL_INTEGRABLE_IMP_INTEGRABLE = prove + (`!f s. f absolutely_real_integrable_on s ==> f real_integrable_on s`, + SIMP_TAC[absolutely_real_integrable_on]);; + +let ABSOLUTELY_REAL_INTEGRABLE_CONTINUOUS = prove + (`!f a b. + f real_continuous_on real_interval[a,b] + ==> f absolutely_real_integrable_on real_interval[a,b]`, + REWRITE_TAC[REAL_CONTINUOUS_ON; ABSOLUTELY_REAL_INTEGRABLE_ON; + has_real_integral; + GSYM integrable_on; GSYM EXISTS_LIFT] THEN + REWRITE_TAC[IMAGE_LIFT_REAL_INTERVAL; ABSOLUTELY_INTEGRABLE_CONTINUOUS]);; + +let NONNEGATIVE_ABSOLUTELY_REAL_INTEGRABLE = prove + (`!f s. + (!x. x IN s ==> &0 <= f(x)) /\ + f real_integrable_on s + ==> f absolutely_real_integrable_on s`, + SIMP_TAC[absolutely_real_integrable_on] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_INTEGRABLE_EQ THEN + EXISTS_TAC `f:real->real` THEN ASM_SIMP_TAC[real_abs]);; + +let ABSOLUTELY_REAL_INTEGRABLE_INTEGRABLE_BOUND = prove + (`!f:real->real g s. + (!x. x IN s ==> abs(f x) <= g x) /\ + f real_integrable_on s /\ g real_integrable_on s + ==> f absolutely_real_integrable_on s`, + REWRITE_TAC[REAL_INTEGRABLE_ON; ABSOLUTELY_REAL_INTEGRABLE_ON] THEN + REPEAT STRIP_TAC THEN + MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_INTEGRABLE_BOUND THEN + EXISTS_TAC `lift o g o drop` THEN ASM_REWRITE_TAC[FORALL_IN_IMAGE] THEN + ASM_REWRITE_TAC[o_DEF; LIFT_DROP; NORM_LIFT]);; + +let ABSOLUTELY_REAL_INTEGRABLE_ABSOLUTELY_REAL_INTEGRABLE_BOUND = prove + (`!f:real->real g:real->real s. + (!x. x IN s ==> abs(f x) <= abs(g x)) /\ + f real_integrable_on s /\ g absolutely_real_integrable_on s + ==> f absolutely_real_integrable_on s`, + REPEAT STRIP_TAC THEN + MATCH_MP_TAC ABSOLUTELY_REAL_INTEGRABLE_INTEGRABLE_BOUND THEN + EXISTS_TAC `\x:real. abs(g x)` THEN ASM_REWRITE_TAC[] THEN + RULE_ASSUM_TAC(REWRITE_RULE[absolutely_real_integrable_on]) THEN + ASM_REWRITE_TAC[]);; + +let ABSOLUTELY_REAL_INTEGRABLE_ABSOLUTELY_REAL_INTEGRABLE_UBOUND = prove + (`!f:real->real g:real->real s. + (!x. x IN s ==> f x <= g x) /\ + f real_integrable_on s /\ g absolutely_real_integrable_on s + ==> f absolutely_real_integrable_on s`, + REWRITE_TAC[ABSOLUTELY_REAL_INTEGRABLE_ON; REAL_INTEGRABLE_ON] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC + ABSOLUTELY_INTEGRABLE_ABSOLUTELY_INTEGRABLE_COMPONENT_UBOUND THEN + EXISTS_TAC `lift o g o drop` THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_IMAGE] THEN + ASM_REWRITE_TAC[IMP_IMP; DIMINDEX_1; FORALL_1; o_THM; LIFT_DROP; + GSYM drop]);; + +let ABSOLUTELY_REAL_INTEGRABLE_ABSOLUTELY_REAL_INTEGRABLE_LBOUND = prove + (`!f:real->real g:real->real s. + (!x. x IN s ==> f x <= g x) /\ + f absolutely_real_integrable_on s /\ g real_integrable_on s + ==> f absolutely_real_integrable_on s`, + REWRITE_TAC[ABSOLUTELY_REAL_INTEGRABLE_ON; REAL_INTEGRABLE_ON] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC + ABSOLUTELY_INTEGRABLE_ABSOLUTELY_INTEGRABLE_COMPONENT_LBOUND THEN + EXISTS_TAC `lift o f o drop` THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_IMAGE] THEN + ASM_REWRITE_TAC[IMP_IMP; DIMINDEX_1; FORALL_1; o_THM; LIFT_DROP; + GSYM drop]);; + +let ABSOLUTELY_REAL_INTEGRABLE_INF = prove + (`!fs s:real->bool k:A->bool. + FINITE k /\ ~(k = {}) /\ + (!i. i IN k ==> (\x. fs x i) absolutely_real_integrable_on s) + ==> (\x. inf (IMAGE (fs x) k)) absolutely_real_integrable_on s`, + GEN_TAC THEN GEN_TAC THEN REWRITE_TAC[IMP_CONJ] THEN + MATCH_MP_TAC FINITE_INDUCT_STRONG THEN REWRITE_TAC[IMAGE_CLAUSES] THEN + SIMP_TAC[INF_INSERT_FINITE; FINITE_IMAGE; IMAGE_EQ_EMPTY] THEN + MAP_EVERY X_GEN_TAC [`a:A`; `k:A->bool`] THEN + ASM_CASES_TAC `k:A->bool = {}` THEN ASM_REWRITE_TAC[] THEN + SIMP_TAC[IN_SING; LEFT_FORALL_IMP_THM; EXISTS_REFL] THEN + REWRITE_TAC[IMP_IMP; GSYM CONJ_ASSOC] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC ABSOLUTELY_REAL_INTEGRABLE_MIN THEN + CONJ_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN REWRITE_TAC[IN_INSERT] THEN + REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_REWRITE_TAC[IN_INSERT]);; + +let ABSOLUTELY_REAL_INTEGRABLE_SUP = prove + (`!fs s:real->bool k:A->bool. + FINITE k /\ ~(k = {}) /\ + (!i. i IN k ==> (\x. fs x i) absolutely_real_integrable_on s) + ==> (\x. sup (IMAGE (fs x) k)) absolutely_real_integrable_on s`, + GEN_TAC THEN GEN_TAC THEN REWRITE_TAC[IMP_CONJ] THEN + MATCH_MP_TAC FINITE_INDUCT_STRONG THEN REWRITE_TAC[IMAGE_CLAUSES] THEN + SIMP_TAC[SUP_INSERT_FINITE; FINITE_IMAGE; IMAGE_EQ_EMPTY] THEN + MAP_EVERY X_GEN_TAC [`a:A`; `k:A->bool`] THEN + ASM_CASES_TAC `k:A->bool = {}` THEN ASM_REWRITE_TAC[] THEN + SIMP_TAC[IN_SING; LEFT_FORALL_IMP_THM; EXISTS_REFL] THEN + REWRITE_TAC[IMP_IMP; GSYM CONJ_ASSOC] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC ABSOLUTELY_REAL_INTEGRABLE_MAX THEN + CONJ_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN REWRITE_TAC[IN_INSERT] THEN + REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_REWRITE_TAC[IN_INSERT]);; + +let REAL_DOMINATED_CONVERGENCE = prove + (`!f:num->real->real g h s. + (!k. (f k) real_integrable_on s) /\ h real_integrable_on s /\ + (!k x. x IN s ==> abs(f k x) <= h x) /\ + (!x. x IN s ==> ((\k. f k x) ---> g x) sequentially) + ==> g real_integrable_on s /\ + ((\k. real_integral s (f k)) ---> real_integral s g) sequentially`, + REPEAT GEN_TAC THEN REWRITE_TAC[REAL_INTEGRABLE_ON; TENDSTO_REAL] THEN + REWRITE_TAC[o_DEF] THEN STRIP_TAC THEN + MP_TAC(ISPECL [`\n x. lift(f (n:num) (drop x))`; + `lift o g o drop`; `lift o h o drop`; `IMAGE lift s`] + DOMINATED_CONVERGENCE) THEN + ASM_REWRITE_TAC[FORALL_IN_IMAGE; LIFT_DROP; o_DEF; NORM_LIFT] THEN + SUBGOAL_THEN + `!k:num. real_integral s (f k) = + drop(integral (IMAGE lift s) (lift o f k o drop))` + (fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th]) THEN REWRITE_TAC[th]) + THENL + [GEN_TAC THEN MATCH_MP_TAC REAL_INTEGRAL THEN + ASM_REWRITE_TAC[REAL_INTEGRABLE_ON; o_DEF]; + ALL_TAC] THEN + REWRITE_TAC[o_DEF; LIFT_DROP] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_TERM_TAC THEN + ONCE_REWRITE_TAC[GSYM DROP_EQ] THEN REWRITE_TAC[LIFT_DROP] THEN + CONV_TAC SYM_CONV THEN REWRITE_TAC[GSYM o_DEF] THEN + MATCH_MP_TAC REAL_INTEGRAL THEN ASM_REWRITE_TAC[REAL_INTEGRABLE_ON; o_DEF]);; + +let HAS_REAL_MEASURE_HAS_MEASURE = prove + (`!s m. s has_real_measure m <=> (IMAGE lift s) has_measure m`, + REWRITE_TAC[has_real_measure; has_measure; has_real_integral] THEN + REWRITE_TAC[o_DEF; LIFT_NUM]);; + +let REAL_MEASURABLE_MEASURABLE = prove + (`!s. real_measurable s <=> measurable(IMAGE lift s)`, + REWRITE_TAC[real_measurable; measurable; HAS_REAL_MEASURE_HAS_MEASURE]);; + +let REAL_MEASURE_MEASURE = prove + (`!s. real_measure s = measure (IMAGE lift s)`, + REWRITE_TAC[real_measure; measure; HAS_REAL_MEASURE_HAS_MEASURE]);; + +let HAS_REAL_MEASURE_MEASURE = prove + (`!s. real_measurable s <=> s has_real_measure (real_measure s)`, + REWRITE_TAC[real_measure; real_measurable] THEN MESON_TAC[]);; + +let HAS_REAL_MEASURE_UNIQUE = prove + (`!s m1 m2. s has_real_measure m1 /\ s has_real_measure m2 ==> m1 = m2`, + REWRITE_TAC[has_real_measure] THEN MESON_TAC[HAS_REAL_INTEGRAL_UNIQUE]);; + +let REAL_MEASURE_UNIQUE = prove + (`!s m. s has_real_measure m ==> real_measure s = m`, + MESON_TAC[HAS_REAL_MEASURE_UNIQUE; HAS_REAL_MEASURE_MEASURE; + real_measurable]);; + +let HAS_REAL_MEASURE_REAL_MEASURABLE_REAL_MEASURE = prove + (`!s m. s has_real_measure m <=> real_measurable s /\ real_measure s = m`, + REWRITE_TAC[HAS_REAL_MEASURE_MEASURE] THEN MESON_TAC[REAL_MEASURE_UNIQUE]);; + +let HAS_REAL_MEASURE_IMP_REAL_MEASURABLE = prove + (`!s m. s has_real_measure m ==> real_measurable s`, + REWRITE_TAC[real_measurable] THEN MESON_TAC[]);; + +let HAS_REAL_MEASURE = prove + (`!s m. s has_real_measure m <=> + ((\x. if x IN s then &1 else &0) has_real_integral m) (:real)`, + SIMP_TAC[HAS_REAL_INTEGRAL_RESTRICT_UNIV; has_real_measure]);; + +let REAL_MEASURABLE = prove + (`!s. real_measurable s <=> (\x. &1) real_integrable_on s`, + REWRITE_TAC[real_measurable; real_integrable_on; + has_real_measure; EXISTS_DROP; LIFT_DROP]);; + +let REAL_MEASURABLE_REAL_INTEGRABLE = prove + (`real_measurable s <=> + (\x. if x IN s then &1 else &0) real_integrable_on UNIV`, + REWRITE_TAC[real_measurable; real_integrable_on; HAS_REAL_MEASURE]);; + +let REAL_MEASURE_REAL_INTEGRAL = prove + (`!s. real_measurable s ==> real_measure s = real_integral s (\x. &1)`, + REPEAT STRIP_TAC THEN CONV_TAC SYM_CONV THEN + MATCH_MP_TAC REAL_INTEGRAL_UNIQUE THEN + ASM_REWRITE_TAC[GSYM has_real_measure; GSYM HAS_REAL_MEASURE_MEASURE]);; + +let REAL_MEASURE_REAL_INTEGRAL_UNIV = prove + (`!s. real_measurable s + ==> real_measure s = + real_integral UNIV (\x. if x IN s then &1 else &0)`, + REPEAT STRIP_TAC THEN CONV_TAC SYM_CONV THEN + MATCH_MP_TAC REAL_INTEGRAL_UNIQUE THEN + ASM_REWRITE_TAC[GSYM HAS_REAL_MEASURE; GSYM HAS_REAL_MEASURE_MEASURE]);; + +let REAL_INTEGRAL_REAL_MEASURE = prove + (`!s. real_measurable s ==> real_integral s (\x. &1) = real_measure s`, + SIMP_TAC[GSYM DROP_EQ; LIFT_DROP; REAL_MEASURE_REAL_INTEGRAL]);; + +let REAL_INTEGRAL_REAL_MEASURE_UNIV = prove + (`!s. real_measurable s + ==> real_integral UNIV (\x. if x IN s then &1 else &0) = + real_measure s`, + SIMP_TAC[REAL_MEASURE_REAL_INTEGRAL_UNIV]);; + +let HAS_REAL_MEASURE_REAL_INTERVAL = prove + (`(!a b. real_interval[a,b] has_real_measure (max (b - a) (&0))) /\ + (!a b. real_interval(a,b) has_real_measure (max (b - a) (&0)))`, + REWRITE_TAC[HAS_REAL_MEASURE_HAS_MEASURE; IMAGE_LIFT_REAL_INTERVAL] THEN + REWRITE_TAC[HAS_MEASURE_MEASURABLE_MEASURE; MEASURABLE_INTERVAL; + MEASURE_INTERVAL] THEN + REWRITE_TAC[CONTENT_CLOSED_INTERVAL_CASES; DIMINDEX_1; FORALL_1] THEN + REWRITE_TAC[PRODUCT_1; GSYM drop; LIFT_DROP] THEN REAL_ARITH_TAC);; + +let REAL_MEASURABLE_REAL_INTERVAL = prove + (`(!a b. real_measurable (real_interval[a,b])) /\ + (!a b. real_measurable (real_interval(a,b)))`, + REWRITE_TAC[real_measurable] THEN + MESON_TAC[HAS_REAL_MEASURE_REAL_INTERVAL]);; + +let REAL_MEASURE_REAL_INTERVAL = prove + (`(!a b. real_measure(real_interval[a,b]) = max (b - a) (&0)) /\ + (!a b. real_measure(real_interval(a,b)) = max (b - a) (&0))`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_MEASURE_UNIQUE THEN + REWRITE_TAC[HAS_REAL_MEASURE_REAL_INTERVAL]);; + +let REAL_MEASURABLE_INTER = prove + (`!s t. real_measurable s /\ real_measurable t + ==> real_measurable (s INTER t)`, + REPEAT GEN_TAC THEN REWRITE_TAC[REAL_MEASURABLE_MEASURABLE] THEN + DISCH_THEN(MP_TAC o MATCH_MP MEASURABLE_INTER) THEN + MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN SET_TAC[LIFT_DROP]);; + +let REAL_MEASURABLE_UNION = prove + (`!s t. real_measurable s /\ real_measurable t + ==> real_measurable (s UNION t)`, + REPEAT GEN_TAC THEN REWRITE_TAC[REAL_MEASURABLE_MEASURABLE] THEN + DISCH_THEN(MP_TAC o MATCH_MP MEASURABLE_UNION) THEN + MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN SET_TAC[LIFT_DROP]);; + +let HAS_REAL_MEASURE_DISJOINT_UNION = prove + (`!s1 s2 m1 m2. s1 has_real_measure m1 /\ s2 has_real_measure m2 /\ + DISJOINT s1 s2 + ==> (s1 UNION s2) has_real_measure (m1 + m2)`, + REPEAT GEN_TAC THEN + REWRITE_TAC[HAS_REAL_MEASURE_HAS_MEASURE; IMAGE_UNION] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_MEASURE_DISJOINT_UNION THEN + ASM SET_TAC[LIFT_DROP]);; + +let REAL_MEASURE_DISJOINT_UNION = prove + (`!s t. real_measurable s /\ real_measurable t /\ DISJOINT s t + ==> real_measure(s UNION t) = real_measure s + real_measure t`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_MEASURE_UNIQUE THEN + ASM_SIMP_TAC[HAS_REAL_MEASURE_DISJOINT_UNION; + GSYM HAS_REAL_MEASURE_MEASURE]);; + +let HAS_REAL_MEASURE_POS_LE = prove + (`!m s. s has_real_measure m ==> &0 <= m`, + REWRITE_TAC[HAS_REAL_MEASURE_HAS_MEASURE; HAS_MEASURE_POS_LE]);; + +let REAL_MEASURE_POS_LE = prove + (`!s. real_measurable s ==> &0 <= real_measure s`, + REWRITE_TAC[HAS_REAL_MEASURE_MEASURE; HAS_REAL_MEASURE_POS_LE]);; + +let HAS_REAL_MEASURE_SUBSET = prove + (`!s1 s2 m1 m2. + s1 has_real_measure m1 /\ s2 has_real_measure m2 /\ s1 SUBSET s2 + ==> m1 <= m2`, + REWRITE_TAC[HAS_REAL_MEASURE_HAS_MEASURE] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC(ISPECL [`IMAGE lift s1`; `IMAGE lift s2`] + HAS_MEASURE_SUBSET) THEN + ASM SET_TAC[HAS_MEASURE_SUBSET]);; + +let REAL_MEASURE_SUBSET = prove + (`!s t. real_measurable s /\ real_measurable t /\ s SUBSET t + ==> real_measure s <= real_measure t`, + REWRITE_TAC[HAS_REAL_MEASURE_MEASURE] THEN + MESON_TAC[HAS_REAL_MEASURE_SUBSET]);; + +let HAS_REAL_MEASURE_0 = prove + (`!s. s has_real_measure &0 <=> real_negligible s`, + REWRITE_TAC[real_negligible; HAS_REAL_MEASURE_HAS_MEASURE] THEN + REWRITE_TAC[HAS_MEASURE_0]);; + +let REAL_MEASURE_EQ_0 = prove + (`!s. real_negligible s ==> real_measure s = &0`, + MESON_TAC[REAL_MEASURE_UNIQUE; HAS_REAL_MEASURE_0]);; + +let HAS_REAL_MEASURE_EMPTY = prove + (`{} has_real_measure &0`, + REWRITE_TAC[HAS_REAL_MEASURE_0; REAL_NEGLIGIBLE_EMPTY]);; + +let REAL_MEASURE_EMPTY = prove + (`real_measure {} = &0`, + SIMP_TAC[REAL_MEASURE_EQ_0; REAL_NEGLIGIBLE_EMPTY]);; + +let REAL_MEASURABLE_EMPTY = prove + (`real_measurable {}`, + REWRITE_TAC[real_measurable] THEN MESON_TAC[HAS_REAL_MEASURE_EMPTY]);; + +let REAL_MEASURABLE_REAL_MEASURE_EQ_0 = prove + (`!s. real_measurable s ==> (real_measure s = &0 <=> real_negligible s)`, + REWRITE_TAC[HAS_REAL_MEASURE_MEASURE; GSYM HAS_REAL_MEASURE_0] THEN + MESON_TAC[REAL_MEASURE_UNIQUE]);; + +let REAL_MEASURABLE_REAL_MEASURE_POS_LT = prove + (`!s. real_measurable s ==> (&0 < real_measure s <=> ~real_negligible s)`, + SIMP_TAC[REAL_LT_LE; REAL_MEASURE_POS_LE; + GSYM REAL_MEASURABLE_REAL_MEASURE_EQ_0] THEN + REWRITE_TAC[EQ_SYM_EQ]);; + +let REAL_NEGLIGIBLE_REAL_INTERVAL = prove + (`(!a b. real_negligible(real_interval[a,b]) <=> real_interval(a,b) = {}) /\ + (!a b. real_negligible(real_interval(a,b)) <=> real_interval(a,b) = {})`, + REWRITE_TAC[real_negligible; IMAGE_LIFT_REAL_INTERVAL] THEN + REWRITE_TAC[NEGLIGIBLE_INTERVAL] THEN + REWRITE_TAC[REAL_INTERVAL_EQ_EMPTY; INTERVAL_EQ_EMPTY_1; LIFT_DROP]);; + +let REAL_MEASURABLE_UNIONS = prove + (`!f. FINITE f /\ (!s. s IN f ==> real_measurable s) + ==> real_measurable (UNIONS f)`, + REWRITE_TAC[REAL_MEASURABLE_MEASURABLE; IMAGE_UNIONS] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC MEASURABLE_UNIONS THEN + ASM_SIMP_TAC[FINITE_IMAGE; FORALL_IN_IMAGE]);; + +let HAS_REAL_MEASURE_DIFF_SUBSET = prove + (`!s1 s2 m1 m2. + s1 has_real_measure m1 /\ s2 has_real_measure m2 /\ s2 SUBSET s1 + ==> (s1 DIFF s2) has_real_measure (m1 - m2)`, + REWRITE_TAC[HAS_REAL_MEASURE_HAS_MEASURE] THEN REPEAT STRIP_TAC THEN + SIMP_TAC[IMAGE_DIFF_INJ; LIFT_EQ] THEN + MATCH_MP_TAC HAS_MEASURE_DIFF_SUBSET THEN + ASM_SIMP_TAC[IMAGE_SUBSET]);; + +let REAL_MEASURABLE_DIFF = prove + (`!s t. real_measurable s /\ real_measurable t + ==> real_measurable (s DIFF t)`, + SIMP_TAC[REAL_MEASURABLE_MEASURABLE; IMAGE_DIFF_INJ; LIFT_EQ] THEN + REWRITE_TAC[MEASURABLE_DIFF]);; + +let REAL_MEASURE_DIFF_SUBSET = prove + (`!s t. real_measurable s /\ real_measurable t /\ t SUBSET s + ==> real_measure(s DIFF t) = real_measure s - real_measure t`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_MEASURE_UNIQUE THEN + ASM_SIMP_TAC[HAS_REAL_MEASURE_DIFF_SUBSET; GSYM HAS_REAL_MEASURE_MEASURE]);; + +let HAS_REAL_MEASURE_UNION_REAL_NEGLIGIBLE = prove + (`!s t m. + s has_real_measure m /\ real_negligible t + ==> (s UNION t) has_real_measure m`, + REWRITE_TAC[HAS_REAL_MEASURE_HAS_MEASURE; real_negligible; IMAGE_UNION] THEN + REWRITE_TAC[HAS_MEASURE_UNION_NEGLIGIBLE]);; + +let HAS_REAL_MEASURE_DIFF_REAL_NEGLIGIBLE = prove + (`!s t m. + s has_real_measure m /\ real_negligible t + ==> (s DIFF t) has_real_measure m`, + REWRITE_TAC[HAS_REAL_MEASURE_HAS_MEASURE; real_negligible] THEN + SIMP_TAC[IMAGE_DIFF_INJ; LIFT_EQ] THEN + REWRITE_TAC[HAS_MEASURE_DIFF_NEGLIGIBLE]);; + +let HAS_REAL_MEASURE_UNION_REAL_NEGLIGIBLE_EQ = prove + (`!s t m. + real_negligible t + ==> ((s UNION t) has_real_measure m <=> s has_real_measure m)`, + REWRITE_TAC[HAS_REAL_MEASURE_HAS_MEASURE; real_negligible; IMAGE_UNION] THEN + REWRITE_TAC[HAS_MEASURE_UNION_NEGLIGIBLE_EQ]);; + +let HAS_REAL_MEASURE_DIFF_REAL_NEGLIGIBLE_EQ = prove + (`!s t m. + real_negligible t + ==> ((s DIFF t) has_real_measure m <=> s has_real_measure m)`, + REWRITE_TAC[HAS_REAL_MEASURE_HAS_MEASURE; real_negligible] THEN + SIMP_TAC[IMAGE_DIFF_INJ; LIFT_EQ] THEN + REWRITE_TAC[HAS_MEASURE_DIFF_NEGLIGIBLE_EQ]);; + +let HAS_REAL_MEASURE_ALMOST = prove + (`!s s' t m. s has_real_measure m /\ real_negligible t /\ + s UNION t = s' UNION t + ==> s' has_real_measure m`, + REWRITE_TAC[HAS_REAL_MEASURE_HAS_MEASURE; real_negligible; IMAGE_UNION] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_MEASURE_ALMOST THEN + MAP_EVERY EXISTS_TAC [`IMAGE lift s`; `IMAGE lift t`] THEN ASM SET_TAC[]);; + +let HAS_REAL_MEASURE_ALMOST_EQ = prove + (`!s s' t. real_negligible t /\ s UNION t = s' UNION t + ==> (s has_real_measure m <=> s' has_real_measure m)`, + MESON_TAC[HAS_REAL_MEASURE_ALMOST]);; + +let REAL_MEASURABLE_ALMOST = prove + (`!s s' t. real_measurable s /\ real_negligible t /\ s UNION t = s' UNION t + ==> real_measurable s'`, + REWRITE_TAC[real_measurable] THEN MESON_TAC[HAS_REAL_MEASURE_ALMOST]);; + +let HAS_REAL_MEASURE_REAL_NEGLIGIBLE_UNION = prove + (`!s1 s2 m1 m2. + s1 has_real_measure m1 /\ s2 has_real_measure m2 /\ + real_negligible(s1 INTER s2) + ==> (s1 UNION s2) has_real_measure (m1 + m2)`, + REWRITE_TAC[HAS_REAL_MEASURE_HAS_MEASURE; real_negligible; IMAGE_UNION] THEN + SIMP_TAC[IMAGE_INTER_INJ; LIFT_EQ] THEN + REWRITE_TAC[HAS_MEASURE_NEGLIGIBLE_UNION]);; + +let REAL_MEASURE_REAL_NEGLIGIBLE_UNION = prove + (`!s t. real_measurable s /\ real_measurable t /\ real_negligible(s INTER t) + ==> real_measure(s UNION t) = real_measure s + real_measure t`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_MEASURE_UNIQUE THEN + ASM_SIMP_TAC[HAS_REAL_MEASURE_REAL_NEGLIGIBLE_UNION; + GSYM HAS_REAL_MEASURE_MEASURE]);; + +let HAS_REAL_MEASURE_REAL_NEGLIGIBLE_SYMDIFF = prove + (`!s t m. + s has_real_measure m /\ + real_negligible((s DIFF t) UNION (t DIFF s)) + ==> t has_real_measure m`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_REAL_MEASURE_ALMOST THEN + MAP_EVERY EXISTS_TAC + [`s:real->bool`; `(s DIFF t) UNION (t DIFF s):real->bool`] THEN + ASM_REWRITE_TAC[] THEN SET_TAC[]);; + +let REAL_MEASURABLE_REAL_NEGLIGIBLE_SYMDIFF = prove + (`!s t. real_measurable s /\ real_negligible((s DIFF t) UNION (t DIFF s)) + ==> real_measurable t`, + REWRITE_TAC[real_measurable] THEN + MESON_TAC[HAS_REAL_MEASURE_REAL_NEGLIGIBLE_SYMDIFF]);; + +let REAL_MEASURE_REAL_NEGLIGIBLE_SYMDIFF = prove + (`!s t. (real_measurable s \/ real_measurable t) /\ + real_negligible((s DIFF t) UNION (t DIFF s)) + ==> real_measure s = real_measure t`, + MESON_TAC[HAS_REAL_MEASURE_REAL_NEGLIGIBLE_SYMDIFF; REAL_MEASURE_UNIQUE; + UNION_COMM; HAS_REAL_MEASURE_MEASURE]);; + +let HAS_REAL_MEASURE_REAL_NEGLIGIBLE_UNIONS = prove + (`!m f. FINITE f /\ + (!s. s IN f ==> s has_real_measure (m s)) /\ + (!s t. s IN f /\ t IN f /\ ~(s = t) ==> real_negligible(s INTER t)) + ==> (UNIONS f) has_real_measure (sum f m)`, + GEN_TAC THEN ONCE_REWRITE_TAC[IMP_CONJ] THEN + MATCH_MP_TAC FINITE_INDUCT_STRONG THEN + SIMP_TAC[SUM_CLAUSES; UNIONS_0; UNIONS_INSERT; HAS_REAL_MEASURE_EMPTY] THEN + REWRITE_TAC[IN_INSERT] THEN + MAP_EVERY X_GEN_TAC [`s:real->bool`; `f:(real->bool)->bool`] THEN + STRIP_TAC THEN STRIP_TAC THEN + MATCH_MP_TAC HAS_REAL_MEASURE_REAL_NEGLIGIBLE_UNION THEN + REPEAT(CONJ_TAC THENL [ASM_MESON_TAC[]; ALL_TAC]) THEN + REWRITE_TAC[INTER_UNIONS] THEN MATCH_MP_TAC REAL_NEGLIGIBLE_UNIONS THEN + ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN + ASM_SIMP_TAC[FINITE_IMAGE; FORALL_IN_IMAGE] THEN REPEAT STRIP_TAC THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_MESON_TAC[]);; + +let REAL_MEASURE_REAL_NEGLIGIBLE_UNIONS = prove + (`!m f. FINITE f /\ + (!s. s IN f ==> s has_real_measure (m s)) /\ + (!s t. s IN f /\ t IN f /\ ~(s = t) ==> real_negligible(s INTER t)) + ==> real_measure(UNIONS f) = sum f m`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_MEASURE_UNIQUE THEN + ASM_SIMP_TAC[HAS_REAL_MEASURE_REAL_NEGLIGIBLE_UNIONS]);; + +let HAS_REAL_MEASURE_DISJOINT_UNIONS = prove + (`!m f. FINITE f /\ + (!s. s IN f ==> s has_real_measure (m s)) /\ + (!s t. s IN f /\ t IN f /\ ~(s = t) ==> DISJOINT s t) + ==> (UNIONS f) has_real_measure (sum f m)`, + REWRITE_TAC[DISJOINT] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC HAS_REAL_MEASURE_REAL_NEGLIGIBLE_UNIONS THEN + ASM_SIMP_TAC[REAL_NEGLIGIBLE_EMPTY]);; + +let REAL_MEASURE_DISJOINT_UNIONS = prove + (`!m f:(real->bool)->bool. + FINITE f /\ + (!s. s IN f ==> s has_real_measure (m s)) /\ + (!s t. s IN f /\ t IN f /\ ~(s = t) ==> DISJOINT s t) + ==> real_measure(UNIONS f) = sum f m`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_MEASURE_UNIQUE THEN + ASM_SIMP_TAC[HAS_REAL_MEASURE_DISJOINT_UNIONS]);; + +let HAS_REAL_MEASURE_REAL_NEGLIGIBLE_UNIONS_IMAGE = prove + (`!f:A->(real->bool) s. + FINITE s /\ + (!x. x IN s ==> real_measurable(f x)) /\ + (!x y. x IN s /\ y IN s /\ ~(x = y) + ==> real_negligible((f x) INTER (f y))) + ==> (UNIONS (IMAGE f s)) has_real_measure + (sum s (\x. real_measure(f x)))`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN + `sum s (\x. real_measure(f x)) = + sum (IMAGE (f:A->real->bool) s) real_measure` + SUBST1_TAC THENL + [CONV_TAC SYM_CONV THEN ONCE_REWRITE_TAC[GSYM o_DEF] THEN + MATCH_MP_TAC SUM_IMAGE_NONZERO THEN ASM_REWRITE_TAC[] THEN + MAP_EVERY X_GEN_TAC [`x:A`; `y:A`] THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`x:A`; `y:A`]) THEN + ASM_SIMP_TAC[INTER_ACI; REAL_MEASURABLE_REAL_MEASURE_EQ_0]; + MATCH_MP_TAC HAS_REAL_MEASURE_REAL_NEGLIGIBLE_UNIONS THEN + ASM_SIMP_TAC[RIGHT_FORALL_IMP_THM; IMP_CONJ; FORALL_IN_IMAGE] THEN + ASM_MESON_TAC[FINITE_IMAGE; HAS_REAL_MEASURE_MEASURE]]);; + +let REAL_MEASURE_REAL_NEGLIGIBLE_UNIONS_IMAGE = prove + (`!f:A->real->bool s. + FINITE s /\ + (!x. x IN s ==> real_measurable(f x)) /\ + (!x y. x IN s /\ y IN s /\ ~(x = y) + ==> real_negligible((f x) INTER (f y))) + ==> real_measure(UNIONS (IMAGE f s)) = sum s (\x. real_measure(f x))`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_MEASURE_UNIQUE THEN + ASM_SIMP_TAC[HAS_REAL_MEASURE_REAL_NEGLIGIBLE_UNIONS_IMAGE]);; + +let HAS_REAL_MEASURE_DISJOINT_UNIONS_IMAGE = prove + (`!f:A->real->bool s. + FINITE s /\ + (!x. x IN s ==> real_measurable(f x)) /\ + (!x y. x IN s /\ y IN s /\ ~(x = y) ==> DISJOINT (f x) (f y)) + ==> (UNIONS (IMAGE f s)) has_real_measure + (sum s (\x. real_measure(f x)))`, + REWRITE_TAC[DISJOINT] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC HAS_REAL_MEASURE_REAL_NEGLIGIBLE_UNIONS_IMAGE THEN + ASM_SIMP_TAC[REAL_NEGLIGIBLE_EMPTY]);; + +let REAL_MEASURE_DISJOINT_UNIONS_IMAGE = prove + (`!f:A->real->bool s. + FINITE s /\ + (!x. x IN s ==> real_measurable(f x)) /\ + (!x y. x IN s /\ y IN s /\ ~(x = y) ==> DISJOINT (f x) (f y)) + ==> real_measure(UNIONS (IMAGE f s)) = sum s (\x. real_measure(f x))`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_MEASURE_UNIQUE THEN + ASM_SIMP_TAC[HAS_REAL_MEASURE_DISJOINT_UNIONS_IMAGE]);; + +let HAS_REAL_MEASURE_REAL_NEGLIGIBLE_UNIONS_IMAGE_STRONG = prove + (`!f:A->real->bool s. + FINITE {x | x IN s /\ ~(f x = {})} /\ + (!x. x IN s ==> real_measurable(f x)) /\ + (!x y. x IN s /\ y IN s /\ ~(x = y) + ==> real_negligible((f x) INTER (f y))) + ==> (UNIONS (IMAGE f s)) has_real_measure + (sum s (\x. real_measure(f x)))`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`f:A->real->bool`; + `{x | x IN s /\ ~((f:A->real->bool) x = {})}`] + HAS_REAL_MEASURE_REAL_NEGLIGIBLE_UNIONS_IMAGE) THEN + ASM_SIMP_TAC[IN_ELIM_THM; FINITE_RESTRICT] THEN + MATCH_MP_TAC EQ_IMP THEN BINOP_TAC THENL + [GEN_REWRITE_TAC I [EXTENSION] THEN + REWRITE_TAC[IN_UNIONS; IN_IMAGE; IN_ELIM_THM] THEN + MESON_TAC[NOT_IN_EMPTY]; + CONV_TAC SYM_CONV THEN MATCH_MP_TAC SUM_SUPERSET THEN + SIMP_TAC[SUBSET; IN_ELIM_THM; TAUT `a /\ ~(a /\ b) <=> a /\ ~b`] THEN + REWRITE_TAC[REAL_MEASURE_EMPTY]]);; + +let REAL_MEASURE_REAL_NEGLIGIBLE_UNIONS_IMAGE_STRONG = prove + (`!f:A->real->bool s. + FINITE {x | x IN s /\ ~(f x = {})} /\ + (!x. x IN s ==> real_measurable(f x)) /\ + (!x y. x IN s /\ y IN s /\ ~(x = y) + ==> real_negligible((f x) INTER (f y))) + ==> real_measure(UNIONS (IMAGE f s)) = sum s (\x. real_measure(f x))`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_MEASURE_UNIQUE THEN + ASM_SIMP_TAC[HAS_REAL_MEASURE_REAL_NEGLIGIBLE_UNIONS_IMAGE_STRONG]);; + +let HAS_REAL_MEASURE_DISJOINT_UNIONS_IMAGE_STRONG = prove + (`!f:A->real->bool s. + FINITE {x | x IN s /\ ~(f x = {})} /\ + (!x. x IN s ==> real_measurable(f x)) /\ + (!x y. x IN s /\ y IN s /\ ~(x = y) ==> DISJOINT (f x) (f y)) + ==> (UNIONS (IMAGE f s)) has_real_measure + (sum s (\x. real_measure(f x)))`, + REWRITE_TAC[DISJOINT] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC HAS_REAL_MEASURE_REAL_NEGLIGIBLE_UNIONS_IMAGE_STRONG THEN + ASM_SIMP_TAC[REAL_NEGLIGIBLE_EMPTY]);; + +let REAL_MEASURE_DISJOINT_UNIONS_IMAGE_STRONG = prove + (`!f:A->real->bool s. + FINITE {x | x IN s /\ ~(f x = {})} /\ + (!x. x IN s ==> real_measurable(f x)) /\ + (!x y. x IN s /\ y IN s /\ ~(x = y) ==> DISJOINT (f x) (f y)) + ==> real_measure(UNIONS (IMAGE f s)) = sum s (\x. real_measure(f x))`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_MEASURE_UNIQUE THEN + ASM_SIMP_TAC[HAS_REAL_MEASURE_DISJOINT_UNIONS_IMAGE_STRONG]);; + +let REAL_MEASURE_UNION = prove + (`!s t. real_measurable s /\ real_measurable t + ==> real_measure(s UNION t) = + real_measure(s) + real_measure(t) - real_measure(s INTER t)`, + REPEAT STRIP_TAC THEN + ONCE_REWRITE_TAC[SET_RULE + `s UNION t = (s INTER t) UNION (s DIFF t) UNION (t DIFF s)`] THEN + ONCE_REWRITE_TAC[REAL_ARITH `a + b - c:real = c + (a - c) + (b - c)`] THEN + MP_TAC(ISPECL [`s DIFF t:real->bool`; `t DIFF s:real->bool`] + REAL_MEASURE_DISJOINT_UNION) THEN + ASM_SIMP_TAC[REAL_MEASURABLE_DIFF] THEN + ANTS_TAC THENL [SET_TAC[]; ALL_TAC] THEN + MP_TAC(ISPECL [`s INTER t:real->bool`; + `(s DIFF t) UNION (t DIFF s):real->bool`] + REAL_MEASURE_DISJOINT_UNION) THEN + ASM_SIMP_TAC[REAL_MEASURABLE_DIFF; + REAL_MEASURABLE_UNION; REAL_MEASURABLE_INTER] THEN + ANTS_TAC THENL [SET_TAC[]; ALL_TAC] THEN + REPEAT(DISCH_THEN SUBST1_TAC) THEN AP_TERM_TAC THEN BINOP_TAC THEN + REWRITE_TAC[REAL_EQ_SUB_LADD] THEN MATCH_MP_TAC EQ_TRANS THENL + [EXISTS_TAC `real_measure((s DIFF t) UNION (s INTER t):real->bool)`; + EXISTS_TAC `real_measure((t DIFF s) UNION (s INTER t):real->bool)`] THEN + (CONJ_TAC THENL + [CONV_TAC SYM_CONV THEN MATCH_MP_TAC REAL_MEASURE_DISJOINT_UNION THEN + ASM_SIMP_TAC[REAL_MEASURABLE_DIFF; REAL_MEASURABLE_INTER]; + AP_TERM_TAC] THEN + SET_TAC[]));; + +let REAL_MEASURE_UNION_LE = prove + (`!s t. real_measurable s /\ real_measurable t + ==> real_measure(s UNION t) <= real_measure s + real_measure t`, + REPEAT STRIP_TAC THEN ASM_SIMP_TAC[REAL_MEASURE_UNION] THEN + REWRITE_TAC[REAL_ARITH `a + b - c <= a + b <=> &0 <= c`] THEN + MATCH_MP_TAC REAL_MEASURE_POS_LE THEN ASM_SIMP_TAC[REAL_MEASURABLE_INTER]);; + +let REAL_MEASURE_UNIONS_LE = prove + (`!f. FINITE f /\ (!s. s IN f ==> real_measurable s) + ==> real_measure(UNIONS f) <= sum f (\s. real_measure s)`, + REWRITE_TAC[IMP_CONJ] THEN + MATCH_MP_TAC FINITE_INDUCT_STRONG THEN + SIMP_TAC[UNIONS_0; UNIONS_INSERT; SUM_CLAUSES] THEN + REWRITE_TAC[REAL_MEASURE_EMPTY; REAL_LE_REFL] THEN + MAP_EVERY X_GEN_TAC [`s:real->bool`; `f:(real->bool)->bool`] THEN + REWRITE_TAC[IN_INSERT] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `real_measure(s) + real_measure(UNIONS f)` THEN + ASM_SIMP_TAC[REAL_MEASURE_UNION_LE; REAL_MEASURABLE_UNIONS] THEN + REWRITE_TAC[REAL_LE_LADD] THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_SIMP_TAC[]);; + +let REAL_MEASURE_UNIONS_LE_IMAGE = prove + (`!f:A->bool s:A->(real->bool). + FINITE f /\ (!a. a IN f ==> real_measurable(s a)) + ==> real_measure(UNIONS (IMAGE s f)) <= sum f (\a. real_measure(s a))`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `sum (IMAGE s (f:A->bool)) (\k:real->bool. real_measure k)` THEN + ASM_SIMP_TAC[REAL_MEASURE_UNIONS_LE; FORALL_IN_IMAGE; FINITE_IMAGE] THEN + GEN_REWRITE_TAC (RAND_CONV o RAND_CONV) [GSYM o_DEF] THEN + REWRITE_TAC[ETA_AX] THEN MATCH_MP_TAC SUM_IMAGE_LE THEN + ASM_SIMP_TAC[REAL_MEASURE_POS_LE]);; + +let REAL_NEGLIGIBLE_OUTER = prove + (`!s. real_negligible s <=> + !e. &0 < e + ==> ?t. s SUBSET t /\ real_measurable t /\ real_measure t < e`, + REWRITE_TAC[real_negligible; REAL_MEASURABLE_MEASURABLE; + REAL_MEASURE_MEASURE; SUBSET_LIFT_IMAGE; + NEGLIGIBLE_OUTER; EXISTS_LIFT_IMAGE]);; + +let REAL_NEGLIGIBLE_OUTER_LE = prove + (`!s. real_negligible s <=> + !e. &0 < e + ==> ?t. s SUBSET t /\ real_measurable t /\ real_measure t <= e`, + REWRITE_TAC[real_negligible; REAL_MEASURABLE_MEASURABLE; + REAL_MEASURE_MEASURE; SUBSET_LIFT_IMAGE; + NEGLIGIBLE_OUTER_LE; EXISTS_LIFT_IMAGE]);; + +let REAL_MEASURABLE_INNER_OUTER = prove + (`!s. real_measurable s <=> + !e. &0 < e + ==> ?t u. t SUBSET s /\ s SUBSET u /\ + real_measurable t /\ real_measurable u /\ + abs(real_measure t - real_measure u) < e`, + GEN_TAC THEN EQ_TAC THEN DISCH_TAC THENL + [GEN_TAC THEN DISCH_TAC THEN REPEAT(EXISTS_TAC `s:real->bool`) THEN + ASM_REWRITE_TAC[SUBSET_REFL; REAL_SUB_REFL; REAL_ABS_NUM]; + ALL_TAC] THEN + REWRITE_TAC[REAL_MEASURABLE_REAL_INTEGRABLE] THEN + MATCH_MP_TAC REAL_INTEGRABLE_STRADDLE THEN + X_GEN_TAC `e:real` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `e:real`) THEN + ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`t:real->bool`; `u:real->bool`] THEN STRIP_TAC THEN + MAP_EVERY EXISTS_TAC + [`(\x. if x IN t then &1 else &0):real->real`; + `(\x. if x IN u then &1 else &0):real->real`; + `real_measure(t:real->bool)`; + `real_measure(u:real->bool)`] THEN + ASM_REWRITE_TAC[GSYM HAS_REAL_MEASURE; GSYM HAS_REAL_MEASURE_MEASURE] THEN + ASM_REWRITE_TAC[GSYM LIFT_SUB; NORM_LIFT] THEN REPEAT STRIP_TAC THEN + REPEAT(COND_CASES_TAC THEN + ASM_REWRITE_TAC[DROP_VEC; REAL_POS; REAL_LE_REFL]) THEN + ASM SET_TAC[]);; + +let HAS_REAL_MEASURE_INNER_OUTER = prove + (`!s m. s has_real_measure m <=> + (!e. &0 < e ==> ?t. t SUBSET s /\ real_measurable t /\ + m - e < real_measure t) /\ + (!e. &0 < e ==> ?u. s SUBSET u /\ real_measurable u /\ + real_measure u < m + e)`, + REPEAT GEN_TAC THEN + GEN_REWRITE_TAC LAND_CONV + [HAS_REAL_MEASURE_REAL_MEASURABLE_REAL_MEASURE] THEN EQ_TAC THENL + [REPEAT STRIP_TAC THEN EXISTS_TAC `s:real->bool` THEN + ASM_REWRITE_TAC[SUBSET_REFL] THEN ASM_REAL_ARITH_TAC; + ALL_TAC] THEN + DISCH_THEN(CONJUNCTS_THEN2 (LABEL_TAC "t") (LABEL_TAC "u")) THEN + MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN CONJ_TAC THENL + [GEN_REWRITE_TAC I [REAL_MEASURABLE_INNER_OUTER] THEN + X_GEN_TAC `e:real` THEN DISCH_TAC THEN + REMOVE_THEN "u" (MP_TAC o SPEC `e / &2`) THEN + REMOVE_THEN "t" (MP_TAC o SPEC `e / &2`) THEN + ASM_SIMP_TAC[REAL_LT_DIV; REAL_OF_NUM_LT; ARITH] THEN + REWRITE_TAC[IMP_IMP; LEFT_AND_EXISTS_THM] THEN + REWRITE_TAC[RIGHT_AND_EXISTS_THM] THEN + REPEAT(MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC) THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN MATCH_MP_TAC(REAL_ARITH + `&0 < e /\ t <= u /\ m - e / &2 < t /\ u < m + e / &2 + ==> abs(t - u) < e`) THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC REAL_MEASURE_SUBSET THEN + ASM_REWRITE_TAC[] THEN ASM SET_TAC[]; + DISCH_TAC THEN MATCH_MP_TAC(REAL_ARITH + `~(&0 < x - y) /\ ~(&0 < y - x) ==> x = y`) THEN + CONJ_TAC THEN DISCH_TAC THENL + [REMOVE_THEN "u" (MP_TAC o SPEC `real_measure(s:real->bool) - m`) THEN + ASM_REWRITE_TAC[REAL_SUB_ADD2; GSYM REAL_NOT_LE]; + REMOVE_THEN "t" (MP_TAC o SPEC `m - real_measure(s:real->bool)`) THEN + ASM_REWRITE_TAC[REAL_SUB_SUB2; GSYM REAL_NOT_LE]] THEN + ASM_MESON_TAC[REAL_MEASURE_SUBSET]]);; + +let HAS_REAL_MEASURE_INNER_OUTER_LE = prove + (`!s:real->bool m. + s has_real_measure m <=> + (!e. &0 < e ==> ?t. t SUBSET s /\ real_measurable t /\ + m - e <= real_measure t) /\ + (!e. &0 < e ==> ?u. s SUBSET u /\ real_measurable u /\ + real_measure u <= m + e)`, + REWRITE_TAC[HAS_REAL_MEASURE_INNER_OUTER] THEN + MESON_TAC[REAL_ARITH `&0 < e /\ m - e / &2 <= t ==> m - e < t`; + REAL_ARITH `&0 < e /\ u <= m + e / &2 ==> u < m + e`; + REAL_ARITH `&0 < e <=> &0 < e / &2`; REAL_LT_IMP_LE]);; + +let HAS_REAL_MEASURE_AFFINITY = prove + (`!s m c y. s has_real_measure y + ==> (IMAGE (\x. m * x + c) s) has_real_measure abs(m) * y`, + REPEAT GEN_TAC THEN REWRITE_TAC[HAS_REAL_MEASURE_HAS_MEASURE] THEN + DISCH_THEN(MP_TAC o SPECL [`m:real`; `lift c`] o MATCH_MP + HAS_MEASURE_AFFINITY) THEN + REWRITE_TAC[DIMINDEX_1; REAL_POW_1; GSYM IMAGE_o] THEN + MATCH_MP_TAC EQ_IMP THEN REPEAT(AP_THM_TAC THEN AP_TERM_TAC) THEN + SIMP_TAC[FUN_EQ_THM; FORALL_DROP; o_THM; LIFT_DROP; LIFT_ADD; LIFT_CMUL]);; + +let HAS_REAL_MEASURE_SCALING = prove + (`!s m y. s has_real_measure y + ==> (IMAGE (\x. m * x) s) has_real_measure abs(m) * y`, + ONCE_REWRITE_TAC[REAL_ARITH `m * x = m * x + &0`] THEN + REWRITE_TAC[REAL_ARITH `abs m * x + &0 = abs m * x`] THEN + REWRITE_TAC[HAS_REAL_MEASURE_AFFINITY]);; + +let HAS_REAL_MEASURE_TRANSLATION = prove + (`!s m a. s has_real_measure m ==> (IMAGE (\x. a + x) s) has_real_measure m`, + REPEAT GEN_TAC THEN + ONCE_REWRITE_TAC[REAL_ARITH `a + x = &1 * x + a`] THEN + GEN_REWRITE_TAC (RAND_CONV o RAND_CONV) [REAL_ARITH `m = abs(&1) * m`] THEN + REWRITE_TAC[HAS_REAL_MEASURE_AFFINITY]);; + +let REAL_NEGLIGIBLE_TRANSLATION = prove + (`!s a. real_negligible s ==> real_negligible (IMAGE (\x. a + x) s)`, + SIMP_TAC[GSYM HAS_REAL_MEASURE_0; HAS_REAL_MEASURE_TRANSLATION]);; + +let HAS_REAL_MEASURE_TRANSLATION_EQ = prove + (`!s m. (IMAGE (\x. a + x) s) has_real_measure m <=> s has_real_measure m`, + REPEAT GEN_TAC THEN EQ_TAC THEN + REWRITE_TAC[HAS_REAL_MEASURE_TRANSLATION] THEN + DISCH_THEN(MP_TAC o SPEC `--a:real` o + MATCH_MP HAS_REAL_MEASURE_TRANSLATION) THEN + MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_TERM_TAC THEN + REWRITE_TAC[GSYM IMAGE_o; o_DEF; REAL_ARITH `--a + a + b:real = b`] THEN + SET_TAC[]);; + +let REAL_NEGLIGIBLE_TRANSLATION_REV = prove + (`!s a. real_negligible (IMAGE (\x. a + x) s) ==> real_negligible s`, + SIMP_TAC[GSYM HAS_REAL_MEASURE_0; HAS_REAL_MEASURE_TRANSLATION_EQ]);; + +let REAL_NEGLIGIBLE_TRANSLATION_EQ = prove + (`!s a. real_negligible (IMAGE (\x. a + x) s) <=> real_negligible s`, + SIMP_TAC[GSYM HAS_REAL_MEASURE_0; HAS_REAL_MEASURE_TRANSLATION_EQ]);; + +let REAL_MEASURABLE_TRANSLATION = prove + (`!s. real_measurable (IMAGE (\x. a + x) s) <=> real_measurable s`, + REWRITE_TAC[real_measurable; HAS_REAL_MEASURE_TRANSLATION_EQ]);; + +let REAL_MEASURE_TRANSLATION = prove + (`!s. real_measurable s + ==> real_measure(IMAGE (\x. a + x) s) = real_measure s`, + REWRITE_TAC[HAS_REAL_MEASURE_MEASURE] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC REAL_MEASURE_UNIQUE THEN + ASM_REWRITE_TAC[HAS_REAL_MEASURE_TRANSLATION_EQ]);; + +let HAS_REAL_MEASURE_SCALING_EQ = prove + (`!s m c. ~(c = &0) + ==> ((IMAGE (\x. c * x) s) has_real_measure (abs(c) * m) <=> + s has_real_measure m)`, + REPEAT STRIP_TAC THEN EQ_TAC THEN REWRITE_TAC[HAS_REAL_MEASURE_SCALING] THEN + DISCH_THEN(MP_TAC o SPEC `inv(c:real)` o + MATCH_MP HAS_REAL_MEASURE_SCALING) THEN + REWRITE_TAC[GSYM IMAGE_o; o_DEF; GSYM REAL_ABS_MUL] THEN + REWRITE_TAC[GSYM REAL_POW_MUL; REAL_MUL_ASSOC] THEN + ASM_SIMP_TAC[GSYM REAL_ABS_MUL; REAL_MUL_LINV] THEN + REWRITE_TAC[REAL_POW_ONE; REAL_ABS_NUM; REAL_MUL_LID] THEN + MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_TERM_TAC THEN SET_TAC[]);; + +let REAL_MEASURABLE_SCALING = prove + (`!s c. real_measurable s ==> real_measurable (IMAGE (\x. c * x) s)`, + REWRITE_TAC[real_measurable] THEN MESON_TAC[HAS_REAL_MEASURE_SCALING]);; + +let REAL_MEASURABLE_SCALING_EQ = prove + (`!s c. ~(c = &0) + ==> (real_measurable (IMAGE (\x. c * x) s) <=> real_measurable s)`, + REPEAT STRIP_TAC THEN EQ_TAC THEN REWRITE_TAC[REAL_MEASURABLE_SCALING] THEN + DISCH_THEN(MP_TAC o SPEC `inv c:real` o MATCH_MP REAL_MEASURABLE_SCALING) THEN + REWRITE_TAC[GSYM IMAGE_o; o_DEF; GSYM REAL_ABS_MUL] THEN + MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN + ASM_SIMP_TAC[REAL_MUL_ASSOC; REAL_MUL_LINV; REAL_MUL_LID] THEN + SET_TAC[]);; + +let REAL_MEASURE_SCALING = prove + (`!s. real_measurable s + ==> real_measure(IMAGE (\x. c * x) s) = abs(c) * real_measure s`, + REWRITE_TAC[HAS_REAL_MEASURE_MEASURE] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC REAL_MEASURE_UNIQUE THEN + ASM_SIMP_TAC[HAS_REAL_MEASURE_SCALING]);; + +let HAS_REAL_MEASURE_NESTED_UNIONS = prove + (`!s B. (!n. real_measurable(s n)) /\ + (!n. real_measure(s n) <= B) /\ + (!n. s(n) SUBSET s(SUC n)) + ==> real_measurable(UNIONS { s(n) | n IN (:num) }) /\ + ((\n. real_measure(s n)) + ---> real_measure(UNIONS { s(n) | n IN (:num) })) + sequentially`, + REPEAT GEN_TAC THEN REWRITE_TAC[TENDSTO_REAL; o_DEF] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + ASM_SIMP_TAC[REAL_MEASURE_MEASURE] THEN POP_ASSUM MP_TAC THEN + REWRITE_TAC[REAL_MEASURABLE_MEASURABLE] THEN + REPEAT(DISCH_THEN(REPEAT_TCL CONJUNCTS_THEN ASSUME_TAC)) THEN + MP_TAC(ISPECL [`IMAGE lift o (s:num->real->bool)`; `B:real`] + HAS_MEASURE_NESTED_UNIONS) THEN + ASM_SIMP_TAC[o_THM; IMAGE_SUBSET] THEN + REWRITE_TAC[SET_RULE `{IMAGE f (s n) | P n} = IMAGE (IMAGE f) {s n | P n}`; + GSYM IMAGE_UNIONS] THEN + SIMP_TAC[REAL_MEASURE_MEASURE; REAL_MEASURABLE_MEASURABLE]);; + +let REAL_MEASURABLE_NESTED_UNIONS = prove + (`!s B. (!n. real_measurable(s n)) /\ + (!n. real_measure(s n) <= B) /\ + (!n. s(n) SUBSET s(SUC n)) + ==> real_measurable(UNIONS { s(n) | n IN (:num) })`, + REPEAT GEN_TAC THEN + DISCH_THEN(MP_TAC o MATCH_MP HAS_REAL_MEASURE_NESTED_UNIONS) THEN + SIMP_TAC[]);; + +let HAS_REAL_MEASURE_COUNTABLE_REAL_NEGLIGIBLE_UNIONS = prove + (`!s:num->real->bool B. + (!n. real_measurable(s n)) /\ + (!m n. ~(m = n) ==> real_negligible(s m INTER s n)) /\ + (!n. sum (0..n) (\k. real_measure(s k)) <= B) + ==> real_measurable(UNIONS { s(n) | n IN (:num) }) /\ + ((\n. real_measure(s n)) real_sums + real_measure(UNIONS { s(n) | n IN (:num) })) (from 0)`, + REPEAT GEN_TAC THEN STRIP_TAC THEN + MP_TAC(ISPECL [`\n. UNIONS (IMAGE s (0..n)):real->bool`; `B:real`] + HAS_REAL_MEASURE_NESTED_UNIONS) THEN + REWRITE_TAC[real_sums; FROM_0; INTER_UNIV] THEN + SUBGOAL_THEN + `!n. (UNIONS (IMAGE s (0..n)):real->bool) has_real_measure + (sum(0..n) (\k. real_measure(s k)))` + MP_TAC THENL + [GEN_TAC THEN MATCH_MP_TAC HAS_REAL_MEASURE_REAL_NEGLIGIBLE_UNIONS_IMAGE THEN + ASM_SIMP_TAC[FINITE_NUMSEG]; + ALL_TAC] THEN + DISCH_THEN(fun th -> ASSUME_TAC th THEN + ASSUME_TAC(GEN `n:num` (MATCH_MP REAL_MEASURE_UNIQUE + (SPEC `n:num` th)))) THEN + ASM_REWRITE_TAC[] THEN ANTS_TAC THENL + [CONJ_TAC THENL [ASM_MESON_TAC[real_measurable]; ALL_TAC] THEN + GEN_TAC THEN MATCH_MP_TAC SUBSET_UNIONS THEN + MATCH_MP_TAC IMAGE_SUBSET THEN + REWRITE_TAC[SUBSET; IN_NUMSEG] THEN ARITH_TAC; + ALL_TAC] THEN + SIMP_TAC[LIFT_SUM; FINITE_NUMSEG; o_DEF] THEN + SUBGOAL_THEN + `UNIONS {UNIONS (IMAGE s (0..n)) | n IN (:num)}:real->bool = + UNIONS (IMAGE s (:num))` + (fun th -> REWRITE_TAC[th] THEN ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN + REWRITE_TAC[]) THEN + GEN_REWRITE_TAC I [EXTENSION] THEN X_GEN_TAC `x:real` THEN + REWRITE_TAC[IN_UNIONS] THEN ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN + REWRITE_TAC[EXISTS_IN_IMAGE; EXISTS_IN_UNIONS; IN_UNIV] THEN + REWRITE_TAC[IN_UNIONS; EXISTS_IN_IMAGE] THEN + REWRITE_TAC[IN_NUMSEG; LE_0] THEN MESON_TAC[LE_REFL]);; + +let REAL_NEGLIGIBLE_COUNTABLE_UNIONS = prove + (`!s:num->real->bool. + (!n. real_negligible(s n)) + ==> real_negligible(UNIONS {s(n) | n IN (:num)})`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`s:num->real->bool`; `&0`] + HAS_REAL_MEASURE_COUNTABLE_REAL_NEGLIGIBLE_UNIONS) THEN + ASM_SIMP_TAC[REAL_MEASURE_EQ_0; SUM_0; REAL_LE_REFL; LIFT_NUM] THEN + ANTS_TAC THENL + [ASM_MESON_TAC[HAS_REAL_MEASURE_0; real_measurable; INTER_SUBSET; + REAL_NEGLIGIBLE_SUBSET]; + ALL_TAC] THEN + SIMP_TAC[GSYM REAL_MEASURABLE_REAL_MEASURE_EQ_0] THEN + STRIP_TAC THEN + MATCH_MP_TAC REAL_SERIES_UNIQUE THEN REWRITE_TAC[LIFT_NUM] THEN + MAP_EVERY EXISTS_TAC [`(\k. &0):num->real`; `from 0`] THEN + ASM_REWRITE_TAC[REAL_SERIES_0]);; + +let REAL_MEASURABLE_COUNTABLE_UNIONS_STRONG = prove + (`!s:num->real->bool B. + (!n. real_measurable(s n)) /\ + (!n. real_measure(UNIONS {s k | k <= n}) <= B) + ==> real_measurable(UNIONS { s(n) | n IN (:num) })`, + REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN STRIP_TAC THEN + MP_TAC(ISPECL [`\n. UNIONS (IMAGE s (0..n)):real->bool`; `B:real`] + REAL_MEASURABLE_NESTED_UNIONS) THEN + SUBGOAL_THEN + `UNIONS {UNIONS (IMAGE s (0..n)) | n IN (:num)}:real->bool = + UNIONS (IMAGE s (:num))` + (fun th -> REWRITE_TAC[th]) + THENL + [GEN_REWRITE_TAC I [EXTENSION] THEN X_GEN_TAC `x:real` THEN + REWRITE_TAC[IN_UNIONS] THEN ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN + REWRITE_TAC[EXISTS_IN_IMAGE; EXISTS_IN_UNIONS; IN_UNIV] THEN + REWRITE_TAC[IN_UNIONS; EXISTS_IN_IMAGE] THEN + REWRITE_TAC[IN_NUMSEG; LE_0] THEN MESON_TAC[LE_REFL]; + ALL_TAC] THEN + DISCH_THEN MATCH_MP_TAC THEN ASM_REWRITE_TAC[] THEN REPEAT CONJ_TAC THENL + [GEN_TAC THEN MATCH_MP_TAC REAL_MEASURABLE_UNIONS THEN + ASM_SIMP_TAC[FINITE_IMAGE; FORALL_IN_IMAGE; FINITE_NUMSEG]; + ONCE_REWRITE_TAC[GSYM SIMPLE_IMAGE] THEN + ASM_REWRITE_TAC[IN_NUMSEG; LE_0]; + GEN_TAC THEN MATCH_MP_TAC SUBSET_UNIONS THEN + MATCH_MP_TAC IMAGE_SUBSET THEN + REWRITE_TAC[SUBSET; IN_NUMSEG; LE_0] THEN ARITH_TAC]);; + +let HAS_REAL_MEASURE_COUNTABLE_REAL_NEGLIGIBLE_UNIONS_BOUNDED = prove + (`!s. (!n. real_measurable(s n)) /\ + (!m n. ~(m = n) ==> real_negligible(s m INTER s n)) /\ + real_bounded(UNIONS { s(n) | n IN (:num) }) + ==> real_measurable(UNIONS { s(n) | n IN (:num) }) /\ + ((\n. real_measure(s n)) real_sums + real_measure(UNIONS { s(n) | n IN (:num) })) (from 0)`, + REPEAT GEN_TAC THEN REWRITE_TAC[TENDSTO_REAL; o_DEF] THEN + REWRITE_TAC[REAL_BOUNDED] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + ASM_SIMP_TAC[REAL_MEASURE_MEASURE] THEN POP_ASSUM MP_TAC THEN + REWRITE_TAC[REAL_MEASURABLE_MEASURABLE; real_negligible] THEN + REPEAT(DISCH_THEN(REPEAT_TCL CONJUNCTS_THEN ASSUME_TAC)) THEN + MP_TAC(ISPEC `IMAGE lift o (s:num->real->bool)` + HAS_MEASURE_COUNTABLE_NEGLIGIBLE_UNIONS_BOUNDED) THEN + ASM_SIMP_TAC[o_THM; IMAGE_SUBSET] THEN + REWRITE_TAC[SET_RULE `{IMAGE f (s n) | P n} = IMAGE (IMAGE f) {s n | P n}`; + GSYM IMAGE_UNIONS] THEN + ASM_SIMP_TAC[GSYM IMAGE_INTER_INJ; LIFT_EQ] THEN + SIMP_TAC[REAL_SUMS; o_DEF; REAL_MEASURE_MEASURE; + REAL_MEASURABLE_MEASURABLE]);; + +let REAL_MEASURABLE_COUNTABLE_UNIONS = prove + (`!s B. (!n. real_measurable(s n)) /\ + (!n. sum (0..n) (\k. real_measure(s k)) <= B) + ==> real_measurable(UNIONS { s(n) | n IN (:num) })`, + REPEAT STRIP_TAC THEN + MATCH_MP_TAC REAL_MEASURABLE_COUNTABLE_UNIONS_STRONG THEN + EXISTS_TAC `B:real` THEN ASM_REWRITE_TAC[] THEN + X_GEN_TAC `n:num` THEN MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `sum(0..n) (\k. real_measure(s k:real->bool))` THEN + ASM_REWRITE_TAC[] THEN + W(MP_TAC o PART_MATCH (rand o rand) REAL_MEASURE_UNIONS_LE_IMAGE o + rand o snd) THEN + ASM_REWRITE_TAC[FINITE_NUMSEG] THEN + ONCE_REWRITE_TAC[GSYM SIMPLE_IMAGE] THEN + REWRITE_TAC[IN_NUMSEG; LE_0]);; + +let REAL_MEASURABLE_COUNTABLE_UNIONS_BOUNDED = prove + (`!s. (!n. real_measurable(s n)) /\ + real_bounded(UNIONS { s(n) | n IN (:num) }) + ==> real_measurable(UNIONS { s(n) | n IN (:num) })`, + REWRITE_TAC[REAL_MEASURABLE_MEASURABLE; REAL_BOUNDED] THEN + SIMP_TAC[IMAGE_INTER_INJ; LIFT_EQ; IMAGE_UNIONS] THEN + REWRITE_TAC[SET_RULE `IMAGE f {g x | x IN s} = {f(g x) | x IN s}`] THEN + REWRITE_TAC[MEASURABLE_COUNTABLE_UNIONS_BOUNDED]);; + +let REAL_MEASURABLE_COUNTABLE_INTERS = prove + (`!s. (!n. real_measurable(s n)) + ==> real_measurable(INTERS { s(n) | n IN (:num) })`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN `INTERS { s(n):real->bool | n IN (:num) } = + s 0 DIFF (UNIONS {s 0 DIFF s n | n IN (:num)})` + SUBST1_TAC THENL + [GEN_REWRITE_TAC I [EXTENSION] THEN + REWRITE_TAC[IN_INTERS; IN_DIFF; IN_UNIONS] THEN + REWRITE_TAC[SIMPLE_IMAGE; FORALL_IN_IMAGE; EXISTS_IN_IMAGE] THEN + ASM SET_TAC[]; + ALL_TAC] THEN + MATCH_MP_TAC REAL_MEASURABLE_DIFF THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC REAL_MEASURABLE_COUNTABLE_UNIONS_STRONG THEN + EXISTS_TAC `real_measure(s 0:real->bool)` THEN + ASM_SIMP_TAC[REAL_MEASURABLE_DIFF; LE_0] THEN + GEN_TAC THEN MATCH_MP_TAC REAL_MEASURE_SUBSET THEN + ASM_REWRITE_TAC[] THEN CONJ_TAC THENL + [ALL_TAC; + REWRITE_TAC[SUBSET; FORALL_IN_UNIONS; IN_ELIM_THM; IN_DIFF] THEN + MESON_TAC[IN_DIFF]] THEN + ONCE_REWRITE_TAC[GSYM IN_NUMSEG_0] THEN + ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN + ASM_SIMP_TAC[FORALL_IN_IMAGE; FINITE_IMAGE; FINITE_NUMSEG; + REAL_MEASURABLE_DIFF; REAL_MEASURABLE_UNIONS]);; + +let REAL_NEGLIGIBLE_COUNTABLE = prove + (`!s. COUNTABLE s ==> real_negligible s`, + REPEAT STRIP_TAC THEN REWRITE_TAC[real_negligible] THEN + MATCH_MP_TAC NEGLIGIBLE_COUNTABLE THEN ASM_SIMP_TAC[COUNTABLE_IMAGE]);; + +let REAL_MEASURABLE_COMPACT = prove + (`!s. real_compact s ==> real_measurable s`, + REWRITE_TAC[REAL_MEASURABLE_MEASURABLE; real_compact; MEASURABLE_COMPACT]);; + +let REAL_MEASURABLE_OPEN = prove + (`!s. real_bounded s /\ real_open s ==> real_measurable s`, + REWRITE_TAC[REAL_MEASURABLE_MEASURABLE; REAL_OPEN; REAL_BOUNDED; + MEASURABLE_OPEN]);; + +let HAS_REAL_INTEGRAL_NEGLIGIBLE_EQ = prove + (`!f s. (!x. x IN s ==> &0 <= f(x)) + ==> ((f has_real_integral &0) s <=> + real_negligible {x | x IN s /\ ~(f x = &0)})`, + REPEAT STRIP_TAC THEN EQ_TAC THEN DISCH_TAC THENL + [ALL_TAC; + MATCH_MP_TAC HAS_REAL_INTEGRAL_NEGLIGIBLE THEN + EXISTS_TAC `{x | x IN s /\ ~((f:real->real) x = &0)}` THEN + ASM_REWRITE_TAC[IN_DIFF; IN_ELIM_THM] THEN MESON_TAC[]] THEN + MATCH_MP_TAC REAL_NEGLIGIBLE_SUBSET THEN EXISTS_TAC + `UNIONS {{x:real | x IN s /\ abs(f x) >= &1 / (&n + &1)} | + n IN (:num)}` THEN + CONJ_TAC THENL + [MATCH_MP_TAC REAL_NEGLIGIBLE_COUNTABLE_UNIONS THEN + X_GEN_TAC `n:num` THEN REWRITE_TAC[GSYM HAS_REAL_MEASURE_0] THEN + REWRITE_TAC[HAS_REAL_MEASURE] THEN + MATCH_MP_TAC HAS_REAL_INTEGRAL_STRADDLE_NULL THEN + EXISTS_TAC `\x:real. if x IN s then (&n + &1) * f(x) else &0` THEN + CONJ_TAC THENL + [REWRITE_TAC[IN_UNIV; IN_ELIM_THM; real_ge] THEN + X_GEN_TAC `x:real` THEN COND_CASES_TAC THEN + ASM_SIMP_TAC[REAL_POS] THENL + [ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN + ASM_SIMP_TAC[GSYM REAL_LE_LDIV_EQ; REAL_ARITH `&0 < &n + &1`] THEN + MATCH_MP_TAC(REAL_ARITH `&0 <= x /\ a <= abs x ==> a <= x`) THEN + ASM_SIMP_TAC[]; + COND_CASES_TAC THEN REWRITE_TAC[REAL_POS] THEN + ASM_SIMP_TAC[REAL_POS; REAL_LE_MUL; REAL_LE_ADD]]; + REWRITE_TAC[HAS_REAL_INTEGRAL_RESTRICT_UNIV] THEN + SUBST1_TAC(REAL_ARITH `&0 = (&n + &1) * &0`) THEN + MATCH_MP_TAC HAS_REAL_INTEGRAL_LMUL THEN ASM_REWRITE_TAC[]]; + REWRITE_TAC[SUBSET; IN_ELIM_THM] THEN X_GEN_TAC `x:real` THEN + REWRITE_TAC[REAL_ABS_NZ] THEN ONCE_REWRITE_TAC[REAL_ARCH_INV] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC (X_CHOOSE_THEN `n:num` + STRIP_ASSUME_TAC)) THEN + REWRITE_TAC[IN_UNIONS; EXISTS_IN_GSPEC] THEN + EXISTS_TAC `n - 1` THEN ASM_SIMP_TAC[IN_UNIV; IN_ELIM_THM; real_ge] THEN + ASM_SIMP_TAC[REAL_OF_NUM_ADD; SUB_ADD; LE_1] THEN + ASM_SIMP_TAC[real_div; REAL_MUL_LID; REAL_LT_IMP_LE]]);; + +(* ------------------------------------------------------------------------- *) +(* Drop the k'th coordinate, or insert t at the k'th coordinate. *) +(* ------------------------------------------------------------------------- *) + +let dropout = new_definition + `(dropout:num->real^N->real^M) k x = + lambda i. if i < k then x$i else x$(i + 1)`;; + +let pushin = new_definition + `pushin k t x = lambda i. if i < k then x$i + else if i = k then t + else x$(i - 1)`;; + +let DROPOUT_PUSHIN = prove + (`!k t x. + dimindex(:M) + 1 = dimindex(:N) + ==> (dropout k:real^N->real^M) (pushin k t x) = x`, + REPEAT GEN_TAC THEN DISCH_THEN(ASSUME_TAC o SYM) THEN + ASM_SIMP_TAC[CART_EQ; dropout; pushin; LAMBDA_BETA; + ARITH_RULE `1 <= n + 1`; ADD_SUB; + ARITH_RULE `m <= n ==> m <= n + 1 /\ m + 1 <= n + 1`] THEN + ARITH_TAC);; + +let PUSHIN_DROPOUT = prove + (`!k x. + dimindex(:M) + 1 = dimindex(:N) /\ 1 <= k /\ k <= dimindex(:N) + ==> pushin k (x$k) ((dropout k:real^N->real^M) x) = x`, + REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN(ASSUME_TAC o GSYM)) THEN + ASM_SIMP_TAC[CART_EQ; dropout; pushin; LAMBDA_BETA; + ARITH_RULE `i <= n + 1 ==> i - 1 <= n`] THEN + X_GEN_TAC `i:num` THEN STRIP_TAC THEN + ASM_CASES_TAC `i:num = k` THEN ASM_REWRITE_TAC[LT_REFL] THEN + FIRST_X_ASSUM(DISJ_CASES_TAC o MATCH_MP (ARITH_RULE + `~(i:num = k) ==> i < k \/ k < i`)) THEN + ASM_SIMP_TAC[ARITH_RULE `i:num < k ==> ~(k < i)`] THEN + W(MP_TAC o PART_MATCH (lhs o rand) LAMBDA_BETA o lhand o snd) THEN + (ANTS_TAC THENL [ASM_ARITH_TAC; DISCH_THEN SUBST1_TAC]) THEN + ASM_SIMP_TAC[ARITH_RULE `k < i ==> ~(i - 1 < k)`] THEN + AP_TERM_TAC THEN ASM_ARITH_TAC);; + +let DROPOUT_GALOIS = prove + (`!k x:real^N y:real^M. + dimindex(:M) + 1 = dimindex(:N) /\ 1 <= k /\ k <= dimindex(:N) + ==> (y = dropout k x <=> (?t. x = pushin k t y))`, + REPEAT STRIP_TAC THEN EQ_TAC THENL + [DISCH_THEN SUBST1_TAC THEN + EXISTS_TAC `(x:real^N)$k` THEN ASM_SIMP_TAC[PUSHIN_DROPOUT]; + DISCH_THEN(X_CHOOSE_THEN `t:real` SUBST1_TAC) THEN + ASM_SIMP_TAC[DROPOUT_PUSHIN]]);; + +let IN_IMAGE_DROPOUT = prove + (`!x s. + dimindex(:M) + 1 = dimindex(:N) /\ 1 <= k /\ k <= dimindex(:N) + ==> (x IN IMAGE (dropout k:real^N->real^M) s <=> + ?t. (pushin k t x) IN s)`, + SIMP_TAC[IN_IMAGE; DROPOUT_GALOIS] THEN MESON_TAC[]);; + +let CLOSED_INTERVAL_DROPOUT = prove + (`!k a b. dimindex(:M) + 1 = dimindex(:N) /\ + 1 <= k /\ k <= dimindex(:N) /\ + a$k <= b$k + ==> interval[dropout k a,dropout k b] = + IMAGE (dropout k:real^N->real^M) (interval[a,b])`, + REPEAT STRIP_TAC THEN + ASM_SIMP_TAC[EXTENSION; IN_IMAGE_DROPOUT; IN_INTERVAL] THEN + X_GEN_TAC `x:real^M` THEN + SIMP_TAC[pushin; dropout; LAMBDA_BETA] THEN EQ_TAC THENL + [DISCH_TAC THEN EXISTS_TAC `(a:real^N)$k` THEN X_GEN_TAC `i:num` THEN + STRIP_TAC THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[] THENL + [FIRST_X_ASSUM(MP_TAC o SPEC `i:num`) THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN MATCH_MP_TAC THEN ASM_ARITH_TAC; + COND_CASES_TAC THEN ASM_REWRITE_TAC[REAL_LE_REFL] THEN + FIRST_X_ASSUM(MP_TAC o SPEC `i - 1`) THEN + COND_CASES_TAC THENL [ASM_ARITH_TAC; ASM_REWRITE_TAC[]] THEN + ANTS_TAC THENL [ASM_ARITH_TAC; ASM_SIMP_TAC[SUB_ADD]]]; + DISCH_THEN(X_CHOOSE_TAC `t:real`) THEN X_GEN_TAC `i:num` THEN + STRIP_TAC THEN COND_CASES_TAC THENL + [FIRST_X_ASSUM(MP_TAC o SPEC `i:num`) THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN MATCH_MP_TAC THEN ASM_ARITH_TAC; + FIRST_X_ASSUM(MP_TAC o SPEC `i + 1`) THEN + ASM_REWRITE_TAC[] THEN ANTS_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[] THENL [ASM_ARITH_TAC; ALL_TAC] THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[] THENL [ASM_ARITH_TAC; ALL_TAC] THEN + ASM_REWRITE_TAC[ADD_SUB]]]);; + +let IMAGE_DROPOUT_CLOSED_INTERVAL = prove + (`!k a b. dimindex(:M) + 1 = dimindex(:N) /\ + 1 <= k /\ k <= dimindex(:N) + ==> IMAGE (dropout k:real^N->real^M) (interval[a,b]) = + if a$k <= b$k then interval[dropout k a,dropout k b] + else {}`, + REPEAT STRIP_TAC THEN COND_CASES_TAC THEN + ASM_SIMP_TAC[CLOSED_INTERVAL_DROPOUT; IMAGE_EQ_EMPTY] THEN + REWRITE_TAC[INTERVAL_EQ_EMPTY; GSYM REAL_NOT_LE] THEN ASM_MESON_TAC[]);; + +let LINEAR_DROPOUT = prove + (`!k. dimindex(:M) < dimindex(:N) + ==> linear(dropout k :real^N->real^M)`, + GEN_TAC THEN DISCH_THEN(MP_TAC o MATCH_MP (ARITH_RULE + `m < n ==> !i:num. i <= m ==> i <= n /\ i + 1 <= n`)) THEN + SIMP_TAC[linear; CART_EQ; VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT; + dropout; LAMBDA_BETA] THEN + REPEAT STRIP_TAC THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN + ASM_SIMP_TAC[VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT; + ARITH_RULE `1 <= i + 1`]);; + +let DROPOUT_EQ = prove + (`!x y k. dimindex(:M) + 1 = dimindex(:N) /\ 1 <= k /\ k <= dimindex(:N) /\ + x$k = y$k /\ (dropout k:real^N->real^M) x = dropout k y + ==> x = y`, + SIMP_TAC[CART_EQ; dropout; VEC_COMPONENT; LAMBDA_BETA; IN_ELIM_THM] THEN + MAP_EVERY X_GEN_TAC [`x:real^N`; `y:real^N`; `k:num`] THEN + STRIP_TAC THEN X_GEN_TAC `i:num` THEN STRIP_TAC THEN + ASM_CASES_TAC `i:num = k` THEN ASM_REWRITE_TAC[] THEN + FIRST_ASSUM(DISJ_CASES_TAC o MATCH_MP (ARITH_RULE + `~(i:num = k) ==> i < k \/ k < i`)) + THENL + [FIRST_X_ASSUM(MP_TAC o SPEC `i:num`) THEN ASM_SIMP_TAC[]; + FIRST_X_ASSUM(MP_TAC o SPEC `i - 1`) THEN + ASM_SIMP_TAC[SUB_ADD; ARITH_RULE `k < i ==> ~(i - 1 < k)`]] THEN + DISCH_THEN MATCH_MP_TAC THEN ASM_ARITH_TAC);; + +let DROPOUT_0 = prove + (`dropout k (vec 0:real^N) = vec 0`, + SIMP_TAC[dropout; VEC_COMPONENT; CART_EQ; COND_ID; LAMBDA_BETA]);; + +let DOT_DROPOUT = prove + (`!k x y:real^N. + dimindex(:M) + 1 = dimindex(:N) /\ 1 <= k /\ k <= dimindex(:N) + ==> (dropout k x:real^M) dot (dropout k y) = x dot y - x$k * y$k`, + REPEAT STRIP_TAC THEN SIMP_TAC[dot; dropout; LAMBDA_BETA] THEN + REWRITE_TAC[TAUT `(if p then x else y:real) * (if p then a else b) = + (if p then x * a else y * b)`] THEN + SIMP_TAC[SUM_CASES; FINITE_NUMSEG] THEN + SUBGOAL_THEN + `(!i. i IN 1..dimindex(:M) /\ i < k <=> i IN 1..k-1) /\ + (!i. i IN 1..dimindex(:M) /\ ~(i < k) <=> i IN k..dimindex(:M))` + (fun th -> REWRITE_TAC[th]) + THENL [REWRITE_TAC[IN_NUMSEG] THEN ASM_ARITH_TAC; ALL_TAC] THEN + REWRITE_TAC[SIMPLE_IMAGE; IMAGE_ID] THEN + REWRITE_TAC[GSYM(SPEC `1` SUM_OFFSET)] THEN + W(MP_TAC o PART_MATCH (rhs o rand) SUM_UNION o lhs o snd) THEN + ANTS_TAC THENL + [REWRITE_TAC[FINITE_NUMSEG; DISJOINT_NUMSEG] THEN ARITH_TAC; + DISCH_THEN(SUBST1_TAC o SYM)] THEN + MP_TAC(ISPECL [`\i. (x:real^N)$i * (y:real^N)$i`; + `1..dimindex(:N)`; + `k:num`] SUM_DELETE) THEN + ASM_REWRITE_TAC[IN_NUMSEG; FINITE_NUMSEG] THEN + DISCH_THEN(SUBST1_TAC o SYM) THEN + AP_THM_TAC THEN AP_TERM_TAC THEN + REWRITE_TAC[EXTENSION; IN_NUMSEG; IN_UNION; IN_DELETE] THEN ASM_ARITH_TAC);; + +let DOT_PUSHIN = prove + (`!k a b x y:real^M. + dimindex(:M) + 1 = dimindex(:N) /\ 1 <= k /\ k <= dimindex(:N) + ==> (pushin k a x:real^N) dot (pushin k b y) = x dot y + a * b`, + REPEAT STRIP_TAC THEN + MATCH_MP_TAC EQ_TRANS THEN + EXISTS_TAC `(dropout k (pushin k a (x:real^M):real^N):real^M) dot + (dropout k (pushin k b (y:real^M):real^N):real^M) + + a * b` THEN + CONJ_TAC THENL [ALL_TAC; ASM_SIMP_TAC[DROPOUT_PUSHIN]] THEN + ASM_SIMP_TAC[DOT_DROPOUT] THEN + MATCH_MP_TAC(REAL_RING + `a':real = a /\ b' = b ==> x = x - a' * b' + a * b`) THEN + ASM_SIMP_TAC[pushin; LAMBDA_BETA; LT_REFL]);; + +let DROPOUT_ADD = prove + (`!k x y:real^N. dropout k (x + y) = dropout k x + dropout k y`, + SIMP_TAC[dropout; VECTOR_ADD_COMPONENT; CART_EQ; LAMBDA_BETA] THEN + MESON_TAC[]);; + +let DROPOUT_SUB = prove + (`!k x y:real^N. dropout k (x - y) = dropout k x - dropout k y`, + SIMP_TAC[dropout; VECTOR_SUB_COMPONENT; CART_EQ; LAMBDA_BETA] THEN + MESON_TAC[]);; + +let DROPOUT_MUL = prove + (`!k c x:real^N. dropout k (c % x) = c % dropout k x`, + SIMP_TAC[dropout; VECTOR_MUL_COMPONENT; CART_EQ; LAMBDA_BETA] THEN + MESON_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* Take slice of set s at x$k = t and drop the k'th coordinate. *) +(* ------------------------------------------------------------------------- *) + +let slice = new_definition + `slice k t s = IMAGE (dropout k) (s INTER {x | x$k = t})`;; + +let IN_SLICE = prove + (`!s:real^N->bool y:real^M. + dimindex(:M) + 1 = dimindex(:N) /\ 1 <= k /\ k <= dimindex(:N) + ==> (y IN slice k t s <=> pushin k t y IN s)`, + SIMP_TAC[slice; IN_IMAGE_DROPOUT; IN_INTER; IN_ELIM_THM] THEN + REPEAT STRIP_TAC THEN REWRITE_TAC[pushin] THEN + ASM_SIMP_TAC[LAMBDA_BETA; LT_REFL] THEN MESON_TAC[]);; + +let INTERVAL_INTER_HYPERPLANE = prove + (`!k t a b:real^N. + 1 <= k /\ k <= dimindex(:N) + ==> interval[a,b] INTER {x | x$k = t} = + if a$k <= t /\ t <= b$k + then interval[(lambda i. if i = k then t else a$i), + (lambda i. if i = k then t else b$i)] + else {}`, + REPEAT STRIP_TAC THEN + REWRITE_TAC[EXTENSION; IN_INTER; IN_INTERVAL; IN_ELIM_THM] THEN + X_GEN_TAC `x:real^N` THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[] THENL + [ALL_TAC; ASM_MESON_TAC[NOT_IN_EMPTY]] THEN + SIMP_TAC[IN_INTERVAL; LAMBDA_BETA] THEN + EQ_TAC THEN STRIP_TAC THENL [ASM_MESON_TAC[REAL_LE_ANTISYM]; ALL_TAC] THEN + CONJ_TAC THENL [ALL_TAC; ASM_MESON_TAC[REAL_LE_ANTISYM]] THEN + X_GEN_TAC `i:num` THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `i:num`) THEN ASM_REWRITE_TAC[] THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN ASM_REAL_ARITH_TAC);; + +let SLICE_INTERVAL = prove + (`!k a b t. dimindex(:M) + 1 = dimindex(:N) /\ + 1 <= k /\ k <= dimindex(:N) + ==> slice k t (interval[a,b]) = + if a$k <= t /\ t <= b$k + then interval[(dropout k:real^N->real^M) a,dropout k b] + else {}`, + REPEAT STRIP_TAC THEN ASM_SIMP_TAC[slice; INTERVAL_INTER_HYPERPLANE] THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[IMAGE_CLAUSES] THEN + ASM_SIMP_TAC[IMAGE_DROPOUT_CLOSED_INTERVAL; LAMBDA_BETA; REAL_LE_REFL] THEN + MATCH_MP_TAC(MESON[] + `a = a' /\ b = b' ==> interval[a,b] = interval[a',b']`) THEN + SIMP_TAC[CART_EQ; LAMBDA_BETA; dropout] THEN + SUBGOAL_THEN + `!i. i <= dimindex(:M) ==> i <= dimindex(:N) /\ i + 1 <= dimindex(:N)` + MP_TAC THENL + [ASM_ARITH_TAC; + ASM_SIMP_TAC[LAMBDA_BETA; ARITH_RULE `1 <= i + 1`] THEN ARITH_TAC]);; + +let SLICE_DIFF = prove + (`!k a s t. + dimindex(:M) + 1 = dimindex(:N) /\ 1 <= k /\ k <= dimindex(:N) + ==> (slice k a:(real^N->bool)->(real^M->bool)) (s DIFF t) = + (slice k a s) DIFF (slice k a t)`, + REPEAT STRIP_TAC THEN REWRITE_TAC[slice] THEN + SIMP_TAC[SET_RULE `(s DIFF t) INTER u = (s INTER u) DIFF (t INTER u)`] THEN + MATCH_MP_TAC(SET_RULE + `(!x y. x IN a /\ y IN a /\ f x = f y ==> x = y) + ==> IMAGE f ((s INTER a) DIFF (t INTER a)) = + IMAGE f (s INTER a) DIFF IMAGE f (t INTER a)`) THEN + REWRITE_TAC[IN_ELIM_THM] THEN ASM_MESON_TAC[DROPOUT_EQ]);; + +let SLICE_UNIV = prove + (`!k a. dimindex(:M) + 1 = dimindex(:N) /\ 1 <= k /\ k <= dimindex(:N) + ==> slice k a (:real^N) = (:real^M)`, + REPEAT STRIP_TAC THEN + SIMP_TAC[EXTENSION; IN_UNIV; IN_IMAGE; slice; INTER_UNIV; IN_ELIM_THM] THEN + X_GEN_TAC `y:real^M` THEN EXISTS_TAC `(pushin k a:real^M->real^N) y` THEN + ASM_SIMP_TAC[DROPOUT_PUSHIN] THEN + ASM_SIMP_TAC[pushin; LAMBDA_BETA; LT_REFL]);; + +let SLICE_EMPTY = prove + (`!k a. slice k a {} = {}`, + REWRITE_TAC[slice; INTER_EMPTY; IMAGE_CLAUSES]);; + +let SLICE_SUBSET = prove + (`!s t k a. s SUBSET t ==> slice k a s SUBSET slice k a t`, + REWRITE_TAC[slice] THEN SET_TAC[]);; + +let SLICE_UNIONS = prove + (`!s k a. slice k a (UNIONS s) = UNIONS (IMAGE (slice k a) s)`, + REPEAT GEN_TAC THEN REWRITE_TAC[slice; INTER_UNIONS; IMAGE_UNIONS] THEN + ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN REWRITE_TAC[GSYM IMAGE_o] THEN + AP_TERM_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN + REWRITE_TAC[FUN_EQ_THM; o_THM; slice]);; + +let SLICE_UNION = prove + (`!k a s t. + dimindex(:M) + 1 = dimindex(:N) /\ 1 <= k /\ k <= dimindex(:N) + ==> (slice k a:(real^N->bool)->(real^M->bool)) (s UNION t) = + (slice k a s) UNION (slice k a t)`, + REPEAT GEN_TAC THEN REWRITE_TAC[slice; IMAGE_UNION; + SET_RULE `(s UNION t) INTER u = (s INTER u) UNION (t INTER u)`] THEN + ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN REWRITE_TAC[GSYM IMAGE_o] THEN + AP_TERM_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN + REWRITE_TAC[FUN_EQ_THM; o_THM; slice]);; + +let SLICE_INTER = prove + (`!k a s t. + dimindex(:M) + 1 = dimindex(:N) /\ 1 <= k /\ k <= dimindex(:N) + ==> (slice k a:(real^N->bool)->(real^M->bool)) (s INTER t) = + (slice k a s) INTER (slice k a t)`, + REPEAT STRIP_TAC THEN REWRITE_TAC[slice] THEN + MATCH_MP_TAC(SET_RULE + `(!x y. x IN u /\ y IN u /\ f x = f y ==> x = y) + ==> IMAGE f ((s INTER t) INTER u) = + IMAGE f (s INTER u) INTER IMAGE f (t INTER u)`) THEN + REWRITE_TAC[IN_ELIM_THM] THEN ASM_MESON_TAC[DROPOUT_EQ]);; + +let CONVEX_SLICE = prove + (`!k t s. dimindex(:M) < dimindex(:N) /\ convex s + ==> convex((slice k t:(real^N->bool)->(real^M->bool)) s)`, + REPEAT STRIP_TAC THEN REWRITE_TAC[slice] THEN + MATCH_MP_TAC CONVEX_LINEAR_IMAGE THEN ASM_SIMP_TAC[LINEAR_DROPOUT] THEN + MATCH_MP_TAC CONVEX_INTER THEN ASM_REWRITE_TAC[CONVEX_STANDARD_HYPERPLANE]);; + +let COMPACT_SLICE = prove + (`!k t s. dimindex(:M) < dimindex(:N) /\ compact s + ==> compact((slice k t:(real^N->bool)->(real^M->bool)) s)`, + REPEAT STRIP_TAC THEN REWRITE_TAC[slice] THEN + MATCH_MP_TAC COMPACT_LINEAR_IMAGE THEN ASM_SIMP_TAC[LINEAR_DROPOUT] THEN + REWRITE_TAC[COMPACT_EQ_BOUNDED_CLOSED] THEN CONJ_TAC THENL + [MATCH_MP_TAC BOUNDED_INTER THEN ASM_SIMP_TAC[COMPACT_IMP_BOUNDED]; + MATCH_MP_TAC CLOSED_INTER THEN + ASM_SIMP_TAC[COMPACT_IMP_CLOSED; CLOSED_STANDARD_HYPERPLANE]]);; + +let CLOSED_SLICE = prove + (`!k t s. dimindex(:M) + 1 = dimindex(:N) /\ 1 <= k /\ k <= dimindex(:N) /\ + closed s + ==> closed((slice k t:(real^N->bool)->(real^M->bool)) s)`, + REPEAT STRIP_TAC THEN REWRITE_TAC[slice] THEN + SUBGOAL_THEN + `closed(IMAGE (dropout k:real^N->real^M) + (IMAGE (\x. x - t % basis k) + (s INTER {x | x$k = t})))` + MP_TAC THENL + [ALL_TAC; + REWRITE_TAC[GSYM IMAGE_o] THEN MATCH_MP_TAC EQ_IMP THEN + AP_TERM_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN + REWRITE_TAC[FUN_EQ_THM; o_THM; dropout] THEN + SUBGOAL_THEN + `!i. i <= dimindex(:M) ==> i <= dimindex(:N) /\ i + 1 <= dimindex(:N)` + MP_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN + SIMP_TAC[VECTOR_SUB_COMPONENT; VECTOR_MUL_COMPONENT; CART_EQ; + LAMBDA_BETA; BASIS_COMPONENT; ARITH_RULE `1 <= i + 1`] THEN + SIMP_TAC[ARITH_RULE `i:num < k ==> ~(i = k)`; + ARITH_RULE `~(i < k) ==> ~(i + 1 = k)`] THEN + REWRITE_TAC[REAL_MUL_RZERO; REAL_SUB_RZERO]] THEN + MATCH_MP_TAC CLOSED_INJECTIVE_IMAGE_SUBSET_SUBSPACE THEN + EXISTS_TAC `{x:real^N | x$k = &0}` THEN + ASM_SIMP_TAC[SUBSPACE_SPECIAL_HYPERPLANE; LINEAR_DROPOUT; + ARITH_RULE `m + 1 = n ==> m < n`] THEN + REPEAT CONJ_TAC THENL + [ONCE_REWRITE_TAC[VECTOR_ARITH `x - t % b:real^N = --(t % b) + x`] THEN + ASM_SIMP_TAC[CLOSED_TRANSLATION_EQ; CLOSED_INTER; + CLOSED_STANDARD_HYPERPLANE]; + MATCH_MP_TAC(SET_RULE + `IMAGE f t SUBSET u ==> IMAGE f (s INTER t) SUBSET u`) THEN + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; IN_ELIM_THM] THEN + ASM_SIMP_TAC[VECTOR_SUB_COMPONENT; VECTOR_MUL_COMPONENT; BASIS_COMPONENT; + REAL_MUL_RID; REAL_SUB_REFL]; + REWRITE_TAC[IN_ELIM_THM] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC DROPOUT_EQ THEN EXISTS_TAC `k:num` THEN + ASM_REWRITE_TAC[DROPOUT_0; VEC_COMPONENT]]);; + +let OPEN_SLICE = prove + (`!k t s. dimindex(:M) + 1 = dimindex(:N) /\ 1 <= k /\ k <= dimindex(:N) /\ + open s + ==> open((slice k t:(real^N->bool)->(real^M->bool)) s)`, + REWRITE_TAC[OPEN_CLOSED] THEN REPEAT STRIP_TAC THEN + SUBGOAL_THEN `closed(slice k t ((:real^N) DIFF s):real^M->bool)` + MP_TAC THENL + [ASM_SIMP_TAC[CLOSED_SLICE]; + ASM_SIMP_TAC[SLICE_DIFF; SLICE_UNIV]]);; + +let BOUNDED_SLICE = prove + (`!k t s. dimindex(:M) + 1 = dimindex(:N) /\ 1 <= k /\ k <= dimindex(:N) /\ + bounded s + ==> bounded((slice k t:(real^N->bool)->(real^M->bool)) s)`, + REPEAT STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o MATCH_MP BOUNDED_SUBSET_CLOSED_INTERVAL) THEN + REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`a:real^N`; `b:real^N`] THEN DISCH_TAC THEN + MATCH_MP_TAC BOUNDED_SUBSET THEN + EXISTS_TAC `(slice k t:(real^N->bool)->(real^M->bool)) (interval[a,b])` THEN + ASM_SIMP_TAC[SLICE_SUBSET] THEN ASM_SIMP_TAC[SLICE_INTERVAL] THEN + MESON_TAC[BOUNDED_EMPTY; BOUNDED_INTERVAL]);; + +let SLICE_CBALL = prove + (`!k t x r. + dimindex(:M) + 1 = dimindex(:N) /\ 1 <= k /\ k <= dimindex(:N) + ==> (slice k t:(real^N->bool)->(real^M->bool)) (cball(x,r)) = + if abs(t - x$k) <= r + then cball(dropout k x,sqrt(r pow 2 - (t - x$k) pow 2)) + else {}`, + REPEAT STRIP_TAC THEN REWRITE_TAC[slice] THEN COND_CASES_TAC THENL + [ALL_TAC; + REWRITE_TAC[IMAGE_EQ_EMPTY] THEN + REWRITE_TAC[EXTENSION; IN_ELIM_THM; IN_INTER; NOT_IN_EMPTY; IN_CBALL] THEN + X_GEN_TAC `y:real^N` THEN REWRITE_TAC[dist] THEN + DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH + `~(a <= r) ==> a <= b ==> b <= r ==> F`)) THEN + ASM_MESON_TAC[VECTOR_SUB_COMPONENT; COMPONENT_LE_NORM; NORM_SUB]] THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP(REAL_ARITH `abs(x) <= r ==> &0 <= r`)) THEN + REWRITE_TAC[EXTENSION; IN_IMAGE; IN_CBALL] THEN X_GEN_TAC `y:real^M` THEN + ASM_SIMP_TAC[DROPOUT_GALOIS; LEFT_AND_EXISTS_THM] THEN + ONCE_REWRITE_TAC[SWAP_EXISTS_THM] THEN REWRITE_TAC[UNWIND_THM2] THEN + REWRITE_TAC[IN_CBALL; IN_INTER; IN_ELIM_THM] THEN + ASM_SIMP_TAC[pushin; LAMBDA_BETA; LT_REFL] THEN + ONCE_REWRITE_TAC[CONJ_SYM] THEN REWRITE_TAC[UNWIND_THM2] THEN + ASM_REWRITE_TAC[dist; NORM_LE_SQUARE; GSYM pushin] THEN + ASM_SIMP_TAC[SQRT_POW_2; SQRT_POS_LE; REAL_SUB_LE; GSYM REAL_LE_SQUARE_ABS; + REAL_ARITH `abs(x) <= r ==> abs(x) <= abs(r)`] THEN + REWRITE_TAC[VECTOR_ARITH + `(x - y:real^N) dot (x - y) = x dot x + y dot y - &2 * x dot y`] THEN + ASM_SIMP_TAC[DOT_DROPOUT; DOT_PUSHIN] THEN MATCH_MP_TAC(REAL_FIELD + `a = t * k + b + ==> (xx + (yy + t * t) - &2 * a <= r pow 2 <=> + xx - k * k + yy - &2 * b <= r pow 2 - (t - k) pow 2)`) THEN + SUBGOAL_THEN + `y:real^M = dropout k (pushin k t y:real^N)` + (fun th -> GEN_REWRITE_TAC (RAND_CONV o ONCE_DEPTH_CONV) [th]) + THENL + [CONV_TAC SYM_CONV THEN MATCH_MP_TAC DROPOUT_PUSHIN THEN ASM_ARITH_TAC; + ASM_SIMP_TAC[DOT_DROPOUT] THEN + ASM_SIMP_TAC[pushin; LAMBDA_BETA; LT_REFL] THEN REAL_ARITH_TAC]);; + +let SLICE_BALL = prove + (`!k t x r. + dimindex(:M) + 1 = dimindex(:N) /\ 1 <= k /\ k <= dimindex(:N) + ==> (slice k t:(real^N->bool)->(real^M->bool)) (ball(x,r)) = + if abs(t - x$k) < r + then ball(dropout k x,sqrt(r pow 2 - (t - x$k) pow 2)) + else {}`, + REPEAT STRIP_TAC THEN REWRITE_TAC[slice] THEN COND_CASES_TAC THENL + [ALL_TAC; + REWRITE_TAC[IMAGE_EQ_EMPTY] THEN + REWRITE_TAC[EXTENSION; IN_ELIM_THM; IN_INTER; NOT_IN_EMPTY; IN_BALL] THEN + X_GEN_TAC `y:real^N` THEN REWRITE_TAC[dist] THEN + DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH + `~(a < r) ==> a <= b ==> b < r ==> F`)) THEN + ASM_MESON_TAC[VECTOR_SUB_COMPONENT; COMPONENT_LE_NORM; NORM_SUB]] THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP(REAL_ARITH `abs(x) < r ==> &0 < r`)) THEN + REWRITE_TAC[EXTENSION; IN_IMAGE; IN_BALL] THEN X_GEN_TAC `y:real^M` THEN + ASM_SIMP_TAC[DROPOUT_GALOIS; LEFT_AND_EXISTS_THM] THEN + ONCE_REWRITE_TAC[SWAP_EXISTS_THM] THEN REWRITE_TAC[UNWIND_THM2] THEN + REWRITE_TAC[IN_BALL; IN_INTER; IN_ELIM_THM] THEN + ASM_SIMP_TAC[pushin; LAMBDA_BETA; LT_REFL] THEN + ONCE_REWRITE_TAC[CONJ_SYM] THEN REWRITE_TAC[UNWIND_THM2] THEN + ASM_REWRITE_TAC[dist; NORM_LT_SQUARE; GSYM pushin] THEN + ASM_SIMP_TAC[SQRT_POW_2; SQRT_POS_LT; REAL_SUB_LT; GSYM REAL_LT_SQUARE_ABS; + REAL_LT_IMP_LE; REAL_ARITH `abs(x) < r ==> abs(x) < abs(r)`] THEN + REWRITE_TAC[VECTOR_ARITH + `(x - y:real^N) dot (x - y) = x dot x + y dot y - &2 * x dot y`] THEN + ASM_SIMP_TAC[DOT_DROPOUT; DOT_PUSHIN] THEN MATCH_MP_TAC(REAL_FIELD + `a = t * k + b + ==> (xx + (yy + t * t) - &2 * a < r pow 2 <=> + xx - k * k + yy - &2 * b < r pow 2 - (t - k) pow 2)`) THEN + SUBGOAL_THEN + `y:real^M = dropout k (pushin k t y:real^N)` + (fun th -> GEN_REWRITE_TAC (RAND_CONV o ONCE_DEPTH_CONV) [th]) + THENL + [CONV_TAC SYM_CONV THEN MATCH_MP_TAC DROPOUT_PUSHIN THEN ASM_ARITH_TAC; + ASM_SIMP_TAC[DOT_DROPOUT] THEN + ASM_SIMP_TAC[pushin; LAMBDA_BETA; LT_REFL] THEN REAL_ARITH_TAC]);; + +(* ------------------------------------------------------------------------- *) +(* Weak but useful versions of Fubini's theorem. *) +(* ------------------------------------------------------------------------- *) + +let FUBINI_CLOSED_INTERVAL = prove + (`!k a b:real^N. + dimindex(:M) + 1 = dimindex(:N) /\ + 1 <= k /\ k <= dimindex(:N) /\ + a$k <= b$k + ==> ((\t. measure (slice k t (interval[a,b]) :real^M->bool)) + has_real_integral + (measure(interval[a,b]))) (:real)`, + REPEAT STRIP_TAC THEN ASM_SIMP_TAC[SLICE_INTERVAL] THEN + ONCE_REWRITE_TAC[COND_RAND] THEN + REWRITE_TAC[MEASURE_EMPTY; MEASURE_INTERVAL] THEN + REWRITE_TAC[GSYM IN_REAL_INTERVAL] THEN + SIMP_TAC[HAS_REAL_INTEGRAL_RESTRICT; SUBSET_UNIV] THEN + SUBGOAL_THEN + `content(interval[a:real^N,b]) = + content(interval[dropout k a:real^M,dropout k b]) * (b$k - a$k)` + SUBST1_TAC THEN ASM_SIMP_TAC[HAS_REAL_INTEGRAL_CONST] THEN + REWRITE_TAC[CONTENT_CLOSED_INTERVAL_CASES] THEN + GEN_REWRITE_TAC (RAND_CONV o RATOR_CONV) [COND_RAND] THEN + GEN_REWRITE_TAC RAND_CONV [COND_RATOR] THEN + REWRITE_TAC[REAL_MUL_LZERO] THEN MATCH_MP_TAC(TAUT + `(p <=> p') /\ x = x' + ==> (if p then x else y) = (if p' then x' else y)`) THEN + CONJ_TAC THENL + [SIMP_TAC[dropout; LAMBDA_BETA] THEN EQ_TAC THEN DISCH_TAC THEN + X_GEN_TAC `i:num` THEN STRIP_TAC THENL + [COND_CASES_TAC THEN REWRITE_TAC[] THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_ARITH_TAC; + ASM_CASES_TAC `i:num = k` THEN ASM_REWRITE_TAC[] THEN + ASM_CASES_TAC `i:num < k` THENL + [FIRST_X_ASSUM(MP_TAC o SPEC `i:num`) THEN ASM_REWRITE_TAC[]; + FIRST_X_ASSUM(MP_TAC o SPEC `i - 1`) THEN + COND_CASES_TAC THENL [ASM_ARITH_TAC; ASM_SIMP_TAC[SUB_ADD]]] THEN + DISCH_THEN MATCH_MP_TAC THEN ASM_ARITH_TAC]; + ALL_TAC] THEN + SUBGOAL_THEN `1..dimindex(:N) = + (1..(k-1)) UNION + (k INSERT (IMAGE (\x. x + 1) (k..dimindex(:M))))` + SUBST1_TAC THENL + [REWRITE_TAC[EXTENSION; IN_NUMSEG; IN_UNION; IN_INSERT; IN_IMAGE] THEN + ASM_SIMP_TAC[ARITH_RULE + `1 <= k + ==> (x = y + 1 /\ k <= y /\ y <= n <=> + y = x - 1 /\ k + 1 <= x /\ x <= n + 1)`] THEN + REWRITE_TAC[CONJ_ASSOC; LEFT_EXISTS_AND_THM; EXISTS_REFL] THEN + ASM_ARITH_TAC; + ALL_TAC] THEN + REWRITE_TAC[SET_RULE `s UNION (x INSERT t) = x INSERT (s UNION t)`] THEN + SIMP_TAC[PRODUCT_CLAUSES; FINITE_NUMSEG; FINITE_UNION; FINITE_IMAGE] THEN + ASM_SIMP_TAC[IN_NUMSEG; IN_UNION; IN_IMAGE; ARITH_RULE + `1 <= k ==> ~(k <= k - 1)`] THEN + COND_CASES_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN + GEN_REWRITE_TAC RAND_CONV [REAL_MUL_SYM] THEN AP_TERM_TAC THEN + MP_TAC(ISPECL [`1`; `k - 1`; `dimindex(:M)`] NUMSEG_COMBINE_R) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; DISCH_THEN(SUBST1_TAC o SYM)] THEN + W(MP_TAC o PART_MATCH (lhs o rand) PRODUCT_UNION o lhand o snd) THEN + SIMP_TAC[FINITE_NUMSEG; FINITE_IMAGE; IN_NUMSEG; SET_RULE + `DISJOINT s (IMAGE f t) <=> !x. x IN t ==> ~(f x IN s)`] THEN + ANTS_TAC THENL [ASM_ARITH_TAC; DISCH_THEN SUBST1_TAC] THEN + W(MP_TAC o PART_MATCH (lhs o rand) PRODUCT_UNION o rand o snd) THEN + SIMP_TAC[FINITE_NUMSEG; FINITE_IMAGE; IN_NUMSEG; SET_RULE + `DISJOINT s t <=> !x. ~(x IN s /\ x IN t)`] THEN + ANTS_TAC THENL [ASM_ARITH_TAC; DISCH_THEN SUBST1_TAC] THEN + ASM_SIMP_TAC[PRODUCT_IMAGE; EQ_ADD_RCANCEL; SUB_ADD] THEN + BINOP_TAC THEN MATCH_MP_TAC PRODUCT_EQ_NUMSEG THEN + SIMP_TAC[dropout; LAMBDA_BETA; o_THM] THEN + REPEAT STRIP_TAC THEN BINOP_TAC THEN + (W(MP_TAC o PART_MATCH (lhs o rand) LAMBDA_BETA o rand o snd) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; DISCH_THEN SUBST1_TAC] THEN + REWRITE_TAC[] THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN + ASM_ARITH_TAC));; + +let MEASURABLE_OUTER_INTERVALS_BOUNDED_EXPLICIT_SPECIAL = prove + (`!s a b e. + 2 <= dimindex(:N) /\ 1 <= k /\ k <= dimindex(:N) /\ + measurable s /\ s SUBSET interval[a,b] /\ &0 < e + ==> ?f:num->real^N->bool. + (!i. (f i) SUBSET interval[a,b] /\ + ?c d. c$k <= d$k /\ f i = interval[c,d]) /\ + (!i j. ~(i = j) ==> negligible(f i INTER f j)) /\ + s SUBSET UNIONS {f n | n IN (:num)} /\ + measurable(UNIONS {f n | n IN (:num)}) /\ + measure(UNIONS {f n | n IN (:num)}) <= measure s + e`, + let lemma = prove + (`UNIONS {if n IN s then f n else {} | n IN (:num)} = + UNIONS (IMAGE f s)`, + SIMP_TAC[EXTENSION; IN_UNIONS; IN_ELIM_THM; IN_UNIV; EXISTS_IN_IMAGE] THEN + MESON_TAC[NOT_IN_EMPTY]) in + REPEAT GEN_TAC THEN + REPLICATE_TAC 3 (DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + DISCH_TAC THEN + FIRST_ASSUM(MP_TAC o MATCH_MP MEASURABLE_OUTER_INTERVALS_BOUNDED) THEN + DISCH_THEN(X_CHOOSE_THEN `d:(real^N->bool)->bool` STRIP_ASSUME_TAC) THEN + ASM_CASES_TAC `FINITE(d:(real^N->bool)->bool)` THENL + [FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [FINITE_INDEX_NUMSEG]) THEN + DISCH_THEN(X_CHOOSE_THEN `f:num->real^N->bool` + (fun th -> SUBST_ALL_TAC(CONJUNCT2 th) THEN ASSUME_TAC(CONJUNCT1 th))) THEN + RULE_ASSUM_TAC(REWRITE_RULE[IMP_CONJ; FORALL_IN_IMAGE; + RIGHT_FORALL_IMP_THM; IN_UNIV]) THEN + EXISTS_TAC `\k. if k IN 1..CARD(d:(real^N->bool)->bool) then f k + else ({}:real^N->bool)` THEN + REWRITE_TAC[] THEN CONJ_TAC THENL + [X_GEN_TAC `i:num` THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[] THENL + [ASM_MESON_TAC[REAL_NOT_LT; IN_NUMSEG; REAL_NOT_LE; INTERVAL_EQ_EMPTY]; + REWRITE_TAC[EMPTY_SUBSET] THEN CONV_TAC(ONCE_DEPTH_CONV SYM_CONV) THEN + EXISTS_TAC `(lambda i. if i = k then &0 else &1):real^N` THEN + EXISTS_TAC `(lambda i. if i = k then &1 else &0):real^N` THEN + REWRITE_TAC[INTERVAL_EQ_EMPTY] THEN CONJ_TAC THENL + [SIMP_TAC[LAMBDA_BETA; ASSUME `1 <= k`; ASSUME `k <= dimindex(:N)`; + REAL_POS]; + ALL_TAC] THEN + SUBGOAL_THEN `?j. 1 <= j /\ j <= dimindex(:N) /\ ~(j = k)` MP_TAC THENL + [MATCH_MP_TAC(MESON[] `P(k - 1) \/ P(k + 1) ==> ?i. P i`) THEN + ASM_ARITH_TAC; + MATCH_MP_TAC MONO_EXISTS THEN SIMP_TAC[LAMBDA_BETA] THEN + REAL_ARITH_TAC]]; + ALL_TAC] THEN + CONJ_TAC THENL [ALL_TAC; ASM_REWRITE_TAC[lemma]] THEN + REPEAT GEN_TAC THEN + REPEAT(COND_CASES_TAC THEN + ASM_REWRITE_TAC[INTER_EMPTY; NEGLIGIBLE_EMPTY]); + MP_TAC(ISPEC `d:(real^N->bool)->bool` COUNTABLE_AS_INJECTIVE_IMAGE) THEN + ASM_REWRITE_TAC[INFINITE] THEN MATCH_MP_TAC MONO_EXISTS THEN + X_GEN_TAC `f:num->real^N->bool` THEN + DISCH_THEN(CONJUNCTS_THEN2 SUBST_ALL_TAC ASSUME_TAC) THEN + RULE_ASSUM_TAC(REWRITE_RULE[IMP_CONJ; FORALL_IN_IMAGE; + RIGHT_FORALL_IMP_THM; IN_UNIV]) THEN + RULE_ASSUM_TAC(REWRITE_RULE[GSYM SIMPLE_IMAGE]) THEN + ASM_REWRITE_TAC[] THEN CONJ_TAC THENL + [ASM_MESON_TAC[REAL_NOT_LT; IN_NUMSEG; REAL_NOT_LE; INTERVAL_EQ_EMPTY]; + ALL_TAC] THEN + MAP_EVERY X_GEN_TAC [`i:num`; `j:num`]] THEN + (DISCH_TAC THEN + SUBGOAL_THEN `negligible(interior((f:num->real^N->bool) i) INTER + interior(f j))` + MP_TAC THENL [ASM_MESON_TAC[NEGLIGIBLE_EMPTY]; ALL_TAC] THEN + REWRITE_TAC[GSYM INTERIOR_INTER] THEN + REWRITE_TAC[GSYM HAS_MEASURE_0] THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] + HAS_MEASURE_NEGLIGIBLE_SYMDIFF) THEN + SIMP_TAC[INTERIOR_SUBSET; SET_RULE + `interior(s) SUBSET s + ==> (interior s DIFF s) UNION (s DIFF interior s) = + s DIFF interior s`] THEN + SUBGOAL_THEN `(?c d. (f:num->real^N->bool) i = interval[c,d]) /\ + (?c d. (f:num->real^N->bool) j = interval[c,d])` + STRIP_ASSUME_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN + ASM_REWRITE_TAC[INTER_INTERVAL; NEGLIGIBLE_FRONTIER_INTERVAL; + INTERIOR_CLOSED_INTERVAL]));; + +let REAL_MONOTONE_CONVERGENCE_INCREASING_AE = prove + (`!f:num->real->real g s. + (!k. (f k) real_integrable_on s) /\ + (!k x. x IN s ==> f k x <= f (SUC k) x) /\ + (?t. real_negligible t /\ + !x. x IN (s DIFF t) ==> ((\k. f k x) ---> g x) sequentially) /\ + real_bounded {real_integral s (f k) | k IN (:num)} + ==> g real_integrable_on s /\ + ((\k. real_integral s (f k)) ---> real_integral s g) sequentially`, + REPEAT GEN_TAC THEN STRIP_TAC THEN + SUBGOAL_THEN + `g real_integrable_on (s DIFF t) /\ + ((\k. real_integral (s DIFF t) (f k)) ---> real_integral (s DIFF t) g) + sequentially` + MP_TAC THENL + [MATCH_MP_TAC REAL_MONOTONE_CONVERGENCE_INCREASING THEN + REPEAT CONJ_TAC THENL + [UNDISCH_TAC `!k:num. f k real_integrable_on s` THEN + MATCH_MP_TAC MONO_FORALL THEN GEN_TAC THEN + MATCH_MP_TAC REAL_INTEGRABLE_SPIKE_SET; + ASM_SIMP_TAC[IN_DIFF]; + ASM_REWRITE_TAC[]; + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [real_bounded]) THEN + REWRITE_TAC[real_bounded; FORALL_IN_GSPEC; IN_UNIV] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `B:real` THEN + MATCH_MP_TAC MONO_FORALL THEN GEN_TAC THEN MATCH_MP_TAC EQ_IMP THEN + AP_THM_TAC THEN AP_TERM_TAC THEN AP_TERM_TAC THEN + MATCH_MP_TAC REAL_INTEGRAL_SPIKE_SET]; + MATCH_MP_TAC EQ_IMP THEN BINOP_TAC THENL + [MATCH_MP_TAC REAL_INTEGRABLE_SPIKE_SET_EQ THEN + MATCH_MP_TAC REAL_NEGLIGIBLE_SUBSET THEN + EXISTS_TAC `t:real->bool` THEN ASM_REWRITE_TAC[] THEN SET_TAC[]; + AP_THM_TAC THEN BINOP_TAC THENL + [ABS_TAC; ALL_TAC] THEN + MATCH_MP_TAC REAL_INTEGRAL_SPIKE_SET]] THEN + MATCH_MP_TAC REAL_NEGLIGIBLE_SUBSET THEN + EXISTS_TAC `t:real->bool` THEN ASM_REWRITE_TAC[] THEN SET_TAC[]);; + +let FUBINI_SIMPLE_LEMMA = prove + (`!k s:real^N->bool e. + &0 < e /\ + dimindex(:M) + 1 = dimindex(:N) /\ + 1 <= k /\ k <= dimindex(:N) /\ + bounded s /\ measurable s /\ + (!t. measurable(slice k t s:real^M->bool)) /\ + (\t. measure (slice k t s:real^M->bool)) real_integrable_on (:real) + ==> real_integral(:real) (\t. measure (slice k t s :real^M->bool)) + <= measure s + e`, + REPEAT STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o MATCH_MP BOUNDED_SUBSET_CLOSED_INTERVAL) THEN + REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`a:real^N`; `b:real^N`] THEN DISCH_TAC THEN + MP_TAC(ISPECL [`s:real^N->bool`; `a:real^N`; `b:real^N`; `e:real`] + MEASURABLE_OUTER_INTERVALS_BOUNDED_EXPLICIT_SPECIAL) THEN + ASM_REWRITE_TAC[] THEN ANTS_TAC THENL + [SUBGOAL_THEN `1 <= dimindex(:M)` MP_TAC THENL + [REWRITE_TAC[DIMINDEX_GE_1]; ASM_ARITH_TAC]; + ALL_TAC] THEN + DISCH_THEN(X_CHOOSE_THEN `d:num->(real^N->bool)` STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN `!t n:num. measurable((slice k t:(real^N->bool)->real^M->bool) + (d n))` + ASSUME_TAC THENL + [MAP_EVERY X_GEN_TAC [`t:real`; `n:num`] THEN + FIRST_X_ASSUM(STRIP_ASSUME_TAC o CONJUNCT2 o SPEC `n:num`) THEN + ASM_SIMP_TAC[SLICE_INTERVAL] THEN + MESON_TAC[MEASURABLE_EMPTY; MEASURABLE_INTERVAL]; + ALL_TAC] THEN + MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `measure(UNIONS {d n | n IN (:num)}:real^N->bool)` THEN + ASM_REWRITE_TAC[] THEN + MP_TAC(ISPECL + [`\n t. sum(0..n) + (\m. measure((slice k t:(real^N->bool)->real^M->bool) + (d m)))`; + `\t. measure((slice k t:(real^N->bool)->real^M->bool) + (UNIONS {d n | n IN (:num)}))`; `(:real)`] + REAL_MONOTONE_CONVERGENCE_INCREASING_AE) THEN + REWRITE_TAC[] THEN ANTS_TAC THENL + [CONJ_TAC THENL + [X_GEN_TAC `i:num` THEN MATCH_MP_TAC REAL_INTEGRABLE_SUM THEN + ASM_REWRITE_TAC[FINITE_NUMSEG] THEN X_GEN_TAC `j:num` THEN + DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o CONJUNCT2 o SPEC `j:num`) THEN + REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`u:real^N`; `v:real^N`] THEN STRIP_TAC THEN + MP_TAC(ISPECL [`k:num`; `u:real^N`; `v:real^N`] + FUBINI_CLOSED_INTERVAL) THEN + ASM_REWRITE_TAC[] THEN MESON_TAC[real_integrable_on]; + ALL_TAC] THEN + CONJ_TAC THENL + [REPEAT STRIP_TAC THEN REWRITE_TAC[SUM_CLAUSES_NUMSEG; LE_0] THEN + REWRITE_TAC[REAL_LE_ADDR] THEN MATCH_MP_TAC MEASURE_POS_LE THEN + ASM_REWRITE_TAC[]; + ALL_TAC] THEN + CONJ_TAC THENL + [ALL_TAC; + REWRITE_TAC[real_bounded; FORALL_IN_GSPEC; IN_UNIV] THEN + EXISTS_TAC `measure(interval[a:real^N,b])` THEN X_GEN_TAC `i:num` THEN + W(MP_TAC o PART_MATCH (lhand o rand) REAL_INTEGRAL_SUM o + rand o lhand o snd) THEN + ANTS_TAC THENL + [REWRITE_TAC[FINITE_NUMSEG] THEN X_GEN_TAC `j:num` THEN DISCH_TAC THEN + SUBGOAL_THEN `?u v. u$k <= v$k /\ + (d:num->real^N->bool) j = interval[u,v]` + STRIP_ASSUME_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN + ASM_REWRITE_TAC[] THEN REWRITE_TAC[real_integrable_on] THEN + EXISTS_TAC `measure(interval[u:real^N,v])` THEN + MATCH_MP_TAC FUBINI_CLOSED_INTERVAL THEN ASM_REWRITE_TAC[]; + ALL_TAC] THEN + DISCH_THEN SUBST1_TAC THEN MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `abs(sum(0..i) (\m. measure(d m:real^N->bool)))` THEN + CONJ_TAC THENL + [MATCH_MP_TAC REAL_EQ_IMP_LE THEN AP_TERM_TAC THEN + MATCH_MP_TAC SUM_EQ_NUMSEG THEN + X_GEN_TAC `j:num` THEN STRIP_TAC THEN REWRITE_TAC[] THEN + MATCH_MP_TAC REAL_INTEGRAL_UNIQUE THEN + SUBGOAL_THEN `?u v. u$k <= v$k /\ + (d:num->real^N->bool) j = interval[u,v]` + STRIP_ASSUME_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN + ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC FUBINI_CLOSED_INTERVAL THEN ASM_REWRITE_TAC[]; + ALL_TAC] THEN + MATCH_MP_TAC(REAL_ARITH `&0 <= x /\ x <= a ==> abs x <= a`) THEN + CONJ_TAC THENL + [MATCH_MP_TAC SUM_POS_LE THEN REWRITE_TAC[FINITE_NUMSEG] THEN + ASM_MESON_TAC[MEASURE_POS_LE; MEASURABLE_INTERVAL]; + ALL_TAC] THEN + W(MP_TAC o PART_MATCH (rhs o rand) MEASURE_NEGLIGIBLE_UNIONS_IMAGE o + lhand o snd) THEN + ANTS_TAC THENL + [ASM_SIMP_TAC[FINITE_NUMSEG] THEN ASM_MESON_TAC[MEASURABLE_INTERVAL]; + ALL_TAC] THEN + DISCH_THEN(SUBST1_TAC o SYM) THEN MATCH_MP_TAC MEASURE_SUBSET THEN + REWRITE_TAC[MEASURABLE_INTERVAL] THEN CONJ_TAC THENL + [MATCH_MP_TAC MEASURABLE_UNIONS THEN + ASM_SIMP_TAC[FINITE_NUMSEG; FINITE_IMAGE; FORALL_IN_IMAGE] THEN + ASM_MESON_TAC[MEASURABLE_INTERVAL]; + REWRITE_TAC[UNIONS_SUBSET; FORALL_IN_IMAGE] THEN ASM_MESON_TAC[]]] THEN + EXISTS_TAC + `(IMAGE (\i. (interval_lowerbound(d i):real^N)$k) (:num)) UNION + (IMAGE (\i. (interval_upperbound(d i):real^N)$k) (:num))` THEN + CONJ_TAC THENL + [MATCH_MP_TAC REAL_NEGLIGIBLE_COUNTABLE THEN + SIMP_TAC[COUNTABLE_UNION; COUNTABLE_IMAGE; NUM_COUNTABLE]; + ALL_TAC] THEN + X_GEN_TAC `t:real` THEN + REWRITE_TAC[IN_DIFF; IN_UNION; IN_IMAGE] THEN + GEN_REWRITE_TAC (LAND_CONV o TOP_DEPTH_CONV) [IN_UNIV] THEN + REWRITE_TAC[DE_MORGAN_THM; NOT_EXISTS_THM] THEN DISCH_TAC THEN + MP_TAC(ISPEC `\n:num. (slice k t:(real^N->bool)->real^M->bool) + (d n)` + HAS_MEASURE_COUNTABLE_NEGLIGIBLE_UNIONS_BOUNDED) THEN + ASM_REWRITE_TAC[SLICE_UNIONS] THEN ANTS_TAC THENL + [ALL_TAC; + DISCH_THEN(MP_TAC o CONJUNCT2) THEN + GEN_REWRITE_TAC (LAND_CONV o RATOR_CONV o LAND_CONV) [GSYM o_DEF] THEN + REWRITE_TAC[GSYM REAL_SUMS; real_sums; FROM_INTER_NUMSEG] THEN + REWRITE_TAC[SIMPLE_IMAGE; GSYM IMAGE_o; o_DEF]] THEN + CONJ_TAC THENL + [ALL_TAC; + MATCH_MP_TAC BOUNDED_SUBSET THEN + EXISTS_TAC `(slice k t:(real^N->bool)->real^M->bool) (interval[a,b])` THEN + CONJ_TAC THENL + [ASM_SIMP_TAC[SLICE_INTERVAL] THEN + MESON_TAC[BOUNDED_INTERVAL; BOUNDED_EMPTY]; + REWRITE_TAC[UNIONS_SUBSET; FORALL_IN_GSPEC] THEN + ASM_MESON_TAC[SLICE_SUBSET]]] THEN + MAP_EVERY X_GEN_TAC [`i:num`; `j:num`] THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`i:num`; `j:num`]) THEN + ASM_REWRITE_TAC[] THEN + ASM_CASES_TAC `(d:num->real^N->bool) i = {}` THENL + [ASM_REWRITE_TAC[INTER_EMPTY; NEGLIGIBLE_EMPTY; SLICE_EMPTY]; + UNDISCH_TAC `~((d:num->real^N->bool) i = {})`] THEN + ASM_CASES_TAC `(d:num->real^N->bool) j = {}` THENL + [ASM_REWRITE_TAC[INTER_EMPTY; NEGLIGIBLE_EMPTY; SLICE_EMPTY]; + UNDISCH_TAC `~((d:num->real^N->bool) j = {})`] THEN + FIRST_ASSUM(fun th -> + MAP_EVERY (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) + [SPEC `i:num` th; SPEC `j:num` th]) THEN + REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`w:real^N`; `x:real^N`] THEN STRIP_TAC THEN + MAP_EVERY X_GEN_TAC [`u:real^N`; `v:real^N`] THEN STRIP_TAC THEN + ASM_SIMP_TAC[SLICE_INTERVAL; INTERVAL_NE_EMPTY] THEN + DISCH_TAC THEN DISCH_TAC THEN + REPEAT(COND_CASES_TAC THEN + ASM_REWRITE_TAC[INTER_EMPTY; NEGLIGIBLE_EMPTY]) THEN + REWRITE_TAC[INTER_INTERVAL; NEGLIGIBLE_INTERVAL; INTERVAL_EQ_EMPTY] THEN + ONCE_REWRITE_TAC[TAUT `a /\ b /\ c <=> ~(a /\ b ==> ~c)`] THEN + SIMP_TAC[LAMBDA_BETA] THEN REWRITE_TAC[NOT_IMP] THEN + DISCH_THEN(X_CHOOSE_THEN `l:num` STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN `~(l:num = k)` ASSUME_TAC THENL + [FIRST_X_ASSUM(CONJUNCTS_THEN + (fun th -> MP_TAC(SPEC `i:num` th) THEN MP_TAC(SPEC `j:num` th))) THEN + ASM_SIMP_TAC[INTERVAL_LOWERBOUND; INTERVAL_UPPERBOUND] THEN + REWRITE_TAC[IMP_IMP] THEN ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN + REWRITE_TAC[] THEN DISCH_THEN SUBST_ALL_TAC THEN ASM_REAL_ARITH_TAC; + ALL_TAC] THEN + FIRST_ASSUM(DISJ_CASES_TAC o MATCH_MP (ARITH_RULE + `~(l:num = k) ==> l < k \/ k < l`)) + THENL + [EXISTS_TAC `l:num` THEN + MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN + CONJ_TAC THENL [ASM_ARITH_TAC; SIMP_TAC[dropout; LAMBDA_BETA]] THEN + ASM_REWRITE_TAC[]; + ALL_TAC] THEN + EXISTS_TAC `l - 1` THEN + MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN + CONJ_TAC THENL [ASM_ARITH_TAC; SIMP_TAC[dropout; LAMBDA_BETA]] THEN + ASM_SIMP_TAC[ARITH_RULE `k < l ==> ~(l - 1 < k)`] THEN + ASM_SIMP_TAC[SUB_ADD]; + ALL_TAC] THEN + STRIP_TAC THEN MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC + `real_integral (:real) + (\t. measure ((slice k t :(real^N->bool)->real^M->bool) + (UNIONS {d n | n IN (:num)})))` THEN + CONJ_TAC THENL + [MATCH_MP_TAC REAL_INTEGRAL_LE THEN ASM_REWRITE_TAC[] THEN + X_GEN_TAC `t:real` THEN DISCH_TAC THEN MATCH_MP_TAC MEASURE_SUBSET THEN + ASM_SIMP_TAC[SLICE_SUBSET; SLICE_UNIONS] THEN + ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN REWRITE_TAC[GSYM IMAGE_o] THEN + ONCE_REWRITE_TAC[GSYM SIMPLE_IMAGE] THEN + MATCH_MP_TAC MEASURABLE_COUNTABLE_UNIONS_BOUNDED THEN + ASM_REWRITE_TAC[o_THM] THEN + MATCH_MP_TAC BOUNDED_SUBSET THEN + EXISTS_TAC `(slice k t:(real^N->bool)->real^M->bool) (interval[a,b])` THEN + CONJ_TAC THENL + [ASM_SIMP_TAC[SLICE_INTERVAL] THEN + MESON_TAC[BOUNDED_INTERVAL; BOUNDED_EMPTY]; + REWRITE_TAC[UNIONS_SUBSET; FORALL_IN_GSPEC] THEN + ASM_MESON_TAC[SLICE_SUBSET]]; + MATCH_MP_TAC REAL_EQ_IMP_LE THEN + MATCH_MP_TAC(ISPEC `sequentially` REALLIM_UNIQUE) THEN + EXISTS_TAC `\n. real_integral (:real) + (\t. sum (0..n) (\m. measure((slice k t:(real^N->bool)->real^M->bool) + + (d m))))` THEN + ASM_REWRITE_TAC[TRIVIAL_LIMIT_SEQUENTIALLY] THEN + MP_TAC(ISPEC `d:num->(real^N->bool)` + HAS_MEASURE_COUNTABLE_NEGLIGIBLE_UNIONS_BOUNDED) THEN + ANTS_TAC THENL + [ASM_REWRITE_TAC[] THEN CONJ_TAC THENL + [ASM_MESON_TAC[MEASURABLE_INTERVAL]; ALL_TAC] THEN + MATCH_MP_TAC BOUNDED_SUBSET THEN EXISTS_TAC `interval[a:real^N,b]` THEN + REWRITE_TAC[BOUNDED_INTERVAL; UNIONS_SUBSET; IN_ELIM_THM] THEN + ASM_MESON_TAC[]; + ALL_TAC] THEN + ASM_REWRITE_TAC[] THEN + GEN_REWRITE_TAC (LAND_CONV o RATOR_CONV o LAND_CONV) [GSYM o_DEF] THEN + REWRITE_TAC[GSYM REAL_SUMS] THEN + REWRITE_TAC[real_sums; FROM_INTER_NUMSEG] THEN + MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_THM_TAC THEN + AP_TERM_TAC THEN GEN_REWRITE_TAC I [FUN_EQ_THM] THEN + X_GEN_TAC `i:num` THEN REWRITE_TAC[] THEN + W(MP_TAC o PART_MATCH (lhand o rand) REAL_INTEGRAL_SUM o rand o snd) THEN + ANTS_TAC THENL + [REWRITE_TAC[FINITE_NUMSEG] THEN X_GEN_TAC `j:num` THEN DISCH_TAC THEN + SUBGOAL_THEN `?u v. u$k <= v$k /\ + (d:num->real^N->bool) j = interval[u,v]` + STRIP_ASSUME_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN + ASM_REWRITE_TAC[] THEN REWRITE_TAC[real_integrable_on] THEN + EXISTS_TAC `measure(interval[u:real^N,v])` THEN + MATCH_MP_TAC FUBINI_CLOSED_INTERVAL THEN ASM_REWRITE_TAC[]; + ALL_TAC] THEN + DISCH_THEN SUBST1_TAC THEN MATCH_MP_TAC SUM_EQ_NUMSEG THEN + X_GEN_TAC `j:num` THEN STRIP_TAC THEN REWRITE_TAC[] THEN + CONV_TAC SYM_CONV THEN MATCH_MP_TAC REAL_INTEGRAL_UNIQUE THEN + SUBGOAL_THEN `?u v. u$k <= v$k /\ + (d:num->real^N->bool) j = interval[u,v]` + STRIP_ASSUME_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN + ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC FUBINI_CLOSED_INTERVAL THEN ASM_REWRITE_TAC[]]);; + +let FUBINI_SIMPLE = prove + (`!k s:real^N->bool. + dimindex(:M) + 1 = dimindex(:N) /\ + 1 <= k /\ k <= dimindex(:N) /\ + bounded s /\ + measurable s /\ + (!t. measurable(slice k t s :real^M->bool)) /\ + (\t. measure (slice k t s :real^M->bool)) real_integrable_on (:real) + ==> measure s = + real_integral(:real)(\t. measure (slice k t s :real^M->bool))`, + REPEAT STRIP_TAC THEN ASM_CASES_TAC `s:real^N->bool = {}` THENL + [ASM_REWRITE_TAC[SLICE_EMPTY; MEASURE_EMPTY; REAL_INTEGRAL_0]; + ALL_TAC] THEN + FIRST_ASSUM(MP_TAC o MATCH_MP BOUNDED_SUBSET_CLOSED_INTERVAL) THEN + REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`a:real^N`; `b:real^N`] THEN DISCH_TAC THEN + SUBGOAL_THEN `~(interval[a:real^N,b] = {})` MP_TAC THENL + [ASM SET_TAC[]; REWRITE_TAC[INTERVAL_NE_EMPTY] THEN DISCH_TAC] THEN + MATCH_MP_TAC(REAL_ARITH `~(&0 < b - a) /\ ~(&0 < a - b) ==> a:real = b`) THEN + CONJ_TAC THEN MATCH_MP_TAC(MESON[] + `(!e. x - y = e ==> ~(&0 < e)) ==> ~(&0 < x - y)`) THEN + X_GEN_TAC `e:real` THEN REPEAT STRIP_TAC THENL + [MP_TAC(ISPECL [`k:num`; `s:real^N->bool`; `e / &2`] + FUBINI_SIMPLE_LEMMA) THEN + ASM_REWRITE_TAC[] THEN ASM_REAL_ARITH_TAC; + ALL_TAC] THEN + MP_TAC(ISPECL [`k:num`; `interval[a:real^N,b] DIFF s`; `e / &2`] + FUBINI_SIMPLE_LEMMA) THEN + ASM_REWRITE_TAC[NOT_IMP; GSYM CONJ_ASSOC] THEN + CONJ_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN + CONJ_TAC THENL [SIMP_TAC[BOUNDED_DIFF; BOUNDED_INTERVAL]; ALL_TAC] THEN + CONJ_TAC THENL + [ASM_SIMP_TAC[MEASURABLE_DIFF; MEASURABLE_INTERVAL]; ALL_TAC] THEN + ASM_SIMP_TAC[SLICE_DIFF] THEN + MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN CONJ_TAC THENL + [X_GEN_TAC `t:real` THEN MATCH_MP_TAC MEASURABLE_DIFF THEN + ASM_SIMP_TAC[SLICE_INTERVAL] THEN + MESON_TAC[MEASURABLE_EMPTY; MEASURABLE_INTERVAL]; + DISCH_TAC] THEN + SUBGOAL_THEN + `!t. measure(slice k t (interval[a:real^N,b]) DIFF + slice k t (s:real^N->bool) :real^M->bool) = + measure(slice k t (interval[a:real^N,b]):real^M->bool) - + measure(slice k t s :real^M->bool)` + (fun th -> REWRITE_TAC[th]) + THENL + [X_GEN_TAC `t:real` THEN MATCH_MP_TAC MEASURE_DIFF_SUBSET THEN + ASM_SIMP_TAC[SLICE_SUBSET] THEN + ASM_SIMP_TAC[SLICE_INTERVAL] THEN + MESON_TAC[MEASURABLE_EMPTY; MEASURABLE_INTERVAL]; + ALL_TAC] THEN + MP_TAC(ISPECL [`k:num`; `a:real^N`; `b:real^N`] FUBINI_CLOSED_INTERVAL) THEN + ASM_SIMP_TAC[] THEN DISCH_TAC THEN CONJ_TAC THENL + [MATCH_MP_TAC REAL_INTEGRABLE_SUB THEN ASM_MESON_TAC[real_integrable_on]; + ALL_TAC] THEN + REWRITE_TAC[REAL_NOT_LE] THEN + ASM_SIMP_TAC[MEASURE_DIFF_SUBSET; MEASURABLE_INTERVAL] THEN + W(MP_TAC o PART_MATCH (lhs o rand) REAL_INTEGRAL_SUB o rand o snd) THEN + ANTS_TAC THENL + [ASM_MESON_TAC[real_integrable_on]; DISCH_THEN SUBST1_TAC] THEN + FIRST_ASSUM(SUBST1_TAC o MATCH_MP REAL_INTEGRAL_UNIQUE) THEN + ASM_REAL_ARITH_TAC);; + +let FUBINI_SIMPLE_ALT = prove + (`!k s:real^N->bool. + dimindex(:M) + 1 = dimindex(:N) /\ + 1 <= k /\ k <= dimindex(:N) /\ + bounded s /\ + measurable s /\ + (!t. measurable(slice k t s :real^M->bool)) /\ + ((\t. measure (slice k t s :real^M->bool)) has_real_integral B) (:real) + ==> measure s = B`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC EQ_TRANS THEN EXISTS_TAC + `real_integral (:real) + (\t. measure (slice k t (s:real^N->bool) :real^M->bool))` THEN + CONJ_TAC THENL + [MATCH_MP_TAC FUBINI_SIMPLE THEN ASM_REWRITE_TAC[] THEN + ASM_MESON_TAC[real_integrable_on]; + MATCH_MP_TAC REAL_INTEGRAL_UNIQUE THEN ASM_REWRITE_TAC[]]);; + +let FUBINI_SIMPLE_COMPACT_STRONG = prove + (`!k s:real^N->bool. + dimindex(:M) + 1 = dimindex(:N) /\ + 1 <= k /\ k <= dimindex(:N) /\ + compact s /\ + ((\t. measure (slice k t s :real^M->bool)) has_real_integral B) (:real) + ==> measurable s /\ measure s = B`, + REPEAT STRIP_TAC THEN ASM_SIMP_TAC[MEASURABLE_COMPACT] THEN + MATCH_MP_TAC FUBINI_SIMPLE_ALT THEN + EXISTS_TAC `k:num` THEN ASM_REWRITE_TAC[] THEN + ASM_SIMP_TAC[COMPACT_IMP_BOUNDED; MEASURABLE_COMPACT] THEN + GEN_TAC THEN MATCH_MP_TAC MEASURABLE_COMPACT THEN + MATCH_MP_TAC COMPACT_SLICE THEN ASM_REWRITE_TAC[] THEN ASM_ARITH_TAC);; + +let FUBINI_SIMPLE_COMPACT = prove + (`!k s:real^N->bool. + dimindex(:M) + 1 = dimindex(:N) /\ + 1 <= k /\ k <= dimindex(:N) /\ + compact s /\ + ((\t. measure (slice k t s :real^M->bool)) has_real_integral B) (:real) + ==> measure s = B`, + REPEAT GEN_TAC THEN + DISCH_THEN(MP_TAC o MATCH_MP FUBINI_SIMPLE_COMPACT_STRONG) THEN SIMP_TAC[]);; + +let FUBINI_SIMPLE_CONVEX_STRONG = prove + (`!k s:real^N->bool. + dimindex(:M) + 1 = dimindex(:N) /\ + 1 <= k /\ k <= dimindex(:N) /\ + bounded s /\ convex s /\ + ((\t. measure (slice k t s :real^M->bool)) has_real_integral B) (:real) + ==> measurable s /\ measure s = B`, + REPEAT STRIP_TAC THEN ASM_SIMP_TAC[MEASURABLE_CONVEX] THEN + MATCH_MP_TAC FUBINI_SIMPLE_ALT THEN + EXISTS_TAC `k:num` THEN ASM_REWRITE_TAC[] THEN + ASM_SIMP_TAC[MEASURABLE_CONVEX] THEN + GEN_TAC THEN MATCH_MP_TAC MEASURABLE_CONVEX THEN CONJ_TAC THENL + [MATCH_MP_TAC CONVEX_SLICE; MATCH_MP_TAC BOUNDED_SLICE] THEN + ASM_REWRITE_TAC[] THEN ASM_ARITH_TAC);; + +let FUBINI_SIMPLE_CONVEX = prove + (`!k s:real^N->bool. + dimindex(:M) + 1 = dimindex(:N) /\ + 1 <= k /\ k <= dimindex(:N) /\ + bounded s /\ convex s /\ + ((\t. measure (slice k t s :real^M->bool)) has_real_integral B) (:real) + ==> measure s = B`, + REPEAT GEN_TAC THEN + DISCH_THEN(MP_TAC o MATCH_MP FUBINI_SIMPLE_CONVEX_STRONG) THEN SIMP_TAC[]);; + +let FUBINI_SIMPLE_OPEN_STRONG = prove + (`!k s:real^N->bool. + dimindex(:M) + 1 = dimindex(:N) /\ + 1 <= k /\ k <= dimindex(:N) /\ + bounded s /\ open s /\ + ((\t. measure (slice k t s :real^M->bool)) has_real_integral B) (:real) + ==> measurable s /\ measure s = B`, + REPEAT STRIP_TAC THEN ASM_SIMP_TAC[MEASURABLE_OPEN] THEN + MATCH_MP_TAC FUBINI_SIMPLE_ALT THEN + EXISTS_TAC `k:num` THEN ASM_REWRITE_TAC[] THEN + ASM_SIMP_TAC[MEASURABLE_OPEN] THEN + GEN_TAC THEN MATCH_MP_TAC MEASURABLE_OPEN THEN CONJ_TAC THENL + [MATCH_MP_TAC BOUNDED_SLICE; MATCH_MP_TAC OPEN_SLICE] THEN + ASM_REWRITE_TAC[] THEN ASM_ARITH_TAC);; + +let FUBINI_SIMPLE_OPEN = prove + (`!k s:real^N->bool. + dimindex(:M) + 1 = dimindex(:N) /\ + 1 <= k /\ k <= dimindex(:N) /\ + bounded s /\ open s /\ + ((\t. measure (slice k t s :real^M->bool)) has_real_integral B) (:real) + ==> measure s = B`, + REPEAT GEN_TAC THEN + DISCH_THEN(MP_TAC o MATCH_MP FUBINI_SIMPLE_OPEN_STRONG) THEN SIMP_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* Scaled integer, and hence rational, values are dense in the reals. *) +(* ------------------------------------------------------------------------- *) + +let REAL_OPEN_SET_RATIONAL = prove + (`!s. real_open s /\ ~(s = {}) ==> ?x. rational x /\ x IN s`, + REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[CONJ_SYM] THEN + MP_TAC(ISPEC `IMAGE lift s` OPEN_SET_RATIONAL_COORDINATES) THEN + ASM_REWRITE_TAC[GSYM REAL_OPEN; IMAGE_EQ_EMPTY; EXISTS_IN_IMAGE] THEN + SIMP_TAC[DIMINDEX_1; FORALL_1; GSYM drop; LIFT_DROP]);; + +let REAL_OPEN_RATIONAL = prove + (`!P. real_open {x | P x} /\ (?x. P x) ==> ?x. rational x /\ P x`, + REPEAT STRIP_TAC THEN + MP_TAC(SPEC `{x:real | P x}` REAL_OPEN_SET_RATIONAL) THEN + ASM_REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; IN_ELIM_THM] THEN ASM_MESON_TAC[]);; + +let REAL_OPEN_SET_EXISTS_RATIONAL = prove + (`!s. real_open s ==> ((?x. rational x /\ x IN s) <=> (?x. x IN s))`, + REPEAT STRIP_TAC THEN EQ_TAC THEN + ASM_MESON_TAC[REAL_OPEN_SET_RATIONAL; GSYM MEMBER_NOT_EMPTY]);; + +let REAL_OPEN_EXISTS_RATIONAL = prove + (`!P. real_open {x | P x} ==> ((?x. rational x /\ P x) <=> (?x. P x))`, + GEN_TAC THEN DISCH_THEN(MP_TAC o MATCH_MP REAL_OPEN_SET_EXISTS_RATIONAL) THEN + REWRITE_TAC[IN_ELIM_THM]);; + +(* ------------------------------------------------------------------------- *) +(* Hence a criterion for two functions to agree. *) +(* ------------------------------------------------------------------------- *) + +let CONTINUOUS_ON_CONST_DYADIC_RATIONALS = prove + (`!f:real^M->real^N a. + f continuous_on (:real^M) /\ + (!x. (!i. 1 <= i /\ i <= dimindex(:M) ==> integer(x$i)) ==> f(x) = a) /\ + (!x. f(x) = a ==> f(inv(&2) % x) = a) + ==> !x. f(x) = a`, + REPEAT GEN_TAC THEN STRIP_TAC THEN MP_TAC(ISPECL + [`f:real^M->real^N`; + `{ inv(&2 pow n) % x:real^M |n,x| + !i. 1 <= i /\ i <= dimindex(:M) ==> integer(x$i) }`; + `a:real^N`] CONTINUOUS_CONSTANT_ON_CLOSURE) THEN + ASM_REWRITE_TAC[FORALL_IN_GSPEC; CLOSURE_DYADIC_RATIONALS; IN_UNIV] THEN + DISCH_THEN MATCH_MP_TAC THEN + INDUCT_TAC THEN ASM_REWRITE_TAC[real_pow; REAL_INV_1; VECTOR_MUL_LID] THEN + ASM_SIMP_TAC[REAL_INV_MUL; GSYM VECTOR_MUL_ASSOC]);; + +let REAL_CONTINUOUS_ON_CONST_DYADIC_RATIONALS = prove + (`!f a. + f real_continuous_on (:real) /\ + (!x. integer(x) ==> f(x) = a) /\ + (!x. f(x) = a ==> f(x / &2) = a) + ==> !x. f(x) = a`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`lift o f o drop`; `lift a`] + CONTINUOUS_ON_CONST_DYADIC_RATIONALS) THEN + ASM_REWRITE_TAC[GSYM REAL_CONTINUOUS_ON; GSYM IMAGE_LIFT_UNIV] THEN + ASM_SIMP_TAC[o_THM; DIMINDEX_1; FORALL_1; GSYM drop; LIFT_EQ; DROP_CMUL; + REAL_ARITH `inv(&2) * x = x / &2`] THEN + ASM_MESON_TAC[LIFT_DROP]);; + +(* ------------------------------------------------------------------------- *) +(* Various sufficient conditions for additivity to imply linearity. *) +(* ------------------------------------------------------------------------- *) + +let CONTINUOUS_ADDITIVE_IMP_LINEAR = prove + (`!f:real^M->real^N. + f continuous_on (:real^M) /\ + (!x y. f(x + y) = f(x) + f(y)) + ==> linear f`, + GEN_TAC THEN STRIP_TAC THEN + SUBGOAL_THEN `(f:real^M->real^N) (vec 0) = vec 0` ASSUME_TAC THENL + [FIRST_ASSUM(MP_TAC o repeat (SPEC `vec 0:real^M`)) THEN + REWRITE_TAC[VECTOR_ADD_LID] THEN VECTOR_ARITH_TAC; + ALL_TAC] THEN + ASM_REWRITE_TAC[linear] THEN + ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN X_GEN_TAC `x:real^M` THEN + MP_TAC(ISPECL [`\c. norm((f:real^M->real^N)(c % x) - c % f(x))`; `&0`] + REAL_CONTINUOUS_ON_CONST_DYADIC_RATIONALS) THEN + REWRITE_TAC[NORM_EQ_0; VECTOR_SUB_EQ] THEN DISCH_THEN MATCH_MP_TAC THEN + REPEAT CONJ_TAC THENL + [RULE_ASSUM_TAC(REWRITE_RULE[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN]) THEN + RULE_ASSUM_TAC(REWRITE_RULE[IN_UNIV; WITHIN_UNIV]) THEN + REWRITE_TAC[REAL_CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN; IN_UNIV] THEN + GEN_TAC THEN GEN_REWRITE_TAC LAND_CONV [GSYM o_DEF] THEN + MATCH_MP_TAC REAL_CONTINUOUS_CONTINUOUS_WITHINREAL_COMPOSE THEN + SIMP_TAC[REAL_CONTINUOUS_NORM_WITHIN] THEN MATCH_MP_TAC CONTINUOUS_SUB THEN + ASM_SIMP_TAC[REWRITE_RULE[GSYM REAL_CONTINUOUS_CONTINUOUS1]CONTINUOUS_VMUL; + REAL_CONTINUOUS_WITHIN_ID; CONTINUOUS_AT_WITHIN; + REWRITE_RULE[o_DEF] CONTINUOUS_WITHINREAL_COMPOSE]; + MATCH_MP_TAC FORALL_INTEGER THEN CONJ_TAC THENL + [INDUCT_TAC THEN ASM_SIMP_TAC[VECTOR_MUL_LZERO; GSYM REAL_OF_NUM_SUC] THEN + ASM_REWRITE_TAC[VECTOR_ADD_RDISTRIB; VECTOR_MUL_LID]; + X_GEN_TAC `c:real` THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`c % x:real^M`; `--(c % x):real^M`]) THEN + ASM_REWRITE_TAC[VECTOR_ADD_RINV; VECTOR_MUL_LNEG; IMP_IMP] THEN + VECTOR_ARITH_TAC]; + X_GEN_TAC `c:real` THEN + FIRST_X_ASSUM(MP_TAC o funpow 2 (SPEC `c / &2 % x:real^M`)) THEN + REWRITE_TAC[VECTOR_ARITH `c / &2 % x + c / &2 % x:real^N = c % x`] THEN + REWRITE_TAC[IMP_IMP] THEN VECTOR_ARITH_TAC]);; + +let OSTROWSKI_THEOREM = prove + (`!f:real^M->real^N B s. + (!x y. f(x + y) = f(x) + f(y)) /\ + (!x. x IN s ==> norm(f x) <= B) /\ + measurable s /\ &0 < measure s + ==> linear f`, + REPEAT GEN_TAC THEN + REPLICATE_TAC 2 (DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + DISCH_THEN(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC o + MATCH_MP STEINHAUS) THEN + SUBGOAL_THEN `!x y. (f:real^M->real^N)(x - y) = f x - f y` ASSUME_TAC THENL + [ASM_MESON_TAC[VECTOR_ARITH `x - y:real^M = z <=> x = y + z`]; + ALL_TAC] THEN + SUBGOAL_THEN `!n x. &n % (f:real^M->real^N) x = f(&n % x)` ASSUME_TAC THENL + [INDUCT_TAC THENL + [ASM_MESON_TAC[VECTOR_SUB_REFL; VECTOR_MUL_LZERO]; + ASM_REWRITE_TAC[GSYM REAL_OF_NUM_SUC; VECTOR_ADD_RDISTRIB] THEN + REWRITE_TAC[VECTOR_MUL_LID]]; + ALL_TAC] THEN + MATCH_MP_TAC CONTINUOUS_ADDITIVE_IMP_LINEAR THEN ASM_REWRITE_TAC[] THEN + SUBGOAL_THEN `!x. norm(x) < d ==> norm((f:real^M->real^N) x) <= &2 * B` + ASSUME_TAC THENL + [X_GEN_TAC `z:real^M` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `z:real^M` o GEN_REWRITE_RULE I [SUBSET]) THEN + ASM_REWRITE_TAC[IN_BALL_0] THEN SPEC_TAC(`z:real^M`,`z:real^M`) THEN + ASM_REWRITE_TAC[FORALL_IN_GSPEC] THEN REWRITE_TAC[IN_ELIM_THM] THEN + REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN(ANTE_RES_THEN MP_TAC)) THEN + CONV_TAC NORM_ARITH; + ALL_TAC] THEN + REWRITE_TAC[continuous_on; IN_UNIV; dist] THEN + MAP_EVERY X_GEN_TAC [`x:real^M`; `e:real`] THEN DISCH_TAC THEN + MP_TAC(SPEC `e:real` REAL_ARCH) THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `n:num` MP_TAC o SPEC `max (&1) (&2 * B)`) THEN + ASM_CASES_TAC `n = 0` THEN ASM_REWRITE_TAC[] THENL + [REAL_ARITH_TAC; DISCH_TAC] THEN + EXISTS_TAC `d / &n` THEN + ASM_SIMP_TAC[REAL_LT_DIV; REAL_OF_NUM_LT; LE_1] THEN + X_GEN_TAC `y:real^M` THEN DISCH_TAC THEN + SUBGOAL_THEN `norm(&n % (f:real^M->real^N)(y - x)) <= &2 * B` MP_TAC THENL + [ASM_REWRITE_TAC[] THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + SIMP_TAC[NORM_MUL; REAL_ABS_NUM] THEN ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN + ASM_SIMP_TAC[GSYM REAL_LT_RDIV_EQ; REAL_OF_NUM_LT; LE_1]; + SIMP_TAC[NORM_MUL; REAL_ABS_NUM] THEN ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN + ASM_SIMP_TAC[GSYM REAL_LE_RDIV_EQ; REAL_OF_NUM_LT; LE_1] THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] REAL_LET_TRANS) THEN + ASM_SIMP_TAC[REAL_LT_LDIV_EQ; REAL_OF_NUM_LT; LE_1] THEN + ASM_REAL_ARITH_TAC]);; + +let MEASURABLE_ADDITIVE_IMP_LINEAR = prove + (`!f:real^M->real^N. + f measurable_on (:real^M) /\ (!x y. f(x + y) = f(x) + f(y)) + ==> linear f`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC OSTROWSKI_THEOREM THEN + FIRST_X_ASSUM(MP_TAC o MATCH_MP MEASURABLE_ON_NORM) THEN + REWRITE_TAC[MEASURABLE_ON_PREIMAGE_OPEN_HALFSPACE_COMPONENT_LE] THEN + REWRITE_TAC[DIMINDEX_1; FORALL_1; GSYM drop; LIFT_DROP] THEN + DISCH_TAC THEN + ASM_CASES_TAC `!b. negligible {x | norm((f:real^M->real^N) x) <= b}` THENL + [FIRST_X_ASSUM(MP_TAC o MATCH_MP NEGLIGIBLE_COUNTABLE_UNIONS o + GEN `n:num` o SPEC `&n:real`) THEN + REWRITE_TAC[UNIONS_GSPEC; IN_ELIM_THM; IN_UNIV; REAL_ARCH_SIMPLE] THEN + SIMP_TAC[SET_RULE `{x | T} = (:real^M)`; OPEN_NOT_NEGLIGIBLE; + OPEN_UNIV; UNIV_NOT_EMPTY]; + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [NOT_FORALL_THM]) THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `B:real` THEN + ONCE_REWRITE_TAC[NEGLIGIBLE_ON_INTERVALS] THEN + REWRITE_TAC[NOT_FORALL_THM; LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`a:real^M`; `b:real^M`] THEN DISCH_TAC THEN + EXISTS_TAC `{x:real^M | norm(f x:real^N) <= B} INTER interval[a,b]` THEN + ASM_SIMP_TAC[IN_ELIM_THM; IN_INTER] THEN + MATCH_MP_TAC(MESON[MEASURABLE_MEASURE_POS_LT] + `measurable s /\ ~negligible s ==> measurable s /\ &0 < measure s`) THEN + ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC MEASURABLE_LEGESGUE_MEASURABLE_INTER_MEASURABLE THEN + ASM_REWRITE_TAC[MEASURABLE_INTERVAL]]);; + +let REAL_CONTINUOUS_ADDITIVE_IMP_LINEAR = prove + (`!f. f real_continuous_on (:real) /\ + (!x y. f(x + y) = f(x) + f(y)) + ==> !a x. f(a * x) = a * f(x)`, + GEN_TAC THEN STRIP_TAC THEN + MP_TAC(ISPEC `lift o f o drop` CONTINUOUS_ADDITIVE_IMP_LINEAR) THEN + ASM_REWRITE_TAC[GSYM REAL_CONTINUOUS_ON; GSYM IMAGE_LIFT_UNIV] THEN + ASM_REWRITE_TAC[linear; GSYM FORALL_DROP; o_THM; DROP_ADD; LIFT_DROP; + DROP_CMUL; GSYM LIFT_ADD; GSYM LIFT_CMUL; LIFT_EQ]);; + +(* ------------------------------------------------------------------------- *) +(* Extending a continuous function in a periodic way. *) +(* ------------------------------------------------------------------------- *) + +let REAL_CONTINUOUS_FLOOR = prove + (`!x. ~(integer x) ==> floor real_continuous (atreal x)`, + REPEAT STRIP_TAC THEN REWRITE_TAC[real_continuous_atreal] THEN + X_GEN_TAC `e:real` THEN DISCH_TAC THEN + EXISTS_TAC `min (x - floor x) ((floor x + &1) - x)` THEN + ASM_REWRITE_TAC[REAL_LT_MIN; REAL_SUB_LT; REAL_FLOOR_LT; FLOOR] THEN + REPEAT STRIP_TAC THEN + MATCH_MP_TAC(REAL_ARITH `&0 < e /\ x = y ==> abs(x - y) < e`) THEN + ASM_REWRITE_TAC[GSYM FLOOR_UNIQUE; FLOOR] THEN + MP_TAC(ISPEC `x:real` FLOOR) THEN ASM_REAL_ARITH_TAC);; + +let REAL_CONTINUOUS_FRAC = prove + (`!x. ~(integer x) ==> frac real_continuous (atreal x)`, + REPEAT STRIP_TAC THEN GEN_REWRITE_TAC LAND_CONV [GSYM ETA_AX] THEN + REWRITE_TAC[FRAC_FLOOR] THEN MATCH_MP_TAC REAL_CONTINUOUS_SUB THEN + ASM_SIMP_TAC[REAL_CONTINUOUS_FLOOR; REAL_CONTINUOUS_AT_ID]);; + +let REAL_CONTINUOUS_ON_COMPOSE_FRAC = prove + (`!f. f real_continuous_on real_interval[&0,&1] /\ f(&1) = f(&0) + ==> (f o frac) real_continuous_on (:real)`, + REPEAT STRIP_TAC THEN + UNDISCH_TAC `f real_continuous_on real_interval[&0,&1]` THEN + REWRITE_TAC[REAL_CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN; WITHINREAL_UNIV] THEN + DISCH_TAC THEN X_GEN_TAC `x:real` THEN DISCH_TAC THEN + ASM_CASES_TAC `integer x` THENL + [ALL_TAC; + MATCH_MP_TAC REAL_CONTINUOUS_ATREAL_COMPOSE THEN + ASM_SIMP_TAC[REAL_CONTINUOUS_FRAC] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE LAND_CONV [IN_REAL_INTERVAL] o + SPEC `frac x`) THEN + ASM_SIMP_TAC[FLOOR_FRAC; REAL_LT_IMP_LE] THEN + REWRITE_TAC[real_continuous_atreal; real_continuous_withinreal] THEN + MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `e:real` THEN + ASM_CASES_TAC `&0 < e` THEN ASM_REWRITE_TAC[IN_REAL_INTERVAL] THEN + DISCH_THEN(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `min d (min (frac x) (&1 - frac x))` THEN + ASM_SIMP_TAC[REAL_LT_MIN; REAL_SUB_LT; FLOOR_FRAC; REAL_FRAC_POS_LT] THEN + REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_REAL_ARITH_TAC] THEN + ASM_SIMP_TAC[real_continuous_atreal; REAL_FRAC_ZERO; REAL_FLOOR_REFL] THEN + X_GEN_TAC `e:real` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE (BINDER_CONV o LAND_CONV) + [IN_REAL_INTERVAL]) THEN + DISCH_THEN(fun th -> MP_TAC(SPEC `&1` th) THEN MP_TAC(SPEC `&0` th)) THEN + REWRITE_TAC[REAL_LE_REFL; REAL_POS] THEN + REWRITE_TAC[IMP_IMP; real_continuous_withinreal; AND_FORALL_THM] THEN + DISCH_THEN(MP_TAC o SPEC `e:real`) THEN + ASM_REWRITE_TAC[IN_REAL_INTERVAL] THEN + DISCH_THEN(CONJUNCTS_THEN2 (X_CHOOSE_THEN `d1:real` STRIP_ASSUME_TAC) + (X_CHOOSE_THEN `d2:real` STRIP_ASSUME_TAC)) THEN + EXISTS_TAC `min (&1) (min d1 d2)` THEN + ASM_REWRITE_TAC[REAL_LT_01; REAL_LT_MIN; o_DEF] THEN + X_GEN_TAC `y:real` THEN STRIP_TAC THEN + DISJ_CASES_TAC(REAL_ARITH `x <= y \/ y < x`) THENL + [SUBGOAL_THEN `floor y = floor x` ASSUME_TAC THENL + [REWRITE_TAC[GSYM FLOOR_UNIQUE; FLOOR] THEN + ASM_SIMP_TAC[REAL_FLOOR_REFL] THEN ASM_REAL_ARITH_TAC; + ASM_SIMP_TAC[FRAC_FLOOR; REAL_FLOOR_REFL; REAL_SUB_REFL] THEN + FIRST_X_ASSUM(fun th -> MATCH_MP_TAC th THEN ASM_REAL_ARITH_TAC)]; + SUBGOAL_THEN `floor y = floor x - &1` ASSUME_TAC THENL + [REWRITE_TAC[GSYM FLOOR_UNIQUE; FLOOR] THEN + ASM_SIMP_TAC[REAL_FLOOR_REFL; INTEGER_CLOSED] THEN ASM_REAL_ARITH_TAC; + ASM_SIMP_TAC[FRAC_FLOOR; REAL_FLOOR_REFL; REAL_SUB_REFL] THEN + FIRST_X_ASSUM(fun th -> MATCH_MP_TAC th THEN ASM_REAL_ARITH_TAC)]]);; + +let REAL_TIETZE_PERIODIC_INTERVAL = prove + (`!f a b. + f real_continuous_on real_interval[a,b] /\ f(a) = f(b) + ==> ?g. g real_continuous_on (:real) /\ + (!x. x IN real_interval[a,b] ==> g(x) = f(x)) /\ + (!x. g(x + (b - a)) = g x)`, + REPEAT STRIP_TAC THEN DISJ_CASES_TAC(REAL_ARITH `b:real <= a \/ a < b`) THENL + [EXISTS_TAC `\x:real. (f:real->real) a` THEN + REWRITE_TAC[IN_REAL_INTERVAL; REAL_CONTINUOUS_ON_CONST] THEN + ASM_MESON_TAC[REAL_LE_TRANS; REAL_LE_ANTISYM]; + EXISTS_TAC `(f:real->real) o (\y. a + (b - a) * y) o frac o + (\x. (x - a) / (b - a))` THEN + REWRITE_TAC[o_THM] THEN REPEAT CONJ_TAC THENL + [REWRITE_TAC[o_ASSOC] THEN MATCH_MP_TAC REAL_CONTINUOUS_ON_COMPOSE THEN + SIMP_TAC[real_div; REAL_CONTINUOUS_ON_RMUL; REAL_CONTINUOUS_ON_SUB; + REAL_CONTINUOUS_ON_CONST; REAL_CONTINUOUS_ON_ID] THEN + MATCH_MP_TAC REAL_CONTINUOUS_ON_SUBSET THEN EXISTS_TAC `(:real)` THEN + REWRITE_TAC[SUBSET_UNIV] THEN + MATCH_MP_TAC REAL_CONTINUOUS_ON_COMPOSE_FRAC THEN + ASM_SIMP_TAC[o_THM; REAL_MUL_RZERO; REAL_MUL_RID; REAL_SUB_ADD2; + REAL_ADD_RID] THEN + MATCH_MP_TAC REAL_CONTINUOUS_ON_COMPOSE THEN + SIMP_TAC[REAL_CONTINUOUS_ON_LMUL; REAL_CONTINUOUS_ON_ADD; + REAL_CONTINUOUS_ON_CONST; REAL_CONTINUOUS_ON_ID] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + REAL_CONTINUOUS_ON_SUBSET)) THEN + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; IN_REAL_INTERVAL] THEN + ASM_SIMP_TAC[REAL_LE_ADDR; REAL_LE_MUL; REAL_LT_IMP_LE; REAL_SUB_LT] THEN + REWRITE_TAC[REAL_ARITH + `a + (b - a) * x <= b <=> &0 <= (b - a) * (&1 - x)`] THEN + ASM_SIMP_TAC[REAL_LE_ADDR; REAL_LE_MUL; REAL_LT_IMP_LE; REAL_SUB_LE]; + X_GEN_TAC `x:real` THEN REWRITE_TAC[IN_REAL_INTERVAL] THEN + STRIP_TAC THEN ASM_CASES_TAC `x:real = b` THENL + [ASM_SIMP_TAC[REAL_DIV_REFL; REAL_LT_IMP_NZ; REAL_SUB_LT] THEN + ASM_REWRITE_TAC[FRAC_NUM; REAL_MUL_RZERO; REAL_ADD_RID]; + SUBGOAL_THEN `frac((x - a) / (b - a)) = (x - a) / (b - a)` + SUBST1_TAC THENL + [REWRITE_TAC[REAL_FRAC_EQ] THEN + ASM_SIMP_TAC[REAL_LE_RDIV_EQ; REAL_LT_LDIV_EQ; REAL_SUB_LT] THEN + ASM_REAL_ARITH_TAC; + AP_TERM_TAC THEN UNDISCH_TAC `a:real < b` THEN CONV_TAC REAL_FIELD]]; + ASM_SIMP_TAC[REAL_FIELD + `a < b ==> ((x + b - a) - a) / (b - a) = &1 + (x - a) / (b - a)`] THEN + REWRITE_TAC[REAL_FRAC_ADD; FRAC_NUM; FLOOR_FRAC; REAL_ADD_LID]]]);; + +(* ------------------------------------------------------------------------- *) +(* A variant of REAL_CONTINUOUS_ADDITIVE_IMP_LINEAR for intervals. *) +(* ------------------------------------------------------------------------- *) + +let REAL_CONTINUOUS_ADDITIVE_EXTEND = prove + (`!f. f real_continuous_on real_interval[&0,&1] /\ + (!x y. &0 <= x /\ &0 <= y /\ x + y <= &1 + ==> f(x + y) = f(x) + f(y)) + ==> ?g. g real_continuous_on (:real) /\ + (!x y. g(x + y) = g(x) + g(y)) /\ + (!x. x IN real_interval[&0,&1] ==> g x = f x)`, + REPEAT STRIP_TAC THEN SUBGOAL_THEN `f(&0) = &0` ASSUME_TAC THENL + [FIRST_ASSUM(MP_TAC o ISPECL [`&0`; `&0`]) THEN + REWRITE_TAC[REAL_ADD_LID] THEN REAL_ARITH_TAC; + ALL_TAC] THEN + EXISTS_TAC `\x. f(&1) * floor(x) + f(frac x)` THEN + REWRITE_TAC[] THEN REPEAT CONJ_TAC THENL + [UNDISCH_TAC `f real_continuous_on real_interval[&0,&1]` THEN + REWRITE_TAC[REAL_CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN; WITHINREAL_UNIV] THEN + DISCH_TAC THEN X_GEN_TAC `x:real` THEN DISCH_TAC THEN + ASM_CASES_TAC `integer x` THENL + [ALL_TAC; + MATCH_MP_TAC REAL_CONTINUOUS_ADD THEN CONJ_TAC THEN + ASM_SIMP_TAC[REAL_CONTINUOUS_LMUL; REAL_CONTINUOUS_FLOOR; ETA_AX] THEN + MATCH_MP_TAC(REWRITE_RULE[o_DEF] REAL_CONTINUOUS_ATREAL_COMPOSE) THEN + ASM_SIMP_TAC[REAL_CONTINUOUS_FRAC] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE LAND_CONV [IN_REAL_INTERVAL] o + SPEC `frac x`) THEN + ASM_SIMP_TAC[FLOOR_FRAC; REAL_LT_IMP_LE] THEN + REWRITE_TAC[real_continuous_atreal; real_continuous_withinreal] THEN + MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `e:real` THEN + ASM_CASES_TAC `&0 < e` THEN ASM_REWRITE_TAC[IN_REAL_INTERVAL] THEN + DISCH_THEN(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `min d (min (frac x) (&1 - frac x))` THEN + ASM_SIMP_TAC[REAL_LT_MIN; REAL_SUB_LT; FLOOR_FRAC; REAL_FRAC_POS_LT] THEN + REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_REAL_ARITH_TAC] THEN + ASM_SIMP_TAC[real_continuous_atreal; REAL_FRAC_ZERO; REAL_FLOOR_REFL] THEN + X_GEN_TAC `e:real` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE (BINDER_CONV o LAND_CONV) + [IN_REAL_INTERVAL]) THEN + DISCH_THEN(fun th -> MP_TAC(SPEC `&1` th) THEN MP_TAC(SPEC `&0` th)) THEN + REWRITE_TAC[REAL_LE_REFL; REAL_POS] THEN + REWRITE_TAC[IMP_IMP; real_continuous_withinreal; AND_FORALL_THM] THEN + DISCH_THEN(MP_TAC o SPEC `e:real`) THEN + ASM_REWRITE_TAC[IN_REAL_INTERVAL] THEN + DISCH_THEN(CONJUNCTS_THEN2 (X_CHOOSE_THEN `d1:real` STRIP_ASSUME_TAC) + (X_CHOOSE_THEN `d2:real` STRIP_ASSUME_TAC)) THEN + EXISTS_TAC `min (&1) (min d1 d2)` THEN + ASM_REWRITE_TAC[REAL_LT_01; REAL_LT_MIN] THEN + X_GEN_TAC `y:real` THEN STRIP_TAC THEN + DISJ_CASES_TAC(REAL_ARITH `x <= y \/ y < x`) THENL + [SUBGOAL_THEN `floor y = floor x` ASSUME_TAC THENL + [REWRITE_TAC[GSYM FLOOR_UNIQUE; FLOOR] THEN + ASM_SIMP_TAC[REAL_FLOOR_REFL] THEN ASM_REAL_ARITH_TAC; + ASM_SIMP_TAC[FRAC_FLOOR; REAL_FLOOR_REFL] THEN + REWRITE_TAC[REAL_ARITH `(a + x) - (a + &0) = x - &0`] THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REAL_ARITH_TAC]; + SUBGOAL_THEN `floor y = floor x - &1` ASSUME_TAC THENL + [REWRITE_TAC[GSYM FLOOR_UNIQUE; FLOOR] THEN + ASM_SIMP_TAC[REAL_FLOOR_REFL; INTEGER_CLOSED] THEN ASM_REAL_ARITH_TAC; + ASM_SIMP_TAC[FRAC_FLOOR; REAL_FLOOR_REFL] THEN + REWRITE_TAC[REAL_ARITH `(f1 * (x - &1) + f) - (f1 * x + &0) = + f - f1`] THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REAL_ARITH_TAC]]; + REPEAT GEN_TAC THEN REWRITE_TAC[REAL_FLOOR_ADD; REAL_FRAC_ADD] THEN + COND_CASES_TAC THEN + ASM_SIMP_TAC[REAL_LT_IMP_LE; FLOOR_FRAC; REAL_LE_ADD] THENL + [REAL_ARITH_TAC; ALL_TAC] THEN + REWRITE_TAC[REAL_ARITH + `f1 * ((x + y) + &1) + g = (f1 * x + z) + f1 * y + h <=> + f1 / &2 + g / &2 = z / &2 + h / &2`] THEN + SUBGOAL_THEN + `!t. &0 <= t /\ t <= &1 ==> f(t) / &2 = f(t / &2)` + ASSUME_TAC THENL + [GEN_TAC THEN FIRST_ASSUM(MP_TAC o ISPECL [`t / &2`; `t / &2`]) THEN + REWRITE_TAC[REAL_HALF] THEN REAL_ARITH_TAC; + ALL_TAC] THEN + ASM_SIMP_TAC[REAL_POS; REAL_LE_REFL; FLOOR_FRAC; REAL_LT_IMP_LE; + REAL_ARITH `~(x + y < &1) ==> &0 <= (x + y) - &1`; + REAL_ARITH `x < &1 /\ y < &1 ==> (x + y) - &1 <= &1`] THEN + MATCH_MP_TAC(MESON[] + `f(a + b) = f a + f b /\ f(c + d) = f(c) + f(d) /\ a + b = c + d + ==> (f:real->real)(a) + f(b) = f(c) + f(d)`) THEN + REPEAT CONJ_TAC THEN TRY REAL_ARITH_TAC THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN + MAP_EVERY (MP_TAC o C SPEC FLOOR_FRAC) [`x:real`; `y:real`] THEN + ASM_REAL_ARITH_TAC; + GEN_TAC THEN REWRITE_TAC[IN_REAL_INTERVAL] THEN ASM_CASES_TAC `x = &1` THEN + ASM_REWRITE_TAC[FLOOR_NUM; FRAC_NUM; REAL_MUL_RID; REAL_ADD_RID] THEN + STRIP_TAC THEN SUBGOAL_THEN `floor x = &0` ASSUME_TAC THENL + [ASM_REWRITE_TAC[GSYM FLOOR_UNIQUE; INTEGER_CLOSED]; + ASM_REWRITE_TAC[FRAC_FLOOR; REAL_SUB_RZERO]] THEN + ASM_REAL_ARITH_TAC]);; + +let REAL_CONTINUOUS_ADDITIVE_IMP_LINEAR_INTERVAL = prove + (`!f b. (f ---> &0) (atreal (&0) within {x | &0 <= x}) /\ + (!x y. &0 <= x /\ &0 <= y /\ x + y <= b ==> f(x + y) = f(x) + f(y)) + ==> !a x. &0 <= x /\ x <= b /\ + &0 <= a * x /\ a * x <= b + ==> f(a * x) = a * f(x)`, + SUBGOAL_THEN + `!f. (f ---> &0) (atreal (&0) within {x | &0 <= x}) /\ + (!x y. &0 <= x /\ &0 <= y /\ x + y <= &1 ==> f(x + y) = f(x) + f(y)) + ==> !a x. &0 <= x /\ x <= &1 /\ &0 <= a * x /\ a * x <= &1 + ==> f(a * x) = a * f(x)` + ASSUME_TAC THENL + [SUBGOAL_THEN + `!f. f real_continuous_on real_interval[&0,&1] /\ + (!x y. &0 <= x /\ &0 <= y /\ x + y <= &1 ==> f(x + y) = f(x) + f(y)) + ==> !a x. &0 <= x /\ x <= &1 /\ &0 <= a * x /\ a * x <= &1 + ==> f(a * x) = a * f(x)` + (fun th -> GEN_TAC THEN STRIP_TAC THEN MATCH_MP_TAC th) THENL + [REPEAT STRIP_TAC THEN + MP_TAC(ISPEC `f:real->real` REAL_CONTINUOUS_ADDITIVE_EXTEND) THEN + ASM_REWRITE_TAC[IN_REAL_INTERVAL] THEN + DISCH_THEN(X_CHOOSE_THEN `g:real->real` STRIP_ASSUME_TAC) THEN + MP_TAC(ISPEC `g:real->real` REAL_CONTINUOUS_ADDITIVE_IMP_LINEAR) THEN + ASM_MESON_TAC[]; + ASM_REWRITE_TAC[real_continuous_on; IN_REAL_INTERVAL] THEN + X_GEN_TAC `x:real` THEN STRIP_TAC THEN + X_GEN_TAC `e:real` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [REALLIM_WITHINREAL]) THEN + DISCH_THEN(MP_TAC o SPEC `e:real`) THEN + ASM_REWRITE_TAC[REAL_SUB_RZERO] THEN REWRITE_TAC[IN_REAL_INTERVAL] THEN + DISCH_THEN(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `d:real` THEN ASM_SIMP_TAC[REAL_LT_MUL] THEN + X_GEN_TAC `y:real` THEN STRIP_TAC THEN + REPEAT_TCL DISJ_CASES_THEN ASSUME_TAC + (REAL_ARITH `y = x \/ y < x \/ x < y`) THENL + [ASM_REWRITE_TAC[REAL_SUB_REFL; REAL_ABS_NUM]; + SUBGOAL_THEN `(f:real->real)(y + (x - y)) = f(y) + f(x - y)` + MP_TAC THENL + [FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REAL_ARITH_TAC; + REWRITE_TAC[REAL_SUB_ADD2] THEN DISCH_THEN SUBST1_TAC THEN + REWRITE_TAC[REAL_ADD_SUB2; REAL_ABS_NEG] THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN + REWRITE_TAC[IN_ELIM_THM] THEN ASM_REAL_ARITH_TAC]; + SUBGOAL_THEN `(f:real->real)(x + (y - x)) = f(x) + f(y - x)` + MP_TAC THENL + [FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REAL_ARITH_TAC; + REWRITE_TAC[REAL_SUB_ADD2] THEN DISCH_THEN SUBST1_TAC THEN + REWRITE_TAC[REAL_ADD_SUB] THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + REWRITE_TAC[IN_ELIM_THM] THEN ASM_REAL_ARITH_TAC]]]; + REPEAT GEN_TAC THEN STRIP_TAC THEN REPEAT_TCL DISJ_CASES_THEN ASSUME_TAC + (REAL_ARITH `b < &0 \/ b = &0 \/ &0 < b`) + THENL + [ASM_REAL_ARITH_TAC; + ASM_SIMP_TAC[REAL_ARITH + `a <= x /\ x <= a /\ a <= y /\ y <= a <=> x = a /\ y = a`] THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`&0`; `&0`]) THEN + ASM_REWRITE_TAC[REAL_ADD_LID; REAL_LE_REFL] THEN CONV_TAC REAL_RING; + ALL_TAC] THEN + FIRST_X_ASSUM(MP_TAC o ISPEC `(\x. f(b * x)):real->real`) THEN + REWRITE_TAC[] THEN ANTS_TAC THENL + [ALL_TAC; + MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `a:real` THEN + DISCH_THEN(fun th -> X_GEN_TAC `x:real` THEN STRIP_TAC THEN + MP_TAC(ISPEC `x / b:real` th)) THEN + ASM_SIMP_TAC[REAL_FIELD `&0 < b ==> b * a * x / b = a * x`; + REAL_DIV_LMUL; REAL_LT_IMP_NZ] THEN + DISCH_THEN MATCH_MP_TAC THEN + REWRITE_TAC[REAL_ARITH `a * x / b:real = (a * x) / b`] THEN + ASM_SIMP_TAC[REAL_LE_RDIV_EQ; REAL_LE_LDIV_EQ] THEN + ASM_REAL_ARITH_TAC] THEN + CONJ_TAC THENL + [ALL_TAC; + REPEAT STRIP_TAC THEN REWRITE_TAC[REAL_ADD_LDISTRIB] THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_SIMP_TAC[REAL_ARITH `b * x + b * y <= b <=> &0 <= b * (&1 - (x + y))`; + REAL_LE_MUL; REAL_LT_IMP_LE; REAL_SUB_LE]] THEN + REWRITE_TAC[REALLIM_WITHINREAL] THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [REALLIM_WITHINREAL]) THEN + DISCH_THEN(MP_TAC o SPEC `e:real`) THEN ASM_REWRITE_TAC[REAL_SUB_RZERO] THEN + REWRITE_TAC[REAL_SUB_RZERO; IN_ELIM_THM] THEN + DISCH_THEN(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `d / b:real` THEN ASM_SIMP_TAC[REAL_LT_DIV] THEN + REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_SIMP_TAC[REAL_LE_MUL; REAL_LT_IMP_LE; REAL_ABS_MUL] THEN + ASM_SIMP_TAC[REAL_ARITH `&0 < b ==> abs b * x = x * b`] THEN + ASM_SIMP_TAC[REAL_LT_MUL; GSYM REAL_LT_RDIV_EQ]]);; + +(* ------------------------------------------------------------------------- *) +(* More Steinhaus variants. *) +(* ------------------------------------------------------------------------- *) + +let STEINHAUS_TRIVIAL = prove + (`!s e. ~(negligible s) /\ &0 < e + ==> ?x y:real^N. x IN s /\ y IN s /\ ~(x = y) /\ norm(x - y) < e`, + REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN + ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN REWRITE_TAC[] THEN DISCH_TAC THEN + MATCH_MP_TAC NEGLIGIBLE_COUNTABLE THEN + MATCH_MP_TAC DISCRETE_IMP_COUNTABLE THEN + ASM_MESON_TAC[REAL_NOT_LT]);; + +let REAL_STEINHAUS = prove + (`!s. real_measurable s /\ &0 < real_measure s + ==> ?d. &0 < d /\ + real_interval(--d,d) SUBSET {x - y | x IN s /\ y IN s}`, + GEN_TAC THEN SIMP_TAC[IMP_CONJ; REAL_MEASURE_MEASURE] THEN + REWRITE_TAC[IMP_IMP; REAL_MEASURABLE_MEASURABLE] THEN + DISCH_THEN(MP_TAC o MATCH_MP STEINHAUS) THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `d:real` THEN + REWRITE_TAC[SUBSET; BALL_INTERVAL; IN_INTERVAL_1; IN_REAL_INTERVAL] THEN + REWRITE_TAC[SET_RULE `{g x y | x IN IMAGE f s /\ y IN IMAGE f t} = + {g (f x) (f y) | x IN s /\ y IN t}`] THEN + REWRITE_TAC[GSYM LIFT_SUB] THEN + REWRITE_TAC[SET_RULE `{lift(f x y) | P x y} = IMAGE lift {f x y | P x y}`; + IN_IMAGE_LIFT_DROP; GSYM FORALL_DROP] THEN + REWRITE_TAC[DROP_SUB; DROP_VEC; LIFT_DROP; DROP_ADD] THEN + REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_REAL_ARITH_TAC);; + +(* ------------------------------------------------------------------------- *) +(* Bernstein polynomials. *) +(* ------------------------------------------------------------------------- *) + +let bernstein = new_definition + `bernstein n k x = &(binom(n,k)) * x pow k * (&1 - x) pow (n - k)`;; + +let BERNSTEIN_CONV = + GEN_REWRITE_CONV I [bernstein] THENC + COMB2_CONV (RAND_CONV(RAND_CONV NUM_BINOM_CONV)) + (RAND_CONV(RAND_CONV NUM_SUB_CONV)) THENC + REAL_POLY_CONV;; + +(* ------------------------------------------------------------------------- *) +(* Lemmas about Bernstein polynomials. *) +(* ------------------------------------------------------------------------- *) + +let BERNSTEIN_POS = prove + (`!n k x. &0 <= x /\ x <= &1 ==> &0 <= bernstein n k x`, + REPEAT STRIP_TAC THEN REWRITE_TAC[bernstein] THEN + MATCH_MP_TAC REAL_LE_MUL THEN REWRITE_TAC[REAL_POS] THEN + MATCH_MP_TAC REAL_LE_MUL THEN CONJ_TAC THEN + MATCH_MP_TAC REAL_POW_LE THEN ASM_REAL_ARITH_TAC);; + +let SUM_BERNSTEIN = prove + (`!n. sum (0..n) (\k. bernstein n k x) = &1`, + REWRITE_TAC[bernstein; GSYM REAL_BINOMIAL_THEOREM] THEN + REWRITE_TAC[REAL_SUB_ADD2; REAL_POW_ONE]);; + +let BERNSTEIN_LEMMA = prove + (`!n x. sum(0..n) (\k. (&k - &n * x) pow 2 * bernstein n k x) = + &n * x * (&1 - x)`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN + `!x y. sum(0..n) (\k. &(binom(n,k)) * x pow k * y pow (n - k)) = + (x + y) pow n` + (LABEL_TAC "0") THENL [ASM_REWRITE_TAC[REAL_BINOMIAL_THEOREM]; ALL_TAC] THEN + SUBGOAL_THEN + `!x y. sum(0..n) (\k. &k * &(binom(n,k)) * x pow (k - 1) * y pow (n - k)) = + &n * (x + y) pow (n - 1)` + (LABEL_TAC "1") THENL + [REPEAT GEN_TAC THEN MATCH_MP_TAC REAL_DERIVATIVE_UNIQUE_ATREAL THEN + MAP_EVERY EXISTS_TAC + [`\x. sum(0..n) (\k. &(binom(n,k)) * x pow k * y pow (n - k))`; + `x:real`] THEN + CONJ_TAC THENL + [MATCH_MP_TAC HAS_REAL_DERIVATIVE_SUM THEN REWRITE_TAC[FINITE_NUMSEG]; + ASM_REWRITE_TAC[]] THEN + REPEAT STRIP_TAC THEN REAL_DIFF_TAC THEN CONV_TAC REAL_RING; + ALL_TAC] THEN + SUBGOAL_THEN + `!x y. sum(0..n) + (\k. &k * &(k - 1) * &(binom(n,k)) * x pow (k - 2) * y pow (n - k)) = + &n * &(n - 1) * (x + y) pow (n - 2)` + (LABEL_TAC "2") THENL + [REPEAT GEN_TAC THEN MATCH_MP_TAC REAL_DERIVATIVE_UNIQUE_ATREAL THEN + MAP_EVERY EXISTS_TAC + [`\x. sum(0..n) (\k. &k * &(binom(n,k)) * x pow (k - 1) * y pow (n - k))`; + `x:real`] THEN + CONJ_TAC THENL + [MATCH_MP_TAC HAS_REAL_DERIVATIVE_SUM THEN REWRITE_TAC[FINITE_NUMSEG]; + ASM_REWRITE_TAC[]] THEN + REPEAT STRIP_TAC THEN REAL_DIFF_TAC THEN + REWRITE_TAC[ARITH_RULE `n - 1 - 1 = n - 2`] THEN CONV_TAC REAL_RING; + ALL_TAC] THEN + REWRITE_TAC[REAL_ARITH + `(a - b) pow 2 * x = + a * (a - &1) * x + (&1 - &2 * b) * a * x + b * b * x`] THEN + REWRITE_TAC[SUM_ADD_NUMSEG; SUM_LMUL; SUM_BERNSTEIN] THEN + SUBGOAL_THEN `sum(0..n) (\k. &k * bernstein n k x) = &n * x` SUBST1_TAC THENL + [REMOVE_THEN "1" (MP_TAC o SPECL [`x:real`; `&1 - x`]) THEN + REWRITE_TAC[REAL_SUB_ADD2; REAL_POW_ONE; bernstein; REAL_MUL_RID] THEN + DISCH_THEN(SUBST1_TAC o SYM) THEN REWRITE_TAC[GSYM SUM_RMUL] THEN + MATCH_MP_TAC SUM_EQ_NUMSEG THEN X_GEN_TAC `k:num` THEN STRIP_TAC THEN + REWRITE_TAC[REAL_ARITH + `(k * b * xk * y) * x:real = k * b * (x * xk) * y`] THEN + REWRITE_TAC[GSYM(CONJUNCT2 real_pow)] THEN + DISJ_CASES_TAC(ARITH_RULE `k = 0 \/ SUC(k - 1) = k`) THEN + ASM_REWRITE_TAC[REAL_MUL_LZERO]; + ALL_TAC] THEN + SUBGOAL_THEN + `sum(0..n) (\k. &k * (&k - &1) * bernstein n k x) = &n * (&n - &1) * x pow 2` + SUBST1_TAC THENL [ALL_TAC; CONV_TAC REAL_RING] THEN + REMOVE_THEN "2" (MP_TAC o SPECL [`x:real`; `&1 - x`]) THEN + REWRITE_TAC[REAL_SUB_ADD2; REAL_POW_ONE; bernstein; REAL_MUL_RID] THEN + ASM_CASES_TAC `n = 0` THEN + ASM_REWRITE_TAC[SUM_SING_NUMSEG; REAL_MUL_LZERO] THEN + ASM_SIMP_TAC[GSYM REAL_OF_NUM_SUB; LE_1; REAL_MUL_ASSOC] THEN + DISCH_THEN(SUBST1_TAC o SYM) THEN REWRITE_TAC[GSYM SUM_RMUL] THEN + MATCH_MP_TAC SUM_EQ_NUMSEG THEN X_GEN_TAC `k:num` THEN STRIP_TAC THEN + REWRITE_TAC[REAL_ARITH `((((k * k1) * b) * xk) * y) * x2:real = + k * k1 * b * y * (x2 * xk)`] THEN + REWRITE_TAC[GSYM REAL_POW_ADD; GSYM REAL_MUL_ASSOC] THEN + REPEAT_TCL DISJ_CASES_THEN ASSUME_TAC + (ARITH_RULE `k = 0 \/ k = 1 \/ 1 <= k /\ 2 + k - 2 = k`) THEN + ASM_REWRITE_TAC[REAL_MUL_LZERO; REAL_MUL_LID; SUB_REFL; REAL_SUB_REFL] THEN + ASM_SIMP_TAC[GSYM REAL_OF_NUM_SUB] THEN REWRITE_TAC[REAL_MUL_AC]);; + +(* ------------------------------------------------------------------------- *) +(* Explicit Bernstein version of 1D Weierstrass approximation theorem *) +(* ------------------------------------------------------------------------- *) + +let BERNSTEIN_WEIERSTRASS = prove + (`!f e. + f real_continuous_on real_interval[&0,&1] /\ &0 < e + ==> ?N. !n x. N <= n /\ x IN real_interval[&0,&1] + ==> abs(f x - + sum(0..n) (\k. f(&k / &n) * bernstein n k x)) < e`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN `real_bounded(IMAGE f (real_interval[&0,&1]))` MP_TAC THENL + [MATCH_MP_TAC REAL_COMPACT_IMP_BOUNDED THEN + MATCH_MP_TAC REAL_COMPACT_CONTINUOUS_IMAGE THEN + ASM_REWRITE_TAC[REAL_COMPACT_INTERVAL]; + REWRITE_TAC[REAL_BOUNDED_POS; LEFT_IMP_EXISTS_THM; FORALL_IN_IMAGE] THEN + REWRITE_TAC[IN_REAL_INTERVAL] THEN X_GEN_TAC `M:real` THEN STRIP_TAC] THEN + SUBGOAL_THEN `f real_uniformly_continuous_on real_interval[&0,&1]` + MP_TAC THENL + [ASM_SIMP_TAC[REAL_COMPACT_UNIFORMLY_CONTINUOUS; REAL_COMPACT_INTERVAL]; + REWRITE_TAC[real_uniformly_continuous_on] THEN + DISCH_THEN(MP_TAC o SPEC `e / &2`) THEN + ASM_REWRITE_TAC[REAL_HALF; IN_REAL_INTERVAL] THEN + DISCH_THEN(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC)] THEN + SUBGOAL_THEN + `!n x. 0 < n /\ &0 <= x /\ x <= &1 + ==> abs(f x - sum(0..n) (\k. f(&k / &n) * bernstein n k x)) + <= e / &2 + (&2 * M) / (d pow 2 * &n)` + ASSUME_TAC THENL + [REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `abs(sum(0..n) (\k. (f x - f(&k / &n)) * bernstein n k x))` THEN + CONJ_TAC THENL + [REWRITE_TAC[REAL_SUB_RDISTRIB; SUM_SUB_NUMSEG; SUM_LMUL] THEN + REWRITE_TAC[SUM_BERNSTEIN; REAL_MUL_RID; REAL_LE_REFL]; + ALL_TAC] THEN + W(MP_TAC o PART_MATCH lhand SUM_ABS_NUMSEG o lhand o snd) THEN + MATCH_MP_TAC(REAL_ARITH `a <= b ==> x <= a ==> x <= b`) THEN + REWRITE_TAC[REAL_ABS_MUL] THEN + ASM_SIMP_TAC[BERNSTEIN_POS; REAL_ARITH `&0 <= x ==> abs x = x`] THEN + MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC + `sum(0..n) (\k. (e / &2 + &2 * M / d pow 2 * (x - &k / &n) pow 2) * + bernstein n k x)` THEN + CONJ_TAC THENL + [MATCH_MP_TAC SUM_LE_NUMSEG THEN X_GEN_TAC `k:num` THEN STRIP_TAC THEN + REWRITE_TAC[] THEN MATCH_MP_TAC REAL_LE_RMUL THEN + ASM_SIMP_TAC[BERNSTEIN_POS] THEN + SUBGOAL_THEN `&0 <= &k / &n /\ &k / &n <= &1` STRIP_ASSUME_TAC THENL + [ASM_SIMP_TAC[REAL_LE_LDIV_EQ; REAL_LE_RDIV_EQ; REAL_OF_NUM_LT] THEN + ASM_REWRITE_TAC[REAL_OF_NUM_MUL; REAL_OF_NUM_LE; MULT_CLAUSES]; + ALL_TAC] THEN + DISJ_CASES_TAC(REAL_ARITH + `abs(x - &k / &n) < d \/ d <= abs(x - &k / &n)`) + THENL + [MATCH_MP_TAC(REAL_ARITH `x < e /\ &0 <= d ==> x <= e + d`) THEN + ASM_SIMP_TAC[REAL_ARITH `&0 <= &2 * x <=> &0 <= x`] THEN + ASM_SIMP_TAC[REAL_LE_MUL; REAL_LE_DIV; REAL_POW_2; REAL_LE_SQUARE; + REAL_LT_IMP_LE]; + MATCH_MP_TAC(REAL_ARITH `&0 < e /\ x <= d ==> x <= e / &2 + d`) THEN + ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC(REAL_ARITH + `abs(x) <= M /\ abs(y) <= M /\ M * &1 <= M * b / d + ==> abs(x - y) <= &2 * M / d * b`) THEN + ASM_SIMP_TAC[REAL_LE_LMUL_EQ; REAL_POW_LT; REAL_LE_RDIV_EQ] THEN + REWRITE_TAC[REAL_MUL_LID; GSYM REAL_LE_SQUARE_ABS] THEN + ASM_REAL_ARITH_TAC]; + REWRITE_TAC[REAL_ADD_RDISTRIB; SUM_ADD_NUMSEG; SUM_LMUL] THEN + REWRITE_TAC[SUM_BERNSTEIN; REAL_MUL_RID; REAL_LE_LADD] THEN + REWRITE_TAC[GSYM REAL_MUL_ASSOC; SUM_LMUL] THEN + REWRITE_TAC[real_div; REAL_INV_MUL; GSYM REAL_MUL_ASSOC] THEN + ASM_SIMP_TAC[REAL_LE_LMUL_EQ; REAL_OF_NUM_LT; ARITH; REAL_POW_LT; + REAL_LT_INV_EQ] THEN + MATCH_MP_TAC REAL_LE_LCANCEL_IMP THEN EXISTS_TAC `&n pow 2` THEN + ASM_SIMP_TAC[GSYM SUM_LMUL; REAL_POW_LT; REAL_OF_NUM_LT; REAL_FIELD + `&0 < n ==> n pow 2 * inv(n) = n`] THEN + REWRITE_TAC[REAL_MUL_ASSOC; GSYM REAL_POW_MUL] THEN + ASM_SIMP_TAC[REAL_OF_NUM_LT; REAL_FIELD + `&0 < n ==> n * (x - k * inv n) = n * x - k`] THEN + ONCE_REWRITE_TAC[REAL_ARITH `(x - y:real) pow 2 = (y - x) pow 2`] THEN + REWRITE_TAC[BERNSTEIN_LEMMA; REAL_ARITH + `&n * x <= &n <=> &n * x <= &n * &1 * &1`] THEN + MATCH_MP_TAC REAL_LE_LMUL THEN REWRITE_TAC[REAL_POS] THEN + MATCH_MP_TAC REAL_LE_MUL2 THEN ASM_REAL_ARITH_TAC]; + MP_TAC(ISPEC `(e / &4 * d pow 2) / (&2 * M)` REAL_ARCH_INV) THEN + ASM_SIMP_TAC[REAL_LT_RDIV_EQ; REAL_OF_NUM_LT; ARITH; REAL_LT_MUL] THEN + ASM_SIMP_TAC[GSYM REAL_LT_LDIV_EQ; REAL_POW_LT; REAL_MUL_LZERO] THEN + REWRITE_TAC[real_div; REAL_MUL_LZERO] THEN + REWRITE_TAC[REAL_ARITH `(x * &2 * m) * i = (&2 * m) * (i * x)`] THEN + REWRITE_TAC[GSYM REAL_INV_MUL] THEN + ASM_SIMP_TAC[GSYM real_div; 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 [`n:num`; `x:real`] THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`n:num`; `x:real`]) THEN ASM_SIMP_TAC[] THEN + ANTS_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN + MATCH_MP_TAC(REAL_ARITH + `&0 < e /\ k < e / &4 ==> x <= e / &2 + k ==> x < e`) THEN + ASM_SIMP_TAC[] THEN FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH + `x < e ==> y <= x ==> y < e`)) THEN + ASM_SIMP_TAC[real_div; REAL_LE_LMUL_EQ; REAL_LT_MUL; + REAL_OF_NUM_LT; ARITH] THEN + MATCH_MP_TAC REAL_LE_INV2 THEN + ASM_SIMP_TAC[REAL_LE_LMUL_EQ; REAL_LT_MUL; REAL_POW_LT; + REAL_OF_NUM_LT; LE_1; REAL_OF_NUM_LE]]);; + +(* ------------------------------------------------------------------------- *) +(* General Stone-Weierstrass theorem. *) +(* ------------------------------------------------------------------------- *) + +let STONE_WEIERSTRASS_ALT = prove + (`!(P:(real^N->real)->bool) (s:real^N->bool). + compact s /\ + (!c. P(\x. c)) /\ + (!f g. P(f) /\ P(g) ==> P(\x. f x + g x)) /\ + (!f g. P(f) /\ P(g) ==> P(\x. f x * g x)) /\ + (!x y. x IN s /\ y IN s /\ ~(x = y) + ==> ?f. (!x. x IN s ==> f real_continuous (at x within s)) /\ + P(f) /\ ~(f x = f y)) + ==> !f e. (!x. x IN s ==> f real_continuous (at x within s)) /\ &0 < e + ==> ?g. P(g) /\ !x. x IN s ==> abs(f x - g x) < e`, + REPEAT GEN_TAC THEN STRIP_TAC THEN MAP_EVERY ABBREV_TAC + [`C = \f. !x:real^N. x IN s ==> f real_continuous at x within s`; + `A = \f. C f /\ + !e. &0 < e + ==> ?g. P(g) /\ !x:real^N. x IN s ==> abs(f x - g x) < e`] THEN + SUBGOAL_THEN `!f:real^N->real. C(f) ==> A(f)` MP_TAC THENL + [ALL_TAC; MAP_EVERY EXPAND_TAC ["A"; "C"] THEN SIMP_TAC[]] THEN + SUBGOAL_THEN `!c:real. A(\x:real^N. c)` (LABEL_TAC "const") THENL + [MAP_EVERY EXPAND_TAC ["A"; "C"] THEN X_GEN_TAC `c:real` THEN + ASM_REWRITE_TAC[REAL_CONTINUOUS_CONST] THEN X_GEN_TAC `e:real` THEN + DISCH_TAC THEN EXISTS_TAC `(\x. c):real^N->real` THEN + ASM_REWRITE_TAC[REAL_SUB_REFL; REAL_ABS_0]; + ALL_TAC] THEN + SUBGOAL_THEN `!f g:real^N->real. A(f) /\ A(g) ==> A(\x. f x + g x)` + (LABEL_TAC "add") THENL + [MAP_EVERY EXPAND_TAC ["A"; "C"] THEN SIMP_TAC[REAL_CONTINUOUS_ADD] THEN + MAP_EVERY X_GEN_TAC [`f:real^N->real`; `g:real^N->real`] THEN + DISCH_THEN(fun th -> REPEAT STRIP_TAC THEN MP_TAC th) THEN + DISCH_THEN(CONJUNCTS_THEN (MP_TAC o SPEC `e / &2` o CONJUNCT2)) THEN + ASM_REWRITE_TAC[REAL_HALF; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `g':real^N->real` THEN STRIP_TAC THEN + X_GEN_TAC `f':real^N->real` THEN STRIP_TAC THEN + EXISTS_TAC `(\x. f' x + g' x):real^N->real` THEN + ASM_SIMP_TAC[REAL_ARITH + `abs(f - f') < e / &2 /\ abs(g - g') < e / &2 + ==> abs((f + g) - (f' + g')) < e`]; + ALL_TAC] THEN + SUBGOAL_THEN `!f:real^N->real. A(f) ==> C(f)` (LABEL_TAC "AC") THENL + [EXPAND_TAC "A" THEN SIMP_TAC[]; ALL_TAC] THEN + SUBGOAL_THEN `!f:real^N->real. C(f) ==> real_bounded(IMAGE f s)` + (LABEL_TAC "bound") THENL + [GEN_TAC THEN EXPAND_TAC "C" THEN + REWRITE_TAC[REAL_BOUNDED; GSYM IMAGE_o] THEN + REWRITE_TAC[REAL_CONTINUOUS_CONTINUOUS1] THEN + REWRITE_TAC[GSYM CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN] THEN + ASM_SIMP_TAC[COMPACT_IMP_BOUNDED; COMPACT_CONTINUOUS_IMAGE]; + ALL_TAC] THEN + SUBGOAL_THEN `!f g:real^N->real. A(f) /\ A(g) ==> A(\x. f x * g x)` + (LABEL_TAC "mul") THENL + [MAP_EVERY X_GEN_TAC [`f:real^N->real`; `g:real^N->real`] THEN + DISCH_THEN(fun th -> STRIP_ASSUME_TAC th THEN MP_TAC th) THEN + MAP_EVERY EXPAND_TAC ["A"; "C"] THEN SIMP_TAC[REAL_CONTINUOUS_MUL] THEN + REWRITE_TAC[IMP_CONJ] THEN + MAP_EVERY (DISCH_THEN o LABEL_TAC) ["cf"; "af"; "cg"; "ag"] THEN + SUBGOAL_THEN + `real_bounded(IMAGE (f:real^N->real) s) /\ + real_bounded(IMAGE (g:real^N->real) s)` + MP_TAC THENL + [ASM_SIMP_TAC[]; REWRITE_TAC[REAL_BOUNDED_POS_LT; FORALL_IN_IMAGE]] THEN + DISCH_THEN(CONJUNCTS_THEN2 + (X_CHOOSE_THEN `Bf:real` STRIP_ASSUME_TAC) + (X_CHOOSE_THEN `Bg:real` STRIP_ASSUME_TAC)) THEN + X_GEN_TAC `e:real` THEN DISCH_TAC THEN + REMOVE_THEN "ag" (MP_TAC o SPEC `e / &2 / Bf`) THEN + ASM_SIMP_TAC[REAL_HALF; REAL_LT_DIV; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `g':real^N->real` THEN STRIP_TAC THEN + REMOVE_THEN "af" (MP_TAC o SPEC `e / &2 / (Bg + e / &2 / Bf)`) THEN + ASM_SIMP_TAC[REAL_HALF; REAL_LT_DIV; REAL_LT_ADD] THEN + DISCH_THEN(X_CHOOSE_THEN `f':real^N->real` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `(\x. f'(x) * g'(x)):real^N->real` THEN + ASM_SIMP_TAC[REAL_ARITH + `f * g - f' * g':real = f * (g - g') + g' * (f - f')`] THEN + X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN + SUBGOAL_THEN `e = Bf * e / &2 / Bf + + (Bg + e / &2 / Bf) * e / &2 / (Bg + e / &2 / Bf)` + SUBST1_TAC THENL + [MATCH_MP_TAC(REAL_ARITH `a = e / &2 /\ b = e / &2 ==> e = a + b`) THEN + CONJ_TAC THEN MAP_EVERY MATCH_MP_TAC [REAL_DIV_LMUL; REAL_LT_IMP_NZ] THEN + ASM_SIMP_TAC[REAL_LT_DIV; REAL_LT_ADD; REAL_HALF]; + MATCH_MP_TAC(REAL_ARITH + `abs a < c /\ abs b < d ==> abs(a + b) < c + d`) THEN + REWRITE_TAC[REAL_ABS_MUL] THEN CONJ_TAC THEN + MATCH_MP_TAC REAL_LT_MUL2 THEN ASM_SIMP_TAC[REAL_ABS_POS] THEN + MATCH_MP_TAC(REAL_ARITH + `!g. abs(g) < Bg /\ abs(g - g') < e ==> abs(g') < Bg + e`) THEN + EXISTS_TAC `(g:real^N->real) x` THEN ASM_SIMP_TAC[]]; + ALL_TAC] THEN + SUBGOAL_THEN + `!x y. x IN s /\ y IN s /\ ~(x = y) + ==> ?f:real^N->real. A(f) /\ ~(f x = f y)` + (LABEL_TAC "sep") THENL + [MAP_EVERY X_GEN_TAC [`x:real^N`; `y:real^N`] THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`x:real^N`; `y:real^N`]) THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC MONO_EXISTS THEN + MAP_EVERY EXPAND_TAC ["A"; "C"] THEN + ASM_MESON_TAC[REAL_SUB_REFL; REAL_ABS_0]; + ALL_TAC] THEN + SUBGOAL_THEN `!f. A(f) ==> A(\x:real^N. abs(f x))` (LABEL_TAC "abs") THENL + [SUBGOAL_THEN `!f. A(f) /\ (!x. x IN s ==> abs(f x) <= &1 / &4) + ==> A(\x:real^N. abs(f x))` + ASSUME_TAC THENL + [ALL_TAC; + REPEAT STRIP_TAC THEN + SUBGOAL_THEN `real_bounded(IMAGE (f:real^N->real) s)` MP_TAC THENL + [ASM_SIMP_TAC[]; REWRITE_TAC[REAL_BOUNDED_POS_LT; FORALL_IN_IMAGE]] THEN + DISCH_THEN(X_CHOOSE_THEN `B:real` STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN `A(\x:real^N. (&4 * B) * abs(inv(&4 * B) * f x)):bool` + MP_TAC THENL + [USE_THEN "mul" MATCH_MP_TAC THEN ASM_REWRITE_TAC[] THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_SIMP_TAC[REAL_ABS_MUL] THEN + ASM_SIMP_TAC[REAL_ARITH `&0 < B ==> abs(B) = B`; + REAL_LT_INV_EQ; REAL_LT_MUL; REAL_OF_NUM_LT; ARITH] THEN + ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN + ASM_SIMP_TAC[GSYM real_div; REAL_LE_LDIV_EQ; REAL_LT_MUL; + REAL_OF_NUM_LT; ARITH; REAL_MUL_ASSOC] THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN + ASM_SIMP_TAC[REAL_MUL_LID; REAL_LT_IMP_LE]; + ASM_SIMP_TAC[REAL_ABS_MUL; REAL_ARITH `&0 < B ==> abs(B) = B`; + REAL_LT_INV_EQ; REAL_LT_MUL; REAL_OF_NUM_LT; ARITH] THEN + ASM_SIMP_TAC[REAL_MUL_ASSOC; REAL_MUL_RINV; REAL_MUL_LID; + REAL_ARITH `&0 < B ==> ~(&4 * B = &0)`]]] THEN + X_GEN_TAC `f:real^N->real` THEN MAP_EVERY EXPAND_TAC ["A"; "C"] THEN + DISCH_THEN(fun th -> CONJ_TAC THEN MP_TAC th) THENL + [DISCH_THEN(MP_TAC o CONJUNCT1 o CONJUNCT1) THEN + MATCH_MP_TAC MONO_FORALL THEN GEN_TAC THEN MATCH_MP_TAC MONO_IMP THEN + REWRITE_TAC[] THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT; o_DEF] + REAL_CONTINUOUS_WITHIN_COMPOSE) THEN + REWRITE_TAC[real_continuous_withinreal] THEN + MESON_TAC[ARITH_RULE `abs(x - y) < d ==> abs(abs x - abs y) < d`]; + ALL_TAC] THEN + DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + DISCH_THEN(fun t -> X_GEN_TAC `e:real` THEN DISCH_TAC THEN MP_TAC t) THEN + DISCH_THEN(MP_TAC o SPEC `min (e / &2) (&1 / &4)`) THEN + ANTS_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN + REWRITE_TAC[REAL_LT_MIN; FORALL_AND_THM; + TAUT `(a ==> b /\ c) <=> (a ==> b) /\ (a ==> c)`] THEN + DISCH_THEN(X_CHOOSE_THEN `p:real^N->real` STRIP_ASSUME_TAC) THEN + MP_TAC(ISPECL [`\x. abs(x - &1 / &2)`; `e / &2`] + BERNSTEIN_WEIERSTRASS) THEN + REWRITE_TAC[] THEN ANTS_TAC THENL + [ASM_REWRITE_TAC[real_continuous_on; REAL_HALF] THEN + MESON_TAC[ARITH_RULE + `abs(x - y) < d ==> abs(abs(x - a) - abs(y - a)) < d`]; + ALL_TAC] THEN + DISCH_THEN(X_CHOOSE_THEN `n:num` (MP_TAC o SPEC `n:num`)) THEN + REWRITE_TAC[LE_REFL] THEN DISCH_TAC THEN + EXISTS_TAC `\x:real^N. sum(0..n) (\k. abs(&k / &n - &1 / &2) * + bernstein n k (&1 / &2 + p x))` THEN + REWRITE_TAC[] THEN CONJ_TAC THENL + [SUBGOAL_THEN + `!m c z. P(\x:real^N. + sum(0..m) (\k. c k * bernstein (z m) k (&1 / &2 + p x)))` + (fun th -> REWRITE_TAC[th]) THEN + SUBGOAL_THEN + `!m k. P(\x:real^N. bernstein m k (&1 / &2 + p x))` + ASSUME_TAC THENL + [ALL_TAC; INDUCT_TAC THEN ASM_SIMP_TAC[SUM_CLAUSES_NUMSEG; LE_0]] THEN + REPEAT GEN_TAC THEN REWRITE_TAC[bernstein] THEN + REWRITE_TAC[REAL_ARITH `&1 - (&1 / &2 + p) = &1 / &2 + -- &1 * p`] THEN + REPEAT(FIRST_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[]) THEN + SUBGOAL_THEN + `!f:real^N->real k. P(f) ==> P(\x. f(x) pow k)` + (fun th -> ASM_SIMP_TAC[th]) THEN + GEN_TAC THEN INDUCT_TAC THEN ASM_SIMP_TAC[real_pow]; + REPEAT STRIP_TAC THEN MATCH_MP_TAC(REAL_ARITH + `!p. abs(abs(p x) - s) < e / &2 /\ + abs(f x - p x) < e / &2 + ==> abs(abs(f x) - s) < e`) THEN + EXISTS_TAC `p:real^N->real` THEN ASM_SIMP_TAC[] THEN + GEN_REWRITE_TAC (PAT_CONV `\x. abs(abs x - a) < e`) + [REAL_ARITH `x = (&1 / &2 + x) - &1 / &2`] THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN REWRITE_TAC[IN_REAL_INTERVAL] THEN + MATCH_MP_TAC(REAL_ARITH + `!f. abs(f) <= &1 / &4 /\ abs(f - p) < &1 / &4 + ==> &0 <= &1 / &2 + p /\ &1 / &2 + p <= &1`) THEN + EXISTS_TAC `(f:real^N->real) x` THEN ASM_SIMP_TAC[]]; + ALL_TAC] THEN + SUBGOAL_THEN `!f:real^N->real g. A(f) /\ A(g) ==> A(\x. max (f x) (g x))` + (LABEL_TAC "max") THENL + [REPEAT STRIP_TAC THEN REWRITE_TAC[REAL_ARITH + `max a b = inv(&2) * (a + b + abs(a + -- &1 * b))`] THEN + REPEAT(FIRST_ASSUM MATCH_MP_TAC THEN ASM_SIMP_TAC[]); + ALL_TAC] THEN + SUBGOAL_THEN `!f:real^N->real g. A(f) /\ A(g) ==> A(\x. min (f x) (g x))` + (LABEL_TAC "min") THENL + [ASM_SIMP_TAC[REAL_ARITH `min a b = -- &1 * (max(-- &1 * a) (-- &1 * b))`]; + ALL_TAC] THEN + SUBGOAL_THEN + `!t. FINITE t /\ (!f. f IN t ==> A(f)) ==> A(\x:real^N. sup {f(x) | f IN t})` + (LABEL_TAC "sup") THENL + [REWRITE_TAC[IMP_CONJ] THEN MATCH_MP_TAC FINITE_INDUCT_STRONG THEN + ASM_SIMP_TAC[FORALL_IN_INSERT; SIMPLE_IMAGE; IMAGE_CLAUSES] THEN + ASM_SIMP_TAC[SUP_INSERT_FINITE; FINITE_IMAGE; IMAGE_EQ_EMPTY] THEN + MAP_EVERY X_GEN_TAC [`f:real^N->real`; `t:(real^N->real)->bool`] THEN + ASM_CASES_TAC `t:(real^N->real)->bool = {}` THEN ASM_SIMP_TAC[ETA_AX]; + ALL_TAC] THEN + SUBGOAL_THEN + `!t. FINITE t /\ (!f. f IN t ==> A(f)) ==> A(\x:real^N. inf {f(x) | f IN t})` + (LABEL_TAC "inf") THENL + [REWRITE_TAC[IMP_CONJ] THEN MATCH_MP_TAC FINITE_INDUCT_STRONG THEN + ASM_SIMP_TAC[FORALL_IN_INSERT; SIMPLE_IMAGE; IMAGE_CLAUSES] THEN + ASM_SIMP_TAC[INF_INSERT_FINITE; FINITE_IMAGE; IMAGE_EQ_EMPTY] THEN + MAP_EVERY X_GEN_TAC [`f:real^N->real`; `t:(real^N->real)->bool`] THEN + ASM_CASES_TAC `t:(real^N->real)->bool = {}` THEN ASM_SIMP_TAC[ETA_AX]; + ALL_TAC] THEN + SUBGOAL_THEN + `!f:real^N->real e. + C(f) /\ &0 < e ==> ?g. A(g) /\ !x. x IN s ==> abs(f x - g x) < e` + ASSUME_TAC THENL + [ALL_TAC; + X_GEN_TAC `f:real^N->real` THEN DISCH_TAC THEN EXPAND_TAC "A" THEN + CONJ_TAC THENL [FIRST_X_ASSUM ACCEPT_TAC; ALL_TAC] THEN + X_GEN_TAC `e:real` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`f:real^N->real`; `e / &2`]) THEN + ASM_REWRITE_TAC[REAL_HALF; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `h:real^N->real` THEN EXPAND_TAC "A" THEN + DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN + DISCH_THEN(MP_TAC o SPEC `e / &2` o CONJUNCT2) THEN + ASM_REWRITE_TAC[REAL_HALF] THEN MATCH_MP_TAC MONO_EXISTS THEN + ASM_MESON_TAC[REAL_ARITH + `abs(f - h) < e / &2 /\ abs(h - g) < e / &2 ==> abs(f - g) < e`]] THEN + MAP_EVERY X_GEN_TAC [`f:real^N->real`; `e:real`] THEN EXPAND_TAC "C" THEN + STRIP_TAC THEN + SUBGOAL_THEN + `!x y. x IN s /\ y IN s + ==> ?h:real^N->real. A(h) /\ h(x) = f(x) /\ h(y) = f(y)` + MP_TAC THENL + [REPEAT STRIP_TAC THEN ASM_CASES_TAC `y:real^N = x` THENL + [EXISTS_TAC `\z:real^N. (f:real^N->real) x` THEN ASM_SIMP_TAC[]; + SUBGOAL_THEN `?h:real^N->real. A(h) /\ ~(h x = h y)` + STRIP_ASSUME_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN + EXISTS_TAC `\z. (f y - f x) / (h y - h x) * (h:real^N->real)(z) + + (f x - (f y - f x) / (h y - h x) * h(x))` THEN + ASM_SIMP_TAC[] THEN + UNDISCH_TAC `~((h:real^N->real) x = h y)` THEN CONV_TAC REAL_FIELD]; + ALL_TAC] THEN + GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [RIGHT_IMP_EXISTS_THM] THEN + REWRITE_TAC[SKOLEM_THM; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `f2:real^N->real^N->real^N->real` THEN DISCH_TAC THEN + ABBREV_TAC `G = \x y. + {z | z IN s /\ (f2:real^N->real^N->real^N->real) x y z < f(z) + e}` THEN + SUBGOAL_THEN `!x y:real^N. x IN s /\ y IN s ==> x IN G x y /\ y IN G x y` + ASSUME_TAC THENL + [EXPAND_TAC "G" THEN REWRITE_TAC[IN_ELIM_THM] THEN + ASM_SIMP_TAC[REAL_LT_ADDR]; + ALL_TAC] THEN + SUBGOAL_THEN + `!x. x IN s ==> ?f1. A(f1) /\ f1 x = f x /\ + !y:real^N. y IN s ==> f1 y < f y + e` + MP_TAC THENL + [REPEAT STRIP_TAC THEN FIRST_ASSUM(MP_TAC o + GEN_REWRITE_RULE I [COMPACT_EQ_HEINE_BOREL_SUBTOPOLOGY]) THEN + DISCH_THEN(MP_TAC o SPEC + `{(G:real^N->real^N->real^N->bool) x y | y IN s}`) THEN + REWRITE_TAC[SIMPLE_IMAGE; UNIONS_IMAGE; FORALL_IN_IMAGE; ETA_AX] THEN + ANTS_TAC THENL + [CONJ_TAC THENL [ALL_TAC; ASM SET_TAC[]] THEN + EXPAND_TAC "G" THEN REWRITE_TAC[] THEN X_GEN_TAC `w:real^N` THEN + DISCH_TAC THEN + MP_TAC(ISPECL [`lift o (\z:real^N. f2 (x:real^N) (w:real^N) z - f z)`; + `s:real^N->bool`; + `{x:real^1 | x$1 < e}`] CONTINUOUS_OPEN_IN_PREIMAGE) THEN + REWRITE_TAC[OPEN_HALFSPACE_COMPONENT_LT; IN_ELIM_THM] THEN + REWRITE_TAC[GSYM drop; LIFT_DROP; o_DEF] THEN + REWRITE_TAC[LIFT_SUB; GSYM REAL_CONTINUOUS_CONTINUOUS1; + REAL_ARITH `x < y + e <=> x - y < e`] THEN + DISCH_THEN MATCH_MP_TAC THEN MATCH_MP_TAC CONTINUOUS_ON_SUB THEN + ONCE_REWRITE_TAC[GSYM o_DEF] THEN + REWRITE_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN] THEN + REWRITE_TAC[GSYM REAL_CONTINUOUS_CONTINUOUS1; ETA_AX] THEN + ASM_MESON_TAC[]; + ALL_TAC] THEN + ONCE_REWRITE_TAC[TAUT `a /\ b /\ c <=> b /\ a /\ c`] THEN + REWRITE_TAC[EXISTS_FINITE_SUBSET_IMAGE; UNIONS_IMAGE] THEN + DISCH_THEN(X_CHOOSE_THEN `t:real^N->bool` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `\z:real^N. inf {f2 (x:real^N) (y:real^N) z | y IN t}` THEN + REWRITE_TAC[] THEN REPEAT CONJ_TAC THENL + [GEN_REWRITE_TAC RAND_CONV [REAL_ARITH `x = min x x`] THEN + REWRITE_TAC[REAL_MIN_INF; INSERT_AC] THEN AP_TERM_TAC THEN ASM SET_TAC[]; + REMOVE_THEN "inf" (MP_TAC o SPEC + `IMAGE (\y z. (f2:real^N->real^N->real^N->real) x y z) t`) THEN + ASM_SIMP_TAC[FINITE_IMAGE; FORALL_IN_IMAGE] THEN + REWRITE_TAC[SIMPLE_IMAGE; ETA_AX] THEN + ANTS_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + REWRITE_TAC[GSYM IMAGE_o; o_DEF]; + SUBGOAL_THEN `~(t:real^N->bool = {})` ASSUME_TAC THENL + [ASM SET_TAC[]; ALL_TAC] THEN + ASM_SIMP_TAC[REAL_INF_LT_FINITE; SIMPLE_IMAGE; + FINITE_IMAGE; IMAGE_EQ_EMPTY] THEN + REWRITE_TAC[EXISTS_IN_IMAGE] THEN + X_GEN_TAC `y:real^N` THEN DISCH_TAC THEN + UNDISCH_TAC + `s SUBSET {y:real^N | ?z:real^N. z IN t /\ y IN G (x:real^N) z}` THEN + REWRITE_TAC[SUBSET; IN_ELIM_THM] THEN + DISCH_THEN(MP_TAC o SPEC `y:real^N`) THEN ASM_REWRITE_TAC[] THEN + EXPAND_TAC "G" THEN REWRITE_TAC[IN_ELIM_THM] THEN ASM_REWRITE_TAC[]]; + GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) + [RIGHT_IMP_EXISTS_THM] THEN + REWRITE_TAC[SKOLEM_THM; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `f1:real^N->real^N->real` THEN DISCH_TAC] THEN + ABBREV_TAC `H = \x:real^N. {z:real^N | z IN s /\ f z - e < f1 x z}` THEN + SUBGOAL_THEN `!x:real^N. x IN s ==> x IN (H x)` ASSUME_TAC THENL + [EXPAND_TAC "H" THEN REWRITE_TAC[IN_ELIM_THM] THEN + ASM_SIMP_TAC[REAL_ARITH `x - e < x <=> &0 < e`]; + ALL_TAC] THEN + FIRST_ASSUM(MP_TAC o + GEN_REWRITE_RULE I [COMPACT_EQ_HEINE_BOREL_SUBTOPOLOGY]) THEN + DISCH_THEN(MP_TAC o SPEC + `{(H:real^N->real^N->bool) x | x IN s}`) THEN + REWRITE_TAC[SIMPLE_IMAGE; UNIONS_IMAGE; FORALL_IN_IMAGE; ETA_AX] THEN + ANTS_TAC THENL + [CONJ_TAC THENL [ALL_TAC; ASM SET_TAC[]] THEN EXPAND_TAC "H" THEN + REWRITE_TAC[] THEN X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN + MP_TAC(ISPECL [`lift o (\z:real^N. f z - f1 (x:real^N) z)`; + `s:real^N->bool`; + `{x:real^1 | x$1 < e}`] CONTINUOUS_OPEN_IN_PREIMAGE) THEN + REWRITE_TAC[OPEN_HALFSPACE_COMPONENT_LT; IN_ELIM_THM] THEN + REWRITE_TAC[GSYM drop; LIFT_DROP; o_DEF] THEN + GEN_REWRITE_TAC (RAND_CONV o ONCE_DEPTH_CONV) + [REAL_ARITH `x - y < z <=> x - z < y`] THEN + DISCH_THEN MATCH_MP_TAC THEN + REWRITE_TAC[LIFT_SUB; GSYM REAL_CONTINUOUS_CONTINUOUS1; + REAL_ARITH `x < y + e <=> x - y < e`] THEN + MATCH_MP_TAC CONTINUOUS_ON_SUB THEN + ONCE_REWRITE_TAC[GSYM o_DEF] THEN + REWRITE_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN] THEN + REWRITE_TAC[GSYM REAL_CONTINUOUS_CONTINUOUS1; ETA_AX] THEN + ASM_MESON_TAC[]; + ALL_TAC] THEN + ONCE_REWRITE_TAC[TAUT `a /\ b /\ c <=> b /\ a /\ c`] THEN + REWRITE_TAC[EXISTS_FINITE_SUBSET_IMAGE; UNIONS_IMAGE] THEN + DISCH_THEN(X_CHOOSE_THEN `t:real^N->bool` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `\z:real^N. sup {f1 (x:real^N) z | x IN t}` THEN + REWRITE_TAC[] THEN CONJ_TAC THENL + [REMOVE_THEN "sup" (MP_TAC o SPEC `IMAGE (f1:real^N->real^N->real) t`) THEN + ASM_SIMP_TAC[FINITE_IMAGE; FORALL_IN_IMAGE] THEN + REWRITE_TAC[SIMPLE_IMAGE; ETA_AX] THEN + ANTS_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + REWRITE_TAC[GSYM IMAGE_o; o_DEF]; + ALL_TAC] THEN + X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN + SUBGOAL_THEN `~(t:real^N->bool = {})` ASSUME_TAC THENL + [ASM SET_TAC[]; ALL_TAC] THEN + REWRITE_TAC[SIMPLE_IMAGE; REAL_ARITH + `abs(f - s) < e <=> f - e < s /\ s < f + e`] THEN + ASM_SIMP_TAC[REAL_SUP_LT_FINITE; REAL_LT_SUP_FINITE; + FINITE_IMAGE; IMAGE_EQ_EMPTY] THEN + REWRITE_TAC[EXISTS_IN_IMAGE; FORALL_IN_IMAGE] THEN + CONJ_TAC THENL [ALL_TAC; ASM SET_TAC[]] THEN + UNDISCH_TAC `s SUBSET {y:real^N | ?x:real^N. x IN t /\ y IN H x}` THEN + REWRITE_TAC[SUBSET; IN_ELIM_THM] THEN + DISCH_THEN(MP_TAC o SPEC `x:real^N`) THEN ASM_REWRITE_TAC[] THEN + EXPAND_TAC "H" THEN REWRITE_TAC[IN_ELIM_THM] THEN ASM_REWRITE_TAC[]);; + +let STONE_WEIERSTRASS = prove + (`!(P:(real^N->real)->bool) (s:real^N->bool). + compact s /\ + (!f. P(f) ==> !x. x IN s ==> f real_continuous (at x within s)) /\ + (!c. P(\x. c)) /\ + (!f g. P(f) /\ P(g) ==> P(\x. f x + g x)) /\ + (!f g. P(f) /\ P(g) ==> P(\x. f x * g x)) /\ + (!x y. x IN s /\ y IN s /\ ~(x = y) ==> ?f. P(f) /\ ~(f x = f y)) + ==> !f e. (!x. x IN s ==> f real_continuous (at x within s)) /\ &0 < e + ==> ?g. P(g) /\ !x. x IN s ==> abs(f x - g x) < e`, + REPEAT GEN_TAC THEN STRIP_TAC THEN + MATCH_MP_TAC STONE_WEIERSTRASS_ALT THEN ASM_SIMP_TAC[] THEN + MAP_EVERY X_GEN_TAC [`x:real^N`; `y:real^N`] THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`x:real^N`; `y:real^N`]) THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC MONO_EXISTS THEN ASM_MESON_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* Real and complex versions of Stone-Weierstrass theorem. *) +(* ------------------------------------------------------------------------- *) + +let REAL_STONE_WEIERSTRASS_ALT = prove + (`!P s. real_compact s /\ + (!c. P (\x. c)) /\ + (!f g. P f /\ P g ==> P (\x. f x + g x)) /\ + (!f g. P f /\ P g ==> P (\x. f x * g x)) /\ + (!x y. x IN s /\ y IN s /\ ~(x = y) + ==> ?f. f real_continuous_on s /\ P f /\ ~(f x = f y)) + ==> !f e. f real_continuous_on s /\ &0 < e + ==> ?g. P g /\ !x. x IN s ==> abs(f x - g x) < e`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL + [`\f. (P:(real->real)->bool)(f o lift)`; + `IMAGE lift s`] STONE_WEIERSTRASS_ALT) THEN + ASM_SIMP_TAC[GSYM real_compact; o_DEF] THEN + REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_IMAGE] THEN + REWRITE_TAC[IMP_IMP; GSYM CONJ_ASSOC] THEN ANTS_TAC THENL + [X_GEN_TAC `x:real` THEN DISCH_TAC THEN + X_GEN_TAC `y:real` THEN REWRITE_TAC[LIFT_EQ] THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`x:real`; `y:real`]) THEN + ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `g:real->real` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `(g:real->real) o drop` THEN + ASM_REWRITE_TAC[o_THM; LIFT_DROP; ETA_AX] THEN + UNDISCH_TAC `g real_continuous_on s` THEN + REWRITE_TAC[REAL_CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN] THEN + REWRITE_TAC[REAL_CONTINUOUS_CONTINUOUS_WITHINREAL] THEN + REWRITE_TAC[real_continuous_within; continuous_within] THEN + REWRITE_TAC[o_THM; LIFT_DROP; DIST_LIFT]; + DISCH_THEN(MP_TAC o SPEC `(f:real->real) o drop`) THEN ANTS_TAC THENL + [UNDISCH_TAC `f real_continuous_on s` THEN + REWRITE_TAC[REAL_CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN] THEN + REWRITE_TAC[REAL_CONTINUOUS_CONTINUOUS_WITHINREAL] THEN + REWRITE_TAC[real_continuous_within; continuous_within] THEN + REWRITE_TAC[o_THM; LIFT_DROP; DIST_LIFT]; + DISCH_THEN(MP_TAC o SPEC `e:real`) THEN + ASM_REWRITE_TAC[o_DEF; LIFT_DROP] THEN + DISCH_THEN(X_CHOOSE_THEN `g:real^1->real` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `(g:real^1->real) o lift` THEN ASM_REWRITE_TAC[o_DEF]]]);; + +let REAL_STONE_WEIERSTRASS = prove + (`!P s. real_compact s /\ + (!f. P f ==> f real_continuous_on s) /\ + (!c. P (\x. c)) /\ + (!f g. P f /\ P g ==> P (\x. f x + g x)) /\ + (!f g. P f /\ P g ==> P (\x. f x * g x)) /\ + (!x y. x IN s /\ y IN s /\ ~(x = y) ==> ?f. P f /\ ~(f x = f y)) + ==> !f e. f real_continuous_on s /\ &0 < e + ==> ?g. P g /\ !x. x IN s ==> abs(f x - g x) < e`, + REPEAT GEN_TAC THEN STRIP_TAC THEN + MATCH_MP_TAC REAL_STONE_WEIERSTRASS_ALT THEN ASM_SIMP_TAC[] THEN + MAP_EVERY X_GEN_TAC [`x:real`; `y:real`] THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`x:real`; `y:real`]) THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC MONO_EXISTS THEN ASM_MESON_TAC[]);; + +let COMPLEX_STONE_WEIERSTRASS_ALT = prove + (`!P s. compact s /\ + (!c. P (\x. c)) /\ + (!f. P f ==> P(\x. cnj(f x))) /\ + (!f g. P f /\ P g ==> P (\x. f x + g x)) /\ + (!f g. P f /\ P g ==> P (\x. f x * g x)) /\ + (!x y. x IN s /\ y IN s /\ ~(x = y) + ==> ?f. P f /\ f continuous_on s /\ ~(f x = f y)) + ==> !f:real^N->complex e. + f continuous_on s /\ &0 < e + ==> ?g. P g /\ !x. x IN s ==> norm(f x - g x) < e`, + REPEAT GEN_TAC THEN STRIP_TAC THEN + SUBGOAL_THEN `!f. P f ==> P(\x:real^N. Cx(Re(f x)))` ASSUME_TAC THENL + [ASM_SIMP_TAC[CX_RE_CNJ; SIMPLE_COMPLEX_ARITH + `x / Cx(&2) = inv(Cx(&2)) * x`]; + ALL_TAC] THEN + SUBGOAL_THEN `!f. P f ==> P(\x:real^N. Cx(Im(f x)))` ASSUME_TAC THENL + [ASM_SIMP_TAC[CX_IM_CNJ; SIMPLE_COMPLEX_ARITH + `x - y = x + --Cx(&1) * y /\ x / Cx(&2) = inv(Cx(&2)) * x`] THEN + REPEAT STRIP_TAC THEN REPEAT(FIRST_ASSUM MATCH_MP_TAC ORELSE CONJ_TAC) THEN + ASM_SIMP_TAC[]; + ALL_TAC] THEN + MP_TAC(ISPECL [`\x. x IN {Re o f | P (f:real^N->complex)}`; `s:real^N->bool`] + STONE_WEIERSTRASS_ALT) THEN + REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_GSPEC] THEN + REWRITE_TAC[EXISTS_IN_GSPEC; IMP_IMP; GSYM CONJ_ASSOC] THEN ANTS_TAC THENL + [ASM_REWRITE_TAC[IMP_IMP; RIGHT_IMP_FORALL_THM; IN_ELIM_THM] THEN + REPEAT CONJ_TAC THENL + [X_GEN_TAC `c:real` THEN EXISTS_TAC `\x:real^N. Cx(c)` THEN + ASM_REWRITE_TAC[FUN_EQ_THM; o_THM; RE_CX]; + MAP_EVERY X_GEN_TAC [`f:real^N->complex`; `g:real^N->complex`] THEN + DISCH_TAC THEN EXISTS_TAC `(\x. f x + g x):real^N->complex` THEN + ASM_SIMP_TAC[o_THM; RE_ADD; FUN_EQ_THM]; + MAP_EVERY X_GEN_TAC [`f:real^N->complex`; `g:real^N->complex`] THEN + STRIP_TAC THEN + EXISTS_TAC `\x:real^N. Cx(Re(f x)) * Cx(Re(g x))` THEN + ASM_SIMP_TAC[FUN_EQ_THM; RE_CX; o_THM; RE_MUL_CX]; + MAP_EVERY X_GEN_TAC [`x:real^N`; `y:real^N`] THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`x:real^N`; `y:real^N`]) THEN + ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `f:real^N->complex` THEN + REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + GEN_REWRITE_TAC (LAND_CONV o RAND_CONV) [COMPLEX_EQ] THEN + REWRITE_TAC[DE_MORGAN_THM] THEN STRIP_TAC THENL + [EXISTS_TAC `\x:real^N. Re(f x)` THEN ASM_REWRITE_TAC[o_DEF] THEN + CONJ_TAC THENL + [ALL_TAC; EXISTS_TAC `f:real^N->complex` THEN ASM_REWRITE_TAC[]]; + EXISTS_TAC `\x:real^N. Im(f x)` THEN ASM_REWRITE_TAC[o_DEF] THEN + CONJ_TAC THENL + [ALL_TAC; + EXISTS_TAC `\x:real^N. Cx(Im(f x))` THEN ASM_SIMP_TAC[RE_CX]]] THEN + X_GEN_TAC `a:real^N` THEN DISCH_TAC THEN REWRITE_TAC[GSYM o_DEF] THEN + MATCH_MP_TAC REAL_CONTINUOUS_CONTINUOUS_WITHIN_COMPOSE THEN + SIMP_TAC[REAL_CONTINUOUS_COMPLEX_COMPONENTS_AT; + REAL_CONTINUOUS_AT_WITHIN] THEN + ASM_MESON_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN]]; + DISCH_THEN(LABEL_TAC "*") THEN X_GEN_TAC `f:real^N->complex` THEN + DISCH_TAC THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN + REMOVE_THEN "*" + (fun th -> MP_TAC(ISPEC `Re o (f:real^N->complex)` th) THEN + MP_TAC(ISPEC `Im o (f:real^N->complex)` th)) THEN + MATCH_MP_TAC(TAUT `(p1 /\ p2) /\ (q1 /\ q2 ==> r) + ==> (p1 ==> q1) ==> (p2 ==> q2) ==> r`) THEN + CONJ_TAC THENL + [CONJ_TAC THEN X_GEN_TAC `a:real^N` THEN DISCH_TAC THEN + MATCH_MP_TAC REAL_CONTINUOUS_CONTINUOUS_WITHIN_COMPOSE THEN + SIMP_TAC[REAL_CONTINUOUS_COMPLEX_COMPONENTS_AT; + REAL_CONTINUOUS_AT_WITHIN] THEN + ASM_MESON_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN]; + ALL_TAC] THEN + REWRITE_TAC[AND_FORALL_THM] THEN + DISCH_THEN(MP_TAC o SPEC `e / &2`) THEN + ASM_REWRITE_TAC[REAL_HALF; o_THM] THEN + DISCH_THEN(CONJUNCTS_THEN2 + (X_CHOOSE_THEN `g:real^N->complex` STRIP_ASSUME_TAC) + (X_CHOOSE_THEN `h:real^N->complex` STRIP_ASSUME_TAC)) THEN + EXISTS_TAC `\x:real^N. Cx(Re(h x)) + ii * Cx(Re(g x))` THEN + ASM_SIMP_TAC[] THEN X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN + GEN_REWRITE_TAC (LAND_CONV o RAND_CONV o LAND_CONV) [COMPLEX_EXPAND] THEN + MATCH_MP_TAC(NORM_ARITH + `norm(x1 - x2) < e / &2 /\ norm(y1 - y2) < e / &2 + ==> norm((x1 + y1) - (x2 + y2)) < e`) THEN + ASM_SIMP_TAC[GSYM CX_SUB; COMPLEX_NORM_CX; GSYM COMPLEX_SUB_LDISTRIB; + COMPLEX_NORM_MUL; COMPLEX_NORM_II; REAL_MUL_LID]]);; + +let COMPLEX_STONE_WEIERSTRASS = prove + (`!P s. compact s /\ + (!f. P f ==> f continuous_on s) /\ + (!c. P (\x. c)) /\ + (!f. P f ==> P(\x. cnj(f x))) /\ + (!f g. P f /\ P g ==> P (\x. f x + g x)) /\ + (!f g. P f /\ P g ==> P (\x. f x * g x)) /\ + (!x y. x IN s /\ y IN s /\ ~(x = y) ==> ?f. P f /\ ~(f x = f y)) + ==> !f:real^N->complex e. + f continuous_on s /\ &0 < e + ==> ?g. P g /\ !x. x IN s ==> norm(f x - g x) < e`, + REPEAT GEN_TAC THEN STRIP_TAC THEN + MATCH_MP_TAC COMPLEX_STONE_WEIERSTRASS_ALT THEN ASM_SIMP_TAC[] THEN + MAP_EVERY X_GEN_TAC [`x:real^N`; `y:real^N`] THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`x:real^N`; `y:real^N`]) THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC MONO_EXISTS THEN ASM_MESON_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* Stone-Weierstrass for R^n -> R polynomials. *) +(* ------------------------------------------------------------------------- *) + +let real_polynomial_function_RULES, + real_polynomial_function_INDUCT, + real_polynomial_function_CASES = new_inductive_definition + `(!i. 1 <= i /\ i <= dimindex(:N) + ==> real_polynomial_function(\x:real^N. x$i)) /\ + (!c. real_polynomial_function(\x:real^N. c)) /\ + (!f g. real_polynomial_function f /\ real_polynomial_function g + ==> real_polynomial_function(\x:real^N. f x + g x)) /\ + (!f g. real_polynomial_function f /\ real_polynomial_function g + ==> real_polynomial_function(\x:real^N. f x * g x))`;; + +let REAL_CONTINUOUS_REAL_POLYMONIAL_FUNCTION = prove + (`!f x:real^N. + real_polynomial_function f ==> f real_continuous at x`, + REWRITE_TAC[RIGHT_FORALL_IMP_THM] THEN + MATCH_MP_TAC real_polynomial_function_INDUCT THEN + SIMP_TAC[REAL_CONTINUOUS_ADD; REAL_CONTINUOUS_MUL; + REAL_CONTINUOUS_CONST; REAL_CONTINUOUS_AT_COMPONENT]);; + +let STONE_WEIERSTRASS_REAL_POLYNOMIAL_FUNCTION = prove + (`!f:real^N->real s e. + compact s /\ + (!x. x IN s ==> f real_continuous at x within s) /\ + &0 < e + ==> ?g. real_polynomial_function g /\ + !x. x IN s ==> abs(f x - g x) < e`, + REPEAT STRIP_TAC THEN + MATCH_MP_TAC(REWRITE_RULE[RIGHT_IMP_FORALL_THM; IMP_IMP] + STONE_WEIERSTRASS) THEN + ASM_REWRITE_TAC[real_polynomial_function_RULES] THEN + SIMP_TAC[REAL_CONTINUOUS_REAL_POLYMONIAL_FUNCTION; + REAL_CONTINUOUS_AT_WITHIN] THEN + MAP_EVERY X_GEN_TAC [`x:real^N`; `y:real^N`] THEN + REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + GEN_REWRITE_TAC (LAND_CONV o RAND_CONV) [CART_EQ] THEN + REWRITE_TAC[NOT_FORALL_THM; NOT_IMP; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `i:num` THEN STRIP_TAC THEN EXISTS_TAC `\x:real^N. x$i` THEN + ASM_SIMP_TAC[real_polynomial_function_RULES]);; + +(* ------------------------------------------------------------------------- *) +(* Stone-Weierstrass for real^M->real^N polynomials. *) +(* ------------------------------------------------------------------------- *) + +let vector_polynomial_function = new_definition + `vector_polynomial_function (f:real^M->real^N) <=> + !i. 1 <= i /\ i <= dimindex(:N) + ==> real_polynomial_function(\x. f(x)$i)`;; + +let VECTOR_POLYNOMIAL_FUNCTION_CONST = prove + (`!c. vector_polynomial_function(\x. c)`, + SIMP_TAC[vector_polynomial_function; real_polynomial_function_RULES]);; + +let VECTOR_POLYNOMIAL_FUNCTION_ID = prove + (`vector_polynomial_function(\x. x)`, + SIMP_TAC[vector_polynomial_function; real_polynomial_function_RULES]);; + +let VECTOR_POLYNOMIAL_FUNCTION_COMPONENT = prove + (`!f:real^M->real^N i. + 1 <= i /\ i <= dimindex(:N) /\ vector_polynomial_function f + ==> vector_polynomial_function(\x. lift(f x$i))`, + SIMP_TAC[vector_polynomial_function; FORALL_1; DIMINDEX_1; GSYM drop; + LIFT_DROP]);; + +let VECTOR_POLYNOMIAL_FUNCTION_ADD = prove + (`!f g:real^M->real^N. + vector_polynomial_function f /\ vector_polynomial_function g + ==> vector_polynomial_function (\x. f x + g x)`, + + REWRITE_TAC[vector_polynomial_function] THEN + SIMP_TAC[VECTOR_ADD_COMPONENT; real_polynomial_function_RULES]);; + +let VECTOR_POLYNOMIAL_FUNCTION_MUL = prove + (`!f g:real^M->real^N. + vector_polynomial_function(lift o f) /\ vector_polynomial_function g + ==> vector_polynomial_function (\x. f x % g x)`, + REWRITE_TAC[vector_polynomial_function; o_DEF; VECTOR_MUL_COMPONENT] THEN + REWRITE_TAC[FORALL_1; DIMINDEX_1; GSYM drop; LIFT_DROP; ETA_AX] THEN + SIMP_TAC[real_polynomial_function_RULES]);; + +let VECTOR_POLYNOMIAL_FUNCTION_CMUL = prove + (`!f:real^M->real^N c. + vector_polynomial_function f + ==> vector_polynomial_function (\x. c % f x)`, + SIMP_TAC[VECTOR_POLYNOMIAL_FUNCTION_CONST; VECTOR_POLYNOMIAL_FUNCTION_MUL; + ETA_AX; o_DEF]);; + +let VECTOR_POLYNOMIAL_FUNCTION_NEG = prove + (`!f:real^M->real^N. + vector_polynomial_function f + ==> vector_polynomial_function (\x. --(f x))`, + REWRITE_TAC[VECTOR_ARITH `--x:real^N = --(&1) % x`] THEN + REWRITE_TAC[VECTOR_POLYNOMIAL_FUNCTION_CMUL]);; + +let VECTOR_POLYNOMIAL_FUNCTION_SUB = prove + (`!f g:real^M->real^N. + vector_polynomial_function f /\ vector_polynomial_function g + ==> vector_polynomial_function (\x. f x - g x)`, + SIMP_TAC[VECTOR_SUB; VECTOR_POLYNOMIAL_FUNCTION_ADD; + VECTOR_POLYNOMIAL_FUNCTION_NEG]);; + +let VECTOR_POLYNOMIAL_FUNCTION_VSUM = prove + (`!f:real^M->A->real^N s. + FINITE s /\ (!i. i IN s ==> vector_polynomial_function (\x. f x i)) + ==> vector_polynomial_function (\x. vsum s (f x))`, + GEN_TAC THEN REWRITE_TAC[IMP_CONJ] THEN + MATCH_MP_TAC FINITE_INDUCT_STRONG THEN + SIMP_TAC[VSUM_CLAUSES; FORALL_IN_INSERT; VECTOR_POLYNOMIAL_FUNCTION_CONST; + VECTOR_POLYNOMIAL_FUNCTION_ADD]);; + +let CONTINUOUS_VECTOR_POLYNOMIAL_FUNCTION = prove + (`!f:real^M->real^N x. + vector_polynomial_function f ==> f continuous at x`, + REWRITE_TAC[vector_polynomial_function; CONTINUOUS_COMPONENTWISE] THEN + REPEAT STRIP_TAC THEN + MATCH_MP_TAC REAL_CONTINUOUS_REAL_POLYMONIAL_FUNCTION THEN + ASM_SIMP_TAC[]);; + +let CONTINUOUS_ON_VECTOR_POLYNOMIAL_FUNCTION = prove + (`!f:real^M->real^N s. + vector_polynomial_function f ==> f continuous_on s`, + SIMP_TAC[CONTINUOUS_AT_IMP_CONTINUOUS_ON; + CONTINUOUS_VECTOR_POLYNOMIAL_FUNCTION]);; + +let HAS_VECTOR_DERIVATIVE_VECTOR_POLYNOMIAL_FUNCTION = prove + (`!p:real^1->real^N. + vector_polynomial_function p + ==> ?p'. vector_polynomial_function p' /\ + !x. (p has_vector_derivative p'(x)) (at x)`, + let lemma = prove + (`!p:real^1->real. + real_polynomial_function p + ==> ?p'. real_polynomial_function p' /\ + !x. ((p o lift) has_real_derivative (p'(lift x))) (atreal x)`, + MATCH_MP_TAC + (derive_strong_induction(real_polynomial_function_RULES, + real_polynomial_function_INDUCT)) THEN + REWRITE_TAC[DIMINDEX_1; FORALL_1; o_DEF; GSYM drop; LIFT_DROP] THEN + CONJ_TAC THENL + [EXISTS_TAC `\x:real^1. &1` THEN + REWRITE_TAC[real_polynomial_function_RULES; HAS_REAL_DERIVATIVE_ID]; + ALL_TAC] THEN + CONJ_TAC THENL + [X_GEN_TAC `c:real` THEN EXISTS_TAC `\x:real^1. &0` THEN + REWRITE_TAC[real_polynomial_function_RULES; HAS_REAL_DERIVATIVE_CONST]; + ALL_TAC] THEN + CONJ_TAC THEN + MAP_EVERY X_GEN_TAC [`f:real^1->real`; `g:real^1->real`] THEN + DISCH_THEN(CONJUNCTS_THEN2 + (CONJUNCTS_THEN2 ASSUME_TAC + (X_CHOOSE_THEN `f':real^1->real` STRIP_ASSUME_TAC)) + (CONJUNCTS_THEN2 ASSUME_TAC + (X_CHOOSE_THEN `g':real^1->real` STRIP_ASSUME_TAC))) + THENL + [EXISTS_TAC `\x. (f':real^1->real) x + g' x`; + EXISTS_TAC `\x. (f:real^1->real) x * g' x + f' x * g x`] THEN + ASM_SIMP_TAC[real_polynomial_function_RULES; HAS_REAL_DERIVATIVE_ADD; + HAS_REAL_DERIVATIVE_MUL_ATREAL]) in + GEN_TAC THEN REWRITE_TAC[vector_polynomial_function] THEN DISCH_TAC THEN + SUBGOAL_THEN + `!i. 1 <= i /\ i <= dimindex(:N) + ==> ?q. real_polynomial_function q /\ + (!x. ((\x. lift(((p x):real^N)$i)) has_vector_derivative + lift(q x)) (at x))` + MP_TAC THENL + [X_GEN_TAC `i:num` THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `i:num`) THEN + ASM_REWRITE_TAC[] THEN + DISCH_THEN(MP_TAC o MATCH_MP lemma) THEN + REWRITE_TAC[HAS_REAL_VECTOR_DERIVATIVE_AT] THEN + REWRITE_TAC[o_DEF; LIFT_DROP; FORALL_DROP]; + GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [RIGHT_IMP_EXISTS_THM] THEN + REWRITE_TAC[SKOLEM_THM; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `q:num->real^1->real` THEN DISCH_TAC THEN + EXISTS_TAC `(\x. lambda i. (q:num->real^1->real) i x):real^1->real^N` THEN + ASM_SIMP_TAC[LAMBDA_BETA; ETA_AX] THEN + REWRITE_TAC[has_vector_derivative; has_derivative_at] THEN + ONCE_REWRITE_TAC[LIM_COMPONENTWISE] THEN X_GEN_TAC `x:real^1` THEN + SIMP_TAC[LINEAR_VMUL_DROP; LINEAR_ID] 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 REPEAT STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `x:real^1`) THEN + REWRITE_TAC[has_vector_derivative; has_derivative_at] THEN + ASM_SIMP_TAC[VECTOR_MUL_COMPONENT; VEC_COMPONENT; VECTOR_SUB_COMPONENT; + VECTOR_ADD_COMPONENT; LAMBDA_BETA; REAL_TENDSTO] THEN + SIMP_TAC[DROP_ADD; DROP_VEC; LIFT_DROP; DROP_CMUL; DROP_SUB; o_DEF]]);; + +let STONE_WEIERSTRASS_VECTOR_POLYNOMIAL_FUNCTION = prove + (`!f:real^M->real^N s e. + compact s /\ f continuous_on s /\ &0 < e + ==> ?g. vector_polynomial_function g /\ + !x. x IN s ==> norm(f x - g x) < e`, + REPEAT STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I + [CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN]) THEN + REWRITE_TAC[CONTINUOUS_COMPONENTWISE] THEN + REWRITE_TAC[IMP_IMP; RIGHT_IMP_FORALL_THM] THEN DISCH_TAC THEN + SUBGOAL_THEN + `!i. 1 <= i /\ i <= dimindex(:N) + ==> ?g. real_polynomial_function g /\ + !x. x IN s ==> abs((f:real^M->real^N) x$i - g x) < + e / &(dimindex(:N))` + MP_TAC THENL + [REPEAT STRIP_TAC THEN + MATCH_MP_TAC STONE_WEIERSTRASS_REAL_POLYNOMIAL_FUNCTION THEN + ASM_SIMP_TAC[REAL_LT_DIV; REAL_OF_NUM_LT; DIMINDEX_GE_1; LE_1]; + GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) + [RIGHT_IMP_EXISTS_THM] THEN + REWRITE_TAC[SKOLEM_THM; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `g:num->real^M->real` THEN DISCH_TAC THEN + EXISTS_TAC `(\x. lambda i. g i x):real^M->real^N` THEN + ASM_SIMP_TAC[vector_polynomial_function; LAMBDA_BETA; ETA_AX] THEN + X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN + W(MP_TAC o PART_MATCH lhand NORM_LE_L1 o lhand o snd) THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] REAL_LET_TRANS) THEN + MATCH_MP_TAC SUM_BOUND_LT_GEN THEN + REWRITE_TAC[FINITE_NUMSEG; CARD_NUMSEG_1; NUMSEG_EMPTY; NOT_LT] THEN + ASM_SIMP_TAC[IN_NUMSEG; DIMINDEX_GE_1; LAMBDA_BETA; + VECTOR_SUB_COMPONENT]]);; + +let STONE_WEIERSTRASS_VECTOR_POLYNOMIAL_FUNCTION_SUBSPACE = prove + (`!f:real^M->real^N s e t. + compact s /\ f continuous_on s /\ &0 < e /\ + subspace t /\ IMAGE f s SUBSET t + ==> ?g. vector_polynomial_function g /\ IMAGE g s SUBSET t /\ + !x. x IN s ==> norm(f x - g x) < e`, + REPEAT STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o MATCH_MP ORTHONORMAL_BASIS_SUBSPACE) THEN + DISCH_THEN(X_CHOOSE_THEN `bas:real^N->bool` MP_TAC) THEN + ASM_CASES_TAC `FINITE(bas:real^N->bool)` THENL + [ALL_TAC; ASM_MESON_TAC[HAS_SIZE]] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [FINITE_INDEX_NUMSEG]) THEN + ABBREV_TAC `n = CARD(bas:real^N->bool)` THEN + REWRITE_TAC[INJECTIVE_ON_ALT; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `b:num->real^N` THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC SUBST1_TAC) THEN + ASM_SIMP_TAC[REWRITE_RULE[INJECTIVE_ON_ALT] HAS_SIZE_IMAGE_INJ_EQ] THEN + REWRITE_TAC[HAS_SIZE; FINITE_NUMSEG; CARD_NUMSEG_1] THEN + ASM_CASES_TAC `dim(t:real^N->bool) = n` THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE] THEN STRIP_TAC THEN + MP_TAC(ISPEC `t:real^N->bool` DIM_SUBSET_UNIV) THEN ASM_REWRITE_TAC[] THEN + DISCH_TAC THEN MP_TAC(ISPECL + [`(\x. lambda i. (f x:real^N) dot (b i)):real^M->real^N`; + `s:real^M->bool`; `e:real`] + STONE_WEIERSTRASS_VECTOR_POLYNOMIAL_FUNCTION) THEN + ASM_REWRITE_TAC[] THEN ANTS_TAC THENL + [ONCE_REWRITE_TAC[CONTINUOUS_ON_COMPONENTWISE_LIFT] THEN + SIMP_TAC[LAMBDA_BETA] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC CONTINUOUS_ON_LIFT_DOT2 THEN + ASM_REWRITE_TAC[CONTINUOUS_ON_CONST]; + DISCH_THEN(X_CHOOSE_THEN `g:real^M->real^N` STRIP_ASSUME_TAC)] THEN + EXISTS_TAC `(\x. vsum(1..n) (\i. (g x:real^N)$i % b i)):real^M->real^N` THEN + REWRITE_TAC[] THEN REPEAT CONJ_TAC THENL + [MATCH_MP_TAC VECTOR_POLYNOMIAL_FUNCTION_VSUM THEN + REWRITE_TAC[FINITE_NUMSEG; IN_NUMSEG] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC VECTOR_POLYNOMIAL_FUNCTION_MUL THEN + REWRITE_TAC[VECTOR_POLYNOMIAL_FUNCTION_CONST; o_DEF] THEN + MATCH_MP_TAC VECTOR_POLYNOMIAL_FUNCTION_COMPONENT THEN + ASM_REWRITE_TAC[] THEN ASM_ARITH_TAC; + REPEAT STRIP_TAC THEN MATCH_MP_TAC SUBSPACE_VSUM THEN + ASM_SIMP_TAC[SUBSPACE_MUL; FINITE_NUMSEG]; + X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `x:real^M`) THEN + ASM_REWRITE_TAC[] THEN ONCE_REWRITE_TAC[DOT_SYM] THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] REAL_LET_TRANS) THEN + SUBGOAL_THEN + `vsum(IMAGE b (1..n)) (\v. (v dot f x) % v) = (f:real^M->real^N) x` + (fun th -> GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [SYM th]) + THENL + [MATCH_MP_TAC ORTHONORMAL_BASIS_EXPAND THEN + ASM_REWRITE_TAC[FORALL_IN_IMAGE] THEN ASM SET_TAC[]; + ASM_SIMP_TAC[REWRITE_RULE[INJECTIVE_ON_ALT] VSUM_IMAGE; + FINITE_NUMSEG] THEN + REWRITE_TAC[GSYM VSUM_SUB_NUMSEG; o_DEF; GSYM VECTOR_SUB_RDISTRIB] THEN + REWRITE_TAC[NORM_LE; GSYM NORM_POW_2] THEN + W(MP_TAC o PART_MATCH (lhs o rand) NORM_VSUM_PYTHAGOREAN o + lhand o snd) THEN + RULE_ASSUM_TAC(REWRITE_RULE[PAIRWISE_IMAGE]) THEN + RULE_ASSUM_TAC(REWRITE_RULE[pairwise]) THEN + ASM_SIMP_TAC[pairwise; ORTHOGONAL_MUL; FINITE_NUMSEG] THEN + DISCH_THEN SUBST1_TAC THEN REWRITE_TAC[NORM_MUL] THEN + REWRITE_TAC[NORM_POW_2] THEN GEN_REWRITE_TAC RAND_CONV [dot] THEN + SIMP_TAC[GSYM REAL_POW_2; VECTOR_SUB_COMPONENT; LAMBDA_BETA] THEN + MATCH_MP_TAC SUM_LE_INCLUDED THEN EXISTS_TAC `\n:num. n` THEN + REWRITE_TAC[FINITE_NUMSEG; REAL_LE_POW_2] THEN + ONCE_REWRITE_TAC[TAUT `p /\ q /\ r <=> q /\ p /\ r`] THEN + REWRITE_TAC[UNWIND_THM2] THEN + ONCE_REWRITE_TAC[TAUT `p ==> q /\ r <=> p ==> q /\ (q ==> r)`] THEN + RULE_ASSUM_TAC(REWRITE_RULE[IN_NUMSEG]) THEN + ASM_SIMP_TAC[LAMBDA_BETA; UNWIND_THM2; IN_NUMSEG] THEN + REWRITE_TAC[REAL_MUL_RID; REAL_POW2_ABS; REAL_LE_REFL] THEN + ASM_ARITH_TAC]]);; + +let STONE_WEIERSTRASS_VECTOR_POLYNOMIAL_FUNCTION_AFFINE = prove + (`!f:real^M->real^N s e t. + compact s /\ f continuous_on s /\ &0 < e /\ + affine t /\ IMAGE f s SUBSET t + ==> ?g. vector_polynomial_function g /\ IMAGE g s SUBSET t /\ + !x. x IN s ==> norm(f x - g x) < e`, + REPEAT GEN_TAC THEN ASM_CASES_TAC `t:real^N->bool = {}` THEN + ASM_REWRITE_TAC[SUBSET_EMPTY; IMAGE_EQ_EMPTY] THENL + [MESON_TAC[VECTOR_POLYNOMIAL_FUNCTION_CONST; NOT_IN_EMPTY]; + STRIP_TAC] THEN + MP_TAC(ISPEC `t:real^N->bool` AFFINE_TRANSLATION_SUBSPACE) THEN + ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`a:real^N`; `u:real^N->bool`] THEN STRIP_TAC THEN + FIRST_X_ASSUM SUBST_ALL_TAC THEN + MP_TAC(ISPECL + [`(\x. f x - a):real^M->real^N`; `s:real^M->bool`; `e:real`; + `u:real^N->bool`] STONE_WEIERSTRASS_VECTOR_POLYNOMIAL_FUNCTION_SUBSPACE) THEN + ASM_SIMP_TAC[CONTINUOUS_ON_SUB; CONTINUOUS_ON_CONST] THEN + FIRST_ASSUM(MP_TAC o ISPEC `\x:real^N. x - a` o MATCH_MP IMAGE_SUBSET) THEN + REWRITE_TAC[GSYM IMAGE_o; o_DEF; VECTOR_ADD_SUB; IMAGE_ID] THEN + DISCH_TAC THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `g:real^M->real^N` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `(\x. g x + a):real^M->real^N` THEN + ASM_SIMP_TAC[VECTOR_POLYNOMIAL_FUNCTION_ADD; + VECTOR_POLYNOMIAL_FUNCTION_CONST; + VECTOR_ARITH `a - (b + c):real^N = a - c - b`] THEN + FIRST_ASSUM(MP_TAC o ISPEC `\x:real^N. a + x` o MATCH_MP IMAGE_SUBSET) THEN + REWRITE_TAC[GSYM IMAGE_o; o_DEF; VECTOR_ADD_AC]);; + +(* ------------------------------------------------------------------------- *) +(* One application is to pick a smooth approximation to a path, or just pick *) +(* a smooth path anyway in an open connected set. *) +(* ------------------------------------------------------------------------- *) + +let PATH_VECTOR_POLYNOMIAL_FUNCTION = prove + (`!g:real^1->real^N. vector_polynomial_function g ==> path g`, + SIMP_TAC[path; CONTINUOUS_ON_VECTOR_POLYNOMIAL_FUNCTION]);; + +let PATH_APPROX_VECTOR_POLYNOMIAL_FUNCTION = prove + (`!g:real^1->real^N e. + path g /\ &0 < e + ==> ?p. vector_polynomial_function p /\ + pathstart p = pathstart g /\ + pathfinish p = pathfinish g /\ + !t. t IN interval[vec 0,vec 1] ==> norm(p t - g t) < e`, + REWRITE_TAC[path] THEN REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`g:real^1->real^N`; `interval[vec 0:real^1,vec 1]`; `e / &4`] + STONE_WEIERSTRASS_VECTOR_POLYNOMIAL_FUNCTION) THEN + ASM_REWRITE_TAC[COMPACT_INTERVAL; REAL_ARITH `&0 < x / &4 <=> &0 < x`] THEN + DISCH_THEN(X_CHOOSE_THEN `q:real^1->real^N` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `\t. (q:real^1->real^N)(t) + (g(vec 0:real^1) - q(vec 0)) + + drop t % ((g(vec 1) - q(vec 1)) - (g(vec 0) - q(vec 0)))` THEN + REWRITE_TAC[pathstart; pathfinish; DROP_VEC] THEN REPEAT CONJ_TAC THENL + [SIMP_TAC[vector_polynomial_function; VECTOR_ADD_COMPONENT; + VECTOR_MUL_COMPONENT; VECTOR_SUB_COMPONENT] THEN + REPEAT STRIP_TAC THEN + RULE_ASSUM_TAC(REWRITE_RULE[vector_polynomial_function]) THEN + MATCH_MP_TAC(el 2 (CONJUNCTS real_polynomial_function_RULES)) THEN + ASM_SIMP_TAC[real_polynomial_function_RULES; drop; DIMINDEX_1; ARITH]; + VECTOR_ARITH_TAC; + VECTOR_ARITH_TAC; + REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[VECTOR_SUB_LDISTRIB] THEN + MATCH_MP_TAC(NORM_ARITH + `norm(x - a) < e / &4 /\ norm b < e / &4 /\ norm c <= &1 * e / &4 /\ + norm d <= &1 * e / &4 + ==> norm((a + b + c - d) - x:real^N) < e`) THEN + ASM_SIMP_TAC[NORM_MUL; IN_INTERVAL_1; DROP_VEC; REAL_POS] THEN + CONJ_TAC THEN MATCH_MP_TAC REAL_LE_MUL2 THEN + ASM_SIMP_TAC[REAL_LT_IMP_LE; IN_INTERVAL_1; DROP_VEC; REAL_POS; + REAL_LE_REFL; NORM_POS_LE] THEN + RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1; DROP_VEC]) THEN + ASM_REAL_ARITH_TAC]);; + +let CONNECTED_OPEN_VECTOR_POLYNOMIAL_CONNECTED = prove + (`!s:real^N->bool. + open s /\ connected s + ==> !x y. x IN s /\ y IN s + ==> ?g. vector_polynomial_function g /\ + path_image g SUBSET s /\ + pathstart g = x /\ + pathfinish g = y`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN `path_connected(s:real^N->bool)` MP_TAC THENL + [ASM_SIMP_TAC[CONNECTED_OPEN_PATH_CONNECTED]; + REWRITE_TAC[path_connected]] THEN + DISCH_THEN(MP_TAC o SPECL [`x:real^N`; `y:real^N`]) THEN + ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `p:real^1->real^N` STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN + `?e. &0 < e /\ !x. x IN path_image p ==> ball(x:real^N,e) SUBSET s` + STRIP_ASSUME_TAC THENL + [ASM_CASES_TAC `s = (:real^N)` THEN ASM_REWRITE_TAC[SUBSET_UNIV] THENL + [MESON_TAC[REAL_LT_01]; ALL_TAC] THEN + EXISTS_TAC `setdist(path_image p,(:real^N) DIFF s)` THEN CONJ_TAC THENL + [ASM_REWRITE_TAC[REAL_ARITH `&0 < x <=> &0 <= x /\ ~(x = &0)`] THEN + ASM_SIMP_TAC[SETDIST_POS_LE; SETDIST_EQ_0_COMPACT_CLOSED; + COMPACT_PATH_IMAGE; GSYM OPEN_CLOSED] THEN + ASM_SIMP_TAC[PATH_IMAGE_NONEMPTY] THEN ASM SET_TAC[]; + X_GEN_TAC `z:real^N` THEN DISCH_TAC THEN REWRITE_TAC[SUBSET] THEN + X_GEN_TAC `w:real^N` THEN REWRITE_TAC[IN_BALL; GSYM REAL_NOT_LE] THEN + MATCH_MP_TAC(SET_RULE + `(w IN (UNIV DIFF s) ==> p) ==> (~p ==> w IN s)`) THEN + ASM_SIMP_TAC[SETDIST_LE_DIST]]; + MP_TAC(ISPECL [`p:real^1->real^N`; `e:real`] + PATH_APPROX_VECTOR_POLYNOMIAL_FUNCTION) THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC MONO_EXISTS THEN + X_GEN_TAC `q:real^1->real^N` THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[path_image; FORALL_IN_IMAGE; SUBSET] THEN RULE_ASSUM_TAC + (REWRITE_RULE[SUBSET; path_image; FORALL_IN_IMAGE;IN_BALL; dist]) THEN + ASM_MESON_TAC[NORM_SUB]]);; + +(* ------------------------------------------------------------------------- *) +(* Lipschitz property for real and vector polynomials. *) +(* ------------------------------------------------------------------------- *) + +let LIPSCHITZ_REAL_POLYNOMIAL_FUNCTION = prove + (`!f:real^N->real s. + real_polynomial_function f /\ bounded s + ==> ?B. &0 < B /\ + !x y. x IN s /\ y IN s ==> abs(f x - f y) <= B * norm(x - y)`, + ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN GEN_TAC THEN + ASM_CASES_TAC `bounded(s:real^N->bool)` THEN ASM_REWRITE_TAC[] THEN + ASM_CASES_TAC `s:real^N->bool = {}` THENL + [ASM_REWRITE_TAC[NOT_IN_EMPTY] THEN MESON_TAC[REAL_LT_01]; ALL_TAC] THEN + MATCH_MP_TAC real_polynomial_function_INDUCT THEN REPEAT CONJ_TAC THENL + [REPEAT STRIP_TAC THEN EXISTS_TAC `&1` THEN REWRITE_TAC[REAL_LT_01] THEN + ASM_SIMP_TAC[REAL_MUL_LID; GSYM VECTOR_SUB_COMPONENT; COMPONENT_LE_NORM]; + GEN_TAC THEN EXISTS_TAC `&1` THEN + SIMP_TAC[REAL_LT_01; REAL_SUB_REFL; REAL_ABS_NUM; REAL_MUL_LID; + NORM_POS_LE]; + ALL_TAC; ALL_TAC] THEN + MAP_EVERY X_GEN_TAC [`f:real^N->real`; `g:real^N->real`] THEN + DISCH_THEN(CONJUNCTS_THEN2 + (X_CHOOSE_THEN `B1:real` STRIP_ASSUME_TAC) + (X_CHOOSE_THEN `B2:real` STRIP_ASSUME_TAC)) + THENL + [EXISTS_TAC `B1 + B2:real` THEN ASM_SIMP_TAC[REAL_LT_ADD] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC(REAL_ARITH + `abs(f - f') <= B1 * n /\ abs(g - g') <= B2 * n + ==> abs((f + g) - (f' + g')) <= (B1 + B2) * n`) THEN + ASM_SIMP_TAC[]; + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN + DISCH_THEN(X_CHOOSE_TAC `a:real^N`) THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [BOUNDED_POS]) THEN + DISCH_THEN(X_CHOOSE_THEN `B:real` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `B1 * (abs(g(a:real^N)) + B2 * &2 * B) + + B2 * (abs(f a) + B1 * &2 * B)` THEN + CONJ_TAC THENL + [MATCH_MP_TAC REAL_LT_ADD THEN CONJ_TAC THEN MATCH_MP_TAC REAL_LT_MUL THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC(REAL_ARITH + `&0 < x ==> &0 < abs a + x`) THEN + MATCH_MP_TAC REAL_LT_MUL THEN ASM_REAL_ARITH_TAC; + REPEAT STRIP_TAC THEN REWRITE_TAC[] THEN MATCH_MP_TAC(REAL_ARITH + `abs((f - f') * g) <= a * n /\ abs((g - g') * f') <= b * n + ==> abs(f * g - f' * g') <= (a + b) * n`) THEN + ONCE_REWRITE_TAC[REAL_ARITH `(a * b) * c:real = (a * c) * b`] THEN + REWRITE_TAC[REAL_ABS_MUL] THEN + CONJ_TAC THEN MATCH_MP_TAC REAL_LE_MUL2 THEN + ASM_SIMP_TAC[REAL_ABS_POS] THEN MATCH_MP_TAC(REAL_ARITH + `abs(g x - g a) <= C * norm(x - a) /\ + C * norm(x - a:real^N) <= C * B ==> abs(g x) <= abs(g a) + C * B`) THEN + ASM_SIMP_TAC[REAL_LE_LMUL_EQ] THEN MATCH_MP_TAC(NORM_ARITH + `norm x <= B /\ norm a <= B ==> norm(x - a:real^N) <= &2 * B`) THEN + ASM_SIMP_TAC[]]]);; + +let LIPSCHITZ_VECTOR_POLYNOMIAL_FUNCTION = prove + (`!f:real^M->real^N s. + vector_polynomial_function f /\ bounded s + ==> ?B. &0 < B /\ + !x y. x IN s /\ y IN s ==> norm(f x - f y) <= B * norm(x - y)`, + REWRITE_TAC[vector_polynomial_function] THEN REPEAT STRIP_TAC THEN + SUBGOAL_THEN + `?b. !i. 1 <= i /\ i <= dimindex(:N) + ==> &0 < (b:real^N)$i /\ + !x y. x IN s /\ y IN s + ==> abs((f:real^M->real^N) x$i - f y$i) <= + b$i * norm(x - y)` + STRIP_ASSUME_TAC THENL + [REWRITE_TAC[GSYM LAMBDA_SKOLEM] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC LIPSCHITZ_REAL_POLYNOMIAL_FUNCTION THEN + ASM_SIMP_TAC[LIPSCHITZ_REAL_POLYNOMIAL_FUNCTION]; + EXISTS_TAC `&1 + sum(1..dimindex(:N)) (\i. (b:real^N)$i)` THEN + CONJ_TAC THENL + [MATCH_MP_TAC(REAL_ARITH `&0 <= x ==> &0 < &1 + x`) THEN + MATCH_MP_TAC SUM_POS_LE_NUMSEG THEN ASM_SIMP_TAC[REAL_LT_IMP_LE]; + REPEAT STRIP_TAC THEN + W(MP_TAC o PART_MATCH lhand NORM_LE_L1 o lhand o snd) THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] REAL_LE_TRANS) THEN + REWRITE_TAC[REAL_ADD_RDISTRIB; GSYM SUM_RMUL; REAL_MUL_LID] THEN + MATCH_MP_TAC(NORM_ARITH `x <= y ==> x <= norm(a:real^N) + y`) THEN + MATCH_MP_TAC SUM_LE_NUMSEG THEN + ASM_SIMP_TAC[VECTOR_SUB_COMPONENT]]]);; + +(* ------------------------------------------------------------------------- *) +(* Differentiability of real and vector polynomial functions. *) +(* ------------------------------------------------------------------------- *) + +let DIFFERENTIABLE_REAL_POLYNOMIAL_FUNCTION_AT = prove + (`!f:real^N->real a. + real_polynomial_function f ==> (lift o f) differentiable (at a)`, + ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN GEN_TAC THEN + MATCH_MP_TAC real_polynomial_function_INDUCT THEN + REWRITE_TAC[o_DEF; LIFT_ADD; LIFT_CMUL] THEN + REWRITE_TAC[DIFFERENTIABLE_LIFT_COMPONENT; DIFFERENTIABLE_CONST] THEN + SIMP_TAC[DIFFERENTIABLE_ADD] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC DIFFERENTIABLE_MUL_AT THEN + ASM_REWRITE_TAC[o_DEF]);; + +let DIFFERENTIABLE_ON_REAL_POLYNOMIAL_FUNCTION = prove + (`!f:real^N->real s. + real_polynomial_function f ==> (lift o f) differentiable_on s`, + SIMP_TAC[DIFFERENTIABLE_AT_IMP_DIFFERENTIABLE_ON; + DIFFERENTIABLE_REAL_POLYNOMIAL_FUNCTION_AT]);; + +let DIFFERENTIABLE_VECTOR_POLYNOMIAL_FUNCTION = prove + (`!f:real^M->real^N a. + vector_polynomial_function f ==> f differentiable (at a)`, + REWRITE_TAC[vector_polynomial_function] THEN REPEAT STRIP_TAC THEN + ONCE_REWRITE_TAC[DIFFERENTIABLE_COMPONENTWISE_AT] THEN + REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[GSYM o_DEF] THEN + MATCH_MP_TAC DIFFERENTIABLE_REAL_POLYNOMIAL_FUNCTION_AT THEN + ASM_SIMP_TAC[]);; + +let DIFFERENTIABLE_ON_VECTOR_POLYNOMIAL_FUNCTION = prove + (`!f:real^M->real^N s. + vector_polynomial_function f ==> f differentiable_on s`, + SIMP_TAC[DIFFERENTIABLE_AT_IMP_DIFFERENTIABLE_ON; + DIFFERENTIABLE_VECTOR_POLYNOMIAL_FUNCTION]);; + +(* ------------------------------------------------------------------------- *) +(* Specific properties of complex measurable functions. *) +(* ------------------------------------------------------------------------- *) + +let MEASURABLE_ON_COMPLEX_MUL = prove + (`!f g:real^N->complex s. + f measurable_on s /\ g measurable_on s + ==> (\x. f x * g x) measurable_on s`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC MEASURABLE_ON_COMBINE THEN + ASM_REWRITE_TAC[COMPLEX_VEC_0; COMPLEX_MUL_LZERO] THEN + MATCH_MP_TAC CONTINUOUS_ON_COMPLEX_MUL THEN + CONJ_TAC THEN MATCH_MP_TAC LINEAR_CONTINUOUS_ON THEN + REWRITE_TAC[LINEAR_FSTCART; LINEAR_SNDCART]);; + +let MEASURABLE_ON_COMPLEX_INV = prove + (`!f:real^N->real^2. + f measurable_on (:real^N) /\ negligible {x | f x = Cx(&0)} + ==> (\x. inv(f x)) measurable_on (:real^N)`, + GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN + REWRITE_TAC[measurable_on; IN_UNIV; LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`k:real^N->bool`; `g:num->real^N->complex`] THEN + STRIP_TAC THEN EXISTS_TAC `k UNION {x:real^N | f x = Cx(&0)}` THEN + ASM_SIMP_TAC[NEGLIGIBLE_UNION] THEN + SUBGOAL_THEN + `!n. ?h. h continuous_on (:real^N) /\ + !x. x IN {x | g n x IN (:complex) DIFF ball(Cx(&0),inv(&n + &1))} + ==> (h:real^N->complex) x = inv(g n x)` + + MP_TAC THENL + [X_GEN_TAC `n:num` THEN MATCH_MP_TAC TIETZE_UNBOUNDED THEN CONJ_TAC THENL + [REWRITE_TAC[SUBTOPOLOGY_UNIV; GSYM CLOSED_IN] THEN + MATCH_MP_TAC CONTINUOUS_CLOSED_PREIMAGE_UNIV THEN + REWRITE_TAC[GSYM OPEN_CLOSED; OPEN_BALL; ETA_AX] THEN + ASM_MESON_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_AT; OPEN_UNIV; IN_UNIV]; + REWRITE_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN] THEN + GEN_TAC THEN DISCH_TAC THEN MATCH_MP_TAC CONTINUOUS_AT_WITHIN THEN + MATCH_MP_TAC CONTINUOUS_COMPLEX_INV_AT THEN CONJ_TAC THENL + [REWRITE_TAC[ETA_AX] THEN + ASM_MESON_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_AT; OPEN_UNIV; IN_UNIV]; + RULE_ASSUM_TAC(REWRITE_RULE[IN_ELIM_THM; IN_UNIV; IN_DIFF]) THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE RAND_CONV [IN_BALL]) THEN + SIMP_TAC[CONTRAPOS_THM; DIST_REFL; REAL_LT_INV_EQ] THEN + REAL_ARITH_TAC]]; + REWRITE_TAC[SKOLEM_THM] THEN MATCH_MP_TAC MONO_EXISTS THEN + X_GEN_TAC `h:num->real^N->complex` THEN + REWRITE_TAC[FORALL_AND_THM; IN_ELIM_THM; IN_DIFF; IN_UNION; IN_UNIV] THEN + REWRITE_TAC[IN_BALL; DE_MORGAN_THM; REAL_NOT_LT] THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN X_GEN_TAC `x:real^N` THEN + STRIP_TAC THEN MATCH_MP_TAC LIM_TRANSFORM THEN + EXISTS_TAC `\n. inv((g:num->real^N->complex) n x)` THEN + ASM_SIMP_TAC[o_DEF; LIM_COMPLEX_INV] THEN + MATCH_MP_TAC LIM_EVENTUALLY THEN + REWRITE_TAC[EVENTUALLY_SEQUENTIALLY] THEN + SUBGOAL_THEN `&0 < norm((f:real^N->complex) x)` ASSUME_TAC THENL + [ASM_REWRITE_TAC[COMPLEX_NORM_NZ]; ALL_TAC] THEN + FIRST_X_ASSUM(MP_TAC o SPEC `x:real^N`) THEN + ASM_REWRITE_TAC[LIM_SEQUENTIALLY] THEN + DISCH_THEN(MP_TAC o SPEC `norm((f:real^N->complex) x) / &2`) THEN + ASM_REWRITE_TAC[REAL_HALF] THEN + DISCH_THEN(X_CHOOSE_THEN `N1:num` (LABEL_TAC "*")) THEN + MP_TAC(SPEC `norm((f:real^N->complex) x) / &2` REAL_ARCH_INV) THEN + ASM_REWRITE_TAC[REAL_HALF] THEN + DISCH_THEN(X_CHOOSE_THEN `N2:num` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `N1 + N2 + 1` THEN X_GEN_TAC `n:num` THEN STRIP_TAC THEN + REWRITE_TAC[VECTOR_SUB_EQ] THEN CONV_TAC SYM_CONV THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN + REWRITE_TAC[GSYM COMPLEX_VEC_0; DIST_0] THEN + REMOVE_THEN "*" (MP_TAC o SPEC `n:num`) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN + DISCH_THEN(MP_TAC o MATCH_MP (NORM_ARITH + `dist(g,f) < norm(f) / &2 ==> norm(f) / &2 <= norm g`)) THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] REAL_LE_TRANS) THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH + `x < y ==> z <= x ==> z <= y`)) THEN + MATCH_MP_TAC REAL_LE_INV2 THEN + ASM_REWRITE_TAC[REAL_OF_NUM_ADD; REAL_OF_NUM_LE; REAL_OF_NUM_LT] THEN + ASM_ARITH_TAC]);; + +let MEASURABLE_ON_COMPLEX_DIV = prove + (`!f g:real^N->complex s. + f measurable_on s /\ g measurable_on (:real^N) /\ + negligible {x | g(x) = Cx(&0)} + ==> (\x. f(x) / g(x)) measurable_on s`, + let lemma = prove + (`!f g:real^N->complex. + f measurable_on (:real^N) /\ g measurable_on (:real^N) /\ + negligible {x | g(x) = Cx(&0)} + ==> (\x. f(x) / g(x)) measurable_on (:real^N)`, + REPEAT STRIP_TAC THEN REWRITE_TAC[complex_div] THEN + ASM_SIMP_TAC[MEASURABLE_ON_COMPLEX_MUL; MEASURABLE_ON_COMPLEX_INV]) in + REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[GSYM MEASURABLE_ON_UNIV] THEN + REWRITE_TAC[IN_UNIV; ETA_AX] THEN DISCH_THEN(MP_TAC o MATCH_MP lemma) THEN + MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_TERM_TAC THEN + REWRITE_TAC[FUN_EQ_THM; complex_div; COMPLEX_VEC_0] THEN + GEN_TAC THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[COMPLEX_MUL_LZERO]);; + +(* ------------------------------------------------------------------------- *) +(* Measurable real->real functions. *) +(* ------------------------------------------------------------------------- *) + +parse_as_infix("real_measurable_on",(12,"right"));; + +let real_measurable_on = new_definition + `f real_measurable_on s <=> + (lift o f o drop) measurable_on (IMAGE lift s)`;; + +let real_lebesgue_measurable = new_definition + `real_lebesgue_measurable s <=> + (\x. if x IN s then &1 else &0) real_measurable_on (:real)`;; + +let REAL_MEASURABLE_ON_UNIV = prove + (`(\x. if x IN s then f(x) else &0) real_measurable_on (:real) <=> + f real_measurable_on s`, + REWRITE_TAC[real_measurable_on; o_DEF; IMAGE_LIFT_UNIV] THEN + SIMP_TAC[COND_RAND; LIFT_NUM; MEASURABLE_ON_UNIV; GSYM IN_IMAGE_LIFT_DROP]);; + +let REAL_LEBESGUE_MEASURABLE = prove + (`!s. real_lebesgue_measurable s <=> lebesgue_measurable (IMAGE lift s)`, + REWRITE_TAC[real_lebesgue_measurable; lebesgue_measurable; COND_RAND; + COND_RAND; real_measurable_on; indicator; IMAGE_LIFT_UNIV; o_DEF] THEN + REWRITE_TAC[LIFT_NUM; IN_IMAGE_LIFT_DROP]);; + +let REAL_MEASURABLE_BOUNDED_BY_INTEGRABLE_IMP_INTEGRABLE = prove + (`!f g s. + f real_measurable_on s /\ + g real_integrable_on s /\ + (!x. x IN s ==> abs(f x) <= g x) + ==> f real_integrable_on s`, + REWRITE_TAC[real_measurable_on; REAL_INTEGRABLE_ON] THEN + REPEAT STRIP_TAC THEN + MATCH_MP_TAC MEASURABLE_BOUNDED_BY_INTEGRABLE_IMP_INTEGRABLE THEN + EXISTS_TAC `lift o g o drop` THEN + ASM_REWRITE_TAC[FORALL_IN_IMAGE; o_THM; LIFT_DROP; NORM_LIFT]);; + +let REAL_MEASURABLE_BOUNDED_BY_INTEGRABLE_IMP_ABSOLUTELY_INTEGRABLE = prove + (`!f g s. + f real_measurable_on s /\ + g real_integrable_on s /\ + (!x. x IN s ==> abs(f x) <= g x) + ==> f absolutely_real_integrable_on s`, + REWRITE_TAC[real_measurable_on; REAL_INTEGRABLE_ON; + ABSOLUTELY_REAL_INTEGRABLE_ON] THEN + REPEAT STRIP_TAC THEN + MATCH_MP_TAC MEASURABLE_BOUNDED_BY_INTEGRABLE_IMP_ABSOLUTELY_INTEGRABLE THEN + EXISTS_TAC `lift o g o drop` THEN + ASM_REWRITE_TAC[FORALL_IN_IMAGE; o_THM; LIFT_DROP; NORM_LIFT]);; + +let INTEGRABLE_SUBINTERVALS_IMP_REAL_MEASURABLE = prove + (`!f. (!a b. f real_integrable_on real_interval[a,b]) + ==> f real_measurable_on (:real)`, + REWRITE_TAC[real_measurable_on; REAL_INTEGRABLE_ON; IMAGE_LIFT_UNIV] THEN + REWRITE_TAC[IMAGE_LIFT_REAL_INTERVAL] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC INTEGRABLE_SUBINTERVALS_IMP_MEASURABLE THEN + ASM_REWRITE_TAC[FORALL_LIFT]);; + +let INTEGRABLE_IMP_REAL_MEASURABLE = prove + (`!f:real->real s. + f real_integrable_on s ==> f real_measurable_on s`, + REWRITE_TAC[real_measurable_on; REAL_INTEGRABLE_ON] THEN + REWRITE_TAC[INTEGRABLE_IMP_MEASURABLE]);; + +let ABSOLUTELY_REAL_INTEGRABLE_REAL_MEASURABLE = prove + (`!f s. f absolutely_real_integrable_on s <=> + f real_measurable_on s /\ (\x. abs(f x)) real_integrable_on s`, + REPEAT GEN_TAC THEN REWRITE_TAC[absolutely_real_integrable_on] THEN + MATCH_MP_TAC(TAUT `(a ==> b) /\ (b /\ c ==> a) ==> (a /\ c <=> b /\ c)`) THEN + REWRITE_TAC[INTEGRABLE_IMP_REAL_MEASURABLE] THEN STRIP_TAC THEN + MATCH_MP_TAC REAL_MEASURABLE_BOUNDED_BY_INTEGRABLE_IMP_INTEGRABLE THEN + EXISTS_TAC `\x. abs((f:real->real) x)` THEN ASM_REWRITE_TAC[REAL_LE_REFL]);; + +let REAL_MEASURABLE_ON_COMPOSE_CONTINUOUS = prove + (`!f g. f real_measurable_on (:real) /\ g real_continuous_on (:real) + ==> (g o f) real_measurable_on (:real)`, + REPEAT GEN_TAC THEN REWRITE_TAC[REAL_CONTINUOUS_ON; real_measurable_on] THEN + REWRITE_TAC[IMAGE_LIFT_UNIV] THEN + DISCH_THEN(MP_TAC o MATCH_MP MEASURABLE_ON_COMPOSE_CONTINUOUS) THEN + REWRITE_TAC[o_DEF; LIFT_DROP]);; + +let REAL_MEASURABLE_ON_COMPOSE_CONTINUOUS_0 = prove + (`!f:real->real g:real->real s. + f real_measurable_on s /\ g real_continuous_on (:real) /\ g(&0) = &0 + ==> (g o f) real_measurable_on s`, + REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[GSYM REAL_MEASURABLE_ON_UNIV] THEN + ONCE_REWRITE_TAC[TAUT `a /\ b /\ c ==> d <=> c ==> a /\ b ==> d`] THEN + DISCH_TAC THEN + DISCH_THEN(MP_TAC o MATCH_MP REAL_MEASURABLE_ON_COMPOSE_CONTINUOUS) THEN + MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_TERM_TAC THEN + REWRITE_TAC[FUN_EQ_THM; o_DEF] THEN ASM_MESON_TAC[]);; + +let REAL_MEASURABLE_ON_COMPOSE_CONTINUOUS_OPEN_INTERVAL = prove + (`!f:real->real g:real->real a b. + f real_measurable_on (:real) /\ + (!x. f(x) IN real_interval(a,b)) /\ + g real_continuous_on real_interval(a,b) + ==> (g o f) real_measurable_on (:real)`, + REPEAT GEN_TAC THEN + MP_TAC(ISPECL [`lift o f o drop`; `lift o g o drop`; `lift a`; `lift b`] + MEASURABLE_ON_COMPOSE_CONTINUOUS_OPEN_INTERVAL) THEN + REWRITE_TAC[real_measurable_on; REAL_CONTINUOUS_ON] THEN + REWRITE_TAC[o_DEF; LIFT_DROP; IMAGE_LIFT_UNIV; IMAGE_LIFT_REAL_INTERVAL] THEN + REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_REWRITE_TAC[GSYM FORALL_DROP] THEN REPEAT GEN_TAC THEN + REWRITE_TAC[INTERVAL_REAL_INTERVAL; LIFT_DROP] THEN ASM SET_TAC[]);; + +let REAL_MEASURABLE_ON_COMPOSE_CONTINUOUS_CLOSED_SET = prove + (`!f:real->real g:real->real s. + real_closed s /\ + f real_measurable_on (:real) /\ + (!x. f(x) IN s) /\ + g real_continuous_on s + ==> (g o f) real_measurable_on (:real)`, + REPEAT GEN_TAC THEN + MP_TAC(ISPECL [`lift o f o drop`; `lift o g o drop`; `IMAGE lift s`] + MEASURABLE_ON_COMPOSE_CONTINUOUS_CLOSED_SET) THEN + REWRITE_TAC[real_measurable_on; REAL_CONTINUOUS_ON; REAL_CLOSED] THEN + REWRITE_TAC[o_DEF; LIFT_DROP; IMAGE_LIFT_UNIV; IMAGE_LIFT_REAL_INTERVAL] THEN + REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_REWRITE_TAC[GSYM FORALL_DROP] THEN REPEAT GEN_TAC THEN + REWRITE_TAC[INTERVAL_REAL_INTERVAL; LIFT_DROP] THEN ASM SET_TAC[]);; + +let REAL_MEASURABLE_ON_COMPOSE_CONTINUOUS_CLOSED_SET_0 = prove + (`!f:real->real g:real->real s t. + real_closed s /\ + f real_measurable_on t /\ + (!x. f(x) IN s) /\ + g real_continuous_on s /\ + &0 IN s /\ g(&0) = &0 + ==> (g o f) real_measurable_on t`, + REPEAT GEN_TAC THEN + MP_TAC(ISPECL [`lift o f o drop`; `lift o g o drop`; + `IMAGE lift s`; `IMAGE lift t`] + MEASURABLE_ON_COMPOSE_CONTINUOUS_CLOSED_SET_0) THEN + REWRITE_TAC[real_measurable_on; REAL_CONTINUOUS_ON; REAL_CLOSED] THEN + REWRITE_TAC[o_DEF; LIFT_DROP; IMAGE_LIFT_UNIV; IMAGE_LIFT_REAL_INTERVAL] THEN + REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_REWRITE_TAC[GSYM FORALL_DROP] THEN + ASM_SIMP_TAC[FUN_IN_IMAGE; LIFT_DROP; GSYM LIFT_NUM]);; + +let CONTINUOUS_IMP_REAL_MEASURABLE_ON = prove + (`!f. f real_continuous_on (:real) ==> f real_measurable_on (:real)`, + REWRITE_TAC[REAL_CONTINUOUS_ON; real_measurable_on] THEN + REWRITE_TAC[CONTINUOUS_IMP_MEASURABLE_ON; IMAGE_LIFT_UNIV]);; + +let REAL_MEASURABLE_ON_CONST = prove + (`!k:real. (\x. k) real_measurable_on (:real)`, + SIMP_TAC[real_measurable_on; o_DEF; MEASURABLE_ON_CONST; IMAGE_LIFT_UNIV]);; + +let REAL_MEASURABLE_ON_0 = prove + (`!s. (\x. &0) real_measurable_on s`, + GEN_TAC THEN ONCE_REWRITE_TAC[GSYM REAL_MEASURABLE_ON_UNIV] THEN + REWRITE_TAC[REAL_MEASURABLE_ON_CONST; COND_ID]);; + +let REAL_MEASURABLE_ON_LMUL = prove + (`!c f s. f real_measurable_on s ==> (\x. c * f x) real_measurable_on s`, + REPEAT GEN_TAC THEN REWRITE_TAC[real_measurable_on] THEN + DISCH_THEN(MP_TAC o SPEC `c:real` o MATCH_MP MEASURABLE_ON_CMUL) THEN + REWRITE_TAC[o_DEF; LIFT_CMUL; LIFT_DROP]);; + +let REAL_MEASURABLE_ON_RMUL = prove + (`!c f s. f real_measurable_on s ==> (\x. f x * c) real_measurable_on s`, + ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN + REWRITE_TAC[REAL_MEASURABLE_ON_LMUL]);; + +let REAL_MEASURABLE_ON_NEG = prove + (`!f s. f real_measurable_on s ==> (\x. --(f x)) real_measurable_on s`, + REPEAT GEN_TAC THEN REWRITE_TAC[real_measurable_on] THEN + DISCH_THEN(MP_TAC o MATCH_MP MEASURABLE_ON_NEG) THEN + REWRITE_TAC[o_DEF; LIFT_NEG; LIFT_DROP]);; + +let REAL_MEASURABLE_ON_NEG_EQ = prove + (`!f s. (\x. --(f x)) real_measurable_on s <=> f real_measurable_on s`, + REPEAT GEN_TAC THEN EQ_TAC THEN + DISCH_THEN(MP_TAC o MATCH_MP REAL_MEASURABLE_ON_NEG) THEN + REWRITE_TAC[REAL_NEG_NEG; ETA_AX]);; + +let REAL_MEASURABLE_ON_ABS = prove + (`!f s. f real_measurable_on s ==> (\x. abs(f x)) real_measurable_on s`, + REPEAT GEN_TAC THEN REWRITE_TAC[real_measurable_on] THEN + DISCH_THEN(MP_TAC o MATCH_MP MEASURABLE_ON_NORM) THEN + REWRITE_TAC[o_DEF; NORM_LIFT]);; + +let REAL_MEASURABLE_ON_ADD = prove + (`!f g s. f real_measurable_on s /\ g real_measurable_on s + ==> (\x. f x + g x) real_measurable_on s`, + REPEAT GEN_TAC THEN REWRITE_TAC[real_measurable_on] THEN + DISCH_THEN(MP_TAC o MATCH_MP MEASURABLE_ON_ADD) THEN + REWRITE_TAC[o_DEF; LIFT_ADD; LIFT_DROP]);; + +let REAL_MEASURABLE_ON_SUB = prove + (`!f g s. + f real_measurable_on s /\ g real_measurable_on s + ==> (\x. f x - g x) real_measurable_on s`, + REPEAT GEN_TAC THEN REWRITE_TAC[real_measurable_on] THEN + DISCH_THEN(MP_TAC o MATCH_MP MEASURABLE_ON_SUB) THEN + REWRITE_TAC[o_DEF; LIFT_SUB; LIFT_DROP]);; + +let REAL_MEASURABLE_ON_MAX = prove + (`!f g s. + f real_measurable_on s /\ g real_measurable_on s + ==> (\x. max (f x) (g x)) real_measurable_on s`, + REPEAT GEN_TAC THEN REWRITE_TAC[real_measurable_on] THEN + DISCH_THEN(MP_TAC o MATCH_MP MEASURABLE_ON_MAX) THEN + MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_TERM_TAC THEN + SIMP_TAC[FUN_EQ_THM; o_THM; CART_EQ; LAMBDA_BETA; DIMINDEX_1; FORALL_1] THEN + REWRITE_TAC[GSYM drop; LIFT_DROP]);; + +let REAL_MEASURABLE_ON_MIN = prove + (`!f g s. + f real_measurable_on s /\ g real_measurable_on s + ==> (\x. min (f x) (g x)) real_measurable_on s`, + REPEAT GEN_TAC THEN REWRITE_TAC[real_measurable_on] THEN + DISCH_THEN(MP_TAC o MATCH_MP MEASURABLE_ON_MIN) THEN + MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_TERM_TAC THEN + SIMP_TAC[FUN_EQ_THM; o_THM; CART_EQ; LAMBDA_BETA; DIMINDEX_1; FORALL_1] THEN + REWRITE_TAC[GSYM drop; LIFT_DROP]);; + +let REAL_MEASURABLE_ON_MUL = prove + (`!f g s. + f real_measurable_on s /\ g real_measurable_on s + ==> (\x. f x * g x) real_measurable_on s`, + REPEAT GEN_TAC THEN REWRITE_TAC[real_measurable_on] THEN + DISCH_THEN(MP_TAC o MATCH_MP MEASURABLE_ON_DROP_MUL) THEN + REWRITE_TAC[o_DEF; LIFT_CMUL; LIFT_DROP]);; + +let REAL_MEASURABLE_ON_SPIKE_SET = prove + (`!f:real->real s t. + real_negligible (s DIFF t UNION t DIFF s) + ==> f real_measurable_on s + ==> f real_measurable_on t`, + REWRITE_TAC[real_measurable_on; real_negligible] THEN + REPEAT GEN_TAC THEN DISCH_TAC THEN + MATCH_MP_TAC MEASURABLE_ON_SPIKE_SET THEN POP_ASSUM MP_TAC THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] NEGLIGIBLE_SUBSET) THEN + SET_TAC[]);; + +let REAL_MEASURABLE_ON_RESTRICT = prove + (`!f s. f real_measurable_on (:real) /\ + real_lebesgue_measurable s + ==> (\x. if x IN s then f(x) else &0) real_measurable_on (:real)`, + REPEAT GEN_TAC THEN + REWRITE_TAC[real_measurable_on; REAL_LEBESGUE_MEASURABLE; + IMAGE_LIFT_UNIV] THEN + REWRITE_TAC[o_DEF; COND_RAND; LIFT_NUM; GSYM IN_IMAGE_LIFT_DROP] THEN + DISCH_THEN(MP_TAC o MATCH_MP MEASURABLE_ON_RESTRICT) THEN + REWRITE_TAC[]);; + +let REAL_MEASURABLE_ON_LIMIT = prove + (`!f g s k. + (!n. (f n) real_measurable_on s) /\ + real_negligible k /\ + (!x. x IN s DIFF k ==> ((\n. f n x) ---> g x) sequentially) + ==> g real_measurable_on s`, + REWRITE_TAC[real_measurable_on; real_negligible; TENDSTO_REAL] THEN + REWRITE_TAC[o_DEF] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC MEASURABLE_ON_LIMIT THEN MAP_EVERY EXISTS_TAC + [`\n:num. lift o f n o drop`; `IMAGE lift k`] THEN + ASM_REWRITE_TAC[] THEN + SIMP_TAC[LIFT_DROP; SET_RULE `(!x. drop(lift x) = x) + ==> IMAGE lift s DIFF IMAGE lift t = IMAGE lift (s DIFF t)`] THEN + ASM_REWRITE_TAC[FORALL_IN_IMAGE; o_DEF; LIFT_DROP]);; + +let ABSOLUTELY_REAL_INTEGRABLE_BOUNDED_MEASURABLE_PRODUCT = prove + (`!f g s. f real_measurable_on s /\ real_bounded (IMAGE f s) /\ + g absolutely_real_integrable_on s + + ==> (\x. f x * g x) absolutely_real_integrable_on s`, + REPEAT STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [REAL_BOUNDED_POS]) THEN + REWRITE_TAC[LEFT_IMP_EXISTS_THM; FORALL_IN_IMAGE] THEN + X_GEN_TAC `B:real` THEN STRIP_TAC THEN MATCH_MP_TAC + REAL_MEASURABLE_BOUNDED_BY_INTEGRABLE_IMP_ABSOLUTELY_INTEGRABLE THEN + EXISTS_TAC `\x. B * abs((g:real->real) x)` THEN + ASM_SIMP_TAC[REAL_MEASURABLE_ON_MUL; INTEGRABLE_IMP_REAL_MEASURABLE; + ABSOLUTELY_REAL_INTEGRABLE_IMP_INTEGRABLE; REAL_INTEGRABLE_LMUL; + ABSOLUTELY_REAL_INTEGRABLE_ABS] THEN + ASM_SIMP_TAC[REAL_ABS_MUL; REAL_LE_RMUL; REAL_ABS_POS]);; + +let REAL_COMPLEX_MEASURABLE_ON = prove + (`!f s. f real_measurable_on s <=> + (Cx o f o drop) measurable_on (IMAGE lift s)`, + ONCE_REWRITE_TAC[GSYM REAL_MEASURABLE_ON_UNIV; + GSYM MEASURABLE_ON_UNIV] THEN + ONCE_REWRITE_TAC[MEASURABLE_ON_COMPONENTWISE] THEN + REWRITE_TAC[FORALL_2; DIMINDEX_2; GSYM RE_DEF; GSYM IM_DEF] THEN + REPEAT GEN_TAC THEN REWRITE_TAC[real_measurable_on; IMAGE_LIFT_UNIV] THEN + REWRITE_TAC[o_DEF; IN_IMAGE_LIFT_DROP] THEN + REWRITE_TAC[COND_RAND; COND_RATOR; LIFT_NUM; COMPLEX_VEC_0] THEN + REWRITE_TAC[RE_CX; IM_CX; COND_ID; MEASURABLE_ON_CONST; LIFT_NUM]);; + +let REAL_MEASURABLE_ON_INV = prove + (`!f. f real_measurable_on (:real) /\ real_negligible {x | f x = &0} + ==> (\x. inv(f x)) real_measurable_on (:real)`, + GEN_TAC THEN REWRITE_TAC[REAL_COMPLEX_MEASURABLE_ON] THEN + REWRITE_TAC[o_DEF; CX_INV; IMAGE_LIFT_UNIV] THEN STRIP_TAC THEN + MATCH_MP_TAC MEASURABLE_ON_COMPLEX_INV THEN ASM_REWRITE_TAC[CX_INJ] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [real_negligible]) THEN + MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN + MATCH_MP_TAC SURJECTIVE_IMAGE_EQ THEN + REWRITE_TAC[IN_ELIM_THM; LIFT_DROP] THEN MESON_TAC[LIFT_DROP]);; + +let REAL_MEASURABLE_ON_DIV = prove + (`!f g. f real_measurable_on s /\ g real_measurable_on (:real) /\ + real_negligible {x | g(x) = &0} + ==> (\x. f(x) / g(x)) real_measurable_on s`, + REPEAT GEN_TAC THEN REWRITE_TAC[REAL_COMPLEX_MEASURABLE_ON] THEN + REWRITE_TAC[o_DEF; CX_DIV; IMAGE_LIFT_UNIV] THEN STRIP_TAC THEN + MATCH_MP_TAC MEASURABLE_ON_COMPLEX_DIV THEN ASM_REWRITE_TAC[CX_INJ] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [real_negligible]) THEN + MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN + MATCH_MP_TAC SURJECTIVE_IMAGE_EQ THEN + REWRITE_TAC[IN_ELIM_THM; LIFT_DROP] THEN MESON_TAC[LIFT_DROP]);; + +(* ------------------------------------------------------------------------- *) +(* Properties of real Lebesgue measurable sets. *) +(* ------------------------------------------------------------------------- *) + +let REAL_MEASURABLE_IMP_REAL_LEBESGUE_MEASURABLE = prove + (`!s. real_measurable s ==> real_lebesgue_measurable s`, + REWRITE_TAC[REAL_LEBESGUE_MEASURABLE; REAL_MEASURABLE_MEASURABLE; + MEASURABLE_IMP_LEBESGUE_MEASURABLE]);; + +let REAL_LEBESGUE_MEASURABLE_EMPTY = prove + (`real_lebesgue_measurable {}`, + REWRITE_TAC[REAL_LEBESGUE_MEASURABLE; IMAGE_CLAUSES; + LEBESGUE_MEASURABLE_EMPTY]);; + +let REAL_LEBESGUE_MEASURABLE_UNIV = prove + (`real_lebesgue_measurable (:real)`, + REWRITE_TAC[REAL_LEBESGUE_MEASURABLE; IMAGE_LIFT_UNIV; + LEBESGUE_MEASURABLE_UNIV]);; + +let REAL_LEBESGUE_MEASURABLE_COMPACT = prove + (`!s. real_compact s ==> real_lebesgue_measurable s`, + SIMP_TAC[REAL_MEASURABLE_IMP_REAL_LEBESGUE_MEASURABLE; + REAL_MEASURABLE_COMPACT]);; + +let REAL_LEBESGUE_MEASURABLE_INTERVAL = prove + (`(!a b. real_lebesgue_measurable(real_interval[a,b])) /\ + (!a b. real_lebesgue_measurable(real_interval(a,b)))`, + SIMP_TAC[REAL_MEASURABLE_IMP_REAL_LEBESGUE_MEASURABLE; + REAL_MEASURABLE_REAL_INTERVAL]);; + +let REAL_LEBESGUE_MEASURABLE_INTER = prove + (`!s t. real_lebesgue_measurable s /\ real_lebesgue_measurable t + ==> real_lebesgue_measurable(s INTER t)`, + REPEAT GEN_TAC THEN REWRITE_TAC[REAL_LEBESGUE_MEASURABLE] THEN + DISCH_THEN(MP_TAC o MATCH_MP LEBESGUE_MEASURABLE_INTER) THEN + MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN MP_TAC LIFT_DROP THEN SET_TAC[]);; + +let REAL_LEBESGUE_MEASURABLE_UNION = prove + (`!s t:real->bool. + real_lebesgue_measurable s /\ real_lebesgue_measurable t + ==> real_lebesgue_measurable(s UNION t)`, + REPEAT GEN_TAC THEN REWRITE_TAC[REAL_LEBESGUE_MEASURABLE] THEN + DISCH_THEN(MP_TAC o MATCH_MP LEBESGUE_MEASURABLE_UNION) THEN + MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN MP_TAC LIFT_DROP THEN SET_TAC[]);; + +let REAL_LEBESGUE_MEASURABLE_COMPL = prove + (`!s. real_lebesgue_measurable((:real) DIFF s) <=> + real_lebesgue_measurable s`, + GEN_TAC THEN REWRITE_TAC[REAL_LEBESGUE_MEASURABLE] THEN + GEN_REWRITE_TAC (RAND_CONV) [GSYM LEBESGUE_MEASURABLE_COMPL] THEN + AP_TERM_TAC THEN MP_TAC LIFT_DROP THEN SET_TAC[]);; + +let REAL_LEBESGUE_MEASURABLE_DIFF = prove + (`!s t:real->bool. + real_lebesgue_measurable s /\ real_lebesgue_measurable t + ==> real_lebesgue_measurable(s DIFF t)`, + ONCE_REWRITE_TAC[SET_RULE `s DIFF t = s INTER (UNIV DIFF t)`] THEN + SIMP_TAC[REAL_LEBESGUE_MEASURABLE_COMPL; REAL_LEBESGUE_MEASURABLE_INTER]);; + +let REAL_LEBESGUE_MEASURABLE_ON_SUBINTERVALS = prove + (`!s. real_lebesgue_measurable s <=> + !a b. real_lebesgue_measurable(s INTER real_interval[a,b])`, + GEN_TAC THEN REWRITE_TAC[REAL_LEBESGUE_MEASURABLE] THEN + GEN_REWRITE_TAC LAND_CONV [LEBESGUE_MEASURABLE_ON_SUBINTERVALS] THEN + REWRITE_TAC[FORALL_DROP; GSYM IMAGE_DROP_INTERVAL] THEN + REPEAT(AP_TERM_TAC THEN ABS_TAC) THEN AP_TERM_TAC THEN + MP_TAC LIFT_DROP THEN SET_TAC[]);; + +let REAL_LEBESGUE_MEASURABLE_CLOSED = prove + (`!s. real_closed s ==> real_lebesgue_measurable s`, + REWRITE_TAC[REAL_LEBESGUE_MEASURABLE; REAL_CLOSED; + LEBESGUE_MEASURABLE_CLOSED]);; + +let REAL_LEBESGUE_MEASURABLE_OPEN = prove + (`!s. real_open s ==> real_lebesgue_measurable s`, + REWRITE_TAC[REAL_LEBESGUE_MEASURABLE; REAL_OPEN; + LEBESGUE_MEASURABLE_OPEN]);; + +let REAL_LEBESGUE_MEASURABLE_UNIONS = prove + (`!f. FINITE f /\ (!s. s IN f ==> real_lebesgue_measurable s) + ==> real_lebesgue_measurable (UNIONS f)`, + REWRITE_TAC[IMP_CONJ] THEN + MATCH_MP_TAC FINITE_INDUCT_STRONG THEN + SIMP_TAC[UNIONS_0; UNIONS_INSERT; REAL_LEBESGUE_MEASURABLE_EMPTY] THEN + REWRITE_TAC[IN_INSERT] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC REAL_LEBESGUE_MEASURABLE_UNION THEN ASM_SIMP_TAC[]);; + +let REAL_LEBESGUE_MEASURABLE_COUNTABLE_UNIONS_EXPLICIT = prove + (`!s:num->real->bool. + (!n. real_lebesgue_measurable(s n)) + ==> real_lebesgue_measurable(UNIONS {s n | n IN (:num)})`, + GEN_TAC THEN REWRITE_TAC[REAL_LEBESGUE_MEASURABLE] THEN DISCH_THEN(MP_TAC o + MATCH_MP LEBESGUE_MEASURABLE_COUNTABLE_UNIONS_EXPLICIT) THEN + REWRITE_TAC[IMAGE_UNIONS; SIMPLE_IMAGE] THEN + MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN SET_TAC[]);; + +let REAL_LEBESGUE_MEASURABLE_COUNTABLE_UNIONS = prove + (`!f:(real->bool)->bool. + COUNTABLE f /\ (!s. s IN f ==> real_lebesgue_measurable s) + ==> real_lebesgue_measurable (UNIONS f)`, + GEN_TAC THEN ASM_CASES_TAC `f:(real->bool)->bool = {}` THEN + ASM_REWRITE_TAC[UNIONS_0; REAL_LEBESGUE_MEASURABLE_EMPTY] THEN STRIP_TAC THEN + MP_TAC(ISPEC `f:(real->bool)->bool` COUNTABLE_AS_IMAGE) THEN + ASM_REWRITE_TAC[] THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + ONCE_REWRITE_TAC[GSYM SIMPLE_IMAGE] THEN + MATCH_MP_TAC REAL_LEBESGUE_MEASURABLE_COUNTABLE_UNIONS_EXPLICIT THEN + GEN_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_REWRITE_TAC[IN_IMAGE; IN_UNIV] THEN MESON_TAC[]);; + +let REAL_LEBESGUE_MEASURABLE_COUNTABLE_INTERS = prove + (`!f:(real->bool)->bool. + COUNTABLE f /\ (!s. s IN f ==> real_lebesgue_measurable s) + ==> real_lebesgue_measurable (INTERS f)`, + REPEAT STRIP_TAC THEN + REWRITE_TAC[INTERS_UNIONS; REAL_LEBESGUE_MEASURABLE_COMPL] THEN + MATCH_MP_TAC REAL_LEBESGUE_MEASURABLE_COUNTABLE_UNIONS THEN + ASM_SIMP_TAC[SIMPLE_IMAGE; FORALL_IN_IMAGE; COUNTABLE_IMAGE; + REAL_LEBESGUE_MEASURABLE_COMPL]);; + +let REAL_LEBESGUE_MEASURABLE_COUNTABLE_INTERS_EXPLICIT = prove + (`!s:num->real->bool. + (!n. real_lebesgue_measurable(s n)) + ==> real_lebesgue_measurable(INTERS {s n | n IN (:num)})`, + REPEAT STRIP_TAC THEN + MATCH_MP_TAC REAL_LEBESGUE_MEASURABLE_COUNTABLE_INTERS THEN + ASM_SIMP_TAC[SIMPLE_IMAGE; FORALL_IN_IMAGE; COUNTABLE_IMAGE; NUM_COUNTABLE]);; + +let REAL_LEBESGUE_MEASURABLE_INTERS = prove + (`!f:(real->bool)->bool. + FINITE f /\ (!s. s IN f ==> real_lebesgue_measurable s) + ==> real_lebesgue_measurable (INTERS f)`, + SIMP_TAC[REAL_LEBESGUE_MEASURABLE_COUNTABLE_INTERS; FINITE_IMP_COUNTABLE]);; + +let REAL_LEBESGUE_MEASURABLE_IFF_MEASURABLE = prove + (`!s. real_bounded s ==> (real_lebesgue_measurable s <=> real_measurable s)`, + REWRITE_TAC[REAL_BOUNDED; REAL_LEBESGUE_MEASURABLE; + REAL_MEASURABLE_MEASURABLE] THEN + REWRITE_TAC[LEBESGUE_MEASURABLE_IFF_MEASURABLE]);; + +let REAL_MEASURABLE_ON_LEBESGUE_MEASURABLE_SUBSET = prove + (`!f s t. s SUBSET t /\ f real_measurable_on t /\ + real_lebesgue_measurable s + ==> f real_measurable_on s`, + REPEAT GEN_TAC THEN + ONCE_REWRITE_TAC[GSYM REAL_MEASURABLE_ON_UNIV] THEN + REWRITE_TAC[IN_UNIV] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + DISCH_THEN(MP_TAC o MATCH_MP REAL_MEASURABLE_ON_RESTRICT) THEN + MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_TERM_TAC THEN + REWRITE_TAC[FUN_EQ_THM] THEN ASM SET_TAC[]);; + +let REAL_MEASURABLE_ON_MEASURABLE_SUBSET = prove + (`!f s t. s SUBSET t /\ f real_measurable_on t /\ real_measurable s + ==> f real_measurable_on s`, + MESON_TAC[REAL_MEASURABLE_ON_LEBESGUE_MEASURABLE_SUBSET; + REAL_MEASURABLE_IMP_REAL_LEBESGUE_MEASURABLE]);; + +let REAL_CONTINUOUS_IMP_REAL_MEASURABLE_ON_CLOSED_SUBSET = prove + (`!f s. f real_continuous_on s /\ real_closed s ==> f real_measurable_on s`, + REWRITE_TAC[REAL_CONTINUOUS_ON; REAL_CLOSED; real_measurable_on] THEN + REWRITE_TAC[CONTINUOUS_IMP_MEASURABLE_ON_CLOSED_SUBSET]);; + +let REAL_MEASURABLE_ON_CASES = prove + (`!P f g s. + real_lebesgue_measurable {x | P x} /\ + f real_measurable_on s /\ g real_measurable_on s + ==> (\x. if P x then f x else g x) real_measurable_on s`, + REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[GSYM REAL_MEASURABLE_ON_UNIV] THEN + REPEAT STRIP_TAC THEN + SUBGOAL_THEN + `!x. (if x IN s then if P x then f x else g x else &0) = + (if x IN {x | P x} then if x IN s then f x else &0 else &0) + + (if x IN (:real) DIFF {x | P x} + then if x IN s then g x else &0 else &0)` + (fun th -> REWRITE_TAC[th]) + THENL + [GEN_TAC THEN REWRITE_TAC[IN_UNIV; IN_ELIM_THM; IN_DIFF] THEN + MESON_TAC[REAL_ADD_LID; REAL_ADD_RID]; + MATCH_MP_TAC REAL_MEASURABLE_ON_ADD THEN + CONJ_TAC THEN MATCH_MP_TAC REAL_MEASURABLE_ON_RESTRICT THEN + ASM_REWRITE_TAC[REAL_LEBESGUE_MEASURABLE_COMPL]]);; + +(* ------------------------------------------------------------------------- *) +(* Various common equivalent forms of function measurability. *) +(* ------------------------------------------------------------------------- *) + +let REAL_MEASURABLE_ON_PREIMAGE_OPEN_HALFSPACE_LT = prove + (`!f. f real_measurable_on (:real) <=> + !a. real_lebesgue_measurable {x | f(x) < a}`, + REWRITE_TAC[real_measurable_on; REAL_LEBESGUE_MEASURABLE; IMAGE_LIFT_UNIV; + MEASURABLE_ON_PREIMAGE_OPEN_HALFSPACE_COMPONENT_LT] THEN + REWRITE_TAC[DIMINDEX_1; FORALL_1; GSYM drop; o_DEF; LIFT_DROP] THEN + GEN_TAC THEN AP_TERM_TAC THEN ABS_TAC THEN AP_TERM_TAC THEN + CONV_TAC SYM_CONV THEN MATCH_MP_TAC SURJECTIVE_IMAGE_EQ THEN + REWRITE_TAC[IN_ELIM_THM] THEN MESON_TAC[LIFT_DROP]);; + +let REAL_MEASURABLE_ON_PREIMAGE_OPEN_HALFSPACE_LE = prove + (`!f. f real_measurable_on (:real) <=> + !a. real_lebesgue_measurable {x | f(x) <= a}`, + REWRITE_TAC[real_measurable_on; REAL_LEBESGUE_MEASURABLE; IMAGE_LIFT_UNIV; + MEASURABLE_ON_PREIMAGE_OPEN_HALFSPACE_COMPONENT_LE] THEN + REWRITE_TAC[DIMINDEX_1; FORALL_1; GSYM drop; o_DEF; LIFT_DROP] THEN + GEN_TAC THEN AP_TERM_TAC THEN ABS_TAC THEN AP_TERM_TAC THEN + CONV_TAC SYM_CONV THEN MATCH_MP_TAC SURJECTIVE_IMAGE_EQ THEN + REWRITE_TAC[IN_ELIM_THM] THEN MESON_TAC[LIFT_DROP]);; + +let REAL_MEASURABLE_ON_PREIMAGE_OPEN_HALFSPACE_GT = prove + (`!f. f real_measurable_on (:real) <=> + !a. real_lebesgue_measurable {x | f(x) > a}`, + REWRITE_TAC[real_measurable_on; REAL_LEBESGUE_MEASURABLE; IMAGE_LIFT_UNIV; + MEASURABLE_ON_PREIMAGE_OPEN_HALFSPACE_COMPONENT_GT] THEN + REWRITE_TAC[DIMINDEX_1; FORALL_1; GSYM drop; o_DEF; LIFT_DROP] THEN + GEN_TAC THEN AP_TERM_TAC THEN ABS_TAC THEN AP_TERM_TAC THEN + CONV_TAC SYM_CONV THEN MATCH_MP_TAC SURJECTIVE_IMAGE_EQ THEN + REWRITE_TAC[IN_ELIM_THM] THEN MESON_TAC[LIFT_DROP]);; + +let REAL_MEASURABLE_ON_PREIMAGE_OPEN_HALFSPACE_GE = prove + (`!f. f real_measurable_on (:real) <=> + !a. real_lebesgue_measurable {x | f(x) >= a}`, + REWRITE_TAC[real_measurable_on; REAL_LEBESGUE_MEASURABLE; IMAGE_LIFT_UNIV; + MEASURABLE_ON_PREIMAGE_OPEN_HALFSPACE_COMPONENT_GE] THEN + REWRITE_TAC[DIMINDEX_1; FORALL_1; GSYM drop; o_DEF; LIFT_DROP] THEN + GEN_TAC THEN AP_TERM_TAC THEN ABS_TAC THEN AP_TERM_TAC THEN + CONV_TAC SYM_CONV THEN MATCH_MP_TAC SURJECTIVE_IMAGE_EQ THEN + REWRITE_TAC[IN_ELIM_THM] THEN MESON_TAC[LIFT_DROP]);; + +let REAL_MEASURABLE_ON_PREIMAGE_OPEN_INTERVAL = prove + (`!f. f real_measurable_on (:real) <=> + !a b. real_lebesgue_measurable {x | f(x) IN real_interval(a,b)}`, + REWRITE_TAC[real_measurable_on; REAL_LEBESGUE_MEASURABLE; IMAGE_LIFT_UNIV; + MEASURABLE_ON_PREIMAGE_OPEN_INTERVAL; FORALL_DROP] THEN + GEN_TAC THEN REPEAT(AP_TERM_TAC THEN ABS_TAC) THEN AP_TERM_TAC THEN + CONV_TAC SYM_CONV THEN MATCH_MP_TAC SURJECTIVE_IMAGE_EQ THEN + REWRITE_TAC[IN_ELIM_THM; o_DEF; GSYM IMAGE_DROP_INTERVAL; LIFT_DROP; + FORALL_DROP; IN_IMAGE] THEN MESON_TAC[LIFT_DROP]);; + +let REAL_MEASURABLE_ON_PREIMAGE_CLOSED_INTERVAL = prove + (`!f. f real_measurable_on (:real) <=> + !a b. real_lebesgue_measurable {x | f(x) IN real_interval[a,b]}`, + REWRITE_TAC[real_measurable_on; REAL_LEBESGUE_MEASURABLE; IMAGE_LIFT_UNIV; + MEASURABLE_ON_PREIMAGE_CLOSED_INTERVAL; FORALL_DROP] THEN + GEN_TAC THEN REPEAT(AP_TERM_TAC THEN ABS_TAC) THEN AP_TERM_TAC THEN + CONV_TAC SYM_CONV THEN MATCH_MP_TAC SURJECTIVE_IMAGE_EQ THEN + REWRITE_TAC[IN_ELIM_THM; o_DEF; GSYM IMAGE_DROP_INTERVAL; LIFT_DROP; + FORALL_DROP; IN_IMAGE] THEN MESON_TAC[LIFT_DROP]);; + +let REAL_MEASURABLE_ON_PREIMAGE_OPEN = prove + (`!f. f real_measurable_on (:real) <=> + !t. real_open t ==> real_lebesgue_measurable {x | f(x) IN t}`, + REWRITE_TAC[real_measurable_on; REAL_LEBESGUE_MEASURABLE; IMAGE_LIFT_UNIV; + MEASURABLE_ON_PREIMAGE_OPEN; REAL_OPEN] THEN + GEN_TAC THEN EQ_TAC THEN DISCH_TAC THENL + [X_GEN_TAC `t:real->bool` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `IMAGE lift t`) THEN + ASM_REWRITE_TAC[]; + X_GEN_TAC `t:real^1->bool` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `IMAGE drop t`) THEN + ASM_REWRITE_TAC[IMAGE_LIFT_DROP; GSYM IMAGE_o]] THEN + MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THENL + [CONV_TAC SYM_CONV; ALL_TAC] THEN + MATCH_MP_TAC SURJECTIVE_IMAGE_EQ THEN + REWRITE_TAC[IN_IMAGE; o_DEF; IN_ELIM_THM] THEN MESON_TAC[LIFT_DROP]);; + +let REAL_MEASURABLE_ON_PREIMAGE_CLOSED = prove + (`!f. f real_measurable_on (:real) <=> + !t. real_closed t ==> real_lebesgue_measurable {x | f(x) IN t}`, + REWRITE_TAC[real_measurable_on; REAL_LEBESGUE_MEASURABLE; IMAGE_LIFT_UNIV; + MEASURABLE_ON_PREIMAGE_CLOSED; REAL_CLOSED] THEN + GEN_TAC THEN EQ_TAC THEN DISCH_TAC THENL + [X_GEN_TAC `t:real->bool` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `IMAGE lift t`) THEN + ASM_REWRITE_TAC[]; + X_GEN_TAC `t:real^1->bool` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `IMAGE drop t`) THEN + ASM_REWRITE_TAC[IMAGE_LIFT_DROP; GSYM IMAGE_o]] THEN + MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THENL + [CONV_TAC SYM_CONV; ALL_TAC] THEN + MATCH_MP_TAC SURJECTIVE_IMAGE_EQ THEN + REWRITE_TAC[IN_IMAGE; o_DEF; IN_ELIM_THM] THEN MESON_TAC[LIFT_DROP]);; + +let REAL_MEASURABLE_ON_SIMPLE_FUNCTION_LIMIT = prove + (`!f. f real_measurable_on (:real) <=> + ?g. (!n. (g n) real_measurable_on (:real)) /\ + (!n. FINITE(IMAGE (g n) (:real))) /\ + (!x. ((\n. g n x) ---> f x) sequentially)`, + GEN_TAC THEN REWRITE_TAC[real_measurable_on; IMAGE_LIFT_UNIV] THEN + GEN_REWRITE_TAC LAND_CONV [MEASURABLE_ON_SIMPLE_FUNCTION_LIMIT] THEN + EQ_TAC THENL + [DISCH_THEN(X_CHOOSE_THEN `g:num->real^1->real^1` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `\n:num. drop o g n o lift` THEN + REWRITE_TAC[TENDSTO_REAL] THEN REPEAT CONJ_TAC THENL + [ASM_REWRITE_TAC[o_DEF; LIFT_DROP; ETA_AX]; + GEN_TAC THEN REWRITE_TAC[IMAGE_o; IMAGE_LIFT_UNIV] THEN + MATCH_MP_TAC FINITE_IMAGE THEN ASM_REWRITE_TAC[]; + X_GEN_TAC `x:real` THEN REWRITE_TAC[TENDSTO_REAL] THEN + FIRST_X_ASSUM(MP_TAC o SPEC `lift x`) THEN + REWRITE_TAC[o_DEF; LIFT_DROP]]; + DISCH_THEN(X_CHOOSE_THEN `g:num->real->real` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `\n:num. lift o g n o drop` THEN REPEAT CONJ_TAC THENL + [ASM_REWRITE_TAC[]; + GEN_TAC THEN REWRITE_TAC[IMAGE_o; IMAGE_DROP_UNIV] THEN + MATCH_MP_TAC FINITE_IMAGE THEN ASM_REWRITE_TAC[]; + X_GEN_TAC `x:real^1` THEN FIRST_X_ASSUM(MP_TAC o SPEC `drop x`) THEN + REWRITE_TAC[TENDSTO_REAL; o_DEF; LIFT_DROP]]]);; + +let REAL_LEBESGUE_MEASURABLE_PREIMAGE_OPEN = prove + (`!f t. f real_measurable_on (:real) /\ real_open t + ==> real_lebesgue_measurable {x | f(x) IN t}`, + SIMP_TAC[REAL_MEASURABLE_ON_PREIMAGE_OPEN]);; + +let REAL_LEBESGUE_MEASURABLE_PREIMAGE_CLOSED = prove + (`!f t. f real_measurable_on (:real) /\ real_closed t + ==> real_lebesgue_measurable {x | f(x) IN t}`, + SIMP_TAC[REAL_MEASURABLE_ON_PREIMAGE_CLOSED]);; + +(* ------------------------------------------------------------------------- *) +(* Continuity of measure within a halfspace w.r.t. to the boundary. *) +(* ------------------------------------------------------------------------- *) + +let REAL_CONTINUOUS_MEASURE_IN_HALFSPACE_LE = prove + (`!(s:real^N->bool) a i. + measurable s /\ 1 <= i /\ i <= dimindex(:N) + ==> (\a. measure(s INTER {x | x$i <= a})) real_continuous atreal a`, + REPEAT STRIP_TAC THEN REWRITE_TAC[REAL_CONTINUOUS_CONTINUOUS1] THEN + REWRITE_TAC[continuous_atreal; o_THM] THEN + X_GEN_TAC `e:real` THEN DISCH_TAC THEN + SUBGOAL_THEN + `?u v:real^N. abs(measure(s INTER interval[u,v]) - measure s) < e / &2 /\ + ~(interval(u,v) = {}) /\ u$i < a /\ a < v$i` + STRIP_ASSUME_TAC THENL + [MP_TAC(ISPECL [`s:real^N->bool`; `e / &2`] MEASURE_LIMIT) THEN + ASM_REWRITE_TAC[REAL_HALF] THEN + DISCH_THEN(X_CHOOSE_THEN `B:real` STRIP_ASSUME_TAC) THEN + MP_TAC(ISPEC `ball(vec 0:real^N,B)` BOUNDED_SUBSET_CLOSED_INTERVAL) THEN + REWRITE_TAC[BOUNDED_BALL; LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`u:real^N`; `v:real^N`] THEN DISCH_TAC THEN + EXISTS_TAC `(lambda j. min (a - &1) ((u:real^N)$j)):real^N` THEN + EXISTS_TAC `(lambda j. max (a + &1) ((v:real^N)$j)):real^N` THEN + CONJ_TAC THENL + [FIRST_X_ASSUM MATCH_MP_TAC THEN FIRST_X_ASSUM + (MATCH_MP_TAC o MATCH_MP(REWRITE_RULE[IMP_CONJ] SUBSET_TRANS)) THEN + SIMP_TAC[SUBSET_INTERVAL; LAMBDA_BETA] THEN REAL_ARITH_TAC; + ASM_SIMP_TAC[INTERVAL_NE_EMPTY; LAMBDA_BETA] THEN REAL_ARITH_TAC]; + ALL_TAC] THEN + MP_TAC(ISPECL + [`indicator(s:real^N->bool)`; `u:real^N`; `v:real^N`; `u:real^N`; + `(lambda j. if j = i then min ((v:real^N)$i) a else v$j):real^N`; + `e / &2`] + INDEFINITE_INTEGRAL_CONTINUOUS) THEN + ASM_REWRITE_TAC[REAL_HALF] THEN ANTS_TAC THENL + [ONCE_REWRITE_TAC[GSYM INTEGRABLE_RESTRICT_UNIV] THEN + REWRITE_TAC[indicator; MESON[] + `(if P then if Q then x else y else y) = + (if P /\ Q then x else y)`] THEN + REWRITE_TAC[GSYM IN_INTER; GSYM MEASURABLE_INTEGRABLE] THEN + ASM_SIMP_TAC[MEASURABLE_INTER; MEASURABLE_INTERVAL] THEN + RULE_ASSUM_TAC(REWRITE_RULE[INTERVAL_NE_EMPTY]) THEN + ASM_SIMP_TAC[IN_INTERVAL; LAMBDA_BETA; REAL_LE_REFL; REAL_LT_IMP_LE] THEN + X_GEN_TAC `j:num` THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `j:num`) THEN ASM_REWRITE_TAC[] THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN ASM_REAL_ARITH_TAC; + ALL_TAC] THEN + DISCH_THEN(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `min d (min (a - (u:real^N)$i) ((v:real^N)$i - a))` THEN + ASM_REWRITE_TAC[REAL_LT_MIN; REAL_SUB_LT] THEN + X_GEN_TAC `b:real` THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`u:real^N`; + `(lambda j. if j = i then min ((v:real^N)$i) b else v$j):real^N`]) THEN + REWRITE_TAC[dist] THEN ANTS_TAC THENL + [RULE_ASSUM_TAC(REWRITE_RULE[INTERVAL_NE_EMPTY]) THEN + ASM_SIMP_TAC[IN_INTERVAL; LAMBDA_BETA; REAL_LE_REFL; REAL_LT_IMP_LE] THEN + ASM_SIMP_TAC[VECTOR_SUB_REFL; NORM_0; REAL_LT_IMP_LE] THEN CONJ_TAC THENL + [X_GEN_TAC `j:num` THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `j:num`) THEN ASM_REWRITE_TAC[] THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN ASM_REAL_ARITH_TAC; + ASM_SIMP_TAC[NORM_LE_SQUARE; dot; REAL_LT_IMP_LE] THEN + MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC + `sum(1..dimindex(:N)) (\j. if j = i then d pow 2 else &0)` THEN + CONJ_TAC THENL + [MATCH_MP_TAC SUM_LE_NUMSEG THEN X_GEN_TAC `j:num` THEN STRIP_TAC THEN + ASM_SIMP_TAC[LAMBDA_BETA; VECTOR_SUB_COMPONENT] THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[GSYM REAL_POW_2; GSYM REAL_LE_SQUARE_ABS] THEN + ASM_REAL_ARITH_TAC; + ASM_REWRITE_TAC[SUM_DELTA; IN_NUMSEG; REAL_LE_REFL]]]; + SUBGOAL_THEN + `!b. integral + (interval[u:real^N, + (lambda j. if j = i then min (v$i) b else (v:real^N)$j)]) + (indicator s) = + lift(measure(s INTER interval[u,v] INTER {x | x$i <= b}))` + (fun th -> REWRITE_TAC[th]) + THENL + [GEN_TAC THEN + ASM_SIMP_TAC[MEASURE_INTEGRAL; MEASURABLE_INTER_HALFSPACE_LE; + MEASURABLE_INTER; MEASURABLE_INTERVAL; LIFT_DROP] THEN + ONCE_REWRITE_TAC[GSYM INTEGRAL_RESTRICT_UNIV] THEN + AP_TERM_TAC THEN REWRITE_TAC[FUN_EQ_THM] THEN GEN_TAC THEN + ASM_SIMP_TAC[INTERVAL_SPLIT; indicator] THEN + REWRITE_TAC[IN_INTER] THEN MESON_TAC[]; + REWRITE_TAC[GSYM LIFT_SUB; NORM_LIFT] THEN + SUBGOAL_THEN + `!b. measure(s INTER {x:real^N | x$i <= b}) = + measure((s INTER interval[u,v]) INTER {x | x$i <= b}) + + measure((s DIFF interval[u,v]) INTER {x | x$i <= b})` + (fun th -> REWRITE_TAC[th]) + THENL + [GEN_TAC THEN CONV_TAC SYM_CONV THEN + MATCH_MP_TAC MEASURE_NEGLIGIBLE_UNION_EQ THEN + ASM_SIMP_TAC[MEASURABLE_INTER; MEASURABLE_INTER_HALFSPACE_LE; + MEASURABLE_INTERVAL; MEASURABLE_DIFF] THEN + CONJ_TAC THENL [SET_TAC[]; ALL_TAC] THEN + MATCH_MP_TAC(MESON[NEGLIGIBLE_EMPTY] `s = {} ==> negligible s`) THEN + SET_TAC[]; + REWRITE_TAC[GSYM INTER_ASSOC] THEN MATCH_MP_TAC(REAL_ARITH + `abs(nub - nua) < e / &2 + ==> abs(mub - mua) < e / &2 + ==> abs((mub + nub) - (mua + nua)) < e`) THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH + `y < e ==> x <= y ==> x < e`)) THEN + SUBGOAL_THEN + `abs(measure(s INTER interval [u,v]) - measure s) = + measure(s DIFF interval[u:real^N,v])` + SUBST1_TAC THENL + [MATCH_MP_TAC(REAL_ARITH + `x + z = y /\ &0 <= z ==> abs(x - y) = z`) THEN + ASM_SIMP_TAC[MEASURE_POS_LE; MEASURABLE_DIFF; + MEASURABLE_INTERVAL] THEN + MATCH_MP_TAC MEASURE_NEGLIGIBLE_UNION_EQ THEN + ASM_SIMP_TAC[MEASURABLE_INTER; MEASURABLE_DIFF; + MEASURABLE_INTERVAL] THEN + CONJ_TAC THENL [SET_TAC[]; ALL_TAC] THEN + MATCH_MP_TAC(MESON[NEGLIGIBLE_EMPTY] `s = {} ==> negligible s`) THEN + SET_TAC[]; + MATCH_MP_TAC(REAL_ARITH + `&0 <= x /\ x <= a /\ &0 <= y /\ y <= a ==> abs(x - y) <= a`) THEN + ASM_SIMP_TAC[MEASURABLE_INTER; MEASURABLE_INTER_HALFSPACE_LE; + MEASURABLE_INTERVAL; MEASURABLE_DIFF; MEASURE_POS_LE] THEN + CONJ_TAC THEN MATCH_MP_TAC MEASURE_SUBSET THEN + ASM_SIMP_TAC[MEASURABLE_INTER; MEASURABLE_INTER_HALFSPACE_LE; + MEASURABLE_INTERVAL; MEASURABLE_DIFF; MEASURE_POS_LE] THEN + SET_TAC[]]]]]);; + +(* ------------------------------------------------------------------------- *) +(* Second mean value theorem and monotone integrability. *) +(* ------------------------------------------------------------------------- *) + +let REAL_SECOND_MEAN_VALUE_THEOREM_FULL = prove + (`!f g a b. + ~(real_interval[a,b] = {}) /\ + f real_integrable_on real_interval[a,b] /\ + (!x y. x IN real_interval[a,b] /\ y IN real_interval[a,b] /\ x <= y + ==> g x <= g y) + ==> ?c. c IN real_interval[a,b] /\ + ((\x. g x * f x) has_real_integral + (g(a) * real_integral (real_interval[a,c]) f + + g(b) * real_integral (real_interval[c,b]) f)) + (real_interval[a,b])`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`lift o f o drop`; `(g:real->real) o drop`; + `lift a`; `lift b`] + SECOND_MEAN_VALUE_THEOREM_FULL) THEN + ASM_REWRITE_TAC[GSYM IMAGE_LIFT_REAL_INTERVAL; IMAGE_EQ_EMPTY] THEN + ASM_REWRITE_TAC[GSYM REAL_INTEGRABLE_ON] THEN + REWRITE_TAC[EXISTS_IN_IMAGE; IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN + ASM_SIMP_TAC[FORALL_IN_IMAGE; o_THM; LIFT_DROP] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `c:real` THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[HAS_REAL_INTEGRAL; IMAGE_LIFT_REAL_INTERVAL] THEN + MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN + REWRITE_TAC[o_DEF; LIFT_CMUL; LIFT_ADD] THEN AP_TERM_TAC THEN + BINOP_TAC THEN AP_TERM_TAC THEN ONCE_REWRITE_TAC[GSYM DROP_EQ] THEN + REWRITE_TAC[LIFT_DROP] THEN + W(MP_TAC o PART_MATCH (lhs o rand) REAL_INTEGRAL o rand o snd) THEN + REWRITE_TAC[o_DEF] THEN ANTS_TAC THEN SIMP_TAC[IMAGE_LIFT_REAL_INTERVAL] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + REAL_INTEGRABLE_ON_SUBINTERVAL)) THEN + REWRITE_TAC[SUBSET_REAL_INTERVAL] THEN + RULE_ASSUM_TAC(REWRITE_RULE[IN_REAL_INTERVAL; REAL_INTERVAL_EQ_EMPTY]) THEN + ASM_REAL_ARITH_TAC);; + +let REAL_SECOND_MEAN_VALUE_THEOREM = prove + (`!f g a b. + ~(real_interval[a,b] = {}) /\ + f real_integrable_on real_interval[a,b] /\ + (!x y. x IN real_interval[a,b] /\ y IN real_interval[a,b] /\ x <= y + ==> g x <= g y) + ==> ?c. c IN real_interval[a,b] /\ + real_integral (real_interval[a,b]) (\x. g x * f x) = + g(a) * real_integral (real_interval[a,c]) f + + g(b) * real_integral (real_interval[c,b]) f`, + REPEAT GEN_TAC THEN + DISCH_THEN(MP_TAC o MATCH_MP REAL_SECOND_MEAN_VALUE_THEOREM_FULL) THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `c:real` THEN + REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + FIRST_X_ASSUM(SUBST1_TAC o MATCH_MP REAL_INTEGRAL_UNIQUE) THEN + REWRITE_TAC[]);; + +let REAL_SECOND_MEAN_VALUE_THEOREM_GEN_FULL = prove + (`!f g a b u v. + ~(real_interval[a,b] = {}) /\ + f real_integrable_on real_interval[a,b] /\ + (!x. x IN real_interval(a,b) ==> u <= g x /\ g x <= v) /\ + (!x y. x IN real_interval[a,b] /\ y IN real_interval[a,b] /\ x <= y + ==> g x <= g y) + ==> ?c. c IN real_interval[a,b] /\ + ((\x. g x * f x) has_real_integral + (u * real_integral (real_interval[a,c]) f + + v * real_integral (real_interval[c,b]) f)) + (real_interval[a,b])`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`lift o f o drop`; `(g:real->real) o drop`; + `lift a`; `lift b`; `u:real`; `v:real`] + SECOND_MEAN_VALUE_THEOREM_GEN_FULL) THEN + ASM_REWRITE_TAC[GSYM IMAGE_LIFT_REAL_INTERVAL; IMAGE_EQ_EMPTY] THEN + ASM_REWRITE_TAC[GSYM REAL_INTEGRABLE_ON] THEN + REWRITE_TAC[EXISTS_IN_IMAGE; IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN + ASM_SIMP_TAC[FORALL_IN_IMAGE; o_THM; LIFT_DROP] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `c:real` THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[HAS_REAL_INTEGRAL; IMAGE_LIFT_REAL_INTERVAL] THEN + MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN + REWRITE_TAC[o_DEF; LIFT_CMUL; LIFT_ADD] THEN AP_TERM_TAC THEN + BINOP_TAC THEN AP_TERM_TAC THEN ONCE_REWRITE_TAC[GSYM DROP_EQ] THEN + REWRITE_TAC[LIFT_DROP] THEN + W(MP_TAC o PART_MATCH (lhs o rand) REAL_INTEGRAL o rand o snd) THEN + REWRITE_TAC[o_DEF] THEN ANTS_TAC THEN SIMP_TAC[IMAGE_LIFT_REAL_INTERVAL] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + REAL_INTEGRABLE_ON_SUBINTERVAL)) THEN + REWRITE_TAC[SUBSET_REAL_INTERVAL] THEN + RULE_ASSUM_TAC(REWRITE_RULE[IN_REAL_INTERVAL; REAL_INTERVAL_EQ_EMPTY]) THEN + ASM_REAL_ARITH_TAC);; + +let REAL_SECOND_MEAN_VALUE_THEOREM_GEN = prove + (`!f g a b u v. + ~(real_interval[a,b] = {}) /\ + f real_integrable_on real_interval[a,b] /\ + (!x. x IN real_interval(a,b) ==> u <= g x /\ g x <= v) /\ + (!x y. x IN real_interval[a,b] /\ y IN real_interval[a,b] /\ x <= y + ==> g x <= g y) + ==> ?c. c IN real_interval[a,b] /\ + real_integral (real_interval[a,b]) (\x. g x * f x) = + u * real_integral (real_interval[a,c]) f + + v * real_integral (real_interval[c,b]) f`, + REPEAT GEN_TAC THEN + DISCH_THEN(MP_TAC o MATCH_MP REAL_SECOND_MEAN_VALUE_THEOREM_GEN_FULL) THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `c:real` THEN + REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + FIRST_X_ASSUM(SUBST1_TAC o MATCH_MP REAL_INTEGRAL_UNIQUE) THEN + REWRITE_TAC[]);; + +let REAL_SECOND_MEAN_VALUE_THEOREM_BONNET_FULL = prove + (`!f g a b. + ~(real_interval[a,b] = {}) /\ + f real_integrable_on real_interval[a,b] /\ + (!x. x IN real_interval[a,b] ==> &0 <= g x) /\ + (!x y. x IN real_interval[a,b] /\ y IN real_interval[a,b] /\ x <= y + ==> g x <= g y) + ==> ?c. c IN real_interval[a,b] /\ + ((\x. g x * f x) has_real_integral + (g(b) * real_integral (real_interval[c,b]) f)) + (real_interval[a,b])`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`lift o f o drop`; `(g:real->real) o drop`; + `lift a`; `lift b`] + SECOND_MEAN_VALUE_THEOREM_BONNET_FULL) THEN + ASM_REWRITE_TAC[GSYM IMAGE_LIFT_REAL_INTERVAL; IMAGE_EQ_EMPTY] THEN + ASM_REWRITE_TAC[GSYM REAL_INTEGRABLE_ON] THEN + REWRITE_TAC[EXISTS_IN_IMAGE; IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN + ASM_SIMP_TAC[FORALL_IN_IMAGE; o_THM; LIFT_DROP] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `c:real` THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[HAS_REAL_INTEGRAL; IMAGE_LIFT_REAL_INTERVAL] THEN + MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN + REWRITE_TAC[o_DEF; LIFT_CMUL; LIFT_ADD] THEN AP_TERM_TAC THEN + AP_TERM_TAC THEN ONCE_REWRITE_TAC[GSYM DROP_EQ] THEN + REWRITE_TAC[LIFT_DROP] THEN + W(MP_TAC o PART_MATCH (lhs o rand) REAL_INTEGRAL o rand o snd) THEN + REWRITE_TAC[o_DEF] THEN ANTS_TAC THEN SIMP_TAC[IMAGE_LIFT_REAL_INTERVAL] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + REAL_INTEGRABLE_ON_SUBINTERVAL)) THEN + REWRITE_TAC[SUBSET_REAL_INTERVAL] THEN + RULE_ASSUM_TAC(REWRITE_RULE[IN_REAL_INTERVAL; REAL_INTERVAL_EQ_EMPTY]) THEN + ASM_REAL_ARITH_TAC);; + +let REAL_SECOND_MEAN_VALUE_THEOREM_BONNET = prove + (`!f g a b. + ~(real_interval[a,b] = {}) /\ + f real_integrable_on real_interval[a,b] /\ + (!x. x IN real_interval[a,b] ==> &0 <= g x) /\ + (!x y. x IN real_interval[a,b] /\ y IN real_interval[a,b] /\ x <= y + ==> g x <= g y) + ==> ?c. c IN real_interval[a,b] /\ + real_integral (real_interval[a,b]) (\x. g x * f x) = + g(b) * real_integral (real_interval[c,b]) f`, + REPEAT GEN_TAC THEN + DISCH_THEN(MP_TAC o MATCH_MP REAL_SECOND_MEAN_VALUE_THEOREM_BONNET_FULL) THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `c:real` THEN + REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + FIRST_X_ASSUM(SUBST1_TAC o MATCH_MP REAL_INTEGRAL_UNIQUE) THEN + REWRITE_TAC[]);; + +let REAL_INTEGRABLE_INCREASING_PRODUCT = prove + (`!f g a b. + f real_integrable_on real_interval[a,b] /\ + (!x y. x IN real_interval[a,b] /\ y IN real_interval[a,b] /\ x <= y + ==> g(x) <= g(y)) + ==> (\x. g(x) * f(x)) real_integrable_on real_interval[a,b]`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`lift o f o drop`; `(g:real->real) o drop`; + `lift a`; `lift b`] + INTEGRABLE_INCREASING_PRODUCT) THEN + ASM_REWRITE_TAC[GSYM IMAGE_LIFT_REAL_INTERVAL; + GSYM REAL_INTEGRABLE_ON] THEN + ASM_SIMP_TAC[FORALL_IN_IMAGE; IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN + ASM_SIMP_TAC[o_DEF; LIFT_DROP; REAL_INTEGRABLE_ON; LIFT_CMUL]);; + +let REAL_INTEGRABLE_INCREASING_PRODUCT_UNIV = prove + (`!f g B. + f real_integrable_on (:real) /\ + (!x y. x <= y ==> g x <= g y) /\ + (!x. abs(g x) <= B) + ==> (\x. g x * f x) real_integrable_on (:real)`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`lift o f o drop`; `(g:real->real) o drop`; `B:real`] + INTEGRABLE_INCREASING_PRODUCT_UNIV) THEN + ASM_REWRITE_TAC[GSYM IMAGE_LIFT_UNIV; + GSYM REAL_INTEGRABLE_ON] THEN + ASM_SIMP_TAC[FORALL_IN_IMAGE; IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN + ASM_SIMP_TAC[o_DEF; LIFT_DROP; REAL_INTEGRABLE_ON; LIFT_CMUL]);; + +let REAL_INTEGRABLE_INCREASING = prove + (`!f a b. + (!x y. x IN real_interval[a,b] /\ y IN real_interval[a,b] /\ x <= y + ==> f(x) <= f(y)) + ==> f real_integrable_on real_interval[a,b]`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`lift o f o drop`; `lift a`; `lift b`] + INTEGRABLE_INCREASING_1) THEN + ASM_REWRITE_TAC[GSYM IMAGE_LIFT_REAL_INTERVAL; + GSYM REAL_INTEGRABLE_ON] THEN + DISCH_THEN MATCH_MP_TAC THEN + ASM_SIMP_TAC[FORALL_IN_IMAGE; IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN + ASM_SIMP_TAC[o_DEF; LIFT_DROP; REAL_INTEGRABLE_ON; LIFT_CMUL]);; + +let REAL_INTEGRABLE_DECREASING_PRODUCT = prove + (`!f g a b. + f real_integrable_on real_interval[a,b] /\ + (!x y. x IN real_interval[a,b] /\ y IN real_interval[a,b] /\ x <= y + ==> g(y) <= g(x)) + ==> (\x. g(x) * f(x)) real_integrable_on real_interval[a,b]`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`lift o f o drop`; `(g:real->real) o drop`; + `lift a`; `lift b`] + INTEGRABLE_DECREASING_PRODUCT) THEN + ASM_REWRITE_TAC[GSYM IMAGE_LIFT_REAL_INTERVAL; + GSYM REAL_INTEGRABLE_ON] THEN + ASM_SIMP_TAC[FORALL_IN_IMAGE; IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN + ASM_SIMP_TAC[o_DEF; LIFT_DROP; REAL_INTEGRABLE_ON; LIFT_CMUL]);; + +let REAL_INTEGRABLE_DECREASING_PRODUCT_UNIV = prove + (`!f g B. + f real_integrable_on (:real) /\ + (!x y. x <= y ==> g y <= g x) /\ + (!x. abs(g x) <= B) + ==> (\x. g x * f x) real_integrable_on (:real)`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`lift o f o drop`; `(g:real->real) o drop`; `B:real`] + INTEGRABLE_DECREASING_PRODUCT_UNIV) THEN + ASM_REWRITE_TAC[GSYM IMAGE_LIFT_UNIV; + GSYM REAL_INTEGRABLE_ON] THEN + ASM_SIMP_TAC[FORALL_IN_IMAGE; IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN + ASM_SIMP_TAC[o_DEF; LIFT_DROP; REAL_INTEGRABLE_ON; LIFT_CMUL]);; + +let REAL_INTEGRABLE_DECREASING = prove + (`!f a b. + (!x y. x IN real_interval[a,b] /\ y IN real_interval[a,b] /\ x <= y + ==> f(y) <= f(x)) + ==> f real_integrable_on real_interval[a,b]`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`lift o f o drop`; `lift a`; `lift b`] + INTEGRABLE_DECREASING_1) THEN + ASM_REWRITE_TAC[GSYM IMAGE_LIFT_REAL_INTERVAL; + GSYM REAL_INTEGRABLE_ON] THEN + DISCH_THEN MATCH_MP_TAC THEN + ASM_SIMP_TAC[FORALL_IN_IMAGE; IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN + ASM_SIMP_TAC[o_DEF; LIFT_DROP; REAL_INTEGRABLE_ON; LIFT_CMUL]);; + +(* ------------------------------------------------------------------------- *) +(* Measurability and absolute integrability of monotone functions. *) +(* ------------------------------------------------------------------------- *) + +let REAL_MEASURABLE_ON_INCREASING_UNIV = prove + (`!f. (!x y. x <= y ==> f x <= f y) ==> f real_measurable_on (:real)`, + REPEAT STRIP_TAC THEN + REWRITE_TAC[REAL_MEASURABLE_ON_PREIMAGE_OPEN_HALFSPACE_LE] THEN + X_GEN_TAC `y:real` THEN + REPEAT_TCL STRIP_THM_THEN ASSUME_TAC + (SET_RULE `{x | (f:real->real) x <= y} = {} \/ + {x | (f:real->real) x <= y} = UNIV \/ + ?a b. f a <= y /\ ~(f b <= y)`) THEN + ASM_REWRITE_TAC[REAL_LEBESGUE_MEASURABLE_EMPTY; + REAL_LEBESGUE_MEASURABLE_UNIV] THEN + MP_TAC(ISPEC `{x | (f:real->real) x <= y}` SUP) THEN + REWRITE_TAC[IN_ELIM_THM; EXTENSION; NOT_IN_EMPTY] THEN ANTS_TAC THENL + [ASM_MESON_TAC[REAL_LE_TOTAL; REAL_LE_TRANS]; ALL_TAC] THEN + ABBREV_TAC `s = sup {x | (f:real->real) x <= y}` THEN STRIP_TAC THEN + SUBGOAL_THEN + `(!x. (f:real->real) x <= y <=> x < s) \/ + (!x. (f:real->real) x <= y <=> x <= s)` + STRIP_ASSUME_TAC THENL + [ASM_CASES_TAC `(f:real->real) s <= y` THEN + ASM_MESON_TAC[REAL_LE_TRANS; REAL_NOT_LE; REAL_LE_ANTISYM; REAL_LE_TOTAL]; + ASM_SIMP_TAC[REAL_OPEN_HALFSPACE_LT; REAL_LEBESGUE_MEASURABLE_OPEN]; + ASM_SIMP_TAC[REAL_CLOSED_HALFSPACE_LE; REAL_LEBESGUE_MEASURABLE_CLOSED]]);; + +let REAL_MEASURABLE_ON_INCREASING = prove + (`!f a b. (!x y. x IN real_interval[a,b] /\ y IN real_interval[a,b] /\ x <= y + ==> f x <= f y) + ==> f real_measurable_on real_interval[a,b]`, + REWRITE_TAC[IN_REAL_INTERVAL] THEN REPEAT STRIP_TAC THEN + ASM_CASES_TAC `real_interval[a,b] = {}` THENL + [ONCE_REWRITE_TAC[GSYM REAL_MEASURABLE_ON_UNIV] THEN + ASM_REWRITE_TAC[NOT_IN_EMPTY; REAL_MEASURABLE_ON_0]; + RULE_ASSUM_TAC(REWRITE_RULE[REAL_INTERVAL_EQ_EMPTY; REAL_NOT_LT])] THEN + ABBREV_TAC `g = \x. if x < a then f(a) + else if b < x then f(b) + else (f:real->real) x` THEN + SUBGOAL_THEN `g real_measurable_on real_interval[a,b]` MP_TAC THENL + [ALL_TAC; + ONCE_REWRITE_TAC[GSYM REAL_MEASURABLE_ON_UNIV] THEN EXPAND_TAC "g" THEN + SIMP_TAC[IN_REAL_INTERVAL; GSYM REAL_NOT_LT]] THEN + MATCH_MP_TAC REAL_MEASURABLE_ON_LEBESGUE_MEASURABLE_SUBSET THEN + EXISTS_TAC `(:real)` THEN + REWRITE_TAC[SUBSET_UNIV; REAL_LEBESGUE_MEASURABLE_INTERVAL] THEN + MATCH_MP_TAC REAL_MEASURABLE_ON_INCREASING_UNIV THEN EXPAND_TAC "g" THEN + ASM_MESON_TAC[REAL_LT_LE; REAL_LE_TRANS; REAL_LE_TOTAL; REAL_LE_ANTISYM; + REAL_NOT_LT; REAL_LT_IMP_LE; REAL_LE_REFL]);; + +let REAL_MEASURABLE_ON_DECREASING_UNIV = prove + (`!f. (!x y. x <= y ==> f y <= f x) ==> f real_measurable_on (:real)`, + REPEAT STRIP_TAC THEN + GEN_REWRITE_TAC I [GSYM REAL_MEASURABLE_ON_NEG_EQ] THEN + MATCH_MP_TAC REAL_MEASURABLE_ON_INCREASING_UNIV THEN + ASM_SIMP_TAC[REAL_LE_NEG2]);; + +let REAL_MEASURABLE_ON_DECREASING = prove + (`!f a b. (!x y. x IN real_interval[a,b] /\ y IN real_interval[a,b] /\ x <= y + ==> f y <= f x) + ==> f real_measurable_on real_interval[a,b]`, + REPEAT STRIP_TAC THEN + GEN_REWRITE_TAC I [GSYM REAL_MEASURABLE_ON_NEG_EQ] THEN + MATCH_MP_TAC REAL_MEASURABLE_ON_INCREASING THEN + ASM_SIMP_TAC[REAL_LE_NEG2]);; + +let ABSOLUTELY_REAL_INTEGRABLE_INCREASING_PRODUCT = prove + (`!f g a b. + (!x y. x IN real_interval[a,b] /\ y IN real_interval[a,b] /\ x <= y + ==> f x <= f y) /\ + g absolutely_real_integrable_on real_interval[a,b] + ==> (\x. f x * g x) absolutely_real_integrable_on real_interval[a,b]`, + REPEAT STRIP_TAC THEN + MATCH_MP_TAC ABSOLUTELY_REAL_INTEGRABLE_BOUNDED_MEASURABLE_PRODUCT THEN + ASM_SIMP_TAC[REAL_MEASURABLE_ON_INCREASING] THEN + REWRITE_TAC[real_bounded; FORALL_IN_IMAGE] THEN + EXISTS_TAC `abs((f:real->real) a) + abs((f:real->real) b)` THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC + (REAL_ARITH `a <= x /\ x <= b ==> abs x <= abs a + abs b`) THEN + CONJ_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_REWRITE_TAC[] THEN + ASM_MESON_TAC[IN_REAL_INTERVAL; REAL_LE_TRANS; REAL_LE_REFL]);; + +let ABSOLUTELY_REAL_INTEGRABLE_INCREASING = prove + (`!f a b. (!x y. x IN real_interval[a,b] /\ y IN real_interval[a,b] /\ x <= y + ==> f x <= f y) + ==> f absolutely_real_integrable_on real_interval[a,b]`, + REPEAT STRIP_TAC THEN GEN_REWRITE_TAC LAND_CONV [GSYM ETA_AX] THEN + GEN_REWRITE_TAC (LAND_CONV o ABS_CONV) [GSYM REAL_MUL_RID] THEN + MATCH_MP_TAC ABSOLUTELY_REAL_INTEGRABLE_INCREASING_PRODUCT THEN + ASM_REWRITE_TAC[ABSOLUTELY_REAL_INTEGRABLE_CONST]);; + +let ABSOLUTELY_REAL_INTEGRABLE_DECREASING_PRODUCT = prove + (`!f g a b. + (!x y. x IN real_interval[a,b] /\ y IN real_interval[a,b] /\ x <= y + ==> f y <= f x) /\ + g absolutely_real_integrable_on real_interval[a,b] + ==> (\x. f x * g x) absolutely_real_integrable_on real_interval[a,b]`, + REPEAT STRIP_TAC THEN + MATCH_MP_TAC ABSOLUTELY_REAL_INTEGRABLE_BOUNDED_MEASURABLE_PRODUCT THEN + ASM_SIMP_TAC[REAL_MEASURABLE_ON_DECREASING] THEN + REWRITE_TAC[real_bounded; FORALL_IN_IMAGE] THEN + EXISTS_TAC `abs((f:real->real) a) + abs((f:real->real) b)` THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC + (REAL_ARITH `b <= x /\ x <= a ==> abs x <= abs a + abs b`) THEN + CONJ_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_REWRITE_TAC[] THEN + ASM_MESON_TAC[IN_REAL_INTERVAL; REAL_LE_TRANS; REAL_LE_REFL]);; + +let ABSOLUTELY_REAL_INTEGRABLE_DECREASING = prove + (`!f a b. (!x y. x IN real_interval[a,b] /\ y IN real_interval[a,b] /\ x <= y + ==> f y <= f x) + ==> f absolutely_real_integrable_on real_interval[a,b]`, + REPEAT STRIP_TAC THEN GEN_REWRITE_TAC LAND_CONV [GSYM ETA_AX] THEN + GEN_REWRITE_TAC (LAND_CONV o ABS_CONV) [GSYM REAL_MUL_RID] THEN + MATCH_MP_TAC ABSOLUTELY_REAL_INTEGRABLE_DECREASING_PRODUCT THEN + ASM_REWRITE_TAC[ABSOLUTELY_REAL_INTEGRABLE_CONST]);; + +(* ------------------------------------------------------------------------- *) +(* Real functions of bounded variation. *) +(* ------------------------------------------------------------------------- *) + +parse_as_infix("has_bounded_real_variation_on",(12,"right"));; + +let has_bounded_real_variation_on = new_definition + `f has_bounded_real_variation_on s <=> + (lift o f o drop) has_bounded_variation_on (IMAGE lift s)`;; + +let real_variation = new_definition + `real_variation s f = vector_variation (IMAGE lift s) (lift o f o drop)`;; + +let HAS_BOUNDED_REAL_VARIATION_ON_EQ = prove + (`!f g s. + (!x. x IN s ==> f x = g x) /\ f has_bounded_real_variation_on s + + + ==> g has_bounded_real_variation_on s`, + REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + REWRITE_TAC[IMP_CONJ; has_bounded_real_variation_on] THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] HAS_BOUNDED_VARIATION_ON_EQ) THEN + ASM_SIMP_TAC[FORALL_IN_IMAGE; o_THM; LIFT_DROP]);; + +let HAS_BOUNDED_REAL_VARIATION_ON_SUBSET = prove + (`!f s t. f has_bounded_real_variation_on s /\ t SUBSET s + ==> f has_bounded_real_variation_on t`, + REWRITE_TAC[has_bounded_real_variation_on] THEN + MESON_TAC[HAS_BOUNDED_VARIATION_ON_SUBSET; IMAGE_SUBSET]);; + +let HAS_BOUNDED_REAL_VARIATION_ON_LMUL = prove + (`!f c s. f has_bounded_real_variation_on s + ==> (\x. c * f x) has_bounded_real_variation_on s`, + REPEAT GEN_TAC THEN REWRITE_TAC[has_bounded_real_variation_on] THEN + REWRITE_TAC[o_DEF; LIFT_CMUL; HAS_BOUNDED_VARIATION_ON_CMUL]);; + +let HAS_BOUNDED_REAL_VARIATION_ON_RMUL = prove + (`!f c s. f has_bounded_real_variation_on s + ==> (\x. f x * c) has_bounded_real_variation_on s`, + ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN + REWRITE_TAC[HAS_BOUNDED_REAL_VARIATION_ON_LMUL]);; + +let HAS_BOUNDED_REAL_VARIATION_ON_NEG = prove + (`!f s. f has_bounded_real_variation_on s + ==> (\x. --f x) has_bounded_real_variation_on s`, + REWRITE_TAC[has_bounded_real_variation_on; o_DEF; LIFT_NEG] THEN + REWRITE_TAC[HAS_BOUNDED_VARIATION_ON_NEG]);; + +let HAS_BOUNDED_REAL_VARIATION_ON_ADD = prove + (`!f g s. f has_bounded_real_variation_on s /\ + g has_bounded_real_variation_on s + ==> (\x. f x + g x) has_bounded_real_variation_on s`, + REWRITE_TAC[has_bounded_real_variation_on; o_DEF; LIFT_ADD] THEN + REWRITE_TAC[HAS_BOUNDED_VARIATION_ON_ADD]);; + +let HAS_BOUNDED_REAL_VARIATION_ON_SUB = prove + (`!f g s. f has_bounded_real_variation_on s /\ + g has_bounded_real_variation_on s + ==> (\x. f x - g x) has_bounded_real_variation_on s`, + REWRITE_TAC[has_bounded_real_variation_on; o_DEF; LIFT_SUB] THEN + REWRITE_TAC[HAS_BOUNDED_VARIATION_ON_SUB]);; + +let HAS_BOUNDED_REAL_VARIATION_ON_NULL = prove + (`!f a b. b <= a ==> f has_bounded_real_variation_on real_interval[a,b]`, + REPEAT STRIP_TAC THEN REWRITE_TAC[has_bounded_real_variation_on] THEN + REWRITE_TAC[IMAGE_LIFT_REAL_INTERVAL] THEN + MATCH_MP_TAC HAS_BOUNDED_VARIATION_ON_NULL THEN + ASM_REWRITE_TAC[BOUNDED_INTERVAL; CONTENT_EQ_0_1; LIFT_DROP]);; + +let HAS_BOUNDED_REAL_VARIATION_ON_EMPTY = prove + (`!f. f has_bounded_real_variation_on {}`, + REWRITE_TAC[IMAGE_CLAUSES; has_bounded_real_variation_on] THEN + REWRITE_TAC[HAS_BOUNDED_VARIATION_ON_EMPTY]);; + +let HAS_BOUNDED_REAL_VARIATION_ON_ABS = prove + (`!f s. f has_bounded_real_variation_on s + ==> (\x. abs(f x)) has_bounded_real_variation_on s`, + REPEAT GEN_TAC THEN REWRITE_TAC[has_bounded_real_variation_on] THEN + DISCH_THEN(MP_TAC o MATCH_MP HAS_BOUNDED_VARIATION_ON_NORM) THEN + REWRITE_TAC[o_DEF; NORM_REAL; GSYM drop; LIFT_DROP]);; + +let HAS_BOUNDED_REAL_VARIATION_ON_MAX = prove + (`!f g s. f has_bounded_real_variation_on s /\ + g has_bounded_real_variation_on s + ==> (\x. max (f x) (g x)) has_bounded_real_variation_on s`, + REPEAT GEN_TAC THEN REWRITE_TAC[has_bounded_real_variation_on] THEN + DISCH_THEN(MP_TAC o MATCH_MP HAS_BOUNDED_VARIATION_ON_MAX) THEN + REWRITE_TAC[o_DEF; LIFT_DROP]);; + +let HAS_BOUNDED_REAL_VARIATION_ON_MIN = prove + (`!f g s. f has_bounded_real_variation_on s /\ + g has_bounded_real_variation_on s + ==> (\x. min (f x) (g x)) has_bounded_real_variation_on s`, + REPEAT GEN_TAC THEN REWRITE_TAC[has_bounded_real_variation_on] THEN + DISCH_THEN(MP_TAC o MATCH_MP HAS_BOUNDED_VARIATION_ON_MIN) THEN + REWRITE_TAC[o_DEF; LIFT_DROP]);; + +let HAS_BOUNDED_REAL_VARIATION_ON_IMP_BOUNDED_ON_INTERVAL = prove + (`!f a b. f has_bounded_real_variation_on real_interval[a,b] + ==> real_bounded(IMAGE f (real_interval[a,b]))`, + REPEAT GEN_TAC THEN + REWRITE_TAC[has_bounded_real_variation_on; REAL_BOUNDED] THEN + REWRITE_TAC[IMAGE_LIFT_REAL_INTERVAL] THEN + DISCH_THEN(MP_TAC o MATCH_MP + HAS_BOUNDED_VARIATION_ON_IMP_BOUNDED_ON_INTERVAL) THEN + REWRITE_TAC[IMAGE_o; IMAGE_DROP_INTERVAL; LIFT_DROP]);; + +let HAS_BOUNDED_REAL_VARIATION_ON_MUL = prove + (`!f g a b. + f has_bounded_real_variation_on real_interval[a,b] /\ + g has_bounded_real_variation_on real_interval[a,b] + ==> (\x. f x * g x) has_bounded_real_variation_on real_interval[a,b]`, + REPEAT GEN_TAC THEN REWRITE_TAC[has_bounded_real_variation_on] THEN + REWRITE_TAC[IMAGE_LIFT_REAL_INTERVAL] THEN + DISCH_THEN(MP_TAC o MATCH_MP HAS_BOUNDED_VARIATION_ON_MUL) THEN + REWRITE_TAC[o_DEF; LIFT_CMUL; LIFT_DROP]);; + +let REAL_VARIATION_POS_LE = prove + (`!f s. f has_bounded_real_variation_on s ==> &0 <= real_variation s f`, + REWRITE_TAC[real_variation; has_bounded_real_variation_on] THEN + REWRITE_TAC[VECTOR_VARIATION_POS_LE]);; + +let REAL_VARIATION_GE_ABS_FUNCTION = prove + (`!f s a b. + f has_bounded_real_variation_on s /\ real_segment[a,b] SUBSET s + ==> abs(f b - f a) <= real_variation s f`, + REWRITE_TAC[has_bounded_real_variation_on] THEN REPEAT STRIP_TAC THEN + MP_TAC(ISPECL + [`lift o f o drop`; `IMAGE lift s`; `lift a`; `lift b`] + VECTOR_VARIATION_GE_NORM_FUNCTION) THEN + ASM_SIMP_TAC[GSYM IMAGE_LIFT_REAL_SEGMENT; + IMAGE_EQ_EMPTY; IMAGE_SUBSET] THEN + REWRITE_TAC[real_variation; o_THM; LIFT_DROP; GSYM LIFT_SUB; NORM_LIFT]);; + +let REAL_VARIATION_GE_FUNCTION = prove + (`!f s a b. + f has_bounded_real_variation_on s /\ real_segment[a,b] SUBSET s + ==> f b - f a <= real_variation s f`, + REPEAT STRIP_TAC THEN + MATCH_MP_TAC(REAL_ARITH `abs x <= a ==> x <= a`) THEN + ASM_MESON_TAC[REAL_VARIATION_GE_ABS_FUNCTION]);; + +let REAL_VARIATION_MONOTONE = prove + (`!f s t. f has_bounded_real_variation_on s /\ t SUBSET s + ==> real_variation t f <= real_variation s f`, + REWRITE_TAC[has_bounded_real_variation_on; real_variation] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC VECTOR_VARIATION_MONOTONE THEN + ASM_SIMP_TAC[IMAGE_SUBSET]);; + +let REAL_VARIATION_NEG = prove + (`!f s. real_variation s (\x. --(f x)) = real_variation s f`, + SIMP_TAC[real_variation; o_DEF; LIFT_NEG; VECTOR_VARIATION_NEG]);; + +let REAL_VARIATION_TRIANGLE = prove + (`!f g s. f has_bounded_real_variation_on s /\ + g has_bounded_real_variation_on s + ==> real_variation s (\x. f x + g x) + <= real_variation s f + real_variation s g`, + REPEAT GEN_TAC THEN + REWRITE_TAC[has_bounded_real_variation_on; real_variation] THEN + DISCH_THEN(MP_TAC o MATCH_MP VECTOR_VARIATION_TRIANGLE) THEN + REWRITE_TAC[o_DEF; LIFT_ADD]);; + +let HAS_BOUNDED_REAL_VARIATION_ON_COMBINE = prove + (`!f a b c. + a <= c /\ c <= b + ==> (f has_bounded_real_variation_on real_interval[a,b] <=> + f has_bounded_real_variation_on real_interval[a,c] /\ + f has_bounded_real_variation_on real_interval[c,b])`, + REWRITE_TAC[has_bounded_real_variation_on; IMAGE_LIFT_REAL_INTERVAL] THEN + REPEAT STRIP_TAC THEN MP_TAC(ISPECL + [`lift o f o drop`; `lift a`; `lift b`; `lift c`] + HAS_BOUNDED_VARIATION_ON_COMBINE) THEN + ASM_REWRITE_TAC[LIFT_DROP; has_bounded_real_variation_on; + IMAGE_LIFT_REAL_INTERVAL]);; + +let REAL_VARIATION_COMBINE = prove + (`!f a b c. + a <= c /\ c <= b /\ + f has_bounded_real_variation_on real_interval[a,b] + ==> real_variation (real_interval[a,c]) f + + real_variation (real_interval[c,b]) f = + real_variation (real_interval[a,b]) f`, + REWRITE_TAC[has_bounded_real_variation_on; IMAGE_LIFT_REAL_INTERVAL] THEN + REPEAT STRIP_TAC THEN MP_TAC(ISPECL + [`lift o f o drop`; `lift a`; `lift b`; `lift c`] + VECTOR_VARIATION_COMBINE) THEN + ASM_REWRITE_TAC[LIFT_DROP; real_variation; IMAGE_LIFT_REAL_INTERVAL]);; + +let REAL_VARIATION_MINUS_FUNCTION_MONOTONE = prove + (`!f a b c d. + f has_bounded_real_variation_on real_interval[a,b] /\ + real_interval[c,d] SUBSET real_interval[a,b] /\ + ~(real_interval[c,d] = {}) + ==> real_variation (real_interval[c,d]) f - (f d - f c) <= + real_variation (real_interval[a,b]) f - (f b - f a)`, + REWRITE_TAC[has_bounded_real_variation_on; IMAGE_LIFT_REAL_INTERVAL] THEN + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL + [`lift o f o drop`; `lift a`; `lift b`; `lift c`; `lift d`] + VECTOR_VARIATION_MINUS_FUNCTION_MONOTONE) THEN + ASM_SIMP_TAC[GSYM IMAGE_LIFT_REAL_INTERVAL; real_variation; + IMAGE_EQ_EMPTY; IMAGE_SUBSET] THEN + REWRITE_TAC[o_THM; LIFT_DROP; DROP_SUB]);; + +let INCREASING_BOUNDED_REAL_VARIATION = prove + (`!f a b. + (!x y. x IN real_interval[a,b] /\ y IN real_interval[a,b] /\ x <= y + ==> f x <= f y) + ==> f has_bounded_real_variation_on real_interval[a,b]`, + REPEAT STRIP_TAC THEN REWRITE_TAC[has_bounded_real_variation_on] THEN + REWRITE_TAC[IMAGE_LIFT_REAL_INTERVAL] THEN + MATCH_MP_TAC INCREASING_BOUNDED_VARIATION THEN + REWRITE_TAC[IN_INTERVAL_1; GSYM FORALL_DROP; o_THM; LIFT_DROP] THEN + RULE_ASSUM_TAC(REWRITE_RULE[IN_REAL_INTERVAL]) THEN ASM_MESON_TAC[]);; + +let INCREASING_REAL_VARIATION = prove + (`!f a b. + ~(real_interval[a,b] = {}) /\ + (!x y. x IN real_interval[a,b] /\ y IN real_interval[a,b] /\ x <= y + ==> f x <= f y) + ==> real_variation (real_interval[a,b]) f = f b - f a`, + REPEAT STRIP_TAC THEN + REWRITE_TAC[real_variation; IMAGE_LIFT_REAL_INTERVAL] THEN + MP_TAC(ISPECL [`lift o f o drop`; `lift a`; `lift b`] + INCREASING_VECTOR_VARIATION) THEN + REWRITE_TAC[o_THM; LIFT_DROP] THEN DISCH_THEN MATCH_MP_TAC THEN + ASM_REWRITE_TAC[GSYM IMAGE_LIFT_REAL_INTERVAL; IMAGE_EQ_EMPTY] THEN + REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_IMAGE] THEN + REWRITE_TAC[LIFT_DROP] THEN ASM_MESON_TAC[]);; + +let HAS_BOUNDED_REAL_VARIATION_AFFINITY2_EQ = prove + (`!m c f s. + (\x. f (m * x + c)) has_bounded_real_variation_on + + + IMAGE (\x. inv m * x + --(inv m * c)) s <=> + m = &0 \/ f has_bounded_real_variation_on s`, + REPEAT GEN_TAC THEN + MP_TAC(ISPECL [`m:real`; `lift c`; `lift o f o drop`; `IMAGE lift s`] + HAS_BOUNDED_VARIATION_AFFINITY2_EQ) THEN + REWRITE_TAC[o_DEF; has_bounded_real_variation_on; GSYM IMAGE_o; + DROP_ADD; DROP_CMUL; LIFT_ADD; LIFT_CMUL; LIFT_NEG; LIFT_DROP]);; + +let REAL_VARIATION_AFFINITY2 = prove + (`!m c f s. + real_variation (IMAGE (\x. inv m * x + --(inv m * c)) s) + (\x. f (m * x + c)) = + if m = &0 then &0 else real_variation s f`, + REPEAT GEN_TAC THEN + MP_TAC(ISPECL [`m:real`; `lift c`; `lift o f o drop`; `IMAGE lift s`] + VECTOR_VARIATION_AFFINITY2) THEN + REWRITE_TAC[o_DEF; real_variation; GSYM IMAGE_o; + DROP_ADD; DROP_CMUL; LIFT_ADD; LIFT_CMUL; LIFT_NEG; LIFT_DROP]);; + +let HAS_BOUNDED_REAL_VARIATION_AFFINITY_EQ = prove + (`!m c f s. + (\x. f (m * x + c)) has_bounded_real_variation_on s <=> + m = &0 \/ f has_bounded_real_variation_on IMAGE (\x. m * x + c) s`, + REPEAT GEN_TAC THEN + MP_TAC(ISPECL [`m:real`; `lift c`; `lift o f o drop`; `IMAGE lift s`] + HAS_BOUNDED_VARIATION_AFFINITY_EQ) THEN + REWRITE_TAC[o_DEF; has_bounded_real_variation_on; GSYM IMAGE_o; + DROP_ADD; DROP_CMUL; LIFT_ADD; LIFT_CMUL; LIFT_NEG; LIFT_DROP]);; + +let REAL_VARIATION_AFFINITY = prove + (`!m c f s. + real_variation s (\x. f (m * x + c)) = + if m = &0 then &0 else real_variation (IMAGE (\x. m * x + c) s) f`, + REPEAT GEN_TAC THEN + MP_TAC(ISPECL [`m:real`; `lift c`; `lift o f o drop`; `IMAGE lift s`] + VECTOR_VARIATION_AFFINITY) THEN + REWRITE_TAC[o_DEF; real_variation; GSYM IMAGE_o; + DROP_ADD; DROP_CMUL; LIFT_ADD; LIFT_CMUL; LIFT_NEG; LIFT_DROP]);; + +let HAS_BOUNDED_REAL_VARIATION_TRANSLATION2_EQ = prove + (`!a f s. + (\x. f(a + x)) has_bounded_real_variation_on (IMAGE (\x. --a + x) s) <=> + f has_bounded_real_variation_on s`, + REPEAT GEN_TAC THEN + MP_TAC(ISPECL [`lift a`; `lift o f o drop`; `IMAGE lift s`] + HAS_BOUNDED_VARIATION_TRANSLATION2_EQ) THEN + REWRITE_TAC[o_DEF; has_bounded_real_variation_on; GSYM IMAGE_o; + DROP_ADD; LIFT_DROP; LIFT_ADD; LIFT_NEG]);; + +let REAL_VARIATION_TRANSLATION2 = prove + (`!a f s. real_variation (IMAGE (\x. --a + x) s) (\x. f(a + x)) = + real_variation s f`, + REPEAT GEN_TAC THEN + MP_TAC(ISPECL [`lift a`; `lift o f o drop`; `IMAGE lift s`] + VECTOR_VARIATION_TRANSLATION2) THEN + REWRITE_TAC[o_DEF; real_variation; GSYM IMAGE_o; + DROP_ADD; LIFT_DROP; LIFT_ADD; LIFT_NEG]);; + +let HAS_BOUNDED_REAL_VARIATION_TRANSLATION_EQ = prove + (`!a f s. (\x. f(a + x)) has_bounded_real_variation_on s <=> + f has_bounded_real_variation_on (IMAGE (\x. a + x) s)`, + REPEAT GEN_TAC THEN + MP_TAC(ISPECL [`lift a`; `lift o f o drop`; `IMAGE lift s`] + HAS_BOUNDED_VARIATION_TRANSLATION_EQ) THEN + REWRITE_TAC[o_DEF; has_bounded_real_variation_on; GSYM IMAGE_o; + DROP_ADD; LIFT_DROP; LIFT_ADD; LIFT_NEG]);; + +let REAL_VARIATION_TRANSLATION = prove + (`!a f s. real_variation s (\x. f(a + x)) = + real_variation (IMAGE (\x. a + x) s) f`, + REPEAT GEN_TAC THEN + MP_TAC(ISPECL [`lift a`; `lift o f o drop`; `IMAGE lift s`] + VECTOR_VARIATION_TRANSLATION) THEN + REWRITE_TAC[o_DEF; real_variation; GSYM IMAGE_o; + DROP_ADD; LIFT_DROP; LIFT_ADD; LIFT_NEG]);; + +let HAS_BOUNDED_REAL_VARIATION_TRANSLATION_EQ_INTERVAL = prove + (`!a f u v. + (\x. f(a + x)) has_bounded_real_variation_on real_interval[u,v] <=> + f has_bounded_real_variation_on real_interval[a+u,a+v]`, + REWRITE_TAC[REAL_INTERVAL_TRANSLATION; + HAS_BOUNDED_REAL_VARIATION_TRANSLATION_EQ]);; + +let REAL_VARIATION_TRANSLATION_INTERVAL = prove + (`!a f u v. + real_variation (real_interval[u,v]) (\x. f(a + x)) = + real_variation (real_interval[a+u,a+v]) f`, + REWRITE_TAC[REAL_INTERVAL_TRANSLATION; + REAL_VARIATION_TRANSLATION]);; + +let HAS_BOUNDED_REAL_VARIATION_TRANSLATION = prove + (`!f s a. f has_bounded_real_variation_on s + ==> (\x. f(a + x)) has_bounded_real_variation_on + (IMAGE (\x. --a + x) s)`, + REWRITE_TAC[HAS_BOUNDED_REAL_VARIATION_TRANSLATION2_EQ]);; + +let HAS_BOUNDED_REAL_VARIATION_REFLECT2_EQ = prove + (`!f s. (\x. f(--x)) has_bounded_real_variation_on (IMAGE (--) s) <=> + f has_bounded_real_variation_on s`, + REPEAT GEN_TAC THEN + MP_TAC(ISPECL [`lift o f o drop`; `IMAGE lift s`] + HAS_BOUNDED_VARIATION_REFLECT2_EQ) THEN + REWRITE_TAC[o_DEF; has_bounded_real_variation_on; GSYM IMAGE_o; + DROP_NEG; LIFT_DROP; LIFT_NEG]);; + +let REAL_VARIATION_REFLECT2 = prove + (`!f s. real_variation (IMAGE (--) s) (\x. f(--x)) = + real_variation s f`, + REPEAT GEN_TAC THEN + MP_TAC(ISPECL [`lift o f o drop`; `IMAGE lift s`] + VECTOR_VARIATION_REFLECT2) THEN + REWRITE_TAC[o_DEF; real_variation; GSYM IMAGE_o; + DROP_NEG; LIFT_DROP; LIFT_NEG]);; + +let HAS_BOUNDED_REAL_VARIATION_REFLECT_EQ = prove + (`!f s. (\x. f(--x)) has_bounded_real_variation_on s <=> + f has_bounded_real_variation_on (IMAGE (--) s)`, + REPEAT GEN_TAC THEN + MP_TAC(ISPECL [`lift o f o drop`; `IMAGE lift s`] + HAS_BOUNDED_VARIATION_REFLECT_EQ) THEN + REWRITE_TAC[o_DEF; has_bounded_real_variation_on; GSYM IMAGE_o; + DROP_NEG; LIFT_DROP; LIFT_NEG]);; + +let REAL_VARIATION_REFLECT = prove + (`!f s. real_variation s (\x. f(--x)) = + real_variation (IMAGE (--) s) f`, + REPEAT GEN_TAC THEN + MP_TAC(ISPECL [`lift o f o drop`; `IMAGE lift s`] + VECTOR_VARIATION_REFLECT) THEN + REWRITE_TAC[o_DEF; real_variation; GSYM IMAGE_o; + DROP_NEG; LIFT_DROP; LIFT_NEG]);; + +let HAS_BOUNDED_REAL_VARIATION_REFLECT_EQ_INTERVAL = prove + (`!f u v. (\x. f(--x)) has_bounded_real_variation_on real_interval[u,v] <=> + f has_bounded_real_variation_on real_interval[--v,--u]`, + REWRITE_TAC[GSYM REFLECT_REAL_INTERVAL; + HAS_BOUNDED_REAL_VARIATION_REFLECT_EQ]);; + +let REAL_VARIATION_REFLECT_INTERVAL = prove + (`!f u v. real_variation (real_interval[u,v]) (\x. f(--x)) = + real_variation (real_interval[--v,--u]) f`, + REWRITE_TAC[GSYM REFLECT_REAL_INTERVAL; REAL_VARIATION_REFLECT]);; + +let HAS_BOUNDED_REAL_VARIATION_DARBOUX = prove + (`!f a b. + f has_bounded_real_variation_on real_interval[a,b] <=> + ?g h. (!x y. x IN real_interval[a,b] /\ y IN real_interval[a,b] /\ x <= y + ==> g x <= g y) /\ + (!x y. x IN real_interval[a,b] /\ y IN real_interval[a,b] /\ x <= y + ==> h x <= h y) /\ + (!x. f x = g x - h x)`, + REPEAT GEN_TAC THEN REWRITE_TAC[has_bounded_real_variation_on] THEN + REWRITE_TAC[HAS_BOUNDED_VARIATION_DARBOUX; IMAGE_LIFT_REAL_INTERVAL] THEN + REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_IMAGE; + GSYM IMAGE_LIFT_REAL_INTERVAL; LIFT_DROP] THEN + REWRITE_TAC[RIGHT_IMP_FORALL_THM; IMP_IMP; GSYM CONJ_ASSOC] THEN + EQ_TAC THEN REWRITE_TAC[LEFT_IMP_EXISTS_THM; o_THM] THENL + [MAP_EVERY X_GEN_TAC [`g:real^1->real^1`; `h:real^1->real^1`] THEN + STRIP_TAC THEN + MAP_EVERY EXISTS_TAC [`drop o g o lift`; `drop o h o lift`] THEN + ASM_REWRITE_TAC[o_THM] THEN REWRITE_TAC[GSYM LIFT_EQ; FORALL_DROP] THEN + ASM_REWRITE_TAC[LIFT_DROP; LIFT_SUB]; + MAP_EVERY X_GEN_TAC [`g:real->real`; `h:real->real`] THEN + STRIP_TAC THEN + MAP_EVERY EXISTS_TAC [`lift o g o drop`; `lift o h o drop`] THEN + ASM_REWRITE_TAC[o_THM; LIFT_DROP] THEN REWRITE_TAC[LIFT_SUB]]);; + +let HAS_BOUNDED_REAL_VARIATION_DARBOUX_STRICT = prove + (`!f a b. + f has_bounded_real_variation_on real_interval[a,b] <=> + ?g h. (!x y. x IN real_interval[a,b] /\ y IN real_interval[a,b] /\ x < y + ==> g x < g y) /\ + (!x y. x IN real_interval[a,b] /\ y IN real_interval[a,b] /\ x < y + ==> h x < h y) /\ + (!x. f x = g x - h x)`, + REPEAT GEN_TAC THEN REWRITE_TAC[has_bounded_real_variation_on] THEN + REWRITE_TAC[HAS_BOUNDED_VARIATION_DARBOUX_STRICT; + IMAGE_LIFT_REAL_INTERVAL] THEN + REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_IMAGE; + GSYM IMAGE_LIFT_REAL_INTERVAL; LIFT_DROP] THEN + REWRITE_TAC[RIGHT_IMP_FORALL_THM; IMP_IMP; GSYM CONJ_ASSOC] THEN + EQ_TAC THEN REWRITE_TAC[LEFT_IMP_EXISTS_THM; o_THM] THENL + [MAP_EVERY X_GEN_TAC [`g:real^1->real^1`; `h:real^1->real^1`] THEN + STRIP_TAC THEN + MAP_EVERY EXISTS_TAC [`drop o g o lift`; `drop o h o lift`] THEN + ASM_REWRITE_TAC[o_THM] THEN REWRITE_TAC[GSYM LIFT_EQ; FORALL_DROP] THEN + ASM_REWRITE_TAC[LIFT_DROP; LIFT_SUB]; + MAP_EVERY X_GEN_TAC [`g:real->real`; `h:real->real`] THEN + STRIP_TAC THEN + MAP_EVERY EXISTS_TAC [`lift o g o drop`; `lift o h o drop`] THEN + ASM_REWRITE_TAC[o_THM; LIFT_DROP] THEN REWRITE_TAC[LIFT_SUB]]);; + +let INCREASING_LEFT_LIMIT = prove + (`!f a b c. + (!x y. x IN real_interval[a,b] /\ y IN real_interval[a,b] /\ x <= y + ==> f x <= f y) /\ + c IN real_interval[a,b] + ==> ?l. (f ---> l) (atreal c within real_interval[a,c])`, + REPEAT STRIP_TAC THEN REWRITE_TAC[TENDSTO_REAL; GSYM EXISTS_LIFT] THEN + REWRITE_TAC[LIM_WITHINREAL_WITHIN; IMAGE_LIFT_REAL_INTERVAL] THEN + MATCH_MP_TAC INCREASING_LEFT_LIMIT_1 THEN EXISTS_TAC `lift b` THEN + SIMP_TAC[GSYM IMAGE_LIFT_REAL_INTERVAL; IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN + ASM_SIMP_TAC[FORALL_IN_IMAGE; o_THM; LIFT_DROP; FUN_IN_IMAGE]);; + +let DECREASING_LEFT_LIMIT = prove + (`!f a b c. + (!x y. x IN real_interval[a,b] /\ y IN real_interval[a,b] /\ x <= y + ==> f y <= f x) /\ + c IN real_interval[a,b] + ==> ?l. (f ---> l) (atreal c within real_interval[a,c])`, + REPEAT STRIP_TAC THEN REWRITE_TAC[TENDSTO_REAL; GSYM EXISTS_LIFT] THEN + REWRITE_TAC[LIM_WITHINREAL_WITHIN; IMAGE_LIFT_REAL_INTERVAL] THEN + MATCH_MP_TAC DECREASING_LEFT_LIMIT_1 THEN EXISTS_TAC `lift b` THEN + SIMP_TAC[GSYM IMAGE_LIFT_REAL_INTERVAL; IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN + ASM_SIMP_TAC[FORALL_IN_IMAGE; o_THM; LIFT_DROP; FUN_IN_IMAGE]);; + +let INCREASING_RIGHT_LIMIT = prove + (`!f a b c. + (!x y. x IN real_interval[a,b] /\ y IN real_interval[a,b] /\ x <= y + ==> f x <= f y) /\ + c IN real_interval[a,b] + ==> ?l. (f ---> l) (atreal c within real_interval[c,b])`, + REPEAT STRIP_TAC THEN REWRITE_TAC[TENDSTO_REAL; GSYM EXISTS_LIFT] THEN + REWRITE_TAC[LIM_WITHINREAL_WITHIN; IMAGE_LIFT_REAL_INTERVAL] THEN + MATCH_MP_TAC INCREASING_RIGHT_LIMIT_1 THEN EXISTS_TAC `lift a` THEN + SIMP_TAC[GSYM IMAGE_LIFT_REAL_INTERVAL; IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN + ASM_SIMP_TAC[FORALL_IN_IMAGE; o_THM; LIFT_DROP; FUN_IN_IMAGE]);; + +let DECREASING_RIGHT_LIMIT = prove + (`!f a b c. + (!x y. x IN real_interval[a,b] /\ y IN real_interval[a,b] /\ x <= y + ==> f y <= f x) /\ + c IN real_interval[a,b] + ==> ?l. (f ---> l) (atreal c within real_interval[c,b])`, + REPEAT STRIP_TAC THEN REWRITE_TAC[TENDSTO_REAL; GSYM EXISTS_LIFT] THEN + REWRITE_TAC[LIM_WITHINREAL_WITHIN; IMAGE_LIFT_REAL_INTERVAL] THEN + MATCH_MP_TAC DECREASING_RIGHT_LIMIT_1 THEN EXISTS_TAC `lift a` THEN + SIMP_TAC[GSYM IMAGE_LIFT_REAL_INTERVAL; IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN + ASM_SIMP_TAC[FORALL_IN_IMAGE; o_THM; LIFT_DROP; FUN_IN_IMAGE]);; + +let HAS_BOUNDED_REAL_VARIATION_LEFT_LIMIT = prove + (`!f a b c. + f has_bounded_real_variation_on real_interval[a,b] /\ + c IN real_interval[a,b] + ==> ?l. (f ---> l) (atreal c within real_interval[a,c])`, + REWRITE_TAC[has_bounded_real_variation_on] THEN REPEAT STRIP_TAC THEN + REWRITE_TAC[TENDSTO_REAL; GSYM EXISTS_LIFT] THEN + REWRITE_TAC[LIM_WITHINREAL_WITHIN; IMAGE_LIFT_REAL_INTERVAL] THEN + MATCH_MP_TAC HAS_BOUNDED_VECTOR_VARIATION_LEFT_LIMIT THEN + EXISTS_TAC `lift b` THEN + ASM_SIMP_TAC[GSYM IMAGE_LIFT_REAL_INTERVAL; GSYM o_ASSOC; FUN_IN_IMAGE]);; + +let HAS_BOUNDED_REAL_VARIATION_RIGHT_LIMIT = prove + (`!f a b c. + f has_bounded_real_variation_on real_interval[a,b] /\ + c IN real_interval[a,b] + ==> ?l. (f ---> l) (atreal c within real_interval[c,b])`, + REWRITE_TAC[has_bounded_real_variation_on] THEN REPEAT STRIP_TAC THEN + REWRITE_TAC[TENDSTO_REAL; GSYM EXISTS_LIFT] THEN + REWRITE_TAC[LIM_WITHINREAL_WITHIN; IMAGE_LIFT_REAL_INTERVAL] THEN + MATCH_MP_TAC HAS_BOUNDED_VECTOR_VARIATION_RIGHT_LIMIT THEN + EXISTS_TAC `lift a` THEN + ASM_SIMP_TAC[GSYM IMAGE_LIFT_REAL_INTERVAL; GSYM o_ASSOC; FUN_IN_IMAGE]);; + +let REAL_VARIATION_CONTINUOUS_LEFT = prove + (`!f a b c. + f has_bounded_real_variation_on real_interval[a,b] /\ + c IN real_interval[a,b] + ==> ((\x. real_variation(real_interval[a,x]) f) + real_continuous (atreal c within real_interval[a,c]) <=> + f real_continuous (atreal c within real_interval[a,c]))`, + REWRITE_TAC[has_bounded_real_variation_on; real_variation] THEN + REWRITE_TAC[IMAGE_LIFT_REAL_INTERVAL; + REAL_CONTINUOUS_CONTINUOUS_WITHINREAL] THEN + REWRITE_TAC[o_DEF; LIFT_DROP] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC VECTOR_VARIATION_CONTINUOUS_LEFT THEN + EXISTS_TAC `lift b` THEN ASM_REWRITE_TAC[] THEN + ASM_SIMP_TAC[GSYM IMAGE_LIFT_REAL_INTERVAL; FUN_IN_IMAGE]);; + +let REAL_VARIATION_CONTINUOUS_RIGHT = prove + (`!f a b c. + f has_bounded_real_variation_on real_interval[a,b] /\ + c IN real_interval[a,b] + ==> ((\x. real_variation(real_interval[a,x]) f) + real_continuous (atreal c within real_interval[c,b]) <=> + f real_continuous (atreal c within real_interval[c,b]))`, + REWRITE_TAC[has_bounded_real_variation_on; real_variation] THEN + REWRITE_TAC[IMAGE_LIFT_REAL_INTERVAL; + REAL_CONTINUOUS_CONTINUOUS_WITHINREAL] THEN + REWRITE_TAC[o_DEF; LIFT_DROP] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC VECTOR_VARIATION_CONTINUOUS_RIGHT THEN + ASM_REWRITE_TAC[] THEN + ASM_SIMP_TAC[GSYM IMAGE_LIFT_REAL_INTERVAL; FUN_IN_IMAGE]);; + +let REAL_VARIATION_CONTINUOUS = prove + (`!f a b c. + f has_bounded_real_variation_on real_interval[a,b] /\ + c IN real_interval[a,b] + ==> ((\x. real_variation(real_interval[a,x]) f) + real_continuous (atreal c within real_interval[a,b]) <=> + f real_continuous (atreal c within real_interval[a,b]))`, + REWRITE_TAC[has_bounded_real_variation_on; real_variation] THEN + REWRITE_TAC[IMAGE_LIFT_REAL_INTERVAL; + REAL_CONTINUOUS_CONTINUOUS_WITHINREAL] THEN + REWRITE_TAC[o_DEF; LIFT_DROP] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC VECTOR_VARIATION_CONTINUOUS THEN + ASM_REWRITE_TAC[] THEN + ASM_SIMP_TAC[GSYM IMAGE_LIFT_REAL_INTERVAL; FUN_IN_IMAGE]);; + +let HAS_BOUNDED_REAL_VARIATION_DARBOUX_STRONG = prove + (`!f a b. + f has_bounded_real_variation_on real_interval[a,b] + ==> ?g h. + (!x. f x = g x - h x) /\ + (!x y. x IN real_interval[a,b] /\ y IN real_interval[a,b] /\ x <= y + ==> g x <= g y) /\ + (!x y. x IN real_interval[a,b] /\ y IN real_interval[a,b] /\ x <= y + ==> h x <= h y) /\ + (!x y. x IN real_interval[a,b] /\ y IN real_interval[a,b] /\ x < y + ==> g x < g y) /\ + (!x y. x IN real_interval[a,b] /\ y IN real_interval[a,b] /\ x < y + ==> h x < h y) /\ + (!x. x IN real_interval[a,b] /\ + f real_continuous (atreal x within real_interval[a,x]) + ==> g real_continuous (atreal x within real_interval[a,x]) /\ + h real_continuous (atreal x within real_interval[a,x])) /\ + (!x. x IN real_interval[a,b] /\ + f real_continuous (atreal x within real_interval[x,b]) + ==> g real_continuous (atreal x within real_interval[x,b]) /\ + h real_continuous (atreal x within real_interval[x,b])) /\ + (!x. x IN real_interval[a,b] /\ + f real_continuous (atreal x within real_interval[a,b]) + ==> g real_continuous (atreal x within real_interval[a,b]) /\ + h real_continuous (atreal x within real_interval[a,b]))`, + REPEAT STRIP_TAC THEN + MAP_EVERY EXISTS_TAC + [`\x. x + real_variation (real_interval[a,x]) f`; + `\x. x + real_variation (real_interval[a,x]) f - f x`] THEN + REWRITE_TAC[REAL_ARITH `(x + l) - (x + l - f):real = f`] THEN + REPEAT STRIP_TAC THENL + [MATCH_MP_TAC REAL_LE_ADD2 THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC REAL_VARIATION_MONOTONE; + MATCH_MP_TAC REAL_LE_ADD2 THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC(REAL_ARITH + `!x. a - (b - x) <= c - (d - x) ==> a - b <= c - d`) THEN + EXISTS_TAC `(f:real->real) a` THEN + MATCH_MP_TAC REAL_VARIATION_MINUS_FUNCTION_MONOTONE; + MATCH_MP_TAC REAL_LTE_ADD2 THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC REAL_VARIATION_MONOTONE; + MATCH_MP_TAC REAL_LTE_ADD2 THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC(REAL_ARITH + `!x. a - (b - x) <= c - (d - x) ==> a - b <= c - d`) THEN + EXISTS_TAC `(f:real->real) a` THEN + MATCH_MP_TAC REAL_VARIATION_MINUS_FUNCTION_MONOTONE; + MATCH_MP_TAC REAL_CONTINUOUS_ADD THEN + REWRITE_TAC[REAL_CONTINUOUS_WITHIN_ID] THEN + MP_TAC(ISPECL [`f:real->real`; `a:real`; `b:real`; `x:real`] + REAL_VARIATION_CONTINUOUS_LEFT) THEN + ASM_REWRITE_TAC[]; + MATCH_MP_TAC REAL_CONTINUOUS_ADD THEN + REWRITE_TAC[REAL_CONTINUOUS_WITHIN_ID] THEN + MATCH_MP_TAC REAL_CONTINUOUS_SUB THEN ASM_REWRITE_TAC[] THEN + MP_TAC(ISPECL [`f:real->real`; `a:real`; `b:real`; `x:real`] + REAL_VARIATION_CONTINUOUS_LEFT) THEN + ASM_REWRITE_TAC[]; + MATCH_MP_TAC REAL_CONTINUOUS_ADD THEN + REWRITE_TAC[REAL_CONTINUOUS_WITHIN_ID] THEN + MP_TAC(ISPECL [`f:real->real`; `a:real`; `b:real`; `x:real`] + REAL_VARIATION_CONTINUOUS_RIGHT) THEN + ASM_REWRITE_TAC[]; + MATCH_MP_TAC REAL_CONTINUOUS_ADD THEN + REWRITE_TAC[REAL_CONTINUOUS_WITHIN_ID] THEN + MATCH_MP_TAC REAL_CONTINUOUS_SUB THEN ASM_REWRITE_TAC[] THEN + MP_TAC(ISPECL [`f:real->real`; `a:real`; `b:real`; `x:real`] + REAL_VARIATION_CONTINUOUS_RIGHT) THEN + ASM_REWRITE_TAC[]; + MATCH_MP_TAC REAL_CONTINUOUS_ADD THEN + REWRITE_TAC[REAL_CONTINUOUS_WITHIN_ID] THEN + MP_TAC(ISPECL [`f:real->real`; `a:real`; `b:real`; `x:real`] + REAL_VARIATION_CONTINUOUS) THEN + ASM_REWRITE_TAC[]; + MATCH_MP_TAC REAL_CONTINUOUS_ADD THEN + REWRITE_TAC[REAL_CONTINUOUS_WITHIN_ID] THEN + MATCH_MP_TAC REAL_CONTINUOUS_SUB THEN ASM_REWRITE_TAC[] THEN + MP_TAC(ISPECL [`f:real->real`; `a:real`; `b:real`; `x:real`] + REAL_VARIATION_CONTINUOUS) THEN + ASM_REWRITE_TAC[]] THEN + (CONJ_TAC THENL + [FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + HAS_BOUNDED_REAL_VARIATION_ON_SUBSET)); + ALL_TAC] THEN + RULE_ASSUM_TAC(REWRITE_RULE[IN_REAL_INTERVAL]) THEN + REWRITE_TAC[SUBSET_REAL_INTERVAL; REAL_INTERVAL_EQ_EMPTY] THEN + ASM_REAL_ARITH_TAC));; + +let HAS_BOUNDED_REAL_VARIATION_COUNTABLE_DISCONTINUITIES = prove + (`!f a b. f has_bounded_real_variation_on real_interval[a,b] + ==> COUNTABLE {x | x IN real_interval[a,b] /\ + ~(f real_continuous atreal x)}`, + REPEAT GEN_TAC THEN REWRITE_TAC[has_bounded_real_variation_on] THEN + REWRITE_TAC[REAL_CONTINUOUS_CONTINUOUS_ATREAL] THEN + REWRITE_TAC[IMAGE_LIFT_REAL_INTERVAL] THEN DISCH_THEN(MP_TAC o + MATCH_MP HAS_BOUNDED_VARIATION_COUNTABLE_DISCONTINUITIES) THEN + DISCH_THEN(MP_TAC o ISPEC `drop` o MATCH_MP COUNTABLE_IMAGE) THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] COUNTABLE_SUBSET) THEN + REWRITE_TAC[SUBSET; IN_IMAGE; EXISTS_LIFT; LIFT_DROP; UNWIND_THM1] THEN + REWRITE_TAC[GSYM IMAGE_LIFT_REAL_INTERVAL; IN_ELIM_THM] THEN + REWRITE_TAC[EXISTS_IN_IMAGE; GSYM CONJ_ASSOC; EXISTS_DROP; LIFT_DROP] THEN + MESON_TAC[LIFT_DROP]);; + +(* ------------------------------------------------------------------------- *) +(* Lebesgue density theorem. This isn't about R specifically, but it's most *) +(* naturally stated as a real limit so it ends up here in this file. *) +(* ------------------------------------------------------------------------- *) + +let LEBESGUE_DENSITY_THEOREM = prove + (`!s:real^N->bool. + lebesgue_measurable s + ==> ?k. negligible k /\ + !x. ~(x IN k) + ==> ((\e. measure(s INTER cball(x,e)) / measure(cball(x,e))) + ---> (if x IN s then &1 else &0)) + (atreal(&0) within {e | &0 < e})`, + REPEAT STRIP_TAC THEN MP_TAC (ISPEC + `indicator(s:real^N->bool)` ABSOLUTELY_INTEGRABLE_LEBESGUE_POINTS) THEN + ANTS_TAC THENL + [REPEAT GEN_TAC THEN REWRITE_TAC[indicator] THEN + MATCH_MP_TAC NONNEGATIVE_ABSOLUTELY_INTEGRABLE THEN CONJ_TAC THENL + [MESON_TAC[VEC_COMPONENT; REAL_POS]; ALL_TAC] THEN + REWRITE_TAC[INTEGRABLE_RESTRICT_INTER] THEN + ONCE_REWRITE_TAC[GSYM INTEGRABLE_RESTRICT_UNIV] THEN + REWRITE_TAC[GSYM MEASURABLE_INTEGRABLE] THEN + MATCH_MP_TAC MEASURABLE_LEGESGUE_MEASURABLE_INTER_MEASURABLE THEN + ASM_REWRITE_TAC[MEASURABLE_INTERVAL]; + ALL_TAC] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `k:real^N->bool` THEN + STRIP_TAC THEN ASM_REWRITE_TAC[REALLIM_WITHINREAL; IN_ELIM_THM] THEN + X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN X_GEN_TAC `e:real` THEN + STRIP_TAC THEN FIRST_X_ASSUM(MP_TAC o SPECL + [`x:real^N`; `e / &(dimindex(:N)) pow dimindex(:N)`]) THEN + ASM_SIMP_TAC[REAL_LT_DIV; REAL_POW_LT; + REAL_OF_NUM_LT; LE_1; DIMINDEX_GE_1] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `d:real` THEN STRIP_TAC THEN + ASM_REWRITE_TAC[REAL_SUB_RZERO] THEN X_GEN_TAC `h:real` THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `h:real`) THEN + ANTS_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN + SIMP_TAC[REAL_LT_RDIV_EQ; REAL_POW_LT; + REAL_OF_NUM_LT; LE_1; DIMINDEX_GE_1] THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] REAL_LET_TRANS) THEN + ASM_SIMP_TAC[MEASURE_CBALL_POS; REAL_FIELD + `&0 < y ==> x / y - a = inv(y) * (x - a * y)`] THEN + REWRITE_TAC[REAL_ABS_MUL; NORM_MUL] THEN ONCE_REWRITE_TAC + [REAL_ARITH `x <= (abs a * b) * c <=> x <= (abs(a) * c) * b`] THEN + MATCH_MP_TAC REAL_LE_MUL2 THEN REWRITE_TAC[REAL_ABS_POS] THEN + CONJ_TAC THENL + [SIMP_TAC[GSYM REAL_LE_LDIV_EQ; REAL_POW_LT; + REAL_OF_NUM_LT; LE_1; DIMINDEX_GE_1] THEN + REWRITE_TAC[REAL_ABS_INV; real_div; GSYM REAL_INV_MUL] THEN + MATCH_MP_TAC REAL_LE_INV2 THEN CONJ_TAC THENL + [REWRITE_TAC[GSYM REAL_ABS_NZ; CONTENT_EQ_0] THEN + REWRITE_TAC[VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT; VEC_COMPONENT; + VECTOR_SUB_COMPONENT] THEN ASM_REAL_ARITH_TAC; + SIMP_TAC[real_abs; CONTENT_POS_LE; MEASURE_POS_LE; MEASURABLE_CBALL] THEN + MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `measure(interval[x - h / &(dimindex(:N)) % vec 1:real^N, + x + h / &(dimindex(:N)) % vec 1]) * + &(dimindex (:N)) pow dimindex (:N)` THEN + CONJ_TAC THENL + [REWRITE_TAC[MEASURE_INTERVAL; CONTENT_CLOSED_INTERVAL_CASES] THEN + REWRITE_TAC[VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT; VEC_COMPONENT; + VECTOR_SUB_COMPONENT; REAL_MUL_RID] THEN + ASM_SIMP_TAC[REAL_ARITH `x - h <= x + h <=> &0 <= h`; + REAL_LE_DIV; REAL_POS; REAL_LT_IMP_LE] THEN + REWRITE_TAC[REAL_ARITH `(x + h) - (x - h) = &2 * h`; + PRODUCT_CONST_NUMSEG_1; REAL_POW_DIV; REAL_POW_MUL] THEN + MATCH_MP_TAC(REAL_ARITH `x = y ==> y <= x`) THEN + REWRITE_TAC[GSYM REAL_MUL_ASSOC] THEN AP_TERM_TAC THEN + MATCH_MP_TAC REAL_DIV_RMUL THEN + REWRITE_TAC[REAL_POW_EQ_0; REAL_OF_NUM_EQ; DIMINDEX_NONZERO]; + MATCH_MP_TAC REAL_LE_RMUL THEN SIMP_TAC[REAL_POS; REAL_POW_LE] THEN + MATCH_MP_TAC MEASURE_SUBSET THEN + REWRITE_TAC[MEASURABLE_INTERVAL; MEASURABLE_CBALL] THEN + REWRITE_TAC[SUBSET; IN_INTERVAL; IN_CBALL] THEN + X_GEN_TAC `y:real^N` THEN + REWRITE_TAC[VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT; VEC_COMPONENT; + VECTOR_SUB_COMPONENT; REAL_MUL_RID; REAL_ARITH + `x - h <= y /\ y <= x + h <=> abs(x - y) <= h`] THEN + STRIP_TAC THEN REWRITE_TAC[dist] THEN MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `sum(1..dimindex(:N)) (\i. abs((x - y:real^N)$i))` THEN + REWRITE_TAC[NORM_LE_L1] THEN MATCH_MP_TAC SUM_BOUND_GEN THEN + ASM_REWRITE_TAC[CARD_NUMSEG_1; VECTOR_SUB_COMPONENT; IN_NUMSEG] THEN + REWRITE_TAC[FINITE_NUMSEG; NUMSEG_EMPTY; NOT_LT; DIMINDEX_GE_1]]]; + REWRITE_TAC[NORM_REAL; GSYM drop] THEN + MATCH_MP_TAC(REAL_ARITH `x <= y ==> x <= abs y`) THEN + MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `drop(integral (cball(x:real^N,h)) + (\t. lift(norm(indicator s t - indicator s x))))` THEN + CONJ_TAC THENL + [ASM_SIMP_TAC[MEASURE_INTEGRAL; MEASURABLE_CBALL; + MEASURABLE_LEGESGUE_MEASURABLE_INTER_MEASURABLE] THEN + REWRITE_TAC[GSYM INTEGRAL_RESTRICT_INTER; GSYM DROP_CMUL] THEN + SIMP_TAC[GSYM INTEGRAL_CMUL; GSYM MEASURABLE; MEASURABLE_CBALL] THEN + REWRITE_TAC[GSYM DROP_SUB; COND_RATOR; COND_RAND] THEN + REWRITE_TAC[VECTOR_MUL_LZERO; VECTOR_MUL_LID] THEN + ASM_SIMP_TAC[GSYM INTEGRAL_SUB; INTEGRABLE_RESTRICT_INTER; + GSYM MEASURABLE; MEASURABLE_CBALL; INTEGRABLE_ON_CONST; + MEASURABLE_LEGESGUE_MEASURABLE_INTER_MEASURABLE] THEN + REWRITE_TAC[GSYM NORM_REAL; drop] THEN REWRITE_TAC[GSYM drop] THEN + MATCH_MP_TAC INTEGRAL_NORM_BOUND_INTEGRAL THEN + ASM_SIMP_TAC[INTEGRABLE_SUB; INTEGRABLE_RESTRICT_INTER; + GSYM MEASURABLE; MEASURABLE_CBALL; INTEGRABLE_ON_CONST; + MEASURABLE_LEGESGUE_MEASURABLE_INTER_MEASURABLE] THEN + CONJ_TAC THENL + [ALL_TAC; + GEN_TAC THEN DISCH_TAC THEN + REPEAT(COND_CASES_TAC THEN ASM_REWRITE_TAC[indicator]) THEN + REWRITE_TAC[NORM_REAL; GSYM drop; DROP_SUB; LIFT_DROP; DROP_VEC] THEN + REAL_ARITH_TAC]; + REWRITE_TAC[NORM_REAL; GSYM drop; LIFT_DROP] THEN + MATCH_MP_TAC INTEGRAL_SUBSET_DROP_LE THEN + REPEAT CONJ_TAC THENL + [REWRITE_TAC[SUBSET; IN_CBALL; IN_INTERVAL] THEN + REWRITE_TAC[VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT; VEC_COMPONENT; + VECTOR_SUB_COMPONENT; REAL_MUL_RID; REAL_ARITH + `x - h <= y /\ y <= x + h <=> abs(x - y) <= h`] THEN + REWRITE_TAC[dist; GSYM VECTOR_SUB_COMPONENT] THEN + MESON_TAC[REAL_LE_TRANS; COMPONENT_LE_NORM]; + ALL_TAC; + ALL_TAC; + REWRITE_TAC[LIFT_DROP; REAL_ABS_POS]]]] THEN + REWRITE_TAC[GSYM NORM_REAL; drop] THEN + MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_IMP_INTEGRABLE THEN + MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_NORM THEN + MATCH_MP_TAC(INST_TYPE [`:1`,`:P`] + ABSOLUTELY_INTEGRABLE_INTEGRABLE_BOUND) THEN + EXISTS_TAC `(\x. vec 1):real^N->real^1` THEN + + REWRITE_TAC[DROP_VEC; GSYM MEASURABLE; MEASURABLE_INTERVAL; + MEASURABLE_CBALL] THEN + (CONJ_TAC THENL + [GEN_TAC THEN DISCH_TAC THEN REWRITE_TAC[indicator] THEN + REPEAT(COND_CASES_TAC THEN + ASM_REWRITE_TAC[NORM_REAL; GSYM drop; DROP_SUB; DROP_VEC]) THEN + CONV_TAC REAL_RAT_REDUCE_CONV; + ALL_TAC]) THEN + MATCH_MP_TAC INTEGRABLE_SUB THEN + REWRITE_TAC[INTEGRABLE_ON_CONST; MEASURABLE_INTERVAL; MEASURABLE_CBALL] THEN + REWRITE_TAC[indicator; INTEGRABLE_RESTRICT_INTER] THEN + REWRITE_TAC[GSYM MEASURABLE] THEN + ASM_SIMP_TAC[MEASURABLE_CBALL; MEASURABLE_INTERVAL; + MEASURABLE_LEGESGUE_MEASURABLE_INTER_MEASURABLE]);; + +(* ------------------------------------------------------------------------- *) +(* Injective map into R is also an open map w.r.t. the universe, and this *) +(* is actually an implication in both directions for an interval. Compare *) +(* the local form in INJECTIVE_INTO_1D_IMP_OPEN_MAP (not a bi-implication). *) +(* ------------------------------------------------------------------------- *) + +let INJECTIVE_EQ_1D_OPEN_MAP_UNIV = prove + (`!f:real^1->real^1 s. + f continuous_on s /\ is_interval s + ==> ((!x y. x IN s /\ y IN s /\ f x = f y ==> x = y) <=> + (!t. open t /\ t SUBSET s ==> open(IMAGE f t)))`, + REPEAT STRIP_TAC THEN EQ_TAC THEN REPEAT STRIP_TAC THENL + [ONCE_REWRITE_TAC[OPEN_SUBOPEN] THEN REWRITE_TAC[FORALL_IN_IMAGE] THEN + X_GEN_TAC `x:real^1` THEN DISCH_TAC THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [OPEN_CONTAINS_CBALL]) THEN + DISCH_THEN(MP_TAC o SPEC `x:real^1`) THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[BALL_1] THEN + DISCH_THEN(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `IMAGE (f:real^1->real^1) + (segment (x - lift d,x + lift d))` THEN + MP_TAC(ISPECL + [`f:real^1->real^1`; `x - lift d`; `x + lift d`] + CONTINUOUS_INJECTIVE_IMAGE_OPEN_SEGMENT_1) THEN + REWRITE_TAC[SEGMENT_1; DROP_ADD; DROP_SUB; LIFT_DROP] THEN + ASM_CASES_TAC `drop x - d <= drop x + d` THENL + [ASM_REWRITE_TAC[] THEN REWRITE_TAC[GSYM SEGMENT_1]; + ASM_REAL_ARITH_TAC] THEN + ANTS_TAC THENL [ASM_MESON_TAC[SUBSET; CONTINUOUS_ON_SUBSET]; ALL_TAC] THEN + REPEAT STRIP_TAC THENL + [ASM_REWRITE_TAC[OPEN_SEGMENT_1]; + MATCH_MP_TAC FUN_IN_IMAGE THEN REWRITE_TAC[IN_INTERVAL_1] THEN + REWRITE_TAC[DROP_ADD; DROP_SUB; LIFT_DROP] THEN ASM_REAL_ARITH_TAC; + MATCH_MP_TAC IMAGE_SUBSET THEN + ASM_MESON_TAC[INTERVAL_OPEN_SUBSET_CLOSED; SUBSET_TRANS]]; + MATCH_MP_TAC(TAUT `(~p ==> F) ==> p`) THEN DISCH_TAC THEN + MP_TAC(ISPECL [`f:real^1->real^1`; `x:real^1`; `y:real^1`] + CONTINUOUS_IVT_LOCAL_EXTREMUM) THEN + ASM_REWRITE_TAC[NOT_IMP] THEN CONJ_TAC THENL + [ASM_MESON_TAC[CONVEX_CONTAINS_SEGMENT_EQ; IS_INTERVAL_CONVEX_1; + CONTINUOUS_ON_SUBSET]; + DISCH_THEN(X_CHOOSE_TAC `z:real^1`) THEN + FIRST_ASSUM(MP_TAC o SPEC `segment(x:real^1,y)`) THEN + REWRITE_TAC[OPEN_SEGMENT_1; NOT_IMP] THEN CONJ_TAC THENL + [ASM_MESON_TAC[CONVEX_CONTAINS_SEGMENT; IS_INTERVAL_CONVEX_1; + SUBSET_TRANS; SEGMENT_OPEN_SUBSET_CLOSED]; + FIRST_X_ASSUM(CONJUNCTS_THEN ASSUME_TAC) THEN + REWRITE_TAC[open_def; FORALL_IN_IMAGE] THEN + DISCH_THEN(MP_TAC o SPEC `z:real^1`) THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `e:real` + (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + FIRST_X_ASSUM DISJ_CASES_TAC THENL + [DISCH_THEN(MP_TAC o SPEC `(f:real^1->real^1) z + lift(e / &2)`); + DISCH_THEN(MP_TAC o SPEC `(f:real^1->real^1) z - lift(e / &2)`)] THEN + ASM_REWRITE_TAC[NORM_ARITH `dist(a + b:real^N,a) = norm b`; + NORM_ARITH `dist(a - b:real^N,a) = norm b`; NORM_LIFT; + REAL_ARITH `abs(e / &2) < e <=> &0 < e`] THEN + REWRITE_TAC[IN_IMAGE] THEN + DISCH_THEN(X_CHOOSE_THEN `w:real^1` (STRIP_ASSUME_TAC o GSYM)) THEN + FIRST_X_ASSUM(MP_TAC o SPEC `w:real^1`) THEN + ASM_SIMP_TAC[REWRITE_RULE[SUBSET] SEGMENT_OPEN_SUBSET_CLOSED] THEN + REWRITE_TAC[DROP_ADD; DROP_SUB; LIFT_DROP] THEN + ASM_REAL_ARITH_TAC]]]);; + +(* ------------------------------------------------------------------------- *) +(* Map f:S^m->S^n for m < n is nullhomotopic. *) +(* ------------------------------------------------------------------------- *) + +let INESSENTIAL_SPHEREMAP_LOWDIM_GEN = prove + (`!f:real^M->real^N s t. + convex s /\ bounded s /\ convex t /\ bounded t /\ aff_dim s < aff_dim t /\ + f continuous_on relative_frontier s /\ + IMAGE f (relative_frontier s) SUBSET (relative_frontier t) + ==> ?c. homotopic_with (\z. T) + (relative_frontier s,relative_frontier t) f (\x. c)`, + let lemma1 = prove + (`!f:real^N->real^N s t. + subspace s /\ subspace t /\ dim s < dim t /\ s SUBSET t /\ + f differentiable_on sphere(vec 0,&1) INTER s + ==> ~(IMAGE f (sphere(vec 0,&1) INTER s) = sphere(vec 0,&1) INTER t)`, + REPEAT STRIP_TAC THEN + ABBREV_TAC + `(g:real^N->real^N) = + \x. norm(x) % (f:real^N->real^N)(inv(norm x) % x)` THEN + SUBGOAL_THEN + `(g:real^N->real^N) differentiable_on s DELETE (vec 0)` + ASSUME_TAC THENL + [EXPAND_TAC "g" THEN MATCH_MP_TAC DIFFERENTIABLE_ON_MUL THEN + SIMP_TAC[o_DEF; DIFFERENTIABLE_ON_NORM; IN_DELETE] THEN + GEN_REWRITE_TAC LAND_CONV [GSYM o_DEF] THEN + MATCH_MP_TAC DIFFERENTIABLE_ON_COMPOSE THEN CONJ_TAC THENL + [MATCH_MP_TAC DIFFERENTIABLE_ON_MUL THEN + REWRITE_TAC[DIFFERENTIABLE_ON_ID] THEN + SUBGOAL_THEN + `lift o (\x:real^N. inv(norm x)) = + (lift o inv o drop) o (\x. lift(norm x))` + SUBST1_TAC THENL [REWRITE_TAC[o_DEF; LIFT_DROP]; ALL_TAC] THEN + MATCH_MP_TAC DIFFERENTIABLE_ON_COMPOSE THEN + SIMP_TAC[DIFFERENTIABLE_ON_NORM; IN_DELETE] THEN + MATCH_MP_TAC DIFFERENTIABLE_AT_IMP_DIFFERENTIABLE_ON THEN + SIMP_TAC[FORALL_IN_IMAGE; IN_DELETE; GSYM REAL_DIFFERENTIABLE_AT] THEN + REPEAT STRIP_TAC THEN GEN_REWRITE_TAC LAND_CONV [GSYM ETA_AX] THEN + MATCH_MP_TAC REAL_DIFFERENTIABLE_INV_ATREAL THEN + ASM_REWRITE_TAC[REAL_DIFFERENTIABLE_ID; NORM_EQ_0]; + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + DIFFERENTIABLE_ON_SUBSET)) THEN + ASM_SIMP_TAC[SUBSET; FORALL_IN_IMAGE; IN_SPHERE_0; IN_INTER; + SUBSPACE_MUL; NORM_MUL; IN_DELETE] THEN + SIMP_TAC[REAL_ABS_INV; REAL_ABS_NORM; REAL_MUL_LINV; NORM_EQ_0]]; + ALL_TAC] THEN + SUBGOAL_THEN + `IMAGE (g:real^N->real^N) (s DELETE vec 0) = t DELETE (vec 0)` + ASSUME_TAC THENL + [UNDISCH_TAC `IMAGE (f:real^N->real^N) (sphere (vec 0,&1) INTER s) = + sphere (vec 0,&1) INTER t` THEN + REWRITE_TAC[GSYM SUBSET_ANTISYM_EQ] THEN + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; IN_DELETE; + IN_INTER; IN_SPHERE_0] THEN + EXPAND_TAC "g" THEN REWRITE_TAC[IN_IMAGE; IN_INTER; IN_SPHERE_0] THEN + SIMP_TAC[IN_DELETE; VECTOR_MUL_EQ_0; NORM_EQ_0] THEN + MATCH_MP_TAC(TAUT + `(p ==> r) /\ (p ==> q ==> s) ==> p /\ q ==> r /\ s`) THEN + CONJ_TAC THENL [ALL_TAC; DISCH_TAC] THEN + DISCH_THEN(fun th -> X_GEN_TAC `x:real^N` THEN STRIP_TAC THEN + MP_TAC(SPEC `inv(norm x) % x:real^N` th)) THEN + ASM_SIMP_TAC[SUBSPACE_MUL; NORM_MUL; REAL_ABS_INV; REAL_ABS_NORM; + REAL_MUL_LINV; NORM_EQ_0; + NORM_ARITH `norm x = &1 ==> ~(x:real^N = vec 0)`] THEN + DISCH_THEN(X_CHOOSE_THEN `y:real^N` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `norm(x:real^N) % y:real^N` THEN + ASM_SIMP_TAC[SUBSPACE_MUL; NORM_MUL; REAL_ABS_NORM; REAL_MUL_RID] THEN + ASM_SIMP_TAC[VECTOR_MUL_ASSOC; REAL_MUL_LINV; NORM_EQ_0] THEN + ASM_REWRITE_TAC[VECTOR_MUL_LID; VECTOR_MUL_EQ_0; NORM_EQ_0] THEN + ASM_SIMP_TAC[NORM_ARITH `norm x = &1 ==> ~(x:real^N = vec 0)`] THEN + UNDISCH_THEN `inv(norm x) % x = (f:real^N->real^N) y` + (SUBST1_TAC o SYM) THEN + ASM_SIMP_TAC[VECTOR_MUL_ASSOC; REAL_MUL_RINV; NORM_EQ_0] THEN + REWRITE_TAC[VECTOR_MUL_LID]; + ALL_TAC] THEN + MP_TAC(ISPECL [`t:real^N->bool`; `(:real^N)`] + DIM_SUBSPACE_ORTHOGONAL_TO_VECTORS) THEN + ASM_REWRITE_TAC[SUBSPACE_UNIV; DIM_UNIV; IN_UNIV; SUBSET_UNIV] THEN + ABBREV_TAC `t' = {y:real^N | !x. x IN t ==> orthogonal x y}` THEN + DISCH_TAC THEN + SUBGOAL_THEN `subspace(t':real^N->bool)` ASSUME_TAC THENL + [EXPAND_TAC "t'" THEN REWRITE_TAC[SUBSPACE_ORTHOGONAL_TO_VECTORS]; + ALL_TAC] THEN + SUBGOAL_THEN + `?fst snd. linear fst /\ linear snd /\ + (!z. fst(z) IN t /\ snd z IN t' /\ fst z + snd z = z) /\ + (!x y:real^N. x IN t /\ y IN t' + ==> fst(x + y) = x /\ snd(x + y) = y)` + STRIP_ASSUME_TAC THENL + [MP_TAC(ISPEC `t:real^N->bool` ORTHOGONAL_SUBSPACE_DECOMP_EXISTS) THEN + REWRITE_TAC[SKOLEM_THM] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `fst:real^N->real^N` THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `snd:real^N->real^N` THEN + DISCH_THEN(MP_TAC o GSYM) THEN + ASM_SIMP_TAC[SPAN_OF_SUBSPACE; FORALL_AND_THM] THEN STRIP_TAC THEN + MATCH_MP_TAC(TAUT `r /\ (r ==> p /\ q /\ s) ==> p /\ q /\ r /\ s`) THEN + CONJ_TAC THENL + [EXPAND_TAC "t'" THEN REWRITE_TAC[IN_ELIM_THM] THEN + ASM_MESON_TAC[ORTHOGONAL_SYM]; + DISCH_TAC] THEN + MATCH_MP_TAC(TAUT `r /\ (r ==> p /\ q) ==> p /\ q /\ r`) THEN + CONJ_TAC THENL + [REPEAT GEN_TAC THEN STRIP_TAC THEN + MATCH_MP_TAC ORTHOGONAL_SUBSPACE_DECOMP_UNIQUE THEN + MAP_EVERY EXISTS_TAC [`t:real^N->bool`; `t':real^N->bool`] THEN + ASM_SIMP_TAC[SPAN_OF_SUBSPACE] THEN ASM SET_TAC[]; + DISCH_TAC] THEN + REWRITE_TAC[linear] THEN + MATCH_MP_TAC(TAUT `(p /\ r) /\ (q /\ s) ==> (p /\ q) /\ (r /\ s)`) THEN + REWRITE_TAC[AND_FORALL_THM] THEN CONJ_TAC THEN REPEAT GEN_TAC THEN + MATCH_MP_TAC ORTHOGONAL_SUBSPACE_DECOMP_UNIQUE THEN + MAP_EVERY EXISTS_TAC [`t:real^N->bool`; `t':real^N->bool`] THEN + ASM_SIMP_TAC[SPAN_OF_SUBSPACE; SUBSPACE_ADD; SUBSPACE_MUL] THEN + (CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC]) THEN + ASM_REWRITE_TAC[GSYM VECTOR_ADD_LDISTRIB] THEN + ONCE_REWRITE_TAC[VECTOR_ARITH + `(x + y) + (x' + y'):real^N = (x + x') + (y + y')`] THEN + ASM_REWRITE_TAC[]; + ALL_TAC] THEN + MP_TAC(ISPECL + [`\x:real^N. (g:real^N->real^N)(fst x) + snd x`; + `{x + y:real^N | x IN (s DELETE vec 0) /\ y IN t'}`] + NEGLIGIBLE_DIFFERENTIABLE_IMAGE_NEGLIGIBLE) THEN + REWRITE_TAC[LE_REFL; NOT_IMP] THEN REPEAT CONJ_TAC THENL + [MATCH_MP_TAC NEGLIGIBLE_LOWDIM THEN + MP_TAC(ISPECL [`s:real^N->bool`; `t':real^N->bool`] DIM_SUMS_INTER) THEN + ASM_REWRITE_TAC[IN_DELETE] THEN + FIRST_ASSUM(MATCH_MP_TAC o MATCH_MP (ARITH_RULE + `t' + t = n ==> s < t /\ d' <= d /\ i = 0 + ==> d + i = s + t' ==> d' < n`)) THEN + ASM_REWRITE_TAC[DIM_EQ_0] THEN CONJ_TAC THENL + [MATCH_MP_TAC DIM_SUBSET THEN SET_TAC[]; EXPAND_TAC "t'"] THEN + REWRITE_TAC[SUBSET; IN_INTER; IN_SING; IN_ELIM_THM] THEN + ASM_MESON_TAC[SUBSET; ORTHOGONAL_REFL]; + MATCH_MP_TAC DIFFERENTIABLE_ON_ADD THEN + ASM_SIMP_TAC[DIFFERENTIABLE_ON_LINEAR] THEN + GEN_REWRITE_TAC LAND_CONV [GSYM o_DEF] THEN + MATCH_MP_TAC DIFFERENTIABLE_ON_COMPOSE THEN + ASM_SIMP_TAC[DIFFERENTIABLE_ON_LINEAR] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + DIFFERENTIABLE_ON_SUBSET)) THEN + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; FORALL_IN_GSPEC] THEN + RULE_ASSUM_TAC(REWRITE_RULE[SUBSET]) THEN ASM_SIMP_TAC[IN_DELETE]; + SUBGOAL_THEN + `~negligible {x + y | x IN IMAGE (g:real^N->real^N) (s DELETE vec 0) /\ + y IN t'}` + MP_TAC THENL + [ASM_REWRITE_TAC[] THEN + SUBGOAL_THEN `negligible(t':real^N->bool)` MP_TAC THENL + [MATCH_MP_TAC NEGLIGIBLE_LOWDIM THEN ASM_ARITH_TAC; + REWRITE_TAC[TAUT `p ==> ~q <=> ~(p /\ q)`]] THEN + REWRITE_TAC[GSYM NEGLIGIBLE_UNION_EQ] THEN + MP_TAC NOT_NEGLIGIBLE_UNIV THEN MATCH_MP_TAC EQ_IMP THEN + AP_TERM_TAC THEN AP_TERM_TAC THEN + REWRITE_TAC[EXTENSION; IN_UNION; IN_UNIV; IN_ELIM_THM; IN_DELETE] THEN + X_GEN_TAC `z:real^N` THEN + REWRITE_TAC[TAUT `p \/ q <=> ~p ==> q`] THEN DISCH_TAC THEN + EXISTS_TAC `(fst:real^N->real^N) z` THEN + EXISTS_TAC `(snd:real^N->real^N) z` THEN + ASM_SIMP_TAC[] THEN ASM_MESON_TAC[VECTOR_ADD_LID]; + REWRITE_TAC[CONTRAPOS_THM] THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] NEGLIGIBLE_SUBSET) THEN + REWRITE_TAC[SUBSET; FORALL_IN_GSPEC; IMP_CONJ; RIGHT_FORALL_IMP_THM; + FORALL_IN_IMAGE; IN_DELETE] THEN + X_GEN_TAC `x:real^N` THEN REPEAT DISCH_TAC THEN + X_GEN_TAC `y:real^N` THEN DISCH_TAC THEN + REWRITE_TAC[IN_IMAGE] THEN EXISTS_TAC `x + y:real^N` THEN + RULE_ASSUM_TAC(REWRITE_RULE[SUBSET]) THEN ASM_SIMP_TAC[] THEN ASM + SET_TAC[]]]) in + let lemma2 = prove + (`!f:real^N->real^N s t. + subspace s /\ subspace t /\ dim s < dim t /\ s SUBSET t /\ + f continuous_on sphere(vec 0,&1) INTER s /\ + IMAGE f (sphere(vec 0,&1) INTER s) SUBSET sphere(vec 0,&1) INTER t + ==> ?c. homotopic_with (\x. T) + (sphere(vec 0,&1) INTER s,sphere(vec 0,&1) INTER t) + f (\x. c)`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`f:real^N->real^N`; `sphere(vec 0:real^N,&1) INTER s`; + `&1 / &2`; `t:real^N->bool`;] + STONE_WEIERSTRASS_VECTOR_POLYNOMIAL_FUNCTION_SUBSPACE) THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN + ASM_SIMP_TAC[COMPACT_INTER_CLOSED; COMPACT_SPHERE; CLOSED_SUBSPACE] THEN + ANTS_TAC THENL [ASM SET_TAC[]; REWRITE_TAC[SUBSET; FORALL_IN_IMAGE]] THEN + DISCH_THEN(X_CHOOSE_THEN `g:real^N->real^N` STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN + `!x. x IN sphere(vec 0,&1) INTER s ==> ~((g:real^N->real^N) x = vec 0)` + ASSUME_TAC THENL + [X_GEN_TAC `x:real^N` THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `x:real^N`) THEN ASM_REWRITE_TAC[] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [SUBSET]) THEN + REWRITE_TAC[FORALL_IN_IMAGE; IN_SPHERE_0] THEN + RULE_ASSUM_TAC(REWRITE_RULE[IN_SPHERE_0]) THEN + DISCH_THEN(MP_TAC o SPEC `x:real^N`) THEN + ASM_REWRITE_TAC[] THEN REWRITE_TAC[IN_INTER; IN_SPHERE_0] THEN + CONV_TAC NORM_ARITH; + ALL_TAC] THEN + SUBGOAL_THEN `(g:real^N->real^N) differentiable_on + sphere(vec 0,&1) INTER s` + ASSUME_TAC THENL + [ASM_SIMP_TAC[DIFFERENTIABLE_ON_VECTOR_POLYNOMIAL_FUNCTION]; ALL_TAC] THEN + ABBREV_TAC `(h:real^N->real^N) = \x. inv(norm(g x)) % g x` THEN + SUBGOAL_THEN + `!x. x IN sphere(vec 0,&1) INTER s + ==> (h:real^N->real^N) x IN sphere(vec 0,&1) INTER t` + ASSUME_TAC THENL + [REPEAT STRIP_TAC THEN EXPAND_TAC "h" THEN + ASM_SIMP_TAC[SUBSPACE_MUL; IN_INTER; IN_SPHERE_0; NORM_MUL] THEN + REWRITE_TAC[REAL_ABS_INV; REAL_ABS_NORM] THEN + ASM_SIMP_TAC[REAL_MUL_LINV; NORM_EQ_0; GSYM IN_SPHERE_0]; + ALL_TAC] THEN + SUBGOAL_THEN + `(h:real^N->real^N) differentiable_on sphere(vec 0,&1) INTER s` + ASSUME_TAC THENL + [EXPAND_TAC "h" THEN MATCH_MP_TAC DIFFERENTIABLE_ON_MUL THEN + ASM_SIMP_TAC[DIFFERENTIABLE_ON_VECTOR_POLYNOMIAL_FUNCTION; o_DEF] THEN + SUBGOAL_THEN + `(\x. lift(inv(norm((g:real^N->real^N) x)))) = + (lift o inv o drop) o (\x. lift(norm x)) o (g:real^N->real^N)` + SUBST1_TAC THENL [REWRITE_TAC[o_DEF; LIFT_DROP]; ALL_TAC] THEN + MATCH_MP_TAC DIFFERENTIABLE_ON_COMPOSE THEN CONJ_TAC THENL + [MATCH_MP_TAC DIFFERENTIABLE_ON_COMPOSE THEN + ASM_SIMP_TAC[DIFFERENTIABLE_ON_VECTOR_POLYNOMIAL_FUNCTION] THEN + MATCH_MP_TAC DIFFERENTIABLE_ON_NORM THEN + ASM_REWRITE_TAC[SET_RULE + `~(z IN IMAGE f s) <=> !x. x IN s ==> ~(f x = z)`]; + MATCH_MP_TAC DIFFERENTIABLE_AT_IMP_DIFFERENTIABLE_ON THEN + REWRITE_TAC[GSYM REAL_DIFFERENTIABLE_AT] THEN + REWRITE_TAC[FORALL_IN_IMAGE; IN_SPHERE_0] THEN + X_GEN_TAC `x:real^N` THEN + ASM_CASES_TAC `x:real^N = vec 0` THEN + ASM_REWRITE_TAC[NORM_0; REAL_OF_NUM_EQ; ARITH_EQ] THEN DISCH_TAC THEN + REWRITE_TAC[GSYM REAL_DIFFERENTIABLE_AT; o_THM] THEN + GEN_REWRITE_TAC LAND_CONV [GSYM ETA_AX] THEN + MATCH_MP_TAC REAL_DIFFERENTIABLE_INV_ATREAL THEN + ASM_SIMP_TAC[REAL_DIFFERENTIABLE_ID; NORM_EQ_0; IN_SPHERE_0]]; + ALL_TAC] THEN + SUBGOAL_THEN + `?c. homotopic_with (\z. T) + (sphere(vec 0,&1) INTER s,sphere(vec 0,&1) INTER t) + (h:real^N->real^N) (\x. c)` + MP_TAC THENL + [ALL_TAC; + MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] HOMOTOPIC_WITH_TRANS) THEN + SUBGOAL_THEN + `homotopic_with (\z. T) + (sphere(vec 0:real^N,&1) INTER s,t DELETE (vec 0:real^N)) + f g` + MP_TAC THENL + [MATCH_MP_TAC HOMOTOPIC_WITH_LINEAR THEN + ASM_SIMP_TAC[CONTINUOUS_ON_VECTOR_POLYNOMIAL_FUNCTION] THEN + X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN REWRITE_TAC[SET_RULE + `s SUBSET t DELETE v <=> s SUBSET t /\ ~(v IN s)`] THEN + CONJ_TAC THENL + [REWRITE_TAC[SEGMENT_CONVEX_HULL] THEN MATCH_MP_TAC HULL_MINIMAL THEN + ASM_SIMP_TAC[SUBSPACE_IMP_CONVEX] THEN ASM SET_TAC[]; + DISCH_THEN(MP_TAC o MATCH_MP SEGMENT_BOUND) THEN + SUBGOAL_THEN + `(f:real^N->real^N) x IN sphere(vec 0,&1) /\ + norm(f x - g x) < &1/ &2` + MP_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + REWRITE_TAC[IN_SPHERE_0] THEN CONV_TAC NORM_ARITH]; + DISCH_THEN(MP_TAC o + ISPECL [`\y:real^N. inv(norm y) % y`; + `sphere(vec 0:real^N,&1) INTER t`] o + MATCH_MP (ONCE_REWRITE_RULE[IMP_CONJ] + HOMOTOPIC_COMPOSE_CONTINUOUS_LEFT)) THEN + ASM_REWRITE_TAC[o_DEF] THEN ANTS_TAC THENL + [CONJ_TAC THENL + [MATCH_MP_TAC CONTINUOUS_ON_MUL THEN + REWRITE_TAC[o_DEF; CONTINUOUS_ON_ID] THEN + MATCH_MP_TAC(REWRITE_RULE[o_DEF] CONTINUOUS_ON_INV) THEN + SIMP_TAC[IN_DELETE; NORM_EQ_0] THEN + REWRITE_TAC[REWRITE_RULE[o_DEF] CONTINUOUS_ON_LIFT_NORM]; + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; IN_DELETE; IN_INTER] THEN + ASM_SIMP_TAC[SUBSPACE_MUL; IN_SPHERE_0; NORM_MUL; REAL_ABS_MUL] THEN + SIMP_TAC[REAL_ABS_INV; REAL_ABS_NORM; REAL_MUL_LINV; NORM_EQ_0]]; + MATCH_MP_TAC(ONCE_REWRITE_RULE[IMP_CONJ_ALT] HOMOTOPIC_WITH_EQ) THEN + RULE_ASSUM_TAC(REWRITE_RULE + [SUBSET; IN_INTER; FORALL_IN_IMAGE; IN_SPHERE_0]) THEN + ASM_SIMP_TAC[IN_SPHERE_0; IN_INTER; + REAL_INV_1; VECTOR_MUL_LID]]]] THEN + SUBGOAL_THEN + `?c. c IN (sphere(vec 0,&1) INTER t) DIFF + (IMAGE (h:real^N->real^N) (sphere(vec 0,&1) INTER s))` + MP_TAC THENL + [MATCH_MP_TAC(SET_RULE + `t SUBSET s /\ ~(t = s) ==> ?a. a IN s DIFF t`) THEN + CONJ_TAC THENL [ASM SET_TAC[]; MATCH_MP_TAC lemma1] THEN + ASM_REWRITE_TAC[]; + REWRITE_TAC[LEFT_IMP_EXISTS_THM; IN_INTER; IN_DIFF; IN_IMAGE] THEN + REWRITE_TAC[SET_RULE + `~(?x. P x /\ x IN s /\ x IN t) <=> + (!x. x IN s INTER t ==> ~(P x))`] THEN + X_GEN_TAC `c:real^N` THEN STRIP_TAC] THEN + EXISTS_TAC `--c:real^N` THEN + SUBGOAL_THEN + `homotopic_with (\z. T) + (sphere(vec 0:real^N,&1) INTER s,t DELETE (vec 0:real^N)) + h (\x. --c)` + MP_TAC THENL + [MATCH_MP_TAC HOMOTOPIC_WITH_LINEAR THEN + ASM_SIMP_TAC[DIFFERENTIABLE_IMP_CONTINUOUS_ON; CONTINUOUS_ON_CONST] THEN + X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN REWRITE_TAC[SET_RULE + `s SUBSET t DELETE v <=> s SUBSET t /\ ~(v IN s)`] THEN + CONJ_TAC THENL + [REWRITE_TAC[SEGMENT_CONVEX_HULL] THEN MATCH_MP_TAC HULL_MINIMAL THEN + ASM_SIMP_TAC[SUBSPACE_IMP_CONVEX; INSERT_SUBSET; SUBSPACE_NEG] THEN + ASM SET_TAC[]; + DISCH_TAC THEN MP_TAC(ISPECL + [`(h:real^N->real^N) x`; `vec 0:real^N`; `--c:real^N`] + MIDPOINT_BETWEEN) THEN + ASM_REWRITE_TAC[BETWEEN_IN_SEGMENT; DIST_0; NORM_NEG] THEN + SUBGOAL_THEN `((h:real^N->real^N) x) IN sphere(vec 0,&1) /\ + (c:real^N) IN sphere(vec 0,&1)` + MP_TAC THENL [ASM SET_TAC[]; SIMP_TAC[IN_SPHERE_0]] THEN + STRIP_TAC THEN REWRITE_TAC[midpoint; VECTOR_ARITH + `vec 0:real^N = inv(&2) % (x + --y) <=> x = y`] THEN + ASM SET_TAC[]]; + DISCH_THEN(MP_TAC o + ISPECL [`\y:real^N. inv(norm y) % y`; + `sphere(vec 0:real^N,&1) INTER t`] o + MATCH_MP (ONCE_REWRITE_RULE[IMP_CONJ] + HOMOTOPIC_COMPOSE_CONTINUOUS_LEFT)) THEN + ASM_REWRITE_TAC[o_DEF] THEN ANTS_TAC THENL + [CONJ_TAC THENL + [MATCH_MP_TAC CONTINUOUS_ON_MUL THEN + REWRITE_TAC[o_DEF; CONTINUOUS_ON_ID] THEN + MATCH_MP_TAC(REWRITE_RULE[o_DEF] CONTINUOUS_ON_INV) THEN + SIMP_TAC[IN_DELETE; NORM_EQ_0] THEN + REWRITE_TAC[REWRITE_RULE[o_DEF] CONTINUOUS_ON_LIFT_NORM]; + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; IN_DELETE; IN_INTER] THEN + ASM_SIMP_TAC[SUBSPACE_MUL; IN_SPHERE_0; NORM_MUL; REAL_ABS_MUL] THEN + SIMP_TAC[REAL_ABS_INV; REAL_ABS_NORM; REAL_MUL_LINV; NORM_EQ_0]]; + MATCH_MP_TAC(ONCE_REWRITE_RULE[IMP_CONJ_ALT] HOMOTOPIC_WITH_EQ) THEN + RULE_ASSUM_TAC(REWRITE_RULE + [SUBSET; IN_INTER; FORALL_IN_IMAGE; IN_SPHERE_0]) THEN + ASM_SIMP_TAC[IN_SPHERE_0; IN_INTER; REAL_INV_1; VECTOR_MUL_LID; + NORM_NEG]]]) in + let lemma3 = prove + (`!s:real^M->bool u:real^N->bool. + bounded s /\ convex s /\ subspace u /\ aff_dim s <= &(dim u) + ==> ?t. subspace t /\ t SUBSET u /\ + (~(s = {}) ==> aff_dim t = aff_dim s) /\ + (relative_frontier s) homeomorphic + (sphere(vec 0,&1) INTER t)`, + REPEAT GEN_TAC THEN ASM_CASES_TAC `s:real^M->bool = {}` THENL + [STRIP_TAC THEN EXISTS_TAC `{vec 0:real^N}` THEN + ASM_REWRITE_TAC[SUBSPACE_TRIVIAL; RELATIVE_FRONTIER_EMPTY] THEN + ASM_SIMP_TAC[HOMEOMORPHIC_EMPTY; + SET_RULE `s INTER {a} = {} <=> ~(a IN s)`; + IN_SPHERE_0; NORM_0; SING_SUBSET; SUBSPACE_0] THEN + CONV_TAC REAL_RAT_REDUCE_CONV; + FIRST_X_ASSUM(X_CHOOSE_THEN `a:real^M` MP_TAC o + GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN + GEOM_ORIGIN_TAC `a:real^M` THEN + SIMP_TAC[AFF_DIM_DIM_0; HULL_INC; INT_OF_NUM_LE; GSYM DIM_UNIV] THEN + REPEAT STRIP_TAC] THEN + FIRST_ASSUM(MP_TAC o MATCH_MP CHOOSE_SUBSPACE_OF_SUBSPACE) THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `t:real^N->bool` THEN + ASM_SIMP_TAC[SPAN_OF_SUBSPACE; AFF_DIM_DIM_SUBSPACE; INT_OF_NUM_EQ] THEN + STRIP_TAC THEN + TRANS_TAC HOMEOMORPHIC_TRANS + `relative_frontier(ball(vec 0:real^N,&1) INTER t)` THEN + CONJ_TAC THENL + [MATCH_MP_TAC HOMEOMORPHIC_RELATIVE_FRONTIERS_CONVEX_BOUNDED_SETS THEN + ASM_SIMP_TAC[CONVEX_INTER; BOUNDED_INTER; BOUNDED_BALL; + SUBSPACE_IMP_CONVEX; CONVEX_BALL] THEN + ONCE_REWRITE_TAC[INTER_COMM] THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP SUBSPACE_0) THEN + SUBGOAL_THEN `~(t INTER ball(vec 0:real^N,&1) = {})` ASSUME_TAC THENL + [REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN EXISTS_TAC `vec 0:real^N` THEN + ASM_REWRITE_TAC[IN_INTER; CENTRE_IN_BALL; REAL_LT_01]; + ASM_SIMP_TAC[AFF_DIM_CONVEX_INTER_OPEN; OPEN_BALL; + SUBSPACE_IMP_CONVEX] THEN + ASM_SIMP_TAC[AFF_DIM_DIM_0; HULL_INC]]; + MATCH_MP_TAC(MESON[HOMEOMORPHIC_REFL] `s = t ==> s homeomorphic t`) THEN + SIMP_TAC[GSYM FRONTIER_BALL; REAL_LT_01] THEN + MATCH_MP_TAC RELATIVE_FRONTIER_CONVEX_INTER_AFFINE THEN + ASM_SIMP_TAC[CONVEX_BALL; SUBSPACE_IMP_AFFINE; + GSYM MEMBER_NOT_EMPTY] THEN + EXISTS_TAC `vec 0:real^N` THEN + ASM_SIMP_TAC[CENTRE_IN_BALL; INTERIOR_OPEN; OPEN_BALL; + SUBSPACE_0; IN_INTER; REAL_LT_01]]) in + ONCE_REWRITE_TAC[MESON[] `(!a b c. P a b c) <=> (!b c a. P a b c)`] THEN + REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN + REWRITE_TAC[IMP_IMP] THEN ONCE_REWRITE_TAC[RIGHT_IMP_FORALL_THM] THEN + REWRITE_TAC[IMP_IMP; GSYM CONJ_ASSOC] THEN REPEAT GEN_TAC THEN + ASM_CASES_TAC `s:real^M->bool = {}` THENL + [ASM_SIMP_TAC[HOMOTOPIC_WITH; RELATIVE_FRONTIER_EMPTY; PCROSS_EMPTY; + NOT_IN_EMPTY; IMAGE_CLAUSES; CONTINUOUS_ON_EMPTY]; + ALL_TAC] THEN + ASM_CASES_TAC `t:real^N->bool = {}` THEN + ASM_SIMP_TAC[AFF_DIM_EMPTY; GSYM INT_NOT_LE; AFF_DIM_GE] THEN + STRIP_TAC THEN + MP_TAC(ISPECL [`t:real^N->bool`; `(:real^N)`] lemma3) THEN + ASM_REWRITE_TAC[DIM_UNIV; SUBSPACE_UNIV; AFF_DIM_LE_UNIV] THEN + DISCH_THEN(X_CHOOSE_THEN `t':real^N->bool` STRIP_ASSUME_TAC) THEN + FIRST_ASSUM(MP_TAC o MATCH_MP HOMEOMORPHIC_IMP_HOMOTOPY_EQUIVALENT) THEN + DISCH_THEN(fun th -> REWRITE_TAC[MATCH_MP + HOMOTOPY_EQUIVALENT_HOMOTOPIC_TRIVIALITY_NULL th]) THEN + MP_TAC(ISPECL [`s:real^M->bool`; `t':real^N->bool`] lemma3) THEN + ASM_SIMP_TAC[GSYM AFF_DIM_DIM_SUBSPACE] THEN + ANTS_TAC THENL [ASM_INT_ARITH_TAC; ALL_TAC] THEN + DISCH_THEN(X_CHOOSE_THEN `s':real^N->bool` STRIP_ASSUME_TAC) THEN + FIRST_ASSUM(MP_TAC o MATCH_MP HOMEOMORPHIC_IMP_HOMOTOPY_EQUIVALENT) THEN + DISCH_THEN(fun th -> REWRITE_TAC[MATCH_MP + HOMOTOPY_EQUIVALENT_COHOMOTOPIC_TRIVIALITY_NULL th]) THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC lemma2 THEN + ASM_SIMP_TAC[GSYM INT_OF_NUM_LT; GSYM AFF_DIM_DIM_SUBSPACE] THEN + ASM_INT_ARITH_TAC);; + +let INESSENTIAL_SPHEREMAP_LOWDIM = prove + (`!f:real^M->real^N a r b s. + dimindex(:M) < dimindex(:N) /\ + f continuous_on sphere(a,r) /\ + IMAGE f (sphere(a,r)) SUBSET (sphere(b,s)) + ==> ?c. homotopic_with (\z. T) (sphere(a,r),sphere(b,s)) f (\x. c)`, + REPEAT GEN_TAC THEN ASM_CASES_TAC `s <= &0` THEN + ASM_SIMP_TAC[NULLHOMOTOPIC_INTO_CONTRACTIBLE; CONTRACTIBLE_SPHERE] THEN + ASM_CASES_TAC `r <= &0` THEN + ASM_SIMP_TAC[NULLHOMOTOPIC_FROM_CONTRACTIBLE; CONTRACTIBLE_SPHERE] THEN + ASM_SIMP_TAC[GSYM FRONTIER_CBALL; INTERIOR_CBALL; BALL_EQ_EMPTY; + CONV_RULE(RAND_CONV SYM_CONV) (SPEC_ALL + RELATIVE_FRONTIER_NONEMPTY_INTERIOR)] THEN + STRIP_TAC THEN MATCH_MP_TAC INESSENTIAL_SPHEREMAP_LOWDIM_GEN THEN + ASM_REWRITE_TAC[CONVEX_CBALL; BOUNDED_CBALL; AFF_DIM_CBALL] THEN + ASM_REWRITE_TAC[GSYM REAL_NOT_LE; INT_OF_NUM_LT]);; + +let HOMEOMORPHIC_SPHERES_EQ,HOMOTOPY_EQUIVALENT_SPHERES_EQ = + (CONJ_PAIR o prove) + (`(!a:real^M b:real^N r s. + sphere(a,r) homeomorphic sphere(b,s) <=> + r < &0 /\ s < &0 \/ r = &0 /\ s = &0 \/ + &0 < r /\ &0 < s /\ dimindex(:M) = dimindex(:N)) /\ + (!a:real^M b:real^N r s. + sphere(a,r) homotopy_equivalent sphere(b,s) <=> + r < &0 /\ s < &0 \/ r = &0 /\ s = &0 \/ + &0 < r /\ &0 < s /\ dimindex(:M) = dimindex(:N))`, + let lemma = prove + (`!a:real^M r b:real^N s. + dimindex(:M) < dimindex(:N) /\ &0 < r /\ &0 < s + ==> ~(sphere(a,r) homotopy_equivalent sphere(b,s))`, + REPEAT STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o ISPEC `sphere(a:real^M,r)` o + MATCH_MP HOMOTOPY_EQUIVALENT_HOMOTOPIC_TRIVIALITY) THEN + MATCH_MP_TAC(TAUT `~p /\ q ==> (p <=> q) ==> F`) THEN CONJ_TAC THENL + [SUBGOAL_THEN `~(sphere(a:real^M,r) = {})` MP_TAC THENL + [REWRITE_TAC[SPHERE_EQ_EMPTY] THEN ASM_REAL_ARITH_TAC; + REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; LEFT_IMP_EXISTS_THM]] THEN + X_GEN_TAC `c:real^M` THEN DISCH_TAC THEN + DISCH_THEN(MP_TAC o SPECL[`\a:real^M. a`; `(\a. c):real^M->real^M`]) THEN + SIMP_TAC[CONTINUOUS_ON_CONST; CONTINUOUS_ON_ID; + IMAGE_ID; SUBSET_REFL] THEN + REWRITE_TAC[NOT_IMP] THEN CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + SUBGOAL_THEN `~(contractible(sphere(a:real^M,r)))` MP_TAC THENL + [REWRITE_TAC[CONTRACTIBLE_SPHERE] THEN ASM_REAL_ARITH_TAC; + REWRITE_TAC[contractible] THEN MESON_TAC[]]; + MAP_EVERY X_GEN_TAC [`f:real^M->real^N`; `g:real^M->real^N`] THEN + STRIP_TAC THEN + MP_TAC(ISPEC `g:real^M->real^N` INESSENTIAL_SPHEREMAP_LOWDIM) THEN + MP_TAC(ISPEC `f:real^M->real^N` INESSENTIAL_SPHEREMAP_LOWDIM) THEN + ASM_REWRITE_TAC[IMP_IMP; AND_FORALL_THM] THEN DISCH_THEN + (MP_TAC o SPECL [`a:real^M`; `r:real`; `b:real^N`; `s:real`]) THEN + ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM; IMP_CONJ; RIGHT_IMP_FORALL_THM] THEN + REPEAT GEN_TAC THEN REWRITE_TAC[IMP_IMP] THEN DISCH_THEN + (fun th -> CONJUNCTS_THEN (ASSUME_TAC o MATCH_MP + HOMOTOPIC_WITH_IMP_SUBSET) th THEN + MP_TAC th) THEN + MATCH_MP_TAC(MESON[HOMOTOPIC_WITH_TRANS; HOMOTOPIC_WITH_SYM] + `homotopic_with p (s,t) c d + ==> homotopic_with p (s,t) f c /\ + homotopic_with p (s,t) g d + ==> homotopic_with p (s,t) f g`) THEN + REWRITE_TAC[HOMOTOPIC_CONSTANT_MAPS] THEN DISJ2_TAC THEN + MP_TAC(ISPECL [`b:real^N`; `s:real`] PATH_CONNECTED_SPHERE) THEN + ANTS_TAC THENL + [FIRST_ASSUM(MATCH_MP_TAC o MATCH_MP (ARITH_RULE + `m < n ==> 1 <= m ==> 2 <= n`)) THEN REWRITE_TAC[DIMINDEX_GE_1]; + REWRITE_TAC[PATH_CONNECTED_IFF_PATH_COMPONENT] THEN + DISCH_THEN MATCH_MP_TAC THEN + SUBGOAL_THEN `~(sphere(a:real^M,r) = {})` MP_TAC THENL + [REWRITE_TAC[SPHERE_EQ_EMPTY] THEN ASM_REAL_ARITH_TAC; + ASM SET_TAC[]]]]) in + REWRITE_TAC[AND_FORALL_THM] THEN REPEAT GEN_TAC THEN + MATCH_MP_TAC(TAUT + `(r ==> p) /\ (q ==> r) /\ (p ==> q) ==> (r <=> q) /\ (p <=> q)`) THEN + REWRITE_TAC[HOMEOMORPHIC_IMP_HOMOTOPY_EQUIVALENT] THEN + ASM_CASES_TAC `r < &0` THEN + ASM_SIMP_TAC[SPHERE_EMPTY; SPHERE_EQ_EMPTY; + HOMEOMORPHIC_EMPTY; HOMOTOPY_EQUIVALENT_EMPTY] + THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN + ASM_CASES_TAC `s < &0` THEN + ASM_SIMP_TAC[SPHERE_EMPTY; SPHERE_EQ_EMPTY; + HOMEOMORPHIC_EMPTY; HOMOTOPY_EQUIVALENT_EMPTY] + THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN + ASM_CASES_TAC `r = &0` THEN + ASM_SIMP_TAC[SPHERE_SING; REAL_LT_REFL; HOMEOMORPHIC_SING; + HOMOTOPY_EQUIVALENT_SING; CONTRACTIBLE_SPHERE; + ONCE_REWRITE_RULE[HOMOTOPY_EQUIVALENT_SYM] + HOMOTOPY_EQUIVALENT_SING] + THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN + ASM_CASES_TAC `s = &0` THEN + ASM_SIMP_TAC[SPHERE_SING; REAL_LT_REFL; HOMEOMORPHIC_SING; + HOMOTOPY_EQUIVALENT_SING; CONTRACTIBLE_SPHERE; + ONCE_REWRITE_RULE[HOMOTOPY_EQUIVALENT_SYM] + HOMOTOPY_EQUIVALENT_SING] + THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `&0 < r /\ &0 < s` STRIP_ASSUME_TAC THENL + [ASM_REAL_ARITH_TAC; ASM_REWRITE_TAC[]] THEN + CONJ_TAC THENL + [DISCH_THEN(fun th -> + let t = `?a:real^M b:real^N. ~(sphere(a,r) homeomorphic sphere(b,s))` in + MP_TAC(DISCH t (GEOM_EQUAL_DIMENSION_RULE th (ASSUME t)))) THEN + ASM_SIMP_TAC[HOMEOMORPHIC_SPHERES] THEN MESON_TAC[]; + ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN + REWRITE_TAC[ARITH_RULE `~(m:num = n) <=> m < n \/ n < m`] THEN + STRIP_TAC THENL [ALL_TAC; ONCE_REWRITE_TAC[HOMOTOPY_EQUIVALENT_SYM]] THEN + ASM_SIMP_TAC[lemma]]);; + +(* ------------------------------------------------------------------------- *) +(* Some technical lemmas about extending maps from cell complexes. *) +(* ------------------------------------------------------------------------- *) + +let EXTEND_MAP_CELL_COMPLEX_TO_SPHERE, + EXTEND_MAP_CELL_COMPLEX_TO_SPHERE_COFINITE = (CONJ_PAIR o prove) + (`(!f:real^M->real^N m s t. + FINITE m /\ (!c. c IN m ==> polytope c /\ aff_dim c < aff_dim t) /\ + (!c1 c2. c1 IN m /\ c2 IN m + ==> c1 INTER c2 face_of c1 /\ c1 INTER c2 face_of c2) /\ + s SUBSET UNIONS m /\ closed s /\ convex t /\ bounded t /\ + f continuous_on s /\ IMAGE f s SUBSET relative_frontier t + ==> ?g. g continuous_on UNIONS m /\ + IMAGE g (UNIONS m) SUBSET relative_frontier t /\ + !x. x IN s ==> g x = f x) /\ + (!f:real^M->real^N m s t. + FINITE m /\ (!c. c IN m ==> polytope c /\ aff_dim c <= aff_dim t) /\ + (!c1 c2. c1 IN m /\ c2 IN m + ==> c1 INTER c2 face_of c1 /\ c1 INTER c2 face_of c2) /\ + s SUBSET UNIONS m /\ closed s /\ convex t /\ bounded t /\ + f continuous_on s /\ IMAGE f s SUBSET relative_frontier t + ==> ?k g. FINITE k /\ DISJOINT k s /\ + g continuous_on (UNIONS m DIFF k) /\ + IMAGE g (UNIONS m DIFF k) SUBSET relative_frontier t /\ + !x. x IN s ==> g x = f x)`, + let wemma = prove + (`!h:real^M->real^N k t f. + (!s. s IN f ==> ?g. g continuous_on s /\ + IMAGE g s SUBSET t /\ + !x. x IN s INTER k ==> g x = h x) /\ + FINITE f /\ (!s. s IN f ==> closed s) /\ + (!s t. s IN f /\ t IN f /\ ~(s = t) ==> (s INTER t) SUBSET k) + ==> ?g. g continuous_on (UNIONS f) /\ + IMAGE g (UNIONS f) SUBSET t /\ + !x. x IN (UNIONS f) INTER k ==> g x = h x`, + REPLICATE_TAC 3 GEN_TAC THEN + ONCE_REWRITE_TAC[TAUT `p /\ q /\ r ==> s <=> q ==> p /\ r ==> s`] THEN + MATCH_MP_TAC FINITE_INDUCT_STRONG THEN + REWRITE_TAC[UNIONS_0; IMAGE_CLAUSES; EMPTY_SUBSET; CONTINUOUS_ON_EMPTY; + INTER_EMPTY; NOT_IN_EMPTY] THEN + REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_INSERT] THEN + REWRITE_TAC[IMP_IMP; GSYM CONJ_ASSOC; SUBSET_REFL] THEN + MAP_EVERY X_GEN_TAC [`s:real^M->bool`; `u:(real^M->bool)->bool`] THEN + DISCH_THEN(CONJUNCTS_THEN2 MP_TAC + (REPEAT_TCL CONJUNCTS_THEN ASSUME_TAC)) THEN + ASM_SIMP_TAC[UNIONS_INSERT] THEN + DISCH_THEN(X_CHOOSE_THEN `g:real^M->real^N` STRIP_ASSUME_TAC) THEN + ASM_CASES_TAC `(s:real^M->bool) UNION UNIONS u = UNIONS u` THENL + [ASM_REWRITE_TAC[] THEN ASM_MESON_TAC[]; ALL_TAC] THEN + FIRST_X_ASSUM(X_CHOOSE_THEN `f:real^M->real^N` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `\x. if x IN s then (f:real^M->real^N) x else g x` THEN + CONJ_TAC THENL [ALL_TAC; ASM SET_TAC[]] THEN + MATCH_MP_TAC CONTINUOUS_ON_CASES THEN ASM_SIMP_TAC[CLOSED_UNIONS] THEN + ASM SET_TAC[]) in + let lemma = prove + (`!h:real^M->real^N k t f. + (!s. s IN f ==> ?g. g continuous_on s /\ + IMAGE g s SUBSET t /\ + !x. x IN s INTER k ==> g x = h x) /\ + FINITE f /\ (!s. s IN f ==> closed s) /\ + (!s t. s IN f /\ t IN f /\ ~(s SUBSET t) /\ ~(t SUBSET s) + ==> (s INTER t) SUBSET k) + ==> ?g. g continuous_on (UNIONS f) /\ + IMAGE g (UNIONS f) SUBSET t /\ + !x. x IN (UNIONS f) INTER k ==> g x = h x`, + REPEAT STRIP_TAC THEN + FIRST_ASSUM(SUBST1_TAC o SYM o MATCH_MP UNIONS_MAXIMAL_SETS) THEN + MATCH_MP_TAC wemma THEN + ASM_SIMP_TAC[FINITE_RESTRICT; IN_ELIM_THM] THEN ASM SET_TAC[]) in + let zemma = prove + (`!f:real^M->real^N m n t. + FINITE m /\ (!c. c IN m ==> polytope c) /\ + n SUBSET m /\ (!c. c IN m DIFF n ==> aff_dim c < aff_dim t) /\ + (!c1 c2. c1 IN m /\ c2 IN m + ==> (c1 INTER c2) face_of c1 /\ (c1 INTER c2) face_of c2) /\ + convex t /\ bounded t /\ + f continuous_on (UNIONS n) /\ + IMAGE f (UNIONS n) SUBSET relative_frontier t + ==> ?g. g continuous_on (UNIONS m) /\ + IMAGE g (UNIONS m) SUBSET relative_frontier t /\ + (!x. x IN UNIONS n ==> g x = f x)`, + REPEAT STRIP_TAC THEN + ASM_CASES_TAC `m DIFF n:(real^M->bool)->bool = {}` THENL + [SUBGOAL_THEN `(UNIONS m:real^M->bool) SUBSET UNIONS n` ASSUME_TAC THENL + [ASM SET_TAC[]; EXISTS_TAC `f:real^M->real^N`] THEN + REWRITE_TAC[] THEN CONJ_TAC THENL + [ASM_MESON_TAC[CONTINUOUS_ON_SUBSET]; ASM SET_TAC[]]; + ALL_TAC] THEN + SUBGOAL_THEN + `!i. &i <= aff_dim t + ==> ?g. g continuous_on + (UNIONS + (n UNION {d | ?c. c IN m /\ d face_of c /\ + aff_dim d < &i})) /\ + IMAGE g (UNIONS + (n UNION {d | ?c. c IN m /\ d face_of c /\ + aff_dim d < &i})) + SUBSET relative_frontier t /\ + (!x. x IN UNIONS n ==> g x = (f:real^M->real^N) x)` + MP_TAC THENL + [ALL_TAC; + MP_TAC(ISPEC `aff_dim(t:real^N->bool)` INT_OF_NUM_EXISTS) THEN + MATCH_MP_TAC(TAUT `q /\ (p ==> r) ==> (p <=> q) ==> r`) THEN + CONJ_TAC THENL + [ASM_MESON_TAC[AFF_DIM_GE; MEMBER_NOT_EMPTY; + INT_ARITH `--(&1):int <= s /\ s < t ==> &0 <= t`]; + ALL_TAC] THEN + DISCH_THEN(X_CHOOSE_TAC `i:num`) THEN + DISCH_THEN(MP_TAC o SPEC `i:num`) THEN ASM_REWRITE_TAC[INT_LE_REFL] THEN + SUBGOAL_THEN + `UNIONS (n UNION {d | ?c. c IN m /\ d face_of c /\ aff_dim d < &i}) = + UNIONS m:real^M->bool` + (fun th -> REWRITE_TAC[th]) THEN + FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN + MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL + [MATCH_MP_TAC UNIONS_MONO THEN REWRITE_TAC[IN_UNION] THEN + REWRITE_TAC[TAUT `p \/ q ==> r <=> (p ==> r) /\ (q ==> r)`] THEN + REWRITE_TAC[FORALL_AND_THM; FORALL_IN_GSPEC] THEN + CONJ_TAC THENL [ASM_MESON_TAC[SUBSET]; GEN_TAC] THEN + MATCH_MP_TAC MONO_EXISTS THEN SIMP_TAC[FACE_OF_IMP_SUBSET]; + MATCH_MP_TAC SUBSET_UNIONS THEN REWRITE_TAC[SUBSET; IN_UNION] THEN + X_GEN_TAC `d:real^M->bool` THEN DISCH_TAC THEN + ASM_CASES_TAC `(d:real^M->bool) IN n` THEN + ASM_SIMP_TAC[IN_ELIM_THM] THEN + EXISTS_TAC `d:real^M->bool` THEN + ASM_SIMP_TAC[FACE_OF_REFL; POLYTOPE_IMP_CONVEX] THEN + ASM SET_TAC[]]] THEN + MATCH_MP_TAC num_INDUCTION THEN CONJ_TAC THENL + [REWRITE_TAC[INT_ARITH `d < &0 <=> (--(&1) <= d ==> d:int = --(&1))`] THEN + REWRITE_TAC[AFF_DIM_GE; AFF_DIM_EQ_MINUS1] THEN + SUBGOAL_THEN + `{d:real^M->bool| ?c. c IN m /\ d face_of c /\ d = {}} = {{}}` + (fun th -> REWRITE_TAC[th]) + THENL + [GEN_REWRITE_TAC I [EXTENSION] THEN X_GEN_TAC `d:real^M->bool` THEN + REWRITE_TAC[IN_SING; IN_ELIM_THM] THEN + ASM_CASES_TAC `d:real^M->bool = {}` THEN + ASM_REWRITE_TAC[EMPTY_FACE_OF] THEN ASM SET_TAC[]; + REWRITE_TAC[UNIONS_UNION; UNIONS_1; UNION_EMPTY] THEN + ASM_MESON_TAC[]]; + ALL_TAC] THEN + X_GEN_TAC `p:num` THEN REWRITE_TAC[GSYM INT_OF_NUM_SUC] THEN + REWRITE_TAC[INT_ARITH `p + &1 <= x <=> p:int < x`] THEN + DISCH_THEN(fun th -> DISCH_TAC THEN MP_TAC th) THEN + ASM_SIMP_TAC[INT_LT_IMP_LE] THEN + DISCH_THEN(X_CHOOSE_THEN `h:real^M->real^N` STRIP_ASSUME_TAC) THEN + REWRITE_TAC[INT_ARITH `x:int < p + &1 <=> x <= p`] THEN + SUBGOAL_THEN `~(t:real^N->bool = {})` ASSUME_TAC THENL + [ASM_MESON_TAC[AFF_DIM_EMPTY; INT_ARITH `~(&p:int < --(&1))`]; + ALL_TAC] THEN + SUBGOAL_THEN `~(relative_frontier t:real^N->bool = {})` ASSUME_TAC THENL + [ASM_REWRITE_TAC[RELATIVE_FRONTIER_EQ_EMPTY] THEN DISCH_TAC THEN + MP_TAC(ISPEC `t:real^N->bool` AFFINE_BOUNDED_EQ_LOWDIM) THEN + ASM_REWRITE_TAC[] THEN ASM_INT_ARITH_TAC; + ALL_TAC] THEN + SUBGOAL_THEN + `!d. d IN n UNION {d | ?c. c IN m /\ d face_of c /\ aff_dim d <= &p} + ==> ?g. (g:real^M->real^N) continuous_on d /\ + IMAGE g d SUBSET relative_frontier t /\ + !x. x IN d INTER + UNIONS + (n UNION {d | ?c. c IN m /\ d face_of c /\ aff_dim d < &p}) + ==> g x = h x` + MP_TAC THENL + [X_GEN_TAC `d:real^M->bool` THEN + ASM_CASES_TAC `(d:real^M->bool) SUBSET UNIONS + (n UNION {d | ?c. c IN m /\ d face_of c /\ aff_dim d < &p})` + THENL + [DISCH_THEN(K ALL_TAC) THEN EXISTS_TAC `h:real^M->real^N` THEN + REWRITE_TAC[] THEN CONJ_TAC THENL + [ASM_MESON_TAC[CONTINUOUS_ON_SUBSET]; ASM SET_TAC[]]; + ALL_TAC] THEN + ASM_CASES_TAC `?a:real^M. d = {a}` THENL + [FIRST_X_ASSUM(X_CHOOSE_THEN `a:real^M` SUBST_ALL_TAC) THEN + DISCH_THEN(K ALL_TAC) THEN ASM_SIMP_TAC[CONTINUOUS_ON_SING; SET_RULE + `~({a} SUBSET s) ==> ~(x IN {a} INTER s)`] THEN + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; + FORALL_IN_INSERT; NOT_IN_EMPTY] THEN + MATCH_MP_TAC(MESON[] `(?c. P(\x. c)) ==> (?f. P f)`) THEN + ASM SET_TAC[]; + ALL_TAC] THEN + SUBGOAL_THEN `~(d:real^M->bool = {})` ASSUME_TAC THENL + [ASM SET_TAC[]; ALL_TAC] THEN + FIRST_ASSUM(MP_TAC o MATCH_MP (SET_RULE + `~(s SUBSET UNIONS f) ==> ~(s IN f)`)) THEN + REWRITE_TAC[IMP_IMP] THEN DISCH_THEN(MP_TAC o MATCH_MP + (SET_RULE `~(d IN s UNION t) /\ d IN s UNION u + ==> ~(d IN s) /\ d IN u DIFF t`)) THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + DISCH_THEN(MP_TAC o MATCH_MP (SET_RULE + `d IN + {d | ?c. c IN m /\ d face_of c /\ aff_dim d <= &p} DIFF + {d | ?c. c IN m /\ d face_of c /\ aff_dim d < &p} + ==> ?c. c IN m /\ d face_of c /\ + (aff_dim d <= &p /\ ~(aff_dim d < &p))`)) THEN + REWRITE_TAC[INT_ARITH `d:int <= p /\ ~(d < p) <=> d = p`] THEN + DISCH_THEN(X_CHOOSE_THEN `c:real^M->bool` STRIP_ASSUME_TAC) THEN + MP_TAC(ISPECL [`h:real^M->real^N`; `relative_frontier d:real^M->bool`; + `t:real^N->bool`] NULLHOMOTOPIC_INTO_RELATIVE_FRONTIER_EXTENSION) THEN + ASM_REWRITE_TAC[CLOSED_RELATIVE_FRONTIER; + RELATIVE_FRONTIER_EQ_EMPTY] THEN + SUBGOAL_THEN + `relative_frontier d SUBSET + UNIONS {e:real^M->bool | e face_of c /\ aff_dim e < &p}` + ASSUME_TAC THENL + [W(MP_TAC o PART_MATCH (lhs o rand) RELATIVE_FRONTIER_OF_POLYHEDRON o + lhand o snd) THEN + ANTS_TAC THENL + [ASM_MESON_TAC[POLYTOPE_IMP_POLYHEDRON; FACE_OF_POLYTOPE_POLYTOPE]; + DISCH_THEN SUBST1_TAC] THEN + MATCH_MP_TAC SUBSET_UNIONS THEN + ASM_SIMP_TAC[SUBSET; FORALL_IN_GSPEC; IN_ELIM_THM; facet_of] THEN + X_GEN_TAC `f:real^M->bool` THEN REPEAT STRIP_TAC THENL + [ASM_MESON_TAC[FACE_OF_TRANS]; INT_ARITH_TAC]; + ALL_TAC] THEN + ANTS_TAC THENL + [REPEAT CONJ_TAC THENL + [FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET)) THEN + ASM SET_TAC[]; + ASM_MESON_TAC[AFFINE_BOUNDED_EQ_TRIVIAL; FACE_OF_POLYTOPE_POLYTOPE; + POLYTOPE_IMP_BOUNDED]; + ASM SET_TAC[]]; + ALL_TAC] THEN + MATCH_MP_TAC(TAUT `p /\ (q ==> r) ==> (p <=> q) ==> r`) THEN + CONJ_TAC THENL + [MATCH_MP_TAC INESSENTIAL_SPHEREMAP_LOWDIM_GEN THEN + ASM_REWRITE_TAC[] THEN REPEAT CONJ_TAC THENL + [ASM_MESON_TAC[FACE_OF_POLYTOPE_POLYTOPE; POLYTOPE_IMP_CONVEX]; + ASM_MESON_TAC[FACE_OF_POLYTOPE_POLYTOPE; POLYTOPE_IMP_BOUNDED]; + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET)) THEN + ASM SET_TAC[]; + ASM SET_TAC[]]; + MATCH_MP_TAC MONO_EXISTS] THEN + X_GEN_TAC `g:real^M->real^N` THEN STRIP_TAC THEN REPEAT CONJ_TAC THENL + [ASM_MESON_TAC[CONTINUOUS_ON_SUBSET; SUBSET_UNIV]; + ASM SET_TAC[]; + ALL_TAC] THEN + REWRITE_TAC[INTER_UNIONS] THEN FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP + (SET_RULE `(!x. x IN s ==> P x) ==> t SUBSET s + ==> !x. x IN t ==> P x`)) THEN + REWRITE_TAC[UNIONS_SUBSET; FORALL_IN_GSPEC] THEN + X_GEN_TAC `e:real^M->bool` THEN DISCH_TAC THEN + MATCH_MP_TAC FACE_OF_SUBSET_RELATIVE_FRONTIER THEN CONJ_TAC THENL + [MATCH_MP_TAC(MESON[] + `(d INTER e) face_of d /\ (d INTER e) face_of e + ==> (d INTER e) face_of d`) THEN + MATCH_MP_TAC FACE_OF_INTER_SUBFACE THEN + EXISTS_TAC `c:real^M->bool` THEN ASM_REWRITE_TAC[] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_UNION]) THEN + REWRITE_TAC[IN_ELIM_THM] THEN + STRIP_TAC THENL [ALL_TAC; ASM_MESON_TAC[]] THEN + ASM_MESON_TAC[FACE_OF_REFL; SUBSET; POLYTOPE_IMP_CONVEX]; + REWRITE_TAC[SET_RULE `d INTER e = d <=> d SUBSET e`] THEN + DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_UNION]) THEN + REWRITE_TAC[IN_ELIM_THM] THEN + DISCH_THEN(DISJ_CASES_THEN MP_TAC) THENL [ASM SET_TAC[]; ALL_TAC] THEN + ASM_MESON_TAC[AFF_DIM_SUBSET; INT_NOT_LE]]; + ALL_TAC] THEN + DISCH_THEN(MP_TAC o MATCH_MP (ONCE_REWRITE_RULE[IMP_CONJ] lemma)) THEN + ANTS_TAC THENL + [ALL_TAC; + MATCH_MP_TAC MONO_EXISTS THEN SIMP_TAC[] THEN ASM SET_TAC[]] THEN + CONJ_TAC THENL + [REWRITE_TAC[FINITE_UNION] THEN + CONJ_TAC THENL [ASM_MESON_TAC[FINITE_SUBSET]; ALL_TAC] THEN + MATCH_MP_TAC FINITE_SUBSET THEN + EXISTS_TAC `UNIONS {{d:real^M->bool | d face_of c} | c IN m}` THEN + CONJ_TAC THENL + [REWRITE_TAC[FINITE_UNIONS; FORALL_IN_GSPEC] THEN + ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN ASM_SIMP_TAC[FINITE_IMAGE] THEN + ASM_MESON_TAC[FINITE_POLYTOPE_FACES]; + REWRITE_TAC[UNIONS_GSPEC] THEN SET_TAC[]]; + ALL_TAC] THEN + CONJ_TAC THENL + [REWRITE_TAC[IN_UNION; IN_ELIM_THM] THEN + ASM_MESON_TAC[FACE_OF_IMP_CLOSED; POLYTOPE_IMP_CLOSED; + POLYTOPE_IMP_CONVEX; SUBSET]; + ALL_TAC] THEN + MAP_EVERY X_GEN_TAC [`d:real^M->bool`; `e:real^M->bool`] THEN + REWRITE_TAC[IN_UNION; IN_ELIM_THM] THEN + DISCH_THEN(CONJUNCTS_THEN2 (DISJ_CASES_THEN2 ASSUME_TAC + (X_CHOOSE_THEN `c:real^M->bool` STRIP_ASSUME_TAC)) MP_TAC) + THENL [ASM SET_TAC[]; ALL_TAC] THEN + DISCH_THEN(CONJUNCTS_THEN2 (DISJ_CASES_THEN2 ASSUME_TAC + (X_CHOOSE_THEN `k:real^M->bool` STRIP_ASSUME_TAC)) MP_TAC) + THENL [ASM SET_TAC[]; STRIP_TAC] THEN + REWRITE_TAC[UNIONS_UNION] THEN + MATCH_MP_TAC(SET_RULE `s SUBSET u ==> s SUBSET t UNION u`) THEN + MATCH_MP_TAC(SET_RULE `x IN s ==> x SUBSET UNIONS s`) THEN + REWRITE_TAC[IN_ELIM_THM] THEN EXISTS_TAC `c:real^M->bool` THEN + ASM_REWRITE_TAC[] THEN + SUBGOAL_THEN `d INTER e face_of (d:real^M->bool) /\ + d INTER e face_of e` + STRIP_ASSUME_TAC THENL [ASM_MESON_TAC[FACE_OF_INTER_SUBFACE]; ALL_TAC] THEN + CONJ_TAC THENL [ASM_MESON_TAC[FACE_OF_TRANS]; ALL_TAC] THEN + TRANS_TAC INT_LTE_TRANS `aff_dim(d:real^M->bool)` THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC FACE_OF_AFF_DIM_LT THEN + ASM_REWRITE_TAC[] THEN CONJ_TAC THENL + [ASM_MESON_TAC[POLYTOPE_IMP_CONVEX; FACE_OF_IMP_CONVEX]; + ASM SET_TAC[]]) in + let memma = prove + (`!h:real^M->real^N k t u f. + (!s. s IN f ==> ?a g. ~(a IN u) /\ g continuous_on (s DELETE a) /\ + IMAGE g (s DELETE a) SUBSET t /\ + !x. x IN s INTER k ==> g x = h x) /\ + FINITE f /\ (!s. s IN f ==> closed s) /\ + (!s t. s IN f /\ t IN f /\ ~(s = t) ==> (s INTER t) SUBSET k) + ==> ?c g. FINITE c /\ DISJOINT c u /\ CARD c <= CARD f /\ + g continuous_on (UNIONS f DIFF c) /\ + IMAGE g (UNIONS f DIFF c) SUBSET t /\ + !x. x IN (UNIONS f DIFF c) INTER k ==> g x = h x`, + REPLICATE_TAC 4 GEN_TAC THEN + ONCE_REWRITE_TAC[TAUT `p /\ q /\ r ==> s <=> q ==> p /\ r ==> s`] THEN + MATCH_MP_TAC FINITE_INDUCT_STRONG THEN + REWRITE_TAC[UNIONS_0; IMAGE_CLAUSES; EMPTY_SUBSET; CONTINUOUS_ON_EMPTY; + INTER_EMPTY; NOT_IN_EMPTY; EMPTY_DIFF] THEN + CONJ_TAC THENL + [MESON_TAC[DISJOINT_EMPTY; FINITE_EMPTY; CARD_CLAUSES; LE_REFL]; + ALL_TAC] THEN + REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_INSERT] THEN + REWRITE_TAC[IMP_IMP; GSYM CONJ_ASSOC; SUBSET_REFL] THEN + MAP_EVERY X_GEN_TAC [`s:real^M->bool`; `u:(real^M->bool)->bool`] THEN + DISCH_THEN(CONJUNCTS_THEN2 MP_TAC + (REPEAT_TCL CONJUNCTS_THEN ASSUME_TAC)) THEN + ASM_SIMP_TAC[UNIONS_INSERT] THEN REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`c:real^M->bool`; `g:real^M->real^N`] THEN + STRIP_TAC THEN ASM_SIMP_TAC[CARD_CLAUSES] THEN + ASM_CASES_TAC `(s:real^M->bool) UNION UNIONS u = UNIONS u` THENL + [ASM_SIMP_TAC[] THEN ASM_MESON_TAC[ARITH_RULE `x <= y ==> x <= SUC y`]; + ALL_TAC] THEN + FIRST_X_ASSUM(X_CHOOSE_THEN `a:real^M` + (X_CHOOSE_THEN `f:real^M->real^N` STRIP_ASSUME_TAC)) THEN + EXISTS_TAC `(a:real^M) INSERT c` THEN + ASM_SIMP_TAC[CARD_CLAUSES; FINITE_INSERT; RIGHT_EXISTS_AND_THM] THEN + REPEAT CONJ_TAC THENL [ASM SET_TAC[]; ASM_ARITH_TAC; ALL_TAC] THEN + EXISTS_TAC `\x. if x IN s then (f:real^M->real^N) x else g x` THEN + CONJ_TAC THENL [ALL_TAC; ASM SET_TAC[]] THEN + MATCH_MP_TAC CONTINUOUS_ON_SUBSET THEN + EXISTS_TAC `(s DIFF ((a:real^M) INSERT c)) UNION + (UNIONS u DIFF ((a:real^M) INSERT c))` THEN + CONJ_TAC THENL [ALL_TAC; ASM SET_TAC[]] THEN + MATCH_MP_TAC CONTINUOUS_ON_CASES_LOCAL THEN REPEAT CONJ_TAC THENL + [REWRITE_TAC[CLOSED_IN_CLOSED] THEN + EXISTS_TAC `s:real^M->bool` THEN ASM_REWRITE_TAC[]; + REWRITE_TAC[CLOSED_IN_CLOSED] THEN + EXISTS_TAC `UNIONS u:real^M->bool` THEN ASM_SIMP_TAC[CLOSED_UNIONS]; + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET)); + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET)); + ALL_TAC] THEN + ASM SET_TAC[]) in + let temma = prove + (`!h:real^M->real^N k t u f. + (!s. s IN f ==> ?a g. ~(a IN u) /\ g continuous_on (s DELETE a) /\ + IMAGE g (s DELETE a) SUBSET t /\ + !x. x IN s INTER k ==> g x = h x) /\ + FINITE f /\ (!s. s IN f ==> closed s) /\ + (!s t. s IN f /\ t IN f /\ ~(s SUBSET t) /\ ~(t SUBSET s) + ==> (s INTER t) SUBSET k) + ==> ?c g. FINITE c /\ DISJOINT c u /\ CARD c <= CARD f /\ + g continuous_on (UNIONS f DIFF c) /\ + IMAGE g (UNIONS f DIFF c) SUBSET t /\ + !x. x IN (UNIONS f DIFF c) INTER k ==> g x = h x`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`h:real^M->real^N`; `k:real^M->bool`; `t:real^N->bool`; + `u:real^M->bool`; + `{t:real^M->bool | t IN f /\ + (!u. u IN f ==> ~(t PSUBSET u))}`] + memma) THEN + ASM_SIMP_TAC[FINITE_RESTRICT; IN_ELIM_THM; UNIONS_MAXIMAL_SETS] THEN + ANTS_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + REPEAT(MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC) THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + LE_TRANS)) THEN + MATCH_MP_TAC CARD_SUBSET THEN + ASM_SIMP_TAC[] THEN SET_TAC[]) in + let bemma = prove + (`!f:real^M->real^N m n t. + FINITE m /\ (!c. c IN m ==> polytope c) /\ + n SUBSET m /\ (!c. c IN m DIFF n ==> aff_dim c <= aff_dim t) /\ + (!c1 c2. c1 IN m /\ c2 IN m + ==> (c1 INTER c2) face_of c1 /\ (c1 INTER c2) face_of c2) /\ + convex t /\ bounded t /\ + f continuous_on (UNIONS n) /\ + IMAGE f (UNIONS n) SUBSET relative_frontier t + ==> ?k g. FINITE k /\ DISJOINT k (UNIONS n) /\ CARD k <= CARD m /\ + g continuous_on (UNIONS m DIFF k) /\ + IMAGE g (UNIONS m DIFF k) SUBSET relative_frontier t /\ + (!x. x IN UNIONS n ==> g x = f x)`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`f:real^M->real^N`; + `n UNION {d:real^M->bool | ?c. c IN m DIFF n /\ d face_of c /\ + aff_dim d < aff_dim(t:real^N->bool)}`; + `n:(real^M->bool)->bool`; `t:real^N->bool`] zemma) THEN + ASM_REWRITE_TAC[SUBSET_UNION; SET_RULE + `(n UNION m) DIFF n = m DIFF n`] THEN + SIMP_TAC[IN_DIFF; IN_ELIM_THM; LEFT_IMP_EXISTS_THM; + LEFT_AND_EXISTS_THM] THEN + ANTS_TAC THENL + [REPEAT CONJ_TAC THENL + [ASM_REWRITE_TAC[FINITE_UNION] THEN + CONJ_TAC THENL [ASM_MESON_TAC[FINITE_SUBSET]; ALL_TAC] THEN + MATCH_MP_TAC FINITE_SUBSET THEN + EXISTS_TAC `UNIONS {{d:real^M->bool | d face_of c} | c IN m}` THEN + CONJ_TAC THENL + [REWRITE_TAC[FINITE_UNIONS; FORALL_IN_GSPEC] THEN + ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN ASM_SIMP_TAC[FINITE_IMAGE] THEN + ASM_MESON_TAC[FINITE_POLYTOPE_FACES]; + REWRITE_TAC[UNIONS_GSPEC] THEN SET_TAC[]]; + REWRITE_TAC[IN_UNION; IN_ELIM_THM] THEN + ASM_MESON_TAC[FACE_OF_POLYTOPE_POLYTOPE; SUBSET]; + REWRITE_TAC[IN_UNION; IN_ELIM_THM] THEN + ASM_MESON_TAC[FACE_OF_INTER_SUBFACE; SUBSET; FACE_OF_REFL; + POLYTOPE_IMP_CONVEX; FACE_OF_IMP_CONVEX]]; + ALL_TAC] THEN + DISCH_THEN(X_CHOOSE_THEN `h:real^M->real^N` STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN + `!d. d IN m + ==> ?a g. ~(a IN UNIONS n) /\ + (g:real^M->real^N) continuous_on (d DELETE a) /\ + IMAGE g (d DELETE a) SUBSET relative_frontier t /\ + !x. x IN d INTER + UNIONS + (n UNION {d | ?c. (c IN m /\ ~(c IN n)) /\ + d face_of c /\ + aff_dim d < aff_dim t}) + ==> g x = h x` + MP_TAC THENL + [X_GEN_TAC `d:real^M->bool` THEN DISCH_TAC THEN + ASM_CASES_TAC `(d:real^M->bool) SUBSET + UNIONS(n UNION {d | ?c. (c IN m /\ ~(c IN n)) /\ + d face_of c /\ + aff_dim d < aff_dim(t:real^N->bool)})` + THENL + [SUBGOAL_THEN `~(UNIONS n = (:real^M))` MP_TAC THENL + [MATCH_MP_TAC(MESON[NOT_BOUNDED_UNIV] + `bounded s ==> ~(s = UNIV)`) THEN + MATCH_MP_TAC BOUNDED_UNIONS THEN + ASM_MESON_TAC[POLYTOPE_IMP_BOUNDED; SUBSET; FINITE_SUBSET]; + GEN_REWRITE_TAC (LAND_CONV o RAND_CONV) [EXTENSION]] THEN + REWRITE_TAC[IN_UNIV; NOT_FORALL_THM] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `a:real^M` THEN + STRIP_TAC THEN EXISTS_TAC `h:real^M->real^N` THEN + ASM_REWRITE_TAC[] THEN CONJ_TAC THENL + [ASM_MESON_TAC[CONTINUOUS_ON_SUBSET; + SET_RULE `s SUBSET t ==> s DELETE a SUBSET t`]; + ASM SET_TAC[]]; + ALL_TAC] THEN + ASM_CASES_TAC `(d:real^M->bool) IN n` THENL [ASM SET_TAC[]; ALL_TAC] THEN + DISJ_CASES_THEN MP_TAC (SPEC + `relative_interior(d:real^M->bool) = {}` EXCLUDED_MIDDLE) + THENL + [ASM_SIMP_TAC[RELATIVE_INTERIOR_EQ_EMPTY; POLYTOPE_IMP_CONVEX] THEN + ASM SET_TAC[]; + REWRITE_TAC[GSYM MEMBER_NOT_EMPTY]] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `a:real^M` THEN STRIP_TAC THEN + SUBGOAL_THEN + `relative_frontier d SUBSET + UNIONS {e:real^M->bool | e face_of d /\ + aff_dim e < aff_dim(t:real^N->bool)}` + ASSUME_TAC THENL + [W(MP_TAC o PART_MATCH (lhs o rand) RELATIVE_FRONTIER_OF_POLYHEDRON o + lhand o snd) THEN + ANTS_TAC THENL + [ASM_MESON_TAC[POLYTOPE_IMP_POLYHEDRON; FACE_OF_POLYTOPE_POLYTOPE]; + DISCH_THEN SUBST1_TAC] THEN + MATCH_MP_TAC SUBSET_UNIONS THEN + ASM_SIMP_TAC[SUBSET; FORALL_IN_GSPEC; IN_ELIM_THM; facet_of] THEN + ASM_SIMP_TAC[INT_ARITH `d - &1:int < t <=> d <= t`; IN_DIFF]; + ALL_TAC] THEN + MP_TAC(ISPECL [`d:real^M->bool`; `a:real^M`] + RELATIVE_FRONTIER_RETRACT_OF_PUNCTURED_AFFINE_HULL) THEN + ASM_SIMP_TAC[POLYTOPE_IMP_CONVEX; POLYTOPE_IMP_BOUNDED] THEN + REWRITE_TAC[retract_of; LEFT_IMP_EXISTS_THM; retraction] THEN + X_GEN_TAC `r:real^M->real^M` THEN STRIP_TAC THEN + EXISTS_TAC `(h:real^M->real^N) o (r:real^M->real^M)` THEN + REPEAT CONJ_TAC THENL + [REWRITE_TAC[IN_UNIONS] THEN + DISCH_THEN(X_CHOOSE_THEN `e:real^M->bool` STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN + `e INTER d face_of e /\ e INTER d face_of (d:real^M->bool)` + MP_TAC THENL [ASM_MESON_TAC[SUBSET]; ALL_TAC] THEN + DISCH_THEN(MP_TAC o MATCH_MP + (REWRITE_RULE[IMP_CONJ] FACE_OF_SUBSET_RELATIVE_FRONTIER) o + CONJUNCT2) THEN + REWRITE_TAC[NOT_IMP; relative_frontier] THEN + MP_TAC(ISPEC `d:real^M->bool` RELATIVE_INTERIOR_SUBSET) THEN + ASM SET_TAC[]; + MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN CONJ_TAC THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET)) THEN + SIMP_TAC[HULL_SUBSET; SET_RULE + `s SUBSET t ==> s DELETE a SUBSET t DELETE a`]; + REWRITE_TAC[IMAGE_o] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE + `IMAGE h t SUBSET u ==> s SUBSET t ==> IMAGE h s SUBSET u`)); + SIMP_TAC[INTER_UNIONS; o_THM] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP + (SET_RULE `(!x. x IN s ==> r x = x) ==> t SUBSET s + ==> !x. x IN t ==> h(r x) = h x`)) THEN + REWRITE_TAC[UNIONS_SUBSET; FORALL_IN_GSPEC] THEN + X_GEN_TAC `e:real^M->bool` THEN DISCH_TAC THEN + MATCH_MP_TAC FACE_OF_SUBSET_RELATIVE_FRONTIER THEN + CONJ_TAC THENL [ALL_TAC; ASM SET_TAC[]] THEN + MATCH_MP_TAC(MESON[] + `(d INTER e) face_of d /\ (d INTER e) face_of e + ==> (d INTER e) face_of d`) THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_UNION]) THEN + REWRITE_TAC[IN_ELIM_THM] THEN STRIP_TAC THENL + [ASM_MESON_TAC[SUBSET]; ALL_TAC] THEN + MATCH_MP_TAC FACE_OF_INTER_SUBFACE THEN + MAP_EVERY EXISTS_TAC [`d:real^M->bool`; `c:real^M->bool`] THEN + ASM_SIMP_TAC[FACE_OF_REFL; POLYTOPE_IMP_CONVEX]] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE + `IMAGE r (h DELETE a) SUBSET t ==> d SUBSET h /\ t SUBSET u + ==> IMAGE r (d DELETE a) SUBSET u`)) THEN + REWRITE_TAC[HULL_SUBSET] THEN ASM SET_TAC[]; + ALL_TAC] THEN + DISCH_THEN(MP_TAC o MATCH_MP (ONCE_REWRITE_RULE[IMP_CONJ] temma)) THEN + ANTS_TAC THENL + [ALL_TAC; + REPEAT(MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC) THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN ASM SET_TAC[]] THEN + ASM_SIMP_TAC[POLYTOPE_IMP_CLOSED] THEN + MAP_EVERY X_GEN_TAC [`d:real^M->bool`; `e:real^M->bool`] THEN + STRIP_TAC THEN REWRITE_TAC[UNIONS_UNION] THEN + ASM_CASES_TAC `(d:real^M->bool) IN n` THENL [ASM SET_TAC[]; ALL_TAC] THEN + MATCH_MP_TAC(SET_RULE `x IN s ==> x SUBSET t UNION UNIONS s`) THEN + REWRITE_TAC[IN_ELIM_THM] THEN EXISTS_TAC `d:real^M->bool` THEN + ASM_REWRITE_TAC[] THEN + ASM_CASES_TAC `d INTER e:real^M->bool = d` THENL + [ASM SET_TAC[]; ALL_TAC] THEN + ASM_SIMP_TAC[] THEN TRANS_TAC INT_LTE_TRANS `aff_dim(d:real^M->bool)` THEN + ASM_SIMP_TAC[IN_DIFF] THEN MATCH_MP_TAC FACE_OF_AFF_DIM_LT THEN + ASM_MESON_TAC[POLYTOPE_IMP_CONVEX]) in + CONJ_TAC THENL + [REPEAT STRIP_TAC THEN + SUBGOAL_THEN `compact(s:real^M->bool)` ASSUME_TAC THENL + [ASM_SIMP_TAC[COMPACT_EQ_BOUNDED_CLOSED] THEN + ASM_MESON_TAC[BOUNDED_SUBSET; BOUNDED_UNIONS; POLYTOPE_IMP_BOUNDED]; + ALL_TAC] THEN + MP_TAC(ISPECL [`f:real^M->real^N`; `s:real^M->bool`; + `relative_frontier t:real^N->bool`] + NEIGHBOURHOOD_EXTENSION_INTO_ANR) THEN + ASM_SIMP_TAC[LEFT_FORALL_IMP_THM; ANR_RELATIVE_FRONTIER_CONVEX] THEN + REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`v:real^M->bool`; `g:real^M->real^N`] THEN + STRIP_TAC THEN + MP_TAC(ISPECL [`s:real^M->bool`; `(:real^M) DIFF v`] + SEPARATE_COMPACT_CLOSED) THEN + ASM_SIMP_TAC[GSYM OPEN_CLOSED; IN_DIFF; IN_UNIV] THEN + ANTS_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + ONCE_REWRITE_TAC[TAUT `p /\ ~q ==> r <=> p /\ ~r ==> q`] THEN + REWRITE_TAC[REAL_NOT_LE; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `d:real` THEN STRIP_TAC THEN + MP_TAC(ISPECL [`m:(real^M->bool)->bool`; `aff_dim(t:real^N->bool) - &1`; + `d:real`] CELL_COMPLEX_SUBDIVISION_EXISTS) THEN + ASM_SIMP_TAC[INT_ARITH `x:int <= t - &1 <=> x < t`] THEN + DISCH_THEN(X_CHOOSE_THEN `n:(real^M->bool)->bool` STRIP_ASSUME_TAC) THEN + MP_TAC(ISPECL + [`g:real^M->real^N`; `n:(real^M->bool)->bool`; + `{c:real^M->bool | c IN n /\ c SUBSET v}`; `t:real^N->bool`] + zemma) THEN + ASM_REWRITE_TAC[] THEN ANTS_TAC THENL + [ASM_SIMP_TAC[SUBSET_RESTRICT; IN_DIFF] THEN CONJ_TAC THENL + [FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET)) THEN + ASM SET_TAC[]; + ASM SET_TAC[]]; + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `h:real^M->real^N` THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN X_GEN_TAC `x:real^M` THEN + DISCH_TAC THEN TRANS_TAC EQ_TRANS `(g:real^M->real^N) x` THEN + CONJ_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[] THEN + SUBGOAL_THEN `(x:real^M) IN UNIONS n` MP_TAC THENL + [ASM SET_TAC[]; ALL_TAC] THEN + REWRITE_TAC[IN_UNIONS] THEN MATCH_MP_TAC MONO_EXISTS THEN + X_GEN_TAC `c:real^M->bool` THEN STRIP_TAC THEN + ASM_REWRITE_TAC[IN_ELIM_THM] THEN REWRITE_TAC[SUBSET] THEN + X_GEN_TAC `y:real^M` THEN DISCH_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + EXISTS_TAC `x:real^M` THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC REAL_LET_TRANS THEN + EXISTS_TAC `diameter(c:real^M->bool)` THEN + ASM_SIMP_TAC[dist] THEN MATCH_MP_TAC DIAMETER_BOUNDED_BOUND THEN + ASM_SIMP_TAC[POLYTOPE_IMP_BOUNDED]]; + REPEAT STRIP_TAC THEN + SUBGOAL_THEN `compact(s:real^M->bool)` ASSUME_TAC THENL + [ASM_SIMP_TAC[COMPACT_EQ_BOUNDED_CLOSED] THEN + ASM_MESON_TAC[BOUNDED_SUBSET; BOUNDED_UNIONS; POLYTOPE_IMP_BOUNDED]; + ALL_TAC] THEN + MP_TAC(ISPECL [`f:real^M->real^N`; `s:real^M->bool`; + `relative_frontier t:real^N->bool`] + NEIGHBOURHOOD_EXTENSION_INTO_ANR) THEN + ASM_SIMP_TAC[LEFT_FORALL_IMP_THM; ANR_RELATIVE_FRONTIER_CONVEX] THEN + REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`v:real^M->bool`; `g:real^M->real^N`] THEN + STRIP_TAC THEN + MP_TAC(ISPECL [`s:real^M->bool`; `(:real^M) DIFF v`] + SEPARATE_COMPACT_CLOSED) THEN + ASM_SIMP_TAC[GSYM OPEN_CLOSED; IN_DIFF; IN_UNIV] THEN + ANTS_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + ONCE_REWRITE_TAC[TAUT `p /\ ~q ==> r <=> p /\ ~r ==> q`] THEN + REWRITE_TAC[REAL_NOT_LE; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `d:real` THEN STRIP_TAC THEN + MP_TAC(ISPECL [`m:(real^M->bool)->bool`; `aff_dim(t:real^N->bool)`; + `d:real`] CELL_COMPLEX_SUBDIVISION_EXISTS) THEN + ASM_SIMP_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `n:(real^M->bool)->bool` STRIP_ASSUME_TAC) THEN + MP_TAC(ISPECL + [`g:real^M->real^N`; `n:(real^M->bool)->bool`; + `{c:real^M->bool | c IN n /\ c SUBSET v}`; `t:real^N->bool`] + bemma) THEN + ASM_REWRITE_TAC[] THEN ANTS_TAC THENL + [ASM_SIMP_TAC[SUBSET_RESTRICT; IN_DIFF] THEN CONJ_TAC THENL + [FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET)) THEN + ASM SET_TAC[]; + ASM SET_TAC[]]; + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `k:real^M->bool` THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `h:real^M->real^N` THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN CONJ_TAC THENL + [FIRST_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE + `DISJOINT k u ==> s SUBSET u ==> DISJOINT k s`)) THEN + REWRITE_TAC[SUBSET] THEN X_GEN_TAC `x:real^M` THEN DISCH_TAC; + X_GEN_TAC `x:real^M` THEN + DISCH_TAC THEN TRANS_TAC EQ_TRANS `(g:real^M->real^N) x` THEN + CONJ_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[]] THEN + (SUBGOAL_THEN `(x:real^M) IN UNIONS n` MP_TAC THENL + [ASM SET_TAC[]; ALL_TAC] THEN + REWRITE_TAC[IN_UNIONS] THEN MATCH_MP_TAC MONO_EXISTS THEN + X_GEN_TAC `c:real^M->bool` THEN STRIP_TAC THEN + ASM_REWRITE_TAC[IN_ELIM_THM] THEN REWRITE_TAC[SUBSET] THEN + X_GEN_TAC `y:real^M` THEN DISCH_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + EXISTS_TAC `x:real^M` THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC REAL_LET_TRANS THEN + EXISTS_TAC `diameter(c:real^M->bool)` THEN + ASM_SIMP_TAC[dist] THEN MATCH_MP_TAC DIAMETER_BOUNDED_BOUND THEN + ASM_SIMP_TAC[POLYTOPE_IMP_BOUNDED])]]);; + +(* ------------------------------------------------------------------------- *) +(* Special cases and corollaries involving spheres. *) +(* ------------------------------------------------------------------------- *) + +let EXTEND_MAP_AFFINE_TO_SPHERE_COFINITE_SIMPLE = prove + (`!f:real^M->real^N s t u. + compact s /\ convex u /\ bounded u /\ aff_dim t <= aff_dim u /\ + s SUBSET t /\ f continuous_on s /\ IMAGE f s SUBSET relative_frontier u + ==> ?k g. FINITE k /\ k SUBSET t /\ DISJOINT k s /\ + g continuous_on (t DIFF k) /\ + IMAGE g (t DIFF k) SUBSET relative_frontier u /\ + !x. x IN s ==> g x = f x`, + let lemma = prove + (`!f:A->B->bool P k. + INFINITE {x | P x} /\ FINITE k /\ + (!x y. P x /\ P y /\ ~(x = y) ==> DISJOINT (f x) (f y)) + ==> ?x. P x /\ DISJOINT k (f x)`, + REWRITE_TAC[INFINITE] THEN REPEAT STRIP_TAC THEN + REWRITE_TAC[SET_RULE `(?x. P x /\ DISJOINT k (f x)) <=> + ~(!x. ?y. P x ==> y IN k /\ y IN f x)`] THEN + REWRITE_TAC[SKOLEM_THM] THEN + DISCH_THEN(X_CHOOSE_TAC `g:A->B`) THEN + MP_TAC(ISPECL [`g:A->B`; `{x:A | P x}`] FINITE_IMAGE_INJ_EQ) THEN + ASM_REWRITE_TAC[IN_ELIM_THM; NOT_IMP] THEN + CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP + (REWRITE_RULE[IMP_CONJ] FINITE_SUBSET)) THEN + ASM SET_TAC[]) in + SUBGOAL_THEN + `!f:real^M->real^N s t u. + compact s /\ convex u /\ bounded u /\ aff_dim t <= aff_dim u /\ + s SUBSET t /\ f continuous_on s /\ IMAGE f s SUBSET relative_frontier u + ==> ?k g. FINITE k /\ DISJOINT k s /\ + g continuous_on (t DIFF k) /\ + IMAGE g (t DIFF k) SUBSET relative_frontier u /\ + !x. x IN s ==> g x = f x` + MP_TAC THENL + [ALL_TAC; + REPEAT(MATCH_MP_TAC MONO_FORALL THEN GEN_TAC) THEN + DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN + ASM_REWRITE_TAC[] THEN ONCE_REWRITE_TAC[SWAP_EXISTS_THM] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `g:real^M->real^N` THEN + DISCH_THEN(X_CHOOSE_THEN `k:real^M->bool` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `k INTER t:real^M->bool` THEN + ASM_SIMP_TAC[FINITE_INTER; INTER_SUBSET] THEN + REPEAT CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC; ASM SET_TAC[]] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET)) THEN ASM SET_TAC[]] THEN + SUBGOAL_THEN + `!f:real^M->real^N s t u. + compact s /\ s SUBSET t /\ affine t /\ + convex u /\ bounded u /\ aff_dim t <= aff_dim u /\ + f continuous_on s /\ IMAGE f s SUBSET relative_frontier u + ==> ?k g. FINITE k /\ DISJOINT k s /\ + g continuous_on (t DIFF k) /\ + IMAGE g (t DIFF k) SUBSET relative_frontier u /\ + !x. x IN s ==> g x = f x` + ASSUME_TAC THENL + [ALL_TAC; + REPEAT STRIP_TAC THEN + SUBGOAL_THEN + `?k g. FINITE k /\ DISJOINT k s /\ + g continuous_on (affine hull t DIFF k) /\ + IMAGE g (affine hull t DIFF k) SUBSET relative_frontier u /\ + !x. x IN s ==> g x = (f:real^M->real^N) x` + MP_TAC THENL + [FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_SIMP_TAC[AFF_DIM_AFFINE_HULL; AFFINE_AFFINE_HULL] THEN + TRANS_TAC SUBSET_TRANS `t:real^M->bool` THEN + ASM_REWRITE_TAC[HULL_SUBSET]; + REPEAT(MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC) THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + CONJ_TAC THENL + [FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET)); + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ_ALT] + SUBSET_TRANS)) THEN + MATCH_MP_TAC IMAGE_SUBSET] THEN + MATCH_MP_TAC(SET_RULE `s SUBSET t ==> s DIFF k SUBSET t DIFF k`) THEN + REWRITE_TAC[HULL_SUBSET]]] THEN + REPEAT STRIP_TAC THEN ASM_CASES_TAC `s:real^M->bool = {}` THENL + [ASM_CASES_TAC `relative_frontier(u:real^N->bool) = {}` THENL + [RULE_ASSUM_TAC(REWRITE_RULE[RELATIVE_FRONTIER_EQ_EMPTY]) THEN + UNDISCH_TAC `bounded(u:real^N->bool)` THEN + ASM_SIMP_TAC[AFFINE_BOUNDED_EQ_LOWDIM] THEN DISCH_TAC THEN + SUBGOAL_THEN `aff_dim(t:real^M->bool) <= &0` MP_TAC THENL + [ASM_INT_ARITH_TAC; ALL_TAC] THEN + SIMP_TAC[AFF_DIM_GE; INT_ARITH + `--(&1):int <= x ==> (x <= &0 <=> x = --(&1) \/ x = &0)`] THEN + REWRITE_TAC[AFF_DIM_EQ_MINUS1; AFF_DIM_EQ_0] THEN + DISCH_THEN(DISJ_CASES_THEN2 ASSUME_TAC (X_CHOOSE_TAC `a:real^M`)) THEN + EXISTS_TAC `{a:real^M}` THEN + ASM_REWRITE_TAC[DISJOINT_EMPTY; FINITE_SING; NOT_IN_EMPTY; + EMPTY_DIFF; DIFF_EQ_EMPTY; IMAGE_CLAUSES; + CONTINUOUS_ON_EMPTY; EMPTY_SUBSET]; + EXISTS_TAC `{}:real^M->bool` THEN + FIRST_X_ASSUM(X_CHOOSE_TAC `y:real^N` o + GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN + ASM_SIMP_TAC[FINITE_EMPTY; DISJOINT_EMPTY; NOT_IN_EMPTY; DIFF_EMPTY] THEN + EXISTS_TAC `(\x. y):real^M->real^N` THEN + REWRITE_TAC[CONTINUOUS_ON_CONST] THEN ASM SET_TAC[]]; + ALL_TAC] THEN + FIRST_ASSUM(MP_TAC o MATCH_MP COMPACT_IMP_BOUNDED) THEN + DISCH_THEN(MP_TAC o MATCH_MP BOUNDED_SUBSET_CLOSED_INTERVAL_SYMMETRIC) THEN + REWRITE_TAC[INSERT_SUBSET] THEN + DISCH_THEN(X_CHOOSE_THEN `b:real^M` STRIP_ASSUME_TAC) THEN + MP_TAC(ISPECL + [`f:real^M->real^N`; + `{interval[--(b + vec 1):real^M,b + vec 1] INTER t}`; + `s:real^M->bool`; `u:real^N->bool`] + EXTEND_MAP_CELL_COMPLEX_TO_SPHERE_COFINITE) THEN + SUBGOAL_THEN + `interval[--b,b] SUBSET interval[--(b + vec 1):real^M,b + vec 1]` + ASSUME_TAC THENL + [REWRITE_TAC[SUBSET_INTERVAL; VECTOR_ADD_COMPONENT; VECTOR_NEG_COMPONENT; + VEC_COMPONENT] THEN + REAL_ARITH_TAC; + ALL_TAC] THEN + ASM_REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FINITE_SING] THEN + REWRITE_TAC[FORALL_IN_INSERT; NOT_IN_EMPTY; IMP_IMP] THEN + REWRITE_TAC[INTER_IDEMPOT; UNIONS_1; FACE_OF_REFL_EQ; SUBSET_INTER] THEN + ANTS_TAC THENL + [ASM_SIMP_TAC[HULL_SUBSET; COMPACT_IMP_CLOSED] THEN REPEAT CONJ_TAC THENL + [MATCH_MP_TAC POLYTOPE_INTER_POLYHEDRON THEN + ASM_SIMP_TAC[POLYTOPE_INTERVAL; AFFINE_IMP_POLYHEDRON]; + TRANS_TAC INT_LE_TRANS `aff_dim(t:real^M->bool)` THEN + ASM_SIMP_TAC[AFF_DIM_SUBSET; INTER_SUBSET]; + ASM_SIMP_TAC[CONVEX_INTER; CONVEX_INTERVAL; AFFINE_IMP_CONVEX]; + ASM SET_TAC[]]; + REWRITE_TAC[LEFT_IMP_EXISTS_THM]] THEN + MAP_EVERY X_GEN_TAC [`k:real^M->bool`; `g:real^M->real^N`] THEN + STRIP_TAC THEN EXISTS_TAC `k:real^M->bool` THEN ASM_REWRITE_TAC[] THEN + SUBGOAL_THEN + `?d:real. (&1 / &2 <= d /\ d <= &1) /\ + DISJOINT k (frontier(interval[--(b + lambda i. d):real^M, + (b + lambda i. d)]))` + STRIP_ASSUME_TAC THENL + [MATCH_MP_TAC lemma THEN + ASM_SIMP_TAC[INFINITE; FINITE_REAL_INTERVAL; REAL_NOT_LE] THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN + MATCH_MP_TAC REAL_WLOG_LT THEN REWRITE_TAC[] THEN + CONJ_TAC THENL [SET_TAC[]; ALL_TAC] THEN + MAP_EVERY X_GEN_TAC [`x:real`; `y:real`] THEN REPEAT STRIP_TAC THEN + REWRITE_TAC[frontier] THEN MATCH_MP_TAC(SET_RULE + `c SUBSET i' ==> DISJOINT (c DIFF i) (c' DIFF i')`) THEN + REWRITE_TAC[INTERIOR_INTERVAL; CLOSURE_INTERVAL] THEN + SIMP_TAC[SUBSET_INTERVAL; VECTOR_NEG_COMPONENT; VECTOR_ADD_COMPONENT; + LAMBDA_BETA] THEN + ASM_REAL_ARITH_TAC; + ALL_TAC] THEN + ABBREV_TAC `c:real^M = b + lambda i. d` THEN SUBGOAL_THEN + `interval[--b:real^M,b] SUBSET interval(--c,c) /\ + interval[--b:real^M,b] SUBSET interval[--c,c] /\ + interval[--c,c] SUBSET interval[--(b + vec 1):real^M,b + vec 1]` + STRIP_ASSUME_TAC THENL + [REWRITE_TAC[SUBSET_INTERVAL] THEN EXPAND_TAC "c" THEN REPEAT CONJ_TAC THEN + SIMP_TAC[VECTOR_NEG_COMPONENT; VECTOR_ADD_COMPONENT; LAMBDA_BETA] THEN + MATCH_MP_TAC MONO_FORALL THEN GEN_TAC THEN MATCH_MP_TAC MONO_IMP THEN + REWRITE_TAC[VEC_COMPONENT] THEN ASM_REAL_ARITH_TAC; + ALL_TAC] THEN + EXISTS_TAC + `(g:real^M->real^N) o + closest_point (interval[--c,c] INTER t)` THEN + REPEAT CONJ_TAC THENL + [MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN CONJ_TAC THENL + [MATCH_MP_TAC CONTINUOUS_ON_CLOSEST_POINT THEN + ASM_SIMP_TAC[CONVEX_INTER; CLOSED_INTER; CLOSED_INTERVAL; CLOSED_AFFINE; + AFFINE_IMP_CONVEX; AFFINE_AFFINE_HULL; CONVEX_INTERVAL] THEN + ASM SET_TAC[]; + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET))]; + REWRITE_TAC[IMAGE_o] THEN + FIRST_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ_ALT] + SUBSET_TRANS)) THEN + MATCH_MP_TAC IMAGE_SUBSET; + X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN REWRITE_TAC[o_THM] THEN + TRANS_TAC EQ_TRANS `(g:real^M->real^N) x` THEN + CONJ_TAC THENL [AP_TERM_TAC; ASM SET_TAC[]] THEN + MATCH_MP_TAC CLOSEST_POINT_SELF THEN + ASM_SIMP_TAC[IN_INTER; HULL_INC] THEN ASM SET_TAC[]] THEN + (REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; IN_DIFF] THEN + X_GEN_TAC `x:real^M` THEN STRIP_TAC THEN CONJ_TAC THENL + [MATCH_MP_TAC(SET_RULE + `closest_point s x IN s /\ s SUBSET u ==> closest_point s x IN u`) THEN + CONJ_TAC THENL [MATCH_MP_TAC CLOSEST_POINT_IN_SET; ASM SET_TAC[]] THEN + ASM_SIMP_TAC[CLOSED_INTER; CLOSED_INTERVAL; CLOSED_AFFINE] THEN + ASM SET_TAC[]; + ALL_TAC] THEN + ASM_CASES_TAC `x IN interval[--c:real^M,c]` THEN + ASM_SIMP_TAC[CLOSEST_POINT_SELF; IN_INTER] THEN + MATCH_MP_TAC(SET_RULE + `closest_point s x IN relative_frontier s /\ + DISJOINT k (relative_frontier s) + ==> ~(closest_point s x IN k)`) THEN + CONJ_TAC THENL + [MATCH_MP_TAC CLOSEST_POINT_IN_RELATIVE_FRONTIER THEN + ASM_SIMP_TAC[CLOSED_INTER; CLOSED_AFFINE; CLOSED_INTERVAL] THEN + CONJ_TAC THENL [ASM SET_TAC[]; REWRITE_TAC[IN_DIFF]] THEN CONJ_TAC THENL + [ALL_TAC; ASM_MESON_TAC[SUBSET; RELATIVE_INTERIOR_SUBSET; IN_INTER]] THEN + ONCE_REWRITE_TAC[INTER_COMM] THEN + W(MP_TAC o PART_MATCH (lhs o rand) + AFFINE_HULL_CONVEX_INTER_NONEMPTY_INTERIOR o rand o snd) THEN + ASM_SIMP_TAC[HULL_HULL; AFFINE_AFFINE_HULL; AFFINE_IMP_CONVEX] THEN + ASM_SIMP_TAC[HULL_P] THEN ANTS_TAC THENL [ALL_TAC; ASM SET_TAC[]] THEN + REWRITE_TAC[INTERIOR_INTERVAL] THEN ASM SET_TAC[]; + W(MP_TAC o PART_MATCH (lhs o rand) RELATIVE_FRONTIER_CONVEX_INTER_AFFINE o + rand o snd) THEN + ANTS_TAC THENL [ALL_TAC; ASM SET_TAC[]] THEN + REWRITE_TAC[CONVEX_INTERVAL; AFFINE_AFFINE_HULL; INTERIOR_INTERVAL] THEN + ASM SET_TAC[]]));; + +let EXTEND_MAP_AFFINE_TO_SPHERE_COFINITE_GEN = prove + (`!f:real^M->real^N s t u p. + compact s /\ convex u /\ bounded u /\ + affine t /\ aff_dim t <= aff_dim u /\ s SUBSET t /\ + f continuous_on s /\ IMAGE f s SUBSET relative_frontier u /\ + (!c. c IN components(t DIFF s) /\ bounded c ==> ~(c INTER p = {})) + ==> ?k g. FINITE k /\ k SUBSET p /\ k SUBSET t /\ DISJOINT k s /\ + g continuous_on (t DIFF k) /\ + IMAGE g (t DIFF k) SUBSET relative_frontier u /\ + !x. x IN s ==> g x = f x`, + let lemma0 = prove + (`!u t s v. closed_in (subtopology euclidean u) v /\ t SUBSET u /\ + s = v INTER t + ==> closed_in (subtopology euclidean t) s`, + REPEAT GEN_TAC THEN REWRITE_TAC[CLOSED_IN_CLOSED; LEFT_AND_EXISTS_THM] THEN + MATCH_MP_TAC MONO_EXISTS THEN SET_TAC[]) in + let lemma1 = prove + (`!f:A->B->bool P k. + INFINITE {x | P x} /\ FINITE k /\ + (!x y. P x /\ P y /\ ~(x = y) ==> DISJOINT (f x) (f y)) + ==> ?x. P x /\ DISJOINT k (f x)`, + REWRITE_TAC[INFINITE] THEN REPEAT STRIP_TAC THEN + REWRITE_TAC[SET_RULE `(?x. P x /\ DISJOINT k (f x)) <=> + ~(!x. ?y. P x ==> y IN k /\ y IN f x)`] THEN + REWRITE_TAC[SKOLEM_THM] THEN + DISCH_THEN(X_CHOOSE_TAC `g:A->B`) THEN + MP_TAC(ISPECL [`g:A->B`; `{x:A | P x}`] FINITE_IMAGE_INJ_EQ) THEN + ASM_REWRITE_TAC[IN_ELIM_THM; NOT_IMP] THEN + CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP + (REWRITE_RULE[IMP_CONJ] FINITE_SUBSET)) THEN + ASM SET_TAC[]) in + let lemma2 = prove + (`!f:real^M->real^N s t k p u. + FINITE k /\ affine u /\ + f continuous_on ((u:real^M->bool) DIFF k) /\ + IMAGE f ((u:real^M->bool) DIFF k) SUBSET t /\ + (!c. c IN components((u:real^M->bool) DIFF s) /\ ~(c INTER k = {}) + ==> ~(c INTER p = {})) /\ + closed_in (subtopology euclidean u) s /\ DISJOINT k s /\ k SUBSET u + ==> ?g. g continuous_on ((u:real^M->bool) DIFF p) /\ + IMAGE g ((u:real^M->bool) DIFF p) SUBSET t /\ + !x. x IN s ==> g x = f x`, + REPEAT GEN_TAC THEN ASM_CASES_TAC `k:real^M->bool = {}` THENL + [ASM_REWRITE_TAC[DIFF_EMPTY] THEN REPEAT STRIP_TAC THEN + EXISTS_TAC `f:real^M->real^N` THEN REWRITE_TAC[] THEN CONJ_TAC THENL + [ASM_MESON_TAC[CONTINUOUS_ON_SUBSET; SUBSET_DIFF]; ASM SET_TAC[]]; + STRIP_TAC] THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP CLOSED_IN_IMP_SUBSET) THEN + SUBGOAL_THEN `~(((u:real^M->bool) DIFF s) INTER k = {})` MP_TAC THENL + [ASM SET_TAC[]; ALL_TAC] THEN + GEN_REWRITE_TAC (LAND_CONV o RAND_CONV o LAND_CONV o LAND_CONV) + [UNIONS_COMPONENTS] THEN + REWRITE_TAC[INTER_UNIONS; EMPTY_UNIONS; FORALL_IN_GSPEC] THEN + REWRITE_TAC[NOT_FORALL_THM; NOT_IMP; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `co:real^M->bool` THEN STRIP_TAC THEN + SUBGOAL_THEN `locally connected (u:real^M->bool)` ASSUME_TAC THENL + [ASM_SIMP_TAC[AFFINE_IMP_CONVEX; CONVEX_IMP_LOCALLY_CONNECTED]; + ALL_TAC] THEN + SUBGOAL_THEN + `!c. c IN components ((u:real^M->bool) DIFF s) /\ ~(c INTER k = {}) + ==> ?a g. a IN c /\ a IN p /\ + g continuous_on (s UNION (c DELETE a)) /\ + IMAGE g (s UNION (c DELETE a)) SUBSET t /\ + !x. x IN s ==> g x = (f:real^M->real^N) x` + MP_TAC THENL + [X_GEN_TAC `c:real^M->bool` THEN STRIP_TAC THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP IN_COMPONENTS_SUBSET) THEN + FIRST_X_ASSUM(MP_TAC o SPEC `c:real^M->bool`) THEN + ASM_REWRITE_TAC[] THEN REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; IN_INTER] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `a:real^M` THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + SUBGOAL_THEN `open_in (subtopology euclidean u) (c:real^M->bool)` + MP_TAC THENL + [MATCH_MP_TAC OPEN_IN_TRANS THEN + EXISTS_TAC `u DIFF s:real^M->bool` THEN + ASM_SIMP_TAC[OPEN_IN_DIFF; OPEN_IN_REFL] THEN + MATCH_MP_TAC OPEN_IN_COMPONENTS_LOCALLY_CONNECTED THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC LOCALLY_OPEN_SUBSET THEN + EXISTS_TAC `u:real^M->bool` THEN + ASM_SIMP_TAC[OPEN_IN_DIFF; OPEN_IN_REFL]; + DISCH_THEN(fun th -> ASSUME_TAC th THEN MP_TAC th)] THEN + REWRITE_TAC[OPEN_IN_CONTAINS_CBALL] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC (MP_TAC o SPEC `a:real^M`)) THEN + ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN `ball(a:real^M,d) INTER u SUBSET c` ASSUME_TAC THENL + [ASM_MESON_TAC[BALL_SUBSET_CBALL; SUBSET_TRANS; + SET_RULE `b SUBSET c ==> b INTER u SUBSET c INTER u`]; + ALL_TAC] THEN + MP_TAC(ISPECL + [`ball(a:real^M,d) INTER u`; `c:real^M->bool`; + `s UNION c:real^M->bool`; `c INTER k:real^M->bool`] + HOMEOMORPHISM_GROUPING_POINTS_EXISTS_GEN) THEN + ASM_REWRITE_TAC[INTER_SUBSET; SUBSET_UNION; UNION_SUBSET] THEN + ANTS_TAC THENL + [REPEAT CONJ_TAC THENL + [MATCH_MP_TAC OPEN_IN_SUBSET_TRANS THEN + EXISTS_TAC `u:real^M->bool` THEN + ASM_SIMP_TAC[HULL_MINIMAL; HULL_SUBSET]; + MP_TAC(ISPECL [`c:real^M->bool`; `u:real^M->bool`] + AFFINE_HULL_OPEN_IN) THEN + ASM_SIMP_TAC[HULL_P] THEN ASM SET_TAC[]; + REWRITE_TAC[HULL_SUBSET]; + ASM_MESON_TAC[IN_COMPONENTS_CONNECTED]; + ASM_MESON_TAC[FINITE_SUBSET; INTER_SUBSET]; + MATCH_MP_TAC OPEN_IN_SUBSET_TRANS THEN + EXISTS_TAC `u:real^M->bool` THEN + ASM_REWRITE_TAC[] THEN + ASM_MESON_TAC[OPEN_IN_OPEN_INTER; OPEN_BALL; INTER_COMM]; + REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; IN_INTER] THEN + EXISTS_TAC `a:real^M` THEN REWRITE_TAC[CENTRE_IN_BALL] THEN + ASM SET_TAC[]]; + REWRITE_TAC[IN_INTER; LEFT_IMP_EXISTS_THM]] THEN + MAP_EVERY X_GEN_TAC [`h:real^M->real^M`; `k:real^M->real^M`] THEN + REWRITE_TAC[homeomorphism] THEN STRIP_TAC THEN + MP_TAC(ISPECL [`cball(a:real^M,d) INTER u`; `a:real^M`] + RELATIVE_FRONTIER_RETRACT_OF_PUNCTURED_AFFINE_HULL) THEN + MP_TAC(ISPECL [`cball(a:real^M,d)`; `u:real^M->bool`] + RELATIVE_INTERIOR_CONVEX_INTER_AFFINE) THEN + MP_TAC(ISPECL [`cball(a:real^M,d)`; `u:real^M->bool`] + RELATIVE_FRONTIER_CONVEX_INTER_AFFINE) THEN + MP_TAC(ISPECL [`u:real^M->bool`; `cball(a:real^M,d)`] + (ONCE_REWRITE_RULE[INTER_COMM] + AFFINE_HULL_AFFINE_INTER_NONEMPTY_INTERIOR)) THEN + ASM_SIMP_TAC[CONVEX_CBALL; FRONTIER_CBALL; INTERIOR_CBALL] THEN + SUBGOAL_THEN `a IN ball(a:real^M,d) INTER u` ASSUME_TAC THENL + [ASM_REWRITE_TAC[CENTRE_IN_BALL; IN_INTER] THEN ASM SET_TAC[]; + ALL_TAC] THEN + REPLICATE_TAC 3 + (ANTS_TAC THENL [ASM SET_TAC[]; DISCH_THEN SUBST1_TAC]) THEN + ASM_SIMP_TAC[CONVEX_INTER; CONVEX_CBALL; AFFINE_IMP_CONVEX] THEN + ANTS_TAC THENL + [ASM_MESON_TAC[BOUNDED_SUBSET; INTER_SUBSET; BOUNDED_CBALL]; + ALL_TAC] THEN + ASM_REWRITE_TAC[retract_of; retraction] THEN + DISCH_THEN(X_CHOOSE_THEN `r:real^M->real^M` STRIP_ASSUME_TAC) THEN + EXISTS_TAC + `(f:real^M->real^N) o (k:real^M->real^M) o + (\x. if x IN ball(a,d) then r x else x)` THEN + REWRITE_TAC[CONJ_ASSOC] THEN CONJ_TAC THENL + [ALL_TAC; + X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN REWRITE_TAC[o_THM] THEN + COND_CASES_TAC THENL + [ASM SET_TAC[]; AP_TERM_TAC THEN ASM SET_TAC[]]] THEN + ABBREV_TAC `j = \x:real^M. if x IN ball(a,d) then r x else x` THEN + SUBGOAL_THEN + `(j:real^M->real^M) continuous_on ((u:real^M->bool) DELETE a)` + ASSUME_TAC THENL + [EXPAND_TAC "j" THEN + SUBGOAL_THEN + `u DELETE (a:real^M) = + (cball(a,d) DELETE a) INTER u UNION + ((u:real^M->bool) DIFF ball(a,d))` + (fun th -> SUBST1_TAC th THEN + MATCH_MP_TAC CONTINUOUS_ON_CASES_LOCAL THEN + SUBST1_TAC(SYM th)) + THENL + [MP_TAC(ISPECL [`a:real^M`; `d:real`] BALL_SUBSET_CBALL) THEN + ASM SET_TAC[]; + ALL_TAC] THEN + REWRITE_TAC[IN_DIFF; IN_INTER; IN_DELETE; CONTINUOUS_ON_ID] THEN + REPEAT CONJ_TAC THENL + [ALL_TAC; ALL_TAC; + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET)) THEN ASM SET_TAC[]; + REWRITE_TAC[GSYM BALL_UNION_SPHERE] THEN ASM SET_TAC[]] THEN + REWRITE_TAC[CLOSED_IN_CLOSED] THENL + [EXISTS_TAC `cball(a:real^M,d)` THEN REWRITE_TAC[CLOSED_CBALL]; + EXISTS_TAC `(:real^M) DIFF ball(a,d)` THEN + REWRITE_TAC[GSYM OPEN_CLOSED; OPEN_BALL]] THEN + MP_TAC(ISPECL [`a:real^M`; `d:real`] BALL_SUBSET_CBALL) THEN + MP_TAC(ISPECL [`a:real^M`; `d:real`] CENTRE_IN_BALL) THEN + ASM SET_TAC[]; + ALL_TAC] THEN + SUBGOAL_THEN + `IMAGE (j:real^M->real^M) (s UNION c DELETE a) SUBSET + (s UNION c DIFF ball(a,d))` + ASSUME_TAC THENL + [EXPAND_TAC "j" THEN REWRITE_TAC[SUBSET; FORALL_IN_IMAGE] THEN + X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN + COND_CASES_TAC THENL [ALL_TAC; ASM SET_TAC[]] THEN + SUBGOAL_THEN `(r:real^M->real^M) x IN sphere(a,d)` MP_TAC THENL + [MP_TAC(ISPECL [`a:real^M`; `d:real`] CENTRE_IN_BALL) THEN + ASM SET_TAC[]; + REWRITE_TAC[GSYM CBALL_DIFF_BALL] THEN ASM SET_TAC[]]; + ALL_TAC] THEN + CONJ_TAC THENL + [REPEAT(MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN CONJ_TAC) THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET)) + THENL [ASM SET_TAC[]; ASM SET_TAC[]; ALL_TAC]; + ONCE_REWRITE_TAC[IMAGE_o] THEN FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP + (SET_RULE `IMAGE f u SUBSET t + ==> s SUBSET u ==> IMAGE f s SUBSET t`))] THEN + REWRITE_TAC[IMAGE_o] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE + `s SUBSET u ==> IMAGE f u SUBSET t ==> IMAGE f s SUBSET t`)) THEN + REWRITE_TAC[SUBSET; IN_UNIV; IN_DIFF; FORALL_IN_IMAGE] THEN + ASM SET_TAC[]; + ALL_TAC] THEN + GEN_REWRITE_TAC (LAND_CONV o TOP_DEPTH_CONV) [RIGHT_IMP_EXISTS_THM] THEN + REWRITE_TAC[SKOLEM_THM; LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC + [`a:(real^M->bool)->real^M`; `h:(real^M->bool)->real^M->real^N`] THEN + DISCH_TAC THEN MP_TAC(ISPECL + [`h:(real^M->bool)->real^M->real^N`; + `\c:real^M->bool. s UNION (c DELETE (a c))`; + `s UNION UNIONS + { c DELETE (a c) | + c IN components ((u:real^M->bool) DIFF s) /\ ~(c INTER k = {})}`; + `{c | c IN components ((u:real^M->bool) DIFF s) /\ ~(c INTER k = {})}`] + PASTING_LEMMA_EXISTS_CLOSED) THEN + SUBGOAL_THEN + `FINITE {c | c IN components((u:real^M->bool) DIFF s) /\ + ~(c INTER k = {})}` + ASSUME_TAC THENL + [MP_TAC(ISPECL + [`\c:real^M->bool. c INTER k`; + `{c | c IN components ((u:real^M->bool) DIFF s) /\ ~(c INTER k = {})}`] + FINITE_IMAGE_INJ_EQ) THEN + REWRITE_TAC[IN_ELIM_THM] THEN ANTS_TAC THENL + [MESON_TAC[COMPONENTS_EQ; + SET_RULE + `s INTER k = t INTER k /\ ~(s INTER k = {}) + ==> ~(s INTER t = {})`]; + DISCH_THEN(SUBST1_TAC o SYM) THEN + REWRITE_TAC[GSYM SIMPLE_IMAGE; IN_ELIM_THM]] THEN + MP_TAC(ISPEC + `{c INTER k |c| c IN components((u:real^M->bool) DIFF s) /\ + ~(c INTER k = {})}` + FINITE_UNIONS) THEN + MATCH_MP_TAC(TAUT `p ==> (p <=> q /\ r) ==> q`) THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + FINITE_SUBSET)) THEN + REWRITE_TAC[UNIONS_GSPEC] THEN ASM SET_TAC[]; + ALL_TAC] THEN + ASM_REWRITE_TAC[IN_ELIM_THM] THEN ANTS_TAC THENL + [REPEAT CONJ_TAC THENL + [REWRITE_TAC[UNIONS_GSPEC] THEN ASM SET_TAC[]; + X_GEN_TAC `c:real^M->bool` THEN DISCH_TAC THEN ASM_SIMP_TAC[] THEN + MATCH_MP_TAC lemma0 THEN + MAP_EVERY EXISTS_TAC [`u:real^M->bool`; `s UNION c:real^M->bool`] THEN + REPEAT CONJ_TAC THENL + [MATCH_MP_TAC CLOSED_IN_UNION_COMPLEMENT_COMPONENT THEN + ASM_REWRITE_TAC[]; + ASM_REWRITE_TAC[UNION_SUBSET; UNIONS_SUBSET; FORALL_IN_GSPEC] THEN + MESON_TAC[IN_COMPONENTS_SUBSET; + SET_RULE `c SUBSET u DIFF s ==> c DELETE a SUBSET u`]; + ASM_SIMP_TAC[CLOSED_UNION_COMPLEMENT_COMPONENT; UNIONS_GSPEC] THEN + MATCH_MP_TAC(SET_RULE + `~(a IN t) /\ c DELETE a SUBSET t + ==> s UNION c DELETE a = (s UNION c) INTER (s UNION t)`) THEN + CONJ_TAC THENL [ALL_TAC; ASM SET_TAC[]] THEN + REWRITE_TAC[IN_ELIM_THM; IN_DELETE] THEN + DISCH_THEN(X_CHOOSE_THEN `c':real^M->bool` STRIP_ASSUME_TAC) THEN + MP_TAC(ISPECL [`(u:real^M->bool) DIFF s`; + `c:real^M->bool`; `c':real^M->bool`] + COMPONENTS_EQ) THEN + ASM_CASES_TAC `c':real^M->bool = c` THENL + [ASM_MESON_TAC[]; ALL_TAC] THEN + ASM SET_TAC[]]; + MAP_EVERY X_GEN_TAC + [`c1:real^M->bool`; `c2:real^M->bool`; `x:real^M`] THEN + STRIP_TAC THEN ASM_CASES_TAC `c2:real^M->bool = c1` THEN + ASM_REWRITE_TAC[] THEN FIRST_ASSUM(MP_TAC o MATCH_MP (SET_RULE + `x IN u INTER (s UNION c1 DELETE a) INTER (s UNION c2 DELETE b) + ==> (c1 INTER c2 = {}) ==> x IN s`)) THEN + ANTS_TAC THENL [ASM_MESON_TAC[COMPONENTS_EQ]; ASM_SIMP_TAC[]]]; + DISCH_THEN(X_CHOOSE_THEN `g:real^M->real^N` STRIP_ASSUME_TAC)] THEN + MP_TAC + (ISPECL [`\x. x IN s UNION + UNIONS {c | c IN components((u:real^M->bool) DIFF s) /\ + c INTER k = {}}`; + `f:real^M->real^N`; + `g:real^M->real^N`; + `s UNION + UNIONS {c | c IN components((u:real^M->bool) DIFF s) /\ + c INTER k = {}}`; + `s UNION + UNIONS { c DELETE (a c) | + c IN components((u:real^M->bool) DIFF s) /\ + ~(c INTER k = {})}`] + CONTINUOUS_ON_CASES_LOCAL) THEN + ASM_REWRITE_TAC[] THEN ANTS_TAC THENL + [REPEAT CONJ_TAC THENL + [MATCH_MP_TAC lemma0 THEN EXISTS_TAC `u:real^M->bool` THEN + EXISTS_TAC `u DIFF + UNIONS {c DELETE a c | + c IN components ((u:real^M->bool) DIFF s) /\ + ~(c INTER k = {})}` THEN + REPEAT CONJ_TAC THENL + [MATCH_MP_TAC CLOSED_IN_DIFF THEN REWRITE_TAC[CLOSED_IN_REFL] THEN + MATCH_MP_TAC OPEN_IN_UNIONS THEN REWRITE_TAC[FORALL_IN_GSPEC] THEN + X_GEN_TAC `c:real^M->bool` THEN DISCH_TAC THEN + MATCH_MP_TAC OPEN_IN_DELETE THEN MATCH_MP_TAC OPEN_IN_TRANS THEN + EXISTS_TAC `u DIFF s:real^M->bool` THEN + ASM_SIMP_TAC[OPEN_IN_DIFF; OPEN_IN_REFL] THEN + MATCH_MP_TAC OPEN_IN_COMPONENTS_LOCALLY_CONNECTED THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC LOCALLY_OPEN_SUBSET THEN + EXISTS_TAC `u:real^M->bool` THEN + ASM_SIMP_TAC[OPEN_IN_DIFF; OPEN_IN_REFL]; + ASM_REWRITE_TAC[UNION_SUBSET] THEN + REWRITE_TAC[UNIONS_SUBSET; IN_ELIM_THM] THEN + MESON_TAC[IN_COMPONENTS_SUBSET; + SET_RULE `c SUBSET u DIFF s ==> c DELETE a SUBSET u /\ + c SUBSET u`]; + REWRITE_TAC[SET_RULE + `(s UNION t) UNION (s UNION u) = (s UNION t) UNION u`] THEN + MATCH_MP_TAC(SET_RULE + `s SUBSET u /\ t INTER s = {} + ==> s = (u DIFF t) INTER (s UNION t)`) THEN + CONJ_TAC THENL + [ASM_REWRITE_TAC[UNION_SUBSET] THEN + REWRITE_TAC[UNIONS_SUBSET; IN_ELIM_THM] THEN + MESON_TAC[IN_COMPONENTS_SUBSET; + SET_RULE `c SUBSET u DIFF s ==> c DELETE a SUBSET u /\ + c SUBSET u`]; + ALL_TAC] THEN + REWRITE_TAC[EMPTY_UNION; SET_RULE + `c INTER (s UNION t) = (s INTER c) UNION (c INTER t)`] THEN + CONJ_TAC THENL + [MATCH_MP_TAC(SET_RULE + `t SUBSET UNIV DIFF s ==> s INTER t = {}`) THEN + REWRITE_TAC[UNIONS_SUBSET; FORALL_IN_GSPEC] THEN GEN_TAC THEN + DISCH_THEN(CONJUNCTS_THEN2 + (MP_TAC o MATCH_MP IN_COMPONENTS_SUBSET) + MP_TAC) THEN ASM SET_TAC[]; + REWRITE_TAC[INTER_UNIONS; EMPTY_UNIONS; FORALL_IN_GSPEC] THEN + X_GEN_TAC `c:real^M->bool` THEN STRIP_TAC THEN + X_GEN_TAC `c':real^M->bool` THEN STRIP_TAC THEN + MP_TAC(ISPECL [`(u:real^M->bool) DIFF s`; + `c:real^M->bool`; `c':real^M->bool`] + COMPONENTS_EQ) THEN + ASM_CASES_TAC `c':real^M->bool = c` THENL + [ASM_MESON_TAC[]; ASM SET_TAC[]]]]; + MATCH_MP_TAC lemma0 THEN EXISTS_TAC `u:real^M->bool` THEN + EXISTS_TAC + `UNIONS {s UNION c |c| c IN components ((u:real^M->bool) DIFF s) /\ + ~(c INTER k = {})}` THEN + REPEAT CONJ_TAC THENL + [MATCH_MP_TAC CLOSED_IN_UNIONS THEN REWRITE_TAC[FORALL_IN_GSPEC] THEN + ONCE_REWRITE_TAC[SIMPLE_IMAGE_GEN] THEN + ASM_SIMP_TAC[FINITE_IMAGE] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC CLOSED_IN_UNION_COMPLEMENT_COMPONENT THEN + ASM_REWRITE_TAC[]; + ASM_REWRITE_TAC[UNION_SUBSET] THEN + REWRITE_TAC[UNIONS_SUBSET; IN_ELIM_THM] THEN + MESON_TAC[IN_COMPONENTS_SUBSET; + SET_RULE `c SUBSET u DIFF s ==> c DELETE a SUBSET u /\ + c SUBSET u`]; + MATCH_MP_TAC(SET_RULE + `t SUBSET u /\ u INTER s SUBSET t ==> t = u INTER (s UNION t)`) THEN + CONJ_TAC THENL + [REWRITE_TAC[UNIONS_GSPEC] THEN ASM SET_TAC[]; ALL_TAC] THEN + MATCH_MP_TAC(SET_RULE + `u INTER t SUBSET s ==> u INTER (s UNION t) SUBSET s UNION v`) THEN + MATCH_MP_TAC(SET_RULE + `((UNIV DIFF s) INTER t) INTER u SUBSET s + ==> t INTER u SUBSET s`) THEN + GEN_REWRITE_TAC (LAND_CONV o LAND_CONV o TOP_DEPTH_CONV) + [INTER_UNIONS] THEN + REWRITE_TAC[SET_RULE + `{g x | x IN {f y | P y}} = {g(f y) | P y}`] THEN + REWRITE_TAC[SET_RULE + `(UNIV DIFF s) INTER (s UNION c) = c DIFF s`] THEN + REWRITE_TAC[SET_RULE + `t INTER u SUBSET s <=> t INTER ((UNIV DIFF s) INTER u) = {}`] THEN + ONCE_REWRITE_TAC[INTER_UNIONS] THEN + REWRITE_TAC[EMPTY_UNIONS; FORALL_IN_GSPEC; INTER_UNIONS] THEN + X_GEN_TAC `c:real^M->bool` THEN STRIP_TAC THEN + X_GEN_TAC `c':real^M->bool` THEN STRIP_TAC THEN + MP_TAC(ISPECL [`(u:real^M->bool) DIFF s`; + `c:real^M->bool`; `c':real^M->bool`] + COMPONENTS_EQ) THEN + ASM_CASES_TAC `c':real^M->bool = c` THENL + [ASM_MESON_TAC[]; ASM SET_TAC[]]]; + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET)) THEN + REWRITE_TAC[UNION_SUBSET] THEN + CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + REWRITE_TAC[UNIONS_SUBSET; IN_ELIM_THM] THEN + GEN_TAC THEN + DISCH_THEN(CONJUNCTS_THEN2 (MP_TAC o MATCH_MP IN_COMPONENTS_SUBSET) + MP_TAC) THEN ASM SET_TAC[]; + REWRITE_TAC[TAUT `p /\ ~p <=> F`] THEN X_GEN_TAC `x:real^M` THEN + REWRITE_TAC[IN_UNION] THEN + ASM_CASES_TAC `(x:real^M) IN s` THEN ASM_REWRITE_TAC[] THENL + [ASM SET_TAC[]; ALL_TAC] THEN + REWRITE_TAC[UNIONS_GSPEC; IN_ELIM_THM; IN_DELETE] THEN + DISCH_THEN(CONJUNCTS_THEN2 (X_CHOOSE_TAC `c:real^M->bool`) + (X_CHOOSE_TAC `c':real^M->bool`)) THEN + MP_TAC(ISPECL [`(u:real^M->bool) DIFF s`; + `c:real^M->bool`; `c':real^M->bool`] + COMPONENTS_EQ) THEN + ASM_CASES_TAC `c':real^M->bool = c` THENL + [ASM_MESON_TAC[]; ASM SET_TAC[]]]; + MATCH_MP_TAC(MESON[CONTINUOUS_ON_SUBSET] + `t SUBSET s /\ P f + ==> f continuous_on s ==> ?g. g continuous_on t /\ P g`) THEN + REWRITE_TAC[] THEN CONJ_TAC THENL + [REWRITE_TAC[SET_RULE + `(s UNION t) UNION (s UNION u) = s UNION (t UNION u)`] THEN + MATCH_MP_TAC(SET_RULE + `(u DIFF s) DIFF p SUBSET t + ==> u DIFF p SUBSET s UNION t`) THEN + GEN_REWRITE_TAC (LAND_CONV o LAND_CONV) [UNIONS_COMPONENTS] THEN + REWRITE_TAC[UNIONS_GSPEC] THEN ASM SET_TAC[]; + SIMP_TAC[IN_UNION]] THEN + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; IN_DIFF; IN_UNION; IN_UNIV] THEN + X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN + ASM_CASES_TAC `(x:real^M) IN s` THENL [ASM SET_TAC[]; ALL_TAC] THEN + ASM_REWRITE_TAC[IN_UNIONS; IN_ELIM_THM] THEN COND_CASES_TAC THENL + [ASM SET_TAC[]; ALL_TAC] THEN + SUBGOAL_THEN + `x IN ((u:real^M->bool) DIFF s)` MP_TAC THENL + [ASM SET_TAC[]; ALL_TAC] THEN + GEN_REWRITE_TAC (LAND_CONV o RAND_CONV) [UNIONS_COMPONENTS] THEN + REWRITE_TAC[IN_UNIONS] THEN + DISCH_THEN(X_CHOOSE_THEN `c:real^M->bool` STRIP_ASSUME_TAC) THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [NOT_EXISTS_THM]) THEN + DISCH_THEN(MP_TAC o SPEC `c:real^M->bool`) THEN ASM_REWRITE_TAC[] THEN + DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`x:real^M`; `c:real^M->bool`]) THEN + ASM_REWRITE_TAC[UNIONS_GSPEC] THEN ASM SET_TAC[]]) in + let lemma3 = prove + (`!f:real^M->real^N s t u p. + compact s /\ convex u /\ bounded u /\ + affine t /\ aff_dim t <= aff_dim u /\ s SUBSET t /\ + f continuous_on s /\ IMAGE f s SUBSET relative_frontier u /\ + (!c. c IN components(t DIFF s) ==> ~(c INTER p = {})) + ==> ?k g. FINITE k /\ k SUBSET p /\ k SUBSET t /\ DISJOINT k s /\ + g continuous_on (t DIFF k) /\ + IMAGE g (t DIFF k) SUBSET relative_frontier u /\ + !x. x IN s ==> g x = f x`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`f:real^M->real^N`; `s:real^M->bool`; + `t:real^M->bool`; `u:real^N->bool`] + EXTEND_MAP_AFFINE_TO_SPHERE_COFINITE_SIMPLE) THEN + ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`k:real^M->bool`; `g:real^M->real^N`] THEN + STRIP_TAC THEN + SUBGOAL_THEN + `!x. ?y. x IN k + ==> ?c. c IN components (t DIFF s:real^M->bool) /\ + x IN c /\ y IN c /\ y IN p` + MP_TAC THENL + [X_GEN_TAC `x:real^M` THEN REWRITE_TAC[RIGHT_EXISTS_IMP_THM] THEN + DISCH_TAC THEN + SUBGOAL_THEN `(x:real^M) IN (t DIFF s)` MP_TAC THENL + [ASM SET_TAC[]; ALL_TAC] THEN + GEN_REWRITE_TAC (LAND_CONV o RAND_CONV) [UNIONS_COMPONENTS] THEN + ONCE_REWRITE_TAC[SWAP_EXISTS_THM] THEN + REWRITE_TAC[IN_UNIONS; RIGHT_EXISTS_AND_THM] THEN + MATCH_MP_TAC MONO_EXISTS THEN ASM SET_TAC[]; + REWRITE_TAC[SKOLEM_THM] THEN + DISCH_THEN(X_CHOOSE_THEN `h:real^M->real^M` (LABEL_TAC "*"))] THEN + EXISTS_TAC `IMAGE (h:real^M->real^M) k` THEN + MP_TAC(ISPECL + [`g:real^M->real^N`; `s:real^M->bool`; + `relative_frontier u:real^N->bool`; `k:real^M->bool`; + `IMAGE (h:real^M->real^M) k`; `t:real^M->bool`] lemma2) THEN + ASM_SIMP_TAC[AFFINE_AFFINE_HULL; FINITE_IMAGE] THEN ANTS_TAC THENL + [CONJ_TAC THENL + [X_GEN_TAC `c:real^M->bool` THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN + ONCE_REWRITE_TAC[INTER_COMM] THEN + REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; EXISTS_IN_IMAGE; IN_INTER] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `x:real^M` THEN + STRIP_TAC THEN REMOVE_THEN "*" (MP_TAC o SPEC `x:real^M`) THEN + ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `c':real^M->bool` THEN STRIP_TAC THEN + MP_TAC(ISPECL [`(t:real^M->bool) DIFF s`; + `c:real^M->bool`; `c':real^M->bool`] + COMPONENTS_EQ) THEN + ASM_CASES_TAC `c':real^M->bool = c` THENL [ALL_TAC; ASM SET_TAC[]] THEN + ASM_REWRITE_TAC[] THEN ASM SET_TAC[]; + MATCH_MP_TAC CLOSED_IN_SUBSET_TRANS THEN + EXISTS_TAC `(:real^M)` THEN + ASM_REWRITE_TAC[SUBTOPOLOGY_UNIV; GSYM CLOSED_IN] THEN + ASM_SIMP_TAC[COMPACT_IMP_CLOSED; SUBSET_UNIV]]; + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `h:real^M->real^N` THEN + STRIP_TAC THEN ASM_SIMP_TAC[] THEN + REWRITE_TAC[SET_RULE `DISJOINT s t <=> !x. x IN s ==> ~(x IN t)`] THEN + ASM_REWRITE_TAC[SUBSET; FORALL_IN_IMAGE] THEN + ASM_MESON_TAC[IN_COMPONENTS_SUBSET; SUBSET; IN_DIFF]]) in + REPEAT STRIP_TAC THEN ASM_CASES_TAC `s:real^M->bool = {}` THENL + [ASM_CASES_TAC `relative_frontier(u:real^N->bool) = {}` THENL + [RULE_ASSUM_TAC(REWRITE_RULE[RELATIVE_FRONTIER_EQ_EMPTY]) THEN + UNDISCH_TAC `bounded(u:real^N->bool)` THEN + ASM_SIMP_TAC[AFFINE_BOUNDED_EQ_LOWDIM] THEN DISCH_TAC THEN + SUBGOAL_THEN `aff_dim(t:real^M->bool) <= &0` MP_TAC THENL + [ASM_INT_ARITH_TAC; ALL_TAC] THEN + SIMP_TAC[AFF_DIM_GE; INT_ARITH + `--(&1):int <= x ==> (x <= &0 <=> x = --(&1) \/ x = &0)`] THEN + REWRITE_TAC[AFF_DIM_EQ_MINUS1; AFF_DIM_EQ_0] THEN + DISCH_THEN(DISJ_CASES_THEN2 ASSUME_TAC (X_CHOOSE_TAC `a:real^M`)) THENL + [EXISTS_TAC `{}:real^M->bool` THEN + ASM_REWRITE_TAC[EMPTY_DIFF; FINITE_EMPTY; CONTINUOUS_ON_EMPTY; + IMAGE_CLAUSES; NOT_IN_EMPTY] THEN + SET_TAC[]; + FIRST_X_ASSUM(MP_TAC o SPEC `{a:real^M}`) THEN + ASM_REWRITE_TAC[DIFF_EMPTY; IN_COMPONENTS_SELF] THEN + REWRITE_TAC[CONNECTED_SING; NOT_INSERT_EMPTY; BOUNDED_SING] THEN + DISCH_TAC THEN EXISTS_TAC `{a:real^M}` THEN + ASM_REWRITE_TAC[DIFF_EQ_EMPTY; CONTINUOUS_ON_EMPTY; NOT_IN_EMPTY; + FINITE_SING; IMAGE_CLAUSES; EMPTY_SUBSET] THEN + ASM SET_TAC[]]; + EXISTS_TAC `{}:real^M->bool` THEN + FIRST_X_ASSUM(X_CHOOSE_TAC `y:real^N` o + GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN + ASM_SIMP_TAC[FINITE_EMPTY; DISJOINT_EMPTY; NOT_IN_EMPTY; DIFF_EMPTY] THEN + EXISTS_TAC `(\x. y):real^M->real^N` THEN + REWRITE_TAC[CONTINUOUS_ON_CONST] THEN ASM SET_TAC[]]; + ALL_TAC] THEN + FIRST_ASSUM(MP_TAC o MATCH_MP COMPACT_IMP_BOUNDED) THEN + DISCH_THEN(MP_TAC o MATCH_MP BOUNDED_SUBSET_CLOSED_INTERVAL_SYMMETRIC) THEN + REWRITE_TAC[INSERT_SUBSET] THEN + DISCH_THEN(X_CHOOSE_THEN `b:real^M` STRIP_ASSUME_TAC) THEN + MP_TAC(ISPECL + [`f:real^M->real^N`; `s:real^M->bool`; + `t:real^M->bool`; `u:real^N->bool`; + `p UNION (UNIONS {c | c IN components (t DIFF s) /\ ~bounded c} DIFF + interval[--(b + vec 1):real^M,b + vec 1])`] + lemma3) THEN + ASM_REWRITE_TAC[] THEN ANTS_TAC THENL + [X_GEN_TAC `c:real^M->bool` THEN STRIP_TAC THEN + ASM_CASES_TAC `bounded(c:real^M->bool)` THENL + [FIRST_X_ASSUM(MP_TAC o SPEC `c:real^M->bool`) THEN + ASM_REWRITE_TAC[] THEN ASM SET_TAC[]; + ALL_TAC] THEN + SUBGOAL_THEN + `~(c SUBSET interval[--(b + vec 1):real^M,b + vec 1])` + MP_TAC THENL [ALL_TAC; ASM SET_TAC[]] THEN + ASM_MESON_TAC[BOUNDED_SUBSET; BOUNDED_INTERVAL]; + ALL_TAC] THEN + REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`k:real^M->bool`; `g:real^M->real^N`] THEN + STRIP_TAC THEN + EXISTS_TAC `k INTER interval[--(b + vec 1):real^M,b + vec 1]` THEN + ASM_SIMP_TAC[FINITE_INTER; RIGHT_EXISTS_AND_THM] THEN + REPEAT(CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC]) THEN + SUBGOAL_THEN + `interval[--b,b] SUBSET interval[--(b + vec 1):real^M,b + vec 1]` + ASSUME_TAC THENL + [REWRITE_TAC[SUBSET_INTERVAL; VECTOR_ADD_COMPONENT; VECTOR_NEG_COMPONENT; + VEC_COMPONENT] THEN + REAL_ARITH_TAC; + ALL_TAC] THEN + SUBGOAL_THEN + `?d:real. (&1 / &2 <= d /\ d <= &1) /\ + DISJOINT k (frontier(interval[--(b + lambda i. d):real^M, + (b + lambda i. d)]))` + STRIP_ASSUME_TAC THENL + [MATCH_MP_TAC lemma1 THEN + ASM_SIMP_TAC[INFINITE; FINITE_REAL_INTERVAL; REAL_NOT_LE] THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN + MATCH_MP_TAC REAL_WLOG_LT THEN REWRITE_TAC[] THEN + CONJ_TAC THENL [SET_TAC[]; ALL_TAC] THEN + MAP_EVERY X_GEN_TAC [`x:real`; `y:real`] THEN REPEAT STRIP_TAC THEN + REWRITE_TAC[frontier] THEN MATCH_MP_TAC(SET_RULE + `c SUBSET i' ==> DISJOINT (c DIFF i) (c' DIFF i')`) THEN + REWRITE_TAC[INTERIOR_INTERVAL; CLOSURE_INTERVAL] THEN + SIMP_TAC[SUBSET_INTERVAL; VECTOR_NEG_COMPONENT; VECTOR_ADD_COMPONENT; + LAMBDA_BETA] THEN + ASM_REAL_ARITH_TAC; + ALL_TAC] THEN + ABBREV_TAC `c:real^M = b + lambda i. d` THEN SUBGOAL_THEN + `interval[--b:real^M,b] SUBSET interval(--c,c) /\ + interval[--b:real^M,b] SUBSET interval[--c,c] /\ + interval[--c,c] SUBSET interval[--(b + vec 1):real^M,b + vec 1]` + STRIP_ASSUME_TAC THENL + [REWRITE_TAC[SUBSET_INTERVAL] THEN EXPAND_TAC "c" THEN REPEAT CONJ_TAC THEN + SIMP_TAC[VECTOR_NEG_COMPONENT; VECTOR_ADD_COMPONENT; LAMBDA_BETA] THEN + MATCH_MP_TAC MONO_FORALL THEN GEN_TAC THEN MATCH_MP_TAC MONO_IMP THEN + REWRITE_TAC[VEC_COMPONENT] THEN ASM_REAL_ARITH_TAC; + ALL_TAC] THEN + EXISTS_TAC + `(g:real^M->real^N) o + closest_point (interval[--c,c] INTER t)` THEN + REPEAT CONJ_TAC THENL + [MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN CONJ_TAC THENL + [MATCH_MP_TAC CONTINUOUS_ON_CLOSEST_POINT THEN + ASM_SIMP_TAC[CONVEX_INTER; CLOSED_INTER; CLOSED_INTERVAL; CLOSED_AFFINE; + AFFINE_IMP_CONVEX; AFFINE_AFFINE_HULL; CONVEX_INTERVAL] THEN + ASM SET_TAC[]; + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET))]; + REWRITE_TAC[IMAGE_o] THEN + FIRST_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ_ALT] + SUBSET_TRANS)) THEN + MATCH_MP_TAC IMAGE_SUBSET; + X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN REWRITE_TAC[o_THM] THEN + TRANS_TAC EQ_TRANS `(g:real^M->real^N) x` THEN + CONJ_TAC THENL [AP_TERM_TAC; ASM SET_TAC[]] THEN + MATCH_MP_TAC CLOSEST_POINT_SELF THEN + ASM_SIMP_TAC[IN_INTER; HULL_INC] THEN ASM SET_TAC[]] THEN + (REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; IN_DIFF] THEN + X_GEN_TAC `x:real^M` THEN STRIP_TAC THEN CONJ_TAC THENL + [MATCH_MP_TAC(SET_RULE + `closest_point s x IN s /\ s SUBSET u ==> closest_point s x IN u`) THEN + CONJ_TAC THENL [MATCH_MP_TAC CLOSEST_POINT_IN_SET; ASM SET_TAC[]] THEN + ASM_SIMP_TAC[CLOSED_INTER; CLOSED_INTERVAL; CLOSED_AFFINE] THEN + ASM SET_TAC[]; + ALL_TAC] THEN + ASM_CASES_TAC `x IN interval[--c:real^M,c]` THEN + ASM_SIMP_TAC[CLOSEST_POINT_SELF; IN_INTER] THENL + [ASM SET_TAC[]; ALL_TAC] THEN + MATCH_MP_TAC(SET_RULE + `closest_point s x IN relative_frontier s /\ + DISJOINT k (relative_frontier s) + ==> ~(closest_point s x IN k)`) THEN + CONJ_TAC THENL + [MATCH_MP_TAC CLOSEST_POINT_IN_RELATIVE_FRONTIER THEN + ASM_SIMP_TAC[CLOSED_INTER; CLOSED_AFFINE; CLOSED_INTERVAL] THEN + CONJ_TAC THENL [ASM SET_TAC[]; REWRITE_TAC[IN_DIFF]] THEN CONJ_TAC THENL + [ALL_TAC; ASM_MESON_TAC[SUBSET; RELATIVE_INTERIOR_SUBSET; IN_INTER]] THEN + ONCE_REWRITE_TAC[INTER_COMM] THEN + W(MP_TAC o PART_MATCH (lhs o rand) + AFFINE_HULL_CONVEX_INTER_NONEMPTY_INTERIOR o rand o snd) THEN + ASM_SIMP_TAC[HULL_HULL; AFFINE_AFFINE_HULL; AFFINE_IMP_CONVEX] THEN + ASM_SIMP_TAC[HULL_P] THEN ANTS_TAC THENL [ALL_TAC; ASM SET_TAC[]] THEN + REWRITE_TAC[INTERIOR_INTERVAL] THEN ASM SET_TAC[]; + W(MP_TAC o PART_MATCH (lhs o rand) RELATIVE_FRONTIER_CONVEX_INTER_AFFINE o + rand o snd) THEN + ANTS_TAC THENL [ALL_TAC; ASM SET_TAC[]] THEN + REWRITE_TAC[CONVEX_INTERVAL; AFFINE_AFFINE_HULL; INTERIOR_INTERVAL] THEN + ASM SET_TAC[]]));; + +let EXTEND_MAP_AFFINE_TO_SPHERE_COFINITE = prove + (`!f:real^M->real^N s t a r p. + compact s /\ affine t /\ aff_dim t <= &(dimindex(:N)) /\ s SUBSET t /\ + &0 <= r /\ f continuous_on s /\ IMAGE f s SUBSET sphere(a,r) /\ + (!c. c IN components(t DIFF s) /\ bounded c ==> ~(c INTER p = {})) + ==> ?k g. FINITE k /\ k SUBSET p /\ k SUBSET t /\ DISJOINT k s /\ + g continuous_on (t DIFF k) /\ + IMAGE g (t DIFF k) SUBSET sphere(a,r) /\ + !x. x IN s ==> g x = f x`, + REPEAT GEN_TAC THEN ASM_CASES_TAC `r = &0` THENL + [ASM_SIMP_TAC[SPHERE_SING] THEN STRIP_TAC THEN + EXISTS_TAC `{}:real^M->bool` THEN + EXISTS_TAC `(\x. a):real^M->real^N` THEN + REWRITE_TAC[CONTINUOUS_ON_CONST; FINITE_EMPTY] THEN ASM SET_TAC[]; + MP_TAC(ISPECL [`a:real^N`; `r:real`] RELATIVE_FRONTIER_CBALL) THEN + ASM_REWRITE_TAC[] THEN DISCH_THEN(SUBST1_TAC o SYM) THEN + STRIP_TAC THEN MATCH_MP_TAC EXTEND_MAP_AFFINE_TO_SPHERE_COFINITE_GEN THEN + ASM_REWRITE_TAC[CONVEX_CBALL; BOUNDED_CBALL; AFF_DIM_CBALL] THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN ASM_REAL_ARITH_TAC]);; + +let EXTEND_MAP_UNIV_TO_SPHERE_COFINITE = prove + (`!f:real^M->real^N s a r p. + dimindex(:M) <= dimindex(:N) /\ &0 <= r /\ + compact s /\ f continuous_on s /\ IMAGE f s SUBSET sphere(a,r) /\ + (!c. c IN components((:real^M) DIFF s) /\ bounded c + ==> ~(c INTER p = {})) + ==> ?k g. FINITE k /\ k SUBSET p /\ DISJOINT k s /\ + g continuous_on ((:real^M) DIFF k) /\ + IMAGE g ((:real^M) DIFF k) SUBSET sphere(a,r) /\ + !x. x IN s ==> g x = f x`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`f:real^M->real^N`; `s:real^M->bool`; `(:real^M)`; + `a:real^N`; `r:real`; `p:real^M->bool`] + EXTEND_MAP_AFFINE_TO_SPHERE_COFINITE) THEN + ASM_REWRITE_TAC[AFFINE_UNIV; SUBSET_UNIV; AFF_DIM_UNIV; INT_OF_NUM_LE]);; + +let EXTEND_MAP_UNIV_TO_SPHERE_NO_BOUNDED_COMPONENT = prove + (`!f:real^M->real^N s a r. + dimindex(:M) <= dimindex(:N) /\ &0 <= r /\ + compact s /\ f continuous_on s /\ IMAGE f s SUBSET sphere(a,r) /\ + (!c. c IN components((:real^M) DIFF s) ==> ~bounded c) + ==> ?g. g continuous_on (:real^M) /\ + IMAGE g (:real^M) SUBSET sphere(a,r) /\ + !x. x IN s ==> g x = f x`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`f:real^M->real^N`; `s:real^M->bool`; `a:real^N`; `r:real`; + `{}:real^M->bool`] EXTEND_MAP_UNIV_TO_SPHERE_COFINITE) THEN + ASM_SIMP_TAC[IMP_CONJ; SUBSET_EMPTY; RIGHT_EXISTS_AND_THM] THEN + ONCE_REWRITE_TAC[TAUT `p /\ q /\ r <=> q /\ p /\ r`] THEN + REWRITE_TAC[UNWIND_THM2; FINITE_EMPTY; DISJOINT_EMPTY; DIFF_EMPTY] THEN + MATCH_MP_TAC MONO_EXISTS THEN SIMP_TAC[]);; + +let EXTEND_MAP_SPHERE_TO_SPHERE_GEN = prove + (`!f:real^M->real^N c s t. + closed c /\ c SUBSET relative_frontier s /\ convex s /\ bounded s /\ + convex t /\ bounded t /\ aff_dim s <= aff_dim t /\ + f continuous_on c /\ IMAGE f c SUBSET relative_frontier t + ==> ?g. g continuous_on (relative_frontier s) /\ + IMAGE g (relative_frontier s) SUBSET relative_frontier t /\ + !x. x IN c ==> g x = f x`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN + `?p:real^M->bool. polytope p /\ aff_dim p = aff_dim(s:real^M->bool)` + STRIP_ASSUME_TAC THENL + [MATCH_MP_TAC CHOOSE_POLYTOPE THEN + ASM_REWRITE_TAC[AFF_DIM_GE; AFF_DIM_LE_UNIV]; + ALL_TAC] THEN + MP_TAC(ISPECL [`s:real^M->bool`; `p:real^M->bool`] + HOMEOMORPHIC_RELATIVE_FRONTIERS_CONVEX_BOUNDED_SETS) THEN + ASM_SIMP_TAC[POLYTOPE_IMP_CONVEX; POLYTOPE_IMP_BOUNDED; homeomorphic] THEN + REWRITE_TAC[HOMEOMORPHISM; LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`h:real^M->real^M`; `k:real^M->real^M`] THEN + STRIP_TAC THEN + MP_TAC(ISPECL + [`(f:real^M->real^N) o (k:real^M->real^M)`; + `{f:real^M->bool | f face_of p /\ ~(f = p)}`; + `IMAGE (h:real^M->real^M) c`; + `t:real^N->bool`] EXTEND_MAP_CELL_COMPLEX_TO_SPHERE) THEN + ASM_SIMP_TAC[FORALL_IN_IMAGE] THEN + ASM_SIMP_TAC[GSYM RELATIVE_FRONTIER_OF_POLYHEDRON_ALT; + POLYTOPE_IMP_POLYHEDRON] THEN + REWRITE_TAC[IN_ELIM_THM; GSYM IMAGE_o; o_THM] THEN ANTS_TAC THENL + [REPEAT CONJ_TAC THENL + [MATCH_MP_TAC FINITE_SUBSET THEN + EXISTS_TAC `{f:real^M->bool | f face_of p}` THEN + ASM_SIMP_TAC[FINITE_POLYTOPE_FACES] THEN SET_TAC[]; + ASM_MESON_TAC[FACE_OF_POLYTOPE_POLYTOPE; + FACE_OF_AFF_DIM_LT; POLYTOPE_IMP_CONVEX; INT_LTE_TRANS]; + ASM_MESON_TAC[FACE_OF_INTER; FACE_OF_SUBSET; + INTER_SUBSET; FACE_OF_INTER; FACE_OF_IMP_SUBSET]; + ASM SET_TAC[]; + MATCH_MP_TAC COMPACT_IMP_CLOSED THEN + MATCH_MP_TAC COMPACT_CONTINUOUS_IMAGE THEN + CONJ_TAC THENL [ASM_MESON_TAC[CONTINUOUS_ON_SUBSET]; ALL_TAC] THEN + ASM_REWRITE_TAC[COMPACT_EQ_BOUNDED_CLOSED] THEN + FIRST_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ_ALT] + BOUNDED_SUBSET)) THEN + ASM_SIMP_TAC[BOUNDED_RELATIVE_FRONTIER]; + MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN CONJ_TAC THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET)) THEN + ASM SET_TAC[]; + REWRITE_TAC[IMAGE_o] THEN ASM SET_TAC[]]; + DISCH_THEN(X_CHOOSE_THEN `g:real^M->real^N` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `(g:real^M->real^N) o (h:real^M->real^M)` THEN + REWRITE_TAC[IMAGE_o; o_THM] THEN + CONJ_TAC THENL [ALL_TAC; ASM SET_TAC[]] THEN + MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN CONJ_TAC THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET)) THEN + ASM SET_TAC[]]);; + +let EXTEND_MAP_SPHERE_TO_SPHERE = prove + (`!f:real^M->real^N c a r b s. + dimindex(:M) <= dimindex(:N) /\ closed c /\ c SUBSET sphere(a,r) /\ + f continuous_on c /\ IMAGE f c SUBSET sphere(b,s) /\ + (&0 <= r /\ c = {} ==> &0 <= s) + ==> ?g. g continuous_on sphere(a,r) /\ + IMAGE g (sphere(a,r)) SUBSET sphere(b,s) /\ + !x. x IN c ==> g x = f x`, + REPEAT GEN_TAC THEN ASM_CASES_TAC `r < &0` THEN + ASM_SIMP_TAC[SPHERE_EMPTY; NOT_IN_EMPTY; CONTINUOUS_ON_EMPTY; + IMAGE_CLAUSES; EMPTY_SUBSET] + THENL [MESON_TAC[]; ASM_REWRITE_TAC[GSYM REAL_NOT_LT]] THEN + ASM_CASES_TAC `sphere(b:real^N,s) = {}` THENL + [FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [SPHERE_EQ_EMPTY]) THEN + ASM SET_TAC[]; + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE RAND_CONV [SPHERE_EQ_EMPTY])] THEN + REWRITE_TAC[REAL_NOT_LE] THEN DISCH_TAC THEN ASM_REWRITE_TAC[] THEN + RULE_ASSUM_TAC(REWRITE_RULE[REAL_NOT_LT]) THEN + ASM_CASES_TAC `r = &0` THEN + ASM_SIMP_TAC[SPHERE_SING; CONTINUOUS_ON_SING; REAL_LE_REFL] THENL + [ASM_CASES_TAC `c:real^M->bool = {}` THENL + [DISCH_THEN(K ALL_TAC) THEN MATCH_MP_TAC(MESON[] + `(?c. P(\x. c)) ==> ?f. P f`) THEN ASM SET_TAC[]; + DISCH_TAC THEN EXISTS_TAC `f:real^M->real^N` THEN ASM SET_TAC[]]; + ALL_TAC] THEN + ASM_CASES_TAC `s = &0` THENL + [ASM_SIMP_TAC[SPHERE_SING] THEN STRIP_TAC THEN + EXISTS_TAC `(\x. b):real^M->real^N` THEN + REWRITE_TAC[CONTINUOUS_ON_CONST] THEN ASM SET_TAC[]; + ALL_TAC] THEN + STRIP_TAC THEN + MP_TAC(ISPECL [`f:real^M->real^N`; `c:real^M->bool`; + `cball(a:real^M,r)`; `cball(b:real^N,s)`] + EXTEND_MAP_SPHERE_TO_SPHERE_GEN) THEN + ASM_REWRITE_TAC[CONVEX_CBALL; BOUNDED_CBALL; AFF_DIM_CBALL; + RELATIVE_FRONTIER_CBALL] THEN + DISCH_THEN MATCH_MP_TAC THEN + REPEAT(COND_CASES_TAC THEN ASM_REWRITE_TAC[INT_OF_NUM_LE]) THEN + ASM_REAL_ARITH_TAC);; + +let EXTEND_MAP_SPHERE_TO_SPHERE_COFINITE_GEN = prove + (`!f:real^M->real^N s t u p. + convex t /\ bounded t /\ convex u /\ bounded u /\ + aff_dim t <= aff_dim u + &1 /\ + closed s /\ s SUBSET relative_frontier t /\ + f continuous_on s /\ IMAGE f s SUBSET relative_frontier u /\ + (!c. c IN components(relative_frontier t DIFF s) ==> ~(c INTER p = {})) + ==> ?k g. FINITE k /\ k SUBSET p /\ + k SUBSET relative_frontier t /\ DISJOINT k s /\ + g continuous_on (relative_frontier t DIFF k) /\ + IMAGE g (relative_frontier t DIFF k) SUBSET + relative_frontier u /\ + !x. x IN s ==> g x = f x`, + REPEAT GEN_TAC THEN + ASM_CASES_TAC `s = (relative_frontier t:real^M->bool)` THENL + [ASM_REWRITE_TAC[] THEN STRIP_TAC THEN + MAP_EVERY EXISTS_TAC [`{}:real^M->bool`; `f:real^M->real^N`] THEN + ASM_REWRITE_TAC[FINITE_EMPTY; DIFF_EMPTY] THEN SET_TAC[]; + POP_ASSUM MP_TAC] THEN + ASM_CASES_TAC `relative_frontier t:real^M->bool = {}` THENL + [ASM SET_TAC[]; REPEAT STRIP_TAC] THEN + SUBGOAL_THEN + `?c q:real^M. c IN components (relative_frontier t DIFF s) /\ + q IN c /\ q IN relative_frontier t /\ ~(q IN s) /\ q IN p` + STRIP_ASSUME_TAC THENL + [MP_TAC(ISPEC `(relative_frontier t:real^M->bool) DIFF s` + UNIONS_COMPONENTS) THEN + DISCH_THEN(MP_TAC o MATCH_MP (SET_RULE + `s = u ==> ~(s = {}) ==> ~(u = {})`)) THEN + ANTS_TAC THENL [ASM SET_TAC[]; REWRITE_TAC[EMPTY_UNIONS]] THEN + REWRITE_TAC[NOT_FORALL_THM; NOT_IMP] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `c:real^M->bool` THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + FIRST_X_ASSUM(MP_TAC o SPEC `c:real^M->bool`) THEN + ASM_REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; IN_INTER] THEN + MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC THEN STRIP_TAC THEN + ASM_REWRITE_TAC[GSYM IN_DIFF] THEN + ASM_MESON_TAC[SUBSET; IN_COMPONENTS_SUBSET]; + ALL_TAC] THEN + SUBGOAL_THEN + `?af. affine af /\ aff_dim(t:real^M->bool) = aff_dim(af:real^M->bool) + &1` + STRIP_ASSUME_TAC THENL + [MP_TAC(ISPECL [`(:real^M)`; `aff_dim(t:real^M->bool) - &1`] + CHOOSE_AFFINE_SUBSET) THEN + REWRITE_TAC[SUBSET_UNIV; AFFINE_UNIV] THEN ANTS_TAC THENL + [MATCH_MP_TAC(INT_ARITH + `&0:int <= t /\ t <= n ==> --a <= t - a /\ t - &1 <= n`) THEN + REWRITE_TAC[AFF_DIM_LE_UNIV; AFF_DIM_UNIV; AFF_DIM_POS_LE] THEN + ASM_MESON_TAC[RELATIVE_FRONTIER_EMPTY; NOT_IN_EMPTY]; + MATCH_MP_TAC MONO_EXISTS THEN SIMP_TAC[] THEN INT_ARITH_TAC]; + ALL_TAC] THEN + MP_TAC(ISPECL [`t:real^M->bool`; `af:real^M->bool`; `q:real^M`] + HOMEOMORPHIC_PUNCTURED_SPHERE_AFFINE_GEN) THEN + ASM_REWRITE_TAC[homeomorphic; homeomorphism; LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`h:real^M->real^M`; `k:real^M->real^M`] THEN + STRIP_TAC THEN MP_TAC(ISPECL + [`(f:real^M->real^N) o (k:real^M->real^M)`; + `IMAGE (h:real^M->real^M) s`; + `(af:real^M->bool)`; + `u:real^N->bool`; + `IMAGE (h:real^M->real^M) (p INTER relative_frontier t DELETE q)`] + EXTEND_MAP_AFFINE_TO_SPHERE_COFINITE_GEN) THEN + ASM_REWRITE_TAC[] THEN ANTS_TAC THENL + [REPEAT CONJ_TAC THENL + [MATCH_MP_TAC COMPACT_CONTINUOUS_IMAGE THEN CONJ_TAC THENL + [FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET)) THEN + ASM SET_TAC[]; + ASM_MESON_TAC[COMPACT_EQ_BOUNDED_CLOSED; BOUNDED_SUBSET; + COMPACT_RELATIVE_FRONTIER_BOUNDED]]; + ASM_INT_ARITH_TAC; + ASM SET_TAC[]; + MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN CONJ_TAC THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET)) THEN + ASM SET_TAC[]; + REWRITE_TAC[IMAGE_o] THEN ASM SET_TAC[]; + X_GEN_TAC `l:real^M->bool` THEN STRIP_TAC THEN + SUBGOAL_THEN `~(l:real^M->bool = {})` ASSUME_TAC THENL + [ASM_MESON_TAC[IN_COMPONENTS_NONEMPTY]; ALL_TAC] THEN + SUBGOAL_THEN `?x:real^M. x IN l` STRIP_ASSUME_TAC THENL + [ASM SET_TAC[]; ALL_TAC] THEN + SUBGOAL_THEN `l SUBSET af DIFF IMAGE (h:real^M->real^M) s` + ASSUME_TAC THENL + [ASM_MESON_TAC[IN_COMPONENTS_SUBSET]; ALL_TAC] THEN + SUBGOAL_THEN `connected(l:real^M->bool)` ASSUME_TAC THENL + [ASM_MESON_TAC[IN_COMPONENTS_CONNECTED]; ALL_TAC] THEN + SUBGOAL_THEN + `?r. r IN components (relative_frontier t DIFF s) /\ + IMAGE (k:real^M->real^M) l SUBSET r` + STRIP_ASSUME_TAC THENL + [REWRITE_TAC[IN_COMPONENTS; LEFT_AND_EXISTS_THM] THEN + EXISTS_TAC `connected_component (relative_frontier t DIFF s) + ((k:real^M->real^M) x)` THEN + EXISTS_TAC `(k:real^M->real^M) x` THEN REWRITE_TAC[] THEN + CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + MATCH_MP_TAC CONNECTED_COMPONENT_MAXIMAL THEN + ASM_SIMP_TAC[FUN_IN_IMAGE] THEN + CONJ_TAC THENL [ALL_TAC; ASM SET_TAC[]] THEN + MATCH_MP_TAC CONNECTED_CONTINUOUS_IMAGE THEN ASM_REWRITE_TAC[] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET)) THEN + ASM SET_TAC[]; + ALL_TAC] THEN + FIRST_X_ASSUM(MP_TAC o SPEC `r:real^M->bool`) THEN + ASM_REWRITE_TAC[] THEN + GEN_REWRITE_TAC LAND_CONV [GSYM MEMBER_NOT_EMPTY] THEN + REWRITE_TAC[LEFT_IMP_EXISTS_THM; IN_INTER] THEN + X_GEN_TAC `z:real^M` THEN STRIP_TAC THEN + SUBGOAL_THEN `r SUBSET ((relative_frontier t:real^M->bool) DIFF s)` + ASSUME_TAC THENL [ASM_MESON_TAC[IN_COMPONENTS_SUBSET]; ALL_TAC] THEN + SUBGOAL_THEN `connected(r:real^M->bool)` ASSUME_TAC THENL + [ASM_MESON_TAC[IN_COMPONENTS_CONNECTED]; ALL_TAC] THEN + ASM_CASES_TAC `(q:real^M) IN r` THENL + [ALL_TAC; + REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN + EXISTS_TAC `(h:real^M->real^M) z` THEN REWRITE_TAC[IN_INTER] THEN + CONJ_TAC THENL [ALL_TAC; ASM SET_TAC[]] THEN + MATCH_MP_TAC(SET_RULE `!s. x IN s /\ s SUBSET t ==> x IN t`) THEN + EXISTS_TAC `IMAGE (h:real^M->real^M) r` THEN + ASM_SIMP_TAC[FUN_IN_IMAGE] THEN MATCH_MP_TAC COMPONENTS_MAXIMAL THEN + EXISTS_TAC `af DIFF IMAGE (h:real^M->real^M) s` THEN + ASM_REWRITE_TAC[] THEN REPEAT CONJ_TAC THENL + [MATCH_MP_TAC CONNECTED_CONTINUOUS_IMAGE THEN ASM_REWRITE_TAC[] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET)) THEN + ASM SET_TAC[]; + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; IN_DIFF; IN_ELIM_THM] THEN + X_GEN_TAC `y:real^M` THEN DISCH_TAC THEN + CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + REWRITE_TAC[SET_RULE + `~(h y IN IMAGE h s) <=> !y'. y' IN s ==> ~(h y = h y')`] THEN + X_GEN_TAC `y':real^M` THEN DISCH_TAC THEN + DISCH_THEN(MP_TAC o AP_TERM `k:real^M->real^M`) THEN + MATCH_MP_TAC(MESON[] + `k(h y) = y /\ k(h y') = y' /\ ~(y = y') + ==> k(h y) = k(h y') ==> F`) THEN + ASM SET_TAC[]; + ASM SET_TAC[]]] THEN + SUBGOAL_THEN + `?n. open_in (subtopology euclidean (relative_frontier t)) n /\ + (q:real^M) IN n /\ n INTER IMAGE (k:real^M->real^M) l = {}` + STRIP_ASSUME_TAC THENL + [EXISTS_TAC `relative_frontier t DIFF + IMAGE (k:real^M->real^M) (closure l)` THEN + SUBGOAL_THEN `closure l SUBSET (af:real^M->bool)` ASSUME_TAC THENL + [MATCH_MP_TAC CLOSURE_MINIMAL THEN + ASM_SIMP_TAC[CLOSED_AFFINE] THEN ASM SET_TAC[]; + ALL_TAC] THEN + REPEAT CONJ_TAC THENL + [MATCH_MP_TAC OPEN_IN_DIFF THEN REWRITE_TAC[OPEN_IN_REFL] THEN + MATCH_MP_TAC CLOSED_SUBSET THEN + CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + MATCH_MP_TAC COMPACT_IMP_CLOSED THEN + MATCH_MP_TAC COMPACT_CONTINUOUS_IMAGE THEN + ASM_REWRITE_TAC[COMPACT_CLOSURE] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET)) THEN + ASM SET_TAC[]; + ASM SET_TAC[]; + MP_TAC(ISPEC `l:real^M->bool` CLOSURE_SUBSET) THEN SET_TAC[]]; + ALL_TAC] THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP OPEN_IN_IMP_SUBSET) THEN + SUBGOAL_THEN + `?w. connected w /\ w SUBSET r DELETE q /\ + (k:real^M->real^M) x IN w /\ ~((n DELETE q) INTER w = {})` + STRIP_ASSUME_TAC THENL + [ALL_TAC; + MATCH_MP_TAC(TAUT `F ==> p`) THEN + SUBGOAL_THEN `IMAGE (h:real^M->real^M) w SUBSET l` MP_TAC THENL + [ALL_TAC; ASM SET_TAC[]] THEN + MATCH_MP_TAC COMPONENTS_MAXIMAL THEN + EXISTS_TAC `af DIFF IMAGE (h:real^M->real^M) s` THEN + ASM_REWRITE_TAC[] THEN REPEAT CONJ_TAC THENL + [MATCH_MP_TAC CONNECTED_CONTINUOUS_IMAGE THEN ASM_REWRITE_TAC[] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET)) THEN + ASM SET_TAC[]; + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; IN_DIFF; IN_ELIM_THM] THEN + X_GEN_TAC `y:real^M` THEN DISCH_TAC THEN + CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + REWRITE_TAC[SET_RULE + `~(h y IN IMAGE h s) <=> !y'. y' IN s ==> ~(h y = h y')`] THEN + X_GEN_TAC `y':real^M` THEN DISCH_TAC THEN + DISCH_THEN(MP_TAC o AP_TERM `k:real^M->real^M`) THEN + MATCH_MP_TAC(MESON[] + `k(h y) = y /\ k(h y') = y' /\ ~(y = y') + ==> k(h y) = k(h y') ==> F`) THEN + ASM SET_TAC[]; + ASM SET_TAC[]]] THEN + SUBGOAL_THEN `path_connected(r:real^M->bool)` MP_TAC THENL + [W(MP_TAC o PART_MATCH (lhand o rand) PATH_CONNECTED_EQ_CONNECTED_LPC o + snd) THEN + ANTS_TAC THENL [ALL_TAC; ASM_MESON_TAC[]] THEN + MATCH_MP_TAC LOCALLY_OPEN_SUBSET THEN + EXISTS_TAC `(relative_frontier t:real^M->bool)` THEN + ASM_SIMP_TAC[LOCALLY_PATH_CONNECTED_SPHERE_GEN] THEN + MATCH_MP_TAC OPEN_IN_TRANS THEN + EXISTS_TAC `(relative_frontier t:real^M->bool) DIFF s` THEN + CONJ_TAC THENL + [MATCH_MP_TAC OPEN_IN_COMPONENTS_LOCALLY_CONNECTED THEN + ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC LOCALLY_OPEN_SUBSET THEN + EXISTS_TAC `(relative_frontier t:real^M->bool)` THEN + ASM_SIMP_TAC[LOCALLY_CONNECTED_SPHERE_GEN]; + ALL_TAC] THEN + MATCH_MP_TAC OPEN_IN_DIFF THEN REWRITE_TAC[OPEN_IN_REFL] THEN + MATCH_MP_TAC CLOSED_SUBSET THEN ASM_REWRITE_TAC[]; + ALL_TAC] THEN + REWRITE_TAC[PATH_CONNECTED_ARCWISE] THEN + DISCH_THEN(MP_TAC o SPECL [`(k:real^M->real^M) x`; `q:real^M`]) THEN + ANTS_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + DISCH_THEN(X_CHOOSE_THEN `g:real^1->real^M` STRIP_ASSUME_TAC) THEN + FIRST_X_ASSUM(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC o + GEN_REWRITE_RULE I [arc]) THEN + DISCH_TAC THEN + SUBGOAL_THEN + `open_in (subtopology euclidean (interval[vec 0,vec 1])) + {x | x IN interval[vec 0,vec 1] /\ + (g:real^1->real^M) x IN n}` + MP_TAC THENL + [MATCH_MP_TAC CONTINUOUS_OPEN_IN_PREIMAGE_GEN THEN + EXISTS_TAC `(relative_frontier t:real^M->bool)` THEN + ASM_REWRITE_TAC[GSYM path; GSYM path_image] THEN + ASM SET_TAC[]; + ALL_TAC] THEN + REWRITE_TAC[OPEN_IN_CONTAINS_CBALL] THEN + REWRITE_TAC[IN_ELIM_THM; SUBSET_RESTRICT] THEN + DISCH_THEN(MP_TAC o SPEC `vec 1:real^1`) THEN + REWRITE_TAC[ENDS_IN_UNIT_INTERVAL] THEN + ANTS_TAC THENL [ASM_MESON_TAC[pathfinish]; ALL_TAC] THEN + DISCH_THEN(X_CHOOSE_THEN `r:real` + (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + ABBREV_TAC `t' = lift(&1 - min (&1 / &2) r)` THEN + SUBGOAL_THEN `t' IN interval[vec 0:real^1,vec 1]` ASSUME_TAC THENL + [EXPAND_TAC "t'" THEN SIMP_TAC[IN_INTERVAL_1; LIFT_DROP; DROP_VEC] THEN + ASM_REAL_ARITH_TAC; + ALL_TAC] THEN + GEN_REWRITE_TAC LAND_CONV [SUBSET] THEN + DISCH_THEN(MP_TAC o SPEC `t':real^1`) THEN + ASM_REWRITE_TAC[IN_INTER; IN_ELIM_THM; IN_CBALL; DIST_REAL; + DROP_VEC; GSYM drop] THEN + ANTS_TAC THENL + [EXPAND_TAC "t'" THEN REWRITE_TAC[LIFT_DROP] THEN ASM_REAL_ARITH_TAC; + DISCH_TAC] THEN + EXISTS_TAC `IMAGE (g:real^1->real^M) (interval[vec 0,t'])` THEN + REPEAT CONJ_TAC THENL + [MATCH_MP_TAC CONNECTED_CONTINUOUS_IMAGE THEN + REWRITE_TAC[CONNECTED_INTERVAL] THEN + MATCH_MP_TAC CONTINUOUS_ON_SUBSET THEN + EXISTS_TAC `interval[vec 0:real^1,vec 1]` THEN + ASM_REWRITE_TAC[GSYM path; SUBSET_INTERVAL_1] THEN + ASM_REWRITE_TAC[REAL_LE_REFL; GSYM IN_INTERVAL_1]; + REWRITE_TAC[SET_RULE + `s SUBSET t DELETE q <=> s SUBSET t /\ !x. x IN s ==> ~(x = q)`] THEN + CONJ_TAC THENL + [TRANS_TAC SUBSET_TRANS + `IMAGE (g:real^1->real^M) (interval[vec 0,vec 1])` THEN + CONJ_TAC THENL + [MATCH_MP_TAC IMAGE_SUBSET THEN + ASM_REWRITE_TAC[REAL_LE_REFL; GSYM IN_INTERVAL_1; + SUBSET_INTERVAL_1]; + ASM_REWRITE_TAC[GSYM path_image]]; + REWRITE_TAC[FORALL_IN_IMAGE] THEN + X_GEN_TAC `t'':real^1` THEN DISCH_TAC THEN + FIRST_X_ASSUM(fun th -> GEN_REWRITE_TAC (RAND_CONV o RAND_CONV) + [SYM th]) THEN + REWRITE_TAC[pathfinish] THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`t'':real^1`; `vec 1:real^1`]) THEN + ASM_REWRITE_TAC[GSYM DROP_EQ] THEN + UNDISCH_TAC `t'' IN interval[vec 0:real^1,t']` THEN + EXPAND_TAC "t'" THEN + REWRITE_TAC[IN_INTERVAL_1; DROP_VEC; LIFT_DROP] THEN + ASM_REAL_ARITH_TAC]; + REWRITE_TAC[IN_IMAGE] THEN EXISTS_TAC `vec 0:real^1` THEN + CONJ_TAC THENL [ASM_MESON_TAC[pathstart]; ALL_TAC] THEN + EXPAND_TAC "t'" THEN + REWRITE_TAC[IN_INTERVAL_1; DROP_VEC; LIFT_DROP] THEN + ASM_REAL_ARITH_TAC; + REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN + ONCE_REWRITE_TAC[INTER_COMM] THEN + REWRITE_TAC[EXISTS_IN_IMAGE; IN_INTER] THEN + EXISTS_TAC `t':real^1` THEN CONJ_TAC THENL + [EXPAND_TAC "t'" THEN + REWRITE_TAC[IN_INTERVAL_1; DROP_VEC; LIFT_DROP] THEN + ASM_REAL_ARITH_TAC; + ASM_REWRITE_TAC[IN_DELETE] THEN + FIRST_X_ASSUM(fun th -> GEN_REWRITE_TAC (RAND_CONV o RAND_CONV) + [SYM th]) THEN + REWRITE_TAC[pathfinish] THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`t':real^1`; `vec 1:real^1`]) THEN + ASM_REWRITE_TAC[GSYM DROP_EQ] THEN + EXPAND_TAC "t'" THEN + REWRITE_TAC[IN_INTERVAL_1; DROP_VEC; LIFT_DROP] THEN + ASM_REAL_ARITH_TAC]]]; + ALL_TAC] THEN + ASM_SIMP_TAC[DOT_BASIS; LE_REFL; DIMINDEX_GE_1; LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`tk:real^M->bool`; `g:real^M->real^N`] THEN + REWRITE_TAC[o_THM] THEN + STRIP_TAC THEN EXISTS_TAC `q INSERT IMAGE (k:real^M->real^M) tk` THEN + EXISTS_TAC `(g:real^M->real^N) o (h:real^M->real^M)` THEN + ASM_SIMP_TAC[FINITE_INSERT; FINITE_IMAGE; o_THM] THEN REPEAT CONJ_TAC THENL + [MATCH_MP_TAC(SET_RULE + `a IN t /\ s SUBSET t DELETE a ==> a INSERT s SUBSET t`) THEN + ASM_REWRITE_TAC[] THEN + TRANS_TAC SUBSET_TRANS + `p INTER (relative_frontier t:real^M->bool) DELETE q` THEN + CONJ_TAC THENL [ALL_TAC; ASM SET_TAC[]] THEN + ASM_REWRITE_TAC[] THEN FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP + (SET_RULE `t SUBSET IMAGE h s ==> IMAGE k (IMAGE h s) SUBSET s + ==> IMAGE k t SUBSET s`)) THEN + REWRITE_TAC[GSYM IMAGE_o] THEN + MATCH_MP_TAC(SET_RULE + `(!x. x IN s ==> f x = x) ==> IMAGE f s SUBSET s`) THEN + REWRITE_TAC[o_THM] THEN ASM SET_TAC[]; + ASM SET_TAC[]; + ASM SET_TAC[]; + MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN CONJ_TAC THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET)) THEN + ASM SET_TAC[]; + REWRITE_TAC[IMAGE_o] THEN ASM SET_TAC[]; + ASM SET_TAC[]]);; + +let EXTEND_MAP_SPHERE_TO_SPHERE_COFINITE = prove + (`!f:real^M->real^N s a d b e p. + dimindex(:M) <= dimindex(:N) + 1 /\ + (&0 < d /\ s = {} ==> &0 <= e) /\ + closed s /\ s SUBSET sphere(a,d) /\ + f continuous_on s /\ IMAGE f s SUBSET sphere(b,e) /\ + (!c. c IN components(sphere(a,d) DIFF s) ==> ~(c INTER p = {})) + ==> ?k g. FINITE k /\ k SUBSET p /\ + k SUBSET sphere(a,d) /\ DISJOINT k s /\ + g continuous_on (sphere(a,d) DIFF k) /\ + IMAGE g (sphere(a,d) DIFF k) SUBSET sphere(b,e) /\ + !x. x IN s ==> g x = f x`, + REPEAT GEN_TAC THEN ASM_CASES_TAC `s = sphere(a:real^M,d)` THENL + [ASM_REWRITE_TAC[] THEN STRIP_TAC THEN + MAP_EVERY EXISTS_TAC [`{}:real^M->bool`; `f:real^M->real^N`] THEN + ASM_REWRITE_TAC[FINITE_EMPTY; DIFF_EMPTY] THEN SET_TAC[]; + POP_ASSUM MP_TAC] THEN + ASM_CASES_TAC `d < &0` THENL + [ASM_SIMP_TAC[SPHERE_EMPTY] THEN SET_TAC[]; ALL_TAC] THEN + ASM_CASES_TAC `d = &0` THENL + [ASM_SIMP_TAC[SPHERE_SING] THEN + ASM_CASES_TAC `s:real^M->bool = {}` THENL + [ASM_REWRITE_TAC[]; ASM SET_TAC[]] THEN + REPEAT STRIP_TAC THEN + EXISTS_TAC `{a:real^M}` THEN + REWRITE_TAC[FINITE_SING; CONTINUOUS_ON_EMPTY; DIFF_EQ_EMPTY] THEN + FIRST_X_ASSUM(MP_TAC o SPEC `{a:real^M}`) THEN + REWRITE_TAC[DIFF_EMPTY; IN_COMPONENTS_SELF; CONNECTED_SING] THEN + REWRITE_TAC[IMAGE_CLAUSES] THEN SET_TAC[]; + ALL_TAC] THEN + SUBGOAL_THEN `&0 < d` ASSUME_TAC THENL + [ASM_REAL_ARITH_TAC; ALL_TAC] THEN + ASM_CASES_TAC `e = &0` THENL + [ASM_SIMP_TAC[SPHERE_SING] THEN REPEAT STRIP_TAC THEN + EXISTS_TAC `{}:real^M->bool` THEN + EXISTS_TAC `(\x. b):real^M->real^N` THEN + REWRITE_TAC[CONTINUOUS_ON_CONST; FINITE_EMPTY] THEN ASM SET_TAC[]; + REPEAT STRIP_TAC] THEN + SUBGOAL_THEN `&0 <= e` ASSUME_TAC THENL + [ASM_CASES_TAC `s:real^M->bool = {}` THEN ASM_SIMP_TAC[] THEN + MP_TAC(SYM(ISPECL [`b:real^N`; `e:real`] SPHERE_EQ_EMPTY)) THEN + SIMP_TAC[GSYM REAL_NOT_LT] THEN ASM SET_TAC[]; + ALL_TAC] THEN + SUBGOAL_THEN `&0 < e` ASSUME_TAC THENL + [ASM_REAL_ARITH_TAC; ALL_TAC] THEN + MP_TAC(ISPECL + [`f:real^M->real^N`; `s:real^M->bool`; `cball(a:real^M,d)`; + `cball(b:real^N,e)`; `p:real^M->bool`] + EXTEND_MAP_SPHERE_TO_SPHERE_COFINITE_GEN) THEN + ASM_REWRITE_TAC[CONVEX_CBALL; BOUNDED_CBALL] THEN + REWRITE_TAC[AFF_DIM_CBALL] THEN + MP_TAC(ISPECL [`a:real^M`; `d:real`] RELATIVE_FRONTIER_CBALL) THEN + MP_TAC(ISPECL [`b:real^N`; `e:real`] RELATIVE_FRONTIER_CBALL) THEN + ASM_REWRITE_TAC[] THEN REPEAT(DISCH_THEN SUBST1_TAC) THEN + ASM_REWRITE_TAC[INT_OF_NUM_ADD; INT_OF_NUM_LE]);; + +(* ------------------------------------------------------------------------- *) +(* Borsuk-style characterization of separation. *) +(* ------------------------------------------------------------------------- *) + +let CONTINUOUS_ON_BORSUK_MAP = prove + (`!s a:real^N. + ~(a IN s) ==> (\x. inv(norm (x - a)) % (x - a)) continuous_on s`, + REPEAT STRIP_TAC THEN + MATCH_MP_TAC CONTINUOUS_ON_MUL THEN SIMP_TAC[o_DEF] THEN CONJ_TAC THENL + [MATCH_MP_TAC(REWRITE_RULE[o_DEF] CONTINUOUS_ON_INV); ALL_TAC] THEN + SIMP_TAC[CONTINUOUS_ON_LIFT_NORM_COMPOSE; CONTINUOUS_ON_SUB; + CONTINUOUS_ON_ID; CONTINUOUS_ON_CONST] THEN + REWRITE_TAC[NORM_EQ_0; VECTOR_SUB_EQ] THEN ASM_MESON_TAC[]);; + +let BORSUK_MAP_INTO_SPHERE = prove + (`!s a:real^N. + IMAGE (\x. inv(norm (x - a)) % (x - a)) s SUBSET sphere(vec 0,&1) <=> + ~(a IN s)`, + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; IN_SPHERE_0] THEN + REWRITE_TAC[NORM_MUL; REAL_ABS_INV; REAL_ABS_NORM] THEN + REWRITE_TAC[REAL_FIELD `inv x * x = &1 <=> ~(x = &0)`] THEN + REWRITE_TAC[NORM_EQ_0; VECTOR_SUB_EQ] THEN MESON_TAC[]);; + +let BORSUK_MAPS_HOMOTOPIC_IN_PATH_COMPONENT = prove + (`!s a b. path_component ((:real^N) DIFF s) a b + ==> homotopic_with (\x. T) (s,sphere(vec 0,&1)) + (\x. inv(norm(x - a)) % (x - a)) + (\x. inv(norm(x - b)) % (x - b))`, + REPEAT GEN_TAC THEN REWRITE_TAC[path_component; LEFT_IMP_EXISTS_THM] THEN + REWRITE_TAC[path; path_image; pathstart; pathfinish; SUBSET; + FORALL_IN_IMAGE; IN_UNIV; IN_DIFF] THEN + X_GEN_TAC `g:real^1->real^N` THEN STRIP_TAC THEN + SIMP_TAC[HOMOTOPIC_WITH] THEN + EXISTS_TAC `\z. inv(norm(sndcart z - g(fstcart z))) % + (sndcart z - (g:real^1->real^N)(fstcart z))` THEN + ASM_SIMP_TAC[FSTCART_PASTECART; SNDCART_PASTECART; IN_SPHERE_0; + SUBSET; FORALL_IN_IMAGE; FORALL_IN_PCROSS] THEN + CONJ_TAC THENL + [MATCH_MP_TAC CONTINUOUS_ON_MUL THEN REWRITE_TAC[o_DEF] THEN CONJ_TAC THENL + [MATCH_MP_TAC(REWRITE_RULE[o_DEF] CONTINUOUS_ON_INV) THEN + ASM_SIMP_TAC[FORALL_IN_PCROSS; FSTCART_PASTECART; SNDCART_PASTECART; + NORM_EQ_0; VECTOR_SUB_EQ] THEN CONJ_TAC + THENL [MATCH_MP_TAC CONTINUOUS_ON_LIFT_NORM_COMPOSE; ASM_MESON_TAC[]]; + ALL_TAC] THEN + MATCH_MP_TAC CONTINUOUS_ON_SUB THEN + SIMP_TAC[LINEAR_CONTINUOUS_ON; LINEAR_SNDCART] THEN + GEN_REWRITE_TAC LAND_CONV [GSYM o_DEF] THEN + MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN + SIMP_TAC[LINEAR_CONTINUOUS_ON; LINEAR_FSTCART] THEN + REWRITE_TAC[IMAGE_FSTCART_PCROSS] THEN ASM_MESON_TAC[CONTINUOUS_ON_EMPTY]; + REPEAT STRIP_TAC THEN + REWRITE_TAC[NORM_MUL; REAL_ABS_INV; REAL_ABS_NORM] THEN + MATCH_MP_TAC REAL_MUL_LINV THEN + ASM_REWRITE_TAC[NORM_EQ_0; VECTOR_SUB_EQ] THEN ASM_MESON_TAC[]]);; + +let NON_EXTENSIBLE_BORSUK_MAP = prove + (`!s c a:real^N. + compact s /\ c IN components((:real^N) DIFF s) /\ bounded c /\ a IN c + ==> ~(?g. g continuous_on (s UNION c) /\ + IMAGE g (s UNION c) SUBSET sphere (vec 0,&1) /\ + (!x. x IN s ==> g x = inv(norm(x - a)) % (x - a)))`, + REPEAT STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o MATCH_MP IN_COMPONENTS_SUBSET) THEN + REWRITE_TAC[SUBSET] THEN DISCH_THEN(MP_TAC o SPEC `a:real^N`) THEN + ASM_REWRITE_TAC[IN_DIFF] THEN STRIP_TAC THEN + SUBGOAL_THEN `c = connected_component ((:real^N) DIFF s) a` SUBST_ALL_TAC + THENL [ASM_MESON_TAC[IN_COMPONENTS; CONNECTED_COMPONENT_EQ]; ALL_TAC] THEN + MP_TAC(ISPECL + [`s UNION connected_component ((:real^N) DIFF s) a`; `a:real^N`] + BOUNDED_SUBSET_BALL) THEN + ASM_SIMP_TAC[BOUNDED_UNION; COMPACT_IMP_BOUNDED] THEN + DISCH_THEN(X_CHOOSE_THEN `r:real` STRIP_ASSUME_TAC) THEN + FIRST_ASSUM(MP_TAC o SPEC `a:real^N` o MATCH_MP NO_RETRACTION_CBALL) THEN + REWRITE_TAC[retract_of; retraction] THEN + EXISTS_TAC `\x. if x IN connected_component ((:real^N) DIFF s) a + then a + r % g(x) + else a + r % inv(norm(x - a)) % (x - a)` THEN + REWRITE_TAC[SPHERE_SUBSET_CBALL] THEN REPEAT CONJ_TAC THENL + [SUBGOAL_THEN `cball(a:real^N,r) = + (s UNION connected_component ((:real^N) DIFF s) a) UNION + (cball(a,r) DIFF connected_component ((:real^N) DIFF s) a)` + SUBST1_TAC THENL + [MP_TAC(ISPECL [`a:real^N`; `r:real`] BALL_SUBSET_CBALL) THEN ASM + SET_TAC[]; + ALL_TAC] THEN + MATCH_MP_TAC CONTINUOUS_ON_CASES THEN REPEAT CONJ_TAC THENL + [MATCH_MP_TAC CLOSED_UNION_COMPLEMENT_COMPONENT THEN + ASM_SIMP_TAC[IN_COMPONENTS; COMPACT_IMP_CLOSED; IN_UNIV; IN_DIFF] THEN + ASM_MESON_TAC[]; + MATCH_MP_TAC CLOSED_DIFF THEN + ASM_SIMP_TAC[CLOSED_CBALL; OPEN_CONNECTED_COMPONENT; GSYM closed; + COMPACT_IMP_CLOSED]; + MATCH_MP_TAC CONTINUOUS_ON_ADD THEN SIMP_TAC[CONTINUOUS_ON_CONST] THEN + MATCH_MP_TAC CONTINUOUS_ON_CMUL THEN ASM_SIMP_TAC[CONTINUOUS_ON_CONST]; + MATCH_MP_TAC CONTINUOUS_ON_ADD THEN SIMP_TAC[CONTINUOUS_ON_CONST] THEN + MATCH_MP_TAC CONTINUOUS_ON_CMUL THEN + MATCH_MP_TAC CONTINUOUS_ON_BORSUK_MAP THEN + ASM_SIMP_TAC[CENTRE_IN_CBALL; IN_DIFF; REAL_LT_IMP_LE] THEN + REWRITE_TAC[IN] THEN REWRITE_TAC[CONNECTED_COMPONENT_REFL_EQ] THEN + ASM_REWRITE_TAC[IN_DIFF; IN_UNIV]; + REPEAT STRIP_TAC THEN AP_TERM_TAC THEN AP_TERM_TAC THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN ASM SET_TAC[]]; + + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE] THEN + REPEAT STRIP_TAC THEN COND_CASES_TAC THEN + ASM_REWRITE_TAC[IN_SPHERE; NORM_ARITH `dist(a:real^N,a + x) = norm x`; + NORM_MUL] THEN + ASM_SIMP_TAC[REAL_ABS_INV; REAL_ABS_NORM; VECTOR_SUB_EQ; + REAL_FIELD `&0 < r ==> abs r = r /\ (r * x = r <=> x = &1)`; + REAL_FIELD `inv x * x = &1 <=> ~(x = &0)`; NORM_EQ_0] + THENL + [ONCE_REWRITE_TAC[GSYM IN_SPHERE_0] THEN ASM SET_TAC[]; + UNDISCH_TAC `~(x IN connected_component ((:real^N) DIFF s) a)` THEN + SIMP_TAC[CONTRAPOS_THM; IN] THEN + ASM_REWRITE_TAC[CONNECTED_COMPONENT_REFL_EQ; IN_DIFF; IN_UNIV]]; + SIMP_TAC[IN_SPHERE; ONCE_REWRITE_RULE[NORM_SUB] dist] THEN + ASM_SIMP_TAC[VECTOR_MUL_ASSOC; REAL_MUL_RINV; REAL_LT_IMP_NZ] THEN + REWRITE_TAC[VECTOR_ARITH `a + &1 % (x - a):real^N = x`] THEN + REPEAT STRIP_TAC THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE + `s UNION t SUBSET u ==> !x. x IN t /\ ~(x IN u) ==> wev`)) THEN + EXISTS_TAC `x:real^N` THEN + ASM_REWRITE_TAC[ONCE_REWRITE_RULE[NORM_SUB] dist; IN_BALL; + REAL_LT_REFL]]);; + +let BORSUK_MAP_ESSENTIAL_BOUNDED_COMPONENT = prove + (`!s a. compact s /\ ~(a IN s) + ==> (bounded(connected_component ((:real^N) DIFF s) a) <=> + ~(?c. homotopic_with (\x. T) (s,sphere(vec 0:real^N,&1)) + (\x. inv(norm(x - a)) % (x - a)) (\x. c)))`, + REPEAT STRIP_TAC THEN ASM_CASES_TAC `s:real^N->bool = {}` THENL + [ASM_SIMP_TAC[DIFF_EMPTY; CONNECTED_COMPONENT_UNIV; NOT_BOUNDED_UNIV] THEN + SIMP_TAC[HOMOTOPIC_WITH; NOT_IN_EMPTY; PCROSS_EMPTY; IMAGE_CLAUSES; + CONTINUOUS_ON_EMPTY; EMPTY_SUBSET]; + ALL_TAC] THEN + EQ_TAC THENL + [ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN REWRITE_TAC[] THEN + REPEAT DISCH_TAC THEN + MP_TAC(ISPECL + [`\x:real^N. inv(norm(x - a)) % (x - a)`; `s:real^N->bool`; + `vec 0:real^N`; `&1`] + NULLHOMOTOPIC_INTO_SPHERE_EXTENSION) THEN + ASM_SIMP_TAC[COMPACT_IMP_CLOSED; NOT_IMP; CONTINUOUS_ON_BORSUK_MAP; + BORSUK_MAP_INTO_SPHERE] THEN + MP_TAC(ISPECL [`s:real^N->bool`; + `connected_component ((:real^N) DIFF s) a`; + `a:real^N`] NON_EXTENSIBLE_BORSUK_MAP) THEN + ASM_REWRITE_TAC[] THEN ANTS_TAC THENL + [GEN_REWRITE_TAC RAND_CONV [IN] THEN + REWRITE_TAC[CONNECTED_COMPONENT_REFL_EQ] THEN + ASM_REWRITE_TAC[IN_COMPONENTS; IN_DIFF; IN_UNIV] THEN ASM_MESON_TAC[]; + REWRITE_TAC[CONTRAPOS_THM] THEN MATCH_MP_TAC MONO_EXISTS THEN + GEN_TAC THEN MATCH_MP_TAC MONO_AND THEN CONJ_TAC THENL + [MESON_TAC[CONTINUOUS_ON_SUBSET; SUBSET_UNIV]; SET_TAC[]]]; + ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN REWRITE_TAC[] THEN + DISCH_TAC THEN + FIRST_ASSUM(MP_TAC o SPEC `vec 0:real^N` o MATCH_MP BOUNDED_SUBSET_BALL o + MATCH_MP COMPACT_IMP_BOUNDED) THEN + DISCH_THEN(X_CHOOSE_THEN `r:real` STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN + `?b. b IN connected_component ((:real^N) DIFF s) a /\ + ~(b IN ball(vec 0,r))` + MP_TAC THENL + [REWRITE_TAC[SET_RULE `(?b. b IN s /\ ~(b IN t)) <=> ~(s SUBSET t)`] THEN + ASM_MESON_TAC[BOUNDED_SUBSET; BOUNDED_BALL]; + DISCH_THEN(X_CHOOSE_THEN `b:real^N` STRIP_ASSUME_TAC)] THEN + SUBGOAL_THEN + `?c. homotopic_with (\x. T) (ball(vec 0:real^N,r),sphere (vec 0,&1)) + (\x. inv (norm (x - b)) % (x - b)) (\x. c)` + MP_TAC THENL + [MATCH_MP_TAC NULLHOMOTOPIC_FROM_CONTRACTIBLE THEN + ASM_SIMP_TAC[CONTINUOUS_ON_BORSUK_MAP; BORSUK_MAP_INTO_SPHERE; + CONVEX_IMP_CONTRACTIBLE; CONVEX_BALL]; + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `c:real^N` THEN STRIP_TAC] THEN + MATCH_MP_TAC HOMOTOPIC_WITH_TRANS THEN + EXISTS_TAC `\x:real^N. inv(norm (x - b)) % (x - b)` THEN CONJ_TAC THENL + [MATCH_MP_TAC BORSUK_MAPS_HOMOTOPIC_IN_PATH_COMPONENT THEN + ASM_SIMP_TAC[OPEN_PATH_CONNECTED_COMPONENT; GSYM closed; + COMPACT_IMP_CLOSED] THEN ASM_MESON_TAC[IN]; + ASM_MESON_TAC[HOMOTOPIC_WITH_SUBSET_LEFT]]]);; + +let HOMOTOPIC_BORSUK_MAPS_IN_BOUNDED_COMPONENT = prove + (`!s a b. + compact s /\ ~(a IN s) /\ ~(b IN s) /\ + bounded (connected_component ((:real^N) DIFF s) a) /\ + homotopic_with (\x. T) (s,sphere(vec 0,&1)) + (\x. inv(norm(x - a)) % (x - a)) + (\x. inv(norm(x - b)) % (x - b)) + ==> connected_component ((:real^N) DIFF s) a b`, + REPEAT STRIP_TAC THEN GEN_REWRITE_TAC I [GSYM IN] THEN + MP_TAC(ISPECL + [`s:real^N->bool`; `connected_component ((:real^N) DIFF s) a`; + `a:real^N`] NON_EXTENSIBLE_BORSUK_MAP) THEN + ASM_REWRITE_TAC[] THEN ANTS_TAC THENL + [GEN_REWRITE_TAC RAND_CONV [IN] THEN + REWRITE_TAC[CONNECTED_COMPONENT_REFL_EQ] THEN + ASM_REWRITE_TAC[IN_COMPONENTS; IN_DIFF; IN_UNIV] THEN ASM_MESON_TAC[]; + ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM]] THEN + DISCH_TAC THEN REWRITE_TAC[] THEN + MATCH_MP_TAC BORSUK_HOMOTOPY_EXTENSION THEN + EXISTS_TAC `\x:real^N. inv(norm(x - b)) % (x - b)` THEN + ASM_SIMP_TAC[COMPACT_IMP_CLOSED] THEN + ONCE_REWRITE_TAC[HOMOTOPIC_WITH_SYM] THEN + ASM_SIMP_TAC[CONTINUOUS_ON_BORSUK_MAP; IN_UNION; BORSUK_MAP_INTO_SPHERE] THEN + REWRITE_TAC[RIGHT_EXISTS_AND_THM] THEN CONJ_TAC THENL + [MATCH_MP_TAC CLOSED_UNION_COMPLEMENT_COMPONENT THEN + ASM_SIMP_TAC[COMPACT_IMP_CLOSED; IN_COMPONENTS; IN_DIFF; IN_UNIV] THEN + ASM_MESON_TAC[]; + EXISTS_TAC `(:real^N) DELETE (vec 0)` THEN + ASM_SIMP_TAC[SPHERE_RETRACT_OF_PUNCTURED_UNIVERSE; REAL_LT_01; + OPEN_DELETE; OPEN_UNIV]]);; + +let BORSUK_MAPS_HOMOTOPIC_IN_CONNECTED_COMPONENT_EQ = prove + (`!s a b. 2 <= dimindex(:N) /\ compact s /\ ~(a IN s) /\ ~(b IN s) + ==> (homotopic_with (\x. T) (s,sphere(vec 0,&1)) + (\x. inv(norm(x - a)) % (x - a)) + (\x. inv(norm(x - b)) % (x - b)) <=> + connected_component ((:real^N) DIFF s) a b)`, + REPEAT STRIP_TAC THEN EQ_TAC THENL + [DISCH_TAC; + ASM_SIMP_TAC[GSYM OPEN_PATH_CONNECTED_COMPONENT; GSYM closed; + COMPACT_IMP_CLOSED] THEN + REWRITE_TAC[BORSUK_MAPS_HOMOTOPIC_IN_PATH_COMPONENT]] THEN + ASM_CASES_TAC `bounded(connected_component ((:real^N) DIFF s) a)` THENL + [MATCH_MP_TAC HOMOTOPIC_BORSUK_MAPS_IN_BOUNDED_COMPONENT THEN + ASM_REWRITE_TAC[]; + ALL_TAC] THEN + ASM_CASES_TAC `bounded(connected_component ((:real^N) DIFF s) b)` THENL + [ONCE_REWRITE_TAC[CONNECTED_COMPONENT_SYM_EQ] THEN + MATCH_MP_TAC HOMOTOPIC_BORSUK_MAPS_IN_BOUNDED_COMPONENT THEN + ASM_REWRITE_TAC[] THEN ONCE_REWRITE_TAC[HOMOTOPIC_WITH_SYM] THEN + ASM_REWRITE_TAC[]; + ALL_TAC] THEN + MP_TAC(ISPECL [`(:real^N) DIFF s`; `a:real^N`; `b:real^N`] + COBOUNDED_UNIQUE_UNBOUNDED_COMPONENT) THEN + ASM_REWRITE_TAC[CONNECTED_COMPONENT_EQ_EQ; IN_DIFF; IN_UNIV; + SET_RULE `UNIV DIFF (UNIV DIFF s) = s`] THEN + ASM_SIMP_TAC[COMPACT_IMP_BOUNDED]);; + +let BORSUK_SEPARATION_THEOREM_GEN = prove + (`!s:real^N->bool. + compact s + ==> ((!c. c IN components((:real^N) DIFF s) ==> ~bounded c) <=> + (!f. f continuous_on s /\ IMAGE f s SUBSET sphere(vec 0:real^N,&1) + ==> ?c. homotopic_with (\x. T) (s,sphere(vec 0,&1)) f (\x. c)))`, + REPEAT STRIP_TAC THEN EQ_TAC THENL + [ALL_TAC; + ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN + REWRITE_TAC[NOT_FORALL_THM; components; EXISTS_IN_GSPEC; NOT_IMP; + IN_UNIV; IN_DIFF] THEN + DISCH_THEN(X_CHOOSE_THEN `a:real^N` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `\x:real^N. inv(norm(x - a)) % (x - a)` THEN + ASM_SIMP_TAC[GSYM BORSUK_MAP_ESSENTIAL_BOUNDED_COMPONENT; + CONTINUOUS_ON_BORSUK_MAP; BORSUK_MAP_INTO_SPHERE]] THEN + DISCH_TAC THEN X_GEN_TAC `f:real^N->real^N` THEN STRIP_TAC THEN + MP_TAC(ISPECL + [`f:real^N->real^N`; `s:real^N->bool`; `vec 0:real^N`; `&1:real`] + EXTEND_MAP_UNIV_TO_SPHERE_NO_BOUNDED_COMPONENT) THEN + ASM_REWRITE_TAC[LE_REFL; REAL_POS] THEN + DISCH_THEN(X_CHOOSE_THEN `g:real^N->real^N` STRIP_ASSUME_TAC) THEN + MP_TAC(ISPECL + [`g:real^N->real^N`; `(:real^N)`; `sphere(vec 0:real^N,&1)`] + NULLHOMOTOPIC_FROM_CONTRACTIBLE) THEN + ASM_REWRITE_TAC[CONTRACTIBLE_UNIV] THEN + MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC THEN + DISCH_THEN(MP_TAC o SPEC `s:real^N->bool` o MATCH_MP + (REWRITE_RULE[IMP_CONJ] HOMOTOPIC_WITH_SUBSET_LEFT)) THEN + REWRITE_TAC[SUBSET_UNIV] THEN + MATCH_MP_TAC(ONCE_REWRITE_RULE[IMP_CONJ_ALT] + HOMOTOPIC_WITH_EQ) THEN + ASM_SIMP_TAC[]);; + +let BORSUK_SEPARATION_THEOREM = prove + (`!s:real^N->bool. + 2 <= dimindex(:N) /\ compact s + ==> (connected((:real^N) DIFF s) <=> + !f. f continuous_on s /\ IMAGE f s SUBSET sphere(vec 0:real^N,&1) + ==> ?c. homotopic_with (\x. T) (s,sphere(vec 0,&1)) f (\x. c))`, + SIMP_TAC[GSYM BORSUK_SEPARATION_THEOREM_GEN] THEN + X_GEN_TAC `s:real^N->bool` THEN STRIP_TAC THEN EQ_TAC THENL + [DISCH_TAC THEN + MP_TAC(ISPEC `(:real^N) DIFF s` COMPONENTS_EQ_SING) THEN + MP_TAC(ISPEC `(:real^N) DIFF s` COBOUNDED_IMP_UNBOUNDED) THEN + ASM_CASES_TAC `(:real^N) DIFF s = {}` THEN + ASM_SIMP_TAC[COMPACT_IMP_BOUNDED; SET_RULE `UNIV DIFF (UNIV DIFF s) = s`; + BOUNDED_EMPTY; FORALL_IN_INSERT; NOT_IN_EMPTY]; + + REWRITE_TAC[components; FORALL_IN_GSPEC; IN_DIFF; IN_UNIV] THEN + DISCH_TAC THEN REWRITE_TAC[CONNECTED_EQ_CONNECTED_COMPONENT_EQ] THEN + REWRITE_TAC[IN_DIFF; IN_UNIV] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC COBOUNDED_UNIQUE_UNBOUNDED_COMPONENT THEN + ASM_SIMP_TAC[COMPACT_IMP_BOUNDED; + SET_RULE `UNIV DIFF (UNIV DIFF s) = s`]]);; + +let HOMOTOPY_EQUIVALENT_SEPARATION = prove + (`!s t. compact s /\ compact t /\ s homotopy_equivalent t + ==> (connected((:real^N) DIFF s) <=> connected((:real^N) DIFF t))`, + let special = prove + (`!s:real^1->bool. + bounded s /\ connected((:real^1) DIFF s) ==> s = {}`, + REWRITE_TAC[GSYM IS_INTERVAL_CONNECTED_1] THEN REPEAT STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o MATCH_MP BOUNDED_SUBSET_OPEN_INTERVAL) THEN + REWRITE_TAC[LEFT_IMP_EXISTS_THM; EXTENSION; NOT_IN_EMPTY] THEN + MAP_EVERY X_GEN_TAC [`a:real^1`; `b:real^1`] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IS_INTERVAL_1]) THEN + DISCH_THEN(MP_TAC o SPECL [`a:real^1`; `b:real^1`]) THEN + REWRITE_TAC[IN_UNIV; IN_DIFF; SUBSET; IN_INTERVAL_1] THEN + MESON_TAC[REAL_LT_REFL; REAL_LT_IMP_LE]) in + REPEAT STRIP_TAC THEN + SUBGOAL_THEN `1 <= dimindex(:N)` MP_TAC THENL + [REWRITE_TAC[DIMINDEX_GE_1]; + REWRITE_TAC[ARITH_RULE `1 <= n <=> n = 1 \/ 2 <= n`] THEN + REWRITE_TAC[GSYM DIMINDEX_1]] THEN + STRIP_TAC THENL + [ASSUME_TAC(GEOM_EQUAL_DIMENSION_RULE(ASSUME `dimindex(:N) = dimindex(:1)`) + special) THEN + EQ_TAC THEN DISCH_TAC THENL + [FIRST_X_ASSUM(MP_TAC o SPEC `s:real^N->bool`); + FIRST_X_ASSUM(MP_TAC o SPEC `t:real^N->bool`)] THEN + ASM_SIMP_TAC[COMPACT_IMP_BOUNDED] THEN DISCH_TAC THEN + UNDISCH_TAC `(s:real^N->bool) homotopy_equivalent (t:real^N->bool)` THEN + ASM_REWRITE_TAC[HOMOTOPY_EQUIVALENT_EMPTY] THEN DISCH_TAC THEN + ASM_REWRITE_TAC[CONNECTED_UNIV; DIFF_EMPTY]; + REPEAT STRIP_TAC THEN ASM_SIMP_TAC[BORSUK_SEPARATION_THEOREM] THEN + MATCH_MP_TAC HOMOTOPY_EQUIVALENT_COHOMOTOPIC_TRIVIALITY_NULL THEN + ASM_REWRITE_TAC[]]);; + +let JORDAN_BROUWER_SEPARATION = prove + (`!s a:real^N r. + &0 < r /\ s homeomorphic sphere(a,r) ==> ~connected((:real^N) DIFF s)`, + REPEAT GEN_TAC THEN STRIP_TAC THEN + MP_TAC(ISPECL [`s:real^N->bool`; `sphere(a:real^N,r)`] + HOMOTOPY_EQUIVALENT_SEPARATION) THEN + ANTS_TAC THENL + [ASM_MESON_TAC[HOMEOMORPHIC_COMPACTNESS; COMPACT_SPHERE; + HOMEOMORPHIC_IMP_HOMOTOPY_EQUIVALENT]; + DISCH_THEN SUBST1_TAC] THEN + DISCH_TAC THEN MP_TAC(ISPECL + [`(:real^N) DIFF sphere(a,r)`; + `ball(a:real^N,r)`] CONNECTED_INTER_FRONTIER) THEN + ASM_SIMP_TAC[FRONTIER_BALL; NOT_IMP] THEN REPEAT CONJ_TAC THENL + [REWRITE_TAC[GSYM CBALL_DIFF_BALL] THEN MATCH_MP_TAC(SET_RULE + `~(b = {}) + ==> ~((UNIV DIFF (c DIFF b)) INTER b = {})`) THEN + ASM_SIMP_TAC[BALL_EQ_EMPTY; REAL_NOT_LE]; + MATCH_MP_TAC(SET_RULE + `~(s UNION t = UNIV) ==> ~(UNIV DIFF t DIFF s = {})`) THEN + REWRITE_TAC[BALL_UNION_SPHERE] THEN + MESON_TAC[BOUNDED_CBALL; NOT_BOUNDED_UNIV]; + SET_TAC[]]);; + +let JORDAN_BROUWER_FRONTIER = prove + (`!s t a:real^N r. + 2 <= dimindex(:N) /\ + s homeomorphic sphere(a,r) /\ t IN components((:real^N) DIFF s) + ==> frontier t = s`, + let lemma = prove + (`!s a r. 2 <= dimindex(:N) /\ &0 < r /\ s PSUBSET sphere(a,r) + ==> connected((:real^N) DIFF s)`, + REWRITE_TAC[PSUBSET_ALT; SUBSET; IN_SPHERE; GSYM REAL_LE_ANTISYM] THEN + REPEAT STRIP_TAC THEN + SUBGOAL_THEN + `(:real^N) DIFF s = + {x:real^N | dist(a,x) <= r /\ ~(x IN s)} UNION + {x:real^N | r <= dist(a,x) /\ ~(x IN s)}` + SUBST1_TAC THENL + [SET_TAC[REAL_LE_TOTAL]; MATCH_MP_TAC CONNECTED_UNION] THEN + REPEAT CONJ_TAC THENL + [MATCH_MP_TAC CONNECTED_INTERMEDIATE_CLOSURE THEN + EXISTS_TAC `ball(a:real^N,r)` THEN + ASM_SIMP_TAC[CONNECTED_BALL; CLOSURE_BALL; SUBSET; IN_BALL; IN_CBALL; + IN_ELIM_THM] THEN + ASM_MESON_TAC[REAL_LT_IMP_LE; REAL_NOT_LE]; + MATCH_MP_TAC CONNECTED_INTERMEDIATE_CLOSURE THEN + EXISTS_TAC `(:real^N) DIFF cball(a,r)` THEN + REWRITE_TAC[CLOSURE_COMPLEMENT; SUBSET; IN_DIFF; IN_UNIV; + IN_BALL; IN_CBALL; IN_ELIM_THM; INTERIOR_CBALL] THEN + CONJ_TAC THENL [ALL_TAC; ASM_MESON_TAC[REAL_LT_IMP_LE; REAL_NOT_LE]] THEN + MATCH_MP_TAC CONNECTED_OPEN_DIFF_CBALL THEN + ASM_REWRITE_TAC[SUBSET_UNIV; CONNECTED_UNIV; OPEN_UNIV]; + ASM SET_TAC[]]) in + MAP_EVERY X_GEN_TAC + [`s:real^N->bool`; `c:real^N->bool`; `a:real^N`; `r:real`] THEN + ASM_CASES_TAC `r < &0` THENL + [ASM_SIMP_TAC[SPHERE_EMPTY; HOMEOMORPHIC_EMPTY; IMP_CONJ; DIFF_EMPTY] THEN + SIMP_TAC[snd(EQ_IMP_RULE(SPEC_ALL COMPONENTS_EQ_SING)); + UNIV_NOT_EMPTY; CONNECTED_UNIV; IN_SING; FRONTIER_UNIV]; + ALL_TAC] THEN + ASM_CASES_TAC `r = &0` THENL + [ASM_SIMP_TAC[HOMEOMORPHIC_FINITE_STRONG; SPHERE_SING; FINITE_SING] THEN + SIMP_TAC[CARD_CLAUSES; FINITE_EMPTY; GSYM HAS_SIZE; NOT_IN_EMPTY] THEN + REWRITE_TAC[HAS_SIZE_CLAUSES; UNWIND_THM2; NOT_IN_EMPTY; IMP_CONJ] THEN + SIMP_TAC[LEFT_IMP_EXISTS_THM; CONNECTED_PUNCTURED_UNIVERSE; IN_SING; + snd(EQ_IMP_RULE(SPEC_ALL COMPONENTS_EQ_SING)); FRONTIER_SING; + SET_RULE `UNIV DIFF s = {} <=> s = UNIV`; FRONTIER_COMPLEMENT; + MESON[BOUNDED_SING; NOT_BOUNDED_UNIV] `~((:real^N) = {a})`]; + ALL_TAC] THEN + SUBGOAL_THEN `&0 < r` ASSUME_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC FRONTIER_MINIMAL_SEPARATING_CLOSED THEN + ASM_REWRITE_TAC[] THEN + FIRST_ASSUM(MP_TAC o MATCH_MP HOMEOMORPHIC_COMPACTNESS) THEN + SIMP_TAC[COMPACT_SPHERE; COMPACT_IMP_CLOSED] THEN DISCH_TAC THEN + CONJ_TAC THENL [ASM_MESON_TAC[JORDAN_BROUWER_SEPARATION]; ALL_TAC] THEN + REPEAT STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [homeomorphic]) THEN + REWRITE_TAC[HOMEOMORPHISM; LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`f:real^N->real^N`; `g:real^N->real^N`] THEN + STRIP_TAC THEN + MP_TAC(ISPECL [`t:real^N->bool`; `IMAGE (f:real^N->real^N) t`] + HOMOTOPY_EQUIVALENT_SEPARATION) THEN + ANTS_TAC THENL + [MATCH_MP_TAC(TAUT `p /\ (p ==> q) ==> p /\ q`) THEN CONJ_TAC THENL + [ASM_MESON_TAC[COMPACT_EQ_BOUNDED_CLOSED; BOUNDED_SUBSET; PSUBSET]; + DISCH_TAC THEN + SUBGOAL_THEN `t homeomorphic (IMAGE (f:real^N->real^N) t)` MP_TAC THENL + [REWRITE_TAC[homeomorphic] THEN MAP_EVERY EXISTS_TAC + [`f:real^N->real^N`; `g:real^N->real^N`] THEN + ASM_REWRITE_TAC[HOMEOMORPHISM] THEN REPEAT CONJ_TAC THEN + TRY(FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP + (REWRITE_RULE[IMP_CONJ] CONTINUOUS_ON_SUBSET))) THEN ASM SET_TAC[]; + ASM_MESON_TAC[HOMEOMORPHIC_COMPACTNESS; + HOMEOMORPHIC_IMP_HOMOTOPY_EQUIVALENT]]]; + DISCH_THEN SUBST1_TAC THEN MATCH_MP_TAC lemma THEN + MAP_EVERY EXISTS_TAC [`a:real^N`; `r:real`] THEN ASM SET_TAC[]]);; + +let JORDAN_BROUWER_NONSEPARATION = prove + (`!s t a:real^N r. + 2 <= dimindex(:N) /\ + s homeomorphic sphere(a,r) /\ t PSUBSET s + ==> connected((:real^N) DIFF t)`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN + `!c. c IN components((:real^N) DIFF s) + ==> connected(c UNION (s DIFF t))` + ASSUME_TAC THENL + [REPEAT STRIP_TAC THEN + MATCH_MP_TAC CONNECTED_INTERMEDIATE_CLOSURE THEN + EXISTS_TAC `c:real^N->bool` THEN + CONJ_TAC THENL [ASM_MESON_TAC[IN_COMPONENTS_CONNECTED]; ALL_TAC] THEN + CONJ_TAC THENL [SET_TAC[]; REWRITE_TAC[UNION_SUBSET; CLOSURE_SUBSET]] THEN + SUBGOAL_THEN `s:real^N->bool = frontier c` SUBST1_TAC THENL + [ASM_MESON_TAC[JORDAN_BROUWER_FRONTIER]; ALL_TAC] THEN + REWRITE_TAC[frontier] THEN SET_TAC[]; + ALL_TAC] THEN + SUBGOAL_THEN + `~(components((:real^N) DIFF s) = {})` + ASSUME_TAC THENL + [REWRITE_TAC[COMPONENTS_EQ_EMPTY; SET_RULE + `UNIV DIFF s = {} <=> s = UNIV`] THEN + ASM_MESON_TAC[NOT_BOUNDED_UNIV; COMPACT_EQ_BOUNDED_CLOSED; + HOMEOMORPHIC_COMPACTNESS; COMPACT_SPHERE]; + ALL_TAC] THEN + SUBGOAL_THEN + `(:real^N) DIFF t = + UNIONS {c UNION (s DIFF t) | c | c IN components((:real^N) DIFF s)}` + SUBST1_TAC THENL + [MP_TAC(ISPEC `(:real^N) DIFF s` UNIONS_COMPONENTS) THEN + REWRITE_TAC[UNIONS_GSPEC] THEN ASM SET_TAC[]; + MATCH_MP_TAC CONNECTED_UNIONS THEN + ASM_REWRITE_TAC[FORALL_IN_GSPEC] THEN + REWRITE_TAC[INTERS_GSPEC] THEN ASM SET_TAC[]]);; + +let JORDAN_BROUWER_ACCESSIBILITY = prove + (`!s c a:real^N r v x. + 2 <= dimindex(:N) /\ + s homeomorphic sphere(a,r) /\ + c IN components((:real^N) DIFF s) /\ x IN c /\ + open_in (subtopology euclidean s) v /\ ~(v = {}) + ==> ?g. arc g /\ + IMAGE g (interval[vec 0,vec 1] DELETE (vec 1)) SUBSET c /\ + pathstart g = x /\ + pathfinish g IN v`, + REPEAT STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o MATCH_MP HOMEOMORPHIC_COMPACTNESS) THEN + REWRITE_TAC[COMPACT_SPHERE] THEN + REWRITE_TAC[closed; COMPACT_EQ_BOUNDED_CLOSED] THEN STRIP_TAC THEN + MATCH_MP_TAC DENSE_ACCESSIBLE_FRONTIER_POINTS_CONNECTED THEN + ASM_REWRITE_TAC[] THEN + ASM_MESON_TAC[JORDAN_BROUWER_FRONTIER; OPEN_COMPONENTS; + IN_COMPONENTS_CONNECTED]);; + +(* ------------------------------------------------------------------------- *) +(* Invariance of domain and corollaries. *) +(* ------------------------------------------------------------------------- *) + +let INVARIANCE_OF_DOMAIN = prove + (`!f:real^N->real^N s. + f continuous_on s /\ open s /\ + (!x y. x IN s /\ y IN s /\ f x = f y ==> x = y) + ==> open(IMAGE f s)`, + let lemma = prove + (`!f:real^N->real^N a r. + f continuous_on cball(a,r) /\ &0 < r /\ + (!x y. x IN cball(a,r) /\ y IN cball(a,r) /\ f x = f y ==> x = y) + ==> open(IMAGE f (ball(a,r)))`, + REPEAT STRIP_TAC THEN ASM_CASES_TAC `dimindex(:N) = 1` THENL + [MP_TAC(ISPECL [`(:real^N)`; `(:real^1)`] ISOMETRIES_SUBSPACES) THEN + ASM_SIMP_TAC[SUBSPACE_UNIV; DIM_UNIV; DIMINDEX_1; + LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`h:real^N->real^1`; `k:real^1->real^N`] THEN + REWRITE_TAC[IN_UNIV] THEN STRIP_TAC THEN + MP_TAC(ISPECL [`(h:real^N->real^1) o f o (k:real^1->real^N)`; + `IMAGE (h:real^N->real^1) (cball(a,r))`] + INJECTIVE_EQ_1D_OPEN_MAP_UNIV) THEN + MATCH_MP_TAC(TAUT + `p /\ q /\ r /\ (s ==> t) + ==> (p /\ q ==> (r <=> s)) ==> t`) THEN + REPEAT CONJ_TAC THENL + [REPEAT(MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN CONJ_TAC) THEN + ASM_SIMP_TAC[LINEAR_CONTINUOUS_ON; GSYM IMAGE_o] THEN + ASM_REWRITE_TAC[o_DEF; IMAGE_ID]; + REWRITE_TAC[IS_INTERVAL_CONNECTED_1] THEN + MATCH_MP_TAC CONNECTED_CONTINUOUS_IMAGE THEN + ASM_SIMP_TAC[LINEAR_CONTINUOUS_ON; CONNECTED_CBALL]; + ASM_SIMP_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; + FORALL_IN_IMAGE; o_DEF] THEN + ASM SET_TAC[]; + DISCH_THEN(MP_TAC o SPEC `IMAGE (h:real^N->real^1) (ball(a,r))`) THEN + ASM_SIMP_TAC[IMAGE_SUBSET; BALL_SUBSET_CBALL; GSYM IMAGE_o] THEN + ANTS_TAC THENL + [MP_TAC(ISPECL [`a:real^N`; `r:real`] OPEN_BALL); ALL_TAC] THEN + MATCH_MP_TAC EQ_IMP THENL + [CONV_TAC SYM_CONV; + REWRITE_TAC[GSYM o_ASSOC] THEN ONCE_REWRITE_TAC[IMAGE_o] THEN + ASM_REWRITE_TAC[o_DEF; ETA_AX]] THEN + MATCH_MP_TAC OPEN_BIJECTIVE_LINEAR_IMAGE_EQ THEN + ASM_MESON_TAC[]]; + FIRST_ASSUM(MP_TAC o MATCH_MP (ARITH_RULE + `~(n = 1) ==> 1 <= n ==> 2 <= n`)) THEN + REWRITE_TAC[DIMINDEX_GE_1] THEN DISCH_TAC] THEN + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`IMAGE (f:real^N->real^N) (sphere(a,r))`; + `a:real^N`; `r:real`] + JORDAN_BROUWER_SEPARATION) THEN + ASM_REWRITE_TAC[] THEN ANTS_TAC THENL + [ONCE_REWRITE_TAC[HOMEOMORPHIC_SYM] THEN + MATCH_MP_TAC HOMEOMORPHIC_COMPACT THEN EXISTS_TAC `f:real^N->real^N` THEN + ASM_MESON_TAC[CONTINUOUS_ON_SUBSET; SUBSET; SPHERE_SUBSET_CBALL; + COMPACT_SPHERE]; + DISCH_TAC] THEN + MP_TAC(ISPEC `(:real^N) DIFF IMAGE f (sphere(a:real^N,r))` + COBOUNDED_HAS_BOUNDED_COMPONENT) THEN + ASM_REWRITE_TAC[SET_RULE `UNIV DIFF (UNIV DIFF s) = s`] THEN + ANTS_TAC THENL + [ASM_MESON_TAC[CONTINUOUS_ON_SUBSET; SUBSET; SPHERE_SUBSET_CBALL; + COMPACT_SPHERE; COMPACT_CONTINUOUS_IMAGE; COMPACT_IMP_BOUNDED]; + DISCH_THEN(X_CHOOSE_THEN `c:real^N->bool` STRIP_ASSUME_TAC)] THEN + SUBGOAL_THEN + `IMAGE (f:real^N->real^N) (ball(a,r)) = c` + SUBST1_TAC THENL + [ALL_TAC; + FIRST_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ_ALT] + OPEN_COMPONENTS)) THEN + REWRITE_TAC[GSYM closed] THEN + ASM_MESON_TAC[CONTINUOUS_ON_SUBSET; SUBSET; SPHERE_SUBSET_CBALL; + COMPACT_SPHERE; COMPACT_CONTINUOUS_IMAGE; COMPACT_IMP_CLOSED]] THEN + MATCH_MP_TAC(SET_RULE + `~(c = {}) /\ (~(c INTER t = {}) ==> t SUBSET c) /\ c SUBSET t + ==> t = c`) THEN + REPEAT STRIP_TAC THENL + [ASM_MESON_TAC[IN_COMPONENTS_NONEMPTY]; + FIRST_ASSUM(MATCH_MP_TAC o MATCH_MP (ONCE_REWRITE_RULE[IMP_CONJ] + COMPONENTS_MAXIMAL)) THEN + ASM_REWRITE_TAC[] THEN CONJ_TAC THENL + [MATCH_MP_TAC CONNECTED_CONTINUOUS_IMAGE THEN + REWRITE_TAC[CONNECTED_BALL] THEN + ASM_MESON_TAC[CONTINUOUS_ON_SUBSET; BALL_SUBSET_CBALL]; + REWRITE_TAC[GSYM CBALL_DIFF_SPHERE] THEN + MP_TAC(ISPECL [`a:real^N`; `r:real`] SPHERE_SUBSET_CBALL) THEN + ASM SET_TAC[]]; + FIRST_ASSUM(MP_TAC o MATCH_MP IN_COMPONENTS_SUBSET) THEN + FIRST_ASSUM(MP_TAC o SPEC `(:real^N) DIFF IMAGE f (cball(a:real^N,r))` o + MATCH_MP (ONCE_REWRITE_RULE[IMP_CONJ] COMPONENTS_MAXIMAL)) THEN + SIMP_TAC[SET_RULE `UNIV DIFF t SUBSET UNIV DIFF s <=> s SUBSET t`; + IMAGE_SUBSET; SPHERE_SUBSET_CBALL] THEN + MATCH_MP_TAC(TAUT `p /\ ~r /\ (~q ==> s) ==> (p /\ q ==> r) ==> s`) THEN + REWRITE_TAC[] THEN REPEAT CONJ_TAC THENL + [MATCH_MP_TAC(INST_TYPE [`:N`,`:M`] + CONNECTED_COMPLEMENT_HOMEOMORPHIC_CONVEX_COMPACT) THEN + EXISTS_TAC `cball(a:real^N,r)` THEN + ASM_REWRITE_TAC[CONVEX_CBALL; COMPACT_CBALL] THEN + ONCE_REWRITE_TAC[HOMEOMORPHIC_SYM] THEN + MATCH_MP_TAC HOMEOMORPHIC_COMPACT THEN + EXISTS_TAC `f:real^N->real^N` THEN ASM_REWRITE_TAC[COMPACT_CBALL]; + DISCH_THEN(MP_TAC o + MATCH_MP(REWRITE_RULE[IMP_CONJ_ALT] BOUNDED_SUBSET)) THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC COBOUNDED_IMP_UNBOUNDED THEN + REWRITE_TAC[SET_RULE `UNIV DIFF (UNIV DIFF s) = s`] THEN + ASM_MESON_TAC[COMPACT_IMP_BOUNDED; COMPACT_CONTINUOUS_IMAGE; + COMPACT_CBALL]; + REWRITE_TAC[GSYM CBALL_DIFF_SPHERE] THEN ASM SET_TAC[]]]) in + REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[OPEN_SUBOPEN] THEN + REWRITE_TAC[FORALL_IN_IMAGE] THEN X_GEN_TAC `a:real^N` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [OPEN_CONTAINS_CBALL]) THEN + DISCH_THEN(MP_TAC o SPEC `a:real^N`) THEN + ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `r:real` THEN STRIP_TAC THEN + EXISTS_TAC `IMAGE (f:real^N->real^N) (ball(a,r))` THEN + REPEAT CONJ_TAC THENL + [MATCH_MP_TAC lemma THEN ASM_MESON_TAC[SUBSET; CONTINUOUS_ON_SUBSET]; + ASM_SIMP_TAC[FUN_IN_IMAGE; CENTRE_IN_BALL]; + MATCH_MP_TAC IMAGE_SUBSET THEN + ASM_MESON_TAC[BALL_SUBSET_CBALL; SUBSET_TRANS]]);; + +let INVARIANCE_OF_DOMAIN_SUBSPACES = prove + (`!f:real^M->real^N u v s. + subspace u /\ subspace v /\ dim v <= dim u /\ + f continuous_on s /\ IMAGE f s SUBSET v /\ + (!x y. x IN s /\ y IN s /\ f x = f y ==> x = y) /\ + open_in (subtopology euclidean u) s + ==> open_in (subtopology euclidean v) (IMAGE f s)`, + let lemma0 = prove + (`!f:real^M->real^M s u. + subspace s /\ dim s = dimindex(:N) /\ + f continuous_on u /\ IMAGE f u SUBSET s /\ + (!x y. x IN u /\ y IN u /\ f x = f y ==> x = y) /\ + open_in (subtopology euclidean s) u + ==> open_in (subtopology euclidean s) (IMAGE f u)`, + REPEAT STRIP_TAC THEN MP_TAC(ISPECL [`(:real^N)`; `s:real^M->bool`] + HOMEOMORPHIC_SUBSPACES) THEN + ASM_REWRITE_TAC[DIM_UNIV; SUBSPACE_UNIV] THEN + REWRITE_TAC[homeomorphic; homeomorphism; LEFT_IMP_EXISTS_THM; IN_UNIV] THEN + MAP_EVERY X_GEN_TAC [`h:real^N->real^M`; `k:real^M->real^N`] THEN + STRIP_TAC THEN MP_TAC(ISPECL + [`(k:real^M->real^N) o f o (h:real^N->real^M)`; + `IMAGE (k:real^M->real^N) u`] INVARIANCE_OF_DOMAIN) THEN + REWRITE_TAC[GSYM IMAGE_o; o_THM] THEN + SUBGOAL_THEN + `!t. open t <=> + open_in (subtopology euclidean (IMAGE (k:real^M->real^N) s)) t` + (fun th -> REWRITE_TAC[th]) + THENL [ASM_REWRITE_TAC[SUBTOPOLOGY_UNIV; GSYM OPEN_IN]; ALL_TAC] THEN + ANTS_TAC THENL + [REPEAT CONJ_TAC THENL + [REPEAT(MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN CONJ_TAC) THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET)) THEN + FIRST_ASSUM(MP_TAC o MATCH_MP OPEN_IN_IMP_SUBSET) THEN + REWRITE_TAC[IMAGE_o] THEN ASM SET_TAC[]; + MATCH_MP_TAC HOMEOMORPHISM_IMP_OPEN_MAP THEN + MAP_EVERY EXISTS_TAC [`h:real^N->real^M`; `s:real^M->bool`] THEN + ASM_REWRITE_TAC[homeomorphism]; + REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_IMAGE] THEN + FIRST_ASSUM(MP_TAC o MATCH_MP OPEN_IN_IMP_SUBSET) THEN + ASM_SIMP_TAC[SUBSET] THEN REPEAT STRIP_TAC THEN AP_TERM_TAC THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN ASM SET_TAC[]]; + ASM_REWRITE_TAC[] THEN DISCH_TAC THEN + SUBGOAL_THEN + `IMAGE f u = + IMAGE (h:real^N->real^M) (IMAGE ((k o f o h) o (k:real^M->real^N)) u)` + SUBST1_TAC THENL + [REWRITE_TAC[GSYM IMAGE_o] THEN MATCH_MP_TAC(SET_RULE + `(!x. x IN s ==> f x = g x) ==> IMAGE f s = IMAGE g s`) THEN + REPEAT(FIRST_X_ASSUM(MP_TAC o MATCH_MP OPEN_IN_IMP_SUBSET)) THEN + ASM_SIMP_TAC[SUBSET; o_THM] THEN ASM SET_TAC[]; + MATCH_MP_TAC HOMEOMORPHISM_IMP_OPEN_MAP THEN + MAP_EVERY EXISTS_TAC [`k:real^M->real^N`; `(:real^N)`] THEN + ASM_REWRITE_TAC[homeomorphism]]]) in + let lemma1 = prove + (`!f:real^N->real^N s u. + subspace s /\ f continuous_on u /\ IMAGE f u SUBSET s /\ + (!x y. x IN u /\ y IN u /\ f x = f y ==> x = y) /\ + open_in (subtopology euclidean s) u + ==> open_in (subtopology euclidean s) (IMAGE f u)`, + REWRITE_TAC[INJECTIVE_ON_ALT] THEN REPEAT STRIP_TAC THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP OPEN_IN_IMP_SUBSET) THEN + ABBREV_TAC `s' = {y:real^N | !x. x IN s ==> orthogonal x y}` THEN + SUBGOAL_THEN `subspace(s':real^N->bool)` ASSUME_TAC THENL + [EXPAND_TAC "s'" THEN REWRITE_TAC[SUBSPACE_ORTHOGONAL_TO_VECTORS]; + FIRST_ASSUM(ASSUME_TAC o MATCH_MP SUBSPACE_IMP_NONEMPTY)] THEN + ABBREV_TAC `g:real^(N,N)finite_sum->real^(N,N)finite_sum = + \z. pastecart (f(fstcart z)) (sndcart z)` THEN + SUBGOAL_THEN + `g continuous_on ((u:real^N->bool) PCROSS s') /\ + IMAGE g (u PCROSS s') SUBSET (s:real^N->bool) PCROSS (s':real^N->bool) /\ + (!w z. w IN u PCROSS s' /\ z IN u PCROSS s' ==> (g w = g z <=> w = z))` + STRIP_ASSUME_TAC THENL + [EXPAND_TAC "g" THEN REPEAT CONJ_TAC THENL + [MATCH_MP_TAC CONTINUOUS_ON_PASTECART THEN + SIMP_TAC[LINEAR_CONTINUOUS_ON; LINEAR_SNDCART] THEN + GEN_REWRITE_TAC LAND_CONV [GSYM o_DEF] THEN + MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN + SIMP_TAC[LINEAR_CONTINUOUS_ON; LINEAR_FSTCART; + IMAGE_FSTCART_PCROSS] THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[CONTINUOUS_ON_EMPTY]; + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; FORALL_IN_PCROSS] THEN + SIMP_TAC[PASTECART_IN_PCROSS; SNDCART_PASTECART; + FSTCART_PASTECART] THEN + ASM SET_TAC[]; + EXPAND_TAC "g" THEN REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN + REWRITE_TAC[FORALL_IN_PCROSS; FSTCART_PASTECART; + SNDCART_PASTECART] THEN + ASM_SIMP_TAC[PASTECART_INJ]]; + ALL_TAC] THEN + SUBGOAL_THEN + `open_in (subtopology euclidean (s PCROSS s')) + (IMAGE (g:real^(N,N)finite_sum->real^(N,N)finite_sum) + (u PCROSS s'))` + MP_TAC THENL + [MATCH_MP_TAC lemma0 THEN + ASM_SIMP_TAC[SUBSPACE_PCROSS; OPEN_IN_PCROSS_EQ; OPEN_IN_REFL] THEN + CONJ_TAC THENL [ASM_SIMP_TAC[DIM_PCROSS]; ASM_MESON_TAC[]] THEN + MP_TAC(ISPECL [`s:real^N->bool`; `(:real^N)`] + DIM_SUBSPACE_ORTHOGONAL_TO_VECTORS) THEN + ASM_REWRITE_TAC[SUBSET_UNIV; SUBSPACE_UNIV; IN_UNIV; DIM_UNIV] THEN + ARITH_TAC; + SUBGOAL_THEN + `IMAGE (g:real^(N,N)finite_sum->real^(N,N)finite_sum) (u PCROSS s') = + IMAGE f u PCROSS s'` + SUBST1_TAC THENL + [EXPAND_TAC "g" THEN + REWRITE_TAC[EXTENSION; EXISTS_PASTECART; PASTECART_IN_PCROSS; + IN_IMAGE; FORALL_PASTECART; PASTECART_IN_PCROSS; + FSTCART_PASTECART; SNDCART_PASTECART; PASTECART_INJ] THEN + ASM SET_TAC[]; + ASM_SIMP_TAC[OPEN_IN_PCROSS_EQ; IMAGE_EQ_EMPTY] THEN + STRIP_TAC THEN ASM_SIMP_TAC[IMAGE_CLAUSES; OPEN_IN_EMPTY]]]) in + REWRITE_TAC[INJECTIVE_ON_ALT] THEN REPEAT STRIP_TAC THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP OPEN_IN_IMP_SUBSET) THEN + MP_TAC(ISPECL [`u:real^M->bool`; `dim(v:real^N->bool)`] + CHOOSE_SUBSPACE_OF_SUBSPACE) THEN ASM_SIMP_TAC[SPAN_OF_SUBSPACE] THEN + DISCH_THEN(X_CHOOSE_THEN `v:real^M->bool` STRIP_ASSUME_TAC) THEN + MP_TAC(ISPECL [`v:real^N->bool`; `v:real^M->bool`] + HOMEOMORPHIC_SUBSPACES) THEN + ASM_REWRITE_TAC[homeomorphic; homeomorphism; LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`h:real^N->real^M`; `k:real^M->real^N`] THEN + STRIP_TAC THEN + SUBGOAL_THEN + `IMAGE (f:real^M->real^N) s = + IMAGE (k:real^M->real^N) (IMAGE ((h:real^N->real^M) o f) s)` + SUBST1_TAC THENL + [REWRITE_TAC[GSYM IMAGE_o] THEN MATCH_MP_TAC(SET_RULE + `(!x. x IN u ==> f x = g x) ==> IMAGE f u = IMAGE g u`) THEN + RULE_ASSUM_TAC(REWRITE_RULE[SUBSET]) THEN + ASM_SIMP_TAC[SUBSET; o_THM] THEN ASM SET_TAC[]; + MATCH_MP_TAC HOMEOMORPHISM_IMP_OPEN_MAP THEN + MAP_EVERY EXISTS_TAC [`h:real^N->real^M`; `v:real^M->bool`] THEN + ASM_REWRITE_TAC[homeomorphism] THEN + MATCH_MP_TAC OPEN_IN_SUBSET_TRANS THEN EXISTS_TAC `u:real^M->bool` THEN + ASM_REWRITE_TAC[IMAGE_o] THEN CONJ_TAC THENL [ALL_TAC; ASM SET_TAC[]] THEN + REWRITE_TAC[GSYM IMAGE_o] THEN MATCH_MP_TAC lemma1 THEN + ASM_REWRITE_TAC[IMAGE_o; o_THM] THEN + CONJ_TAC THENL [ALL_TAC; ASM SET_TAC[]] THEN + MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN ASM_REWRITE_TAC[] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET)) THEN + ASM SET_TAC[]]);; + +let INVARIANCE_OF_DIMENSION_SUBSPACES = prove + (`!f:real^M->real^N u v s. + subspace u /\ subspace v /\ + ~(s = {}) /\ open_in (subtopology euclidean u) s /\ + f continuous_on s /\ IMAGE f s SUBSET v /\ + (!x y. x IN s /\ y IN s /\ f x = f y ==> x = y) + ==> dim u <= dim v`, + REWRITE_TAC[GSYM NOT_LT] THEN REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`u:real^M->bool`; `dim(v:real^N->bool)`] + CHOOSE_SUBSPACE_OF_SUBSPACE) THEN + ASM_SIMP_TAC[SPAN_OF_SUBSPACE; LE_LT] THEN + DISCH_THEN(X_CHOOSE_THEN `t:real^M->bool` STRIP_ASSUME_TAC) THEN + MP_TAC(ISPECL [`v:real^N->bool`; `t:real^M->bool`] + HOMEOMORPHIC_SUBSPACES) THEN + FIRST_X_ASSUM(SUBST_ALL_TAC o SYM) THEN + ASM_REWRITE_TAC[homeomorphic; homeomorphism; NOT_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`h:real^N->real^M`; `k:real^M->real^N`] THEN + STRIP_TAC THEN MP_TAC(ISPECL + [`(h:real^N->real^M) o (f:real^M->real^N)`; `u:real^M->bool`; + `u:real^M->bool`; `s:real^M->bool`] + INVARIANCE_OF_DOMAIN_SUBSPACES) THEN + ASM_REWRITE_TAC[LE_LT; NOT_IMP] THEN REPEAT CONJ_TAC THENL + [MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN ASM_REWRITE_TAC[] THEN + ASM_MESON_TAC[CONTINUOUS_ON_SUBSET]; + REWRITE_TAC[IMAGE_o] THEN ASM SET_TAC[]; + REWRITE_TAC[o_THM] THEN ASM SET_TAC[]; + ALL_TAC] THEN + SUBGOAL_THEN `IMAGE ((h:real^N->real^M) o (f:real^M->real^N)) s SUBSET t` + ASSUME_TAC THENL [REWRITE_TAC[IMAGE_o] THEN ASM SET_TAC[]; ALL_TAC] THEN + ABBREV_TAC `w = IMAGE ((h:real^N->real^M) o (f:real^M->real^N)) s` THEN + DISCH_TAC THEN UNDISCH_TAC `dim(t:real^M->bool) < dim(u:real^M->bool)` THEN + REWRITE_TAC[NOT_LT] THEN MP_TAC(ISPECL + [`w:real^M->bool`; `u:real^M->bool`] DIM_OPEN_IN) THEN + ASM_REWRITE_TAC[] THEN ANTS_TAC THENL + [ASM_MESON_TAC[IMAGE_EQ_EMPTY]; DISCH_THEN(SUBST1_TAC o SYM)] THEN + ASM_SIMP_TAC[DIM_SUBSET]);; + +let INVARIANCE_OF_DOMAIN_AFFINE_SETS = prove + (`!f:real^M->real^N u v s. + affine u /\ affine v /\ aff_dim v <= aff_dim u /\ + f continuous_on s /\ IMAGE f s SUBSET v /\ + (!x y. x IN s /\ y IN s /\ f x = f y ==> x = y) /\ + open_in (subtopology euclidean u) s + ==> open_in (subtopology euclidean v) (IMAGE f s)`, + REPEAT GEN_TAC THEN ASM_CASES_TAC `s:real^M->bool = {}` THEN + ASM_REWRITE_TAC[IMAGE_CLAUSES; OPEN_IN_EMPTY; INJECTIVE_ON_ALT] THEN + REPEAT STRIP_TAC THEN + SUBGOAL_THEN `?a:real^M b:real^N. a IN s /\ a IN u /\ b IN v` + STRIP_ASSUME_TAC THENL + [FIRST_ASSUM(MP_TAC o MATCH_MP OPEN_IN_IMP_SUBSET) THEN + ASM SET_TAC[]; + ALL_TAC] THEN + MP_TAC(ISPECL + [`(\x. --b + x) o (f:real^M->real^N) o (\x. a + x)`; + `IMAGE (\x:real^M. --a + x) u`; `IMAGE (\x:real^N. --b + x) v`; + `IMAGE (\x:real^M. --a + x) s`] INVARIANCE_OF_DOMAIN_SUBSPACES) THEN + REWRITE_TAC[IMAGE_o; INJECTIVE_ON_ALT; OPEN_IN_TRANSLATION_EQ] THEN + SIMP_TAC[IMP_CONJ; GSYM INT_OF_NUM_LE; GSYM AFF_DIM_DIM_SUBSPACE] THEN + ASM_REWRITE_TAC[AFF_DIM_TRANSLATION_EQ; RIGHT_FORALL_IMP_THM] THEN + SIMP_TAC[FORALL_IN_IMAGE; o_THM; GSYM IMAGE_o; IMP_IMP; GSYM CONJ_ASSOC] THEN + ANTS_TAC THENL + [ONCE_REWRITE_TAC[CONJ_ASSOC] THEN CONJ_TAC THENL + [CONJ_TAC THEN MATCH_MP_TAC AFFINE_IMP_SUBSPACE THEN + ASM_REWRITE_TAC[AFFINE_TRANSLATION_EQ] THEN REWRITE_TAC[IN_IMAGE; + VECTOR_ARITH `vec 0:real^N = --a + x <=> x = a`] THEN + ASM_MESON_TAC[]; + REPEAT CONJ_TAC THENL + [REPEAT(MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN + SIMP_TAC[CONTINUOUS_ON_ADD; CONTINUOUS_ON_CONST; CONTINUOUS_ON_ID]); + REWRITE_TAC[GSYM o_ASSOC] THEN REWRITE_TAC[IMAGE_o] THEN + MATCH_MP_TAC IMAGE_SUBSET; + REWRITE_TAC[VECTOR_ARITH `a + x:real^N = a + y <=> x = y`]]]; + ALL_TAC] THEN + ASM_SIMP_TAC[VECTOR_ARITH `a + --a + x:real^N = x`; GSYM IMAGE_o; o_DEF; + IMAGE_ID; ETA_AX]);; + +let INVARIANCE_OF_DIMENSION_AFFINE_SETS = prove + (`!f:real^M->real^N u v s. + affine u /\ affine v /\ + ~(s = {}) /\ open_in (subtopology euclidean u) s /\ + f continuous_on s /\ IMAGE f s SUBSET v /\ + (!x y. x IN s /\ y IN s /\ f x = f y ==> x = y) + ==> aff_dim u <= aff_dim v`, + REPEAT GEN_TAC THEN ASM_CASES_TAC `s:real^M->bool = {}` THEN + ASM_REWRITE_TAC[IMAGE_CLAUSES; OPEN_IN_EMPTY; INJECTIVE_ON_ALT] THEN + REPEAT STRIP_TAC THEN + SUBGOAL_THEN `?a:real^M b:real^N. a IN s /\ a IN u /\ b IN v` + STRIP_ASSUME_TAC THENL + [FIRST_ASSUM(MP_TAC o MATCH_MP OPEN_IN_IMP_SUBSET) THEN + ASM SET_TAC[]; + ALL_TAC] THEN + MP_TAC(ISPECL + [`(\x. --b + x) o (f:real^M->real^N) o (\x. a + x)`; + `IMAGE (\x:real^M. --a + x) u`; `IMAGE (\x:real^N. --b + x) v`; + `IMAGE (\x:real^M. --a + x) s`] INVARIANCE_OF_DIMENSION_SUBSPACES) THEN + REWRITE_TAC[IMAGE_o; INJECTIVE_ON_ALT; OPEN_IN_TRANSLATION_EQ] THEN + SIMP_TAC[IMP_CONJ; GSYM INT_OF_NUM_LE; GSYM AFF_DIM_DIM_SUBSPACE] THEN + ASM_REWRITE_TAC[AFF_DIM_TRANSLATION_EQ; RIGHT_FORALL_IMP_THM] THEN + SIMP_TAC[FORALL_IN_IMAGE; o_THM; GSYM IMAGE_o; IMP_IMP; GSYM CONJ_ASSOC] THEN + DISCH_THEN MATCH_MP_TAC THEN ONCE_REWRITE_TAC[CONJ_ASSOC] THEN CONJ_TAC THENL + [CONJ_TAC THEN MATCH_MP_TAC AFFINE_IMP_SUBSPACE THEN + ASM_REWRITE_TAC[AFFINE_TRANSLATION_EQ] THEN REWRITE_TAC[IN_IMAGE; + VECTOR_ARITH `vec 0:real^N = --a + x <=> x = a`] THEN + ASM_MESON_TAC[]; + ASM_REWRITE_TAC[IMAGE_EQ_EMPTY] THEN REPEAT CONJ_TAC THENL + [REPEAT(MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN + SIMP_TAC[CONTINUOUS_ON_ADD; CONTINUOUS_ON_CONST; CONTINUOUS_ON_ID]); + REWRITE_TAC[GSYM o_ASSOC] THEN REWRITE_TAC[IMAGE_o] THEN + MATCH_MP_TAC IMAGE_SUBSET; + REWRITE_TAC[VECTOR_ARITH `a + x:real^N = a + y <=> x = y`]]] THEN + ASM_SIMP_TAC[VECTOR_ARITH `a + --a + x:real^N = x`; GSYM IMAGE_o; o_DEF; + IMAGE_ID; ETA_AX]);; + +let INVARIANCE_OF_DIMENSION = prove + (`!f:real^M->real^N s. + f continuous_on s /\ open s /\ ~(s = {}) /\ + (!x y. x IN s /\ y IN s /\ f x = f y ==> x = y) + ==> dimindex(:M) <= dimindex(:N)`, + REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM DIM_UNIV] THEN + MATCH_MP_TAC INVARIANCE_OF_DIMENSION_SUBSPACES THEN + MAP_EVERY EXISTS_TAC [`f:real^M->real^N`; `s:real^M->bool`] THEN + ASM_REWRITE_TAC[SUBSPACE_UNIV; SUBSET_UNIV; SUBTOPOLOGY_UNIV; + GSYM OPEN_IN]);; + +let CONTINUOUS_INJECTIVE_IMAGE_SUBSPACE_DIM_LE = prove + (`!f:real^M->real^N s t. + subspace s /\ subspace t /\ + f continuous_on s /\ IMAGE f s SUBSET t /\ + (!x y. x IN s /\ y IN s /\ f x = f y ==> x = y) + ==> dim(s) <= dim(t)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC INVARIANCE_OF_DIMENSION_SUBSPACES THEN + MAP_EVERY EXISTS_TAC [`f:real^M->real^N`; `s:real^M->bool`] THEN + ASM_REWRITE_TAC[OPEN_IN_REFL] THEN ASM_SIMP_TAC[SUBSPACE_IMP_NONEMPTY]);; + +let INVARIANCE_OF_DIMENSION_CONVEX_DOMAIN = prove + (`!f:real^M->real^N s t. + + convex s /\ f continuous_on s /\ IMAGE f s SUBSET affine hull t /\ + (!x y. x IN s /\ y IN s /\ f x = f y ==> x = y) + ==> aff_dim(s) <= aff_dim(t)`, + REPEAT STRIP_TAC THEN ASM_CASES_TAC `s:real^M->bool = {}` THEN + ASM_REWRITE_TAC[AFF_DIM_EMPTY; AFF_DIM_GE] THEN + MP_TAC(ISPECL + [`f:real^M->real^N`; `affine hull s:real^M->bool`; + `affine hull t:real^N->bool`; `relative_interior s:real^M->bool`] + INVARIANCE_OF_DIMENSION_AFFINE_SETS) THEN + ASM_REWRITE_TAC[AFFINE_AFFINE_HULL; AFF_DIM_AFFINE_HULL; + OPEN_IN_RELATIVE_INTERIOR] THEN + DISCH_THEN MATCH_MP_TAC THEN + CONJ_TAC THENL [ASM_MESON_TAC[RELATIVE_INTERIOR_EQ_EMPTY]; ALL_TAC] THEN + ASSUME_TAC(ISPEC `s:real^M->bool` RELATIVE_INTERIOR_SUBSET) THEN + CONJ_TAC THENL [ASM_MESON_TAC[CONTINUOUS_ON_SUBSET]; ASM SET_TAC[]]);; + +let HOMEOMORPHIC_CONVEX_SETS = prove + (`!s:real^M->bool t:real^N->bool. + convex s /\ convex t /\ s homeomorphic t ==> aff_dim s = aff_dim t`, + REPEAT STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [homeomorphic]) THEN + REWRITE_TAC[LEFT_IMP_EXISTS_THM; GSYM INT_LE_ANTISYM; homeomorphism] THEN + MAP_EVERY X_GEN_TAC [`f:real^M->real^N`; `g:real^N->real^M`] THEN + REPEAT STRIP_TAC THEN + MATCH_MP_TAC INVARIANCE_OF_DIMENSION_CONVEX_DOMAIN THENL + [EXISTS_TAC `f:real^M->real^N`; EXISTS_TAC `g:real^N->real^M`] THEN + ASM_REWRITE_TAC[HULL_SUBSET] THEN ASM SET_TAC[]);; + +let HOMEOMORPHIC_CONVEX_COMPACT_SETS_EQ = prove + (`!s:real^M->bool t:real^N->bool. + convex s /\ compact s /\ convex t /\ compact t + ==> (s homeomorphic t <=> aff_dim s = aff_dim t)`, + MESON_TAC[HOMEOMORPHIC_CONVEX_SETS; HOMEOMORPHIC_CONVEX_COMPACT_SETS]);; + +let INVARIANCE_OF_DOMAIN_GEN = prove + (`!f:real^M->real^N s. + dimindex(:N) <= dimindex(:M) /\ f continuous_on s /\ open s /\ + (!x y. x IN s /\ y IN s /\ f x = f y ==> x = y) + ==> open(IMAGE f s)`, + REPEAT STRIP_TAC THEN MP_TAC(ISPECL + [`f:real^M->real^N`; `(:real^M)`; `(:real^N)`; `s:real^M->bool`] + INVARIANCE_OF_DOMAIN_SUBSPACES) THEN + ASM_REWRITE_TAC[SUBTOPOLOGY_UNIV; GSYM OPEN_IN; SUBSPACE_UNIV; + DIM_UNIV; SUBSET_UNIV]);; + +let INJECTIVE_INTO_1D_IMP_OPEN_MAP_UNIV = prove + (`!f:real^N->real^1 s t. + f continuous_on s /\ + (!x y. x IN s /\ y IN s /\ f x = f y ==> x = y) /\ + open t /\ t SUBSET s + ==> open (IMAGE f t)`, + REPEAT STRIP_TAC THEN + MATCH_MP_TAC INVARIANCE_OF_DOMAIN_GEN THEN + ASM_REWRITE_TAC[DIMINDEX_1; DIMINDEX_GE_1] THEN CONJ_TAC THENL + [ASM_MESON_TAC[CONTINUOUS_ON_SUBSET]; ASM SET_TAC[]]);; + +let CONTINUOUS_ON_INVERSE_OPEN = prove + (`!f:real^M->real^N g s. + dimindex(:N) <= dimindex(:M) /\ + f continuous_on s /\ open s /\ + (!x. x IN s ==> g(f x) = x) + ==> g continuous_on IMAGE f s`, + REPEAT STRIP_TAC THEN + REWRITE_TAC[CONTINUOUS_OPEN_IN_PREIMAGE_EQ] THEN + X_GEN_TAC `t:real^M->bool` THEN DISCH_TAC THEN + SUBGOAL_THEN + `{x | x IN IMAGE f s /\ g x IN t} = IMAGE (f:real^M->real^N) (s INTER t)` + SUBST1_TAC THENL [ASM SET_TAC[]; MATCH_MP_TAC OPEN_OPEN_IN_TRANS] THEN + REWRITE_TAC[CONJ_ASSOC] THEN CONJ_TAC THENL [ALL_TAC; SET_TAC[]] THEN + CONJ_TAC THEN MATCH_MP_TAC INVARIANCE_OF_DOMAIN_GEN THEN + ASM_SIMP_TAC[OPEN_INTER; IN_INTER] THEN + ASM_MESON_TAC[CONTINUOUS_ON_SUBSET; INTER_SUBSET]);; + +let CONTINUOUS_ON_INVERSE_INTO_1D = prove + (`!f:real^N->real^1 g s t. + f continuous_on s /\ + (path_connected s \/ compact s \/ open s) /\ + IMAGE f s = t /\ (!x. x IN s ==> g(f x) = x) + ==> g continuous_on t`, + REPEAT STRIP_TAC THENL + [REPEAT STRIP_TAC THEN MATCH_MP_TAC CONTINUOUS_ON_INVERSE_OPEN_MAP THEN + MAP_EVERY EXISTS_TAC [`f:real^N->real^1`; `s:real^N->bool`] THEN + ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN + FIRST_ASSUM(SUBST1_TAC o SYM) THEN + MATCH_MP_TAC INJECTIVE_INTO_1D_IMP_OPEN_MAP THEN ASM SET_TAC[]; + ASM_MESON_TAC[CONTINUOUS_ON_INVERSE]; + FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN + MATCH_MP_TAC CONTINUOUS_ON_INVERSE_OPEN THEN + ASM_REWRITE_TAC[DIMINDEX_1; DIMINDEX_GE_1]]);; + +let REAL_CONTINUOUS_ON_INVERSE = prove + (`!f g s. f real_continuous_on s /\ + (is_realinterval s \/ real_compact s \/ real_open s) /\ + (!x. x IN s ==> g(f x) = x) + ==> g real_continuous_on (IMAGE f s)`, + REPEAT GEN_TAC THEN + REWRITE_TAC[REAL_CONTINUOUS_ON; real_compact; REAL_OPEN; + IS_REALINTERVAL_IS_INTERVAL] THEN + DISCH_TAC THEN MATCH_MP_TAC CONTINUOUS_ON_INVERSE_INTO_1D THEN + MAP_EVERY EXISTS_TAC [`lift o f o drop`; `IMAGE lift s`] THEN + ASM_REWRITE_TAC[GSYM IS_INTERVAL_PATH_CONNECTED_1] THEN + ASM_SIMP_TAC[FORALL_IN_IMAGE; o_DEF; LIFT_DROP; GSYM IMAGE_o]);; + +let REAL_CONTINUOUS_ON_INVERSE_ALT = prove + (`!f g s t. f real_continuous_on s /\ + (is_realinterval s \/ real_compact s \/ real_open s) /\ + IMAGE f s = t /\ (!x. x IN s ==> g(f x) = x) + ==> g real_continuous_on t`, + MESON_TAC[REAL_CONTINUOUS_ON_INVERSE]);; + +let INVARIANCE_OF_DOMAIN_HOMEOMORPHISM = prove + (`!f:real^M->real^N s. + dimindex(:N) <= dimindex(:M) /\ f continuous_on s /\ open s /\ + (!x y. x IN s /\ y IN s /\ f x = f y ==> x = y) + ==> ?g. homeomorphism (s,IMAGE f s) (f,g)`, + REPEAT STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [INJECTIVE_ON_LEFT_INVERSE]) THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `g:real^N->real^M` THEN + DISCH_TAC THEN ASM_REWRITE_TAC[homeomorphism] THEN + ASM_SIMP_TAC[CONTINUOUS_ON_INVERSE_OPEN] THEN ASM SET_TAC[]);; + +let INVARIANCE_OF_DOMAIN_HOMEOMORPHIC = prove + (`!f:real^M->real^N s. + dimindex(:N) <= dimindex(:M) /\ f continuous_on s /\ open s /\ + (!x y. x IN s /\ y IN s /\ f x = f y ==> x = y) + ==> s homeomorphic (IMAGE f s)`, + REPEAT GEN_TAC THEN + DISCH_THEN(MP_TAC o MATCH_MP INVARIANCE_OF_DOMAIN_HOMEOMORPHISM) THEN + REWRITE_TAC[homeomorphic] THEN MESON_TAC[]);; + +let HOMEOMORPHIC_INTERVALS_EQ = prove + (`(!a b:real^M c d:real^N. + interval[a,b] homeomorphic interval[c,d] <=> + aff_dim(interval[a,b]) = aff_dim(interval[c,d])) /\ + (!a b:real^M c d:real^N. + interval[a,b] homeomorphic interval(c,d) <=> + interval[a,b] = {} /\ interval(c,d) = {}) /\ + (!a b:real^M c d:real^N. + interval(a,b) homeomorphic interval[c,d] <=> + interval(a,b) = {} /\ interval[c,d] = {}) /\ + (!a b:real^M c d:real^N. + interval(a,b) homeomorphic interval(c,d) <=> + interval(a,b) = {} /\ interval(c,d) = {} \/ + ~(interval(a,b) = {}) /\ ~(interval(c,d) = {}) /\ + dimindex(:M) = dimindex(:N))`, + SIMP_TAC[HOMEOMORPHIC_CONVEX_COMPACT_SETS_EQ; CONVEX_INTERVAL; + COMPACT_INTERVAL] THEN + REPEAT STRIP_TAC THEN EQ_TAC THEN STRIP_TAC THEN + ASM_REWRITE_TAC[HOMEOMORPHIC_EMPTY] THENL + [FIRST_ASSUM(MP_TAC o MATCH_MP HOMEOMORPHIC_COMPACTNESS) THEN + REWRITE_TAC[COMPACT_INTERVAL_EQ] THEN ASM_MESON_TAC[HOMEOMORPHIC_EMPTY]; + FIRST_ASSUM(MP_TAC o MATCH_MP HOMEOMORPHIC_COMPACTNESS) THEN + REWRITE_TAC[COMPACT_INTERVAL_EQ] THEN ASM_MESON_TAC[HOMEOMORPHIC_EMPTY]; + MATCH_MP_TAC(TAUT + `(p <=> q) /\ (~p /\ ~q ==> r) ==> p /\ q \/ ~p /\ ~q /\ r`) THEN + CONJ_TAC THENL [ASM_MESON_TAC[HOMEOMORPHIC_EMPTY]; STRIP_TAC] THEN + REWRITE_TAC[GSYM LE_ANTISYM] THEN CONJ_TAC THEN + MATCH_MP_TAC INVARIANCE_OF_DIMENSION THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [homeomorphic]) THENL + [ALL_TAC; GEN_REWRITE_TAC LAND_CONV [SWAP_EXISTS_THM]] THEN + MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC THEN + REWRITE_TAC[homeomorphism] THEN STRIP_TAC THENL + [EXISTS_TAC `interval(a:real^M,b)`; + EXISTS_TAC `interval(c:real^N,d)`] THEN + ASM_REWRITE_TAC[OPEN_INTERVAL] THEN ASM SET_TAC[]; + TRANS_TAC HOMEOMORPHIC_TRANS + `IMAGE ((\x. lambda i. x$i):real^M->real^N) + (interval(a,b))` THEN + CONJ_TAC THENL + [MATCH_MP_TAC INVARIANCE_OF_DOMAIN_HOMEOMORPHIC THEN + REPEAT CONJ_TAC THENL + [ASM_MESON_TAC[LE_REFL]; + MATCH_MP_TAC LINEAR_CONTINUOUS_ON THEN + SIMP_TAC[linear; VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT; + LAMBDA_BETA; CART_EQ]; + REWRITE_TAC[OPEN_INTERVAL]; + SIMP_TAC[CART_EQ; LAMBDA_BETA] THEN ASM_MESON_TAC[]]; + ALL_TAC] THEN + SUBGOAL_THEN + `IMAGE ((\x. lambda i. x$i):real^M->real^N) + (interval(a,b)) = + interval((lambda i. a$i),(lambda i. b$i))` + SUBST1_TAC THENL + [MATCH_MP_TAC SURJECTIVE_IMAGE_EQ THEN + SIMP_TAC[IN_INTERVAL; LAMBDA_BETA] THEN + CONJ_TAC THENL [ALL_TAC; ASM_MESON_TAC[]] THEN + X_GEN_TAC `y:real^N` THEN DISCH_TAC THEN + EXISTS_TAC `(lambda i. (y:real^N)$i):real^M` THEN + SIMP_TAC[CART_EQ; LAMBDA_BETA] THEN + FIRST_ASSUM(SUBST1_TAC o SYM) THEN SIMP_TAC[CART_EQ; LAMBDA_BETA]; + MATCH_MP_TAC HOMEOMORPHIC_OPEN_INTERVALS THEN + GEN_REWRITE_TAC I [TAUT `(p <=> q) <=> (~p <=> ~q)`] THEN + SIMP_TAC[INTERVAL_NE_EMPTY; LAMBDA_BETA] THEN + REPEAT(FIRST_X_ASSUM(MP_TAC o + GEN_REWRITE_RULE I [INTERVAL_NE_EMPTY])) THEN + ASM_MESON_TAC[]]]);; + +let CONTINUOUS_IMAGE_SUBSET_INTERIOR = prove + (`!f:real^M->real^N s. + f continuous_on s /\ dimindex(:N) <= dimindex(:M) /\ + (!x y. x IN s /\ y IN s /\ f x = f y ==> x = y) + ==> IMAGE f (interior s) SUBSET interior(IMAGE f s)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC INTERIOR_MAXIMAL THEN + SIMP_TAC[IMAGE_SUBSET; INTERIOR_SUBSET] THEN + ASM_CASES_TAC `interior s:real^M->bool = {}` THENL + [ASM_REWRITE_TAC[INTERIOR_EMPTY; OPEN_EMPTY; IMAGE_CLAUSES]; + MATCH_MP_TAC INVARIANCE_OF_DOMAIN_GEN] THEN + ASM_REWRITE_TAC[OPEN_INTERIOR] THEN + ASM_MESON_TAC[CONTINUOUS_ON_SUBSET; INTERIOR_SUBSET; SUBSET]);; + +let HOMEOMORPHIC_INTERIORS_SAME_DIMENSION = prove + (`!s:real^M->bool t:real^N->bool. + dimindex(:M) = dimindex(:N) /\ s homeomorphic t + ==> (interior s) homeomorphic (interior t)`, + REPEAT STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [HOMEOMORPHIC_MINIMAL]) THEN + REWRITE_TAC[HOMEOMORPHIC_MINIMAL] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `f:real^M->real^N` THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `g:real^N->real^M` THEN + STRIP_TAC THEN ASM_SIMP_TAC[REWRITE_RULE[SUBSET] INTERIOR_SUBSET] THEN + REWRITE_TAC[SET_RULE `(!x. x IN s ==> f x IN t) <=> IMAGE f s SUBSET t`] THEN + REPEAT CONJ_TAC THENL + [SUBGOAL_THEN `t = IMAGE (f:real^M->real^N) s` SUBST1_TAC THENL + [ASM SET_TAC[]; + MATCH_MP_TAC CONTINUOUS_IMAGE_SUBSET_INTERIOR THEN + ASM_MESON_TAC[LE_REFL]]; + SUBGOAL_THEN `s = IMAGE (g:real^N->real^M) t` SUBST1_TAC THENL + [ASM SET_TAC[]; + MATCH_MP_TAC CONTINUOUS_IMAGE_SUBSET_INTERIOR THEN + ASM_MESON_TAC[LE_REFL]]; + ASM_MESON_TAC[CONTINUOUS_ON_SUBSET; INTERIOR_SUBSET]; + ASM_MESON_TAC[CONTINUOUS_ON_SUBSET; INTERIOR_SUBSET]]);; + +let HOMEOMORPHIC_INTERIORS = prove + (`!s:real^M->bool t:real^N->bool. + s homeomorphic t /\ (interior s = {} <=> interior t = {}) + ==> (interior s) homeomorphic (interior t)`, + REPEAT GEN_TAC THEN + ASM_CASES_TAC `interior t:real^N->bool = {}` THEN + ASM_SIMP_TAC[HOMEOMORPHIC_EMPTY] THEN STRIP_TAC THEN + MATCH_MP_TAC HOMEOMORPHIC_INTERIORS_SAME_DIMENSION THEN + ASM_REWRITE_TAC[] THEN FIRST_X_ASSUM + (STRIP_ASSUME_TAC o GEN_REWRITE_RULE I [HOMEOMORPHIC_MINIMAL]) THEN + REWRITE_TAC[GSYM LE_ANTISYM] THEN CONJ_TAC THEN + MATCH_MP_TAC INVARIANCE_OF_DIMENSION THENL + [MAP_EVERY EXISTS_TAC [`f:real^M->real^N`; `interior s:real^M->bool`]; + MAP_EVERY EXISTS_TAC [`g:real^N->real^M`; `interior t:real^N->bool`]] THEN + ASM_REWRITE_TAC[OPEN_INTERIOR] THEN + ASM_MESON_TAC[CONTINUOUS_ON_SUBSET; INTERIOR_SUBSET; SUBSET]);; + +let HOMEOMORPHIC_FRONTIERS_SAME_DIMENSION = prove + (`!s:real^M->bool t:real^N->bool. + dimindex(:M) = dimindex(:N) /\ + s homeomorphic t /\ closed s /\ closed t + ==> (frontier s) homeomorphic (frontier t)`, + REPEAT STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [HOMEOMORPHIC_MINIMAL]) THEN + REWRITE_TAC[HOMEOMORPHIC_MINIMAL] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `f:real^M->real^N` THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `g:real^N->real^M` THEN + ASM_SIMP_TAC[REWRITE_RULE[SUBSET] FRONTIER_SUBSET_CLOSED] THEN + STRIP_TAC THEN ONCE_REWRITE_TAC[CONJ_ASSOC] THEN CONJ_TAC THENL + [ALL_TAC; ASM_MESON_TAC[FRONTIER_SUBSET_CLOSED; CONTINUOUS_ON_SUBSET]] THEN + ASM_SIMP_TAC[frontier; CLOSURE_CLOSED] THEN + SUBGOAL_THEN + `(!x:real^M. x IN interior s ==> f x IN interior t) /\ + (!y:real^N. y IN interior t ==> g y IN interior s)` + MP_TAC THENL [ALL_TAC; ASM SET_TAC[]] THEN + REWRITE_TAC[SET_RULE `(!x. x IN s ==> f x IN t) <=> IMAGE f s SUBSET t`] THEN + CONJ_TAC THENL + [SUBGOAL_THEN `t = IMAGE (f:real^M->real^N) s` SUBST1_TAC THENL + [ASM SET_TAC[]; + MATCH_MP_TAC CONTINUOUS_IMAGE_SUBSET_INTERIOR THEN + ASM_MESON_TAC[LE_REFL]]; + SUBGOAL_THEN `s = IMAGE (g:real^N->real^M) t` SUBST1_TAC THENL + [ASM SET_TAC[]; + MATCH_MP_TAC CONTINUOUS_IMAGE_SUBSET_INTERIOR THEN + ASM_MESON_TAC[LE_REFL]]]);; + +let HOMEOMORPHIC_FRONTIERS = prove + (`!s:real^M->bool t:real^N->bool. + s homeomorphic t /\ closed s /\ closed t /\ + (interior s = {} <=> interior t = {}) + ==> (frontier s) homeomorphic (frontier t)`, + REPEAT GEN_TAC THEN + ASM_CASES_TAC `interior t:real^N->bool = {}` THENL + [ASM_SIMP_TAC[frontier; CLOSURE_CLOSED; DIFF_EMPTY]; STRIP_TAC] THEN + MATCH_MP_TAC HOMEOMORPHIC_FRONTIERS_SAME_DIMENSION THEN + ASM_REWRITE_TAC[] THEN FIRST_X_ASSUM + (STRIP_ASSUME_TAC o GEN_REWRITE_RULE I [HOMEOMORPHIC_MINIMAL]) THEN + REWRITE_TAC[GSYM LE_ANTISYM] THEN CONJ_TAC THEN + MATCH_MP_TAC INVARIANCE_OF_DIMENSION THENL + [MAP_EVERY EXISTS_TAC [`f:real^M->real^N`; `interior s:real^M->bool`]; + MAP_EVERY EXISTS_TAC [`g:real^N->real^M`; `interior t:real^N->bool`]] THEN + ASM_REWRITE_TAC[OPEN_INTERIOR] THEN + ASM_MESON_TAC[CONTINUOUS_ON_SUBSET; INTERIOR_SUBSET; SUBSET]);; + +let CONTINUOUS_IMAGE_SUBSET_RELATIVE_INTERIOR = prove + (`!f:real^M->real^N s t. + f continuous_on s /\ IMAGE f s SUBSET t /\ aff_dim t <= aff_dim s /\ + (!x y. x IN s /\ y IN s /\ f x = f y ==> x = y) + ==> IMAGE f (relative_interior s) SUBSET relative_interior(IMAGE f s)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC RELATIVE_INTERIOR_MAXIMAL THEN + SIMP_TAC[IMAGE_SUBSET; RELATIVE_INTERIOR_SUBSET] THEN + MATCH_MP_TAC INVARIANCE_OF_DOMAIN_AFFINE_SETS THEN + EXISTS_TAC `affine hull s:real^M->bool` THEN + ASM_REWRITE_TAC[AFFINE_AFFINE_HULL; AFF_DIM_AFFINE_HULL] THEN + REWRITE_TAC[OPEN_IN_RELATIVE_INTERIOR] THEN CONJ_TAC THENL + [ASM_MESON_TAC[AFF_DIM_SUBSET; INT_LE_TRANS]; ALL_TAC] THEN + ASSUME_TAC(ISPEC `s:real^M->bool` RELATIVE_INTERIOR_SUBSET) THEN + REPEAT CONJ_TAC THENL + [ASM_MESON_TAC[CONTINUOUS_ON_SUBSET]; ALL_TAC; ASM SET_TAC[]] THEN + MATCH_MP_TAC SUBSET_TRANS THEN + EXISTS_TAC `IMAGE (f:real^M->real^N) s` THEN + SIMP_TAC[IMAGE_SUBSET; RELATIVE_INTERIOR_SUBSET; HULL_SUBSET]);; + +let HOMEOMORPHIC_RELATIVE_INTERIORS_SAME_DIMENSION = prove + (`!s:real^M->bool t:real^N->bool. + aff_dim s = aff_dim t /\ s homeomorphic t + ==> (relative_interior s) homeomorphic (relative_interior t)`, + REPEAT STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [HOMEOMORPHIC_MINIMAL]) THEN + REWRITE_TAC[HOMEOMORPHIC_MINIMAL] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `f:real^M->real^N` THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `g:real^N->real^M` THEN + STRIP_TAC THEN + ASM_SIMP_TAC[REWRITE_RULE[SUBSET] RELATIVE_INTERIOR_SUBSET] THEN + REWRITE_TAC[SET_RULE `(!x. x IN s ==> f x IN t) <=> IMAGE f s SUBSET t`] THEN + REPEAT CONJ_TAC THENL + [SUBGOAL_THEN `t = IMAGE (f:real^M->real^N) s` SUBST1_TAC THENL + [ASM SET_TAC[]; + MATCH_MP_TAC CONTINUOUS_IMAGE_SUBSET_RELATIVE_INTERIOR THEN + EXISTS_TAC `t:real^N->bool` THEN ASM_REWRITE_TAC[INT_LE_REFL] THEN + ASM SET_TAC[]]; + SUBGOAL_THEN `s = IMAGE (g:real^N->real^M) t` SUBST1_TAC THENL + [ASM SET_TAC[]; + MATCH_MP_TAC CONTINUOUS_IMAGE_SUBSET_RELATIVE_INTERIOR THEN + EXISTS_TAC `s:real^M->bool` THEN ASM_REWRITE_TAC[INT_LE_REFL] THEN + ASM SET_TAC[]]; + ASM_MESON_TAC[CONTINUOUS_ON_SUBSET; RELATIVE_INTERIOR_SUBSET]; + ASM_MESON_TAC[CONTINUOUS_ON_SUBSET; RELATIVE_INTERIOR_SUBSET]]);; + +let HOMEOMORPHIC_RELATIVE_INTERIORS = prove + (`!s:real^M->bool t:real^N->bool. + s homeomorphic t /\ + (relative_interior s = {} <=> relative_interior t = {}) + ==> (relative_interior s) homeomorphic (relative_interior t)`, + REPEAT GEN_TAC THEN + ASM_CASES_TAC `relative_interior t:real^N->bool = {}` THEN + ASM_SIMP_TAC[HOMEOMORPHIC_EMPTY] THEN STRIP_TAC THEN + MATCH_MP_TAC HOMEOMORPHIC_RELATIVE_INTERIORS_SAME_DIMENSION THEN + ASM_REWRITE_TAC[] THEN FIRST_X_ASSUM + (STRIP_ASSUME_TAC o GEN_REWRITE_RULE I [HOMEOMORPHIC_MINIMAL]) THEN + ONCE_REWRITE_TAC[GSYM AFF_DIM_AFFINE_HULL] THEN + REWRITE_TAC[GSYM INT_LE_ANTISYM] THEN CONJ_TAC THEN + MATCH_MP_TAC INVARIANCE_OF_DIMENSION_AFFINE_SETS THENL + [MAP_EVERY EXISTS_TAC + [`f:real^M->real^N`; `relative_interior s:real^M->bool`]; + MAP_EVERY EXISTS_TAC + [`g:real^N->real^M`; `relative_interior t:real^N->bool`]] THEN + ASM_REWRITE_TAC[OPEN_IN_RELATIVE_INTERIOR; AFFINE_AFFINE_HULL] THEN + (REPEAT CONJ_TAC THENL + [ASM_MESON_TAC[CONTINUOUS_ON_SUBSET; RELATIVE_INTERIOR_SUBSET]; + ASM_MESON_TAC[RELATIVE_INTERIOR_SUBSET; HULL_SUBSET; SET_RULE + `(!x. x IN s ==> f x IN t) /\ s' SUBSET s /\ t SUBSET t' + ==> IMAGE f s' SUBSET t'`]; + ASM_MESON_TAC[RELATIVE_INTERIOR_SUBSET; SUBSET]]));; + +let HOMEOMORPHIC_RELATIVE_BOUNDARIES_SAME_DIMENSION = prove + (`!s:real^M->bool t:real^N->bool. + aff_dim s = aff_dim t /\ s homeomorphic t + ==> (s DIFF relative_interior s) homeomorphic + (t DIFF relative_interior t)`, + REPEAT STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [HOMEOMORPHIC_MINIMAL]) THEN + REWRITE_TAC[HOMEOMORPHIC_MINIMAL] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `f:real^M->real^N` THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `g:real^N->real^M` THEN + STRIP_TAC THEN ASM_SIMP_TAC[IN_DIFF] THEN + ONCE_REWRITE_TAC[CONJ_ASSOC] THEN CONJ_TAC THENL + [ALL_TAC; ASM_MESON_TAC[SUBSET_DIFF; CONTINUOUS_ON_SUBSET]] THEN + SUBGOAL_THEN + `(!x:real^M. x IN relative_interior s ==> f x IN relative_interior t) /\ + (!y:real^N. y IN relative_interior t ==> g y IN relative_interior s)` + MP_TAC THENL [ALL_TAC; ASM SET_TAC[]] THEN + REWRITE_TAC[SET_RULE `(!x. x IN s ==> f x IN t) <=> IMAGE f s SUBSET t`] THEN + CONJ_TAC THENL + [SUBGOAL_THEN `t = IMAGE (f:real^M->real^N) s` SUBST1_TAC THENL + [ASM SET_TAC[]; + MATCH_MP_TAC CONTINUOUS_IMAGE_SUBSET_RELATIVE_INTERIOR THEN + EXISTS_TAC `t:real^N->bool` THEN ASM_REWRITE_TAC[INT_LE_REFL] THEN + ASM SET_TAC[]]; + SUBGOAL_THEN `s = IMAGE (g:real^N->real^M) t` SUBST1_TAC THENL + [ASM SET_TAC[]; + MATCH_MP_TAC CONTINUOUS_IMAGE_SUBSET_RELATIVE_INTERIOR THEN + EXISTS_TAC `s:real^M->bool` THEN ASM_REWRITE_TAC[INT_LE_REFL] THEN + ASM SET_TAC[]]]);; + +let HOMEOMORPHIC_RELATIVE_BOUNDARIES = prove + (`!s:real^M->bool t:real^N->bool. + s homeomorphic t /\ + (relative_interior s = {} <=> relative_interior t = {}) + ==> (s DIFF relative_interior s) homeomorphic + (t DIFF relative_interior t)`, + REPEAT GEN_TAC THEN + ASM_CASES_TAC `relative_interior t:real^N->bool = {}` THEN + ASM_SIMP_TAC[DIFF_EMPTY] THEN STRIP_TAC THEN + MATCH_MP_TAC HOMEOMORPHIC_RELATIVE_BOUNDARIES_SAME_DIMENSION THEN + ASM_REWRITE_TAC[] THEN FIRST_X_ASSUM + (STRIP_ASSUME_TAC o GEN_REWRITE_RULE I [HOMEOMORPHIC_MINIMAL]) THEN + ONCE_REWRITE_TAC[GSYM AFF_DIM_AFFINE_HULL] THEN + REWRITE_TAC[GSYM INT_LE_ANTISYM] THEN CONJ_TAC THEN + MATCH_MP_TAC INVARIANCE_OF_DIMENSION_AFFINE_SETS THENL + [MAP_EVERY EXISTS_TAC + [`f:real^M->real^N`; `relative_interior s:real^M->bool`]; + MAP_EVERY EXISTS_TAC + [`g:real^N->real^M`; `relative_interior t:real^N->bool`]] THEN + ASM_REWRITE_TAC[OPEN_IN_RELATIVE_INTERIOR; AFFINE_AFFINE_HULL] THEN + (REPEAT CONJ_TAC THENL + [ASM_MESON_TAC[CONTINUOUS_ON_SUBSET; RELATIVE_INTERIOR_SUBSET]; + ASM_MESON_TAC[RELATIVE_INTERIOR_SUBSET; HULL_SUBSET; SET_RULE + `(!x. x IN s ==> f x IN t) /\ s' SUBSET s /\ t SUBSET t' + ==> IMAGE f s' SUBSET t'`]; + ASM_MESON_TAC[RELATIVE_INTERIOR_SUBSET; SUBSET]]));; + +let UNIFORMLY_CONTINUOUS_HOMEOMORPHISM_UNIV_TRIVIAL = prove + (`!f g s:real^N->bool. + homeomorphism (s,(:real^N)) (f,g) /\ f uniformly_continuous_on s + ==> s = (:real^N)`, + REPEAT GEN_TAC THEN REWRITE_TAC[homeomorphism; IN_UNIV] THEN + ASM_CASES_TAC `s:real^N->bool = {}` THEN + ASM_REWRITE_TAC[NOT_IN_EMPTY] THENL [SET_TAC[]; STRIP_TAC] THEN + MP_TAC(ISPEC `s:real^N->bool` CLOPEN) THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(SUBST1_TAC o SYM) THEN CONJ_TAC THENL + [REWRITE_TAC[GSYM COMPLETE_EQ_CLOSED; complete] THEN + X_GEN_TAC `x:num->real^N` THEN STRIP_TAC THEN + SUBGOAL_THEN `cauchy ((f:real^N->real^N) o x)` MP_TAC THENL + [ASM_MESON_TAC[UNIFORMLY_CONTINUOUS_IMP_CAUCHY_CONTINUOUS]; ALL_TAC] THEN + REWRITE_TAC[GSYM CONVERGENT_EQ_CAUCHY] THEN + DISCH_THEN(X_CHOOSE_TAC `l:real^N`) THEN + EXISTS_TAC `(g:real^N->real^N) l` THEN + CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + MATCH_MP_TAC LIM_TRANSFORM_EVENTUALLY THEN + EXISTS_TAC `(g:real^N->real^N) o (f:real^N->real^N) o (x:num->real^N)` THEN + REWRITE_TAC[o_DEF] THEN CONJ_TAC THENL + [MATCH_MP_TAC ALWAYS_EVENTUALLY THEN ASM SET_TAC[]; + MATCH_MP_TAC LIM_CONTINUOUS_FUNCTION THEN ASM_SIMP_TAC[GSYM o_DEF] THEN + ASM_MESON_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_AT; OPEN_UNIV; IN_UNIV]]; + FIRST_X_ASSUM(fun th -> GEN_REWRITE_TAC RAND_CONV [SYM th]) THEN + MATCH_MP_TAC INVARIANCE_OF_DOMAIN THEN + ASM_REWRITE_TAC[OPEN_UNIV] THEN ASM SET_TAC[]]);; + +let INVARIANCE_OF_DOMAIN_SPHERE_AFFINE_SET_GEN = prove + (`!f:real^M->real^N u s t. + f continuous_on s /\ IMAGE f s SUBSET t /\ + (!x y. x IN s /\ y IN s /\ f x = f y ==> x = y) /\ + bounded u /\ convex u /\ affine t /\ aff_dim t < aff_dim u /\ + open_in (subtopology euclidean (relative_frontier u)) s + ==> open_in (subtopology euclidean t) (IMAGE f s)`, + REPEAT GEN_TAC THEN + ASM_CASES_TAC `relative_frontier u:real^M->bool = {}` THEN + ASM_SIMP_TAC[OPEN_IN_SUBTOPOLOGY_EMPTY; IMAGE_CLAUSES; OPEN_IN_EMPTY] THEN + STRIP_TAC THEN FIRST_ASSUM(ASSUME_TAC o MATCH_MP OPEN_IN_IMP_SUBSET) THEN + SUBGOAL_THEN + `?b c:real^M. b IN relative_frontier u /\ c IN relative_frontier u /\ + ~(b = c)` + STRIP_ASSUME_TAC THENL + [MATCH_MP_TAC(SET_RULE + `~(s = {} \/ ?x. s = {x}) ==> ?a b. a IN s /\ b IN s /\ ~(a = b)`) THEN + ASM_MESON_TAC[RELATIVE_FRONTIER_NOT_SING]; + ALL_TAC] THEN + MP_TAC(ISPECL [`(:real^M)`; `aff_dim(u:real^M->bool) - &1`] + CHOOSE_AFFINE_SUBSET) THEN + REWRITE_TAC[SUBSET_UNIV; AFFINE_UNIV] THEN ANTS_TAC THENL + [MATCH_MP_TAC(INT_ARITH + `&0:int <= t /\ t <= n ==> --a <= t - a /\ t - &1 <= n`) THEN + REWRITE_TAC[AFF_DIM_LE_UNIV; AFF_DIM_UNIV; AFF_DIM_POS_LE] THEN + ASM_MESON_TAC[RELATIVE_FRONTIER_EMPTY; NOT_IN_EMPTY]; + DISCH_THEN(X_CHOOSE_THEN `af:real^M->bool` STRIP_ASSUME_TAC)] THEN + MP_TAC(ISPECL [`u:real^M->bool`; `af:real^M->bool`] + HOMEOMORPHIC_PUNCTURED_SPHERE_AFFINE_GEN) THEN + ASM_REWRITE_TAC[INT_ARITH `x - a + a:int = x`] THEN + DISCH_THEN(fun th -> + MP_TAC(SPEC `c:real^M` th) THEN MP_TAC(SPEC `b:real^M` th)) THEN + ASM_REWRITE_TAC[homeomorphic; homeomorphism; LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`g:real^M->real^M`; `h:real^M->real^M`] THEN + REWRITE_TAC[IN_ELIM_THM] THEN STRIP_TAC THEN + MAP_EVERY X_GEN_TAC [`j:real^M->real^M`; `k:real^M->real^M`] THEN + STRIP_TAC THEN + MP_TAC(ISPECL + [`(f:real^M->real^N) o (k:real^M->real^M)`; + `(af:real^M->bool)`; + `t:real^N->bool`; `IMAGE (j:real^M->real^M) (s DELETE c)`] + INVARIANCE_OF_DOMAIN_AFFINE_SETS) THEN + MP_TAC(ISPECL + [`(f:real^M->real^N) o (h:real^M->real^M)`; + `(af:real^M->bool)`; + `t:real^N->bool`; `IMAGE (g:real^M->real^M) (s DELETE b)`] + INVARIANCE_OF_DOMAIN_AFFINE_SETS) THEN + ASM_REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_IMAGE] THEN + ASM_REWRITE_TAC[IMP_IMP; INT_ARITH `x:int <= y - &1 <=> x < y`] THEN + MATCH_MP_TAC(TAUT + `(p1 /\ p2) /\ (q1 /\ q2 ==> r) ==> (p1 ==> q1) /\ (p2 ==> q2) ==> r`) THEN + REPEAT CONJ_TAC THENL + [MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN CONJ_TAC THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET)) THEN + ASM SET_TAC[]; + REWRITE_TAC[IMAGE_o] THEN ASM SET_TAC[]; + RULE_ASSUM_TAC(REWRITE_RULE[SUBSET; IN_DELETE]) THEN + ASM_SIMP_TAC[o_THM; IN_DELETE; IMP_CONJ] THEN ASM_MESON_TAC[]; + MATCH_MP_TAC HOMEOMORPHISM_IMP_OPEN_MAP THEN MAP_EVERY EXISTS_TAC + [`h:real^M->real^M`; `relative_frontier u DELETE (b:real^M)`] THEN + ASM_SIMP_TAC[homeomorphism; DOT_BASIS; DIMINDEX_GE_1; LE_REFL] THEN + ASM_REWRITE_TAC[IN_ELIM_THM; OPEN_IN_OPEN] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [OPEN_IN_OPEN]) THEN + MATCH_MP_TAC MONO_EXISTS THEN SET_TAC[]; + MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN CONJ_TAC THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET)) THEN + ASM SET_TAC[]; + REWRITE_TAC[IMAGE_o] THEN ASM SET_TAC[]; + RULE_ASSUM_TAC(REWRITE_RULE[SUBSET; IN_DELETE]) THEN + ASM_SIMP_TAC[o_THM; IN_DELETE; IMP_CONJ] THEN ASM_MESON_TAC[]; + MATCH_MP_TAC HOMEOMORPHISM_IMP_OPEN_MAP THEN MAP_EVERY EXISTS_TAC + [`k:real^M->real^M`; `relative_frontier u DELETE (c:real^M)`] THEN + ASM_SIMP_TAC[homeomorphism; DOT_BASIS; DIMINDEX_GE_1; LE_REFL] THEN + ASM_REWRITE_TAC[IN_ELIM_THM; OPEN_IN_OPEN] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [OPEN_IN_OPEN]) THEN + MATCH_MP_TAC MONO_EXISTS THEN SET_TAC[]; + DISCH_THEN(MP_TAC o MATCH_MP OPEN_IN_UNION) THEN + MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN + MATCH_MP_TAC EQ_TRANS THEN + EXISTS_TAC `IMAGE (f:real^M->real^N) + ((s DELETE b) UNION (s DELETE c))` THEN + CONJ_TAC THENL + [REWRITE_TAC[IMAGE_UNION] THEN BINOP_TAC; ASM SET_TAC[]] THEN + REWRITE_TAC[IMAGE_o] THEN AP_TERM_TAC THEN ASM SET_TAC[]]);; + +let INVARIANCE_OF_DOMAIN_SPHERE_AFFINE_SET = prove + (`!f:real^M->real^N a r s t. + f continuous_on s /\ IMAGE f s SUBSET t /\ + (!x y. x IN s /\ y IN s /\ f x = f y ==> x = y) /\ + ~(r = &0) /\ affine t /\ aff_dim t < &(dimindex(:M)) /\ + open_in (subtopology euclidean (sphere(a,r))) s + ==> open_in (subtopology euclidean t) (IMAGE f s)`, + REPEAT GEN_TAC THEN ASM_CASES_TAC `sphere(a:real^M,r) = {}` THEN + ASM_SIMP_TAC[OPEN_IN_SUBTOPOLOGY_EMPTY; OPEN_IN_EMPTY; IMAGE_CLAUSES] THEN + RULE_ASSUM_TAC(REWRITE_RULE[SPHERE_EQ_EMPTY; REAL_NOT_LT]) THEN + STRIP_TAC THEN + MP_TAC(ISPECL [`f:real^M->real^N`; `cball(a:real^M,r)`; + `s:real^M->bool`; `t:real^N->bool`] + INVARIANCE_OF_DOMAIN_SPHERE_AFFINE_SET_GEN) THEN + ASM_REWRITE_TAC[AFF_DIM_CBALL; RELATIVE_FRONTIER_CBALL; + BOUNDED_CBALL; CONVEX_CBALL] THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN ASM_REAL_ARITH_TAC);; + +let NO_EMBEDDING_SPHERE_LOWDIM = prove + (`!f:real^M->real^N a r. + &0 < r /\ + f continuous_on sphere(a,r) /\ + (!x y. x IN sphere(a,r) /\ y IN sphere(a,r) /\ f x = f y ==> x = y) + ==> dimindex(:M) <= dimindex(:N)`, + REWRITE_TAC[GSYM NOT_LT] THEN REPEAT STRIP_TAC THEN + MP_TAC(ISPEC `IMAGE (f:real^M->real^N) (sphere(a:real^M,r))` + COMPACT_OPEN) THEN + ASM_SIMP_TAC[COMPACT_CONTINUOUS_IMAGE; IMAGE_EQ_EMPTY; + COMPACT_SPHERE; SPHERE_EQ_EMPTY; + REAL_ARITH `&0 < r ==> ~(r < &0)`] THEN + ONCE_REWRITE_TAC[OPEN_IN] THEN + ONCE_REWRITE_TAC[GSYM SUBTOPOLOGY_UNIV] THEN + MATCH_MP_TAC INVARIANCE_OF_DOMAIN_SPHERE_AFFINE_SET THEN + MAP_EVERY EXISTS_TAC [`a:real^M`; `r:real`] THEN + ASM_REWRITE_TAC[AFFINE_UNIV; SUBSET_UNIV; AFF_DIM_UNIV; + OPEN_IN_REFL; INT_OF_NUM_LT] THEN + ASM_REAL_ARITH_TAC);; + +(* ------------------------------------------------------------------------- *) +(* Dimension-based conditions for various homeomorphisms. *) +(* ------------------------------------------------------------------------- *) + +let HOMEOMORPHIC_SUBSPACES_EQ = prove + (`!s:real^M->bool t:real^N->bool. + subspace s /\ subspace t ==> (s homeomorphic t <=> dim s = dim t)`, + REPEAT STRIP_TAC THEN EQ_TAC THENL + [ALL_TAC; ASM_MESON_TAC[HOMEOMORPHIC_SUBSPACES]] THEN + REWRITE_TAC[homeomorphic; HOMEOMORPHISM; LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`f:real^M->real^N`; `g:real^N->real^M`] THEN + STRIP_TAC THEN REWRITE_TAC[GSYM LE_ANTISYM] THEN CONJ_TAC THEN + MATCH_MP_TAC CONTINUOUS_INJECTIVE_IMAGE_SUBSPACE_DIM_LE THEN + ASM_MESON_TAC[]);; + +let HOMEOMORPHIC_AFFINE_SETS_EQ = prove + (`!s:real^M->bool t:real^N->bool. + affine s /\ affine t ==> (s homeomorphic t <=> aff_dim s = aff_dim t)`, + REPEAT GEN_TAC THEN + ASM_CASES_TAC `t:real^N->bool = {}` THEN + ASM_REWRITE_TAC[AFF_DIM_EMPTY; AFF_DIM_EQ_MINUS1; HOMEOMORPHIC_EMPTY] THEN + POP_ASSUM MP_TAC THEN + GEN_REWRITE_TAC (funpow 3 RAND_CONV) [EQ_SYM_EQ] THEN + ASM_CASES_TAC `s:real^M->bool = {}` THEN + ASM_SIMP_TAC[AFF_DIM_EMPTY; AFF_DIM_EQ_MINUS1; HOMEOMORPHIC_EMPTY] THEN + POP_ASSUM MP_TAC THEN REWRITE_TAC + [GSYM MEMBER_NOT_EMPTY; LEFT_IMP_EXISTS_THM; RIGHT_IMP_FORALL_THM] THEN + MAP_EVERY X_GEN_TAC [`a:real^M`; `b:real^N`] THEN + GEOM_ORIGIN_TAC `a:real^M` THEN GEOM_ORIGIN_TAC `b:real^N` THEN + SIMP_TAC[AFFINE_EQ_SUBSPACE; HOMEOMORPHIC_SUBSPACES_EQ; AFF_DIM_DIM_0; + HULL_INC; INT_OF_NUM_EQ] THEN + MESON_TAC[]);; + +let HOMEOMORPHIC_HYPERPLANES_EQ = prove + (`!a:real^M b c:real^N d. + ~(a = vec 0) /\ ~(c = vec 0) + ==> ({x | a dot x = b} homeomorphic {x | c dot x = d} <=> + dimindex(:M) = dimindex(:N))`, + SIMP_TAC[HOMEOMORPHIC_AFFINE_SETS_EQ; AFFINE_HYPERPLANE] THEN + SIMP_TAC[AFF_DIM_HYPERPLANE; INT_OF_NUM_EQ; + INT_ARITH `x - &1:int = y - &1 <=> x = y`]);; + +let HOMEOMORPHIC_UNIV_UNIV = prove + (`(:real^M) homeomorphic (:real^N) <=> dimindex(:M) = dimindex(:N)`, + SIMP_TAC[HOMEOMORPHIC_SUBSPACES_EQ; DIM_UNIV; SUBSPACE_UNIV]);; + +let HOMEOMORPHIC_CBALLS_EQ = prove + (`!a:real^M b:real^N r s. + cball(a,r) homeomorphic cball(b,s) <=> + r < &0 /\ s < &0 \/ r = &0 /\ s = &0 \/ + &0 < r /\ &0 < s /\ dimindex(:M) = dimindex(:N)`, + let lemma = + let d = `dimindex(:M) = dimindex(:N)` + and t = `?a:real^M b:real^N. ~(cball(a,r) homeomorphic cball(b,s))` in + DISCH d (DISCH t (GEOM_EQUAL_DIMENSION_RULE (ASSUME d) (ASSUME t))) in + REPEAT GEN_TAC THEN ASM_CASES_TAC `r < &0` THENL + [ASM_SIMP_TAC[CBALL_EMPTY; HOMEOMORPHIC_EMPTY; CBALL_EQ_EMPTY] THEN + EQ_TAC THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN ASM_REAL_ARITH_TAC; + ALL_TAC] THEN + ASM_CASES_TAC `r = &0` THEN ASM_REWRITE_TAC[REAL_LT_REFL] THENL + [ASM_SIMP_TAC[CBALL_TRIVIAL; FINITE_SING; HOMEOMORPHIC_FINITE_STRONG] THEN + REWRITE_TAC[FINITE_CBALL] THEN + ASM_CASES_TAC `s < &0` THEN + ASM_SIMP_TAC[CBALL_EMPTY; CARD_CLAUSES; FINITE_EMPTY; + NOT_IN_EMPTY; ARITH; REAL_LT_IMP_NE] THEN + ASM_CASES_TAC `s = &0` THENL [ALL_TAC; ASM_REAL_ARITH_TAC] THEN + ASM_SIMP_TAC[CBALL_TRIVIAL; CARD_CLAUSES; FINITE_EMPTY; NOT_IN_EMPTY; + REAL_LE_REFL; ARITH]; + ALL_TAC] THEN + SUBGOAL_THEN `&0 < r` ASSUME_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN + ASM_CASES_TAC `s <= &0` THEN + ASM_SIMP_TAC[HOMEOMORPHIC_FINITE_STRONG; FINITE_CBALL] THENL + [ASM_REAL_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `&0 < s` ASSUME_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN + ASM_REWRITE_TAC[] THEN EQ_TAC THENL + [REWRITE_TAC[homeomorphic; HOMEOMORPHISM; LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`f:real^M->real^N`; `g:real^N->real^M`] THEN + STRIP_TAC THEN REWRITE_TAC[GSYM LE_ANTISYM] THEN CONJ_TAC THEN + MATCH_MP_TAC INVARIANCE_OF_DIMENSION THENL + [MAP_EVERY EXISTS_TAC [`f:real^M->real^N`; `ball(a:real^M,r)`] THEN + MP_TAC(ISPECL [`a:real^M`; `r:real`] BALL_SUBSET_CBALL); + MAP_EVERY EXISTS_TAC [`g:real^N->real^M`; `ball(b:real^N,s)`] THEN + MP_TAC(ISPECL [`b:real^N`; `s:real`] BALL_SUBSET_CBALL)] THEN + ASM_REWRITE_TAC[BALL_EQ_EMPTY; OPEN_BALL; REAL_NOT_LE] THEN + ASM_MESON_TAC[SUBSET; CONTINUOUS_ON_SUBSET]; + DISCH_THEN(MP_TAC o MATCH_MP lemma) THEN + GEN_REWRITE_TAC LAND_CONV [GSYM CONTRAPOS_THM] THEN + REWRITE_TAC[NOT_EXISTS_THM] THEN ASM_SIMP_TAC[HOMEOMORPHIC_CBALLS]]);; + +let HOMEOMORPHIC_BALLS_EQ = prove + (`!a:real^M b:real^N r s. + ball(a,r) homeomorphic ball(b,s) <=> + r <= &0 /\ s <= &0 \/ + &0 < r /\ &0 < s /\ dimindex(:M) = dimindex(:N)`, + let lemma = + let d = `dimindex(:M) = dimindex(:N)` + and t = `?a:real^M b:real^N. ~(ball(a,r) homeomorphic ball(b,s))` in + DISCH d (DISCH t (GEOM_EQUAL_DIMENSION_RULE (ASSUME d) (ASSUME t))) in + REPEAT GEN_TAC THEN ASM_CASES_TAC `r <= &0` THENL + [ASM_SIMP_TAC[BALL_EMPTY; HOMEOMORPHIC_EMPTY; BALL_EQ_EMPTY] THEN + EQ_TAC THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN ASM_REAL_ARITH_TAC; + ALL_TAC] THEN + ASM_CASES_TAC `s <= &0` THENL + [ASM_SIMP_TAC[BALL_EMPTY; HOMEOMORPHIC_EMPTY; BALL_EQ_EMPTY] THEN + ASM_REAL_ARITH_TAC; + ALL_TAC] THEN + ASM_REWRITE_TAC[] THEN RULE_ASSUM_TAC(REWRITE_RULE[REAL_NOT_LE]) THEN + ASM_REWRITE_TAC[] THEN EQ_TAC THENL + [REWRITE_TAC[homeomorphic; HOMEOMORPHISM; LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`f:real^M->real^N`; `g:real^N->real^M`] THEN + STRIP_TAC THEN REWRITE_TAC[GSYM LE_ANTISYM] THEN CONJ_TAC THEN + MATCH_MP_TAC INVARIANCE_OF_DIMENSION THENL + [MAP_EVERY EXISTS_TAC [`f:real^M->real^N`; `ball(a:real^M,r)`]; + MAP_EVERY EXISTS_TAC [`g:real^N->real^M`; `ball(b:real^N,s)`]] THEN + ASM_REWRITE_TAC[BALL_EQ_EMPTY; OPEN_BALL; REAL_NOT_LE] THEN + ASM SET_TAC[]; + DISCH_THEN(MP_TAC o MATCH_MP lemma) THEN + GEN_REWRITE_TAC LAND_CONV [GSYM CONTRAPOS_THM] THEN + REWRITE_TAC[NOT_EXISTS_THM] THEN ASM_SIMP_TAC[HOMEOMORPHIC_BALLS]]);; + +let SIMPLY_CONNECTED_SPHERE_EQ = prove + (`!a:real^N r. + simply_connected(sphere(a,r)) <=> 3 <= dimindex(:N) \/ r <= &0`, + let hslemma = prove + (`!a:real^M r b:real^N s. + dimindex(:M) = dimindex(:N) + ==> &0 < r /\ &0 < s ==> (sphere(a,r) homeomorphic sphere(b,s))`, + REPEAT STRIP_TAC THEN FIRST_ASSUM(fun th -> + let t = `?a:real^M b:real^N. ~(sphere(a,r) homeomorphic sphere(b,s))` in + MP_TAC(DISCH t (GEOM_EQUAL_DIMENSION_RULE th (ASSUME t)))) THEN + ASM_SIMP_TAC[HOMEOMORPHIC_SPHERES] THEN MESON_TAC[]) in + REPEAT GEN_TAC THEN + ASM_CASES_TAC `r < &0` THEN + ASM_SIMP_TAC[SPHERE_EMPTY; REAL_LT_IMP_LE; SIMPLY_CONNECTED_EMPTY] THEN + ASM_CASES_TAC `r = &0` THEN + ASM_SIMP_TAC[SPHERE_SING; REAL_LE_REFL; CONVEX_IMP_SIMPLY_CONNECTED; + CONVEX_SING] THEN + ASM_REWRITE_TAC[REAL_LE_LT] THEN + EQ_TAC THEN REWRITE_TAC[SIMPLY_CONNECTED_SPHERE] THEN + ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN + REWRITE_TAC[ARITH_RULE `~(3 <= n) <=> (1 <= n ==> n = 1 \/ n = 2)`] THEN + REWRITE_TAC[DIMINDEX_GE_1] THEN STRIP_TAC THENL + [DISCH_THEN(MP_TAC o MATCH_MP SIMPLY_CONNECTED_IMP_CONNECTED) THEN + ASM_REWRITE_TAC[CONNECTED_SPHERE_EQ; ARITH] THEN ASM_REAL_ARITH_TAC; + RULE_ASSUM_TAC(REWRITE_RULE[GSYM DIMINDEX_2]) THEN + FIRST_ASSUM(MP_TAC o ISPECL [`a:real^N`; `r:real`; `vec 0:real^2`; + `&1:real`] o MATCH_MP hslemma) THEN + ANTS_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN + DISCH_THEN(SUBST1_TAC o MATCH_MP HOMEOMORPHIC_SIMPLY_CONNECTED_EQ) THEN + REWRITE_TAC[SIMPLY_CONNECTED_EQ_CONTRACTIBLE_CIRCLEMAP] THEN + REPEAT STRIP_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC `\x:real^2. x`) THEN + REWRITE_TAC[CONTINUOUS_ON_ID; IMAGE_ID; SUBSET_REFL] THEN + REWRITE_TAC[GSYM contractible; CONTRACTIBLE_SPHERE] THEN + CONV_TAC REAL_RAT_REDUCE_CONV]);; + +let NOT_SIMPLY_CONNECTED_CIRCLE = prove + (`!a:real^2 r. &0 < r ==> ~simply_connected(sphere(a,r))`, + REWRITE_TAC[SIMPLY_CONNECTED_SPHERE_EQ; DIMINDEX_2; ARITH] THEN + REAL_ARITH_TAC);; + +(* ------------------------------------------------------------------------- *) +(* The power, squaring and exponential functions as covering maps. *) +(* ------------------------------------------------------------------------- *) + +let COVERING_SPACE_POW_PUNCTURED_PLANE = prove + (`!n. 0 < n + ==> covering_space ((:complex) DIFF {Cx(&0)},(\z. z pow n)) + ((:complex) DIFF {Cx (&0)})`, + let lemma = prove + (`!n. 0 < n + ==> ?e. &0 < e /\ + !w z. norm(w - z) < e * norm(z) + ==> (w pow n = z pow n <=> w = z)`, + REPEAT STRIP_TAC THEN + FIRST_ASSUM(DISJ_CASES_TAC o MATCH_MP (ARITH_RULE + `0 < n ==> n = 1 \/ 2 <= n`)) THEN + ASM_SIMP_TAC[COMPLEX_POW_1] THENL [MESON_TAC[REAL_LT_01]; ALL_TAC] THEN + EXISTS_TAC `&2 * sin(pi / &n)` THEN CONJ_TAC THENL + [REWRITE_TAC[REAL_ARITH `&0 < &2 * x <=> &0 < x`] THEN + MATCH_MP_TAC SIN_POS_PI THEN + ASM_SIMP_TAC[REAL_LT_DIV; PI_POS; REAL_OF_NUM_LT] THEN + REWRITE_TAC[REAL_ARITH `x / y < x <=> &0 < x * (&1 - inv y)`] THEN + MATCH_MP_TAC REAL_LT_MUL THEN REWRITE_TAC[PI_POS; REAL_SUB_LT] THEN + MATCH_MP_TAC REAL_INV_LT_1 THEN REWRITE_TAC[REAL_OF_NUM_LT] THEN + ASM_ARITH_TAC; + ALL_TAC] THEN + REPEAT GEN_TAC THEN ASM_CASES_TAC `z = Cx(&0)` THENL + [ASM_REWRITE_TAC[COMPLEX_NORM_0; COMPLEX_SUB_RZERO] THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN REWRITE_TAC[] THEN + SIMP_TAC[NORM_ARITH `norm(w) < x * &0 <=> F`]; + ALL_TAC] THEN + ASM_SIMP_TAC[GSYM REAL_LT_LDIV_EQ; COMPLEX_NORM_NZ] THEN + ASM_SIMP_TAC[COMPLEX_POW_EQ_0; COMPLEX_FIELD + `~(z = Cx(&0)) ==> (w = z <=> w / z = Cx(&1))`] THEN + REWRITE_TAC[GSYM COMPLEX_NORM_DIV; GSYM COMPLEX_POW_DIV] THEN + ASM_SIMP_TAC[COMPLEX_FIELD + `~(z = Cx(&0)) ==> (w - z) / z = w / z - Cx(&1)`] THEN + ASM_CASES_TAC `w / z = Cx(&0)` THENL + [ASM_REWRITE_TAC[COMPLEX_SUB_LZERO; NORM_NEG; COMPLEX_NORM_CX] THEN + ASM_SIMP_TAC[COMPLEX_POW_ZERO; LE_1]; + UNDISCH_TAC `~(w / z = Cx(&0))` THEN + UNDISCH_THEN `~(z = Cx(&0))` (K ALL_TAC) THEN + REPEAT(POP_ASSUM MP_TAC) THEN + SPEC_TAC(`w / z:complex`,`z:complex`) THEN REPEAT STRIP_TAC] THEN + EQ_TAC THEN SIMP_TAC[COMPLEX_POW_ONE] THEN DISCH_TAC THEN + UNDISCH_TAC `norm(z - Cx(&1)) < &2 * sin (pi / &n)` THEN + ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN REWRITE_TAC[REAL_NOT_LT] THEN + DISCH_TAC THEN MP_TAC(SPEC `n:num` COMPLEX_ROOTS_UNITY) THEN + ASM_SIMP_TAC[LE_1; EXTENSION; IN_ELIM_THM] THEN + DISCH_THEN(MP_TAC o SPEC `z:complex`) THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `j:num` MP_TAC) THEN + REWRITE_TAC[COMPLEX_RING `t * p * ii * q = ii * (t * p * q)`] THEN + REWRITE_TAC[GSYM CX_MUL] THEN ASM_CASES_TAC `j = 0` THENL + [ASM_REWRITE_TAC[real_div; REAL_MUL_LZERO; REAL_MUL_RZERO; CEXP_0; + COMPLEX_MUL_RZERO]; + STRIP_TAC THEN ASM_REWRITE_TAC[DIST_CEXP_II_1]] THEN + MATCH_MP_TAC(REAL_ARITH `x <= y ==> &2 * x <= &2 * abs y`) THEN + REWRITE_TAC[REAL_ARITH `(&2 * x) / &2 = x`] THEN + ASM_CASES_TAC `&j / &n <= &1 / &2` THENL + [ALL_TAC; + SUBGOAL_THEN `sin(pi * &j / &n) = sin(pi * &(n - j) / &n)` + SUBST1_TAC THENL + [ASM_SIMP_TAC[GSYM REAL_OF_NUM_SUB; LT_IMP_LE; REAL_OF_NUM_LT; + REAL_FIELD `&0 < n ==> pi * (n - j) / n = pi - pi * j / n`] THEN + REWRITE_TAC[SIN_SUB; COS_PI; SIN_PI] THEN REAL_ARITH_TAC; + ALL_TAC]] THEN + MATCH_MP_TAC SIN_MONO_LE THEN + REWRITE_TAC[REAL_ARITH `--(pi / &2) = pi * --(&1 / &2)`; real_div] THEN + SIMP_TAC[REAL_LE_LMUL_EQ; PI_POS] THEN + ASM_SIMP_TAC[GSYM real_div; REAL_LE_RDIV_EQ; REAL_MUL_LINV; REAL_LT_IMP_NZ; + REAL_LE_LDIV_EQ; REAL_OF_NUM_LT; REAL_OF_NUM_LT; LE_1; + ARITH_RULE `j < n ==> 1 <= n - j`; REAL_OF_NUM_LE; + REAL_ARITH `&0 <= x ==> --(&1 / &2) <= x`; + REAL_POS; REAL_LE_INV_EQ] THEN + ASM_SIMP_TAC[GSYM REAL_OF_NUM_SUB; LT_IMP_LE] THEN + REWRITE_TAC[REAL_ARITH `n - j <= inv(&2) * n <=> inv(&2) * n <= j`] THEN + ASM_SIMP_TAC[GSYM REAL_LE_LDIV_EQ; GSYM REAL_LE_RDIV_EQ; + REAL_OF_NUM_LT] THEN + ASM_REAL_ARITH_TAC) in + REPEAT STRIP_TAC THEN + SIMP_TAC[covering_space; CONTINUOUS_ON_COMPLEX_POW; CONTINUOUS_ON_ID] THEN + SIMP_TAC[OPEN_IN_OPEN_EQ; OPEN_DIFF; OPEN_UNIV; CLOSED_SING] THEN + MATCH_MP_TAC(TAUT `p /\ (p ==> q) ==> p /\ q`) THEN CONJ_TAC THENL + [REWRITE_TAC[EXTENSION; IN_IMAGE; IN_DIFF; IN_UNIV; IN_SING] THEN + ASM_MESON_TAC[COMPLEX_POW_EQ_0; EXISTS_COMPLEX_ROOT; LE_1]; + DISCH_THEN(fun th -> GEN_REWRITE_TAC + (BINDER_CONV o LAND_CONV o RAND_CONV) [GSYM th])] THEN + REWRITE_TAC[FORALL_IN_IMAGE; IN_UNIV; IN_DIFF; IN_SING] THEN + SIMP_TAC[SUBSET_UNIV; SET_RULE `s SUBSET UNIV DIFF {a} <=> ~(a IN s)`] THEN + X_GEN_TAC `z:complex` THEN DISCH_TAC THEN + MP_TAC(SPEC `n:num` lemma) THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `e:real` STRIP_ASSUME_TAC) THEN + ABBREV_TAC `d = (min (&1 / &2) (e / &4)) * norm(z:complex)` THEN + SUBGOAL_THEN `&0 < d` ASSUME_TAC THENL + [EXPAND_TAC "d" THEN MATCH_MP_TAC REAL_LT_MUL THEN + ASM_REWRITE_TAC[COMPLEX_NORM_NZ] THEN ASM_REAL_ARITH_TAC; + ALL_TAC] THEN + SUBGOAL_THEN + `!w x y. w pow n = z pow n /\ x IN ball(w,d) /\ y IN ball(w,d) + ==> (x pow n = y pow n <=> x = y)` + ASSUME_TAC THENL + [REWRITE_TAC[IN_BALL] THEN REPEAT STRIP_TAC THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[] THEN + SUBGOAL_THEN `norm(z pow n) = norm(w pow n)` MP_TAC THENL + [ASM_MESON_TAC[]; REWRITE_TAC[COMPLEX_NORM_POW]] THEN + DISCH_THEN(MP_TAC o MATCH_MP (ONCE_REWRITE_RULE[IMP_CONJ_ALT] + (REWRITE_RULE[CONJ_ASSOC] REAL_POW_EQ))) THEN + ASM_SIMP_TAC[LE_1; NORM_POS_LE] THEN + ASM_CASES_TAC `w = Cx(&0)` THENL + [ASM_MESON_TAC[COMPLEX_NORM_ZERO]; DISCH_THEN SUBST_ALL_TAC] THEN + MATCH_MP_TAC REAL_LTE_TRANS THEN EXISTS_TAC `&2 * d` THEN CONJ_TAC THENL + [MAP_EVERY UNDISCH_TAC + [`dist(w:complex,x) < d`; `dist(w:complex,y) < d`] THEN + CONV_TAC NORM_ARITH; + ALL_TAC] THEN + EXPAND_TAC "d" THEN MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `&2 * e / &4 * norm(w:complex)` THEN CONJ_TAC THENL + [MATCH_MP_TAC REAL_LE_LMUL THEN REWRITE_TAC[REAL_POS] THEN + MATCH_MP_TAC REAL_LE_RMUL THEN REWRITE_TAC[NORM_POS_LE] THEN + REAL_ARITH_TAC; + ALL_TAC] THEN + ASM_SIMP_TAC[REAL_LE_LMUL_EQ; REAL_ARITH + `&2 * e / &4 * x <= e * y <=> e * x <= e * &2 * y`] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (NORM_ARITH + `dist(z,y) < d ==> d <= &1 / &2 * norm(z) + ==> norm(z) <= &2 * norm y`)) THEN + EXPAND_TAC "d" THEN MATCH_MP_TAC REAL_LE_RMUL THEN + REWRITE_TAC[NORM_POS_LE] THEN REAL_ARITH_TAC; + ALL_TAC] THEN + EXISTS_TAC `IMAGE (\w. w pow n) (ball(z,d))` THEN REPEAT CONJ_TAC THENL + [REWRITE_TAC[IN_IMAGE] THEN ASM_MESON_TAC[CENTRE_IN_BALL]; + MATCH_MP_TAC INVARIANCE_OF_DOMAIN THEN + SIMP_TAC[OPEN_BALL; CONTINUOUS_ON_COMPLEX_POW; CONTINUOUS_ON_ID] THEN + ASM_MESON_TAC[]; + REWRITE_TAC[SET_RULE + `~(z IN IMAGE f s) <=> (!x. x IN s ==> ~(f x = z))`] THEN + X_GEN_TAC `w:complex` THEN + ASM_SIMP_TAC[IN_BALL; COMPLEX_POW_EQ_0; LE_1] THEN + ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN + SIMP_TAC[GSYM COMPLEX_VEC_0; DIST_0] THEN DISCH_TAC THEN + EXPAND_TAC "d" THEN + REWRITE_TAC[REAL_ARITH `~(z < e * z) <=> &0 <= z * (&1 - e)`] THEN + MATCH_MP_TAC REAL_LE_MUL THEN CONV_TAC NORM_ARITH; + ALL_TAC] THEN + SUBGOAL_THEN + `!z'. z' pow n = z pow n + ==> IMAGE (\w. w pow n) (ball(z',d)) = + IMAGE (\w. w pow n) (ball(z,d))` + ASSUME_TAC THENL + [REWRITE_TAC[EXTENSION; IN_IMAGE; IN_BALL] THEN + X_GEN_TAC `w:complex` THEN DISCH_TAC THEN + ASM_CASES_TAC `w = Cx(&0)` THENL + [ASM_MESON_TAC[COMPLEX_POW_EQ_0; LE_1]; ALL_TAC] THEN + X_GEN_TAC `x:complex` THEN EQ_TAC THEN + DISCH_THEN(X_CHOOSE_THEN `y:complex` STRIP_ASSUME_TAC) THENL + [EXISTS_TAC `z / w * y:complex`; + EXISTS_TAC `w / z * y:complex`] THEN + ASM_SIMP_TAC[COMPLEX_POW_MUL; COMPLEX_POW_DIV; COMPLEX_DIV_REFL; + COMPLEX_POW_EQ_0; LE_1; COMPLEX_MUL_LID; dist] THEN + ASM_SIMP_TAC[COMPLEX_FIELD + `~(w = Cx(&0)) ==> z - z / w * y = z / w * (w - y)`] THEN + REWRITE_TAC[COMPLEX_NORM_MUL; COMPLEX_NORM_DIV] THEN + (SUBGOAL_THEN `norm(z pow n) = norm(w pow n)` MP_TAC THENL + [ASM_MESON_TAC[]; REWRITE_TAC[COMPLEX_NORM_POW]]) THEN + DISCH_THEN(MP_TAC o MATCH_MP (ONCE_REWRITE_RULE[IMP_CONJ_ALT] + (REWRITE_RULE[CONJ_ASSOC] REAL_POW_EQ))) THEN + ASM_SIMP_TAC[LE_1; NORM_POS_LE; REAL_DIV_REFL; COMPLEX_NORM_ZERO] THEN + ASM_REWRITE_TAC[REAL_MUL_LID; GSYM dist]; + ALL_TAC] THEN + EXISTS_TAC `{ ball(z',d) | z' pow n = z pow n}` THEN + REWRITE_TAC[FORALL_IN_GSPEC] THEN REPEAT CONJ_TAC THENL + [REWRITE_TAC[UNIONS_GSPEC; EXTENSION; IN_ELIM_THM] THEN + X_GEN_TAC `x:complex` THEN EQ_TAC THENL + [DISCH_THEN(X_CHOOSE_THEN `w:complex` STRIP_ASSUME_TAC) THEN + CONJ_TAC THENL + [DISCH_TAC THEN UNDISCH_TAC `x IN ball(w:complex,d)` THEN + ASM_REWRITE_TAC[IN_BALL; GSYM COMPLEX_VEC_0; DIST_0] THEN + SUBGOAL_THEN `norm(w pow n) = norm(z pow n)` MP_TAC THENL + [ASM_MESON_TAC[]; REWRITE_TAC[COMPLEX_NORM_POW]] THEN + DISCH_THEN(MP_TAC o MATCH_MP (ONCE_REWRITE_RULE[IMP_CONJ_ALT] + (REWRITE_RULE[CONJ_ASSOC] REAL_POW_EQ))) THEN + ASM_SIMP_TAC[LE_1; NORM_POS_LE; REAL_NOT_LT] THEN DISCH_TAC THEN + EXPAND_TAC "d" THEN REWRITE_TAC[REAL_ARITH + `e * z <= z <=> &0 <= z * (&1 - e)`] THEN + MATCH_MP_TAC REAL_LE_MUL THEN CONV_TAC NORM_ARITH; + SUBGOAL_THEN `IMAGE (\w. w pow n) (ball(z,d)) = + IMAGE (\w. w pow n) (ball(w,d))` + SUBST1_TAC THENL [ASM_MESON_TAC[]; ASM SET_TAC[]]]; + STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_IMAGE]) THEN + REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN X_GEN_TAC `y:complex` THEN + REWRITE_TAC[IN_BALL] THEN STRIP_TAC THEN + ASM_CASES_TAC `y = Cx(&0)` THENL + [ASM_MESON_TAC[COMPLEX_POW_EQ_0; LE_1]; ALL_TAC] THEN + EXISTS_TAC `x / y * z:complex` THEN + REWRITE_TAC[COMPLEX_NORM_MUL; COMPLEX_NORM_DIV] THEN + ASM_SIMP_TAC[COMPLEX_POW_MUL; COMPLEX_POW_DIV; COMPLEX_DIV_REFL; + COMPLEX_POW_EQ_0; LE_1; COMPLEX_MUL_LID; dist] THEN + ASM_SIMP_TAC[COMPLEX_FIELD + `~(y = Cx(&0)) ==> x / y * z - x = x / y * (z - y)`] THEN + REWRITE_TAC[COMPLEX_NORM_MUL; COMPLEX_NORM_DIV] THEN + SUBGOAL_THEN `norm(y pow n) = norm(x pow n)` MP_TAC THENL + [ASM_MESON_TAC[]; REWRITE_TAC[COMPLEX_NORM_POW]] THEN + REWRITE_TAC[COMPLEX_POW_MUL; COMPLEX_POW_DIV] THEN + DISCH_THEN(MP_TAC o MATCH_MP (ONCE_REWRITE_RULE[IMP_CONJ_ALT] + (REWRITE_RULE[CONJ_ASSOC] REAL_POW_EQ))) THEN + ASM_SIMP_TAC[LE_1; NORM_POS_LE; REAL_DIV_REFL; COMPLEX_NORM_ZERO] THEN + ASM_REWRITE_TAC[REAL_MUL_LID; GSYM dist]]; + X_GEN_TAC `w:complex` THEN DISCH_TAC THEN + REWRITE_TAC[OPEN_BALL; IN_BALL; REAL_NOT_LT; dist; COMPLEX_SUB_RZERO] THEN + SUBGOAL_THEN `norm(w pow n) = norm(z pow n)` MP_TAC THENL + [ASM_MESON_TAC[]; REWRITE_TAC[COMPLEX_NORM_POW]] THEN + DISCH_THEN(MP_TAC o MATCH_MP (ONCE_REWRITE_RULE[IMP_CONJ_ALT] + (REWRITE_RULE[CONJ_ASSOC] REAL_POW_EQ))) THEN + ASM_SIMP_TAC[LE_1; NORM_POS_LE] THEN DISCH_THEN SUBST1_TAC THEN + EXPAND_TAC "d" THEN + REWRITE_TAC[REAL_ARITH `e * z <= z <=> &0 <= z * (&1 - e)`] THEN + MATCH_MP_TAC REAL_LE_MUL THEN CONV_TAC NORM_ARITH; + REWRITE_TAC[pairwise; IMP_CONJ; FORALL_IN_GSPEC; RIGHT_FORALL_IMP_THM] THEN + X_GEN_TAC `u:complex` THEN DISCH_TAC THEN + X_GEN_TAC `v:complex` THEN DISCH_TAC THEN + ASM_CASES_TAC `v:complex = u` THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(K ALL_TAC) THEN + REWRITE_TAC[SET_RULE `DISJOINT s t <=> !x. x IN s /\ x IN t ==> F`] THEN + X_GEN_TAC `x:complex` THEN REWRITE_TAC[IN_BALL] THEN + DISCH_THEN(MP_TAC o MATCH_MP (NORM_ARITH + `dist(u,x) < d /\ dist(v,x) < d ==> dist(u,v) < &2 * d`)) THEN + REWRITE_TAC[REAL_NOT_LT] THEN MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `e * norm(z:complex)` THEN CONJ_TAC THENL + [EXPAND_TAC "d" THEN REWRITE_TAC[REAL_MUL_ASSOC] THEN + MATCH_MP_TAC REAL_LE_RMUL THEN + REWRITE_TAC[NORM_POS_LE] THEN ASM_REAL_ARITH_TAC; + ONCE_REWRITE_TAC[GSYM REAL_NOT_LT] THEN REWRITE_TAC[dist]] THEN + SUBGOAL_THEN `norm(z pow n) = norm(v pow n)` MP_TAC THENL + [ASM_MESON_TAC[]; REWRITE_TAC[COMPLEX_NORM_POW]] THEN + DISCH_THEN(MP_TAC o MATCH_MP (ONCE_REWRITE_RULE[IMP_CONJ_ALT] + (REWRITE_RULE[CONJ_ASSOC] REAL_POW_EQ))) THEN + ASM_SIMP_TAC[LE_1; NORM_POS_LE] THEN ASM_MESON_TAC[]; + X_GEN_TAC `w:complex` THEN DISCH_TAC THEN + SUBGOAL_THEN `IMAGE (\w. w pow n) (ball(z,d)) = + IMAGE (\w. w pow n) (ball(w,d))` + SUBST1_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN + MATCH_MP_TAC INVARIANCE_OF_DOMAIN_HOMEOMORPHISM THEN + SIMP_TAC[LE_REFL; OPEN_BALL; CONTINUOUS_ON_COMPLEX_POW; + CONTINUOUS_ON_ID] THEN + ASM_MESON_TAC[]]);; + +let COVERING_SPACE_SQUARE_PUNCTURED_PLANE = prove + (`covering_space ((:complex) DIFF {Cx(&0)},(\z. z pow 2)) + ((:complex) DIFF {Cx (&0)})`, + SIMP_TAC[COVERING_SPACE_POW_PUNCTURED_PLANE; ARITH]);; + +let COVERING_SPACE_CEXP_PUNCTURED_PLANE = prove + (`covering_space((:complex),cexp) ((:complex) DIFF {Cx(&0)})`, + SIMP_TAC[covering_space; IN_UNIV; CONTINUOUS_ON_CEXP; IN_DIFF; IN_SING] THEN + CONJ_TAC THENL [SET_TAC[CEXP_CLOG; CEXP_NZ]; ALL_TAC] THEN + SIMP_TAC[OPEN_IN_OPEN_EQ; OPEN_DIFF; OPEN_UNIV; CLOSED_SING] THEN + SIMP_TAC[SUBSET_UNIV; SET_RULE `s SUBSET UNIV DIFF {a} <=> ~(a IN s)`] THEN + X_GEN_TAC `z:complex` THEN DISCH_TAC THEN + EXISTS_TAC `IMAGE cexp (ball(clog z,&1))` THEN + REWRITE_TAC[SET_RULE `~(z IN IMAGE f s) <=> !x. x IN s ==> ~(f x = z)`] THEN + REWRITE_TAC[CEXP_NZ] THEN CONJ_TAC THENL + [REWRITE_TAC[IN_IMAGE] THEN EXISTS_TAC `clog z` THEN + ASM_SIMP_TAC[CEXP_CLOG; CENTRE_IN_BALL; REAL_LT_01]; + ALL_TAC] THEN + SUBGOAL_THEN + `!x y. x IN cball(clog z,&1) /\ y IN cball(clog z,&1) /\ cexp x = cexp y + ==> x = y` + ASSUME_TAC THENL + [REWRITE_TAC[IN_CBALL] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC COMPLEX_EQ_CEXP THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC REAL_LET_TRANS THEN EXISTS_TAC `norm(x - y:complex)` THEN + REWRITE_TAC[GSYM IM_SUB; COMPLEX_NORM_GE_RE_IM] THEN + MATCH_MP_TAC REAL_LET_TRANS THEN EXISTS_TAC `&2` THEN CONJ_TAC THENL + [REPEAT(POP_ASSUM MP_TAC) THEN CONV_TAC NORM_ARITH; + MP_TAC PI_APPROX_32 THEN REAL_ARITH_TAC]; + ALL_TAC] THEN + CONJ_TAC THENL + [MATCH_MP_TAC INVARIANCE_OF_DOMAIN THEN + REWRITE_TAC[OPEN_BALL; CONTINUOUS_ON_CEXP] THEN + ASM_MESON_TAC[SUBSET; BALL_SUBSET_CBALL]; + ALL_TAC] THEN + MP_TAC(ISPECL [`cball(clog z,&1)`; `cexp`; + `IMAGE cexp (cball(clog z,&1))`] HOMEOMORPHISM_COMPACT) THEN + ASM_REWRITE_TAC[COMPACT_CBALL; CONTINUOUS_ON_CEXP] THEN + REWRITE_TAC[homeomorphism; LEFT_IMP_EXISTS_THM; FORALL_IN_IMAGE] THEN + X_GEN_TAC `l:complex->complex` THEN STRIP_TAC THEN + EXISTS_TAC `{ IMAGE (\x. x + Cx (&2 * n * pi) * ii) + (ball(clog z,&1)) + | integer n}` THEN + SIMP_TAC[FORALL_IN_GSPEC; OPEN_BALL; + ONCE_REWRITE_RULE[VECTOR_ADD_SYM] OPEN_TRANSLATION] THEN + REPEAT CONJ_TAC THENL + [REWRITE_TAC[UNIONS_GSPEC; IN_IMAGE; CEXP_EQ] THEN SET_TAC[]; + REWRITE_TAC[pairwise; IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN + REWRITE_TAC[FORALL_IN_GSPEC] THEN + X_GEN_TAC `m:real` THEN DISCH_TAC THEN + X_GEN_TAC `n:real` THEN DISCH_TAC THEN + ASM_CASES_TAC `m:real = n` THEN ASM_REWRITE_TAC[] THEN DISCH_TAC THEN + REWRITE_TAC[IN_BALL; dist; SET_RULE + `DISJOINT (IMAGE f s) (IMAGE g s) <=> + !x y. x IN s /\ y IN s ==> ~(f x = g y)`] THEN + REPEAT GEN_TAC THEN MATCH_MP_TAC(NORM_ARITH + `&2 <= norm(m - n) + ==> norm(c - x) < &1 /\ norm(c - y) < &1 ==> ~(x + m = y + n)`) THEN + REWRITE_TAC[GSYM COMPLEX_SUB_RDISTRIB; COMPLEX_NORM_MUL] THEN + REWRITE_TAC[COMPLEX_NORM_II; GSYM CX_SUB; COMPLEX_NORM_CX] THEN + REWRITE_TAC[GSYM REAL_SUB_LDISTRIB; GSYM REAL_SUB_RDISTRIB] THEN + REWRITE_TAC[REAL_ABS_MUL; REAL_ABS_NUM; REAL_ABS_PI; REAL_MUL_RID] THEN + MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC `&2 * &1 * pi` THEN + CONJ_TAC THENL [MP_TAC PI_APPROX_32 THEN REAL_ARITH_TAC; ALL_TAC] THEN + MATCH_MP_TAC REAL_LE_LMUL THEN + SIMP_TAC[REAL_LE_RMUL_EQ; PI_POS; REAL_POS] THEN + MATCH_MP_TAC REAL_ABS_INTEGER_LEMMA THEN + ASM_SIMP_TAC[REAL_SUB_0; INTEGER_CLOSED]; + X_GEN_TAC `n:real` THEN DISCH_TAC THEN + EXISTS_TAC `(\x. x + Cx(&2 * n * pi) * ii) o (l:complex->complex)` THEN + ASM_REWRITE_TAC[CONTINUOUS_ON_CEXP; o_THM; IMAGE_o; FORALL_IN_IMAGE] THEN + RULE_ASSUM_TAC(REWRITE_RULE[INJECTIVE_ON_ALT]) THEN + ASM_SIMP_TAC[CEXP_ADD; CEXP_INTEGER_2PI; COMPLEX_MUL_RID; + REWRITE_RULE[SUBSET] BALL_SUBSET_CBALL] THEN + REPEAT CONJ_TAC THENL + [MATCH_MP_TAC(SET_RULE + `(!x. e(f x) = e x) ==> IMAGE e (IMAGE f s) = IMAGE e s`) THEN + ASM_SIMP_TAC[CEXP_ADD; CEXP_INTEGER_2PI; COMPLEX_MUL_RID]; + MATCH_MP_TAC(SET_RULE + `(!x. x IN s ==> l(e x) = x) + ==> IMAGE t (IMAGE l (IMAGE e s)) = IMAGE t s`) THEN + ASM_SIMP_TAC[REWRITE_RULE[SUBSET] BALL_SUBSET_CBALL]; + MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN + SIMP_TAC[CONTINUOUS_ON_ADD; CONTINUOUS_ON_ID; + CONTINUOUS_ON_CONST] THEN + ASM_MESON_TAC[BALL_SUBSET_CBALL; IMAGE_SUBSET; + CONTINUOUS_ON_SUBSET]]]);; + +(* ------------------------------------------------------------------------- *) +(* Hence the Borsukian results about mappings into circle. *) +(* ------------------------------------------------------------------------- *) + +let INESSENTIAL_EQ_CONTINUOUS_LOGARITHM = prove + (`!f:real^N->complex s. + (?a. homotopic_with (\h. T) (s,(:complex) DIFF {Cx(&0)}) f (\t. a)) <=> + (?g. g continuous_on s /\ (!x. x IN s ==> f x = cexp(g x)))`, + REPEAT GEN_TAC THEN EQ_TAC THENL + [DISCH_THEN(CHOOSE_THEN + (MP_TAC o CONJ COVERING_SPACE_CEXP_PUNCTURED_PLANE)) THEN + DISCH_THEN(MP_TAC o MATCH_MP COVERING_SPACE_LIFT_INESSENTIAL_FUNCTION) THEN + REWRITE_TAC[SUBSET_UNIV] THEN MESON_TAC[]; + DISCH_THEN(X_CHOOSE_THEN `g:real^N->complex` STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN + `?a. homotopic_with (\h. T) (s,(:complex) DIFF {Cx(&0)}) + (cexp o g) (\x:real^N. a)` + MP_TAC THENL + [MATCH_MP_TAC NULLHOMOTOPIC_THROUGH_CONTRACTIBLE THEN + EXISTS_TAC `(:complex)` THEN ASM_REWRITE_TAC[SUBSET_UNIV] THEN + ASM_SIMP_TAC[STARLIKE_IMP_CONTRACTIBLE; STARLIKE_UNIV] THEN + REWRITE_TAC[CONTINUOUS_ON_CEXP; SUBSET; FORALL_IN_IMAGE] THEN + REWRITE_TAC[IN_UNIV; IN_DIFF; IN_SING; CEXP_NZ]; + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `a:complex` THEN + MATCH_MP_TAC(ONCE_REWRITE_RULE[IMP_CONJ_ALT] HOMOTOPIC_WITH_EQ) THEN + ASM_SIMP_TAC[o_THM]]]);; + +let INESSENTIAL_IMP_CONTINUOUS_LOGARITHM_CIRCLE = prove + (`!f:real^N->complex s. + (?a. homotopic_with (\h. T) (s,sphere(vec 0,&1)) f (\t. a)) + ==> ?g. g continuous_on s /\ !x. x IN s ==> f x = cexp(g x)`, + REPEAT GEN_TAC THEN + SIMP_TAC[sphere; GSYM INESSENTIAL_EQ_CONTINUOUS_LOGARITHM] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `a:complex` THEN + REWRITE_TAC[homotopic_with] THEN MATCH_MP_TAC MONO_EXISTS THEN + REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP + (REWRITE_RULE[IMP_CONJ] SUBSET_TRANS)) THEN + SIMP_TAC[SUBSET; DIST_0; FORALL_IN_GSPEC; IN_UNIV; IN_DIFF; IN_SING] THEN + ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN + SIMP_TAC[COMPLEX_NORM_CX] THEN REAL_ARITH_TAC);; + +let INESSENTIAL_EQ_CONTINUOUS_LOGARITHM_CIRCLE = prove + (`!f:real^N->complex s. + (?a. homotopic_with (\h. T) (s,sphere(vec 0,&1)) f (\t. a)) <=> + (?g. (Cx o g) continuous_on s /\ + !x. x IN s ==> f x = cexp(ii * Cx(g x)))`, + REPEAT GEN_TAC THEN EQ_TAC THENL + [DISCH_TAC THEN FIRST_ASSUM(MP_TAC o + MATCH_MP INESSENTIAL_IMP_CONTINUOUS_LOGARITHM_CIRCLE) THEN + DISCH_THEN(X_CHOOSE_THEN `g:real^N->complex` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `Im o (g:real^N->complex)` THEN CONJ_TAC THENL + [REWRITE_TAC[o_ASSOC] THEN MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN + ASM_REWRITE_TAC[CONTINUOUS_ON_CX_IM]; + FIRST_X_ASSUM(CHOOSE_THEN (MP_TAC o CONJUNCT1 o + MATCH_MP HOMOTOPIC_WITH_IMP_SUBSET)) THEN + ASM_SIMP_TAC[SUBSET; FORALL_IN_IMAGE; IN_SPHERE_0; NORM_CEXP] THEN + REWRITE_TAC[EULER; o_THM; RE_MUL_II; IM_MUL_II] THEN + SIMP_TAC[RE_CX; IM_CX; REAL_NEG_0; REAL_EXP_0]]; + DISCH_THEN(X_CHOOSE_THEN `g:real^N->real` STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN + `?a. homotopic_with (\h. T) (s,sphere(vec 0,&1)) + ((cexp o (\z. ii * z)) o (Cx o g)) (\x:real^N. a)` + MP_TAC THENL + [MATCH_MP_TAC NULLHOMOTOPIC_THROUGH_CONTRACTIBLE THEN + EXISTS_TAC `{z | Im z = &0}` THEN ASM_REWRITE_TAC[] THEN + ASM_SIMP_TAC[CONTINUOUS_ON_COMPOSE; CONTINUOUS_ON_CEXP; CONJ_ASSOC; + CONTINUOUS_ON_COMPLEX_LMUL; CONTINUOUS_ON_ID] THEN + CONJ_TAC THENL + [REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; IN_ELIM_THM; IN_SPHERE_0; + o_THM; IM_CX] THEN + SIMP_TAC[NORM_CEXP; RE_MUL_II; REAL_EXP_0; REAL_NEG_0]; + MATCH_MP_TAC STARLIKE_IMP_CONTRACTIBLE THEN + MATCH_MP_TAC CONVEX_IMP_STARLIKE THEN CONJ_TAC THENL + [REWRITE_TAC[IM_DEF; CONVEX_STANDARD_HYPERPLANE]; + REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; IN_ELIM_THM] THEN + MESON_TAC[IM_CX]]]; + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `a:complex` THEN + MATCH_MP_TAC(ONCE_REWRITE_RULE[IMP_CONJ_ALT] HOMOTOPIC_WITH_EQ) THEN + ASM_SIMP_TAC[o_THM]]]);; + +let HOMOTOPIC_CIRCLEMAPS_DIV,HOMOTOPIC_CIRCLEMAPS_DIV_1 = (CONJ_PAIR o prove) + (`(!f g:real^N->real^2 s. + homotopic_with (\x. T) (s,sphere(vec 0,&1)) f g <=> + f continuous_on s /\ IMAGE f s SUBSET sphere(vec 0,&1) /\ + g continuous_on s /\ IMAGE g s SUBSET sphere(vec 0,&1) /\ + ?c. homotopic_with (\x. T) (s,sphere(vec 0,&1)) (\x. f x / g x) (\x. c)) /\ + (!f g:real^N->real^2 s. + homotopic_with (\x. T) (s,sphere(vec 0,&1)) f g <=> + f continuous_on s /\ IMAGE f s SUBSET sphere(vec 0,&1) /\ + g continuous_on s /\ IMAGE g s SUBSET sphere(vec 0,&1) /\ + homotopic_with (\x. T) (s,sphere(vec 0,&1)) (\x. f x / g x) (\x. Cx(&1)))`, + let lemma = prove + (`!f g h:real^N->real^2 s. + homotopic_with (\x. T) (s,sphere(vec 0,&1)) f g + ==> h continuous_on s /\ (!x. x IN s ==> h(x) IN sphere(vec 0,&1)) + ==> homotopic_with (\x. T) (s,sphere(vec 0,&1)) + (\x. f x * h x) (\x. g x * h x)`, + REWRITE_TAC[IN_SPHERE_0] THEN REPEAT STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [homotopic_with]) THEN + ASM_SIMP_TAC[HOMOTOPIC_WITH; LEFT_IMP_EXISTS_THM] THEN + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; IN_SPHERE_0; FORALL_IN_PCROSS] THEN + X_GEN_TAC `k:real^((1,N)finite_sum)->real^2` THEN STRIP_TAC THEN + EXISTS_TAC `\z. (k:real^(1,N)finite_sum->real^2) z * h(sndcart z)` THEN + ASM_SIMP_TAC[COMPLEX_NORM_MUL; SNDCART_PASTECART; REAL_MUL_LID] THEN + ASM_REWRITE_TAC[SNDCART_PASTECART] THEN + MATCH_MP_TAC CONTINUOUS_ON_COMPLEX_MUL THEN + ASM_REWRITE_TAC[GSYM o_DEF] THEN MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN + SIMP_TAC[LINEAR_CONTINUOUS_ON; LINEAR_SNDCART; IMAGE_SNDCART_PCROSS] THEN + ASM_REWRITE_TAC[UNIT_INTERVAL_NONEMPTY]) in + REWRITE_TAC[AND_FORALL_THM] THEN REPEAT GEN_TAC THEN MATCH_MP_TAC + (TAUT `(q <=> r) /\ (p <=> r) ==> (p <=> q) /\ (p <=> r)`) THEN + CONJ_TAC THENL + [REPEAT(MATCH_MP_TAC(TAUT `(p ==> (q <=> r)) ==> (p /\ q <=> p /\ r)`) THEN + DISCH_TAC) THEN + EQ_TAC THENL + [ALL_TAC; DISCH_TAC THEN EXISTS_TAC `Cx(&1)` THEN ASM_MESON_TAC[]] THEN + REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN X_GEN_TAC `c:complex` THEN + DISCH_THEN(fun th -> ASSUME_TAC(MATCH_MP HOMOTOPIC_WITH_IMP_SUBSET th) THEN + MP_TAC th) THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] HOMOTOPIC_WITH_TRANS) THEN + REWRITE_TAC[HOMOTOPIC_CONSTANT_MAPS] THEN + ASM_CASES_TAC `s:real^N->bool = {}` THEN ASM_REWRITE_TAC[] THEN + MP_TAC(ISPECL [`vec 0:real^2`; `&1`] PATH_CONNECTED_SPHERE) THEN + REWRITE_TAC[DIMINDEX_2; LE_REFL; PATH_CONNECTED_IFF_PATH_COMPONENT] THEN + DISCH_THEN MATCH_MP_TAC THEN CONJ_TAC THENL + [ASM SET_TAC[]; REWRITE_TAC[IN_SPHERE_0; COMPLEX_NORM_CX; REAL_ABS_NUM]]; + EQ_TAC THEN STRIP_TAC THEN FIRST_ASSUM(MP_TAC o MATCH_MP lemma) THENL + [FIRST_ASSUM(STRIP_ASSUME_TAC o + MATCH_MP HOMOTOPIC_WITH_IMP_CONTINUOUS) THEN + FIRST_ASSUM(STRIP_ASSUME_TAC o MATCH_MP HOMOTOPIC_WITH_IMP_SUBSET) THEN + DISCH_THEN(MP_TAC o SPEC `\x. inv((g:real^N->complex) x)`); + DISCH_THEN(MP_TAC o SPEC `g:real^N->complex`)] THEN + RULE_ASSUM_TAC(REWRITE_RULE[SUBSET; FORALL_IN_IMAGE; IN_SPHERE_0]) THEN + ASM_SIMP_TAC[IN_SPHERE_0; COMPLEX_NORM_INV; REAL_INV_1] THEN + ASM_SIMP_TAC[GSYM COMPLEX_NORM_ZERO; REAL_OF_NUM_EQ; ARITH_EQ; + CONTINUOUS_ON_COMPLEX_INV] THEN + ASM_REWRITE_TAC[SUBSET; IN_SPHERE_0; FORALL_IN_IMAGE] THEN + MATCH_MP_TAC(ONCE_REWRITE_RULE[IMP_CONJ_ALT] + HOMOTOPIC_WITH_EQ) THEN + ASM_SIMP_TAC[COMPLEX_DIV_RMUL; COMPLEX_MUL_LID; COMPLEX_MUL_RINV; + GSYM complex_div; COMPLEX_DIV_REFL; + GSYM COMPLEX_NORM_ZERO; REAL_OF_NUM_EQ; ARITH_EQ]]);; + +(* ------------------------------------------------------------------------- *) +(* In particular, complex logs exist on various "well-behaved" sets. *) +(* ------------------------------------------------------------------------- *) + +let CONTINUOUS_LOGARITHM_ON_CONTRACTIBLE = prove + (`!f:real^N->complex s. + f continuous_on s /\ contractible s /\ + (!x. x IN s ==> ~(f x = Cx(&0))) + ==> ?g. g continuous_on s /\ !x. x IN s ==> f x = cexp(g x)`, + REPEAT STRIP_TAC THEN + REWRITE_TAC[GSYM INESSENTIAL_EQ_CONTINUOUS_LOGARITHM] THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC NULLHOMOTOPIC_FROM_CONTRACTIBLE THEN + ASM_REWRITE_TAC[] THEN ASM SET_TAC[]);; + +let CONTINUOUS_LOGARITHM_ON_SIMPLY_CONNECTED = prove + (`!f:real^N->complex s. + f continuous_on s /\ simply_connected s /\ locally path_connected s /\ + (!x. x IN s ==> ~(f x = Cx(&0))) + ==> ?g. g continuous_on s /\ !x. x IN s ==> f x = cexp(g x)`, + REPEAT STRIP_TAC THEN MP_TAC + (ISPECL [`f:real^N->complex`; `s:real^N->bool`] + (MATCH_MP (ONCE_REWRITE_RULE[IMP_CONJ] COVERING_SPACE_LIFT) + COVERING_SPACE_CEXP_PUNCTURED_PLANE)) THEN + ASM_REWRITE_TAC[IN_UNIV] THEN ASM SET_TAC[]);; + +let CONTINUOUS_LOGARITHM_ON_CBALL = prove + (`!f:real^N->complex a r. + f continuous_on cball(a,r) /\ + (!z. z IN cball(a,r) ==> ~(f z = Cx(&0))) + ==> ?h. h continuous_on cball(a,r) /\ + !z. z IN cball(a,r) ==> f z = cexp(h z)`, + REPEAT STRIP_TAC THEN + ASM_CASES_TAC `cball(a:real^N,r) = {}` THEN + ASM_REWRITE_TAC[CONTINUOUS_ON_EMPTY; NOT_IN_EMPTY] THEN + MATCH_MP_TAC CONTINUOUS_LOGARITHM_ON_CONTRACTIBLE THEN + ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC STARLIKE_IMP_CONTRACTIBLE THEN + MATCH_MP_TAC CONVEX_IMP_STARLIKE THEN + ASM_REWRITE_TAC[CONVEX_CBALL]);; + +let CONTINUOUS_LOGARITHM_ON_BALL = prove + (`!f:real^N->complex a r. + f continuous_on ball(a,r) /\ + (!x. x IN ball(a,r) ==> ~(f x = Cx(&0))) + ==> ?h. h continuous_on ball(a,r) /\ + !x. x IN ball(a,r) ==> f x = cexp(h x)`, + REPEAT STRIP_TAC THEN + ASM_CASES_TAC `ball(a:real^N,r) = {}` THEN + ASM_REWRITE_TAC[CONTINUOUS_ON_EMPTY; NOT_IN_EMPTY] THEN + MATCH_MP_TAC CONTINUOUS_LOGARITHM_ON_CONTRACTIBLE THEN + ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC STARLIKE_IMP_CONTRACTIBLE THEN + MATCH_MP_TAC CONVEX_IMP_STARLIKE THEN + ASM_REWRITE_TAC[CONVEX_BALL]);; + +let CONTINUOUS_SQRT_ON_CONTRACTIBLE = prove + (`!f:real^N->complex s. + f continuous_on s /\ contractible s /\ + (!x. x IN s ==> ~(f x = Cx(&0))) + ==> ?g. g continuous_on s /\ !x. x IN s ==> f x = (g x) pow 2`, + REPEAT GEN_TAC THEN DISCH_TAC THEN + FIRST_ASSUM(MP_TAC o MATCH_MP CONTINUOUS_LOGARITHM_ON_CONTRACTIBLE) THEN + DISCH_THEN(X_CHOOSE_THEN `g:real^N->complex` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `\z:real^N. cexp(g z / Cx(&2))` THEN + ASM_SIMP_TAC[GSYM CEXP_N; COMPLEX_RING `Cx(&2) * z / Cx(&2) = z`] THEN + GEN_REWRITE_TAC LAND_CONV [GSYM o_DEF] THEN + MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN + REWRITE_TAC[CONTINUOUS_ON_CEXP] THEN + MATCH_MP_TAC CONTINUOUS_ON_COMPLEX_DIV THEN + ASM_SIMP_TAC[CONTINUOUS_ON_CONST] THEN + CONV_TAC COMPLEX_RING);; + +let CONTINUOUS_SQRT_ON_SIMPLY_CONNECTED = prove + (`!f:real^N->complex s. + f continuous_on s /\ simply_connected s /\ locally path_connected s /\ + (!x. x IN s ==> ~(f x = Cx(&0))) + ==> ?g. g continuous_on s /\ !x. x IN s ==> f x = (g x) pow 2`, + REPEAT GEN_TAC THEN DISCH_TAC THEN + FIRST_ASSUM(MP_TAC o MATCH_MP CONTINUOUS_LOGARITHM_ON_SIMPLY_CONNECTED) THEN + DISCH_THEN(X_CHOOSE_THEN `g:real^N->complex` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `\z:real^N. cexp(g z / Cx(&2))` THEN + ASM_SIMP_TAC[GSYM CEXP_N; COMPLEX_RING `Cx(&2) * z / Cx(&2) = z`] THEN + GEN_REWRITE_TAC LAND_CONV [GSYM o_DEF] THEN + MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN + REWRITE_TAC[CONTINUOUS_ON_CEXP] THEN + MATCH_MP_TAC CONTINUOUS_ON_COMPLEX_DIV THEN + ASM_SIMP_TAC[CONTINUOUS_ON_CONST] THEN + CONV_TAC COMPLEX_RING);; + +(* ------------------------------------------------------------------------- *) +(* Analogously, holomorphic logarithms and square roots. *) +(* ------------------------------------------------------------------------- *) + +let CONTRACTIBLE_IMP_HOLOMORPHIC_LOG,SIMPLY_CONNECTED_IMP_HOLOMORPHIC_LOG = + (CONJ_PAIR o prove) + (`(!s:complex->bool. + contractible s + ==> !f. f holomorphic_on s /\ (!z. z IN s ==> ~(f z = Cx(&0))) + ==> ?g. g holomorphic_on s /\ !z. z IN s ==> f z = cexp(g z)) /\ + (!s:complex->bool. + simply_connected s /\ locally path_connected s + ==> !f. f holomorphic_on s /\ (!z. z IN s ==> ~(f z = Cx(&0))) + ==> ?g. g holomorphic_on s /\ !z. z IN s ==> f z = cexp(g z))`, + REPEAT STRIP_TAC THENL + [MP_TAC(ISPECL [`f:complex->complex`; `s:complex->bool`] + CONTINUOUS_LOGARITHM_ON_CONTRACTIBLE); + MP_TAC(ISPECL [`f:complex->complex`; `s:complex->bool`] + CONTINUOUS_LOGARITHM_ON_SIMPLY_CONNECTED)] THEN + ASM_SIMP_TAC[HOLOMORPHIC_ON_IMP_CONTINUOUS_ON] THEN + (MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `g:complex->complex` THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + UNDISCH_TAC `f holomorphic_on s` THEN + REWRITE_TAC[holomorphic_on] THEN MATCH_MP_TAC MONO_FORALL THEN + X_GEN_TAC `z:complex` THEN ASM_CASES_TAC `(z:complex) IN s` THEN + ASM_REWRITE_TAC[HAS_COMPLEX_DERIVATIVE_WITHIN] THEN + DISCH_THEN(X_CHOOSE_THEN `f':complex` MP_TAC) THEN + DISCH_THEN(MP_TAC o + ISPECL [`\x. (cexp(g x) - cexp(g z)) / (x - z)`; `&1`] o + MATCH_MP (REWRITE_RULE [TAUT `p /\ q /\ r ==> s <=> r ==> p /\ q ==> s`] + LIM_TRANSFORM_WITHIN)) THEN + ASM_SIMP_TAC[REAL_LT_01] THEN + DISCH_THEN(MP_TAC o + SPECL [`\x:complex. if g x = g z then cexp(g z) + else (cexp(g x) - cexp(g z)) / (g x - g z)`; + `cexp(g(z:complex))`] o + MATCH_MP (REWRITE_RULE[IMP_CONJ] LIM_COMPLEX_DIV)) THEN + REWRITE_TAC[CEXP_NZ] THEN ANTS_TAC THENL + [SUBGOAL_THEN + `(\x. if g x = g z then cexp(g z) + else (cexp(g x) - cexp(g(z:complex))) / (g x - g z)) = + (\y. if y = g z then cexp(g z) else (cexp y - cexp(g z)) / (y - g z)) o g` + SUBST1_TAC THENL [REWRITE_TAC[o_DEF]; ALL_TAC] THEN + MATCH_MP_TAC LIM_COMPOSE_AT THEN + EXISTS_TAC `(g:complex->complex) z` THEN REPEAT CONJ_TAC THENL + [ASM_MESON_TAC[CONTINUOUS_ON]; + REWRITE_TAC[EVENTUALLY_TRUE]; + ONCE_REWRITE_TAC[LIM_AT_ZERO] THEN + SIMP_TAC[COMPLEX_VEC_0; COMPLEX_ADD_SUB; COMPLEX_EQ_ADD_LCANCEL_0] THEN + MP_TAC(SPEC `cexp(g(z:complex))` (MATCH_MP LIM_COMPLEX_LMUL + LIM_CEXP_MINUS_1)) THEN REWRITE_TAC[COMPLEX_MUL_RID] THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] LIM_TRANSFORM_EVENTUALLY) THEN + SIMP_TAC[EVENTUALLY_AT; GSYM DIST_NZ; CEXP_ADD] THEN + EXISTS_TAC `&1` THEN REWRITE_TAC[REAL_LT_01] THEN + SIMPLE_COMPLEX_ARITH_TAC]; + DISCH_THEN(fun th -> + EXISTS_TAC `f' / cexp(g(z:complex))` THEN MP_TAC th) THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] + LIM_TRANSFORM_EVENTUALLY) THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I + [CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN]) THEN + DISCH_THEN(MP_TAC o SPEC `z:complex`) THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[CONTINUOUS_WITHIN; tendsto] THEN + DISCH_THEN(MP_TAC o SPEC `&2 * pi`) THEN + REWRITE_TAC[REAL_ARITH `&0 < &2 * x <=> &0 < x`; PI_POS] THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] EVENTUALLY_MONO) THEN + X_GEN_TAC `w:complex` THEN REWRITE_TAC[dist] THEN DISCH_TAC THEN + COND_CASES_TAC THENL + [ASM_REWRITE_TAC[COMPLEX_SUB_REFL; complex_div; COMPLEX_MUL_LZERO]; + ASM_CASES_TAC `w:complex = z` THENL [ASM_MESON_TAC[]; ALL_TAC] THEN + SUBGOAL_THEN `~(cexp(g(w:complex)) = cexp(g z))` MP_TAC THENL + [UNDISCH_TAC `~((g:complex->complex) w = g z)` THEN + REWRITE_TAC[CONTRAPOS_THM] THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] COMPLEX_EQ_CEXP) THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ_ALT] + REAL_LET_TRANS)) THEN + REWRITE_TAC[GSYM IM_SUB; COMPLEX_NORM_GE_RE_IM]; + REPEAT(FIRST_X_ASSUM(MP_TAC o check(is_neg o concl))) THEN + CONV_TAC COMPLEX_FIELD]]]));; + +let CONTRACTIBLE_IMP_HOLOMORPHIC_SQRT,SIMPLY_CONNECTED_IMP_HOLOMORPHIC_SQRT = + (CONJ_PAIR o prove) + (`(!s:complex->bool. + contractible s + ==> !f. f holomorphic_on s /\ (!z. z IN s ==> ~(f z = Cx(&0))) + ==> ?g. g holomorphic_on s /\ !z. z IN s ==> f z = g z pow 2) /\ + (!s:complex->bool. + simply_connected s /\ locally path_connected s + ==> !f. f holomorphic_on s /\ (!z. z IN s ==> ~(f z = Cx(&0))) + ==> ?g. g holomorphic_on s /\ !z. z IN s ==> f z = g z pow 2)`, + CONJ_TAC THEN GEN_TAC THENL + [DISCH_THEN(ASSUME_TAC o MATCH_MP CONTRACTIBLE_IMP_HOLOMORPHIC_LOG); + DISCH_THEN(ASSUME_TAC o + MATCH_MP SIMPLY_CONNECTED_IMP_HOLOMORPHIC_LOG)] THEN + REPEAT STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `f:complex->complex`) THEN ASM_SIMP_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `g:complex->complex` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `\z:complex. cexp(g z / Cx(&2))` THEN + ASM_SIMP_TAC[GSYM CEXP_N; COMPLEX_RING `Cx(&2) * z / Cx(&2) = z`] THEN + GEN_REWRITE_TAC LAND_CONV [GSYM o_DEF] THEN + MATCH_MP_TAC HOLOMORPHIC_ON_COMPOSE THEN + REWRITE_TAC[HOLOMORPHIC_ON_CEXP] THEN + MATCH_MP_TAC HOLOMORPHIC_ON_DIV THEN + ASM_SIMP_TAC[HOLOMORPHIC_ON_CONST] THEN + CONV_TAC COMPLEX_RING);; + +(* ------------------------------------------------------------------------- *) +(* Related theorems about holomorphic inverse cosines. *) +(* ------------------------------------------------------------------------- *) + +let CONTRACTIBLE_IMP_HOLOMORPHIC_ACS = prove + (`!f s. f holomorphic_on s /\ contractible s /\ + (!z. z IN s ==> ~(f z = Cx(&1)) /\ ~(f z = --Cx(&1))) + ==> ?g. g holomorphic_on s /\ !z. z IN s ==> f z = ccos(g z)`, + REPEAT STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o SPEC `\z:complex. Cx(&1) - f(z) pow 2` o + MATCH_MP CONTRACTIBLE_IMP_HOLOMORPHIC_SQRT) THEN + ASM_SIMP_TAC[HOLOMORPHIC_ON_SUB; HOLOMORPHIC_ON_CONST; HOLOMORPHIC_ON_POW; + COMPLEX_RING `~(Cx(&1) - z pow 2 = Cx(&0)) <=> + ~(z = Cx(&1)) /\ ~(z = --Cx(&1))`] THEN + REWRITE_TAC[COMPLEX_RING + `Cx(&1) - w pow 2 = z pow 2 <=> + (w + ii * z) * (w - ii * z) = Cx(&1)`] THEN + DISCH_THEN(X_CHOOSE_THEN `g:complex->complex` STRIP_ASSUME_TAC) THEN + FIRST_ASSUM(MP_TAC o SPEC `\z:complex. f(z) + ii * g(z)` o + MATCH_MP CONTRACTIBLE_IMP_HOLOMORPHIC_LOG) THEN + ASM_SIMP_TAC[HOLOMORPHIC_ON_ADD; HOLOMORPHIC_ON_MUL; HOLOMORPHIC_ON_CONST; + COMPLEX_RING `(a + b) * (a - b) = Cx(&1) ==> ~(a + b = Cx(&0))`] THEN + DISCH_THEN(X_CHOOSE_THEN `h:complex->complex` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `\z:complex. --ii * h(z)` THEN + ASM_SIMP_TAC[HOLOMORPHIC_ON_MUL; HOLOMORPHIC_ON_CONST; ccos] THEN + X_GEN_TAC `z:complex` THEN + DISCH_TAC THEN REPEAT(FIRST_X_ASSUM(MP_TAC o SPEC `z:complex`)) THEN + ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o MATCH_MP (COMPLEX_FIELD + `a * b = Cx(&1) ==> b = inv a`)) THEN + ASM_SIMP_TAC[GSYM CEXP_NEG] THEN + FIRST_X_ASSUM(ASSUME_TAC o SYM) THEN DISCH_THEN(ASSUME_TAC o SYM) THEN + ASM_REWRITE_TAC[COMPLEX_RING `ii * --ii * z = z`; + COMPLEX_RING `--ii * --ii * z = --z`] THEN + CONV_TAC COMPLEX_RING);; + +let CONTRACTIBLE_IMP_HOLOMORPHIC_ACS_BOUNDED = prove + (`!f s a. + f holomorphic_on s /\ contractible s /\ a IN s /\ + (!z. z IN s ==> ~(f z = Cx(&1)) /\ ~(f z = --Cx(&1))) + ==> ?g. g holomorphic_on s /\ norm(g a) <= pi + norm(f a) /\ + !z. z IN s ==> f z = ccos(g z)`, + let lemma = prove + (`!w. ?v. ccos(v) = w /\ norm(v) <= pi + norm(w)`, + GEN_TAC THEN EXISTS_TAC `cacs w` THEN ABBREV_TAC `v = cacs w` THEN + MATCH_MP_TAC(TAUT `p /\ (p ==> q) ==> p /\ q`) THEN CONJ_TAC THENL + [ASM_MESON_TAC[CCOS_CACS]; DISCH_THEN(SUBST1_TAC o SYM)] THEN + SIMP_TAC[NORM_LE_SQUARE; PI_POS_LE; NORM_POS_LE; REAL_LE_ADD] THEN + MATCH_MP_TAC(REAL_ARITH + `&0 <= b * c /\ a <= b pow 2 + c pow 2 ==> a <= (b + c) pow 2`) THEN + SIMP_TAC[REAL_LE_MUL; PI_POS_LE; NORM_POS_LE] THEN + REWRITE_TAC[COMPLEX_SQNORM; GSYM NORM_POW_2; NORM_CCOS_POW_2] THEN + MATCH_MP_TAC REAL_LE_ADD2 THEN REWRITE_TAC[GSYM REAL_LE_SQUARE_ABS] THEN + EXPAND_TAC "v" THEN REWRITE_TAC[REAL_ABS_PI; RE_CACS_BOUND] THEN + MATCH_MP_TAC(REAL_ARITH + `&0 <= c /\ x <= (d / &2) pow 2 ==> x <= c + d pow 2 / &4`) THEN + REWRITE_TAC[REAL_LE_POW_2; GSYM REAL_LE_SQUARE_ABS; REAL_LE_ABS_SINH]) in + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`f:complex->complex`; `s:complex->bool`] + CONTRACTIBLE_IMP_HOLOMORPHIC_ACS) THEN + ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `g:complex->complex` STRIP_ASSUME_TAC) THEN + MP_TAC(SPEC `(f:complex->complex) a` lemma) THEN + DISCH_THEN(X_CHOOSE_THEN `b:complex` STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN `ccos b = ccos(g(a:complex))` MP_TAC THENL + [ASM_MESON_TAC[]; REWRITE_TAC[CCOS_EQ]] THEN + DISCH_THEN(X_CHOOSE_THEN `n:real` (STRIP_ASSUME_TAC o GSYM)) THENL + [EXISTS_TAC `\z:complex. g z + Cx(&2 * n * pi)`; + EXISTS_TAC `\z:complex. --(g z) + Cx(&2 * n * pi)`] THEN + ASM_SIMP_TAC[HOLOMORPHIC_ON_ADD; HOLOMORPHIC_ON_NEG; + HOLOMORPHIC_ON_CONST] THEN + CONV_TAC(ONCE_DEPTH_CONV SYM_CONV) THEN REWRITE_TAC[CCOS_EQ] THEN + ASM_MESON_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* Another interesting equivalent of an inessential mapping into C-{0} *) +(* ------------------------------------------------------------------------- *) + +let INESSENTIAL_EQ_EXTENSIBLE = prove + (`!f s. + closed s + ==> ((?a. homotopic_with (\h. T) (s,(:complex) DIFF {Cx(&0)}) f (\t. a)) <=> + (?g. g continuous_on (:real^N) /\ + (!x. x IN s ==> g x = f x) /\ (!x. ~(g x = Cx(&0)))))`, + REPEAT GEN_TAC THEN DISCH_TAC THEN EQ_TAC THENL + [DISCH_THEN(X_CHOOSE_TAC `a:complex`) THEN + ASM_CASES_TAC `s:real^N->bool = {}` THENL + [EXISTS_TAC `\x:real^N. Cx(&1)` THEN + ASM_REWRITE_TAC[CONTINUOUS_ON_CONST; NOT_IN_EMPTY] THEN + CONV_TAC COMPLEX_RING; + ALL_TAC] THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP HOMOTOPIC_WITH_IMP_CONTINUOUS) THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP HOMOTOPIC_WITH_IMP_SUBSET) THEN + FIRST_ASSUM(MP_TAC o + SPECL [`(:real^N)`; `(:complex) DIFF {Cx(&0)}`] o + MATCH_MP(ONCE_REWRITE_RULE[IMP_CONJ_ALT] + (REWRITE_RULE[CONJ_ASSOC] BORSUK_HOMOTOPY_EXTENSION)) o + GEN_REWRITE_RULE I [HOMOTOPIC_WITH_SYM]) THEN + ASM_SIMP_TAC[CLOSED_UNIV; CONTINUOUS_ON_CONST; OPEN_DIFF; CLOSED_SING; + OPEN_UNIV; RETRACT_OF_REFL] THEN + ANTS_TAC THENL [ASM SET_TAC[]; MATCH_MP_TAC MONO_EXISTS] THEN + ASM SET_TAC[]; + DISCH_THEN(X_CHOOSE_THEN `g:real^N->complex` STRIP_ASSUME_TAC) THEN + REWRITE_TAC[INESSENTIAL_EQ_CONTINUOUS_LOGARITHM] THEN + MP_TAC(ISPECL [`vec 0:real^N`; `&1`] HOMEOMORPHIC_BALL_UNIV) THEN + REWRITE_TAC[REAL_LT_01; homeomorphic; LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`h:real^N->real^N`; `k:real^N->real^N`] THEN + REWRITE_TAC[homeomorphism; IN_UNIV] THEN STRIP_TAC THEN + MP_TAC(ISPECL [`(g:real^N->complex) o (h:real^N->real^N)`; + `vec 0:real^N`; `&1`] CONTINUOUS_LOGARITHM_ON_BALL) THEN + ASM_SIMP_TAC[CONTINUOUS_ON_COMPOSE; o_THM] THEN + DISCH_THEN(X_CHOOSE_THEN `j:real^N->complex` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `(j:real^N->complex) o (k:real^N->real^N)` THEN + ASM_SIMP_TAC[o_THM] THEN CONJ_TAC THENL [ALL_TAC; ASM SET_TAC[]] THEN + MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN CONJ_TAC THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET)) THEN ASM SET_TAC[]]);; + +(* ------------------------------------------------------------------------- *) +(* Unicoherence. *) +(* ------------------------------------------------------------------------- *) + +let INESSENTIAL_IMP_UNICOHERENT = prove + (`!u:real^N->bool. + (!f. f continuous_on u /\ IMAGE f u SUBSET sphere(vec 0,&1) + ==> ?a. homotopic_with (\h. T) + (u,(:complex) DIFF {Cx (&0)}) f (\t. a)) + ==> !s t. connected s /\ connected t /\ s UNION t = u /\ + closed_in (subtopology euclidean u) s /\ + closed_in (subtopology euclidean u) t + ==> connected (s INTER t)`, + REWRITE_TAC[sphere; DIST_0; INESSENTIAL_EQ_CONTINUOUS_LOGARITHM] THEN + REPEAT STRIP_TAC THEN SIMP_TAC[CONNECTED_CLOSED_IN_EQ; NOT_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`v:real^N->bool`; `w:real^N->bool`] THEN STRIP_TAC THEN + SUBGOAL_THEN + `closed_in (subtopology euclidean u) (v:real^N->bool) /\ + closed_in (subtopology euclidean u) (w:real^N->bool)` + STRIP_ASSUME_TAC THENL + [ASM_MESON_TAC[CLOSED_IN_INTER; CLOSED_IN_TRANS]; ALL_TAC] THEN + MP_TAC(ISPECL + [`v:real^N->bool`; `w:real^N->bool`; `u:real^N->bool`; + `vec 0:real^1`; `vec 1:real^1`] URYSOHN_LOCAL) THEN + ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `q:real^N->real^1` STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN + `?g:real^N->real^2. + g continuous_on u /\ IMAGE g u SUBSET {x | norm x = &1} /\ + (!x. x IN s ==> g(x) = cexp(Cx pi * ii * Cx(drop(q x)))) /\ + (!x. x IN t ==> g(x) = inv(cexp(Cx pi * ii * Cx(drop(q x)))))` + (DESTRUCT_TAC "@g. cont circle s t") THENL + [EXISTS_TAC + `\x. if (x:real^N) IN s then cexp(Cx pi * ii * Cx(drop(q x))) + else inv(cexp(Cx pi * ii * Cx(drop(q x))))` THEN + SUBGOAL_THEN + `!x:real^N. + x IN s INTER t + ==> cexp(Cx pi * ii * Cx(drop(q x))) = + inv(cexp(Cx pi * ii * Cx(drop (q x))))` + ASSUME_TAC THENL + [SUBST1_TAC(SYM(ASSUME `v UNION w:real^N->bool = s INTER t`)) THEN + REWRITE_TAC[IN_UNION] THEN REPEAT STRIP_TAC THEN ASM_SIMP_TAC[] THEN + REWRITE_TAC[DROP_VEC; COMPLEX_MUL_RZERO; CEXP_0; COMPLEX_INV_1] THEN + REWRITE_TAC[COMPLEX_MUL_RID; EULER] THEN + REWRITE_TAC[RE_MUL_CX; IM_MUL_CX; RE_MUL_II; IM_MUL_II] THEN + REWRITE_TAC[RE_II; IM_II; REAL_MUL_RZERO; REAL_MUL_RID] THEN + REWRITE_TAC[REAL_EXP_0; COMPLEX_MUL_LID; COS_PI; SIN_PI] THEN + REWRITE_TAC[COMPLEX_MUL_RZERO; COMPLEX_ADD_RID] THEN + CONV_TAC COMPLEX_RING; + ALL_TAC] THEN + SIMP_TAC[] THEN REPEAT CONJ_TAC THENL + [EXPAND_TAC "u" THEN MATCH_MP_TAC CONTINUOUS_ON_CASES_LOCAL THEN + ASM_REWRITE_TAC[SET_RULE + `P /\ ~P \/ x IN t /\ x IN s <=> x IN s INTER t`] THEN + CONJ_TAC THENL + [ALL_TAC; + MATCH_MP_TAC CONTINUOUS_ON_COMPLEX_INV THEN REWRITE_TAC[CEXP_NZ]] THEN + GEN_REWRITE_TAC LAND_CONV [GSYM o_DEF] THEN + MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN + REWRITE_TAC[CONTINUOUS_ON_CEXP] THEN + REWRITE_TAC[COMPLEX_MUL_ASSOC] THEN + MATCH_MP_TAC CONTINUOUS_ON_COMPLEX_MUL THEN + REWRITE_TAC[CONTINUOUS_ON_CONST] THEN + MATCH_MP_TAC CONTINUOUS_ON_CX_DROP THEN + ASM_MESON_TAC[CONTINUOUS_ON_SUBSET; SUBSET_UNION]; + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; IN_ELIM_THM] THEN + REPEAT STRIP_TAC THEN COND_CASES_TAC THEN + REWRITE_TAC[COMPLEX_NORM_INV; NORM_CEXP] THEN + REWRITE_TAC[RE_MUL_CX; RE_MUL_II; IM_CX] THEN + REWRITE_TAC[REAL_MUL_RZERO; REAL_NEG_0; REAL_EXP_0; REAL_INV_1]; + GEN_TAC THEN DISCH_TAC THEN COND_CASES_TAC THEN + ASM_REWRITE_TAC[] THEN ASM SET_TAC[]]; + FIRST_X_ASSUM(MP_TAC o SPEC `g:real^N->complex`) THEN + ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `h:real^N->complex` STRIP_ASSUME_TAC)] THEN + SUBGOAL_THEN + `(?n. integer n /\ + !x:real^N. x IN s + ==> h(x) - Cx pi * ii * Cx (drop (q x)) = + Cx(&2 * n * pi) * ii) /\ + (?n. integer n /\ + !x:real^N. x IN t + ==> h(x) + Cx pi * ii * Cx (drop (q x)) = + Cx(&2 * n * pi) * ii)` + (CONJUNCTS_THEN2 + (X_CHOOSE_THEN `m:real` (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) + (X_CHOOSE_THEN `n:real` (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC))) + THENL + [CONJ_TAC THEN MATCH_MP_TAC(MESON[] + `(?x. x IN s) /\ + (!x. x IN s ==> ?n. P n /\ f x = k n) /\ + (?a. !x. x IN s ==> f x = a) + ==> (?n. P n /\ !x. x IN s ==> f x = k n)`) THEN + (CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC]) THEN + MATCH_MP_TAC(TAUT `p /\ (p ==> q) ==> p /\ q`) THEN + (CONJ_TAC THENL + [REWRITE_TAC[COMPLEX_RING `a + b:complex = c <=> a = --b + c`; + COMPLEX_RING `a - b:complex = c <=> a = b + c`] THEN + REWRITE_TAC[GSYM CEXP_EQ; CEXP_NEG] THEN ASM SET_TAC[]; + ALL_TAC] THEN + DISCH_THEN(LABEL_TAC "*") THEN + MATCH_MP_TAC CONTINUOUS_DISCRETE_RANGE_CONSTANT THEN + ASM_REWRITE_TAC[] THEN CONJ_TAC THENL + [(MATCH_MP_TAC CONTINUOUS_ON_ADD ORELSE + MATCH_MP_TAC CONTINUOUS_ON_SUB) THEN + CONJ_TAC THENL + [ASM_MESON_TAC[CONTINUOUS_ON_SUBSET; SUBSET_UNION]; ALL_TAC] THEN + REWRITE_TAC[COMPLEX_MUL_ASSOC] THEN + MATCH_MP_TAC CONTINUOUS_ON_COMPLEX_MUL THEN + REWRITE_TAC[CONTINUOUS_ON_CONST] THEN + MATCH_MP_TAC CONTINUOUS_ON_CX_DROP THEN + ASM_MESON_TAC[CONTINUOUS_ON_SUBSET; SUBSET_UNION]; + X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN EXISTS_TAC `&2 * pi` THEN + REWRITE_TAC[REAL_ARITH `&0 < &2 * x <=> &0 < x`; PI_POS] THEN + X_GEN_TAC `y:real^N` THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + REMOVE_THEN "*" (fun th -> + MP_TAC(SPEC `y:real^N` th) THEN MP_TAC(SPEC `x:real^N` th)) THEN + ASM_REWRITE_TAC[] THEN STRIP_TAC THEN STRIP_TAC THEN + ASM_REWRITE_TAC[] THEN + REWRITE_TAC[COMPLEX_EQ_MUL_RCANCEL; II_NZ; GSYM COMPLEX_SUB_RDISTRIB; + COMPLEX_NORM_MUL; CX_INJ; COMPLEX_NORM_II; REAL_MUL_RID] THEN + REWRITE_TAC[GSYM CX_SUB; COMPLEX_NORM_CX] THEN + REWRITE_TAC[REAL_EQ_MUL_LCANCEL; GSYM REAL_SUB_LDISTRIB] THEN + REWRITE_TAC[GSYM REAL_SUB_RDISTRIB; REAL_ABS_MUL] THEN + REWRITE_TAC[REAL_EQ_MUL_RCANCEL; PI_NZ; REAL_ABS_PI] THEN + REWRITE_TAC[REAL_ABS_NUM; REAL_OF_NUM_EQ; ARITH_EQ] THEN + DISCH_TAC THEN REWRITE_TAC[REAL_ARITH + `&2 * p <= &2 * a * p <=> &0 <= &2 * p * (a - &1)`] THEN + MATCH_MP_TAC REAL_LE_MUL THEN REWRITE_TAC[REAL_POS] THEN + MATCH_MP_TAC REAL_LE_MUL THEN REWRITE_TAC[PI_POS_LE; REAL_SUB_LE] THEN + MATCH_MP_TAC REAL_ABS_INTEGER_LEMMA THEN + ASM_SIMP_TAC[INTEGER_CLOSED; REAL_SUB_0]]); + ALL_TAC] THEN + GEN_REWRITE_TAC I [TAUT `p ==> q ==> F <=> ~(p /\ q)`] THEN + DISCH_THEN(MP_TAC o MATCH_MP (SET_RULE + `(!x. x IN s ==> P x) /\ (!x. x IN t ==> Q x) + ==> ~(v = {}) /\ ~(w = {}) /\ v UNION w SUBSET s INTER t + ==> ~(!y z. y IN v /\ z IN w ==> ~(P y /\ Q y /\ P z /\ Q z))`)) THEN + ANTS_TAC THENL [ASM SET_TAC[]; ASM_SIMP_TAC[]] THEN + REPEAT GEN_TAC THEN STRIP_TAC THEN DISCH_THEN(MP_TAC o MATCH_MP (COMPLEX_RING + `y + p = n /\ y - p = m /\ z + q = n /\ z - q = m ==> q:complex = p`)) THEN + REWRITE_TAC[DROP_VEC; COMPLEX_MUL_RZERO; COMPLEX_ENTIRE; CX_INJ] THEN + REWRITE_TAC[PI_NZ; II_NZ; REAL_OF_NUM_EQ; ARITH_EQ]);; + +let CONTRACTIBLE_IMP_UNICOHERENT = prove + (`!u:real^N->bool. + contractible u + ==> !s t. connected s /\ connected t /\ s UNION t = u /\ + closed_in (subtopology euclidean u) s /\ + closed_in (subtopology euclidean u) t + ==> connected (s INTER t)`, + GEN_TAC THEN DISCH_TAC THEN MATCH_MP_TAC INESSENTIAL_IMP_UNICOHERENT THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC NULLHOMOTOPIC_FROM_CONTRACTIBLE THEN + ASM_REWRITE_TAC[] THEN FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP + (REWRITE_RULE[IMP_CONJ] SUBSET_TRANS)) THEN + REWRITE_TAC[SUBSET; IN_SPHERE_0; IN_DIFF; IN_UNIV; IN_SING] THEN + ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN + SIMP_TAC[COMPLEX_NORM_0] THEN REAL_ARITH_TAC);; + +let CONVEX_IMP_UNICOHERENT = prove + (`!u:real^N->bool. + convex u + ==> !s t. connected s /\ connected t /\ s UNION t = u /\ + closed_in (subtopology euclidean u) s /\ + closed_in (subtopology euclidean u) t + ==> connected (s INTER t)`, + GEN_TAC THEN DISCH_TAC THEN + ASM_CASES_TAC `u:real^N->bool = {}` THEN + ASM_SIMP_TAC[EMPTY_UNION; INTER_EMPTY; CONNECTED_EMPTY] THEN + MATCH_MP_TAC CONTRACTIBLE_IMP_UNICOHERENT THEN + ASM_SIMP_TAC[CONVEX_IMP_STARLIKE; STARLIKE_IMP_CONTRACTIBLE]);; + +let UNICOHERENT_UNIV = prove + (`!s t. closed s /\ closed t /\ connected s /\ connected t /\ + s UNION t = (:real^N) + ==> connected(s INTER t)`, + MP_TAC(ISPEC `(:real^N)` CONVEX_IMP_UNICOHERENT) THEN + REWRITE_TAC[CONVEX_UNIV; SUBTOPOLOGY_UNIV; GSYM CLOSED_IN] THEN + REWRITE_TAC[CONJ_ACI]);; + +(* ------------------------------------------------------------------------- *) +(* Another simple case where sphere maps are nullhomotopic. *) +(* ------------------------------------------------------------------------- *) + +let INESSENTIAL_SPHEREMAP_2 = prove + (`!f:real^M->real^N a r b s. + 2 < dimindex(:M) /\ dimindex(:N) = 2 /\ + f continuous_on sphere(a,r) /\ + IMAGE f (sphere(a,r)) SUBSET (sphere(b,s)) + ==> ?c. homotopic_with (\z. T) (sphere(a,r),sphere(b,s)) f (\x. c)`, + let lemma = prove + (`!f:real^N->real^2 a r. + 2 < dimindex(:N) /\ + f continuous_on sphere(a,r) /\ + IMAGE f (sphere(a,r)) SUBSET (sphere(vec 0,&1)) + ==> ?c. homotopic_with (\z. T) (sphere(a,r),sphere(vec 0,&1)) + f (\x. c)`, + REPEAT STRIP_TAC THEN + REWRITE_TAC[INESSENTIAL_EQ_CONTINUOUS_LOGARITHM_CIRCLE] THEN + MP_TAC(ISPECL [`f:real^N->real^2`; `sphere(a:real^N,r)`] + CONTINUOUS_LOGARITHM_ON_SIMPLY_CONNECTED) THEN + ASM_SIMP_TAC[SIMPLY_CONNECTED_SPHERE_EQ; LOCALLY_PATH_CONNECTED_SPHERE] THEN + ANTS_TAC THENL + [ASM_REWRITE_TAC[ARITH_RULE `3 <= n <=> 2 < n`] THEN FIRST_X_ASSUM + (MATCH_MP_TAC o MATCH_MP (SET_RULE + `IMAGE f s SUBSET t ==> (!x. P x ==> ~(x IN t)) + ==> !x. x IN s ==> ~P(f x)`)) THEN + SIMP_TAC[COMPLEX_NORM_0; IN_SPHERE_0] THEN REAL_ARITH_TAC; + DISCH_THEN(X_CHOOSE_THEN `g:real^N->real^2` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `Im o (g:real^N->real^2)` THEN CONJ_TAC THENL + [REWRITE_TAC[o_ASSOC] THEN MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN + ASM_REWRITE_TAC[CONTINUOUS_ON_CX_IM]; + X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN + ASM_SIMP_TAC[] THEN AP_TERM_TAC THEN + REWRITE_TAC[o_DEF; COMPLEX_EQ; RE_MUL_II; IM_MUL_II; RE_CX; IM_CX] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [SUBSET]) THEN + REWRITE_TAC[FORALL_IN_IMAGE] THEN + DISCH_THEN(MP_TAC o SPEC `x:real^N`) THEN + ASM_SIMP_TAC[IN_SPHERE_0; NORM_CEXP; REAL_EXP_EQ_1] THEN + REAL_ARITH_TAC]]) + and hslemma = prove + (`!a:real^M r b:real^N s. + dimindex(:M) = dimindex(:N) /\ &0 < r /\ &0 < s + ==> (sphere(a,r) homeomorphic sphere(b,s))`, + REPEAT STRIP_TAC THEN FIRST_ASSUM(fun th -> + let t = `?a:real^M b:real^N. ~(sphere(a,r) homeomorphic sphere(b,s))` in + MP_TAC(DISCH t (GEOM_EQUAL_DIMENSION_RULE th (ASSUME t)))) THEN + ASM_SIMP_TAC[HOMEOMORPHIC_SPHERES] THEN MESON_TAC[]) in + REPEAT STRIP_TAC THEN ASM_CASES_TAC `s <= &0` THEN + ASM_SIMP_TAC[NULLHOMOTOPIC_INTO_CONTRACTIBLE; CONTRACTIBLE_SPHERE] THEN + RULE_ASSUM_TAC(REWRITE_RULE[REAL_NOT_LE]) THEN + SUBGOAL_THEN + `(sphere(b:real^N,s)) homeomorphic (sphere(vec 0:real^2,&1))` + MP_TAC THENL + [ASM_SIMP_TAC[hslemma; REAL_LT_01; DIMINDEX_2]; + REWRITE_TAC[homeomorphic; LEFT_IMP_EXISTS_THM]] THEN + MAP_EVERY X_GEN_TAC [`h:real^N->real^2`; `k:real^2->real^N`] THEN + REWRITE_TAC[homeomorphism] THEN STRIP_TAC THEN + MP_TAC(ISPECL + [`(h:real^N->real^2) o (f:real^M->real^N)`; + `a:real^M`; `r:real`] lemma) THEN + ASM_REWRITE_TAC[IMAGE_o] THEN ANTS_TAC THENL + [CONJ_TAC THENL [MATCH_MP_TAC CONTINUOUS_ON_COMPOSE; ASM SET_TAC[]] THEN + ASM_MESON_TAC[CONTINUOUS_ON_SUBSET]; + DISCH_THEN(X_CHOOSE_THEN `c:real^2` (fun th -> + EXISTS_TAC `(k:real^2->real^N) c` THEN MP_TAC th)) THEN + DISCH_THEN(MP_TAC o ISPEC `k:real^2->real^N` o MATCH_MP + (ONCE_REWRITE_RULE[IMP_CONJ] HOMOTOPIC_COMPOSE_CONTINUOUS_LEFT)) THEN + DISCH_THEN(MP_TAC o SPEC `sphere(b:real^N,s)`) THEN + ASM_REWRITE_TAC[SUBSET_REFL] THEN + MATCH_MP_TAC(ONCE_REWRITE_RULE[IMP_CONJ_ALT] HOMOTOPIC_WITH_EQ) THEN + REWRITE_TAC[o_DEF] THEN ASM SET_TAC[]]);; + +(* ------------------------------------------------------------------------- *) +(* Janiszewski's theorem. *) +(* ------------------------------------------------------------------------- *) + +let JANISZEWSKI = prove + (`!s t a b:real^2. + compact s /\ closed t /\ connected(s INTER t) /\ + connected_component ((:real^2) DIFF s) a b /\ + connected_component ((:real^2) DIFF t) a b + ==> connected_component ((:real^2) DIFF (s UNION t)) a b`, + let lemma = prove + (`!s t a b:real^2. + compact s /\ compact t /\ connected(s INTER t) /\ + connected_component ((:real^2) DIFF s) a b /\ + connected_component ((:real^2) DIFF t) a b + ==> connected_component ((:real^2) DIFF (s UNION t)) a b`, + REPEAT GEN_TAC THEN + REPLICATE_TAC 3 (DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + DISCH_THEN(fun th -> ASSUME_TAC th THEN MP_TAC th) THEN + FIRST_X_ASSUM(CONJUNCTS_THEN(MP_TAC o MATCH_MP CONNECTED_COMPONENT_IN)) THEN + REWRITE_TAC[IN_DIFF; IN_UNIV] THEN STRIP_TAC THEN STRIP_TAC THEN + ASM_SIMP_TAC[GSYM BORSUK_MAPS_HOMOTOPIC_IN_CONNECTED_COMPONENT_EQ; + DIMINDEX_2; LE_REFL; COMPACT_UNION; IN_UNION] THEN + ONCE_REWRITE_TAC[HOMOTOPIC_CIRCLEMAPS_DIV] THEN + REWRITE_TAC[INESSENTIAL_EQ_CONTINUOUS_LOGARITHM_CIRCLE] THEN + ASM_SIMP_TAC[BORSUK_MAP_INTO_SPHERE; CONTINUOUS_ON_BORSUK_MAP; + IN_UNION] THEN + DISCH_THEN(CONJUNCTS_THEN2 + (X_CHOOSE_THEN `g:real^2->real` STRIP_ASSUME_TAC) + (X_CHOOSE_THEN `h:real^2->real` STRIP_ASSUME_TAC)) THEN + SUBGOAL_THEN + `closed_in (subtopology euclidean (s UNION t)) s /\ + closed_in (subtopology euclidean (s UNION t)) (t:real^2->bool)` + STRIP_ASSUME_TAC THENL + [REWRITE_TAC[CLOSED_IN_CLOSED] THEN CONJ_TAC THENL + [EXISTS_TAC `s:real^2->bool`; EXISTS_TAC `t:real^2->bool`] THEN + ASM_SIMP_TAC[COMPACT_IMP_CLOSED] THEN ASM SET_TAC[]; + ALL_TAC] THEN + ASM_CASES_TAC `s INTER t:real^2->bool = {}` THENL + [EXISTS_TAC `(\x. if x IN s then g x else h x):real^2->real` THEN + CONJ_TAC THENL [ALL_TAC; ASM_MESON_TAC[]] THEN + REWRITE_TAC[o_DEF; COND_RAND] THEN + MATCH_MP_TAC CONTINUOUS_ON_CASES_LOCAL THEN + ASM_REWRITE_TAC[GSYM o_DEF] THEN ASM SET_TAC[]; + ALL_TAC] THEN + MP_TAC(ISPECL + [`\x:real^2. lift(g x) - lift(h x)`; `s INTER t:real^2->bool`] + CONTINUOUS_DISCRETE_RANGE_CONSTANT) THEN + ASM_REWRITE_TAC[] THEN ANTS_TAC THENL + [CONJ_TAC THENL + [MATCH_MP_TAC CONTINUOUS_ON_SUB THEN + REWRITE_TAC[GSYM CONTINUOUS_ON_CX_LIFT] THEN + REWRITE_TAC[GSYM o_DEF] THEN + ASM_MESON_TAC[CONTINUOUS_ON_SUBSET; INTER_SUBSET]; + REWRITE_TAC[o_DEF]] THEN + X_GEN_TAC `x:real^2` THEN REWRITE_TAC[IN_INTER] THEN STRIP_TAC THEN + EXISTS_TAC `&2 * pi` THEN + REWRITE_TAC[REAL_ARITH `&0 < &2 * x <=> &0 < x`; PI_POS] THEN + X_GEN_TAC `y:real^2` THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN REWRITE_TAC[REAL_NOT_LE] THEN + REWRITE_TAC[GSYM LIFT_SUB; LIFT_EQ; NORM_LIFT] THEN DISCH_TAC THEN + ONCE_REWRITE_TAC[REAL_RING `a - b:real = c - d <=> a - c = b - d`] THEN + REWRITE_TAC[GSYM CX_INJ] THEN + MATCH_MP_TAC(COMPLEX_RING `ii * w = ii * z ==> w = z`) THEN + MATCH_MP_TAC COMPLEX_EQ_CEXP THEN CONJ_TAC THENL + [REWRITE_TAC[IM_MUL_II; RE_CX] THEN ASM_REAL_ARITH_TAC; + REWRITE_TAC[CX_SUB; COMPLEX_SUB_LDISTRIB; CEXP_SUB] THEN + ASM_MESON_TAC[]]; + REWRITE_TAC[EXISTS_LIFT; GSYM LIFT_SUB; LIFT_EQ; IN_INTER] THEN + REWRITE_TAC[REAL_EQ_SUB_RADD; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `z:real` THEN DISCH_TAC THEN + EXISTS_TAC `(\x. if x IN s then g x else z + h x):real^2->real` THEN + CONJ_TAC THENL + [REWRITE_TAC[o_DEF; COND_RAND] THEN + MATCH_MP_TAC CONTINUOUS_ON_CASES_LOCAL THEN + ASM_SIMP_TAC[TAUT `~(p /\ ~p)`; CX_ADD; GSYM o_DEF] THEN + REWRITE_TAC[o_DEF; CX_ADD] THEN MATCH_MP_TAC CONTINUOUS_ON_ADD THEN + ASM_REWRITE_TAC[CONTINUOUS_ON_CONST; GSYM o_DEF]; + X_GEN_TAC `x:real^2` THEN REWRITE_TAC[] THEN + COND_CASES_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN + ASM_SIMP_TAC[] THEN DISCH_TAC THEN + SUBGOAL_THEN + `?w:real^2. cexp(ii * Cx(h w)) = cexp (ii * Cx(z + h w))` + (CHOOSE_THEN MP_TAC) THENL [ASM SET_TAC[]; ALL_TAC] THEN + REWRITE_TAC[CX_ADD; COMPLEX_ADD_LDISTRIB; CEXP_ADD] THEN + REWRITE_TAC[COMPLEX_FIELD `a = b * a <=> a = Cx(&0) \/ b = Cx(&1)`; + CEXP_NZ]]]) in + REPEAT STRIP_TAC THEN + SUBGOAL_THEN + `?c:real^2->bool. + compact c /\ connected c /\ a IN c /\ b IN c /\ c INTER t = {}` + STRIP_ASSUME_TAC THENL + [SUBGOAL_THEN `path_component((:real^2) DIFF t) a b` MP_TAC THENL + [ASM_MESON_TAC[OPEN_PATH_CONNECTED_COMPONENT; closed; COMPACT_IMP_CLOSED]; + REWRITE_TAC[path_component; SET_RULE + `s SUBSET UNIV DIFF t <=> s INTER t = {}`]] THEN + DISCH_THEN(X_CHOOSE_THEN `g:real^1->real^2` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `path_image(g:real^1->real^2)` THEN + ASM_SIMP_TAC[CONNECTED_PATH_IMAGE; COMPACT_PATH_IMAGE] THEN + ASM_MESON_TAC[PATHSTART_IN_PATH_IMAGE; PATHFINISH_IN_PATH_IMAGE]; + ALL_TAC] THEN + MP_TAC(ISPECL [`c UNION s:real^2->bool`; `vec 0:real^2`] + BOUNDED_SUBSET_BALL) THEN + ASM_SIMP_TAC[BOUNDED_UNION; COMPACT_IMP_BOUNDED; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `r:real` THEN STRIP_TAC THEN + MP_TAC(ISPECL [`s:real^2->bool`; + `(t INTER cball(vec 0,r)) UNION sphere(vec 0:real^2,r)`; + `a:real^2`; `b:real^2`] lemma) THEN + ASM_SIMP_TAC[COMPACT_UNION; CLOSED_INTER_COMPACT; + COMPACT_SPHERE; COMPACT_CBALL] THEN + ANTS_TAC THENL + [CONJ_TAC THENL + [UNDISCH_TAC `connected(s INTER t:real^2->bool)` THEN + MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC; + REWRITE_TAC[connected_component] THEN EXISTS_TAC `c:real^2->bool`] THEN + MP_TAC(ISPECL [`vec 0:real^2`; `r:real`] CBALL_DIFF_SPHERE) THEN + ASM SET_TAC[]; + REWRITE_TAC[connected_component] THEN MATCH_MP_TAC MONO_EXISTS THEN + X_GEN_TAC `u:real^2->bool` THEN + SIMP_TAC[SET_RULE `s SUBSET UNIV DIFF t <=> s INTER t = {}`] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + DISCH_THEN(CONJUNCTS_THEN2 MP_TAC STRIP_ASSUME_TAC) THEN + MP_TAC(ISPECL + [`u:real^2->bool`; `cball(vec 0:real^2,r)`] CONNECTED_INTER_FRONTIER) THEN + ASM_REWRITE_TAC[FRONTIER_CBALL] THEN + MP_TAC(ISPECL [`vec 0:real^2`; `r:real`] BALL_SUBSET_CBALL) THEN + ASM SET_TAC[]]);; + +let JANISZEWSKI_GEN = prove + (`!s t a b:real^N. + dimindex(:N) <= 2 /\ + compact s /\ closed t /\ connected(s INTER t) /\ + connected_component ((:real^N) DIFF s) a b /\ + connected_component ((:real^N) DIFF t) a b + ==> connected_component ((:real^N) DIFF (s UNION t)) a b`, + REPEAT GEN_TAC THEN ASM_CASES_TAC `dimindex(:N) = 1` THENL + [ASM_SIMP_TAC[CONNECTED_COMPONENT_1_GEN] THEN SET_TAC[]; + ASM_SIMP_TAC[ARITH_RULE `1 <= n /\ ~(n = 1) ==> (n <= 2 <=> n = 2)`; + DIMINDEX_GE_1] THEN + ONCE_REWRITE_TAC[IMP_CONJ] THEN REWRITE_TAC[GSYM DIMINDEX_2] THEN + DISCH_THEN(fun th -> + MATCH_ACCEPT_TAC(GEOM_EQUAL_DIMENSION_RULE th JANISZEWSKI))]);; diff --git a/Multivariate/tarski.ml b/Multivariate/tarski.ml new file mode 100644 index 0000000..8e9d031 --- /dev/null +++ b/Multivariate/tarski.ml @@ -0,0 +1,261 @@ +(* ========================================================================= *) +(* Proof that Tarski's axioms for geometry hold in Euclidean space. *) +(* ========================================================================= *) + +needs "Multivariate/convex.ml";; + +(* ------------------------------------------------------------------------- *) +(* Axiom 1 (reflexivity for equidistance). *) +(* ------------------------------------------------------------------------- *) + +let TARSKI_AXIOM_1_EUCLIDEAN = prove + (`!a b:real^2. dist(a,b) = dist(b,a)`, + NORM_ARITH_TAC);; + +(* ------------------------------------------------------------------------- *) +(* Axiom 2 (transitivity for equidistance). *) +(* ------------------------------------------------------------------------- *) + +let TARSKI_AXIOM_2_EUCLIDEAN = prove + (`!a b p q r s. + dist(a,b) = dist(p,q) /\ dist(a,b) = dist(r,s) + ==> dist(p,q) = dist(r,s)`, + REAL_ARITH_TAC);; + +(* ------------------------------------------------------------------------- *) +(* Axiom 3 (identity for equidistance). *) +(* ------------------------------------------------------------------------- *) + +let TARSKI_AXIOM_3_EUCLIDEAN = prove + (`!a b c. dist(a,b) = dist(c,c) ==> a = b`, + NORM_ARITH_TAC);; + +(* ------------------------------------------------------------------------- *) +(* Axiom 4 (segment construction). *) +(* ------------------------------------------------------------------------- *) + +let TARSKI_AXIOM_4_EUCLIDEAN = prove + (`!a q b c:real^2. ?x:real^2. between a (q,x) /\ dist(a,x) = dist(b,c)`, + GEOM_ORIGIN_TAC `a:real^2` THEN REPEAT GEN_TAC THEN + REWRITE_TAC[DIST_0] THEN ASM_CASES_TAC `q:real^2 = vec 0` THENL + [ASM_SIMP_TAC[BETWEEN_REFL; VECTOR_CHOOSE_SIZE; DIST_POS_LE]; + EXISTS_TAC `--(dist(b:real^2,c) / norm(q) % q):real^2` THEN + REWRITE_TAC[between; DIST_0] THEN + REWRITE_TAC[dist; NORM_MUL; NORM_NEG; REAL_ABS_DIV; REAL_ABS_NORM; + VECTOR_ARITH `q - --(a % q) = (&1 + a) % q`] THEN + CONJ_TAC THENL + [MATCH_MP_TAC(REAL_RING `a = &1 + b ==> a * q = q + b * q`) THEN + SIMP_TAC[REAL_ABS_REFL; REAL_POS; REAL_LE_ADD; REAL_LE_DIV; NORM_POS_LE]; + ASM_SIMP_TAC[REAL_DIV_RMUL; NORM_EQ_0]]]);; + +(* ------------------------------------------------------------------------- *) +(* Axiom 5 (five-segments axiom). *) +(* ------------------------------------------------------------------------- *) + +let TARSKI_AXIOM_5_EUCLIDEAN = prove + (`!a b c x:real^2 a' b' c' x':real^2. + ~(a = b) /\ + dist(a,b) = dist(a',b') /\ + dist(a,c) = dist(a',c') /\ + dist(b,c) = dist(b',c') /\ + between b (a,x) /\ between b' (a',x') /\ dist(b,x) = dist(b',x') + ==> dist(c,x) = dist(c',x')`, + let lemma = prove + (`!a b x y:real^N. + ~(b = a) /\ between b (a,x) /\ between b (a,y) /\ dist(b,x) = dist(b,y) + ==> x = y`, + REPEAT STRIP_TAC THEN REPEAT(FIRST_X_ASSUM(MP_TAC o MATCH_MP (REWRITE_RULE + [IMP_CONJ] BETWEEN_EXISTS_EXTENSION))) THEN ASM_SIMP_TAC[] THEN + REPEAT STRIP_TAC THEN UNDISCH_TAC `dist(b:real^N,x) = dist(b,y)` THEN + ASM_REWRITE_TAC[NORM_ARITH `dist(b:real^N,b + x) = norm x`; NORM_MUL] THEN + ASM_SIMP_TAC[REAL_EQ_MUL_RCANCEL; NORM_EQ_0; real_abs; VECTOR_SUB_EQ]) in + REPEAT STRIP_TAC THEN MP_TAC(ISPECL + [`a:real^2`; `b:real^2`; `c:real^2`; `a':real^2`; `b':real^2`; `c':real^2`] + RIGID_TRANSFORMATION_BETWEEN_3) THEN + ANTS_TAC THENL [ASM_MESON_TAC[DIST_EQ_0; DIST_SYM]; ALL_TAC] THEN + DISCH_THEN(X_CHOOSE_THEN `k:real^2` + (X_CHOOSE_THEN `f:real^2->real^2` (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC))) THEN + DISCH_THEN(REPEAT_TCL CONJUNCTS_THEN SUBST_ALL_TAC) THEN + SUBGOAL_THEN `x' = k + (f:real^2->real^2) x` SUBST1_TAC THENL + [MATCH_MP_TAC lemma THEN MAP_EVERY EXISTS_TAC + [`k + (f:real^2->real^2) a`; `k + (f:real^2->real^2) b`]; + ALL_TAC] THEN + ASM_REWRITE_TAC[NORM_ARITH `dist(a + x:real^N,a + y) = dist(x,y)`; + BETWEEN_TRANSLATION; VECTOR_ARITH `a + x:real^N = a + y <=> x = y`] THEN + ASM_MESON_TAC[BETWEEN_TRANSLATION; orthogonal_transformation; + NORM_ARITH `dist(a + x:real^N,a + y) = dist(x,y)`; + ORTHOGONAL_TRANSFORMATION_ISOMETRY; BETWEEN_LINEAR_IMAGE_EQ; + DIST_EQ_0; ORTHOGONAL_TRANSFORMATION_INJECTIVE]);; + +(* ------------------------------------------------------------------------- *) +(* Axiom 6 (identity for between-ness). *) +(* ------------------------------------------------------------------------- *) + +let TARSKI_AXIOM_6_EUCLIDEAN = prove + (`!a b. between b (a,a) ==> a = b`, + SIMP_TAC[BETWEEN_REFL_EQ]);; + +(* ------------------------------------------------------------------------- *) +(* Axiom 7 (Pasch's axiom). *) +(* ------------------------------------------------------------------------- *) + +let TARSKI_AXIOM_7_EUCLIDEAN = prove + (`!a b c p q:real^2. + between p (a,c) /\ between q (b,c) + ==> ?x. between x (p,b) /\ between x (q,a)`, + REPEAT GEN_TAC THEN ASM_CASES_TAC `q:real^2 = c` THENL + [ASM_MESON_TAC[BETWEEN_REFL; BETWEEN_SYM]; POP_ASSUM MP_TAC] THEN + ASM_CASES_TAC `p:real^2 = a /\ b:real^2 = q` THENL + [ASM_MESON_TAC[BETWEEN_REFL; BETWEEN_SYM]; POP_ASSUM MP_TAC] THEN + GEOM_ORIGIN_TAC `a:real^2` THEN GEOM_NORMALIZE_TAC `q:real^2` THEN + CONJ_TAC THENL + [ONCE_REWRITE_TAC[CONJ_SYM] THEN REWRITE_TAC[BETWEEN_REFL_EQ] THEN + REWRITE_TAC[UNWIND_THM2; between; DIST_0] THEN NORM_ARITH_TAC; + ALL_TAC] THEN + GEOM_BASIS_MULTIPLE_TAC 1 `q:real^2` THEN SIMP_TAC + [NORM_MUL; NORM_BASIS; real_abs; DIMINDEX_2; ARITH; REAL_MUL_RID] THEN + GEN_TAC THEN REPEAT(DISCH_THEN(K ALL_TAC)) THEN SIMP_TAC[VECTOR_MUL_LID] THEN + REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[BETWEEN_SYM] THEN DISCH_TAC THEN + DISCH_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 + (X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC o + REWRITE_RULE[BETWEEN_IN_SEGMENT; IN_SEGMENT]) + (MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] BETWEEN_EXISTS_EXTENSION))) THEN + ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN X_GEN_TAC `e:real` THEN + STRIP_TAC THEN ASM_REWRITE_TAC[BETWEEN_IN_SEGMENT; IN_SEGMENT] THEN + REWRITE_TAC[VECTOR_MUL_RZERO; VECTOR_ADD_LID] THEN + SUBGOAL_THEN `&0 < &1 - d + e` ASSUME_TAC THENL + [ASM_CASES_TAC `d = &1 /\ e = &0` THENL [ALL_TAC; ASM_REAL_ARITH_TAC] THEN + REPEAT(FIRST_X_ASSUM(MP_TAC o check (is_eq o concl))) THEN + ASM_REWRITE_TAC[REAL_SUB_REFL; VECTOR_MUL_LZERO; VECTOR_MUL_RZERO] THEN + ASM_REWRITE_TAC[VECTOR_ADD_RID; IMP_IMP]; + EXISTS_TAC `(&1 - d + e - d * e) / (&1 - d + e) % basis 1:real^2` THEN + CONJ_TAC THENL + [EXISTS_TAC `e / (&1 - d + e)` THEN + ASM_SIMP_TAC[REAL_LE_LDIV_EQ; REAL_LE_RDIV_EQ] THEN + REPEAT(CONJ_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC]) THEN + SIMP_TAC[CART_EQ; DIMINDEX_2; FORALL_2; BASIS_COMPONENT; VEC_COMPONENT; + ARITH; VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT; + VECTOR_SUB_COMPONENT] THEN + UNDISCH_TAC `&0 < &1 - d + e` THEN CONV_TAC REAL_FIELD; + EXISTS_TAC `(&1 - d + e - d * e) / (&1 - d + e)` THEN + ASM_SIMP_TAC[REAL_LE_LDIV_EQ; REAL_LE_RDIV_EQ] THEN + SUBGOAL_THEN `&0 <= (&1 - d) * (&1 + e) /\ &0 <= d * e` MP_TAC THENL + [CONJ_TAC THEN MATCH_MP_TAC REAL_LE_MUL; ALL_TAC] THEN + ASM_REAL_ARITH_TAC]]);; + +(* ------------------------------------------------------------------------- *) +(* Axiom 8 (lower 2-dimensional axiom). *) +(* ------------------------------------------------------------------------- *) + +let TARSKI_AXIOM_8_EUCLIDEAN = prove + (`?a b c:real^2. ~between b (a,c) /\ ~between c (b,a) /\ ~between a (c,b)`, + REWRITE_TAC[GSYM DE_MORGAN_THM] THEN ONCE_REWRITE_TAC[BETWEEN_SYM] THEN + REWRITE_TAC[GSYM COLLINEAR_BETWEEN_CASES; COLLINEAR_3_2D] THEN + MAP_EVERY EXISTS_TAC + [`vec 0:real^2`; `basis 1:real^2`; `basis 2:real^2`] THEN + SIMP_TAC[BASIS_COMPONENT; VEC_COMPONENT; DIMINDEX_2; ARITH] THEN + CONV_TAC REAL_RAT_REDUCE_CONV);; + +(* ------------------------------------------------------------------------- *) +(* Axiom 9 (upper 2-dimensional axiom). *) +(* ------------------------------------------------------------------------- *) + +let TARSKI_AXIOM_9_EUCLIDEAN = prove + (`!p q a b c:real^2. + ~(p = q) /\ + dist(a,p) = dist(a,q) /\ dist(b,p) = dist(b,q) /\ dist(c,p) = dist(c,q) + ==> between b (a,c) \/ between c (b,a) \/ between a (c,b)`, + REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[BETWEEN_SYM] THEN + REWRITE_TAC[GSYM COLLINEAR_BETWEEN_CASES] THEN + REWRITE_TAC[dist; NORM_EQ; NORM_ARITH + `~(p = q) <=> ~(norm(p - q) = &0)`] THEN + ONCE_REWRITE_TAC[REAL_RING `~(x = &0) <=> ~(x pow 2 = &0)`] THEN + REWRITE_TAC[NORM_POW_2; COLLINEAR_3_2D] THEN + REWRITE_TAC[DOT_2; VECTOR_SUB_COMPONENT] THEN + CONV_TAC REAL_FIELD);; + +(* ------------------------------------------------------------------------- *) +(* Axiom 10 (Euclidean axiom). *) +(* ------------------------------------------------------------------------- *) + +let TARSKI_AXIOM_10_EUCLIDEAN = prove + (`!a b c d t:real^N. + between d (a,t) /\ between d (b,c) /\ ~(a = d) + ==> ?x y. between b (a,x) /\ between c (a,y) /\ between t (x,y)`, + REPEAT GEN_TAC THEN GEOM_ORIGIN_TAC `a:real^N` THEN REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`vec 0:real^N`; `d:real^N`; `t:real^N`] + BETWEEN_EXISTS_EXTENSION) THEN + ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM; VECTOR_ARITH + `d + u % (d - vec 0):real^N = (&1 + u) % d`] THEN + X_GEN_TAC `u:real` THEN STRIP_TAC THEN + MAP_EVERY EXISTS_TAC [`(&1 + u) % b:real^N`; `(&1 + u) % c:real^N`] THEN + ASM_REWRITE_TAC[between; dist; GSYM VECTOR_SUB_LDISTRIB] THEN + ASM_REWRITE_TAC[VECTOR_SUB_LZERO; NORM_NEG; + VECTOR_ARITH `b - (&1 + u) % b:real^N = --(u % b)`] THEN + ASM_SIMP_TAC[NORM_MUL; REAL_LE_ADD; REAL_POS; real_abs] THEN + REWRITE_TAC[GSYM REAL_ADD_LDISTRIB; REAL_EQ_MUL_LCANCEL] THEN + ASM_REWRITE_TAC[GSYM dist; GSYM between] THEN REAL_ARITH_TAC);; + +(* ------------------------------------------------------------------------- *) +(* Axiom 11 (Continuity). *) +(* ------------------------------------------------------------------------- *) + +let TARSKI_AXIOM_11_EUCLIDEAN = prove + (`!X Y:real^2->bool. + (?a. !x y. x IN X /\ y IN Y ==> between x (a,y)) + ==> (?b. !x y. x IN X /\ y IN Y ==> between b (x,y))`, + REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN GEOM_ORIGIN_TAC `a:real^2` THEN + REPEAT GEN_TAC THEN ASM_CASES_TAC `!x:real^2. x IN X ==> x = vec 0` THENL + [ASM_MESON_TAC[BETWEEN_REFL]; POP_ASSUM MP_TAC] THEN + ASM_CASES_TAC `Y:real^2->bool = {}` THEN ASM_REWRITE_TAC[NOT_IN_EMPTY] THEN + SUBGOAL_THEN `?c:real^2. c IN Y` (CHOOSE_THEN MP_TAC) THENL + [ASM SET_TAC[]; REPEAT(POP_ASSUM MP_TAC)] THEN + GEOM_BASIS_MULTIPLE_TAC 1 `c:real^2` THEN + X_GEN_TAC `c:real` THEN DISCH_TAC THEN REPEAT GEN_TAC THEN + DISCH_TAC THEN DISCH_TAC THEN REWRITE_TAC[NOT_FORALL_THM; NOT_IMP] THEN + DISCH_THEN(X_CHOOSE_THEN `z:real^2` STRIP_ASSUME_TAC) THEN + DISCH_THEN(LABEL_TAC "*") THEN + SUBGOAL_THEN `X SUBSET IMAGE (\c. c % basis 1:real^2) {c | &0 <= c} /\ + Y SUBSET IMAGE (\c. c % basis 1:real^2) {c | &0 <= c}` + MP_TAC THENL + [REWRITE_TAC[SUBSET; IN_IMAGE; IN_ELIM_THM] THEN + MATCH_MP_TAC(TAUT `p /\ (p ==> q) ==> p /\ q`) THEN CONJ_TAC THENL + [X_GEN_TAC `x:real^2` THEN DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o SPECL + [`x:real^2`; `c % basis 1:real^2`]) THEN + ASM_REWRITE_TAC[BETWEEN_IN_SEGMENT; IN_SEGMENT] THEN + REWRITE_TAC[VECTOR_MUL_RZERO; VECTOR_ADD_LID; IN_ELIM_THM] THEN + ASM_MESON_TAC[VECTOR_MUL_ASSOC; REAL_LE_MUL]; + DISCH_THEN(MP_TAC o SPEC `z:real^2`) THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC) THEN + UNDISCH_TAC `~(z:real^2 = vec 0)` THEN + ASM_REWRITE_TAC[VECTOR_MUL_EQ_0; DE_MORGAN_THM] THEN + STRIP_TAC THEN X_GEN_TAC `y:real^2` THEN DISCH_TAC THEN + REMOVE_THEN "*" (MP_TAC o SPECL [`z:real^2`; `y:real^2`]) THEN + ASM_REWRITE_TAC[VECTOR_MUL_ASSOC] THEN + REWRITE_TAC[BETWEEN_IN_SEGMENT; IN_SEGMENT] THEN + REWRITE_TAC[VECTOR_MUL_RZERO; VECTOR_ADD_LID; IN_ELIM_THM] THEN + DISCH_THEN(X_CHOOSE_THEN `u:real` MP_TAC) THEN + ASM_CASES_TAC `u = &0` THEN + ASM_REWRITE_TAC[VECTOR_MUL_LZERO; VECTOR_MUL_EQ_0] THEN + STRIP_TAC THEN EXISTS_TAC `inv(u) * d:real` THEN + ASM_REWRITE_TAC[GSYM VECTOR_MUL_ASSOC] THEN + ASM_SIMP_TAC[REAL_LE_MUL; REAL_LE_INV_EQ; VECTOR_MUL_ASSOC] THEN + ASM_SIMP_TAC[REAL_MUL_LINV; VECTOR_MUL_LID]]; + REWRITE_TAC[SUBSET_IMAGE] THEN REWRITE_TAC[SUBSET; IN_ELIM_THM] THEN + DISCH_THEN(CONJUNCTS_THEN2 + (X_CHOOSE_THEN `s:real->bool` STRIP_ASSUME_TAC) + (X_CHOOSE_THEN `t:real->bool` STRIP_ASSUME_TAC)) THEN + REMOVE_THEN "*" MP_TAC THEN + ASM_REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_IMAGE] THEN + DISCH_THEN(fun th -> + EXISTS_TAC `sup s % basis 1 :real^2` THEN MP_TAC th) THEN + REWRITE_TAC[between; dist; NORM_ARITH `norm(vec 0 - x) = norm x`] THEN + REWRITE_TAC[GSYM VECTOR_SUB_RDISTRIB; NORM_MUL] THEN + SIMP_TAC[NORM_BASIS; DIMINDEX_GE_1; LE_REFL; REAL_MUL_RID] THEN + ASM_SIMP_TAC[REAL_ARITH + `&0 <= x /\ &0 <= y ==> (abs y = abs x + abs(x - y) <=> x <= y)`] THEN + DISCH_TAC THEN X_GEN_TAC `x:real` THEN DISCH_TAC THEN + X_GEN_TAC `y:real` THEN DISCH_TAC THEN MATCH_MP_TAC(REAL_ARITH + `x <= s /\ s <= y ==> abs(x - y) = abs(x - s) + abs(s - y)`) THEN + MP_TAC(SPEC `s:real->bool` SUP) THEN + ASM_MESON_TAC[IMAGE_EQ_EMPTY; MEMBER_NOT_EMPTY]]);; diff --git a/Multivariate/topology.ml b/Multivariate/topology.ml new file mode 100644 index 0000000..cc11bb9 --- /dev/null +++ b/Multivariate/topology.ml @@ -0,0 +1,17240 @@ +(* ========================================================================= *) +(* Elementary topology in Euclidean space. *) +(* *) +(* (c) Copyright, John Harrison 1998-2008 *) +(* (c) Copyright, Valentina Bruno 2010 *) +(* ========================================================================= *) + +needs "Library/card.ml";; +needs "Multivariate/determinants.ml";; + +(* ------------------------------------------------------------------------- *) +(* General notion of a topology. *) +(* ------------------------------------------------------------------------- *) + +let istopology = new_definition + `istopology L <=> + {} IN L /\ + (!s t. s IN L /\ t IN L ==> (s INTER t) IN L) /\ + (!k. k SUBSET L ==> (UNIONS k) IN L)`;; + +let topology_tybij_th = prove + (`?t:(A->bool)->bool. istopology t`, + EXISTS_TAC `UNIV:(A->bool)->bool` THEN REWRITE_TAC[istopology; IN_UNIV]);; + +let topology_tybij = + new_type_definition "topology" ("topology","open_in") topology_tybij_th;; + +let ISTOPOLOGY_OPEN_IN = prove + (`istopology(open_in top)`, + MESON_TAC[topology_tybij]);; + +let TOPOLOGY_EQ = prove + (`!top1 top2. top1 = top2 <=> !s. open_in top1 s <=> open_in top2 s`, + REPEAT GEN_TAC THEN GEN_REWRITE_TAC RAND_CONV [GSYM FUN_EQ_THM] THEN + REWRITE_TAC[ETA_AX] THEN MESON_TAC[topology_tybij]);; + +(* ------------------------------------------------------------------------- *) +(* Infer the "universe" from union of all sets in the topology. *) +(* ------------------------------------------------------------------------- *) + +let topspace = new_definition + `topspace top = UNIONS {s | open_in top s}`;; + +(* ------------------------------------------------------------------------- *) +(* Main properties of open sets. *) +(* ------------------------------------------------------------------------- *) + +let OPEN_IN_CLAUSES = prove + (`!top:(A)topology. + open_in top {} /\ + (!s t. open_in top s /\ open_in top t ==> open_in top (s INTER t)) /\ + (!k. (!s. s IN k ==> open_in top s) ==> open_in top (UNIONS k))`, + SIMP_TAC[IN; SUBSET; SIMP_RULE[istopology; IN; SUBSET] ISTOPOLOGY_OPEN_IN]);; + +let OPEN_IN_SUBSET = prove + (`!top s. open_in top s ==> s SUBSET (topspace top)`, + REWRITE_TAC[topspace] THEN SET_TAC[]);; + +let OPEN_IN_EMPTY = prove + (`!top. open_in top {}`, + REWRITE_TAC[OPEN_IN_CLAUSES]);; + +let OPEN_IN_INTER = prove + (`!top s t. open_in top s /\ open_in top t ==> open_in top (s INTER t)`, + REWRITE_TAC[OPEN_IN_CLAUSES]);; + +let OPEN_IN_UNIONS = prove + (`!top k. (!s. s IN k ==> open_in top s) ==> open_in top (UNIONS k)`, + REWRITE_TAC[OPEN_IN_CLAUSES]);; + +let OPEN_IN_UNION = prove + (`!top s t. open_in top s /\ open_in top t ==> open_in top (s UNION t)`, + REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM UNIONS_2] THEN + MATCH_MP_TAC OPEN_IN_UNIONS THEN ASM SET_TAC[]);; + +let OPEN_IN_TOPSPACE = prove + (`!top. open_in top (topspace top)`, + SIMP_TAC[topspace; OPEN_IN_UNIONS; IN_ELIM_THM]);; + +let OPEN_IN_INTERS = prove + (`!top s:(A->bool)->bool. + FINITE s /\ ~(s = {}) /\ (!t. t IN s ==> open_in top t) + ==> open_in top (INTERS s)`, + GEN_TAC THEN REWRITE_TAC[IMP_CONJ] THEN + MATCH_MP_TAC FINITE_INDUCT_STRONG THEN + REWRITE_TAC[INTERS_INSERT; IMP_IMP; NOT_INSERT_EMPTY; FORALL_IN_INSERT] THEN + MAP_EVERY X_GEN_TAC [`s:A->bool`; `f:(A->bool)->bool`] THEN + ASM_CASES_TAC `f:(A->bool)->bool = {}` THEN + ASM_SIMP_TAC[INTERS_0; INTER_UNIV] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC OPEN_IN_INTER THEN ASM_SIMP_TAC[]);; + +let OPEN_IN_SUBOPEN = prove + (`!top s:A->bool. + open_in top s <=> + !x. x IN s ==> ?t. open_in top t /\ x IN t /\ t SUBSET s`, + REPEAT GEN_TAC THEN EQ_TAC THENL [MESON_TAC[SUBSET_REFL]; 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; LEFT_IMP_EXISTS_THM] THEN + ONCE_REWRITE_TAC[GSYM FORALL_IN_IMAGE] THEN REPEAT STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o MATCH_MP OPEN_IN_UNIONS) THEN + MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN ASM SET_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* Closed sets. *) +(* ------------------------------------------------------------------------- *) + +let closed_in = new_definition + `closed_in top s <=> + s SUBSET (topspace top) /\ open_in top (topspace top DIFF s)`;; + +let CLOSED_IN_SUBSET = prove + (`!top s. closed_in top s ==> s SUBSET (topspace top)`, + MESON_TAC[closed_in]);; + +let CLOSED_IN_EMPTY = prove + (`!top. closed_in top {}`, + REWRITE_TAC[closed_in; EMPTY_SUBSET; DIFF_EMPTY; OPEN_IN_TOPSPACE]);; + +let CLOSED_IN_TOPSPACE = prove + (`!top. closed_in top (topspace top)`, + REWRITE_TAC[closed_in; SUBSET_REFL; DIFF_EQ_EMPTY; OPEN_IN_EMPTY]);; + +let CLOSED_IN_UNION = prove + (`!top s t. closed_in top s /\ closed_in top t ==> closed_in top (s UNION t)`, + SIMP_TAC[closed_in; UNION_SUBSET; OPEN_IN_INTER; + SET_RULE `u DIFF (s UNION t) = (u DIFF s) INTER (u DIFF t)`]);; + +let CLOSED_IN_INTERS = prove + (`!top k:(A->bool)->bool. + ~(k = {}) /\ (!s. s IN k ==> closed_in top s) + ==> closed_in top (INTERS k)`, + REPEAT GEN_TAC THEN REWRITE_TAC[closed_in] THEN REPEAT STRIP_TAC THENL + [ASM SET_TAC[]; ALL_TAC] THEN + SUBGOAL_THEN `topspace top DIFF INTERS k :A->bool = + UNIONS {topspace top DIFF s | s IN k}` SUBST1_TAC + THENL [ALL_TAC; MATCH_MP_TAC OPEN_IN_UNIONS THEN ASM SET_TAC[]] THEN + GEN_REWRITE_TAC I [EXTENSION] THEN ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN + REWRITE_TAC[IN_UNIONS; IN_INTERS; IN_DIFF; EXISTS_IN_IMAGE] THEN + MESON_TAC[]);; + +let CLOSED_IN_INTER = prove + (`!top s t. closed_in top s /\ closed_in top t ==> closed_in top (s INTER t)`, + REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM INTERS_2] THEN + MATCH_MP_TAC CLOSED_IN_INTERS THEN ASM SET_TAC[]);; + +let OPEN_IN_CLOSED_IN_EQ = prove + (`!top s. open_in top s <=> + s SUBSET topspace top /\ closed_in top (topspace top DIFF s)`, + REWRITE_TAC[closed_in; SET_RULE `(u DIFF s) SUBSET u`] THEN + REWRITE_TAC[SET_RULE `u DIFF (u DIFF s) = u INTER s`] THEN + MESON_TAC[OPEN_IN_SUBSET; SET_RULE `s SUBSET t ==> t INTER s = s`]);; + +let OPEN_IN_CLOSED_IN = prove + (`!s. s SUBSET topspace top + ==> (open_in top s <=> closed_in top (topspace top DIFF s))`, + SIMP_TAC[OPEN_IN_CLOSED_IN_EQ]);; + +let OPEN_IN_DIFF = prove + (`!top s t:A->bool. + open_in top s /\ closed_in top t ==> open_in top (s DIFF t)`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN `s DIFF t :A->bool = s INTER (topspace top DIFF t)` + SUBST1_TAC THENL + [FIRST_X_ASSUM(MP_TAC o MATCH_MP OPEN_IN_SUBSET) THEN SET_TAC[]; + MATCH_MP_TAC OPEN_IN_INTER THEN ASM_MESON_TAC[closed_in]]);; + +let CLOSED_IN_DIFF = prove + (`!top s t:A->bool. + closed_in top s /\ open_in top t ==> closed_in top (s DIFF t)`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN `s DIFF t :A->bool = s INTER (topspace top DIFF t)` + SUBST1_TAC THENL + [FIRST_X_ASSUM(MP_TAC o MATCH_MP CLOSED_IN_SUBSET) THEN SET_TAC[]; + MATCH_MP_TAC CLOSED_IN_INTER THEN ASM_MESON_TAC[OPEN_IN_CLOSED_IN_EQ]]);; + +let CLOSED_IN_UNIONS = prove + (`!top s. FINITE s /\ (!t. t IN s ==> closed_in top t) + ==> closed_in top (UNIONS s)`, + GEN_TAC THEN REWRITE_TAC[IMP_CONJ] THEN + MATCH_MP_TAC FINITE_INDUCT_STRONG THEN + REWRITE_TAC[UNIONS_INSERT; UNIONS_0; CLOSED_IN_EMPTY; IN_INSERT] THEN + MESON_TAC[CLOSED_IN_UNION]);; + +(* ------------------------------------------------------------------------- *) +(* Subspace topology. *) +(* ------------------------------------------------------------------------- *) + +let subtopology = new_definition + `subtopology top u = topology {s INTER u | open_in top s}`;; + +let ISTOPLOGY_SUBTOPOLOGY = prove + (`!top u:A->bool. istopology {s INTER u | open_in top s}`, + REWRITE_TAC[istopology; SET_RULE + `{s INTER u | open_in top s} = + IMAGE (\s. s INTER u) {s | open_in top s}`] THEN + REWRITE_TAC[IMP_CONJ; FORALL_IN_IMAGE; RIGHT_FORALL_IMP_THM] THEN + REWRITE_TAC[SUBSET_IMAGE; IN_IMAGE; IN_ELIM_THM; SUBSET] THEN + REPEAT GEN_TAC THEN REPEAT CONJ_TAC THENL + [EXISTS_TAC `{}:A->bool` THEN REWRITE_TAC[OPEN_IN_EMPTY; INTER_EMPTY]; + SIMP_TAC[SET_RULE `(s INTER u) INTER t INTER u = (s INTER t) INTER u`] THEN + ASM_MESON_TAC[OPEN_IN_INTER]; + REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`f:(A->bool)->bool`; `g:(A->bool)->bool`] THEN + STRIP_TAC THEN EXISTS_TAC `UNIONS g :A->bool` THEN + ASM_SIMP_TAC[OPEN_IN_UNIONS; INTER_UNIONS] THEN SET_TAC[]]);; + +let OPEN_IN_SUBTOPOLOGY = prove + (`!top u s. open_in (subtopology top u) s <=> + ?t. open_in top t /\ s = t INTER u`, + REWRITE_TAC[subtopology] THEN + SIMP_TAC[REWRITE_RULE[CONJUNCT2 topology_tybij] ISTOPLOGY_SUBTOPOLOGY] THEN + REWRITE_TAC[EXTENSION; IN_ELIM_THM]);; + +let TOPSPACE_SUBTOPOLOGY = prove + (`!top u. topspace(subtopology top u) = topspace top INTER u`, + REWRITE_TAC[topspace; OPEN_IN_SUBTOPOLOGY; INTER_UNIONS] THEN + REPEAT STRIP_TAC THEN AP_TERM_TAC THEN + GEN_REWRITE_TAC I [EXTENSION] THEN REWRITE_TAC[IN_ELIM_THM]);; + +let CLOSED_IN_SUBTOPOLOGY = prove + (`!top u s. closed_in (subtopology top u) s <=> + ?t:A->bool. closed_in top t /\ s = t INTER u`, + REWRITE_TAC[closed_in; TOPSPACE_SUBTOPOLOGY] THEN + REWRITE_TAC[SUBSET_INTER; OPEN_IN_SUBTOPOLOGY; RIGHT_AND_EXISTS_THM] THEN + REPEAT STRIP_TAC THEN EQ_TAC THEN + DISCH_THEN(X_CHOOSE_THEN `t:A->bool` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `topspace top DIFF t :A->bool` THEN + ASM_SIMP_TAC[CLOSED_IN_TOPSPACE; OPEN_IN_DIFF; CLOSED_IN_DIFF; + OPEN_IN_TOPSPACE] THEN + ASM SET_TAC[]);; + +let OPEN_IN_SUBTOPOLOGY_EMPTY = prove + (`!top s. open_in (subtopology top {}) s <=> s = {}`, + REWRITE_TAC[OPEN_IN_SUBTOPOLOGY; INTER_EMPTY] THEN + MESON_TAC[OPEN_IN_EMPTY]);; + +let CLOSED_IN_SUBTOPOLOGY_EMPTY = prove + (`!top s. closed_in (subtopology top {}) s <=> s = {}`, + REWRITE_TAC[CLOSED_IN_SUBTOPOLOGY; INTER_EMPTY] THEN + MESON_TAC[CLOSED_IN_EMPTY]);; + +let OPEN_IN_SUBTOPOLOGY_REFL = prove + (`!top u:A->bool. open_in (subtopology top u) u <=> u SUBSET topspace top`, + REPEAT GEN_TAC THEN REWRITE_TAC[OPEN_IN_SUBTOPOLOGY] THEN EQ_TAC THENL + [REPEAT STRIP_TAC THEN ONCE_ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC(SET_RULE `s SUBSET u ==> s INTER t SUBSET u`) THEN + ASM_SIMP_TAC[OPEN_IN_SUBSET]; + DISCH_TAC THEN EXISTS_TAC `topspace top:A->bool` THEN + REWRITE_TAC[OPEN_IN_TOPSPACE] THEN ASM SET_TAC[]]);; + +let CLOSED_IN_SUBTOPOLOGY_REFL = prove + (`!top u:A->bool. closed_in (subtopology top u) u <=> u SUBSET topspace top`, + REPEAT GEN_TAC THEN REWRITE_TAC[CLOSED_IN_SUBTOPOLOGY] THEN EQ_TAC THENL + [REPEAT STRIP_TAC THEN ONCE_ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC(SET_RULE `s SUBSET u ==> s INTER t SUBSET u`) THEN + ASM_SIMP_TAC[CLOSED_IN_SUBSET]; + DISCH_TAC THEN EXISTS_TAC `topspace top:A->bool` THEN + REWRITE_TAC[CLOSED_IN_TOPSPACE] THEN ASM SET_TAC[]]);; + +let SUBTOPOLOGY_SUPERSET = prove + (`!top s:A->bool. topspace top SUBSET s ==> subtopology top s = top`, + REPEAT GEN_TAC THEN SIMP_TAC[TOPOLOGY_EQ; OPEN_IN_SUBTOPOLOGY] THEN + DISCH_TAC THEN X_GEN_TAC `u:A->bool` THEN EQ_TAC THENL + [DISCH_THEN(CHOOSE_THEN(CONJUNCTS_THEN2 MP_TAC SUBST1_TAC)) THEN + DISCH_THEN(fun th -> MP_TAC th THEN + ASSUME_TAC(MATCH_MP OPEN_IN_SUBSET th)) THEN + MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN ASM SET_TAC[]; + DISCH_TAC THEN EXISTS_TAC `u:A->bool` THEN + FIRST_ASSUM(MP_TAC o MATCH_MP OPEN_IN_SUBSET) THEN ASM SET_TAC[]]);; + +let SUBTOPOLOGY_TOPSPACE = prove + (`!top. subtopology top (topspace top) = top`, + SIMP_TAC[SUBTOPOLOGY_SUPERSET; SUBSET_REFL]);; + +let SUBTOPOLOGY_UNIV = prove + (`!top. subtopology top UNIV = top`, + SIMP_TAC[SUBTOPOLOGY_SUPERSET; SUBSET_UNIV]);; + +let OPEN_IN_IMP_SUBSET = prove + (`!top s t. open_in (subtopology top s) t ==> t SUBSET s`, + REWRITE_TAC[OPEN_IN_SUBTOPOLOGY] THEN SET_TAC[]);; + +let CLOSED_IN_IMP_SUBSET = prove + (`!top s t. closed_in (subtopology top s) t ==> t SUBSET s`, + REWRITE_TAC[closed_in; TOPSPACE_SUBTOPOLOGY] THEN SET_TAC[]);; + +let OPEN_IN_SUBTOPOLOGY_UNION = prove + (`!top s t u:A->bool. + open_in (subtopology top t) s /\ open_in (subtopology top u) s + ==> open_in (subtopology top (t UNION u)) s`, + REPEAT GEN_TAC THEN REWRITE_TAC[OPEN_IN_SUBTOPOLOGY] THEN + DISCH_THEN(CONJUNCTS_THEN2 + (X_CHOOSE_THEN `s':A->bool` STRIP_ASSUME_TAC) + (X_CHOOSE_THEN `t':A->bool` STRIP_ASSUME_TAC)) THEN + EXISTS_TAC `s' INTER t':A->bool` THEN ASM_SIMP_TAC[OPEN_IN_INTER] THEN + ASM SET_TAC[]);; + +let CLOSED_IN_SUBTOPOLOGY_UNION = prove + (`!top s t u:A->bool. + closed_in (subtopology top t) s /\ closed_in (subtopology top u) s + ==> closed_in (subtopology top (t UNION u)) s`, + REPEAT GEN_TAC THEN REWRITE_TAC[CLOSED_IN_SUBTOPOLOGY] THEN + DISCH_THEN(CONJUNCTS_THEN2 + (X_CHOOSE_THEN `s':A->bool` STRIP_ASSUME_TAC) + (X_CHOOSE_THEN `t':A->bool` STRIP_ASSUME_TAC)) THEN + EXISTS_TAC `s' INTER t':A->bool` THEN ASM_SIMP_TAC[CLOSED_IN_INTER] THEN + ASM SET_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* The universal Euclidean versions are what we use most of the time. *) +(* ------------------------------------------------------------------------- *) + +let open_def = new_definition + `open s <=> !x. x IN s ==> ?e. &0 < e /\ !x'. dist(x',x) < e ==> x' IN s`;; + +let closed = new_definition + `closed(s:real^N->bool) <=> open(UNIV DIFF s)`;; + +let euclidean = new_definition + `euclidean = topology open`;; + +let OPEN_EMPTY = prove + (`open {}`, + REWRITE_TAC[open_def; NOT_IN_EMPTY]);; + +let OPEN_UNIV = prove + (`open(:real^N)`, + REWRITE_TAC[open_def; IN_UNIV] THEN MESON_TAC[REAL_LT_01]);; + +let OPEN_INTER = prove + (`!s t. open s /\ open t ==> open (s INTER t)`, + REPEAT GEN_TAC THEN REWRITE_TAC[open_def; AND_FORALL_THM; IN_INTER] THEN + MATCH_MP_TAC MONO_FORALL THEN GEN_TAC THEN + DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN + ASM_REWRITE_TAC[] THEN DISCH_THEN(CONJUNCTS_THEN2 + (X_CHOOSE_TAC `d1:real`) (X_CHOOSE_TAC `d2:real`)) THEN + MP_TAC(SPECL [`d1:real`; `d2:real`] REAL_DOWN2) THEN + ASM_MESON_TAC[REAL_LT_TRANS]);; + +let OPEN_UNIONS = prove + (`(!s. s IN f ==> open s) ==> open(UNIONS f)`, + REWRITE_TAC[open_def; IN_UNIONS] THEN MESON_TAC[]);; + +let OPEN_EXISTS_IN = prove + (`!P Q:A->real^N->bool. + (!a. P a ==> open {x | Q a x}) ==> open {x | ?a. P a /\ Q a x}`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN `open(UNIONS {{x | Q (a:A) (x:real^N)} | P a})` MP_TAC THENL + [MATCH_MP_TAC OPEN_UNIONS THEN ASM_REWRITE_TAC[FORALL_IN_GSPEC]; + MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN REWRITE_TAC[UNIONS_GSPEC] THEN + SET_TAC[]]);; + +let OPEN_EXISTS = prove + (`!Q:A->real^N->bool. (!a. open {x | Q a x}) ==> open {x | ?a. Q a x}`, + MP_TAC(ISPEC `\x:A. T` OPEN_EXISTS_IN) THEN REWRITE_TAC[]);; + +let OPEN_IN = prove + (`!s:real^N->bool. open s <=> open_in euclidean s`, + GEN_TAC THEN REWRITE_TAC[euclidean] THEN CONV_TAC SYM_CONV THEN + AP_THM_TAC THEN REWRITE_TAC[GSYM(CONJUNCT2 topology_tybij)] THEN + REWRITE_TAC[REWRITE_RULE[IN] istopology] THEN + REWRITE_TAC[OPEN_EMPTY; OPEN_INTER; SUBSET] THEN + MESON_TAC[IN; OPEN_UNIONS]);; + +let TOPSPACE_EUCLIDEAN = prove + (`topspace euclidean = (:real^N)`, + REWRITE_TAC[topspace; EXTENSION; IN_UNIV; IN_UNIONS; IN_ELIM_THM] THEN + MESON_TAC[OPEN_UNIV; IN_UNIV; OPEN_IN]);; + +let TOPSPACE_EUCLIDEAN_SUBTOPOLOGY = prove + (`!s. topspace (subtopology euclidean s) = s`, + REWRITE_TAC[TOPSPACE_EUCLIDEAN; TOPSPACE_SUBTOPOLOGY; INTER_UNIV]);; + +let OPEN_IN_REFL = prove + (`!s:real^N->bool. open_in (subtopology euclidean s) s`, + REWRITE_TAC[OPEN_IN_SUBTOPOLOGY_REFL; TOPSPACE_EUCLIDEAN; SUBSET_UNIV]);; + +let CLOSED_IN_REFL = prove + (`!s:real^N->bool. closed_in (subtopology euclidean s) s`, + REWRITE_TAC[CLOSED_IN_SUBTOPOLOGY_REFL; TOPSPACE_EUCLIDEAN; SUBSET_UNIV]);; + +let CLOSED_IN = prove + (`!s:real^N->bool. closed s <=> closed_in euclidean s`, + REWRITE_TAC[closed; closed_in; TOPSPACE_EUCLIDEAN; OPEN_IN; SUBSET_UNIV]);; + +let OPEN_UNION = prove + (`!s t. open s /\ open t ==> open(s UNION t)`, + REWRITE_TAC[OPEN_IN; OPEN_IN_UNION]);; + +let OPEN_SUBOPEN = prove + (`!s. open s <=> !x. x IN s ==> ?t. open t /\ x IN t /\ t SUBSET s`, + REWRITE_TAC[OPEN_IN; GSYM OPEN_IN_SUBOPEN]);; + +let CLOSED_EMPTY = prove + (`closed {}`, + REWRITE_TAC[CLOSED_IN; CLOSED_IN_EMPTY]);; + +let CLOSED_UNIV = prove + (`closed(UNIV:real^N->bool)`, + REWRITE_TAC[CLOSED_IN; GSYM TOPSPACE_EUCLIDEAN; CLOSED_IN_TOPSPACE]);; + +let CLOSED_UNION = prove + (`!s t. closed s /\ closed t ==> closed(s UNION t)`, + REWRITE_TAC[CLOSED_IN; CLOSED_IN_UNION]);; + +let CLOSED_INTER = prove + (`!s t. closed s /\ closed t ==> closed(s INTER t)`, + REWRITE_TAC[CLOSED_IN; CLOSED_IN_INTER]);; + +let CLOSED_INTERS = prove + (`!f. (!s:real^N->bool. s IN f ==> closed s) ==> closed(INTERS f)`, + REWRITE_TAC[CLOSED_IN] THEN REPEAT STRIP_TAC THEN + ASM_CASES_TAC `f:(real^N->bool)->bool = {}` THEN + ASM_SIMP_TAC[CLOSED_IN_INTERS; INTERS_0] THEN + REWRITE_TAC[GSYM TOPSPACE_EUCLIDEAN; CLOSED_IN_TOPSPACE]);; + +let CLOSED_FORALL_IN = prove + (`!P Q:A->real^N->bool. + (!a. P a ==> closed {x | Q a x}) ==> closed {x | !a. P a ==> Q a x}`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN `closed(INTERS {{x | Q (a:A) (x:real^N)} | P a})` MP_TAC THENL + [MATCH_MP_TAC CLOSED_INTERS THEN ASM_REWRITE_TAC[FORALL_IN_GSPEC]; + MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN REWRITE_TAC[INTERS_GSPEC] THEN + SET_TAC[]]);; + +let CLOSED_FORALL = prove + (`!Q:A->real^N->bool. (!a. closed {x | Q a x}) ==> closed {x | !a. Q a x}`, + MP_TAC(ISPEC `\x:A. T` CLOSED_FORALL_IN) THEN REWRITE_TAC[]);; + +let OPEN_CLOSED = prove + (`!s:real^N->bool. open s <=> closed(UNIV DIFF s)`, + SIMP_TAC[OPEN_IN; CLOSED_IN; TOPSPACE_EUCLIDEAN; SUBSET_UNIV; + OPEN_IN_CLOSED_IN_EQ]);; + +let OPEN_DIFF = prove + (`!s t. open s /\ closed t ==> open(s DIFF t)`, + REWRITE_TAC[OPEN_IN; CLOSED_IN; OPEN_IN_DIFF]);; + +let CLOSED_DIFF = prove + (`!s t. closed s /\ open t ==> closed(s DIFF t)`, + REWRITE_TAC[OPEN_IN; CLOSED_IN; CLOSED_IN_DIFF]);; + +let OPEN_INTERS = prove + (`!s. FINITE s /\ (!t. t IN s ==> open t) ==> open(INTERS s)`, + REWRITE_TAC[IMP_CONJ] THEN MATCH_MP_TAC FINITE_INDUCT_STRONG THEN + REWRITE_TAC[INTERS_INSERT; INTERS_0; OPEN_UNIV; IN_INSERT] THEN + MESON_TAC[OPEN_INTER]);; + +let CLOSED_UNIONS = prove + (`!s. FINITE s /\ (!t. t IN s ==> closed t) ==> closed(UNIONS s)`, + REWRITE_TAC[IMP_CONJ] THEN MATCH_MP_TAC FINITE_INDUCT_STRONG THEN + REWRITE_TAC[UNIONS_INSERT; UNIONS_0; CLOSED_EMPTY; IN_INSERT] THEN + MESON_TAC[CLOSED_UNION]);; + +(* ------------------------------------------------------------------------- *) +(* Open and closed balls and spheres. *) +(* ------------------------------------------------------------------------- *) + +let ball = new_definition + `ball(x,e) = { y | dist(x,y) < e}`;; + +let cball = new_definition + `cball(x,e) = { y | dist(x,y) <= e}`;; + +let sphere = new_definition + `sphere(x,e) = { y | dist(x,y) = e}`;; + +let IN_BALL = prove + (`!x y e. y IN ball(x,e) <=> dist(x,y) < e`, + REWRITE_TAC[ball; IN_ELIM_THM]);; + +let IN_CBALL = prove + (`!x y e. y IN cball(x,e) <=> dist(x,y) <= e`, + REWRITE_TAC[cball; IN_ELIM_THM]);; + +let IN_SPHERE = prove + (`!x y e. y IN sphere(x,e) <=> dist(x,y) = e`, + REWRITE_TAC[sphere; IN_ELIM_THM]);; + +let IN_BALL_0 = prove + (`!x e. x IN ball(vec 0,e) <=> norm(x) < e`, + REWRITE_TAC[IN_BALL; dist; VECTOR_SUB_LZERO; NORM_NEG]);; + +let IN_CBALL_0 = prove + (`!x e. x IN cball(vec 0,e) <=> norm(x) <= e`, + REWRITE_TAC[IN_CBALL; dist; VECTOR_SUB_LZERO; NORM_NEG]);; + +let IN_SPHERE_0 = prove + (`!x e. x IN sphere(vec 0,e) <=> norm(x) = e`, + REWRITE_TAC[IN_SPHERE; dist; VECTOR_SUB_LZERO; NORM_NEG]);; + +let BALL_TRIVIAL = prove + (`!x. ball(x,&0) = {}`, + REWRITE_TAC[EXTENSION; IN_BALL; IN_SING; NOT_IN_EMPTY] THEN NORM_ARITH_TAC);; + +let CBALL_TRIVIAL = prove + (`!x. cball(x,&0) = {x}`, + REWRITE_TAC[EXTENSION; IN_CBALL; IN_SING; NOT_IN_EMPTY] THEN NORM_ARITH_TAC);; + +let CENTRE_IN_CBALL = prove + (`!x e. x IN cball(x,e) <=> &0 <= e`, + MESON_TAC[IN_CBALL; DIST_REFL]);; + +let BALL_SUBSET_CBALL = prove + (`!x e. ball(x,e) SUBSET cball(x,e)`, + REWRITE_TAC[IN_BALL; IN_CBALL; SUBSET] THEN REAL_ARITH_TAC);; + +let SPHERE_SUBSET_CBALL = prove + (`!x e. sphere(x,e) SUBSET cball(x,e)`, + REWRITE_TAC[IN_SPHERE; IN_CBALL; SUBSET] THEN REAL_ARITH_TAC);; + +let SUBSET_BALL = prove + (`!x d e. d <= e ==> ball(x,d) SUBSET ball(x,e)`, + REWRITE_TAC[SUBSET; IN_BALL] THEN MESON_TAC[REAL_LTE_TRANS]);; + +let SUBSET_CBALL = prove + (`!x d e. d <= e ==> cball(x,d) SUBSET cball(x,e)`, + REWRITE_TAC[SUBSET; IN_CBALL] THEN MESON_TAC[REAL_LE_TRANS]);; + +let BALL_MAX_UNION = prove + (`!a r s. ball(a,max r s) = ball(a,r) UNION ball(a,s)`, + REWRITE_TAC[IN_BALL; IN_UNION; EXTENSION] THEN REAL_ARITH_TAC);; + +let BALL_MIN_INTER = prove + (`!a r s. ball(a,min r s) = ball(a,r) INTER ball(a,s)`, + REWRITE_TAC[IN_BALL; IN_INTER; EXTENSION] THEN REAL_ARITH_TAC);; + +let BALL_TRANSLATION = prove + (`!a x r. ball(a + x,r) = IMAGE (\y. a + y) (ball(x,r))`, + REWRITE_TAC[ball] THEN GEOM_TRANSLATE_TAC[]);; + +let CBALL_TRANSLATION = prove + (`!a x r. cball(a + x,r) = IMAGE (\y. a + y) (cball(x,r))`, + REWRITE_TAC[cball] THEN GEOM_TRANSLATE_TAC[]);; + +let SPHERE_TRANSLATION = prove + (`!a x r. sphere(a + x,r) = IMAGE (\y. a + y) (sphere(x,r))`, + REWRITE_TAC[sphere] THEN GEOM_TRANSLATE_TAC[]);; + +add_translation_invariants + [BALL_TRANSLATION; CBALL_TRANSLATION; SPHERE_TRANSLATION];; + +let BALL_LINEAR_IMAGE = prove + (`!f:real^M->real^N x r. + linear f /\ (!y. ?x. f x = y) /\ (!x. norm(f x) = norm x) + ==> ball(f x,r) = IMAGE f (ball(x,r))`, + REWRITE_TAC[ball] THEN GEOM_TRANSFORM_TAC[]);; + +let CBALL_LINEAR_IMAGE = prove + (`!f:real^M->real^N x r. + linear f /\ (!y. ?x. f x = y) /\ (!x. norm(f x) = norm x) + ==> cball(f x,r) = IMAGE f (cball(x,r))`, + REWRITE_TAC[cball] THEN GEOM_TRANSFORM_TAC[]);; + +let SPHERE_LINEAR_IMAGE = prove + (`!f:real^M->real^N x r. + linear f /\ (!y. ?x. f x = y) /\ (!x. norm(f x) = norm x) + ==> sphere(f x,r) = IMAGE f (sphere(x,r))`, + REWRITE_TAC[sphere] THEN GEOM_TRANSFORM_TAC[]);; + +add_linear_invariants + [BALL_LINEAR_IMAGE; CBALL_LINEAR_IMAGE; SPHERE_LINEAR_IMAGE];; + +let BALL_SCALING = prove + (`!c. &0 < c ==> !x r. ball(c % x,c * r) = IMAGE (\x. c % x) (ball(x,r))`, + REPEAT STRIP_TAC THEN CONV_TAC SYM_CONV THEN + MATCH_MP_TAC SURJECTIVE_IMAGE_EQ THEN REWRITE_TAC[] THEN CONJ_TAC THENL + [ASM_MESON_TAC[SURJECTIVE_SCALING; REAL_LT_IMP_NZ]; ALL_TAC] THEN + REWRITE_TAC[IN_BALL; DIST_MUL] THEN + ASM_SIMP_TAC[REAL_ARITH `&0 < c ==> abs c = c`; REAL_LT_LMUL_EQ]);; + +let CBALL_SCALING = prove + (`!c. &0 < c ==> !x r. cball(c % x,c * r) = IMAGE (\x. c % x) (cball(x,r))`, + REPEAT STRIP_TAC THEN CONV_TAC SYM_CONV THEN + MATCH_MP_TAC SURJECTIVE_IMAGE_EQ THEN REWRITE_TAC[] THEN CONJ_TAC THENL + [ASM_MESON_TAC[SURJECTIVE_SCALING; REAL_LT_IMP_NZ]; ALL_TAC] THEN + REWRITE_TAC[IN_CBALL; DIST_MUL] THEN + ASM_SIMP_TAC[REAL_ARITH `&0 < c ==> abs c = c`; REAL_LE_LMUL_EQ]);; + +add_scaling_theorems [BALL_SCALING; CBALL_SCALING];; + +let CBALL_DIFF_BALL = prove + (`!a r. cball(a,r) DIFF ball(a,r) = sphere(a,r)`, + REWRITE_TAC[ball; cball; sphere; EXTENSION; IN_DIFF; IN_ELIM_THM] THEN + REAL_ARITH_TAC);; + +let BALL_UNION_SPHERE = prove + (`!a r. ball(a,r) UNION sphere(a,r) = cball(a,r)`, + REWRITE_TAC[ball; cball; sphere; EXTENSION; IN_UNION; IN_ELIM_THM] THEN + REAL_ARITH_TAC);; + +let SPHERE_UNION_BALL = prove + (`!a r. sphere(a,r) UNION ball(a,r) = cball(a,r)`, + REWRITE_TAC[ball; cball; sphere; EXTENSION; IN_UNION; IN_ELIM_THM] THEN + REAL_ARITH_TAC);; + +let CBALL_DIFF_SPHERE = prove + (`!a r. cball(a,r) DIFF sphere(a,r) = ball(a,r)`, + REWRITE_TAC[EXTENSION; IN_DIFF; IN_SPHERE; IN_BALL; IN_CBALL] THEN + REAL_ARITH_TAC);; + +let OPEN_BALL = prove + (`!x e. open(ball(x,e))`, + REWRITE_TAC[open_def; ball; IN_ELIM_THM] THEN ONCE_REWRITE_TAC[DIST_SYM] THEN + MESON_TAC[REAL_SUB_LT; REAL_LT_SUB_LADD; REAL_ADD_SYM; REAL_LET_TRANS; + DIST_TRIANGLE_ALT]);; + +let CENTRE_IN_BALL = prove + (`!x e. x IN ball(x,e) <=> &0 < e`, + MESON_TAC[IN_BALL; DIST_REFL]);; + +let OPEN_CONTAINS_BALL = prove + (`!s. open s <=> !x. x IN s ==> ?e. &0 < e /\ ball(x,e) SUBSET s`, + REWRITE_TAC[open_def; SUBSET; IN_BALL] THEN REWRITE_TAC[DIST_SYM]);; + +let OPEN_CONTAINS_BALL_EQ = prove + (`!s. open s ==> (!x. x IN s <=> ?e. &0 < e /\ ball(x,e) SUBSET s)`, + MESON_TAC[OPEN_CONTAINS_BALL; SUBSET; CENTRE_IN_BALL]);; + +let BALL_EQ_EMPTY = prove + (`!x e. (ball(x,e) = {}) <=> e <= &0`, + REWRITE_TAC[EXTENSION; IN_BALL; NOT_IN_EMPTY; REAL_NOT_LT] THEN + MESON_TAC[DIST_POS_LE; REAL_LE_TRANS; DIST_REFL]);; + +let BALL_EMPTY = prove + (`!x e. e <= &0 ==> ball(x,e) = {}`, + REWRITE_TAC[BALL_EQ_EMPTY]);; + +let OPEN_CONTAINS_CBALL = prove + (`!s. open s <=> !x. x IN s ==> ?e. &0 < e /\ cball(x,e) SUBSET s`, + GEN_TAC THEN REWRITE_TAC[OPEN_CONTAINS_BALL] THEN EQ_TAC THENL + [ALL_TAC; ASM_MESON_TAC[SUBSET_TRANS; BALL_SUBSET_CBALL]] THEN + MATCH_MP_TAC MONO_FORALL THEN GEN_TAC THEN MATCH_MP_TAC MONO_IMP THEN + REWRITE_TAC[SUBSET; IN_BALL; IN_CBALL] THEN + DISCH_THEN(X_CHOOSE_THEN `e:real` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `e / &2` THEN ASM_REWRITE_TAC[REAL_HALF] THEN + SUBGOAL_THEN `e / &2 < e` (fun th -> ASM_MESON_TAC[th; REAL_LET_TRANS]) THEN + ASM_SIMP_TAC[REAL_LT_LDIV_EQ; REAL_OF_NUM_LT; ARITH] THEN + UNDISCH_TAC `&0 < e` THEN REAL_ARITH_TAC);; + +let OPEN_CONTAINS_CBALL_EQ = prove + (`!s. open s ==> (!x. x IN s <=> ?e. &0 < e /\ cball(x,e) SUBSET s)`, + MESON_TAC[OPEN_CONTAINS_CBALL; SUBSET; REAL_LT_IMP_LE; CENTRE_IN_CBALL]);; + +let SPHERE_EQ_EMPTY = prove + (`!a:real^N r. sphere(a,r) = {} <=> r < &0`, + REWRITE_TAC[sphere; EXTENSION; IN_ELIM_THM; NOT_IN_EMPTY] THEN + REPEAT GEN_TAC THEN EQ_TAC THENL [ALL_TAC; CONV_TAC NORM_ARITH] THEN + MESON_TAC[VECTOR_CHOOSE_DIST; REAL_NOT_LE]);; + +let SPHERE_EMPTY = prove + (`!a:real^N r. r < &0 ==> sphere(a,r) = {}`, + REWRITE_TAC[SPHERE_EQ_EMPTY]);; + +let NEGATIONS_BALL = prove + (`!r. IMAGE (--) (ball(vec 0:real^N,r)) = ball(vec 0,r)`, + GEN_TAC THEN MATCH_MP_TAC SURJECTIVE_IMAGE_EQ THEN + REWRITE_TAC[IN_BALL_0; NORM_NEG] THEN MESON_TAC[VECTOR_NEG_NEG]);; + +let NEGATIONS_CBALL = prove + (`!r. IMAGE (--) (cball(vec 0:real^N,r)) = cball(vec 0,r)`, + GEN_TAC THEN MATCH_MP_TAC SURJECTIVE_IMAGE_EQ THEN + REWRITE_TAC[IN_CBALL_0; NORM_NEG] THEN MESON_TAC[VECTOR_NEG_NEG]);; + +let NEGATIONS_SPHERE = prove + (`!r. IMAGE (--) (sphere(vec 0:real^N,r)) = sphere(vec 0,r)`, + GEN_TAC THEN MATCH_MP_TAC SURJECTIVE_IMAGE_EQ THEN + REWRITE_TAC[IN_SPHERE_0; NORM_NEG] THEN MESON_TAC[VECTOR_NEG_NEG]);; + +(* ------------------------------------------------------------------------- *) +(* Basic "localization" results are handy for connectedness. *) +(* ------------------------------------------------------------------------- *) + +let OPEN_IN_OPEN = prove + (`!s:real^N->bool u. + open_in (subtopology euclidean u) s <=> ?t. open t /\ (s = u INTER t)`, + REPEAT STRIP_TAC THEN REWRITE_TAC[OPEN_IN_SUBTOPOLOGY; GSYM OPEN_IN] THEN + REWRITE_TAC[INTER_ACI]);; + +let OPEN_IN_INTER_OPEN = prove + (`!s t u:real^N->bool. + open_in (subtopology euclidean u) s /\ open t + ==> open_in (subtopology euclidean u) (s INTER t)`, + REWRITE_TAC[OPEN_IN_OPEN] THEN REPEAT STRIP_TAC THEN + ASM_REWRITE_TAC[INTER_ASSOC] THEN ASM_MESON_TAC[OPEN_INTER]);; + +let OPEN_IN_OPEN_INTER = prove + (`!u s. open s ==> open_in (subtopology euclidean u) (u INTER s)`, + REWRITE_TAC[OPEN_IN_OPEN] THEN MESON_TAC[]);; + +let OPEN_OPEN_IN_TRANS = prove + (`!s t. open s /\ open t /\ t SUBSET s + ==> open_in (subtopology euclidean s) t`, + MESON_TAC[OPEN_IN_OPEN_INTER; SET_RULE `t SUBSET s ==> t = s INTER t`]);; + +let OPEN_SUBSET = prove + (`!s t:real^N->bool. + s SUBSET t /\ open s ==> open_in (subtopology euclidean t) s`, + REPEAT STRIP_TAC THEN REWRITE_TAC[OPEN_IN_OPEN] THEN + EXISTS_TAC `s:real^N->bool` THEN ASM SET_TAC[]);; + +let CLOSED_IN_CLOSED = prove + (`!s:real^N->bool u. + closed_in (subtopology euclidean u) s <=> ?t. closed t /\ (s = u INTER t)`, + REPEAT STRIP_TAC THEN REWRITE_TAC[CLOSED_IN_SUBTOPOLOGY; GSYM CLOSED_IN] THEN + REWRITE_TAC[INTER_ACI]);; + +let CLOSED_SUBSET_EQ = prove + (`!u s:real^N->bool. + closed s ==> (closed_in (subtopology euclidean u) s <=> s SUBSET u)`, + REPEAT STRIP_TAC THEN EQ_TAC THEN DISCH_TAC THENL + [FIRST_ASSUM(MP_TAC o MATCH_MP CLOSED_IN_SUBSET) THEN + REWRITE_TAC[TOPSPACE_EUCLIDEAN_SUBTOPOLOGY]; + REWRITE_TAC[CLOSED_IN_CLOSED] THEN EXISTS_TAC `s:real^N->bool` THEN + ASM SET_TAC[]]);; + +let CLOSED_IN_INTER_CLOSED = prove + (`!s t u:real^N->bool. + closed_in (subtopology euclidean u) s /\ closed t + ==> closed_in (subtopology euclidean u) (s INTER t)`, + REWRITE_TAC[CLOSED_IN_CLOSED] THEN REPEAT STRIP_TAC THEN + ASM_REWRITE_TAC[INTER_ASSOC] THEN ASM_MESON_TAC[CLOSED_INTER]);; + +let CLOSED_IN_CLOSED_INTER = prove + (`!u s. closed s ==> closed_in (subtopology euclidean u) (u INTER s)`, + REWRITE_TAC[CLOSED_IN_CLOSED] THEN MESON_TAC[]);; + +let CLOSED_CLOSED_IN_TRANS = prove + (`!s t. closed s /\ closed t /\ t SUBSET s + ==> closed_in (subtopology euclidean s) t`, + MESON_TAC[CLOSED_IN_CLOSED_INTER; SET_RULE `t SUBSET s ==> t = s INTER t`]);; + +let CLOSED_SUBSET = prove + (`!s t:real^N->bool. + s SUBSET t /\ closed s ==> closed_in (subtopology euclidean t) s`, + REPEAT STRIP_TAC THEN REWRITE_TAC[CLOSED_IN_CLOSED] THEN + EXISTS_TAC `s:real^N->bool` THEN ASM SET_TAC[]);; + +let OPEN_IN_SUBSET_TRANS = prove + (`!s t u:real^N->bool. + open_in (subtopology euclidean u) s /\ s SUBSET t /\ t SUBSET u + ==> open_in (subtopology euclidean t) s`, + REPEAT GEN_TAC THEN REWRITE_TAC[OPEN_IN_OPEN; LEFT_AND_EXISTS_THM] THEN + MATCH_MP_TAC MONO_EXISTS THEN SET_TAC[]);; + +let CLOSED_IN_SUBSET_TRANS = prove + (`!s t u:real^N->bool. + closed_in (subtopology euclidean u) s /\ s SUBSET t /\ t SUBSET u + ==> closed_in (subtopology euclidean t) s`, + REPEAT GEN_TAC THEN REWRITE_TAC[CLOSED_IN_CLOSED; LEFT_AND_EXISTS_THM] THEN + MATCH_MP_TAC MONO_EXISTS THEN SET_TAC[]);; + +let open_in = prove + (`!u s:real^N->bool. + open_in (subtopology euclidean u) s <=> + s SUBSET u /\ + !x. x IN s ==> ?e. &0 < e /\ + !x'. x' IN u /\ dist(x',x) < e ==> x' IN s`, + REPEAT GEN_TAC THEN + REWRITE_TAC[OPEN_IN_SUBTOPOLOGY; GSYM OPEN_IN] THEN EQ_TAC THENL + [REWRITE_TAC[open_def] THEN ASM SET_TAC[INTER_SUBSET; IN_INTER]; + ALL_TAC] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_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 `d:real^N->real`) THEN + EXISTS_TAC `UNIONS {b | ?x:real^N. (b = ball(x,d x)) /\ x IN s}` THEN + CONJ_TAC THENL + [MATCH_MP_TAC OPEN_UNIONS THEN + ASM_SIMP_TAC[IN_ELIM_THM; LEFT_IMP_EXISTS_THM; OPEN_BALL]; + GEN_REWRITE_TAC I [EXTENSION] THEN + REWRITE_TAC[IN_INTER; IN_UNIONS; IN_ELIM_THM] THEN + ASM_MESON_TAC[SUBSET; DIST_REFL; DIST_SYM; IN_BALL]]);; + +let OPEN_IN_CONTAINS_BALL = prove + (`!s t:real^N->bool. + open_in (subtopology euclidean t) s <=> + s SUBSET t /\ + !x. x IN s ==> ?e. &0 < e /\ ball(x,e) INTER t SUBSET s`, + REWRITE_TAC[open_in; INTER; SUBSET; IN_ELIM_THM; IN_BALL] THEN + MESON_TAC[DIST_SYM]);; + +let OPEN_IN_CONTAINS_CBALL = prove + (`!s t:real^N->bool. + open_in (subtopology euclidean t) s <=> + s SUBSET t /\ + !x. x IN s ==> ?e. &0 < e /\ cball(x,e) INTER t SUBSET s`, + REPEAT GEN_TAC THEN REWRITE_TAC[OPEN_IN_CONTAINS_BALL] THEN + AP_TERM_TAC THEN REWRITE_TAC[IN_BALL; IN_INTER; SUBSET; IN_CBALL] THEN + MESON_TAC[REAL_ARITH `&0 < e ==> &0 < e / &2 /\ (x <= e / &2 ==> x < e)`; + REAL_LT_IMP_LE]);; + +(* ------------------------------------------------------------------------- *) +(* These "transitivity" results are handy too. *) +(* ------------------------------------------------------------------------- *) + +let OPEN_IN_TRANS = prove + (`!s t u. open_in (subtopology euclidean t) s /\ + open_in (subtopology euclidean u) t + ==> open_in (subtopology euclidean u) s`, + ASM_MESON_TAC[OPEN_IN_OPEN; OPEN_IN; OPEN_INTER; INTER_ASSOC]);; + +let OPEN_IN_OPEN_TRANS = prove + (`!s t. open_in (subtopology euclidean t) s /\ open t ==> open s`, + REWRITE_TAC[ONCE_REWRITE_RULE[GSYM SUBTOPOLOGY_UNIV] OPEN_IN] THEN + REWRITE_TAC[OPEN_IN_TRANS]);; + +let CLOSED_IN_TRANS = prove + (`!s t u. closed_in (subtopology euclidean t) s /\ + closed_in (subtopology euclidean u) t + ==> closed_in (subtopology euclidean u) s`, + ASM_MESON_TAC[CLOSED_IN_CLOSED; CLOSED_IN; CLOSED_INTER; INTER_ASSOC]);; + +let CLOSED_IN_CLOSED_TRANS = prove + (`!s t. closed_in (subtopology euclidean t) s /\ closed t ==> closed s`, + REWRITE_TAC[ONCE_REWRITE_RULE[GSYM SUBTOPOLOGY_UNIV] CLOSED_IN] THEN + REWRITE_TAC[CLOSED_IN_TRANS]);; + +let OPEN_IN_SUBTOPOLOGY_INTER_SUBSET = prove + (`!s u v. open_in (subtopology euclidean u) (u INTER s) /\ v SUBSET u + ==> open_in (subtopology euclidean v) (v INTER s)`, + REPEAT GEN_TAC THEN REWRITE_TAC[OPEN_IN_OPEN; LEFT_AND_EXISTS_THM] THEN + MATCH_MP_TAC MONO_EXISTS THEN SET_TAC[]);; + +let OPEN_IN_OPEN_EQ = prove + (`!s t. open s + ==> (open_in (subtopology euclidean s) t <=> open t /\ t SUBSET s)`, + MESON_TAC[OPEN_OPEN_IN_TRANS; OPEN_IN_OPEN_TRANS; open_in]);; + +let CLOSED_IN_CLOSED_EQ = prove + (`!s t. closed s + ==> (closed_in (subtopology euclidean s) t <=> + closed t /\ t SUBSET s)`, + MESON_TAC[CLOSED_CLOSED_IN_TRANS; CLOSED_IN_CLOSED_TRANS; closed_in; + TOPSPACE_EUCLIDEAN_SUBTOPOLOGY]);; + +(* ------------------------------------------------------------------------- *) +(* Also some invariance theorems for relative topology. *) +(* ------------------------------------------------------------------------- *) + +let OPEN_IN_TRANSLATION_EQ = prove + (`!a s t. open_in (subtopology euclidean (IMAGE (\x. a + x) t)) + (IMAGE (\x. a + x) s) <=> + open_in (subtopology euclidean t) s`, + REWRITE_TAC[open_in] THEN GEOM_TRANSLATE_TAC[]);; + +add_translation_invariants [OPEN_IN_TRANSLATION_EQ];; + +let CLOSED_IN_TRANSLATION_EQ = prove + (`!a s t. closed_in (subtopology euclidean (IMAGE (\x. a + x) t)) + (IMAGE (\x. a + x) s) <=> + closed_in (subtopology euclidean t) s`, + REWRITE_TAC[closed_in; TOPSPACE_EUCLIDEAN_SUBTOPOLOGY] THEN + GEOM_TRANSLATE_TAC[]);; + +add_translation_invariants [CLOSED_IN_TRANSLATION_EQ];; + +let OPEN_IN_INJECTIVE_LINEAR_IMAGE = prove + (`!f:real^M->real^N s t. + linear f /\ (!x y. f x = f y ==> x = y) + ==> (open_in (subtopology euclidean (IMAGE f t)) (IMAGE f s) <=> + open_in (subtopology euclidean t) s)`, + REWRITE_TAC[open_in; FORALL_IN_IMAGE; IMP_CONJ; SUBSET] THEN + REPEAT STRIP_TAC THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP (SET_RULE + `(!x y. f x = f y ==> x = y) ==> (!x s. f x IN IMAGE f s <=> x IN s)`)) THEN + ASM_REWRITE_TAC[] THEN + MP_TAC(ISPEC `f:real^M->real^N` LINEAR_BOUNDED_POS) THEN + MP_TAC(ISPEC `f:real^M->real^N` LINEAR_INJECTIVE_BOUNDED_BELOW_POS) THEN + ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `B2:real` THEN STRIP_TAC THEN + X_GEN_TAC `B1:real` THEN STRIP_TAC THEN + AP_TERM_TAC THEN AP_TERM_TAC THEN + GEN_REWRITE_TAC I [FUN_EQ_THM] THEN X_GEN_TAC `x:real^M` THEN + REWRITE_TAC[] THEN AP_TERM_TAC THEN + FIRST_ASSUM(ASSUME_TAC o GSYM o MATCH_MP LINEAR_SUB) THEN + ASM_REWRITE_TAC[dist; IMP_IMP] THEN EQ_TAC THEN + DISCH_THEN(X_CHOOSE_THEN `e:real` STRIP_ASSUME_TAC) THENL + [EXISTS_TAC `e / B1:real`; EXISTS_TAC `e * B2:real`] THEN + ASM_SIMP_TAC[REAL_LT_MUL; REAL_LT_DIV] THEN + REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[] THENL + [MATCH_MP_TAC(REAL_ARITH + `norm(f x) <= B1 * norm(x) /\ norm(x) * B1 < e ==> norm(f x) < e`) THEN + ASM_SIMP_TAC[GSYM REAL_LT_RDIV_EQ]; + MATCH_MP_TAC(REAL_ARITH + `norm x <= norm (f x :real^N) / B2 /\ norm(f x) / B2 < e + ==> norm x < e`) THEN + ASM_SIMP_TAC[REAL_LE_RDIV_EQ; REAL_LT_LDIV_EQ]]);; + +add_linear_invariants [OPEN_IN_INJECTIVE_LINEAR_IMAGE];; + +let CLOSED_IN_INJECTIVE_LINEAR_IMAGE = prove + (`!f:real^M->real^N s t. + linear f /\ (!x y. f x = f y ==> x = y) + ==> (closed_in (subtopology euclidean (IMAGE f t)) (IMAGE f s) <=> + closed_in (subtopology euclidean t) s)`, + REWRITE_TAC[closed_in; TOPSPACE_EUCLIDEAN_SUBTOPOLOGY] THEN + GEOM_TRANSFORM_TAC[]);; + +add_linear_invariants [CLOSED_IN_INJECTIVE_LINEAR_IMAGE];; + +(* ------------------------------------------------------------------------- *) +(* Connectedness. *) +(* ------------------------------------------------------------------------- *) + +let connected = new_definition + `connected s <=> + ~(?e1 e2. open e1 /\ open e2 /\ s SUBSET (e1 UNION e2) /\ + (e1 INTER e2 INTER s = {}) /\ + ~(e1 INTER s = {}) /\ ~(e2 INTER s = {}))`;; + +let CONNECTED_CLOSED = prove + (`!s:real^N->bool. + connected s <=> + ~(?e1 e2. closed e1 /\ closed e2 /\ s SUBSET (e1 UNION e2) /\ + (e1 INTER e2 INTER s = {}) /\ + ~(e1 INTER s = {}) /\ ~(e2 INTER s = {}))`, + GEN_TAC THEN REWRITE_TAC[connected] THEN AP_TERM_TAC THEN + EQ_TAC THEN REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`u:real^N->bool`; `v:real^N->bool`] THEN STRIP_TAC THEN + MAP_EVERY EXISTS_TAC [`(:real^N) DIFF v`; `(:real^N) DIFF u`] THEN + ASM_REWRITE_TAC[GSYM closed; GSYM OPEN_CLOSED] THEN ASM SET_TAC[]);; + +let CONNECTED_OPEN_IN = prove + (`!s. connected s <=> + ~(?e1 e2. + open_in (subtopology euclidean s) e1 /\ + open_in (subtopology euclidean s) e2 /\ + s SUBSET e1 UNION e2 /\ + e1 INTER e2 = {} /\ + ~(e1 = {}) /\ + ~(e2 = {}))`, + GEN_TAC THEN REWRITE_TAC[connected; OPEN_IN_OPEN] THEN + REWRITE_TAC[LEFT_AND_EXISTS_THM; RIGHT_AND_EXISTS_THM] THEN + CONV_TAC(ONCE_DEPTH_CONV UNWIND_CONV) THEN + AP_TERM_TAC THEN REPEAT(AP_TERM_TAC THEN ABS_TAC) THEN + SET_TAC[]);; + +let CONNECTED_OPEN_IN_EQ = prove + (`!s. connected s <=> + ~(?e1 e2. + open_in (subtopology euclidean s) e1 /\ + open_in (subtopology euclidean s) e2 /\ + e1 UNION e2 = s /\ e1 INTER e2 = {} /\ + ~(e1 = {}) /\ ~(e2 = {}))`, + GEN_TAC THEN REWRITE_TAC[CONNECTED_OPEN_IN] THEN + AP_TERM_TAC THEN REPEAT(AP_TERM_TAC THEN ABS_TAC) THEN + EQ_TAC THEN STRIP_TAC THEN ASM_REWRITE_TAC[SUBSET_REFL] THEN + RULE_ASSUM_TAC(REWRITE_RULE[OPEN_IN_CLOSED_IN_EQ; + TOPSPACE_EUCLIDEAN_SUBTOPOLOGY]) THEN + ASM SET_TAC[]);; + +let CONNECTED_CLOSED_IN = prove + (`!s. connected s <=> + ~(?e1 e2. + closed_in (subtopology euclidean s) e1 /\ + closed_in (subtopology euclidean s) e2 /\ + s SUBSET e1 UNION e2 /\ + e1 INTER e2 = {} /\ + ~(e1 = {}) /\ + ~(e2 = {}))`, + GEN_TAC THEN REWRITE_TAC[CONNECTED_CLOSED; CLOSED_IN_CLOSED] THEN + REWRITE_TAC[LEFT_AND_EXISTS_THM; RIGHT_AND_EXISTS_THM] THEN + CONV_TAC(ONCE_DEPTH_CONV UNWIND_CONV) THEN + AP_TERM_TAC THEN REPEAT(AP_TERM_TAC THEN ABS_TAC) THEN + SET_TAC[]);; + +let CONNECTED_CLOSED_IN_EQ = prove + (`!s. connected s <=> + ~(?e1 e2. + closed_in (subtopology euclidean s) e1 /\ + closed_in (subtopology euclidean s) e2 /\ + + e1 UNION e2 = s /\ e1 INTER e2 = {} /\ + ~(e1 = {}) /\ ~(e2 = {}))`, + GEN_TAC THEN REWRITE_TAC[CONNECTED_CLOSED_IN] THEN + AP_TERM_TAC THEN REPEAT(AP_TERM_TAC THEN ABS_TAC) THEN + EQ_TAC THEN STRIP_TAC THEN ASM_REWRITE_TAC[SUBSET_REFL] THEN + RULE_ASSUM_TAC(REWRITE_RULE[closed_in; TOPSPACE_EUCLIDEAN_SUBTOPOLOGY]) THEN + ASM SET_TAC[]);; + +let CONNECTED_CLOPEN = prove + (`!s. connected s <=> + !t. open_in (subtopology euclidean s) t /\ + closed_in (subtopology euclidean s) t ==> t = {} \/ t = s`, + GEN_TAC THEN REWRITE_TAC[connected; OPEN_IN_OPEN; CLOSED_IN_CLOSED] THEN + GEN_REWRITE_TAC (LAND_CONV o RAND_CONV o BINDER_CONV) [GSYM EXISTS_DIFF] THEN + ONCE_REWRITE_TAC[TAUT `(~a <=> b) <=> (a <=> ~b)`] THEN + REWRITE_TAC[NOT_FORALL_THM; NOT_IMP; GSYM CONJ_ASSOC; DE_MORGAN_THM] THEN + ONCE_REWRITE_TAC[TAUT `a /\ b /\ c /\ d <=> b /\ a /\ c /\ d`] THEN + REWRITE_TAC[LEFT_AND_EXISTS_THM] THEN REWRITE_TAC[GSYM closed] THEN + ONCE_REWRITE_TAC[SWAP_EXISTS_THM] THEN AP_TERM_TAC THEN ABS_TAC THEN + REWRITE_TAC[LEFT_AND_EXISTS_THM; RIGHT_AND_EXISTS_THM] THEN + ONCE_REWRITE_TAC[SWAP_EXISTS_THM] THEN AP_TERM_TAC THEN ABS_TAC THEN + REWRITE_TAC[TAUT `(a /\ b) /\ (c /\ d) /\ e <=> a /\ c /\ b /\ d /\ e`] THEN + REWRITE_TAC[RIGHT_EXISTS_AND_THM; UNWIND_THM2] THEN + AP_TERM_TAC THEN AP_TERM_TAC THEN SET_TAC[]);; + +let CONNECTED_CLOSED_SET = prove + (`!s:real^N->bool. + closed s + ==> (connected s <=> + ~(?e1 e2. closed e1 /\ closed e2 /\ ~(e1 = {}) /\ ~(e2 = {}) /\ + e1 UNION e2 = s /\ e1 INTER e2 = {}))`, + REPEAT STRIP_TAC THEN EQ_TAC THENL + [REWRITE_TAC[CONNECTED_CLOSED; CONTRAPOS_THM] THEN + REPEAT(MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC) THEN + SIMP_TAC[] THEN SET_TAC[]; + REWRITE_TAC[CONNECTED_CLOSED_IN; CONTRAPOS_THM; LEFT_IMP_EXISTS_THM] THEN + REWRITE_TAC[CLOSED_IN_CLOSED; LEFT_IMP_EXISTS_THM; IMP_CONJ] THEN + REWRITE_TAC[RIGHT_IMP_FORALL_THM] THEN REWRITE_TAC[IMP_IMP] THEN + MAP_EVERY X_GEN_TAC + [`e1:real^N->bool`; `e2:real^N->bool`; + `u:real^N->bool`; `v:real^N->bool`] THEN + STRIP_TAC THEN MAP_EVERY (C UNDISCH_THEN SUBST_ALL_TAC) + [`e1:real^N->bool = s INTER u`; + `e2:real^N->bool = s INTER v`] THEN + MAP_EVERY EXISTS_TAC + [`s INTER u:real^N->bool`; `s INTER v:real^N->bool`] THEN + ASM_SIMP_TAC[CLOSED_INTER] THEN ASM SET_TAC[]]);; + +let CONNECTED_OPEN_SET = prove + (`!s:real^N->bool. + open s + ==> (connected s <=> + ~(?e1 e2. open e1 /\ open e2 /\ ~(e1 = {}) /\ ~(e2 = {}) /\ + e1 UNION e2 = s /\ e1 INTER e2 = {}))`, + REPEAT STRIP_TAC THEN EQ_TAC THENL + [REWRITE_TAC[connected; CONTRAPOS_THM] THEN + REPEAT(MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC) THEN + SIMP_TAC[] THEN SET_TAC[]; + REWRITE_TAC[CONNECTED_OPEN_IN; CONTRAPOS_THM; LEFT_IMP_EXISTS_THM] THEN + REWRITE_TAC[OPEN_IN_OPEN; LEFT_IMP_EXISTS_THM; IMP_CONJ] THEN + REWRITE_TAC[RIGHT_IMP_FORALL_THM] THEN REWRITE_TAC[IMP_IMP] THEN + MAP_EVERY X_GEN_TAC + [`e1:real^N->bool`; `e2:real^N->bool`; + `u:real^N->bool`; `v:real^N->bool`] THEN + STRIP_TAC THEN MAP_EVERY (C UNDISCH_THEN SUBST_ALL_TAC) + [`e1:real^N->bool = s INTER u`; + `e2:real^N->bool = s INTER v`] THEN + MAP_EVERY EXISTS_TAC + [`s INTER u:real^N->bool`; `s INTER v:real^N->bool`] THEN + ASM_SIMP_TAC[OPEN_INTER] THEN ASM SET_TAC[]]);; + +let CONNECTED_EMPTY = prove + (`connected {}`, + REWRITE_TAC[connected; INTER_EMPTY]);; + +let CONNECTED_SING = prove + (`!a. connected{a}`, + REWRITE_TAC[connected] THEN SET_TAC[]);; + +let CONNECTED_UNIONS = prove + (`!P:(real^N->bool)->bool. + (!s. s IN P ==> connected s) /\ ~(INTERS P = {}) + ==> connected(UNIONS P)`, + GEN_TAC THEN REWRITE_TAC[connected; NOT_EXISTS_THM] THEN STRIP_TAC THEN + MAP_EVERY X_GEN_TAC [`e1:real^N->bool`; `e2:real^N->bool`] THEN + STRIP_TAC THEN UNDISCH_TAC `~(INTERS P :real^N->bool = {})` THEN + PURE_REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; IN_INTERS] THEN + DISCH_THEN(X_CHOOSE_THEN `a:real^N` STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN `(a:real^N) IN e1 \/ a IN e2` STRIP_ASSUME_TAC THENL + [ASM SET_TAC[]; + UNDISCH_TAC `~(e2 INTER UNIONS P:real^N->bool = {})`; + UNDISCH_TAC `~(e1 INTER UNIONS P:real^N->bool = {})`] THEN + PURE_REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; IN_INTER; IN_UNIONS] THEN + DISCH_THEN(X_CHOOSE_THEN `b:real^N` + (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + DISCH_THEN(X_CHOOSE_THEN `s:real^N->bool` STRIP_ASSUME_TAC) THEN + UNDISCH_TAC `!t:real^N->bool. t IN P ==> a IN t` THEN + DISCH_THEN(MP_TAC o SPEC `s:real^N->bool`) THEN + ASM_REWRITE_TAC[] THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `s:real^N->bool`) THEN + ASM_REWRITE_TAC[] THEN + DISCH_THEN(MP_TAC o SPECL [`e1:real^N->bool`; `e2:real^N->bool`]) THEN + ASM SET_TAC[]);; + +let CONNECTED_UNION = prove + (`!s t:real^N->bool. + connected s /\ connected t /\ ~(s INTER t = {}) + ==> connected (s UNION t)`, + REWRITE_TAC[GSYM UNIONS_2; GSYM INTERS_2] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC CONNECTED_UNIONS THEN + ASM SET_TAC[]);; + +let CONNECTED_DIFF_OPEN_FROM_CLOSED = prove + (`!s t u:real^N->bool. + s SUBSET t /\ t SUBSET u /\ + open s /\ closed t /\ connected u /\ connected(t DIFF s) + ==> connected(u DIFF s)`, + REPEAT STRIP_TAC THEN REWRITE_TAC[connected; NOT_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`v:real^N->bool`; `w:real^N->bool`] THEN STRIP_TAC THEN + UNDISCH_TAC `connected(t DIFF s:real^N->bool)` THEN SIMP_TAC[connected] THEN + MAP_EVERY EXISTS_TAC [`v:real^N->bool`; `w:real^N->bool`] THEN + ASM_REWRITE_TAC[] THEN + REPLICATE_TAC 2 (CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC]) THEN + POP_ASSUM_LIST(MP_TAC o end_itlist CONJ) THEN + MAP_EVERY (fun t -> SPEC_TAC(t,t)) [`v:real^N->bool`; `w:real^N->bool`] THEN + MATCH_MP_TAC(MESON[] + `(!v w. P v w ==> P w v) /\ (!w v. P v w /\ Q w ==> F) + ==> !w v. P v w ==> ~(Q v) /\ ~(Q w)`) THEN + CONJ_TAC THENL [SIMP_TAC[CONJ_ACI; INTER_ACI; UNION_ACI]; ALL_TAC] THEN + REPEAT STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [connected]) THEN SIMP_TAC[] THEN + MAP_EVERY EXISTS_TAC [`v UNION s:real^N->bool`; `w DIFF t:real^N->bool`] THEN + ASM_SIMP_TAC[OPEN_UNION; OPEN_DIFF] THEN ASM SET_TAC[]);; + +let CONNECTED_DISJOINT_UNIONS_OPEN_UNIQUE = prove + (`!f:(real^N->bool)->bool f'. + pairwise DISJOINT f /\ pairwise DISJOINT f' /\ + (!s. s IN f ==> open s /\ connected s /\ ~(s = {})) /\ + (!s. s IN f' ==> open s /\ connected s /\ ~(s = {})) /\ + UNIONS f = UNIONS f' + ==> f = f'`, + GEN_REWRITE_TAC (funpow 2 BINDER_CONV o RAND_CONV) [EXTENSION] THEN + MATCH_MP_TAC(MESON[] + `(!s t. P s t ==> P t s) /\ (!s t x. P s t /\ x IN s ==> x IN t) + ==> (!s t. P s t ==> (!x. x IN s <=> x IN t))`) THEN + CONJ_TAC THENL [MESON_TAC[]; ALL_TAC] THEN + GEN_TAC THEN GEN_TAC THEN X_GEN_TAC `s:real^N->bool` THEN STRIP_TAC THEN + SUBGOAL_THEN + `?t a:real^N. t IN f' /\ a IN s /\ a IN t` STRIP_ASSUME_TAC + THENL [ASM SET_TAC[]; ALL_TAC] THEN + SUBGOAL_THEN `s:real^N->bool = t` (fun th -> ASM_REWRITE_TAC[th]) THEN + REWRITE_TAC[EXTENSION] THEN POP_ASSUM_LIST(MP_TAC o end_itlist CONJ) THEN + MAP_EVERY (fun t -> SPEC_TAC(t,t)) + [`s:real^N->bool`; `t:real^N->bool`; + `f:(real^N->bool)->bool`; `f':(real^N->bool)->bool`] THEN + MATCH_MP_TAC(MESON[] + `(!f f' s t. P f f' s t ==> P f' f t s) /\ + (!f f' s t x. P f f' s t /\ x IN s ==> x IN t) + ==> (!f' f t s. P f f' s t ==> (!x. x IN s <=> x IN t))`) THEN + CONJ_TAC THENL [MESON_TAC[]; ALL_TAC] THEN + REPLICATE_TAC 4 GEN_TAC THEN X_GEN_TAC `b:real^N` THEN STRIP_TAC THEN + UNDISCH_TAC + `!s:real^N->bool. s IN f ==> open s /\ connected s /\ ~(s = {})` THEN + DISCH_THEN(MP_TAC o SPEC `s:real^N->bool`) THEN ASM_REWRITE_TAC[] THEN + STRIP_TAC THEN ASM_CASES_TAC `(b:real^N) IN t` THEN + ASM_REWRITE_TAC[] THEN + UNDISCH_TAC `connected(s:real^N->bool)` THEN + REWRITE_TAC[connected] THEN + MAP_EVERY EXISTS_TAC + [`t:real^N->bool`; `UNIONS(f' DELETE (t:real^N->bool))`] THEN + REPEAT STRIP_TAC THENL + [ASM_SIMP_TAC[]; + MATCH_MP_TAC OPEN_UNIONS THEN ASM_SIMP_TAC[IN_DELETE]; + REWRITE_TAC[GSYM UNIONS_INSERT] THEN ASM SET_TAC[]; + MATCH_MP_TAC(SET_RULE `t INTER u = {} ==> t INTER u INTER s = {}`) THEN + REWRITE_TAC[INTER_UNIONS; EMPTY_UNIONS; FORALL_IN_GSPEC] THEN + REWRITE_TAC[IN_DELETE; GSYM DISJOINT] THEN ASM_MESON_TAC[pairwise]; + ASM SET_TAC[]; + ASM SET_TAC[]]);; + +(* ------------------------------------------------------------------------- *) +(* Sort of induction principle for connected sets. *) +(* ------------------------------------------------------------------------- *) + +let CONNECTED_INDUCTION = prove + (`!P Q s:real^N->bool. + connected s /\ + (!t a. open_in (subtopology euclidean s) t /\ a IN t + ==> ?z. z IN t /\ P z) /\ + (!a. a IN s + ==> ?t. open_in (subtopology euclidean s) t /\ a IN t /\ + !x y. x IN t /\ y IN t /\ P x /\ P y /\ Q x ==> Q y) + ==> !a b. a IN s /\ b IN s /\ P a /\ P b /\ Q a ==> Q b`, + REPEAT STRIP_TAC THEN + GEN_REWRITE_TAC I [TAUT `p <=> ~ ~p`] THEN DISCH_TAC THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [CONNECTED_OPEN_IN]) THEN + REWRITE_TAC[] THEN MAP_EVERY EXISTS_TAC + [`{b:real^N | ?t. open_in (subtopology euclidean s) t /\ b IN t /\ + !x. x IN t /\ P x ==> Q x}`; + `{b:real^N | ?t. open_in (subtopology euclidean s) t /\ b IN t /\ + !x. x IN t /\ P x ==> ~(Q x)}`] THEN + REPEAT CONJ_TAC THENL + [ONCE_REWRITE_TAC[OPEN_IN_SUBOPEN] THEN + X_GEN_TAC `c:real^N` THEN REWRITE_TAC[IN_ELIM_THM] THEN + MATCH_MP_TAC MONO_EXISTS THEN ASM SET_TAC[]; + ONCE_REWRITE_TAC[OPEN_IN_SUBOPEN] THEN + X_GEN_TAC `c:real^N` THEN REWRITE_TAC[IN_ELIM_THM] THEN + MATCH_MP_TAC MONO_EXISTS THEN ASM SET_TAC[]; + REWRITE_TAC[SUBSET; IN_ELIM_THM; IN_UNION] THEN + X_GEN_TAC `c:real^N` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `c:real^N`) THEN ASM SET_TAC[]; + REWRITE_TAC[EXTENSION; IN_INTER; NOT_IN_EMPTY; IN_ELIM_THM] THEN + X_GEN_TAC `c:real^N` THEN DISCH_THEN(CONJUNCTS_THEN2 + (X_CHOOSE_THEN `t:real^N->bool` STRIP_ASSUME_TAC) + (X_CHOOSE_THEN `u:real^N->bool` STRIP_ASSUME_TAC)) THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`t INTER u:real^N->bool`; `c:real^N`]) THEN + ASM_SIMP_TAC[OPEN_IN_INTER] THEN ASM SET_TAC[]; + ASM SET_TAC[]; + ASM SET_TAC[]]);; + +let CONNECTED_EQUIVALENCE_RELATION_GEN = prove + (`!P R s:real^N->bool. + connected s /\ + (!x y. R x y ==> R y x) /\ + (!x y z. R x y /\ R y z ==> R x z) /\ + (!t a. open_in (subtopology euclidean s) t /\ a IN t + ==> ?z. z IN t /\ P z) /\ + (!a. a IN s + ==> ?t. open_in (subtopology euclidean s) t /\ a IN t /\ + !x y. x IN t /\ y IN t /\ P x /\ P y ==> R x y) + ==> !a b. a IN s /\ b IN s /\ P a /\ P b ==> R a b`, + REPEAT GEN_TAC THEN STRIP_TAC THEN + SUBGOAL_THEN + `!a:real^N. a IN s /\ P a + ==> !b c. b IN s /\ c IN s /\ P b /\ P c /\ R a b ==> R a c` + MP_TAC THENL [ALL_TAC; ASM_MESON_TAC[]] THEN + GEN_TAC THEN DISCH_TAC THEN MATCH_MP_TAC CONNECTED_INDUCTION THEN + ASM_MESON_TAC[]);; + +let CONNECTED_INDUCTION_SIMPLE = prove + (`!P s:real^N->bool. + connected s /\ + (!a. a IN s + ==> ?t. open_in (subtopology euclidean s) t /\ a IN t /\ + !x y. x IN t /\ y IN t /\ P x ==> P y) + ==> !a b. a IN s /\ b IN s /\ P a ==> P b`, + MP_TAC(ISPEC `\x:real^N. T` CONNECTED_INDUCTION) THEN + REWRITE_TAC[] THEN + REPEAT(MATCH_MP_TAC MONO_FORALL THEN GEN_TAC) THEN MESON_TAC[]);; + +let CONNECTED_EQUIVALENCE_RELATION = prove + (`!R s:real^N->bool. + connected s /\ + (!x y. R x y ==> R y x) /\ + (!x y z. R x y /\ R y z ==> R x z) /\ + (!a. a IN s + ==> ?t. open_in (subtopology euclidean s) t /\ a IN t /\ + !x. x IN t ==> R a x) + ==> !a b. a IN s /\ b IN s ==> R a b`, + REPEAT GEN_TAC THEN STRIP_TAC THEN + SUBGOAL_THEN + `!a:real^N. a IN s ==> !b c. b IN s /\ c IN s /\ R a b ==> R a c` + MP_TAC THENL [ALL_TAC; ASM_MESON_TAC[]] THEN + GEN_TAC THEN DISCH_TAC THEN MATCH_MP_TAC CONNECTED_INDUCTION_SIMPLE THEN + ASM_MESON_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* Limit points. *) +(* ------------------------------------------------------------------------- *) + +parse_as_infix ("limit_point_of",(12,"right"));; + +let limit_point_of = new_definition + `x limit_point_of s <=> + !t. x IN t /\ open t ==> ?y. ~(y = x) /\ y IN s /\ y IN t`;; + +let LIMPT_SUBSET = prove + (`!x s t. x limit_point_of s /\ s SUBSET t ==> x limit_point_of t`, + REWRITE_TAC[limit_point_of; SUBSET] THEN MESON_TAC[]);; + +let LIMPT_APPROACHABLE = prove + (`!x s. x limit_point_of s <=> + !e. &0 < e ==> ?x'. x' IN s /\ ~(x' = x) /\ dist(x',x) < e`, + REPEAT GEN_TAC THEN REWRITE_TAC[limit_point_of] THEN + MESON_TAC[open_def; DIST_SYM; OPEN_BALL; CENTRE_IN_BALL; IN_BALL]);; + +let LIMPT_APPROACHABLE_LE = prove + (`!x s. x limit_point_of s <=> + !e. &0 < e ==> ?x'. x' IN s /\ ~(x' = x) /\ dist(x',x) <= e`, + REPEAT GEN_TAC THEN REWRITE_TAC[LIMPT_APPROACHABLE] THEN + MATCH_MP_TAC(TAUT `(~a <=> ~b) ==> (a <=> b)`) THEN + REWRITE_TAC[NOT_FORALL_THM; NOT_IMP; NOT_EXISTS_THM] THEN + REWRITE_TAC[TAUT `~(a /\ b /\ c) <=> c ==> ~(a /\ b)`; APPROACHABLE_LT_LE]);; + +let LIMPT_UNIV = prove + (`!x:real^N. x limit_point_of UNIV`, + GEN_TAC THEN REWRITE_TAC[LIMPT_APPROACHABLE; IN_UNIV] THEN + X_GEN_TAC `e:real` THEN DISCH_TAC THEN + SUBGOAL_THEN `?c:real^N. norm(c) = e / &2` CHOOSE_TAC THENL + [ASM_SIMP_TAC[VECTOR_CHOOSE_SIZE; REAL_HALF; REAL_LT_IMP_LE]; + ALL_TAC] THEN + EXISTS_TAC `x + c:real^N` THEN + REWRITE_TAC[dist; VECTOR_EQ_ADDR] THEN ASM_REWRITE_TAC[VECTOR_ADD_SUB] THEN + SUBGOAL_THEN `&0 < e / &2 /\ e / &2 < e` + (fun th -> ASM_MESON_TAC[th; NORM_0; REAL_LT_REFL]) THEN + SIMP_TAC[REAL_LT_LDIV_EQ; REAL_LT_RDIV_EQ; REAL_OF_NUM_LT; ARITH] THEN + UNDISCH_TAC `&0 < e` THEN REAL_ARITH_TAC);; + +let CLOSED_LIMPT = prove + (`!s. closed s <=> !x. x limit_point_of s ==> x IN s`, + REWRITE_TAC[closed] THEN ONCE_REWRITE_TAC[OPEN_SUBOPEN] THEN + REWRITE_TAC[limit_point_of; IN_DIFF; IN_UNIV; SUBSET] THEN MESON_TAC[]);; + +let LIMPT_EMPTY = prove + (`!x. ~(x limit_point_of {})`, + REWRITE_TAC[LIMPT_APPROACHABLE; NOT_IN_EMPTY] THEN MESON_TAC[REAL_LT_01]);; + +let NO_LIMIT_POINT_IMP_CLOSED = prove + (`!s. ~(?x. x limit_point_of s) ==> closed s`, + MESON_TAC[CLOSED_LIMPT]);; + +let CLOSED_POSITIVE_ORTHANT = prove + (`closed {x:real^N | !i. 1 <= i /\ i <= dimindex(:N) + ==> &0 <= x$i}`, + REWRITE_TAC[CLOSED_LIMPT; LIMPT_APPROACHABLE] THEN + REWRITE_TAC[IN_ELIM_THM] THEN X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN + X_GEN_TAC `i:num` THEN STRIP_TAC THEN REWRITE_TAC[GSYM REAL_NOT_LT] THEN + DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC `--(x:real^N $ i)`) THEN + ASM_REWRITE_TAC[REAL_LT_RNEG; REAL_ADD_LID; NOT_EXISTS_THM] THEN + X_GEN_TAC `y:real^N` THEN + MATCH_MP_TAC(TAUT `(a ==> ~c) ==> ~(a /\ b /\ c)`) THEN DISCH_TAC THEN + MATCH_MP_TAC(REAL_ARITH `!b. abs x <= b /\ b <= a ==> ~(a + x < &0)`) THEN + EXISTS_TAC `abs((y - x :real^N)$i)` THEN + ASM_SIMP_TAC[dist; COMPONENT_LE_NORM] THEN + ASM_SIMP_TAC[VECTOR_SUB_COMPONENT; REAL_ARITH + `x < &0 /\ &0 <= y ==> abs(x) <= abs(y - x)`]);; + +let FINITE_SET_AVOID = prove + (`!a:real^N s. FINITE s + ==> ?d. &0 < d /\ !x. x IN s /\ ~(x = a) ==> d <= dist(a,x)`, + GEN_TAC THEN MATCH_MP_TAC FINITE_INDUCT_STRONG THEN + REWRITE_TAC[NOT_IN_EMPTY] THEN + CONJ_TAC THENL [MESON_TAC[REAL_LT_01]; ALL_TAC] THEN + MAP_EVERY X_GEN_TAC [`x:real^N`; `s:real^N->bool`] THEN + DISCH_THEN(REPEAT_TCL CONJUNCTS_THEN ASSUME_TAC) THEN + FIRST_X_ASSUM(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC) THEN + ASM_CASES_TAC `x:real^N = a` THEN REWRITE_TAC[IN_INSERT] THENL + [ASM_MESON_TAC[]; ALL_TAC] THEN + EXISTS_TAC `min d (dist(a:real^N,x))` THEN + ASM_REWRITE_TAC[REAL_LT_MIN; GSYM DIST_NZ; REAL_MIN_LE] THEN + ASM_MESON_TAC[REAL_LE_REFL]);; + +let LIMIT_POINT_FINITE = prove + (`!s a. FINITE s ==> ~(a limit_point_of s)`, + REWRITE_TAC[LIMPT_APPROACHABLE; GSYM REAL_NOT_LE] THEN + REWRITE_TAC[NOT_FORALL_THM; NOT_IMP; NOT_EXISTS_THM; REAL_NOT_LE; + REAL_NOT_LT; TAUT `~(a /\ b /\ c) <=> a /\ b ==> ~c`] THEN + MESON_TAC[FINITE_SET_AVOID; DIST_SYM]);; + +let LIMPT_SING = prove + (`!x y:real^N. ~(x limit_point_of {y})`, + SIMP_TAC[LIMIT_POINT_FINITE; FINITE_SING]);; + +let LIMIT_POINT_UNION = prove + (`!s t x:real^N. x limit_point_of (s UNION t) <=> + x limit_point_of s \/ x limit_point_of t`, + REPEAT GEN_TAC THEN EQ_TAC THENL + [ALL_TAC; MESON_TAC[LIMPT_SUBSET; SUBSET_UNION]] THEN + REWRITE_TAC[LIMPT_APPROACHABLE; IN_UNION] THEN DISCH_TAC THEN + MATCH_MP_TAC(TAUT `(~a ==> b) ==> a \/ b`) THEN + REWRITE_TAC[NOT_FORALL_THM; LEFT_IMP_EXISTS_THM; NOT_IMP] THEN + X_GEN_TAC `e:real` THEN STRIP_TAC THEN X_GEN_TAC `d:real` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `min d e`) THEN ASM_REWRITE_TAC[REAL_LT_MIN] THEN + ASM_MESON_TAC[]);; + +let LIMPT_INSERT = prove + (`!s x y:real^N. x limit_point_of (y INSERT s) <=> x limit_point_of s`, + ONCE_REWRITE_TAC[SET_RULE `y INSERT s = {y} UNION s`] THEN + REWRITE_TAC[LIMIT_POINT_UNION] THEN + SIMP_TAC[FINITE_SING; LIMIT_POINT_FINITE]);; + +let LIMPT_OF_LIMPTS = prove + (`!x:real^N s. + x limit_point_of {y | y limit_point_of s} ==> x limit_point_of s`, + REWRITE_TAC[LIMPT_APPROACHABLE; IN_ELIM_THM] THEN REPEAT GEN_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 + DISCH_THEN(X_CHOOSE_THEN `y:real^N` STRIP_ASSUME_TAC) THEN + FIRST_X_ASSUM(MP_TAC o SPEC `dist(y:real^N,x)`) THEN + ASM_SIMP_TAC[DIST_POS_LT] THEN MATCH_MP_TAC MONO_EXISTS THEN + GEN_TAC THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + REPEAT(POP_ASSUM MP_TAC) THEN NORM_ARITH_TAC);; + +let CLOSED_LIMPTS = prove + (`!s. closed {x:real^N | x limit_point_of s}`, + REWRITE_TAC[CLOSED_LIMPT; IN_ELIM_THM; LIMPT_OF_LIMPTS]);; + +let DISCRETE_IMP_CLOSED = prove + (`!s:real^N->bool e. + &0 < e /\ + (!x y. x IN s /\ y IN s /\ norm(y - x) < e ==> y = x) + ==> closed s`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN `!x:real^N. ~(x limit_point_of s)` + (fun th -> MESON_TAC[th; CLOSED_LIMPT]) THEN + GEN_TAC THEN REWRITE_TAC[LIMPT_APPROACHABLE] THEN DISCH_TAC THEN + FIRST_ASSUM(MP_TAC o SPEC `e / &2`) THEN + REWRITE_TAC[REAL_HALF; ASSUME `&0 < e`] THEN + DISCH_THEN(X_CHOOSE_THEN `y:real^N` STRIP_ASSUME_TAC) THEN + FIRST_X_ASSUM(MP_TAC o SPEC `min (e / &2) (dist(x:real^N,y))`) THEN + ASM_SIMP_TAC[REAL_LT_MIN; DIST_POS_LT; REAL_HALF] THEN + DISCH_THEN(X_CHOOSE_THEN `z:real^N` STRIP_ASSUME_TAC) THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`y:real^N`; `z:real^N`]) THEN + ASM_REWRITE_TAC[] THEN ASM_NORM_ARITH_TAC);; + +let LIMPT_OF_UNIV = prove + (`!x. x limit_point_of (:real^N)`, + GEN_TAC THEN REWRITE_TAC[LIMPT_APPROACHABLE; IN_UNIV] THEN + X_GEN_TAC `e:real` THEN DISCH_TAC THEN + MP_TAC(ISPECL [`x:real^N`; `e / &2`] VECTOR_CHOOSE_DIST) THEN + ANTS_TAC THENL [ASM_REAL_ARITH_TAC; MATCH_MP_TAC MONO_EXISTS] THEN + POP_ASSUM MP_TAC THEN CONV_TAC NORM_ARITH);; + +let LIMPT_OF_OPEN_IN = prove + (`!s t x:real^N. + open_in (subtopology euclidean s) t /\ x limit_point_of s /\ x IN t + ==> x limit_point_of t`, + REWRITE_TAC[open_in; SUBSET; LIMPT_APPROACHABLE] THEN + REPEAT GEN_TAC THEN STRIP_TAC THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `x:real^N`) THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC) THEN + FIRST_X_ASSUM(MP_TAC o SPEC `min d e / &2`) THEN + ANTS_TAC THENL [ASM_REAL_ARITH_TAC; MATCH_MP_TAC MONO_EXISTS] THEN + GEN_TAC THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN CONJ_TAC THEN + TRY(FIRST_X_ASSUM MATCH_MP_TAC) THEN ASM_REWRITE_TAC[] THEN + ASM_REAL_ARITH_TAC);; + +let LIMPT_OF_OPEN = prove + (`!s x:real^N. open s /\ x IN s ==> x limit_point_of s`, + REWRITE_TAC[OPEN_IN] THEN ONCE_REWRITE_TAC[GSYM SUBTOPOLOGY_UNIV] THEN + MESON_TAC[LIMPT_OF_OPEN_IN; LIMPT_OF_UNIV]);; + +let OPEN_IN_SING = prove + (`!s a. open_in (subtopology euclidean s) {a} <=> + a IN s /\ ~(a limit_point_of s)`, + REWRITE_TAC[open_in; LIMPT_APPROACHABLE; SING_SUBSET; IN_SING] THEN + REWRITE_TAC[FORALL_UNWIND_THM2] THEN MESON_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* Interior of a set. *) +(* ------------------------------------------------------------------------- *) + +let interior = new_definition + `interior s = {x | ?t. open t /\ x IN t /\ t SUBSET s}`;; + +let INTERIOR_EQ = prove + (`!s. (interior s = s) <=> open s`, + GEN_TAC THEN REWRITE_TAC[EXTENSION; interior; IN_ELIM_THM] THEN + GEN_REWRITE_TAC RAND_CONV [OPEN_SUBOPEN] THEN MESON_TAC[SUBSET]);; + +let INTERIOR_OPEN = prove + (`!s. open s ==> (interior s = s)`, + MESON_TAC[INTERIOR_EQ]);; + +let INTERIOR_EMPTY = prove + (`interior {} = {}`, + SIMP_TAC[INTERIOR_OPEN; OPEN_EMPTY]);; + +let INTERIOR_UNIV = prove + (`interior(:real^N) = (:real^N)`, + SIMP_TAC[INTERIOR_OPEN; OPEN_UNIV]);; + +let OPEN_INTERIOR = prove + (`!s. open(interior s)`, + GEN_TAC THEN REWRITE_TAC[interior] THEN GEN_REWRITE_TAC I [OPEN_SUBOPEN] THEN + REWRITE_TAC[SUBSET; IN_ELIM_THM] THEN MESON_TAC[]);; + +let INTERIOR_INTERIOR = prove + (`!s. interior(interior s) = interior s`, + MESON_TAC[INTERIOR_EQ; OPEN_INTERIOR]);; + +let INTERIOR_SUBSET = prove + (`!s. (interior s) SUBSET s`, + REWRITE_TAC[SUBSET; interior; IN_ELIM_THM] THEN MESON_TAC[]);; + +let SUBSET_INTERIOR = prove + (`!s t. s SUBSET t ==> (interior s) SUBSET (interior t)`, + REWRITE_TAC[interior; SUBSET; IN_ELIM_THM] THEN MESON_TAC[]);; + +let INTERIOR_MAXIMAL = prove + (`!s t. t SUBSET s /\ open t ==> t SUBSET (interior s)`, + REWRITE_TAC[interior; SUBSET; IN_ELIM_THM] THEN MESON_TAC[]);; + +let INTERIOR_MAXIMAL_EQ = prove + (`!s t:real^N->bool. open s ==> (s SUBSET interior t <=> s SUBSET t)`, + MESON_TAC[INTERIOR_MAXIMAL; SUBSET_TRANS; INTERIOR_SUBSET]);; + +let INTERIOR_UNIQUE = prove + (`!s t. t SUBSET s /\ open t /\ (!t'. t' SUBSET s /\ open t' ==> t' SUBSET t) + ==> (interior s = t)`, + MESON_TAC[SUBSET_ANTISYM; INTERIOR_MAXIMAL; INTERIOR_SUBSET; + OPEN_INTERIOR]);; + +let IN_INTERIOR = prove + (`!x s. x IN interior s <=> ?e. &0 < e /\ ball(x,e) SUBSET s`, + REWRITE_TAC[interior; IN_ELIM_THM] THEN + MESON_TAC[OPEN_CONTAINS_BALL; SUBSET_TRANS; CENTRE_IN_BALL; OPEN_BALL]);; + +let OPEN_SUBSET_INTERIOR = prove + (`!s t. open s ==> (s SUBSET interior t <=> s SUBSET t)`, + MESON_TAC[INTERIOR_MAXIMAL; INTERIOR_SUBSET; SUBSET_TRANS]);; + +let INTERIOR_INTER = prove + (`!s t:real^N->bool. interior(s INTER t) = interior s INTER interior t`, + REPEAT GEN_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL + [REWRITE_TAC[SUBSET_INTER] THEN CONJ_TAC THEN + MATCH_MP_TAC SUBSET_INTERIOR THEN REWRITE_TAC[INTER_SUBSET]; + MATCH_MP_TAC INTERIOR_MAXIMAL THEN SIMP_TAC[OPEN_INTER; OPEN_INTERIOR] THEN + MATCH_MP_TAC(SET_RULE + `s SUBSET s' /\ t SUBSET t' ==> s INTER t SUBSET s' INTER t'`) THEN + REWRITE_TAC[INTERIOR_SUBSET]]);; + +let INTERIOR_FINITE_INTERS = prove + (`!s:(real^N->bool)->bool. + FINITE s ==> interior(INTERS s) = INTERS(IMAGE interior s)`, + MATCH_MP_TAC FINITE_INDUCT_STRONG THEN + REWRITE_TAC[INTERS_0; INTERS_INSERT; INTERIOR_UNIV; IMAGE_CLAUSES] THEN + SIMP_TAC[INTERIOR_INTER]);; + +let INTERIOR_INTERS_SUBSET = prove + (`!f. interior(INTERS f) SUBSET INTERS (IMAGE interior f)`, + REWRITE_TAC[SUBSET; IN_INTERIOR; IN_INTERS; FORALL_IN_IMAGE] THEN + MESON_TAC[]);; + +let UNION_INTERIOR_SUBSET = prove + (`!s t:real^N->bool. + interior s UNION interior t SUBSET interior(s UNION t)`, + SIMP_TAC[INTERIOR_MAXIMAL_EQ; OPEN_UNION; OPEN_INTERIOR] THEN + REPEAT GEN_TAC THEN MATCH_MP_TAC(SET_RULE + `s SUBSET s' /\ t SUBSET t' ==> (s UNION t) SUBSET (s' UNION t')`) THEN + REWRITE_TAC[INTERIOR_SUBSET]);; + +let INTERIOR_EQ_EMPTY = prove + (`!s:real^N->bool. interior s = {} <=> !t. open t /\ t SUBSET s ==> t = {}`, + MESON_TAC[INTERIOR_MAXIMAL_EQ; SUBSET_EMPTY; + OPEN_INTERIOR; INTERIOR_SUBSET]);; + +let INTERIOR_EQ_EMPTY_ALT = prove + (`!s:real^N->bool. + interior s = {} <=> + !t. open t /\ ~(t = {}) ==> ~(t DIFF s = {})`, + GEN_TAC THEN REWRITE_TAC[INTERIOR_EQ_EMPTY] THEN SET_TAC[]);; + +let INTERIOR_LIMIT_POINT = prove + (`!s x:real^N. x IN interior s ==> x limit_point_of s`, + REPEAT GEN_TAC THEN + REWRITE_TAC[IN_INTERIOR; IN_ELIM_THM; SUBSET; IN_BALL] THEN + DISCH_THEN(X_CHOOSE_THEN `e:real` STRIP_ASSUME_TAC) THEN + REWRITE_TAC[LIMPT_APPROACHABLE] THEN X_GEN_TAC `d:real` THEN + DISCH_TAC THEN + MP_TAC(ISPECL [`x:real^N`; `min d e / &2`] VECTOR_CHOOSE_DIST) THEN + ANTS_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `y:real^N` THEN STRIP_TAC THEN + REPEAT CONJ_TAC THENL + [FIRST_X_ASSUM MATCH_MP_TAC; + CONV_TAC (RAND_CONV SYM_CONV) THEN REWRITE_TAC[GSYM DIST_EQ_0]; + ONCE_REWRITE_TAC[DIST_SYM]] THEN + ASM_REAL_ARITH_TAC);; + +let INTERIOR_SING = prove + (`!a:real^N. interior {a} = {}`, + REWRITE_TAC[EXTENSION; NOT_IN_EMPTY] THEN + MESON_TAC[INTERIOR_LIMIT_POINT; LIMPT_SING]);; + +let INTERIOR_CLOSED_UNION_EMPTY_INTERIOR = prove + (`!s t:real^N->bool. + closed(s) /\ interior(t) = {} + ==> interior(s UNION t) = interior(s)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN + SIMP_TAC[SUBSET_INTERIOR; SUBSET_UNION] THEN + REWRITE_TAC[SUBSET; IN_INTERIOR; IN_INTER; IN_UNION] THEN + X_GEN_TAC `x:real^N` THEN MATCH_MP_TAC MONO_EXISTS THEN + X_GEN_TAC `e:real` THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + X_GEN_TAC `y:real^N` THEN STRIP_TAC THEN + SUBGOAL_THEN `(y:real^N) limit_point_of s` + (fun th -> ASM_MESON_TAC[CLOSED_LIMPT; th]) THEN + REWRITE_TAC[IN_INTERIOR; NOT_IN_EMPTY; LIMPT_APPROACHABLE] THEN + X_GEN_TAC `d:real` THEN DISCH_TAC THEN + SUBGOAL_THEN + `?z:real^N. ~(z IN t) /\ ~(z = y) /\ dist(z,y) < d /\ dist(x,z) < e` + (fun th -> ASM_MESON_TAC[th; IN_BALL]) THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_BALL]) THEN + DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [EXTENSION]) THEN + REWRITE_TAC[IN_INTERIOR; NOT_IN_EMPTY; NOT_EXISTS_THM] THEN + ABBREV_TAC `k = min d (e - dist(x:real^N,y))` THEN + SUBGOAL_THEN `&0 < k` ASSUME_TAC THENL + [ASM_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `?w:real^N. dist(y,w) = k / &2` CHOOSE_TAC THENL + [ASM_SIMP_TAC[VECTOR_CHOOSE_DIST; REAL_HALF; REAL_LT_IMP_LE]; ALL_TAC] THEN + DISCH_THEN(MP_TAC o SPECL [`w:real^N`; `k / &4`]) THEN + ASM_SIMP_TAC[SUBSET; NOT_FORALL_THM; REAL_LT_DIV; REAL_OF_NUM_LT; ARITH; + NOT_IMP; IN_BALL] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `z:real^N` THEN + DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN ASM_REWRITE_TAC[] THEN + ASM_NORM_ARITH_TAC);; + +let INTERIOR_UNION_EQ_EMPTY = prove + (`!s t:real^N->bool. + closed s \/ closed t + ==> (interior(s UNION t) = {} <=> + interior s = {} /\ interior t = {})`, + REPEAT GEN_TAC THEN DISCH_TAC THEN EQ_TAC THENL + [ASM_MESON_TAC[SUBSET_UNION; SUBSET_INTERIOR; SUBSET_EMPTY]; + ASM_MESON_TAC[UNION_COMM; INTERIOR_CLOSED_UNION_EMPTY_INTERIOR]]);; + +let INTERIOR_UNIONS_OPEN_SUBSETS = prove + (`!s:real^N->bool. UNIONS {t | open t /\ t SUBSET s} = interior s`, + GEN_TAC THEN CONV_TAC SYM_CONV THEN MATCH_MP_TAC INTERIOR_UNIQUE THEN + SIMP_TAC[OPEN_UNIONS; IN_ELIM_THM] THEN SET_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* Closure of a set. *) +(* ------------------------------------------------------------------------- *) + +let closure = new_definition + `closure s = s UNION {x | x limit_point_of s}`;; + +let CLOSURE_INTERIOR = prove + (`!s:real^N->bool. closure s = UNIV DIFF (interior (UNIV DIFF s))`, + REWRITE_TAC[EXTENSION; closure; IN_UNION; IN_DIFF; IN_UNIV; interior; + IN_ELIM_THM; limit_point_of; SUBSET] THEN + MESON_TAC[]);; + +let INTERIOR_CLOSURE = prove + (`!s:real^N->bool. interior s = UNIV DIFF (closure (UNIV DIFF s))`, + let lemma = prove(`!s t. UNIV DIFF (UNIV DIFF t) = t`,SET_TAC[]) in + REWRITE_TAC[CLOSURE_INTERIOR; lemma]);; + +let CLOSED_CLOSURE = prove + (`!s. closed(closure s)`, + let lemma = prove(`UNIV DIFF (UNIV DIFF s) = s`,SET_TAC[]) in + REWRITE_TAC[closed; CLOSURE_INTERIOR; lemma; OPEN_INTERIOR]);; + +let CLOSURE_HULL = prove + (`!s. closure s = closed hull s`, + GEN_TAC THEN MATCH_MP_TAC(GSYM HULL_UNIQUE) THEN + REWRITE_TAC[CLOSED_CLOSURE; SUBSET] THEN + REWRITE_TAC[closure; IN_UNION; IN_ELIM_THM; CLOSED_LIMPT] THEN + MESON_TAC[limit_point_of]);; + +let CLOSURE_EQ = prove + (`!s. (closure s = s) <=> closed s`, + SIMP_TAC[CLOSURE_HULL; HULL_EQ; CLOSED_INTERS]);; + +let CLOSURE_CLOSED = prove + (`!s. closed s ==> (closure s = s)`, + MESON_TAC[CLOSURE_EQ]);; + +let CLOSURE_CLOSURE = prove + (`!s. closure(closure s) = closure s`, + REWRITE_TAC[CLOSURE_HULL; HULL_HULL]);; + +let CLOSURE_SUBSET = prove + (`!s. s SUBSET (closure s)`, + REWRITE_TAC[CLOSURE_HULL; HULL_SUBSET]);; + +let SUBSET_CLOSURE = prove + (`!s t. s SUBSET t ==> (closure s) SUBSET (closure t)`, + REWRITE_TAC[CLOSURE_HULL; HULL_MONO]);; + +let CLOSURE_UNION = prove + (`!s t:real^N->bool. closure(s UNION t) = closure s UNION closure t`, + REWRITE_TAC[LIMIT_POINT_UNION; closure] THEN SET_TAC[]);; + +let CLOSURE_INTER_SUBSET = prove + (`!s t. closure(s INTER t) SUBSET closure(s) INTER closure(t)`, + REPEAT GEN_TAC THEN REWRITE_TAC[SUBSET_INTER] THEN + CONJ_TAC THEN MATCH_MP_TAC SUBSET_CLOSURE THEN SET_TAC[]);; + +let CLOSURE_INTERS_SUBSET = prove + (`!f. closure(INTERS f) SUBSET INTERS(IMAGE closure f)`, + REWRITE_TAC[SET_RULE `s SUBSET INTERS f <=> !t. t IN f ==> s SUBSET t`] THEN + REWRITE_TAC[FORALL_IN_IMAGE] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC SUBSET_CLOSURE THEN ASM SET_TAC[]);; + +let CLOSURE_MINIMAL = prove + (`!s t. s SUBSET t /\ closed t ==> (closure s) SUBSET t`, + REWRITE_TAC[HULL_MINIMAL; CLOSURE_HULL]);; + +let CLOSURE_MINIMAL_EQ = prove + (`!s t:real^N->bool. closed t ==> (closure s SUBSET t <=> s SUBSET t)`, + MESON_TAC[SUBSET_TRANS; CLOSURE_SUBSET; CLOSURE_MINIMAL]);; + +let CLOSURE_UNIQUE = prove + (`!s t. s SUBSET t /\ closed t /\ + (!t'. s SUBSET t' /\ closed t' ==> t SUBSET t') + ==> (closure s = t)`, + REWRITE_TAC[CLOSURE_HULL; HULL_UNIQUE]);; + +let CLOSURE_EMPTY = prove + (`closure {} = {}`, + SIMP_TAC[CLOSURE_CLOSED; CLOSED_EMPTY]);; + +let CLOSURE_UNIV = prove + (`closure(:real^N) = (:real^N)`, + SIMP_TAC[CLOSURE_CLOSED; CLOSED_UNIV]);; + +let CLOSURE_UNIONS = prove + (`!f. FINITE f ==> closure(UNIONS f) = UNIONS {closure s | s IN f}`, + MATCH_MP_TAC FINITE_INDUCT_STRONG THEN + REWRITE_TAC[UNIONS_0; UNIONS_INSERT; SET_RULE `{f x | x IN {}} = {}`; + SET_RULE `{f x | x IN a INSERT s} = (f a) INSERT {f x | x IN s}`] THEN + SIMP_TAC[CLOSURE_EMPTY; CLOSURE_UNION]);; + +let CLOSURE_EQ_EMPTY = prove + (`!s. closure s = {} <=> s = {}`, + GEN_TAC THEN EQ_TAC THEN SIMP_TAC[CLOSURE_EMPTY] THEN + MATCH_MP_TAC(SET_RULE `s SUBSET t ==> t = {} ==> s = {}`) THEN + REWRITE_TAC[CLOSURE_SUBSET]);; + +let CLOSURE_SUBSET_EQ = prove + (`!s:real^N->bool. closure s SUBSET s <=> closed s`, + GEN_TAC THEN REWRITE_TAC[GSYM CLOSURE_EQ] THEN + MP_TAC(ISPEC `s:real^N->bool` CLOSURE_SUBSET) THEN SET_TAC[]);; + +let OPEN_INTER_CLOSURE_EQ_EMPTY = prove + (`!s t:real^N->bool. + open s ==> (s INTER (closure t) = {} <=> s INTER t = {})`, + REPEAT STRIP_TAC THEN EQ_TAC THENL + [MP_TAC(ISPEC `t:real^N->bool` CLOSURE_SUBSET) THEN SET_TAC[]; ALL_TAC] THEN + DISCH_TAC THEN REWRITE_TAC[CLOSURE_INTERIOR] THEN + MATCH_MP_TAC(SET_RULE `s SUBSET t ==> s INTER (UNIV DIFF t) = {}`) THEN + ASM_SIMP_TAC[OPEN_SUBSET_INTERIOR] THEN ASM SET_TAC[]);; + +let OPEN_INTER_CLOSURE_SUBSET = prove + (`!s t:real^N->bool. + open s ==> (s INTER (closure t)) SUBSET closure(s INTER t)`, + REPEAT STRIP_TAC THEN + SIMP_TAC[SUBSET; IN_INTER; closure; IN_UNION; IN_ELIM_THM] THEN + X_GEN_TAC `x:real^N` THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + DISJ2_TAC THEN REWRITE_TAC[LIMPT_APPROACHABLE] THEN + X_GEN_TAC `e:real` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [open_def]) THEN + DISCH_THEN(MP_TAC o SPEC `x:real^N`) THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC) THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [LIMPT_APPROACHABLE]) THEN + DISCH_THEN(MP_TAC o SPEC `min d e`) THEN + ASM_REWRITE_TAC[REAL_LT_MIN; IN_INTER] THEN + MATCH_MP_TAC MONO_EXISTS THEN ASM_MESON_TAC[]);; + +let CLOSURE_OPEN_INTER_SUPERSET = prove + (`!s t:real^N->bool. + open s /\ s SUBSET closure t ==> closure(s INTER t) = closure s`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN + SIMP_TAC[SUBSET_CLOSURE; INTER_SUBSET] THEN + MATCH_MP_TAC CLOSURE_MINIMAL THEN REWRITE_TAC[CLOSED_CLOSURE] THEN + W(MP_TAC o PART_MATCH (rand o rand) + OPEN_INTER_CLOSURE_SUBSET o rand o snd) THEN + ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] SUBSET_TRANS) THEN ASM SET_TAC[]);; + +let CLOSURE_COMPLEMENT = prove + (`!s:real^N->bool. closure(UNIV DIFF s) = UNIV DIFF interior(s)`, + REWRITE_TAC[SET_RULE `s = UNIV DIFF t <=> UNIV DIFF s = t`] THEN + REWRITE_TAC[GSYM INTERIOR_CLOSURE]);; + +let INTERIOR_COMPLEMENT = prove + (`!s:real^N->bool. interior(UNIV DIFF s) = UNIV DIFF closure(s)`, + REWRITE_TAC[SET_RULE `s = UNIV DIFF t <=> UNIV DIFF s = t`] THEN + REWRITE_TAC[GSYM CLOSURE_INTERIOR]);; + +let CONNECTED_INTERMEDIATE_CLOSURE = prove + (`!s t:real^N->bool. + connected s /\ s SUBSET t /\ t SUBSET closure s ==> connected t`, + REPEAT GEN_TAC THEN REWRITE_TAC[connected; NOT_EXISTS_THM] THEN + STRIP_TAC THEN + MAP_EVERY X_GEN_TAC [`u:real^N->bool`; `v:real^N->bool`] THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`u:real^N->bool`; `v:real^N->bool`]) THEN + ASM_REWRITE_TAC[] THEN ASSUME_TAC(ISPEC `s:real^N->bool` CLOSURE_SUBSET) THEN + REPLICATE_TAC 2 (CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC]) THEN + REWRITE_TAC[GSYM DE_MORGAN_THM] THEN STRIP_TAC THENL + [SUBGOAL_THEN `(closure s) SUBSET ((:real^N) DIFF u)` MP_TAC THENL + [MATCH_MP_TAC CLOSURE_MINIMAL THEN ASM_REWRITE_TAC[GSYM OPEN_CLOSED]; + ALL_TAC]; + SUBGOAL_THEN `(closure s) SUBSET ((:real^N) DIFF v)` MP_TAC THENL + [MATCH_MP_TAC CLOSURE_MINIMAL THEN ASM_REWRITE_TAC[GSYM OPEN_CLOSED]; + ALL_TAC]] THEN + ASM SET_TAC[]);; + +let CONNECTED_CLOSURE = prove + (`!s:real^N->bool. connected s ==> connected(closure s)`, + MESON_TAC[CONNECTED_INTERMEDIATE_CLOSURE; CLOSURE_SUBSET; SUBSET_REFL]);; + +let CONNECTED_UNION_STRONG = prove + (`!s t:real^N->bool. + connected s /\ connected t /\ ~(closure s INTER t = {}) + ==> connected(s UNION t)`, + REPEAT STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN + DISCH_THEN(X_CHOOSE_TAC `p:real^N`) THEN + SUBGOAL_THEN `s UNION t = ((p:real^N) INSERT s) UNION t` SUBST1_TAC THENL + [ASM SET_TAC[]; ALL_TAC] THEN + MATCH_MP_TAC CONNECTED_UNION THEN ASM_REWRITE_TAC[] THEN CONJ_TAC THENL + [MATCH_MP_TAC CONNECTED_INTERMEDIATE_CLOSURE THEN + EXISTS_TAC `s:real^N->bool` THEN ASM_REWRITE_TAC[] THEN + MP_TAC(ISPEC `s:real^N->bool` CLOSURE_SUBSET) THEN ASM SET_TAC[]; + ASM SET_TAC[]]);; + +let INTERIOR_DIFF = prove + (`!s t. interior(s DIFF t) = interior(s) DIFF closure(t)`, + ONCE_REWRITE_TAC[SET_RULE `s DIFF t = s INTER (UNIV DIFF t)`] THEN + REWRITE_TAC[INTERIOR_INTER; CLOSURE_INTERIOR] THEN SET_TAC[]);; + +let LIMPT_OF_CLOSURE = prove + (`!x:real^N s. x limit_point_of closure s <=> x limit_point_of s`, + REWRITE_TAC[closure; IN_UNION; IN_ELIM_THM; LIMIT_POINT_UNION] THEN + REPEAT GEN_TAC THEN MATCH_MP_TAC(TAUT `(q ==> p) ==> (p \/ q <=> p)`) THEN + REWRITE_TAC[LIMPT_OF_LIMPTS]);; + +let CLOSED_IN_LIMPT = prove + (`!s t. closed_in (subtopology euclidean t) s <=> + s SUBSET t /\ !x:real^N. x limit_point_of s /\ x IN t ==> x IN s`, + REPEAT GEN_TAC THEN REWRITE_TAC[CLOSED_IN_CLOSED] THEN EQ_TAC THENL + [DISCH_THEN(X_CHOOSE_THEN `u:real^N->bool` STRIP_ASSUME_TAC) THEN + ASM_SIMP_TAC[IN_INTER] THEN + ASM_MESON_TAC[CLOSED_LIMPT; LIMPT_SUBSET; INTER_SUBSET]; + STRIP_TAC THEN EXISTS_TAC `closure s :real^N->bool` THEN + REWRITE_TAC[CLOSED_CLOSURE] THEN REWRITE_TAC[closure] THEN + ASM SET_TAC[]]);; + +let INTERIOR_CLOSURE_IDEMP = prove + (`!s:real^N->bool. + interior(closure(interior(closure s))) = interior(closure s)`, + GEN_TAC THEN MATCH_MP_TAC INTERIOR_UNIQUE THEN + ASM_MESON_TAC[OPEN_INTERIOR; CLOSURE_SUBSET; CLOSURE_CLOSURE; SUBSET_TRANS; + OPEN_SUBSET_INTERIOR;SUBSET_CLOSURE; INTERIOR_SUBSET]);; + +let CLOSURE_INTERIOR_IDEMP = prove + (`!s:real^N->bool. + closure(interior(closure(interior s))) = closure(interior s)`, + GEN_TAC THEN + ONCE_REWRITE_TAC[SET_RULE `s = t <=> UNIV DIFF s = UNIV DIFF t`] THEN + REWRITE_TAC[GSYM INTERIOR_COMPLEMENT; GSYM CLOSURE_COMPLEMENT] THEN + REWRITE_TAC[INTERIOR_CLOSURE_IDEMP]);; + +let NOWHERE_DENSE_UNION = prove + (`!s t:real^N->bool. + interior(closure(s UNION t)) = {} <=> + interior(closure s) = {} /\ interior(closure t) = {}`, + SIMP_TAC[CLOSURE_UNION; INTERIOR_UNION_EQ_EMPTY; CLOSED_CLOSURE]);; + +let NOWHERE_DENSE = prove + (`!s:real^N->bool. + interior(closure s) = {} <=> + !t. open t /\ ~(t = {}) + ==> ?u. open u /\ ~(u = {}) /\ u SUBSET t /\ u INTER s = {}`, + GEN_TAC THEN REWRITE_TAC[INTERIOR_EQ_EMPTY_ALT] THEN EQ_TAC THEN + DISCH_TAC THEN X_GEN_TAC `t:real^N->bool` THEN STRIP_TAC THENL + [EXISTS_TAC `t DIFF closure s:real^N->bool` THEN + ASM_SIMP_TAC[OPEN_DIFF; CLOSED_CLOSURE] THEN + MP_TAC(ISPEC `s:real^N->bool` CLOSURE_SUBSET) THEN SET_TAC[]; + FIRST_X_ASSUM(MP_TAC o SPEC `t:real^N->bool`) THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `u:real^N->bool` STRIP_ASSUME_TAC) THEN + MP_TAC(ISPECL [`u:real^N->bool`; `s:real^N->bool`] + OPEN_INTER_CLOSURE_EQ_EMPTY) THEN + ASM SET_TAC[]]);; + +(* ------------------------------------------------------------------------- *) +(* Frontier (aka boundary). *) +(* ------------------------------------------------------------------------- *) + +let frontier = new_definition + `frontier s = (closure s) DIFF (interior s)`;; + +let FRONTIER_CLOSED = prove + (`!s. closed(frontier s)`, + SIMP_TAC[frontier; CLOSED_DIFF; CLOSED_CLOSURE; OPEN_INTERIOR]);; + +let FRONTIER_CLOSURES = prove + (`!s:real^N->bool. frontier s = (closure s) INTER (closure(UNIV DIFF s))`, + let lemma = prove(`s DIFF (UNIV DIFF t) = s INTER t`,SET_TAC[]) in + REWRITE_TAC[frontier; INTERIOR_CLOSURE; lemma]);; + +let FRONTIER_STRADDLE = prove + (`!a:real^N s. + a IN frontier s <=> + !e. &0 < e ==> (?x. x IN s /\ dist(a,x) < e) /\ + (?x. ~(x IN s) /\ dist(a,x) < e)`, + REPEAT GEN_TAC THEN REWRITE_TAC[FRONTIER_CLOSURES; IN_INTER] THEN + REWRITE_TAC[closure; IN_UNION; IN_ELIM_THM; limit_point_of; + IN_UNIV; IN_DIFF] THEN + ASM_MESON_TAC[IN_BALL; SUBSET; OPEN_CONTAINS_BALL; + CENTRE_IN_BALL; OPEN_BALL; DIST_REFL]);; + +let FRONTIER_SUBSET_CLOSED = prove + (`!s. closed s ==> (frontier s) SUBSET s`, + MESON_TAC[frontier; CLOSURE_CLOSED; SUBSET_DIFF]);; + +let FRONTIER_EMPTY = prove + (`frontier {} = {}`, + REWRITE_TAC[frontier; CLOSURE_EMPTY; EMPTY_DIFF]);; + +let FRONTIER_UNIV = prove + (`frontier(:real^N) = {}`, + REWRITE_TAC[frontier; CLOSURE_UNIV; INTERIOR_UNIV] THEN SET_TAC[]);; + +let FRONTIER_SUBSET_EQ = prove + (`!s:real^N->bool. (frontier s) SUBSET s <=> closed s`, + GEN_TAC THEN EQ_TAC THEN SIMP_TAC[FRONTIER_SUBSET_CLOSED] THEN + REWRITE_TAC[frontier] THEN + DISCH_THEN(MP_TAC o MATCH_MP (SET_RULE + `s DIFF t SUBSET u ==> t SUBSET u ==> s SUBSET u`)) THEN + REWRITE_TAC[INTERIOR_SUBSET; CLOSURE_SUBSET_EQ]);; + +let FRONTIER_COMPLEMENT = prove + (`!s:real^N->bool. frontier(UNIV DIFF s) = frontier s`, + REWRITE_TAC[frontier; CLOSURE_COMPLEMENT; INTERIOR_COMPLEMENT] THEN + SET_TAC[]);; + +let FRONTIER_DISJOINT_EQ = prove + (`!s. (frontier s) INTER s = {} <=> open s`, + ONCE_REWRITE_TAC[GSYM FRONTIER_COMPLEMENT; OPEN_CLOSED] THEN + REWRITE_TAC[GSYM FRONTIER_SUBSET_EQ] THEN SET_TAC[]);; + +let FRONTIER_INTER_SUBSET = prove + (`!s t. frontier(s INTER t) SUBSET frontier(s) UNION frontier(t)`, + REPEAT GEN_TAC THEN REWRITE_TAC[frontier; INTERIOR_INTER] THEN + MATCH_MP_TAC(SET_RULE + `cst SUBSET cs INTER ct + ==> cst DIFF (s INTER t) SUBSET (cs DIFF s) UNION (ct DIFF t)`) THEN + REWRITE_TAC[CLOSURE_INTER_SUBSET]);; + +let FRONTIER_UNION_SUBSET = prove + (`!s t:real^N->bool. frontier(s UNION t) SUBSET frontier s UNION frontier t`, + ONCE_REWRITE_TAC[GSYM FRONTIER_COMPLEMENT] THEN + REWRITE_TAC[SET_RULE `u DIFF (s UNION t) = (u DIFF s) INTER (u DIFF t)`] THEN + REWRITE_TAC[FRONTIER_INTER_SUBSET]);; + +let FRONTIER_INTERIORS = prove + (`!s. frontier s = (:real^N) DIFF interior(s) DIFF interior((:real^N) DIFF s)`, + REWRITE_TAC[frontier; CLOSURE_INTERIOR] THEN SET_TAC[]);; + +let FRONTIER_FRONTIER_SUBSET = prove + (`!s:real^N->bool. frontier(frontier s) SUBSET frontier s`, + GEN_TAC THEN GEN_REWRITE_TAC LAND_CONV [frontier] THEN + SIMP_TAC[CLOSURE_CLOSED; FRONTIER_CLOSED] THEN SET_TAC[]);; + +let INTERIOR_FRONTIER = prove + (`!s:real^N->bool. + interior(frontier s) = interior(closure s) DIFF closure(interior s)`, + ONCE_REWRITE_TAC[SET_RULE `s DIFF t = s INTER (UNIV DIFF t)`] THEN + REWRITE_TAC[GSYM INTERIOR_COMPLEMENT; GSYM INTERIOR_INTER; frontier] THEN + GEN_TAC THEN AP_TERM_TAC THEN SET_TAC[]);; + +let INTERIOR_FRONTIER_EMPTY = prove + (`!s:real^N->bool. open s \/ closed s ==> interior(frontier s) = {}`, + REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[INTERIOR_FRONTIER] THEN + ASM_SIMP_TAC[CLOSURE_CLOSED; INTERIOR_OPEN] THEN + REWRITE_TAC[SET_RULE `s DIFF t = {} <=> s SUBSET t`] THEN + REWRITE_TAC[INTERIOR_SUBSET; CLOSURE_SUBSET]);; + +let FRONTIER_FRONTIER_FRONTIER = prove + (`!s:real^N->bool. frontier(frontier(frontier s)) = frontier(frontier s)`, + GEN_TAC THEN GEN_REWRITE_TAC LAND_CONV [frontier] THEN + SIMP_TAC[CLOSURE_CLOSED; FRONTIER_CLOSED; INTERIOR_FRONTIER_EMPTY] THEN + SET_TAC[]);; + +let CONNECTED_INTER_FRONTIER = prove + (`!s t:real^N->bool. + connected s /\ ~(s INTER t = {}) /\ ~(s DIFF t = {}) + ==> ~(s INTER frontier t = {})`, + REWRITE_TAC[FRONTIER_INTERIORS] THEN REPEAT STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [CONNECTED_OPEN_IN]) THEN + REWRITE_TAC[] THEN MAP_EVERY EXISTS_TAC + [`s INTER interior t:real^N->bool`; + `s INTER (interior((:real^N) DIFF t))`] THEN + SIMP_TAC[OPEN_IN_OPEN_INTER; OPEN_INTERIOR] THEN + MAP_EVERY (MP_TAC o C ISPEC INTERIOR_SUBSET) + [`t:real^N->bool`; `(:real^N) DIFF t`] THEN + ASM SET_TAC[]);; + +let INTERIOR_CLOSED_EQ_EMPTY_AS_FRONTIER = prove + (`!s:real^N->bool. + closed s /\ interior s = {} <=> ?t. open t /\ s = frontier t`, + GEN_TAC THEN EQ_TAC THEN STRIP_TAC THENL + [EXISTS_TAC `(:real^N) DIFF s` THEN + ASM_SIMP_TAC[OPEN_DIFF; OPEN_UNIV; FRONTIER_COMPLEMENT] THEN + ASM_SIMP_TAC[frontier; CLOSURE_CLOSED; DIFF_EMPTY]; + ASM_SIMP_TAC[FRONTIER_CLOSED; INTERIOR_FRONTIER_EMPTY]]);; + +let FRONTIER_UNION = prove + (`!s t:real^N->bool. + closure s INTER closure t = {} + ==> frontier(s UNION t) = frontier(s) UNION frontier(t)`, + REPEAT STRIP_TAC THEN + MATCH_MP_TAC SUBSET_ANTISYM THEN REWRITE_TAC[FRONTIER_UNION_SUBSET] THEN + GEN_REWRITE_TAC RAND_CONV [frontier] THEN + REWRITE_TAC[CLOSURE_UNION] THEN MATCH_MP_TAC(SET_RULE + `(fs SUBSET cs /\ ft SUBSET ct) /\ k INTER fs = {} /\ k INTER ft = {} + ==> (fs UNION ft) SUBSET (cs UNION ct) DIFF k`) THEN + CONJ_TAC THENL [REWRITE_TAC[frontier] THEN SET_TAC[]; ALL_TAC] THEN + CONJ_TAC THENL + [ALL_TAC; + ONCE_REWRITE_TAC[UNION_COMM] THEN + RULE_ASSUM_TAC(ONCE_REWRITE_RULE[INTER_COMM])] THEN + FIRST_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE + `s INTER t = {} ==> s' SUBSET s /\ s' INTER u INTER (UNIV DIFF t) = {} + ==> u INTER s' = {}`)) THEN + REWRITE_TAC[frontier; SUBSET_DIFF; GSYM INTERIOR_COMPLEMENT] THEN + REWRITE_TAC[GSYM INTERIOR_INTER; SET_RULE + `(s UNION t) INTER (UNIV DIFF t) = s DIFF t`] THEN + MATCH_MP_TAC(SET_RULE + `ti SUBSET si ==> (c DIFF si) INTER ti = {}`) THEN + SIMP_TAC[SUBSET_INTERIOR; SUBSET_DIFF]);; + +let CLOSURE_UNION_FRONTIER = prove + (`!s:real^N->bool. closure s = s UNION frontier s`, + GEN_TAC THEN REWRITE_TAC[frontier] THEN + MP_TAC(ISPEC `s:real^N->bool` INTERIOR_SUBSET) THEN + MP_TAC(ISPEC `s:real^N->bool` CLOSURE_SUBSET) THEN + SET_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* A variant of nets (slightly non-standard but good for our purposes). *) +(* ------------------------------------------------------------------------- *) + +let net_tybij = new_type_definition "net" ("mk_net","netord") + (prove + (`?g:A->A->bool. !x y. (!z. g z x ==> g z y) \/ (!z. g z y ==> g z x)`, + EXISTS_TAC `\x:A y:A. F` THEN REWRITE_TAC[]));; + +let NET = prove + (`!n x y. (!z. netord n z x ==> netord n z y) \/ + (!z. netord n z y ==> netord n z x)`, + REWRITE_TAC[net_tybij; ETA_AX]);; + +let OLDNET = prove + (`!n x y. netord n x x /\ netord n y y + ==> ?z. netord n z z /\ + !w. netord n w z ==> netord n w x /\ netord n w y`, + MESON_TAC[NET]);; + +let NET_DILEMMA = prove + (`!net. (?a. (?x. netord net x a) /\ (!x. netord net x a ==> P x)) /\ + (?b. (?x. netord net x b) /\ (!x. netord net x b ==> Q x)) + ==> ?c. (?x. netord net x c) /\ (!x. netord net x c ==> P x /\ Q x)`, + MESON_TAC[NET]);; + +(* ------------------------------------------------------------------------- *) +(* Common nets and the "within" modifier for nets. *) +(* ------------------------------------------------------------------------- *) + +parse_as_infix("within",(14,"right"));; +parse_as_infix("in_direction",(14,"right"));; + +let at = new_definition + `at a = mk_net(\x y. &0 < dist(x,a) /\ dist(x,a) <= dist(y,a))`;; + +let at_infinity = new_definition + `at_infinity = mk_net(\x y. norm(x) >= norm(y))`;; + +let sequentially = new_definition + `sequentially = mk_net(\m:num n. m >= n)`;; + +let within = new_definition + `net within s = mk_net(\x y. netord net x y /\ x IN s)`;; + +let in_direction = new_definition + `a in_direction v = (at a) within {b | ?c. &0 <= c /\ (b - a = c % v)}`;; + +(* ------------------------------------------------------------------------- *) +(* Prove that they are all nets. *) +(* ------------------------------------------------------------------------- *) + +let NET_PROVE_TAC[def] = + REWRITE_TAC[GSYM FUN_EQ_THM; def] THEN + REWRITE_TAC[ETA_AX] THEN + ASM_SIMP_TAC[GSYM(CONJUNCT2 net_tybij)];; + +let AT = prove + (`!a:real^N x y. + netord(at a) x y <=> &0 < dist(x,a) /\ dist(x,a) <= dist(y,a)`, + GEN_TAC THEN NET_PROVE_TAC[at] THEN + MESON_TAC[REAL_LE_TOTAL; REAL_LE_REFL; REAL_LE_TRANS; REAL_LET_TRANS]);; + +let AT_INFINITY = prove + (`!x y. netord at_infinity x y <=> norm(x) >= norm(y)`, + NET_PROVE_TAC[at_infinity] THEN + REWRITE_TAC[real_ge; REAL_LE_REFL] THEN + MESON_TAC[REAL_LE_TOTAL; REAL_LE_REFL; REAL_LE_TRANS]);; + +let SEQUENTIALLY = prove + (`!m n. netord sequentially m n <=> m >= n`, + NET_PROVE_TAC[sequentially] THEN REWRITE_TAC[GE; LE_REFL] THEN + MESON_TAC[LE_CASES; LE_REFL; LE_TRANS]);; + +let WITHIN = prove + (`!n s x y. netord(n within s) x y <=> netord n x y /\ x IN s`, + GEN_TAC THEN GEN_TAC THEN REWRITE_TAC[within; GSYM FUN_EQ_THM] THEN + REWRITE_TAC[GSYM(CONJUNCT2 net_tybij); ETA_AX] THEN + MESON_TAC[NET]);; + +let IN_DIRECTION = prove + (`!a v x y. netord(a in_direction v) x y <=> + &0 < dist(x,a) /\ dist(x,a) <= dist(y,a) /\ + ?c. &0 <= c /\ (x - a = c % v)`, + REWRITE_TAC[WITHIN; AT; in_direction; IN_ELIM_THM; CONJ_ACI]);; + +let WITHIN_UNIV = prove + (`!x:real^N. at x within UNIV = at x`, + REWRITE_TAC[within; at; IN_UNIV] THEN REWRITE_TAC[ETA_AX; net_tybij]);; + +let WITHIN_WITHIN = prove + (`!net s t. (net within s) within t = net within (s INTER t)`, + ONCE_REWRITE_TAC[within] THEN + REWRITE_TAC[WITHIN; IN_INTER; GSYM CONJ_ASSOC]);; + +(* ------------------------------------------------------------------------- *) +(* Identify trivial limits, where we can't approach arbitrarily closely. *) +(* ------------------------------------------------------------------------- *) + +let trivial_limit = new_definition + `trivial_limit net <=> + (!a:A b. a = b) \/ + ?a:A b. ~(a = b) /\ !x. ~(netord(net) x a) /\ ~(netord(net) x b)`;; + +let TRIVIAL_LIMIT_WITHIN = prove + (`!a:real^N. trivial_limit (at a within s) <=> ~(a limit_point_of s)`, + REWRITE_TAC[trivial_limit; LIMPT_APPROACHABLE_LE; WITHIN; AT; DIST_NZ] THEN + REPEAT GEN_TAC THEN EQ_TAC THENL + [DISCH_THEN(DISJ_CASES_THEN MP_TAC) THENL + [MESON_TAC[REAL_LT_01; REAL_LT_REFL; VECTOR_CHOOSE_DIST; + DIST_REFL; REAL_LT_IMP_LE]; + DISCH_THEN(X_CHOOSE_THEN `b:real^N` (X_CHOOSE_THEN `c:real^N` + STRIP_ASSUME_TAC)) THEN + SUBGOAL_THEN `&0 < dist(a,b:real^N) \/ &0 < dist(a,c:real^N)` MP_TAC THEN + ASM_MESON_TAC[DIST_TRIANGLE; DIST_SYM; GSYM DIST_NZ; GSYM DIST_EQ_0; + REAL_ARITH `x <= &0 + &0 ==> ~(&0 < x)`]]; + REWRITE_TAC[NOT_FORALL_THM; NOT_IMP; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `e:real` THEN DISCH_TAC THEN DISJ2_TAC THEN + EXISTS_TAC `a:real^N` THEN + SUBGOAL_THEN `?b:real^N. dist(a,b) = e` MP_TAC THENL + [ASM_SIMP_TAC[VECTOR_CHOOSE_DIST; REAL_LT_IMP_LE]; ALL_TAC] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `b:real^N` THEN + DISCH_THEN(SUBST_ALL_TAC o SYM) THEN + ASM_MESON_TAC[REAL_NOT_LE; DIST_REFL; DIST_NZ; DIST_SYM]]);; + +let TRIVIAL_LIMIT_AT = prove + (`!a. ~(trivial_limit (at a))`, + ONCE_REWRITE_TAC[GSYM WITHIN_UNIV] THEN + REWRITE_TAC[TRIVIAL_LIMIT_WITHIN; LIMPT_UNIV]);; + +let TRIVIAL_LIMIT_AT_INFINITY = prove + (`~(trivial_limit at_infinity)`, + REWRITE_TAC[trivial_limit; AT_INFINITY; real_ge] THEN + MESON_TAC[REAL_LE_REFL; VECTOR_CHOOSE_SIZE; REAL_LT_01; REAL_LT_LE]);; + +let TRIVIAL_LIMIT_SEQUENTIALLY = prove + (`~(trivial_limit sequentially)`, + REWRITE_TAC[trivial_limit; SEQUENTIALLY] THEN + MESON_TAC[GE_REFL; NOT_SUC]);; + +let LIM_WITHIN_CLOSED_TRIVIAL = prove + (`!a s. closed s /\ ~(a IN s) ==> trivial_limit (at a within s)`, + REWRITE_TAC[TRIVIAL_LIMIT_WITHIN] THEN MESON_TAC[CLOSED_LIMPT]);; + +let NONTRIVIAL_LIMIT_WITHIN = prove + (`!net s. trivial_limit net ==> trivial_limit(net within s)`, + REWRITE_TAC[trivial_limit; WITHIN] THEN MESON_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* Some property holds "sufficiently close" to the limit point. *) +(* ------------------------------------------------------------------------- *) + +let eventually = new_definition + `eventually p net <=> + trivial_limit net \/ + ?y. (?x. netord net x y) /\ (!x. netord net x y ==> p x)`;; + +let EVENTUALLY_HAPPENS = prove + (`!net p. eventually p net ==> trivial_limit net \/ ?x. p x`, + REWRITE_TAC[eventually] THEN MESON_TAC[]);; + +let EVENTUALLY_WITHIN_LE = prove + (`!s a:real^M p. + eventually p (at a within s) <=> + ?d. &0 < d /\ !x. x IN s /\ &0 < dist(x,a) /\ dist(x,a) <= d ==> p(x)`, + REWRITE_TAC[eventually; AT; WITHIN; TRIVIAL_LIMIT_WITHIN] THEN + REWRITE_TAC[LIMPT_APPROACHABLE_LE; DIST_NZ] THEN + REPEAT GEN_TAC THEN EQ_TAC THENL [MESON_TAC[REAL_LTE_TRANS]; ALL_TAC] THEN + DISCH_THEN(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC) THEN + MATCH_MP_TAC(TAUT `(a ==> b) ==> ~a \/ b`) THEN DISCH_TAC THEN + SUBGOAL_THEN `?b:real^M. dist(a,b) = d` MP_TAC THENL + [ASM_SIMP_TAC[VECTOR_CHOOSE_DIST; REAL_LT_IMP_LE]; ALL_TAC] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `b:real^M` THEN + DISCH_THEN(SUBST_ALL_TAC o SYM) THEN + ASM_MESON_TAC[REAL_NOT_LE; DIST_REFL; DIST_NZ; DIST_SYM]);; + +let EVENTUALLY_WITHIN = prove + (`!s a:real^M p. + eventually p (at a within s) <=> + ?d. &0 < d /\ !x. x IN s /\ &0 < dist(x,a) /\ dist(x,a) < d ==> p(x)`, + REWRITE_TAC[EVENTUALLY_WITHIN_LE] THEN + ONCE_REWRITE_TAC[TAUT `a /\ b /\ c ==> d <=> c ==> a /\ b ==> d`] THEN + REWRITE_TAC[APPROACHABLE_LT_LE]);; + +let EVENTUALLY_AT = prove + (`!a p. eventually p (at a) <=> + ?d. &0 < d /\ !x. &0 < dist(x,a) /\ dist(x,a) < d ==> p(x)`, + ONCE_REWRITE_TAC[GSYM WITHIN_UNIV] THEN + REWRITE_TAC[EVENTUALLY_WITHIN; IN_UNIV]);; + +let EVENTUALLY_SEQUENTIALLY = prove + (`!p. eventually p sequentially <=> ?N. !n. N <= n ==> p n`, + REWRITE_TAC[eventually; SEQUENTIALLY; GE; LE_REFL; + TRIVIAL_LIMIT_SEQUENTIALLY] THEN MESON_TAC[LE_REFL]);; + +let EVENTUALLY_AT_INFINITY = prove + (`!p. eventually p at_infinity <=> ?b. !x. norm(x) >= b ==> p x`, + REWRITE_TAC[eventually; AT_INFINITY; TRIVIAL_LIMIT_AT_INFINITY] THEN + REPEAT GEN_TAC THEN EQ_TAC THENL [MESON_TAC[REAL_LE_REFL]; ALL_TAC] THEN + MESON_TAC[real_ge; REAL_LE_REFL; VECTOR_CHOOSE_SIZE; + REAL_ARITH `&0 <= b \/ (!x. x >= &0 ==> x >= b)`]);; + +let ALWAYS_EVENTUALLY = prove + (`(!x. p x) ==> eventually p net`, + REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[eventually; trivial_limit] THEN + MESON_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* Combining theorems for "eventually". *) +(* ------------------------------------------------------------------------- *) + +let EVENTUALLY_AND = prove + (`!net:(A net) p q. + eventually (\x. p x /\ q x) net <=> + eventually p net /\ eventually q net`, + REPEAT GEN_TAC THEN REWRITE_TAC[eventually] THEN + ASM_CASES_TAC `trivial_limit(net:(A net))` THEN ASM_REWRITE_TAC[] THEN + EQ_TAC THEN SIMP_TAC[NET_DILEMMA] THEN MESON_TAC[]);; + +let EVENTUALLY_MONO = prove + (`!net:(A net) p q. + (!x. p x ==> q x) /\ eventually p net + ==> eventually q net`, + REWRITE_TAC[eventually] THEN MESON_TAC[]);; + +let EVENTUALLY_MP = prove + (`!net:(A net) p q. + eventually (\x. p x ==> q x) net /\ eventually p net + ==> eventually q net`, + REWRITE_TAC[GSYM EVENTUALLY_AND] THEN + REWRITE_TAC[eventually] THEN MESON_TAC[]);; + +let EVENTUALLY_FALSE = prove + (`!net. eventually (\x. F) net <=> trivial_limit net`, + REWRITE_TAC[eventually] THEN MESON_TAC[]);; + +let EVENTUALLY_TRUE = prove + (`!net. eventually (\x. T) net <=> T`, + REWRITE_TAC[eventually; trivial_limit] THEN MESON_TAC[]);; + +let NOT_EVENTUALLY = prove + (`!net p. (!x. ~(p x)) /\ ~(trivial_limit net) ==> ~(eventually p net)`, + REWRITE_TAC[eventually] THEN MESON_TAC[]);; + +let EVENTUALLY_FORALL = prove + (`!net:(A net) p s:B->bool. + FINITE s /\ ~(s = {}) + ==> (eventually (\x. !a. a IN s ==> p a x) net <=> + !a. a IN s ==> eventually (p a) net)`, + GEN_TAC THEN GEN_TAC THEN REWRITE_TAC[IMP_CONJ] THEN + MATCH_MP_TAC FINITE_INDUCT_STRONG THEN + REWRITE_TAC[FORALL_IN_INSERT; EVENTUALLY_AND; ETA_AX] THEN + MAP_EVERY X_GEN_TAC [`b:B`; `t:B->bool`] THEN + ASM_CASES_TAC `t:B->bool = {}` THEN + ASM_SIMP_TAC[NOT_IN_EMPTY; EVENTUALLY_TRUE]);; + +let FORALL_EVENTUALLY = prove + (`!net:(A net) p s:B->bool. + FINITE s /\ ~(s = {}) + ==> ((!a. a IN s ==> eventually (p a) net) <=> + eventually (\x. !a. a IN s ==> p a x) net)`, + SIMP_TAC[EVENTUALLY_FORALL]);; + +(* ------------------------------------------------------------------------- *) +(* Limits, defined as vacuously true when the limit is trivial. *) +(* ------------------------------------------------------------------------- *) + +parse_as_infix("-->",(12,"right"));; + +let tendsto = new_definition + `(f --> l) net <=> !e. &0 < e ==> eventually (\x. dist(f(x),l) < e) net`;; + +let lim = new_definition + `lim net f = @l. (f --> l) net`;; + +let LIM = prove + (`(f --> l) net <=> + trivial_limit net \/ + !e. &0 < e ==> ?y. (?x. netord(net) x y) /\ + !x. netord(net) x y ==> dist(f(x),l) < e`, + REWRITE_TAC[tendsto; eventually] THEN MESON_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* Show that they yield usual definitions in the various cases. *) +(* ------------------------------------------------------------------------- *) + +let LIM_WITHIN_LE = prove + (`!f:real^M->real^N l a s. + (f --> l)(at a within s) <=> + !e. &0 < e ==> ?d. &0 < d /\ + !x. x IN s /\ &0 < dist(x,a) /\ dist(x,a) <= d + ==> dist(f(x),l) < e`, + REWRITE_TAC[tendsto; EVENTUALLY_WITHIN_LE]);; + +let LIM_WITHIN = prove + (`!f:real^M->real^N l a s. + (f --> l) (at a within s) <=> + !e. &0 < e + ==> ?d. &0 < d /\ + !x. x IN s /\ &0 < dist(x,a) /\ dist(x,a) < d + ==> dist(f(x),l) < e`, + REWRITE_TAC[tendsto; EVENTUALLY_WITHIN] THEN MESON_TAC[]);; + +let LIM_AT = prove + (`!f l:real^N a:real^M. + (f --> l) (at a) <=> + !e. &0 < e + ==> ?d. &0 < d /\ !x. &0 < dist(x,a) /\ dist(x,a) < d + ==> dist(f(x),l) < e`, + REWRITE_TAC[tendsto; EVENTUALLY_AT] THEN MESON_TAC[]);; + +let LIM_AT_INFINITY = prove + (`!f l. (f --> l) at_infinity <=> + !e. &0 < e ==> ?b. !x. norm(x) >= b ==> dist(f(x),l) < e`, + REWRITE_TAC[tendsto; EVENTUALLY_AT_INFINITY] THEN MESON_TAC[]);; + +let LIM_SEQUENTIALLY = prove + (`!s l. (s --> l) sequentially <=> + !e. &0 < e ==> ?N. !n. N <= n ==> dist(s(n),l) < e`, + REWRITE_TAC[tendsto; EVENTUALLY_SEQUENTIALLY] THEN MESON_TAC[]);; + +let LIM_EVENTUALLY = prove + (`!net f l. eventually (\x. f x = l) net ==> (f --> l) net`, + REWRITE_TAC[eventually; LIM] THEN MESON_TAC[DIST_REFL]);; + +(* ------------------------------------------------------------------------- *) +(* The expected monotonicity property. *) +(* ------------------------------------------------------------------------- *) + +let LIM_WITHIN_EMPTY = prove + (`!f l x. (f --> l) (at x within {})`, + REWRITE_TAC[LIM_WITHIN; NOT_IN_EMPTY] THEN MESON_TAC[REAL_LT_01]);; + +let LIM_WITHIN_SUBSET = prove + (`!f l a s. + (f --> l) (at a within s) /\ t SUBSET s ==> (f --> l) (at a within t)`, + REWRITE_TAC[LIM_WITHIN; SUBSET] THEN MESON_TAC[]);; + +let LIM_UNION = prove + (`!f x l s t. + (f --> l) (at x within s) /\ (f --> l) (at x within t) + ==> (f --> l) (at x within (s UNION t))`, + REPEAT GEN_TAC THEN REWRITE_TAC[LIM_WITHIN; IN_UNION] THEN + REWRITE_TAC[AND_FORALL_THM] THEN MATCH_MP_TAC MONO_FORALL THEN + X_GEN_TAC `e:real` THEN ASM_CASES_TAC `&0 < e` THEN ASM_SIMP_TAC[] THEN + DISCH_THEN(CONJUNCTS_THEN2 + (X_CHOOSE_TAC `d1:real`) (X_CHOOSE_TAC `d2:real`)) THEN + EXISTS_TAC `min d1 d2` THEN ASM_MESON_TAC[REAL_LT_MIN]);; + +let LIM_UNION_UNIV = prove + (`!f x l s t. + (f --> l) (at x within s) /\ (f --> l) (at x within t) /\ + s UNION t = (:real^N) + ==> (f --> l) (at x)`, + MESON_TAC[LIM_UNION; WITHIN_UNIV]);; + +(* ------------------------------------------------------------------------- *) +(* Composition of limits. *) +(* ------------------------------------------------------------------------- *) + +let LIM_COMPOSE_WITHIN = prove + (`!net f:real^M->real^N g:real^N->real^P s y z. + (f --> y) net /\ + eventually (\w. f w IN s /\ (f w = y ==> g y = z)) net /\ + (g --> z) (at y within s) + ==> ((g o f) --> z) net`, + REPEAT GEN_TAC THEN REWRITE_TAC[tendsto; CONJ_ASSOC] THEN + ONCE_REWRITE_TAC[LEFT_AND_FORALL_THM] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `e:real` THEN + ASM_CASES_TAC `&0 < e` THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[EVENTUALLY_WITHIN; GSYM DIST_NZ; o_DEF] THEN + DISCH_THEN(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC) THEN + FIRST_X_ASSUM(MP_TAC o SPEC `d:real`) THEN + ASM_REWRITE_TAC[GSYM EVENTUALLY_AND] THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] EVENTUALLY_MONO) THEN + ASM_MESON_TAC[DIST_REFL]);; + +let LIM_COMPOSE_AT = prove + (`!net f:real^M->real^N g:real^N->real^P y z. + (f --> y) net /\ + eventually (\w. f w = y ==> g y = z) net /\ + (g --> z) (at y) + ==> ((g o f) --> z) net`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`net:(real^M)net`; `f:real^M->real^N`; `g:real^N->real^P`; + `(:real^N)`; `y:real^N`; `z:real^P`] + LIM_COMPOSE_WITHIN) THEN + ASM_REWRITE_TAC[IN_UNIV; WITHIN_UNIV]);; + +(* ------------------------------------------------------------------------- *) +(* Interrelations between restricted and unrestricted limits. *) +(* ------------------------------------------------------------------------- *) + +let LIM_AT_WITHIN = prove + (`!f l a s. (f --> l)(at a) ==> (f --> l)(at a within s)`, + REWRITE_TAC[LIM_AT; LIM_WITHIN] THEN MESON_TAC[]);; + +let LIM_WITHIN_OPEN = prove + (`!f l a:real^M s. + a IN s /\ open s ==> ((f --> l)(at a within s) <=> (f --> l)(at a))`, + REPEAT STRIP_TAC THEN EQ_TAC THEN SIMP_TAC[LIM_AT_WITHIN] THEN + REWRITE_TAC[LIM_AT; LIM_WITHIN] THEN + MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `e:real` THEN + ASM_CASES_TAC `&0 < e` THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `d1:real` STRIP_ASSUME_TAC) THEN + FIRST_X_ASSUM(MP_TAC o SPEC `a:real^M` o GEN_REWRITE_RULE I [open_def]) THEN + ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `d2:real` STRIP_ASSUME_TAC) THEN + MP_TAC(SPECL [`d1:real`; `d2:real`] REAL_DOWN2) THEN ASM_REWRITE_TAC[] THEN + ASM_MESON_TAC[REAL_LT_TRANS]);; + +(* ------------------------------------------------------------------------- *) +(* More limit point characterizations. *) +(* ------------------------------------------------------------------------- *) + +let LIMPT_SEQUENTIAL_INJ = prove + (`!x:real^N s. + x limit_point_of s <=> + ?f. (!n. f(n) IN (s DELETE x)) /\ + (!m n. f m = f n <=> m = n) /\ + (f --> x) sequentially`, + REPEAT GEN_TAC THEN + REWRITE_TAC[LIMPT_APPROACHABLE; LIM_SEQUENTIALLY; IN_DELETE] THEN + EQ_TAC THENL [ALL_TAC; MESON_TAC[GE; LE_REFL]] THEN + GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [RIGHT_IMP_EXISTS_THM] THEN + REWRITE_TAC[SKOLEM_THM; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `y:real->real^N` THEN DISCH_TAC THEN + (STRIP_ASSUME_TAC o prove_recursive_functions_exist num_RECURSION) + `(z 0 = y (&1)) /\ + (!n. z (SUC n):real^N = y(min (inv(&2 pow (SUC n))) (dist(z n,x))))` THEN + EXISTS_TAC `z:num->real^N` THEN + SUBGOAL_THEN + `!n. z(n) IN s /\ ~(z n:real^N = x) /\ dist(z n,x) < inv(&2 pow n)` + ASSUME_TAC THENL + [INDUCT_TAC THEN ASM_REWRITE_TAC[] THEN CONV_TAC REAL_RAT_REDUCE_CONV THEN + ASM_SIMP_TAC[REAL_LT_01] THEN FIRST_X_ASSUM(MP_TAC o SPEC + `min (inv(&2 pow (SUC n))) (dist(z n:real^N,x))`) THEN + ASM_SIMP_TAC[REAL_LT_MIN; REAL_LT_INV_EQ; REAL_LT_POW2; DIST_POS_LT]; + ASM_REWRITE_TAC[] THEN CONJ_TAC THENL + [MATCH_MP_TAC WLOG_LT THEN REWRITE_TAC[EQ_SYM_EQ] THEN + SUBGOAL_THEN `!m n:num. m < n ==> dist(z n:real^N,x) < dist(z m,x)` + (fun th -> MESON_TAC[th; REAL_LT_REFL; LT_REFL]) THEN + MATCH_MP_TAC TRANSITIVE_STEPWISE_LT THEN + CONJ_TAC THENL [REAL_ARITH_TAC; GEN_TAC THEN ASM_REWRITE_TAC[]] THEN + FIRST_X_ASSUM(MP_TAC o SPEC + `min (inv(&2 pow (SUC n))) (dist(z n:real^N,x))`) THEN + ASM_SIMP_TAC[REAL_LT_MIN; REAL_LT_INV_EQ; REAL_LT_POW2; DIST_POS_LT]; + X_GEN_TAC `e:real` THEN DISCH_TAC THEN + MP_TAC(ISPECL [`inv(&2)`; `e:real`] REAL_ARCH_POW_INV) THEN + ANTS_TAC THENL [ASM_REAL_ARITH_TAC; MATCH_MP_TAC MONO_EXISTS] THEN + X_GEN_TAC `N:num` THEN REWRITE_TAC[REAL_POW_INV] THEN DISCH_TAC THEN + X_GEN_TAC `n:num` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ_ALT] + REAL_LT_TRANS)) THEN + MATCH_MP_TAC REAL_LTE_TRANS THEN EXISTS_TAC `inv(&2 pow n)` THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC REAL_LE_INV2 THEN + ASM_REWRITE_TAC[REAL_LT_POW2] THEN MATCH_MP_TAC REAL_POW_MONO THEN + REWRITE_TAC[REAL_OF_NUM_LE] THEN ASM_ARITH_TAC]]);; + +let LIMPT_SEQUENTIAL = prove + (`!x:real^N s. + x limit_point_of s <=> + ?f. (!n. f(n) IN (s DELETE x)) /\ (f --> x) sequentially`, + REPEAT GEN_TAC THEN EQ_TAC THENL + [REWRITE_TAC[LIMPT_SEQUENTIAL_INJ] THEN MESON_TAC[]; + REWRITE_TAC[LIMPT_APPROACHABLE; LIM_SEQUENTIALLY; IN_DELETE] THEN + MESON_TAC[GE; LE_REFL]]);; + +let [LIMPT_INFINITE_OPEN; LIMPT_INFINITE_BALL; LIMPT_INFINITE_CBALL] = + (CONJUNCTS o prove) + (`(!s x:real^N. + x limit_point_of s <=> !t. x IN t /\ open t ==> INFINITE(s INTER t)) /\ + (!s x:real^N. + x limit_point_of s <=> !e. &0 < e ==> INFINITE(s INTER ball(x,e))) /\ + (!s x:real^N. + x limit_point_of s <=> !e. &0 < e ==> INFINITE(s INTER cball(x,e)))`, + REWRITE_TAC[AND_FORALL_THM] THEN REPEAT GEN_TAC THEN MATCH_MP_TAC(TAUT + `(q ==> p) /\ (r ==> s) /\ (s ==> q) /\ (p ==> r) + ==> (p <=> q) /\ (p <=> r) /\ (p <=> s)`) THEN + REPEAT CONJ_TAC THENL + [REWRITE_TAC[limit_point_of; INFINITE; SET_RULE + `(?y. ~(y = x) /\ y IN s /\ y IN t) <=> ~(s INTER t SUBSET {x})`] THEN + MESON_TAC[FINITE_SUBSET; FINITE_SING]; + MESON_TAC[INFINITE_SUPERSET; BALL_SUBSET_CBALL; + SET_RULE `t SUBSET u ==> s INTER t SUBSET s INTER u`]; + MESON_TAC[INFINITE_SUPERSET; OPEN_CONTAINS_CBALL; + SET_RULE `t SUBSET u ==> s INTER t SUBSET s INTER u`]; + REWRITE_TAC[LIMPT_SEQUENTIAL_INJ; IN_DELETE; FORALL_AND_THM] THEN + DISCH_THEN(X_CHOOSE_THEN `f:num->real^N` STRIP_ASSUME_TAC) THEN + X_GEN_TAC `e:real` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [LIM_SEQUENTIALLY]) THEN + DISCH_THEN(MP_TAC o SPEC `e:real`) THEN + ASM_REWRITE_TAC[GSYM(ONCE_REWRITE_RULE[DIST_SYM] IN_BALL)] THEN + DISCH_THEN(X_CHOOSE_TAC `N:num`) THEN + MATCH_MP_TAC INFINITE_SUPERSET THEN + EXISTS_TAC `IMAGE (f:num->real^N) (from N)` THEN + ASM_SIMP_TAC[SUBSET; FORALL_IN_IMAGE; IN_FROM; IN_INTER] THEN + ASM_MESON_TAC[INFINITE_IMAGE_INJ; INFINITE_FROM]]);; + +let INFINITE_OPEN_IN = prove + (`!u s:real^N->bool. + open_in (subtopology euclidean u) s /\ (?x. x IN s /\ x limit_point_of u) + ==> INFINITE s`, + REPEAT STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [OPEN_IN_OPEN]) THEN + DISCH_THEN(X_CHOOSE_THEN `t:real^N->bool` STRIP_ASSUME_TAC) THEN + FIRST_X_ASSUM(MP_TAC o SPEC `t:real^N->bool` o + GEN_REWRITE_RULE I [LIMPT_INFINITE_OPEN]) THEN + FIRST_X_ASSUM SUBST_ALL_TAC THEN ASM SET_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* Condensation points. *) +(* ------------------------------------------------------------------------- *) + +parse_as_infix ("condensation_point_of",(12,"right"));; + +let condensation_point_of = new_definition + `x condensation_point_of s <=> + !t. x IN t /\ open t ==> ~COUNTABLE(s INTER t)`;; + +let CONDENSATION_POINT_IMP_LIMPT = prove + (`!x s. x condensation_point_of s ==> x limit_point_of s`, + REWRITE_TAC[condensation_point_of; LIMPT_INFINITE_OPEN; INFINITE] THEN + MESON_TAC[FINITE_IMP_COUNTABLE]);; + +let CONDENSATION_POINT_INFINITE_BALL,CONDENSATION_POINT_INFINITE_CBALL = + (CONJ_PAIR o prove) + (`(!s x:real^N. + x condensation_point_of s <=> + !e. &0 < e ==> ~COUNTABLE(s INTER ball(x,e))) /\ + (!s x:real^N. + x condensation_point_of s <=> + !e. &0 < e ==> ~COUNTABLE(s INTER cball(x,e)))`, + REWRITE_TAC[AND_FORALL_THM] THEN REPEAT GEN_TAC THEN MATCH_MP_TAC(TAUT + `(p ==> q) /\ (q ==> r) /\ (r ==> p) + ==> (p <=> q) /\ (p <=> r)`) THEN + REWRITE_TAC[condensation_point_of] THEN REPEAT CONJ_TAC THENL + [MESON_TAC[OPEN_BALL; CENTRE_IN_BALL]; + MESON_TAC[BALL_SUBSET_CBALL; COUNTABLE_SUBSET; + SET_RULE `t SUBSET u ==> s INTER t SUBSET s INTER u`]; + MESON_TAC[COUNTABLE_SUBSET; OPEN_CONTAINS_CBALL; + SET_RULE `t SUBSET u ==> s INTER t SUBSET s INTER u`]]);; + +let LIMPT_OF_CONDENSATION_POINTS = prove + (`!x:real^N s. + x limit_point_of {y | y condensation_point_of s} + ==> x condensation_point_of s`, + REWRITE_TAC[LIMPT_APPROACHABLE; CONDENSATION_POINT_INFINITE_BALL] THEN + REPEAT GEN_TAC THEN REWRITE_TAC[IN_ELIM_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(X_CHOOSE_THEN `y:real^N` STRIP_ASSUME_TAC) THEN + FIRST_X_ASSUM(MP_TAC o SPEC `e / &2`) THEN + ASM_REWRITE_TAC[REAL_HALF; CONTRAPOS_THM] THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] COUNTABLE_SUBSET) THEN + SIMP_TAC[SUBSET; IN_INTER; IN_BALL] THEN + REPEAT(POP_ASSUM MP_TAC) THEN NORM_ARITH_TAC);; + +let CLOSED_CONDENSATION_POINTS = prove + (`!s:real^N->bool. closed {x | x condensation_point_of s}`, + SIMP_TAC[CLOSED_LIMPT; LIMPT_OF_CONDENSATION_POINTS; IN_ELIM_THM]);; + +(* ------------------------------------------------------------------------- *) +(* Basic arithmetical combining theorems for limits. *) +(* ------------------------------------------------------------------------- *) + +let LIM_LINEAR = prove + (`!net:(A)net h f l. + (f --> l) net /\ linear h ==> ((\x. h(f x)) --> h l) net`, + REPEAT GEN_TAC THEN REWRITE_TAC[LIM] THEN + ASM_CASES_TAC `trivial_limit (net:(A)net)` THEN ASM_REWRITE_TAC[] THEN + STRIP_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`) THEN + ASM_SIMP_TAC[REAL_LT_DIV; dist; GSYM LINEAR_SUB; REAL_LT_RDIV_EQ] THEN + ASM_MESON_TAC[REAL_LET_TRANS; REAL_MUL_SYM]);; + +let LIM_CONST = prove + (`!net a:real^N. ((\x. a) --> a) net`, + SIMP_TAC[LIM; DIST_REFL; trivial_limit] THEN MESON_TAC[]);; + +let LIM_CMUL = prove + (`!f l c. (f --> l) net ==> ((\x. c % f x) --> c % l) net`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC LIM_LINEAR THEN + ASM_REWRITE_TAC[REWRITE_RULE[ETA_AX] + (MATCH_MP LINEAR_COMPOSE_CMUL LINEAR_ID)]);; + +let LIM_CMUL_EQ = prove + (`!net f l c. + ~(c = &0) ==> (((\x. c % f x) --> c % l) net <=> (f --> l) net)`, + REPEAT STRIP_TAC THEN EQ_TAC THEN SIMP_TAC[LIM_CMUL] THEN + DISCH_THEN(MP_TAC o SPEC `inv c:real` o MATCH_MP LIM_CMUL) THEN + ASM_SIMP_TAC[VECTOR_MUL_ASSOC; REAL_MUL_LINV; VECTOR_MUL_LID; ETA_AX]);; + +let LIM_NEG = prove + (`!net f l:real^N. (f --> l) net ==> ((\x. --(f x)) --> --l) net`, + REPEAT GEN_TAC THEN REWRITE_TAC[LIM; dist] THEN + REWRITE_TAC[VECTOR_ARITH `--x - --y = --(x - y:real^N)`; NORM_NEG]);; + +let LIM_NEG_EQ = prove + (`!net f l:real^N. ((\x. --(f x)) --> --l) net <=> (f --> l) net`, + REPEAT GEN_TAC THEN EQ_TAC THEN + DISCH_THEN(MP_TAC o MATCH_MP LIM_NEG) THEN + REWRITE_TAC[VECTOR_NEG_NEG; ETA_AX]);; + +let LIM_ADD = prove + (`!net:(A)net f g l m. + (f --> l) net /\ (g --> m) net ==> ((\x. f(x) + g(x)) --> l + m) net`, + REPEAT GEN_TAC THEN REWRITE_TAC[LIM] THEN + ASM_CASES_TAC `trivial_limit (net:(A)net)` THEN + ASM_REWRITE_TAC[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(MP_TAC o MATCH_MP NET_DILEMMA) THEN MATCH_MP_TAC MONO_EXISTS THEN + MESON_TAC[REAL_HALF; DIST_TRIANGLE_ADD; REAL_LT_ADD2; REAL_LET_TRANS]);; + +let LIM_ABS = prove + (`!net:(A)net f:A->real^N l. + (f --> l) net + ==> ((\x. lambda i. (abs(f(x)$i))) --> (lambda i. abs(l$i)):real^N) net`, + REPEAT GEN_TAC THEN REWRITE_TAC[LIM] THEN + ASM_CASES_TAC `trivial_limit (net:(A)net)` THEN ASM_REWRITE_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 + MATCH_MP_TAC MONO_FORALL THEN GEN_TAC THEN + MATCH_MP_TAC MONO_IMP THEN REWRITE_TAC[] THEN + MATCH_MP_TAC(NORM_ARITH + `norm(x - y) <= norm(a - b) ==> dist(a,b) < e ==> dist(x,y) < e`) THEN + MATCH_MP_TAC NORM_LE_COMPONENTWISE THEN + SIMP_TAC[LAMBDA_BETA; VECTOR_SUB_COMPONENT] THEN + REAL_ARITH_TAC);; + +let LIM_SUB = prove + (`!net:(A)net f g l m. + (f --> l) net /\ (g --> m) net ==> ((\x. f(x) - g(x)) --> l - m) net`, + REWRITE_TAC[real_sub; VECTOR_SUB] THEN ASM_SIMP_TAC[LIM_ADD; LIM_NEG]);; + +let LIM_MAX = prove + (`!net:(A)net f g l:real^N m:real^N. + (f --> l) net /\ (g --> m) net + ==> ((\x. lambda i. max (f(x)$i) (g(x)$i)) + --> (lambda i. max (l$i) (m$i)):real^N) net`, + REPEAT GEN_TAC THEN DISCH_TAC THEN + FIRST_ASSUM(MP_TAC o MATCH_MP LIM_ADD) THEN + FIRST_ASSUM(MP_TAC o MATCH_MP LIM_SUB) THEN + DISCH_THEN(MP_TAC o MATCH_MP LIM_ABS) THEN + REWRITE_TAC[IMP_IMP] THEN + DISCH_THEN(MP_TAC o MATCH_MP LIM_ADD) THEN + DISCH_THEN(MP_TAC o SPEC `inv(&2)` o MATCH_MP LIM_CMUL) THEN + MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN BINOP_TAC THEN + SIMP_TAC[FUN_EQ_THM; CART_EQ; VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT; + VECTOR_SUB_COMPONENT; LAMBDA_BETA] THEN + REAL_ARITH_TAC);; + +let LIM_MIN = prove + (`!net:(A)net f g l:real^N m:real^N. + (f --> l) net /\ (g --> m) net + ==> ((\x. lambda i. min (f(x)$i) (g(x)$i)) + --> (lambda i. min (l$i) (m$i)):real^N) net`, + REPEAT GEN_TAC THEN + DISCH_THEN(CONJUNCTS_THEN(MP_TAC o MATCH_MP LIM_NEG)) THEN + REWRITE_TAC[IMP_IMP] THEN + DISCH_THEN(MP_TAC o MATCH_MP LIM_NEG o MATCH_MP LIM_MAX) THEN + MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN BINOP_TAC THEN + SIMP_TAC[FUN_EQ_THM; CART_EQ; LAMBDA_BETA; VECTOR_NEG_COMPONENT] THEN + REAL_ARITH_TAC);; + +let LIM_NORM = prove + (`!net f:A->real^N l. + (f --> l) net ==> ((\x. lift(norm(f x))) --> lift(norm l)) net`, + REPEAT GEN_TAC THEN REWRITE_TAC[tendsto; DIST_LIFT] THEN + MATCH_MP_TAC MONO_FORALL THEN GEN_TAC THEN MATCH_MP_TAC MONO_IMP THEN + REWRITE_TAC[] THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] EVENTUALLY_MONO) THEN + REWRITE_TAC[] THEN NORM_ARITH_TAC);; + +let LIM_NULL = prove + (`!net f l. (f --> l) net <=> ((\x. f(x) - l) --> vec 0) net`, + REWRITE_TAC[LIM; dist; VECTOR_SUB_RZERO]);; + +let LIM_NULL_NORM = prove + (`!net f. (f --> vec 0) net <=> ((\x. lift(norm(f x))) --> vec 0) net`, + REWRITE_TAC[LIM; dist; VECTOR_SUB_RZERO; REAL_ABS_NORM; NORM_LIFT]);; + +let LIM_NULL_CMUL_EQ = prove + (`!net f c. + ~(c = &0) ==> (((\x. c % f x) --> vec 0) net <=> (f --> vec 0) net)`, + MESON_TAC[LIM_CMUL_EQ; VECTOR_MUL_RZERO]);; + +let LIM_NULL_COMPARISON = prove + (`!net f g. eventually (\x. norm(f x) <= g x) net /\ + ((\x. lift(g x)) --> vec 0) net + ==> (f --> vec 0) net`, + REPEAT GEN_TAC THEN REWRITE_TAC[tendsto; RIGHT_AND_FORALL_THM] THEN + MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `e:real` THEN + ASM_CASES_TAC `&0 < e` THEN ASM_REWRITE_TAC[GSYM EVENTUALLY_AND] THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] EVENTUALLY_MONO) THEN + REWRITE_TAC[dist; VECTOR_SUB_RZERO; NORM_LIFT] THEN REAL_ARITH_TAC);; + +let LIM_COMPONENT = prove + (`!net f i l:real^N. (f --> l) net /\ 1 <= i /\ i <= dimindex(:N) + ==> ((\a. lift(f(a)$i)) --> lift(l$i)) net`, + REWRITE_TAC[LIM; dist; GSYM LIFT_SUB; NORM_LIFT] THEN + SIMP_TAC[GSYM VECTOR_SUB_COMPONENT] THEN + MESON_TAC[COMPONENT_LE_NORM; REAL_LET_TRANS]);; + +let LIM_TRANSFORM_BOUND = prove + (`!f g. eventually (\n. norm(f n) <= norm(g n)) net /\ (g --> vec 0) net + ==> (f --> vec 0) net`, + REPEAT GEN_TAC THEN + REWRITE_TAC[tendsto; RIGHT_AND_FORALL_THM] THEN + MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `e:real` THEN + ASM_CASES_TAC `&0 < e` THEN ASM_REWRITE_TAC[GSYM EVENTUALLY_AND] THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] EVENTUALLY_MONO) THEN + REWRITE_TAC[dist; VECTOR_SUB_RZERO] THEN REAL_ARITH_TAC);; + +let LIM_NULL_CMUL_BOUNDED = prove + (`!f g:A->real^N B. + eventually (\a. g a = vec 0 \/ abs(f a) <= B) net /\ + (g --> vec 0) net + ==> ((\n. f n % g n) --> vec 0) net`, + REPEAT GEN_TAC THEN REWRITE_TAC[tendsto] THEN STRIP_TAC THEN + X_GEN_TAC `e:real` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `e / (abs B + &1)`) THEN + ASM_SIMP_TAC[REAL_LT_DIV; REAL_ARITH `&0 < abs x + &1`] THEN + UNDISCH_TAC `eventually (\a. g a:real^N = vec 0 \/ abs(f a) <= B) + (net:(A net))` THEN + REWRITE_TAC[IMP_IMP; GSYM EVENTUALLY_AND] THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] EVENTUALLY_MP) THEN + REWRITE_TAC[dist; VECTOR_SUB_RZERO; o_THM; NORM_LIFT; NORM_MUL] THEN + MATCH_MP_TAC ALWAYS_EVENTUALLY THEN X_GEN_TAC `x:A` THEN REWRITE_TAC[] THEN + ASM_CASES_TAC `(g:A->real^N) x = vec 0` THEN + ASM_REWRITE_TAC[NORM_0; REAL_MUL_RZERO] THEN + STRIP_TAC THEN MATCH_MP_TAC REAL_LET_TRANS THEN + EXISTS_TAC `B * e / (abs B + &1)` THEN + ASM_SIMP_TAC[REAL_LE_MUL2; REAL_ABS_POS; NORM_POS_LE; REAL_LT_IMP_LE] THEN + REWRITE_TAC[REAL_ARITH `c * (a / b) = (c * a) / b`] THEN + SIMP_TAC[REAL_LT_LDIV_EQ; REAL_ARITH `&0 < abs x + &1`] THEN + MATCH_MP_TAC(REAL_ARITH + `e * B <= e * abs B /\ &0 < e ==> B * e < e * (abs B + &1)`) THEN + ASM_SIMP_TAC[REAL_LE_LMUL_EQ] THEN REAL_ARITH_TAC);; + +let LIM_NULL_VMUL_BOUNDED = prove + (`!f g:A->real^N B. + ((lift o f) --> vec 0) net /\ + eventually (\a. f a = &0 \/ norm(g a) <= B) net + ==> ((\n. f n % g n) --> vec 0) net`, + REPEAT GEN_TAC THEN REWRITE_TAC[tendsto] THEN STRIP_TAC THEN + X_GEN_TAC `e:real` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `e / (abs B + &1)`) THEN + ASM_SIMP_TAC[REAL_LT_DIV; REAL_ARITH `&0 < abs x + &1`] THEN + UNDISCH_TAC `eventually(\a. f a = &0 \/ norm((g:A->real^N) a) <= B) net` THEN + REWRITE_TAC[IMP_IMP; GSYM EVENTUALLY_AND] THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] EVENTUALLY_MP) THEN + REWRITE_TAC[dist; VECTOR_SUB_RZERO; o_THM; NORM_LIFT; NORM_MUL] THEN + MATCH_MP_TAC ALWAYS_EVENTUALLY THEN X_GEN_TAC `x:A` THEN REWRITE_TAC[] THEN + ASM_CASES_TAC `(f:A->real) x = &0` THEN + ASM_REWRITE_TAC[REAL_ABS_NUM; REAL_MUL_LZERO] THEN + STRIP_TAC THEN MATCH_MP_TAC REAL_LET_TRANS THEN + EXISTS_TAC `e / (abs B + &1) * B` THEN + ASM_SIMP_TAC[REAL_LE_MUL2; REAL_ABS_POS; NORM_POS_LE; REAL_LT_IMP_LE] THEN + REWRITE_TAC[REAL_ARITH `(a / b) * c = (a * c) / b`] THEN + SIMP_TAC[REAL_LT_LDIV_EQ; REAL_ARITH `&0 < abs x + &1`] THEN + MATCH_MP_TAC(REAL_ARITH + `e * B <= e * abs B /\ &0 < e ==> e * B < e * (abs B + &1)`) THEN + ASM_SIMP_TAC[REAL_LE_LMUL_EQ] THEN REAL_ARITH_TAC);; + +let LIM_VSUM = prove + (`!f:A->B->real^N s. + FINITE s /\ (!i. i IN s ==> ((f i) --> (l i)) net) + ==> ((\x. vsum s (\i. f i x)) --> vsum s l) net`, + GEN_TAC THEN REWRITE_TAC[IMP_CONJ] THEN + MATCH_MP_TAC FINITE_INDUCT_STRONG THEN + SIMP_TAC[VSUM_CLAUSES; LIM_CONST; LIM_ADD; IN_INSERT; ETA_AX]);; + +(* ------------------------------------------------------------------------- *) +(* Deducing things about the limit from the elements. *) +(* ------------------------------------------------------------------------- *) + +let LIM_IN_CLOSED_SET = prove + (`!net f:A->real^N s l. + closed s /\ eventually (\x. f(x) IN s) net /\ + ~(trivial_limit net) /\ (f --> l) net + ==> l IN s`, + REWRITE_TAC[closed] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC(SET_RULE `~(x IN (UNIV DIFF s)) ==> x IN s`) THEN + DISCH_TAC THEN + FIRST_ASSUM(MP_TAC o SPEC `l:real^N` o GEN_REWRITE_RULE I + [OPEN_CONTAINS_BALL]) THEN + ASM_REWRITE_TAC[SUBSET; IN_BALL; IN_DIFF; IN_UNION] THEN + DISCH_THEN(X_CHOOSE_THEN `e:real` STRIP_ASSUME_TAC) THEN + FIRST_X_ASSUM(MP_TAC o SPEC `e:real` o GEN_REWRITE_RULE I [tendsto]) THEN + UNDISCH_TAC `eventually (\x. (f:A->real^N) x IN s) net` THEN + ASM_REWRITE_TAC[GSYM EVENTUALLY_AND; TAUT `a ==> ~b <=> ~(a /\ b)`] THEN + MATCH_MP_TAC NOT_EVENTUALLY THEN ASM_MESON_TAC[DIST_SYM]);; + +(* ------------------------------------------------------------------------- *) +(* Need to prove closed(cball(x,e)) before deducing this as a corollary. *) +(* ------------------------------------------------------------------------- *) + +let LIM_NORM_UBOUND = prove + (`!net:(A)net f (l:real^N) b. + ~(trivial_limit net) /\ + (f --> l) net /\ + eventually (\x. norm(f x) <= b) net + ==> norm(l) <= b`, + REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + ASM_REWRITE_TAC[LIM] THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + ASM_REWRITE_TAC[eventually] THEN + STRIP_TAC THEN REWRITE_TAC[GSYM REAL_NOT_LT] THEN + ONCE_REWRITE_TAC[GSYM REAL_SUB_LT] THEN DISCH_TAC THEN + SUBGOAL_THEN + `?x:A. dist(f(x):real^N,l) < norm(l:real^N) - b /\ norm(f x) <= b` + (CHOOSE_THEN MP_TAC) THENL [ASM_MESON_TAC[NET]; ALL_TAC] THEN + REWRITE_TAC[REAL_NOT_LT; REAL_LE_SUB_RADD; DE_MORGAN_THM; dist] THEN + NORM_ARITH_TAC);; + +let LIM_NORM_LBOUND = prove + (`!net:(A)net f (l:real^N) b. + ~(trivial_limit net) /\ (f --> l) net /\ + eventually (\x. b <= norm(f x)) net + ==> b <= norm(l)`, + REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + ASM_REWRITE_TAC[LIM] THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + ASM_REWRITE_TAC[eventually] THEN + STRIP_TAC THEN REWRITE_TAC[GSYM REAL_NOT_LT] THEN + ONCE_REWRITE_TAC[GSYM REAL_SUB_LT] THEN DISCH_TAC THEN + SUBGOAL_THEN + `?x:A. dist(f(x):real^N,l) < b - norm(l:real^N) /\ b <= norm(f x)` + (CHOOSE_THEN MP_TAC) THENL [ASM_MESON_TAC[NET]; ALL_TAC] THEN + REWRITE_TAC[REAL_NOT_LT; REAL_LE_SUB_RADD; DE_MORGAN_THM; dist] THEN + NORM_ARITH_TAC);; + +(* ------------------------------------------------------------------------- *) +(* Uniqueness of the limit, when nontrivial. *) +(* ------------------------------------------------------------------------- *) + +let LIM_UNIQUE = prove + (`!net:(A)net f l:real^N l'. + ~(trivial_limit net) /\ (f --> l) net /\ (f --> l') net ==> (l = l')`, + REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + DISCH_THEN(ASSUME_TAC o REWRITE_RULE[VECTOR_SUB_REFL] o MATCH_MP LIM_SUB) THEN + SUBGOAL_THEN `!e. &0 < e ==> norm(l:real^N - l') <= e` MP_TAC THENL + [GEN_TAC THEN DISCH_TAC THEN MATCH_MP_TAC LIM_NORM_UBOUND THEN + MAP_EVERY EXISTS_TAC [`net:(A)net`; `\x:A. vec 0 : real^N`] THEN + ASM_SIMP_TAC[NORM_0; REAL_LT_IMP_LE; eventually] THEN + ASM_MESON_TAC[trivial_limit]; + ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN REWRITE_TAC[DIST_NZ; dist] THEN + DISCH_TAC THEN DISCH_THEN(MP_TAC o SPEC `norm(l - l':real^N) / &2`) THEN + ASM_SIMP_TAC[REAL_LT_RDIV_EQ; REAL_LE_RDIV_EQ; REAL_OF_NUM_LT; ARITH] THEN + UNDISCH_TAC `&0 < norm(l - l':real^N)` THEN REAL_ARITH_TAC]);; + +let TENDSTO_LIM = prove + (`!net f l. ~(trivial_limit net) /\ (f --> l) net ==> lim net f = l`, + REWRITE_TAC[lim] THEN MESON_TAC[LIM_UNIQUE]);; + +let LIM_CONST_EQ = prove + (`!net:(A net) c d:real^N. + ((\x. c) --> d) net <=> trivial_limit net \/ c = d`, + REPEAT GEN_TAC THEN + ASM_CASES_TAC `trivial_limit (net:A net)` THEN ASM_REWRITE_TAC[] THENL + [ASM_REWRITE_TAC[LIM]; ALL_TAC] THEN + EQ_TAC THEN SIMP_TAC[LIM_CONST] THEN DISCH_TAC THEN + MATCH_MP_TAC(SPEC `net:A net` LIM_UNIQUE) THEN + EXISTS_TAC `(\x. c):A->real^N` THEN ASM_REWRITE_TAC[LIM_CONST]);; + +(* ------------------------------------------------------------------------- *) +(* Some unwieldy but occasionally useful theorems about uniform limits. *) +(* ------------------------------------------------------------------------- *) + +let UNIFORM_LIM_ADD = prove + (`!net:(A)net P f g l m. + (!e. &0 < e + ==> eventually (\x. !n:B. P n ==> norm(f n x - l n) < e) net) /\ + (!e. &0 < e + ==> eventually (\x. !n. P n ==> norm(g n x - m n) < e) net) + ==> !e. &0 < e + ==> eventually + (\x. !n. P n + ==> norm((f n x + g n x) - (l n + m n)) < e) + net`, + REPEAT GEN_TAC THEN REWRITE_TAC[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; GSYM EVENTUALLY_AND] THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] EVENTUALLY_MONO) THEN + GEN_TAC THEN REWRITE_TAC[AND_FORALL_THM] THEN + MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `n:B` THEN + ASM_CASES_TAC `(P:B->bool) n` THEN ASM_REWRITE_TAC[] THEN + CONV_TAC NORM_ARITH);; + +let UNIFORM_LIM_SUB = prove + (`!net:(A)net P f g l m. + (!e. &0 < e + ==> eventually (\x. !n:B. P n ==> norm(f n x - l n) < e) net) /\ + (!e. &0 < e + ==> eventually (\x. !n. P n ==> norm(g n x - m n) < e) net) + ==> !e. &0 < e + ==> eventually + (\x. !n. P n + ==> norm((f n x - g n x) - (l n - m n)) < e) + net`, + REPEAT GEN_TAC THEN REWRITE_TAC[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; GSYM EVENTUALLY_AND] THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] EVENTUALLY_MONO) THEN + GEN_TAC THEN REWRITE_TAC[AND_FORALL_THM] THEN + MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `n:B` THEN + ASM_CASES_TAC `(P:B->bool) n` THEN ASM_REWRITE_TAC[] THEN + CONV_TAC NORM_ARITH);; + +(* ------------------------------------------------------------------------- *) +(* Limit under bilinear function, uniform version first. *) +(* ------------------------------------------------------------------------- *) + +let UNIFORM_LIM_BILINEAR = prove + (`!net:(A)net P (h:real^M->real^N->real^P) f g l m b1 b2. + bilinear h /\ + eventually (\x. !n. P n ==> norm(l n) <= b1) net /\ + eventually (\x. !n. P n ==> norm(m n) <= b2) net /\ + (!e. &0 < e + ==> eventually (\x. !n:B. P n ==> norm(f n x - l n) < e) net) /\ + (!e. &0 < e + ==> eventually (\x. !n. P n ==> norm(g n x - m n) < e) net) + ==> !e. &0 < e + ==> eventually + (\x. !n. P n + ==> norm(h (f n x) (g n x) - h (l n) (m n)) < e) + net`, + REPEAT GEN_TAC THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + FIRST_ASSUM(X_CHOOSE_THEN `B:real` STRIP_ASSUME_TAC o MATCH_MP + BILINEAR_BOUNDED_POS) THEN + REWRITE_TAC[AND_FORALL_THM; RIGHT_AND_FORALL_THM] THEN DISCH_TAC THEN + X_GEN_TAC `e:real` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC + `min (abs b2 + &1) (e / &2 / (B * (abs b1 + abs b2 + &2)))`) THEN + ASM_SIMP_TAC[REAL_HALF; REAL_LT_DIV; REAL_LT_MUL; REAL_LT_MIN; + REAL_ARITH `&0 < abs x + &1`; + REAL_ARITH `&0 < abs x + abs y + &2`] THEN + REWRITE_TAC[GSYM EVENTUALLY_AND] THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] EVENTUALLY_MONO) THEN + X_GEN_TAC `x:A` THEN REWRITE_TAC[AND_FORALL_THM] THEN + MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `n:B` THEN + ASM_CASES_TAC `(P:B->bool) n` THEN ASM_REWRITE_TAC[] THEN + STRIP_TAC THEN + ONCE_REWRITE_TAC[VECTOR_ARITH + `h a b - h c d :real^N = (h a b - h a d) + (h a d - h c d)`] THEN + ASM_SIMP_TAC[GSYM BILINEAR_LSUB; GSYM BILINEAR_RSUB] THEN + MATCH_MP_TAC NORM_TRIANGLE_LT THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP + (MESON[REAL_LE_ADD2; REAL_LET_TRANS] + `(!x y. norm(h x y:real^P) <= B * norm x * norm y) + ==> B * norm a * norm b + B * norm c * norm d < e + ==> norm(h a b) + norm(h c d) < e`)) THEN + MATCH_MP_TAC(REAL_ARITH + `x * B < e / &2 /\ y * B < e / &2 ==> B * x + B * y < e`) THEN + CONJ_TAC THEN ASM_SIMP_TAC[GSYM REAL_LT_RDIV_EQ] THENL + [ONCE_REWRITE_TAC[REAL_MUL_SYM]; ALL_TAC] THEN + MATCH_MP_TAC REAL_LET_TRANS THEN + EXISTS_TAC `e / &2 / (B * (abs b1 + abs b2 + &2)) * + (abs b1 + abs b2 + &1)` THEN + (CONJ_TAC THENL + [MATCH_MP_TAC REAL_LE_MUL2 THEN + ASM_SIMP_TAC[NORM_POS_LE; REAL_LT_IMP_LE] THEN + ASM_SIMP_TAC[REAL_ARITH `a <= b2 ==> a <= abs b1 + abs b2 + &1`] THEN + ASM_MESON_TAC[NORM_ARITH + `norm(f - l:real^P) < abs b2 + &1 /\ norm(l) <= b1 + ==> norm(f) <= abs b1 + abs b2 + &1`]; + ONCE_REWRITE_TAC[real_div] THEN + ASM_SIMP_TAC[REAL_LT_LMUL_EQ; REAL_HALF; GSYM REAL_MUL_ASSOC; + REAL_INV_MUL] THEN + REWRITE_TAC[REAL_ARITH `B * inv x * y < B <=> B * y / x < B * &1`] THEN + ASM_SIMP_TAC[REAL_LT_INV_EQ; REAL_LT_LMUL_EQ; REAL_LT_LDIV_EQ; + REAL_ARITH `&0 < abs x + abs y + &2`] THEN + REAL_ARITH_TAC]));; + +let LIM_BILINEAR = prove + (`!net:(A)net (h:real^M->real^N->real^P) f g l m. + (f --> l) net /\ (g --> m) net /\ bilinear h + ==> ((\x. h (f x) (g x)) --> (h l m)) net`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL + [`net:(A)net`; `\x:one. T`; `h:real^M->real^N->real^P`; + `\n:one. (f:A->real^M)`; `\n:one. (g:A->real^N)`; + `\n:one. (l:real^M)`; `\n:one. (m:real^N)`; + `norm(l:real^M)`; `norm(m:real^N)`] + UNIFORM_LIM_BILINEAR) THEN + ASM_REWRITE_TAC[REAL_LE_REFL; EVENTUALLY_TRUE] THEN + ASM_REWRITE_TAC[GSYM dist; GSYM tendsto]);; + +(* ------------------------------------------------------------------------- *) +(* These are special for limits out of the same vector space. *) +(* ------------------------------------------------------------------------- *) + +let LIM_WITHIN_ID = prove + (`!a s. ((\x. x) --> a) (at a within s)`, + REWRITE_TAC[LIM_WITHIN] THEN MESON_TAC[]);; + +let LIM_AT_ID = prove + (`!a. ((\x. x) --> a) (at a)`, + ONCE_REWRITE_TAC[GSYM WITHIN_UNIV] THEN REWRITE_TAC[LIM_WITHIN_ID]);; + +let LIM_AT_ZERO = prove + (`!f:real^M->real^N l a. + (f --> l) (at a) <=> ((\x. f(a + x)) --> l) (at(vec 0))`, + REPEAT GEN_TAC THEN REWRITE_TAC[LIM_AT] THEN + AP_TERM_TAC THEN ABS_TAC THEN + ASM_CASES_TAC `&0 < e` THEN ASM_REWRITE_TAC[] THEN + AP_TERM_TAC THEN ABS_TAC THEN + ASM_CASES_TAC `&0 < d` THEN ASM_REWRITE_TAC[] THEN + EQ_TAC THEN DISCH_TAC THEN X_GEN_TAC `x:real^M` THENL + [FIRST_X_ASSUM(MP_TAC o SPEC `a + x:real^M`) THEN + REWRITE_TAC[dist; VECTOR_ADD_SUB; VECTOR_SUB_RZERO]; + FIRST_X_ASSUM(MP_TAC o SPEC `x - a:real^M`) THEN + REWRITE_TAC[dist; VECTOR_SUB_RZERO; VECTOR_SUB_ADD2]]);; + +(* ------------------------------------------------------------------------- *) +(* It's also sometimes useful to extract the limit point from the net. *) +(* ------------------------------------------------------------------------- *) + +let netlimit = new_definition + `netlimit net = @a. !x. ~(netord net x a)`;; + +let NETLIMIT_WITHIN = prove + (`!a:real^N s. ~(trivial_limit (at a within s)) + ==> (netlimit (at a within s) = a)`, + REWRITE_TAC[trivial_limit; netlimit; AT; WITHIN; DE_MORGAN_THM] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC SELECT_UNIQUE THEN REWRITE_TAC[] THEN + SUBGOAL_THEN + `!x:real^N. ~(&0 < dist(x,a) /\ dist(x,a) <= dist(a,a) /\ x IN s)` + ASSUME_TAC THENL + [ASM_MESON_TAC[DIST_REFL; REAL_NOT_LT]; ASM_MESON_TAC[]]);; + +let NETLIMIT_AT = prove + (`!a. netlimit(at a) = a`, + GEN_TAC THEN ONCE_REWRITE_TAC[GSYM WITHIN_UNIV] THEN + MATCH_MP_TAC NETLIMIT_WITHIN THEN + SIMP_TAC[TRIVIAL_LIMIT_AT; WITHIN_UNIV]);; + +(* ------------------------------------------------------------------------- *) +(* Transformation of limit. *) +(* ------------------------------------------------------------------------- *) + +let LIM_TRANSFORM = prove + (`!net f g l. + ((\x. f x - g x) --> vec 0) net /\ (f --> l) net ==> (g --> l) net`, + REPEAT GEN_TAC THEN DISCH_THEN(MP_TAC o MATCH_MP LIM_SUB) THEN + DISCH_THEN(MP_TAC o MATCH_MP LIM_NEG) THEN MATCH_MP_TAC EQ_IMP THEN + AP_THM_TAC THEN BINOP_TAC THEN REWRITE_TAC[FUN_EQ_THM] THEN + VECTOR_ARITH_TAC);; + +let LIM_TRANSFORM_EVENTUALLY = prove + (`!net f g l. + eventually (\x. f x = g x) net /\ (f --> l) net ==> (g --> l) net`, + REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[GSYM VECTOR_SUB_EQ] THEN + DISCH_THEN(CONJUNCTS_THEN2 (MP_TAC o MATCH_MP LIM_EVENTUALLY) MP_TAC) THEN + MESON_TAC[LIM_TRANSFORM]);; + +let LIM_TRANSFORM_WITHIN = prove + (`!f g x s d. + &0 < d /\ + (!x'. x' IN s /\ &0 < dist(x',x) /\ dist(x',x) < d ==> f(x') = g(x')) /\ + (f --> l) (at x within s) + ==> (g --> l) (at x within s)`, + REPEAT GEN_TAC THEN REWRITE_TAC[IMP_CONJ] THEN + DISCH_TAC THEN DISCH_TAC THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] LIM_TRANSFORM) THEN + REWRITE_TAC[LIM_WITHIN] THEN REPEAT STRIP_TAC THEN EXISTS_TAC `d:real` THEN + ASM_SIMP_TAC[VECTOR_SUB_REFL; DIST_REFL]);; + +let LIM_TRANSFORM_AT = prove + (`!f g x d. + &0 < d /\ + (!x'. &0 < dist(x',x) /\ dist(x',x) < d ==> f(x') = g(x')) /\ + (f --> l) (at x) + ==> (g --> l) (at x)`, + ONCE_REWRITE_TAC[GSYM WITHIN_UNIV] THEN MESON_TAC[LIM_TRANSFORM_WITHIN]);; + +let LIM_TRANSFORM_EQ = prove + (`!net f:A->real^N g l. + ((\x. f x - g x) --> vec 0) net ==> ((f --> l) net <=> (g --> l) net)`, + REPEAT STRIP_TAC THEN EQ_TAC THEN + DISCH_TAC THEN MATCH_MP_TAC LIM_TRANSFORM THENL + [EXISTS_TAC `f:A->real^N` THEN ASM_REWRITE_TAC[]; + EXISTS_TAC `g:A->real^N` THEN ASM_REWRITE_TAC[] THEN + ONCE_REWRITE_TAC[GSYM LIM_NEG_EQ] THEN + ASM_REWRITE_TAC[VECTOR_NEG_SUB; VECTOR_NEG_0]]);; + +let LIM_TRANSFORM_WITHIN_SET = prove + (`!f a s t. + eventually (\x. x IN s <=> x IN t) (at a) + ==> ((f --> l) (at a within s) <=> (f --> l) (at a within t))`, + REPEAT GEN_TAC THEN REWRITE_TAC[EVENTUALLY_AT; LIM_WITHIN] THEN + DISCH_THEN(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC) THEN + EQ_TAC THEN DISCH_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_THEN `k:real` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `min d k:real` THEN ASM_REWRITE_TAC[REAL_LT_MIN] THEN + ASM_MESON_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* Common case assuming being away from some crucial point like 0. *) +(* ------------------------------------------------------------------------- *) + +let LIM_TRANSFORM_AWAY_WITHIN = prove + (`!f:real^M->real^N g a b s. + ~(a = b) /\ + (!x. x IN s /\ ~(x = a) /\ ~(x = b) ==> f(x) = g(x)) /\ + (f --> l) (at a within s) + ==> (g --> l) (at a within s)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC LIM_TRANSFORM_WITHIN THEN + MAP_EVERY EXISTS_TAC [`f:real^M->real^N`; `dist(a:real^M,b)`] THEN + ASM_REWRITE_TAC[GSYM DIST_NZ] THEN X_GEN_TAC `y:real^M` THEN + REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_MESON_TAC[DIST_SYM; REAL_LT_REFL]);; + +let LIM_TRANSFORM_AWAY_AT = prove + (`!f:real^M->real^N g a b. + ~(a = b) /\ + (!x. ~(x = a) /\ ~(x = b) ==> f(x) = g(x)) /\ + (f --> l) (at a) + ==> (g --> l) (at a)`, + ONCE_REWRITE_TAC[GSYM WITHIN_UNIV] THEN + MESON_TAC[LIM_TRANSFORM_AWAY_WITHIN]);; + +(* ------------------------------------------------------------------------- *) +(* Alternatively, within an open set. *) +(* ------------------------------------------------------------------------- *) + +let LIM_TRANSFORM_WITHIN_OPEN = prove + (`!f g:real^M->real^N s a. + open s /\ a IN s /\ + (!x. x IN s /\ ~(x = a) ==> f x = g x) /\ + (f --> l) (at a) + ==> (g --> l) (at a)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC LIM_TRANSFORM_AT THEN + EXISTS_TAC `f:real^M->real^N` THEN ASM_REWRITE_TAC[] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [OPEN_CONTAINS_BALL]) THEN + DISCH_THEN(MP_TAC o SPEC `a:real^M`) THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC MONO_EXISTS THEN REWRITE_TAC[SUBSET; IN_BALL] THEN + ASM_MESON_TAC[DIST_NZ; DIST_SYM]);; + +(* ------------------------------------------------------------------------- *) +(* Another quite common idiom of an explicit conditional in a sequence. *) +(* ------------------------------------------------------------------------- *) + +let LIM_CASES_FINITE_SEQUENTIALLY = prove + (`!f g l. FINITE {n | P n} + ==> (((\n. if P n then f n else g n) --> l) sequentially <=> + (g --> l) sequentially)`, + REPEAT STRIP_TAC THEN EQ_TAC THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] LIM_TRANSFORM_EVENTUALLY) THEN + FIRST_ASSUM(MP_TAC o SPEC `\n:num. n` o MATCH_MP UPPER_BOUND_FINITE_SET) THEN + REWRITE_TAC[IN_ELIM_THM; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `N:num` THEN DISCH_TAC THEN SIMP_TAC[EVENTUALLY_SEQUENTIALLY] THEN + EXISTS_TAC `N + 1` THEN + ASM_MESON_TAC[ARITH_RULE `~(x <= n /\ n + 1 <= x)`]);; + +let LIM_CASES_COFINITE_SEQUENTIALLY = prove + (`!f g l. FINITE {n | ~P n} + ==> (((\n. if P n then f n else g n) --> l) sequentially <=> + (f --> l) sequentially)`, + ONCE_REWRITE_TAC[TAUT `(if p then x else y) = (if ~p then y else x)`] THEN + REWRITE_TAC[LIM_CASES_FINITE_SEQUENTIALLY]);; + +let LIM_CASES_SEQUENTIALLY = prove + (`!f g l m. (((\n. if m <= n then f n else g n) --> l) sequentially <=> + (f --> l) sequentially) /\ + (((\n. if m < n then f n else g n) --> l) sequentially <=> + (f --> l) sequentially) /\ + (((\n. if n <= m then f n else g n) --> l) sequentially <=> + (g --> l) sequentially) /\ + (((\n. if n < m then f n else g n) --> l) sequentially <=> + (g --> l) sequentially)`, + SIMP_TAC[LIM_CASES_FINITE_SEQUENTIALLY; LIM_CASES_COFINITE_SEQUENTIALLY; + NOT_LE; NOT_LT; FINITE_NUMSEG_LT; FINITE_NUMSEG_LE]);; + +(* ------------------------------------------------------------------------- *) +(* A congruence rule allowing us to transform limits assuming not at point. *) +(* ------------------------------------------------------------------------- *) + +let LIM_CONG_WITHIN = prove + (`(!x. ~(x = a) ==> f x = g x) + ==> (((\x. f x) --> l) (at a within s) <=> ((g --> l) (at a within s)))`, + REWRITE_TAC[LIM_WITHIN; GSYM DIST_NZ] THEN SIMP_TAC[]);; + +let LIM_CONG_AT = prove + (`(!x. ~(x = a) ==> f x = g x) + ==> (((\x. f x) --> l) (at a) <=> ((g --> l) (at a)))`, + REWRITE_TAC[LIM_AT; GSYM DIST_NZ] THEN SIMP_TAC[]);; + +extend_basic_congs [LIM_CONG_WITHIN; LIM_CONG_AT];; + +(* ------------------------------------------------------------------------- *) +(* Useful lemmas on closure and set of possible sequential limits. *) +(* ------------------------------------------------------------------------- *) + +let CLOSURE_SEQUENTIAL = prove + (`!s l:real^N. + l IN closure(s) <=> ?x. (!n. x(n) IN s) /\ (x --> l) sequentially`, + REWRITE_TAC[closure; IN_UNION; LIMPT_SEQUENTIAL; IN_ELIM_THM; IN_DELETE] THEN + REPEAT GEN_TAC THEN MATCH_MP_TAC(TAUT + `((b ==> c) /\ (~a /\ c ==> b)) /\ (a ==> c) ==> (a \/ b <=> c)`) THEN + CONJ_TAC THENL [MESON_TAC[]; ALL_TAC] THEN DISCH_TAC THEN + EXISTS_TAC `\n:num. l:real^N` THEN + ASM_REWRITE_TAC[LIM_CONST]);; + +let CLOSED_CONTAINS_SEQUENTIAL_LIMIT = prove + (`!s x l:real^N. + closed s /\ (!n. x n IN s) /\ (x --> l) sequentially ==> l IN s`, + MESON_TAC[CLOSURE_SEQUENTIAL; CLOSURE_CLOSED]);; + +let CLOSED_SEQUENTIAL_LIMITS = prove + (`!s. closed s <=> + !x l. (!n. x(n) IN s) /\ (x --> l) sequentially ==> l IN s`, + MESON_TAC[CLOSURE_SEQUENTIAL; CLOSURE_CLOSED; + CLOSED_LIMPT; LIMPT_SEQUENTIAL; IN_DELETE]);; + +let CLOSURE_APPROACHABLE = prove + (`!x s. x IN closure(s) <=> !e. &0 < e ==> ?y. y IN s /\ dist(y,x) < e`, + REWRITE_TAC[closure; LIMPT_APPROACHABLE; IN_UNION; IN_ELIM_THM] THEN + MESON_TAC[DIST_REFL]);; + +let CLOSED_APPROACHABLE = prove + (`!x s. closed s + ==> ((!e. &0 < e ==> ?y. y IN s /\ dist(y,x) < e) <=> x IN s)`, + MESON_TAC[CLOSURE_CLOSED; CLOSURE_APPROACHABLE]);; + +let IN_CLOSURE_DELETE = prove + (`!s x:real^N. x IN closure(s DELETE x) <=> x limit_point_of s`, + SIMP_TAC[CLOSURE_APPROACHABLE; LIMPT_APPROACHABLE; IN_DELETE; CONJ_ASSOC]);; + +(* ------------------------------------------------------------------------- *) +(* Some other lemmas about sequences. *) +(* ------------------------------------------------------------------------- *) + +let SEQ_OFFSET = prove + (`!f l k. (f --> l) sequentially ==> ((\i. f(i + k)) --> l) sequentially`, + REWRITE_TAC[LIM_SEQUENTIALLY] THEN + MESON_TAC[ARITH_RULE `N <= n ==> N <= n + k:num`]);; + +let SEQ_OFFSET_NEG = prove + (`!f l k. (f --> l) sequentially ==> ((\i. f(i - k)) --> l) sequentially`, + REWRITE_TAC[LIM_SEQUENTIALLY] THEN + MESON_TAC[ARITH_RULE `N + k <= n ==> N <= n - k:num`]);; + +let SEQ_OFFSET_REV = prove + (`!f l k. ((\i. f(i + k)) --> l) sequentially ==> (f --> l) sequentially`, + REWRITE_TAC[LIM_SEQUENTIALLY] THEN + MESON_TAC[ARITH_RULE `N + k <= n ==> N <= n - k /\ (n - k) + k = n:num`]);; + +let SEQ_HARMONIC = prove + (`((\n. lift(inv(&n))) --> vec 0) sequentially`, + REWRITE_TAC[LIM_SEQUENTIALLY] THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN + FIRST_ASSUM(X_CHOOSE_THEN `N:num` STRIP_ASSUME_TAC o + GEN_REWRITE_RULE I [REAL_ARCH_INV]) THEN + EXISTS_TAC `N:num` THEN REPEAT STRIP_TAC THEN + REWRITE_TAC[dist; VECTOR_SUB_RZERO; NORM_LIFT] THEN + ASM_REWRITE_TAC[REAL_ABS_INV; REAL_ABS_NUM] THEN + MATCH_MP_TAC REAL_LET_TRANS THEN EXISTS_TAC `inv(&N)` THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC REAL_LE_INV2 THEN + ASM_REWRITE_TAC[REAL_OF_NUM_LT; REAL_OF_NUM_LE; LT_NZ]);; + +(* ------------------------------------------------------------------------- *) +(* More properties of closed balls. *) +(* ------------------------------------------------------------------------- *) + +let CLOSED_CBALL = prove + (`!x:real^N e. closed(cball(x,e))`, + REWRITE_TAC[CLOSED_SEQUENTIAL_LIMITS; IN_CBALL; dist] THEN + GEN_TAC THEN GEN_TAC THEN X_GEN_TAC `s:num->real^N` THEN + X_GEN_TAC `y:real^N` THEN STRIP_TAC THEN + MATCH_MP_TAC(ISPEC `sequentially` LIM_NORM_UBOUND) THEN + EXISTS_TAC `\n. x - (s:num->real^N) n` THEN + REWRITE_TAC[TRIVIAL_LIMIT_SEQUENTIALLY; EVENTUALLY_SEQUENTIALLY] THEN + ASM_SIMP_TAC[LIM_SUB; LIM_CONST; SEQUENTIALLY] THEN MESON_TAC[GE_REFL]);; + +let IN_INTERIOR_CBALL = prove + (`!x s. x IN interior s <=> ?e. &0 < e /\ cball(x,e) SUBSET s`, + REWRITE_TAC[interior; IN_ELIM_THM] THEN + MESON_TAC[OPEN_CONTAINS_CBALL; SUBSET_TRANS; + BALL_SUBSET_CBALL; CENTRE_IN_BALL; OPEN_BALL]);; + +let LIMPT_BALL = prove + (`!x:real^N y e. y limit_point_of ball(x,e) <=> &0 < e /\ y IN cball(x,e)`, + REPEAT GEN_TAC THEN ASM_CASES_TAC `&0 < e` THENL + [ALL_TAC; ASM_MESON_TAC[LIMPT_EMPTY; REAL_NOT_LT; BALL_EQ_EMPTY]] THEN + ASM_REWRITE_TAC[] THEN EQ_TAC THENL + [MESON_TAC[CLOSED_CBALL; CLOSED_LIMPT; LIMPT_SUBSET; BALL_SUBSET_CBALL]; + REWRITE_TAC[IN_CBALL; LIMPT_APPROACHABLE; IN_BALL]] THEN + DISCH_TAC THEN X_GEN_TAC `d:real` THEN DISCH_TAC THEN + ASM_CASES_TAC `y:real^N = x` THEN ASM_REWRITE_TAC[DIST_NZ] THENL + [MP_TAC(SPECL [`d:real`; `e:real`] REAL_DOWN2) THEN + ASM_REWRITE_TAC[] THEN + GEN_MESON_TAC 0 40 1 [VECTOR_CHOOSE_DIST; DIST_SYM; REAL_LT_IMP_LE]; + ALL_TAC] THEN + MP_TAC(SPECL [`norm(y:real^N - x)`; `d:real`] REAL_DOWN2) THEN + RULE_ASSUM_TAC(REWRITE_RULE[DIST_NZ; dist]) THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `k:real` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `(y:real^N) - (k / dist(y,x)) % (y - x)` THEN + REWRITE_TAC[dist; VECTOR_ARITH `(y - c % z) - y = --c % z`] THEN + REWRITE_TAC[NORM_MUL; REAL_ABS_DIV; REAL_ABS_NORM; REAL_ABS_NEG] THEN + ASM_SIMP_TAC[REAL_DIV_RMUL; REAL_LT_IMP_NZ] THEN + REWRITE_TAC[VECTOR_ARITH `x - (y - k % (y - x)) = (&1 - k) % (x - y)`] THEN + ASM_SIMP_TAC[REAL_ARITH `&0 < k ==> &0 < abs k`; NORM_MUL] THEN + ASM_SIMP_TAC[REAL_ARITH `&0 < k /\ k < d ==> abs k < d`] THEN + MATCH_MP_TAC REAL_LTE_TRANS THEN EXISTS_TAC `norm(x:real^N - y)` THEN + ASM_REWRITE_TAC[] THEN GEN_REWRITE_TAC RAND_CONV [GSYM REAL_MUL_LID] THEN + MATCH_MP_TAC REAL_LT_RMUL THEN CONJ_TAC THENL + [ALL_TAC; ASM_MESON_TAC[NORM_SUB]] THEN + MATCH_MP_TAC(REAL_ARITH `&0 < k /\ k < &1 ==> abs(&1 - k) < &1`) THEN + ASM_SIMP_TAC[REAL_LT_LDIV_EQ; REAL_LT_RDIV_EQ; REAL_MUL_LZERO; + REAL_MUL_LID]);; + +let CLOSURE_BALL = prove + (`!x:real^N e. &0 < e ==> (closure(ball(x,e)) = cball(x,e))`, + SIMP_TAC[EXTENSION; closure; IN_ELIM_THM; IN_UNION; LIMPT_BALL] THEN + REWRITE_TAC[IN_BALL; IN_CBALL] THEN REAL_ARITH_TAC);; + +let INTERIOR_CBALL = prove + (`!x:real^N e. interior(cball(x,e)) = ball(x,e)`, + REPEAT GEN_TAC THEN ASM_CASES_TAC `&0 <= e` THENL + [ALL_TAC; + SUBGOAL_THEN `cball(x:real^N,e) = {} /\ ball(x:real^N,e) = {}` + (fun th -> REWRITE_TAC[th; INTERIOR_EMPTY]) THEN + REWRITE_TAC[IN_BALL; IN_CBALL; EXTENSION; NOT_IN_EMPTY] THEN + CONJ_TAC THEN X_GEN_TAC `y:real^N` THEN + MP_TAC(ISPECL [`x:real^N`; `y:real^N`] DIST_POS_LE) THEN + POP_ASSUM MP_TAC THEN REAL_ARITH_TAC] THEN + MATCH_MP_TAC INTERIOR_UNIQUE THEN + REWRITE_TAC[BALL_SUBSET_CBALL; OPEN_BALL] THEN + X_GEN_TAC `t:real^N->bool` THEN + SIMP_TAC[SUBSET; IN_CBALL; IN_BALL; REAL_LT_LE] THEN STRIP_TAC THEN + X_GEN_TAC `z:real^N` THEN DISCH_TAC THEN DISCH_THEN(SUBST_ALL_TAC o SYM) THEN + FIRST_X_ASSUM(MP_TAC o SPEC `z:real^N` o GEN_REWRITE_RULE I [open_def]) THEN + ASM_REWRITE_TAC[] THEN DISCH_THEN(X_CHOOSE_THEN `d:real` MP_TAC) THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + ASM_CASES_TAC `z:real^N = x` THENL + [FIRST_X_ASSUM SUBST_ALL_TAC THEN + FIRST_X_ASSUM(X_CHOOSE_TAC `k:real` o MATCH_MP REAL_DOWN) THEN + SUBGOAL_THEN `?w:real^N. dist(w,x) = k` STRIP_ASSUME_TAC THENL + [ASM_MESON_TAC[VECTOR_CHOOSE_DIST; DIST_SYM; REAL_LT_IMP_LE]; + ASM_MESON_TAC[REAL_NOT_LE; DIST_REFL; DIST_SYM]]; + RULE_ASSUM_TAC(REWRITE_RULE[DIST_NZ]) THEN + DISCH_THEN(MP_TAC o SPEC `z + ((d / &2) / dist(z,x)) % (z - x:real^N)`) THEN + REWRITE_TAC[dist; VECTOR_ADD_SUB; NORM_MUL; REAL_ABS_DIV; + REAL_ABS_NORM; REAL_ABS_NUM] THEN + ASM_SIMP_TAC[REAL_DIV_RMUL; GSYM dist; REAL_LT_IMP_NZ] THEN + ASM_SIMP_TAC[REAL_LT_LDIV_EQ; REAL_OF_NUM_LT; ARITH] THEN + ASM_REWRITE_TAC[REAL_ARITH `abs d < d * &2 <=> &0 < d`] THEN + DISCH_THEN(ANTE_RES_THEN MP_TAC) THEN REWRITE_TAC[dist] THEN + REWRITE_TAC[VECTOR_ARITH `x - (z + k % (z - x)) = (&1 + k) % (x - z)`] THEN + REWRITE_TAC[REAL_NOT_LE; NORM_MUL] THEN + GEN_REWRITE_TAC LAND_CONV [GSYM REAL_MUL_LID] THEN + ONCE_REWRITE_TAC[NORM_SUB] THEN + ASM_SIMP_TAC[REAL_LT_RMUL_EQ; GSYM dist] THEN + MATCH_MP_TAC(REAL_ARITH `&0 < x ==> &1 < abs(&1 + x)`) THEN + ONCE_REWRITE_TAC[DIST_SYM] THEN + ASM_SIMP_TAC[REAL_LT_DIV; REAL_OF_NUM_LT; ARITH]]);; + +let FRONTIER_BALL = prove + (`!a e. &0 < e ==> frontier(ball(a,e)) = sphere(a,e)`, + SIMP_TAC[frontier; sphere; CLOSURE_BALL; INTERIOR_OPEN; OPEN_BALL; + REAL_LT_IMP_LE] THEN + REWRITE_TAC[EXTENSION; IN_DIFF; IN_ELIM_THM; IN_BALL; IN_CBALL] THEN + REAL_ARITH_TAC);; + +let FRONTIER_CBALL = prove + (`!a e. frontier(cball(a,e)) = sphere(a,e)`, + SIMP_TAC[frontier; sphere; INTERIOR_CBALL; CLOSED_CBALL; CLOSURE_CLOSED; + REAL_LT_IMP_LE] THEN + REWRITE_TAC[EXTENSION; IN_DIFF; IN_ELIM_THM; IN_BALL; IN_CBALL] THEN + REAL_ARITH_TAC);; + +let CBALL_EQ_EMPTY = prove + (`!x e. (cball(x,e) = {}) <=> e < &0`, + REWRITE_TAC[EXTENSION; IN_CBALL; NOT_IN_EMPTY; REAL_NOT_LE] THEN + MESON_TAC[DIST_POS_LE; DIST_REFL; REAL_LTE_TRANS]);; + +let CBALL_EMPTY = prove + (`!x e. e < &0 ==> cball(x,e) = {}`, + REWRITE_TAC[CBALL_EQ_EMPTY]);; + +let CBALL_EQ_SING = prove + (`!x:real^N e. (cball(x,e) = {x}) <=> e = &0`, + REPEAT GEN_TAC THEN REWRITE_TAC[EXTENSION; IN_CBALL; IN_SING] THEN + EQ_TAC THENL [ALL_TAC; MESON_TAC[DIST_LE_0]] THEN + DISCH_THEN(fun th -> MP_TAC(SPEC `x + (e / &2) % basis 1:real^N` th) THEN + MP_TAC(SPEC `x:real^N` th)) THEN + REWRITE_TAC[dist; VECTOR_ARITH `x - (x + e):real^N = --e`; + VECTOR_ARITH `x + e = x <=> e:real^N = vec 0`] THEN + REWRITE_TAC[NORM_NEG; NORM_MUL; VECTOR_MUL_EQ_0; NORM_0; VECTOR_SUB_REFL] THEN + SIMP_TAC[NORM_BASIS; BASIS_NONZERO; LE_REFL; DIMINDEX_GE_1] THEN + REAL_ARITH_TAC);; + +let CBALL_SING = prove + (`!x e. e = &0 ==> cball(x,e) = {x}`, + REWRITE_TAC[CBALL_EQ_SING]);; + +let SPHERE_SING = prove + (`!x e. e = &0 ==> sphere(x,e) = {x}`, + SIMP_TAC[sphere; DIST_EQ_0; SING_GSPEC]);; + +let SPHERE_EQ_SING = prove + (`!a:real^N r x. sphere(a,r) = {x} <=> x = a /\ r = &0`, + REPEAT GEN_TAC THEN EQ_TAC THEN SIMP_TAC[SPHERE_SING] THEN + ASM_CASES_TAC `r < &0` THEN ASM_SIMP_TAC[SPHERE_EMPTY; NOT_INSERT_EMPTY] THEN + ASM_CASES_TAC `r = &0` THEN ASM_SIMP_TAC[SPHERE_SING] THENL + [ASM SET_TAC[]; ALL_TAC] THEN + MATCH_MP_TAC(SET_RULE + `!y. (x IN s ==> y IN s /\ ~(y = x)) ==> ~(s = {x})`) THEN + EXISTS_TAC `a - (x - a):real^N` THEN REWRITE_TAC[IN_SPHERE] THEN + REPEAT(POP_ASSUM MP_TAC) THEN CONV_TAC NORM_ARITH);; + +(* ------------------------------------------------------------------------- *) +(* For points in the interior, localization of limits makes no difference. *) +(* ------------------------------------------------------------------------- *) + +let EVENTUALLY_WITHIN_INTERIOR = prove + (`!p s x. + x IN interior s + ==> (eventually p (at x within s) <=> eventually p (at x))`, + REWRITE_TAC[EVENTUALLY_WITHIN; EVENTUALLY_AT; IN_INTERIOR] THEN + REPEAT GEN_TAC THEN SIMP_TAC[SUBSET; IN_BALL; LEFT_IMP_FORALL_THM] THEN + DISCH_THEN(X_CHOOSE_THEN `e:real` STRIP_ASSUME_TAC) THEN + EQ_TAC THEN DISCH_THEN(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `min (d:real) e` THEN ASM_REWRITE_TAC[REAL_LT_MIN] THEN + ASM_MESON_TAC[DIST_SYM]);; + +let LIM_WITHIN_INTERIOR = prove + (`!f l s x. + x IN interior s + ==> ((f --> l) (at x within s) <=> (f --> l) (at x))`, + SIMP_TAC[tendsto; EVENTUALLY_WITHIN_INTERIOR]);; + +let NETLIMIT_WITHIN_INTERIOR = prove + (`!s x:real^N. x IN interior s ==> netlimit(at x within s) = x`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC NETLIMIT_WITHIN THEN + REWRITE_TAC[TRIVIAL_LIMIT_WITHIN] THEN + FIRST_ASSUM(MP_TAC o MATCH_MP(REWRITE_RULE[OPEN_CONTAINS_BALL] + (SPEC_ALL OPEN_INTERIOR))) THEN + ASM_MESON_TAC[LIMPT_SUBSET; LIMPT_BALL; CENTRE_IN_CBALL; REAL_LT_IMP_LE; + SUBSET_TRANS; INTERIOR_SUBSET]);; + +(* ------------------------------------------------------------------------- *) +(* A non-singleton connected set is perfect (i.e. has no isolated points). *) +(* ------------------------------------------------------------------------- *) + +let CONNECTED_IMP_PERFECT = prove + (`!s x:real^N. + connected s /\ ~(?a. s = {a}) /\ x IN s ==> x limit_point_of s`, + REPEAT STRIP_TAC THEN REWRITE_TAC[limit_point_of] THEN + X_GEN_TAC `t:real^N->bool` THEN STRIP_TAC THEN + MATCH_MP_TAC(TAUT `(~p ==> F) ==> p`) THEN DISCH_TAC THEN + FIRST_ASSUM(MP_TAC o SPEC `x:real^N` o GEN_REWRITE_RULE I + [OPEN_CONTAINS_CBALL]) THEN + ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `e:real` STRIP_ASSUME_TAC) THEN + FIRST_X_ASSUM(MP_TAC o SPEC `{x:real^N}` o + GEN_REWRITE_RULE I [CONNECTED_CLOPEN]) THEN + REWRITE_TAC[NOT_IMP] THEN REPEAT CONJ_TAC THENL + [REWRITE_TAC[OPEN_IN_OPEN] THEN EXISTS_TAC `t:real^N->bool` THEN + ASM SET_TAC[]; + REWRITE_TAC[CLOSED_IN_CLOSED] THEN + EXISTS_TAC `cball(x:real^N,e)` THEN REWRITE_TAC[CLOSED_CBALL] THEN + REWRITE_TAC[EXTENSION; IN_INTER; IN_SING] THEN + ASM_MESON_TAC[CENTRE_IN_CBALL; SUBSET; REAL_LT_IMP_LE]; + ASM SET_TAC[]]);; + +(* ------------------------------------------------------------------------- *) +(* Boundedness. *) +(* ------------------------------------------------------------------------- *) + +let bounded = new_definition + `bounded s <=> ?a. !x:real^N. x IN s ==> norm(x) <= a`;; + +let BOUNDED_EMPTY = prove + (`bounded {}`, + REWRITE_TAC[bounded; NOT_IN_EMPTY]);; + +let BOUNDED_SUBSET = prove + (`!s t. bounded t /\ s SUBSET t ==> bounded s`, + MESON_TAC[bounded; SUBSET]);; + +let BOUNDED_INTERIOR = prove + (`!s:real^N->bool. bounded s ==> bounded(interior s)`, + MESON_TAC[BOUNDED_SUBSET; INTERIOR_SUBSET]);; + +let BOUNDED_CLOSURE = prove + (`!s:real^N->bool. bounded s ==> bounded(closure s)`, + REWRITE_TAC[bounded; CLOSURE_SEQUENTIAL] THEN + GEN_TAC THEN MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC THEN + MESON_TAC[REWRITE_RULE[eventually] LIM_NORM_UBOUND; + TRIVIAL_LIMIT_SEQUENTIALLY; trivial_limit]);; + +let BOUNDED_CLOSURE_EQ = prove + (`!s:real^N->bool. bounded(closure s) <=> bounded s`, + GEN_TAC THEN EQ_TAC THEN REWRITE_TAC[BOUNDED_CLOSURE] THEN + MESON_TAC[BOUNDED_SUBSET; CLOSURE_SUBSET]);; + +let BOUNDED_CBALL = prove + (`!x:real^N e. bounded(cball(x,e))`, + REPEAT GEN_TAC THEN REWRITE_TAC[bounded] THEN + EXISTS_TAC `norm(x:real^N) + e` THEN REWRITE_TAC[IN_CBALL; dist] THEN + NORM_ARITH_TAC);; + +let BOUNDED_BALL = prove + (`!x e. bounded(ball(x,e))`, + MESON_TAC[BALL_SUBSET_CBALL; BOUNDED_CBALL; BOUNDED_SUBSET]);; + +let FINITE_IMP_BOUNDED = prove + (`!s:real^N->bool. FINITE s ==> bounded s`, + MATCH_MP_TAC FINITE_INDUCT_STRONG THEN REWRITE_TAC[BOUNDED_EMPTY] THEN + REWRITE_TAC[bounded; IN_INSERT] THEN X_GEN_TAC `x:real^N` THEN GEN_TAC THEN + DISCH_THEN(CONJUNCTS_THEN2 (X_CHOOSE_TAC `B:real`) STRIP_ASSUME_TAC) THEN + EXISTS_TAC `norm(x:real^N) + abs B` THEN REPEAT STRIP_TAC THEN + ASM_MESON_TAC[NORM_POS_LE; REAL_ARITH + `(y <= b /\ &0 <= x ==> y <= x + abs b) /\ x <= x + abs b`]);; + +let BOUNDED_UNION = prove + (`!s t. bounded (s UNION t) <=> bounded s /\ bounded t`, + REWRITE_TAC[bounded; IN_UNION] THEN MESON_TAC[REAL_LE_MAX]);; + +let BOUNDED_UNIONS = prove + (`!f. FINITE f /\ (!s. s IN f ==> bounded s) ==> bounded(UNIONS f)`, + REWRITE_TAC[IMP_CONJ] THEN + MATCH_MP_TAC FINITE_INDUCT_STRONG THEN + REWRITE_TAC[UNIONS_0; BOUNDED_EMPTY; IN_INSERT; UNIONS_INSERT] THEN + MESON_TAC[BOUNDED_UNION]);; + +let BOUNDED_POS = prove + (`!s. bounded s <=> ?b. &0 < b /\ !x. x IN s ==> norm(x) <= b`, + REWRITE_TAC[bounded] THEN + MESON_TAC[REAL_ARITH `&0 < &1 + abs(y) /\ (x <= y ==> x <= &1 + abs(y))`]);; + +let BOUNDED_POS_LT = prove + (`!s. bounded s <=> ?b. &0 < b /\ !x. x IN s ==> norm(x) < b`, + REWRITE_TAC[bounded] THEN + MESON_TAC[REAL_LT_IMP_LE; + REAL_ARITH `&0 < &1 + abs(y) /\ (x <= y ==> x < &1 + abs(y))`]);; + +let BOUNDED_INTER = prove + (`!s t. bounded s \/ bounded t ==> bounded (s INTER t)`, + MESON_TAC[BOUNDED_SUBSET; INTER_SUBSET]);; + +let BOUNDED_DIFF = prove + (`!s t. bounded s ==> bounded (s DIFF t)`, + MESON_TAC[BOUNDED_SUBSET; SUBSET_DIFF]);; + +let BOUNDED_INSERT = prove + (`!x s. bounded(x INSERT s) <=> bounded s`, + ONCE_REWRITE_TAC[SET_RULE `x INSERT s = {x} UNION s`] THEN + SIMP_TAC[BOUNDED_UNION; FINITE_IMP_BOUNDED; FINITE_RULES]);; + +let BOUNDED_SING = prove + (`!a. bounded {a}`, + REWRITE_TAC[BOUNDED_INSERT; BOUNDED_EMPTY]);; + +let BOUNDED_INTERS = prove + (`!f:(real^N->bool)->bool. + (?s:real^N->bool. s IN f /\ bounded s) ==> bounded(INTERS f)`, + REWRITE_TAC[LEFT_IMP_EXISTS_THM; IMP_CONJ] THEN REPEAT GEN_TAC THEN + DISCH_TAC THEN MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] BOUNDED_SUBSET) THEN + ASM SET_TAC[]);; + +let NOT_BOUNDED_UNIV = prove + (`~(bounded (:real^N))`, + REWRITE_TAC[BOUNDED_POS; NOT_FORALL_THM; NOT_EXISTS_THM; IN_UNIV; + DE_MORGAN_THM; REAL_NOT_LE] THEN + X_GEN_TAC `B:real` THEN ASM_CASES_TAC `&0 < B` THEN ASM_REWRITE_TAC[] THEN + MP_TAC(SPEC `B + &1` VECTOR_CHOOSE_SIZE) THEN + ASM_SIMP_TAC[REAL_ARITH `&0 < B ==> &0 <= B + &1`] THEN + MATCH_MP_TAC MONO_EXISTS THEN REAL_ARITH_TAC);; + +let COBOUNDED_IMP_UNBOUNDED = prove + (`!s. bounded((:real^N) DIFF s) ==> ~bounded s`, + GEN_TAC THEN REWRITE_TAC[TAUT `a ==> ~b <=> ~(a /\ b)`] THEN + REWRITE_TAC[GSYM BOUNDED_UNION; SET_RULE `UNIV DIFF s UNION s = UNIV`] THEN + REWRITE_TAC[NOT_BOUNDED_UNIV]);; + +let BOUNDED_LINEAR_IMAGE = prove + (`!f:real^M->real^N s. bounded s /\ linear f ==> bounded(IMAGE f s)`, + REPEAT GEN_TAC THEN REWRITE_TAC[BOUNDED_POS] THEN + DISCH_THEN(CONJUNCTS_THEN2 (X_CHOOSE_TAC `B1:real`) MP_TAC) THEN + DISCH_THEN(X_CHOOSE_TAC `B2:real` o MATCH_MP LINEAR_BOUNDED_POS) THEN + EXISTS_TAC `B2 * B1` THEN ASM_SIMP_TAC[REAL_LT_MUL; FORALL_IN_IMAGE] THEN + X_GEN_TAC `x:real^M` THEN STRIP_TAC THEN + MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC `B2 * norm(x:real^M)` THEN + ASM_SIMP_TAC[REAL_LE_LMUL_EQ]);; + +let BOUNDED_LINEAR_IMAGE_EQ = prove + (`!f s. linear f /\ (!x y. f x = f y ==> x = y) + ==> (bounded (IMAGE f s) <=> bounded s)`, + MATCH_ACCEPT_TAC(LINEAR_INVARIANT_RULE BOUNDED_LINEAR_IMAGE));; + +add_linear_invariants [BOUNDED_LINEAR_IMAGE_EQ];; + +let BOUNDED_SCALING = prove + (`!c s. bounded s ==> bounded (IMAGE (\x. c % x) s)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC BOUNDED_LINEAR_IMAGE THEN + ASM_SIMP_TAC[LINEAR_COMPOSE_CMUL; LINEAR_ID]);; + +let BOUNDED_NEGATIONS = prove + (`!s. bounded s ==> bounded (IMAGE (--) s)`, + GEN_TAC THEN + DISCH_THEN(MP_TAC o SPEC `-- &1` o MATCH_MP BOUNDED_SCALING) THEN + REWRITE_TAC[bounded; IN_IMAGE; VECTOR_MUL_LNEG; VECTOR_MUL_LID]);; + +let BOUNDED_TRANSLATION = prove + (`!a:real^N s. bounded s ==> bounded (IMAGE (\x. a + x) s)`, + REPEAT GEN_TAC THEN REWRITE_TAC[BOUNDED_POS; FORALL_IN_IMAGE] THEN + DISCH_THEN(X_CHOOSE_TAC `B:real`) THEN + EXISTS_TAC `B + norm(a:real^N)` THEN POP_ASSUM MP_TAC THEN + MATCH_MP_TAC MONO_AND THEN CONJ_TAC THENL [NORM_ARITH_TAC; ALL_TAC] THEN + MATCH_MP_TAC MONO_FORALL THEN GEN_TAC THEN MATCH_MP_TAC MONO_IMP THEN + REWRITE_TAC[] THEN NORM_ARITH_TAC);; + +let BOUNDED_TRANSLATION_EQ = prove + (`!a s. bounded (IMAGE (\x:real^N. a + x) s) <=> bounded s`, + REPEAT GEN_TAC THEN EQ_TAC THEN REWRITE_TAC[BOUNDED_TRANSLATION] THEN + DISCH_THEN(MP_TAC o SPEC `--a:real^N` o MATCH_MP BOUNDED_TRANSLATION) THEN + REWRITE_TAC[GSYM IMAGE_o; o_DEF; IMAGE_ID; + VECTOR_ARITH `--a + a + x:real^N = x`]);; + +add_translation_invariants [BOUNDED_TRANSLATION_EQ];; + +let BOUNDED_DIFFS = prove + (`!s t:real^N->bool. + bounded s /\ bounded t ==> bounded {x - y | x IN s /\ y IN t}`, + REPEAT GEN_TAC THEN REWRITE_TAC[BOUNDED_POS] THEN + DISCH_THEN(CONJUNCTS_THEN2 + (X_CHOOSE_TAC `B:real`) (X_CHOOSE_TAC `C:real`)) THEN + EXISTS_TAC `B + C:real` THEN REWRITE_TAC[IN_ELIM_THM] THEN + CONJ_TAC THENL [ASM_REAL_ARITH_TAC; REPEAT STRIP_TAC] THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC(NORM_ARITH + `norm x <= a /\ norm y <= b ==> norm(x - y) <= a + b`) THEN + ASM_SIMP_TAC[]);; + +let BOUNDED_SUMS = prove + (`!s t:real^N->bool. + bounded s /\ bounded t ==> bounded {x + y | x IN s /\ y IN t}`, + REPEAT GEN_TAC THEN REWRITE_TAC[BOUNDED_POS] THEN + DISCH_THEN(CONJUNCTS_THEN2 + (X_CHOOSE_TAC `B:real`) (X_CHOOSE_TAC `C:real`)) THEN + EXISTS_TAC `B + C:real` THEN REWRITE_TAC[IN_ELIM_THM] THEN + CONJ_TAC THENL [ASM_REAL_ARITH_TAC; REPEAT STRIP_TAC] THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC(NORM_ARITH + `norm x <= a /\ norm y <= b ==> norm(x + y) <= a + b`) THEN + ASM_SIMP_TAC[]);; + +let BOUNDED_SUMS_IMAGE = prove + (`!f g t. bounded {f x | x IN t} /\ bounded {g x | x IN t} + ==> bounded {f x + g x | x IN t}`, + REPEAT GEN_TAC THEN DISCH_THEN(MP_TAC o MATCH_MP BOUNDED_SUMS) THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] BOUNDED_SUBSET) THEN + SET_TAC[]);; + +let BOUNDED_SUMS_IMAGES = prove + (`!f:A->B->real^N t s. + FINITE s /\ + (!a. a IN s ==> bounded {f x a | x IN t}) + ==> bounded { vsum s (f x) | x IN t}`, + GEN_TAC THEN GEN_TAC THEN REWRITE_TAC[IMP_CONJ] THEN + MATCH_MP_TAC FINITE_INDUCT_STRONG THEN + SIMP_TAC[VSUM_CLAUSES] THEN CONJ_TAC THENL + [DISCH_THEN(K ALL_TAC) THEN MATCH_MP_TAC BOUNDED_SUBSET THEN + EXISTS_TAC `{vec 0:real^N}` THEN + SIMP_TAC[FINITE_IMP_BOUNDED; FINITE_RULES] THEN SET_TAC[]; + ALL_TAC] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC BOUNDED_SUMS_IMAGE THEN + ASM_SIMP_TAC[IN_INSERT]);; + +let BOUNDED_SUBSET_BALL = prove + (`!s x:real^N. bounded(s) ==> ?r. &0 < r /\ s SUBSET ball(x,r)`, + REPEAT GEN_TAC THEN REWRITE_TAC[BOUNDED_POS] THEN + DISCH_THEN(X_CHOOSE_THEN `B:real` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `&2 * B + norm(x:real^N)` THEN + ASM_SIMP_TAC[NORM_POS_LE; REAL_ARITH + `&0 < B /\ &0 <= x ==> &0 < &2 * B + x`] THEN + REWRITE_TAC[SUBSET] THEN X_GEN_TAC `y:real^N` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `y:real^N`) THEN ASM_REWRITE_TAC[IN_BALL] THEN + UNDISCH_TAC `&0 < B` THEN NORM_ARITH_TAC);; + +let BOUNDED_SUBSET_CBALL = prove + (`!s x:real^N. bounded(s) ==> ?r. &0 < r /\ s SUBSET cball(x,r)`, + MESON_TAC[BOUNDED_SUBSET_BALL; SUBSET_TRANS; BALL_SUBSET_CBALL]);; + +let UNBOUNDED_INTER_COBOUNDED = prove + (`!s t. ~bounded s /\ bounded((:real^N) DIFF t) ==> ~(s INTER t = {})`, + REWRITE_TAC[SET_RULE `s INTER t = {} <=> s SUBSET (:real^N) DIFF t`] THEN + MESON_TAC[BOUNDED_SUBSET]);; + +let COBOUNDED_INTER_UNBOUNDED = prove + (`!s t. bounded((:real^N) DIFF s) /\ ~bounded t ==> ~(s INTER t = {})`, + REWRITE_TAC[SET_RULE `s INTER t = {} <=> t SUBSET (:real^N) DIFF s`] THEN + MESON_TAC[BOUNDED_SUBSET]);; + +let SUBSPACE_BOUNDED_EQ_TRIVIAL = prove + (`!s:real^N->bool. subspace s ==> (bounded s <=> s = {vec 0})`, + REPEAT STRIP_TAC THEN EQ_TAC THEN SIMP_TAC[BOUNDED_SING] THEN + ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN + DISCH_THEN(MP_TAC o MATCH_MP (SET_RULE + `~(s = {a}) ==> a IN s ==> ?b. b IN s /\ ~(b = a)`)) THEN + ASM_SIMP_TAC[SUBSPACE_0] THEN + DISCH_THEN(X_CHOOSE_THEN `v:real^N` STRIP_ASSUME_TAC) THEN + REWRITE_TAC[bounded; NOT_EXISTS_THM] THEN X_GEN_TAC `B:real` THEN + DISCH_THEN(MP_TAC o SPEC `(B + &1) / norm v % v:real^N`) THEN + ASM_SIMP_TAC[SUBSPACE_MUL; NORM_MUL; REAL_ABS_DIV; REAL_ABS_NORM] THEN + ASM_SIMP_TAC[REAL_DIV_RMUL; NORM_EQ_0] THEN REAL_ARITH_TAC);; + +let BOUNDED_COMPONENTWISE = prove + (`!s:real^N->bool. + bounded s <=> !i. 1 <= i /\ i <= dimindex(:N) + ==> bounded (IMAGE (\x. lift(x$i)) s)`, + GEN_TAC THEN REWRITE_TAC[BOUNDED_POS; FORALL_IN_IMAGE; NORM_LIFT] THEN + EQ_TAC THENL [ASM_MESON_TAC[COMPONENT_LE_NORM; REAL_LE_TRANS]; ALL_TAC] THEN + GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [RIGHT_IMP_EXISTS_THM] THEN + SIMP_TAC[SKOLEM_THM; LEFT_IMP_EXISTS_THM] THEN X_GEN_TAC `b:num->real` THEN + DISCH_TAC THEN EXISTS_TAC `sum(1..dimindex(:N)) b` THEN CONJ_TAC THENL + [MATCH_MP_TAC REAL_LET_TRANS THEN + EXISTS_TAC `sum(1..dimindex(:N)) (\i. &0)` THEN + SIMP_TAC[SUM_POS_LE_NUMSEG; REAL_POS] THEN + MATCH_MP_TAC SUM_LT_ALL THEN + ASM_SIMP_TAC[IN_NUMSEG; FINITE_NUMSEG; NUMSEG_EMPTY] THEN + REWRITE_TAC[NOT_LT; DIMINDEX_GE_1]; + REPEAT STRIP_TAC THEN + W(MP_TAC o PART_MATCH lhand NORM_LE_L1 o lhand o snd) THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] REAL_LE_TRANS) THEN + MATCH_MP_TAC SUM_LE THEN ASM_SIMP_TAC[IN_NUMSEG; FINITE_NUMSEG]]);; + +(* ------------------------------------------------------------------------- *) +(* Some theorems on sups and infs using the notion "bounded". *) +(* ------------------------------------------------------------------------- *) + +let BOUNDED_LIFT = prove + (`!s. bounded(IMAGE lift s) <=> ?a. !x. x IN s ==> abs(x) <= a`, + REWRITE_TAC[bounded; FORALL_LIFT; NORM_LIFT; LIFT_IN_IMAGE_LIFT]);; + +let BOUNDED_HAS_SUP = prove + (`!s. bounded(IMAGE lift s) /\ ~(s = {}) + ==> (!x. x IN s ==> x <= sup s) /\ + (!b. (!x. x IN s ==> x <= b) ==> sup s <= b)`, + REWRITE_TAC[BOUNDED_LIFT; IMAGE_EQ_EMPTY] THEN + MESON_TAC[SUP; REAL_ARITH `abs(x) <= a ==> x <= a`]);; + +let SUP_INSERT = prove + (`!x s. bounded (IMAGE lift s) + ==> sup(x INSERT s) = if s = {} then x else max x (sup s)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_SUP_UNIQUE THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[IN_SING] THENL + [MESON_TAC[REAL_LE_REFL]; ALL_TAC] THEN + REWRITE_TAC[REAL_LE_MAX; REAL_LT_MAX; IN_INSERT] THEN + MP_TAC(ISPEC `s:real->bool` BOUNDED_HAS_SUP) THEN ASM_REWRITE_TAC[] THEN + REPEAT STRIP_TAC THEN ASM_MESON_TAC[REAL_LE_REFL; REAL_NOT_LT]);; + +let BOUNDED_HAS_INF = prove + (`!s. bounded(IMAGE lift s) /\ ~(s = {}) + ==> (!x. x IN s ==> inf s <= x) /\ + (!b. (!x. x IN s ==> b <= x) ==> b <= inf s)`, + REWRITE_TAC[BOUNDED_LIFT; IMAGE_EQ_EMPTY] THEN + MESON_TAC[INF; REAL_ARITH `abs(x) <= a ==> --a <= x`]);; + +let INF_INSERT = prove + (`!x s. bounded (IMAGE lift s) + ==> inf(x INSERT s) = if s = {} then x else min x (inf s)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_INF_UNIQUE THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[IN_SING] THENL + [MESON_TAC[REAL_LE_REFL]; ALL_TAC] THEN + REWRITE_TAC[REAL_MIN_LE; REAL_MIN_LT; IN_INSERT] THEN + MP_TAC(ISPEC `s:real->bool` BOUNDED_HAS_INF) THEN ASM_REWRITE_TAC[] THEN + REPEAT STRIP_TAC THEN ASM_MESON_TAC[REAL_LE_REFL; REAL_NOT_LT]);; + +(* ------------------------------------------------------------------------- *) +(* Subset relation on balls. *) +(* ------------------------------------------------------------------------- *) + +let SUBSET_BALLS = prove + (`(!a a':real^N r r'. + ball(a,r) SUBSET ball(a',r') <=> dist(a,a') + r <= r' \/ r <= &0) /\ + (!a a':real^N r r'. + ball(a,r) SUBSET cball(a',r') <=> dist(a,a') + r <= r' \/ r <= &0) /\ + (!a a':real^N r r'. + cball(a,r) SUBSET ball(a',r') <=> dist(a,a') + r < r' \/ r < &0) /\ + (!a a':real^N r r'. + cball(a,r) SUBSET cball(a',r') <=> dist(a,a') + r <= r' \/ r < &0)`, + let lemma = prove + (`(!a':real^N r r'. + cball(a,r) SUBSET cball(a',r') <=> dist(a,a') + r <= r' \/ r < &0) /\ + (!a':real^N r r'. + cball(a,r) SUBSET ball(a',r') <=> dist(a,a') + r < r' \/ r < &0)`, + CONJ_TAC THEN + (GEOM_ORIGIN_TAC `a':real^N` THEN + REPEAT GEN_TAC THEN REWRITE_TAC[SUBSET; IN_CBALL; IN_BALL] THEN + EQ_TAC THENL [REWRITE_TAC[DIST_0]; NORM_ARITH_TAC] THEN + DISJ_CASES_TAC(REAL_ARITH `r < &0 \/ &0 <= r`) THEN + ASM_REWRITE_TAC[] THEN DISCH_TAC THEN DISJ1_TAC THEN + ASM_CASES_TAC `a:real^N = vec 0` THENL + [FIRST_X_ASSUM(MP_TAC o SPEC `r % basis 1:real^N`) THEN + ASM_SIMP_TAC[DIST_0; NORM_MUL; NORM_BASIS; DIMINDEX_GE_1; LE_REFL]; + FIRST_X_ASSUM(MP_TAC o SPEC `(&1 + r / norm(a)) % a:real^N`) THEN + SIMP_TAC[dist; VECTOR_ARITH `a - (&1 + x) % a:real^N = --(x % a)`] THEN + ASM_SIMP_TAC[NORM_MUL; REAL_ABS_DIV; REAL_ABS_NORM; NORM_NEG; REAL_POS; + REAL_LE_DIV; NORM_POS_LE; REAL_ADD_RDISTRIB; REAL_DIV_RMUL; + NORM_EQ_0; REAL_ARITH `&0 <= x ==> abs(&1 + x) = &1 + x`]] THEN + UNDISCH_TAC `&0 <= r` THEN NORM_ARITH_TAC)) + and tac = DISCH_THEN(MP_TAC o MATCH_MP SUBSET_CLOSURE) THEN + ASM_SIMP_TAC[CLOSED_CBALL; CLOSURE_CLOSED; CLOSURE_BALL] in + REWRITE_TAC[AND_FORALL_THM] THEN GEOM_ORIGIN_TAC `a':real^N` THEN + REPEAT STRIP_TAC THEN + (EQ_TAC THENL + [ALL_TAC; REWRITE_TAC[SUBSET; IN_BALL; IN_CBALL] THEN NORM_ARITH_TAC]) THEN + MATCH_MP_TAC(SET_RULE + `(s = {} <=> q) /\ (s SUBSET t /\ ~(s = {}) /\ ~(t = {}) ==> p) + ==> s SUBSET t ==> p \/ q`) THEN + REWRITE_TAC[BALL_EQ_EMPTY; CBALL_EQ_EMPTY; REAL_NOT_LE; REAL_NOT_LT] THEN + DISCH_THEN(CONJUNCTS_THEN2 MP_TAC STRIP_ASSUME_TAC) THENL + [tac; tac; ALL_TAC; ALL_TAC] THEN REWRITE_TAC[lemma] THEN + REPEAT(POP_ASSUM MP_TAC) THEN NORM_ARITH_TAC);; + +(* ------------------------------------------------------------------------- *) +(* Compactness (the definition is the one based on convegent subsequences). *) +(* ------------------------------------------------------------------------- *) + +let compact = new_definition + `compact s <=> + !f:num->real^N. + (!n. f(n) IN s) + ==> ?l r. l IN s /\ (!m n:num. m < n ==> r(m) < r(n)) /\ + ((f o r) --> l) sequentially`;; + +let MONOTONE_BIGGER = prove + (`!r. (!m n. m < n ==> r(m) < r(n)) ==> !n:num. n <= r(n)`, + GEN_TAC THEN DISCH_TAC THEN INDUCT_TAC THEN + ASM_MESON_TAC[LE_0; ARITH_RULE `n <= m /\ m < p ==> SUC n <= p`; LT]);; + +let LIM_SUBSEQUENCE = prove + (`!s r l. (!m n. m < n ==> r(m) < r(n)) /\ (s --> l) sequentially + ==> (s o r --> l) sequentially`, + REWRITE_TAC[LIM_SEQUENTIALLY; o_THM] THEN + MESON_TAC[MONOTONE_BIGGER; LE_TRANS]);; + +let MONOTONE_SUBSEQUENCE = prove + (`!s:num->real. ?r:num->num. + (!m n. m < n ==> r(m) < r(n)) /\ + ((!m n. m <= n ==> s(r(m)) <= s(r(n))) \/ + (!m n. m <= n ==> s(r(n)) <= s(r(m))))`, + GEN_TAC THEN + ASM_CASES_TAC `!n:num. ?p. n < p /\ !m. p <= m ==> s(m) <= s(p)` THEN + POP_ASSUM MP_TAC THEN + REWRITE_TAC[NOT_FORALL_THM; NOT_EXISTS_THM; NOT_IMP; DE_MORGAN_THM] THEN + REWRITE_TAC[RIGHT_OR_EXISTS_THM; SKOLEM_THM; REAL_NOT_LE; REAL_NOT_LT] THENL + [ABBREV_TAC `N = 0`; DISCH_THEN(X_CHOOSE_THEN `N:num` MP_TAC)] THEN + DISCH_THEN(X_CHOOSE_THEN `next:num->num` STRIP_ASSUME_TAC) THEN + (MP_TAC o prove_recursive_functions_exist num_RECURSION) + `(r 0 = next(SUC N)) /\ (!n. r(SUC n) = next(r n))` THEN + MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC THEN STRIP_TAC THENL + [SUBGOAL_THEN `!m:num n:num. r n <= m ==> s(m) <= s(r n):real` + ASSUME_TAC THEN TRY CONJ_TAC THEN TRY DISJ2_TAC THEN + GEN_TAC THEN INDUCT_TAC THEN ASM_REWRITE_TAC[LT; LE] THEN + ASM_MESON_TAC[REAL_LE_TRANS; REAL_LE_REFL; LT_IMP_LE; LT_TRANS]; + SUBGOAL_THEN `!n. N < (r:num->num) n` ASSUME_TAC THEN + TRY(CONJ_TAC THENL [GEN_TAC; DISJ1_TAC THEN GEN_TAC]) THEN + INDUCT_TAC THEN ASM_REWRITE_TAC[LT; LE] THEN + TRY STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + ASM_MESON_TAC[REAL_LT_REFL; LT_LE; LTE_TRANS; REAL_LE_REFL; + REAL_LT_LE; REAL_LE_TRANS; LT]]);; + +let CONVERGENT_BOUNDED_INCREASING = prove + (`!s:num->real b. (!m n. m <= n ==> s m <= s n) /\ (!n. abs(s n) <= b) + ==> ?l. !e. &0 < e ==> ?N. !n. N <= n ==> abs(s n - l) < e`, + REPEAT STRIP_TAC THEN + MP_TAC(SPEC `\x. ?n. (s:num->real) n = x` REAL_COMPLETE) THEN + REWRITE_TAC[] THEN ANTS_TAC THENL + [ASM_MESON_TAC[REAL_ARITH `abs(x) <= b ==> x <= b`]; ALL_TAC] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `l:real` THEN STRIP_TAC THEN + X_GEN_TAC `e:real` THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `l - e`) THEN + ASM_MESON_TAC[REAL_ARITH `&0 < e ==> ~(l <= l - e)`; + REAL_ARITH `x <= y /\ y <= l /\ ~(x <= l - e) ==> abs(y - l) < e`]);; + +let CONVERGENT_BOUNDED_MONOTONE = prove + (`!s:num->real b. (!n. abs(s n) <= b) /\ + ((!m n. m <= n ==> s m <= s n) \/ + (!m n. m <= n ==> s n <= s m)) + ==> ?l. !e. &0 < e ==> ?N. !n. N <= n ==> abs(s n - l) < e`, + REPEAT STRIP_TAC THENL + [ASM_MESON_TAC[CONVERGENT_BOUNDED_INCREASING]; ALL_TAC] THEN + MP_TAC(SPEC `\n. --((s:num->real) n)` CONVERGENT_BOUNDED_INCREASING) THEN + ASM_REWRITE_TAC[REAL_LE_NEG2; REAL_ABS_NEG] THEN + ASM_MESON_TAC[REAL_ARITH `abs(x - --l) = abs(--x - l)`]);; + +let COMPACT_REAL_LEMMA = prove + (`!s b. (!n:num. abs(s n) <= b) + ==> ?l r. (!m n:num. m < n ==> r(m) < r(n)) /\ + !e. &0 < e ==> ?N. !n. N <= n ==> abs(s(r n) - l) < e`, + REPEAT GEN_TAC THEN DISCH_TAC THEN ONCE_REWRITE_TAC[SWAP_EXISTS_THM] THEN + MP_TAC(SPEC `s:num->real` MONOTONE_SUBSEQUENCE) THEN + MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC THEN DISCH_TAC THEN ASM_SIMP_TAC[] THEN + MATCH_MP_TAC CONVERGENT_BOUNDED_MONOTONE THEN ASM_MESON_TAC[]);; + +let COMPACT_LEMMA = prove + (`!s. bounded s /\ (!n. (x:num->real^N) n IN s) + ==> !d. d <= dimindex(:N) + ==> ?l:real^N r. (!m n. m < n ==> r m < (r:num->num) n) /\ + !e. &0 < e + ==> ?N. !n i. 1 <= i /\ i <= d + ==> N <= n + ==> abs(x(r n)$i - l$i) < e`, + GEN_TAC THEN REWRITE_TAC[bounded] THEN + DISCH_THEN(CONJUNCTS_THEN2 (X_CHOOSE_TAC `b:real`) ASSUME_TAC) THEN + INDUCT_TAC THENL + [REWRITE_TAC[ARITH_RULE `1 <= i /\ i <= 0 <=> F`; CONJ_ASSOC] THEN + DISCH_TAC THEN EXISTS_TAC `\n:num. n` THEN REWRITE_TAC[]; + ALL_TAC] THEN + DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o check (is_imp o concl)) THEN + ASM_SIMP_TAC[ARITH_RULE `SUC d <= n ==> d <= n`] THEN STRIP_TAC THEN + MP_TAC(SPECL [`\n:num. (x:num->real^N) (r n) $ (SUC d)`; `b:real`] + COMPACT_REAL_LEMMA) THEN + REWRITE_TAC[] THEN ANTS_TAC THENL + [ASM_MESON_TAC[REAL_LE_TRANS; COMPONENT_LE_NORM; ARITH_RULE `1 <= SUC n`]; + ALL_TAC] THEN + DISCH_THEN(X_CHOOSE_THEN `y:real` (X_CHOOSE_THEN `s:num->num` + STRIP_ASSUME_TAC)) THEN + MAP_EVERY EXISTS_TAC + [`(lambda k. if k = SUC d then y else (l:real^N)$k):real^N`; + `(r:num->num) o (s:num->num)`] THEN + ASM_SIMP_TAC[o_THM] THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN + REPEAT(FIRST_ASSUM(C UNDISCH_THEN (MP_TAC o SPEC `e:real`) o concl)) THEN + ASM_REWRITE_TAC[] THEN DISCH_THEN(X_CHOOSE_TAC `N1:num`) THEN + DISCH_THEN(X_CHOOSE_TAC `N2:num`) THEN EXISTS_TAC `N1 + N2:num` THEN + FIRST_ASSUM(fun th -> SIMP_TAC[LAMBDA_BETA; MATCH_MP(ARITH_RULE + `SUC d <= n ==> !i. 1 <= i /\ i <= SUC d ==> 1 <= i /\ i <= n`) th]) THEN + REWRITE_TAC[LE] THEN REPEAT STRIP_TAC THEN + ASM_REWRITE_TAC[] THEN TRY COND_CASES_TAC THEN + ASM_MESON_TAC[MONOTONE_BIGGER; LE_TRANS; + ARITH_RULE `N1 + N2 <= n ==> N2 <= n:num /\ N1 <= n`; + ARITH_RULE `1 <= i /\ i <= d /\ SUC d <= n + ==> ~(i = SUC d) /\ 1 <= SUC d /\ d <= n /\ i <= n`]);; + +let BOUNDED_CLOSED_IMP_COMPACT = prove + (`!s:real^N->bool. bounded s /\ closed s ==> compact s`, + REPEAT STRIP_TAC THEN REWRITE_TAC[compact] THEN + X_GEN_TAC `x:num->real^N` THEN DISCH_TAC THEN + MP_TAC(ISPEC `s:real^N->bool` COMPACT_LEMMA) THEN + ASM_REWRITE_TAC[] THEN + DISCH_THEN(MP_TAC o SPEC `dimindex(:N)`) THEN + REWRITE_TAC[LE_REFL] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `l:real^N` THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `r:num->num` THEN ASM_SIMP_TAC[] THEN + STRIP_TAC THEN MATCH_MP_TAC(TAUT `(b ==> a) /\ b ==> a /\ b`) THEN + REPEAT STRIP_TAC THENL + [FIRST_ASSUM(MATCH_MP_TAC o REWRITE_RULE[CLOSED_SEQUENTIAL_LIMITS]) THEN + EXISTS_TAC `(x:num->real^N) o (r:num->num)` THEN + ASM_REWRITE_TAC[o_THM]; + ALL_TAC] THEN + REWRITE_TAC[LIM_SEQUENTIALLY] THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `e / &2 / &(dimindex(:N))`) THEN + ASM_SIMP_TAC[REAL_LT_DIV; REAL_OF_NUM_LT; DIMINDEX_NONZERO; + REAL_HALF; ARITH_RULE `0 < n <=> ~(n = 0)`] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `N:num` THEN + REWRITE_TAC[dist] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC(MATCH_MP (REAL_ARITH `a <= b ==> b < e ==> a < e`) + (SPEC_ALL NORM_LE_L1)) THEN + MATCH_MP_TAC REAL_LET_TRANS THEN + EXISTS_TAC `sum (1..dimindex(:N)) + (\k. e / &2 / &(dimindex(:N)))` THEN + CONJ_TAC THENL + [MATCH_MP_TAC SUM_LE_NUMSEG THEN + SIMP_TAC[o_THM; LAMBDA_BETA; vector_sub] THEN + ASM_MESON_TAC[REAL_LT_IMP_LE; LE_TRANS]; + ASM_SIMP_TAC[SUM_CONST_NUMSEG; ADD_SUB; REAL_DIV_LMUL; REAL_OF_NUM_EQ; + DIMINDEX_NONZERO; REAL_LE_REFL; REAL_LT_LDIV_EQ; ARITH; + REAL_OF_NUM_LT; REAL_ARITH `x < x * &2 <=> &0 < x`]]);; + +(* ------------------------------------------------------------------------- *) +(* Completeness. *) +(* ------------------------------------------------------------------------- *) + +let cauchy = new_definition + `cauchy (s:num->real^N) <=> + !e. &0 < e ==> ?N. !m n. m >= N /\ n >= N ==> dist(s m,s n) < e`;; + +let complete = new_definition + `complete s <=> + !f:num->real^N. (!n. f n IN s) /\ cauchy f + ==> ?l. l IN s /\ (f --> l) sequentially`;; + +let CAUCHY = prove + (`!s:num->real^N. + cauchy s <=> !e. &0 < e ==> ?N. !n. n >= N ==> dist(s n,s N) < e`, + REPEAT GEN_TAC THEN REWRITE_TAC[cauchy; GE] THEN EQ_TAC THENL + [MESON_TAC[LE_REFL]; 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 + MESON_TAC[DIST_TRIANGLE_HALF_L]);; + +let CONVERGENT_IMP_CAUCHY = prove + (`!s l. (s --> l) sequentially ==> cauchy s`, + REWRITE_TAC[LIM_SEQUENTIALLY; cauchy] THEN + REPEAT GEN_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_SIMP_TAC[REAL_LT_DIV; REAL_OF_NUM_LT; ARITH] THEN + ASM_MESON_TAC[GE; LE_REFL; DIST_TRIANGLE_HALF_L]);; + +let CAUCHY_IMP_BOUNDED = prove + (`!s:num->real^N. cauchy s ==> bounded {y | ?n. y = s n}`, + REWRITE_TAC[cauchy; bounded; IN_ELIM_THM] THEN GEN_TAC THEN + DISCH_THEN(MP_TAC o SPEC `&1`) THEN REWRITE_TAC[REAL_LT_01] THEN + DISCH_THEN(X_CHOOSE_THEN `N:num` (MP_TAC o SPEC `N:num`)) THEN + REWRITE_TAC[GE_REFL] THEN DISCH_TAC THEN + SUBGOAL_THEN `!n:num. N <= n ==> norm(s n :real^N) <= norm(s N) + &1` + ASSUME_TAC THENL + [ASM_MESON_TAC[GE; dist; DIST_SYM; NORM_TRIANGLE_SUB; + REAL_ARITH `a <= b + c /\ c < &1 ==> a <= b + &1`]; + MP_TAC(ISPECL [`\n:num. norm(s n :real^N)`; `0..N`] + UPPER_BOUND_FINITE_SET_REAL) THEN + SIMP_TAC[FINITE_NUMSEG; IN_NUMSEG; LE_0; LEFT_IMP_EXISTS_THM] THEN + ASM_MESON_TAC[LE_CASES; + REAL_ARITH `x <= a \/ x <= b ==> x <= abs a + abs b`]]);; + +let COMPACT_IMP_COMPLETE = prove + (`!s:real^N->bool. compact s ==> complete s`, + GEN_TAC THEN REWRITE_TAC[complete; compact] THEN + MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `f:num->real^N` THEN + DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC THEN + DISCH_THEN(X_CHOOSE_THEN `r:num->num` STRIP_ASSUME_TAC) THEN + FIRST_X_ASSUM(MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] LIM_ADD)) THEN + DISCH_THEN(MP_TAC o SPEC `\n. (f:num->real^N)(n) - f(r n)`) THEN + DISCH_THEN(MP_TAC o SPEC `vec 0: real^N`) THEN ASM_REWRITE_TAC[o_THM] THEN + REWRITE_TAC[VECTOR_ADD_RID; VECTOR_SUB_ADD2; ETA_AX] THEN + DISCH_THEN MATCH_MP_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [cauchy]) THEN + REWRITE_TAC[GE; LIM; SEQUENTIALLY; dist; VECTOR_SUB_RZERO] THEN + SUBGOAL_THEN `!n:num. n <= r(n)` MP_TAC THENL [INDUCT_TAC; ALL_TAC] THEN + ASM_MESON_TAC[ LE_TRANS; LE_REFL; LT; LET_TRANS; LE_0; LE_SUC_LT]);; + +let COMPLETE_UNIV = prove + (`complete(:real^N)`, + REWRITE_TAC[complete; IN_UNIV] THEN X_GEN_TAC `x:num->real^N` THEN + DISCH_TAC THEN FIRST_ASSUM(MP_TAC o MATCH_MP CAUCHY_IMP_BOUNDED) THEN + DISCH_THEN(ASSUME_TAC o MATCH_MP BOUNDED_CLOSURE) THEN + MP_TAC(ISPEC `closure {y:real^N | ?n:num. y = x n}` + COMPACT_IMP_COMPLETE) THEN + ASM_SIMP_TAC[BOUNDED_CLOSED_IMP_COMPACT; CLOSED_CLOSURE; complete] THEN + DISCH_THEN(MP_TAC o SPEC `x:num->real^N`) THEN + ANTS_TAC THENL [ALL_TAC; MESON_TAC[]] THEN + ASM_REWRITE_TAC[closure; IN_ELIM_THM; IN_UNION] THEN MESON_TAC[]);; + +let COMPLETE_EQ_CLOSED = prove + (`!s:real^N->bool. complete s <=> closed s`, + GEN_TAC THEN EQ_TAC THENL + [REWRITE_TAC[complete; CLOSED_LIMPT; LIMPT_SEQUENTIAL] THEN + REWRITE_TAC[RIGHT_IMP_FORALL_THM] THEN GEN_TAC THEN + REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN MATCH_MP_TAC MONO_FORALL THEN + MESON_TAC[CONVERGENT_IMP_CAUCHY; IN_DELETE; LIM_UNIQUE; + TRIVIAL_LIMIT_SEQUENTIALLY]; + REWRITE_TAC[complete; CLOSED_SEQUENTIAL_LIMITS] THEN DISCH_TAC THEN + X_GEN_TAC `f:num->real^N` THEN STRIP_TAC THEN + MP_TAC(REWRITE_RULE[complete] COMPLETE_UNIV) THEN + DISCH_THEN(MP_TAC o SPEC `f:num->real^N`) THEN + ASM_REWRITE_TAC[IN_UNIV] THEN ASM_MESON_TAC[]]);; + +let CONVERGENT_EQ_CAUCHY = prove + (`!s. (?l. (s --> l) sequentially) <=> cauchy s`, + GEN_TAC THEN EQ_TAC THENL + [REWRITE_TAC[LEFT_IMP_EXISTS_THM; CONVERGENT_IMP_CAUCHY]; + REWRITE_TAC[REWRITE_RULE[complete; IN_UNIV] COMPLETE_UNIV]]);; + +let CONVERGENT_IMP_BOUNDED = prove + (`!s l. (s --> l) sequentially ==> bounded (IMAGE s (:num))`, + REWRITE_TAC[LEFT_FORALL_IMP_THM; CONVERGENT_EQ_CAUCHY] THEN + REPEAT GEN_TAC THEN DISCH_THEN(MP_TAC o MATCH_MP CAUCHY_IMP_BOUNDED) THEN + REWRITE_TAC[IMAGE; IN_UNIV]);; + +(* ------------------------------------------------------------------------- *) +(* Total boundedness. *) +(* ------------------------------------------------------------------------- *) + +let COMPACT_IMP_TOTALLY_BOUNDED = prove + (`!s:real^N->bool. + compact s + ==> !e. &0 < e ==> ?k. FINITE k /\ k SUBSET s /\ + s SUBSET (UNIONS(IMAGE (\x. ball(x,e)) k))`, + GEN_TAC THEN ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN + REWRITE_TAC[NOT_FORALL_THM; NOT_IMP; NOT_EXISTS_THM] THEN + REWRITE_TAC[TAUT `~(a /\ b /\ c) <=> a /\ b ==> ~c`; SUBSET] THEN + DISCH_THEN(X_CHOOSE_THEN `e:real` STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN + `?x:num->real^N. !n. x(n) IN s /\ !m. m < n ==> ~(dist(x(m),x(n)) < e)` + MP_TAC THENL + [SUBGOAL_THEN + `?x:num->real^N. + !n. x(n) = @y. y IN s /\ !m. m < n ==> ~(dist(x(m),y) < e)` + MP_TAC THENL + [MATCH_MP_TAC(MATCH_MP WF_REC WF_num) THEN SIMP_TAC[]; ALL_TAC] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `x:num->real^N` THEN + DISCH_TAC THEN MATCH_MP_TAC num_WF THEN X_GEN_TAC `n:num` THEN + FIRST_X_ASSUM(SUBST1_TAC o SPEC `n:num`) THEN STRIP_TAC THEN + CONV_TAC SELECT_CONV THEN + FIRST_X_ASSUM(MP_TAC o SPEC `IMAGE (x:num->real^N) {m | m < n}`) THEN + SIMP_TAC[FINITE_IMAGE; FINITE_NUMSEG_LT; NOT_FORALL_THM; NOT_IMP] THEN + REWRITE_TAC[IN_UNIONS; IN_IMAGE; IN_ELIM_THM] THEN ASM_MESON_TAC[IN_BALL]; + ALL_TAC] THEN + REWRITE_TAC[compact; NOT_FORALL_THM] THEN MATCH_MP_TAC MONO_EXISTS THEN + X_GEN_TAC `x:num->real^N` THEN REWRITE_TAC[NOT_IMP; FORALL_AND_THM] THEN + STRIP_TAC THEN ASM_REWRITE_TAC[NOT_EXISTS_THM] THEN REPEAT STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o MATCH_MP CONVERGENT_IMP_CAUCHY) THEN + REWRITE_TAC[cauchy] THEN DISCH_THEN(MP_TAC o SPEC `e:real`) THEN + ASM_REWRITE_TAC[o_THM; NOT_EXISTS_THM; NOT_IMP; NOT_FORALL_THM; NOT_IMP] THEN + X_GEN_TAC `N:num` THEN MAP_EVERY EXISTS_TAC [`N:num`; `SUC N`] THEN + CONJ_TAC THENL [ARITH_TAC; ASM_MESON_TAC[LT]]);; + +(* ------------------------------------------------------------------------- *) +(* Heine-Borel theorem (following Burkill & Burkill vol. 2) *) +(* ------------------------------------------------------------------------- *) + +let HEINE_BOREL_LEMMA = prove + (`!s:real^N->bool. + compact s + ==> !t. s SUBSET (UNIONS t) /\ (!b. b IN t ==> open b) + ==> ?e. &0 < e /\ + !x. x IN s ==> ?b. b IN t /\ ball(x,e) SUBSET b`, + GEN_TAC THEN ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN + REWRITE_TAC[NOT_FORALL_THM; NOT_IMP; NOT_EXISTS_THM] THEN + DISCH_THEN(CHOOSE_THEN (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + DISCH_THEN(MP_TAC o GEN `n:num` o SPEC `&1 / (&n + &1)`) THEN + SIMP_TAC[REAL_LT_DIV; REAL_LT_01; REAL_ARITH `x <= y ==> x < y + &1`; + FORALL_AND_THM; REAL_POS; NOT_FORALL_THM; NOT_IMP; SKOLEM_THM; compact] THEN + MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC THEN REWRITE_TAC[NOT_EXISTS_THM] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN ASM_REWRITE_TAC[] THEN + DISCH_TAC THEN MAP_EVERY X_GEN_TAC [`l:real^N`; `r:num->num`] THEN + STRIP_TAC THEN + SUBGOAL_THEN `?b:real^N->bool. l IN b /\ b IN t` STRIP_ASSUME_TAC THENL + [ASM_MESON_TAC[SUBSET; IN_UNIONS]; ALL_TAC] THEN + SUBGOAL_THEN `?e. &0 < e /\ !z:real^N. dist(z,l) < e ==> z IN b` + STRIP_ASSUME_TAC THENL [ASM_MESON_TAC[open_def]; ALL_TAC] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [LIM_SEQUENTIALLY]) THEN + DISCH_THEN(MP_TAC o SPEC `e / &2`) THEN + SUBGOAL_THEN `&0 < e / &2` (fun th -> + REWRITE_TAC[th; o_THM] THEN MP_TAC(GEN_REWRITE_RULE I [REAL_ARCH_INV] th)) + THENL [ASM_REWRITE_TAC[REAL_HALF]; ALL_TAC] THEN + DISCH_THEN(X_CHOOSE_THEN `N1:num` STRIP_ASSUME_TAC) THEN + DISCH_THEN(X_CHOOSE_THEN `N2:num` STRIP_ASSUME_TAC) THEN + FIRST_X_ASSUM(MP_TAC o SPECL + [`(r:num->num)(N1 + N2)`; `b:real^N->bool`]) THEN + ASM_REWRITE_TAC[SUBSET] THEN X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN MATCH_MP_TAC DIST_TRIANGLE_HALF_R THEN + EXISTS_TAC `(f:num->real^N)(r(N1 + N2:num))` THEN CONJ_TAC THENL + [ALL_TAC; FIRST_X_ASSUM MATCH_MP_TAC THEN ARITH_TAC] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_BALL]) THEN + MATCH_MP_TAC(REAL_ARITH `a <= b ==> x < a ==> x < b`) THEN + MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC `inv(&N1)` THEN + ASM_SIMP_TAC[REAL_LT_IMP_LE] THEN REWRITE_TAC[real_div; REAL_MUL_LID] THEN + MATCH_MP_TAC REAL_LE_INV2 THEN + REWRITE_TAC[REAL_OF_NUM_ADD; REAL_OF_NUM_LE; REAL_OF_NUM_LT] THEN + ASM_MESON_TAC[ARITH_RULE `(~(n = 0) ==> 0 < n)`; LE_ADD; MONOTONE_BIGGER; + LT_IMP_LE; LE_TRANS]);; + +let COMPACT_IMP_HEINE_BOREL = prove + (`!s. compact (s:real^N->bool) + ==> !f. (!t. t IN f ==> open t) /\ s SUBSET (UNIONS f) + ==> ?f'. f' SUBSET f /\ FINITE f' /\ s SUBSET (UNIONS f')`, + REPEAT STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o SPEC `f:(real^N->bool)->bool` o + MATCH_MP HEINE_BOREL_LEMMA) THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `e:real` (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [RIGHT_IMP_EXISTS_THM] THEN + REWRITE_TAC[SKOLEM_THM; SUBSET; IN_BALL] THEN + DISCH_THEN(X_CHOOSE_TAC `B:real^N->real^N->bool`) THEN + FIRST_ASSUM(MP_TAC o SPEC `e:real` o + MATCH_MP COMPACT_IMP_TOTALLY_BOUNDED) THEN + ASM_REWRITE_TAC[UNIONS_IMAGE; SUBSET; IN_ELIM_THM] THEN + REWRITE_TAC[IN_UNIONS; IN_BALL] THEN + DISCH_THEN(X_CHOOSE_THEN `k:real^N->bool` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `IMAGE (B:real^N->real^N->bool) k` THEN + ASM_SIMP_TAC[FINITE_IMAGE; SUBSET; IN_IMAGE; LEFT_IMP_EXISTS_THM] THEN + ASM_MESON_TAC[IN_BALL]);; + +(* ------------------------------------------------------------------------- *) +(* Bolzano-Weierstrass property. *) +(* ------------------------------------------------------------------------- *) + +let HEINE_BOREL_IMP_BOLZANO_WEIERSTRASS = prove + (`!s:real^N->bool. + (!f. (!t. t IN f ==> open t) /\ s SUBSET (UNIONS f) + ==> ?f'. f' SUBSET f /\ FINITE f' /\ s SUBSET (UNIONS f')) + ==> !t. INFINITE t /\ t SUBSET s ==> ?x. x IN s /\ x limit_point_of t`, + REWRITE_TAC[RIGHT_IMP_FORALL_THM; limit_point_of] THEN REPEAT GEN_TAC THEN + ONCE_REWRITE_TAC[TAUT `a ==> b /\ c ==> d <=> c ==> ~d ==> a ==> ~b`] THEN + REWRITE_TAC[NOT_FORALL_THM; NOT_EXISTS_THM; RIGHT_AND_FORALL_THM] THEN + DISCH_TAC THEN REWRITE_TAC[SKOLEM_THM] THEN + DISCH_THEN(X_CHOOSE_TAC `f:real^N->real^N->bool`) THEN + DISCH_THEN(MP_TAC o SPEC + `{t:real^N->bool | ?x:real^N. x IN s /\ (t = f x)}`) THEN + REWRITE_TAC[INFINITE; SUBSET; IN_ELIM_THM; IN_UNIONS; NOT_IMP] THEN + ANTS_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN + DISCH_THEN(X_CHOOSE_THEN `g:(real^N->bool)->bool` STRIP_ASSUME_TAC) THEN + MATCH_MP_TAC FINITE_SUBSET THEN + EXISTS_TAC `{x:real^N | x IN t /\ (f(x):real^N->bool) IN g}` THEN + CONJ_TAC THENL + [MATCH_MP_TAC FINITE_IMAGE_INJ_GENERAL THEN ASM_MESON_TAC[SUBSET]; + SIMP_TAC[SUBSET; IN_ELIM_THM] THEN X_GEN_TAC `u:real^N` THEN + DISCH_TAC THEN SUBGOAL_THEN `(u:real^N) IN s` ASSUME_TAC THEN + ASM_MESON_TAC[SUBSET]]);; + +(* ------------------------------------------------------------------------- *) +(* Complete the chain of compactness variants. *) +(* ------------------------------------------------------------------------- *) + +let BOLZANO_WEIERSTRASS_IMP_BOUNDED = prove + (`!s:real^N->bool. + (!t. INFINITE t /\ t SUBSET s ==> ?x. x IN s /\ x limit_point_of t) + ==> bounded s`, + GEN_TAC THEN ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN + SIMP_TAC[compact; bounded] THEN + REWRITE_TAC[NOT_FORALL_THM; NOT_EXISTS_THM; SKOLEM_THM; NOT_IMP] THEN + REWRITE_TAC[REAL_NOT_LE] THEN + DISCH_THEN(X_CHOOSE_TAC `beyond:real->real^N`) THEN + (MP_TAC o prove_recursive_functions_exist num_RECURSION) + `(f(0) = beyond(&0)) /\ + (!n. f(SUC n) = beyond(norm(f n) + &1):real^N)` THEN + DISCH_THEN(X_CHOOSE_THEN `x:num->real^N` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `IMAGE (x:num->real^N) UNIV` THEN + SUBGOAL_THEN + `!m n. m < n ==> norm((x:num->real^N) m) + &1 < norm(x n)` + ASSUME_TAC THENL + [GEN_TAC THEN INDUCT_TAC THEN ASM_REWRITE_TAC[LT] THEN + ASM_MESON_TAC[REAL_LT_TRANS; REAL_ARITH `b < b + &1`]; + ALL_TAC] THEN + SUBGOAL_THEN `!m n. ~(m = n) ==> &1 < dist((x:num->real^N) m,x n)` + ASSUME_TAC THENL + [REPEAT GEN_TAC THEN REPEAT_TCL DISJ_CASES_THEN ASSUME_TAC + (SPECL [`m:num`; `n:num`] LT_CASES) THEN + ASM_MESON_TAC[dist; LT_CASES; NORM_TRIANGLE_SUB; NORM_SUB; + REAL_ARITH `x + &1 < y /\ y <= x + d ==> &1 < d`]; + ALL_TAC] THEN + REPEAT CONJ_TAC THENL + [ASM_MESON_TAC[INFINITE_IMAGE_INJ; num_INFINITE; DIST_REFL; + REAL_ARITH `~(&1 < &0)`]; + REWRITE_TAC[SUBSET; IN_IMAGE; IN_UNIV; LEFT_IMP_EXISTS_THM] THEN + GEN_TAC THEN INDUCT_TAC THEN ASM_MESON_TAC[]; + ALL_TAC] THEN + X_GEN_TAC `l:real^N` THEN REWRITE_TAC[LIMPT_APPROACHABLE] THEN + REWRITE_TAC[IN_IMAGE; IN_UNIV; LEFT_AND_EXISTS_THM] THEN + ONCE_REWRITE_TAC[SWAP_EXISTS_THM] THEN REWRITE_TAC[UNWIND_THM2] THEN + STRIP_TAC THEN FIRST_ASSUM(MP_TAC o SPEC `&1 / &2`) THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN + DISCH_THEN(X_CHOOSE_THEN `k:num` STRIP_ASSUME_TAC) THEN + FIRST_X_ASSUM(MP_TAC o SPEC `dist((x:num->real^N) k,l)`) THEN + ASM_SIMP_TAC[DIST_POS_LT] THEN + DISCH_THEN(X_CHOOSE_THEN `m:num` STRIP_ASSUME_TAC) THEN + ASM_CASES_TAC `m:num = k` THEN + ASM_MESON_TAC[DIST_TRIANGLE_HALF_L; REAL_LT_TRANS; REAL_LT_REFL]);; + +let SEQUENCE_INFINITE_LEMMA = prove + (`!f l. (!n. ~(f(n) = l)) /\ (f --> l) sequentially + ==> INFINITE {y:real^N | ?n. y = f n}`, + REWRITE_TAC[INFINITE] THEN REPEAT STRIP_TAC THEN MP_TAC(ISPEC + `IMAGE (\y:real^N. dist(y,l)) {y | ?n:num. y = f n}` INF_FINITE) THEN + ASM_SIMP_TAC[GSYM MEMBER_NOT_EMPTY; IN_IMAGE; FINITE_IMAGE; IN_ELIM_THM] THEN + ASM_MESON_TAC[LIM_SEQUENTIALLY; LE_REFL; REAL_NOT_LE; DIST_POS_LT]);; + +let LIMPT_OF_SEQUENCE_SUBSEQUENCE = prove + (`!f:num->real^N l. + l limit_point_of (IMAGE f (:num)) + ==> ?r. (!m n. m < n ==> r(m) < r(n)) /\ ((f o r) --> l) sequentially`, + REPEAT STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [LIMPT_APPROACHABLE]) THEN + DISCH_THEN(MP_TAC o GEN `n:num` o SPEC + `inf((inv(&n + &1)) INSERT + IMAGE (\k. dist((f:num->real^N) k,l)) + {k | k IN 0..n /\ ~(f k = l)})`) THEN + SIMP_TAC[REAL_LT_INF_FINITE; FINITE_INSERT; NOT_INSERT_EMPTY; + FINITE_RESTRICT; FINITE_NUMSEG; FINITE_IMAGE] THEN + REWRITE_TAC[FORALL_IN_INSERT; EXISTS_IN_IMAGE; FORALL_IN_IMAGE; IN_UNIV] THEN + REWRITE_TAC[REAL_LT_INV_EQ; REAL_ARITH `&0 < &n + &1`] THEN + SIMP_TAC[FORALL_AND_THM; FORALL_IN_GSPEC; GSYM DIST_NZ; SKOLEM_THM] THEN + DISCH_THEN(X_CHOOSE_THEN `nn:num->num` STRIP_ASSUME_TAC) THEN + (MP_TAC o prove_recursive_functions_exist num_RECURSION) + `r 0 = nn 0 /\ (!n. r (SUC n) = nn(r n))` THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `r:num->num` THEN + STRIP_TAC THEN + MATCH_MP_TAC(TAUT `p /\ (p ==> q) ==> p /\ q`) THEN CONJ_TAC THENL + [MATCH_MP_TAC TRANSITIVE_STEPWISE_LT THEN REWRITE_TAC[LT_TRANS] THEN + X_GEN_TAC `n:num` THEN ASM_REWRITE_TAC[] THEN + FIRST_X_ASSUM(MP_TAC o SPECL + [`(r:num->num) n`; `(nn:num->num)(r(n:num))`]) THEN + ASM_REWRITE_TAC[IN_NUMSEG; LE_0; REAL_LT_REFL] THEN ARITH_TAC; + DISCH_THEN(ASSUME_TAC o MATCH_MP MONOTONE_BIGGER)] THEN + REWRITE_TAC[LIM_SEQUENTIALLY] THEN + X_GEN_TAC `e:real` THEN GEN_REWRITE_TAC LAND_CONV [REAL_ARCH_INV] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `N:num` THEN STRIP_TAC THEN + MATCH_MP_TAC num_INDUCTION THEN ASM_REWRITE_TAC[CONJUNCT1 LE] THEN + X_GEN_TAC `n:num` THEN DISCH_THEN(K ALL_TAC) THEN DISCH_TAC THEN + ASM_REWRITE_TAC[o_THM] THEN MATCH_MP_TAC REAL_LT_TRANS THEN + EXISTS_TAC `inv(&((r:num->num) n) + &1)` THEN ASM_REWRITE_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 + ASM_SIMP_TAC[REAL_OF_NUM_LE; REAL_OF_NUM_LT; LE_1; REAL_OF_NUM_ADD] THEN + MATCH_MP_TAC(ARITH_RULE `N <= SUC n /\ n <= r n ==> N <= r n + 1`) THEN + ASM_REWRITE_TAC[]);; + +let SEQUENCE_UNIQUE_LIMPT = prove + (`!f l l':real^N. + (f --> l) sequentially /\ l' limit_point_of {y | ?n. y = f n} + ==> l' = l`, + REWRITE_TAC[SET_RULE `{y | ?n. y = f n} = IMAGE f (:num)`] THEN + REPEAT STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o MATCH_MP LIMPT_OF_SEQUENCE_SUBSEQUENCE) THEN + DISCH_THEN(X_CHOOSE_THEN `r:num->num` STRIP_ASSUME_TAC) THEN + MATCH_MP_TAC(ISPEC `sequentially` LIM_UNIQUE) THEN + EXISTS_TAC `(f:num->real^N) o (r:num->num)` THEN + ASM_SIMP_TAC[TRIVIAL_LIMIT_SEQUENTIALLY; LIM_SUBSEQUENCE]);; + +let BOLZANO_WEIERSTRASS_IMP_CLOSED = prove + (`!s:real^N->bool. + (!t. INFINITE t /\ t SUBSET s ==> ?x. x IN s /\ x limit_point_of t) + ==> closed s`, + REPEAT STRIP_TAC THEN REWRITE_TAC[CLOSED_SEQUENTIAL_LIMITS] THEN + MAP_EVERY X_GEN_TAC [`f:num->real^N`; `l:real^N`] THEN + DISCH_TAC THEN + MAP_EVERY (MP_TAC o ISPECL [`f:num->real^N`; `l:real^N`]) + [SEQUENCE_UNIQUE_LIMPT; SEQUENCE_INFINITE_LEMMA] THEN + MATCH_MP_TAC(TAUT + `(~d ==> a /\ ~(b /\ c)) ==> (a ==> b) ==> c ==> d`) THEN + DISCH_TAC THEN CONJ_TAC THENL [ASM_MESON_TAC[]; STRIP_TAC] THEN + FIRST_X_ASSUM(MP_TAC o SPEC `{y:real^N | ?n:num. y = f n}`) THEN + ASM_REWRITE_TAC[NOT_IMP] THEN CONJ_TAC THENL + [REWRITE_TAC[SUBSET; IN_ELIM_THM]; + ABBREV_TAC `t = {y:real^N | ?n:num. y = f n}`] THEN + ASM_MESON_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* Hence express everything as an equivalence. *) +(* ------------------------------------------------------------------------- *) + +let COMPACT_EQ_HEINE_BOREL = prove + (`!s:real^N->bool. + compact s <=> + !f. (!t. t IN f ==> open t) /\ s SUBSET (UNIONS f) + ==> ?f'. f' SUBSET f /\ FINITE f' /\ s SUBSET (UNIONS f')`, + GEN_TAC THEN EQ_TAC THEN SIMP_TAC[COMPACT_IMP_HEINE_BOREL] THEN + DISCH_THEN(MP_TAC o MATCH_MP HEINE_BOREL_IMP_BOLZANO_WEIERSTRASS) THEN + DISCH_TAC THEN MATCH_MP_TAC BOUNDED_CLOSED_IMP_COMPACT THEN + ASM_SIMP_TAC[BOLZANO_WEIERSTRASS_IMP_BOUNDED; + BOLZANO_WEIERSTRASS_IMP_CLOSED]);; + +let COMPACT_EQ_BOLZANO_WEIERSTRASS = prove + (`!s:real^N->bool. + compact s <=> + !t. INFINITE t /\ t SUBSET s ==> ?x. x IN s /\ x limit_point_of t`, + GEN_TAC THEN EQ_TAC THENL + [SIMP_TAC[COMPACT_EQ_HEINE_BOREL; HEINE_BOREL_IMP_BOLZANO_WEIERSTRASS]; + SIMP_TAC[BOLZANO_WEIERSTRASS_IMP_BOUNDED; BOLZANO_WEIERSTRASS_IMP_CLOSED; + BOUNDED_CLOSED_IMP_COMPACT]]);; + +let COMPACT_EQ_BOUNDED_CLOSED = prove + (`!s:real^N->bool. compact s <=> bounded s /\ closed s`, + GEN_TAC THEN EQ_TAC THEN REWRITE_TAC[BOUNDED_CLOSED_IMP_COMPACT] THEN + SIMP_TAC[COMPACT_EQ_BOLZANO_WEIERSTRASS; BOLZANO_WEIERSTRASS_IMP_BOUNDED; + BOLZANO_WEIERSTRASS_IMP_CLOSED]);; + +let COMPACT_IMP_BOUNDED = prove + (`!s. compact s ==> bounded s`, + SIMP_TAC[COMPACT_EQ_BOUNDED_CLOSED]);; + +let COMPACT_IMP_CLOSED = prove + (`!s. compact s ==> closed s`, + SIMP_TAC[COMPACT_EQ_BOUNDED_CLOSED]);; + +let COMPACT_SEQUENCE_WITH_LIMIT = prove + (`!f l:real^N. + (f --> l) sequentially ==> compact (l INSERT IMAGE f (:num))`, + REPEAT STRIP_TAC THEN REWRITE_TAC[COMPACT_EQ_BOUNDED_CLOSED] THEN + REWRITE_TAC[BOUNDED_INSERT] THEN CONJ_TAC THENL + [ASM_MESON_TAC[CONVERGENT_IMP_BOUNDED]; + SIMP_TAC[CLOSED_LIMPT; LIMPT_INSERT; IN_INSERT] THEN + REWRITE_TAC[IMAGE; IN_UNIV] THEN REPEAT STRIP_TAC THEN DISJ1_TAC THEN + MATCH_MP_TAC SEQUENCE_UNIQUE_LIMPT THEN ASM_MESON_TAC[]]);; + +let CLOSED_IN_COMPACT = prove + (`!s t:real^N->bool. + compact s /\ closed_in (subtopology euclidean s) t + ==> compact t`, + SIMP_TAC[IMP_CONJ; COMPACT_EQ_BOUNDED_CLOSED; CLOSED_IN_CLOSED_EQ] THEN + MESON_TAC[BOUNDED_SUBSET]);; + +(* ------------------------------------------------------------------------- *) +(* A version of Heine-Borel for subtopology. *) +(* ------------------------------------------------------------------------- *) + +let COMPACT_EQ_HEINE_BOREL_SUBTOPOLOGY = prove + (`!s:real^N->bool. + compact s <=> + (!f. (!t. t IN f ==> open_in(subtopology euclidean s) t) /\ + s SUBSET UNIONS f + ==> ?f'. f' SUBSET f /\ FINITE f' /\ s SUBSET UNIONS f')`, + GEN_TAC THEN REWRITE_TAC[COMPACT_EQ_HEINE_BOREL] THEN EQ_TAC THEN + DISCH_TAC THEN X_GEN_TAC `f:(real^N->bool)->bool` THENL + [REWRITE_TAC[OPEN_IN_OPEN] THEN + GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [RIGHT_IMP_EXISTS_THM] THEN + REWRITE_TAC[SKOLEM_THM] THEN + DISCH_THEN(CONJUNCTS_THEN2 + (X_CHOOSE_TAC `m:(real^N->bool)->(real^N->bool)`) ASSUME_TAC) THEN + FIRST_X_ASSUM(MP_TAC o SPEC + `IMAGE (m:(real^N->bool)->(real^N->bool)) f`) THEN + ASM_SIMP_TAC[FORALL_IN_IMAGE] THEN + ANTS_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + DISCH_THEN(X_CHOOSE_THEN `f':(real^N->bool)->bool` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `IMAGE (\t:real^N->bool. s INTER t) f'` THEN + ASM_SIMP_TAC[FINITE_IMAGE; UNIONS_IMAGE; SUBSET; FORALL_IN_IMAGE] THEN + CONJ_TAC THENL [ALL_TAC; ASM SET_TAC[]] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [SUBSET_IMAGE]) THEN + STRIP_TAC THEN ASM_REWRITE_TAC[FORALL_IN_IMAGE] THEN ASM_MESON_TAC[SUBSET]; + DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `{s INTER t:real^N->bool | t IN f}`) THEN + REWRITE_TAC[SIMPLE_IMAGE; FORALL_IN_IMAGE; OPEN_IN_OPEN; UNIONS_IMAGE] THEN + ANTS_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + ONCE_REWRITE_TAC[TAUT `a /\ b /\ c <=> b /\ a /\ c`] THEN + REWRITE_TAC[EXISTS_FINITE_SUBSET_IMAGE; UNIONS_IMAGE] THEN + MATCH_MP_TAC MONO_EXISTS THEN SET_TAC[]]);; + +(* ------------------------------------------------------------------------- *) +(* More easy lemmas. *) +(* ------------------------------------------------------------------------- *) + +let COMPACT_CLOSURE = prove + (`!s. compact(closure s) <=> bounded s`, + REWRITE_TAC[COMPACT_EQ_BOUNDED_CLOSED; CLOSED_CLOSURE; BOUNDED_CLOSURE_EQ]);; + +let BOLZANO_WEIERSTRASS_CONTRAPOS = prove + (`!s t:real^N->bool. + compact s /\ t SUBSET s /\ + (!x. x IN s ==> ~(x limit_point_of t)) + ==> FINITE t`, + REWRITE_TAC[COMPACT_EQ_BOLZANO_WEIERSTRASS; INFINITE] THEN MESON_TAC[]);; + +let DISCRETE_BOUNDED_IMP_FINITE = prove + (`!s:real^N->bool e. + &0 < e /\ + (!x y. x IN s /\ y IN s /\ norm(y - x) < e ==> y = x) /\ + bounded s + ==> FINITE s`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN `compact(s:real^N->bool)` MP_TAC THENL + [ASM_REWRITE_TAC[COMPACT_EQ_BOUNDED_CLOSED] THEN + ASM_MESON_TAC[DISCRETE_IMP_CLOSED]; + DISCH_THEN(MP_TAC o MATCH_MP COMPACT_IMP_HEINE_BOREL)] THEN + DISCH_THEN(MP_TAC o SPEC `IMAGE (\x:real^N. ball(x,e)) s`) THEN + REWRITE_TAC[FORALL_IN_IMAGE; OPEN_BALL; UNIONS_IMAGE; IN_ELIM_THM] THEN + ANTS_TAC THENL + [REWRITE_TAC[SUBSET; IN_ELIM_THM] THEN ASM_MESON_TAC[CENTRE_IN_BALL]; + ONCE_REWRITE_TAC[TAUT `a /\ b /\ c <=> b /\ a /\ c`]] THEN + REWRITE_TAC[EXISTS_FINITE_SUBSET_IMAGE] THEN + DISCH_THEN(X_CHOOSE_THEN `t:real^N->bool` STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN `s:real^N->bool = t` (fun th -> ASM_REWRITE_TAC[th]) THEN + MATCH_MP_TAC SUBSET_ANTISYM THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[SUBSET] THEN X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE RAND_CONV [UNIONS_IMAGE]) THEN + DISCH_THEN(MP_TAC o SPEC `x:real^N` o GEN_REWRITE_RULE I [SUBSET]) THEN + ASM_REWRITE_TAC[IN_ELIM_THM; IN_BALL; dist] THEN ASM_MESON_TAC[SUBSET]);; + +let BOLZANO_WEIERSTRASS = prove + (`!s:real^N->bool. bounded s /\ INFINITE s ==> ?x. x limit_point_of s`, + GEN_TAC THEN ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN DISCH_TAC THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP NO_LIMIT_POINT_IMP_CLOSED) THEN + STRIP_TAC THEN + MP_TAC(ISPEC `s:real^N->bool` COMPACT_EQ_BOLZANO_WEIERSTRASS) THEN + ASM_REWRITE_TAC[COMPACT_EQ_BOUNDED_CLOSED] THEN + DISCH_THEN(MP_TAC o SPEC `s:real^N->bool`) THEN + ASM_REWRITE_TAC[SUBSET_REFL] THEN ASM_MESON_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* In particular, some common special cases. *) +(* ------------------------------------------------------------------------- *) + +let COMPACT_EMPTY = prove + (`compact {}`, + REWRITE_TAC[compact; NOT_IN_EMPTY]);; + +let COMPACT_UNION = prove + (`!s t. compact s /\ compact t ==> compact (s UNION t)`, + SIMP_TAC[COMPACT_EQ_BOUNDED_CLOSED; BOUNDED_UNION; CLOSED_UNION]);; + +let COMPACT_INTER = prove + (`!s t. compact s /\ compact t ==> compact (s INTER t)`, + SIMP_TAC[COMPACT_EQ_BOUNDED_CLOSED; BOUNDED_INTER; CLOSED_INTER]);; + +let COMPACT_INTER_CLOSED = prove + (`!s t. compact s /\ closed t ==> compact (s INTER t)`, + SIMP_TAC[COMPACT_EQ_BOUNDED_CLOSED; CLOSED_INTER] THEN + MESON_TAC[BOUNDED_SUBSET; INTER_SUBSET]);; + +let CLOSED_INTER_COMPACT = prove + (`!s t. closed s /\ compact t ==> compact (s INTER t)`, + MESON_TAC[COMPACT_INTER_CLOSED; INTER_COMM]);; + +let COMPACT_INTERS = prove + (`!f:(real^N->bool)->bool. + (!s. s IN f ==> compact s) /\ ~(f = {}) + ==> compact(INTERS f)`, + SIMP_TAC[COMPACT_EQ_BOUNDED_CLOSED; CLOSED_INTERS] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC BOUNDED_INTERS THEN ASM SET_TAC[]);; + +let FINITE_IMP_CLOSED = prove + (`!s. FINITE s ==> closed s`, + MESON_TAC[BOLZANO_WEIERSTRASS_IMP_CLOSED; INFINITE; FINITE_SUBSET]);; + +let FINITE_IMP_CLOSED_IN = prove + (`!s t. FINITE s /\ s SUBSET t ==> closed_in (subtopology euclidean t) s`, + SIMP_TAC[CLOSED_SUBSET_EQ; FINITE_IMP_CLOSED]);; + +let FINITE_IMP_COMPACT = prove + (`!s. FINITE s ==> compact s`, + SIMP_TAC[COMPACT_EQ_BOUNDED_CLOSED; FINITE_IMP_CLOSED; FINITE_IMP_BOUNDED]);; + +let COMPACT_SING = prove + (`!a. compact {a}`, + SIMP_TAC[FINITE_IMP_COMPACT; FINITE_RULES]);; + +let COMPACT_INSERT = prove + (`!a s. compact s ==> compact(a INSERT s)`, + ONCE_REWRITE_TAC[SET_RULE `a INSERT s = {a} UNION s`] THEN + SIMP_TAC[COMPACT_UNION; COMPACT_SING]);; + +let CLOSED_SING = prove + (`!a. closed {a}`, + MESON_TAC[COMPACT_EQ_BOUNDED_CLOSED; COMPACT_SING]);; + +let CLOSED_IN_SING = prove + (`!u x:real^N. closed_in (subtopology euclidean u) {x} <=> x IN u`, + SIMP_TAC[CLOSED_SUBSET_EQ; CLOSED_SING] THEN SET_TAC[]);; + +let CLOSURE_SING = prove + (`!x:real^N. closure {x} = {x}`, + SIMP_TAC[CLOSURE_CLOSED; CLOSED_SING]);; + +let CLOSED_INSERT = prove + (`!a s. closed s ==> closed(a INSERT s)`, + ONCE_REWRITE_TAC[SET_RULE `a INSERT s = {a} UNION s`] THEN + SIMP_TAC[CLOSED_UNION; CLOSED_SING]);; + +let COMPACT_CBALL = prove + (`!x e. compact(cball(x,e))`, + REWRITE_TAC[COMPACT_EQ_BOUNDED_CLOSED; BOUNDED_CBALL; CLOSED_CBALL]);; + +let COMPACT_FRONTIER_BOUNDED = prove + (`!s. bounded s ==> compact(frontier s)`, + SIMP_TAC[frontier; COMPACT_EQ_BOUNDED_CLOSED; + CLOSED_DIFF; OPEN_INTERIOR; CLOSED_CLOSURE] THEN + MESON_TAC[SUBSET_DIFF; BOUNDED_SUBSET; BOUNDED_CLOSURE]);; + +let COMPACT_FRONTIER = prove + (`!s. compact s ==> compact (frontier s)`, + MESON_TAC[COMPACT_EQ_BOUNDED_CLOSED; COMPACT_FRONTIER_BOUNDED]);; + +let BOUNDED_FRONTIER = prove + (`!s:real^N->bool. bounded s ==> bounded(frontier s)`, + MESON_TAC[COMPACT_FRONTIER_BOUNDED; COMPACT_IMP_BOUNDED]);; + +let FRONTIER_SUBSET_COMPACT = prove + (`!s. compact s ==> frontier s SUBSET s`, + MESON_TAC[FRONTIER_SUBSET_CLOSED; COMPACT_EQ_BOUNDED_CLOSED]);; + +let OPEN_DELETE = prove + (`!s x. open s ==> open(s DELETE x)`, + let lemma = prove(`s DELETE x = s DIFF {x}`,SET_TAC[]) in + SIMP_TAC[lemma; OPEN_DIFF; CLOSED_SING]);; + +let OPEN_IN_DELETE = prove + (`!u s a:real^N. + open_in (subtopology euclidean u) s + ==> open_in (subtopology euclidean u) (s DELETE a)`, + REPEAT STRIP_TAC THEN ASM_CASES_TAC `(a:real^N) IN s` THENL + [ONCE_REWRITE_TAC[SET_RULE `s DELETE a = s DIFF {a}`] THEN + MATCH_MP_TAC OPEN_IN_DIFF THEN ASM_REWRITE_TAC[CLOSED_IN_SING] THEN + FIRST_X_ASSUM(MP_TAC o MATCH_MP OPEN_IN_IMP_SUBSET) THEN ASM SET_TAC[]; + ASM_SIMP_TAC[SET_RULE `~(a IN s) ==> s DELETE a = s`]]);; + +let CLOSED_INTERS_COMPACT = prove + (`!s:real^N->bool. + closed s <=> !e. compact(cball(vec 0,e) INTER s)`, + GEN_TAC THEN EQ_TAC THENL + [SIMP_TAC[COMPACT_EQ_BOUNDED_CLOSED; CLOSED_INTER; CLOSED_CBALL; + BOUNDED_INTER; BOUNDED_CBALL]; + ALL_TAC] THEN + STRIP_TAC THEN REWRITE_TAC[CLOSED_LIMPT] THEN + X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `norm(x:real^N) + &1`) THEN + DISCH_THEN(MP_TAC o MATCH_MP COMPACT_IMP_CLOSED) THEN + REWRITE_TAC[CLOSED_LIMPT] THEN DISCH_THEN(MP_TAC o SPEC `x:real^N`) THEN + REWRITE_TAC[IN_INTER] THEN ANTS_TAC THENL [ALL_TAC; MESON_TAC[]] THEN + POP_ASSUM MP_TAC THEN REWRITE_TAC[LIMPT_APPROACHABLE] THEN + DISCH_TAC THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `min e (&1 / &2)`) THEN + ANTS_TAC THENL [ASM_REAL_ARITH_TAC; MATCH_MP_TAC MONO_EXISTS] THEN + X_GEN_TAC `y:real^N` THEN SIMP_TAC[IN_INTER; IN_CBALL] THEN NORM_ARITH_TAC);; + +let COMPACT_UNIONS = prove + (`!s. FINITE s /\ (!t. t IN s ==> compact t) ==> compact(UNIONS s)`, + SIMP_TAC[COMPACT_EQ_BOUNDED_CLOSED; CLOSED_UNIONS; BOUNDED_UNIONS]);; + +let COMPACT_DIFF = prove + (`!s t. compact s /\ open t ==> compact(s DIFF t)`, + ONCE_REWRITE_TAC[SET_RULE `s DIFF t = s INTER (UNIV DIFF t)`] THEN + SIMP_TAC[COMPACT_INTER_CLOSED; GSYM OPEN_CLOSED]);; + +let COMPACT_SPHERE = prove + (`!a:real^N r. compact(sphere(a,r))`, + REPEAT GEN_TAC THEN + REWRITE_TAC[GSYM FRONTIER_CBALL] THEN MATCH_MP_TAC COMPACT_FRONTIER THEN + REWRITE_TAC[COMPACT_CBALL]);; + +let BOUNDED_SPHERE = prove + (`!a:real^N r. bounded(sphere(a,r))`, + SIMP_TAC[COMPACT_SPHERE; COMPACT_IMP_BOUNDED]);; + +let CLOSED_SPHERE = prove + (`!a r. closed(sphere(a,r))`, + SIMP_TAC[COMPACT_SPHERE; COMPACT_IMP_CLOSED]);; + +let FRONTIER_SING = prove + (`!a:real^N. frontier {a} = {a}`, + REWRITE_TAC[frontier; CLOSURE_SING; INTERIOR_SING; DIFF_EMPTY]);; + +(* ------------------------------------------------------------------------- *) +(* Finite intersection property. I could make it an equivalence in fact. *) +(* ------------------------------------------------------------------------- *) + +let COMPACT_IMP_FIP = prove + (`!s:real^N->bool f. + compact s /\ + (!t. t IN f ==> closed t) /\ + (!f'. FINITE f' /\ f' SUBSET f ==> ~(s INTER (INTERS f') = {})) + ==> ~(s INTER (INTERS f) = {})`, + let lemma = prove(`(s = UNIV DIFF t) <=> (UNIV DIFF s = t)`,SET_TAC[]) in + REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [COMPACT_EQ_HEINE_BOREL]) THEN + DISCH_THEN(MP_TAC o SPEC `IMAGE (\t:real^N->bool. UNIV DIFF t) f`) THEN + ASM_SIMP_TAC[FORALL_IN_IMAGE] THEN + DISCH_THEN(fun th -> REPEAT STRIP_TAC THEN MP_TAC th) THEN + ASM_SIMP_TAC[OPEN_DIFF; CLOSED_DIFF; OPEN_UNIV; CLOSED_UNIV; NOT_IMP] THEN + CONJ_TAC THENL + [UNDISCH_TAC `(s:real^N->bool) INTER INTERS f = {}` THEN + ONCE_REWRITE_TAC[SUBSET; EXTENSION] THEN + REWRITE_TAC[IN_UNIONS; EXISTS_IN_IMAGE] THEN SET_TAC[]; + DISCH_THEN(X_CHOOSE_THEN `g:(real^N->bool)->bool` MP_TAC) THEN + FIRST_X_ASSUM(MP_TAC o SPEC `IMAGE (\t:real^N->bool. UNIV DIFF t) g`) THEN + ASM_CASES_TAC `FINITE(g:(real^N->bool)->bool)` THEN + ASM_SIMP_TAC[FINITE_IMAGE] THEN ONCE_REWRITE_TAC[SUBSET; EXTENSION] THEN + REWRITE_TAC[FORALL_IN_IMAGE; IN_INTER; IN_INTERS; IN_IMAGE; IN_DIFF; + IN_UNIV; NOT_IN_EMPTY; lemma; UNWIND_THM1; IN_UNIONS] THEN + SET_TAC[]]);; + +let CLOSED_FIP = prove + (`!f. (!t:real^N->bool. t IN f ==> closed t) /\ (?t. t IN f /\ bounded t) /\ + (!f'. FINITE f' /\ f' SUBSET f ==> ~(INTERS f' = {})) + ==> ~(INTERS f = {})`, + GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + DISCH_THEN(CONJUNCTS_THEN2 (X_CHOOSE_THEN `s:real^N->bool` STRIP_ASSUME_TAC) + ASSUME_TAC) THEN + MATCH_MP_TAC(SET_RULE `!s. ~(s INTER f = {}) ==> ~(f = {})`) THEN + EXISTS_TAC `s:real^N->bool` THEN MATCH_MP_TAC COMPACT_IMP_FIP THEN + ASM_SIMP_TAC[COMPACT_EQ_BOUNDED_CLOSED] THEN + GEN_TAC THEN STRIP_TAC THEN MATCH_MP_TAC COMPACT_IMP_FIP THEN + ASM_SIMP_TAC[COMPACT_EQ_BOUNDED_CLOSED] THEN + CONJ_TAC THENL [ASM_MESON_TAC[SUBSET]; ALL_TAC] THEN + GEN_TAC THEN STRIP_TAC THEN REWRITE_TAC[GSYM INTERS_INSERT] THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_REWRITE_TAC[FINITE_INSERT] THEN ASM SET_TAC[]);; + +let COMPACT_FIP = prove + (`!f. (!t:real^N->bool. t IN f ==> compact t) /\ + (!f'. FINITE f' /\ f' SUBSET f ==> ~(INTERS f' = {})) + ==> ~(INTERS f = {})`, + GEN_TAC THEN STRIP_TAC THEN + ASM_CASES_TAC `f:(real^N->bool)->bool = {}` THEN + ASM_REWRITE_TAC[INTERS_0; UNIV_NOT_EMPTY] THEN + MATCH_MP_TAC CLOSED_FIP THEN + ASM_SIMP_TAC[COMPACT_IMP_CLOSED] THEN + ASM_MESON_TAC[MEMBER_NOT_EMPTY; COMPACT_IMP_BOUNDED]);; + +(* ------------------------------------------------------------------------- *) +(* Bounded closed nest property (proof does not use Heine-Borel). *) +(* ------------------------------------------------------------------------- *) + +let BOUNDED_CLOSED_NEST = prove + (`!s. (!n. closed(s n)) /\ (!n. ~(s n = {})) /\ + (!m n. m <= n ==> s(n) SUBSET s(m)) /\ + bounded(s 0) + ==> ?a:real^N. !n:num. a IN s(n)`, + GEN_TAC THEN REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; SKOLEM_THM] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + DISCH_THEN(CONJUNCTS_THEN2 + (X_CHOOSE_TAC `a:num->real^N`) STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN `compact(s 0:real^N->bool)` MP_TAC THENL + [ASM_MESON_TAC[BOUNDED_CLOSED_IMP_COMPACT]; ALL_TAC] THEN + REWRITE_TAC[compact] THEN + DISCH_THEN(MP_TAC o SPEC `a:num->real^N`) THEN + ANTS_TAC THENL [ASM_MESON_TAC[SUBSET; LE_0]; ALL_TAC] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `l:real^N` THEN + REWRITE_TAC[LIM_SEQUENTIALLY; o_THM] THEN + DISCH_THEN(X_CHOOSE_THEN `r:num->num` STRIP_ASSUME_TAC) THEN + GEN_REWRITE_TAC I [TAUT `p <=> ~(~p)`] THEN + GEN_REWRITE_TAC RAND_CONV [NOT_FORALL_THM] THEN + DISCH_THEN(X_CHOOSE_THEN `N:num` MP_TAC) THEN + MP_TAC(ISPECL [`l:real^N`; `(s:num->real^N->bool) N`] + CLOSED_APPROACHABLE) THEN + ASM_MESON_TAC[SUBSET; LE_REFL; LE_TRANS; LE_CASES; MONOTONE_BIGGER]);; + +(* ------------------------------------------------------------------------- *) +(* Decreasing case does not even need compactness, just completeness. *) +(* ------------------------------------------------------------------------- *) + +let DECREASING_CLOSED_NEST = prove + (`!s. (!n. closed(s n)) /\ (!n. ~(s n = {})) /\ + (!m n. m <= n ==> s(n) SUBSET s(m)) /\ + (!e. &0 < e ==> ?n. !x y. x IN s(n) /\ y IN s(n) ==> dist(x,y) < e) + ==> ?a:real^N. !n:num. a IN s(n)`, + GEN_TAC THEN REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; SKOLEM_THM] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + DISCH_THEN(CONJUNCTS_THEN2 + (X_CHOOSE_TAC `a:num->real^N`) STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN `?l:real^N. (a --> l) sequentially` MP_TAC THENL + [ASM_MESON_TAC[cauchy; GE; SUBSET; LE_TRANS; LE_REFL; + complete; COMPLETE_UNIV; IN_UNIV]; + ASM_MESON_TAC[LIM_SEQUENTIALLY; CLOSED_APPROACHABLE; + SUBSET; LE_REFL; LE_TRANS; LE_CASES]]);; + +(* ------------------------------------------------------------------------- *) +(* Strengthen it to the intersection actually being a singleton. *) +(* ------------------------------------------------------------------------- *) + +let DECREASING_CLOSED_NEST_SING = prove + (`!s. (!n. closed(s n)) /\ (!n. ~(s n = {})) /\ + (!m n. m <= n ==> s(n) SUBSET s(m)) /\ + (!e. &0 < e ==> ?n. !x y. x IN s(n) /\ y IN s(n) ==> dist(x,y) < e) + ==> ?a:real^N. INTERS {t | ?n:num. t = s n} = {a}`, + GEN_TAC THEN DISCH_TAC THEN + FIRST_ASSUM(MP_TAC o MATCH_MP DECREASING_CLOSED_NEST) THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `a:real^N` THEN + DISCH_TAC THEN REWRITE_TAC[EXTENSION; IN_INTERS; IN_SING; IN_ELIM_THM] THEN + ASM_MESON_TAC[DIST_POS_LT; REAL_LT_REFL; SUBSET; LE_CASES]);; + +(* ------------------------------------------------------------------------- *) +(* A version for a more general chain, not indexed by N. *) +(* ------------------------------------------------------------------------- *) + +let BOUNDED_CLOSED_CHAIN = prove + (`!f b:real^N->bool. + (!s. s IN f ==> closed s /\ ~(s = {})) /\ + (!s t. s IN f /\ t IN f ==> s SUBSET t \/ t SUBSET s) /\ + b IN f /\ bounded b + ==> ~(INTERS f = {})`, + REPEAT GEN_TAC THEN STRIP_TAC THEN + SUBGOAL_THEN `~(b INTER (INTERS f):real^N->bool = {})` MP_TAC THENL + [ALL_TAC; SET_TAC[]] THEN + MATCH_MP_TAC COMPACT_IMP_FIP THEN + ASM_SIMP_TAC[COMPACT_EQ_BOUNDED_CLOSED] THEN + X_GEN_TAC `u:(real^N->bool)->bool` THEN STRIP_TAC THEN + SUBGOAL_THEN `?s:real^N->bool. s IN f /\ !t. t IN u ==> s SUBSET t` + MP_TAC THENL [ALL_TAC; ASM SET_TAC[]] THEN + UNDISCH_TAC `(u:(real^N->bool)->bool) SUBSET f` THEN + UNDISCH_TAC `FINITE(u:(real^N->bool)->bool)` THEN + SPEC_TAC(`u:(real^N->bool)->bool`,`u:(real^N->bool)->bool`) THEN + MATCH_MP_TAC FINITE_INDUCT_STRONG THEN + CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + MAP_EVERY X_GEN_TAC [`t:real^N->bool`; `u:(real^N->bool)->bool`] THEN + REWRITE_TAC[INSERT_SUBSET] THEN + DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN + ASM_REWRITE_TAC[] THEN + DISCH_THEN(CONJUNCTS_THEN2 MP_TAC STRIP_ASSUME_TAC) THEN + DISCH_THEN(X_CHOOSE_THEN `s:real^N->bool` STRIP_ASSUME_TAC) THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`s:real^N->bool`; `t:real^N->bool`]) THEN + ASM SET_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* Analogous things directly for compactness. *) +(* ------------------------------------------------------------------------- *) + +let COMPACT_CHAIN = prove + (`!f:(real^N->bool)->bool. + (!s. s IN f ==> compact s /\ ~(s = {})) /\ + (!s t. s IN f /\ t IN f ==> s SUBSET t \/ t SUBSET s) + ==> ~(INTERS f = {})`, + GEN_TAC THEN REWRITE_TAC[COMPACT_EQ_BOUNDED_CLOSED] THEN STRIP_TAC THEN + ASM_CASES_TAC `f:(real^N->bool)->bool = {}` THENL + [ASM_REWRITE_TAC[INTERS_0] THEN SET_TAC[]; + MATCH_MP_TAC BOUNDED_CLOSED_CHAIN THEN ASM SET_TAC[]]);; + +let COMPACT_NEST = prove + (`!s. (!n. compact(s n) /\ ~(s n = {})) /\ + (!m n. m <= n ==> s n SUBSET s m) + ==> ~(INTERS {s n | n IN (:num)} = {})`, + GEN_TAC THEN STRIP_TAC THEN MATCH_MP_TAC COMPACT_CHAIN THEN + ASM_SIMP_TAC[FORALL_IN_GSPEC; IN_UNIV; IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN + MATCH_MP_TAC WLOG_LE THEN ASM_MESON_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* Cauchy-type criteria for *uniform* convergence. *) +(* ------------------------------------------------------------------------- *) + +let UNIFORMLY_CONVERGENT_EQ_CAUCHY = prove + (`!P s:num->A->real^N. + (?l. !e. &0 < e + ==> ?N. !n x. N <= n /\ P x ==> dist(s n x,l x) < e) <=> + (!e. &0 < e + ==> ?N. !m n x. N <= m /\ N <= n /\ P x + ==> dist(s m x,s n x) < e)`, + REPEAT GEN_TAC THEN EQ_TAC THENL + [DISCH_THEN(X_CHOOSE_TAC `l:A->real^N`) 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 MESON_TAC[DIST_TRIANGLE_HALF_L]; + ALL_TAC] THEN + DISCH_TAC THEN + SUBGOAL_THEN `!x:A. P x ==> cauchy (\n. s n x :real^N)` MP_TAC THENL + [REWRITE_TAC[cauchy; GE] THEN ASM_MESON_TAC[]; ALL_TAC] THEN + REWRITE_TAC[GSYM CONVERGENT_EQ_CAUCHY; LIM_SEQUENTIALLY] THEN + GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [RIGHT_IMP_EXISTS_THM] THEN + REWRITE_TAC[SKOLEM_THM] THEN MATCH_MP_TAC MONO_EXISTS THEN + X_GEN_TAC `l:A->real^N` 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 `N:num` THEN STRIP_TAC THEN + MAP_EVERY X_GEN_TAC [`n:num`; `x:A`] THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `x:A`) THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(MP_TAC o SPEC `e / &2`) THEN ASM_REWRITE_TAC[REAL_HALF] THEN + DISCH_THEN(X_CHOOSE_TAC `M:num`) THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`n:num`; `N + M:num`; `x:A`]) THEN + ASM_REWRITE_TAC[LE_ADD] THEN ONCE_REWRITE_TAC[ADD_SYM] THEN + FIRST_X_ASSUM(MP_TAC o SPEC `M + N:num`) THEN REWRITE_TAC[LE_ADD] THEN + ASM_MESON_TAC[DIST_TRIANGLE_HALF_L; DIST_SYM]);; + +let UNIFORMLY_CAUCHY_IMP_UNIFORMLY_CONVERGENT = prove + (`!P (s:num->A->real^N) l. + (!e. &0 < e + ==> ?N. !m n x. N <= m /\ N <= n /\ P x ==> dist(s m x,s n x) < e) /\ + (!x. P x ==> !e. &0 < e ==> ?N. !n. N <= n ==> dist(s n x,l x) < e) + ==> (!e. &0 < e ==> ?N. !n x. N <= n /\ P x ==> dist(s n x,l x) < e)`, + REPEAT GEN_TAC THEN REWRITE_TAC[GSYM UNIFORMLY_CONVERGENT_EQ_CAUCHY] THEN + DISCH_THEN(CONJUNCTS_THEN2 (X_CHOOSE_TAC `l':A->real^N`) ASSUME_TAC) THEN + SUBGOAL_THEN `!x. P x ==> (l:A->real^N) x = l' x` MP_TAC THENL + [ALL_TAC; ASM_MESON_TAC[]] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC(ISPEC `sequentially` LIM_UNIQUE) THEN + EXISTS_TAC `\n. (s:num->A->real^N) n x` THEN + REWRITE_TAC[LIM_SEQUENTIALLY; TRIVIAL_LIMIT_SEQUENTIALLY] THEN + ASM_MESON_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* Define continuity over a net to take in restrictions of the set. *) +(* ------------------------------------------------------------------------- *) + +parse_as_infix ("continuous",(12,"right"));; + +let continuous = new_definition + `f continuous net <=> (f --> f(netlimit net)) net`;; + +let CONTINUOUS_TRIVIAL_LIMIT = prove + (`!f net. trivial_limit net ==> f continuous net`, + SIMP_TAC[continuous; LIM]);; + +let CONTINUOUS_WITHIN = prove + (`!f x:real^M. f continuous (at x within s) <=> (f --> f(x)) (at x within s)`, + REPEAT GEN_TAC THEN REWRITE_TAC[continuous] THEN + ASM_CASES_TAC `trivial_limit(at (x:real^M) within s)` THENL + [ASM_REWRITE_TAC[LIM]; ASM_SIMP_TAC[NETLIMIT_WITHIN]]);; + +let CONTINUOUS_AT = prove + (`!f (x:real^N). f continuous (at x) <=> (f --> f(x)) (at x)`, + ONCE_REWRITE_TAC[GSYM WITHIN_UNIV] THEN + REWRITE_TAC[CONTINUOUS_WITHIN; IN_UNIV]);; + +let CONTINUOUS_AT_WITHIN = prove + (`!f:real^M->real^N x s. + f continuous (at x) ==> f continuous (at x within s)`, + SIMP_TAC[LIM_AT_WITHIN; CONTINUOUS_AT; CONTINUOUS_WITHIN]);; + +let CONTINUOUS_WITHIN_CLOSED_NONTRIVIAL = prove + (`!a s. closed s /\ ~(a IN s) ==> f continuous (at a within s)`, + ASM_SIMP_TAC[continuous; LIM; LIM_WITHIN_CLOSED_TRIVIAL]);; + +let CONTINUOUS_TRANSFORM_WITHIN = prove + (`!f g:real^M->real^N s x d. + &0 < d /\ x IN s /\ + (!x'. x' IN s /\ dist(x',x) < d ==> f(x') = g(x')) /\ + f continuous (at x within s) + ==> g continuous (at x within s)`, + REWRITE_TAC[CONTINUOUS_WITHIN] THEN + MESON_TAC[LIM_TRANSFORM_WITHIN; DIST_REFL]);; + +let CONTINUOUS_TRANSFORM_AT = prove + (`!f g:real^M->real^N x d. + &0 < d /\ (!x'. dist(x',x) < d ==> f(x') = g(x')) /\ + f continuous (at x) + ==> g continuous (at x)`, + REWRITE_TAC[CONTINUOUS_AT] THEN + MESON_TAC[LIM_TRANSFORM_AT; DIST_REFL]);; + +(* ------------------------------------------------------------------------- *) +(* Derive the epsilon-delta forms, which we often use as "definitions" *) +(* ------------------------------------------------------------------------- *) + +let continuous_within = prove + (`f continuous (at x within s) <=> + !e. &0 < e + ==> ?d. &0 < d /\ + !x'. x' IN s /\ dist(x',x) < d ==> dist(f(x'),f(x)) < e`, + REWRITE_TAC[CONTINUOUS_WITHIN; LIM_WITHIN] THEN + REWRITE_TAC[GSYM DIST_NZ] THEN MESON_TAC[DIST_REFL]);; + +let continuous_at = prove + (`f continuous (at x) <=> + !e. &0 < e ==> ?d. &0 < d /\ + !x'. dist(x',x) < d ==> dist(f(x'),f(x)) < e`, + ONCE_REWRITE_TAC[GSYM WITHIN_UNIV] THEN + REWRITE_TAC[continuous_within; IN_UNIV]);; + +(* ------------------------------------------------------------------------- *) +(* Versions in terms of open balls. *) +(* ------------------------------------------------------------------------- *) + +let CONTINUOUS_WITHIN_BALL = prove + (`!f s x. f continuous (at x within s) <=> + !e. &0 < e + ==> ?d. &0 < d /\ + IMAGE f (ball(x,d) INTER s) SUBSET ball(f x,e)`, + SIMP_TAC[SUBSET; FORALL_IN_IMAGE; IN_BALL; continuous_within; IN_INTER] THEN + MESON_TAC[DIST_SYM]);; + +let CONTINUOUS_AT_BALL = prove + (`!f x. f continuous (at x) <=> + !e. &0 < e + ==> ?d. &0 < d /\ + IMAGE f (ball(x,d)) SUBSET ball(f x,e)`, + SIMP_TAC[SUBSET; FORALL_IN_IMAGE; IN_BALL; continuous_at] THEN + MESON_TAC[DIST_SYM]);; + +(* ------------------------------------------------------------------------- *) +(* For setwise continuity, just start from the epsilon-delta definitions. *) +(* ------------------------------------------------------------------------- *) + +parse_as_infix ("continuous_on",(12,"right"));; +parse_as_infix ("uniformly_continuous_on",(12,"right"));; + +let continuous_on = new_definition + `f continuous_on s <=> + !x. x IN s ==> !e. &0 < e + ==> ?d. &0 < d /\ + !x'. x' IN s /\ dist(x',x) < d + ==> dist(f(x'),f(x)) < e`;; + +let uniformly_continuous_on = new_definition + `f uniformly_continuous_on s <=> + !e. &0 < e + ==> ?d. &0 < d /\ + !x x'. x IN s /\ x' IN s /\ dist(x',x) < d + ==> dist(f(x'),f(x)) < e`;; + +(* ------------------------------------------------------------------------- *) +(* Some simple consequential lemmas. *) +(* ------------------------------------------------------------------------- *) + +let UNIFORMLY_CONTINUOUS_IMP_CONTINUOUS = prove + (`!f s. f uniformly_continuous_on s ==> f continuous_on s`, + REWRITE_TAC[uniformly_continuous_on; continuous_on] THEN MESON_TAC[]);; + +let CONTINUOUS_AT_IMP_CONTINUOUS_ON = prove + (`!f s. (!x. x IN s ==> f continuous (at x)) ==> f continuous_on s`, + REWRITE_TAC[continuous_at; continuous_on] THEN MESON_TAC[]);; + +let CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN = prove + (`!f s. f continuous_on s <=> !x. x IN s ==> f continuous (at x within s)`, + REWRITE_TAC[continuous_on; continuous_within]);; + +let CONTINUOUS_ON = prove + (`!f (s:real^N->bool). + f continuous_on s <=> !x. x IN s ==> (f --> f(x)) (at x within s)`, + REWRITE_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN; CONTINUOUS_WITHIN]);; + +let CONTINUOUS_ON_EQ_CONTINUOUS_AT = prove + (`!f:real^M->real^N s. + open s ==> (f continuous_on s <=> (!x. x IN s ==> f continuous (at x)))`, + SIMP_TAC[CONTINUOUS_ON; CONTINUOUS_AT; LIM_WITHIN_OPEN]);; + +let CONTINUOUS_WITHIN_SUBSET = prove + (`!f s t x. f continuous (at x within s) /\ t SUBSET s + ==> f continuous (at x within t)`, + REWRITE_TAC[CONTINUOUS_WITHIN] THEN MESON_TAC[LIM_WITHIN_SUBSET]);; + +let CONTINUOUS_ON_SUBSET = prove + (`!f s t. f continuous_on s /\ t SUBSET s ==> f continuous_on t`, + REWRITE_TAC[CONTINUOUS_ON] THEN MESON_TAC[SUBSET; LIM_WITHIN_SUBSET]);; + +let UNIFORMLY_CONTINUOUS_ON_SUBSET = prove + (`!f s t. f uniformly_continuous_on s /\ t SUBSET s + ==> f uniformly_continuous_on t`, + REWRITE_TAC[uniformly_continuous_on] THEN + MESON_TAC[SUBSET; LIM_WITHIN_SUBSET]);; + +let CONTINUOUS_ON_INTERIOR = prove + (`!f:real^M->real^N s x. + f continuous_on s /\ x IN interior(s) ==> f continuous at x`, + REWRITE_TAC[interior; IN_ELIM_THM] THEN + MESON_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_AT; CONTINUOUS_ON_SUBSET]);; + +let CONTINUOUS_ON_EQ = prove + (`!f g s. (!x. x IN s ==> f(x) = g(x)) /\ f continuous_on s + ==> g continuous_on s`, + SIMP_TAC[continuous_on; IMP_CONJ]);; + +let UNIFORMLY_CONTINUOUS_ON_EQ = prove + (`!f g s. + (!x. x IN s ==> f x = g x) /\ f uniformly_continuous_on s + ==> g uniformly_continuous_on s`, + SIMP_TAC[uniformly_continuous_on; IMP_CONJ]);; + +let CONTINUOUS_ON_SING = prove + (`!f:real^M->real^N a. f continuous_on {a}`, + SIMP_TAC[continuous_on; IN_SING; FORALL_UNWIND_THM2; DIST_REFL] THEN + MESON_TAC[]);; + +let CONTINUOUS_ON_EMPTY = prove + (`!f:real^M->real^N. f continuous_on {}`, + MESON_TAC[CONTINUOUS_ON_SING; EMPTY_SUBSET; CONTINUOUS_ON_SUBSET]);; + +let CONTINUOUS_ON_NO_LIMPT = prove + (`!f:real^M->real^N s. + ~(?x. x limit_point_of s) ==> f continuous_on s`, + REWRITE_TAC[continuous_on; LIMPT_APPROACHABLE] THEN MESON_TAC[DIST_REFL]);; + +let CONTINUOUS_ON_FINITE = prove + (`!f:real^M->real^N s. FINITE s ==> f continuous_on s`, + MESON_TAC[CONTINUOUS_ON_NO_LIMPT; LIMIT_POINT_FINITE]);; + +let CONTRACTION_IMP_CONTINUOUS_ON = prove + (`!f:real^M->real^N. + (!x y. x IN s /\ y IN s ==> dist(f x,f y) <= dist(x,y)) + ==> f continuous_on s`, + SIMP_TAC[continuous_on] THEN MESON_TAC[REAL_LET_TRANS]);; + +let ISOMETRY_ON_IMP_CONTINUOUS_ON = prove + (`!f:real^M->real^N. + (!x y. x IN s /\ y IN s ==> dist(f x,f y) = dist(x,y)) + ==> f continuous_on s`, + SIMP_TAC[CONTRACTION_IMP_CONTINUOUS_ON; REAL_LE_REFL]);; + +(* ------------------------------------------------------------------------- *) +(* Characterization of various kinds of continuity in terms of sequences. *) +(* ------------------------------------------------------------------------- *) + +let CONTINUOUS_WITHIN_SEQUENTIALLY = prove + (`!f a:real^N. + f continuous (at a within s) <=> + !x. (!n. x(n) IN s) /\ (x --> a) sequentially + ==> ((f o x) --> f(a)) sequentially`, + REPEAT GEN_TAC THEN REWRITE_TAC[continuous_within] THEN EQ_TAC THENL + [REWRITE_TAC[LIM_SEQUENTIALLY; o_THM] THEN MESON_TAC[]; ALL_TAC] THEN + ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN + REWRITE_TAC[NOT_FORALL_THM; NOT_IMP; NOT_EXISTS_THM] THEN + DISCH_THEN(X_CHOOSE_THEN `e:real` (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + DISCH_THEN(MP_TAC o GEN `n:num` o SPEC `&1 / (&n + &1)`) THEN + SIMP_TAC[REAL_LT_DIV; REAL_OF_NUM_LT; REAL_OF_NUM_LE; REAL_POS; ARITH; + REAL_ARITH `&0 <= n ==> &0 < n + &1`; NOT_FORALL_THM; SKOLEM_THM] THEN + MATCH_MP_TAC MONO_EXISTS THEN REWRITE_TAC[NOT_IMP; FORALL_AND_THM] THEN + X_GEN_TAC `y:num->real^N` THEN REWRITE_TAC[LIM_SEQUENTIALLY; o_THM] THEN + STRIP_TAC THEN CONJ_TAC THENL [ALL_TAC; ASM_MESON_TAC[LE_REFL]] THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC FORALL_POS_MONO_1 THEN + CONJ_TAC THENL [ASM_MESON_TAC[REAL_LT_TRANS]; ALL_TAC] THEN + X_GEN_TAC `n:num` THEN EXISTS_TAC `n:num` THEN X_GEN_TAC `m:num` THEN + DISCH_TAC THEN MATCH_MP_TAC REAL_LTE_TRANS THEN + EXISTS_TAC `&1 / (&m + &1)` THEN ASM_REWRITE_TAC[] THEN + ASM_SIMP_TAC[REAL_LE_INV2; real_div; REAL_ARITH `&0 <= x ==> &0 < x + &1`; + REAL_POS; REAL_MUL_LID; REAL_LE_RADD; REAL_OF_NUM_LE]);; + +let CONTINUOUS_AT_SEQUENTIALLY = prove + (`!f a:real^N. + f continuous (at a) <=> + !x. (x --> a) sequentially + ==> ((f o x) --> f(a)) sequentially`, + ONCE_REWRITE_TAC[GSYM WITHIN_UNIV] THEN + REWRITE_TAC[CONTINUOUS_WITHIN_SEQUENTIALLY; IN_UNIV]);; + +let CONTINUOUS_ON_SEQUENTIALLY = prove + (`!f s:real^N->bool. + f continuous_on s <=> + !x a. a IN s /\ (!n. x(n) IN s) /\ (x --> a) sequentially + ==> ((f o x) --> f(a)) sequentially`, + REWRITE_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN; + CONTINUOUS_WITHIN_SEQUENTIALLY] THEN MESON_TAC[]);; + +let UNIFORMLY_CONTINUOUS_ON_SEQUENTIALLY = prove + (`!f s:real^N->bool. + f uniformly_continuous_on s <=> + !x y. (!n. x(n) IN s) /\ (!n. y(n) IN s) /\ + ((\n. x(n) - y(n)) --> vec 0) sequentially + ==> ((\n. f(x(n)) - f(y(n))) --> vec 0) sequentially`, + REPEAT GEN_TAC THEN REWRITE_TAC[uniformly_continuous_on] THEN + REWRITE_TAC[LIM_SEQUENTIALLY; dist; VECTOR_SUB_RZERO] THEN + EQ_TAC THENL [MESON_TAC[]; ALL_TAC] THEN + ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN + REWRITE_TAC[NOT_FORALL_THM; NOT_IMP; NOT_EXISTS_THM] THEN + DISCH_THEN(X_CHOOSE_THEN `e:real` (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + DISCH_THEN(MP_TAC o GEN `n:num` o SPEC `&1 / (&n + &1)`) THEN + SIMP_TAC[REAL_LT_DIV; REAL_OF_NUM_LT; REAL_OF_NUM_LE; REAL_POS; ARITH; + REAL_ARITH `&0 <= n ==> &0 < n + &1`; NOT_FORALL_THM; SKOLEM_THM] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `x:num->real^N` THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `y:num->real^N` THEN + REWRITE_TAC[NOT_IMP; FORALL_AND_THM] THEN STRIP_TAC THEN + ASM_REWRITE_TAC[] THEN ONCE_REWRITE_TAC[NORM_SUB] THEN CONJ_TAC THENL + [MATCH_MP_TAC FORALL_POS_MONO_1 THEN + CONJ_TAC THENL [ASM_MESON_TAC[REAL_LT_TRANS]; ALL_TAC] THEN + X_GEN_TAC `n:num` THEN EXISTS_TAC `n:num` THEN X_GEN_TAC `m:num` THEN + DISCH_TAC THEN MATCH_MP_TAC REAL_LTE_TRANS THEN + EXISTS_TAC `&1 / (&m + &1)` THEN ASM_REWRITE_TAC[] THEN + ASM_SIMP_TAC[REAL_LE_INV2; real_div; REAL_ARITH `&0 <= x ==> &0 < x + &1`; + REAL_POS; REAL_MUL_LID; REAL_LE_RADD; REAL_OF_NUM_LE]; + EXISTS_TAC `e:real` THEN ASM_REWRITE_TAC[] THEN + EXISTS_TAC `\x:num. x` THEN ASM_REWRITE_TAC[LE_REFL]]);; + +let LIM_CONTINUOUS_FUNCTION = prove + (`!f net g l. + f continuous (at l) /\ (g --> l) net ==> ((\x. f(g x)) --> f l) net`, + REWRITE_TAC[tendsto; continuous_at; eventually] THEN MESON_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* Combination results for pointwise continuity. *) +(* ------------------------------------------------------------------------- *) + +let CONTINUOUS_CONST = prove + (`!net c. (\x. c) continuous net`, + REWRITE_TAC[continuous; LIM_CONST]);; + +let CONTINUOUS_CMUL = prove + (`!f c net. f continuous net ==> (\x. c % f(x)) continuous net`, + REWRITE_TAC[continuous; LIM_CMUL]);; + +let CONTINUOUS_NEG = prove + (`!f net. f continuous net ==> (\x. --(f x)) continuous net`, + REWRITE_TAC[continuous; LIM_NEG]);; + +let CONTINUOUS_ADD = prove + (`!f g net. f continuous net /\ g continuous net + ==> (\x. f(x) + g(x)) continuous net`, + REWRITE_TAC[continuous; LIM_ADD]);; + +let CONTINUOUS_SUB = prove + (`!f g net. f continuous net /\ g continuous net + ==> (\x. f(x) - g(x)) continuous net`, + REWRITE_TAC[continuous; LIM_SUB]);; + +let CONTINUOUS_ABS = prove + (`!(f:A->real^N) net. + f continuous net + ==> (\x. (lambda i. abs(f(x)$i)):real^N) continuous net`, + REWRITE_TAC[continuous; LIM_ABS]);; + +let CONTINUOUS_MAX = prove + (`!(f:A->real^N) (g:A->real^N) net. + f continuous net /\ g continuous net + ==> (\x. (lambda i. max (f(x)$i) (g(x)$i)):real^N) continuous net`, + REWRITE_TAC[continuous; LIM_MAX]);; + +let CONTINUOUS_MIN = prove + (`!(f:A->real^N) (g:A->real^N) net. + f continuous net /\ g continuous net + ==> (\x. (lambda i. min (f(x)$i) (g(x)$i)):real^N) continuous net`, + REWRITE_TAC[continuous; LIM_MIN]);; + +let CONTINUOUS_VSUM = prove + (`!net f s. FINITE s /\ (!a. a IN s ==> (f a) continuous net) + ==> (\x. vsum s (\a. f a x)) continuous net`, + GEN_TAC THEN GEN_TAC THEN REWRITE_TAC[IMP_CONJ] THEN + MATCH_MP_TAC FINITE_INDUCT_STRONG THEN + SIMP_TAC[FORALL_IN_INSERT; NOT_IN_EMPTY; VSUM_CLAUSES; + CONTINUOUS_CONST; CONTINUOUS_ADD; ETA_AX]);; + +(* ------------------------------------------------------------------------- *) +(* Same thing for setwise continuity. *) +(* ------------------------------------------------------------------------- *) + +let CONTINUOUS_ON_CONST = prove + (`!s c. (\x. c) continuous_on s`, + SIMP_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN; CONTINUOUS_CONST]);; + +let CONTINUOUS_ON_CMUL = prove + (`!f c s. f continuous_on s ==> (\x. c % f(x)) continuous_on s`, + SIMP_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN; CONTINUOUS_CMUL]);; + +let CONTINUOUS_ON_NEG = prove + (`!f s. f continuous_on s + ==> (\x. --(f x)) continuous_on s`, + SIMP_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN; CONTINUOUS_NEG]);; + +let CONTINUOUS_ON_ADD = prove + (`!f g s. f continuous_on s /\ g continuous_on s + ==> (\x. f(x) + g(x)) continuous_on s`, + SIMP_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN; CONTINUOUS_ADD]);; + +let CONTINUOUS_ON_SUB = prove + (`!f g s. f continuous_on s /\ g continuous_on s + ==> (\x. f(x) - g(x)) continuous_on s`, + SIMP_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN; CONTINUOUS_SUB]);; + +let CONTINUOUS_ON_ABS = prove + (`!f:real^M->real^N s. + f continuous_on s + ==> (\x. (lambda i. abs(f(x)$i)):real^N) continuous_on s`, + SIMP_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN; CONTINUOUS_ABS]);; + +let CONTINUOUS_ON_MAX = prove + (`!f:real^M->real^N g:real^M->real^N s. + f continuous_on s /\ g continuous_on s + ==> (\x. (lambda i. max (f(x)$i) (g(x)$i)):real^N) + continuous_on s`, + SIMP_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN; CONTINUOUS_MAX]);; + +let CONTINUOUS_ON_MIN = prove + (`!f:real^M->real^N g:real^M->real^N s. + f continuous_on s /\ g continuous_on s + ==> (\x. (lambda i. min (f(x)$i) (g(x)$i)):real^N) + continuous_on s`, + SIMP_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN; CONTINUOUS_MIN]);; + +let CONTINUOUS_ON_VSUM = prove + (`!t f s. FINITE s /\ (!a. a IN s ==> (f a) continuous_on t) + ==> (\x. vsum s (\a. f a x)) continuous_on t`, + SIMP_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN; CONTINUOUS_VSUM]);; + +(* ------------------------------------------------------------------------- *) +(* Same thing for uniform continuity, using sequential formulations. *) +(* ------------------------------------------------------------------------- *) + +let UNIFORMLY_CONTINUOUS_ON_CONST = prove + (`!s c. (\x. c) uniformly_continuous_on s`, + REWRITE_TAC[UNIFORMLY_CONTINUOUS_ON_SEQUENTIALLY; o_DEF; + VECTOR_SUB_REFL; LIM_CONST]);; + +let LINEAR_UNIFORMLY_CONTINUOUS_ON = prove + (`!f:real^M->real^N s. linear f ==> f uniformly_continuous_on s`, + REPEAT STRIP_TAC THEN + ASM_SIMP_TAC[uniformly_continuous_on; dist; GSYM LINEAR_SUB] 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 EXISTS_TAC `e / B:real` THEN + ASM_SIMP_TAC[REAL_LT_DIV] THEN + MAP_EVERY X_GEN_TAC [`x:real^M`; `y:real^M`] THEN STRIP_TAC THEN + MATCH_MP_TAC REAL_LET_TRANS THEN + EXISTS_TAC `B * norm(y - x:real^M)` THEN ASM_REWRITE_TAC[] THEN + ASM_MESON_TAC[REAL_LT_RDIV_EQ; REAL_MUL_SYM]);; + +let UNIFORMLY_CONTINUOUS_ON_COMPOSE = prove + (`!f g s. f uniformly_continuous_on s /\ + g uniformly_continuous_on (IMAGE f s) + ==> (g o f) uniformly_continuous_on s`, + let lemma = prove + (`(!y. ((?x. (y = f x) /\ P x) /\ Q y ==> R y)) <=> + (!x. P x /\ Q (f x) ==> R (f x))`, + MESON_TAC[]) in + REPEAT GEN_TAC THEN + REWRITE_TAC[uniformly_continuous_on; o_THM; IN_IMAGE] THEN + ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN REWRITE_TAC[lemma] THEN + ONCE_REWRITE_TAC[TAUT `a /\ b /\ c <=> b /\ a /\ c`] THEN + ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN REWRITE_TAC[lemma] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + MATCH_MP_TAC MONO_FORALL THEN + X_GEN_TAC `e:real` THEN ASM_CASES_TAC `&0 < e` THEN ASM_REWRITE_TAC[] THEN + ASM_MESON_TAC[]);; + +let BILINEAR_UNIFORMLY_CONTINUOUS_ON_COMPOSE = prove + (`!f:real^M->real^N g (h:real^N->real^P->real^Q) s. + f uniformly_continuous_on s /\ g uniformly_continuous_on s /\ + bilinear h /\ bounded(IMAGE f s) /\ bounded(IMAGE g s) + ==> (\x. h (f x) (g x)) uniformly_continuous_on s`, + REPEAT STRIP_TAC THEN REWRITE_TAC[uniformly_continuous_on; dist] THEN + X_GEN_TAC `e:real` THEN DISCH_TAC THEN + SUBGOAL_THEN + `!a b c d. (h:real^N->real^P->real^Q) a b - h c d = + h (a - c) b + h c (b - d)` + (fun th -> ONCE_REWRITE_TAC[th]) + THENL + [FIRST_ASSUM(fun th -> REWRITE_TAC[MATCH_MP BILINEAR_LSUB th]) THEN + FIRST_ASSUM(fun th -> REWRITE_TAC[MATCH_MP BILINEAR_RSUB th]) THEN + VECTOR_ARITH_TAC; + ALL_TAC] THEN + FIRST_X_ASSUM(X_CHOOSE_THEN `B:real` STRIP_ASSUME_TAC o + MATCH_MP BILINEAR_BOUNDED_POS) THEN + UNDISCH_TAC `bounded(IMAGE (g:real^M->real^P) s)` THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [BOUNDED_POS]) THEN + REWRITE_TAC[BOUNDED_POS; FORALL_IN_IMAGE] THEN + DISCH_THEN(X_CHOOSE_THEN `B1:real` STRIP_ASSUME_TAC) THEN + DISCH_THEN(X_CHOOSE_THEN `B2:real` STRIP_ASSUME_TAC) THEN + UNDISCH_TAC `(g:real^M->real^P) uniformly_continuous_on s` THEN + UNDISCH_TAC `(f:real^M->real^N) uniformly_continuous_on s` THEN + REWRITE_TAC[uniformly_continuous_on] THEN + DISCH_THEN(MP_TAC o SPEC `e / &2 / &2 / B / B2`) THEN + ASM_SIMP_TAC[REAL_LT_DIV; REAL_HALF; dist] THEN + DISCH_THEN(X_CHOOSE_THEN `d1:real` STRIP_ASSUME_TAC) THEN + DISCH_THEN(MP_TAC o SPEC `e / &2 / &2 / B / B1`) THEN + ASM_SIMP_TAC[REAL_LT_DIV; REAL_HALF; dist] THEN + DISCH_THEN(X_CHOOSE_THEN `d2:real` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `min d1 d2` THEN ASM_REWRITE_TAC[REAL_LT_MIN] THEN + MAP_EVERY X_GEN_TAC [`x:real^M`; `y:real^M`] THEN STRIP_TAC THEN + REPEAT(FIRST_X_ASSUM(MP_TAC o SPECL [`x:real^M`; `y:real^M`])) THEN + ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC REAL_LET_TRANS THEN EXISTS_TAC + `B * e / &2 / &2 / B / B2 * B2 + B * B1 * e / &2 / &2 / B / B1` THEN + CONJ_TAC THENL + [MATCH_MP_TAC(NORM_ARITH + `norm(x) <= a /\ norm(y) <= b ==> norm(x + y:real^N) <= a + b`) THEN + CONJ_TAC THEN + FIRST_X_ASSUM(fun th -> W(MP_TAC o PART_MATCH lhand th o lhand o snd)) THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] REAL_LE_TRANS) THEN + MATCH_MP_TAC REAL_LE_LMUL THEN ASM_SIMP_TAC[REAL_LT_IMP_LE] THEN + MATCH_MP_TAC REAL_LE_MUL2 THEN + ASM_SIMP_TAC[REAL_LT_IMP_LE; NORM_POS_LE]; + ASM_SIMP_TAC[REAL_DIV_RMUL; REAL_DIV_LMUL; REAL_LT_IMP_NZ] THEN + ASM_REAL_ARITH_TAC]);; + +let UNIFORMLY_CONTINUOUS_ON_MUL = prove + (`!f g:real^M->real^N s. + (lift o f) uniformly_continuous_on s /\ g uniformly_continuous_on s /\ + bounded(IMAGE (lift o f) s) /\ bounded(IMAGE g s) + ==> (\x. f x % g x) uniformly_continuous_on s`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL + [`lift o (f:real^M->real)`; `g:real^M->real^N`; + `\c (v:real^N). drop c % v`; `s:real^M->bool`] + BILINEAR_UNIFORMLY_CONTINUOUS_ON_COMPOSE) THEN + ASM_REWRITE_TAC[o_THM; LIFT_DROP] THEN DISCH_THEN MATCH_MP_TAC THEN + REWRITE_TAC[bilinear; linear; DROP_ADD; DROP_CMUL] THEN VECTOR_ARITH_TAC);; + +let UNIFORMLY_CONTINUOUS_ON_CMUL = prove + (`!f c s. f uniformly_continuous_on s + ==> (\x. c % f(x)) uniformly_continuous_on s`, + REPEAT GEN_TAC THEN REWRITE_TAC[UNIFORMLY_CONTINUOUS_ON_SEQUENTIALLY] THEN + REPEAT(MATCH_MP_TAC MONO_FORALL THEN GEN_TAC) THEN + DISCH_THEN(fun th -> DISCH_TAC THEN MP_TAC th) THEN + ASM_REWRITE_TAC[] THEN + DISCH_THEN(MP_TAC o MATCH_MP LIM_CMUL) THEN + ASM_SIMP_TAC[VECTOR_SUB_LDISTRIB; VECTOR_MUL_RZERO]);; + +let UNIFORMLY_CONTINUOUS_ON_VMUL = prove + (`!s:real^M->bool c v:real^N. + (lift o c) uniformly_continuous_on s + ==> (\x. c x % v) uniformly_continuous_on s`, + REPEAT GEN_TAC THEN + DISCH_THEN(MP_TAC o ISPEC `\x. (drop x % v:real^N)` o MATCH_MP + (REWRITE_RULE[IMP_CONJ] UNIFORMLY_CONTINUOUS_ON_COMPOSE)) THEN + REWRITE_TAC[o_DEF; LIFT_DROP] THEN DISCH_THEN MATCH_MP_TAC THEN + MATCH_MP_TAC LINEAR_UNIFORMLY_CONTINUOUS_ON THEN + MATCH_MP_TAC LINEAR_VMUL_DROP THEN REWRITE_TAC[LINEAR_ID]);; + +let UNIFORMLY_CONTINUOUS_ON_NEG = prove + (`!f s. f uniformly_continuous_on s + ==> (\x. --(f x)) uniformly_continuous_on s`, + ONCE_REWRITE_TAC[VECTOR_NEG_MINUS1] THEN + REWRITE_TAC[UNIFORMLY_CONTINUOUS_ON_CMUL]);; + +let UNIFORMLY_CONTINUOUS_ON_ADD = prove + (`!f g s. f uniformly_continuous_on s /\ g uniformly_continuous_on s + ==> (\x. f(x) + g(x)) uniformly_continuous_on s`, + REPEAT GEN_TAC THEN REWRITE_TAC[UNIFORMLY_CONTINUOUS_ON_SEQUENTIALLY] THEN + REWRITE_TAC[AND_FORALL_THM] THEN + REPEAT(MATCH_MP_TAC MONO_FORALL THEN GEN_TAC) THEN + DISCH_THEN(fun th -> DISCH_TAC THEN MP_TAC th) THEN + ASM_REWRITE_TAC[o_DEF] THEN DISCH_THEN(MP_TAC o MATCH_MP LIM_ADD) THEN + MATCH_MP_TAC EQ_IMP THEN + REWRITE_TAC[VECTOR_ADD_LID] THEN AP_THM_TAC THEN BINOP_TAC THEN + REWRITE_TAC[FUN_EQ_THM] THEN VECTOR_ARITH_TAC);; + +let UNIFORMLY_CONTINUOUS_ON_SUB = prove + (`!f g s. f uniformly_continuous_on s /\ g uniformly_continuous_on s + ==> (\x. f(x) - g(x)) uniformly_continuous_on s`, + REWRITE_TAC[VECTOR_SUB] THEN + SIMP_TAC[UNIFORMLY_CONTINUOUS_ON_NEG; UNIFORMLY_CONTINUOUS_ON_ADD]);; + +let UNIFORMLY_CONTINUOUS_ON_VSUM = prove + (`!t f s. FINITE s /\ (!a. a IN s ==> (f a) uniformly_continuous_on t) + ==> (\x. vsum s (\a. f a x)) uniformly_continuous_on t`, + GEN_TAC THEN GEN_TAC THEN REWRITE_TAC[IMP_CONJ] THEN + MATCH_MP_TAC FINITE_INDUCT_STRONG THEN + SIMP_TAC[FORALL_IN_INSERT; NOT_IN_EMPTY; VSUM_CLAUSES; + UNIFORMLY_CONTINUOUS_ON_CONST; UNIFORMLY_CONTINUOUS_ON_ADD; ETA_AX]);; + +(* ------------------------------------------------------------------------- *) +(* Identity function is continuous in every sense. *) +(* ------------------------------------------------------------------------- *) + +let CONTINUOUS_WITHIN_ID = prove + (`!a s. (\x. x) continuous (at a within s)`, + REWRITE_TAC[continuous_within] THEN MESON_TAC[]);; + +let CONTINUOUS_AT_ID = prove + (`!a. (\x. x) continuous (at a)`, + REWRITE_TAC[continuous_at] THEN MESON_TAC[]);; + +let CONTINUOUS_ON_ID = prove + (`!s. (\x. x) continuous_on s`, + REWRITE_TAC[continuous_on] THEN MESON_TAC[]);; + +let UNIFORMLY_CONTINUOUS_ON_ID = prove + (`!s. (\x. x) uniformly_continuous_on s`, + REWRITE_TAC[uniformly_continuous_on] THEN MESON_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* Continuity of all kinds is preserved under composition. *) +(* ------------------------------------------------------------------------- *) + +let CONTINUOUS_WITHIN_COMPOSE = prove + (`!f g x s. f continuous (at x within s) /\ + g continuous (at (f x) within IMAGE f s) + ==> (g o f) continuous (at x within s)`, + REPEAT GEN_TAC THEN REWRITE_TAC[continuous_within; o_THM; IN_IMAGE] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `e:real` THEN + ASM_MESON_TAC[]);; + +let CONTINUOUS_AT_COMPOSE = prove + (`!f g x. f continuous (at x) /\ g continuous (at (f x)) + ==> (g o f) continuous (at x)`, + ONCE_REWRITE_TAC[GSYM WITHIN_UNIV] THEN + MESON_TAC[CONTINUOUS_WITHIN_COMPOSE; IN_IMAGE; CONTINUOUS_WITHIN_SUBSET; + SUBSET_UNIV; IN_UNIV]);; + +let CONTINUOUS_ON_COMPOSE = prove + (`!f g s. f continuous_on s /\ g continuous_on (IMAGE f s) + ==> (g o f) continuous_on s`, + REWRITE_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN] THEN + MESON_TAC[IN_IMAGE; CONTINUOUS_WITHIN_COMPOSE]);; + +(* ------------------------------------------------------------------------- *) +(* Continuity in terms of open preimages. *) +(* ------------------------------------------------------------------------- *) + +let CONTINUOUS_WITHIN_OPEN = prove + (`!f:real^M->real^N x u. + f continuous (at x within u) <=> + !t. open t /\ f(x) IN t + ==> ?s. open s /\ x IN s /\ + !x'. x' IN s /\ x' IN u ==> f(x') IN t`, + REPEAT GEN_TAC THEN REWRITE_TAC[continuous_within] THEN EQ_TAC THENL + [DISCH_TAC THEN X_GEN_TAC `t:real^N->bool` THEN + DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN + GEN_REWRITE_TAC LAND_CONV [open_def] THEN + DISCH_THEN(MP_TAC o SPEC `(f:real^M->real^N) x`) THEN + ASM_MESON_TAC[IN_BALL; DIST_SYM; OPEN_BALL; CENTRE_IN_BALL; DIST_SYM]; + DISCH_TAC THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `ball((f:real^M->real^N) x,e)`) THEN + ASM_SIMP_TAC[OPEN_BALL; CENTRE_IN_BALL] THEN + MESON_TAC[open_def; IN_BALL; REAL_LT_TRANS; DIST_SYM]]);; + +let CONTINUOUS_AT_OPEN = prove + (`!f:real^M->real^N x. + f continuous (at x) <=> + !t. open t /\ f(x) IN t + ==> ?s. open s /\ x IN s /\ + !x'. x' IN s ==> f(x') IN t`, + REPEAT GEN_TAC THEN REWRITE_TAC[continuous_at] THEN EQ_TAC THENL + [DISCH_TAC THEN X_GEN_TAC `t:real^N->bool` THEN + DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN + GEN_REWRITE_TAC LAND_CONV [open_def] THEN + DISCH_THEN(MP_TAC o SPEC `(f:real^M->real^N) x`) THEN + ASM_MESON_TAC[IN_BALL; DIST_SYM; OPEN_BALL; CENTRE_IN_BALL]; + DISCH_TAC THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `ball((f:real^M->real^N) x,e)`) THEN + ASM_SIMP_TAC[OPEN_BALL; CENTRE_IN_BALL] THEN + MESON_TAC[open_def; IN_BALL; REAL_LT_TRANS; DIST_SYM]]);; + +let CONTINUOUS_ON_OPEN_GEN = prove + (`!f:real^M->real^N s t. + IMAGE f s SUBSET t + ==> (f continuous_on s <=> + !u. open_in (subtopology euclidean t) u + ==> open_in (subtopology euclidean s) {x | x IN s /\ f x IN u})`, + REPEAT STRIP_TAC THEN REWRITE_TAC[continuous_on] THEN EQ_TAC THENL + [REWRITE_TAC[open_in; SUBSET; IN_ELIM_THM] THEN + DISCH_TAC THEN X_GEN_TAC `u:real^N->bool` THEN STRIP_TAC THEN + CONJ_TAC THENL [ASM_MESON_TAC[DIST_REFL]; ALL_TAC] THEN + X_GEN_TAC `x:real^M` THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `(f:real^M->real^N) x`) THEN ASM SET_TAC[]; + DISCH_TAC THEN X_GEN_TAC `x:real^M` THEN + DISCH_TAC THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o + SPEC `ball((f:real^M->real^N) x,e) INTER t`) THEN + ANTS_TAC THENL + [ASM_MESON_TAC[OPEN_IN_OPEN; INTER_COMM; OPEN_BALL]; ALL_TAC] THEN + REWRITE_TAC[open_in; SUBSET; IN_INTER; IN_ELIM_THM; IN_BALL; IN_IMAGE] THEN + REWRITE_TAC[AND_FORALL_THM] THEN DISCH_THEN(MP_TAC o SPEC `x:real^M`) THEN + RULE_ASSUM_TAC(REWRITE_RULE[SUBSET; FORALL_IN_IMAGE]) THEN + ASM_MESON_TAC[DIST_REFL; DIST_SYM]]);; + +let CONTINUOUS_ON_OPEN = prove + (`!f:real^M->real^N s. + f continuous_on s <=> + !t. open_in (subtopology euclidean (IMAGE f s)) t + ==> open_in (subtopology euclidean s) {x | x IN s /\ f(x) IN t}`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC CONTINUOUS_ON_OPEN_GEN THEN + REWRITE_TAC[SUBSET_REFL]);; + +let CONTINUOUS_OPEN_IN_PREIMAGE_GEN = prove + (`!f:real^M->real^N s t u. + f continuous_on s /\ IMAGE f s SUBSET t /\ + open_in (subtopology euclidean t) u + ==> open_in (subtopology euclidean s) {x | x IN s /\ f x IN u}`, + MESON_TAC[CONTINUOUS_ON_OPEN_GEN]);; + +let CONTINUOUS_ON_IMP_OPEN_IN = prove + (`!f:real^M->real^N s t. + f continuous_on s /\ + open_in (subtopology euclidean (IMAGE f s)) t + ==> open_in (subtopology euclidean s) {x | x IN s /\ f x IN t}`, + MESON_TAC[CONTINUOUS_ON_OPEN]);; + +(* ------------------------------------------------------------------------- *) +(* Similarly in terms of closed sets. *) +(* ------------------------------------------------------------------------- *) + +let CONTINUOUS_ON_CLOSED_GEN = prove + (`!f:real^M->real^N s t. + IMAGE f s SUBSET t + ==> (f continuous_on s <=> + !u. closed_in (subtopology euclidean t) u + ==> closed_in (subtopology euclidean s) + {x | x IN s /\ f x IN u})`, + REPEAT STRIP_TAC THEN FIRST_ASSUM(fun th -> + ONCE_REWRITE_TAC[MATCH_MP CONTINUOUS_ON_OPEN_GEN th]) THEN + EQ_TAC THEN DISCH_TAC THEN X_GEN_TAC `u:real^N->bool` THEN + FIRST_X_ASSUM(MP_TAC o SPEC `t DIFF u:real^N->bool`) THENL + [REWRITE_TAC[closed_in]; REWRITE_TAC[OPEN_IN_CLOSED_IN_EQ]] THEN + REWRITE_TAC[TOPSPACE_EUCLIDEAN_SUBTOPOLOGY] THEN + DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN + ASM_REWRITE_TAC[SUBSET_RESTRICT] THEN + MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN ASM SET_TAC[]);; + +let CONTINUOUS_ON_CLOSED = prove + (`!f:real^M->real^N s. + f continuous_on s <=> + !t. closed_in (subtopology euclidean (IMAGE f s)) t + ==> closed_in (subtopology euclidean s) {x | x IN s /\ f(x) IN t}`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC CONTINUOUS_ON_CLOSED_GEN THEN + REWRITE_TAC[SUBSET_REFL]);; + +let CONTINUOUS_CLOSED_IN_PREIMAGE_GEN = prove + (`!f:real^M->real^N s t u. + f continuous_on s /\ IMAGE f s SUBSET t /\ + closed_in (subtopology euclidean t) u + ==> closed_in (subtopology euclidean s) {x | x IN s /\ f x IN u}`, + MESON_TAC[CONTINUOUS_ON_CLOSED_GEN]);; + +let CONTINUOUS_ON_IMP_CLOSED_IN = prove + (`!f:real^M->real^N s t. + f continuous_on s /\ + closed_in (subtopology euclidean (IMAGE f s)) t + ==> closed_in (subtopology euclidean s) {x | x IN s /\ f x IN t}`, + MESON_TAC[CONTINUOUS_ON_CLOSED]);; + +(* ------------------------------------------------------------------------- *) +(* Half-global and completely global cases. *) +(* ------------------------------------------------------------------------- *) + +let CONTINUOUS_OPEN_IN_PREIMAGE = prove + (`!f s t. + f continuous_on s /\ open t + ==> open_in (subtopology euclidean s) {x | x IN s /\ f x IN t}`, + REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[SET_RULE + `x IN s /\ f x IN t <=> x IN s /\ f x IN (t INTER IMAGE f s)`] THEN + FIRST_ASSUM(MATCH_MP_TAC o REWRITE_RULE[CONTINUOUS_ON_OPEN]) THEN + ONCE_REWRITE_TAC[INTER_COMM] THEN MATCH_MP_TAC OPEN_IN_OPEN_INTER THEN + ASM_REWRITE_TAC[]);; + +let CONTINUOUS_CLOSED_IN_PREIMAGE = prove + (`!f s t. + f continuous_on s /\ closed t + ==> closed_in (subtopology euclidean s) {x | x IN s /\ f x IN t}`, + REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[SET_RULE + `x IN s /\ f x IN t <=> x IN s /\ f x IN (t INTER IMAGE f s)`] THEN + FIRST_ASSUM(MATCH_MP_TAC o REWRITE_RULE[CONTINUOUS_ON_CLOSED]) THEN + ONCE_REWRITE_TAC[INTER_COMM] THEN MATCH_MP_TAC CLOSED_IN_CLOSED_INTER THEN + ASM_REWRITE_TAC[]);; + +let CONTINUOUS_OPEN_PREIMAGE = prove + (`!f:real^M->real^N s t. + f continuous_on s /\ open s /\ open t + ==> open {x | x IN s /\ f(x) IN t}`, + REPEAT STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [CONTINUOUS_ON_OPEN]) THEN + REWRITE_TAC [OPEN_IN_OPEN] THEN + DISCH_THEN(MP_TAC o SPEC `IMAGE (f:real^M->real^N) s INTER t`) THEN + ANTS_TAC THENL + [EXISTS_TAC `t:real^N->bool` THEN ASM_REWRITE_TAC []; + STRIP_TAC THEN + SUBGOAL_THEN `{x | x IN s /\ (f:real^M->real^N) x IN t} = + s INTER t'` SUBST1_TAC THENL + [ASM SET_TAC []; ASM_MESON_TAC [OPEN_INTER]]]);; + +let CONTINUOUS_CLOSED_PREIMAGE = prove + (`!f:real^M->real^N s t. + f continuous_on s /\ closed s /\ closed t + ==> closed {x | x IN s /\ f(x) IN t}`, + REPEAT STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [CONTINUOUS_ON_CLOSED]) THEN + REWRITE_TAC [CLOSED_IN_CLOSED] THEN + DISCH_THEN(MP_TAC o SPEC `IMAGE (f:real^M->real^N) s INTER t`) THEN + ANTS_TAC THENL + [EXISTS_TAC `t:real^N->bool` THEN ASM_REWRITE_TAC []; + STRIP_TAC THEN + SUBGOAL_THEN `{x | x IN s /\ (f:real^M->real^N) x IN t} = + s INTER t'` SUBST1_TAC THENL + [ASM SET_TAC []; ASM_MESON_TAC [CLOSED_INTER]]]);; + +let CONTINUOUS_OPEN_PREIMAGE_UNIV = prove + (`!f:real^M->real^N s. + (!x. f continuous (at x)) /\ open s ==> open {x | f(x) IN s}`, + REPEAT STRIP_TAC THEN + MP_TAC(SPECL [`f:real^M->real^N`; `(:real^M)`; `s:real^N->bool`] + CONTINUOUS_OPEN_PREIMAGE) THEN + ASM_SIMP_TAC[OPEN_UNIV; IN_UNIV; CONTINUOUS_AT_IMP_CONTINUOUS_ON]);; + +let CONTINUOUS_CLOSED_PREIMAGE_UNIV = prove + (`!f:real^M->real^N s. + (!x. f continuous (at x)) /\ closed s ==> closed {x | f(x) IN s}`, + REPEAT STRIP_TAC THEN + MP_TAC(SPECL [`f:real^M->real^N`; `(:real^M)`; `s:real^N->bool`] + CONTINUOUS_CLOSED_PREIMAGE) THEN + ASM_SIMP_TAC[CLOSED_UNIV; IN_UNIV; CONTINUOUS_AT_IMP_CONTINUOUS_ON]);; + +let CONTINUOUS_OPEN_IN_PREIMAGE_EQ = prove + (`!f:real^M->real^N s. + f continuous_on s <=> + !t. open t ==> open_in (subtopology euclidean s) {x | x IN s /\ f x IN t}`, + REPEAT GEN_TAC THEN EQ_TAC THEN SIMP_TAC[CONTINUOUS_OPEN_IN_PREIMAGE] THEN + REWRITE_TAC[CONTINUOUS_ON_OPEN] THEN DISCH_TAC THEN + X_GEN_TAC `t:real^N->bool` THEN GEN_REWRITE_TAC LAND_CONV [OPEN_IN_OPEN] THEN + DISCH_THEN(X_CHOOSE_THEN `u:real^N->bool` STRIP_ASSUME_TAC) THEN + FIRST_X_ASSUM(MP_TAC o SPEC `u:real^N->bool`) THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN SET_TAC[]);; + +let CONTINUOUS_CLOSED_IN_PREIMAGE_EQ = prove + (`!f:real^M->real^N s. + f continuous_on s <=> + !t. closed t + ==> closed_in (subtopology euclidean s) {x | x IN s /\ f x IN t}`, + REPEAT GEN_TAC THEN EQ_TAC THEN SIMP_TAC[CONTINUOUS_CLOSED_IN_PREIMAGE] THEN + REWRITE_TAC[CONTINUOUS_ON_CLOSED] THEN DISCH_TAC THEN + X_GEN_TAC `t:real^N->bool` THEN + GEN_REWRITE_TAC LAND_CONV [CLOSED_IN_CLOSED] THEN + DISCH_THEN(X_CHOOSE_THEN `u:real^N->bool` STRIP_ASSUME_TAC) THEN + FIRST_X_ASSUM(MP_TAC o SPEC `u:real^N->bool`) THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN SET_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* Quotient maps are occasionally useful. *) +(* ------------------------------------------------------------------------- *) + +let OPEN_MAP_IMP_QUOTIENT_MAP = prove + (`!f:real^M->real^N s. + f continuous_on s /\ + (!t. open_in (subtopology euclidean s) t + ==> open_in (subtopology euclidean (IMAGE f s)) (IMAGE f t)) + ==> !t. t SUBSET IMAGE f s + ==> (open_in (subtopology euclidean s) {x | x IN s /\ f x IN t} <=> + open_in (subtopology euclidean (IMAGE f s)) t)`, + REPEAT STRIP_TAC THEN EQ_TAC THEN DISCH_TAC THENL + [SUBGOAL_THEN + `t = IMAGE f {x | x IN s /\ (f:real^M->real^N) x IN t}` + SUBST1_TAC THENL [ASM SET_TAC[]; ASM_SIMP_TAC[]]; + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [CONTINUOUS_ON_OPEN]) THEN + ASM_SIMP_TAC[]]);; + +let CLOSED_MAP_IMP_QUOTIENT_MAP = prove + (`!f:real^M->real^N s. + f continuous_on s /\ + (!t. closed_in (subtopology euclidean s) t + ==> closed_in (subtopology euclidean (IMAGE f s)) (IMAGE f t)) + ==> !t. t SUBSET IMAGE f s + ==> (open_in (subtopology euclidean s) {x | x IN s /\ f x IN t} <=> + open_in (subtopology euclidean (IMAGE f s)) t)`, + REPEAT STRIP_TAC THEN EQ_TAC THEN DISCH_TAC THENL + [FIRST_X_ASSUM(MP_TAC o SPEC + `s DIFF {x | x IN s /\ (f:real^M->real^N) x IN t}`) THEN + ANTS_TAC THENL + [MATCH_MP_TAC CLOSED_IN_DIFF THEN + ASM_SIMP_TAC[CLOSED_IN_SUBTOPOLOGY_REFL; + TOPSPACE_EUCLIDEAN; SUBSET_UNIV]; + REWRITE_TAC[closed_in; TOPSPACE_EUCLIDEAN_SUBTOPOLOGY] THEN + DISCH_THEN(MP_TAC o CONJUNCT2) THEN MATCH_MP_TAC EQ_IMP THEN + AP_TERM_TAC THEN ASM SET_TAC[]]; + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [CONTINUOUS_ON_OPEN]) THEN + ASM_SIMP_TAC[]]);; + +let CONTINUOUS_RIGHT_INVERSE_IMP_QUOTIENT_MAP = prove + (`!f:real^M->real^N g s t. + f continuous_on s /\ IMAGE f s SUBSET t /\ + g continuous_on t /\ IMAGE g t SUBSET s /\ + (!y. y IN t ==> f(g y) = y) + ==> (!u. u SUBSET t + ==> (open_in (subtopology euclidean s) {x | x IN s /\ f x IN u} <=> + open_in (subtopology euclidean t) u))`, + REWRITE_TAC[CONTINUOUS_ON_OPEN] THEN REPEAT STRIP_TAC THEN EQ_TAC THENL + [DISCH_TAC THEN FIRST_ASSUM(MP_TAC o SPEC `(IMAGE (g:real^N->real^M) t) + INTER + {x | x IN s /\ (f:real^M->real^N) x IN u}`) THEN + ANTS_TAC THENL + [FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [OPEN_IN_OPEN]) THEN + REWRITE_TAC[OPEN_IN_OPEN] THEN MATCH_MP_TAC MONO_EXISTS THEN + ASM SET_TAC[]; + MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN ASM SET_TAC[]]; + DISCH_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + SUBGOAL_THEN `IMAGE (f:real^M->real^N) s = t` + (fun th -> ASM_REWRITE_TAC[th]) THEN + ASM SET_TAC[]]);; + +let CONTINUOUS_LEFT_INVERSE_IMP_QUOTIENT_MAP = prove + (`!f:real^M->real^N g s. + f continuous_on s /\ g continuous_on (IMAGE f s) /\ + (!x. x IN s ==> g(f x) = x) + ==> (!u. u SUBSET (IMAGE f s) + ==> (open_in (subtopology euclidean s) {x | x IN s /\ f x IN u} <=> + open_in (subtopology euclidean (IMAGE f s)) u))`, + REPEAT GEN_TAC THEN STRIP_TAC THEN + MATCH_MP_TAC CONTINUOUS_RIGHT_INVERSE_IMP_QUOTIENT_MAP THEN + EXISTS_TAC `g:real^N->real^M` THEN + ASM_REWRITE_TAC[] THEN ASM SET_TAC[]);; + +let QUOTIENT_MAP_OPEN_CLOSED = prove + (`!f:real^M->real^N s t. + IMAGE f s SUBSET t + ==> ((!u. u SUBSET t + ==> (open_in (subtopology euclidean s) + {x | x IN s /\ f x IN u} <=> + open_in (subtopology euclidean t) u)) <=> + (!u. u SUBSET t + ==> (closed_in (subtopology euclidean s) + {x | x IN s /\ f x IN u} <=> + closed_in (subtopology euclidean t) u)))`, + SIMP_TAC[closed_in; TOPSPACE_EUCLIDEAN_SUBTOPOLOGY] THEN + REPEAT STRIP_TAC THEN EQ_TAC THEN DISCH_TAC THEN + X_GEN_TAC `u:real^N->bool` THEN + DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC `t DIFF u:real^N->bool`) THEN + ASM_SIMP_TAC[SET_RULE `u SUBSET t ==> t DIFF (t DIFF u) = u`] THEN + (ANTS_TAC THENL [SET_TAC[]; DISCH_THEN(SUBST1_TAC o SYM)]) THEN + REWRITE_TAC[SUBSET_RESTRICT] THEN AP_TERM_TAC THEN ASM SET_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* More properties of open and closed maps. *) +(* ------------------------------------------------------------------------- *) + +let CLOSED_MAP_IMP_OPEN_MAP = prove + (`!f:real^M->real^N s t. + + IMAGE f s = t /\ + (!u. closed_in (subtopology euclidean s) u + ==> closed_in (subtopology euclidean t) (IMAGE f u)) /\ + (!u. open_in (subtopology euclidean s) u + ==> open_in (subtopology euclidean s) + {x | x IN s /\ f x IN IMAGE f u}) + ==> (!u. open_in (subtopology euclidean s) u + ==> open_in (subtopology euclidean t) (IMAGE f u))`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN + `IMAGE (f:real^M->real^N) u = + t DIFF IMAGE f (s DIFF {x | x IN s /\ f x IN IMAGE f u})` + SUBST1_TAC THENL + [FIRST_ASSUM(MP_TAC o MATCH_MP OPEN_IN_IMP_SUBSET) THEN ASM SET_TAC[]; + MATCH_MP_TAC OPEN_IN_DIFF THEN REWRITE_TAC[OPEN_IN_REFL] THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN + MATCH_MP_TAC CLOSED_IN_DIFF THEN REWRITE_TAC[OPEN_IN_REFL] THEN + ASM_SIMP_TAC[CLOSED_IN_REFL]]);; + +let OPEN_MAP_IMP_CLOSED_MAP = prove + (`!f:real^M->real^N s t. + IMAGE f s = t /\ + (!u. open_in (subtopology euclidean s) u + ==> open_in (subtopology euclidean t) (IMAGE f u)) /\ + (!u. closed_in (subtopology euclidean s) u + ==> closed_in (subtopology euclidean s) + {x | x IN s /\ f x IN IMAGE f u}) + ==> (!u. closed_in (subtopology euclidean s) u + ==> closed_in (subtopology euclidean t) (IMAGE f u))`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN + `IMAGE (f:real^M->real^N) u = + t DIFF IMAGE f (s DIFF {x | x IN s /\ f x IN IMAGE f u})` + SUBST1_TAC THENL + [FIRST_ASSUM(MP_TAC o MATCH_MP CLOSED_IN_IMP_SUBSET) THEN ASM SET_TAC[]; + MATCH_MP_TAC CLOSED_IN_DIFF THEN REWRITE_TAC[CLOSED_IN_REFL] THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN + MATCH_MP_TAC OPEN_IN_DIFF THEN REWRITE_TAC[CLOSED_IN_REFL] THEN + ASM_SIMP_TAC[OPEN_IN_REFL]]);; + +let OPEN_MAP_FROM_COMPOSITION_SURJECTIVE = prove + (`!f:real^M->real^N g:real^N->real^P s t u. + f continuous_on s /\ IMAGE f s = t /\ IMAGE g t SUBSET u /\ + (!k. open_in (subtopology euclidean s) k + ==> open_in (subtopology euclidean u) (IMAGE (g o f) k)) + ==> (!k. open_in (subtopology euclidean t) k + ==> open_in (subtopology euclidean u) (IMAGE g k))`, + REPEAT STRIP_TAC THEN SUBGOAL_THEN + `IMAGE g k = IMAGE ((g:real^N->real^P) o (f:real^M->real^N)) + {x | x IN s /\ f(x) IN k}` + SUBST1_TAC THENL + [FIRST_ASSUM(MP_TAC o MATCH_MP OPEN_IN_IMP_SUBSET) THEN + REWRITE_TAC[IMAGE_o] THEN ASM SET_TAC[]; + FIRST_X_ASSUM MATCH_MP_TAC THEN + MATCH_MP_TAC CONTINUOUS_OPEN_IN_PREIMAGE_GEN THEN + EXISTS_TAC `t:real^N->bool` THEN ASM_REWRITE_TAC[SUBSET_REFL]]);; + +let CLOSED_MAP_FROM_COMPOSITION_SURJECTIVE = prove + (`!f:real^M->real^N g:real^N->real^P s t u. + f continuous_on s /\ IMAGE f s = t /\ IMAGE g t SUBSET u /\ + (!k. closed_in (subtopology euclidean s) k + ==> closed_in (subtopology euclidean u) (IMAGE (g o f) k)) + ==> (!k. closed_in (subtopology euclidean t) k + ==> closed_in (subtopology euclidean u) (IMAGE g k))`, + REPEAT STRIP_TAC THEN SUBGOAL_THEN + `IMAGE g k = IMAGE ((g:real^N->real^P) o (f:real^M->real^N)) + {x | x IN s /\ f(x) IN k}` + SUBST1_TAC THENL + [FIRST_ASSUM(MP_TAC o MATCH_MP CLOSED_IN_IMP_SUBSET) THEN + REWRITE_TAC[IMAGE_o] THEN ASM SET_TAC[]; + FIRST_X_ASSUM MATCH_MP_TAC THEN + MATCH_MP_TAC CONTINUOUS_CLOSED_IN_PREIMAGE_GEN THEN + EXISTS_TAC `t:real^N->bool` THEN ASM_REWRITE_TAC[SUBSET_REFL]]);; + +let OPEN_MAP_FROM_COMPOSITION_INJECTIVE = prove + (`!f:real^M->real^N g:real^N->real^P s t u. + IMAGE f s SUBSET t /\ IMAGE g t SUBSET u /\ + g continuous_on t /\ (!x y. x IN t /\ y IN t /\ g x = g y ==> x = y) /\ + (!k. open_in (subtopology euclidean s) k + ==> open_in (subtopology euclidean u) (IMAGE (g o f) k)) + ==> (!k. open_in (subtopology euclidean s) k + ==> open_in (subtopology euclidean t) (IMAGE f k))`, + REPEAT STRIP_TAC THEN SUBGOAL_THEN + `IMAGE f k = {x | x IN t /\ + g(x) IN IMAGE ((g:real^N->real^P) o (f:real^M->real^N)) k}` + SUBST1_TAC THENL + [FIRST_ASSUM(MP_TAC o MATCH_MP OPEN_IN_IMP_SUBSET) THEN + REWRITE_TAC[IMAGE_o] THEN ASM SET_TAC[]; + MATCH_MP_TAC CONTINUOUS_OPEN_IN_PREIMAGE_GEN THEN + EXISTS_TAC `u:real^P->bool` THEN ASM_SIMP_TAC[]]);; + +let CLOSED_MAP_FROM_COMPOSITION_INJECTIVE = prove + (`!f:real^M->real^N g:real^N->real^P s t u. + IMAGE f s SUBSET t /\ IMAGE g t SUBSET u /\ + g continuous_on t /\ (!x y. x IN t /\ y IN t /\ g x = g y ==> x = y) /\ + (!k. closed_in (subtopology euclidean s) k + ==> closed_in (subtopology euclidean u) (IMAGE (g o f) k)) + ==> (!k. closed_in (subtopology euclidean s) k + ==> closed_in (subtopology euclidean t) (IMAGE f k))`, + REPEAT STRIP_TAC THEN SUBGOAL_THEN + `IMAGE f k = {x | x IN t /\ + g(x) IN IMAGE ((g:real^N->real^P) o (f:real^M->real^N)) k}` + SUBST1_TAC THENL + [FIRST_ASSUM(MP_TAC o MATCH_MP CLOSED_IN_IMP_SUBSET) THEN + REWRITE_TAC[IMAGE_o] THEN ASM SET_TAC[]; + MATCH_MP_TAC CONTINUOUS_CLOSED_IN_PREIMAGE_GEN THEN + EXISTS_TAC `u:real^P->bool` THEN ASM_SIMP_TAC[]]);; + +(* ------------------------------------------------------------------------- *) +(* Two equivalent characterizations of a proper/perfect map. *) +(* ------------------------------------------------------------------------- *) + +let PROPER_MAP = prove + (`!f:real^M->real^N s t. + IMAGE f s SUBSET t + ==> ((!k. k SUBSET t /\ compact k ==> compact {x | x IN s /\ f x IN k}) <=> + (!k. closed_in (subtopology euclidean s) k + ==> closed_in (subtopology euclidean t) (IMAGE f k)) /\ + (!a. a IN t ==> compact {x | x IN s /\ f x = a}))`, + REPEAT STRIP_TAC THEN EQ_TAC THENL + [REPEAT STRIP_TAC THENL + [ALL_TAC; + ONCE_REWRITE_TAC[SET_RULE `x = a <=> x IN {a}`] THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_REWRITE_TAC[SING_SUBSET; COMPACT_SING]] THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP CLOSED_IN_IMP_SUBSET) THEN + REWRITE_TAC[CLOSED_IN_LIMPT] THEN + CONJ_TAC THENL [ASM SET_TAC[]; X_GEN_TAC `y:real^N`] THEN + REWRITE_TAC[LIMPT_SEQUENTIAL_INJ; IN_DELETE] THEN + REWRITE_TAC[IN_IMAGE; LEFT_AND_EXISTS_THM; SKOLEM_THM] THEN + ONCE_REWRITE_TAC[SWAP_EXISTS_THM] THEN + REWRITE_TAC[GSYM CONJ_ASSOC; FORALL_AND_THM] THEN + ONCE_REWRITE_TAC[GSYM FUN_EQ_THM] THEN + REWRITE_TAC[UNWIND_THM2; FUN_EQ_THM] THEN + DISCH_THEN(X_CHOOSE_THEN `x:num->real^M` STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN + `~(INTERS {{a | a IN k /\ + (f:real^M->real^N) a IN + (y INSERT IMAGE (\i. f(x(n + i))) (:num))} | + n IN (:num)} = {})` + MP_TAC THENL + [MATCH_MP_TAC COMPACT_FIP THEN CONJ_TAC THENL + [REWRITE_TAC[FORALL_IN_GSPEC; IN_UNIV] THEN X_GEN_TAC `n:num` THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [CLOSED_IN_CLOSED]) THEN + DISCH_THEN(X_CHOOSE_THEN `c:real^M->bool` STRIP_ASSUME_TAC) THEN + ASM_REWRITE_TAC[SET_RULE + `{x | x IN s INTER k /\ P x} = k INTER {x | x IN s /\ P x}`] THEN + MATCH_MP_TAC CLOSED_INTER_COMPACT THEN ASM_REWRITE_TAC[] THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN + CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + MATCH_MP_TAC COMPACT_SEQUENCE_WITH_LIMIT THEN + FIRST_ASSUM(MP_TAC o SPEC `n:num` o MATCH_MP SEQ_OFFSET) THEN + REWRITE_TAC[ADD_SYM]; + REWRITE_TAC[SIMPLE_IMAGE; FORALL_FINITE_SUBSET_IMAGE] THEN + X_GEN_TAC `i:num->bool` THEN STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o ISPEC `\n:num. n` o MATCH_MP + UPPER_BOUND_FINITE_SET) THEN + REWRITE_TAC[] THEN DISCH_THEN(X_CHOOSE_TAC `m:num`) THEN + REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; INTERS_IMAGE; IN_ELIM_THM] THEN + EXISTS_TAC `(x:num->real^M) m` THEN + X_GEN_TAC `p:num` THEN DISCH_TAC THEN + CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + REWRITE_TAC[IN_INSERT; IN_IMAGE; IN_UNIV] THEN DISJ2_TAC THEN + EXISTS_TAC `m - p:num` THEN + ASM_MESON_TAC[ARITH_RULE `p <= m ==> p + m - p:num = m`]]; + REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN MATCH_MP_TAC MONO_EXISTS THEN + X_GEN_TAC `x:real^M` THEN + REWRITE_TAC[INTERS_GSPEC; IN_ELIM_THM; IN_UNIV] THEN + DISCH_THEN(fun th -> LABEL_TAC "*" th THEN MP_TAC(SPEC `0` th)) THEN + REWRITE_TAC[ADD_CLAUSES; IN_INSERT; IN_IMAGE; IN_UNIV] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC (DISJ_CASES_THEN MP_TAC)) THEN + ASM_SIMP_TAC[] THEN DISCH_THEN(X_CHOOSE_TAC `i:num`) THEN + REMOVE_THEN "*" (MP_TAC o SPEC `i + 1`) THEN + ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN DISCH_TAC THEN + ASM_REWRITE_TAC[IN_INSERT; IN_IMAGE; IN_UNIV] THEN ARITH_TAC]; + STRIP_TAC THEN X_GEN_TAC `k:real^N->bool` THEN STRIP_TAC THEN + REWRITE_TAC[COMPACT_EQ_HEINE_BOREL] THEN + X_GEN_TAC `c:(real^M->bool)->bool` THEN STRIP_TAC THEN + SUBGOAL_THEN + `!a. a IN k + ==> ?g. g SUBSET c /\ FINITE g /\ + {x | x IN s /\ (f:real^M->real^N) x = a} SUBSET UNIONS g` + MP_TAC THENL + [X_GEN_TAC `a:real^N` THEN DISCH_TAC THEN UNDISCH_THEN + `!a. a IN t ==> compact {x | x IN s /\ (f:real^M->real^N) x = a}` + (MP_TAC o SPEC `a:real^N`) THEN + ANTS_TAC THENL [ASM SET_TAC[]; REWRITE_TAC[COMPACT_EQ_HEINE_BOREL]] THEN + DISCH_THEN MATCH_MP_TAC THEN ASM_REWRITE_TAC[] THEN ASM SET_TAC[]; + GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [RIGHT_IMP_EXISTS_THM] THEN + REWRITE_TAC[SKOLEM_THM; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `uu:real^N->(real^M->bool)->bool` THEN + DISCH_THEN(LABEL_TAC "*")] THEN + SUBGOAL_THEN + `!a. a IN k + ==> ?v. open v /\ a IN v /\ + {x | x IN s /\ (f:real^M->real^N) x IN v} SUBSET UNIONS(uu a)` + MP_TAC THENL + [REPEAT STRIP_TAC THEN + UNDISCH_THEN + `!k. closed_in (subtopology euclidean s) k + ==> closed_in (subtopology euclidean t) + (IMAGE (f:real^M->real^N) k)` + (MP_TAC o SPEC `(s:real^M->bool) DIFF UNIONS(uu(a:real^N))`) THEN + SIMP_TAC[closed_in; TOPSPACE_EUCLIDEAN_SUBTOPOLOGY] THEN ANTS_TAC THENL + [CONJ_TAC THENL [SET_TAC[]; ALL_TAC] THEN + REWRITE_TAC[SET_RULE `s DIFF (s DIFF t) = s INTER t`] THEN + MATCH_MP_TAC OPEN_IN_OPEN_INTER THEN + MATCH_MP_TAC OPEN_UNIONS THEN ASM SET_TAC[]; + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + REWRITE_TAC[OPEN_IN_OPEN] THEN MATCH_MP_TAC MONO_EXISTS THEN + X_GEN_TAC `v:real^N->bool` THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + REPEAT(FIRST_X_ASSUM(MP_TAC o SPEC `a:real^N`)) THEN + ASM_REWRITE_TAC[] THEN REPEAT + ((ANTS_TAC THENL [ASM SET_TAC[]; DISCH_TAC]) ORELSE STRIP_TAC) + THENL [ALL_TAC; ASM SET_TAC[]] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [EXTENSION]) THEN + DISCH_THEN(MP_TAC o SPEC `a:real^N`) THEN ASM SET_TAC[]]; + GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [RIGHT_IMP_EXISTS_THM] THEN + REWRITE_TAC[SKOLEM_THM; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `vv:real^N->(real^N->bool)` THEN + DISCH_THEN(LABEL_TAC "+")] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [COMPACT_EQ_HEINE_BOREL]) THEN + DISCH_THEN(MP_TAC o SPEC `IMAGE (vv:real^N->(real^N->bool)) k`) THEN + ANTS_TAC THENL [ASM SET_TAC[]; REWRITE_TAC[LEFT_IMP_EXISTS_THM]] THEN + ONCE_REWRITE_TAC[TAUT `p /\ q /\ r ==> s <=> q /\ p ==> r ==> s`] THEN + REWRITE_TAC[FORALL_FINITE_SUBSET_IMAGE] THEN + X_GEN_TAC `j:real^N->bool` THEN REPEAT STRIP_TAC THEN + EXISTS_TAC `UNIONS(IMAGE (uu:real^N->(real^M->bool)->bool) j)` THEN + REPEAT CONJ_TAC THENL + [ASM SET_TAC[]; + ASM_SIMP_TAC[FINITE_UNIONS; FORALL_IN_IMAGE; FINITE_IMAGE] THEN + ASM SET_TAC[]; + REWRITE_TAC[UNIONS_IMAGE; SUBSET; IN_UNIONS; IN_ELIM_THM] THEN + ASM SET_TAC[]]]);; + +let PROPER_MAP_FROM_COMPACT = prove + (`!f:real^M->real^N s k. + f continuous_on s /\ IMAGE f s SUBSET t /\ compact s /\ + closed_in (subtopology euclidean t) k + ==> compact {x | x IN s /\ f x IN k}`, + REPEAT STRIP_TAC THEN + MATCH_MP_TAC CLOSED_IN_COMPACT THEN EXISTS_TAC `s:real^M->bool` THEN + ASM_MESON_TAC[CONTINUOUS_CLOSED_IN_PREIMAGE_GEN]);; + +(* ------------------------------------------------------------------------- *) +(* Pasting functions together on open sets. *) +(* ------------------------------------------------------------------------- *) + +let PASTING_LEMMA = prove + (`!f:A->real^M->real^N g t s k. + (!i. i IN k + ==> open_in (subtopology euclidean s) (t i) /\ + (f i) continuous_on (t i)) /\ + (!i j x. i IN k /\ j IN k /\ x IN s INTER t i INTER t j + ==> f i x = f j x) /\ + (!x. x IN s ==> ?j. j IN k /\ x IN t j /\ g x = f j x) + ==> g continuous_on s`, + REPEAT GEN_TAC THEN REWRITE_TAC[CONTINUOUS_OPEN_IN_PREIMAGE_EQ] THEN + STRIP_TAC THEN X_GEN_TAC `u:real^N->bool` THEN DISCH_TAC THEN + SUBGOAL_THEN + `{x | x IN s /\ g x IN u} = + UNIONS {{x | x IN (t i) /\ ((f:A->real^M->real^N) i x) IN u} | + i IN k}` + SUBST1_TAC THENL + [SUBGOAL_THEN `!i. i IN k ==> ((t:A->real^M->bool) i) SUBSET s` + ASSUME_TAC THENL + [ASM_MESON_TAC[OPEN_IN_SUBSET; TOPSPACE_EUCLIDEAN_SUBTOPOLOGY]; + REWRITE_TAC[UNIONS_GSPEC] THEN ASM SET_TAC[]]; + MATCH_MP_TAC OPEN_IN_UNIONS THEN REWRITE_TAC[FORALL_IN_GSPEC] THEN + ASM_MESON_TAC[OPEN_IN_TRANS]]);; + +let PASTING_LEMMA_EXISTS = prove + (`!f:A->real^M->real^N t s k. + s SUBSET UNIONS {t i | i IN k} /\ + (!i. i IN k + ==> open_in (subtopology euclidean s) (t i) /\ + (f i) continuous_on (t i)) /\ + (!i j x. i IN k /\ j IN k /\ x IN s INTER t i INTER t j + ==> f i x = f j x) + ==> ?g. g continuous_on s /\ + (!x i. i IN k /\ x IN s INTER t i ==> g x = f i x)`, + REPEAT STRIP_TAC THEN + EXISTS_TAC `\x. (f:A->real^M->real^N)(@i. i IN k /\ x IN t i) x` THEN + CONJ_TAC THENL [ALL_TAC; ASM SET_TAC[]] THEN MATCH_MP_TAC PASTING_LEMMA THEN + MAP_EVERY EXISTS_TAC + [`f:A->real^M->real^N`; `t:A->real^M->bool`; `k:A->bool`] THEN + ASM SET_TAC[]);; + +let CONTINUOUS_ON_UNION_LOCAL_OPEN = prove + (`!f:real^M->real^N s. + open_in (subtopology euclidean (s UNION t)) s /\ + open_in (subtopology euclidean (s UNION t)) t /\ + f continuous_on s /\ f continuous_on t + ==> f continuous_on (s UNION t)`, + REPEAT STRIP_TAC THEN MP_TAC(ISPECL + [`\i:(real^M->bool). (f:real^M->real^N)`; `f:real^M->real^N`; + `\i:(real^M->bool). i`; `s UNION t:real^M->bool`; `{s:real^M->bool,t}`] + PASTING_LEMMA) THEN DISCH_THEN MATCH_MP_TAC THEN + ASM_REWRITE_TAC[FORALL_IN_INSERT; EXISTS_IN_INSERT; NOT_IN_EMPTY] THEN + REWRITE_TAC[IN_UNION]);; + +let CONTINUOUS_ON_UNION_OPEN = prove + (`!f s t. open s /\ open t /\ f continuous_on s /\ f continuous_on t + ==> f continuous_on (s UNION t)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC CONTINUOUS_ON_UNION_LOCAL_OPEN THEN + ASM_REWRITE_TAC[] THEN CONJ_TAC THEN MATCH_MP_TAC OPEN_OPEN_IN_TRANS THEN + ASM_SIMP_TAC[OPEN_UNION] THEN SET_TAC[]);; + +let CONTINUOUS_ON_CASES_LOCAL_OPEN = prove + (`!P f g:real^M->real^N s t. + open_in (subtopology euclidean (s UNION t)) s /\ + open_in (subtopology euclidean (s UNION t)) t /\ + f continuous_on s /\ g continuous_on t /\ + (!x. x IN s /\ ~P x \/ x IN t /\ P x ==> f x = g x) + ==> (\x. if P x then f x else g x) continuous_on (s UNION t)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC CONTINUOUS_ON_UNION_LOCAL_OPEN THEN + ASM_REWRITE_TAC[] THEN CONJ_TAC THEN MATCH_MP_TAC CONTINUOUS_ON_EQ THENL + [EXISTS_TAC `f:real^M->real^N`; EXISTS_TAC `g:real^M->real^N`] THEN + ASM_REWRITE_TAC[] THEN ASM_MESON_TAC[]);; + +let CONTINUOUS_ON_CASES_OPEN = prove + (`!P f g s t. + open s /\ + open t /\ + f continuous_on s /\ + g continuous_on t /\ + (!x. x IN s /\ ~P x \/ x IN t /\ P x ==> f x = g x) + ==> (\x. if P x then f x else g x) continuous_on s UNION t`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC CONTINUOUS_ON_CASES_LOCAL_OPEN THEN + ASM_REWRITE_TAC[] THEN CONJ_TAC THEN MATCH_MP_TAC OPEN_OPEN_IN_TRANS THEN + ASM_SIMP_TAC[OPEN_UNION] THEN SET_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* Likewise on closed sets, with a finiteness assumption. *) +(* ------------------------------------------------------------------------- *) + +let PASTING_LEMMA_CLOSED = prove + (`!f:A->real^M->real^N g t s k. + FINITE k /\ + (!i. i IN k + ==> closed_in (subtopology euclidean s) (t i) /\ + (f i) continuous_on (t i)) /\ + (!i j x. i IN k /\ j IN k /\ x IN s INTER t i INTER t j + ==> f i x = f j x) /\ + (!x. x IN s ==> ?j. j IN k /\ x IN t j /\ g x = f j x) + ==> g continuous_on s`, + REPEAT GEN_TAC THEN REWRITE_TAC[CONTINUOUS_CLOSED_IN_PREIMAGE_EQ] THEN + STRIP_TAC THEN X_GEN_TAC `u:real^N->bool` THEN DISCH_TAC THEN + SUBGOAL_THEN + `{x | x IN s /\ g x IN u} = + UNIONS {{x | x IN (t i) /\ ((f:A->real^M->real^N) i x) IN u} | + i IN k}` + SUBST1_TAC THENL + [SUBGOAL_THEN `!i. i IN k ==> ((t:A->real^M->bool) i) SUBSET s` + ASSUME_TAC THENL + [ASM_MESON_TAC[CLOSED_IN_SUBSET; TOPSPACE_EUCLIDEAN_SUBTOPOLOGY]; + REWRITE_TAC[UNIONS_GSPEC] THEN ASM SET_TAC[]]; + MATCH_MP_TAC CLOSED_IN_UNIONS THEN + ASM_SIMP_TAC[SIMPLE_IMAGE; FINITE_IMAGE; FORALL_IN_IMAGE] THEN + ASM_MESON_TAC[CLOSED_IN_TRANS]]);; + +let PASTING_LEMMA_EXISTS_CLOSED = prove + (`!f:A->real^M->real^N t s k. + FINITE k /\ + s SUBSET UNIONS {t i | i IN k} /\ + (!i. i IN k + ==> closed_in (subtopology euclidean s) (t i) /\ + (f i) continuous_on (t i)) /\ + (!i j x. i IN k /\ j IN k /\ x IN s INTER t i INTER t j + ==> f i x = f j x) + ==> ?g. g continuous_on s /\ + (!x i. i IN k /\ x IN s INTER t i ==> g x = f i x)`, + REPEAT STRIP_TAC THEN + EXISTS_TAC `\x. (f:A->real^M->real^N)(@i. i IN k /\ x IN t i) x` THEN + CONJ_TAC THENL [ALL_TAC; ASM SET_TAC[]] THEN + MATCH_MP_TAC PASTING_LEMMA_CLOSED THEN + MAP_EVERY EXISTS_TAC + [`f:A->real^M->real^N`; `t:A->real^M->bool`; `k:A->bool`] THEN + ASM SET_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* Closure of halflines, halfspaces and hyperplanes. *) +(* ------------------------------------------------------------------------- *) + +let LIM_LIFT_DOT = prove + (`!f:real^M->real^N a. + (f --> l) net ==> ((lift o (\y. a dot f(y))) --> lift(a dot l)) net`, + REPEAT GEN_TAC THEN ASM_CASES_TAC `a = vec 0:real^N` THENL + [ASM_REWRITE_TAC[DOT_LZERO; LIFT_NUM; o_DEF; LIM_CONST]; ALL_TAC] THEN + REWRITE_TAC[LIM] THEN MATCH_MP_TAC MONO_OR THEN REWRITE_TAC[] THEN + DISCH_TAC THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `e / norm(a:real^N)`) THEN + ASM_SIMP_TAC[REAL_LT_DIV; NORM_POS_LT; REAL_LT_RDIV_EQ] THEN + REWRITE_TAC[dist; o_THM; GSYM LIFT_SUB; GSYM DOT_RSUB; NORM_LIFT] THEN + ONCE_REWRITE_TAC[DOT_SYM] THEN + MESON_TAC[NORM_CAUCHY_SCHWARZ_ABS; REAL_MUL_SYM; REAL_LET_TRANS]);; + +let CONTINUOUS_AT_LIFT_DOT = prove + (`!a:real^N x. (lift o (\y. a dot y)) continuous at x`, + REPEAT GEN_TAC THEN REWRITE_TAC[CONTINUOUS_AT; o_THM] THEN + MATCH_MP_TAC LIM_LIFT_DOT THEN REWRITE_TAC[LIM_AT] THEN MESON_TAC[]);; + +let CONTINUOUS_ON_LIFT_DOT = prove + (`!s. (lift o (\y. a dot y)) continuous_on s`, + SIMP_TAC[CONTINUOUS_AT_IMP_CONTINUOUS_ON; CONTINUOUS_AT_LIFT_DOT]);; + +let CLOSED_INTERVAL_LEFT = prove + (`!b:real^N. + closed + {x:real^N | !i. 1 <= i /\ i <= dimindex(:N) ==> x$i <= b$i}`, + REWRITE_TAC[CLOSED_LIMPT; LIMPT_APPROACHABLE; IN_ELIM_THM] THEN + REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM REAL_NOT_LT] THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `(x:real^N)$i - (b:real^N)$i`) THEN + ASM_REWRITE_TAC[REAL_SUB_LT] THEN + DISCH_THEN(X_CHOOSE_THEN `z:real^N` MP_TAC) THEN + REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + REWRITE_TAC[dist; REAL_NOT_LT] THEN + MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC `abs((z - x :real^N)$i)` THEN + ASM_SIMP_TAC[COMPONENT_LE_NORM] THEN + ASM_SIMP_TAC[VECTOR_SUB_COMPONENT] THEN + ASM_SIMP_TAC[REAL_ARITH `z <= b /\ b < x ==> x - b <= abs(z - x)`]);; + +let CLOSED_INTERVAL_RIGHT = prove + (`!a:real^N. + closed + {x:real^N | !i. 1 <= i /\ i <= dimindex(:N) ==> a$i <= x$i}`, + REWRITE_TAC[CLOSED_LIMPT; LIMPT_APPROACHABLE; IN_ELIM_THM] THEN + REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM REAL_NOT_LT] THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `(a:real^N)$i - (x:real^N)$i`) THEN + ASM_REWRITE_TAC[REAL_SUB_LT] THEN + DISCH_THEN(X_CHOOSE_THEN `z:real^N` MP_TAC) THEN + REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + REWRITE_TAC[dist; REAL_NOT_LT] THEN + MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC `abs((z - x :real^N)$i)` THEN + ASM_SIMP_TAC[COMPONENT_LE_NORM] THEN + ASM_SIMP_TAC[VECTOR_SUB_COMPONENT] THEN + ASM_SIMP_TAC[REAL_ARITH `x < a /\ a <= z ==> a - x <= abs(z - x)`]);; + +let CLOSED_HALFSPACE_LE = prove + (`!a:real^N b. closed {x | a dot x <= b}`, + REPEAT GEN_TAC THEN + MP_TAC(ISPEC `(:real^N)` CONTINUOUS_ON_LIFT_DOT) THEN + REWRITE_TAC[CONTINUOUS_ON_CLOSED; GSYM CLOSED_IN; SUBTOPOLOGY_UNIV] THEN + DISCH_THEN(MP_TAC o SPEC + `IMAGE lift {r | ?x:real^N. (a dot x = r) /\ r <= b}`) THEN + ANTS_TAC THENL + [ALL_TAC; + MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN + REWRITE_TAC[EXTENSION; IN_ELIM_THM; IN_IMAGE; IN_UNIV] THEN + REWRITE_TAC[o_DEF] THEN MESON_TAC[LIFT_DROP]] THEN + REWRITE_TAC[CLOSED_IN_CLOSED] THEN + EXISTS_TAC `{x | !i. 1 <= i /\ i <= dimindex(:1) + ==> (x:real^1)$i <= (lift b)$i}` THEN + REWRITE_TAC[CLOSED_INTERVAL_LEFT] THEN + SIMP_TAC[EXTENSION; IN_IMAGE; IN_UNIV; IN_ELIM_THM; IN_INTER; + VEC_COMPONENT; DIMINDEX_1; LAMBDA_BETA; o_THM] THEN + SIMP_TAC[ARITH_RULE `1 <= i /\ i <= 1 <=> (i = 1)`] THEN + REWRITE_TAC[GSYM drop; LEFT_FORALL_IMP_THM; EXISTS_REFL] THEN + MESON_TAC[LIFT_DROP]);; + +let CLOSED_HALFSPACE_GE = prove + (`!a:real^N b. closed {x | a dot x >= b}`, + REWRITE_TAC[REAL_ARITH `a >= b <=> --a <= --b`] THEN + REWRITE_TAC[GSYM DOT_LNEG; CLOSED_HALFSPACE_LE]);; + +let CLOSED_HYPERPLANE = prove + (`!a b. closed {x | a dot x = b}`, + REPEAT GEN_TAC THEN REWRITE_TAC[GSYM REAL_LE_ANTISYM] THEN + REWRITE_TAC[REAL_ARITH `b <= a dot x <=> a dot x >= b`] THEN + REWRITE_TAC[SET_RULE `{x | P x /\ Q x} = {x | P x} INTER {x | Q x}`] THEN + SIMP_TAC[CLOSED_INTER; CLOSED_HALFSPACE_LE; CLOSED_HALFSPACE_GE]);; + +let CLOSED_STANDARD_HYPERPLANE = prove + (`!k a. closed {x:real^N | x$k = a}`, + REPEAT GEN_TAC THEN + SUBGOAL_THEN `?i. 1 <= i /\ i <= dimindex(:N) /\ !x:real^N. x$k = x$i` + CHOOSE_TAC THENL + [ASM_REWRITE_TAC[FINITE_INDEX_INRANGE]; ALL_TAC] THEN + MP_TAC(ISPECL [`basis i:real^N`; `a:real`] CLOSED_HYPERPLANE) THEN + ASM_SIMP_TAC[DOT_BASIS]);; + +let CLOSED_HALFSPACE_COMPONENT_LE = prove + (`!a k. closed {x:real^N | x$k <= a}`, + REPEAT GEN_TAC THEN + SUBGOAL_THEN `?i. 1 <= i /\ i <= dimindex(:N) /\ !x:real^N. x$k = x$i` + CHOOSE_TAC THENL + [ASM_REWRITE_TAC[FINITE_INDEX_INRANGE]; ALL_TAC] THEN + MP_TAC(ISPECL [`basis i:real^N`; `a:real`] CLOSED_HALFSPACE_LE) THEN + ASM_SIMP_TAC[DOT_BASIS]);; + +let CLOSED_HALFSPACE_COMPONENT_GE = prove + (`!a k. closed {x:real^N | x$k >= a}`, + REPEAT GEN_TAC THEN + SUBGOAL_THEN `?i. 1 <= i /\ i <= dimindex(:N) /\ !x:real^N. x$k = x$i` + CHOOSE_TAC THENL + [ASM_REWRITE_TAC[FINITE_INDEX_INRANGE]; ALL_TAC] THEN + MP_TAC(ISPECL [`basis i:real^N`; `a:real`] CLOSED_HALFSPACE_GE) THEN + ASM_SIMP_TAC[DOT_BASIS]);; + +(* ------------------------------------------------------------------------- *) +(* Openness of halfspaces. *) +(* ------------------------------------------------------------------------- *) + +let OPEN_HALFSPACE_LT = prove + (`!a b. open {x | a dot x < b}`, + REWRITE_TAC[GSYM REAL_NOT_LE] THEN + REWRITE_TAC[SET_RULE `{x | ~p x} = UNIV DIFF {x | p x}`] THEN + REWRITE_TAC[GSYM closed; GSYM real_ge; CLOSED_HALFSPACE_GE]);; + +let OPEN_HALFSPACE_COMPONENT_LT = prove + (`!a k. open {x:real^N | x$k < a}`, + REPEAT GEN_TAC THEN + SUBGOAL_THEN `?i. 1 <= i /\ i <= dimindex(:N) /\ !x:real^N. x$k = x$i` + CHOOSE_TAC THENL + [ASM_REWRITE_TAC[FINITE_INDEX_INRANGE]; ALL_TAC] THEN + MP_TAC(ISPECL [`basis i:real^N`; `a:real`] OPEN_HALFSPACE_LT) THEN + ASM_SIMP_TAC[DOT_BASIS]);; + +let OPEN_HALFSPACE_GT = prove + (`!a b. open {x | a dot x > b}`, + REWRITE_TAC[REAL_ARITH `x > y <=> ~(x <= y)`] THEN + REWRITE_TAC[SET_RULE `{x | ~p x} = UNIV DIFF {x | p x}`] THEN + REWRITE_TAC[GSYM closed; CLOSED_HALFSPACE_LE]);; + +let OPEN_HALFSPACE_COMPONENT_GT = prove + (`!a k. open {x:real^N | x$k > a}`, + REPEAT GEN_TAC THEN + SUBGOAL_THEN `?i. 1 <= i /\ i <= dimindex(:N) /\ !x:real^N. x$k = x$i` + CHOOSE_TAC THENL + [ASM_REWRITE_TAC[FINITE_INDEX_INRANGE]; ALL_TAC] THEN + MP_TAC(ISPECL [`basis i:real^N`; `a:real`] OPEN_HALFSPACE_GT) THEN + ASM_SIMP_TAC[DOT_BASIS]);; + +let OPEN_POSITIVE_MULTIPLES = prove + (`!s:real^N->bool. open s ==> open {c % x | &0 < c /\ x IN s}`, + REWRITE_TAC[open_def; FORALL_IN_GSPEC] THEN GEN_TAC THEN DISCH_TAC THEN + MAP_EVERY X_GEN_TAC [`c:real`; `x:real^N`] THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `x:real^N`) THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `e:real` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `c * e:real` THEN ASM_SIMP_TAC[REAL_LT_MUL] THEN + X_GEN_TAC `y:real^N` THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `inv(c) % y:real^N`) THEN ANTS_TAC THENL + [SUBGOAL_THEN `x:real^N = inv c % c % x` SUBST1_TAC THENL + [ASM_SIMP_TAC[VECTOR_MUL_ASSOC; REAL_MUL_LINV; VECTOR_MUL_LID; + REAL_LT_IMP_NZ]; + ASM_SIMP_TAC[DIST_MUL; real_abs; REAL_LT_INV_EQ; REAL_LT_IMP_LE] THEN + ONCE_REWRITE_TAC[REAL_ARITH `inv c * x:real = x / c`] THEN + ASM_MESON_TAC[REAL_LT_LDIV_EQ; REAL_MUL_SYM]]; + DISCH_TAC THEN REWRITE_TAC[IN_ELIM_THM] THEN + EXISTS_TAC `c:real` THEN EXISTS_TAC `inv(c) % y:real^N` THEN + ASM_SIMP_TAC[VECTOR_MUL_ASSOC; REAL_MUL_RINV; REAL_LT_IMP_NZ] THEN + VECTOR_ARITH_TAC]);; + +(* ------------------------------------------------------------------------- *) +(* Closures and interiors of halfspaces. *) +(* ------------------------------------------------------------------------- *) + +let INTERIOR_HALFSPACE_LE = prove + (`!a:real^N b. + ~(a = vec 0) ==> interior {x | a dot x <= b} = {x | a dot x < b}`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC INTERIOR_UNIQUE THEN + SIMP_TAC[OPEN_HALFSPACE_LT; SUBSET; IN_ELIM_THM; REAL_LT_IMP_LE] THEN + X_GEN_TAC `s:real^N->bool` THEN STRIP_TAC THEN + X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN ASM_SIMP_TAC[REAL_LT_LE] THEN + DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [OPEN_CONTAINS_CBALL]) THEN + DISCH_THEN(MP_TAC o SPEC `x:real^N`) THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `e:real` (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + REWRITE_TAC[SUBSET; IN_CBALL] THEN + DISCH_THEN(MP_TAC o SPEC `x + e / norm(a) % a:real^N`) THEN + REWRITE_TAC[NORM_ARITH `dist(x:real^N,x + y) = norm y`] THEN + ASM_SIMP_TAC[NORM_MUL; REAL_ABS_DIV; REAL_ABS_NORM; REAL_DIV_RMUL; + NORM_EQ_0; REAL_ARITH `&0 < x ==> abs x <= x`] THEN + DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `x + e / norm(a) % a:real^N`) THEN + ASM_REWRITE_TAC[DOT_RADD; DOT_RMUL] THEN + MATCH_MP_TAC(REAL_ARITH `&0 < e ==> ~(b + e <= b)`) THEN + ASM_SIMP_TAC[REAL_LT_MUL; REAL_LT_DIV; NORM_POS_LT; DOT_POS_LT]);; + +let INTERIOR_HALFSPACE_GE = prove + (`!a:real^N b. + ~(a = vec 0) ==> interior {x | a dot x >= b} = {x | a dot x > b}`, + REPEAT STRIP_TAC THEN + ONCE_REWRITE_TAC[REAL_ARITH `a >= b <=> --a <= --b`; + REAL_ARITH `a > b <=> --a < --b`] THEN + ASM_SIMP_TAC[GSYM DOT_LNEG; INTERIOR_HALFSPACE_LE; VECTOR_NEG_EQ_0]);; + +let INTERIOR_HALFSPACE_COMPONENT_LE = prove + (`!a k. interior {x:real^N | x$k <= a} = {x | x$k < a}`, + REPEAT GEN_TAC THEN + SUBGOAL_THEN `?i. 1 <= i /\ i <= dimindex(:N) /\ !x:real^N. x$k = x$i` + CHOOSE_TAC THENL + [ASM_REWRITE_TAC[FINITE_INDEX_INRANGE]; ALL_TAC] THEN + MP_TAC(ISPECL [`basis i:real^N`; `a:real`] INTERIOR_HALFSPACE_LE) THEN + ASM_SIMP_TAC[DOT_BASIS; BASIS_NONZERO]);; + +let INTERIOR_HALFSPACE_COMPONENT_GE = prove + (`!a k. interior {x:real^N | x$k >= a} = {x | x$k > a}`, + REPEAT GEN_TAC THEN + SUBGOAL_THEN `?i. 1 <= i /\ i <= dimindex(:N) /\ !x:real^N. x$k = x$i` + CHOOSE_TAC THENL + [ASM_REWRITE_TAC[FINITE_INDEX_INRANGE]; ALL_TAC] THEN + MP_TAC(ISPECL [`basis i:real^N`; `a:real`] INTERIOR_HALFSPACE_GE) THEN + ASM_SIMP_TAC[DOT_BASIS; BASIS_NONZERO]);; + +let CLOSURE_HALFSPACE_LT = prove + (`!a:real^N b. + ~(a = vec 0) ==> closure {x | a dot x < b} = {x | a dot x <= b}`, + REPEAT STRIP_TAC THEN REWRITE_TAC[CLOSURE_INTERIOR] THEN + REWRITE_TAC[SET_RULE `UNIV DIFF {x | P x} = {x | ~P x}`] THEN + ASM_SIMP_TAC[REAL_ARITH `~(x < b) <=> x >= b`; INTERIOR_HALFSPACE_GE] THEN + REWRITE_TAC[EXTENSION; IN_DIFF; IN_UNIV; IN_ELIM_THM] THEN REAL_ARITH_TAC);; + +let CLOSURE_HALFSPACE_GT = prove + (`!a:real^N b. + ~(a = vec 0) ==> closure {x | a dot x > b} = {x | a dot x >= b}`, + REPEAT STRIP_TAC THEN + ONCE_REWRITE_TAC[REAL_ARITH `a >= b <=> --a <= --b`; + REAL_ARITH `a > b <=> --a < --b`] THEN + ASM_SIMP_TAC[GSYM DOT_LNEG; CLOSURE_HALFSPACE_LT; VECTOR_NEG_EQ_0]);; + +let CLOSURE_HALFSPACE_COMPONENT_LT = prove + (`!a k. closure {x:real^N | x$k < a} = {x | x$k <= a}`, + REPEAT GEN_TAC THEN + SUBGOAL_THEN `?i. 1 <= i /\ i <= dimindex(:N) /\ !x:real^N. x$k = x$i` + CHOOSE_TAC THENL + [ASM_REWRITE_TAC[FINITE_INDEX_INRANGE]; ALL_TAC] THEN + MP_TAC(ISPECL [`basis i:real^N`; `a:real`] CLOSURE_HALFSPACE_LT) THEN + ASM_SIMP_TAC[DOT_BASIS; BASIS_NONZERO]);; + +let CLOSURE_HALFSPACE_COMPONENT_GT = prove + (`!a k. closure {x:real^N | x$k > a} = {x | x$k >= a}`, + REPEAT GEN_TAC THEN + SUBGOAL_THEN `?i. 1 <= i /\ i <= dimindex(:N) /\ !x:real^N. x$k = x$i` + CHOOSE_TAC THENL + [ASM_REWRITE_TAC[FINITE_INDEX_INRANGE]; ALL_TAC] THEN + MP_TAC(ISPECL [`basis i:real^N`; `a:real`] CLOSURE_HALFSPACE_GT) THEN + ASM_SIMP_TAC[DOT_BASIS; BASIS_NONZERO]);; + +let INTERIOR_HYPERPLANE = prove + (`!a b. ~(a = vec 0) ==> interior {x | a dot x = b} = {}`, + REWRITE_TAC[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 + REWRITE_TAC[INTERIOR_INTER] THEN + ASM_SIMP_TAC[INTERIOR_HALFSPACE_LE; INTERIOR_HALFSPACE_GE] THEN + REWRITE_TAC[EXTENSION; IN_INTER; IN_ELIM_THM; NOT_IN_EMPTY] THEN + REAL_ARITH_TAC);; + +let FRONTIER_HALFSPACE_LE = prove + (`!a:real^N b. ~(a = vec 0 /\ b = &0) + ==> frontier {x | a dot x <= b} = {x | a dot x = b}`, + REPEAT GEN_TAC THEN ASM_CASES_TAC `a:real^N = vec 0` THEN + ASM_SIMP_TAC[DOT_LZERO] THENL + [ASM_CASES_TAC `&0 <= b` THEN + ASM_REWRITE_TAC[UNIV_GSPEC; FRONTIER_UNIV; EMPTY_GSPEC; FRONTIER_EMPTY]; + ASM_SIMP_TAC[frontier; INTERIOR_HALFSPACE_LE; CLOSURE_CLOSED; + CLOSED_HALFSPACE_LE] THEN + REWRITE_TAC[EXTENSION; IN_DIFF; IN_ELIM_THM] THEN REAL_ARITH_TAC]);; + +let FRONTIER_HALFSPACE_GE = prove + (`!a:real^N b. ~(a = vec 0 /\ b = &0) + ==> frontier {x | a dot x >= b} = {x | a dot x = b}`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`--a:real^N`; `--b:real`] FRONTIER_HALFSPACE_LE) THEN + ASM_REWRITE_TAC[VECTOR_NEG_EQ_0; REAL_NEG_EQ_0; DOT_LNEG] THEN + REWRITE_TAC[REAL_LE_NEG2; REAL_EQ_NEG2; real_ge]);; + +let FRONTIER_HALFSPACE_LT = prove + (`!a:real^N b. ~(a = vec 0 /\ b = &0) + ==> frontier {x | a dot x < b} = {x | a dot x = b}`, + REPEAT GEN_TAC THEN ASM_CASES_TAC `a:real^N = vec 0` THEN + ASM_SIMP_TAC[DOT_LZERO] THENL + [ASM_CASES_TAC `&0 < b` THEN + ASM_REWRITE_TAC[UNIV_GSPEC; FRONTIER_UNIV; EMPTY_GSPEC; FRONTIER_EMPTY]; + ASM_SIMP_TAC[frontier; CLOSURE_HALFSPACE_LT; INTERIOR_OPEN; + OPEN_HALFSPACE_LT] THEN + REWRITE_TAC[EXTENSION; IN_DIFF; IN_ELIM_THM] THEN REAL_ARITH_TAC]);; + +let FRONTIER_HALFSPACE_GT = prove + (`!a:real^N b. ~(a = vec 0 /\ b = &0) + ==> frontier {x | a dot x > b} = {x | a dot x = b}`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`--a:real^N`; `--b:real`] FRONTIER_HALFSPACE_LT) THEN + ASM_REWRITE_TAC[VECTOR_NEG_EQ_0; REAL_NEG_EQ_0; DOT_LNEG] THEN + REWRITE_TAC[REAL_LT_NEG2; REAL_EQ_NEG2; real_gt]);; + +let INTERIOR_STANDARD_HYPERPLANE = prove + (`!k a. interior {x:real^N | x$k = a} = {}`, + REPEAT GEN_TAC THEN + SUBGOAL_THEN `?i. 1 <= i /\ i <= dimindex(:N) /\ !x:real^N. x$k = x$i` + CHOOSE_TAC THENL + [ASM_REWRITE_TAC[FINITE_INDEX_INRANGE]; ALL_TAC] THEN + MP_TAC(ISPECL [`basis i:real^N`; `a:real`] INTERIOR_HYPERPLANE) THEN + ASM_SIMP_TAC[DOT_BASIS; BASIS_NONZERO]);; + +let EMPTY_INTERIOR_LOWDIM = prove + (`!s:real^N->bool. dim(s) < dimindex(:N) ==> interior s = {}`, + GEN_TAC THEN DISCH_THEN(MP_TAC o MATCH_MP LOWDIM_SUBSET_HYPERPLANE) THEN + DISCH_THEN(X_CHOOSE_THEN `a:real^N` STRIP_ASSUME_TAC) THEN + MATCH_MP_TAC(SET_RULE + `!t u. s SUBSET t /\ t SUBSET u /\ u = {} ==> s = {}`) THEN + MAP_EVERY EXISTS_TAC + [`interior(span(s):real^N->bool)`; + `interior({x:real^N | a dot x = &0})`] THEN + ASM_SIMP_TAC[SUBSET_INTERIOR; SPAN_INC; INTERIOR_HYPERPLANE]);; + +(* ------------------------------------------------------------------------- *) +(* Unboundedness of halfspaces. *) +(* ------------------------------------------------------------------------- *) + +let UNBOUNDED_HALFSPACE_COMPONENT_LE = prove + (`!a k. ~bounded {x:real^N | x$k <= a}`, + REPEAT GEN_TAC THEN + SUBGOAL_THEN `?i. 1 <= i /\ i <= dimindex(:N) /\ !z:real^N. z$k = z$i` + CHOOSE_TAC THENL [REWRITE_TAC[FINITE_INDEX_INRANGE]; ALL_TAC] THEN + ASM_REWRITE_TAC[bounded; FORALL_IN_GSPEC] THEN + DISCH_THEN(X_CHOOSE_THEN `B:real` MP_TAC) THEN + REWRITE_TAC[NOT_FORALL_THM; NOT_IMP] THEN + EXISTS_TAC `--(&1 + max (abs B) (abs a)) % basis i:real^N` THEN + ASM_SIMP_TAC[NORM_MUL; NORM_BASIS; BASIS_COMPONENT; + VECTOR_MUL_COMPONENT] THEN + REAL_ARITH_TAC);; + +let UNBOUNDED_HALFSPACE_COMPONENT_GE = prove + (`!a k. ~bounded {x:real^N | x$k >= a}`, + REPEAT GEN_TAC THEN DISCH_THEN(MP_TAC o MATCH_MP BOUNDED_NEGATIONS) THEN + MP_TAC(SPECL [`--a:real`; `k:num`] UNBOUNDED_HALFSPACE_COMPONENT_LE) THEN + REWRITE_TAC[CONTRAPOS_THM] THEN MATCH_MP_TAC EQ_IMP THEN + AP_TERM_TAC THEN MATCH_MP_TAC SURJECTIVE_IMAGE_EQ THEN CONJ_TAC THENL + [MESON_TAC[VECTOR_NEG_NEG]; + REWRITE_TAC[IN_ELIM_THM; VECTOR_NEG_COMPONENT] THEN REAL_ARITH_TAC]);; + +let UNBOUNDED_HALFSPACE_COMPONENT_LT = prove + (`!a k. ~bounded {x:real^N | x$k < a}`, + ONCE_REWRITE_TAC[GSYM BOUNDED_CLOSURE_EQ] THEN + REWRITE_TAC[CLOSURE_HALFSPACE_COMPONENT_LT; + UNBOUNDED_HALFSPACE_COMPONENT_LE]);; + +let UNBOUNDED_HALFSPACE_COMPONENT_GT = prove + (`!a k. ~bounded {x:real^N | x$k > a}`, + ONCE_REWRITE_TAC[GSYM BOUNDED_CLOSURE_EQ] THEN + REWRITE_TAC[CLOSURE_HALFSPACE_COMPONENT_GT; + UNBOUNDED_HALFSPACE_COMPONENT_GE]);; + +let BOUNDED_HALFSPACE_LE = prove + (`!a:real^N b. bounded {x | a dot x <= b} <=> a = vec 0 /\ b < &0`, + GEOM_BASIS_MULTIPLE_TAC 1 `a:real^N` THEN + SIMP_TAC[DOT_LMUL; DOT_BASIS; VECTOR_MUL_EQ_0; DIMINDEX_GE_1; LE_REFL; + BASIS_NONZERO] THEN + X_GEN_TAC `a:real` THEN ASM_CASES_TAC `a = &0` THEN ASM_REWRITE_TAC[] THEN + DISCH_TAC THEN X_GEN_TAC `b:real` THENL + [REWRITE_TAC[REAL_MUL_LZERO; DOT_LZERO; GSYM REAL_NOT_LE] THEN + ASM_CASES_TAC `&0 <= b` THEN + ASM_REWRITE_TAC[BOUNDED_EMPTY; NOT_BOUNDED_UNIV; + SET_RULE `{x | T} = UNIV`; EMPTY_GSPEC]; + ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN + ASM_SIMP_TAC[GSYM REAL_LE_RDIV_EQ; REAL_LT_LE; + UNBOUNDED_HALFSPACE_COMPONENT_LE]]);; + +let BOUNDED_HALFSPACE_GE = prove + (`!a:real^N b. bounded {x | a dot x >= b} <=> a = vec 0 /\ &0 < b`, + REWRITE_TAC[REAL_ARITH `a >= b <=> --a <= --b`] THEN + REWRITE_TAC[GSYM DOT_LNEG; BOUNDED_HALFSPACE_LE] THEN + REWRITE_TAC[VECTOR_NEG_EQ_0; REAL_ARITH `--b < &0 <=> &0 < b`]);; + +let BOUNDED_HALFSPACE_LT = prove + (`!a:real^N b. bounded {x | a dot x < b} <=> a = vec 0 /\ b <= &0`, + REPEAT GEN_TAC THEN ASM_CASES_TAC `a:real^N = vec 0` THEN + ASM_REWRITE_TAC[] THENL + [REWRITE_TAC[DOT_LZERO; GSYM REAL_NOT_LE] THEN ASM_CASES_TAC `b <= &0` THEN + ASM_REWRITE_TAC[BOUNDED_EMPTY; NOT_BOUNDED_UNIV; + SET_RULE `{x | T} = UNIV`; EMPTY_GSPEC]; + ONCE_REWRITE_TAC[GSYM BOUNDED_CLOSURE_EQ] THEN + ASM_SIMP_TAC[CLOSURE_HALFSPACE_LT; BOUNDED_HALFSPACE_LE]]);; + +let BOUNDED_HALFSPACE_GT = prove + (`!a:real^N b. bounded {x | a dot x > b} <=> a = vec 0 /\ &0 <= b`, + REWRITE_TAC[REAL_ARITH `a > b <=> --a < --b`] THEN + REWRITE_TAC[GSYM DOT_LNEG; BOUNDED_HALFSPACE_LT] THEN + REWRITE_TAC[VECTOR_NEG_EQ_0; REAL_ARITH `--b <= &0 <=> &0 <= b`]);; + +(* ------------------------------------------------------------------------- *) +(* Equality of continuous functions on closure and related results. *) +(* ------------------------------------------------------------------------- *) + +let FORALL_IN_CLOSURE = prove + (`!f:real^M->real^N s t. + closed t /\ f continuous_on (closure s) /\ + (!x. x IN s ==> f x IN t) + ==> (!x. x IN closure s ==> f x IN t)`, + REWRITE_TAC[SET_RULE `(!x. x IN s ==> f x IN t) <=> + s SUBSET {x | x IN s /\ f x IN t}`] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC CLOSURE_MINIMAL THEN + ASM_REWRITE_TAC[CLOSED_CLOSURE] THEN CONJ_TAC THENL + [MP_TAC(ISPEC `s:real^M->bool` CLOSURE_SUBSET) THEN ASM SET_TAC[]; + MATCH_MP_TAC CONTINUOUS_CLOSED_PREIMAGE THEN + ASM_REWRITE_TAC[CLOSED_CLOSURE]]);; + +let CONTINUOUS_LE_ON_CLOSURE = prove + (`!f:real^M->real s a. + (lift o f) continuous_on closure(s) /\ (!x. x IN s ==> f(x) <= a) + ==> !x. x IN closure(s) ==> f(x) <= a`, + let lemma = prove + (`x IN s ==> f x <= a <=> x IN s ==> (lift o f) x IN {y | y$1 <= a}`, + REWRITE_TAC[IN_ELIM_THM; o_THM; GSYM drop; LIFT_DROP]) in + REWRITE_TAC[lemma] THEN REPEAT GEN_TAC THEN STRIP_TAC THEN + MATCH_MP_TAC FORALL_IN_CLOSURE THEN + ASM_REWRITE_TAC[ETA_AX; CLOSED_HALFSPACE_COMPONENT_LE]);; + +let CONTINUOUS_GE_ON_CLOSURE = prove + (`!f:real^M->real s a. + (lift o f) continuous_on closure(s) /\ (!x. x IN s ==> a <= f(x)) + ==> !x. x IN closure(s) ==> a <= f(x)`, + let lemma = prove + (`x IN s ==> a <= f x <=> x IN s ==> (lift o f) x IN {y | y$1 >= a}`, + REWRITE_TAC[IN_ELIM_THM; o_THM; GSYM drop; real_ge; LIFT_DROP]) in + REWRITE_TAC[lemma] THEN REPEAT GEN_TAC THEN STRIP_TAC THEN + MATCH_MP_TAC FORALL_IN_CLOSURE THEN + ASM_REWRITE_TAC[ETA_AX; CLOSED_HALFSPACE_COMPONENT_GE]);; + +let CONTINUOUS_CONSTANT_ON_CLOSURE = prove + (`!f:real^M->real^N s a. + f continuous_on closure(s) /\ (!x. x IN s ==> f(x) = a) + ==> !x. x IN closure(s) ==> f(x) = a`, + REWRITE_TAC[SET_RULE + `x IN s ==> f x = a <=> x IN s ==> f x IN {a}`] THEN + REPEAT GEN_TAC THEN STRIP_TAC THEN MATCH_MP_TAC FORALL_IN_CLOSURE THEN + ASM_REWRITE_TAC[CLOSED_SING]);; + +let CONTINUOUS_AGREE_ON_CLOSURE = prove + (`!g h:real^M->real^N. + g continuous_on closure s /\ h continuous_on closure s /\ + (!x. x IN s ==> g x = h x) + ==> !x. x IN closure s ==> g x = h x`, + REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[GSYM VECTOR_SUB_EQ] THEN STRIP_TAC THEN + MATCH_MP_TAC CONTINUOUS_CONSTANT_ON_CLOSURE THEN + ASM_SIMP_TAC[CONTINUOUS_ON_SUB]);; + +let CONTINUOUS_CLOSED_IN_PREIMAGE_CONSTANT = prove + (`!f:real^M->real^N s a. + f continuous_on s + ==> closed_in (subtopology euclidean s) {x | x IN s /\ f x = a}`, + REPEAT STRIP_TAC THEN + ONCE_REWRITE_TAC[SET_RULE + `{x | x IN s /\ f(x) = a} = {x | x IN s /\ f(x) IN {a}}`] THEN + MATCH_MP_TAC CONTINUOUS_CLOSED_IN_PREIMAGE THEN + ASM_REWRITE_TAC[CLOSED_SING]);; + +let CONTINUOUS_CLOSED_PREIMAGE_CONSTANT = prove + (`!f:real^M->real^N s. + f continuous_on s /\ closed s ==> closed {x | x IN s /\ f(x) = a}`, + REPEAT STRIP_TAC THEN + ASM_CASES_TAC `{x | x IN s /\ (f:real^M->real^N)(x) = a} = {}` THEN + ASM_REWRITE_TAC[CLOSED_EMPTY] THEN ONCE_REWRITE_TAC[SET_RULE + `{x | x IN s /\ f(x) = a} = {x | x IN s /\ f(x) IN {a}}`] THEN + MATCH_MP_TAC CONTINUOUS_CLOSED_PREIMAGE THEN + ASM_REWRITE_TAC[CLOSED_SING] THEN ASM SET_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* Theorems relating continuity and uniform continuity to closures. *) +(* ------------------------------------------------------------------------- *) + +let CONTINUOUS_ON_CLOSURE = prove + (`!f:real^M->real^N s. + f continuous_on closure s <=> + !x e. x IN closure s /\ &0 < e + ==> ?d. &0 < d /\ + !y. y IN s /\ dist(y,x) < d ==> dist(f y,f x) < e`, + REPEAT GEN_TAC THEN REWRITE_TAC[continuous_on] THEN + EQ_TAC THENL [MESON_TAC[REWRITE_RULE[SUBSET] CLOSURE_SUBSET]; ALL_TAC] THEN + DISCH_TAC THEN X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN + X_GEN_TAC `e:real` THEN DISCH_TAC THEN + FIRST_ASSUM(MP_TAC o SPECL [`x:real^M`; `e / &2`]) THEN + ANTS_TAC THENL [ASM_REWRITE_TAC[REAL_HALF]; ALL_TAC] THEN + DISCH_THEN(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `d / &2` THEN ASM_REWRITE_TAC[REAL_HALF] THEN + X_GEN_TAC `y:real^M` THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`y:real^M`; `e / &2`]) THEN + ASM_REWRITE_TAC[REAL_HALF] THEN + DISCH_THEN(X_CHOOSE_THEN `k:real` STRIP_ASSUME_TAC) THEN + MP_TAC(ISPECL [`y:real^M`; `s:real^M->bool`] CLOSURE_APPROACHABLE) THEN + ASM_REWRITE_TAC[] THEN DISCH_THEN(MP_TAC o SPEC `min k (d / &2)`) THEN + ASM_REWRITE_TAC[REAL_HALF; REAL_LT_MIN] THEN + ASM_MESON_TAC[DIST_SYM; NORM_ARITH + `dist(a,b) < e / &2 /\ dist(b,c) < e / &2 ==> dist(a,c) < e`]);; + +let CONTINUOUS_ON_CLOSURE_SEQUENTIALLY = prove + (`!f:real^M->real^N s. + f continuous_on closure s <=> + !x a. a IN closure s /\ (!n. x n IN s) /\ (x --> a) sequentially + ==> ((f o x) --> f a) sequentially`, + REWRITE_TAC[CONTINUOUS_ON_CLOSURE] THEN + REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN + REWRITE_TAC[IMP_IMP; GSYM continuous_within] THEN + REWRITE_TAC[CONTINUOUS_WITHIN_SEQUENTIALLY] THEN MESON_TAC[]);; + +let UNIFORMLY_CONTINUOUS_ON_CLOSURE = prove + (`!f:real^M->real^N s. + f uniformly_continuous_on s /\ f continuous_on closure s + ==> f uniformly_continuous_on closure s`, + REPEAT GEN_TAC THEN + REWRITE_TAC[uniformly_continuous_on] THEN STRIP_TAC THEN + X_GEN_TAC `e:real` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `e / &3`) THEN + ANTS_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN + DISCH_THEN(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `d / &3` THEN CONJ_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN + MAP_EVERY X_GEN_TAC [`x:real^M`; `y:real^M`] THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [continuous_on]) THEN + DISCH_THEN(fun th -> + MP_TAC(SPEC `y:real^M` th) THEN MP_TAC(SPEC `x:real^M` th)) THEN + ASM_REWRITE_TAC[] 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 `d1:real` (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + MP_TAC(ISPECL [`x:real^M`; `s:real^M->bool`] CLOSURE_APPROACHABLE) THEN + ASM_REWRITE_TAC[] THEN DISCH_THEN(MP_TAC o SPEC `min d1 (d / &3)`) THEN + ANTS_TAC THENL [ASM_REAL_ARITH_TAC; REWRITE_TAC[REAL_LT_MIN]] THEN + DISCH_THEN(X_CHOOSE_THEN `x':real^M` STRIP_ASSUME_TAC) THEN + DISCH_THEN(MP_TAC o SPEC `x':real^M`) THEN + ASM_SIMP_TAC[REWRITE_RULE[SUBSET] CLOSURE_SUBSET] THEN DISCH_TAC 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 `d2:real` (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + MP_TAC(ISPECL [`y:real^M`; `s:real^M->bool`] CLOSURE_APPROACHABLE) THEN + ASM_REWRITE_TAC[] THEN DISCH_THEN(MP_TAC o SPEC `min d2 (d / &3)`) THEN + ANTS_TAC THENL [ASM_REAL_ARITH_TAC; REWRITE_TAC[REAL_LT_MIN]] THEN + DISCH_THEN(X_CHOOSE_THEN `y':real^M` STRIP_ASSUME_TAC) THEN + DISCH_THEN(MP_TAC o SPEC `y':real^M`) THEN + ASM_SIMP_TAC[REWRITE_RULE[SUBSET] CLOSURE_SUBSET] THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`x':real^M`; `y':real^M`]) THEN + ASM_MESON_TAC[DIST_SYM; NORM_ARITH + `dist(y,x) < d / &3 /\ dist(x',x) < d / &3 /\ dist(y',y) < d / &3 + ==> dist(y',x') < d`]);; + +(* ------------------------------------------------------------------------- *) +(* Continuity properties for square roots. We get other forms of this *) +(* later (transcendentals.ml and realanalysis.ml) but it's nice to have *) +(* them around earlier. *) +(* ------------------------------------------------------------------------- *) + +let CONTINUOUS_AT_SQRT = prove + (`!a s. &0 < drop a ==> (lift o sqrt o drop) continuous (at a)`, + REPEAT STRIP_TAC THEN REWRITE_TAC[continuous_at; o_THM; DIST_LIFT] THEN + X_GEN_TAC `e:real` THEN DISCH_TAC THEN + EXISTS_TAC `min (drop a) (e * sqrt(drop a))` THEN + ASM_SIMP_TAC[REAL_LT_MIN; SQRT_POS_LT; REAL_LT_MUL; DIST_REAL] THEN + X_GEN_TAC `b:real^1` THEN REWRITE_TAC[GSYM drop] THEN STRIP_TAC THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP (REAL_ARITH + `abs(b - a) < a ==> &0 < b`)) THEN + SUBGOAL_THEN + `sqrt(drop b) - sqrt(drop a) = + (drop b - drop a) / (sqrt(drop a) + sqrt(drop b))` + SUBST1_TAC THENL + [MATCH_MP_TAC(REAL_FIELD + `sa pow 2 = a /\ sb pow 2 = b /\ &0 < sa /\ &0 < sb + ==> sb - sa = (b - a) / (sa + sb)`) THEN + ASM_SIMP_TAC[SQRT_POS_LT; SQRT_POW_2; REAL_LT_IMP_LE]; + ASM_SIMP_TAC[REAL_ABS_DIV; SQRT_POS_LT; REAL_LT_ADD; REAL_LT_LDIV_EQ; + REAL_ARITH `&0 < x ==> abs x = x`] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + REAL_LTE_TRANS)) THEN + ASM_SIMP_TAC[REAL_LE_LMUL_EQ; REAL_LE_ADDR; SQRT_POS_LE; + REAL_LT_IMP_LE]]);; + +let CONTINUOUS_WITHIN_LIFT_SQRT = prove + (`!a s. (!x. x IN s ==> &0 <= drop x) + ==> (lift o sqrt o drop) continuous (at a within s)`, + REPEAT STRIP_TAC THEN + REPEAT_TCL DISJ_CASES_THEN ASSUME_TAC + (REAL_ARITH `drop a < &0 \/ drop a = &0 \/ &0 < drop a`) + THENL + [MATCH_MP_TAC CONTINUOUS_WITHIN_SUBSET THEN + EXISTS_TAC `{x | &0 <= drop x}` THEN + ASM_SIMP_TAC[SUBSET; IN_ELIM_THM] THEN + MATCH_MP_TAC CONTINUOUS_WITHIN_CLOSED_NONTRIVIAL THEN + ASM_REWRITE_TAC[IN_ELIM_THM; REAL_NOT_LE] THEN + REWRITE_TAC[drop; REWRITE_RULE[real_ge] CLOSED_HALFSPACE_COMPONENT_GE]; + RULE_ASSUM_TAC(REWRITE_RULE[GSYM LIFT_EQ; LIFT_DROP; LIFT_NUM]) THEN + ASM_REWRITE_TAC[continuous_within; o_THM; DROP_VEC; SQRT_0; LIFT_NUM] THEN + REWRITE_TAC[DIST_0; NORM_LIFT; NORM_REAL; GSYM drop] THEN + X_GEN_TAC `e:real` THEN DISCH_TAC THEN + EXISTS_TAC `(e:real) pow 2` THEN ASM_SIMP_TAC[REAL_POW_LT] THEN + X_GEN_TAC `x:real^1` THEN STRIP_TAC THEN + ASM_SIMP_TAC[real_abs; SQRT_POS_LE] THEN + SUBGOAL_THEN `e = sqrt(e pow 2)` SUBST1_TAC THENL + [ASM_SIMP_TAC[POW_2_SQRT; REAL_LT_IMP_LE]; + MATCH_MP_TAC SQRT_MONO_LT THEN ASM_SIMP_TAC[] THEN ASM_REAL_ARITH_TAC]; + MATCH_MP_TAC CONTINUOUS_AT_WITHIN THEN + MATCH_MP_TAC CONTINUOUS_AT_SQRT THEN ASM_REWRITE_TAC[]]);; + +let CONTINUOUS_WITHIN_SQRT_COMPOSE = prove + (`!f s a:real^N. + (\x. lift(f x)) continuous (at a within s) /\ + (&0 < f a \/ !x. x IN s ==> &0 <= f x) + ==> (\x. lift(sqrt(f x))) continuous (at a within s)`, + REPEAT GEN_TAC THEN + SUBGOAL_THEN + `(\x:real^N. lift(sqrt(f x))) = (lift o sqrt o drop) o (lift o f)` + SUBST1_TAC THENL [REWRITE_TAC[o_DEF; LIFT_DROP]; ALL_TAC] THEN + REPEAT STRIP_TAC THEN + (MATCH_MP_TAC CONTINUOUS_WITHIN_COMPOSE THEN + CONJ_TAC THENL [ASM_REWRITE_TAC[o_DEF]; ALL_TAC]) + THENL + [MATCH_MP_TAC CONTINUOUS_AT_WITHIN THEN + MATCH_MP_TAC CONTINUOUS_AT_SQRT THEN ASM_REWRITE_TAC[o_DEF; LIFT_DROP]; + MATCH_MP_TAC CONTINUOUS_WITHIN_LIFT_SQRT THEN + ASM_REWRITE_TAC[FORALL_IN_IMAGE; o_DEF; LIFT_DROP]]);; + +let CONTINUOUS_AT_SQRT_COMPOSE = prove + (`!f a:real^N. + (\x. lift(f x)) continuous (at a) /\ (&0 < f a \/ !x. &0 <= f x) + ==> (\x. lift(sqrt(f x))) continuous (at a)`, + REPEAT GEN_TAC THEN + MP_TAC(ISPECL [`f:real^N->real`; `(:real^N)`; `a:real^N`] + CONTINUOUS_WITHIN_SQRT_COMPOSE) THEN + REWRITE_TAC[WITHIN_UNIV; IN_UNIV]);; + +let CONTINUOUS_ON_LIFT_SQRT = prove + (`!s. (!x. x IN s ==> &0 <= drop x) + ==> (lift o sqrt o drop) continuous_on s`, + SIMP_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN; CONTINUOUS_WITHIN_LIFT_SQRT]);; + +let CONTINUOUS_ON_LIFT_SQRT_COMPOSE = prove + (`!f:real^N->real s. + (lift o f) continuous_on s /\ (!x. x IN s ==> &0 <= f x) + ==> (\x. lift(sqrt(f x))) continuous_on s`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN + `(\x:real^N. lift(sqrt(f x))) = (lift o sqrt o drop) o (lift o f)` + SUBST1_TAC THENL + [REWRITE_TAC[o_DEF; LIFT_DROP]; + MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC CONTINUOUS_ON_LIFT_SQRT THEN + ASM_REWRITE_TAC[FORALL_IN_IMAGE; o_THM; LIFT_DROP]]);; + +(* ------------------------------------------------------------------------- *) +(* Cauchy continuity, and the extension of functions to closures. *) +(* ------------------------------------------------------------------------- *) + +let UNIFORMLY_CONTINUOUS_IMP_CAUCHY_CONTINUOUS = prove + (`!f:real^M->real^N s. + f uniformly_continuous_on s + ==> (!x. cauchy x /\ (!n. (x n) IN s) ==> cauchy(f o x))`, + REPEAT GEN_TAC THEN REWRITE_TAC[uniformly_continuous_on; cauchy; o_DEF] THEN + MESON_TAC[]);; + +let CONTINUOUS_CLOSED_IMP_CAUCHY_CONTINUOUS = prove + (`!f:real^M->real^N s. + f continuous_on s /\ closed s + ==> (!x. cauchy x /\ (!n. (x n) IN s) ==> cauchy(f o x))`, + REWRITE_TAC[GSYM COMPLETE_EQ_CLOSED; CONTINUOUS_ON_SEQUENTIALLY] THEN + REWRITE_TAC[complete] THEN MESON_TAC[CONVERGENT_IMP_CAUCHY]);; + +let CAUCHY_CONTINUOUS_UNIQUENESS_LEMMA = prove + (`!f:real^M->real^N s. + (!x. cauchy x /\ (!n. (x n) IN s) ==> cauchy(f o x)) + ==> !a x. (!n. (x n) IN s) /\ (x --> a) sequentially + ==> ?l. ((f o x) --> l) sequentially /\ + !y. (!n. (y n) IN s) /\ (y --> a) sequentially + ==> ((f o y) --> l) sequentially`, + REPEAT STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o SPEC `x:num->real^M`) THEN + ANTS_TAC THENL [ASM_MESON_TAC[CONVERGENT_IMP_CAUCHY]; ALL_TAC] THEN + REWRITE_TAC[GSYM CONVERGENT_EQ_CAUCHY] THEN MATCH_MP_TAC MONO_EXISTS THEN + X_GEN_TAC `l:real^N` THEN DISCH_TAC THEN ASM_REWRITE_TAC[] THEN + X_GEN_TAC `y:num->real^M` THEN STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o SPEC `y:num->real^M`) THEN + ANTS_TAC THENL [ASM_MESON_TAC[CONVERGENT_IMP_CAUCHY]; ALL_TAC] THEN + REWRITE_TAC[GSYM CONVERGENT_EQ_CAUCHY] THEN + DISCH_THEN(X_CHOOSE_THEN `m:real^N` STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN `l:real^N = m` (fun th -> ASM_REWRITE_TAC[th]) THEN + ONCE_REWRITE_TAC[GSYM VECTOR_SUB_EQ] THEN + MATCH_MP_TAC(ISPEC `sequentially` LIM_UNIQUE) THEN + EXISTS_TAC `\n:num. (f:real^M->real^N)(x n) - f(y n)` THEN + RULE_ASSUM_TAC(REWRITE_RULE[o_DEF]) THEN + ASM_SIMP_TAC[LIM_SUB; TRIVIAL_LIMIT_SEQUENTIALLY] THEN + FIRST_X_ASSUM(MP_TAC o SPEC + `\n. if EVEN n then x(n DIV 2):real^M else y(n DIV 2)`) THEN + REWRITE_TAC[cauchy; o_THM; LIM_SEQUENTIALLY] THEN ANTS_TAC THENL + [CONJ_TAC THENL [ALL_TAC; ASM_MESON_TAC[]] THEN + X_GEN_TAC `e:real` THEN DISCH_TAC THEN MAP_EVERY UNDISCH_TAC + [`((y:num->real^M) --> a) sequentially`; + `((x:num->real^M) --> a) sequentially`] THEN + REPEAT(FIRST_X_ASSUM(K ALL_TAC o check (is_forall o concl))) THEN + REWRITE_TAC[LIM_SEQUENTIALLY] THEN + DISCH_THEN(MP_TAC o SPEC `e / &2`) THEN ASM_REWRITE_TAC[REAL_HALF] THEN + DISCH_THEN(X_CHOOSE_TAC `N1:num`) THEN + DISCH_THEN(MP_TAC o SPEC `e / &2`) THEN ASM_REWRITE_TAC[REAL_HALF] THEN + DISCH_THEN(X_CHOOSE_TAC `N2:num`) THEN + EXISTS_TAC `2 * (N1 + N2)` THEN + MAP_EVERY X_GEN_TAC [`m:num`; `n:num`] THEN STRIP_TAC THEN + REPEAT(FIRST_X_ASSUM(fun th -> + MP_TAC(SPEC `m DIV 2` th) THEN MP_TAC(SPEC `n DIV 2` th))) THEN + REPEAT(ANTS_TAC THENL [ASM_ARITH_TAC; DISCH_TAC]) THEN + REPEAT(COND_CASES_TAC THEN ASM_REWRITE_TAC[]) THEN + REPEAT(FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM REAL_NOT_LE])) THEN + CONV_TAC NORM_ARITH; + MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `e:real` THEN + ASM_CASES_TAC `&0 < e` THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `N:num` THEN DISCH_TAC THEN + X_GEN_TAC `n:num` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`2 * n`; `2 * n + 1`]) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN + REWRITE_TAC[EVEN_ADD; EVEN_MULT; ARITH_EVEN] THEN + REWRITE_TAC[ARITH_RULE `(2 * n) DIV 2 = n /\ (2 * n + 1) DIV 2 = n`] THEN + REWRITE_TAC[dist; VECTOR_SUB_RZERO]]);; + +let CAUCHY_CONTINUOUS_EXTENDS_TO_CLOSURE = prove + (`!f:real^M->real^N s. + (!x. cauchy x /\ (!n. (x n) IN s) ==> cauchy(f o x)) + ==> ?g. g continuous_on closure s /\ (!x. x IN s ==> g x = f x)`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN + `!a:real^M. ?x. + a IN closure s ==> (!n. x n IN s) /\ (x --> a) sequentially` + MP_TAC THENL [MESON_TAC[CLOSURE_SEQUENTIAL]; ALL_TAC] THEN + REWRITE_TAC[SKOLEM_THM; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `X:real^M->num->real^M` THEN DISCH_TAC THEN + FIRST_ASSUM(MP_TAC o MATCH_MP CAUCHY_CONTINUOUS_UNIQUENESS_LEMMA) THEN + DISCH_THEN(MP_TAC o GEN `a:real^M` o + SPECL [`a:real^M`; `(X:real^M->num->real^M) a`]) THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (MESON[] + `(!a. P a ==> Q a) ==> ((!a. P a ==> R a) ==> p) + ==> ((!a. Q a ==> R a) ==> p)`)) THEN + GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [RIGHT_IMP_EXISTS_THM] THEN + REWRITE_TAC[SKOLEM_THM] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `g:real^M->real^N` THEN + STRIP_TAC THEN + MATCH_MP_TAC(TAUT `b /\ (b ==> a) ==> a /\ b`) THEN CONJ_TAC THENL + [X_GEN_TAC `a:real^M` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `a:real^M`) THEN + ASM_SIMP_TAC[REWRITE_RULE[SUBSET] CLOSURE_SUBSET] THEN + DISCH_THEN(MP_TAC o SPEC `(\n. a):num->real^M` o CONJUNCT2) THEN + ASM_SIMP_TAC[LIM_CONST_EQ; o_DEF; TRIVIAL_LIMIT_SEQUENTIALLY]; + STRIP_TAC] THEN + ASM_SIMP_TAC[CONTINUOUS_ON_CLOSURE_SEQUENTIALLY] THEN + MAP_EVERY X_GEN_TAC [`x:num->real^M`; `a:real^M`] THEN STRIP_TAC THEN + MATCH_MP_TAC LIM_TRANSFORM_EVENTUALLY THEN + EXISTS_TAC `(f:real^M->real^N) o (x:num->real^M)` THEN ASM_SIMP_TAC[] THEN + MATCH_MP_TAC ALWAYS_EVENTUALLY THEN ASM_SIMP_TAC[o_THM]);; + +let UNIFORMLY_CONTINUOUS_EXTENDS_TO_CLOSURE = prove + (`!f:real^M->real^N s. + f uniformly_continuous_on s + ==> ?g. g uniformly_continuous_on closure s /\ (!x. x IN s ==> g x = f x) /\ + !h. h continuous_on closure s /\ (!x. x IN s ==> h x = f x) + ==> !x. x IN closure s ==> h x = g x`, + REPEAT STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o MATCH_MP CAUCHY_CONTINUOUS_EXTENDS_TO_CLOSURE o + MATCH_MP UNIFORMLY_CONTINUOUS_IMP_CAUCHY_CONTINUOUS) THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `g:real^M->real^N` THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN CONJ_TAC THENL + [ASM_MESON_TAC[UNIFORMLY_CONTINUOUS_ON_CLOSURE; UNIFORMLY_CONTINUOUS_ON_EQ]; + ASM_MESON_TAC[CONTINUOUS_AGREE_ON_CLOSURE]]);; + +let CAUCHY_CONTINUOUS_IMP_CONTINUOUS = prove + (`!f:real^M->real^N s. + (!x. cauchy x /\ (!n. (x n) IN s) ==> cauchy(f o x)) + ==> f continuous_on s`, + REPEAT STRIP_TAC THEN + FIRST_ASSUM(CHOOSE_TAC o MATCH_MP CAUCHY_CONTINUOUS_EXTENDS_TO_CLOSURE) THEN + ASM_MESON_TAC[CONTINUOUS_ON_SUBSET; CLOSURE_SUBSET; CONTINUOUS_ON_EQ]);; + +(* ------------------------------------------------------------------------- *) +(* Linear functions are (uniformly) continuous on any set. *) +(* ------------------------------------------------------------------------- *) + +let LINEAR_LIM_0 = prove + (`!f. linear f ==> (f --> vec 0) (at (vec 0))`, + REPEAT STRIP_TAC THEN REWRITE_TAC[LIM_AT] THEN + FIRST_X_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 EXISTS_TAC `e / B` THEN + ASM_SIMP_TAC[REAL_LT_DIV] THEN REWRITE_TAC[dist; VECTOR_SUB_RZERO] THEN + ASM_MESON_TAC[REAL_MUL_SYM; REAL_LET_TRANS; REAL_LT_RDIV_EQ]);; + +let LINEAR_CONTINUOUS_AT = prove + (`!f:real^M->real^N a. linear f ==> f continuous (at a)`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPEC `\x. (f:real^M->real^N) (a + x) - f(a)` LINEAR_LIM_0) THEN + ANTS_TAC THENL + [POP_ASSUM MP_TAC THEN SIMP_TAC[linear] THEN + REPEAT STRIP_TAC THEN VECTOR_ARITH_TAC; + ALL_TAC] THEN + REWRITE_TAC[GSYM LIM_NULL; CONTINUOUS_AT] THEN + GEN_REWRITE_TAC RAND_CONV [LIM_AT_ZERO] THEN SIMP_TAC[]);; + +let LINEAR_CONTINUOUS_WITHIN = prove + (`!f:real^M->real^N s x. linear f ==> f continuous (at x within s)`, + SIMP_TAC[CONTINUOUS_AT_WITHIN; LINEAR_CONTINUOUS_AT]);; + +let LINEAR_CONTINUOUS_ON = prove + (`!f:real^M->real^N s. linear f ==> f continuous_on s`, + MESON_TAC[LINEAR_CONTINUOUS_AT; CONTINUOUS_AT_IMP_CONTINUOUS_ON]);; + +let LINEAR_CONTINUOUS_COMPOSE = prove + (`!net f:A->real^N g:real^N->real^P. + f continuous net /\ linear g ==> (\x. g(f x)) continuous net`, + REWRITE_TAC[continuous; LIM_LINEAR]);; + +let LINEAR_CONTINUOUS_ON_COMPOSE = prove + (`!f:real^M->real^N g:real^N->real^P s. + f continuous_on s /\ linear g ==> (\x. g(f x)) continuous_on s`, + SIMP_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN; + LINEAR_CONTINUOUS_COMPOSE]);; + +let CONTINUOUS_LIFT_COMPONENT_COMPOSE = prove + (`!net f:A->real^N i. f continuous net ==> (\x. lift(f x$i)) continuous net`, + REPEAT GEN_TAC THEN + SUBGOAL_THEN `linear(\x:real^N. lift (x$i))` MP_TAC THENL + [REWRITE_TAC[LINEAR_LIFT_COMPONENT]; REWRITE_TAC[GSYM IMP_CONJ_ALT]] THEN + REWRITE_TAC[LINEAR_CONTINUOUS_COMPOSE]);; + +let CONTINUOUS_ON_LIFT_COMPONENT_COMPOSE = prove + (`!f:real^M->real^N s. + f continuous_on s + ==> (\x. lift (f x$i)) continuous_on s`, + SIMP_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN; + CONTINUOUS_LIFT_COMPONENT_COMPOSE]);; + +(* ------------------------------------------------------------------------- *) +(* Also bilinear functions, in composition form. *) +(* ------------------------------------------------------------------------- *) + +let BILINEAR_CONTINUOUS_COMPOSE = prove + (`!net f:A->real^M g:A->real^N h:real^M->real^N->real^P. + f continuous net /\ g continuous net /\ bilinear h + ==> (\x. h (f x) (g x)) continuous net`, + REWRITE_TAC[continuous; LIM_BILINEAR]);; + +let BILINEAR_CONTINUOUS_ON_COMPOSE = prove + (`!f g h s. f continuous_on s /\ g continuous_on s /\ bilinear h + ==> (\x. h (f x) (g x)) continuous_on s`, + SIMP_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN; + BILINEAR_CONTINUOUS_COMPOSE]);; + +let BILINEAR_DOT = prove + (`bilinear (\x y:real^N. lift(x dot y))`, + REWRITE_TAC[bilinear; linear; DOT_LADD; DOT_RADD; DOT_LMUL; DOT_RMUL] THEN + REWRITE_TAC[LIFT_ADD; LIFT_CMUL]);; + +let CONTINUOUS_LIFT_DOT2 = prove + (`!net f g:A->real^N. + f continuous net /\ g continuous net + ==> (\x. lift(f x dot g x)) continuous net`, + REPEAT GEN_TAC THEN DISCH_THEN(MP_TAC o MATCH_MP (MATCH_MP (REWRITE_RULE + [TAUT `p /\ q /\ r ==> s <=> r ==> p /\ q ==> s`] + BILINEAR_CONTINUOUS_COMPOSE) BILINEAR_DOT)) THEN REWRITE_TAC[]);; + +let CONTINUOUS_ON_LIFT_DOT2 = prove + (`!f:real^M->real^N g s. + f continuous_on s /\ g continuous_on s + ==> (\x. lift(f x dot g x)) continuous_on s`, + REPEAT GEN_TAC THEN DISCH_THEN(MP_TAC o MATCH_MP (MATCH_MP (REWRITE_RULE + [TAUT `p /\ q /\ r ==> s <=> r ==> p /\ q ==> s`] + BILINEAR_CONTINUOUS_ON_COMPOSE) BILINEAR_DOT)) THEN REWRITE_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* Occasionally useful invariance properties. *) +(* ------------------------------------------------------------------------- *) + +let CONTINUOUS_AT_COMPOSE_EQ = prove + (`!f:real^M->real^N g:real^M->real^M h:real^M->real^M. + g continuous at x /\ h continuous at (g x) /\ + (!y. g(h y) = y) /\ h(g x) = x + ==> (f continuous at (g x) <=> (\x. f(g x)) continuous at x)`, + REPEAT STRIP_TAC THEN EQ_TAC THEN + ASM_SIMP_TAC[REWRITE_RULE[o_DEF] CONTINUOUS_AT_COMPOSE] THEN + DISCH_TAC THEN + SUBGOAL_THEN + `((f:real^M->real^N) o (g:real^M->real^M) o (h:real^M->real^M)) + continuous at (g(x:real^M))` + MP_TAC THENL + [REWRITE_TAC[o_ASSOC] THEN MATCH_MP_TAC CONTINUOUS_AT_COMPOSE THEN + ASM_REWRITE_TAC[o_DEF]; + + ASM_REWRITE_TAC[o_DEF; ETA_AX]]);; + +let CONTINUOUS_AT_TRANSLATION = prove + (`!a z f:real^M->real^N. + f continuous at (a + z) <=> (\x. f(a + x)) continuous at z`, + REPEAT GEN_TAC THEN MATCH_MP_TAC CONTINUOUS_AT_COMPOSE_EQ THEN + EXISTS_TAC `\x:real^M. x - a` THEN + SIMP_TAC[CONTINUOUS_ADD; CONTINUOUS_SUB; + CONTINUOUS_AT_ID; CONTINUOUS_CONST] THEN + VECTOR_ARITH_TAC);; + +add_translation_invariants [CONTINUOUS_AT_TRANSLATION];; + +let CONTINUOUS_AT_LINEAR_IMAGE = prove + (`!h:real^M->real^M z f:real^M->real^N. + linear h /\ (!x. norm(h x) = norm x) + ==> (f continuous at (h z) <=> (\x. f(h x)) continuous at z)`, + REPEAT GEN_TAC THEN DISCH_TAC THEN + FIRST_ASSUM(ASSUME_TAC o GEN_REWRITE_RULE I + [GSYM ORTHOGONAL_TRANSFORMATION]) THEN + FIRST_ASSUM(X_CHOOSE_TAC `g:real^M->real^M` o MATCH_MP + ORTHOGONAL_TRANSFORMATION_INVERSE) THEN + MATCH_MP_TAC CONTINUOUS_AT_COMPOSE_EQ THEN + EXISTS_TAC `g:real^M->real^M` THEN + RULE_ASSUM_TAC(REWRITE_RULE[ORTHOGONAL_TRANSFORMATION]) THEN + ASM_SIMP_TAC[LINEAR_CONTINUOUS_AT]);; + +add_linear_invariants [CONTINUOUS_AT_LINEAR_IMAGE];; + +(* ------------------------------------------------------------------------- *) +(* Interior of an injective image. *) +(* ------------------------------------------------------------------------- *) + +let INTERIOR_IMAGE_SUBSET = prove + (`!f:real^M->real^N s. + (!x. f continuous at x) /\ (!x y. f x = f y ==> x = y) + ==> interior(IMAGE f s) SUBSET IMAGE f (interior s)`, + REPEAT STRIP_TAC THEN REWRITE_TAC[SUBSET] THEN + REWRITE_TAC[interior; IN_ELIM_THM] THEN + X_GEN_TAC `y:real^N` THEN + DISCH_THEN(X_CHOOSE_THEN `t:real^N->bool` STRIP_ASSUME_TAC) THEN + REWRITE_TAC[IN_IMAGE; IN_ELIM_THM] THEN + SUBGOAL_THEN `y IN IMAGE (f:real^M->real^N) s` MP_TAC THENL + [ASM SET_TAC[]; ALL_TAC] THEN + REWRITE_TAC[IN_IMAGE] THEN + MATCH_MP_TAC MONO_EXISTS THEN REPEAT STRIP_TAC THEN + ASM_REWRITE_TAC[IN_ELIM_THM] THEN FIRST_X_ASSUM SUBST_ALL_TAC THEN + EXISTS_TAC `{x | (f:real^M->real^N)(x) IN t}` THEN + REWRITE_TAC[SUBSET; IN_ELIM_THM] THEN CONJ_TAC THENL + [MATCH_MP_TAC CONTINUOUS_OPEN_PREIMAGE_UNIV THEN ASM_MESON_TAC[]; + ASM SET_TAC[]]);; + +(* ------------------------------------------------------------------------- *) +(* Making a continuous function avoid some value in a neighbourhood. *) +(* ------------------------------------------------------------------------- *) + +let CONTINUOUS_WITHIN_AVOID = prove + (`!f:real^M->real^N x s a. + f continuous (at x within s) /\ x IN s /\ ~(f x = a) + ==> ?e. &0 < e /\ !y. y IN s /\ dist(x,y) < e ==> ~(f y = a)`, + REPEAT STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [continuous_within]) THEN + DISCH_THEN(MP_TAC o SPEC `norm((f:real^M->real^N) x - a)`) THEN + ASM_REWRITE_TAC[NORM_POS_LT; VECTOR_SUB_EQ] THEN + MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC THEN MATCH_MP_TAC MONO_AND THEN + REWRITE_TAC[] THEN MATCH_MP_TAC MONO_FORALL THEN + GEN_TAC THEN MATCH_MP_TAC MONO_IMP THEN SIMP_TAC[] THEN NORM_ARITH_TAC);; + +let CONTINUOUS_AT_AVOID = prove + (`!f:real^M->real^N x a. + f continuous (at x) /\ ~(f x = a) + ==> ?e. &0 < e /\ !y. dist(x,y) < e ==> ~(f y = a)`, + MP_TAC CONTINUOUS_WITHIN_AVOID THEN + REPLICATE_TAC 2 (MATCH_MP_TAC MONO_FORALL THEN GEN_TAC) THEN + DISCH_THEN(MP_TAC o SPEC `(:real^M)`) THEN + MATCH_MP_TAC MONO_FORALL THEN GEN_TAC THEN + REWRITE_TAC[WITHIN_UNIV; IN_UNIV]);; + +let CONTINUOUS_ON_AVOID = prove + (`!f:real^M->real^N x s a. + f continuous_on s /\ x IN s /\ ~(f x = a) + ==> ?e. &0 < e /\ !y. y IN s /\ dist(x,y) < e ==> ~(f y = a)`, + REWRITE_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC CONTINUOUS_WITHIN_AVOID THEN + ASM_SIMP_TAC[]);; + +let CONTINUOUS_ON_OPEN_AVOID = prove + (`!f:real^M->real^N x s a. + f continuous_on s /\ open s /\ x IN s /\ ~(f x = a) + ==> ?e. &0 < e /\ !y. dist(x,y) < e ==> ~(f y = a)`, + REPEAT GEN_TAC THEN ASM_CASES_TAC `open(s:real^M->bool)` THEN + ASM_SIMP_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_AT] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC CONTINUOUS_AT_AVOID THEN + ASM_SIMP_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* Proving a function is constant by proving open-ness of level set. *) +(* ------------------------------------------------------------------------- *) + +let CONTINUOUS_LEVELSET_OPEN_IN_CASES = prove + (`!f:real^M->real^N s a. + connected s /\ + f continuous_on s /\ + open_in (subtopology euclidean s) {x | x IN s /\ f x = a} + ==> (!x. x IN s ==> ~(f x = a)) \/ (!x. x IN s ==> f x = a)`, + REWRITE_TAC[SET_RULE `(!x. x IN s ==> ~(f x = a)) <=> + {x | x IN s /\ f x = a} = {}`; + SET_RULE `(!x. x IN s ==> f x = a) <=> + {x | x IN s /\ f x = a} = s`] THEN + REWRITE_TAC[CONNECTED_CLOPEN] THEN REPEAT STRIP_TAC THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_SIMP_TAC[CONTINUOUS_CLOSED_IN_PREIMAGE_CONSTANT]);; + +let CONTINUOUS_LEVELSET_OPEN_IN = prove + (`!f:real^M->real^N s a. + connected s /\ + f continuous_on s /\ + open_in (subtopology euclidean s) {x | x IN s /\ f x = a} /\ + (?x. x IN s /\ f x = a) + ==> (!x. x IN s ==> f x = a)`, + MESON_TAC[CONTINUOUS_LEVELSET_OPEN_IN_CASES]);; + +let CONTINUOUS_LEVELSET_OPEN = prove + (`!f:real^M->real^N s a. + connected s /\ + f continuous_on s /\ + open {x | x IN s /\ f x = a} /\ + (?x. x IN s /\ f x = a) + ==> (!x. x IN s ==> f x = a)`, + REPEAT GEN_TAC THEN DISCH_THEN(REPEAT_TCL CONJUNCTS_THEN ASSUME_TAC) THEN + MATCH_MP_TAC CONTINUOUS_LEVELSET_OPEN_IN THEN + ASM_REWRITE_TAC[OPEN_IN_OPEN] THEN + EXISTS_TAC `{x | x IN s /\ (f:real^M->real^N) x = a}` THEN + ASM_REWRITE_TAC[] THEN SET_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* Some arithmetical combinations (more to prove). *) +(* ------------------------------------------------------------------------- *) + +let OPEN_SCALING = prove + (`!s:real^N->bool c. ~(c = &0) /\ open s ==> open(IMAGE (\x. c % x) s)`, + REPEAT GEN_TAC THEN REWRITE_TAC[open_def; FORALL_IN_IMAGE] THEN + STRIP_TAC THEN X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `x:real^N`) THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `e:real` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `e * abs(c)` THEN ASM_SIMP_TAC[REAL_LT_MUL; GSYM REAL_ABS_NZ] THEN + X_GEN_TAC `y:real^N` THEN DISCH_TAC THEN REWRITE_TAC[IN_IMAGE] THEN + EXISTS_TAC `inv(c) % y:real^N` THEN + ASM_SIMP_TAC[VECTOR_MUL_ASSOC; REAL_MUL_RINV; VECTOR_MUL_LID] THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN + SUBGOAL_THEN `x = inv(c) % c % x:real^N` SUBST1_TAC THENL + [ASM_SIMP_TAC[VECTOR_MUL_ASSOC; REAL_MUL_LINV; VECTOR_MUL_LID]; + REWRITE_TAC[dist; GSYM VECTOR_SUB_LDISTRIB; NORM_MUL] THEN + ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN REWRITE_TAC[REAL_ABS_INV] THEN + ASM_SIMP_TAC[GSYM real_div; REAL_LT_LDIV_EQ; GSYM REAL_ABS_NZ] THEN + ASM_REWRITE_TAC[GSYM dist]]);; + +let OPEN_NEGATIONS = prove + (`!s:real^N->bool. open s ==> open (IMAGE (--) s)`, + SUBGOAL_THEN `(--) = \x:real^N. --(&1) % x` + (fun th -> SIMP_TAC[th; OPEN_SCALING; REAL_ARITH `~(--(&1) = &0)`]) THEN + REWRITE_TAC[FUN_EQ_THM] THEN VECTOR_ARITH_TAC);; + +let OPEN_TRANSLATION = prove + (`!s a:real^N. open s ==> open(IMAGE (\x. a + x) s)`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`\x:real^N. x - a`; `s:real^N->bool`] + CONTINUOUS_OPEN_PREIMAGE_UNIV) THEN + ASM_SIMP_TAC[CONTINUOUS_SUB; CONTINUOUS_AT_ID; CONTINUOUS_CONST] THEN + MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN + REWRITE_TAC[EXTENSION; IN_ELIM_THM; IN_IMAGE; IN_UNIV] THEN + ASM_MESON_TAC[VECTOR_ARITH `(a + x) - a = x:real^N`; + VECTOR_ARITH `a + (x - a) = x:real^N`]);; + +let OPEN_TRANSLATION_EQ = prove + (`!a s. open (IMAGE (\x:real^N. a + x) s) <=> open s`, + REWRITE_TAC[open_def] THEN GEOM_TRANSLATE_TAC[]);; + +add_translation_invariants [OPEN_TRANSLATION_EQ];; + +let OPEN_AFFINITY = prove + (`!s a:real^N c. + open s /\ ~(c = &0) ==> open (IMAGE (\x. a + c % x) s)`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN `(\x:real^N. a + c % x) = (\x. a + x) o (\x. c % x)` + SUBST1_TAC THENL [REWRITE_TAC[o_DEF]; ALL_TAC] THEN + ASM_SIMP_TAC[IMAGE_o; OPEN_TRANSLATION; OPEN_SCALING]);; + +let INTERIOR_TRANSLATION = prove + (`!a:real^N s. + interior (IMAGE (\x. a + x) s) = IMAGE (\x. a + x) (interior s)`, + REWRITE_TAC[interior] THEN GEOM_TRANSLATE_TAC[]);; + +add_translation_invariants [INTERIOR_TRANSLATION];; + +let OPEN_SUMS = prove + (`!s t:real^N->bool. + open s \/ open t ==> open {x + y | x IN s /\ y IN t}`, + REPEAT GEN_TAC THEN REWRITE_TAC[open_def] THEN STRIP_TAC THEN + REWRITE_TAC[FORALL_IN_GSPEC] THEN + MAP_EVERY X_GEN_TAC [`x:real^N`; `y:real^N`] THEN STRIP_TAC THENL + [FIRST_X_ASSUM(MP_TAC o SPEC `x:real^N`); + FIRST_X_ASSUM(MP_TAC o SPEC `y:real^N`)] THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC MONO_EXISTS THEN + X_GEN_TAC `e:real` THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + X_GEN_TAC `z:real^N` THEN DISCH_TAC THEN REWRITE_TAC[IN_ELIM_THM] THEN + ASM_MESON_TAC[VECTOR_ADD_SYM; VECTOR_ARITH `(z - y) + y:real^N = z`; + NORM_ARITH `dist(z:real^N,x + y) < e ==> dist(z - y,x) < e`]);; + +(* ------------------------------------------------------------------------- *) +(* Preservation of compactness and connectedness under continuous function. *) +(* ------------------------------------------------------------------------- *) + +let COMPACT_CONTINUOUS_IMAGE = prove + (`!f:real^M->real^N s. + f continuous_on s /\ compact s ==> compact(IMAGE f s)`, + REPEAT GEN_TAC THEN REWRITE_TAC[continuous_on; compact] THEN + STRIP_TAC THEN X_GEN_TAC `y:num->real^N` THEN + REWRITE_TAC[IN_IMAGE; SKOLEM_THM; FORALL_AND_THM] THEN + DISCH_THEN(X_CHOOSE_THEN `x:num->real^M` STRIP_ASSUME_TAC) THEN + FIRST_X_ASSUM(MP_TAC o SPEC `x:num->real^M`) THEN ASM_REWRITE_TAC[] THEN + ONCE_REWRITE_TAC[SWAP_EXISTS_THM] THEN MATCH_MP_TAC MONO_EXISTS THEN + X_GEN_TAC `r:num->num` THEN + DISCH_THEN(X_CHOOSE_THEN `l:real^M` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `(f:real^M->real^N) l` THEN ASM_REWRITE_TAC[] THEN + CONJ_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN + REWRITE_TAC[LIM_SEQUENTIALLY] THEN + FIRST_X_ASSUM(MP_TAC o SPEC `l:real^M`) THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `e:real` THEN + DISCH_THEN(fun th -> DISCH_TAC THEN MP_TAC th) THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC) THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [LIM_SEQUENTIALLY]) THEN + DISCH_THEN(MP_TAC o SPEC `d:real`) THEN ASM_REWRITE_TAC[o_THM] THEN + ASM_MESON_TAC[]);; + +let COMPACT_CONTINUOUS_IMAGE_EQ = prove + (`!f:real^M->real^N s. + (!x y. x IN s /\ y IN s /\ f x = f y ==> x = y) + ==> (f continuous_on s <=> + !t. compact t /\ t SUBSET s ==> compact(IMAGE f t))`, + REPEAT STRIP_TAC THEN EQ_TAC THENL + [MESON_TAC[COMPACT_CONTINUOUS_IMAGE; CONTINUOUS_ON_SUBSET]; DISCH_TAC] THEN + FIRST_X_ASSUM(X_CHOOSE_TAC `g:real^N->real^M` o + GEN_REWRITE_RULE I [INJECTIVE_ON_LEFT_INVERSE]) THEN + REWRITE_TAC[CONTINUOUS_ON_CLOSED] THEN + X_GEN_TAC `u:real^N->bool` THEN DISCH_TAC THEN + MP_TAC(ISPECL [`g:real^N->real^M`; `IMAGE (f:real^M->real^N) s`; + `s:real^M->bool`] PROPER_MAP) THEN + ANTS_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + MATCH_MP_TAC(TAUT `(q ==> s) /\ p ==> (p <=> q /\ r) ==> s`) THEN + REPEAT STRIP_TAC THENL + [SUBGOAL_THEN + `{x | x IN s /\ (f:real^M->real^N) x IN u} = IMAGE g u` + (fun th -> ASM_MESON_TAC[th]); + SUBGOAL_THEN + `{x | x IN IMAGE f s /\ (g:real^N->real^M) x IN k} = IMAGE f k` + (fun th -> ASM_SIMP_TAC[th])] THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP CLOSED_IN_IMP_SUBSET) THEN ASM SET_TAC[]);; + +let COMPACT_LINEAR_IMAGE = prove + (`!f:real^M->real^N s. compact s /\ linear f ==> compact(IMAGE f s)`, + SIMP_TAC[LINEAR_CONTINUOUS_ON; COMPACT_CONTINUOUS_IMAGE]);; + +let COMPACT_LINEAR_IMAGE_EQ = prove + (`!f s. linear f /\ (!x y. f x = f y ==> x = y) + ==> (compact (IMAGE f s) <=> compact s)`, + MATCH_ACCEPT_TAC(LINEAR_INVARIANT_RULE COMPACT_LINEAR_IMAGE));; + +add_linear_invariants [COMPACT_LINEAR_IMAGE_EQ];; + +let CONNECTED_CONTINUOUS_IMAGE = prove + (`!f:real^M->real^N s. + f continuous_on s /\ connected s ==> connected(IMAGE f s)`, + REPEAT GEN_TAC THEN REWRITE_TAC[CONTINUOUS_ON_OPEN] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN + REWRITE_TAC[CONNECTED_CLOPEN; NOT_FORALL_THM; NOT_IMP; DE_MORGAN_THM] THEN + REWRITE_TAC[closed_in; TOPSPACE_EUCLIDEAN_SUBTOPOLOGY] THEN + DISCH_THEN(X_CHOOSE_THEN `t:real^N->bool` STRIP_ASSUME_TAC) THEN + FIRST_X_ASSUM(fun th -> MP_TAC(SPEC `t:real^N->bool` th) THEN + MP_TAC(SPEC `IMAGE (f:real^M->real^N) s DIFF t` th)) THEN + ASM_REWRITE_TAC[] THEN + SUBGOAL_THEN `{x | x IN s /\ (f:real^M->real^N) x IN IMAGE f s DIFF t} = + s DIFF {x | x IN s /\ f x IN t}` + SUBST1_TAC THENL + [UNDISCH_TAC `t SUBSET IMAGE (f:real^M->real^N) s` THEN + REWRITE_TAC[EXTENSION; IN_IMAGE; IN_DIFF; IN_ELIM_THM; SUBSET] THEN + MESON_TAC[]; + REPEAT STRIP_TAC THEN + EXISTS_TAC `{x | x IN s /\ (f:real^M->real^N) x IN t}` THEN + ASM_REWRITE_TAC[] THEN POP_ASSUM_LIST(MP_TAC o end_itlist CONJ) THEN + REWRITE_TAC[IN_IMAGE; SUBSET; IN_ELIM_THM; NOT_IN_EMPTY; EXTENSION] THEN + MESON_TAC[]]);; + +let CONNECTED_TRANSLATION = prove + (`!a s. connected s ==> connected (IMAGE (\x:real^N. a + x) s)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC CONNECTED_CONTINUOUS_IMAGE THEN + ASM_SIMP_TAC[CONTINUOUS_ON_ADD; CONTINUOUS_ON_ID; CONTINUOUS_ON_CONST]);; + +let CONNECTED_TRANSLATION_EQ = prove + (`!a s. connected (IMAGE (\x:real^N. a + x) s) <=> connected s`, + REWRITE_TAC[connected] THEN GEOM_TRANSLATE_TAC[]);; + +add_translation_invariants [CONNECTED_TRANSLATION_EQ];; + +let CONNECTED_LINEAR_IMAGE = prove + (`!f:real^M->real^N s. connected s /\ linear f ==> connected(IMAGE f s)`, + SIMP_TAC[LINEAR_CONTINUOUS_ON; CONNECTED_CONTINUOUS_IMAGE]);; + +let CONNECTED_LINEAR_IMAGE_EQ = prove + (`!f s. linear f /\ (!x y. f x = f y ==> x = y) + ==> (connected (IMAGE f s) <=> connected s)`, + MATCH_ACCEPT_TAC(LINEAR_INVARIANT_RULE CONNECTED_LINEAR_IMAGE));; + +add_linear_invariants [CONNECTED_LINEAR_IMAGE_EQ];; + +let BOUNDED_UNIFORMLY_CONTINUOUS_IMAGE = prove + (`!f:real^M->real^N s. + f uniformly_continuous_on s /\ bounded s ==> bounded(IMAGE f s)`, + REPEAT STRIP_TAC THEN FIRST_ASSUM + (MP_TAC o MATCH_MP UNIFORMLY_CONTINUOUS_EXTENDS_TO_CLOSURE) THEN + DISCH_THEN(X_CHOOSE_THEN `g:real^M->real^N` STRIP_ASSUME_TAC) THEN + MATCH_MP_TAC BOUNDED_SUBSET THEN + EXISTS_TAC `IMAGE (g:real^M->real^N) (closure s)` THEN CONJ_TAC THENL + [ASM_MESON_TAC[COMPACT_CLOSURE; UNIFORMLY_CONTINUOUS_IMP_CONTINUOUS; + COMPACT_IMP_BOUNDED; COMPACT_CONTINUOUS_IMAGE]; + MP_TAC(ISPEC `s:real^M->bool` CLOSURE_SUBSET) THEN ASM SET_TAC[]]);; + +(* ------------------------------------------------------------------------- *) +(* Connected components, considered as a "connectedness" relation or a set. *) +(* ------------------------------------------------------------------------- *) + +let connected_component = new_definition + `connected_component s x y <=> + ?t. connected t /\ t SUBSET s /\ x IN t /\ y IN t`;; + +let CONNECTED_COMPONENT_IN = prove + (`!s x y. connected_component s x y ==> x IN s /\ y IN s`, + REWRITE_TAC[connected_component] THEN SET_TAC[]);; + +let CONNECTED_COMPONENT_REFL = prove + (`!s x:real^N. x IN s ==> connected_component s x x`, + REWRITE_TAC[connected_component] THEN REPEAT STRIP_TAC THEN + EXISTS_TAC `{x:real^N}` THEN REWRITE_TAC[CONNECTED_SING] THEN + ASM SET_TAC[]);; + +let CONNECTED_COMPONENT_REFL_EQ = prove + (`!s x:real^N. connected_component s x x <=> x IN s`, + REPEAT GEN_TAC THEN EQ_TAC THEN REWRITE_TAC[CONNECTED_COMPONENT_REFL] THEN + REWRITE_TAC[connected_component] THEN SET_TAC[]);; + +let CONNECTED_COMPONENT_SYM = prove + (`!s x y:real^N. connected_component s x y ==> connected_component s y x`, + REWRITE_TAC[connected_component] THEN MESON_TAC[]);; + +let CONNECTED_COMPONENT_TRANS = prove + (`!s x y:real^N. + connected_component s x y /\ connected_component s y z + ==> connected_component s x z`, + REPEAT GEN_TAC THEN REWRITE_TAC[connected_component] THEN + DISCH_THEN(CONJUNCTS_THEN2 (X_CHOOSE_TAC `t:real^N->bool`) + (X_CHOOSE_TAC `u:real^N->bool`)) THEN + EXISTS_TAC `t UNION u:real^N->bool` THEN + ASM_REWRITE_TAC[IN_UNION; UNION_SUBSET] THEN + MATCH_MP_TAC CONNECTED_UNION THEN ASM SET_TAC[]);; + +let CONNECTED_COMPONENT_OF_SUBSET = prove + (`!s t x. s SUBSET t /\ connected_component s x y + ==> connected_component t x y`, + REWRITE_TAC[connected_component] THEN SET_TAC[]);; + +let CONNECTED_COMPONENT_SET = prove + (`!s x. connected_component s x = + { y | ?t. connected t /\ t SUBSET s /\ x IN t /\ y IN t}`, + REWRITE_TAC[IN_ELIM_THM; EXTENSION] THEN + REWRITE_TAC[IN; connected_component] THEN MESON_TAC[]);; + +let CONNECTED_COMPONENT_UNIONS = prove + (`!s x. connected_component s x = + UNIONS {t | connected t /\ x IN t /\ t SUBSET s}`, + REWRITE_TAC[CONNECTED_COMPONENT_SET] THEN SET_TAC[]);; + +let CONNECTED_COMPONENT_SUBSET = prove + (`!s x. (connected_component s x) SUBSET s`, + REWRITE_TAC[CONNECTED_COMPONENT_SET] THEN SET_TAC[]);; + +let CONNECTED_CONNECTED_COMPONENT_SET = prove + (`!s. connected s <=> !x:real^N. x IN s ==> connected_component s x = s`, + GEN_TAC THEN REWRITE_TAC[CONNECTED_COMPONENT_UNIONS] THEN EQ_TAC THENL + [SET_TAC[]; ALL_TAC] THEN + ASM_CASES_TAC `s:real^N->bool = {}` THEN + ASM_REWRITE_TAC[CONNECTED_EMPTY] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN + DISCH_THEN(X_CHOOSE_THEN `a:real^N` STRIP_ASSUME_TAC) THEN + DISCH_THEN(MP_TAC o SPEC `a:real^N`) THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(SUBST1_TAC o SYM) THEN MATCH_MP_TAC CONNECTED_UNIONS THEN + ASM SET_TAC[]);; + +let CONNECTED_COMPONENT_EQ_SELF = prove + (`!s x. connected s /\ x IN s ==> connected_component s x = s`, + MESON_TAC[CONNECTED_CONNECTED_COMPONENT_SET]);; + +let CONNECTED_IFF_CONNECTED_COMPONENT = prove + (`!s. connected s <=> + !x y. x IN s /\ y IN s ==> connected_component s x y`, + REWRITE_TAC[CONNECTED_CONNECTED_COMPONENT_SET] THEN + REWRITE_TAC[EXTENSION] THEN MESON_TAC[IN; CONNECTED_COMPONENT_IN]);; + +let CONNECTED_COMPONENT_MAXIMAL = prove + (`!s t x:real^N. + x IN t /\ connected t /\ t SUBSET s + ==> t SUBSET (connected_component s x)`, + REWRITE_TAC[CONNECTED_COMPONENT_SET] THEN SET_TAC[]);; + +let CONNECTED_COMPONENT_MONO = prove + (`!s t x. s SUBSET t + ==> (connected_component s x) SUBSET (connected_component t x)`, + REWRITE_TAC[CONNECTED_COMPONENT_SET] THEN SET_TAC[]);; + +let CONNECTED_CONNECTED_COMPONENT = prove + (`!s x. connected(connected_component s x)`, + REWRITE_TAC[CONNECTED_COMPONENT_UNIONS] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC CONNECTED_UNIONS THEN SET_TAC[]);; + +let CONNECTED_COMPONENT_EQ_EMPTY = prove + (`!s x:real^N. connected_component s x = {} <=> ~(x IN s)`, + REPEAT GEN_TAC THEN EQ_TAC THENL + [REWRITE_TAC[EXTENSION; NOT_IN_EMPTY] THEN + DISCH_THEN(MP_TAC o SPEC `x:real^N`) THEN + REWRITE_TAC[IN; CONNECTED_COMPONENT_REFL_EQ]; + REWRITE_TAC[CONNECTED_COMPONENT_SET] THEN SET_TAC[]]);; + +let CONNECTED_COMPONENT_EMPTY = prove + (`!x. connected_component {} x = {}`, + REWRITE_TAC[CONNECTED_COMPONENT_EQ_EMPTY; NOT_IN_EMPTY]);; + +let CONNECTED_COMPONENT_EQ = prove + (`!s x y. y IN connected_component s x + ==> (connected_component s y = connected_component s x)`, + REWRITE_TAC[EXTENSION; IN] THEN + MESON_TAC[CONNECTED_COMPONENT_SYM; CONNECTED_COMPONENT_TRANS]);; + +let CLOSED_CONNECTED_COMPONENT = prove + (`!s x:real^N. closed s ==> closed(connected_component s x)`, + REPEAT STRIP_TAC THEN + ASM_CASES_TAC `(x:real^N) IN s` THENL + [ALL_TAC; ASM_MESON_TAC[CONNECTED_COMPONENT_EQ_EMPTY; CLOSED_EMPTY]] THEN + REWRITE_TAC[GSYM CLOSURE_EQ] THEN + MATCH_MP_TAC SUBSET_ANTISYM THEN REWRITE_TAC[CLOSURE_SUBSET] THEN + MATCH_MP_TAC CONNECTED_COMPONENT_MAXIMAL THEN + SIMP_TAC[CONNECTED_CLOSURE; CONNECTED_CONNECTED_COMPONENT] THEN + CONJ_TAC THENL + [MATCH_MP_TAC(REWRITE_RULE[SUBSET] CLOSURE_SUBSET) THEN + ASM_REWRITE_TAC[IN; CONNECTED_COMPONENT_REFL_EQ]; + MATCH_MP_TAC CLOSURE_MINIMAL THEN + ASM_REWRITE_TAC[CONNECTED_COMPONENT_SUBSET]]);; + +let CONNECTED_COMPONENT_DISJOINT = prove + (`!s a b. DISJOINT (connected_component s a) (connected_component s b) <=> + ~(a IN connected_component s b)`, + REWRITE_TAC[DISJOINT; EXTENSION; IN_INTER; NOT_IN_EMPTY] THEN + REWRITE_TAC[IN] THEN + MESON_TAC[CONNECTED_COMPONENT_SYM; CONNECTED_COMPONENT_TRANS]);; + +let CONNECTED_COMPONENT_NONOVERLAP = prove + (`!s a b:real^N. + (connected_component s a) INTER (connected_component s b) = {} <=> + ~(a IN s) \/ ~(b IN s) \/ + ~(connected_component s a = connected_component s b)`, + REPEAT GEN_TAC THEN + ASM_CASES_TAC `(a:real^N) IN s` THEN ASM_REWRITE_TAC[] THEN + RULE_ASSUM_TAC(REWRITE_RULE[GSYM CONNECTED_COMPONENT_EQ_EMPTY]) THEN + ASM_REWRITE_TAC[INTER_EMPTY] THEN + ASM_CASES_TAC `(b:real^N) IN s` THEN ASM_REWRITE_TAC[] THEN + RULE_ASSUM_TAC(REWRITE_RULE[GSYM CONNECTED_COMPONENT_EQ_EMPTY]) THEN + ASM_REWRITE_TAC[INTER_EMPTY] THEN ASM_CASES_TAC + `connected_component s (a:real^N) = connected_component s b` THEN + ASM_REWRITE_TAC[INTER_IDEMPOT; CONNECTED_COMPONENT_EQ_EMPTY] THEN + FIRST_X_ASSUM(MP_TAC o check(is_neg o concl)) THEN + ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN DISCH_TAC THEN + REWRITE_TAC[] THEN MATCH_MP_TAC CONNECTED_COMPONENT_EQ THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE RAND_CONV [GSYM DISJOINT]) THEN + REWRITE_TAC[CONNECTED_COMPONENT_DISJOINT]);; + +let CONNECTED_COMPONENT_OVERLAP = prove + (`!s a b:real^N. + ~((connected_component s a) INTER (connected_component s b) = {}) <=> + a IN s /\ b IN s /\ + connected_component s a = connected_component s b`, + REWRITE_TAC[CONNECTED_COMPONENT_NONOVERLAP; DE_MORGAN_THM]);; + +let CONNECTED_COMPONENT_SYM_EQ = prove + (`!s x y. connected_component s x y <=> connected_component s y x`, + MESON_TAC[CONNECTED_COMPONENT_SYM]);; + +let CONNECTED_COMPONENT_EQ_EQ = prove + (`!s x y:real^N. + connected_component s x = connected_component s y <=> + ~(x IN s) /\ ~(y IN s) \/ + x IN s /\ y IN s /\ connected_component s x y`, + REPEAT GEN_TAC THEN ASM_CASES_TAC `(y:real^N) IN s` THENL + [ASM_CASES_TAC `(x:real^N) IN s` THEN ASM_REWRITE_TAC[] THENL + [REWRITE_TAC[FUN_EQ_THM] THEN + ASM_MESON_TAC[CONNECTED_COMPONENT_TRANS; CONNECTED_COMPONENT_REFL; + CONNECTED_COMPONENT_SYM]; + ASM_MESON_TAC[CONNECTED_COMPONENT_EQ_EMPTY]]; + RULE_ASSUM_TAC(REWRITE_RULE[GSYM CONNECTED_COMPONENT_EQ_EMPTY]) THEN + ASM_REWRITE_TAC[CONNECTED_COMPONENT_EQ_EMPTY] THEN + ONCE_REWRITE_TAC[CONNECTED_COMPONENT_SYM_EQ] THEN + ASM_REWRITE_TAC[EMPTY] THEN ASM_MESON_TAC[CONNECTED_COMPONENT_EQ_EMPTY]]);; + +let CONNECTED_EQ_CONNECTED_COMPONENT_EQ = prove + (`!s. connected s <=> + !x y. x IN s /\ y IN s + ==> connected_component s x = connected_component s y`, + SIMP_TAC[CONNECTED_COMPONENT_EQ_EQ] THEN + REWRITE_TAC[CONNECTED_IFF_CONNECTED_COMPONENT]);; + +let CONNECTED_COMPONENT_IDEMP = prove + (`!s x:real^N. connected_component (connected_component s x) x = + connected_component s x`, + REWRITE_TAC[FUN_EQ_THM; connected_component] THEN + REPEAT GEN_TAC THEN AP_TERM_TAC THEN ABS_TAC THEN EQ_TAC THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + ASM_MESON_TAC[CONNECTED_COMPONENT_MAXIMAL; SUBSET_TRANS; + CONNECTED_COMPONENT_SUBSET]);; + +let CONNECTED_COMPONENT_UNIQUE = prove + (`!s c x:real^N. + x IN c /\ c SUBSET s /\ connected c /\ + (!c'. x IN c' /\ c' SUBSET s /\ connected c' + ==> c' SUBSET c) + ==> connected_component s x = c`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL + [FIRST_X_ASSUM MATCH_MP_TAC THEN + REWRITE_TAC[CONNECTED_COMPONENT_SUBSET; CONNECTED_CONNECTED_COMPONENT] THEN + REWRITE_TAC[IN] THEN ASM_REWRITE_TAC[CONNECTED_COMPONENT_REFL_EQ] THEN + ASM SET_TAC[]; + MATCH_MP_TAC CONNECTED_COMPONENT_MAXIMAL THEN ASM_REWRITE_TAC[]]);; + +let JOINABLE_CONNECTED_COMPONENT_EQ = prove + (`!s t x y:real^N. + connected t /\ t SUBSET s /\ + ~(connected_component s x INTER t = {}) /\ + ~(connected_component s y INTER t = {}) + ==> connected_component s x = connected_component s y`, + REPEAT GEN_TAC THEN + REPLICATE_TAC 2 (DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; IN_INTER] THEN DISCH_THEN(CONJUNCTS_THEN2 + (X_CHOOSE_THEN `w:real^N` STRIP_ASSUME_TAC) + (X_CHOOSE_THEN `z:real^N` STRIP_ASSUME_TAC)) THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC CONNECTED_COMPONENT_EQ THEN + REWRITE_TAC[IN] THEN + MATCH_MP_TAC CONNECTED_COMPONENT_TRANS THEN + EXISTS_TAC `z:real^N` THEN CONJ_TAC THENL [ASM_MESON_TAC[IN]; ALL_TAC] THEN + MATCH_MP_TAC CONNECTED_COMPONENT_TRANS THEN + EXISTS_TAC `w:real^N` THEN CONJ_TAC THENL + [REWRITE_TAC[connected_component] THEN + EXISTS_TAC `t:real^N->bool` THEN ASM_REWRITE_TAC[]; + ASM_MESON_TAC[IN; CONNECTED_COMPONENT_SYM]]);; + +let CONNECTED_COMPONENT_TRANSLATION = prove + (`!a s x. connected_component (IMAGE (\x. a + x) s) (a + x) = + IMAGE (\x. a + x) (connected_component s x)`, + REWRITE_TAC[CONNECTED_COMPONENT_SET] THEN GEOM_TRANSLATE_TAC[]);; + +add_translation_invariants [CONNECTED_COMPONENT_TRANSLATION];; + +let CONNECTED_COMPONENT_LINEAR_IMAGE = prove + (`!f s x. linear f /\ (!x y. f x = f y ==> x = y) /\ (!y. ?x. f x = y) + ==> connected_component (IMAGE f s) (f x) = + IMAGE f (connected_component s x)`, + REWRITE_TAC[CONNECTED_COMPONENT_SET] THEN + GEOM_TRANSFORM_TAC[]);; + +add_linear_invariants [CONNECTED_COMPONENT_LINEAR_IMAGE];; + +let UNIONS_CONNECTED_COMPONENT = prove + (`!s:real^N->bool. UNIONS {connected_component s x |x| x IN s} = s`, + GEN_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN + REWRITE_TAC[UNIONS_SUBSET; FORALL_IN_GSPEC; CONNECTED_COMPONENT_SUBSET] THEN + REWRITE_TAC[SUBSET; UNIONS_GSPEC; IN_ELIM_THM] THEN + X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN EXISTS_TAC `x:real^N` THEN + ASM_REWRITE_TAC[] THEN REWRITE_TAC[IN] THEN + ASM_REWRITE_TAC[CONNECTED_COMPONENT_REFL_EQ]);; + +let CLOSED_IN_CONNECTED_COMPONENT = prove + (`!s x:real^N. closed_in (subtopology euclidean s) (connected_component s x)`, + REPEAT GEN_TAC THEN + ASM_CASES_TAC `connected_component s (x:real^N) = {}` THEN + ASM_REWRITE_TAC[CLOSED_IN_EMPTY] THEN + RULE_ASSUM_TAC(REWRITE_RULE[CONNECTED_COMPONENT_EQ_EMPTY]) THEN + REWRITE_TAC[CLOSED_IN_CLOSED] THEN + EXISTS_TAC `closure(connected_component s x):real^N->bool` THEN + REWRITE_TAC[CLOSED_CLOSURE] THEN MATCH_MP_TAC SUBSET_ANTISYM THEN + REWRITE_TAC[SUBSET_INTER; CONNECTED_COMPONENT_SUBSET; CLOSURE_SUBSET] THEN + MATCH_MP_TAC CONNECTED_COMPONENT_MAXIMAL THEN REWRITE_TAC[INTER_SUBSET] THEN + CONJ_TAC THENL + [ASM_REWRITE_TAC[IN_INTER] THEN + MATCH_MP_TAC(REWRITE_RULE[SUBSET] CLOSURE_SUBSET) THEN + ASM_REWRITE_TAC[IN; CONNECTED_COMPONENT_REFL_EQ]; + MATCH_MP_TAC CONNECTED_INTERMEDIATE_CLOSURE THEN + EXISTS_TAC `connected_component s (x:real^N)` THEN + REWRITE_TAC[INTER_SUBSET; CONNECTED_CONNECTED_COMPONENT; + SUBSET_INTER; CONNECTED_COMPONENT_SUBSET; CLOSURE_SUBSET]]);; + +let OPEN_IN_CONNECTED_COMPONENT = prove + (`!s x:real^N. + FINITE {connected_component s x |x| x IN s} + ==> open_in (subtopology euclidean s) (connected_component s x)`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN + `connected_component s (x:real^N) = + s DIFF (UNIONS {connected_component s y |y| y IN s} DIFF + connected_component s x)` + SUBST1_TAC THENL + [REWRITE_TAC[UNIONS_CONNECTED_COMPONENT] THEN + MATCH_MP_TAC(SET_RULE `t SUBSET s ==> t = s DIFF (s DIFF t)`) THEN + REWRITE_TAC[CONNECTED_COMPONENT_SUBSET]; + MATCH_MP_TAC OPEN_IN_DIFF THEN + REWRITE_TAC[OPEN_IN_SUBTOPOLOGY_REFL; TOPSPACE_EUCLIDEAN; SUBSET_UNIV] THEN + REWRITE_TAC[UNIONS_DIFF] THEN + MATCH_MP_TAC CLOSED_IN_UNIONS THEN REWRITE_TAC[FORALL_IN_GSPEC] THEN + ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN ASM_SIMP_TAC[FINITE_IMAGE] THEN + X_GEN_TAC `y:real^N` THEN DISCH_TAC THEN + SUBGOAL_THEN + `connected_component s y DIFF connected_component s x = + connected_component s y \/ + connected_component s (y:real^N) DIFF connected_component s x = {}` + (DISJ_CASES_THEN SUBST1_TAC) + THENL + [MATCH_MP_TAC(SET_RULE + `(~(s INTER t = {}) ==> s = t) ==> s DIFF t = s \/ s DIFF t = {}`) THEN + SIMP_TAC[CONNECTED_COMPONENT_OVERLAP]; + REWRITE_TAC[CLOSED_IN_CONNECTED_COMPONENT]; + REWRITE_TAC[CLOSED_IN_EMPTY]]]);; + +let CONNECTED_COMPONENT_EQUIVALENCE_RELATION = prove + (`!R s:real^N->bool. + (!x y. R x y ==> R y x) /\ + (!x y z. R x y /\ R y z ==> R x z) /\ + (!a. a IN s + ==> ?t. open_in (subtopology euclidean s) t /\ a IN t /\ + !x. x IN t ==> R a x) + ==> !a b. connected_component s a b ==> R a b`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`R:real^N->real^N->bool`; `connected_component s (a:real^N)`] + CONNECTED_EQUIVALENCE_RELATION) THEN + ASM_REWRITE_TAC[CONNECTED_CONNECTED_COMPONENT] THEN ANTS_TAC THENL + [X_GEN_TAC `c:real^N` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `c:real^N`) THEN ANTS_TAC THENL + [ASM_MESON_TAC[CONNECTED_COMPONENT_SUBSET; SUBSET]; ALL_TAC] THEN + DISCH_THEN(X_CHOOSE_THEN `t:real^N->bool` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `t INTER connected_component s (a:real^N)` THEN + ASM_SIMP_TAC[IN_INTER; OPEN_IN_OPEN] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [OPEN_IN_OPEN]) THEN + MATCH_MP_TAC MONO_EXISTS THEN SIMP_TAC[] THEN + MP_TAC(ISPECL [`s:real^N->bool`; `a:real^N`] + CONNECTED_COMPONENT_SUBSET) THEN + SET_TAC[]; + DISCH_THEN MATCH_MP_TAC THEN ASM_REWRITE_TAC[IN] THEN + REWRITE_TAC[CONNECTED_COMPONENT_REFL_EQ] THEN + ASM_MESON_TAC[CONNECTED_COMPONENT_IN]]);; + +(* ------------------------------------------------------------------------- *) +(* The set of connected components of a set. *) +(* ------------------------------------------------------------------------- *) + +let components = new_definition + `components s = {connected_component s x | x | x:real^N IN s}`;; + +let COMPONENTS_TRANSLATION = prove + (`!a s. components(IMAGE (\x. a + x) s) = + IMAGE (IMAGE (\x. a + x)) (components s)`, + REWRITE_TAC[components] THEN GEOM_TRANSLATE_TAC[] THEN SET_TAC[]);; + +add_translation_invariants [COMPONENTS_TRANSLATION];; + +let COMPONENTS_LINEAR_IMAGE = prove + (`!f s. linear f /\ (!x y. f x = f y ==> x = y) /\ (!y. ?x. f x = y) + ==> components(IMAGE f s) = IMAGE (IMAGE f) (components s)`, + REWRITE_TAC[components] THEN GEOM_TRANSFORM_TAC[] THEN SET_TAC[]);; + +add_linear_invariants [COMPONENTS_LINEAR_IMAGE];; + +let IN_COMPONENTS = prove + (`!u:real^N->bool s. s IN components u + <=> ?x. x IN u /\ s = connected_component u x`, + REPEAT GEN_TAC THEN REWRITE_TAC[components] THEN EQ_TAC + THENL [SET_TAC[];STRIP_TAC THEN ASM_SIMP_TAC[] THEN + UNDISCH_TAC `x:real^N IN u` THEN SET_TAC[]]);; + +let UNIONS_COMPONENTS = prove + (`!u:real^N->bool. u = UNIONS (components u)`, + REWRITE_TAC[EXTENSION] THEN REPEAT GEN_TAC THEN EQ_TAC + THENL[DISCH_TAC THEN REWRITE_TAC[IN_UNIONS] THEN + EXISTS_TAC `connected_component (u:real^N->bool) x` THEN CONJ_TAC THENL + [REWRITE_TAC[components] THEN SET_TAC[ASSUME `x:real^N IN u`]; + REWRITE_TAC[CONNECTED_COMPONENT_SET] THEN SUBGOAL_THEN + `?s:real^N->bool. connected s /\ s SUBSET u /\ x IN s` MP_TAC + THENL[EXISTS_TAC `{x:real^N}` THEN ASM_REWRITE_TAC[CONNECTED_SING] THEN + POP_ASSUM MP_TAC THEN SET_TAC[]; SET_TAC[]]]; + REWRITE_TAC[IN_UNIONS] THEN STRIP_TAC THEN + MATCH_MP_TAC (SET_RULE `!x:real^N s u. x IN s /\ s SUBSET u ==> x IN u`) THEN + EXISTS_TAC `t:real^N->bool` THEN ASM_REWRITE_TAC[] THEN STRIP_ASSUME_TAC + (MESON[IN_COMPONENTS;ASSUME `t:real^N->bool IN components u`] + `?y. t:real^N->bool = connected_component u y`) THEN + ASM_REWRITE_TAC[CONNECTED_COMPONENT_SUBSET]]);; + +let PAIRWISE_DISJOINT_COMPONENTS = prove + (`!u:real^N->bool. pairwise DISJOINT (components u)`, + GEN_TAC THEN REWRITE_TAC[pairwise;DISJOINT] THEN + MAP_EVERY X_GEN_TAC [`s:real^N->bool`; `t:real^N->bool`] THEN STRIP_TAC THEN + ASSERT_TAC `(?a. s:real^N->bool = connected_component u a) /\ + ?b. t:real^N->bool = connected_component u b` + THENL [ASM_MESON_TAC[IN_COMPONENTS]; + ASM_MESON_TAC[CONNECTED_COMPONENT_NONOVERLAP]]);; + +let IN_COMPONENTS_NONEMPTY = prove + (`!s c. c IN components s ==> ~(c = {})`, + REPEAT GEN_TAC THEN REWRITE_TAC[components; IN_ELIM_THM] THEN + STRIP_TAC THEN ASM_REWRITE_TAC[CONNECTED_COMPONENT_EQ_EMPTY]);; + +let IN_COMPONENTS_SUBSET = prove + (`!s c. c IN components s ==> c SUBSET s`, + REPEAT GEN_TAC THEN REWRITE_TAC[components; IN_ELIM_THM] THEN + STRIP_TAC THEN ASM_REWRITE_TAC[CONNECTED_COMPONENT_SUBSET]);; + +let IN_COMPONENTS_CONNECTED = prove + (`!s c. c IN components s ==> connected c`, + REPEAT GEN_TAC THEN REWRITE_TAC[components; IN_ELIM_THM] THEN + STRIP_TAC THEN ASM_REWRITE_TAC[CONNECTED_CONNECTED_COMPONENT]);; + +let IN_COMPONENTS_MAXIMAL = prove + (`!s c:real^N->bool. + c IN components s <=> + ~(c = {}) /\ c SUBSET s /\ connected c /\ + !c'. ~(c' = {}) /\ c SUBSET c' /\ c' SUBSET s /\ connected c' + ==> c' = c`, + REPEAT GEN_TAC THEN REWRITE_TAC[components; IN_ELIM_THM] THEN EQ_TAC THENL + [DISCH_THEN(X_CHOOSE_THEN `x:real^N` STRIP_ASSUME_TAC) THEN + ASM_REWRITE_TAC[CONNECTED_COMPONENT_EQ_EMPTY; CONNECTED_COMPONENT_SUBSET; + CONNECTED_CONNECTED_COMPONENT] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC CONNECTED_COMPONENT_MAXIMAL THEN + ASM_MESON_TAC[CONNECTED_COMPONENT_REFL; IN; SUBSET]; + STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `x:real^N` THEN + DISCH_TAC THEN CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + MATCH_MP_TAC(GSYM CONNECTED_COMPONENT_UNIQUE) THEN + ASM_REWRITE_TAC[] THEN X_GEN_TAC `c':real^N->bool` THEN STRIP_TAC THEN + REWRITE_TAC[SET_RULE `c' SUBSET c <=> c' UNION c = c`] THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN + REPEAT(CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC]) THEN + MATCH_MP_TAC CONNECTED_UNION THEN ASM SET_TAC[]]);; + +let JOINABLE_COMPONENTS_EQ = prove + (`!s t c1 c2. + connected t /\ t SUBSET s /\ + c1 IN components s /\ c2 IN components s /\ + ~(c1 INTER t = {}) /\ ~(c2 INTER t = {}) + ==> c1 = c2`, + REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; components; FORALL_IN_GSPEC] THEN + MESON_TAC[JOINABLE_CONNECTED_COMPONENT_EQ]);; + +let CLOSED_COMPONENTS = prove + (`!s c. closed s /\ c IN components s ==> closed c`, + REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; components; FORALL_IN_GSPEC] THEN + SIMP_TAC[CLOSED_CONNECTED_COMPONENT]);; + +let CONTINUOUS_ON_COMPONENTS_GEN = prove + (`!f:real^M->real^N s. + (!c. c IN components s + ==> open_in (subtopology euclidean s) c /\ f continuous_on c) + ==> f continuous_on s`, + REPEAT GEN_TAC THEN REWRITE_TAC[CONTINUOUS_OPEN_IN_PREIMAGE_EQ] THEN + DISCH_TAC THEN X_GEN_TAC `t:real^N->bool` THEN DISCH_TAC THEN + SUBGOAL_THEN + `{x | x IN s /\ (f:real^M->real^N) x IN t} = + UNIONS {{x | x IN c /\ f x IN t} | c IN components s}` + SUBST1_TAC THENL + [CONV_TAC(LAND_CONV(SUBS_CONV + [ISPEC `s:real^M->bool` UNIONS_COMPONENTS])) THEN + REWRITE_TAC[UNIONS_GSPEC; IN_UNIONS] THEN SET_TAC[]; + MATCH_MP_TAC OPEN_IN_UNIONS THEN REWRITE_TAC[FORALL_IN_GSPEC] THEN + ASM_MESON_TAC[OPEN_IN_TRANS]]);; + +let CONTINUOUS_ON_COMPONENTS_CLOSED_GEN = prove + (`!f:real^M->real^N s. + FINITE(components s) /\ + (!c. c IN components s + ==> closed_in (subtopology euclidean s) c /\ f continuous_on c) + ==> f continuous_on s`, + REPEAT GEN_TAC THEN REWRITE_TAC[CONTINUOUS_CLOSED_IN_PREIMAGE_EQ] THEN + DISCH_TAC THEN X_GEN_TAC `t:real^N->bool` THEN DISCH_TAC THEN + SUBGOAL_THEN + `{x | x IN s /\ (f:real^M->real^N) x IN t} = + UNIONS {{x | x IN c /\ f x IN t} | c IN components s}` + SUBST1_TAC THENL + [CONV_TAC(LAND_CONV(SUBS_CONV + [ISPEC `s:real^M->bool` UNIONS_COMPONENTS])) THEN + REWRITE_TAC[UNIONS_GSPEC; IN_UNIONS] THEN SET_TAC[]; + MATCH_MP_TAC CLOSED_IN_UNIONS THEN + ASM_SIMP_TAC[SIMPLE_IMAGE; FINITE_IMAGE; FORALL_IN_IMAGE] THEN + ASM_MESON_TAC[CLOSED_IN_TRANS]]);; + +let CONTINUOUS_ON_COMPONENTS_CLOSED = prove + (`!f:real^M->real^N s. + closed s /\ FINITE(components s) /\ + (!c. c IN components s ==> f continuous_on c) + ==> f continuous_on s`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC CONTINUOUS_ON_COMPONENTS_CLOSED_GEN THEN + ASM_SIMP_TAC[] THEN REPEAT STRIP_TAC THEN MATCH_MP_TAC CLOSED_SUBSET THEN + ASM_MESON_TAC[CLOSED_COMPONENTS; IN_COMPONENTS_SUBSET]);; + +let COMPONENTS_NONOVERLAP = prove + (`!s c c'. c IN components s /\ c' IN components s + ==> (c INTER c' = {} <=> ~(c = c'))`, + REWRITE_TAC[components; IN_ELIM_THM] THEN REPEAT STRIP_TAC THEN + ASM_SIMP_TAC[CONNECTED_COMPONENT_NONOVERLAP]);; + +let COMPONENTS_EQ = prove + (`!s c c'. c IN components s /\ c' IN components s + ==> (c = c' <=> ~(c INTER c' = {}))`, + MESON_TAC[COMPONENTS_NONOVERLAP]);; + +let COMPONENTS_EQ_EMPTY = prove + (`!s. components s = {} <=> s = {}`, + GEN_TAC THEN REWRITE_TAC[EXTENSION] THEN + REWRITE_TAC[components; connected_component; IN_ELIM_THM] THEN + SET_TAC[]);; + +let CONNECTED_EQ_CONNECTED_COMPONENTS_EQ = prove + (`!s. connected s <=> + !c c'. c IN components s /\ c' IN components s ==> c = c'`, + REWRITE_TAC[components; IN_ELIM_THM] THEN + MESON_TAC[CONNECTED_EQ_CONNECTED_COMPONENT_EQ]);; + +let COMPONENTS_EQ_SING,COMPONENTS_EQ_SING_EXISTS = (CONJ_PAIR o prove) + (`(!s:real^N->bool. components s = {s} <=> connected s /\ ~(s = {})) /\ + (!s:real^N->bool. (?a. components s = {a}) <=> connected s /\ ~(s = {}))`, + REWRITE_TAC[AND_FORALL_THM] THEN X_GEN_TAC `s:real^N->bool` THEN + MATCH_MP_TAC(TAUT `(p ==> q) /\ (q ==> r) /\ (r ==> p) + ==> (p <=> r) /\ (q <=> r)`) THEN + REPEAT CONJ_TAC THENL + [MESON_TAC[]; + STRIP_TAC THEN ASM_REWRITE_TAC[CONNECTED_EQ_CONNECTED_COMPONENTS_EQ] THEN + ASM_MESON_TAC[IN_SING; COMPONENTS_EQ_EMPTY; NOT_INSERT_EMPTY]; + STRIP_TAC THEN ONCE_REWRITE_TAC[EXTENSION] THEN + REWRITE_TAC[IN_SING] THEN + REWRITE_TAC[components; IN_ELIM_THM] THEN + ASM_MESON_TAC[CONNECTED_CONNECTED_COMPONENT_SET; MEMBER_NOT_EMPTY]]);; + +let IN_COMPONENTS_SELF = prove + (`!s:real^N->bool. s IN components s <=> connected s /\ ~(s = {})`, + GEN_TAC THEN EQ_TAC THENL + [MESON_TAC[IN_COMPONENTS_NONEMPTY; IN_COMPONENTS_CONNECTED]; + SIMP_TAC[GSYM COMPONENTS_EQ_SING; IN_SING]]);; + +let COMPONENTS_MAXIMAL = prove + (`!s t c:real^N->bool. + c IN components s /\ connected t /\ t SUBSET s /\ ~(c INTER t = {}) + ==> t SUBSET c`, + REWRITE_TAC[IMP_CONJ; components; FORALL_IN_GSPEC] THEN + REPEAT STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN + REWRITE_TAC[IN_INTER; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `y:real^N` THEN STRIP_TAC THEN + FIRST_ASSUM(SUBST1_TAC o SYM o MATCH_MP CONNECTED_COMPONENT_EQ) THEN + MATCH_MP_TAC CONNECTED_COMPONENT_MAXIMAL THEN ASM_REWRITE_TAC[]);; + +let COMPONENTS_UNIQUE = prove + (`!s:real^N->bool k. + UNIONS k = s /\ + (!c. c IN k + ==> connected c /\ ~(c = {}) /\ + !c'. connected c' /\ c SUBSET c' /\ c' SUBSET s ==> c' = c) + ==> components s = k`, + REPEAT STRIP_TAC THEN GEN_REWRITE_TAC I [EXTENSION] THEN + X_GEN_TAC `c:real^N->bool` THEN REWRITE_TAC[IN_COMPONENTS] THEN + EQ_TAC THENL + [DISCH_THEN(X_CHOOSE_THEN `x:real^N` + (CONJUNCTS_THEN2 ASSUME_TAC SUBST1_TAC)) THEN + FIRST_ASSUM(MP_TAC o SPEC `x:real^N` o GEN_REWRITE_RULE I [EXTENSION]) THEN + REWRITE_TAC[IN_UNIONS] THEN ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `c:real^N->bool` THEN STRIP_TAC THEN + SUBGOAL_THEN `connected_component s (x:real^N) = c` + (fun th -> ASM_REWRITE_TAC[th]) THEN + MATCH_MP_TAC CONNECTED_COMPONENT_UNIQUE THEN + FIRST_X_ASSUM(MP_TAC o SPEC `c:real^N->bool`) THEN + ASM_REWRITE_TAC[] THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + X_GEN_TAC `c':real^N->bool` THEN STRIP_TAC THEN + REWRITE_TAC[SET_RULE `c' SUBSET c <=> c' UNION c = c`] THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN CONJ_TAC THENL + [MATCH_MP_TAC CONNECTED_UNION; ASM SET_TAC[]] THEN + ASM SET_TAC[]; + DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC `c:real^N->bool`) THEN + ASM_REWRITE_TAC[] THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `x:real^N` THEN STRIP_TAC THEN + CONJ_TAC THENL [ASM SET_TAC[]; CONV_TAC SYM_CONV] THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN + REWRITE_TAC[CONNECTED_CONNECTED_COMPONENT; CONNECTED_COMPONENT_SUBSET] THEN + MATCH_MP_TAC CONNECTED_COMPONENT_MAXIMAL THEN + ASM_REWRITE_TAC[] THEN ASM SET_TAC[]]);; + +let COMPONENTS_UNIQUE_EQ = prove + (`!s:real^N->bool k. + components s = k <=> + UNIONS k = s /\ + (!c. c IN k + ==> connected c /\ ~(c = {}) /\ + !c'. connected c' /\ c SUBSET c' /\ c' SUBSET s ==> c' = c)`, + REPEAT GEN_TAC THEN EQ_TAC THENL + [DISCH_THEN(SUBST1_TAC o SYM); REWRITE_TAC[COMPONENTS_UNIQUE]] THEN + REWRITE_TAC[GSYM UNIONS_COMPONENTS] THEN + X_GEN_TAC `c:real^N->bool` THEN DISCH_TAC THEN REPEAT CONJ_TAC THENL + [ASM_MESON_TAC[IN_COMPONENTS_CONNECTED]; + ASM_MESON_TAC[IN_COMPONENTS_NONEMPTY]; + RULE_ASSUM_TAC(REWRITE_RULE[IN_COMPONENTS_MAXIMAL]) THEN + ASM_MESON_TAC[SUBSET_EMPTY]]);; + +(* ------------------------------------------------------------------------- *) +(* Continuity implies uniform continuity on a compact domain. *) +(* ------------------------------------------------------------------------- *) + +let COMPACT_UNIFORMLY_EQUICONTINUOUS = prove + (`!(fs:(real^M->real^N)->bool) s. + (!x e. x IN s /\ &0 < e + ==> ?d. &0 < d /\ + (!f x'. f IN fs /\ x' IN s /\ dist (x',x) < d + ==> dist (f x',f x) < e)) /\ + compact s + ==> !e. &0 < e + ==> ?d. &0 < d /\ + !f x x'. f IN fs /\ x IN s /\ x' IN s /\ dist (x',x) < d + ==> dist(f x',f x) < e`, + REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN + GEN_REWRITE_TAC (LAND_CONV o TOP_DEPTH_CONV) [RIGHT_IMP_EXISTS_THM] THEN + REWRITE_TAC[SKOLEM_THM; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `d:real^M->real->real` THEN DISCH_TAC THEN X_GEN_TAC `e:real` THEN + DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o MATCH_MP HEINE_BOREL_LEMMA) THEN + DISCH_THEN(MP_TAC o SPEC + `{ ball(x:real^M,d x (e / &2)) | x IN s}`) THEN + SIMP_TAC[FORALL_IN_GSPEC; OPEN_BALL; UNIONS_GSPEC; SUBSET; IN_ELIM_THM] THEN + ANTS_TAC THENL [ASM_MESON_TAC[CENTRE_IN_BALL; REAL_HALF]; ALL_TAC] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `k:real` THEN STRIP_TAC THEN + ASM_REWRITE_TAC[] THEN + MAP_EVERY X_GEN_TAC [`f:real^M->real^N`; `u:real^M`; `v:real^M`] THEN + STRIP_TAC THEN FIRST_X_ASSUM(fun th -> MP_TAC(SPEC `v:real^M` th) THEN + ASM_REWRITE_TAC[] THEN DISCH_THEN(CHOOSE_THEN MP_TAC)) THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + DISCH_THEN(fun th -> + MP_TAC(SPEC `u:real^M` th) THEN MP_TAC(SPEC `v:real^M` th)) THEN + ASM_REWRITE_TAC[DIST_REFL] THEN + FIRST_X_ASSUM(X_CHOOSE_THEN `w:real^M` (CONJUNCTS_THEN2 ASSUME_TAC + SUBST_ALL_TAC)) THEN + ASM_REWRITE_TAC[CENTRE_IN_BALL] THEN ASM_REWRITE_TAC[IN_BALL] THEN + ONCE_REWRITE_TAC[DIST_SYM] THEN REPEAT STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`w:real^M`; `e / &2`]) THEN + ASM_REWRITE_TAC[REAL_HALF] THEN + DISCH_THEN(MP_TAC o SPEC `f:real^M->real^N` o CONJUNCT2) THEN + DISCH_THEN(fun th -> MP_TAC(SPEC `u:real^M` th) THEN + MP_TAC(SPEC `v:real^M` th)) THEN + ASM_REWRITE_TAC[] THEN CONV_TAC NORM_ARITH);; + +let COMPACT_UNIFORMLY_CONTINUOUS = prove + (`!f:real^M->real^N s. + f continuous_on s /\ compact s ==> f uniformly_continuous_on s`, + REPEAT GEN_TAC THEN REWRITE_TAC[continuous_on; uniformly_continuous_on] THEN + STRIP_TAC THEN + MP_TAC(ISPECL [`{f:real^M->real^N}`; `s:real^M->bool`] + COMPACT_UNIFORMLY_EQUICONTINUOUS) THEN + REWRITE_TAC[RIGHT_FORALL_IMP_THM; IMP_CONJ; IN_SING; FORALL_UNWIND_THM2] THEN + ASM_MESON_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* A uniformly convergent limit of continuous functions is continuous. *) +(* ------------------------------------------------------------------------- *) + +let CONTINUOUS_UNIFORM_LIMIT = prove + (`!net f:A->real^M->real^N g s. + ~(trivial_limit net) /\ + eventually (\n. (f n) continuous_on s) net /\ + (!e. &0 < e + ==> eventually (\n. !x. x IN s ==> norm(f n x - g x) < e) net) + ==> g continuous_on s`, + REWRITE_TAC[continuous_on] THEN REPEAT GEN_TAC THEN STRIP_TAC THEN + X_GEN_TAC `x:real^M` THEN STRIP_TAC THEN + X_GEN_TAC `e:real` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `e / &3`) THEN + ASM_SIMP_TAC[REAL_LT_DIV; REAL_OF_NUM_LT; ARITH] THEN + FIRST_X_ASSUM(fun th -> MP_TAC th THEN REWRITE_TAC[IMP_IMP] THEN + GEN_REWRITE_TAC LAND_CONV [GSYM EVENTUALLY_AND]) THEN + DISCH_THEN(MP_TAC o MATCH_MP EVENTUALLY_HAPPENS) THEN + ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN X_GEN_TAC `a:A` THEN + DISCH_THEN(CONJUNCTS_THEN2 (MP_TAC o SPEC `x:real^M`) ASSUME_TAC) THEN + ASM_REWRITE_TAC[] THEN DISCH_THEN(MP_TAC o SPEC `e / &3`) THEN + ASM_SIMP_TAC[REAL_LT_DIV; REAL_OF_NUM_LT; ARITH] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `d:real` THEN + MATCH_MP_TAC MONO_AND THEN REWRITE_TAC[] THEN + MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `y:real^M` THEN + DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN ASM_REWRITE_TAC[] THEN + FIRST_X_ASSUM(fun th -> + MP_TAC(SPEC `x:real^M` th) THEN MP_TAC(SPEC `y:real^M` th)) THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC(REAL_ARITH + `w <= x + y + z + ==> x < e / &3 ==> y < e / &3 ==> z < e / &3 ==> w < e`) THEN + REWRITE_TAC[dist] THEN + SUBST1_TAC(VECTOR_ARITH + `(g:real^M->real^N) y - g x = + --(f (a:A) y - g y) + (f a x - g x) + (f a y - f a x)`) THEN + MATCH_MP_TAC NORM_TRIANGLE_LE THEN REWRITE_TAC[NORM_NEG; REAL_LE_LADD] THEN + MATCH_MP_TAC NORM_TRIANGLE_LE THEN REWRITE_TAC[NORM_NEG; REAL_LE_REFL]);; + +(* ------------------------------------------------------------------------- *) +(* Topological stuff lifted from and dropped to R *) +(* ------------------------------------------------------------------------- *) + +let OPEN_LIFT = prove + (`!s. open(IMAGE lift s) <=> + !x. x IN s ==> ?e. &0 < e /\ !x'. abs(x' - x) < e ==> x' IN s`, + REWRITE_TAC[open_def; FORALL_LIFT; LIFT_IN_IMAGE_LIFT; DIST_LIFT]);; + +let LIMPT_APPROACHABLE_LIFT = prove + (`!x s. (lift x) limit_point_of (IMAGE lift s) <=> + !e. &0 < e ==> ?x'. x' IN s /\ ~(x' = x) /\ abs(x' - x) < e`, + REWRITE_TAC[LIMPT_APPROACHABLE; EXISTS_LIFT; LIFT_IN_IMAGE_LIFT; + LIFT_EQ; DIST_LIFT]);; + +let CLOSED_LIFT = prove + (`!s. closed (IMAGE lift s) <=> + !x. (!e. &0 < e ==> ?x'. x' IN s /\ ~(x' = x) /\ abs(x' - x) < e) + ==> x IN s`, + GEN_TAC THEN REWRITE_TAC[CLOSED_LIMPT; LIMPT_APPROACHABLE] THEN + ONCE_REWRITE_TAC[FORALL_LIFT] THEN + REWRITE_TAC[LIMPT_APPROACHABLE_LIFT; LIFT_EQ; DIST_LIFT; + EXISTS_LIFT; LIFT_IN_IMAGE_LIFT]);; + +let CONTINUOUS_AT_LIFT_RANGE = prove + (`!f x. (lift o f) continuous (at x) <=> + !e. &0 < e + ==> ?d. &0 < d /\ + (!x'. norm(x' - x) < d + ==> abs(f x' - f x) < e)`, + REWRITE_TAC[continuous_at; o_THM; DIST_LIFT] THEN REWRITE_TAC[dist]);; + +let CONTINUOUS_ON_LIFT_RANGE = prove + (`!f s. (lift o f) continuous_on s <=> + !x. x IN s + ==> !e. &0 < e + ==> ?d. &0 < d /\ + (!x'. x' IN s /\ norm(x' - x) < d + ==> abs(f x' - f x) < e)`, + REWRITE_TAC[continuous_on; o_THM; DIST_LIFT] THEN REWRITE_TAC[dist]);; + +let CONTINUOUS_LIFT_NORM_COMPOSE = prove + (`!net f:A->real^N. + f continuous net + ==> (\x. lift(norm(f x))) continuous net`, + REPEAT GEN_TAC THEN REWRITE_TAC[continuous; tendsto] THEN + MATCH_MP_TAC MONO_FORALL THEN GEN_TAC THEN MATCH_MP_TAC MONO_IMP THEN + REWRITE_TAC[] THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] EVENTUALLY_MONO) THEN + REWRITE_TAC[DIST_REAL; GSYM drop; LIFT_DROP] THEN + NORM_ARITH_TAC);; + +let CONTINUOUS_ON_LIFT_NORM_COMPOSE = prove + (`!f:real^M->real^N s. + f continuous_on s + ==> (\x. lift(norm(f x))) continuous_on s`, + SIMP_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN; CONTINUOUS_LIFT_NORM_COMPOSE]);; + +let CONTINUOUS_AT_LIFT_NORM = prove + (`!x. (lift o norm) continuous (at x)`, + REWRITE_TAC[CONTINUOUS_AT_LIFT_RANGE; NORM_LIFT] THEN + MESON_TAC[REAL_ABS_SUB_NORM; REAL_LET_TRANS]);; + +let CONTINUOUS_ON_LIFT_NORM = prove + (`!s. (lift o norm) continuous_on s`, + REWRITE_TAC[CONTINUOUS_ON_LIFT_RANGE; NORM_LIFT] THEN + MESON_TAC[REAL_ABS_SUB_NORM; REAL_LET_TRANS]);; + +let CONTINUOUS_AT_LIFT_COMPONENT = prove + (`!i a. 1 <= i /\ i <= dimindex(:N) + ==> (\x:real^N. lift(x$i)) continuous (at a)`, + SIMP_TAC[continuous_at; DIST_LIFT; GSYM VECTOR_SUB_COMPONENT] THEN + MESON_TAC[dist; REAL_LET_TRANS; COMPONENT_LE_NORM]);; + +let CONTINUOUS_ON_LIFT_COMPONENT = prove + (`!i s. 1 <= i /\ i <= dimindex(:N) + ==> (\x:real^N. lift(x$i)) continuous_on s`, + SIMP_TAC[continuous_on; DIST_LIFT; GSYM VECTOR_SUB_COMPONENT] THEN + MESON_TAC[dist; REAL_LET_TRANS; COMPONENT_LE_NORM]);; + +let CONTINUOUS_AT_LIFT_INFNORM = prove + (`!x:real^N. (lift o infnorm) continuous (at x)`, + REWRITE_TAC[CONTINUOUS_AT; LIM_AT; o_THM; DIST_LIFT] THEN + MESON_TAC[REAL_LET_TRANS; dist; REAL_ABS_SUB_INFNORM; INFNORM_LE_NORM]);; + +let CONTINUOUS_AT_LIFT_DIST = prove + (`!a:real^N x. (lift o (\x. dist(a,x))) continuous (at x)`, + REWRITE_TAC[CONTINUOUS_AT_LIFT_RANGE] THEN + MESON_TAC[NORM_ARITH `abs(dist(a:real^N,x) - dist(a,y)) <= norm(x - y)`; + REAL_LET_TRANS]);; + +let CONTINUOUS_ON_LIFT_DIST = prove + (`!a s. (lift o (\x. dist(a,x))) continuous_on s`, + REWRITE_TAC[CONTINUOUS_ON_LIFT_RANGE] THEN + MESON_TAC[NORM_ARITH `abs(dist(a:real^N,x) - dist(a,y)) <= norm(x - y)`; + REAL_LET_TRANS]);; + +(* ------------------------------------------------------------------------- *) +(* Hence some handy theorems on distance, diameter etc. of/from a set. *) +(* ------------------------------------------------------------------------- *) + +let COMPACT_ATTAINS_SUP = prove + (`!s. compact (IMAGE lift s) /\ ~(s = {}) + ==> ?x. x IN s /\ !y. y IN s ==> y <= x`, + REWRITE_TAC[COMPACT_EQ_BOUNDED_CLOSED] THEN REPEAT STRIP_TAC THEN + MP_TAC(SPEC `s:real->bool` BOUNDED_HAS_SUP) THEN ASM_REWRITE_TAC[] THEN + STRIP_TAC THEN EXISTS_TAC `sup s` THEN ASM_REWRITE_TAC[] THEN + ASM_MESON_TAC[CLOSED_LIFT; REAL_ARITH `s <= s - e <=> ~(&0 < e)`; + REAL_ARITH `x <= s /\ ~(x <= s - e) ==> abs(x - s) < e`]);; + +let COMPACT_ATTAINS_INF = prove + (`!s. compact (IMAGE lift s) /\ ~(s = {}) + ==> ?x. x IN s /\ !y. y IN s ==> x <= y`, + REWRITE_TAC[COMPACT_EQ_BOUNDED_CLOSED] THEN REPEAT STRIP_TAC THEN + MP_TAC(SPEC `s:real->bool` BOUNDED_HAS_INF) THEN ASM_REWRITE_TAC[] THEN + STRIP_TAC THEN EXISTS_TAC `inf s` THEN ASM_REWRITE_TAC[] THEN + ASM_MESON_TAC[CLOSED_LIFT; REAL_ARITH `s + e <= s <=> ~(&0 < e)`; + REAL_ARITH `s <= x /\ ~(s + e <= x) ==> abs(x - s) < e`]);; + +let CONTINUOUS_ATTAINS_SUP = prove + (`!f:real^N->real s. + compact s /\ ~(s = {}) /\ (lift o f) continuous_on s + ==> ?x. x IN s /\ !y. y IN s ==> f(y) <= f(x)`, + REPEAT STRIP_TAC THEN + MP_TAC(SPEC `IMAGE (f:real^N->real) s` COMPACT_ATTAINS_SUP) THEN + ASM_SIMP_TAC[GSYM IMAGE_o; COMPACT_CONTINUOUS_IMAGE; IMAGE_EQ_EMPTY] THEN + MESON_TAC[IN_IMAGE]);; + +let CONTINUOUS_ATTAINS_INF = prove + (`!f:real^N->real s. + compact s /\ ~(s = {}) /\ (lift o f) continuous_on s + ==> ?x. x IN s /\ !y. y IN s ==> f(x) <= f(y)`, + REPEAT STRIP_TAC THEN + MP_TAC(SPEC `IMAGE (f:real^N->real) s` COMPACT_ATTAINS_INF) THEN + ASM_SIMP_TAC[GSYM IMAGE_o; COMPACT_CONTINUOUS_IMAGE; IMAGE_EQ_EMPTY] THEN + MESON_TAC[IN_IMAGE]);; + +let DISTANCE_ATTAINS_SUP = prove + (`!s a. compact s /\ ~(s = {}) + ==> ?x. x IN s /\ !y. y IN s ==> dist(a,y) <= dist(a,x)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC CONTINUOUS_ATTAINS_SUP THEN + ASM_REWRITE_TAC[CONTINUOUS_ON_LIFT_RANGE] THEN REWRITE_TAC[dist] THEN + ASM_MESON_TAC[REAL_LET_TRANS; REAL_ABS_SUB_NORM; NORM_NEG; + VECTOR_ARITH `(a - x) - (a - y) = --(x - y):real^N`]);; + +(* ------------------------------------------------------------------------- *) +(* For *minimal* distance, we only need closure, not compactness. *) +(* ------------------------------------------------------------------------- *) + +let DISTANCE_ATTAINS_INF = prove + (`!s a:real^N. + closed s /\ ~(s = {}) + ==> ?x. x IN s /\ !y. y IN s ==> dist(a,x) <= dist(a,y)`, + REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN + DISCH_THEN(X_CHOOSE_TAC `b:real^N`) THEN + MP_TAC(ISPECL [`\x:real^N. dist(a,x)`; `cball(a:real^N,dist(b,a)) INTER s`] + CONTINUOUS_ATTAINS_INF) THEN + ANTS_TAC THENL + [ASM_SIMP_TAC[COMPACT_EQ_BOUNDED_CLOSED; CLOSED_INTER; BOUNDED_INTER; + BOUNDED_CBALL; CLOSED_CBALL; GSYM MEMBER_NOT_EMPTY] THEN + REWRITE_TAC[dist; CONTINUOUS_ON_LIFT_RANGE; IN_INTER; IN_CBALL] THEN + ASM_MESON_TAC[REAL_LET_TRANS; REAL_ABS_SUB_NORM; NORM_NEG; REAL_LE_REFL; + NORM_SUB; VECTOR_ARITH `(a - x) - (a - y) = --(x - y):real^N`]; + MATCH_MP_TAC MONO_EXISTS THEN REWRITE_TAC[IN_INTER; IN_CBALL] THEN + ASM_MESON_TAC[DIST_SYM; REAL_LE_TOTAL; REAL_LE_TRANS]]);; + +(* ------------------------------------------------------------------------- *) +(* We can now extend limit compositions to consider the scalar multiplier. *) +(* ------------------------------------------------------------------------- *) + +let LIM_MUL = prove + (`!net:(A)net f l:real^N c d. + ((lift o c) --> lift d) net /\ (f --> l) net + ==> ((\x. c(x) % f(x)) --> (d % l)) net`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`net:(A)net`; `\x (y:real^N). drop x % y`; + `lift o (c:A->real)`; `f:A->real^N`; `lift d`; `l:real^N`] LIM_BILINEAR) THEN + ASM_REWRITE_TAC[LIFT_DROP; o_THM] THEN DISCH_THEN MATCH_MP_TAC THEN + REWRITE_TAC[bilinear; linear; DROP_ADD; DROP_CMUL] THEN + REPEAT STRIP_TAC THEN VECTOR_ARITH_TAC);; + +let LIM_VMUL = prove + (`!net:(A)net c d v:real^N. + ((lift o c) --> lift d) net ==> ((\x. c(x) % v) --> d % v) net`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC LIM_MUL THEN ASM_REWRITE_TAC[LIM_CONST]);; + +let CONTINUOUS_VMUL = prove + (`!net c v. (lift o c) continuous net ==> (\x. c(x) % v) continuous net`, + REWRITE_TAC[continuous; LIM_VMUL; o_THM]);; + +let CONTINUOUS_MUL = prove + (`!net f c. (lift o c) continuous net /\ f continuous net + ==> (\x. c(x) % f(x)) continuous net`, + REWRITE_TAC[continuous; LIM_MUL; o_THM]);; + +let CONTINUOUS_ON_VMUL = prove + (`!s c v. (lift o c) continuous_on s ==> (\x. c(x) % v) continuous_on s`, + REWRITE_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN] THEN + SIMP_TAC[CONTINUOUS_VMUL]);; + +let CONTINUOUS_ON_MUL = prove + (`!s c f. (lift o c) continuous_on s /\ f continuous_on s + ==> (\x. c(x) % f(x)) continuous_on s`, + REWRITE_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN] THEN + SIMP_TAC[CONTINUOUS_MUL]);; + +let CONTINUOUS_LIFT_POW = prove + (`!net f:A->real n. + (\x. lift(f x)) continuous net + ==> (\x. lift(f x pow n)) continuous net`, + REWRITE_TAC[RIGHT_FORALL_IMP_THM] THEN REPEAT GEN_TAC THEN DISCH_TAC THEN + INDUCT_TAC THEN ASM_REWRITE_TAC[LIFT_CMUL; real_pow; CONTINUOUS_CONST] THEN + MATCH_MP_TAC CONTINUOUS_MUL THEN ASM_REWRITE_TAC[o_DEF]);; + +let CONTINUOUS_ON_LIFT_POW = prove + (`!f:real^N->real s n. + (\x. lift(f x)) continuous_on s + ==> (\x. lift(f x pow n)) continuous_on s`, + REWRITE_TAC[RIGHT_FORALL_IMP_THM] THEN REPEAT GEN_TAC THEN + DISCH_TAC THEN INDUCT_TAC THEN + ASM_REWRITE_TAC[LIFT_CMUL; real_pow; CONTINUOUS_ON_CONST] THEN + MATCH_MP_TAC CONTINUOUS_ON_MUL THEN ASM_REWRITE_TAC[o_DEF]);; + +let CONTINUOUS_LIFT_PRODUCT = prove + (`!net:(A)net f (t:B->bool). + FINITE t /\ + (!i. i IN t ==> (\x. lift(f x i)) continuous net) + ==> (\x. lift(product t (f x))) continuous net`, + GEN_TAC THEN GEN_TAC THEN REWRITE_TAC[IMP_CONJ] THEN + MATCH_MP_TAC FINITE_INDUCT_STRONG THEN SIMP_TAC[PRODUCT_CLAUSES] THEN + REWRITE_TAC[CONTINUOUS_CONST; LIFT_CMUL; FORALL_IN_INSERT] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC CONTINUOUS_MUL THEN + ASM_SIMP_TAC[o_DEF]);; + +let CONTINUOUS_ON_LIFT_PRODUCT = prove + (`!f:real^N->A->real s t. + FINITE t /\ + + (!i. i IN t ==> (\x. lift(f x i)) continuous_on s) + ==> (\x. lift(product t (f x))) continuous_on s`, + SIMP_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN; CONTINUOUS_LIFT_PRODUCT]);; + +(* ------------------------------------------------------------------------- *) +(* And so we have continuity of inverse. *) +(* ------------------------------------------------------------------------- *) + +let LIM_INV = prove + (`!net:(A)net f l. + ((lift o f) --> lift l) net /\ ~(l = &0) + ==> ((lift o inv o f) --> lift(inv l)) net`, + REPEAT GEN_TAC THEN REWRITE_TAC[LIM] THEN + ASM_CASES_TAC `trivial_limit(net:(A)net)` THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[o_THM; DIST_LIFT] THEN STRIP_TAC THEN + X_GEN_TAC `e:real` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `min (abs(l) / &2) ((l pow 2 * e) / &2)`) THEN + REWRITE_TAC[REAL_LT_MIN] THEN ANTS_TAC THENL + [ASM_SIMP_TAC[GSYM REAL_ABS_NZ; REAL_LT_DIV; REAL_OF_NUM_LT; ARITH] THEN + MATCH_MP_TAC REAL_LT_DIV THEN REWRITE_TAC[REAL_OF_NUM_LT; ARITH] THEN + ONCE_REWRITE_TAC[GSYM REAL_POW2_ABS] THEN + ASM_SIMP_TAC[REAL_LT_MUL; GSYM REAL_ABS_NZ; REAL_POW_LT]; + ALL_TAC] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `a:A` THEN + MATCH_MP_TAC MONO_AND THEN REWRITE_TAC[] THEN + MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `b:A` THEN + MATCH_MP_TAC MONO_IMP THEN REWRITE_TAC[] THEN + SIMP_TAC[REAL_LT_RDIV_EQ; REAL_OF_NUM_LT; ARITH] THEN STRIP_TAC THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP (REAL_ARITH + `abs(x - l) * &2 < abs l ==> ~(x = &0)`)) THEN + ASM_SIMP_TAC[REAL_SUB_INV; REAL_ABS_DIV; REAL_LT_LDIV_EQ; + GSYM REAL_ABS_NZ; REAL_ENTIRE] THEN + FIRST_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH + `abs(x - y) * &2 < b * c ==> c * b <= d * &2 ==> abs(y - x) < d`)) THEN + ASM_SIMP_TAC[GSYM REAL_MUL_ASSOC; REAL_LE_LMUL_EQ] THEN + ONCE_REWRITE_TAC[GSYM REAL_POW2_ABS] THEN ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN + ASM_SIMP_TAC[REAL_ABS_MUL; REAL_POW_2; REAL_MUL_ASSOC; GSYM REAL_ABS_NZ; + REAL_LE_RMUL_EQ] THEN + ASM_SIMP_TAC[REAL_ARITH `abs(x - y) * &2 < abs y ==> abs y <= &2 * abs x`]);; + +let CONTINUOUS_INV = prove + (`!net f. (lift o f) continuous net /\ ~(f(netlimit net) = &0) + ==> (lift o inv o f) continuous net`, + REWRITE_TAC[continuous; LIM_INV; o_THM]);; + +let CONTINUOUS_AT_WITHIN_INV = prove + (`!f s a:real^N. + (lift o f) continuous (at a within s) /\ ~(f a = &0) + ==> (lift o inv o f) continuous (at a within s)`, + REPEAT GEN_TAC THEN + ASM_CASES_TAC `trivial_limit (at (a:real^N) within s)` THENL + [ASM_REWRITE_TAC[continuous; LIM]; + ASM_SIMP_TAC[NETLIMIT_WITHIN; CONTINUOUS_INV]]);; + +let CONTINUOUS_AT_INV = prove + (`!f a. (lift o f) continuous at a /\ ~(f a = &0) + ==> (lift o inv o f) continuous at a`, + ONCE_REWRITE_TAC[GSYM WITHIN_UNIV] THEN + REWRITE_TAC[CONTINUOUS_AT_WITHIN_INV]);; + +let CONTINUOUS_ON_INV = prove + (`!f s. (lift o f) continuous_on s /\ (!x. x IN s ==> ~(f x = &0)) + ==> (lift o inv o f) continuous_on s`, + SIMP_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN; CONTINUOUS_AT_WITHIN_INV]);; + +(* ------------------------------------------------------------------------- *) +(* Preservation properties for pasted sets (Cartesian products). *) +(* ------------------------------------------------------------------------- *) + +let BOUNDED_PCROSS_EQ = prove + (`!s:real^M->bool t:real^N->bool. + bounded (s PCROSS t) <=> + s = {} \/ t = {} \/ bounded s /\ bounded t`, + REPEAT GEN_TAC THEN REWRITE_TAC[PCROSS] THEN + ASM_CASES_TAC `s:real^M->bool = {}` THEN ASM_REWRITE_TAC[NOT_IN_EMPTY] THEN + ASM_CASES_TAC `t:real^N->bool = {}` THEN ASM_REWRITE_TAC[NOT_IN_EMPTY] THEN + REWRITE_TAC[SET_RULE `{f x y |x,y| F} = {}`; BOUNDED_EMPTY] THEN + RULE_ASSUM_TAC(REWRITE_RULE[GSYM MEMBER_NOT_EMPTY]) THEN + REWRITE_TAC[bounded; FORALL_PASTECART; IN_ELIM_PASTECART_THM] THEN + ASM_MESON_TAC[NORM_LE_PASTECART; REAL_LE_TRANS; NORM_PASTECART_LE; + REAL_LE_ADD2]);; + +let BOUNDED_PCROSS = prove + (`!s:real^M->bool t:real^N->bool. + bounded s /\ bounded t ==> bounded (s PCROSS t)`, + SIMP_TAC[BOUNDED_PCROSS_EQ]);; + +let CLOSED_PCROSS_EQ = prove + (`!s:real^M->bool t:real^N->bool. + closed (s PCROSS t) <=> + s = {} \/ t = {} \/ closed s /\ closed t`, + REPEAT GEN_TAC THEN REWRITE_TAC[PCROSS] THEN MAP_EVERY ASM_CASES_TAC + [`s:real^M->bool = {}`; `t:real^N->bool = {}`] THEN + ASM_REWRITE_TAC[NOT_IN_EMPTY; CLOSED_EMPTY; SET_RULE + `{f x y |x,y| F} = {}`] THEN + REWRITE_TAC[CLOSED_SEQUENTIAL_LIMITS; LIM_SEQUENTIALLY] THEN + REWRITE_TAC[FORALL_PASTECART; IN_ELIM_PASTECART_THM] THEN + REWRITE_TAC[IN_ELIM_THM; SKOLEM_THM; FORALL_AND_THM] THEN + ONCE_REWRITE_TAC[GSYM FUN_EQ_THM] THEN + REWRITE_TAC[LEFT_AND_EXISTS_THM; LEFT_IMP_EXISTS_THM] THEN + SIMP_TAC[TAUT `((p /\ q) /\ r) /\ s ==> t <=> r ==> p /\ q /\ s ==> t`] THEN + ONCE_REWRITE_TAC[MESON[] + `(!a b c d e. P a b c d e) <=> (!d e b c a. P a b c d e)`] THEN + REWRITE_TAC[FORALL_UNWIND_THM2] THEN + RULE_ASSUM_TAC(REWRITE_RULE[GSYM MEMBER_NOT_EMPTY]) THEN EQ_TAC THENL + [GEN_REWRITE_TAC (LAND_CONV o TOP_DEPTH_CONV) + [TAUT `p ==> q /\ r <=> (p ==> q) /\ (p ==> r)`; FORALL_AND_THM] THEN + MATCH_MP_TAC MONO_AND THEN CONJ_TAC THENL + [ALL_TAC; GEN_REWRITE_TAC LAND_CONV [SWAP_FORALL_THM]] THEN + MATCH_MP_TAC MONO_FORALL THEN REPEAT STRIP_TAC THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN MATCH_MP_TAC(MESON[] + `(?x. P x (\n. x)) ==> (?s x. P x s)`) THEN + ASM_MESON_TAC[DIST_PASTECART_CANCEL]; + ONCE_REWRITE_TAC[MESON[] + `(!x l. P x l) /\ (!y m. Q y m) <=> (!x y l m. P x l /\ Q y m)`] THEN + REPEAT(MATCH_MP_TAC MONO_FORALL THEN GEN_TAC) THEN + REWRITE_TAC[dist; PASTECART_SUB] THEN + ASM_MESON_TAC[NORM_LE_PASTECART; REAL_LET_TRANS]]);; + +let CLOSED_PCROSS = prove + (`!s:real^M->bool t:real^N->bool. + closed s /\ closed t ==> closed (s PCROSS t)`, + SIMP_TAC[CLOSED_PCROSS_EQ]);; + +let COMPACT_PCROSS_EQ = prove + (`!s:real^M->bool t:real^N->bool. + compact (s PCROSS t) <=> + s = {} \/ t = {} \/ compact s /\ compact t`, + REWRITE_TAC[COMPACT_EQ_BOUNDED_CLOSED; CLOSED_PCROSS_EQ; + BOUNDED_PCROSS_EQ] THEN + MESON_TAC[]);; + +let COMPACT_PCROSS = prove + (`!s:real^M->bool t:real^N->bool. + compact s /\ compact t ==> compact (s PCROSS t)`, + SIMP_TAC[COMPACT_PCROSS_EQ]);; + +let OPEN_PCROSS_EQ = prove + (`!s:real^M->bool t:real^N->bool. + open (s PCROSS t) <=> + s = {} \/ t = {} \/ open s /\ open t`, + REPEAT GEN_TAC THEN REWRITE_TAC[PCROSS] THEN + ASM_CASES_TAC `s:real^M->bool = {}` THEN ASM_REWRITE_TAC[NOT_IN_EMPTY] THEN + ASM_CASES_TAC `t:real^N->bool = {}` THEN ASM_REWRITE_TAC[NOT_IN_EMPTY] THEN + REWRITE_TAC[SET_RULE `{f x y |x,y| F} = {}`; OPEN_EMPTY] THEN + RULE_ASSUM_TAC(REWRITE_RULE[GSYM MEMBER_NOT_EMPTY]) THEN + EQ_TAC THENL + [REWRITE_TAC[open_def; FORALL_PASTECART; IN_ELIM_PASTECART_THM] THEN + ASM_MESON_TAC[DIST_PASTECART_CANCEL]; + REWRITE_TAC[OPEN_CLOSED] THEN STRIP_TAC THEN + SUBGOAL_THEN + `UNIV DIFF {pastecart x y | x IN s /\ y IN t} = + {pastecart x y | x IN ((:real^M) DIFF s) /\ y IN (:real^N)} UNION + {pastecart x y | x IN (:real^M) /\ y IN ((:real^N) DIFF t)}` + SUBST1_TAC THENL + [REWRITE_TAC[EXTENSION; IN_DIFF; IN_UNION; FORALL_PASTECART; IN_UNIV] THEN + REWRITE_TAC[IN_ELIM_THM; PASTECART_EQ; FSTCART_PASTECART; + SNDCART_PASTECART] THEN MESON_TAC[]; + SIMP_TAC[GSYM PCROSS] THEN MATCH_MP_TAC CLOSED_UNION THEN CONJ_TAC THEN + MATCH_MP_TAC CLOSED_PCROSS THEN ASM_REWRITE_TAC[CLOSED_UNIV]]]);; + +let OPEN_PCROSS = prove + (`!s:real^M->bool t:real^N->bool. + open s /\ open t ==> open (s PCROSS t)`, + SIMP_TAC[OPEN_PCROSS_EQ]);; + +let OPEN_IN_PCROSS = prove + (`!s s':real^M->bool t t':real^N->bool. + open_in (subtopology euclidean s) s' /\ + open_in (subtopology euclidean t) t' + ==> open_in (subtopology euclidean (s PCROSS t)) (s' PCROSS t')`, + REPEAT GEN_TAC THEN REWRITE_TAC[OPEN_IN_OPEN] THEN DISCH_THEN(CONJUNCTS_THEN2 + (X_CHOOSE_THEN `s'':real^M->bool` STRIP_ASSUME_TAC) + (X_CHOOSE_THEN `t'':real^N->bool` STRIP_ASSUME_TAC)) THEN + EXISTS_TAC `(s'':real^M->bool) PCROSS (t'':real^N->bool)` THEN + ASM_SIMP_TAC[OPEN_PCROSS; EXTENSION; FORALL_PASTECART] THEN + REWRITE_TAC[IN_INTER; PASTECART_IN_PCROSS] THEN ASM SET_TAC[]);; + +let PASTECART_IN_INTERIOR_SUBTOPOLOGY = prove + (`!s t u x:real^M y:real^N. + pastecart x y IN u /\ open_in (subtopology euclidean (s PCROSS t)) u + ==> ?v w. open_in (subtopology euclidean s) v /\ x IN v /\ + open_in (subtopology euclidean t) w /\ y IN w /\ + (v PCROSS w) SUBSET u`, + REWRITE_TAC[open_in; FORALL_PASTECART; PASTECART_IN_PCROSS] THEN + REPEAT STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`x:real^M`; `y:real^N`]) THEN + ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `e:real` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `ball(x:real^M,e / &2) INTER s` THEN + EXISTS_TAC `ball(y:real^N,e / &2) INTER t` THEN + SUBGOAL_THEN `(x:real^M) IN s /\ (y:real^N) IN t` STRIP_ASSUME_TAC THENL + [ASM_MESON_TAC[SUBSET; PASTECART_IN_PCROSS]; ALL_TAC] THEN + ASM_SIMP_TAC[INTER_SUBSET; IN_INTER; CENTRE_IN_BALL; REAL_HALF] THEN + REWRITE_TAC[IN_BALL] THEN REPEAT(CONJ_TAC THENL + [MESON_TAC[REAL_SUB_LT; NORM_ARITH + `dist(x,y) < e /\ dist(z,y) < e - dist(x,y) + ==> dist(x:real^N,z) < e`]; + ALL_TAC]) THEN + REWRITE_TAC[SUBSET; FORALL_PASTECART; PASTECART_IN_PCROSS] THEN + REWRITE_TAC[IN_BALL; IN_INTER] THEN REPEAT STRIP_TAC THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_REWRITE_TAC[dist; PASTECART_SUB] THEN + W(MP_TAC o PART_MATCH lhand NORM_PASTECART_LE o lhand o snd) THEN + REWRITE_TAC[GSYM(ONCE_REWRITE_RULE[DIST_SYM] dist)] THEN + ASM_REAL_ARITH_TAC);; + +let OPEN_IN_PCROSS_EQ = prove + (`!s s':real^M->bool t t':real^N->bool. + open_in (subtopology euclidean (s PCROSS t)) (s' PCROSS t') <=> + s' = {} \/ t' = {} \/ + open_in (subtopology euclidean s) s' /\ + open_in (subtopology euclidean t) t'`, + REPEAT GEN_TAC THEN + ASM_CASES_TAC `s':real^M->bool = {}` THEN + ASM_REWRITE_TAC[PCROSS_EMPTY; OPEN_IN_EMPTY] THEN + ASM_CASES_TAC `t':real^N->bool = {}` THEN + ASM_REWRITE_TAC[PCROSS_EMPTY; OPEN_IN_EMPTY] THEN + EQ_TAC THEN REWRITE_TAC[OPEN_IN_PCROSS] THEN REPEAT STRIP_TAC THENL + [ONCE_REWRITE_TAC[OPEN_IN_SUBOPEN] THEN + X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN + UNDISCH_TAC `~(t':real^N->bool = {})` THEN + REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN + DISCH_THEN(X_CHOOSE_TAC `y:real^N`); + ONCE_REWRITE_TAC[OPEN_IN_SUBOPEN] THEN + X_GEN_TAC `y:real^N` THEN DISCH_TAC THEN + UNDISCH_TAC `~(s':real^M->bool = {})` THEN + REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN + DISCH_THEN(X_CHOOSE_TAC `x:real^M`)] THEN + MP_TAC(ISPECL + [`s:real^M->bool`; `t:real^N->bool`; + `(s':real^M->bool) PCROSS (t':real^N->bool)`; + `x:real^M`; `y:real^N`] PASTECART_IN_INTERIOR_SUBTOPOLOGY) THEN + ASM_REWRITE_TAC[SUBSET; FORALL_PASTECART; PASTECART_IN_PCROSS] THEN + MESON_TAC[]);; + +let INTERIOR_PCROSS = prove + (`!s:real^M->bool t:real^N->bool. + interior (s PCROSS t) = (interior s) PCROSS (interior t)`, + REPEAT GEN_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL + [REWRITE_TAC[SUBSET; FORALL_PASTECART; PASTECART_IN_PCROSS] THEN + MAP_EVERY X_GEN_TAC [`x:real^M`; `y:real^N`] THEN DISCH_TAC THEN + MP_TAC(ISPECL [`(:real^M)`; `(:real^N)`; + `interior((s:real^M->bool) PCROSS (t:real^N->bool))`; + `x:real^M`; `y:real^N`] PASTECART_IN_INTERIOR_SUBTOPOLOGY) THEN + REWRITE_TAC[UNIV_PCROSS_UNIV; SUBTOPOLOGY_UNIV; GSYM OPEN_IN] THEN + ASM_REWRITE_TAC[OPEN_INTERIOR] THEN STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o MATCH_MP (MESON[INTERIOR_SUBSET; SUBSET_TRANS] + `s SUBSET interior t ==> s SUBSET t`)) THEN + REWRITE_TAC[SUBSET_PCROSS] THEN + ASM_MESON_TAC[NOT_IN_EMPTY; INTERIOR_MAXIMAL; SUBSET]; + MATCH_MP_TAC INTERIOR_MAXIMAL THEN + SIMP_TAC[OPEN_PCROSS; OPEN_INTERIOR; PCROSS_MONO; INTERIOR_SUBSET]]);; + +let LIM_PASTECART = prove + (`!net f:A->real^M g:A->real^N. + (f --> a) net /\ (g --> b) net + ==> ((\x. pastecart (f x) (g x)) --> pastecart a b) net`, + REPEAT GEN_TAC THEN REWRITE_TAC[LIM] THEN + ASM_CASES_TAC `trivial_limit(net:(A)net)` THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[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(MP_TAC o MATCH_MP NET_DILEMMA) THEN + MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC THEN MATCH_MP_TAC MONO_AND THEN + REWRITE_TAC[] THEN MATCH_MP_TAC MONO_FORALL THEN GEN_TAC THEN + MATCH_MP_TAC MONO_IMP THEN REWRITE_TAC[] THEN + REWRITE_TAC[dist; PASTECART_SUB] THEN + MATCH_MP_TAC(REAL_ARITH + `z <= x + y ==> x < e / &2 /\ y < e / &2 ==> z < e`) THEN + REWRITE_TAC[NORM_PASTECART_LE]);; + +let LIM_PASTECART_EQ = prove + (`!net f:A->real^M g:A->real^N. + ((\x. pastecart (f x) (g x)) --> pastecart a b) net <=> + (f --> a) net /\ (g --> b) net`, + REPEAT GEN_TAC THEN EQ_TAC THEN REWRITE_TAC[LIM_PASTECART] THEN + REPEAT STRIP_TAC THENL + [FIRST_ASSUM(MP_TAC o ISPEC `fstcart:real^(M,N)finite_sum->real^M` o + MATCH_MP (REWRITE_RULE[IMP_CONJ] LIM_LINEAR)) THEN + REWRITE_TAC[LINEAR_FSTCART; FSTCART_PASTECART; ETA_AX]; + FIRST_ASSUM(MP_TAC o ISPEC `sndcart:real^(M,N)finite_sum->real^N` o + MATCH_MP (REWRITE_RULE[IMP_CONJ] LIM_LINEAR)) THEN + REWRITE_TAC[LINEAR_SNDCART; SNDCART_PASTECART; ETA_AX]]);; + +let CONTINUOUS_PASTECART = prove + (`!net f:A->real^M g:A->real^N. + f continuous net /\ g continuous net + ==> (\x. pastecart (f x) (g x)) continuous net`, + REWRITE_TAC[continuous; LIM_PASTECART]);; + +let CONTINUOUS_ON_PASTECART = prove + (`!f:real^M->real^N g:real^M->real^P s. + f continuous_on s /\ g continuous_on s + ==> (\x. pastecart (f x) (g x)) continuous_on s`, + SIMP_TAC[CONTINUOUS_ON; LIM_PASTECART]);; + +let CONNECTED_PCROSS = prove + (`!s:real^M->bool t:real^N->bool. + connected s /\ connected t + ==> connected (s PCROSS t)`, + REPEAT GEN_TAC THEN + REWRITE_TAC[PCROSS; CONNECTED_IFF_CONNECTED_COMPONENT] THEN + DISCH_TAC THEN REWRITE_TAC[FORALL_PASTECART; IN_ELIM_PASTECART_THM] THEN + MAP_EVERY X_GEN_TAC [`x1:real^M`; `y1:real^N`; `x2:real^M`; `y2:real^N`] THEN + STRIP_TAC THEN FIRST_X_ASSUM(CONJUNCTS_THEN2 + (MP_TAC o SPECL [`x1:real^M`; `x2:real^M`]) + (MP_TAC o SPECL [`y1:real^N`; `y2:real^N`])) THEN + ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM; connected_component] THEN + X_GEN_TAC `c2:real^N->bool` THEN STRIP_TAC THEN + X_GEN_TAC `c1:real^M->bool` THEN STRIP_TAC THEN + EXISTS_TAC + `IMAGE (\x:real^M. pastecart x y1) c1 UNION + IMAGE (\y:real^N. pastecart x2 y) c2` THEN + REWRITE_TAC[IN_UNION] THEN REPEAT CONJ_TAC THENL + [MATCH_MP_TAC CONNECTED_UNION THEN + ASM_SIMP_TAC[CONNECTED_CONTINUOUS_IMAGE; CONTINUOUS_ON_PASTECART; + CONTINUOUS_ON_CONST; CONTINUOUS_ON_ID] THEN + REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; IN_INTER; EXISTS_IN_IMAGE] THEN + EXISTS_TAC `x2:real^M` THEN ASM SET_TAC[]; + REWRITE_TAC[SUBSET; IN_UNION; FORALL_AND_THM; FORALL_IN_IMAGE; + TAUT `a \/ b ==> c <=> (a ==> c) /\ (b ==> c)`] THEN + ASM SET_TAC[]; + ASM SET_TAC[]; + ASM SET_TAC[]]);; + +let CONNECTED_PCROSS_EQ = prove + (`!s:real^M->bool t:real^N->bool. + connected (s PCROSS t) <=> + s = {} \/ t = {} \/ connected s /\ connected t`, + REPEAT GEN_TAC THEN + ASM_CASES_TAC `s:real^M->bool = {}` THEN ASM_REWRITE_TAC[NOT_IN_EMPTY] THEN + ASM_CASES_TAC `t:real^N->bool = {}` THEN ASM_REWRITE_TAC[NOT_IN_EMPTY] THEN + REWRITE_TAC[PCROSS_EMPTY; CONNECTED_EMPTY] THEN + EQ_TAC THEN SIMP_TAC[CONNECTED_PCROSS] THEN + REWRITE_TAC[PCROSS] THEN REPEAT STRIP_TAC THENL + [SUBGOAL_THEN `connected (IMAGE fstcart + {pastecart (x:real^M) (y:real^N) | x IN s /\ y IN t})` + MP_TAC THENL [MATCH_MP_TAC CONNECTED_CONTINUOUS_IMAGE; ALL_TAC]; + SUBGOAL_THEN `connected (IMAGE sndcart + {pastecart (x:real^M) (y:real^N) | x IN s /\ y IN t})` + MP_TAC THENL [MATCH_MP_TAC CONNECTED_CONTINUOUS_IMAGE; ALL_TAC]] THEN + ASM_SIMP_TAC[LINEAR_CONTINUOUS_ON; LINEAR_FSTCART; LINEAR_SNDCART] THEN + MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN + REWRITE_TAC[EXTENSION; IN_IMAGE; EXISTS_PASTECART; IN_ELIM_PASTECART_THM; + FSTCART_PASTECART; SNDCART_PASTECART] THEN + ASM SET_TAC[]);; + +let CLOSURE_PCROSS = prove + (`!s:real^M->bool t:real^N->bool. + closure (s PCROSS t) = (closure s) PCROSS (closure t)`, + REWRITE_TAC[EXTENSION; PCROSS; FORALL_PASTECART] THEN REPEAT GEN_TAC THEN + REWRITE_TAC[CLOSURE_APPROACHABLE; EXISTS_PASTECART; FORALL_PASTECART] THEN + REWRITE_TAC[IN_ELIM_PASTECART_THM; PASTECART_INJ] THEN + REWRITE_TAC[FSTCART_PASTECART; SNDCART_PASTECART] THEN + REWRITE_TAC[dist; PASTECART_SUB] THEN EQ_TAC THENL + [MESON_TAC[NORM_LE_PASTECART; REAL_LET_TRANS]; 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_MESON_TAC[REAL_HALF; NORM_PASTECART_LE; REAL_ARITH + `z <= x + y /\ x < e / &2 /\ y < e / &2 ==> z < e`]);; + +let LIMPT_PCROSS = prove + (`!s:real^M->bool t:real^N->bool x y. + x limit_point_of s /\ y limit_point_of t + ==> (pastecart x y) limit_point_of (s PCROSS t)`, + REPEAT GEN_TAC THEN + REWRITE_TAC[PCROSS; LIMPT_APPROACHABLE; EXISTS_PASTECART] THEN + REWRITE_TAC[IN_ELIM_PASTECART_THM; PASTECART_INJ; dist; PASTECART_SUB] 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_MESON_TAC[REAL_HALF; NORM_PASTECART_LE; REAL_ARITH + `z <= x + y /\ x < e / &2 /\ y < e / &2 ==> z < e`]);; + +(* ------------------------------------------------------------------------- *) +(* Hence some useful properties follow quite easily. *) +(* ------------------------------------------------------------------------- *) + +let CONNECTED_SCALING = prove + (`!s:real^N->bool c. connected s ==> connected (IMAGE (\x. c % x) s)`, + REPEAT STRIP_TAC THEN + MATCH_MP_TAC CONNECTED_CONTINUOUS_IMAGE THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC CONTINUOUS_AT_IMP_CONTINUOUS_ON THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC LINEAR_CONTINUOUS_AT THEN + REWRITE_TAC[linear] THEN CONJ_TAC THEN VECTOR_ARITH_TAC);; + +let CONNECTED_NEGATIONS = prove + (`!s:real^N->bool. connected s ==> connected (IMAGE (--) s)`, + REPEAT STRIP_TAC THEN + MATCH_MP_TAC CONNECTED_CONTINUOUS_IMAGE THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC CONTINUOUS_AT_IMP_CONTINUOUS_ON THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC LINEAR_CONTINUOUS_AT THEN + REWRITE_TAC[linear] THEN CONJ_TAC THEN VECTOR_ARITH_TAC);; + +let CONNECTED_SUMS = prove + (`!s t:real^N->bool. + connected s /\ connected t ==> connected {x + y | x IN s /\ y IN t}`, + REPEAT GEN_TAC THEN DISCH_THEN(MP_TAC o MATCH_MP CONNECTED_PCROSS) THEN + DISCH_THEN(MP_TAC o ISPEC + `\z. (fstcart z + sndcart z:real^N)` o + MATCH_MP (REWRITE_RULE[IMP_CONJ_ALT] CONNECTED_CONTINUOUS_IMAGE)) THEN + SIMP_TAC[CONTINUOUS_ON_ADD; LINEAR_CONTINUOUS_ON; LINEAR_FSTCART; + LINEAR_SNDCART; PCROSS] THEN + MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN + REWRITE_TAC[EXTENSION; IN_IMAGE; IN_ELIM_THM; EXISTS_PASTECART] THEN + REWRITE_TAC[PASTECART_INJ; FSTCART_PASTECART; SNDCART_PASTECART] THEN + MESON_TAC[]);; + +let COMPACT_SCALING = prove + (`!s:real^N->bool c. compact s ==> compact (IMAGE (\x. c % x) s)`, + REPEAT STRIP_TAC THEN + MATCH_MP_TAC COMPACT_CONTINUOUS_IMAGE THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC CONTINUOUS_AT_IMP_CONTINUOUS_ON THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC LINEAR_CONTINUOUS_AT THEN + REWRITE_TAC[linear] THEN CONJ_TAC THEN VECTOR_ARITH_TAC);; + +let COMPACT_NEGATIONS = prove + (`!s:real^N->bool. compact s ==> compact (IMAGE (--) s)`, + REPEAT STRIP_TAC THEN + MATCH_MP_TAC COMPACT_CONTINUOUS_IMAGE THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC CONTINUOUS_AT_IMP_CONTINUOUS_ON THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC LINEAR_CONTINUOUS_AT THEN + REWRITE_TAC[linear] THEN CONJ_TAC THEN VECTOR_ARITH_TAC);; + +let COMPACT_SUMS = prove + (`!s:real^N->bool t. + compact s /\ compact t ==> compact {x + y | x IN s /\ y IN t}`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN `{x + y | x IN s /\ y IN t} = + IMAGE (\z. fstcart z + sndcart z :real^N) (s PCROSS t)` + SUBST1_TAC THENL + [REWRITE_TAC[EXTENSION; IN_ELIM_THM; IN_IMAGE; PCROSS] THEN + GEN_TAC THEN EQ_TAC THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + ASM_MESON_TAC[FSTCART_PASTECART; SNDCART_PASTECART; PASTECART_FST_SND]; + ALL_TAC] THEN + MATCH_MP_TAC COMPACT_CONTINUOUS_IMAGE THEN + ASM_SIMP_TAC[COMPACT_PCROSS] THEN + MATCH_MP_TAC CONTINUOUS_AT_IMP_CONTINUOUS_ON THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC LINEAR_CONTINUOUS_AT THEN + REWRITE_TAC[linear; FSTCART_ADD; FSTCART_CMUL; SNDCART_ADD; + SNDCART_CMUL] THEN + CONJ_TAC THEN VECTOR_ARITH_TAC);; + +let COMPACT_DIFFERENCES = prove + (`!s:real^N->bool t. + compact s /\ compact t ==> compact {x - y | x IN s /\ y IN t}`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN `{x - y | x:real^N IN s /\ y IN t} = + {x + y | x IN s /\ y IN (IMAGE (--) t)}` + (fun th -> ASM_SIMP_TAC[th; COMPACT_SUMS; COMPACT_NEGATIONS]) THEN + REWRITE_TAC[EXTENSION; IN_ELIM_THM; IN_IMAGE] THEN + ONCE_REWRITE_TAC[VECTOR_ARITH `(x:real^N = --y) <=> (y = --x)`] THEN + SIMP_TAC[VECTOR_SUB; GSYM CONJ_ASSOC; UNWIND_THM2] THEN + MESON_TAC[VECTOR_NEG_NEG]);; + +let COMPACT_TRANSLATION_EQ = prove + (`!a s. compact (IMAGE (\x:real^N. a + x) s) <=> compact s`, + REWRITE_TAC[COMPACT_EQ_HEINE_BOREL] THEN GEOM_TRANSLATE_TAC[]);; + +let COMPACT_TRANSLATION = prove + (`!s a:real^N. compact s ==> compact (IMAGE (\x. a + x) s)`, + REWRITE_TAC[COMPACT_TRANSLATION_EQ]);; + +add_translation_invariants [COMPACT_TRANSLATION_EQ];; + +let COMPACT_AFFINITY = prove + (`!s a:real^N c. + compact s ==> compact (IMAGE (\x. a + c % x) s)`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN `(\x:real^N. a + c % x) = (\x. a + x) o (\x. c % x)` + SUBST1_TAC THENL [REWRITE_TAC[o_DEF]; ALL_TAC] THEN + ASM_SIMP_TAC[IMAGE_o; COMPACT_TRANSLATION; COMPACT_SCALING]);; + +(* ------------------------------------------------------------------------- *) +(* Hence we get the following. *) +(* ------------------------------------------------------------------------- *) + +let COMPACT_SUP_MAXDISTANCE = prove + (`!s:real^N->bool. + compact s /\ ~(s = {}) + ==> ?x y. x IN s /\ y IN s /\ + !u v. u IN s /\ v IN s ==> norm(u - v) <= norm(x - y)`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`{x - y:real^N | x IN s /\ y IN s}`; `vec 0:real^N`] + DISTANCE_ATTAINS_SUP) THEN + ANTS_TAC THENL + [ASM_SIMP_TAC[COMPACT_DIFFERENCES] THEN + REWRITE_TAC[EXTENSION; IN_ELIM_THM; NOT_IN_EMPTY] THEN + ASM_MESON_TAC[MEMBER_NOT_EMPTY]; + REWRITE_TAC[IN_ELIM_THM; dist; VECTOR_SUB_RZERO; VECTOR_SUB_LZERO; + NORM_NEG] THEN + MESON_TAC[]]);; + +(* ------------------------------------------------------------------------- *) +(* We can state this in terms of diameter of a set. *) +(* ------------------------------------------------------------------------- *) + +let diameter = new_definition + `diameter s = + if s = {} then &0 + else sup {norm(x - y) | x IN s /\ y IN s}`;; + +let DIAMETER_BOUNDED = prove + (`!s. bounded s + ==> (!x:real^N y. x IN s /\ y IN s ==> norm(x - y) <= diameter s) /\ + (!d. &0 <= d /\ d < diameter s + ==> ?x y. x IN s /\ y IN s /\ norm(x - y) > d)`, + GEN_TAC THEN DISCH_TAC THEN + ASM_CASES_TAC `s:real^N->bool = {}` THEN + ASM_REWRITE_TAC[diameter; NOT_IN_EMPTY; REAL_LET_ANTISYM] THEN + MP_TAC(SPEC `{norm(x - y:real^N) | x IN s /\ y IN s}` SUP) THEN + ABBREV_TAC `b = sup {norm(x - y:real^N) | x IN s /\ y IN s}` THEN + REWRITE_TAC[EXTENSION; IN_ELIM_THM] THEN + REWRITE_TAC[NOT_IN_EMPTY; real_gt] THEN ANTS_TAC THENL + [CONJ_TAC THENL [ASM_MESON_TAC[MEMBER_NOT_EMPTY]; ALL_TAC]; + MESON_TAC[REAL_NOT_LE]] THEN + SIMP_TAC[VECTOR_SUB; LEFT_IMP_EXISTS_THM] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [bounded]) THEN + MESON_TAC[REAL_ARITH `x <= y + z /\ y <= b /\ z<= b ==> x <= b + b`; + NORM_TRIANGLE; NORM_NEG]);; + +let DIAMETER_BOUNDED_BOUND = prove + (`!s x y. bounded s /\ x IN s /\ y IN s ==> norm(x - y) <= diameter s`, + MESON_TAC[DIAMETER_BOUNDED]);; + +let DIAMETER_COMPACT_ATTAINED = prove + (`!s:real^N->bool. + compact s /\ ~(s = {}) + ==> ?x y. x IN s /\ y IN s /\ (norm(x - y) = diameter s)`, + GEN_TAC THEN DISCH_TAC THEN + FIRST_ASSUM(MP_TAC o MATCH_MP COMPACT_SUP_MAXDISTANCE) THEN + REPEAT(MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC) THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + MP_TAC(SPEC `s:real^N->bool` DIAMETER_BOUNDED) THEN + RULE_ASSUM_TAC(REWRITE_RULE[COMPACT_EQ_BOUNDED_CLOSED]) THEN + ASM_REWRITE_TAC[real_gt] THEN STRIP_TAC THEN + REWRITE_TAC[GSYM REAL_LE_ANTISYM] THEN + ASM_MESON_TAC[NORM_POS_LE; REAL_NOT_LT]);; + +let DIAMETER_TRANSLATION = prove + (`!a s. diameter (IMAGE (\x. a + x) s) = diameter s`, + REWRITE_TAC[diameter] THEN GEOM_TRANSLATE_TAC[]);; + +add_translation_invariants [DIAMETER_TRANSLATION];; + +let DIAMETER_LINEAR_IMAGE = prove + (`!f:real^M->real^N s. + linear f /\ (!x. norm(f x) = norm x) + ==> diameter(IMAGE f s) = diameter s`, + REWRITE_TAC[diameter] THEN + REPEAT STRIP_TAC THEN REWRITE_TAC[diameter; IMAGE_EQ_EMPTY] THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN AP_TERM_TAC THEN + REWRITE_TAC[EXTENSION; IN_ELIM_THM] THEN + REWRITE_TAC[GSYM CONJ_ASSOC; RIGHT_EXISTS_AND_THM; EXISTS_IN_IMAGE] THEN + ASM_MESON_TAC[LINEAR_SUB]);; + +add_linear_invariants [DIAMETER_LINEAR_IMAGE];; + +let DIAMETER_EMPTY = prove + (`diameter {} = &0`, + REWRITE_TAC[diameter]);; + +let DIAMETER_SING = prove + (`!a. diameter {a} = &0`, + REWRITE_TAC[diameter; NOT_INSERT_EMPTY; IN_SING] THEN + REWRITE_TAC[SET_RULE `{f x y | x = a /\ y = a} = {f a a }`] THEN + REWRITE_TAC[SUP_SING; VECTOR_SUB_REFL; NORM_0]);; + +let DIAMETER_POS_LE = prove + (`!s:real^N->bool. bounded s ==> &0 <= diameter s`, + REPEAT STRIP_TAC THEN REWRITE_TAC[diameter] THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[REAL_LE_REFL] THEN + MP_TAC(SPEC `{norm(x - y:real^N) | x IN s /\ y IN s}` SUP) THEN + REWRITE_TAC[FORALL_IN_GSPEC] THEN ANTS_TAC THENL + [CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + FIRST_X_ASSUM(X_CHOOSE_TAC `B:real` o GEN_REWRITE_RULE I [BOUNDED_POS]) THEN + EXISTS_TAC `&2 * B` THEN + ASM_SIMP_TAC[NORM_ARITH + `norm x <= B /\ norm y <= B ==> norm(x - y) <= &2 * B`]; + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN + DISCH_THEN(X_CHOOSE_TAC `a:real^N`) THEN + DISCH_THEN(MP_TAC o SPECL [`a:real^N`; `a:real^N`] o CONJUNCT1) THEN + ASM_REWRITE_TAC[VECTOR_SUB_REFL; NORM_0]]);; + +let DIAMETER_SUBSET = prove + (`!s t:real^N->bool. s SUBSET t /\ bounded t ==> diameter s <= diameter t`, + REPEAT STRIP_TAC THEN + ASM_CASES_TAC `s:real^N->bool = {}` THEN + ASM_SIMP_TAC[DIAMETER_EMPTY; DIAMETER_POS_LE] THEN + ASM_REWRITE_TAC[diameter] THEN + COND_CASES_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + MATCH_MP_TAC REAL_SUP_LE_SUBSET THEN + REPEAT(CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC]) THEN + REWRITE_TAC[FORALL_IN_GSPEC] THEN + FIRST_X_ASSUM(X_CHOOSE_TAC `B:real` o GEN_REWRITE_RULE I [BOUNDED_POS]) THEN + EXISTS_TAC `&2 * B` THEN + ASM_SIMP_TAC[NORM_ARITH + `norm x <= B /\ norm y <= B ==> norm(x - y) <= &2 * B`]);; + +let DIAMETER_CLOSURE = prove + (`!s:real^N->bool. bounded s ==> diameter(closure s) = diameter s`, + REWRITE_TAC[GSYM REAL_LE_ANTISYM] THEN REPEAT STRIP_TAC THEN + ASM_SIMP_TAC[DIAMETER_SUBSET; BOUNDED_CLOSURE; CLOSURE_SUBSET] THEN + REWRITE_TAC[GSYM REAL_NOT_LT] THEN ONCE_REWRITE_TAC[GSYM REAL_SUB_LT] THEN + DISCH_TAC THEN MP_TAC(ISPEC `closure s:real^N->bool` DIAMETER_BOUNDED) THEN + ABBREV_TAC `d = diameter(closure s) - diameter(s:real^N->bool)` THEN + ASM_SIMP_TAC[BOUNDED_CLOSURE] THEN DISCH_THEN(MP_TAC o + SPEC `diameter(closure(s:real^N->bool)) - d / &2` o CONJUNCT2) THEN + REWRITE_TAC[NOT_IMP; GSYM CONJ_ASSOC; NOT_EXISTS_THM] THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP DIAMETER_POS_LE) THEN + REPEAT(CONJ_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC]) THEN + MAP_EVERY X_GEN_TAC [`x:real^N`; `y:real^N`] THEN + REWRITE_TAC[CLOSURE_APPROACHABLE; CONJ_ASSOC; AND_FORALL_THM] THEN + DISCH_THEN(CONJUNCTS_THEN2 (MP_TAC o SPEC `d / &4`) ASSUME_TAC) THEN + ASM_REWRITE_TAC[REAL_ARITH `&0 < d / &4 <=> &0 < d`] THEN + DISCH_THEN(CONJUNCTS_THEN2 + (X_CHOOSE_THEN `u:real^N` (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) + (X_CHOOSE_THEN `v:real^N` (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC))) THEN + FIRST_ASSUM(MP_TAC o MATCH_MP DIAMETER_BOUNDED) THEN + DISCH_THEN(MP_TAC o SPECL [`u:real^N`; `v:real^N`] o CONJUNCT1) THEN + ASM_REWRITE_TAC[] THEN REPEAT(POP_ASSUM MP_TAC) THEN NORM_ARITH_TAC);; + +let DIAMETER_SUBSET_CBALL_NONEMPTY = prove + (`!s:real^N->bool. + bounded s /\ ~(s = {}) ==> ?z. z IN s /\ s SUBSET cball(z,diameter s)`, + REPEAT STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `a:real^N` THEN + DISCH_TAC THEN ASM_REWRITE_TAC[SUBSET] THEN X_GEN_TAC `b:real^N` THEN + DISCH_TAC THEN REWRITE_TAC[IN_CBALL; dist] THEN + ASM_MESON_TAC[DIAMETER_BOUNDED]);; + +let DIAMETER_SUBSET_CBALL = prove + (`!s:real^N->bool. bounded s ==> ?z. s SUBSET cball(z,diameter s)`, + REPEAT STRIP_TAC THEN ASM_CASES_TAC `s:real^N->bool = {}` THEN + ASM_MESON_TAC[DIAMETER_SUBSET_CBALL_NONEMPTY; EMPTY_SUBSET]);; + +let DIAMETER_EQ_0 = prove + (`!s:real^N->bool. + bounded s ==> (diameter s = &0 <=> s = {} \/ ?a. s = {a})`, + REPEAT STRIP_TAC THEN EQ_TAC THEN STRIP_TAC THEN + ASM_REWRITE_TAC[DIAMETER_EMPTY; DIAMETER_SING] THEN + REWRITE_TAC[SET_RULE + `s = {} \/ (?a. s = {a}) <=> !a b. a IN s /\ b IN s ==> a = b`] THEN + MAP_EVERY X_GEN_TAC [`a:real^N`; `b:real^N`] THEN STRIP_TAC THEN + MP_TAC(ISPECL [`s:real^N->bool`; `a:real^N`; `b:real^N`] + DIAMETER_BOUNDED_BOUND) THEN + ASM_REWRITE_TAC[] THEN NORM_ARITH_TAC);; + +let DIAMETER_LE = prove + (`!s:real^N->bool. + (~(s = {}) \/ &0 <= d) /\ + (!x y. x IN s /\ y IN s ==> norm(x - y) <= d) ==> diameter s <= d`, + GEN_TAC THEN REWRITE_TAC[diameter] THEN + COND_CASES_TAC THEN ASM_SIMP_TAC[] THEN + STRIP_TAC THEN MATCH_MP_TAC REAL_SUP_LE THEN + CONJ_TAC THENL [ASM SET_TAC[]; ASM_SIMP_TAC[FORALL_IN_GSPEC]]);; + +let DIAMETER_CBALL = prove + (`!a:real^N r. diameter(cball(a,r)) = if r < &0 then &0 else &2 * r`, + REPEAT GEN_TAC THEN COND_CASES_TAC THENL + [ASM_MESON_TAC[CBALL_EQ_EMPTY; DIAMETER_EMPTY]; ALL_TAC] THEN + RULE_ASSUM_TAC(REWRITE_RULE[REAL_NOT_LT]) THEN + REWRITE_TAC[GSYM REAL_LE_ANTISYM] THEN CONJ_TAC THENL + [MATCH_MP_TAC DIAMETER_LE THEN + ASM_SIMP_TAC[CBALL_EQ_EMPTY; REAL_LE_MUL; REAL_POS; REAL_NOT_LT] THEN + REWRITE_TAC[IN_CBALL] THEN NORM_ARITH_TAC; + MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `norm((a + r % basis 1) - (a - r % basis 1):real^N)` THEN + CONJ_TAC THENL + [REWRITE_TAC[VECTOR_ARITH `(a + r % b) - (a - r % b:real^N) = + (&2 * r) % b`] THEN + SIMP_TAC[NORM_MUL; NORM_BASIS; DIMINDEX_GE_1; LE_REFL] THEN + ASM_REAL_ARITH_TAC; + MATCH_MP_TAC DIAMETER_BOUNDED_BOUND THEN + REWRITE_TAC[BOUNDED_CBALL; IN_CBALL] THEN + REWRITE_TAC[NORM_ARITH + `dist(a:real^N,a + b) = norm b /\ dist(a,a - b) = norm b`] THEN + SIMP_TAC[NORM_MUL; NORM_BASIS; DIMINDEX_GE_1; LE_REFL] THEN + ASM_REAL_ARITH_TAC]]);; + +let DIAMETER_BALL = prove + (`!a:real^N r. diameter(ball(a,r)) = if r < &0 then &0 else &2 * r`, + REPEAT GEN_TAC THEN COND_CASES_TAC THENL + [ASM_SIMP_TAC[BALL_EMPTY; REAL_LT_IMP_LE; DIAMETER_EMPTY]; ALL_TAC] THEN + ASM_CASES_TAC `r = &0` THEN + ASM_SIMP_TAC[BALL_EMPTY; REAL_LE_REFL; DIAMETER_EMPTY; REAL_MUL_RZERO] THEN + MATCH_MP_TAC EQ_TRANS THEN + EXISTS_TAC `diameter(cball(a:real^N,r))` THEN CONJ_TAC THENL + [SUBGOAL_THEN `&0 < r` ASSUME_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN + ASM_SIMP_TAC[GSYM CLOSURE_BALL; DIAMETER_CLOSURE; BOUNDED_BALL]; + ASM_SIMP_TAC[DIAMETER_CBALL]]);; + +let LEBESGUE_COVERING_LEMMA = prove + (`!s:real^N->bool c. + compact s /\ ~(c = {}) /\ s SUBSET UNIONS c /\ (!b. b IN c ==> open b) + ==> ?d. &0 < d /\ + !t. t SUBSET s /\ diameter t <= d + ==> ?b. b IN c /\ t SUBSET b`, + REPEAT STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o MATCH_MP HEINE_BOREL_LEMMA) THEN + DISCH_THEN(MP_TAC o SPEC `c:(real^N->bool)->bool`) THEN ASM_SIMP_TAC[] THEN + ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN X_GEN_TAC `e:real` THEN + STRIP_TAC THEN EXISTS_TAC `e / &2` THEN ASM_REWRITE_TAC[REAL_HALF] THEN + X_GEN_TAC `t:real^N->bool` THEN STRIP_TAC THEN + ASM_CASES_TAC `t:real^N->bool = {}` THENL [ASM SET_TAC[]; ALL_TAC] THEN + MP_TAC(ISPEC `t:real^N->bool` DIAMETER_SUBSET_CBALL_NONEMPTY) THEN + ANTS_TAC THENL + [ASM_MESON_TAC[BOUNDED_SUBSET; COMPACT_IMP_BOUNDED]; ALL_TAC] THEN + DISCH_THEN(X_CHOOSE_THEN `x:real^N` STRIP_ASSUME_TAC) THEN + FIRST_X_ASSUM(MP_TAC o SPEC `x:real^N`) THEN + ANTS_TAC THENL [ASM SET_TAC[]; MATCH_MP_TAC MONO_EXISTS] THEN + X_GEN_TAC `b:real^N->bool` THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC SUBSET_TRANS THEN + EXISTS_TAC `cball(x:real^N,diameter(t:real^N->bool))` THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC SUBSET_TRANS THEN + EXISTS_TAC `ball(x:real^N,e)` THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[SUBSET; IN_CBALL; IN_BALL] THEN + MAP_EVERY UNDISCH_TAC [`&0 < e`; `diameter(t:real^N->bool) <= e / &2`] THEN + NORM_ARITH_TAC);; + +(* ------------------------------------------------------------------------- *) +(* Related results with closure as the conclusion. *) +(* ------------------------------------------------------------------------- *) + +let CLOSED_SCALING = prove + (`!s:real^N->bool c. closed s ==> closed (IMAGE (\x. c % x) s)`, + REPEAT GEN_TAC THEN + ASM_CASES_TAC `s :real^N->bool = {}` THEN + ASM_REWRITE_TAC[CLOSED_EMPTY; IMAGE_CLAUSES] THEN + ASM_CASES_TAC `c = &0` THENL + [SUBGOAL_THEN `IMAGE (\x:real^N. c % x) s = {(vec 0)}` + (fun th -> REWRITE_TAC[th; CLOSED_SING]) THEN + ASM_REWRITE_TAC[EXTENSION; IN_IMAGE; IN_SING; VECTOR_MUL_LZERO] THEN + ASM_MESON_TAC[MEMBER_NOT_EMPTY]; + ALL_TAC] THEN + REWRITE_TAC[CLOSED_SEQUENTIAL_LIMITS; IN_IMAGE; SKOLEM_THM] THEN + STRIP_TAC THEN X_GEN_TAC `x:num->real^N` THEN X_GEN_TAC `l:real^N` THEN + DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN + DISCH_THEN(X_CHOOSE_THEN `y:num->real^N` MP_TAC) THEN + REWRITE_TAC[FORALL_AND_THM] THEN STRIP_TAC THEN + EXISTS_TAC `inv(c) % l :real^N` THEN + ASM_SIMP_TAC[VECTOR_MUL_ASSOC; REAL_MUL_RINV; VECTOR_MUL_LID] THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN EXISTS_TAC `\n:num. inv(c) % x n:real^N` THEN + ASM_REWRITE_TAC[] THEN CONJ_TAC THENL + [ASM_SIMP_TAC[VECTOR_MUL_ASSOC; REAL_MUL_LINV; VECTOR_MUL_LID]; + MATCH_MP_TAC LIM_CMUL THEN + FIRST_ASSUM(fun th -> REWRITE_TAC[SYM(SPEC_ALL th)]) THEN + ASM_REWRITE_TAC[ETA_AX]]);; + +let CLOSED_NEGATIONS = prove + (`!s:real^N->bool. closed s ==> closed (IMAGE (--) s)`, + REPEAT GEN_TAC THEN + SUBGOAL_THEN `IMAGE (--) s = IMAGE (\x:real^N. --(&1) % x) s` + SUBST1_TAC THEN SIMP_TAC[CLOSED_SCALING] THEN + REWRITE_TAC[VECTOR_ARITH `--(&1) % x = --x`] THEN REWRITE_TAC[ETA_AX]);; + +let COMPACT_CLOSED_SUMS = prove + (`!s:real^N->bool t. + compact s /\ closed t ==> closed {x + y | x IN s /\ y IN t}`, + REPEAT GEN_TAC THEN + REWRITE_TAC[compact; IN_ELIM_THM; CLOSED_SEQUENTIAL_LIMITS] THEN + STRIP_TAC THEN X_GEN_TAC `f:num->real^N` THEN X_GEN_TAC `l:real^N` THEN + REWRITE_TAC[SKOLEM_THM; FORALL_AND_THM] THEN + DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN + DISCH_THEN(X_CHOOSE_THEN `a:num->real^N` MP_TAC) THEN + DISCH_THEN(X_CHOOSE_THEN `b:num->real^N` STRIP_ASSUME_TAC) THEN + FIRST_X_ASSUM(MP_TAC o check(is_imp o concl) o SPEC `a:num->real^N`) THEN + ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `la:real^N` (X_CHOOSE_THEN `sub:num->num` + STRIP_ASSUME_TAC)) THEN + MAP_EVERY EXISTS_TAC [`la:real^N`; `l - la:real^N`] THEN + ASM_REWRITE_TAC[VECTOR_ARITH `a + (b - a) = b:real^N`] THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN + EXISTS_TAC `\n. (f o (sub:num->num)) n - (a o sub) n:real^N` THEN + CONJ_TAC THENL [ASM_REWRITE_TAC[VECTOR_ADD_SUB; o_THM]; ALL_TAC] THEN + MATCH_MP_TAC LIM_SUB THEN ASM_SIMP_TAC[LIM_SUBSEQUENCE; ETA_AX]);; + +let CLOSED_COMPACT_SUMS = prove + (`!s:real^N->bool t. + closed s /\ compact t ==> closed {x + y | x IN s /\ y IN t}`, + REPEAT GEN_TAC THEN + SUBGOAL_THEN `{x + y:real^N | x IN s /\ y IN t} = {y + x | y IN t /\ x IN s}` + SUBST1_TAC THEN SIMP_TAC[COMPACT_CLOSED_SUMS] THEN + REWRITE_TAC[EXTENSION; IN_ELIM_THM] THEN MESON_TAC[VECTOR_ADD_SYM]);; + +let COMPACT_CLOSED_DIFFERENCES = prove + (`!s:real^N->bool t. + compact s /\ closed t ==> closed {x - y | x IN s /\ y IN t}`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN `{x - y | x:real^N IN s /\ y IN t} = + {x + y | x IN s /\ y IN (IMAGE (--) t)}` + (fun th -> ASM_SIMP_TAC[th; COMPACT_CLOSED_SUMS; CLOSED_NEGATIONS]) THEN + REWRITE_TAC[EXTENSION; IN_ELIM_THM; IN_IMAGE] THEN + ONCE_REWRITE_TAC[VECTOR_ARITH `(x:real^N = --y) <=> (y = --x)`] THEN + SIMP_TAC[VECTOR_SUB; GSYM CONJ_ASSOC; UNWIND_THM2] THEN + MESON_TAC[VECTOR_NEG_NEG]);; + +let CLOSED_COMPACT_DIFFERENCES = prove + (`!s:real^N->bool t. + closed s /\ compact t ==> closed {x - y | x IN s /\ y IN t}`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN `{x - y | x:real^N IN s /\ y IN t} = + {x + y | x IN s /\ y IN (IMAGE (--) t)}` + (fun th -> ASM_SIMP_TAC[th; CLOSED_COMPACT_SUMS; COMPACT_NEGATIONS]) THEN + REWRITE_TAC[EXTENSION; IN_ELIM_THM; IN_IMAGE] THEN + ONCE_REWRITE_TAC[VECTOR_ARITH `(x:real^N = --y) <=> (y = --x)`] THEN + SIMP_TAC[VECTOR_SUB; GSYM CONJ_ASSOC; UNWIND_THM2] THEN + MESON_TAC[VECTOR_NEG_NEG]);; + +let CLOSED_TRANSLATION_EQ = prove + (`!a s. closed (IMAGE (\x:real^N. a + x) s) <=> closed s`, + REWRITE_TAC[closed] THEN GEOM_TRANSLATE_TAC[]);; + +let CLOSED_TRANSLATION = prove + (`!s a:real^N. closed s ==> closed (IMAGE (\x. a + x) s)`, + REWRITE_TAC[CLOSED_TRANSLATION_EQ]);; + +add_translation_invariants [CLOSED_TRANSLATION_EQ];; + +let COMPLETE_TRANSLATION_EQ = prove + (`!a s. complete(IMAGE (\x:real^N. a + x) s) <=> complete s`, + REWRITE_TAC[COMPLETE_EQ_CLOSED; CLOSED_TRANSLATION_EQ]);; + +add_translation_invariants [COMPLETE_TRANSLATION_EQ];; + +let TRANSLATION_UNIV = prove + (`!a. IMAGE (\x. a + x) (:real^N) = (:real^N)`, + CONV_TAC(ONCE_DEPTH_CONV SYM_CONV) THEN GEOM_TRANSLATE_TAC[]);; + +let TRANSLATION_DIFF = prove + (`!s t:real^N->bool. + IMAGE (\x. a + x) (s DIFF t) = + (IMAGE (\x. a + x) s) DIFF (IMAGE (\x. a + x) t)`, + REWRITE_TAC[EXTENSION; IN_DIFF; IN_IMAGE] THEN + ONCE_REWRITE_TAC[VECTOR_ARITH `x:real^N = a + y <=> y = x - a`] THEN + REWRITE_TAC[UNWIND_THM2]);; + +let CLOSURE_TRANSLATION = prove + (`!a s. closure(IMAGE (\x:real^N. a + x) s) = IMAGE (\x. a + x) (closure s)`, + REWRITE_TAC[CLOSURE_INTERIOR] THEN GEOM_TRANSLATE_TAC[]);; + +add_translation_invariants [CLOSURE_TRANSLATION];; + +let FRONTIER_TRANSLATION = prove + (`!a s. frontier(IMAGE (\x:real^N. a + x) s) = IMAGE (\x. a + x) (frontier s)`, + REWRITE_TAC[frontier] THEN GEOM_TRANSLATE_TAC[]);; + +add_translation_invariants [FRONTIER_TRANSLATION];; + +(* ------------------------------------------------------------------------- *) +(* Separation between points and sets. *) +(* ------------------------------------------------------------------------- *) + +let SEPARATE_POINT_CLOSED = prove + (`!s a:real^N. + closed s /\ ~(a IN s) + ==> ?d. &0 < d /\ !x. x IN s ==> d <= dist(a,x)`, + REPEAT STRIP_TAC THEN + ASM_CASES_TAC `s:real^N->bool = {}` THENL + [EXISTS_TAC `&1` THEN ASM_REWRITE_TAC[NOT_IN_EMPTY; REAL_LT_01]; + ALL_TAC] THEN + MP_TAC(ISPECL [`s:real^N->bool`; `a:real^N`] DISTANCE_ATTAINS_INF) THEN + ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN X_GEN_TAC `b:real^N` THEN + STRIP_TAC THEN EXISTS_TAC `dist(a:real^N,b)` THEN + ASM_MESON_TAC[DIST_POS_LT]);; + +let SEPARATE_COMPACT_CLOSED = prove + (`!s t:real^N->bool. + compact s /\ closed t /\ s INTER t = {} + ==> ?d. &0 < d /\ !x y. x IN s /\ y IN t ==> d <= dist(x,y)`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`{x - y:real^N | x IN s /\ y IN t}`; `vec 0:real^N`] + SEPARATE_POINT_CLOSED) THEN + ASM_SIMP_TAC[COMPACT_CLOSED_DIFFERENCES; IN_ELIM_THM] THEN + REWRITE_TAC[VECTOR_ARITH `vec 0 = x - y <=> x = y`] THEN + ANTS_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + MATCH_MP_TAC MONO_EXISTS THEN SIMP_TAC[LEFT_IMP_EXISTS_THM] THEN + MESON_TAC[NORM_ARITH `dist(vec 0,x - y) = dist(x,y)`]);; + +let SEPARATE_CLOSED_COMPACT = prove + (`!s t:real^N->bool. + closed s /\ compact t /\ s INTER t = {} + ==> ?d. &0 < d /\ !x y. x IN s /\ y IN t ==> d <= dist(x,y)`, + ONCE_REWRITE_TAC[DIST_SYM; INTER_COMM] THEN + MESON_TAC[SEPARATE_COMPACT_CLOSED]);; + +(* ------------------------------------------------------------------------- *) +(* Representing sets as the union of a chain of compact sets. *) +(* ------------------------------------------------------------------------- *) + +let CLOSED_UNION_COMPACT_SUBSETS = prove + (`!s. closed s + ==> ?f:num->real^N->bool. + (!n. compact(f n)) /\ + (!n. (f n) SUBSET s) /\ + (!n. (f n) SUBSET f(n + 1)) /\ + UNIONS {f n | n IN (:num)} = s /\ + (!k. compact k /\ k SUBSET s + ==> ?N. !n. n >= N ==> k SUBSET (f n))`, + REPEAT STRIP_TAC THEN + EXISTS_TAC `\n. s INTER cball(vec 0:real^N,&n)` THEN + ASM_SIMP_TAC[INTER_SUBSET; COMPACT_CBALL; CLOSED_INTER_COMPACT] THEN + REPEAT CONJ_TAC THENL + [GEN_TAC THEN MATCH_MP_TAC(SET_RULE + `t SUBSET u ==> s INTER t SUBSET s INTER u`) THEN + REWRITE_TAC[SUBSET_BALLS; DIST_REFL; GSYM REAL_OF_NUM_ADD] THEN + REAL_ARITH_TAC; + REWRITE_TAC[EXTENSION; UNIONS_GSPEC; IN_ELIM_THM; IN_UNIV; IN_INTER] THEN + X_GEN_TAC `x:real^N` THEN REWRITE_TAC[IN_CBALL_0] THEN + MESON_TAC[REAL_ARCH_SIMPLE]; + X_GEN_TAC `k:real^N->bool` THEN SIMP_TAC[SUBSET_INTER] THEN + REPEAT STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o MATCH_MP COMPACT_IMP_BOUNDED) THEN DISCH_THEN + (MP_TAC o SPEC `vec 0:real^N` o MATCH_MP BOUNDED_SUBSET_CBALL) THEN + DISCH_THEN(X_CHOOSE_THEN `r:real` STRIP_ASSUME_TAC) THEN + MP_TAC(ISPEC `r:real` REAL_ARCH_SIMPLE) THEN MATCH_MP_TAC MONO_EXISTS THEN + X_GEN_TAC `N:num` THEN REWRITE_TAC[GSYM REAL_OF_NUM_GE] THEN + + REPEAT STRIP_TAC THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + SUBSET_TRANS)) THEN + REWRITE_TAC[SUBSET_BALLS; DIST_REFL] THEN ASM_REAL_ARITH_TAC]);; + +let OPEN_UNION_COMPACT_SUBSETS = prove + (`!s. open s + ==> ?f:num->real^N->bool. + (!n. compact(f n)) /\ + (!n. (f n) SUBSET s) /\ + (!n. (f n) SUBSET interior(f(n + 1))) /\ + UNIONS {f n | n IN (:num)} = s /\ + (!k. compact k /\ k SUBSET s + ==> ?N. !n. n >= N ==> k SUBSET (f n))`, + GEN_TAC THEN ASM_CASES_TAC `s:real^N->bool = {}` THENL + [DISCH_TAC THEN EXISTS_TAC `(\n. {}):num->real^N->bool` THEN + ASM_SIMP_TAC[EMPTY_SUBSET; SUBSET_EMPTY; COMPACT_EMPTY] THEN + REWRITE_TAC[EXTENSION; UNIONS_GSPEC; IN_ELIM_THM; NOT_IN_EMPTY]; + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN + DISCH_THEN(X_CHOOSE_TAC `a:real^N`) THEN STRIP_TAC] THEN + MATCH_MP_TAC(MESON[] + `(!f. p1 f /\ p3 f /\ p4 f ==> p5 f) /\ + (?f. p1 f /\ p2 f /\ p3 f /\ (p2 f ==> p4 f)) + ==> ?f. p1 f /\ p2 f /\ p3 f /\ p4 f /\ p5 f`) THEN + CONJ_TAC THENL + [X_GEN_TAC `f:num->real^N->bool` THEN STRIP_TAC THEN + FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN + X_GEN_TAC `k:real^N->bool` THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [COMPACT_EQ_HEINE_BOREL]) THEN + DISCH_THEN(MP_TAC o SPEC `{interior(f n):real^N->bool | n IN (:num)}`) THEN + REWRITE_TAC[FORALL_IN_GSPEC; OPEN_INTERIOR] THEN ANTS_TAC THENL + [FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + SUBSET_TRANS)) THEN + REWRITE_TAC[SUBSET; UNIONS_GSPEC; IN_ELIM_THM] THEN ASM SET_TAC[]; + ONCE_REWRITE_TAC[TAUT `p /\ q /\ r <=> q /\ p /\ r`] THEN + REWRITE_TAC[SIMPLE_IMAGE; EXISTS_FINITE_SUBSET_IMAGE] THEN + REWRITE_TAC[SUBSET_UNIV] THEN + DISCH_THEN(X_CHOOSE_THEN `i:num->bool` STRIP_ASSUME_TAC) THEN + FIRST_ASSUM(MP_TAC o SPEC `\n:num. n` o + MATCH_MP UPPER_BOUND_FINITE_SET) THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `N:num` THEN + REWRITE_TAC[GE] THEN DISCH_TAC THEN X_GEN_TAC `n:num` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + SUBSET_TRANS)) THEN + REWRITE_TAC[UNIONS_SUBSET; FORALL_IN_IMAGE] THEN + X_GEN_TAC `m:num` THEN DISCH_TAC THEN MATCH_MP_TAC SUBSET_TRANS THEN + EXISTS_TAC `(f:num->real^N->bool) m` THEN + REWRITE_TAC[INTERIOR_SUBSET] THEN + SUBGOAL_THEN `!m n. m <= n ==> (f:num->real^N->bool) m SUBSET f n` + (fun th -> ASM_MESON_TAC[th; LE_TRANS]) THEN + MATCH_MP_TAC TRANSITIVE_STEPWISE_LE THEN + ASM_MESON_TAC[SUBSET; ADD1; INTERIOR_SUBSET]]; + EXISTS_TAC + `\n. cball(a,&n) DIFF + {x + e | x IN (:real^N) DIFF s /\ e IN ball(vec 0,inv(&n + &1))}` THEN + REWRITE_TAC[] THEN REPEAT CONJ_TAC THENL + [X_GEN_TAC `n:num` THEN MATCH_MP_TAC COMPACT_DIFF THEN + SIMP_TAC[COMPACT_CBALL; OPEN_SUMS; OPEN_BALL]; + GEN_TAC THEN MATCH_MP_TAC(SET_RULE + `(UNIV DIFF s) SUBSET t ==> c DIFF t SUBSET s`) THEN + REWRITE_TAC[SUBSET; IN_ELIM_THM] THEN + X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN + MAP_EVERY EXISTS_TAC [`x:real^N`; `vec 0:real^N`] THEN + ASM_REWRITE_TAC[VECTOR_ADD_RID; CENTRE_IN_BALL; REAL_LT_INV_EQ] THEN + REAL_ARITH_TAC; + GEN_TAC THEN REWRITE_TAC[INTERIOR_DIFF] THEN MATCH_MP_TAC(SET_RULE + `s SUBSET s' /\ t' SUBSET t ==> (s DIFF t) SUBSET (s' DIFF t')`) THEN + CONJ_TAC THENL + [REWRITE_TAC[INTERIOR_CBALL; SUBSET; IN_BALL; IN_CBALL] THEN + REWRITE_TAC[GSYM REAL_OF_NUM_ADD] THEN REAL_ARITH_TAC; + MATCH_MP_TAC SUBSET_TRANS THEN + EXISTS_TAC `{x + e | x IN (:real^N) DIFF s /\ + e IN cball(vec 0,inv(&n + &2))}` THEN + CONJ_TAC THENL + [MATCH_MP_TAC CLOSURE_MINIMAL THEN + ASM_SIMP_TAC[CLOSED_COMPACT_SUMS; COMPACT_CBALL; + GSYM OPEN_CLOSED] THEN + MATCH_MP_TAC(SET_RULE + `t SUBSET t' + ==> {f x y | x IN s /\ y IN t} SUBSET + {f x y | x IN s /\ y IN t'}`) THEN + REWRITE_TAC[SUBSET; IN_BALL; IN_CBALL; GSYM REAL_OF_NUM_ADD] THEN + REAL_ARITH_TAC; + MATCH_MP_TAC(SET_RULE + `t SUBSET t' + ==> {f x y | x IN s /\ y IN t} SUBSET + {f x y | x IN s /\ y IN t'}`) THEN + REWRITE_TAC[SUBSET; IN_BALL; IN_CBALL; GSYM REAL_OF_NUM_ADD] THEN + GEN_TAC THEN MATCH_MP_TAC(REAL_ARITH + `a < b ==> x <= a ==> x < b`) THEN + MATCH_MP_TAC REAL_LT_INV2 THEN REAL_ARITH_TAC]]; + DISCH_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN + ASM_REWRITE_TAC[UNIONS_SUBSET; FORALL_IN_GSPEC] THEN + REWRITE_TAC[SUBSET; UNIONS_GSPEC; IN_UNIV; IN_ELIM_THM] THEN + X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN REWRITE_TAC[IN_DIFF] THEN + REWRITE_TAC[IN_ELIM_THM; IN_UNIV; IN_BALL_0] THEN + REWRITE_TAC[VECTOR_ARITH `x:real^N = y + e <=> e = x - y`] THEN + REWRITE_TAC[TAUT `(p /\ q) /\ r <=> r /\ p /\ q`; UNWIND_THM2] THEN + REWRITE_TAC[MESON[] `~(?x. ~P x /\ Q x) <=> !x. Q x ==> P x`] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [OPEN_CONTAINS_BALL]) THEN + DISCH_THEN(MP_TAC o SPEC `x:real^N`) THEN + ASM_REWRITE_TAC[SUBSET; IN_BALL; dist] THEN + DISCH_THEN(X_CHOOSE_THEN `e:real` STRIP_ASSUME_TAC) THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [REAL_ARCH_INV]) THEN + DISCH_THEN(X_CHOOSE_THEN `N1:num` STRIP_ASSUME_TAC) THEN + MP_TAC(ISPEC `norm(x - a:real^N)` REAL_ARCH_SIMPLE) THEN + DISCH_THEN(X_CHOOSE_TAC `N2:num`) THEN EXISTS_TAC `N1 + N2:num` THEN + CONJ_TAC THENL + [REWRITE_TAC[IN_CBALL] THEN ONCE_REWRITE_TAC[DIST_SYM] THEN + UNDISCH_TAC `norm(x - a:real^N) <= &N2` THEN + REWRITE_TAC[dist; GSYM REAL_OF_NUM_ADD] THEN REAL_ARITH_TAC; + REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + SUBGOAL_THEN `inv(&(N1 + N2) + &1) <= inv(&N1)` MP_TAC THENL + [MATCH_MP_TAC REAL_LE_INV2 THEN + ASM_SIMP_TAC[REAL_OF_NUM_LT; LE_1] THEN + REWRITE_TAC[GSYM REAL_OF_NUM_ADD] THEN REAL_ARITH_TAC; + ASM_REAL_ARITH_TAC]]]]);; + +(* ------------------------------------------------------------------------- *) +(* A cute way of denoting open and closed intervals using overloading. *) +(* ------------------------------------------------------------------------- *) + +let open_interval = new_definition + `open_interval(a:real^N,b:real^N) = + {x:real^N | !i. 1 <= i /\ i <= dimindex(:N) + ==> a$i < x$i /\ x$i < b$i}`;; + +let closed_interval = new_definition + `closed_interval(l:(real^N#real^N)list) = + {x:real^N | !i. 1 <= i /\ i <= dimindex(:N) + ==> FST(HD l)$i <= x$i /\ x$i <= SND(HD l)$i}`;; + +make_overloadable "interval" `:A`;; + +overload_interface("interval",`open_interval`);; +overload_interface("interval",`closed_interval`);; + +let interval = prove + (`(interval (a,b) = {x:real^N | !i. 1 <= i /\ i <= dimindex(:N) + ==> a$i < x$i /\ x$i < b$i}) /\ + (interval [a,b] = {x:real^N | !i. 1 <= i /\ i <= dimindex(:N) + ==> a$i <= x$i /\ x$i <= b$i})`, + REWRITE_TAC[open_interval; closed_interval; HD; FST; SND]);; + +let IN_INTERVAL = prove + (`(!x:real^N. + x IN interval (a,b) <=> + !i. 1 <= i /\ i <= dimindex(:N) + ==> a$i < x$i /\ x$i < b$i) /\ + (!x:real^N. + x IN interval [a,b] <=> + !i. 1 <= i /\ i <= dimindex(:N) + ==> a$i <= x$i /\ x$i <= b$i)`, + REWRITE_TAC[interval; IN_ELIM_THM]);; + +let IN_INTERVAL_REFLECT = prove + (`(!a b x. (--x) IN interval[--b,--a] <=> x IN interval[a,b]) /\ + (!a b x. (--x) IN interval(--b,--a) <=> x IN interval(a,b))`, + SIMP_TAC[IN_INTERVAL; REAL_LT_NEG2; REAL_LE_NEG2; VECTOR_NEG_COMPONENT] THEN + MESON_TAC[]);; + +let REFLECT_INTERVAL = prove + (`(!a b:real^N. IMAGE (--) (interval[a,b]) = interval[--b,--a]) /\ + (!a b:real^N. IMAGE (--) (interval(a,b)) = interval(--b,--a))`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC SURJECTIVE_IMAGE_EQ THEN + REWRITE_TAC[IN_INTERVAL_REFLECT] THEN MESON_TAC[VECTOR_NEG_NEG]);; + +let INTERVAL_EQ_EMPTY = prove + (`((interval [a:real^N,b] = {}) <=> + ?i. 1 <= i /\ i <= dimindex(:N) /\ b$i < a$i) /\ + ((interval (a:real^N,b) = {}) <=> + ?i. 1 <= i /\ i <= dimindex(:N) /\ b$i <= a$i)`, + REWRITE_TAC[EXTENSION; IN_INTERVAL; NOT_IN_EMPTY] THEN + REWRITE_TAC[NOT_FORALL_THM; NOT_IMP; GSYM CONJ_ASSOC] THEN + CONJ_TAC THEN EQ_TAC THENL + [MESON_TAC[REAL_LE_REFL; REAL_NOT_LE]; + MESON_TAC[REAL_LE_TRANS; REAL_NOT_LE]; + ALL_TAC; + MESON_TAC[REAL_LT_TRANS; REAL_NOT_LT]] THEN + SUBGOAL_THEN `!a b. ?c. a < b ==> a < c /\ c < b` + (MP_TAC o REWRITE_RULE[SKOLEM_THM]) THENL + [MESON_TAC[REAL_LT_BETWEEN]; ALL_TAC] THEN + DISCH_THEN(X_CHOOSE_TAC `mid:real->real->real`) THEN + DISCH_THEN(MP_TAC o SPEC + `(lambda i. mid ((a:real^N)$i) ((b:real^N)$i)):real^N`) THEN + ONCE_REWRITE_TAC[TAUT `a /\ b /\ c <=> ~(a /\ b ==> ~c)`] THEN + SIMP_TAC[LAMBDA_BETA] THEN ASM_MESON_TAC[REAL_NOT_LT]);; + +let INTERVAL_NE_EMPTY = prove + (`(~(interval [a:real^N,b] = {}) <=> + !i. 1 <= i /\ i <= dimindex(:N) ==> a$i <= b$i) /\ + (~(interval (a:real^N,b) = {}) <=> + !i. 1 <= i /\ i <= dimindex(:N) ==> a$i < b$i)`, + REWRITE_TAC[INTERVAL_EQ_EMPTY] THEN MESON_TAC[REAL_NOT_LE]);; + +let SUBSET_INTERVAL_IMP = prove + (`((!i. 1 <= i /\ i <= dimindex(:N) ==> a$i <= c$i /\ d$i <= b$i) + ==> interval[c,d] SUBSET interval[a:real^N,b]) /\ + ((!i. 1 <= i /\ i <= dimindex(:N) ==> a$i < c$i /\ d$i < b$i) + ==> interval[c,d] SUBSET interval(a:real^N,b)) /\ + ((!i. 1 <= i /\ i <= dimindex(:N) ==> a$i <= c$i /\ d$i <= b$i) + ==> interval(c,d) SUBSET interval[a:real^N,b]) /\ + ((!i. 1 <= i /\ i <= dimindex(:N) ==> a$i <= c$i /\ d$i <= b$i) + ==> interval(c,d) SUBSET interval(a:real^N,b))`, + REWRITE_TAC[SUBSET; IN_INTERVAL] THEN REPEAT CONJ_TAC THEN + DISCH_TAC THEN GEN_TAC THEN POP_ASSUM MP_TAC THEN + REWRITE_TAC[IMP_IMP; AND_FORALL_THM] THEN MATCH_MP_TAC MONO_FORALL THEN + GEN_TAC THEN DISCH_THEN(fun th -> DISCH_TAC THEN MP_TAC th) THEN + ASM_REWRITE_TAC[] THEN REAL_ARITH_TAC);; + +let INTERVAL_SING = prove + (`interval[a,a] = {a} /\ interval(a,a) = {}`, + REWRITE_TAC[EXTENSION; IN_SING; NOT_IN_EMPTY; IN_INTERVAL] THEN + REWRITE_TAC[REAL_LE_ANTISYM; REAL_LT_ANTISYM; CART_EQ; EQ_SYM_EQ] THEN + MESON_TAC[DIMINDEX_GE_1; LE_REFL]);; + +let SUBSET_INTERVAL = prove + (`(interval[c,d] SUBSET interval[a:real^N,b] <=> + (!i. 1 <= i /\ i <= dimindex(:N) ==> c$i <= d$i) + ==> (!i. 1 <= i /\ i <= dimindex(:N) ==> a$i <= c$i /\ d$i <= b$i)) /\ + (interval[c,d] SUBSET interval(a:real^N,b) <=> + (!i. 1 <= i /\ i <= dimindex(:N) ==> c$i <= d$i) + ==> (!i. 1 <= i /\ i <= dimindex(:N) ==> a$i < c$i /\ d$i < b$i)) /\ + (interval(c,d) SUBSET interval[a:real^N,b] <=> + (!i. 1 <= i /\ i <= dimindex(:N) ==> c$i < d$i) + ==> (!i. 1 <= i /\ i <= dimindex(:N) ==> a$i <= c$i /\ d$i <= b$i)) /\ + (interval(c,d) SUBSET interval(a:real^N,b) <=> + (!i. 1 <= i /\ i <= dimindex(:N) ==> c$i < d$i) + ==> (!i. 1 <= i /\ i <= dimindex(:N) ==> a$i <= c$i /\ d$i <= b$i))`, + let lemma = prove + (`(!x:real^N. (!i. 1 <= i /\ i <= dimindex(:N) ==> Q i (x$i)) + ==> (!i. 1 <= i /\ i <= dimindex(:N) ==> R i (x$i))) + ==> (!i. 1 <= i /\ i <= dimindex(:N) ==> ?y. Q i y) + ==> !i y. 1 <= i /\ i <= dimindex(:N) /\ Q i y ==> R i y`, + DISCH_TAC THEN REWRITE_TAC[RIGHT_IMP_EXISTS_THM; SKOLEM_THM] THEN + DISCH_THEN(X_CHOOSE_THEN `f:num->real` STRIP_ASSUME_TAC) THEN + REPEAT STRIP_TAC THEN FIRST_X_ASSUM(MP_TAC o + SPEC `(lambda j. if j = i then y else f j):real^N`) THEN + SIMP_TAC[LAMBDA_BETA] THEN ASM_MESON_TAC[]) in + REPEAT STRIP_TAC THEN + (MATCH_MP_TAC(TAUT + `(~q ==> p) /\ (q ==> (p <=> r)) ==> (p <=> q ==> r)`) THEN + CONJ_TAC THENL + [DISCH_TAC THEN MATCH_MP_TAC(SET_RULE `s = {} ==> s SUBSET t`) THEN + REWRITE_TAC[INTERVAL_EQ_EMPTY] THEN ASM_MESON_TAC[REAL_NOT_LT]; + ALL_TAC] THEN + DISCH_TAC THEN EQ_TAC THEN REWRITE_TAC[SUBSET_INTERVAL_IMP] THEN + REWRITE_TAC[SUBSET; IN_INTERVAL] THEN + DISCH_THEN(MP_TAC o MATCH_MP lemma) THEN ANTS_TAC THENL + [ASM_MESON_TAC[REAL_LT_BETWEEN; REAL_LE_BETWEEN]; ALL_TAC] THEN + MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `i:num` THEN + DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN ASM_REWRITE_TAC[] THEN + FIRST_X_ASSUM(MP_TAC o SPEC `i:num`) THEN + ASM_REWRITE_TAC[] THEN POP_ASSUM_LIST(K ALL_TAC) THEN STRIP_TAC) + THENL + [ASM_MESON_TAC[REAL_LE_TRANS; REAL_LE_REFL]; + ASM_MESON_TAC[REAL_LE_TRANS; REAL_LE_REFL]; + ALL_TAC; ALL_TAC] THEN + (REPEAT STRIP_TAC THENL + [FIRST_X_ASSUM(MP_TAC o SPEC + `((c:real^N)$i + min ((a:real^N)$i) ((d:real^N)$i)) / &2`) THEN + POP_ASSUM MP_TAC THEN REAL_ARITH_TAC; + FIRST_X_ASSUM(MP_TAC o SPEC + `(max ((b:real^N)$i) ((c:real^N)$i) + (d:real^N)$i) / &2`) THEN + POP_ASSUM MP_TAC THEN REAL_ARITH_TAC]));; + +let DISJOINT_INTERVAL = prove + (`!a b c d:real^N. + (interval[a,b] INTER interval[c,d] = {} <=> + ?i. 1 <= i /\ i <= dimindex(:N) /\ + (b$i < a$i \/ d$i < c$i \/ b$i < c$i \/ d$i < a$i)) /\ + (interval[a,b] INTER interval(c,d) = {} <=> + ?i. 1 <= i /\ i <= dimindex(:N) /\ + (b$i < a$i \/ d$i <= c$i \/ b$i <= c$i \/ d$i <= a$i)) /\ + (interval(a,b) INTER interval[c,d] = {} <=> + ?i. 1 <= i /\ i <= dimindex(:N) /\ + (b$i <= a$i \/ d$i < c$i \/ b$i <= c$i \/ d$i <= a$i)) /\ + (interval(a,b) INTER interval(c,d) = {} <=> + ?i. 1 <= i /\ i <= dimindex(:N) /\ + (b$i <= a$i \/ d$i <= c$i \/ b$i <= c$i \/ d$i <= a$i))`, + REWRITE_TAC[EXTENSION; IN_INTER; IN_INTERVAL; NOT_IN_EMPTY] THEN + REWRITE_TAC[AND_FORALL_THM; NOT_FORALL_THM] THEN + REWRITE_TAC[TAUT `~((p ==> q) /\ (p ==> r)) <=> p /\ (~q \/ ~r)`] THEN + REWRITE_TAC[DE_MORGAN_THM] THEN REPEAT STRIP_TAC THEN + (EQ_TAC THENL + [DISCH_THEN(MP_TAC o SPEC + `(lambda i. (max ((a:real^N)$i) ((c:real^N)$i) + + min ((b:real^N)$i) ((d:real^N)$i)) / &2):real^N`) THEN + MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC THEN + DISCH_THEN(CONJUNCTS_THEN2 STRIP_ASSUME_TAC MP_TAC) THEN + ASM_SIMP_TAC[LAMBDA_BETA] THEN REAL_ARITH_TAC; + DISCH_THEN(fun th -> GEN_TAC THEN MP_TAC th) THEN + MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC THEN SIMP_TAC[] THEN + REAL_ARITH_TAC]));; + +let ENDS_IN_INTERVAL = prove + (`(!a b. a IN interval[a,b] <=> ~(interval[a,b] = {})) /\ + (!a b. b IN interval[a,b] <=> ~(interval[a,b] = {})) /\ + (!a b. ~(a IN interval(a,b))) /\ + (!a b. ~(b IN interval(a,b)))`, + REWRITE_TAC[IN_INTERVAL; INTERVAL_NE_EMPTY] THEN + REWRITE_TAC[REAL_LE_REFL; REAL_LT_REFL] THEN + MESON_TAC[DIMINDEX_GE_1; LE_REFL]);; + +let ENDS_IN_UNIT_INTERVAL = prove + (`vec 0 IN interval[vec 0,vec 1] /\ + vec 1 IN interval[vec 0,vec 1] /\ + ~(vec 0 IN interval(vec 0,vec 1)) /\ + ~(vec 1 IN interval(vec 0,vec 1))`, + REWRITE_TAC[ENDS_IN_INTERVAL; INTERVAL_NE_EMPTY; VEC_COMPONENT] THEN + REWRITE_TAC[REAL_POS]);; + +let INTER_INTERVAL = prove + (`interval[a,b] INTER interval[c,d] = + interval[(lambda i. max (a$i) (c$i)),(lambda i. min (b$i) (d$i))]`, + REWRITE_TAC[EXTENSION; IN_INTER; IN_INTERVAL] THEN + SIMP_TAC[LAMBDA_BETA; REAL_MAX_LE; REAL_LE_MIN] THEN MESON_TAC[]);; + +let INTERVAL_OPEN_SUBSET_CLOSED = prove + (`!a b. interval(a,b) SUBSET interval[a,b]`, + REWRITE_TAC[SUBSET; IN_INTERVAL] THEN MESON_TAC[REAL_LT_IMP_LE]);; + +let OPEN_INTERVAL_LEMMA = prove + (`!a b x. a < x /\ x < b + ==> ?d. &0 < d /\ !x'. abs(x' - x) < d ==> a < x' /\ x' < b`, + REPEAT STRIP_TAC THEN + EXISTS_TAC `min (x - a) (b - x)` THEN REWRITE_TAC[REAL_LT_MIN] THEN + ASM_REAL_ARITH_TAC);; + +let OPEN_INTERVAL = prove + (`!a:real^N b. open(interval (a,b))`, + REPEAT GEN_TAC THEN REWRITE_TAC[open_def; interval; IN_ELIM_THM] THEN + X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN + SUBGOAL_THEN `!i. 1 <= i /\ i <= dimindex(:N) + ==> ?d. &0 < d /\ + !x'. abs(x' - (x:real^N)$i) < d + ==> (a:real^N)$i < x' /\ x' < (b:real^N)$i` + MP_TAC THENL [ASM_SIMP_TAC[OPEN_INTERVAL_LEMMA]; 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_THEN `d:num->real` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `inf (IMAGE d (1..dimindex(:N)))` THEN + SIMP_TAC[REAL_LT_INF_FINITE; FINITE_IMAGE; FINITE_NUMSEG; + IMAGE_EQ_EMPTY; NOT_INSERT_EMPTY; NUMSEG_EMPTY; + ARITH_RULE `n < 1 <=> (n = 0)`; DIMINDEX_NONZERO] THEN + REWRITE_TAC[FORALL_IN_IMAGE; IN_NUMSEG; dist] THEN + ASM_MESON_TAC[COMPONENT_LE_NORM; REAL_LET_TRANS; VECTOR_SUB_COMPONENT]);; + +let CLOSED_INTERVAL = prove + (`!a:real^N b. closed(interval [a,b])`, + REWRITE_TAC[CLOSED_LIMPT; LIMPT_APPROACHABLE; IN_INTERVAL] THEN + REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM REAL_NOT_LT] THEN DISCH_TAC THENL + [FIRST_X_ASSUM(MP_TAC o SPEC `(a:real^N)$i - (x:real^N)$i`); + FIRST_X_ASSUM(MP_TAC o SPEC `(x:real^N)$i - (b:real^N)$i`)] THEN + ASM_REWRITE_TAC[REAL_SUB_LT] THEN + DISCH_THEN(X_CHOOSE_THEN `z:real^N` MP_TAC) THEN + REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + REWRITE_TAC[dist; REAL_NOT_LT] THEN + MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC `abs((z - x :real^N)$i)` THEN + ASM_SIMP_TAC[COMPONENT_LE_NORM] THEN + ASM_SIMP_TAC[VECTOR_SUB_COMPONENT] THEN + ASM_SIMP_TAC[REAL_ARITH `x < a /\ a <= z ==> a - x <= abs(z - x)`; + REAL_ARITH `z <= b /\ b < x ==> x - b <= abs(z - x)`]);; + +let INTERIOR_CLOSED_INTERVAL = prove + (`!a:real^N b. interior(interval [a,b]) = interval (a,b)`, + REPEAT GEN_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL + [ALL_TAC; + MATCH_MP_TAC INTERIOR_MAXIMAL THEN + REWRITE_TAC[INTERVAL_OPEN_SUBSET_CLOSED; OPEN_INTERVAL]] THEN + REWRITE_TAC[interior; SUBSET; IN_INTERVAL; IN_ELIM_THM] THEN + X_GEN_TAC `x:real^N` THEN + DISCH_THEN(X_CHOOSE_THEN `s:real^N->bool` STRIP_ASSUME_TAC) THEN + X_GEN_TAC `i:num` THEN STRIP_TAC THEN + ASM_SIMP_TAC[REAL_LT_LE] THEN REPEAT STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [open_def]) THEN + DISCH_THEN(MP_TAC o SPEC `x:real^N`) THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `e:real` (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THENL + [(let t = `x - (e / &2) % basis i :real^N` in + DISCH_THEN(MP_TAC o SPEC t) THEN FIRST_X_ASSUM(MP_TAC o SPEC t)); + (let t = `x + (e / &2) % basis i :real^N` in + DISCH_THEN(MP_TAC o SPEC t) THEN FIRST_X_ASSUM(MP_TAC o SPEC t))] THEN + REWRITE_TAC[dist; VECTOR_ADD_SUB; VECTOR_ARITH `x - y - x = --y:real^N`] THEN + ASM_SIMP_TAC[NORM_MUL; NORM_BASIS; NORM_NEG; REAL_MUL_RID; + REAL_ARITH `&0 < e ==> abs(e / &2) < e`] THEN + MATCH_MP_TAC(TAUT `~b ==> (a ==> b) ==> ~a`) THEN + REWRITE_TAC[NOT_FORALL_THM] THEN EXISTS_TAC `i:num` THEN + ASM_SIMP_TAC[DE_MORGAN_THM; VECTOR_SUB_COMPONENT; VECTOR_ADD_COMPONENT] THENL + [DISJ1_TAC THEN REWRITE_TAC[REAL_ARITH `a <= a - b <=> ~(&0 < b)`]; + DISJ2_TAC THEN REWRITE_TAC[REAL_ARITH `a + b <= a <=> ~(&0 < b)`]] THEN + ASM_SIMP_TAC[VECTOR_MUL_COMPONENT; basis; LAMBDA_BETA; REAL_MUL_RID] THEN + ASM_REWRITE_TAC[REAL_HALF]);; + +let INTERIOR_INTERVAL = prove + (`(!a b. interior(interval[a,b]) = interval(a,b)) /\ + (!a b. interior(interval(a,b)) = interval(a,b))`, + SIMP_TAC[INTERIOR_CLOSED_INTERVAL; INTERIOR_OPEN; OPEN_INTERVAL]);; + +let BOUNDED_CLOSED_INTERVAL = prove + (`!a b:real^N. bounded (interval [a,b])`, + REPEAT STRIP_TAC THEN REWRITE_TAC[bounded; interval] THEN + EXISTS_TAC `sum(1..dimindex(:N)) + (\i. abs((a:real^N)$i) + abs((b:real^N)$i))` THEN + X_GEN_TAC `x:real^N` THEN REWRITE_TAC[IN_ELIM_THM] THEN + STRIP_TAC THEN MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `sum(1..dimindex(:N)) (\i. abs((x:real^N)$i))` THEN + REWRITE_TAC[NORM_LE_L1] THEN MATCH_MP_TAC SUM_LE THEN + ASM_SIMP_TAC[FINITE_NUMSEG; IN_NUMSEG; REAL_ARITH + `a <= x /\ x <= b ==> abs(x) <= abs(a) + abs(b)`]);; + +let BOUNDED_INTERVAL = prove + (`(!a b. bounded (interval [a,b])) /\ (!a b. bounded (interval (a,b)))`, + MESON_TAC[BOUNDED_CLOSED_INTERVAL; BOUNDED_SUBSET; + INTERVAL_OPEN_SUBSET_CLOSED]);; + +let NOT_INTERVAL_UNIV = prove + (`(!a b. ~(interval[a,b] = UNIV)) /\ + (!a b. ~(interval(a,b) = UNIV))`, + MESON_TAC[BOUNDED_INTERVAL; NOT_BOUNDED_UNIV]);; + +let COMPACT_INTERVAL = prove + (`!a b. compact (interval [a,b])`, + SIMP_TAC[COMPACT_EQ_BOUNDED_CLOSED; BOUNDED_INTERVAL; CLOSED_INTERVAL]);; + +let OPEN_INTERVAL_MIDPOINT = prove + (`!a b:real^N. + ~(interval(a,b) = {}) ==> (inv(&2) % (a + b)) IN interval(a,b)`, + REWRITE_TAC[INTERVAL_NE_EMPTY; IN_INTERVAL] THEN + SIMP_TAC[VECTOR_MUL_COMPONENT; VECTOR_ADD_COMPONENT] THEN + REPEAT GEN_TAC THEN MATCH_MP_TAC MONO_FORALL THEN GEN_TAC THEN + MATCH_MP_TAC MONO_IMP THEN REWRITE_TAC[] THEN REAL_ARITH_TAC);; + +let OPEN_CLOSED_INTERVAL_CONVEX = prove + (`!a b x y:real^N e. + x IN interval(a,b) /\ y IN interval[a,b] /\ &0 < e /\ e <= &1 + ==> (e % x + (&1 - e) % y) IN interval(a,b)`, + REPEAT GEN_TAC THEN MATCH_MP_TAC(TAUT + `(c /\ d ==> a /\ b ==> e) ==> a /\ b /\ c /\ d ==> e`) THEN + STRIP_TAC THEN REWRITE_TAC[IN_INTERVAL; AND_FORALL_THM] THEN + SIMP_TAC[VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT] THEN + MATCH_MP_TAC MONO_FORALL THEN + GEN_TAC THEN DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN + ASM_REWRITE_TAC[] THEN STRIP_TAC THEN + SUBST1_TAC(REAL_ARITH `(a:real^N)$i = e * a$i + (&1 - e) * a$i`) THEN + SUBST1_TAC(REAL_ARITH `(b:real^N)$i = e * b$i + (&1 - e) * b$i`) THEN + CONJ_TAC THEN MATCH_MP_TAC REAL_LTE_ADD2 THEN + ASM_SIMP_TAC[REAL_LT_LMUL_EQ; REAL_LE_LMUL; REAL_SUB_LE]);; + +let CLOSURE_OPEN_INTERVAL = prove + (`!a b:real^N. + ~(interval(a,b) = {}) ==> closure(interval(a,b)) = interval[a,b]`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL + [MATCH_MP_TAC CLOSURE_MINIMAL THEN + REWRITE_TAC[INTERVAL_OPEN_SUBSET_CLOSED; CLOSED_INTERVAL]; + ALL_TAC] THEN + REWRITE_TAC[SUBSET; closure; IN_UNION] THEN X_GEN_TAC `x:real^N` THEN + DISCH_TAC THEN MATCH_MP_TAC(TAUT `(~b ==> c) ==> b \/ c`) THEN DISCH_TAC THEN + REWRITE_TAC[IN_ELIM_THM; LIMPT_SEQUENTIAL] THEN + ABBREV_TAC `(c:real^N) = inv(&2) % (a + b)` THEN + EXISTS_TAC `\n. (x:real^N) + inv(&n + &1) % (c - x)` THEN CONJ_TAC THENL + [X_GEN_TAC `n:num` THEN REWRITE_TAC[IN_DELETE] THEN + REWRITE_TAC[VECTOR_ARITH `x + a = x <=> a = vec 0`] THEN + REWRITE_TAC[VECTOR_MUL_EQ_0; REAL_INV_EQ_0] THEN + REWRITE_TAC[VECTOR_SUB_EQ; REAL_ARITH `~(&n + &1 = &0)`] THEN + CONJ_TAC THENL [ALL_TAC; ASM_MESON_TAC[OPEN_INTERVAL_MIDPOINT]] THEN + REWRITE_TAC[VECTOR_ARITH `x + a % (y - x) = a % y + (&1 - a) % x`] THEN + MATCH_MP_TAC OPEN_CLOSED_INTERVAL_CONVEX THEN + CONJ_TAC THENL [ASM_MESON_TAC[OPEN_INTERVAL_MIDPOINT]; ALL_TAC] THEN + ASM_REWRITE_TAC[REAL_LT_INV_EQ; REAL_ARITH `&0 < &n + &1`] THEN + MATCH_MP_TAC REAL_INV_LE_1 THEN REAL_ARITH_TAC; + ALL_TAC] THEN + GEN_REWRITE_TAC LAND_CONV [VECTOR_ARITH `x:real^N = x + &0 % (c - x)`] THEN + MATCH_MP_TAC LIM_ADD THEN REWRITE_TAC[LIM_CONST] THEN + MATCH_MP_TAC LIM_VMUL THEN REWRITE_TAC[LIM_CONST] THEN + REWRITE_TAC[LIM_SEQUENTIALLY; o_THM; DIST_LIFT; REAL_SUB_RZERO] THEN + X_GEN_TAC `e:real` THEN GEN_REWRITE_TAC LAND_CONV [REAL_ARCH_INV] 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[REAL_ABS_INV] THEN MATCH_MP_TAC REAL_LET_TRANS THEN + EXISTS_TAC `inv(&N)` THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC REAL_LE_INV2 THEN UNDISCH_TAC `N:num <= n` THEN + UNDISCH_TAC `~(N = 0)` THEN + REWRITE_TAC[GSYM LT_NZ; GSYM REAL_OF_NUM_LE; GSYM REAL_OF_NUM_LT] THEN + REAL_ARITH_TAC);; + +let CLOSURE_INTERVAL = prove + (`(!a b. closure(interval[a,b]) = interval[a,b]) /\ + (!a b. closure(interval(a,b)) = + if interval(a,b) = {} then {} else interval[a,b])`, + SIMP_TAC[CLOSURE_CLOSED; CLOSED_INTERVAL] THEN REPEAT GEN_TAC THEN + COND_CASES_TAC THEN ASM_SIMP_TAC[CLOSURE_OPEN_INTERVAL; CLOSURE_EMPTY]);; + +let BOUNDED_SUBSET_OPEN_INTERVAL_SYMMETRIC = prove + (`!s:real^N->bool. bounded s ==> ?a. s SUBSET interval(--a,a)`, + REWRITE_TAC[BOUNDED_POS; LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`s:real^N->bool`; `B:real`] THEN STRIP_TAC THEN + EXISTS_TAC `(lambda i. B + &1):real^N` THEN + REWRITE_TAC[SUBSET] THEN X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN + SIMP_TAC[IN_INTERVAL; LAMBDA_BETA; REAL_BOUNDS_LT; VECTOR_NEG_COMPONENT] THEN + ASM_MESON_TAC[COMPONENT_LE_NORM; + REAL_ARITH `x <= y ==> a <= x ==> a < y + &1`]);; + +let BOUNDED_SUBSET_OPEN_INTERVAL = prove + (`!s:real^N->bool. bounded s ==> ?a b. s SUBSET interval(a,b)`, + MESON_TAC[BOUNDED_SUBSET_OPEN_INTERVAL_SYMMETRIC]);; + +let BOUNDED_SUBSET_CLOSED_INTERVAL_SYMMETRIC = prove + (`!s:real^N->bool. bounded s ==> ?a. s SUBSET interval[--a,a]`, + GEN_TAC THEN + DISCH_THEN(MP_TAC o MATCH_MP BOUNDED_SUBSET_OPEN_INTERVAL_SYMMETRIC) THEN + MATCH_MP_TAC MONO_EXISTS THEN + SIMP_TAC[IN_BALL; IN_INTERVAL; SUBSET; REAL_LT_IMP_LE]);; + +let BOUNDED_SUBSET_CLOSED_INTERVAL = prove + (`!s:real^N->bool. bounded s ==> ?a b. s SUBSET interval[a,b]`, + MESON_TAC[BOUNDED_SUBSET_CLOSED_INTERVAL_SYMMETRIC]);; + +let FRONTIER_CLOSED_INTERVAL = prove + (`!a b. frontier(interval[a,b]) = interval[a,b] DIFF interval(a,b)`, + SIMP_TAC[frontier; INTERIOR_CLOSED_INTERVAL; CLOSURE_CLOSED; + CLOSED_INTERVAL]);; + +let FRONTIER_OPEN_INTERVAL = prove + (`!a b. frontier(interval(a,b)) = + if interval(a,b) = {} then {} + else interval[a,b] DIFF interval(a,b)`, + REPEAT GEN_TAC THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[FRONTIER_EMPTY] THEN + ASM_SIMP_TAC[frontier; CLOSURE_OPEN_INTERVAL; INTERIOR_OPEN; + OPEN_INTERVAL]);; + +let INTER_INTERVAL_MIXED_EQ_EMPTY = prove + (`!a b c d:real^N. + ~(interval(c,d) = {}) + ==> (interval(a,b) INTER interval[c,d] = {} <=> + interval(a,b) INTER interval(c,d) = {})`, + SIMP_TAC[GSYM CLOSURE_OPEN_INTERVAL; OPEN_INTER_CLOSURE_EQ_EMPTY; + OPEN_INTERVAL]);; + +let INTERVAL_TRANSLATION = prove + (`(!c a b. interval[c + a,c + b] = IMAGE (\x. c + x) (interval[a,b])) /\ + (!c a b. interval(c + a,c + b) = IMAGE (\x. c + x) (interval(a,b)))`, + REWRITE_TAC[interval] THEN CONJ_TAC THEN GEOM_TRANSLATE_TAC[] THEN + REWRITE_TAC[VECTOR_ADD_COMPONENT; REAL_LT_LADD; REAL_LE_LADD]);; + +add_translation_invariants + [CONJUNCT1 INTERVAL_TRANSLATION; CONJUNCT2 INTERVAL_TRANSLATION];; + +let EMPTY_AS_INTERVAL = prove + (`{} = interval[vec 1,vec 0]`, + SIMP_TAC[EXTENSION; NOT_IN_EMPTY; IN_INTERVAL; VEC_COMPONENT] THEN + GEN_TAC THEN DISCH_THEN(MP_TAC o SPEC `1`) THEN + REWRITE_TAC[LE_REFL; DIMINDEX_GE_1] THEN REAL_ARITH_TAC);; + +let UNIT_INTERVAL_NONEMPTY = prove + (`~(interval[vec 0:real^N,vec 1] = {}) /\ + ~(interval(vec 0:real^N,vec 1) = {})`, + SIMP_TAC[INTERVAL_NE_EMPTY; VEC_COMPONENT; REAL_LT_01; REAL_POS]);; + +let IMAGE_STRETCH_INTERVAL = prove + (`!a b:real^N m. + IMAGE (\x. lambda k. m(k) * x$k) (interval[a,b]) = + if interval[a,b] = {} then {} + else interval[(lambda k. min (m(k) * a$k) (m(k) * b$k)):real^N, + (lambda k. max (m(k) * a$k) (m(k) * b$k))]`, + REPEAT GEN_TAC THEN COND_CASES_TAC THEN ASM_SIMP_TAC[IMAGE_CLAUSES] THEN + ASM_SIMP_TAC[EXTENSION; IN_IMAGE; CART_EQ; IN_INTERVAL; AND_FORALL_THM; + TAUT `(a ==> b) /\ (a ==> c) <=> a ==> b /\ c`; + LAMBDA_BETA; GSYM LAMBDA_SKOLEM] THEN + X_GEN_TAC `x:real^N` THEN MATCH_MP_TAC(MESON[] + `(!x. p x ==> (q x <=> r x)) + ==> ((!x. p x ==> q x) <=> (!x. p x ==> r x))`) THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [INTERVAL_NE_EMPTY]) THEN + MATCH_MP_TAC MONO_FORALL THEN + X_GEN_TAC `k:num` THEN ASM_CASES_TAC `1 <= k /\ k <= dimindex(:N)` THEN + ASM_REWRITE_TAC[] THEN ASM_CASES_TAC `(m:num->real) k = &0` THENL + [ASM_REWRITE_TAC[REAL_MUL_LZERO; REAL_MAX_ACI; REAL_MIN_ACI] THEN + ASM_MESON_TAC[REAL_LE_ANTISYM; REAL_LE_REFL]; + ALL_TAC] THEN + ASM_SIMP_TAC[REAL_FIELD `~(m = &0) ==> (x = m * y <=> y = x / m)`] THEN + REWRITE_TAC[UNWIND_THM2] THEN FIRST_X_ASSUM(DISJ_CASES_TAC o MATCH_MP + (REAL_ARITH `~(z = &0) ==> &0 < z \/ &0 < --z`)) + THENL + [ALL_TAC; + ONCE_REWRITE_TAC[GSYM REAL_LE_NEG2] THEN + ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN + REWRITE_TAC[REAL_ARITH `--(max a b) = min (--a) (--b)`; + REAL_ARITH `--(min a b) = max (--a) (--b)`; real_div; + GSYM REAL_MUL_RNEG; GSYM REAL_INV_NEG] THEN + REWRITE_TAC[GSYM real_div]] THEN + ASM_SIMP_TAC[REAL_LE_LDIV_EQ; REAL_LE_RDIV_EQ] THEN + ASM_SIMP_TAC[real_min; real_max; REAL_LE_LMUL_EQ; REAL_LE_RMUL_EQ] THEN + REAL_ARITH_TAC);; + +let INTERVAL_IMAGE_STRETCH_INTERVAL = prove + (`!a b:real^N m. ?u v:real^N. + IMAGE (\x. lambda k. m k * x$k) (interval[a,b]) = interval[u,v]`, + REWRITE_TAC[IMAGE_STRETCH_INTERVAL] THEN MESON_TAC[EMPTY_AS_INTERVAL]);; + +let CLOSED_INTERVAL_IMAGE_UNIT_INTERVAL = prove + (`!a b:real^N. + ~(interval[a,b] = {}) + ==> interval[a,b] = IMAGE (\x:real^N. a + x) + (IMAGE (\x. (lambda i. (b$i - a$i) * x$i)) + (interval[vec 0:real^N,vec 1]))`, + REWRITE_TAC[INTERVAL_NE_EMPTY] THEN REPEAT STRIP_TAC THEN + REWRITE_TAC[IMAGE_STRETCH_INTERVAL; UNIT_INTERVAL_NONEMPTY] THEN + REWRITE_TAC[GSYM INTERVAL_TRANSLATION] THEN + REWRITE_TAC[EXTENSION; IN_INTERVAL] THEN + SIMP_TAC[LAMBDA_BETA; VECTOR_ADD_COMPONENT; VEC_COMPONENT] THEN + GEN_TAC THEN REWRITE_TAC[REAL_MUL_RZERO; REAL_MUL_RID] THEN + MATCH_MP_TAC(MESON[] `(!x. P x <=> Q x) ==> ((!x. P x) <=> (!x. Q x))`) THEN + POP_ASSUM MP_TAC THEN MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `i:num` THEN + ASM_CASES_TAC `1 <= i /\ i <= dimindex(:N)` THEN ASM_REWRITE_TAC[] THEN + REAL_ARITH_TAC);; + +let SUMS_INTERVALS = prove + (`(!a b c d:real^N. + ~(interval[a,b] = {}) /\ ~(interval[c,d] = {}) + ==> {x + y | x IN interval[a,b] /\ y IN interval[c,d]} = + interval[a+c,b+d]) /\ + (!a b c d:real^N. + ~(interval(a,b) = {}) /\ ~(interval(c,d) = {}) + ==> {x + y | x IN interval(a,b) /\ y IN interval(c,d)} = + interval(a+c,b+d))`, + CONJ_TAC THEN REPEAT GEN_TAC THEN REWRITE_TAC[INTERVAL_NE_EMPTY] THEN + STRIP_TAC THEN REWRITE_TAC[EXTENSION; IN_INTERVAL; IN_ELIM_THM] THEN + REWRITE_TAC[TAUT `(a /\ b) /\ c <=> c /\ a /\ b`] THEN + REWRITE_TAC[VECTOR_ARITH `x:real^N = y + z <=> z = x - y`] THEN + REWRITE_TAC[UNWIND_THM2; VECTOR_ADD_COMPONENT; VECTOR_SUB_COMPONENT] THEN + (X_GEN_TAC `x:real^N` THEN EQ_TAC THENL + [DISCH_THEN(X_CHOOSE_THEN `y:real^N` STRIP_ASSUME_TAC); + DISCH_TAC THEN + REWRITE_TAC[AND_FORALL_THM; GSYM LAMBDA_SKOLEM; + TAUT `(p ==> q) /\ (p ==> r) <=> p ==> q /\ r`] THEN + REWRITE_TAC[REAL_ARITH + `((a <= y /\ y <= b) /\ c <= x - y /\ x - y <= d <=> + max a (x - d) <= y /\ y <= min b (x - c)) /\ + ((a < y /\ y < b) /\ c < x - y /\ x - y < d <=> + max a (x - d) < y /\ y < min b (x - c))`] THEN + REWRITE_TAC[GSYM REAL_LE_BETWEEN; GSYM REAL_LT_BETWEEN]] 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 ASM_REAL_ARITH_TAC));; + +let PCROSS_INTERVAL = prove + (`!a b:real^M c d:real^N. + interval[a,b] PCROSS interval[c,d] = + interval[pastecart a c,pastecart b d]`, + REPEAT GEN_TAC THEN REWRITE_TAC[PCROSS] THEN + REWRITE_TAC[EXTENSION; FORALL_PASTECART; IN_ELIM_PASTECART_THM] THEN + SIMP_TAC[IN_INTERVAL; pastecart; LAMBDA_BETA; DIMINDEX_FINITE_SUM] THEN + MAP_EVERY X_GEN_TAC [`x:real^M`; `y:real^N`] THEN EQ_TAC THEN STRIP_TAC THENL + [X_GEN_TAC `i:num` THEN STRIP_TAC THEN + COND_CASES_TAC THEN ASM_SIMP_TAC[] THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_ARITH_TAC; + CONJ_TAC THEN X_GEN_TAC `i:num` THEN STRIP_TAC THENL + [FIRST_X_ASSUM(MP_TAC o SPEC `i:num`) THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN MATCH_MP_TAC THEN ASM_ARITH_TAC; + FIRST_X_ASSUM(MP_TAC o SPEC `i + dimindex(:M)`) THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[ADD_SUB] THENL + [ASM_ARITH_TAC; + DISCH_THEN MATCH_MP_TAC THEN ASM_ARITH_TAC]]]);; + +let OPEN_CONTAINS_INTERVAL,OPEN_CONTAINS_OPEN_INTERVAL = (CONJ_PAIR o prove) + (`(!s:real^N->bool. + open s <=> + !x. x IN s ==> ?a b. x IN interval(a,b) /\ interval[a,b] SUBSET s) /\ + (!s:real^N->bool. + open s <=> + !x. x IN s ==> ?a b. x IN interval(a,b) /\ interval(a,b) SUBSET s)`, + REWRITE_TAC[AND_FORALL_THM] THEN GEN_TAC THEN + MATCH_MP_TAC(TAUT + `(q ==> r) /\ (r ==> p) /\ (p ==> q) ==> (p <=> q) /\ (p <=> r)`) THEN + REPEAT CONJ_TAC THENL + [MESON_TAC[SUBSET_TRANS; INTERVAL_OPEN_SUBSET_CLOSED]; + DISCH_TAC THEN REWRITE_TAC[OPEN_CONTAINS_BALL] THEN + X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `x:real^N`) THEN + ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`a:real^N`; `b:real^N`] THEN STRIP_TAC THEN + MP_TAC(ISPEC `interval(a:real^N,b)` OPEN_CONTAINS_BALL) THEN + REWRITE_TAC[OPEN_INTERVAL] THEN + DISCH_THEN(MP_TAC o SPEC `x:real^N`) THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC MONO_EXISTS THEN + REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + ASM_MESON_TAC[SUBSET_TRANS; INTERVAL_OPEN_SUBSET_CLOSED]; + DISCH_TAC THEN X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN + FIRST_ASSUM(MP_TAC o SPEC `x:real^N` o + GEN_REWRITE_RULE I [OPEN_CONTAINS_CBALL]) THEN + ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `e:real` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `x - e / &(dimindex(:N)) % vec 1:real^N` THEN + EXISTS_TAC `x + e / &(dimindex(:N)) % vec 1:real^N` THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE + `b SUBSET s ==> x IN i /\ j SUBSET b ==> x IN i /\ j SUBSET s`)) THEN + SIMP_TAC[IN_INTERVAL; VECTOR_SUB_COMPONENT; VECTOR_MUL_COMPONENT; IN_CBALL; + VEC_COMPONENT; VECTOR_ADD_COMPONENT; SUBSET; REAL_MUL_RID] THEN + REWRITE_TAC[REAL_ARITH `x - e < x /\ x < x + e <=> &0 < e`; + REAL_ARITH `x - e <= y /\ y <= x + e <=> abs(x - y) <= e`] THEN + ASM_SIMP_TAC[REAL_LT_DIV; REAL_OF_NUM_LT; LE_1; DIMINDEX_GE_1] THEN + X_GEN_TAC `y:real^N` THEN REWRITE_TAC[GSYM VECTOR_SUB_COMPONENT] THEN + DISCH_TAC THEN REWRITE_TAC[dist] THEN + MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `sum(1..dimindex(:N)) (\i. abs((x - y:real^N)$i))` THEN + REWRITE_TAC[NORM_LE_L1] THEN MATCH_MP_TAC SUM_BOUND_GEN THEN + ASM_SIMP_TAC[CARD_NUMSEG_1; IN_NUMSEG; FINITE_NUMSEG] THEN + REWRITE_TAC[NUMSEG_EMPTY; NOT_LT; DIMINDEX_GE_1]]);; + +let DIAMETER_INTERVAL = prove + (`(!a b:real^N. + diameter(interval[a,b]) = + if interval[a,b] = {} then &0 else norm(b - a)) /\ + (!a b:real^N. + diameter(interval(a,b)) = + if interval(a,b) = {} then &0 else norm(b - a))`, + REWRITE_TAC[AND_FORALL_THM] THEN REPEAT GEN_TAC THEN + ASM_CASES_TAC `interval[a:real^N,b] = {}` THENL + [ASM_MESON_TAC[INTERVAL_OPEN_SUBSET_CLOSED; SUBSET_EMPTY; DIAMETER_EMPTY]; + ASM_REWRITE_TAC[]] THEN + MATCH_MP_TAC(TAUT `p /\ (p ==> q) ==> p /\ q`) THEN CONJ_TAC THENL + [REWRITE_TAC[GSYM REAL_LE_ANTISYM] THEN + ASM_SIMP_TAC[DIAMETER_BOUNDED_BOUND; + ENDS_IN_INTERVAL; BOUNDED_INTERVAL] THEN + MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC + `diameter(cball(inv(&2) % (a + b):real^N,norm(b - a) / &2))` THEN + CONJ_TAC THENL + [MATCH_MP_TAC DIAMETER_SUBSET THEN REWRITE_TAC[BOUNDED_CBALL] THEN + REWRITE_TAC[SUBSET; IN_INTERVAL; IN_CBALL] THEN + GEN_TAC THEN DISCH_TAC THEN REWRITE_TAC[dist] THEN + REWRITE_TAC[GSYM NORM_MUL; REAL_ARITH `x / &2 = abs(inv(&2)) * x`] THEN + MATCH_MP_TAC NORM_LE_COMPONENTWISE THEN + X_GEN_TAC `i:num` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `i:num`) THEN + ASM_REWRITE_TAC[VECTOR_ADD_COMPONENT; VECTOR_SUB_COMPONENT; + VECTOR_MUL_COMPONENT] THEN + REAL_ARITH_TAC; + REWRITE_TAC[DIAMETER_CBALL] THEN NORM_ARITH_TAC]; + DISCH_TAC THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[DIAMETER_EMPTY] THEN + SUBGOAL_THEN `interval[a:real^N,b] = closure(interval(a,b))` + SUBST_ALL_TAC THEN ASM_REWRITE_TAC[CLOSURE_INTERVAL] THEN + ASM_MESON_TAC[DIAMETER_CLOSURE; BOUNDED_INTERVAL]]);; + +(* ------------------------------------------------------------------------- *) +(* Some special cases for intervals in R^1. *) +(* ------------------------------------------------------------------------- *) + +let INTERVAL_CASES_1 = prove + (`!x:real^1. x IN interval[a,b] ==> x IN interval(a,b) \/ (x = a) \/ (x = b)`, + REWRITE_TAC[CART_EQ; IN_INTERVAL; FORALL_DIMINDEX_1] THEN REAL_ARITH_TAC);; + +let IN_INTERVAL_1 = prove + (`!a b x:real^1. + (x IN interval[a,b] <=> drop a <= drop x /\ drop x <= drop b) /\ + (x IN interval(a,b) <=> drop a < drop x /\ drop x < drop b)`, + REWRITE_TAC[IN_INTERVAL; drop; CONJ_ASSOC; DIMINDEX_1; LE_ANTISYM] THEN + MESON_TAC[]);; + +let INTERVAL_EQ_EMPTY_1 = prove + (`!a b:real^1. + (interval[a,b] = {} <=> drop b < drop a) /\ + (interval(a,b) = {} <=> drop b <= drop a)`, + REWRITE_TAC[INTERVAL_EQ_EMPTY; drop; CONJ_ASSOC; DIMINDEX_1; LE_ANTISYM] THEN + MESON_TAC[]);; + +let INTERVAL_NE_EMPTY_1 = prove + (`(!a b:real^1. ~(interval[a,b] = {}) <=> drop a <= drop b) /\ + (!a b:real^1. ~(interval(a,b) = {}) <=> drop a < drop b)`, + REWRITE_TAC[INTERVAL_EQ_EMPTY_1] THEN REAL_ARITH_TAC);; + +let SUBSET_INTERVAL_1 = prove + (`!a b c d. + (interval[a,b] SUBSET interval[c,d] <=> + drop b < drop a \/ + drop c <= drop a /\ drop a <= drop b /\ drop b <= drop d) /\ + (interval[a,b] SUBSET interval(c,d) <=> + drop b < drop a \/ + drop c < drop a /\ drop a <= drop b /\ drop b < drop d) /\ + (interval(a,b) SUBSET interval[c,d] <=> + drop b <= drop a \/ + drop c <= drop a /\ drop a < drop b /\ drop b <= drop d) /\ + (interval(a,b) SUBSET interval(c,d) <=> + drop b <= drop a \/ + drop c <= drop a /\ drop a < drop b /\ drop b <= drop d)`, + REWRITE_TAC[SUBSET_INTERVAL; FORALL_1; DIMINDEX_1; drop] THEN + REAL_ARITH_TAC);; + +let EQ_INTERVAL_1 = prove + (`!a b c d:real^1. + (interval[a,b] = interval[c,d] <=> + drop b < drop a /\ drop d < drop c \/ + drop a = drop c /\ drop b = drop d)`, + REWRITE_TAC[SET_RULE `s = t <=> s SUBSET t /\ t SUBSET s`] THEN + REWRITE_TAC[SUBSET_INTERVAL_1] THEN REAL_ARITH_TAC);; + +let DISJOINT_INTERVAL_1 = prove + (`!a b c d:real^1. + (interval[a,b] INTER interval[c,d] = {} <=> + drop b < drop a \/ drop d < drop c \/ + drop b < drop c \/ drop d < drop a) /\ + (interval[a,b] INTER interval(c,d) = {} <=> + drop b < drop a \/ drop d <= drop c \/ + drop b <= drop c \/ drop d <= drop a) /\ + (interval(a,b) INTER interval[c,d] = {} <=> + drop b <= drop a \/ drop d < drop c \/ + drop b <= drop c \/ drop d <= drop a) /\ + (interval(a,b) INTER interval(c,d) = {} <=> + drop b <= drop a \/ drop d <= drop c \/ + drop b <= drop c \/ drop d <= drop a)`, + REWRITE_TAC[DISJOINT_INTERVAL; CONJ_ASSOC; DIMINDEX_1; LE_ANTISYM; + UNWIND_THM1; drop]);; + +let OPEN_CLOSED_INTERVAL_1 = prove + (`!a b:real^1. interval(a,b) = interval[a,b] DIFF {a,b}`, + REWRITE_TAC[EXTENSION; IN_INTERVAL_1; IN_DIFF; IN_INSERT; NOT_IN_EMPTY] THEN + REWRITE_TAC[GSYM DROP_EQ] THEN REAL_ARITH_TAC);; + +let CLOSED_OPEN_INTERVAL_1 = prove + (`!a b:real^1. drop a <= drop b ==> interval[a,b] = interval(a,b) UNION {a,b}`, + REWRITE_TAC[EXTENSION; IN_INTERVAL_1; IN_UNION; IN_INSERT; NOT_IN_EMPTY] THEN + REWRITE_TAC[GSYM DROP_EQ] THEN REAL_ARITH_TAC);; + +let BALL_1 = prove + (`!x:real^1 r. cball(x,r) = interval[x - lift r,x + lift r] /\ + ball(x,r) = interval(x - lift r,x + lift r)`, + REWRITE_TAC[EXTENSION; IN_BALL; IN_CBALL; IN_INTERVAL_1] THEN + REWRITE_TAC[dist; NORM_REAL; GSYM drop; DROP_SUB; LIFT_DROP; DROP_ADD] THEN + REAL_ARITH_TAC);; + +let SPHERE_1 = prove + (`!a:real^1 r. sphere(a,r) = if r < &0 then {} else {a - lift r,a + lift r}`, + REPEAT GEN_TAC THEN REWRITE_TAC[sphere] THEN COND_CASES_TAC THEN + REWRITE_TAC[DIST_REAL; GSYM drop; FORALL_DROP] THEN + REWRITE_TAC[EXTENSION; IN_INSERT; NOT_IN_EMPTY; IN_ELIM_THM] THEN + REWRITE_TAC[GSYM DROP_EQ; DROP_ADD; DROP_SUB; LIFT_DROP] THEN + ASM_REAL_ARITH_TAC);; + +let FINITE_SPHERE_1 = prove + (`!a:real^1 r. FINITE(sphere(a,r))`, + REPEAT GEN_TAC THEN REWRITE_TAC[SPHERE_1] THEN + MESON_TAC[FINITE_INSERT; FINITE_EMPTY]);; + +let FINITE_INTERVAL_1 = prove + (`(!a b. FINITE(interval[a,b]) <=> drop b <= drop a) /\ + (!a b. FINITE(interval(a,b)) <=> drop b <= drop a)`, + REWRITE_TAC[OPEN_CLOSED_INTERVAL_1] THEN + REWRITE_TAC[SET_RULE `s DIFF {a,b} = s DELETE a DELETE b`] THEN + REWRITE_TAC[FINITE_DELETE] THEN REPEAT GEN_TAC THEN + SUBGOAL_THEN `interval[a,b] = IMAGE lift {x | drop a <= x /\ x <= drop b}` + SUBST1_TAC THENL + [CONV_TAC SYM_CONV THEN MATCH_MP_TAC SURJECTIVE_IMAGE_EQ THEN + CONJ_TAC THENL [MESON_TAC[LIFT_DROP]; ALL_TAC] THEN + REWRITE_TAC[IN_INTERVAL_1; IN_ELIM_THM; LIFT_DROP]; + SIMP_TAC[FINITE_IMAGE_INJ_EQ; LIFT_EQ; FINITE_REAL_INTERVAL]]);; + +let BALL_INTERVAL = prove + (`!x:real^1 e. ball(x,e) = interval(x - lift e,x + lift e)`, + REWRITE_TAC[EXTENSION; IN_BALL; IN_INTERVAL_1; DIST_REAL] THEN + REWRITE_TAC[GSYM drop; DROP_SUB; DROP_ADD; LIFT_DROP] THEN REAL_ARITH_TAC);; + +let CBALL_INTERVAL = prove + (`!x:real^1 e. cball(x,e) = interval[x - lift e,x + lift e]`, + REWRITE_TAC[EXTENSION; IN_CBALL; IN_INTERVAL_1; DIST_REAL] THEN + REWRITE_TAC[GSYM drop; DROP_SUB; DROP_ADD; LIFT_DROP] THEN REAL_ARITH_TAC);; + +let BALL_INTERVAL_0 = prove + (`!e. ball(vec 0:real^1,e) = interval(--lift e,lift e)`, + GEN_TAC THEN REWRITE_TAC[BALL_INTERVAL] THEN AP_TERM_TAC THEN + BINOP_TAC THEN VECTOR_ARITH_TAC);; + +let CBALL_INTERVAL_0 = prove + (`!e. cball(vec 0:real^1,e) = interval[--lift e,lift e]`, + GEN_TAC THEN REWRITE_TAC[CBALL_INTERVAL] THEN AP_TERM_TAC THEN + AP_THM_TAC THEN AP_TERM_TAC THEN BINOP_TAC THEN VECTOR_ARITH_TAC);; + +let INTER_INTERVAL_1 = prove + (`!a b c d:real^1. + interval[a,b] INTER interval[c,d] = + interval[lift(max (drop a) (drop c)),lift(min (drop b) (drop d))]`, + REWRITE_TAC[EXTENSION; IN_INTER; IN_INTERVAL_1; real_max; real_min] THEN + REPEAT GEN_TAC THEN + REPEAT(COND_CASES_TAC THEN ASM_REWRITE_TAC[LIFT_DROP]) THEN + ASM_REAL_ARITH_TAC);; + +let CLOSED_DIFF_OPEN_INTERVAL_1 = prove + (`!a b:real^1. + interval[a,b] DIFF interval(a,b) = + if interval[a,b] = {} then {} else {a,b}`, + REWRITE_TAC[EXTENSION; IN_DIFF; INTERVAL_EQ_EMPTY_1; IN_INTERVAL_1] THEN + REPEAT GEN_TAC THEN COND_CASES_TAC THEN + ASM_REWRITE_TAC[NOT_IN_EMPTY; IN_INSERT; NOT_IN_EMPTY] THEN + REWRITE_TAC[GSYM DROP_EQ] THEN ASM_REAL_ARITH_TAC);; + +(* ------------------------------------------------------------------------- *) +(* Intervals in general, including infinite and mixtures of open and closed. *) +(* ------------------------------------------------------------------------- *) + +let is_interval = new_definition + `is_interval(s:real^N->bool) <=> + !a b x. a IN s /\ b IN s /\ + (!i. 1 <= i /\ i <= dimindex(:N) + ==> (a$i <= x$i /\ x$i <= b$i) \/ + (b$i <= x$i /\ x$i <= a$i)) + ==> x IN s`;; + +let IS_INTERVAL_INTERVAL = prove + (`!a:real^N b. is_interval(interval (a,b)) /\ is_interval(interval [a,b])`, + REWRITE_TAC[is_interval; IN_INTERVAL] THEN + MESON_TAC[REAL_LT_TRANS; REAL_LE_TRANS; REAL_LET_TRANS; REAL_LTE_TRANS]);; + +let IS_INTERVAL_EMPTY = prove + (`is_interval {}`, + REWRITE_TAC[is_interval; NOT_IN_EMPTY]);; + +let IS_INTERVAL_UNIV = prove + (`is_interval(UNIV:real^N->bool)`, + REWRITE_TAC[is_interval; IN_UNIV]);; + +let IS_INTERVAL_TRANSLATION_EQ = prove + (`!a:real^N s. is_interval(IMAGE (\x. a + x) s) <=> is_interval s`, + REWRITE_TAC[is_interval] THEN GEOM_TRANSLATE_TAC[] THEN + REWRITE_TAC[VECTOR_ADD_COMPONENT; REAL_LT_LADD; REAL_LE_LADD]);; + +add_translation_invariants [IS_INTERVAL_TRANSLATION_EQ];; + +let IS_INTERVAL_TRANSLATION = prove + (`!s a:real^N. is_interval s ==> is_interval(IMAGE (\x. a + x) s)`, + REWRITE_TAC[IS_INTERVAL_TRANSLATION_EQ]);; + +let IS_INTERVAL_POINTWISE = prove + (`!s:real^N->bool x. + is_interval s /\ + (!i. 1 <= i /\ i <= dimindex(:N) ==> ?a. a IN s /\ a$i = x$i) + ==> x IN s`, + REWRITE_TAC[is_interval] THEN REPEAT STRIP_TAC THEN + SUBGOAL_THEN + `!n. ?y:real^N. (!i. 1 <= i /\ i <= n ==> y$i = (x:real^N)$i) /\ y IN s` + MP_TAC THENL + [INDUCT_TAC THEN REWRITE_TAC[ARITH_RULE `~(1 <= i /\ i <= 0)`] THENL + [ASM_MESON_TAC[DIMINDEX_GE_1; LE_REFL]; ALL_TAC] THEN + FIRST_X_ASSUM(X_CHOOSE_TAC `y:real^N`) THEN + ASM_CASES_TAC `SUC n <= dimindex(:N)` THENL + [FIRST_X_ASSUM(MP_TAC o SPEC `SUC n`) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN + DISCH_THEN(X_CHOOSE_THEN `z:real^N` STRIP_ASSUME_TAC) THEN + EXISTS_TAC + `(lambda i. if i <= n then (y:real^N)$i else (z:real^N)$i):real^N` THEN + CONJ_TAC THENL + [X_GEN_TAC `i:num` THEN STRIP_TAC THEN + SUBGOAL_THEN `i <= dimindex(:N)` ASSUME_TAC THENL + [ASM_ARITH_TAC; ASM_SIMP_TAC[LAMBDA_BETA]] THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN + SUBGOAL_THEN `i = SUC n` (fun th -> ASM_REWRITE_TAC[th]) THEN + ASM_ARITH_TAC; + FIRST_X_ASSUM(ASSUME_TAC o CONJUNCT2) THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN + MAP_EVERY EXISTS_TAC [`y:real^N`; `z:real^N`] THEN + ASM_SIMP_TAC[LAMBDA_BETA] THEN REAL_ARITH_TAC]; + EXISTS_TAC `y:real^N` THEN ASM_REWRITE_TAC[] THEN + SUBGOAL_THEN `y:real^N = x` (fun th -> REWRITE_TAC[th]) THEN + REWRITE_TAC[CART_EQ] THEN + ASM_MESON_TAC[ARITH_RULE `i <= N /\ ~(SUC n <= N) ==> i <= n`]]; + DISCH_THEN(MP_TAC o SPEC `dimindex(:N)`) THEN + REWRITE_TAC[GSYM CART_EQ] THEN MESON_TAC[]]);; + +let IS_INTERVAL_COMPACT = prove + (`!s:real^N->bool. is_interval s /\ compact s <=> ?a b. s = interval[a,b]`, + GEN_TAC THEN EQ_TAC THEN STRIP_TAC THEN + ASM_SIMP_TAC[IS_INTERVAL_INTERVAL; COMPACT_INTERVAL] THEN + ASM_CASES_TAC `s:real^N->bool = {}` THENL + [ASM_MESON_TAC[EMPTY_AS_INTERVAL]; ALL_TAC] THEN + EXISTS_TAC `(lambda i. inf { (x:real^N)$i | x IN s}):real^N` THEN + EXISTS_TAC `(lambda i. sup { (x:real^N)$i | x IN s}):real^N` THEN + SIMP_TAC[EXTENSION; IN_INTERVAL; LAMBDA_BETA] THEN X_GEN_TAC `x:real^N` THEN + EQ_TAC THENL + [DISCH_TAC THEN X_GEN_TAC `i:num` THEN STRIP_TAC THEN + MP_TAC(ISPEC `{ (x:real^N)$i | x IN s}` INF) THEN + MP_TAC(ISPEC `{ (x:real^N)$i | x IN s}` SUP) THEN + ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN + ASM_REWRITE_TAC[IMAGE_EQ_EMPTY; FORALL_IN_IMAGE] THEN + FIRST_ASSUM(MP_TAC o MATCH_MP COMPACT_IMP_BOUNDED) THEN + REWRITE_TAC[bounded] THEN + ASM_MESON_TAC[COMPONENT_LE_NORM; REAL_LE_TRANS; MEMBER_NOT_EMPTY; + REAL_ARITH `abs(x) <= B ==> --B <= x /\ x <= B`]; + DISCH_TAC THEN MATCH_MP_TAC IS_INTERVAL_POINTWISE THEN + ASM_REWRITE_TAC[] THEN X_GEN_TAC `i:num` THEN STRIP_TAC THEN + SUBGOAL_THEN + `?a b:real^N. a IN s /\ b IN s /\ a$i <= (x:real^N)$i /\ x$i <= b$i` + STRIP_ASSUME_TAC THENL + [MP_TAC(ISPECL [`\x:real^N. x$i`; `s:real^N->bool`] + CONTINUOUS_ATTAINS_INF) THEN + ASM_SIMP_TAC[CONTINUOUS_ON_LIFT_COMPONENT; o_DEF] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `a:real^N` THEN STRIP_TAC THEN + MP_TAC(ISPECL [`\x:real^N. x$i`; `s:real^N->bool`] + CONTINUOUS_ATTAINS_SUP) THEN + ASM_SIMP_TAC[CONTINUOUS_ON_LIFT_COMPONENT; o_DEF] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `b:real^N` THEN STRIP_TAC THEN + ASM_REWRITE_TAC[] THEN CONJ_TAC THEN MATCH_MP_TAC REAL_LE_TRANS THENL + [EXISTS_TAC `inf {(x:real^N)$i | x IN s}` THEN ASM_SIMP_TAC[] THEN + MATCH_MP_TAC REAL_LE_INF THEN ASM SET_TAC[]; + EXISTS_TAC `sup {(x:real^N)$i | x IN s}` THEN ASM_SIMP_TAC[] THEN + MATCH_MP_TAC REAL_SUP_LE THEN ASM SET_TAC[]]; + EXISTS_TAC + `(lambda j. if j = i then (x:real^N)$i else (a:real^N)$j):real^N` THEN + ASM_SIMP_TAC[LAMBDA_BETA] THEN + FIRST_ASSUM(MATCH_MP_TAC o REWRITE_RULE[is_interval]) THEN + MAP_EVERY EXISTS_TAC + [`a:real^N`; + `(lambda j. if j = i then (b:real^N)$i else (a:real^N)$j):real^N`] THEN + ASM_SIMP_TAC[LAMBDA_BETA] THEN CONJ_TAC THENL + [FIRST_X_ASSUM(MATCH_MP_TAC o REWRITE_RULE[is_interval]) THEN + MAP_EVERY EXISTS_TAC [`a:real^N`; `b:real^N`] THEN + ASM_SIMP_TAC[LAMBDA_BETA]; + ALL_TAC] THEN + GEN_TAC THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN + ASM_REAL_ARITH_TAC]]);; + +let IS_INTERVAL_1 = prove + (`!s:real^1->bool. + is_interval s <=> + !a b x. a IN s /\ b IN s /\ drop a <= drop x /\ drop x <= drop b + ==> x IN s`, + REWRITE_TAC[is_interval; DIMINDEX_1; FORALL_1; GSYM drop] THEN + REWRITE_TAC[FORALL_LIFT; LIFT_DROP] THEN MESON_TAC[]);; + +let IS_INTERVAL_1_CASES = prove + (`!s:real^1->bool. + is_interval s <=> + s = {} \/ + s = (:real^1) \/ + (?a. s = {x | a < drop x}) \/ + (?a. s = {x | a <= drop x}) \/ + (?b. s = {x | drop x <= b}) \/ + (?b. s = {x | drop x < b}) \/ + (?a b. s = {x | a < drop x /\ drop x < b}) \/ + (?a b. s = {x | a < drop x /\ drop x <= b}) \/ + (?a b. s = {x | a <= drop x /\ drop x < b}) \/ + (?a b. s = {x | a <= drop x /\ drop x <= b})`, + GEN_TAC THEN REWRITE_TAC[IS_INTERVAL_1] THEN EQ_TAC THENL + [DISCH_TAC; + STRIP_TAC THEN ASM_REWRITE_TAC[IN_ELIM_THM; IN_UNIV; NOT_IN_EMPTY] THEN + REAL_ARITH_TAC] THEN + ASM_CASES_TAC `s:real^1->bool = {}` THEN ASM_REWRITE_TAC[] THEN + MP_TAC(ISPEC `IMAGE drop s` SUP) THEN + MP_TAC(ISPEC `IMAGE drop s` INF) THEN + ASM_REWRITE_TAC[IMAGE_EQ_EMPTY; FORALL_IN_IMAGE] THEN + ASM_CASES_TAC `?a. !x. x IN s ==> a <= drop x` THEN + ASM_CASES_TAC `?b. !x. x IN s ==> drop x <= b` THEN + ASM_REWRITE_TAC[] THENL + [STRIP_TAC THEN STRIP_TAC THEN + MAP_EVERY ASM_CASES_TAC + [`inf(IMAGE drop s) IN IMAGE drop s`; `sup(IMAGE drop s) IN IMAGE drop s`] + THENL + [REPLICATE_TAC 8 DISJ2_TAC; + REPLICATE_TAC 7 DISJ2_TAC THEN DISJ1_TAC; + REPLICATE_TAC 6 DISJ2_TAC THEN DISJ1_TAC; + REPLICATE_TAC 5 DISJ2_TAC THEN DISJ1_TAC] THEN + MAP_EVERY EXISTS_TAC [`inf(IMAGE drop s)`; `sup(IMAGE drop s)`]; + STRIP_TAC THEN ASM_CASES_TAC `inf(IMAGE drop s) IN IMAGE drop s` THENL + [REPLICATE_TAC 2 DISJ2_TAC THEN DISJ1_TAC; + DISJ2_TAC THEN DISJ1_TAC] THEN + EXISTS_TAC `inf(IMAGE drop s)`; + STRIP_TAC THEN ASM_CASES_TAC `sup(IMAGE drop s) IN IMAGE drop s` THENL + [REPLICATE_TAC 3 DISJ2_TAC THEN DISJ1_TAC; + REPLICATE_TAC 4 DISJ2_TAC THEN DISJ1_TAC] THEN + EXISTS_TAC `sup(IMAGE drop s)`; + DISJ1_TAC] THEN + REWRITE_TAC[EXTENSION; IN_ELIM_THM; IN_UNIV] THEN + RULE_ASSUM_TAC(REWRITE_RULE[IN_IMAGE]) THEN + REWRITE_TAC[GSYM REAL_NOT_LE] THEN + ASM_MESON_TAC[REAL_LE_TRANS; REAL_LE_TOTAL; REAL_LE_ANTISYM]);; + +let IS_INTERVAL_PCROSS = prove + (`!s:real^M->bool t:real^N->bool. + is_interval s /\ is_interval t ==> is_interval(s PCROSS t)`, + REWRITE_TAC[is_interval; DIMINDEX_FINITE_SUM] THEN + REWRITE_TAC[FORALL_PASTECART; PASTECART_IN_PCROSS] THEN + REPEAT GEN_TAC THEN + MATCH_MP_TAC(MESON[] + `(!a b a' b' x x'. P a b x /\ Q a' b' x' ==> R a b x a' b' x') + ==> (!a b x. P a b x) /\ (!a' b' x'. Q a' b' x') + ==> (!a a' b b' x x'. R a b x a' b' x')`) THEN + REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_REWRITE_TAC[] THEN X_GEN_TAC `i:num` THEN STRIP_TAC THENL + [FIRST_X_ASSUM(MP_TAC o SPEC `i:num`) THEN + ASM_SIMP_TAC[pastecart; LAMBDA_BETA; DIMINDEX_FINITE_SUM; + ARITH_RULE `x:num <= m ==> x <= m + n`]; + FIRST_X_ASSUM(MP_TAC o SPEC `dimindex(:M) + i`) THEN + ASM_SIMP_TAC[pastecart; LAMBDA_BETA; DIMINDEX_FINITE_SUM; + ARITH_RULE `x:num <= n ==> m + x <= m + n`; + ARITH_RULE `1 <= x ==> 1 <= m + x`] THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[ADD_SUB2] THEN ASM_ARITH_TAC]);; + +let IS_INTERVAL_PCROSS_EQ = prove + (`!s:real^M->bool t:real^N->bool. + is_interval(s PCROSS t) <=> + s = {} \/ t = {} \/ is_interval s /\ is_interval t`, + REPEAT GEN_TAC THEN + ASM_CASES_TAC `s:real^M->bool = {}` THEN + ASM_REWRITE_TAC[PCROSS_EMPTY; IS_INTERVAL_EMPTY] THEN + ASM_CASES_TAC `t:real^N->bool = {}` THEN + ASM_REWRITE_TAC[PCROSS_EMPTY; IS_INTERVAL_EMPTY] THEN + EQ_TAC THEN REWRITE_TAC[IS_INTERVAL_PCROSS] THEN + REWRITE_TAC[is_interval] THEN + REWRITE_TAC[FORALL_PASTECART; PASTECART_IN_PCROSS] THEN + STRIP_TAC THEN CONJ_TAC THENL + [MAP_EVERY X_GEN_TAC [`a:real^M`; `b:real^M`; `x:real^M`] THEN + STRIP_TAC THEN UNDISCH_TAC `~(t:real^N->bool = {})` THEN + REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN + DISCH_THEN(X_CHOOSE_TAC `y:real^N`) THEN + FIRST_X_ASSUM(MP_TAC o SPECL + [`a:real^M`; `y:real^N`; `b:real^M`; + `y:real^N`; `x:real^M`; `y:real^N`]); + MAP_EVERY X_GEN_TAC [`a:real^N`; `b:real^N`; `x:real^N`] THEN + STRIP_TAC THEN UNDISCH_TAC `~(s:real^M->bool = {})` THEN + REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN + DISCH_THEN(X_CHOOSE_TAC `w:real^M`) THEN + FIRST_X_ASSUM(MP_TAC o SPECL + [`w:real^M`; `a:real^N`; `w:real^M`; + `b:real^N`; `w:real^M`; `x:real^N`])] THEN + ASM_REWRITE_TAC[] THEN DISCH_THEN MATCH_MP_TAC THEN + SIMP_TAC[pastecart; LAMBDA_BETA] THEN + REPEAT STRIP_TAC THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[REAL_LE_REFL] THEN + ASM_MESON_TAC[DIMINDEX_FINITE_SUM; ARITH_RULE + `1 <= i /\ i <= m + n /\ ~(i <= m) ==> 1 <= i - m /\ i - m <= n`]);; + +let IS_INTERVAL_INTER = prove + (`!s t:real^N->bool. + is_interval s /\ is_interval t ==> is_interval(s INTER t)`, + REWRITE_TAC[is_interval; IN_INTER] THEN REPEAT GEN_TAC THEN STRIP_TAC THEN + MAP_EVERY X_GEN_TAC [`a:real^N`; `b:real^N`; `x:real^N`] THEN + REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + MAP_EVERY EXISTS_TAC [`a:real^N`; `b:real^N`] THEN ASM_REWRITE_TAC[]);; + +let INTERVAL_SUBSET_IS_INTERVAL = prove + (`!s a b:real^N. + is_interval s + ==> (interval[a,b] SUBSET s <=> interval[a,b] = {} \/ a IN s /\ b IN s)`, + REWRITE_TAC[is_interval] THEN REPEAT STRIP_TAC THEN + ASM_CASES_TAC `interval[a:real^N,b] = {}` THEN + ASM_REWRITE_TAC[EMPTY_SUBSET] THEN + EQ_TAC THENL [ASM_MESON_TAC[ENDS_IN_INTERVAL; SUBSET]; ALL_TAC] THEN + REWRITE_TAC[SUBSET; IN_INTERVAL] THEN ASM_MESON_TAC[]);; + +let INTERVAL_CONTAINS_COMPACT_NEIGHBOURHOOD = prove + (`!s x:real^N. + is_interval s /\ x IN s + ==> ?a b d. &0 < d /\ x IN interval[a,b] /\ + interval[a,b] SUBSET s /\ + ball(x,d) INTER s SUBSET interval[a,b]`, + REPEAT STRIP_TAC THEN ASM_SIMP_TAC[INTERVAL_SUBSET_IS_INTERVAL] THEN + SUBGOAL_THEN + `!i. 1 <= i /\ i <= dimindex(:N) + ==> ?a. (?y. y IN s /\ y$i = a) /\ + (a < x$i \/ a = (x:real^N)$i /\ + !y:real^N. y IN s ==> a <= y$i)` + MP_TAC THENL [ASM_MESON_TAC[REAL_NOT_LT]; REWRITE_TAC[LAMBDA_SKOLEM]] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `a:real^N` THEN STRIP_TAC THEN + SUBGOAL_THEN + `!i. 1 <= i /\ i <= dimindex(:N) + ==> ?b. (?y. y IN s /\ y$i = b) /\ + (x$i < b \/ b = (x:real^N)$i /\ + !y:real^N. y IN s ==> y$i <= b)` + MP_TAC THENL [ASM_MESON_TAC[REAL_NOT_LT]; REWRITE_TAC[LAMBDA_SKOLEM]] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `b:real^N` THEN STRIP_TAC THEN + EXISTS_TAC `min (inf (IMAGE (\i. if a$i < x$i + then (x:real^N)$i - (a:real^N)$i else &1) + (1..dimindex(:N)))) + (inf (IMAGE (\i. if x$i < b$i + then (b:real^N)$i - x$i else &1) + (1..dimindex(:N))))` THEN + REWRITE_TAC[REAL_LT_MIN; SUBSET; IN_BALL; IN_INTER] THEN + SIMP_TAC[REAL_LT_INF_FINITE; IMAGE_EQ_EMPTY; FINITE_IMAGE; + FINITE_NUMSEG; NUMSEG_EMPTY; GSYM NOT_LE; DIMINDEX_GE_1] THEN + REWRITE_TAC[FORALL_IN_IMAGE; IN_INTERVAL] THEN REPEAT CONJ_TAC THENL + [MESON_TAC[REAL_SUB_LT; REAL_LT_01]; + MESON_TAC[REAL_SUB_LT; REAL_LT_01]; + ASM_MESON_TAC[REAL_LE_LT]; + DISJ2_TAC THEN CONJ_TAC THEN MATCH_MP_TAC IS_INTERVAL_POINTWISE THEN + ASM_MESON_TAC[]; + X_GEN_TAC `y:real^N` THEN + DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN + REWRITE_TAC[AND_FORALL_THM] THEN MATCH_MP_TAC MONO_FORALL THEN + X_GEN_TAC `i:num` THEN DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN + ASM_REWRITE_TAC[IN_NUMSEG] THEN MATCH_MP_TAC MONO_AND THEN CONJ_TAC THEN + (COND_CASES_TAC THENL [REWRITE_TAC[dist]; ASM_MESON_TAC[]]) THEN + DISCH_TAC THEN MP_TAC(ISPECL [`x - y:real^N`; `i:num`] + COMPONENT_LE_NORM) THEN + ASM_REWRITE_TAC[VECTOR_SUB_COMPONENT] THEN ASM_REAL_ARITH_TAC]);; + +let IS_INTERVAL_SUMS = prove + (`!s t:real^N->bool. + is_interval s /\ is_interval t + ==> is_interval {x + y | x IN s /\ y IN t}`, + REPEAT GEN_TAC THEN REWRITE_TAC[is_interval] THEN + REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN + REWRITE_TAC[FORALL_IN_GSPEC] THEN + REWRITE_TAC[RIGHT_IMP_FORALL_THM] THEN + REWRITE_TAC[IMP_IMP; GSYM CONJ_ASSOC] THEN + MAP_EVERY X_GEN_TAC + [`a:real^N`; `a':real^N`; `b:real^N`; `b':real^N`; `y:real^N`] THEN + DISCH_THEN(CONJUNCTS_THEN2 + (MP_TAC o SPECL [`a:real^N`; `b:real^N`]) MP_TAC) THEN + DISCH_THEN(CONJUNCTS_THEN2 + (MP_TAC o SPECL [`a':real^N`; `b':real^N`]) STRIP_ASSUME_TAC) THEN + ASM_REWRITE_TAC[IMP_IMP; IN_ELIM_THM] THEN ONCE_REWRITE_TAC[CONJ_SYM] THEN + ONCE_REWRITE_TAC[VECTOR_ARITH `z:real^N = x + y <=> y = z - x`] THEN + REWRITE_TAC[UNWIND_THM2] THEN MATCH_MP_TAC(MESON[] + `(?x. P x /\ Q(f x)) + ==> (!x. P x ==> x IN s) /\ (!x. Q x ==> x IN t) + ==> ?x. x IN s /\ f x IN t`) THEN + REWRITE_TAC[VECTOR_SUB_COMPONENT; AND_FORALL_THM; + TAUT `(p ==> q) /\ (p ==> r) <=> p ==> q /\ r`] THEN + REWRITE_TAC[GSYM LAMBDA_SKOLEM] THEN + X_GEN_TAC `i:num` THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `i:num`) THEN + ASM_REWRITE_TAC[VECTOR_ADD_COMPONENT] THEN + REWRITE_TAC[REAL_ARITH + `c <= y - x /\ y - x <= d <=> y - d <= x /\ x <= y - c`] THEN + REWRITE_TAC[REAL_ARITH + `a <= x /\ x <= b \/ b <= x /\ x <= a <=> min a b <= x /\ x <= max a b`] THEN + ONCE_REWRITE_TAC[TAUT `(p /\ q) /\ (r /\ s) <=> (p /\ r) /\ (q /\ s)`] THEN + REWRITE_TAC[GSYM REAL_LE_MIN; GSYM REAL_MAX_LE] THEN + REWRITE_TAC[GSYM REAL_LE_BETWEEN] THEN REAL_ARITH_TAC);; + +let IS_INTERVAL_SING = prove + (`!a:real^N. is_interval {a}`, + SIMP_TAC[is_interval; IN_SING; IMP_CONJ; CART_EQ; REAL_LE_ANTISYM]);; + +let IS_INTERVAL_SCALING = prove + (`!s:real^N->bool c. is_interval s ==> is_interval(IMAGE (\x. c % x) s)`, + REPEAT GEN_TAC THEN ASM_CASES_TAC `c = &0` THENL + [ASM_REWRITE_TAC[VECTOR_MUL_LZERO] THEN + SUBGOAL_THEN `IMAGE ((\x. vec 0):real^N->real^N) s = {} \/ + IMAGE ((\x. vec 0):real^N->real^N) s = {vec 0}` + STRIP_ASSUME_TAC THENL + [SET_TAC[]; + ASM_REWRITE_TAC[IS_INTERVAL_EMPTY]; + ASM_REWRITE_TAC[IS_INTERVAL_SING]]; + REWRITE_TAC[is_interval; IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN + REWRITE_TAC[FORALL_IN_IMAGE] THEN + GEN_REWRITE_TAC (BINOP_CONV o REDEPTH_CONV) [RIGHT_IMP_FORALL_THM] THEN + REWRITE_TAC[IMP_IMP; VECTOR_MUL_COMPONENT] THEN + MAP_EVERY (fun t -> MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC t) + [`a:real^N`; `b:real^N`] THEN + DISCH_THEN(fun th -> X_GEN_TAC `x:real^N` THEN STRIP_TAC THEN + MP_TAC(SPEC `inv(c) % x:real^N` th)) THEN + ASM_REWRITE_TAC[VECTOR_MUL_COMPONENT; IN_IMAGE] THEN ANTS_TAC THENL + [X_GEN_TAC `i:num` THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `i:num`) THEN ASM_REWRITE_TAC[] THEN + ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN REWRITE_TAC[GSYM real_div] THEN + FIRST_X_ASSUM(DISJ_CASES_TAC o MATCH_MP (REAL_ARITH + `~(c = &0) ==> &0 < c \/ &0 < --c`)) THEN + ASM_SIMP_TAC[REAL_LE_RDIV_EQ; REAL_LE_LDIV_EQ] THEN + GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [GSYM REAL_LE_NEG2] THEN + ASM_SIMP_TAC[GSYM REAL_MUL_RNEG; GSYM REAL_LE_RDIV_EQ; GSYM + REAL_LE_LDIV_EQ] THEN + REWRITE_TAC[real_div; REAL_INV_NEG] THEN REAL_ARITH_TAC; + DISCH_TAC THEN EXISTS_TAC `inv c % x:real^N` THEN + ASM_SIMP_TAC[VECTOR_MUL_ASSOC; REAL_MUL_RINV; VECTOR_MUL_LID]]]);; + +let IS_INTERVAL_SCALING_EQ = prove + (`!s:real^N->bool c. + is_interval(IMAGE (\x. c % x) s) <=> c = &0 \/ is_interval s`, + REPEAT GEN_TAC THEN ASM_CASES_TAC `c = &0` THENL + [ASM_REWRITE_TAC[VECTOR_MUL_LZERO] THEN + SUBGOAL_THEN `IMAGE ((\x. vec 0):real^N->real^N) s = {} \/ + IMAGE ((\x. vec 0):real^N->real^N) s = {vec 0}` + STRIP_ASSUME_TAC THENL + [SET_TAC[]; + ASM_REWRITE_TAC[IS_INTERVAL_EMPTY]; + ASM_REWRITE_TAC[IS_INTERVAL_SING]]; + ASM_REWRITE_TAC[] THEN EQ_TAC THEN REWRITE_TAC[IS_INTERVAL_SCALING] THEN + DISCH_THEN(MP_TAC o SPEC `inv c:real` o MATCH_MP IS_INTERVAL_SCALING) THEN + ASM_SIMP_TAC[GSYM IMAGE_o; VECTOR_MUL_ASSOC; o_DEF; REAL_MUL_LINV; + VECTOR_MUL_LID; IMAGE_ID]]);; + +let lemma = prove + (`!c. &0 < c + ==> !s:real^N->bool. is_interval(IMAGE (\x. c % x) s) <=> + is_interval s`, + SIMP_TAC[IS_INTERVAL_SCALING_EQ; REAL_LT_IMP_NZ]) in +add_scaling_theorems [lemma];; + +(* ------------------------------------------------------------------------- *) +(* Line segments, with same open/closed overloading as for intervals. *) +(* ------------------------------------------------------------------------- *) + +let closed_segment = define + `closed_segment[a,b] = {(&1 - u) % a + u % b | &0 <= u /\ u <= &1}`;; + +let open_segment = new_definition + `open_segment(a,b) = closed_segment[a,b] DIFF {a,b}`;; + +let OPEN_SEGMENT_ALT = prove + (`!a b:real^N. + ~(a = b) + ==> open_segment(a,b) = {(&1 - u) % a + u % b | &0 < u /\ u < &1}`, + REPEAT STRIP_TAC THEN REWRITE_TAC[open_segment; closed_segment] THEN + REWRITE_TAC[EXTENSION; IN_DIFF; IN_INSERT; NOT_IN_EMPTY; IN_ELIM_THM] THEN + X_GEN_TAC `x:real^N` THEN REWRITE_TAC[LEFT_AND_EXISTS_THM] THEN + AP_TERM_TAC THEN REWRITE_TAC[FUN_EQ_THM] THEN + X_GEN_TAC `u:real` THEN ASM_CASES_TAC `x:real^N = (&1 - u) % a + u % b` THEN + ASM_REWRITE_TAC[REAL_LE_LT; + VECTOR_ARITH `(&1 - u) % a + u % b = a <=> u % (b - a) = vec 0`; + VECTOR_ARITH `(&1 - u) % a + u % b = b <=> (&1 - u) % (b - a) = vec 0`; + VECTOR_MUL_EQ_0; REAL_SUB_0; VECTOR_SUB_EQ] THEN + REAL_ARITH_TAC);; + +make_overloadable "segment" `:A`;; + +overload_interface("segment",`open_segment`);; +overload_interface("segment",`closed_segment`);; + +let segment = prove + (`segment[a,b] = {(&1 - u) % a + u % b | &0 <= u /\ u <= &1} /\ + segment(a,b) = segment[a,b] DIFF {a,b}`, + REWRITE_TAC[open_segment; closed_segment]);; + +let SEGMENT_REFL = prove + (`(!a. segment[a,a] = {a}) /\ + (!a. segment(a,a) = {})`, + REWRITE_TAC[segment; VECTOR_ARITH `(&1 - u) % a + u % a = a`] THEN + SET_TAC[REAL_POS]);; + +let IN_SEGMENT = prove + (`!a b x:real^N. + (x IN segment[a,b] <=> + ?u. &0 <= u /\ u <= &1 /\ x = (&1 - u) % a + u % b) /\ + (x IN segment(a,b) <=> + ~(a = b) /\ ?u. &0 < u /\ u < &1 /\ x = (&1 - u) % a + u % b)`, + REPEAT STRIP_TAC THENL + [REWRITE_TAC[segment; IN_ELIM_THM; CONJ_ASSOC]; ALL_TAC] THEN + ASM_CASES_TAC `a:real^N = b` THEN + ASM_REWRITE_TAC[SEGMENT_REFL; NOT_IN_EMPTY] THEN + ASM_SIMP_TAC[OPEN_SEGMENT_ALT; IN_ELIM_THM; CONJ_ASSOC]);; + +let SEGMENT_SYM = prove + (`(!a b:real^N. segment[a,b] = segment[b,a]) /\ + (!a b:real^N. segment(a,b) = segment(b,a))`, + MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN + SIMP_TAC[open_segment] THEN + CONJ_TAC THENL [ALL_TAC; SIMP_TAC[INSERT_AC]] THEN + REWRITE_TAC[EXTENSION; IN_SEGMENT] THEN REPEAT GEN_TAC THEN EQ_TAC THEN + DISCH_THEN(X_CHOOSE_TAC `u:real`) THEN EXISTS_TAC `&1 - u` THEN + ASM_REWRITE_TAC[] THEN + REPEAT CONJ_TAC THEN TRY ASM_ARITH_TAC THEN VECTOR_ARITH_TAC);; + +let ENDS_IN_SEGMENT = prove + (`!a b. a IN segment[a,b] /\ b IN segment[a,b]`, + REPEAT STRIP_TAC THEN REWRITE_TAC[segment; IN_ELIM_THM] THENL + [EXISTS_TAC `&0`; EXISTS_TAC `&1`] THEN + (CONJ_TAC THENL [REAL_ARITH_TAC; VECTOR_ARITH_TAC]));; + +let ENDS_NOT_IN_SEGMENT = prove + (`!a b. ~(a IN segment(a,b)) /\ ~(b IN segment(a,b))`, + REWRITE_TAC[open_segment] THEN SET_TAC[]);; + +let SEGMENT_CLOSED_OPEN = prove + (`!a b. segment[a,b] = segment(a,b) UNION {a,b}`, + REPEAT GEN_TAC THEN REWRITE_TAC[open_segment] THEN MATCH_MP_TAC(SET_RULE + `a IN s /\ b IN s ==> s = (s DIFF {a,b}) UNION {a,b}`) THEN + REWRITE_TAC[ENDS_IN_SEGMENT]);; + +let MIDPOINT_IN_SEGMENT = prove + (`(!a b:real^N. midpoint(a,b) IN segment[a,b]) /\ + (!a b:real^N. midpoint(a,b) IN segment(a,b) <=> ~(a = b))`, + REWRITE_TAC[IN_SEGMENT] THEN REPEAT STRIP_TAC THENL + [ALL_TAC; ASM_CASES_TAC `a:real^N = b` THEN ASM_REWRITE_TAC[]] THEN + EXISTS_TAC `&1 / &2` THEN REWRITE_TAC[midpoint] THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN VECTOR_ARITH_TAC);; + +let BETWEEN_IN_SEGMENT = prove + (`!x a b:real^N. between x (a,b) <=> x IN segment[a,b]`, + REPEAT GEN_TAC THEN REWRITE_TAC[between] THEN + ASM_CASES_TAC `a:real^N = b` THEN + ASM_REWRITE_TAC[SEGMENT_REFL; IN_SING] THENL [NORM_ARITH_TAC; ALL_TAC] THEN + REWRITE_TAC[segment; IN_ELIM_THM] THEN EQ_TAC THENL + [DISCH_THEN(ASSUME_TAC o SYM) THEN + EXISTS_TAC `dist(a:real^N,x) / dist(a,b)` THEN + ASM_SIMP_TAC[REAL_LE_LDIV_EQ; REAL_LE_RDIV_EQ; DIST_POS_LT] THEN CONJ_TAC + THENL [FIRST_ASSUM(SUBST1_TAC o SYM) THEN NORM_ARITH_TAC; ALL_TAC] THEN + MATCH_MP_TAC VECTOR_MUL_LCANCEL_IMP THEN EXISTS_TAC `dist(a:real^N,b)` THEN + ASM_SIMP_TAC[VECTOR_MUL_ASSOC; VECTOR_ADD_LDISTRIB; REAL_SUB_LDISTRIB; + REAL_DIV_LMUL; DIST_EQ_0] THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [DIST_TRIANGLE_EQ] o SYM) THEN + FIRST_ASSUM(SUBST1_TAC o SYM) THEN + REWRITE_TAC[dist; REAL_ARITH `(a + b) * &1 - a = b`] THEN + VECTOR_ARITH_TAC; + STRIP_TAC THEN ASM_REWRITE_TAC[dist] THEN + REWRITE_TAC[VECTOR_ARITH `a - ((&1 - u) % a + u % b) = u % (a - b)`; + VECTOR_ARITH `((&1 - u) % a + u % b) - b = (&1 - u) % (a - b)`; + NORM_MUL; GSYM REAL_ADD_LDISTRIB] THEN + REPEAT(POP_ASSUM MP_TAC) THEN CONV_TAC REAL_FIELD]);; + +let IN_SEGMENT_COMPONENT = prove + (`!a b x:real^N i. + x IN segment[a,b] /\ 1 <= i /\ i <= dimindex(:N) + ==> min (a$i) (b$i) <= x$i /\ x$i <= max (a$i) (b$i)`, + REPEAT STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_SEGMENT]) THEN + DISCH_THEN(REPEAT_TCL CONJUNCTS_THEN ASSUME_TAC) THEN + FIRST_X_ASSUM(X_CHOOSE_THEN `t:real` STRIP_ASSUME_TAC) THEN + ASM_REWRITE_TAC[VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT] THEN + SIMP_TAC[REAL_ARITH `c <= u * a + t * b <=> u * --a + t * --b <= --c`] THEN + MATCH_MP_TAC REAL_CONVEX_BOUND_LE THEN ASM_REAL_ARITH_TAC);; + +let SEGMENT_1 = prove + (`(!a b. segment[a,b] = + if drop a <= drop b then interval[a,b] else interval[b,a]) /\ + (!a b. segment(a,b) = + if drop a <= drop b then interval(a,b) else interval(b,a))`, + CONJ_TAC THEN REPEAT GEN_TAC THEN REWRITE_TAC[open_segment] THEN + COND_CASES_TAC THEN + REWRITE_TAC[IN_DIFF; IN_INSERT; NOT_IN_EMPTY; + EXTENSION; GSYM BETWEEN_IN_SEGMENT; between; IN_INTERVAL_1] THEN + REWRITE_TAC[GSYM DROP_EQ; DIST_REAL; GSYM drop] THEN ASM_REAL_ARITH_TAC);; + +let OPEN_SEGMENT_1 = prove + (`!a b:real^1. open(segment(a,b))`, + REPEAT GEN_TAC THEN REWRITE_TAC[SEGMENT_1] THEN + COND_CASES_TAC THEN REWRITE_TAC[OPEN_INTERVAL]);; + +let SEGMENT_TRANSLATION = prove + (`(!c a b. segment[c + a,c + b] = IMAGE (\x. c + x) (segment[a,b])) /\ + (!c a b. segment(c + a,c + b) = IMAGE (\x. c + x) (segment(a,b)))`, + REWRITE_TAC[EXTENSION; IN_SEGMENT; IN_IMAGE] THEN + REWRITE_TAC[VECTOR_ARITH `(&1 - u) % (c + a) + u % (c + b) = + c + (&1 - u) % a + u % b`] THEN + REWRITE_TAC[VECTOR_ARITH `c + a:real^N = c + b <=> a = b`] THEN + MESON_TAC[]);; + +add_translation_invariants + [CONJUNCT1 SEGMENT_TRANSLATION; CONJUNCT2 SEGMENT_TRANSLATION];; + +let CLOSED_SEGMENT_LINEAR_IMAGE = prove + (`!f a b. linear f + ==> segment[f a,f b] = IMAGE f (segment[a,b])`, + REPEAT STRIP_TAC THEN REWRITE_TAC[EXTENSION; IN_IMAGE; IN_SEGMENT] THEN + FIRST_ASSUM(fun th -> REWRITE_TAC[GSYM(MATCH_MP LINEAR_CMUL th)]) THEN + FIRST_ASSUM(fun th -> REWRITE_TAC[GSYM(MATCH_MP LINEAR_ADD th)]) THEN + MESON_TAC[]);; + +add_linear_invariants [CLOSED_SEGMENT_LINEAR_IMAGE];; + +let OPEN_SEGMENT_LINEAR_IMAGE = prove + (`!f:real^M->real^N a b. + linear f /\ (!x y. f x = f y ==> x = y) + ==> segment(f a,f b) = IMAGE f (segment(a,b))`, + REWRITE_TAC[open_segment] THEN GEOM_TRANSFORM_TAC[]);; + +add_linear_invariants [OPEN_SEGMENT_LINEAR_IMAGE];; + +let IN_OPEN_SEGMENT = prove + (`!a b x:real^N. + x IN segment(a,b) <=> x IN segment[a,b] /\ ~(x = a) /\ ~(x = b)`, + REPEAT GEN_TAC THEN REWRITE_TAC[open_segment; IN_DIFF] THEN SET_TAC[]);; + +let IN_OPEN_SEGMENT_ALT = prove + (`!a b x:real^N. + x IN segment(a,b) <=> + x IN segment[a,b] /\ ~(x = a) /\ ~(x = b) /\ ~(a = b)`, + REPEAT GEN_TAC THEN ASM_CASES_TAC `a:real^N = b` THEN + ASM_REWRITE_TAC[SEGMENT_REFL; IN_SING; NOT_IN_EMPTY] THEN + ASM_MESON_TAC[IN_OPEN_SEGMENT]);; + +let COLLINEAR_DIST_IN_CLOSED_SEGMENT = prove + (`!a b x. collinear {x,a,b} /\ + dist(x,a) <= dist(a,b) /\ dist(x,b) <= dist(a,b) + ==> x IN segment[a,b]`, + REWRITE_TAC[GSYM BETWEEN_IN_SEGMENT; COLLINEAR_DIST_BETWEEN]);; + +let COLLINEAR_DIST_IN_OPEN_SEGMENT = prove + (`!a b x. collinear {x,a,b} /\ + dist(x,a) < dist(a,b) /\ dist(x,b) < dist(a,b) + ==> x IN segment(a,b)`, + REWRITE_TAC[IN_OPEN_SEGMENT] THEN + MESON_TAC[COLLINEAR_DIST_IN_CLOSED_SEGMENT; REAL_LT_LE; DIST_SYM]);; + +let SEGMENT_SCALAR_MULTIPLE = prove + (`(!a b v. segment[a % v,b % v] = + {x % v:real^N | a <= x /\ x <= b \/ b <= x /\ x <= a}) /\ + (!a b v. ~(v = vec 0) + ==> segment(a % v,b % v) = + {x % v:real^N | a < x /\ x < b \/ b < x /\ x < a})`, + MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN REPEAT STRIP_TAC THENL + [REPEAT GEN_TAC THEN + MP_TAC(SPECL [`a % basis 1:real^1`; `b % basis 1:real^1`] + (CONJUNCT1 SEGMENT_1)) THEN + REWRITE_TAC[segment; VECTOR_MUL_ASSOC; GSYM VECTOR_ADD_RDISTRIB] THEN + REWRITE_TAC[SET_RULE `{f x % b | p x} = IMAGE (\a. a % b) {f x | p x}`] THEN + DISCH_TAC THEN AP_TERM_TAC THEN + FIRST_X_ASSUM(MP_TAC o AP_TERM `IMAGE drop`) THEN + REWRITE_TAC[GSYM IMAGE_o; o_DEF; DROP_CMUL] THEN + SIMP_TAC[drop; BASIS_COMPONENT; DIMINDEX_GE_1; LE_REFL] THEN + REWRITE_TAC[REAL_MUL_RID; IMAGE_ID] THEN DISCH_THEN SUBST1_TAC THEN + MATCH_MP_TAC SURJECTIVE_IMAGE_EQ THEN + CONJ_TAC THENL [MESON_TAC[LIFT_DROP]; ALL_TAC] THEN + REWRITE_TAC[FORALL_LIFT; LIFT_DROP] THEN GEN_TAC THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[IN_INTERVAL_1; LIFT_DROP] THEN + SIMP_TAC[drop; VECTOR_MUL_COMPONENT; BASIS_COMPONENT; DIMINDEX_GE_1; + LE_REFL; IN_ELIM_THM] THEN ASM_REAL_ARITH_TAC; + ASM_REWRITE_TAC[open_segment] THEN + ASM_SIMP_TAC[VECTOR_MUL_RCANCEL; SET_RULE + `(!x y. x % v = y % v <=> x = y) + ==> {x % v | P x} DIFF {a % v,b % v} = + {x % v | P x /\ ~(x = a) /\ ~(x = b)}`] THEN + ONCE_REWRITE_TAC[SIMPLE_IMAGE_GEN] THEN AP_TERM_TAC THEN + REWRITE_TAC[EXTENSION; IN_ELIM_THM] THEN REAL_ARITH_TAC]);; + +let FINITE_INTER_COLLINEAR_OPEN_SEGMENTS = prove + (`!a b c d:real^N. + collinear{a,b,c} + ==> (FINITE(segment(a,b) INTER segment(c,d)) <=> + segment(a,b) INTER segment(c,d) = {})`, + REPEAT GEN_TAC THEN ABBREV_TAC `m:real^N = b - a` THEN POP_ASSUM MP_TAC THEN + GEOM_NORMALIZE_TAC `m:real^N` THEN + SIMP_TAC[VECTOR_SUB_EQ; SEGMENT_REFL; INTER_EMPTY; FINITE_EMPTY] THEN + X_GEN_TAC `m:real^N` THEN DISCH_TAC THEN REPEAT GEN_TAC THEN + DISCH_THEN(SUBST_ALL_TAC o SYM) THEN POP_ASSUM MP_TAC THEN + GEOM_ORIGIN_TAC `a:real^N` THEN GEOM_BASIS_MULTIPLE_TAC 1 `b:real^N` THEN + X_GEN_TAC `b:real` THEN DISCH_TAC THEN + MAP_EVERY X_GEN_TAC [`x:real^N`; `y:real^N`] THEN + SIMP_TAC[VECTOR_SUB_RZERO; NORM_MUL; NORM_BASIS; DIMINDEX_GE_1; LE_REFL] THEN + ASM_REWRITE_TAC[real_abs; REAL_MUL_RID] THEN DISCH_THEN SUBST_ALL_TAC THEN + POP_ASSUM(K ALL_TAC) THEN + ASM_CASES_TAC `collinear{vec 0:real^N,&1 % basis 1,y}` THENL + [POP_ASSUM MP_TAC THEN + SIMP_TAC[COLLINEAR_LEMMA_ALT; BASIS_NONZERO; DIMINDEX_GE_1; LE_REFL] THEN + MATCH_MP_TAC(TAUT + `~a /\ (b ==> c ==> d) ==> a \/ b ==> a \/ c ==> d`) THEN + CONJ_TAC THENL + [SIMP_TAC[VECTOR_MUL_LID; BASIS_NONZERO; DIMINDEX_GE_1; LE_REFL]; + REWRITE_TAC[LEFT_IMP_EXISTS_THM]] THEN + X_GEN_TAC `b:real` THEN DISCH_THEN SUBST_ALL_TAC THEN + X_GEN_TAC `a:real` THEN DISCH_THEN SUBST_ALL_TAC THEN + REWRITE_TAC[VECTOR_MUL_ASSOC; REAL_MUL_RID] THEN + SUBST1_TAC(VECTOR_ARITH `vec 0:real^N = &0 % basis 1`) THEN + SIMP_TAC[SEGMENT_SCALAR_MULTIPLE; BASIS_NONZERO; DIMINDEX_GE_1; LE_REFL; + VECTOR_MUL_RCANCEL; IMAGE_EQ_EMPTY; FINITE_IMAGE_INJ_EQ; SET_RULE + `(!x y. x % v = y % v <=> x = y) + ==> {x % v | P x} INTER {x % v | Q x} = + IMAGE (\x. x % v) {x | P x /\ Q x}`] THEN + REWRITE_TAC[REAL_ARITH `(&0 < x /\ x < &1 \/ &1 < x /\ x < &0) /\ + (b < x /\ x < a \/ a < x /\ x < b) <=> + max (&0) (min a b) < x /\ x < min (&1) (max a b)`] THEN + SIMP_TAC[FINITE_REAL_INTERVAL; EXTENSION; NOT_IN_EMPTY; IN_ELIM_THM] THEN + SIMP_TAC[GSYM REAL_LT_BETWEEN; GSYM NOT_EXISTS_THM] THEN REAL_ARITH_TAC; + DISCH_TAC THEN ASM_CASES_TAC + `segment(vec 0:real^N,&1 % basis 1) INTER segment (x,y) = {}` THEN + ASM_REWRITE_TAC[FINITE_EMPTY] THEN DISCH_THEN(K ALL_TAC) THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN + REWRITE_TAC[open_segment; IN_DIFF; NOT_IN_EMPTY; + DE_MORGAN_THM; IN_INTER; IN_INSERT] THEN + DISCH_THEN(X_CHOOSE_THEN `p:real^N` STRIP_ASSUME_TAC) THEN + UNDISCH_TAC `~collinear{vec 0:real^N,&1 % basis 1, y}` THEN + RULE_ASSUM_TAC(REWRITE_RULE[VECTOR_MUL_LID]) THEN + REWRITE_TAC[VECTOR_MUL_LID] THEN + MATCH_MP_TAC COLLINEAR_SUBSET THEN + EXISTS_TAC `{p,x:real^N, y, vec 0, basis 1}` THEN + CONJ_TAC THENL [ALL_TAC; SET_TAC[]] THEN + MP_TAC(ISPECL [`{y:real^N,vec 0,basis 1}`; `p:real^N`; `x:real^N`] + COLLINEAR_TRIPLES) THEN + ASM_REWRITE_TAC[] THEN DISCH_THEN SUBST1_TAC THEN + REWRITE_TAC[FORALL_IN_INSERT; NOT_IN_EMPTY] THEN CONJ_TAC THENL + [ONCE_REWRITE_TAC[SET_RULE `{p,x,y} = {x,p,y}`] THEN + MATCH_MP_TAC BETWEEN_IMP_COLLINEAR THEN + ASM_REWRITE_TAC[BETWEEN_IN_SEGMENT]; + ALL_TAC] THEN + ASM_SIMP_TAC[GSYM COLLINEAR_4_3] THEN + ONCE_REWRITE_TAC[SET_RULE `{p,x,z,w} = {w,z,p,x}`] THEN + SIMP_TAC[COLLINEAR_4_3; BASIS_NONZERO; DIMINDEX_GE_1; ARITH] THEN + REPEAT(FIRST_X_ASSUM(MP_TAC o MATCH_MP BETWEEN_IMP_COLLINEAR o + GEN_REWRITE_RULE I [GSYM BETWEEN_IN_SEGMENT])) THEN + REPEAT(POP_ASSUM MP_TAC) THEN SIMP_TAC[INSERT_AC]]);; + +let DIST_IN_CLOSED_SEGMENT,DIST_IN_OPEN_SEGMENT = (CONJ_PAIR o prove) + (`(!a b x:real^N. + x IN segment[a,b] ==> dist(x,a) <= dist(a,b) /\ dist(x,b) <= dist(a,b)) /\ + (!a b x:real^N. + x IN segment(a,b) ==> dist(x,a) < dist(a,b) /\ dist(x,b) < dist(a,b))`, + SIMP_TAC[IN_SEGMENT; RIGHT_AND_EXISTS_THM; LEFT_IMP_EXISTS_THM; dist; + VECTOR_ARITH + `((&1 - u) % a + u % b) - a:real^N = u % (b - a) /\ + ((&1 - u) % a + u % b) - b = --(&1 - u) % (b - a)`] THEN + REWRITE_TAC[NORM_MUL; REAL_ABS_NEG; NORM_SUB] THEN CONJ_TAC THEN + REPEAT GEN_TAC THEN STRIP_TAC THENL + [REWRITE_TAC[REAL_ARITH `x * y <= y <=> x * y <= &1 * y`] THEN + CONJ_TAC THEN MATCH_MP_TAC REAL_LE_RMUL THEN + REWRITE_TAC[NORM_POS_LE] THEN ASM_REAL_ARITH_TAC; + REWRITE_TAC[REAL_ARITH `x * y < y <=> x * y < &1 * y`] THEN + ASM_SIMP_TAC[REAL_LT_RMUL_EQ; NORM_POS_LT; VECTOR_SUB_EQ] THEN + ASM_REAL_ARITH_TAC]);; + +(* ------------------------------------------------------------------------- *) +(* Limit component bounds. *) +(* ------------------------------------------------------------------------- *) + +let LIM_COMPONENT_UBOUND = prove + (`!net:(A)net f (l:real^N) b k. + ~(trivial_limit net) /\ (f --> l) net /\ + eventually (\x. (f x)$k <= b) net /\ + 1 <= k /\ k <= dimindex(:N) + ==> l$k <= b`, + REPEAT STRIP_TAC THEN MP_TAC(ISPECL + [`net:(A)net`; `f:A->real^N`; `{y:real^N | basis k dot y <= b}`; `l:real^N`] + LIM_IN_CLOSED_SET) THEN + ASM_SIMP_TAC[CLOSED_HALFSPACE_LE; IN_ELIM_THM; DOT_BASIS]);; + +let LIM_COMPONENT_LBOUND = prove + (`!net:(A)net f (l:real^N) b k. + ~(trivial_limit net) /\ (f --> l) net /\ + eventually (\x. b <= (f x)$k) net /\ + 1 <= k /\ k <= dimindex(:N) + ==> b <= l$k`, + REPEAT STRIP_TAC THEN MP_TAC(ISPECL + [`net:(A)net`; `f:A->real^N`; `{y:real^N | b <= basis k dot y}`; `l:real^N`] + LIM_IN_CLOSED_SET) THEN + ASM_SIMP_TAC[REWRITE_RULE[real_ge] CLOSED_HALFSPACE_GE; + IN_ELIM_THM; DOT_BASIS]);; + +let LIM_COMPONENT_EQ = prove + (`!net f:A->real^N i l b. + (f --> l) net /\ 1 <= i /\ i <= dimindex(:N) /\ + ~(trivial_limit net) /\ eventually (\x. f(x)$i = b) net + ==> l$i = b`, + REWRITE_TAC[GSYM REAL_LE_ANTISYM; EVENTUALLY_AND] THEN + MESON_TAC[LIM_COMPONENT_UBOUND; LIM_COMPONENT_LBOUND]);; + +let LIM_COMPONENT_LE = prove + (`!net:(A)net f:A->real^N g:A->real^N k l m. + ~(trivial_limit net) /\ (f --> l) net /\ (g --> m) net /\ + eventually (\x. (f x)$k <= (g x)$k) net /\ + 1 <= k /\ k <= dimindex(:N) + ==> l$k <= m$k`, + REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[GSYM REAL_SUB_LE] THEN + REWRITE_TAC[GSYM VECTOR_SUB_COMPONENT; LIM_COMPONENT_LBOUND] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + ONCE_REWRITE_TAC[TAUT `a /\ b /\ c ==> d <=> b /\ a ==> c ==> d`] THEN + DISCH_THEN(MP_TAC o MATCH_MP LIM_SUB) THEN POP_ASSUM MP_TAC THEN + REWRITE_TAC[IMP_IMP; GSYM CONJ_ASSOC; LIM_COMPONENT_LBOUND]);; + +let LIM_DROP_LE = prove + (`!net:(A)net f g l m. + ~(trivial_limit net) /\ (f --> l) net /\ (g --> m) net /\ + eventually (\x. drop(f x) <= drop(g x)) net + ==> drop l <= drop m`, + REWRITE_TAC[drop] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC(ISPEC `net:(A)net` LIM_COMPONENT_LE) THEN + MAP_EVERY EXISTS_TAC [`f:A->real^1`; `g:A->real^1`] THEN + ASM_REWRITE_TAC[DIMINDEX_1; LE_REFL]);; + +let LIM_DROP_UBOUND = prove + (`!net f:A->real^1 l b. + (f --> l) net /\ + ~(trivial_limit net) /\ eventually (\x. drop(f x) <= b) net + ==> drop l <= b`, + SIMP_TAC[drop] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC LIM_COMPONENT_UBOUND THEN + REWRITE_TAC[LE_REFL; DIMINDEX_1] THEN ASM_MESON_TAC[]);; + +let LIM_DROP_LBOUND = prove + (`!net f:A->real^1 l b. + (f --> l) net /\ + ~(trivial_limit net) /\ eventually (\x. b <= drop(f x)) net + ==> b <= drop l`, + SIMP_TAC[drop] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC LIM_COMPONENT_LBOUND THEN + REWRITE_TAC[LE_REFL; DIMINDEX_1] THEN ASM_MESON_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* Also extending closed bounds to closures. *) +(* ------------------------------------------------------------------------- *) + +let IMAGE_CLOSURE_SUBSET = prove + (`!f (s:real^N->bool) (t:real^M->bool). + f continuous_on closure s /\ closed t /\ IMAGE f s SUBSET t + ==> IMAGE f (closure s) SUBSET t`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN `closure s SUBSET {x | (f:real^N->real^M) x IN t}` MP_TAC + THENL [MATCH_MP_TAC SUBSET_TRANS; SET_TAC []] THEN + EXISTS_TAC `{x | x IN closure s /\ (f:real^N->real^M) x IN t}` THEN + CONJ_TAC THENL + [MATCH_MP_TAC CLOSURE_MINIMAL; SET_TAC[]] THEN + ASM_SIMP_TAC[CONTINUOUS_CLOSED_PREIMAGE; CLOSED_CLOSURE] THEN + MP_TAC (ISPEC `s:real^N->bool` CLOSURE_SUBSET) THEN ASM SET_TAC[]);; + +let CLOSURE_IMAGE_CLOSURE = prove + (`!f:real^M->real^N s. + f continuous_on closure s + ==> closure(IMAGE f (closure s)) = closure(IMAGE f s)`, + REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM SUBSET_ANTISYM_EQ] THEN + SIMP_TAC[SUBSET_CLOSURE; IMAGE_SUBSET; CLOSURE_SUBSET] THEN + SIMP_TAC[CLOSURE_MINIMAL_EQ; CLOSED_CLOSURE] THEN + MATCH_MP_TAC IMAGE_CLOSURE_SUBSET THEN + ASM_REWRITE_TAC[CLOSED_CLOSURE; CLOSURE_SUBSET]);; + +let CONTINUOUS_ON_CLOSURE_NORM_LE = prove + (`!f:real^N->real^M s x b. + f continuous_on (closure s) /\ + (!y. y IN s ==> norm(f y) <= b) /\ + x IN (closure s) + ==> norm(f x) <= b`, + REWRITE_TAC [GSYM IN_CBALL_0] THEN REPEAT STRIP_TAC THEN + SUBGOAL_THEN `IMAGE (f:real^N->real^M) (closure s) SUBSET cball(vec 0,b)` + MP_TAC THENL + [MATCH_MP_TAC IMAGE_CLOSURE_SUBSET; ASM SET_TAC []] THEN + ASM_REWRITE_TAC [CLOSED_CBALL] THEN ASM SET_TAC []);; + +let CONTINUOUS_ON_CLOSURE_COMPONENT_LE = prove + (`!f:real^N->real^M s x b k. + f continuous_on (closure s) /\ + (!y. y IN s ==> (f y)$k <= b) /\ + x IN (closure s) + ==> (f x)$k <= b`, + REWRITE_TAC [GSYM IN_CBALL_0] THEN REPEAT STRIP_TAC THEN + SUBGOAL_THEN `IMAGE (f:real^N->real^M) (closure s) SUBSET {x | x$k <= b}` + MP_TAC THENL + [MATCH_MP_TAC IMAGE_CLOSURE_SUBSET; ASM SET_TAC []] THEN + ASM_REWRITE_TAC[CLOSED_HALFSPACE_COMPONENT_LE] THEN ASM SET_TAC[]);; + +let CONTINUOUS_ON_CLOSURE_COMPONENT_GE = prove + (`!f:real^N->real^M s x b k. + f continuous_on (closure s) /\ + (!y. y IN s ==> b <= (f y)$k) /\ + x IN (closure s) + ==> b <= (f x)$k`, + REWRITE_TAC [GSYM IN_CBALL_0] THEN REPEAT STRIP_TAC THEN + SUBGOAL_THEN `IMAGE (f:real^N->real^M) (closure s) SUBSET {x | x$k >= b}` + MP_TAC THENL + [MATCH_MP_TAC IMAGE_CLOSURE_SUBSET; ASM SET_TAC [real_ge]] THEN + ASM_REWRITE_TAC[CLOSED_HALFSPACE_COMPONENT_GE] THEN ASM SET_TAC[real_ge]);; + +(* ------------------------------------------------------------------------- *) +(* Limits relative to a union. *) +(* ------------------------------------------------------------------------- *) + +let LIM_WITHIN_UNION = prove + (`(f --> l) (at x within (s UNION t)) <=> + (f --> l) (at x within s) /\ (f --> l) (at x within t)`, + REWRITE_TAC[LIM_WITHIN; IN_UNION; AND_FORALL_THM] THEN + AP_TERM_TAC THEN REWRITE_TAC[FUN_EQ_THM] THEN X_GEN_TAC `e:real` THEN + ASM_CASES_TAC `&0 < e` THEN ASM_REWRITE_TAC[] THEN + EQ_TAC THENL [MESON_TAC[]; ALL_TAC] THEN DISCH_THEN + (CONJUNCTS_THEN2 (X_CHOOSE_TAC `d:real`) (X_CHOOSE_TAC `k:real`)) THEN + EXISTS_TAC `min d k` THEN ASM_REWRITE_TAC[REAL_LT_MIN] THEN + ASM_MESON_TAC[]);; + +let CONTINUOUS_ON_UNION = prove + (`!f s t. closed s /\ closed t /\ f continuous_on s /\ f continuous_on t + ==> f continuous_on (s UNION t)`, + REWRITE_TAC[CONTINUOUS_ON; CLOSED_LIMPT; IN_UNION; LIM_WITHIN_UNION] THEN + MESON_TAC[LIM; TRIVIAL_LIMIT_WITHIN]);; + +let CONTINUOUS_ON_CASES = prove + (`!P f g:real^M->real^N s t. + closed s /\ closed t /\ f continuous_on s /\ g continuous_on t /\ + (!x. x IN s /\ ~P x \/ x IN t /\ P x ==> f x = g x) + ==> (\x. if P x then f x else g x) continuous_on (s UNION t)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC CONTINUOUS_ON_UNION THEN + ASM_REWRITE_TAC[] THEN CONJ_TAC THEN MATCH_MP_TAC CONTINUOUS_ON_EQ THENL + [EXISTS_TAC `f:real^M->real^N`; EXISTS_TAC `g:real^M->real^N`] THEN + ASM_REWRITE_TAC[] THEN ASM_MESON_TAC[]);; + +let CONTINUOUS_ON_UNION_LOCAL = prove + (`!f:real^M->real^N s. + closed_in (subtopology euclidean (s UNION t)) s /\ + closed_in (subtopology euclidean (s UNION t)) t /\ + f continuous_on s /\ f continuous_on t + ==> f continuous_on (s UNION t)`, + REWRITE_TAC[CONTINUOUS_ON; CLOSED_IN_LIMPT; IN_UNION; LIM_WITHIN_UNION] THEN + MESON_TAC[LIM; TRIVIAL_LIMIT_WITHIN]);; + +let CONTINUOUS_ON_CASES_LOCAL = prove + (`!P f g:real^M->real^N s t. + closed_in (subtopology euclidean (s UNION t)) s /\ + closed_in (subtopology euclidean (s UNION t)) t /\ + f continuous_on s /\ g continuous_on t /\ + (!x. x IN s /\ ~P x \/ x IN t /\ P x ==> f x = g x) + ==> (\x. if P x then f x else g x) continuous_on (s UNION t)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC CONTINUOUS_ON_UNION_LOCAL THEN + ASM_REWRITE_TAC[] THEN CONJ_TAC THEN MATCH_MP_TAC CONTINUOUS_ON_EQ THENL + [EXISTS_TAC `f:real^M->real^N`; EXISTS_TAC `g:real^M->real^N`] THEN + ASM_REWRITE_TAC[] THEN ASM_MESON_TAC[]);; + +let CONTINUOUS_ON_CASES_LE = prove + (`!f g:real^M->real^N h s a. + f continuous_on {t | t IN s /\ h t <= a} /\ + g continuous_on {t | t IN s /\ a <= h t} /\ + (lift o h) continuous_on s /\ + (!t. t IN s /\ h t = a ==> f t = g t) + ==> (\t. if h t <= a then f(t) else g(t)) continuous_on s`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC CONTINUOUS_ON_SUBSET THEN EXISTS_TAC + `{t | t IN s /\ (h:real^M->real) t <= a} UNION + {t | t IN s /\ a <= h t}` THEN + CONJ_TAC THENL + [ALL_TAC; SIMP_TAC[SUBSET; IN_UNION; IN_ELIM_THM; REAL_LE_TOTAL]] THEN + MATCH_MP_TAC CONTINUOUS_ON_CASES_LOCAL THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[IN_ELIM_THM; GSYM CONJ_ASSOC; REAL_LE_ANTISYM] THEN + REWRITE_TAC[CONJ_ASSOC] THEN CONJ_TAC THENL + [ALL_TAC; ASM_MESON_TAC[]] THEN + CONJ_TAC THENL + [SUBGOAL_THEN + `{t | t IN s /\ (h:real^M->real) t <= a} = + {t | t IN ({t | t IN s /\ h t <= a} UNION {t | t IN s /\ a <= h t}) /\ + (lift o h) t IN {x | x$1 <= a}}` + (fun th -> GEN_REWRITE_TAC RAND_CONV [th]) + THENL + [REWRITE_TAC[GSYM drop; o_THM; IN_ELIM_THM; LIFT_DROP; EXTENSION; + IN_UNION] THEN + GEN_TAC THEN EQ_TAC THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + ASM_REAL_ARITH_TAC; + MATCH_MP_TAC CONTINUOUS_CLOSED_IN_PREIMAGE THEN + ASM_REWRITE_TAC[CLOSED_HALFSPACE_COMPONENT_LE; ETA_AX] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET)) THEN + SET_TAC[]]; + SUBGOAL_THEN + `{t | t IN s /\ a <= (h:real^M->real) t} = + {t | t IN ({t | t IN s /\ h t <= a} UNION {t | t IN s /\ a <= h t}) /\ + (lift o h) t IN {x | x$1 >= a}}` + (fun th -> GEN_REWRITE_TAC RAND_CONV [th]) + THENL + [REWRITE_TAC[GSYM drop; o_THM; IN_ELIM_THM; LIFT_DROP; EXTENSION; + IN_UNION] THEN + GEN_TAC THEN EQ_TAC THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + ASM_REAL_ARITH_TAC; + MATCH_MP_TAC CONTINUOUS_CLOSED_IN_PREIMAGE THEN + ASM_REWRITE_TAC[CLOSED_HALFSPACE_COMPONENT_GE; ETA_AX] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET)) THEN + SET_TAC[]]]);; + +let CONTINUOUS_ON_CASES_1 = prove + (`!f g:real^1->real^N s a. + f continuous_on {t | t IN s /\ drop t <= a} /\ + g continuous_on {t | t IN s /\ a <= drop t} /\ + (lift a IN s ==> f(lift a) = g(lift a)) + ==> (\t. if drop t <= a then f(t) else g(t)) continuous_on s`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC CONTINUOUS_ON_CASES_LE THEN + ASM_REWRITE_TAC[o_DEF; LIFT_DROP; CONTINUOUS_ON_ID] THEN + REWRITE_TAC[GSYM LIFT_EQ; LIFT_DROP] THEN ASM_MESON_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* Componentwise limits and continuity. *) +(* ------------------------------------------------------------------------- *) + +let LIM_COMPONENTWISE_LIFT = prove + (`!net f:A->real^N. + (f --> l) net <=> + !i. 1 <= i /\ i <= dimindex(:N) + ==> ((\x. lift((f x)$i)) --> lift(l$i)) net`, + REPEAT GEN_TAC THEN REWRITE_TAC[tendsto] THEN EQ_TAC THENL + [DISCH_TAC THEN X_GEN_TAC `i:num` THEN STRIP_TAC THEN + X_GEN_TAC `e:real` THEN + DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC `e:real`) THEN + ASM_SIMP_TAC[GSYM VECTOR_SUB_COMPONENT] THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] EVENTUALLY_MONO) THEN + GEN_TAC THEN REWRITE_TAC[dist] THEN MATCH_MP_TAC(REAL_ARITH + `y <= x ==> x < e ==> y < e`) THEN + ASM_SIMP_TAC[COMPONENT_LE_NORM; GSYM LIFT_SUB; NORM_LIFT; + GSYM VECTOR_SUB_COMPONENT]; + GEN_REWRITE_TAC (LAND_CONV o BINDER_CONV) [RIGHT_IMP_FORALL_THM] THEN + ONCE_REWRITE_TAC[IMP_IMP] THEN ONCE_REWRITE_TAC[IMP_CONJ_ALT] THEN + ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN + REWRITE_TAC[GSYM IN_NUMSEG; RIGHT_FORALL_IMP_THM] THEN + SIMP_TAC[FORALL_EVENTUALLY; FINITE_NUMSEG; NUMSEG_EMPTY; + GSYM NOT_LE; DIMINDEX_GE_1] THEN + REWRITE_TAC[DIST_LIFT; GSYM VECTOR_SUB_COMPONENT] THEN + DISCH_TAC THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `e / &(dimindex(:N))`) THEN + ASM_SIMP_TAC[REAL_LT_DIV; REAL_OF_NUM_LT; LE_1; DIMINDEX_GE_1] THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] EVENTUALLY_MONO) THEN + X_GEN_TAC `x:A` THEN SIMP_TAC[GSYM VECTOR_SUB_COMPONENT; dist] THEN + DISCH_TAC THEN W(MP_TAC o PART_MATCH lhand NORM_LE_L1 o lhand o snd) THEN + MATCH_MP_TAC(REAL_ARITH `s < e ==> n <= s ==> n < e`) THEN + MATCH_MP_TAC SUM_BOUND_LT_GEN THEN + ASM_SIMP_TAC[FINITE_NUMSEG; NUMSEG_EMPTY; GSYM NOT_LE; DIMINDEX_GE_1; + CARD_NUMSEG_1; GSYM IN_NUMSEG]]);; + +let CONTINUOUS_COMPONENTWISE_LIFT = prove + (`!net f:A->real^N. + f continuous net <=> + !i. 1 <= i /\ i <= dimindex(:N) + ==> (\x. lift((f x)$i)) continuous net`, + REWRITE_TAC[continuous; GSYM LIM_COMPONENTWISE_LIFT]);; + +let CONTINUOUS_ON_COMPONENTWISE_LIFT = prove + (`!f:real^M->real^N s. + f continuous_on s <=> + !i. 1 <= i /\ i <= dimindex(:N) + ==> (\x. lift((f x)$i)) continuous_on s`, + REPEAT GEN_TAC THEN + REWRITE_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN] THEN + GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) + [CONTINUOUS_COMPONENTWISE_LIFT] THEN + MESON_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* Some more convenient intermediate-value theorem formulations. *) +(* ------------------------------------------------------------------------- *) + +let CONNECTED_IVT_HYPERPLANE = prove + (`!s x y:real^N a b. + connected s /\ + x IN s /\ y IN s /\ a dot x <= b /\ b <= a dot y + ==> ?z. z IN s /\ a dot z = b`, + REPEAT STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [connected]) THEN + REWRITE_TAC[NOT_EXISTS_THM] THEN DISCH_THEN(MP_TAC o SPECL + [`{x:real^N | a dot x < b}`; `{x:real^N | a dot x > b}`]) THEN + REWRITE_TAC[OPEN_HALFSPACE_LT; OPEN_HALFSPACE_GT] THEN + ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN STRIP_TAC THEN + REWRITE_TAC[EXTENSION; IN_ELIM_THM; IN_INTER; NOT_IN_EMPTY; SUBSET; + IN_UNION; REAL_LT_LE; real_gt] THEN + ASM_MESON_TAC[REAL_LE_TOTAL; REAL_LE_ANTISYM]);; + +let CONNECTED_IVT_COMPONENT = prove + (`!s x y:real^N a k. + connected s /\ x IN s /\ y IN s /\ + 1 <= k /\ k <= dimindex(:N) /\ x$k <= a /\ a <= y$k + ==> ?z. z IN s /\ z$k = a`, + REPEAT STRIP_TAC THEN MP_TAC(ISPECL + [`s:real^N->bool`; `x:real^N`; `y:real^N`; `(basis k):real^N`; + `a:real`] CONNECTED_IVT_HYPERPLANE) THEN + ASM_SIMP_TAC[DOT_BASIS]);; + +(* ------------------------------------------------------------------------- *) +(* Also more convenient formulations of monotone convergence. *) +(* ------------------------------------------------------------------------- *) + +let BOUNDED_INCREASING_CONVERGENT = prove + (`!s:num->real^1. + bounded {s n | n IN (:num)} /\ (!n. drop(s n) <= drop(s(SUC n))) + ==> ?l. (s --> l) sequentially`, + GEN_TAC THEN + REWRITE_TAC[bounded; IN_ELIM_THM; ABS_DROP; LIM_SEQUENTIALLY; dist; + DROP_SUB; IN_UNIV; GSYM EXISTS_DROP] THEN + DISCH_TAC THEN MATCH_MP_TAC CONVERGENT_BOUNDED_MONOTONE THEN + REWRITE_TAC[LEFT_EXISTS_AND_THM] THEN + CONJ_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN + DISJ1_TAC THEN MATCH_MP_TAC TRANSITIVE_STEPWISE_LE THEN + ASM_REWRITE_TAC[REAL_LE_TRANS; REAL_LE_REFL]);; + +let BOUNDED_DECREASING_CONVERGENT = prove + (`!s:num->real^1. + bounded {s n | n IN (:num)} /\ (!n. drop(s(SUC n)) <= drop(s(n))) + ==> ?l. (s --> l) sequentially`, + GEN_TAC THEN REWRITE_TAC[bounded; FORALL_IN_GSPEC] THEN + DISCH_THEN(REPEAT_TCL CONJUNCTS_THEN ASSUME_TAC) THEN + MP_TAC(ISPEC `\n. --((s:num->real^1) n)` BOUNDED_INCREASING_CONVERGENT) THEN + ASM_SIMP_TAC[bounded; FORALL_IN_GSPEC; NORM_NEG; DROP_NEG; REAL_LE_NEG2] THEN + GEN_REWRITE_TAC (LAND_CONV o BINDER_CONV) [GSYM LIM_NEG_EQ] THEN + REWRITE_TAC[VECTOR_NEG_NEG; ETA_AX] THEN MESON_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* Since we'll use some cardinality reasoning, add invariance theorems. *) +(* ------------------------------------------------------------------------- *) + +let card_translation_invariants = (CONJUNCTS o prove) + (`(!a (s:real^N->bool) (t:A->bool). + IMAGE (\x. a + x) s =_c t <=> s =_c t) /\ + (!a (s:A->bool) (t:real^N->bool). + s =_c IMAGE (\x. a + x) t <=> s =_c t) /\ + (!a (s:real^N->bool) (t:A->bool). + IMAGE (\x. a + x) s <_c t <=> s <_c t) /\ + (!a (s:A->bool) (t:real^N->bool). + s <_c IMAGE (\x. a + x) t <=> s <_c t) /\ + (!a (s:real^N->bool) (t:A->bool). + IMAGE (\x. a + x) s <=_c t <=> s <=_c t) /\ + (!a (s:A->bool) (t:real^N->bool). + s <=_c IMAGE (\x. a + x) t <=> s <=_c t) /\ + (!a (s:real^N->bool) (t:A->bool). + IMAGE (\x. a + x) s >_c t <=> s >_c t) /\ + (!a (s:A->bool) (t:real^N->bool). + s >_c IMAGE (\x. a + x) t <=> s >_c t) /\ + (!a (s:real^N->bool) (t:A->bool). + IMAGE (\x. a + x) s >=_c t <=> s >=_c t) /\ + (!a (s:A->bool) (t:real^N->bool). + s >=_c IMAGE (\x. a + x) t <=> s >=_c t)`, + REWRITE_TAC[gt_c; ge_c] THEN REPEAT STRIP_TAC THENL + [MATCH_MP_TAC CARD_EQ_CONG; + MATCH_MP_TAC CARD_EQ_CONG; + MATCH_MP_TAC CARD_LT_CONG; + MATCH_MP_TAC CARD_LT_CONG; + MATCH_MP_TAC CARD_LE_CONG; + MATCH_MP_TAC CARD_LE_CONG; + MATCH_MP_TAC CARD_LT_CONG; + MATCH_MP_TAC CARD_LT_CONG; + MATCH_MP_TAC CARD_LE_CONG; + MATCH_MP_TAC CARD_LE_CONG] THEN + REWRITE_TAC[CARD_EQ_REFL] THEN MATCH_MP_TAC CARD_EQ_IMAGE THEN + SIMP_TAC[VECTOR_ARITH `a + x:real^N = a + y <=> x = y`]) in +add_translation_invariants card_translation_invariants;; + +let card_linear_invariants = (CONJUNCTS o prove) + (`(!(f:real^M->real^N) s (t:A->bool). + linear f /\ (!x y. f x = f y ==> x = y) + ==> (IMAGE f s =_c t <=> s =_c t)) /\ + (!(f:real^M->real^N) (s:A->bool) t. + linear f /\ (!x y. f x = f y ==> x = y) + ==> (s =_c IMAGE f t <=> s =_c t)) /\ + (!(f:real^M->real^N) s (t:A->bool). + linear f /\ (!x y. f x = f y ==> x = y) + ==> (IMAGE f s <_c t <=> s <_c t)) /\ + (!(f:real^M->real^N) (s:A->bool) t. + linear f /\ (!x y. f x = f y ==> x = y) + ==> (s <_c IMAGE f t <=> s <_c t)) /\ + (!(f:real^M->real^N) s (t:A->bool). + linear f /\ (!x y. f x = f y ==> x = y) + ==> (IMAGE f s <=_c t <=> s <=_c t)) /\ + (!(f:real^M->real^N) (s:A->bool) t. + linear f /\ (!x y. f x = f y ==> x = y) + ==> (s <=_c IMAGE f t <=> s <=_c t)) /\ + (!(f:real^M->real^N) s (t:A->bool). + linear f /\ (!x y. f x = f y ==> x = y) + ==> (IMAGE f s >_c t <=> s >_c t)) /\ + (!(f:real^M->real^N) (s:A->bool) t. + linear f /\ (!x y. f x = f y ==> x = y) + ==> (s >_c IMAGE f t <=> s >_c t)) /\ + (!(f:real^M->real^N) s (t:A->bool). + linear f /\ (!x y. f x = f y ==> x = y) + ==> (IMAGE f s >=_c t <=> s >=_c t)) /\ + (!(f:real^M->real^N) (s:A->bool) t. + linear f /\ (!x y. f x = f y ==> x = y) + ==> (s >=_c IMAGE f t <=> s >=_c t))`, + REWRITE_TAC[gt_c; ge_c] THEN REPEAT STRIP_TAC THENL + [MATCH_MP_TAC CARD_EQ_CONG; + MATCH_MP_TAC CARD_EQ_CONG; + MATCH_MP_TAC CARD_LT_CONG; + MATCH_MP_TAC CARD_LT_CONG; + MATCH_MP_TAC CARD_LE_CONG; + MATCH_MP_TAC CARD_LE_CONG; + MATCH_MP_TAC CARD_LT_CONG; + MATCH_MP_TAC CARD_LT_CONG; + MATCH_MP_TAC CARD_LE_CONG; + MATCH_MP_TAC CARD_LE_CONG] THEN + REWRITE_TAC[CARD_EQ_REFL] THEN MATCH_MP_TAC CARD_EQ_IMAGE THEN + ASM_MESON_TAC[]) in +add_linear_invariants card_linear_invariants;; + +(* ------------------------------------------------------------------------- *) +(* Basic homeomorphism definitions. *) +(* ------------------------------------------------------------------------- *) + +let homeomorphism = new_definition + `homeomorphism (s,t) (f,g) <=> + (!x. x IN s ==> (g(f(x)) = x)) /\ (IMAGE f s = t) /\ f continuous_on s /\ + (!y. y IN t ==> (f(g(y)) = y)) /\ (IMAGE g t = s) /\ g continuous_on t`;; + +parse_as_infix("homeomorphic",(12,"right"));; + +let homeomorphic = new_definition + `s homeomorphic t <=> ?f g. homeomorphism (s,t) (f,g)`;; + +let HOMEOMORPHISM = prove + (`!s:real^M->bool t:real^N->bool f g. + homeomorphism (s,t) (f,g) <=> + f continuous_on s /\ IMAGE f s SUBSET t /\ + g continuous_on t /\ IMAGE g t SUBSET s /\ + (!x. x IN s ==> g (f x) = x) /\ + (!y. y IN t ==> f (g y) = y)`, + REPEAT GEN_TAC THEN REWRITE_TAC[homeomorphism] THEN + EQ_TAC THEN SIMP_TAC[] THEN SET_TAC[]);; + +let HOMEOMORPHISM_OF_SUBSETS = prove + (`!f g s t s' t'. + homeomorphism (s,t) (f,g) /\ s' SUBSET s /\ t' SUBSET t /\ IMAGE f s' = t' + ==> homeomorphism (s',t') (f,g)`, + REWRITE_TAC[homeomorphism] THEN + REPEAT STRIP_TAC THEN + TRY(MATCH_MP_TAC CONTINUOUS_ON_SUBSET) THEN ASM SET_TAC[]);; + +let HOMEOMORPHISM_ID = prove + (`!s:real^N->bool. homeomorphism (s,s) ((\x. x),(\x. x))`, + REWRITE_TAC[homeomorphism; IMAGE_ID; CONTINUOUS_ON_ID]);; + +let HOMEOMORPHISM_I = prove + (`!s:real^N->bool. homeomorphism (s,s) (I,I)`, + REWRITE_TAC[I_DEF; HOMEOMORPHISM_ID]);; + +let HOMEOMORPHIC_REFL = prove + (`!s:real^N->bool. s homeomorphic s`, + REWRITE_TAC[homeomorphic] THEN MESON_TAC[HOMEOMORPHISM_I]);; + +let HOMEOMORPHISM_SYM = prove + (`!f:real^M->real^N g s t. + homeomorphism (s,t) (f,g) <=> homeomorphism (t,s) (g,f)`, + REWRITE_TAC[homeomorphism] THEN MESON_TAC[]);; + +let HOMEOMORPHIC_SYM = prove + (`!s t. s homeomorphic t <=> t homeomorphic s`, + REPEAT GEN_TAC THEN REWRITE_TAC[homeomorphic; homeomorphism] THEN + GEN_REWRITE_TAC RAND_CONV [SWAP_EXISTS_THM] THEN + REPEAT(AP_TERM_TAC THEN ABS_TAC) THEN CONV_TAC TAUT);; + +let HOMEOMORPHISM_COMPOSE = prove + (`!f:real^M->real^N g h:real^N->real^P k s t u. + homeomorphism (s,t) (f,g) /\ homeomorphism (t,u) (h,k) + ==> homeomorphism (s,u) (h o f,g o k)`, + SIMP_TAC[homeomorphism; CONTINUOUS_ON_COMPOSE; IMAGE_o; o_THM] THEN + SET_TAC[]);; + +let HOMEOMORPHIC_TRANS = prove + (`!s:real^M->bool t:real^N->bool u:real^P->bool. + s homeomorphic t /\ t homeomorphic u ==> s homeomorphic u`, + REWRITE_TAC[homeomorphic] THEN MESON_TAC[HOMEOMORPHISM_COMPOSE]);; + +let HOMEOMORPHIC_IMP_CARD_EQ = prove + (`!s:real^M->bool t:real^N->bool. s homeomorphic t ==> s =_c t`, + REPEAT GEN_TAC THEN REWRITE_TAC[homeomorphic; homeomorphism; eq_c] THEN + MATCH_MP_TAC MONO_EXISTS THEN SET_TAC[]);; + +let HOMEOMORPHIC_EMPTY = prove + (`(!s. (s:real^N->bool) homeomorphic ({}:real^M->bool) <=> s = {}) /\ + (!s. ({}:real^M->bool) homeomorphic (s:real^N->bool) <=> s = {})`, + REWRITE_TAC[homeomorphic; homeomorphism; IMAGE_CLAUSES; IMAGE_EQ_EMPTY] THEN + REPEAT STRIP_TAC THEN ASM_CASES_TAC `s:real^N->bool = {}` THEN + ASM_REWRITE_TAC[continuous_on; NOT_IN_EMPTY]);; + +let HOMEOMORPHIC_MINIMAL = prove + (`!s t. s homeomorphic t <=> + ?f g. (!x. x IN s ==> f(x) IN t /\ (g(f(x)) = x)) /\ + (!y. y IN t ==> g(y) IN s /\ (f(g(y)) = y)) /\ + f continuous_on s /\ g continuous_on t`, + REWRITE_TAC[homeomorphic; homeomorphism; EXTENSION; IN_IMAGE] THEN + REPEAT GEN_TAC THEN REPEAT(AP_TERM_TAC THEN ABS_TAC) THEN MESON_TAC[]);; + +let HOMEOMORPHIC_INJECTIVE_LINEAR_IMAGE_SELF = prove + (`!f:real^M->real^N s. + linear f /\ (!x y. f x = f y ==> x = y) + ==> (IMAGE f s) homeomorphic s`, + REPEAT STRIP_TAC THEN REWRITE_TAC[HOMEOMORPHIC_MINIMAL] THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [INJECTIVE_LEFT_INVERSE]) THEN + MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC THEN DISCH_TAC THEN + EXISTS_TAC `f:real^M->real^N` THEN + ASM_SIMP_TAC[LINEAR_CONTINUOUS_ON; FORALL_IN_IMAGE; FUN_IN_IMAGE] THEN + ASM_SIMP_TAC[continuous_on; IMP_CONJ; FORALL_IN_IMAGE] THEN + X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN + X_GEN_TAC `e:real` THEN DISCH_TAC THEN + MP_TAC(ISPEC `f:real^M->real^N` LINEAR_INJECTIVE_BOUNDED_BELOW_POS) THEN + ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `B:real` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `e * B:real` THEN ASM_SIMP_TAC[REAL_LT_MUL] THEN + X_GEN_TAC `y:real^M` THEN ASM_SIMP_TAC[dist; GSYM LINEAR_SUB] THEN + DISCH_TAC THEN ASM_SIMP_TAC[GSYM REAL_LT_LDIV_EQ] THEN + MATCH_MP_TAC(REAL_ARITH `a <= b ==> b < x ==> a < x`) THEN + ASM_SIMP_TAC[REAL_LE_RDIV_EQ]);; + +let HOMEOMORPHIC_INJECTIVE_LINEAR_IMAGE_LEFT_EQ = prove + (`!f:real^M->real^N s t. + linear f /\ (!x y. f x = f y ==> x = y) + ==> ((IMAGE f s) homeomorphic t <=> s homeomorphic t)`, + REPEAT GEN_TAC THEN DISCH_THEN(ASSUME_TAC o SPEC `s:real^M->bool` o + MATCH_MP HOMEOMORPHIC_INJECTIVE_LINEAR_IMAGE_SELF) THEN + EQ_TAC THENL + [FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [HOMEOMORPHIC_SYM]); + POP_ASSUM MP_TAC] THEN + REWRITE_TAC[IMP_IMP; HOMEOMORPHIC_TRANS]);; + +let HOMEOMORPHIC_INJECTIVE_LINEAR_IMAGE_RIGHT_EQ = prove + (`!f:real^M->real^N s t. + linear f /\ (!x y. f x = f y ==> x = y) + ==> (s homeomorphic (IMAGE f t) <=> s homeomorphic t)`, + ONCE_REWRITE_TAC[HOMEOMORPHIC_SYM] THEN + REWRITE_TAC[HOMEOMORPHIC_INJECTIVE_LINEAR_IMAGE_LEFT_EQ]);; + +add_linear_invariants + [HOMEOMORPHIC_INJECTIVE_LINEAR_IMAGE_LEFT_EQ; + HOMEOMORPHIC_INJECTIVE_LINEAR_IMAGE_RIGHT_EQ];; + +let HOMEOMORPHIC_TRANSLATION_SELF = prove + (`!a:real^N s. (IMAGE (\x. a + x) s) homeomorphic s`, + REPEAT GEN_TAC THEN REWRITE_TAC[HOMEOMORPHIC_MINIMAL] THEN + EXISTS_TAC `\x:real^N. x - a` THEN + EXISTS_TAC `\x:real^N. a + x` THEN + SIMP_TAC[FORALL_IN_IMAGE; CONTINUOUS_ON_SUB; CONTINUOUS_ON_ID; + CONTINUOUS_ON_CONST; CONTINUOUS_ON_ADD; VECTOR_ADD_SUB] THEN + REWRITE_TAC[IN_IMAGE] THEN MESON_TAC[]);; + +let HOMEOMORPHIC_TRANSLATION_LEFT_EQ = prove + (`!a:real^N s t. + (IMAGE (\x. a + x) s) homeomorphic t <=> s homeomorphic t`, + MESON_TAC[HOMEOMORPHIC_TRANSLATION_SELF; + HOMEOMORPHIC_SYM; HOMEOMORPHIC_TRANS]);; + +let HOMEOMORPHIC_TRANSLATION_RIGHT_EQ = prove + (`!a:real^N s t. + s homeomorphic (IMAGE (\x. a + x) t) <=> s homeomorphic t`, + ONCE_REWRITE_TAC[HOMEOMORPHIC_SYM] THEN + REWRITE_TAC[HOMEOMORPHIC_TRANSLATION_LEFT_EQ]);; + +add_translation_invariants + [HOMEOMORPHIC_TRANSLATION_LEFT_EQ; + HOMEOMORPHIC_TRANSLATION_RIGHT_EQ];; + +let HOMEOMORPHISM_IMP_QUOTIENT_MAP = prove + (`!f:real^M->real^N g s t. + homeomorphism (s,t) (f,g) + ==> !u. u SUBSET t + ==> (open_in (subtopology euclidean s) {x | x IN s /\ f x IN u} <=> + open_in (subtopology euclidean t) u)`, + REPEAT GEN_TAC THEN REWRITE_TAC[homeomorphism] THEN + STRIP_TAC THEN MATCH_MP_TAC CONTINUOUS_RIGHT_INVERSE_IMP_QUOTIENT_MAP THEN + EXISTS_TAC `g:real^N->real^M` THEN ASM_REWRITE_TAC[SUBSET_REFL]);; + +let HOMEOMORPHIC_PCROSS = prove + (`!s:real^M->bool t:real^N->bool s':real^P->bool t':real^Q->bool. + s homeomorphic s' /\ t homeomorphic t' + ==> (s PCROSS t) homeomorphic (s' PCROSS t')`, + REPEAT GEN_TAC THEN REWRITE_TAC[homeomorphic; HOMEOMORPHISM] THEN + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE] THEN + DISCH_THEN(CONJUNCTS_THEN2 + (X_CHOOSE_THEN `f:real^M->real^P` + (X_CHOOSE_THEN `f':real^P->real^M` STRIP_ASSUME_TAC)) + (X_CHOOSE_THEN `g:real^N->real^Q` + (X_CHOOSE_THEN `g':real^Q->real^N` STRIP_ASSUME_TAC))) THEN + MAP_EVERY EXISTS_TAC + [`(\z. pastecart (f(fstcart z)) (g(sndcart z))) + :real^(M,N)finite_sum->real^(P,Q)finite_sum`; + `(\z. pastecart (f'(fstcart z)) (g'(sndcart z))) + :real^(P,Q)finite_sum->real^(M,N)finite_sum`] THEN + ASM_SIMP_TAC[FORALL_IN_PCROSS; FSTCART_PASTECART; SNDCART_PASTECART; + SUBSET; FORALL_IN_IMAGE; PASTECART_IN_PCROSS] THEN + CONJ_TAC THEN MATCH_MP_TAC CONTINUOUS_ON_PASTECART THEN + CONJ_TAC THEN ONCE_REWRITE_TAC[GSYM o_DEF] THEN + MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN + SIMP_TAC[LINEAR_FSTCART; LINEAR_SNDCART; LINEAR_CONTINUOUS_ON] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET)) THEN + REWRITE_TAC[FORALL_IN_IMAGE; FORALL_IN_PCROSS; SUBSET] THEN + SIMP_TAC[FSTCART_PASTECART; SNDCART_PASTECART]);; + +let HOMEOMORPHIC_PCROSS_SYM = prove + (`!s:real^M->bool t:real^N->bool. (s PCROSS t) homeomorphic (t PCROSS s)`, + REPEAT GEN_TAC THEN REWRITE_TAC[homeomorphic; homeomorphism] THEN + EXISTS_TAC `(\z. pastecart (sndcart z) (fstcart z)) + :real^(M,N)finite_sum->real^(N,M)finite_sum` THEN + EXISTS_TAC `(\z. pastecart (sndcart z) (fstcart z)) + :real^(N,M)finite_sum->real^(M,N)finite_sum` THEN + REWRITE_TAC[GSYM SUBSET_ANTISYM_EQ; SUBSET; FORALL_IN_IMAGE] THEN + SIMP_TAC[CONTINUOUS_ON_PASTECART; LINEAR_CONTINUOUS_ON; + LINEAR_FSTCART; LINEAR_SNDCART] THEN + REWRITE_TAC[FORALL_IN_PCROSS; FSTCART_PASTECART; SNDCART_PASTECART; + IN_IMAGE; EXISTS_PASTECART; PASTECART_INJ; PASTECART_IN_PCROSS] THEN + MESON_TAC[]);; + +let HOMEOMORPHIC_PCROSS_ASSOC = prove + (`!s:real^M->bool t:real^N->bool u:real^P->bool. + (s PCROSS (t PCROSS u)) homeomorphic ((s PCROSS t) PCROSS u)`, + REPEAT GEN_TAC THEN REWRITE_TAC[homeomorphic; HOMEOMORPHISM] THEN + MAP_EVERY EXISTS_TAC + [`\z:real^(M,(N,P)finite_sum)finite_sum. + pastecart (pastecart (fstcart z) (fstcart(sndcart z))) + (sndcart(sndcart z))`; + `\z:real^((M,N)finite_sum,P)finite_sum. + pastecart (fstcart(fstcart z)) + (pastecart (sndcart(fstcart z)) (sndcart z))`] THEN + REWRITE_TAC[FORALL_IN_PCROSS; SUBSET; FORALL_IN_IMAGE; + RIGHT_FORALL_IMP_THM; IMP_CONJ] THEN + SIMP_TAC[FSTCART_PASTECART; SNDCART_PASTECART; PASTECART_IN_PCROSS] THEN + CONJ_TAC THEN MATCH_MP_TAC LINEAR_CONTINUOUS_ON THEN + REPEAT(MATCH_MP_TAC LINEAR_PASTECART THEN CONJ_TAC) THEN + TRY(GEN_REWRITE_TAC RAND_CONV [GSYM o_DEF] THEN + MATCH_MP_TAC LINEAR_COMPOSE) THEN + REWRITE_TAC[LINEAR_FSTCART; LINEAR_SNDCART]);; + +let HOMEOMORPHIC_SCALING_LEFT = prove + (`!c. &0 < c + ==> !s t. (IMAGE (\x. c % x) s) homeomorphic t <=> s homeomorphic t`, + REWRITE_TAC[RIGHT_IMP_FORALL_THM] THEN REPEAT GEN_TAC THEN DISCH_TAC THEN + MATCH_MP_TAC HOMEOMORPHIC_INJECTIVE_LINEAR_IMAGE_LEFT_EQ THEN + ASM_SIMP_TAC[VECTOR_MUL_LCANCEL; REAL_LT_IMP_NZ; LINEAR_SCALING]);; + +let HOMEOMORPHIC_SCALING_RIGHT = prove + (`!c. &0 < c + ==> !s t. s homeomorphic (IMAGE (\x. c % x) t) <=> s homeomorphic t`, + REWRITE_TAC[RIGHT_IMP_FORALL_THM] THEN REPEAT GEN_TAC THEN DISCH_TAC THEN + MATCH_MP_TAC HOMEOMORPHIC_INJECTIVE_LINEAR_IMAGE_RIGHT_EQ THEN + ASM_SIMP_TAC[VECTOR_MUL_LCANCEL; REAL_LT_IMP_NZ; LINEAR_SCALING]);; + +let HOMEOMORPHIC_SUBSPACES = prove + (`!s:real^M->bool t:real^N->bool. + subspace s /\ subspace t /\ dim s = dim t ==> s homeomorphic t`, + REPEAT GEN_TAC THEN REWRITE_TAC[homeomorphic; HOMEOMORPHISM] THEN + DISCH_THEN(MP_TAC o MATCH_MP ISOMETRIES_SUBSPACES) THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `f:real^M->real^N` THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `g:real^N->real^M` THEN + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; IN_INTER; IN_CBALL_0] THEN + SIMP_TAC[LINEAR_CONTINUOUS_ON] THEN ASM SET_TAC[]);; + +let HOMEOMORPHIC_FINITE = prove + (`!s:real^M->bool t:real^N->bool. + FINITE s /\ FINITE t ==> (s homeomorphic t <=> CARD s = CARD t)`, + REPEAT STRIP_TAC THEN EQ_TAC THENL + [DISCH_THEN(MP_TAC o MATCH_MP HOMEOMORPHIC_IMP_CARD_EQ) THEN + ASM_SIMP_TAC[CARD_EQ_CARD]; + STRIP_TAC THEN REWRITE_TAC[homeomorphic; HOMEOMORPHISM] THEN + MP_TAC(ISPECL [`s:real^M->bool`; `t:real^N->bool`] + CARD_EQ_BIJECTIONS) THEN + ASM_REWRITE_TAC[] THEN + REPEAT(MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC) THEN + ASM_SIMP_TAC[CONTINUOUS_ON_FINITE] THEN ASM SET_TAC[]]);; + +let HOMEOMORPHIC_FINITE_STRONG = prove + (`!s:real^M->bool t:real^N->bool. + FINITE s \/ FINITE t + ==> (s homeomorphic t <=> FINITE s /\ FINITE t /\ CARD s = CARD t)`, + REPEAT GEN_TAC THEN DISCH_TAC THEN EQ_TAC THEN + SIMP_TAC[HOMEOMORPHIC_FINITE] THEN DISCH_TAC THEN + FIRST_ASSUM(MP_TAC o MATCH_MP CARD_FINITE_CONG o MATCH_MP + HOMEOMORPHIC_IMP_CARD_EQ) THEN + FIRST_X_ASSUM DISJ_CASES_TAC THEN ASM_REWRITE_TAC[] THEN + ASM_MESON_TAC[HOMEOMORPHIC_FINITE]);; + +let HOMEOMORPHIC_SING = prove + (`!a:real^M b:real^N. {a} homeomorphic {b}`, + SIMP_TAC[HOMEOMORPHIC_FINITE; FINITE_SING; CARD_SING]);; + +let HOMEOMORPHIC_PCROSS_SING = prove + (`(!s:real^M->bool a:real^N. s homeomorphic (s PCROSS {a})) /\ + (!s:real^M->bool a:real^N. s homeomorphic ({a} PCROSS s))`, + MATCH_MP_TAC(TAUT `(p ==> q) /\ p ==> p /\ q`) THEN CONJ_TAC THENL + [MESON_TAC[HOMEOMORPHIC_PCROSS_SYM; HOMEOMORPHIC_TRANS]; ALL_TAC] THEN + REPEAT GEN_TAC THEN REWRITE_TAC[homeomorphic; HOMEOMORPHISM] THEN + EXISTS_TAC `\x. (pastecart x a:real^(M,N)finite_sum)` THEN + EXISTS_TAC `fstcart:real^(M,N)finite_sum->real^M` THEN + SIMP_TAC[CONTINUOUS_ON_PASTECART; CONTINUOUS_ON_CONST; CONTINUOUS_ON_ID] THEN + SIMP_TAC[LINEAR_FSTCART; LINEAR_CONTINUOUS_ON; SUBSET; FORALL_IN_IMAGE] THEN + REWRITE_TAC[FORALL_IN_PCROSS; PASTECART_IN_PCROSS; IN_SING] THEN + SIMP_TAC[FSTCART_PASTECART]);; + +(* ------------------------------------------------------------------------- *) +(* Inverse function property for open/closed maps. *) +(* ------------------------------------------------------------------------- *) + +let CONTINUOUS_ON_INVERSE_OPEN_MAP = prove + (`!f:real^M->real^N g s t. + f continuous_on s /\ IMAGE f s = t /\ (!x. x IN s ==> g(f x) = x) /\ + (!u. open_in (subtopology euclidean s) u + ==> open_in (subtopology euclidean t) (IMAGE f u)) + ==> g continuous_on t`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`g:real^N->real^M`; `t:real^N->bool`; `s:real^M->bool`] + CONTINUOUS_ON_OPEN_GEN) THEN + ANTS_TAC THENL [ASM SET_TAC[]; DISCH_THEN SUBST1_TAC] THEN + X_GEN_TAC `u:real^M->bool` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `u:real^M->bool`) THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN + FIRST_ASSUM(MP_TAC o CONJUNCT1 o GEN_REWRITE_RULE I [open_in]) THEN + ASM SET_TAC[]);; + +let CONTINUOUS_ON_INVERSE_CLOSED_MAP = prove + (`!f:real^M->real^N g s t. + f continuous_on s /\ IMAGE f s = t /\ (!x. x IN s ==> g(f x) = x) /\ + (!u. closed_in (subtopology euclidean s) u + ==> closed_in (subtopology euclidean t) (IMAGE f u)) + ==> g continuous_on t`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`g:real^N->real^M`; `t:real^N->bool`; `s:real^M->bool`] + CONTINUOUS_ON_CLOSED_GEN) THEN + ANTS_TAC THENL [ASM SET_TAC[]; DISCH_THEN SUBST1_TAC] THEN + X_GEN_TAC `u:real^M->bool` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `u:real^M->bool`) THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN + FIRST_ASSUM(MP_TAC o CONJUNCT1 o GEN_REWRITE_RULE I [closed_in]) THEN + REWRITE_TAC[TOPSPACE_EUCLIDEAN_SUBTOPOLOGY] THEN ASM SET_TAC[]);; + +let HOMEOMORPHISM_INJECTIVE_OPEN_MAP = prove + (`!f:real^M->real^N s t. + f continuous_on s /\ IMAGE f s = t /\ + (!x y. x IN s /\ y IN s /\ f x = f y ==> x = y) /\ + (!u. open_in (subtopology euclidean s) u + ==> open_in (subtopology euclidean t) (IMAGE f u)) + ==> ?g. homeomorphism (s,t) (f,g)`, + REPEAT STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [INJECTIVE_ON_LEFT_INVERSE]) THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `g:real^N->real^M` THEN + DISCH_TAC THEN ASM_SIMP_TAC[homeomorphism] THEN + REPEAT(CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC]) THEN + MATCH_MP_TAC CONTINUOUS_ON_INVERSE_OPEN_MAP THEN ASM_MESON_TAC[]);; + +let HOMEOMORPHISM_INJECTIVE_CLOSED_MAP = prove + (`!f:real^M->real^N s t. + f continuous_on s /\ IMAGE f s = t /\ + (!x y. x IN s /\ y IN s /\ f x = f y ==> x = y) /\ + (!u. closed_in (subtopology euclidean s) u + ==> closed_in (subtopology euclidean t) (IMAGE f u)) + ==> ?g. homeomorphism (s,t) (f,g)`, + REPEAT STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [INJECTIVE_ON_LEFT_INVERSE]) THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `g:real^N->real^M` THEN + DISCH_TAC THEN ASM_SIMP_TAC[homeomorphism] THEN + REPEAT(CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC]) THEN + MATCH_MP_TAC CONTINUOUS_ON_INVERSE_CLOSED_MAP THEN ASM_MESON_TAC[]);; + +let HOMEOMORPHISM_IMP_OPEN_MAP = prove + (`!f:real^M->real^N g s t u. + homeomorphism (s,t) (f,g) /\ open_in (subtopology euclidean s) u + ==> open_in (subtopology euclidean t) (IMAGE f u)`, + REWRITE_TAC[homeomorphism] THEN REPEAT STRIP_TAC THEN + SUBGOAL_THEN `IMAGE (f:real^M->real^N) u = + {y | y IN t /\ g(y) IN u}` + SUBST1_TAC THENL + [FIRST_ASSUM(MP_TAC o CONJUNCT1 o GEN_REWRITE_RULE I [open_in]) THEN + ASM SET_TAC[]; + MATCH_MP_TAC CONTINUOUS_ON_IMP_OPEN_IN THEN ASM_REWRITE_TAC[]]);; + +let HOMEOMORPHISM_IMP_CLOSED_MAP = prove + (`!f:real^M->real^N g s t u. + homeomorphism (s,t) (f,g) /\ closed_in (subtopology euclidean s) u + ==> closed_in (subtopology euclidean t) (IMAGE f u)`, + REWRITE_TAC[homeomorphism] THEN REPEAT STRIP_TAC THEN + SUBGOAL_THEN `IMAGE (f:real^M->real^N) u = + {y | y IN t /\ g(y) IN u}` + SUBST1_TAC THENL + [FIRST_ASSUM(MP_TAC o CONJUNCT1 o GEN_REWRITE_RULE I [closed_in]) THEN + REWRITE_TAC[TOPSPACE_EUCLIDEAN_SUBTOPOLOGY] THEN ASM SET_TAC[]; + MATCH_MP_TAC CONTINUOUS_ON_IMP_CLOSED_IN THEN ASM_REWRITE_TAC[]]);; + +let HOMEOMORPHISM_INJECTIVE_OPEN_MAP_EQ = prove + (`!f:real^M->real^N s t. + f continuous_on s /\ IMAGE f s = t /\ + (!x y. x IN s /\ y IN s /\ f x = f y ==> x = y) + ==> ((?g. homeomorphism (s,t) (f,g)) <=> + !u. open_in (subtopology euclidean s) u + ==> open_in (subtopology euclidean t) (IMAGE f u))`, + REPEAT STRIP_TAC THEN EQ_TAC THEN REPEAT STRIP_TAC THENL + [MATCH_MP_TAC HOMEOMORPHISM_IMP_OPEN_MAP THEN ASM_MESON_TAC[]; + MATCH_MP_TAC HOMEOMORPHISM_INJECTIVE_OPEN_MAP THEN + ASM_REWRITE_TAC[]]);; + +let HOMEOMORPHISM_INJECTIVE_CLOSED_MAP_EQ = prove + (`!f:real^M->real^N s t. + f continuous_on s /\ IMAGE f s = t /\ + (!x y. x IN s /\ y IN s /\ f x = f y ==> x = y) + ==> ((?g. homeomorphism (s,t) (f,g)) <=> + !u. closed_in (subtopology euclidean s) u + ==> closed_in (subtopology euclidean t) (IMAGE f u))`, + REPEAT STRIP_TAC THEN EQ_TAC THEN REPEAT STRIP_TAC THENL + [MATCH_MP_TAC HOMEOMORPHISM_IMP_CLOSED_MAP THEN ASM_MESON_TAC[]; + MATCH_MP_TAC HOMEOMORPHISM_INJECTIVE_CLOSED_MAP THEN + ASM_REWRITE_TAC[]]);; + +let INJECTIVE_MAP_OPEN_IFF_CLOSED = prove + (`!f:real^M->real^N s t. + f continuous_on s /\ IMAGE f s = t /\ + (!x y. x IN s /\ y IN s /\ f x = f y ==> x = y) + ==> ((!u. open_in (subtopology euclidean s) u + ==> open_in (subtopology euclidean t) (IMAGE f u)) <=> + (!u. closed_in (subtopology euclidean s) u + ==> closed_in (subtopology euclidean t) (IMAGE f u)))`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC EQ_TRANS THEN + EXISTS_TAC `?g:real^N->real^M. homeomorphism (s,t) (f,g)` THEN + CONJ_TAC THENL + [CONV_TAC SYM_CONV THEN MATCH_MP_TAC HOMEOMORPHISM_INJECTIVE_OPEN_MAP_EQ; + MATCH_MP_TAC HOMEOMORPHISM_INJECTIVE_CLOSED_MAP_EQ] THEN + ASM_REWRITE_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* Relatively weak hypotheses if the domain of the function is compact. *) +(* ------------------------------------------------------------------------- *) + +let CONTINUOUS_IMP_CLOSED_MAP = prove + (`!f:real^M->real^N s t. + f continuous_on s /\ IMAGE f s = t /\ compact s + ==> !u. closed_in (subtopology euclidean s) u + ==> closed_in (subtopology euclidean t) (IMAGE f u)`, + SIMP_TAC[CLOSED_IN_CLOSED_EQ; COMPACT_IMP_CLOSED] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC CLOSED_CLOSED_IN_TRANS THEN + EXPAND_TAC "t" THEN REWRITE_TAC[CONJ_ASSOC] THEN + CONJ_TAC THENL [ALL_TAC; ASM SET_TAC[]] THEN + CONJ_TAC THEN MATCH_MP_TAC COMPACT_IMP_CLOSED THEN + MATCH_MP_TAC COMPACT_CONTINUOUS_IMAGE THEN ASM_REWRITE_TAC[] THEN + ASM_MESON_TAC[COMPACT_EQ_BOUNDED_CLOSED; CLOSED_IN_CLOSED_TRANS; + BOUNDED_SUBSET; CONTINUOUS_ON_SUBSET]);; + +let CONTINUOUS_ON_INVERSE = prove + (`!f:real^M->real^N g s. + f continuous_on s /\ compact s /\ (!x. x IN s ==> (g(f(x)) = x)) + ==> g continuous_on (IMAGE f s)`, + REPEAT STRIP_TAC THEN REWRITE_TAC[CONTINUOUS_ON_CLOSED] THEN + SUBGOAL_THEN `IMAGE g (IMAGE (f:real^M->real^N) s) = s` SUBST1_TAC THENL + [REWRITE_TAC[EXTENSION; IN_IMAGE] THEN ASM_MESON_TAC[]; ALL_TAC] THEN + X_GEN_TAC `t:real^M->bool` THEN DISCH_TAC THEN + REWRITE_TAC[CLOSED_IN_CLOSED] THEN + EXISTS_TAC `IMAGE (f:real^M->real^N) t` THEN CONJ_TAC THENL + [MATCH_MP_TAC COMPACT_IMP_CLOSED THEN + MATCH_MP_TAC COMPACT_CONTINUOUS_IMAGE THEN + FIRST_ASSUM(MP_TAC o MATCH_MP CLOSED_IN_SUBSET) THEN + REWRITE_TAC[COMPACT_EQ_BOUNDED_CLOSED; TOPSPACE_EUCLIDEAN_SUBTOPOLOGY] THEN + ASM_MESON_TAC[COMPACT_EQ_BOUNDED_CLOSED; CLOSED_IN_CLOSED_TRANS; + BOUNDED_SUBSET; CONTINUOUS_ON_SUBSET]; + REWRITE_TAC[EXTENSION; IN_INTER; IN_ELIM_THM; IN_IMAGE] THEN + ASM_MESON_TAC[CLOSED_IN_SUBSET; TOPSPACE_EUCLIDEAN_SUBTOPOLOGY; SUBSET]]);; + +let HOMEOMORPHISM_COMPACT = prove + (`!s f t. compact s /\ f continuous_on s /\ (IMAGE f s = t) /\ + (!x y. x IN s /\ y IN s /\ (f x = f y) ==> (x = y)) + ==> ?g. homeomorphism(s,t) (f,g)`, + REWRITE_TAC[INJECTIVE_ON_LEFT_INVERSE] THEN REPEAT GEN_TAC THEN + REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + MATCH_MP_TAC MONO_EXISTS THEN ASM_SIMP_TAC[EXTENSION; homeomorphism] THEN + FIRST_X_ASSUM(SUBST_ALL_TAC o SYM) THEN + ASM_MESON_TAC[CONTINUOUS_ON_INVERSE; IN_IMAGE]);; + +let HOMEOMORPHIC_COMPACT = prove + (`!s f t. compact s /\ f continuous_on s /\ (IMAGE f s = t) /\ + (!x y. x IN s /\ y IN s /\ (f x = f y) ==> (x = y)) + ==> s homeomorphic t`, + REWRITE_TAC[homeomorphic] THEN MESON_TAC[HOMEOMORPHISM_COMPACT]);; + +(* ------------------------------------------------------------------------- *) +(* Lemmas about composition of homeomorphisms. *) +(* ------------------------------------------------------------------------- *) + +let HOMEOMORPHISM_FROM_COMPOSITION_SURJECTIVE = prove + (`!f:real^M->real^N g:real^N->real^P s t u. + f continuous_on s /\ IMAGE f s = t /\ + g continuous_on t /\ IMAGE g t SUBSET u /\ + (?h. homeomorphism (s,u) (g o f,h)) + ==> (?f'. homeomorphism (s,t) (f,f')) /\ + (?g'. homeomorphism (t,u) (g,g'))`, + REPEAT GEN_TAC THEN STRIP_TAC THEN + RULE_ASSUM_TAC(REWRITE_RULE[homeomorphism; o_THM]) THEN + MATCH_MP_TAC(TAUT `q /\ (q ==> p) ==> p /\ q`) THEN CONJ_TAC THENL + [MATCH_MP_TAC HOMEOMORPHISM_INJECTIVE_OPEN_MAP THEN + REPEAT(CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC]) THEN + MATCH_MP_TAC OPEN_MAP_FROM_COMPOSITION_SURJECTIVE THEN + MAP_EVERY EXISTS_TAC [`f:real^M->real^N`; `s:real^M->bool`] THEN + ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC HOMEOMORPHISM_IMP_OPEN_MAP THEN + MAP_EVERY EXISTS_TAC [`h:real^P->real^M`; `s:real^M->bool`] THEN + ASM_REWRITE_TAC[homeomorphism; o_THM]; + REWRITE_TAC[homeomorphism; o_THM] THEN + DISCH_THEN(X_CHOOSE_THEN `g':real^P->real^N` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `(h:real^P->real^M) o (g:real^N->real^P)` THEN + ASM_SIMP_TAC[o_THM; IMAGE_o] THEN + CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN + ASM_MESON_TAC[CONTINUOUS_ON_SUBSET]]);; + +let HOMEOMORPHISM_FROM_COMPOSITION_INJECTIVE = prove + (`!f:real^M->real^N g:real^N->real^P s t u. + f continuous_on s /\ IMAGE f s SUBSET t /\ + g continuous_on t /\ IMAGE g t SUBSET u /\ + (!x y. x IN t /\ y IN t /\ g x = g y ==> x = y) /\ + (?h. homeomorphism (s,u) (g o f,h)) + ==> (?f'. homeomorphism (s,t) (f,f')) /\ + (?g'. homeomorphism (t,u) (g,g'))`, + REPEAT GEN_TAC THEN STRIP_TAC THEN + RULE_ASSUM_TAC(REWRITE_RULE[homeomorphism; o_THM]) THEN + MATCH_MP_TAC(TAUT `p /\ (p ==> q) ==> p /\ q`) THEN CONJ_TAC THENL + [MATCH_MP_TAC HOMEOMORPHISM_INJECTIVE_OPEN_MAP THEN + REPEAT(CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC]) THEN + MATCH_MP_TAC OPEN_MAP_FROM_COMPOSITION_INJECTIVE THEN + MAP_EVERY EXISTS_TAC [`g:real^N->real^P`; `u:real^P->bool`] THEN + ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC HOMEOMORPHISM_IMP_OPEN_MAP THEN + MAP_EVERY EXISTS_TAC [`h:real^P->real^M`; `s:real^M->bool`] THEN + ASM_REWRITE_TAC[homeomorphism; o_THM]; + REWRITE_TAC[homeomorphism; o_THM] THEN + DISCH_THEN(X_CHOOSE_THEN `f':real^N->real^M` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `(f:real^M->real^N) o (h:real^P->real^M)` THEN + ASM_SIMP_TAC[o_THM; IMAGE_o] THEN + REPEAT(CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC]) THEN + MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN + ASM_MESON_TAC[CONTINUOUS_ON_SUBSET]]);; + +(* ------------------------------------------------------------------------- *) +(* Preservation of topological properties. *) +(* ------------------------------------------------------------------------- *) + +let HOMEOMORPHIC_COMPACTNESS = prove + (`!s t. s homeomorphic t ==> (compact s <=> compact t)`, + REWRITE_TAC[homeomorphic; homeomorphism] THEN + MESON_TAC[COMPACT_CONTINUOUS_IMAGE]);; + +let HOMEOMORPHIC_CONNECTEDNESS = prove + (`!s t. s homeomorphic t ==> (connected s <=> connected t)`, + REWRITE_TAC[homeomorphic; homeomorphism] THEN + MESON_TAC[CONNECTED_CONTINUOUS_IMAGE]);; + +(* ------------------------------------------------------------------------- *) +(* Results on translation, scaling etc. *) +(* ------------------------------------------------------------------------- *) + +let HOMEOMORPHIC_SCALING = prove + (`!s:real^N->bool c. ~(c = &0) ==> s homeomorphic (IMAGE (\x. c % x) s)`, + REPEAT STRIP_TAC THEN REWRITE_TAC[HOMEOMORPHIC_MINIMAL] THEN + MAP_EVERY EXISTS_TAC [`\x:real^N. c % x`; `\x:real^N. inv(c) % x`] THEN + ASM_SIMP_TAC[CONTINUOUS_ON_CMUL; CONTINUOUS_ON_ID; FORALL_IN_IMAGE] THEN + ASM_SIMP_TAC[VECTOR_MUL_ASSOC; REAL_MUL_LINV; REAL_MUL_RINV] THEN + SIMP_TAC[VECTOR_MUL_LID; IN_IMAGE; REAL_MUL_LID] THEN MESON_TAC[]);; + +let HOMEOMORPHIC_TRANSLATION = prove + (`!s a:real^N. s homeomorphic (IMAGE (\x. a + x) s)`, + REPEAT STRIP_TAC THEN REWRITE_TAC[HOMEOMORPHIC_MINIMAL] THEN + MAP_EVERY EXISTS_TAC [`\x:real^N. a + x`; `\x:real^N. --a + x`] THEN + ASM_SIMP_TAC[CONTINUOUS_ON_ADD; CONTINUOUS_ON_CONST; CONTINUOUS_ON_ID] THEN + SIMP_TAC[VECTOR_ADD_ASSOC; VECTOR_ADD_LINV; VECTOR_ADD_RINV; + FORALL_IN_IMAGE; VECTOR_ADD_LID] THEN + REWRITE_TAC[IN_IMAGE] THEN MESON_TAC[]);; + +let HOMEOMORPHIC_AFFINITY = prove + (`!s a:real^N c. ~(c = &0) ==> s homeomorphic (IMAGE (\x. a + c % x) s)`, + REPEAT STRIP_TAC THEN + MATCH_MP_TAC HOMEOMORPHIC_TRANS THEN + EXISTS_TAC `IMAGE (\x:real^N. c % x) s` THEN + ASM_SIMP_TAC[HOMEOMORPHIC_SCALING] THEN + SUBGOAL_THEN `(\x:real^N. a + c % x) = (\x. a + x) o (\x. c % x)` + SUBST1_TAC THENL [REWRITE_TAC[o_DEF]; ALL_TAC] THEN + REWRITE_TAC[IMAGE_o; HOMEOMORPHIC_TRANSLATION]);; + +let [HOMEOMORPHIC_BALLS; HOMEOMORPHIC_CBALLS; HOMEOMORPHIC_SPHERES] = + (CONJUNCTS o prove) + (`(!a:real^N b:real^N d e. + &0 < d /\ &0 < e ==> ball(a,d) homeomorphic ball(b,e)) /\ + (!a:real^N b:real^N d e. + &0 < d /\ &0 < e ==> cball(a,d) homeomorphic cball(b,e)) /\ + (!a:real^N b:real^N d e. + &0 < d /\ &0 < e ==> sphere(a,d) homeomorphic sphere(b,e))`, + REPEAT STRIP_TAC THEN REWRITE_TAC[HOMEOMORPHIC_MINIMAL] THEN + EXISTS_TAC `\x:real^N. b + (e / d) % (x - a)` THEN + EXISTS_TAC `\x:real^N. a + (d / e) % (x - b)` THEN + ASM_SIMP_TAC[CONTINUOUS_ON_ADD; CONTINUOUS_ON_SUB; CONTINUOUS_ON_CMUL; + CONTINUOUS_ON_CONST; CONTINUOUS_ON_ID; IN_BALL; IN_CBALL; IN_SPHERE] THEN + REWRITE_TAC[dist; VECTOR_ARITH `a - (a + b) = --b:real^N`; NORM_NEG] THEN + REWRITE_TAC[real_div; VECTOR_ARITH + `a + d % ((b + e % (x - a)) - b) = (&1 - d * e) % a + (d * e) % x`] THEN + ONCE_REWRITE_TAC[REAL_ARITH + `(e * d') * (d * e') = (d * d') * (e * e')`] THEN + ASM_SIMP_TAC[REAL_MUL_RINV; REAL_LT_IMP_NZ; REAL_MUL_LID; REAL_SUB_REFL] THEN + REWRITE_TAC[NORM_MUL; VECTOR_MUL_LZERO; VECTOR_MUL_LID; VECTOR_ADD_LID] THEN + ASM_SIMP_TAC[REAL_ABS_MUL; REAL_ABS_INV; REAL_ARITH + `&0 < x ==> (abs x = x)`] THEN + GEN_REWRITE_TAC(BINOP_CONV o BINDER_CONV o funpow 2 RAND_CONV) + [GSYM REAL_MUL_RID] THEN + ONCE_REWRITE_TAC[AC REAL_MUL_AC `(a * b) * c = (a * c) * b`] THEN + ASM_SIMP_TAC[REAL_LE_LMUL_EQ; GSYM real_div; REAL_LE_LDIV_EQ; REAL_MUL_LID; + GSYM REAL_MUL_ASSOC; REAL_LT_LMUL_EQ; REAL_LT_LDIV_EQ; NORM_SUB] THEN + ASM_SIMP_TAC[REAL_DIV_REFL; REAL_LT_IMP_NZ; REAL_MUL_RID]);; + +(* ------------------------------------------------------------------------- *) +(* Homeomorphism of one-point compactifications. *) +(* ------------------------------------------------------------------------- *) + +let HOMEOMORPHIC_ONE_POINT_COMPACTIFICATIONS = prove + (`!s:real^M->bool t:real^N->bool a b. + compact s /\ compact t /\ a IN s /\ b IN t /\ + (s DELETE a) homeomorphic (t DELETE b) + ==> s homeomorphic t`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC HOMEOMORPHIC_COMPACT THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [homeomorphic]) THEN + REWRITE_TAC[HOMEOMORPHISM; LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`f:real^M->real^N`; `g:real^N->real^M`] THEN + STRIP_TAC THEN + EXISTS_TAC `\x. if x = a then b else (f:real^M->real^N) x` THEN + ASM_REWRITE_TAC[] THEN CONJ_TAC THENL [ALL_TAC; ASM SET_TAC[]] THEN + REWRITE_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN] THEN + X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN + ASM_CASES_TAC `x:real^M = a` THEN ASM_REWRITE_TAC[] THENL + [REWRITE_TAC[continuous_within] THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN + MP_TAC(ISPECL [`b:real^N`; `e:real`] CENTRE_IN_BALL) THEN + ASM_REWRITE_TAC[] THEN DISCH_TAC THEN + SUBGOAL_THEN + `closed_in (subtopology euclidean s) + { x | x IN (s DELETE a) /\ + (f:real^M->real^N)(x) IN t DIFF ball(b,e)}` + MP_TAC THENL + [MATCH_MP_TAC CLOSED_SUBSET THEN CONJ_TAC THENL [SET_TAC[]; ALL_TAC] THEN + MATCH_MP_TAC COMPACT_IMP_CLOSED THEN SUBGOAL_THEN + `{x | x IN s DELETE a /\ f x IN t DIFF ball(b,e)} = + IMAGE (g:real^N->real^M) (t DIFF ball (b,e))` + SUBST1_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + MATCH_MP_TAC COMPACT_CONTINUOUS_IMAGE THEN + ASM_SIMP_TAC[COMPACT_DIFF; OPEN_BALL] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET)) THEN ASM SET_TAC[]; + REWRITE_TAC[closed_in; open_in; TOPSPACE_EUCLIDEAN_SUBTOPOLOGY] THEN + DISCH_THEN(MP_TAC o SPEC `a:real^M` o last o CONJUNCTS) THEN + ASM_REWRITE_TAC[IN_ELIM_THM; IN_DIFF; IN_DELETE] THEN + SIMP_TAC[IMP_CONJ; DE_MORGAN_THM] THEN + MATCH_MP_TAC MONO_EXISTS THEN REPEAT STRIP_TAC THEN + ASM_REWRITE_TAC[] THEN COND_CASES_TAC THEN + ASM_REWRITE_TAC[DIST_REFL] THEN ONCE_REWRITE_TAC[DIST_SYM] THEN + RULE_ASSUM_TAC(REWRITE_RULE[IN_BALL]) THEN ASM SET_TAC[]]; + UNDISCH_TAC `(f:real^M->real^N) continuous_on (s DELETE a)` THEN + REWRITE_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN] THEN + DISCH_THEN(MP_TAC o SPEC `x:real^M`) THEN ASM_REWRITE_TAC[IN_DELETE] THEN + REWRITE_TAC[continuous_within] THEN + MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `e:real` THEN + ASM_CASES_TAC `&0 < e` THEN ASM_REWRITE_TAC[IN_DELETE] THEN + DISCH_THEN(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `min d (dist(a:real^M,x))` THEN + ASM_REWRITE_TAC[REAL_LT_MIN; GSYM DIST_NZ] THEN + ASM_MESON_TAC[REAL_LT_REFL]]);; + +(* ------------------------------------------------------------------------- *) +(* Homeomorphisms between open intervals in real^1 and then in real^N. *) +(* Could prove similar things for closed intervals, but they drop out of *) +(* later stuff in "convex.ml" even more easily. *) +(* ------------------------------------------------------------------------- *) + +let HOMEOMORPHIC_OPEN_INTERVALS_1 = prove + (`!a b c d. + drop a < drop b /\ drop c < drop d + ==> interval(a,b) homeomorphic interval(c,d)`, + SUBGOAL_THEN + `!a b. drop a < drop b + ==> interval(vec 0:real^1,vec 1) homeomorphic interval(a,b)` + ASSUME_TAC THENL + [REPEAT STRIP_TAC THEN REWRITE_TAC[HOMEOMORPHIC_MINIMAL] THEN + EXISTS_TAC `(\x. a + drop x % (b - a)):real^1->real^1` THEN + EXISTS_TAC `(\x. inv(drop b - drop a) % (x - a)):real^1->real^1` THEN + ASM_REWRITE_TAC[IN_INTERVAL_1; GSYM DROP_EQ] THEN + REWRITE_TAC[DROP_ADD; DROP_CMUL; DROP_NEG; DROP_VEC; DROP_SUB] THEN + REWRITE_TAC[REAL_ARITH `inv b * a:real = a / b`] THEN + ASM_SIMP_TAC[REAL_LT_LDIV_EQ; REAL_LT_RDIV_EQ; REAL_SUB_LT; + REAL_LT_ADDR; REAL_EQ_LDIV_EQ; REAL_DIV_RMUL; REAL_LT_IMP_NZ; + REAL_LT_MUL; REAL_MUL_LZERO; REAL_ADD_SUB; REAL_LT_RMUL_EQ; + REAL_ARITH `a + x < b <=> x < &1 * (b - a)`] THEN + REPEAT CONJ_TAC THENL + [REAL_ARITH_TAC; + MATCH_MP_TAC CONTINUOUS_ON_ADD THEN REWRITE_TAC[CONTINUOUS_ON_CONST] THEN + MATCH_MP_TAC CONTINUOUS_ON_VMUL THEN + REWRITE_TAC[o_DEF; LIFT_DROP; CONTINUOUS_ON_ID]; + MATCH_MP_TAC CONTINUOUS_ON_CMUL THEN + ASM_SIMP_TAC[CONTINUOUS_ON_SUB; CONTINUOUS_ON_CONST; CONTINUOUS_ON_ID]]; + REPEAT STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o SPECL [`a:real^1`; `b:real^1`]) THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`c:real^1`; `d:real^1`]) THEN + ASM_REWRITE_TAC[GSYM IMP_CONJ_ALT] THEN + GEN_REWRITE_TAC (LAND_CONV o LAND_CONV) [HOMEOMORPHIC_SYM] THEN + REWRITE_TAC[HOMEOMORPHIC_TRANS]]);; + +let HOMEOMORPHIC_OPEN_INTERVAL_UNIV_1 = prove + (`!a b. drop a < drop b ==> interval(a,b) homeomorphic (:real^1)`, + REPEAT STRIP_TAC THEN + MP_TAC(SPECL [`a:real^1`; `b:real^1`; `--vec 1:real^1`; `vec 1:real^1`] + HOMEOMORPHIC_OPEN_INTERVALS_1) THEN + ASM_REWRITE_TAC[DROP_VEC; DROP_NEG] THEN CONV_TAC REAL_RAT_REDUCE_CONV THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] HOMEOMORPHIC_TRANS) THEN + POP_ASSUM_LIST(K ALL_TAC) THEN + REWRITE_TAC[HOMEOMORPHIC_MINIMAL; IN_UNIV] THEN + EXISTS_TAC `\x:real^1. inv(&1 - norm x) % x` THEN + EXISTS_TAC `\y. if &0 <= drop y then inv(&1 + drop y) % y + else inv(&1 - drop y) % y` THEN + REWRITE_TAC[] THEN REPEAT CONJ_TAC THENL + [X_GEN_TAC `x:real^1` THEN REWRITE_TAC[IN_INTERVAL_1] THEN + REWRITE_TAC[DROP_NEG; DROP_VEC; DROP_CMUL; NORM_REAL; GSYM drop] THEN + SIMP_TAC[REAL_LE_MUL_EQ; REAL_LT_INV_EQ; REAL_LE_MUL_EQ; REAL_ARITH + `--a < x /\ x < a ==> &0 < a - abs x`] THEN + SIMP_TAC[real_abs; VECTOR_MUL_ASSOC] THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN STRIP_TAC THEN + GEN_REWRITE_TAC RAND_CONV [GSYM VECTOR_MUL_LID] THEN + AP_THM_TAC THEN AP_TERM_TAC THEN + REPEAT(POP_ASSUM MP_TAC) THEN CONV_TAC REAL_FIELD; + X_GEN_TAC `y:real^1` THEN COND_CASES_TAC THEN + ASM_REWRITE_TAC[IN_INTERVAL_1; DROP_NEG; DROP_VEC; REAL_BOUNDS_LT] THEN + REWRITE_TAC[DROP_CMUL; REAL_ABS_MUL; REAL_ABS_INV] THEN + REWRITE_TAC[GSYM(ONCE_REWRITE_RULE[REAL_MUL_SYM] real_div)] THEN + ASM_SIMP_TAC[REAL_LT_LDIV_EQ; REAL_ARITH `&0 <= x ==> &0 < abs(&1 + x)`; + REAL_ARITH `~(&0 <= x) ==> &0 < abs(&1 - x)`] THEN + (CONJ_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC]) THEN + REWRITE_TAC[NORM_REAL; VECTOR_MUL_ASSOC] THEN + REWRITE_TAC[GSYM drop; DROP_CMUL; REAL_ABS_MUL] THEN + ASM_REWRITE_TAC[real_abs; REAL_LE_INV_EQ] THEN + ASM_SIMP_TAC[REAL_ARITH `&0 <= x ==> &0 <= &1 + x`; + REAL_ARITH `~(&0 <= x) ==> &0 <= &1 - x`] THEN + GEN_REWRITE_TAC RAND_CONV [GSYM VECTOR_MUL_LID] THEN + AP_THM_TAC THEN AP_TERM_TAC THEN + REPEAT(POP_ASSUM MP_TAC) THEN CONV_TAC REAL_FIELD; + MATCH_MP_TAC CONTINUOUS_AT_IMP_CONTINUOUS_ON THEN + X_GEN_TAC `x:real^1` THEN + REWRITE_TAC[IN_INTERVAL_1; DROP_NEG; DROP_VEC] THEN + DISCH_TAC THEN MATCH_MP_TAC CONTINUOUS_MUL THEN + REWRITE_TAC[CONTINUOUS_AT_ID] THEN + ONCE_REWRITE_TAC[GSYM o_DEF] THEN MATCH_MP_TAC CONTINUOUS_INV THEN + REWRITE_TAC[NETLIMIT_AT; o_DEF; LIFT_SUB; LIFT_DROP] THEN + CONJ_TAC THENL + [MATCH_MP_TAC CONTINUOUS_SUB THEN + SIMP_TAC[CONTINUOUS_CONST; REWRITE_RULE[o_DEF] CONTINUOUS_AT_LIFT_NORM]; + REWRITE_TAC[NORM_REAL; GSYM drop] THEN ASM_REAL_ARITH_TAC]; + SUBGOAL_THEN `(:real^1) = {x | x$1 >= &0} UNION {x | x$1 <= &0}` + SUBST1_TAC THENL + [REWRITE_TAC[EXTENSION; IN_UNION; IN_UNION; IN_ELIM_THM; IN_UNIV] THEN + REAL_ARITH_TAC; + MATCH_MP_TAC CONTINUOUS_ON_CASES THEN + REWRITE_TAC[CLOSED_HALFSPACE_COMPONENT_LE; CLOSED_HALFSPACE_COMPONENT_GE; + IN_ELIM_THM] THEN + REWRITE_TAC[GSYM drop; REAL_NOT_LE; real_ge; REAL_LET_ANTISYM] THEN + SIMP_TAC[REAL_LE_ANTISYM; REAL_SUB_RZERO; REAL_ADD_RID] THEN + CONJ_TAC THEN MATCH_MP_TAC CONTINUOUS_AT_IMP_CONTINUOUS_ON THEN + X_GEN_TAC `y:real^1` THEN REWRITE_TAC[IN_ELIM_THM; real_ge] THEN + DISCH_TAC THEN MATCH_MP_TAC CONTINUOUS_MUL THEN + REWRITE_TAC[CONTINUOUS_AT_ID] THEN + ONCE_REWRITE_TAC[GSYM o_DEF] THEN MATCH_MP_TAC CONTINUOUS_INV THEN + REWRITE_TAC[NETLIMIT_AT; o_DEF; LIFT_ADD; LIFT_SUB; LIFT_DROP] THEN + ASM_SIMP_TAC[CONTINUOUS_ADD; CONTINUOUS_AT_ID; CONTINUOUS_SUB; + CONTINUOUS_CONST] THEN + ASM_REAL_ARITH_TAC]]);; + +let HOMEOMORPHIC_OPEN_INTERVALS = prove + (`!a b:real^N c d:real^N. + (interval(a,b) = {} <=> interval(c,d) = {}) + ==> interval(a,b) homeomorphic interval(c,d)`, + REPEAT GEN_TAC THEN ASM_CASES_TAC `interval(c:real^N,d) = {}` THEN + ASM_REWRITE_TAC[] THEN DISCH_TAC THEN ASM_REWRITE_TAC[HOMEOMORPHIC_REFL] THEN + SUBGOAL_THEN + `!i. 1 <= i /\ i <= dimindex(:N) + ==> interval(lift((a:real^N)$i),lift((b:real^N)$i)) homeomorphic + interval(lift((c:real^N)$i),lift((d:real^N)$i))` + MP_TAC THENL + [RULE_ASSUM_TAC(REWRITE_RULE[INTERVAL_NE_EMPTY]) THEN + ASM_SIMP_TAC[HOMEOMORPHIC_OPEN_INTERVALS_1; LIFT_DROP]; + ALL_TAC] THEN + REWRITE_TAC[HOMEOMORPHIC_MINIMAL; IN_INTERVAL_1; LIFT_DROP] THEN + GEN_REWRITE_TAC (LAND_CONV o TOP_DEPTH_CONV) [RIGHT_IMP_EXISTS_THM] THEN + REWRITE_TAC[SKOLEM_THM; LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`f:num->real^1->real^1`; `g:num->real^1->real^1`] THEN + DISCH_TAC THEN + EXISTS_TAC + `(\x. lambda i. + drop((f:num->real^1->real^1) i (lift(x$i)))):real^N->real^N` THEN + EXISTS_TAC + `(\x. lambda i. + drop((g:num->real^1->real^1) i (lift(x$i)))):real^N->real^N` THEN + ASM_SIMP_TAC[IN_INTERVAL; LAMBDA_BETA; CART_EQ; LIFT_DROP] THEN + ONCE_REWRITE_TAC[CONTINUOUS_ON_COMPONENTWISE_LIFT] THEN + SIMP_TAC[LAMBDA_BETA; LIFT_DROP] THEN CONJ_TAC THEN REPEAT STRIP_TAC THEN + ONCE_REWRITE_TAC[GSYM o_DEF] THEN + MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN + ASM_SIMP_TAC[CONTINUOUS_ON_LIFT_COMPONENT] THEN + MATCH_MP_TAC CONTINUOUS_ON_SUBSET THENL + [EXISTS_TAC `interval(lift((a:real^N)$i),lift((b:real^N)$i))`; + EXISTS_TAC `interval(lift((c:real^N)$i),lift((d:real^N)$i))`] THEN + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; IN_INTERVAL_1] THEN + ASM_SIMP_TAC[LIFT_DROP; IN_INTERVAL]);; + +let HOMEOMORPHIC_OPEN_INTERVAL_UNIV = prove + (`!a b:real^N. + ~(interval(a,b) = {}) + ==> interval(a,b) homeomorphic (:real^N)`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN + `!i. 1 <= i /\ i <= dimindex(:N) + ==> interval(lift((a:real^N)$i),lift((b:real^N)$i)) homeomorphic + (:real^1)` + MP_TAC THENL + [RULE_ASSUM_TAC(REWRITE_RULE[INTERVAL_NE_EMPTY]) THEN + ASM_SIMP_TAC[HOMEOMORPHIC_OPEN_INTERVAL_UNIV_1; LIFT_DROP]; + ALL_TAC] THEN + REWRITE_TAC[HOMEOMORPHIC_MINIMAL; IN_INTERVAL_1; LIFT_DROP] THEN + GEN_REWRITE_TAC (LAND_CONV o TOP_DEPTH_CONV) [RIGHT_IMP_EXISTS_THM] THEN + REWRITE_TAC[SKOLEM_THM; LEFT_IMP_EXISTS_THM; IN_UNIV] THEN + MAP_EVERY X_GEN_TAC [`f:num->real^1->real^1`; `g:num->real^1->real^1`] THEN + DISCH_TAC THEN + EXISTS_TAC + `(\x. lambda i. + drop((f:num->real^1->real^1) i (lift(x$i)))):real^N->real^N` THEN + EXISTS_TAC + `(\x. lambda i. + drop((g:num->real^1->real^1) i (lift(x$i)))):real^N->real^N` THEN + ASM_SIMP_TAC[IN_INTERVAL; LAMBDA_BETA; CART_EQ; LIFT_DROP; IN_UNIV] THEN + ONCE_REWRITE_TAC[CONTINUOUS_ON_COMPONENTWISE_LIFT] THEN + SIMP_TAC[LAMBDA_BETA; LIFT_DROP] THEN CONJ_TAC THEN REPEAT STRIP_TAC THEN + ONCE_REWRITE_TAC[GSYM o_DEF] THEN + MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN + ASM_SIMP_TAC[CONTINUOUS_ON_LIFT_COMPONENT] THEN + MATCH_MP_TAC CONTINUOUS_ON_SUBSET THENL + [EXISTS_TAC `interval(lift((a:real^N)$i),lift((b:real^N)$i))`; + EXISTS_TAC `(:real^1)`] THEN + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; IN_INTERVAL_1; IN_UNIV] THEN + ASM_SIMP_TAC[LIFT_DROP; IN_INTERVAL]);; + +let HOMEOMORPHIC_BALL_UNIV = prove + (`!a:real^N r. &0 < r ==> ball(a,r) homeomorphic (:real^N)`, + REPEAT GEN_TAC THEN GEOM_ORIGIN_TAC `a:real^N` THEN REPEAT STRIP_TAC THEN + SUBGOAL_THEN `?y:real^N. r = norm(y)` (CHOOSE_THEN SUBST_ALL_TAC) THENL + [ASM_MESON_TAC[VECTOR_CHOOSE_SIZE; REAL_LT_IMP_LE]; POP_ASSUM MP_TAC] THEN + REWRITE_TAC[NORM_POS_LT] THEN GEOM_NORMALIZE_TAC `y:real^N` THEN + SIMP_TAC[] THEN GEN_TAC THEN REPEAT(DISCH_THEN(K ALL_TAC)) THEN + REWRITE_TAC[HOMEOMORPHIC_MINIMAL] THEN + EXISTS_TAC `\z:real^N. inv(&1 - norm(z)) % z` THEN + EXISTS_TAC `\z:real^N. inv(&1 + norm(z)) % z` THEN + REWRITE_TAC[IN_BALL; IN_UNIV; DIST_0; VECTOR_MUL_ASSOC; VECTOR_MUL_EQ_0; + VECTOR_ARITH `a % x:real^N = x <=> (a - &1) % x = vec 0`] THEN + REPEAT CONJ_TAC THENL + [X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN DISJ1_TAC THEN + REWRITE_TAC[GSYM REAL_INV_MUL; REAL_SUB_0; REAL_INV_EQ_1] THEN + REWRITE_TAC[NORM_MUL; REAL_ABS_INV] THEN + ASM_SIMP_TAC[REAL_ARITH `x < &1 ==> abs(&1 - x) = &1 - x`] THEN + POP_ASSUM MP_TAC THEN CONV_TAC REAL_FIELD; + X_GEN_TAC `y:real^N` THEN REWRITE_TAC[NORM_MUL; REAL_ABS_INV] THEN + ASM_SIMP_TAC[NORM_POS_LE; REAL_ARITH + `&0 <= y ==> inv(abs(&1 + y)) * z = z / (&1 + y)`] THEN + ASM_SIMP_TAC[NORM_POS_LE; REAL_LT_LDIV_EQ; REAL_ARITH + `&0 <= y ==> &0 < &1 + y`] THEN + CONJ_TAC THENL [REAL_ARITH_TAC; DISJ1_TAC] THEN + REWRITE_TAC[GSYM REAL_INV_MUL; REAL_SUB_0; REAL_INV_EQ_1] THEN + MP_TAC(ISPEC `y:real^N` NORM_POS_LE) THEN CONV_TAC REAL_FIELD; + MATCH_MP_TAC CONTINUOUS_ON_MUL THEN REWRITE_TAC[CONTINUOUS_ON_ID] THEN + GEN_REWRITE_TAC (LAND_CONV o RAND_CONV) [GSYM o_DEF] THEN + MATCH_MP_TAC CONTINUOUS_ON_INV THEN + SIMP_TAC[IN_BALL_0; REAL_SUB_0; REAL_ARITH `x < &1 ==> ~(&1 = x)`] THEN + REWRITE_TAC[o_DEF; LIFT_SUB] THEN MATCH_MP_TAC CONTINUOUS_ON_SUB THEN + REWRITE_TAC[CONTINUOUS_ON_CONST] THEN + MATCH_MP_TAC CONTINUOUS_ON_LIFT_NORM_COMPOSE THEN + REWRITE_TAC[CONTINUOUS_ON_ID]; + MATCH_MP_TAC CONTINUOUS_ON_MUL THEN REWRITE_TAC[CONTINUOUS_ON_ID] THEN + GEN_REWRITE_TAC (LAND_CONV o RAND_CONV) [GSYM o_DEF] THEN + MATCH_MP_TAC CONTINUOUS_ON_INV THEN + SIMP_TAC[NORM_POS_LE; REAL_ARITH `&0 <= x ==> ~(&1 + x = &0)`] THEN + REWRITE_TAC[o_DEF; LIFT_ADD] THEN MATCH_MP_TAC CONTINUOUS_ON_ADD THEN + REWRITE_TAC[CONTINUOUS_ON_CONST] THEN + MATCH_MP_TAC CONTINUOUS_ON_LIFT_NORM_COMPOSE THEN + REWRITE_TAC[CONTINUOUS_ON_ID]]);; + +(* ------------------------------------------------------------------------- *) +(* Cardinalities of various useful sets. *) +(* ------------------------------------------------------------------------- *) + +let CARD_EQ_EUCLIDEAN = prove + (`(:real^N) =_c (:real)`, + MATCH_MP_TAC CARD_EQ_CART THEN REWRITE_TAC[real_INFINITE]);; + +let UNCOUNTABLE_EUCLIDEAN = prove + (`~COUNTABLE(:real^N)`, + MATCH_MP_TAC CARD_EQ_REAL_IMP_UNCOUNTABLE THEN + REWRITE_TAC[CARD_EQ_EUCLIDEAN]);; + +let CARD_EQ_INTERVAL = prove + (`(!a b:real^N. ~(interval(a,b) = {}) ==> interval[a,b] =_c (:real)) /\ + (!a b:real^N. ~(interval(a,b) = {}) ==> interval(a,b) =_c (:real))`, + REWRITE_TAC[AND_FORALL_THM] THEN REPEAT GEN_TAC THEN + ASM_CASES_TAC `interval(a:real^N,b) = {}` THEN ASM_REWRITE_TAC[] THEN + CONJ_TAC THEN REWRITE_TAC[GSYM CARD_LE_ANTISYM] THEN CONJ_TAC THENL + [TRANS_TAC CARD_LE_TRANS `(:real^N)` THEN + REWRITE_TAC[CARD_LE_UNIV] THEN MATCH_MP_TAC CARD_EQ_IMP_LE THEN + REWRITE_TAC[CARD_EQ_EUCLIDEAN]; + TRANS_TAC CARD_LE_TRANS `interval(a:real^N,b)` THEN + SIMP_TAC[CARD_LE_SUBSET; INTERVAL_OPEN_SUBSET_CLOSED]; + TRANS_TAC CARD_LE_TRANS `(:real^N)` THEN + REWRITE_TAC[CARD_LE_UNIV] THEN MATCH_MP_TAC CARD_EQ_IMP_LE THEN + REWRITE_TAC[CARD_EQ_EUCLIDEAN]; + ALL_TAC] THEN + TRANS_TAC CARD_LE_TRANS `(:real^N)` THEN + SIMP_TAC[ONCE_REWRITE_RULE[CARD_EQ_SYM] CARD_EQ_IMP_LE; + CARD_EQ_EUCLIDEAN] THEN + FIRST_X_ASSUM(MP_TAC o MATCH_MP HOMEOMORPHIC_OPEN_INTERVAL_UNIV) THEN + DISCH_THEN(MP_TAC o MATCH_MP HOMEOMORPHIC_IMP_CARD_EQ) THEN + MESON_TAC[CARD_EQ_IMP_LE; CARD_EQ_SYM]);; + +let UNCOUNTABLE_INTERVAL = prove + (`(!a b. ~(interval(a,b) = {}) ==> ~COUNTABLE(interval[a,b])) /\ + (!a b. ~(interval(a,b) = {}) ==> ~COUNTABLE(interval(a,b)))`, + SIMP_TAC[CARD_EQ_REAL_IMP_UNCOUNTABLE; CARD_EQ_INTERVAL]);; + +let COUNTABLE_OPEN_INTERVAL = prove + (`!a b. COUNTABLE(interval(a,b)) <=> interval(a,b) = {}`, + MESON_TAC[COUNTABLE_EMPTY; UNCOUNTABLE_INTERVAL]);; + +let CARD_EQ_OPEN = prove + (`!s:real^N->bool. open s /\ ~(s = {}) ==> s =_c (:real)`, + REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM CARD_LE_ANTISYM] THEN CONJ_TAC THENL + [TRANS_TAC CARD_LE_TRANS `(:real^N)` THEN + REWRITE_TAC[CARD_LE_UNIV] THEN MATCH_MP_TAC CARD_EQ_IMP_LE THEN + REWRITE_TAC[CARD_EQ_EUCLIDEAN]; + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [OPEN_CONTAINS_INTERVAL]) THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN + DISCH_THEN(X_CHOOSE_TAC `c:real^N`) THEN + DISCH_THEN(MP_TAC o SPEC `c:real^N`) THEN + ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`a:real^N`; `b:real^N`] THEN + ASM_CASES_TAC `interval(a:real^N,b) = {}` THEN + ASM_REWRITE_TAC[NOT_IN_EMPTY] THEN STRIP_TAC THEN + TRANS_TAC CARD_LE_TRANS `interval[a:real^N,b]` THEN + ASM_SIMP_TAC[CARD_LE_SUBSET] THEN MATCH_MP_TAC CARD_EQ_IMP_LE THEN + ONCE_REWRITE_TAC[CARD_EQ_SYM] THEN ASM_SIMP_TAC[CARD_EQ_INTERVAL]]);; + +let UNCOUNTABLE_OPEN = prove + (`!s:real^N->bool. open s /\ ~(s = {}) ==> ~(COUNTABLE s)`, + SIMP_TAC[CARD_EQ_OPEN; CARD_EQ_REAL_IMP_UNCOUNTABLE]);; + +let CARD_EQ_BALL = prove + (`!a:real^N r. &0 < r ==> ball(a,r) =_c (:real)`, + SIMP_TAC[CARD_EQ_OPEN; OPEN_BALL; BALL_EQ_EMPTY; GSYM REAL_NOT_LT]);; + +let CARD_EQ_CBALL = prove + (`!a:real^N r. &0 < r ==> cball(a,r) =_c (:real)`, + REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM CARD_LE_ANTISYM] THEN CONJ_TAC THENL + [TRANS_TAC CARD_LE_TRANS `(:real^N)` THEN + REWRITE_TAC[CARD_LE_UNIV] THEN MATCH_MP_TAC CARD_EQ_IMP_LE THEN + REWRITE_TAC[CARD_EQ_EUCLIDEAN]; + TRANS_TAC CARD_LE_TRANS `ball(a:real^N,r)` THEN + SIMP_TAC[CARD_LE_SUBSET; BALL_SUBSET_CBALL] THEN + MATCH_MP_TAC CARD_EQ_IMP_LE THEN + ONCE_REWRITE_TAC[CARD_EQ_SYM] THEN ASM_SIMP_TAC[CARD_EQ_BALL]]);; + +let FINITE_IMP_NOT_OPEN = prove + (`!s:real^N->bool. FINITE s /\ ~(s = {}) ==> ~(open s)`, + MESON_TAC[UNCOUNTABLE_OPEN; FINITE_IMP_COUNTABLE]);; + +let OPEN_IMP_INFINITE = prove + (`!s. open s ==> s = {} \/ INFINITE s`, + MESON_TAC[FINITE_IMP_NOT_OPEN; INFINITE]);; + +let EMPTY_INTERIOR_FINITE = prove + (`!s:real^N->bool. FINITE s ==> interior s = {}`, + REPEAT STRIP_TAC THEN MP_TAC(ISPEC `s:real^N->bool` OPEN_INTERIOR) THEN + ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] FINITE_IMP_NOT_OPEN) THEN + MATCH_MP_TAC FINITE_SUBSET THEN EXISTS_TAC `s:real^N->bool` THEN + ASM_REWRITE_TAC[INTERIOR_SUBSET]);; + +let CARD_EQ_CONNECTED = prove + (`!s a b:real^N. + connected s /\ a IN s /\ b IN s /\ ~(a = b) ==> s =_c (:real)`, + GEOM_ORIGIN_TAC `b:real^N` THEN GEOM_NORMALIZE_TAC `a:real^N` THEN + REWRITE_TAC[NORM_EQ_SQUARE; REAL_POS; REAL_POW_ONE] THEN + REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM CARD_LE_ANTISYM] THEN CONJ_TAC THENL + [TRANS_TAC CARD_LE_TRANS `(:real^N)` THEN + SIMP_TAC[CARD_LE_UNIV; CARD_EQ_EUCLIDEAN; CARD_EQ_IMP_LE]; + TRANS_TAC CARD_LE_TRANS `interval[vec 0:real^1,vec 1]` THEN CONJ_TAC THENL + [MATCH_MP_TAC(ONCE_REWRITE_RULE[CARD_EQ_SYM] CARD_EQ_IMP_LE) THEN + SIMP_TAC[UNIT_INTERVAL_NONEMPTY; CARD_EQ_INTERVAL]; + REWRITE_TAC[LE_C] THEN EXISTS_TAC `\x:real^N. lift(a dot x)` THEN + SIMP_TAC[FORALL_LIFT; LIFT_EQ; IN_INTERVAL_1; LIFT_DROP; DROP_VEC] THEN + X_GEN_TAC `t:real` THEN STRIP_TAC THEN + MATCH_MP_TAC CONNECTED_IVT_HYPERPLANE THEN + MAP_EVERY EXISTS_TAC [`vec 0:real^N`; `a:real^N`] THEN + ASM_REWRITE_TAC[DOT_RZERO]]]);; + +let UNCOUNTABLE_CONNECTED = prove + (`!s a b:real^N. + connected s /\ a IN s /\ b IN s /\ ~(a = b) ==> ~COUNTABLE s`, + REPEAT GEN_TAC THEN STRIP_TAC THEN + MATCH_MP_TAC CARD_EQ_REAL_IMP_UNCOUNTABLE THEN + MATCH_MP_TAC CARD_EQ_CONNECTED THEN + ASM_MESON_TAC[]);; + +let CARD_LT_IMP_DISCONNECTED = prove + (`!s x:real^N. s <_c (:real) /\ x IN s ==> connected_component s x = {x}`, + REPEAT STRIP_TAC THEN REWRITE_TAC[SET_RULE + `s = {a} <=> a IN s /\ !a b. a IN s /\ b IN s /\ ~(a = b) ==> F`] THEN + REPEAT STRIP_TAC THEN REWRITE_TAC[IN] THEN + ASM_REWRITE_TAC[CONNECTED_COMPONENT_REFL_EQ] THEN + MP_TAC(ISPECL [`connected_component s (x:real^N)`; `a:real^N`; `b:real^N`] + CARD_EQ_CONNECTED) THEN + ASM_REWRITE_TAC[CONNECTED_CONNECTED_COMPONENT] THEN + DISCH_TAC THEN UNDISCH_TAC `(s:real^N->bool) <_c (:real)` THEN + REWRITE_TAC[CARD_NOT_LT] THEN + TRANS_TAC CARD_LE_TRANS `connected_component s (x:real^N)` THEN + ASM_SIMP_TAC[ONCE_REWRITE_RULE[CARD_EQ_SYM] CARD_EQ_IMP_LE] THEN + MATCH_MP_TAC CARD_LE_SUBSET THEN REWRITE_TAC[CONNECTED_COMPONENT_SUBSET]);; + +let COUNTABLE_IMP_DISCONNECTED = prove + (`!s x:real^N. COUNTABLE s /\ x IN s ==> connected_component s x = {x}`, + SIMP_TAC[CARD_LT_IMP_DISCONNECTED; COUNTABLE_IMP_CARD_LT_REAL]);; + +let CONNECTED_CARD_EQ_IFF_NONTRIVIAL = prove + (`!s:real^N->bool. + connected s ==> (s =_c (:real) <=> ~(?a. s SUBSET {a}))`, + REPEAT STRIP_TAC THEN EQ_TAC THEN REPEAT STRIP_TAC THENL + [ALL_TAC; MATCH_MP_TAC CARD_EQ_CONNECTED THEN ASM SET_TAC[]] THEN + FIRST_ASSUM(MP_TAC o MATCH_MP(REWRITE_RULE[IMP_CONJ_ALT] FINITE_SUBSET)) THEN + REWRITE_TAC[FINITE_SING] THEN + ASM_MESON_TAC[CARD_EQ_REAL_IMP_UNCOUNTABLE; FINITE_IMP_COUNTABLE]);; + +(* ------------------------------------------------------------------------- *) +(* "Iff" forms of constancy of function from connected set into a set that *) +(* is smaller than R, or countable, or finite, or disconnected, or discrete. *) +(* ------------------------------------------------------------------------- *) + +let [CONTINUOUS_DISCONNECTED_RANGE_CONSTANT_EQ; + CONTINUOUS_DISCRETE_RANGE_CONSTANT_EQ; + CONTINUOUS_FINITE_RANGE_CONSTANT_EQ] = (CONJUNCTS o prove) + (`(!s. connected s <=> + !f:real^M->real^N t. + f continuous_on s /\ IMAGE f s SUBSET t /\ + (!y. y IN t ==> connected_component t y = {y}) + ==> ?a. !x. x IN s ==> f x = a) /\ + (!s. connected s <=> + !f:real^M->real^N. + f continuous_on s /\ + (!x. x IN s + ==> ?e. &0 < e /\ + !y. y IN s /\ ~(f y = f x) ==> e <= norm(f y - f x)) + ==> ?a. !x. x IN s ==> f x = a) /\ + (!s. connected s <=> + !f:real^M->real^N. + f continuous_on s /\ FINITE(IMAGE f s) + ==> ?a. !x. x IN s ==> f x = a)`, + REWRITE_TAC[AND_FORALL_THM] THEN X_GEN_TAC `s:real^M->bool` THEN + MATCH_MP_TAC(TAUT + `(s ==> t) /\ (t ==> u) /\ (u ==> v) /\ (v ==> s) + ==> (s <=> t) /\ (s <=> u) /\ (s <=> v)`) THEN + REPEAT CONJ_TAC THENL + [REPEAT STRIP_TAC THEN ASM_CASES_TAC `s:real^M->bool = {}` THEN + ASM_REWRITE_TAC[NOT_IN_EMPTY] THEN + FIRST_X_ASSUM(X_CHOOSE_TAC `x:real^M` o + GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN + EXISTS_TAC `(f:real^M->real^N) x` THEN + MATCH_MP_TAC(SET_RULE + `IMAGE f s SUBSET {a} ==> !y. y IN s ==> f y = a`) THEN + FIRST_X_ASSUM(MP_TAC o SPEC `(f:real^M->real^N) x`) THEN + ANTS_TAC THENL [ASM SET_TAC[]; DISCH_THEN(SUBST1_TAC o SYM)] THEN + MATCH_MP_TAC CONNECTED_COMPONENT_MAXIMAL THEN + ASM_SIMP_TAC[CONNECTED_CONTINUOUS_IMAGE] THEN ASM SET_TAC[]; + REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + EXISTS_TAC `IMAGE (f:real^M->real^N) s` THEN + ASM_REWRITE_TAC[FORALL_IN_IMAGE; SUBSET_REFL] THEN + X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `x:real^M`) THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `e:real` STRIP_ASSUME_TAC) THEN + MATCH_MP_TAC(SET_RULE + `(!y. y IN s /\ f y IN connected_component (IMAGE f s) a ==> f y = a) /\ + connected_component (IMAGE f s) a SUBSET (IMAGE f s) /\ + connected_component (IMAGE f s) a a + ==> connected_component (IMAGE f s) a = {a}`) THEN + REWRITE_TAC[CONNECTED_COMPONENT_SUBSET; CONNECTED_COMPONENT_REFL_EQ] THEN + ASM_SIMP_TAC[FUN_IN_IMAGE] THEN X_GEN_TAC `y:real^M` THEN STRIP_TAC THEN + MP_TAC(ISPEC `connected_component (IMAGE (f:real^M->real^N) s) (f x)` + CONNECTED_CLOSED) THEN + REWRITE_TAC[CONNECTED_CONNECTED_COMPONENT] THEN + ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN DISCH_TAC THEN + ASM_REWRITE_TAC[] THEN MAP_EVERY EXISTS_TAC + [`cball((f:real^M->real^N) x,e / &2)`; + `(:real^N) DIFF ball((f:real^M->real^N) x,e)`] THEN + REWRITE_TAC[GSYM OPEN_CLOSED; OPEN_BALL; CLOSED_CBALL] THEN + REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN REPEAT CONJ_TAC THENL + [REWRITE_TAC[SUBSET; IN_CBALL; IN_UNION; IN_DIFF; IN_BALL; IN_UNIV] THEN + MATCH_MP_TAC(MESON[SUBSET; CONNECTED_COMPONENT_SUBSET] + `(!x. x IN s ==> P x) + ==> (!x. x IN connected_component s y ==> P x)`) THEN + REWRITE_TAC[FORALL_IN_IMAGE] THEN X_GEN_TAC `z:real^M` THEN + DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC `z:real^M`) THEN + ASM_REWRITE_TAC[] THEN CONV_TAC NORM_ARITH; + MATCH_MP_TAC(SET_RULE + `(!x. x IN s /\ x IN t ==> F) ==> s INTER t INTER u = {}`) THEN + REWRITE_TAC[IN_BALL; IN_CBALL; IN_DIFF; IN_UNIV] THEN + UNDISCH_TAC `&0 < e` THEN CONV_TAC NORM_ARITH; + EXISTS_TAC `(f:real^M->real^N) x` THEN + ASM_SIMP_TAC[CENTRE_IN_CBALL; REAL_HALF; REAL_LT_IMP_LE; IN_INTER] THEN + REWRITE_TAC[IN] THEN + ASM_SIMP_TAC[CONNECTED_COMPONENT_REFL_EQ; FUN_IN_IMAGE]; + EXISTS_TAC `(f:real^M->real^N) y` THEN + ASM_REWRITE_TAC[IN_INTER; IN_DIFF; IN_UNIV; IN_BALL; REAL_NOT_LT] THEN + ASM_SIMP_TAC[ONCE_REWRITE_RULE[DIST_SYM] dist]]; + MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `f:real^M->real^N` THEN + DISCH_THEN(fun th -> STRIP_TAC THEN MATCH_MP_TAC th) THEN + ASM_REWRITE_TAC[] THEN X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN + ASM_CASES_TAC `IMAGE (f:real^M->real^N) s DELETE (f x) = {}` THENL + [EXISTS_TAC `&1` THEN REWRITE_TAC[REAL_LT_01] THEN ASM SET_TAC[]; + ALL_TAC] THEN + EXISTS_TAC + `inf{norm(z - f x) |z| z IN IMAGE (f:real^M->real^N) s DELETE (f x)}` THEN + REWRITE_TAC[SIMPLE_IMAGE] THEN + ASM_SIMP_TAC[REAL_LT_INF_FINITE; REAL_INF_LE_FINITE; FINITE_DELETE; + FINITE_IMAGE; IMAGE_EQ_EMPTY] THEN + REWRITE_TAC[FORALL_IN_IMAGE; EXISTS_IN_IMAGE] THEN + REWRITE_TAC[IN_DELETE; NORM_POS_LT; VECTOR_SUB_EQ; IN_IMAGE] THEN + MESON_TAC[REAL_LE_REFL]; + REWRITE_TAC[CONNECTED_CLOSED_IN_EQ] THEN + ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN + REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`t:real^M->bool`; `u:real^M->bool`] THEN + STRIP_TAC THEN DISCH_THEN(MP_TAC o SPEC + `(\x. if x IN t then vec 0 else basis 1):real^M->real^N`) THEN + REWRITE_TAC[NOT_IMP] THEN REPEAT CONJ_TAC THENL + [EXPAND_TAC "s" THEN MATCH_MP_TAC CONTINUOUS_ON_CASES_LOCAL THEN + ASM_REWRITE_TAC[CONTINUOUS_ON_CONST] THEN ASM SET_TAC[]; + MATCH_MP_TAC FINITE_SUBSET THEN EXISTS_TAC `{vec 0:real^N,basis 1}` THEN + REWRITE_TAC[FINITE_INSERT; FINITE_EMPTY] THEN SET_TAC[]; + SUBGOAL_THEN `?a b:real^M. a IN s /\ a IN t /\ b IN s /\ ~(b IN t)` + STRIP_ASSUME_TAC THENL + [ASM SET_TAC[]; DISCH_THEN(CHOOSE_THEN MP_TAC)] THEN + DISCH_THEN(fun th -> MP_TAC(SPEC `a:real^M` th) THEN + MP_TAC(SPEC `b:real^M` th)) THEN + ASM_REWRITE_TAC[] THEN DISCH_THEN(SUBST1_TAC o SYM) THEN + CONV_TAC(RAND_CONV SYM_CONV) THEN + SIMP_TAC[BASIS_NONZERO; LE_REFL; DIMINDEX_GE_1; REAL_LE_REFL]]]);; + +let CONTINUOUS_DISCONNECTED_RANGE_CONSTANT = prove + (`!f:real^M->real^N s. + connected s /\ + f continuous_on s /\ IMAGE f s SUBSET t /\ + (!y. y IN t ==> connected_component t y = {y}) + ==> ?a. !x. x IN s ==> f x = a`, + MESON_TAC[CONTINUOUS_DISCONNECTED_RANGE_CONSTANT_EQ]);; + +let CONTINUOUS_DISCRETE_RANGE_CONSTANT = prove + (`!f:real^M->real^N s. + connected s /\ + f continuous_on s /\ + (!x. x IN s + ==> ?e. &0 < e /\ + !y. y IN s /\ ~(f y = f x) ==> e <= norm(f y - f x)) + ==> ?a. !x. x IN s ==> f x = a`, + ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN + REWRITE_TAC[RIGHT_FORALL_IMP_THM; IMP_CONJ] THEN + REWRITE_TAC[IMP_IMP; GSYM CONTINUOUS_DISCRETE_RANGE_CONSTANT_EQ]);; + +let CONTINUOUS_FINITE_RANGE_CONSTANT = prove + (`!f:real^M->real^N s. + connected s /\ + f continuous_on s /\ + FINITE(IMAGE f s) + ==> ?a. !x. x IN s ==> f x = a`, + MESON_TAC[CONTINUOUS_FINITE_RANGE_CONSTANT_EQ]);; + +let CONTINUOUS_COUNTABLE_RANGE_CONSTANT_EQ = prove + (`!s. connected s <=> + !f:real^M->real^N. + f continuous_on s /\ COUNTABLE(IMAGE f s) + ==> ?a. !x. x IN s ==> f x = a`, + GEN_TAC THEN EQ_TAC THENL + [REWRITE_TAC[CONTINUOUS_DISCONNECTED_RANGE_CONSTANT_EQ]; + REWRITE_TAC[CONTINUOUS_FINITE_RANGE_CONSTANT_EQ]] THEN + REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_SIMP_TAC[FINITE_IMP_COUNTABLE] THEN + EXISTS_TAC `IMAGE (f:real^M->real^N) s` THEN + ASM_SIMP_TAC[COUNTABLE_IMP_DISCONNECTED; SUBSET_REFL]);; + +let CONTINUOUS_CARD_LT_RANGE_CONSTANT_EQ = prove + (`!s. connected s <=> + !f:real^M->real^N. + f continuous_on s /\ (IMAGE f s) <_c (:real) + ==> ?a. !x. x IN s ==> f x = a`, + GEN_TAC THEN EQ_TAC THENL + [REWRITE_TAC[CONTINUOUS_DISCONNECTED_RANGE_CONSTANT_EQ]; + REWRITE_TAC[CONTINUOUS_COUNTABLE_RANGE_CONSTANT_EQ]] THEN + REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_SIMP_TAC[COUNTABLE_IMP_CARD_LT_REAL] THEN + EXISTS_TAC `IMAGE (f:real^M->real^N) s` THEN + ASM_SIMP_TAC[CARD_LT_IMP_DISCONNECTED; SUBSET_REFL]);; + +let CONTINUOUS_COUNTABLE_RANGE_CONSTANT = prove + (`!f:real^M->real^N s. + connected s /\ f continuous_on s /\ COUNTABLE(IMAGE f s) + ==> ?a. !x. x IN s ==> f x = a`, + MESON_TAC[CONTINUOUS_COUNTABLE_RANGE_CONSTANT_EQ]);; + +let CONTINUOUS_CARD_LT_RANGE_CONSTANT = prove + (`!f:real^M->real^N s. + connected s /\ f continuous_on s /\ (IMAGE f s) <_c (:real) + ==> ?a. !x. x IN s ==> f x = a`, + MESON_TAC[CONTINUOUS_CARD_LT_RANGE_CONSTANT_EQ]);; + +(* ------------------------------------------------------------------------- *) +(* Homeomorphism of hyperplanes. *) +(* ------------------------------------------------------------------------- *) + +let HOMEOMORPHIC_HYPERPLANES = prove + (`!a:real^N b c:real^N d. + ~(a = vec 0) /\ ~(c = vec 0) + ==> {x | a dot x = b} homeomorphic {x | c dot x = d}`, + let lemma = prove + (`~(a = vec 0) + ==> {x:real^N | a dot x = b} homeomorphic {x:real^N | x$1 = &0}`, + REPEAT STRIP_TAC THEN SUBGOAL_THEN `?c:real^N. a dot c = b` + STRIP_ASSUME_TAC THENL + [FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE RAND_CONV [CART_EQ]) THEN + REWRITE_TAC[NOT_FORALL_THM; NOT_IMP; VEC_COMPONENT] THEN + DISCH_THEN(X_CHOOSE_THEN `k:num` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `b / (a:real^N)$k % basis k:real^N` THEN + ASM_SIMP_TAC[DOT_RMUL; DOT_BASIS; REAL_DIV_RMUL]; + FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN + ABBREV_TAC `p = {x:real^N | x$1 = &0}` THEN + GEOM_ORIGIN_TAC `c:real^N` THEN + REWRITE_TAC[VECTOR_ADD_RID; DOT_RADD; DOT_RZERO; REAL_EQ_ADD_LCANCEL_0; + REAL_ADD_RID] THEN + REPEAT STRIP_TAC THEN UNDISCH_TAC `~(a:real^N = vec 0)` THEN + GEOM_BASIS_MULTIPLE_TAC 1 `a:real^N` THEN + SIMP_TAC[VECTOR_MUL_EQ_0; DE_MORGAN_THM; DOT_LMUL; REAL_ENTIRE] THEN + SIMP_TAC[DOT_BASIS; LE_REFL; DIMINDEX_GE_1] THEN + EXPAND_TAC "p" THEN REWRITE_TAC[HOMEOMORPHIC_REFL]]) in + REPEAT STRIP_TAC THEN + TRANS_TAC HOMEOMORPHIC_TRANS `{x:real^N | x$1 = &0}` THEN + ASM_SIMP_TAC[lemma] THEN ONCE_REWRITE_TAC[HOMEOMORPHIC_SYM] THEN + ASM_SIMP_TAC[lemma]);; + +let HOMEOMORPHIC_HYPERPLANE_STANDARD_HYPERPLANE = prove + (`!a:real^N b k c. + ~(a = vec 0) /\ 1 <= k /\ k <= dimindex(:N) + ==> {x | a dot x = b} homeomorphic {x:real^N | x$k = c}`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN `{x:real^N | x$k = c} = {x | basis k dot x = c}` SUBST1_TAC + THENL [ASM_SIMP_TAC[DOT_BASIS]; MATCH_MP_TAC HOMEOMORPHIC_HYPERPLANES] THEN + ASM_SIMP_TAC[BASIS_NONZERO]);; + +let HOMEOMORPHIC_STANDARD_HYPERPLANE_HYPERPLANE = prove + (`!a:real^N b k c. + ~(a = vec 0) /\ 1 <= k /\ k <= dimindex(:N) + ==> {x:real^N | x$k = c} homeomorphic {x | a dot x = b}`, + ONCE_REWRITE_TAC[HOMEOMORPHIC_SYM] THEN + REWRITE_TAC[HOMEOMORPHIC_HYPERPLANE_STANDARD_HYPERPLANE]);; + +let HOMEOMORPHIC_HYPERPLANE_UNIV = prove + (`!a b. ~(a = vec 0) /\ dimindex(:N) = dimindex(:M) + 1 + ==> {x:real^N | a dot x = b} homeomorphic (:real^M)`, + REPEAT STRIP_TAC THEN TRANS_TAC HOMEOMORPHIC_TRANS + `{x:real^N | basis(dimindex(:N)) dot x = &0}` THEN + ASM_SIMP_TAC[HOMEOMORPHIC_HYPERPLANES; BASIS_NONZERO; + LE_REFL; DIMINDEX_GE_1] THEN + REWRITE_TAC[homeomorphic; HOMEOMORPHISM] THEN + EXISTS_TAC `(\x. lambda i. x$i):real^N->real^M` THEN + EXISTS_TAC `(\x. lambda i. if i <= dimindex(:M) then x$i else &0) + :real^M->real^N` THEN + REPEAT CONJ_TAC THENL + [MATCH_MP_TAC LINEAR_CONTINUOUS_ON THEN + SIMP_TAC[linear; CART_EQ; LAMBDA_BETA; VECTOR_ADD_COMPONENT; + VECTOR_MUL_COMPONENT]; + REWRITE_TAC[SUBSET_UNIV]; + MATCH_MP_TAC LINEAR_CONTINUOUS_ON THEN + SIMP_TAC[linear; CART_EQ; LAMBDA_BETA; VECTOR_ADD_COMPONENT; + VECTOR_MUL_COMPONENT] THEN + REPEAT STRIP_TAC THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN + REAL_ARITH_TAC; + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; IN_ELIM_THM; IN_UNIV] THEN + ASM_SIMP_TAC[DOT_BASIS; LAMBDA_BETA; LE_REFL; ARITH_RULE `1 <= n + 1`; + ARITH_RULE `~(m + 1 <= m)`]; + ASM_SIMP_TAC[IN_ELIM_THM; LAMBDA_BETA; DOT_BASIS; LE_REFL; CART_EQ; + ARITH_RULE `1 <= n + 1`] THEN + GEN_TAC THEN DISCH_TAC THEN X_GEN_TAC `i:num` THEN + ASM_CASES_TAC `i = dimindex(:M) + 1` THEN ASM_REWRITE_TAC[COND_ID] THEN + COND_CASES_TAC THEN REWRITE_TAC[] THEN ASM_ARITH_TAC; + ASM_SIMP_TAC[LAMBDA_BETA; CART_EQ; IN_UNIV; LE_REFL; + ARITH_RULE `i <= n ==> i <= n + 1`]]);; + +(* ------------------------------------------------------------------------- *) +(* "Isometry" (up to constant bounds) of injective linear map etc. *) +(* ------------------------------------------------------------------------- *) + +let CAUCHY_ISOMETRIC = prove + (`!f s e x. + &0 < e /\ subspace s /\ + linear f /\ (!x. x IN s ==> norm(f x) >= e * norm(x)) /\ + (!n. x(n) IN s) /\ cauchy(f o x) + ==> cauchy x`, + REPEAT GEN_TAC THEN REWRITE_TAC[real_ge] THEN + REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + REWRITE_TAC[CAUCHY; dist; o_THM] THEN + FIRST_ASSUM(fun th -> REWRITE_TAC[GSYM(MATCH_MP LINEAR_SUB th)]) THEN + DISCH_THEN(fun th -> X_GEN_TAC `d:real` THEN DISCH_TAC THEN MP_TAC th) THEN + DISCH_THEN(MP_TAC o SPEC `d * e`) THEN ASM_SIMP_TAC[REAL_LT_MUL] THEN + ASM_MESON_TAC[REAL_LE_RDIV_EQ; REAL_MUL_SYM; REAL_LET_TRANS; SUBSPACE_SUB; + REAL_LT_LDIV_EQ]);; + +let COMPLETE_ISOMETRIC_IMAGE = prove + (`!f:real^M->real^N s e. + &0 < e /\ subspace s /\ + linear f /\ (!x. x IN s ==> norm(f x) >= e * norm(x)) /\ + complete s + ==> complete(IMAGE f s)`, + REPEAT GEN_TAC THEN REWRITE_TAC[complete; EXISTS_IN_IMAGE] THEN + STRIP_TAC THEN X_GEN_TAC `g:num->real^N` THEN + REWRITE_TAC[IN_IMAGE; SKOLEM_THM; FORALL_AND_THM] THEN + DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN + DISCH_THEN(X_CHOOSE_THEN `x:num->real^M` MP_TAC) THEN + GEN_REWRITE_TAC (LAND_CONV o LAND_CONV) [GSYM FUN_EQ_THM] THEN + REWRITE_TAC[GSYM o_DEF] THEN + DISCH_THEN(CONJUNCTS_THEN2 SUBST_ALL_TAC ASSUME_TAC) THEN + FIRST_X_ASSUM(MP_TAC o SPEC `x:num->real^M`) THEN + ASM_MESON_TAC[CAUCHY_ISOMETRIC; LINEAR_CONTINUOUS_AT; + CONTINUOUS_AT_SEQUENTIALLY]);; + +let INJECTIVE_IMP_ISOMETRIC = prove + (`!f:real^M->real^N s. + closed s /\ subspace s /\ + linear f /\ (!x. x IN s /\ (f x = vec 0) ==> (x = vec 0)) + ==> ?e. &0 < e /\ !x. x IN s ==> norm(f x) >= e * norm(x)`, + REPEAT STRIP_TAC THEN + ASM_CASES_TAC `s SUBSET {vec 0 :real^M}` THENL + [EXISTS_TAC `&1` THEN REWRITE_TAC[REAL_LT_01; REAL_MUL_LID; real_ge] THEN + ASM_MESON_TAC[SUBSET; IN_SING; NORM_0; LINEAR_0; REAL_LE_REFL]; + ALL_TAC] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE RAND_CONV [SUBSET]) THEN + REWRITE_TAC[NOT_FORALL_THM; NOT_IMP; IN_SING] THEN + DISCH_THEN(X_CHOOSE_THEN `a:real^M` STRIP_ASSUME_TAC) THEN + MP_TAC(ISPECL + [`{(f:real^M->real^N) x | x IN s /\ norm(x) = norm(a:real^M)}`; + `vec 0:real^N`] DISTANCE_ATTAINS_INF) THEN + ANTS_TAC THENL + [REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; IN_ELIM_THM] THEN + CONJ_TAC THENL [ALL_TAC; ASM_MESON_TAC[]] THEN + MATCH_MP_TAC COMPACT_IMP_CLOSED THEN + SUBST1_TAC(SET_RULE + `{f x | x IN s /\ norm(x) = norm(a:real^M)} = + IMAGE (f:real^M->real^N) (s INTER {x | norm x = norm a})`) THEN + MATCH_MP_TAC COMPACT_CONTINUOUS_IMAGE THEN + ASM_SIMP_TAC[LINEAR_CONTINUOUS_ON] THEN + MATCH_MP_TAC CLOSED_INTER_COMPACT THEN ASM_REWRITE_TAC[] THEN + SUBGOAL_THEN + `{x:real^M | norm x = norm(a:real^M)} = frontier(cball(vec 0,norm a))` + SUBST1_TAC THENL + [ASM_SIMP_TAC[FRONTIER_CBALL; NORM_POS_LT; dist; VECTOR_SUB_LZERO; + NORM_NEG; sphere]; + ASM_SIMP_TAC[COMPACT_FRONTIER; COMPACT_CBALL]]; + ALL_TAC] THEN + ONCE_REWRITE_TAC[SET_RULE `{f x | P x} = IMAGE f {x | P x}`] THEN + REWRITE_TAC[FORALL_IN_IMAGE; EXISTS_IN_IMAGE] THEN + DISCH_THEN(X_CHOOSE_THEN `b:real^M` MP_TAC) THEN + REWRITE_TAC[IN_ELIM_THM; dist; VECTOR_SUB_LZERO; NORM_NEG] THEN + STRIP_TAC THEN REWRITE_TAC[CLOSED_LIMPT; LIMPT_APPROACHABLE] THEN + EXISTS_TAC `norm((f:real^M->real^N) b) / norm(b)` THEN CONJ_TAC THENL + [ASM_MESON_TAC[REAL_LT_DIV; NORM_POS_LT; NORM_EQ_0]; ALL_TAC] THEN + X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN + ASM_CASES_TAC `x:real^M = vec 0` THENL + [FIRST_ASSUM(fun th -> ASM_REWRITE_TAC[MATCH_MP LINEAR_0 th]) THEN + REWRITE_TAC[NORM_0; REAL_MUL_RZERO; real_ge; REAL_LE_REFL]; + ALL_TAC] THEN + FIRST_X_ASSUM(MP_TAC o SPEC `(norm(a:real^M) / norm(x)) % x:real^M`) THEN + ANTS_TAC THENL + [ASM_SIMP_TAC[NORM_MUL; REAL_ABS_DIV; REAL_ABS_NORM] THEN + ASM_SIMP_TAC[REAL_DIV_RMUL; NORM_EQ_0] THEN ASM_MESON_TAC[subspace]; + ALL_TAC] THEN + FIRST_ASSUM(fun th -> REWRITE_TAC[MATCH_MP LINEAR_CMUL th]) THEN + ASM_REWRITE_TAC[NORM_MUL; REAL_ABS_DIV; REAL_ABS_NORM; real_ge] THEN + ASM_SIMP_TAC[GSYM REAL_LE_RDIV_EQ; REAL_LE_LDIV_EQ; NORM_POS_LT] THEN + REWRITE_TAC[real_div; REAL_MUL_AC]);; + +let CLOSED_INJECTIVE_IMAGE_SUBSPACE = prove + (`!f s. subspace s /\ + linear f /\ + (!x. x IN s /\ f(x) = vec 0 ==> x = vec 0) /\ + closed s + ==> closed(IMAGE f s)`, + REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM COMPLETE_EQ_CLOSED] THEN + MATCH_MP_TAC COMPLETE_ISOMETRIC_IMAGE THEN + ASM_REWRITE_TAC[COMPLETE_EQ_CLOSED] THEN + MATCH_MP_TAC INJECTIVE_IMP_ISOMETRIC THEN + ASM_REWRITE_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* Relating linear images to open/closed/interior/closure. *) +(* ------------------------------------------------------------------------- *) + +let OPEN_SURJECTIVE_LINEAR_IMAGE = prove + (`!f:real^M->real^N. + linear f /\ (!y. ?x. f x = y) + ==> !s. open s ==> open(IMAGE f s)`, + GEN_TAC THEN STRIP_TAC THEN + REWRITE_TAC[open_def; FORALL_IN_IMAGE] THEN + FIRST_ASSUM(MP_TAC o GEN `k:num` o SPEC `basis k:real^N`) THEN + REWRITE_TAC[SKOLEM_THM] THEN + DISCH_THEN(X_CHOOSE_THEN `b:num->real^M` STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN `bounded(IMAGE (b:num->real^M) (1..dimindex(:N)))` MP_TAC THENL + [SIMP_TAC[FINITE_IMP_BOUNDED; FINITE_IMAGE; FINITE_NUMSEG]; ALL_TAC] THEN + REWRITE_TAC[BOUNDED_POS; FORALL_IN_IMAGE; IN_NUMSEG] THEN + DISCH_THEN(X_CHOOSE_THEN `B:real` STRIP_ASSUME_TAC) THEN + X_GEN_TAC `s:real^M->bool` THEN MATCH_MP_TAC MONO_FORALL THEN + X_GEN_TAC `x:real^M` THEN ASM_CASES_TAC `(x:real^M) IN s` THEN + ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `e:real` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `e / B / &(dimindex(:N))` THEN + ASM_SIMP_TAC[REAL_LT_DIV; REAL_OF_NUM_LT; DIMINDEX_GE_1; LE_1] THEN + X_GEN_TAC `y:real^N` THEN DISCH_TAC THEN REWRITE_TAC[IN_IMAGE] THEN + ABBREV_TAC `u = y - (f:real^M->real^N) x` THEN + EXISTS_TAC `x + vsum(1..dimindex(:N)) (\i. (u:real^N)$i % b i):real^M` THEN + ASM_SIMP_TAC[LINEAR_ADD; LINEAR_VSUM; FINITE_NUMSEG; o_DEF; + LINEAR_CMUL; BASIS_EXPANSION] THEN + CONJ_TAC THENL [EXPAND_TAC "u" THEN VECTOR_ARITH_TAC; ALL_TAC] THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN + REWRITE_TAC[NORM_ARITH `dist(x + y,x) = norm y`] THEN + MATCH_MP_TAC REAL_LET_TRANS THEN + EXISTS_TAC `(dist(y,(f:real^M->real^N) x) * &(dimindex(:N))) * B` THEN + ASM_SIMP_TAC[GSYM REAL_LT_RDIV_EQ; REAL_OF_NUM_LT; DIMINDEX_GE_1; LE_1] THEN + MATCH_MP_TAC VSUM_NORM_TRIANGLE THEN REWRITE_TAC[FINITE_NUMSEG] THEN + ONCE_REWRITE_TAC[REAL_ARITH `(a * b) * c:real = b * a * c`] THEN + GEN_REWRITE_TAC(RAND_CONV o LAND_CONV o RAND_CONV) [GSYM CARD_NUMSEG_1] THEN + MATCH_MP_TAC SUM_BOUND THEN REWRITE_TAC[FINITE_NUMSEG; IN_NUMSEG] THEN + X_GEN_TAC `k:num` THEN STRIP_TAC THEN REWRITE_TAC[NORM_MUL; dist] THEN + MATCH_MP_TAC REAL_LE_MUL2 THEN REWRITE_TAC[REAL_ABS_POS; NORM_POS_LE] THEN + ASM_SIMP_TAC[COMPONENT_LE_NORM]);; + +let OPEN_BIJECTIVE_LINEAR_IMAGE_EQ = prove + (`!f:real^M->real^N s. + linear f /\ (!x y. f x = f y ==> x = y) /\ (!y. ?x. f x = y) + ==> (open(IMAGE f s) <=> open s)`, + REPEAT STRIP_TAC THEN EQ_TAC THENL + [DISCH_TAC; ASM_MESON_TAC[OPEN_SURJECTIVE_LINEAR_IMAGE]] THEN + SUBGOAL_THEN `s = {x | (f:real^M->real^N) x IN IMAGE f s}` + SUBST1_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + MATCH_MP_TAC CONTINUOUS_OPEN_PREIMAGE_UNIV THEN + ASM_SIMP_TAC[LINEAR_CONTINUOUS_AT]);; + +add_linear_invariants [OPEN_BIJECTIVE_LINEAR_IMAGE_EQ];; + +let CLOSED_INJECTIVE_LINEAR_IMAGE = prove + (`!f:real^M->real^N. + linear f /\ (!x y. f x = f y ==> x = y) + ==> !s. closed s ==> closed(IMAGE f s)`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPEC `f:real^M->real^N` LINEAR_INJECTIVE_LEFT_INVERSE) THEN + ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `g:real^N->real^M` STRIP_ASSUME_TAC) THEN + MATCH_MP_TAC CLOSED_IN_CLOSED_TRANS THEN + EXISTS_TAC `IMAGE (f:real^M->real^N) (:real^M)` THEN + CONJ_TAC THENL + [MP_TAC(ISPECL [`g:real^N->real^M`; `IMAGE (f:real^M->real^N) (:real^M)`; + `IMAGE (g:real^N->real^M) (IMAGE (f:real^M->real^N) s)`] + CONTINUOUS_CLOSED_IN_PREIMAGE) THEN + ASM_SIMP_TAC[LINEAR_CONTINUOUS_ON] THEN ANTS_TAC THENL + [ASM_REWRITE_TAC[GSYM IMAGE_o; IMAGE_I]; ALL_TAC] THEN + MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [FUN_EQ_THM]) THEN + REWRITE_TAC[EXTENSION; o_THM; I_THM] THEN SET_TAC[]; + MATCH_MP_TAC CLOSED_INJECTIVE_IMAGE_SUBSPACE THEN + ASM_REWRITE_TAC[IN_UNIV; SUBSPACE_UNIV; CLOSED_UNIV] THEN + X_GEN_TAC `x:real^M` THEN + DISCH_THEN(MP_TAC o AP_TERM `g:real^N->real^M`) THEN + RULE_ASSUM_TAC(REWRITE_RULE[FUN_EQ_THM; I_THM; o_THM]) THEN + ASM_MESON_TAC[LINEAR_0]]);; + +let CLOSED_INJECTIVE_LINEAR_IMAGE_EQ = prove + (`!f:real^M->real^N s. + linear f /\ (!x y. f x = f y ==> x = y) + ==> (closed(IMAGE f s) <=> closed s)`, + REPEAT STRIP_TAC THEN EQ_TAC THENL + [DISCH_TAC; ASM_MESON_TAC[CLOSED_INJECTIVE_LINEAR_IMAGE]] THEN + SUBGOAL_THEN `s = {x | (f:real^M->real^N) x IN IMAGE f s}` + SUBST1_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + MATCH_MP_TAC CONTINUOUS_CLOSED_PREIMAGE_UNIV THEN + ASM_SIMP_TAC[LINEAR_CONTINUOUS_AT]);; + +add_linear_invariants [CLOSED_INJECTIVE_LINEAR_IMAGE_EQ];; + +let CLOSURE_LINEAR_IMAGE_SUBSET = prove + (`!f:real^M->real^N s. + linear f ==> IMAGE f (closure s) SUBSET closure(IMAGE f s)`, + REPEAT STRIP_TAC THEN + MATCH_MP_TAC IMAGE_CLOSURE_SUBSET THEN + ASM_SIMP_TAC[CLOSED_CLOSURE; CLOSURE_SUBSET; LINEAR_CONTINUOUS_ON]);; + +let CLOSURE_INJECTIVE_LINEAR_IMAGE = prove + (`!f:real^M->real^N s. + linear f /\ (!x y. f x = f y ==> x = y) + ==> closure(IMAGE f s) = IMAGE f (closure s)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN + ASM_SIMP_TAC[CLOSURE_LINEAR_IMAGE_SUBSET] THEN + MATCH_MP_TAC CLOSURE_MINIMAL THEN + SIMP_TAC[CLOSURE_SUBSET; IMAGE_SUBSET] THEN + ASM_MESON_TAC[CLOSED_INJECTIVE_LINEAR_IMAGE; CLOSED_CLOSURE]);; + +add_linear_invariants [CLOSURE_INJECTIVE_LINEAR_IMAGE];; + +let CLOSURE_BOUNDED_LINEAR_IMAGE = prove + (`!f:real^M->real^N s. + linear f /\ bounded s + ==> closure(IMAGE f s) = IMAGE f (closure s)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN + ASM_SIMP_TAC[CLOSURE_LINEAR_IMAGE_SUBSET] THEN + MATCH_MP_TAC CLOSURE_MINIMAL THEN + SIMP_TAC[CLOSURE_SUBSET; IMAGE_SUBSET] THEN + MATCH_MP_TAC COMPACT_IMP_CLOSED THEN + MATCH_MP_TAC COMPACT_LINEAR_IMAGE THEN + ASM_REWRITE_TAC[COMPACT_CLOSURE]);; + +let LINEAR_INTERIOR_IMAGE_SUBSET = prove + (`!f:real^M->real^N s. + linear f /\ (!x y. f x = f y ==> x = y) + ==> interior(IMAGE f s) SUBSET IMAGE f (interior s)`, + MESON_TAC[INTERIOR_IMAGE_SUBSET; LINEAR_CONTINUOUS_AT]);; + +let LINEAR_IMAGE_SUBSET_INTERIOR = prove + (`!f:real^M->real^N s. + linear f /\ (!y. ?x. f x = y) + ==> IMAGE f (interior s) SUBSET interior(IMAGE f s)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC INTERIOR_MAXIMAL THEN + ASM_SIMP_TAC[OPEN_SURJECTIVE_LINEAR_IMAGE; OPEN_INTERIOR; + IMAGE_SUBSET; INTERIOR_SUBSET]);; + +let INTERIOR_BIJECTIVE_LINEAR_IMAGE = prove + (`!f:real^M->real^N s. + linear f /\ (!x y. f x = f y ==> x = y) /\ (!y. ?x. f x = y) + ==> interior(IMAGE f s) = IMAGE f (interior s)`, + REWRITE_TAC[interior] THEN GEOM_TRANSFORM_TAC[]);; + +add_linear_invariants [INTERIOR_BIJECTIVE_LINEAR_IMAGE];; + +let FRONTIER_BIJECTIVE_LINEAR_IMAGE = prove + (`!f:real^M->real^N s. + linear f /\ (!x y. f x = f y ==> x = y) /\ (!y. ?x. f x = y) + ==> frontier(IMAGE f s) = IMAGE f (frontier s)`, + REWRITE_TAC[frontier] THEN GEOM_TRANSFORM_TAC[]);; + +add_linear_invariants [FRONTIER_BIJECTIVE_LINEAR_IMAGE];; + +(* ------------------------------------------------------------------------- *) +(* Corollaries, reformulations and special cases for M = N. *) +(* ------------------------------------------------------------------------- *) + +let IN_INTERIOR_LINEAR_IMAGE = prove + (`!f:real^M->real^N g s x. + linear f /\ linear g /\ (f o g = I) /\ x IN interior s + ==> (f x) IN interior (IMAGE f s)`, + REWRITE_TAC[FUN_EQ_THM; o_THM; I_THM] THEN REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`f:real^M->real^N`; `s:real^M->bool`] + LINEAR_IMAGE_SUBSET_INTERIOR) THEN + ASM_REWRITE_TAC[SUBSET; FORALL_IN_IMAGE] THEN + ASM_MESON_TAC[]);; + +let LINEAR_OPEN_MAPPING = prove + (`!f:real^M->real^N g. + linear f /\ linear g /\ (f o g = I) + ==> !s. open s ==> open(IMAGE f s)`, + REPEAT GEN_TAC THEN REWRITE_TAC[FUN_EQ_THM; o_THM; I_THM] THEN DISCH_TAC THEN + MATCH_MP_TAC OPEN_SURJECTIVE_LINEAR_IMAGE THEN + ASM_MESON_TAC[]);; + +let INTERIOR_INJECTIVE_LINEAR_IMAGE = prove + (`!f:real^N->real^N s. + linear f /\ (!x y. f x = f y ==> x = y) + ==> interior(IMAGE f s) = IMAGE f (interior s)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC INTERIOR_BIJECTIVE_LINEAR_IMAGE THEN + ASM_MESON_TAC[LINEAR_INJECTIVE_IMP_SURJECTIVE]);; + +let INTERIOR_SURJECTIVE_LINEAR_IMAGE = prove + (`!f:real^N->real^N s. + linear f /\ (!y. ?x. f x = y) + ==> interior(IMAGE f s) = IMAGE f (interior s)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC INTERIOR_BIJECTIVE_LINEAR_IMAGE THEN + ASM_MESON_TAC[LINEAR_SURJECTIVE_IMP_INJECTIVE]);; + +let CLOSURE_SURJECTIVE_LINEAR_IMAGE = prove + (`!f:real^N->real^N s. + linear f /\ (!y. ?x. f x = y) + ==> closure(IMAGE f s) = IMAGE f (closure s)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC CLOSURE_INJECTIVE_LINEAR_IMAGE THEN + ASM_MESON_TAC[LINEAR_SURJECTIVE_IMP_INJECTIVE]);; + +let FRONTIER_INJECTIVE_LINEAR_IMAGE = prove + (`!f:real^N->real^N s. + linear f /\ (!x y. f x = f y ==> x = y) + ==> frontier(IMAGE f s) = IMAGE f (frontier s)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC FRONTIER_BIJECTIVE_LINEAR_IMAGE THEN + ASM_MESON_TAC[LINEAR_INJECTIVE_IMP_SURJECTIVE]);; + +let FRONTIER_SURJECTIVE_LINEAR_IMAGE = prove + (`!f:real^N->real^N. + linear f /\ (!y. ?x. f x = y) + ==> frontier(IMAGE f s) = IMAGE f (frontier s)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC FRONTIER_BIJECTIVE_LINEAR_IMAGE THEN + ASM_MESON_TAC[LINEAR_SURJECTIVE_IMP_INJECTIVE]);; + +let COMPLETE_INJECTIVE_LINEAR_IMAGE = prove + (`!f:real^M->real^N. + linear f /\ (!x y. f x = f y ==> x = y) + ==> !s. complete s ==> complete(IMAGE f s)`, + REWRITE_TAC[COMPLETE_EQ_CLOSED; CLOSED_INJECTIVE_LINEAR_IMAGE]);; + +let COMPLETE_INJECTIVE_LINEAR_IMAGE_EQ = prove + (`!f:real^M->real^N s. + linear f /\ (!x y. f x = f y ==> x = y) + ==> (complete(IMAGE f s) <=> complete s)`, + REWRITE_TAC[COMPLETE_EQ_CLOSED; CLOSED_INJECTIVE_LINEAR_IMAGE_EQ]);; + +add_linear_invariants [COMPLETE_INJECTIVE_LINEAR_IMAGE_EQ];; + +let LIMPT_INJECTIVE_LINEAR_IMAGE_EQ = prove + (`!f:real^M->real^N s. + linear f /\ (!x y. f x = f y ==> x = y) + ==> ((f x) limit_point_of (IMAGE f s) <=> x limit_point_of s)`, + REWRITE_TAC[LIMPT_APPROACHABLE; EXISTS_IN_IMAGE] THEN + REPEAT STRIP_TAC THEN EQ_TAC THEN DISCH_TAC THEN X_GEN_TAC `e:real` THEN + DISCH_TAC THENL + [MP_TAC(ISPEC `f:real^M->real^N` LINEAR_INJECTIVE_BOUNDED_BELOW_POS); + MP_TAC(ISPEC `f:real^M->real^N` LINEAR_BOUNDED_POS)] THEN + ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `B:real` STRIP_ASSUME_TAC) THENL + [FIRST_X_ASSUM(MP_TAC o SPEC `e * B:real`); + FIRST_X_ASSUM(MP_TAC o SPEC `e / B:real`)] THEN + ASM_SIMP_TAC[REAL_LT_DIV; REAL_LT_MUL; dist; GSYM LINEAR_SUB] THEN + MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC THEN + REPEAT(MATCH_MP_TAC MONO_AND THEN + CONJ_TAC THENL [ASM_MESON_TAC[]; ALL_TAC]) THEN + ASM_SIMP_TAC[GSYM REAL_LT_LDIV_EQ; REAL_LT_RDIV_EQ] THEN + MATCH_MP_TAC(REAL_ARITH `a <= b ==> b < x ==> a < x`) THEN + ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN ASM_SIMP_TAC[REAL_LE_RDIV_EQ]);; + +add_linear_invariants [LIMPT_INJECTIVE_LINEAR_IMAGE_EQ];; + +let LIMPT_TRANSLATION_EQ = prove + (`!a s x. (a + x) limit_point_of (IMAGE (\y. a + y) s) <=> x limit_point_of s`, + REWRITE_TAC[limit_point_of] THEN GEOM_TRANSLATE_TAC[]);; + +add_translation_invariants [LIMPT_TRANSLATION_EQ];; + +let OPEN_OPEN_LEFT_PROJECTION = prove + (`!s t:real^(M,N)finite_sum->bool. + open s /\ open t ==> open {x | x IN s /\ ?y. pastecart x y IN t}`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN + `{x | x IN s /\ ?y. (pastecart x y:real^(M,N)finite_sum) IN t} = + s INTER IMAGE fstcart t` + SUBST1_TAC THENL + [REWRITE_TAC[EXTENSION; IN_ELIM_THM; IN_INTER; IN_IMAGE] THEN + MESON_TAC[FSTCART_PASTECART; PASTECART_FST_SND]; + MATCH_MP_TAC OPEN_INTER THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_IMP; RIGHT_IMP_FORALL_THM] + OPEN_SURJECTIVE_LINEAR_IMAGE) THEN + ASM_REWRITE_TAC[LINEAR_FSTCART] THEN MESON_TAC[FSTCART_PASTECART]]);; + +let OPEN_OPEN_RIGHT_PROJECTION = prove + (`!s t:real^(M,N)finite_sum->bool. + open s /\ open t ==> open {y | y IN s /\ ?x. pastecart x y IN t}`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN + `{y | y IN s /\ ?x. (pastecart x y:real^(M,N)finite_sum) IN t} = + s INTER IMAGE sndcart t` + SUBST1_TAC THENL + [REWRITE_TAC[EXTENSION; IN_ELIM_THM; IN_INTER; IN_IMAGE] THEN + MESON_TAC[SNDCART_PASTECART; PASTECART_FST_SND]; + MATCH_MP_TAC OPEN_INTER THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_IMP; RIGHT_IMP_FORALL_THM] + OPEN_SURJECTIVE_LINEAR_IMAGE) THEN + ASM_REWRITE_TAC[LINEAR_SNDCART] THEN MESON_TAC[SNDCART_PASTECART]]);; + +(* ------------------------------------------------------------------------- *) +(* Even more special cases. *) +(* ------------------------------------------------------------------------- *) + +let INTERIOR_NEGATIONS = prove + (`!s. interior(IMAGE (--) s) = IMAGE (--) (interior s)`, + GEN_TAC THEN MATCH_MP_TAC INTERIOR_INJECTIVE_LINEAR_IMAGE THEN + REWRITE_TAC[linear] THEN REPEAT CONJ_TAC THEN VECTOR_ARITH_TAC);; + +let SYMMETRIC_INTERIOR = prove + (`!s:real^N->bool. + (!x. x IN s ==> --x IN s) + ==> !x. x IN interior s ==> (--x) IN interior s`, + REPEAT GEN_TAC THEN DISCH_TAC THEN GEN_TAC THEN + DISCH_THEN(MP_TAC o MATCH_MP(ISPEC `(--):real^N->real^N` FUN_IN_IMAGE)) THEN + REWRITE_TAC[GSYM INTERIOR_NEGATIONS] THEN + MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN AP_TERM_TAC THEN + REWRITE_TAC[EXTENSION; IN_IMAGE] THEN ASM_MESON_TAC[VECTOR_NEG_NEG]);; + +let CLOSURE_NEGATIONS = prove + (`!s. closure(IMAGE (--) s) = IMAGE (--) (closure s)`, + GEN_TAC THEN MATCH_MP_TAC CLOSURE_INJECTIVE_LINEAR_IMAGE THEN + REWRITE_TAC[linear] THEN REPEAT CONJ_TAC THEN VECTOR_ARITH_TAC);; + +let SYMMETRIC_CLOSURE = prove + (`!s:real^N->bool. + (!x. x IN s ==> --x IN s) + ==> !x. x IN closure s ==> (--x) IN closure s`, + REPEAT GEN_TAC THEN DISCH_TAC THEN GEN_TAC THEN + DISCH_THEN(MP_TAC o MATCH_MP(ISPEC `(--):real^N->real^N` FUN_IN_IMAGE)) THEN + REWRITE_TAC[GSYM CLOSURE_NEGATIONS] THEN + MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN AP_TERM_TAC THEN + REWRITE_TAC[EXTENSION; IN_IMAGE] THEN ASM_MESON_TAC[VECTOR_NEG_NEG]);; + +(* ------------------------------------------------------------------------- *) +(* Some properties of a canonical subspace. *) +(* ------------------------------------------------------------------------- *) + +let SUBSPACE_SUBSTANDARD = prove + (`!d. subspace + {x:real^N | !i. d < i /\ i <= dimindex(:N) ==> x$i = &0}`, + GEN_TAC THEN ASM_CASES_TAC `d <= dimindex(:N)` THENL + [MP_TAC(ARITH_RULE `!i. d < i ==> 1 <= i`) THEN + SIMP_TAC[subspace; IN_ELIM_THM; REAL_MUL_RZERO; REAL_ADD_LID; + VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT; VEC_COMPONENT]; + ASM_SIMP_TAC[ARITH_RULE `~(d:num <= e) ==> (d < i /\ i <= e <=> F)`] THEN + REWRITE_TAC[SET_RULE `{x | T} = UNIV`; SUBSPACE_UNIV]]);; + +let CLOSED_SUBSTANDARD = prove + (`!d. closed + {x:real^N | !i. d < i /\ i <= dimindex(:N) ==> x$i = &0}`, + GEN_TAC THEN + SUBGOAL_THEN + `{x:real^N | !i. d < i /\ i <= dimindex(:N) ==> x$i = &0} = + INTERS {{x | basis i dot x = &0} | d < i /\ i <= dimindex(:N)}` + SUBST1_TAC THENL + [ALL_TAC; + SIMP_TAC[CLOSED_INTERS; CLOSED_HYPERPLANE; IN_ELIM_THM; + LEFT_IMP_EXISTS_THM]] THEN + GEN_REWRITE_TAC I [EXTENSION] THEN REWRITE_TAC[IN_INTERS; IN_ELIM_THM] THEN + SIMP_TAC[LEFT_IMP_EXISTS_THM; IN_ELIM_THM] THEN + MP_TAC(ARITH_RULE `!i. d < i ==> 1 <= i`) THEN + SIMP_TAC[DOT_BASIS] THEN MESON_TAC[]);; + +let DIM_SUBSTANDARD = prove + (`!d. d <= dimindex(:N) + ==> (dim {x:real^N | !i. d < i /\ i <= dimindex(:N) + ==> x$i = &0} = + d)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC DIM_UNIQUE THEN + EXISTS_TAC `IMAGE (basis:num->real^N) (1..d)` THEN REPEAT CONJ_TAC THENL + [REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; IN_ELIM_THM; IN_NUMSEG] THEN + MESON_TAC[BASIS_COMPONENT; ARITH_RULE `d < i ==> 1 <= i`; NOT_LT]; + ALL_TAC; + MATCH_MP_TAC INDEPENDENT_MONO THEN + EXISTS_TAC `{basis i :real^N | 1 <= i /\ i <= dimindex(:N)}` THEN + REWRITE_TAC[INDEPENDENT_STDBASIS]THEN + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; IN_ELIM_THM; IN_NUMSEG] THEN + ASM_MESON_TAC[LE_TRANS]; + MATCH_MP_TAC HAS_SIZE_IMAGE_INJ THEN REWRITE_TAC[HAS_SIZE_NUMSEG_1] THEN + REWRITE_TAC[IN_NUMSEG] THEN ASM_MESON_TAC[LE_TRANS; BASIS_INJ]] THEN + POP_ASSUM MP_TAC THEN SPEC_TAC(`d:num`,`d:num`) THEN + INDUCT_TAC THENL + [REWRITE_TAC[ARITH_RULE `0 < i <=> 1 <= i`; SPAN_STDBASIS] THEN + SUBGOAL_THEN `IMAGE basis (1 .. 0) :real^N->bool = {}` SUBST1_TAC THENL + [REWRITE_TAC[IMAGE_EQ_EMPTY; NUMSEG_EMPTY; ARITH]; ALL_TAC] THEN + DISCH_TAC THEN REWRITE_TAC[SPAN_EMPTY; SUBSET; IN_ELIM_THM; IN_SING] THEN + SIMP_TAC[CART_EQ; VEC_COMPONENT]; + ALL_TAC] THEN + DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o check (is_imp o concl)) THEN + ASM_SIMP_TAC[ARITH_RULE `SUC d <= n ==> d <= n`] THEN + REWRITE_TAC[SUBSET; IN_ELIM_THM] THEN DISCH_TAC THEN + X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `x - (x$(SUC d)) % basis(SUC d) :real^N`) THEN + ANTS_TAC THENL + [X_GEN_TAC `i:num` THEN STRIP_TAC THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP(ARITH_RULE `d < i ==> 1 <= i`)) THEN + ASM_SIMP_TAC[VECTOR_SUB_COMPONENT; VECTOR_MUL_COMPONENT] THEN + ASM_SIMP_TAC[BASIS_COMPONENT] THEN COND_CASES_TAC THEN + ASM_REWRITE_TAC[REAL_MUL_RID; REAL_SUB_REFL] THEN + ASM_REWRITE_TAC[REAL_MUL_RZERO; REAL_SUB_RZERO] THEN + ASM_MESON_TAC[ARITH_RULE `d < i /\ ~(i = SUC d) ==> SUC d < i`]; + ALL_TAC] THEN + DISCH_TAC THEN + SUBST1_TAC(VECTOR_ARITH + `x = (x - (x$(SUC d)) % basis(SUC d)) + + x$(SUC d) % basis(SUC d) :real^N`) THEN + MATCH_MP_TAC SPAN_ADD THEN CONJ_TAC THENL + [ASM_MESON_TAC[SPAN_MONO; SUBSET_IMAGE; SUBSET; SUBSET_NUMSEG; LE_REFL; LE]; + MATCH_MP_TAC SPAN_MUL THEN MATCH_MP_TAC SPAN_SUPERSET THEN + REWRITE_TAC[IN_IMAGE; IN_NUMSEG] THEN + MESON_TAC[LE_REFL; ARITH_RULE `1 <= SUC d`]]);; + +(* ------------------------------------------------------------------------- *) +(* Hence closure and completeness of all subspaces. *) +(* ------------------------------------------------------------------------- *) + +let CLOSED_SUBSPACE = prove + (`!s:real^N->bool. subspace s ==> closed s`, + REPEAT STRIP_TAC THEN ABBREV_TAC `d = dim(s:real^N->bool)` THEN + MP_TAC(MATCH_MP DIM_SUBSTANDARD + (ISPEC `s:real^N->bool` DIM_SUBSET_UNIV)) THEN + ASM_REWRITE_TAC[] THEN DISCH_TAC THEN + MP_TAC(ISPECL + [`{x:real^N | !i. d < i /\ i <= dimindex(:N) + ==> x$i = &0}`; + `s:real^N->bool`] SUBSPACE_ISOMORPHISM) THEN + ASM_REWRITE_TAC[SUBSPACE_SUBSTANDARD] THEN + DISCH_THEN(X_CHOOSE_THEN `f:real^N->real^N` MP_TAC) THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + DISCH_THEN(CONJUNCTS_THEN2 (SUBST_ALL_TAC o SYM) STRIP_ASSUME_TAC) THEN + MATCH_MP_TAC(ISPEC `f:real^N->real^N` CLOSED_INJECTIVE_IMAGE_SUBSPACE) THEN + ASM_REWRITE_TAC[SUBSPACE_SUBSTANDARD; CLOSED_SUBSTANDARD] THEN + X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_REWRITE_TAC[] THEN + CONJ_TAC THENL [ALL_TAC; ASM_MESON_TAC[LINEAR_0]] THEN + REWRITE_TAC[IN_ELIM_THM] THEN + ASM_MESON_TAC[VEC_COMPONENT; ARITH_RULE `d < i ==> 1 <= i`]);; + +let COMPLETE_SUBSPACE = prove + (`!s:real^N->bool. subspace s ==> complete s`, + REWRITE_TAC[COMPLETE_EQ_CLOSED; CLOSED_SUBSPACE]);; + +let CLOSED_SPAN = prove + (`!s. closed(span s)`, + SIMP_TAC[CLOSED_SUBSPACE; SUBSPACE_SPAN]);; + +let DIM_CLOSURE = prove + (`!s:real^N->bool. dim(closure s) = dim s`, + GEN_TAC THEN REWRITE_TAC[GSYM LE_ANTISYM] THEN CONJ_TAC THENL + [GEN_REWRITE_TAC RAND_CONV [GSYM DIM_SPAN]; ALL_TAC] THEN + MATCH_MP_TAC DIM_SUBSET THEN REWRITE_TAC[CLOSURE_SUBSET] THEN + MATCH_MP_TAC CLOSURE_MINIMAL THEN + SIMP_TAC[CLOSED_SUBSPACE; SUBSPACE_SPAN; SPAN_INC]);; + +let CLOSED_BOUNDEDPREIM_CONTINUOUS_IMAGE = prove + (`!f:real^M->real^N s. + closed s /\ f continuous_on s /\ + (!e. bounded {x | x IN s /\ norm(f x) <= e}) + ==> closed(IMAGE f s)`, + REPEAT STRIP_TAC THEN REWRITE_TAC[CLOSED_INTERS_COMPACT] THEN + REWRITE_TAC[SET_RULE + `cball(vec 0,e) INTER IMAGE (f:real^M->real^N) s = + IMAGE f (s INTER {x | x IN s /\ f x IN cball(vec 0,e)})`] THEN + X_GEN_TAC `e:real` THEN MATCH_MP_TAC COMPACT_CONTINUOUS_IMAGE THEN + CONJ_TAC THENL + [MATCH_MP_TAC CONTINUOUS_ON_SUBSET THEN EXISTS_TAC `s:real^M->bool` THEN + ASM_REWRITE_TAC[] THEN SET_TAC[]; + MATCH_MP_TAC CLOSED_INTER_COMPACT THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[COMPACT_EQ_BOUNDED_CLOSED] THEN CONJ_TAC THENL + [ASM_REWRITE_TAC[IN_CBALL_0]; + ASM_SIMP_TAC[CONTINUOUS_CLOSED_PREIMAGE; CLOSED_CBALL]]]);; + +let CLOSED_INJECTIVE_IMAGE_SUBSET_SUBSPACE = prove + (`!f:real^M->real^N s t. + closed s /\ s SUBSET t /\ subspace t /\ + linear f /\ + (!x. x IN t /\ f(x) = vec 0 ==> x = vec 0) + ==> closed(IMAGE f s)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC CLOSED_BOUNDEDPREIM_CONTINUOUS_IMAGE THEN + ASM_SIMP_TAC[LINEAR_CONTINUOUS_ON] THEN + MP_TAC(ISPECL [`f:real^M->real^N`; `t:real^M->bool`] + INJECTIVE_IMP_ISOMETRIC) THEN + ASM_SIMP_TAC[CLOSED_SUBSPACE; real_ge] THEN + ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN + DISCH_THEN(X_CHOOSE_THEN `B:real` STRIP_ASSUME_TAC) THEN + X_GEN_TAC `e:real` THEN MATCH_MP_TAC BOUNDED_SUBSET THEN + EXISTS_TAC `cball(vec 0:real^M,e / B)` THEN + REWRITE_TAC[BOUNDED_CBALL] THEN + ASM_SIMP_TAC[SUBSET; IN_ELIM_THM; IN_CBALL_0; REAL_LE_RDIV_EQ] THEN + ASM_MESON_TAC[SUBSET; REAL_LE_TRANS]);; + +let BASIS_COORDINATES_LIPSCHITZ = prove + (`!b:real^N->bool. + independent b + ==> ?B. &0 < B /\ + !c v. v IN b + ==> abs(c v) <= B * norm(vsum b (\v. c(v) % v))`, + X_GEN_TAC `k:real^N->bool` THEN DISCH_TAC THEN + FIRST_ASSUM(STRIP_ASSUME_TAC o MATCH_MP INDEPENDENT_BOUND) THEN + FIRST_ASSUM(X_CHOOSE_THEN `b:num->real^N` STRIP_ASSUME_TAC o + GEN_REWRITE_RULE I [FINITE_INDEX_NUMSEG]) THEN + ABBREV_TAC `n = CARD(k:real^N->bool)` THEN + MP_TAC(ISPECL + [`(\x. vsum(1..n) (\i. x$i % b i)):real^N->real^N`; + `span(IMAGE basis (1..n)):real^N->bool`] + INJECTIVE_IMP_ISOMETRIC) THEN + REWRITE_TAC[SUBSPACE_SPAN] THEN ANTS_TAC THENL + [CONJ_TAC THENL [SIMP_TAC[CLOSED_SUBSPACE; SUBSPACE_SPAN]; ALL_TAC] THEN + CONJ_TAC THENL + [MATCH_MP_TAC LINEAR_COMPOSE_VSUM THEN + REWRITE_TAC[FINITE_NUMSEG; IN_NUMSEG] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC LINEAR_VMUL_COMPONENT THEN + SIMP_TAC[LINEAR_ID] THEN ASM_ARITH_TAC; + ALL_TAC] THEN + X_GEN_TAC `x:real^N` THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_SPAN_IMAGE_BASIS]) THEN + REWRITE_TAC[IN_NUMSEG] THEN DISCH_TAC THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [INJECTIVE_ON_LEFT_INVERSE]) THEN + DISCH_THEN(X_CHOOSE_TAC `c:real^N->num`) THEN + SUBGOAL_THEN + `vsum(1..n) (\i. (x:real^N)$i % b i:real^N) = vsum k (\v. x$(c v) % v)` + SUBST1_TAC THENL + [MATCH_MP_TAC VSUM_EQ_GENERAL_INVERSES THEN + MAP_EVERY EXISTS_TAC [`b:num->real^N`; `c:real^N->num`] THEN + ASM SET_TAC[]; + ALL_TAC] THEN + DISCH_TAC THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [INDEPENDENT_EXPLICIT]) THEN + DISCH_THEN(MP_TAC o SPEC `\v:real^N. (x:real^N)$(c v)` o CONJUNCT2) THEN + ASM_REWRITE_TAC[] THEN ANTS_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN + REWRITE_TAC[CART_EQ; FORALL_IN_IMAGE; VEC_COMPONENT] THEN + ASM_MESON_TAC[IN_NUMSEG]; + ALL_TAC] THEN + DISCH_THEN(X_CHOOSE_THEN `B:real` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `inv(B:real)` THEN ASM_REWRITE_TAC[REAL_LT_INV_EQ] THEN + ASM_REWRITE_TAC[FORALL_IN_IMAGE; IN_NUMSEG] THEN + MAP_EVERY X_GEN_TAC [`c:real^N->real`; `j:num`] THEN STRIP_TAC THEN + ONCE_REWRITE_TAC[REAL_ARITH `inv B * x = x / B`] THEN + ASM_SIMP_TAC[REAL_LE_RDIV_EQ] THEN + W(MP_TAC o PART_MATCH (lhs o rand) VSUM_IMAGE o rand o rand o snd) THEN + ASM_REWRITE_TAC[FINITE_NUMSEG] THEN DISCH_THEN SUBST1_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC + `(lambda i. if 1 <= i /\ i <= n then c(b i:real^N) else &0):real^N`) THEN + SIMP_TAC[IN_SPAN_IMAGE_BASIS; LAMBDA_BETA] THEN + ANTS_TAC THENL [MESON_TAC[IN_NUMSEG]; ALL_TAC] THEN + MATCH_MP_TAC(REAL_ARITH `x = v /\ u <= y ==> x >= y ==> u <= v`) THEN + CONJ_TAC THENL + [AP_TERM_TAC THEN MATCH_MP_TAC VSUM_EQ_NUMSEG THEN + SUBGOAL_THEN `!i. i <= n ==> i <= dimindex(:N)` MP_TAC THENL + [ASM_ARITH_TAC; SIMP_TAC[LAMBDA_BETA] THEN DISCH_THEN(K ALL_TAC)] THEN + REWRITE_TAC[o_THM]; + GEN_REWRITE_TAC RAND_CONV [REAL_MUL_SYM] THEN + ASM_SIMP_TAC[REAL_LE_RMUL_EQ] THEN + MP_TAC(ISPECL + [`(lambda i. if 1 <= i /\ i <= n then c(b i:real^N) else &0):real^N`; + `j:num`] COMPONENT_LE_NORM) THEN + SIMP_TAC[LAMBDA_BETA] THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN MATCH_MP_TAC THEN ASM_ARITH_TAC]);; + +let BASIS_COORDINATES_CONTINUOUS = prove + (`!b:real^N->bool e. + independent b /\ &0 < e + ==> ?d. &0 < d /\ + !c. norm(vsum b (\v. c(v) % v)) < d + ==> !v. v IN b ==> abs(c v) < e`, + REPEAT STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o MATCH_MP BASIS_COORDINATES_LIPSCHITZ) THEN + DISCH_THEN(X_CHOOSE_THEN `B:real` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `e / B:real` THEN ASM_SIMP_TAC[REAL_LT_DIV] THEN + X_GEN_TAC `c:real^N->real` THEN DISCH_TAC THEN + X_GEN_TAC `v:real^N` THEN DISCH_TAC THEN + MATCH_MP_TAC REAL_LET_TRANS THEN + EXISTS_TAC `B * norm(vsum b (\v:real^N. c v % v))` THEN + ASM_SIMP_TAC[] THEN ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN + ASM_SIMP_TAC[GSYM REAL_LT_RDIV_EQ]);; + +(* ------------------------------------------------------------------------- *) +(* Affine transformations of intervals. *) +(* ------------------------------------------------------------------------- *) + +let AFFINITY_INVERSES = prove + (`!m c. ~(m = &0) + ==> (\x. m % x + c) o (\x. inv(m) % x + (--(inv(m) % c))) = I /\ + (\x. inv(m) % x + (--(inv(m) % c))) o (\x. m % x + c) = I`, + REWRITE_TAC[FUN_EQ_THM; o_THM; I_THM] THEN + REWRITE_TAC[VECTOR_ADD_LDISTRIB; VECTOR_MUL_RNEG] THEN + SIMP_TAC[VECTOR_MUL_ASSOC; REAL_MUL_LINV; REAL_MUL_RINV] THEN + REPEAT STRIP_TAC THEN VECTOR_ARITH_TAC);; + +let REAL_AFFINITY_LE = prove + (`!m c x y. &0 < m ==> (m * x + c <= y <=> x <= inv(m) * y + --(c / m))`, + REWRITE_TAC[REAL_ARITH `m * x + c <= y <=> x * m <= y - c`] THEN + SIMP_TAC[GSYM REAL_LE_RDIV_EQ] THEN REAL_ARITH_TAC);; + +let REAL_LE_AFFINITY = prove + (`!m c x y. &0 < m ==> (y <= m * x + c <=> inv(m) * y + --(c / m) <= x)`, + REWRITE_TAC[REAL_ARITH `y <= m * x + c <=> y - c <= x * m`] THEN + SIMP_TAC[GSYM REAL_LE_LDIV_EQ] THEN REAL_ARITH_TAC);; + +let REAL_AFFINITY_LT = prove + (`!m c x y. &0 < m ==> (m * x + c < y <=> x < inv(m) * y + --(c / m))`, + SIMP_TAC[REAL_LE_AFFINITY; GSYM REAL_NOT_LE]);; + +let REAL_LT_AFFINITY = prove + (`!m c x y. &0 < m ==> (y < m * x + c <=> inv(m) * y + --(c / m) < x)`, + SIMP_TAC[REAL_AFFINITY_LE; GSYM REAL_NOT_LE]);; + +let REAL_AFFINITY_EQ = prove + (`!m c x y. ~(m = &0) ==> (m * x + c = y <=> x = inv(m) * y + --(c / m))`, + CONV_TAC REAL_FIELD);; + +let REAL_EQ_AFFINITY = prove + (`!m c x y. ~(m = &0) ==> (y = m * x + c <=> inv(m) * y + --(c / m) = x)`, + CONV_TAC REAL_FIELD);; + +let VECTOR_AFFINITY_EQ = prove + (`!m c x y. ~(m = &0) + ==> (m % x + c = y <=> x = inv(m) % y + --(inv(m) % c))`, + SIMP_TAC[CART_EQ; VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT; + real_div; VECTOR_NEG_COMPONENT; REAL_AFFINITY_EQ] THEN + REWRITE_TAC[REAL_MUL_AC]);; + +let VECTOR_EQ_AFFINITY = prove + (`!m c x y. ~(m = &0) + ==> (y = m % x + c <=> inv(m) % y + --(inv(m) % c) = x)`, + SIMP_TAC[CART_EQ; VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT; + real_div; VECTOR_NEG_COMPONENT; REAL_EQ_AFFINITY] THEN + REWRITE_TAC[REAL_MUL_AC]);; + +let IMAGE_AFFINITY_INTERVAL = prove + (`!a b:real^N m c. + IMAGE (\x. m % x + c) (interval[a,b]) = + if interval[a,b] = {} then {} + else if &0 <= m then interval[m % a + c,m % b + c] + else interval[m % b + c,m % a + c]`, + REPEAT GEN_TAC THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[IMAGE_CLAUSES] THEN + ASM_CASES_TAC `m = &0` THEN ASM_REWRITE_TAC[REAL_LE_LT] THENL + [ASM_REWRITE_TAC[VECTOR_MUL_LZERO; VECTOR_ADD_LID; COND_ID] THEN + REWRITE_TAC[INTERVAL_SING] THEN ASM SET_TAC[]; + ALL_TAC] THEN + FIRST_ASSUM(DISJ_CASES_TAC o MATCH_MP (REAL_ARITH + `~(x = &0) ==> &0 < x \/ &0 < --x`)) THEN + ASM_SIMP_TAC[EXTENSION; IN_IMAGE; REAL_ARITH `&0 < --x ==> ~(&0 < x)`] THENL + [ALL_TAC; + ONCE_REWRITE_TAC[VECTOR_ARITH `x = m % y + c <=> c = (--m) % y + x`]] THEN + ASM_SIMP_TAC[VECTOR_EQ_AFFINITY; REAL_LT_IMP_NZ; UNWIND_THM1] THEN + SIMP_TAC[IN_INTERVAL; VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT; + VECTOR_NEG_COMPONENT] THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM REAL_LT_INV_EQ]) THEN + SIMP_TAC[REAL_AFFINITY_LE; REAL_LE_AFFINITY; real_div] THEN + DISCH_THEN(K ALL_TAC) THEN REWRITE_TAC[REAL_INV_INV] THEN + REWRITE_TAC[REAL_MUL_LNEG; REAL_NEGNEG] THEN + ASM_SIMP_TAC[REAL_FIELD `&0 < m ==> (inv m * x) * m = x`] THEN + GEN_TAC THEN AP_TERM_TAC THEN ABS_TAC THEN AP_TERM_TAC THEN REAL_ARITH_TAC);; + +(* ------------------------------------------------------------------------- *) +(* Existence of eigenvectors. The proof is only in this file because it uses *) +(* a few simple results about continuous functions (at least *) +(* CONTINUOUS_ON_LIFT_DOT2, CONTINUOUS_ATTAINS_SUP and CLOSED_SUBSPACE). *) +(* ------------------------------------------------------------------------- *) + +let SELF_ADJOINT_HAS_EIGENVECTOR_IN_SUBSPACE = prove + (`!f:real^N->real^N s. + linear f /\ adjoint f = f /\ + subspace s /\ ~(s = {vec 0}) /\ (!x. x IN s ==> f x IN s) + ==> ?v c. v IN s /\ norm(v) = &1 /\ f(v) = c % v`, + let lemma = prove + (`!a b. (!x. a * x <= b * x pow 2) ==> &0 <= b ==> a = &0`, + REPEAT GEN_TAC THEN DISCH_TAC THEN REWRITE_TAC[REAL_LE_LT] THEN + ASM_CASES_TAC `b = &0` THEN ASM_REWRITE_TAC[] THENL + [FIRST_X_ASSUM(fun t -> MP_TAC(SPEC `&1` t) THEN + MP_TAC(SPEC `-- &1` t)) THEN ASM_REAL_ARITH_TAC; + DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC `a / &2 / b`) THEN + ASM_SIMP_TAC[REAL_FIELD + `&0 < b ==> (b * (a / b) pow 2) = a pow 2 / b`] THEN + REWRITE_TAC[real_div; REAL_MUL_ASSOC] THEN SIMP_TAC[GSYM real_div] THEN + ASM_SIMP_TAC[REAL_LE_DIV2_EQ] THEN + REWRITE_TAC[REAL_LT_SQUARE; REAL_ARITH + `(a * a) / &2 <= (a / &2) pow 2 <=> ~(&0 < a * a)`]]) in + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`\x:real^N. (f x) dot x`; + `s INTER sphere(vec 0:real^N,&1)`] + CONTINUOUS_ATTAINS_SUP) THEN + REWRITE_TAC[EXISTS_IN_GSPEC; FORALL_IN_GSPEC; o_DEF] THEN ANTS_TAC THENL + [ASM_SIMP_TAC[CONTINUOUS_ON_LIFT_DOT2; LINEAR_CONTINUOUS_ON; + CONTINUOUS_ON_ID] THEN + ASM_SIMP_TAC[COMPACT_SPHERE; CLOSED_INTER_COMPACT; CLOSED_SUBSPACE] THEN + FIRST_X_ASSUM(MP_TAC o MATCH_MP (SET_RULE + `~(s = {a}) ==> a IN s ==> ?b. ~(b = a) /\ b IN s`)) THEN + ASM_SIMP_TAC[SUBSPACE_0; IN_SPHERE_0; GSYM MEMBER_NOT_EMPTY; IN_INTER] THEN + DISCH_THEN(X_CHOOSE_THEN `x:real^N` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `inv(norm x) % x:real^N` THEN + ASM_REWRITE_TAC[IN_ELIM_THM; VECTOR_SUB_RZERO; NORM_MUL] THEN + ASM_SIMP_TAC[SUBSPACE_MUL; REAL_ABS_INV; REAL_ABS_NORM] THEN + ASM_SIMP_TAC[REAL_MUL_LINV; NORM_EQ_0]; + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `v:real^N` THEN + REWRITE_TAC[IN_INTER; IN_SPHERE_0] THEN STRIP_TAC THEN + ABBREV_TAC `c = (f:real^N->real^N) v dot v` THEN + EXISTS_TAC `c:real` THEN ASM_REWRITE_TAC[]] THEN + ABBREV_TAC `p = \x y:real^N. c * (x dot y) - (f x) dot y` THEN + SUBGOAL_THEN `!x:real^N. x IN s ==> &0 <= p x x` (LABEL_TAC "POSDEF") THENL + [X_GEN_TAC `x:real^N` THEN EXPAND_TAC "p" THEN REWRITE_TAC[] THEN + ASM_CASES_TAC `x:real^N = vec 0` THEN DISCH_TAC THEN + ASM_REWRITE_TAC[DOT_RZERO; REAL_MUL_RZERO; REAL_SUB_LE; REAL_LE_REFL] THEN + FIRST_X_ASSUM(MP_TAC o SPEC `inv(norm x) % x:real^N`) THEN + ASM_SIMP_TAC[SUBSPACE_MUL] THEN + ASM_SIMP_TAC[LINEAR_CMUL; NORM_MUL; REAL_ABS_INV; DOT_RMUL] THEN + ASM_SIMP_TAC[REAL_ABS_NORM; REAL_MUL_LINV; NORM_EQ_0; DOT_LMUL] THEN + ASM_SIMP_TAC[GSYM REAL_LE_LDIV_EQ; DOT_POS_LT] THEN + REWRITE_TAC[GSYM NORM_POW_2; real_div; REAL_INV_POW] THEN REAL_ARITH_TAC; + ALL_TAC] THEN + SUBGOAL_THEN `!y:real^N. y IN s ==> !a. p v y * a <= p y y * a pow 2` + MP_TAC THENL + [REPEAT STRIP_TAC THEN + REMOVE_THEN "POSDEF" (MP_TAC o SPEC `v - (&2 * a) % y:real^N`) THEN + EXPAND_TAC "p" THEN ASM_SIMP_TAC[SUBSPACE_SUB; SUBSPACE_MUL] THEN + ASM_SIMP_TAC[LINEAR_SUB; LINEAR_CMUL] THEN + REWRITE_TAC[DOT_LSUB; DOT_LMUL] THEN + REWRITE_TAC[DOT_RSUB; DOT_RMUL] THEN + SUBGOAL_THEN `f y dot (v:real^N) = f v dot y` SUBST1_TAC THENL + [ASM_MESON_TAC[ADJOINT_CLAUSES; DOT_SYM]; ALL_TAC] THEN + ASM_REWRITE_TAC[GSYM NORM_POW_2] THEN REWRITE_TAC[NORM_POW_2] THEN + MATCH_MP_TAC(REAL_ARITH + `&4 * (z - y) = x ==> &0 <= x ==> y <= z`) THEN + REWRITE_TAC[DOT_SYM] THEN CONV_TAC REAL_RING; + DISCH_THEN(MP_TAC o GEN `y:real^N` o DISCH `(y:real^N) IN s` o + MATCH_MP lemma o C MP (ASSUME `(y:real^N) IN s`) o SPEC `y:real^N`) THEN + ASM_SIMP_TAC[] THEN EXPAND_TAC "p" THEN + REWRITE_TAC[GSYM DOT_LMUL; GSYM DOT_LSUB] THEN + DISCH_THEN(MP_TAC o SPEC `c % v - f v:real^N`) THEN + ASM_SIMP_TAC[SUBSPACE_MUL; SUBSPACE_SUB; DOT_EQ_0; VECTOR_SUB_EQ]]);; + +let SELF_ADJOINT_HAS_EIGENVECTOR = prove + (`!f:real^N->real^N. + linear f /\ adjoint f = f ==> ?v c. norm(v) = &1 /\ f(v) = c % v`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`f:real^N->real^N`; `(:real^N)`] + SELF_ADJOINT_HAS_EIGENVECTOR_IN_SUBSPACE) THEN + ASM_REWRITE_TAC[SUBSPACE_UNIV; IN_UNIV] THEN DISCH_THEN MATCH_MP_TAC THEN + MATCH_MP_TAC(SET_RULE `!a. ~(a IN s) ==> ~(UNIV = s)`) THEN + EXISTS_TAC `vec 1:real^N` THEN + REWRITE_TAC[IN_SING; VEC_EQ; ARITH_EQ]);; + +let SELF_ADJOINT_HAS_EIGENVECTOR_BASIS_OF_SUBSPACE = prove + (`!f:real^N->real^N s. + linear f /\ adjoint f = f /\ + subspace s /\ (!x. x IN s ==> f x IN s) + ==> ?b. b SUBSET s /\ + pairwise orthogonal b /\ + (!x. x IN b ==> norm x = &1 /\ ?c. f(x) = c % x) /\ + independent b /\ + span b = s /\ + b HAS_SIZE dim s`, + let lemma = prove + (`!f:real^N->real^N s. + linear f /\ adjoint f = f /\ subspace s /\ (!x. x IN s ==> f x IN s) + ==> ?b. b SUBSET s /\ b HAS_SIZE dim s /\ + pairwise orthogonal b /\ + (!x. x IN b ==> norm x = &1 /\ ?c. f(x) = c % x)`, + REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN REWRITE_TAC[IMP_IMP] THEN + GEN_TAC THEN STRIP_TAC THEN GEN_TAC THEN + WF_INDUCT_TAC `dim(s:real^N->bool)` THEN STRIP_TAC THEN + ASM_CASES_TAC `dim(s:real^N->bool) = 0` THENL + [EXISTS_TAC `{}:real^N->bool` THEN + ASM_SIMP_TAC[HAS_SIZE_CLAUSES; NOT_IN_EMPTY; + PAIRWISE_EMPTY; EMPTY_SUBSET]; + ALL_TAC] THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE RAND_CONV [DIM_EQ_0]) THEN + DISCH_THEN(ASSUME_TAC o MATCH_MP (SET_RULE + `~(s SUBSET {a}) ==> ~(s = {a})`)) THEN + MP_TAC(ISPECL [`f:real^N->real^N`; `s:real^N->bool`] + SELF_ADJOINT_HAS_EIGENVECTOR_IN_SUBSPACE) THEN + ASM_REWRITE_TAC[RIGHT_EXISTS_AND_THM] THEN + DISCH_THEN(X_CHOOSE_THEN `v:real^N` MP_TAC) THEN + ASM_CASES_TAC `v:real^N = vec 0` THEN ASM_REWRITE_TAC[NORM_0] THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN + DISCH_THEN(REPEAT_TCL CONJUNCTS_THEN ASSUME_TAC) THEN + FIRST_X_ASSUM(MP_TAC o SPEC `{y:real^N | y IN s /\ orthogonal v y}`) THEN + REWRITE_TAC[SUBSPACE_ORTHOGONAL_TO_VECTOR; IN_ELIM_THM] THEN + MP_TAC(ISPECL [`span {v:real^N}`; `s:real^N->bool`] + DIM_SUBSPACE_ORTHOGONAL_TO_VECTORS) THEN + REWRITE_TAC[ONCE_REWRITE_RULE[ORTHOGONAL_SYM] ORTHOGONAL_TO_SPAN_EQ] THEN + ASM_REWRITE_TAC[SUBSPACE_SPAN; IN_SING; FORALL_UNWIND_THM2] THEN + ANTS_TAC THENL + [MATCH_MP_TAC SPAN_SUBSET_SUBSPACE THEN ASM SET_TAC[]; + DISCH_THEN(SUBST1_TAC o SYM)] THEN + ASM_REWRITE_TAC[DIM_SPAN; DIM_SING; ARITH_RULE `n < n + 1`] THEN + ANTS_TAC THENL + [REWRITE_TAC[SET_RULE `{x | x IN s /\ P x} = s INTER {x | P x}`] THEN + ASM_SIMP_TAC[SUBSPACE_INTER; SUBSPACE_ORTHOGONAL_TO_VECTOR] THEN + REWRITE_TAC[orthogonal] THEN X_GEN_TAC `x:real^N` THEN STRIP_TAC THEN + MATCH_MP_TAC EQ_TRANS THEN + EXISTS_TAC `(f:real^N->real^N) v dot x` THEN CONJ_TAC THENL + [ASM_MESON_TAC[ADJOINT_CLAUSES]; + ASM_MESON_TAC[DOT_LMUL; REAL_MUL_RZERO]]; + DISCH_THEN(X_CHOOSE_THEN `b:real^N->bool` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `(v:real^N) INSERT b` THEN + ASM_REWRITE_TAC[FORALL_IN_INSERT] THEN + CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + ASM_REWRITE_TAC[PAIRWISE_INSERT] THEN + RULE_ASSUM_TAC(REWRITE_RULE[HAS_SIZE; SUBSET; IN_ELIM_THM]) THEN + CONJ_TAC THENL + [ASM_SIMP_TAC[HAS_SIZE; FINITE_INSERT; CARD_CLAUSES] THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[ADD1] THEN + ASM_MESON_TAC[ORTHOGONAL_REFL]; + RULE_ASSUM_TAC(REWRITE_RULE[SUBSET; IN_ELIM_THM]) THEN + ASM_MESON_TAC[ORTHOGONAL_SYM]]]) in + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`f:real^N->real^N`; `s:real^N->bool`] lemma) THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC MONO_EXISTS THEN + X_GEN_TAC `b:real^N->bool` THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC(TAUT `p /\ (p ==> q) ==> p /\ q`) THEN CONJ_TAC THENL + [MATCH_MP_TAC PAIRWISE_ORTHOGONAL_INDEPENDENT THEN + ASM_MESON_TAC[NORM_ARITH `~(norm(vec 0:real^N) = &1)`]; + DISCH_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL + [ASM_MESON_TAC[SPAN_SUBSET_SUBSPACE]; + MATCH_MP_TAC CARD_GE_DIM_INDEPENDENT THEN + RULE_ASSUM_TAC(REWRITE_RULE[HAS_SIZE]) THEN + ASM_REWRITE_TAC[LE_REFL]]]);; + +let SELF_ADJOINT_HAS_EIGENVECTOR_BASIS = prove + (`!f:real^N->real^N. + linear f /\ adjoint f = f + ==> ?b. pairwise orthogonal b /\ + (!x. x IN b ==> norm x = &1 /\ ?c. f(x) = c % x) /\ + independent b /\ + span b = (:real^N) /\ + b HAS_SIZE (dimindex(:N))`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`f:real^N->real^N`; `(:real^N)`] + SELF_ADJOINT_HAS_EIGENVECTOR_BASIS_OF_SUBSPACE) THEN + ASM_REWRITE_TAC[SUBSPACE_UNIV; IN_UNIV; DIM_UNIV; SUBSET_UNIV]);; + +(* ------------------------------------------------------------------------- *) +(* Diagonalization of symmetric matrix. *) +(* ------------------------------------------------------------------------- *) + +let SYMMETRIC_MATRIX_DIAGONALIZABLE_EXPLICIT = prove + (`!A:real^N^N. + transp A = A + ==> ?P d. orthogonal_matrix P /\ + transp P ** A ** P = (lambda i j. if i = j then d i else &0)`, + let lemma1 = prove + (`!A:real^N^N P:real^N^N d. + A ** P = P ** (lambda i j. if i = j then d i else &0) <=> + !i. 1 <= i /\ i <= dimindex(:N) + ==> A ** column i P = d i % column i P`, + SIMP_TAC[CART_EQ; matrix_mul; matrix_vector_mul; LAMBDA_BETA; + column; VECTOR_MUL_COMPONENT] THEN + REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[COND_RAND] THEN + SIMP_TAC[REAL_MUL_RZERO; SUM_DELTA; IN_NUMSEG] THEN + EQ_TAC THEN STRIP_TAC THEN ASM_SIMP_TAC[] THEN + REWRITE_TAC[REAL_MUL_SYM]) in + let lemma2 = prove + (`!A:real^N^N P:real^N^N d. + orthogonal_matrix P /\ + transp P ** A ** P = (lambda i j. if i = j then d i else &0) <=> + orthogonal_matrix P /\ + !i. 1 <= i /\ i <= dimindex(:N) + ==> A ** column i P = d i % column i P`, + REPEAT GEN_TAC THEN REWRITE_TAC[GSYM lemma1; orthogonal_matrix] THEN + ABBREV_TAC `D:real^N^N = lambda i j. if i = j then d i else &0` THEN + MESON_TAC[MATRIX_MUL_ASSOC; MATRIX_MUL_LID]) in + REPEAT STRIP_TAC THEN + REWRITE_TAC[lemma2] THEN REWRITE_TAC[RIGHT_EXISTS_AND_THM] THEN + REWRITE_TAC[GSYM SKOLEM_THM] THEN + MP_TAC(ISPEC `\x:real^N. (A:real^N^N) ** x` + SELF_ADJOINT_HAS_EIGENVECTOR_BASIS) THEN + ASM_SIMP_TAC[MATRIX_SELF_ADJOINT; MATRIX_VECTOR_MUL_LINEAR; + MATRIX_OF_MATRIX_VECTOR_MUL] THEN + DISCH_THEN(X_CHOOSE_THEN `b:real^N->bool` MP_TAC) THEN + REWRITE_TAC[CONJ_ASSOC] THEN ONCE_REWRITE_TAC[IMP_CONJ_ALT] THEN + REWRITE_TAC[HAS_SIZE] THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [FINITE_INDEX_NUMSEG]) THEN + ASM_REWRITE_TAC[IN_NUMSEG; TAUT + `p /\ q /\ x = y ==> a = b <=> p /\ q /\ ~(a = b) ==> ~(x = y)`] THEN + DISCH_THEN(X_CHOOSE_THEN `f:num->real^N` STRIP_ASSUME_TAC) THEN + ASM_REWRITE_TAC[PAIRWISE_IMAGE; FORALL_IN_IMAGE] THEN + ASM_SIMP_TAC[pairwise; IN_NUMSEG] THEN STRIP_TAC THEN + EXISTS_TAC `transp(lambda i. f i):real^N^N` THEN + SIMP_TAC[COLUMN_TRANSP; ORTHOGONAL_MATRIX_TRANSP] THEN + SIMP_TAC[ORTHOGONAL_MATRIX_ORTHONORMAL_ROWS_INDEXED; row] THEN + SIMP_TAC[LAMBDA_ETA; LAMBDA_BETA; pairwise; IN_NUMSEG] THEN + ASM_MESON_TAC[]);; + +let SYMMETRIC_MATRIX_IMP_DIAGONALIZABLE = prove + (`!A:real^N^N. + transp A = A + ==> ?P. orthogonal_matrix P /\ diagonal_matrix(transp P ** A ** P)`, + GEN_TAC THEN + DISCH_THEN(MP_TAC o MATCH_MP SYMMETRIC_MATRIX_DIAGONALIZABLE_EXPLICIT) THEN + MATCH_MP_TAC MONO_EXISTS THEN REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + SIMP_TAC[diagonal_matrix; LAMBDA_BETA]);; + +let SYMMETRIC_MATRIX_EQ_DIAGONALIZABLE = prove + (`!A:real^N^N. + transp A = A <=> + ?P. orthogonal_matrix P /\ diagonal_matrix(transp P ** A ** P)`, + GEN_TAC THEN EQ_TAC THEN + REWRITE_TAC[SYMMETRIC_MATRIX_IMP_DIAGONALIZABLE] THEN + REWRITE_TAC[orthogonal_matrix] THEN + DISCH_THEN(X_CHOOSE_THEN `P:real^N^N` STRIP_ASSUME_TAC) THEN + ABBREV_TAC `D:real^N^N = transp P ** (A:real^N^N) ** P` THEN + SUBGOAL_THEN `A:real^N^N = P ** (D:real^N^N) ** transp P` SUBST1_TAC THENL + [EXPAND_TAC "D" THEN REWRITE_TAC[MATRIX_MUL_ASSOC] THEN + ASM_REWRITE_TAC[MATRIX_MUL_LID] THEN + ASM_REWRITE_TAC[GSYM MATRIX_MUL_ASSOC; MATRIX_MUL_RID]; + REWRITE_TAC[MATRIX_TRANSP_MUL; TRANSP_TRANSP; MATRIX_MUL_ASSOC] THEN + ASM_MESON_TAC[TRANSP_DIAGONAL_MATRIX]]);; + +(* ------------------------------------------------------------------------- *) +(* Some matrix identities are easier to deduce for invertible matrices. We *) +(* can then extend by continuity, which is why this material needs to be *) +(* here after basic topological notions have been defined. *) +(* ------------------------------------------------------------------------- *) + +let CONTINUOUS_LIFT_DET = prove + (`!(A:A->real^N^N) net. + (!i j. 1 <= i /\ i <= dimindex(:N) /\ + 1 <= j /\ j <= dimindex(:N) + ==> (\x. lift(A x$i$j)) continuous net) + ==> (\x. lift(det(A x))) continuous net`, + REPEAT STRIP_TAC THEN REWRITE_TAC[det] THEN + SIMP_TAC[LIFT_SUM; FINITE_PERMUTATIONS; FINITE_NUMSEG; o_DEF] THEN + MATCH_MP_TAC CONTINUOUS_VSUM THEN + SIMP_TAC[FINITE_PERMUTATIONS; FINITE_NUMSEG; LIFT_CMUL; IN_ELIM_THM] THEN + X_GEN_TAC `p:num->num` THEN DISCH_TAC THEN + MATCH_MP_TAC CONTINUOUS_CMUL THEN + MATCH_MP_TAC CONTINUOUS_LIFT_PRODUCT THEN + REWRITE_TAC[FINITE_NUMSEG; IN_NUMSEG] THEN + REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + FIRST_ASSUM(MP_TAC o MATCH_MP PERMUTES_IMAGE) THEN + DISCH_THEN(MP_TAC o MATCH_MP (SET_RULE `s = t ==> s SUBSET t`)) THEN + ASM_SIMP_TAC[SUBSET; FORALL_IN_IMAGE; IN_NUMSEG]);; + +let CONTINUOUS_ON_LIFT_DET = prove + (`!A:real^M->real^N^N s. + (!i j. 1 <= i /\ i <= dimindex(:N) /\ + 1 <= j /\ j <= dimindex(:N) + ==> (\x. lift(A x$i$j)) continuous_on s) + ==> (\x. lift(det(A x))) continuous_on s`, + SIMP_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN; CONTINUOUS_LIFT_DET]);; + +let NEARBY_INVERTIBLE_MATRIX = prove + (`!A:real^N^N. + ?e. &0 < e /\ !x. ~(x = &0) /\ abs x < e ==> invertible(A + x %% mat 1)`, + GEN_TAC THEN MP_TAC(ISPEC `A:real^N^N` CHARACTERISTIC_POLYNOMIAL) THEN + DISCH_THEN(X_CHOOSE_THEN `a:num->real` STRIP_ASSUME_TAC) THEN + MP_TAC(ISPECL [`dimindex(:N)`; `a:num->real`] REAL_POLYFUN_FINITE_ROOTS) THEN + MATCH_MP_TAC(TAUT `q /\ (p ==> r) ==> (p <=> q) ==> r`) THEN CONJ_TAC THENL + [EXISTS_TAC `dimindex(:N)` THEN ASM_REWRITE_TAC[IN_NUMSEG] THEN ARITH_TAC; + ALL_TAC] THEN + DISCH_THEN(MP_TAC o ISPEC `lift` o MATCH_MP FINITE_IMAGE) THEN + DISCH_THEN(MP_TAC o MATCH_MP LIMIT_POINT_FINITE) THEN + DISCH_THEN(MP_TAC o SPEC `lift(&0)`) THEN + REWRITE_TAC[LIMPT_APPROACHABLE; EXISTS_IN_IMAGE; EXISTS_IN_GSPEC] THEN + REWRITE_TAC[DIST_LIFT; LIFT_EQ; REAL_SUB_RZERO; NOT_FORALL_THM; NOT_IMP] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `e:real` THEN + ASM_CASES_TAC `&0 < e` THEN ASM_REWRITE_TAC[NOT_EXISTS_THM] THEN + DISCH_THEN(fun th -> X_GEN_TAC `x:real` THEN STRIP_TAC THEN + MP_TAC(SPEC `--x:real` th)) THEN + FIRST_X_ASSUM(SUBST1_TAC o SYM o SPEC `--x:real`) THEN + ASM_REWRITE_TAC[REAL_NEG_EQ_0; REAL_ABS_NEG] THEN + ONCE_REWRITE_TAC[GSYM INVERTIBLE_NEG] THEN + REWRITE_TAC[INVERTIBLE_DET_NZ; CONTRAPOS_THM] THEN + REWRITE_TAC[MATRIX_SUB; MATRIX_NEG_MINUS1] THEN + ONCE_REWRITE_TAC[REAL_ARITH `--x = -- &1 * x`] THEN + REWRITE_TAC[GSYM MATRIX_CMUL_ADD_LDISTRIB; GSYM MATRIX_CMUL_ASSOC] THEN + REWRITE_TAC[MATRIX_CMUL_LID; MATRIX_ADD_SYM]);; + +let MATRIX_WLOG_INVERTIBLE = prove + (`!P. (!A:real^N^N. invertible A ==> P A) /\ + (!A:real^N^N. ?d. &0 < d /\ + closed {x | x IN cball(vec 0,d) /\ + P(A + drop x %% mat 1)}) + ==> !A:real^N^N. P A`, + REPEAT GEN_TAC THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + MATCH_MP_TAC MONO_FORALL THEN GEN_TAC THEN + DISCH_THEN(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC) THEN + FIRST_ASSUM(MP_TAC o SPEC `vec 0:real^1` o + GEN_REWRITE_RULE I [CLOSED_LIMPT]) THEN + ASM_SIMP_TAC[IN_ELIM_THM; DROP_VEC; MATRIX_CMUL_LZERO; MATRIX_ADD_RID] THEN + ANTS_TAC THENL [ALL_TAC; CONV_TAC TAUT] THEN + MP_TAC(ISPEC `A:real^N^N` NEARBY_INVERTIBLE_MATRIX) THEN + DISCH_THEN(X_CHOOSE_THEN `e:real` STRIP_ASSUME_TAC) THEN + REWRITE_TAC[LIMPT_APPROACHABLE] THEN X_GEN_TAC `k:real` THEN + DISCH_TAC THEN REWRITE_TAC[EXISTS_LIFT; IN_ELIM_THM] THEN + REWRITE_TAC[GSYM LIFT_NUM; IN_CBALL_0; NORM_LIFT; DIST_LIFT] THEN + REWRITE_TAC[REAL_SUB_RZERO; LIFT_EQ; LIFT_DROP] THEN + EXISTS_TAC `min d ((min e k) / &2)` THEN + CONJ_TAC THENL [ALL_TAC; ASM_REAL_ARITH_TAC] THEN + CONJ_TAC THENL [ASM_REAL_ARITH_TAC; FIRST_X_ASSUM MATCH_MP_TAC] THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REAL_ARITH_TAC);; + +let SYLVESTER_DETERMINANT_IDENTITY = prove + (`!A:real^N^M B:real^M^N. det(mat 1 + A ** B) = det(mat 1 + B ** A)`, + let lemma1 = prove + (`!A:real^N^N B:real^N^N. det(mat 1 + A ** B) = det(mat 1 + B ** A)`, + ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN GEN_TAC THEN + MATCH_MP_TAC MATRIX_WLOG_INVERTIBLE THEN CONJ_TAC THENL + [REPEAT STRIP_TAC THEN + SUBGOAL_THEN `det((mat 1 + A ** B) ** A:real^N^N) = + det(A ** (mat 1 + B ** A))` + MP_TAC THENL + [REWRITE_TAC[MATRIX_ADD_RDISTRIB; MATRIX_ADD_LDISTRIB] THEN + REWRITE_TAC[MATRIX_MUL_LID; MATRIX_MUL_RID; MATRIX_MUL_ASSOC]; + REWRITE_TAC[DET_MUL] THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [INVERTIBLE_DET_NZ]) THEN + CONV_TAC REAL_RING]; + X_GEN_TAC `A:real^N^N` THEN EXISTS_TAC `&1` THEN + REWRITE_TAC[REAL_LT_01; SET_RULE + `{x | x IN s /\ P x} = s INTER {x | P x}`] THEN + MATCH_MP_TAC CLOSED_INTER THEN REWRITE_TAC[CLOSED_CBALL] THEN + ONCE_REWRITE_TAC[GSYM REAL_SUB_0] THEN + REWRITE_TAC[GSYM LIFT_EQ; LIFT_NUM] THEN + REWRITE_TAC[SET_RULE `{x | f x = a} = {x | f x IN {a}}`] THEN + MATCH_MP_TAC CONTINUOUS_CLOSED_PREIMAGE_UNIV THEN + REWRITE_TAC[CLOSED_SING; LIFT_SUB] THEN X_GEN_TAC `x:real^1` THEN + REWRITE_TAC[o_DEF; LIFT_SUB] THEN MATCH_MP_TAC CONTINUOUS_SUB THEN + CONJ_TAC THEN MATCH_MP_TAC CONTINUOUS_LIFT_DET THEN + MAP_EVERY X_GEN_TAC [`i:num`; `j:num`] THEN STRIP_TAC THEN + ASM_SIMP_TAC[MATRIX_ADD_COMPONENT; LIFT_ADD] THEN + MATCH_MP_TAC CONTINUOUS_ADD THEN + ASM_SIMP_TAC[matrix_mul; LAMBDA_BETA; CONTINUOUS_CONST] THEN + SIMP_TAC[LIFT_SUM; FINITE_NUMSEG; o_DEF] THEN + MATCH_MP_TAC CONTINUOUS_VSUM THEN + REWRITE_TAC[FINITE_NUMSEG; IN_NUMSEG] THEN X_GEN_TAC `k:num` THEN + DISCH_TAC THENL [ONCE_REWRITE_TAC[REAL_MUL_SYM]; ALL_TAC] THEN + REWRITE_TAC[LIFT_CMUL] THEN MATCH_MP_TAC CONTINUOUS_CMUL THEN + REWRITE_TAC[MATRIX_ADD_COMPONENT; MATRIX_CMUL_COMPONENT; LIFT_ADD] THEN + MATCH_MP_TAC CONTINUOUS_ADD THEN REWRITE_TAC[CONTINUOUS_CONST] THEN + REWRITE_TAC[ONCE_REWRITE_RULE[REAL_MUL_SYM] LIFT_CMUL] THEN + MATCH_MP_TAC CONTINUOUS_CMUL THEN + REWRITE_TAC[LIFT_DROP; CONTINUOUS_AT_ID]]) in + let lemma2 = prove + (`!A:real^N^M B:real^M^N. + dimindex(:M) <= dimindex(:N) + ==> det(mat 1 + A ** B) = det(mat 1 + B ** A)`, + REPEAT STRIP_TAC THEN + MAP_EVERY ABBREV_TAC + [`A':real^N^N = + lambda i j. if i <= dimindex(:M) then (A:real^N^M)$i$j + else &0`; + `B':real^N^N = + lambda i j. if j <= dimindex(:M) then (B:real^M^N)$i$j + else &0`] THEN + MP_TAC(ISPECL [`A':real^N^N`; `B':real^N^N`] lemma1) THEN + SUBGOAL_THEN + `(B':real^N^N) ** (A':real^N^N) = (B:real^M^N) ** (A:real^N^M)` + SUBST1_TAC THENL + [MAP_EVERY EXPAND_TAC ["A'"; "B'"] THEN + SIMP_TAC[CART_EQ; LAMBDA_BETA; matrix_mul] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC SUM_EQ_SUPERSET THEN + ASM_SIMP_TAC[IN_NUMSEG; REAL_MUL_LZERO; FINITE_NUMSEG; SUBSET_NUMSEG; + LE_REFL; TAUT `(p /\ q) /\ ~(p /\ r) <=> p /\ q /\ ~r`]; + DISCH_THEN(SUBST1_TAC o SYM)] THEN + REWRITE_TAC[det] THEN MATCH_MP_TAC EQ_TRANS THEN EXISTS_TAC + `sum {p | p permutes 1..dimindex(:N) /\ !i. dimindex(:M) < i ==> p i = i} + (\p. sign p * product (1..dimindex(:N)) + (\i. (mat 1 + (A':real^N^N) ** (B':real^N^N))$i$p i))` THEN + CONJ_TAC THENL + [ALL_TAC; + CONV_TAC SYM_CONV THEN MATCH_MP_TAC SUM_SUPERSET THEN + CONJ_TAC THENL [SET_TAC[]; SIMP_TAC[IN_ELIM_THM; IMP_CONJ]] THEN + X_GEN_TAC `p:num->num` THEN REPEAT STRIP_TAC THEN + REWRITE_TAC[REAL_ENTIRE; PRODUCT_EQ_0_NUMSEG] THEN DISJ2_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [NOT_FORALL_THM]) THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `k:num` THEN + REWRITE_TAC[NOT_IMP] THEN STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o SPEC `k:num` o CONJUNCT1 o + GEN_REWRITE_RULE I [permutes]) THEN + ASM_REWRITE_TAC[IN_NUMSEG] THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + FIRST_ASSUM(MP_TAC o MATCH_MP PERMUTES_IMAGE) THEN + DISCH_THEN(MP_TAC o MATCH_MP (SET_RULE `s = t ==> s SUBSET t`)) THEN + ASM_SIMP_TAC[SUBSET; FORALL_IN_IMAGE; IN_NUMSEG] THEN + DISCH_THEN(MP_TAC o SPEC `k:num`) THEN ASM_SIMP_TAC[] THEN STRIP_TAC THEN + ASM_SIMP_TAC[MATRIX_ADD_COMPONENT; MAT_COMPONENT; REAL_ADD_LID] THEN + ASM_SIMP_TAC[matrix_mul; LAMBDA_BETA] THEN + MATCH_MP_TAC SUM_EQ_0_NUMSEG THEN REPEAT STRIP_TAC THEN + REWRITE_TAC[REAL_ENTIRE] THEN DISJ1_TAC THEN EXPAND_TAC "A'" THEN + ASM_SIMP_TAC[LAMBDA_BETA; GSYM NOT_LT]] THEN + CONV_TAC SYM_CONV THEN MATCH_MP_TAC SUM_EQ_GENERAL THEN + EXISTS_TAC `\f:num->num. f` THEN REWRITE_TAC[IN_ELIM_THM] THEN + CONJ_TAC THEN X_GEN_TAC `p:num->num` THEN STRIP_TAC THENL + [REWRITE_TAC[MESON[] `(?!x. P x /\ x = y) <=> P y`] THEN CONJ_TAC THENL + [MATCH_MP_TAC PERMUTES_SUBSET THEN + EXISTS_TAC `1..dimindex(:M)` THEN + ASM_REWRITE_TAC[SUBSET_NUMSEG; LE_REFL]; + X_GEN_TAC `k:num` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MATCH_MP_TAC o CONJUNCT1 o + GEN_REWRITE_RULE I [permutes]) THEN + ASM_REWRITE_TAC[IN_NUMSEG; DE_MORGAN_THM; NOT_LE]]; + MATCH_MP_TAC(TAUT `p /\ (p ==> q) ==> p /\ q`) THEN CONJ_TAC THENL + [MATCH_MP_TAC PERMUTES_SUPERSET THEN + EXISTS_TAC `1..dimindex(:N)` THEN + ASM_REWRITE_TAC[IN_DIFF; IN_NUMSEG] THEN ASM_MESON_TAC[NOT_LE]; + DISCH_TAC] THEN + AP_TERM_TAC THEN FIRST_ASSUM(SUBST1_TAC o MATCH_MP (ARITH_RULE + `m:num <= n ==> n = m + (n - m)`)) THEN + SIMP_TAC[PRODUCT_ADD_SPLIT; ARITH_RULE `1 <= n + 1`] THEN + MATCH_MP_TAC(REAL_RING `x = y /\ z = &1 ==> x = y * z`) THEN + CONJ_TAC THENL + [MATCH_MP_TAC PRODUCT_EQ_NUMSEG THEN + X_GEN_TAC `i:num` THEN STRIP_TAC THEN + SUBGOAL_THEN `i <= dimindex(:N)` ASSUME_TAC THENL + [ASM_ARITH_TAC; ALL_TAC] THEN + MP_TAC(ISPECL [`p:num->num`; `1..dimindex(:M)`] PERMUTES_IMAGE) THEN + ASM_REWRITE_TAC[] THEN + DISCH_THEN(MP_TAC o MATCH_MP (SET_RULE `s = t ==> s SUBSET t`)) THEN + ASM_SIMP_TAC[SUBSET; FORALL_IN_IMAGE; IN_NUMSEG] THEN + DISCH_THEN(MP_TAC o SPEC `i:num`) THEN + ASM_REWRITE_TAC[] THEN STRIP_TAC THEN + SUBGOAL_THEN `(p:num->num) i <= dimindex(:N)` ASSUME_TAC THENL + [ASM_ARITH_TAC; ALL_TAC] THEN + ASM_SIMP_TAC[MATRIX_ADD_COMPONENT; MAT_COMPONENT] THEN + AP_TERM_TAC THEN ASM_SIMP_TAC[matrix_mul; LAMBDA_BETA] THEN + MATCH_MP_TAC SUM_EQ_NUMSEG THEN REPEAT STRIP_TAC THEN + MAP_EVERY EXPAND_TAC ["A'"; "B'"] THEN + ASM_SIMP_TAC[LAMBDA_BETA]; + MATCH_MP_TAC PRODUCT_EQ_1_NUMSEG THEN + ASM_SIMP_TAC[ARITH_RULE `n + 1 <= i ==> n < i`] THEN + ASM_SIMP_TAC[ARITH_RULE `m:num <= n ==> m + (n - m) = n`] THEN + 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[MATRIX_ADD_COMPONENT; MAT_COMPONENT] THEN + ASM_SIMP_TAC[REAL_EQ_ADD_LCANCEL_0; matrix_mul; LAMBDA_BETA] THEN + MATCH_MP_TAC SUM_EQ_0_NUMSEG THEN REPEAT STRIP_TAC THEN + REWRITE_TAC[REAL_ENTIRE] THEN DISJ1_TAC THEN EXPAND_TAC "A'" THEN + ASM_SIMP_TAC[LAMBDA_BETA; ARITH_RULE `m + 1 <= i ==> ~(i <= m)`]]]) in + REPEAT GEN_TAC THEN DISJ_CASES_TAC (ARITH_RULE + `dimindex(:M) <= dimindex(:N) \/ dimindex(:N) <= dimindex(:M)`) + THENL [ALL_TAC; CONV_TAC SYM_CONV] THEN + MATCH_MP_TAC lemma2 THEN ASM_REWRITE_TAC[]);; + +let COFACTOR_MATRIX_MUL = prove + (`!A B:real^N^N. cofactor(A ** B) = cofactor(A) ** cofactor(B)`, + MATCH_MP_TAC MATRIX_WLOG_INVERTIBLE THEN CONJ_TAC THENL + [GEN_TAC THEN DISCH_TAC THEN MATCH_MP_TAC MATRIX_WLOG_INVERTIBLE THEN + CONJ_TAC THENL + [ASM_SIMP_TAC[COFACTOR_MATRIX_INV; GSYM INVERTIBLE_DET_NZ; + INVERTIBLE_MATRIX_MUL] THEN + REWRITE_TAC[DET_MUL; MATRIX_MUL_LMUL] THEN + REWRITE_TAC[MATRIX_MUL_RMUL; MATRIX_CMUL_ASSOC; + GSYM MATRIX_TRANSP_MUL] THEN + ASM_SIMP_TAC[MATRIX_INV_MUL]; + GEN_TAC THEN EXISTS_TAC `&1` THEN REWRITE_TAC[REAL_LT_01]]; + X_GEN_TAC `A:real^N^N` THEN EXISTS_TAC `&1` THEN + REWRITE_TAC[REAL_LT_01] THEN REWRITE_TAC[RIGHT_AND_FORALL_THM] THEN + MATCH_MP_TAC CLOSED_FORALL THEN GEN_TAC] THEN + REWRITE_TAC[SET_RULE + `{x | x IN s /\ P x} = s INTER {x | P x}`] THEN + MATCH_MP_TAC CLOSED_INTER THEN REWRITE_TAC[CLOSED_CBALL] THEN + REWRITE_TAC[CART_EQ] THEN + MATCH_MP_TAC CLOSED_FORALL_IN THEN X_GEN_TAC `i:num` THEN STRIP_TAC THEN + MATCH_MP_TAC CLOSED_FORALL_IN THEN X_GEN_TAC `j:num` THEN STRIP_TAC THEN + ONCE_REWRITE_TAC[GSYM REAL_SUB_0] THEN + REWRITE_TAC[GSYM LIFT_EQ; LIFT_NUM] THEN + REWRITE_TAC[SET_RULE `{x | f x = a} = {x | f x IN {a}}`] THEN + MATCH_MP_TAC CONTINUOUS_CLOSED_PREIMAGE_UNIV THEN + REWRITE_TAC[CLOSED_SING; LIFT_SUB] THEN X_GEN_TAC `x:real^1` THEN + ASM_SIMP_TAC[matrix_mul; LAMBDA_BETA; cofactor; LIFT_SUM; + FINITE_NUMSEG; o_DEF] THEN + (MATCH_MP_TAC CONTINUOUS_SUB THEN CONJ_TAC THENL + [ALL_TAC; + MATCH_MP_TAC CONTINUOUS_VSUM THEN + REWRITE_TAC[FINITE_NUMSEG; IN_NUMSEG] THEN + X_GEN_TAC `k:num` THEN STRIP_TAC THEN + REWRITE_TAC[LIFT_CMUL] THEN MATCH_MP_TAC CONTINUOUS_MUL THEN + REWRITE_TAC[o_DEF] THEN CONJ_TAC]) THEN + MATCH_MP_TAC CONTINUOUS_LIFT_DET THEN + MAP_EVERY X_GEN_TAC [`m:num`; `n:num`] THEN STRIP_TAC THEN + ASM_SIMP_TAC[LAMBDA_BETA; CONTINUOUS_CONST] THEN + REPEAT(W(fun (asl,w) -> + let t = find_term is_cond w in + ASM_CASES_TAC (lhand(rator t)) THEN ASM_REWRITE_TAC[CONTINUOUS_CONST])) THEN + SIMP_TAC[LIFT_SUM; FINITE_NUMSEG; o_DEF] THEN + TRY(MATCH_MP_TAC CONTINUOUS_VSUM THEN REWRITE_TAC[FINITE_NUMSEG] THEN + REWRITE_TAC[IN_NUMSEG] THEN X_GEN_TAC `p:num` THEN STRIP_TAC) THEN + REWRITE_TAC[LIFT_CMUL] THEN + TRY(MATCH_MP_TAC CONTINUOUS_MUL THEN + REWRITE_TAC[o_DEF; CONTINUOUS_CONST]) THEN + REWRITE_TAC[MATRIX_ADD_COMPONENT; LIFT_ADD] THEN + MATCH_MP_TAC CONTINUOUS_ADD THEN REWRITE_TAC[CONTINUOUS_CONST] THEN + REWRITE_TAC[MATRIX_CMUL_COMPONENT; LIFT_CMUL; o_DEF] THEN + MATCH_MP_TAC CONTINUOUS_MUL THEN + REWRITE_TAC[CONTINUOUS_CONST; o_DEF; LIFT_DROP; CONTINUOUS_AT_ID]);; + +let DET_COFACTOR = prove + (`!A:real^N^N. det(cofactor A) = det(A) pow (dimindex(:N) - 1)`, + MATCH_MP_TAC MATRIX_WLOG_INVERTIBLE THEN CONJ_TAC THEN + X_GEN_TAC `A:real^N^N` THENL + [REWRITE_TAC[INVERTIBLE_DET_NZ] THEN STRIP_TAC THEN + FIRST_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_FIELD + `~(a = &0) ==> a * x = a * y ==> x = y`)) THEN + GEN_REWRITE_TAC (LAND_CONV o RAND_CONV) [GSYM DET_TRANSP] THEN + REWRITE_TAC[GSYM DET_MUL; MATRIX_MUL_RIGHT_COFACTOR] THEN + REWRITE_TAC[DET_CMUL; GSYM(CONJUNCT2 real_pow); DET_I; REAL_MUL_RID] THEN + SIMP_TAC[DIMINDEX_GE_1; ARITH_RULE `1 <= n ==> SUC(n - 1) = n`]; + ALL_TAC] THEN + EXISTS_TAC `&1` THEN REWRITE_TAC[REAL_LT_01] THEN + REWRITE_TAC[SET_RULE + `{x | x IN s /\ P x} = s INTER {x | P x}`] THEN + MATCH_MP_TAC CLOSED_INTER THEN REWRITE_TAC[CLOSED_CBALL] THEN + ONCE_REWRITE_TAC[GSYM REAL_SUB_0] THEN + REWRITE_TAC[GSYM LIFT_EQ; LIFT_NUM] THEN + REWRITE_TAC[SET_RULE `{x | f x = a} = {x | f x IN {a}}`] THEN + MATCH_MP_TAC CONTINUOUS_CLOSED_PREIMAGE_UNIV THEN + REWRITE_TAC[CLOSED_SING; LIFT_SUB] THEN X_GEN_TAC `x:real^1` THEN + MATCH_MP_TAC CONTINUOUS_SUB THEN + CONJ_TAC THENL [ALL_TAC; MATCH_MP_TAC CONTINUOUS_LIFT_POW] THEN + MATCH_MP_TAC CONTINUOUS_LIFT_DET THEN + MAP_EVERY X_GEN_TAC [`i:num`; `j:num`] THEN STRIP_TAC THEN + ASM_SIMP_TAC[MATRIX_ADD_COMPONENT; MATRIX_CMUL_COMPONENT; LIFT_ADD; + LIFT_CMUL; LIFT_DROP; CONTINUOUS_ADD; CONTINUOUS_CONST; + CONTINUOUS_MUL; o_DEF; LIFT_DROP; CONTINUOUS_AT_ID] THEN + ASM_SIMP_TAC[cofactor; LAMBDA_BETA] THEN + MATCH_MP_TAC CONTINUOUS_LIFT_DET THEN + MAP_EVERY X_GEN_TAC [`m:num`; `n:num`] THEN STRIP_TAC THEN + ASM_SIMP_TAC[LAMBDA_BETA] THEN + REPEAT(W(fun (asl,w) -> + let t = find_term is_cond w in + ASM_CASES_TAC (lhand(rator t)) THEN ASM_REWRITE_TAC[CONTINUOUS_CONST])) THEN + ASM_SIMP_TAC[MATRIX_ADD_COMPONENT; MATRIX_CMUL_COMPONENT; LIFT_ADD; + LIFT_CMUL; LIFT_DROP; CONTINUOUS_ADD; CONTINUOUS_CONST; + CONTINUOUS_MUL; o_DEF; LIFT_DROP; CONTINUOUS_AT_ID]);; + +let INVERTIBLE_COFACTOR = prove + (`!A:real^N^N. invertible(cofactor A) <=> dimindex(:N) = 1 \/ invertible A`, + SIMP_TAC[DET_COFACTOR; INVERTIBLE_DET_NZ; REAL_POW_EQ_0; DE_MORGAN_THM; + DIMINDEX_GE_1; ARITH_RULE `1 <= n ==> (n - 1 = 0 <=> n = 1)`; + DISJ_ACI]);; + +let COFACTOR_COFACTOR = prove + (`!A:real^N^N. + 2 <= dimindex(:N) + ==> cofactor(cofactor A) = (det(A) pow (dimindex(:N) - 2)) %% A`, + REWRITE_TAC[RIGHT_FORALL_IMP_THM] THEN DISCH_TAC THEN + MATCH_MP_TAC MATRIX_WLOG_INVERTIBLE THEN CONJ_TAC THEN + X_GEN_TAC `A:real^N^N` THENL + [REWRITE_TAC[INVERTIBLE_DET_NZ] THEN DISCH_TAC THEN + MP_TAC(ISPECL [`A:real^N^N`; `transp(cofactor A):real^N^N`] + COFACTOR_MATRIX_MUL) THEN + REWRITE_TAC[MATRIX_MUL_RIGHT_COFACTOR; COFACTOR_CMUL; COFACTOR_I] THEN + REWRITE_TAC[COFACTOR_TRANSP] THEN + DISCH_THEN(MP_TAC o AP_TERM `transp:real^N^N->real^N^N`) THEN + REWRITE_TAC[MATRIX_TRANSP_MUL; TRANSP_TRANSP; TRANSP_MATRIX_CMUL] THEN + REWRITE_TAC[TRANSP_MAT] THEN + DISCH_THEN(MP_TAC o AP_TERM `(\x. x ** A):real^N^N->real^N^N`) THEN + REWRITE_TAC[GSYM MATRIX_MUL_ASSOC; MATRIX_MUL_LEFT_COFACTOR] THEN + REWRITE_TAC[MATRIX_MUL_LMUL; MATRIX_MUL_RMUL] THEN + REWRITE_TAC[MATRIX_MUL_LID; MATRIX_MUL_RID] THEN + DISCH_THEN(MP_TAC o AP_TERM `\x:real^N^N. inv(det(A:real^N^N)) %% x`) THEN + ASM_SIMP_TAC[MATRIX_CMUL_ASSOC; REAL_MUL_LINV; MATRIX_CMUL_LID] THEN + DISCH_THEN(SUBST1_TAC o SYM) THEN AP_THM_TAC THEN AP_TERM_TAC THEN + ASM_SIMP_TAC[REAL_POW_SUB; ARITH_RULE `2 <= n ==> 1 <= n`] THEN + REWRITE_TAC[REAL_POW_2; real_div; REAL_INV_POW] THEN REAL_ARITH_TAC; + POP_ASSUM(K ALL_TAC)] THEN + EXISTS_TAC `&1` THEN REWRITE_TAC[REAL_LT_01] THEN + REWRITE_TAC[SET_RULE + `{x | x IN s /\ P x} = s INTER {x | P x}`] THEN + MATCH_MP_TAC CLOSED_INTER THEN REWRITE_TAC[CLOSED_CBALL] THEN + REWRITE_TAC[CART_EQ] THEN + MATCH_MP_TAC CLOSED_FORALL_IN THEN X_GEN_TAC `i:num` THEN STRIP_TAC THEN + MATCH_MP_TAC CLOSED_FORALL_IN THEN X_GEN_TAC `j:num` THEN STRIP_TAC THEN + ONCE_REWRITE_TAC[GSYM REAL_SUB_0] THEN + REWRITE_TAC[GSYM LIFT_EQ; LIFT_NUM] THEN + REWRITE_TAC[SET_RULE `{x | f x = a} = {x | f x IN {a}}`] THEN + MATCH_MP_TAC CONTINUOUS_CLOSED_PREIMAGE_UNIV THEN + REWRITE_TAC[CLOSED_SING; LIFT_SUB] THEN X_GEN_TAC `x:real^1` THEN + MATCH_MP_TAC CONTINUOUS_SUB THEN CONJ_TAC THENL + [REPLICATE_TAC 2 + (ONCE_REWRITE_TAC[cofactor] THEN ASM_SIMP_TAC[LAMBDA_BETA] THEN + MATCH_MP_TAC CONTINUOUS_LIFT_DET THEN REPEAT STRIP_TAC THEN + ASM_SIMP_TAC[LAMBDA_BETA] THEN + REPEAT(W(fun (asl,w) -> + let t = find_term is_cond w in + ASM_CASES_TAC (lhand(rator t)) THEN + ASM_REWRITE_TAC[CONTINUOUS_CONST]))); + REWRITE_TAC[MATRIX_CMUL_COMPONENT; LIFT_CMUL] THEN + MATCH_MP_TAC CONTINUOUS_MUL THEN REWRITE_TAC[o_DEF] THEN CONJ_TAC THENL + [MATCH_MP_TAC CONTINUOUS_LIFT_POW THEN + MATCH_MP_TAC CONTINUOUS_LIFT_DET THEN REPEAT STRIP_TAC; + ALL_TAC]] THEN + REWRITE_TAC[MATRIX_ADD_COMPONENT; MATRIX_CMUL_COMPONENT] THEN + ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN + REWRITE_TAC[LIFT_ADD; LIFT_CMUL; LIFT_DROP] THEN + SIMP_TAC[CONTINUOUS_ADD; CONTINUOUS_CONST; CONTINUOUS_CMUL; + CONTINUOUS_AT_ID]);; + +(* ------------------------------------------------------------------------- *) +(* Infinite sums of vectors. Allow general starting point (and more). *) +(* ------------------------------------------------------------------------- *) + +parse_as_infix("sums",(12,"right"));; + +let sums = new_definition + `(f sums l) s = ((\n. vsum(s INTER (0..n)) f) --> l) sequentially`;; + +let infsum = new_definition + `infsum s f = @l. (f sums l) s`;; + +let summable = new_definition + `summable s f = ?l. (f sums l) s`;; + +let SUMS_SUMMABLE = prove + (`!f l s. (f sums l) s ==> summable s f`, + REWRITE_TAC[summable] THEN MESON_TAC[]);; + +let SUMS_INFSUM = prove + (`!f s. (f sums (infsum s f)) s <=> summable s f`, + REWRITE_TAC[infsum; summable] THEN MESON_TAC[]);; + +let SUMS_LIM = prove + (`!f:num->real^N s. + (f sums lim sequentially (\n. vsum (s INTER (0..n)) f)) s + <=> summable s f`, + GEN_TAC THEN GEN_TAC THEN EQ_TAC THENL [MESON_TAC[summable]; + REWRITE_TAC[summable; sums] THEN STRIP_TAC THEN REWRITE_TAC[lim] THEN + ASM_MESON_TAC[]]);; + +let FINITE_INTER_NUMSEG = prove + (`!s m n. FINITE(s INTER (m..n))`, + MESON_TAC[FINITE_SUBSET; FINITE_NUMSEG; INTER_SUBSET]);; + +let SERIES_FROM = prove + (`!f l k. (f sums l) (from k) = ((\n. vsum(k..n) f) --> l) sequentially`, + REPEAT GEN_TAC THEN REWRITE_TAC[sums] THEN + AP_THM_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN ABS_TAC THEN + AP_THM_TAC THEN AP_TERM_TAC THEN + REWRITE_TAC[EXTENSION; numseg; from; IN_ELIM_THM; IN_INTER] THEN ARITH_TAC);; + +let SERIES_UNIQUE = prove + (`!f:num->real^N l l' s. (f sums l) s /\ (f sums l') s ==> (l = l')`, + REWRITE_TAC[sums] THEN MESON_TAC[TRIVIAL_LIMIT_SEQUENTIALLY; LIM_UNIQUE]);; + +let INFSUM_UNIQUE = prove + (`!f:num->real^N l s. (f sums l) s ==> infsum s f = l`, + MESON_TAC[SERIES_UNIQUE; SUMS_INFSUM; summable]);; + +let SERIES_FINITE = prove + (`!f s. FINITE s ==> (f sums (vsum s f)) s`, + REPEAT GEN_TAC THEN REWRITE_TAC[num_FINITE; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `n:num` THEN REWRITE_TAC[sums; LIM_SEQUENTIALLY] THEN + DISCH_TAC THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN EXISTS_TAC `n:num` THEN + X_GEN_TAC `m:num` THEN DISCH_TAC THEN + SUBGOAL_THEN `s INTER (0..m) = s` + (fun th -> ASM_REWRITE_TAC[th; DIST_REFL]) THEN + REWRITE_TAC[EXTENSION; IN_INTER; IN_NUMSEG; LE_0] THEN + ASM_MESON_TAC[LE_TRANS]);; + +let SERIES_LINEAR = prove + (`!f h l s. (f sums l) s /\ linear h ==> ((\n. h(f n)) sums h l) s`, + SIMP_TAC[sums; LIM_LINEAR; FINITE_INTER; FINITE_NUMSEG; + GSYM(REWRITE_RULE[o_DEF] LINEAR_VSUM)]);; + +let SERIES_0 = prove + (`!s. ((\n. vec 0) sums (vec 0)) s`, + REWRITE_TAC[sums; VSUM_0; LIM_CONST]);; + +let SERIES_ADD = prove + (`!x x0 y y0 s. + (x sums x0) s /\ (y sums y0) s ==> ((\n. x n + y n) sums (x0 + y0)) s`, + SIMP_TAC[sums; FINITE_INTER_NUMSEG; VSUM_ADD; LIM_ADD]);; + +let SERIES_SUB = prove + (`!x x0 y y0 s. + (x sums x0) s /\ (y sums y0) s ==> ((\n. x n - y n) sums (x0 - y0)) s`, + SIMP_TAC[sums; FINITE_INTER_NUMSEG; VSUM_SUB; LIM_SUB]);; + +let SERIES_CMUL = prove + (`!x x0 c s. (x sums x0) s ==> ((\n. c % x n) sums (c % x0)) s`, + SIMP_TAC[sums; FINITE_INTER_NUMSEG; VSUM_LMUL; LIM_CMUL]);; + +let SERIES_NEG = prove + (`!x x0 s. (x sums x0) s ==> ((\n. --(x n)) sums (--x0)) s`, + SIMP_TAC[sums; FINITE_INTER_NUMSEG; VSUM_NEG; LIM_NEG]);; + +let SUMS_IFF = prove + (`!f g k. (!x. x IN k ==> f x = g x) ==> ((f sums l) k <=> (g sums l) k)`, + REPEAT STRIP_TAC THEN REWRITE_TAC[sums] THEN + AP_THM_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN ABS_TAC THEN + MATCH_MP_TAC VSUM_EQ THEN ASM_SIMP_TAC[IN_INTER]);; + +let SUMS_EQ = prove + (`!f g k. (!x. x IN k ==> f x = g x) /\ (f sums l) k ==> (g sums l) k`, + MESON_TAC[SUMS_IFF]);; + +let SUMS_0 = prove + (`!f:num->real^N s. (!n. n IN s ==> f n = vec 0) ==> (f sums vec 0) s`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC SUMS_EQ THEN + EXISTS_TAC `\n:num. vec 0:real^N` THEN ASM_SIMP_TAC[SERIES_0]);; + +let SERIES_FINITE_SUPPORT = prove + (`!f:num->real^N s k. + FINITE (s INTER k) /\ (!x. ~(x IN s INTER k) ==> f x = vec 0) + ==> (f sums vsum (s INTER k) f) k`, + REWRITE_TAC[sums; LIM_SEQUENTIALLY] THEN REPEAT STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o ISPEC `\x:num. x` o MATCH_MP UPPER_BOUND_FINITE_SET) THEN + 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 `vsum (k INTER (0..n)) (f:num->real^N) = vsum(s INTER k) f` + (fun th -> ASM_REWRITE_TAC[DIST_REFL; th]) THEN + MATCH_MP_TAC VSUM_SUPERSET THEN + ASM_SIMP_TAC[SUBSET; IN_INTER; IN_NUMSEG; LE_0] THEN + ASM_MESON_TAC[IN_INTER; LE_TRANS]);; + +let SERIES_COMPONENT = prove + (`!f s l:real^N k. (f sums l) s /\ 1 <= k /\ k <= dimindex(:N) + ==> ((\i. lift(f(i)$k)) sums lift(l$k)) s`, + REPEAT GEN_TAC THEN REWRITE_TAC[sums] THEN STRIP_TAC THEN + ONCE_REWRITE_TAC[GSYM o_DEF] THEN + ASM_SIMP_TAC[GSYM LIFT_SUM; GSYM VSUM_COMPONENT; + FINITE_INTER; FINITE_NUMSEG] THEN + ASM_SIMP_TAC[o_DEF; LIM_COMPONENT]);; + +let SERIES_DIFFS = prove + (`!f:num->real^N k. + (f --> vec 0) sequentially + ==> ((\n. f(n) - f(n + 1)) sums f(k)) (from k)`, + REWRITE_TAC[sums; FROM_INTER_NUMSEG; VSUM_DIFFS] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC LIM_TRANSFORM_EVENTUALLY THEN + EXISTS_TAC `\n. (f:num->real^N) k - f(n + 1)` THEN CONJ_TAC THENL + [REWRITE_TAC[EVENTUALLY_SEQUENTIALLY] THEN EXISTS_TAC `k:num` THEN + SIMP_TAC[]; + GEN_REWRITE_TAC LAND_CONV [GSYM VECTOR_SUB_RZERO] THEN + MATCH_MP_TAC LIM_SUB THEN REWRITE_TAC[LIM_CONST] THEN + MATCH_MP_TAC SEQ_OFFSET THEN ASM_REWRITE_TAC[]]);; + +let SERIES_TRIVIAL = prove + (`!f. (f sums vec 0) {}`, + REWRITE_TAC[sums; INTER_EMPTY; VSUM_CLAUSES; LIM_CONST]);; + +let SERIES_RESTRICT = prove + (`!f k l:real^N. + ((\n. if n IN k then f(n) else vec 0) sums l) (:num) <=> + (f sums l) k`, + REPEAT GEN_TAC THEN REWRITE_TAC[sums] THEN + AP_THM_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN + REWRITE_TAC[FUN_EQ_THM; INTER_UNIV] THEN GEN_TAC THEN + MATCH_MP_TAC(MESON[] `vsum s f = vsum t f /\ vsum t f = vsum t g + ==> vsum s f = vsum t g`) THEN + CONJ_TAC THENL + [MATCH_MP_TAC VSUM_SUPERSET THEN SET_TAC[]; + MATCH_MP_TAC VSUM_EQ THEN SIMP_TAC[IN_INTER]]);; + +let SERIES_VSUM = prove + (`!f l k s. FINITE s /\ s SUBSET k /\ (!x. ~(x IN s) ==> f x = vec 0) /\ + vsum s f = l ==> (f sums l) k`, + REPEAT STRIP_TAC THEN EXPAND_TAC "l" THEN + SUBGOAL_THEN `s INTER k = s:num->bool` ASSUME_TAC THENL + [ASM SET_TAC []; ASM_MESON_TAC [SERIES_FINITE_SUPPORT]]);; + +let SUMS_REINDEX = prove + (`!k a l n. ((\x. a(x + k)) sums l) (from n) <=> (a sums l) (from(n + k))`, + REPEAT GEN_TAC THEN REWRITE_TAC[sums; FROM_INTER_NUMSEG] THEN + REPEAT GEN_TAC THEN REWRITE_TAC[GSYM VSUM_OFFSET] THEN + REWRITE_TAC[LIM_SEQUENTIALLY] THEN + ASM_MESON_TAC[ARITH_RULE `N + k:num <= n ==> n = (n - k) + k /\ N <= n - k`; + ARITH_RULE `N + k:num <= n ==> N <= n + k`]);; + +(* ------------------------------------------------------------------------- *) +(* Similar combining theorems just for summability. *) +(* ------------------------------------------------------------------------- *) + +let SUMMABLE_LINEAR = prove + (`!f h s. summable s f /\ linear h ==> summable s (\n. h(f n))`, + REWRITE_TAC[summable] THEN MESON_TAC[SERIES_LINEAR]);; + +let SUMMABLE_0 = prove + (`!s. summable s (\n. vec 0)`, + REWRITE_TAC[summable] THEN MESON_TAC[SERIES_0]);; + +let SUMMABLE_ADD = prove + (`!x y s. summable s x /\ summable s y ==> summable s (\n. x n + y n)`, + REWRITE_TAC[summable] THEN MESON_TAC[SERIES_ADD]);; + +let SUMMABLE_SUB = prove + (`!x y s. summable s x /\ summable s y ==> summable s (\n. x n - y n)`, + REWRITE_TAC[summable] THEN MESON_TAC[SERIES_SUB]);; + +let SUMMABLE_CMUL = prove + (`!s x c. summable s x ==> summable s (\n. c % x n)`, + REWRITE_TAC[summable] THEN MESON_TAC[SERIES_CMUL]);; + +let SUMMABLE_NEG = prove + (`!x s. summable s x ==> summable s (\n. --(x n))`, + REWRITE_TAC[summable] THEN MESON_TAC[SERIES_NEG]);; + +let SUMMABLE_IFF = prove + (`!f g k. (!x. x IN k ==> f x = g x) ==> (summable k f <=> summable k g)`, + REWRITE_TAC[summable] THEN MESON_TAC[SUMS_IFF]);; + +let SUMMABLE_EQ = prove + (`!f g k. (!x. x IN k ==> f x = g x) /\ summable k f ==> summable k g`, + REWRITE_TAC[summable] THEN MESON_TAC[SUMS_EQ]);; + +let SUMMABLE_COMPONENT = prove + (`!f:num->real^N s k. + summable s f /\ 1 <= k /\ k <= dimindex(:N) + ==> summable s (\i. lift(f(i)$k))`, + REPEAT STRIP_TAC THEN + FIRST_X_ASSUM(X_CHOOSE_TAC `l:real^N` o REWRITE_RULE[summable]) THEN + REWRITE_TAC[summable] THEN EXISTS_TAC `lift((l:real^N)$k)` THEN + ASM_SIMP_TAC[SERIES_COMPONENT]);; + +let SERIES_SUBSET = prove + (`!x s t l. + s SUBSET t /\ + ((\i. if i IN s then x i else vec 0) sums l) t + ==> (x sums l) s`, + REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + REWRITE_TAC[sums] THEN MATCH_MP_TAC EQ_IMP THEN + AP_THM_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN ABS_TAC THEN + ASM_SIMP_TAC[GSYM VSUM_RESTRICT_SET; FINITE_INTER_NUMSEG] THEN + AP_THM_TAC THEN AP_TERM_TAC THEN POP_ASSUM MP_TAC THEN SET_TAC[]);; + +let SUMMABLE_SUBSET = prove + (`!x s t. + s SUBSET t /\ + summable t (\i. if i IN s then x i else vec 0) + ==> summable s x`, + REWRITE_TAC[summable] THEN MESON_TAC[SERIES_SUBSET]);; + +let SUMMABLE_TRIVIAL = prove + (`!f:num->real^N. summable {} f`, + GEN_TAC THEN REWRITE_TAC[summable] THEN EXISTS_TAC `vec 0:real^N` THEN + REWRITE_TAC[SERIES_TRIVIAL]);; + +let SUMMABLE_RESTRICT = prove + (`!f:num->real^N k. + summable (:num) (\n. if n IN k then f(n) else vec 0) <=> + summable k f`, + REWRITE_TAC[summable; SERIES_RESTRICT]);; + +let SUMS_FINITE_DIFF = prove + (`!f:num->real^N t s l. + t SUBSET s /\ FINITE t /\ (f sums l) s + ==> (f sums (l - vsum t f)) (s DIFF t)`, + REPEAT GEN_TAC THEN + REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + FIRST_ASSUM(MP_TAC o ISPEC `f:num->real^N` o MATCH_MP SERIES_FINITE) THEN + ONCE_REWRITE_TAC[GSYM SERIES_RESTRICT] THEN + REWRITE_TAC[IMP_IMP] THEN ONCE_REWRITE_TAC[CONJ_SYM] THEN + DISCH_THEN(MP_TAC o MATCH_MP SERIES_SUB) THEN + MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN + REWRITE_TAC[FUN_EQ_THM] THEN X_GEN_TAC `x:num` THEN REWRITE_TAC[IN_DIFF] THEN + FIRST_ASSUM(MP_TAC o SPEC `x:num` o GEN_REWRITE_RULE I [SUBSET]) THEN + MAP_EVERY ASM_CASES_TAC [`(x:num) IN s`; `(x:num) IN t`] THEN + ASM_REWRITE_TAC[] THEN VECTOR_ARITH_TAC);; + +let SUMS_FINITE_UNION = prove + (`!f:num->real^N s t l. + FINITE t /\ (f sums l) s + ==> (f sums (l + vsum (t DIFF s) f)) (s UNION t)`, + REPEAT GEN_TAC THEN + REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + FIRST_ASSUM(MP_TAC o SPEC `s:num->bool` o MATCH_MP FINITE_DIFF) THEN + DISCH_THEN(MP_TAC o ISPEC `f:num->real^N` o MATCH_MP SERIES_FINITE) THEN + ONCE_REWRITE_TAC[GSYM SERIES_RESTRICT] THEN + REWRITE_TAC[IMP_IMP] THEN ONCE_REWRITE_TAC[CONJ_SYM] THEN + DISCH_THEN(MP_TAC o MATCH_MP SERIES_ADD) THEN + MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN + REWRITE_TAC[FUN_EQ_THM] THEN X_GEN_TAC `x:num` THEN + REWRITE_TAC[IN_DIFF; IN_UNION] THEN + MAP_EVERY ASM_CASES_TAC [`(x:num) IN s`; `(x:num) IN t`] THEN + ASM_REWRITE_TAC[] THEN VECTOR_ARITH_TAC);; + +let SUMS_OFFSET = prove + (`!f:num->real^N l m n. + (f sums l) (from m) /\ m < n + ==> (f sums (l - vsum(m..(n-1)) f)) (from n)`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN `from n = from m DIFF (m..(n-1))` SUBST1_TAC THENL + [REWRITE_TAC[EXTENSION; IN_FROM; IN_DIFF; IN_NUMSEG] THEN ASM_ARITH_TAC; + MATCH_MP_TAC SUMS_FINITE_DIFF THEN ASM_REWRITE_TAC[FINITE_NUMSEG] THEN + SIMP_TAC[SUBSET; IN_FROM; IN_NUMSEG]]);; + +let SUMS_OFFSET_REV = prove + (`!f:num->real^N l m n. + (f sums l) (from m) /\ n < m + ==> (f sums (l + vsum(n..m-1) f)) (from n)`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`f:num->real^N`; `from m`; `n..m-1`; `l:real^N`] + SUMS_FINITE_UNION) THEN + ASM_REWRITE_TAC[FINITE_NUMSEG] THEN MATCH_MP_TAC EQ_IMP THEN + BINOP_TAC THENL [AP_TERM_TAC THEN AP_THM_TAC THEN AP_TERM_TAC; ALL_TAC] THEN + REWRITE_TAC[EXTENSION; IN_DIFF; IN_UNION; IN_FROM; IN_NUMSEG] THEN + ASM_ARITH_TAC);; + +let SUMMABLE_REINDEX = prove + (`!k a n. summable (from n) (\x. a (x + k)) <=> summable (from(n + k)) a`, + REWRITE_TAC[summable; GSYM SUMS_REINDEX]);; + +(* ------------------------------------------------------------------------- *) +(* Similar combining theorems for infsum. *) +(* ------------------------------------------------------------------------- *) + +let INFSUM_LINEAR = prove + (`!f h s. summable s f /\ linear h + ==> infsum s (\n. h(f n)) = h(infsum s f)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC INFSUM_UNIQUE THEN + MATCH_MP_TAC SERIES_LINEAR THEN ASM_REWRITE_TAC[SUMS_INFSUM]);; + +let INFSUM_0 = prove + (`infsum s (\i. vec 0) = vec 0`, + MATCH_MP_TAC INFSUM_UNIQUE THEN REWRITE_TAC[SERIES_0]);; + +let INFSUM_ADD = prove + (`!x y s. summable s x /\ summable s y + ==> infsum s (\i. x i + y i) = infsum s x + infsum s y`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC INFSUM_UNIQUE THEN + MATCH_MP_TAC SERIES_ADD THEN ASM_REWRITE_TAC[SUMS_INFSUM]);; + +let INFSUM_SUB = prove + (`!x y s. summable s x /\ summable s y + ==> infsum s (\i. x i - y i) = infsum s x - infsum s y`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC INFSUM_UNIQUE THEN + MATCH_MP_TAC SERIES_SUB THEN ASM_REWRITE_TAC[SUMS_INFSUM]);; + +let INFSUM_CMUL = prove + (`!s x c. summable s x ==> infsum s (\n. c % x n) = c % infsum s x`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC INFSUM_UNIQUE THEN + MATCH_MP_TAC SERIES_CMUL THEN ASM_REWRITE_TAC[SUMS_INFSUM]);; + +let INFSUM_NEG = prove + (`!s x. summable s x ==> infsum s (\n. --(x n)) = --(infsum s x)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC INFSUM_UNIQUE THEN + MATCH_MP_TAC SERIES_NEG THEN ASM_REWRITE_TAC[SUMS_INFSUM]);; + +let INFSUM_EQ = prove + (`!f g k. summable k f /\ summable k g /\ (!x. x IN k ==> f x = g x) + ==> infsum k f = infsum k g`, + REPEAT STRIP_TAC THEN REWRITE_TAC[infsum] THEN + AP_TERM_TAC THEN ABS_TAC THEN ASM_MESON_TAC[SUMS_EQ; SUMS_INFSUM]);; + +let INFSUM_RESTRICT = prove + (`!k a:num->real^N. + infsum (:num) (\n. if n IN k then a n else vec 0) = infsum k a`, + REPEAT GEN_TAC THEN + MP_TAC(ISPECL [`a:num->real^N`; `k:num->bool`] SUMMABLE_RESTRICT) THEN + ASM_CASES_TAC `summable k (a:num->real^N)` THEN ASM_REWRITE_TAC[] THEN + STRIP_TAC THENL + [MATCH_MP_TAC INFSUM_UNIQUE THEN + ASM_REWRITE_TAC[SERIES_RESTRICT; SUMS_INFSUM]; + RULE_ASSUM_TAC(REWRITE_RULE[summable; NOT_EXISTS_THM]) THEN + ASM_REWRITE_TAC[infsum]]);; + +let PARTIAL_SUMS_COMPONENT_LE_INFSUM = prove + (`!f:num->real^N s k n. + 1 <= k /\ k <= dimindex(:N) /\ + (!i. i IN s ==> &0 <= (f i)$k) /\ + summable s f + ==> (vsum (s INTER (0..n)) f)$k <= (infsum s f)$k`, + REPEAT GEN_TAC THEN REWRITE_TAC[GSYM SUMS_INFSUM] THEN + REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + REWRITE_TAC[sums; LIM_SEQUENTIALLY] THEN DISCH_TAC THEN + REWRITE_TAC[GSYM REAL_NOT_LT] THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC + `vsum (s INTER (0..n)) (f:num->real^N)$k - (infsum s f)$k`) THEN + ASM_REWRITE_TAC[REAL_SUB_LT] THEN + DISCH_THEN(X_CHOOSE_THEN `N:num` (MP_TAC o SPEC `N + n:num`)) THEN + REWRITE_TAC[LE_ADD; REAL_NOT_LT; dist] THEN + MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `abs((vsum (s INTER (0..N + n)) f - infsum s f:real^N)$k)` THEN + ASM_SIMP_TAC[COMPONENT_LE_NORM] THEN REWRITE_TAC[VECTOR_SUB_COMPONENT] THEN + MATCH_MP_TAC(REAL_ARITH `s < a /\ a <= b ==> a - s <= abs(b - s)`) THEN + ASM_REWRITE_TAC[] THEN ONCE_REWRITE_TAC[ADD_SYM] THEN + SIMP_TAC[NUMSEG_ADD_SPLIT; LE_0; UNION_OVER_INTER] THEN + W(MP_TAC o PART_MATCH (lhs o rand) VSUM_UNION o lhand o rand o snd) THEN + ANTS_TAC THENL + [SIMP_TAC[FINITE_INTER; FINITE_NUMSEG; DISJOINT; EXTENSION] THEN + REWRITE_TAC[IN_INTER; NOT_IN_EMPTY; IN_NUMSEG] THEN ARITH_TAC; + DISCH_THEN SUBST1_TAC THEN + REWRITE_TAC[REAL_LE_ADDR; VECTOR_ADD_COMPONENT] THEN + ASM_SIMP_TAC[VSUM_COMPONENT] THEN MATCH_MP_TAC SUM_POS_LE THEN + ASM_SIMP_TAC[FINITE_INTER; IN_INTER; FINITE_NUMSEG]]);; + +let PARTIAL_SUMS_DROP_LE_INFSUM = prove + (`!f s n. + (!i. i IN s ==> &0 <= drop(f i)) /\ + summable s f + ==> drop(vsum (s INTER (0..n)) f) <= drop(infsum s f)`, + REPEAT STRIP_TAC THEN REWRITE_TAC[drop] THEN + MATCH_MP_TAC PARTIAL_SUMS_COMPONENT_LE_INFSUM THEN + ASM_REWRITE_TAC[DIMINDEX_1; LE_REFL; GSYM drop]);; + +(* ------------------------------------------------------------------------- *) +(* Cauchy criterion for series. *) +(* ------------------------------------------------------------------------- *) + +let SEQUENCE_CAUCHY_WLOG = prove + (`!P s. (!m n:num. P m /\ P n ==> dist(s m,s n) < e) <=> + (!m n. P m /\ P n /\ m <= n ==> dist(s m,s n) < e)`, + MESON_TAC[DIST_SYM; LE_CASES]);; + +let VSUM_DIFF_LEMMA = prove + (`!f:num->real^N k m n. + m <= n + ==> vsum(k INTER (0..n)) f - vsum(k INTER (0..m)) f = + vsum(k INTER (m+1..n)) f`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`f:num->real^N`; `k INTER (0..n)`; `k INTER (0..m)`] + VSUM_DIFF) THEN + ANTS_TAC THENL + [SIMP_TAC[FINITE_INTER; FINITE_NUMSEG] THEN MATCH_MP_TAC + (SET_RULE `s SUBSET t ==> (u INTER s SUBSET u INTER t)`) THEN + REWRITE_TAC[SUBSET; IN_NUMSEG] THEN POP_ASSUM MP_TAC THEN ARITH_TAC; + DISCH_THEN(SUBST1_TAC o SYM) THEN AP_THM_TAC THEN AP_TERM_TAC THEN + REWRITE_TAC[SET_RULE + `(k INTER s) DIFF (k INTER t) = k INTER (s DIFF t)`] THEN + AP_TERM_TAC THEN REWRITE_TAC[EXTENSION; IN_DIFF; IN_NUMSEG] THEN + POP_ASSUM MP_TAC THEN ARITH_TAC]);; + +let NORM_VSUM_TRIVIAL_LEMMA = prove + (`!e. &0 < e ==> (P ==> norm(vsum(s INTER (m..n)) f) < e <=> + P ==> n < m \/ norm(vsum(s INTER (m..n)) f) < e)`, + REPEAT STRIP_TAC THEN ASM_CASES_TAC `n:num < m` THEN ASM_REWRITE_TAC[] THEN + FIRST_X_ASSUM(SUBST1_TAC o GEN_REWRITE_RULE I [GSYM NUMSEG_EMPTY]) THEN + ASM_REWRITE_TAC[VSUM_CLAUSES; NORM_0; INTER_EMPTY]);; + +let SERIES_CAUCHY = prove + (`!f s. (?l. (f sums l) s) = + !e. &0 < e + ==> ?N. !m n. m >= N + ==> norm(vsum(s INTER (m..n)) f) < e`, + REPEAT GEN_TAC THEN REWRITE_TAC[sums; CONVERGENT_EQ_CAUCHY; cauchy] THEN + REWRITE_TAC[SEQUENCE_CAUCHY_WLOG] THEN ONCE_REWRITE_TAC[DIST_SYM] THEN + SIMP_TAC[dist; VSUM_DIFF_LEMMA; NORM_VSUM_TRIVIAL_LEMMA] THEN + REWRITE_TAC[GE; TAUT `a ==> b \/ c <=> a /\ ~b ==> c`] THEN + REWRITE_TAC[NOT_LT; ARITH_RULE + `(N <= m /\ N <= n /\ m <= n) /\ m + 1 <= n <=> + N + 1 <= m + 1 /\ m + 1 <= n`] THEN + AP_TERM_TAC THEN REWRITE_TAC[FUN_EQ_THM] THEN X_GEN_TAC `e:real` THEN + ASM_CASES_TAC `&0 < e` THEN ASM_REWRITE_TAC[] THEN + EQ_TAC THEN DISCH_THEN(X_CHOOSE_TAC `N:num`) THENL + [EXISTS_TAC `N + 1`; EXISTS_TAC `N:num`] THEN + REPEAT STRIP_TAC THEN + ASM_SIMP_TAC[ARITH_RULE `N + 1 <= m + 1 ==> N <= m + 1`] THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`m - 1`; `n:num`]) THEN + SUBGOAL_THEN `m - 1 + 1 = m` SUBST_ALL_TAC THENL + [ALL_TAC; ANTS_TAC THEN SIMP_TAC[]] THEN + ASM_ARITH_TAC);; + +let SUMMABLE_CAUCHY = prove + (`!f s. summable s f <=> + !e. &0 < e + ==> ?N. !m n. m >= N ==> norm(vsum(s INTER (m..n)) f) < e`, + REWRITE_TAC[summable; GSYM SERIES_CAUCHY]);; + +let SUMMABLE_IFF_EVENTUALLY = prove + (`!f g k. (?N. !n. N <= n /\ n IN k ==> f n = g n) + ==> (summable k f <=> summable k g)`, + REWRITE_TAC[summable; SERIES_CAUCHY] THEN REPEAT GEN_TAC THEN + DISCH_THEN(X_CHOOSE_THEN `N0:num` STRIP_ASSUME_TAC) THEN + AP_TERM_TAC THEN REWRITE_TAC[FUN_EQ_THM] THEN X_GEN_TAC `e:real` THEN + AP_TERM_TAC THEN EQ_TAC THEN + DISCH_THEN(X_CHOOSE_THEN `N1:num` + (fun th -> EXISTS_TAC `N0 + N1:num` THEN MP_TAC th)) THEN + REPEAT(MATCH_MP_TAC MONO_FORALL THEN GEN_TAC) THEN + DISCH_THEN(fun th -> DISCH_TAC THEN MP_TAC th) THEN + (ANTS_TAC THENL [ASM_ARITH_TAC; ALL_TAC]) THEN + MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_TERM_TAC THEN AP_TERM_TAC THEN + MATCH_MP_TAC VSUM_EQ THEN ASM_SIMP_TAC[IN_INTER; IN_NUMSEG] THEN + REPEAT STRIP_TAC THENL [ALL_TAC; CONV_TAC SYM_CONV] THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[] THEN + ASM_ARITH_TAC);; + +let SUMMABLE_EQ_EVENTUALLY = prove + (`!f g k. (?N. !n. N <= n /\ n IN k ==> f n = g n) /\ summable k f + ==> summable k g`, + MESON_TAC[SUMMABLE_IFF_EVENTUALLY]);; + +let SUMMABLE_IFF_COFINITE = prove + (`!f s t. FINITE((s DIFF t) UNION (t DIFF s)) + ==> (summable s f <=> summable t f)`, + REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[GSYM SUMMABLE_RESTRICT] THEN + MATCH_MP_TAC SUMMABLE_IFF_EVENTUALLY THEN + FIRST_ASSUM(MP_TAC o ISPEC `\x:num.x` o MATCH_MP UPPER_BOUND_FINITE_SET) THEN + DISCH_THEN(X_CHOOSE_THEN `N:num` MP_TAC) THEN REWRITE_TAC[IN_UNIV] THEN + DISCH_TAC THEN EXISTS_TAC `N + 1` THEN + REWRITE_TAC[ARITH_RULE `N + 1 <= n <=> ~(n <= N)`] THEN ASM SET_TAC[]);; + +let SUMMABLE_EQ_COFINITE = prove + (`!f s t. FINITE((s DIFF t) UNION (t DIFF s)) /\ summable s f + ==> summable t f`, + MESON_TAC[SUMMABLE_IFF_COFINITE]);; + +let SUMMABLE_FROM_ELSEWHERE = prove + (`!f m n. summable (from m) f ==> summable (from n) f`, + REPEAT GEN_TAC THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] SUMMABLE_EQ_COFINITE) THEN + MATCH_MP_TAC FINITE_SUBSET THEN EXISTS_TAC `0..(m+n)` THEN + SIMP_TAC[FINITE_NUMSEG; SUBSET; IN_NUMSEG; IN_UNION; IN_DIFF; IN_FROM] THEN + ARITH_TAC);; + +(* ------------------------------------------------------------------------- *) +(* Uniform vesion of Cauchy criterion. *) +(* ------------------------------------------------------------------------- *) + +let SERIES_CAUCHY_UNIFORM = prove + (`!P f:A->num->real^N k. + (?l. !e. &0 < e + ==> ?N. !n x. N <= n /\ P x + ==> dist(vsum(k INTER (0..n)) (f x), + l x) < e) <=> + (!e. &0 < e ==> ?N. !m n x. N <= m /\ P x + ==> norm(vsum(k INTER (m..n)) (f x)) < e)`, + REPEAT GEN_TAC THEN + REWRITE_TAC[sums; UNIFORMLY_CONVERGENT_EQ_CAUCHY; cauchy] THEN + ONCE_REWRITE_TAC[MESON[] + `(!m n:num y. N <= m /\ N <= n /\ P y ==> Q m n y) <=> + (!y. P y ==> !m n. N <= m /\ N <= n ==> Q m n y)`] THEN + REWRITE_TAC[SEQUENCE_CAUCHY_WLOG] THEN ONCE_REWRITE_TAC[DIST_SYM] THEN + SIMP_TAC[dist; VSUM_DIFF_LEMMA; NORM_VSUM_TRIVIAL_LEMMA] THEN + REWRITE_TAC[GE; TAUT `a ==> b \/ c <=> a /\ ~b ==> c`] THEN + REWRITE_TAC[NOT_LT; ARITH_RULE + `(N <= m /\ N <= n /\ m <= n) /\ m + 1 <= n <=> + N + 1 <= m + 1 /\ m + 1 <= n`] THEN + AP_TERM_TAC THEN REWRITE_TAC[FUN_EQ_THM] THEN X_GEN_TAC `e:real` THEN + ASM_CASES_TAC `&0 < e` THEN ASM_REWRITE_TAC[] THEN + EQ_TAC THEN DISCH_THEN(X_CHOOSE_TAC `N:num`) THENL + [EXISTS_TAC `N + 1`; EXISTS_TAC `N:num`] THEN + REPEAT STRIP_TAC THEN + ASM_SIMP_TAC[ARITH_RULE `N + 1 <= m + 1 ==> N <= m + 1`] THEN + FIRST_X_ASSUM(MP_TAC o SPEC `x:A`) THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(MP_TAC o SPECL [`m - 1`; `n:num`]) THEN + SUBGOAL_THEN `m - 1 + 1 = m` SUBST_ALL_TAC THENL + [ALL_TAC; ANTS_TAC THEN SIMP_TAC[]] THEN + ASM_ARITH_TAC);; + +(* ------------------------------------------------------------------------- *) +(* So trivially, terms of a convergent series go to zero. *) +(* ------------------------------------------------------------------------- *) + +let SERIES_GOESTOZERO = prove + (`!s x. summable s x + ==> !e. &0 < e + ==> eventually (\n. n IN s ==> norm(x n) < e) sequentially`, + REPEAT GEN_TAC THEN REWRITE_TAC[summable; SERIES_CAUCHY] THEN + MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `e:real` THEN + MATCH_MP_TAC MONO_IMP THEN REWRITE_TAC[EVENTUALLY_SEQUENTIALLY] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `N:num` THEN DISCH_TAC THEN + X_GEN_TAC `n:num` THEN REPEAT STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`n:num`; `n:num`]) THEN + ASM_SIMP_TAC[NUMSEG_SING; GE; SET_RULE `n IN s ==> s INTER {n} = {n}`] THEN + REWRITE_TAC[VSUM_SING]);; + +let SUMMABLE_IMP_TOZERO = prove + (`!f:num->real^N k. + summable k f + ==> ((\n. if n IN k then f(n) else vec 0) --> vec 0) sequentially`, + REPEAT GEN_TAC THEN GEN_REWRITE_TAC LAND_CONV [GSYM SUMMABLE_RESTRICT] THEN + REWRITE_TAC[summable; LIM_SEQUENTIALLY; INTER_UNIV; sums] THEN + DISCH_THEN(X_CHOOSE_TAC `l:real^N`) 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; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `N:num` THEN DISCH_TAC THEN EXISTS_TAC `N + 1` THEN + X_GEN_TAC `n:num` THEN DISCH_TAC THEN + FIRST_X_ASSUM(fun th -> + MP_TAC(SPEC `n - 1` th) THEN MP_TAC(SPEC `n:num` th)) THEN + ASM_SIMP_TAC[ARITH_RULE `N + 1 <= n ==> N <= n /\ N <= n - 1`] THEN + ABBREV_TAC `m = n - 1` THEN + SUBGOAL_THEN `n = SUC m` SUBST1_TAC THENL + [ASM_ARITH_TAC; ALL_TAC] THEN + REWRITE_TAC[VSUM_CLAUSES_NUMSEG; LE_0] THEN + REWRITE_TAC[NORM_ARITH `dist(x,vec 0) = norm x`] THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[NORM_0] THEN CONV_TAC NORM_ARITH);; + +let SUMMABLE_IMP_BOUNDED = prove + (`!f:num->real^N k. summable k f ==> bounded (IMAGE f k)`, + REPEAT GEN_TAC THEN + DISCH_THEN(MP_TAC o MATCH_MP SUMMABLE_IMP_TOZERO) THEN + DISCH_THEN(MP_TAC o MATCH_MP CONVERGENT_IMP_BOUNDED) THEN + REWRITE_TAC[BOUNDED_POS; FORALL_IN_IMAGE; IN_UNIV] THEN + MATCH_MP_TAC MONO_EXISTS THEN MESON_TAC[REAL_LT_IMP_LE; NORM_0]);; + +let SUMMABLE_IMP_SUMS_BOUNDED = prove + (`!f:num->real^N k. + summable (from k) f ==> bounded { vsum(k..n) f | n IN (:num) }`, + REWRITE_TAC[summable; sums; LEFT_IMP_EXISTS_THM] THEN REPEAT GEN_TAC THEN + DISCH_THEN(MP_TAC o MATCH_MP CONVERGENT_IMP_BOUNDED) THEN + REWRITE_TAC[FROM_INTER_NUMSEG; SIMPLE_IMAGE]);; + +(* ------------------------------------------------------------------------- *) +(* Comparison test. *) +(* ------------------------------------------------------------------------- *) + +let SERIES_COMPARISON = prove + (`!f g s. (?l. ((lift o g) sums l) s) /\ + (?N. !n. n >= N /\ n IN s ==> norm(f n) <= g n) + ==> ?l:real^N. (f sums l) s`, + REPEAT GEN_TAC THEN REWRITE_TAC[SERIES_CAUCHY] THEN + DISCH_THEN(CONJUNCTS_THEN2 MP_TAC (X_CHOOSE_TAC `N1:num`)) THEN + MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `e:real` THEN + MATCH_MP_TAC MONO_IMP THEN REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_TAC `N2:num`) THEN + EXISTS_TAC `N1 + N2:num` THEN + MAP_EVERY X_GEN_TAC [`m:num`; `n:num`] THEN DISCH_TAC THEN + MATCH_MP_TAC REAL_LET_TRANS THEN + EXISTS_TAC `norm (vsum (s INTER (m .. n)) (lift o g))` THEN CONJ_TAC THENL + [SIMP_TAC[GSYM LIFT_SUM; FINITE_INTER_NUMSEG; NORM_LIFT] THEN + MATCH_MP_TAC(REAL_ARITH `x <= a ==> x <= abs(a)`) THEN + MATCH_MP_TAC VSUM_NORM_LE THEN + REWRITE_TAC[FINITE_INTER_NUMSEG; IN_INTER; IN_NUMSEG] THEN + ASM_MESON_TAC[ARITH_RULE `m >= N1 + N2:num /\ m <= x ==> x >= N1`]; + ASM_MESON_TAC[ARITH_RULE `m >= N1 + N2:num ==> m >= N2`]]);; + +let SUMMABLE_COMPARISON = prove + (`!f g s. summable s (lift o g) /\ + (?N. !n. n >= N /\ n IN s ==> norm(f n) <= g n) + ==> summable s f`, + REWRITE_TAC[summable; SERIES_COMPARISON]);; + +let SERIES_LIFT_ABSCONV_IMP_CONV = prove + (`!x:num->real^N k. summable k (\n. lift(norm(x n))) ==> summable k x`, + REWRITE_TAC[summable] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC SERIES_COMPARISON THEN + EXISTS_TAC `\n:num. norm(x n:real^N)` THEN + ASM_REWRITE_TAC[o_DEF; REAL_LE_REFL] THEN ASM_MESON_TAC[]);; + +let SUMMABLE_SUBSET_ABSCONV = prove + (`!x:num->real^N s t. + summable s (\n. lift(norm(x n))) /\ t SUBSET s + ==> summable t (\n. lift(norm(x n)))`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC SUMMABLE_SUBSET THEN + EXISTS_TAC `s:num->bool` THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[summable] THEN MATCH_MP_TAC SERIES_COMPARISON THEN + EXISTS_TAC `\n:num. norm(x n:real^N)` THEN + ASM_REWRITE_TAC[o_DEF; GSYM summable] THEN + EXISTS_TAC `0` THEN REPEAT STRIP_TAC THEN COND_CASES_TAC THEN + REWRITE_TAC[REAL_LE_REFL; NORM_LIFT; REAL_ABS_NORM; NORM_0; NORM_POS_LE]);; + +(* ------------------------------------------------------------------------- *) +(* Uniform version of comparison test. *) +(* ------------------------------------------------------------------------- *) + +let SERIES_COMPARISON_UNIFORM = prove + (`!f g P s. (?l. ((lift o g) sums l) s) /\ + (?N. !n x. N <= n /\ n IN s /\ P x ==> norm(f x n) <= g n) + ==> ?l:A->real^N. + !e. &0 < e + ==> ?N. !n x. N <= n /\ P x + ==> dist(vsum(s INTER (0..n)) (f x), + l x) < e`, + REPEAT GEN_TAC THEN SIMP_TAC[GE; SERIES_CAUCHY; SERIES_CAUCHY_UNIFORM] THEN + DISCH_THEN(CONJUNCTS_THEN2 MP_TAC (X_CHOOSE_TAC `N1:num`)) THEN + MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `e:real` THEN + MATCH_MP_TAC MONO_IMP THEN REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_TAC `N2:num`) THEN + EXISTS_TAC `N1 + N2:num` THEN + MAP_EVERY X_GEN_TAC [`m:num`; `n:num`; `x:A`] THEN DISCH_TAC THEN + MATCH_MP_TAC REAL_LET_TRANS THEN + EXISTS_TAC `norm (vsum (s INTER (m .. n)) (lift o g))` THEN CONJ_TAC THENL + [SIMP_TAC[GSYM LIFT_SUM; FINITE_INTER_NUMSEG; NORM_LIFT] THEN + MATCH_MP_TAC(REAL_ARITH `x <= a ==> x <= abs(a)`) THEN + MATCH_MP_TAC VSUM_NORM_LE THEN + REWRITE_TAC[FINITE_INTER_NUMSEG; IN_INTER; IN_NUMSEG] THEN + ASM_MESON_TAC[ARITH_RULE `N1 + N2:num <= m /\ m <= x ==> N1 <= x`]; + ASM_MESON_TAC[ARITH_RULE `N1 + N2:num <= m ==> N2 <= m`]]);; + +(* ------------------------------------------------------------------------- *) +(* Ratio test. *) +(* ------------------------------------------------------------------------- *) + +let SERIES_RATIO = prove + (`!c a s N. + c < &1 /\ + (!n. n >= N ==> norm(a(SUC n)) <= c * norm(a(n))) + ==> ?l:real^N. (a sums l) s`, + REWRITE_TAC[GE] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC SERIES_COMPARISON THEN + DISJ_CASES_TAC(REAL_ARITH `c <= &0 \/ &0 < c`) THENL + [EXISTS_TAC `\n:num. &0` THEN REWRITE_TAC[o_DEF; LIFT_NUM] THEN + CONJ_TAC THENL [MESON_TAC[SERIES_0]; ALL_TAC] THEN + EXISTS_TAC `N + 1` THEN REWRITE_TAC[GE] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC `c * norm(a(n - 1):real^N)` THEN + CONJ_TAC THENL + [ASM_MESON_TAC[ARITH_RULE `N + 1 <= n ==> SUC(n - 1) = n /\ N <= n - 1`]; + ALL_TAC] THEN + MATCH_MP_TAC(REAL_ARITH `&0 <= --c * x ==> c * x <= &0`) THEN + MATCH_MP_TAC REAL_LE_MUL THEN REWRITE_TAC[NORM_POS_LE] THEN + UNDISCH_TAC `c <= &0` THEN REAL_ARITH_TAC; + ASSUME_TAC(MATCH_MP REAL_LT_IMP_LE (ASSUME `&0 < c`))] THEN + EXISTS_TAC `\n. norm(a(N):real^N) * c pow (n - N)` THEN + REWRITE_TAC[] THEN CONJ_TAC THENL + [ALL_TAC; + EXISTS_TAC `N:num` THEN + SIMP_TAC[GE; LE_EXISTS; IMP_CONJ; ADD_SUB2; LEFT_IMP_EXISTS_THM] THEN + SUBGOAL_THEN `!d:num. norm(a(N + d):real^N) <= norm(a N) * c pow d` + (fun th -> MESON_TAC[th]) THEN INDUCT_TAC THEN + REWRITE_TAC[ADD_CLAUSES; real_pow; REAL_MUL_RID; REAL_LE_REFL] THEN + MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `c * norm((a:num->real^N) (N + d))` THEN + ASM_SIMP_TAC[LE_ADD] THEN ASM_MESON_TAC[REAL_LE_LMUL; REAL_MUL_AC]] THEN + GEN_REWRITE_TAC I [SERIES_CAUCHY] THEN X_GEN_TAC `e:real` THEN + SIMP_TAC[GSYM LIFT_SUM; FINITE_INTER; NORM_LIFT; FINITE_NUMSEG] THEN + DISCH_TAC THEN SIMP_TAC[SUM_LMUL; FINITE_INTER; FINITE_NUMSEG] THEN + ASM_CASES_TAC `(a:num->real^N) N = vec 0` THENL + [ASM_REWRITE_TAC[NORM_0; REAL_MUL_LZERO; REAL_ABS_NUM]; ALL_TAC] THEN + MP_TAC(SPECL [`c:real`; `((&1 - c) * e) / norm((a:num->real^N) N)`] + REAL_ARCH_POW_INV) THEN + ASM_SIMP_TAC[REAL_LT_DIV; REAL_LT_MUL; REAL_SUB_LT; NORM_POS_LT; GE] THEN + DISCH_THEN(X_CHOOSE_TAC `M:num`) THEN EXISTS_TAC `N + M:num` THEN + MAP_EVERY X_GEN_TAC [`m:num`; `n:num`] THEN DISCH_TAC THEN + MATCH_MP_TAC REAL_LET_TRANS THEN + EXISTS_TAC `abs(norm((a:num->real^N) N) * + sum(m..n) (\i. c pow (i - N)))` THEN + CONJ_TAC THENL + [REWRITE_TAC[REAL_ABS_MUL] THEN MATCH_MP_TAC REAL_LE_LMUL THEN + REWRITE_TAC[REAL_ABS_POS] THEN + MATCH_MP_TAC(REAL_ARITH `&0 <= x /\ x <= y ==> abs x <= abs y`) THEN + ASM_SIMP_TAC[SUM_POS_LE; FINITE_INTER_NUMSEG; REAL_POW_LE] THEN + MATCH_MP_TAC SUM_SUBSET THEN ASM_SIMP_TAC[REAL_POW_LE] THEN + REWRITE_TAC[FINITE_INTER_NUMSEG; FINITE_NUMSEG] THEN + REWRITE_TAC[IN_INTER; IN_DIFF] THEN MESON_TAC[]; + ALL_TAC] THEN + REWRITE_TAC[REAL_ABS_MUL; REAL_ABS_NORM] THEN + DISJ_CASES_TAC(ARITH_RULE `n:num < m \/ m <= n`) THENL + [ASM_SIMP_TAC[SUM_TRIV_NUMSEG; REAL_ABS_NUM; REAL_MUL_RZERO]; ALL_TAC] THEN + SUBGOAL_THEN `m = 0 + m /\ n = (n - m) + m` (CONJUNCTS_THEN SUBST1_TAC) THENL + [UNDISCH_TAC `m:num <= n` THEN ARITH_TAC; ALL_TAC] THEN + REWRITE_TAC[SUM_OFFSET] THEN UNDISCH_TAC `N + M:num <= m` THEN + SIMP_TAC[LE_EXISTS] THEN DISCH_THEN(X_CHOOSE_THEN `d:num` SUBST_ALL_TAC) THEN + REWRITE_TAC[ARITH_RULE `(i + (N + M) + d) - N:num = (M + d) + i`] THEN + ONCE_REWRITE_TAC[REAL_POW_ADD] THEN REWRITE_TAC[SUM_LMUL; SUM_GP] THEN + ASM_SIMP_TAC[LT; REAL_LT_IMP_NE] THEN ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN + ASM_SIMP_TAC[GSYM REAL_LT_RDIV_EQ; NORM_POS_LT; REAL_ABS_MUL] THEN + REWRITE_TAC[REAL_ABS_POW] THEN ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN + ASM_SIMP_TAC[GSYM REAL_LT_RDIV_EQ; REAL_ABS_DIV; REAL_POW_LT; REAL_ARITH + `&0 < c /\ c < &1 ==> &0 < abs c /\ &0 < abs(&1 - c)`; REAL_LT_LDIV_EQ] THEN + MATCH_MP_TAC(REAL_ARITH + `&0 < x /\ x <= &1 /\ &1 <= e ==> abs(c pow 0 - x) < e`) THEN + ASM_SIMP_TAC[REAL_POW_LT; REAL_POW_1_LE; REAL_LT_IMP_LE] THEN + ASM_SIMP_TAC[REAL_ARITH `c < &1 ==> x * abs(&1 - c) = (&1 - c) * x`] THEN + REWRITE_TAC[real_div; REAL_INV_MUL; REAL_POW_ADD; REAL_MUL_ASSOC] THEN + REWRITE_TAC[REAL_ARITH + `(((a * b) * c) * d) * e = (e * ((a * b) * c)) * d`] THEN + ASM_SIMP_TAC[GSYM real_div; REAL_LE_RDIV_EQ; REAL_POW_LT; REAL_MUL_LID; + REAL_ARITH `&0 < c ==> abs c = c`] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH + `xm < e ==> &0 <= (d - &1) * e ==> xm <= d * e`)) THEN + MATCH_MP_TAC REAL_LE_MUL THEN CONJ_TAC THENL + [REWRITE_TAC[REAL_SUB_LE; GSYM REAL_POW_INV] THEN + MATCH_MP_TAC REAL_POW_LE_1 THEN + MATCH_MP_TAC REAL_INV_1_LE THEN ASM_SIMP_TAC[REAL_LT_IMP_LE]; + MATCH_MP_TAC REAL_LT_IMP_LE THEN + ASM_SIMP_TAC[REAL_SUB_LT; REAL_LT_MUL; REAL_LT_DIV; NORM_POS_LT]]);; + +(* ------------------------------------------------------------------------- *) +(* Ostensibly weaker versions of the boundedness of partial sums. *) +(* ------------------------------------------------------------------------- *) + +let BOUNDED_PARTIAL_SUMS = prove + (`!f:num->real^N k. + bounded { vsum(k..n) f | n IN (:num) } + ==> bounded { vsum(m..n) f | m IN (:num) /\ n IN (:num) }`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN `bounded { vsum(0..n) f:real^N | n IN (:num) }` MP_TAC THENL + [FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [BOUNDED_POS]) THEN + REWRITE_TAC[bounded] THEN + REWRITE_TAC[SIMPLE_IMAGE; FORALL_IN_IMAGE; IN_UNIV] THEN + DISCH_THEN(X_CHOOSE_THEN `B:real` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `sum { i:num | i < k} (\i. norm(f i:real^N)) + B` THEN + X_GEN_TAC `i:num` THEN ASM_CASES_TAC `i:num < k` THENL + [MATCH_MP_TAC(REAL_ARITH + `!y. x <= y /\ y <= a /\ &0 < b ==> x <= a + b`) THEN + EXISTS_TAC `sum (0..i) (\i. norm(f i:real^N))` THEN + ASM_SIMP_TAC[VSUM_NORM; FINITE_NUMSEG] THEN + MATCH_MP_TAC SUM_SUBSET THEN + REWRITE_TAC[FINITE_NUMSEG; FINITE_NUMSEG_LT; NORM_POS_LE] THEN + REWRITE_TAC[IN_DIFF; IN_NUMSEG; IN_ELIM_THM] THEN ASM_ARITH_TAC; + ALL_TAC] THEN + ASM_CASES_TAC `k = 0` THENL + [FIRST_X_ASSUM SUBST_ALL_TAC THEN MATCH_MP_TAC(REAL_ARITH + `x <= B /\ &0 <= b ==> x <= b + B`) THEN + ASM_SIMP_TAC[SUM_POS_LE; FINITE_NUMSEG_LT; NORM_POS_LE]; + ALL_TAC] THEN + MP_TAC(ISPECL [`f:num->real^N`; `0`; `k:num`; `i:num`] + VSUM_COMBINE_L) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN + DISCH_THEN(SUBST1_TAC o SYM) THEN ASM_REWRITE_TAC[NUMSEG_LT] THEN + MATCH_MP_TAC(NORM_ARITH + `norm(x) <= a /\ norm(y) <= b ==> norm(x + y) <= a + b`) THEN + ASM_SIMP_TAC[VSUM_NORM; FINITE_NUMSEG]; + ALL_TAC] THEN + DISCH_THEN(fun th -> + MP_TAC(MATCH_MP BOUNDED_DIFFS (W CONJ th)) THEN MP_TAC th) THEN + REWRITE_TAC[IMP_IMP; GSYM BOUNDED_UNION] THEN + MATCH_MP_TAC(REWRITE_RULE[TAUT `a /\ b ==> c <=> b ==> a ==> c`] + BOUNDED_SUBSET) THEN + REWRITE_TAC[SUBSET; IN_ELIM_THM; IN_UNION; LEFT_IMP_EXISTS_THM; IN_UNIV] THEN + MAP_EVERY X_GEN_TAC [`x:real^N`; `m:num`; `n:num`] THEN + DISCH_THEN SUBST1_TAC THEN + ASM_CASES_TAC `m = 0` THENL [ASM_MESON_TAC[]; ALL_TAC] THEN + ASM_CASES_TAC `n:num < m` THENL + [DISJ2_TAC THEN REPEAT(EXISTS_TAC `vsum(0..0) (f:num->real^N)`) THEN + ASM_SIMP_TAC[VSUM_TRIV_NUMSEG; VECTOR_SUB_REFL] THEN MESON_TAC[]; + ALL_TAC] THEN + DISJ2_TAC THEN MAP_EVERY EXISTS_TAC + [`vsum(0..n) (f:num->real^N)`; `vsum(0..(m-1)) (f:num->real^N)`] THEN + CONJ_TAC THENL [MESON_TAC[]; ALL_TAC] THEN + MP_TAC(ISPECL [`f:num->real^N`; `0`; `m:num`; `n:num`] + VSUM_COMBINE_L) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; VECTOR_ARITH_TAC]);; + +(* ------------------------------------------------------------------------- *) +(* General Dirichlet convergence test (could make this uniform on a set). *) +(* ------------------------------------------------------------------------- *) + +let SUMMABLE_BILINEAR_PARTIAL_PRE = prove + (`!f g h:real^M->real^N->real^P l k. + bilinear h /\ + ((\n. h (f(n + 1)) (g(n))) --> l) sequentially /\ + summable (from k) (\n. h (f(n + 1) - f(n)) (g(n))) + ==> summable (from k) (\n. h (f n) (g(n) - g(n - 1)))`, + REPEAT GEN_TAC THEN + REWRITE_TAC[summable; sums; FROM_INTER_NUMSEG] THEN + REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + FIRST_ASSUM(fun th -> + REWRITE_TAC[MATCH_MP BILINEAR_VSUM_PARTIAL_PRE th]) THEN + DISCH_THEN(X_CHOOSE_TAC `l':real^P`) THEN + EXISTS_TAC `l - (h:real^M->real^N->real^P) (f k) (g(k - 1)) - l'` THEN + REWRITE_TAC[LIM_CASES_SEQUENTIALLY] THEN + REPEAT(MATCH_MP_TAC LIM_SUB THEN ASM_REWRITE_TAC[LIM_CONST]));; + +let SERIES_DIRICHLET_BILINEAR = prove + (`!f g h:real^M->real^N->real^P k m p l. + bilinear h /\ + bounded { vsum (m..n) f | n IN (:num)} /\ + summable (from p) (\n. lift(norm(g(n + 1) - g(n)))) /\ + ((\n. h (g(n + 1)) (vsum(1..n) f)) --> l) sequentially + ==> summable (from k) (\n. h (g n) (f n))`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC SUMMABLE_FROM_ELSEWHERE THEN + EXISTS_TAC `1` THEN + FIRST_X_ASSUM(ASSUME_TAC o MATCH_MP BOUNDED_PARTIAL_SUMS) THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [BOUNDED_POS]) THEN + SIMP_TAC[IN_ELIM_THM; IN_UNIV; LEFT_IMP_EXISTS_THM] THEN + REWRITE_TAC[MESON[] `(!x a b. x = f a b ==> p a b) <=> (!a b. p a b)`] THEN + X_GEN_TAC `B:real` THEN STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o MATCH_MP BILINEAR_BOUNDED_POS) THEN + DISCH_THEN(X_CHOOSE_THEN `C:real` STRIP_ASSUME_TAC) THEN + MATCH_MP_TAC SUMMABLE_EQ THEN + EXISTS_TAC `\n. (h:real^M->real^N->real^P) + (g n) (vsum (1..n) f - vsum (1..n-1) f)` THEN + SIMP_TAC[IN_FROM; GSYM NUMSEG_RREC] THEN + SIMP_TAC[VSUM_CLAUSES; FINITE_NUMSEG; IN_NUMSEG; + ARITH_RULE `1 <= n ==> ~(n <= n - 1)`] THEN + CONJ_TAC THENL + [REPEAT STRIP_TAC THEN ASM_SIMP_TAC[BILINEAR_RADD; BILINEAR_RSUB] THEN + VECTOR_ARITH_TAC; + ALL_TAC] THEN + MATCH_MP_TAC SUMMABLE_FROM_ELSEWHERE THEN EXISTS_TAC `p:num` THEN + MP_TAC(ISPECL [`g:num->real^M`; `\n. vsum(1..n) f:real^N`; + `h:real^M->real^N->real^P`; `l:real^P`; `p:num`] + SUMMABLE_BILINEAR_PARTIAL_PRE) THEN + REWRITE_TAC[] THEN DISCH_THEN MATCH_MP_TAC THEN + ASM_REWRITE_TAC[] THEN + SUBGOAL_THEN + `summable (from p) (lift o (\n. C * B * norm(g(n + 1) - g(n):real^M)))` + MP_TAC THENL [ASM_SIMP_TAC[o_DEF; LIFT_CMUL; SUMMABLE_CMUL]; ALL_TAC] THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] SUMMABLE_COMPARISON) THEN + EXISTS_TAC `0` THEN REWRITE_TAC[IN_FROM; GE; LE_0] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC + `C * norm(g(n + 1) - g(n):real^M) * norm(vsum (1..n) f:real^N)` THEN + ASM_SIMP_TAC[REAL_LE_LMUL_EQ] THEN + GEN_REWRITE_TAC RAND_CONV [REAL_MUL_SYM] THEN + ASM_SIMP_TAC[REAL_LE_LMUL; NORM_POS_LE]);; + +let SERIES_DIRICHLET = prove + (`!f:num->real^N g N k m. + bounded { vsum (m..n) f | n IN (:num)} /\ + (!n. N <= n ==> g(n + 1) <= g(n)) /\ + ((lift o g) --> vec 0) sequentially + ==> summable (from k) (\n. g(n) % f(n))`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`f:num->real^N`; `lift o (g:num->real)`; + `\x y:real^N. drop x % y`] SERIES_DIRICHLET_BILINEAR) THEN + REWRITE_TAC[o_THM; LIFT_DROP] THEN DISCH_THEN MATCH_MP_TAC THEN + MAP_EVERY EXISTS_TAC [`m:num`; `N:num`; `vec 0:real^N`] THEN CONJ_TAC THENL + [REWRITE_TAC[bilinear; linear; DROP_ADD; DROP_CMUL] THEN + REPEAT STRIP_TAC THEN VECTOR_ARITH_TAC; + ALL_TAC] THEN + ASM_REWRITE_TAC[GSYM LIFT_SUB; NORM_LIFT] THEN + FIRST_ASSUM(MP_TAC o SPEC `1` o MATCH_MP SEQ_OFFSET) THEN + REWRITE_TAC[o_THM] THEN DISCH_TAC THEN CONJ_TAC THENL + [MATCH_MP_TAC SUMMABLE_EQ_EVENTUALLY THEN + EXISTS_TAC `\n. lift(g(n) - g(n + 1))` THEN REWRITE_TAC[] THEN + CONJ_TAC THENL + [ASM_MESON_TAC[REAL_ARITH `b <= a ==> abs(b - a) = a - b`]; + REWRITE_TAC[summable; sums; FROM_INTER_NUMSEG; VSUM_DIFFS; LIFT_SUB] THEN + REWRITE_TAC[LIM_CASES_SEQUENTIALLY] THEN + EXISTS_TAC `lift(g(N:num)) - vec 0` THEN + MATCH_MP_TAC LIM_SUB THEN ASM_REWRITE_TAC[LIM_CONST]]; + MATCH_MP_TAC LIM_NULL_VMUL_BOUNDED THEN ASM_REWRITE_TAC[o_DEF] THEN + REWRITE_TAC[EVENTUALLY_SEQUENTIALLY] THEN + FIRST_X_ASSUM(ASSUME_TAC o MATCH_MP BOUNDED_PARTIAL_SUMS) THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [BOUNDED_POS]) THEN + SIMP_TAC[IN_ELIM_THM; IN_UNIV] THEN MESON_TAC[]]);; + +(* ------------------------------------------------------------------------- *) +(* Rearranging absolutely convergent series. *) +(* ------------------------------------------------------------------------- *) + +let SERIES_INJECTIVE_IMAGE_STRONG = prove + (`!x:num->real^N s f. + summable (IMAGE f s) (\n. lift(norm(x n))) /\ + (!m n. m IN s /\ n IN s /\ f m = f n ==> m = n) + ==> ((\n. vsum (IMAGE f s INTER (0..n)) x - + vsum (s INTER (0..n)) (x o f)) --> vec 0) + sequentially`, + let lemma = prove + (`!f:A->real^N s t. + FINITE s /\ FINITE t + ==> vsum s f - vsum t f = vsum (s DIFF t) f - vsum (t DIFF s) f`, + REPEAT STRIP_TAC THEN + ONCE_REWRITE_TAC[SET_RULE `s DIFF t = s DIFF (s INTER t)`] THEN + ASM_SIMP_TAC[VSUM_DIFF; INTER_SUBSET] THEN + REWRITE_TAC[INTER_COMM] THEN VECTOR_ARITH_TAC) in + REPEAT STRIP_TAC THEN REWRITE_TAC[LIM_SEQUENTIALLY] THEN + X_GEN_TAC `e:real` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [SUMMABLE_CAUCHY]) THEN + SIMP_TAC[VSUM_REAL; FINITE_INTER; FINITE_NUMSEG] THEN + GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [o_DEF] THEN + REWRITE_TAC[NORM_LIFT; LIFT_DROP] THEN + SIMP_TAC[real_abs; SUM_POS_LE; NORM_POS_LE; FINITE_INTER; FINITE_NUMSEG] THEN + DISCH_THEN(MP_TAC o SPEC `e / &2`) THEN + ASM_REWRITE_TAC[dist; GE; VECTOR_SUB_RZERO; REAL_HALF] THEN + DISCH_THEN(X_CHOOSE_THEN `N:num` STRIP_ASSUME_TAC) THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [INJECTIVE_ON_LEFT_INVERSE]) THEN + DISCH_THEN(X_CHOOSE_TAC `g:num->num`) THEN + MP_TAC(ISPECL [`g:num->num`; `0..N`] UPPER_BOUND_FINITE_SET) THEN + REWRITE_TAC[FINITE_NUMSEG; IN_NUMSEG; LE_0] THEN + DISCH_THEN(X_CHOOSE_TAC `P:num`) THEN + EXISTS_TAC `MAX N P` THEN X_GEN_TAC `n:num` THEN + SIMP_TAC[ARITH_RULE `MAX a b <= c <=> a <= c /\ b <= c`] THEN DISCH_TAC THEN + W(MP_TAC o PART_MATCH (rand o rand) VSUM_IMAGE o rand o + rand o lhand o snd) THEN + ANTS_TAC THENL + [ASM_MESON_TAC[FINITE_INTER; FINITE_NUMSEG; IN_INTER]; + DISCH_THEN(SUBST1_TAC o SYM)] THEN + W(MP_TAC o PART_MATCH (lhand o rand) lemma o rand o lhand o snd) THEN + SIMP_TAC[FINITE_INTER; FINITE_IMAGE; FINITE_NUMSEG] THEN + DISCH_THEN SUBST1_TAC THEN MATCH_MP_TAC(NORM_ARITH + `norm a < e / &2 /\ norm b < e / &2 ==> norm(a - b:real^N) < e`) THEN + CONJ_TAC THEN + W(MP_TAC o PART_MATCH (lhand o rand) VSUM_NORM o lhand o snd) THEN + SIMP_TAC[FINITE_DIFF; FINITE_IMAGE; FINITE_INTER; FINITE_NUMSEG] THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] REAL_LET_TRANS) THEN + MATCH_MP_TAC REAL_LET_TRANS THENL + [EXISTS_TAC + `sum(IMAGE (f:num->num) s INTER (N..n)) (\i. norm(x i :real^N))` THEN + ASM_SIMP_TAC[LE_REFL] THEN MATCH_MP_TAC SUM_SUBSET_SIMPLE THEN + SIMP_TAC[NORM_POS_LE; FINITE_INTER; FINITE_NUMSEG] THEN + MATCH_MP_TAC(SET_RULE + `(!x. x IN s /\ f(x) IN n /\ ~(x IN m) ==> f x IN t) + ==> (IMAGE f s INTER n) DIFF (IMAGE f (s INTER m)) SUBSET + IMAGE f s INTER t`) THEN + ASM_SIMP_TAC[IN_NUMSEG; LE_0; NOT_LE] THEN + X_GEN_TAC `i:num` THEN STRIP_TAC THEN + MATCH_MP_TAC LT_IMP_LE THEN ONCE_REWRITE_TAC[GSYM NOT_LE] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o GEN_REWRITE_RULE BINDER_CONV + [GSYM CONTRAPOS_THM]) THEN + ASM_SIMP_TAC[] THEN ASM_ARITH_TAC; + MP_TAC(ISPECL [`f:num->num`; `0..n`] UPPER_BOUND_FINITE_SET) THEN + REWRITE_TAC[FINITE_NUMSEG; IN_NUMSEG; LE_0] THEN + DISCH_THEN(X_CHOOSE_TAC `p:num`) THEN + EXISTS_TAC + `sum(IMAGE (f:num->num) s INTER (N..p)) (\i. norm(x i :real^N))` THEN + ASM_SIMP_TAC[LE_REFL] THEN MATCH_MP_TAC SUM_SUBSET_SIMPLE THEN + SIMP_TAC[NORM_POS_LE; FINITE_INTER; FINITE_NUMSEG] THEN + MATCH_MP_TAC(SET_RULE + `(!x. x IN s /\ x IN n /\ ~(f x IN m) ==> f x IN t) + ==> (IMAGE f (s INTER n) DIFF (IMAGE f s) INTER m) SUBSET + (IMAGE f s INTER t)`) THEN + ASM_SIMP_TAC[IN_NUMSEG; LE_0] THEN ASM_ARITH_TAC]);; + +let SERIES_INJECTIVE_IMAGE = prove + (`!x:num->real^N s f l. + summable (IMAGE f s) (\n. lift(norm(x n))) /\ + (!m n. m IN s /\ n IN s /\ f m = f n ==> m = n) + ==> (((x o f) sums l) s <=> (x sums l) (IMAGE f s))`, + REPEAT STRIP_TAC THEN CONV_TAC SYM_CONV THEN REWRITE_TAC[sums] THEN + MATCH_MP_TAC LIM_TRANSFORM_EQ THEN REWRITE_TAC[] THEN + MATCH_MP_TAC SERIES_INJECTIVE_IMAGE_STRONG THEN + ASM_REWRITE_TAC[]);; + +let SERIES_REARRANGE_EQ = prove + (`!x:num->real^N s p l. + summable s (\n. lift(norm(x n))) /\ p permutes s + ==> (((x o p) sums l) s <=> (x sums l) s)`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`x:num->real^N`; `s:num->bool`; `p:num->num`; `l:real^N`] + SERIES_INJECTIVE_IMAGE) THEN + ASM_SIMP_TAC[PERMUTES_IMAGE] THEN + ASM_MESON_TAC[PERMUTES_INJECTIVE]);; + +let SERIES_REARRANGE = prove + (`!x:num->real^N s p l. + summable s (\n. lift(norm(x n))) /\ p permutes s /\ (x sums l) s + ==> ((x o p) sums l) s`, + MESON_TAC[SERIES_REARRANGE_EQ]);; + +let SUMMABLE_REARRANGE = prove + (`!x s p. + summable s (\n. lift(norm(x n))) /\ p permutes s + ==> summable s (x o p)`, + MESON_TAC[SERIES_LIFT_ABSCONV_IMP_CONV; summable; SERIES_REARRANGE]);; + +(* ------------------------------------------------------------------------- *) +(* Banach fixed point theorem (not really topological...) *) +(* ------------------------------------------------------------------------- *) + +let BANACH_FIX = prove + (`!f s c. complete s /\ ~(s = {}) /\ + &0 <= c /\ c < &1 /\ + (IMAGE f s) SUBSET s /\ + (!x y. x IN s /\ y IN s ==> dist(f(x),f(y)) <= c * dist(x,y)) + ==> ?!x:real^N. x IN s /\ (f x = x)`, + REPEAT STRIP_TAC THEN REWRITE_TAC[EXISTS_UNIQUE_THM] THEN CONJ_TAC THENL + [ALL_TAC; + MAP_EVERY X_GEN_TAC [`x:real^N`; `y:real^N`] THEN STRIP_TAC THEN + SUBGOAL_THEN `dist((f:real^N->real^N) x,f y) <= c * dist(x,y)` MP_TAC THENL + [ASM_MESON_TAC[]; ALL_TAC] THEN + ASM_REWRITE_TAC[REAL_ARITH `a <= c * a <=> &0 <= --a * (&1 - c)`] THEN + ASM_SIMP_TAC[GSYM REAL_LE_LDIV_EQ; REAL_SUB_LT; real_div] THEN + REWRITE_TAC[REAL_MUL_LZERO; REAL_ARITH `&0 <= --x <=> ~(&0 < x)`] THEN + MESON_TAC[DIST_POS_LT]] THEN + STRIP_ASSUME_TAC(prove_recursive_functions_exist num_RECURSION + `(z 0 = @x:real^N. x IN s) /\ (!n. z(SUC n) = f(z n))`) THEN + SUBGOAL_THEN `!n. (z:num->real^N) n IN s` ASSUME_TAC THENL + [INDUCT_TAC THEN ASM_REWRITE_TAC[] THEN + ASM_MESON_TAC[MEMBER_NOT_EMPTY; SUBSET; IN_IMAGE]; + ALL_TAC] THEN + UNDISCH_THEN `z 0 = @x:real^N. x IN s` (K ALL_TAC) THEN + SUBGOAL_THEN `?x:real^N. x IN s /\ (z --> x) sequentially` MP_TAC THENL + [ALL_TAC; + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `a:real^N` THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + ABBREV_TAC `e = dist(f(a:real^N),a)` THEN + SUBGOAL_THEN `~(&0 < e)` (fun th -> ASM_MESON_TAC[th; DIST_POS_LT]) THEN + DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [LIM_SEQUENTIALLY]) THEN + DISCH_THEN(MP_TAC o SPEC `e / &2`) THEN + ASM_REWRITE_TAC[REAL_HALF] THEN DISCH_THEN(X_CHOOSE_TAC `N:num`) THEN + SUBGOAL_THEN + `dist(f(z N),a:real^N) < e / &2 /\ dist(f(z(N:num)),f(a)) < e / &2` + (fun th -> ASM_MESON_TAC[th; DIST_TRIANGLE_HALF_R; REAL_LT_REFL]) THEN + CONJ_TAC THENL [ASM_MESON_TAC[ARITH_RULE `N <= SUC N`]; ALL_TAC] THEN + MATCH_MP_TAC REAL_LET_TRANS THEN + EXISTS_TAC `c * dist((z:num->real^N) N,a)` THEN ASM_SIMP_TAC[] THEN + MATCH_MP_TAC(REAL_ARITH `x < y /\ c * x <= &1 * x ==> c * x < y`) THEN + ASM_SIMP_TAC[LE_REFL; REAL_LE_RMUL; DIST_POS_LE; REAL_LT_IMP_LE]] THEN + FIRST_ASSUM(MATCH_MP_TAC o GEN_REWRITE_RULE I [complete]) THEN + ASM_REWRITE_TAC[CAUCHY] THEN + SUBGOAL_THEN `!n. dist(z(n):real^N,z(SUC n)) <= c pow n * dist(z(0),z(1))` + ASSUME_TAC THENL + [INDUCT_TAC THEN + REWRITE_TAC[real_pow; ARITH; REAL_MUL_LID; REAL_LE_REFL] THEN + MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `c * dist(z(n):real^N,z(SUC n))` THEN + CONJ_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN + REWRITE_TAC[GSYM REAL_MUL_ASSOC] THEN ASM_SIMP_TAC[REAL_LE_LMUL]; + ALL_TAC] THEN + SUBGOAL_THEN + `!m n:num. (&1 - c) * dist(z(m):real^N,z(m+n)) + <= c pow m * dist(z(0),z(1)) * (&1 - c pow n)` + ASSUME_TAC THENL + [GEN_TAC THEN INDUCT_TAC THENL + [REWRITE_TAC[ADD_CLAUSES; DIST_REFL; REAL_MUL_RZERO] THEN + MATCH_MP_TAC REAL_LE_MUL THEN + ASM_SIMP_TAC[REAL_LE_MUL; REAL_POW_LE; DIST_POS_LE; REAL_SUB_LE; + REAL_POW_1_LE; REAL_LT_IMP_LE]; + ALL_TAC] THEN + MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC + `(&1 - c) * (dist(z m:real^N,z(m + n)) + dist(z(m + n),z(m + SUC n)))` THEN + ASM_SIMP_TAC[REAL_LE_LMUL; REAL_SUB_LE; REAL_LT_IMP_LE; DIST_TRIANGLE] THEN + FIRST_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH + `c * x <= y ==> c * x' + y <= y' ==> c * (x + x') <= y'`)) THEN + REWRITE_TAC[REAL_ARITH + `q + a * b * (&1 - x) <= a * b * (&1 - y) <=> q <= a * b * (x - y)`] THEN + REWRITE_TAC[ADD_CLAUSES; real_pow] THEN + REWRITE_TAC[REAL_ARITH `a * b * (d - c * d) = (&1 - c) * a * d * b`] THEN + MATCH_MP_TAC REAL_LE_LMUL THEN + ASM_SIMP_TAC[REAL_SUB_LE; REAL_LT_IMP_LE] THEN + REWRITE_TAC[GSYM REAL_POW_ADD; REAL_MUL_ASSOC] THEN ASM_MESON_TAC[]; + ALL_TAC] THEN + X_GEN_TAC `e:real` THEN DISCH_TAC THEN + ASM_CASES_TAC `(z:num->real^N) 0 = z 1` THENL + [FIRST_X_ASSUM SUBST_ALL_TAC THEN EXISTS_TAC `0` THEN + REWRITE_TAC[GE; LE_0] THEN X_GEN_TAC `n:num` THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`0`; `n:num`]) THEN + REWRITE_TAC[ADD_CLAUSES; DIST_REFL; REAL_MUL_LZERO; REAL_MUL_RZERO] THEN + ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN + ASM_CASES_TAC `(z:num->real^N) 0 = z n` THEN + ASM_REWRITE_TAC[DIST_REFL; REAL_NOT_LE] THEN + ASM_SIMP_TAC[REAL_LT_MUL; DIST_POS_LT; REAL_SUB_LT]; + ALL_TAC] THEN + MP_TAC(SPECL [`c:real`; `e * (&1 - c) / dist((z:num->real^N) 0,z 1)`] + REAL_ARCH_POW_INV) THEN + ASM_SIMP_TAC[REAL_LT_MUL; REAL_LT_DIV; REAL_SUB_LT; DIST_POS_LT] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `N:num` THEN + REWRITE_TAC[real_div; GE; REAL_MUL_ASSOC] THEN + ASM_SIMP_TAC[REAL_LT_RDIV_EQ; GSYM real_div; DIST_POS_LT] THEN + ASM_SIMP_TAC[GSYM REAL_LT_LDIV_EQ; REAL_SUB_LT] THEN DISCH_TAC THEN + REWRITE_TAC[LE_EXISTS; LEFT_IMP_EXISTS_THM] THEN + GEN_TAC THEN X_GEN_TAC `d:num` THEN DISCH_THEN SUBST_ALL_TAC THEN + ONCE_REWRITE_TAC[DIST_SYM] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP(REAL_ARITH + `d < e ==> x <= d ==> x < e`)) THEN + ASM_SIMP_TAC[REAL_LE_RDIV_EQ; REAL_SUB_LT] THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`N:num`; `d:num`]) THEN + MATCH_MP_TAC(REAL_ARITH + `(c * d) * e <= (c * d) * &1 ==> x * y <= c * d * e ==> y * x <= c * d`) THEN + MATCH_MP_TAC REAL_LE_LMUL THEN + ASM_SIMP_TAC[REAL_LE_MUL; REAL_POW_LE; DIST_POS_LE; REAL_ARITH + `&0 <= x ==> &1 - x <= &1`]);; + +(* ------------------------------------------------------------------------- *) +(* Edelstein fixed point theorem. *) +(* ------------------------------------------------------------------------- *) + +let EDELSTEIN_FIX = prove + (`!f s. compact s /\ ~(s = {}) /\ (IMAGE f s) SUBSET s /\ + (!x y. x IN s /\ y IN s /\ ~(x = y) ==> dist(f(x),f(y)) < dist(x,y)) + ==> ?!x:real^N. x IN s /\ f x = x`, + MAP_EVERY X_GEN_TAC [`g:real^N->real^N`; `s:real^N->bool`] THEN + REPEAT STRIP_TAC THEN REWRITE_TAC[EXISTS_UNIQUE_THM] THEN CONJ_TAC THENL + [ALL_TAC; ASM_MESON_TAC[REAL_LT_REFL]] THEN + SUBGOAL_THEN + `!x y. x IN s /\ y IN s ==> dist((g:real^N->real^N)(x),g(y)) <= dist(x,y)` + ASSUME_TAC THENL + [REPEAT STRIP_TAC THEN ASM_CASES_TAC `x:real^N = y` THEN + ASM_SIMP_TAC[DIST_REFL; REAL_LE_LT]; + ALL_TAC] THEN + ASM_CASES_TAC `?x:real^N. x IN s /\ ~(g x = x)` THENL + [ALL_TAC; ASM SET_TAC[]] THEN + FIRST_X_ASSUM(X_CHOOSE_THEN `x:real^N` STRIP_ASSUME_TAC) THEN + ABBREV_TAC `y = (g:real^N->real^N) x` THEN + SUBGOAL_THEN `(y:real^N) IN s` ASSUME_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + FIRST_ASSUM(MP_TAC o MATCH_MP COMPACT_PCROSS o W CONJ) THEN + REWRITE_TAC[compact; PCROSS] THEN + (STRIP_ASSUME_TAC o prove_general_recursive_function_exists) + `?f:num->real^N->real^N. + (!z. f 0 z = z) /\ (!z n. f (SUC n) z = g(f n z))` THEN + SUBGOAL_THEN `!n z. z IN s ==> (f:num->real^N->real^N) n z IN s` + STRIP_ASSUME_TAC THENL [INDUCT_TAC THEN ASM SET_TAC[]; ALL_TAC] THEN + SUBGOAL_THEN + `!m n w z. m <= n /\ w IN s /\ z IN s + ==> dist((f:num->real^N->real^N) n w,f n z) <= dist(f m w,f m z)` + ASSUME_TAC THENL + [REWRITE_TAC[RIGHT_FORALL_IMP_THM; IMP_CONJ] THEN + MATCH_MP_TAC TRANSITIVE_STEPWISE_LE THEN + RULE_ASSUM_TAC(REWRITE_RULE[SUBSET; FORALL_IN_IMAGE]) THEN + ASM_SIMP_TAC[REAL_LE_REFL] THEN MESON_TAC[REAL_LE_TRANS]; + ALL_TAC] THEN + DISCH_THEN(MP_TAC o SPEC + `\n:num. pastecart (f n (x:real^N)) (f n y:real^N)`) THEN + ANTS_TAC THENL [ASM SET_TAC[]; REWRITE_TAC[LEFT_IMP_EXISTS_THM]] THEN + MAP_EVERY X_GEN_TAC [`l:real^(N,N)finite_sum`; `s:num->num`] THEN + REWRITE_TAC[o_DEF; IN_ELIM_THM] THEN + DISCH_THEN(CONJUNCTS_THEN2 MP_TAC STRIP_ASSUME_TAC) THEN + REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`a:real^N`; `b:real^N`] THEN + DISCH_THEN(CONJUNCTS_THEN2 STRIP_ASSUME_TAC SUBST_ALL_TAC) THEN + SUBGOAL_THEN + `(\x:real^(N,N)finite_sum. fstcart x) continuous_on UNIV /\ + (\x:real^(N,N)finite_sum. sndcart x) continuous_on UNIV` + MP_TAC THENL + [CONJ_TAC THEN MATCH_MP_TAC LINEAR_CONTINUOUS_ON THEN + REWRITE_TAC[ETA_AX; LINEAR_FSTCART; LINEAR_SNDCART]; + ALL_TAC] THEN + REWRITE_TAC[CONTINUOUS_ON_SEQUENTIALLY; IN_UNIV] THEN + DISCH_THEN(CONJUNCTS_THEN(fun th -> FIRST_ASSUM(MP_TAC o MATCH_MP th))) THEN + REWRITE_TAC[o_DEF; FSTCART_PASTECART; SNDCART_PASTECART; IMP_IMP] THEN + ONCE_REWRITE_TAC[CONJ_SYM] THEN + DISCH_THEN(fun th -> CONJUNCTS_THEN2 (LABEL_TAC "A") (LABEL_TAC "B") th THEN + MP_TAC(MATCH_MP LIM_SUB th)) THEN + REWRITE_TAC[] THEN DISCH_THEN(LABEL_TAC "AB") THEN + SUBGOAL_THEN + `!n. dist(a:real^N,b) <= dist((f:num->real^N->real^N) n x,f n y)` + STRIP_ASSUME_TAC THENL + [X_GEN_TAC `N:num` THEN REWRITE_TAC[GSYM REAL_NOT_LT] THEN + ONCE_REWRITE_TAC[GSYM REAL_SUB_LT] THEN DISCH_TAC THEN + USE_THEN "AB" (MP_TAC o REWRITE_RULE[LIM_SEQUENTIALLY]) THEN + DISCH_THEN(fun th -> FIRST_X_ASSUM(MP_TAC o MATCH_MP th)) THEN + REWRITE_TAC[NOT_EXISTS_THM] THEN X_GEN_TAC `M:num` THEN + DISCH_THEN(MP_TAC o SPEC `M + N:num`) THEN REWRITE_TAC[LE_ADD] THEN + MATCH_MP_TAC(NORM_ARITH + `dist(fx,fy) <= dist(x,y) + ==> ~(dist(fx - fy,a - b) < dist(a,b) - dist(x,y))`) THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[] THEN + FIRST_X_ASSUM(MP_TAC o SPEC `M + N:num` o MATCH_MP MONOTONE_BIGGER) THEN + ARITH_TAC; + ALL_TAC] THEN + SUBGOAL_THEN `b:real^N = a` SUBST_ALL_TAC THENL + [MATCH_MP_TAC(TAUT `(~p ==> F) ==> p`) THEN DISCH_TAC THEN + ABBREV_TAC `e = dist(a,b) - dist((g:real^N->real^N) a,g b)` THEN + SUBGOAL_THEN `&0 < e` ASSUME_TAC THENL + [ASM_MESON_TAC[REAL_SUB_LT]; ALL_TAC] THEN + SUBGOAL_THEN + `?n. dist((f:num->real^N->real^N) n x,a) < e / &2 /\ + dist(f n y,b) < e / &2` + STRIP_ASSUME_TAC THENL + [MAP_EVERY (fun s -> USE_THEN s (MP_TAC o SPEC `e / &2` o + REWRITE_RULE[LIM_SEQUENTIALLY])) ["A"; "B"] THEN + ASM_REWRITE_TAC[REAL_HALF] THEN + DISCH_THEN(X_CHOOSE_TAC `M:num`) THEN + DISCH_THEN(X_CHOOSE_TAC `N:num`) THEN + EXISTS_TAC `(s:num->num) (M + N)` THEN + CONJ_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ARITH_TAC; + ALL_TAC] THEN + SUBGOAL_THEN `dist(f (SUC n) x,(g:real^N->real^N) a) + + dist((f:num->real^N->real^N) (SUC n) y,g b) < e` + MP_TAC THENL + [ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC(REAL_ARITH `x < e / &2 /\ y < e / &2 ==> x + y < e`) THEN + CONJ_TAC THEN FIRST_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH + `dist(x,y) < e + ==> dist(g x,g y) <= dist(x,y) ==> dist(g x,g y) < e`)) THEN + ASM_SIMP_TAC[]; + ALL_TAC] THEN + MP_TAC(SPEC `SUC n` (ASSUME + `!n. dist (a:real^N,b) <= + dist ((f:num->real^N->real^N) n x,f n y)`)) THEN + EXPAND_TAC "e" THEN NORM_ARITH_TAC; + ALL_TAC] THEN + EXISTS_TAC `a:real^N` THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC(ISPEC `sequentially` LIM_UNIQUE) THEN + EXISTS_TAC `\n:num. (f:num->real^N->real^N) (SUC(s n)) x` THEN + REWRITE_TAC[TRIVIAL_LIMIT_SEQUENTIALLY] THEN CONJ_TAC THENL + [ASM_REWRITE_TAC[] THEN + SUBGOAL_THEN `(g:real^N->real^N) continuous_on s` MP_TAC THENL + [REWRITE_TAC[continuous_on] THEN ASM_MESON_TAC[REAL_LET_TRANS]; + ALL_TAC] THEN + REWRITE_TAC[CONTINUOUS_ON_SEQUENTIALLY; o_DEF] THEN + DISCH_THEN MATCH_MP_TAC THEN ASM_SIMP_TAC[]; + SUBGOAL_THEN `!n. (f:num->real^N->real^N) (SUC n) x = f n y` + (fun th -> ASM_SIMP_TAC[th]) THEN + INDUCT_TAC THEN ASM_REWRITE_TAC[]]);; + +(* ------------------------------------------------------------------------- *) +(* Dini's theorem. *) +(* ------------------------------------------------------------------------- *) + +let DINI = prove + (`!f:num->real^N->real^1 g s. + compact s /\ (!n. (f n) continuous_on s) /\ g continuous_on s /\ + (!x. x IN s ==> ((\n. (f n x)) --> g x) sequentially) /\ + (!n x. x IN s ==> drop(f n x) <= drop(f (n + 1) x)) + ==> !e. &0 < e + ==> eventually (\n. !x. x IN s ==> norm(f n x - g x) < e) + sequentially`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN + `!x:real^N m n:num. x IN s /\ m <= n ==> drop(f m x) <= drop(f n x)` + ASSUME_TAC THENL + [GEN_TAC THEN ASM_CASES_TAC `(x:real^N) IN s` THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC TRANSITIVE_STEPWISE_LE THEN ASM_SIMP_TAC[ADD1] THEN + REAL_ARITH_TAC; + ALL_TAC] THEN + SUBGOAL_THEN `!n:num x:real^N. x IN s ==> drop(f n x) <= drop(g x)` + ASSUME_TAC THENL + [REPEAT STRIP_TAC THEN + MATCH_MP_TAC(ISPEC `sequentially` LIM_DROP_LE) THEN + EXISTS_TAC `\m:num. (f:num->real^N->real^1) n x` THEN + EXISTS_TAC `\m:num. (f:num->real^N->real^1) m x` THEN + ASM_SIMP_TAC[LIM_CONST; TRIVIAL_LIMIT_SEQUENTIALLY] THEN + REWRITE_TAC[EVENTUALLY_SEQUENTIALLY] THEN ASM_MESON_TAC[]; + ALL_TAC] THEN + RULE_ASSUM_TAC(REWRITE_RULE[LIM_SEQUENTIALLY; dist]) THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I + [COMPACT_EQ_HEINE_BOREL_SUBTOPOLOGY]) THEN + DISCH_THEN(MP_TAC o SPEC + `IMAGE (\n. { x | x IN s /\ norm((f:num->real^N->real^1) n x - g x) < e}) + (:num)`) THEN + REWRITE_TAC[FORALL_IN_IMAGE; IN_UNIV] THEN + ONCE_REWRITE_TAC[TAUT `p /\ q /\ r <=> q /\ p /\ r`] THEN + REWRITE_TAC[EXISTS_FINITE_SUBSET_IMAGE; SUBSET_UNION; UNIONS_IMAGE] THEN + REWRITE_TAC[IN_UNIV; IN_ELIM_THM; EVENTUALLY_SEQUENTIALLY] THEN + SIMP_TAC[SUBSET; IN_UNIV; IN_ELIM_THM] THEN ANTS_TAC THENL + [CONJ_TAC THENL [ALL_TAC; ASM_MESON_TAC[LE_REFL]] THEN + X_GEN_TAC `n:num` THEN REWRITE_TAC[GSYM IN_BALL_0] THEN + MATCH_MP_TAC CONTINUOUS_OPEN_IN_PREIMAGE THEN + ASM_SIMP_TAC[OPEN_BALL; CONTINUOUS_ON_SUB; ETA_AX]; + + DISCH_THEN(X_CHOOSE_THEN `k:num->bool` (CONJUNCTS_THEN2 + (MP_TAC o SPEC `\n:num. n` o MATCH_MP UPPER_BOUND_FINITE_SET) + (LABEL_TAC "*"))) THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `N:num` THEN + REWRITE_TAC[] THEN STRIP_TAC THEN X_GEN_TAC `n:num` THEN + DISCH_TAC THEN X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN + REMOVE_THEN "*" (MP_TAC o SPEC `x:real^N`) THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `m:num` (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + REWRITE_TAC[NORM_REAL; GSYM drop; DROP_SUB] THEN MATCH_MP_TAC(REAL_ARITH + `m <= n /\ n <= g ==> abs(m - g) < e ==> abs(n - g) < e`) THEN + ASM_MESON_TAC[LE_TRANS]]);; + +(* ------------------------------------------------------------------------- *) +(* Closest point of a (closed) set to a point. *) +(* ------------------------------------------------------------------------- *) + +let closest_point = new_definition + `closest_point s a = @x. x IN s /\ !y. y IN s ==> dist(a,x) <= dist(a,y)`;; + +let CLOSEST_POINT_EXISTS = prove + (`!s a. closed s /\ ~(s = {}) + ==> (closest_point s a) IN s /\ + !y. y IN s ==> dist(a,closest_point s a) <= dist(a,y)`, + REWRITE_TAC[closest_point] THEN CONV_TAC(ONCE_DEPTH_CONV SELECT_CONV) THEN + REWRITE_TAC[DISTANCE_ATTAINS_INF]);; + +let CLOSEST_POINT_IN_SET = prove + (`!s a. closed s /\ ~(s = {}) ==> (closest_point s a) IN s`, + MESON_TAC[CLOSEST_POINT_EXISTS]);; + +let CLOSEST_POINT_LE = prove + (`!s a x. closed s /\ x IN s ==> dist(a,closest_point s a) <= dist(a,x)`, + MESON_TAC[CLOSEST_POINT_EXISTS; MEMBER_NOT_EMPTY]);; + +let CLOSEST_POINT_SELF = prove + (`!s x:real^N. x IN s ==> closest_point s x = x`, + REPEAT STRIP_TAC THEN REWRITE_TAC[closest_point] THEN + MATCH_MP_TAC SELECT_UNIQUE THEN REWRITE_TAC[] THEN GEN_TAC THEN EQ_TAC THENL + [STRIP_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC `x:real^N`) THEN + ASM_SIMP_TAC[DIST_LE_0; DIST_REFL]; + STRIP_TAC THEN ASM_REWRITE_TAC[DIST_REFL; DIST_POS_LE]]);; + +let CLOSEST_POINT_REFL = prove + (`!s x:real^N. closed s /\ ~(s = {}) ==> (closest_point s x = x <=> x IN s)`, + MESON_TAC[CLOSEST_POINT_IN_SET; CLOSEST_POINT_SELF]);; + +let DIST_CLOSEST_POINT_LIPSCHITZ = prove + (`!s x y:real^N. + closed s /\ ~(s = {}) + ==> abs(dist(x,closest_point s x) - dist(y,closest_point s y)) + <= dist(x,y)`, + REPEAT GEN_TAC THEN DISCH_TAC THEN + FIRST_ASSUM(MP_TAC o MATCH_MP CLOSEST_POINT_EXISTS) THEN + DISCH_THEN(fun th -> + CONJUNCTS_THEN2 ASSUME_TAC + (MP_TAC o SPEC `closest_point s (y:real^N)`) (SPEC `x:real^N` th) THEN + CONJUNCTS_THEN2 ASSUME_TAC + (MP_TAC o SPEC `closest_point s (x:real^N)`) (SPEC `y:real^N` th)) THEN + ASM_REWRITE_TAC[] THEN NORM_ARITH_TAC);; + +let CONTINUOUS_AT_DIST_CLOSEST_POINT = prove + (`!s x:real^N. + closed s /\ ~(s = {}) + ==> (\x. lift(dist(x,closest_point s x))) continuous (at x)`, + REPEAT STRIP_TAC THEN REWRITE_TAC[continuous_at; DIST_LIFT] THEN + ASM_MESON_TAC[DIST_CLOSEST_POINT_LIPSCHITZ; REAL_LET_TRANS]);; + +let CONTINUOUS_ON_DIST_CLOSEST_POINT = prove + (`!s t. closed s /\ ~(s = {}) + ==> (\x. lift(dist(x,closest_point s x))) continuous_on t`, + MESON_TAC[CONTINUOUS_AT_IMP_CONTINUOUS_ON; + CONTINUOUS_AT_DIST_CLOSEST_POINT]);; + +let UNIFORMLY_CONTINUOUS_ON_DIST_CLOSEST_POINT = prove + (`!s t:real^N->bool. + closed s /\ ~(s = {}) + ==> (\x. lift(dist(x,closest_point s x))) uniformly_continuous_on t`, + REPEAT STRIP_TAC THEN REWRITE_TAC[uniformly_continuous_on; DIST_LIFT] THEN + ASM_MESON_TAC[DIST_CLOSEST_POINT_LIPSCHITZ; REAL_LET_TRANS]);; + +let SEGMENT_TO_CLOSEST_POINT = prove + (`!s a:real^N. + closed s /\ ~(s = {}) + ==> segment(a,closest_point s a) INTER s = {}`, + REPEAT STRIP_TAC THEN + REWRITE_TAC[SET_RULE `s INTER t = {} <=> !x. x IN s ==> ~(x IN t)`] THEN + GEN_TAC THEN DISCH_THEN(MP_TAC o MATCH_MP DIST_IN_OPEN_SEGMENT) THEN + MATCH_MP_TAC(TAUT `(r ==> ~p) ==> p /\ q ==> ~r`) THEN + ASM_MESON_TAC[CLOSEST_POINT_EXISTS; REAL_NOT_LT; DIST_SYM]);; + +let SEGMENT_TO_POINT_EXISTS = prove + (`!s a:real^N. + closed s /\ ~(s = {}) ==> ?b. b IN s /\ segment(a,b) INTER s = {}`, + MESON_TAC[SEGMENT_TO_CLOSEST_POINT; CLOSEST_POINT_EXISTS]);; + +let CLOSEST_POINT_IN_INTERIOR = prove + (`!s x:real^N. + closed s /\ ~(s = {}) + ==> ((closest_point s x) IN interior s <=> x IN interior s)`, + REPEAT STRIP_TAC THEN ASM_CASES_TAC `(x:real^N) IN s` THEN + ASM_SIMP_TAC[CLOSEST_POINT_SELF] THEN + MATCH_MP_TAC(TAUT `~q /\ ~p ==> (p <=> q)`) THEN + CONJ_TAC THENL [ASM_MESON_TAC[INTERIOR_SUBSET; SUBSET]; STRIP_TAC] THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_INTERIOR_CBALL]) THEN + DISCH_THEN(X_CHOOSE_THEN `e:real` STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN `closest_point s (x:real^N) IN s` ASSUME_TAC THENL + [ASM_MESON_TAC[INTERIOR_SUBSET; SUBSET]; ALL_TAC] THEN + SUBGOAL_THEN `~(closest_point s (x:real^N) = x)` ASSUME_TAC THENL + [ASM_MESON_TAC[]; ALL_TAC] THEN + MP_TAC(ISPECL [`s:real^N->bool`; `x:real^N`; + `closest_point s x - + (min (&1) (e / norm(closest_point s x - x))) % + (closest_point s x - x):real^N`] + CLOSEST_POINT_LE) THEN + ASM_REWRITE_TAC[dist; NOT_IMP; VECTOR_ARITH + `x - (y - e % (y - x)):real^N = (&1 - e) % (x - y)`] THEN + CONJ_TAC THENL + [FIRST_X_ASSUM(MATCH_MP_TAC o GEN_REWRITE_RULE I [SUBSET]) THEN + REWRITE_TAC[IN_CBALL; NORM_ARITH `dist(a:real^N,a - x) = norm x`] THEN + REWRITE_TAC[NORM_MUL; REAL_ABS_DIV; REAL_ABS_NORM] THEN + ASM_SIMP_TAC[GSYM REAL_LE_RDIV_EQ; NORM_POS_LT; VECTOR_SUB_EQ] THEN + MATCH_MP_TAC(REAL_ARITH `&0 <= a ==> abs(min (&1) a) <= a`) THEN + ASM_SIMP_TAC[REAL_LT_IMP_LE; REAL_LE_DIV; NORM_POS_LE]; + REWRITE_TAC[NORM_MUL; REAL_ARITH + `~(n <= a * n) <=> &0 < (&1 - a) * n`] THEN + MATCH_MP_TAC REAL_LT_MUL THEN + ASM_SIMP_TAC[NORM_POS_LT; VECTOR_SUB_EQ] THEN + MATCH_MP_TAC(REAL_ARITH + `&0 < e /\ e <= &1 ==> &0 < &1 - abs(&1 - e)`) THEN + REWRITE_TAC[REAL_MIN_LE; REAL_LT_MIN; REAL_LT_01; REAL_LE_REFL] THEN + ASM_SIMP_TAC[REAL_LT_DIV; NORM_POS_LT; VECTOR_SUB_EQ]]);; + +let CLOSEST_POINT_IN_FRONTIER = prove + (`!s x:real^N. + closed s /\ ~(s = {}) /\ ~(x IN interior s) + ==> (closest_point s x) IN frontier s`, + SIMP_TAC[frontier; IN_DIFF; CLOSEST_POINT_IN_INTERIOR] THEN + SIMP_TAC[CLOSEST_POINT_IN_SET; CLOSURE_CLOSED]);; + +(* ------------------------------------------------------------------------- *) +(* More general infimum of distance between two sets. *) +(* ------------------------------------------------------------------------- *) + +let setdist = new_definition + `setdist(s,t) = + if s = {} \/ t = {} then &0 + else inf {dist(x,y) | x IN s /\ y IN t}`;; + +let SETDIST_EMPTY = prove + (`(!t. setdist({},t) = &0) /\ (!s. setdist(s,{}) = &0)`, + REWRITE_TAC[setdist]);; + +let SETDIST_POS_LE = prove + (`!s t. &0 <= setdist(s,t)`, + REPEAT GEN_TAC THEN REWRITE_TAC[setdist] THEN + COND_CASES_TAC THEN REWRITE_TAC[REAL_LE_REFL] THEN + MATCH_MP_TAC REAL_LE_INF THEN + REWRITE_TAC[FORALL_IN_GSPEC; DIST_POS_LE] THEN ASM SET_TAC[]);; + +let REAL_LE_SETDIST = prove + (`!s t:real^N->bool d. + ~(s = {}) /\ ~(t = {}) /\ + (!x y. x IN s /\ y IN t ==> d <= dist(x,y)) + ==> d <= setdist(s,t)`, + REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[setdist] THEN + MP_TAC(ISPEC `{dist(x:real^N,y) | x IN s /\ y IN t}` INF) THEN + REWRITE_TAC[FORALL_IN_GSPEC] THEN ANTS_TAC THENL + [CONJ_TAC THENL [ASM SET_TAC[]; MESON_TAC[DIST_POS_LE]]; ALL_TAC] THEN + ASM_MESON_TAC[]);; + +let SETDIST_LE_DIST = prove + (`!s t x y:real^N. x IN s /\ y IN t ==> setdist(s,t) <= dist(x,y)`, + REPEAT GEN_TAC THEN REWRITE_TAC[setdist] THEN + COND_CASES_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + MP_TAC(ISPEC `{dist(x:real^N,y) | x IN s /\ y IN t}` INF) THEN + REWRITE_TAC[FORALL_IN_GSPEC] THEN ANTS_TAC THENL + [CONJ_TAC THENL [ASM SET_TAC[]; MESON_TAC[DIST_POS_LE]]; ALL_TAC] THEN + ASM_MESON_TAC[]);; + +let REAL_LE_SETDIST_EQ = prove + (`!d s t:real^N->bool. + d <= setdist(s,t) <=> + (!x y. x IN s /\ y IN t ==> d <= dist(x,y)) /\ + (s = {} \/ t = {} ==> d <= &0)`, + REPEAT GEN_TAC THEN MAP_EVERY ASM_CASES_TAC + [`s:real^N->bool = {}`; `t:real^N->bool = {}`] THEN + ASM_REWRITE_TAC[SETDIST_EMPTY; NOT_IN_EMPTY] THEN + ASM_MESON_TAC[REAL_LE_SETDIST; SETDIST_LE_DIST; REAL_LE_TRANS]);; + +let SETDIST_REFL = prove + (`!s:real^N->bool. setdist(s,s) = &0`, + GEN_TAC THEN REWRITE_TAC[GSYM REAL_LE_ANTISYM; SETDIST_POS_LE] THEN + ASM_CASES_TAC `s:real^N->bool = {}` THENL + [ASM_REWRITE_TAC[setdist; REAL_LE_REFL]; ALL_TAC] THEN + ASM_MESON_TAC[SETDIST_LE_DIST; MEMBER_NOT_EMPTY; DIST_REFL]);; + +let SETDIST_SYM = prove + (`!s t. setdist(s,t) = setdist(t,s)`, + REPEAT GEN_TAC THEN REWRITE_TAC[setdist; DISJ_SYM] THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN + AP_TERM_TAC THEN REWRITE_TAC[EXTENSION; IN_ELIM_THM] THEN + MESON_TAC[DIST_SYM]);; + +let SETDIST_TRIANGLE = prove + (`!s a t:real^N->bool. + setdist(s,t) <= setdist(s,{a}) + setdist({a},t)`, + REPEAT STRIP_TAC THEN ASM_CASES_TAC `s:real^N->bool = {}` THEN + ASM_REWRITE_TAC[SETDIST_EMPTY; REAL_ADD_LID; SETDIST_POS_LE] THEN + ASM_CASES_TAC `t:real^N->bool = {}` THEN + ASM_REWRITE_TAC[SETDIST_EMPTY; REAL_ADD_RID; SETDIST_POS_LE] THEN + ONCE_REWRITE_TAC[GSYM REAL_LE_SUB_RADD] THEN + MATCH_MP_TAC REAL_LE_SETDIST THEN + ASM_REWRITE_TAC[NOT_INSERT_EMPTY; IN_SING; IMP_CONJ; + RIGHT_FORALL_IMP_THM; FORALL_UNWIND_THM2] THEN + X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN + ONCE_REWRITE_TAC[REAL_ARITH `x - y <= z <=> x - z <= y`] THEN + MATCH_MP_TAC REAL_LE_SETDIST THEN + ASM_REWRITE_TAC[NOT_INSERT_EMPTY; IN_SING; IMP_CONJ; + RIGHT_FORALL_IMP_THM; FORALL_UNWIND_THM2] THEN + X_GEN_TAC `y:real^N` THEN STRIP_TAC THEN + REWRITE_TAC[REAL_LE_SUB_RADD] THEN MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `dist(x:real^N,y)` THEN + ASM_SIMP_TAC[SETDIST_LE_DIST] THEN CONV_TAC NORM_ARITH);; + +let SETDIST_SINGS = prove + (`!x y. setdist({x},{y}) = dist(x,y)`, + REWRITE_TAC[setdist; NOT_INSERT_EMPTY] THEN + REWRITE_TAC[SET_RULE `{f x y | x IN {a} /\ y IN {b}} = {f a b}`] THEN + SIMP_TAC[INF_INSERT_FINITE; FINITE_EMPTY]);; + +let SETDIST_LIPSCHITZ = prove + (`!s t x y:real^N. abs(setdist({x},s) - setdist({y},s)) <= dist(x,y)`, + REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM SETDIST_SINGS] THEN + REWRITE_TAC[REAL_ARITH + `abs(x - y) <= z <=> x <= z + y /\ y <= z + x`] THEN + MESON_TAC[SETDIST_TRIANGLE; SETDIST_SYM]);; + +let CONTINUOUS_AT_LIFT_SETDIST = prove + (`!s x:real^N. (\y. lift(setdist({y},s))) continuous (at x)`, + REPEAT STRIP_TAC THEN REWRITE_TAC[continuous_at; DIST_LIFT] THEN + ASM_MESON_TAC[SETDIST_LIPSCHITZ; REAL_LET_TRANS]);; + +let CONTINUOUS_ON_LIFT_SETDIST = prove + (`!s t:real^N->bool. (\y. lift(setdist({y},s))) continuous_on t`, + MESON_TAC[CONTINUOUS_AT_IMP_CONTINUOUS_ON; + CONTINUOUS_AT_LIFT_SETDIST]);; + +let UNIFORMLY_CONTINUOUS_ON_LIFT_SETDIST = prove + (`!s t:real^N->bool. + (\y. lift(setdist({y},s))) uniformly_continuous_on t`, + REPEAT GEN_TAC THEN REWRITE_TAC[uniformly_continuous_on; DIST_LIFT] THEN + ASM_MESON_TAC[SETDIST_LIPSCHITZ; REAL_LET_TRANS]);; + +let SETDIST_DIFFERENCES = prove + (`!s t. setdist(s,t) = setdist({vec 0},{x - y:real^N | x IN s /\ y IN t})`, + REPEAT GEN_TAC THEN REWRITE_TAC[setdist; NOT_INSERT_EMPTY; + SET_RULE `{f x y | x IN s /\ y IN t} = {} <=> s = {} \/ t = {}`] THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN AP_TERM_TAC THEN + REWRITE_TAC[EXTENSION; IN_ELIM_THM; IN_SING] THEN + REWRITE_TAC[GSYM CONJ_ASSOC; RIGHT_EXISTS_AND_THM; UNWIND_THM2; DIST_0] THEN + REWRITE_TAC[dist] THEN MESON_TAC[]);; + +let SETDIST_SUBSET_RIGHT = prove + (`!s t u:real^N->bool. + ~(t = {}) /\ t SUBSET u ==> setdist(s,u) <= setdist(s,t)`, + REPEAT STRIP_TAC THEN + MAP_EVERY ASM_CASES_TAC [`s:real^N->bool = {}`; `u:real^N->bool = {}`] THEN + ASM_REWRITE_TAC[SETDIST_EMPTY; SETDIST_POS_LE; REAL_LE_REFL] THEN + ASM_REWRITE_TAC[setdist] THEN MATCH_MP_TAC REAL_LE_INF_SUBSET THEN + ASM_REWRITE_TAC[FORALL_IN_GSPEC; SUBSET] THEN + REPEAT(CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC]) THEN + MESON_TAC[DIST_POS_LE]);; + +let SETDIST_SUBSET_LEFT = prove + (`!s t u:real^N->bool. + ~(s = {}) /\ s SUBSET t ==> setdist(t,u) <= setdist(s,u)`, + MESON_TAC[SETDIST_SUBSET_RIGHT; SETDIST_SYM]);; + +let SETDIST_CLOSURE = prove + (`(!s t:real^N->bool. setdist(closure s,t) = setdist(s,t)) /\ + (!s t:real^N->bool. setdist(s,closure t) = setdist(s,t))`, + GEN_REWRITE_TAC RAND_CONV [SWAP_FORALL_THM] THEN + GEN_REWRITE_TAC (RAND_CONV o ONCE_DEPTH_CONV) [SETDIST_SYM] THEN + REWRITE_TAC[] THEN + REWRITE_TAC[MESON[REAL_LE_ANTISYM] + `x:real = y <=> !d. d <= x <=> d <= y`] THEN + REPEAT GEN_TAC THEN REWRITE_TAC[REAL_LE_SETDIST_EQ] THEN + MAP_EVERY ASM_CASES_TAC [`s:real^N->bool = {}`; `t:real^N->bool = {}`] THEN + ASM_REWRITE_TAC[CLOSURE_EQ_EMPTY; CLOSURE_EMPTY; NOT_IN_EMPTY] THEN + MATCH_MP_TAC(SET_RULE + `s SUBSET c /\ + (!y. Q y /\ (!x. x IN s ==> P x y) ==> (!x. x IN c ==> P x y)) + ==> ((!x y. x IN c /\ Q y ==> P x y) <=> + (!x y. x IN s /\ Q y ==> P x y))`) THEN + REWRITE_TAC[CLOSURE_SUBSET] THEN GEN_TAC THEN STRIP_TAC THEN + MATCH_MP_TAC CONTINUOUS_GE_ON_CLOSURE THEN + ASM_REWRITE_TAC[o_DEF; dist] THEN + MATCH_MP_TAC CONTINUOUS_ON_LIFT_NORM_COMPOSE THEN + SIMP_TAC[CONTINUOUS_ON_SUB; CONTINUOUS_ON_CONST; CONTINUOUS_ON_ID]);; + +let SETDIST_COMPACT_CLOSED = prove + (`!s t:real^N->bool. + compact s /\ closed t /\ ~(s = {}) /\ ~(t = {}) + ==> ?x y. x IN s /\ y IN t /\ dist(x,y) = setdist(s,t)`, + REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM REAL_LE_ANTISYM] THEN + MATCH_MP_TAC(MESON[] + `(!x y. P x /\ Q y ==> S x y) /\ (?x y. P x /\ Q y /\ R x y) + ==> ?x y. P x /\ Q y /\ R x y /\ S x y`) THEN + SIMP_TAC[SETDIST_LE_DIST] THEN + ASM_REWRITE_TAC[REAL_LE_SETDIST_EQ] THEN + MP_TAC(ISPECL [`{x - y:real^N | x IN s /\ y IN t}`; `vec 0:real^N`] + DISTANCE_ATTAINS_INF) THEN + ASM_SIMP_TAC[COMPACT_CLOSED_DIFFERENCES; EXISTS_IN_GSPEC; FORALL_IN_GSPEC; + DIST_0; GSYM CONJ_ASSOC] THEN + REWRITE_TAC[dist] THEN DISCH_THEN MATCH_MP_TAC THEN ASM SET_TAC[]);; + +let SETDIST_CLOSED_COMPACT = prove + (`!s t:real^N->bool. + closed s /\ compact t /\ ~(s = {}) /\ ~(t = {}) + ==> ?x y. x IN s /\ y IN t /\ dist(x,y) = setdist(s,t)`, + REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM REAL_LE_ANTISYM] THEN + MATCH_MP_TAC(MESON[] + `(!x y. P x /\ Q y ==> S x y) /\ (?x y. P x /\ Q y /\ R x y) + ==> ?x y. P x /\ Q y /\ R x y /\ S x y`) THEN + SIMP_TAC[SETDIST_LE_DIST] THEN + ASM_REWRITE_TAC[REAL_LE_SETDIST_EQ] THEN + MP_TAC(ISPECL [`{x - y:real^N | x IN s /\ y IN t}`; `vec 0:real^N`] + DISTANCE_ATTAINS_INF) THEN + ASM_SIMP_TAC[CLOSED_COMPACT_DIFFERENCES; EXISTS_IN_GSPEC; FORALL_IN_GSPEC; + DIST_0; GSYM CONJ_ASSOC] THEN + REWRITE_TAC[dist] THEN DISCH_THEN MATCH_MP_TAC THEN ASM SET_TAC[]);; + +let SETDIST_EQ_0_COMPACT_CLOSED = prove + (`!s t:real^N->bool. + compact s /\ closed t + ==> (setdist(s,t) = &0 <=> s = {} \/ t = {} \/ ~(s INTER t = {}))`, + REPEAT STRIP_TAC THEN + MAP_EVERY ASM_CASES_TAC [`s:real^N->bool = {}`; `t:real^N->bool = {}`] THEN + ASM_REWRITE_TAC[SETDIST_EMPTY] THEN EQ_TAC THENL + [MP_TAC(ISPECL [`s:real^N->bool`; `t:real^N->bool`] + SETDIST_COMPACT_CLOSED) THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[EXTENSION; IN_INTER; NOT_IN_EMPTY] THEN MESON_TAC[DIST_EQ_0]; + REWRITE_TAC[GSYM REAL_LE_ANTISYM; SETDIST_POS_LE] THEN + REWRITE_TAC[EXTENSION; IN_INTER; NOT_IN_EMPTY] THEN + MESON_TAC[SETDIST_LE_DIST; DIST_EQ_0]]);; + +let SETDIST_EQ_0_CLOSED_COMPACT = prove + (`!s t:real^N->bool. + closed s /\ compact t + ==> (setdist(s,t) = &0 <=> s = {} \/ t = {} \/ ~(s INTER t = {}))`, + ONCE_REWRITE_TAC[SETDIST_SYM] THEN + SIMP_TAC[SETDIST_EQ_0_COMPACT_CLOSED] THEN SET_TAC[]);; + +let SETDIST_EQ_0_BOUNDED = prove + (`!s t:real^N->bool. + (bounded s \/ bounded t) + ==> (setdist(s,t) = &0 <=> + s = {} \/ t = {} \/ ~(closure(s) INTER closure(t) = {}))`, + REPEAT GEN_TAC THEN + MAP_EVERY ASM_CASES_TAC [`s:real^N->bool = {}`; `t:real^N->bool = {}`] THEN + ASM_REWRITE_TAC[SETDIST_EMPTY] THEN STRIP_TAC THEN + ONCE_REWRITE_TAC[MESON[SETDIST_CLOSURE] + `setdist(s,t) = setdist(closure s,closure t)`] THEN + ASM_SIMP_TAC[SETDIST_EQ_0_COMPACT_CLOSED; SETDIST_EQ_0_CLOSED_COMPACT; + COMPACT_CLOSURE; CLOSED_CLOSURE; CLOSURE_EQ_EMPTY]);; + + +let SETDIST_TRANSLATION = prove + (`!a:real^N s t. + setdist(IMAGE (\x. a + x) s,IMAGE (\x. a + x) t) = setdist(s,t)`, + REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[SETDIST_DIFFERENCES] THEN + AP_TERM_TAC THEN AP_TERM_TAC THEN + REWRITE_TAC[SET_RULE + `{f x y | x IN IMAGE g s /\ y IN IMAGE g t} = + {f (g x) (g y) | x IN s /\ y IN t}`] THEN + REWRITE_TAC[VECTOR_ARITH `(a + x) - (a + y):real^N = x - y`]);; + +add_translation_invariants [SETDIST_TRANSLATION];; + +let SETDIST_LINEAR_IMAGE = prove + (`!f:real^M->real^N s t. + linear f /\ (!x. norm(f x) = norm x) + ==> setdist(IMAGE f s,IMAGE f t) = setdist(s,t)`, + REPEAT STRIP_TAC THEN REWRITE_TAC[setdist; IMAGE_EQ_EMPTY] THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[dist] THEN AP_TERM_TAC THEN + REWRITE_TAC[SET_RULE + `{f x y | x IN IMAGE g s /\ y IN IMAGE g t} = + {f (g x) (g y) | x IN s /\ y IN t}`] THEN + FIRST_X_ASSUM(fun th -> REWRITE_TAC[GSYM(MATCH_MP LINEAR_SUB th)]) THEN + ASM_REWRITE_TAC[]);; + +add_linear_invariants [SETDIST_LINEAR_IMAGE];; + +let SETDIST_UNIQUE = prove + (`!s t a b:real^N d. + a IN s /\ b IN t /\ dist(a,b) = d /\ + (!x y. x IN s /\ y IN t ==> dist(a,b) <= dist(x,y)) + ==> setdist(s,t) = d`, + REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM REAL_LE_ANTISYM] THEN CONJ_TAC THENL + [ASM_MESON_TAC[SETDIST_LE_DIST]; + MATCH_MP_TAC REAL_LE_SETDIST THEN ASM SET_TAC[]]);; + +let SETDIST_CLOSEST_POINT = prove + (`!a:real^N s. + closed s /\ ~(s = {}) ==> setdist({a},s) = dist(a,closest_point s a)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC SETDIST_UNIQUE THEN + REWRITE_TAC[RIGHT_EXISTS_AND_THM; IN_SING; UNWIND_THM2] THEN + EXISTS_TAC `closest_point s (a:real^N)` THEN + ASM_MESON_TAC[CLOSEST_POINT_EXISTS; DIST_SYM]);; + +let SETDIST_EQ_0_SING = prove + (`(!s x:real^N. setdist({x},s) = &0 <=> s = {} \/ x IN closure s) /\ + (!s x:real^N. setdist(s,{x}) = &0 <=> s = {} \/ x IN closure s)`, + SIMP_TAC[SETDIST_EQ_0_BOUNDED; BOUNDED_SING; CLOSURE_SING] THEN SET_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* Use set distance for an easy proof of separation properties. *) +(* ------------------------------------------------------------------------- *) + +let SEPARATION_CLOSURES = prove + (`!s t:real^N->bool. + s INTER closure(t) = {} /\ t INTER closure(s) = {} + ==> ?u v. DISJOINT u v /\ open u /\ open v /\ + s SUBSET u /\ t SUBSET v`, + REPEAT STRIP_TAC THEN + ASM_CASES_TAC `s:real^N->bool = {}` THENL + [MAP_EVERY EXISTS_TAC [`{}:real^N->bool`; `(:real^N)`] THEN + ASM_REWRITE_TAC[OPEN_EMPTY; OPEN_UNIV] THEN ASM SET_TAC[]; + ALL_TAC] THEN + ASM_CASES_TAC `t:real^N->bool = {}` THENL + [MAP_EVERY EXISTS_TAC [`(:real^N)`; `{}:real^N->bool`] THEN + ASM_REWRITE_TAC[OPEN_EMPTY; OPEN_UNIV] THEN ASM SET_TAC[]; + ALL_TAC] THEN + EXISTS_TAC `{x | x IN (:real^N) /\ + lift(setdist({x},t) - setdist({x},s)) IN + {x | &0 < x$1}}` THEN + EXISTS_TAC `{x | x IN (:real^N) /\ + lift(setdist({x},t) - setdist({x},s)) IN + {x | x$1 < &0}}` THEN + REPEAT CONJ_TAC THENL + [REWRITE_TAC[SET_RULE `DISJOINT s t <=> !x. x IN s /\ x IN t ==> F`] THEN + REWRITE_TAC[IN_ELIM_THM; IN_UNIV] THEN REAL_ARITH_TAC; + MATCH_MP_TAC CONTINUOUS_OPEN_PREIMAGE THEN + SIMP_TAC[REWRITE_RULE[real_gt] OPEN_HALFSPACE_COMPONENT_GT; OPEN_UNIV] THEN + SIMP_TAC[LIFT_SUB; CONTINUOUS_ON_SUB; CONTINUOUS_ON_LIFT_SETDIST]; + MATCH_MP_TAC CONTINUOUS_OPEN_PREIMAGE THEN + SIMP_TAC[OPEN_HALFSPACE_COMPONENT_LT; OPEN_UNIV] THEN + SIMP_TAC[LIFT_SUB; CONTINUOUS_ON_SUB; CONTINUOUS_ON_LIFT_SETDIST]; + REWRITE_TAC[SUBSET; IN_ELIM_THM; IN_UNIV; GSYM drop; LIFT_DROP] THEN + GEN_TAC THEN DISCH_TAC THEN MATCH_MP_TAC(REAL_ARITH + `&0 <= x /\ y = &0 /\ ~(x = &0) ==> &0 < x - y`); + REWRITE_TAC[SUBSET; IN_ELIM_THM; IN_UNIV; GSYM drop; LIFT_DROP] THEN + GEN_TAC THEN DISCH_TAC THEN MATCH_MP_TAC(REAL_ARITH + `&0 <= y /\ x = &0 /\ ~(y = &0) ==> x - y < &0`)] THEN + ASM_SIMP_TAC[SETDIST_POS_LE; SETDIST_EQ_0_BOUNDED; BOUNDED_SING] THEN + ASM_SIMP_TAC[CLOSED_SING; CLOSURE_CLOSED; NOT_INSERT_EMPTY; + REWRITE_RULE[SUBSET] CLOSURE_SUBSET; + SET_RULE `{a} INTER s = {} <=> ~(a IN s)`] THEN + ASM SET_TAC[]);; + +let SEPARATION_NORMAL = prove + (`!s t:real^N->bool. + closed s /\ closed t /\ s INTER t = {} + ==> ?u v. open u /\ open v /\ + s SUBSET u /\ t SUBSET v /\ u INTER v = {}`, + REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM DISJOINT] THEN + ONCE_REWRITE_TAC[TAUT + `a /\ b /\ c /\ d /\ e <=> e /\ a /\ b /\ c /\ d`] THEN + MATCH_MP_TAC SEPARATION_CLOSURES THEN + ASM_SIMP_TAC[CLOSURE_CLOSED] THEN ASM SET_TAC[]);; + +let SEPARATION_NORMAL_COMPACT = prove + (`!s t:real^N->bool. + compact s /\ closed t /\ s INTER t = {} + ==> ?u v. open u /\ compact(closure u) /\ open v /\ + s SUBSET u /\ t SUBSET v /\ u INTER v = {}`, + REWRITE_TAC[COMPACT_EQ_BOUNDED_CLOSED; CLOSED_CLOSURE] THEN + REPEAT STRIP_TAC THEN FIRST_ASSUM + (MP_TAC o SPEC `vec 0:real^N` o MATCH_MP BOUNDED_SUBSET_BALL) THEN + DISCH_THEN(X_CHOOSE_THEN `r:real` STRIP_ASSUME_TAC) THEN + MP_TAC(ISPECL [`s:real^N->bool`; `t UNION ((:real^N) DIFF ball(vec 0,r))`] + SEPARATION_NORMAL) THEN + ASM_SIMP_TAC[CLOSED_UNION; GSYM OPEN_CLOSED; OPEN_BALL] THEN + ANTS_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + REPEAT(MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC) THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + CONJ_TAC THENL [MATCH_MP_TAC BOUNDED_CLOSURE; ASM SET_TAC[]] THEN + MATCH_MP_TAC BOUNDED_SUBSET THEN EXISTS_TAC `ball(vec 0:real^N,r)` THEN + REWRITE_TAC[BOUNDED_BALL] THEN ASM SET_TAC[]);; + +let SEPARATION_HAUSDORFF = prove + (`!x:real^N y. + ~(x = y) + ==> ?u v. open u /\ open v /\ x IN u /\ y IN v /\ (u INTER v = {})`, + REPEAT STRIP_TAC THEN + MP_TAC(SPECL [`{x:real^N}`; `{y:real^N}`] SEPARATION_NORMAL) THEN + REWRITE_TAC[SING_SUBSET; CLOSED_SING] THEN + DISCH_THEN MATCH_MP_TAC THEN ASM SET_TAC[]);; + +let SEPARATION_T2 = prove + (`!x:real^N y. + ~(x = y) <=> ?u v. open u /\ open v /\ x IN u /\ y IN v /\ + (u INTER v = {})`, + REPEAT STRIP_TAC THEN EQ_TAC THEN ASM_SIMP_TAC[SEPARATION_HAUSDORFF] THEN + REWRITE_TAC[EXTENSION; IN_INTER; NOT_IN_EMPTY] THEN MESON_TAC[]);; + +let SEPARATION_T1 = prove + (`!x:real^N y. + ~(x = y) <=> ?u v. open u /\ open v /\ x IN u /\ ~(y IN u) /\ + ~(x IN v) /\ y IN v`, + REPEAT STRIP_TAC THEN EQ_TAC THENL + [ASM_SIMP_TAC[SEPARATION_T2; EXTENSION; NOT_IN_EMPTY; IN_INTER]; + ALL_TAC] THEN MESON_TAC[]);; + +let SEPARATION_T0 = prove + (`!x:real^N y. ~(x = y) <=> ?u. open u /\ ~(x IN u <=> y IN u)`, + MESON_TAC[SEPARATION_T1]);; + +let CLOSED_COMPACT_PROJECTION = prove + (`!s:real^M->bool t:real^(M,N)finite_sum->bool. + compact s /\ closed t + ==> closed {y | ?x. x IN s /\ (pastecart x y) IN t}`, + REPEAT STRIP_TAC THEN + ASM_CASES_TAC `s:real^M->bool = {}` THEN + ASM_CASES_TAC `t:real^(M,N)finite_sum->bool = {}` THEN + ASM_REWRITE_TAC[NOT_IN_EMPTY; EMPTY_GSPEC; CLOSED_EMPTY] THEN + REWRITE_TAC[closed; open_def; IN_DIFF; IN_UNIV; IN_ELIM_THM] THEN + X_GEN_TAC `y:real^N` THEN DISCH_TAC THEN + EXISTS_TAC `setdist({pastecart (x:real^M) (y:real^N) | x IN s},t)` THEN + CONJ_TAC THENL + [REWRITE_TAC[REAL_LT_LE; SETDIST_POS_LE] THEN + ONCE_REWRITE_TAC[EQ_SYM_EQ] THEN + W(MP_TAC o PART_MATCH (lhs o rand) SETDIST_EQ_0_COMPACT_CLOSED o + rand o snd) THEN + ANTS_TAC THENL + [REWRITE_TAC[SET_RULE + `{pastecart x y | P x} = {pastecart x z | P x /\ z IN {y}}`] THEN + REWRITE_TAC[GSYM PCROSS] THEN + ASM_SIMP_TAC[COMPACT_PCROSS; COMPACT_SING]; + DISCH_THEN SUBST1_TAC THEN ASM_REWRITE_TAC[] THEN ASM SET_TAC[]]; + X_GEN_TAC `z:real^N` THEN ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN + REWRITE_TAC[REAL_NOT_LT] THEN + DISCH_THEN(X_CHOOSE_THEN `w:real^M` STRIP_ASSUME_TAC) THEN + MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `dist(pastecart (w:real^M) (y:real^N),pastecart w z)` THEN + CONJ_TAC THENL + [MATCH_MP_TAC SETDIST_LE_DIST THEN ASM SET_TAC[]; + REWRITE_TAC[DIST_PASTECART_CANCEL; REAL_LE_REFL; DIST_SYM]]]);; + +let CLOSED_IN_COMPACT_PROJECTION = prove + (`!s:real^M->bool t:real^N->bool u. + compact s /\ + closed_in (subtopology euclidean (s PCROSS t)) u + ==> closed_in (subtopology euclidean t) + {y | ?x. x IN s /\ pastecart x y IN u}`, + REPEAT GEN_TAC THEN REWRITE_TAC[PCROSS; CLOSED_IN_CLOSED] THEN + REWRITE_TAC[RIGHT_AND_EXISTS_THM; CONJ_ASSOC] THEN + DISCH_THEN(CHOOSE_THEN(CONJUNCTS_THEN2 MP_TAC SUBST1_TAC)) THEN + DISCH_THEN(MP_TAC o MATCH_MP CLOSED_COMPACT_PROJECTION) THEN + MATCH_MP_TAC(MESON[] + `P p==> (closed p ==> ?t. closed t /\ P t)`) THEN + REWRITE_TAC[IN_ELIM_PASTECART_THM; IN_INTER] THEN SET_TAC[]);; + +let TUBE_LEMMA = prove + (`!s:real^M->bool t:real^N->bool u a. + compact s /\ ~(s = {}) /\ {pastecart x a | x IN s} SUBSET u /\ + open_in(subtopology euclidean (s PCROSS t)) u + ==> ?v. open_in (subtopology euclidean t) v /\ a IN v /\ + (s PCROSS v) SUBSET u`, + REPEAT GEN_TAC THEN REWRITE_TAC[PCROSS] THEN + REWRITE_TAC[OPEN_IN_CLOSED_IN_EQ] THEN + REWRITE_TAC[TOPSPACE_EUCLIDEAN_SUBTOPOLOGY] THEN + REPEAT STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ_ALT; PCROSS] + CLOSED_IN_COMPACT_PROJECTION)) THEN + ASM_REWRITE_TAC[IN_ELIM_PASTECART_THM; IN_DIFF] THEN + REWRITE_TAC[GSYM CONJ_ASSOC] THEN MATCH_MP_TAC(MESON[] + `(closed_in top t ==> s DIFF (s DIFF t) = t) /\ + s DIFF t SUBSET s /\ P(s DIFF t) + ==> closed_in top t + ==> ?v. v SUBSET s /\ closed_in top (s DIFF v) /\ P v`) THEN + REWRITE_TAC[SET_RULE `s DIFF (s DIFF t) = t <=> t SUBSET s`] THEN + REWRITE_TAC[SUBSET_DIFF] THEN + SIMP_TAC[closed_in; TOPSPACE_EUCLIDEAN_SUBTOPOLOGY] THEN + REWRITE_TAC[IN_DIFF; IN_ELIM_THM] THEN + REWRITE_TAC[SUBSET; FORALL_IN_GSPEC] THEN + CONJ_TAC THENL [ALL_TAC; MESON_TAC[]] THEN + REPEAT(FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [SUBSET])) THEN + REWRITE_TAC[FORALL_IN_GSPEC; IN_SING; FORALL_PASTECART] THEN + REWRITE_TAC[IN_ELIM_PASTECART_THM] THEN ASM_MESON_TAC[MEMBER_NOT_EMPTY]);; + +(* ------------------------------------------------------------------------- *) +(* Urysohn's lemma (for real^N, where the proof is easy using distances). *) +(* ------------------------------------------------------------------------- *) + +let URYSOHN_LOCAL_STRONG = prove + (`!s t u a b. + closed_in (subtopology euclidean u) s /\ + closed_in (subtopology euclidean u) t /\ + s INTER t = {} /\ ~(a = b) + ==> ?f:real^N->real^M. + f continuous_on u /\ + (!x. x IN u ==> f(x) IN segment[a,b]) /\ + (!x. x IN u ==> (f x = a <=> x IN s)) /\ + (!x. x IN u ==> (f x = b <=> x IN t))`, + let lemma = prove + (`!s t u a b. + closed_in (subtopology euclidean u) s /\ + closed_in (subtopology euclidean u) t /\ + s INTER t = {} /\ ~(s = {}) /\ ~(t = {}) /\ ~(a = b) + ==> ?f:real^N->real^M. + f continuous_on u /\ + (!x. x IN u ==> f(x) IN segment[a,b]) /\ + (!x. x IN u ==> (f x = a <=> x IN s)) /\ + (!x. x IN u ==> (f x = b <=> x IN t))`, + REPEAT STRIP_TAC THEN EXISTS_TAC + `\x:real^N. a + setdist({x},s) / (setdist({x},s) + setdist({x},t)) % + (b - a:real^M)` THEN REWRITE_TAC[] THEN + SUBGOAL_THEN + `(!x:real^N. x IN u ==> (setdist({x},s) = &0 <=> x IN s)) /\ + (!x:real^N. x IN u ==> (setdist({x},t) = &0 <=> x IN t))` + STRIP_ASSUME_TAC THENL + [ASM_REWRITE_TAC[SETDIST_EQ_0_SING] THEN CONJ_TAC THENL + [MP_TAC(ISPEC `s:real^N->bool` CLOSED_IN_CLOSED); + MP_TAC(ISPEC `t:real^N->bool` CLOSED_IN_CLOSED)] THEN + DISCH_THEN(MP_TAC o SPEC `u:real^N->bool`) THEN + ASM_REWRITE_TAC[] THEN DISCH_THEN(X_CHOOSE_THEN `v:real^N->bool` + (CONJUNCTS_THEN2 ASSUME_TAC SUBST_ALL_TAC)) THEN + ASM_MESON_TAC[CLOSURE_CLOSED; INTER_SUBSET; SUBSET_CLOSURE; SUBSET; + IN_INTER; CLOSURE_SUBSET]; + ALL_TAC] THEN + SUBGOAL_THEN `!x:real^N. x IN u ==> &0 < setdist({x},s) + setdist({x},t)` + ASSUME_TAC THENL + [REPEAT STRIP_TAC THEN MATCH_MP_TAC(REAL_ARITH + `&0 <= x /\ &0 <= y /\ ~(x = &0 /\ y = &0) ==> &0 < x + y`) THEN + REWRITE_TAC[SETDIST_POS_LE] THEN ASM SET_TAC[]; + ALL_TAC] THEN + REPEAT CONJ_TAC THENL + [MATCH_MP_TAC CONTINUOUS_ON_ADD THEN REWRITE_TAC[CONTINUOUS_ON_CONST] THEN + REWRITE_TAC[real_div; GSYM VECTOR_MUL_ASSOC] THEN + REPEAT(MATCH_MP_TAC CONTINUOUS_ON_MUL THEN CONJ_TAC) THEN + REWRITE_TAC[CONTINUOUS_ON_CONST; o_DEF] THEN + REWRITE_TAC[CONTINUOUS_ON_LIFT_SETDIST] THEN + MATCH_MP_TAC(REWRITE_RULE[o_DEF] CONTINUOUS_ON_INV) THEN + ASM_SIMP_TAC[REAL_LT_IMP_NZ] THEN + REWRITE_TAC[LIFT_ADD] THEN MATCH_MP_TAC CONTINUOUS_ON_ADD THEN + REWRITE_TAC[CONTINUOUS_ON_LIFT_SETDIST]; + X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN + REWRITE_TAC[segment; IN_ELIM_THM] THEN + REWRITE_TAC[VECTOR_MUL_EQ_0; LEFT_OR_DISTRIB; VECTOR_ARITH + `a + x % (b - a):real^N = (&1 - u) % a + u % b <=> + (x - u) % (b - a) = vec 0`; + EXISTS_OR_THM] THEN + DISJ1_TAC THEN ONCE_REWRITE_TAC[CONJ_SYM] THEN + REWRITE_TAC[REAL_SUB_0; UNWIND_THM1] THEN + ASM_SIMP_TAC[REAL_LE_DIV; REAL_LE_ADD; SETDIST_POS_LE; REAL_LE_LDIV_EQ; + REAL_ARITH `a <= &1 * (a + b) <=> &0 <= b`]; + REWRITE_TAC[VECTOR_ARITH `a + x:real^N = a <=> x = vec 0`]; + REWRITE_TAC[VECTOR_ARITH `a + x % (b - a):real^N = b <=> + (x - &1) % (b - a) = vec 0`]] THEN + ASM_REWRITE_TAC[VECTOR_MUL_EQ_0; VECTOR_SUB_EQ] THEN + ASM_SIMP_TAC[REAL_SUB_0; REAL_EQ_LDIV_EQ; + REAL_MUL_LZERO; REAL_MUL_LID] THEN + REWRITE_TAC[REAL_ARITH `x:real = x + y <=> y = &0`] THEN + ASM_REWRITE_TAC[]) in + MATCH_MP_TAC(MESON[] + `(!s t. P s t <=> P t s) /\ + (!s t. ~(s = {}) /\ ~(t = {}) ==> P s t) /\ + P {} {} /\ (!t. ~(t = {}) ==> P {} t) + ==> !s t. P s t`) THEN + REPEAT CONJ_TAC THENL + [REPEAT GEN_TAC THEN + GEN_REWRITE_TAC (RAND_CONV o BINDER_CONV) [SWAP_FORALL_THM] THEN + REPEAT(AP_TERM_TAC THEN ABS_TAC) THEN + REWRITE_TAC[SEGMENT_SYM; INTER_COMM; CONJ_ACI; EQ_SYM_EQ]; + SIMP_TAC[lemma]; + REPEAT STRIP_TAC THEN EXISTS_TAC `(\x. midpoint(a,b)):real^N->real^M` THEN + ASM_SIMP_TAC[NOT_IN_EMPTY; CONTINUOUS_ON_CONST; MIDPOINT_IN_SEGMENT] THEN + REWRITE_TAC[midpoint] THEN CONJ_TAC THEN GEN_TAC THEN DISCH_TAC THEN + UNDISCH_TAC `~(a:real^M = b)` THEN REWRITE_TAC[CONTRAPOS_THM] THEN + VECTOR_ARITH_TAC; + REPEAT STRIP_TAC THEN ASM_CASES_TAC `t:real^N->bool = u` THENL + [EXISTS_TAC `(\x. b):real^N->real^M` THEN + ASM_REWRITE_TAC[NOT_IN_EMPTY; ENDS_IN_SEGMENT; IN_UNIV; + CONTINUOUS_ON_CONST]; + SUBGOAL_THEN `?c:real^N. c IN u /\ ~(c IN t)` STRIP_ASSUME_TAC THENL + [REPEAT(FIRST_X_ASSUM(MP_TAC o MATCH_MP CLOSED_IN_SUBSET)) THEN + REWRITE_TAC[TOPSPACE_EUCLIDEAN_SUBTOPOLOGY] THEN ASM SET_TAC[]; + ALL_TAC] THEN + MP_TAC(ISPECL [`{c:real^N}`; `t:real^N->bool`; `u:real^N->bool`; + `midpoint(a,b):real^M`; `b:real^M`] lemma) THEN + ASM_REWRITE_TAC[CLOSED_IN_SING; MIDPOINT_EQ_ENDPOINT] THEN + ANTS_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + MATCH_MP_TAC MONO_EXISTS THEN SIMP_TAC[NOT_IN_EMPTY] THEN + X_GEN_TAC `f:real^N->real^M` THEN STRIP_TAC THEN CONJ_TAC THENL + [SUBGOAL_THEN + `segment[midpoint(a,b):real^M,b] SUBSET segment[a,b]` MP_TAC + THENL + [REWRITE_TAC[SUBSET; IN_SEGMENT; midpoint] THEN GEN_TAC THEN + DISCH_THEN(X_CHOOSE_THEN `u:real` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `(&1 + u) / &2` THEN ASM_REWRITE_TAC[] THEN + REPEAT(CONJ_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC]) THEN + VECTOR_ARITH_TAC; + ASM SET_TAC[]]; + SUBGOAL_THEN `~(a IN segment[midpoint(a,b):real^M,b])` MP_TAC THENL + [ALL_TAC; ASM_MESON_TAC[]] THEN + DISCH_THEN(MP_TAC o CONJUNCT2 o MATCH_MP DIST_IN_CLOSED_SEGMENT) THEN + REWRITE_TAC[DIST_MIDPOINT] THEN + UNDISCH_TAC `~(a:real^M = b)` THEN NORM_ARITH_TAC]]]);; + +let URYSOHN_LOCAL = prove + (`!s t u a b. + closed_in (subtopology euclidean u) s /\ + closed_in (subtopology euclidean u) t /\ + s INTER t = {} + ==> ?f:real^N->real^M. + f continuous_on u /\ + (!x. x IN u ==> f(x) IN segment[a,b]) /\ + (!x. x IN s ==> f x = a) /\ + (!x. x IN t ==> f x = b)`, + REPEAT STRIP_TAC THEN ASM_CASES_TAC `a:real^M = b` THENL + [EXISTS_TAC `(\x. b):real^N->real^M` THEN + ASM_REWRITE_TAC[ENDS_IN_SEGMENT; CONTINUOUS_ON_CONST]; + MP_TAC(ISPECL [`s:real^N->bool`; `t:real^N->bool`; `u:real^N->bool`; + `a:real^M`; `b:real^M`] URYSOHN_LOCAL_STRONG) THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC MONO_EXISTS THEN SIMP_TAC[] THEN + REPEAT(FIRST_X_ASSUM(MP_TAC o MATCH_MP CLOSED_IN_SUBSET)) THEN + REWRITE_TAC[TOPSPACE_EUCLIDEAN_SUBTOPOLOGY] THEN SET_TAC[]]);; + +let URYSOHN_STRONG = prove + (`!s t a b. + closed s /\ closed t /\ s INTER t = {} /\ ~(a = b) + ==> ?f:real^N->real^M. + f continuous_on (:real^N) /\ (!x. f(x) IN segment[a,b]) /\ + (!x. f x = a <=> x IN s) /\ (!x. f x = b <=> x IN t)`, + REPEAT GEN_TAC THEN REWRITE_TAC[CLOSED_IN] THEN + ONCE_REWRITE_TAC[GSYM SUBTOPOLOGY_UNIV] THEN + DISCH_THEN(MP_TAC o MATCH_MP URYSOHN_LOCAL_STRONG) THEN + REWRITE_TAC[IN_UNIV]);; + +let URYSOHN = prove + (`!s t a b. + closed s /\ closed t /\ s INTER t = {} + ==> ?f:real^N->real^M. + f continuous_on (:real^N) /\ (!x. f(x) IN segment[a,b]) /\ + (!x. x IN s ==> f x = a) /\ (!x. x IN t ==> f x = b)`, + REPEAT GEN_TAC THEN REWRITE_TAC[CLOSED_IN] THEN + ONCE_REWRITE_TAC[GSYM SUBTOPOLOGY_UNIV] THEN DISCH_THEN + (MP_TAC o ISPECL [`a:real^M`; `b:real^M`] o MATCH_MP URYSOHN_LOCAL) THEN + REWRITE_TAC[IN_UNIV]);; + +(* ------------------------------------------------------------------------- *) +(* Tietze extension theorem, likewise just for real^N. *) +(* ------------------------------------------------------------------------- *) + +let TIETZE_STEP = prove + (`!f:real^N->real^1 u s B. + &0 < B /\ closed_in (subtopology euclidean u) s /\ + f continuous_on s /\ + (!x. x IN s ==> norm(f x) <= B) + ==> ?g. g continuous_on u /\ + (!x. x IN u ==> norm(g x) <= B / &3) /\ + (!x. x IN s ==> norm(f x - g x) <= &2 / &3 * B)`, + REWRITE_TAC[NORM_REAL; GSYM drop; DROP_SUB] THEN REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`{x:real^N | x IN s /\ f x IN {y | drop y <= --(B / &3)}}`; + `{x:real^N | x IN s /\ f x IN {y | drop y >= B / &3}}`; + `u:real^N->bool`; + `lift(--(B / &3))`; `lift(B / &3)`] URYSOHN_LOCAL) THEN + ANTS_TAC THENL + [REWRITE_TAC[CONJ_ASSOC] THEN CONJ_TAC THENL + [ALL_TAC; + REWRITE_TAC[EXTENSION; IN_ELIM_THM; NOT_IN_EMPTY; IN_INTER] THEN + ASM_REAL_ARITH_TAC] THEN + CONJ_TAC THEN MATCH_MP_TAC CLOSED_IN_TRANS THEN + EXISTS_TAC `s:real^N->bool` THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC CONTINUOUS_CLOSED_IN_PREIMAGE THEN + ASM_REWRITE_TAC[] THENL + [MP_TAC(ISPECL [`lift(&1)`; `--(B / &3)`] CLOSED_HALFSPACE_LE); + MP_TAC(ISPECL [`lift(&1)`; `B / &3`] CLOSED_HALFSPACE_GE)] THEN + REWRITE_TAC[DOT_1; GSYM drop; LIFT_DROP; REAL_MUL_LID]; + ASM_SIMP_TAC[SEGMENT_1; IN_ELIM_THM; LIFT_DROP; IN_INTERVAL_1; + REAL_ARITH `&0 < B ==> --(B / &3) <= B / &3`] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `g:real^N->real^1` THEN + STRIP_TAC THEN ASM_REWRITE_TAC[NORM_REAL; GSYM drop] THEN + ASM_SIMP_TAC[GSYM REAL_BOUNDS_LE] THEN X_GEN_TAC `x:real^N` THEN + DISCH_TAC THEN REWRITE_TAC[DROP_SUB; REAL_BOUNDS_LE] THEN + FIRST_ASSUM(ASSUME_TAC o REWRITE_RULE[SUBSET] o MATCH_MP + CLOSED_IN_IMP_SUBSET) THEN + REPEAT_TCL DISJ_CASES_THEN ASSUME_TAC + (REAL_ARITH `drop(f x) <= --(B / &3) \/ drop(f x) >= B / &3 \/ + abs(drop(f(x:real^N))) <= B / &3`) + THENL + [UNDISCH_THEN + `!x:real^N. x IN s /\ drop(f x) <= --(B / &3) ==> g x = lift(--(B / &3))` + (MP_TAC o SPEC `x:real^N`); + UNDISCH_THEN + `!x:real^N. x IN s /\ drop(f x) >= B / &3 ==> g x = lift(B / &3)` + (MP_TAC o SPEC `x:real^N`); + MATCH_MP_TAC(REAL_ARITH + `abs(f) <= B / &3 /\ --(B / &3) <= g /\ g <= B / &3 + ==> abs(f - g) <= &2 / &3 * B`)] THEN + ASM_SIMP_TAC[] THEN DISCH_THEN SUBST_ALL_TAC THEN + UNDISCH_THEN `!x:real^N. x IN s ==> abs(drop(f x)) <= B` + (MP_TAC o SPEC `x:real^N`) THEN + ASM_REWRITE_TAC[LIFT_DROP] THEN ASM_REAL_ARITH_TAC]);; + +let TIETZE = prove + (`!f:real^N->real^1 u s B. + &0 <= B /\ + closed_in (subtopology euclidean u) s /\ + f continuous_on s /\ + (!x. x IN s ==> norm(f x) <= B) + ==> ?g. g continuous_on u /\ + (!x. x IN s ==> g x = f x) /\ + (!x. x IN u ==> norm(g x) <= B)`, + REPEAT STRIP_TAC THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP CLOSED_IN_IMP_SUBSET) THEN + FIRST_X_ASSUM(MP_TAC o MATCH_MP (REAL_ARITH + `&0 <= B ==> B = &0 \/ &0 < B`)) THEN + DISCH_THEN(DISJ_CASES_THEN2 SUBST_ALL_TAC ASSUME_TAC) THENL + [EXISTS_TAC `\x:real^N. (vec 0:real^1)` THEN + ASM_SIMP_TAC[CONTINUOUS_ON_CONST; NORM_0; REAL_LE_REFL] THEN + ASM_MESON_TAC[NORM_LE_0]; + ALL_TAC] THEN + MP_TAC(ISPECL [`f:real^N->real^1`; `u:real^N->bool`; + `s:real^N->bool`; `B:real`] + TIETZE_STEP) THEN + ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `g0:real^N->real^1` STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN + `?g. (g 0 = (g0:real^N->real^1)) /\ + (!n. g(SUC n) = + @h. h continuous_on u /\ + (!x. x IN u ==> + norm(h x) <= &2 pow SUC n * B / &3 pow (SUC n + 1)) /\ + (!x. x IN s ==> norm(f x - vsum(0..n) (\i. g i x) - h x) + <= &2 pow (SUC n + 1) * B / &3 pow (SUC n + 1)))` + STRIP_ASSUME_TAC THENL + [SIMP_TAC[VSUM_REAL; FINITE_NUMSEG; o_DEF] THEN + W(ACCEPT_TAC o prove_general_recursive_function_exists o snd); + ALL_TAC] THEN + SUBGOAL_THEN + `!n. (!m. m < n ==> g m continuous_on u) /\ + g n continuous_on u /\ + (!x. x IN u ==> norm(g n x:real^1) <= &2 pow n * B / &3 pow (n + 1)) /\ + (!x:real^N. x IN s ==> norm(f x - vsum(0..n) (\i. g i x)) + <= &2 pow (n + 1) * B / &3 pow (n + 1))` + ASSUME_TAC THENL + [INDUCT_TAC THEN ASM_REWRITE_TAC[VSUM_CLAUSES_NUMSEG; LT] THENL + [CONV_TAC NUM_REDUCE_CONV THEN CONV_TAC REAL_RAT_REDUCE_CONV THEN + ASM_REWRITE_TAC[REAL_MUL_LID; REAL_ARITH `&2 * B / &3 = &2 / &3 * B`]; + ALL_TAC] THEN + ASM_REWRITE_TAC[MESON[] `(!m:num. m = n \/ m < n ==> P m) <=> + (!m. m < n ==> P m) /\ P n`] THEN + REWRITE_TAC[LE_0; VECTOR_ARITH `f - (g + h):real^1 = f - g - h`] THEN + CONV_TAC SELECT_CONV THEN + REWRITE_TAC[REAL_POW_ADD; REAL_ARITH + `(&2 pow (SUC n) * &2 pow 1) * B = &2 * &2 pow (SUC n) * B`] THEN + REWRITE_TAC[real_div; REAL_INV_MUL; REAL_POW_1] THEN + REWRITE_TAC[REAL_ARITH `a * b * inv c * inv d = (a * b / c) / d`] THEN + REWRITE_TAC[REAL_ARITH `&2 * x / &3 = &2 / &3 * x`] THEN + MATCH_MP_TAC TIETZE_STEP THEN + ASM_SIMP_TAC[REAL_LT_DIV; ADD1; REAL_LT_MUL; REAL_POW_LT; + REAL_OF_NUM_LT; ARITH] THEN + MATCH_MP_TAC CONTINUOUS_ON_SUB THEN ASM_REWRITE_TAC[ETA_AX] THEN + MATCH_MP_TAC CONTINUOUS_ON_VSUM THEN + REWRITE_TAC[FINITE_NUMSEG; IN_NUMSEG; LE_0] THEN REWRITE_TAC[LE_LT] THEN + GEN_TAC THEN STRIP_TAC THEN MATCH_MP_TAC CONTINUOUS_ON_SUBSET THEN + EXISTS_TAC `u:real^N->bool` THEN ASM_SIMP_TAC[]; + ALL_TAC] THEN + ABBREV_TAC `(h:num->real^N->real^1) = \n x. vsum(0..n) (\i. g i x)` THEN + SUBGOAL_THEN + `?k:real^N->real^1. + !e. &0 < e + ==> ?N:num. !n x. + N <= n /\ x IN u ==> dist(vsum (from 0 INTER (0..n)) + (\i. g i x),k x) < e` + MP_TAC THENL + [REWRITE_TAC[SERIES_CAUCHY_UNIFORM]; ALL_TAC] THEN + REWRITE_TAC[FROM_0; INTER_UNIV; IN_UNIV] THENL + [X_GEN_TAC `e:real` THEN DISCH_TAC THEN + MP_TAC(ISPECL [`&2 / &3`; `e / B`] REAL_ARCH_POW_INV) THEN + ASM_SIMP_TAC[REAL_LT_DIV] THEN CONV_TAC REAL_RAT_REDUCE_CONV THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `N:num` THEN DISCH_TAC THEN + MAP_EVERY X_GEN_TAC [`m:num`; `n:num`; `x:real^N`] THEN DISCH_TAC THEN + MATCH_MP_TAC REAL_LET_TRANS THEN + EXISTS_TAC `sum(m..n) (\i. &2 pow i * B / &3 pow (i + 1))` THEN + ASM_SIMP_TAC[VSUM_NORM_LE; FINITE_NUMSEG] THEN + REWRITE_TAC[REAL_POW_ADD; real_div; REAL_INV_MUL] THEN + REWRITE_TAC[REAL_ARITH `x * B * inv y * inv(&3 pow 1) = B / &3 * x / y`; + SUM_LMUL; GSYM REAL_POW_DIV] THEN + REWRITE_TAC[SUM_GP] THEN CONV_TAC REAL_RAT_REDUCE_CONV THEN + COND_CASES_TAC THENL + [ASM_REWRITE_TAC[real_div; REAL_MUL_LZERO; REAL_MUL_RZERO]; ALL_TAC] THEN + REWRITE_TAC[REAL_ARITH `B / &3 * x / (&1 / &3) < e <=> x * B < e`] THEN + ASM_SIMP_TAC[GSYM REAL_LT_RDIV_EQ] THEN + MATCH_MP_TAC(REAL_ARITH `&0 < y /\ x < e ==> x - y < e`) THEN + ASM_SIMP_TAC[REAL_POW_LT; REAL_LT_DIV; REAL_OF_NUM_LT; ARITH] THEN + MATCH_MP_TAC REAL_LET_TRANS THEN EXISTS_TAC `(&2 / &3) pow N` THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC REAL_POW_MONO_INV THEN + ASM_REWRITE_TAC[] THEN CONV_TAC REAL_RAT_REDUCE_CONV; + ALL_TAC] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `k:real^N->real^1` THEN + DISCH_TAC THEN REPEAT CONJ_TAC THENL + [MATCH_MP_TAC(ISPEC `sequentially` CONTINUOUS_UNIFORM_LIMIT) THEN + EXISTS_TAC `\n x:real^N. vsum (0..n) (\i. g i x :real^1)` THEN + ASM_REWRITE_TAC[TRIVIAL_LIMIT_SEQUENTIALLY; EVENTUALLY_SEQUENTIALLY] THEN + ASM_REWRITE_TAC[IN_UNIV; IMP_IMP; RIGHT_IMP_FORALL_THM; GSYM dist] THEN + EXISTS_TAC `0` THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC CONTINUOUS_ON_VSUM THEN ASM_REWRITE_TAC[FINITE_NUMSEG]; + X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN + MATCH_MP_TAC(NORM_ARITH `~(&0 < norm(x - y)) ==> x = y`) THEN + DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `norm((k:real^N->real^1) x - f x) / &2`) THEN + ASM_REWRITE_TAC[REAL_HALF; NOT_EXISTS_THM] THEN + X_GEN_TAC `N1:num` THEN DISCH_THEN(LABEL_TAC "*") THEN + MP_TAC(ISPECL [`&2 / &3`; `norm((k:real^N->real^1) x - f x) / &2 / B`] + REAL_ARCH_POW_INV) THEN + ASM_SIMP_TAC[REAL_LT_DIV; REAL_HALF] THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN ASM_SIMP_TAC[REAL_LT_RDIV_EQ] THEN + ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN + DISCH_THEN(X_CHOOSE_THEN `N2:num` (LABEL_TAC "+")) THEN + REMOVE_THEN "*" (MP_TAC o SPECL [`N1 + N2:num`; `x:real^N`]) THEN + REWRITE_TAC[LE_ADD; NOT_IMP] THEN + CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN MATCH_MP_TAC(NORM_ARITH + `norm(f - s) < norm(k - f) / &2 + ==> ~(dist(s,k) < norm(k - f) / &2)`) THEN + MATCH_MP_TAC REAL_LET_TRANS THEN + EXISTS_TAC `B * (&2 / &3) pow N2` THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `&2 pow ((N1 + N2) + 1) * B / &3 pow ((N1 + N2) + 1)` THEN + ASM_SIMP_TAC[] THEN + ONCE_REWRITE_TAC[REAL_ARITH `x * B / y = B * x / y`] THEN + ASM_SIMP_TAC[REAL_LE_LMUL_EQ; GSYM REAL_POW_DIV] THEN + MATCH_MP_TAC REAL_POW_MONO_INV THEN + ASM_REWRITE_TAC[] THEN CONV_TAC REAL_RAT_REDUCE_CONV THEN ARITH_TAC; + X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN + MATCH_MP_TAC(ISPEC `sequentially` LIM_NORM_UBOUND) THEN + EXISTS_TAC `\n. vsum(0..n) (\i. (g:num->real^N->real^1) i x)` THEN + REWRITE_TAC[TRIVIAL_LIMIT_SEQUENTIALLY; EVENTUALLY_SEQUENTIALLY] THEN + CONJ_TAC THENL + [REWRITE_TAC[LIM_SEQUENTIALLY] THEN ASM_MESON_TAC[]; ALL_TAC] THEN + EXISTS_TAC `0` THEN X_GEN_TAC `n:num` THEN DISCH_TAC THEN + MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `sum(0..n) (\i. &2 pow i * B / &3 pow (i + 1))` THEN + ASM_SIMP_TAC[VSUM_NORM_LE; FINITE_NUMSEG] THEN + REWRITE_TAC[REAL_POW_ADD; real_div; REAL_INV_MUL] THEN + REWRITE_TAC[REAL_ARITH `x * B * inv y * inv(&3 pow 1) = B / &3 * x / y`; + SUM_LMUL; GSYM REAL_POW_DIV] THEN + REWRITE_TAC[REAL_ARITH `B / &3 * x <= B <=> B * x / &3 <= B * &1`] THEN + ASM_SIMP_TAC[REAL_LE_LMUL_EQ; REAL_LE_LDIV_EQ; REAL_OF_NUM_LT; ARITH] THEN + REWRITE_TAC[SUM_GP] THEN CONV_TAC REAL_RAT_REDUCE_CONV THEN + COND_CASES_TAC THENL + [SIMP_TAC[real_div; REAL_MUL_LZERO; REAL_MUL_RZERO; REAL_POS]; + ALL_TAC] THEN + REWRITE_TAC[REAL_ARITH `x / (&1 / &3) <= &3 <=> x <= &1`] THEN + REWRITE_TAC[REAL_ARITH `&1 - x <= &1 <=> &0 <= x`] THEN + MATCH_MP_TAC REAL_POW_LE THEN CONV_TAC REAL_RAT_REDUCE_CONV]);; + +(* ------------------------------------------------------------------------- *) +(* The same result for intervals in real^1. *) +(* ------------------------------------------------------------------------- *) + +let TIETZE_CLOSED_INTERVAL_1 = prove + (`!f:real^N->real^1 u s a b. + drop a <= drop b /\ + closed_in (subtopology euclidean u) s /\ + f continuous_on s /\ + (!x. x IN s ==> f x IN interval[a,b]) + ==> ?g. g continuous_on u /\ + (!x. x IN s ==> g x = f x) /\ + (!x. x IN u ==> g(x) IN interval[a,b])`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`\x. (f:real^N->real^1)(x) - inv(&2) % (a + b)`; + `u:real^N->bool`; `s:real^N->bool`; `(drop(b) - drop(a)) / &2`] + TIETZE) THEN + ASM_SIMP_TAC[CONTINUOUS_ON_SUB; CONTINUOUS_ON_CONST] THEN ANTS_TAC THENL + [CONJ_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN + X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `x:real^N`) THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[IN_INTERVAL_1; NORM_REAL; GSYM drop] THEN + REWRITE_TAC[DROP_ADD; DROP_CMUL; DROP_SUB] THEN REAL_ARITH_TAC; + ALL_TAC] THEN + DISCH_THEN(X_CHOOSE_THEN `g:real^N->real^1` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `\x. (g:real^N->real^1)(x) + inv(&2) % (a + b)` THEN + REPEAT CONJ_TAC THENL + [ASM_SIMP_TAC[CONTINUOUS_ON_ADD; CONTINUOUS_ON_CONST]; + REPEAT STRIP_TAC THEN ASM_SIMP_TAC[] THEN VECTOR_ARITH_TAC; + X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN UNDISCH_TAC + `!x. x IN u ==> norm((g:real^N->real^1) x) <= (drop b - drop a) / &2` THEN + DISCH_THEN(MP_TAC o SPEC `x:real^N`) THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[IN_INTERVAL_1; NORM_REAL; GSYM drop] THEN + REWRITE_TAC[DROP_ADD; DROP_CMUL; DROP_SUB] THEN REAL_ARITH_TAC]);; + +let TIETZE_OPEN_INTERVAL_1 = prove + (`!f:real^N->real^1 u s a b. + drop a < drop b /\ + closed_in (subtopology euclidean u) s /\ + f continuous_on s /\ + (!x. x IN s ==> f x IN interval(a,b)) + ==> ?g. g continuous_on u /\ + (!x. x IN s ==> g x = f x) /\ + (!x. x IN u ==> g(x) IN interval(a,b))`, + REWRITE_TAC[IN_INTERVAL_1] THEN REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`f:real^N->real^1`; `u:real^N->bool`; `s:real^N->bool`; + `a:real^1`; `b:real^1`] TIETZE_CLOSED_INTERVAL_1) THEN + ASM_REWRITE_TAC[] THEN ANTS_TAC THENL + [ASM_MESON_TAC[IN_INTERVAL_1; REAL_LT_IMP_LE]; ALL_TAC] THEN + DISCH_THEN(X_CHOOSE_THEN `g:real^N->real^1` STRIP_ASSUME_TAC) THEN + MP_TAC(ISPECL [`s:real^N->bool`; + `{x | x IN u /\ (g:real^N->real^1) x IN {a,b}}`; + `u:real^N->bool`; + `vec 1:real^1`; `vec 0:real^1`] URYSOHN_LOCAL) THEN + ASM_REWRITE_TAC[SEGMENT_1; DROP_VEC; REAL_OF_NUM_LE; ARITH] THEN + REWRITE_TAC[IN_INTERVAL_1; DROP_VEC] THEN ANTS_TAC THENL + [CONJ_TAC THENL + [MATCH_MP_TAC CONTINUOUS_CLOSED_IN_PREIMAGE THEN + ASM_SIMP_TAC[FINITE_IMP_CLOSED; FINITE_INSERT; FINITE_EMPTY] THEN + ASM_MESON_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_AT; OPEN_UNIV; IN_UNIV]; + RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1]) THEN + ASM SET_TAC[REAL_LT_REFL]]; + REWRITE_TAC[IN_ELIM_THM] THEN + DISCH_THEN(X_CHOOSE_THEN `h:real^N->real^1` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `(\x. &1 / &2 % (a + b) + + drop(h x) % (g x - &1 / &2 % (a + b))):real^N->real^1` THEN + ASM_SIMP_TAC[DROP_CMUL; DROP_VEC; VECTOR_MUL_LID] THEN + REWRITE_TAC[VECTOR_ARITH `a + x - a:real^N = x`] THEN CONJ_TAC THENL + [MATCH_MP_TAC CONTINUOUS_ON_ADD THEN REWRITE_TAC[CONTINUOUS_ON_CONST] THEN + MATCH_MP_TAC CONTINUOUS_ON_MUL THEN + ASM_SIMP_TAC[CONTINUOUS_ON_SUB; CONTINUOUS_ON_CONST; ETA_AX] THEN + ASM_REWRITE_TAC[o_DEF; LIFT_DROP; ETA_AX]; + ALL_TAC] THEN + X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN + REWRITE_TAC[DROP_ADD; DROP_CMUL; DROP_SUB] THEN + REWRITE_TAC[REAL_ARITH + `a < &1 / &2 * (a + b) + x /\ &1 / &2 * (a + b) + x < b <=> + abs(x) < &1 * (b - a) / &2`] THEN + ASM_CASES_TAC `(g:real^N->real^1) x IN {a,b}` THENL + [ASM_SIMP_TAC[DROP_VEC; REAL_MUL_LZERO] THEN ASM_REAL_ARITH_TAC; + REWRITE_TAC[REAL_ABS_MUL] THEN MATCH_MP_TAC(REAL_ARITH + `y < a /\ abs(x) * y <= &1 * y ==> abs(x) * y < a`) THEN + CONJ_TAC THENL + [REWRITE_TAC[REAL_MUL_LID] THEN MATCH_MP_TAC(REAL_ARITH + `a < x /\ x < b ==> abs(x - &1 / &2 * (a + b)) < (b - a) / &2`) THEN + RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1]) THEN + ASM_REWRITE_TAC[REAL_LT_LE; DROP_EQ] THEN ASM SET_TAC[]; + MATCH_MP_TAC REAL_LE_RMUL THEN REWRITE_TAC[REAL_ABS_POS] THEN + REPEAT(FIRST_X_ASSUM(MP_TAC o SPEC `x:real^N`)) THEN + FIRST_ASSUM(MP_TAC o MATCH_MP CLOSED_IN_IMP_SUBSET) THEN + ASM_SIMP_TAC[SUBSET] THEN REAL_ARITH_TAC]]]);; + +let TIETZE_UNBOUNDED_1 = prove + (`!f:real^N->real^1 u s. + closed_in (subtopology euclidean u) s /\ f continuous_on s + ==> ?g. g continuous_on u /\ (!x. x IN s ==> g x = f x)`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`vec 0:real^1`; `vec 1:real^1`] + HOMEOMORPHIC_OPEN_INTERVAL_UNIV) THEN + REWRITE_TAC[INTERVAL_NE_EMPTY; VEC_COMPONENT; REAL_LT_01] THEN + REWRITE_TAC[HOMEOMORPHIC_MINIMAL; LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`h:real^1->real^1`; `k:real^1->real^1`] THEN + REWRITE_TAC[IN_UNIV] THEN STRIP_TAC THEN + MP_TAC(ISPECL [`(k:real^1->real^1) o (f:real^N->real^1)`; `u:real^N->bool`; + `s:real^N->bool`; `vec 0:real^1`; `vec 1:real^1`] + TIETZE_OPEN_INTERVAL_1) THEN + REWRITE_TAC[] THEN ANTS_TAC THENL + [ASM_REWRITE_TAC[DROP_VEC; REAL_LT_01; o_THM] THEN + MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC CONTINUOUS_ON_SUBSET THEN + EXISTS_TAC `(:real^1)` THEN ASM_REWRITE_TAC[SUBSET_UNIV]; + DISCH_THEN(X_CHOOSE_THEN `g:real^N->real^1` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `(h:real^1->real^1) o (g:real^N->real^1)` THEN + ASM_SIMP_TAC[o_THM] THEN + MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC CONTINUOUS_ON_SUBSET THEN + EXISTS_TAC `interval(vec 0:real^1,vec 1)` THEN + ASM_REWRITE_TAC[SUBSET_UNIV] THEN ASM SET_TAC[]]);; + +(* ------------------------------------------------------------------------- *) +(* Now for general intervals in real^N by componentwise extension. *) +(* ------------------------------------------------------------------------- *) + +let TIETZE_CLOSED_INTERVAL = prove + (`!f:real^M->real^N u s a b. + ~(interval[a,b] = {}) /\ + closed_in (subtopology euclidean u) s /\ + f continuous_on s /\ + (!x. x IN s ==> f x IN interval[a,b]) + ==> ?g. g continuous_on u /\ + (!x. x IN s ==> g x = f x) /\ + (!x. x IN u ==> g(x) IN interval[a,b])`, + REWRITE_TAC[INTERVAL_NE_EMPTY] THEN REPEAT STRIP_TAC THEN + SUBGOAL_THEN + `!i. 1 <= i /\ i <= dimindex(:N) + ==> ?g. g continuous_on u /\ + (!x. x IN s ==> g x = lift((f:real^M->real^N)(x)$i)) /\ + (!x. x IN u ==> + g(x) IN interval[lift((a:real^N)$i),lift((b:real^N)$i)])` + MP_TAC THENL + [REPEAT STRIP_TAC THEN MATCH_MP_TAC TIETZE_CLOSED_INTERVAL_1 THEN + RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL]) THEN + ASM_SIMP_TAC[IN_INTERVAL_1; LIFT_DROP] THEN + SUBGOAL_THEN `(\x. lift((f:real^M->real^N) x$i)) = (\x. lift(x$i)) o f` + SUBST1_TAC THENL [REWRITE_TAC[o_DEF]; ALL_TAC] THEN + ASM_SIMP_TAC[CONTINUOUS_ON_LIFT_COMPONENT; CONTINUOUS_ON_COMPOSE]; + ALL_TAC] THEN + GEN_REWRITE_TAC (LAND_CONV o BINDER_CONV) [RIGHT_IMP_EXISTS_THM] THEN + REWRITE_TAC[SKOLEM_THM; IN_INTERVAL_1; LIFT_DROP] THEN + DISCH_THEN(X_CHOOSE_TAC `g:num->real^M->real^1`) THEN + EXISTS_TAC `(\x. lambda i. drop(g i x)):real^M->real^N` THEN + SIMP_TAC[CART_EQ; IN_INTERVAL; LAMBDA_BETA] THEN CONJ_TAC THENL + [ONCE_REWRITE_TAC[CONTINUOUS_ON_COMPONENTWISE_LIFT] THEN + ASM_SIMP_TAC[LAMBDA_BETA; LIFT_DROP; ETA_AX]; + ASM_SIMP_TAC[LIFT_DROP]]);; + +let TIETZE_OPEN_INTERVAL = prove + (`!f:real^M->real^N u s a b. + ~(interval(a,b) = {}) /\ + closed_in (subtopology euclidean u) s /\ + f continuous_on s /\ + (!x. x IN s ==> f x IN interval(a,b)) + ==> ?g. g continuous_on u /\ + (!x. x IN s ==> g x = f x) /\ + (!x. x IN u ==> g(x) IN interval(a,b))`, + REWRITE_TAC[INTERVAL_NE_EMPTY] THEN REPEAT STRIP_TAC THEN + SUBGOAL_THEN + `!i. 1 <= i /\ i <= dimindex(:N) + ==> ?g. g continuous_on u /\ + (!x. x IN s ==> g x = lift((f:real^M->real^N)(x)$i)) /\ + (!x. x IN u ==> + g(x) IN interval(lift((a:real^N)$i),lift((b:real^N)$i)))` + MP_TAC THENL + [REPEAT STRIP_TAC THEN MATCH_MP_TAC TIETZE_OPEN_INTERVAL_1 THEN + RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL]) THEN + ASM_SIMP_TAC[IN_INTERVAL_1; LIFT_DROP] THEN + SUBGOAL_THEN `(\x. lift((f:real^M->real^N) x$i)) = (\x. lift(x$i)) o f` + SUBST1_TAC THENL [REWRITE_TAC[o_DEF]; ALL_TAC] THEN + ASM_SIMP_TAC[CONTINUOUS_ON_LIFT_COMPONENT; CONTINUOUS_ON_COMPOSE]; + ALL_TAC] THEN + GEN_REWRITE_TAC (LAND_CONV o BINDER_CONV) [RIGHT_IMP_EXISTS_THM] THEN + REWRITE_TAC[SKOLEM_THM; IN_INTERVAL_1; LIFT_DROP] THEN + DISCH_THEN(X_CHOOSE_TAC `g:num->real^M->real^1`) THEN + EXISTS_TAC `(\x. lambda i. drop(g i x)):real^M->real^N` THEN + SIMP_TAC[CART_EQ; IN_INTERVAL; LAMBDA_BETA] THEN CONJ_TAC THENL + [ONCE_REWRITE_TAC[CONTINUOUS_ON_COMPONENTWISE_LIFT] THEN + ASM_SIMP_TAC[LAMBDA_BETA; LIFT_DROP; ETA_AX]; + ASM_SIMP_TAC[LIFT_DROP]]);; + +let TIETZE_UNBOUNDED = prove + (`!f:real^M->real^N u s. + closed_in (subtopology euclidean u) s /\ f continuous_on s + ==> ?g. g continuous_on u /\ + (!x. x IN s ==> g x = f x)`, + REWRITE_TAC[INTERVAL_NE_EMPTY] THEN REPEAT STRIP_TAC THEN + SUBGOAL_THEN + `!i. 1 <= i /\ i <= dimindex(:N) + ==> ?g. g continuous_on u /\ + (!x. x IN s ==> g x = lift((f:real^M->real^N)(x)$i))` + MP_TAC THENL + [REPEAT STRIP_TAC THEN MATCH_MP_TAC TIETZE_UNBOUNDED_1 THEN + RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL]) THEN + ASM_SIMP_TAC[IN_INTERVAL_1; LIFT_DROP] THEN + SUBGOAL_THEN `(\x. lift((f:real^M->real^N) x$i)) = (\x. lift(x$i)) o f` + SUBST1_TAC THENL [REWRITE_TAC[o_DEF]; ALL_TAC] THEN + ASM_SIMP_TAC[CONTINUOUS_ON_LIFT_COMPONENT; CONTINUOUS_ON_COMPOSE]; + ALL_TAC] THEN + GEN_REWRITE_TAC (LAND_CONV o BINDER_CONV) [RIGHT_IMP_EXISTS_THM] THEN + REWRITE_TAC[SKOLEM_THM; IN_INTERVAL_1; LIFT_DROP] THEN + DISCH_THEN(X_CHOOSE_TAC `g:num->real^M->real^1`) THEN + EXISTS_TAC `(\x. lambda i. drop(g i x)):real^M->real^N` THEN + SIMP_TAC[CART_EQ; IN_INTERVAL; LAMBDA_BETA] THEN CONJ_TAC THENL + [ONCE_REWRITE_TAC[CONTINUOUS_ON_COMPONENTWISE_LIFT] THEN + ASM_SIMP_TAC[LAMBDA_BETA; LIFT_DROP; ETA_AX]; + ASM_SIMP_TAC[LIFT_DROP]]);; + +(* ------------------------------------------------------------------------- *) +(* Countability of some relevant sets. *) +(* ------------------------------------------------------------------------- *) + +let COUNTABLE_INTEGER = prove + (`COUNTABLE integer`, + MATCH_MP_TAC COUNTABLE_SUBSET THEN EXISTS_TAC + `IMAGE (\n. (&n:real)) (:num) UNION IMAGE (\n. --(&n)) (:num)` THEN + SIMP_TAC[COUNTABLE_IMAGE; COUNTABLE_UNION; NUM_COUNTABLE] THEN + REWRITE_TAC[SUBSET; IN_UNION; IN_IMAGE; IN_UNIV] THEN + REWRITE_TAC[IN; INTEGER_CASES]);; + +let CARD_EQ_INTEGER = prove + (`integer =_c (:num)`, + REWRITE_TAC[GSYM CARD_LE_ANTISYM; GSYM COUNTABLE_ALT; COUNTABLE_INTEGER] THEN + REWRITE_TAC[le_c] THEN EXISTS_TAC `real_of_num` THEN + REWRITE_TAC[IN_UNIV; REAL_OF_NUM_EQ] THEN + REWRITE_TAC[IN; INTEGER_CLOSED]);; + +let COUNTABLE_RATIONAL = prove + (`COUNTABLE rational`, + MATCH_MP_TAC COUNTABLE_SUBSET THEN + EXISTS_TAC `IMAGE (\(x,y). x / y) (integer CROSS integer)` THEN + SIMP_TAC[COUNTABLE_IMAGE; COUNTABLE_CROSS; COUNTABLE_INTEGER] THEN + REWRITE_TAC[SUBSET; IN_IMAGE; EXISTS_PAIR_THM; IN_CROSS] THEN + REWRITE_TAC[rational; IN] THEN MESON_TAC[]);; + +let CARD_EQ_RATIONAL = prove + (`rational =_c (:num)`, + REWRITE_TAC[GSYM CARD_LE_ANTISYM; GSYM COUNTABLE_ALT; COUNTABLE_RATIONAL] THEN + REWRITE_TAC[le_c] THEN EXISTS_TAC `real_of_num` THEN + REWRITE_TAC[IN_UNIV; REAL_OF_NUM_EQ] THEN + REWRITE_TAC[IN; RATIONAL_CLOSED]);; + +let COUNTABLE_INTEGER_COORDINATES = prove + (`COUNTABLE { x:real^N | !i. 1 <= i /\ i <= dimindex(:N) ==> integer(x$i) }`, + MATCH_MP_TAC COUNTABLE_CART THEN + REWRITE_TAC[SET_RULE `{x | P x} = P`; COUNTABLE_INTEGER]);; + +let COUNTABLE_RATIONAL_COORDINATES = prove + (`COUNTABLE { x:real^N | !i. 1 <= i /\ i <= dimindex(:N) ==> rational(x$i) }`, + MATCH_MP_TAC COUNTABLE_CART THEN + REWRITE_TAC[SET_RULE `{x | P x} = P`; COUNTABLE_RATIONAL]);; + +(* ------------------------------------------------------------------------- *) +(* Density of points with rational, or just dyadic rational, coordinates. *) +(* ------------------------------------------------------------------------- *) + +let CLOSURE_DYADIC_RATIONALS = prove + (`closure { inv(&2 pow n) % x |n,x| + !i. 1 <= i /\ i <= dimindex(:N) ==> integer(x$i) } = (:real^N)`, + REWRITE_TAC[EXTENSION; CLOSURE_APPROACHABLE; IN_UNIV; EXISTS_IN_GSPEC] THEN + MAP_EVERY X_GEN_TAC [`x:real^N`; `e:real`] THEN DISCH_TAC THEN + MP_TAC(SPECL [`inv(&2)`; `e / &(dimindex(:N))`] REAL_ARCH_POW_INV) THEN + ASM_SIMP_TAC[REAL_LT_DIV; REAL_OF_NUM_LT; LE_1; DIMINDEX_GE_1; + REAL_POW_INV; REAL_LT_RDIV_EQ] THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN MATCH_MP_TAC MONO_EXISTS THEN + ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN X_GEN_TAC `n:num` THEN DISCH_TAC THEN + EXISTS_TAC `(lambda i. floor(&2 pow n * (x:real^N)$i)):real^N` THEN + ASM_SIMP_TAC[LAMBDA_BETA; FLOOR; dist; NORM_MUL] THEN + MATCH_MP_TAC(MATCH_MP (REWRITE_RULE[IMP_CONJ] REAL_LET_TRANS) + (SPEC_ALL NORM_LE_L1)) THEN + SIMP_TAC[LAMBDA_BETA; VECTOR_SUB_COMPONENT; VECTOR_MUL_COMPONENT] THEN + MATCH_MP_TAC REAL_LET_TRANS THEN + EXISTS_TAC `&(dimindex(:N)) * inv(&2 pow n)` THEN ASM_REWRITE_TAC[] THEN + GEN_REWRITE_TAC (RAND_CONV o LAND_CONV o RAND_CONV) [GSYM CARD_NUMSEG_1] THEN + MATCH_MP_TAC SUM_BOUND THEN REWRITE_TAC[FINITE_NUMSEG; IN_NUMSEG] THEN + X_GEN_TAC `k:num` THEN STRIP_TAC THEN + GEN_REWRITE_TAC RAND_CONV [GSYM REAL_MUL_RID] THEN + SIMP_TAC[REAL_ABS_MUL; REAL_POW_EQ_0; REAL_OF_NUM_EQ; ARITH; + REAL_FIELD `~(a = &0) ==> inv a * b - x = inv a * (b - a * x)`] THEN + MATCH_MP_TAC REAL_LE_MUL2 THEN REWRITE_TAC[REAL_ABS_POS] THEN + REWRITE_TAC[REAL_LE_REFL; REAL_ABS_POW; REAL_ABS_INV; REAL_ABS_NUM] THEN + MP_TAC(SPEC `&2 pow n * (x:real^N)$k` FLOOR) THEN REAL_ARITH_TAC);; + +let CLOSURE_RATIONAL_COORDINATES = prove + (`closure { x | !i. 1 <= i /\ i <= dimindex(:N) ==> rational(x$i) } = + (:real^N)`, + MATCH_MP_TAC(SET_RULE `!s. s SUBSET t /\ s = UNIV ==> t = UNIV`) THEN + EXISTS_TAC + `closure { inv(&2 pow n) % x:real^N |n,x| + !i. 1 <= i /\ i <= dimindex(:N) ==> integer(x$i) }` THEN + + CONJ_TAC THENL [ALL_TAC; REWRITE_TAC[CLOSURE_DYADIC_RATIONALS]] THEN + MATCH_MP_TAC SUBSET_CLOSURE THEN + REWRITE_TAC[SUBSET; FORALL_IN_GSPEC; IN_ELIM_THM; VECTOR_MUL_COMPONENT] THEN + ASM_SIMP_TAC[RATIONAL_CLOSED]);; + +let CLOSURE_DYADIC_RATIONALS_IN_OPEN_SET = prove + (`!s:real^N->bool. + open s + ==> closure(s INTER + { inv(&2 pow n) % x | n,x | + !i. 1 <= i /\ i <= dimindex(:N) ==> integer(x$i) }) = + closure s`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC CLOSURE_OPEN_INTER_SUPERSET THEN + ASM_REWRITE_TAC[CLOSURE_DYADIC_RATIONALS; SUBSET_UNIV]);; + +let CLOSURE_RATIONALS_IN_OPEN_SET = prove + (`!s:real^N->bool. + open s + ==> closure(s INTER + { inv(&2 pow n) % x | n,x | + !i. 1 <= i /\ i <= dimindex(:N) ==> integer(x$i) }) = + closure s`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC CLOSURE_OPEN_INTER_SUPERSET THEN + ASM_REWRITE_TAC[CLOSURE_DYADIC_RATIONALS; SUBSET_UNIV]);; + +(* ------------------------------------------------------------------------- *) +(* Various separability-type properties. *) +(* ------------------------------------------------------------------------- *) + +let UNIV_SECOND_COUNTABLE = prove + (`?b. COUNTABLE b /\ (!c. c IN b ==> open c) /\ + !s:real^N->bool. open s ==> ?u. u SUBSET b /\ s = UNIONS u`, + EXISTS_TAC + `IMAGE (\(v:real^N,q). ball(v,q)) + ({v | !i. 1 <= i /\ i <= dimindex(:N) ==> rational(v$i)} CROSS + rational)` THEN + REPEAT CONJ_TAC THENL + [MATCH_MP_TAC COUNTABLE_IMAGE THEN MATCH_MP_TAC COUNTABLE_CROSS THEN + REWRITE_TAC[COUNTABLE_RATIONAL] THEN MATCH_MP_TAC COUNTABLE_CART THEN + REWRITE_TAC[COUNTABLE_RATIONAL; SET_RULE `{x | P x} = P`]; + REWRITE_TAC[FORALL_IN_IMAGE; CROSS; FORALL_IN_GSPEC; OPEN_BALL]; + REPEAT STRIP_TAC THEN + ASM_CASES_TAC `s:real^N->bool = {}` THENL + [EXISTS_TAC `{}:(real^N->bool)->bool` THEN + ASM_REWRITE_TAC[UNIONS_0; EMPTY_SUBSET]; + ALL_TAC] THEN + EXISTS_TAC `{c | c IN IMAGE (\(v:real^N,q). ball(v,q)) + ({v | !i. 1 <= i /\ i <= dimindex(:N) ==> rational(v$i)} CROSS + rational) /\ c SUBSET s}` THEN + CONJ_TAC THENL [SET_TAC[]; ALL_TAC] THEN + MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL [ALL_TAC; SET_TAC[]] THEN + REWRITE_TAC[SUBSET; IN_UNIONS; IN_ELIM_THM] THEN + REWRITE_TAC[GSYM CONJ_ASSOC; EXISTS_IN_IMAGE] THEN + REWRITE_TAC[CROSS; EXISTS_PAIR_THM; EXISTS_IN_GSPEC] THEN + REWRITE_TAC[IN_ELIM_PAIR_THM] THEN X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [OPEN_CONTAINS_BALL]) THEN + DISCH_THEN(MP_TAC o SPEC `x:real^N`) THEN + ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM; SUBSET; IN_BALL] THEN + X_GEN_TAC `e:real` THEN STRIP_TAC THEN REWRITE_TAC[IN_ELIM_THM] THEN + MP_TAC(REWRITE_RULE[EXTENSION; IN_UNIV] CLOSURE_RATIONAL_COORDINATES) THEN + REWRITE_TAC[CLOSURE_APPROACHABLE] THEN + DISCH_THEN(MP_TAC o SPECL [`x:real^N`; `e / &4`]) THEN + ANTS_TAC THENL [ASM_REAL_ARITH_TAC; REWRITE_TAC[IN_ELIM_THM]] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `y:real^N` THEN STRIP_TAC THEN + SUBGOAL_THEN `?x. rational x /\ e / &3 < x /\ x < e / &2` + (X_CHOOSE_THEN `q:real` STRIP_ASSUME_TAC) + THENL + [MP_TAC(ISPECL [`&5 / &12 * e`; `e / &12`] RATIONAL_APPROXIMATION) THEN + ANTS_TAC THENL [ASM_REAL_ARITH_TAC; MATCH_MP_TAC MONO_EXISTS] THEN + SIMP_TAC[] THEN REAL_ARITH_TAC; + EXISTS_TAC `q:real` THEN ASM_REWRITE_TAC[] THEN REPEAT CONJ_TAC THENL + [ASM_REWRITE_TAC[IN]; + REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + REPEAT(POP_ASSUM MP_TAC) THEN NORM_ARITH_TAC; + ASM_REAL_ARITH_TAC]]]);; + +let UNIV_SECOND_COUNTABLE_SEQUENCE = prove + (`?b:num->real^N->bool. + (!m n. b m = b n <=> m = n) /\ + (!n. open(b n)) /\ + (!s. open s ==> ?k. s = UNIONS {b n | n IN k})`, + X_CHOOSE_THEN `bb:(real^N->bool)->bool` STRIP_ASSUME_TAC + UNIV_SECOND_COUNTABLE THEN + MP_TAC(ISPEC `bb:(real^N->bool)->bool` COUNTABLE_AS_INJECTIVE_IMAGE) THEN + ANTS_TAC THENL + [ASM_REWRITE_TAC[INFINITE] THEN DISCH_TAC THEN + SUBGOAL_THEN + `INFINITE {ball(vec 0:real^N,inv(&n + &1)) | n IN (:num)}` + MP_TAC THENL + [REWRITE_TAC[SIMPLE_IMAGE] THEN MATCH_MP_TAC(REWRITE_RULE + [RIGHT_IMP_FORALL_THM; IMP_IMP] INFINITE_IMAGE_INJ) THEN + REWRITE_TAC[num_INFINITE] THEN MATCH_MP_TAC WLOG_LT THEN SIMP_TAC[] THEN + CONJ_TAC THENL [MESON_TAC[]; ALL_TAC] THEN + MAP_EVERY X_GEN_TAC [`m:num`; `n:num`] THEN DISCH_TAC THEN + REWRITE_TAC[EXTENSION] THEN + DISCH_THEN(MP_TAC o SPEC `inv(&n + &1) % basis 1:real^N`) THEN + REWRITE_TAC[IN_BALL; DIST_0; NORM_MUL; REAL_ABS_INV] THEN + SIMP_TAC[NORM_BASIS; DIMINDEX_GE_1; LE_REFL; REAL_MUL_RID] THEN + ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN DISCH_TAC THEN + REWRITE_TAC[REAL_ARITH `abs(&n + &1) = &n + &1`; REAL_LT_REFL] THEN + MATCH_MP_TAC REAL_LT_INV2 THEN + REWRITE_TAC[REAL_OF_NUM_LT; REAL_OF_NUM_ADD] THEN ASM_ARITH_TAC; + REWRITE_TAC[INFINITE; SIMPLE_IMAGE] THEN + MATCH_MP_TAC FINITE_SUBSET THEN + EXISTS_TAC `IMAGE UNIONS {u | u SUBSET bb} :(real^N->bool)->bool` THEN + ASM_SIMP_TAC[FINITE_IMAGE; FINITE_POWERSET] THEN + GEN_REWRITE_TAC I [SUBSET] THEN SIMP_TAC[FORALL_IN_IMAGE; IN_UNIV] THEN + X_GEN_TAC `n:num` THEN REWRITE_TAC[IN_IMAGE; IN_ELIM_THM] THEN + ASM_MESON_TAC[OPEN_BALL]]; + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `b:num->real^N->bool` THEN + DISCH_THEN(CONJUNCTS_THEN2 SUBST_ALL_TAC ASSUME_TAC) THEN + RULE_ASSUM_TAC(REWRITE_RULE[FORALL_IN_IMAGE; IN_UNIV]) THEN + REPEAT(CONJ_TAC THENL [ASM_MESON_TAC[]; ALL_TAC]) THEN + X_GEN_TAC `s:real^N->bool` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `s:real^N->bool`) THEN + ASM_REWRITE_TAC[SUBSET_IMAGE; LEFT_AND_EXISTS_THM; SUBSET_UNIV] THEN + ONCE_REWRITE_TAC[SWAP_EXISTS_THM] THEN MATCH_MP_TAC MONO_EXISTS THEN + REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[SIMPLE_IMAGE]]);; + +let SUBSET_SECOND_COUNTABLE = prove + (`!s:real^N->bool. + ?b. COUNTABLE b /\ + (!c. c IN b ==> ~(c = {}) /\ open_in(subtopology euclidean s) c) /\ + !t. open_in(subtopology euclidean s) t + ==> ?u. u SUBSET b /\ t = UNIONS u`, + GEN_TAC THEN + SUBGOAL_THEN + `?b. COUNTABLE b /\ + (!c:real^N->bool. c IN b ==> open_in(subtopology euclidean s) c) /\ + !t. open_in(subtopology euclidean s) t + ==> ?u. u SUBSET b /\ t = UNIONS u` + STRIP_ASSUME_TAC THENL + [X_CHOOSE_THEN `B:(real^N->bool)->bool` STRIP_ASSUME_TAC + UNIV_SECOND_COUNTABLE THEN + EXISTS_TAC `{s INTER c :real^N->bool | c IN B}` THEN + ASM_SIMP_TAC[SIMPLE_IMAGE; COUNTABLE_IMAGE] THEN + ASM_SIMP_TAC[FORALL_IN_IMAGE; EXISTS_SUBSET_IMAGE; OPEN_IN_OPEN_INTER] THEN + REWRITE_TAC[OPEN_IN_OPEN] THEN + X_GEN_TAC `t:real^N->bool` THEN + DISCH_THEN(X_CHOOSE_THEN `u:real^N->bool` STRIP_ASSUME_TAC) THEN + FIRST_X_ASSUM SUBST_ALL_TAC THEN + SUBGOAL_THEN `?b. b SUBSET B /\ u:real^N->bool = UNIONS b` + STRIP_ASSUME_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN + FIRST_X_ASSUM SUBST_ALL_TAC THEN + EXISTS_TAC `b:(real^N->bool)->bool` THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[INTER_UNIONS] THEN AP_TERM_TAC THEN SET_TAC[]; + EXISTS_TAC `b DELETE ({}:real^N->bool)` THEN + ASM_SIMP_TAC[COUNTABLE_DELETE; IN_DELETE; SUBSET_DELETE] THEN + X_GEN_TAC `t:real^N->bool` THEN DISCH_THEN(ANTE_RES_THEN MP_TAC) THEN + DISCH_THEN(X_CHOOSE_THEN `u:(real^N->bool)->bool` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `u DELETE ({}:real^N->bool)` THEN + REPEAT(CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC]) THEN + FIRST_X_ASSUM SUBST_ALL_TAC THEN + REWRITE_TAC[EXTENSION; IN_UNIONS] THEN + GEN_TAC THEN AP_TERM_TAC THEN ABS_TAC THEN + REWRITE_TAC[IN_DELETE] THEN SET_TAC[]]);; + +let SEPARABLE = prove + (`!s:real^N->bool. + ?t. COUNTABLE t /\ t SUBSET s /\ s SUBSET closure t`, + MP_TAC SUBSET_SECOND_COUNTABLE THEN + MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `s:real^N->bool` THEN + REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; LEFT_AND_EXISTS_THM] THEN + DISCH_THEN(X_CHOOSE_THEN `B:(real^N->bool)->bool` + (CONJUNCTS_THEN2 ASSUME_TAC (CONJUNCTS_THEN2 MP_TAC ASSUME_TAC))) THEN + GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [RIGHT_IMP_EXISTS_THM] THEN + REWRITE_TAC[SKOLEM_THM; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `f:(real^N->bool)->real^N` THEN DISCH_TAC THEN + EXISTS_TAC `IMAGE (f:(real^N->bool)->real^N) B` THEN + ASM_SIMP_TAC[COUNTABLE_IMAGE] THEN CONJ_TAC THENL + [REWRITE_TAC[SUBSET; FORALL_IN_IMAGE] THEN + X_GEN_TAC `c:real^N->bool` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `c:real^N->bool`) THEN + ASM_REWRITE_TAC[] THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o MATCH_MP OPEN_IN_SUBSET) THEN + REWRITE_TAC[TOPSPACE_SUBTOPOLOGY; TOPSPACE_EUCLIDEAN] THEN ASM SET_TAC[]; + REWRITE_TAC[SUBSET; CLOSURE_APPROACHABLE; EXISTS_IN_IMAGE] THEN + X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN + X_GEN_TAC `e:real` THEN DISCH_TAC THEN + UNDISCH_THEN + `!t:real^N->bool. + open_in (subtopology euclidean s) t + ==> (?u. u SUBSET B /\ t = UNIONS u)` + (MP_TAC o SPEC `s INTER ball(x:real^N,e)`) THEN + SIMP_TAC[OPEN_IN_OPEN_INTER; OPEN_BALL; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `b:(real^N->bool)->bool` THEN + ASM_CASES_TAC `b:(real^N->bool)->bool = {}` THENL + [MATCH_MP_TAC(TAUT `~b ==> a /\ b ==> c`) THEN + ASM_REWRITE_TAC[EXTENSION; IN_INTER; NOT_IN_EMPTY; UNIONS_0] THEN + ASM_MESON_TAC[CENTRE_IN_BALL]; + STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `c:real^N->bool` THEN + DISCH_TAC THEN CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [EXTENSION]) THEN + DISCH_THEN(MP_TAC o SPEC `(f:(real^N->bool)->real^N) c`) THEN + ONCE_REWRITE_TAC[DIST_SYM] THEN REWRITE_TAC[IN_INTER; IN_BALL] THEN + MATCH_MP_TAC(TAUT `a /\ c ==> (a /\ b <=> c) ==> b`) THEN + CONJ_TAC THENL [ALL_TAC; ASM SET_TAC[]] THEN + FIRST_X_ASSUM(MP_TAC o SPEC `c:real^N->bool`) THEN + ANTS_TAC THENL [ASM SET_TAC[]; STRIP_TAC] THEN + FIRST_X_ASSUM(MP_TAC o MATCH_MP OPEN_IN_SUBSET) THEN + REWRITE_TAC[TOPSPACE_SUBTOPOLOGY; TOPSPACE_EUCLIDEAN] THEN + ASM SET_TAC[]]]);; + +let OPEN_SET_RATIONAL_COORDINATES = prove + (`!s. open s /\ ~(s = {}) + ==> ?x:real^N. x IN s /\ + !i. 1 <= i /\ i <= dimindex(:N) ==> rational(x$i)`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN + `~(closure { x | !i. 1 <= i /\ i <= dimindex(:N) ==> rational(x$i) } INTER + (s:real^N->bool) = {})` + MP_TAC THENL + [ASM_REWRITE_TAC[CLOSURE_RATIONAL_COORDINATES; INTER_UNIV]; ALL_TAC] THEN + REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; CLOSURE_APPROACHABLE; IN_INTER; + IN_ELIM_THM] THEN + DISCH_THEN(X_CHOOSE_THEN `a:real^N` STRIP_ASSUME_TAC) THEN + FIRST_X_ASSUM(MP_TAC o SPEC `a:real^N` o REWRITE_RULE[open_def]) THEN + ASM_REWRITE_TAC[] THEN ASM_MESON_TAC[]);; + +let OPEN_COUNTABLE_UNION_OPEN_INTERVALS, + OPEN_COUNTABLE_UNION_CLOSED_INTERVALS = (CONJ_PAIR o prove) + (`(!s:real^N->bool. + open s + ==> ?D. COUNTABLE D /\ + (!i. i IN D ==> i SUBSET s /\ ?a b. i = interval(a,b)) /\ + UNIONS D = s) /\ + (!s:real^N->bool. + open s + ==> ?D. COUNTABLE D /\ + (!i. i IN D ==> i SUBSET s /\ ?a b. i = interval[a,b]) /\ + UNIONS D = s)`, + REPEAT STRIP_TAC THENL + [EXISTS_TAC + `{i | i IN IMAGE (\(a:real^N,b). interval(a,b)) + ({x | !i. 1 <= i /\ i <= dimindex(:N) ==> rational(x$i)} CROSS + {x | !i. 1 <= i /\ i <= dimindex(:N) ==> rational(x$i)}) /\ + i SUBSET s}`; + EXISTS_TAC + `{i | i IN IMAGE (\(a:real^N,b). interval[a,b]) + ({x | !i. 1 <= i /\ i <= dimindex(:N) ==> rational(x$i)} CROSS + {x | !i. 1 <= i /\ i <= dimindex(:N) ==> rational(x$i)}) /\ + i SUBSET s}`] THEN + (SIMP_TAC[COUNTABLE_RESTRICT; COUNTABLE_IMAGE; COUNTABLE_CROSS; + COUNTABLE_RATIONAL_COORDINATES] THEN + REWRITE_TAC[IN_ELIM_THM; UNIONS_GSPEC; IMP_CONJ; GSYM CONJ_ASSOC] THEN + REWRITE_TAC[FORALL_IN_IMAGE; EXISTS_IN_IMAGE] THEN + REWRITE_TAC[FORALL_PAIR_THM; EXISTS_PAIR_THM; IN_CROSS; IN_ELIM_THM] THEN + CONJ_TAC THENL [MESON_TAC[]; ALL_TAC] THEN + REWRITE_TAC[EXTENSION; IN_ELIM_THM] THEN + X_GEN_TAC `x:real^N` THEN EQ_TAC THENL [SET_TAC[]; DISCH_TAC] THEN + FIRST_X_ASSUM(MP_TAC o SPEC `x:real^N` o REWRITE_RULE[open_def]) THEN + ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `e:real` STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN + `!i. 1 <= i /\ i <= dimindex(:N) + ==> ?a b. rational a /\ rational b /\ + a < (x:real^N)$i /\ (x:real^N)$i < b /\ + abs(b - a) < e / &(dimindex(:N))` + MP_TAC THENL + [REPEAT STRIP_TAC THEN MATCH_MP_TAC RATIONAL_APPROXIMATION_STRADDLE THEN + ASM_SIMP_TAC[REAL_LT_DIV; REAL_OF_NUM_LT; LE_1; DIMINDEX_GE_1]; + REWRITE_TAC[LAMBDA_SKOLEM]] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `a:real^N` THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `b:real^N` THEN + DISCH_TAC THEN ASM_SIMP_TAC[SUBSET; IN_INTERVAL; REAL_LT_IMP_LE] THEN + X_GEN_TAC `y:real^N` THEN DISCH_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + REWRITE_TAC[dist] THEN MP_TAC(ISPEC `y - x:real^N` NORM_LE_L1) THEN + MATCH_MP_TAC(REAL_ARITH `s < e ==> n <= s ==> n < e`) THEN + MATCH_MP_TAC SUM_BOUND_LT_GEN THEN + REWRITE_TAC[FINITE_NUMSEG; NUMSEG_EMPTY; NOT_LT; CARD_NUMSEG_1] THEN + REWRITE_TAC[DIMINDEX_GE_1; IN_NUMSEG; VECTOR_SUB_COMPONENT] THEN + X_GEN_TAC `k:num` THEN STRIP_TAC THEN + REPEAT(FIRST_X_ASSUM(MP_TAC o SPEC `k:num`)) THEN ASM_REWRITE_TAC[] THEN + ASM_REAL_ARITH_TAC));; + +let LINDELOF = prove + (`!f:(real^N->bool)->bool. + (!s. s IN f ==> open s) + ==> ?f'. f' SUBSET f /\ COUNTABLE f' /\ UNIONS f' = UNIONS f`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN + `?b. COUNTABLE b /\ + (!c:real^N->bool. c IN b ==> open c) /\ + (!s. open s ==> ?u. u SUBSET b /\ s = UNIONS u)` + STRIP_ASSUME_TAC THENL [ASM_REWRITE_TAC[UNIV_SECOND_COUNTABLE]; ALL_TAC] THEN + ABBREV_TAC + `d = {s:real^N->bool | s IN b /\ ?u. u IN f /\ s SUBSET u}` THEN + SUBGOAL_THEN + `COUNTABLE d /\ UNIONS f :real^N->bool = UNIONS d` + STRIP_ASSUME_TAC THENL + [EXPAND_TAC "d" THEN ASM_SIMP_TAC[COUNTABLE_RESTRICT] THEN ASM SET_TAC[]; + ALL_TAC] THEN + SUBGOAL_THEN + `!s:real^N->bool. ?u. s IN d ==> u IN f /\ s SUBSET u` + MP_TAC THENL [EXPAND_TAC "d" THEN SET_TAC[]; ALL_TAC] THEN + REWRITE_TAC[SKOLEM_THM; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `g:(real^N->bool)->(real^N->bool)` THEN STRIP_TAC THEN + EXISTS_TAC `IMAGE (g:(real^N->bool)->(real^N->bool)) d` THEN + ASM_SIMP_TAC[COUNTABLE_IMAGE; UNIONS_IMAGE] THEN + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE] THEN ASM SET_TAC[]);; + +let LINDELOF_OPEN_IN = prove + (`!f u:real^N->bool. + (!s. s IN f ==> open_in (subtopology euclidean u) s) + ==> ?f'. f' SUBSET f /\ COUNTABLE f' /\ UNIONS f' = UNIONS f`, + REPEAT GEN_TAC THEN REWRITE_TAC[OPEN_IN_OPEN] THEN + GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [RIGHT_IMP_EXISTS_THM] THEN + REWRITE_TAC[SKOLEM_THM; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `v:(real^N->bool)->real^N->bool` THEN DISCH_TAC THEN + MP_TAC(ISPEC `IMAGE (v:(real^N->bool)->real^N->bool) f` LINDELOF) THEN + ASM_SIMP_TAC[FORALL_IN_IMAGE] THEN + ONCE_REWRITE_TAC[TAUT `p /\ q /\ r <=> q /\ p /\ r`] THEN + REWRITE_TAC[EXISTS_COUNTABLE_SUBSET_IMAGE] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `f':(real^N->bool)->bool` THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + SUBGOAL_THEN + `!f'. f' SUBSET f ==> UNIONS f' = (u:real^N->bool) INTER UNIONS (IMAGE v f')` + MP_TAC THENL [ASM SET_TAC[]; ASM_SIMP_TAC[SUBSET_REFL]]);; + +let COUNTABLE_DISJOINT_OPEN_SUBSETS = prove + (`!f. (!s:real^N->bool. s IN f ==> open s) /\ pairwise DISJOINT f + ==> COUNTABLE f`, + REPEAT STRIP_TAC THEN FIRST_ASSUM(MP_TAC o MATCH_MP LINDELOF) THEN + DISCH_THEN(X_CHOOSE_THEN `g:(real^N->bool)->bool` STRIP_ASSUME_TAC) THEN + MATCH_MP_TAC COUNTABLE_SUBSET THEN + EXISTS_TAC `({}:real^N->bool) INSERT g` THEN + ASM_REWRITE_TAC[COUNTABLE_INSERT] THEN + REWRITE_TAC[SUBSET; IN_INSERT] THEN + REPEAT(POP_ASSUM MP_TAC) THEN + REWRITE_TAC[EXTENSION; SUBSET] THEN + REWRITE_TAC[IN_UNIONS; pairwise] THEN + REWRITE_TAC[SET_RULE `DISJOINT s t <=> !x. ~(x IN s /\ x IN t)`] THEN + REWRITE_TAC[NOT_IN_EMPTY] THEN MESON_TAC[]);; + +let CARD_EQ_OPEN_SETS = prove + (`{s:real^N->bool | open s} =_c (:real)`, + REWRITE_TAC[GSYM CARD_LE_ANTISYM] THEN CONJ_TAC THENL + [X_CHOOSE_THEN `b:(real^N->bool)->bool` STRIP_ASSUME_TAC + UNIV_SECOND_COUNTABLE THEN + TRANS_TAC CARD_LE_TRANS `{s:(real^N->bool)->bool | s SUBSET b}` THEN + CONJ_TAC THENL + [REWRITE_TAC[LE_C] THEN + EXISTS_TAC `UNIONS:((real^N->bool)->bool)->real^N->bool` THEN + REWRITE_TAC[IN_ELIM_THM] THEN ASM_MESON_TAC[]; + TRANS_TAC CARD_LE_TRANS `{s | s SUBSET (:num)}` THEN CONJ_TAC THENL + [MATCH_MP_TAC CARD_LE_POWERSET THEN ASM_REWRITE_TAC[GSYM COUNTABLE_ALT]; + REWRITE_TAC[SUBSET_UNIV; UNIV_GSPEC] THEN + MESON_TAC[CARD_EQ_IMP_LE; CARD_EQ_SYM; CARD_EQ_REAL]]]; + REWRITE_TAC[le_c; IN_UNIV; IN_ELIM_THM] THEN + EXISTS_TAC `\x. ball(x % basis 1:real^N,&1)` THEN + REWRITE_TAC[OPEN_BALL; GSYM SUBSET_ANTISYM_EQ; SUBSET_BALLS] THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN + REWRITE_TAC[NORM_ARITH `dist(p:real^N,q) + &1 <= &1 <=> p = q`] THEN + REWRITE_TAC[VECTOR_MUL_RCANCEL; EQ_SYM_EQ] THEN + SIMP_TAC[BASIS_NONZERO; DIMINDEX_GE_1; ARITH]]);; + +let CARD_EQ_CLOSED_SETS = prove + (`{s:real^N->bool | closed s} =_c (:real)`, + SUBGOAL_THEN + `{s:real^N->bool | closed s} = + IMAGE (\s. (:real^N) DIFF s) {s | open s}` + SUBST1_TAC THENL + [CONV_TAC SYM_CONV THEN MATCH_MP_TAC SURJECTIVE_IMAGE_EQ THEN + REWRITE_TAC[IN_ELIM_THM; GSYM OPEN_CLOSED] THEN + MESON_TAC[SET_RULE `UNIV DIFF (UNIV DIFF s) = s`]; + TRANS_TAC CARD_EQ_TRANS `{s:real^N->bool | open s}` THEN + REWRITE_TAC[CARD_EQ_OPEN_SETS] THEN + MATCH_MP_TAC CARD_EQ_IMAGE THEN SET_TAC[]]);; + +let CARD_EQ_COMPACT_SETS = prove + (`{s:real^N->bool | compact s} =_c (:real)`, + REWRITE_TAC[GSYM CARD_LE_ANTISYM] THEN CONJ_TAC THENL + [TRANS_TAC CARD_LE_TRANS `{s:real^N->bool | closed s}` THEN + SIMP_TAC[CARD_EQ_IMP_LE; CARD_EQ_CLOSED_SETS] THEN + MATCH_MP_TAC CARD_LE_SUBSET THEN + SIMP_TAC[SUBSET; IN_ELIM_THM; COMPACT_IMP_CLOSED]; + REWRITE_TAC[le_c; IN_UNIV; IN_ELIM_THM] THEN + EXISTS_TAC `\x. {x % basis 1:real^N}` THEN + REWRITE_TAC[COMPACT_SING; SET_RULE `{x} = {y} <=> x = y`] THEN + SIMP_TAC[VECTOR_MUL_RCANCEL; BASIS_NONZERO; DIMINDEX_GE_1; ARITH]]);; + +let COUNTABLE_NON_CONDENSATION_POINTS = prove + (`!s:real^N->bool. COUNTABLE(s DIFF {x | x condensation_point_of s})`, + REPEAT STRIP_TAC THEN REWRITE_TAC[condensation_point_of] THEN + MATCH_MP_TAC COUNTABLE_SUBSET THEN + X_CHOOSE_THEN `b:(real^N->bool)->bool` STRIP_ASSUME_TAC + UNIV_SECOND_COUNTABLE THEN + EXISTS_TAC + `s INTER UNIONS { u:real^N->bool | u IN b /\ COUNTABLE(s INTER u)}` THEN + REWRITE_TAC[INTER_UNIONS; IN_ELIM_THM] THEN CONJ_TAC THENL + [MATCH_MP_TAC COUNTABLE_UNIONS THEN SIMP_TAC[FORALL_IN_GSPEC] THEN + ONCE_REWRITE_TAC[SIMPLE_IMAGE_GEN] THEN + ASM_SIMP_TAC[COUNTABLE_IMAGE; COUNTABLE_RESTRICT]; + SIMP_TAC[SUBSET; UNIONS_GSPEC; IN_ELIM_THM; IN_INTER; IN_DIFF] THEN + X_GEN_TAC `x:real^N` THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + REWRITE_TAC[NOT_FORALL_THM; NOT_IMP; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `t:real^N->bool` THEN STRIP_TAC THEN + SUBGOAL_THEN `?u:real^N->bool. x IN u /\ u IN b /\ u SUBSET t` MP_TAC THENL + [ASM SET_TAC[]; MATCH_MP_TAC MONO_EXISTS] THEN + REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC COUNTABLE_SUBSET THEN + EXISTS_TAC `s INTER t:real^N->bool` THEN ASM SET_TAC[]]);; + +let CARD_EQ_CONDENSATION_POINTS_IN_SET = prove + (`!s:real^N->bool. + ~(COUNTABLE s) ==> {x | x IN s /\ x condensation_point_of s} =_c s`, + REPEAT STRIP_TAC THEN + TRANS_TAC CARD_EQ_TRANS + `(s DIFF {x | x condensation_point_of s}) +_c + {x:real^N | x IN s /\ x condensation_point_of s}` THEN + CONJ_TAC THENL + [ONCE_REWRITE_TAC[CARD_EQ_SYM] THEN MATCH_MP_TAC CARD_ADD_ABSORB THEN + MATCH_MP_TAC(TAUT `p /\ (p ==> q) ==> p /\ q`) THEN CONJ_TAC THENL + [POP_ASSUM MP_TAC THEN REWRITE_TAC[INFINITE; CONTRAPOS_THM] THEN + DISCH_THEN(MP_TAC o CONJ (SPEC `s:real^N->bool` + COUNTABLE_NON_CONDENSATION_POINTS) o MATCH_MP FINITE_IMP_COUNTABLE) THEN + REWRITE_TAC[GSYM COUNTABLE_UNION] THEN MATCH_MP_TAC EQ_IMP THEN + AP_TERM_TAC THEN SET_TAC[]; + REWRITE_TAC[INFINITE_CARD_LE] THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] CARD_LE_TRANS) THEN + REWRITE_TAC[GSYM COUNTABLE_ALT; COUNTABLE_NON_CONDENSATION_POINTS]]; + ONCE_REWRITE_TAC[CARD_EQ_SYM] THEN + W(MP_TAC o PART_MATCH (rand o rand) CARD_DISJOINT_UNION o rand o snd) THEN + ANTS_TAC THENL [SET_TAC[]; ALL_TAC] THEN + MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_TERM_TAC THEN SET_TAC[]]);; + +(* ------------------------------------------------------------------------- *) +(* A discrete set is countable, and an uncountable set has a limit point. *) +(* ------------------------------------------------------------------------- *) + +let DISCRETE_IMP_COUNTABLE = prove + (`!s:real^N->bool. + (!x. x IN s ==> ?e. &0 < e /\ + !y. y IN s /\ ~(y = x) ==> e <= norm(y - x)) + ==> COUNTABLE s`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN + `!x. x IN s + ==> ?q. (!i. 1 <= i /\ i <= dimindex(:N) ==> rational(q$i)) /\ + !y:real^N. y IN s /\ ~(y = x) ==> norm(x - q) < norm(y - q)` + MP_TAC THENL + [X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `x:real^N`) THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `e:real` STRIP_ASSUME_TAC) THEN + MP_TAC(SET_RULE `x IN (:real^N)`) THEN + REWRITE_TAC[GSYM CLOSURE_RATIONAL_COORDINATES] THEN + REWRITE_TAC[CLOSURE_APPROACHABLE; IN_ELIM_THM] 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 `q:real^N` THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + X_GEN_TAC `y:real^N` THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `y:real^N`) THEN ASM_REWRITE_TAC[] THEN + REPEAT(POP_ASSUM MP_TAC) THEN NORM_ARITH_TAC; + POP_ASSUM(K ALL_TAC) THEN + REWRITE_TAC[RIGHT_IMP_EXISTS_THM; SKOLEM_THM; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `q:real^N->real^N` THEN DISCH_TAC THEN + MP_TAC(ISPECL + [`s:real^N->bool`; + `{ x:real^N | !i. 1 <= i /\ i <= dimindex(:N) ==> rational(x$i) }`; + `(:num)`] CARD_LE_TRANS) THEN + REWRITE_TAC[COUNTABLE; ge_c] THEN DISCH_THEN MATCH_MP_TAC THEN + SIMP_TAC[REWRITE_RULE[COUNTABLE; ge_c] COUNTABLE_RATIONAL_COORDINATES] THEN + REWRITE_TAC[le_c] THEN EXISTS_TAC `q:real^N->real^N` THEN + ASM_SIMP_TAC[IN_ELIM_THM] THEN ASM_MESON_TAC[REAL_LT_ANTISYM]]);; + +let UNCOUNTABLE_CONTAINS_LIMIT_POINT = prove + (`!s. ~(COUNTABLE s) ==> ?x. x IN s /\ x limit_point_of s`, + GEN_TAC THEN DISCH_THEN(MP_TAC o MATCH_MP + (ONCE_REWRITE_RULE[GSYM CONTRAPOS_THM] DISCRETE_IMP_COUNTABLE)) THEN + REWRITE_TAC[LIMPT_APPROACHABLE; GSYM REAL_NOT_LT; dist] THEN + MESON_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* The Brouwer reduction theorem. *) +(* ------------------------------------------------------------------------- *) + +let BROUWER_REDUCTION_THEOREM_GEN = prove + (`!P s:real^N->bool. + (!f. (!n. closed(f n) /\ P(f n)) /\ (!n. f(SUC n) SUBSET f(n)) + ==> P(INTERS {f n | n IN (:num)})) /\ + closed s /\ P s + ==> ?t. t SUBSET s /\ closed t /\ P t /\ + (!u. u SUBSET s /\ closed u /\ P u ==> ~(u PSUBSET t))`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN + `?b:num->real^N->bool. + (!m n. b m = b n <=> m = n) /\ + (!n. open (b n)) /\ + (!s. open s ==> (?k. s = UNIONS {b n | n IN k}))` + STRIP_ASSUME_TAC THENL + [REWRITE_TAC[UNIV_SECOND_COUNTABLE_SEQUENCE]; ALL_TAC] THEN + X_CHOOSE_THEN `a:num->real^N->bool` MP_TAC + (prove_recursive_functions_exist num_RECURSION + `a 0 = (s:real^N->bool) /\ + (!n. a(SUC n) = + if ?u. u SUBSET a(n) /\ closed u /\ P u /\ u INTER (b n) = {} + then @u. u SUBSET a(n) /\ closed u /\ P u /\ u INTER (b n) = {} + else a(n))`) THEN + DISCH_THEN(CONJUNCTS_THEN2 (LABEL_TAC "base") (LABEL_TAC "step")) THEN + EXISTS_TAC `INTERS {a n :real^N->bool | n IN (:num)}` THEN + SUBGOAL_THEN `!n. (a:num->real^N->bool)(SUC n) SUBSET a(n)` ASSUME_TAC THENL + [GEN_TAC THEN ASM_REWRITE_TAC[] THEN + COND_CASES_TAC THEN REWRITE_TAC[SUBSET_REFL] THEN + FIRST_X_ASSUM(MP_TAC o SELECT_RULE) THEN MESON_TAC[]; + ALL_TAC] THEN + SUBGOAL_THEN `!n. (a:num->real^N->bool) n SUBSET s` ASSUME_TAC THENL + [INDUCT_TAC THEN ASM_MESON_TAC[SUBSET_REFL; SUBSET_TRANS]; ALL_TAC] THEN + SUBGOAL_THEN `!n. closed((a:num->real^N->bool) n) /\ P(a n)` ASSUME_TAC THENL + [INDUCT_TAC THEN ASM_REWRITE_TAC[] THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN + FIRST_X_ASSUM(MP_TAC o SELECT_RULE) THEN MESON_TAC[]; + ALL_TAC] THEN + REPEAT CONJ_TAC THENL + [ASM SET_TAC[]; + MATCH_MP_TAC CLOSED_INTERS THEN + ASM_REWRITE_TAC[FORALL_IN_GSPEC; IN_UNIV] THEN SET_TAC[]; + FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[]; + X_GEN_TAC `t:real^N->bool` THEN STRIP_TAC THEN + REWRITE_TAC[PSUBSET_ALT] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + REWRITE_TAC[INTERS_GSPEC; EXISTS_IN_GSPEC; IN_UNIV] THEN + DISCH_THEN(X_CHOOSE_THEN `x:real^N` STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN + `?n. x IN (b:num->real^N->bool)(n) /\ t INTER b n = {}` + STRIP_ASSUME_TAC THENL + [MP_TAC(ISPEC `(:real^N) DIFF t` OPEN_CONTAINS_BALL) THEN + ASM_REWRITE_TAC[GSYM closed] THEN + DISCH_THEN(MP_TAC o SPEC `x:real^N`) THEN + ASM_REWRITE_TAC[IN_DIFF; IN_UNIV; LEFT_IMP_EXISTS_THM] THEN + REWRITE_TAC[SET_RULE `s SUBSET UNIV DIFF t <=> t INTER s = {}`] THEN + X_GEN_TAC `e:real` THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + MP_TAC(ISPECL [`x:real^N`; `e:real`] CENTRE_IN_BALL) THEN + FIRST_X_ASSUM(MP_TAC o SPEC `ball(x:real^N,e)`) THEN + ASM_REWRITE_TAC[OPEN_BALL; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `k:num->bool` THEN DISCH_THEN SUBST1_TAC THEN + REWRITE_TAC[IN_UNIONS; INTER_UNIONS; EMPTY_UNIONS; FORALL_IN_GSPEC] THEN + SET_TAC[]; + REMOVE_THEN "step" (MP_TAC o SPEC `n:num`) THEN + COND_CASES_TAC THENL + [DISCH_THEN(ASSUME_TAC o SYM) THEN + FIRST_X_ASSUM(MP_TAC o SELECT_RULE) THEN ASM_REWRITE_TAC[] THEN + ASM SET_TAC[]; + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [NOT_EXISTS_THM]) THEN + DISCH_THEN(MP_TAC o SPEC `t:real^N->bool`) THEN ASM_REWRITE_TAC[] THEN + ASM SET_TAC[]]]]);; + +let BROUWER_REDUCTION_THEOREM = prove + (`!P s:real^N->bool. + (!f. (!n. compact(f n) /\ ~(f n = {}) /\ P(f n)) /\ + (!n. f(SUC n) SUBSET f(n)) + ==> P(INTERS {f n | n IN (:num)})) /\ + compact s /\ ~(s = {}) /\ P s + ==> ?t. t SUBSET s /\ compact t /\ ~(t = {}) /\ P t /\ + (!u. u SUBSET s /\ closed u /\ ~(u = {}) /\ P u + ==> ~(u PSUBSET t))`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`\t:real^N->bool. ~(t = {}) /\ t SUBSET s /\ P t`; + `s:real^N->bool`] + BROUWER_REDUCTION_THEOREM_GEN) THEN + ASM_SIMP_TAC[COMPACT_IMP_CLOSED; SUBSET_REFL] THEN ANTS_TAC THENL + [GEN_TAC THEN STRIP_TAC THEN + SUBGOAL_THEN `!n. compact((f:num->real^N->bool) n)` ASSUME_TAC THENL + [ASM_MESON_TAC[COMPACT_EQ_BOUNDED_CLOSED; BOUNDED_SUBSET]; ALL_TAC] THEN + REPEAT CONJ_TAC THENL + [MATCH_MP_TAC COMPACT_NEST THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC TRANSITIVE_STEPWISE_LE THEN ASM_SIMP_TAC[] THEN SET_TAC[]; + ASM SET_TAC[]; + FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[]]; + MATCH_MP_TAC MONO_EXISTS THEN ASM_SIMP_TAC[] THEN + ASM_MESON_TAC[COMPACT_EQ_BOUNDED_CLOSED; BOUNDED_SUBSET]]);; + +(* ------------------------------------------------------------------------- *) +(* The Arzela-Ascoli theorem. *) +(* ------------------------------------------------------------------------- *) + +let SUBSEQUENCE_DIAGONALIZATION_LEMMA = prove + (`!P:num->(num->A)->bool. + (!i r:num->A. ?k. (!m n. m < n ==> k m < k n) /\ P i (r o k)) /\ + (!i r:num->A k1 k2 N. + P i (r o k1) /\ (!j. N <= j ==> ?j'. j <= j' /\ k2 j = k1 j') + ==> P i (r o k2)) + ==> !r:num->A. ?k. (!m n. m < n ==> k m < k n) /\ (!i. P i (r o k))`, + REPEAT GEN_TAC THEN + DISCH_THEN(CONJUNCTS_THEN2 MP_TAC STRIP_ASSUME_TAC) THEN + GEN_REWRITE_TAC (LAND_CONV o TOP_DEPTH_CONV) [SKOLEM_THM] THEN + REWRITE_TAC[FORALL_AND_THM; TAUT + `(p ==> q /\ r) <=> (p ==> q) /\ (p ==> r)`] THEN + DISCH_THEN(X_CHOOSE_THEN + `kk:num->(num->A)->num->num` STRIP_ASSUME_TAC) THEN + X_GEN_TAC `r:num->A` THEN + (STRIP_ASSUME_TAC o prove_recursive_functions_exist num_RECURSION) + `(rr 0 = (kk:num->(num->A)->num->num) 0 r) /\ + (!n. rr(SUC n) = rr n o kk (SUC n) (r o rr n))` THEN + EXISTS_TAC `\n. (rr:num->num->num) n n` THEN REWRITE_TAC[ETA_AX] THEN + SUBGOAL_THEN + `(!i. (!m n. m < n ==> (rr:num->num->num) i m < rr i n)) /\ + (!i. (P:num->(num->A)->bool) i (r o rr i))` + STRIP_ASSUME_TAC THENL + [REWRITE_TAC[AND_FORALL_THM] THEN + INDUCT_TAC THEN ASM_REWRITE_TAC[o_ASSOC] THEN + REWRITE_TAC[o_THM] THEN ASM_MESON_TAC[]; + ALL_TAC] THEN + SUBGOAL_THEN `!i j n. i <= j ==> (rr:num->num->num) i n <= rr j n` + ASSUME_TAC THENL + [REPEAT GEN_TAC THEN GEN_REWRITE_TAC LAND_CONV [LE_EXISTS] THEN + SIMP_TAC[LEFT_IMP_EXISTS_THM] THEN SPEC_TAC(`j:num`,`j:num`) THEN + ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN SIMP_TAC[FORALL_UNWIND_THM2] THEN + INDUCT_TAC THEN REWRITE_TAC[ADD_CLAUSES; LE_REFL] THEN + ASM_REWRITE_TAC[] THEN FIRST_ASSUM(MATCH_MP_TAC o MATCH_MP + (REWRITE_RULE[IMP_CONJ] LE_TRANS)) THEN REWRITE_TAC[o_THM] THEN + FIRST_ASSUM(MATCH_MP_TAC o MATCH_MP + (MESON[LE_LT] + `!f:num->num. + (!m n. m < n ==> f m < f n) ==> (!m n. m <= n ==> f m <= f n)`) o + SPEC `i + d:num`) THEN + SPEC_TAC(`n:num`,`n:num`) THEN MATCH_MP_TAC MONOTONE_BIGGER THEN + ASM_SIMP_TAC[]; + ALL_TAC] THEN + CONJ_TAC THENL + [MAP_EVERY X_GEN_TAC [`m:num`; `n:num`] THEN DISCH_TAC THEN + MATCH_MP_TAC LET_TRANS THEN + EXISTS_TAC `(rr:num->num->num) n m` THEN + ASM_MESON_TAC[LT_IMP_LE]; + ALL_TAC] THEN + SUBGOAL_THEN + `!m n i. n <= m ==> ?j. i <= j /\ (rr:num->num->num) m i = rr n j` + ASSUME_TAC THENL + [ALL_TAC; + X_GEN_TAC `i:num` THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + EXISTS_TAC `(rr:num->num->num) i` THEN ASM_REWRITE_TAC[] THEN + EXISTS_TAC `i:num` THEN ASM_MESON_TAC[]] THEN + SUBGOAL_THEN + `!p d i. ?j. i <= j /\ (rr:num->num->num) (p + d) i = rr p j` + (fun th -> MESON_TAC[LE_EXISTS; th]) THEN + X_GEN_TAC `p:num` THEN MATCH_MP_TAC num_INDUCTION THEN + ASM_REWRITE_TAC[ADD_CLAUSES] THEN CONJ_TAC THENL + [MESON_TAC[LE_REFL]; ALL_TAC] THEN + X_GEN_TAC `d:num` THEN DISCH_THEN(LABEL_TAC "+") THEN + X_GEN_TAC `i:num` THEN ASM_REWRITE_TAC[o_THM] THEN + REMOVE_THEN "+" (MP_TAC o SPEC + `(kk:num->(num->A)->num->num) (SUC(p + d)) + ((r:num->A) o (rr:num->num->num) (p + d)) i`) THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `j:num` THEN + MATCH_MP_TAC MONO_AND THEN REWRITE_TAC[] THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] LE_TRANS) THEN + SPEC_TAC(`i:num`,`i:num`) THEN MATCH_MP_TAC MONOTONE_BIGGER THEN + ASM_REWRITE_TAC[o_THM] THEN ASM_MESON_TAC[]);; + +let FUNCTION_CONVERGENT_SUBSEQUENCE = prove + (`!f:num->real^M->real^N s M. + COUNTABLE s /\ (!n x. x IN s ==> norm(f n x) <= M) + ==> ?k. (!m n:num. m < n ==> k m < k n) /\ + !x. x IN s ==> ?l. ((\n. f (k n) x) --> l) sequentially`, + REPEAT STRIP_TAC THEN + ASM_CASES_TAC `s:real^M->bool = {}` THENL + [EXISTS_TAC `\n:num. n` THEN ASM_REWRITE_TAC[NOT_IN_EMPTY]; + ALL_TAC] THEN + MP_TAC(ISPEC `s:real^M->bool` COUNTABLE_AS_IMAGE) THEN + ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `X:num->real^M` THEN DISCH_THEN SUBST_ALL_TAC THEN + MP_TAC(ISPEC + `\i r. ?l. ((\n. ((f:num->real^M->real^N) o (r:num->num)) n + ((X:num->real^M) i)) --> l) sequentially` + SUBSEQUENCE_DIAGONALIZATION_LEMMA) THEN + REWRITE_TAC[FORALL_IN_IMAGE; o_THM; IN_UNIV] THEN + ANTS_TAC THENL [ALL_TAC; DISCH_THEN MATCH_ACCEPT_TAC] THEN CONJ_TAC THENL + [RULE_ASSUM_TAC(REWRITE_RULE[FORALL_IN_IMAGE; IN_UNIV]) THEN + MAP_EVERY X_GEN_TAC [`i:num`; `r:num->num`] THEN + MP_TAC(ISPEC `cball(vec 0:real^N,M)` compact) THEN + REWRITE_TAC[COMPACT_CBALL] THEN DISCH_THEN(MP_TAC o SPEC + `\n. (f:num->real^M->real^N) ((r:num->num) n) (X(i:num))`) THEN + ASM_REWRITE_TAC[IN_CBALL_0; o_DEF] THEN MESON_TAC[]; + REPEAT GEN_TAC THEN REWRITE_TAC[LIM_SEQUENTIALLY; GE] THEN + DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) 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[] THEN + ASM_MESON_TAC[LE_TRANS; ARITH_RULE `MAX a b <= c <=> a <= c /\ b <= c`]]);; + +let ARZELA_ASCOLI = prove + (`!f:num->real^M->real^N s M. + compact s /\ + (!n x. x IN s ==> norm(f n x) <= M) /\ + (!x e. x IN s /\ &0 < e + ==> ?d. &0 < d /\ + !n y. y IN s /\ norm(x - y) < d + ==> norm(f n x - f n y) < e) + ==> ?g. g continuous_on s /\ + ?r. (!m n:num. m < n ==> r m < r n) /\ + !e. &0 < e + ==> ?N. !n x. n >= N /\ x IN s + ==> norm(f(r n) x - g x) < e`, + REPEAT STRIP_TAC THEN REWRITE_TAC[GE] THEN + MATCH_MP_TAC(MESON[] + `(!k g. V k g ==> N g) /\ (?k. M k /\ ?g. V k g) + ==> ?g. N g /\ ?k. M k /\ V k g`) THEN + CONJ_TAC THENL + [MAP_EVERY X_GEN_TAC [`k:num->num`; `g:real^M->real^N`] THEN + STRIP_TAC THEN MATCH_MP_TAC(ISPEC `sequentially` + CONTINUOUS_UNIFORM_LIMIT) THEN + EXISTS_TAC `(f:num->real^M->real^N) o (k:num->num)` THEN + ASM_SIMP_TAC[EVENTUALLY_SEQUENTIALLY; o_THM; TRIVIAL_LIMIT_SEQUENTIALLY; + RIGHT_IMP_FORALL_THM; IMP_IMP] THEN + EXISTS_TAC `0` THEN REWRITE_TAC[continuous_on; dist] THEN + ASM_MESON_TAC[NORM_SUB]; + ALL_TAC] THEN + MP_TAC(ISPECL + [`IMAGE (f:num->real^M->real^N) (:num)`; + `s:real^M->bool`] + COMPACT_UNIFORMLY_EQUICONTINUOUS) THEN + REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_IMAGE; IN_UNIV] THEN + ANTS_TAC THENL + [REWRITE_TAC[dist] THEN ONCE_REWRITE_TAC[NORM_SUB] THEN ASM_MESON_TAC[]; + ASM_REWRITE_TAC[] THEN FIRST_X_ASSUM(K ALL_TAC o SPEC `x:real^M`)] THEN + REWRITE_TAC[RIGHT_IMP_FORALL_THM] THEN + REWRITE_TAC[IMP_IMP; GSYM CONJ_ASSOC; dist] THEN + DISCH_THEN(ASSUME_TAC o ONCE_REWRITE_RULE[NORM_SUB]) THEN + REWRITE_TAC[GSYM dist; UNIFORMLY_CONVERGENT_EQ_CAUCHY] THEN + X_CHOOSE_THEN `r:real^M->bool` STRIP_ASSUME_TAC + (ISPEC `s:real^M->bool` SEPARABLE) THEN + MP_TAC(ISPECL [`f:num->real^M->real^N`; `r:real^M->bool`; `M:real`] + FUNCTION_CONVERGENT_SUBSEQUENCE) THEN + ANTS_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `k:num->num` THEN + REWRITE_TAC[CONVERGENT_EQ_CAUCHY; cauchy] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC (LABEL_TAC "*")) THEN + ASM_REWRITE_TAC[] THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `e / &3`) THEN + ANTS_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN + DISCH_THEN(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC) THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [COMPACT_EQ_HEINE_BOREL]) THEN + DISCH_THEN(MP_TAC o SPEC `IMAGE (\x:real^M. ball(x,d)) r`) THEN + REWRITE_TAC[FORALL_IN_IMAGE; OPEN_BALL] THEN + ONCE_REWRITE_TAC[TAUT `a /\ b /\ c <=> b /\ a /\ c`] THEN + REWRITE_TAC[EXISTS_FINITE_SUBSET_IMAGE] THEN ANTS_TAC THENL + [MATCH_MP_TAC SUBSET_TRANS THEN EXISTS_TAC `closure r:real^M->bool` THEN + ASM_REWRITE_TAC[] THEN REWRITE_TAC[SUBSET; CLOSURE_APPROACHABLE] THEN + X_GEN_TAC `x:real^M` THEN DISCH_THEN(MP_TAC o SPEC `d:real`) THEN + ASM_REWRITE_TAC[UNIONS_IMAGE; IN_ELIM_THM; IN_BALL]; + DISCH_THEN(X_CHOOSE_THEN `t:real^M->bool` STRIP_ASSUME_TAC)] THEN + REMOVE_THEN "*" MP_TAC THEN REWRITE_TAC[RIGHT_IMP_FORALL_THM] THEN + GEN_REWRITE_TAC LAND_CONV [SWAP_FORALL_THM] THEN + DISCH_THEN(MP_TAC o SPEC `e / &3`) THEN + ASM_REWRITE_TAC[REAL_ARITH `&0 < e / &3 <=> &0 < e`] THEN + GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [RIGHT_IMP_EXISTS_THM] THEN + REWRITE_TAC[SKOLEM_THM; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `M:real^M->num` THEN DISCH_THEN(LABEL_TAC "*") THEN + MP_TAC(ISPECL [`M:real^M->num`; `t:real^M->bool`] + UPPER_BOUND_FINITE_SET) THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `N:num` THEN + DISCH_TAC THEN + MAP_EVERY X_GEN_TAC [`m:num`; `n:num`; `x:real^M`] THEN STRIP_TAC THEN + UNDISCH_TAC `s SUBSET UNIONS (IMAGE (\x:real^M. ball (x,d)) t)` THEN + REWRITE_TAC[SUBSET; UNIONS_IMAGE; IN_ELIM_THM] THEN + DISCH_THEN(MP_TAC o SPEC `x:real^M`) THEN + ASM_REWRITE_TAC[IN_BALL; LEFT_IMP_EXISTS_THM; dist] THEN + X_GEN_TAC `y:real^M` THEN STRIP_TAC THEN + MATCH_MP_TAC(NORM_ARITH + `norm(f (k(m:num)) y - f (k m) x) < e / &3 /\ + norm(f (k n) y - f (k n) x) < e / &3 /\ + norm(f (k m) y - f (k n) y) < e / &3 + ==> norm(f (k m) x - f (k n) x :real^M) < e`) THEN + ASM_SIMP_TAC[] THEN REMOVE_THEN "*" (MP_TAC o SPEC `y:real^M`) THEN + ANTS_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + DISCH_THEN(MP_TAC o SPECL [`m:num`; `n:num`]) THEN + ASM_REWRITE_TAC[dist; GE] THEN ASM_MESON_TAC[SUBSET; LE_TRANS]);; diff --git a/Multivariate/transcendentals.ml b/Multivariate/transcendentals.ml new file mode 100644 index 0000000..b9c4cbe --- /dev/null +++ b/Multivariate/transcendentals.ml @@ -0,0 +1,6553 @@ +(* ========================================================================= *) +(* Complex transcendentals and their real counterparts. *) +(* *) +(* (c) Copyright, John Harrison 1998-2008 *) +(* ========================================================================= *) + +needs "Multivariate/determinants.ml";; +needs "Multivariate/canal.ml";; + +prioritize_complex();; + +(* ------------------------------------------------------------------------- *) +(* The complex exponential function. *) +(* ------------------------------------------------------------------------- *) + +let cexp = new_definition + `cexp z = infsum (from 0) (\n. z pow n / Cx(&(FACT n)))`;; + +let CEXP_0 = prove + (`cexp(Cx(&0)) = Cx(&1)`, + REWRITE_TAC[cexp] THEN MATCH_MP_TAC INFSUM_UNIQUE THEN + MP_TAC(ISPECL [`\i. Cx(&0) pow i / Cx(&(FACT i))`; `{0}`; `from 0`] + SERIES_FINITE_SUPPORT) THEN + SIMP_TAC[FROM_0; INTER_UNIV; FINITE_INSERT; FINITE_RULES] THEN ANTS_TAC THENL + [INDUCT_TAC THEN REWRITE_TAC[IN_SING; NOT_SUC] THEN + REWRITE_TAC[complex_div; complex_pow; COMPLEX_MUL_LZERO; COMPLEX_VEC_0]; + REWRITE_TAC[VSUM_SING; FACT; COMPLEX_DIV_1; complex_pow]]);; + +let CEXP_CONVERGES_UNIFORMLY_CAUCHY = prove + (`!R e. &0 < e /\ &0 < R + ==> ?N. !m n z. m >= N /\ norm(z) <= R + ==> norm(vsum(m..n) (\i. z pow i / Cx(&(FACT i)))) + < e`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`&1 / &2`; `\i. Cx(R) pow i / Cx(&(FACT i))`; + `from 0`] SERIES_RATIO) THEN + REWRITE_TAC[SERIES_CAUCHY; LEFT_FORALL_IMP_THM] THEN + MP_TAC(SPEC `&2 * norm(Cx(R))` REAL_ARCH_SIMPLE) THEN + REWRITE_TAC[COMPLEX_NORM_CX; COMPLEX_NORM_DIV; COMPLEX_NORM_POW] THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN + MATCH_MP_TAC(TAUT `(a ==> b) /\ (c ==> d) ==> a ==> (b ==> c) ==> d`) THEN + CONJ_TAC THENL + [MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `N:num` THEN DISCH_TAC THEN + X_GEN_TAC `n:num` THEN REWRITE_TAC[GE] THEN DISCH_TAC THEN + SIMP_TAC[FACT; real_pow; GSYM REAL_OF_NUM_MUL; real_div; REAL_INV_MUL] THEN + REWRITE_TAC[REAL_ARITH + `(z * zn) * (is * ik) <= (&1 * inv(&2)) * zn * ik <=> + &0 <= (&1 - (&2 * z) * is) * zn * ik`] THEN + MATCH_MP_TAC REAL_LE_MUL THEN + SIMP_TAC[REAL_LE_MUL; REAL_POS; REAL_POW_LE; REAL_SUB_LE; + REAL_LE_INV_EQ; REAL_ABS_POS] THEN + ASM_SIMP_TAC[GSYM real_div; REAL_LE_LDIV_EQ; REAL_OF_NUM_LT; LT_0] THEN + REPEAT(POP_ASSUM MP_TAC) THEN + REWRITE_TAC[GSYM REAL_OF_NUM_LE; GSYM REAL_OF_NUM_SUC] THEN + REAL_ARITH_TAC; + DISCH_THEN(MP_TAC o SPEC `e:real`) THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `N:num` THEN + REWRITE_TAC[FROM_0; INTER_UNIV] THEN + REPEAT(MATCH_MP_TAC MONO_FORALL THEN GEN_TAC) THEN + DISCH_THEN(fun th -> REPEAT STRIP_TAC THEN MP_TAC th) THEN + ASM_SIMP_TAC[GSYM CX_DIV; GSYM CX_POW; VSUM_CX_NUMSEG; COMPLEX_NORM_CX] THEN + MATCH_MP_TAC(REAL_ARITH `x <= y ==> y < e ==> x < e`) THEN + SUBGOAL_THEN `abs (sum (m..n) (\i. R pow i / &(FACT i))) = + sum (m..n) (\i. R pow i / &(FACT i))` + SUBST1_TAC THENL + [REWRITE_TAC[REAL_ABS_REFL] THEN MATCH_MP_TAC SUM_POS_LE_NUMSEG THEN + ASM_SIMP_TAC[REAL_LT_IMP_LE;REAL_LT_DIV; REAL_OF_NUM_LT; + FACT_LT; REAL_POW_LT]; + ALL_TAC] THEN + MATCH_MP_TAC VSUM_NORM_LE THEN REWRITE_TAC[IN_NUMSEG; FINITE_NUMSEG] THEN + X_GEN_TAC `i:num` THEN + REWRITE_TAC[COMPLEX_NORM_DIV; COMPLEX_NORM_POW; COMPLEX_NORM_CX] THEN + SIMP_TAC[REAL_ABS_NUM; REAL_LE_DIV2_EQ; REAL_OF_NUM_LT; FACT_LT] THEN + ASM_SIMP_TAC[REAL_POW_LE2; NORM_POS_LE]]);; + +let CEXP_CONVERGES = prove + (`!z. ((\n. z pow n / Cx(&(FACT n))) sums cexp(z)) (from 0)`, + GEN_TAC THEN REWRITE_TAC[cexp; SUMS_INFSUM; summable; SERIES_CAUCHY] THEN + REWRITE_TAC[FROM_0; INTER_UNIV] THEN + MP_TAC(SPEC `norm(z:complex) + &1` CEXP_CONVERGES_UNIFORMLY_CAUCHY) THEN + SIMP_TAC[REAL_ARITH `&0 <= x ==> &0 < x + &1`; NORM_POS_LE] THEN + MESON_TAC[REAL_ARITH `x <= x + &1`]);; + +let CEXP_CONVERGES_UNIQUE = prove + (`!w z. ((\n. z pow n / Cx(&(FACT n))) sums w) (from 0) <=> w = cexp(z)`, + REPEAT GEN_TAC THEN EQ_TAC THEN SIMP_TAC[CEXP_CONVERGES] THEN + DISCH_THEN(MP_TAC o C CONJ (SPEC `z:complex` CEXP_CONVERGES)) THEN + REWRITE_TAC[SERIES_UNIQUE]);; + +let CEXP_CONVERGES_UNIFORMLY = prove + (`!R e. &0 < R /\ &0 < e + ==> ?N. !n z. n >= N /\ norm(z) < R + ==> norm(vsum(0..n) (\i. z pow i / Cx(&(FACT i))) - + cexp(z)) <= e`, + REPEAT STRIP_TAC THEN + MP_TAC(SPECL [`R:real`; `e / &2`] CEXP_CONVERGES_UNIFORMLY_CAUCHY) THEN + ASM_REWRITE_TAC[REAL_HALF] THEN MATCH_MP_TAC MONO_EXISTS THEN + X_GEN_TAC `N:num` THEN DISCH_TAC THEN + MAP_EVERY X_GEN_TAC [`n:num`; `z:complex`] THEN STRIP_TAC THEN + MP_TAC(SPEC `z:complex` CEXP_CONVERGES) THEN + REWRITE_TAC[sums; LIM_SEQUENTIALLY; FROM_0; INTER_UNIV; dist] THEN + DISCH_THEN(MP_TAC o SPEC `e / &2`) THEN ASM_REWRITE_TAC[REAL_HALF] THEN + DISCH_THEN(X_CHOOSE_THEN `M:num` (MP_TAC o SPEC `n + M + 1`)) THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`n + 1`; `n + M + 1`; `z:complex`]) THEN + ASM_SIMP_TAC[ARITH_RULE `(n >= N ==> n + 1 >= N) /\ M <= n + M + 1`] THEN + ASM_SIMP_TAC[REAL_LT_IMP_LE; VSUM_ADD_SPLIT; LE_0] THEN + CONV_TAC(ONCE_DEPTH_CONV(ALPHA_CONV `i:num`)) THEN NORM_ARITH_TAC);; + +let HAS_COMPLEX_DERIVATIVE_CEXP = prove + (`!z. (cexp has_complex_derivative cexp(z)) (at z)`, + REPEAT GEN_TAC THEN MP_TAC(ISPECL + [`ball(Cx(&0),norm(z:complex) + &1)`; + `\n z. z pow n / Cx(&(FACT n))`; + `\n z. if n = 0 then Cx(&0) else z pow (n-1) / Cx(&(FACT(n-1)))`; + `cexp:complex->complex`; + `(from 0)`] + HAS_COMPLEX_DERIVATIVE_SERIES) THEN + REWRITE_TAC[CONVEX_BALL; OPEN_BALL; IN_BALL; dist] THEN + SIMP_TAC[HAS_COMPLEX_DERIVATIVE_WITHIN_OPEN; OPEN_BALL; IN_BALL; + dist; COMPLEX_SUB_LZERO; COMPLEX_SUB_RZERO; NORM_NEG] THEN + ANTS_TAC THEN REPEAT CONJ_TAC THENL + [X_GEN_TAC `n:num` THEN REPEAT STRIP_TAC THEN COMPLEX_DIFF_TAC THEN + SPEC_TAC(`n:num`,`n:num`) THEN INDUCT_TAC THEN + REWRITE_TAC[ARITH; complex_div; COMPLEX_MUL_LZERO] THEN + MP_TAC(SPECL [`&n + &1`; `&0`] CX_INJ) THEN + REWRITE_TAC[NOT_SUC; SUC_SUB1; GSYM REAL_OF_NUM_SUC; FACT; + CX_ADD; CX_MUL; GSYM REAL_OF_NUM_MUL; COMPLEX_INV_MUL] THEN + REWRITE_TAC[REAL_ARITH `~(&n + &1 = &0)`] THEN + ABBREV_TAC `a = inv(Cx(&(FACT n)))` THEN CONV_TAC COMPLEX_FIELD; + REPEAT STRIP_TAC THEN + MP_TAC(SPECL [`norm(z:complex) + &1`; `e:real`] + CEXP_CONVERGES_UNIFORMLY) THEN + ASM_SIMP_TAC[NORM_POS_LE; REAL_ARITH `&0 <= x ==> &0 < x + &1`] THEN + DISCH_THEN(X_CHOOSE_TAC `N:num`) THEN EXISTS_TAC `N + 1` THEN + MAP_EVERY X_GEN_TAC [`n:num`; `w:complex`] THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`n - 1`; `w:complex`]) THEN + ASM_SIMP_TAC[ARITH_RULE `n >= m + 1 ==> n - 1 >= m`] THEN + REWRITE_TAC[FROM_0; INTER_UNIV] THEN MATCH_MP_TAC EQ_IMP THEN + AP_THM_TAC THEN AP_TERM_TAC THEN AP_TERM_TAC THEN + AP_THM_TAC THEN AP_TERM_TAC THEN + SUBGOAL_THEN `0..n = 0 INSERT (IMAGE SUC (0..n-1))` SUBST1_TAC THENL + [REWRITE_TAC[EXTENSION; IN_INSERT; IN_IMAGE; IN_NUMSEG] THEN + INDUCT_TAC THEN REWRITE_TAC[LE_0; NOT_SUC; SUC_INJ; UNWIND_THM1] THEN + UNDISCH_TAC `n >= N + 1` THEN ARITH_TAC; + ALL_TAC] THEN + SIMP_TAC[VSUM_CLAUSES; FINITE_IMAGE; FINITE_NUMSEG] THEN + REWRITE_TAC[IN_IMAGE; NOT_SUC; COMPLEX_ADD_LID] THEN + SIMP_TAC[VSUM_IMAGE; FINITE_NUMSEG; SUC_INJ] THEN + MATCH_MP_TAC VSUM_EQ THEN SIMP_TAC[IN_NUMSEG; NOT_SUC; o_THM; SUC_SUB1]; + MAP_EVERY EXISTS_TAC [`Cx(&0)`; `cexp(Cx(&0))`] THEN + REWRITE_TAC[CEXP_CONVERGES; COMPLEX_NORM_0] THEN + SIMP_TAC[REAL_ARITH `&0 <= z ==> &0 < z + &1`; NORM_POS_LE]; + DISCH_THEN(X_CHOOSE_THEN `g:complex->complex` MP_TAC) THEN + REWRITE_TAC[CEXP_CONVERGES_UNIQUE] THEN STRIP_TAC THEN + MATCH_MP_TAC HAS_COMPLEX_DERIVATIVE_TRANSFORM_AT THEN + MAP_EVERY EXISTS_TAC [`g:complex->complex`; `&1`] THEN + REWRITE_TAC[REAL_LT_01] THEN CONJ_TAC THENL + [ALL_TAC; + FIRST_X_ASSUM(MP_TAC o SPEC `z:complex`) THEN + ANTS_TAC THENL [REAL_ARITH_TAC; SIMP_TAC[]]] THEN + POP_ASSUM MP_TAC THEN MATCH_MP_TAC MONO_FORALL THEN + X_GEN_TAC `w:complex` THEN MATCH_MP_TAC MONO_IMP THEN SIMP_TAC[] THEN + NORM_ARITH_TAC]);; + +let COMPLEX_DIFFERENTIABLE_AT_CEXP = prove + (`!z. cexp complex_differentiable at z`, + REWRITE_TAC[complex_differentiable] THEN + MESON_TAC[HAS_COMPLEX_DERIVATIVE_CEXP]);; + +let COMPLEX_DIFFERENTIABLE_WITHIN_CEXP = prove + (`!s z. cexp complex_differentiable (at z within s)`, + MESON_TAC[COMPLEX_DIFFERENTIABLE_AT_WITHIN; + COMPLEX_DIFFERENTIABLE_AT_CEXP]);; + +let CONTINUOUS_AT_CEXP = prove + (`!z. cexp continuous at z`, + MESON_TAC[HAS_COMPLEX_DERIVATIVE_CEXP; + HAS_COMPLEX_DERIVATIVE_IMP_CONTINUOUS_AT]);; + +let CONTINUOUS_WITHIN_CEXP = prove + (`!s z. cexp continuous (at z within s)`, + MESON_TAC[CONTINUOUS_AT_WITHIN; CONTINUOUS_AT_CEXP]);; + +let CONTINUOUS_ON_CEXP = prove + (`!s. cexp continuous_on s`, + MESON_TAC[CONTINUOUS_AT_IMP_CONTINUOUS_ON; CONTINUOUS_AT_CEXP]);; + +let HOLOMORPHIC_ON_CEXP = prove + (`!s. cexp holomorphic_on s`, + REWRITE_TAC [holomorphic_on] THEN + MESON_TAC [HAS_COMPLEX_DERIVATIVE_AT_WITHIN; HAS_COMPLEX_DERIVATIVE_CEXP]);; + +(* ------------------------------------------------------------------------- *) +(* Add it to the database. *) +(* ------------------------------------------------------------------------- *) + +add_complex_differentiation_theorems + (CONJUNCTS(REWRITE_RULE[FORALL_AND_THM] + (MATCH_MP HAS_COMPLEX_DERIVATIVE_CHAIN_UNIV + HAS_COMPLEX_DERIVATIVE_CEXP)));; + +(* ------------------------------------------------------------------------- *) +(* Hence the main results. *) +(* ------------------------------------------------------------------------- *) + +let CEXP_ADD_MUL = prove + (`!w z. cexp(w + z) * cexp(--z) = cexp(w)`, + GEN_TAC THEN + ONCE_REWRITE_TAC[SET_RULE `(!x. P x) <=> (!x. x IN UNIV ==> P x)`] THEN + MATCH_MP_TAC HAS_COMPLEX_DERIVATIVE_ZERO_UNIQUE THEN + EXISTS_TAC `Cx(&0)` THEN REWRITE_TAC[OPEN_UNIV; CONVEX_UNIV; IN_UNIV] THEN + REWRITE_TAC[COMPLEX_ADD_RID; COMPLEX_NEG_0; CEXP_0; COMPLEX_MUL_RID] THEN + GEN_TAC THEN COMPLEX_DIFF_TAC THEN CONV_TAC COMPLEX_RING);; + +let CEXP_NEG_RMUL = prove + (`!z. cexp(z) * cexp(--z) = Cx(&1)`, + MP_TAC(SPEC `Cx(&0)` CEXP_ADD_MUL) THEN MATCH_MP_TAC MONO_FORALL THEN + SIMP_TAC[COMPLEX_ADD_LID; CEXP_0]);; + +let CEXP_NEG_LMUL = prove + (`!z. cexp(--z) * cexp(z) = Cx(&1)`, + ONCE_REWRITE_TAC[COMPLEX_MUL_SYM] THEN REWRITE_TAC[CEXP_NEG_RMUL]);; + +let CEXP_NEG = prove + (`!z. cexp(--z) = inv(cexp z)`, + MP_TAC CEXP_NEG_LMUL THEN MATCH_MP_TAC MONO_FORALL THEN + CONV_TAC COMPLEX_FIELD);; + +let CEXP_ADD = prove + (`!w z. cexp(w + z) = cexp(w) * cexp(z)`, + REPEAT GEN_TAC THEN + MP_TAC(SPECL [`w:complex`; `z:complex`] CEXP_ADD_MUL) THEN + MP_TAC(SPEC `z:complex` CEXP_NEG_LMUL) THEN CONV_TAC COMPLEX_FIELD);; + +let CEXP_SUB = prove + (`!w z. cexp(w - z) = cexp(w) / cexp(z)`, + REPEAT GEN_TAC THEN + REWRITE_TAC[complex_sub; complex_div; CEXP_ADD; CEXP_NEG]);; + +let CEXP_NZ = prove + (`!z. ~(cexp(z) = Cx(&0))`, + MP_TAC CEXP_NEG_LMUL THEN MATCH_MP_TAC MONO_FORALL THEN + CONV_TAC COMPLEX_FIELD);; + +let CEXP_N = prove + (`!n x. cexp(Cx(&n) * x) = cexp(x) pow n`, + INDUCT_TAC THEN REWRITE_TAC[GSYM REAL_OF_NUM_SUC; CX_ADD] THEN + REWRITE_TAC[COMPLEX_MUL_LZERO; complex_pow; CEXP_0] THEN + ASM_REWRITE_TAC[COMPLEX_ADD_RDISTRIB; CEXP_ADD; COMPLEX_MUL_LID] THEN + REWRITE_TAC[COMPLEX_MUL_AC]);; + +let CEXP_VSUM = prove + (`!f s. FINITE s ==> cexp(vsum s f) = cproduct s (\x. cexp(f x))`, + GEN_TAC THEN MATCH_MP_TAC FINITE_INDUCT_STRONG THEN + SIMP_TAC[VSUM_CLAUSES; CPRODUCT_CLAUSES; CEXP_ADD; COMPLEX_VEC_0; CEXP_0]);; + +let LIM_CEXP_MINUS_1 = prove + (`((\z. (cexp(z) - Cx(&1)) / z) --> Cx(&1)) (at (Cx(&0)))`, + MP_TAC(COMPLEX_DIFF_CONV + `((\z. cexp(z) - Cx(&1)) has_complex_derivative f') (at(Cx(&0)))`) THEN + REWRITE_TAC[HAS_COMPLEX_DERIVATIVE_AT; CEXP_0; COMPLEX_SUB_REFL] THEN + REWRITE_TAC[COMPLEX_MUL_LID; COMPLEX_SUB_RZERO]);; + +(* ------------------------------------------------------------------------- *) +(* Crude bounds on complex exponential function, usable to get tighter ones. *) +(* ------------------------------------------------------------------------- *) + +let CEXP_BOUND_BLEMMA = prove + (`!B. (!z. norm(z) <= &1 / &2 ==> norm(cexp z) <= B) + ==> !z. norm(z) <= &1 / &2 ==> norm(cexp z) <= &1 + B / &2`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`cexp`; `cexp`; `cball(Cx(&0),&1 / &2)`; `B:real`] + COMPLEX_DIFFERENTIABLE_BOUND) THEN + ASM_SIMP_TAC[CONVEX_CBALL; IN_CBALL; dist; COMPLEX_SUB_LZERO; NORM_NEG; + HAS_COMPLEX_DERIVATIVE_AT_WITHIN; HAS_COMPLEX_DERIVATIVE_CEXP] THEN + DISCH_THEN(MP_TAC o SPECL [`z:complex`; `Cx(&0)`]) THEN + REWRITE_TAC[COMPLEX_NORM_0; CEXP_0; COMPLEX_SUB_RZERO] THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC(NORM_ARITH + `norm(y) = &1 /\ d <= e ==> norm(x - y) <= d ==> norm(x) <= &1 + e`) THEN + REWRITE_TAC[COMPLEX_NORM_CX; real_div; REAL_ABS_NUM] THEN + MATCH_MP_TAC REAL_LE_LMUL THEN FIRST_X_ASSUM(MP_TAC o SPEC `Cx(&0)`) THEN + REWRITE_TAC[COMPLEX_NORM_CX] THEN POP_ASSUM MP_TAC THEN + NORM_ARITH_TAC);; + +let CEXP_BOUND_HALF = prove + (`!z. norm(z) <= &1 / &2 ==> norm(cexp z) <= &2`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`IMAGE cexp (cball(Cx(&0),&1 / &2))`; `Cx(&0)`] + DISTANCE_ATTAINS_SUP) THEN + SIMP_TAC[COMPACT_CONTINUOUS_IMAGE; COMPACT_CBALL; CONTINUOUS_ON_CEXP; + IMAGE_EQ_EMPTY; CBALL_EQ_EMPTY; FORALL_IN_IMAGE; EXISTS_IN_IMAGE; + IN_CBALL; dist; COMPLEX_SUB_LZERO; NORM_NEG] THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN + DISCH_THEN(X_CHOOSE_THEN `w:complex` STRIP_ASSUME_TAC) THEN + FIRST_ASSUM(MP_TAC o SPEC `w:complex` o MATCH_MP CEXP_BOUND_BLEMMA) THEN + FIRST_X_ASSUM(MP_TAC o SPEC `z:complex`) THEN + ASM_REWRITE_TAC[] THEN REAL_ARITH_TAC);; + +let CEXP_BOUND_LEMMA = prove + (`!z. norm(z) <= &1 / &2 ==> norm(cexp z) <= &1 + &2 * norm(z)`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`cexp`; `cexp`; `cball(Cx(&0),&1 / &2)`; `&2`] + COMPLEX_DIFFERENTIABLE_BOUND) THEN + ASM_SIMP_TAC[CONVEX_CBALL; IN_CBALL; dist; COMPLEX_SUB_LZERO; NORM_NEG; + HAS_COMPLEX_DERIVATIVE_AT_WITHIN; HAS_COMPLEX_DERIVATIVE_CEXP; + CEXP_BOUND_HALF] THEN + DISCH_THEN(MP_TAC o SPECL [`z:complex`; `Cx(&0)`]) THEN + REWRITE_TAC[COMPLEX_NORM_0; CEXP_0; COMPLEX_SUB_RZERO] THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC(NORM_ARITH + `norm(y) = &1 ==> norm(x - y) <= d ==> norm(x) <= &1 + d`) THEN + REWRITE_TAC[COMPLEX_NORM_CX; REAL_ABS_NUM]);; + +(* ------------------------------------------------------------------------- *) +(* Complex trig functions. *) +(* ------------------------------------------------------------------------- *) + +let ccos = new_definition + `ccos z = (cexp(ii * z) + cexp(--ii * z)) / Cx(&2)`;; + +let csin = new_definition + `csin z = (cexp(ii * z) - cexp(--ii * z)) / (Cx(&2) * ii)`;; + +let CSIN_0 = prove + (`csin(Cx(&0)) = Cx(&0)`, + REWRITE_TAC[csin; COMPLEX_MUL_RZERO; COMPLEX_SUB_REFL] THEN + CONV_TAC COMPLEX_FIELD);; + +let CCOS_0 = prove + (`ccos(Cx(&0)) = Cx(&1)`, + REWRITE_TAC[ccos; COMPLEX_MUL_RZERO; CEXP_0] THEN + CONV_TAC COMPLEX_FIELD);; + +let CSIN_CIRCLE = prove + (`!z. csin(z) pow 2 + ccos(z) pow 2 = Cx(&1)`, + GEN_TAC THEN REWRITE_TAC[csin; ccos] THEN + MP_TAC(SPEC `ii * z` CEXP_NEG_LMUL) THEN + REWRITE_TAC[COMPLEX_MUL_LNEG] THEN + CONV_TAC COMPLEX_FIELD);; + +let CSIN_ADD = prove + (`!w z. csin(w + z) = csin(w) * ccos(z) + ccos(w) * csin(z)`, + REPEAT GEN_TAC THEN + REWRITE_TAC[csin; ccos; COMPLEX_ADD_LDISTRIB; CEXP_ADD] THEN + CONV_TAC COMPLEX_FIELD);; + +let CCOS_ADD = prove + (`!w z. ccos(w + z) = ccos(w) * ccos(z) - csin(w) * csin(z)`, + REPEAT GEN_TAC THEN + REWRITE_TAC[csin; ccos; COMPLEX_ADD_LDISTRIB; CEXP_ADD] THEN + CONV_TAC COMPLEX_FIELD);; + +let CSIN_NEG = prove + (`!z. csin(--z) = --(csin(z))`, + REWRITE_TAC[csin; COMPLEX_MUL_LNEG; COMPLEX_MUL_RNEG; COMPLEX_NEG_NEG] THEN + CONV_TAC COMPLEX_FIELD);; + +let CCOS_NEG = prove + (`!z. ccos(--z) = ccos(z)`, + REWRITE_TAC[ccos; COMPLEX_MUL_LNEG; COMPLEX_MUL_RNEG; COMPLEX_NEG_NEG] THEN + CONV_TAC COMPLEX_FIELD);; + +let CSIN_DOUBLE = prove + (`!z. csin(Cx(&2) * z) = Cx(&2) * csin(z) * ccos(z)`, + REWRITE_TAC[COMPLEX_RING `Cx(&2) * x = x + x`; CSIN_ADD] THEN + CONV_TAC COMPLEX_RING);; + +let CCOS_DOUBLE = prove + (`!z. ccos(Cx(&2) * z) = (ccos(z) pow 2) - (csin(z) pow 2)`, + REWRITE_TAC[COMPLEX_RING `Cx(&2) * x = x + x`; CCOS_ADD] THEN + CONV_TAC COMPLEX_RING);; + +let CSIN_SUB = prove + (`!w z. csin(w - z) = csin(w) * ccos(z) - ccos(w) * csin(z)`, + REWRITE_TAC[complex_sub; COMPLEX_MUL_RNEG; CSIN_ADD; CSIN_NEG; CCOS_NEG]);; + +let CCOS_SUB = prove + (`!w z. ccos(w - z) = ccos(w) * ccos(z) + csin(w) * csin(z)`, + REWRITE_TAC[complex_sub; CCOS_ADD; CSIN_NEG; CCOS_NEG; + COMPLEX_MUL_RNEG; COMPLEX_NEG_NEG]);; + +let COMPLEX_MUL_CSIN_CSIN = prove + (`!w z. csin(w) * csin(z) = (ccos(w - z) - ccos(w + z)) / Cx(&2)`, + REWRITE_TAC[CCOS_ADD; CCOS_SUB] THEN CONV_TAC COMPLEX_RING);; + +let COMPLEX_MUL_CSIN_CCOS = prove + (`!w z. csin(w) * ccos(z) = (csin(w + z) + csin(w - z)) / Cx(&2)`, + REWRITE_TAC[CSIN_ADD; CSIN_SUB] THEN CONV_TAC COMPLEX_RING);; + +let COMPLEX_MUL_CCOS_CSIN = prove + (`!w z. ccos(w) * csin(z) = (csin(w + z) - csin(w - z)) / Cx(&2)`, + REWRITE_TAC[CSIN_ADD; CSIN_SUB] THEN CONV_TAC COMPLEX_RING);; + +let COMPLEX_MUL_CCOS_CCOS = prove + (`!w z. ccos(w) * ccos(z) = (ccos(w - z) + ccos(w + z)) / Cx(&2)`, + REWRITE_TAC[CCOS_ADD; CCOS_SUB] THEN CONV_TAC COMPLEX_RING);; + +let COMPLEX_ADD_CSIN = prove + (`!w z. csin(w) + csin(z) = + Cx(&2) * csin((w + z) / Cx(&2)) * ccos((w - z) / Cx(&2))`, + SIMP_TAC[COMPLEX_MUL_CSIN_CCOS; COMPLEX_RING `Cx(&2) * x / Cx(&2) = x`] THEN + REPEAT GEN_TAC THEN BINOP_TAC THEN AP_TERM_TAC THEN CONV_TAC COMPLEX_RING);; + +let COMPLEX_SUB_CSIN = prove + (`!w z. csin(w) - csin(z) = + Cx(&2) * csin((w - z) / Cx(&2)) * ccos((w + z) / Cx(&2))`, + SIMP_TAC[COMPLEX_MUL_CSIN_CCOS; COMPLEX_RING `Cx(&2) * x / Cx(&2) = x`] THEN + REPEAT GEN_TAC THEN REWRITE_TAC[complex_sub; GSYM CSIN_NEG] THEN + BINOP_TAC THEN AP_TERM_TAC THEN CONV_TAC COMPLEX_RING);; + +let COMPLEX_ADD_CCOS = prove + (`!w z. ccos(w) + ccos(z) = + Cx(&2) * ccos((w + z) / Cx(&2)) * ccos((w - z) / Cx(&2))`, + SIMP_TAC[COMPLEX_MUL_CCOS_CCOS; COMPLEX_RING `Cx(&2) * x / Cx(&2) = x`] THEN + REPEAT GEN_TAC THEN GEN_REWRITE_TAC LAND_CONV [COMPLEX_ADD_SYM] THEN + BINOP_TAC THEN AP_TERM_TAC THEN CONV_TAC COMPLEX_RING);; + +let COMPLEX_SUB_CCOS = prove + (`!w z. ccos(w) - ccos(z) = + Cx(&2) * csin((w + z) / Cx(&2)) * csin((z - w) / Cx(&2))`, + SIMP_TAC[COMPLEX_MUL_CSIN_CSIN; COMPLEX_RING `Cx(&2) * x / Cx(&2) = x`] THEN + REPEAT GEN_TAC THEN BINOP_TAC THEN AP_TERM_TAC THEN CONV_TAC COMPLEX_RING);; + +let CCOS_DOUBLE_CCOS = prove + (`!z. ccos(Cx(&2) * z) = Cx(&2) * ccos z pow 2 - Cx(&1)`, + GEN_TAC THEN REWRITE_TAC[COMPLEX_RING `Cx(&2) * x = x + x`; CCOS_ADD] THEN + MP_TAC(SPEC `z:complex` CSIN_CIRCLE) THEN CONV_TAC COMPLEX_RING);; + +let CCOS_DOUBLE_CSIN = prove + (`!z. ccos(Cx(&2) * z) = Cx(&1) - Cx(&2) * csin z pow 2`, + GEN_TAC THEN REWRITE_TAC[COMPLEX_RING `Cx(&2) * x = x + x`; CCOS_ADD] THEN + MP_TAC(SPEC `z:complex` CSIN_CIRCLE) THEN CONV_TAC COMPLEX_RING);; + +(* ------------------------------------------------------------------------- *) +(* Euler and de Moivre formulas. *) +(* ------------------------------------------------------------------------- *) + +let CEXP_EULER = prove + (`!z. cexp(ii * z) = ccos(z) + ii * csin(z)`, + REWRITE_TAC[ccos; csin] THEN CONV_TAC COMPLEX_FIELD);; + +let DEMOIVRE = prove + (`!z n. (ccos z + ii * csin z) pow n = + ccos(Cx(&n) * z) + ii * csin(Cx(&n) * z)`, + REWRITE_TAC[GSYM CEXP_EULER; GSYM CEXP_N] THEN + REWRITE_TAC[COMPLEX_MUL_AC]);; + +(* ------------------------------------------------------------------------- *) +(* Real exponential function. Same names as old Library/transc.ml. *) +(* ------------------------------------------------------------------------- *) + +let exp = new_definition `exp(x) = Re(cexp(Cx x))`;; + +let CNJ_CEXP = prove + (`!z. cnj(cexp z) = cexp(cnj z)`, + GEN_TAC THEN MATCH_MP_TAC SERIES_UNIQUE THEN + MAP_EVERY EXISTS_TAC [`\n. cnj(z pow n / Cx(&(FACT n)))`; `from 0`] THEN + CONJ_TAC THENL + [REWRITE_TAC[SUMS_CNJ; CEXP_CONVERGES]; + REWRITE_TAC[CNJ_DIV; CNJ_CX; CNJ_POW; CEXP_CONVERGES]]);; + +let REAL_EXP = prove + (`!z. real z ==> real(cexp z)`, + SIMP_TAC[REAL_CNJ; CNJ_CEXP]);; + +let CX_EXP = prove + (`!x. Cx(exp x) = cexp(Cx x)`, + REWRITE_TAC[exp] THEN MESON_TAC[REAL; REAL_CX; REAL_EXP]);; + +let REAL_EXP_ADD = prove + (`!x y. exp(x + y) = exp(x) * exp(y)`, + REWRITE_TAC[GSYM CX_INJ; CX_MUL; CX_EXP; CX_ADD; CEXP_ADD]);; + +let REAL_EXP_0 = prove + (`exp(&0) = &1`, + REWRITE_TAC[GSYM CX_INJ; CX_EXP; CEXP_0]);; + +let REAL_EXP_ADD_MUL = prove + (`!x y. exp(x + y) * exp(--x) = exp(y)`, + ONCE_REWRITE_TAC[REAL_ADD_SYM] THEN + REWRITE_TAC[GSYM CX_INJ; CX_MUL; CX_EXP; CX_ADD; CX_NEG; CEXP_ADD_MUL]);; + +let REAL_EXP_NEG_MUL = prove + (`!x. exp(x) * exp(--x) = &1`, + REWRITE_TAC[GSYM CX_INJ; CX_MUL; CX_EXP; CX_NEG; CEXP_NEG_RMUL]);; + +let REAL_EXP_NEG_MUL2 = prove + (`!x. exp(--x) * exp(x) = &1`, + REWRITE_TAC[GSYM CX_INJ; CX_MUL; CX_EXP; CX_NEG; CEXP_NEG_LMUL]);; + +let REAL_EXP_NEG = prove + (`!x. exp(--x) = inv(exp(x))`, + REWRITE_TAC[GSYM CX_INJ; CX_INV; CX_EXP; CX_NEG; CEXP_NEG]);; + +let REAL_EXP_N = prove + (`!n x. exp(&n * x) = exp(x) pow n`, + REWRITE_TAC[GSYM CX_INJ; CX_EXP; CX_POW; CX_MUL; CEXP_N]);; + +let REAL_EXP_SUB = prove + (`!x y. exp(x - y) = exp(x) / exp(y)`, + REWRITE_TAC[GSYM CX_INJ; CX_SUB; CX_DIV; CX_EXP; CEXP_SUB]);; + +let REAL_EXP_NZ = prove + (`!x. ~(exp(x) = &0)`, + REWRITE_TAC[GSYM CX_INJ; CX_EXP; CEXP_NZ]);; + +let REAL_EXP_POS_LE = prove + (`!x. &0 <= exp(x)`, + GEN_TAC THEN SUBST1_TAC(REAL_ARITH `x = x / &2 + x / &2`) THEN + REWRITE_TAC[REAL_EXP_ADD; REAL_LE_SQUARE]);; + +let REAL_EXP_POS_LT = prove + (`!x. &0 < exp(x)`, + REWRITE_TAC[REAL_LT_LE; REAL_EXP_NZ; REAL_EXP_POS_LE]);; + +let REAL_EXP_LE_X = prove + (`!x. &0 <= x ==> &1 + x <= exp(x)`, + REPEAT STRIP_TAC THEN REWRITE_TAC[exp; RE_DEF] THEN + MATCH_MP_TAC(MATCH_MP + (ONCE_REWRITE_RULE[TAUT `a /\ b /\ c ==> d <=> b ==> a /\ c ==> d`] + LIM_COMPONENT_LBOUND) + (REWRITE_RULE[sums] (SPEC `Cx x` CEXP_CONVERGES))) THEN + SIMP_TAC[DIMINDEX_2; ARITH; TRIVIAL_LIMIT_SEQUENTIALLY; + VSUM_COMPONENT; EVENTUALLY_SEQUENTIALLY; FROM_0; INTER_UNIV] THEN + REWRITE_TAC[GSYM CX_DIV; GSYM RE_DEF; RE_CX; GSYM CX_POW] THEN + EXISTS_TAC `1` THEN SIMP_TAC[SUM_CLAUSES_LEFT; LE_0; ADD_CLAUSES] THEN + CONV_TAC NUM_REDUCE_CONV THEN + SIMP_TAC[real_pow; REAL_POW_1; REAL_DIV_1; REAL_LE_ADDR; REAL_ADD_ASSOC] THEN + ASM_SIMP_TAC[SUM_POS_LE_NUMSEG; REAL_LE_DIV; REAL_POW_LE; REAL_POS]);; + +let REAL_EXP_LT_1 = prove + (`!x. &0 < x ==> &1 < exp(x)`, + MP_TAC REAL_EXP_LE_X THEN MATCH_MP_TAC MONO_FORALL THEN REAL_ARITH_TAC);; + +let REAL_EXP_MONO_IMP = prove + (`!x y. x < y ==> exp(x) < exp(y)`, + REPEAT GEN_TAC THEN GEN_REWRITE_TAC LAND_CONV [GSYM REAL_SUB_LT] THEN + DISCH_THEN(MP_TAC o MATCH_MP REAL_EXP_LT_1) THEN + SIMP_TAC[REAL_EXP_SUB; REAL_LT_RDIV_EQ; REAL_EXP_POS_LT; REAL_MUL_LID]);; + +let REAL_EXP_MONO_LT = prove + (`!x y. exp(x) < exp(y) <=> x < y`, + REPEAT GEN_TAC THEN MATCH_MP_TAC(REAL_ARITH + `(x < y ==> f < g) /\ (x = y ==> f = g) /\ (y < x ==> g < f) + ==> (f < g <=> x < y)`) THEN + SIMP_TAC[REAL_EXP_MONO_IMP]);; + +let REAL_EXP_MONO_LE = prove + (`!x y. exp(x) <= exp(y) <=> x <= y`, + REWRITE_TAC[GSYM REAL_NOT_LT; REAL_EXP_MONO_LT]);; + +let REAL_EXP_INJ = prove + (`!x y. (exp(x) = exp(y)) <=> (x = y)`, + REWRITE_TAC[GSYM REAL_LE_ANTISYM; REAL_EXP_MONO_LE]);; + +let REAL_EXP_EQ_1 = prove + (`!x. exp(x) = &1 <=> x = &0`, + ONCE_REWRITE_TAC[GSYM REAL_EXP_0] THEN REWRITE_TAC[REAL_EXP_INJ]);; + +let REAL_ABS_EXP = prove + (`!x. abs(exp x) = exp x`, + REWRITE_TAC[real_abs; REAL_EXP_POS_LE]);; + +let REAL_EXP_SUM = prove + (`!f s. FINITE s ==> exp(sum s f) = product s (\x. exp(f x))`, + GEN_TAC THEN MATCH_MP_TAC FINITE_INDUCT_STRONG THEN + SIMP_TAC[SUM_CLAUSES; PRODUCT_CLAUSES; REAL_EXP_ADD; REAL_EXP_0]);; + +let REAL_EXP_BOUND_LEMMA = prove + (`!x. &0 <= x /\ x <= inv(&2) ==> exp(x) <= &1 + &2 * x`, + REPEAT STRIP_TAC THEN MP_TAC(SPEC `Cx x` CEXP_BOUND_LEMMA) THEN + REWRITE_TAC[GSYM CX_EXP; COMPLEX_NORM_CX; RE_CX] THEN + ASM_REAL_ARITH_TAC);; + +(* ------------------------------------------------------------------------- *) +(* Real trig functions, their reality, derivatives of complex versions. *) +(* ------------------------------------------------------------------------- *) + +let sin = new_definition `sin(x) = Re(csin(Cx x))`;; + +let cos = new_definition `cos(x) = Re(ccos(Cx x))`;; + +let CNJ_CSIN = prove + (`!z. cnj(csin z) = csin(cnj z)`, + REWRITE_TAC[csin; CNJ_DIV; CNJ_SUB; CNJ_MUL; CNJ_CX; CNJ_CEXP; + CNJ_NEG; CNJ_II; COMPLEX_NEG_NEG] THEN + CONV_TAC COMPLEX_FIELD);; + +let CNJ_CCOS = prove + (`!z. cnj(ccos z) = ccos(cnj z)`, + REWRITE_TAC[ccos; CNJ_DIV; CNJ_ADD; CNJ_MUL; CNJ_CX; CNJ_CEXP; + CNJ_NEG; CNJ_II; COMPLEX_NEG_NEG; COMPLEX_ADD_AC]);; + +let REAL_SIN = prove + (`!z. real z ==> real(csin z)`, + SIMP_TAC[REAL_CNJ; CNJ_CSIN]);; + +let REAL_COS = prove + (`!z. real z ==> real(ccos z)`, + SIMP_TAC[REAL_CNJ; CNJ_CCOS]);; + +let CX_SIN = prove + (`!x. Cx(sin x) = csin(Cx x)`, + REWRITE_TAC[sin] THEN MESON_TAC[REAL; REAL_CX; REAL_SIN]);; + +let CX_COS = prove + (`!x. Cx(cos x) = ccos(Cx x)`, + REWRITE_TAC[cos] THEN MESON_TAC[REAL; REAL_CX; REAL_COS]);; + +let HAS_COMPLEX_DERIVATIVE_CSIN = prove + (`!z. (csin has_complex_derivative ccos z) (at z)`, + GEN_TAC THEN GEN_REWRITE_TAC (RATOR_CONV o LAND_CONV) [GSYM ETA_AX] THEN + REWRITE_TAC[csin; ccos] THEN COMPLEX_DIFF_TAC THEN + CONV_TAC COMPLEX_FIELD);; + +let COMPLEX_DIFFERENTIABLE_AT_CSIN = prove + (`!z. csin complex_differentiable at z`, + REWRITE_TAC[complex_differentiable] THEN + MESON_TAC[HAS_COMPLEX_DERIVATIVE_CSIN]);; + +let COMPLEX_DIFFERENTIABLE_WITHIN_CSIN = prove + (`!s z. csin complex_differentiable (at z within s)`, + MESON_TAC[COMPLEX_DIFFERENTIABLE_AT_WITHIN; + COMPLEX_DIFFERENTIABLE_AT_CSIN]);; + +add_complex_differentiation_theorems + (CONJUNCTS(REWRITE_RULE[FORALL_AND_THM] + (MATCH_MP HAS_COMPLEX_DERIVATIVE_CHAIN_UNIV + HAS_COMPLEX_DERIVATIVE_CSIN)));; + +let HAS_COMPLEX_DERIVATIVE_CCOS = prove + (`!z. (ccos has_complex_derivative --csin z) (at z)`, + GEN_TAC THEN GEN_REWRITE_TAC (RATOR_CONV o LAND_CONV) [GSYM ETA_AX] THEN + REWRITE_TAC[csin; ccos] THEN COMPLEX_DIFF_TAC THEN + CONV_TAC COMPLEX_FIELD);; + +let COMPLEX_DIFFERENTIABLE_AT_CCOS = prove + (`!z. ccos complex_differentiable at z`, + REWRITE_TAC[complex_differentiable] THEN + MESON_TAC[HAS_COMPLEX_DERIVATIVE_CCOS]);; + +let COMPLEX_DIFFERENTIABLE_WITHIN_CCOS = prove + (`!s z. ccos complex_differentiable (at z within s)`, + MESON_TAC[COMPLEX_DIFFERENTIABLE_AT_WITHIN; + COMPLEX_DIFFERENTIABLE_AT_CCOS]);; + +add_complex_differentiation_theorems + (CONJUNCTS(REWRITE_RULE[FORALL_AND_THM] + (MATCH_MP HAS_COMPLEX_DERIVATIVE_CHAIN_UNIV + HAS_COMPLEX_DERIVATIVE_CCOS)));; + +let CONTINUOUS_AT_CSIN = prove + (`!z. csin continuous at z`, + MESON_TAC[HAS_COMPLEX_DERIVATIVE_CSIN; + HAS_COMPLEX_DERIVATIVE_IMP_CONTINUOUS_AT]);; + +let CONTINUOUS_WITHIN_CSIN = prove + (`!s z. csin continuous (at z within s)`, + MESON_TAC[CONTINUOUS_AT_WITHIN; CONTINUOUS_AT_CSIN]);; + +let CONTINUOUS_ON_CSIN = prove + (`!s. csin continuous_on s`, + MESON_TAC[CONTINUOUS_AT_IMP_CONTINUOUS_ON; CONTINUOUS_AT_CSIN]);; + +let HOLOMORPHIC_ON_CSIN = prove + (`!s. csin holomorphic_on s`, + REWRITE_TAC [holomorphic_on] THEN + MESON_TAC [HAS_COMPLEX_DERIVATIVE_AT_WITHIN; HAS_COMPLEX_DERIVATIVE_CSIN]);; + +let CONTINUOUS_AT_CCOS = prove + (`!z. ccos continuous at z`, + MESON_TAC[HAS_COMPLEX_DERIVATIVE_CCOS; + HAS_COMPLEX_DERIVATIVE_IMP_CONTINUOUS_AT]);; + +let CONTINUOUS_WITHIN_CCOS = prove + (`!s z. ccos continuous (at z within s)`, + MESON_TAC[CONTINUOUS_AT_WITHIN; CONTINUOUS_AT_CCOS]);; + +let CONTINUOUS_ON_CCOS = prove + (`!s. ccos continuous_on s`, + MESON_TAC[CONTINUOUS_AT_IMP_CONTINUOUS_ON; CONTINUOUS_AT_CCOS]);; + +let HOLOMORPHIC_ON_CCOS = prove + (`!s. ccos holomorphic_on s`, + REWRITE_TAC [holomorphic_on] THEN + MESON_TAC [HAS_COMPLEX_DERIVATIVE_AT_WITHIN; HAS_COMPLEX_DERIVATIVE_CCOS]);; + +(* ------------------------------------------------------------------------- *) +(* Slew of theorems for compatibility with old transc.ml file. *) +(* ------------------------------------------------------------------------- *) + +let SIN_0 = prove + (`sin(&0) = &0`, + REWRITE_TAC[GSYM CX_INJ; CX_SIN; CSIN_0]);; + +let COS_0 = prove + (`cos(&0) = &1`, + REWRITE_TAC[GSYM CX_INJ; CX_COS; CCOS_0]);; + +let SIN_CIRCLE = prove + (`!x. (sin(x) pow 2) + (cos(x) pow 2) = &1`, + REWRITE_TAC[GSYM CX_INJ; CX_COS; CX_SIN; CX_ADD; CX_POW; CSIN_CIRCLE]);; + +let SIN_ADD = prove + (`!x y. sin(x + y) = sin(x) * cos(y) + cos(x) * sin(y)`, + REWRITE_TAC[GSYM CX_INJ; CX_COS; CX_SIN; CX_ADD; CX_MUL; CSIN_ADD]);; + +let COS_ADD = prove + (`!x y. cos(x + y) = cos(x) * cos(y) - sin(x) * sin(y)`, + REWRITE_TAC[GSYM CX_INJ; CX_COS; CX_SIN; CX_ADD; CX_SUB; CX_MUL; CCOS_ADD]);; + +let SIN_NEG = prove + (`!x. sin(--x) = --(sin(x))`, + REWRITE_TAC[GSYM CX_INJ; CX_SIN; CX_NEG; CSIN_NEG]);; + +let COS_NEG = prove + (`!x. cos(--x) = cos(x)`, + REWRITE_TAC[GSYM CX_INJ; CX_COS; CX_NEG; CCOS_NEG]);; + +let SIN_DOUBLE = prove + (`!x. sin(&2 * x) = &2 * sin(x) * cos(x)`, + REWRITE_TAC[GSYM CX_INJ; CX_SIN; CX_COS; CX_MUL; CSIN_DOUBLE]);; + +let COS_DOUBLE = prove + (`!x. cos(&2 * x) = (cos(x) pow 2) - (sin(x) pow 2)`, + SIMP_TAC[GSYM CX_INJ; CX_SIN; CX_COS; CX_SUB; CX_MUL; CX_POW; CCOS_DOUBLE]);; + +let COS_DOUBLE_COS = prove + (`!x. cos(&2 * x) = &2 * cos(x) pow 2 - &1`, + MP_TAC SIN_CIRCLE THEN MATCH_MP_TAC MONO_FORALL THEN + REWRITE_TAC[COS_DOUBLE] THEN REAL_ARITH_TAC);; + +let (SIN_BOUND,COS_BOUND) = (CONJ_PAIR o prove) + (`(!x. abs(sin x) <= &1) /\ (!x. abs(cos x) <= &1)`, + CONJ_TAC THEN GEN_TAC THEN ONCE_REWRITE_TAC[GSYM REAL_ABS_NUM] THEN + ONCE_REWRITE_TAC[REAL_LE_SQUARE_ABS] THEN + MP_TAC(SPEC `x:real` SIN_CIRCLE) THEN + MAP_EVERY (MP_TAC o C SPEC REAL_LE_SQUARE) [`sin x`; `cos x`] THEN + REAL_ARITH_TAC);; + +let SIN_BOUNDS = prove + (`!x. --(&1) <= sin(x) /\ sin(x) <= &1`, + MP_TAC SIN_BOUND THEN MATCH_MP_TAC MONO_FORALL THEN REAL_ARITH_TAC);; + +let COS_BOUNDS = prove + (`!x. --(&1) <= cos(x) /\ cos(x) <= &1`, + MP_TAC COS_BOUND THEN MATCH_MP_TAC MONO_FORALL THEN REAL_ARITH_TAC);; + +let COS_ABS = prove + (`!x. cos(abs x) = cos(x)`, + REWRITE_TAC[real_abs] THEN MESON_TAC[COS_NEG]);; + +let SIN_SUB = prove + (`!w z. sin(w - z) = sin(w) * cos(z) - cos(w) * sin(z)`, + REWRITE_TAC[GSYM CX_INJ; CX_SIN; CX_COS; CX_SUB; CX_MUL; CSIN_SUB]);; + +let COS_SUB = prove + (`!w z. cos(w - z) = cos(w) * cos(z) + sin(w) * sin(z)`, + REWRITE_TAC[GSYM CX_INJ; CX_SIN; CX_COS; CX_SUB; CX_ADD; CX_MUL; CCOS_SUB]);; + +let REAL_MUL_SIN_SIN = prove + (`!x y. sin(x) * sin(y) = (cos(x - y) - cos(x + y)) / &2`, + REWRITE_TAC[GSYM CX_INJ; CX_COS; CX_SIN; CX_ADD; CX_SUB; CX_MUL; CX_DIV] THEN + REWRITE_TAC[COMPLEX_MUL_CSIN_CSIN]);; + +let REAL_MUL_SIN_COS = prove + (`!x y. sin(x) * cos(y) = (sin(x + y) + sin(x - y)) / &2`, + REWRITE_TAC[GSYM CX_INJ; CX_COS; CX_SIN; CX_ADD; CX_SUB; CX_MUL; CX_DIV] THEN + REWRITE_TAC[COMPLEX_MUL_CSIN_CCOS]);; + +let REAL_MUL_COS_SIN = prove + (`!x y. cos(x) * sin(y) = (sin(x + y) - sin(x - y)) / &2`, + REWRITE_TAC[GSYM CX_INJ; CX_COS; CX_SIN; CX_ADD; CX_SUB; CX_MUL; CX_DIV] THEN + REWRITE_TAC[COMPLEX_MUL_CCOS_CSIN]);; + +let REAL_MUL_COS_COS = prove + (`!x y. cos(x) * cos(y) = (cos(x - y) + cos(x + y)) / &2`, + REWRITE_TAC[GSYM CX_INJ; CX_COS; CX_SIN; CX_ADD; CX_SUB; CX_MUL; CX_DIV] THEN + REWRITE_TAC[COMPLEX_MUL_CCOS_CCOS]);; + +let REAL_ADD_SIN = prove + (`!x y. sin(x) + sin(y) = &2 * sin((x + y) / &2) * cos((x - y) / &2)`, + REWRITE_TAC[GSYM CX_INJ; CX_COS; CX_SIN; CX_ADD; CX_SUB; CX_MUL; CX_DIV] THEN + REWRITE_TAC[COMPLEX_ADD_CSIN]);; + +let REAL_SUB_SIN = prove + (`!x y. sin(x) - sin(y) = &2 * sin((x - y) / &2) * cos((x + y) / &2)`, + REWRITE_TAC[GSYM CX_INJ; CX_COS; CX_SIN; CX_ADD; CX_SUB; CX_MUL; CX_DIV] THEN + REWRITE_TAC[COMPLEX_SUB_CSIN]);; + +let REAL_ADD_COS = prove + (`!x y. cos(x) + cos(y) = &2 * cos((x + y) / &2) * cos((x - y) / &2)`, + REWRITE_TAC[GSYM CX_INJ; CX_COS; CX_SIN; CX_ADD; CX_SUB; CX_MUL; CX_DIV] THEN + REWRITE_TAC[COMPLEX_ADD_CCOS]);; + +let REAL_SUB_COS = prove + (`!x y. cos(x) - cos(y) = &2 * sin((x + y) / &2) * sin((y - x) / &2)`, + REWRITE_TAC[GSYM CX_INJ; CX_COS; CX_SIN; CX_ADD; CX_SUB; CX_MUL; CX_DIV] THEN + REWRITE_TAC[COMPLEX_SUB_CCOS]);; + +let COS_DOUBLE_SIN = prove + (`!x. cos(&2 * x) = &1 - &2 * sin x pow 2`, + GEN_TAC THEN REWRITE_TAC[REAL_RING `&2 * x = x + x`; COS_ADD] THEN + MP_TAC(SPEC `x:real` SIN_CIRCLE) THEN CONV_TAC REAL_RING);; + +(* ------------------------------------------------------------------------- *) +(* Get a nice real/imaginary separation in Euler's formula. *) +(* ------------------------------------------------------------------------- *) + +let EULER = prove + (`!z. cexp(z) = Cx(exp(Re z)) * (Cx(cos(Im z)) + ii * Cx(sin(Im z)))`, + GEN_TAC THEN GEN_REWRITE_TAC (LAND_CONV o RAND_CONV) [COMPLEX_EXPAND] THEN + REWRITE_TAC[CEXP_ADD; CEXP_EULER; GSYM CX_SIN; GSYM CX_COS; GSYM CX_EXP]);; + +let RE_CEXP = prove + (`!z. Re(cexp z) = exp(Re z) * cos(Im z)`, + REWRITE_TAC[EULER; RE_ADD; RE_MUL_CX; RE_MUL_II; IM_CX; RE_CX] THEN + REAL_ARITH_TAC);; + +let IM_CEXP = prove + (`!z. Im(cexp z) = exp(Re z) * sin(Im z)`, + REWRITE_TAC[EULER; IM_ADD; IM_MUL_CX; IM_MUL_II; IM_CX; RE_CX] THEN + REAL_ARITH_TAC);; + +let RE_CSIN = prove + (`!z. Re(csin z) = (exp(Im z) + exp(--(Im z))) / &2 * sin(Re z)`, + GEN_TAC THEN REWRITE_TAC[csin] THEN + SIMP_TAC[COMPLEX_FIELD `x / (Cx(&2) * ii) = ii * --(x / Cx(&2))`] THEN + REWRITE_TAC[IM_MUL_II; IM_DIV_CX; RE_NEG; IM_SUB; IM_CEXP; + RE_MUL_II; COMPLEX_MUL_LNEG; IM_NEG] THEN + REWRITE_TAC[REAL_NEG_NEG; SIN_NEG] THEN CONV_TAC REAL_RING);; + +let IM_CSIN = prove + (`!z. Im(csin z) = (exp(Im z) - exp(--(Im z))) / &2 * cos(Re z)`, + GEN_TAC THEN REWRITE_TAC[csin] THEN + SIMP_TAC[COMPLEX_FIELD `x / (Cx(&2) * ii) = ii * --(x / Cx(&2))`] THEN + REWRITE_TAC[IM_MUL_II; RE_DIV_CX; RE_NEG; RE_SUB; RE_CEXP; + RE_MUL_II; COMPLEX_MUL_LNEG; IM_NEG] THEN + REWRITE_TAC[REAL_NEG_NEG; COS_NEG] THEN CONV_TAC REAL_RING);; + +let RE_CCOS = prove + (`!z. Re(ccos z) = (exp(Im z) + exp(--(Im z))) / &2 * cos(Re z)`, + GEN_TAC THEN REWRITE_TAC[ccos] THEN + REWRITE_TAC[RE_DIV_CX; RE_ADD; RE_CEXP; COMPLEX_MUL_LNEG; + RE_MUL_II; IM_MUL_II; RE_NEG; IM_NEG; COS_NEG] THEN + REWRITE_TAC[REAL_NEG_NEG] THEN CONV_TAC REAL_RING);; + +let IM_CCOS = prove + (`!z. Im(ccos z) = (exp(--(Im z)) - exp(Im z)) / &2 * sin(Re z)`, + GEN_TAC THEN REWRITE_TAC[ccos] THEN + REWRITE_TAC[IM_DIV_CX; IM_ADD; IM_CEXP; COMPLEX_MUL_LNEG; + RE_MUL_II; IM_MUL_II; RE_NEG; IM_NEG; SIN_NEG] THEN + REWRITE_TAC[REAL_NEG_NEG] THEN CONV_TAC REAL_RING);; + +(* ------------------------------------------------------------------------- *) +(* Some special intermediate value theorems over the reals. *) +(* ------------------------------------------------------------------------- *) + +let IVT_INCREASING_RE = prove + (`!f a b y. + a <= b /\ + (!x. a <= x /\ x <= b ==> f continuous at (Cx x)) /\ + Re(f(Cx a)) <= y /\ y <= Re(f(Cx b)) + ==> ?x. a <= x /\ x <= b /\ Re(f(Cx x)) = y`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`(f:complex->complex) o Cx o drop`; + `lift a`; `lift b`; `y:real`; `1`] + IVT_INCREASING_COMPONENT_1) THEN + REWRITE_TAC[EXISTS_DROP; GSYM drop; LIFT_DROP; o_THM; GSYM RE_DEF] THEN + ASM_REWRITE_TAC[IN_INTERVAL_1; GSYM CONJ_ASSOC; LIFT_DROP] THEN + DISCH_THEN MATCH_MP_TAC THEN REWRITE_TAC[DIMINDEX_2; ARITH] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC CONTINUOUS_AT_COMPOSE THEN + ASM_SIMP_TAC[o_THM] THEN REWRITE_TAC[continuous_at; o_THM] THEN + REWRITE_TAC[dist; GSYM CX_SUB; GSYM DROP_SUB; COMPLEX_NORM_CX] THEN + REWRITE_TAC[GSYM ABS_DROP] THEN MESON_TAC[]);; + +let IVT_DECREASING_RE = prove + (`!f a b y. + a <= b /\ + (!x. a <= x /\ x <= b ==> f continuous at (Cx x)) /\ + Re(f(Cx b)) <= y /\ y <= Re(f(Cx a)) + ==> ?x. a <= x /\ x <= b /\ Re(f(Cx x)) = y`, + REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[GSYM REAL_EQ_NEG2] THEN + REWRITE_TAC[GSYM RE_NEG] THEN MATCH_MP_TAC IVT_INCREASING_RE THEN + ASM_SIMP_TAC[CONTINUOUS_NEG; RE_NEG; REAL_LE_NEG2]);; + +let IVT_INCREASING_IM = prove + (`!f a b y. + a <= b /\ + (!x. a <= x /\ x <= b ==> f continuous at (Cx x)) /\ + Im(f(Cx a)) <= y /\ y <= Im(f(Cx b)) + ==> ?x. a <= x /\ x <= b /\ Im(f(Cx x)) = y`, + REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[GSYM REAL_EQ_NEG2] THEN + REWRITE_TAC[SYM(CONJUNCT2(SPEC_ALL RE_MUL_II))] THEN + MATCH_MP_TAC IVT_DECREASING_RE THEN + ASM_SIMP_TAC[CONTINUOUS_COMPLEX_MUL; ETA_AX; CONTINUOUS_CONST] THEN + ASM_REWRITE_TAC[RE_MUL_II; REAL_LE_NEG2]);; + +let IVT_DECREASING_IM = prove + (`!f a b y. + a <= b /\ + (!x. a <= x /\ x <= b ==> f continuous at (Cx x)) /\ + Im(f(Cx b)) <= y /\ y <= Im(f(Cx a)) + ==> ?x. a <= x /\ x <= b /\ Im(f(Cx x)) = y`, + REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[GSYM REAL_EQ_NEG2] THEN + REWRITE_TAC[GSYM IM_NEG] THEN MATCH_MP_TAC IVT_INCREASING_IM THEN + ASM_SIMP_TAC[CONTINUOUS_NEG; IM_NEG; REAL_LE_NEG2]);; + +(* ------------------------------------------------------------------------- *) +(* Some minimal properties of real logs help to define complex logs. *) +(* ------------------------------------------------------------------------- *) + +let log_def = new_definition + `log y = @x. exp(x) = y`;; + +let EXP_LOG = prove + (`!x. &0 < x ==> exp(log x) = x`, + REPEAT STRIP_TAC THEN REWRITE_TAC[log_def] THEN CONV_TAC SELECT_CONV THEN + SUBGOAL_THEN `?y. --inv(x) <= y /\ y <= x /\ Re(cexp(Cx y)) = x` + MP_TAC THENL [ALL_TAC; MESON_TAC[CX_EXP; RE_CX]] THEN + MATCH_MP_TAC IVT_INCREASING_RE THEN + SIMP_TAC[GSYM CX_EXP; RE_CX; CONTINUOUS_AT_CEXP] THEN REPEAT CONJ_TAC THENL + [MATCH_MP_TAC(REAL_ARITH `&0 < x /\ &0 < y ==> --y <= x`) THEN + ASM_SIMP_TAC[REAL_LT_INV_EQ]; + ONCE_REWRITE_TAC[GSYM REAL_INV_INV] THEN MATCH_MP_TAC REAL_LE_INV2 THEN + ASM_REWRITE_TAC[REAL_EXP_NEG; REAL_INV_INV; REAL_LT_INV_EQ]; + ALL_TAC] THEN + MATCH_MP_TAC(REAL_ARITH `&1 + x <= y ==> x <= y`) THEN + ASM_SIMP_TAC[REAL_EXP_LE_X; REAL_LE_INV_EQ; REAL_LT_IMP_LE]);; + +let LOG_EXP = prove + (`!x. log(exp x) = x`, + GEN_TAC THEN ONCE_REWRITE_TAC[GSYM REAL_EXP_INJ] THEN + SIMP_TAC[EXP_LOG; REAL_EXP_POS_LT]);; + +let REAL_EXP_LOG = prove + (`!x. (exp(log x) = x) <=> &0 < x`, + MESON_TAC[EXP_LOG; REAL_EXP_POS_LT]);; + +let LOG_MUL = prove + (`!x y. &0 < x /\ &0 < y ==> (log(x * y) = log(x) + log(y))`, + REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[GSYM REAL_EXP_INJ] THEN + ASM_SIMP_TAC[REAL_EXP_ADD; REAL_LT_MUL; EXP_LOG]);; + +let LOG_INJ = prove + (`!x y. &0 < x /\ &0 < y ==> (log(x) = log(y) <=> x = y)`, + REPEAT STRIP_TAC THEN GEN_REWRITE_TAC LAND_CONV [GSYM REAL_EXP_INJ] THEN + ASM_SIMP_TAC[EXP_LOG]);; + +let LOG_1 = prove + (`log(&1) = &0`, + ONCE_REWRITE_TAC[GSYM REAL_EXP_INJ] THEN + REWRITE_TAC[REAL_EXP_0; REAL_EXP_LOG; REAL_LT_01]);; + +let LOG_INV = prove + (`!x. &0 < x ==> (log(inv x) = --(log x))`, + REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[GSYM REAL_EXP_INJ] THEN + ASM_SIMP_TAC[REAL_EXP_NEG; EXP_LOG; REAL_LT_INV_EQ]);; + +let LOG_DIV = prove + (`!x y. &0 < x /\ &0 < y ==> log(x / y) = log(x) - log(y)`, + SIMP_TAC[real_div; real_sub; LOG_MUL; LOG_INV; REAL_LT_INV_EQ]);; + +let LOG_MONO_LT = prove + (`!x y. &0 < x /\ &0 < y ==> (log(x) < log(y) <=> x < y)`, + REPEAT STRIP_TAC THEN GEN_REWRITE_TAC LAND_CONV [GSYM REAL_EXP_MONO_LT] THEN + ASM_SIMP_TAC[EXP_LOG]);; + +let LOG_MONO_LT_IMP = prove + (`!x y. &0 < x /\ x < y ==> log(x) < log(y)`, + MESON_TAC[LOG_MONO_LT; REAL_LT_TRANS]);; + +let LOG_MONO_LE = prove + (`!x y. &0 < x /\ &0 < y ==> (log(x) <= log(y) <=> x <= y)`, + REPEAT STRIP_TAC THEN GEN_REWRITE_TAC LAND_CONV [GSYM REAL_EXP_MONO_LE] THEN + ASM_SIMP_TAC[EXP_LOG]);; + +let LOG_MONO_LE_IMP = prove + (`!x y. &0 < x /\ x <= y ==> log(x) <= log(y)`, + MESON_TAC[LOG_MONO_LE; REAL_LT_IMP_LE; REAL_LTE_TRANS]);; + +let LOG_POW = prove + (`!n x. &0 < x ==> (log(x pow n) = &n * log(x))`, + REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[GSYM REAL_EXP_INJ] THEN + ASM_SIMP_TAC[REAL_EXP_N; EXP_LOG; REAL_POW_LT]);; + +let LOG_LE = prove + (`!x. &0 <= x ==> log(&1 + x) <= x`, + REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[GSYM REAL_EXP_MONO_LE] THEN + ASM_SIMP_TAC[EXP_LOG; REAL_ARITH `&0 <= x ==> &0 < &1 + x`; REAL_EXP_LE_X]);; + +let LOG_LT_X = prove + (`!x. &0 < x ==> log(x) < x`, + REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[GSYM REAL_EXP_MONO_LT] THEN + ASM_SIMP_TAC[EXP_LOG] THEN MP_TAC(SPEC `x:real` REAL_EXP_LE_X) THEN + POP_ASSUM MP_TAC THEN REAL_ARITH_TAC);; + +let LOG_POS = prove + (`!x. &1 <= x ==> &0 <= log(x)`, + REWRITE_TAC[GSYM LOG_1] THEN + SIMP_TAC[LOG_MONO_LE; ARITH_RULE `&1 <= x ==> &0 < x`; REAL_LT_01]);; + +let LOG_POS_LT = prove + (`!x. &1 < x ==> &0 < log(x)`, + REWRITE_TAC[GSYM LOG_1] THEN + SIMP_TAC[LOG_MONO_LT; ARITH_RULE `&1 < x ==> &0 < x`; REAL_LT_01]);; + +(* ------------------------------------------------------------------------- *) +(* Deduce periodicity just from derivative and zero values. *) +(* ------------------------------------------------------------------------- *) + +let SIN_NEARZERO = prove + (`?x. &0 < x /\ !y. &0 < y /\ y <= x ==> &0 < sin(y)`, + MP_TAC(SPEC `&1 / &2` (CONJUNCT2 + (REWRITE_RULE[has_complex_derivative; HAS_DERIVATIVE_AT_ALT] + (ISPEC `Cx(&0)` HAS_COMPLEX_DERIVATIVE_CSIN)))) THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN + REWRITE_TAC[CSIN_0; COMPLEX_SUB_RZERO; CCOS_0; COMPLEX_MUL_LZERO; + COMPLEX_MUL_LID] THEN + DISCH_THEN(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `d / &2` THEN ASM_REWRITE_TAC[REAL_HALF] THEN + X_GEN_TAC `y:real` THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `Cx y`) THEN + ASM_REWRITE_TAC[GSYM CX_SIN; COMPLEX_NORM_CX; GSYM CX_SUB] THEN + ASM_REAL_ARITH_TAC);; + +let SIN_NONTRIVIAL = prove + (`?x. &0 < x /\ ~(sin x = &0)`, + MESON_TAC[REAL_LE_REFL; REAL_LT_REFL; SIN_NEARZERO]);; + +let COS_NONTRIVIAL = prove + (`?x. &0 < x /\ ~(cos x = &1)`, + MP_TAC SIN_NONTRIVIAL THEN MATCH_MP_TAC MONO_EXISTS THEN + MP_TAC SIN_CIRCLE THEN MATCH_MP_TAC MONO_FORALL THEN + CONV_TAC REAL_FIELD);; + +let COS_DOUBLE_BOUND = prove + (`!x. &0 <= cos x ==> &2 * (&1 - cos x) <= &1 - cos(&2 * x)`, + REWRITE_TAC[COS_DOUBLE_COS] THEN REWRITE_TAC[REAL_ARITH + `&2 * (&1 - a) <= &1 - (&2 * b - &1) <=> b <= &1 * a`] THEN + SIMP_TAC[REAL_POW_2; REAL_LE_RMUL; COS_BOUNDS]);; + +let COS_GOESNEGATIVE_LEMMA = prove + (`!x. cos(x) < &1 ==> ?n. cos(&2 pow n * x) < &0`, + GEN_TAC THEN DISCH_TAC THEN MATCH_MP_TAC(TAUT `(~p ==> p) ==> p`) THEN + REWRITE_TAC[NOT_EXISTS_THM; REAL_NOT_LT] THEN DISCH_TAC THEN + SUBGOAL_THEN `!n. &2 pow n * (&1 - cos x) <= &1 - cos(&2 pow n * x)` + ASSUME_TAC THENL + [INDUCT_TAC THEN REWRITE_TAC[real_pow; REAL_MUL_LID; REAL_LE_REFL] THEN + MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `&2 * (&1 - cos(&2 pow n * x))` THEN + ASM_SIMP_TAC[GSYM REAL_MUL_ASSOC; REAL_LE_LMUL; REAL_POS; COS_DOUBLE_BOUND]; + MP_TAC(ISPEC `&1 / (&1 - cos(x))` REAL_ARCH_POW2) THEN + ASM_SIMP_TAC[REAL_LT_LDIV_EQ; REAL_SUB_LT] THEN + DISCH_THEN(X_CHOOSE_THEN `n:num` MP_TAC) THEN + REPEAT(FIRST_X_ASSUM(MP_TAC o SPEC `n:num`)) THEN REAL_ARITH_TAC]);; + +let COS_GOESNEGATIVE = prove + (`?x. &0 < x /\ cos(x) < &0`, + X_CHOOSE_TAC `x:real` COS_NONTRIVIAL THEN + MP_TAC(SPEC `x:real` COS_GOESNEGATIVE_LEMMA) THEN ANTS_TAC THENL + [MP_TAC(SPEC `x:real` COS_BOUNDS) THEN + ASM_REAL_ARITH_TAC; + ASM_MESON_TAC[REAL_LT_MUL; REAL_POW_LT; REAL_ARITH `&0 < &2`]]);; + +let COS_HASZERO = prove + (`?x. &0 < x /\ cos(x) = &0`, + X_CHOOSE_THEN `z:real` STRIP_ASSUME_TAC COS_GOESNEGATIVE THEN + SUBGOAL_THEN `?x. &0 <= x /\ x <= z /\ Re(ccos(Cx x)) = &0` MP_TAC THENL + [MATCH_MP_TAC IVT_DECREASING_RE THEN + ASM_SIMP_TAC[GSYM CX_COS; RE_CX; REAL_LT_IMP_LE; COS_0; REAL_POS] THEN + MESON_TAC[HAS_COMPLEX_DERIVATIVE_IMP_CONTINUOUS_AT; + HAS_COMPLEX_DERIVATIVE_CCOS]; + MATCH_MP_TAC MONO_EXISTS THEN REWRITE_TAC[GSYM CX_COS; RE_CX] THEN + MESON_TAC[COS_0; REAL_LE_LT; REAL_ARITH `~(&1 = &0)`]]);; + +let SIN_HASZERO = prove + (`?x. &0 < x /\ sin(x) = &0`, + X_CHOOSE_THEN `x:real` STRIP_ASSUME_TAC COS_HASZERO THEN + EXISTS_TAC `&2 * x` THEN ASM_SIMP_TAC[SIN_DOUBLE] THEN + ASM_REAL_ARITH_TAC);; + +let SIN_HASZERO_MINIMAL = prove + (`?p. &0 < p /\ sin p = &0 /\ !x. &0 < x /\ x < p ==> ~(sin x = &0)`, + X_CHOOSE_THEN `e:real` STRIP_ASSUME_TAC SIN_NEARZERO THEN + MP_TAC(ISPECL + [`{z | z IN IMAGE Cx {x | x >= e} /\ csin z IN {Cx(&0)}}`; `Cx(&0)`] + DISTANCE_ATTAINS_INF) THEN + ANTS_TAC THENL + [ALL_TAC; + REWRITE_TAC[IN_ELIM_THM; GSYM CONJ_ASSOC; IMP_CONJ] THEN + REWRITE_TAC[FORALL_IN_IMAGE; EXISTS_IN_IMAGE] THEN + REWRITE_TAC[IN_ELIM_THM; IN_SING; real_ge; GSYM CX_COS; CX_INJ] THEN + REWRITE_TAC[dist; GSYM CX_SUB; GSYM CX_SIN; CX_INJ; COMPLEX_NORM_CX] THEN + MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC THEN + REWRITE_TAC[REAL_ARITH `abs(&0 - x) = abs x`] THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN CONJ_TAC THENL + [ALL_TAC; + X_GEN_TAC `x:real` THEN + REPEAT(FIRST_X_ASSUM(MP_TAC o SPEC `x:real`))] THEN + ASM_REAL_ARITH_TAC] THEN + X_CHOOSE_TAC `a:real` SIN_HASZERO THEN CONJ_TAC THENL + [ALL_TAC; + REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN EXISTS_TAC `Cx a` THEN + ASM_REWRITE_TAC[IN_SING; IN_IMAGE; IN_ELIM_THM; GSYM CX_SIN] THEN + ASM_MESON_TAC[REAL_ARITH `x >= w \/ x <= w`; REAL_LT_REFL]] THEN + MATCH_MP_TAC CONTINUOUS_CLOSED_PREIMAGE THEN + REWRITE_TAC[CONTINUOUS_ON_CSIN; CLOSED_SING] THEN + SUBGOAL_THEN + `IMAGE Cx {x | x >= e} = {z | Im(z) = &0} INTER {z | Re(z) >= e}` + (fun th -> SIMP_TAC[th; CLOSED_INTER; CLOSED_HALFSPACE_IM_EQ; + CLOSED_HALFSPACE_RE_GE]) THEN + REWRITE_TAC[EXTENSION; IN_IMAGE; IN_INTER; IN_ELIM_THM] THEN + REWRITE_TAC[FORALL_COMPLEX; COMPLEX_EQ; RE; IM; RE_CX; IM_CX] THEN + MESON_TAC[]);; + +let pi = new_definition + `pi = @p. &0 < p /\ sin(p) = &0 /\ !x. &0 < x /\ x < p ==> ~(sin(x) = &0)`;; + +let PI_WORKS = prove + (`&0 < pi /\ sin(pi) = &0 /\ !x. &0 < x /\ x < pi ==> ~(sin x = &0)`, + REWRITE_TAC[pi] THEN CONV_TAC SELECT_CONV THEN + REWRITE_TAC[SIN_HASZERO_MINIMAL]);; + +(* ------------------------------------------------------------------------- *) +(* Now more relatively easy consequences. *) +(* ------------------------------------------------------------------------- *) + +let PI_POS = prove + (`&0 < pi`, + REWRITE_TAC[PI_WORKS]);; + +let PI_POS_LE = prove + (`&0 <= pi`, + REWRITE_TAC[REAL_LE_LT; PI_POS]);; + +let PI_NZ = prove + (`~(pi = &0)`, + SIMP_TAC[PI_POS; REAL_LT_IMP_NZ]);; + +let REAL_ABS_PI = prove + (`abs pi = pi`, + REWRITE_TAC[real_abs; PI_POS_LE]);; + +let SIN_PI = prove + (`sin(pi) = &0`, + REWRITE_TAC[PI_WORKS]);; + +let SIN_POS_PI = prove + (`!x. &0 < x /\ x < pi ==> &0 < sin(x)`, + REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[GSYM REAL_NOT_LE] THEN DISCH_TAC THEN + X_CHOOSE_THEN `e:real` STRIP_ASSUME_TAC SIN_NEARZERO THEN + MP_TAC(ISPECL [`csin`; `e:real`; `x:real`; `&0`] IVT_DECREASING_RE) THEN + ASM_SIMP_TAC[NOT_IMP; CONTINUOUS_AT_CSIN; GSYM CX_SIN; RE_CX; SIN_0] THEN + ASM_MESON_TAC[REAL_LE_TOTAL; REAL_LET_ANTISYM; PI_WORKS; REAL_LET_TRANS; + REAL_LTE_TRANS]);; + +let COS_PI2 = prove + (`cos(pi / &2) = &0`, + MP_TAC(SYM(SPEC `pi / &2` SIN_DOUBLE)) THEN + REWRITE_TAC[REAL_HALF; SIN_PI; REAL_ENTIRE; REAL_OF_NUM_EQ; ARITH] THEN + MATCH_MP_TAC(REAL_ARITH `&0 < y ==> y = &0 \/ z = &0 ==> z = &0`) THEN + MATCH_MP_TAC SIN_POS_PI THEN MP_TAC PI_POS THEN REAL_ARITH_TAC);; + +let COS_PI = prove + (`cos(pi) = -- &1`, + ONCE_REWRITE_TAC[REAL_ARITH `pi = &2 * pi / &2`] THEN + REWRITE_TAC[COS_DOUBLE_COS; COS_PI2] THEN REAL_ARITH_TAC);; + +let SIN_PI2 = prove + (`sin(pi / &2) = &1`, + MP_TAC(SPEC `pi / &2` SIN_CIRCLE) THEN + REWRITE_TAC[COS_PI2; REAL_POW_2; REAL_ADD_RID; REAL_MUL_LZERO] THEN + REWRITE_TAC[REAL_RING `x * x = &1 <=> x = &1 \/ x = -- &1`] THEN + MP_TAC(SPEC `pi / &2` SIN_POS_PI) THEN MP_TAC PI_POS THEN REAL_ARITH_TAC);; + +let SIN_COS = prove + (`!x. sin(x) = cos(pi / &2 - x)`, + REWRITE_TAC[COS_SUB; COS_PI2; SIN_PI2] THEN REAL_ARITH_TAC);; + +let COS_SIN = prove + (`!x. cos(x) = sin(pi / &2 - x)`, + REWRITE_TAC[SIN_SUB; COS_PI2; SIN_PI2] THEN REAL_ARITH_TAC);; + +let SIN_PERIODIC_PI = prove + (`!x. sin(x + pi) = --(sin(x))`, + REWRITE_TAC[SIN_ADD; SIN_PI; COS_PI] THEN REAL_ARITH_TAC);; + +let COS_PERIODIC_PI = prove + (`!x. cos(x + pi) = --(cos(x))`, + REWRITE_TAC[COS_ADD; SIN_PI; COS_PI] THEN REAL_ARITH_TAC);; + +let SIN_PERIODIC = prove + (`!x. sin(x + &2 * pi) = sin(x)`, + REWRITE_TAC[REAL_MUL_2; REAL_ADD_ASSOC; SIN_PERIODIC_PI; REAL_NEG_NEG]);; + +let COS_PERIODIC = prove + (`!x. cos(x + &2 * pi) = cos(x)`, + REWRITE_TAC[REAL_MUL_2; REAL_ADD_ASSOC; COS_PERIODIC_PI; REAL_NEG_NEG]);; + +let SIN_NPI = prove + (`!n. sin(&n * pi) = &0`, + INDUCT_TAC THEN + ASM_REWRITE_TAC[GSYM REAL_OF_NUM_SUC; REAL_MUL_LID; REAL_ADD_RDISTRIB; + REAL_NEG_0; SIN_PERIODIC_PI; REAL_MUL_LZERO; SIN_0]);; + +let COS_NPI = prove + (`!n. cos(&n * pi) = --(&1) pow n`, + INDUCT_TAC THEN + ASM_REWRITE_TAC[real_pow; REAL_MUL_LZERO; COS_0; COS_PERIODIC_PI; + REAL_MUL_LID; REAL_MUL_LNEG; GSYM REAL_OF_NUM_SUC; REAL_ADD_RDISTRIB]);; + +let COS_POS_PI2 = prove + (`!x. &0 < x /\ x < pi / &2 ==> &0 < cos(x)`, + REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[GSYM REAL_NOT_LE] THEN DISCH_TAC THEN + MP_TAC(ISPECL [`ccos`; `&0`; `x:real`; `&0`] IVT_DECREASING_RE) THEN + ASM_SIMP_TAC[CONTINUOUS_AT_CCOS; REAL_LT_IMP_LE; GSYM CX_COS; RE_CX] THEN + REWRITE_TAC[COS_0; REAL_POS] THEN DISCH_THEN(X_CHOOSE_TAC `y:real`) THEN + MP_TAC(SPEC `y:real` SIN_DOUBLE) THEN ASM_REWRITE_TAC[REAL_MUL_RZERO] THEN + MATCH_MP_TAC(last(CONJUNCTS PI_WORKS)) THEN REPEAT(POP_ASSUM MP_TAC) THEN + ASM_CASES_TAC `y = &0` THEN ASM_REWRITE_TAC[COS_0] THEN + POP_ASSUM MP_TAC THEN REAL_ARITH_TAC);; + +let SIN_POS_PI2 = prove + (`!x. &0 < x /\ x < pi / &2 ==> &0 < sin(x)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC SIN_POS_PI THEN + ASM_REAL_ARITH_TAC);; + +let COS_POS_PI = prove + (`!x. --(pi / &2) < x /\ x < pi / &2 ==> &0 < cos(x)`, + GEN_TAC THEN MP_TAC(SPEC `abs x` COS_POS_PI2) THEN REWRITE_TAC[COS_ABS] THEN + ASM_CASES_TAC `x = &0` THEN ASM_REWRITE_TAC[COS_0] THEN + POP_ASSUM MP_TAC THEN REAL_ARITH_TAC);; + +let COS_POS_PI_LE = prove + (`!x. --(pi / &2) <= x /\ x <= pi / &2 ==> &0 <= cos(x)`, + REWRITE_TAC[REAL_LE_LT] THEN MESON_TAC[COS_PI2; COS_NEG; COS_POS_PI]);; + +let SIN_POS_PI_LE = prove + (`!x. &0 <= x /\ x <= pi ==> &0 <= sin(x)`, + REWRITE_TAC[REAL_LE_LT] THEN MESON_TAC[SIN_0; SIN_PI; SIN_POS_PI]);; + +let SIN_PIMUL_EQ_0 = prove + (`!n. sin(n * pi) = &0 <=> integer(n)`, + SUBGOAL_THEN `!n. integer n ==> sin(n * pi) = &0 /\ ~(cos(n * pi) = &0)` + ASSUME_TAC THENL + [REWRITE_TAC[INTEGER_CASES] THEN GEN_TAC THEN STRIP_TAC THEN CONJ_TAC THEN + ASM_SIMP_TAC[REAL_MUL_LNEG; COS_NPI; SIN_NPI; + SIN_NEG; COS_NEG; REAL_POW_EQ_0] THEN REAL_ARITH_TAC; + ALL_TAC] THEN + GEN_TAC THEN EQ_TAC THEN ASM_SIMP_TAC[] THEN + SUBST1_TAC(last(CONJUNCTS(SPEC `n:real` FLOOR_FRAC))) THEN + ASM_SIMP_TAC[REAL_ADD_RDISTRIB; FLOOR; SIN_ADD; REAL_MUL_LZERO] THEN + ASM_SIMP_TAC[REAL_ADD_LID; REAL_ENTIRE; FLOOR] THEN + DISCH_TAC THEN MP_TAC(SPEC `frac n * pi` SIN_POS_PI) THEN + ASM_SIMP_TAC[REAL_LT_REFL; GSYM REAL_LT_RDIV_EQ; GSYM REAL_LT_LDIV_EQ; + PI_POS; REAL_DIV_REFL; REAL_LT_IMP_NZ] THEN + MP_TAC(SPEC `n:real` FLOOR_FRAC) THEN ASM_CASES_TAC `frac n = &0` THEN + ASM_REWRITE_TAC[FLOOR; REAL_ADD_RID] THEN + ASM_REAL_ARITH_TAC);; + +let SIN_EQ_0 = prove + (`!x. sin(x) = &0 <=> ?n. integer n /\ x = n * pi`, + GEN_TAC THEN MP_TAC(SPEC `x / pi` SIN_PIMUL_EQ_0) THEN + SIMP_TAC[REAL_DIV_RMUL; REAL_LT_IMP_NZ; GSYM REAL_EQ_LDIV_EQ; PI_POS] THEN + ONCE_REWRITE_TAC[CONJ_SYM] THEN REWRITE_TAC[UNWIND_THM1]);; + +let COS_EQ_0 = prove + (`!x. cos(x) = &0 <=> ?n. integer n /\ x = (n + &1 / &2) * pi`, + GEN_TAC THEN REWRITE_TAC[COS_SIN; SIN_EQ_0] THEN + EQ_TAC THEN DISCH_THEN(X_CHOOSE_THEN `n:real` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `--n:real` THEN ASM_REWRITE_TAC[INTEGER_NEG] THEN + ASM_REAL_ARITH_TAC);; + +let SIN_ZERO_PI = prove + (`!x. sin(x) = &0 <=> (?n. x = &n * pi) \/ (?n. x = --(&n * pi))`, + REWRITE_TAC[SIN_EQ_0; INTEGER_CASES] THEN MESON_TAC[REAL_MUL_LNEG]);; + +let COS_ZERO_PI = prove + (`!x. cos(x) = &0 <=> + (?n. x = (&n + &1 / &2) * pi) \/ (?n. x = --((&n + &1 / &2) * pi))`, + GEN_TAC THEN REWRITE_TAC[COS_EQ_0; INTEGER_CASES; RIGHT_OR_DISTRIB] THEN + REWRITE_TAC[EXISTS_OR_THM; LEFT_AND_EXISTS_THM] THEN + ONCE_REWRITE_TAC[SWAP_EXISTS_THM] THEN SIMP_TAC[UNWIND_THM2] THEN EQ_TAC THEN + DISCH_THEN(DISJ_CASES_THEN (X_CHOOSE_THEN `n:num` SUBST1_TAC)) THENL + [DISJ1_TAC THEN EXISTS_TAC `n:num`; + ASM_CASES_TAC `n = 0` THENL + [DISJ1_TAC THEN EXISTS_TAC `0`; + DISJ2_TAC THEN EXISTS_TAC `n - 1`]; + DISJ1_TAC THEN EXISTS_TAC `n:num`; + DISJ2_TAC THEN EXISTS_TAC `n + 1`] THEN + ASM_SIMP_TAC[GSYM REAL_OF_NUM_SUB; GSYM REAL_OF_NUM_ADD; + ARITH_RULE `1 <= n <=> ~(n = 0)`] THEN + REAL_ARITH_TAC);; + +let SIN_ZERO = prove + (`!x. (sin(x) = &0) <=> (?n. EVEN n /\ x = &n * (pi / &2)) \/ + (?n. EVEN n /\ x = --(&n * (pi / &2)))`, + REWRITE_TAC[SIN_ZERO_PI; EVEN_EXISTS; LEFT_AND_EXISTS_THM] THEN + ONCE_REWRITE_TAC[SWAP_EXISTS_THM] THEN REWRITE_TAC[UNWIND_THM2] THEN + SIMP_TAC[GSYM REAL_OF_NUM_MUL; REAL_ARITH `(&2 * x) * y / &2 = x * y`]);; + +let COS_ZERO = prove + (`!x. cos(x) = &0 <=> (?n. ~EVEN n /\ (x = &n * (pi / &2))) \/ + (?n. ~EVEN n /\ (x = --(&n * (pi / &2))))`, + REWRITE_TAC[COS_ZERO_PI; NOT_EVEN; ODD_EXISTS; LEFT_AND_EXISTS_THM] THEN + ONCE_REWRITE_TAC[SWAP_EXISTS_THM] THEN REWRITE_TAC[UNWIND_THM2] THEN + SIMP_TAC[GSYM REAL_OF_NUM_MUL; GSYM REAL_OF_NUM_SUC; + REAL_ARITH `(&2 * x + &1) * y / &2 = (x + &1 / &2) * y`]);; + +let COS_ONE_2PI = prove + (`!x. (cos(x) = &1) <=> (?n. x = &n * &2 * pi) \/ (?n. x = --(&n * &2 * pi))`, + GEN_TAC THEN EQ_TAC THEN DISCH_TAC THENL + [FIRST_ASSUM(MP_TAC o SPEC `sin(x)` o MATCH_MP (REAL_RING + `c = &1 ==> !s. s pow 2 + c pow 2 = &1 ==> s = &0`)) THEN + REWRITE_TAC[SIN_ZERO_PI; SIN_CIRCLE] THEN + DISCH_THEN(DISJ_CASES_THEN(X_CHOOSE_THEN `n:num` SUBST_ALL_TAC)) THEN + POP_ASSUM MP_TAC THEN REWRITE_TAC[COS_NEG; COS_NPI; REAL_POW_NEG] THEN + COND_CASES_TAC THEN REWRITE_TAC[REAL_POW_ONE] THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN + FIRST_X_ASSUM(MP_TAC o REWRITE_RULE[EVEN_EXISTS]) THEN + REWRITE_TAC[OR_EXISTS_THM] THEN MATCH_MP_TAC MONO_EXISTS THEN + SIMP_TAC[GSYM REAL_OF_NUM_MUL] THEN REAL_ARITH_TAC; + FIRST_X_ASSUM (DISJ_CASES_THEN CHOOSE_TAC) THEN + ASM_REWRITE_TAC[COS_NEG; REAL_MUL_ASSOC; REAL_OF_NUM_MUL; COS_NPI; + REAL_POW_NEG; EVEN_MULT; ARITH; REAL_POW_ONE]]);; + +let SIN_COS_SQRT = prove + (`!x. &0 <= sin(x) ==> (sin(x) = sqrt(&1 - (cos(x) pow 2)))`, + REPEAT STRIP_TAC THEN CONV_TAC SYM_CONV THEN MATCH_MP_TAC SQRT_UNIQUE THEN + ASM_REWRITE_TAC[SIN_CIRCLE; REAL_EQ_SUB_LADD]);; + +let SIN_EQ_0_PI = prove + (`!x. --pi < x /\ x < pi /\ sin(x) = &0 ==> x = &0`, + GEN_TAC THEN REWRITE_TAC[SIN_EQ_0; CONJ_ASSOC] THEN + DISCH_THEN(CONJUNCTS_THEN2 MP_TAC + (X_CHOOSE_THEN `n:real` STRIP_ASSUME_TAC)) THEN + ASM_REWRITE_TAC[REAL_ARITH + `--p < n * p /\ n * p < p <=> -- &1 * p < n * p /\ n * p < &1 * p`] THEN + SIMP_TAC[REAL_ENTIRE; REAL_LT_IMP_NZ; REAL_LT_RMUL_EQ; PI_POS] THEN + MP_TAC(SPEC `n:real` REAL_ABS_INTEGER_LEMMA) THEN + ASM_REWRITE_TAC[] THEN REAL_ARITH_TAC);; + +let COS_TREBLE_COS = prove + (`!x. cos(&3 * x) = &4 * cos(x) pow 3 - &3 * cos x`, + GEN_TAC THEN REWRITE_TAC[COS_ADD; REAL_ARITH `&3 * x = &2 * x + x`] THEN + REWRITE_TAC[SIN_DOUBLE; COS_DOUBLE_COS] THEN + MP_TAC(SPEC `x:real` SIN_CIRCLE) THEN CONV_TAC REAL_RING);; + +let COS_PI6 = prove + (`cos(pi / &6) = sqrt(&3) / &2`, + MP_TAC(ISPEC `pi / &6` COS_TREBLE_COS) THEN + REWRITE_TAC[REAL_ARITH `&3 * x / &6 = x / &2`; COS_PI2] THEN + REWRITE_TAC[REAL_RING `&0 = &4 * c pow 3 - &3 * c <=> + c = &0 \/ (&2 * c) pow 2 = &3`] THEN + SUBGOAL_THEN `&0 < cos(pi / &6)` ASSUME_TAC THENL + [MATCH_MP_TAC COS_POS_PI THEN MP_TAC PI_POS THEN REAL_ARITH_TAC; + DISCH_THEN(DISJ_CASES_THEN MP_TAC) THENL + [ASM_MESON_TAC[REAL_LT_REFL]; ALL_TAC] THEN + DISCH_THEN(MP_TAC o AP_TERM `sqrt`) THEN + ASM_SIMP_TAC[POW_2_SQRT; REAL_LE_MUL; REAL_LT_IMP_LE; REAL_POS] THEN + REAL_ARITH_TAC]);; + +let SIN_PI6 = prove + (`sin(pi / &6) = &1 / &2`, + MP_TAC(SPEC `pi / &6` SIN_CIRCLE) THEN REWRITE_TAC[COS_PI6] THEN + SIMP_TAC[REAL_POW_DIV; SQRT_POW_2; REAL_POS] THEN MATCH_MP_TAC(REAL_FIELD + `~(s + &1 / &2 = &0) ==> s pow 2 + &3 / &2 pow 2 = &1 ==> s = &1 / &2`) THEN + MATCH_MP_TAC(REAL_ARITH `&0 < x ==> ~(x + &1 / &2 = &0)`) THEN + MATCH_MP_TAC SIN_POS_PI THEN MP_TAC PI_POS THEN REAL_ARITH_TAC);; + +let SIN_POS_PI_REV = prove + (`!x. &0 <= x /\ x <= &2 * pi /\ &0 < sin x ==> &0 < x /\ x < pi`, + GEN_TAC THEN ASM_CASES_TAC `x = &0` THEN + ASM_REWRITE_TAC[SIN_0; REAL_LT_REFL] THEN + ASM_CASES_TAC `x = pi` THEN + ASM_REWRITE_TAC[SIN_PI; REAL_LT_REFL] THEN + ASM_CASES_TAC `x = &2 * pi` THEN + ASM_REWRITE_TAC[SIN_NPI; REAL_LT_REFL] THEN + REPEAT STRIP_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN + REWRITE_TAC[GSYM REAL_NOT_LE] THEN DISCH_TAC THEN + SUBGOAL_THEN `&0 < sin(&2 * pi - x)` MP_TAC THENL + [MATCH_MP_TAC SIN_POS_PI THEN ASM_REAL_ARITH_TAC; + REWRITE_TAC[SIN_SUB; SIN_NPI; COS_NPI] THEN ASM_REAL_ARITH_TAC]);; + +(* ------------------------------------------------------------------------- *) +(* Prove totality of trigs. *) +(* ------------------------------------------------------------------------- *) + +let SIN_TOTAL_POS = prove + (`!y. &0 <= y /\ y <= &1 + ==> ?x. &0 <= x /\ x <= pi / &2 /\ sin(x) = y`, + REPEAT STRIP_TAC THEN + MP_TAC(SPECL [`csin`; `&0`; `pi / &2`; `y:real`] IVT_INCREASING_RE) THEN + ASM_REWRITE_TAC[GSYM CX_SIN; RE_CX; SIN_0; SIN_PI2] THEN + SIMP_TAC[CONTINUOUS_AT_CSIN; PI_POS; REAL_ARITH `&0 < x ==> &0 <= x / &2`]);; + +let SINCOS_TOTAL_PI2 = prove + (`!x y. &0 <= x /\ &0 <= y /\ x pow 2 + y pow 2 = &1 + ==> ?t. &0 <= t /\ t <= pi / &2 /\ x = cos t /\ y = sin t`, + REPEAT STRIP_TAC THEN MP_TAC(SPEC `y:real` SIN_TOTAL_POS) THEN ANTS_TAC THENL + [ASM_REWRITE_TAC[] THEN FIRST_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH + `x pow 2 + y pow 2 = &1 + ==> (&1 < y ==> &1 pow 2 < y pow 2) /\ &0 <= x * x + ==> y <= &1`)) THEN + SIMP_TAC[REAL_LE_SQUARE; REAL_POW_LT2; REAL_POS; ARITH]; + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `t:real` THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + SUBGOAL_THEN `x = cos t \/ x = --(cos t)` MP_TAC THENL + [MP_TAC(SPEC `t:real` SIN_CIRCLE); + MP_TAC(SPEC `t:real` COS_POS_PI_LE)] THEN + REPEAT(POP_ASSUM MP_TAC) THEN CONV_TAC REAL_FIELD]);; + +let SINCOS_TOTAL_PI = prove + (`!x y. &0 <= y /\ x pow 2 + y pow 2 = &1 + ==> ?t. &0 <= t /\ t <= pi /\ x = cos t /\ y = sin t`, + REPEAT STRIP_TAC THEN DISJ_CASES_TAC(REAL_ARITH `&0 <= x \/ &0 <= --x`) THENL + [MP_TAC(SPECL [`x:real`; `y:real`] SINCOS_TOTAL_PI2); + MP_TAC(SPECL [`--x:real`; `y:real`] SINCOS_TOTAL_PI2)] THEN + ASM_REWRITE_TAC[REAL_POW_NEG; ARITH] THEN + DISCH_THEN(X_CHOOSE_THEN `t:real` STRIP_ASSUME_TAC) THENL + [EXISTS_TAC `t:real`; EXISTS_TAC `pi - t`] THEN + ASM_REWRITE_TAC[SIN_SUB; COS_SUB; SIN_PI; COS_PI] THEN + ASM_REAL_ARITH_TAC);; + +let SINCOS_TOTAL_2PI = prove + (`!x y. x pow 2 + y pow 2 = &1 + ==> ?t. &0 <= t /\ t < &2 * pi /\ x = cos t /\ y = sin t`, + REPEAT STRIP_TAC THEN ASM_CASES_TAC `x = &1 /\ y = &0` THENL + [EXISTS_TAC `&0` THEN ASM_REWRITE_TAC[SIN_0; COS_0] THEN + MP_TAC PI_POS THEN REAL_ARITH_TAC; + ALL_TAC] THEN + DISJ_CASES_TAC(REAL_ARITH `&0 <= y \/ &0 <= --y`) THENL + [MP_TAC(SPECL [`x:real`; `y:real`] SINCOS_TOTAL_PI); + MP_TAC(SPECL [`x:real`; `--y:real`] SINCOS_TOTAL_PI)] THEN + ASM_REWRITE_TAC[REAL_POW_NEG; ARITH] THEN + DISCH_THEN(X_CHOOSE_THEN `t:real` STRIP_ASSUME_TAC) THENL + [EXISTS_TAC `t:real`; EXISTS_TAC `&2 * pi - t`] THEN + ASM_REWRITE_TAC[SIN_SUB; COS_SUB; SIN_NPI; COS_NPI] THENL + [MP_TAC PI_POS THEN ASM_REAL_ARITH_TAC; + ALL_TAC] THEN + REPEAT(POP_ASSUM MP_TAC) THEN ASM_CASES_TAC `t = &0` THEN + ASM_REWRITE_TAC[SIN_0; COS_0] THEN POP_ASSUM MP_TAC THEN REAL_ARITH_TAC);; + +let CIRCLE_SINCOS = prove + (`!x y. x pow 2 + y pow 2 = &1 ==> ?t. x = cos(t) /\ y = sin(t)`, + MESON_TAC[SINCOS_TOTAL_2PI]);; + +(* ------------------------------------------------------------------------- *) +(* Polar representation. *) +(* ------------------------------------------------------------------------- *) + +let CX_PI_NZ = prove + (`~(Cx pi = Cx(&0))`, + SIMP_TAC[CX_INJ; REAL_LT_IMP_NZ; PI_POS]);; + +let COMPLEX_UNIMODULAR_POLAR = prove + (`!z. (norm z = &1) ==> ?x. z = complex(cos(x),sin(x))`, + GEN_TAC THEN + DISCH_THEN(MP_TAC o C AP_THM `2` o AP_TERM `(pow):real->num->real`) THEN + REWRITE_TAC[complex_norm] THEN + SIMP_TAC[REAL_POW_2; REWRITE_RULE[REAL_POW_2] SQRT_POW_2; + REAL_LE_SQUARE; REAL_LE_ADD] THEN + REWRITE_TAC[GSYM REAL_POW_2; REAL_MUL_LID] THEN + DISCH_THEN(X_CHOOSE_TAC `t:real` o MATCH_MP CIRCLE_SINCOS) THEN + EXISTS_TAC `t:real` THEN ASM_REWRITE_TAC[COMPLEX_EQ; RE; IM]);; + +let SIN_INTEGER_2PI = prove + (`!n. integer n ==> sin((&2 * pi) * n) = &0`, + REWRITE_TAC[SIN_EQ_0; REAL_ARITH `(&2 * pi) * n = (&2 * n) * pi`] THEN + MESON_TAC[INTEGER_CLOSED]);; + +let SIN_INTEGER_PI = prove + (`!n. integer n ==> sin (n * pi) = &0`, + REWRITE_TAC[INTEGER_CASES] THEN REPEAT STRIP_TAC THEN + ASM_REWRITE_TAC[REAL_MUL_LNEG; SIN_NPI; SIN_NEG; REAL_NEG_0]);; + +let COS_INTEGER_2PI = prove + (`!n. integer n ==> cos((&2 * pi) * n) = &1`, + REWRITE_TAC[INTEGER_CASES; REAL_ARITH `(&2 * pi) * n = (&2 * n) * pi`] THEN + REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[REAL_MUL_RNEG; REAL_OF_NUM_MUL] THEN + SIMP_TAC[COS_NEG; COS_NPI; REAL_POW_NEG; REAL_MUL_LNEG; + ARITH; EVEN_MULT; REAL_POW_ONE]);; + +let SINCOS_PRINCIPAL_VALUE = prove + (`!x. ?y. (--pi < y /\ y <= pi) /\ (sin(y) = sin(x) /\ cos(y) = cos(x))`, + GEN_TAC THEN EXISTS_TAC `pi - (&2 * pi) * frac((pi - x) / (&2 * pi))` THEN + CONJ_TAC THENL + [SIMP_TAC[REAL_ARITH `--p < p - x <=> x < (&2 * p) * &1`; + REAL_ARITH `p - x <= p <=> (&2 * p) * &0 <= x`; + REAL_LT_LMUL_EQ; REAL_LE_LMUL_EQ; REAL_LT_MUL; + PI_POS; REAL_OF_NUM_LT; ARITH; FLOOR_FRAC]; + REWRITE_TAC[FRAC_FLOOR; REAL_SUB_LDISTRIB] THEN + SIMP_TAC[REAL_DIV_LMUL; REAL_ENTIRE; REAL_OF_NUM_EQ; ARITH; REAL_LT_IMP_NZ; + PI_POS; REAL_ARITH `a - (a - b - c):real = b + c`; SIN_ADD; COS_ADD] THEN + SIMP_TAC[FLOOR_FRAC; SIN_INTEGER_2PI; COS_INTEGER_2PI] THEN + CONV_TAC REAL_RING]);; + +let CEXP_COMPLEX = prove + (`!r t. cexp(complex(r,t)) = Cx(exp r) * complex(cos t,sin t)`, + REPEAT GEN_TAC THEN + GEN_REWRITE_TAC (LAND_CONV o RAND_CONV) [COMPLEX_EXPAND] THEN + REWRITE_TAC[RE; IM; CEXP_ADD; CEXP_EULER; CX_EXP] THEN + REWRITE_TAC[COMPLEX_TRAD; CX_SIN; CX_COS]);; + +let NORM_COSSIN = prove + (`!t. norm(complex(cos t,sin t)) = &1`, + REWRITE_TAC[complex_norm; RE; IM] THEN ONCE_REWRITE_TAC[REAL_ADD_SYM] THEN + REWRITE_TAC[SIN_CIRCLE; SQRT_1]);; + +let NORM_CEXP = prove + (`!z. norm(cexp z) = exp(Re z)`, + REWRITE_TAC[FORALL_COMPLEX; CEXP_COMPLEX; COMPLEX_NORM_MUL] THEN + REWRITE_TAC[NORM_COSSIN; RE; COMPLEX_NORM_CX] THEN + MP_TAC REAL_EXP_POS_LT THEN MATCH_MP_TAC MONO_FORALL THEN REAL_ARITH_TAC);; + +let NORM_CEXP_II = prove + (`!t. norm (cexp (ii * Cx t)) = &1`, + REWRITE_TAC [NORM_CEXP; RE_MUL_II; IM_CX; REAL_NEG_0; REAL_EXP_0]);; + +let NORM_CEXP_IMAGINARY = prove + (`!z. norm(cexp z) = &1 ==> Re(z) = &0`, + REWRITE_TAC[NORM_CEXP; REAL_EXP_EQ_1]);; + +let CEXP_EQ_1 = prove + (`!z. cexp z = Cx(&1) <=> Re(z) = &0 /\ ?n. integer n /\ Im(z) = &2 * n * pi`, + REWRITE_TAC[FORALL_COMPLEX; CEXP_COMPLEX; RE; IM] THEN + MAP_EVERY X_GEN_TAC [`x:real`; `y:real`] THEN EQ_TAC THENL + [DISCH_TAC THEN FIRST_ASSUM(MP_TAC o AP_TERM `norm:complex->real`) THEN + SIMP_TAC[COMPLEX_NORM_MUL; CX_EXP; NORM_CEXP; RE_CX; COMPLEX_NORM_CX] THEN + REWRITE_TAC[NORM_COSSIN; REAL_ABS_NUM; REAL_ABS_EXP; REAL_MUL_RID] THEN + REWRITE_TAC[REAL_EXP_EQ_1] THEN DISCH_THEN SUBST_ALL_TAC THEN + POP_ASSUM MP_TAC THEN REWRITE_TAC[REAL_EXP_0; COMPLEX_MUL_LID] THEN + REWRITE_TAC[COMPLEX_EQ; RE; IM; RE_CX; IM_CX] THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [SIN_EQ_0]) THEN + DISCH_THEN(X_CHOOSE_THEN `m:real` + (CONJUNCTS_THEN2 ASSUME_TAC SUBST_ALL_TAC)) THEN + EXISTS_TAC `m / &2` THEN CONJ_TAC THENL [ALL_TAC; REAL_ARITH_TAC] THEN + ONCE_REWRITE_TAC[GSYM INTEGER_ABS] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE LAND_CONV [GSYM COS_ABS]) THEN + REWRITE_TAC[REAL_ABS_MUL; REAL_ABS_DIV; REAL_ABS_NUM] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [integer]) THEN + DISCH_THEN(X_CHOOSE_THEN `n:num` SUBST_ALL_TAC) THEN + SIMP_TAC[real_abs; PI_POS; REAL_LT_IMP_LE; COS_NPI] THEN + REWRITE_TAC[REAL_POW_NEG; REAL_POW_ONE] THEN + COND_CASES_TAC THEN CONV_TAC REAL_RAT_REDUCE_CONV THEN + FIRST_X_ASSUM(CHOOSE_THEN SUBST1_TAC o REWRITE_RULE[EVEN_EXISTS]) THEN + REWRITE_TAC[GSYM REAL_OF_NUM_MUL; REAL_ARITH `(&2 * x) / &2 = x`] THEN + REWRITE_TAC[INTEGER_CLOSED]; + DISCH_THEN(CONJUNCTS_THEN2 SUBST1_TAC (X_CHOOSE_TAC `n:real`)) THEN + ASM_SIMP_TAC[REAL_EXP_0; COMPLEX_MUL_LID] THEN + ONCE_REWRITE_TAC[REAL_ARITH `&2 * x * y = (&2 * y) * x`] THEN + ASM_SIMP_TAC[SIN_INTEGER_2PI; COS_INTEGER_2PI] THEN + SIMPLE_COMPLEX_ARITH_TAC]);; + +let CEXP_EQ = prove + (`!w z. cexp w = cexp z <=> ?n. integer n /\ w = z + Cx(&2 * n * pi) * ii`, + SIMP_TAC[CEXP_NZ; COMPLEX_FIELD + `~(z = Cx(&0)) ==> (w = z <=> w / z = Cx(&1))`] THEN + REWRITE_TAC[GSYM CEXP_SUB; CEXP_EQ_1; RE_SUB; IM_SUB; REAL_SUB_0] THEN + SIMP_TAC[COMPLEX_EQ; RE_ADD; IM_ADD; RE_MUL_II; IM_MUL_II; RE_CX; IM_CX] THEN + REWRITE_TAC[REAL_NEG_0; REAL_ADD_RID; REAL_EQ_SUB_RADD] THEN + MESON_TAC[REAL_ADD_SYM]);; + +let COMPLEX_EQ_CEXP = prove + (`!w z. abs(Im w - Im z) < &2 * pi /\ cexp w = cexp z ==> w = z`, + SIMP_TAC[CEXP_NZ; GSYM CEXP_SUB; CEXP_EQ_1; COMPLEX_FIELD + `~(a = Cx(&0)) /\ ~(b = Cx(&0)) ==> (a = b <=> a / b = Cx(&1))`] THEN + REPEAT GEN_TAC THEN DISCH_THEN(REPEAT_TCL CONJUNCTS_THEN ASSUME_TAC) THEN + FIRST_X_ASSUM(X_CHOOSE_THEN `n:real` STRIP_ASSUME_TAC) THEN + UNDISCH_TAC `abs(Im w - Im z) < &2 * pi` THEN + ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN DISCH_TAC THEN + ASM_REWRITE_TAC[GSYM IM_SUB; REAL_ABS_MUL; REAL_ABS_PI; REAL_ABS_NUM] THEN + SIMP_TAC[REAL_MUL_ASSOC; REAL_LT_RMUL_EQ; PI_POS] THEN + MATCH_MP_TAC(REAL_ARITH `&1 <= x ==> ~(&2 * x < &2)`) THEN + MATCH_MP_TAC REAL_ABS_INTEGER_LEMMA THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN SUBST_ALL_TAC THEN UNDISCH_TAC `~(w:complex = z)` THEN + REWRITE_TAC[] THEN ONCE_REWRITE_TAC[GSYM COMPLEX_SUB_0] THEN + ASM_REWRITE_TAC[COMPLEX_EQ; RE_CX; IM_CX; REAL_MUL_LZERO; REAL_MUL_RZERO]);; + +let CEXP_INTEGER_2PI = prove + (`!n. integer n ==> cexp(Cx(&2 * n * pi) * ii) = Cx(&1)`, + REWRITE_TAC[CEXP_EQ_1; IM_MUL_II; RE_MUL_II; RE_CX; IM_CX] THEN + REWRITE_TAC[REAL_NEG_0] THEN MESON_TAC[]);; + +let SIN_COS_EQ = prove + (`!x y. sin y = sin x /\ cos y = cos x <=> + ?n. integer n /\ y = x + &2 * n * pi`, + REPEAT GEN_TAC THEN MP_TAC(ISPECL [`ii * Cx y`; `ii * Cx x`] CEXP_EQ) THEN + REWRITE_TAC[CEXP_EULER; GSYM CX_SIN; GSYM CX_COS] THEN + REWRITE_TAC[COMPLEX_RING `ii * y = ii * x + z * ii <=> y = x + z`] THEN + REWRITE_TAC[GSYM CX_ADD; CX_INJ] THEN DISCH_THEN(SUBST1_TAC o SYM) THEN + REWRITE_TAC[COMPLEX_EQ; RE_ADD; IM_ADD; RE_MUL_II; IM_MUL_II; RE_CX; IM_CX; + REAL_NEG_0; REAL_ADD_LID; REAL_ADD_RID] THEN + MESON_TAC[]);; + +let SIN_COS_INJ = prove + (`!x y. sin x = sin y /\ cos x = cos y /\ abs(x - y) < &2 * pi ==> x = y`, + REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[GSYM CX_INJ] THEN + MATCH_MP_TAC(COMPLEX_RING `ii * x = ii * y ==> x = y`) THEN + MATCH_MP_TAC COMPLEX_EQ_CEXP THEN + ASM_REWRITE_TAC[CEXP_EULER; GSYM CX_SIN; GSYM CX_COS] THEN + ASM_REWRITE_TAC[IM_MUL_II; RE_CX]);; + +let CEXP_II_NE_1 = prove + (`!x. &0 < x /\ x < &2 * pi ==> ~(cexp(ii * Cx x) = Cx(&1))`, + GEN_TAC THEN STRIP_TAC THEN REWRITE_TAC[CEXP_EQ_1] THEN + REWRITE_TAC[RE_MUL_II; IM_CX; IM_MUL_II; IM_CX; REAL_NEG_0; RE_CX] THEN + DISCH_THEN(X_CHOOSE_THEN `n:real` + (CONJUNCTS_THEN2 ASSUME_TAC SUBST_ALL_TAC)) THEN + UNDISCH_TAC `&0 < &2 * n * pi` THEN ASM_CASES_TAC `n = &0` THEN + ASM_REWRITE_TAC[REAL_MUL_LZERO; REAL_MUL_RZERO; REAL_LT_REFL] THEN + MP_TAC(ISPEC `n:real` REAL_ABS_INTEGER_LEMMA) THEN ASM_REWRITE_TAC[] THEN + DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o MATCH_MP (REAL_ARITH + `&2 * n * pi < &2 * pi ==> &0 < (&1 - n) * &2 * pi`)) THEN + ASM_SIMP_TAC[REAL_LT_MUL_EQ; PI_POS; REAL_LT_MUL; REAL_OF_NUM_LT; ARITH] THEN + ASM_REAL_ARITH_TAC);; + +let CSIN_EQ_0 = prove + (`!z. csin z = Cx(&0) <=> ?n. integer n /\ z = Cx(n * pi)`, + GEN_TAC THEN REWRITE_TAC[csin; COMPLEX_MUL_LNEG; CEXP_NEG] THEN + SIMP_TAC[CEXP_NZ; COMPLEX_FIELD `~(z = Cx(&0)) + ==> ((z - inv z) / (Cx(&2) * ii) = Cx(&0) <=> z pow 2 = Cx(&1))`] THEN + REWRITE_TAC[GSYM CEXP_N; CEXP_EQ_1] THEN + REWRITE_TAC[RE_MUL_CX; IM_MUL_CX; RE_MUL_II; IM_MUL_II] THEN + REWRITE_TAC[COMPLEX_EQ; IM_CX; RE_CX; RIGHT_AND_EXISTS_THM] THEN + EQ_TAC THEN MATCH_MP_TAC MONO_EXISTS THEN SIMP_TAC[] THEN REAL_ARITH_TAC);; + +let CCOS_EQ_0 = prove + (`!z. ccos z = Cx(&0) <=> ?n. integer n /\ z = Cx((n + &1 / &2) * pi)`, + GEN_TAC THEN MP_TAC(SPEC `z - Cx(pi / &2)` CSIN_EQ_0) THEN + REWRITE_TAC[CSIN_SUB; GSYM CX_SIN; GSYM CX_COS; SIN_PI2; COS_PI2] THEN + SIMP_TAC[COMPLEX_RING `s * Cx(&0) - c * Cx(&1) = Cx(&0) <=> c = Cx(&0)`] THEN + REWRITE_TAC[REAL_ADD_RDISTRIB; COMPLEX_EQ_SUB_RADD; CX_ADD] THEN + REWRITE_TAC[REAL_ARITH `&1 / &2 * x = x / &2`]);; + +let CCOS_EQ_1 = prove + (`!z. ccos z = Cx(&1) <=> ?n. integer n /\ z = Cx(&2 * n * pi)`, + GEN_TAC THEN GEN_REWRITE_TAC (LAND_CONV o LAND_CONV o RAND_CONV) + [COMPLEX_RING `z = Cx(&2) * z / Cx(&2)`] THEN + REWRITE_TAC[CCOS_DOUBLE_CSIN; COMPLEX_RING + `a - Cx(&2) * s pow 2 = a <=> s = Cx(&0)`] THEN + REWRITE_TAC[CSIN_EQ_0; CX_MUL] THEN + EQ_TAC THEN MATCH_MP_TAC MONO_EXISTS THEN SIMP_TAC[] THEN + CONV_TAC COMPLEX_RING);; + +let CSIN_EQ_1 = prove + (`!z. csin z = Cx(&1) <=> ?n. integer n /\ z = Cx((&2 * n + &1 / &2) * pi)`, + GEN_TAC THEN MP_TAC(SPEC `z - Cx(pi / &2)` CCOS_EQ_1) THEN + REWRITE_TAC[CCOS_SUB; GSYM CX_SIN; GSYM CX_COS; SIN_PI2; COS_PI2] THEN + SIMP_TAC[COMPLEX_RING `s * Cx(&0) + c * Cx(&1) = Cx(&1) <=> c = Cx(&1)`] THEN + REWRITE_TAC[REAL_ADD_RDISTRIB; COMPLEX_EQ_SUB_RADD; CX_ADD] THEN + REWRITE_TAC[REAL_MUL_ASSOC; REAL_ARITH `&1 / &2 * x = x / &2`]);; + +let CSIN_EQ_MINUS1 = prove + (`!z. csin z = --Cx(&1) <=> + ?n. integer n /\ z = Cx((&2 * n + &3 / &2) * pi)`, + GEN_TAC THEN REWRITE_TAC[COMPLEX_RING `z:complex = --w <=> --z = w`] THEN + REWRITE_TAC[GSYM CSIN_NEG; CSIN_EQ_1] THEN + REWRITE_TAC[COMPLEX_RING `--z:complex = w <=> z = --w`] THEN + EQ_TAC THEN DISCH_THEN(X_CHOOSE_THEN `n:real` STRIP_ASSUME_TAC) THEN + ASM_REWRITE_TAC[GSYM CX_NEG; CX_INJ] THEN + EXISTS_TAC `--(n + &1)` THEN + ASM_SIMP_TAC[INTEGER_CLOSED] THEN REAL_ARITH_TAC);; + +let CCOS_EQ_MINUS1 = prove + (`!z. ccos z = --Cx(&1) <=> + ?n. integer n /\ z = Cx((&2 * n + &1) * pi)`, + GEN_TAC THEN MP_TAC(SPEC `z - Cx(pi / &2)` CSIN_EQ_1) THEN + REWRITE_TAC[CSIN_SUB; GSYM CX_SIN; GSYM CX_COS; SIN_PI2; COS_PI2] THEN + SIMP_TAC[COMPLEX_RING + `s * Cx(&0) - c * Cx(&1) = Cx(&1) <=> c = --Cx(&1)`] THEN + REWRITE_TAC[REAL_ADD_RDISTRIB; COMPLEX_EQ_SUB_RADD; GSYM CX_ADD] THEN + DISCH_TAC THEN EQ_TAC THEN MATCH_MP_TAC MONO_EXISTS THEN + SIMP_TAC[CX_INJ] THEN REAL_ARITH_TAC);; + +let COS_EQ_1 = prove + (`!x. cos x = &1 <=> ?n. integer n /\ x = &2 * n * pi`, + REWRITE_TAC[GSYM CX_INJ; CX_COS; CCOS_EQ_1]);; + +let SIN_EQ_1 = prove + (`!x. sin x = &1 <=> ?n. integer n /\ x = (&2 * n + &1 / &2) * pi`, + REWRITE_TAC[GSYM CX_INJ; CX_SIN; CSIN_EQ_1]);; + +let SIN_EQ_MINUS1 = prove + (`!x. sin x = --(&1) <=> ?n. integer n /\ x = (&2 * n + &3 / &2) * pi`, + REWRITE_TAC[GSYM CX_INJ; CX_NEG; CX_SIN; CSIN_EQ_MINUS1]);; + +let COS_EQ_MINUS1 = prove + (`!x. cos x = --(&1) <=> + ?n. integer n /\ x = (&2 * n + &1) * pi`, + REWRITE_TAC[GSYM CX_INJ; CX_NEG; CX_COS; CCOS_EQ_MINUS1]);; + +let DIST_CEXP_II_1 = prove + (`!z. norm(cexp(ii * Cx t) - Cx(&1)) = &2 * abs(sin(t / &2))`, + GEN_TAC THEN REWRITE_TAC[NORM_EQ_SQUARE] THEN + CONJ_TAC THENL [REAL_ARITH_TAC; REWRITE_TAC[GSYM NORM_POW_2]] THEN + REWRITE_TAC[CEXP_EULER; COMPLEX_SQNORM; GSYM CX_COS; GSYM CX_SIN] THEN + REWRITE_TAC[IM_ADD; RE_ADD; IM_SUB; RE_SUB; IM_MUL_II; RE_MUL_II] THEN + REWRITE_TAC[RE_CX; IM_CX; REAL_POW2_ABS; REAL_POW_MUL] THEN + MP_TAC(ISPEC `t / &2` COS_DOUBLE_SIN) THEN + REWRITE_TAC[REAL_ARITH `&2 * t / &2 = t`] THEN + MP_TAC(SPEC `t:real` SIN_CIRCLE) THEN CONV_TAC REAL_RING);; + +let CX_SINH = prove + (`Cx((exp x - inv(exp x)) / &2) = --ii * csin(ii * Cx x)`, + REWRITE_TAC[csin; COMPLEX_RING `--ii * ii * z = z /\ ii * ii * z = --z`] THEN + REWRITE_TAC[CEXP_NEG; GSYM CX_EXP; GSYM CX_INV; CX_SUB; CX_DIV] THEN + CONV_TAC COMPLEX_FIELD);; + +let CX_COSH = prove + (`Cx((exp x + inv(exp x)) / &2) = ccos(ii * Cx x)`, + REWRITE_TAC[ccos; COMPLEX_RING `--ii * ii * z = z /\ ii * ii * z = --z`] THEN + REWRITE_TAC[CEXP_NEG; GSYM CX_EXP; GSYM CX_INV; CX_ADD; CX_DIV] THEN + CONV_TAC COMPLEX_FIELD);; + +let NORM_CCOS_POW_2 = prove + (`!z. norm(ccos z) pow 2 = + cos(Re z) pow 2 + (exp(Im z) - inv(exp(Im z))) pow 2 / &4`, + REWRITE_TAC[FORALL_COMPLEX; RE; IM] THEN + REWRITE_TAC[COMPLEX_TRAD; CCOS_ADD; COMPLEX_SQNORM] THEN + SIMP_TAC[RE_SUB; IM_SUB; GSYM CX_COS; GSYM CX_SIN; IM_MUL_CX; RE_MUL_CX] THEN + REWRITE_TAC[ccos; csin; CEXP_NEG; COMPLEX_FIELD + `--ii * ii * z = z /\ ii * ii * z = --z /\ + z / (Cx(&2) * ii) = --(ii * z / Cx(&2))`] THEN + REWRITE_TAC[RE_ADD; RE_SUB; IM_ADD; IM_SUB; RE_MUL_II; IM_MUL_II; + RE_DIV_CX; IM_DIV_CX; RE_NEG; IM_NEG] THEN + REWRITE_TAC[GSYM CX_EXP; GSYM CX_INV; IM_CX; RE_CX] THEN + MAP_EVERY X_GEN_TAC [`x:real`; `y:real`] THEN + MP_TAC(SPEC `x:real` SIN_CIRCLE) THEN MP_TAC(SPEC `y:real` REAL_EXP_NZ) THEN + CONV_TAC REAL_FIELD);; + +let NORM_CSIN_POW_2 = prove + (`!z. norm(csin z) pow 2 = + (exp(&2 * Im z) + inv(exp(&2 * Im z)) - &2 * cos(&2 * Re z)) / &4`, + REWRITE_TAC[FORALL_COMPLEX; RE; IM] THEN + REWRITE_TAC[COMPLEX_TRAD; CSIN_ADD; COMPLEX_SQNORM] THEN + SIMP_TAC[RE_ADD; IM_ADD; GSYM CX_SIN; GSYM CX_SIN; IM_MUL_CX; RE_MUL_CX; + GSYM CX_COS] THEN + REWRITE_TAC[ccos; csin; CEXP_NEG; COMPLEX_FIELD + `--ii * ii * z = z /\ ii * ii * z = --z /\ + z / (Cx(&2) * ii) = --(ii * z / Cx(&2))`] THEN + REWRITE_TAC[RE_ADD; RE_SUB; IM_ADD; IM_SUB; RE_MUL_II; IM_MUL_II; + RE_DIV_CX; IM_DIV_CX; RE_NEG; IM_NEG] THEN + REWRITE_TAC[GSYM CX_EXP; GSYM CX_INV; IM_CX; RE_CX] THEN + REWRITE_TAC[REAL_EXP_N; COS_DOUBLE] THEN + MAP_EVERY X_GEN_TAC [`x:real`; `y:real`] THEN + MP_TAC(SPEC `x:real` SIN_CIRCLE) THEN MP_TAC(SPEC `y:real` REAL_EXP_NZ) THEN + CONV_TAC REAL_FIELD);; + +let CSIN_EQ = prove + (`!w z. csin w = csin z <=> + ?n. integer n /\ + (w = z + Cx(&2 * n * pi) \/ w = --z + Cx((&2 * n + &1) * pi))`, + REPEAT GEN_TAC THEN GEN_REWRITE_TAC LAND_CONV [GSYM COMPLEX_SUB_0] THEN + REWRITE_TAC[COMPLEX_SUB_CSIN; COMPLEX_ENTIRE; CSIN_EQ_0; CCOS_EQ_0] THEN + REWRITE_TAC[CX_INJ; REAL_OF_NUM_EQ; ARITH_EQ; OR_EXISTS_THM] THEN + AP_TERM_TAC THEN REWRITE_TAC[FUN_EQ_THM] THEN X_GEN_TAC `n:real` THEN + ASM_CASES_TAC `integer(n)` THEN + ASM_REWRITE_TAC[COMPLEX_FIELD `a / Cx(&2) = b <=> a = Cx(&2) * b`] THEN + REWRITE_TAC[GSYM CX_MUL; REAL_ARITH + `&2 * (n + &1 / &2) * pi = (&2 * n + &1) * pi`] THEN + CONV_TAC COMPLEX_RING);; + +let CCOS_EQ = prove + (`!w z. ccos(w) = ccos(z) <=> + ?n. integer n /\ + (w = z + Cx(&2 * n * pi) \/ w = --z + Cx(&2 * n * pi))`, + REPEAT GEN_TAC THEN CONV_TAC(LAND_CONV SYM_CONV) THEN + GEN_REWRITE_TAC LAND_CONV [GSYM COMPLEX_SUB_0] THEN + REWRITE_TAC[COMPLEX_SUB_CCOS; COMPLEX_ENTIRE; CSIN_EQ_0] THEN + REWRITE_TAC[CX_INJ; REAL_OF_NUM_EQ; ARITH_EQ; OR_EXISTS_THM] THEN + AP_TERM_TAC THEN REWRITE_TAC[FUN_EQ_THM] THEN X_GEN_TAC `n:real` THEN + ASM_CASES_TAC `integer(n)` THEN ASM_REWRITE_TAC[CX_MUL] THEN + CONV_TAC COMPLEX_RING);; + +let SIN_EQ = prove + (`!x y. sin x = sin y <=> + ?n. integer n /\ + (x = y + &2 * n * pi \/ x = --y + (&2 * n + &1) * pi)`, + REWRITE_TAC[GSYM CX_INJ; CX_SIN; CSIN_EQ] THEN + REWRITE_TAC[GSYM CX_ADD; GSYM CX_NEG; CX_INJ]);; + +let COS_EQ = prove + (`!x y. cos x = cos y <=> + ?n. integer n /\ + (x = y + &2 * n * pi \/ x = --y + &2 * n * pi)`, + REWRITE_TAC[GSYM CX_INJ; CX_COS; CCOS_EQ] THEN + REWRITE_TAC[GSYM CX_ADD; GSYM CX_NEG; CX_INJ]);; + +let NORM_CCOS_LE = prove + (`!z. norm(ccos z) <= exp(norm z)`, + GEN_TAC THEN REWRITE_TAC[ccos] THEN + REWRITE_TAC[COMPLEX_NORM_DIV; COMPLEX_NORM_CX; REAL_ABS_NUM] THEN + REWRITE_TAC[REAL_ARITH `x / &2 <= y <=> x <= &2 * y`] THEN + MATCH_MP_TAC(NORM_ARITH + `norm(a) + norm(b) <= d ==> norm(a + b) <= d`) THEN + REWRITE_TAC[NORM_CEXP; COMPLEX_MUL_LNEG; RE_NEG; REAL_EXP_NEG] THEN + REWRITE_TAC[COMPLEX_NORM_CX; RE_MUL_II; REAL_ABS_NUM] THEN + MATCH_MP_TAC(REAL_ARITH + `exp(&0) = &1 /\ (exp(&0) <= w \/ exp(&0) <= z) /\ (w <= u /\ z <= u) + ==> w + z <= &2 * u`) THEN + REWRITE_TAC[GSYM REAL_EXP_NEG; REAL_EXP_MONO_LE] THEN + REWRITE_TAC[REAL_EXP_0] THEN + MP_TAC(SPEC `z:complex` COMPLEX_NORM_GE_RE_IM) THEN + REAL_ARITH_TAC);; + +let NORM_CCOS_PLUS1_LE = prove + (`!z. norm(Cx(&1) + ccos z) <= &2 * exp(norm z)`, + GEN_TAC THEN REWRITE_TAC[ccos] THEN + REWRITE_TAC[COMPLEX_NORM_DIV; COMPLEX_NORM_CX; REAL_ABS_NUM; COMPLEX_RING + `Cx(&1) + (z + z') / Cx(&2) = (Cx(&2) + z + z') / Cx(&2)`] THEN + REWRITE_TAC[REAL_ARITH `x / &2 <= &2 * y <=> x <= &4 * y`] THEN + MATCH_MP_TAC(NORM_ARITH + `norm(a) + norm(b) + norm(c) <= d ==> norm(a + b + c) <= d`) THEN + REWRITE_TAC[NORM_CEXP; COMPLEX_MUL_LNEG; RE_NEG; REAL_EXP_NEG] THEN + REWRITE_TAC[COMPLEX_NORM_CX; RE_MUL_II; REAL_ABS_NUM] THEN + MATCH_MP_TAC(REAL_ARITH + `exp(&0) = &1 /\ (exp(&0) <= w \/ exp(&0) <= z) /\ (w <= u /\ z <= u) + ==> &2 + w + z <= &4 * u`) THEN + REWRITE_TAC[GSYM REAL_EXP_NEG; REAL_EXP_MONO_LE] THEN + REWRITE_TAC[REAL_EXP_0] THEN + MP_TAC(SPEC `z:complex` COMPLEX_NORM_GE_RE_IM) THEN + REAL_ARITH_TAC);; + +(* ------------------------------------------------------------------------- *) +(* Taylor series for complex exponential. *) +(* ------------------------------------------------------------------------- *) + +let TAYLOR_CEXP = prove + (`!n z. norm(cexp z - vsum(0..n) (\k. z pow k / Cx(&(FACT k)))) + <= exp(abs(Re z)) * (norm z) pow (n + 1) / &(FACT n)`, + REPEAT GEN_TAC THEN MP_TAC(ISPECL + [`\k:num. cexp`; `n:num`; `segment[Cx(&0),z]`; `exp(abs(Re z))`] + COMPLEX_TAYLOR) THEN + REWRITE_TAC[CONVEX_SEGMENT; NORM_CEXP; REAL_EXP_MONO_LE] THEN ANTS_TAC THENL + [REWRITE_TAC[IN_SEGMENT] THEN REPEAT STRIP_TAC THENL + [GEN_REWRITE_TAC(RATOR_CONV o LAND_CONV) [GSYM ETA_AX] THEN + COMPLEX_DIFF_TAC THEN REWRITE_TAC[COMPLEX_MUL_LID]; + ASM_REWRITE_TAC[GSYM COMPLEX_VEC_0; VECTOR_MUL_RZERO] THEN + REWRITE_TAC[VECTOR_ADD_LID; COMPLEX_CMUL; COMPLEX_NORM_MUL] THEN + GEN_REWRITE_TAC RAND_CONV [GSYM REAL_MUL_LID] THEN + MATCH_MP_TAC(REAL_ARITH `abs x <= a ==> x <= a`) THEN + REWRITE_TAC[RE_MUL_CX; REAL_ABS_MUL] THEN MATCH_MP_TAC REAL_LE_RMUL THEN + ASM_REAL_ARITH_TAC]; + DISCH_THEN(MP_TAC o SPECL [`Cx(&0)`; `z:complex`]) THEN + SIMP_TAC[ENDS_IN_SEGMENT; COMPLEX_SUB_RZERO; CEXP_0; COMPLEX_MUL_LID]]);; + +(* ------------------------------------------------------------------------- *) +(* Approximation to e. *) +(* ------------------------------------------------------------------------- *) + +let E_APPROX_32 = prove + (`abs(exp(&1) - &11674931555 / &4294967296) <= inv(&2 pow 32)`, + let lemma = prove + (`abs(e - x) <= e * d + ==> &0 <= d /\ d < &1 + ==> abs(e - x) <= x * d / (&1 - d)`, + DISCH_THEN(fun th -> STRIP_TAC THEN ASSUME_TAC th THEN MP_TAC th) THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] REAL_LE_TRANS) THEN + ASM_SIMP_TAC[REAL_ARITH `e * d <= x * d / i <=> d * e <= d * x / i`] THEN + MATCH_MP_TAC REAL_LE_LMUL THEN ASM_REWRITE_TAC[] THEN + ASM_SIMP_TAC[REAL_LE_RDIV_EQ; REAL_SUB_LT] THEN ASM_REAL_ARITH_TAC) in + MP_TAC(ISPECL [`14`; `Cx(&1)`] TAYLOR_CEXP) THEN + SIMP_TAC[GSYM CX_EXP; RE_CX; COMPLEX_NORM_CX; REAL_ABS_NUM; + REAL_POW_ONE; GSYM CX_DIV; GSYM CX_POW] THEN + CONV_TAC(ONCE_DEPTH_CONV EXPAND_VSUM_CONV) THEN + REWRITE_TAC[GSYM CX_ADD; GSYM CX_SUB; COMPLEX_NORM_CX] THEN + CONV_TAC NUM_REDUCE_CONV THEN CONV_TAC REAL_RAT_REDUCE_CONV THEN + DISCH_THEN(MP_TAC o MATCH_MP lemma) THEN REAL_ARITH_TAC);; + +(* ------------------------------------------------------------------------- *) +(* Taylor series for complex sine and cosine. *) +(* ------------------------------------------------------------------------- *) + +let TAYLOR_CSIN_RAW = prove + (`!n z. norm(csin z - + vsum(0..n) (\k. if ODD k + then --ii * (ii * z) pow k / Cx(&(FACT k)) + else Cx(&0))) + <= exp(abs(Im z)) * (norm z) pow (n + 1) / &(FACT n)`, + MP_TAC TAYLOR_CEXP THEN MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `n:num` THEN + DISCH_TAC THEN X_GEN_TAC `z:complex` THEN REWRITE_TAC[csin] THEN + REWRITE_TAC[COMPLEX_FIELD + `a / (Cx(&2) * ii) - b = (a - Cx(&2) * ii * b) / (Cx(&2) * ii)`] THEN + FIRST_ASSUM(fun th -> + MP_TAC(SPEC `ii * z` th) THEN MP_TAC(SPEC `--ii * z` th)) THEN + REWRITE_TAC[COMPLEX_MUL_LNEG; RE_NEG; REAL_ABS_NEG; RE_MUL_II] THEN + REWRITE_TAC[COMPLEX_NORM_DIV; COMPLEX_NORM_MUL; COMPLEX_NORM_CX; NORM_NEG; + COMPLEX_NORM_II; REAL_ABS_NUM; REAL_MUL_RID; REAL_MUL_LID; + REAL_ARITH `x / &2 <= y <=> x <= &2 * y`] THEN + MATCH_MP_TAC(NORM_ARITH + `sp - sn = s2 + ==> norm(en - sn) <= d + ==> norm(ep - sp) <= d ==> norm(ep - en - s2) <= &2 * d`) THEN + SIMP_TAC[GSYM VSUM_SUB; GSYM VSUM_COMPLEX_LMUL; FINITE_NUMSEG] THEN + MATCH_MP_TAC VSUM_EQ THEN X_GEN_TAC `k:num` THEN DISCH_TAC THEN + REWRITE_TAC[COMPLEX_POW_NEG; GSYM NOT_EVEN] THEN ASM_CASES_TAC `EVEN k` THEN + ASM_REWRITE_TAC[COMPLEX_SUB_REFL; COMPLEX_MUL_RZERO] THEN + REWRITE_TAC[COMPLEX_RING `Cx(&2) * ii * --(ii * z) = Cx(&2) * z`] THEN + SIMPLE_COMPLEX_ARITH_TAC);; + +let TAYLOR_CSIN = prove + (`!n z. norm(csin z - + vsum(0..n) (\k. --Cx(&1) pow k * + z pow (2 * k + 1) / Cx(&(FACT(2 * k + 1))))) + <= exp(abs(Im z)) * norm(z) pow (2 * n + 3) / &(FACT(2 * n + 2))`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`SUC(2 * n + 1)`; `z:complex`] TAYLOR_CSIN_RAW) THEN + SIMP_TAC[VSUM_CLAUSES_NUMSEG; VSUM_PAIR_0; ODD_ADD; ODD_MULT; ARITH_ODD; + LE_0; ODD; COMPLEX_ADD_LID; COMPLEX_ADD_RID] THEN + SIMP_TAC[ARITH_RULE `SUC(2 * n + 1) = 2 * n + 2`; GSYM ADD_ASSOC; ARITH] THEN + MATCH_MP_TAC(NORM_ARITH + `s = t ==> norm(x - s) <= e ==> norm(x - t) <= e`) THEN + MATCH_MP_TAC VSUM_EQ THEN X_GEN_TAC `k:num` THEN STRIP_TAC THEN + REWRITE_TAC[COMPLEX_POW_MUL; complex_div; COMPLEX_MUL_ASSOC] THEN + AP_THM_TAC THEN AP_TERM_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN + REWRITE_TAC[COMPLEX_POW_ADD; GSYM COMPLEX_POW_POW] THEN + REWRITE_TAC[COMPLEX_POW_II_2] THEN CONV_TAC COMPLEX_RING);; + +let TAYLOR_CCOS_RAW = prove + (`!n z. norm(ccos z - + vsum(0..n) (\k. if EVEN k + then (ii * z) pow k / Cx(&(FACT k)) + else Cx(&0))) + <= exp(abs(Im z)) * (norm z) pow (n + 1) / &(FACT n)`, + MP_TAC TAYLOR_CEXP THEN MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `n:num` THEN + DISCH_TAC THEN X_GEN_TAC `z:complex` THEN REWRITE_TAC[ccos] THEN + REWRITE_TAC[COMPLEX_FIELD + `a / Cx(&2) - b = (a - Cx(&2) * b) / Cx(&2)`] THEN + FIRST_ASSUM(fun th -> + MP_TAC(SPEC `ii * z` th) THEN MP_TAC(SPEC `--ii * z` th)) THEN + REWRITE_TAC[COMPLEX_MUL_LNEG; RE_NEG; REAL_ABS_NEG; RE_MUL_II] THEN + REWRITE_TAC[COMPLEX_NORM_DIV; COMPLEX_NORM_MUL; COMPLEX_NORM_CX; NORM_NEG; + COMPLEX_NORM_II; REAL_ABS_NUM; REAL_MUL_RID; REAL_MUL_LID; + REAL_ARITH `x / &2 <= y <=> x <= &2 * y`] THEN + MATCH_MP_TAC(NORM_ARITH + `sp + sn = s2 + ==> norm(en - sn) <= d + ==> norm(ep - sp) <= d ==> norm((ep + en) - s2) <= &2 * d`) THEN + SIMP_TAC[GSYM VSUM_ADD; GSYM VSUM_COMPLEX_LMUL; FINITE_NUMSEG] THEN + MATCH_MP_TAC VSUM_EQ THEN X_GEN_TAC `k:num` THEN DISCH_TAC THEN + REWRITE_TAC[COMPLEX_POW_NEG; GSYM NOT_EVEN] THEN ASM_CASES_TAC `EVEN k` THEN + ASM_REWRITE_TAC[COMPLEX_ADD_RINV; COMPLEX_MUL_RZERO] THEN + SIMPLE_COMPLEX_ARITH_TAC);; + +let TAYLOR_CCOS = prove + (`!n z. norm(ccos z - + vsum(0..n) (\k. --Cx(&1) pow k * + z pow (2 * k) / Cx(&(FACT(2 * k))))) + <= exp(abs(Im z)) * norm(z) pow (2 * n + 2) / &(FACT(2 * n + 1))`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`2 * n + 1`; `z:complex`] TAYLOR_CCOS_RAW) THEN + SIMP_TAC[VSUM_PAIR_0; EVEN_ADD; EVEN_MULT; ARITH_EVEN; + LE_0; EVEN; COMPLEX_ADD_LID; COMPLEX_ADD_RID] THEN + SIMP_TAC[ARITH_RULE `(2 * n + 1) + 1 = 2 * n + 2`] THEN + MATCH_MP_TAC(NORM_ARITH + `s = t ==> norm(x - s) <= e ==> norm(x - t) <= e`) THEN + MATCH_MP_TAC VSUM_EQ THEN X_GEN_TAC `k:num` THEN STRIP_TAC THEN + REWRITE_TAC[COMPLEX_POW_MUL; complex_div; COMPLEX_MUL_ASSOC] THEN + AP_THM_TAC THEN AP_TERM_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN + REWRITE_TAC[GSYM COMPLEX_POW_POW; COMPLEX_POW_II_2]);; + +(* ------------------------------------------------------------------------- *) +(* The argument of a complex number, where 0 <= arg(z) < 2 pi *) +(* ------------------------------------------------------------------------- *) + +let Arg_DEF = new_definition + `Arg z = if z = Cx(&0) then &0 + else @t. &0 <= t /\ t < &2 * pi /\ + z = Cx(norm(z)) * cexp(ii * Cx t)`;; + +let ARG_0 = prove + (`Arg(Cx(&0)) = &0`, + REWRITE_TAC[Arg_DEF]);; + +let ARG = prove + (`!z. &0 <= Arg(z) /\ Arg(z) < &2 * pi /\ + z = Cx(norm z) * cexp(ii * Cx(Arg z))`, + GEN_TAC THEN REWRITE_TAC[Arg_DEF] THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[COMPLEX_NORM_0; COMPLEX_MUL_LZERO] THEN + SIMP_TAC[REAL_LE_REFL; REAL_LT_MUL; PI_POS; REAL_ARITH `&0 < &2`] THEN + CONV_TAC SELECT_CONV THEN + MP_TAC(SPECL [`Re(z) / norm z`; `Im(z) / norm z`] + SINCOS_TOTAL_2PI) THEN + ASM_SIMP_TAC[COMPLEX_SQNORM; COMPLEX_NORM_ZERO; REAL_FIELD + `~(z = &0) /\ x pow 2 + y pow 2 = z pow 2 + ==> (x / z) pow 2 + (y / z) pow 2 = &1`] THEN + MATCH_MP_TAC MONO_EXISTS THEN + ASM_SIMP_TAC[COMPLEX_NORM_ZERO; REAL_FIELD + `~(z = &0) ==> (x / z = y <=> x = z * y)`] THEN + REWRITE_TAC[COMPLEX_EQ; RE_MUL_CX; IM_MUL_CX; CEXP_EULER; RE_ADD; IM_ADD; + RE_MUL_II; IM_MUL_II; GSYM CX_SIN; GSYM CX_COS; RE_CX; IM_CX] THEN + REAL_ARITH_TAC);; + +let COMPLEX_NORM_EQ_1_CEXP = prove + (`!z. norm z = &1 <=> (?t. z = cexp(ii * Cx t))`, + GEN_TAC THEN EQ_TAC THEN STRIP_TAC THEN + ASM_REWRITE_TAC [NORM_CEXP; RE_MUL_II; IM_CX; REAL_NEG_0; REAL_EXP_0] THEN + MP_TAC (SPEC `z:complex` ARG) THEN ASM_REWRITE_TAC [COMPLEX_MUL_LID] THEN + MESON_TAC[]);; + +let ARG_UNIQUE = prove + (`!a r z. &0 < r /\ Cx r * cexp(ii * Cx a) = z /\ &0 <= a /\ a < &2 * pi + ==> Arg z = a`, + REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[GSYM CX_INJ] THEN + MATCH_MP_TAC(COMPLEX_RING `ii * x = ii * y ==> x = y`) THEN + MATCH_MP_TAC COMPLEX_EQ_CEXP THEN CONJ_TAC THENL + [REWRITE_TAC[IM_MUL_II; RE_CX] THEN + MATCH_MP_TAC(REAL_ARITH `&0 <= x /\ x < p /\ &0 <= y /\ y < p + ==> abs(x - y) < p`) THEN + ASM_SIMP_TAC[ARG]; + MATCH_MP_TAC(COMPLEX_RING + `!a b. Cx a = Cx b /\ ~(Cx b = Cx(&0)) /\ + Cx a * w = Cx b * z ==> w = z`) THEN + MAP_EVERY EXISTS_TAC [`norm(z:complex)`; `r:real`] THEN + ASM_REWRITE_TAC[GSYM ARG] THEN ASM_SIMP_TAC[CX_INJ; REAL_LT_IMP_NZ] THEN + EXPAND_TAC "z" THEN + REWRITE_TAC[NORM_CEXP_II; COMPLEX_NORM_MUL; COMPLEX_NORM_CX] THEN + ASM_REAL_ARITH_TAC]);; + +let ARG_MUL_CX = prove + (`!r z. &0 < r ==> Arg(Cx r * z) = Arg(z)`, + REPEAT STRIP_TAC THEN + ASM_CASES_TAC `z = Cx(&0)` THEN ASM_REWRITE_TAC[COMPLEX_MUL_RZERO] THEN + MATCH_MP_TAC ARG_UNIQUE THEN EXISTS_TAC `r * norm(z:complex)` THEN + ASM_REWRITE_TAC[CX_MUL; GSYM COMPLEX_MUL_ASSOC; GSYM ARG] THEN + ASM_SIMP_TAC[REAL_LT_MUL; COMPLEX_NORM_NZ]);; + +let ARG_DIV_CX = prove + (`!r z. &0 < r ==> Arg(z / Cx r) = Arg(z)`, + REWRITE_TAC[ONCE_REWRITE_RULE[COMPLEX_MUL_SYM] complex_div] THEN + SIMP_TAC[GSYM CX_INV; ARG_MUL_CX; REAL_LT_INV_EQ]);; + +let ARG_LT_NZ = prove + (`!z. &0 < Arg z <=> ~(Arg z = &0)`, + MP_TAC ARG THEN MATCH_MP_TAC MONO_FORALL THEN REAL_ARITH_TAC);; + +let ARG_LE_PI = prove + (`!z. Arg z <= pi <=> &0 <= Im z`, + GEN_TAC THEN ASM_CASES_TAC `z = Cx(&0)` THENL + [ASM_REWRITE_TAC[Arg_DEF; IM_CX; REAL_LE_REFL; PI_POS_LE]; ALL_TAC] THEN + GEN_REWRITE_TAC (funpow 3 RAND_CONV) [ARG] THEN + ASM_SIMP_TAC[IM_MUL_CX; CEXP_EULER; REAL_LE_MUL_EQ; COMPLEX_NORM_NZ] THEN + REWRITE_TAC[IM_ADD; GSYM CX_SIN; GSYM CX_COS; IM_CX; IM_MUL_II; RE_CX] THEN + REWRITE_TAC[REAL_ADD_LID] THEN EQ_TAC THEN SIMP_TAC[ARG; SIN_POS_PI_LE] THEN + ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN DISCH_TAC THEN + SUBGOAL_THEN `&0 < sin(&2 * pi - Arg z)` MP_TAC THENL + [MATCH_MP_TAC SIN_POS_PI THEN MP_TAC(SPEC `z:complex` ARG) THEN + ASM_REAL_ARITH_TAC; + REWRITE_TAC[SIN_SUB; SIN_NPI; COS_NPI] THEN REAL_ARITH_TAC]);; + +let ARG_LT_PI = prove + (`!z. &0 < Arg z /\ Arg z < pi <=> &0 < Im z`, + GEN_TAC THEN ASM_CASES_TAC `z = Cx(&0)` THENL + [ASM_REWRITE_TAC[Arg_DEF; IM_CX; REAL_LT_REFL; PI_POS_LE]; ALL_TAC] THEN + GEN_REWRITE_TAC (funpow 3 RAND_CONV) [ARG] THEN + ASM_SIMP_TAC[IM_MUL_CX; CEXP_EULER; REAL_LT_MUL_EQ; COMPLEX_NORM_NZ] THEN + REWRITE_TAC[IM_ADD; GSYM CX_SIN; GSYM CX_COS; IM_CX; IM_MUL_II; RE_CX] THEN + REWRITE_TAC[REAL_ADD_LID] THEN EQ_TAC THEN SIMP_TAC[SIN_POS_PI] THEN + ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN + ASM_CASES_TAC `Arg z = &0` THEN + ASM_REWRITE_TAC[SIN_0; REAL_LT_REFL] THEN + ASM_SIMP_TAC[ARG; REAL_ARITH `~(x = &0) ==> (&0 < x <=> &0 <= x)`] THEN + DISCH_TAC THEN + SUBGOAL_THEN `&0 <= sin(&2 * pi - Arg z)` MP_TAC THENL + [MATCH_MP_TAC SIN_POS_PI_LE THEN MP_TAC(SPEC `z:complex` ARG) THEN + ASM_REAL_ARITH_TAC; + REWRITE_TAC[SIN_SUB; SIN_NPI; COS_NPI] THEN REAL_ARITH_TAC]);; + +let ARG_EQ_0 = prove + (`!z. Arg z = &0 <=> real z /\ &0 <= Re z`, + GEN_TAC THEN ASM_CASES_TAC `z = Cx(&0)` THENL + [ASM_REWRITE_TAC[REAL_CX; RE_CX; Arg_DEF; REAL_LE_REFL]; ALL_TAC] THEN + CONV_TAC(RAND_CONV(SUBS_CONV[last(CONJUNCTS(SPEC `z:complex` ARG))])) THEN + ASM_SIMP_TAC[RE_MUL_CX; REAL_MUL_CX; REAL_LE_MUL_EQ; COMPLEX_NORM_NZ] THEN + ASM_REWRITE_TAC[COMPLEX_NORM_ZERO; CEXP_EULER] THEN + REWRITE_TAC[real; RE_ADD; IM_ADD; RE_MUL_II; IM_MUL_II; + GSYM CX_SIN; GSYM CX_COS; RE_CX; IM_CX] THEN + REWRITE_TAC[REAL_ADD_RID; REAL_ADD_LID; REAL_NEG_0] THEN + EQ_TAC THEN SIMP_TAC[SIN_0; COS_0; REAL_POS] THEN + ASM_CASES_TAC `Arg z = pi` THENL + [ASM_REWRITE_TAC[COS_PI] THEN REAL_ARITH_TAC; ALL_TAC] THEN + MP_TAC(SPEC `z:complex` ARG) THEN REWRITE_TAC[CONJ_ASSOC] THEN + DISCH_THEN(MP_TAC o CONJUNCT1) THEN DISCH_THEN(STRIP_ASSUME_TAC o MATCH_MP + (REAL_ARITH `&0 <= x /\ x < &2 * pi + ==> --pi < x /\ x < pi \/ --pi < x - pi /\ x - pi < pi`)) THEN + REPEAT STRIP_TAC THEN ASM_SIMP_TAC[SIN_EQ_0_PI] THEN + UNDISCH_TAC `~(Arg z = pi)` THEN ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN + DISCH_TAC THEN REWRITE_TAC[REAL_ARITH `x = pi <=> x - pi = &0`] THEN + MATCH_MP_TAC SIN_EQ_0_PI THEN ASM_REWRITE_TAC[SIN_SUB; SIN_PI] THEN + REAL_ARITH_TAC);; + +let ARG_NUM = prove + (`!n. Arg(Cx(&n)) = &0`, + REWRITE_TAC[ARG_EQ_0; REAL_CX; RE_CX; REAL_POS]);; + +let ARG_EQ_PI = prove + (`!z. Arg z = pi <=> real z /\ Re z < &0`, + SIMP_TAC[ARG; PI_POS; REAL_ARITH + `&0 < pi /\ &0 <= z + ==> (z = pi <=> z <= pi /\ ~(z = &0) /\ ~(&0 < z /\ z < pi))`] THEN + REWRITE_TAC[ARG_EQ_0; ARG; ARG_LT_PI; ARG_LE_PI; real] THEN + REAL_ARITH_TAC);; + +let ARG_EQ_0_PI = prove + (`!z. Arg z = &0 \/ Arg z = pi <=> real z`, + REWRITE_TAC[ARG_EQ_0; ARG_EQ_PI; real] THEN REAL_ARITH_TAC);; + +let ARG_INV = prove + (`!z. ~(real z /\ &0 <= Re z) ==> Arg(inv z) = &2 * pi - Arg z`, + GEN_TAC THEN ASM_CASES_TAC `z = Cx(&0)` THEN + ASM_REWRITE_TAC[REAL_CX; RE_CX; REAL_LE_REFL] THEN + REWRITE_TAC[real] THEN STRIP_TAC THEN MATCH_MP_TAC ARG_UNIQUE THEN + EXISTS_TAC `inv(norm(z:complex))` THEN + ASM_SIMP_TAC[COMPLEX_NORM_NZ; REAL_LT_INV_EQ] THEN + REWRITE_TAC[CX_SUB; CX_MUL; COMPLEX_SUB_LDISTRIB; CEXP_SUB] THEN + SUBST1_TAC(SPEC `Cx(&2) * Cx pi` CEXP_EULER) THEN + REWRITE_TAC[GSYM CX_MUL; GSYM CX_SIN; GSYM CX_COS] THEN + REWRITE_TAC[SIN_NPI; COS_NPI; COMPLEX_MUL_RZERO; COMPLEX_ADD_RID] THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN + REWRITE_TAC[complex_div; COMPLEX_MUL_LID; CX_INV; GSYM COMPLEX_INV_MUL] THEN + REWRITE_TAC[GSYM ARG] THEN + MP_TAC(SPEC `z:complex` ARG_EQ_0) THEN ASM_REWRITE_TAC[real] THEN + MP_TAC(SPEC `z:complex` ARG) THEN REAL_ARITH_TAC);; + +let ARG_EQ = prove + (`!w z. ~(w = Cx(&0)) /\ ~(z = Cx(&0)) + ==> (Arg w = Arg z <=> ?x. &0 < x /\ w = Cx(x) * z)`, + REPEAT STRIP_TAC THEN EQ_TAC THENL + [ALL_TAC; STRIP_TAC THEN ASM_SIMP_TAC[ARG_MUL_CX]] THEN + DISCH_TAC THEN + MAP_EVERY (MP_TAC o CONJUNCT2 o CONJUNCT2 o C SPEC ARG) + [`z:complex`; `w:complex`] THEN + ASM_REWRITE_TAC[IMP_IMP] THEN + DISCH_THEN(fun th -> CONV_TAC(SUBS_CONV(CONJUNCTS th))) THEN + EXISTS_TAC `norm(w:complex) / norm(z:complex)` THEN + ASM_SIMP_TAC[REAL_LT_DIV; COMPLEX_NORM_NZ; CX_DIV] THEN + REWRITE_TAC[COMPLEX_MUL_ASSOC] THEN AP_THM_TAC THEN AP_TERM_TAC THEN + ASM_SIMP_TAC[COMPLEX_DIV_RMUL; COMPLEX_NORM_ZERO; CX_INJ]);; + +let ARG_INV_EQ_0 = prove + (`!z. Arg(inv z) = &0 <=> Arg z = &0`, + GEN_TAC THEN REWRITE_TAC[ARG_EQ_0; REAL_INV_EQ] THEN + MATCH_MP_TAC(TAUT `(a ==> (b <=> c)) ==> (a /\ b <=> a /\ c)`) THEN + REWRITE_TAC[real] THEN DISCH_TAC THEN ASM_REWRITE_TAC[complex_inv; RE] THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN REWRITE_TAC[REAL_ADD_RID] THEN + ASM_CASES_TAC `Re z = &0` THEN ASM_REWRITE_TAC[real_div; REAL_MUL_LZERO] THEN + ASM_SIMP_TAC[REAL_FIELD `~(x = &0) ==> x * inv(x pow 2) = inv x`] THEN + REWRITE_TAC[REAL_LE_INV_EQ]);; + +let ARG_LE_DIV_SUM = prove + (`!w z. ~(w = Cx(&0)) /\ ~(z = Cx(&0)) /\ Arg(w) <= Arg(z) + ==> Arg(z) = Arg(w) + Arg(z / w)`, + REPEAT STRIP_TAC THEN + ONCE_REWRITE_TAC[REAL_ARITH `a:real = b + c <=> c = a - b`] THEN + MATCH_MP_TAC ARG_UNIQUE THEN EXISTS_TAC `norm(z / w)`THEN + ASM_SIMP_TAC[ARG; REAL_ARITH + `&0 <= a /\ a < &2 * pi /\ &0 <= b /\ b <= a ==> a - b < &2 * pi`] THEN + ASM_REWRITE_TAC[REAL_SUB_LE] THEN + ASM_SIMP_TAC[COMPLEX_NORM_DIV; CX_DIV] THEN + ASM_SIMP_TAC[REAL_LT_DIV; COMPLEX_NORM_NZ] THEN + REWRITE_TAC[COMPLEX_SUB_LDISTRIB; CEXP_SUB; CX_SUB] THEN + REWRITE_TAC[complex_div] THEN + ONCE_REWRITE_TAC[COMPLEX_RING + `(a * b) * (c * d):complex = (a * c) * (b * d)`] THEN + REWRITE_TAC[GSYM COMPLEX_INV_MUL] THEN ASM_SIMP_TAC[GSYM ARG]);; + +let ARG_LE_DIV_SUM_EQ = prove + (`!w z. ~(w = Cx(&0)) /\ ~(z = Cx(&0)) + ==> (Arg(w) <= Arg(z) <=> Arg(z) = Arg(w) + Arg(z / w))`, + MESON_TAC[ARG_LE_DIV_SUM; REAL_LE_ADDR; ARG]);; + +let REAL_SUB_ARG = prove + (`!w z. ~(w = Cx(&0)) /\ ~(z = Cx(&0)) + ==> Arg w - Arg z = if Arg(z) <= Arg(w) then Arg(w / z) + else Arg(w / z) - &2 * pi`, + REPEAT STRIP_TAC THEN COND_CASES_TAC THENL + [MP_TAC(ISPECL [`z:complex`; `w:complex`] ARG_LE_DIV_SUM) THEN + ASM_REWRITE_TAC[] THEN REAL_ARITH_TAC; + MP_TAC(ISPECL [`w:complex`; `z:complex`] ARG_LE_DIV_SUM) THEN + ASM_REWRITE_TAC[] THEN + ANTS_TAC THENL [ASM_REAL_ARITH_TAC; DISCH_THEN SUBST1_TAC] THEN + REWRITE_TAC[REAL_ARITH `a - (a + b):real = --b`] THEN + GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [GSYM COMPLEX_INV_DIV] THEN + MATCH_MP_TAC(REAL_ARITH `x = &2 * pi - y ==> --x = y - &2 * pi`) THEN + MATCH_MP_TAC ARG_INV THEN REWRITE_TAC[GSYM ARG_EQ_0] THEN + ONCE_REWRITE_TAC[GSYM COMPLEX_INV_DIV] THEN + REWRITE_TAC[ARG_INV_EQ_0] THEN + MP_TAC(ISPECL [`w:complex`; `z:complex`] ARG_LE_DIV_SUM) THEN + ASM_REWRITE_TAC[] THEN ASM_REAL_ARITH_TAC]);; + +let REAL_ADD_ARG = prove + (`!w z. ~(w = Cx(&0)) /\ ~(z = Cx(&0)) + ==> Arg(w) + Arg(z) = + if Arg w + Arg z < &2 * pi + then Arg(w * z) + else Arg(w * z) + &2 * pi`, + REPEAT STRIP_TAC THEN + MP_TAC(SPECL [`w * z:complex`; `z:complex`] REAL_SUB_ARG) THEN + MP_TAC(SPECL [`z:complex`; `w * z:complex`] ARG_LE_DIV_SUM_EQ) THEN + ASM_SIMP_TAC[COMPLEX_ENTIRE; COMPLEX_FIELD + `~(z = Cx(&0)) ==> (w * z) / z = w`] THEN + ASM_CASES_TAC `Arg (w * z) = Arg z + Arg w` THEN ASM_REWRITE_TAC[] THENL + [ASM_MESON_TAC[ARG; REAL_ADD_SYM]; + SIMP_TAC[REAL_ARITH `wz - z = w - &2 * pi <=> w + z = wz + &2 * pi`] THEN + REWRITE_TAC[REAL_ARITH `w + p < p <=> ~(&0 <= w)`; ARG]]);; + +let ARG_MUL = prove + (`!w z. ~(w = Cx(&0)) /\ ~(z = Cx(&0)) + ==> Arg(w * z) = if Arg w + Arg z < &2 * pi + then Arg w + Arg z + else (Arg w + Arg z) - &2 * pi`, + REPEAT GEN_TAC THEN DISCH_THEN(MP_TAC o MATCH_MP REAL_ADD_ARG) THEN + REAL_ARITH_TAC);; + +let ARG_CNJ = prove + (`!z. Arg(cnj z) = if real z /\ &0 <= Re z then Arg z else &2 * pi - Arg z`, + GEN_TAC THEN ASM_CASES_TAC `z = Cx(&0)` THEN + ASM_REWRITE_TAC[CNJ_CX; ARG_0; REAL_CX; RE_CX; REAL_LE_REFL] THEN + COND_CASES_TAC THEN ASM_SIMP_TAC[REAL_IMP_CNJ] THEN + MATCH_MP_TAC EQ_TRANS THEN EXISTS_TAC `Arg(inv z)` THEN CONJ_TAC THENL + [REWRITE_TAC[COMPLEX_INV_CNJ] THEN + ASM_SIMP_TAC[GSYM CX_POW; ARG_DIV_CX; REAL_POW_LT; COMPLEX_NORM_NZ]; + ASM_SIMP_TAC[ARG_INV]]);; + +let ARG_REAL = prove + (`!z. real z ==> Arg z = if &0 <= Re z then &0 else pi`, + REPEAT STRIP_TAC THEN COND_CASES_TAC THEN + ASM_REWRITE_TAC[ARG_EQ_PI; ARG_EQ_0] THEN ASM_REAL_ARITH_TAC);; + +let ARG_CEXP = prove + (`!z. &0 <= Im z /\ Im z < &2 * pi ==> Arg(cexp(z)) = Im z`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC ARG_UNIQUE THEN + EXISTS_TAC `exp(Re z)` THEN + ASM_REWRITE_TAC[CX_EXP; GSYM CEXP_ADD; REAL_EXP_POS_LT] THEN + REWRITE_TAC[GSYM COMPLEX_EXPAND]);; + +(* ------------------------------------------------------------------------- *) +(* Properties of 2-D rotations, and their interpretation using cexp. *) +(* ------------------------------------------------------------------------- *) + +let rotate2d = new_definition + `(rotate2d:real->real^2->real^2) t x = + vector[x$1 * cos(t) - x$2 * sin(t); + x$1 * sin(t) + x$2 * cos(t)]`;; + +let LINEAR_ROTATE2D = prove + (`!t. linear(rotate2d t)`, + SIMP_TAC[linear; CART_EQ; DIMINDEX_2; FORALL_2; VECTOR_2; + VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT; rotate2d] THEN + REAL_ARITH_TAC);; + +let ROTATE2D_ADD_VECTORS = prove + (`!t w z. rotate2d t (w + z) = rotate2d t w + rotate2d t z`, + SIMP_TAC[LINEAR_ADD; LINEAR_ROTATE2D]);; + +let ROTATE2D_SUB = prove + (`!t w z. rotate2d t (w - z) = rotate2d t w - rotate2d t z`, + SIMP_TAC[LINEAR_SUB; LINEAR_ROTATE2D]);; + +let NORM_ROTATE2D = prove + (`!t z. norm(rotate2d t z) = norm z`, + REWRITE_TAC[NORM_EQ; rotate2d; DIMINDEX_2; DOT_2; VECTOR_2] THEN + REPEAT GEN_TAC THEN MP_TAC(ISPEC `t:real` SIN_CIRCLE) THEN + CONV_TAC REAL_RING);; + +let ROTATE2D_0 = prove + (`!t. rotate2d t (Cx(&0)) = Cx(&0)`, + REWRITE_TAC[GSYM COMPLEX_NORM_ZERO; NORM_ROTATE2D; COMPLEX_NORM_0]);; + +let ROTATE2D_EQ_0 = prove + (`!t z. rotate2d t z = Cx(&0) <=> z = Cx(&0)`, + REWRITE_TAC[GSYM COMPLEX_NORM_ZERO; NORM_ROTATE2D]);; + +let ROTATE2D_ZERO = prove + (`!z. rotate2d (&0) z = z`, + REWRITE_TAC[rotate2d; SIN_0; COS_0] THEN + REWRITE_TAC[CART_EQ; DIMINDEX_2; FORALL_2; VECTOR_2] THEN + REAL_ARITH_TAC);; + +let ORTHOGONAL_TRANSFORMATION_ROTATE2D = prove + (`!t. orthogonal_transformation(rotate2d t)`, + REWRITE_TAC[ORTHOGONAL_TRANSFORMATION; LINEAR_ROTATE2D; NORM_ROTATE2D]);; + +let ROTATE2D_POLAR = prove + (`!r t s. rotate2d t (vector[r * cos(s); r * sin(s)]) = + vector[r * cos(t + s); r * sin(t + s)]`, + SIMP_TAC[rotate2d; DIMINDEX_2; VECTOR_2; CART_EQ; FORALL_2] THEN + REWRITE_TAC[SIN_ADD; COS_ADD] THEN REAL_ARITH_TAC);; + +let MATRIX_ROTATE2D = prove + (`!t. matrix(rotate2d t) = vector[vector[cos t;--(sin t)]; + vector[sin t; cos t]]`, + SIMP_TAC[MATRIX_EQ; MATRIX_WORKS; LINEAR_ROTATE2D] THEN + SIMP_TAC[matrix_vector_mul; rotate2d; CART_EQ; DIMINDEX_2; FORALL_2; + LAMBDA_BETA; VECTOR_2; ARITH; SUM_2] THEN + REAL_ARITH_TAC);; + +let DET_MATRIX_ROTATE2D = prove + (`!t. det(matrix(rotate2d t)) = &1`, + GEN_TAC THEN REWRITE_TAC[MATRIX_ROTATE2D; DET_2; VECTOR_2] THEN + MP_TAC(SPEC `t:real` SIN_CIRCLE) THEN REAL_ARITH_TAC);; + +let ROTATION_ROTATE2D = prove + (`!f. orthogonal_transformation f /\ det(matrix f) = &1 + ==> ?t. &0 <= t /\ t < &2 * pi /\ f = rotate2d t`, + REWRITE_TAC[ORTHOGONAL_TRANSFORMATION_MATRIX] THEN + REWRITE_TAC[matrix_mul; orthogonal_matrix; transp] THEN + SIMP_TAC[DIMINDEX_2; SUM_2; FORALL_2; LAMBDA_BETA; ARITH; + CART_EQ; mat; DET_2] THEN REPEAT STRIP_TAC THEN + SUBGOAL_THEN `(matrix f)$1$1 pow 2 + (matrix f)$2$1 pow 2 = &1 /\ + (matrix f)$1$2 = --((matrix f)$2$1) /\ + (matrix f:real^2^2)$2$2 = (matrix f)$1$1` + STRIP_ASSUME_TAC THENL + [REPEAT(FIRST_X_ASSUM(MP_TAC o SYM)) THEN CONV_TAC REAL_RING; + FIRST_X_ASSUM(MP_TAC o MATCH_MP SINCOS_TOTAL_2PI) THEN + MATCH_MP_TAC MONO_EXISTS THEN REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC LINEAR_EQ_MATRIX THEN + ASM_REWRITE_TAC[LINEAR_ROTATE2D; MATRIX_ROTATE2D] THEN + ASM_SIMP_TAC[CART_EQ; DIMINDEX_2; FORALL_2; VECTOR_2]]);; + +let ROTATE2D_ADD = prove + (`!s t x. rotate2d (s + t) x = rotate2d s (rotate2d t x)`, + SIMP_TAC[CART_EQ; rotate2d; LAMBDA_BETA; DIMINDEX_2; ARITH; + FORALL_2; VECTOR_2] THEN + REWRITE_TAC[SIN_ADD; COS_ADD] THEN REAL_ARITH_TAC);; + +let ROTATE2D_COMPLEX = prove + (`!t z. rotate2d t z = cexp(ii * Cx t) * z`, + REPEAT GEN_TAC THEN GEN_REWRITE_TAC RAND_CONV [complex_mul] THEN + REWRITE_TAC[CEXP_EULER; rotate2d; GSYM CX_SIN; GSYM CX_COS; + RE_ADD; IM_ADD; RE_MUL_II; IM_MUL_II; IM_CX; RE_CX] THEN + REWRITE_TAC[CART_EQ; FORALL_2; VECTOR_2; DIMINDEX_2] THEN + REWRITE_TAC[GSYM RE_DEF; GSYM IM_DEF; RE; IM] THEN + REAL_ARITH_TAC);; + +let ROTATE2D_PI2 = prove + (`!z. rotate2d (pi / &2) z = ii * z`, + REWRITE_TAC[ROTATE2D_COMPLEX; CEXP_EULER; SIN_PI2; COS_PI2; GSYM CX_SIN; + GSYM CX_COS] THEN + CONV_TAC COMPLEX_RING);; + +let ROTATE2D_PI = prove + (`!z. rotate2d pi z = --z`, + REWRITE_TAC[ROTATE2D_COMPLEX; CEXP_EULER; SIN_PI; COS_PI; GSYM CX_SIN; + GSYM CX_COS] THEN + CONV_TAC COMPLEX_RING);; + +let ROTATE2D_NPI = prove + (`!n z. rotate2d (&n * pi) z = --Cx(&1) pow n * z`, + REWRITE_TAC[ROTATE2D_COMPLEX; CEXP_EULER; SIN_NPI; COS_NPI; GSYM CX_SIN; + GSYM CX_COS; CX_NEG; CX_POW] THEN + CONV_TAC COMPLEX_RING);; + +let ROTATE2D_2PI = prove + (`!z. rotate2d (&2 * pi) z = z`, + REWRITE_TAC[ROTATE2D_NPI] THEN CONV_TAC COMPLEX_RING);; + +let ARG_ROTATE2D = prove + (`!t z. ~(z = Cx(&0)) /\ &0 <= t + Arg z /\ t + Arg z < &2 * pi + ==> Arg(rotate2d t z) = t + Arg z`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC ARG_UNIQUE THEN + EXISTS_TAC `norm(z:complex)` THEN + ASM_SIMP_TAC[ARG; ROTATE2D_COMPLEX; REAL_LE_ADD; COMPLEX_NORM_NZ] THEN + GEN_REWRITE_TAC (RAND_CONV o RAND_CONV) [ARG] THEN + REWRITE_TAC[CX_ADD; COMPLEX_ADD_LDISTRIB; CEXP_ADD] THEN + REWRITE_TAC[COMPLEX_MUL_AC]);; + +let ARG_ROTATE2D_UNIQUE = prove + (`!t a z. ~(z = Cx(&0)) /\ Arg(rotate2d t z) = a + ==> ?n. integer n /\ t = &2 * n * pi + (a - Arg z)`, + REPEAT STRIP_TAC THEN + MP_TAC(last(CONJUNCTS(ISPEC `rotate2d t z` ARG))) THEN + ASM_REWRITE_TAC[NORM_ROTATE2D] THEN + REWRITE_TAC[ROTATE2D_COMPLEX] THEN + GEN_REWRITE_TAC (LAND_CONV o LAND_CONV o RAND_CONV) [ARG] THEN + ASM_REWRITE_TAC[COMPLEX_RING `a * z * b = z * c <=> z = Cx(&0) \/ a * b = c`; + CX_INJ; COMPLEX_NORM_ZERO; GSYM CEXP_ADD; CEXP_EQ] THEN + MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC THEN MATCH_MP_TAC MONO_AND THEN + REWRITE_TAC[GSYM CX_ADD; GSYM CX_SUB; CX_INJ; COMPLEX_RING + `ii * t + ii * z = ii * a + n * ii <=> t = n + (a - z)`]);; + +let ARG_ROTATE2D_UNIQUE_2PI = prove + (`!s t z. ~(z = Cx(&0)) /\ + &0 <= s /\ s < &2 * pi /\ &0 <= t /\ t < &2 * pi /\ + Arg(rotate2d s z) = Arg(rotate2d t z) + ==> s = t`, + REPEAT STRIP_TAC THEN ABBREV_TAC `a = Arg(rotate2d t z)` THEN + MP_TAC(ISPECL [`s:real`; `a:real`; `z:complex`] ARG_ROTATE2D_UNIQUE) THEN + MP_TAC(ISPECL [`t:real`; `a:real`; `z:complex`] ARG_ROTATE2D_UNIQUE) THEN + ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN MATCH_MP_TAC SIN_COS_INJ THEN + REWRITE_TAC[CONJ_ASSOC] THEN CONJ_TAC THENL + [ASM_REWRITE_TAC[SIN_COS_EQ; REAL_RING + `x + az:real = (y + az) + z <=> x - y = z`] THEN + REWRITE_TAC[GSYM REAL_SUB_LDISTRIB; GSYM REAL_SUB_RDISTRIB] THEN + ASM_MESON_TAC[INTEGER_CLOSED]; + ASM_REAL_ARITH_TAC]);; + +let COMPLEX_DIV_ROTATION = prove + (`!f w z. orthogonal_transformation f /\ det(matrix f) = &1 + ==> f w / f z = w / z`, + REPEAT GEN_TAC THEN DISCH_THEN(MP_TAC o MATCH_MP ROTATION_ROTATE2D) THEN + DISCH_THEN(X_CHOOSE_THEN `t:real` STRIP_ASSUME_TAC) THEN + ASM_REWRITE_TAC[ROTATE2D_COMPLEX] THEN + SIMP_TAC[complex_div; COMPLEX_INV_MUL; CEXP_NZ; COMPLEX_FIELD + `~(a = Cx(&0)) ==> (a * w) * (inv a * z) = w * z`]);; + +let th = prove + (`!f w z. linear f /\ (!x. norm(f x) = norm x) /\ + (2 <= dimindex(:2) ==> det(matrix f) = &1) + ==> f w / f z = w / z`, + REWRITE_TAC[CONJ_ASSOC; GSYM ORTHOGONAL_TRANSFORMATION; + DIMINDEX_2; LE_REFL; COMPLEX_DIV_ROTATION]) in +add_linear_invariants [th];; + +let th = prove + (`!f t z. linear f /\ (!x. norm(f x) = norm x) /\ + (2 <= dimindex(:2) ==> det(matrix f) = &1) + ==> rotate2d t (f z) = f(rotate2d t z)`, + REWRITE_TAC[DIMINDEX_2; LE_REFL] THEN REPEAT STRIP_TAC THEN + MP_TAC(SPEC `f:complex->complex` ROTATION_ROTATE2D) THEN + ASM_REWRITE_TAC[ORTHOGONAL_TRANSFORMATION] THEN + DISCH_THEN(X_CHOOSE_THEN `s:real` STRIP_ASSUME_TAC) THEN + ASM_REWRITE_TAC[GSYM ROTATE2D_ADD] THEN REWRITE_TAC[REAL_ADD_SYM]) in +add_linear_invariants [th];; + +let ROTATION_ROTATE2D_EXISTS_GEN = prove + (`!x y. ?t. &0 <= t /\ t < &2 * pi /\ norm(y) % rotate2d t x = norm(x) % y`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`norm(y:real^2) % x:real^2`; `norm(x:real^2) % y:real^2`] + ROTATION_EXISTS) THEN + ASM_REWRITE_TAC[DIMINDEX_2; NORM_MUL; ARITH; REAL_ABS_NORM; + EQT_INTRO(SPEC_ALL REAL_MUL_SYM); CONJ_ASSOC] THEN + DISCH_THEN(X_CHOOSE_THEN `f:real^2->real^2` (CONJUNCTS_THEN ASSUME_TAC)) THEN + FIRST_ASSUM(MP_TAC o MATCH_MP ROTATION_ROTATE2D) THEN + MATCH_MP_TAC MONO_EXISTS THEN FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN + REPEAT STRIP_TAC THEN ASM_SIMP_TAC[LINEAR_CMUL; LINEAR_ROTATE2D]);; + +let ROTATION_ROTATE2D_EXISTS = prove + (`!x y. norm x = norm y ==> ?t. &0 <= t /\ t < &2 * pi /\ rotate2d t x = y`, + REPEAT GEN_TAC THEN + ASM_CASES_TAC `norm(y:complex) = &0` THENL + [ASM_REWRITE_TAC[] THEN DISCH_TAC THEN EXISTS_TAC `&0` THEN + SIMP_TAC[REAL_LT_MUL; PI_POS; REAL_OF_NUM_LT; ARITH; REAL_LE_REFL] THEN + ASM_MESON_TAC[COMPLEX_NORM_ZERO; ROTATE2D_0]; + DISCH_TAC THEN + MP_TAC(ISPECL [`x:complex`; `y:complex`] ROTATION_ROTATE2D_EXISTS_GEN) THEN + ASM_REWRITE_TAC[VECTOR_MUL_LCANCEL]]);; + +let ROTATION_ROTATE2D_EXISTS_ORTHOGONAL = prove + (`!e1 e2. norm(e1) = &1 /\ norm(e2) = &1 /\ orthogonal e1 e2 + ==> e1 = rotate2d (pi / &2) e2 \/ e2 = rotate2d (pi / &2) e1`, + REWRITE_TAC[NORM_EQ_1; orthogonal] THEN + SIMP_TAC[DOT_2; CART_EQ; FORALL_2; DIMINDEX_2; rotate2d; VECTOR_2] THEN + REWRITE_TAC[COS_PI2; SIN_PI2; REAL_MUL_RZERO; REAL_ADD_RID; + REAL_SUB_LZERO; REAL_SUB_RZERO; REAL_MUL_RID] THEN + CONV_TAC REAL_RING);; + +let ROTATION_ROTATE2D_EXISTS_ORTHOGONAL_ORIENTED = prove + (`!e1 e2. norm(e1) = &1 /\ norm(e2) = &1 /\ orthogonal e1 e2 /\ + &0 < e1$1 * e2$2 - e1$2 * e2$1 + ==> e2 = rotate2d (pi / &2) e1`, + REPEAT GEN_TAC THEN REWRITE_TAC[CONJ_ASSOC] THEN + DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN + REWRITE_TAC[GSYM CONJ_ASSOC] THEN DISCH_TAC THEN + FIRST_ASSUM(DISJ_CASES_THEN SUBST_ALL_TAC o MATCH_MP + ROTATION_ROTATE2D_EXISTS_ORTHOGONAL) THEN + REWRITE_TAC[] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM REAL_NOT_LE]) THEN + ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN DISCH_THEN(K ALL_TAC) THEN + SIMP_TAC[DOT_2; CART_EQ; FORALL_2; DIMINDEX_2; rotate2d; VECTOR_2] THEN + REWRITE_TAC[COS_PI2; SIN_PI2; REAL_MUL_RZERO; REAL_ADD_RID; + REAL_SUB_LZERO; REAL_SUB_RZERO; REAL_MUL_RID] THEN + REWRITE_TAC[REAL_ARITH `--x * x - y * y <= &0 <=> &0 <= x * x + y * y`] THEN + MATCH_MP_TAC REAL_LE_ADD THEN REWRITE_TAC[REAL_LE_SQUARE]);; + +let ROTATE2D_EQ = prove + (`!t x y. rotate2d t x = rotate2d t y <=> x = y`, + MESON_TAC[ORTHOGONAL_TRANSFORMATION_INJECTIVE; + ORTHOGONAL_TRANSFORMATION_ROTATE2D]);; + +let ROTATE2D_SUB_ARG = prove + (`!w z. ~(w = Cx(&0)) /\ ~(z = Cx(&0)) + ==> rotate2d(Arg w - Arg z) = rotate2d(Arg(w / z))`, + REPEAT STRIP_TAC THEN ASM_SIMP_TAC[REAL_SUB_ARG] THEN + COND_CASES_TAC THEN REWRITE_TAC[real_sub; ROTATE2D_ADD; FUN_EQ_THM] THEN + GEN_TAC THEN AP_TERM_TAC THEN REWRITE_TAC[ROTATE2D_COMPLEX] THEN + REWRITE_TAC[EULER; RE_MUL_II; IM_MUL_II; RE_CX; IM_CX; COS_NEG; SIN_NEG] THEN + REWRITE_TAC[SIN_NPI; COS_NPI; REAL_EXP_NEG; REAL_EXP_0; CX_NEG] THEN + REWRITE_TAC[COMPLEX_NEG_0; COMPLEX_MUL_RZERO; COMPLEX_ADD_RID] THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN REWRITE_TAC[COMPLEX_MUL_LID]);; + +let ROTATION_MATRIX_ROTATE2D = prove + (`!t. rotation_matrix(matrix(rotate2d t))`, + SIMP_TAC[ROTATION_MATRIX_2; MATRIX_ROTATE2D; VECTOR_2] THEN + MESON_TAC[SIN_CIRCLE; REAL_ADD_SYM]);; + +let ROTATION_MATRIX_ROTATE2D_EQ = prove + (`!A:real^2^2. rotation_matrix A <=> ?t. A = matrix(rotate2d t)`, + GEN_TAC THEN EQ_TAC THEN + SIMP_TAC[LEFT_IMP_EXISTS_THM; ROTATION_MATRIX_ROTATE2D] THEN + REWRITE_TAC[ROTATION_MATRIX_2; MATRIX_ROTATE2D] THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o MATCH_MP SINCOS_TOTAL_2PI) THEN + MATCH_MP_TAC MONO_EXISTS THEN REPEAT STRIP_TAC THEN + REWRITE_TAC[CART_EQ; DIMINDEX_2; FORALL_2; VECTOR_2] THEN + ASM_REAL_ARITH_TAC);; + +(* ------------------------------------------------------------------------- *) +(* Homotopy staying within the set of orthogonal transformations *) +(* ------------------------------------------------------------------------- *) + +let NULLHOMOTOPIC_ORTHOGONAL_TRANSFORMATION = prove + (`!f:real^N->real^N. + orthogonal_transformation f /\ det(matrix f) = &1 + ==> homotopic_with orthogonal_transformation ((:real^N),(:real^N)) f I`, + let lemma0 = prove + (`!a x:real^N. + 2 <= dimindex(:N) /\ a IN span {basis 1,basis 2} + ==> reflect_along (vector[a$1; a$2]:real^2) (lambda i. x$i) = + (lambda i. reflect_along a x$i)`, + REPEAT STRIP_TAC THEN + SIMP_TAC[CART_EQ; LAMBDA_BETA; reflect_along; VECTOR_SUB_COMPONENT; + VECTOR_MUL_COMPONENT; DIMINDEX_2; FORALL_2; VECTOR_2; ARITH] THEN + CONJ_TAC THEN AP_TERM_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN + AP_TERM_TAC THEN BINOP_TAC THEN REWRITE_TAC[dot] THEN + CONV_TAC SYM_CONV THEN MATCH_MP_TAC SUM_EQ_SUPERSET THEN + ASM_SIMP_TAC[FINITE_NUMSEG; IN_NUMSEG; FORALL_2; DIMINDEX_2; LAMBDA_BETA; + ARITH; VECTOR_2; SUBSET_NUMSEG] THEN + REWRITE_TAC[ARITH_RULE + `(1 <= i /\ i <= n) /\ ~(1 <= i /\ i <= 2) <=> + 1 <= i /\ 3 <= i /\ i <= n`] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE RAND_CONV [SPAN_2]) THEN + REWRITE_TAC[IN_ELIM_THM; IN_UNIV] THEN + STRIP_TAC THEN + ASM_REWRITE_TAC[VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT] THEN + SIMP_TAC[BASIS_COMPONENT] THEN + REPEAT STRIP_TAC THEN + REPEAT(COND_CASES_TAC THEN ASM_REWRITE_TAC[REAL_MUL_RZERO]) THEN + ASM_ARITH_TAC) in + let lemma1 = prove + (`!a b:real^2 r. + ~(a = vec 0) /\ ~(b = vec 0) + ==> homotopic_with orthogonal_transformation ((:real^2),(:real^2)) + (reflect_along a o reflect_along b) I`, + REPEAT STRIP_TAC THEN + MP_TAC(SPEC `reflect_along (a:real^2) o reflect_along b` + ROTATION_ROTATE2D) THEN + ANTS_TAC THENL + [REPEAT(FIRST_X_ASSUM(MP_TAC o + MATCH_MP ROTOINVERSION_MATRIX_REFLECT_ALONG)) THEN + REWRITE_TAC[rotoinversion_matrix] THEN + SIMP_TAC[ORTHOGONAL_MATRIX_MATRIX; + ORTHGOONAL_TRANSFORMATION_REFLECT_ALONG; + ORTHOGONAL_TRANSFORMATION_COMPOSE; MATRIX_COMPOSE; + LINEAR_REFLECT_ALONG; DET_MUL] THEN + CONV_TAC REAL_RAT_REDUCE_CONV; + DISCH_THEN(X_CHOOSE_THEN `t:real` STRIP_ASSUME_TAC) THEN + ONCE_REWRITE_TAC[HOMOTOPIC_WITH_SYM] THEN + ASM_REWRITE_TAC[homotopic_with] THEN + EXISTS_TAC `\z. rotate2d (drop(fstcart z) * t) (sndcart z)` THEN + SIMP_TAC[ORTHOGONAL_TRANSFORMATION_ROTATE2D; SNDCART_PASTECART; + ETA_AX; FSTCART_PASTECART; DROP_VEC; I_THM; NORM_ROTATE2D; + REAL_MUL_LZERO; REAL_MUL_LID; SUBSET; FORALL_IN_IMAGE; IN_UNIV; + FORALL_IN_PCROSS; IN_SPHERE_0; ROTATE2D_ZERO] THEN + REWRITE_TAC[ROTATE2D_COMPLEX] THEN + MATCH_MP_TAC CONTINUOUS_ON_COMPLEX_MUL THEN + SIMP_TAC[LINEAR_CONTINUOUS_ON; LINEAR_SNDCART] THEN + GEN_REWRITE_TAC LAND_CONV [GSYM o_DEF] THEN + MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN + REWRITE_TAC[CONTINUOUS_ON_CEXP; CX_MUL] THEN + ONCE_REWRITE_TAC[COMPLEX_RING `ii * x * t = (ii * t) * x`] THEN + MATCH_MP_TAC CONTINUOUS_ON_COMPLEX_LMUL THEN + MATCH_MP_TAC CONTINUOUS_ON_CX_DROP THEN + SIMP_TAC[LINEAR_CONTINUOUS_ON; LINEAR_FSTCART]]) in + let lemma2 = prove + (`!a b:real^N r. + 2 <= dimindex(:N) /\ + ~(a = vec 0) /\ ~(b = vec 0) /\ + {a,b} SUBSET span {basis 1,basis 2} + ==> homotopic_with orthogonal_transformation ((:real^N),(:real^N)) + (reflect_along a o reflect_along b) I`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN + `homotopic_with orthogonal_transformation + ((:real^N),(:real^N)) + ((\z. (lambda i. if i <= 2 then (fstcart z)$i + else (sndcart z)$i):real^N) o + (\z. pastecart + (((reflect_along (vector [(a:real^N)$1; a$2]) o + reflect_along (vector [(b:real^N)$1; b$2])) + :real^2->real^2)(fstcart z)) + (sndcart z)) o + (\z:real^N. pastecart ((lambda i. z$i) :real^2) z)) + ((\z. (lambda i. if i <= 2 then (fstcart z)$i + else (sndcart z)$i):real^N) o + I o + (\z:real^N. pastecart ((lambda i. z$i) :real^2) z))` + MP_TAC THENL + [MATCH_MP_TAC HOMOTOPIC_WITH_COMPOSE_CONTINUOUS_LEFT THEN + EXISTS_TAC `(:real^2) PCROSS (:real^N)` THEN + REWRITE_TAC[SUBSET_UNIV] THEN CONJ_TAC THENL + [ALL_TAC; + MATCH_MP_TAC LINEAR_CONTINUOUS_ON THEN + ONCE_REWRITE_TAC[LINEAR_COMPONENTWISE] THEN + SIMP_TAC[LAMBDA_BETA] THEN X_GEN_TAC `i:num` THEN + STRIP_TAC THEN ASM_CASES_TAC `i <= 2` THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[linear; FSTCART_ADD; FSTCART_CMUL; + SNDCART_ADD; SNDCART_CMUL] THEN + REWRITE_TAC[VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT] THEN + REWRITE_TAC[LIFT_ADD; LIFT_CMUL]] THEN + MATCH_MP_TAC HOMOTOPIC_WITH_COMPOSE_CONTINUOUS_RIGHT THEN + EXISTS_TAC `(:real^2) PCROSS (:real^N)` THEN + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; IN_UNIV; PASTECART_IN_PCROSS] THEN + CONJ_TAC THENL + [ALL_TAC; + MATCH_MP_TAC LINEAR_CONTINUOUS_ON THEN + MATCH_MP_TAC LINEAR_PASTECART THEN REWRITE_TAC[LINEAR_ID] THEN + SIMP_TAC[linear; CART_EQ; LAMBDA_BETA; VECTOR_ADD_COMPONENT; + VECTOR_MUL_COMPONENT]] THEN + SUBGOAL_THEN + `I = \z:real^(2,N)finite_sum. pastecart (fstcart z) (sndcart z)` + SUBST1_TAC THENL + [REWRITE_TAC[PASTECART_FST_SND; I_DEF]; ALL_TAC] THEN + MATCH_MP_TAC HOMOTOPIC_WITH_PCROSS THEN + EXISTS_TAC `orthogonal_transformation:(real^2->real^2)->bool` THEN + EXISTS_TAC `\f:real^N->real^N. f = I` THEN REPEAT CONJ_TAC THENL + [REWRITE_TAC[GSYM I_DEF; ETA_AX] THEN MATCH_MP_TAC lemma1 THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [INSERT_SUBSET]) THEN + REWRITE_TAC[SING_SUBSET; SPAN_2; IN_ELIM_THM; IN_UNIV] THEN + DISCH_THEN(REPEAT_TCL STRIP_THM_THEN SUBST_ALL_TAC) THEN + POP_ASSUM_LIST(MP_TAC o end_itlist CONJ o rev) THEN + REWRITE_TAC[CART_EQ; VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT; + DIMINDEX_2; FORALL_2; VECTOR_2] THEN + SIMP_TAC[BASIS_COMPONENT; ARITH; DIMINDEX_2; VEC_COMPONENT; + DIMINDEX_GE_1; LE_REFL] THEN + MATCH_MP_TAC(TAUT + `(r ==> q) /\ (s ==> p) ==> a /\ ~p /\ ~q ==> ~s /\ ~r`) THEN + SIMP_TAC[REAL_MUL_RZERO; REAL_MUL_LZERO; REAL_MUL_RID; + REAL_ADD_LID; REAL_ADD_RID]; + REWRITE_TAC[HOMOTOPIC_WITH_REFL; SUBSET_UNIV; I_DEF] THEN + REWRITE_TAC[CONTINUOUS_ON_ID]; + SIMP_TAC[o_DEF; FSTCART_PASTECART; SNDCART_PASTECART; + LAMBDA_BETA; DIMINDEX_2; ARITH; I_THM] THEN + REWRITE_TAC[ORTHOGONAL_TRANSFORMATION; NORM_EQ] THEN + X_GEN_TAC `f:real^2->real^2` THEN GEN_TAC THEN STRIP_TAC THEN + CONJ_TAC THENL + [FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [linear]) THEN + SIMP_TAC[linear; CART_EQ; LAMBDA_BETA; VECTOR_ADD_COMPONENT; + VECTOR_MUL_COMPONENT; DIMINDEX_2; ARITH] THEN + MATCH_MP_TAC MONO_AND THEN CONJ_TAC THEN + DISCH_THEN(ASSUME_TAC o GSYM) THEN GEN_TAC THEN + GEN_TAC THEN X_GEN_TAC `i:num` THEN STRIP_TAC THEN + COND_CASES_TAC THEN ASM_SIMP_TAC[] THEN + AP_THM_TAC THEN AP_TERM_TAC THEN AP_TERM_TAC THEN + SIMP_TAC[CART_EQ; LAMBDA_BETA; VECTOR_ADD_COMPONENT; + VECTOR_MUL_COMPONENT]; + X_GEN_TAC `v:real^N` THEN REWRITE_TAC[dot; GSYM REAL_POW_2] THEN + SUBGOAL_THEN `dimindex(:N) = 2 + (dimindex(:N) - 2)` SUBST1_TAC THENL + [ASM_ARITH_TAC; ALL_TAC] THEN + ASM_SIMP_TAC[SUM_ADD_SPLIT; ARITH_RULE `1 <= n + 1`] THEN + BINOP_TAC THENL + [RULE_ASSUM_TAC(REWRITE_RULE[dot; DIMINDEX_2; GSYM REAL_POW_2]) THEN + FIRST_X_ASSUM(MP_TAC o SPEC `(lambda i. (v:real^N)$i):real^2`) THEN + MATCH_MP_TAC EQ_IMP THEN BINOP_TAC THEN + MATCH_MP_TAC SUM_EQ_NUMSEG THEN + FIRST_ASSUM(MP_TAC o MATCH_MP (ARITH_RULE + `2 <= n ==> !i. i <= 2 ==> i <= n`)) THEN + SIMP_TAC[LAMBDA_BETA; DIMINDEX_2]; + ASM_SIMP_TAC[ARITH_RULE `2 <= n ==> 2 + n - 2 = n`] THEN + MATCH_MP_TAC SUM_EQ_NUMSEG THEN + SIMP_TAC[ARITH_RULE `2 + 1 <= i ==> 1 <= i`; + LAMBDA_BETA; DIMINDEX_2] THEN + REPEAT STRIP_TAC THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN + ASM_ARITH_TAC]]]; + MATCH_MP_TAC(ONCE_REWRITE_RULE[IMP_CONJ_ALT] HOMOTOPIC_WITH_EQ) THEN + REWRITE_TAC[IN_UNIV; GSYM FUN_EQ_THM] THEN + SIMP_TAC[o_DEF; FSTCART_PASTECART; SNDCART_PASTECART; + LAMBDA_BETA; DIMINDEX_2; ARITH; I_THM] THEN + RULE_ASSUM_TAC(REWRITE_RULE[INSERT_SUBSET; EMPTY_SUBSET]) THEN + ASM_SIMP_TAC[lemma0] THEN + SIMP_TAC[CART_EQ; LAMBDA_BETA; DIMINDEX_2; ARITH; COND_ID] THEN + MAP_EVERY X_GEN_TAC [`x:real^N`; `i:num`] THEN STRIP_TAC THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN + SUBGOAL_THEN `(a:real^N)$i = &0 /\ (b:real^N)$i = &0` ASSUME_TAC THENL + [FIRST_X_ASSUM(CONJUNCTS_THEN MP_TAC) THEN + REWRITE_TAC[SPAN_2; IN_ELIM_THM; IN_UNIV] THEN REPEAT STRIP_TAC THEN + ASM_SIMP_TAC[VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT; + BASIS_COMPONENT] THEN + REPEAT(COND_CASES_TAC THEN ASM_REWRITE_TAC[]) THEN + (REAL_ARITH_TAC ORELSE ASM_ARITH_TAC); + ASM_REWRITE_TAC[reflect_along; VECTOR_SUB_COMPONENT; REAL_MUL_RZERO; + VECTOR_MUL_COMPONENT; REAL_SUB_RZERO]]]) in + let lemma3 = prove + (`!a b:real^N r. + ~(a = vec 0) /\ ~(b = vec 0) + ==> homotopic_with orthogonal_transformation ((:real^N),(:real^N)) + (reflect_along a o reflect_along b) I`, + REPEAT STRIP_TAC THEN ASM_CASES_TAC `dimindex(:N) = 1` THENL + [ASM_SIMP_TAC[o_DEF; I_DEF; REFLECT_ALONG_1D; VECTOR_NEG_NEG] THEN + REWRITE_TAC[HOMOTOPIC_WITH_REFL; SUBSET_UNIV; CONTINUOUS_ON_ID] THEN + REWRITE_TAC[ORTHOGONAL_TRANSFORMATION_ID]; + FIRST_X_ASSUM(MP_TAC o MATCH_MP(ARITH_RULE + `~(n = 1) ==> 1 <= n ==> 2 <= n`)) THEN + REWRITE_TAC[DIMINDEX_GE_1] THEN DISCH_TAC] THEN + MP_TAC(ISPECL [`span{a:real^N,b}`; `span{basis 1:real^N,basis 2}`] + ORTHOGONAL_TRANSFORMATION_INTO_SUBSPACE) THEN + REWRITE_TAC[SUBSPACE_SPAN; DIM_SPAN] THEN ANTS_TAC THENL + [ASM_REWRITE_TAC[DIM_INSERT; SPAN_SING; SPAN_EMPTY; + IN_SING; DIM_EMPTY] THEN + MATCH_MP_TAC(ARITH_RULE `m <= 2 /\ n = 2 ==> m <= n`) THEN + CONJ_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN + ASM_SIMP_TAC[BASIS_NONZERO; ARITH] THEN + REWRITE_TAC[IN_ELIM_THM; IN_UNIV] THEN + COND_CASES_TAC THEN REWRITE_TAC[] THEN + FIRST_X_ASSUM(CHOOSE_THEN (MP_TAC o AP_TERM `(\x:real^N. x$1)`)) THEN + ASM_SIMP_TAC[BASIS_COMPONENT; VECTOR_MUL_COMPONENT; + ARITH; DIMINDEX_GE_1] THEN + REAL_ARITH_TAC; + DISCH_THEN(X_CHOOSE_THEN `f:real^N->real^N` STRIP_ASSUME_TAC) THEN + MP_TAC(ISPEC `f:real^N->real^N` ORTHOGONAL_TRANSFORMATION_INVERSE_o) THEN + ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `g:real^N->real^N` STRIP_ASSUME_TAC)] THEN + SUBGOAL_THEN + `homotopic_with orthogonal_transformation ((:real^N),(:real^N)) + (g o (f o (reflect_along a o reflect_along b) o (g:real^N->real^N)) o f) + (g o (f o I o (g:real^N->real^N)) o f)` + MP_TAC THENL + [ALL_TAC; + ASM_REWRITE_TAC[o_ASSOC] THEN ASM_REWRITE_TAC[GSYM o_ASSOC; I_O_ID]] THEN + MATCH_MP_TAC HOMOTOPIC_WITH_COMPOSE_CONTINUOUS_LEFT THEN + EXISTS_TAC `(:real^N)` THEN REWRITE_TAC[SUBSET_UNIV] THEN + ASM_SIMP_TAC[ORTHOGONAL_TRANSFORMATION_LINEAR; LINEAR_CONTINUOUS_ON] THEN + MATCH_MP_TAC HOMOTOPIC_WITH_COMPOSE_CONTINUOUS_RIGHT THEN + EXISTS_TAC `(:real^N)` THEN REWRITE_TAC[SUBSET_UNIV] THEN + ASM_SIMP_TAC[ORTHOGONAL_TRANSFORMATION_LINEAR; LINEAR_CONTINUOUS_ON] THEN + ASM_REWRITE_TAC[I_O_ID] THEN + MP_TAC(ISPEC `f:real^N->real^N` REFLECT_ALONG_LINEAR_IMAGE) THEN + ASM_REWRITE_TAC[GSYM ORTHOGONAL_TRANSFORMATION] THEN + DISCH_THEN(ASSUME_TAC o GSYM) THEN + SUBGOAL_THEN + `!h:real^N->real^N. + orthogonal_transformation (g o h o (f:real^N->real^N)) <=> + orthogonal_transformation h` + (fun th -> REWRITE_TAC[th; ETA_AX]) + THENL + [GEN_TAC THEN EQ_TAC THEN + ASM_SIMP_TAC[ORTHOGONAL_TRANSFORMATION_COMPOSE] THEN + DISCH_TAC THEN + SUBGOAL_THEN `h:real^N->real^N = f o (g o h o f) o (g:real^N->real^N)` + SUBST1_TAC THENL + [ALL_TAC; ASM_SIMP_TAC[ORTHOGONAL_TRANSFORMATION_COMPOSE]] THEN + ASM_REWRITE_TAC[o_ASSOC] THEN ASM_REWRITE_TAC[GSYM o_ASSOC; I_O_ID]; + ALL_TAC] THEN + SUBGOAL_THEN + `(f:real^N->real^N) o (reflect_along a o reflect_along b) o g = + reflect_along (f a) o reflect_along (f b)` + SUBST1_TAC THENL + [RULE_ASSUM_TAC(REWRITE_RULE[FUN_EQ_THM; o_THM; I_THM]) THEN + ASM_REWRITE_TAC[o_DEF]; + MATCH_MP_TAC lemma2 THEN RULE_ASSUM_TAC + (REWRITE_RULE[GSYM NORM_EQ_0; ORTHOGONAL_TRANSFORMATION]) THEN + ASM_REWRITE_TAC[GSYM NORM_EQ_0] THEN + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ_ALT] + SUBSET_TRANS)) THEN + ASM_SIMP_TAC[GSYM SPAN_LINEAR_IMAGE; IMAGE_CLAUSES] THEN + REWRITE_TAC[SPAN_INC]]) in + GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + MP_TAC(ISPECL [`f:real^N->real^N`; `dimindex(:N)`] + ORTHOGONAL_TRANSFORMATION_GENERATED_BY_REFLECTIONS) THEN + ASM_REWRITE_TAC[ARITH_RULE `n:num <= a + n`] THEN + DISCH_THEN(X_CHOOSE_THEN `l:(real^N)list` STRIP_ASSUME_TAC) THEN + UNDISCH_TAC `ALL (\v:real^N. ~(v = vec 0)) l` THEN + UNDISCH_TAC `orthogonal_transformation(f:real^N->real^N)` THEN + MATCH_MP_TAC(TAUT `r /\ (p /\ q ==> s) ==> r ==> p ==> q ==> s`) THEN + ASM_REWRITE_TAC[IMP_IMP] THEN + SPEC_TAC(`l:(real^N)list`,`l:(real^N)list`) THEN + POP_ASSUM_LIST(K ALL_TAC) THEN GEN_TAC THEN + WF_INDUCT_TAC `LENGTH(l:(real^N)list)` THEN POP_ASSUM MP_TAC THEN + SPEC_TAC(`l:(real^N)list`,`l:(real^N)list`) THEN + MATCH_MP_TAC list_INDUCT THEN + REWRITE_TAC[ALL; ITLIST; HOMOTOPIC_WITH_REFL] THEN + REWRITE_TAC[REWRITE_RULE[GSYM I_DEF] CONTINUOUS_ON_ID; + ORTHOGONAL_TRANSFORMATION_I; SUBSET_UNIV] THEN + X_GEN_TAC `a:real^N` THEN MATCH_MP_TAC list_INDUCT THEN + REWRITE_TAC[ALL; ITLIST; I_O_ID; DET_MATRIX_REFLECT_ALONG] THEN + REWRITE_TAC[ORTHGOONAL_TRANSFORMATION_REFLECT_ALONG] THEN + CONJ_TAC THENL [MESON_TAC[REAL_ARITH `~(-- &1 = &1)`]; ALL_TAC] THEN + MAP_EVERY X_GEN_TAC [`b:real^N`; `l:(real^N)list`] THEN + REPLICATE_TAC 2 (DISCH_THEN(K ALL_TAC)) THEN + DISCH_THEN(MP_TAC o SPEC `l:(real^N)list`) THEN + REWRITE_TAC[LENGTH; ARITH_RULE `n < SUC(SUC n)`] THEN + SIMP_TAC[LINEAR_COMPOSE; LINEAR_REFLECT_ALONG; MATRIX_COMPOSE; + ORTHGOONAL_TRANSFORMATION_REFLECT_ALONG; + ORTHOGONAL_TRANSFORMATION_COMPOSE; ORTHOGONAL_TRANSFORMATION_LINEAR] THEN + DISCH_THEN(fun th -> + DISCH_THEN(CONJUNCTS_THEN2 STRIP_ASSUME_TAC MP_TAC) THEN MP_TAC th) THEN + ASM_SIMP_TAC[DET_MUL; DET_MATRIX_REFLECT_ALONG; REAL_ARITH + `-- &1 * -- &1 * x = x`] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + DISCH_THEN(fun th -> DISCH_TAC THEN MP_TAC th) THEN + ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] HOMOTOPIC_WITH_TRANS) THEN + GEN_REWRITE_TAC RAND_CONV [MESON[I_O_ID] `f = I o f`] THEN + REWRITE_TAC[o_ASSOC] THEN + MATCH_MP_TAC HOMOTOPIC_WITH_COMPOSE_CONTINUOUS_RIGHT THEN + EXISTS_TAC `(:real^N)` THEN REWRITE_TAC[SUBSET_UNIV] THEN + ASM_SIMP_TAC[LINEAR_CONTINUOUS_ON; ORTHOGONAL_TRANSFORMATION_LINEAR] THEN + ABBREV_TAC `g = ITLIST (\v:real^N h. reflect_along v o h) l I` THEN + SUBGOAL_THEN + `(\f:real^N->real^N. + orthogonal_transformation (f o g)) = orthogonal_transformation` + SUBST1_TAC THENL [ALL_TAC; MATCH_MP_TAC lemma3 THEN ASM_REWRITE_TAC[]] THEN + REWRITE_TAC[FUN_EQ_THM] THEN X_GEN_TAC `f:real^N->real^N` THEN + EQ_TAC THEN ASM_SIMP_TAC[ORTHOGONAL_TRANSFORMATION_COMPOSE] THEN + DISCH_TAC THEN + MP_TAC(ISPEC `g:real^N->real^N` ORTHOGONAL_TRANSFORMATION_INVERSE_o) THEN + ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN X_GEN_TAC `h:real^N->real^N` THEN + STRIP_TAC THEN + SUBGOAL_THEN `f = ((f:real^N->real^N) o (g:real^N->real^N)) o h` + SUBST1_TAC THENL + [ASM_REWRITE_TAC[GSYM o_ASSOC; I_O_ID]; + ASM_SIMP_TAC[ORTHOGONAL_TRANSFORMATION_COMPOSE]]);; + +let HOMOTOPIC_SPECIAL_ORTHOGONAL_TRANSFORMATIONS, + HOMOTOPIC_ORTHOGONAL_TRANSFORMATIONS = (CONJ_PAIR o prove) + (`(!f g. homotopic_with + (\h. orthogonal_transformation h /\ det(matrix h) = det(matrix f)) + ((:real^N),(:real^N)) f g <=> + homotopic_with + orthogonal_transformation ((:real^N),(:real^N)) f g) /\ + !f g. homotopic_with orthogonal_transformation ((:real^N),(:real^N)) f g <=> + orthogonal_transformation f /\ orthogonal_transformation g /\ + det(matrix f) = det(matrix g)`, + REWRITE_TAC[AND_FORALL_THM] THEN REPEAT GEN_TAC THEN MATCH_MP_TAC(TAUT + `(u ==> s) /\ (s ==> t) /\ (t ==> u) + ==> (u <=> t) /\ (t <=> s)`) THEN + REPEAT CONJ_TAC THENL + [DISCH_THEN(MP_TAC o MATCH_MP HOMOTOPIC_WITH_IMP_PROPERTY) THEN MESON_TAC[]; + STRIP_TAC THEN + MP_TAC(ISPEC `g:real^N->real^N` ORTHOGONAL_TRANSFORMATION_INVERSE_o) THEN + ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `h:real^N->real^N` STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN + `(f:real^N->real^N) = g o (h:real^N->real^N) o f /\ g = g o I` + (fun th -> ONCE_REWRITE_TAC[th]) + THENL [ASM_REWRITE_TAC[o_ASSOC; I_O_ID]; ALL_TAC] THEN + MATCH_MP_TAC HOMOTOPIC_WITH_COMPOSE_CONTINUOUS_LEFT THEN + EXISTS_TAC `(:real^N)` THEN REWRITE_TAC[SUBSET_UNIV] THEN + ASM_SIMP_TAC[ORTHOGONAL_TRANSFORMATION_LINEAR; LINEAR_CONTINUOUS_ON] THEN + SUBGOAL_THEN + `!k:real^N->real^N. + orthogonal_transformation (g o k) <=> orthogonal_transformation k` + (fun th -> REWRITE_TAC[th; ETA_AX]) + THENL + [GEN_TAC THEN EQ_TAC THEN + ASM_SIMP_TAC[ORTHOGONAL_TRANSFORMATION_COMPOSE] THEN DISCH_THEN + (MP_TAC o SPEC `h:real^N->real^N` o MATCH_MP (ONCE_REWRITE_RULE + [IMP_CONJ_ALT] ORTHOGONAL_TRANSFORMATION_COMPOSE)) THEN + ASM_SIMP_TAC[o_ASSOC; I_O_ID]; + MATCH_MP_TAC NULLHOMOTOPIC_ORTHOGONAL_TRANSFORMATION THEN + REPEAT(FIRST_X_ASSUM(MP_TAC o AP_TERM + `\f:real^N->real^N. det(matrix f)`)) THEN + ASM_SIMP_TAC[MATRIX_COMPOSE; ORTHOGONAL_TRANSFORMATION_LINEAR; + ORTHOGONAL_TRANSFORMATION_COMPOSE; DET_MUL; + MATRIX_I; DET_I]]; + REWRITE_TAC[homotopic_with] THEN MATCH_MP_TAC MONO_EXISTS THEN + X_GEN_TAC `k:real^(1,N)finite_sum->real^N` THEN + STRIP_TAC THEN ASM_SIMP_TAC[] THEN MP_TAC(ISPECL + [`\t. lift( + det(matrix((k:real^(1,N)finite_sum->real^N) o pastecart t)))`; + `interval[vec 0:real^1,vec 1]`] + CONTINUOUS_DISCRETE_RANGE_CONSTANT) THEN + REWRITE_TAC[CONNECTED_INTERVAL] THEN ANTS_TAC THENL + [CONJ_TAC THENL + [MATCH_MP_TAC CONTINUOUS_ON_LIFT_DET THEN + SIMP_TAC[matrix; LAMBDA_BETA; o_DEF] THEN + MAP_EVERY X_GEN_TAC [`i:num`; `j:num`] THEN STRIP_TAC THEN + MATCH_MP_TAC CONTINUOUS_ON_LIFT_COMPONENT_COMPOSE THEN + ASM_REWRITE_TAC[] 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 + SIMP_TAC[SUBSET; FORALL_IN_IMAGE; PASTECART_IN_PCROSS; IN_UNIV]; + X_GEN_TAC `t:real^1` THEN DISCH_TAC THEN EXISTS_TAC `&1` THEN + REWRITE_TAC[REAL_LT_01] THEN X_GEN_TAC `u:real^1` THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + REWRITE_TAC[GSYM LIFT_SUB; NORM_LIFT; LIFT_EQ] THEN + SUBGOAL_THEN + `orthogonal_transformation + ((k:real^(1,N)finite_sum->real^N) o pastecart t) /\ + orthogonal_transformation (k o pastecart u)` + MP_TAC THENL [ASM_SIMP_TAC[o_DEF]; ALL_TAC] THEN + DISCH_THEN(CONJUNCTS_THEN + (STRIP_ASSUME_TAC o MATCH_MP DET_ORTHOGONAL_MATRIX o + MATCH_MP ORTHOGONAL_MATRIX_MATRIX)) THEN + ASM_REWRITE_TAC[] THEN CONV_TAC REAL_RAT_REDUCE_CONV]; + REWRITE_TAC[o_DEF; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `a:real^1` THEN DISCH_TAC THEN + REPEAT(FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM FUN_EQ_THM])) THEN + REPEAT(DISCH_THEN(SUBST1_TAC o SYM)) THEN + ASM_SIMP_TAC[ENDS_IN_UNIT_INTERVAL; GSYM LIFT_EQ]]]);; + +(* ------------------------------------------------------------------------- *) +(* Complex tangent function. *) +(* ------------------------------------------------------------------------- *) + +let ctan = new_definition + `ctan z = csin z / ccos z`;; + +let CTAN_0 = prove + (`ctan(Cx(&0)) = Cx(&0)`, + REWRITE_TAC[ctan; CSIN_0; CCOS_0; COMPLEX_DIV_1]);; + +let CTAN_NEG = prove + (`!z. ctan(--z) = --(ctan z)`, + REWRITE_TAC[ctan; CSIN_NEG; CCOS_NEG; complex_div; COMPLEX_MUL_LNEG]);; + +let CTAN_ADD = prove + (`!w z. ~(ccos(w) = Cx(&0)) /\ + ~(ccos(z) = Cx(&0)) /\ + ~(ccos(w + z) = Cx(&0)) + ==> ctan(w + z) = (ctan w + ctan z) / (Cx(&1) - ctan(w) * ctan(z))`, + REPEAT GEN_TAC THEN REWRITE_TAC[ctan; CSIN_ADD; CCOS_ADD] THEN + CONV_TAC COMPLEX_FIELD);; + +let CTAN_DOUBLE = prove + (`!z. ~(ccos(z) = Cx(&0)) /\ ~(ccos(Cx(&2) * z) = Cx(&0)) + ==> ctan(Cx(&2) * z) = + (Cx(&2) * ctan z) / (Cx(&1) - ctan(z) pow 2)`, + SIMP_TAC[COMPLEX_MUL_2; CTAN_ADD; COMPLEX_POW_2]);; + +let CTAN_SUB = prove + (`!w z. ~(ccos(w) = Cx(&0)) /\ + ~(ccos(z) = Cx(&0)) /\ + ~(ccos(w - z) = Cx(&0)) + ==> ctan(w - z) = (ctan w - ctan z) / (Cx(&1) + ctan(w) * ctan(z))`, + SIMP_TAC[complex_sub; CTAN_ADD; CCOS_NEG; CTAN_NEG] THEN + REWRITE_TAC[COMPLEX_MUL_RNEG; COMPLEX_NEG_NEG]);; + +let COMPLEX_ADD_CTAN = prove + (`!w z. ~(ccos(w) = Cx(&0)) /\ + ~(ccos(z) = Cx(&0)) + ==> ctan(w) + ctan(z) = csin(w + z) / (ccos(w) * ccos(z))`, + REWRITE_TAC[ctan; CSIN_ADD] THEN CONV_TAC COMPLEX_FIELD);; + +let COMPLEX_SUB_CTAN = prove + (`!w z. ~(ccos(w) = Cx(&0)) /\ + ~(ccos(z) = Cx(&0)) + ==> ctan(w) - ctan(z) = csin(w - z) / (ccos(w) * ccos(z))`, + REWRITE_TAC[ctan; CSIN_SUB] THEN CONV_TAC COMPLEX_FIELD);; + +(* ------------------------------------------------------------------------- *) +(* Analytic properties of tangent function. *) +(* ------------------------------------------------------------------------- *) + +let HAS_COMPLEX_DERIVATIVE_CTAN = prove + (`!z. ~(ccos z = Cx(&0)) + ==> (ctan has_complex_derivative (inv(ccos(z) pow 2))) (at z)`, + REPEAT STRIP_TAC THEN + GEN_REWRITE_TAC (RATOR_CONV o LAND_CONV) [GSYM ETA_AX] THEN + REWRITE_TAC[ctan] THEN COMPLEX_DIFF_TAC THEN + MP_TAC(SPEC `z:complex` CSIN_CIRCLE) THEN + POP_ASSUM MP_TAC THEN CONV_TAC COMPLEX_FIELD);; + +let COMPLEX_DIFFERENTIABLE_AT_CTAN = prove + (`!z. ~(ccos z = Cx(&0)) ==> ctan complex_differentiable at z`, + REWRITE_TAC[complex_differentiable] THEN + MESON_TAC[HAS_COMPLEX_DERIVATIVE_CTAN]);; + +let COMPLEX_DIFFERENTIABLE_WITHIN_CTAN = prove + (`!s z. ~(ccos z = Cx(&0)) + ==> ctan complex_differentiable (at z within s)`, + MESON_TAC[COMPLEX_DIFFERENTIABLE_AT_WITHIN; + COMPLEX_DIFFERENTIABLE_AT_CTAN]);; + +add_complex_differentiation_theorems + (CONJUNCTS(REWRITE_RULE[FORALL_AND_THM] + (MATCH_MP HAS_COMPLEX_DERIVATIVE_CHAIN + HAS_COMPLEX_DERIVATIVE_CTAN)));; + +let CONTINUOUS_AT_CTAN = prove + (`!z. ~(ccos z = Cx(&0)) ==> ctan continuous at z`, + MESON_TAC[HAS_COMPLEX_DERIVATIVE_CTAN; + HAS_COMPLEX_DERIVATIVE_IMP_CONTINUOUS_AT]);; + +let CONTINUOUS_WITHIN_CTAN = prove + (`!s z. ~(ccos z = Cx(&0)) ==> ctan continuous (at z within s)`, + MESON_TAC[CONTINUOUS_AT_WITHIN; CONTINUOUS_AT_CTAN]);; + +let CONTINUOUS_ON_CTAN = prove + (`!s. (!z. z IN s ==> ~(ccos z = Cx(&0))) ==> ctan continuous_on s`, + MESON_TAC[CONTINUOUS_AT_IMP_CONTINUOUS_ON; CONTINUOUS_AT_CTAN]);; + +let HOLOMORPHIC_ON_CTAN = prove + (`!s. (!z. z IN s ==> ~(ccos z = Cx(&0))) ==> ctan holomorphic_on s`, + REWRITE_TAC [holomorphic_on] THEN + MESON_TAC [HAS_COMPLEX_DERIVATIVE_AT_WITHIN; HAS_COMPLEX_DERIVATIVE_CTAN]);; + +(* ------------------------------------------------------------------------- *) +(* Real tangent function. *) +(* ------------------------------------------------------------------------- *) + +let tan_def = new_definition + `tan(x) = Re(ctan(Cx x))`;; + +let CNJ_CTAN = prove + (`!z. cnj(ctan z) = ctan(cnj z)`, + REWRITE_TAC[ctan; CNJ_DIV; CNJ_CSIN; CNJ_CCOS]);; + +let REAL_TAN = prove + (`!z. real z ==> real(ctan z)`, + SIMP_TAC[REAL_CNJ; CNJ_CTAN]);; + +let CX_TAN = prove + (`!x. Cx(tan x) = ctan(Cx x)`, + REWRITE_TAC[tan_def] THEN MESON_TAC[REAL; REAL_CX; REAL_TAN]);; + +let tan = prove + (`!x. tan x = sin x / cos x`, + REWRITE_TAC[GSYM CX_INJ; CX_DIV; CX_TAN; CX_SIN; CX_COS; ctan]);; + +let TAN_0 = prove + (`tan(&0) = &0`, + REWRITE_TAC[GSYM CX_INJ; CX_TAN; CTAN_0]);; + +let TAN_PI = prove + (`tan(pi) = &0`, + REWRITE_TAC[tan; SIN_PI; real_div; REAL_MUL_LZERO]);; + +let TAN_NPI = prove + (`!n. tan(&n * pi) = &0`, + REWRITE_TAC[tan; SIN_NPI; real_div; REAL_MUL_LZERO]);; + +let TAN_NEG = prove + (`!x. tan(--x) = --(tan x)`, + REWRITE_TAC[GSYM CX_INJ; CX_TAN; CX_NEG; CTAN_NEG]);; + +let TAN_PERIODIC_PI = prove + (`!x. tan(x + pi) = tan(x)`, + REWRITE_TAC[tan; SIN_PERIODIC_PI; COS_PERIODIC_PI; real_div] THEN + REWRITE_TAC[REAL_MUL_LNEG; REAL_INV_NEG; REAL_MUL_RNEG; REAL_NEG_NEG]);; + +let TAN_PERIODIC_NPI = prove + (`!x n. tan(x + &n * pi) = tan(x)`, + GEN_TAC THEN INDUCT_TAC THEN REWRITE_TAC[REAL_MUL_LZERO; REAL_ADD_RID] THEN + REWRITE_TAC[GSYM REAL_OF_NUM_SUC; REAL_ADD_RDISTRIB; REAL_MUL_LID] THEN + ASM_REWRITE_TAC[REAL_ADD_ASSOC; TAN_PERIODIC_PI]);; + +let TAN_ADD = prove + (`!x y. ~(cos(x) = &0) /\ ~(cos(y) = &0) /\ ~(cos(x + y) = &0) + ==> tan(x + y) = (tan(x) + tan(y)) / (&1 - tan(x) * tan(y))`, + REWRITE_TAC[GSYM CX_INJ; CX_TAN; CX_SIN; CX_COS; CTAN_ADD; + CX_DIV; CX_ADD; CX_SUB; CX_MUL]);; + +let TAN_SUB = prove + (`!x y. ~(cos(x) = &0) /\ ~(cos(y) = &0) /\ ~(cos(x - y) = &0) + ==> tan(x - y) = (tan(x) - tan(y)) / (&1 + tan(x) * tan(y))`, + REWRITE_TAC[GSYM CX_INJ; CX_TAN; CX_SIN; CX_COS; CX_ADD; CTAN_SUB; + CX_DIV; CX_ADD; CX_SUB; CX_MUL]);; + +let TAN_DOUBLE = prove + (`!x. ~(cos(x) = &0) /\ ~(cos(&2 * x) = &0) + ==> tan(&2 * x) = (&2 * tan(x)) / (&1 - (tan(x) pow 2))`, + SIMP_TAC[REAL_MUL_2; TAN_ADD; REAL_POW_2]);; + +let REAL_ADD_TAN = prove + (`!x y. ~(cos(x) = &0) /\ ~(cos(y) = &0) + ==> tan(x) + tan(y) = sin(x + y) / (cos(x) * cos(y))`, + REWRITE_TAC[GSYM CX_INJ; CX_TAN; CX_SIN; CX_COS; CX_MUL; CX_ADD; CX_DIV] THEN + REWRITE_TAC[COMPLEX_ADD_CTAN]);; + +let REAL_SUB_TAN = prove + (`!x y. ~(cos(x) = &0) /\ ~(cos(y) = &0) + ==> tan(x) - tan(y) = sin(x - y) / (cos(x) * cos(y))`, + REWRITE_TAC[GSYM CX_INJ; CX_TAN; CX_SIN; CX_COS; CX_MUL; CX_SUB; CX_DIV] THEN + REWRITE_TAC[COMPLEX_SUB_CTAN]);; + +let TAN_PI4 = prove + (`tan(pi / &4) = &1`, + REWRITE_TAC[tan; SIN_COS; REAL_ARITH `p / &2 - p / &4 = p / &4`] THEN + MATCH_MP_TAC REAL_DIV_REFL THEN REWRITE_TAC[COS_EQ_0; PI_NZ; REAL_FIELD + `p / &4 = (n + &1 / &2) * p <=> p = &0 \/ n = -- &1 / &4`] THEN + ONCE_REWRITE_TAC[CONJ_SYM] THEN REWRITE_TAC[UNWIND_THM2] THEN + DISCH_THEN(MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + REAL_ABS_INTEGER_LEMMA)) THEN + REAL_ARITH_TAC);; + +let TAN_POS_PI2 = prove + (`!x. &0 < x /\ x < pi / &2 ==> &0 < tan x`, + REPEAT STRIP_TAC THEN REWRITE_TAC[tan] THEN + MATCH_MP_TAC REAL_LT_DIV THEN CONJ_TAC THENL + [MATCH_MP_TAC SIN_POS_PI; MATCH_MP_TAC COS_POS_PI] THEN + ASM_REAL_ARITH_TAC);; + +let TAN_POS_PI2_LE = prove + (`!x. &0 <= x /\ x < pi / &2 ==> &0 <= tan x`, + REWRITE_TAC[REAL_LE_LT] THEN MESON_TAC[TAN_0; TAN_POS_PI2]);; + +let COS_TAN = prove + (`!x. abs(x) < pi / &2 ==> cos(x) = &1 / sqrt(&1 + tan(x) pow 2)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC(REAL_FIELD + `sqrt(s) pow 2 = s /\ c pow 2 * s = &1 /\ ~(&1 + c * sqrt s = &0) + ==> c = &1 / sqrt s`) THEN + SUBGOAL_THEN `&0 < &1 + tan x pow 2` ASSUME_TAC THENL + [MP_TAC(SPEC `tan x` REAL_LE_SQUARE) THEN REAL_ARITH_TAC; ALL_TAC] THEN + ASM_SIMP_TAC[SQRT_POW_2; REAL_LT_IMP_LE] THEN CONJ_TAC THENL + [REWRITE_TAC[tan] THEN + MATCH_MP_TAC(REAL_FIELD + `s pow 2 + c pow 2 = &1 /\ &0 < c + ==> c pow 2 * (&1 + (s / c) pow 2) = &1`) THEN + ASM_SIMP_TAC[SIN_CIRCLE; COS_POS_PI; REAL_BOUNDS_LT]; + MATCH_MP_TAC(REAL_ARITH `&0 < x ==> ~(&1 + x = &0)`) THEN + ASM_SIMP_TAC[SIN_CIRCLE; COS_POS_PI; REAL_BOUNDS_LT; SQRT_POS_LT; + REAL_LT_MUL]]);; + +let SIN_TAN = prove + (`!x. abs(x) < pi / &2 ==> sin(x) = tan(x) / sqrt(&1 + tan(x) pow 2)`, + REPEAT STRIP_TAC THEN + ONCE_REWRITE_TAC[REAL_ARITH `a / b = a * &1 / b`] THEN + ASM_SIMP_TAC[GSYM COS_TAN] THEN + ASM_SIMP_TAC[tan; REAL_DIV_RMUL; REAL_LT_IMP_NZ; COS_POS_PI; + REAL_BOUNDS_LT]);; + +(* ------------------------------------------------------------------------- *) +(* Monotonicity theorems for the basic trig functions. *) +(* ------------------------------------------------------------------------- *) + +let SIN_MONO_LT = prove + (`!x y. --(pi / &2) <= x /\ x < y /\ y <= pi / &2 ==> sin(x) < sin(y)`, + REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[GSYM REAL_SUB_LT] THEN + REWRITE_TAC[REAL_SUB_SIN; REAL_ARITH `&0 < &2 * x <=> &0 < x`] THEN + MATCH_MP_TAC REAL_LT_MUL THEN CONJ_TAC THENL + [MATCH_MP_TAC SIN_POS_PI; MATCH_MP_TAC COS_POS_PI] THEN + ASM_REAL_ARITH_TAC);; + +let SIN_MONO_LE = prove + (`!x y. --(pi / &2) <= x /\ x <= y /\ y <= pi / &2 ==> sin(x) <= sin(y)`, + MESON_TAC[SIN_MONO_LT; REAL_LE_LT]);; + +let SIN_MONO_LT_EQ = prove + (`!x y. --(pi / &2) <= x /\ x <= pi / &2 /\ --(pi / &2) <= y /\ y <= pi / &2 + ==> (sin(x) < sin(y) <=> x < y)`, + MESON_TAC[REAL_NOT_LE; SIN_MONO_LT; SIN_MONO_LE]);; + +let SIN_MONO_LE_EQ = prove + (`!x y. --(pi / &2) <= x /\ x <= pi / &2 /\ --(pi / &2) <= y /\ y <= pi / &2 + ==> (sin(x) <= sin(y) <=> x <= y)`, + MESON_TAC[REAL_NOT_LE; SIN_MONO_LT; SIN_MONO_LE]);; + +let SIN_INJ_PI = prove + (`!x y. --(pi / &2) <= x /\ x <= pi / &2 /\ + --(pi / &2) <= y /\ y <= pi / &2 /\ + sin(x) = sin(y) + ==> x = y`, + REWRITE_TAC[GSYM REAL_LE_ANTISYM] THEN MESON_TAC[SIN_MONO_LE_EQ]);; + +let COS_MONO_LT = prove + (`!x y. &0 <= x /\ x < y /\ y <= pi ==> cos(y) < cos(x)`, + REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[GSYM REAL_SUB_LT] THEN + REWRITE_TAC[REAL_SUB_COS; REAL_ARITH `&0 < &2 * x <=> &0 < x`] THEN + MATCH_MP_TAC REAL_LT_MUL THEN CONJ_TAC THEN MATCH_MP_TAC SIN_POS_PI THEN + ASM_REAL_ARITH_TAC);; + +let COS_MONO_LE = prove + (`!x y. &0 <= x /\ x <= y /\ y <= pi ==> cos(y) <= cos(x)`, + MESON_TAC[COS_MONO_LT; REAL_LE_LT]);; + +let COS_MONO_LT_EQ = prove + (`!x y. &0 <= x /\ x <= pi /\ &0 <= y /\ y <= pi + ==> (cos(x) < cos(y) <=> y < x)`, + MESON_TAC[REAL_NOT_LE; COS_MONO_LT; COS_MONO_LE]);; + +let COS_MONO_LE_EQ = prove + (`!x y. &0 <= x /\ x <= pi /\ &0 <= y /\ y <= pi + ==> (cos(x) <= cos(y) <=> y <= x)`, + MESON_TAC[REAL_NOT_LE; COS_MONO_LT; COS_MONO_LE]);; + +let COS_INJ_PI = prove + (`!x y. &0 <= x /\ x <= pi /\ &0 <= y /\ y <= pi /\ cos(x) = cos(y) + ==> x = y`, + REWRITE_TAC[GSYM REAL_LE_ANTISYM] THEN MESON_TAC[COS_MONO_LE_EQ]);; + +let TAN_MONO_LT = prove + (`!x y. --(pi / &2) < x /\ x < y /\ y < pi / &2 ==> tan(x) < tan(y)`, + REPEAT STRIP_TAC THEN GEN_REWRITE_TAC I [GSYM REAL_SUB_LT] THEN + SUBGOAL_THEN `&0 < cos(x) /\ &0 < cos(y)` STRIP_ASSUME_TAC THENL + [CONJ_TAC THEN MATCH_MP_TAC COS_POS_PI; + ASM_SIMP_TAC[REAL_LT_IMP_NZ; REAL_SUB_TAN] THEN + MATCH_MP_TAC REAL_LT_DIV THEN ASM_SIMP_TAC[REAL_LT_MUL] THEN + MATCH_MP_TAC SIN_POS_PI] THEN + ASM_REAL_ARITH_TAC);; + +let TAN_MONO_LE = prove + (`!x y. --(pi / &2) < x /\ x <= y /\ y < pi / &2 ==> tan(x) <= tan(y)`, + REWRITE_TAC[REAL_LE_LT] THEN MESON_TAC[TAN_MONO_LT]);; + +let TAN_MONO_LT_EQ = prove + (`!x y. --(pi / &2) < x /\ x < pi / &2 /\ --(pi / &2) < y /\ y < pi / &2 + ==> (tan(x) < tan(y) <=> x < y)`, + MESON_TAC[REAL_NOT_LE; TAN_MONO_LT; TAN_MONO_LE]);; + +let TAN_MONO_LE_EQ = prove + (`!x y. --(pi / &2) < x /\ x < pi / &2 /\ --(pi / &2) < y /\ y < pi / &2 + ==> (tan(x) <= tan(y) <=> x <= y)`, + MESON_TAC[REAL_NOT_LE; TAN_MONO_LT; TAN_MONO_LE]);; + +let TAN_BOUND_PI2 = prove + (`!x. abs(x) < pi / &4 ==> abs(tan x) < &1`, + REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM TAN_PI4] THEN + REWRITE_TAC[GSYM TAN_NEG; REAL_ARITH `abs(x) < a <=> --a < x /\ x < a`] THEN + CONJ_TAC THEN MATCH_MP_TAC TAN_MONO_LT THEN + POP_ASSUM MP_TAC THEN REAL_ARITH_TAC);; + +let TAN_COT = prove + (`!x. tan(pi / &2 - x) = inv(tan x)`, + REWRITE_TAC[tan; SIN_SUB; COS_SUB; SIN_PI2; COS_PI2; REAL_INV_DIV] THEN + GEN_TAC THEN BINOP_TAC THEN REAL_ARITH_TAC);; + +(* ------------------------------------------------------------------------- *) +(* Approximation to pi. *) +(* ------------------------------------------------------------------------- *) + +let SIN_PI6_STRADDLE = prove + (`!a b. &0 <= a /\ a <= b /\ b <= &4 /\ + sin(a / &6) <= &1 / &2 /\ &1 / &2 <= sin(b / &6) + ==> a <= pi /\ pi <= b`, + REPEAT GEN_TAC THEN STRIP_TAC THEN + MP_TAC(SPECL [`pi / &6`; `b / &6`] SIN_MONO_LE_EQ) THEN + MP_TAC(SPECL [`a / &6`; `pi / &6`] SIN_MONO_LE_EQ) THEN + ASM_REWRITE_TAC[SIN_PI6] THEN + SUBGOAL_THEN `!x. &0 < x /\ x < &7 / &5 ==> &0 < sin x` + MP_TAC THENL + [REPEAT STRIP_TAC THEN MP_TAC(ISPECL [`0`; `Cx(x)`] TAYLOR_CSIN) THEN + REWRITE_TAC[VSUM_SING_NUMSEG] THEN CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[COMPLEX_DIV_1; COMPLEX_POW_1; complex_pow] THEN + REWRITE_TAC[COMPLEX_MUL_LID; GSYM CX_SIN; GSYM CX_SUB] THEN + REWRITE_TAC[IM_CX; COMPLEX_NORM_CX; REAL_ABS_NUM; REAL_EXP_0] THEN + MATCH_MP_TAC(REAL_ARITH + `e + d < a ==> abs(s - a) <= d ==> e < s`) THEN + ASM_SIMP_TAC[real_abs; real_pow; REAL_MUL_LID; REAL_LT_IMP_LE] THEN + SIMP_TAC[REAL_ARITH `&0 + x pow 3 / &2 < x <=> x * x pow 2 < x * &2`] THEN + ASM_SIMP_TAC[REAL_LT_LMUL_EQ] THEN + MATCH_MP_TAC REAL_LT_TRANS THEN EXISTS_TAC `(&7 / &5) pow 2` THEN + ASM_SIMP_TAC[REAL_POW_LT2; ARITH_EQ; REAL_LT_IMP_LE] THEN + CONV_TAC REAL_RAT_REDUCE_CONV; + DISCH_THEN(MP_TAC o SPEC `pi`) THEN + SIMP_TAC[SIN_PI; REAL_LT_REFL; PI_POS; REAL_NOT_LT] THEN + ASM_REAL_ARITH_TAC]);; + +let PI_APPROX_32 = prove + (`abs(pi - &13493037705 / &4294967296) <= inv(&2 pow 32)`, + REWRITE_TAC[REAL_ARITH `abs(x - a) <= e <=> a - e <= x /\ x <= a + e`] THEN + MATCH_MP_TAC SIN_PI6_STRADDLE THEN CONV_TAC REAL_RAT_REDUCE_CONV THEN + CONJ_TAC THENL + [MP_TAC(SPECL [`5`; `Cx(&1686629713 / &3221225472)`] TAYLOR_CSIN); + MP_TAC(SPECL [`5`; `Cx(&6746518853 / &12884901888)`] TAYLOR_CSIN)] THEN + CONV_TAC(ONCE_DEPTH_CONV EXPAND_VSUM_CONV) THEN CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[GSYM CX_POW; GSYM CX_DIV; GSYM CX_ADD; GSYM CX_SUB; + GSYM CX_NEG; GSYM CX_MUL; GSYM CX_SIN; COMPLEX_NORM_CX] THEN + REWRITE_TAC[IM_CX; REAL_ABS_NUM; REAL_EXP_0] THEN REAL_ARITH_TAC);; + +let PI2_BOUNDS = prove + (`&0 < pi / &2 /\ pi / &2 < &2`, + MP_TAC PI_APPROX_32 THEN REAL_ARITH_TAC);; + +(* ------------------------------------------------------------------------- *) +(* Complex logarithms (the conventional principal value). *) +(* ------------------------------------------------------------------------- *) + +let clog = new_definition + `clog z = @w. cexp(w) = z /\ --pi < Im(w) /\ Im(w) <= pi`;; + +let EXISTS_COMPLEX' = prove + (`!P. (?z. P (Re z) (Im z)) <=> ?x y. P x y`, + MESON_TAC[RE; IM; COMPLEX]);; + +let CLOG_WORKS = prove + (`!z. ~(z = Cx(&0)) + ==> cexp(clog z) = z /\ --pi < Im(clog z) /\ Im(clog z) <= pi`, + GEN_TAC THEN DISCH_TAC THEN REWRITE_TAC[clog] THEN CONV_TAC SELECT_CONV THEN + MP_TAC(SPEC `z / Cx(norm z)` COMPLEX_UNIMODULAR_POLAR) THEN ANTS_TAC THENL + [ASM_SIMP_TAC[COMPLEX_NORM_DIV; COMPLEX_NORM_CX] THEN + ASM_SIMP_TAC[REAL_ABS_NORM; REAL_DIV_REFL; COMPLEX_NORM_ZERO]; + ALL_TAC] THEN + DISCH_THEN(X_CHOOSE_THEN `x:real` STRIP_ASSUME_TAC) THEN + MP_TAC(SPEC `x:real` SINCOS_PRINCIPAL_VALUE) THEN + DISCH_THEN(X_CHOOSE_THEN `y:real` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `complex(log(norm(z:complex)),y)` THEN + ASM_REWRITE_TAC[RE; IM; CEXP_COMPLEX] THEN + REPEAT(FIRST_X_ASSUM(SUBST_ALL_TAC o SYM)) THEN + ASM_SIMP_TAC[EXP_LOG; COMPLEX_NORM_NZ; COMPLEX_DIV_LMUL; + COMPLEX_NORM_ZERO; CX_INJ]);; + +let CEXP_CLOG = prove + (`!z. ~(z = Cx(&0)) ==> cexp(clog z) = z`, + SIMP_TAC[CLOG_WORKS]);; + +let CLOG_CEXP = prove + (`!z. --pi < Im(z) /\ Im(z) <= pi ==> clog(cexp z) = z`, + REPEAT STRIP_TAC THEN REWRITE_TAC[clog] THEN + MATCH_MP_TAC SELECT_UNIQUE THEN X_GEN_TAC `w:complex` THEN + EQ_TAC THEN ASM_SIMP_TAC[] THEN REWRITE_TAC[CEXP_EQ] THEN + REWRITE_TAC[IMP_CONJ] THEN DISCH_THEN(X_CHOOSE_THEN `n:real` + (CONJUNCTS_THEN2 ASSUME_TAC SUBST1_TAC)) THEN + REWRITE_TAC[IM_ADD; IM_MUL_II; RE_CX] THEN REPEAT STRIP_TAC THEN + ASM_CASES_TAC `n = &0` THEN ASM_REWRITE_TAC[REAL_MUL_LZERO] THEN + REWRITE_TAC[REAL_MUL_RZERO; COMPLEX_ADD_RID; COMPLEX_MUL_LZERO] THEN + SUBGOAL_THEN `abs(n * pi) < &1 * pi` MP_TAC THENL + [ASM_REAL_ARITH_TAC; ALL_TAC] THEN + ASM_SIMP_TAC[REAL_ABS_MUL; REAL_LT_RMUL_EQ; PI_POS; REAL_ABS_PI] THEN + ASM_MESON_TAC[REAL_ABS_INTEGER_LEMMA; REAL_NOT_LT]);; + +let CLOG_EQ = prove + (`!w z. ~(w = Cx(&0)) /\ ~(z = Cx(&0)) ==> (clog w = clog z <=> w = z)`, + MESON_TAC[CEXP_CLOG]);; + +let CLOG_UNIQUE = prove + (`!w z. --pi < Im(z) /\ Im(z) <= pi /\ cexp(z) = w ==> clog w = z`, + MESON_TAC[CLOG_CEXP]);; + +let RE_CLOG = prove + (`!z. ~(z = Cx(&0)) ==> Re(clog z) = log(norm z)`, + REPEAT STRIP_TAC THEN FIRST_X_ASSUM + (MP_TAC o AP_TERM `norm:complex->real` o MATCH_MP CEXP_CLOG) THEN + REWRITE_TAC[NORM_CEXP] THEN DISCH_THEN(SUBST1_TAC o SYM) THEN + REWRITE_TAC[LOG_EXP]);; + +let EXISTS_COMPLEX_ROOT = prove + (`!a n. ~(n = 0) ==> ?z. z pow n = a`, + REPEAT STRIP_TAC THEN ASM_CASES_TAC `a = Cx(&0)` THENL + [EXISTS_TAC `Cx(&0)` THEN ASM_REWRITE_TAC[COMPLEX_POW_ZERO]; + EXISTS_TAC `cexp(clog(a) / Cx(&n))` THEN REWRITE_TAC[GSYM CEXP_N] THEN + ASM_SIMP_TAC[COMPLEX_DIV_LMUL; CX_INJ; REAL_OF_NUM_EQ; CEXP_CLOG]]);; + +(* ------------------------------------------------------------------------- *) +(* Derivative of clog away from the branch cut. *) +(* ------------------------------------------------------------------------- *) + +let HAS_COMPLEX_DERIVATIVE_CLOG = prove + (`!z. (Im(z) = &0 ==> &0 < Re(z)) + ==> (clog has_complex_derivative inv(z)) (at z)`, + REPEAT STRIP_TAC THEN + MATCH_MP_TAC HAS_COMPLEX_DERIVATIVE_INVERSE_STRONG_X THEN + EXISTS_TAC `cexp` THEN + EXISTS_TAC `{w | --pi < Im(w) /\ Im(w) < pi}` THEN + REWRITE_TAC[IN_ELIM_THM] THEN + ASM_CASES_TAC `z = Cx(&0)` THENL + [FIRST_X_ASSUM SUBST_ALL_TAC THEN POP_ASSUM MP_TAC THEN + ASM_REWRITE_TAC[RE_CX; IM_CX; REAL_LT_REFL]; + ALL_TAC] THEN + ASM_SIMP_TAC[CONTINUOUS_ON_CEXP; CEXP_CLOG; CLOG_CEXP; REAL_LT_IMP_LE] THEN + REPEAT CONJ_TAC THENL + [REWRITE_TAC[SET_RULE `{x | p x /\ q x} = {x | p x} INTER {x | q x}`] THEN + MATCH_MP_TAC OPEN_INTER THEN + REWRITE_TAC[REAL_ARITH `--x < w <=> w > --x`] THEN + REWRITE_TAC[OPEN_HALFSPACE_IM_LT; OPEN_HALFSPACE_IM_GT]; + ASM_SIMP_TAC[CLOG_WORKS]; + ASM_SIMP_TAC[CLOG_WORKS; REAL_LT_LE] THEN + DISCH_THEN(fun th -> + FIRST_X_ASSUM(SUBST_ALL_TAC o SYM o MATCH_MP CEXP_CLOG) THEN + POP_ASSUM MP_TAC THEN ASSUME_TAC th) THEN + ASM_REWRITE_TAC[EULER; COS_PI; SIN_PI; COMPLEX_MUL_RZERO] THEN + REWRITE_TAC[COMPLEX_ADD_RID; CX_NEG; COMPLEX_MUL_RNEG] THEN + REWRITE_TAC[COMPLEX_MUL_RID; IM_NEG; IM_CX; RE_NEG; RE_CX] THEN + MP_TAC(SPEC `Re(clog z)` REAL_EXP_POS_LT) THEN REAL_ARITH_TAC; + ASM_MESON_TAC[HAS_COMPLEX_DERIVATIVE_CEXP; CEXP_CLOG]]);; + +let COMPLEX_DIFFERENTIABLE_AT_CLOG = prove + (`!z. (Im(z) = &0 ==> &0 < Re(z)) ==> clog complex_differentiable at z`, + REWRITE_TAC[complex_differentiable] THEN + MESON_TAC[HAS_COMPLEX_DERIVATIVE_CLOG]);; + +let COMPLEX_DIFFERENTIABLE_WITHIN_CLOG = prove + (`!s z. (Im(z) = &0 ==> &0 < Re(z)) + ==> clog complex_differentiable (at z within s)`, + MESON_TAC[COMPLEX_DIFFERENTIABLE_AT_WITHIN; + COMPLEX_DIFFERENTIABLE_AT_CLOG]);; + +add_complex_differentiation_theorems + (CONJUNCTS(REWRITE_RULE[FORALL_AND_THM] + (MATCH_MP HAS_COMPLEX_DERIVATIVE_CHAIN + HAS_COMPLEX_DERIVATIVE_CLOG)));; + +let CONTINUOUS_AT_CLOG = prove + (`!z. (Im(z) = &0 ==> &0 < Re(z)) ==> clog continuous at z`, + MESON_TAC[HAS_COMPLEX_DERIVATIVE_CLOG; + HAS_COMPLEX_DERIVATIVE_IMP_CONTINUOUS_AT]);; + +let CONTINUOUS_WITHIN_CLOG = prove + (`!s z. (Im(z) = &0 ==> &0 < Re(z)) ==> clog continuous (at z within s)`, + MESON_TAC[CONTINUOUS_AT_WITHIN; CONTINUOUS_AT_CLOG]);; + +let CONTINUOUS_ON_CLOG = prove + (`!s. (!z. z IN s /\ Im(z) = &0 ==> &0 < Re(z)) ==> clog continuous_on s`, + MESON_TAC[CONTINUOUS_AT_IMP_CONTINUOUS_ON; CONTINUOUS_AT_CLOG]);; + +let HOLOMORPHIC_ON_CLOG = prove + (`!s. (!z. z IN s /\ Im(z) = &0 ==> &0 < Re(z)) ==> clog holomorphic_on s`, + REWRITE_TAC [holomorphic_on] THEN + MESON_TAC [HAS_COMPLEX_DERIVATIVE_AT_WITHIN; HAS_COMPLEX_DERIVATIVE_CLOG]);; + +(* ------------------------------------------------------------------------- *) +(* Relation to real log. *) +(* ------------------------------------------------------------------------- *) + +let CX_LOG = prove + (`!z. &0 < z ==> Cx(log z) = clog(Cx z)`, + REPEAT STRIP_TAC THEN FIRST_ASSUM(fun th -> + GEN_REWRITE_TAC (RAND_CONV o ONCE_DEPTH_CONV) + [SYM(MATCH_MP EXP_LOG th)]) THEN + REWRITE_TAC[CX_EXP] THEN CONV_TAC SYM_CONV THEN + MATCH_MP_TAC CLOG_CEXP THEN REWRITE_TAC[IM_CX] THEN + MP_TAC PI_POS THEN REAL_ARITH_TAC);; + +(* ------------------------------------------------------------------------- *) +(* Quadrant-type results for clog. *) +(* ------------------------------------------------------------------------- *) + +let RE_CLOG_POS_LT = prove + (`!z. ~(z = Cx(&0)) ==> (abs(Im(clog z)) < pi / &2 <=> &0 < Re(z))`, + GEN_TAC THEN DISCH_THEN(MP_TAC o MATCH_MP CLOG_WORKS) THEN + DISCH_THEN(CONJUNCTS_THEN2 + (fun th -> GEN_REWRITE_TAC (RAND_CONV o ONCE_DEPTH_CONV) [SYM th]) + MP_TAC) THEN + SIMP_TAC[RE_CEXP; REAL_LT_MUL_EQ; REAL_EXP_POS_LT] THEN + SPEC_TAC(`clog z`,`z:complex`) THEN GEN_TAC THEN + DISCH_THEN(MP_TAC o MATCH_MP (REAL_ARITH + `--p < x /\ x <= p + ==> --(p / &2) < x /\ x < p / &2 \/ + --(p / &2) <= p + x /\ p + x <= p / &2 \/ + --(p / &2) <= x - p /\ x - p <= p / &2`)) THEN + DISCH_THEN(REPEAT_TCL DISJ_CASES_THEN ASSUME_TAC) THEN + (FIRST_ASSUM(MP_TAC o MATCH_MP COS_POS_PI) ORELSE + FIRST_ASSUM(MP_TAC o MATCH_MP COS_POS_PI_LE)) THEN + REPEAT(POP_ASSUM MP_TAC) THEN + REWRITE_TAC[COS_ADD; COS_SUB; COS_PI; SIN_PI] THEN + REAL_ARITH_TAC);; + +let RE_CLOG_POS_LE = prove + (`!z. ~(z = Cx(&0)) ==> (abs(Im(clog z)) <= pi / &2 <=> &0 <= Re(z))`, + GEN_TAC THEN DISCH_THEN(MP_TAC o MATCH_MP CLOG_WORKS) THEN + DISCH_THEN(CONJUNCTS_THEN2 + (fun th -> GEN_REWRITE_TAC (RAND_CONV o ONCE_DEPTH_CONV) [SYM th]) + MP_TAC) THEN + SIMP_TAC[RE_CEXP; REAL_LE_MUL_EQ; REAL_EXP_POS_LT] THEN + SPEC_TAC(`clog z`,`z:complex`) THEN GEN_TAC THEN + DISCH_THEN(MP_TAC o MATCH_MP (REAL_ARITH + `--p < x /\ x <= p + ==> --(p / &2) <= x /\ x <= p / &2 \/ + --(p / &2) < p + x /\ p + x < p / &2 \/ + --(p / &2) < x - p /\ x - p < p / &2`)) THEN + DISCH_THEN(REPEAT_TCL DISJ_CASES_THEN ASSUME_TAC) THEN + (FIRST_ASSUM(MP_TAC o MATCH_MP COS_POS_PI) ORELSE + FIRST_ASSUM(MP_TAC o MATCH_MP COS_POS_PI_LE)) THEN + REPEAT(POP_ASSUM MP_TAC) THEN + REWRITE_TAC[COS_ADD; COS_SUB; COS_PI; SIN_PI] THEN + REAL_ARITH_TAC);; + +let IM_CLOG_POS_LT = prove + (`!z. ~(z = Cx(&0)) ==> (&0 < Im(clog z) /\ Im(clog z) < pi <=> &0 < Im(z))`, + GEN_TAC THEN DISCH_THEN(MP_TAC o MATCH_MP CLOG_WORKS) THEN + DISCH_THEN(CONJUNCTS_THEN2 + (fun th -> GEN_REWRITE_TAC (RAND_CONV o ONCE_DEPTH_CONV) [SYM th]) + MP_TAC) THEN + SIMP_TAC[IM_CEXP; REAL_LT_MUL_EQ; REAL_EXP_POS_LT] THEN + SPEC_TAC(`clog z`,`z:complex`) THEN GEN_TAC THEN + DISCH_THEN(MP_TAC o MATCH_MP (REAL_ARITH + `--p < x /\ x <= p + ==> &0 < x /\ x < p \/ + &0 <= x + p /\ x + p <= p \/ + &0 <= x - p /\ x - p <= p`)) THEN + DISCH_THEN(REPEAT_TCL DISJ_CASES_THEN ASSUME_TAC) THEN + (FIRST_ASSUM(MP_TAC o MATCH_MP SIN_POS_PI) ORELSE + FIRST_ASSUM(MP_TAC o MATCH_MP SIN_POS_PI_LE)) THEN + REPEAT(POP_ASSUM MP_TAC) THEN + REWRITE_TAC[SIN_ADD; SIN_SUB; COS_PI; SIN_PI] THEN + REAL_ARITH_TAC);; + +let IM_CLOG_POS_LE = prove + (`!z. ~(z = Cx(&0)) ==> (&0 <= Im(clog z) <=> &0 <= Im(z))`, + GEN_TAC THEN DISCH_THEN(MP_TAC o MATCH_MP CLOG_WORKS) THEN + DISCH_THEN(CONJUNCTS_THEN2 + (fun th -> GEN_REWRITE_TAC (RAND_CONV o ONCE_DEPTH_CONV) [SYM th]) + MP_TAC) THEN + SIMP_TAC[IM_CEXP; REAL_LE_MUL_EQ; REAL_EXP_POS_LT] THEN + SPEC_TAC(`clog z`,`z:complex`) THEN GEN_TAC THEN + DISCH_THEN(MP_TAC o MATCH_MP (REAL_ARITH + `--p < x /\ x <= p + ==> &0 <= x /\ x <= p \/ + &0 < x + p /\ x + p < p \/ + &0 < p - x /\ p - x < p`)) THEN + DISCH_THEN(REPEAT_TCL DISJ_CASES_THEN ASSUME_TAC) THEN + (FIRST_ASSUM(MP_TAC o MATCH_MP SIN_POS_PI) ORELSE + FIRST_ASSUM(MP_TAC o MATCH_MP SIN_POS_PI_LE)) THEN + REPEAT(POP_ASSUM MP_TAC) THEN + REWRITE_TAC[SIN_ADD; SIN_SUB; COS_PI; SIN_PI] THEN + REAL_ARITH_TAC);; + +let RE_CLOG_POS_LT_IMP = prove + (`!z. &0 < Re(z) ==> abs(Im(clog z)) < pi / &2`, + GEN_TAC THEN ASM_CASES_TAC `z = Cx(&0)` THEN + ASM_SIMP_TAC[RE_CLOG_POS_LT; RE_CX; REAL_LT_REFL]);; + +let IM_CLOG_POS_LT_IMP = prove + (`!z. &0 < Im(z) ==> &0 < Im(clog z) /\ Im(clog z) < pi`, + GEN_TAC THEN ASM_CASES_TAC `z = Cx(&0)` THEN + ASM_SIMP_TAC[IM_CLOG_POS_LT; IM_CX; REAL_LT_REFL]);; + +let IM_CLOG_EQ_0 = prove + (`!z. ~(z = Cx(&0)) ==> (Im(clog z) = &0 <=> &0 < Re(z) /\ Im(z) = &0)`, + REPEAT STRIP_TAC THEN + GEN_REWRITE_TAC (RAND_CONV o ONCE_DEPTH_CONV) + [REAL_ARITH `z = &0 <=> &0 <= z /\ ~(&0 < z)`] THEN + ASM_SIMP_TAC[GSYM RE_CLOG_POS_LT; GSYM IM_CLOG_POS_LE; + GSYM IM_CLOG_POS_LT] THEN + MP_TAC PI_POS THEN REAL_ARITH_TAC);; + +let IM_CLOG_EQ_PI = prove + (`!z. ~(z = Cx(&0)) ==> (Im(clog z) = pi <=> Re(z) < &0 /\ Im(z) = &0)`, + SIMP_TAC[PI_POS; RE_CLOG_POS_LE; IM_CLOG_POS_LE; IM_CLOG_POS_LT; CLOG_WORKS; + REAL_ARITH `&0 < pi ==> (x = pi <=> (&0 <= x /\ x <= pi) /\ + ~(abs x <= pi / &2) /\ ~(&0 < x /\ x < pi))`] THEN + REAL_ARITH_TAC);; + +(* ------------------------------------------------------------------------- *) +(* Various properties. *) +(* ------------------------------------------------------------------------- *) + +let CNJ_CLOG = prove + (`!z. (Im z = &0 ==> &0 < Re z) ==> cnj(clog z) = clog(cnj z)`, + GEN_TAC THEN ASM_CASES_TAC `z = Cx(&0)` THEN + ASM_REWRITE_TAC[RE_CX; IM_CX; REAL_LT_REFL] THEN + DISCH_TAC THEN MATCH_MP_TAC COMPLEX_EQ_CEXP THEN + REWRITE_TAC[GSYM CNJ_CEXP] THEN + ASM_SIMP_TAC[CEXP_CLOG; CNJ_EQ_CX; IM_CNJ] THEN + MATCH_MP_TAC(REAL_ARITH + `(--p < x /\ x <= p) /\ (--p < y /\ y <= p) /\ + ~(x = p /\ y = p) + ==> abs(--x - y) < &2 * p`) THEN + ASM_SIMP_TAC[IM_CLOG_EQ_PI; CNJ_EQ_CX; CLOG_WORKS] THEN + ASM_REAL_ARITH_TAC);; + +let CLOG_INV = prove + (`!z. (Im(z) = &0 ==> &0 < Re z) ==> clog(inv z) = --(clog z)`, + GEN_TAC THEN ASM_CASES_TAC `z = Cx(&0)` THEN + ASM_REWRITE_TAC[RE_CX; IM_CX; REAL_LT_REFL] THEN + STRIP_TAC THEN MATCH_MP_TAC COMPLEX_EQ_CEXP THEN + ASM_SIMP_TAC[CEXP_CLOG; CEXP_NEG; COMPLEX_INV_EQ_0] THEN + REWRITE_TAC[IM_NEG; REAL_SUB_RNEG] THEN + MATCH_MP_TAC(REAL_ARITH + `--pi < x /\ x <= pi /\ --pi < y /\ y <= pi /\ + ~(x = pi /\ y = pi) ==> abs(x + y) < &2 * pi`) THEN + ASM_SIMP_TAC[CLOG_WORKS; COMPLEX_INV_EQ_0; IM_CLOG_EQ_PI] THEN + UNDISCH_TAC `Im z = &0 ==> &0 < Re z` THEN + ASM_CASES_TAC `Im z = &0` THEN ASM_REWRITE_TAC[] THEN REAL_ARITH_TAC);; + +let CLOG_1 = prove + (`clog(Cx(&1)) = Cx(&0)`, + REWRITE_TAC[GSYM CEXP_0] THEN MATCH_MP_TAC CLOG_CEXP THEN + REWRITE_TAC[IM_CX] THEN MP_TAC PI_POS THEN REAL_ARITH_TAC);; + +let CLOG_NEG_1 = prove + (`clog(--Cx(&1)) = ii * Cx pi`, + MATCH_MP_TAC COMPLEX_EQ_CEXP THEN REWRITE_TAC[GSYM CX_NEG] THEN + SIMP_TAC[CEXP_EULER; GSYM CX_COS; GSYM CX_SIN; IM_MUL_II; IM_CX; RE_CX] THEN + REWRITE_TAC[COS_PI; SIN_PI; COMPLEX_MUL_RZERO; COMPLEX_ADD_RID] THEN + SIMP_TAC[CLOG_WORKS; COMPLEX_RING `~(Cx(-- &1) = Cx(&0))`; + REAL_ARITH `--pi < x /\ x <= pi ==> abs(x - pi) < &2 * pi`]);; + +let CLOG_II = prove + (`clog ii = ii * Cx(pi / &2)`, + MP_TAC(SPEC `ii * Cx(pi / &2)` CLOG_CEXP) THEN + SIMP_TAC[CEXP_EULER; GSYM CX_COS; GSYM CX_SIN; IM_MUL_II; IM_CX; RE_CX] THEN + REWRITE_TAC[COS_PI2; SIN_PI2] THEN ANTS_TAC THENL + [MP_TAC PI_POS THEN REAL_ARITH_TAC; + REWRITE_TAC[COMPLEX_ADD_LID; COMPLEX_MUL_RID]]);; + +let CLOG_NEG_II = prove + (`clog(--ii) = --ii * Cx(pi / &2)`, + GEN_REWRITE_TAC (LAND_CONV o RAND_CONV) [COMPLEX_FIELD `--ii = inv ii`] THEN + SIMP_TAC[CLOG_INV; RE_II; IM_II; REAL_OF_NUM_EQ; ARITH; CLOG_II] THEN + REWRITE_TAC[COMPLEX_MUL_LNEG]);; + +(* ------------------------------------------------------------------------- *) +(* Relation between square root and exp/log, and hence its derivative. *) +(* ------------------------------------------------------------------------- *) + +let CSQRT_CEXP_CLOG = prove + (`!z. ~(z = Cx(&0)) ==> csqrt z = cexp(clog(z) / Cx(&2))`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC CSQRT_UNIQUE THEN + REWRITE_TAC[GSYM CEXP_N; RE_CEXP; IM_CEXP] THEN + ASM_SIMP_TAC[COMPLEX_DIV_LMUL; CX_INJ; REAL_OF_NUM_EQ; ARITH; CEXP_CLOG] THEN + SIMP_TAC[REAL_LT_MUL_EQ; REAL_EXP_POS_LT; REAL_LE_MUL_EQ] THEN + REWRITE_TAC[REAL_ENTIRE; REAL_EXP_NZ; IM_DIV_CX] THEN + FIRST_ASSUM(STRIP_ASSUME_TAC o CONJUNCT2 o MATCH_MP CLOG_WORKS) THEN + FIRST_X_ASSUM(DISJ_CASES_TAC o REWRITE_RULE[REAL_LE_LT]) THENL + [DISJ1_TAC THEN MATCH_MP_TAC COS_POS_PI THEN + ASM_REAL_ARITH_TAC; + DISJ2_TAC THEN ASM_REWRITE_TAC[COS_PI2; SIN_PI2; REAL_POS]]);; + +let CNJ_CSQRT = prove + (`!z. (Im z = &0 ==> &0 <= Re(z)) ==> cnj(csqrt z) = csqrt(cnj z)`, + GEN_TAC THEN ASM_CASES_TAC `z = Cx(&0)` THEN + ASM_REWRITE_TAC[CSQRT_0; CNJ_CX] THEN DISCH_TAC THEN + SUBGOAL_THEN `Im z = &0 ==> &0 < Re(z)` ASSUME_TAC THENL + [REPEAT(POP_ASSUM MP_TAC) THEN + REWRITE_TAC[COMPLEX_EQ; IM_CX; RE_CX] THEN REAL_ARITH_TAC; + ASM_REWRITE_TAC[RE_CX; IM_CX; REAL_LT_REFL] THEN + ASM_SIMP_TAC[CSQRT_CEXP_CLOG; CNJ_CEXP; CNJ_CLOG; + CNJ_DIV; CNJ_EQ_CX; CNJ_CX]]);; + +let HAS_COMPLEX_DERIVATIVE_CSQRT = prove + (`!z. (Im z = &0 ==> &0 < Re(z)) + ==> (csqrt has_complex_derivative inv(Cx(&2) * csqrt z)) (at z)`, + GEN_TAC THEN ASM_CASES_TAC `z = Cx(&0)` THEN + ASM_REWRITE_TAC[IM_CX; RE_CX; REAL_LT_REFL] THEN DISCH_TAC THEN + MATCH_MP_TAC HAS_COMPLEX_DERIVATIVE_TRANSFORM_AT THEN + MAP_EVERY EXISTS_TAC [`\z. cexp(clog(z) / Cx(&2))`; `norm(z:complex)`] THEN + ASM_REWRITE_TAC[COMPLEX_NORM_NZ] THEN CONJ_TAC THENL + [REPEAT STRIP_TAC THEN CONV_TAC SYM_CONV THEN + MATCH_MP_TAC CSQRT_CEXP_CLOG THEN REWRITE_TAC[GSYM COMPLEX_VEC_0] THEN + REPEAT(POP_ASSUM MP_TAC) THEN NORM_ARITH_TAC; + COMPLEX_DIFF_TAC THEN ASM_SIMP_TAC[GSYM CSQRT_CEXP_CLOG] THEN + UNDISCH_TAC `~(z = Cx(&0))` THEN MP_TAC(SPEC `z:complex` CSQRT) THEN + CONV_TAC COMPLEX_FIELD]);; + +let COMPLEX_DIFFERENTIABLE_AT_CSQRT = prove + (`!z. (Im z = &0 ==> &0 < Re(z)) ==> csqrt complex_differentiable at z`, + REWRITE_TAC[complex_differentiable] THEN + MESON_TAC[HAS_COMPLEX_DERIVATIVE_CSQRT]);; + +let COMPLEX_DIFFERENTIABLE_WITHIN_CSQRT = prove + (`!s z. (Im z = &0 ==> &0 < Re(z)) + ==> csqrt complex_differentiable (at z within s)`, + MESON_TAC[COMPLEX_DIFFERENTIABLE_AT_WITHIN; + COMPLEX_DIFFERENTIABLE_AT_CSQRT]);; + +add_complex_differentiation_theorems + (CONJUNCTS(REWRITE_RULE[FORALL_AND_THM] + (MATCH_MP HAS_COMPLEX_DERIVATIVE_CHAIN + HAS_COMPLEX_DERIVATIVE_CSQRT)));; + +let CONTINUOUS_AT_CSQRT = prove + (`!z. (Im z = &0 ==> &0 < Re(z)) ==> csqrt continuous at z`, + MESON_TAC[HAS_COMPLEX_DERIVATIVE_CSQRT; + HAS_COMPLEX_DERIVATIVE_IMP_CONTINUOUS_AT]);; + +let CONTINUOUS_WITHIN_CSQRT = prove + (`!s z. (Im z = &0 ==> &0 < Re(z)) ==> csqrt continuous (at z within s)`, + MESON_TAC[CONTINUOUS_AT_WITHIN; CONTINUOUS_AT_CSQRT]);; + +let CONTINUOUS_ON_CSQRT = prove + (`!s. (!z. z IN s /\ Im z = &0 ==> &0 < Re(z)) ==> csqrt continuous_on s`, + MESON_TAC[CONTINUOUS_AT_IMP_CONTINUOUS_ON; CONTINUOUS_AT_CSQRT]);; + +let HOLOMORPHIC_ON_CSQRT = prove + (`!s. (!z. z IN s /\ Im(z) = &0 ==> &0 < Re(z)) ==> csqrt holomorphic_on s`, + REWRITE_TAC [holomorphic_on] THEN + MESON_TAC [HAS_COMPLEX_DERIVATIVE_AT_WITHIN; HAS_COMPLEX_DERIVATIVE_CSQRT]);; + +let CONTINUOUS_WITHIN_CSQRT_POSREAL = prove + (`!z. csqrt continuous (at z within {w | real w /\ &0 <= Re(w)})`, + REPEAT STRIP_TAC THEN ASM_CASES_TAC `Im z = &0 ==> &0 < Re(z)` THENL + [ASM_SIMP_TAC[CONTINUOUS_WITHIN_CSQRT]; ALL_TAC] THEN + POP_ASSUM MP_TAC THEN REWRITE_TAC[NOT_IMP; REAL_NOT_LT] THEN + REWRITE_TAC[REAL_ARITH `x <= &0 <=> x < &0 \/ x = &0`] THEN STRIP_TAC THENL + [MATCH_MP_TAC CONTINUOUS_WITHIN_CLOSED_NONTRIVIAL THEN + REWRITE_TAC[SET_RULE `{x | P x /\ Q x} = {x | P x} INTER {x | Q x}`] THEN + SIMP_TAC[CLOSED_REAL_SET; CLOSED_INTER; IN_INTER; IN_ELIM_THM; + REWRITE_RULE[real_ge] CLOSED_HALFSPACE_RE_GE] THEN + ASM_REAL_ARITH_TAC; + SUBGOAL_THEN `z = Cx(&0)` SUBST_ALL_TAC THENL + [ASM_REWRITE_TAC[COMPLEX_EQ; RE_CX; IM_CX]; ALL_TAC] THEN + REWRITE_TAC[continuous_within] THEN + REWRITE_TAC[IN_ELIM_THM; IMP_CONJ; FORALL_REAL; RE_CX] THEN + SIMP_TAC[GSYM CX_SQRT; REAL_LE_REFL] THEN + SIMP_TAC[dist; GSYM CX_SUB; COMPLEX_NORM_CX; SQRT_0; REAL_SUB_RZERO] THEN + X_GEN_TAC `e:real` THEN STRIP_TAC THEN EXISTS_TAC `(e:real) pow 2` THEN + ASM_SIMP_TAC[REAL_POW_LT] THEN REPEAT STRIP_TAC THEN + SUBGOAL_THEN `e = sqrt(e pow 2)` SUBST1_TAC THENL + [ASM_SIMP_TAC[POW_2_SQRT; REAL_LT_IMP_LE]; + ASM_SIMP_TAC[real_abs; SQRT_POS_LE]] THEN + MATCH_MP_TAC SQRT_MONO_LT THEN ASM_REAL_ARITH_TAC]);; + +(* ------------------------------------------------------------------------- *) +(* Complex powers. *) +(* ------------------------------------------------------------------------- *) + +parse_as_infix("cpow",(24,"left"));; + +let cpow = new_definition + `w cpow z = if w = Cx(&0) then Cx(&0) + else cexp(z * clog w)`;; + +let CPOW_0 = prove + (`!z. Cx(&0) cpow z = Cx(&0)`, + REWRITE_TAC[cpow]);; + +let CPOW_N = prove + (`!z. z cpow (Cx(&n)) = if z = Cx(&0) then Cx(&0) else z pow n`, + GEN_TAC THEN REWRITE_TAC[cpow] THEN COND_CASES_TAC THEN + ASM_SIMP_TAC[CEXP_N; CEXP_CLOG]);; + +let CPOW_1 = prove + (`!z. Cx(&1) cpow z = Cx(&1)`, + REWRITE_TAC[cpow; CX_INJ; REAL_OF_NUM_EQ; ARITH_EQ; CLOG_1] THEN + REWRITE_TAC[CEXP_0; COMPLEX_MUL_RZERO]);; + +let CPOW_ADD = prove + (`!w z1 z2. w cpow (z1 + z2) = w cpow z1 * w cpow z2`, + REPEAT GEN_TAC THEN REWRITE_TAC[cpow] THEN + ASM_CASES_TAC `w = Cx(&0)` THEN ASM_REWRITE_TAC[COMPLEX_MUL_RZERO] THEN + REWRITE_TAC[COMPLEX_ADD_RDISTRIB; CEXP_ADD]);; + +let CPOW_NEG = prove + (`!w z. w cpow (--z) = inv(w cpow z)`, + REPEAT GEN_TAC THEN REWRITE_TAC[cpow] THEN ASM_CASES_TAC `w = Cx(&0)` THEN + ASM_REWRITE_TAC[COMPLEX_MUL_RZERO; COMPLEX_INV_0] THEN + REWRITE_TAC[COMPLEX_MUL_LNEG; CEXP_NEG]);; + +let CPOW_SUB = prove + (`!w z1 z2. w cpow (z1 - z2) = w cpow z1 / w cpow z2`, + REWRITE_TAC[complex_sub; complex_div; CPOW_ADD; CPOW_NEG]);; + +let CPOW_EQ_0 = prove + (`!w z. w cpow z = Cx(&0) <=> w = Cx(&0)`, + REPEAT GEN_TAC THEN REWRITE_TAC[cpow] THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[CEXP_NZ]);; + +let NORM_CPOW_REAL = prove + (`!w z. real w /\ &0 < Re w ==> norm(w cpow z) = exp(Re z * log(Re w))`, + REPEAT STRIP_TAC THEN + FIRST_X_ASSUM(SUBST_ALL_TAC o SYM o GEN_REWRITE_RULE I [REAL]) THEN + RULE_ASSUM_TAC(REWRITE_RULE[RE_CX]) THEN + ASM_SIMP_TAC[cpow; CX_INJ; REAL_LT_IMP_NZ] THEN + ASM_SIMP_TAC[NORM_CEXP; GSYM CX_LOG; RE_MUL_CX; RE_CX]);; + +let CPOW_REAL_REAL = prove + (`!w z. real w /\ real z /\ &0 < Re w + ==> w cpow z = Cx(exp(Re z * log(Re w)))`, + REPEAT STRIP_TAC THEN + REPEAT(FIRST_X_ASSUM(SUBST_ALL_TAC o SYM o GEN_REWRITE_RULE I [REAL])) THEN + RULE_ASSUM_TAC(REWRITE_RULE[RE_CX]) THEN + ASM_SIMP_TAC[cpow; CX_INJ; REAL_LT_IMP_NZ] THEN + ASM_SIMP_TAC[NORM_CEXP; GSYM CX_LOG; RE_MUL_CX; RE_CX; CX_EXP; CX_MUL]);; + +let NORM_CPOW_REAL_MONO = prove + (`!w z1 z2. real w /\ &1 < Re w + ==> (norm(w cpow z1) <= norm(w cpow z2) <=> Re(z1) <= Re(z2))`, + SIMP_TAC[NORM_CPOW_REAL; REAL_ARITH `&1 < x ==> &0 < x`] THEN + SIMP_TAC[REAL_EXP_MONO_LE; REAL_LE_RMUL_EQ; LOG_POS_LT]);; + +let CPOW_MUL_REAL = prove + (`!x y z. real x /\ real y /\ &0 <= Re x /\ &0 <= Re y + ==> (x * y) cpow z = x cpow z * y cpow z`, + REPEAT STRIP_TAC THEN + REPEAT(FIRST_X_ASSUM(SUBST_ALL_TAC o SYM o GEN_REWRITE_RULE I [REAL])) THEN + REPEAT(POP_ASSUM MP_TAC) THEN REWRITE_TAC[RE_CX; IM_CX] THEN + REWRITE_TAC[REAL_ARITH `&0 <= x <=> x = &0 \/ &0 < x`] THEN + REPEAT STRIP_TAC THEN + ASM_REWRITE_TAC[COMPLEX_MUL_LZERO; COMPLEX_MUL_RZERO; CPOW_0] THEN + ASM_SIMP_TAC[cpow; COMPLEX_ENTIRE; CX_INJ; REAL_LT_IMP_NZ] THEN + REWRITE_TAC[GSYM CEXP_ADD; GSYM COMPLEX_ADD_LDISTRIB] THEN + ASM_SIMP_TAC[GSYM CX_LOG; GSYM CX_ADD; GSYM CX_MUL; REAL_LT_MUL] THEN + ASM_SIMP_TAC[LOG_MUL]);; + +let HAS_COMPLEX_DERIVATIVE_CPOW = prove + (`!s z. (Im z = &0 ==> &0 < Re z) + ==> ((\z. z cpow s) has_complex_derivative + (s * z cpow (s - Cx(&1)))) (at z)`, + REPEAT GEN_TAC THEN ASM_CASES_TAC `z = Cx(&0)` THEN + ASM_REWRITE_TAC[IM_CX; RE_CX; REAL_LT_REFL] THEN + REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[cpow] THEN + MATCH_MP_TAC HAS_COMPLEX_DERIVATIVE_TRANSFORM_AT THEN + MAP_EVERY EXISTS_TAC [`\z. cexp (s * clog z)`; `norm(z:complex)`] THEN + ASM_REWRITE_TAC[COMPLEX_NORM_NZ] THEN CONJ_TAC THENL + [GEN_TAC THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[dist] THEN + REWRITE_TAC[COMPLEX_SUB_LZERO; NORM_NEG; REAL_LT_REFL]; + COMPLEX_DIFF_TAC THEN ASM_REWRITE_TAC[CEXP_SUB; COMPLEX_SUB_RDISTRIB] THEN + ASM_SIMP_TAC[CEXP_CLOG; COMPLEX_MUL_LID] THEN + REPEAT(POP_ASSUM MP_TAC) THEN CONV_TAC COMPLEX_FIELD]);; + +add_complex_differentiation_theorems + (CONJUNCTS(REWRITE_RULE[FORALL_AND_THM] + (GEN `s:complex` + (MATCH_MP HAS_COMPLEX_DERIVATIVE_CHAIN + (SPEC `s:complex` HAS_COMPLEX_DERIVATIVE_CPOW)))));; + +let HAS_COMPLEX_DERIVATIVE_CPOW_RIGHT = prove + (`!w z. ~(w = Cx(&0)) + ==> ((\z. w cpow z) has_complex_derivative clog(w) * w cpow z) (at z)`, + REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[cpow] THEN + COMPLEX_DIFF_TAC THEN REWRITE_TAC[COMPLEX_MUL_LID]);; + +add_complex_differentiation_theorems + (CONJUNCTS(REWRITE_RULE[FORALL_AND_THM] + (GEN `s:complex` + (MATCH_MP HAS_COMPLEX_DERIVATIVE_CHAIN + (SPEC `s:complex` HAS_COMPLEX_DERIVATIVE_CPOW_RIGHT)))));; + +let COMPLEX_DIFFERENTIABLE_CPOW_RIGHT = prove + (`!w z. ~(w = Cx(&0)) ==> (\z. w cpow z) complex_differentiable (at z)`, + REWRITE_TAC[complex_differentiable] THEN + MESON_TAC[HAS_COMPLEX_DERIVATIVE_CPOW_RIGHT]);; + +let HOLOMORPHIC_ON_CPOW_RIGHT = prove + (`!w f s. ~(w = Cx(&0)) /\ f holomorphic_on s + ==> (\z. w cpow (f z)) holomorphic_on s`, + REPEAT STRIP_TAC THEN GEN_REWRITE_TAC LAND_CONV [GSYM o_DEF] THEN + MATCH_MP_TAC HOLOMORPHIC_ON_COMPOSE THEN ASM_REWRITE_TAC[] THEN + GEN_REWRITE_TAC LAND_CONV [GSYM ETA_AX] THEN + REWRITE_TAC[holomorphic_on; GSYM complex_differentiable] THEN + ASM_SIMP_TAC[COMPLEX_DIFFERENTIABLE_CPOW_RIGHT; + COMPLEX_DIFFERENTIABLE_AT_WITHIN]);; + +(* ------------------------------------------------------------------------- *) +(* Product rule. *) +(* ------------------------------------------------------------------------- *) + +let CLOG_MUL = prove + (`!w z. ~(w = Cx(&0)) /\ ~(z = Cx(&0)) + ==> clog(w * z) = + if Im(clog w + clog z) <= --pi then + (clog(w) + clog(z)) + ii * Cx(&2 * pi) + else if Im(clog w + clog z) > pi then + (clog(w) + clog(z)) - ii * Cx(&2 * pi) + else clog(w) + clog(z)`, + REPEAT STRIP_TAC THEN + REPEAT(COND_CASES_TAC THEN ASM_REWRITE_TAC[]) THEN + MATCH_MP_TAC CLOG_UNIQUE THEN + ASM_SIMP_TAC[CEXP_ADD; CEXP_SUB; CEXP_EULER; CEXP_CLOG; CONJ_ASSOC; + GSYM CX_SIN; GSYM CX_COS; COS_NPI; SIN_NPI] THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN + TRY(CONJ_TAC THENL [ALL_TAC; CONV_TAC COMPLEX_FIELD]) THEN + REPEAT(FIRST_X_ASSUM(MP_TAC o MATCH_MP CLOG_WORKS)) THEN + REPEAT(POP_ASSUM MP_TAC) THEN + REWRITE_TAC[IM_ADD; IM_SUB; IM_MUL_II; RE_CX] THEN + REAL_ARITH_TAC);; + +let CLOG_MUL_SIMPLE = prove + (`!w z. ~(w = Cx(&0)) /\ ~(z = Cx(&0)) /\ + --pi < Im(clog(w)) + Im(clog(z)) /\ + Im(clog(w)) + Im(clog(z)) <= pi + ==> clog(w * z) = clog(w) + clog(z)`, + SIMP_TAC[CLOG_MUL; IM_ADD] THEN REAL_ARITH_TAC);; + +let CLOG_NEG = prove + (`!z. ~(z = Cx(&0)) + ==> clog(--z) = if Im(z) <= &0 /\ ~(Re(z) < &0 /\ Im(z) = &0) + then clog(z) + ii * Cx(pi) + else clog(z) - ii * Cx(pi)`, + REPEAT STRIP_TAC THEN + SUBST1_TAC(SIMPLE_COMPLEX_ARITH `--z = --Cx(&1) * z`) THEN + ASM_SIMP_TAC[CLOG_MUL; COMPLEX_RING `~(--Cx(&1) = Cx(&0))`] THEN + REWRITE_TAC[CLOG_NEG_1; IM_ADD; IM_MUL_II; RE_CX] THEN + ASM_SIMP_TAC[CLOG_WORKS; REAL_ARITH + `--p < x /\ x <= p ==> ~(p + x <= --p)`] THEN + REWRITE_TAC[REAL_ARITH `p + x > p <=> &0 < x`] THEN + ASM_SIMP_TAC[GSYM IM_CLOG_EQ_PI] THEN + ONCE_REWRITE_TAC[REAL_ARITH `Im z <= &0 <=> ~(&0 < Im z)`] THEN + ASM_SIMP_TAC[GSYM IM_CLOG_POS_LT] THEN + ASM_SIMP_TAC[CLOG_WORKS; REAL_ARITH `x <= p ==> (x < p <=> ~(x = p))`] THEN + REWRITE_TAC[TAUT `~(a /\ ~b) /\ ~b <=> ~a /\ ~b`] THEN + ASM_CASES_TAC `Im(clog z) = pi` THEN ASM_REWRITE_TAC[PI_POS] THEN + ASM_CASES_TAC `&0 < Im(clog z)` THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[CX_MUL] THEN CONV_TAC COMPLEX_RING);; + +let CLOG_MUL_II = prove + (`!z. ~(z = Cx(&0)) + ==> clog(ii * z) = if &0 <= Re(z) \/ Im(z) < &0 + then clog(z) + ii * Cx(pi / &2) + else clog(z) - ii * Cx(&3 * pi / &2)`, + REPEAT STRIP_TAC THEN ASM_SIMP_TAC[CLOG_MUL; II_NZ; CLOG_II] THEN + REWRITE_TAC[IM_ADD; IM_MUL_II; RE_CX] THEN + ASM_SIMP_TAC[CLOG_WORKS; REAL_ARITH + `--p < x /\ x <= p ==> ~(p / &2 + x <= --p)`] THEN + REWRITE_TAC[REAL_ARITH `p / &2 + x > p <=> p / &2 < x`] THEN + REWRITE_TAC[REAL_ARITH `Im z < &0 <=> ~(&0 <= Im z)`] THEN + ASM_SIMP_TAC[GSYM RE_CLOG_POS_LE; GSYM IM_CLOG_POS_LE] THEN + MATCH_MP_TAC(MESON[] + `(p <=> ~q) /\ x = a /\ y = b + ==> ((if p then x else y) = (if q then b else a))`) THEN + CONJ_TAC THENL + [MP_TAC PI_POS THEN REAL_ARITH_TAC; + REWRITE_TAC[CX_MUL; CX_DIV] THEN CONV_TAC COMPLEX_RING]);; + +(* ------------------------------------------------------------------------- *) +(* Unwinding number gives another version of log-product formula. *) +(* Note that in this special case the unwinding number is -1, 0 or 1. *) +(* ------------------------------------------------------------------------- *) + +let unwinding = new_definition + `unwinding(z) = (z - clog(cexp z)) / (Cx(&2 * pi) * ii)`;; + +let UNWINDING_2PI = prove + (`Cx(&2 * pi) * ii * unwinding(z) = z - clog(cexp z)`, + REWRITE_TAC[unwinding; COMPLEX_MUL_ASSOC] THEN + MATCH_MP_TAC COMPLEX_DIV_LMUL THEN + REWRITE_TAC[COMPLEX_ENTIRE; CX_INJ; II_NZ] THEN + MP_TAC PI_POS THEN REAL_ARITH_TAC);; + +let CLOG_MUL_UNWINDING = prove + (`!w z. ~(w = Cx(&0)) /\ ~(z = Cx(&0)) + ==> clog(w * z) = + clog(w) + clog(z) - + Cx(&2 * pi) * ii * unwinding(clog w + clog z)`, + REWRITE_TAC[UNWINDING_2PI; + COMPLEX_RING `w + z - ((w + z) - c) = c:complex`] THEN + ASM_SIMP_TAC[CEXP_ADD; CEXP_CLOG]);; + +(* ------------------------------------------------------------------------- *) +(* Complex arctangent (branch cut gives standard bounds in real case). *) +(* ------------------------------------------------------------------------- *) + +let catn = new_definition + `catn z = (ii / Cx(&2)) * clog((Cx(&1) - ii * z) / (Cx(&1) + ii * z))`;; + +let IM_COMPLEX_DIV_LEMMA = prove + (`!z. Im((Cx(&1) - ii * z) / (Cx(&1) + ii * z)) = &0 <=> Re z = &0`, + REWRITE_TAC[IM_COMPLEX_DIV_EQ_0] THEN + REWRITE_TAC[complex_mul; IM; RE; IM_CNJ; RE_CNJ; RE_CX; IM_CX; RE_II; IM_II; + RE_SUB; RE_ADD; IM_SUB; IM_ADD] THEN + REAL_ARITH_TAC);; + +let RE_COMPLEX_DIV_LEMMA = prove + (`!z. &0 < Re((Cx(&1) - ii * z) / (Cx(&1) + ii * z)) <=> norm(z) < &1`, + REWRITE_TAC[RE_COMPLEX_DIV_GT_0; NORM_LT_SQUARE; REAL_LT_01] THEN + REWRITE_TAC[GSYM NORM_POW_2; COMPLEX_SQNORM] THEN + REWRITE_TAC[complex_mul; IM; RE; IM_CNJ; RE_CNJ; RE_CX; IM_CX; RE_II; IM_II; + RE_SUB; RE_ADD; IM_SUB; IM_ADD] THEN + REAL_ARITH_TAC);; + +let CTAN_CATN = prove + (`!z. ~(z pow 2 = --Cx(&1)) ==> ctan(catn z) = z`, + REPEAT STRIP_TAC THEN + REWRITE_TAC[catn; ctan; csin; ccos; + COMPLEX_RING `--i * i / Cx(&2) * z = --(i * i) / Cx(&2) * z`; + COMPLEX_RING `i * i / Cx(&2) * z = (i * i) / Cx(&2) * z`] THEN + REWRITE_TAC[COMPLEX_POW_II_2; GSYM COMPLEX_POW_2] THEN + REWRITE_TAC[COMPLEX_RING `--Cx(&1) / Cx(&2) * x = --(Cx(&1) / Cx(&2) * x)`; + CEXP_NEG] THEN + SUBGOAL_THEN + `~(cexp(Cx(&1) / Cx(&2) * + (clog((Cx(&1) - ii * z) / (Cx(&1) + ii * z)))) pow 2 = --Cx(&1))` + ASSUME_TAC THENL + [REWRITE_TAC[GSYM CEXP_N; CEXP_SUB; COMPLEX_RING + `Cx(&2) * Cx(&1) / Cx(&2) * z = z`] THEN + ASM_SIMP_TAC[CEXP_CLOG; COMPLEX_POW_II_2; + COMPLEX_FIELD `~(w = Cx(&0)) /\ ~(z = Cx(&0)) ==> ~(w / z = Cx(&0))`; + COMPLEX_FIELD `~(w = Cx(&0)) ==> (x / w = y <=> x = y * w)`; + COMPLEX_FIELD + `ii pow 2 = --Cx(&1) /\ ~(z pow 2 = --Cx(&1)) + ==> ~(Cx(&1) - ii * z = Cx(&0)) /\ ~(Cx(&1) + ii * z = Cx(&0))`] THEN + POP_ASSUM MP_TAC THEN CONV_TAC COMPLEX_FIELD; + ALL_TAC] THEN + REWRITE_TAC[COMPLEX_RING `-- --Cx (&1) / Cx (&2) = Cx(&1) / Cx(&2)`] THEN + ASM_SIMP_TAC[CEXP_NZ; COMPLEX_FIELD + `~(z = Cx(&0)) /\ ~(z pow 2 = --Cx(&1)) + ==> ((inv(z) - z) / (Cx(&2) * ii)) / ((inv(z) + z) / Cx(&2)) = + inv ii * ((Cx(&1) - z pow 2) / (Cx(&1) + z pow 2))`] THEN + ASM_SIMP_TAC[GSYM CEXP_N; CEXP_SUB; + COMPLEX_RING `Cx(&2) * Cx(&1) / Cx(&2) * z = z`] THEN + ASM_SIMP_TAC[CEXP_CLOG; COMPLEX_FIELD + `~(z pow 2 = --Cx(&1)) + ==> ~((Cx(&1) - ii * z) / (Cx(&1) + ii * z) = Cx(&0))`] THEN + UNDISCH_TAC `~(z pow 2 = --Cx(&1))` THEN CONV_TAC COMPLEX_FIELD);; + +let CATN_CTAN = prove + (`!z. abs(Re z) < pi / &2 ==> catn(ctan z) = z`, + REPEAT STRIP_TAC THEN REWRITE_TAC[catn; ctan; csin; ccos] THEN + ASM_SIMP_TAC[COMPLEX_FIELD + `ii * (a / (Cx(&2) * ii)) / (b / Cx(&2)) = a / b`] THEN + SIMP_TAC[COMPLEX_FIELD + `ii / Cx(&2) * x = y <=> x = Cx(&2) * --(ii * y)`] THEN + SUBGOAL_THEN `~(cexp(ii * z) pow 2 = --Cx(&1))` ASSUME_TAC THENL + [SUBGOAL_THEN `--Cx(&1) = cexp(ii * Cx pi)` SUBST1_TAC THENL + [REWRITE_TAC[CEXP_EULER; GSYM CX_SIN; GSYM CX_COS; SIN_PI; COS_PI] THEN + CONV_TAC COMPLEX_RING; + ALL_TAC] THEN + REWRITE_TAC[GSYM CEXP_N; CEXP_EQ] THEN + DISCH_THEN(X_CHOOSE_THEN `n:real` STRIP_ASSUME_TAC) THEN + FIRST_X_ASSUM(MP_TAC o AP_TERM `Im`) THEN + REWRITE_TAC[IM_MUL_CX; IM_MUL_II; IM_ADD; RE_CX; IM_II; REAL_MUL_RID] THEN + MATCH_MP_TAC(REAL_ARITH + `abs(z) < p / &2 /\ (w = &0 \/ abs(w) >= &2 * p) + ==> ~(&2 * z = p + w)`) THEN + ASM_REWRITE_TAC[REAL_ABS_MUL; REAL_ABS_PI; REAL_ABS_NUM] THEN + SIMP_TAC[real_ge; REAL_MUL_ASSOC; REAL_LE_RMUL_EQ; PI_POS] THEN + REWRITE_TAC[REAL_ENTIRE; PI_NZ] THEN + MP_TAC(SPEC `n:real` REAL_ABS_INTEGER_LEMMA) THEN + ASM_REWRITE_TAC[] THEN REAL_ARITH_TAC; + ASM_SIMP_TAC[CEXP_NEG; CEXP_NZ; COMPLEX_MUL_LNEG; COMPLEX_FIELD + `~(w = Cx(&0)) /\ ~(w pow 2 = --Cx(&1)) + ==> (Cx(&1) - (w - inv w) / (w + inv w)) / + (Cx(&1) + (w - inv w) / (w + inv w)) = + inv(w) pow 2`] THEN + REWRITE_TAC[GSYM CEXP_N; GSYM CEXP_NEG] THEN + MATCH_MP_TAC CLOG_CEXP THEN REWRITE_TAC[IM_MUL_CX; IM_NEG; IM_MUL_II] THEN + ASM_REAL_ARITH_TAC]);; + +let RE_CATN_BOUNDS = prove + (`!z. (Re z = &0 ==> abs(Im z) < &1) ==> abs(Re(catn z)) < pi / &2`, + REWRITE_TAC[catn; complex_div; GSYM CX_INV; GSYM COMPLEX_MUL_ASSOC] THEN + REPEAT STRIP_TAC THEN REWRITE_TAC[RE_MUL_II; IM_MUL_CX] THEN + MATCH_MP_TAC(REAL_ARITH `abs x < p ==> abs(--(inv(&2) * x)) < p / &2`) THEN + MATCH_MP_TAC(REAL_ARITH `(--p < x /\ x <= p) /\ ~(x = p) ==> abs x < p`) THEN + SUBGOAL_THEN `~(z = ii) /\ ~(z = --ii)` STRIP_ASSUME_TAC THENL + [CONJ_TAC THEN + DISCH_THEN(fun th -> POP_ASSUM MP_TAC THEN SUBST1_TAC th) THEN + REWRITE_TAC[RE_II; IM_II; RE_NEG; IM_NEG] THEN REAL_ARITH_TAC; + ALL_TAC] THEN + REWRITE_TAC[GSYM complex_div] THEN CONJ_TAC THENL + [SUBGOAL_THEN `~((Cx(&1) - ii * z) / (Cx(&1) + ii * z) = Cx(&0))` + (fun th -> MESON_TAC[th; CLOG_WORKS]) THEN + REPEAT(POP_ASSUM MP_TAC) THEN CONV_TAC COMPLEX_FIELD; + ALL_TAC] THEN + DISCH_TAC THEN + MP_TAC(ISPEC `clog((Cx(&1) - ii * z) / (Cx(&1) + ii * z))` EULER) THEN + ASM_REWRITE_TAC[SIN_PI; COS_PI; CX_NEG] THEN + REWRITE_TAC[COMPLEX_RING + `x = y * (--Cx(&1) + z * Cx(&0)) <=> x + y = Cx(&0)`] THEN + REWRITE_TAC[CX_EXP] THEN + ASM_SIMP_TAC[CEXP_CLOG; COMPLEX_FIELD + `~(z = ii) /\ ~(z = --ii) + ==> ~((Cx(&1) - ii * z) / (Cx(&1) + ii * z) = Cx(&0))`] THEN + REWRITE_TAC[GSYM CX_EXP] THEN DISCH_THEN(MP_TAC o AP_TERM `Im`) THEN + REWRITE_TAC[IM_ADD; IM_CX; REAL_ADD_RID; IM_COMPLEX_DIV_LEMMA] THEN + DISCH_TAC THEN UNDISCH_TAC `Re z = &0 ==> abs (Im z) < &1` THEN + ASM_REWRITE_TAC[] THEN DISCH_TAC THEN + SUBGOAL_THEN `ii * z = --Cx(Im z)` SUBST_ALL_TAC THENL + [ASM_REWRITE_TAC[COMPLEX_EQ; RE_NEG; IM_NEG; RE_MUL_II; IM_MUL_II; + RE_CX; IM_CX; REAL_NEG_0]; + ALL_TAC] THEN + UNDISCH_TAC + `Im(clog((Cx(&1) - --Cx(Im z)) / (Cx(&1) + --Cx(Im z)))) = pi` THEN + REWRITE_TAC[COMPLEX_SUB_RNEG; GSYM complex_sub] THEN + REWRITE_TAC[GSYM CX_ADD; GSYM CX_SUB; GSYM CX_DIV] THEN + SUBGOAL_THEN `&0 < (&1 + Im z) / (&1 - Im z)` ASSUME_TAC THENL + [MATCH_MP_TAC REAL_LT_DIV THEN ASM_REAL_ARITH_TAC; + ASM_SIMP_TAC[GSYM CX_LOG; IM_CX; PI_NZ]]);; + +let HAS_COMPLEX_DERIVATIVE_CATN = prove + (`!z. (Re z = &0 ==> abs(Im z) < &1) + ==> (catn has_complex_derivative inv(Cx(&1) + z pow 2)) (at z)`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN `~(z = ii) /\ ~(z = --ii)` STRIP_ASSUME_TAC THENL + [CONJ_TAC THEN + DISCH_THEN(fun th -> POP_ASSUM MP_TAC THEN SUBST1_TAC th) THEN + REWRITE_TAC[RE_II; IM_II; RE_NEG; IM_NEG] THEN REAL_ARITH_TAC; + ALL_TAC] THEN + GEN_REWRITE_TAC (RATOR_CONV o LAND_CONV) [GSYM ETA_AX] THEN + REWRITE_TAC[catn] THEN COMPLEX_DIFF_TAC THEN + REWRITE_TAC[RE_SUB; RE_ADD; IM_SUB; IM_ADD; + RE_CX; RE_MUL_II; IM_CX; IM_MUL_II] THEN + REWRITE_TAC[GSYM CONJ_ASSOC] THEN CONJ_TAC THENL + [ASM_REWRITE_TAC[IM_COMPLEX_DIV_LEMMA; RE_COMPLEX_DIV_LEMMA] THEN + SIMP_TAC[complex_norm] THEN CONV_TAC REAL_RAT_REDUCE_CONV THEN + ASM_REWRITE_TAC[REAL_ADD_LID; POW_2_SQRT_ABS]; + REPEAT(POP_ASSUM MP_TAC) THEN CONV_TAC COMPLEX_FIELD]);; + +let COMPLEX_DIFFERENTIABLE_AT_CATN = prove + (`!z. (Re z = &0 ==> abs(Im z) < &1) ==> catn complex_differentiable at z`, + REWRITE_TAC[complex_differentiable] THEN + MESON_TAC[HAS_COMPLEX_DERIVATIVE_CATN]);; + +let COMPLEX_DIFFERENTIABLE_WITHIN_CATN = prove + (`!s z. (Re z = &0 ==> abs(Im z) < &1) + ==> catn complex_differentiable (at z within s)`, + MESON_TAC[COMPLEX_DIFFERENTIABLE_AT_WITHIN; + COMPLEX_DIFFERENTIABLE_AT_CATN]);; + +add_complex_differentiation_theorems + (CONJUNCTS(REWRITE_RULE[FORALL_AND_THM] + (MATCH_MP HAS_COMPLEX_DERIVATIVE_CHAIN + HAS_COMPLEX_DERIVATIVE_CATN)));; + +let CONTINUOUS_AT_CATN = prove + (`!z. (Re z = &0 ==> abs(Im z) < &1) ==> catn continuous at z`, + MESON_TAC[HAS_COMPLEX_DERIVATIVE_CATN; + HAS_COMPLEX_DERIVATIVE_IMP_CONTINUOUS_AT]);; + +let CONTINUOUS_WITHIN_CATN = prove + (`!s z. (Re z = &0 ==> abs(Im z) < &1) ==> catn continuous (at z within s)`, + MESON_TAC[CONTINUOUS_AT_WITHIN; CONTINUOUS_AT_CATN]);; + +let CONTINUOUS_ON_CATN = prove + (`!s. (!z. z IN s /\ Re z = &0 ==> abs(Im z) < &1) ==> catn continuous_on s`, + MESON_TAC[CONTINUOUS_AT_IMP_CONTINUOUS_ON; CONTINUOUS_AT_CATN]);; + +let HOLOMORPHIC_ON_CATN = prove + (`!s. (!z. z IN s /\ Re z = &0 ==> abs(Im z) < &1) ==> catn holomorphic_on s`, + REWRITE_TAC [holomorphic_on] THEN + MESON_TAC [HAS_COMPLEX_DERIVATIVE_AT_WITHIN; HAS_COMPLEX_DERIVATIVE_CATN]);; + +(* ------------------------------------------------------------------------- *) +(* Real arctangent. *) +(* ------------------------------------------------------------------------- *) + +let atn = new_definition + `atn(x) = Re(catn(Cx x))`;; + +let CX_ATN = prove + (`!x. Cx(atn x) = catn(Cx x)`, + GEN_TAC THEN REWRITE_TAC[atn; catn; GSYM REAL; real] THEN + REWRITE_TAC[complex_div; IM_MUL_II; GSYM CX_INV; GSYM COMPLEX_MUL_ASSOC] THEN + REWRITE_TAC[RE_MUL_CX; REAL_ARITH `inv(&2) * x = &0 <=> x = &0`] THEN + MATCH_MP_TAC NORM_CEXP_IMAGINARY THEN + SUBGOAL_THEN `~(Cx(&1) - ii * Cx(x) = Cx(&0)) /\ + ~(Cx(&1) + ii * Cx(x) = Cx(&0))` + STRIP_ASSUME_TAC THENL + [CONJ_TAC THEN DISCH_THEN(MP_TAC o AP_TERM `Re`) THEN + REWRITE_TAC[RE_ADD; RE_SUB; RE_MUL_II; IM_CX; RE_CX] THEN + CONV_TAC REAL_RAT_REDUCE_CONV; + ALL_TAC] THEN + ASM_SIMP_TAC[CEXP_SUB; CEXP_CLOG; COMPLEX_FIELD + `~(a = Cx(&0)) /\ ~(b = Cx(&0)) ==> ~(a * inv b = Cx(&0))`] THEN + REWRITE_TAC[GSYM complex_div; COMPLEX_NORM_DIV] THEN + MATCH_MP_TAC(REAL_FIELD `~(b = &0) /\ a = b ==> a / b = &1`) THEN + ASM_REWRITE_TAC[COMPLEX_NORM_ZERO] THEN + MATCH_MP_TAC(MESON[COMPLEX_NORM_CNJ] `cnj a = b ==> norm a = norm b`) THEN + REWRITE_TAC[CNJ_SUB; CNJ_MUL; CNJ_MUL; CNJ_II; CNJ_CX] THEN + CONV_TAC COMPLEX_RING);; + +let ATN_TAN = prove + (`!y. tan(atn y) = y`, + GEN_TAC THEN REWRITE_TAC[tan_def; atn] THEN + MATCH_MP_TAC EQ_TRANS THEN EXISTS_TAC `Re(ctan(catn(Cx y)))` THEN + CONJ_TAC THENL [REWRITE_TAC[GSYM CX_ATN; RE_CX]; ALL_TAC] THEN + GEN_REWRITE_TAC RAND_CONV [GSYM RE_CX] THEN AP_TERM_TAC THEN + MATCH_MP_TAC CTAN_CATN THEN MATCH_MP_TAC(COMPLEX_RING + `~(z = ii) /\ ~(z = --ii) ==> ~(z pow 2 = --Cx(&1))`) THEN + CONJ_TAC THEN DISCH_THEN(MP_TAC o AP_TERM `Im`) THEN + REWRITE_TAC[IM_II; IM_CX; IM_NEG] THEN REAL_ARITH_TAC);; + +let ATN_BOUND = prove + (`!y. abs(atn y) < pi / &2`, + GEN_TAC THEN REWRITE_TAC[atn] THEN MATCH_MP_TAC RE_CATN_BOUNDS THEN + REWRITE_TAC[IM_CX] THEN CONV_TAC REAL_RAT_REDUCE_CONV);; + +let ATN_BOUNDS = prove + (`!y. --(pi / &2) < atn(y) /\ atn(y) < (pi / &2)`, + MP_TAC ATN_BOUND THEN MATCH_MP_TAC MONO_FORALL THEN REAL_ARITH_TAC);; + +let TAN_ATN = prove + (`!x. --(pi / &2) < x /\ x < pi / &2 ==> atn(tan(x)) = x`, + REPEAT STRIP_TAC THEN REWRITE_TAC[tan_def; atn] THEN + MATCH_MP_TAC EQ_TRANS THEN EXISTS_TAC `Re(catn(ctan(Cx x)))` THEN + CONJ_TAC THENL [REWRITE_TAC[GSYM CX_TAN; RE_CX]; ALL_TAC] THEN + GEN_REWRITE_TAC RAND_CONV [GSYM RE_CX] THEN AP_TERM_TAC THEN + MATCH_MP_TAC CATN_CTAN THEN REWRITE_TAC[RE_CX] THEN + ASM_REAL_ARITH_TAC);; + +let ATN_0 = prove + (`atn(&0) = &0`, + GEN_REWRITE_TAC (LAND_CONV o RAND_CONV) [SYM TAN_0] THEN + MATCH_MP_TAC TAN_ATN THEN MP_TAC PI_POS THEN REAL_ARITH_TAC);; + +let ATN_1 = prove + (`atn(&1) = pi / &4`, + MP_TAC(AP_TERM `atn` TAN_PI4) THEN DISCH_THEN(SUBST1_TAC o SYM) THEN + MATCH_MP_TAC TAN_ATN THEN MP_TAC PI_POS THEN REAL_ARITH_TAC);; + +let ATN_NEG = prove + (`!x. atn(--x) = --(atn x)`, + GEN_TAC THEN MP_TAC(SPEC `atn(x)` TAN_NEG) THEN REWRITE_TAC[ATN_TAN] THEN + DISCH_THEN(SUBST1_TAC o SYM) THEN MATCH_MP_TAC TAN_ATN THEN + MP_TAC(SPEC `x:real` ATN_BOUNDS) THEN REAL_ARITH_TAC);; + +let ATN_MONO_LT = prove + (`!x y. x < y ==> atn(x) < atn(y)`, + REPEAT GEN_TAC THEN + GEN_REWRITE_TAC (LAND_CONV o BINOP_CONV) [GSYM ATN_TAN] THEN + ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN REWRITE_TAC[REAL_NOT_LT] THEN + SIMP_TAC[TAN_MONO_LE; ATN_BOUNDS]);; + +let ATN_MONO_LT_EQ = prove + (`!x y. atn(x) < atn(y) <=> x < y`, + MESON_TAC[REAL_NOT_LE; REAL_LE_LT; ATN_MONO_LT]);; + +let ATN_MONO_LE_EQ = prove + (`!x y. atn(x) <= atn(y) <=> x <= y`, + REWRITE_TAC[GSYM REAL_NOT_LT; ATN_MONO_LT_EQ]);; + +let ATN_INJ = prove + (`!x y. (atn x = atn y) <=> (x = y)`, + REWRITE_TAC[GSYM REAL_LE_ANTISYM; ATN_MONO_LE_EQ]);; + +let ATN_POS_LT = prove + (`&0 < atn(x) <=> &0 < x`, + MESON_TAC[ATN_0; ATN_MONO_LT_EQ]);; + +let ATN_POS_LE = prove + (`&0 <= atn(x) <=> &0 <= x`, + MESON_TAC[ATN_0; ATN_MONO_LE_EQ]);; + +let ATN_LT_PI4_POS = prove + (`!x. x < &1 ==> atn(x) < pi / &4`, + SIMP_TAC[GSYM ATN_1; ATN_MONO_LT]);; + +let ATN_LT_PI4_NEG = prove + (`!x. --(&1) < x ==> --(pi / &4) < atn(x)`, + SIMP_TAC[GSYM ATN_1; GSYM ATN_NEG; ATN_MONO_LT]);; + +let ATN_LT_PI4 = prove + (`!x. abs(x) < &1 ==> abs(atn x) < pi / &4`, + GEN_TAC THEN + MATCH_MP_TAC(REAL_ARITH + `(&0 < x ==> &0 < y) /\ + (x < &0 ==> y < &0) /\ + ((x = &0) ==> (y = &0)) /\ + (x < a ==> y < b) /\ + (--a < x ==> --b < y) + ==> abs(x) < a ==> abs(y) < b`) THEN + SIMP_TAC[ATN_LT_PI4_POS; ATN_LT_PI4_NEG; ATN_0] THEN CONJ_TAC THEN + GEN_REWRITE_TAC (RAND_CONV o ONCE_DEPTH_CONV) [GSYM ATN_0] THEN + SIMP_TAC[ATN_MONO_LT]);; + +let ATN_LE_PI4 = prove + (`!x. abs(x) <= &1 ==> abs(atn x) <= pi / &4`, + REWRITE_TAC[REAL_LE_LT] THEN REPEAT STRIP_TAC THEN + ASM_SIMP_TAC[ATN_LT_PI4] THEN DISJ2_TAC THEN + FIRST_ASSUM(DISJ_CASES_THEN SUBST1_TAC o MATCH_MP + (REAL_ARITH `(abs(x) = a) ==> (x = a) \/ (x = --a)`)) THEN + ASM_REWRITE_TAC[ATN_1; ATN_NEG] THEN + REWRITE_TAC[REAL_ABS_DIV; REAL_ABS_NUM; REAL_ABS_NEG] THEN + SIMP_TAC[real_abs; REAL_LT_IMP_LE; PI_POS]);; + +let COS_ATN_NZ = prove + (`!x. ~(cos(atn(x)) = &0)`, + GEN_TAC THEN MATCH_MP_TAC REAL_LT_IMP_NZ THEN + MATCH_MP_TAC COS_POS_PI THEN REWRITE_TAC[ATN_BOUNDS]);; + +let TAN_SEC = prove + (`!x. ~(cos(x) = &0) ==> (&1 + (tan(x) pow 2) = inv(cos x) pow 2)`, + MP_TAC SIN_CIRCLE THEN MATCH_MP_TAC MONO_FORALL THEN REWRITE_TAC[tan] THEN + CONV_TAC REAL_FIELD);; + +let COS_ATN = prove + (`!x. cos(atn x) = &1 / sqrt(&1 + x pow 2)`, + SIMP_TAC[COS_TAN; ATN_BOUND; ATN_TAN]);; + +let SIN_ATN = prove + (`!x. sin(atn x) = x / sqrt(&1 + x pow 2)`, + SIMP_TAC[SIN_TAN; ATN_BOUND; ATN_TAN]);; + +(* ------------------------------------------------------------------------- *) +(* Some bound theorems where a bit of simple calculus is handy. *) +(* ------------------------------------------------------------------------- *) + +let ATN_ABS_LE_X = prove + (`!x. abs(atn x) <= abs x`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`catn`; `\z. inv(Cx(&1) + z pow 2)`; `real`; `&1`] + COMPLEX_MVT) THEN + REWRITE_TAC[CONVEX_REAL; IN] THEN ANTS_TAC THENL + [CONJ_TAC THENL + [REWRITE_TAC[real] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC HAS_COMPLEX_DERIVATIVE_AT_WITHIN THEN + MATCH_MP_TAC HAS_COMPLEX_DERIVATIVE_CATN THEN + ASM_REWRITE_TAC[] THEN REAL_ARITH_TAC; + GEN_TAC THEN REWRITE_TAC[REAL] THEN + DISCH_THEN(SUBST1_TAC o SYM) THEN + REWRITE_TAC[GSYM CX_POW; GSYM CX_ADD; GSYM CX_INV; COMPLEX_NORM_CX] THEN + REWRITE_TAC[REAL_ABS_INV] THEN MATCH_MP_TAC REAL_INV_LE_1 THEN + MP_TAC(SPEC `Re z` REAL_LE_SQUARE) THEN REAL_ARITH_TAC]; + DISCH_THEN(MP_TAC o SPECL [`Cx(&0)`; `Cx(x)`]) THEN + REWRITE_TAC[GSYM CX_ATN; COMPLEX_SUB_RZERO; REAL_CX; ATN_0] THEN + REWRITE_TAC[COMPLEX_NORM_CX; REAL_MUL_LID]]);; + +let ATN_LE_X = prove + (`!x. &0 <= x ==> atn(x) <= x`, + MP_TAC ATN_ABS_LE_X THEN MATCH_MP_TAC MONO_FORALL THEN REAL_ARITH_TAC);; + +let TAN_ABS_GE_X = prove + (`!x. abs(x) < pi / &2 ==> abs(x) <= abs(tan x)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `abs(atn(tan x))` THEN REWRITE_TAC[ATN_ABS_LE_X] THEN + MATCH_MP_TAC REAL_EQ_IMP_LE THEN AP_TERM_TAC THEN + CONV_TAC SYM_CONV THEN MATCH_MP_TAC TAN_ATN THEN + POP_ASSUM MP_TAC THEN REAL_ARITH_TAC);; + +(* ------------------------------------------------------------------------- *) +(* Probably not very useful, but for compatibility with old analysis theory. *) +(* ------------------------------------------------------------------------- *) + +let TAN_TOTAL = prove + (`!y. ?!x. --(pi / &2) < x /\ x < (pi / &2) /\ tan(x) = y`, + MESON_TAC[TAN_ATN; ATN_TAN; ATN_BOUNDS]);; + +let TAN_TOTAL_POS = prove + (`!y. &0 <= y ==> ?x. &0 <= x /\ x < pi / &2 /\ tan(x) = y`, + MESON_TAC[ATN_TAN; ATN_BOUNDS; ATN_POS_LE]);; + +let TAN_TOTAL_LEMMA = prove + (`!y. &0 < y ==> ?x. &0 < x /\ x < pi / &2 /\ y < tan(x)`, + REPEAT STRIP_TAC THEN EXISTS_TAC `atn(y + &1)` THEN + REWRITE_TAC[ATN_TAN; ATN_BOUNDS; ATN_POS_LT] THEN + POP_ASSUM MP_TAC THEN REAL_ARITH_TAC);; + +(* ------------------------------------------------------------------------- *) +(* Some slightly ad hoc lemmas useful here. *) +(* ------------------------------------------------------------------------- *) + +let RE_POW_2 = prove + (`Re(z pow 2) = Re(z) pow 2 - Im(z) pow 2`, + REWRITE_TAC[COMPLEX_POW_2; complex_mul; RE] THEN REAL_ARITH_TAC);; + +let IM_POW_2 = prove + (`Im(z pow 2) = &2 * Re(z) * Im(z)`, + REWRITE_TAC[COMPLEX_POW_2; complex_mul; IM] THEN REAL_ARITH_TAC);; + +let ABS_SQUARE_LT_1 = prove + (`!x. x pow 2 < &1 <=> abs(x) < &1`, + ONCE_REWRITE_TAC[GSYM REAL_ABS_NUM] THEN + REWRITE_TAC[REAL_LT_SQUARE_ABS] THEN REAL_ARITH_TAC);; + +let ABS_SQUARE_LE_1 = prove + (`!x. x pow 2 <= &1 <=> abs(x) <= &1`, + ONCE_REWRITE_TAC[GSYM REAL_ABS_NUM] THEN + REWRITE_TAC[REAL_LT_SQUARE_ABS; GSYM REAL_NOT_LT] THEN REAL_ARITH_TAC);; + +let ABS_SQUARE_EQ_1 = prove + (`!x. x pow 2 = &1 <=> abs(x) = &1`, + REWRITE_TAC[REAL_RING `x pow 2 = &1 <=> x = &1 \/ x = -- &1`] THEN + REAL_ARITH_TAC);; + +(* ------------------------------------------------------------------------- *) +(* Inverse sine. *) +(* ------------------------------------------------------------------------- *) + +let casn = new_definition + `casn z = --ii * clog(ii * z + csqrt(Cx(&1) - z pow 2))`;; + +let CASN_BODY_LEMMA = prove + (`!z. ~(ii * z + csqrt(Cx(&1) - z pow 2) = Cx(&0))`, + GEN_TAC THEN MP_TAC(SPEC `Cx(&1) - z pow 2` CSQRT) THEN + CONV_TAC COMPLEX_FIELD);; + +let CSIN_CASN = prove + (`!z. csin(casn z) = z`, + GEN_TAC THEN REWRITE_TAC[csin; casn; COMPLEX_MUL_LNEG; COMPLEX_MUL_RNEG] THEN + REWRITE_TAC[COMPLEX_MUL_ASSOC; COMPLEX_NEG_NEG] THEN + REWRITE_TAC[COMPLEX_POW_II_2; GSYM COMPLEX_POW_2] THEN + REWRITE_TAC[COMPLEX_NEG_NEG; COMPLEX_MUL_LNEG; COMPLEX_MUL_LID] THEN + REWRITE_TAC[CEXP_NEG] THEN + ASM_SIMP_TAC[CASN_BODY_LEMMA; CEXP_CLOG; COMPLEX_FIELD + `~(z = Cx(&0)) + ==> ((z - inv z) / (Cx(&2) * ii) = c <=> + z pow 2 - Cx(&1) = Cx(&2) * ii * c * z)`] THEN + MP_TAC(SPEC `Cx(&1) - z pow 2` CSQRT) THEN CONV_TAC COMPLEX_FIELD);; + +let CASN_CSIN = prove + (`!z. abs(Re z) < pi / &2 \/ (abs(Re z) = pi / &2 /\ Im z = &0) + ==> casn(csin z) = z`, + GEN_TAC THEN DISCH_THEN(REPEAT_TCL CONJUNCTS_THEN ASSUME_TAC) THEN + REWRITE_TAC[csin; casn; COMPLEX_MUL_LNEG; CEXP_NEG] THEN + SIMP_TAC[CEXP_NZ; COMPLEX_FIELD + `~(z = Cx(&0)) + ==> Cx(&1) - ((z - inv z) / (Cx(&2) * ii)) pow 2 = + ((z + inv z) / Cx(&2)) pow 2`] THEN + SUBGOAL_THEN + `csqrt(((cexp(ii * z) + inv(cexp(ii * z))) / Cx(&2)) pow 2) = + (cexp(ii * z) + inv(cexp(ii * z))) / Cx(&2)` + SUBST1_TAC THENL + [MATCH_MP_TAC POW_2_CSQRT THEN REWRITE_TAC[GSYM CEXP_NEG] THEN + REWRITE_TAC[complex_div; GSYM CX_INV; RE_MUL_CX; IM_MUL_CX] THEN + REWRITE_TAC[REAL_ARITH + `&0 < r * inv(&2) \/ r * inv(&2) = &0 /\ &0 <= i * inv(&2) <=> + &0 < r \/ r = &0 /\ &0 <= i`] THEN + REWRITE_TAC[RE_ADD; IM_ADD; RE_CEXP; IM_CEXP] THEN + REWRITE_TAC[RE_MUL_II; RE_NEG; IM_MUL_II; IM_NEG] THEN + REWRITE_TAC[SIN_NEG; COS_NEG; REAL_NEG_NEG] THEN + REWRITE_TAC[REAL_MUL_RNEG; GSYM real_sub] THEN + REWRITE_TAC[GSYM REAL_ADD_RDISTRIB; GSYM REAL_SUB_RDISTRIB] THEN + FIRST_X_ASSUM(DISJ_CASES_THEN STRIP_ASSUME_TAC) THENL + [DISJ1_TAC THEN MATCH_MP_TAC REAL_LT_MUL THEN + ASM_SIMP_TAC[REAL_LT_ADD; REAL_EXP_POS_LT] THEN + MATCH_MP_TAC COS_POS_PI THEN POP_ASSUM MP_TAC THEN REAL_ARITH_TAC; + DISJ2_TAC THEN ASM_REWRITE_TAC[SIN_PI2; COS_PI2] THEN + REWRITE_TAC[REAL_EXP_NEG; REAL_EXP_0; REAL_INV_1; REAL_SUB_REFL] THEN + REWRITE_TAC[REAL_MUL_LZERO; REAL_LE_REFL; REAL_ENTIRE] THEN + FIRST_X_ASSUM(DISJ_CASES_THEN SUBST1_TAC o MATCH_MP (REAL_ARITH + `abs(x) = p ==> x = p \/ x = --p`)) THEN + REWRITE_TAC[COS_PI2; COS_NEG] THEN REAL_ARITH_TAC]; + ALL_TAC] THEN + SIMP_TAC[COMPLEX_FIELD + `ii * (a - b) / (Cx(&2) * ii) + (a + b) / Cx(&2) = a`] THEN + SIMP_TAC[COMPLEX_FIELD `--(ii * w) = z <=> w = ii * z`] THEN + MATCH_MP_TAC CLOG_CEXP THEN REWRITE_TAC[IM_MUL_II] THEN + MP_TAC PI_POS THEN POP_ASSUM MP_TAC THEN REAL_ARITH_TAC);; + +let CASN_UNIQUE = prove + (`!w z. csin(z) = w /\ + (abs(Re z) < pi / &2 \/ (abs(Re z) = pi / &2 /\ Im z = &0)) + ==> casn w = z`, + MESON_TAC[CASN_CSIN]);; + +let CASN_0 = prove + (`casn(Cx(&0)) = Cx(&0)`, + REWRITE_TAC[casn; COMPLEX_MUL_RZERO; COMPLEX_ADD_LID; COMPLEX_POW_2; + COMPLEX_SUB_RZERO; CSQRT_1; CLOG_1; COMPLEX_MUL_RZERO]);; + +let CASN_1 = prove + (`casn(Cx(&1)) = Cx(pi / &2)`, + REWRITE_TAC[casn; GSYM CX_POW; GSYM CX_SUB] THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN + REWRITE_TAC[CSQRT_0; COMPLEX_MUL_RID; COMPLEX_ADD_RID] THEN + REWRITE_TAC[CLOG_II] THEN CONV_TAC COMPLEX_RING);; + +let CASN_NEG_1 = prove + (`casn(--Cx(&1)) = --Cx(pi / &2)`, + REWRITE_TAC[casn; GSYM CX_NEG; GSYM CX_POW; GSYM CX_SUB] THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN + REWRITE_TAC[CSQRT_0; COMPLEX_MUL_RID; COMPLEX_ADD_RID] THEN + REWRITE_TAC[CX_NEG; COMPLEX_MUL_RID; COMPLEX_MUL_RNEG] THEN + REWRITE_TAC[CLOG_NEG_II] THEN CONV_TAC COMPLEX_RING);; + +let HAS_COMPLEX_DERIVATIVE_CASN = prove + (`!z. (Im z = &0 ==> abs(Re z) < &1) + ==> (casn has_complex_derivative inv(ccos(casn z))) (at z)`, + REPEAT STRIP_TAC THEN + MATCH_MP_TAC HAS_COMPLEX_DERIVATIVE_INVERSE_BASIC THEN + EXISTS_TAC `csin` THEN + REWRITE_TAC[CSIN_CASN; HAS_COMPLEX_DERIVATIVE_CSIN; CONTINUOUS_AT_CSIN] THEN + EXISTS_TAC `ball(z:complex,&1)` THEN + REWRITE_TAC[OPEN_BALL; CENTRE_IN_BALL; REAL_LT_01] THEN CONJ_TAC THENL + [DISCH_THEN(MP_TAC o MATCH_MP (COMPLEX_RING + `ccos z = Cx(&0) ==> csin(z) pow 2 + ccos(z) pow 2 = Cx(&1) + ==> csin(z) pow 2 = Cx(&1)`)) THEN + REWRITE_TAC[CSIN_CASN; CSIN_CIRCLE] THEN + REWRITE_TAC[COMPLEX_RING + `z pow 2 = Cx(&1) <=> z = Cx(&1) \/ z = --Cx(&1)`] THEN + DISCH_THEN(DISJ_CASES_THEN SUBST_ALL_TAC) THEN + POP_ASSUM MP_TAC THEN REWRITE_TAC[RE_CX; IM_CX; RE_NEG; IM_NEG] THEN + REAL_ARITH_TAC; + ALL_TAC] THEN + GEN_REWRITE_TAC LAND_CONV [GSYM ETA_AX] THEN REWRITE_TAC[casn] THEN + MATCH_MP_TAC CONTINUOUS_COMPLEX_MUL THEN REWRITE_TAC[CONTINUOUS_CONST] THEN + ONCE_REWRITE_TAC[GSYM o_DEF] THEN MATCH_MP_TAC CONTINUOUS_AT_COMPOSE THEN + CONJ_TAC THENL + [MATCH_MP_TAC CONTINUOUS_ADD THEN + SIMP_TAC[CONTINUOUS_COMPLEX_MUL; CONTINUOUS_CONST; CONTINUOUS_AT_ID] THEN + ONCE_REWRITE_TAC[GSYM o_DEF] THEN MATCH_MP_TAC CONTINUOUS_AT_COMPOSE THEN + SIMP_TAC[CONTINUOUS_COMPLEX_POW; CONTINUOUS_SUB; + CONTINUOUS_CONST; CONTINUOUS_AT_ID] THEN + MATCH_MP_TAC CONTINUOUS_AT_CSQRT THEN + REWRITE_TAC[RE_SUB; IM_SUB; RE_CX; IM_CX; RE_POW_2; IM_POW_2] THEN + REWRITE_TAC[REAL_RING `&0 - &2 * x * y = &0 <=> x = &0 \/ y = &0`] THEN + STRIP_TAC THEN + ASM_REWRITE_TAC[REAL_POW_2; REAL_MUL_LZERO; REAL_SUB_RZERO; + REAL_ARITH `&1 - (&0 - x) = &1 + x`] THEN + ASM_SIMP_TAC[REAL_LE_SQUARE; REAL_ARITH `&0 <= x ==> &0 < &1 + x`] THEN + REWRITE_TAC[REAL_ARITH `&0 < &1 - x * x <=> x pow 2 < &1 pow 2`] THEN + ONCE_REWRITE_TAC[GSYM REAL_POW2_ABS] THEN MATCH_MP_TAC REAL_POW_LT2 THEN + ASM_SIMP_TAC[REAL_ABS_POS; REAL_ABS_NUM; ARITH]; + ALL_TAC] THEN + MATCH_MP_TAC CONTINUOUS_AT_CLOG THEN + REWRITE_TAC[IM_ADD; IM_MUL_II; RE_ADD; RE_MUL_II] THEN + ASM_CASES_TAC `Im z = &0` THENL + [DISCH_THEN(K ALL_TAC) THEN ASM_REWRITE_TAC[csqrt] THEN + ASM_REWRITE_TAC[IM_SUB; RE_SUB; IM_CX; RE_CX; IM_POW_2; RE_POW_2; + REAL_MUL_RZERO; REAL_SUB_REFL] THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN + REWRITE_TAC[REAL_ARITH `&0 <= &1 - (z pow 2 - &0) <=> z pow 2 <= &1 pow 2`; + GSYM REAL_LE_SQUARE_ABS] THEN + ASM_SIMP_TAC[REAL_LT_IMP_LE; REAL_ABS_NUM; RE; REAL_ADD_LID] THEN + MATCH_MP_TAC SQRT_POS_LT THEN + REWRITE_TAC[REAL_ARITH `&0 < &1 - (z pow 2 - &0) <=> z pow 2 < &1 pow 2`; + GSYM REAL_LT_SQUARE_ABS] THEN + ASM_REAL_ARITH_TAC; + ALL_TAC] THEN + REWRITE_TAC[csqrt; IM_SUB; RE_SUB; IM_CX; RE_CX; IM_POW_2; RE_POW_2] THEN + REWRITE_TAC[REAL_RING `&0 - &2 * x * y = &0 <=> x = &0 \/ y = &0`] THEN + ASM_CASES_TAC `Re z = &0` THEN ASM_REWRITE_TAC[RE; IM] THENL + [CONV_TAC REAL_RAT_REDUCE_CONV THEN + REWRITE_TAC[REAL_ARITH `&1 - (&0 - x) = &1 + x`] THEN + SIMP_TAC[REAL_POW_2; REAL_LE_ADD; REAL_LE_SQUARE; REAL_POS] THEN + REWRITE_TAC[RE; IM; REAL_ADD_LID; REAL_ARITH `&0 < --x + y <=> x < y`] THEN + MATCH_MP_TAC REAL_LT_RSQRT THEN REAL_ARITH_TAC; + ALL_TAC] THEN + DISCH_TAC THEN REWRITE_TAC[REAL_ARITH `&0 < --x + y <=> x < y`] THEN + MATCH_MP_TAC REAL_LT_RSQRT THEN + REWRITE_TAC[REAL_POW_2; REAL_ARITH + `a < (n + &1 - (b - a)) / &2 <=> (a + b) - &1 < n`] THEN + REWRITE_TAC[complex_norm] THEN MATCH_MP_TAC REAL_LT_RSQRT THEN + REWRITE_TAC[RE_SUB; IM_SUB; RE_CX; IM_CX; RE_POW_2; IM_POW_2] THEN + REPEAT(FIRST_X_ASSUM(MP_TAC o + GEN_REWRITE_RULE I [GSYM REAL_LT_SQUARE])) THEN + REAL_ARITH_TAC);; + +let COMPLEX_DIFFERENTIABLE_AT_CASN = prove + (`!z. (Im z = &0 ==> abs(Re z) < &1) ==> casn complex_differentiable at z`, + REWRITE_TAC[complex_differentiable] THEN + MESON_TAC[HAS_COMPLEX_DERIVATIVE_CASN]);; + +let COMPLEX_DIFFERENTIABLE_WITHIN_CASN = prove + (`!s z. (Im z = &0 ==> abs(Re z) < &1) + ==> casn complex_differentiable (at z within s)`, + MESON_TAC[COMPLEX_DIFFERENTIABLE_AT_WITHIN; + COMPLEX_DIFFERENTIABLE_AT_CASN]);; + +add_complex_differentiation_theorems + (CONJUNCTS(REWRITE_RULE[FORALL_AND_THM] + (MATCH_MP HAS_COMPLEX_DERIVATIVE_CHAIN + HAS_COMPLEX_DERIVATIVE_CASN)));; + +let CONTINUOUS_AT_CASN = prove + (`!z. (Im z = &0 ==> abs(Re z) < &1) ==> casn continuous at z`, + MESON_TAC[HAS_COMPLEX_DERIVATIVE_CASN; + HAS_COMPLEX_DERIVATIVE_IMP_CONTINUOUS_AT]);; + +let CONTINUOUS_WITHIN_CASN = prove + (`!s z. (Im z = &0 ==> abs(Re z) < &1) ==> casn continuous (at z within s)`, + MESON_TAC[CONTINUOUS_AT_WITHIN; CONTINUOUS_AT_CASN]);; + +let CONTINUOUS_ON_CASN = prove + (`!s. (!z. z IN s /\ Im z = &0 ==> abs(Re z) < &1) ==> casn continuous_on s`, + MESON_TAC[CONTINUOUS_AT_IMP_CONTINUOUS_ON; CONTINUOUS_AT_CASN]);; + +let HOLOMORPHIC_ON_CASN = prove + (`!s. (!z. z IN s /\ Im z = &0 ==> abs(Re z) < &1) ==> casn holomorphic_on s`, + REWRITE_TAC [holomorphic_on] THEN + MESON_TAC [HAS_COMPLEX_DERIVATIVE_AT_WITHIN; HAS_COMPLEX_DERIVATIVE_CASN]);; + +(* ------------------------------------------------------------------------- *) +(* Inverse cosine. *) +(* ------------------------------------------------------------------------- *) + +let cacs = new_definition + `cacs z = --ii * clog(z + ii * csqrt(Cx(&1) - z pow 2))`;; + +let CACS_BODY_LEMMA = prove + (`!z. ~(z + ii * csqrt(Cx(&1) - z pow 2) = Cx(&0))`, + GEN_TAC THEN MP_TAC(SPEC `Cx(&1) - z pow 2` CSQRT) THEN + CONV_TAC COMPLEX_FIELD);; + +let CCOS_CACS = prove + (`!z. ccos(cacs z) = z`, + GEN_TAC THEN REWRITE_TAC[ccos; cacs; COMPLEX_MUL_LNEG; COMPLEX_MUL_RNEG] THEN + REWRITE_TAC[COMPLEX_MUL_ASSOC; COMPLEX_NEG_NEG] THEN + REWRITE_TAC[COMPLEX_POW_II_2; GSYM COMPLEX_POW_2] THEN + REWRITE_TAC[COMPLEX_NEG_NEG; COMPLEX_MUL_LNEG; COMPLEX_MUL_LID] THEN + REWRITE_TAC[CEXP_NEG] THEN + ASM_SIMP_TAC[CACS_BODY_LEMMA; CEXP_CLOG; COMPLEX_POW_II_2; COMPLEX_FIELD + `~(z = Cx(&0)) + ==> ((z + inv z) / Cx(&2) = c <=> + z pow 2 + Cx(&1) = Cx(&2) * c * z)`] THEN + MP_TAC(SPEC `Cx(&1) - z pow 2` CSQRT) THEN CONV_TAC COMPLEX_FIELD);; + +let CACS_CCOS = prove + (`!z. &0 < Re z /\ Re z < pi \/ + Re(z) = &0 /\ &0 <= Im(z) \/ + Re(z) = pi /\ Im(z) <= &0 + ==> cacs(ccos z) = z`, + GEN_TAC THEN DISCH_THEN(REPEAT_TCL CONJUNCTS_THEN ASSUME_TAC) THEN + REWRITE_TAC[ccos; cacs; COMPLEX_MUL_LNEG; CEXP_NEG] THEN + SIMP_TAC[CEXP_NZ; COMPLEX_FIELD + `~(z = Cx(&0)) + ==> Cx(&1) - ((z + inv z) / Cx(&2)) pow 2 = + --(((z - inv z) / Cx(&2)) pow 2)`] THEN + SUBGOAL_THEN + `csqrt(--(((cexp(ii * z) - inv(cexp(ii * z))) / Cx(&2)) pow 2)) = + --ii * (cexp(ii * z) - inv(cexp(ii * z))) / Cx(&2)` + SUBST1_TAC THENL + [SIMP_TAC[COMPLEX_FIELD `--(x pow 2) = (--ii * x) pow 2`] THEN + MATCH_MP_TAC POW_2_CSQRT THEN REWRITE_TAC[GSYM CEXP_NEG] THEN + REWRITE_TAC[complex_div; GSYM CX_INV; RE_MUL_CX; IM_MUL_CX; RE_NEG; IM_NEG; + COMPLEX_MUL_LNEG; RE_MUL_II; IM_MUL_II; RE_SUB; IM_SUB] THEN + REWRITE_TAC[REAL_NEG_NEG; REAL_NEG_EQ_0] THEN + REWRITE_TAC[REAL_ARITH + `&0 < r * inv(&2) \/ r * inv(&2) = &0 /\ &0 <= --(i * inv(&2)) <=> + &0 < r \/ r = &0 /\ &0 <= --i`] THEN + REWRITE_TAC[RE_ADD; IM_ADD; RE_CEXP; IM_CEXP] THEN + REWRITE_TAC[RE_MUL_II; RE_NEG; IM_MUL_II; IM_NEG] THEN + REWRITE_TAC[SIN_NEG; COS_NEG; REAL_NEG_NEG] THEN + REWRITE_TAC[REAL_MUL_RNEG; GSYM real_sub; REAL_SUB_RNEG; REAL_NEG_SUB] THEN + REWRITE_TAC[GSYM REAL_ADD_RDISTRIB; GSYM REAL_SUB_RDISTRIB] THEN + ASM_SIMP_TAC[REAL_LT_ADD; REAL_EXP_POS_LT; REAL_LT_MUL_EQ] THEN + POP_ASSUM(REPEAT_TCL DISJ_CASES_THEN STRIP_ASSUME_TAC) THEN + ASM_SIMP_TAC[SIN_POS_PI] THEN DISJ2_TAC THEN + REWRITE_TAC[SIN_PI; REAL_MUL_RZERO; COS_PI; SIN_0; COS_0] THEN + REWRITE_TAC[REAL_MUL_RID; REAL_MUL_RNEG] THEN + REWRITE_TAC[REAL_NEG_SUB; REAL_SUB_LE; REAL_EXP_MONO_LE] THEN + ASM_REAL_ARITH_TAC; + ALL_TAC] THEN + SIMP_TAC[COMPLEX_FIELD + `(e + e') / Cx(&2) + ii * --ii * (e - e') / Cx(&2) = e`] THEN + SIMP_TAC[COMPLEX_FIELD `--(ii * w) = z <=> w = ii * z`] THEN + MATCH_MP_TAC CLOG_CEXP THEN REWRITE_TAC[IM_MUL_II] THEN + MP_TAC PI_POS THEN ASM_REAL_ARITH_TAC);; + +let CACS_UNIQUE = prove + (`!w z. + ccos z = w /\ + (&0 < Re z /\ Re z < pi \/ + Re(z) = &0 /\ &0 <= Im(z) \/ + Re(z) = pi /\ Im(z) <= &0) + ==> cacs(w) = z`, + MESON_TAC[CACS_CCOS]);; + +let CACS_0 = prove + (`cacs(Cx(&0)) = Cx(pi / &2)`, + MATCH_MP_TAC CACS_UNIQUE THEN + REWRITE_TAC[RE_CX; IM_CX; GSYM CX_COS; COS_PI2] THEN + MP_TAC PI_POS THEN REAL_ARITH_TAC);; + +let CACS_1 = prove + (`cacs(Cx(&1)) = Cx(&0)`, + MATCH_MP_TAC CACS_UNIQUE THEN + REWRITE_TAC[RE_CX; IM_CX; GSYM CX_COS; COS_0; REAL_LE_REFL]);; + +let CACS_NEG_1 = prove + (`cacs(--Cx(&1)) = Cx pi`, + MATCH_MP_TAC CACS_UNIQUE THEN + REWRITE_TAC[RE_CX; IM_CX; GSYM CX_COS; COS_PI; CX_NEG; REAL_LE_REFL]);; + +let HAS_COMPLEX_DERIVATIVE_CACS = prove + (`!z. (Im z = &0 ==> abs(Re z) < &1) + ==> (cacs has_complex_derivative --inv(csin(cacs z))) (at z)`, + REPEAT STRIP_TAC THEN REWRITE_TAC[COMPLEX_NEG_INV] THEN + MATCH_MP_TAC HAS_COMPLEX_DERIVATIVE_INVERSE_BASIC THEN + EXISTS_TAC `ccos` THEN + REWRITE_TAC[CCOS_CACS; HAS_COMPLEX_DERIVATIVE_CCOS; CONTINUOUS_AT_CCOS] THEN + EXISTS_TAC `ball(z:complex,&1)` THEN + REWRITE_TAC[OPEN_BALL; CENTRE_IN_BALL; REAL_LT_01] THEN CONJ_TAC THENL + [DISCH_THEN(MP_TAC o MATCH_MP (COMPLEX_RING + `--(csin z) = Cx(&0) ==> csin(z) pow 2 + ccos(z) pow 2 = Cx(&1) + ==> ccos(z) pow 2 = Cx(&1)`)) THEN + REWRITE_TAC[CCOS_CACS; CSIN_CIRCLE] THEN + REWRITE_TAC[COMPLEX_RING + `z pow 2 = Cx(&1) <=> z = Cx(&1) \/ z = --Cx(&1)`] THEN + DISCH_THEN(DISJ_CASES_THEN SUBST_ALL_TAC) THEN + POP_ASSUM MP_TAC THEN REWRITE_TAC[RE_CX; IM_CX; RE_NEG; IM_NEG] THEN + REAL_ARITH_TAC; + ALL_TAC] THEN + GEN_REWRITE_TAC LAND_CONV [GSYM ETA_AX] THEN REWRITE_TAC[cacs] THEN + MATCH_MP_TAC CONTINUOUS_COMPLEX_MUL THEN REWRITE_TAC[CONTINUOUS_CONST] THEN + ONCE_REWRITE_TAC[GSYM o_DEF] THEN MATCH_MP_TAC CONTINUOUS_AT_COMPOSE THEN + CONJ_TAC THENL + [MATCH_MP_TAC CONTINUOUS_ADD THEN REWRITE_TAC[CONTINUOUS_AT_ID] THEN + MATCH_MP_TAC CONTINUOUS_COMPLEX_MUL THEN REWRITE_TAC[CONTINUOUS_CONST] THEN + ONCE_REWRITE_TAC[GSYM o_DEF] THEN MATCH_MP_TAC CONTINUOUS_AT_COMPOSE THEN + SIMP_TAC[CONTINUOUS_COMPLEX_POW; CONTINUOUS_SUB; + CONTINUOUS_CONST; CONTINUOUS_AT_ID] THEN + MATCH_MP_TAC CONTINUOUS_AT_CSQRT THEN + REWRITE_TAC[RE_SUB; IM_SUB; RE_CX; IM_CX; RE_POW_2; IM_POW_2] THEN + REWRITE_TAC[REAL_RING `&0 - &2 * x * y = &0 <=> x = &0 \/ y = &0`] THEN + STRIP_TAC THEN + ASM_REWRITE_TAC[REAL_POW_2; REAL_MUL_LZERO; REAL_SUB_RZERO; + REAL_ARITH `&1 - (&0 - x) = &1 + x`] THEN + ASM_SIMP_TAC[REAL_LE_SQUARE; REAL_ARITH `&0 <= x ==> &0 < &1 + x`] THEN + REWRITE_TAC[REAL_ARITH `&0 < &1 - x * x <=> x pow 2 < &1 pow 2`] THEN + ONCE_REWRITE_TAC[GSYM REAL_POW2_ABS] THEN MATCH_MP_TAC REAL_POW_LT2 THEN + ASM_SIMP_TAC[REAL_ABS_POS; REAL_ABS_NUM; ARITH]; + ALL_TAC] THEN + MATCH_MP_TAC CONTINUOUS_AT_CLOG THEN + REWRITE_TAC[IM_ADD; IM_MUL_II; RE_ADD; RE_MUL_II] THEN + ASM_CASES_TAC `Im z = &0` THENL + [ASM_REWRITE_TAC[csqrt] THEN + ASM_REWRITE_TAC[IM_SUB; RE_SUB; IM_CX; RE_CX; IM_POW_2; RE_POW_2; + REAL_MUL_RZERO; REAL_SUB_REFL] THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN + REWRITE_TAC[REAL_ARITH `&0 <= &1 - (z pow 2 - &0) <=> z pow 2 <= &1 pow 2`; + GSYM REAL_LE_SQUARE_ABS] THEN + ASM_SIMP_TAC[REAL_LT_IMP_LE; REAL_ABS_NUM; RE; REAL_ADD_LID] THEN + REWRITE_TAC[GSYM real_sub; IM; REAL_SUB_LT; REAL_SUB_RZERO] THEN + MATCH_MP_TAC(REAL_ARITH `&0 < x ==> x = &0 ==> &0 < y`) THEN + MATCH_MP_TAC SQRT_POS_LT THEN + ASM_SIMP_TAC[REAL_SUB_LT; ABS_SQUARE_LT_1]; + ALL_TAC] THEN + REWRITE_TAC[csqrt; IM_SUB; RE_SUB; IM_CX; RE_CX; IM_POW_2; RE_POW_2] THEN + REWRITE_TAC[REAL_RING `&0 - &2 * x * y = &0 <=> x = &0 \/ y = &0`] THEN + ASM_CASES_TAC `Re z = &0` THEN ASM_REWRITE_TAC[RE; IM] THENL + [CONV_TAC REAL_RAT_REDUCE_CONV THEN + REWRITE_TAC[REAL_ARITH `&1 - (&0 - x) = &1 + x`] THEN + SIMP_TAC[REAL_POW_2; REAL_LE_ADD; REAL_LE_SQUARE; REAL_POS] THEN + REWRITE_TAC[RE; IM; REAL_ADD_LID] THEN CONV_TAC REAL_RAT_REDUCE_CONV THEN + DISCH_THEN(MP_TAC o MATCH_MP (REAL_ARITH `a + b = &0 ==> a = --b`)) THEN + DISCH_THEN(MP_TAC o AP_TERM `\x:real. x pow 2`) THEN + SIMP_TAC[SQRT_POW_2; REAL_POW_NEG; ARITH; REAL_LE_SQUARE; REAL_LE_ADD; + REAL_POS] THEN + REAL_ARITH_TAC; + ALL_TAC] THEN + DISCH_THEN(MP_TAC o MATCH_MP (REAL_ARITH `a + b = &0 ==> a = --b`)) THEN + DISCH_THEN(MP_TAC o AP_TERM `\x:real. x pow 2`) THEN + SUBGOAL_THEN `&0 < (norm(Cx (&1) - z pow 2) + + &1 - (Re z pow 2 - Im z pow 2)) / &2` + ASSUME_TAC THENL + [REWRITE_TAC[REAL_ARITH `&0 < (x + y - z) / &2 <=> z - y < x`] THEN + REWRITE_TAC[complex_norm] THEN MATCH_MP_TAC REAL_LT_RSQRT THEN + REWRITE_TAC[RE_SUB; IM_SUB; RE_CX; IM_CX; RE_POW_2; IM_POW_2] THEN + REPEAT(FIRST_X_ASSUM(MP_TAC o + GEN_REWRITE_RULE I [GSYM REAL_LT_SQUARE])) THEN + REWRITE_TAC[IMP_IMP] THEN DISCH_THEN(MP_TAC o MATCH_MP REAL_LT_MUL) THEN + REAL_ARITH_TAC; + ALL_TAC] THEN + ASM_SIMP_TAC[SQRT_POW_2; REAL_POW_NEG; ARITH; REAL_LT_IMP_LE] THEN + REWRITE_TAC[REAL_POW_2; REAL_ARITH + `a = (n + &1 - (b - a)) / &2 <=> (a + b) - &1 = n`] THEN + REWRITE_TAC[complex_norm] THEN + DISCH_THEN(MP_TAC o AP_TERM `\x:real. x pow 2`) THEN + SIMP_TAC[SQRT_POW_2; REWRITE_RULE[GSYM REAL_POW_2] REAL_LE_SQUARE; + REAL_LE_ADD] THEN + REWRITE_TAC[RE_SUB; RE_CX; RE_POW_2; IM_SUB; IM_CX; IM_POW_2] THEN + REPEAT(FIRST_X_ASSUM(MP_TAC o + GEN_REWRITE_RULE I [GSYM REAL_LT_SQUARE])) THEN + REAL_ARITH_TAC);; + +let COMPLEX_DIFFERENTIABLE_AT_CACS = prove + (`!z. (Im z = &0 ==> abs(Re z) < &1) ==> cacs complex_differentiable at z`, + REWRITE_TAC[complex_differentiable] THEN + MESON_TAC[HAS_COMPLEX_DERIVATIVE_CACS]);; + +let COMPLEX_DIFFERENTIABLE_WITHIN_CACS = prove + (`!s z. (Im z = &0 ==> abs(Re z) < &1) + ==> cacs complex_differentiable (at z within s)`, + MESON_TAC[COMPLEX_DIFFERENTIABLE_AT_WITHIN; + COMPLEX_DIFFERENTIABLE_AT_CACS]);; + +add_complex_differentiation_theorems + (CONJUNCTS(REWRITE_RULE[FORALL_AND_THM] + (MATCH_MP HAS_COMPLEX_DERIVATIVE_CHAIN + HAS_COMPLEX_DERIVATIVE_CACS)));; + +let CONTINUOUS_AT_CACS = prove + (`!z. (Im z = &0 ==> abs(Re z) < &1) ==> cacs continuous at z`, + MESON_TAC[HAS_COMPLEX_DERIVATIVE_CACS; + HAS_COMPLEX_DERIVATIVE_IMP_CONTINUOUS_AT]);; + +let CONTINUOUS_WITHIN_CACS = prove + (`!s z. (Im z = &0 ==> abs(Re z) < &1) ==> cacs continuous (at z within s)`, + MESON_TAC[CONTINUOUS_AT_WITHIN; CONTINUOUS_AT_CACS]);; + +let CONTINUOUS_ON_CACS = prove + (`!s. (!z. z IN s /\ Im z = &0 ==> abs(Re z) < &1) ==> cacs continuous_on s`, + MESON_TAC[CONTINUOUS_AT_IMP_CONTINUOUS_ON; CONTINUOUS_AT_CACS]);; + +let HOLOMORPHIC_ON_CACS = prove + (`!s. (!z. z IN s /\ Im z = &0 ==> abs(Re z) < &1) ==> cacs holomorphic_on s`, + REWRITE_TAC [holomorphic_on] THEN + MESON_TAC [HAS_COMPLEX_DERIVATIVE_AT_WITHIN; HAS_COMPLEX_DERIVATIVE_CACS]);; + +(* ------------------------------------------------------------------------- *) +(* Some crude range theorems (could be sharpened). *) +(* ------------------------------------------------------------------------- *) + +let CASN_RANGE_LEMMA = prove + (`!z. abs (Re z) < &1 ==> &0 < Re(ii * z + csqrt(Cx(&1) - z pow 2))`, + REPEAT STRIP_TAC THEN REWRITE_TAC[RE_ADD; RE_MUL_II] THEN + REWRITE_TAC[REAL_ARITH `&0 < --i + r <=> i < r`] THEN + REWRITE_TAC[csqrt; IM_SUB; RE_SUB; COMPLEX_POW_2; RE_CX; IM_CX] THEN + REWRITE_TAC[complex_mul; RE; IM] THEN REWRITE_TAC[GSYM complex_mul] THEN + REWRITE_TAC[REAL_ARITH `r * i + i * r = &2 * r * i`] THEN + REWRITE_TAC[REAL_SUB_LZERO; REAL_NEG_EQ_0; REAL_ABS_NEG] THEN + REWRITE_TAC[REAL_NEG_SUB; REAL_ENTIRE; REAL_OF_NUM_EQ; ARITH] THEN + MAP_EVERY ASM_CASES_TAC [`Re z = &0`; `Im z = &0`] THEN + ASM_REWRITE_TAC[REAL_SUB_LZERO; REAL_SUB_RZERO] THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN + REWRITE_TAC[RE; SQRT_1] THEN CONV_TAC REAL_RAT_REDUCE_CONV THENL + [REWRITE_TAC[REAL_ARITH `&1 - (&0 - z) = &1 + z`] THEN + SIMP_TAC[REAL_LE_ADD; REAL_POS; REAL_LE_SQUARE; RE] THEN + MATCH_MP_TAC REAL_LT_RSQRT THEN REAL_ARITH_TAC; + SUBGOAL_THEN `Re(z) pow 2 < &1 pow 2` MP_TAC THENL + [ONCE_REWRITE_TAC[GSYM REAL_POW2_ABS] THEN MATCH_MP_TAC REAL_POW_LT2 THEN + ASM_REWRITE_TAC[REAL_ABS_POS; REAL_ABS_NUM; ARITH]; + REWRITE_TAC[REAL_POW_ONE] THEN STRIP_TAC] THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[RE] THEN + TRY(MATCH_MP_TAC SQRT_POS_LT) THEN ASM_REAL_ARITH_TAC; + MATCH_MP_TAC REAL_LT_RSQRT THEN + REWRITE_TAC[REAL_POW_2; REAL_ARITH + `a < (n + &1 - (b - a)) / &2 <=> (a + b) - &1 < n`] THEN + REWRITE_TAC[complex_norm] THEN MATCH_MP_TAC REAL_LT_RSQRT THEN + REWRITE_TAC[RE_SUB; IM_SUB; RE_CX; IM_CX] THEN + REWRITE_TAC[complex_mul; RE; IM] THEN + REPEAT(FIRST_X_ASSUM(MP_TAC o + GEN_REWRITE_RULE I [GSYM REAL_LT_SQUARE])) THEN + REAL_ARITH_TAC]);; + +let CACS_RANGE_LEMMA = prove + (`!z. abs(Re z) < &1 ==> &0 < Im(z + ii * csqrt(Cx(&1) - z pow 2))`, + REPEAT STRIP_TAC THEN MP_TAC(SPEC `--z:complex` CASN_RANGE_LEMMA) THEN + ASM_SIMP_TAC[IM_NEG; RE_NEG; IM_ADD; RE_ADD; IM_MUL_II; RE_MUL_II; + COMPLEX_POW_NEG; ARITH; REAL_ABS_NEG] THEN + REAL_ARITH_TAC);; + +let RE_CASN = prove + (`!z. Re(casn z) = Im(clog(ii * z + csqrt(Cx(&1) - z pow 2)))`, + REWRITE_TAC[casn; COMPLEX_MUL_LNEG; RE_NEG; RE_MUL_II; REAL_NEGNEG]);; + +let RE_CACS = prove + (`!z. Re(cacs z) = Im(clog(z + ii * csqrt(Cx(&1) - z pow 2)))`, + REWRITE_TAC[cacs; COMPLEX_MUL_LNEG; RE_NEG; RE_MUL_II; REAL_NEGNEG]);; + +let CASN_BOUNDS = prove + (`!z. abs(Re z) < &1 ==> abs(Re(casn z)) < pi / &2`, + GEN_TAC THEN DISCH_TAC THEN REWRITE_TAC[RE_CASN] THEN + MATCH_MP_TAC RE_CLOG_POS_LT_IMP THEN ASM_SIMP_TAC[CASN_RANGE_LEMMA]);; + +let CACS_BOUNDS = prove + (`!z. abs(Re z) < &1 ==> &0 < Re(cacs z) /\ Re(cacs z) < pi`, + GEN_TAC THEN DISCH_TAC THEN REWRITE_TAC[RE_CACS] THEN + MATCH_MP_TAC IM_CLOG_POS_LT_IMP THEN ASM_SIMP_TAC[CACS_RANGE_LEMMA]);; + +let RE_CACS_BOUNDS = prove + (`!z. --pi < Re(cacs z) /\ Re(cacs z) <= pi`, + REWRITE_TAC[RE_CACS] THEN SIMP_TAC[CLOG_WORKS; CACS_BODY_LEMMA]);; + +let RE_CACS_BOUND = prove + (`!z. abs(Re(cacs z)) <= pi`, + MP_TAC RE_CACS_BOUNDS THEN MATCH_MP_TAC MONO_FORALL THEN REAL_ARITH_TAC);; + +let RE_CASN_BOUNDS = prove + (`!z. --pi < Re(casn z) /\ Re(casn z) <= pi`, + REWRITE_TAC[RE_CASN] THEN SIMP_TAC[CLOG_WORKS; CASN_BODY_LEMMA]);; + +let RE_CASN_BOUND = prove + (`!z. abs(Re(casn z)) <= pi`, + MP_TAC RE_CASN_BOUNDS THEN MATCH_MP_TAC MONO_FORALL THEN REAL_ARITH_TAC);; + +(* ------------------------------------------------------------------------- *) +(* Interrelations between the two functions. *) +(* ------------------------------------------------------------------------- *) + +let CCOS_CASN_NZ = prove + (`!z. ~(z pow 2 = Cx(&1)) ==> ~(ccos(casn z) = Cx(&0))`, + REWRITE_TAC[ccos; casn; CEXP_NEG; COMPLEX_RING `ii * --ii * z = z`; + COMPLEX_RING `--ii * --ii * z = --z`] THEN + SIMP_TAC[CEXP_CLOG; CASN_BODY_LEMMA; + COMPLEX_FIELD `~(x = Cx(&0)) + ==> ((x + inv(x)) / Cx(&2) = Cx(&0) <=> + x pow 2 = --Cx(&1))`] THEN + SIMP_TAC[CSQRT; COMPLEX_FIELD + `s pow 2 = Cx(&1) - z pow 2 + ==> ((ii * z + s) pow 2 = --Cx(&1) <=> + ii * s * z = Cx(&1) - z pow 2)`] THEN + GEN_TAC THEN STRIP_TAC THEN + MATCH_MP_TAC(COMPLEX_RING + `~(x pow 2 + y pow 2 = Cx(&0)) ==> ~(ii * x = y)`) THEN + REPEAT(POP_ASSUM MP_TAC) THEN + MP_TAC(SPEC `Cx(&1) - z pow 2` CSQRT) THEN CONV_TAC COMPLEX_RING);; + +let CSIN_CACS_NZ = prove + (`!z. ~(z pow 2 = Cx(&1)) ==> ~(csin(cacs z) = Cx(&0))`, + REWRITE_TAC[csin; cacs; CEXP_NEG; COMPLEX_RING `ii * --ii * z = z`; + COMPLEX_RING `--ii * --ii * z = --z`] THEN + SIMP_TAC[CEXP_CLOG; CACS_BODY_LEMMA; + COMPLEX_FIELD `~(x = Cx(&0)) + ==> ((x - inv(x)) / (Cx(&2) * ii) = Cx(&0) <=> + x pow 2 = Cx(&1))`] THEN + SIMP_TAC[CSQRT; COMPLEX_FIELD + `s pow 2 = Cx(&1) - z pow 2 + ==> ((z + ii * s) pow 2 = Cx(&1) <=> + ii * s * z = Cx(&1) - z pow 2)`] THEN + GEN_TAC THEN STRIP_TAC THEN + MATCH_MP_TAC(COMPLEX_RING + `~(x pow 2 + y pow 2 = Cx(&0)) ==> ~(ii * x = y)`) THEN + REPEAT(POP_ASSUM MP_TAC) THEN + MP_TAC(SPEC `Cx(&1) - z pow 2` CSQRT) THEN CONV_TAC COMPLEX_RING);; + +let CCOS_CSIN_CSQRT = prove + (`!z. &0 < cos(Re z) \/ cos(Re z) = &0 /\ Im(z) * sin(Re z) <= &0 + ==> ccos(z) = csqrt(Cx(&1) - csin(z) pow 2)`, + REPEAT STRIP_TAC THEN CONV_TAC SYM_CONV THEN MATCH_MP_TAC CSQRT_UNIQUE THEN + REWRITE_TAC[COMPLEX_EQ_SUB_LADD] THEN ONCE_REWRITE_TAC[COMPLEX_ADD_SYM] THEN + REWRITE_TAC[CSIN_CIRCLE] THEN REWRITE_TAC[RE_CCOS; IM_CCOS] THEN + ASM_SIMP_TAC[REAL_LT_MUL_EQ; REAL_HALF; REAL_LT_ADD; REAL_EXP_POS_LT] THEN + DISJ2_TAC THEN REWRITE_TAC[REAL_MUL_RZERO] THEN + FIRST_ASSUM(MP_TAC o MATCH_MP(REAL_ARITH + `x * y <= &0 ==> &0 <= --x * y`)) THEN + REWRITE_TAC[REAL_MUL_POS_LE] THEN + SIMP_TAC[REAL_ARITH `x / &2 = &0 <=> x = &0`; REAL_LT_RDIV_EQ; REAL_ADD_LID; + REAL_SUB_LT; REAL_LT_LDIV_EQ; REAL_OF_NUM_LT; ARITH; REAL_MUL_LZERO; + REAL_SUB_0; REAL_EXP_MONO_LT; REAL_LT_SUB_RADD; REAL_EXP_INJ] THEN + REAL_ARITH_TAC);; + +let CSIN_CCOS_CSQRT = prove + (`!z. &0 < sin(Re z) \/ sin(Re z) = &0 /\ &0 <= Im(z) * cos(Re z) + ==> csin(z) = csqrt(Cx(&1) - ccos(z) pow 2)`, + REPEAT STRIP_TAC THEN CONV_TAC SYM_CONV THEN MATCH_MP_TAC CSQRT_UNIQUE THEN + REWRITE_TAC[COMPLEX_EQ_SUB_LADD] THEN ONCE_REWRITE_TAC[COMPLEX_ADD_SYM] THEN + REWRITE_TAC[ONCE_REWRITE_RULE[COMPLEX_ADD_SYM] CSIN_CIRCLE] THEN + REWRITE_TAC[RE_CSIN; IM_CSIN] THEN + ASM_SIMP_TAC[REAL_LT_MUL_EQ; REAL_HALF; REAL_LT_ADD; REAL_EXP_POS_LT] THEN + DISJ2_TAC THEN REWRITE_TAC[REAL_MUL_RZERO] THEN + REPEAT(POP_ASSUM MP_TAC) THEN + REWRITE_TAC[REAL_MUL_POS_LE] THEN + SIMP_TAC[REAL_ARITH `x / &2 = &0 <=> x = &0`; REAL_LT_RDIV_EQ; REAL_ADD_LID; + REAL_SUB_LT; REAL_LT_LDIV_EQ; REAL_OF_NUM_LT; ARITH; REAL_MUL_LZERO; + + REAL_SUB_0; REAL_EXP_MONO_LT; REAL_LT_SUB_RADD; REAL_EXP_INJ] THEN + REAL_ARITH_TAC);; + +let CASN_CACS_SQRT_POS = prove + (`!z. (&0 < Re z \/ Re z = &0 /\ &0 <= Im z) + ==> casn(z) = cacs(csqrt(Cx(&1) - z pow 2))`, + GEN_TAC THEN DISCH_TAC THEN REWRITE_TAC[casn; cacs] THEN + AP_TERM_TAC THEN AP_TERM_TAC THEN + MATCH_MP_TAC(COMPLEX_RING `w = z ==> ii * z + s = s + ii * w`) THEN + MATCH_MP_TAC CSQRT_UNIQUE THEN + ASM_REWRITE_TAC[CSQRT] THEN CONV_TAC COMPLEX_RING);; + +let CACS_CASN_SQRT_POS = prove + (`!z. (&0 < Re z \/ Re z = &0 /\ &0 <= Im z) + ==> cacs(z) = casn(csqrt(Cx(&1) - z pow 2))`, + GEN_TAC THEN DISCH_TAC THEN REWRITE_TAC[casn; cacs] THEN + AP_TERM_TAC THEN AP_TERM_TAC THEN + MATCH_MP_TAC(COMPLEX_RING `w = z ==> z + ii * s = ii * s + w`) THEN + MATCH_MP_TAC CSQRT_UNIQUE THEN + ASM_REWRITE_TAC[CSQRT] THEN CONV_TAC COMPLEX_RING);; + +let CSIN_CACS = prove + (`!z. &0 < Re z \/ Re(z) = &0 /\ &0 <= Im z + ==> csin(cacs z) = csqrt(Cx(&1) - z pow 2)`, + GEN_TAC THEN DISCH_TAC THEN + GEN_REWRITE_TAC RAND_CONV [GSYM CSIN_CASN] THEN + AP_TERM_TAC THEN MATCH_MP_TAC CACS_CASN_SQRT_POS THEN + ASM_REWRITE_TAC[]);; + +let CCOS_CASN = prove + (`!z. &0 < Re z \/ Re(z) = &0 /\ &0 <= Im z + ==> ccos(casn z) = csqrt(Cx(&1) - z pow 2)`, + GEN_TAC THEN DISCH_TAC THEN + GEN_REWRITE_TAC RAND_CONV [GSYM CCOS_CACS] THEN + AP_TERM_TAC THEN MATCH_MP_TAC CASN_CACS_SQRT_POS THEN + ASM_REWRITE_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* Real arcsin. *) +(* ------------------------------------------------------------------------- *) + +let asn = new_definition `asn(x) = Re(casn(Cx x))`;; + +let REAL_ASN = prove + (`!z. real z /\ abs(Re z) <= &1 ==> real(casn z)`, + GEN_TAC THEN REWRITE_TAC[IMP_CONJ] THEN + GEN_REWRITE_TAC LAND_CONV [REAL] THEN + DISCH_THEN(SUBST1_TAC o SYM) THEN SPEC_TAC(`Re z`,`x:real`) THEN + REWRITE_TAC[real; casn; COMPLEX_MUL_LNEG; IM_NEG; IM_MUL_II] THEN + GEN_TAC THEN REWRITE_TAC[RE_CX; REAL_NEG_EQ_0] THEN DISCH_TAC THEN + MATCH_MP_TAC NORM_CEXP_IMAGINARY THEN + SIMP_TAC[CEXP_CLOG; CASN_BODY_LEMMA; NORM_EQ_SQUARE] THEN + REWRITE_TAC[DOT_SQUARE_NORM; COMPLEX_SQNORM] THEN + REWRITE_TAC[RE_ADD; IM_ADD; RE_MUL_II; IM_MUL_II; RE_CX; IM_CX] THEN + ASM_SIMP_TAC[GSYM CX_POW; GSYM CX_SUB; GSYM CX_SQRT; REAL_SUB_LE; + ABS_SQUARE_LE_1; RE_CX; IM_CX; REAL_NEG_0; REAL_ADD_LID; + SQRT_POW_2] THEN + REAL_ARITH_TAC);; + +let CX_ASN = prove + (`!x. abs(x) <= &1 ==> Cx(asn x) = casn(Cx x)`, + REWRITE_TAC[asn] THEN MESON_TAC[REAL; RE_CX; REAL_CX; REAL_ASN]);; + +let SIN_ASN = prove + (`!y. --(&1) <= y /\ y <= &1 ==> sin(asn(y)) = y`, + REWRITE_TAC[REAL_ARITH `--(&1) <= y /\ y <= &1 <=> abs(y) <= &1`] THEN + ONCE_REWRITE_TAC[GSYM CX_INJ] THEN SIMP_TAC[CX_ASN; CX_SIN; CSIN_CASN]);; + +let ASN_SIN = prove + (`!x. --(pi / &2) <= x /\ x <= pi / &2 ==> asn(sin(x)) = x`, + ONCE_REWRITE_TAC[GSYM CX_INJ] THEN SIMP_TAC[CX_ASN; SIN_BOUND; CX_SIN] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC CASN_CSIN THEN + REWRITE_TAC[IM_CX; RE_CX] THEN REPEAT(POP_ASSUM MP_TAC) THEN + REAL_ARITH_TAC);; + +let ASN_BOUNDS_LT = prove + (`!y. --(&1) < y /\ y < &1 ==> --(pi / &2) < asn(y) /\ asn(y) < pi / &2`, + GEN_TAC THEN REWRITE_TAC[asn] THEN + MP_TAC(SPEC `Cx y` CASN_BOUNDS) THEN + REWRITE_TAC[RE_CX] THEN REAL_ARITH_TAC);; + +let ASN_0 = prove + (`asn(&0) = &0`, + REWRITE_TAC[asn; CASN_0; RE_CX]);; + +let ASN_1 = prove + (`asn(&1) = pi / &2`, + REWRITE_TAC[asn; CASN_1; RE_CX]);; + +let ASN_NEG_1 = prove + (`asn(-- &1) = --(pi / &2)`, + REWRITE_TAC[asn; CX_NEG; CASN_NEG_1; RE_CX; RE_NEG]);; + +let ASN_BOUNDS = prove + (`!y. --(&1) <= y /\ y <= &1 ==> --(pi / &2) <= asn(y) /\ asn(y) <= pi / &2`, + REWRITE_TAC[REAL_LE_LT] THEN REPEAT STRIP_TAC THEN + MAP_EVERY MP_TAC [ASN_1; ASN_NEG_1; SPEC `y:real` ASN_BOUNDS_LT] THEN + ASM_REWRITE_TAC[] THEN REPEAT(POP_ASSUM MP_TAC) THEN + MP_TAC PI_POS THEN REAL_ARITH_TAC);; + +let ASN_NEG = prove + (`!x. -- &1 <= x /\ x <= &1 ==> asn(--x) = --asn(x)`, + GEN_TAC THEN DISCH_TAC THEN + FIRST_ASSUM(fun th -> GEN_REWRITE_TAC (LAND_CONV o RAND_CONV o RAND_CONV) + [GSYM(MATCH_MP SIN_ASN th)]) THEN + REWRITE_TAC[GSYM SIN_NEG] THEN MATCH_MP_TAC ASN_SIN THEN + REWRITE_TAC[REAL_ARITH `--a <= --x /\ --x <= a <=> --a <= x /\ x <= a`] THEN + ASM_SIMP_TAC[ASN_BOUNDS]);; + +let COS_ASN_NZ = prove + (`!x. --(&1) < x /\ x < &1 ==> ~(cos(asn(x)) = &0)`, + ONCE_REWRITE_TAC[GSYM CX_INJ] THEN SIMP_TAC[CX_ASN; CX_COS; + REAL_ARITH `--(&1) < x /\ x < &1 ==> abs(x) <= &1`] THEN + GEN_TAC THEN STRIP_TAC THEN MATCH_MP_TAC CCOS_CASN_NZ THEN + SIMP_TAC[COMPLEX_RING `x pow 2 = Cx(&1) <=> x = Cx(&1) \/ x = --Cx(&1)`] THEN + REWRITE_TAC[GSYM CX_NEG; CX_INJ] THEN + ASM_REAL_ARITH_TAC);; + +let ASN_MONO_LT_EQ = prove + (`!x y. abs(x) <= &1 /\ abs(y) <= &1 ==> (asn(x) < asn(y) <=> x < y)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC EQ_TRANS THEN + EXISTS_TAC `sin(asn(x)) < sin(asn(y))` THEN CONJ_TAC THENL + [CONV_TAC SYM_CONV THEN MATCH_MP_TAC SIN_MONO_LT_EQ THEN + ONCE_REWRITE_TAC[CONJ_ASSOC] THEN CONJ_TAC THEN MATCH_MP_TAC ASN_BOUNDS; + BINOP_TAC THEN MATCH_MP_TAC SIN_ASN] THEN + ASM_REAL_ARITH_TAC);; + +let ASN_MONO_LE_EQ = prove + (`!x y. abs(x) <= &1 /\ abs(y) <= &1 ==> (asn(x) <= asn(y) <=> x <= y)`, + REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM REAL_NOT_LT] THEN + ASM_SIMP_TAC[ASN_MONO_LT_EQ]);; + +let ASN_MONO_LT = prove + (`!x y. --(&1) <= x /\ x < y /\ y <= &1 ==> asn(x) < asn(y)`, + MP_TAC ASN_MONO_LT_EQ THEN REPEAT(MATCH_MP_TAC MONO_FORALL THEN GEN_TAC) THEN + REAL_ARITH_TAC);; + +let ASN_MONO_LE = prove + (`!x y. --(&1) <= x /\ x <= y /\ y <= &1 ==> asn(x) <= asn(y)`, + MP_TAC ASN_MONO_LE_EQ THEN REPEAT(MATCH_MP_TAC MONO_FORALL THEN GEN_TAC) THEN + REAL_ARITH_TAC);; + +let COS_ASN = prove + (`!x. --(&1) <= x /\ x <= &1 ==> cos(asn x) = sqrt(&1 - x pow 2)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC(GSYM SQRT_UNIQUE) THEN + ASM_SIMP_TAC[ASN_BOUNDS; COS_POS_PI_LE; REAL_EQ_SUB_RADD] THEN + ASM_MESON_TAC[SIN_ASN; SIN_CIRCLE; REAL_ADD_SYM]);; + +(* ------------------------------------------------------------------------- *) +(* Real arccosine. *) +(* ------------------------------------------------------------------------- *) + +let acs = new_definition `acs(x) = Re(cacs(Cx x))`;; + +let REAL_ACS = prove + (`!z. real z /\ abs(Re z) <= &1 ==> real(cacs z)`, + GEN_TAC THEN REWRITE_TAC[IMP_CONJ] THEN + GEN_REWRITE_TAC LAND_CONV [REAL] THEN + DISCH_THEN(SUBST1_TAC o SYM) THEN SPEC_TAC(`Re z`,`x:real`) THEN + REWRITE_TAC[real; cacs; COMPLEX_MUL_LNEG; IM_NEG; IM_MUL_II] THEN + GEN_TAC THEN REWRITE_TAC[RE_CX; REAL_NEG_EQ_0] THEN DISCH_TAC THEN + MATCH_MP_TAC NORM_CEXP_IMAGINARY THEN + SIMP_TAC[CEXP_CLOG; CACS_BODY_LEMMA; NORM_EQ_SQUARE] THEN + REWRITE_TAC[DOT_SQUARE_NORM; COMPLEX_SQNORM] THEN + REWRITE_TAC[RE_ADD; IM_ADD; RE_MUL_II; IM_MUL_II; RE_CX; IM_CX] THEN + ASM_SIMP_TAC[GSYM CX_POW; GSYM CX_SUB; GSYM CX_SQRT; REAL_SUB_LE; + ABS_SQUARE_LE_1; RE_CX; IM_CX; REAL_NEG_0; REAL_ADD_LID; + SQRT_POW_2] THEN + REAL_ARITH_TAC);; + +let CX_ACS = prove + (`!x. abs(x) <= &1 ==> Cx(acs x) = cacs(Cx x)`, + REWRITE_TAC[acs] THEN MESON_TAC[REAL; RE_CX; REAL_CX; REAL_ACS]);; + +let COS_ACS = prove + (`!y. --(&1) <= y /\ y <= &1 ==> cos(acs(y)) = y`, + REWRITE_TAC[REAL_ARITH `--(&1) <= y /\ y <= &1 <=> abs(y) <= &1`] THEN + ONCE_REWRITE_TAC[GSYM CX_INJ] THEN SIMP_TAC[CX_ACS; CX_COS; CCOS_CACS]);; + +let ACS_COS = prove + (`!x. &0 <= x /\ x <= pi ==> acs(cos(x)) = x`, + ONCE_REWRITE_TAC[GSYM CX_INJ] THEN SIMP_TAC[CX_ACS; COS_BOUND; CX_COS] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC CACS_CCOS THEN + REWRITE_TAC[IM_CX; RE_CX] THEN ASM_REAL_ARITH_TAC);; + +let ACS_BOUNDS_LT = prove + (`!y. --(&1) < y /\ y < &1 ==> &0 < acs(y) /\ acs(y) < pi`, + GEN_TAC THEN REWRITE_TAC[acs] THEN + MP_TAC(SPEC `Cx y` CACS_BOUNDS) THEN + REWRITE_TAC[RE_CX] THEN REAL_ARITH_TAC);; + +let ACS_0 = prove + (`acs(&0) = pi / &2`, + REWRITE_TAC[acs; CACS_0; RE_CX]);; + +let ACS_1 = prove + (`acs(&1) = &0`, + REWRITE_TAC[acs; CACS_1; RE_CX]);; + +let ACS_NEG_1 = prove + (`acs(-- &1) = pi`, + REWRITE_TAC[acs; CX_NEG; CACS_NEG_1; RE_CX; RE_NEG]);; + +let ACS_BOUNDS = prove + (`!y. --(&1) <= y /\ y <= &1 ==> &0 <= acs(y) /\ acs(y) <= pi`, + REWRITE_TAC[REAL_LE_LT] THEN REPEAT STRIP_TAC THEN + MAP_EVERY MP_TAC [ACS_1; ACS_NEG_1; SPEC `y:real` ACS_BOUNDS_LT] THEN + ASM_REWRITE_TAC[] THEN REPEAT(POP_ASSUM MP_TAC) THEN + MP_TAC PI_POS THEN REAL_ARITH_TAC);; + +let ACS_NEG = prove + (`!x. -- &1 <= x /\ x <= &1 ==> acs(--x) = pi - acs(x)`, + GEN_TAC THEN DISCH_TAC THEN + FIRST_ASSUM(fun th -> GEN_REWRITE_TAC (LAND_CONV o RAND_CONV o RAND_CONV) + [GSYM(MATCH_MP COS_ACS th)]) THEN + ONCE_REWRITE_TAC[GSYM COS_NEG] THEN REWRITE_TAC[GSYM COS_PERIODIC_PI] THEN + REWRITE_TAC[REAL_ARITH `--x + y:real = y - x`] THEN MATCH_MP_TAC ACS_COS THEN + SIMP_TAC[REAL_ARITH `&0 <= p - x /\ p - x <= p <=> &0 <= x /\ x <= p`] THEN + ASM_SIMP_TAC[ACS_BOUNDS]);; + +let SIN_ACS_NZ = prove + (`!x. --(&1) < x /\ x < &1 ==> ~(sin(acs(x)) = &0)`, + ONCE_REWRITE_TAC[GSYM CX_INJ] THEN SIMP_TAC[CX_ACS; CX_SIN; + REAL_ARITH `--(&1) < x /\ x < &1 ==> abs(x) <= &1`] THEN + GEN_TAC THEN STRIP_TAC THEN MATCH_MP_TAC CSIN_CACS_NZ THEN + SIMP_TAC[COMPLEX_RING `x pow 2 = Cx(&1) <=> x = Cx(&1) \/ x = --Cx(&1)`] THEN + REWRITE_TAC[GSYM CX_NEG; CX_INJ] THEN + ASM_REAL_ARITH_TAC);; + +let ACS_MONO_LT_EQ = prove + (`!x y. abs(x) <= &1 /\ abs(y) <= &1 ==> (acs(x) < acs(y) <=> y < x)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC EQ_TRANS THEN + EXISTS_TAC `cos(acs(y)) < cos(acs(x))` THEN CONJ_TAC THENL + [CONV_TAC SYM_CONV THEN MATCH_MP_TAC COS_MONO_LT_EQ THEN + ONCE_REWRITE_TAC[CONJ_ASSOC] THEN CONJ_TAC THEN MATCH_MP_TAC ACS_BOUNDS; + BINOP_TAC THEN MATCH_MP_TAC COS_ACS] THEN + ASM_REAL_ARITH_TAC);; + +let ACS_MONO_LE_EQ = prove + (`!x y. abs(x) <= &1 /\ abs(y) <= &1 ==> (acs(x) <= acs(y) <=> y <= x)`, + REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM REAL_NOT_LT] THEN + ASM_SIMP_TAC[ACS_MONO_LT_EQ]);; + +let ACS_MONO_LT = prove + (`!x y. --(&1) <= x /\ x < y /\ y <= &1 ==> acs(y) < acs(x)`, + REPEAT GEN_TAC THEN + MP_TAC(SPECL [`y:real`; `x:real`] ACS_MONO_LT_EQ) THEN + REAL_ARITH_TAC);; + +let ACS_MONO_LE = prove + (`!x y. --(&1) <= x /\ x <= y /\ y <= &1 ==> acs(y) <= acs(x)`, + REPEAT GEN_TAC THEN + MP_TAC(SPECL [`y:real`; `x:real`] ACS_MONO_LE_EQ) THEN + REAL_ARITH_TAC);; + +let SIN_ACS = prove + (`!x. --(&1) <= x /\ x <= &1 ==> sin(acs x) = sqrt(&1 - x pow 2)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC(GSYM SQRT_UNIQUE) THEN + ASM_SIMP_TAC[ACS_BOUNDS; SIN_POS_PI_LE; REAL_EQ_SUB_RADD] THEN + ASM_MESON_TAC[COS_ACS; SIN_CIRCLE]);; + +let ACS_INJ = prove + (`!x y. abs(x) <= &1 /\ abs(y) <= &1 ==> (acs x = acs y <=> x = y)`, + REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM REAL_LE_ANTISYM] THEN + ASM_SIMP_TAC[ACS_MONO_LE_EQ] THEN REAL_ARITH_TAC);; + +(* ------------------------------------------------------------------------- *) +(* Some interrelationships among the real inverse trig functions. *) +(* ------------------------------------------------------------------------- *) + +let ACS_ATN = prove + (`!x. -- &1 < x /\ x < &1 ==> acs(x) = pi / &2 - atn(x / sqrt(&1 - x pow 2))`, + REPEAT STRIP_TAC THEN + ONCE_REWRITE_TAC[REAL_ARITH `x:real = p - y <=> y - (p - x) = &0`] THEN + MATCH_MP_TAC SIN_EQ_0_PI THEN + ASM_SIMP_TAC[ATN_BOUND; ACS_BOUNDS; REAL_LT_IMP_LE; REAL_ARITH + `abs(x) < pi / &2 /\ &0 <= y /\ y <= pi + ==> --pi < x - (pi / &2 - y) /\ x - (pi / &2 - y) < pi`] THEN + SUBGOAL_THEN `tan(atn(x / sqrt(&1 - x pow 2))) = tan(pi / &2 - acs x)` + MP_TAC THENL + [REWRITE_TAC[TAN_COT; ATN_TAN] THEN REWRITE_TAC[tan] THEN + ASM_SIMP_TAC[SIN_ACS; COS_ACS; REAL_LT_IMP_LE; REAL_INV_DIV]; + ALL_TAC] THEN + GEN_REWRITE_TAC LAND_CONV [GSYM REAL_SUB_0] THEN + ASM_SIMP_TAC[SIN_ACS_NZ; GSYM SIN_COS; COS_ATN_NZ; REAL_SUB_TAN; REAL_FIELD + `~(y = &0) /\ ~(z = &0) ==> (x / (y * z) = &0 <=> x = &0)`]);; + +let ASN_PLUS_ACS = prove + (`!x. -- &1 <= x /\ x <= &1 ==> asn(x) + acs(x) = pi / &2`, + REPEAT STRIP_TAC THEN + ONCE_REWRITE_TAC[REAL_ARITH `x + y:real = p <=> x = p - y`] THEN + MATCH_MP_TAC SIN_INJ_PI THEN + ASM_SIMP_TAC[SIN_PI2; COS_PI2; SIN_SUB; REAL_MUL_LZERO; REAL_SUB_RZERO] THEN + ASM_SIMP_TAC[SIN_ASN; COS_ACS; REAL_MUL_LID] THEN + REWRITE_TAC[REAL_ARITH `--p <= p - x <=> x <= &2 * p`; + REAL_ARITH `p - x <= p <=> &0 <= x`] THEN + ASM_SIMP_TAC[ASN_BOUNDS; ACS_BOUNDS; REAL_ARITH `&2 * x / &2 = x`]);; + +let ASN_ACS = prove + (`!x. -- &1 <= x /\ x <= &1 ==> asn(x) = pi / &2 - acs(x)`, + SIMP_TAC[REAL_EQ_SUB_LADD; ASN_PLUS_ACS]);; + +let ACS_ASN = prove + (`!x. -- &1 <= x /\ x <= &1 ==> acs(x) = pi / &2 - asn(x)`, + SIMP_TAC[ASN_ACS] THEN REAL_ARITH_TAC);; + +let ASN_ATN = prove + (`!x. -- &1 < x /\ x < &1 ==> asn(x) = atn(x / sqrt(&1 - x pow 2))`, + SIMP_TAC[ASN_ACS; REAL_LT_IMP_LE; ACS_ATN] THEN REAL_ARITH_TAC);; + +let ASN_ACS_SQRT_POS = prove + (`!x. &0 <= x /\ x <= &1 ==> asn(x) = acs(sqrt(&1 - x pow 2))`, + REPEAT STRIP_TAC THEN REWRITE_TAC[asn; acs] THEN + ASM_SIMP_TAC[CX_SQRT; REAL_SUB_LE; REAL_POW_1_LE; CX_SUB; CX_POW] THEN + AP_TERM_TAC THEN MATCH_MP_TAC CASN_CACS_SQRT_POS THEN + ASM_REWRITE_TAC[RE_CX; IM_CX] THEN ASM_REAL_ARITH_TAC);; + +let ASN_ACS_SQRT_NEG = prove + (`!x. -- &1 <= x /\ x <= &0 ==> asn(x) = --acs(sqrt(&1 - x pow 2))`, + REPEAT STRIP_TAC THEN + ONCE_REWRITE_TAC[REAL_ARITH `x = --y <=> (--x:real) = y`] THEN + ASM_SIMP_TAC[GSYM ASN_NEG; REAL_ARITH `x <= &0 ==> x <= &1`] THEN + ONCE_REWRITE_TAC[REAL_ARITH `(x:real) pow 2 = (--x) pow 2`] THEN + MATCH_MP_TAC ASN_ACS_SQRT_POS THEN ASM_REAL_ARITH_TAC);; + +let ACS_ASN_SQRT_POS = prove + (`!x. &0 <= x /\ x <= &1 ==> acs(x) = asn(sqrt(&1 - x pow 2))`, + REPEAT STRIP_TAC THEN REWRITE_TAC[asn; acs] THEN + ASM_SIMP_TAC[CX_SQRT; REAL_SUB_LE; REAL_POW_1_LE; CX_SUB; CX_POW] THEN + AP_TERM_TAC THEN MATCH_MP_TAC CACS_CASN_SQRT_POS THEN + ASM_REWRITE_TAC[RE_CX; IM_CX] THEN ASM_REAL_ARITH_TAC);; + +let ACS_ASN_SQRT_NEG = prove + (`!x. -- &1 <= x /\ x <= &0 ==> acs(x) = pi - asn(sqrt(&1 - x pow 2))`, + REPEAT STRIP_TAC THEN MP_TAC(SPEC `--x:real` ACS_ASN_SQRT_POS) THEN + ANTS_TAC THENL [ASM_REAL_ARITH_TAC; SIMP_TAC[REAL_POW_NEG; ARITH]] THEN + DISCH_THEN(SUBST1_TAC o SYM) THEN + GEN_REWRITE_TAC (LAND_CONV o RAND_CONV) [GSYM REAL_NEG_NEG] THEN + MATCH_MP_TAC ACS_NEG THEN ASM_REAL_ARITH_TAC);; + +(* ------------------------------------------------------------------------- *) +(* More delicate continuity results for arcsin and arccos. *) +(* ------------------------------------------------------------------------- *) + +let CONTINUOUS_ON_CASN_REAL = prove + (`casn continuous_on {w | real w /\ abs(Re w) <= &1}`, + MATCH_MP_TAC CONTINUOUS_ON_SUBSET THEN + EXISTS_TAC `IMAGE csin {z | real z /\ abs(Re z) <= pi / &2}` THEN + CONJ_TAC THENL + [MATCH_MP_TAC CONTINUOUS_ON_INVERSE THEN + REWRITE_TAC[CONTINUOUS_ON_CSIN] THEN CONJ_TAC THENL + [REWRITE_TAC[COMPACT_EQ_BOUNDED_CLOSED] THEN CONJ_TAC THENL + [MATCH_MP_TAC BOUNDED_SUBSET THEN + EXISTS_TAC `cball(Cx(&0),pi / &2)` THEN + REWRITE_TAC[BOUNDED_CBALL; SUBSET; IN_ELIM_THM; IN_CBALL] THEN + REWRITE_TAC[dist; COMPLEX_SUB_LZERO; NORM_NEG; real] THEN + X_GEN_TAC `z:complex` THEN + MP_TAC(SPEC `z:complex` COMPLEX_NORM_LE_RE_IM) THEN REAL_ARITH_TAC; + SIMP_TAC[SET_RULE `{x | P x /\ Q x} = {x | P x} INTER {x | Q x}`; + GSYM REAL_BOUNDS_LE] THEN + SIMP_TAC[CLOSED_INTER; CLOSED_REAL_SET; CLOSED_HALFSPACE_RE_LE; + REWRITE_RULE[real_ge] CLOSED_HALFSPACE_RE_GE]]; + SIMP_TAC[SUBSET; IMP_CONJ; FORALL_REAL; IN_ELIM_THM; RE_CX] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC CASN_CSIN THEN + REWRITE_TAC[RE_CX; IM_CX] THEN ASM_REAL_ARITH_TAC]; + SIMP_TAC[SUBSET; IMP_CONJ; FORALL_REAL; IN_ELIM_THM; RE_CX; IN_IMAGE] THEN + X_GEN_TAC `x:real` THEN DISCH_TAC THEN + EXISTS_TAC `Cx(asn x)` THEN + ASM_SIMP_TAC[RE_CX; ASN_BOUNDS; REAL_BOUNDS_LE; REAL_CX; SIN_ASN; + GSYM CX_SIN] THEN + ASM_MESON_TAC[REAL_BOUNDS_LE; ASN_BOUNDS]]);; + +let CONTINUOUS_WITHIN_CASN_REAL = prove + (`!z. casn continuous (at z within {w | real w /\ abs(Re w) <= &1})`, + GEN_TAC THEN ASM_CASES_TAC `z IN {w | real w /\ abs(Re w) <= &1}` THENL + [ASM_SIMP_TAC[REWRITE_RULE[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN] + CONTINUOUS_ON_CASN_REAL]; + MATCH_MP_TAC CONTINUOUS_WITHIN_CLOSED_NONTRIVIAL THEN + ASM_REWRITE_TAC[] THEN REWRITE_TAC[GSYM REAL_BOUNDS_LE] THEN + ASM_SIMP_TAC[SET_RULE `{x | P x /\ Q x} = {x | P x} INTER {x | Q x}`] THEN + SIMP_TAC[CLOSED_INTER; CLOSED_REAL_SET; CLOSED_HALFSPACE_RE_LE; + REWRITE_RULE[real_ge] CLOSED_HALFSPACE_RE_GE]]);; + +let CONTINUOUS_ON_CACS_REAL = prove + (`cacs continuous_on {w | real w /\ abs(Re w) <= &1}`, + MATCH_MP_TAC CONTINUOUS_ON_SUBSET THEN + EXISTS_TAC `IMAGE ccos {z | real z /\ &0 <= Re z /\ Re z <= pi}` THEN + CONJ_TAC THENL + [MATCH_MP_TAC CONTINUOUS_ON_INVERSE THEN + REWRITE_TAC[CONTINUOUS_ON_CCOS] THEN CONJ_TAC THENL + [REWRITE_TAC[COMPACT_EQ_BOUNDED_CLOSED] THEN CONJ_TAC THENL + [MATCH_MP_TAC BOUNDED_SUBSET THEN + EXISTS_TAC `cball(Cx(&0),&2 * pi)` THEN + REWRITE_TAC[BOUNDED_CBALL; SUBSET; IN_ELIM_THM; IN_CBALL] THEN + REWRITE_TAC[dist; COMPLEX_SUB_LZERO; NORM_NEG; real] THEN + X_GEN_TAC `z:complex` THEN + MP_TAC(SPEC `z:complex` COMPLEX_NORM_LE_RE_IM) THEN REAL_ARITH_TAC; + SIMP_TAC[SET_RULE `{x | P x /\ Q x} = {x | P x} INTER {x | Q x}`] THEN + SIMP_TAC[CLOSED_INTER; CLOSED_REAL_SET; CLOSED_HALFSPACE_RE_LE; + REWRITE_RULE[real_ge] CLOSED_HALFSPACE_RE_GE]]; + SIMP_TAC[SUBSET; IMP_CONJ; FORALL_REAL; IN_ELIM_THM; RE_CX] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC CACS_CCOS THEN + REWRITE_TAC[RE_CX; IM_CX] THEN ASM_REAL_ARITH_TAC]; + SIMP_TAC[SUBSET; IMP_CONJ; FORALL_REAL; IN_ELIM_THM; RE_CX; IN_IMAGE] THEN + X_GEN_TAC `x:real` THEN DISCH_TAC THEN + EXISTS_TAC `Cx(acs x)` THEN + ASM_SIMP_TAC[RE_CX; ACS_BOUNDS; REAL_BOUNDS_LE; REAL_CX; COS_ACS; + GSYM CX_COS]]);; + +let CONTINUOUS_WITHIN_CACS_REAL = prove + (`!z. cacs continuous (at z within {w | real w /\ abs(Re w) <= &1})`, + GEN_TAC THEN ASM_CASES_TAC `z IN {w | real w /\ abs(Re w) <= &1}` THENL + [ASM_SIMP_TAC[REWRITE_RULE[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN] + CONTINUOUS_ON_CACS_REAL]; + MATCH_MP_TAC CONTINUOUS_WITHIN_CLOSED_NONTRIVIAL THEN + ASM_REWRITE_TAC[] THEN REWRITE_TAC[GSYM REAL_BOUNDS_LE] THEN + ASM_SIMP_TAC[SET_RULE `{x | P x /\ Q x} = {x | P x} INTER {x | Q x}`] THEN + SIMP_TAC[CLOSED_INTER; CLOSED_REAL_SET; CLOSED_HALFSPACE_RE_LE; + REWRITE_RULE[real_ge] CLOSED_HALFSPACE_RE_GE]]);; + +(* ------------------------------------------------------------------------- *) +(* Some limits, most involving sequences of transcendentals. *) +(* ------------------------------------------------------------------------- *) + +let LIM_LOG_OVER_POWER = prove + (`!s. &0 < Re s + ==> ((\n. clog(Cx(&n)) / Cx(&n) cpow s) --> Cx(&0)) sequentially`, + REPEAT STRIP_TAC THEN REWRITE_TAC[LIM_SEQUENTIALLY] THEN + FIRST_ASSUM(MP_TAC o SPEC `&2` o MATCH_MP REAL_ARCH) THEN + DISCH_THEN(X_CHOOSE_THEN `N:num` MP_TAC) THEN + ASM_CASES_TAC `N = 0` THEN + ASM_REWRITE_TAC[REAL_MUL_LZERO; REAL_OF_NUM_LT; ARITH] THEN DISCH_TAC THEN + X_GEN_TAC `e:real` THEN DISCH_TAC THEN + MP_TAC(ISPEC `(&N / e) pow N + &1` REAL_ARCH_SIMPLE) THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `M:num` THEN + ASM_CASES_TAC `M = 0` THENL + [ASM_REWRITE_TAC[] THEN MATCH_MP_TAC(TAUT `~a ==> a ==> b`) THEN + MATCH_MP_TAC(REAL_ARITH `&0 <= x ==> ~(x + &1 <= &0)`) THEN + ASM_SIMP_TAC[REAL_POW_LE; REAL_POS; REAL_LT_IMP_LE; REAL_LE_DIV]; + ALL_TAC] THEN + STRIP_TAC THEN X_GEN_TAC `n:num` THEN DISCH_TAC THEN + SUBGOAL_THEN `~(n = 0)` ASSUME_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN + REWRITE_TAC[dist; COMPLEX_SUB_RZERO; COMPLEX_NORM_DIV] THEN + ASM_SIMP_TAC[NORM_CPOW_REAL; REAL_CX; RE_CX; REAL_OF_NUM_LT; LT_NZ] THEN + ASM_SIMP_TAC[REAL_LT_LDIV_EQ; REAL_EXP_POS_LT] THEN + ASM_SIMP_TAC[GSYM CX_LOG; REAL_OF_NUM_LT; LT_NZ; COMPLEX_NORM_CX] THEN + ASM_SIMP_TAC[real_abs; LOG_POS; REAL_OF_NUM_LE; + ARITH_RULE `~(n = 0) ==> 1 <= n`] THEN + MATCH_MP_TAC REAL_LET_TRANS THEN + EXISTS_TAC `&N * log(exp(log(&n) / &N))` THEN CONJ_TAC THENL + [ASM_SIMP_TAC[LOG_EXP; REAL_LE_REFL; REAL_DIV_LMUL; REAL_OF_NUM_EQ]; + ALL_TAC] THEN + MATCH_MP_TAC REAL_LET_TRANS THEN EXISTS_TAC `&N * exp(log(&n) / &N)` THEN + CONJ_TAC THENL + [MATCH_MP_TAC REAL_LE_LMUL THEN REWRITE_TAC[REAL_POS] THEN + MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `log(&1 + exp(log(&n) / &N))` THEN CONJ_TAC THENL + [MATCH_MP_TAC LOG_MONO_LE_IMP THEN + REWRITE_TAC[REAL_EXP_POS_LT] THEN REAL_ARITH_TAC; + MATCH_MP_TAC LOG_LE THEN REWRITE_TAC[REAL_EXP_POS_LE]]; + ALL_TAC] THEN + SIMP_TAC[GSYM REAL_LT_RDIV_EQ; REAL_EXP_POS_LT] THEN + REWRITE_TAC[real_div; GSYM REAL_MUL_ASSOC; GSYM REAL_EXP_NEG; + GSYM REAL_EXP_ADD] THEN + ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN + ASM_SIMP_TAC[GSYM REAL_LT_LDIV_EQ] THEN + MATCH_MP_TAC REAL_LTE_TRANS THEN EXISTS_TAC `exp(log(&n) / &N)` THEN + CONJ_TAC THENL + [ALL_TAC; + REWRITE_TAC[REAL_EXP_MONO_LE] THEN + REWRITE_TAC[REAL_ARITH + `l / n <= r * l + --(l * inv n) <=> &0 <= l * (r - &2 / n)`] THEN + MATCH_MP_TAC REAL_LE_MUL THEN + ASM_SIMP_TAC[LOG_POS; REAL_OF_NUM_LE; ARITH_RULE `1 <= n <=> ~(n = 0)`; + REAL_SUB_LE; REAL_LE_LDIV_EQ; REAL_OF_NUM_LT; LT_NZ] THEN + ASM_REAL_ARITH_TAC] THEN + W(MP_TAC o PART_MATCH (rand o rand) LOG_MONO_LT o snd) THEN + ASM_SIMP_TAC[REAL_LT_DIV; REAL_OF_NUM_LT; LT_NZ; REAL_EXP_POS_LT] THEN + DISCH_THEN(SUBST1_TAC o SYM) THEN REWRITE_TAC[LOG_EXP] THEN + ASM_SIMP_TAC[REAL_LT_RDIV_EQ; REAL_OF_NUM_LT; LT_NZ] THEN + ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN + ASM_SIMP_TAC[GSYM LOG_POW; REAL_LT_DIV; REAL_OF_NUM_LT; LT_NZ] THEN + MATCH_MP_TAC LOG_MONO_LT_IMP THEN + ASM_SIMP_TAC[REAL_POW_LT; REAL_LT_DIV; REAL_OF_NUM_LT; LT_NZ] THEN + MATCH_MP_TAC REAL_LTE_TRANS THEN EXISTS_TAC `&M` THEN + ASM_REWRITE_TAC[REAL_OF_NUM_LE] THEN ASM_REAL_ARITH_TAC);; + +let LIM_LOG_OVER_N = prove + (`((\n. clog(Cx(&n)) / Cx(&n)) --> Cx(&0)) sequentially`, + MP_TAC(SPEC `Cx(&1)` LIM_LOG_OVER_POWER) THEN SIMP_TAC[RE_CX; REAL_LT_01] THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] LIM_TRANSFORM_EVENTUALLY) THEN + REWRITE_TAC[EVENTUALLY_SEQUENTIALLY; CPOW_N; CX_INJ] THEN EXISTS_TAC `1` THEN + SIMP_TAC[COMPLEX_POW_1; REAL_OF_NUM_EQ; ARITH_RULE `1 <= n <=> ~(n = 0)`]);; + +let LIM_1_OVER_POWER = prove + (`!s. &0 < Re s + ==> ((\n. Cx(&1) / Cx(&n) cpow s) --> Cx(&0)) sequentially`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC LIM_NULL_COMPLEX_BOUND THEN + EXISTS_TAC `\n. clog(Cx(&n)) / Cx(&n) cpow s` THEN + ASM_SIMP_TAC[LIM_LOG_OVER_POWER] THEN + REWRITE_TAC[EVENTUALLY_SEQUENTIALLY] THEN + MP_TAC(ISPEC `exp(&1)` REAL_ARCH_SIMPLE) THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `N:num` THEN + ASM_CASES_TAC `N = 0` THENL + [ASM_SIMP_TAC[GSYM REAL_NOT_LT; REAL_EXP_POS_LT]; ALL_TAC] THEN + DISCH_TAC THEN X_GEN_TAC `n:num` THEN DISCH_TAC THEN + REWRITE_TAC[complex_div; COMPLEX_NORM_MUL] THEN + MATCH_MP_TAC REAL_LE_RMUL THEN REWRITE_TAC[NORM_POS_LE] THEN + SUBGOAL_THEN `~(n = 0)` ASSUME_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN + ASM_SIMP_TAC[GSYM CX_LOG; REAL_OF_NUM_LT; LT_NZ; + COMPLEX_NORM_CX; REAL_ABS_NUM] THEN + MATCH_MP_TAC(REAL_ARITH `x <= y ==> x <= abs y`) THEN + ONCE_REWRITE_TAC[GSYM REAL_EXP_MONO_LE] THEN + ASM_SIMP_TAC[EXP_LOG; REAL_OF_NUM_LT; LT_NZ] THEN + RULE_ASSUM_TAC(REWRITE_RULE[GSYM REAL_OF_NUM_LE]) THEN ASM_REAL_ARITH_TAC);; + +let LIM_1_OVER_N = prove + (`((\n. Cx(&1) / Cx(&n)) --> Cx(&0)) sequentially`, + MP_TAC(SPEC `Cx(&1)` LIM_1_OVER_POWER) THEN SIMP_TAC[RE_CX; REAL_LT_01] THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] LIM_TRANSFORM_EVENTUALLY) THEN + REWRITE_TAC[EVENTUALLY_SEQUENTIALLY; CPOW_N; CX_INJ] THEN EXISTS_TAC `1` THEN + SIMP_TAC[COMPLEX_POW_1; REAL_OF_NUM_EQ; ARITH_RULE `1 <= n <=> ~(n = 0)`]);; + +let LIM_INV_N = prove + (`((\n. inv(Cx(&n))) --> Cx(&0)) sequentially`, + MP_TAC LIM_1_OVER_N THEN REWRITE_TAC[complex_div; COMPLEX_MUL_LID]);; + +let LIM_1_OVER_LOG = prove + (`((\n. Cx(&1) / clog(Cx(&n))) --> Cx(&0)) sequentially`, + REWRITE_TAC[LIM_SEQUENTIALLY] THEN X_GEN_TAC `e:real` THEN + DISCH_TAC THEN X_CHOOSE_TAC `N:num` (SPEC `exp(inv e)` REAL_ARCH_SIMPLE) THEN + EXISTS_TAC `N + 1` THEN X_GEN_TAC `n:num` THEN DISCH_TAC THEN + REWRITE_TAC[dist; COMPLEX_SUB_RZERO; COMPLEX_MUL_LID; complex_div] THEN + SUBGOAL_THEN `0 < n` ASSUME_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN + RULE_ASSUM_TAC(REWRITE_RULE + [GSYM REAL_OF_NUM_LT; GSYM REAL_OF_NUM_LE; GSYM REAL_OF_NUM_ADD]) THEN + ASM_SIMP_TAC[GSYM CX_LOG; COMPLEX_NORM_CX; COMPLEX_NORM_INV] THEN + GEN_REWRITE_TAC RAND_CONV [GSYM REAL_INV_INV] THEN + MATCH_MP_TAC REAL_LT_INV2 THEN ASM_REWRITE_TAC[REAL_LT_INV_EQ] THEN + MATCH_MP_TAC(REAL_ARITH `a < x ==> a < abs x`) THEN + ONCE_REWRITE_TAC[GSYM REAL_EXP_MONO_LT] THEN + ASM_SIMP_TAC[EXP_LOG] THEN ASM_REAL_ARITH_TAC);; + +let LIM_N_TIMES_POWN = prove + (`!z. norm(z) < &1 ==> ((\n. Cx(&n) * z pow n) --> Cx(&0)) sequentially`, + REPEAT STRIP_TAC THEN ASM_CASES_TAC `z = Cx(&0)` THEN + ASM_SIMP_TAC[COMPLEX_POW_ZERO; LIM_CASES_FINITE_SEQUENTIALLY; LIM_CONST; + COND_RAND; FINITE_SING; SING_GSPEC; COMPLEX_MUL_RZERO] THEN + MP_TAC LIM_LOG_OVER_N THEN + REWRITE_TAC[LIM_SEQUENTIALLY; dist; COMPLEX_SUB_RZERO] THEN + DISCH_THEN(MP_TAC o SPEC `log(inv(norm(z:complex))) / &2`) THEN + ASM_SIMP_TAC[LOG_POS_LT; REAL_INV_1_LT; COMPLEX_NORM_NZ; REAL_HALF] THEN + DISCH_THEN(X_CHOOSE_THEN `N1:num` (LABEL_TAC "+")) THEN + X_GEN_TAC `e:real` THEN DISCH_TAC THEN + FIRST_ASSUM(X_CHOOSE_THEN `N2:num` STRIP_ASSUME_TAC o + GEN_REWRITE_RULE I [REAL_ARCH_INV]) THEN + EXISTS_TAC `MAX 1 (MAX N1 N2)` THEN + REWRITE_TAC[ARITH_RULE `MAX a b <= c <=> a <= c /\ b <= c`] THEN + X_GEN_TAC `n:num` THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `n:num`) THEN + ASM_SIMP_TAC[GSYM CX_LOG; REAL_OF_NUM_LT; LE_1; GSYM CX_DIV; + COMPLEX_NORM_CX; REAL_ABS_DIV; REAL_ABS_NUM] THEN + ASM_SIMP_TAC[REAL_LT_RDIV_EQ; REAL_OF_NUM_LT; ARITH; real_abs; + LOG_POS; REAL_OF_NUM_LE] THEN + ONCE_REWRITE_TAC[REAL_ARITH `a / b * &2 = (&2 * a) / b`] THEN + ASM_SIMP_TAC[REAL_LT_LDIV_EQ; REAL_OF_NUM_LT; LE_1] THEN + GEN_REWRITE_TAC (LAND_CONV o RAND_CONV) [REAL_MUL_SYM] THEN + GEN_REWRITE_TAC LAND_CONV [GSYM REAL_EXP_MONO_LT] THEN + ASM_SIMP_TAC[REAL_EXP_N; EXP_LOG; REAL_OF_NUM_LT; LE_1; + REAL_LT_INV_EQ; COMPLEX_NORM_NZ] THEN + REWRITE_TAC[REAL_POW_INV] THEN + GEN_REWRITE_TAC (LAND_CONV o RAND_CONV) [GSYM REAL_MUL_LID] THEN + ASM_SIMP_TAC[GSYM real_div; REAL_LT_RDIV_EQ; REAL_POW_LT; COMPLEX_NORM_NZ; + COMPLEX_NORM_MUL; COMPLEX_NORM_NUM; COMPLEX_NORM_POW] THEN + DISCH_TAC THEN MATCH_MP_TAC REAL_LET_TRANS THEN EXISTS_TAC `inv(&N2)` THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `inv(&n)` THEN + ASM_SIMP_TAC[REAL_LE_INV2; REAL_OF_NUM_LE; REAL_OF_NUM_LT; LE_1] THEN + MATCH_MP_TAC REAL_LE_LCANCEL_IMP THEN EXISTS_TAC `&n` THEN + ASM_SIMP_TAC[REAL_MUL_RINV; REAL_LT_IMP_NZ; REAL_OF_NUM_LT; LE_1] THEN + ASM_REAL_ARITH_TAC);; + +let LIM_N_OVER_POWN = prove + (`!z. &1 < norm(z) ==> ((\n. Cx(&n) / z pow n) --> Cx(&0)) sequentially`, + ASM_SIMP_TAC[complex_div; GSYM COMPLEX_POW_INV; COMPLEX_NORM_INV; + REAL_INV_LT_1; LIM_N_TIMES_POWN]);; + +let LIM_POWN = prove + (`!z. norm(z) < &1 ==> ((\n. z pow n) --> Cx(&0)) sequentially`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC LIM_NULL_COMPARISON_COMPLEX THEN + EXISTS_TAC `\n. Cx(&n) * z pow n` THEN ASM_SIMP_TAC[LIM_N_TIMES_POWN] THEN + REWRITE_TAC[EVENTUALLY_SEQUENTIALLY] THEN EXISTS_TAC `1` THEN + REWRITE_TAC[COMPLEX_NORM_MUL; COMPLEX_NORM_CX; REAL_ABS_NUM] THEN + REWRITE_TAC[REAL_ARITH `a <= n * a <=> &0 <= (n - &1) * a`] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_LE_MUL THEN + ASM_REWRITE_TAC[NORM_POS_LE; REAL_SUB_LE; REAL_OF_NUM_LE]);; + +(* ------------------------------------------------------------------------- *) +(* Roots of unity. *) +(* ------------------------------------------------------------------------- *) + +let COMPLEX_ROOT_POLYFUN = prove + (`!n z a. + 1 <= n + ==> (z pow n = a <=> + vsum(0..n) (\i. (if i = 0 then --a else if i = n then Cx(&1) + else Cx(&0)) * z pow i) = Cx(&0))`, + ASM_SIMP_TAC[VSUM_CLAUSES_RIGHT; LE_1; LE_0] THEN + SIMP_TAC[VSUM_CLAUSES_LEFT; LE_0; ADD_CLAUSES] THEN + ASM_SIMP_TAC[LE_1; ARITH_RULE `1 <= n /\ 1 <= i /\ i <= n - 1 + ==> ~(i = n)`] THEN + REWRITE_TAC[COMPLEX_MUL_LZERO; complex_pow; COMPLEX_MUL_RID] THEN + REWRITE_TAC[GSYM COMPLEX_VEC_0; VSUM_0; VECTOR_ADD_RID] THEN + REWRITE_TAC[COMPLEX_VEC_0] THEN CONV_TAC COMPLEX_RING);; + +let COMPLEX_ROOT_UNITY = prove + (`!n j. ~(n = 0) + ==> cexp(Cx(&2) * Cx pi * ii * Cx(&j / &n)) pow n = Cx(&1)`, + REWRITE_TAC[GSYM CEXP_N; CX_DIV] THEN + ASM_SIMP_TAC[CX_INJ; complex_div; REAL_OF_NUM_EQ; COMPLEX_FIELD + `~(n = Cx(&0)) ==> n * t * p * ii * j * inv(n) = j * (ii * t * p)`] THEN + REWRITE_TAC[CEXP_N; GSYM CX_MUL] THEN + REWRITE_TAC[CEXP_EULER; GSYM CX_MUL; GSYM CX_SIN; GSYM CX_COS] THEN + REWRITE_TAC[COS_NPI; SIN_NPI; REAL_POW_NEG; COMPLEX_MUL_RZERO; + REAL_POW_ONE; ARITH_EVEN; COMPLEX_ADD_RID; COMPLEX_POW_ONE]);; + +let COMPLEX_ROOT_UNITY_EQ = prove + (`!n j k. ~(n = 0) + ==> (cexp(Cx(&2) * Cx pi * ii * Cx(&j / &n)) = + cexp(Cx(&2) * Cx pi * ii * Cx(&k / &n)) <=> (j == k) (mod n))`, + REPEAT STRIP_TAC THEN REWRITE_TAC[CEXP_EQ; num_congruent; CX_MUL] THEN + REWRITE_TAC[COMPLEX_RING + `t * p * ii * j = t * p * ii * k + (t * n * p) * ii <=> + (t * p * ii = Cx(&0)) \/ j - k = n`] THEN + SIMP_TAC[COMPLEX_ENTIRE; II_NZ; CX_INJ; PI_NZ; REAL_OF_NUM_EQ; ARITH] THEN + REWRITE_TAC[GSYM CX_SUB; CX_INJ] THEN + ASM_SIMP_TAC[REAL_OF_NUM_EQ; REAL_FIELD + `~(n = &0) ==> (j / n - k / n = m <=> j - k = n * m)`] THEN + REWRITE_TAC[int_congruent] THEN + REWRITE_TAC[int_eq; int_sub_th; int_mul_th; int_of_num_th] THEN + MESON_TAC[int_abstr; int_rep]);; + +let COMPLEX_ROOT_UNITY_EQ_1 = prove + (`!n j. ~(n = 0) + ==> (cexp(Cx(&2) * Cx pi * ii * Cx(&j / &n)) = Cx(&1) <=> + n divides j)`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN `Cx(&1) = cexp(Cx(&2) * Cx pi * ii * Cx(&n / &n))` + SUBST1_TAC THENL + [ASM_SIMP_TAC[REAL_DIV_REFL; REAL_OF_NUM_EQ; COMPLEX_MUL_RID] THEN + ONCE_REWRITE_TAC[COMPLEX_RING `t * p * ii = ii * t * p`] THEN + REWRITE_TAC[CEXP_EULER; GSYM CX_MUL; GSYM CX_SIN; GSYM CX_COS] THEN + REWRITE_TAC[COS_NPI; SIN_NPI] THEN SIMPLE_COMPLEX_ARITH_TAC; + ASM_SIMP_TAC[COMPLEX_ROOT_UNITY_EQ] THEN CONV_TAC NUMBER_RULE]);; + +let FINITE_CARD_COMPLEX_ROOTS_UNITY = prove + (`!n. 1 <= n + ==> FINITE {z | z pow n = Cx(&1)} /\ CARD {z | z pow n = Cx(&1)} <= n`, + REPEAT GEN_TAC THEN DISCH_TAC THEN ASM_SIMP_TAC[COMPLEX_ROOT_POLYFUN] THEN + MATCH_MP_TAC COMPLEX_POLYFUN_ROOTBOUND THEN + DISCH_THEN(MP_TAC o SPEC `n:num`) THEN + ASM_SIMP_TAC[IN_NUMSEG; LE_1; LE_0; LE_REFL] THEN CONV_TAC COMPLEX_RING);; + +let FINITE_COMPLEX_ROOTS_UNITY = prove + (`!n. ~(n = 0) ==> FINITE {z | z pow n = Cx(&1)}`, + SIMP_TAC[FINITE_CARD_COMPLEX_ROOTS_UNITY; LE_1]);; + +let FINITE_CARD_COMPLEX_ROOTS_UNITY_EXPLICIT = prove + (`!n. 1 <= n + ==> FINITE {cexp(Cx(&2) * Cx pi * ii * Cx(&j / &n)) | j | j < n} /\ + CARD {cexp(Cx(&2) * Cx pi * ii * Cx(&j / &n)) | j | j < n} = n`, + let lemma = prove (* So we don't need to load number theories yet *) + (`!x y n:num. (x == y) (mod n) /\ x < y + n /\ y < x + n ==> x = y`, + REWRITE_TAC[num_congruent; GSYM INT_OF_NUM_EQ; GSYM INT_OF_NUM_LT] THEN + REWRITE_TAC[GSYM INT_OF_NUM_ADD] THEN + REWRITE_TAC[INT_ARITH `x < y + n /\ y < x + n <=> abs(x - y:int) < n`] THEN + REPEAT GEN_TAC THEN REWRITE_TAC[int_congruent] THEN + DISCH_THEN(CONJUNCTS_THEN2 (X_CHOOSE_TAC `d:int`) MP_TAC) THEN + ONCE_REWRITE_TAC[GSYM INT_SUB_0] THEN + ASM_SIMP_TAC[INT_ABS_MUL; INT_ENTIRE; INT_ABS_NUM; + INT_ARITH `n * x:int < n <=> n * x < n * &1`] THEN + DISJ_CASES_TAC(INT_ARITH `&n:int = &0 \/ &0:int < &n`) THEN + ASM_SIMP_TAC[INT_LT_LMUL_EQ] THEN INT_ARITH_TAC) in + REWRITE_TAC[GSYM HAS_SIZE] THEN + REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC [SIMPLE_IMAGE_GEN] THEN + MATCH_MP_TAC HAS_SIZE_IMAGE_INJ THEN REWRITE_TAC[IN_ELIM_THM] THEN + ASM_SIMP_TAC[HAS_SIZE_NUMSEG_LT; COMPLEX_ROOT_UNITY_EQ; LE_1] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC lemma THEN EXISTS_TAC `n:num` THEN + ASM_REWRITE_TAC[] THEN ASM_ARITH_TAC);; + +let COMPLEX_ROOTS_UNITY = prove + (`!n. 1 <= n + ==> {z | z pow n = Cx(&1)} = + {cexp(Cx(&2) * Cx pi * ii * Cx(&j / &n)) | j | j < n}`, + REPEAT STRIP_TAC THEN CONV_TAC SYM_CONV THEN MATCH_MP_TAC CARD_SUBSET_LE THEN + ASM_SIMP_TAC[FINITE_CARD_COMPLEX_ROOTS_UNITY; + FINITE_CARD_COMPLEX_ROOTS_UNITY_EXPLICIT] THEN + GEN_REWRITE_TAC LAND_CONV [SIMPLE_IMAGE_GEN] THEN + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; IN_ELIM_THM] THEN + ASM_SIMP_TAC[COMPLEX_ROOT_UNITY; LE_1]);; + +let CARD_COMPLEX_ROOTS_UNITY = prove + (`!n. 1 <= n ==> CARD {z | z pow n = Cx(&1)} = n`, + SIMP_TAC[COMPLEX_ROOTS_UNITY; FINITE_CARD_COMPLEX_ROOTS_UNITY_EXPLICIT]);; + +let HAS_SIZE_COMPLEX_ROOTS_UNITY = prove + (`!n. 1 <= n ==> {z | z pow n = Cx(&1)} HAS_SIZE n`, + SIMP_TAC[HAS_SIZE; CARD_COMPLEX_ROOTS_UNITY; FINITE_COMPLEX_ROOTS_UNITY; + LE_1]);; + +let COMPLEX_NOT_ROOT_UNITY = prove + (`!n. 1 <= n ==> ?u. norm u = &1 /\ ~(u pow n = Cx(&1))`, + GEN_TAC THEN DISCH_TAC THEN + ABBREV_TAC `u = cexp (Cx pi * ii * Cx (&1 / &n))` THEN + EXISTS_TAC `u : complex` THEN CONJ_TAC THEN EXPAND_TAC "u" THEN + REWRITE_TAC [NORM_CEXP; RE_MUL_CX; RE_II; REAL_MUL_LZERO; + REAL_MUL_RZERO; REAL_EXP_0] THEN + EXPAND_TAC "u" THEN REWRITE_TAC[GSYM CEXP_N] THEN + ASM_SIMP_TAC[CX_DIV; LE_1; CX_INJ; REAL_OF_NUM_EQ; COMPLEX_FIELD + `~(n = Cx(&0)) ==> n * p * i * Cx(&1) / n = i * p`] THEN + REWRITE_TAC[CEXP_EULER; RE_CX; IM_CX; GSYM CX_COS; GSYM CX_SIN] THEN + REWRITE_TAC[COS_PI; SIN_PI] THEN CONV_TAC COMPLEX_RING);; + +(* ------------------------------------------------------------------------- *) +(* Relation between clog and Arg, and hence continuity of Arg. *) +(* ------------------------------------------------------------------------- *) + +let ARG_CLOG = prove + (`!z. &0 < Arg z ==> Arg z = Im(clog(--z)) + pi`, + GEN_TAC THEN ASM_CASES_TAC `z = Cx(&0)` THENL + [ASM_REWRITE_TAC[Arg_DEF; REAL_LT_REFL]; ALL_TAC] THEN + DISCH_TAC THEN MP_TAC(last(CONJUNCTS(SPEC `z:complex` ARG))) THEN + ASM_SIMP_TAC[CX_INJ; COMPLEX_NORM_ZERO; COMPLEX_FIELD + `~(z = Cx(&0)) ==> (w = z * a <=> a = w / z)`] THEN + DISCH_THEN(MP_TAC o AP_TERM `( * ) (cexp(--(ii * Cx pi)))`) THEN + REWRITE_TAC[GSYM CEXP_ADD] THEN DISCH_THEN(MP_TAC o AP_TERM `clog`) THEN + W(MP_TAC o PART_MATCH (lhs o rand) CLOG_CEXP o lhand o lhand o snd) THEN + REWRITE_TAC[IM_ADD; IM_MUL_II; RE_CX; IM_NEG] THEN + ASM_SIMP_TAC[REAL_LT_ADDR; ARG; REAL_ARITH + `z < &2 * pi ==> --pi + z <= pi`] THEN + DISCH_THEN SUBST1_TAC THEN REWRITE_TAC[CEXP_NEG; CEXP_EULER] THEN + REWRITE_TAC[GSYM CX_SIN; GSYM CX_COS; SIN_PI; COS_PI] THEN + REWRITE_TAC[CX_NEG; COMPLEX_MUL_RZERO; COMPLEX_ADD_RID; + SIMPLE_COMPLEX_ARITH `inv(--Cx(&1)) * z / w = --z / w`] THEN + DISCH_THEN(MP_TAC o AP_TERM `Im`) THEN + REWRITE_TAC[IM_ADD; IM_NEG; IM_MUL_II; RE_CX] THEN + MATCH_MP_TAC(REAL_RING `w = z ==> --pi + x = w ==> x = z + pi`) THEN + REWRITE_TAC[complex_div] THEN + W(MP_TAC o PART_MATCH (lhs o rand) CLOG_MUL_SIMPLE o rand o lhand o snd) THEN + ASM_SIMP_TAC[CX_INJ; REAL_INV_EQ_0; COMPLEX_NORM_ZERO; COMPLEX_NEG_EQ_0; + GSYM CX_INV; GSYM CX_LOG; REAL_LT_INV_EQ; COMPLEX_NORM_NZ; IM_CX] THEN + ASM_SIMP_TAC[REAL_ADD_RID; CLOG_WORKS; COMPLEX_NEG_EQ_0] THEN + DISCH_THEN SUBST1_TAC THEN REWRITE_TAC[IM_ADD; IM_CX; REAL_ADD_RID]);; + +let CONTINUOUS_AT_ARG = prove + (`!z. ~(real z /\ &0 <= Re z) ==> (Cx o Arg) continuous (at z)`, + let lemma = prove + (`(\z. Cx(Im(f z) + pi)) = (Cx o Im) o (\z. f z + ii * Cx pi)`, + REWRITE_TAC[FUN_EQ_THM; o_DEF; IM_ADD; IM_CX; IM_MUL_II; RE_CX]) in + REPEAT STRIP_TAC THEN REWRITE_TAC[CONTINUOUS_AT] THEN + MATCH_MP_TAC LIM_TRANSFORM_WITHIN_OPEN THEN + EXISTS_TAC `\z. Cx(Im(clog(--z)) + pi)` THEN + EXISTS_TAC `(:complex) DIFF {z | real z /\ &0 <= Re z}` THEN + ASM_REWRITE_TAC[IN_DIFF; IN_UNIV; IN_ELIM_THM; GSYM closed] THEN + ASM_SIMP_TAC[o_THM; ARG_CLOG; ARG_LT_NZ; ARG_EQ_0] THEN CONJ_TAC THENL + [REWRITE_TAC[SET_RULE `{z | P z /\ Q z} = P INTER {z | Q z}`] THEN + MATCH_MP_TAC CLOSED_INTER THEN + REWRITE_TAC[CLOSED_REAL; GSYM real_ge; CLOSED_HALFSPACE_RE_GE]; + REWRITE_TAC[GSYM CONTINUOUS_AT; lemma] THEN + MATCH_MP_TAC CONTINUOUS_AT_COMPOSE THEN + REWRITE_TAC[CONTINUOUS_AT_CX_IM] THEN + MATCH_MP_TAC CONTINUOUS_ADD THEN REWRITE_TAC[CONTINUOUS_CONST] THEN + MATCH_MP_TAC(REWRITE_RULE[o_DEF] CONTINUOUS_AT_COMPOSE) THEN + GEN_REWRITE_TAC (LAND_CONV o LAND_CONV) [GSYM ETA_AX] THEN + SIMP_TAC[CONTINUOUS_NEG; CONTINUOUS_AT_ID] THEN + MATCH_MP_TAC CONTINUOUS_AT_CLOG THEN POP_ASSUM MP_TAC THEN + REWRITE_TAC[real; IM_NEG; RE_NEG] THEN REAL_ARITH_TAC]);; + +let CONTINUOUS_WITHIN_UPPERHALF_ARG = prove + (`!z. ~(z = Cx(&0)) + ==> (Cx o Arg) continuous (at z) within {z | &0 <= Im z}`, + REPEAT STRIP_TAC THEN ASM_CASES_TAC `real z /\ &0 <= Re z` THEN + ASM_SIMP_TAC[CONTINUOUS_AT_ARG; CONTINUOUS_AT_WITHIN] THEN + FIRST_X_ASSUM(CONJUNCTS_THEN2 + (ASSUME_TAC o GEN_REWRITE_RULE I [real]) MP_TAC) THEN + SUBGOAL_THEN `~(Re z = &0)` ASSUME_TAC THENL + [DISCH_TAC THEN UNDISCH_TAC `~(z = Cx(&0))` THEN + ASM_REWRITE_TAC[COMPLEX_EQ; RE_CX; IM_CX]; + GEN_REWRITE_TAC LAND_CONV [REAL_LE_LT]] THEN + ASM_REWRITE_TAC[] THEN DISCH_TAC THEN + MP_TAC(ISPEC `rotate2d (pi / &2) z` CONTINUOUS_AT_ARG) THEN ANTS_TAC THENL + [ASM_REWRITE_TAC[ROTATE2D_PI2; real; IM_MUL_II]; ALL_TAC] THEN + REWRITE_TAC[continuous_at; continuous_within] THEN + MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `e:real` THEN + ASM_CASES_TAC `&0 < e` THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `d:real` THEN + REWRITE_TAC[o_THM; dist; GSYM CX_SUB; COMPLEX_NORM_CX] THEN + STRIP_TAC THEN ASM_REWRITE_TAC[IN_ELIM_THM] THEN + X_GEN_TAC `w:complex` THEN STRIP_TAC THEN + SUBGOAL_THEN `Arg z = &0` ASSUME_TAC THENL + [ASM_SIMP_TAC[ARG_EQ_0; real; REAL_LT_IMP_LE]; ALL_TAC] THEN + ASM_CASES_TAC `Arg w = &0` THEN + ASM_REWRITE_TAC[REAL_SUB_REFL; REAL_ABS_NUM] THEN + SUBGOAL_THEN `&0 < Arg w` ASSUME_TAC THENL + [ASM_REWRITE_TAC[ARG; REAL_LT_LE]; ALL_TAC] THEN + FIRST_X_ASSUM(MP_TAC o SPEC `rotate2d (pi / &2) w`) THEN + ASM_REWRITE_TAC[GSYM ROTATE2D_SUB; NORM_ROTATE2D] THEN + MP_TAC(ISPECL [`pi / &2`; `z:complex`] ARG_ROTATE2D) THEN ANTS_TAC THENL + [ASM_REWRITE_TAC[] THEN MP_TAC PI_POS THEN ASM_REAL_ARITH_TAC; ALL_TAC] THEN + DISCH_THEN SUBST1_TAC THEN ASM_REWRITE_TAC[REAL_ADD_RID] THEN + MATCH_MP_TAC(REAL_ARITH + `w' = p + w ==> abs(w' - p) < e ==> abs(w - &0) < e`) THEN + MATCH_MP_TAC ARG_ROTATE2D THEN CONJ_TAC THENL + [DISCH_TAC THEN UNDISCH_TAC `&0 < Arg w` THEN + ASM_REWRITE_TAC[Arg_DEF; REAL_LT_REFL]; + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM ARG_LE_PI]) THEN + MP_TAC(SPEC `w:complex` ARG) THEN REAL_ARITH_TAC]);; + +let CONTINUOUS_ON_UPPERHALF_ARG = prove + (`(Cx o Arg) continuous_on ({z | &0 <= Im z} DIFF {Cx(&0)})`, + REWRITE_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN] THEN + X_GEN_TAC `z:complex` THEN REWRITE_TAC[IN_DIFF; IN_SING; IN_ELIM_THM] THEN + STRIP_TAC THEN FIRST_ASSUM(MP_TAC o + MATCH_MP CONTINUOUS_WITHIN_UPPERHALF_ARG) THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] CONTINUOUS_WITHIN_SUBSET) THEN + SET_TAC[]);; + +let CONTINUOUS_ON_COMPOSE_ARG = prove + (`!s p:real->real^N. + (p o drop) continuous_on interval[vec 0,lift(&2 * pi)] /\ + p(&2 * pi) = p(&0) /\ ~(Cx(&0) IN s) + ==> (\z. p(Arg z)) continuous_on s`, + let ulemma = prove + (`!s. s INTER {z | &0 <= Im z} UNION s INTER {z | Im z <= &0} = s`, + SET_TAC[REAL_LE_TOTAL]) in + REPEAT STRIP_TAC THEN MATCH_MP_TAC CONTINUOUS_ON_EQ THEN + EXISTS_TAC + `\z. if &0 <= Im z then p(Arg z) + else p(&2 * pi - Arg(cnj z)):real^N` THEN + REWRITE_TAC[IN_UNIV; IN_SING; IN_DIFF] THEN CONJ_TAC THENL + [X_GEN_TAC `z:complex` THEN DISCH_TAC THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[ARG_CNJ] THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[REAL_SUB_SUB2] THEN + SUBGOAL_THEN `Arg z = &0` + (fun th -> ASM_REWRITE_TAC[REAL_SUB_RZERO; th]) THEN + ASM_REWRITE_TAC[ARG_EQ_0]; + GEN_REWRITE_TAC RAND_CONV [GSYM ulemma] THEN + MATCH_MP_TAC CONTINUOUS_ON_CASES_LOCAL THEN REWRITE_TAC[ulemma] THEN + SIMP_TAC[CLOSED_IN_CLOSED_INTER; CLOSED_HALFSPACE_IM_LE; + REWRITE_RULE[real_ge] CLOSED_HALFSPACE_IM_GE] THEN + REWRITE_TAC[IN_INTER; IN_DIFF; IN_UNIV; IN_SING; IN_ELIM_THM] THEN + SIMP_TAC[GSYM CONJ_ASSOC; REAL_LE_ANTISYM; TAUT `~(p /\ ~p)`] THEN + REWRITE_TAC[CONJ_ASSOC] THEN CONJ_TAC THENL + [GEN_REWRITE_TAC (BINOP_CONV o LAND_CONV) [GSYM o_DEF] THEN + SUBGOAL_THEN `(p:real->real^N) = (p o drop) o lift` SUBST1_TAC THENL + [REWRITE_TAC[o_DEF; LIFT_DROP; ETA_AX]; ALL_TAC] THEN + ONCE_REWRITE_TAC[GSYM o_ASSOC] THEN + CONJ_TAC THEN MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN CONJ_TAC THENL + [REWRITE_TAC[o_DEF; GSYM CONTINUOUS_ON_CX_LIFT] THEN + MP_TAC CONTINUOUS_ON_UPPERHALF_ARG THEN REWRITE_TAC[o_DEF] THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] CONTINUOUS_ON_SUBSET) THEN + ASM SET_TAC[]; + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET)) THEN + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; IN_INTER; IN_ELIM_THM] THEN + REWRITE_TAC[IN_INTERVAL_1; LIFT_DROP; o_THM; DROP_VEC] THEN + SIMP_TAC[ARG; REAL_LT_IMP_LE]; + REWRITE_TAC[o_DEF; LIFT_SUB] THEN MATCH_MP_TAC CONTINUOUS_ON_SUB THEN + REWRITE_TAC[CONTINUOUS_ON_CONST] THEN + GEN_REWRITE_TAC (LAND_CONV o TOP_DEPTH_CONV) [GSYM o_DEF] THEN + REWRITE_TAC[o_ASSOC] THEN MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN + REWRITE_TAC[CONTINUOUS_ON_CNJ; o_DEF; GSYM CONTINUOUS_ON_CX_LIFT] THEN + MP_TAC CONTINUOUS_ON_UPPERHALF_ARG THEN REWRITE_TAC[o_DEF] THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] CONTINUOUS_ON_SUBSET) THEN + SIMP_TAC[SUBSET; FORALL_IN_IMAGE; IN_INTER; IN_ELIM_THM; IN_DIFF] THEN + SIMP_TAC[IN_SING; CNJ_EQ_0; IM_CNJ; REAL_NEG_GE0] THEN ASM SET_TAC[]; + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET)) THEN + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; IN_INTER; IN_ELIM_THM] THEN + REWRITE_TAC[IN_INTERVAL_1; LIFT_DROP; o_THM; DROP_VEC] THEN + X_GEN_TAC `z:complex` THEN STRIP_TAC THEN + MP_TAC(SPEC `cnj z` ARG) THEN REAL_ARITH_TAC]; + REWRITE_TAC[GSYM ARG_EQ_0_PI; GSYM real; ARG_CNJ] THEN + REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[REAL_SUB_SUB2; REAL_SUB_RZERO] THEN + ASM_REWRITE_TAC[REAL_ARITH `&2 * x - x = x`]]]);; + +let OPEN_ARG_LTT = prove + (`!s t. &0 <= s /\ t <= &2 * pi ==> open {z | s < Arg z /\ Arg z < t}`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`Cx o Arg`; `(:complex) DIFF {z | real z /\ &0 <= Re z}`; + `{z | Re(z) > s} INTER {z | Re(z) < t}`] + CONTINUOUS_OPEN_PREIMAGE) THEN + ASM_SIMP_TAC[OPEN_INTER; OPEN_HALFSPACE_RE_GT; OPEN_HALFSPACE_RE_LT] THEN + ANTS_TAC THENL + [CONJ_TAC THENL + [MATCH_MP_TAC CONTINUOUS_AT_IMP_CONTINUOUS_ON THEN + REWRITE_TAC[IN_DIFF; IN_UNIV; IN_ELIM_THM; CONTINUOUS_AT_ARG]; + REWRITE_TAC[GSYM closed] THEN + REWRITE_TAC[SET_RULE `{z | P z /\ Q z} = P INTER {z | Q z}`] THEN + MATCH_MP_TAC CLOSED_INTER THEN + REWRITE_TAC[CLOSED_REAL; GSYM real_ge; CLOSED_HALFSPACE_RE_GE]]; + MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN REWRITE_TAC[EXTENSION] THEN + ASM_SIMP_TAC[IN_DIFF; IN_INTER; IN_UNIV; IN_ELIM_THM; o_THM; RE_CX; + GSYM ARG_EQ_0] THEN + ASM_REAL_ARITH_TAC]);; + +let OPEN_ARG_GT = prove + (`!t. open {z | t < Arg z}`, + GEN_TAC THEN DISJ_CASES_TAC(REAL_ARITH `t < &0 \/ &0 <= t`) THENL + [SUBGOAL_THEN `{z | t < Arg z} = (:complex)` + (fun th -> SIMP_TAC[th; OPEN_UNIV]) THEN + REWRITE_TAC[EXTENSION; IN_UNIV; IN_ELIM_THM] THEN + MP_TAC ARG THEN MATCH_MP_TAC MONO_FORALL THEN ASM_REAL_ARITH_TAC; + MP_TAC(ISPECL [`t:real`; `&2 * pi`] OPEN_ARG_LTT) THEN + ASM_REWRITE_TAC[ARG; REAL_LE_REFL]]);; + +let CLOSED_ARG_LE = prove + (`!t. closed {z | Arg z <= t}`, + REWRITE_TAC[closed; DIFF; IN_UNIV; IN_ELIM_THM] THEN + REWRITE_TAC[REAL_NOT_LE; OPEN_ARG_GT]);; + +(* ------------------------------------------------------------------------- *) +(* Relation between Arg and arctangent in upper halfplane. *) +(* ------------------------------------------------------------------------- *) + +let ARG_ATAN_UPPERHALF = prove + (`!z. &0 < Im z ==> Arg(z) = pi / &2 - atn(Re z / Im z)`, + GEN_TAC THEN ASM_CASES_TAC `z = Cx(&0)` THEN + ASM_REWRITE_TAC[IM_CX; REAL_LT_REFL] THEN DISCH_TAC THEN + MATCH_MP_TAC ARG_UNIQUE THEN EXISTS_TAC `norm(z:complex)` THEN + ASM_REWRITE_TAC[COMPLEX_NORM_NZ] THEN CONJ_TAC THENL + [ALL_TAC; MP_TAC(ISPEC `Re z / Im z` ATN_BOUNDS) THEN REAL_ARITH_TAC] THEN + REWRITE_TAC[CEXP_EULER; GSYM CX_SIN; GSYM CX_COS] THEN + REWRITE_TAC[SIN_SUB; COS_SUB; SIN_PI2; COS_PI2] THEN + REWRITE_TAC[REAL_MUL_LZERO; REAL_MUL_LID; SIN_ATN; COS_ATN] THEN + SUBGOAL_THEN `sqrt(&1 + (Re z / Im z) pow 2) = norm(z) / Im z` + SUBST1_TAC THENL + [MATCH_MP_TAC SQRT_UNIQUE THEN + ASM_SIMP_TAC[REAL_LE_DIV; NORM_POS_LE; REAL_LT_IMP_LE] THEN + REWRITE_TAC[REAL_POW_DIV; COMPLEX_SQNORM] THEN + UNDISCH_TAC `&0 < Im z` THEN CONV_TAC REAL_FIELD; + REWRITE_TAC[REAL_ADD_LID; REAL_SUB_RZERO; real_div] THEN + REWRITE_TAC[COMPLEX_EQ; RE_MUL_CX; IM_MUL_CX; RE_MUL_II; IM_MUL_II; + RE_ADD; IM_ADD; RE_CX; IM_CX] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM COMPLEX_NORM_NZ]) THEN + POP_ASSUM MP_TAC THEN CONV_TAC REAL_FIELD]);; + +(* ------------------------------------------------------------------------- *) +(* Real n'th roots. *) +(* ------------------------------------------------------------------------- *) + +let root = new_definition + `root(n) x = @u:real. (&0 <= x ==> &0 <= u) /\ u pow n = x`;; + +let ROOT_0 = prove + (`!n. ~(n = 0) ==> root n (&0) = &0`, + SIMP_TAC[root; REAL_LT_REFL; REAL_POW_EQ_0; REAL_LE_REFL; SELECT_REFL; + REAL_ARITH `&0 <= u /\ u = &0 <=> u = &0`]);; + +let ROOT_1 = prove + (`!n. ~(n = 0) ==> root n (&1) = &1`, + SIMP_TAC[root; REAL_POS; REAL_POW_EQ_1; CONJ_ASSOC] THEN + REWRITE_TAC[REAL_ARITH `&0 <= u /\ abs u = &1 <=> u = &1`] THEN + SIMP_TAC[TAUT `a /\ b <=> ~(a ==> ~b)`] THEN + CONV_TAC REAL_RAT_REDUCE_CONV);; + +let ROOT_2 = prove + (`!x. root 2 x = sqrt x`, + GEN_TAC THEN REWRITE_TAC[sqrt; root] THEN + AP_TERM_TAC THEN REWRITE_TAC[FUN_EQ_THM] THEN X_GEN_TAC `y:real` THEN + ASM_CASES_TAC `x:real = y pow 2` THEN + ASM_REWRITE_TAC[REAL_POW_2; REAL_LE_SQUARE] THEN REAL_ARITH_TAC);; + +let ROOT_WORKS = prove + (`!n x. ODD n \/ ~(n = 0) /\ &0 <= x + ==> (&0 <= x ==> &0 <= root n x) /\ (root n x) pow n = x`, + REPEAT GEN_TAC THEN + ASM_CASES_TAC `n = 0` THEN ASM_REWRITE_TAC[ARITH] THEN DISCH_TAC THEN + REWRITE_TAC[root] THEN CONV_TAC SELECT_CONV THEN + REPEAT_TCL DISJ_CASES_THEN ASSUME_TAC + (REAL_ARITH `x = &0 \/ &0 < x \/ &0 < --x`) + THENL + [EXISTS_TAC `&0` THEN ASM_REWRITE_TAC[REAL_POW_ZERO]; + EXISTS_TAC `exp(log x / &n)` THEN REWRITE_TAC[REAL_EXP_POS_LE] THEN + ASM_SIMP_TAC[GSYM REAL_EXP_N; REAL_DIV_LMUL; REAL_OF_NUM_EQ; EXP_LOG]; + FIRST_X_ASSUM(DISJ_CASES_THEN ASSUME_TAC) THENL + [ALL_TAC; ASM_REAL_ARITH_TAC] THEN + EXISTS_TAC `--exp(log(--x) / &n)` THEN REWRITE_TAC[REAL_POW_NEG] THEN + ASM_SIMP_TAC[GSYM NOT_ODD; REAL_ARITH `&0 < --x ==> ~(&0 <= x)`] THEN + ASM_SIMP_TAC[GSYM REAL_EXP_N; REAL_DIV_LMUL; REAL_OF_NUM_EQ; EXP_LOG; + REAL_NEG_NEG]]);; + +let REAL_POW_ROOT = prove + (`!n x. ODD n \/ ~(n = 0) /\ &0 <= x ==> (root n x) pow n = x`, + SIMP_TAC[ROOT_WORKS]);; + +let ROOT_POS_LE = prove + (`!n x. ~(n = 0) /\ &0 <= x ==> &0 <= root n x`, + SIMP_TAC[ROOT_WORKS]);; + +let ROOT_POS_LT = prove + (`!n x. ~(n = 0) /\ &0 < x ==> &0 < root n x`, + REPEAT GEN_TAC THEN SIMP_TAC[REAL_LT_LE; ROOT_POS_LE] THEN STRIP_TAC THEN + DISCH_THEN(ASSUME_TAC o SYM) THEN + MP_TAC(SPECL [`n:num`; `x:real`] REAL_POW_ROOT) THEN + ASM_REWRITE_TAC[REAL_POW_ZERO]);; + +let REAL_ROOT_POW = prove + (`!n x. ODD n \/ ~(n = 0) /\ &0 <= x ==> root n (x pow n) = x`, + REPEAT GEN_TAC THEN DISCH_TAC THEN REWRITE_TAC[root] THEN + GEN_REWRITE_TAC RAND_CONV [GSYM SELECT_REFL] THEN + AP_TERM_TAC THEN REWRITE_TAC[FUN_EQ_THM] THEN X_GEN_TAC `y:real` THEN + MP_TAC(SPECL [`n:num`; `&0`; `x:real`] REAL_POW_LE2_ODD_EQ) THEN + POP_ASSUM MP_TAC THEN REWRITE_TAC[REAL_POW_EQ_EQ; GSYM NOT_EVEN] THEN + ASM_CASES_TAC `n = 0` THEN ASM_REWRITE_TAC[ARITH] THEN + COND_CASES_TAC THEN ASM_SIMP_TAC[REAL_POW_LE; REAL_POW_ZERO] THEN + ASM_REAL_ARITH_TAC);; + +let ROOT_UNIQUE = prove + (`!n x y. y pow n = x /\ (ODD n \/ ~(n = 0) /\ &0 <= y) ==> root n x = y`, + REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN ASSUME_TAC) THEN + UNDISCH_THEN `(y:real) pow n = x` (SUBST_ALL_TAC o SYM) THEN + MATCH_MP_TAC REAL_ROOT_POW THEN ASM_REWRITE_TAC[]);; + +let REAL_ROOT_MUL = prove + (`!n x y. ~(n = 0) /\ &0 <= x /\ &0 <= y + ==> root n (x * y) = root n x * root n y`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC ROOT_UNIQUE THEN + ASM_SIMP_TAC[REAL_POW_MUL; REAL_POW_ROOT; REAL_LE_MUL; ROOT_POS_LE]);; + +let REAL_ROOT_INV = prove + (`!n x. ~(n = 0) /\ &0 <= x ==> root n (inv x) = inv(root n x)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC ROOT_UNIQUE THEN + ASM_SIMP_TAC[REAL_POW_INV; REAL_POW_ROOT; REAL_LE_INV_EQ; ROOT_POS_LE]);; + +let REAL_ROOT_DIV = prove + (`!n x y. ~(n = 0) /\ &0 <= x /\ &0 <= y + ==> root n (x / y) = root n x / root n y`, + SIMP_TAC[real_div; REAL_ROOT_MUL; REAL_ROOT_INV; REAL_LE_INV_EQ]);; + +let ROOT_MONO_LT = prove + (`!n x y. ~(n = 0) /\ &0 <= x /\ x < y ==> root n x < root n y`, + REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + MATCH_MP_TAC(REAL_ARITH + `(&0 <= x /\ &0 <= y ==> (v <= u ==> y <= x)) + ==> &0 <= x /\ x < y ==> u < v`) THEN + REPEAT STRIP_TAC THEN + SUBGOAL_THEN `(root n y) pow n <= (root n x) pow n` MP_TAC THENL + [MATCH_MP_TAC REAL_POW_LE2 THEN ASM_SIMP_TAC[ROOT_POS_LE]; + ASM_SIMP_TAC[REAL_POW_ROOT]]);; + +let ROOT_MONO_LE = prove + (`!n x y. ~(n = 0) /\ &0 <= x /\ x <= y ==> root n x <= root n y`, + MESON_TAC[ROOT_MONO_LT; REAL_LE_LT]);; + +let ROOT_MONO_LT_EQ = prove + (`!n x y. ~(n = 0) /\ &0 <= x /\ &0 <= y ==> (root n x < root n y <=> x < y)`, + MESON_TAC[ROOT_MONO_LT; REAL_NOT_LT; ROOT_MONO_LE]);; + +let ROOT_MONO_LE_EQ = prove + (`!n x y. ~(n = 0) /\ &0 <= x /\ &0 <= y + ==> (root n x <= root n y <=> x <= y)`, + MESON_TAC[ROOT_MONO_LT; REAL_NOT_LT; ROOT_MONO_LE]);; + +let ROOT_INJ = prove + (`!n x y. ~(n = 0) /\ &0 <= x /\ &0 <= y ==> (root n x = root n y <=> x = y)`, + SIMP_TAC[GSYM REAL_LE_ANTISYM; ROOT_MONO_LE_EQ]);; + +let REAL_ROOT_LE = prove + (`!n x y. ~(n = 0) /\ &0 <= x /\ &0 <= y + ==> (root n x <= y <=> x <= y pow n)`, + MESON_TAC[REAL_ROOT_POW; REAL_POW_LE; ROOT_MONO_LE_EQ]);; + +let REAL_LE_ROOT = prove + (`!n x y. ~(n = 0) /\ &0 <= x /\ &0 <= y + ==> (x <= root n y <=> x pow n <= y)`, + MESON_TAC[REAL_ROOT_POW; REAL_POW_LE; ROOT_MONO_LE_EQ]);; + +let LOG_ROOT = prove + (`!n x. ~(n = 0) /\ &0 < x ==> log(root n x) = log x / &n`, + SIMP_TAC[REAL_EQ_RDIV_EQ; REAL_OF_NUM_LT; LE_1] THEN + ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN + SIMP_TAC[GSYM LOG_POW; ROOT_POS_LT; REAL_POW_ROOT; REAL_LT_IMP_LE]);; + +let ROOT_EXP_LOG = prove + (`!n x. ~(n = 0) /\ &0 < x ==> root n x = exp(log x / &n)`, + REPEAT GEN_TAC THEN DISCH_TAC THEN + FIRST_ASSUM(MP_TAC o MATCH_MP ROOT_POS_LT) THEN + REWRITE_TAC[GSYM REAL_EXP_LOG] THEN DISCH_THEN(SUBST1_TAC o SYM) THEN + AP_TERM_TAC THEN ASM_SIMP_TAC[LOG_ROOT]);; + +(* ------------------------------------------------------------------------- *) +(* Real power function. This involves a few arbitrary choices. *) +(* *) +(* The value of x^y is unarguable when x > 0. *) +(* *) +(* We make 0^0 = 1 to agree with "pow", but otherwise 0^y = 0. *) +(* *) +(* There is a sensible real value for (-x)^(p/q) where q is odd and either *) +(* p is even [(-x)^y = x^y] or odd [(-x)^y = -x^y]. *) +(* *) +(* In all other cases, we return (-x)^y = -x^y. This is meaningless but at *) +(* least it covers half the cases above without another case split. *) +(* *) +(* As for laws of indices, we do have x^-y = 1/x^y. Of course we can't have *) +(* x^(yz) = x^y^z or x^(y+z) = x^y x^z since then (-1)^(1/2)^2 = -1. *) +(* ------------------------------------------------------------------------- *) + +parse_as_infix("rpow",(24,"left"));; + +let rpow = new_definition + `x rpow y = if &0 < x then exp(y * log x) + else if x = &0 then if y = &0 then &1 else &0 + else if ?m n. ODD(m) /\ ODD(n) /\ (abs y = &m / &n) + then --(exp(y * log(--x))) + else exp(y * log(--x))`;; + +let RPOW_POW = prove + (`!x n. x rpow &n = x pow n`, + REPEAT GEN_TAC THEN REWRITE_TAC[rpow] THEN + COND_CASES_TAC THEN ASM_SIMP_TAC[REAL_EXP_N; EXP_LOG] THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[REAL_POW_ZERO; REAL_OF_NUM_EQ] THEN + ASM_SIMP_TAC[EXP_LOG; REAL_ARITH `~(&0 < x) /\ ~(x = &0) ==> &0 < --x`] THEN + REWRITE_TAC[REAL_POW_NEG; REAL_ABS_NUM] THEN + SUBGOAL_THEN `(?p q. ODD(p) /\ ODD(q) /\ &n = &p / &q) <=> ODD n` + (fun th -> SIMP_TAC[th; GSYM NOT_ODD; REAL_NEG_NEG; COND_ID]) THEN + EQ_TAC THEN REWRITE_TAC[LEFT_IMP_EXISTS_THM] THENL + [REPEAT GEN_TAC THEN ASM_CASES_TAC `q = 0` THEN + ASM_REWRITE_TAC[ARITH_ODD] THEN + REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + ASM_SIMP_TAC[REAL_OF_NUM_EQ; REAL_FIELD + `~(q = &0) ==> (n = p / q <=> q * n = p)`] THEN + REWRITE_TAC[REAL_OF_NUM_MUL; REAL_OF_NUM_EQ] THEN + ASM_MESON_TAC[ODD_MULT]; + DISCH_TAC THEN MAP_EVERY EXISTS_TAC [`n:num`; `1`] THEN + ASM_REWRITE_TAC[REAL_DIV_1; ARITH_ODD]]);; + +let RPOW_NEG = prove + (`!x y. x rpow (--y) = inv(x rpow y)`, + REPEAT GEN_TAC THEN REWRITE_TAC[rpow] THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[REAL_MUL_LNEG; REAL_EXP_NEG] THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[REAL_NEG_EQ_0] THENL + [COND_CASES_TAC THEN ASM_REWRITE_TAC[REAL_INV_0; REAL_INV_1]; + REWRITE_TAC[REAL_ABS_NEG] THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[REAL_INV_NEG]]);; + +let RPOW_ZERO = prove + (`!y. &0 rpow y = if y = &0 then &1 else &0`, + REWRITE_TAC[rpow; REAL_LT_REFL]);; + +let RPOW_POS_LT = prove + (`!x y. &0 < x ==> &0 < x rpow y`, + SIMP_TAC[rpow; REAL_EXP_POS_LT]);; + +let RPOW_POS_LE = prove + (`!x y. &0 <= x ==> &0 <= x rpow y`, + REPEAT GEN_TAC THEN ASM_CASES_TAC `x = &0` THENL + [ASM_REWRITE_TAC[RPOW_ZERO] THEN MESON_TAC[REAL_POS]; + ASM_SIMP_TAC[RPOW_POS_LT; REAL_LE_LT]]);; + +let RPOW_LT2 = prove + (`!x y z. &0 <= x /\ x < y /\ &0 < z ==> x rpow z < y rpow z`, + REPEAT GEN_TAC THEN ASM_CASES_TAC `x = &0` THEN + ASM_SIMP_TAC[RPOW_ZERO; REAL_LT_IMP_NZ; RPOW_POS_LT] THEN + REPEAT STRIP_TAC THEN REWRITE_TAC[rpow] THEN + ASM_CASES_TAC `&0 < x /\ &0 < y` THENL + [ALL_TAC; MATCH_MP_TAC(TAUT `F ==> p`) THEN ASM_REAL_ARITH_TAC] THEN + ASM_SIMP_TAC[REAL_EXP_MONO_LT; REAL_LT_LMUL_EQ] THEN + MATCH_MP_TAC LOG_MONO_LT_IMP THEN ASM_REAL_ARITH_TAC);; + +let RPOW_LE2 = prove + (`!x y z. &0 <= x /\ x <= y /\ &0 <= z ==> x rpow z <= y rpow z`, + REPEAT GEN_TAC THEN ASM_CASES_TAC `z = &0` THEN + ASM_REWRITE_TAC[RPOW_POW; real_pow; REAL_LE_REFL] THEN + ASM_CASES_TAC `x:real = y` THEN ASM_REWRITE_TAC[REAL_LE_REFL] THEN + ASM_MESON_TAC[RPOW_LT2; REAL_LE_LT]);; + +let REAL_ABS_RPOW = prove + (`!x y. abs(x rpow y) = abs(x) rpow y`, + REPEAT GEN_TAC THEN REWRITE_TAC[rpow] THEN + ASM_CASES_TAC `x = &0` THEN ASM_REWRITE_TAC[REAL_ABS_NUM; REAL_LT_REFL] THENL + [REAL_ARITH_TAC; ALL_TAC] THEN + ASM_REWRITE_TAC[GSYM REAL_ABS_NZ; REAL_ABS_ZERO] THEN + COND_CASES_TAC THEN + ASM_SIMP_TAC[REAL_ABS_EXP; REAL_ARITH `&0 < x ==> abs x = x`] THEN + COND_CASES_TAC THEN REWRITE_TAC[REAL_ABS_NEG; REAL_ABS_EXP] THEN + AP_TERM_TAC THEN AP_TERM_TAC THEN AP_TERM_TAC THEN ASM_REAL_ARITH_TAC);; + +let RPOW_ONE = prove + (`!z. &1 rpow z = &1`, + REWRITE_TAC[rpow; REAL_LT_01; LOG_1; REAL_MUL_RZERO; REAL_EXP_0]);; + +let RPOW_RPOW = prove + (`!x y z. &0 <= x ==> x rpow y rpow z = x rpow (y * z)`, + REPEAT GEN_TAC THEN REWRITE_TAC[REAL_LE_LT] THEN + ASM_CASES_TAC `x = &0` THEN ASM_REWRITE_TAC[] THENL + [ASM_REWRITE_TAC[RPOW_ZERO; REAL_ENTIRE] THEN + ASM_CASES_TAC `y = &0` THEN ASM_REWRITE_TAC[RPOW_ZERO; RPOW_ONE]; + SIMP_TAC[rpow; REAL_EXP_POS_LT; LOG_EXP] THEN + REWRITE_TAC[REAL_MUL_AC]]);; + +let RPOW_LNEG = prove + (`!x y. --x rpow y = + if ?m n. ODD m /\ ODD n /\ abs y = &m / &n + then --(x rpow y) else x rpow y`, + REPEAT GEN_TAC THEN REWRITE_TAC[rpow] THEN + ASM_CASES_TAC `x = &0` THEN + ASM_REWRITE_TAC[REAL_NEG_0; REAL_ABS_NUM; REAL_LT_REFL] THENL + [ASM_CASES_TAC `y = &0` THEN ASM_REWRITE_TAC[REAL_NEG_0; COND_ID] THEN + REWRITE_TAC[REAL_ARITH `abs(&0) = m / n <=> m * inv n = &0`] THEN + SIMP_TAC[REAL_ENTIRE; REAL_INV_EQ_0; REAL_OF_NUM_EQ] THEN MESON_TAC[ODD]; + ASM_SIMP_TAC[REAL_ARITH `~(x = &0) ==> (&0 < --x <=> ~(&0 < x))`] THEN + ASM_REWRITE_TAC[REAL_NEG_EQ_0] THEN + ASM_CASES_TAC `&0 < x` THEN ASM_REWRITE_TAC[REAL_NEG_NEG; COND_ID]]);; + +let RPOW_EQ_0 = prove + (`!x y. x rpow y = &0 <=> x = &0 /\ ~(y = &0)`, + REPEAT GEN_TAC THEN REWRITE_TAC[rpow] THEN + ASM_CASES_TAC `x = &0` THEN ASM_REWRITE_TAC[REAL_LT_REFL] THEN + REPEAT(COND_CASES_TAC THEN ASM_REWRITE_TAC[REAL_NEG_EQ_0; REAL_EXP_NZ]) THEN + REAL_ARITH_TAC);; + +let RPOW_MUL = prove + (`!x y z. (x * y) rpow z = x rpow z * y rpow z`, + SUBGOAL_THEN + `!x y z. &0 <= x /\ &0 <= y ==> (x * y) rpow z = x rpow z * y rpow z` + ASSUME_TAC THENL + [REPEAT GEN_TAC THEN REWRITE_TAC[REAL_LE_LT] THEN + ASM_CASES_TAC `z = &0` THEN + ASM_REWRITE_TAC[RPOW_POW; real_pow; REAL_MUL_LID] THEN + ASM_CASES_TAC `x = &0` THEN ASM_REWRITE_TAC[REAL_MUL_LZERO; RPOW_ZERO] THEN + ASM_CASES_TAC `y = &0` THEN ASM_REWRITE_TAC[REAL_MUL_RZERO; RPOW_ZERO] THEN + SIMP_TAC[rpow; REAL_LT_MUL; LOG_MUL; REAL_ADD_LDISTRIB; REAL_EXP_ADD]; + REPEAT GEN_TAC THEN + REPEAT_TCL DISJ_CASES_THEN (ANTE_RES_THEN (MP_TAC o SPEC `z:real`)) + (REAL_ARITH `&0 <= x /\ &0 <= y \/ &0 <= x /\ &0 <= --y \/ + &0 <= --x /\ &0 <= y \/ &0 <= --x /\ &0 <= --y`) THEN + REWRITE_TAC[RPOW_LNEG; REAL_MUL_RNEG; REAL_MUL_LNEG] THEN + COND_CASES_TAC THEN + ASM_REWRITE_TAC[REAL_MUL_RNEG; REAL_MUL_LNEG; REAL_EQ_NEG2]]);; + +let RPOW_INV = prove + (`!x y. inv(x) rpow y = inv(x rpow y)`, + REPEAT GEN_TAC THEN REWRITE_TAC[rpow; REAL_LT_INV_EQ] THEN + SIMP_TAC[LOG_INV; REAL_MUL_RNEG; REAL_EXP_NEG] THEN + COND_CASES_TAC THEN REWRITE_TAC[] THEN + REWRITE_TAC[REAL_INV_EQ_0] THEN + REPEAT(COND_CASES_TAC THEN ASM_REWRITE_TAC[REAL_INV_1; REAL_INV_0]) THEN + ASM_SIMP_TAC[GSYM REAL_INV_NEG; LOG_INV; + REAL_ARITH `~(&0 < x) /\ ~(x = &0) ==> &0 < --x`] THEN + REWRITE_TAC[REAL_MUL_RNEG; REAL_EXP_NEG; REAL_INV_NEG]);; + +let REAL_INV_RPOW = prove + (`!x y. inv(x rpow y) = inv(x) rpow y`, + REWRITE_TAC[RPOW_INV]);; + +let RPOW_ADD = prove + (`!x y z. &0 < x ==> x rpow (y + z) = x rpow y * x rpow z`, + REPEAT STRIP_TAC THEN + ASM_REWRITE_TAC[rpow; REAL_ADD_RDISTRIB; REAL_EXP_ADD]);; + +let RPOW_ADD_ALT = prove + (`!x y z. &0 <= x /\ (x = &0 /\ y + z = &0 ==> y = &0 \/ z = &0) + ==> x rpow (y + z) = x rpow y * x rpow z`, + REPEAT GEN_TAC THEN + ASM_CASES_TAC `x = &0` THEN ASM_SIMP_TAC[REAL_LE_LT; RPOW_ADD] THEN + REWRITE_TAC[RPOW_ZERO] THEN + ASM_CASES_TAC `y = &0` THEN + ASM_REWRITE_TAC[REAL_MUL_LID; REAL_ADD_LID] THEN + ASM_CASES_TAC `y + z = &0` THEN ASM_REWRITE_TAC[] THEN + ASM_REAL_ARITH_TAC);; + +let RPOW_SQRT = prove + (`!x. &0 <= x ==> x rpow (&1 / &2) = sqrt x`, + REPEAT STRIP_TAC THEN + MATCH_MP_TAC(REAL_RING + `x pow 2 = y pow 2 /\ (x + y = &0 ==> x = &0 /\ y = &0) + ==> x = y`) THEN + CONJ_TAC THENL + [ASM_SIMP_TAC[SQRT_POW_2] THEN + ASM_SIMP_TAC[GSYM RPOW_POW; RPOW_RPOW] THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN + REWRITE_TAC[RPOW_POW; REAL_POW_1]; + MATCH_MP_TAC(REAL_ARITH + `&0 <= x /\ &0 <= y ==> x + y = &0 ==> x = &0 /\ y = &0`) THEN + ASM_SIMP_TAC[SQRT_POS_LE; RPOW_POS_LE]]);; + +let RPOW_MONO = prove + (`!a b x. &1 <= x /\ a <= b ==> x rpow a <= x rpow b`, + SIMP_TAC[rpow; REAL_ARITH `&1 <= x ==> &0 < x`] THEN + SIMP_TAC[REAL_EXP_MONO_LE; LOG_POS; REAL_LE_RMUL]);; + +let RPOW_MONO_INV = prove + (`!a b x. &0 < x /\ x <= &1 /\ b <= a ==> x rpow a <= x rpow b`, + REPEAT STRIP_TAC THEN + GEN_REWRITE_TAC BINOP_CONV [GSYM REAL_INV_INV] THEN + MATCH_MP_TAC REAL_LE_INV2 THEN + ASM_SIMP_TAC[REAL_LT_INV_EQ; RPOW_POS_LT; GSYM RPOW_INV] THEN + MATCH_MP_TAC RPOW_MONO THEN + ASM_SIMP_TAC[REAL_INV_1_LE]);; + +let RPOW_1_LE = prove + (`!a x. &0 <= x /\ x <= &1 /\ &0 <= a ==> x rpow a <= &1`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `&1 rpow a` THEN CONJ_TAC THENL + [MATCH_MP_TAC RPOW_LE2 THEN ASM_REAL_ARITH_TAC; + REWRITE_TAC[RPOW_ONE; REAL_LE_REFL]]);; + +let REAL_ROOT_RPOW = prove + (`!n x. ~(n = 0) /\ (&0 <= x \/ ODD n) ==> root n x = x rpow (inv(&n))`, + REPEAT GEN_TAC THEN ASM_CASES_TAC `x = &0` THEN + ASM_SIMP_TAC[ROOT_0; RPOW_ZERO; REAL_INV_EQ_0; REAL_OF_NUM_EQ] THEN + ASM_CASES_TAC `&0 <= x` THEN ASM_REWRITE_TAC[] THEN STRIP_TAC THENL + [ASM_SIMP_TAC[ROOT_EXP_LOG; rpow; REAL_LT_LE] THEN AP_TERM_TAC THEN + REAL_ARITH_TAC; + ASM_REWRITE_TAC[rpow] THEN COND_CASES_TAC THENL + [ASM_REAL_ARITH_TAC; ALL_TAC] THEN + REWRITE_TAC[REAL_ABS_INV; REAL_ABS_NUM] THEN + REWRITE_TAC[REAL_ARITH `inv x = &1 / x`] THEN + COND_CASES_TAC THENL [ALL_TAC; ASM_MESON_TAC[ARITH]] THEN + MATCH_MP_TAC ROOT_UNIQUE THEN + ASM_REWRITE_TAC[REAL_POW_NEG; GSYM REAL_EXP_N; GSYM NOT_ODD] THEN + ASM_SIMP_TAC[REAL_OF_NUM_EQ; REAL_FIELD + `~(n = &0) ==> n * &1 / n * x = x`] THEN + ONCE_REWRITE_TAC[REAL_ARITH `--x:real = y <=> x = --y`] THEN + MATCH_MP_TAC EXP_LOG THEN ASM_REAL_ARITH_TAC]);; + +(* ------------------------------------------------------------------------- *) +(* Formulation of loop homotopy in terms of maps out of S^1 *) +(* ------------------------------------------------------------------------- *) + +let HOMOTOPIC_CIRCLEMAPS_IMP_HOMOTOPIC_LOOPS = prove + (`!f:complex->real^N g s. + homotopic_with (\h. T) (sphere(vec 0,&1),s) f g + ==> homotopic_loops s (f o cexp o (\t. Cx(&2 * pi * drop t) * ii)) + (g o cexp o (\t. Cx(&2 * pi * drop t) * ii))`, + REWRITE_TAC[homotopic_loops; sphere; DIST_0] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC HOMOTOPIC_WITH_COMPOSE_CONTINUOUS_RIGHT THEN + EXISTS_TAC `{z:complex | norm z = &1}` THEN + REWRITE_TAC[pathstart; pathfinish; o_THM; DROP_VEC] THEN + ONCE_REWRITE_TAC[REAL_ARITH `&2 * pi * n = &2 * n * pi`] THEN + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; o_THM; IN_ELIM_THM] THEN + ASM_SIMP_TAC[CEXP_INTEGER_2PI; INTEGER_CLOSED] THEN + REWRITE_TAC[ONCE_REWRITE_RULE[COMPLEX_MUL_SYM] NORM_CEXP_II] THEN + MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN REWRITE_TAC[CONTINUOUS_ON_CEXP] THEN + REWRITE_TAC[CX_MUL] THEN + REPEAT(MATCH_MP_TAC CONTINUOUS_ON_COMPLEX_MUL THEN + REWRITE_TAC[CONTINUOUS_ON_CONST]) THEN + SIMP_TAC[CONTINUOUS_ON_CX_DROP; CONTINUOUS_ON_ID]);; + +let HOMOTOPIC_LOOPS_IMP_HOMOTOPIC_CIRCLEMAPS = prove + (`!p q s:real^N->bool. + homotopic_loops s p q + ==> homotopic_with (\h. T) (sphere(vec 0,&1),s) + (p o (\z. lift(Arg z / (&2 * pi)))) + (q o (\z. lift(Arg z / (&2 * pi))))`, + let ulemma = prove + (`!s. s INTER (UNIV PCROSS {z | &0 <= Im z}) UNION + s INTER (UNIV PCROSS {z | Im z <= &0}) = s`, + REWRITE_TAC[EXTENSION; FORALL_PASTECART; IN_INTER; IN_UNION; + PASTECART_IN_PCROSS] THEN + SET_TAC[REAL_LE_TOTAL]) in + REPEAT GEN_TAC THEN REWRITE_TAC[homotopic_loops; sphere; DIST_0] THEN + GEN_REWRITE_TAC LAND_CONV [homotopic_with] THEN + SIMP_TAC[pathstart; pathfinish; LEFT_IMP_EXISTS_THM; HOMOTOPIC_WITH] THEN + X_GEN_TAC `h:real^(1,1)finite_sum->real^N` THEN STRIP_TAC THEN + EXISTS_TAC `\w. (h:real^(1,1)finite_sum->real^N) + (pastecart (fstcart w) + (lift(Arg(sndcart w) / (&2 * pi))))` THEN + ASM_REWRITE_TAC[FSTCART_PASTECART; SNDCART_PASTECART; o_THM] THEN + CONJ_TAC THENL + [MATCH_MP_TAC CONTINUOUS_ON_EQ THEN + EXISTS_TAC + `(\z. if &0 <= Im(sndcart z) + then h (pastecart (fstcart z) (lift(Arg(sndcart z) / (&2 * pi)))) + else h (pastecart (fstcart z) + (vec 1 - lift(Arg(cnj(sndcart z)) / (&2 * pi))))) + :real^(1,2)finite_sum->real^N` THEN + REWRITE_TAC[FORALL_IN_PCROSS; FSTCART_PASTECART; SNDCART_PASTECART] THEN + REWRITE_TAC[IN_ELIM_THM] THEN CONJ_TAC THENL + [MAP_EVERY X_GEN_TAC [`t:real^1`; `z:complex`] THEN STRIP_TAC THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[ARG_CNJ] THEN + COND_CASES_TAC THENL [ASM_MESON_TAC[real; REAL_LE_REFL]; ALL_TAC] THEN + SIMP_TAC[PI_POS; LIFT_SUB; LIFT_NUM; REAL_FIELD + `&0 < pi ==> (&2 * pi - z) / (&2 * pi) = &1 - z / (&2 * pi)`] THEN + REWRITE_TAC[VECTOR_ARITH `a - (a - b):real^N = b`]; + GEN_REWRITE_TAC RAND_CONV [GSYM ulemma] THEN + MATCH_MP_TAC CONTINUOUS_ON_CASES_LOCAL THEN REWRITE_TAC[ulemma] THEN + SIMP_TAC[CLOSED_IN_CLOSED_INTER; CLOSED_HALFSPACE_IM_LE; CLOSED_UNIV; + CLOSED_PCROSS; REWRITE_RULE[real_ge] CLOSED_HALFSPACE_IM_GE] THEN + REWRITE_TAC[FORALL_PASTECART; PASTECART_IN_PCROSS; IN_INTER; IN_DIFF; + FSTCART_PASTECART; SNDCART_PASTECART; IN_UNIV; IN_SING; IN_ELIM_THM; + GSYM CONJ_ASSOC; REAL_LE_ANTISYM; TAUT `~(p /\ ~p)`] THEN + REWRITE_TAC[CONJ_ASSOC] THEN CONJ_TAC THENL + [ALL_TAC; + REWRITE_TAC[GSYM ARG_EQ_0_PI; GSYM real; ARG_CNJ] THEN + REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + SIMP_TAC[REAL_ARITH `&2 * x - x = x`; COND_ID; GSYM LIFT_NUM; PI_POS; + GSYM LIFT_SUB; REAL_FIELD + `&0 < pi ==> &1 - pi / (&2 * pi) = pi / (&2 * pi)`] THEN + COND_CASES_TAC THEN + SIMP_TAC[REAL_SUB_RZERO; REAL_DIV_REFL; REAL_ENTIRE; REAL_OF_NUM_EQ; + ARITH_EQ; PI_NZ] THEN + SIMP_TAC[real_div; REAL_MUL_LZERO; REAL_SUB_REFL; REAL_SUB_RZERO] THEN + ASM_SIMP_TAC[LIFT_NUM]] THEN + GEN_REWRITE_TAC (BINOP_CONV o LAND_CONV) [GSYM o_DEF] THEN + CONJ_TAC THEN MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN CONJ_TAC THENL + [MATCH_MP_TAC CONTINUOUS_ON_PASTECART THEN + SIMP_TAC[LINEAR_CONTINUOUS_ON; LINEAR_FSTCART] THEN + REWRITE_TAC[real_div; REWRITE_RULE[REAL_MUL_SYM] LIFT_CMUL] THEN + MATCH_MP_TAC CONTINUOUS_ON_VMUL THEN + GEN_REWRITE_TAC (LAND_CONV o RAND_CONV) [GSYM o_DEF] THEN + REWRITE_TAC[o_ASSOC] THEN MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN + SIMP_TAC[LINEAR_CONTINUOUS_ON; LINEAR_SNDCART] THEN + REWRITE_TAC[o_DEF; GSYM CONTINUOUS_ON_CX_LIFT] THEN + MP_TAC CONTINUOUS_ON_UPPERHALF_ARG THEN REWRITE_TAC[o_DEF] THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] CONTINUOUS_ON_SUBSET) THEN + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; FORALL_PASTECART; IN_INTER; + PASTECART_IN_PCROSS; IN_ELIM_THM; SNDCART_PASTECART] THEN + MAP_EVERY X_GEN_TAC [`t:real^1`; `z:complex`] THEN + SIMP_TAC[IN_DIFF; IN_ELIM_THM; IN_SING] THEN + ASM_CASES_TAC `z = Cx(&0)` THEN ASM_REWRITE_TAC[COMPLEX_NORM_0] THEN + REWRITE_TAC[REAL_OF_NUM_EQ; ARITH_EQ]; + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET)) THEN + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; FORALL_PASTECART; IN_INTER; + PASTECART_IN_PCROSS; IN_ELIM_THM; SNDCART_PASTECART; + FSTCART_PASTECART] THEN + SIMP_TAC[IN_INTERVAL_1; LIFT_DROP; DROP_VEC] THEN + SIMP_TAC[REAL_LE_LDIV_EQ; REAL_LE_RDIV_EQ; PI_POS; REAL_MUL_LZERO; + REAL_MUL_LID; REAL_ARITH `&0 < &2 * x <=> &0 < x`] THEN + SIMP_TAC[ARG; REAL_LT_IMP_LE]; + MATCH_MP_TAC CONTINUOUS_ON_PASTECART THEN + SIMP_TAC[LINEAR_CONTINUOUS_ON; LINEAR_FSTCART] THEN + MATCH_MP_TAC CONTINUOUS_ON_SUB THEN + REWRITE_TAC[CONTINUOUS_ON_CONST] THEN + REWRITE_TAC[real_div; REWRITE_RULE[REAL_MUL_SYM] LIFT_CMUL] THEN + MATCH_MP_TAC CONTINUOUS_ON_VMUL THEN + GEN_REWRITE_TAC (LAND_CONV o RAND_CONV) [GSYM o_DEF] THEN + REWRITE_TAC[o_ASSOC] THEN MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN + GEN_REWRITE_TAC (LAND_CONV o LAND_CONV) [GSYM o_DEF] THEN + SIMP_TAC[LINEAR_CONTINUOUS_ON; LINEAR_SNDCART; CONTINUOUS_ON_COMPOSE; + CONTINUOUS_ON_CNJ] THEN + REWRITE_TAC[o_DEF; GSYM CONTINUOUS_ON_CX_LIFT] THEN + MP_TAC CONTINUOUS_ON_UPPERHALF_ARG THEN REWRITE_TAC[o_DEF] THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] CONTINUOUS_ON_SUBSET) THEN + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; FORALL_PASTECART; IN_INTER; + PASTECART_IN_PCROSS; IN_ELIM_THM; SNDCART_PASTECART] THEN + MAP_EVERY X_GEN_TAC [`t:real^1`; `z:complex`] THEN + SIMP_TAC[IN_DIFF; IN_ELIM_THM; IN_SING] THEN + SIMP_TAC[IM_CNJ; REAL_NEG_GE0; CNJ_EQ_0] THEN + ASM_CASES_TAC `z = Cx(&0)` THEN ASM_REWRITE_TAC[COMPLEX_NORM_0] THEN + REWRITE_TAC[REAL_OF_NUM_EQ; ARITH_EQ]; + FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + CONTINUOUS_ON_SUBSET)) THEN + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; FORALL_PASTECART; IN_INTER; + PASTECART_IN_PCROSS; IN_ELIM_THM; SNDCART_PASTECART; + FSTCART_PASTECART] THEN + SIMP_TAC[IN_INTERVAL_1; DROP_SUB; DROP_VEC; LIFT_DROP] THEN + REWRITE_TAC[REAL_ARITH `&0 <= &1 - x /\ &1 - x <= &1 <=> + &0 <= x /\ x <= &1`] THEN + SIMP_TAC[REAL_LE_LDIV_EQ; REAL_LE_RDIV_EQ; PI_POS; REAL_MUL_LZERO; + REAL_MUL_LID; REAL_ARITH `&0 < &2 * x <=> &0 < x`] THEN + SIMP_TAC[ARG; REAL_LT_IMP_LE]]]; + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; FORALL_IN_PCROSS; IN_ELIM_THM] THEN + REWRITE_TAC[FSTCART_PASTECART; SNDCART_PASTECART] THEN + REPEAT STRIP_TAC THEN FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE + `IMAGE h s SUBSET t ==> y IN s ==> h y IN t`)) THEN + ASM_REWRITE_TAC[PASTECART_IN_PCROSS; IN_INTERVAL_1; LIFT_DROP] THEN + SIMP_TAC[DROP_VEC; REAL_LE_LDIV_EQ; REAL_LE_RDIV_EQ; PI_POS; + REAL_ARITH `&0 < &2 * x <=> &0 < x`] THEN + SIMP_TAC[REAL_MUL_LZERO; REAL_MUL_LID; ARG; REAL_LT_IMP_LE]]);; + +let SIMPLY_CONNECTED_EQ_HOMOTOPIC_CIRCLEMAPS, + SIMPLY_CONNECTED_EQ_CONTRACTIBLE_CIRCLEMAP = + (CONJ_PAIR o prove) + (`(!s:real^N->bool. + simply_connected s <=> + !f g:complex->real^N. + f continuous_on sphere(vec 0,&1) /\ + IMAGE f (sphere(vec 0,&1)) SUBSET s /\ + g continuous_on sphere(vec 0,&1) /\ + IMAGE g (sphere(vec 0,&1)) SUBSET s + ==> homotopic_with (\h. T) (sphere(vec 0,&1),s) f g) /\ + (!s:real^N->bool. + simply_connected s <=> + path_connected s /\ + !f:real^2->real^N. + f continuous_on sphere(vec 0,&1) /\ + IMAGE f (sphere(vec 0,&1)) SUBSET s + ==> ?a. homotopic_with (\h. T) (sphere(vec 0,&1),s) f (\x. a))`, + REWRITE_TAC[AND_FORALL_THM] THEN GEN_TAC THEN MATCH_MP_TAC(TAUT + `(p ==> q) /\ (q ==> r) /\ (r ==> p) ==> (p <=> q) /\ (p <=> r)`) THEN + REPEAT CONJ_TAC THENL + [REWRITE_TAC[simply_connected] THEN DISCH_TAC THEN + MAP_EVERY X_GEN_TAC [`f:complex->real^N`; `g:complex->real^N`] THEN + STRIP_TAC THEN FIRST_X_ASSUM(MP_TAC o SPECL + [`(f:complex->real^N) o cexp o (\t. Cx(&2 * pi * drop t) * ii)`; + `(g:complex->real^N) o cexp o (\t. Cx(&2 * pi * drop t) * ii)`]) THEN + ONCE_REWRITE_TAC[TAUT `p1 /\ q1 /\ r1 /\ p2 /\ q2 /\ r2 <=> + (p1 /\ r1 /\ q1) /\ (p2 /\ r2 /\ q2)`] THEN + REWRITE_TAC[GSYM HOMOTOPIC_LOOPS_REFL] THEN + ASM_SIMP_TAC[HOMOTOPIC_CIRCLEMAPS_IMP_HOMOTOPIC_LOOPS; + HOMOTOPIC_WITH_REFL] THEN + DISCH_THEN(MP_TAC o MATCH_MP HOMOTOPIC_LOOPS_IMP_HOMOTOPIC_CIRCLEMAPS) THEN + MATCH_MP_TAC(ONCE_REWRITE_RULE[IMP_CONJ_ALT] HOMOTOPIC_WITH_EQ) THEN + REWRITE_TAC[IN_SPHERE_0; LIFT_DROP; o_DEF] THEN X_GEN_TAC `z:complex` THEN + REPEAT STRIP_TAC THEN AP_TERM_TAC THEN MP_TAC(SPEC `z:complex` ARG) THEN + ASM_REWRITE_TAC[COMPLEX_MUL_LID] THEN + DISCH_THEN(STRIP_ASSUME_TAC o GSYM) THEN SIMP_TAC[PI_POS; + REAL_FIELD `&0 < pi ==> &2 * pi * x / (&2 * pi) = x`] THEN + ASM_MESON_TAC[COMPLEX_MUL_SYM]; + DISCH_TAC THEN CONJ_TAC THENL + [REWRITE_TAC[PATH_CONNECTED_EQ_HOMOTOPIC_POINTS] THEN + MAP_EVERY X_GEN_TAC [`a:real^N`; `b:real^N`] THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPECL + [`(\x. a):complex->real^N`; `(\x. b):complex->real^N`]) THEN + REWRITE_TAC[CONTINUOUS_ON_CONST] THEN + ANTS_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN DISCH_THEN + (MP_TAC o MATCH_MP HOMOTOPIC_CIRCLEMAPS_IMP_HOMOTOPIC_LOOPS) THEN + REWRITE_TAC[o_DEF; LINEPATH_REFL]; + X_GEN_TAC `f:complex->real^N` THEN STRIP_TAC THEN + EXISTS_TAC `f(Cx(&1)):real^N` THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_REWRITE_TAC[CONTINUOUS_ON_CONST] THEN + RULE_ASSUM_TAC(REWRITE_RULE[SUBSET; FORALL_IN_IMAGE; IN_SPHERE_0]) THEN + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; IN_SPHERE_0] THEN + REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + REWRITE_TAC[COMPLEX_NORM_CX] THEN REAL_ARITH_TAC]; + STRIP_TAC THEN + ASM_REWRITE_TAC[SIMPLY_CONNECTED_EQ_CONTRACTIBLE_LOOP_SOME] THEN + X_GEN_TAC `p:real^1->real^N` THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC + `(p:real^1->real^N) o (\z. lift(Arg z / (&2 * pi)))`) THEN + ANTS_TAC THENL + [MP_TAC(ISPECL [`s:real^N->bool`; `p:real^1->real^N`] + HOMOTOPIC_LOOPS_REFL) THEN + ASM_REWRITE_TAC[] THEN DISCH_THEN(MP_TAC o MATCH_MP + HOMOTOPIC_LOOPS_IMP_HOMOTOPIC_CIRCLEMAPS) THEN + SIMP_TAC[HOMOTOPIC_WITH_REFL]; + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `a:real^N` THEN + STRIP_TAC THEN FIRST_ASSUM + (MP_TAC o MATCH_MP HOMOTOPIC_CIRCLEMAPS_IMP_HOMOTOPIC_LOOPS) THEN + FIRST_ASSUM(MP_TAC o MATCH_MP HOMOTOPIC_WITH_IMP_SUBSET) THEN + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; IN_SPHERE_0; o_DEF] THEN + DISCH_THEN(MP_TAC o SPEC `Cx(&1)` o CONJUNCT2) THEN + REWRITE_TAC[COMPLEX_NORM_CX; REAL_ABS_NUM] THEN + STRIP_TAC THEN ASM_REWRITE_TAC[LINEPATH_REFL] THEN + MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] HOMOTOPIC_LOOPS_TRANS) THEN + MATCH_MP_TAC HOMOTOPIC_LOOPS_EQ THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[IN_INTERVAL_1; FORALL_LIFT; LIFT_DROP; DROP_VEC] THEN + X_GEN_TAC `t:real` THEN STRIP_TAC THEN ASM_CASES_TAC `t = &1` THENL + [ASM_REWRITE_TAC[REAL_ARITH `&2 * pi * &1 = &2 * &1 * pi`] THEN + SIMP_TAC[CEXP_INTEGER_2PI; INTEGER_CLOSED; ARG_NUM] THEN + REWRITE_TAC[real_div; REAL_MUL_LZERO; LIFT_NUM] THEN + ASM_MESON_TAC[pathstart; pathfinish]; + AP_TERM_TAC THEN AP_TERM_TAC THEN SIMP_TAC[PI_POS; REAL_FIELD + `&0 < pi ==> (t = x / (&2 * pi) <=> x = &2 * pi * t)`] THEN + MATCH_MP_TAC EQ_TRANS THEN EXISTS_TAC `Im(Cx (&2 * pi * t) * ii)` THEN + CONJ_TAC THENL [MATCH_MP_TAC ARG_CEXP; ALL_TAC] THEN + SIMP_TAC[IM_MUL_II; RE_CX; REAL_ARITH + `a < &2 * pi <=> a < &2 * pi * &1`] THEN + ASM_SIMP_TAC[REAL_LE_MUL; REAL_LT_LMUL_EQ; REAL_OF_NUM_LT; ARITH; + PI_POS; REAL_LT_IMP_LE; REAL_POS; REAL_LE_MUL] THEN + ASM_REWRITE_TAC[REAL_LT_LE]]]]);; + +let HOMOTOPY_EQUIVALENT_SIMPLE_CONNECTEDNESS = prove + (`!s:real^M->bool t:real^N->bool. + s homotopy_equivalent t + ==> (simply_connected s <=> simply_connected t)`, + REWRITE_TAC[SIMPLY_CONNECTED_EQ_HOMOTOPIC_CIRCLEMAPS] THEN + REWRITE_TAC[HOMOTOPY_EQUIVALENT_HOMOTOPIC_TRIVIALITY]);; + +(* ------------------------------------------------------------------------- *) +(* Homeomorphism of simple closed curves to circles. *) +(* ------------------------------------------------------------------------- *) + +let HOMEOMORPHIC_SIMPLE_PATH_IMAGE_CIRCLE = prove + (`!g:real^1->real^N a:real^2 r. + simple_path g /\ pathfinish g = pathstart g /\ &0 < r + ==> (path_image g) homeomorphic sphere(a,r)`, + REPEAT STRIP_TAC THEN + TRANS_TAC HOMEOMORPHIC_TRANS `sphere(vec 0:real^2,&1)` THEN + ASM_SIMP_TAC[HOMEOMORPHIC_SPHERES; REAL_LT_01] THEN MP_TAC(ISPECL + [`g:real^1->real^N`; `g:real^1->real^N`; `path_image(g:real^1->real^N)`] + HOMOTOPIC_LOOPS_IMP_HOMOTOPIC_CIRCLEMAPS) THEN + REWRITE_TAC[HOMOTOPIC_LOOPS_REFL; HOMOTOPIC_WITH_REFL; SUBSET_REFL] THEN + ASM_SIMP_TAC[SIMPLE_PATH_IMP_PATH] THEN STRIP_TAC THEN + ONCE_REWRITE_TAC[HOMEOMORPHIC_SYM] THEN REWRITE_TAC[homeomorphic] THEN + EXISTS_TAC `(g:real^1->real^N) o (\z. lift(Arg z / (&2 * pi)))` THEN + MATCH_MP_TAC HOMEOMORPHISM_COMPACT THEN + ASM_REWRITE_TAC[COMPACT_SPHERE] THEN CONJ_TAC THENL + [MATCH_MP_TAC SUBSET_ANTISYM THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[SUBSET; path_image; FORALL_IN_IMAGE; IN_INTERVAL_1] THEN + X_GEN_TAC `t:real^1` THEN REWRITE_TAC[DROP_VEC] THEN STRIP_TAC THEN + REWRITE_TAC[IN_IMAGE; o_THM; IN_SPHERE_0] THEN + ASM_CASES_TAC `t:real^1 = vec 1` THENL + [EXISTS_TAC `Cx(&1)` THEN + ASM_REWRITE_TAC[ARG_NUM; COMPLEX_NORM_CX; real_div; REAL_MUL_LZERO] THEN + REWRITE_TAC[LIFT_NUM; REAL_ABS_NUM] THEN + ASM_MESON_TAC[pathstart; pathfinish]; + EXISTS_TAC `cexp(ii * Cx(&2 * pi * drop t))` THEN + REWRITE_TAC[NORM_CEXP_II] THEN AP_TERM_TAC THEN + W(MP_TAC o PART_MATCH (lhand o rand) ARG_CEXP o + lhand o rand o rand o snd) THEN + REWRITE_TAC[IM_MUL_II; RE_CX] THEN ANTS_TAC THENL + [ASM_SIMP_TAC[REAL_LE_MUL; PI_POS_LE; REAL_POS] THEN + SIMP_TAC[REAL_ARITH `&2 * pi * x < &2 * pi <=> pi * x < pi * &1`; + REAL_LT_LMUL_EQ; PI_POS] THEN + ASM_REWRITE_TAC[REAL_LT_LE] THEN + ASM_REWRITE_TAC[GSYM LIFT_EQ; LIFT_DROP; LIFT_NUM]; + DISCH_THEN SUBST1_TAC THEN REWRITE_TAC[GSYM DROP_EQ; LIFT_DROP] THEN + MP_TAC PI_POS THEN CONV_TAC REAL_FIELD]]; + MAP_EVERY X_GEN_TAC [`w:complex`; `z:complex`] THEN + REWRITE_TAC[IN_SPHERE_0] THEN STRIP_TAC THEN + MAP_EVERY (SUBST1_TAC o last o CONJUNCTS o C SPEC ARG) + [`w:complex`; `z:complex`] THEN + FIRST_X_ASSUM(MP_TAC o SYM o SYM) THEN + ASM_REWRITE_TAC[o_DEF; COMPLEX_MUL_LID] THEN DISCH_TAC THEN + AP_TERM_TAC THEN AP_TERM_TAC THEN AP_TERM_TAC THEN + MATCH_MP_TAC(REAL_FIELD + `&0 < pi /\ x / (&2 * pi) = y / (&2 * pi) ==> x = y`) THEN + REWRITE_TAC[PI_POS; GSYM LIFT_EQ] THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [simple_path]) THEN + DISCH_THEN(MP_TAC o SPECL + [`lift(Arg w / (&2 * pi))`; `lift(Arg z / (&2 * pi))`] o CONJUNCT2) THEN + ASM_REWRITE_TAC[GSYM LIFT_NUM; IN_INTERVAL_1; LIFT_DROP; LIFT_EQ] THEN + ASM_SIMP_TAC[REAL_LE_RDIV_EQ; REAL_LE_LDIV_EQ; PI_POS; + REAL_ARITH `&0 < &2 * x <=> &0 < x`; + REAL_FIELD `&0 < y ==> (x / y = &1 <=> x = y)`] THEN + SIMP_TAC[REAL_MUL_LZERO; REAL_MUL_LID; ARG; REAL_LT_IMP_LE; + REAL_LT_IMP_NE]]);; + +let HOMEOMORPHIC_SIMPLE_PATH_IMAGES = prove + (`!g:real^1->real^M h:real^1->real^N. + simple_path g /\ pathfinish g = pathstart g /\ + simple_path h /\ pathfinish h = pathstart h + ==> (path_image g) homeomorphic (path_image h)`, + REPEAT STRIP_TAC THEN + TRANS_TAC HOMEOMORPHIC_TRANS `sphere(vec 0:real^2,&1)` THEN + CONJ_TAC THENL [ALL_TAC; ONCE_REWRITE_TAC[HOMEOMORPHIC_SYM]] THEN + MATCH_MP_TAC HOMEOMORPHIC_SIMPLE_PATH_IMAGE_CIRCLE THEN + ASM_REWRITE_TAC[REAL_LT_01]);; + +let ANR_PATH_IMAGE_SIMPLE_PATH = prove + (`!g:real^1->real^N. + simple_path g ==> ?t. open t /\ (path_image g) retract_of t`, + REPEAT STRIP_TAC THEN + ASM_CASES_TAC `pathfinish g:real^N = pathstart g` THENL + [MP_TAC(ISPECL [`g:real^1->real^N`; `vec 0:real^2`; `&1`] + HOMEOMORPHIC_SIMPLE_PATH_IMAGE_CIRCLE) THEN + ASM_REWRITE_TAC[REAL_LT_01] THEN + DISCH_THEN(SUBST1_TAC o MATCH_MP HOMEOMORPHIC_ANRNESS) THEN + EXISTS_TAC `(:real^2) DELETE (vec 0)` THEN + SIMP_TAC[OPEN_DELETE; OPEN_UNIV] THEN + MATCH_MP_TAC SPHERE_RETRACT_OF_PUNCTURED_UNIVERSE THEN + REWRITE_TAC[REAL_LT_01]; + EXISTS_TAC `(:real^N)` THEN REWRITE_TAC[OPEN_UNIV] THEN + MATCH_MP_TAC ABSOLUTE_RETRACT_PATH_IMAGE_ARC THEN + ASM_REWRITE_TAC[ARC_SIMPLE_PATH; SUBSET_UNIV]]);; diff --git a/Multivariate/vectors.ml b/Multivariate/vectors.ml new file mode 100644 index 0000000..55d018e --- /dev/null +++ b/Multivariate/vectors.ml @@ -0,0 +1,8489 @@ +(* ========================================================================= *) +(* Real vectors in Euclidean space, and elementary linear algebra. *) +(* *) +(* (c) Copyright, John Harrison 1998-2008 *) +(* ========================================================================= *) + +needs "Multivariate/misc.ml";; + +(* ------------------------------------------------------------------------- *) +(* Some common special cases. *) +(* ------------------------------------------------------------------------- *) + +let FORALL_1 = prove + (`(!i. 1 <= i /\ i <= 1 ==> P i) <=> P 1`, + MESON_TAC[LE_ANTISYM]);; + +let FORALL_2 = prove + (`!P. (!i. 1 <= i /\ i <= 2 ==> P i) <=> P 1 /\ P 2`, + MESON_TAC[ARITH_RULE `1 <= i /\ i <= 2 <=> i = 1 \/ i = 2`]);; + +let FORALL_3 = prove + (`!P. (!i. 1 <= i /\ i <= 3 ==> P i) <=> P 1 /\ P 2 /\ P 3`, + MESON_TAC[ARITH_RULE `1 <= i /\ i <= 3 <=> i = 1 \/ i = 2 \/ i = 3`]);; + +let FORALL_4 = prove + (`!P. (!i. 1 <= i /\ i <= 4 ==> P i) <=> P 1 /\ P 2 /\ P 3 /\ P 4`, + MESON_TAC[ARITH_RULE `1 <= i /\ i <= 4 <=> + i = 1 \/ i = 2 \/ i = 3 \/ i = 4`]);; + +let SUM_1 = prove + (`sum(1..1) f = f(1)`, + REWRITE_TAC[SUM_SING_NUMSEG]);; + +let SUM_2 = prove + (`!t. sum(1..2) t = t(1) + t(2)`, + REWRITE_TAC[num_CONV `2`; SUM_CLAUSES_NUMSEG] THEN + REWRITE_TAC[SUM_SING_NUMSEG; ARITH; REAL_ADD_ASSOC]);; + +let SUM_3 = prove + (`!t. sum(1..3) t = t(1) + t(2) + t(3)`, + REWRITE_TAC[num_CONV `3`; num_CONV `2`; SUM_CLAUSES_NUMSEG] THEN + REWRITE_TAC[SUM_SING_NUMSEG; ARITH; REAL_ADD_ASSOC]);; + +let SUM_4 = prove + (`!t. sum(1..4) t = t(1) + t(2) + t(3) + t(4)`, + SIMP_TAC[num_CONV `4`; num_CONV `3`; num_CONV `2`; SUM_CLAUSES_NUMSEG] THEN + REWRITE_TAC[SUM_SING_NUMSEG; ARITH; REAL_ADD_ASSOC]);; + +(* ------------------------------------------------------------------------- *) +(* Basic componentwise operations on vectors. *) +(* ------------------------------------------------------------------------- *) + +let vector_add = new_definition + `(vector_add:real^N->real^N->real^N) x y = lambda i. x$i + y$i`;; + +let vector_sub = new_definition + `(vector_sub:real^N->real^N->real^N) x y = lambda i. x$i - y$i`;; + +let vector_neg = new_definition + `(vector_neg:real^N->real^N) x = lambda i. --(x$i)`;; + +overload_interface ("+",`(vector_add):real^N->real^N->real^N`);; +overload_interface ("-",`(vector_sub):real^N->real^N->real^N`);; +overload_interface ("--",`(vector_neg):real^N->real^N`);; + +prioritize_real();; + +let prioritize_vector = let ty = `:real^N` in + fun () -> prioritize_overload ty;; + +(* ------------------------------------------------------------------------- *) +(* Also the scalar-vector multiplication. *) +(* ------------------------------------------------------------------------- *) + +parse_as_infix("%",(21,"right"));; + +let vector_mul = new_definition + `((%):real->real^N->real^N) c x = lambda i. c * x$i`;; + +(* ------------------------------------------------------------------------- *) +(* Vectors corresponding to small naturals. Perhaps should overload "&"? *) +(* ------------------------------------------------------------------------- *) + +let vec = new_definition + `(vec:num->real^N) n = lambda i. &n`;; + +(* ------------------------------------------------------------------------- *) +(* Dot products. *) +(* ------------------------------------------------------------------------- *) + +parse_as_infix("dot",(20,"right"));; + +let dot = new_definition + `(x:real^N) dot (y:real^N) = sum(1..dimindex(:N)) (\i. x$i * y$i)`;; + +let DOT_1 = prove + (`(x:real^1) dot (y:real^1) = x$1 * y$1`, + REWRITE_TAC[dot; DIMINDEX_1; SUM_1]);; + +let DOT_2 = prove + (`(x:real^2) dot (y:real^2) = x$1 * y$1 + x$2 * y$2`, + REWRITE_TAC[dot; DIMINDEX_2; SUM_2]);; + +let DOT_3 = prove + (`(x:real^3) dot (y:real^3) = x$1 * y$1 + x$2 * y$2 + x$3 * y$3`, + REWRITE_TAC[dot; DIMINDEX_3; SUM_3]);; + +let DOT_4 = prove + (`(x:real^4) dot (y:real^4) = x$1 * y$1 + x$2 * y$2 + x$3 * y$3 + x$4 * y$4`, + REWRITE_TAC[dot; DIMINDEX_4; SUM_4]);; + +(* ------------------------------------------------------------------------- *) +(* A naive proof procedure to lift really trivial arithmetic stuff from R. *) +(* ------------------------------------------------------------------------- *) + +let VECTOR_ARITH_TAC = + let RENAMED_LAMBDA_BETA th = + if fst(dest_fun_ty(type_of(funpow 3 rand (concl th)))) = aty + then INST_TYPE [aty,bty; bty,aty] LAMBDA_BETA else LAMBDA_BETA in + POP_ASSUM_LIST(K ALL_TAC) THEN + REPEAT(GEN_TAC ORELSE CONJ_TAC ORELSE DISCH_TAC ORELSE EQ_TAC) THEN + REPEAT(POP_ASSUM MP_TAC) THEN REWRITE_TAC[IMP_IMP; GSYM CONJ_ASSOC] THEN + REWRITE_TAC[dot; GSYM SUM_ADD_NUMSEG; GSYM SUM_SUB_NUMSEG; + GSYM SUM_LMUL; GSYM SUM_RMUL; GSYM SUM_NEG] THEN + (MATCH_MP_TAC SUM_EQ_NUMSEG ORELSE MATCH_MP_TAC SUM_EQ_0_NUMSEG ORELSE + GEN_REWRITE_TAC ONCE_DEPTH_CONV [CART_EQ]) THEN + REWRITE_TAC[AND_FORALL_THM] THEN TRY EQ_TAC THEN + TRY(MATCH_MP_TAC MONO_FORALL) THEN GEN_TAC THEN + REWRITE_TAC[TAUT `(a ==> b) /\ (a ==> c) <=> a ==> b /\ c`; + TAUT `(a ==> b) \/ (a ==> c) <=> a ==> b \/ c`] THEN + TRY(MATCH_MP_TAC(TAUT `(a ==> b ==> c) ==> (a ==> b) ==> (a ==> c)`)) THEN + REWRITE_TAC[vector_add; vector_sub; vector_neg; vector_mul; vec] THEN + DISCH_THEN(fun th -> REWRITE_TAC[MATCH_MP(RENAMED_LAMBDA_BETA th) th]) THEN + REAL_ARITH_TAC;; + +let VECTOR_ARITH tm = prove(tm,VECTOR_ARITH_TAC);; + +(* ------------------------------------------------------------------------- *) +(* Obvious "component-pushing". *) +(* ------------------------------------------------------------------------- *) + +let VEC_COMPONENT = prove + (`!k i. (vec k :real^N)$i = &k`, + REPEAT GEN_TAC THEN + SUBGOAL_THEN `?k. 1 <= k /\ k <= dimindex(:N) /\ !z:real^N. z$i = z$k` + CHOOSE_TAC THENL + [REWRITE_TAC[FINITE_INDEX_INRANGE]; + ASM_SIMP_TAC[vec; CART_EQ; LAMBDA_BETA]]);; + +let VECTOR_ADD_COMPONENT = prove + (`!x:real^N y i. (x + y)$i = x$i + y$i`, + REPEAT GEN_TAC THEN + SUBGOAL_THEN `?k. 1 <= k /\ k <= dimindex(:N) /\ !z:real^N. z$i = z$k` + CHOOSE_TAC THENL + [REWRITE_TAC[FINITE_INDEX_INRANGE]; + ASM_SIMP_TAC[vector_add; CART_EQ; LAMBDA_BETA]]);; + +let VECTOR_SUB_COMPONENT = prove + (`!x:real^N y i. (x - y)$i = x$i - y$i`, + REPEAT GEN_TAC THEN + SUBGOAL_THEN `?k. 1 <= k /\ k <= dimindex(:N) /\ !z:real^N. z$i = z$k` + CHOOSE_TAC THENL + [REWRITE_TAC[FINITE_INDEX_INRANGE]; + ASM_SIMP_TAC[vector_sub; CART_EQ; LAMBDA_BETA]]);; + +let VECTOR_NEG_COMPONENT = prove + (`!x:real^N i. (--x)$i = --(x$i)`, + REPEAT GEN_TAC THEN + SUBGOAL_THEN `?k. 1 <= k /\ k <= dimindex(:N) /\ !z:real^N. z$i = z$k` + CHOOSE_TAC THENL + [REWRITE_TAC[FINITE_INDEX_INRANGE]; + ASM_SIMP_TAC[vector_neg; CART_EQ; LAMBDA_BETA]]);; + +let VECTOR_MUL_COMPONENT = prove + (`!c x:real^N i. (c % x)$i = c * x$i`, + REPEAT GEN_TAC THEN + SUBGOAL_THEN `?k. 1 <= k /\ k <= dimindex(:N) /\ !z:real^N. z$i = z$k` + CHOOSE_TAC THENL + [REWRITE_TAC[FINITE_INDEX_INRANGE]; + ASM_SIMP_TAC[vector_mul; CART_EQ; LAMBDA_BETA]]);; + +let COND_COMPONENT = prove + (`(if b then x else y)$i = if b then x$i else y$i`, + MESON_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* Some frequently useful arithmetic lemmas over vectors. *) +(* ------------------------------------------------------------------------- *) + +let VECTOR_ADD_SYM = VECTOR_ARITH `!x y:real^N. x + y = y + x`;; + +let VECTOR_ADD_LID = VECTOR_ARITH `!x. vec 0 + x = x`;; + +let VECTOR_ADD_RID = VECTOR_ARITH `!x. x + vec 0 = x`;; + +let VECTOR_SUB_REFL = VECTOR_ARITH `!x. x - x = vec 0`;; + +let VECTOR_ADD_LINV = VECTOR_ARITH `!x. --x + x = vec 0`;; + +let VECTOR_ADD_RINV = VECTOR_ARITH `!x. x + --x = vec 0`;; + +let VECTOR_SUB_RADD = VECTOR_ARITH `!x y. x - (x + y) = --y:real^N`;; + +let VECTOR_NEG_SUB = VECTOR_ARITH `!x:real^N y. --(x - y) = y - x`;; + +let VECTOR_SUB_EQ = VECTOR_ARITH `!x y. (x - y = vec 0) <=> (x = y)`;; + +let VECTOR_MUL_ASSOC = VECTOR_ARITH `!a b x. a % (b % x) = (a * b) % x`;; + +let VECTOR_MUL_LID = VECTOR_ARITH `!x. &1 % x = x`;; + +let VECTOR_MUL_LZERO = VECTOR_ARITH `!x. &0 % x = vec 0`;; + +let VECTOR_SUB_ADD = VECTOR_ARITH `(x - y) + y = x:real^N`;; + +let VECTOR_SUB_ADD2 = VECTOR_ARITH `y + (x - y) = x:real^N`;; + +let VECTOR_ADD_LDISTRIB = VECTOR_ARITH `c % (x + y) = c % x + c % y`;; + +let VECTOR_SUB_LDISTRIB = VECTOR_ARITH `c % (x - y) = c % x - c % y`;; + +let VECTOR_ADD_RDISTRIB = VECTOR_ARITH `(a + b) % x = a % x + b % x`;; + +let VECTOR_SUB_RDISTRIB = VECTOR_ARITH `(a - b) % x = a % x - b % x`;; + +let VECTOR_ADD_SUB = VECTOR_ARITH `(x + y:real^N) - x = y`;; + +let VECTOR_EQ_ADDR = VECTOR_ARITH `(x + y = x) <=> (y = vec 0)`;; + +let VECTOR_SUB = VECTOR_ARITH `x - y = x + --(y:real^N)`;; + +let VECTOR_SUB_RZERO = VECTOR_ARITH `x - vec 0 = x`;; + +let VECTOR_MUL_RZERO = VECTOR_ARITH `c % vec 0 = vec 0`;; + +let VECTOR_NEG_MINUS1 = VECTOR_ARITH `--x = (--(&1)) % x`;; + +let VECTOR_ADD_ASSOC = VECTOR_ARITH `(x:real^N) + y + z = (x + y) + z`;; + +let VECTOR_SUB_LZERO = VECTOR_ARITH `vec 0 - x = --x`;; + +let VECTOR_NEG_NEG = VECTOR_ARITH `--(--(x:real^N)) = x`;; + +let VECTOR_MUL_LNEG = VECTOR_ARITH `--c % x = --(c % x)`;; + +let VECTOR_MUL_RNEG = VECTOR_ARITH `c % --x = --(c % x)`;; + +let VECTOR_NEG_0 = VECTOR_ARITH `--(vec 0) = vec 0`;; + +let VECTOR_NEG_EQ_0 = VECTOR_ARITH `--x = vec 0 <=> x = vec 0`;; + +let VECTOR_EQ_NEG2 = VECTOR_ARITH `!x y:real^N. --x = --y <=> x = y`;; + +let VECTOR_ADD_AC = VECTOR_ARITH + `(m + n = n + m:real^N) /\ + ((m + n) + p = m + n + p) /\ + (m + n + p = n + m + p)`;; + +let VEC_EQ = prove + (`!m n. (vec m = vec n) <=> (m = n)`, + SIMP_TAC[CART_EQ; VEC_COMPONENT; REAL_OF_NUM_EQ] THEN + MESON_TAC[LE_REFL; DIMINDEX_GE_1]);; + +(* ------------------------------------------------------------------------- *) +(* Infinitude of Euclidean space. *) +(* ------------------------------------------------------------------------- *) + +let EUCLIDEAN_SPACE_INFINITE = prove + (`INFINITE(:real^N)`, + REWRITE_TAC[INFINITE] THEN DISCH_TAC THEN + FIRST_ASSUM(MP_TAC o ISPEC `vec:num->real^N` o + MATCH_MP (REWRITE_RULE[IMP_CONJ_ALT] FINITE_IMAGE_INJ)) THEN + REWRITE_TAC[VEC_EQ; SET_RULE `{x | f x IN UNIV} = UNIV`] THEN + REWRITE_TAC[GSYM INFINITE; num_INFINITE]);; + +(* ------------------------------------------------------------------------- *) +(* Properties of the dot product. *) +(* ------------------------------------------------------------------------- *) + +let DOT_SYM = VECTOR_ARITH `!x y. x dot y = y dot x`;; + +let DOT_LADD = VECTOR_ARITH `!x y z. (x + y) dot z = (x dot z) + (y dot z)`;; + +let DOT_RADD = VECTOR_ARITH `!x y z. x dot (y + z) = (x dot y) + (x dot z)`;; + +let DOT_LSUB = VECTOR_ARITH `!x y z. (x - y) dot z = (x dot z) - (y dot z)`;; + +let DOT_RSUB = VECTOR_ARITH `!x y z. x dot (y - z) = (x dot y) - (x dot z)`;; + +let DOT_LMUL = VECTOR_ARITH `!c x y. (c % x) dot y = c * (x dot y)`;; + +let DOT_RMUL = VECTOR_ARITH `!c x y. x dot (c % y) = c * (x dot y)`;; + +let DOT_LNEG = VECTOR_ARITH `!x y. (--x) dot y = --(x dot y)`;; + +let DOT_RNEG = VECTOR_ARITH `!x y. x dot (--y) = --(x dot y)`;; + +let DOT_LZERO = VECTOR_ARITH `!x. (vec 0) dot x = &0`;; + +let DOT_RZERO = VECTOR_ARITH `!x. x dot (vec 0) = &0`;; + +let DOT_POS_LE = prove + (`!x. &0 <= x dot x`, + SIMP_TAC[dot; SUM_POS_LE_NUMSEG; REAL_LE_SQUARE]);; + +let DOT_EQ_0 = prove + (`!x:real^N. ((x dot x = &0) <=> (x = vec 0))`, + REPEAT GEN_TAC THEN EQ_TAC THENL [ALL_TAC; MESON_TAC[DOT_LZERO]] THEN + SIMP_TAC[dot; CART_EQ; vec; LAMBDA_BETA] THEN DISCH_TAC THEN + ONCE_REWRITE_TAC[GSYM(REWRITE_CONV[REAL_ENTIRE] `x * x = &0`)] THEN + MATCH_MP_TAC SUM_POS_EQ_0_NUMSEG THEN ASM_REWRITE_TAC[REAL_LE_SQUARE]);; + +let DOT_POS_LT = prove + (`!x. (&0 < x dot x) <=> ~(x = vec 0)`, + REWRITE_TAC[REAL_LT_LE; DOT_POS_LE] THEN MESON_TAC[DOT_EQ_0]);; + +let FORALL_DOT_EQ_0 = prove + (`(!y. (!x. x dot y = &0) <=> y = vec 0) /\ + (!x. (!y. x dot y = &0) <=> x = vec 0)`, + MESON_TAC[DOT_LZERO; DOT_RZERO; DOT_EQ_0]);; + +(* ------------------------------------------------------------------------- *) +(* Introduce norms, but defer many properties till we get square roots. *) +(* ------------------------------------------------------------------------- *) + +make_overloadable "norm" `:A->real`;; +overload_interface("norm",`vector_norm:real^N->real`);; + +let vector_norm = new_definition + `norm x = sqrt(x dot x)`;; + +(* ------------------------------------------------------------------------- *) +(* Useful for the special cases of 1 dimension. *) +(* ------------------------------------------------------------------------- *) + +let FORALL_DIMINDEX_1 = prove + (`(!i. 1 <= i /\ i <= dimindex(:1) ==> P i) <=> P 1`, + MESON_TAC[DIMINDEX_1; LE_ANTISYM]);; + +(* ------------------------------------------------------------------------- *) +(* The collapse of the general concepts to the real line R^1. *) +(* ------------------------------------------------------------------------- *) + +let VECTOR_ONE = prove + (`!x:real^1. x = lambda i. x$1`, + SIMP_TAC[CART_EQ; LAMBDA_BETA] THEN MESON_TAC[DIMINDEX_1; LE_ANTISYM]);; + +let FORALL_REAL_ONE = prove + (`(!x:real^1. P x) <=> (!x. P(lambda i. x))`, + EQ_TAC THEN SIMP_TAC[] THEN DISCH_TAC THEN GEN_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `(x:real^1)$1`) THEN + REWRITE_TAC[GSYM VECTOR_ONE]);; + +let NORM_REAL = prove + (`!x:real^1. norm(x) = abs(x$1)`, + REWRITE_TAC[vector_norm; dot; DIMINDEX_1; SUM_SING_NUMSEG; + GSYM REAL_POW_2; POW_2_SQRT_ABS]);; + +(* ------------------------------------------------------------------------- *) +(* Metric function. *) +(* ------------------------------------------------------------------------- *) + +override_interface("dist",`distance:real^N#real^N->real`);; + +let dist = new_definition + `dist(x,y) = norm(x - y)`;; + +let DIST_REAL = prove + (`!x:real^1 y. dist(x,y) = abs(x$1 - y$1)`, + SIMP_TAC[dist; NORM_REAL; vector_sub; LAMBDA_BETA; LE_REFL; DIMINDEX_1]);; + +(* ------------------------------------------------------------------------- *) +(* A connectedness or intermediate value lemma with several applications. *) +(* ------------------------------------------------------------------------- *) + +let CONNECTED_REAL_LEMMA = prove + (`!f:real->real^N a b e1 e2. + a <= b /\ f(a) IN e1 /\ f(b) IN e2 /\ + (!e x. a <= x /\ x <= b /\ &0 < e + ==> ?d. &0 < d /\ + !y. abs(y - x) < d ==> dist(f(y),f(x)) < e) /\ + (!y. y IN e1 ==> ?e. &0 < e /\ !y'. dist(y',y) < e ==> y' IN e1) /\ + (!y. y IN e2 ==> ?e. &0 < e /\ !y'. dist(y',y) < e ==> y' IN e2) /\ + ~(?x. a <= x /\ x <= b /\ f(x) IN e1 /\ f(x) IN e2) + ==> ?x. a <= x /\ x <= b /\ ~(f(x) IN e1) /\ ~(f(x) IN e2)`, + let tac = ASM_MESON_TAC[REAL_LT_IMP_LE; REAL_LE_TOTAL; REAL_LE_ANTISYM] in + REWRITE_TAC[EXTENSION; NOT_IN_EMPTY] THEN REPEAT STRIP_TAC THEN + MP_TAC(SPEC `\c. !x. a <= x /\ x <= c ==> (f(x):real^N) IN e1` + REAL_COMPLETE) THEN + REWRITE_TAC[] THEN ANTS_TAC THENL [tac; ALL_TAC] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `x:real` THEN STRIP_TAC THEN + SUBGOAL_THEN `a <= x /\ x <= b` STRIP_ASSUME_TAC THENL [tac; ALL_TAC] THEN + ASM_REWRITE_TAC[] THEN + SUBGOAL_THEN `!z. a <= z /\ z < x ==> (f(z):real^N) IN e1` ASSUME_TAC THENL + [ASM_MESON_TAC[REAL_NOT_LT; REAL_LT_IMP_LE]; ALL_TAC] THEN + REPEAT STRIP_TAC THENL + [SUBGOAL_THEN + `?d. &0 < d /\ !y. abs(y - x) < d ==> (f(y):real^N) IN e1` + STRIP_ASSUME_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN + ASM_MESON_TAC[REAL_ARITH `z <= x + e /\ e < d ==> z < x \/ abs(z - x) < d`; + REAL_ARITH `&0 < e ==> ~(x + e <= x)`; REAL_DOWN]; + SUBGOAL_THEN + `?d. &0 < d /\ !y. abs(y - x) < d ==> (f(y):real^N) IN e2` + STRIP_ASSUME_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN + MP_TAC(SPECL [`x - a`; `d:real`] REAL_DOWN2) THEN ANTS_TAC THENL + [ASM_MESON_TAC[REAL_LT_LE; REAL_SUB_LT]; ALL_TAC] THEN + ASM_MESON_TAC[REAL_ARITH `e < x - a ==> a <= x - e`; + REAL_ARITH `&0 < e /\ x <= b ==> x - e <= b`; + REAL_ARITH `&0 < e /\ e < d ==> x - e < x /\ abs((x - e) - x) < d`]]);; + +(* ------------------------------------------------------------------------- *) +(* One immediately useful corollary is the existence of square roots! *) +(* ------------------------------------------------------------------------- *) + +let SQUARE_BOUND_LEMMA = prove + (`!x. x < (&1 + x) * (&1 + x)`, + GEN_TAC THEN REWRITE_TAC[REAL_POW_2] THEN + MAP_EVERY (fun t -> MP_TAC(SPEC t REAL_LE_SQUARE)) [`x:real`; `&1 + x`] THEN + REAL_ARITH_TAC);; + +let SQUARE_CONTINUOUS = prove + (`!x e. &0 < e + ==> ?d. &0 < d /\ !y. abs(y - x) < d ==> abs(y * y - x * x) < e`, + REPEAT STRIP_TAC THEN ASM_CASES_TAC `x = &0` THENL + [ASM_REWRITE_TAC[REAL_MUL_LZERO; REAL_SUB_RZERO] THEN + EXISTS_TAC `inv(&1 + inv(e))` THEN + ASM_SIMP_TAC[REAL_LT_INV_EQ; REAL_LT_ADD; REAL_LT_01] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_LTE_TRANS THEN + EXISTS_TAC `inv(&1 + inv(e)) * inv(&1 + inv(e))` THEN + ASM_SIMP_TAC[REAL_ABS_MUL; REAL_LT_MUL2; REAL_ABS_POS] THEN + REWRITE_TAC[GSYM REAL_INV_MUL] THEN + GEN_REWRITE_TAC RAND_CONV [GSYM REAL_INV_INV] THEN + MATCH_MP_TAC REAL_LE_INV2 THEN + ASM_SIMP_TAC[REAL_LT_IMP_LE; SQUARE_BOUND_LEMMA; REAL_LT_INV_EQ]; + MP_TAC(SPECL [`abs(x)`; `e / (&3 * abs(x))`] REAL_DOWN2)THEN + ASM_SIMP_TAC[GSYM REAL_ABS_NZ; REAL_LT_DIV; REAL_LT_MUL; REAL_OF_NUM_LT; + ARITH; REAL_LT_RDIV_EQ] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `d:real` THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN X_GEN_TAC `y:real` THEN + REWRITE_TAC[REAL_ARITH `x * x - y * y = (x - y) * (x + y)`] THEN + DISCH_TAC THEN MATCH_MP_TAC REAL_LET_TRANS THEN + EXISTS_TAC `d * &3 * abs(x)` THEN ASM_REWRITE_TAC[REAL_ABS_MUL] THEN + MATCH_MP_TAC REAL_LE_MUL2 THEN + ASM_SIMP_TAC[REAL_ABS_POS; REAL_LT_IMP_LE] THEN + MAP_EVERY UNDISCH_TAC [`abs (y - x) < d`; `d < abs(x)`] THEN + REAL_ARITH_TAC]);; + +let SQRT_WORKS = prove + (`!x. &0 <= x ==> &0 <= sqrt(x) /\ (sqrt(x) pow 2 = x)`, + GEN_TAC THEN GEN_REWRITE_TAC LAND_CONV [REAL_LE_LT] THEN STRIP_TAC THENL + [ALL_TAC; + ASM_MESON_TAC[SQRT_0; REAL_POW_2; REAL_LE_REFL; REAL_MUL_LZERO]] THEN + REWRITE_TAC[sqrt] THEN CONV_TAC SELECT_CONV THEN + MP_TAC(ISPECL [`(\u. lambda i. u):real->real^1`; `&0`; `&1 + x`; + `{u:real^1 | u$1 * u$1 < x}`; `{u:real^1 | u$1 * u$1 > x}`] + CONNECTED_REAL_LEMMA) THEN + SIMP_TAC[LAMBDA_BETA; LE_REFL; DIMINDEX_1; DIST_REAL; + EXTENSION; IN_INTER; IN_ELIM_THM; NOT_IN_EMPTY; + REAL_MUL_LZERO; FORALL_REAL_ONE; real_gt] THEN + ANTS_TAC THENL [ALL_TAC; ASM_MESON_TAC[REAL_POW_2; REAL_LT_TOTAL]] THEN + ASM_SIMP_TAC[REAL_LT_ANTISYM; REAL_ARITH `&0 < x ==> &0 <= &1 + x`] THEN + REWRITE_TAC[SQUARE_BOUND_LEMMA] THEN + MESON_TAC[SQUARE_CONTINUOUS; REAL_SUB_LT; + REAL_ARITH `abs(z2 - x2) < y - x2 ==> z2 < y`; + REAL_ARITH `abs(z2 - x2) < x2 - y ==> y < z2`]);; + +let SQRT_POS_LE = prove + (`!x. &0 <= x ==> &0 <= sqrt(x)`, + MESON_TAC[SQRT_WORKS]);; + +let SQRT_POW_2 = prove + (`!x. &0 <= x ==> (sqrt(x) pow 2 = x)`, + MESON_TAC[SQRT_WORKS]);; + +let SQRT_MUL = prove + (`!x y. &0 <= x /\ &0 <= y + ==> (sqrt(x * y) = sqrt x * sqrt y)`, + ASM_MESON_TAC[REAL_POW_2; SQRT_WORKS; REAL_LE_MUL; SQRT_UNIQUE; + REAL_ARITH `(x * y) * (x * y) = (x * x) * y * y`]);; + +let SQRT_INV = prove + (`!x. &0 <= x ==> (sqrt (inv x) = inv(sqrt x))`, + MESON_TAC[SQRT_UNIQUE; SQRT_WORKS; REAL_POW_INV; REAL_LE_INV_EQ]);; + +let SQRT_DIV = prove + (`!x y. &0 <= x /\ &0 <= y ==> (sqrt (x / y) = sqrt x / sqrt y)`, + SIMP_TAC[real_div; SQRT_MUL; SQRT_INV; REAL_LE_INV_EQ]);; + +let SQRT_POW2 = prove + (`!x. (sqrt(x) pow 2 = x) <=> &0 <= x`, + MESON_TAC[REAL_POW_2; REAL_LE_SQUARE; SQRT_POW_2]);; + +let SQRT_MONO_LT = prove + (`!x y. &0 <= x /\ x < y ==> sqrt(x) < sqrt(y)`, + REWRITE_TAC[GSYM REAL_NOT_LE] THEN + MESON_TAC[REAL_LT_IMP_LE; REAL_NOT_LE; REAL_LE_TRANS; + REAL_POW_LE2; SQRT_WORKS]);; + +let SQRT_MONO_LE = prove + (`!x y. &0 <= x /\ x <= y ==> sqrt(x) <= sqrt(y)`, + MESON_TAC[REAL_LE_LT; SQRT_MONO_LT]);; + +let SQRT_MONO_LT_EQ = prove + (`!x y. &0 <= x /\ &0 <= y ==> (sqrt(x) < sqrt(y) <=> x < y)`, + MESON_TAC[REAL_NOT_LT; SQRT_MONO_LT; SQRT_MONO_LE]);; + +let SQRT_MONO_LE_EQ = prove + (`!x y. &0 <= x /\ &0 <= y ==> (sqrt(x) <= sqrt(y) <=> x <= y)`, + MESON_TAC[REAL_NOT_LT; SQRT_MONO_LT; SQRT_MONO_LE]);; + +let SQRT_INJ = prove + (`!x y. &0 <= x /\ &0 <= y ==> ((sqrt(x) = sqrt(y)) <=> (x = y))`, + SIMP_TAC[GSYM REAL_LE_ANTISYM; SQRT_MONO_LE_EQ]);; + +let SQRT_LT_0 = prove + (`!x. &0 <= x ==> (&0 < sqrt x <=> &0 < x)`, + MESON_TAC[SQRT_0; REAL_LE_REFL; SQRT_MONO_LT_EQ]);; + +let SQRT_EQ_0 = prove + (`!x. &0 <= x ==> ((sqrt x = &0) <=> (x = &0))`, + MESON_TAC[SQRT_INJ; SQRT_0; REAL_LE_REFL]);; + +let SQRT_POS_LT = prove + (`!x. &0 < x ==> &0 < sqrt(x)`, + MESON_TAC[REAL_LT_LE; SQRT_POS_LE; SQRT_EQ_0]);; + +let REAL_LE_LSQRT = prove + (`!x y. &0 <= x /\ &0 <= y /\ x <= y pow 2 ==> sqrt(x) <= y`, + MESON_TAC[SQRT_MONO_LE; REAL_POW_LE; POW_2_SQRT]);; + +let REAL_LE_RSQRT = prove + (`!x y. x pow 2 <= y ==> x <= sqrt(y)`, + MESON_TAC[REAL_LE_TOTAL; SQRT_MONO_LE; SQRT_POS_LE; REAL_POW_2; + REAL_LE_SQUARE; REAL_LE_TRANS; POW_2_SQRT]);; + +let REAL_LT_LSQRT = prove + (`!x y. &0 <= x /\ &0 <= y /\ x < y pow 2 ==> sqrt x < y`, + MESON_TAC[SQRT_MONO_LT; REAL_POW_LE; POW_2_SQRT]);; + +let REAL_LT_RSQRT = prove + (`!x y. x pow 2 < y ==> x < sqrt(y)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC(REAL_ARITH `abs x < a ==> x < a`) THEN + REWRITE_TAC[GSYM POW_2_SQRT_ABS] THEN MATCH_MP_TAC SQRT_MONO_LT THEN + ASM_REWRITE_TAC[REAL_POW_2; REAL_LE_SQUARE]);; + +let SQRT_EVEN_POW2 = prove + (`!n. EVEN n ==> (sqrt(&2 pow n) = &2 pow (n DIV 2))`, + SIMP_TAC[EVEN_EXISTS; LEFT_IMP_EXISTS_THM; DIV_MULT; ARITH_EQ] THEN + MESON_TAC[SQRT_UNIQUE; REAL_POW_POW; MULT_SYM; REAL_POW_LE; REAL_POS]);; + +let REAL_DIV_SQRT = prove + (`!x. &0 <= x ==> (x / sqrt(x) = sqrt(x))`, + REWRITE_TAC[REAL_LE_LT] THEN REPEAT STRIP_TAC THENL + [ALL_TAC; ASM_MESON_TAC[SQRT_0; real_div; REAL_MUL_LZERO]] THEN + ASM_SIMP_TAC[REAL_EQ_LDIV_EQ; SQRT_POS_LT; GSYM REAL_POW_2] THEN + ASM_SIMP_TAC[SQRT_POW_2; REAL_LT_IMP_LE]);; + +let REAL_RSQRT_LE = prove + (`!x y. &0 <= x /\ &0 <= y /\ x <= sqrt y ==> x pow 2 <= y`, + MESON_TAC[REAL_POW_LE2; SQRT_POW_2]);; + +let REAL_LSQRT_LE = prove + (`!x y. &0 <= x /\ sqrt x <= y ==> x <= y pow 2`, + MESON_TAC[REAL_POW_LE2; SQRT_POS_LE; REAL_LE_TRANS; SQRT_POW_2]);; + +(* ------------------------------------------------------------------------- *) +(* Hence derive more interesting properties of the norm. *) +(* ------------------------------------------------------------------------- *) + +let NORM_0 = prove + (`norm(vec 0) = &0`, + REWRITE_TAC[vector_norm; DOT_LZERO; SQRT_0]);; + +let NORM_POS_LE = prove + (`!x. &0 <= norm x`, + GEN_TAC THEN SIMP_TAC[DOT_POS_LE; vector_norm; SQRT_POS_LE]);; + +let NORM_NEG = prove + (`!x. norm(--x) = norm x`, + REWRITE_TAC[vector_norm; DOT_LNEG; DOT_RNEG; REAL_NEG_NEG]);; + +let NORM_SUB = prove + (`!x y. norm(x - y) = norm(y - x)`, + MESON_TAC[NORM_NEG; VECTOR_NEG_SUB]);; + +let NORM_MUL = prove + (`!a x. norm(a % x) = abs(a) * norm x`, + REWRITE_TAC[vector_norm; DOT_LMUL; DOT_RMUL; REAL_MUL_ASSOC] THEN + SIMP_TAC[SQRT_MUL; SQRT_POS_LE; DOT_POS_LE; REAL_LE_SQUARE] THEN + REWRITE_TAC[GSYM REAL_POW_2; POW_2_SQRT_ABS]);; + +let NORM_EQ_0_DOT = prove + (`!x. (norm x = &0) <=> (x dot x = &0)`, + SIMP_TAC[vector_norm; SQRT_EQ_0; DOT_POS_LE]);; + +let NORM_EQ_0 = prove + (`!x. (norm x = &0) <=> (x = vec 0)`, + SIMP_TAC[vector_norm; DOT_EQ_0; SQRT_EQ_0; DOT_POS_LE]);; + +let NORM_POS_LT = prove + (`!x. &0 < norm x <=> ~(x = vec 0)`, + MESON_TAC[REAL_LT_LE; NORM_POS_LE; NORM_EQ_0]);; + +let NORM_POW_2 = prove + (`!x. norm(x) pow 2 = x dot x`, + SIMP_TAC[vector_norm; SQRT_POW_2; DOT_POS_LE]);; + +let NORM_EQ_0_IMP = prove + (`!x. (norm x = &0) ==> (x = vec 0)`, + MESON_TAC[NORM_EQ_0]);; + +let NORM_LE_0 = prove + (`!x. norm x <= &0 <=> (x = vec 0)`, + MESON_TAC[REAL_LE_ANTISYM; NORM_EQ_0; NORM_POS_LE]);; + +let VECTOR_MUL_EQ_0 = prove + (`!a x. (a % x = vec 0) <=> (a = &0) \/ (x = vec 0)`, + REWRITE_TAC[GSYM NORM_EQ_0; NORM_MUL; REAL_ABS_ZERO; REAL_ENTIRE]);; + +let VECTOR_MUL_LCANCEL = prove + (`!a x y. (a % x = a % y) <=> (a = &0) \/ (x = y)`, + MESON_TAC[VECTOR_MUL_EQ_0; VECTOR_SUB_LDISTRIB; VECTOR_SUB_EQ]);; + +let VECTOR_MUL_RCANCEL = prove + (`!a b x. (a % x = b % x) <=> (a = b) \/ (x = vec 0)`, + MESON_TAC[VECTOR_MUL_EQ_0; VECTOR_SUB_RDISTRIB; REAL_SUB_0; VECTOR_SUB_EQ]);; + +let VECTOR_MUL_LCANCEL_IMP = prove + (`!a x y. ~(a = &0) /\ (a % x = a % y) ==> (x = y)`, + MESON_TAC[VECTOR_MUL_LCANCEL]);; + +let VECTOR_MUL_RCANCEL_IMP = prove + (`!a b x. ~(x = vec 0) /\ (a % x = b % x) ==> (a = b)`, + MESON_TAC[VECTOR_MUL_RCANCEL]);; + +let NORM_CAUCHY_SCHWARZ = prove + (`!(x:real^N) y. x dot y <= norm(x) * norm(y)`, + REPEAT STRIP_TAC THEN MAP_EVERY ASM_CASES_TAC + [`norm(x:real^N) = &0`; `norm(y:real^N) = &0`] THEN + ASM_SIMP_TAC[NORM_EQ_0_IMP; DOT_LZERO; DOT_RZERO; + REAL_MUL_LZERO; REAL_MUL_RZERO] THEN + MP_TAC(ISPEC `norm(y:real^N) % x - norm(x:real^N) % y` DOT_POS_LE) THEN + REWRITE_TAC[DOT_RSUB; DOT_LSUB; DOT_LMUL; DOT_RMUL; GSYM NORM_POW_2; + REAL_POW_2; REAL_LE_REFL] THEN + REWRITE_TAC[DOT_SYM; REAL_ARITH + `&0 <= y * (y * x * x - x * d) - x * (y * d - x * y * y) <=> + x * y * d <= x * y * x * y`] THEN + ASM_SIMP_TAC[REAL_LE_LMUL_EQ; REAL_LT_LE; NORM_POS_LE]);; + +let NORM_CAUCHY_SCHWARZ_ABS = prove + (`!x:real^N y. abs(x dot y) <= norm(x) * norm(y)`, + REPEAT GEN_TAC THEN MP_TAC(ISPEC `x:real^N` NORM_CAUCHY_SCHWARZ) THEN + DISCH_THEN(fun th -> MP_TAC(SPEC `y:real^N` th) THEN + MP_TAC(SPEC `--(y:real^N)` th)) THEN + REWRITE_TAC[DOT_RNEG; NORM_NEG] THEN REAL_ARITH_TAC);; + +let REAL_ABS_NORM = prove + (`!x. abs(norm x) = norm x`, + REWRITE_TAC[NORM_POS_LE; REAL_ABS_REFL]);; + +let NORM_CAUCHY_SCHWARZ_DIV = prove + (`!x:real^N y. abs((x dot y) / (norm x * norm y)) <= &1`, + REPEAT GEN_TAC THEN + MAP_EVERY ASM_CASES_TAC [`x:real^N = vec 0`; `y:real^N = vec 0`] THEN + ASM_REWRITE_TAC[NORM_0; REAL_MUL_LZERO; REAL_MUL_RZERO; real_div; + REAL_INV_1; DOT_LZERO; DOT_RZERO; REAL_ABS_NUM; REAL_POS] THEN + ASM_SIMP_TAC[GSYM real_div; REAL_ABS_DIV; REAL_LE_LDIV_EQ; REAL_LT_MUL; + REAL_ABS_INV; NORM_POS_LT; REAL_ABS_MUL; REAL_ABS_NORM] THEN + REWRITE_TAC[REAL_MUL_LID; NORM_CAUCHY_SCHWARZ_ABS]);; + +let NORM_TRIANGLE = prove + (`!x y. norm(x + y) <= norm(x) + norm(y)`, + REPEAT GEN_TAC THEN REWRITE_TAC[vector_norm] THEN + MATCH_MP_TAC REAL_LE_LSQRT THEN + SIMP_TAC[GSYM vector_norm; DOT_POS_LE; NORM_POS_LE; REAL_LE_ADD] THEN + REWRITE_TAC[DOT_LADD; DOT_RADD; REAL_POW_2; GSYM NORM_POW_2] THEN + SIMP_TAC[NORM_CAUCHY_SCHWARZ; DOT_SYM; REAL_ARITH + `d <= x * y ==> (x * x + d) + (d + y * y) <= (x + y) * (x + y)`]);; + +let NORM_TRIANGLE_SUB = prove + (`!x y:real^N. norm(x) <= norm(y) + norm(x - y)`, + MESON_TAC[NORM_TRIANGLE; VECTOR_SUB_ADD2]);; + +let NORM_TRIANGLE_LE = prove + (`!x y. norm(x) + norm(y) <= e ==> norm(x + y) <= e`, + MESON_TAC[REAL_LE_TRANS; NORM_TRIANGLE]);; + +let NORM_TRIANGLE_LT = prove + (`!x y. norm(x) + norm(y) < e ==> norm(x + y) < e`, + MESON_TAC[REAL_LET_TRANS; NORM_TRIANGLE]);; + +let COMPONENT_LE_NORM = prove + (`!x:real^N i. 1 <= i /\ i <= dimindex(:N) + ==> abs(x$i) <= norm x`, + REPEAT STRIP_TAC THEN REWRITE_TAC[vector_norm] THEN + MATCH_MP_TAC REAL_LE_RSQRT THEN REWRITE_TAC[GSYM REAL_ABS_POW] THEN + REWRITE_TAC[real_abs; REAL_POW_2; REAL_LE_SQUARE] THEN + SUBGOAL_THEN + `x$i * (x:real^N)$i = + sum(1..dimindex(:N)) (\k. if k = i then x$i * x$i else &0)` + SUBST1_TAC THENL + [REWRITE_TAC[SUM_DELTA] THEN ASM_REWRITE_TAC[IN_NUMSEG]; ALL_TAC] THEN + REWRITE_TAC[dot] THEN MATCH_MP_TAC SUM_LE THEN + REWRITE_TAC[FINITE_NUMSEG] THEN + REPEAT STRIP_TAC THEN COND_CASES_TAC THEN + ASM_REWRITE_TAC[REAL_LE_REFL; REAL_LE_SQUARE]);; + +let NORM_BOUND_COMPONENT_LE = prove + (`!x:real^N e. norm(x) <= e + ==> !i. 1 <= i /\ i <= dimindex(:N) ==> abs(x$i) <= e`, + MESON_TAC[COMPONENT_LE_NORM; REAL_LE_TRANS]);; + +let NORM_BOUND_COMPONENT_LT = prove + (`!x:real^N e. norm(x) < e + ==> !i. 1 <= i /\ i <= dimindex(:N) ==> abs(x$i) < e`, + MESON_TAC[COMPONENT_LE_NORM; REAL_LET_TRANS]);; + +let NORM_LE_L1 = prove + (`!x:real^N. norm x <= sum(1..dimindex(:N)) (\i. abs(x$i))`, + REPEAT GEN_TAC THEN REWRITE_TAC[vector_norm; dot] THEN + MATCH_MP_TAC REAL_LE_LSQRT THEN REWRITE_TAC[REAL_POW_2] THEN + SIMP_TAC[SUM_POS_LE; FINITE_NUMSEG; REAL_LE_SQUARE; REAL_ABS_POS] THEN + SPEC_TAC(`dimindex(:N)`,`n:num`) THEN INDUCT_TAC THEN + REWRITE_TAC[SUM_CLAUSES_NUMSEG; ARITH_EQ; ARITH_RULE `1 <= SUC n`] THEN + SIMP_TAC[REAL_MUL_LZERO; REAL_LE_REFL] THEN + MATCH_MP_TAC(REAL_ARITH + `a2 <= a * a /\ &0 <= a * b /\ b2 <= b * b + ==> a2 + b2 <= (a + b) * (a + b)`) THEN + ASM_SIMP_TAC[SUM_POS_LE; REAL_LE_MUL; REAL_ABS_POS; FINITE_NUMSEG] THEN + REWRITE_TAC[GSYM REAL_ABS_MUL] THEN REAL_ARITH_TAC);; + +let REAL_ABS_SUB_NORM = prove + (`abs(norm(x) - norm(y)) <= norm(x - y)`, + REWRITE_TAC[REAL_ARITH `abs(x - y) <= a <=> x <= y + a /\ y <= x + a`] THEN + MESON_TAC[NORM_TRIANGLE_SUB; NORM_SUB]);; + +let NORM_LE = prove + (`!x y. norm(x) <= norm(y) <=> x dot x <= y dot y`, + REWRITE_TAC[vector_norm] THEN MESON_TAC[SQRT_MONO_LE_EQ; DOT_POS_LE]);; + +let NORM_LT = prove + (`!x y. norm(x) < norm(y) <=> x dot x < y dot y`, + REWRITE_TAC[vector_norm] THEN MESON_TAC[SQRT_MONO_LT_EQ; DOT_POS_LE]);; + +let NORM_EQ = prove + (`!x y. (norm x = norm y) <=> (x dot x = y dot y)`, + REWRITE_TAC[GSYM REAL_LE_ANTISYM; NORM_LE]);; + +let NORM_EQ_1 = prove + (`!x. norm(x) = &1 <=> x dot x = &1`, + GEN_TAC THEN GEN_REWRITE_TAC (LAND_CONV o RAND_CONV) [GSYM SQRT_1] THEN + SIMP_TAC[vector_norm; SQRT_INJ; DOT_POS_LE; REAL_POS]);; + +let NORM_LE_COMPONENTWISE = prove + (`!x:real^N y:real^N. + (!i. 1 <= i /\ i <= dimindex(:N) ==> abs(x$i) <= abs(y$i)) + ==> norm(x) <= norm(y)`, + REPEAT STRIP_TAC THEN REWRITE_TAC[NORM_LE; dot] THEN + MATCH_MP_TAC SUM_LE_NUMSEG THEN + ASM_SIMP_TAC[GSYM REAL_POW_2; GSYM REAL_LE_SQUARE_ABS]);; + +let L1_LE_NORM = prove + (`!x:real^N. + sum(1..dimindex(:N)) (\i. abs(x$i)) <= sqrt(&(dimindex(:N))) * norm x`, + let lemma = prove + (`!x n. &n * sum(1..n) (\i. x i pow 2) - (sum(1..n) x) pow 2 = + sum(1..n) (\i. sum(i+1..n) (\j. (x i - x j) pow 2))`, + GEN_TAC THEN CONV_TAC(BINDER_CONV SYM_CONV) THEN INDUCT_TAC THEN + REWRITE_TAC[SUM_CLAUSES_NUMSEG; ARITH; ARITH_RULE `1 <= SUC n`] THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN + SIMP_TAC[ARITH_RULE `i <= n ==> i + 1 <= SUC n`; SUM_TRIV_NUMSEG; + ARITH_RULE `~(n + 1 <= n)`; ARITH_RULE `n < SUC n + 1`] THEN + ASM_REWRITE_TAC[SUM_ADD_NUMSEG; REAL_ADD_RID] THEN + REWRITE_TAC[REAL_ARITH + `(x - y) pow 2 = (x pow 2 + y pow 2) - &2 * x * y`] THEN + REWRITE_TAC[SUM_ADD_NUMSEG; SUM_SUB_NUMSEG; SUM_LMUL; SUM_RMUL; + GSYM REAL_OF_NUM_SUC; SUM_CONST_NUMSEG; ADD_SUB] THEN + REAL_ARITH_TAC) in + GEN_TAC THEN + MATCH_MP_TAC(REAL_ARITH `&0 <= y /\ abs x <= abs y ==> x <= y`) THEN + SIMP_TAC[REAL_LE_MUL; NORM_POS_LE; SQRT_POS_LE; REAL_POS] THEN + REWRITE_TAC[REAL_LE_SQUARE_ABS; REAL_POW_MUL] THEN + SIMP_TAC[SQRT_POW_2; REAL_POS; NORM_POW_2; dot] THEN + REWRITE_TAC[GSYM REAL_POW_2] THEN + GEN_REWRITE_TAC (RAND_CONV o ONCE_DEPTH_CONV) [GSYM REAL_POW2_ABS] THEN + ONCE_REWRITE_TAC[GSYM REAL_SUB_LE] THEN REWRITE_TAC[lemma] THEN + SIMP_TAC[SUM_POS_LE_NUMSEG; REAL_LE_POW_2]);; + +(* ------------------------------------------------------------------------- *) +(* Squaring equations and inequalities involving norms. *) +(* ------------------------------------------------------------------------- *) + +let DOT_SQUARE_NORM = prove + (`!x. x dot x = norm(x) pow 2`, + SIMP_TAC[vector_norm; SQRT_POW_2; DOT_POS_LE]);; + +let NORM_EQ_SQUARE = prove + (`!x:real^N. norm(x) = a <=> &0 <= a /\ x dot x = a pow 2`, + REWRITE_TAC[DOT_SQUARE_NORM] THEN + ONCE_REWRITE_TAC[REAL_RING `x pow 2 = a pow 2 <=> x = a \/ x + a = &0`] THEN + GEN_TAC THEN MP_TAC(ISPEC `x:real^N` NORM_POS_LE) THEN REAL_ARITH_TAC);; + +let NORM_LE_SQUARE = prove + (`!x:real^N. norm(x) <= a <=> &0 <= a /\ x dot x <= a pow 2`, + REWRITE_TAC[DOT_SQUARE_NORM; GSYM REAL_LE_SQUARE_ABS] THEN + GEN_TAC THEN MP_TAC(ISPEC `x:real^N` NORM_POS_LE) THEN REAL_ARITH_TAC);; + +let NORM_GE_SQUARE = prove + (`!x:real^N. norm(x) >= a <=> a <= &0 \/ x dot x >= a pow 2`, + REWRITE_TAC[real_ge; DOT_SQUARE_NORM; GSYM REAL_LE_SQUARE_ABS] THEN + GEN_TAC THEN MP_TAC(ISPEC `x:real^N` NORM_POS_LE) THEN REAL_ARITH_TAC);; + +let NORM_LT_SQUARE = prove + (`!x:real^N. norm(x) < a <=> &0 < a /\ x dot x < a pow 2`, + REWRITE_TAC[REAL_ARITH `x < a <=> ~(x >= a)`; NORM_GE_SQUARE] THEN + REAL_ARITH_TAC);; + +let NORM_GT_SQUARE = prove + (`!x:real^N. norm(x) > a <=> a < &0 \/ x dot x > a pow 2`, + REWRITE_TAC[REAL_ARITH `x > a <=> ~(x <= a)`; NORM_LE_SQUARE] THEN + REAL_ARITH_TAC);; + +let NORM_LT_SQUARE_ALT = prove + (`!x:real^N. norm(x) < a <=> &0 <= a /\ x dot x < a pow 2`, + REWRITE_TAC[REAL_ARITH `x < a <=> ~(x >= a)`; NORM_GE_SQUARE] THEN + REPEAT GEN_TAC THEN ASM_CASES_TAC `a = &0` THENL + [ASM_REWRITE_TAC[real_ge] THEN CONV_TAC REAL_RAT_REDUCE_CONV THEN + REWRITE_TAC[DOT_POS_LE]; + ASM_REAL_ARITH_TAC]);; + +(* ------------------------------------------------------------------------- *) +(* General linear decision procedure for normed spaces. *) +(* ------------------------------------------------------------------------- *) + +let NORM_ARITH = + let find_normedterms = + let augment_norm b tm acc = + match tm with + Comb(Const("vector_norm",_),v) -> insert (b,v) acc + | _ -> acc in + let rec find_normedterms tm acc = + match tm with + Comb(Comb(Const("real_add",_),l),r) -> + find_normedterms l (find_normedterms r acc) + | Comb(Comb(Const("real_mul",_),c),n) -> + if not (is_ratconst c) then acc else + augment_norm (rat_of_term c >=/ Int 0) n acc + | _ -> augment_norm true tm acc in + find_normedterms in + let lincomb_neg t = mapf minus_num t in + let lincomb_cmul c t = if c =/ Int 0 then undefined else mapf (( */ ) c) t in + let lincomb_add l r = combine (+/) (fun x -> x =/ Int 0) l r in + let lincomb_sub l r = lincomb_add l (lincomb_neg r) in + let lincomb_eq l r = lincomb_sub l r = undefined in + let rec vector_lincomb tm = + match tm with + Comb(Comb(Const("vector_add",_),l),r) -> + lincomb_add (vector_lincomb l) (vector_lincomb r) + | Comb(Comb(Const("vector_sub",_),l),r) -> + lincomb_sub (vector_lincomb l) (vector_lincomb r) + | Comb(Comb(Const("%",_),l),r) -> + lincomb_cmul (rat_of_term l) (vector_lincomb r) + | Comb(Const("vector_neg",_),t) -> + lincomb_neg (vector_lincomb t) + | Comb(Const("vec",_),n) when is_numeral n & dest_numeral n =/ Int 0 -> + undefined + | _ -> (tm |=> Int 1) in + let vector_lincombs tms = + itlist (fun t fns -> + if can (assoc t) fns then fns else + let f = vector_lincomb t in + try let _,f' = find (fun (_,f') -> lincomb_eq f f') fns in + (t,f')::fns + with Failure _ -> (t,f)::fns) tms [] in + let rec replacenegnorms fn tm = + match tm with + Comb(Comb(Const("real_add",_),l),r) -> + BINOP_CONV (replacenegnorms fn) tm + | Comb(Comb(Const("real_mul",_),c),n) when rat_of_term c + RAND_CONV fn tm + | _ -> REFL tm in + let flip v eq = + if defined eq v then (v |-> minus_num(apply eq v)) eq else eq in + let rec allsubsets s = + match s with + [] -> [[]] + | (a::t) -> let res = allsubsets t in + map (fun b -> a::b) res @ res in + let evaluate env lin = + foldr (fun x c s -> s +/ c */ apply env x) lin (Int 0) in + let rec solve (vs,eqs) = + match (vs,eqs) with + [],[] -> (0 |=> Int 1) + | _,eq::oeqs -> + let v = hd(intersect vs (dom eq)) in + let c = apply eq v in + let vdef = lincomb_cmul (Int(-1) // c) eq in + let eliminate eqn = + if not(defined eqn v) then eqn else + lincomb_add (lincomb_cmul (apply eqn v) vdef) eqn in + let soln = solve (subtract vs [v],map eliminate oeqs) in + (v |-> evaluate soln (undefine v vdef)) soln in + let rec combinations k l = + if k = 0 then [[]] else + match l with + [] -> [] + | h::t -> map (fun c -> h::c) (combinations (k - 1) t) @ + combinations k t in + let vertices vs eqs = + let vertex cmb = + let soln = solve(vs,cmb) in + map (fun v -> tryapplyd soln v (Int 0)) vs in + let rawvs = mapfilter vertex (combinations (length vs) eqs) in + let unset = filter (forall (fun c -> c >=/ Int 0)) rawvs in + itlist (insert' (forall2 (=/))) unset [] in + let subsumes l m = forall2 (fun x y -> abs_num x <=/ abs_num y) l m in + let rec subsume todo dun = + match todo with + [] -> dun + | v::ovs -> let dun' = if exists (fun w -> subsumes w v) dun then dun + else v::(filter (fun w -> not(subsumes v w)) dun) in + subsume ovs dun' in + let NORM_CMUL_RULE = + let MATCH_pth = (MATCH_MP o prove) + (`!b x. b >= norm(x) ==> !c. abs(c) * b >= norm(c % x)`, + SIMP_TAC[NORM_MUL; real_ge; REAL_LE_LMUL; REAL_ABS_POS]) in + fun c th -> ISPEC(term_of_rat c) (MATCH_pth th) in + let NORM_ADD_RULE = + let MATCH_pth = (MATCH_MP o prove) + (`!b1 b2 x1 x2. b1 >= norm(x1) /\ b2 >= norm(x2) + ==> b1 + b2 >= norm(x1 + x2)`, + REWRITE_TAC[real_ge] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC NORM_TRIANGLE_LE THEN ASM_SIMP_TAC[REAL_LE_ADD2]) in + fun th1 th2 -> MATCH_pth (CONJ th1 th2) in + let INEQUALITY_CANON_RULE = + CONV_RULE(LAND_CONV REAL_POLY_CONV) o + CONV_RULE(LAND_CONV REAL_RAT_REDUCE_CONV) o + GEN_REWRITE_RULE I [REAL_ARITH `s >= t <=> s - t >= &0`] in + let NORM_CANON_CONV = + let APPLY_pth1 = GEN_REWRITE_CONV I + [VECTOR_ARITH `x:real^N = &1 % x`] + and APPLY_pth2 = GEN_REWRITE_CONV I + [VECTOR_ARITH `x - y:real^N = x + --y`] + and APPLY_pth3 = GEN_REWRITE_CONV I + [VECTOR_ARITH `--x:real^N = -- &1 % x`] + and APPLY_pth4 = GEN_REWRITE_CONV I + [VECTOR_ARITH `&0 % x:real^N = vec 0`; + VECTOR_ARITH `c % vec 0:real^N = vec 0`] + and APPLY_pth5 = GEN_REWRITE_CONV I + [VECTOR_ARITH `c % (d % x) = (c * d) % x`] + and APPLY_pth6 = GEN_REWRITE_CONV I + [VECTOR_ARITH `c % (x + y) = c % x + c % y`] + and APPLY_pth7 = GEN_REWRITE_CONV I + [VECTOR_ARITH `vec 0 + x = x`; + VECTOR_ARITH `x + vec 0 = x`] + and APPLY_pth8 = + GEN_REWRITE_CONV I [VECTOR_ARITH `c % x + d % x = (c + d) % x`] THENC + LAND_CONV REAL_RAT_ADD_CONV THENC + GEN_REWRITE_CONV TRY_CONV [VECTOR_ARITH `&0 % x = vec 0`] + and APPLY_pth9 = + GEN_REWRITE_CONV I + [VECTOR_ARITH `(c % x + z) + d % x = (c + d) % x + z`; + VECTOR_ARITH `c % x + (d % x + z) = (c + d) % x + z`; + VECTOR_ARITH `(c % x + w) + (d % x + z) = (c + d) % x + (w + z)`] THENC + LAND_CONV(LAND_CONV REAL_RAT_ADD_CONV) + and APPLY_ptha = + GEN_REWRITE_CONV I [VECTOR_ARITH `&0 % x + y = y`] + and APPLY_pthb = + GEN_REWRITE_CONV I + [VECTOR_ARITH `c % x + d % y = c % x + d % y`; + VECTOR_ARITH `(c % x + z) + d % y = c % x + (z + d % y)`; + VECTOR_ARITH `c % x + (d % y + z) = c % x + (d % y + z)`; + VECTOR_ARITH `(c % x + w) + (d % y + z) = c % x + (w + (d % y + z))`] + and APPLY_pthc = + GEN_REWRITE_CONV I + [VECTOR_ARITH `c % x + d % y = d % y + c % x`; + VECTOR_ARITH `(c % x + z) + d % y = d % y + (c % x + z)`; + VECTOR_ARITH `c % x + (d % y + z) = d % y + (c % x + z)`; + VECTOR_ARITH `(c % x + w) + (d % y + z) = d % y + ((c % x + w) + z)`] + and APPLY_pthd = + GEN_REWRITE_CONV TRY_CONV + [VECTOR_ARITH `x + vec 0 = x`] in + let headvector tm = + match tm with + Comb(Comb(Const("vector_add",_),Comb(Comb(Const("%",_),l),v)),r) -> v + | Comb(Comb(Const("%",_),l),v) -> v + | _ -> failwith "headvector: non-canonical term" in + let rec VECTOR_CMUL_CONV tm = + ((APPLY_pth5 THENC LAND_CONV REAL_RAT_MUL_CONV) ORELSEC + (APPLY_pth6 THENC BINOP_CONV VECTOR_CMUL_CONV)) tm + and VECTOR_ADD_CONV tm = + try APPLY_pth7 tm with Failure _ -> + try APPLY_pth8 tm with Failure _ -> + match tm with + Comb(Comb(Const("vector_add",_),lt),rt) -> + let l = headvector lt and r = headvector rt in + if l < r then (APPLY_pthb THENC + RAND_CONV VECTOR_ADD_CONV THENC + APPLY_pthd) tm + else if r < l then (APPLY_pthc THENC + RAND_CONV VECTOR_ADD_CONV THENC + APPLY_pthd) tm else + (APPLY_pth9 THENC + ((APPLY_ptha THENC VECTOR_ADD_CONV) ORELSEC + RAND_CONV VECTOR_ADD_CONV THENC + APPLY_pthd)) tm + | _ -> REFL tm in + let rec VECTOR_CANON_CONV tm = + match tm with + Comb(Comb(Const("vector_add",_),l),r) -> + let lth = VECTOR_CANON_CONV l and rth = VECTOR_CANON_CONV r in + let th = MK_COMB(AP_TERM (rator(rator tm)) lth,rth) in + CONV_RULE (RAND_CONV VECTOR_ADD_CONV) th + | Comb(Comb(Const("%",_),l),r) -> + let rth = AP_TERM (rator tm) (VECTOR_CANON_CONV r) in + CONV_RULE (RAND_CONV(APPLY_pth4 ORELSEC VECTOR_CMUL_CONV)) rth + | Comb(Comb(Const("vector_sub",_),l),r) -> + (APPLY_pth2 THENC VECTOR_CANON_CONV) tm + | Comb(Const("vector_neg",_),t) -> + (APPLY_pth3 THENC VECTOR_CANON_CONV) tm + | Comb(Const("vec",_),n) when is_numeral n & dest_numeral n =/ Int 0 -> + REFL tm + | _ -> APPLY_pth1 tm in + fun tm -> + match tm with + Comb(Const("vector_norm",_),e) -> RAND_CONV VECTOR_CANON_CONV tm + | _ -> failwith "NORM_CANON_CONV" in + let REAL_VECTOR_COMBO_PROVER = + let pth_zero = prove(`norm(vec 0:real^N) = &0`,REWRITE_TAC[NORM_0]) + and tv_n = mk_vartype "N" in + fun translator (nubs,ges,gts) -> + let sources = map (rand o rand o concl) nubs + and rawdests = itlist (find_normedterms o lhand o concl) (ges @ gts) [] in + if not (forall fst rawdests) then failwith "Sanity check" else + let dests = setify (map snd rawdests) in + let srcfuns = map vector_lincomb sources + and destfuns = map vector_lincomb dests in + let vvs = itlist (union o dom) (srcfuns @ destfuns) [] in + let n = length srcfuns in + let nvs = 1--n in + let srccombs = zip srcfuns nvs in + let consider d = + let coefficients x = + let inp = if defined d x then 0 |=> minus_num(apply d x) + else undefined in + itlist (fun (f,v) g -> if defined f x then (v |-> apply f x) g else g) + srccombs inp in + let equations = map coefficients vvs + and inequalities = map (fun n -> (n |=> Int 1)) nvs in + let plausiblevertices f = + let flippedequations = map (itlist flip f) equations in + let constraints = flippedequations @ inequalities in + let rawverts = vertices nvs constraints in + let check_solution v = + let f = itlist2 (|->) nvs v (0 |=> Int 1) in + forall (fun e -> evaluate f e =/ Int 0) flippedequations in + let goodverts = filter check_solution rawverts in + let signfixups = map (fun n -> if mem n f then -1 else 1) nvs in + map (map2 (fun s c -> Int s */ c) signfixups) goodverts in + let allverts = itlist (@) (map plausiblevertices (allsubsets nvs)) [] in + subsume allverts [] in + let compute_ineq v = + let ths = mapfilter (fun (v,t) -> if v =/ Int 0 then fail() + else NORM_CMUL_RULE v t) + (zip v nubs) in + INEQUALITY_CANON_RULE (end_itlist NORM_ADD_RULE ths) in + let ges' = mapfilter compute_ineq (itlist ((@) o consider) destfuns []) @ + map INEQUALITY_CANON_RULE nubs @ ges in + let zerodests = filter + (fun t -> dom(vector_lincomb t) = []) (map snd rawdests) in + REAL_LINEAR_PROVER translator + (map (fun t -> INST_TYPE [last(snd(dest_type(type_of t))),tv_n] pth_zero) + zerodests, + map (CONV_RULE(ONCE_DEPTH_CONV NORM_CANON_CONV THENC + LAND_CONV REAL_POLY_CONV)) ges', + map (CONV_RULE(ONCE_DEPTH_CONV NORM_CANON_CONV THENC + LAND_CONV REAL_POLY_CONV)) gts) in + let REAL_VECTOR_INEQ_PROVER = + let pth = prove + (`norm(x) = n ==> norm(x) >= &0 /\ n >= norm(x)`, + DISCH_THEN(SUBST_ALL_TAC o SYM) THEN + REWRITE_TAC[real_ge; NORM_POS_LE] THEN REAL_ARITH_TAC) in + let NORM_MP = MATCH_MP pth in + fun translator (ges,gts) -> + let ntms = itlist find_normedterms (map (lhand o concl) (ges @ gts)) [] in + let lctab = vector_lincombs (map snd (filter (not o fst) ntms)) in + let asl = map (fun (t,_) -> + ASSUME(mk_eq(mk_icomb(mk_const("vector_norm",[]),t), + genvar `:real`))) lctab in + let replace_conv = GEN_REWRITE_CONV TRY_CONV asl in + let replace_rule = CONV_RULE (LAND_CONV (replacenegnorms replace_conv)) in + let ges' = + itlist (fun th ths -> CONJUNCT1(NORM_MP th)::ths) + asl (map replace_rule ges) + and gts' = map replace_rule gts + and nubs = map (CONJUNCT2 o NORM_MP) asl in + let th1 = REAL_VECTOR_COMBO_PROVER translator (nubs,ges',gts') in + let th2 = INST + (map (fun th -> let l,r = dest_eq(concl th) in (l,r)) asl) th1 in + itlist PROVE_HYP (map (REFL o lhand o concl) asl) th2 in + let REAL_VECTOR_PROVER = + let rawrule = + GEN_REWRITE_RULE I [REAL_ARITH `x = &0 <=> x >= &0 /\ --x >= &0`] in + let splitequation th acc = + let th1,th2 = CONJ_PAIR(rawrule th) in + th1::CONV_RULE(LAND_CONV REAL_POLY_NEG_CONV) th2::acc in + fun translator (eqs,ges,gts) -> + REAL_VECTOR_INEQ_PROVER translator + (itlist splitequation eqs ges,gts) in + let pth = prove + (`(!x y:real^N. x = y <=> norm(x - y) <= &0) /\ + (!x y:real^N. ~(x = y) <=> ~(norm(x - y) <= &0))`, + REWRITE_TAC[NORM_LE_0; VECTOR_SUB_EQ]) in + let conv1 = GEN_REWRITE_CONV TRY_CONV [pth] in + let conv2 tm = (conv1 tm,conv1(mk_neg tm)) in + let init = GEN_REWRITE_CONV ONCE_DEPTH_CONV [DECIMAL] THENC + REAL_RAT_REDUCE_CONV THENC + GEN_REWRITE_CONV ONCE_DEPTH_CONV [dist] THENC + GEN_NNF_CONV true (conv1,conv2) + and pure = GEN_REAL_ARITH REAL_VECTOR_PROVER in + fun tm -> let th = init tm in EQ_MP (SYM th) (pure(rand(concl th)));; + +let NORM_ARITH_TAC = CONV_TAC NORM_ARITH;; + +let ASM_NORM_ARITH_TAC = + REPEAT(FIRST_X_ASSUM(MP_TAC o check (not o is_forall o concl))) THEN + NORM_ARITH_TAC;; + +(* ------------------------------------------------------------------------- *) +(* Dot product in terms of the norm rather than conversely. *) +(* ------------------------------------------------------------------------- *) + +let DOT_NORM = prove + (`!x y. x dot y = (norm(x + y) pow 2 - norm(x) pow 2 - norm(y) pow 2) / &2`, + REWRITE_TAC[NORM_POW_2; DOT_LADD; DOT_RADD; DOT_SYM] THEN REAL_ARITH_TAC);; + +let DOT_NORM_NEG = prove + (`!x y. x dot y = ((norm(x) pow 2 + norm(y) pow 2) - norm(x - y) pow 2) / &2`, + REWRITE_TAC[NORM_POW_2; DOT_LADD; DOT_RADD; DOT_LSUB; DOT_RSUB; DOT_SYM] THEN + REAL_ARITH_TAC);; + +let DOT_NORM_SUB = prove + (`!x y. x dot y = ((norm(x) pow 2 + norm(y) pow 2) - norm(x - y) pow 2) / &2`, + REWRITE_TAC[NORM_POW_2; DOT_LSUB; DOT_RSUB; DOT_SYM] THEN REAL_ARITH_TAC);; + +(* ------------------------------------------------------------------------- *) +(* Equality of vectors in terms of dot products. *) +(* ------------------------------------------------------------------------- *) + +let VECTOR_EQ = prove + (`!x y. (x = y) <=> (x dot x = x dot y) /\ (y dot y = x dot x)`, + REPEAT GEN_TAC THEN EQ_TAC THENL [SIMP_TAC[]; ALL_TAC] THEN + ONCE_REWRITE_TAC[GSYM VECTOR_SUB_EQ] THEN + REWRITE_TAC[GSYM DOT_EQ_0] THEN + SIMP_TAC[DOT_LSUB; DOT_RSUB; DOT_SYM] THEN REAL_ARITH_TAC);; + +(* ------------------------------------------------------------------------- *) +(* Hence more metric properties. *) +(* ------------------------------------------------------------------------- *) + +let DIST_REFL = prove + (`!x. dist(x,x) = &0`, + NORM_ARITH_TAC);; + +let DIST_SYM = prove + (`!x y. dist(x,y) = dist(y,x)`, + NORM_ARITH_TAC);; + +let DIST_POS_LE = prove + (`!x y. &0 <= dist(x,y)`, + NORM_ARITH_TAC);; + +let DIST_TRIANGLE = prove + (`!x:real^N y z. dist(x,z) <= dist(x,y) + dist(y,z)`, + NORM_ARITH_TAC);; + +let DIST_TRIANGLE_ALT = prove + (`!x y z. dist(y,z) <= dist(x,y) + dist(x,z)`, + NORM_ARITH_TAC);; + +let DIST_EQ_0 = prove + (`!x y. (dist(x,y) = &0) <=> (x = y)`, + NORM_ARITH_TAC);; + +let DIST_POS_LT = prove + (`!x y. ~(x = y) ==> &0 < dist(x,y)`, + NORM_ARITH_TAC);; + +let DIST_NZ = prove + (`!x y. ~(x = y) <=> &0 < dist(x,y)`, + NORM_ARITH_TAC);; + +let DIST_TRIANGLE_LE = prove + (`!x y z e. dist(x,z) + dist(y,z) <= e ==> dist(x,y) <= e`, + NORM_ARITH_TAC);; + +let DIST_TRIANGLE_LT = prove + (`!x y z e. dist(x,z) + dist(y,z) < e ==> dist(x,y) < e`, + NORM_ARITH_TAC);; + +let DIST_TRIANGLE_HALF_L = prove + (`!x1 x2 y. dist(x1,y) < e / &2 /\ dist(x2,y) < e / &2 ==> dist(x1,x2) < e`, + NORM_ARITH_TAC);; + +let DIST_TRIANGLE_HALF_R = prove + (`!x1 x2 y. dist(y,x1) < e / &2 /\ dist(y,x2) < e / &2 ==> dist(x1,x2) < e`, + NORM_ARITH_TAC);; + +let DIST_TRIANGLE_ADD = prove + (`!x x' y y'. dist(x + y,x' + y') <= dist(x,x') + dist(y,y')`, + NORM_ARITH_TAC);; + +let DIST_MUL = prove + (`!x y c. dist(c % x,c % y) = abs(c) * dist(x,y)`, + REWRITE_TAC[dist; GSYM VECTOR_SUB_LDISTRIB; NORM_MUL]);; + +let DIST_TRIANGLE_ADD_HALF = prove + (`!x x' y y':real^N. + dist(x,x') < e / &2 /\ dist(y,y') < e / &2 ==> dist(x + y,x' + y') < e`, + NORM_ARITH_TAC);; + +let DIST_LE_0 = prove + (`!x y. dist(x,y) <= &0 <=> x = y`, + NORM_ARITH_TAC);; + +let DIST_EQ = prove + (`!w x y z. dist(w,x) = dist(y,z) <=> dist(w,x) pow 2 = dist(y,z) pow 2`, + REWRITE_TAC[dist; NORM_POW_2; NORM_EQ]);; + +let DIST_0 = prove + (`!x. dist(x,vec 0) = norm(x) /\ dist(vec 0,x) = norm(x)`, + NORM_ARITH_TAC);; + +(* ------------------------------------------------------------------------- *) +(* Sums of vectors. *) +(* ------------------------------------------------------------------------- *) + +let NEUTRAL_VECTOR_ADD = prove + (`neutral(+) = vec 0:real^N`, + REWRITE_TAC[neutral] THEN MATCH_MP_TAC SELECT_UNIQUE THEN + REWRITE_TAC[VECTOR_ARITH `x + y = y <=> x = vec 0`; + VECTOR_ARITH `x + y = x <=> y = vec 0`]);; + +let MONOIDAL_VECTOR_ADD = prove + (`monoidal((+):real^N->real^N->real^N)`, + REWRITE_TAC[monoidal; NEUTRAL_VECTOR_ADD] THEN + REPEAT CONJ_TAC THEN VECTOR_ARITH_TAC);; + +let vsum = new_definition + `(vsum:(A->bool)->(A->real^N)->real^N) s f = lambda i. sum s (\x. f(x)$i)`;; + +let VSUM_CLAUSES = prove + (`(!f. vsum {} f = vec 0) /\ + (!x f s. FINITE s + ==> (vsum (x INSERT s) f = + if x IN s then vsum s f else f(x) + vsum s f))`, + SIMP_TAC[vsum; CART_EQ; LAMBDA_BETA; VECTOR_ADD_COMPONENT; SUM_CLAUSES] THEN + SIMP_TAC[VEC_COMPONENT] THEN REPEAT STRIP_TAC THEN + COND_CASES_TAC THEN ASM_SIMP_TAC[LAMBDA_BETA; VECTOR_ADD_COMPONENT]);; + +let VSUM = prove + (`!f s. FINITE s ==> vsum s f = iterate (+) s f`, + GEN_TAC THEN MATCH_MP_TAC FINITE_INDUCT_STRONG THEN + ASM_SIMP_TAC[VSUM_CLAUSES; ITERATE_CLAUSES; MONOIDAL_VECTOR_ADD] THEN + REWRITE_TAC[NEUTRAL_VECTOR_ADD]);; + +let VSUM_EQ_0 = prove + (`!f s. (!x:A. x IN s ==> (f(x) = vec 0)) ==> (vsum s f = vec 0)`, + SIMP_TAC[vsum; CART_EQ; LAMBDA_BETA; vec; SUM_EQ_0]);; + +let VSUM_0 = prove + (`vsum s (\x. vec 0) = vec 0`, + SIMP_TAC[VSUM_EQ_0]);; + +let VSUM_LMUL = prove + (`!f c s. vsum s (\x. c % f(x)) = c % vsum s f`, + SIMP_TAC[vsum; CART_EQ; LAMBDA_BETA; VECTOR_MUL_COMPONENT; SUM_LMUL]);; + +let VSUM_RMUL = prove + (`!c s v. vsum s (\x. c x % v) = (sum s c) % v`, + SIMP_TAC[vsum; CART_EQ; LAMBDA_BETA; VECTOR_MUL_COMPONENT; SUM_RMUL]);; + +let VSUM_ADD = prove + (`!f g s. FINITE s ==> (vsum s (\x. f x + g x) = vsum s f + vsum s g)`, + SIMP_TAC[vsum; CART_EQ; LAMBDA_BETA; VECTOR_ADD_COMPONENT; SUM_ADD]);; + +let VSUM_SUB = prove + (`!f g s. FINITE s ==> (vsum s (\x. f x - g x) = vsum s f - vsum s g)`, + SIMP_TAC[vsum; CART_EQ; LAMBDA_BETA; VECTOR_SUB_COMPONENT; SUM_SUB]);; + +let VSUM_CONST = prove + (`!c s. FINITE s ==> (vsum s (\n. c) = &(CARD s) % c)`, + SIMP_TAC[vsum; CART_EQ; LAMBDA_BETA; SUM_CONST; VECTOR_MUL_COMPONENT]);; + +let VSUM_COMPONENT = prove + (`!s f i. 1 <= i /\ i <= dimindex(:N) + ==> ((vsum s (f:A->real^N))$i = sum s (\x. f(x)$i))`, + SIMP_TAC[vsum; LAMBDA_BETA]);; + +let VSUM_IMAGE = prove + (`!f g s. FINITE s /\ (!x y. x IN s /\ y IN s /\ (f x = f y) ==> (x = y)) + ==> (vsum (IMAGE f s) g = vsum s (g o f))`, + SIMP_TAC[vsum; CART_EQ; LAMBDA_BETA] THEN REPEAT STRIP_TAC THEN + W(MP_TAC o PART_MATCH (lhs o rand) SUM_IMAGE o lhs o snd) THEN + ASM_REWRITE_TAC[o_DEF]);; + +let VSUM_UNION = prove + (`!f s t. FINITE s /\ FINITE t /\ DISJOINT s t + ==> (vsum (s UNION t) f = vsum s f + vsum t f)`, + SIMP_TAC[vsum; CART_EQ; LAMBDA_BETA; SUM_UNION; VECTOR_ADD_COMPONENT]);; + +let VSUM_DIFF = prove + (`!f s t. FINITE s /\ t SUBSET s + ==> (vsum (s DIFF t) f = vsum s f - vsum t f)`, + SIMP_TAC[vsum; CART_EQ; LAMBDA_BETA; SUM_DIFF; VECTOR_SUB_COMPONENT]);; + +let VSUM_DELETE = prove + (`!f s a. FINITE s /\ a IN s + ==> vsum (s DELETE a) f = vsum s f - f a`, + SIMP_TAC[vsum; CART_EQ; LAMBDA_BETA; SUM_DELETE; VECTOR_SUB_COMPONENT]);; + +let VSUM_INCL_EXCL = prove + (`!s t (f:A->real^N). + FINITE s /\ FINITE t + ==> vsum s f + vsum t f = vsum (s UNION t) f + vsum (s INTER t) f`, + SIMP_TAC[vsum; CART_EQ; LAMBDA_BETA; VECTOR_ADD_COMPONENT] THEN + SIMP_TAC[SUM_INCL_EXCL]);; + +let VSUM_NEG = prove + (`!f s. vsum s (\x. --f x) = --vsum s f`, + SIMP_TAC[vsum; CART_EQ; LAMBDA_BETA; SUM_NEG; VECTOR_NEG_COMPONENT]);; + +let VSUM_EQ = prove + (`!f g s. (!x. x IN s ==> (f x = g x)) ==> (vsum s f = vsum s g)`, + SIMP_TAC[vsum; CART_EQ; LAMBDA_BETA] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC SUM_EQ THEN ASM_SIMP_TAC[]);; + +let VSUM_SUPERSET = prove + (`!f:A->real^N u v. + u SUBSET v /\ (!x. x IN v /\ ~(x IN u) ==> (f(x) = vec 0)) + ==> (vsum v f = vsum u f)`, + SIMP_TAC[vsum; CART_EQ; LAMBDA_BETA; VEC_COMPONENT; SUM_SUPERSET]);; + +let VSUM_EQ_SUPERSET = prove + (`!f s t:A->bool. + FINITE t /\ t SUBSET s /\ + (!x. x IN t ==> (f x = g x)) /\ + (!x. x IN s /\ ~(x IN t) ==> f(x) = vec 0) + ==> vsum s f = vsum t g`, + MESON_TAC[VSUM_SUPERSET; VSUM_EQ]);; + +let VSUM_UNION_RZERO = prove + (`!f:A->real^N u v. + FINITE u /\ (!x. x IN v /\ ~(x IN u) ==> (f(x) = vec 0)) + ==> (vsum (u UNION v) f = vsum u f)`, + SIMP_TAC[vsum; CART_EQ; LAMBDA_BETA; VEC_COMPONENT; SUM_UNION_RZERO]);; + +let VSUM_UNION_LZERO = prove + (`!f:A->real^N u v. + FINITE v /\ (!x. x IN u /\ ~(x IN v) ==> (f(x) = vec 0)) + ==> (vsum (u UNION v) f = vsum v f)`, + MESON_TAC[VSUM_UNION_RZERO; UNION_COMM]);; + +let VSUM_RESTRICT = prove + (`!f s. FINITE s + ==> (vsum s (\x. if x IN s then f(x) else vec 0) = vsum s f)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC VSUM_EQ THEN ASM_SIMP_TAC[]);; + +let VSUM_RESTRICT_SET = prove + (`!P s f. vsum {x | x IN s /\ P x} f = + vsum s (\x. if P x then f x else vec 0)`, + SIMP_TAC[vsum; CART_EQ; LAMBDA_BETA; VEC_COMPONENT; SUM_RESTRICT_SET; + COND_COMPONENT]);; + +let VSUM_CASES = prove + (`!s P f g. FINITE s + ==> vsum s (\x:A. if P x then (f x):real^N else g x) = + vsum {x | x IN s /\ P x} f + vsum {x | x IN s /\ ~P x} g`, + SIMP_TAC[vsum; CART_EQ; LAMBDA_BETA; VECTOR_ADD_COMPONENT; SUM_CASES; + COND_COMPONENT]);; + +let VSUM_SING = prove + (`!f x. vsum {x} f = f(x)`, + SIMP_TAC[VSUM_CLAUSES; FINITE_RULES; NOT_IN_EMPTY; VECTOR_ADD_RID]);; + +let VSUM_NORM = prove + (`!f s. FINITE s ==> norm(vsum s f) <= sum s (\x. norm(f x))`, + GEN_TAC THEN MATCH_MP_TAC FINITE_INDUCT_STRONG THEN + SIMP_TAC[SUM_CLAUSES; VSUM_CLAUSES; NORM_0; REAL_LE_REFL] THEN + NORM_ARITH_TAC);; + +let VSUM_NORM_LE = prove + (`!s f:A->real^N g. + FINITE s /\ (!x. x IN s ==> norm(f x) <= g(x)) + ==> norm(vsum s f) <= sum s g`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `sum s (\x:A. norm(f x :real^N))` THEN + ASM_SIMP_TAC[VSUM_NORM; SUM_LE]);; + +let VSUM_NORM_TRIANGLE = prove + (`!s f b. FINITE s /\ sum s (\a. norm(f a)) <= b + ==> norm(vsum s f) <= b`, + MESON_TAC[VSUM_NORM; REAL_LE_TRANS]);; + +let VSUM_NORM_BOUND = prove + (`!s f b. FINITE s /\ (!x:A. x IN s ==> norm(f(x)) <= b) + ==> norm(vsum s f) <= &(CARD s) * b`, + SIMP_TAC[GSYM SUM_CONST; VSUM_NORM_LE]);; + +let VSUM_CLAUSES_NUMSEG = prove + (`(!m. vsum(m..0) f = if m = 0 then f(0) else vec 0) /\ + (!m n. vsum(m..SUC n) f = if m <= SUC n then vsum(m..n) f + f(SUC n) + else vsum(m..n) f)`, + REWRITE_TAC[NUMSEG_CLAUSES] THEN REPEAT STRIP_TAC THEN + COND_CASES_TAC THEN + ASM_SIMP_TAC[VSUM_SING; VSUM_CLAUSES; FINITE_NUMSEG; IN_NUMSEG] THEN + REWRITE_TAC[ARITH_RULE `~(SUC n <= n)`; VECTOR_ADD_AC]);; + +let VSUM_CLAUSES_RIGHT = prove + (`!f m n. 0 < n /\ m <= n ==> vsum(m..n) f = vsum(m..n-1) f + (f n):real^N`, + GEN_TAC THEN GEN_TAC THEN INDUCT_TAC THEN + SIMP_TAC[LT_REFL; VSUM_CLAUSES_NUMSEG; SUC_SUB1]);; + +let VSUM_CMUL_NUMSEG = prove + (`!f c m n. vsum (m..n) (\x. c % f x) = c % vsum (m..n) f`, + SIMP_TAC[VSUM_LMUL; FINITE_NUMSEG]);; + +let VSUM_EQ_NUMSEG = prove + (`!f g m n. + (!x. m <= x /\ x <= n ==> (f x = g x)) + ==> (vsum(m .. n) f = vsum(m .. n) g)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC VSUM_EQ THEN + ASM_SIMP_TAC[FINITE_NUMSEG; IN_NUMSEG]);; + +let VSUM_IMAGE_GEN = prove + (`!f:A->B g s. + FINITE s + ==> (vsum s g = + vsum (IMAGE f s) (\y. vsum {x | x IN s /\ (f(x) = y)} g))`, + SIMP_TAC[vsum; CART_EQ; LAMBDA_BETA; SUM_IMAGE_GEN]);; + +let VSUM_GROUP = prove + (`!f:A->B g s t. + FINITE s /\ IMAGE f s SUBSET t + ==> vsum t (\y. vsum {x | x IN s /\ f(x) = y} g) = vsum s g`, + SIMP_TAC[vsum; CART_EQ; LAMBDA_BETA; SUM_GROUP]);; + +let VSUM_VMUL = prove + (`!f v s. FINITE s ==> ((sum s f) % v = vsum s (\x. f(x) % v))`, + GEN_TAC THEN GEN_TAC THEN MATCH_MP_TAC FINITE_INDUCT_STRONG THEN + ASM_SIMP_TAC[SUM_CLAUSES; VSUM_CLAUSES] THEN + REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[VECTOR_ADD_RDISTRIB] THEN + VECTOR_ARITH_TAC);; + +let VSUM_DELTA = prove + (`!s a. vsum s (\x. if x = a then b else vec 0) = + if a IN s then b else vec 0`, + SIMP_TAC[CART_EQ; LAMBDA_BETA; VSUM_COMPONENT; COND_COMPONENT] THEN + SIMP_TAC[VEC_COMPONENT; SUM_DELTA]);; + +let VSUM_ADD_NUMSEG = prove + (`!f g m n. vsum(m..n) (\i. f i + g i) = vsum(m..n) f + vsum(m..n) g`, + SIMP_TAC[VSUM_ADD; FINITE_NUMSEG]);; + +let VSUM_SUB_NUMSEG = prove + (`!f g m n. vsum(m..n) (\i. f i - g i) = vsum(m..n) f - vsum(m..n) g`, + SIMP_TAC[VSUM_SUB; FINITE_NUMSEG]);; + +let VSUM_ADD_SPLIT = prove + (`!f m n p. + m <= n + 1 ==> vsum(m..n + p) f = vsum(m..n) f + vsum(n + 1..n + p) f`, + SIMP_TAC[CART_EQ; LAMBDA_BETA; VSUM_COMPONENT; VECTOR_ADD_COMPONENT; + SUM_ADD_SPLIT]);; + +let VSUM_VSUM_PRODUCT = prove + (`!s:A->bool t:A->B->bool x. + FINITE s /\ (!i. i IN s ==> FINITE(t i)) + ==> vsum s (\i. vsum (t i) (x i)) = + vsum {i,j | i IN s /\ j IN t i} (\(i,j). x i j)`, + SIMP_TAC[CART_EQ; LAMBDA_BETA; VSUM_COMPONENT; COND_COMPONENT] THEN + SIMP_TAC[SUM_SUM_PRODUCT] THEN REPEAT STRIP_TAC THEN AP_TERM_TAC THEN + REWRITE_TAC[FUN_EQ_THM; FORALL_PAIR_THM]);; + +let VSUM_IMAGE_NONZERO = prove + (`!d:B->real^N i:A->B s. + FINITE s /\ + (!x y. x IN s /\ y IN s /\ ~(x = y) /\ i x = i y ==> d(i x) = vec 0) + ==> vsum (IMAGE i s) d = vsum s (d o i)`, + GEN_TAC THEN GEN_TAC THEN ONCE_REWRITE_TAC[IMP_CONJ] THEN + MATCH_MP_TAC FINITE_INDUCT_STRONG THEN + SIMP_TAC[IMAGE_CLAUSES; VSUM_CLAUSES; FINITE_IMAGE] THEN + MAP_EVERY X_GEN_TAC [`a:A`; `s:A->bool`] THEN + REWRITE_TAC[IN_INSERT] THEN REPEAT STRIP_TAC THEN + SUBGOAL_THEN `vsum s ((d:B->real^N) o (i:A->B)) = vsum (IMAGE i s) d` + SUBST1_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[o_THM] THEN + REWRITE_TAC[VECTOR_ARITH `a = x + a <=> x = vec 0`] THEN + ASM_MESON_TAC[IN_IMAGE]);; + +let VSUM_UNION_NONZERO = prove + (`!f s t. FINITE s /\ FINITE t /\ (!x. x IN s INTER t ==> f(x) = vec 0) + ==> vsum (s UNION t) f = vsum s f + vsum t f`, + SIMP_TAC[vsum; CART_EQ; LAMBDA_BETA; VECTOR_ADD_COMPONENT] THEN + SIMP_TAC[VEC_COMPONENT; SUM_UNION_NONZERO]);; + +let VSUM_UNIONS_NONZERO = prove + (`!f s. FINITE s /\ (!t:A->bool. t IN s ==> FINITE t) /\ + (!t1 t2 x. t1 IN s /\ t2 IN s /\ ~(t1 = t2) /\ x IN t1 /\ x IN t2 + ==> f x = vec 0) + ==> vsum (UNIONS s) f = vsum s (\t. vsum t f)`, + GEN_TAC THEN ONCE_REWRITE_TAC[IMP_CONJ] THEN + MATCH_MP_TAC FINITE_INDUCT_STRONG THEN + REWRITE_TAC[UNIONS_0; UNIONS_INSERT; VSUM_CLAUSES; IN_INSERT] THEN + MAP_EVERY X_GEN_TAC [`t:A->bool`; `s:(A->bool)->bool`] THEN + DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN + ONCE_REWRITE_TAC[IMP_CONJ] THEN ASM_SIMP_TAC[VSUM_CLAUSES] THEN + ANTS_TAC THENL [ASM_MESON_TAC[]; DISCH_THEN(SUBST_ALL_TAC o SYM)] THEN + STRIP_TAC THEN MATCH_MP_TAC VSUM_UNION_NONZERO THEN + ASM_SIMP_TAC[FINITE_UNIONS; IN_INTER; IN_UNIONS] THEN ASM_MESON_TAC[]);; + +let VSUM_CLAUSES_LEFT = prove + (`!f m n. m <= n ==> vsum(m..n) f = f m + vsum(m + 1..n) f`, + SIMP_TAC[vsum; CART_EQ; LAMBDA_BETA; VECTOR_ADD_COMPONENT] THEN + SIMP_TAC[VEC_COMPONENT; SUM_CLAUSES_LEFT]);; + +let VSUM_DIFFS = prove + (`!m n. vsum(m..n) (\k. f(k) - f(k + 1)) = + if m <= n then f(m) - f(n + 1) else vec 0`, + GEN_TAC THEN INDUCT_TAC THEN ASM_SIMP_TAC[VSUM_CLAUSES_NUMSEG; LE] THEN + ASM_CASES_TAC `m = SUC n` THEN + ASM_REWRITE_TAC[ARITH_RULE `~(SUC n <= n)`; VECTOR_ADD_LID] THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[GSYM ADD1] THEN VECTOR_ARITH_TAC);; + +let VSUM_DIFFS_ALT = prove + (`!m n. vsum(m..n) (\k. f(k + 1) - f(k)) = + if m <= n then f(n + 1) - f(m) else vec 0`, + REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[GSYM VECTOR_NEG_SUB] THEN + SIMP_TAC[VSUM_NEG; VSUM_DIFFS] THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[VECTOR_NEG_SUB; VECTOR_NEG_0]);; + +let VSUM_DELETE_CASES = prove + (`!x f s. + FINITE(s:A->bool) + ==> vsum(s DELETE x) f = if x IN s then vsum s f - f x else vsum s f`, + REPEAT STRIP_TAC THEN COND_CASES_TAC THEN + ASM_SIMP_TAC[SET_RULE `~(x IN s) ==> s DELETE x = s`] THEN + FIRST_ASSUM(fun th -> GEN_REWRITE_TAC (RAND_CONV o ONCE_DEPTH_CONV) + [MATCH_MP (SET_RULE `x IN s ==> s = x INSERT (s DELETE x)`) th]) THEN + ASM_SIMP_TAC[VSUM_CLAUSES; FINITE_DELETE; IN_DELETE] THEN VECTOR_ARITH_TAC);; + +let VSUM_EQ_GENERAL = prove + (`!s:A->bool t:B->bool (f:A->real^N) g h. + (!y. y IN t ==> ?!x. x IN s /\ h x = y) /\ + (!x. x IN s ==> h x IN t /\ g(h x) = f x) + ==> vsum s f = vsum t g`, + SIMP_TAC[vsum; CART_EQ; LAMBDA_BETA] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC SUM_EQ_GENERAL THEN + EXISTS_TAC `h:A->B` THEN ASM_MESON_TAC[]);; + +let VSUM_EQ_GENERAL_INVERSES = prove + (`!s t (f:A->real^N) (g:B->real^N) h k. + (!y. y IN t ==> k y IN s /\ h (k y) = y) /\ + (!x. x IN s ==> h x IN t /\ k (h x) = x /\ g (h x) = f x) + ==> vsum s f = vsum t g`, + SIMP_TAC[vsum; CART_EQ; LAMBDA_BETA] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC SUM_EQ_GENERAL_INVERSES THEN + MAP_EVERY EXISTS_TAC [`h:A->B`; `k:B->A`] THEN ASM_MESON_TAC[]);; + +let VSUM_NORM_ALLSUBSETS_BOUND = prove + (`!f:A->real^N p e. + FINITE p /\ + (!q. q SUBSET p ==> norm(vsum q f) <= e) + ==> sum p (\x. norm(f x)) <= &2 * &(dimindex(:N)) * e`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC + `sum p (\x:A. sum (1..dimindex(:N)) (\i. abs((f x:real^N)$i)))` THEN + CONJ_TAC THENL + [MATCH_MP_TAC SUM_LE THEN ASM_SIMP_TAC[NORM_LE_L1]; ALL_TAC] THEN + W(MP_TAC o PART_MATCH (lhand o rand) SUM_SWAP o lhand o snd) THEN + ASM_REWRITE_TAC[FINITE_NUMSEG] THEN DISCH_THEN SUBST1_TAC THEN + ONCE_REWRITE_TAC[REAL_ARITH `&2 * &n * e = &n * &2 * e`] THEN + GEN_REWRITE_TAC (RAND_CONV o LAND_CONV o RAND_CONV) + [GSYM CARD_NUMSEG_1] THEN + MATCH_MP_TAC SUM_BOUND THEN REWRITE_TAC[FINITE_NUMSEG; IN_NUMSEG] THEN + X_GEN_TAC `k:num` THEN STRIP_TAC THEN MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `sum {x:A | x IN p /\ &0 <= (f x:real^N)$k} (\x. abs((f x)$k)) + + sum {x | x IN p /\ (f x)$k < &0} (\x. abs((f x)$k))` THEN + CONJ_TAC THENL + [MATCH_MP_TAC(REAL_ARITH `a = b ==> b <= a`) THEN + MATCH_MP_TAC SUM_UNION_EQ THEN + ASM_SIMP_TAC[EXTENSION; NOT_IN_EMPTY; IN_INTER; IN_UNION; IN_ELIM_THM] THEN + CONJ_TAC THEN X_GEN_TAC `x:A` THEN ASM_CASES_TAC `(x:A) IN p` THEN + ASM_REWRITE_TAC[] THEN REAL_ARITH_TAC; + ALL_TAC] THEN + MATCH_MP_TAC(REAL_ARITH `x <= e /\ y <= e ==> x + y <= &2 * e`) THEN + GEN_REWRITE_TAC (RAND_CONV o ONCE_DEPTH_CONV) [GSYM REAL_ABS_NEG] THEN + CONJ_TAC THEN MATCH_MP_TAC(REAL_ARITH + `!g. sum s g = sum s f /\ sum s g <= e ==> sum s f <= e`) + THENL + [EXISTS_TAC `\x. ((f:A->real^N) x)$k`; + EXISTS_TAC `\x. --(((f:A->real^N) x)$k)`] THEN + (CONJ_TAC THENL + [MATCH_MP_TAC SUM_EQ THEN REWRITE_TAC[IN_ELIM_THM] THEN REAL_ARITH_TAC; + ALL_TAC]) THEN + ASM_SIMP_TAC[GSYM VSUM_COMPONENT; SUM_NEG; FINITE_RESTRICT] THEN + MATCH_MP_TAC(REAL_ARITH `abs(x) <= e ==> x <= e`) THEN + REWRITE_TAC[REAL_ABS_NEG] THEN + MATCH_MP_TAC(REAL_ARITH + `abs((vsum q f)$k) <= norm(vsum q f) /\ + norm(vsum q f) <= e + ==> abs((vsum q f)$k) <= e`) THEN + ASM_SIMP_TAC[COMPONENT_LE_NORM] THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN SET_TAC[]);; + +let DOT_LSUM = prove + (`!s f y. FINITE s ==> (vsum s f) dot y = sum s (\x. f(x) dot y)`, + REWRITE_TAC[RIGHT_FORALL_IMP_THM] THEN + MATCH_MP_TAC FINITE_INDUCT_STRONG THEN + ASM_SIMP_TAC[VSUM_CLAUSES; SUM_CLAUSES; DOT_LZERO; DOT_LADD]);; + +let DOT_RSUM = prove + (`!s f x. FINITE s ==> x dot (vsum s f) = sum s (\y. x dot f(y))`, + REWRITE_TAC[RIGHT_FORALL_IMP_THM] THEN + MATCH_MP_TAC FINITE_INDUCT_STRONG THEN + ASM_SIMP_TAC[VSUM_CLAUSES; SUM_CLAUSES; DOT_RZERO; DOT_RADD]);; + +let VSUM_OFFSET = prove + (`!f m p. vsum(m + p..n + p) f = vsum(m..n) (\i. f (i + p))`, + SIMP_TAC[vsum; CART_EQ; LAMBDA_BETA; VEC_COMPONENT; SUM_OFFSET]);; + +let VSUM_OFFSET_0 = prove + (`!f m n. m <= n ==> vsum(m..n) f = vsum(0..n - m) (\i. f (i + m))`, + SIMP_TAC[vsum; CART_EQ; LAMBDA_BETA; VEC_COMPONENT; SUM_OFFSET_0]);; + +let VSUM_TRIV_NUMSEG = prove + (`!f m n. n < m ==> vsum(m..n) f = vec 0`, + SIMP_TAC[GSYM NUMSEG_EMPTY; VSUM_CLAUSES]);; + +let VSUM_CONST_NUMSEG = prove + (`!c m n. vsum(m..n) (\n. c) = &((n + 1) - m) % c`, + SIMP_TAC[VSUM_CONST; FINITE_NUMSEG; CARD_NUMSEG]);; + +let VSUM_SUC = prove + (`!f m n. vsum (SUC n..SUC m) f = vsum (n..m) (f o SUC)`, + REPEAT GEN_TAC THEN + SUBGOAL_THEN `SUC n..SUC m = IMAGE SUC (n..m)` SUBST1_TAC THENL + [REWRITE_TAC [ADD1; NUMSEG_OFFSET_IMAGE] THEN + REWRITE_TAC [ONE; ADD_SUC; ADD_0; ETA_AX]; + SIMP_TAC [VSUM_IMAGE; FINITE_NUMSEG; SUC_INJ]]);; + +let VSUM_BIJECTION = prove + (`!f:A->real^N p s:A->bool. + (!x. x IN s ==> p(x) IN s) /\ + (!y. y IN s ==> ?!x. x IN s /\ p(x) = y) + ==> vsum s f = vsum s (f o p)`, + REPEAT STRIP_TAC THEN CONV_TAC SYM_CONV THEN + MATCH_MP_TAC VSUM_EQ_GENERAL THEN EXISTS_TAC `p:A->A` THEN + ASM_REWRITE_TAC[o_THM]);; + +let VSUM_PARTIAL_SUC = prove + (`!f g:num->real^N m n. + vsum (m..n) (\k. f(k) % (g(k + 1) - g(k))) = + if m <= n then f(n + 1) % g(n + 1) - f(m) % g(m) - + vsum (m..n) (\k. (f(k + 1) - f(k)) % g(k + 1)) + else vec 0`, + GEN_TAC THEN GEN_TAC THEN GEN_TAC THEN INDUCT_TAC THEN + COND_CASES_TAC THEN ASM_SIMP_TAC[VSUM_TRIV_NUMSEG; GSYM NOT_LE] THEN + ASM_REWRITE_TAC[VSUM_CLAUSES_NUMSEG] THENL + [COND_CASES_TAC THEN ASM_SIMP_TAC[ARITH] THENL + [VECTOR_ARITH_TAC; ASM_ARITH_TAC]; + ALL_TAC] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [LE]) THEN + DISCH_THEN(DISJ_CASES_THEN2 SUBST_ALL_TAC ASSUME_TAC) THEN + ASM_SIMP_TAC[GSYM NOT_LT; VSUM_TRIV_NUMSEG; ARITH_RULE `n < SUC n`] THEN + ASM_SIMP_TAC[GSYM ADD1; ADD_CLAUSES] THEN VECTOR_ARITH_TAC);; + +let VSUM_PARTIAL_PRE = prove + (`!f g:num->real^N m n. + vsum (m..n) (\k. f(k) % (g(k) - g(k - 1))) = + if m <= n then f(n + 1) % g(n) - f(m) % g(m - 1) - + vsum (m..n) (\k. (f(k + 1) - f(k)) % g(k)) + else vec 0`, + REPEAT GEN_TAC THEN + MP_TAC(ISPECL [`f:num->real`; `\k. (g:num->real^N)(k - 1)`; + `m:num`; `n:num`] VSUM_PARTIAL_SUC) THEN + REWRITE_TAC[ADD_SUB] THEN DISCH_THEN SUBST1_TAC THEN + COND_CASES_TAC THEN REWRITE_TAC[]);; + +let VSUM_COMBINE_L = prove + (`!f m n p. + 0 < n /\ m <= n /\ n <= p + 1 + ==> vsum(m..n - 1) f + vsum(n..p) f = vsum(m..p) f`, + SIMP_TAC[CART_EQ; VECTOR_ADD_COMPONENT; VSUM_COMPONENT; SUM_COMBINE_L]);; + +let VSUM_COMBINE_R = prove + (`!f m n p. + m <= n + 1 /\ n <= p + ==> vsum(m..n) f + vsum(n + 1..p) f = vsum(m..p) f`, + SIMP_TAC[CART_EQ; VECTOR_ADD_COMPONENT; VSUM_COMPONENT; SUM_COMBINE_R]);; + +let VSUM_INJECTION = prove + (`!f p s. + FINITE s /\ + (!x. x IN s ==> p x IN s) /\ + (!x y. x IN s /\ y IN s /\ p x = p y ==> x = y) + ==> vsum s (f o p) = vsum s f`, + REPEAT GEN_TAC THEN DISCH_THEN(MP_TAC o MATCH_MP SUM_INJECTION) THEN + SIMP_TAC[CART_EQ; VSUM_COMPONENT; o_DEF]);; + +let VSUM_SWAP = prove + (`!f s t. + FINITE s /\ FINITE t + ==> vsum s (\i. vsum t (f i)) = vsum t (\j. vsum s (\i. f i j))`, + SIMP_TAC[CART_EQ; VSUM_COMPONENT] THEN REPEAT STRIP_TAC THEN + W(MP_TAC o PART_MATCH (lhs o rand) SUM_SWAP o lhs o snd) THEN + ASM_REWRITE_TAC[]);; + +let VSUM_SWAP_NUMSEG = prove + (`!a b c d f. + vsum (a..b) (\i. vsum (c..d) (f i)) = + vsum (c..d) (\j. vsum (a..b) (\i. f i j))`, + REPEAT GEN_TAC THEN MATCH_MP_TAC VSUM_SWAP THEN REWRITE_TAC[FINITE_NUMSEG]);; + +let VSUM_ADD_GEN = prove + (`!f g s. + FINITE {x | x IN s /\ ~(f x = vec 0)} /\ + FINITE {x | x IN s /\ ~(g x = vec 0)} + ==> vsum s (\x. f x + g x) = vsum s f + vsum s g`, + REPEAT GEN_TAC THEN DISCH_TAC THEN + SIMP_TAC[CART_EQ; vsum; LAMBDA_BETA; VECTOR_ADD_COMPONENT] THEN + REPEAT GEN_TAC THEN DISCH_THEN(K ALL_TAC) THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC SUM_ADD_GEN THEN + POP_ASSUM MP_TAC THEN MATCH_MP_TAC MONO_AND THEN + CONJ_TAC THEN MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] FINITE_SUBSET) THEN + REWRITE_TAC[SUBSET; IN_ELIM_THM] THEN GEN_TAC THEN + ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN REWRITE_TAC[DE_MORGAN_THM] THEN + STRIP_TAC THEN ASM_REWRITE_TAC[VEC_COMPONENT]);; + +let VSUM_CASES_1 = prove + (`!s a. FINITE s /\ a IN s + ==> vsum s (\x. if x = a then y else f(x)) = vsum s f + (y - f a)`, + REPEAT STRIP_TAC THEN ASM_SIMP_TAC[VSUM_CASES] THEN + ASM_SIMP_TAC[GSYM DELETE; VSUM_DELETE] THEN + ASM_SIMP_TAC[SET_RULE `a IN s ==> {x | x IN s /\ x = a} = {a}`] THEN + REWRITE_TAC[VSUM_SING] THEN VECTOR_ARITH_TAC);; + +let VSUM_SING_NUMSEG = prove + (`vsum(n..n) f = f n`, + REWRITE_TAC[NUMSEG_SING; VSUM_SING]);; + +let VSUM_1 = prove + (`vsum(1..1) f = f(1)`, + REWRITE_TAC[VSUM_SING_NUMSEG]);; + +let VSUM_2 = prove + (`!t. vsum(1..2) t = t(1) + t(2)`, + REWRITE_TAC[num_CONV `2`; VSUM_CLAUSES_NUMSEG] THEN + REWRITE_TAC[VSUM_SING_NUMSEG; ARITH; REAL_ADD_ASSOC]);; + +let VSUM_3 = prove + (`!t. vsum(1..3) t = t(1) + t(2) + t(3)`, + REWRITE_TAC[num_CONV `3`; num_CONV `2`; VSUM_CLAUSES_NUMSEG] THEN + REWRITE_TAC[VSUM_SING_NUMSEG; ARITH; VECTOR_ADD_ASSOC]);; + +let VSUM_4 = prove + (`!t. vsum(1..4) t = t(1) + t(2) + t(3) + t(4)`, + SIMP_TAC[num_CONV `4`; num_CONV `3`; num_CONV `2`; VSUM_CLAUSES_NUMSEG] THEN + REWRITE_TAC[VSUM_SING_NUMSEG; ARITH; VECTOR_ADD_ASSOC]);; + +let VSUM_PAIR = prove + (`!f:num->real^N m n. + vsum(2*m..2*n+1) f = vsum(m..n) (\i. f(2*i) + f(2*i+1))`, + SIMP_TAC[CART_EQ; VSUM_COMPONENT; VECTOR_ADD_COMPONENT; SUM_PAIR]);; + +let VSUM_PAIR_0 = prove + (`!f:num->real^N n. vsum(0..2*n+1) f = vsum(0..n) (\i. f(2*i) + f(2*i+1))`, + REPEAT GEN_TAC THEN + MP_TAC(ISPECL [`f:num->real^N`; `0`; `n:num`] VSUM_PAIR) THEN + ASM_REWRITE_TAC[ARITH]);; + +(* ------------------------------------------------------------------------- *) +(* Add useful congruences to the simplifier. *) +(* ------------------------------------------------------------------------- *) + +let th = prove + (`(!f g s. (!x. x IN s ==> f(x) = g(x)) + ==> vsum s (\i. f(i)) = vsum s g) /\ + (!f g a b. (!i. a <= i /\ i <= b ==> f(i) = g(i)) + ==> vsum(a..b) (\i. f(i)) = vsum(a..b) g) /\ + (!f g p. (!x. p x ==> f x = g x) + ==> vsum {y | p y} (\i. f(i)) = vsum {y | p y} g)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC VSUM_EQ THEN + ASM_SIMP_TAC[IN_ELIM_THM; IN_NUMSEG]) in + extend_basic_congs (map SPEC_ALL (CONJUNCTS th));; + +(* ------------------------------------------------------------------------- *) +(* A conversion for evaluation of `vsum(m..n) f` for numerals m and n. *) +(* ------------------------------------------------------------------------- *) + +let EXPAND_VSUM_CONV = + let pth_0,pth_1 = (CONJ_PAIR o prove) + (`vsum(0..0) (f:num->real^N) = f(0) /\ + vsum(0..SUC n) f = vsum(0..n) f + f(SUC n)`, + REWRITE_TAC[VSUM_CLAUSES_NUMSEG; LE_0; VECTOR_ADD_AC]) in + let conv_0 = REWR_CONV pth_0 and conv_1 = REWR_CONV pth_1 in + let rec conv tm = + try (LAND_CONV(RAND_CONV num_CONV) THENC conv_1 THENC + NUM_REDUCE_CONV THENC LAND_CONV conv) tm + with Failure _ -> conv_0 tm in + conv THENC + (REDEPTH_CONV BETA_CONV) THENC + GEN_REWRITE_CONV TOP_DEPTH_CONV [GSYM VECTOR_ADD_ASSOC];; + +(* ------------------------------------------------------------------------- *) +(* Basis vectors in coordinate directions. *) +(* ------------------------------------------------------------------------- *) + +let basis = new_definition + `basis k = lambda i. if i = k then &1 else &0`;; + +let NORM_BASIS = prove + (`!k. 1 <= k /\ k <= dimindex(:N) + ==> (norm(basis k :real^N) = &1)`, + REPEAT GEN_TAC THEN DISCH_TAC THEN REWRITE_TAC[basis; dot; vector_norm] THEN + GEN_REWRITE_TAC RAND_CONV [GSYM SQRT_1] THEN AP_TERM_TAC THEN + MATCH_MP_TAC EQ_TRANS THEN EXISTS_TAC + `sum (1..dimindex(:N)) (\i. if i = k then &1 else &0)` THEN + CONJ_TAC THENL + [MATCH_MP_TAC SUM_EQ_NUMSEG THEN + ASM_SIMP_TAC[LAMBDA_BETA; IN_NUMSEG; EQ_SYM_EQ] THEN + REPEAT STRIP_TAC THEN COND_CASES_TAC THEN REAL_ARITH_TAC; + ASM_REWRITE_TAC[SUM_DELTA; IN_NUMSEG]]);; + +let NORM_BASIS_1 = prove + (`norm(basis 1) = &1`, + SIMP_TAC[NORM_BASIS; ARITH_EQ; ARITH_RULE `1 <= k <=> ~(k = 0)`; + DIMINDEX_NONZERO]);; + +let VECTOR_CHOOSE_SIZE = prove + (`!c. &0 <= c ==> ?x:real^N. norm(x) = c`, + REPEAT STRIP_TAC THEN EXISTS_TAC `c % basis 1 :real^N` THEN + ASM_REWRITE_TAC[NORM_MUL; real_abs; NORM_BASIS_1; REAL_MUL_RID]);; + +let VECTOR_CHOOSE_DIST = prove + (`!x e. &0 <= e ==> ?y:real^N. dist(x,y) = e`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN `?c:real^N. norm(c) = e` CHOOSE_TAC THENL + [ASM_SIMP_TAC[VECTOR_CHOOSE_SIZE]; ALL_TAC] THEN + EXISTS_TAC `x - c:real^N` THEN REWRITE_TAC[dist] THEN + ASM_REWRITE_TAC[VECTOR_ARITH `x - (x - c) = c:real^N`]);; + +let BASIS_INJ = prove + (`!i j. 1 <= i /\ i <= dimindex(:N) /\ + 1 <= j /\ j <= dimindex(:N) /\ + (basis i :real^N = basis j) + ==> (i = j)`, + SIMP_TAC[basis; CART_EQ; LAMBDA_BETA] THEN REPEAT GEN_TAC THEN + REPEAT STRIP_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC `i:num`) THEN + ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN + ASM_SIMP_TAC[REAL_OF_NUM_EQ; ARITH_EQ]);; + +let BASIS_INJ_EQ = prove + (`!i j. 1 <= i /\ i <= dimindex(:N) /\ 1 <= j /\ j <= dimindex(:N) + ==> (basis i:real^N = basis j <=> i = j)`, + MESON_TAC[BASIS_INJ]);; + +let BASIS_NE = prove + (`!i j. 1 <= i /\ i <= dimindex(:N) /\ + 1 <= j /\ j <= dimindex(:N) /\ + ~(i = j) + ==> ~(basis i :real^N = basis j)`, + MESON_TAC[BASIS_INJ]);; + +let BASIS_COMPONENT = prove + (`!k i. 1 <= i /\ i <= dimindex(:N) + ==> ((basis k :real^N)$i = if i = k then &1 else &0)`, + SIMP_TAC[basis; LAMBDA_BETA] THEN MESON_TAC[]);; + +let BASIS_EXPANSION = prove + (`!x:real^N. vsum(1..dimindex(:N)) (\i. x$i % basis i) = x`, + SIMP_TAC[CART_EQ; VSUM_COMPONENT; VECTOR_MUL_COMPONENT; BASIS_COMPONENT] THEN + ONCE_REWRITE_TAC[COND_RAND] THEN REWRITE_TAC[REAL_MUL_RZERO] THEN + REPEAT STRIP_TAC THEN + GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [EQ_SYM_EQ] THEN + ASM_SIMP_TAC[SUM_DELTA; IN_NUMSEG; REAL_MUL_RID]);; + +let BASIS_EXPANSION_UNIQUE = prove + (`!f x:real^N. (vsum(1..dimindex(:N)) (\i. f(i) % basis i) = x) <=> + (!i. 1 <= i /\ i <= dimindex(:N) ==> f(i) = x$i)`, + SIMP_TAC[CART_EQ; VSUM_COMPONENT; VECTOR_MUL_COMPONENT; BASIS_COMPONENT] THEN + REPEAT GEN_TAC THEN REWRITE_TAC[COND_RAND; REAL_MUL_RZERO; REAL_MUL_RID] THEN + GEN_REWRITE_TAC (LAND_CONV o BINDER_CONV o RAND_CONV o LAND_CONV o + ONCE_DEPTH_CONV) [EQ_SYM_EQ] THEN + SIMP_TAC[SUM_DELTA; IN_NUMSEG]);; + +let DOT_BASIS = prove + (`!x:real^N i. + 1 <= i /\ i <= dimindex(:N) + ==> ((basis i) dot x = x$i) /\ (x dot (basis i) = x$i)`, + SIMP_TAC[dot; basis; LAMBDA_BETA] THEN + REWRITE_TAC[COND_RATOR; COND_RAND] THEN + REWRITE_TAC[REAL_MUL_LZERO; REAL_MUL_RZERO] THEN + SIMP_TAC[SUM_DELTA; IN_NUMSEG; REAL_MUL_LID; REAL_MUL_RID]);; + +let DOT_BASIS_BASIS = prove + (`!i j. 1 <= i /\ i <= dimindex(:N) /\ + 1 <= j /\ j <= dimindex(:N) + ==> (basis i:real^N) dot (basis j) = if i = j then &1 else &0`, + SIMP_TAC[DOT_BASIS; BASIS_COMPONENT]);; + +let DOT_BASIS_BASIS_UNEQUAL = prove + (`!i j. ~(i = j) ==> (basis i) dot (basis j) = &0`, + SIMP_TAC[basis; dot; LAMBDA_BETA] THEN ONCE_REWRITE_TAC[COND_RAND] THEN + SIMP_TAC[SUM_0; REAL_MUL_RZERO; REAL_MUL_LZERO; COND_ID]);; + +let BASIS_EQ_0 = prove + (`!i. (basis i :real^N = vec 0) <=> ~(i IN 1..dimindex(:N))`, + SIMP_TAC[CART_EQ; BASIS_COMPONENT; VEC_COMPONENT; IN_NUMSEG] THEN + MESON_TAC[REAL_ARITH `~(&1 = &0)`]);; + +let BASIS_NONZERO = prove + (`!k. 1 <= k /\ k <= dimindex(:N) + ==> ~(basis k :real^N = vec 0)`, + REWRITE_TAC[BASIS_EQ_0; IN_NUMSEG]);; + +let VECTOR_EQ_LDOT = prove + (`!y z. (!x. x dot y = x dot z) <=> y = z`, + REPEAT GEN_TAC THEN EQ_TAC THEN SIMP_TAC[] THEN + REWRITE_TAC[CART_EQ] THEN MESON_TAC[DOT_BASIS]);; + +let VECTOR_EQ_RDOT = prove + (`!x y. (!z. x dot z = y dot z) <=> x = y`, + REPEAT GEN_TAC THEN EQ_TAC THEN SIMP_TAC[] THEN + REWRITE_TAC[CART_EQ] THEN MESON_TAC[DOT_BASIS]);; + +(* ------------------------------------------------------------------------- *) +(* Orthogonality. *) +(* ------------------------------------------------------------------------- *) + +let orthogonal = new_definition + `orthogonal x y <=> (x dot y = &0)`;; + +let ORTHOGONAL_0 = prove + (`!x. orthogonal (vec 0) x /\ orthogonal x (vec 0)`, + REWRITE_TAC[orthogonal; DOT_LZERO; DOT_RZERO]);; + +let ORTHOGONAL_REFL = prove + (`!x. orthogonal x x <=> x = vec 0`, + REWRITE_TAC[orthogonal; DOT_EQ_0]);; + +let ORTHOGONAL_SYM = prove + (`!x y. orthogonal x y <=> orthogonal y x`, + REWRITE_TAC[orthogonal; DOT_SYM]);; + +let ORTHOGONAL_LNEG = prove + (`!x y. orthogonal (--x) y <=> orthogonal x y`, + REWRITE_TAC[orthogonal; DOT_LNEG; REAL_NEG_EQ_0]);; + +let ORTHOGONAL_RNEG = prove + (`!x y. orthogonal x (--y) <=> orthogonal x y`, + REWRITE_TAC[orthogonal; DOT_RNEG; REAL_NEG_EQ_0]);; + +let ORTHOGONAL_MUL = prove + (`(!a x y:real^N. orthogonal (a % x) y <=> a = &0 \/ orthogonal x y) /\ + (!a x y:real^N. orthogonal x (a % y) <=> a = &0 \/ orthogonal x y)`, + REWRITE_TAC[orthogonal; DOT_LMUL; DOT_RMUL; REAL_ENTIRE]);; + +let ORTHOGONAL_BASIS = prove + (`!x:real^N i. 1 <= i /\ i <= dimindex(:N) + ==> (orthogonal (basis i) x <=> (x$i = &0))`, + REPEAT STRIP_TAC THEN SIMP_TAC[orthogonal; dot; basis; LAMBDA_BETA] THEN + REWRITE_TAC[COND_RAND; COND_RATOR; REAL_MUL_LZERO] THEN + ASM_SIMP_TAC[SUM_DELTA; IN_NUMSEG; REAL_MUL_LID]);; + +let ORTHOGONAL_BASIS_BASIS = prove + (`!i j. 1 <= i /\ i <= dimindex(:N) /\ + 1 <= j /\ j <= dimindex(:N) + ==> (orthogonal (basis i :real^N) (basis j) <=> ~(i = j))`, + ASM_SIMP_TAC[ORTHOGONAL_BASIS] THEN ASM_SIMP_TAC[BASIS_COMPONENT] THEN + MESON_TAC[REAL_ARITH `~(&1 = &0)`]);; + +let ORTHOGONAL_CLAUSES = prove + (`(!a. orthogonal a (vec 0)) /\ + (!a x c. orthogonal a x ==> orthogonal a (c % x)) /\ + (!a x. orthogonal a x ==> orthogonal a (--x)) /\ + (!a x y. orthogonal a x /\ orthogonal a y ==> orthogonal a (x + y)) /\ + (!a x y. orthogonal a x /\ orthogonal a y ==> orthogonal a (x - y)) /\ + (!a. orthogonal (vec 0) a) /\ + (!a x c. orthogonal x a ==> orthogonal (c % x) a) /\ + (!a x. orthogonal x a ==> orthogonal (--x) a) /\ + (!a x y. orthogonal x a /\ orthogonal y a ==> orthogonal (x + y) a) /\ + (!a x y. orthogonal x a /\ orthogonal y a ==> orthogonal (x - y) a)`, + REWRITE_TAC[orthogonal; DOT_RNEG; DOT_RMUL; DOT_RADD; DOT_RSUB; + DOT_LZERO; DOT_RZERO; DOT_LNEG; DOT_LMUL; DOT_LADD; DOT_LSUB] THEN + SIMP_TAC[] THEN REAL_ARITH_TAC);; + +let ORTHOGONAL_RVSUM = prove + (`!f:A->real^N s x. + FINITE s /\ + (!y. y IN s ==> orthogonal x (f y)) + ==> orthogonal x (vsum s f)`, + GEN_TAC THEN REWRITE_TAC[RIGHT_FORALL_IMP_THM; IMP_CONJ] THEN + MATCH_MP_TAC FINITE_INDUCT_STRONG THEN + SIMP_TAC[NOT_IN_EMPTY; FORALL_IN_INSERT; ORTHOGONAL_CLAUSES; VSUM_CLAUSES]);; + +let ORTHOGONAL_LVSUM = prove + (`!f:A->real^N s y. + FINITE s /\ + (!x. x IN s ==> orthogonal (f x) y) + ==> orthogonal (vsum s f) y`, + GEN_TAC THEN REWRITE_TAC[RIGHT_FORALL_IMP_THM; IMP_CONJ] THEN + MATCH_MP_TAC FINITE_INDUCT_STRONG THEN + SIMP_TAC[NOT_IN_EMPTY; FORALL_IN_INSERT; ORTHOGONAL_CLAUSES; VSUM_CLAUSES]);; + +let NORM_ADD_PYTHAGOREAN = prove + (`!a b:real^N. + orthogonal a b + ==> norm(a + b) pow 2 = norm(a) pow 2 + norm(b) pow 2`, + SIMP_TAC[NORM_POW_2; orthogonal; DOT_LADD; DOT_RADD; DOT_SYM] THEN + REAL_ARITH_TAC);; + +let NORM_VSUM_PYTHAGOREAN = prove + (`!k u:A->real^N. + FINITE k /\ pairwise (\i j. orthogonal (u i) (u j)) k + ==> norm(vsum k u) pow 2 = sum k (\i. norm(u i) pow 2)`, + ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN GEN_TAC THEN SIMP_TAC[IMP_CONJ] THEN + MATCH_MP_TAC FINITE_INDUCT_STRONG THEN + SIMP_TAC[VSUM_CLAUSES; SUM_CLAUSES; NORM_0] THEN + CONV_TAC REAL_RAT_REDUCE_CONV THEN REWRITE_TAC[PAIRWISE_INSERT] THEN + REWRITE_TAC[pairwise] THEN REPEAT GEN_TAC THEN + DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(STRIP_ASSUME_TAC o GSYM) THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC NORM_ADD_PYTHAGOREAN THEN MATCH_MP_TAC ORTHOGONAL_RVSUM THEN + ASM_MESON_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* Explicit vector construction from lists. *) +(* ------------------------------------------------------------------------- *) + +let VECTOR_1 = prove + (`(vector[x]:A^1)$1 = x`, + SIMP_TAC[vector; LAMBDA_BETA; DIMINDEX_1; ARITH; LENGTH; EL; HD; TL]);; + +let VECTOR_2 = prove + (`(vector[x;y]:A^2)$1 = x /\ + (vector[x;y]:A^2)$2 = y`, + SIMP_TAC[vector; LAMBDA_BETA; DIMINDEX_2; ARITH; LENGTH; EL] THEN + REWRITE_TAC[num_CONV `1`; HD; TL; EL]);; + +let VECTOR_3 = prove + (`(vector[x;y;z]:A^3)$1 = x /\ + (vector[x;y;z]:A^3)$2 = y /\ + (vector[x;y;z]:A^3)$3 = z`, + SIMP_TAC[vector; LAMBDA_BETA; DIMINDEX_3; ARITH; LENGTH; EL] THEN + REWRITE_TAC[num_CONV `2`; num_CONV `1`; HD; TL; EL]);; + +let VECTOR_4 = prove + (`(vector[w;x;y;z]:A^4)$1 = w /\ + (vector[w;x;y;z]:A^4)$2 = x /\ + (vector[w;x;y;z]:A^4)$3 = y /\ + (vector[w;x;y;z]:A^4)$4 = z`, + SIMP_TAC[vector; LAMBDA_BETA; DIMINDEX_4; ARITH; LENGTH; EL] THEN + REWRITE_TAC[num_CONV `3`; num_CONV `2`; num_CONV `1`; HD; TL; EL]);; + +let FORALL_VECTOR_1 = prove + (`(!v:A^1. P v) <=> !x. P(vector[x])`, + EQ_TAC THEN SIMP_TAC[] THEN REPEAT STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `(v:A^1)$1`) THEN + MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN + REWRITE_TAC[CART_EQ; FORALL_1; VECTOR_1; DIMINDEX_1]);; + +let FORALL_VECTOR_2 = prove + (`(!v:A^2. P v) <=> !x y. P(vector[x;y])`, + EQ_TAC THEN SIMP_TAC[] THEN REPEAT STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`(v:A^2)$1`; `(v:A^2)$2`]) THEN + MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN + REWRITE_TAC[CART_EQ; FORALL_2; VECTOR_2; DIMINDEX_2]);; + +let FORALL_VECTOR_3 = prove + (`(!v:A^3. P v) <=> !x y z. P(vector[x;y;z])`, + EQ_TAC THEN SIMP_TAC[] THEN REPEAT STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPECL + [`(v:A^3)$1`; `(v:A^3)$2`; `(v:A^3)$3`]) THEN + MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN + REWRITE_TAC[CART_EQ; FORALL_3; VECTOR_3; DIMINDEX_3]);; + +let FORALL_VECTOR_4 = prove + (`(!v:A^4. P v) <=> !w x y z. P(vector[w;x;y;z])`, + EQ_TAC THEN SIMP_TAC[] THEN REPEAT STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPECL + [`(v:A^4)$1`; `(v:A^4)$2`; `(v:A^4)$3`; `(v:A^4)$4`]) THEN + MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN + REWRITE_TAC[CART_EQ; FORALL_4; VECTOR_4; DIMINDEX_4]);; + +let EXISTS_VECTOR_1 = prove + (`(?v:A^1. P v) <=> ?x. P(vector[x])`, + REWRITE_TAC[MESON[] `(?x. P x) <=> ~(!x. ~P x)`] THEN + REWRITE_TAC[FORALL_VECTOR_1]);; + +let EXISTS_VECTOR_2 = prove + (`(?v:A^2. P v) <=> ?x y. P(vector[x;y])`, + REWRITE_TAC[MESON[] `(?x. P x) <=> ~(!x. ~P x)`] THEN + REWRITE_TAC[FORALL_VECTOR_2]);; + +let EXISTS_VECTOR_3 = prove + (`(?v:A^3. P v) <=> ?x y z. P(vector[x;y;z])`, + REWRITE_TAC[MESON[] `(?x. P x) <=> ~(!x. ~P x)`] THEN + REWRITE_TAC[FORALL_VECTOR_3]);; + +let EXISTS_VECTOR_4 = prove + (`(?v:A^4. P v) <=> ?w x y z. P(vector[w;x;y;z])`, + REWRITE_TAC[MESON[] `(?x. P x) <=> ~(!x. ~P x)`] THEN + REWRITE_TAC[FORALL_VECTOR_4]);; + +let VECTOR_EXPAND_1 = prove + (`!x:real^1. x = vector[x$1]`, + SIMP_TAC[CART_EQ; DIMINDEX_1; FORALL_1; VECTOR_1]);; + +let VECTOR_EXPAND_2 = prove + (`!x:real^2. x = vector[x$1;x$2]`, + SIMP_TAC[CART_EQ; DIMINDEX_2; FORALL_2; VECTOR_2]);; + +let VECTOR_EXPAND_3 = prove + (`!x:real^3. x = vector[x$1;x$2;x$3]`, + SIMP_TAC[CART_EQ; DIMINDEX_3; FORALL_3; VECTOR_3]);; + +let VECTOR_EXPAND_4 = prove + (`!x:real^4. x = vector[x$1;x$2;x$3;x$4]`, + SIMP_TAC[CART_EQ; DIMINDEX_4; FORALL_4; VECTOR_4]);; + +(* ------------------------------------------------------------------------- *) +(* Linear functions. *) +(* ------------------------------------------------------------------------- *) + +let linear = new_definition + `linear (f:real^M->real^N) <=> + (!x y. f(x + y) = f(x) + f(y)) /\ + (!c x. f(c % x) = c % f(x))`;; + +let LINEAR_COMPOSE_CMUL = prove + (`!f c. linear f ==> linear (\x. c % f(x))`, + SIMP_TAC[linear] THEN REPEAT STRIP_TAC THEN VECTOR_ARITH_TAC);; + +let LINEAR_COMPOSE_NEG = prove + (`!f. linear f ==> linear (\x. --(f(x)))`, + SIMP_TAC[linear] THEN REPEAT STRIP_TAC THEN VECTOR_ARITH_TAC);; + +let LINEAR_COMPOSE_ADD = prove + (`!f g. linear f /\ linear g ==> linear (\x. f(x) + g(x))`, + SIMP_TAC[linear] THEN REPEAT STRIP_TAC THEN VECTOR_ARITH_TAC);; + +let LINEAR_COMPOSE_SUB = prove + (`!f g. linear f /\ linear g ==> linear (\x. f(x) - g(x))`, + SIMP_TAC[linear] THEN REPEAT STRIP_TAC THEN VECTOR_ARITH_TAC);; + +let LINEAR_COMPOSE = prove + (`!f g. linear f /\ linear g ==> linear (g o f)`, + SIMP_TAC[linear; o_THM]);; + +let LINEAR_ID = prove + (`linear (\x. x)`, + REWRITE_TAC[linear]);; + +let LINEAR_I = prove + (`linear I`, + REWRITE_TAC[I_DEF; LINEAR_ID]);; + +let LINEAR_ZERO = prove + (`linear (\x. vec 0)`, + REWRITE_TAC[linear] THEN CONJ_TAC THEN VECTOR_ARITH_TAC);; + +let LINEAR_NEGATION = prove + (`linear(--)`, + REWRITE_TAC[linear] THEN VECTOR_ARITH_TAC);; + +let LINEAR_COMPOSE_VSUM = prove + (`!f s. FINITE s /\ (!a. a IN s ==> linear(f a)) + ==> linear(\x. vsum s (\a. f a x))`, + GEN_TAC THEN REWRITE_TAC[IMP_CONJ] THEN + MATCH_MP_TAC FINITE_INDUCT_STRONG THEN + SIMP_TAC[VSUM_CLAUSES; LINEAR_ZERO] THEN + ASM_SIMP_TAC[ETA_AX; IN_INSERT; LINEAR_COMPOSE_ADD]);; + +let LINEAR_VMUL_COMPONENT = prove + (`!f:real^M->real^N v k. + linear f /\ 1 <= k /\ k <= dimindex(:N) + ==> linear (\x. f(x)$k % v)`, + SIMP_TAC[linear; VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT] THEN + REPEAT STRIP_TAC THEN VECTOR_ARITH_TAC);; + +let LINEAR_0 = prove + (`!f. linear f ==> (f(vec 0) = vec 0)`, + MESON_TAC[VECTOR_MUL_LZERO; linear]);; + +let LINEAR_CMUL = prove + (`!f c x. linear f ==> (f(c % x) = c % f(x))`, + SIMP_TAC[linear]);; + +let LINEAR_NEG = prove + (`!f x. linear f ==> (f(--x) = --(f x))`, + ONCE_REWRITE_TAC[VECTOR_NEG_MINUS1] THEN SIMP_TAC[LINEAR_CMUL]);; + +let LINEAR_ADD = prove + (`!f x y. linear f ==> (f(x + y) = f(x) + f(y))`, + SIMP_TAC[linear]);; + +let LINEAR_SUB = prove + (`!f x y. linear f ==> (f(x - y) = f(x) - f(y))`, + SIMP_TAC[VECTOR_SUB; LINEAR_ADD; LINEAR_NEG]);; + +let LINEAR_VSUM = prove + (`!f g s. linear f /\ FINITE s ==> (f(vsum s g) = vsum s (f o g))`, + GEN_TAC THEN GEN_TAC THEN SIMP_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN + DISCH_TAC THEN MATCH_MP_TAC FINITE_INDUCT_STRONG THEN + SIMP_TAC[VSUM_CLAUSES] THEN FIRST_ASSUM(fun th -> + SIMP_TAC[MATCH_MP LINEAR_0 th; MATCH_MP LINEAR_ADD th; o_THM]));; + +let LINEAR_VSUM_MUL = prove + (`!f s c v. + linear f /\ FINITE s + ==> f(vsum s (\i. c i % v i)) = vsum s (\i. c(i) % f(v i))`, + SIMP_TAC[LINEAR_VSUM; o_DEF; LINEAR_CMUL]);; + +let LINEAR_INJECTIVE_0 = prove + (`!f. linear f + ==> ((!x y. (f(x) = f(y)) ==> (x = y)) <=> + (!x. (f(x) = vec 0) ==> (x = vec 0)))`, + REPEAT STRIP_TAC THEN + GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [GSYM VECTOR_SUB_EQ] THEN + ASM_SIMP_TAC[GSYM LINEAR_SUB] THEN MESON_TAC[VECTOR_SUB_RZERO]);; + +let LINEAR_BOUNDED = prove + (`!f:real^M->real^N. linear f ==> ?B. !x. norm(f x) <= B * norm(x)`, + REPEAT STRIP_TAC THEN EXISTS_TAC + `sum(1..dimindex(:M)) (\i. norm((f:real^M->real^N)(basis i)))` THEN + GEN_TAC THEN + GEN_REWRITE_TAC (LAND_CONV o funpow 2 RAND_CONV) [GSYM BASIS_EXPANSION] THEN + ASM_SIMP_TAC[LINEAR_VSUM; FINITE_NUMSEG] THEN + ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN REWRITE_TAC[GSYM SUM_LMUL] THEN + MATCH_MP_TAC VSUM_NORM_LE THEN + SIMP_TAC[FINITE_CROSS; FINITE_NUMSEG; IN_NUMSEG] THEN + ASM_SIMP_TAC[o_DEF; NORM_MUL; LINEAR_CMUL] THEN + ASM_SIMP_TAC[REAL_LE_RMUL; NORM_POS_LE; COMPONENT_LE_NORM]);; + +let LINEAR_BOUNDED_POS = prove + (`!f:real^M->real^N. linear f ==> ?B. &0 < B /\ !x. norm(f x) <= B * norm(x)`, + REPEAT STRIP_TAC THEN + FIRST_ASSUM(X_CHOOSE_TAC `B:real` o MATCH_MP LINEAR_BOUNDED) THEN + EXISTS_TAC `abs(B) + &1` THEN CONJ_TAC THENL [REAL_ARITH_TAC; ALL_TAC] THEN + POP_ASSUM MP_TAC THEN MATCH_MP_TAC MONO_FORALL THEN GEN_TAC THEN + MATCH_MP_TAC(REAL_ARITH `a <= b ==> x <= a ==> x <= b`) THEN + MATCH_MP_TAC REAL_LE_RMUL THEN REWRITE_TAC[NORM_POS_LE] THEN + REAL_ARITH_TAC);; + +let SYMMETRIC_LINEAR_IMAGE = prove + (`!f s. (!x. x IN s ==> --x IN s) /\ linear f + ==> !x. x IN (IMAGE f s) ==> --x IN (IMAGE f s)`, + REWRITE_TAC[FORALL_IN_IMAGE] THEN + SIMP_TAC[GSYM LINEAR_NEG] THEN SET_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* Bilinear functions. *) +(* ------------------------------------------------------------------------- *) + +let bilinear = new_definition + `bilinear f <=> (!x. linear(\y. f x y)) /\ (!y. linear(\x. f x y))`;; + +let BILINEAR_LADD = prove + (`!h x y z. bilinear h ==> h (x + y) z = (h x z) + (h y z)`, + SIMP_TAC[bilinear; linear]);; + +let BILINEAR_RADD = prove + (`!h x y z. bilinear h ==> h x (y + z) = (h x y) + (h x z)`, + SIMP_TAC[bilinear; linear]);; + +let BILINEAR_LMUL = prove + (`!h c x y. bilinear h ==> h (c % x) y = c % (h x y)`, + SIMP_TAC[bilinear; linear]);; + +let BILINEAR_RMUL = prove + (`!h c x y. bilinear h ==> h x (c % y) = c % (h x y)`, + SIMP_TAC[bilinear; linear]);; + +let BILINEAR_LNEG = prove + (`!h x y. bilinear h ==> h (--x) y = --(h x y)`, + ONCE_REWRITE_TAC[VECTOR_NEG_MINUS1] THEN SIMP_TAC[BILINEAR_LMUL]);; + +let BILINEAR_RNEG = prove + (`!h x y. bilinear h ==> h x (--y) = --(h x y)`, + ONCE_REWRITE_TAC[VECTOR_NEG_MINUS1] THEN SIMP_TAC[BILINEAR_RMUL]);; + +let BILINEAR_LZERO = prove + (`!h x. bilinear h ==> h (vec 0) x = vec 0`, + ONCE_REWRITE_TAC[VECTOR_ARITH `x = vec 0 <=> x + x = x`] THEN + SIMP_TAC[GSYM BILINEAR_LADD; VECTOR_ADD_LID]);; + +let BILINEAR_RZERO = prove + (`!h x. bilinear h ==> h x (vec 0) = vec 0`, + ONCE_REWRITE_TAC[VECTOR_ARITH `x = vec 0 <=> x + x = x`] THEN + SIMP_TAC[GSYM BILINEAR_RADD; VECTOR_ADD_LID]);; + +let BILINEAR_LSUB = prove + (`!h x y z. bilinear h ==> h (x - y) z = (h x z) - (h y z)`, + SIMP_TAC[VECTOR_SUB; BILINEAR_LNEG; BILINEAR_LADD]);; + +let BILINEAR_RSUB = prove + (`!h x y z. bilinear h ==> h x (y - z) = (h x y) - (h x z)`, + SIMP_TAC[VECTOR_SUB; BILINEAR_RNEG; BILINEAR_RADD]);; + +let BILINEAR_VSUM = prove + (`!h:real^M->real^N->real^P. + bilinear h /\ FINITE s /\ FINITE t + ==> h (vsum s f) (vsum t g) = vsum (s CROSS t) (\(i,j). h (f i) (g j))`, + REPEAT GEN_TAC THEN SIMP_TAC[bilinear; ETA_AX] THEN + ONCE_REWRITE_TAC[TAUT `(a /\ b) /\ c /\ d <=> (a /\ d) /\ (b /\ c)`] THEN + DISCH_THEN(CONJUNCTS_THEN2 STRIP_ASSUME_TAC MP_TAC) THEN + ONCE_REWRITE_TAC[LEFT_AND_FORALL_THM] THEN DISCH_TAC THEN + FIRST_ASSUM(MP_TAC o GEN_ALL o MATCH_MP LINEAR_VSUM o SPEC_ALL) THEN + SIMP_TAC[] THEN ASM_SIMP_TAC[LINEAR_VSUM; o_DEF; VSUM_VSUM_PRODUCT] THEN + REWRITE_TAC[GSYM CROSS]);; + +let BILINEAR_BOUNDED = prove + (`!h:real^M->real^N->real^P. + bilinear h ==> ?B. !x y. norm(h x y) <= B * norm(x) * norm(y)`, + REPEAT STRIP_TAC THEN + EXISTS_TAC `sum ((1..dimindex(:M)) CROSS (1..dimindex(:N))) + (\(i,j). norm((h:real^M->real^N->real^P) + (basis i) (basis j)))` THEN + REPEAT GEN_TAC THEN GEN_REWRITE_TAC + (LAND_CONV o RAND_CONV o BINOP_CONV) [GSYM BASIS_EXPANSION] THEN + ASM_SIMP_TAC[BILINEAR_VSUM; FINITE_NUMSEG] THEN + ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN REWRITE_TAC[GSYM SUM_LMUL] THEN + MATCH_MP_TAC VSUM_NORM_LE THEN + SIMP_TAC[FINITE_CROSS; FINITE_NUMSEG; FORALL_PAIR_THM; IN_CROSS] THEN + REWRITE_TAC[IN_NUMSEG] THEN REPEAT STRIP_TAC THEN + ASM_SIMP_TAC[BILINEAR_LMUL; NORM_MUL] THEN + ASM_SIMP_TAC[BILINEAR_RMUL; NORM_MUL; REAL_MUL_ASSOC] THEN + MATCH_MP_TAC REAL_LE_RMUL THEN REWRITE_TAC[NORM_POS_LE] THEN + ASM_SIMP_TAC[COMPONENT_LE_NORM; REAL_ABS_POS; REAL_LE_MUL2]);; + +let BILINEAR_BOUNDED_POS = prove + (`!h. bilinear h + ==> ?B. &0 < B /\ !x y. norm(h x y) <= B * norm(x) * norm(y)`, + REPEAT STRIP_TAC THEN + FIRST_ASSUM(X_CHOOSE_TAC `B:real` o MATCH_MP BILINEAR_BOUNDED) THEN + EXISTS_TAC `abs(B) + &1` THEN CONJ_TAC THENL [REAL_ARITH_TAC; ALL_TAC] THEN + POP_ASSUM MP_TAC THEN REPEAT(MATCH_MP_TAC MONO_FORALL THEN GEN_TAC) THEN + MATCH_MP_TAC(REAL_ARITH `a <= b ==> x <= a ==> x <= b`) THEN + REPEAT(MATCH_MP_TAC REAL_LE_RMUL THEN + SIMP_TAC[NORM_POS_LE; REAL_LE_MUL]) THEN + REAL_ARITH_TAC);; + +let BILINEAR_VSUM_PARTIAL_SUC = prove + (`!f g h:real^M->real^N->real^P m n. + bilinear h + ==> vsum (m..n) (\k. h (f k) (g(k + 1) - g(k))) = + if m <= n then h (f(n + 1)) (g(n + 1)) - h (f m) (g m) - + vsum (m..n) (\k. h (f(k + 1) - f(k)) (g(k + 1))) + else vec 0`, + REWRITE_TAC[RIGHT_FORALL_IMP_THM] THEN REPEAT GEN_TAC THEN DISCH_TAC THEN + GEN_TAC THEN INDUCT_TAC THEN + COND_CASES_TAC THEN ASM_SIMP_TAC[VSUM_TRIV_NUMSEG; GSYM NOT_LE] THEN + ASM_REWRITE_TAC[VSUM_CLAUSES_NUMSEG] THENL + [COND_CASES_TAC THEN ASM_SIMP_TAC[ARITH] THENL + [ASM_SIMP_TAC[BILINEAR_RSUB; BILINEAR_LSUB] THEN VECTOR_ARITH_TAC; + ASM_ARITH_TAC]; + ALL_TAC] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [LE]) THEN + DISCH_THEN(DISJ_CASES_THEN2 SUBST_ALL_TAC ASSUME_TAC) THEN + ASM_SIMP_TAC[GSYM NOT_LT; VSUM_TRIV_NUMSEG; ARITH_RULE `n < SUC n`] THEN + ASM_SIMP_TAC[GSYM ADD1; ADD_CLAUSES] THEN + ASM_SIMP_TAC[BILINEAR_RSUB; BILINEAR_LSUB] THEN VECTOR_ARITH_TAC);; + +let BILINEAR_VSUM_PARTIAL_PRE = prove + (`!f g h:real^M->real^N->real^P m n. + bilinear h + ==> vsum (m..n) (\k. h (f k) (g(k) - g(k - 1))) = + if m <= n then h (f(n + 1)) (g(n)) - h (f m) (g(m - 1)) - + vsum (m..n) (\k. h (f(k + 1) - f(k)) (g(k))) + else vec 0`, + REPEAT STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o ISPECL [`f:num->real^M`; `\k. (g:num->real^N)(k - 1)`; + `m:num`; `n:num`] o MATCH_MP BILINEAR_VSUM_PARTIAL_SUC) THEN + REWRITE_TAC[ADD_SUB] THEN DISCH_THEN SUBST1_TAC THEN + COND_CASES_TAC THEN REWRITE_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* Adjoints. *) +(* ------------------------------------------------------------------------- *) + +let adjoint = new_definition + `adjoint(f:real^M->real^N) = @f'. !x y. f(x) dot y = x dot f'(y)`;; + +let ADJOINT_WORKS = prove + (`!f:real^M->real^N. linear f ==> !x y. f(x) dot y = x dot (adjoint f)(y)`, + GEN_TAC THEN DISCH_TAC THEN SIMP_TAC[adjoint] THEN CONV_TAC SELECT_CONV THEN + ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN ONCE_REWRITE_TAC[GSYM SKOLEM_THM] THEN + X_GEN_TAC `y:real^N` THEN + EXISTS_TAC `(lambda i. (f:real^M->real^N) (basis i) dot y):real^M` THEN + X_GEN_TAC `x:real^M` THEN + GEN_REWRITE_TAC (funpow 2 LAND_CONV o RAND_CONV) [GSYM BASIS_EXPANSION] THEN + ASM_SIMP_TAC[LINEAR_VSUM; FINITE_NUMSEG] THEN + SIMP_TAC[dot; LAMBDA_BETA; VSUM_COMPONENT; GSYM SUM_LMUL; GSYM SUM_RMUL] THEN + GEN_REWRITE_TAC RAND_CONV [SUM_SWAP_NUMSEG] THEN + ASM_SIMP_TAC[o_THM; VECTOR_MUL_COMPONENT; LINEAR_CMUL; REAL_MUL_ASSOC]);; + +let ADJOINT_LINEAR = prove + (`!f:real^M->real^N. linear f ==> linear(adjoint f)`, + REPEAT STRIP_TAC THEN REWRITE_TAC[linear; GSYM VECTOR_EQ_LDOT] THEN + ASM_SIMP_TAC[DOT_RMUL; DOT_RADD; GSYM ADJOINT_WORKS]);; + +let ADJOINT_CLAUSES = prove + (`!f:real^M->real^N. + linear f ==> (!x y. x dot (adjoint f)(y) = f(x) dot y) /\ + (!x y. (adjoint f)(y) dot x = y dot f(x))`, + MESON_TAC[ADJOINT_WORKS; DOT_SYM]);; + +let ADJOINT_ADJOINT = prove + (`!f:real^M->real^N. linear f ==> adjoint(adjoint f) = f`, + SIMP_TAC[FUN_EQ_THM; GSYM VECTOR_EQ_LDOT; ADJOINT_CLAUSES; ADJOINT_LINEAR]);; + +let ADJOINT_UNIQUE = prove + (`!f f'. linear f /\ (!x y. f'(x) dot y = x dot f(y)) + ==> f' = adjoint f`, + SIMP_TAC[FUN_EQ_THM; GSYM VECTOR_EQ_RDOT; ADJOINT_CLAUSES]);; + +let ADJOINT_COMPOSE = prove + (`!f g:real^N->real^N. + linear f /\ linear g ==> adjoint(f o g) = adjoint g o adjoint f`, + REPEAT STRIP_TAC THEN CONV_TAC SYM_CONV THEN MATCH_MP_TAC ADJOINT_UNIQUE THEN + ASM_SIMP_TAC[LINEAR_COMPOSE; o_THM; ADJOINT_CLAUSES]);; + +let SELF_ADJOINT_COMPOSE = prove + (`!f g:real^N->real^N. + linear f /\ linear g /\ adjoint f = f /\ adjoint g = g + ==> (adjoint(f o g) = f o g <=> f o g = g o f)`, + SIMP_TAC[ADJOINT_COMPOSE] THEN MESON_TAC[]);; + +let SELF_ADJOINT_ORTHOGONAL_EIGENVECTORS = prove + (`!f:real^N->real^N v w a b. + linear f /\ adjoint f = f /\ f v = a % v /\ f w = b % w /\ ~(a = b) + ==> orthogonal v w`, + REPEAT STRIP_TAC THEN FIRST_ASSUM(MP_TAC o SPECL [`v:real^N`; `w:real^N`] o + MATCH_MP ADJOINT_WORKS) THEN + ASM_REWRITE_TAC[DOT_LMUL; DOT_RMUL; orthogonal; REAL_EQ_MUL_RCANCEL]);; + +(* ------------------------------------------------------------------------- *) +(* Matrix notation. NB: an MxN matrix is of type real^N^M, not real^M^N. *) +(* We could define a special type if we're going to use them a lot. *) +(* ------------------------------------------------------------------------- *) + +overload_interface ("--",`(matrix_neg):real^N^M->real^N^M`);; +overload_interface ("+",`(matrix_add):real^N^M->real^N^M->real^N^M`);; +overload_interface ("-",`(matrix_sub):real^N^M->real^N^M->real^N^M`);; + +make_overloadable "**" `:A->B->C`;; + +overload_interface ("**",`(matrix_mul):real^N^M->real^P^N->real^P^M`);; +overload_interface ("**",`(matrix_vector_mul):real^N^M->real^N->real^M`);; +overload_interface ("**",`(vector_matrix_mul):real^M->real^N^M->real^N`);; + +parse_as_infix("%%",(21,"right"));; + +prioritize_real();; + +let matrix_cmul = new_definition + `((%%):real->real^N^M->real^N^M) c A = lambda i j. c * A$i$j`;; + +let matrix_neg = new_definition + `!A:real^N^M. --A = lambda i j. --(A$i$j)`;; + +let matrix_add = new_definition + `!A:real^N^M B:real^N^M. A + B = lambda i j. A$i$j + B$i$j`;; + +let matrix_sub = new_definition + `!A:real^N^M B:real^N^M. A - B = lambda i j. A$i$j - B$i$j`;; + +let matrix_mul = new_definition + `!A:real^N^M B:real^P^N. + A ** B = + lambda i j. sum(1..dimindex(:N)) (\k. A$i$k * B$k$j)`;; + +let matrix_vector_mul = new_definition + `!A:real^N^M x:real^N. + A ** x = lambda i. sum(1..dimindex(:N)) (\j. A$i$j * x$j)`;; + +let vector_matrix_mul = new_definition + `!A:real^N^M x:real^M. + x ** A = lambda j. sum(1..dimindex(:M)) (\i. A$i$j * x$i)`;; + +let mat = new_definition + `(mat:num->real^N^M) k = lambda i j. if i = j then &k else &0`;; + +let transp = new_definition + `(transp:real^N^M->real^M^N) A = lambda i j. A$j$i`;; + +let row = new_definition + `(row:num->real^N^M->real^N) i A = lambda j. A$i$j`;; + +let column = new_definition + `(column:num->real^N^M->real^M) j A = lambda i. A$i$j`;; + +let rows = new_definition + `rows(A:real^N^M) = { row i A | 1 <= i /\ i <= dimindex(:M)}`;; + +let columns = new_definition + `columns(A:real^N^M) = { column i A | 1 <= i /\ i <= dimindex(:N)}`;; + +let MATRIX_CMUL_COMPONENT = prove + (`!c A:real^N^M i. (c %% A)$i$j = c * A$i$j`, + REPEAT GEN_TAC THEN + SUBGOAL_THEN `?k. 1 <= k /\ k <= dimindex(:M) /\ !A:real^N^M. A$i = A$k` + CHOOSE_TAC THENL [REWRITE_TAC[FINITE_INDEX_INRANGE]; ALL_TAC] THEN + SUBGOAL_THEN `?l. 1 <= l /\ l <= dimindex(:N) /\ !z:real^N. z$j = z$l` + CHOOSE_TAC THENL [REWRITE_TAC[FINITE_INDEX_INRANGE]; ALL_TAC] THEN + ASM_SIMP_TAC[matrix_cmul; CART_EQ; LAMBDA_BETA]);; + +let MATRIX_ADD_COMPONENT = prove + (`!A B:real^N^M i j. (A + B)$i$j = A$i$j + B$i$j`, + REPEAT GEN_TAC THEN + SUBGOAL_THEN `?k. 1 <= k /\ k <= dimindex(:M) /\ !A:real^N^M. A$i = A$k` + CHOOSE_TAC THENL [REWRITE_TAC[FINITE_INDEX_INRANGE]; ALL_TAC] THEN + SUBGOAL_THEN `?l. 1 <= l /\ l <= dimindex(:N) /\ !z:real^N. z$j = z$l` + CHOOSE_TAC THENL [REWRITE_TAC[FINITE_INDEX_INRANGE]; ALL_TAC] THEN + ASM_SIMP_TAC[matrix_add; LAMBDA_BETA]);; + +let MATRIX_SUB_COMPONENT = prove + (`!A B:real^N^M i j. (A - B)$i$j = A$i$j - B$i$j`, + REPEAT GEN_TAC THEN + SUBGOAL_THEN `?k. 1 <= k /\ k <= dimindex(:M) /\ !A:real^N^M. A$i = A$k` + CHOOSE_TAC THENL [REWRITE_TAC[FINITE_INDEX_INRANGE]; ALL_TAC] THEN + SUBGOAL_THEN `?l. 1 <= l /\ l <= dimindex(:N) /\ !z:real^N. z$j = z$l` + CHOOSE_TAC THENL [REWRITE_TAC[FINITE_INDEX_INRANGE]; ALL_TAC] THEN + ASM_SIMP_TAC[matrix_sub; LAMBDA_BETA]);; + +let MATRIX_NEG_COMPONENT = prove + (`!A:real^N^M i j. (--A)$i$j = --(A$i$j)`, + REPEAT GEN_TAC THEN + SUBGOAL_THEN `?k. 1 <= k /\ k <= dimindex(:M) /\ !A:real^N^M. A$i = A$k` + CHOOSE_TAC THENL [REWRITE_TAC[FINITE_INDEX_INRANGE]; ALL_TAC] THEN + SUBGOAL_THEN `?l. 1 <= l /\ l <= dimindex(:N) /\ !z:real^N. z$j = z$l` + CHOOSE_TAC THENL [REWRITE_TAC[FINITE_INDEX_INRANGE]; ALL_TAC] THEN + ASM_SIMP_TAC[matrix_neg; LAMBDA_BETA]);; + +let TRANSP_COMPONENT = prove + (`!A:real^N^M i j. (transp A)$i$j = A$j$i`, + REPEAT GEN_TAC THEN + SUBGOAL_THEN `?k. 1 <= k /\ k <= dimindex(:N) /\ + (!A:real^M^N. A$i = A$k) /\ (!z:real^N. z$i = z$k)` + CHOOSE_TAC THENL [REWRITE_TAC[FINITE_INDEX_INRANGE_2]; ALL_TAC] THEN + SUBGOAL_THEN `?l. 1 <= l /\ l <= dimindex(:M) /\ + (!A:real^N^M. A$j = A$l) /\ (!z:real^M. z$j = z$l)` + CHOOSE_TAC THENL [REWRITE_TAC[FINITE_INDEX_INRANGE_2]; ALL_TAC] THEN + ASM_SIMP_TAC[transp; LAMBDA_BETA]);; + +let MAT_COMPONENT = prove + (`!n i j. + 1 <= i /\ i <= dimindex(:M) /\ + 1 <= j /\ j <= dimindex(:N) + ==> (mat n:real^N^M)$i$j = if i = j then &n else &0`, + SIMP_TAC[mat; LAMBDA_BETA]);; + +let MAT_0_COMPONENT = prove + (`!i j. (mat 0:real^N^M)$i$j = &0`, + REPEAT GEN_TAC THEN + SUBGOAL_THEN `?k. 1 <= k /\ k <= dimindex(:M) /\ !A:real^N^M. A$i = A$k` + CHOOSE_TAC THENL [REWRITE_TAC[FINITE_INDEX_INRANGE]; ALL_TAC] THEN + SUBGOAL_THEN `?l. 1 <= l /\ l <= dimindex(:N) /\ !z:real^N. z$j = z$l` + CHOOSE_TAC THENL [REWRITE_TAC[FINITE_INDEX_INRANGE]; ALL_TAC] THEN + ASM_SIMP_TAC[mat; COND_ID; LAMBDA_BETA]);; + +let MATRIX_CMUL_ASSOC = prove + (`!a b X:real^M^N. a %% (b %% X) = (a * b) %% X`, + SIMP_TAC[CART_EQ; matrix_cmul; LAMBDA_BETA; REAL_MUL_ASSOC]);; + +let MATRIX_CMUL_LID = prove + (`!X:real^M^N. &1 %% X = X`, + SIMP_TAC[CART_EQ; matrix_cmul; LAMBDA_BETA; REAL_MUL_LID]);; + +let MATRIX_ADD_SYM = prove + (`!A:real^N^M B. A + B = B + A`, + SIMP_TAC[matrix_add; CART_EQ; LAMBDA_BETA; REAL_ADD_AC]);; + +let MATRIX_ADD_ASSOC = prove + (`!A:real^N^M B C. A + (B + C) = (A + B) + C`, + SIMP_TAC[matrix_add; CART_EQ; LAMBDA_BETA; REAL_ADD_AC]);; + +let MATRIX_ADD_LID = prove + (`!A. mat 0 + A = A`, + SIMP_TAC[matrix_add; mat; COND_ID; CART_EQ; LAMBDA_BETA; REAL_ADD_LID]);; + +let MATRIX_ADD_RID = prove + (`!A. A + mat 0 = A`, + SIMP_TAC[matrix_add; mat; COND_ID; CART_EQ; LAMBDA_BETA; REAL_ADD_RID]);; + +let MATRIX_ADD_LNEG = prove + (`!A. --A + A = mat 0`, + SIMP_TAC[matrix_neg; matrix_add; mat; COND_ID; + CART_EQ; LAMBDA_BETA; REAL_ADD_LINV]);; + +let MATRIX_ADD_RNEG = prove + (`!A. A + --A = mat 0`, + SIMP_TAC[matrix_neg; matrix_add; mat; COND_ID; + CART_EQ; LAMBDA_BETA; REAL_ADD_RINV]);; + +let MATRIX_SUB = prove + (`!A:real^N^M B. A - B = A + --B`, + SIMP_TAC[matrix_neg; matrix_add; matrix_sub; CART_EQ; LAMBDA_BETA; + real_sub]);; + +let MATRIX_SUB_REFL = prove + (`!A. A - A = mat 0`, + REWRITE_TAC[MATRIX_SUB; MATRIX_ADD_RNEG]);; + +let MATRIX_ADD_LDISTRIB = prove + (`!A:real^N^M B:real^P^N C. A ** (B + C) = A ** B + A ** C`, + SIMP_TAC[matrix_mul; matrix_add; CART_EQ; LAMBDA_BETA; + GSYM SUM_ADD_NUMSEG] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC SUM_EQ_NUMSEG THEN + ASM_SIMP_TAC[LAMBDA_BETA; REAL_ADD_LDISTRIB]);; + +let MATRIX_MUL_LID = prove + (`!A:real^N^M. mat 1 ** A = A`, + REWRITE_TAC[matrix_mul; + GEN_REWRITE_RULE (RAND_CONV o ONCE_DEPTH_CONV) [EQ_SYM_EQ] + (SPEC_ALL mat)] THEN + SIMP_TAC[CART_EQ; LAMBDA_BETA] THEN REWRITE_TAC[COND_RATOR; COND_RAND] THEN + SIMP_TAC[SUM_DELTA; REAL_MUL_LZERO; IN_NUMSEG; REAL_MUL_LID]);; + +let MATRIX_MUL_RID = prove + (`!A:real^N^M. A ** mat 1 = A`, + REWRITE_TAC[matrix_mul; mat] THEN + SIMP_TAC[CART_EQ; LAMBDA_BETA] THEN REWRITE_TAC[COND_RATOR; COND_RAND] THEN + SIMP_TAC[SUM_DELTA; REAL_MUL_RZERO; IN_NUMSEG; REAL_MUL_RID]);; + +let MATRIX_MUL_ASSOC = prove + (`!A:real^N^M B:real^P^N C:real^Q^P. A ** B ** C = (A ** B) ** C`, + REPEAT GEN_TAC THEN + SIMP_TAC[matrix_mul; CART_EQ; LAMBDA_BETA; GSYM SUM_LMUL; GSYM SUM_RMUL] THEN + REWRITE_TAC[REAL_MUL_ASSOC] THEN REPEAT STRIP_TAC THEN + GEN_REWRITE_TAC RAND_CONV [SUM_SWAP_NUMSEG] THEN REWRITE_TAC[]);; + +let MATRIX_MUL_LZERO = prove + (`!A. (mat 0:real^N^M) ** (A:real^P^N) = mat 0`, + SIMP_TAC[matrix_mul; mat; CART_EQ; LAMBDA_BETA; COND_ID; REAL_MUL_LZERO] THEN + REWRITE_TAC[SUM_0]);; + +let MATRIX_MUL_RZERO = prove + (`!A. (A:real^N^M) ** (mat 0:real^P^N) = mat 0`, + SIMP_TAC[matrix_mul; mat; CART_EQ; LAMBDA_BETA; COND_ID; REAL_MUL_RZERO] THEN + REWRITE_TAC[SUM_0]);; + +let MATRIX_ADD_RDISTRIB = prove + (`!A:real^N^M B C:real^P^N. (A + B) ** C = A ** C + B ** C`, + SIMP_TAC[matrix_mul; matrix_add; CART_EQ; LAMBDA_BETA] THEN + REWRITE_TAC[REAL_ADD_RDISTRIB; SUM_ADD_NUMSEG]);; + +let MATRIX_SUB_LDISTRIB = prove + (`!A:real^N^M B C:real^P^N. A ** (B - C) = A ** B - A ** C`, + SIMP_TAC[matrix_mul; matrix_sub; CART_EQ; LAMBDA_BETA] THEN + REWRITE_TAC[REAL_SUB_LDISTRIB; SUM_SUB_NUMSEG]);; + +let MATRIX_SUB_RDISTRIB = prove + (`!A:real^N^M B C:real^P^N. (A - B) ** C = A ** C - B ** C`, + SIMP_TAC[matrix_mul; matrix_sub; CART_EQ; LAMBDA_BETA] THEN + REWRITE_TAC[REAL_SUB_RDISTRIB; SUM_SUB_NUMSEG]);; + +let MATRIX_MUL_LMUL = prove + (`!A:real^N^M B:real^P^N c. (c %% A) ** B = c %% (A ** B)`, + SIMP_TAC[matrix_mul; matrix_cmul; CART_EQ; LAMBDA_BETA] THEN + REWRITE_TAC[GSYM REAL_MUL_ASSOC; SUM_LMUL]);; + +let MATRIX_MUL_RMUL = prove + (`!A:real^N^M B:real^P^N c. A ** (c %% B) = c %% (A ** B)`, + SIMP_TAC[matrix_mul; matrix_cmul; CART_EQ; LAMBDA_BETA] THEN + ONCE_REWRITE_TAC[REAL_ARITH `A * c * B:real = c * A * B`] THEN + REWRITE_TAC[SUM_LMUL]);; + +let MATRIX_CMUL_ADD_LDISTRIB = prove + (`!A:real^N^M B c. c %% (A + B) = c %% A + c %% B`, + SIMP_TAC[matrix_cmul; matrix_add; CART_EQ; LAMBDA_BETA] THEN + REWRITE_TAC[REAL_ADD_LDISTRIB]);; + +let MATRIX_CMUL_SUB_LDISTRIB = prove + (`!A:real^N^M B c. c %% (A - B) = c %% A - c %% B`, + SIMP_TAC[matrix_cmul; matrix_sub; CART_EQ; LAMBDA_BETA] THEN + REWRITE_TAC[REAL_SUB_LDISTRIB]);; + +let MATRIX_CMUL_ADD_RDISTRIB = prove + (`!A:real^N^M b c. (b + c) %% A = b %% A + c %% A`, + SIMP_TAC[matrix_cmul; matrix_add; CART_EQ; LAMBDA_BETA] THEN + REWRITE_TAC[REAL_ADD_RDISTRIB]);; + +let MATRIX_CMUL_SUB_RDISTRIB = prove + (`!A:real^N^M b c. (b - c) %% A = b %% A - c %% A`, + SIMP_TAC[matrix_cmul; matrix_sub; CART_EQ; LAMBDA_BETA] THEN + REWRITE_TAC[REAL_SUB_RDISTRIB]);; + +let MATRIX_CMUL_RZERO = prove + (`!c. c %% mat 0 = mat 0`, + SIMP_TAC[matrix_cmul; mat; CART_EQ; LAMBDA_BETA; COND_ID; REAL_MUL_RZERO]);; + +let MATRIX_CMUL_LZERO = prove + (`!A. &0 %% A = mat 0`, + SIMP_TAC[matrix_cmul; mat; CART_EQ; LAMBDA_BETA; COND_ID; REAL_MUL_LZERO]);; + +let MATRIX_NEG_MINUS1 = prove + (`!A:real^N^M. --A = --(&1) %% A`, + REWRITE_TAC[matrix_cmul; matrix_neg; CART_EQ; LAMBDA_BETA] THEN + REWRITE_TAC[GSYM REAL_NEG_MINUS1]);; + +let MATRIX_ADD_AC = prove + (`(A:real^N^M) + B = B + A /\ + (A + B) + C = A + (B + C) /\ + A + (B + C) = B + (A + C)`, + MESON_TAC[MATRIX_ADD_ASSOC; MATRIX_ADD_SYM]);; + +let MATRIX_NEG_ADD = prove + (`!A B:real^N^M. --(A + B) = --A + --B`, + SIMP_TAC[matrix_neg; matrix_add; CART_EQ; LAMBDA_BETA; REAL_NEG_ADD]);; + +let MATRIX_NEG_SUB = prove + (`!A B:real^N^M. --(A - B) = B - A`, + SIMP_TAC[matrix_neg; matrix_sub; CART_EQ; LAMBDA_BETA; REAL_NEG_SUB]);; + +let MATRIX_NEG_0 = prove + (`--(mat 0) = mat 0`, + SIMP_TAC[CART_EQ; mat; matrix_neg; LAMBDA_BETA; REAL_NEG_0; COND_ID]);; + +let MATRIX_SUB_RZERO = prove + (`!A:real^N^M. A - mat 0 = A`, + SIMP_TAC[CART_EQ; mat; matrix_sub; LAMBDA_BETA; REAL_SUB_RZERO; COND_ID]);; + +let MATRIX_SUB_LZERO = prove + (`!A:real^N^M. mat 0 - A = --A`, + SIMP_TAC[CART_EQ; mat; matrix_sub; matrix_neg; + LAMBDA_BETA; REAL_SUB_LZERO; COND_ID]);; + +let MATRIX_NEG_EQ_0 = prove + (`!A:real^N^M. --A = mat 0 <=> A = mat 0`, + SIMP_TAC[CART_EQ; matrix_neg; mat; LAMBDA_BETA; REAL_NEG_EQ_0; COND_ID]);; + +let MATRIX_VECTOR_MUL_ASSOC = prove + (`!A:real^N^M B:real^P^N x:real^P. A ** B ** x = (A ** B) ** x`, + REPEAT GEN_TAC THEN + SIMP_TAC[matrix_mul; matrix_vector_mul; + CART_EQ; LAMBDA_BETA; GSYM SUM_LMUL; GSYM SUM_RMUL] THEN + REWRITE_TAC[REAL_MUL_ASSOC] THEN REPEAT STRIP_TAC THEN + GEN_REWRITE_TAC RAND_CONV [SUM_SWAP_NUMSEG] THEN REWRITE_TAC[]);; + +let MATRIX_VECTOR_MUL_LID = prove + (`!x:real^N. mat 1 ** x = x`, + REWRITE_TAC[matrix_vector_mul; + GEN_REWRITE_RULE (RAND_CONV o ONCE_DEPTH_CONV) [EQ_SYM_EQ] + (SPEC_ALL mat)] THEN + SIMP_TAC[CART_EQ; LAMBDA_BETA] THEN REWRITE_TAC[COND_RATOR; COND_RAND] THEN + SIMP_TAC[SUM_DELTA; REAL_MUL_LZERO; IN_NUMSEG; REAL_MUL_LID]);; + +let MATRIX_VECTOR_MUL_LZERO = prove + (`!x:real^N. mat 0 ** x = vec 0`, + SIMP_TAC[mat; matrix_vector_mul; CART_EQ; VEC_COMPONENT; LAMBDA_BETA; + COND_ID; REAL_MUL_LZERO; SUM_0]);; + +let MATRIX_VECTOR_MUL_RZERO = prove + (`!A:real^M^N. A ** vec 0 = vec 0`, + SIMP_TAC[mat; matrix_vector_mul; CART_EQ; VEC_COMPONENT; LAMBDA_BETA; + COND_ID; REAL_MUL_RZERO; SUM_0]);; + +let MATRIX_VECTOR_MUL_ADD_LDISTRIB = prove + (`!A:real^M^N x:real^M y. A ** (x + y) = A ** x + A ** y`, + SIMP_TAC[CART_EQ; matrix_vector_mul; VECTOR_ADD_COMPONENT; LAMBDA_BETA; + SUM_ADD_NUMSEG; REAL_ADD_LDISTRIB]);; + +let MATRIX_VECTOR_MUL_SUB_LDISTRIB = prove + (`!A:real^M^N x:real^M y. A ** (x - y) = A ** x - A ** y`, + SIMP_TAC[CART_EQ; matrix_vector_mul; VECTOR_SUB_COMPONENT; LAMBDA_BETA; + SUM_SUB_NUMSEG; REAL_SUB_LDISTRIB]);; + +let MATRIX_VECTOR_MUL_ADD_RDISTRIB = prove + (`!A:real^M^N B x. (A + B) ** x = (A ** x) + (B ** x)`, + SIMP_TAC[CART_EQ; matrix_vector_mul; matrix_add; LAMBDA_BETA; + VECTOR_ADD_COMPONENT; REAL_ADD_RDISTRIB; SUM_ADD_NUMSEG]);; + +let MATRIX_VECTOR_MUL_SUB_RDISTRIB = prove + (`!A:real^M^N B x. (A - B) ** x = (A ** x) - (B ** x)`, + SIMP_TAC[CART_EQ; matrix_vector_mul; matrix_sub; LAMBDA_BETA; + VECTOR_SUB_COMPONENT; REAL_SUB_RDISTRIB; SUM_SUB_NUMSEG]);; + +let MATRIX_VECTOR_MUL_RMUL = prove + (`!A:real^M^N x:real^M c. A ** (c % x) = c % (A ** x)`, + SIMP_TAC[CART_EQ; VECTOR_MUL_COMPONENT; matrix_vector_mul; LAMBDA_BETA] THEN + REWRITE_TAC[GSYM SUM_LMUL] THEN REWRITE_TAC[REAL_MUL_AC]);; + +let MATRIX_MUL_LNEG = prove + (`!A:real^N^M B:real^P^N. (--A) ** B = --(A ** B)`, + REWRITE_TAC[MATRIX_NEG_MINUS1; MATRIX_MUL_LMUL]);; + +let MATRIX_MUL_RNEG = prove + (`!A:real^N^M B:real^P^N. A ** --B = --(A ** B)`, + REWRITE_TAC[MATRIX_NEG_MINUS1; MATRIX_MUL_RMUL]);; + +let MATRIX_NEG_NEG = prove + (`!A:real^N^N. --(--A) = A`, + SIMP_TAC[CART_EQ; MATRIX_NEG_COMPONENT; REAL_NEG_NEG]);; + +let MATRIX_TRANSP_MUL = prove + (`!A B. transp(A ** B) = transp(B) ** transp(A)`, + SIMP_TAC[matrix_mul; transp; CART_EQ; LAMBDA_BETA] THEN + REWRITE_TAC[REAL_MUL_AC]);; + +let SYMMETRIC_MATRIX_MUL = prove + (`!A B:real^N^N. + transp(A) = A /\ transp(B) = B + ==> (transp(A ** B) = A ** B <=> A ** B = B ** A)`, + SIMP_TAC[MATRIX_TRANSP_MUL] THEN MESON_TAC[]);; + +let MATRIX_EQ = prove + (`!A:real^N^M B. (A = B) = !x:real^N. A ** x = B ** x`, + REPEAT GEN_TAC THEN EQ_TAC THENL [MESON_TAC[]; ALL_TAC] THEN + DISCH_THEN(MP_TAC o GEN `i:num` o SPEC `(basis i):real^N`) THEN + SIMP_TAC[CART_EQ; matrix_vector_mul; LAMBDA_BETA; basis] THEN + SIMP_TAC[SUM_DELTA; COND_RAND; REAL_MUL_RZERO] THEN + REWRITE_TAC[TAUT `(if p then b else T) <=> p ==> b`] THEN + SIMP_TAC[REAL_MUL_RID; IN_NUMSEG]);; + +let MATRIX_VECTOR_MUL_COMPONENT = prove + (`!A:real^N^M x k. + 1 <= k /\ k <= dimindex(:M) ==> ((A ** x)$k = (A$k) dot x)`, + SIMP_TAC[matrix_vector_mul; LAMBDA_BETA; dot]);; + +let DOT_LMUL_MATRIX = prove + (`!A:real^N^M x:real^M y:real^N. (x ** A) dot y = x dot (A ** y)`, + SIMP_TAC[dot; matrix_vector_mul; vector_matrix_mul; dot; LAMBDA_BETA] THEN + REPEAT GEN_TAC THEN REWRITE_TAC[GSYM SUM_LMUL] THEN + REWRITE_TAC[GSYM SUM_RMUL] THEN + GEN_REWRITE_TAC RAND_CONV [SUM_SWAP_NUMSEG] THEN REWRITE_TAC[REAL_MUL_AC]);; + +let TRANSP_MATRIX_CMUL = prove + (`!A:real^M^N c. transp(c %% A) = c %% transp A`, + SIMP_TAC[CART_EQ; transp; MATRIX_CMUL_COMPONENT; LAMBDA_BETA]);; + +let TRANSP_MATRIX_ADD = prove + (`!A B:real^N^M. transp(A + B) = transp A + transp B`, + SIMP_TAC[CART_EQ; transp; LAMBDA_BETA; matrix_add]);; + +let TRANSP_MATRIX_SUB = prove + (`!A B:real^N^M. transp(A - B) = transp A - transp B`, + SIMP_TAC[CART_EQ; transp; LAMBDA_BETA; matrix_sub]);; + +let TRANSP_MATRIX_NEG = prove + (`!A:real^N^M. transp(--A) = --(transp A)`, + SIMP_TAC[CART_EQ; transp; LAMBDA_BETA; matrix_neg]);; + +let TRANSP_MAT = prove + (`!n. transp(mat n) = mat n`, + SIMP_TAC[transp; mat; LAMBDA_BETA; CART_EQ; EQ_SYM_EQ]);; + +let TRANSP_TRANSP = prove + (`!A:real^N^M. transp(transp A) = A`, + SIMP_TAC[CART_EQ; transp; LAMBDA_BETA]);; + +let SYMMETRIX_MATRIX_CONJUGATE = prove + (`!A B:real^N^N. transp B = B + ==> transp(transp A ** B ** A) = transp A ** B ** A`, + SIMP_TAC[MATRIX_TRANSP_MUL; TRANSP_TRANSP; MATRIX_MUL_ASSOC]);; + +let TRANSP_EQ = prove + (`!A B:real^M^N. transp A = transp B <=> A = B`, + MESON_TAC[TRANSP_TRANSP]);; + +let ROW_TRANSP = prove + (`!A:real^N^M i. + 1 <= i /\ i <= dimindex(:N) ==> row i (transp A) = column i A`, + SIMP_TAC[row; column; transp; CART_EQ; LAMBDA_BETA]);; + +let COLUMN_TRANSP = prove + (`!A:real^N^M i. + 1 <= i /\ i <= dimindex(:M) ==> column i (transp A) = row i A`, + SIMP_TAC[row; column; transp; CART_EQ; LAMBDA_BETA]);; + +let ROWS_TRANSP = prove + (`!A:real^N^M. rows(transp A) = columns A`, + REWRITE_TAC[rows; columns; EXTENSION; IN_ELIM_THM] THEN + MESON_TAC[ROW_TRANSP]);; + +let COLUMNS_TRANSP = prove + (`!A:real^N^M. columns(transp A) = rows A`, + MESON_TAC[TRANSP_TRANSP; ROWS_TRANSP]);; + +let VECTOR_MATRIX_MUL_TRANSP = prove + (`!A:real^M^N x:real^N. x ** A = transp A ** x`, + REWRITE_TAC[matrix_vector_mul; vector_matrix_mul; transp] THEN + SIMP_TAC[LAMBDA_BETA; CART_EQ]);; + +let MATRIX_VECTOR_MUL_TRANSP = prove + (`!A:real^M^N x:real^M. A ** x = x ** transp A`, + REWRITE_TAC[VECTOR_MATRIX_MUL_TRANSP; TRANSP_TRANSP]);; + +let FINITE_ROWS = prove + (`!A:real^N^M. FINITE(rows A)`, + REWRITE_TAC[rows] THEN ONCE_REWRITE_TAC[SIMPLE_IMAGE_GEN] THEN + SIMP_TAC[GSYM numseg; FINITE_IMAGE; FINITE_NUMSEG]);; + +let FINITE_COLUMNS = prove + (`!A:real^N^M. FINITE(columns A)`, + REWRITE_TAC[columns] THEN ONCE_REWRITE_TAC[SIMPLE_IMAGE_GEN] THEN + SIMP_TAC[GSYM numseg; FINITE_IMAGE; FINITE_NUMSEG]);; + +let MATRIX_EQUAL_ROWS = prove + (`!A B:real^N^M. + A = B <=> !i. 1 <= i /\ i <= dimindex(:M) ==> row i A = row i B`, + SIMP_TAC[row; CART_EQ; LAMBDA_BETA]);; + +let MATRIX_EQUAL_COLUMNS = prove + (`!A B:real^N^M. + A = B <=> !i. 1 <= i /\ i <= dimindex(:N) ==> column i A = column i B`, + SIMP_TAC[column; CART_EQ; LAMBDA_BETA] THEN MESON_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* Two sometimes fruitful ways of looking at matrix-vector multiplication. *) +(* ------------------------------------------------------------------------- *) + +let MATRIX_MUL_DOT = prove + (`!A:real^N^M x. A ** x = lambda i. A$i dot x`, + REWRITE_TAC[matrix_vector_mul; dot] THEN SIMP_TAC[CART_EQ; LAMBDA_BETA]);; + +let MATRIX_MUL_VSUM = prove + (`!A:real^N^M x. A ** x = vsum(1..dimindex(:N)) (\i. x$i % column i A)`, + SIMP_TAC[matrix_vector_mul; CART_EQ; VSUM_COMPONENT; LAMBDA_BETA; + VECTOR_MUL_COMPONENT; column; REAL_MUL_AC]);; + +(* ------------------------------------------------------------------------- *) +(* Slightly gruesome lemmas: better to define sums over vectors really... *) +(* ------------------------------------------------------------------------- *) + +let VECTOR_COMPONENTWISE = prove + (`!x:real^N. + x = lambda j. sum(1..dimindex(:N)) + (\i. x$i * (basis i :real^N)$j)`, + SIMP_TAC[CART_EQ; LAMBDA_BETA; basis] THEN + ONCE_REWRITE_TAC[ARITH_RULE `(m:num = n) <=> (n = m)`] THEN + SIMP_TAC[COND_RAND; REAL_MUL_RZERO; SUM_DELTA; IN_NUMSEG] THEN + REWRITE_TAC[REAL_MUL_RID; COND_ID]);; + +let LINEAR_COMPONENTWISE_EXPANSION = prove + (`!f:real^M->real^N. + linear(f) + ==> !x j. 1 <= j /\ j <= dimindex(:N) + ==> (f x $j = + sum(1..dimindex(:M)) (\i. x$i * f(basis i)$j))`, + REWRITE_TAC[linear] THEN REPEAT STRIP_TAC THEN + GEN_REWRITE_TAC (LAND_CONV o LAND_CONV o RAND_CONV) + [VECTOR_COMPONENTWISE] THEN + SPEC_TAC(`dimindex(:M)`,`n:num`) THEN + INDUCT_TAC THEN REWRITE_TAC[SUM_CLAUSES_NUMSEG; ARITH] THENL + [REWRITE_TAC[GSYM vec] THEN + GEN_REWRITE_TAC (LAND_CONV o LAND_CONV o RAND_CONV) + [GSYM VECTOR_MUL_LZERO] THEN + ASM_REWRITE_TAC[] THEN REWRITE_TAC[VECTOR_MUL_LZERO] THEN + ASM_SIMP_TAC[vec; LAMBDA_BETA]; + REWRITE_TAC[ARITH_RULE `1 <= SUC n`] THEN + ASSUM_LIST(fun thl -> REWRITE_TAC(map GSYM thl)) THEN + SIMP_TAC[GSYM VECTOR_MUL_COMPONENT; + ASSUME `1 <= j`; ASSUME `j <= dimindex(:N)`] THEN + ASSUM_LIST(fun thl -> REWRITE_TAC(map GSYM thl)) THEN + SIMP_TAC[GSYM VECTOR_ADD_COMPONENT; + ASSUME `1 <= j`; ASSUME `j <= dimindex(:N)`] THEN + ASSUM_LIST(fun thl -> REWRITE_TAC(map GSYM thl)) THEN + AP_THM_TAC THEN AP_TERM_TAC THEN AP_TERM_TAC THEN + ASM_SIMP_TAC[CART_EQ; VECTOR_ADD_COMPONENT; LAMBDA_BETA] THEN + SIMP_TAC[VECTOR_MUL_COMPONENT]]);; + +(* ------------------------------------------------------------------------- *) +(* Inverse matrices (not necessarily square, but it's vacuous otherwise). *) +(* ------------------------------------------------------------------------- *) + +let invertible = new_definition + `invertible(A:real^N^M) <=> + ?A':real^M^N. (A ** A' = mat 1) /\ (A' ** A = mat 1)`;; + +let matrix_inv = new_definition + `matrix_inv(A:real^N^M) = + @A':real^M^N. (A ** A' = mat 1) /\ (A' ** A = mat 1)`;; + +let MATRIX_INV = prove + (`!A:real^N^M. + invertible A ==> A ** matrix_inv A = mat 1 /\ matrix_inv A ** A = mat 1`, + GEN_TAC THEN DISCH_TAC THEN REWRITE_TAC[matrix_inv; invertible] THEN + CONV_TAC SELECT_CONV THEN ASM_REWRITE_TAC[GSYM invertible]);; + +let MATRIX_INV_UNIQUE = prove + (`!A:real^N^M B. A ** B = mat 1 /\ B ** A = mat 1 ==> matrix_inv A = B`, + REPEAT STRIP_TAC THEN MP_TAC(ISPEC `A:real^N^M` MATRIX_INV) THEN + ANTS_TAC THENL [ASM_MESON_TAC[invertible]; ALL_TAC] THEN + DISCH_THEN(MP_TAC o + AP_TERM `(( ** ):real^M^N->real^M^M->real^M^N) B` o CONJUNCT1) THEN + ASM_REWRITE_TAC[MATRIX_MUL_ASSOC; MATRIX_MUL_LID; MATRIX_MUL_RID]);; + +let INVERTIBLE_NEG = prove + (`!A:real^N^M. invertible(--A) <=> invertible A`, + REWRITE_TAC[invertible] THEN + MESON_TAC[MATRIX_MUL_LNEG; MATRIX_MUL_RNEG; MATRIX_NEG_NEG]);; + +let MATRIX_INV_I = prove + (`matrix_inv(mat 1:real^N^N) = mat 1`, + MATCH_MP_TAC MATRIX_INV_UNIQUE THEN + REWRITE_TAC[MATRIX_MUL_LID]);; + +(* ------------------------------------------------------------------------- *) +(* Correspondence between matrices and linear operators. *) +(* ------------------------------------------------------------------------- *) + +let matrix = new_definition + `(matrix:(real^M->real^N)->real^M^N) f = lambda i j. f(basis j)$i`;; + +let MATRIX_VECTOR_MUL_LINEAR = prove + (`!A:real^N^M. linear(\x. A ** x)`, + REWRITE_TAC[linear; matrix_vector_mul] THEN + SIMP_TAC[CART_EQ; LAMBDA_BETA; VECTOR_ADD_COMPONENT; + VECTOR_MUL_COMPONENT] THEN + REWRITE_TAC[GSYM SUM_ADD_NUMSEG; GSYM SUM_LMUL; REAL_ADD_LDISTRIB] THEN + REWRITE_TAC[REAL_ADD_AC; REAL_MUL_AC]);; + +let MATRIX_WORKS = prove + (`!f:real^M->real^N. linear f ==> !x. matrix f ** x = f(x)`, + REWRITE_TAC[matrix; matrix_vector_mul] THEN + SIMP_TAC[CART_EQ; LAMBDA_BETA] THEN GEN_TAC THEN DISCH_TAC THEN + REPEAT GEN_TAC THEN DISCH_TAC THEN + ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN + ASM_SIMP_TAC[GSYM LINEAR_COMPONENTWISE_EXPANSION]);; + +let MATRIX_VECTOR_MUL = prove + (`!f:real^M->real^N. linear f ==> f = \x. matrix f ** x`, + SIMP_TAC[FUN_EQ_THM; MATRIX_WORKS]);; + +let MATRIX_OF_MATRIX_VECTOR_MUL = prove + (`!A:real^N^M. matrix(\x. A ** x) = A`, + SIMP_TAC[MATRIX_EQ; MATRIX_VECTOR_MUL_LINEAR; MATRIX_WORKS]);; + +let MATRIX_COMPOSE = prove + (`!f g. linear f /\ linear g ==> (matrix(g o f) = matrix g ** matrix f)`, + SIMP_TAC[MATRIX_EQ; MATRIX_WORKS; LINEAR_COMPOSE; + GSYM MATRIX_VECTOR_MUL_ASSOC; o_THM]);; + +let MATRIX_VECTOR_COLUMN = prove + (`!A:real^N^M x. + A ** x = vsum(1..dimindex(:N)) (\i. x$i % (transp A)$i)`, + REWRITE_TAC[matrix_vector_mul; transp] THEN + SIMP_TAC[CART_EQ; LAMBDA_BETA; VSUM_COMPONENT; VECTOR_MUL_COMPONENT] THEN + REWRITE_TAC[REAL_MUL_AC]);; + +let MATRIX_MUL_COMPONENT = prove + (`!i. 1 <= i /\ i <= dimindex(:N) + ==> ((A:real^N^N) ** (B:real^N^N))$i = transp B ** A$i`, + SIMP_TAC[matrix_mul; LAMBDA_BETA; matrix_vector_mul; vector_matrix_mul; + transp; CART_EQ] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC SUM_EQ_NUMSEG THEN + REWRITE_TAC[REAL_MUL_AC]);; + +let ADJOINT_MATRIX = prove + (`!A:real^N^M. adjoint(\x. A ** x) = (\x. transp A ** x)`, + GEN_TAC THEN CONV_TAC SYM_CONV THEN MATCH_MP_TAC ADJOINT_UNIQUE THEN + REWRITE_TAC[MATRIX_VECTOR_MUL_LINEAR] THEN REPEAT GEN_TAC THEN + SIMP_TAC[transp; dot; LAMBDA_BETA; matrix_vector_mul; + GSYM SUM_LMUL; GSYM SUM_RMUL] THEN + GEN_REWRITE_TAC LAND_CONV [SUM_SWAP_NUMSEG] THEN REWRITE_TAC[REAL_MUL_AC]);; + +let MATRIX_ADJOINT = prove + (`!f. linear f ==> matrix(adjoint f) = transp(matrix f)`, + GEN_TAC THEN DISCH_THEN + (fun th -> GEN_REWRITE_TAC (LAND_CONV o funpow 2 RAND_CONV) + [MATCH_MP MATRIX_VECTOR_MUL th]) THEN + REWRITE_TAC[ADJOINT_MATRIX; MATRIX_OF_MATRIX_VECTOR_MUL]);; + +let MATRIX_ID = prove + (`matrix(\x. x) = mat 1`, + SIMP_TAC[MATRIX_EQ; LINEAR_ID; MATRIX_WORKS; MATRIX_VECTOR_MUL_LID]);; + +let MATRIX_I = prove + (`matrix I = mat 1`, + REWRITE_TAC[I_DEF; MATRIX_ID]);; + +let LINEAR_EQ_MATRIX = prove + (`!f g. linear f /\ linear g /\ matrix f = matrix g ==> f = g`, + REPEAT STRIP_TAC THEN + REPEAT(FIRST_X_ASSUM(SUBST1_TAC o MATCH_MP MATRIX_VECTOR_MUL)) THEN + ASM_REWRITE_TAC[]);; + +let MATRIX_SELF_ADJOINT = prove + (`!f. linear f ==> (adjoint f = f <=> transp(matrix f) = matrix f)`, + SIMP_TAC[GSYM MATRIX_ADJOINT] THEN + MESON_TAC[LINEAR_EQ_MATRIX; ADJOINT_LINEAR]);; + +let LINEAR_MATRIX_EXISTS = prove + (`!f:real^M->real^N. linear f <=> ?A:real^M^N. f = \x. A ** x`, + GEN_TAC THEN EQ_TAC THEN + SIMP_TAC[MATRIX_VECTOR_MUL_LINEAR; LEFT_IMP_EXISTS_THM] THEN + DISCH_TAC THEN EXISTS_TAC `matrix(f:real^M->real^N)` THEN + ASM_SIMP_TAC[GSYM MATRIX_VECTOR_MUL]);; + +let LINEAR_1 = prove + (`!f:real^1->real^1. linear f <=> ?c. f = \x. c % x`, + SIMP_TAC[LINEAR_MATRIX_EXISTS; EXISTS_VECTOR_1] THEN + SIMP_TAC[FUN_EQ_THM; CART_EQ; FORALL_1; DIMINDEX_1; VECTOR_1; + matrix_vector_mul; SUM_1; CART_EQ; LAMBDA_BETA; + VECTOR_MUL_COMPONENT]);; + +let SYMMETRIC_MATRIX = prove + (`!A:real^N^N. transp A = A <=> adjoint(\x. A ** x) = \x. A ** x`, + SIMP_TAC[MATRIX_SELF_ADJOINT; MATRIX_VECTOR_MUL_LINEAR] THEN + REWRITE_TAC[MATRIX_OF_MATRIX_VECTOR_MUL]);; + +let SYMMETRIC_MATRIX_ORTHOGONAL_EIGENVECTORS = prove + (`!A:real^N^N v w a b. + transp A = A /\ A ** v = a % v /\ A ** w = b % w /\ ~(a = b) + ==> orthogonal v w`, + REPEAT GEN_TAC THEN REWRITE_TAC[SYMMETRIC_MATRIX] THEN + DISCH_THEN(MATCH_MP_TAC o MATCH_MP (ONCE_REWRITE_RULE[IMP_CONJ_ALT] + SELF_ADJOINT_ORTHOGONAL_EIGENVECTORS)) THEN + REWRITE_TAC[MATRIX_VECTOR_MUL_LINEAR]);; + +(* ------------------------------------------------------------------------- *) +(* Operator norm. *) +(* ------------------------------------------------------------------------- *) + +let onorm = new_definition + `onorm (f:real^M->real^N) = sup { norm(f x) | norm(x) = &1 }`;; + +let NORM_BOUND_GENERALIZE = prove + (`!f:real^M->real^N b. + linear f + ==> ((!x. (norm(x) = &1) ==> norm(f x) <= b) <=> + (!x. norm(f x) <= b * norm(x)))`, + REPEAT STRIP_TAC THEN EQ_TAC THEN DISCH_TAC THENL + [ALL_TAC; ASM_MESON_TAC[REAL_MUL_RID]] THEN + X_GEN_TAC `x:real^M` THEN ASM_CASES_TAC `x:real^M = vec 0` THENL + [ASM_REWRITE_TAC[NORM_0; REAL_MUL_RZERO] THEN + ASM_MESON_TAC[LINEAR_0; NORM_0; REAL_LE_REFL]; + ALL_TAC] THEN + ASM_SIMP_TAC[GSYM REAL_LE_LDIV_EQ; NORM_POS_LT; real_div] THEN + MATCH_MP_TAC(REAL_ARITH `abs(a * b) <= c ==> b * a <= c`) THEN + REWRITE_TAC[REAL_ABS_MUL; REAL_ABS_NORM; GSYM NORM_MUL] THEN + FIRST_ASSUM(fun th -> REWRITE_TAC[GSYM(MATCH_MP LINEAR_CMUL th)]) THEN + ASM_SIMP_TAC[NORM_MUL; REAL_ABS_INV; REAL_ABS_NORM; REAL_MUL_LINV; + NORM_EQ_0]);; + +let ONORM = prove + (`!f:real^M->real^N. + linear f + ==> (!x. norm(f x) <= onorm f * norm(x)) /\ + (!b. (!x. norm(f x) <= b * norm(x)) ==> onorm f <= b)`, + GEN_TAC THEN DISCH_TAC THEN + MP_TAC(SPEC `{ norm((f:real^M->real^N) x) | norm(x) = &1 }` SUP) THEN + SIMP_TAC[IN_ELIM_THM; LEFT_IMP_EXISTS_THM] THEN + ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN + REWRITE_TAC[LEFT_FORALL_IMP_THM; RIGHT_EXISTS_AND_THM; EXISTS_REFL] THEN + ASM_SIMP_TAC[NORM_BOUND_GENERALIZE; GSYM onorm; GSYM MEMBER_NOT_EMPTY] THEN + DISCH_THEN MATCH_MP_TAC THEN REWRITE_TAC[IN_ELIM_THM] THEN + ASM_MESON_TAC[VECTOR_CHOOSE_SIZE; LINEAR_BOUNDED; REAL_POS]);; + +let ONORM_POS_LE = prove + (`!f. linear f ==> &0 <= onorm f`, + MESON_TAC[ONORM; VECTOR_CHOOSE_SIZE; REAL_POS; REAL_MUL_RID; NORM_POS_LE; + REAL_LE_TRANS]);; + +let ONORM_EQ_0 = prove + (`!f:real^M->real^N. linear f ==> ((onorm f = &0) <=> (!x. f x = vec 0))`, + REPEAT STRIP_TAC THEN EQ_TAC THEN DISCH_TAC THEN + MP_TAC(SPEC `f:real^M->real^N` ONORM) THEN + ASM_SIMP_TAC[GSYM REAL_LE_ANTISYM; ONORM_POS_LE; NORM_0; REAL_MUL_LZERO; + NORM_LE_0; REAL_LE_REFL]);; + +let ONORM_CONST = prove + (`!y:real^N. onorm(\x:real^M. y) = norm(y)`, + GEN_TAC THEN REWRITE_TAC[onorm] THEN + MATCH_MP_TAC EQ_TRANS THEN EXISTS_TAC `sup {norm(y:real^N)}` THEN + CONJ_TAC THENL + [AP_TERM_TAC THEN MATCH_MP_TAC(SET_RULE + `(?x. P x) ==> {f y | x | P x} = {f y}`) THEN + EXISTS_TAC `basis 1 :real^M` THEN + SIMP_TAC[NORM_BASIS; DIMINDEX_GE_1; LE_REFL]; + MATCH_MP_TAC REAL_SUP_UNIQUE THEN SET_TAC[REAL_LE_REFL]]);; + +let ONORM_POS_LT = prove + (`!f. linear f ==> (&0 < onorm f <=> ~(!x. f x = vec 0))`, + SIMP_TAC[GSYM ONORM_EQ_0; ONORM_POS_LE; + REAL_ARITH `(&0 < x <=> ~(x = &0)) <=> &0 <= x`]);; + +let ONORM_COMPOSE = prove + (`!f g. linear f /\ linear g ==> onorm(f o g) <= onorm f * onorm g`, + MESON_TAC[ONORM; LINEAR_COMPOSE; o_THM; REAL_MUL_ASSOC; REAL_LE_TRANS; ONORM; + REAL_LE_LMUL; ONORM_POS_LE]);; + +let ONORM_NEG_LEMMA = prove + (`!f. linear f ==> onorm(\x. --(f x)) <= onorm f`, + REPEAT STRIP_TAC THEN + FIRST_ASSUM(STRIP_ASSUME_TAC o MATCH_MP ONORM o + MATCH_MP LINEAR_COMPOSE_NEG) THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_SIMP_TAC[NORM_NEG; ONORM]);; + +let ONORM_NEG = prove + (`!f:real^M->real^N. linear f ==> (onorm(\x. --(f x)) = onorm f)`, + REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM REAL_LE_ANTISYM] THEN + ASM_SIMP_TAC[ONORM_NEG_LEMMA] THEN + SUBGOAL_THEN `f:real^M->real^N = \x. --(--(f x))` + (fun th -> GEN_REWRITE_TAC (LAND_CONV o RAND_CONV) [th]) THEN + ASM_SIMP_TAC[ONORM_NEG_LEMMA; LINEAR_COMPOSE_NEG] THEN + REWRITE_TAC[VECTOR_NEG_NEG; ETA_AX]);; + +let ONORM_TRIANGLE = prove + (`!f:real^M->real^N g. + linear f /\ linear g ==> onorm(\x. f x + g x) <= onorm f + onorm g`, + REPEAT GEN_TAC THEN DISCH_TAC THEN + FIRST_ASSUM(MATCH_MP_TAC o CONJUNCT2 o MATCH_MP ONORM o MATCH_MP + LINEAR_COMPOSE_ADD) THEN + REWRITE_TAC[REAL_ADD_RDISTRIB] THEN + ASM_MESON_TAC[REAL_LE_ADD2; REAL_LE_TRANS; NORM_TRIANGLE; ONORM]);; + +let ONORM_TRIANGLE_LE = prove + (`!f g. linear f /\ linear g /\ onorm(f) + onorm(g) <= e + ==> onorm(\x. f x + g x) <= e`, + MESON_TAC[REAL_LE_TRANS; ONORM_TRIANGLE]);; + +let ONORM_TRIANGLE_LT = prove + (`!f g. linear f /\ linear g /\ onorm(f) + onorm(g) < e + ==> onorm(\x. f x + g x) < e`, + MESON_TAC[REAL_LET_TRANS; ONORM_TRIANGLE]);; + +let ONORM_ID = prove + (`onorm(\x:real^N. x) = &1`, + REWRITE_TAC[onorm] THEN + SUBGOAL_THEN `{norm(x:real^N) | norm x = &1} = {&1}` + (fun th -> REWRITE_TAC[th; SUP_SING]) THEN + SUBGOAL_THEN `norm(basis 1:real^N) = &1` MP_TAC THENL + [SIMP_TAC[NORM_BASIS; DIMINDEX_GE_1; LE_REFL]; SET_TAC[]]);; + +let ONORM_I = prove + (`onorm(I:real^N->real^N) = &1`, + REWRITE_TAC[I_DEF; ONORM_ID]);; + +(* ------------------------------------------------------------------------- *) +(* It's handy to "lift" from R to R^1 and "drop" from R^1 to R. *) +(* ------------------------------------------------------------------------- *) + +let lift = new_definition + `(lift:real->real^1) x = lambda i. x`;; + +let drop = new_definition + `(drop:real^1->real) x = x$1`;; + +let LIFT_COMPONENT = prove + (`!x. (lift x)$1 = x`, + SIMP_TAC[lift; LAMBDA_BETA; DIMINDEX_1; LE_ANTISYM]);; + +let LIFT_DROP = prove + (`(!x. lift(drop x) = x) /\ (!x. drop(lift x) = x)`, + SIMP_TAC[lift; drop; CART_EQ; LAMBDA_BETA; DIMINDEX_1; LE_ANTISYM]);; + +let IMAGE_LIFT_DROP = prove + (`(!s. IMAGE (lift o drop) s = s) /\ (!s. IMAGE (drop o lift) s = s)`, + REWRITE_TAC[o_DEF; LIFT_DROP] THEN SET_TAC[]);; + +let IN_IMAGE_LIFT_DROP = prove + (`(!x s. x IN IMAGE lift s <=> drop x IN s) /\ + (!x s. x IN IMAGE drop s <=> lift x IN s)`, + REWRITE_TAC[IN_IMAGE] THEN MESON_TAC[LIFT_DROP]);; + +let FORALL_LIFT = prove + (`(!x. P x) = (!x. P(lift x))`, + MESON_TAC[LIFT_DROP]);; + +let EXISTS_LIFT = prove + (`(?x. P x) = (?x. P(lift x))`, + MESON_TAC[LIFT_DROP]);; + +let FORALL_DROP = prove + (`(!x. P x) = (!x. P(drop x))`, + MESON_TAC[LIFT_DROP]);; + +let EXISTS_DROP = prove + (`(?x. P x) = (?x. P(drop x))`, + MESON_TAC[LIFT_DROP]);; + +let FORALL_LIFT_FUN = prove + (`!P:(A->real^1)->bool. (!f. P f) <=> (!f. P(lift o f))`, + GEN_TAC THEN EQ_TAC THEN SIMP_TAC[] THEN DISCH_TAC THEN + X_GEN_TAC `f:A->real^1` THEN + FIRST_X_ASSUM(MP_TAC o SPEC `drop o (f:A->real^1)`) THEN + REWRITE_TAC[o_DEF; LIFT_DROP; ETA_AX]);; + +let FORALL_DROP_FUN = prove + (`!P:(A->real)->bool. (!f. P f) <=> (!f. P(drop o f))`, + REWRITE_TAC[FORALL_LIFT_FUN; o_DEF; LIFT_DROP; ETA_AX]);; + +let EXISTS_LIFT_FUN = prove + (`!P:(A->real^1)->bool. (?f. P f) <=> (?f. P(lift o f))`, + ONCE_REWRITE_TAC[MESON[] `(?x. P x) <=> ~(!x. ~P x)`] THEN + REWRITE_TAC[FORALL_LIFT_FUN]);; + +let EXISTS_DROP_FUN = prove + (`!P:(A->real)->bool. (?f. P f) <=> (?f. P(drop o f))`, + ONCE_REWRITE_TAC[MESON[] `(?x. P x) <=> ~(!x. ~P x)`] THEN + REWRITE_TAC[FORALL_DROP_FUN]);; + +let LIFT_EQ = prove + (`!x y. (lift x = lift y) <=> (x = y)`, + MESON_TAC[LIFT_DROP]);; + +let DROP_EQ = prove + (`!x y. (drop x = drop y) <=> (x = y)`, + MESON_TAC[LIFT_DROP]);; + +let LIFT_IN_IMAGE_LIFT = prove + (`!x s. (lift x) IN (IMAGE lift s) <=> x IN s`, + REWRITE_TAC[IN_IMAGE] THEN MESON_TAC[LIFT_DROP]);; + +let FORALL_LIFT_IMAGE = prove + (`!P. (!s. P s) <=> (!s. P(IMAGE lift s))`, + MESON_TAC[IMAGE_LIFT_DROP; IMAGE_o]);; + +let EXISTS_LIFT_IMAGE = prove + (`!P. (?s. P s) <=> (?s. P(IMAGE lift s))`, + MESON_TAC[IMAGE_LIFT_DROP; IMAGE_o]);; + +let SUBSET_LIFT_IMAGE = prove + (`!s t. IMAGE lift s SUBSET IMAGE lift t <=> s SUBSET t`, + REPEAT GEN_TAC THEN EQ_TAC THEN REWRITE_TAC[IMAGE_SUBSET] THEN + DISCH_THEN(MP_TAC o ISPEC `drop` o MATCH_MP IMAGE_SUBSET) THEN + REWRITE_TAC[GSYM IMAGE_o; IMAGE_LIFT_DROP]);; + +let FORALL_DROP_IMAGE = prove + (`!P. (!s. P s) <=> (!s. P(IMAGE drop s))`, + MESON_TAC[IMAGE_LIFT_DROP; IMAGE_o]);; + +let EXISTS_DROP_IMAGE = prove + (`!P. (?s. P s) <=> (?s. P(IMAGE drop s))`, + MESON_TAC[IMAGE_LIFT_DROP; IMAGE_o]);; + +let SUBSET_DROP_IMAGE = prove + (`!s t. IMAGE drop s SUBSET IMAGE drop t <=> s SUBSET t`, + REPEAT GEN_TAC THEN EQ_TAC THEN REWRITE_TAC[IMAGE_SUBSET] THEN + DISCH_THEN(MP_TAC o ISPEC `lift` o MATCH_MP IMAGE_SUBSET) THEN + REWRITE_TAC[GSYM IMAGE_o; IMAGE_LIFT_DROP]);; + +let DROP_IN_IMAGE_DROP = prove + (`!x s. (drop x) IN (IMAGE drop s) <=> x IN s`, + REWRITE_TAC[IN_IMAGE] THEN MESON_TAC[LIFT_DROP]);; + +let LIFT_NUM = prove + (`!n. lift(&n) = vec n`, + SIMP_TAC[CART_EQ; lift; vec; LAMBDA_BETA]);; + +let LIFT_ADD = prove + (`!x y. lift(x + y) = lift x + lift y`, + SIMP_TAC[CART_EQ; lift; LAMBDA_BETA; VECTOR_ADD_COMPONENT]);; + +let LIFT_SUB = prove + (`!x y. lift(x - y) = lift x - lift y`, + SIMP_TAC[CART_EQ; lift; LAMBDA_BETA; VECTOR_SUB_COMPONENT]);; + +let LIFT_CMUL = prove + (`!x c. lift(c * x) = c % lift(x)`, + SIMP_TAC[CART_EQ; lift; LAMBDA_BETA; VECTOR_MUL_COMPONENT]);; + +let LIFT_NEG = prove + (`!x. lift(--x) = --(lift x)`, + SIMP_TAC[CART_EQ; lift; LAMBDA_BETA; VECTOR_NEG_COMPONENT]);; + +let LIFT_EQ_CMUL = prove + (`!x. lift x = x % vec 1`, + REWRITE_TAC[GSYM LIFT_NUM; GSYM LIFT_CMUL; REAL_MUL_RID]);; + +let LIFT_SUM = prove + (`!k x. FINITE k ==> (lift(sum k x) = vsum k (lift o x))`, + REWRITE_TAC[RIGHT_FORALL_IMP_THM] THEN + MATCH_MP_TAC FINITE_INDUCT_STRONG THEN + SIMP_TAC[SUM_CLAUSES; VSUM_CLAUSES; o_THM; LIFT_ADD; LIFT_NUM]);; + +let DROP_LAMBDA = prove + (`!x. drop(lambda i. x i) = x 1`, + SIMP_TAC[drop; LAMBDA_BETA; DIMINDEX_1; LE_REFL]);; + +let DROP_VEC = prove + (`!n. drop(vec n) = &n`, + MESON_TAC[LIFT_DROP; LIFT_NUM]);; + +let DROP_ADD = prove + (`!x y. drop(x + y) = drop x + drop y`, + MESON_TAC[LIFT_DROP; LIFT_ADD]);; + +let DROP_SUB = prove + (`!x y. drop(x - y) = drop x - drop y`, + MESON_TAC[LIFT_DROP; LIFT_SUB]);; + +let DROP_CMUL = prove + (`!x c. drop(c % x) = c * drop(x)`, + MESON_TAC[LIFT_DROP; LIFT_CMUL]);; + +let DROP_NEG = prove + (`!x. drop(--x) = --(drop x)`, + MESON_TAC[LIFT_DROP; LIFT_NEG]);; + +let DROP_VSUM = prove + (`!k x. FINITE k ==> (drop(vsum k x) = sum k (drop o x))`, + REWRITE_TAC[RIGHT_FORALL_IMP_THM] THEN + MATCH_MP_TAC FINITE_INDUCT_STRONG THEN + SIMP_TAC[SUM_CLAUSES; VSUM_CLAUSES; o_THM; DROP_ADD; DROP_VEC]);; + +let NORM_1 = prove + (`!x. norm x = abs(drop x)`, + REWRITE_TAC[drop; NORM_REAL]);; + +let NORM_1_POS = prove + (`!x. &0 <= drop x ==> norm x = drop x`, + SIMP_TAC[NORM_1; real_abs]);; + +let NORM_LIFT = prove + (`!x. norm(lift x) = abs(x)`, + SIMP_TAC[lift; NORM_REAL; LIFT_COMPONENT]);; + +let DIST_LIFT = prove + (`!x y. dist(lift x,lift y) = abs(x - y)`, + REWRITE_TAC[DIST_REAL; LIFT_COMPONENT]);; + +let ABS_DROP = prove + (`!x. norm x = abs(drop x)`, + REWRITE_TAC[FORALL_LIFT; LIFT_DROP; NORM_LIFT]);; + +let LINEAR_VMUL_DROP = prove + (`!f v. linear f ==> linear (\x. drop(f x) % v)`, + SIMP_TAC[drop; LINEAR_VMUL_COMPONENT; DIMINDEX_1; LE_REFL]);; + +let LINEAR_FROM_REALS = prove + (`!f:real^1->real^N. linear f ==> f = \x. drop x % column 1 (matrix f)`, + GEN_TAC THEN REWRITE_TAC[FUN_EQ_THM] THEN + DISCH_THEN(fun th -> REWRITE_TAC[GSYM(MATCH_MP MATRIX_WORKS th)]) THEN + SIMP_TAC[CART_EQ; matrix_vector_mul; vector_mul; LAMBDA_BETA; + DIMINDEX_1; SUM_SING_NUMSEG; drop; column] THEN + REWRITE_TAC[REAL_MUL_AC]);; + +let LINEAR_TO_REALS = prove + (`!f:real^N->real^1. linear f ==> f = \x. lift(row 1 (matrix f) dot x)`, + GEN_TAC THEN REWRITE_TAC[FUN_EQ_THM] THEN + DISCH_THEN(fun th -> REWRITE_TAC[GSYM(MATCH_MP MATRIX_WORKS th)]) THEN + SIMP_TAC[CART_EQ; matrix_vector_mul; dot; LAMBDA_BETA; + DIMINDEX_1; SUM_SING_NUMSEG; lift; row; LE_ANTISYM]);; + +let DROP_EQ_0 = prove + (`!x. drop x = &0 <=> x = vec 0`, + REWRITE_TAC[GSYM DROP_EQ; DROP_VEC]);; + +let VSUM_REAL = prove + (`!f s. FINITE s ==> vsum s f = lift(sum s (drop o f))`, + SIMP_TAC[LIFT_SUM; o_DEF; LIFT_DROP; ETA_AX]);; + +let DROP_WLOG_LE = prove + (`(!x y. P x y <=> P y x) /\ (!x y. drop x <= drop y ==> P x y) + ==> (!x y. P x y)`, + MESON_TAC[REAL_LE_TOTAL]);; + +let IMAGE_LIFT_UNIV = prove + (`IMAGE lift (:real) = (:real^1)`, + REWRITE_TAC[EXTENSION; IN_IMAGE; IN_UNIV] THEN MESON_TAC[LIFT_DROP]);; + +let IMAGE_DROP_UNIV = prove + (`IMAGE drop (:real^1) = (:real)`, + REWRITE_TAC[EXTENSION; IN_IMAGE; IN_UNIV] THEN MESON_TAC[LIFT_DROP]);; + +let SUM_VSUM = prove + (`!f s. FINITE s ==> sum s f = drop(vsum s (lift o f))`, + SIMP_TAC[VSUM_REAL; o_DEF; LIFT_DROP; ETA_AX]);; + +let LINEAR_LIFT_DOT = prove + (`!a. linear(\x. lift(a dot x))`, + REWRITE_TAC[linear; DOT_RMUL; DOT_RADD; LIFT_ADD; LIFT_CMUL]);; + +let LINEAR_LIFT_COMPONENT = prove + (`!k. linear(\x:real^N. lift(x$k))`, + REPEAT GEN_TAC THEN + SUBGOAL_THEN `?j. 1 <= j /\ j <= dimindex(:N) /\ !z:real^N. z$k = z$j` + CHOOSE_TAC THENL + [REWRITE_TAC[FINITE_INDEX_INRANGE]; + MP_TAC(ISPEC `basis j:real^N` LINEAR_LIFT_DOT) THEN + ASM_SIMP_TAC[DOT_BASIS]]);; + +let BILINEAR_DROP_MUL = prove + (`bilinear (\x y:real^N. drop x % y)`, + REWRITE_TAC[bilinear; linear] THEN + REWRITE_TAC[DROP_ADD; DROP_CMUL] THEN VECTOR_ARITH_TAC);; + +let LINEAR_COMPONENTWISE = prove + (`!f:real^M->real^N. + linear f <=> + !i. 1 <= i /\ i <= dimindex(:N) ==> linear(\x. lift(f(x)$i))`, + REPEAT GEN_TAC THEN REWRITE_TAC[linear] THEN + GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [CART_EQ] THEN + SIMP_TAC[GSYM LIFT_CMUL; GSYM LIFT_ADD; LIFT_EQ] THEN + REWRITE_TAC[VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT] THEN + MESON_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* Pasting vectors. *) +(* ------------------------------------------------------------------------- *) + +let LINEAR_FSTCART = prove + (`linear fstcart`, + SIMP_TAC[linear; fstcart; CART_EQ; LAMBDA_BETA; VECTOR_ADD_COMPONENT; + VECTOR_MUL_COMPONENT; DIMINDEX_FINITE_SUM; + ARITH_RULE `x <= a ==> x <= a + b:num`]);; + +let LINEAR_SNDCART = prove + (`linear sndcart`, + SIMP_TAC[linear; sndcart; CART_EQ; LAMBDA_BETA; VECTOR_ADD_COMPONENT; + VECTOR_MUL_COMPONENT; DIMINDEX_FINITE_SUM; + ARITH_RULE `x <= a ==> x <= a + b:num`; + ARITH_RULE `x <= b ==> x + a <= a + b:num`]);; + +let FSTCART_VEC = prove + (`!n. fstcart(vec n) = vec n`, + SIMP_TAC[vec; fstcart; LAMBDA_BETA; CART_EQ; DIMINDEX_FINITE_SUM; + ARITH_RULE `m <= n:num ==> m <= n + p`]);; + +let FSTCART_ADD = prove + (`!x:real^(M,N)finite_sum y. fstcart(x + y) = fstcart(x) + fstcart(y)`, + REWRITE_TAC[REWRITE_RULE[linear] LINEAR_FSTCART]);; + +let FSTCART_CMUL = prove + (`!x:real^(M,N)finite_sum c. fstcart(c % x) = c % fstcart(x)`, + REWRITE_TAC[REWRITE_RULE[linear] LINEAR_FSTCART]);; + +let FSTCART_NEG = prove + (`!x:real^(M,N)finite_sum. --(fstcart x) = fstcart(--x)`, + ONCE_REWRITE_TAC[VECTOR_ARITH `--x = --(&1) % x`] THEN + REWRITE_TAC[FSTCART_CMUL]);; + +let FSTCART_SUB = prove + (`!x:real^(M,N)finite_sum y. fstcart(x - y) = fstcart(x) - fstcart(y)`, + REWRITE_TAC[VECTOR_SUB; FSTCART_NEG; FSTCART_ADD]);; + +let FSTCART_VSUM = prove + (`!k x. FINITE k ==> (fstcart(vsum k x) = vsum k (\i. fstcart(x i)))`, + REWRITE_TAC[RIGHT_FORALL_IMP_THM] THEN + MATCH_MP_TAC FINITE_INDUCT_STRONG THEN + SIMP_TAC[VSUM_CLAUSES; FINITE_RULES; FSTCART_ADD; FSTCART_VEC]);; + +let SNDCART_VEC = prove + (`!n. sndcart(vec n) = vec n`, + SIMP_TAC[vec; sndcart; LAMBDA_BETA; CART_EQ; DIMINDEX_FINITE_SUM; + ARITH_RULE `x <= a ==> x <= a + b:num`; + ARITH_RULE `x <= b ==> x + a <= a + b:num`]);; + +let SNDCART_ADD = prove + (`!x:real^(M,N)finite_sum y. sndcart(x + y) = sndcart(x) + sndcart(y)`, + REWRITE_TAC[REWRITE_RULE[linear] LINEAR_SNDCART]);; + +let SNDCART_CMUL = prove + (`!x:real^(M,N)finite_sum c. sndcart(c % x) = c % sndcart(x)`, + REWRITE_TAC[REWRITE_RULE[linear] LINEAR_SNDCART]);; + +let SNDCART_NEG = prove + (`!x:real^(M,N)finite_sum. --(sndcart x) = sndcart(--x)`, + ONCE_REWRITE_TAC[VECTOR_ARITH `--x = --(&1) % x`] THEN + REWRITE_TAC[SNDCART_CMUL]);; + +let SNDCART_SUB = prove + (`!x:real^(M,N)finite_sum y. sndcart(x - y) = sndcart(x) - sndcart(y)`, + REWRITE_TAC[VECTOR_SUB; SNDCART_NEG; SNDCART_ADD]);; + +let SNDCART_VSUM = prove + (`!k x. FINITE k ==> (sndcart(vsum k x) = vsum k (\i. sndcart(x i)))`, + REWRITE_TAC[RIGHT_FORALL_IMP_THM] THEN + MATCH_MP_TAC FINITE_INDUCT_STRONG THEN + SIMP_TAC[VSUM_CLAUSES; FINITE_RULES; SNDCART_ADD; SNDCART_VEC]);; + +let PASTECART_VEC = prove + (`!n. pastecart (vec n) (vec n) = vec n`, + REWRITE_TAC[PASTECART_EQ; FSTCART_VEC; SNDCART_VEC; + FSTCART_PASTECART; SNDCART_PASTECART]);; + +let PASTECART_ADD = prove + (`!x1 y1 x2:real^M y2:real^N. + pastecart x1 y1 + pastecart x2 y2 = pastecart (x1 + x2) (y1 + y2)`, + REWRITE_TAC[PASTECART_EQ; FSTCART_ADD; SNDCART_ADD; + FSTCART_PASTECART; SNDCART_PASTECART]);; + +let PASTECART_CMUL = prove + (`!x1 y1 c. pastecart (c % x1) (c % y1) = c % pastecart x1 y1`, + REWRITE_TAC[PASTECART_EQ; FSTCART_CMUL; SNDCART_CMUL; + FSTCART_PASTECART; SNDCART_PASTECART]);; + +let PASTECART_NEG = prove + (`!x:real^M y:real^N. pastecart (--x) (--y) = --(pastecart x y)`, + ONCE_REWRITE_TAC[VECTOR_ARITH `--x = --(&1) % x`] THEN + REWRITE_TAC[PASTECART_CMUL]);; + +let PASTECART_SUB = prove + (`!x1 y1 x2:real^M y2:real^N. + pastecart x1 y1 - pastecart x2 y2 = pastecart (x1 - x2) (y1 - y2)`, + REWRITE_TAC[VECTOR_SUB; GSYM PASTECART_NEG; PASTECART_ADD]);; + +let PASTECART_VSUM = prove + (`!k x y. FINITE k ==> (pastecart (vsum k x) (vsum k y) = + vsum k (\i. pastecart (x i) (y i)))`, + SIMP_TAC[PASTECART_EQ; FSTCART_VSUM; SNDCART_VSUM; + FSTCART_PASTECART; SNDCART_PASTECART; ETA_AX]);; + +let PASTECART_EQ_VEC = prove + (`!x y n. pastecart x y = vec n <=> x = vec n /\ y = vec n`, + REWRITE_TAC[PASTECART_EQ; FSTCART_VEC; SNDCART_VEC; + FSTCART_PASTECART; SNDCART_PASTECART]);; + +let NORM_FSTCART = prove + (`!x. norm(fstcart x) <= norm x`, + GEN_TAC THEN + GEN_REWRITE_TAC (RAND_CONV o RAND_CONV) [GSYM PASTECART_FST_SND] THEN + SIMP_TAC[SQRT_MONO_LE_EQ; DOT_POS_LE; vector_norm] THEN + SIMP_TAC[pastecart; dot; DIMINDEX_FINITE_SUM; LAMBDA_BETA; DIMINDEX_NONZERO; + SUM_ADD_SPLIT; REAL_LE_ADDR; SUM_POS_LE; FINITE_NUMSEG; + REAL_LE_SQUARE; ARITH_RULE `x <= a ==> x <= a + b:num`; + ARITH_RULE `~(d = 0) ==> 1 <= d + 1`]);; + +let DIST_FSTCART = prove + (`!x y. dist(fstcart x,fstcart y) <= dist(x,y)`, + REWRITE_TAC[dist; GSYM FSTCART_SUB; NORM_FSTCART]);; + +let NORM_SNDCART = prove + (`!x. norm(sndcart x) <= norm x`, + GEN_TAC THEN + GEN_REWRITE_TAC (RAND_CONV o RAND_CONV) [GSYM PASTECART_FST_SND] THEN + SIMP_TAC[SQRT_MONO_LE_EQ; DOT_POS_LE; vector_norm] THEN + SIMP_TAC[pastecart; dot; DIMINDEX_FINITE_SUM; LAMBDA_BETA; DIMINDEX_NONZERO; + SUM_ADD_SPLIT; ARITH_RULE `x <= a ==> x <= a + b:num`; + ARITH_RULE `~(d = 0) ==> 1 <= d + 1`] THEN + ONCE_REWRITE_TAC[ADD_SYM] THEN REWRITE_TAC[NUMSEG_OFFSET_IMAGE] THEN + SIMP_TAC[SUM_IMAGE; FINITE_NUMSEG; EQ_ADD_RCANCEL; o_DEF; ADD_SUB] THEN + SIMP_TAC[ARITH_RULE `1 <= x ==> ~(x + a <= a)`; SUM_POS_LE; FINITE_NUMSEG; + REAL_LE_ADDL; REAL_LE_SQUARE]);; + +let DIST_SNDCART = prove + (`!x y. dist(sndcart x,sndcart y) <= dist(x,y)`, + REWRITE_TAC[dist; GSYM SNDCART_SUB; NORM_SNDCART]);; + +let DOT_PASTECART = prove + (`!x1 x2 y1 y2. (pastecart x1 x2) dot (pastecart y1 y2) = + x1 dot y1 + x2 dot y2`, + SIMP_TAC[pastecart; dot; LAMBDA_BETA; DIMINDEX_FINITE_SUM] THEN + SIMP_TAC[SUM_ADD_SPLIT; ARITH_RULE `~(d = 0) ==> 1 <= d + 1`; + DIMINDEX_NONZERO; REAL_LE_LADD] THEN + ONCE_REWRITE_TAC[ADD_SYM] THEN REWRITE_TAC[NUMSEG_OFFSET_IMAGE] THEN + SIMP_TAC[SUM_IMAGE; FINITE_NUMSEG; EQ_ADD_RCANCEL; o_DEF; ADD_SUB] THEN + SIMP_TAC[ARITH_RULE `1 <= x ==> ~(x + a <= a)`; REAL_LE_REFL]);; + +let SQNORM_PASTECART = prove + (`!x y. norm(pastecart x y) pow 2 = norm(x) pow 2 + norm(y) pow 2`, + REWRITE_TAC[NORM_POW_2; DOT_PASTECART]);; + +let NORM_PASTECART = prove + (`!x y. norm(pastecart x y) = sqrt(norm(x) pow 2 + norm(y) pow 2)`, + REWRITE_TAC[NORM_EQ_SQUARE] THEN + SIMP_TAC[SQRT_POS_LE; SQRT_POW_2; REAL_LE_ADD; REAL_LE_POW_2] THEN + REWRITE_TAC[DOT_PASTECART; NORM_POW_2]);; + +let NORM_PASTECART_LE = prove + (`!x y. norm(pastecart x y) <= norm(x) + norm(y)`, + REPEAT GEN_TAC THEN MATCH_MP_TAC TRIANGLE_LEMMA THEN + REWRITE_TAC[NORM_POS_LE; NORM_POW_2; DOT_PASTECART; REAL_LE_REFL]);; + +let NORM_LE_PASTECART = prove + (`!x:real^M y:real^N. + norm(x) <= norm(pastecart x y) /\ + norm(y) <= norm(pastecart x y)`, + REPEAT GEN_TAC THEN REWRITE_TAC[NORM_PASTECART] THEN CONJ_TAC THEN + MATCH_MP_TAC REAL_LE_RSQRT THEN + REWRITE_TAC[REAL_LE_ADDL; REAL_LE_ADDR; REAL_LE_POW_2]);; + +let NORM_PASTECART_0 = prove + (`(!x. norm(pastecart x (vec 0)) = norm x) /\ + (!y. norm(pastecart (vec 0) y) = norm y)`, + REWRITE_TAC[NORM_EQ_SQUARE; NORM_POW_2; NORM_POS_LE] THEN + REWRITE_TAC[DOT_PASTECART; DOT_LZERO; REAL_ADD_LID; REAL_ADD_RID]);; + +let DIST_PASTECART_CANCEL = prove + (`(!x x' y. dist(pastecart x y,pastecart x' y) = dist(x,x')) /\ + (!x y y'. dist(pastecart x y,pastecart x y') = dist(y,y'))`, + REWRITE_TAC[dist; PASTECART_SUB; VECTOR_SUB_REFL; NORM_PASTECART_0]);; + +let LINEAR_PASTECART = prove + (`!f:real^M->real^N g:real^M->real^P. + linear f /\ linear g ==> linear (\x. pastecart (f x) (g x))`, + SIMP_TAC[linear; PASTECART_ADD; GSYM PASTECART_CMUL]);; + +(* ------------------------------------------------------------------------- *) +(* A bit of linear algebra. *) +(* ------------------------------------------------------------------------- *) + +let subspace = new_definition + `subspace s <=> + vec(0) IN s /\ + (!x y. x IN s /\ y IN s ==> (x + y) IN s) /\ + (!c x. x IN s ==> (c % x) IN s)`;; + +let span = new_definition + `span s = subspace hull s`;; + +let dependent = new_definition + `dependent s <=> ?a. a IN s /\ a IN span(s DELETE a)`;; + +let independent = new_definition + `independent s <=> ~(dependent s)`;; + +(* ------------------------------------------------------------------------- *) +(* Closure properties of subspaces. *) +(* ------------------------------------------------------------------------- *) + +let SUBSPACE_UNIV = prove + (`subspace(UNIV:real^N->bool)`, + REWRITE_TAC[subspace; IN_UNIV]);; + +let SUBSPACE_IMP_NONEMPTY = prove + (`!s. subspace s ==> ~(s = {})`, + REWRITE_TAC[subspace] THEN SET_TAC[]);; + +let SUBSPACE_0 = prove + (`subspace s ==> vec(0) IN s`, + SIMP_TAC[subspace]);; + +let SUBSPACE_ADD = prove + (`!x y s. subspace s /\ x IN s /\ y IN s ==> (x + y) IN s`, + SIMP_TAC[subspace]);; + +let SUBSPACE_MUL = prove + (`!x c s. subspace s /\ x IN s ==> (c % x) IN s`, + SIMP_TAC[subspace]);; + +let SUBSPACE_NEG = prove + (`!x s. subspace s /\ x IN s ==> (--x) IN s`, + SIMP_TAC[VECTOR_ARITH `--x = --(&1) % x`; SUBSPACE_MUL]);; + +let SUBSPACE_SUB = prove + (`!x y s. subspace s /\ x IN s /\ y IN s ==> (x - y) IN s`, + SIMP_TAC[VECTOR_SUB; SUBSPACE_ADD; SUBSPACE_NEG]);; + +let SUBSPACE_VSUM = prove + (`!s f t. subspace s /\ FINITE t /\ (!x. x IN t ==> f(x) IN s) + ==> (vsum t f) IN s`, + REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN + GEN_TAC THEN DISCH_TAC THEN GEN_TAC THEN + MATCH_MP_TAC FINITE_INDUCT_STRONG THEN + ASM_SIMP_TAC[VSUM_CLAUSES; SUBSPACE_0; IN_INSERT; SUBSPACE_ADD]);; + +let SUBSPACE_LINEAR_IMAGE = prove + (`!f s. linear f /\ subspace s ==> subspace(IMAGE f s)`, + REWRITE_TAC[subspace; IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN + REWRITE_TAC[FORALL_IN_IMAGE] THEN REWRITE_TAC[IN_IMAGE] THEN + MESON_TAC[linear; LINEAR_0]);; + +let SUBSPACE_LINEAR_PREIMAGE = prove + (`!f s. linear f /\ subspace s ==> subspace {x | f(x) IN s}`, + REWRITE_TAC[subspace; IN_ELIM_THM] THEN + MESON_TAC[linear; LINEAR_0]);; + +let SUBSPACE_TRIVIAL = prove + (`subspace {vec 0}`, + SIMP_TAC[subspace; IN_SING] THEN CONJ_TAC THEN VECTOR_ARITH_TAC);; + +let SUBSPACE_INTER = prove + (`!s t. subspace s /\ subspace t ==> subspace (s INTER t)`, + REWRITE_TAC[subspace; IN_INTER] THEN MESON_TAC[]);; + +let SUBSPACE_INTERS = prove + (`!f. (!s. s IN f ==> subspace s) ==> subspace(INTERS f)`, + SIMP_TAC[subspace; IMP_CONJ; RIGHT_FORALL_IMP_THM; IN_INTERS]);; + +let LINEAR_INJECTIVE_0_SUBSPACE = prove + (`!f:real^M->real^N s. + linear f /\ subspace s + ==> ((!x y. x IN s /\ y IN s /\ f x = f y ==> x = y) <=> + (!x. x IN s /\ f x = vec 0 ==> x = vec 0))`, + REPEAT STRIP_TAC THEN + GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [GSYM VECTOR_SUB_EQ] THEN + ASM_SIMP_TAC[GSYM LINEAR_SUB] THEN + ASM_MESON_TAC[VECTOR_SUB_RZERO; SUBSPACE_SUB; SUBSPACE_0]);; + +let SUBSPACE_UNION_CHAIN = prove + (`!s t:real^N->bool. + subspace s /\ subspace t /\ subspace(s UNION t) + ==> s SUBSET t \/ t SUBSET s`, + REPEAT STRIP_TAC THEN REWRITE_TAC[SET_RULE + `s SUBSET t \/ t SUBSET s <=> + ~(?x y. x IN s /\ ~(x IN t) /\ y IN t /\ ~(y IN s))`] THEN + STRIP_TAC THEN SUBGOAL_THEN `(x + y:real^N) IN s UNION t` MP_TAC THENL + [MATCH_MP_TAC SUBSPACE_ADD THEN ASM_REWRITE_TAC[] THEN ASM SET_TAC[]; + REWRITE_TAC[IN_UNION; DE_MORGAN_THM] THEN + ASM_MESON_TAC[SUBSPACE_SUB; VECTOR_ARITH + `(x + y) - x:real^N = y /\ (x + y) - y = x`]]);; + +let SUBSPACE_PCROSS = prove + (`!s:real^M->bool t:real^N->bool. + subspace s /\ subspace t ==> subspace(s PCROSS t)`, + REWRITE_TAC[subspace; IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN + REWRITE_TAC[FORALL_IN_PCROSS; GSYM PASTECART_CMUL; PASTECART_ADD] THEN + REWRITE_TAC[GSYM PASTECART_VEC; PASTECART_IN_PCROSS] THEN SIMP_TAC[]);; + +let SUBSPACE_PCROSS_EQ = prove + (`!s:real^M->bool t:real^N->bool. + subspace(s PCROSS t) <=> subspace s /\ subspace t`, + REPEAT GEN_TAC THEN + ASM_CASES_TAC `s:real^M->bool = {}` THENL + [ASM_MESON_TAC[PCROSS_EMPTY; SUBSPACE_IMP_NONEMPTY]; ALL_TAC] THEN + ASM_CASES_TAC `t:real^N->bool = {}` THENL + [ASM_MESON_TAC[PCROSS_EMPTY; SUBSPACE_IMP_NONEMPTY]; ALL_TAC] THEN + EQ_TAC THEN REWRITE_TAC[SUBSPACE_PCROSS] THEN REPEAT STRIP_TAC THENL + [MP_TAC(ISPECL [`fstcart:real^(M,N)finite_sum->real^M`; + `(s:real^M->bool) PCROSS (t:real^N->bool)`] SUBSPACE_LINEAR_IMAGE) THEN + ASM_REWRITE_TAC[LINEAR_FSTCART]; + MP_TAC(ISPECL [`sndcart:real^(M,N)finite_sum->real^N`; + `(s:real^M->bool) PCROSS (t:real^N->bool)`] SUBSPACE_LINEAR_IMAGE) THEN + ASM_REWRITE_TAC[LINEAR_SNDCART]] THEN + MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN + REWRITE_TAC[EXTENSION; IN_IMAGE; EXISTS_PASTECART; PASTECART_IN_PCROSS; + FSTCART_PASTECART; SNDCART_PASTECART] THEN + ASM SET_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* Lemmas. *) +(* ------------------------------------------------------------------------- *) + +let SPAN_SPAN = prove + (`!s. span(span s) = span s`, + REWRITE_TAC[span; HULL_HULL]);; + +let SPAN_MONO = prove + (`!s t. s SUBSET t ==> span s SUBSET span t`, + REWRITE_TAC[span; HULL_MONO]);; + +let SUBSPACE_SPAN = prove + (`!s. subspace(span s)`, + GEN_TAC THEN REWRITE_TAC[span] THEN MATCH_MP_TAC P_HULL THEN + SIMP_TAC[subspace; IN_INTERS]);; + +let SPAN_CLAUSES = prove + (`(!a s. a IN s ==> a IN span s) /\ + (vec(0) IN span s) /\ + (!x y s. x IN span s /\ y IN span s ==> (x + y) IN span s) /\ + (!x c s. x IN span s ==> (c % x) IN span s)`, + MESON_TAC[span; HULL_SUBSET; SUBSET; SUBSPACE_SPAN; subspace]);; + +let SPAN_INDUCT = prove + (`!s h. (!x. x IN s ==> x IN h) /\ subspace h ==> !x. x IN span(s) ==> h(x)`, + REWRITE_TAC[span] THEN MESON_TAC[SUBSET; HULL_MINIMAL; IN]);; + +let SPAN_EMPTY = prove + (`span {} = {vec 0}`, + REWRITE_TAC[span] THEN MATCH_MP_TAC HULL_UNIQUE THEN + SIMP_TAC[subspace; SUBSET; IN_SING; NOT_IN_EMPTY] THEN + REPEAT STRIP_TAC THEN VECTOR_ARITH_TAC);; + +let INDEPENDENT_EMPTY = prove + (`independent {}`, + REWRITE_TAC[independent; dependent; NOT_IN_EMPTY]);; + +let INDEPENDENT_NONZERO = prove + (`!s. independent s ==> ~(vec 0 IN s)`, + REWRITE_TAC[independent; dependent] THEN MESON_TAC[SPAN_CLAUSES]);; + +let INDEPENDENT_MONO = prove + (`!s t. independent t /\ s SUBSET t ==> independent s`, + REWRITE_TAC[independent; dependent] THEN + ASM_MESON_TAC[SPAN_MONO; SUBSET; IN_DELETE]);; + +let DEPENDENT_MONO = prove + (`!s t:real^N->bool. dependent s /\ s SUBSET t ==> dependent t`, + ONCE_REWRITE_TAC[TAUT `p /\ q ==> r <=> ~r /\ q ==> ~p`] THEN + REWRITE_TAC[GSYM independent; INDEPENDENT_MONO]);; + +let SPAN_SUBSPACE = prove + (`!b s. b SUBSET s /\ s SUBSET (span b) /\ subspace s ==> (span b = s)`, + MESON_TAC[SUBSET_ANTISYM; span; HULL_MINIMAL]);; + +let SPAN_INDUCT_ALT = prove + (`!s h. h(vec 0) /\ + (!c x y. x IN s /\ h(y) ==> h(c % x + y)) + ==> !x:real^N. x IN span(s) ==> h(x)`, + REPEAT GEN_TAC THEN DISCH_TAC THEN + FIRST_ASSUM(MP_TAC o prove_inductive_relations_exist o concl) THEN + DISCH_THEN(X_CHOOSE_THEN `g:real^N->bool` STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN `!x:real^N. x IN span(s) ==> g(x)` + (fun th -> ASM_MESON_TAC[th]) THEN + MATCH_MP_TAC SPAN_INDUCT THEN REWRITE_TAC[subspace; IN_ELIM_THM] THEN + REWRITE_TAC[IN; IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN + ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN REWRITE_TAC[RIGHT_FORALL_IMP_THM] THEN + REPEAT CONJ_TAC THEN TRY(FIRST_X_ASSUM MATCH_MP_TAC) THEN + REWRITE_TAC[VECTOR_ADD_LDISTRIB; VECTOR_MUL_ASSOC] THEN + ASM_MESON_TAC[IN; VECTOR_ADD_LID; VECTOR_ADD_ASSOC; VECTOR_ADD_SYM; + VECTOR_MUL_LID; VECTOR_MUL_RZERO]);; + +(* ------------------------------------------------------------------------- *) +(* Individual closure properties. *) +(* ------------------------------------------------------------------------- *) + +let SPAN_SUPERSET = prove + (`!x. x IN s ==> x IN span s`, + MESON_TAC[SPAN_CLAUSES]);; + +let SPAN_INC = prove + (`!s. s SUBSET span s`, + REWRITE_TAC[SUBSET; SPAN_SUPERSET]);; + +let SPAN_UNION_SUBSET = prove + (`!s t. span s UNION span t SUBSET span(s UNION t)`, + REWRITE_TAC[span; HULL_UNION_SUBSET]);; + +let SPAN_UNIV = prove + (`span(:real^N) = (:real^N)`, + SIMP_TAC[SPAN_INC; SET_RULE `UNIV SUBSET s ==> s = UNIV`]);; + +let SPAN_0 = prove + (`vec(0) IN span s`, + MESON_TAC[SUBSPACE_SPAN; SUBSPACE_0]);; + +let SPAN_ADD = prove + (`!x y s. x IN span s /\ y IN span s ==> (x + y) IN span s`, + MESON_TAC[SUBSPACE_SPAN; SUBSPACE_ADD]);; + +let SPAN_MUL = prove + (`!x c s. x IN span s ==> (c % x) IN span s`, + MESON_TAC[SUBSPACE_SPAN; SUBSPACE_MUL]);; + +let SPAN_MUL_EQ = prove + (`!x:real^N c s. ~(c = &0) ==> ((c % x) IN span s <=> x IN span s)`, + REPEAT(STRIP_TAC ORELSE EQ_TAC) THEN ASM_SIMP_TAC[SPAN_MUL] THEN + SUBGOAL_THEN `(inv(c) % c % x:real^N) IN span s` MP_TAC THENL + [ASM_SIMP_TAC[SPAN_MUL]; + ASM_SIMP_TAC[VECTOR_MUL_ASSOC; REAL_MUL_LINV; VECTOR_MUL_LID]]);; + +let SPAN_NEG = prove + (`!x s. x IN span s ==> (--x) IN span s`, + MESON_TAC[SUBSPACE_SPAN; SUBSPACE_NEG]);; + +let SPAN_NEG_EQ = prove + (`!x s. --x IN span s <=> x IN span s`, + MESON_TAC[SPAN_NEG; VECTOR_NEG_NEG]);; + +let SPAN_SUB = prove + (`!x y s. x IN span s /\ y IN span s ==> (x - y) IN span s`, + MESON_TAC[SUBSPACE_SPAN; SUBSPACE_SUB]);; + +let SPAN_VSUM = prove + (`!s f t. FINITE t /\ (!x. x IN t ==> f(x) IN span(s)) + ==> (vsum t f) IN span(s)`, + MESON_TAC[SUBSPACE_SPAN; SUBSPACE_VSUM]);; + +let SPAN_ADD_EQ = prove + (`!s x y. x IN span s ==> ((x + y) IN span s <=> y IN span s)`, + MESON_TAC[SPAN_ADD; SPAN_SUB; VECTOR_ARITH `(x + y) - x:real^N = y`]);; + +let SPAN_EQ_SELF = prove + (`!s. span s = s <=> subspace s`, + GEN_TAC THEN EQ_TAC THENL [MESON_TAC[SUBSPACE_SPAN]; ALL_TAC] THEN + DISCH_TAC THEN MATCH_MP_TAC SPAN_SUBSPACE THEN + ASM_REWRITE_TAC[SUBSET_REFL; SPAN_INC]);; + +let SPAN_OF_SUBSPACE = prove + (`!s:real^N->bool. subspace s ==> span s = s`, + REWRITE_TAC[SPAN_EQ_SELF]);; + +let SPAN_SUBSET_SUBSPACE = prove + (`!s t:real^N->bool. s SUBSET t /\ subspace t ==> span s SUBSET t`, + MESON_TAC[SPAN_MONO; SPAN_EQ_SELF]);; + +let SUBSPACE_TRANSLATION_SELF = prove + (`!s a. subspace s /\ a IN s ==> IMAGE (\x. a + x) s = s`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC SURJECTIVE_IMAGE_EQ THEN + FIRST_ASSUM(SUBST1_TAC o SYM o GEN_REWRITE_RULE I [GSYM SPAN_EQ_SELF]) THEN + ASM_SIMP_TAC[SPAN_ADD_EQ; SPAN_CLAUSES] THEN + REWRITE_TAC[VECTOR_ARITH `a + x:real^N = y <=> x = y - a`; EXISTS_REFL]);; + +let SUBSPACE_TRANSLATION_SELF_EQ = prove + (`!s a:real^N. subspace s ==> (IMAGE (\x. a + x) s = s <=> a IN s)`, + REPEAT STRIP_TAC THEN EQ_TAC THEN + ASM_SIMP_TAC[SUBSPACE_TRANSLATION_SELF] THEN + DISCH_THEN(MP_TAC o AP_TERM `\s. (a:real^N) IN s`) THEN + REWRITE_TAC[] THEN DISCH_THEN(SUBST1_TAC o SYM) THEN + REWRITE_TAC[IN_IMAGE] THEN EXISTS_TAC `vec 0:real^N` THEN + ASM_MESON_TAC[subspace; VECTOR_ADD_RID]);; + +let SUBSPACE_SUMS = prove + (`!s t. subspace s /\ subspace t + ==> subspace {x + y | x IN s /\ y IN t}`, + REWRITE_TAC[subspace; FORALL_IN_GSPEC; IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN + REWRITE_TAC[IN_ELIM_THM] THEN REPEAT STRIP_TAC THENL + [ASM_MESON_TAC[VECTOR_ADD_LID]; + ONCE_REWRITE_TAC[VECTOR_ARITH + `(x + y) + (x' + y'):real^N = (x + x') + (y + y')`] THEN + ASM_MESON_TAC[]; + REWRITE_TAC[VECTOR_ADD_LDISTRIB] THEN ASM_MESON_TAC[]]);; + +let SPAN_UNION = prove + (`!s t. span(s UNION t) = {x + y:real^N | x IN span s /\ y IN span t}`, + REPEAT GEN_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL + [MATCH_MP_TAC SPAN_SUBSET_SUBSPACE THEN + SIMP_TAC[SUBSPACE_SUMS; SUBSPACE_SPAN] THEN + REWRITE_TAC[SUBSET; IN_UNION; IN_ELIM_THM] THEN + X_GEN_TAC `x:real^N` THEN STRIP_TAC THENL + [MAP_EVERY EXISTS_TAC [`x:real^N`; `vec 0:real^N`] THEN + ASM_SIMP_TAC[SPAN_SUPERSET; SPAN_0; VECTOR_ADD_RID]; + MAP_EVERY EXISTS_TAC [`vec 0:real^N`; `x:real^N`] THEN + ASM_SIMP_TAC[SPAN_SUPERSET; SPAN_0; VECTOR_ADD_LID]]; + REWRITE_TAC[SUBSET; FORALL_IN_GSPEC] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC SPAN_ADD THEN + ASM_MESON_TAC[SPAN_MONO; SUBSET_UNION; SUBSET]]);; + +(* ------------------------------------------------------------------------- *) +(* Mapping under linear image. *) +(* ------------------------------------------------------------------------- *) + +let SPAN_LINEAR_IMAGE = prove + (`!f:real^M->real^N s. linear f ==> (span(IMAGE f s) = IMAGE f (span s))`, + REPEAT STRIP_TAC THEN GEN_REWRITE_TAC I [EXTENSION] THEN + X_GEN_TAC `x:real^N` THEN EQ_TAC THENL + [SPEC_TAC(`x:real^N`,`x:real^N`) THEN MATCH_MP_TAC SPAN_INDUCT THEN + REWRITE_TAC[SET_RULE `(\x. x IN s) = s`] THEN + ASM_SIMP_TAC[SUBSPACE_SPAN; SUBSPACE_LINEAR_IMAGE] THEN + REWRITE_TAC[FORALL_IN_IMAGE] THEN REWRITE_TAC[IN_IMAGE] THEN + MESON_TAC[SPAN_SUPERSET; SUBSET]; + SPEC_TAC(`x:real^N`,`x:real^N`) THEN REWRITE_TAC[FORALL_IN_IMAGE] THEN + MATCH_MP_TAC SPAN_INDUCT THEN + REWRITE_TAC[SET_RULE `(\x. f x IN span(s)) = {x | f(x) IN span s}`] THEN + ASM_SIMP_TAC[SUBSPACE_LINEAR_PREIMAGE; SUBSPACE_SPAN] THEN + REWRITE_TAC[IN_ELIM_THM] THEN + MESON_TAC[SPAN_SUPERSET; SUBSET; IN_IMAGE]]);; + +let DEPENDENT_LINEAR_IMAGE_EQ = prove + (`!f:real^M->real^N s. + linear f /\ (!x y. f x = f y ==> x = y) + ==> (dependent(IMAGE f s) <=> dependent s)`, + REPEAT STRIP_TAC THEN REWRITE_TAC[dependent; EXISTS_IN_IMAGE] THEN + AP_TERM_TAC THEN REWRITE_TAC[FUN_EQ_THM] THEN X_GEN_TAC `a:real^M` THEN + ASM_CASES_TAC `(a:real^M) IN s` THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC EQ_TRANS THEN + EXISTS_TAC `(f:real^M->real^N) a IN span(IMAGE f (s DELETE a))` THEN + CONJ_TAC THENL + [AP_TERM_TAC THEN AP_TERM_TAC THEN ASM SET_TAC[]; + ASM_SIMP_TAC[SPAN_LINEAR_IMAGE] THEN ASM SET_TAC[]]);; + +let DEPENDENT_LINEAR_IMAGE = prove + (`!f:real^M->real^N s. + linear f /\ (!x y. x IN s /\ y IN s /\ f x = f y ==> x = y) /\ + dependent(s) + ==> dependent(IMAGE f s)`, + REPEAT GEN_TAC THEN + REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + REWRITE_TAC[dependent; EXISTS_IN_IMAGE] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `a:real^M` THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + SUBGOAL_THEN `IMAGE (f:real^M->real^N) s DELETE f a = IMAGE f (s DELETE a)` + (fun th -> ASM_SIMP_TAC[FUN_IN_IMAGE; SPAN_LINEAR_IMAGE; th]) THEN + ASM SET_TAC[]);; + +let INDEPENDENT_LINEAR_IMAGE_EQ = prove + (`!f:real^M->real^N s. + linear f /\ (!x y. f x = f y ==> x = y) + ==> (independent(IMAGE f s) <=> independent s)`, + REWRITE_TAC[independent; TAUT `(~p <=> ~q) <=> (p <=> q)`] THEN + REWRITE_TAC[DEPENDENT_LINEAR_IMAGE_EQ]);; + +(* ------------------------------------------------------------------------- *) +(* The key breakdown property. *) +(* ------------------------------------------------------------------------- *) + +let SPAN_BREAKDOWN = prove + (`!b s a:real^N. + b IN s /\ a IN span s ==> ?k. (a - k % b) IN span(s DELETE b)`, + REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN + REPEAT GEN_TAC THEN DISCH_TAC THEN MATCH_MP_TAC SPAN_INDUCT THEN + REWRITE_TAC[subspace; IN_ELIM_THM] THEN CONJ_TAC THENL + [GEN_TAC THEN DISCH_TAC THEN ASM_CASES_TAC `a:real^N = b`; ALL_TAC] THEN + ASM_MESON_TAC[SPAN_CLAUSES; IN_DELETE; VECTOR_ARITH + `(a - &1 % a = vec 0) /\ (a - &0 % b = a) /\ + ((x + y) - (k1 + k2) % b = (x - k1 % b) + (y - k2 % b)) /\ + (c % x - (c * k) % y = c % (x - k % y))`]);; + +let SPAN_BREAKDOWN_EQ = prove + (`!a:real^N s. (x IN span(a INSERT s) <=> (?k. (x - k % a) IN span s))`, + REPEAT STRIP_TAC THEN EQ_TAC THENL + [DISCH_THEN(MP_TAC o CONJ(SET_RULE `(a:real^N) IN (a INSERT s)`)) THEN + DISCH_THEN(MP_TAC o MATCH_MP SPAN_BREAKDOWN) THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `k:real` THEN + SPEC_TAC(`x - k % a:real^N`,`y:real^N`) THEN + REWRITE_TAC[GSYM SUBSET] THEN MATCH_MP_TAC SPAN_MONO THEN SET_TAC[]; + DISCH_THEN(X_CHOOSE_TAC `k:real`) THEN + SUBST1_TAC(VECTOR_ARITH `x = (x - k % a) + k % a:real^N`) THEN + MATCH_MP_TAC SPAN_ADD THEN + ASM_MESON_TAC[SPAN_MONO; SUBSET; IN_INSERT; SPAN_CLAUSES]]);; + +let SPAN_INSERT_0 = prove + (`!s. span(vec 0 INSERT s) = span s`, + SIMP_TAC[EXTENSION; SPAN_BREAKDOWN_EQ; VECTOR_MUL_RZERO; VECTOR_SUB_RZERO]);; + +let SPAN_SING = prove + (`!a. span {a} = {u % a | u IN (:real)}`, + REWRITE_TAC[EXTENSION; IN_ELIM_THM; SPAN_BREAKDOWN_EQ; SPAN_EMPTY] THEN + REWRITE_TAC[IN_UNIV; IN_SING; VECTOR_SUB_EQ]);; + +let SPAN_2 = prove + (`!a b. span {a,b} = {u % a + v % b | u IN (:real) /\ v IN (:real)}`, + REWRITE_TAC[EXTENSION; IN_ELIM_THM; SPAN_BREAKDOWN_EQ; SPAN_EMPTY] THEN + REWRITE_TAC[IN_UNIV; IN_SING; VECTOR_SUB_EQ] THEN + REWRITE_TAC[VECTOR_ARITH `x - y:real^N = z <=> x = y + z`]);; + +let SPAN_3 = prove + (`!a b c. span {a,b,c} = + {u % a + v % b + w % c | u IN (:real) /\ v IN (:real) /\ w IN (:real)}`, + REWRITE_TAC[EXTENSION; IN_ELIM_THM; SPAN_BREAKDOWN_EQ; SPAN_EMPTY] THEN + REWRITE_TAC[IN_UNIV; IN_SING; VECTOR_SUB_EQ] THEN + REWRITE_TAC[VECTOR_ARITH `x - y:real^N = z <=> x = y + z`]);; + +(* ------------------------------------------------------------------------- *) +(* Hence some "reversal" results. *) +(* ------------------------------------------------------------------------- *) + +let IN_SPAN_INSERT = prove + (`!a b:real^N s. + a IN span(b INSERT s) /\ ~(a IN span s) ==> b IN span(a INSERT s)`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`b:real^N`; `(b:real^N) INSERT s`; `a:real^N`] + SPAN_BREAKDOWN) THEN ASM_REWRITE_TAC[IN_INSERT] THEN + DISCH_THEN(X_CHOOSE_THEN `k:real` MP_TAC) THEN ASM_CASES_TAC `k = &0` THEN + ASM_REWRITE_TAC[VECTOR_ARITH `a - &0 % b = a`; DELETE_INSERT] THENL + [ASM_MESON_TAC[SPAN_MONO; SUBSET; DELETE_SUBSET]; ALL_TAC] THEN + DISCH_THEN(MP_TAC o SPEC `inv(k)` o MATCH_MP SPAN_MUL) THEN + ASM_SIMP_TAC[VECTOR_SUB_LDISTRIB; VECTOR_MUL_ASSOC; REAL_MUL_LINV] THEN + DISCH_TAC THEN SUBST1_TAC(VECTOR_ARITH + `b:real^N = inv(k) % a - (inv(k) % a - &1 % b)`) THEN + MATCH_MP_TAC SPAN_SUB THEN + ASM_MESON_TAC[SPAN_CLAUSES; IN_INSERT; SUBSET; IN_DELETE; SPAN_MONO]);; + +let IN_SPAN_DELETE = prove + (`!a b s. + a IN span s /\ ~(a IN span (s DELETE b)) + ==> b IN span (a INSERT (s DELETE b))`, + ASM_MESON_TAC[IN_SPAN_INSERT; SPAN_MONO; SUBSET; IN_INSERT; IN_DELETE]);; + +let EQ_SPAN_INSERT_EQ = prove + (`!s x y:real^N. (x - y) IN span s ==> span(x INSERT s) = span(y INSERT s)`, + REPEAT STRIP_TAC THEN REWRITE_TAC[SPAN_BREAKDOWN_EQ; EXTENSION] THEN + ASM_MESON_TAC[SPAN_ADD; SPAN_SUB; SPAN_MUL; + VECTOR_ARITH `(z - k % y) - k % (x - y) = z - k % x`; + VECTOR_ARITH `(z - k % x) + k % (x - y) = z - k % y`]);; + +(* ------------------------------------------------------------------------- *) +(* Transitivity property. *) +(* ------------------------------------------------------------------------- *) + +let SPAN_TRANS = prove + (`!x y:real^N s. x IN span(s) /\ y IN span(x INSERT s) ==> y IN span(s)`, + REPEAT STRIP_TAC THEN + MP_TAC(SPECL [`x:real^N`; `(x:real^N) INSERT s`; `y:real^N`] + SPAN_BREAKDOWN) THEN + ASM_REWRITE_TAC[IN_INSERT] THEN + DISCH_THEN(X_CHOOSE_THEN `k:real` STRIP_ASSUME_TAC) THEN + SUBST1_TAC(VECTOR_ARITH `y:real^N = (y - k % x) + k % x`) THEN + MATCH_MP_TAC SPAN_ADD THEN ASM_SIMP_TAC[SPAN_MUL] THEN + ASM_MESON_TAC[SPAN_MONO; SUBSET; IN_INSERT; IN_DELETE]);; + +(* ------------------------------------------------------------------------- *) +(* An explicit expansion is sometimes needed. *) +(* ------------------------------------------------------------------------- *) + +let SPAN_EXPLICIT = prove + (`!(p:real^N -> bool). + span p = + {y | ?s u. FINITE s /\ s SUBSET p /\ + vsum s (\v. u v % v) = y}`, + GEN_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL + [ALL_TAC; + REWRITE_TAC[SUBSET; IN_ELIM_THM] THEN + REPEAT STRIP_TAC THEN FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN + MATCH_MP_TAC SPAN_VSUM THEN ASM_REWRITE_TAC[] THEN + ASM_MESON_TAC[SPAN_SUPERSET; SPAN_MUL]] THEN + REWRITE_TAC[SUBSET; IN_ELIM_THM] THEN + MATCH_MP_TAC SPAN_INDUCT_ALT THEN CONJ_TAC THENL + [EXISTS_TAC `{}:real^N->bool` THEN + REWRITE_TAC[FINITE_RULES; VSUM_CLAUSES; EMPTY_SUBSET; NOT_IN_EMPTY]; + ALL_TAC] THEN + MAP_EVERY X_GEN_TAC [`c:real`; `x:real^N`; `y:real^N`] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`s:real^N->bool`; `u:real^N->real`] THEN + STRIP_TAC THEN EXISTS_TAC `(x:real^N) INSERT s` THEN + EXISTS_TAC `\y. if y = x then (if x IN s then (u:real^N->real) y + c else c) + else u y` THEN + ASM_SIMP_TAC[FINITE_INSERT; IN_INSERT; VSUM_CLAUSES] THEN + CONJ_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN + FIRST_X_ASSUM(SUBST_ALL_TAC o SYM) THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[] THENL + [FIRST_X_ASSUM(SUBST1_TAC o MATCH_MP (SET_RULE + `x IN s ==> s = x INSERT (s DELETE x)`)) THEN + ASM_SIMP_TAC[VSUM_CLAUSES; FINITE_INSERT; FINITE_DELETE; IN_DELETE] THEN + MATCH_MP_TAC(VECTOR_ARITH + `y = z ==> (c + d) % x + y = d % x + c % x + z`); + AP_TERM_TAC] THEN + MATCH_MP_TAC VSUM_EQ THEN ASM_MESON_TAC[IN_DELETE]);; + +let DEPENDENT_EXPLICIT = prove + (`!p. dependent (p:real^N -> bool) <=> + ?s u. FINITE s /\ s SUBSET p /\ + (?v. v IN s /\ ~(u v = &0)) /\ + vsum s (\v. u v % v) = vec 0`, + GEN_TAC THEN REWRITE_TAC[dependent; SPAN_EXPLICIT; IN_ELIM_THM] THEN + REWRITE_TAC[RIGHT_AND_EXISTS_THM; LEFT_AND_EXISTS_THM] THEN + EQ_TAC THEN REWRITE_TAC[LEFT_IMP_EXISTS_THM] THENL + [MAP_EVERY X_GEN_TAC [`a:real^N`; `s:real^N->bool`; `u:real^N->real`] THEN + STRIP_TAC THEN MAP_EVERY EXISTS_TAC + [`(a:real^N) INSERT s`; + `\y. if y = a then -- &1 else (u:real^N->real) y`; + `a:real^N`] THEN + ASM_REWRITE_TAC[IN_INSERT; INSERT_SUBSET; FINITE_INSERT] THEN + CONJ_TAC THENL [ASM SET_TAC[]; CONV_TAC REAL_RAT_REDUCE_CONV] THEN + ASM_SIMP_TAC[VSUM_CLAUSES] THEN + COND_CASES_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + REWRITE_TAC[VECTOR_ARITH `-- &1 % a + s = vec 0 <=> a = s`] THEN + FIRST_X_ASSUM(fun th -> GEN_REWRITE_TAC LAND_CONV [SYM th]) THEN + MATCH_MP_TAC VSUM_EQ THEN ASM SET_TAC[]; + MAP_EVERY X_GEN_TAC [`s:real^N->bool`; `u:real^N->real`; `a:real^N`] THEN + STRIP_TAC THEN MAP_EVERY EXISTS_TAC + [`a:real^N`; `s DELETE (a:real^N)`; + `\i. --((u:real^N->real) i) / (u a)`] THEN + ASM_SIMP_TAC[VSUM_DELETE; FINITE_DELETE] THEN + REPEAT(CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC]) THEN + REWRITE_TAC[real_div] THEN ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN + ASM_REWRITE_TAC[VECTOR_MUL_LNEG; GSYM VECTOR_MUL_ASSOC; VSUM_LMUL; + VSUM_NEG; VECTOR_MUL_RNEG; VECTOR_MUL_RZERO] THEN + ASM_SIMP_TAC[VECTOR_MUL_ASSOC; REAL_MUL_LINV] THEN VECTOR_ARITH_TAC]);; + +let DEPENDENT_FINITE = prove + (`!s:real^N->bool. + FINITE s + ==> (dependent s <=> ?u. (?v. v IN s /\ ~(u v = &0)) /\ + vsum s (\v. u(v) % v) = vec 0)`, + REPEAT STRIP_TAC THEN REWRITE_TAC[DEPENDENT_EXPLICIT] THEN EQ_TAC THEN + REWRITE_TAC[LEFT_IMP_EXISTS_THM] THENL + [MAP_EVERY X_GEN_TAC [`t:real^N->bool`; `u:real^N->real`] THEN + DISCH_THEN(REPEAT_TCL CONJUNCTS_THEN ASSUME_TAC) THEN + EXISTS_TAC `\v:real^N. if v IN t then u(v) else &0` THEN + REWRITE_TAC[] THEN CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + ONCE_REWRITE_TAC[COND_RAND] THEN ONCE_REWRITE_TAC[COND_RATOR] THEN + ASM_SIMP_TAC[VECTOR_MUL_LZERO; GSYM VSUM_RESTRICT_SET] THEN + ASM_SIMP_TAC[SET_RULE `t SUBSET s ==> {x | x IN s /\ x IN t} = t`]; + GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN ASSUME_TAC) THEN + MAP_EVERY EXISTS_TAC [`s:real^N->bool`; `u:real^N->real`] THEN + ASM_REWRITE_TAC[SUBSET_REFL]]);; + +let SPAN_FINITE = prove + (`!s:real^N->bool. + FINITE s ==> span s = {y | ?u. vsum s (\v. u v % v) = y}`, + REPEAT STRIP_TAC THEN REWRITE_TAC[SPAN_EXPLICIT; EXTENSION; IN_ELIM_THM] THEN + X_GEN_TAC `y:real^N` THEN EQ_TAC THEN REWRITE_TAC[LEFT_IMP_EXISTS_THM] THENL + [MAP_EVERY X_GEN_TAC [`t:real^N->bool`; `u:real^N->real`] THEN + STRIP_TAC THEN FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN + EXISTS_TAC `\x:real^N. if x IN t then u(x) else &0` THEN + REWRITE_TAC[COND_RAND; COND_RATOR; VECTOR_MUL_LZERO] THEN + ASM_SIMP_TAC[GSYM VSUM_RESTRICT_SET] THEN + ASM_SIMP_TAC[SET_RULE `t SUBSET s ==> {x | x IN s /\ x IN t} = t`]; + X_GEN_TAC `u:real^N->real` THEN DISCH_THEN(SUBST1_TAC o SYM) THEN + MAP_EVERY EXISTS_TAC [`s:real^N->bool`; `u:real^N->real`] THEN + ASM_REWRITE_TAC[SUBSET_REFL]]);; + +(* ------------------------------------------------------------------------- *) +(* Standard bases are a spanning set, and obviously finite. *) +(* ------------------------------------------------------------------------- *) + +let SPAN_STDBASIS = prove + (`span {basis i :real^N | 1 <= i /\ i <= dimindex(:N)} = UNIV`, + REWRITE_TAC[EXTENSION; IN_UNIV] THEN X_GEN_TAC `x:real^N` THEN + GEN_REWRITE_TAC LAND_CONV [GSYM BASIS_EXPANSION] THEN + MATCH_MP_TAC SPAN_VSUM THEN SIMP_TAC[FINITE_NUMSEG; IN_NUMSEG] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC SPAN_MUL THEN + MATCH_MP_TAC SPAN_SUPERSET THEN REWRITE_TAC[IN_ELIM_THM] THEN + ASM_MESON_TAC[]);; + +let HAS_SIZE_STDBASIS = prove + (`{basis i :real^N | 1 <= i /\ i <= dimindex(:N)} HAS_SIZE + dimindex(:N)`, + ONCE_REWRITE_TAC[SET_RULE `{f x | P x} = IMAGE f {x | P x}`] THEN + MATCH_MP_TAC HAS_SIZE_IMAGE_INJ THEN + REWRITE_TAC[GSYM numseg; HAS_SIZE_NUMSEG_1; IN_NUMSEG] THEN + MESON_TAC[BASIS_INJ]);; + +let FINITE_STDBASIS = prove + (`FINITE {basis i :real^N | 1 <= i /\ i <= dimindex(:N)}`, + MESON_TAC[HAS_SIZE_STDBASIS; HAS_SIZE]);; + +let CARD_STDBASIS = prove + (`CARD {basis i :real^N | 1 <= i /\ i <= dimindex(:N)} = + dimindex(:N)`, + MESON_TAC[HAS_SIZE_STDBASIS; HAS_SIZE]);; + +let IN_SPAN_IMAGE_BASIS = prove + (`!x:real^N s. + x IN span(IMAGE basis s) <=> + !i. 1 <= i /\ i <= dimindex(:N) /\ ~(i IN s) ==> x$i = &0`, + REPEAT GEN_TAC THEN EQ_TAC THENL + [SPEC_TAC(`x:real^N`,`x:real^N`) THEN MATCH_MP_TAC SPAN_INDUCT THEN + SIMP_TAC[subspace; IN_ELIM_THM; VEC_COMPONENT; VECTOR_ADD_COMPONENT; + VECTOR_MUL_COMPONENT; REAL_MUL_RZERO; REAL_ADD_RID] THEN + SIMP_TAC[FORALL_IN_IMAGE; BASIS_COMPONENT] THEN MESON_TAC[]; + DISCH_TAC THEN REWRITE_TAC[SPAN_EXPLICIT; IN_ELIM_THM] THEN + EXISTS_TAC `(IMAGE basis ((1..dimindex(:N)) INTER s)):real^N->bool` THEN + SIMP_TAC[FINITE_IMAGE; FINITE_INTER; FINITE_NUMSEG] THEN + REWRITE_TAC[RIGHT_EXISTS_AND_THM] THEN + CONJ_TAC THENL [SET_TAC[]; ALL_TAC] THEN + EXISTS_TAC `\v:real^N. x dot v` THEN + W(MP_TAC o PART_MATCH (lhs o rand) VSUM_IMAGE o lhand o snd) THEN + ANTS_TAC THENL + [SIMP_TAC[FINITE_IMAGE; FINITE_INTER; FINITE_NUMSEG] THEN + REWRITE_TAC[IN_INTER; IN_NUMSEG] THEN MESON_TAC[BASIS_INJ]; + DISCH_THEN SUBST1_TAC THEN REWRITE_TAC[]] THEN + REWRITE_TAC[o_DEF] THEN + SIMP_TAC[CART_EQ; VSUM_COMPONENT; VECTOR_MUL_COMPONENT; + BASIS_COMPONENT] THEN + ONCE_REWRITE_TAC[COND_RAND] THEN + ONCE_REWRITE_TAC[MESON[] + `(if x = y then p else q) = (if y = x then p else q)`] THEN + SIMP_TAC[SUM_DELTA; REAL_MUL_RZERO; IN_INTER; IN_NUMSEG; DOT_BASIS] THEN + ASM_MESON_TAC[REAL_MUL_RID]]);; + +let INDEPENDENT_STDBASIS = prove + (`independent {basis i :real^N | 1 <= i /\ i <= dimindex(:N)}`, + REWRITE_TAC[independent; dependent] THEN + ONCE_REWRITE_TAC[SET_RULE `{f x | P x} = IMAGE f {x | P x}`] THEN + REWRITE_TAC[EXISTS_IN_IMAGE] THEN REWRITE_TAC[IN_ELIM_THM] THEN + DISCH_THEN(X_CHOOSE_THEN `k:num` (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + SUBGOAL_THEN + `IMAGE basis {i | 1 <= i /\ i <= dimindex(:N)} DELETE + (basis k:real^N) = + IMAGE basis ({i | 1 <= i /\ i <= dimindex(:N)} DELETE k)` + SUBST1_TAC THENL + [REWRITE_TAC[EXTENSION; IN_IMAGE; IN_DELETE; IN_ELIM_THM] THEN + GEN_TAC THEN EQ_TAC THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + ASM_MESON_TAC[BASIS_INJ]; + ALL_TAC] THEN + REWRITE_TAC[IN_SPAN_IMAGE_BASIS] THEN DISCH_THEN(MP_TAC o SPEC `k:num`) THEN + ASM_SIMP_TAC[IN_DELETE; BASIS_COMPONENT; REAL_OF_NUM_EQ; ARITH]);; + +(* ------------------------------------------------------------------------- *) +(* This is useful for building a basis step-by-step. *) +(* ------------------------------------------------------------------------- *) + +let INDEPENDENT_INSERT = prove + (`!a:real^N s. independent(a INSERT s) <=> + if a IN s then independent s + else independent s /\ ~(a IN span s)`, + REPEAT GEN_TAC THEN ASM_CASES_TAC `(a:real^N) IN s` THEN + ASM_SIMP_TAC[SET_RULE `x IN s ==> (x INSERT s = s)`] THEN + EQ_TAC THENL + [DISCH_TAC THEN CONJ_TAC THENL + [ASM_MESON_TAC[INDEPENDENT_MONO; SUBSET; IN_INSERT]; + POP_ASSUM MP_TAC THEN REWRITE_TAC[independent; dependent] THEN + ASM_MESON_TAC[IN_INSERT; SET_RULE + `~(a IN s) ==> ((a INSERT s) DELETE a = s)`]]; + ALL_TAC] THEN + REWRITE_TAC[independent; dependent; NOT_EXISTS_THM] THEN + STRIP_TAC THEN X_GEN_TAC `b:real^N` THEN + REWRITE_TAC[IN_INSERT] THEN ASM_CASES_TAC `b:real^N = a` THEN + ASM_SIMP_TAC[SET_RULE `~(a IN s) ==> ((a INSERT s) DELETE a = s)`] THEN + ASM_SIMP_TAC[SET_RULE + `~(a IN s) /\ ~(b = a) + ==> ((a INSERT s) DELETE b = a INSERT (s DELETE b))`] THEN + ASM_MESON_TAC[IN_SPAN_INSERT; SET_RULE + `b IN s ==> (b INSERT (s DELETE b) = s)`]);; + +(* ------------------------------------------------------------------------- *) +(* The degenerate case of the Exchange Lemma. *) +(* ------------------------------------------------------------------------- *) + +let SPANNING_SUBSET_INDEPENDENT = prove + (`!s t:real^N->bool. + t SUBSET s /\ independent s /\ s SUBSET span(t) ==> (s = t)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN + ASM_REWRITE_TAC[] THEN REWRITE_TAC[SUBSET] THEN + X_GEN_TAC `a:real^N` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [independent]) THEN + REWRITE_TAC[dependent; NOT_EXISTS_THM] THEN + DISCH_THEN(MP_TAC o SPEC `a:real^N`) THEN ASM_REWRITE_TAC[] THEN + ASM_MESON_TAC[SPAN_MONO; SUBSET; IN_DELETE]);; + +(* ------------------------------------------------------------------------- *) +(* The general case of the Exchange Lemma, the key to what follows. *) +(* ------------------------------------------------------------------------- *) + +let EXCHANGE_LEMMA = prove + (`!s t:real^N->bool. + FINITE t /\ independent s /\ s SUBSET span t + ==> ?t'. t' HAS_SIZE (CARD t) /\ + s SUBSET t' /\ t' SUBSET (s UNION t) /\ s SUBSET (span t')`, + REPEAT GEN_TAC THEN + WF_INDUCT_TAC `CARD(t DIFF s :real^N->bool)` THEN + ASM_CASES_TAC `(s:real^N->bool) SUBSET t` THENL + [ASM_MESON_TAC[HAS_SIZE; SUBSET_UNION]; ALL_TAC] THEN + ASM_CASES_TAC `t SUBSET (s:real^N->bool)` THENL + [ASM_MESON_TAC[SPANNING_SUBSET_INDEPENDENT; HAS_SIZE]; ALL_TAC] THEN + STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o REWRITE_RULE[SUBSET] o check(is_neg o concl)) THEN + REWRITE_TAC[NOT_FORALL_THM; NOT_IMP] THEN + DISCH_THEN(X_CHOOSE_THEN `b:real^N` STRIP_ASSUME_TAC) THEN + ASM_CASES_TAC `s SUBSET span(t DELETE (b:real^N))` THENL + [FIRST_X_ASSUM(MP_TAC o + SPECL [`t DELETE (b:real^N)`; `s:real^N->bool`]) THEN + ASM_REWRITE_TAC[SET_RULE `s DELETE a DIFF t = (s DIFF t) DELETE a`] THEN + ASM_SIMP_TAC[CARD_DELETE; FINITE_DIFF; IN_DIFF; FINITE_DELETE; + CARD_EQ_0; ARITH_RULE `n - 1 < n <=> ~(n = 0)`] THEN + ANTS_TAC THENL + [UNDISCH_TAC `~((s:real^N->bool) SUBSET t)` THEN ASM SET_TAC[]; + ALL_TAC] THEN + DISCH_THEN(X_CHOOSE_THEN `u:real^N->bool` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `(b:real^N) INSERT u` THEN + ASM_SIMP_TAC[SUBSET_INSERT; INSERT_SUBSET; IN_UNION] THEN CONJ_TAC THENL + [UNDISCH_TAC `(u:real^N->bool) HAS_SIZE CARD(t:real^N->bool) - 1` THEN + SIMP_TAC[HAS_SIZE; FINITE_RULES; CARD_CLAUSES] THEN STRIP_TAC THEN + COND_CASES_TAC THENL + [ASM_MESON_TAC[SUBSET; IN_UNION; IN_DELETE]; ALL_TAC] THEN + ASM_MESON_TAC[ARITH_RULE `~(n = 0) ==> (SUC(n - 1) = n)`; + CARD_EQ_0; MEMBER_NOT_EMPTY]; + ALL_TAC] THEN + CONJ_TAC THENL + [UNDISCH_TAC `u SUBSET s UNION t DELETE (b:real^N)` THEN SET_TAC[]; + ASM_MESON_TAC[SUBSET; SPAN_MONO; IN_INSERT]]; + ALL_TAC] THEN + UNDISCH_TAC `~(s SUBSET span (t DELETE (b:real^N)))` THEN + GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [SUBSET] THEN + REWRITE_TAC[NOT_FORALL_THM; NOT_IMP] THEN + DISCH_THEN(X_CHOOSE_THEN `a:real^N` STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN `~(a:real^N = b)` ASSUME_TAC THENL + [ASM_MESON_TAC[]; ALL_TAC] THEN + SUBGOAL_THEN `~((a:real^N) IN t)` ASSUME_TAC THENL + [ASM_MESON_TAC[IN_DELETE; SPAN_CLAUSES]; ALL_TAC] THEN + FIRST_X_ASSUM(MP_TAC o SPECL + [`(a:real^N) INSERT (t DELETE b)`; `s:real^N->bool`]) THEN + ANTS_TAC THENL + [ASM_SIMP_TAC[SET_RULE + `a IN s ==> ((a INSERT (t DELETE b) DIFF s) = (t DIFF s) DELETE b)`] THEN + ASM_SIMP_TAC[CARD_DELETE; FINITE_DELETE; FINITE_DIFF; IN_DIFF] THEN + ASM_SIMP_TAC[ARITH_RULE `n - 1 < n <=> ~(n = 0)`; CARD_EQ_0; + FINITE_DIFF] THEN + UNDISCH_TAC `~((s:real^N->bool) SUBSET t)` THEN ASM SET_TAC[]; + ALL_TAC] THEN + ANTS_TAC THENL + [ASM_SIMP_TAC[FINITE_RULES; FINITE_DELETE] THEN + REWRITE_TAC[SUBSET] THEN X_GEN_TAC `x:real^N` THEN + DISCH_TAC THEN MATCH_MP_TAC SPAN_TRANS THEN EXISTS_TAC `b:real^N` THEN + ASM_MESON_TAC[IN_SPAN_DELETE; SUBSET; SPAN_MONO; + SET_RULE `t SUBSET (b INSERT (a INSERT (t DELETE b)))`]; + ALL_TAC] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `u:real^N->bool` THEN + ASM_SIMP_TAC[HAS_SIZE; CARD_CLAUSES; CARD_DELETE; FINITE_DELETE; IN_DELETE; + ARITH_RULE `(SUC(n - 1) = n) <=> ~(n = 0)`; + CARD_EQ_0] THEN + UNDISCH_TAC `(b:real^N) IN t` THEN ASM SET_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* This implies corresponding size bounds. *) +(* ------------------------------------------------------------------------- *) + +let INDEPENDENT_SPAN_BOUND = prove + (`!s t. FINITE t /\ independent s /\ s SUBSET span(t) + ==> FINITE s /\ CARD(s) <= CARD(t)`, + REPEAT GEN_TAC THEN DISCH_TAC THEN + FIRST_ASSUM(MP_TAC o MATCH_MP EXCHANGE_LEMMA) THEN + ASM_MESON_TAC[HAS_SIZE; CARD_SUBSET; FINITE_SUBSET]);; + +let INDEPENDENT_BOUND = prove + (`!s:real^N->bool. + independent s ==> FINITE s /\ CARD(s) <= dimindex(:N)`, + REPEAT GEN_TAC THEN DISCH_TAC THEN + ONCE_REWRITE_TAC[GSYM CARD_STDBASIS] THEN + MATCH_MP_TAC INDEPENDENT_SPAN_BOUND THEN + ASM_REWRITE_TAC[FINITE_STDBASIS; SPAN_STDBASIS; SUBSET_UNIV]);; + +let DEPENDENT_BIGGERSET = prove + (`!s:real^N->bool. (FINITE s ==> CARD(s) > dimindex(:N)) ==> dependent s`, + MP_TAC INDEPENDENT_BOUND THEN MATCH_MP_TAC MONO_FORALL THEN + REWRITE_TAC[GT; GSYM NOT_LE; independent] THEN MESON_TAC[]);; + +let INDEPENDENT_IMP_FINITE = prove + (`!s:real^N->bool. independent s ==> FINITE s`, + SIMP_TAC[INDEPENDENT_BOUND]);; + +(* ------------------------------------------------------------------------- *) +(* Explicit formulation of independence. *) +(* ------------------------------------------------------------------------- *) + +let INDEPENDENT_EXPLICIT = prove + (`!b:real^N->bool. + independent b <=> + FINITE b /\ + !c. vsum b (\v. c(v) % v) = vec 0 ==> !v. v IN b ==> c(v) = &0`, + GEN_TAC THEN + ASM_CASES_TAC `FINITE(b:real^N->bool)` THENL + [ALL_TAC; ASM_MESON_TAC[INDEPENDENT_BOUND]] THEN + ASM_SIMP_TAC[independent; DEPENDENT_FINITE] THEN MESON_TAC[]);; + +let INDEPENDENT_SING = prove + (`!x. independent {x} <=> ~(x = vec 0)`, + REWRITE_TAC[INDEPENDENT_INSERT; NOT_IN_EMPTY; SPAN_EMPTY] THEN + REWRITE_TAC[INDEPENDENT_EMPTY] THEN SET_TAC[]);; + +let DEPENDENT_SING = prove + (`!x. dependent {x} <=> x = vec 0`, + MESON_TAC[independent; INDEPENDENT_SING]);; + +let DEPENDENT_2 = prove + (`!a b:real^N. + dependent {a,b} <=> + if a = b then a = vec 0 + else ?x y. x % a + y % b = vec 0 /\ ~(x = &0 /\ y = &0)`, + REPEAT STRIP_TAC THEN COND_CASES_TAC THEN + ASM_REWRITE_TAC[DEPENDENT_SING; SET_RULE `{x,x} = {x}`] THEN + SIMP_TAC[DEPENDENT_FINITE; VSUM_CLAUSES; FINITE_INSERT; FINITE_EMPTY] THEN + ASM_REWRITE_TAC[IN_SING; NOT_IN_EMPTY; VECTOR_ADD_RID; EXISTS_IN_INSERT] THEN + EQ_TAC THEN REWRITE_TAC[LEFT_IMP_EXISTS_THM] THENL + [X_GEN_TAC `u:real^N->real` THEN STRIP_TAC THEN + MAP_EVERY EXISTS_TAC [`(u:real^N->real) a`; `(u:real^N->real) b`] THEN + ASM_REWRITE_TAC[]; + MAP_EVERY X_GEN_TAC [`x:real`; `y:real`] THEN DISCH_TAC THEN EXISTS_TAC + `\v:real^N. if v = a then x else if v = b then y else z:real` THEN + ASM_MESON_TAC[]]);; + +let DEPENDENT_3 = prove + (`!a b c:real^N. + ~(a = b) /\ ~(a = c) /\ ~(b = c) + ==> (dependent {a,b,c} <=> + ?x y z. x % a + y % b + z % c = vec 0 /\ + ~(x = &0 /\ y = &0 /\ z = &0))`, + REPEAT STRIP_TAC THEN + SIMP_TAC[DEPENDENT_FINITE; VSUM_CLAUSES; FINITE_INSERT; FINITE_EMPTY] THEN + ASM_REWRITE_TAC[IN_SING; NOT_IN_EMPTY; VECTOR_ADD_RID; IN_INSERT] THEN + EQ_TAC THEN REWRITE_TAC[LEFT_IMP_EXISTS_THM] THENL + [X_GEN_TAC `u:real^N->real` THEN STRIP_TAC THEN MAP_EVERY EXISTS_TAC + [`(u:real^N->real) a`; `(u:real^N->real) b`; `(u:real^N->real) c`]; + MAP_EVERY X_GEN_TAC [`x:real`; `y:real`; `z:real`] THEN DISCH_TAC THEN + EXISTS_TAC + `\v:real^N. if v = a then x else if v = b then y else z:real`] THEN + ASM_MESON_TAC[]);; + +let INDEPENDENT_2 = prove + (`!a b:real^N x y. + independent{a,b} /\ ~(a = b) + ==> (x % a + y % b = vec 0 <=> x = &0 /\ y = &0)`, + SIMP_TAC[IMP_CONJ_ALT; independent; DEPENDENT_2] THEN + MESON_TAC[VECTOR_MUL_LZERO; VECTOR_ADD_LID]);; + +let INDEPENDENT_3 = prove + (`!a b c:real^N x y z. + independent{a,b,c} /\ ~(a = b) /\ ~(a = c) /\ ~(b = c) + ==> (x % a + y % b + z % c = vec 0 <=> x = &0 /\ y = &0 /\ z = &0)`, + SIMP_TAC[IMP_CONJ_ALT; independent; DEPENDENT_3] THEN + MESON_TAC[VECTOR_MUL_LZERO; VECTOR_ADD_LID]);; + +(* ------------------------------------------------------------------------- *) +(* Hence we can create a maximal independent subset. *) +(* ------------------------------------------------------------------------- *) + +let MAXIMAL_INDEPENDENT_SUBSET_EXTEND = prove + (`!s v:real^N->bool. + s SUBSET v /\ independent s + ==> ?b. s SUBSET b /\ b SUBSET v /\ independent b /\ + v SUBSET (span b)`, + REPEAT GEN_TAC THEN + WF_INDUCT_TAC `dimindex(:N) - CARD(s:real^N->bool)` THEN + REPEAT STRIP_TAC THEN + ASM_CASES_TAC `v SUBSET (span(s:real^N->bool))` THENL + [ASM_MESON_TAC[SUBSET_REFL]; ALL_TAC] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE RAND_CONV [SUBSET]) THEN + REWRITE_TAC[NOT_FORALL_THM; NOT_IMP] THEN + DISCH_THEN(X_CHOOSE_THEN `a:real^N` STRIP_ASSUME_TAC) THEN + FIRST_X_ASSUM(MP_TAC o SPEC `(a:real^N) INSERT s`) THEN + REWRITE_TAC[IMP_IMP] THEN ANTS_TAC THENL + [ALL_TAC; MESON_TAC[INSERT_SUBSET]] THEN + SUBGOAL_THEN `independent ((a:real^N) INSERT s)` ASSUME_TAC THENL + [ASM_REWRITE_TAC[INDEPENDENT_INSERT; COND_ID]; ALL_TAC] THEN + ASM_REWRITE_TAC[INSERT_SUBSET] THEN + MATCH_MP_TAC(ARITH_RULE `(b = a + 1) /\ b <= n ==> n - b < n - a`) THEN + ASM_SIMP_TAC[CARD_CLAUSES; INDEPENDENT_BOUND] THEN + ASM_MESON_TAC[SPAN_SUPERSET; ADD1]);; + +let MAXIMAL_INDEPENDENT_SUBSET = prove + (`!v:real^N->bool. ?b. b SUBSET v /\ independent b /\ v SUBSET (span b)`, + MP_TAC(SPEC `EMPTY:real^N->bool` MAXIMAL_INDEPENDENT_SUBSET_EXTEND) THEN + REWRITE_TAC[EMPTY_SUBSET; INDEPENDENT_EMPTY]);; + +(* ------------------------------------------------------------------------- *) +(* A kind of closed graph property for linearity. *) +(* ------------------------------------------------------------------------- *) + +let LINEAR_SUBSPACE_GRAPH = prove + (`!f:real^M->real^N. + linear f <=> subspace {pastecart x (f x) | x IN (:real^M)}`, + REWRITE_TAC[linear; subspace; IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN + REWRITE_TAC[FORALL_IN_GSPEC; GSYM(SPEC `0` PASTECART_VEC); IN_UNIV] THEN + REWRITE_TAC[IN_ELIM_THM; PASTECART_INJ; UNWIND_THM1; PASTECART_ADD; + GSYM PASTECART_CMUL] THEN + MESON_TAC[VECTOR_MUL_LZERO]);; + +(* ------------------------------------------------------------------------- *) +(* Notion of dimension. *) +(* ------------------------------------------------------------------------- *) + +let dim = new_definition + `dim v = @n. ?b. b SUBSET v /\ independent b /\ v SUBSET (span b) /\ + b HAS_SIZE n`;; + +let BASIS_EXISTS = prove + (`!v. ?b. b SUBSET v /\ independent b /\ v SUBSET (span b) /\ + b HAS_SIZE (dim v)`, + GEN_TAC THEN REWRITE_TAC[dim] THEN CONV_TAC SELECT_CONV THEN + MESON_TAC[MAXIMAL_INDEPENDENT_SUBSET; HAS_SIZE; INDEPENDENT_BOUND]);; + +let BASIS_EXISTS_FINITE = prove + (`!v. ?b. FINITE b /\ + b SUBSET v /\ + independent b /\ + v SUBSET (span b) /\ + b HAS_SIZE (dim v)`, + MESON_TAC[BASIS_EXISTS; INDEPENDENT_IMP_FINITE]);; + +let BASIS_SUBSPACE_EXISTS = prove + (`!s:real^N->bool. + subspace s + ==> ?b. FINITE b /\ + b SUBSET s /\ + independent b /\ + span b = s /\ + b HAS_SIZE dim s`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPEC `s:real^N->bool` BASIS_EXISTS) THEN + MATCH_MP_TAC MONO_EXISTS THEN REPEAT STRIP_TAC THEN + ASM_REWRITE_TAC[GSYM SUBSET_ANTISYM_EQ] THEN + ASM_MESON_TAC[SPAN_EQ_SELF; SPAN_MONO; INDEPENDENT_IMP_FINITE]);; + +(* ------------------------------------------------------------------------- *) +(* Consequences of independence or spanning for cardinality. *) +(* ------------------------------------------------------------------------- *) + +let INDEPENDENT_CARD_LE_DIM = prove + (`!v b:real^N->bool. + b SUBSET v /\ independent b ==> FINITE b /\ CARD(b) <= dim v`, + MESON_TAC[BASIS_EXISTS; INDEPENDENT_SPAN_BOUND; HAS_SIZE;SUBSET_TRANS]);; + +let SPAN_CARD_GE_DIM = prove + (`!v b:real^N->bool. + v SUBSET (span b) /\ FINITE b ==> dim(v) <= CARD(b)`, + MESON_TAC[BASIS_EXISTS; INDEPENDENT_SPAN_BOUND; HAS_SIZE;SUBSET_TRANS]);; + +let BASIS_CARD_EQ_DIM = prove + (`!v b. b SUBSET v /\ v SUBSET (span b) /\ independent b + ==> FINITE b /\ (CARD b = dim v)`, + MESON_TAC[LE_ANTISYM; INDEPENDENT_CARD_LE_DIM; SPAN_CARD_GE_DIM]);; + +let BASIS_HAS_SIZE_DIM = prove + (`!v b. independent b /\ span b = v ==> b HAS_SIZE (dim v)`, + REPEAT STRIP_TAC THEN REWRITE_TAC[HAS_SIZE] THEN + MATCH_MP_TAC BASIS_CARD_EQ_DIM THEN ASM_REWRITE_TAC[SUBSET_REFL] THEN + FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN REWRITE_TAC[SPAN_INC]);; + +let DIM_UNIQUE = prove + (`!v b. b SUBSET v /\ v SUBSET (span b) /\ independent b /\ b HAS_SIZE n + ==> (dim v = n)`, + MESON_TAC[BASIS_CARD_EQ_DIM; HAS_SIZE]);; + +let DIM_LE_CARD = prove + (`!s. FINITE s ==> dim s <= CARD s`, + GEN_TAC THEN DISCH_TAC THEN MATCH_MP_TAC SPAN_CARD_GE_DIM THEN + ASM_REWRITE_TAC[SPAN_INC; SUBSET_REFL]);; + +(* ------------------------------------------------------------------------- *) +(* More lemmas about dimension. *) +(* ------------------------------------------------------------------------- *) + +let DIM_UNIV = prove + (`dim(:real^N) = dimindex(:N)`, + MATCH_MP_TAC DIM_UNIQUE THEN + EXISTS_TAC `{basis i :real^N | 1 <= i /\ i <= dimindex(:N)}` THEN + REWRITE_TAC[SUBSET_UNIV; SPAN_STDBASIS; HAS_SIZE_STDBASIS; + INDEPENDENT_STDBASIS]);; + +let DIM_SUBSET = prove + (`!s t:real^N->bool. s SUBSET t ==> dim(s) <= dim(t)`, + MESON_TAC[BASIS_EXISTS; INDEPENDENT_SPAN_BOUND; SUBSET; HAS_SIZE]);; + +let DIM_SUBSET_UNIV = prove + (`!s:real^N->bool. dim(s) <= dimindex(:N)`, + GEN_TAC THEN REWRITE_TAC[GSYM DIM_UNIV] THEN + MATCH_MP_TAC DIM_SUBSET THEN REWRITE_TAC[SUBSET_UNIV]);; + +let BASIS_HAS_SIZE_UNIV = prove + (`!b. independent b /\ span b = (:real^N) ==> b HAS_SIZE (dimindex(:N))`, + REWRITE_TAC[GSYM DIM_UNIV; BASIS_HAS_SIZE_DIM]);; + +(* ------------------------------------------------------------------------- *) +(* Converses to those. *) +(* ------------------------------------------------------------------------- *) + +let CARD_GE_DIM_INDEPENDENT = prove + (`!v b:real^N->bool. + b SUBSET v /\ independent b /\ dim v <= CARD(b) + ==> v SUBSET (span b)`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN `!a:real^N. ~(a IN v /\ ~(a IN span b))` MP_TAC THENL + [ALL_TAC; SET_TAC[]] THEN + X_GEN_TAC `a:real^N` THEN STRIP_TAC THEN + SUBGOAL_THEN `independent((a:real^N) INSERT b)` ASSUME_TAC THENL + [ASM_MESON_TAC[INDEPENDENT_INSERT]; ALL_TAC] THEN + MP_TAC(ISPECL [`v:real^N->bool`; `(a:real^N) INSERT b`] + INDEPENDENT_CARD_LE_DIM) THEN + ASM_SIMP_TAC[INSERT_SUBSET; CARD_CLAUSES; INDEPENDENT_BOUND] THEN + ASM_MESON_TAC[SPAN_SUPERSET; SUBSET; ARITH_RULE + `x <= y ==> ~(SUC y <= x)`]);; + +let CARD_LE_DIM_SPANNING = prove + (`!v b:real^N->bool. + v SUBSET (span b) /\ FINITE b /\ CARD(b) <= dim v + ==> independent b`, + REPEAT STRIP_TAC THEN REWRITE_TAC[independent; dependent] THEN + DISCH_THEN(X_CHOOSE_THEN `a:real^N` STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN `dim(v:real^N->bool) <= CARD(b DELETE (a:real^N))` MP_TAC THENL + [ALL_TAC; + ASM_SIMP_TAC[CARD_DELETE] THEN MATCH_MP_TAC + (ARITH_RULE `b <= n /\ ~(b = 0) ==> ~(n <= b - 1)`) THEN + ASM_SIMP_TAC[CARD_EQ_0] THEN ASM_MESON_TAC[MEMBER_NOT_EMPTY]] THEN + MATCH_MP_TAC SPAN_CARD_GE_DIM THEN ASM_SIMP_TAC[FINITE_DELETE] THEN + REWRITE_TAC[SUBSET] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC SPAN_TRANS THEN EXISTS_TAC `a:real^N` THEN + ASM_SIMP_TAC[SET_RULE `a IN b ==> (a INSERT (b DELETE a) = b)`] THEN + ASM_MESON_TAC[SUBSET]);; + +let CARD_EQ_DIM = prove + (`!v b. b SUBSET v /\ b HAS_SIZE (dim v) + ==> (independent b <=> v SUBSET (span b))`, + REWRITE_TAC[HAS_SIZE; GSYM LE_ANTISYM] THEN + MESON_TAC[CARD_LE_DIM_SPANNING; CARD_GE_DIM_INDEPENDENT]);; + +(* ------------------------------------------------------------------------- *) +(* More general size bound lemmas. *) +(* ------------------------------------------------------------------------- *) + +let INDEPENDENT_BOUND_GENERAL = prove + (`!s:real^N->bool. independent s ==> FINITE s /\ CARD(s) <= dim(s)`, + MESON_TAC[INDEPENDENT_CARD_LE_DIM; INDEPENDENT_BOUND; SUBSET_REFL]);; + +let DEPENDENT_BIGGERSET_GENERAL = prove + (`!s:real^N->bool. (FINITE s ==> CARD(s) > dim(s)) ==> dependent s`, + MP_TAC INDEPENDENT_BOUND_GENERAL THEN MATCH_MP_TAC MONO_FORALL THEN + REWRITE_TAC[GT; GSYM NOT_LE; independent] THEN MESON_TAC[]);; + +let DIM_SPAN = prove + (`!s:real^N->bool. dim(span s) = dim s`, + GEN_TAC THEN REWRITE_TAC[GSYM LE_ANTISYM] THEN CONJ_TAC THENL + [ALL_TAC; + MATCH_MP_TAC DIM_SUBSET THEN MESON_TAC[SUBSET; SPAN_SUPERSET]] THEN + MP_TAC(ISPEC `s:real^N->bool` BASIS_EXISTS) THEN + REWRITE_TAC[HAS_SIZE] THEN STRIP_TAC THEN + FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN + MATCH_MP_TAC SPAN_CARD_GE_DIM THEN ASM_REWRITE_TAC[] THEN + GEN_REWRITE_TAC RAND_CONV [GSYM SPAN_SPAN] THEN + MATCH_MP_TAC SPAN_MONO THEN ASM_REWRITE_TAC[]);; + +let DIM_INSERT_0 = prove + (`!s:real^N->bool. dim(vec 0 INSERT s) = dim s`, + ONCE_REWRITE_TAC[GSYM DIM_SPAN] THEN + REWRITE_TAC[SPAN_INSERT_0]);; + +let DIM_EQ_CARD = prove + (`!s:real^N->bool. independent s ==> dim s = CARD s`, + REPEAT STRIP_TAC THEN MP_TAC + (ISPECL [`span s:real^N->bool`; `s:real^N->bool`] BASIS_CARD_EQ_DIM) THEN + ASM_SIMP_TAC[SUBSET_REFL; SPAN_INC; DIM_SPAN]);; + +let SUBSET_LE_DIM = prove + (`!s t:real^N->bool. s SUBSET (span t) ==> dim s <= dim t`, + MESON_TAC[DIM_SPAN; DIM_SUBSET]);; + +let SPAN_EQ_DIM = prove + (`!s t. span s = span t ==> dim s = dim t`, + MESON_TAC[DIM_SPAN]);; + +let SPANS_IMAGE = prove + (`!f b v. linear f /\ v SUBSET (span b) + ==> (IMAGE f v) SUBSET span(IMAGE f b)`, + SIMP_TAC[SPAN_LINEAR_IMAGE; IMAGE_SUBSET]);; + +let DIM_LINEAR_IMAGE_LE = prove + (`!f:real^M->real^N s. linear f ==> dim(IMAGE f s) <= dim s`, + REPEAT STRIP_TAC THEN MP_TAC(ISPEC `s:real^M->bool` BASIS_EXISTS) THEN + REWRITE_TAC[HAS_SIZE] THEN STRIP_TAC THEN FIRST_ASSUM(SUBST1_TAC o SYM) THEN + MATCH_MP_TAC LE_TRANS THEN EXISTS_TAC `CARD(IMAGE (f:real^M->real^N) b)` THEN + ASM_SIMP_TAC[CARD_IMAGE_LE] THEN MATCH_MP_TAC SPAN_CARD_GE_DIM THEN + ASM_MESON_TAC[SPAN_LINEAR_IMAGE; SPANS_IMAGE; SUBSET_IMAGE; FINITE_IMAGE]);; + +(* ------------------------------------------------------------------------- *) +(* Some stepping theorems. *) +(* ------------------------------------------------------------------------- *) + +let DIM_EMPTY = prove + (`dim({}:real^N->bool) = 0`, + MATCH_MP_TAC DIM_UNIQUE THEN EXISTS_TAC `{}:real^N->bool` THEN + REWRITE_TAC[SUBSET_REFL; SPAN_EMPTY; INDEPENDENT_EMPTY; HAS_SIZE_0; + EMPTY_SUBSET]);; + +let DIM_INSERT = prove + (`!x:real^N s. dim(x INSERT s) = if x IN span s then dim s else dim s + 1`, + REPEAT GEN_TAC THEN COND_CASES_TAC THENL + [MATCH_MP_TAC SPAN_EQ_DIM THEN MATCH_MP_TAC SUBSET_ANTISYM THEN + ASM_MESON_TAC[SPAN_TRANS; SUBSET; SPAN_MONO; IN_INSERT]; + ALL_TAC] THEN + X_CHOOSE_THEN `b:real^N->bool` STRIP_ASSUME_TAC + (ISPEC `span s:real^N->bool` BASIS_EXISTS) THEN + ONCE_REWRITE_TAC[GSYM DIM_SPAN] THEN + MATCH_MP_TAC DIM_UNIQUE THEN + EXISTS_TAC `(x:real^N) INSERT b` THEN REPEAT CONJ_TAC THENL + [REWRITE_TAC[INSERT_SUBSET] THEN + ASM_MESON_TAC[SUBSET; SPAN_MONO; IN_INSERT; SPAN_SUPERSET]; + REWRITE_TAC[SUBSET; SPAN_BREAKDOWN_EQ] THEN + ASM_MESON_TAC[SUBSET]; + REWRITE_TAC[INDEPENDENT_INSERT] THEN + ASM_MESON_TAC[SUBSET; SPAN_SUPERSET; SPAN_MONO; SPAN_SPAN]; + RULE_ASSUM_TAC(REWRITE_RULE[HAS_SIZE]) THEN + ASM_SIMP_TAC[HAS_SIZE; CARD_CLAUSES; FINITE_INSERT; ADD1] THEN + ASM_MESON_TAC[SUBSET; SPAN_SUPERSET; SPAN_MONO; SPAN_SPAN]]);; + +let DIM_SING = prove + (`!x. dim{x} = if x = vec 0 then 0 else 1`, + REWRITE_TAC[DIM_INSERT; DIM_EMPTY; SPAN_EMPTY; IN_SING; ARITH]);; + +let DIM_EQ_0 = prove + (`!s:real^N->bool. dim s = 0 <=> s SUBSET {vec 0}`, + REPEAT STRIP_TAC THEN EQ_TAC THEN DISCH_TAC THENL + [MATCH_MP_TAC(SET_RULE + `~(?b. ~(b = a) /\ {b} SUBSET s) ==> s SUBSET {a}`) THEN + STRIP_TAC THEN FIRST_X_ASSUM(MP_TAC o MATCH_MP DIM_SUBSET); + MATCH_MP_TAC(ARITH_RULE `!m. m = 0 /\ n <= m ==> n = 0`) THEN + EXISTS_TAC `dim{vec 0:real^N}` THEN ASM_SIMP_TAC[DIM_SUBSET]] THEN + ASM_REWRITE_TAC[DIM_SING; ARITH]);; + +(* ------------------------------------------------------------------------- *) +(* Choosing a subspace of a given dimension. *) +(* ------------------------------------------------------------------------- *) + +let CHOOSE_SUBSPACE_OF_SUBSPACE = prove + (`!s:real^N->bool n. + n <= dim s ==> ?t. subspace t /\ t SUBSET span s /\ dim t = n`, + GEN_TAC THEN INDUCT_TAC THENL + [DISCH_TAC THEN EXISTS_TAC `{vec 0:real^N}` THEN + REWRITE_TAC[SUBSPACE_TRIVIAL; DIM_SING; SING_SUBSET; SPAN_0]; + DISCH_THEN(fun th -> POP_ASSUM MP_TAC THEN ASSUME_TAC th) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN + DISCH_THEN(X_CHOOSE_THEN `t:real^N->bool` STRIP_ASSUME_TAC) THEN + ASM_CASES_TAC `span (s:real^N->bool) SUBSET span t` THENL + [SUBGOAL_THEN `dim(s:real^N->bool) = dim(t:real^N->bool)` MP_TAC THENL + [ALL_TAC; ASM_ARITH_TAC] THEN MATCH_MP_TAC SPAN_EQ_DIM THEN + MATCH_MP_TAC SUBSET_ANTISYM THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC SPAN_SUBSET_SUBSPACE THEN ASM_REWRITE_TAC[SUBSPACE_SPAN]; + FIRST_ASSUM(X_CHOOSE_THEN `y:real^N` STRIP_ASSUME_TAC o MATCH_MP(SET_RULE + `~(s SUBSET t) ==> ?a. a IN s /\ ~(a IN t)`)) THEN + EXISTS_TAC `span((y:real^N) INSERT t)` THEN + REWRITE_TAC[SUBSPACE_SPAN] THEN CONJ_TAC THENL + [MATCH_MP_TAC SPAN_SUBSET_SUBSPACE THEN + ASM_REWRITE_TAC[SUBSPACE_SPAN] THEN ASM SET_TAC[]; + ASM_REWRITE_TAC[DIM_SPAN; DIM_INSERT; ADD1]]]]);; + +(* ------------------------------------------------------------------------- *) +(* Relation between bases and injectivity/surjectivity of map. *) +(* ------------------------------------------------------------------------- *) + +let SPANNING_SURJECTIVE_IMAGE = prove + (`!f:real^M->real^N s. + UNIV SUBSET (span s) /\ linear f /\ (!y. ?x. f(x) = y) + ==> UNIV SUBSET span(IMAGE f s)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC SUBSET_TRANS THEN + EXISTS_TAC `IMAGE (f:real^M->real^N) UNIV` THEN + ASM_SIMP_TAC[SPANS_IMAGE] THEN + REWRITE_TAC[SUBSET; IN_UNIV; IN_IMAGE] THEN ASM_MESON_TAC[]);; + +let INDEPENDENT_INJECTIVE_IMAGE_GEN = prove + (`!f:real^M->real^N s. + independent s /\ linear f /\ + (!x y. x IN span s /\ y IN span s /\ f(x) = f(y) ==> x = y) + ==> independent (IMAGE f s)`, + REPEAT GEN_TAC THEN + DISCH_THEN(CONJUNCTS_THEN2 MP_TAC STRIP_ASSUME_TAC) THEN + ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN + REWRITE_TAC[independent; DEPENDENT_EXPLICIT] THEN + REWRITE_TAC[CONJ_ASSOC; FINITE_SUBSET_IMAGE] THEN + REWRITE_TAC[MESON[] + `(?s u. ((?t. p t /\ s = f t) /\ q s u) /\ r s u) <=> + (?t u. p t /\ q (f t) u /\ r (f t) u)`] THEN + REWRITE_TAC[EXISTS_IN_IMAGE; LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`t:real^M->bool`; `u:real^N->real`] THEN + DISCH_THEN(REPEAT_TCL CONJUNCTS_THEN ASSUME_TAC) THEN + MAP_EVERY EXISTS_TAC + [`t:real^M->bool`; `(u:real^N->real) o (f:real^M->real^N)`] THEN + ASM_REWRITE_TAC[o_THM] THEN + FIRST_ASSUM MATCH_MP_TAC THEN REPEAT CONJ_TAC THENL + [MATCH_MP_TAC SPAN_VSUM THEN ASM_REWRITE_TAC[] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC SPAN_MUL THEN + MATCH_MP_TAC SPAN_SUPERSET THEN ASM SET_TAC[]; + REWRITE_TAC[SPAN_0]; + ASM_SIMP_TAC[LINEAR_VSUM] THEN + FIRST_ASSUM(SUBST1_TAC o MATCH_MP LINEAR_0) THEN + FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN CONV_TAC SYM_CONV THEN + W(MP_TAC o PART_MATCH (lhs o rand) VSUM_IMAGE o lhand o snd) THEN + ASM_SIMP_TAC[o_DEF; LINEAR_CMUL] THEN DISCH_THEN MATCH_MP_TAC THEN + ASM_MESON_TAC[SPAN_SUPERSET; SUBSET]]);; + +let INDEPENDENT_INJECTIVE_IMAGE = prove + (`!f:real^M->real^N s. + independent s /\ linear f /\ (!x y. (f(x) = f(y)) ==> (x = y)) + ==> independent (IMAGE f s)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC INDEPENDENT_INJECTIVE_IMAGE_GEN THEN + ASM_MESON_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* Picking an orthogonal replacement for a spanning set. *) +(* ------------------------------------------------------------------------- *) + +let VECTOR_SUB_PROJECT_ORTHOGONAL = prove + (`!b:real^N x. b dot (x - ((b dot x) / (b dot b)) % b) = &0`, + REPEAT GEN_TAC THEN ASM_CASES_TAC `b = vec 0 :real^N` THENL + [ASM_REWRITE_TAC[DOT_LZERO]; ALL_TAC] THEN + ASM_SIMP_TAC[DOT_RSUB; DOT_RMUL] THEN + ASM_SIMP_TAC[REAL_SUB_REFL; REAL_DIV_RMUL; DOT_EQ_0]);; + +let BASIS_ORTHOGONAL = prove + (`!b:real^N->bool. + FINITE b + ==> ?c. FINITE c /\ CARD c <= CARD b /\ + span c = span b /\ pairwise orthogonal c`, + REWRITE_TAC[pairwise; orthogonal] THEN MATCH_MP_TAC FINITE_INDUCT_STRONG THEN + CONJ_TAC THENL + [EXISTS_TAC `{}:real^N->bool` THEN + REWRITE_TAC[FINITE_RULES; NOT_IN_EMPTY; LE_REFL]; + ALL_TAC] THEN + MAP_EVERY X_GEN_TAC [`a:real^N`; `b:real^N->bool`] THEN + DISCH_THEN(CONJUNCTS_THEN2 (X_CHOOSE_THEN `c:real^N->bool` STRIP_ASSUME_TAC) + STRIP_ASSUME_TAC) THEN + EXISTS_TAC `(a - vsum c (\x. ((x dot a) / (x dot x)) % x):real^N) + INSERT c` THEN + ASM_SIMP_TAC[FINITE_RULES; CARD_CLAUSES] THEN REPEAT CONJ_TAC THENL + [ASM_ARITH_TAC; + REWRITE_TAC[EXTENSION; SPAN_BREAKDOWN_EQ] THEN + FIRST_X_ASSUM(SUBST_ALL_TAC o SYM) THEN GEN_TAC THEN + AP_TERM_TAC THEN ABS_TAC THEN REWRITE_TAC[VECTOR_SUB_LDISTRIB] THEN + REWRITE_TAC[VECTOR_ARITH `a - (x - y):real^N = y + (a - x)`] THEN + MATCH_MP_TAC SPAN_ADD_EQ THEN MATCH_MP_TAC SPAN_MUL THEN + MATCH_MP_TAC SPAN_VSUM THEN ASM_REWRITE_TAC[] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC SPAN_MUL THEN + ASM_SIMP_TAC[SPAN_SUPERSET]; + REWRITE_TAC[IN_INSERT] THEN REPEAT STRIP_TAC THENL + [ASM_MESON_TAC[]; + FIRST_X_ASSUM SUBST_ALL_TAC; + FIRST_X_ASSUM SUBST_ALL_TAC; + ASM_MESON_TAC[]] THEN + REWRITE_TAC[DOT_LSUB; DOT_RSUB; REAL_SUB_0] THEN + FIRST_ASSUM(SUBST1_TAC o MATCH_MP (SET_RULE + `x IN s ==> s = x INSERT (s DELETE x)`)) THEN + ASM_SIMP_TAC[VSUM_CLAUSES; FINITE_DELETE; IN_DELETE] THEN + REWRITE_TAC[DOT_LADD; DOT_RADD; DOT_LMUL; DOT_RMUL] THEN + MATCH_MP_TAC(REAL_ARITH `s = &0 /\ a = b ==> b = a + s`) THEN + ASM_SIMP_TAC[DOT_LSUM; DOT_RSUM; FINITE_DELETE] THEN + (CONJ_TAC THENL + [MATCH_MP_TAC SUM_EQ_0 THEN + ASM_SIMP_TAC[DOT_LMUL; DOT_RMUL; IN_DELETE; + REAL_MUL_RZERO; REAL_MUL_LZERO]; + W(MP_TAC o PART_MATCH (lhand o rand) REAL_DIV_RMUL o lhand o snd) THEN + REWRITE_TAC[DOT_SYM] THEN + MATCH_MP_TAC(TAUT `(p ==> q) ==> (~p ==> q) ==> q`) THEN + SIMP_TAC[] THEN SIMP_TAC[DOT_EQ_0; DOT_RZERO; DOT_LZERO] THEN + REWRITE_TAC[REAL_MUL_LZERO; REAL_MUL_RZERO]])]);; + +let ORTHOGONAL_BASIS_EXISTS = prove + (`!v:real^N->bool. + ?b. independent b /\ + b SUBSET span v /\ + v SUBSET span b /\ + b HAS_SIZE dim v /\ + pairwise orthogonal b`, + GEN_TAC THEN MP_TAC(ISPEC `v:real^N->bool` BASIS_EXISTS) THEN + DISCH_THEN(X_CHOOSE_THEN `b:real^N->bool` STRIP_ASSUME_TAC) THEN + MP_TAC(SPEC `b:real^N->bool` BASIS_ORTHOGONAL) THEN + ANTS_TAC THENL [ASM_MESON_TAC[HAS_SIZE]; ALL_TAC] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `c:real^N->bool` THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN REPEAT CONJ_TAC THENL + [MATCH_MP_TAC CARD_LE_DIM_SPANNING THEN ASM_REWRITE_TAC[] THEN + EXISTS_TAC `span(v):real^N->bool` THEN CONJ_TAC THENL + [ASM_MESON_TAC[SPAN_SPAN; SPAN_MONO]; + ASM_MESON_TAC[LE_TRANS; HAS_SIZE; DIM_SPAN]]; + ASM_MESON_TAC[SUBSET_TRANS; SPAN_INC; SPAN_SPAN; SPAN_MONO]; + RULE_ASSUM_TAC(REWRITE_RULE[HAS_SIZE]) THEN + ASM_REWRITE_TAC[HAS_SIZE; GSYM LE_ANTISYM] THEN + CONJ_TAC THENL [ASM_MESON_TAC[LE_TRANS]; ALL_TAC] THEN + ONCE_REWRITE_TAC[GSYM DIM_SPAN] THEN MATCH_MP_TAC SPAN_CARD_GE_DIM THEN + ASM_REWRITE_TAC[] THEN + ASM_MESON_TAC[SPAN_SPAN; SPAN_MONO; SUBSET_TRANS; SPAN_INC]]);; + +let SPAN_EQ = prove + (`!s t. span s = span t <=> s SUBSET span t /\ t SUBSET span s`, + REWRITE_TAC[GSYM SUBSET_ANTISYM_EQ] THEN + MESON_TAC[SUBSET_TRANS; SPAN_SPAN; SPAN_MONO; SPAN_INC]);; + +let SPAN_EQ_INSERT = prove + (`!s x. span(x INSERT s) = span s <=> x IN span s`, + REWRITE_TAC[SPAN_EQ; INSERT_SUBSET] THEN + MESON_TAC[SPAN_INC; SUBSET; SET_RULE `s SUBSET (x INSERT s)`]);; + +(* ------------------------------------------------------------------------- *) +(* We can extend a linear basis-basis injection to the whole set. *) +(* ------------------------------------------------------------------------- *) + +let LINEAR_INDEP_IMAGE_LEMMA = prove + (`!f b. linear(f:real^M->real^N) /\ + FINITE b /\ + independent (IMAGE f b) /\ + (!x y. x IN b /\ y IN b /\ (f x = f y) ==> (x = y)) + ==> !x. x IN span b ==> (f(x) = vec 0) ==> (x = vec 0)`, + REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN + GEN_TAC THEN DISCH_TAC THEN + GEN_REWRITE_TAC (BINDER_CONV o RAND_CONV) [IMP_IMP] THEN + MATCH_MP_TAC FINITE_INDUCT_STRONG THEN + CONJ_TAC THENL [SIMP_TAC[IN_SING; SPAN_EMPTY]; ALL_TAC] THEN + MAP_EVERY X_GEN_TAC [`a:real^M`; `b:real^M->bool`] THEN STRIP_TAC THEN + STRIP_TAC THEN FIRST_X_ASSUM(MP_TAC o check (is_imp o concl)) THEN + ANTS_TAC THENL + [ASM_MESON_TAC[INDEPENDENT_MONO; IMAGE_CLAUSES; SUBSET; IN_INSERT]; + ALL_TAC] THEN + DISCH_TAC THEN X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN + MP_TAC(ISPECL [`a:real^M`; `(a:real^M) INSERT b`; `x:real^M`] + SPAN_BREAKDOWN) THEN + ASM_REWRITE_TAC[IN_INSERT] THEN + SIMP_TAC[ASSUME `~((a:real^M) IN b)`; SET_RULE + `~(a IN b) ==> ((a INSERT b) DELETE a = b)`] THEN + DISCH_THEN(X_CHOOSE_THEN `k:real` STRIP_ASSUME_TAC) THEN DISCH_TAC THEN + SUBGOAL_THEN `(f:real^M->real^N)(x - k % a) IN span(IMAGE f b)` MP_TAC THENL + [ASM_MESON_TAC[SPAN_LINEAR_IMAGE; IN_IMAGE]; ALL_TAC] THEN + FIRST_ASSUM(fun th -> REWRITE_TAC[MATCH_MP LINEAR_SUB th]) THEN + FIRST_ASSUM(fun th -> REWRITE_TAC[MATCH_MP LINEAR_CMUL th]) THEN + ASM_REWRITE_TAC[VECTOR_ARITH `vec 0 - k % x = (--k) % x`] THEN + ASM_CASES_TAC `k = &0` THENL + [ASM_MESON_TAC[VECTOR_ARITH `x - &0 % y = x`]; ALL_TAC] THEN + DISCH_THEN(MP_TAC o SPEC `--inv(k)` o MATCH_MP SPAN_MUL) THEN + REWRITE_TAC[VECTOR_MUL_ASSOC; REAL_MUL_LNEG; REAL_MUL_RNEG] THEN + SIMP_TAC[REAL_NEGNEG; REAL_MUL_LINV; ASSUME `~(k = &0)`] THEN + REWRITE_TAC[VECTOR_MUL_LID] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [independent]) THEN + REWRITE_TAC[dependent; NOT_EXISTS_THM] THEN + DISCH_THEN(MP_TAC o SPEC `(f:real^M->real^N) a`) THEN + SUBGOAL_THEN + `IMAGE (f:real^M->real^N) (a INSERT b) DELETE f a = + IMAGE f ((a INSERT b) DELETE a)` + SUBST1_TAC THENL + [REWRITE_TAC[EXTENSION; IN_IMAGE; IN_DELETE; IN_INSERT] THEN + ASM_MESON_TAC[IN_INSERT]; + ALL_TAC] THEN + ASM_REWRITE_TAC[DELETE_INSERT] THEN + SIMP_TAC[SET_RULE `~(a IN b) ==> (b DELETE a = b)`; + ASSUME `~(a:real^M IN b)`] THEN + SIMP_TAC[IMAGE_CLAUSES; IN_INSERT]);; + +(* ------------------------------------------------------------------------- *) +(* We can extend a linear mapping from basis. *) +(* ------------------------------------------------------------------------- *) + +let LINEAR_INDEPENDENT_EXTEND_LEMMA = prove + (`!f b. FINITE b + ==> independent b + ==> ?g:real^M->real^N. + (!x y. x IN span b /\ y IN span b + ==> (g(x + y) = g(x) + g(y))) /\ + (!x c. x IN span b ==> (g(c % x) = c % g(x))) /\ + (!x. x IN b ==> (g x = f x))`, + GEN_TAC THEN MATCH_MP_TAC FINITE_INDUCT_STRONG THEN + REWRITE_TAC[NOT_IN_EMPTY; INDEPENDENT_INSERT] THEN CONJ_TAC THENL + [REPEAT STRIP_TAC THEN EXISTS_TAC `(\x. vec 0):real^M->real^N` THEN + SIMP_TAC[SPAN_EMPTY] THEN REPEAT STRIP_TAC THEN VECTOR_ARITH_TAC; + ALL_TAC] THEN + SIMP_TAC[] THEN MAP_EVERY X_GEN_TAC [`a:real^M`; `b:real^M->bool`] THEN + DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(CONJUNCTS_THEN2 MP_TAC STRIP_ASSUME_TAC) THEN + DISCH_THEN(X_CHOOSE_THEN `g:real^M->real^N` STRIP_ASSUME_TAC) THEN + ABBREV_TAC `h = \z:real^M. @k. (z - k % a) IN span b` THEN + SUBGOAL_THEN `!z:real^M. z IN span(a INSERT b) + ==> (z - h(z) % a) IN span(b) /\ + !k. (z - k % a) IN span(b) ==> (k = h(z))` + MP_TAC THENL + [GEN_TAC THEN DISCH_TAC THEN + MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN CONJ_TAC THENL + [EXPAND_TAC "h" THEN CONV_TAC SELECT_CONV THEN + ASM_MESON_TAC[SPAN_BREAKDOWN_EQ]; + ALL_TAC] THEN + REWRITE_TAC[RIGHT_IMP_FORALL_THM; IMP_IMP] THEN GEN_TAC THEN + DISCH_THEN(MP_TAC o MATCH_MP SPAN_SUB) THEN + REWRITE_TAC[VECTOR_ARITH `(z - a % v) - (z - b % v) = (b - a) % v`] THEN + ASM_CASES_TAC `k = (h:real^M->real) z` THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(MP_TAC o SPEC `inv(k - (h:real^M->real) z)` o + MATCH_MP SPAN_MUL) THEN + ASM_SIMP_TAC[REAL_MUL_LINV; VECTOR_MUL_ASSOC; REAL_SUB_0] THEN + ASM_REWRITE_TAC[VECTOR_MUL_LID]; + ALL_TAC] THEN + REWRITE_TAC[TAUT `(a ==> b /\ c) <=> (a ==> b) /\ (a ==> c)`] THEN + REWRITE_TAC[RIGHT_IMP_FORALL_THM; IMP_IMP] THEN + GEN_REWRITE_TAC LAND_CONV [FORALL_AND_THM] THEN STRIP_TAC THEN + EXISTS_TAC `\z:real^M. h(z) % (f:real^M->real^N)(a) + g(z - h(z) % a)` THEN + REPEAT CONJ_TAC THENL + [MAP_EVERY X_GEN_TAC [`x:real^M`; `y:real^M`] THEN STRIP_TAC THEN + SUBGOAL_THEN `(h:real^M->real)(x + y) = h(x) + h(y)` ASSUME_TAC THENL + [CONV_TAC SYM_CONV THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + REWRITE_TAC[VECTOR_ARITH + `(x + y) - (k + l) % a = (x - k % a) + (y - l % a)`] THEN + CONJ_TAC THEN MATCH_MP_TAC SPAN_ADD THEN ASM_REWRITE_TAC[] THEN + ASM_SIMP_TAC[]; + ALL_TAC] THEN + ASM_REWRITE_TAC[VECTOR_ARITH + `(x + y) - (k + l) % a = (x - k % a) + (y - l % a)`] THEN + ASM_SIMP_TAC[] THEN VECTOR_ARITH_TAC; + MAP_EVERY X_GEN_TAC [`x:real^M`; `c:real`] THEN STRIP_TAC THEN + SUBGOAL_THEN `(h:real^M->real)(c % x) = c * h(x)` ASSUME_TAC THENL + [CONV_TAC SYM_CONV THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + REWRITE_TAC[VECTOR_ARITH + `c % x - (c * k) % a = c % (x - k % a)`] THEN + CONJ_TAC THEN MATCH_MP_TAC SPAN_MUL THEN ASM_REWRITE_TAC[] THEN + ASM_SIMP_TAC[]; + ALL_TAC] THEN + ASM_REWRITE_TAC[VECTOR_ARITH + `c % x - (c * k) % a = c % (x - k % a)`] THEN + ASM_SIMP_TAC[] THEN VECTOR_ARITH_TAC; + ALL_TAC] THEN + X_GEN_TAC `x:real^M` THEN REWRITE_TAC[IN_INSERT] THEN + DISCH_THEN(DISJ_CASES_THEN2 SUBST_ALL_TAC ASSUME_TAC) THENL + [SUBGOAL_THEN `&1 = h(a:real^M)` (SUBST1_TAC o SYM) THENL + [FIRST_X_ASSUM MATCH_MP_TAC; ALL_TAC] THEN + REWRITE_TAC[VECTOR_ARITH `a - &1 % a = vec 0`; SPAN_0] THENL + [ASM_MESON_TAC[SPAN_SUPERSET; SUBSET; IN_INSERT]; ALL_TAC] THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`vec 0:real^M`; `vec 0:real^M`]) THEN + REWRITE_TAC[SPAN_0; VECTOR_ADD_LID] THEN + REWRITE_TAC[VECTOR_ARITH `(a = a + a) <=> (a = vec 0)`] THEN + DISCH_THEN SUBST1_TAC THEN VECTOR_ARITH_TAC; + ALL_TAC] THEN + SUBGOAL_THEN `&0 = h(x:real^M)` (SUBST1_TAC o SYM) THENL + [FIRST_X_ASSUM MATCH_MP_TAC; ALL_TAC] THEN + REWRITE_TAC[VECTOR_ADD_LID; VECTOR_MUL_LZERO; VECTOR_SUB_RZERO] THEN + ASM_MESON_TAC[SUBSET; IN_INSERT; SPAN_SUPERSET]);; + +let LINEAR_INDEPENDENT_EXTEND = prove + (`!f b. independent b + ==> ?g:real^M->real^N. linear g /\ (!x. x IN b ==> (g x = f x))`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`b:real^M->bool`; `(:real^M)`] + MAXIMAL_INDEPENDENT_SUBSET_EXTEND) THEN + ASM_REWRITE_TAC[SUBSET_UNIV; UNIV_SUBSET] THEN + REWRITE_TAC[EXTENSION; IN_UNIV] THEN + DISCH_THEN(X_CHOOSE_THEN `c:real^M->bool` STRIP_ASSUME_TAC) THEN + MP_TAC(ISPECL [`f:real^M->real^N`; `c:real^M->bool`] + LINEAR_INDEPENDENT_EXTEND_LEMMA) THEN + ASM_SIMP_TAC[INDEPENDENT_BOUND; linear] THEN + ASM_MESON_TAC[SUBSET]);; + +(* ------------------------------------------------------------------------- *) +(* Linear functions are equal on a subspace if they are on a spanning set. *) +(* ------------------------------------------------------------------------- *) + +let SUBSPACE_KERNEL = prove + (`!f. linear f ==> subspace {x | f(x) = vec 0}`, + REWRITE_TAC[subspace; IN_ELIM_THM] THEN + SIMP_TAC[LINEAR_ADD; LINEAR_CMUL; VECTOR_ADD_LID; VECTOR_MUL_RZERO] THEN + MESON_TAC[LINEAR_0]);; + +let LINEAR_EQ_0_SPAN = prove + (`!f:real^M->real^N b. + linear f /\ (!x. x IN b ==> f(x) = vec 0) + ==> !x. x IN span(b) ==> f(x) = vec 0`, + REPEAT GEN_TAC THEN STRIP_TAC THEN + RULE_ASSUM_TAC(REWRITE_RULE[IN]) THEN + MATCH_MP_TAC SPAN_INDUCT THEN ASM_REWRITE_TAC[IN] THEN + MP_TAC(ISPEC `f:real^M->real^N` SUBSPACE_KERNEL) THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC EQ_IMP THEN + AP_TERM_TAC THEN REWRITE_TAC[EXTENSION; IN_ELIM_THM]);; + +let LINEAR_EQ_0 = prove + (`!f b s. linear f /\ s SUBSET (span b) /\ (!x. x IN b ==> f(x) = vec 0) + ==> !x. x IN s ==> f(x) = vec 0`, + MESON_TAC[LINEAR_EQ_0_SPAN; SUBSET]);; + +let LINEAR_EQ = prove + (`!f g b s. linear f /\ linear g /\ s SUBSET (span b) /\ + (!x. x IN b ==> f(x) = g(x)) + ==> !x. x IN s ==> f(x) = g(x)`, + REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[GSYM VECTOR_SUB_EQ] THEN + STRIP_TAC THEN MATCH_MP_TAC LINEAR_EQ_0 THEN + ASM_MESON_TAC[LINEAR_COMPOSE_SUB]);; + +let LINEAR_EQ_STDBASIS = prove + (`!f:real^M->real^N g. + linear f /\ linear g /\ + (!i. 1 <= i /\ i <= dimindex(:M) + ==> f(basis i) = g(basis i)) + ==> f = g`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN `!x. x IN UNIV ==> (f:real^M->real^N) x = g x` + (fun th -> MP_TAC th THEN REWRITE_TAC[FUN_EQ_THM; IN_UNIV]) THEN + MATCH_MP_TAC LINEAR_EQ THEN + EXISTS_TAC `{basis i :real^M | 1 <= i /\ i <= dimindex(:M)}` THEN + ASM_REWRITE_TAC[SPAN_STDBASIS; SUBSET_REFL; IN_ELIM_THM] THEN + ASM_MESON_TAC[]);; + +let SUBSPACE_LINEAR_FIXED_POINTS = prove + (`!f:real^N->real^N. linear f ==> subspace {x | f(x) = x}`, + REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[GSYM VECTOR_SUB_EQ] THEN + MATCH_MP_TAC SUBSPACE_KERNEL THEN + ASM_SIMP_TAC[LINEAR_COMPOSE_SUB; LINEAR_ID]);; + +(* ------------------------------------------------------------------------- *) +(* Similar results for bilinear functions. *) +(* ------------------------------------------------------------------------- *) + +let BILINEAR_EQ = prove + (`!f:real^M->real^N->real^P g b c s. + bilinear f /\ bilinear g /\ + s SUBSET (span b) /\ t SUBSET (span c) /\ + (!x y. x IN b /\ y IN c ==> f x y = g x y) + ==> !x y. x IN s /\ y IN t ==> f x y = g x y`, + REPEAT STRIP_TAC THEN SUBGOAL_THEN + `!x:real^M. x IN span b + ==> !y:real^N. y IN span c ==> (f x y :real^P = g x y)` + (fun th -> ASM_MESON_TAC[th; SUBSET]) THEN + MATCH_MP_TAC SPAN_INDUCT THEN REWRITE_TAC[subspace; IN_ELIM_THM] THEN + CONJ_TAC THENL + [GEN_TAC THEN DISCH_TAC; + ASM_SIMP_TAC[BILINEAR_LADD; BILINEAR_LMUL] THEN + ASM_MESON_TAC[BILINEAR_LZERO]] THEN + MATCH_MP_TAC SPAN_INDUCT THEN REWRITE_TAC[subspace; IN_ELIM_THM] THEN + ASM_SIMP_TAC[BILINEAR_RADD; BILINEAR_RMUL] THEN + ASM_MESON_TAC[BILINEAR_RZERO]);; + +let BILINEAR_EQ_STDBASIS = prove + (`!f:real^M->real^N->real^P g. + bilinear f /\ bilinear g /\ + (!i j. 1 <= i /\ i <= dimindex(:M) /\ 1 <= j /\ j <= dimindex(:N) + ==> f (basis i) (basis j) = g (basis i) (basis j)) + ==> f = g`, + REPEAT STRIP_TAC THEN SUBGOAL_THEN + `!x y. x IN UNIV /\ y IN UNIV ==> (f:real^M->real^N->real^P) x y = g x y` + (fun th -> MP_TAC th THEN REWRITE_TAC[FUN_EQ_THM; IN_UNIV]) THEN + MATCH_MP_TAC BILINEAR_EQ THEN + EXISTS_TAC `{basis i :real^M | 1 <= i /\ i <= dimindex(:M)}` THEN + EXISTS_TAC `{basis i :real^N | 1 <= i /\ i <= dimindex(:N)}` THEN + ASM_REWRITE_TAC[SPAN_STDBASIS; SUBSET_REFL; IN_ELIM_THM] THEN + ASM_MESON_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* Detailed theorems about left and right invertibility in general case. *) +(* ------------------------------------------------------------------------- *) + +let LEFT_INVERTIBLE_TRANSP = prove + (`!A:real^N^M. + (?B:real^N^M. B ** transp A = mat 1) <=> (?B:real^M^N. A ** B = mat 1)`, + MESON_TAC[MATRIX_TRANSP_MUL; TRANSP_MAT; TRANSP_TRANSP]);; + +let RIGHT_INVERTIBLE_TRANSP = prove + (`!A:real^N^M. + (?B:real^N^M. transp A ** B = mat 1) <=> (?B:real^M^N. B ** A = mat 1)`, + MESON_TAC[MATRIX_TRANSP_MUL; TRANSP_MAT; TRANSP_TRANSP]);; + +let INVERTIBLE_TRANSP = prove + (`!A:real^N^M. invertible(transp A) <=> invertible A`, + GEN_TAC THEN REWRITE_TAC[invertible] THEN + GEN_REWRITE_TAC LAND_CONV [MESON[TRANSP_TRANSP] + `(?A:real^M^N. P A) <=> (?A:real^N^M. P(transp A))`] THEN + GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [GSYM TRANSP_MAT] THEN + REWRITE_TAC[GSYM MATRIX_TRANSP_MUL; TRANSP_EQ] THEN MESON_TAC[]);; + +let LINEAR_INJECTIVE_LEFT_INVERSE = prove + (`!f:real^M->real^N. + linear f /\ (!x y. f x = f y ==> x = y) + ==> ?g. linear g /\ g o f = I`, + REWRITE_TAC[INJECTIVE_LEFT_INVERSE] THEN REPEAT STRIP_TAC THEN SUBGOAL_THEN + `?h. linear(h:real^N->real^M) /\ + !x. x IN IMAGE (f:real^M->real^N) + {basis i | 1 <= i /\ i <= dimindex(:M)} ==> h x = g x` + MP_TAC THENL + [MATCH_MP_TAC LINEAR_INDEPENDENT_EXTEND THEN + MATCH_MP_TAC INDEPENDENT_INJECTIVE_IMAGE THEN + ASM_MESON_TAC[INJECTIVE_LEFT_INVERSE; INDEPENDENT_STDBASIS]; + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `h:real^N->real^M` THEN + ASM_REWRITE_TAC[FORALL_IN_IMAGE; IN_ELIM_THM] THEN STRIP_TAC THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC LINEAR_EQ_STDBASIS THEN + ASM_SIMP_TAC[I_DEF; LINEAR_COMPOSE; LINEAR_ID; o_THM] THEN + ASM_MESON_TAC[]]);; + +let LINEAR_SURJECTIVE_RIGHT_INVERSE = prove + (`!f:real^M->real^N. + linear f /\ (!y. ?x. f x = y) ==> ?g. linear g /\ f o g = I`, + REWRITE_TAC[SURJECTIVE_RIGHT_INVERSE] THEN REPEAT STRIP_TAC THEN SUBGOAL_THEN + `?h. linear(h:real^N->real^M) /\ + !x. x IN {basis i | 1 <= i /\ i <= dimindex(:N)} ==> h x = g x` + MP_TAC THENL + [MATCH_MP_TAC LINEAR_INDEPENDENT_EXTEND THEN + REWRITE_TAC[INDEPENDENT_STDBASIS]; + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `h:real^N->real^M` THEN + ASM_REWRITE_TAC[FORALL_IN_IMAGE; IN_ELIM_THM] THEN STRIP_TAC THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC LINEAR_EQ_STDBASIS THEN + ASM_SIMP_TAC[I_DEF; LINEAR_COMPOSE; LINEAR_ID; o_THM] THEN + ASM_MESON_TAC[]]);; + +let MATRIX_LEFT_INVERTIBLE_INJECTIVE = prove + (`!A:real^N^M. + (?B:real^M^N. B ** A = mat 1) <=> + !x y:real^N. A ** x = A ** y ==> x = y`, + GEN_TAC THEN EQ_TAC THENL + [STRIP_TAC THEN REPEAT GEN_TAC THEN + DISCH_THEN(MP_TAC o AP_TERM `\x:real^M. (B:real^M^N) ** x`) THEN + ASM_REWRITE_TAC[MATRIX_VECTOR_MUL_ASSOC; MATRIX_VECTOR_MUL_LID]; + DISCH_TAC THEN MP_TAC(ISPEC + `\x:real^N. (A:real^N^M) ** x` LINEAR_INJECTIVE_LEFT_INVERSE) THEN + ASM_REWRITE_TAC[MATRIX_VECTOR_MUL_LINEAR; FUN_EQ_THM; I_THM; o_THM] THEN + DISCH_THEN(X_CHOOSE_THEN `g:real^M->real^N` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `matrix(g):real^M^N` THEN + REWRITE_TAC[MATRIX_EQ; MATRIX_VECTOR_MUL_LID] THEN + ASM_MESON_TAC[MATRIX_VECTOR_MUL_ASSOC; MATRIX_WORKS]]);; + +let MATRIX_LEFT_INVERTIBLE_KER = prove + (`!A:real^N^M. + (?B:real^M^N. B ** A = mat 1) <=> !x. A ** x = vec 0 ==> x = vec 0`, + GEN_TAC THEN REWRITE_TAC[MATRIX_LEFT_INVERTIBLE_INJECTIVE] THEN + MATCH_MP_TAC LINEAR_INJECTIVE_0 THEN REWRITE_TAC[MATRIX_VECTOR_MUL_LINEAR]);; + +let MATRIX_RIGHT_INVERTIBLE_SURJECTIVE = prove + (`!A:real^N^M. + (?B:real^M^N. A ** B = mat 1) <=> !y. ?x. A ** x = y`, + GEN_TAC THEN EQ_TAC THENL + [STRIP_TAC THEN X_GEN_TAC `y:real^M` THEN + EXISTS_TAC `(B:real^M^N) ** (y:real^M)` THEN + ASM_REWRITE_TAC[MATRIX_VECTOR_MUL_ASSOC; MATRIX_VECTOR_MUL_LID]; + DISCH_TAC THEN MP_TAC(ISPEC + `\x:real^N. (A:real^N^M) ** x` LINEAR_SURJECTIVE_RIGHT_INVERSE) THEN + ASM_REWRITE_TAC[MATRIX_VECTOR_MUL_LINEAR; FUN_EQ_THM; I_THM; o_THM] THEN + DISCH_THEN(X_CHOOSE_THEN `g:real^M->real^N` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `matrix(g):real^M^N` THEN + REWRITE_TAC[MATRIX_EQ; MATRIX_VECTOR_MUL_LID] THEN + ASM_MESON_TAC[MATRIX_VECTOR_MUL_ASSOC; MATRIX_WORKS]]);; + +let MATRIX_LEFT_INVERTIBLE_INDEPENDENT_COLUMNS = prove + (`!A:real^N^M. (?B:real^M^N. B ** A = mat 1) <=> + !c. vsum(1..dimindex(:N)) (\i. c(i) % column i A) = vec 0 ==> + !i. 1 <= i /\ i <= dimindex(:N) ==> c(i) = &0`, + GEN_TAC THEN REWRITE_TAC[MATRIX_LEFT_INVERTIBLE_KER; MATRIX_MUL_VSUM] THEN + EQ_TAC THEN DISCH_TAC THENL + [X_GEN_TAC `c:num->real` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `(lambda i. c(i)):real^N`); + X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPEC `\i. (x:real^N)$i`)] THEN + ASM_SIMP_TAC[LAMBDA_BETA; CART_EQ; VEC_COMPONENT]);; + +let MATRIX_RIGHT_INVERTIBLE_INDEPENDENT_ROWS = prove + (`!A:real^N^M. (?B:real^M^N. A ** B = mat 1) <=> + !c. vsum(1..dimindex(:M)) (\i. c(i) % row i A) = vec 0 ==> + !i. 1 <= i /\ i <= dimindex(:M) ==> c(i) = &0`, + ONCE_REWRITE_TAC[GSYM LEFT_INVERTIBLE_TRANSP] THEN + REWRITE_TAC[MATRIX_LEFT_INVERTIBLE_INDEPENDENT_COLUMNS] THEN + SIMP_TAC[COLUMN_TRANSP]);; + +let MATRIX_RIGHT_INVERTIBLE_SPAN_COLUMNS = prove + (`!A:real^N^M. (?B:real^M^N. A ** B = mat 1) <=> span(columns A) = (:real^M)`, + GEN_TAC THEN REWRITE_TAC[MATRIX_RIGHT_INVERTIBLE_SURJECTIVE] THEN + REWRITE_TAC[MATRIX_MUL_VSUM; EXTENSION; IN_UNIV] THEN + AP_TERM_TAC THEN REWRITE_TAC[FUN_EQ_THM] THEN X_GEN_TAC `y:real^M` THEN + EQ_TAC THENL + [DISCH_THEN(X_CHOOSE_THEN `x:real^N` (SUBST1_TAC o SYM)) THEN + MATCH_MP_TAC SPAN_VSUM THEN REWRITE_TAC[FINITE_NUMSEG; IN_NUMSEG] THEN + X_GEN_TAC `i:num` THEN STRIP_TAC THEN MATCH_MP_TAC SPAN_MUL THEN + MATCH_MP_TAC(CONJUNCT1 SPAN_CLAUSES) THEN + REWRITE_TAC[columns; IN_ELIM_THM] THEN ASM_MESON_TAC[]; + ALL_TAC] THEN + SPEC_TAC(`y:real^M`,`y:real^M`) THEN MATCH_MP_TAC SPAN_INDUCT_ALT THEN + CONJ_TAC THENL + [EXISTS_TAC `vec 0 :real^N` THEN + SIMP_TAC[VEC_COMPONENT; VECTOR_MUL_LZERO; VSUM_0]; + ALL_TAC] THEN + MAP_EVERY X_GEN_TAC [`c:real`; `y1:real^M`; `y2:real^M`] THEN + REWRITE_TAC[columns; IN_ELIM_THM] THEN DISCH_THEN(CONJUNCTS_THEN2 + (X_CHOOSE_THEN `i:num` STRIP_ASSUME_TAC) + (X_CHOOSE_THEN `x:real^N` (SUBST1_TAC o SYM))) THEN + EXISTS_TAC `(lambda j. if j = i then c + (x:real^N)$i else x$j):real^N` THEN + SUBGOAL_THEN `1..dimindex(:N) = i INSERT ((1..dimindex(:N)) DELETE i)` + SUBST1_TAC THENL [ASM_MESON_TAC[INSERT_DELETE; IN_NUMSEG]; ALL_TAC] THEN + SIMP_TAC[VSUM_CLAUSES; FINITE_DELETE; FINITE_NUMSEG; IN_DELETE] THEN + ASM_SIMP_TAC[LAMBDA_BETA; VECTOR_ADD_RDISTRIB; VECTOR_ADD_ASSOC] THEN + AP_TERM_TAC THEN MATCH_MP_TAC VSUM_EQ THEN + SIMP_TAC[FINITE_DELETE; IN_DELETE; FINITE_NUMSEG; LAMBDA_BETA; IN_NUMSEG]);; + +let MATRIX_LEFT_INVERTIBLE_SPAN_ROWS = prove + (`!A:real^N^M. (?B:real^M^N. B ** A = mat 1) <=> span(rows A) = (:real^N)`, + MESON_TAC[RIGHT_INVERTIBLE_TRANSP; COLUMNS_TRANSP; + MATRIX_RIGHT_INVERTIBLE_SPAN_COLUMNS]);; + +(* ------------------------------------------------------------------------- *) +(* An injective map real^N->real^N is also surjective. *) +(* ------------------------------------------------------------------------- *) + +let LINEAR_INJECTIVE_IMP_SURJECTIVE = prove + (`!f:real^N->real^N. + linear f /\ (!x y. (f(x) = f(y)) ==> (x = y)) + ==> !y. ?x. f(x) = y`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPEC `(:real^N)` BASIS_EXISTS) THEN + REWRITE_TAC[SUBSET_UNIV; HAS_SIZE] THEN + DISCH_THEN(X_CHOOSE_THEN `b:real^N->bool` STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN `UNIV SUBSET span(IMAGE (f:real^N->real^N) b)` MP_TAC THENL + [MATCH_MP_TAC CARD_GE_DIM_INDEPENDENT THEN + ASM_MESON_TAC[INDEPENDENT_INJECTIVE_IMAGE; LE_REFL; + SUBSET_UNIV; CARD_IMAGE_INJ]; + ASM_SIMP_TAC[SPAN_LINEAR_IMAGE] THEN + ASM_MESON_TAC[SUBSET; IN_IMAGE; IN_UNIV]]);; + +(* ------------------------------------------------------------------------- *) +(* And vice versa. *) +(* ------------------------------------------------------------------------- *) + +let LINEAR_SURJECTIVE_IMP_INJECTIVE = prove + (`!f:real^N->real^N. + linear f /\ (!y. ?x. f(x) = y) + ==> !x y. (f(x) = f(y)) ==> (x = y)`, + REPEAT GEN_TAC THEN STRIP_TAC THEN + MP_TAC(ISPEC `(:real^N)` BASIS_EXISTS) THEN + REWRITE_TAC[SUBSET_UNIV; HAS_SIZE] THEN + DISCH_THEN(X_CHOOSE_THEN `b:real^N->bool` STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN + `!x. x IN span b ==> (f:real^N->real^N) x = vec 0 ==> x = vec 0` + (fun th -> ASM_MESON_TAC[th; LINEAR_INJECTIVE_0; SUBSET; IN_UNIV]) THEN + MATCH_MP_TAC LINEAR_INDEP_IMAGE_LEMMA THEN + ASM_REWRITE_TAC[] THEN CONJ_TAC THENL + [MATCH_MP_TAC CARD_LE_DIM_SPANNING THEN + EXISTS_TAC `(:real^N)` THEN + ASM_SIMP_TAC[SUBSET_UNIV; FINITE_IMAGE; SPAN_LINEAR_IMAGE] THEN + REWRITE_TAC[SUBSET; IN_UNIV; IN_IMAGE] THEN + ASM_MESON_TAC[CARD_IMAGE_LE; SUBSET; IN_UNIV]; + ALL_TAC] THEN + SUBGOAL_THEN `dim(:real^N) <= CARD(IMAGE (f:real^N->real^N) b)` + MP_TAC THENL + [MATCH_MP_TAC SPAN_CARD_GE_DIM THEN + ASM_SIMP_TAC[SUBSET_UNIV; FINITE_IMAGE] THEN + ASM_SIMP_TAC[SPAN_LINEAR_IMAGE] THEN MATCH_MP_TAC SUBSET_TRANS THEN + EXISTS_TAC `IMAGE (f:real^N->real^N) UNIV` THEN + ASM_SIMP_TAC[IMAGE_SUBSET] THEN + ASM_REWRITE_TAC[SUBSET; IN_IMAGE; IN_UNIV] THEN ASM_MESON_TAC[]; + ALL_TAC] THEN + FIRST_X_ASSUM(MP_TAC o ISPEC `f:real^N->real^N` o + MATCH_MP CARD_IMAGE_LE) THEN + ASM_REWRITE_TAC[IMP_IMP; LE_ANTISYM] THEN DISCH_TAC THEN + MP_TAC(ISPECL + [`b:real^N->bool`; `IMAGE (f:real^N->real^N) b`; `f:real^N->real^N`] + SURJECTIVE_IFF_INJECTIVE_GEN) THEN + ASM_SIMP_TAC[FINITE_IMAGE; INDEPENDENT_BOUND; SUBSET_REFL] THEN + REWRITE_TAC[FORALL_IN_IMAGE] THEN MESON_TAC[]);; + +let LINEAR_SURJECTIVE_IFF_INJECTIVE = prove + (`!f:real^N->real^N. + linear f ==> ((!y. ?x. f x = y) <=> (!x y. f x = f y ==> x = y))`, + MESON_TAC[LINEAR_INJECTIVE_IMP_SURJECTIVE; + LINEAR_SURJECTIVE_IMP_INJECTIVE]);; + +(* ------------------------------------------------------------------------- *) +(* Hence either is enough for isomorphism. *) +(* ------------------------------------------------------------------------- *) + +let LEFT_RIGHT_INVERSE_EQ = prove + (`!f:A->A g h. f o g = I /\ g o h = I ==> f = h`, + MESON_TAC[o_ASSOC; I_O_ID]);; + +let ISOMORPHISM_EXPAND = prove + (`!f g. f o g = I /\ g o f = I <=> (!x. f(g x) = x) /\ (!x. g(f x) = x)`, + REWRITE_TAC[FUN_EQ_THM; o_THM; I_THM]);; + +let LINEAR_INJECTIVE_ISOMORPHISM = prove + (`!f:real^N->real^N. + linear f /\ (!x y. f x = f y ==> x = y) + ==> ?f'. linear f' /\ (!x. f'(f x) = x) /\ (!x. f(f' x) = x)`, + REPEAT STRIP_TAC THEN + REWRITE_TAC[GSYM ISOMORPHISM_EXPAND] THEN + MP_TAC(ISPEC `f:real^N->real^N` LINEAR_SURJECTIVE_RIGHT_INVERSE) THEN + MP_TAC(ISPEC `f:real^N->real^N` LINEAR_INJECTIVE_LEFT_INVERSE) THEN + MP_TAC(ISPEC `f:real^N->real^N` LINEAR_INJECTIVE_IMP_SURJECTIVE) THEN + ASM_REWRITE_TAC[] THEN SIMP_TAC[] THEN MESON_TAC[LEFT_RIGHT_INVERSE_EQ]);; + +let LINEAR_SURJECTIVE_ISOMORPHISM = prove + (`!f:real^N->real^N. + linear f /\ (!y. ?x. f x = y) + ==> ?f'. linear f' /\ (!x. f'(f x) = x) /\ (!x. f(f' x) = x)`, + REPEAT STRIP_TAC THEN + REWRITE_TAC[GSYM ISOMORPHISM_EXPAND] THEN + MP_TAC(ISPEC `f:real^N->real^N` LINEAR_SURJECTIVE_RIGHT_INVERSE) THEN + MP_TAC(ISPEC `f:real^N->real^N` LINEAR_INJECTIVE_LEFT_INVERSE) THEN + MP_TAC(ISPEC `f:real^N->real^N` LINEAR_SURJECTIVE_IMP_INJECTIVE) THEN + ASM_REWRITE_TAC[] THEN SIMP_TAC[] THEN MESON_TAC[LEFT_RIGHT_INVERSE_EQ]);; + +(* ------------------------------------------------------------------------- *) +(* Left and right inverses are the same for R^N->R^N. *) +(* ------------------------------------------------------------------------- *) + +let LINEAR_INVERSE_LEFT = prove + (`!f:real^N->real^N f'. + linear f /\ linear f' ==> ((f o f' = I) <=> (f' o f = I))`, + SUBGOAL_THEN + `!f:real^N->real^N f'. + linear f /\ linear f' /\ (f o f' = I) ==> (f' o f = I)` + (fun th -> MESON_TAC[th]) THEN + REWRITE_TAC[FUN_EQ_THM; o_THM; I_THM] THEN REPEAT STRIP_TAC THEN + MP_TAC(ISPEC `f:real^N->real^N` LINEAR_SURJECTIVE_ISOMORPHISM) THEN + ASM_MESON_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* Moreover, a one-sided inverse is automatically linear. *) +(* ------------------------------------------------------------------------- *) + +let LEFT_INVERSE_LINEAR = prove + (`!f g:real^N->real^N. linear f /\ (g o f = I) ==> linear g`, + REPEAT GEN_TAC THEN REWRITE_TAC[FUN_EQ_THM; o_THM; I_THM] THEN + STRIP_TAC THEN SUBGOAL_THEN + `?h:real^N->real^N. linear h /\ (!x. h(f x) = x) /\ (!x. f(h x) = x)` + CHOOSE_TAC THENL + [MATCH_MP_TAC LINEAR_INJECTIVE_ISOMORPHISM THEN ASM_MESON_TAC[]; + SUBGOAL_THEN `g:real^N->real^N = h` (fun th -> ASM_REWRITE_TAC[th]) THEN + REWRITE_TAC[FUN_EQ_THM] THEN ASM_MESON_TAC[]]);; + +let RIGHT_INVERSE_LINEAR = prove + (`!f g:real^N->real^N. linear f /\ (f o g = I) ==> linear g`, + REPEAT GEN_TAC THEN REWRITE_TAC[FUN_EQ_THM; o_THM; I_THM] THEN + STRIP_TAC THEN SUBGOAL_THEN + `?h:real^N->real^N. linear h /\ (!x. h(f x) = x) /\ (!x. f(h x) = x)` + CHOOSE_TAC THENL [ASM_MESON_TAC[LINEAR_SURJECTIVE_ISOMORPHISM]; ALL_TAC] THEN + SUBGOAL_THEN `g:real^N->real^N = h` (fun th -> ASM_REWRITE_TAC[th]) THEN + REWRITE_TAC[FUN_EQ_THM] THEN ASM_MESON_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* Without (ostensible) constraints on types, though dimensions must match. *) +(* ------------------------------------------------------------------------- *) + +let LEFT_RIGHT_INVERSE_LINEAR = prove + (`!f g:real^M->real^N. + linear f /\ g o f = I /\ f o g = I ==> linear g`, + REWRITE_TAC[linear; FUN_EQ_THM; o_THM; I_THM] THEN MESON_TAC[]);; + +let LINEAR_BIJECTIVE_LEFT_RIGHT_INVERSE = prove + (`!f:real^M->real^N. + linear f /\ (!x y. f x = f y ==> x = y) /\ (!y. ?x. f x = y) + ==> ?g. linear g /\ (!x. g(f x) = x) /\ (!y. f(g y) = y)`, + GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN ASSUME_TAC) THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [BIJECTIVE_LEFT_RIGHT_INVERSE]) THEN + MATCH_MP_TAC MONO_EXISTS THEN REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC LEFT_RIGHT_INVERSE_LINEAR THEN + EXISTS_TAC `f:real^M->real^N` THEN + ASM_REWRITE_TAC[FUN_EQ_THM; o_THM; I_THM]);; + +(* ------------------------------------------------------------------------- *) +(* The same result in terms of square matrices. *) +(* ------------------------------------------------------------------------- *) + +let MATRIX_LEFT_RIGHT_INVERSE = prove + (`!A:real^N^N A':real^N^N. (A ** A' = mat 1) <=> (A' ** A = mat 1)`, + SUBGOAL_THEN + `!A:real^N^N A':real^N^N. (A ** A' = mat 1) ==> (A' ** A = mat 1)` + (fun th -> MESON_TAC[th]) THEN + REPEAT STRIP_TAC THEN + MP_TAC(ISPEC `\x:real^N. A:(real^N^N) ** x` + LINEAR_SURJECTIVE_ISOMORPHISM) THEN + REWRITE_TAC[MATRIX_VECTOR_MUL_LINEAR] THEN ANTS_TAC THENL + [X_GEN_TAC `x:real^N` THEN EXISTS_TAC `(A':real^N^N) ** (x:real^N)` THEN + ASM_REWRITE_TAC[MATRIX_VECTOR_MUL_ASSOC; MATRIX_VECTOR_MUL_LID]; + ALL_TAC] THEN + DISCH_THEN(X_CHOOSE_THEN `f':real^N->real^N` STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN `matrix (f':real^N->real^N) ** (A:real^N^N) = mat 1` + MP_TAC THENL + [ASM_SIMP_TAC[MATRIX_EQ; MATRIX_WORKS; GSYM MATRIX_VECTOR_MUL_ASSOC; + MATRIX_VECTOR_MUL_LID]; + ALL_TAC] THEN + DISCH_THEN(fun th -> ASSUME_TAC th THEN MP_TAC th) THEN + DISCH_THEN(MP_TAC o AP_TERM `(\m:real^N^N. m ** (A':real^N^N))`) THEN + REWRITE_TAC[GSYM MATRIX_MUL_ASSOC] THEN + ASM_REWRITE_TAC[MATRIX_MUL_RID; MATRIX_MUL_LID] THEN ASM_MESON_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* Invertibility of matrices and corresponding linear functions. *) +(* ------------------------------------------------------------------------- *) + +let MATRIX_LEFT_INVERTIBLE = prove + (`!f:real^M->real^N. + linear f ==> ((?B:real^N^M. B ** matrix f = mat 1) <=> + (?g. linear g /\ g o f = I))`, + GEN_TAC THEN DISCH_TAC THEN EQ_TAC THEN STRIP_TAC THENL + [EXISTS_TAC `\y:real^N. (B:real^N^M) ** y` THEN + REWRITE_TAC[MATRIX_VECTOR_MUL_LINEAR] THEN + FIRST_X_ASSUM(fun th -> GEN_REWRITE_TAC (LAND_CONV o RAND_CONV) + [MATCH_MP MATRIX_VECTOR_MUL th]) THEN + ASM_REWRITE_TAC[FUN_EQ_THM; o_THM; I_THM; MATRIX_VECTOR_MUL_ASSOC; + MATRIX_VECTOR_MUL_LID]; + EXISTS_TAC `matrix(g:real^N->real^M)` THEN + ASM_SIMP_TAC[GSYM MATRIX_COMPOSE; MATRIX_I]]);; + +let MATRIX_RIGHT_INVERTIBLE = prove + (`!f:real^M->real^N. + linear f ==> ((?B:real^N^M. matrix f ** B = mat 1) <=> + (?g. linear g /\ f o g = I))`, + GEN_TAC THEN DISCH_TAC THEN EQ_TAC THEN STRIP_TAC THENL + [EXISTS_TAC `\y:real^N. (B:real^N^M) ** y` THEN + REWRITE_TAC[MATRIX_VECTOR_MUL_LINEAR] THEN + FIRST_X_ASSUM(fun th -> GEN_REWRITE_TAC (LAND_CONV o LAND_CONV) + [MATCH_MP MATRIX_VECTOR_MUL th]) THEN + ASM_REWRITE_TAC[FUN_EQ_THM; o_THM; I_THM; MATRIX_VECTOR_MUL_ASSOC; + MATRIX_VECTOR_MUL_LID]; + EXISTS_TAC `matrix(g:real^N->real^M)` THEN + ASM_SIMP_TAC[GSYM MATRIX_COMPOSE; MATRIX_I]]);; + +let INVERTIBLE_LEFT_INVERSE = prove + (`!A:real^N^N. invertible(A) <=> ?B:real^N^N. B ** A = mat 1`, + MESON_TAC[invertible; MATRIX_LEFT_RIGHT_INVERSE]);; + +let INVERTIBLE_RIGHT_INVERSE = prove + (`!A:real^N^N. invertible(A) <=> ?B:real^N^N. A ** B = mat 1`, + MESON_TAC[invertible; MATRIX_LEFT_RIGHT_INVERSE]);; + +let MATRIX_INVERTIBLE = prove + (`!f:real^N->real^N. + linear f + ==> (invertible(matrix f) <=> + ?g. linear g /\ f o g = I /\ g o f = I)`, + SIMP_TAC[INVERTIBLE_LEFT_INVERSE; MATRIX_LEFT_INVERTIBLE] THEN + MESON_TAC[LINEAR_INVERSE_LEFT]);; + +let MATRIX_INV_UNIQUE_LEFT = prove + (`!A:real^N^N B. A ** B = mat 1 ==> matrix_inv B = A`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC MATRIX_INV_UNIQUE THEN + ASM_MESON_TAC[MATRIX_LEFT_RIGHT_INVERSE]);; + +let MATRIX_INV_UNIQUE_RIGHT = prove + (`!A:real^N^N B. A ** B = mat 1 ==> matrix_inv A = B`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC MATRIX_INV_UNIQUE THEN + ASM_MESON_TAC[MATRIX_LEFT_RIGHT_INVERSE]);; + +(* ------------------------------------------------------------------------- *) +(* Left-invertible linear transformation has a lower bound. *) +(* ------------------------------------------------------------------------- *) + +let LINEAR_INVERTIBLE_BOUNDED_BELOW_POS = prove + (`!f:real^M->real^N g. + linear f /\ linear g /\ (g o f = I) + ==> ?B. &0 < B /\ !x. B * norm(x) <= norm(f x)`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPEC `g:real^N->real^M` LINEAR_BOUNDED_POS) THEN + ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `B:real` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `inv B:real` THEN ASM_REWRITE_TAC[REAL_LT_INV_EQ] THEN + X_GEN_TAC `x:real^M` THEN MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `inv(B) * norm(((g:real^N->real^M) o (f:real^M->real^N)) x)` THEN + CONJ_TAC THENL [ASM_SIMP_TAC[I_THM; REAL_LE_REFL]; ALL_TAC] THEN + REWRITE_TAC[REAL_ARITH `inv B * x = x / B`] THEN + ASM_SIMP_TAC[o_THM; REAL_LE_LDIV_EQ] THEN + ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN ASM_REWRITE_TAC[]);; + +let LINEAR_INVERTIBLE_BOUNDED_BELOW = prove + (`!f:real^M->real^N g. + linear f /\ linear g /\ (g o f = I) + ==> ?B. !x. B * norm(x) <= norm(f x)`, + MESON_TAC[LINEAR_INVERTIBLE_BOUNDED_BELOW_POS]);; + +let LINEAR_INJECTIVE_BOUNDED_BELOW_POS = prove + (`!f:real^M->real^N. + linear f /\ (!x y. f x = f y ==> x = y) + ==> ?B. &0 < B /\ !x. norm(x) * B <= norm(f x)`, + REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN + MATCH_MP_TAC LINEAR_INVERTIBLE_BOUNDED_BELOW_POS THEN + ASM_MESON_TAC[LINEAR_INJECTIVE_LEFT_INVERSE]);; + +(* ------------------------------------------------------------------------- *) +(* Preservation of dimension by injective map. *) +(* ------------------------------------------------------------------------- *) + +let DIM_INJECTIVE_LINEAR_IMAGE = prove + (`!f:real^M->real^N s. + linear f /\ (!x y. f x = f y ==> x = y) ==> dim(IMAGE f s) = dim s`, + REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM LE_ANTISYM] THEN + CONJ_TAC THENL [ASM_MESON_TAC[DIM_LINEAR_IMAGE_LE]; ALL_TAC] THEN + MP_TAC(ISPEC `f:real^M->real^N` LINEAR_INJECTIVE_LEFT_INVERSE) THEN + ASM_REWRITE_TAC[FUN_EQ_THM; o_THM; I_THM] THEN + DISCH_THEN(X_CHOOSE_THEN `g:real^N->real^M` STRIP_ASSUME_TAC) THEN + MATCH_MP_TAC LE_TRANS THEN + EXISTS_TAC `dim(IMAGE (g:real^N->real^M) (IMAGE (f:real^M->real^N) s))` THEN + CONJ_TAC THENL + [ASM_REWRITE_TAC[GSYM IMAGE_o; o_DEF; IMAGE_ID; LE_REFL]; + MATCH_MP_TAC DIM_LINEAR_IMAGE_LE THEN ASM_REWRITE_TAC[]]);; + +let LINEAR_INJECTIVE_DIMINDEX_LE = prove + (`!f:real^M->real^N. + linear f /\ (!x y. f x = f y ==> x = y) + ==> dimindex(:M) <= dimindex(:N)`, + REWRITE_TAC[GSYM DIM_UNIV] THEN REPEAT GEN_TAC THEN DISCH_THEN + (SUBST1_TAC o SYM o SPEC `(:real^M)` o + MATCH_MP DIM_INJECTIVE_LINEAR_IMAGE) THEN + MATCH_MP_TAC DIM_SUBSET THEN REWRITE_TAC[SUBSET_UNIV]);; + +let LINEAR_SURJECTIVE_DIMINDEX_LE = prove + (`!f:real^M->real^N. + linear f /\ (!y. ?x. f x = y) + ==> dimindex(:N) <= dimindex(:M)`, + REPEAT GEN_TAC THEN DISCH_TAC THEN FIRST_ASSUM + (MP_TAC o MATCH_MP LINEAR_SURJECTIVE_RIGHT_INVERSE) THEN + REWRITE_TAC[FUN_EQ_THM; o_THM; I_THM; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `g:real^N->real^M` THEN STRIP_TAC THEN + MATCH_MP_TAC LINEAR_INJECTIVE_DIMINDEX_LE THEN + EXISTS_TAC `g:real^N->real^M` THEN ASM_MESON_TAC[]);; + +let LINEAR_BIJECTIVE_DIMINDEX_EQ = prove + (`!f:real^M->real^N. + linear f /\ (!x y. f x = f y ==> x = y) /\ (!y. ?x. f x = y) + ==> dimindex(:M) = dimindex(:N)`, + REWRITE_TAC[GSYM LE_ANTISYM] THEN REPEAT STRIP_TAC THENL + [MATCH_MP_TAC LINEAR_INJECTIVE_DIMINDEX_LE; + MATCH_MP_TAC LINEAR_SURJECTIVE_DIMINDEX_LE] THEN + EXISTS_TAC `f:real^M->real^N` THEN ASM_REWRITE_TAC[]);; + +let INVERTIBLE_IMP_SQUARE_MATRIX = prove + (`!A:real^N^M. invertible A ==> dimindex(:M) = dimindex(:N)`, + GEN_TAC THEN REWRITE_TAC[invertible; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `B:real^M^N` THEN STRIP_TAC THEN + MATCH_MP_TAC LINEAR_BIJECTIVE_DIMINDEX_EQ THEN + EXISTS_TAC `\x:real^M. (B:real^M^N) ** x` THEN + ASM_REWRITE_TAC[MATRIX_VECTOR_MUL_LINEAR; + GSYM MATRIX_LEFT_INVERTIBLE_INJECTIVE; + GSYM MATRIX_RIGHT_INVERTIBLE_SURJECTIVE] THEN + ASM_MESON_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* Considering an n-element vector as an n-by-1 or 1-by-n matrix. *) +(* ------------------------------------------------------------------------- *) + +let rowvector = new_definition + `(rowvector:real^N->real^N^1) v = lambda i j. v$j`;; + +let columnvector = new_definition + `(columnvector:real^N->real^1^N) v = lambda i j. v$i`;; + +let TRANSP_COLUMNVECTOR = prove + (`!v. transp(columnvector v) = rowvector v`, + SIMP_TAC[transp; columnvector; rowvector; CART_EQ; LAMBDA_BETA]);; + +let TRANSP_ROWVECTOR = prove + (`!v. transp(rowvector v) = columnvector v`, + SIMP_TAC[transp; columnvector; rowvector; CART_EQ; LAMBDA_BETA]);; + +let DOT_ROWVECTOR_COLUMNVECTOR = prove + (`!A:real^N^M v:real^N. columnvector(A ** v) = A ** columnvector v`, + REWRITE_TAC[rowvector; columnvector; matrix_mul; matrix_vector_mul] THEN + SIMP_TAC[CART_EQ; LAMBDA_BETA]);; + +let DOT_MATRIX_PRODUCT = prove + (`!x y:real^N. x dot y = (rowvector x ** columnvector y)$1$1`, + REWRITE_TAC[matrix_mul; columnvector; rowvector; dot] THEN + SIMP_TAC[LAMBDA_BETA; DIMINDEX_1; LE_REFL]);; + +let DOT_MATRIX_VECTOR_MUL = prove + (`!A:real^N^N B:real^N^N x:real^N y:real^N. + (A ** x) dot (B ** y) = + ((rowvector x) ** (transp(A) ** B) ** (columnvector y))$1$1`, + REWRITE_TAC[DOT_MATRIX_PRODUCT] THEN + ONCE_REWRITE_TAC[GSYM TRANSP_COLUMNVECTOR] THEN + REWRITE_TAC[DOT_ROWVECTOR_COLUMNVECTOR; MATRIX_TRANSP_MUL] THEN + REWRITE_TAC[MATRIX_MUL_ASSOC]);; + +(* ------------------------------------------------------------------------- *) +(* Rank of a matrix. Equivalence of row and column rank is taken from *) +(* George Mackiw's paper, Mathematics Magazine 1995, p. 285. *) +(* ------------------------------------------------------------------------- *) + +let MATRIX_VECTOR_MUL_IN_COLUMNSPACE = prove + (`!A:real^M^N x:real^M. (A ** x) IN span(columns A)`, + REPEAT GEN_TAC THEN REWRITE_TAC[MATRIX_VECTOR_COLUMN; columns] THEN + MATCH_MP_TAC SPAN_VSUM THEN + SIMP_TAC[FINITE_NUMSEG; IN_NUMSEG; transp; LAMBDA_BETA] THEN + X_GEN_TAC `k:num` THEN STRIP_TAC THEN MATCH_MP_TAC SPAN_MUL THEN + MATCH_MP_TAC SPAN_SUPERSET THEN + REWRITE_TAC[IN_ELIM_THM; column] THEN EXISTS_TAC `k:num` THEN + ASM_REWRITE_TAC[]);; + +let SUBSPACE_ORTHOGONAL_TO_VECTOR = prove + (`!x. subspace {y | orthogonal x y}`, + SIMP_TAC[subspace; IN_ELIM_THM; ORTHOGONAL_CLAUSES]);; + +let SUBSPACE_ORTHOGONAL_TO_VECTORS = prove + (`!s. subspace {y | (!x. x IN s ==> orthogonal x y)}`, + SIMP_TAC[subspace; IN_ELIM_THM; ORTHOGONAL_CLAUSES]);; + +let ORTHOGONAL_TO_SPAN = prove + (`!s x. (!y. y IN s ==> orthogonal x y) + ==> !y. y IN span(s) ==> orthogonal x y`, + REPEAT GEN_TAC THEN DISCH_TAC THEN MATCH_MP_TAC SPAN_INDUCT THEN + REWRITE_TAC[SET_RULE `(\y. orthogonal x y) = {y | orthogonal x y}`] THEN + ASM_SIMP_TAC[SUBSPACE_ORTHOGONAL_TO_VECTOR; IN_ELIM_THM]);; + +let ORTHOGONAL_TO_SPAN_EQ = prove + (`!s x. (!y. y IN span(s) ==> orthogonal x y) <=> + (!y. y IN s ==> orthogonal x y)`, + MESON_TAC[SPAN_SUPERSET; ORTHOGONAL_TO_SPAN]);; + +let ORTHOGONAL_TO_SPANS_EQ = prove + (`!s t. (!x y. x IN span(s) /\ y IN span(t) ==> orthogonal x y) <=> + (!x y. x IN s /\ y IN t ==> orthogonal x y)`, + MESON_TAC[ORTHOGONAL_TO_SPAN_EQ; ORTHOGONAL_SYM]);; + +let ORTHOGONAL_NULLSPACE_ROWSPACE = prove + (`!A:real^M^N x y:real^M. + A ** x = vec 0 /\ y IN span(rows A) ==> orthogonal x y`, + REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN + REPEAT GEN_TAC THEN DISCH_TAC THEN MATCH_MP_TAC SPAN_INDUCT THEN + REWRITE_TAC[SET_RULE `(\y. orthogonal x y) = {y | orthogonal x y}`] THEN + REWRITE_TAC[SUBSPACE_ORTHOGONAL_TO_VECTOR; rows; FORALL_IN_GSPEC] THEN + X_GEN_TAC `k:num` THEN STRIP_TAC THEN REWRITE_TAC[IN_ELIM_THM] THEN + FIRST_X_ASSUM(MP_TAC o AP_TERM `\y:real^N. y$k`) THEN + ASM_SIMP_TAC[MATRIX_VECTOR_MUL_COMPONENT; VEC_COMPONENT; row; dot; + orthogonal; LAMBDA_BETA] THEN + REWRITE_TAC[REAL_MUL_SYM]);; + +let NULLSPACE_INTER_ROWSPACE = prove + (`!A:real^M^N x:real^M. A ** x = vec 0 /\ x IN span(rows A) <=> x = vec 0`, + REPEAT GEN_TAC THEN EQ_TAC THENL + [MESON_TAC[ORTHOGONAL_NULLSPACE_ROWSPACE; ORTHOGONAL_REFL]; + SIMP_TAC[MATRIX_VECTOR_MUL_RZERO; SPAN_0]]);; + +let MATRIX_VECTOR_MUL_INJECTIVE_ON_ROWSPACE = prove + (`!A:real^M^N x y:real^M. + x IN span(rows A) /\ y IN span(rows A) /\ A ** x = A ** y ==> x = y`, + ONCE_REWRITE_TAC[GSYM VECTOR_SUB_EQ] THEN + REWRITE_TAC[GSYM MATRIX_VECTOR_MUL_SUB_LDISTRIB] THEN + REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[GSYM NULLSPACE_INTER_ROWSPACE] THEN + ASM_SIMP_TAC[SPAN_SUB]);; + +let DIM_ROWS_LE_DIM_COLUMNS = prove + (`!A:real^M^N. dim(rows A) <= dim(columns A)`, + REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[GSYM DIM_SPAN] THEN + X_CHOOSE_THEN `b:real^M->bool` STRIP_ASSUME_TAC + (ISPEC `span(rows(A:real^M^N))` BASIS_EXISTS) THEN + SUBGOAL_THEN `FINITE(IMAGE (\x:real^M. (A:real^M^N) ** x) b) /\ + CARD (IMAGE (\x:real^M. (A:real^M^N) ** x) b) <= + dim(span(columns A))` + MP_TAC THENL + [MATCH_MP_TAC INDEPENDENT_CARD_LE_DIM THEN + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; MATRIX_VECTOR_MUL_IN_COLUMNSPACE] THEN + MATCH_MP_TAC INDEPENDENT_INJECTIVE_IMAGE_GEN THEN + ASM_REWRITE_TAC[MATRIX_VECTOR_MUL_LINEAR] THEN + SUBGOAL_THEN `span(b) = span(rows(A:real^M^N))` SUBST1_TAC THENL + [ALL_TAC; ASM_MESON_TAC[MATRIX_VECTOR_MUL_INJECTIVE_ON_ROWSPACE]] THEN + MATCH_MP_TAC SUBSET_ANTISYM THEN ASM_REWRITE_TAC[] THEN + GEN_REWRITE_TAC RAND_CONV [GSYM SPAN_SPAN] THEN + ASM_SIMP_TAC[SPAN_MONO]; + DISCH_THEN(MP_TAC o CONJUNCT2) THEN MATCH_MP_TAC EQ_IMP THEN + AP_THM_TAC THEN AP_TERM_TAC THEN + FIRST_ASSUM(CONJUNCTS_THEN2 ASSUME_TAC (SUBST1_TAC o SYM) o + GEN_REWRITE_RULE I [HAS_SIZE]) THEN + MATCH_MP_TAC CARD_IMAGE_INJ THEN ASM_REWRITE_TAC[] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC + (ISPEC `A:real^M^N` MATRIX_VECTOR_MUL_INJECTIVE_ON_ROWSPACE) THEN + ASM SET_TAC[]]);; + +let rank = new_definition + `rank(A:real^M^N) = dim(columns A)`;; + +let RANK_ROW = prove + (`!A:real^M^N. rank(A) = dim(rows A)`, + GEN_TAC THEN REWRITE_TAC[rank] THEN + MP_TAC(ISPEC `A:real^M^N` DIM_ROWS_LE_DIM_COLUMNS) THEN + MP_TAC(ISPEC `transp(A:real^M^N)` DIM_ROWS_LE_DIM_COLUMNS) THEN + REWRITE_TAC[ROWS_TRANSP; COLUMNS_TRANSP] THEN ARITH_TAC);; + +let RANK_TRANSP = prove + (`!A:real^M^N. rank(transp A) = rank A`, + GEN_TAC THEN GEN_REWRITE_TAC RAND_CONV [RANK_ROW] THEN + REWRITE_TAC[rank; COLUMNS_TRANSP]);; + +let MATRIX_VECTOR_MUL_BASIS = prove + (`!A:real^M^N k. 1 <= k /\ k <= dimindex(:M) + ==> A ** (basis k) = column k A`, + SIMP_TAC[CART_EQ; column; MATRIX_VECTOR_MUL_COMPONENT; DOT_BASIS; + LAMBDA_BETA]);; + +let COLUMNS_IMAGE_BASIS = prove + (`!A:real^M^N. + columns A = IMAGE (\x. A ** x) {basis i | 1 <= i /\ i <= dimindex(:M)}`, + GEN_TAC THEN REWRITE_TAC[columns] THEN + ONCE_REWRITE_TAC[SIMPLE_IMAGE_GEN] THEN + REWRITE_TAC[GSYM IMAGE_o; o_DEF] THEN + MATCH_MP_TAC(SET_RULE + `(!x. x IN s ==> f x = g x) ==> IMAGE f s = IMAGE g s`) THEN + SIMP_TAC[IN_ELIM_THM; MATRIX_VECTOR_MUL_BASIS]);; + +let RANK_DIM_IM = prove + (`!A:real^M^N. rank A = dim(IMAGE (\x. A ** x) (:real^M))`, + GEN_TAC THEN REWRITE_TAC[rank] THEN + MATCH_MP_TAC SPAN_EQ_DIM THEN REWRITE_TAC[COLUMNS_IMAGE_BASIS] THEN + SIMP_TAC[SPAN_LINEAR_IMAGE; MATRIX_VECTOR_MUL_LINEAR] THEN + AP_TERM_TAC THEN GEN_REWRITE_TAC LAND_CONV [GSYM SPAN_SPAN] THEN + REWRITE_TAC[SPAN_STDBASIS]);; + +let DIM_EQ_SPAN = prove + (`!s t:real^N->bool. s SUBSET t /\ dim t <= dim s ==> span s = span t`, + REPEAT STRIP_TAC THEN + X_CHOOSE_THEN `b:real^N->bool` STRIP_ASSUME_TAC + (ISPEC `span s:real^N->bool` BASIS_EXISTS) THEN + MP_TAC(ISPECL [`span t:real^N->bool`; `b:real^N->bool`] + CARD_GE_DIM_INDEPENDENT) THEN + RULE_ASSUM_TAC(REWRITE_RULE[HAS_SIZE]) THEN + ASM_REWRITE_TAC[DIM_SPAN] THEN + ASM_MESON_TAC[SPAN_MONO; SPAN_SPAN; SUBSET_TRANS; SUBSET_ANTISYM]);; + +let DIM_EQ_FULL = prove + (`!s:real^N->bool. dim s = dimindex(:N) <=> span s = (:real^N)`, + GEN_TAC THEN ONCE_REWRITE_TAC[GSYM DIM_SPAN] THEN EQ_TAC THEN + SIMP_TAC[DIM_UNIV] THEN DISCH_TAC THEN + GEN_REWRITE_TAC RAND_CONV [GSYM SPAN_UNIV] THEN MATCH_MP_TAC DIM_EQ_SPAN THEN + ASM_REWRITE_TAC[SUBSET_UNIV; DIM_UNIV] THEN + ASM_MESON_TAC[LE_REFL; DIM_SPAN]);; + +let DIM_PSUBSET = prove + (`!s t. (span s) PSUBSET (span t) ==> dim s < dim t`, + ONCE_REWRITE_TAC[GSYM DIM_SPAN] THEN + SIMP_TAC[PSUBSET; DIM_SUBSET; LT_LE] THEN + MESON_TAC[EQ_IMP_LE; DIM_EQ_SPAN; SPAN_SPAN]);; + +let RANK_BOUND = prove + (`!A:real^M^N. rank(A) <= MIN (dimindex(:M)) (dimindex(:N))`, + GEN_TAC THEN REWRITE_TAC[ARITH_RULE `x <= MIN a b <=> x <= a /\ x <= b`] THEN + CONJ_TAC THENL + [REWRITE_TAC[DIM_SUBSET_UNIV; RANK_ROW]; + REWRITE_TAC[DIM_SUBSET_UNIV; rank]]);; + +let FULL_RANK_INJECTIVE = prove + (`!A:real^M^N. + rank A = dimindex(:M) <=> + (!x y:real^M. A ** x = A ** y ==> x = y)`, + REWRITE_TAC[GSYM MATRIX_LEFT_INVERTIBLE_INJECTIVE] THEN + REWRITE_TAC[MATRIX_LEFT_INVERTIBLE_SPAN_ROWS] THEN + REWRITE_TAC[RANK_ROW; DIM_EQ_FULL]);; + +let FULL_RANK_SURJECTIVE = prove + (`!A:real^M^N. + rank A = dimindex(:N) <=> (!y:real^N. ?x:real^M. A ** x = y)`, + REWRITE_TAC[GSYM MATRIX_RIGHT_INVERTIBLE_SURJECTIVE] THEN + REWRITE_TAC[GSYM LEFT_INVERTIBLE_TRANSP] THEN + REWRITE_TAC[MATRIX_LEFT_INVERTIBLE_INJECTIVE] THEN + REWRITE_TAC[GSYM FULL_RANK_INJECTIVE; RANK_TRANSP]);; + +let RANK_I = prove + (`rank(mat 1:real^N^N) = dimindex(:N)`, + REWRITE_TAC[FULL_RANK_INJECTIVE; MATRIX_VECTOR_MUL_LID]);; + +let MATRIX_FULL_LINEAR_EQUATIONS = prove + (`!A:real^M^N b:real^N. + rank A = dimindex(:N) ==> ?x. A ** x = b`, + SIMP_TAC[FULL_RANK_SURJECTIVE]);; + +let MATRIX_NONFULL_LINEAR_EQUATIONS_EQ = prove + (`!A:real^M^N. + (?x. ~(x = vec 0) /\ A ** x = vec 0) <=> ~(rank A = dimindex(:M))`, + REPEAT GEN_TAC THEN REWRITE_TAC[FULL_RANK_INJECTIVE] THEN + SIMP_TAC[LINEAR_INJECTIVE_0; MATRIX_VECTOR_MUL_LINEAR] THEN + MESON_TAC[]);; + +let MATRIX_NONFULL_LINEAR_EQUATIONS = prove + (`!A:real^M^N. + ~(rank A = dimindex(:M)) ==> ?x. ~(x = vec 0) /\ A ** x = vec 0`, + REWRITE_TAC[MATRIX_NONFULL_LINEAR_EQUATIONS_EQ]);; + +let MATRIX_TRIVIAL_LINEAR_EQUATIONS = prove + (`!A:real^M^N. + dimindex(:N) < dimindex(:M) + ==> ?x. ~(x = vec 0) /\ A ** x = vec 0`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC MATRIX_NONFULL_LINEAR_EQUATIONS THEN + MATCH_MP_TAC(ARITH_RULE + `!a. x <= MIN b a /\ a < b ==> ~(x = b)`) THEN + EXISTS_TAC `dimindex(:N)` THEN ASM_REWRITE_TAC[RANK_BOUND]);; + +let RANK_EQ_0 = prove + (`!A:real^M^N. rank A = 0 <=> A = mat 0`, + REWRITE_TAC[RANK_DIM_IM; DIM_EQ_0; SUBSET; FORALL_IN_IMAGE; IN_SING; + IN_UNIV] THEN + GEN_TAC THEN GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [CART_EQ] THEN + SIMP_TAC[CART_EQ; MATRIX_MUL_DOT; VEC_COMPONENT; LAMBDA_BETA; mat] THEN + ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN + REWRITE_TAC[RIGHT_FORALL_IMP_THM; FORALL_DOT_EQ_0; COND_ID] THEN + REWRITE_TAC[CART_EQ; VEC_COMPONENT]);; + +let RANK_0 = prove + (`rank(mat 0) = 0`, + REWRITE_TAC[RANK_EQ_0]);; + +let RANK_MUL_LE_RIGHT = prove + (`!A:real^N^M B:real^P^N. rank(A ** B) <= rank(B)`, + REPEAT GEN_TAC THEN MATCH_MP_TAC LE_TRANS THEN + EXISTS_TAC `dim(IMAGE (\y. (A:real^N^M) ** y) + (IMAGE (\x. (B:real^P^N) ** x) (:real^P)))` THEN + REWRITE_TAC[RANK_DIM_IM] THEN CONJ_TAC THENL + [REWRITE_TAC[GSYM IMAGE_o; o_DEF; MATRIX_VECTOR_MUL_ASSOC; LE_REFL]; + MATCH_MP_TAC DIM_LINEAR_IMAGE_LE THEN + REWRITE_TAC[MATRIX_VECTOR_MUL_LINEAR]]);; + +let RANK_MUL_LE_LEFT = prove + (`!A:real^N^M B:real^P^N. rank(A ** B) <= rank(A)`, + ONCE_REWRITE_TAC[GSYM RANK_TRANSP] THEN + REWRITE_TAC[MATRIX_TRANSP_MUL] THEN + REWRITE_TAC[RANK_MUL_LE_RIGHT]);; + +(* ------------------------------------------------------------------------- *) +(* Basic lemmas about hyperplanes and halfspaces. *) +(* ------------------------------------------------------------------------- *) + +let HYPERPLANE_EQ_EMPTY = prove + (`!a:real^N b. {x | a dot x = b} = {} <=> a = vec 0 /\ ~(b = &0)`, + REPEAT GEN_TAC THEN REWRITE_TAC[EXTENSION; IN_ELIM_THM; NOT_IN_EMPTY] THEN + ASM_CASES_TAC `a:real^N = vec 0` THEN ASM_REWRITE_TAC[DOT_LZERO] THENL + [MESON_TAC[]; + DISCH_THEN(MP_TAC o SPEC `b / (a dot a) % a:real^N`) THEN + ASM_SIMP_TAC[DOT_RMUL; REAL_DIV_RMUL; DOT_EQ_0]]);; + +let HYPERPLANE_EQ_UNIV = prove + (`!a b. {x | a dot x = b} = (:real^N) <=> a = vec 0 /\ b = &0`, + REPEAT GEN_TAC THEN REWRITE_TAC[EXTENSION; IN_ELIM_THM; IN_UNIV] THEN + ASM_CASES_TAC `a:real^N = vec 0` THEN ASM_REWRITE_TAC[DOT_LZERO] THENL + [MESON_TAC[]; + DISCH_THEN(MP_TAC o SPEC `(b + &1) / (a dot a) % a:real^N`) THEN + ASM_SIMP_TAC[DOT_RMUL; REAL_DIV_RMUL; DOT_EQ_0] THEN REAL_ARITH_TAC]);; + +let HALFSPACE_EQ_EMPTY_LT = prove + (`!a:real^N b. {x | a dot x < b} = {} <=> a = vec 0 /\ b <= &0`, + REPEAT GEN_TAC THEN ASM_CASES_TAC `a:real^N = vec 0` THENL + [ASM_SIMP_TAC[DOT_LZERO; SET_RULE `{x | p} = if p then UNIV else {}`] THEN + COND_CASES_TAC THEN REWRITE_TAC[UNIV_NOT_EMPTY] THEN ASM_REAL_ARITH_TAC; + ASM_REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; IN_ELIM_THM] THEN + EXISTS_TAC `(b - &1) / (a dot a) % a:real^N` THEN + ASM_SIMP_TAC[DOT_RMUL; REAL_DIV_RMUL; DOT_EQ_0] THEN + REAL_ARITH_TAC]);; + +let HALFSPACE_EQ_EMPTY_GT = prove + (`!a:real^N b. {x | a dot x > b} = {} <=> a = vec 0 /\ b >= &0`, + REPEAT GEN_TAC THEN + MP_TAC(ISPECL [`--a:real^N`; `--b:real`] HALFSPACE_EQ_EMPTY_LT) THEN + SIMP_TAC[real_gt; DOT_LNEG; REAL_LT_NEG2; VECTOR_NEG_EQ_0] THEN + DISCH_TAC THEN AP_TERM_TAC THEN REAL_ARITH_TAC);; + +let HALFSPACE_EQ_EMPTY_LE = prove + (`!a:real^N b. {x | a dot x <= b} = {} <=> a = vec 0 /\ b < &0`, + REPEAT GEN_TAC THEN ASM_CASES_TAC `a:real^N = vec 0` THENL + [ASM_SIMP_TAC[DOT_LZERO; SET_RULE `{x | p} = if p then UNIV else {}`] THEN + COND_CASES_TAC THEN REWRITE_TAC[UNIV_NOT_EMPTY] THEN ASM_REAL_ARITH_TAC; + ASM_REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; IN_ELIM_THM] THEN + EXISTS_TAC `(b - &1) / (a dot a) % a:real^N` THEN + ASM_SIMP_TAC[DOT_RMUL; REAL_DIV_RMUL; DOT_EQ_0] THEN + REAL_ARITH_TAC]);; + +let HALFSPACE_EQ_EMPTY_GE = prove + (`!a:real^N b. {x | a dot x >= b} = {} <=> a = vec 0 /\ b > &0`, + REPEAT GEN_TAC THEN + MP_TAC(ISPECL [`--a:real^N`; `--b:real`] HALFSPACE_EQ_EMPTY_LE) THEN + SIMP_TAC[real_ge; DOT_LNEG; REAL_LE_NEG2; VECTOR_NEG_EQ_0] THEN + DISCH_TAC THEN AP_TERM_TAC THEN REAL_ARITH_TAC);; + +(* ------------------------------------------------------------------------- *) +(* A non-injective linear function maps into a hyperplane. *) +(* ------------------------------------------------------------------------- *) + +let ADJOINT_INJECTIVE = prove + (`!f:real^M->real^N. + linear f + ==> ((!x y. adjoint f x = adjoint f y ==> x = y) <=> + (!y. ?x. f x = y))`, + REPEAT STRIP_TAC THEN + FIRST_ASSUM(ASSUME_TAC o GSYM o MATCH_MP MATRIX_WORKS o MATCH_MP + ADJOINT_LINEAR) THEN + FIRST_ASSUM(ASSUME_TAC o GSYM o MATCH_MP MATRIX_WORKS) THEN + ASM_REWRITE_TAC[GSYM FULL_RANK_INJECTIVE; GSYM FULL_RANK_SURJECTIVE] THEN + ASM_SIMP_TAC[MATRIX_ADJOINT; RANK_TRANSP]);; + +let ADJOINT_SURJECTIVE = prove + (`!f:real^M->real^N. + linear f + ==> ((!y. ?x. adjoint f x = y) <=> (!x y. f x = f y ==> x = y))`, + REPEAT STRIP_TAC THEN + FIRST_ASSUM(fun th -> GEN_REWRITE_TAC (RAND_CONV o ONCE_DEPTH_CONV) + [GSYM(MATCH_MP ADJOINT_ADJOINT th)]) THEN + ASM_SIMP_TAC[ADJOINT_INJECTIVE; ADJOINT_LINEAR]);; + +let ADJOINT_INJECTIVE_INJECTIVE = prove + (`!f:real^N->real^N. + linear f + ==> ((!x y. adjoint f x = adjoint f y ==> x = y) <=> + (!x y. f x = f y ==> x = y))`, + SIMP_TAC[ADJOINT_INJECTIVE] THEN + MESON_TAC[LINEAR_INJECTIVE_IMP_SURJECTIVE; + LINEAR_SURJECTIVE_IMP_INJECTIVE]);; + +let ADJOINT_INJECTIVE_INJECTIVE_0 = prove + (`!f:real^N->real^N. + linear f + ==> ((!x. adjoint f x = vec 0 ==> x = vec 0) <=> + (!x. f x = vec 0 ==> x = vec 0))`, + REPEAT STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o MATCH_MP ADJOINT_INJECTIVE_INJECTIVE) THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP ADJOINT_LINEAR) THEN + ASM_MESON_TAC[LINEAR_INJECTIVE_0]);; + +let LINEAR_SINGULAR_INTO_HYPERPLANE = prove + (`!f:real^N->real^N. + linear f + ==> (~(!x y. f(x) = f(y) ==> x = y) <=> + ?a. ~(a = vec 0) /\ !x. a dot f(x) = &0)`, + REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[DOT_SYM] THEN + ASM_SIMP_TAC[ADJOINT_WORKS; FORALL_DOT_EQ_0] THEN + REWRITE_TAC[MESON[] `(?a. ~p a /\ q a) <=> ~(!a. q a ==> p a)`] THEN + ASM_SIMP_TAC[ADJOINT_INJECTIVE_INJECTIVE_0; LINEAR_INJECTIVE_0]);; + +let LINEAR_SINGULAR_IMAGE_HYPERPLANE = prove + (`!f:real^N->real^N. + linear f /\ ~(!x y. f(x) = f(y) ==> x = y) + ==> ?a. ~(a = vec 0) /\ !s. IMAGE f s SUBSET {x | a dot x = &0}`, + GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + ASM_SIMP_TAC[LINEAR_SINGULAR_INTO_HYPERPLANE] THEN + SIMP_TAC[SUBSET; FORALL_IN_IMAGE; IN_ELIM_THM] THEN MESON_TAC[]);; + +let LOWDIM_EXPAND_DIMENSION = prove + (`!s:real^N->bool n. + dim s <= n /\ n <= dimindex(:N) + ==> ?t. dim(t) = n /\ span s SUBSET span t`, + GEN_TAC THEN + GEN_REWRITE_TAC (BINDER_CONV o LAND_CONV o LAND_CONV) [LE_EXISTS] THEN + SIMP_TAC[LEFT_AND_EXISTS_THM; LEFT_IMP_EXISTS_THM; IMP_CONJ] THEN + ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN + REWRITE_TAC[RIGHT_FORALL_IMP_THM; LEFT_FORALL_IMP_THM; EXISTS_REFL] THEN + INDUCT_TAC THENL [MESON_TAC[ADD_CLAUSES; SUBSET_REFL]; ALL_TAC] THEN + REWRITE_TAC[ARITH_RULE `s + SUC d <= n <=> s + d < n`] THEN + DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o check (is_imp o concl)) THEN + ASM_SIMP_TAC[LT_IMP_LE; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `t:real^N->bool` THEN STRIP_TAC THEN + REWRITE_TAC[ADD_CLAUSES] THEN FIRST_X_ASSUM(SUBST_ALL_TAC o SYM) THEN + SUBGOAL_THEN `~(span t = (:real^N))` MP_TAC THENL + [REWRITE_TAC[GSYM DIM_EQ_FULL] THEN ASM_ARITH_TAC; ALL_TAC] THEN + REWRITE_TAC[EXTENSION; IN_UNIV; NOT_FORALL_THM; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `a:real^N` THEN DISCH_TAC THEN + EXISTS_TAC `(a:real^N) INSERT t` THEN ASM_REWRITE_TAC[DIM_INSERT; ADD1] THEN + MATCH_MP_TAC SUBSET_TRANS THEN EXISTS_TAC `span(t:real^N->bool)` THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC SPAN_MONO THEN SET_TAC[]);; + +let LOWDIM_EXPAND_BASIS = prove + (`!s:real^N->bool n. + dim s <= n /\ n <= dimindex(:N) + ==> ?b. b HAS_SIZE n /\ independent b /\ span s SUBSET span b`, + REPEAT GEN_TAC THEN DISCH_TAC THEN + FIRST_ASSUM(X_CHOOSE_THEN `t:real^N->bool` STRIP_ASSUME_TAC o + MATCH_MP LOWDIM_EXPAND_DIMENSION) THEN + MP_TAC(ISPEC `t:real^N->bool` BASIS_EXISTS) THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `b:real^N->bool` THEN + ASM_REWRITE_TAC[] THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + ASM_MESON_TAC[SPAN_SPAN; SUBSET_TRANS; SPAN_MONO]);; + +(* ------------------------------------------------------------------------- *) +(* Orthogonal bases, Gram-Schmidt process, and related theorems. *) +(* ------------------------------------------------------------------------- *) + +let SPAN_DELETE_0 = prove + (`!s:real^N->bool. span(s DELETE vec 0) = span s`, + GEN_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN + SIMP_TAC[DELETE_SUBSET; SPAN_MONO] THEN + MATCH_MP_TAC SUBSET_TRANS THEN + EXISTS_TAC `span((vec 0:real^N) INSERT (s DELETE vec 0))` THEN CONJ_TAC THENL + [MATCH_MP_TAC SPAN_MONO THEN SET_TAC[]; + SIMP_TAC[SUBSET; SPAN_BREAKDOWN_EQ; VECTOR_MUL_RZERO; VECTOR_SUB_RZERO]]);; + +let SPAN_IMAGE_SCALE = prove + (`!c s. FINITE s /\ (!x. x IN s ==> ~(c x = &0)) + ==> span (IMAGE (\x:real^N. c(x) % x) s) = span s`, + GEN_TAC THEN REWRITE_TAC[IMP_CONJ] THEN + MATCH_MP_TAC FINITE_INDUCT_STRONG THEN + SIMP_TAC[IMAGE_CLAUSES; SPAN_BREAKDOWN_EQ; EXTENSION; FORALL_IN_INSERT] THEN + MAP_EVERY X_GEN_TAC [`x:real^N`; `t:real^N->bool`] THEN + STRIP_TAC THEN STRIP_TAC THEN X_GEN_TAC `y:real^N` THEN + REWRITE_TAC[VECTOR_MUL_ASSOC] THEN EQ_TAC THENL [MESON_TAC[]; ALL_TAC] THEN + DISCH_THEN(X_CHOOSE_TAC `k:real`) THEN + EXISTS_TAC `k / (c:real^N->real) x` THEN + ASM_SIMP_TAC[REAL_DIV_RMUL]);; + +let PAIRWISE_ORTHOGONAL_INDEPENDENT = prove + (`!s:real^N->bool. + pairwise orthogonal s /\ ~(vec 0 IN s) ==> independent s`, + REWRITE_TAC[pairwise; orthogonal] THEN REPEAT STRIP_TAC THEN + REWRITE_TAC[independent; dependent] THEN + DISCH_THEN(X_CHOOSE_THEN `a:real^N` (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN + REWRITE_TAC[SPAN_EXPLICIT; IN_ELIM_THM; NOT_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`t:real^N->bool`; `u:real^N->real`] THEN + REWRITE_TAC[SUBSET; IN_DELETE] THEN STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o AP_TERM `\x:real^N. a dot x`) THEN + ASM_SIMP_TAC[DOT_RSUM; DOT_RMUL; REAL_MUL_RZERO; SUM_0] THEN + ASM_MESON_TAC[DOT_EQ_0]);; + +let PAIRWISE_ORTHOGONAL_IMP_FINITE = prove + (`!s:real^N->bool. pairwise orthogonal s ==> FINITE s`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN `independent (s DELETE (vec 0:real^N))` MP_TAC THENL + [MATCH_MP_TAC PAIRWISE_ORTHOGONAL_INDEPENDENT THEN + REWRITE_TAC[IN_DELETE] THEN MATCH_MP_TAC PAIRWISE_MONO THEN + EXISTS_TAC `s:real^N->bool` THEN + ASM_SIMP_TAC[SUBSET; IN_DELETE]; + DISCH_THEN(MP_TAC o MATCH_MP INDEPENDENT_IMP_FINITE) THEN + REWRITE_TAC[FINITE_DELETE]]);; + +let GRAM_SCHMIDT_STEP = prove + (`!s a x. + pairwise orthogonal s /\ x IN span s + ==> orthogonal x (a - vsum s (\b:real^N. (b dot a) / (b dot b) % b))`, + REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN + REWRITE_TAC[ONCE_REWRITE_RULE[ORTHOGONAL_SYM] ORTHOGONAL_TO_SPAN_EQ] THEN + X_GEN_TAC `s:real^N->bool` THEN STRIP_TAC THEN + MAP_EVERY X_GEN_TAC [`a:real^N`; `x:real^N`] THEN DISCH_TAC THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP PAIRWISE_ORTHOGONAL_IMP_FINITE) THEN + REWRITE_TAC[orthogonal; DOT_RSUB] THEN ASM_SIMP_TAC[DOT_RSUM] THEN + REWRITE_TAC[REAL_SUB_0; DOT_RMUL] THEN MATCH_MP_TAC EQ_TRANS THEN + EXISTS_TAC `sum s (\y:real^N. if y = x then y dot a else &0)` THEN + CONJ_TAC THENL [ASM_SIMP_TAC[SUM_DELTA; DOT_SYM]; ALL_TAC] THEN + MATCH_MP_TAC SUM_EQ THEN X_GEN_TAC `y:real^N` THEN DISCH_TAC THEN + RULE_ASSUM_TAC(REWRITE_RULE[pairwise; orthogonal]) THEN + ASM_CASES_TAC `x:real^N = y` THEN ASM_SIMP_TAC[DOT_LMUL; REAL_MUL_RZERO] THEN + ASM_CASES_TAC `y:real^N = vec 0` THEN + ASM_SIMP_TAC[REAL_DIV_RMUL; DOT_EQ_0; DOT_LZERO; REAL_MUL_RZERO]);; + +let ORTHOGONAL_EXTENSION = prove + (`!s t:real^N->bool. + pairwise orthogonal s + ==> ?u. pairwise orthogonal (s UNION u) /\ + span (s UNION u) = span (s UNION t)`, + let lemma = prove + (`!t s:real^N->bool. + FINITE t /\ FINITE s /\ pairwise orthogonal s + ==> ?u. pairwise orthogonal (s UNION u) /\ + span (s UNION u) = span (s UNION t)`, + REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN + MATCH_MP_TAC FINITE_INDUCT_STRONG THEN CONJ_TAC THENL + [REPEAT STRIP_TAC THEN EXISTS_TAC `{}:real^N->bool` THEN + ASM_REWRITE_TAC[UNION_EMPTY]; + ALL_TAC] THEN + MAP_EVERY X_GEN_TAC [`a:real^N`; `t:real^N->bool`] THEN + REWRITE_TAC[pairwise; orthogonal] THEN REPEAT STRIP_TAC THEN + ABBREV_TAC `a' = a - vsum s (\b:real^N. (b dot a) / (b dot b) % b)` THEN + FIRST_X_ASSUM(MP_TAC o SPEC `(a':real^N) INSERT s`) THEN + ASM_REWRITE_TAC[FINITE_INSERT] THEN ANTS_TAC THENL + [SUBGOAL_THEN `!x:real^N. x IN s ==> a' dot x = &0` + (fun th -> REWRITE_TAC[IN_INSERT] THEN ASM_MESON_TAC[DOT_SYM; th]) THEN + REPEAT STRIP_TAC THEN EXPAND_TAC "a'" THEN + REWRITE_TAC[GSYM orthogonal] THEN ONCE_REWRITE_TAC[ORTHOGONAL_SYM] THEN + MATCH_MP_TAC GRAM_SCHMIDT_STEP THEN + ASM_SIMP_TAC[pairwise; orthogonal; SPAN_CLAUSES]; + DISCH_THEN(X_CHOOSE_THEN `u:real^N->bool` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `(a':real^N) INSERT u` THEN + ASM_REWRITE_TAC[SET_RULE `s UNION a INSERT u = a INSERT s UNION u`] THEN + REWRITE_TAC[SET_RULE `(x INSERT s) UNION t = x INSERT (s UNION t)`] THEN + MATCH_MP_TAC EQ_SPAN_INSERT_EQ THEN EXPAND_TAC "a'" THEN + REWRITE_TAC[VECTOR_ARITH `a - x - a:real^N = --x`] THEN + MATCH_MP_TAC SPAN_NEG THEN MATCH_MP_TAC SPAN_VSUM THEN + ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC SPAN_MUL THEN ASM_SIMP_TAC[SPAN_SUPERSET; IN_UNION]]) in + REPEAT STRIP_TAC THEN + MP_TAC(ISPEC `span t:real^N->bool` BASIS_SUBSPACE_EXISTS) THEN + REWRITE_TAC[SUBSPACE_SPAN; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `b:real^N->bool` THEN STRIP_TAC THEN + MP_TAC(ISPECL [`b:real^N->bool`; `s:real^N->bool`] lemma) THEN + ANTS_TAC THENL + [ASM_MESON_TAC[HAS_SIZE; PAIRWISE_ORTHOGONAL_IMP_FINITE]; + MATCH_MP_TAC MONO_EXISTS THEN REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + ASM_REWRITE_TAC[SPAN_UNION]]);; + +let ORTHOGONAL_EXTENSION_STRONG = prove + (`!s t:real^N->bool. + pairwise orthogonal s + ==> ?u. DISJOINT u (vec 0 INSERT s) /\ + pairwise orthogonal (s UNION u) /\ + span (s UNION u) = span (s UNION t)`, + REPEAT STRIP_TAC THEN FIRST_X_ASSUM(MP_TAC o + SPEC `t:real^N->bool` o MATCH_MP ORTHOGONAL_EXTENSION) THEN + DISCH_THEN(X_CHOOSE_THEN `u:real^N->bool` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `u DIFF ((vec 0:real^N) INSERT s)` THEN REPEAT CONJ_TAC THENL + [SET_TAC[]; + FIRST_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + PAIRWISE_MONO)) THEN SET_TAC[]; + FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN + GEN_REWRITE_TAC BINOP_CONV [GSYM SPAN_DELETE_0] THEN + AP_TERM_TAC THEN SET_TAC[]]);; + +let ORTHONORMAL_EXTENSION = prove + (`!s t:real^N->bool. + pairwise orthogonal s /\ (!x. x IN s ==> norm x = &1) + ==> ?u. DISJOINT u s /\ + pairwise orthogonal (s UNION u) /\ + (!x. x IN u ==> norm x = &1) /\ + span(s UNION u) = span(s UNION t)`, + REPEAT STRIP_TAC THEN FIRST_X_ASSUM(MP_TAC o + SPEC `t:real^N->bool` o MATCH_MP ORTHOGONAL_EXTENSION_STRONG) THEN + REWRITE_TAC[SET_RULE `DISJOINT u s <=> !x. x IN u ==> ~(x IN s)`] THEN + REWRITE_TAC[IN_INSERT; DE_MORGAN_THM; pairwise] THEN + DISCH_THEN(X_CHOOSE_THEN `u:real^N->bool` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `IMAGE (\x:real^N. inv(norm x) % x) u` THEN + REWRITE_TAC[FORALL_IN_IMAGE; IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN + REPEAT CONJ_TAC THENL + [X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN + ASM_CASES_TAC `norm(x:real^N) = &1` THEN + ASM_SIMP_TAC[REAL_INV_1; VECTOR_MUL_LID] THEN DISCH_TAC THEN + FIRST_X_ASSUM(MP_TAC o SPECL [`x:real^N`; `inv(norm x) % x:real^N`]) THEN + ASM_REWRITE_TAC[IN_UNION; VECTOR_MUL_EQ_0; REAL_SUB_0; REAL_INV_EQ_1; + VECTOR_ARITH `x:real^N = a % x <=> (a - &1) % x = vec 0`] THEN + ASM_CASES_TAC `x:real^N = vec 0` THENL + [ASM_MESON_TAC[VECTOR_MUL_RZERO]; + ASM_REWRITE_TAC[orthogonal; DOT_RMUL; REAL_ENTIRE; DOT_EQ_0] THEN + ASM_REWRITE_TAC[REAL_INV_EQ_0; NORM_EQ_0]]; + REWRITE_TAC[IN_UNION; IN_IMAGE] THEN REPEAT STRIP_TAC THEN + ASM_SIMP_TAC[orthogonal; DOT_LMUL; DOT_RMUL; REAL_ENTIRE; DOT_EQ_0; + REAL_INV_EQ_0; NORM_EQ_0] THEN + REWRITE_TAC[GSYM orthogonal] THEN FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_REWRITE_TAC[IN_UNION] THEN DISCH_THEN(SUBST_ALL_TAC o SYM) THEN + ASM SET_TAC[]; + ASM_SIMP_TAC[NORM_MUL; REAL_MUL_LINV; NORM_EQ_0; REAL_ABS_INV; + REAL_ABS_NORM]; + FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN + REWRITE_TAC[SPAN_EQ; UNION_SUBSET] THEN + SIMP_TAC[SUBSET; FORALL_IN_IMAGE; SPAN_SUPERSET; SPAN_MUL; IN_UNION] THEN + X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN + SUBGOAL_THEN `x:real^N = norm(x) % inv(norm x) % x` + (fun th -> GEN_REWRITE_TAC LAND_CONV [th]) + THENL + [ASM_SIMP_TAC[VECTOR_MUL_ASSOC; REAL_MUL_RINV; NORM_EQ_0; VECTOR_MUL_LID]; + MATCH_MP_TAC SPAN_MUL THEN MATCH_MP_TAC SPAN_SUPERSET THEN + REWRITE_TAC[IN_UNION; IN_IMAGE] THEN ASM_MESON_TAC[]]]);; + +let VECTOR_IN_ORTHOGONAL_SPANNINGSET = prove + (`!a. ?s. a IN s /\ pairwise orthogonal s /\ span s = (:real^N)`, + GEN_TAC THEN + MP_TAC(ISPECL [`{a:real^N}`; `(IMAGE basis (1..dimindex(:N))):real^N->bool`] + ORTHOGONAL_EXTENSION) THEN + REWRITE_TAC[PAIRWISE_SING] THEN + DISCH_THEN(X_CHOOSE_THEN `u:real^N->bool` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `{a:real^N} UNION u` THEN ASM_REWRITE_TAC[IN_UNION; IN_SING] THEN + MATCH_MP_TAC(SET_RULE `!s. s = UNIV /\ s SUBSET t ==> t = UNIV`) THEN + EXISTS_TAC `span {basis i:real^N | 1 <= i /\ i <= dimindex (:N)}` THEN + CONJ_TAC THENL [REWRITE_TAC[SPAN_STDBASIS]; MATCH_MP_TAC SPAN_MONO] THEN + REWRITE_TAC[SUBSET; FORALL_IN_GSPEC; GSYM IN_NUMSEG] THEN SET_TAC[]);; + +let VECTOR_IN_ORTHOGONAL_BASIS = prove + (`!a. ~(a = vec 0) + ==> ?s. a IN s /\ ~(vec 0 IN s) /\ + pairwise orthogonal s /\ + independent s /\ + s HAS_SIZE (dimindex(:N)) /\ + span s = (:real^N)`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPEC `a:real^N` VECTOR_IN_ORTHOGONAL_SPANNINGSET) THEN + DISCH_THEN(X_CHOOSE_THEN `s:real^N->bool` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `s DELETE (vec 0:real^N)` THEN ASM_REWRITE_TAC[IN_DELETE] THEN + MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN CONJ_TAC THENL + [RULE_ASSUM_TAC(REWRITE_RULE[pairwise]) THEN + ASM_SIMP_TAC[pairwise; IN_DELETE]; + DISCH_TAC] THEN + MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN CONJ_TAC THENL + [MATCH_MP_TAC PAIRWISE_ORTHOGONAL_INDEPENDENT THEN ASM_SIMP_TAC[IN_DELETE]; + DISCH_TAC] THEN + MATCH_MP_TAC(TAUT `b /\ (b ==> a) ==> a /\ b`) THEN CONJ_TAC THENL + [ASM_MESON_TAC[SPAN_DELETE_0]; + DISCH_TAC THEN ASM_SIMP_TAC[BASIS_HAS_SIZE_UNIV]]);; + +let VECTOR_IN_ORTHONORMAL_BASIS = prove + (`!a. norm a = &1 + ==> ?s. a IN s /\ + pairwise orthogonal s /\ + (!x. x IN s ==> norm x = &1) /\ + independent s /\ + s HAS_SIZE (dimindex(:N)) /\ + span s = (:real^N)`, + GEN_TAC THEN ASM_CASES_TAC `a:real^N = vec 0` THEN + ASM_REWRITE_TAC[NORM_0; REAL_OF_NUM_EQ; ARITH_EQ] THEN DISCH_TAC THEN + FIRST_ASSUM(MP_TAC o MATCH_MP VECTOR_IN_ORTHOGONAL_BASIS) THEN + DISCH_THEN(X_CHOOSE_THEN `s:real^N->bool` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `IMAGE (\x:real^N. inv(norm x) % x) s` THEN + CONJ_TAC THENL + [REWRITE_TAC[IN_IMAGE] THEN EXISTS_TAC `a:real^N` THEN + ASM_REWRITE_TAC[REAL_INV_1; VECTOR_MUL_LID]; + ALL_TAC] THEN + MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN CONJ_TAC THENL + [REWRITE_TAC[pairwise; IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_IMAGE] THEN + RULE_ASSUM_TAC(REWRITE_RULE[pairwise]) THEN + ASM_MESON_TAC[ORTHOGONAL_CLAUSES]; + DISCH_TAC] THEN + MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN CONJ_TAC THENL + [REWRITE_TAC[FORALL_IN_IMAGE; NORM_MUL; REAL_ABS_INV; REAL_ABS_NORM] THEN + ASM_MESON_TAC[REAL_MUL_LINV; NORM_EQ_0]; + DISCH_TAC] THEN + MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN CONJ_TAC THENL + [MATCH_MP_TAC PAIRWISE_ORTHOGONAL_INDEPENDENT THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[IN_IMAGE] THEN ONCE_REWRITE_TAC[EQ_SYM_EQ] THEN + SIMP_TAC[VECTOR_MUL_EQ_0; REAL_INV_EQ_0; NORM_EQ_0] THEN ASM_MESON_TAC[]; + DISCH_TAC] THEN + MATCH_MP_TAC(TAUT `b /\ (b ==> a) ==> a /\ b`) THEN CONJ_TAC THENL + [ALL_TAC; ASM_SIMP_TAC[BASIS_HAS_SIZE_UNIV]] THEN + UNDISCH_THEN `span s = (:real^N)` (SUBST1_TAC o SYM) THEN + MATCH_MP_TAC SPAN_IMAGE_SCALE THEN + REWRITE_TAC[REAL_INV_EQ_0; NORM_EQ_0] THEN + ASM_MESON_TAC[HAS_SIZE]);; + +let BESSEL_INEQUALITY = prove + (`!s x:real^N. + pairwise orthogonal s /\ (!x. x IN s ==> norm x = &1) + ==> sum s (\e. (e dot x) pow 2) <= norm(x) pow 2`, + REPEAT STRIP_TAC THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP PAIRWISE_ORTHOGONAL_IMP_FINITE) THEN + MP_TAC(ISPEC `x - vsum s (\e. (e dot x) % e):real^N` DOT_POS_LE) THEN + REWRITE_TAC[NORM_POW_2; VECTOR_ARITH + `(a - b:real^N) dot (a - b) = a dot a + b dot b - &2 * b dot a`] THEN + ASM_SIMP_TAC[DOT_LSUM; REAL_POW_2; DOT_LMUL] THEN + MATCH_MP_TAC(REAL_ARITH `t = s ==> &0 <= x + t - &2 * s ==> s <= x`) THEN + MATCH_MP_TAC SUM_EQ THEN X_GEN_TAC `e:real^N` THEN DISCH_TAC THEN + ASM_SIMP_TAC[DOT_RSUM] THEN AP_TERM_TAC THEN + MATCH_MP_TAC EQ_TRANS THEN + EXISTS_TAC `sum s (\k:real^N. if k = e then e dot x else &0)` THEN + CONJ_TAC THENL [ALL_TAC; ASM_SIMP_TAC[SUM_DELTA]] THEN + MATCH_MP_TAC SUM_EQ THEN X_GEN_TAC `k:real^N` THEN DISCH_TAC THEN + REWRITE_TAC[DOT_RMUL] THEN COND_CASES_TAC THENL + [ASM_REWRITE_TAC[REAL_RING `a * x = a <=> a = &0 \/ x = &1`] THEN + DISJ2_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC `e:real^N`) THEN + ASM_REWRITE_TAC[NORM_EQ_SQUARE] THEN REAL_ARITH_TAC; + RULE_ASSUM_TAC(REWRITE_RULE[pairwise; orthogonal]) THEN + ASM_SIMP_TAC[REAL_ENTIRE]]);; + +(* ------------------------------------------------------------------------- *) +(* Analogous theorems for existence of orthonormal basis for a subspace. *) +(* ------------------------------------------------------------------------- *) + +let ORTHOGONAL_SPANNINGSET_SUBSPACE = prove + (`!s:real^N->bool. + subspace s + ==> ?b. b SUBSET s /\ pairwise orthogonal b /\ span b = s`, + REPEAT STRIP_TAC THEN MP_TAC(ISPEC `s:real^N->bool` BASIS_EXISTS) THEN + DISCH_THEN(X_CHOOSE_THEN `b:real^N->bool` STRIP_ASSUME_TAC) THEN + MP_TAC(ISPECL[`{}:real^N->bool`; `b:real^N->bool`] ORTHOGONAL_EXTENSION) THEN + REWRITE_TAC[PAIRWISE_EMPTY; UNION_EMPTY] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `c:real^N->bool` THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC(TAUT `b /\ (b ==> a) ==> a /\ b`) THEN CONJ_TAC THENL + [MATCH_MP_TAC SPAN_SUBSPACE THEN ASM_REWRITE_TAC[]; + DISCH_THEN(SUBST1_TAC o SYM) THEN ASM_MESON_TAC[SPAN_INC]]);; + +let ORTHOGONAL_BASIS_SUBSPACE = prove + (`!s:real^N->bool. + subspace s + ==> ?b. ~(vec 0 IN b) /\ + b SUBSET s /\ + pairwise orthogonal b /\ + independent b /\ + b HAS_SIZE (dim s) /\ + span b = s`, + REPEAT STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o MATCH_MP ORTHOGONAL_SPANNINGSET_SUBSPACE) THEN + DISCH_THEN(X_CHOOSE_THEN `b:real^N->bool` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `b DELETE (vec 0:real^N)` THEN ASM_REWRITE_TAC[IN_DELETE] THEN + CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN CONJ_TAC THENL + [RULE_ASSUM_TAC(REWRITE_RULE[pairwise]) THEN + ASM_SIMP_TAC[pairwise; IN_DELETE]; + DISCH_TAC] THEN + MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN CONJ_TAC THENL + [MATCH_MP_TAC PAIRWISE_ORTHOGONAL_INDEPENDENT THEN ASM_SIMP_TAC[IN_DELETE]; + DISCH_TAC] THEN + MATCH_MP_TAC(TAUT `b /\ (b ==> a) ==> a /\ b`) THEN CONJ_TAC THENL + [ASM_MESON_TAC[SPAN_DELETE_0]; + DISCH_TAC THEN ASM_SIMP_TAC[BASIS_HAS_SIZE_DIM]]);; + +let ORTHONORMAL_BASIS_SUBSPACE = prove + (`!s:real^N->bool. + subspace s + ==> ?b. b SUBSET s /\ + pairwise orthogonal b /\ + (!x. x IN b ==> norm x = &1) /\ + independent b /\ + b HAS_SIZE (dim s) /\ + span b = s`, + REPEAT STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o MATCH_MP ORTHOGONAL_BASIS_SUBSPACE) THEN + DISCH_THEN(X_CHOOSE_THEN `b:real^N->bool` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `IMAGE (\x:real^N. inv(norm x) % x) b` THEN + CONJ_TAC THENL + [REWRITE_TAC[SUBSET; FORALL_IN_IMAGE] THEN + ASM_MESON_TAC[SPAN_MUL; SPAN_INC; SUBSET]; + ALL_TAC] THEN + MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN CONJ_TAC THENL + [REWRITE_TAC[pairwise; IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_IMAGE] THEN + RULE_ASSUM_TAC(REWRITE_RULE[pairwise]) THEN + ASM_MESON_TAC[ORTHOGONAL_CLAUSES]; + DISCH_TAC] THEN + MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN CONJ_TAC THENL + [REWRITE_TAC[FORALL_IN_IMAGE; NORM_MUL; REAL_ABS_INV; REAL_ABS_NORM] THEN + ASM_MESON_TAC[REAL_MUL_LINV; NORM_EQ_0]; + DISCH_TAC] THEN + MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN CONJ_TAC THENL + [MATCH_MP_TAC PAIRWISE_ORTHOGONAL_INDEPENDENT THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[IN_IMAGE] THEN ONCE_REWRITE_TAC[EQ_SYM_EQ] THEN + SIMP_TAC[VECTOR_MUL_EQ_0; REAL_INV_EQ_0; NORM_EQ_0] THEN ASM_MESON_TAC[]; + DISCH_TAC] THEN + MATCH_MP_TAC(TAUT `b /\ (b ==> a) ==> a /\ b`) THEN CONJ_TAC THENL + [ALL_TAC; ASM_SIMP_TAC[BASIS_HAS_SIZE_DIM]] THEN + UNDISCH_THEN `span b = (s:real^N->bool)` (SUBST1_TAC o SYM) THEN + MATCH_MP_TAC SPAN_IMAGE_SCALE THEN + REWRITE_TAC[REAL_INV_EQ_0; NORM_EQ_0] THEN + ASM_MESON_TAC[HAS_SIZE]);; + +let ORTHOGONAL_TO_SUBSPACE_EXISTS_GEN = prove + (`!s t:real^N->bool. + span s PSUBSET span t + ==> ?x. ~(x = vec 0) /\ x IN span t /\ + (!y. y IN span s ==> orthogonal x y)`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPEC `span s:real^N->bool` ORTHOGONAL_BASIS_SUBSPACE) THEN + REWRITE_TAC[SUBSPACE_SPAN] THEN + DISCH_THEN(X_CHOOSE_THEN `b:real^N->bool` STRIP_ASSUME_TAC) THEN + FIRST_X_ASSUM(SUBST_ALL_TAC o SYM) THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [PSUBSET_ALT]) THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC + (X_CHOOSE_THEN `u:real^N` STRIP_ASSUME_TAC)) THEN + MP_TAC(ISPECL [`b:real^N->bool`; `{u:real^N}`] ORTHOGONAL_EXTENSION) THEN + ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `ns:real^N->bool` MP_TAC) THEN + ASM_CASES_TAC `ns SUBSET (vec 0:real^N) INSERT b` THENL + [DISCH_THEN(MP_TAC o AP_TERM `(IN) (u:real^N)` o CONJUNCT2) THEN + SIMP_TAC[SPAN_SUPERSET; IN_UNION; IN_SING] THEN + MATCH_MP_TAC(TAUT `~p ==> p ==> q`) THEN + SUBGOAL_THEN `~(u IN span (b UNION {vec 0:real^N}))` MP_TAC THENL + [ASM_REWRITE_TAC[SET_RULE `s UNION {a} = a INSERT s`; SPAN_INSERT_0]; + MATCH_MP_TAC(SET_RULE `s SUBSET t ==> ~(x IN t) ==> ~(x IN s)`) THEN + MATCH_MP_TAC SPAN_MONO THEN ASM SET_TAC[]]; + ALL_TAC] THEN + FIRST_X_ASSUM(MP_TAC o MATCH_MP (SET_RULE + `~(s SUBSET t) ==> ?z. z IN s /\ ~(z IN t)`)) THEN + REWRITE_TAC[LEFT_IMP_EXISTS_THM; IN_INSERT; DE_MORGAN_THM] THEN + X_GEN_TAC `n:real^N` THEN STRIP_TAC THEN + DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN + REWRITE_TAC[pairwise; IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN + DISCH_THEN(MP_TAC o SPEC `n:real^N`) THEN ASM_REWRITE_TAC[IN_UNION] THEN + REWRITE_TAC[IMP_IMP] THEN DISCH_TAC THEN EXISTS_TAC `n:real^N` THEN + ASM_REWRITE_TAC[] THEN CONJ_TAC THENL + [SUBGOAL_THEN `(n:real^N) IN span (b UNION ns)` MP_TAC THENL + [MATCH_MP_TAC SPAN_SUPERSET THEN ASM SET_TAC[]; + ASM_REWRITE_TAC[] THEN SPEC_TAC(`n:real^N`,`n:real^N`) THEN + REWRITE_TAC[GSYM SUBSET] THEN + MATCH_MP_TAC SPAN_SUBSET_SUBSPACE THEN REWRITE_TAC[SUBSPACE_SPAN] THEN + ASM_REWRITE_TAC[SET_RULE + `s UNION {a} SUBSET t <=> s SUBSET t /\ a IN t`] THEN + ASM_MESON_TAC[SPAN_INC; SUBSET_TRANS]]; + MATCH_MP_TAC SPAN_INDUCT THEN + REWRITE_TAC[SET_RULE `(\y. orthogonal n y) = {y | orthogonal n y}`] THEN + REWRITE_TAC[SUBSPACE_ORTHOGONAL_TO_VECTOR] THEN ASM SET_TAC[]]);; + +let ORTHOGONAL_TO_SUBSPACE_EXISTS = prove + (`!s:real^N->bool. dim s < dimindex(:N) + ==> ?x. ~(x = vec 0) /\ !y. y IN s ==> orthogonal x y`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`s:real^N->bool`; `(:real^N)`] + ORTHOGONAL_TO_SUBSPACE_EXISTS_GEN) THEN + ANTS_TAC THENL [REWRITE_TAC[PSUBSET]; MESON_TAC[SPAN_SUPERSET]] THEN + REWRITE_TAC[SPAN_UNIV; SUBSET_UNIV] THEN + ASM_MESON_TAC[DIM_SPAN; DIM_UNIV; LT_REFL]);; + +let ORTHOGONAL_TO_VECTOR_EXISTS = prove + (`!x:real^N. 2 <= dimindex(:N) ==> ?y. ~(y = vec 0) /\ orthogonal x y`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPEC `{x:real^N}` ORTHOGONAL_TO_SUBSPACE_EXISTS) THEN + SIMP_TAC[DIM_SING; IN_SING; LEFT_FORALL_IMP_THM; EXISTS_REFL] THEN + ANTS_TAC THENL [ASM_ARITH_TAC; MESON_TAC[ORTHOGONAL_SYM]]);; + +let SPAN_NOT_UNIV_ORTHOGONAL = prove + (`!s. ~(span s = (:real^N)) + ==> ?a. ~(a = vec 0) /\ !x. x IN span s ==> a dot x = &0`, + REWRITE_TAC[GSYM DIM_EQ_FULL; GSYM LE_ANTISYM; DIM_SUBSET_UNIV; + NOT_LE] THEN + REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM orthogonal] THEN + MATCH_MP_TAC ORTHOGONAL_TO_SUBSPACE_EXISTS THEN ASM_REWRITE_TAC[DIM_SPAN]);; + +let SPAN_NOT_UNIV_SUBSET_HYPERPLANE = prove + (`!s. ~(span s = (:real^N)) + ==> ?a. ~(a = vec 0) /\ span s SUBSET {x | a dot x = &0}`, + REWRITE_TAC[SUBSET; IN_ELIM_THM; SPAN_NOT_UNIV_ORTHOGONAL]);; + +let LOWDIM_SUBSET_HYPERPLANE = prove + (`!s. dim s < dimindex(:N) + ==> ?a:real^N. ~(a = vec 0) /\ span s SUBSET {x | a dot x = &0}`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC SPAN_NOT_UNIV_SUBSET_HYPERPLANE THEN + REWRITE_TAC[GSYM SUBSET_ANTISYM_EQ; SUBSET_UNIV] THEN + DISCH_THEN(MP_TAC o MATCH_MP DIM_SUBSET) THEN + ASM_REWRITE_TAC[NOT_LE; DIM_SPAN; DIM_UNIV]);; + +let VECTOR_EQ_DOT_SPAN = prove + (`!b x y:real^N. + (!v. v IN b ==> v dot x = v dot y) /\ x IN span b /\ y IN span b + ==> x = y`, + ONCE_REWRITE_TAC[GSYM REAL_SUB_0; GSYM VECTOR_SUB_EQ] THEN + REWRITE_TAC[GSYM DOT_RSUB; GSYM ORTHOGONAL_REFL; GSYM orthogonal] THEN + MESON_TAC[ORTHOGONAL_TO_SPAN; SPAN_SUB; ORTHOGONAL_SYM]);; + +let ORTHONORMAL_BASIS_EXPAND = prove + (`!b x:real^N. + pairwise orthogonal b /\ (!v. v IN b ==> norm v = &1) /\ x IN span b + ==> vsum b (\v. (v dot x) % v) = x`, + REWRITE_TAC[NORM_EQ_1] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC VECTOR_EQ_DOT_SPAN THEN EXISTS_TAC `b:real^N->bool` THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP PAIRWISE_ORTHOGONAL_IMP_FINITE) THEN + RULE_ASSUM_TAC(REWRITE_RULE[pairwise; orthogonal]) THEN + ASM_SIMP_TAC[SPAN_VSUM; SPAN_MUL; DOT_RSUM; DOT_RMUL; SPAN_SUPERSET] THEN + X_GEN_TAC `v:real^N` THEN DISCH_TAC THEN + TRANS_TAC EQ_TRANS `sum b (\w:real^N. if w = v then v dot x else &0)` THEN + CONJ_TAC THENL [ALL_TAC; ASM_SIMP_TAC[SUM_DELTA]] THEN + MATCH_MP_TAC SUM_EQ THEN ASM_REWRITE_TAC[] THEN + X_GEN_TAC `w:real^N` THEN DISCH_TAC THEN + COND_CASES_TAC THEN ASM_SIMP_TAC[REAL_MUL_RID; REAL_MUL_RZERO]);; + +(* ------------------------------------------------------------------------- *) +(* Decomposing a vector into parts in orthogonal subspaces. *) +(* ------------------------------------------------------------------------- *) + +let ORTHOGONAL_SUBSPACE_DECOMP_UNIQUE = prove + (`!s t x y x' y':real^N. + (!a b. a IN s /\ b IN t ==> orthogonal a b) /\ + x IN span s /\ x' IN span s /\ y IN span t /\ y' IN span t /\ + x + y = x' + y' + ==> x = x' /\ y = y'`, + REWRITE_TAC[VECTOR_ARITH `x + y:real^N = x' + y' <=> x - x' = y' - y`] THEN + ONCE_REWRITE_TAC[GSYM ORTHOGONAL_TO_SPANS_EQ] THEN + REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[VECTOR_ARITH + `x:real^N = x' /\ y:real^N = y' <=> x - x' = vec 0 /\ y' - y = vec 0`] THEN + STRIP_TAC THEN ASM_REWRITE_TAC[GSYM ORTHOGONAL_REFL] THEN + FIRST_X_ASSUM(fun th -> GEN_REWRITE_TAC RAND_CONV [SYM th]) THEN + ASM_MESON_TAC[ORTHOGONAL_CLAUSES; ORTHOGONAL_SYM]);; + +let ORTHOGONAL_SUBSPACE_DECOMP_EXISTS = prove + (`!s x:real^N. ?y z. y IN span s /\ (!w. w IN span s ==> orthogonal z w) /\ + x = y + z`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPEC `span s:real^N->bool` ORTHOGONAL_BASIS_SUBSPACE) THEN + REWRITE_TAC[SUBSPACE_SPAN; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `t:real^N->bool` THEN STRIP_TAC THEN + FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN + EXISTS_TAC `vsum t (\b:real^N. (b dot x) / (b dot b) % b)` THEN + EXISTS_TAC `x - vsum t (\b:real^N. (b dot x) / (b dot b) % b)` THEN + REPEAT CONJ_TAC THENL + [MATCH_MP_TAC SPAN_VSUM THEN + ASM_SIMP_TAC[INDEPENDENT_IMP_FINITE; SPAN_CLAUSES]; + REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[ORTHOGONAL_SYM] THEN + MATCH_MP_TAC GRAM_SCHMIDT_STEP THEN ASM_SIMP_TAC[]; + VECTOR_ARITH_TAC]);; + +let ORTHOGONAL_SUBSPACE_DECOMP = prove + (`!s x. ?!(y,z). y IN span s /\ + z IN {z:real^N | !x. x IN span s ==> orthogonal z x} /\ + x = y + z`, + REWRITE_TAC[EXISTS_UNIQUE_DEF; IN_ELIM_THM] THEN + REWRITE_TAC[EXISTS_PAIRED_THM; FORALL_PAIRED_THM] THEN + REWRITE_TAC[FORALL_PAIR_THM; ORTHOGONAL_SUBSPACE_DECOMP_EXISTS] THEN + REPEAT STRIP_TAC THEN REWRITE_TAC[PAIR_EQ] THEN + MATCH_MP_TAC ORTHOGONAL_SUBSPACE_DECOMP_UNIQUE THEN + MAP_EVERY EXISTS_TAC + [`s:real^N->bool`; `{z:real^N | !x. x IN span s ==> orthogonal z x}`] THEN + ASM_SIMP_TAC[SPAN_CLAUSES; IN_ELIM_THM] THEN + ASM_MESON_TAC[SPAN_CLAUSES; ORTHOGONAL_SYM]);; + +(* ------------------------------------------------------------------------- *) +(* Existence of isometry between subspaces of same dimension. *) +(* ------------------------------------------------------------------------- *) + +let ISOMETRY_SUBSET_SUBSPACE = prove + (`!s:real^M->bool t:real^N->bool. + subspace s /\ subspace t /\ dim s <= dim t + ==> ?f. linear f /\ IMAGE f s SUBSET t /\ + (!x. x IN s ==> norm(f x) = norm(x))`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPEC `t:real^N->bool` ORTHONORMAL_BASIS_SUBSPACE) THEN + MP_TAC(ISPEC `s:real^M->bool` ORTHONORMAL_BASIS_SUBSPACE) THEN + ASM_REWRITE_TAC[HAS_SIZE] THEN + DISCH_THEN(X_CHOOSE_THEN `b:real^M->bool` STRIP_ASSUME_TAC) THEN + DISCH_THEN(X_CHOOSE_THEN `c:real^N->bool` STRIP_ASSUME_TAC) THEN + MP_TAC(ISPECL [`b:real^M->bool`; `c:real^N->bool`] CARD_LE_INJ) THEN + ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM; INJECTIVE_ON_ALT] THEN + X_GEN_TAC `fb:real^M->real^N` THEN STRIP_TAC THEN + MP_TAC(ISPECL [`fb:real^M->real^N`; `b:real^M->bool`] + LINEAR_INDEPENDENT_EXTEND) THEN + ASM_REWRITE_TAC[IMP_IMP; LEFT_AND_EXISTS_THM; INJECTIVE_ON_ALT] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `f:real^M->real^N` THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN CONJ_TAC THENL + [REWRITE_TAC[SYM(ASSUME `span b:real^M->bool = s`)] THEN + ASM_SIMP_TAC[GSYM SPAN_LINEAR_IMAGE] THEN + REWRITE_TAC[SYM(ASSUME `span c:real^N->bool = t`)] THEN + MATCH_MP_TAC SPAN_MONO THEN ASM SET_TAC[]; + UNDISCH_THEN `span b:real^M->bool = s` (SUBST1_TAC o SYM) THEN + ASM_SIMP_TAC[SPAN_FINITE] THEN + REWRITE_TAC[IN_ELIM_THM; LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`z:real^M`; `u:real^M->real`] THEN + DISCH_THEN(SUBST1_TAC o SYM) THEN ASM_SIMP_TAC[LINEAR_VSUM] THEN + REWRITE_TAC[o_DEF; NORM_EQ_SQUARE; NORM_POS_LE; GSYM NORM_POW_2] THEN + ASM_SIMP_TAC[LINEAR_CMUL] THEN + W(MP_TAC o PART_MATCH (lhand o rand) + NORM_VSUM_PYTHAGOREAN o rand o snd) THEN + W(MP_TAC o PART_MATCH (lhand o rand) + NORM_VSUM_PYTHAGOREAN o lhand o rand o snd) THEN + RULE_ASSUM_TAC(REWRITE_RULE[pairwise]) THEN + ASM_SIMP_TAC[pairwise; ORTHOGONAL_CLAUSES] THEN ANTS_TAC THENL + [REPEAT STRIP_TAC THEN REWRITE_TAC[ORTHOGONAL_MUL] THEN ASM SET_TAC[]; + REPEAT(DISCH_THEN SUBST1_TAC) THEN ASM_SIMP_TAC[NORM_MUL] THEN + MATCH_MP_TAC SUM_EQ THEN ASM SET_TAC[]]]);; + +let ISOMETRIES_SUBSPACES = prove + (`!s:real^M->bool t:real^N->bool. + subspace s /\ subspace t /\ dim s = dim t + ==> ?f g. linear f /\ linear g /\ + IMAGE f s = t /\ IMAGE g t = s /\ + (!x. x IN s ==> norm(f x) = norm x) /\ + (!y. y IN t ==> norm(g y) = norm y) /\ + (!x. x IN s ==> g(f x) = x) /\ + (!y. y IN t ==> f(g y) = y)`, + REPEAT STRIP_TAC THEN ABBREV_TAC `n = dim(t:real^N->bool)` THEN + MP_TAC(ISPEC `t:real^N->bool` ORTHONORMAL_BASIS_SUBSPACE) THEN + MP_TAC(ISPEC `s:real^M->bool` ORTHONORMAL_BASIS_SUBSPACE) THEN + ASM_REWRITE_TAC[] THEN + DISCH_THEN(X_CHOOSE_THEN `b:real^M->bool` STRIP_ASSUME_TAC) THEN + DISCH_THEN(X_CHOOSE_THEN `c:real^N->bool` STRIP_ASSUME_TAC) THEN + MP_TAC(ISPECL [`b:real^M->bool`; `c:real^N->bool`] CARD_EQ_BIJECTIONS) THEN + RULE_ASSUM_TAC(REWRITE_RULE[HAS_SIZE]) THEN + ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`fb:real^M->real^N`; `gb:real^N->real^M`] THEN + STRIP_TAC THEN + MP_TAC(ISPECL [`gb:real^N->real^M`; `c:real^N->bool`] + LINEAR_INDEPENDENT_EXTEND) THEN + MP_TAC(ISPECL [`fb:real^M->real^N`; `b:real^M->bool`] + LINEAR_INDEPENDENT_EXTEND) THEN + ASM_REWRITE_TAC[IMP_IMP; LEFT_AND_EXISTS_THM] THEN + REWRITE_TAC[RIGHT_AND_EXISTS_THM] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `f:real^M->real^N` THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `g:real^N->real^M` THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN REPEAT CONJ_TAC THENL + [REWRITE_TAC[SYM(ASSUME `span b:real^M->bool = s`)] THEN + ASM_SIMP_TAC[GSYM SPAN_LINEAR_IMAGE] THEN + REWRITE_TAC[SYM(ASSUME `span c:real^N->bool = t`)] THEN + AP_TERM_TAC THEN ASM SET_TAC[]; + REWRITE_TAC[SYM(ASSUME `span c:real^N->bool = t`)] THEN + ASM_SIMP_TAC[GSYM SPAN_LINEAR_IMAGE] THEN + REWRITE_TAC[SYM(ASSUME `span b:real^M->bool = s`)] THEN + AP_TERM_TAC THEN ASM SET_TAC[]; + UNDISCH_THEN `span b:real^M->bool = s` (SUBST1_TAC o SYM) THEN + ASM_SIMP_TAC[SPAN_FINITE] THEN + REWRITE_TAC[IN_ELIM_THM; LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`z:real^M`; `u:real^M->real`] THEN + DISCH_THEN(SUBST1_TAC o SYM) THEN ASM_SIMP_TAC[LINEAR_VSUM] THEN + REWRITE_TAC[o_DEF; NORM_EQ_SQUARE; NORM_POS_LE; GSYM NORM_POW_2] THEN + ASM_SIMP_TAC[LINEAR_CMUL] THEN + W(MP_TAC o PART_MATCH (lhand o rand) + NORM_VSUM_PYTHAGOREAN o rand o snd) THEN + W(MP_TAC o PART_MATCH (lhand o rand) + NORM_VSUM_PYTHAGOREAN o lhand o rand o snd) THEN + RULE_ASSUM_TAC(REWRITE_RULE[pairwise]) THEN + ASM_SIMP_TAC[pairwise; ORTHOGONAL_CLAUSES] THEN ANTS_TAC THENL + [REPEAT STRIP_TAC THEN REWRITE_TAC[ORTHOGONAL_MUL] THEN ASM SET_TAC[]; + REPEAT(DISCH_THEN SUBST1_TAC) THEN + ASM_SIMP_TAC[NORM_MUL]]; + UNDISCH_THEN `span c:real^N->bool = t` (SUBST1_TAC o SYM) THEN + ASM_SIMP_TAC[SPAN_FINITE] THEN + REWRITE_TAC[IN_ELIM_THM; LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`z:real^N`; `u:real^N->real`] THEN + DISCH_THEN(SUBST1_TAC o SYM) THEN ASM_SIMP_TAC[LINEAR_VSUM] THEN + REWRITE_TAC[o_DEF; NORM_EQ_SQUARE; NORM_POS_LE; GSYM NORM_POW_2] THEN + ASM_SIMP_TAC[LINEAR_CMUL] THEN + W(MP_TAC o PART_MATCH (lhand o rand) + NORM_VSUM_PYTHAGOREAN o rand o snd) THEN + W(MP_TAC o PART_MATCH (lhand o rand) + NORM_VSUM_PYTHAGOREAN o lhand o rand o snd) THEN + RULE_ASSUM_TAC(REWRITE_RULE[pairwise]) THEN + ASM_SIMP_TAC[pairwise; ORTHOGONAL_CLAUSES] THEN ANTS_TAC THENL + [REPEAT STRIP_TAC THEN REWRITE_TAC[ORTHOGONAL_MUL] THEN ASM SET_TAC[]; + REPEAT(DISCH_THEN SUBST1_TAC) THEN + ASM_SIMP_TAC[NORM_MUL]]; + REWRITE_TAC[SYM(ASSUME `span b:real^M->bool = s`)] THEN + MATCH_MP_TAC SPAN_INDUCT THEN + CONJ_TAC THENL [ASM_MESON_TAC[SUBSET; IN]; ALL_TAC] THEN + REWRITE_TAC[subspace; IN] THEN ASM_MESON_TAC[linear; LINEAR_0]; + REWRITE_TAC[SYM(ASSUME `span c:real^N->bool = t`)] THEN + MATCH_MP_TAC SPAN_INDUCT THEN + CONJ_TAC THENL [ASM_MESON_TAC[SUBSET; IN]; ALL_TAC] THEN + REWRITE_TAC[subspace; IN] THEN ASM_MESON_TAC[linear; LINEAR_0]]);; + +let ISOMETRY_SUBSPACES = prove + (`!s:real^M->bool t:real^N->bool. + subspace s /\ subspace t /\ dim s = dim t + ==> ?f:real^M->real^N. linear f /\ IMAGE f s = t /\ + (!x. x IN s ==> norm(f x) = norm(x))`, + REPEAT GEN_TAC THEN + DISCH_THEN(MP_TAC o MATCH_MP ISOMETRIES_SUBSPACES) THEN + MATCH_MP_TAC MONO_EXISTS THEN MESON_TAC[]);; + +let ISOMETRY_UNIV_SUBSPACE = prove + (`!s. subspace s /\ dimindex(:M) = dim s + ==> ?f:real^M->real^N. + linear f /\ IMAGE f (:real^M) = s /\ + (!x. norm(f x) = norm(x))`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`(:real^M)`; `s:real^N->bool`] ISOMETRY_SUBSPACES) THEN + ASM_REWRITE_TAC[SUBSPACE_UNIV; IN_UNIV; DIM_UNIV]);; + +let ISOMETRY_UNIV_SUPERSET_SUBSPACE = prove + (`!s. subspace s /\ dim s <= dimindex(:M) /\ dimindex(:M) <= dimindex(:N) + ==> ?f:real^M->real^N. + linear f /\ s SUBSET (IMAGE f (:real^M)) /\ + (!x. norm(f x) = norm(x))`, + GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN ASSUME_TAC) THEN + FIRST_ASSUM(MP_TAC o MATCH_MP LOWDIM_EXPAND_DIMENSION) THEN + DISCH_THEN(X_CHOOSE_THEN `t:real^N->bool` STRIP_ASSUME_TAC) THEN + MP_TAC(ISPECL [`(:real^M)`; `span t:real^N->bool`] ISOMETRY_SUBSPACES) THEN + ASM_REWRITE_TAC[SUBSPACE_SPAN; SUBSPACE_UNIV; DIM_UNIV; DIM_SPAN] THEN + MATCH_MP_TAC MONO_EXISTS THEN SIMP_TAC[IN_UNIV] THEN + ASM_MESON_TAC[SUBSET; SPAN_INC]);; + +let ISOMETRY_UNIV_UNIV = prove + (`dimindex(:M) <= dimindex(:N) + ==> ?f:real^M->real^N. linear f /\ (!x. norm(f x) = norm(x))`, + DISCH_TAC THEN + MP_TAC(ISPEC `{vec 0:real^N}`ISOMETRY_UNIV_SUPERSET_SUBSPACE) THEN + ASM_REWRITE_TAC[SUBSPACE_TRIVIAL] THEN + ANTS_TAC THENL [ALL_TAC; ASM_MESON_TAC[]] THEN + MATCH_MP_TAC(ARITH_RULE `x = 0 /\ 1 <= y ==> x <= y`) THEN + ASM_REWRITE_TAC[DIM_EQ_0; DIMINDEX_GE_1] THEN SET_TAC[]);; + +let SUBSPACE_ISOMORPHISM = prove + (`!s t. subspace s /\ subspace t /\ dim(s) = dim(t) + ==> ?f:real^M->real^N. + linear f /\ (IMAGE f s = t) /\ + (!x y. x IN s /\ y IN s /\ f x = f y ==> (x = y))`, + REPEAT GEN_TAC THEN DISCH_TAC THEN + FIRST_ASSUM(MP_TAC o MATCH_MP ISOMETRY_SUBSPACES) THEN + MATCH_MP_TAC MONO_EXISTS THEN + ASM_SIMP_TAC[LINEAR_INJECTIVE_0_SUBSPACE] THEN MESON_TAC[NORM_EQ_0]);; + +let ISOMORPHISMS_UNIV_UNIV = prove + (`dimindex(:M) = dimindex(:N) + ==> ?f:real^M->real^N g. + linear f /\ linear g /\ + (!x. norm(f x) = norm x) /\ (!y. norm(g y) = norm y) /\ + (!x. g(f x) = x) /\ (!y. f(g y) = y)`, + REPEAT STRIP_TAC THEN + EXISTS_TAC `(\x. lambda i. x$i):real^M->real^N` THEN + EXISTS_TAC `(\x. lambda i. x$i):real^N->real^M` THEN + SIMP_TAC[vector_norm; dot; LAMBDA_BETA] THEN + SIMP_TAC[linear; CART_EQ; VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT; + LAMBDA_BETA] THEN + FIRST_ASSUM SUBST1_TAC THEN SIMP_TAC[LAMBDA_BETA] THEN + FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN SIMP_TAC[LAMBDA_BETA]);; + +(* ------------------------------------------------------------------------- *) +(* Properties of special hyperplanes. *) +(* ------------------------------------------------------------------------- *) + +let SUBSPACE_HYPERPLANE = prove + (`!a. subspace {x:real^N | a dot x = &0}`, + SIMP_TAC[subspace; DOT_RADD; DOT_RMUL; IN_ELIM_THM; REAL_ADD_LID; + REAL_MUL_RZERO; DOT_RZERO]);; + +let SUBSPACE_SPECIAL_HYPERPLANE = prove + (`!k. subspace {x:real^N | x$k = &0}`, + SIMP_TAC[subspace; IN_ELIM_THM; VEC_COMPONENT; + VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT] THEN REAL_ARITH_TAC);; + +let SPECIAL_HYPERPLANE_SPAN = prove + (`!k. 1 <= k /\ k <= dimindex(:N) + ==> {x:real^N | x$k = &0} = + span(IMAGE basis ((1..dimindex(:N)) DELETE k))`, + REPEAT STRIP_TAC THEN CONV_TAC SYM_CONV THEN MATCH_MP_TAC SPAN_SUBSPACE THEN + ASM_SIMP_TAC[SUBSPACE_SPECIAL_HYPERPLANE] THEN CONJ_TAC THENL + [REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; IN_ELIM_THM] THEN + ASM_SIMP_TAC[BASIS_COMPONENT; IN_DELETE]; + REWRITE_TAC[SUBSET; IN_ELIM_THM] THEN + X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN + GEN_REWRITE_TAC LAND_CONV [GSYM BASIS_EXPANSION] THEN + SIMP_TAC[SPAN_FINITE; FINITE_IMAGE; FINITE_DELETE; FINITE_NUMSEG] THEN + REWRITE_TAC[IN_ELIM_THM] THEN + EXISTS_TAC `\v:real^N. x dot v` THEN + W(MP_TAC o PART_MATCH (lhs o rand) VSUM_IMAGE o lhs o snd) THEN + ANTS_TAC THENL + [REWRITE_TAC[FINITE_DELETE; FINITE_NUMSEG; IN_NUMSEG; IN_DELETE] THEN + MESON_TAC[BASIS_INJ]; + DISCH_THEN SUBST1_TAC THEN REWRITE_TAC[o_DEF] THEN + ASM_SIMP_TAC[VSUM_DELETE; FINITE_NUMSEG; IN_NUMSEG; DOT_BASIS] THEN + REWRITE_TAC[VECTOR_MUL_LZERO; VECTOR_SUB_RZERO]]]);; + +let DIM_SPECIAL_HYPERPLANE = prove + (`!k. 1 <= k /\ k <= dimindex(:N) + ==> dim {x:real^N | x$k = &0} = dimindex(:N) - 1`, + SIMP_TAC[SPECIAL_HYPERPLANE_SPAN] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC DIM_UNIQUE THEN + EXISTS_TAC `IMAGE (basis:num->real^N) ((1..dimindex(:N)) DELETE k)` THEN + REWRITE_TAC[SUBSET_REFL; SPAN_INC] THEN CONJ_TAC THENL + [MATCH_MP_TAC INDEPENDENT_MONO THEN + EXISTS_TAC `{basis i:real^N | 1 <= i /\ i <= dimindex(:N)}` THEN + REWRITE_TAC[INDEPENDENT_STDBASIS; SUBSET; FORALL_IN_IMAGE] THEN + REWRITE_TAC[IN_DELETE; IN_NUMSEG; IN_ELIM_THM] THEN MESON_TAC[]; + MATCH_MP_TAC HAS_SIZE_IMAGE_INJ THEN CONJ_TAC THENL + [REWRITE_TAC[FINITE_DELETE; FINITE_NUMSEG; IN_NUMSEG; IN_DELETE] THEN + MESON_TAC[BASIS_INJ]; + ASM_SIMP_TAC[HAS_SIZE; FINITE_DELETE; FINITE_NUMSEG; CARD_DELETE; + FINITE_IMAGE; IN_NUMSEG; CARD_NUMSEG_1]]]);; + +(* ------------------------------------------------------------------------- *) +(* More theorems about dimensions of different subspaces. *) +(* ------------------------------------------------------------------------- *) + +let DIM_IMAGE_KERNEL_GEN = prove + (`!f:real^M->real^N s. + linear f /\ subspace s + ==> dim(IMAGE f s) + dim {x | x IN s /\ f x = vec 0} = dim(s)`, + REPEAT STRIP_TAC THEN MP_TAC + (ISPEC `{x | x IN s /\ (f:real^M->real^N) x = vec 0}` BASIS_EXISTS) THEN + DISCH_THEN(X_CHOOSE_THEN `v:real^M->bool` STRIP_ASSUME_TAC) THEN + MP_TAC(ISPECL [`v:real^M->bool`; `s:real^M->bool`] + MAXIMAL_INDEPENDENT_SUBSET_EXTEND) THEN + ANTS_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + DISCH_THEN(X_CHOOSE_THEN `w:real^M->bool` STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN `span(w:real^M->bool) = s` + (fun th -> GEN_REWRITE_TAC (RAND_CONV o RAND_CONV) [SYM th] THEN + ASSUME_TAC th) + THENL [ASM_SIMP_TAC[SPAN_SUBSPACE]; ALL_TAC] THEN + SUBGOAL_THEN `subspace {x | x IN s /\ (f:real^M->real^N) x = vec 0}` + ASSUME_TAC THENL + [REWRITE_TAC[SET_RULE `{x | x IN s /\ P x} = s INTER {x | P x}`] THEN + ASM_SIMP_TAC[SUBSPACE_INTER; SUBSPACE_KERNEL]; + ALL_TAC] THEN + SUBGOAL_THEN `{x | x IN s /\ (f:real^M->real^N) x = vec 0} = span v` + ASSUME_TAC THENL + [ASM_MESON_TAC[SUBSET_ANTISYM; SPAN_SUBSET_SUBSPACE; SUBSPACE_KERNEL]; + ALL_TAC] THEN + ASM_SIMP_TAC[DIM_SPAN; DIM_EQ_CARD] THEN + SUBGOAL_THEN + `!x. x IN span(w DIFF v) /\ (f:real^M->real^N) x = vec 0 ==> x = vec 0` + (LABEL_TAC "*") THENL + [MATCH_MP_TAC(SET_RULE + `!t. s SUBSET t /\ (!x. x IN s /\ x IN t /\ P x ==> Q x) + ==> (!x. x IN s /\ P x ==> Q x)`) THEN + EXISTS_TAC `s:real^M->bool` THEN CONJ_TAC THENL + [ASM_MESON_TAC[SPAN_MONO; SUBSET_DIFF]; ALL_TAC] THEN + ASM_SIMP_TAC[SPAN_FINITE; IN_ELIM_THM; IMP_CONJ; FINITE_DIFF; + INDEPENDENT_IMP_FINITE; LEFT_IMP_EXISTS_THM] THEN + GEN_TAC THEN X_GEN_TAC `u:real^M->real` THEN + DISCH_THEN(SUBST1_TAC o SYM) THEN REWRITE_TAC[IMP_IMP] THEN + ONCE_REWRITE_TAC[SET_RULE + `y IN s /\ f y = a <=> y IN {x | x IN s /\ f x = a}`] THEN + ASM_REWRITE_TAC[] THEN + ASM_SIMP_TAC[SPAN_FINITE; INDEPENDENT_IMP_FINITE; IN_ELIM_THM] THEN + DISCH_THEN(X_CHOOSE_TAC `t:real^M->real`) THEN + MP_TAC(ISPEC `w:real^M->bool` INDEPENDENT_EXPLICIT) THEN + ASM_REWRITE_TAC[] THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + DISCH_THEN(MP_TAC o SPEC + `(\x. if x IN w DIFF v then --u x else t x):real^M->real`) THEN + ASM_REWRITE_TAC[COND_RAND] THEN ONCE_REWRITE_TAC[COND_RATOR] THEN + ASM_SIMP_TAC[VSUM_CASES; INDEPENDENT_IMP_FINITE] THEN + REWRITE_TAC[SET_RULE `{x | x IN w /\ x IN (w DIFF v)} = w DIFF v`] THEN + SIMP_TAC[ASSUME `(v:real^M->bool) SUBSET w`; SET_RULE + `v SUBSET w ==> {x | x IN w /\ ~(x IN (w DIFF v))} = v`] THEN + ASM_REWRITE_TAC[VECTOR_MUL_LNEG; VSUM_NEG; VECTOR_ADD_LINV] THEN + DISCH_THEN(fun th -> MATCH_MP_TAC VSUM_EQ_0 THEN MP_TAC th) THEN + REWRITE_TAC[REAL_NEG_EQ_0; VECTOR_MUL_EQ_0; IN_DIFF] THEN MESON_TAC[]; + ALL_TAC] THEN + SUBGOAL_THEN `!x y. x IN (w DIFF v) /\ y IN (w DIFF v) /\ + (f:real^M->real^N) x = f y ==> x = y` + ASSUME_TAC THENL + [REMOVE_THEN "*" MP_TAC THEN + ASM_SIMP_TAC[GSYM LINEAR_INJECTIVE_0_SUBSPACE; SUBSPACE_SPAN] THEN + MP_TAC(ISPEC `w DIFF v:real^M->bool` SPAN_INC) THEN SET_TAC[]; + ALL_TAC] THEN + SUBGOAL_THEN `IMAGE (f:real^M->real^N) s = span(IMAGE f (w DIFF v))` + SUBST1_TAC THENL + [MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL + [ALL_TAC; + ASM_MESON_TAC[SUBSPACE_LINEAR_IMAGE; SPAN_MONO; IMAGE_SUBSET; + SUBSET_TRANS; SUBSET_DIFF; SPAN_EQ_SELF]] THEN + SIMP_TAC[SUBSET; FORALL_IN_IMAGE] THEN X_GEN_TAC `x:real^M` THEN + DISCH_TAC THEN UNDISCH_TAC `span w:real^M->bool = s` THEN + REWRITE_TAC[EXTENSION] THEN DISCH_THEN(MP_TAC o SPEC `x:real^M`) THEN + ASM_REWRITE_TAC[] THEN + REMOVE_THEN "*" (MP_TAC o SPEC `x:real^M`) THEN + (CONV_TAC o GEN_SIMPLIFY_CONV TOP_DEPTH_SQCONV (basic_ss []) 4) + [IN_UNIV; SPAN_FINITE; INDEPENDENT_IMP_FINITE; IN_ELIM_THM; + FINITE_IMAGE; FINITE_DIFF; ASSUME `independent(w:real^M->bool)`] THEN + REWRITE_TAC[IMP_CONJ; LEFT_IMP_EXISTS_THM] THEN DISCH_TAC THEN + X_GEN_TAC `u:real^M->real` THEN DISCH_THEN(SUBST1_TAC o SYM) THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [INJECTIVE_ON_LEFT_INVERSE]) THEN + DISCH_THEN(X_CHOOSE_TAC `g:real^N->real^M`) THEN + EXISTS_TAC `(u:real^M->real) o (g:real^N->real^M)` THEN + W(MP_TAC o PART_MATCH (lhs o rand) VSUM_IMAGE o lhand o snd) THEN + ASM_REWRITE_TAC[] THEN + ASM_SIMP_TAC[FINITE_DIFF; INDEPENDENT_IMP_FINITE; LINEAR_VSUM] THEN + DISCH_THEN SUBST1_TAC THEN ASM_REWRITE_TAC[o_DEF] THEN + CONV_TAC SYM_CONV THEN MATCH_MP_TAC VSUM_EQ_SUPERSET THEN + SIMP_TAC[SUBSET_DIFF; FINITE_DIFF; INDEPENDENT_IMP_FINITE; + LINEAR_CMUL; IN_DIFF; TAUT `a /\ ~(a /\ ~b) <=> a /\ b`; + ASSUME `independent(w:real^M->bool)`; + ASSUME `linear(f:real^M->real^N)`] THEN + REWRITE_TAC[VECTOR_MUL_EQ_0] THEN ASM SET_TAC[]; + SUBGOAL_THEN `independent(IMAGE (f:real^M->real^N) (w DIFF v))` + ASSUME_TAC THENL + [MATCH_MP_TAC INDEPENDENT_INJECTIVE_IMAGE_GEN THEN + ASM_SIMP_TAC[LINEAR_INJECTIVE_0_SUBSPACE; SUBSPACE_SPAN] THEN + ASM_MESON_TAC[INDEPENDENT_MONO; SUBSET_DIFF]; + ASM_SIMP_TAC[DIM_SPAN; DIM_EQ_CARD] THEN + W(MP_TAC o PART_MATCH (lhs o rand) CARD_IMAGE_INJ o + lhand o lhand o snd) THEN + ASM_REWRITE_TAC[] THEN + ASM_SIMP_TAC[FINITE_DIFF; CARD_DIFF; INDEPENDENT_IMP_FINITE] THEN + DISCH_THEN SUBST1_TAC THEN MATCH_MP_TAC SUB_ADD THEN + ASM_MESON_TAC[CARD_SUBSET; INDEPENDENT_IMP_FINITE]]]);; + +let DIM_IMAGE_KERNEL = prove + (`!f:real^M->real^N. + linear f + ==> dim(IMAGE f (:real^M)) + dim {x | f x = vec 0} = dimindex(:M)`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`f:real^M->real^N`; `(:real^M)`] DIM_IMAGE_KERNEL_GEN) THEN + ASM_REWRITE_TAC[SUBSPACE_UNIV; IN_UNIV; DIM_UNIV]);; + +let DIM_SUMS_INTER = prove + (`!s t:real^N->bool. + subspace s /\ subspace t + ==> dim {x + y | x IN s /\ y IN t} + dim(s INTER t) = dim(s) + dim(t)`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPEC `s INTER t:real^N->bool` BASIS_EXISTS) THEN + DISCH_THEN(X_CHOOSE_THEN `b:real^N->bool` STRIP_ASSUME_TAC) THEN + MP_TAC(ISPECL [`b:real^N->bool`; `s:real^N->bool`] + MAXIMAL_INDEPENDENT_SUBSET_EXTEND) THEN + ANTS_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + DISCH_THEN(X_CHOOSE_THEN `c:real^N->bool` STRIP_ASSUME_TAC) THEN + MP_TAC(ISPECL [`b:real^N->bool`; `t:real^N->bool`] + MAXIMAL_INDEPENDENT_SUBSET_EXTEND) THEN + ANTS_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN + DISCH_THEN(X_CHOOSE_THEN `d:real^N->bool` STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN `(c:real^N->bool) INTER d = b` ASSUME_TAC THENL + [MATCH_MP_TAC SUBSET_ANTISYM THEN ASM_REWRITE_TAC[SUBSET_INTER] THEN + REWRITE_TAC[SUBSET; IN_INTER] THEN X_GEN_TAC `x:real^N` THEN + STRIP_TAC THEN MP_TAC(ISPEC `c:real^N->bool` independent) THEN + ASM_REWRITE_TAC[dependent; NOT_EXISTS_THM] THEN + DISCH_THEN(MP_TAC o SPEC `x:real^N`) THEN ASM_REWRITE_TAC[] THEN + ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN STRIP_TAC THEN + REWRITE_TAC[] THEN + SUBGOAL_THEN `(x:real^N) IN span b` MP_TAC THENL + [ASM_MESON_TAC[SUBSET; IN_INTER; SPAN_INC]; + MP_TAC(ISPECL [`b:real^N->bool`; `c DELETE (x:real^N)`] SPAN_MONO) THEN + ASM SET_TAC[]]; + ALL_TAC] THEN + SUBGOAL_THEN + `dim (s INTER t:real^N->bool) = CARD(b:real^N->bool) /\ + dim s = CARD c /\ dim t = CARD d /\ + dim {x + y:real^N | x IN s /\ y IN t} = CARD(c UNION d:real^N->bool)` + (REPEAT_TCL CONJUNCTS_THEN SUBST1_TAC) THENL + [ALL_TAC; + ASM_SIMP_TAC[CARD_UNION_GEN; INDEPENDENT_IMP_FINITE] THEN + MATCH_MP_TAC(ARITH_RULE `b:num <= c ==> (c + d) - b + b = c + d`) THEN + ASM_SIMP_TAC[CARD_SUBSET; INDEPENDENT_IMP_FINITE]] THEN + REPEAT CONJ_TAC THEN MATCH_MP_TAC DIM_UNIQUE THENL + [EXISTS_TAC `b:real^N->bool`; + EXISTS_TAC `c:real^N->bool`; + EXISTS_TAC `d:real^N->bool`; + EXISTS_TAC `c UNION d:real^N->bool`] THEN + ASM_SIMP_TAC[HAS_SIZE; INDEPENDENT_IMP_FINITE; FINITE_UNION] THEN + REWRITE_TAC[UNION_SUBSET; GSYM CONJ_ASSOC] THEN + REWRITE_TAC[SUBSET; IN_ELIM_THM; FORALL_IN_GSPEC] THEN REPEAT CONJ_TAC THENL + [X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN + MAP_EVERY EXISTS_TAC [`x:real^N`; `vec 0:real^N`] THEN + ASM_SIMP_TAC[SUBSPACE_0; VECTOR_ADD_RID] THEN ASM SET_TAC[]; + X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN + MAP_EVERY EXISTS_TAC [`vec 0:real^N`; `x:real^N`] THEN + ASM_SIMP_TAC[SUBSPACE_0; VECTOR_ADD_LID] THEN ASM SET_TAC[]; + MAP_EVERY X_GEN_TAC [`x:real^N`; `y:real^N`] THEN STRIP_TAC THEN + MATCH_MP_TAC SPAN_ADD THEN CONJ_TAC THENL + [MP_TAC(ISPECL[`c:real^N->bool`; `c UNION d:real^N->bool`] SPAN_MONO); + MP_TAC(ISPECL[`d:real^N->bool`; `c UNION d:real^N->bool`] SPAN_MONO)] THEN + REWRITE_TAC[SUBSET_UNION] THEN REWRITE_TAC[SUBSET] THEN + DISCH_THEN MATCH_MP_TAC THEN ASM SET_TAC[]; + ALL_TAC] THEN + ASM_SIMP_TAC[INDEPENDENT_EXPLICIT; FINITE_UNION; INDEPENDENT_IMP_FINITE] THEN + X_GEN_TAC `a:real^N->real` THEN + GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) + [SET_RULE `s UNION t = s UNION (t DIFF s)`] THEN + ASM_SIMP_TAC[VSUM_UNION; SET_RULE `DISJOINT c (d DIFF c)`; + INDEPENDENT_IMP_FINITE; FINITE_DIFF; FINITE_UNION] THEN + DISCH_TAC THEN + SUBGOAL_THEN + `(vsum (d DIFF c) (\v:real^N. a v % v)) IN span b` + MP_TAC THENL + [FIRST_ASSUM(MATCH_MP_TAC o GEN_REWRITE_RULE I [SUBSET]) THEN + REWRITE_TAC[IN_INTER] THEN CONJ_TAC THENL + [FIRST_X_ASSUM(SUBST1_TAC o MATCH_MP (VECTOR_ARITH + `a + b = vec 0 ==> b = --a`)) THEN + MATCH_MP_TAC SUBSPACE_NEG THEN ASM_REWRITE_TAC[]; + ALL_TAC] THEN + MATCH_MP_TAC SUBSPACE_VSUM THEN + ASM_SIMP_TAC[FINITE_DIFF; INDEPENDENT_IMP_FINITE] THEN + REPEAT STRIP_TAC THEN MATCH_MP_TAC SUBSPACE_MUL THEN + ASM_REWRITE_TAC[] THEN ASM SET_TAC[]; + ALL_TAC] THEN + ASM_SIMP_TAC[SPAN_FINITE; INDEPENDENT_IMP_FINITE; IN_ELIM_THM] THEN + DISCH_THEN(X_CHOOSE_TAC `e:real^N->real`) THEN + MP_TAC(ISPEC `c:real^N->bool` INDEPENDENT_EXPLICIT) THEN + ASM_REWRITE_TAC[] THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC + (MP_TAC o SPEC `(\x. if x IN b then a x + e x else a x):real^N->real`)) THEN + REWRITE_TAC[] THEN ONCE_REWRITE_TAC[COND_RAND] THEN + ONCE_REWRITE_TAC[COND_RATOR] THEN ASM_SIMP_TAC[VSUM_CASES] THEN + REWRITE_TAC[VECTOR_ADD_RDISTRIB; GSYM DIFF] THEN + ASM_SIMP_TAC[SET_RULE `b SUBSET c ==> {x | x IN c /\ x IN b} = b`] THEN + ASM_SIMP_TAC[VSUM_ADD; INDEPENDENT_IMP_FINITE] THEN + ONCE_REWRITE_TAC[VECTOR_ARITH `(a + b) + c:real^N = (a + c) + b`] THEN + ASM_SIMP_TAC[GSYM VSUM_UNION; FINITE_DIFF; INDEPENDENT_IMP_FINITE; + SET_RULE `DISJOINT b (c DIFF b)`] THEN + ASM_SIMP_TAC[SET_RULE `b SUBSET c ==> b UNION (c DIFF b) = c`] THEN + DISCH_TAC THEN + SUBGOAL_THEN `!v:real^N. v IN (c DIFF b) ==> a v = &0` ASSUME_TAC THENL + [ASM SET_TAC[]; ALL_TAC] THEN + MP_TAC(ISPEC `d:real^N->bool` INDEPENDENT_EXPLICIT) THEN + ASM_REWRITE_TAC[] THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC + (MP_TAC o SPEC `a:real^N->real`)) THEN + SUBGOAL_THEN `d:real^N->bool = b UNION (d DIFF c)` + (fun th -> GEN_REWRITE_TAC (LAND_CONV o LAND_CONV o ONCE_DEPTH_CONV) [th]) + THENL [ASM SET_TAC[]; ALL_TAC] THEN + ANTS_TAC THENL [ALL_TAC; ASM SET_TAC[]] THEN + ASM_SIMP_TAC[VSUM_UNION; FINITE_DIFF; INDEPENDENT_IMP_FINITE; + SET_RULE `c INTER d = b ==> DISJOINT b (d DIFF c)`] THEN + SUBGOAL_THEN `vsum b (\x:real^N. a x % x) = vsum c (\x. a x % x)` + (fun th -> ASM_REWRITE_TAC[th]) THEN + CONV_TAC SYM_CONV THEN MATCH_MP_TAC VSUM_SUPERSET THEN + ASM_SIMP_TAC[VECTOR_MUL_EQ_0] THEN ASM_MESON_TAC[]);; + +let DIM_KERNEL_COMPOSE = prove + (`!f:real^M->real^N g:real^N->real^P. + linear f /\ linear g + ==> dim {x | (g o f) x = vec 0} <= + dim {x | f(x) = vec 0} + + dim {y | g(y) = vec 0}`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPEC `{x | (f:real^M->real^N) x = vec 0}` BASIS_EXISTS_FINITE) THEN + DISCH_THEN(X_CHOOSE_THEN `b:real^M->bool` STRIP_ASSUME_TAC) THEN + SUBGOAL_THEN + `?c. FINITE c /\ + IMAGE f c SUBSET {y | g(y):real^P = vec 0} /\ + independent (IMAGE (f:real^M->real^N) c) /\ + IMAGE f (:real^M) INTER {y | g(y) = vec 0} SUBSET span(IMAGE f c) /\ + (!x y. x IN c /\ y IN c ==> (f x = f y <=> x = y)) /\ + (IMAGE f c) HAS_SIZE dim (IMAGE f (:real^M) INTER {y | g(y) = vec 0})` + STRIP_ASSUME_TAC THENL + [MP_TAC(ISPEC `IMAGE (f:real^M->real^N) (:real^M) INTER + {x | (g:real^N->real^P) x = vec 0}` BASIS_EXISTS_FINITE) THEN + REWRITE_TAC[SUBSET_INTER; GSYM CONJ_ASSOC; EXISTS_FINITE_SUBSET_IMAGE] THEN + DISCH_THEN(X_CHOOSE_THEN `c:real^M->bool` STRIP_ASSUME_TAC) THEN + MP_TAC(ISPECL [`f:real^M->real^N`; `c:real^M->bool`] + IMAGE_INJECTIVE_IMAGE_OF_SUBSET) THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `d:real^M->bool` THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC + (CONJUNCTS_THEN2 SUBST_ALL_TAC ASSUME_TAC)) THEN + ASM_REWRITE_TAC[] THEN ASM_MESON_TAC[FINITE_SUBSET]; + ALL_TAC] THEN + MATCH_MP_TAC LE_TRANS THEN + EXISTS_TAC `dim(span(b UNION c:real^M->bool))` THEN CONJ_TAC THENL + [MATCH_MP_TAC DIM_SUBSET THEN + REWRITE_TAC[SUBSET; FORALL_IN_GSPEC; o_THM] THEN + X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN + SUBGOAL_THEN `(f:real^M->real^N) x IN span(IMAGE f c)` MP_TAC THENL + [ASM SET_TAC[]; ALL_TAC] THEN + ASM_SIMP_TAC[SPAN_LINEAR_IMAGE; IN_IMAGE; LEFT_IMP_EXISTS_THM] THEN + X_GEN_TAC `y:real^M` THEN STRIP_TAC THEN + SUBST1_TAC(VECTOR_ARITH `x:real^M = y + (x - y)`) THEN + MATCH_MP_TAC SPAN_ADD THEN CONJ_TAC THENL + [ASM_MESON_TAC[SUBSET_UNION; SPAN_MONO; SUBSET]; ALL_TAC] THEN + MATCH_MP_TAC(SET_RULE + `!t. x IN t /\ t SUBSET s ==> x IN s`) THEN + EXISTS_TAC `{x | (f:real^M->real^N) x = vec 0}` THEN CONJ_TAC THENL + [REWRITE_TAC[IN_ELIM_THM] THEN ASM_MESON_TAC[LINEAR_SUB; VECTOR_SUB_EQ]; + ASM_MESON_TAC[SUBSET_TRANS; SUBSET_UNION; SPAN_MONO]]; + REWRITE_TAC[DIM_SPAN] THEN MATCH_MP_TAC LE_TRANS THEN + EXISTS_TAC `CARD(b UNION c:real^M->bool)` THEN + ASM_SIMP_TAC[DIM_LE_CARD; FINITE_UNION; INDEPENDENT_IMP_FINITE] THEN + MATCH_MP_TAC LE_TRANS THEN + EXISTS_TAC `CARD(b:real^M->bool) + CARD(c:real^M->bool)` THEN + ASM_SIMP_TAC[CARD_UNION_LE] THEN MATCH_MP_TAC LE_ADD2 THEN CONJ_TAC THENL + [ASM_SIMP_TAC[GSYM DIM_EQ_CARD; DIM_SUBSET]; ALL_TAC] THEN + MATCH_MP_TAC LE_TRANS THEN + EXISTS_TAC `dim(IMAGE (f:real^M->real^N) c)` THEN CONJ_TAC THENL + [ASM_SIMP_TAC[DIM_EQ_CARD] THEN + ASM_MESON_TAC[CARD_IMAGE_INJ; LE_REFL]; + ASM_SIMP_TAC[GSYM DIM_EQ_CARD; DIM_SUBSET]]]);; + +let DIM_ORTHOGONAL_SUM = prove + (`!s t:real^N->bool. + (!x y. x IN s /\ y IN t ==> x dot y = &0) + ==> dim(s UNION t) = dim(s) + dim(t)`, + REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[GSYM DIM_SPAN] THEN + REWRITE_TAC[SPAN_UNION] THEN + SIMP_TAC[GSYM DIM_SUMS_INTER; SUBSPACE_SPAN] THEN + REWRITE_TAC[ARITH_RULE `x = x + y <=> y = 0`] THEN + REWRITE_TAC[DIM_EQ_0; SUBSET; IN_INTER] THEN + SUBGOAL_THEN + `!x:real^N. x IN span s ==> !y:real^N. y IN span t ==> x dot y = &0` + MP_TAC THENL + [MATCH_MP_TAC SPAN_INDUCT THEN CONJ_TAC THENL + [X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN REWRITE_TAC[IN_ELIM_THM] THEN + MATCH_MP_TAC SPAN_INDUCT THEN ASM_SIMP_TAC[IN_ELIM_THM] THEN + SIMP_TAC[subspace; IN_ELIM_THM; DOT_RMUL; DOT_RADD; DOT_RZERO] THEN + REAL_ARITH_TAC; + SIMP_TAC[subspace; IN_ELIM_THM; DOT_LMUL; DOT_LADD; DOT_LZERO] THEN + REAL_ARITH_TAC]; + REWRITE_TAC[IN_SING] THEN MESON_TAC[DOT_EQ_0]]);; + +let DIM_SUBSPACE_ORTHOGONAL_TO_VECTORS = prove + (`!s t:real^N->bool. + subspace s /\ subspace t /\ s SUBSET t + ==> dim {y | y IN t /\ !x. x IN s ==> orthogonal x y} + dim s = dim t`, + REPEAT STRIP_TAC THEN + W(MP_TAC o PART_MATCH (rand o rand) DIM_ORTHOGONAL_SUM o lhand o snd) THEN + ANTS_TAC THENL + [SIMP_TAC[IN_ELIM_THM; orthogonal] THEN MESON_TAC[DOT_SYM]; + DISCH_THEN(SUBST1_TAC o SYM)] THEN + ONCE_REWRITE_TAC[GSYM DIM_SPAN] THEN AP_TERM_TAC THEN + MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL + [MATCH_MP_TAC SPAN_MONO THEN ASM SET_TAC[]; ALL_TAC] THEN + MATCH_MP_TAC SPAN_SUBSET_SUBSPACE THEN REWRITE_TAC[SUBSPACE_SPAN] THEN + REWRITE_TAC[SPAN_UNION; SUBSET; IN_ELIM_THM] THEN + X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN + ONCE_REWRITE_TAC[SWAP_EXISTS_THM] THEN + MP_TAC(ISPECL [`s:real^N->bool`; `x:real^N`] + ORTHOGONAL_SUBSPACE_DECOMP_EXISTS) THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `y:real^N` THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `z:real^N` THEN + STRIP_TAC THEN ASM_REWRITE_TAC[VECTOR_ADD_SYM] THEN + MATCH_MP_TAC SPAN_SUPERSET THEN REWRITE_TAC[IN_ELIM_THM] THEN CONJ_TAC THENL + [FIRST_ASSUM(SUBST1_TAC o MATCH_MP (VECTOR_ARITH + `x:real^N = y + z ==> z = x - y`)) THEN + MATCH_MP_TAC SUBSPACE_SUB THEN + ASM_MESON_TAC[SUBSET; SPAN_EQ_SELF]; + ASM_MESON_TAC[SPAN_SUPERSET; ORTHOGONAL_SYM]]);; + +let DIM_SPECIAL_SUBSPACE = prove + (`!k. dim {x:real^N | + !i. 1 <= i /\ i <= dimindex(:N) /\ i IN k ==> x$i = &0} = + CARD((1..dimindex(:N)) DIFF k)`, + GEN_TAC THEN MATCH_MP_TAC DIM_UNIQUE THEN + EXISTS_TAC `IMAGE (basis:num->real^N) ((1..dimindex(:N)) DIFF k)` THEN + REPEAT CONJ_TAC THENL + [REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; IN_ELIM_THM] THEN + SIMP_TAC[BASIS_COMPONENT; IN_DIFF; IN_NUMSEG] THEN MESON_TAC[]; + REWRITE_TAC[SUBSET; FORALL_IN_GSPEC] THEN X_GEN_TAC `x:real^N` THEN + DISCH_TAC THEN GEN_REWRITE_TAC LAND_CONV [GSYM BASIS_EXPANSION] THEN + MATCH_MP_TAC SPAN_VSUM THEN REWRITE_TAC[FINITE_NUMSEG; IN_NUMSEG] THEN + X_GEN_TAC `j:num` THEN STRIP_TAC THEN + ASM_CASES_TAC `(x:real^N)$j = &0` THEN + ASM_REWRITE_TAC[SPAN_0; VECTOR_MUL_LZERO] THEN + MATCH_MP_TAC SPAN_MUL THEN MATCH_MP_TAC SPAN_SUPERSET THEN + REWRITE_TAC[IN_IMAGE] THEN EXISTS_TAC `j:num` THEN + REWRITE_TAC[IN_NUMSEG; IN_DIFF] THEN ASM_MESON_TAC[]; + MATCH_MP_TAC PAIRWISE_ORTHOGONAL_INDEPENDENT THEN + REWRITE_TAC[pairwise; IMP_CONJ; RIGHT_FORALL_IMP_THM; + SET_RULE `~(a IN IMAGE f s) <=> (!x. x IN s ==> ~(f x = a))`] THEN + SIMP_TAC[FORALL_IN_IMAGE; ORTHOGONAL_BASIS_BASIS; BASIS_INJ_EQ; + IN_DIFF; IN_NUMSEG; BASIS_NONZERO]; + SIMP_TAC[HAS_SIZE; FINITE_IMAGE; FINITE_DIFF; FINITE_NUMSEG] THEN + MATCH_MP_TAC CARD_IMAGE_INJ THEN + SIMP_TAC[FINITE_DIFF; FINITE_NUMSEG; IMP_CONJ; RIGHT_FORALL_IMP_THM; + SET_RULE `~(a IN IMAGE f s) <=> (!x. x IN s ==> ~(f x = a))`] THEN + SIMP_TAC[FORALL_IN_IMAGE; ORTHOGONAL_BASIS_BASIS; BASIS_INJ_EQ; + IN_DIFF; IN_NUMSEG; BASIS_NONZERO]]);; + +(* ------------------------------------------------------------------------- *) +(* More about product spaces. *) +(* ------------------------------------------------------------------------- *) + +let PASTECART_AS_ORTHOGONAL_SUM = prove + (`!x:real^M y:real^N. + pastecart x y = pastecart x (vec 0) + pastecart (vec 0) y`, + REWRITE_TAC[PASTECART_ADD; VECTOR_ADD_LID; VECTOR_ADD_RID]);; + +let PCROSS_AS_ORTHOGONAL_SUM = prove + (`!s:real^M->bool t:real^N->bool. + s PCROSS t = + {u + v | u IN IMAGE (\x. pastecart x (vec 0)) s /\ + v IN IMAGE (\y. pastecart (vec 0) y) t}`, + REPEAT GEN_TAC THEN REWRITE_TAC[PCROSS] THEN + GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) + [PASTECART_AS_ORTHOGONAL_SUM] THEN + SET_TAC[]);; + +let DIM_PCROSS = prove + (`!s:real^M->bool t:real^N->bool. + subspace s /\ subspace t ==> dim(s PCROSS t) = dim s + dim t`, + REPEAT STRIP_TAC THEN REWRITE_TAC[PCROSS_AS_ORTHOGONAL_SUM] THEN + W(MP_TAC o PART_MATCH (lhand o lhand o rand) DIM_SUMS_INTER o + lhand o snd) THEN + ANTS_TAC THENL + [CONJ_TAC THEN MATCH_MP_TAC SUBSPACE_LINEAR_IMAGE; + MATCH_MP_TAC(ARITH_RULE `c = d /\ b = 0 ==> a + b = c ==> a = d`) THEN + CONJ_TAC THENL + [BINOP_TAC THEN MATCH_MP_TAC DIM_INJECTIVE_LINEAR_IMAGE THEN + SIMP_TAC[PASTECART_INJ]; + REWRITE_TAC[DIM_EQ_0; SUBSET; IN_INTER; IN_IMAGE; IN_SING] THEN + REWRITE_TAC[PASTECART_EQ; FSTCART_PASTECART; SNDCART_PASTECART] THEN + MESON_TAC[FSTCART_VEC; SNDCART_VEC]]] THEN + ASM_REWRITE_TAC[linear; GSYM PASTECART_VEC] THEN + REWRITE_TAC[PASTECART_ADD; GSYM PASTECART_CMUL; PASTECART_INJ] THEN + VECTOR_ARITH_TAC);; + +let SPAN_PCROSS_SUBSET = prove + (`!s:real^M->bool t:real^N->bool. + span(s PCROSS t) SUBSET (span s) PCROSS (span t)`, + REPEAT GEN_TAC THEN MATCH_MP_TAC SPAN_SUBSET_SUBSPACE THEN + SIMP_TAC[SUBSPACE_PCROSS; SUBSPACE_SPAN; PCROSS_MONO; SPAN_INC]);; + +let SPAN_PCROSS = prove + (`!s:real^M->bool t:real^N->bool. + ~(s = {}) /\ ~(t = {}) /\ (vec 0 IN s \/ vec 0 IN t) + ==> span(s PCROSS t) = (span s) PCROSS (span t)`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN + REWRITE_TAC[SPAN_PCROSS_SUBSET] THEN + REWRITE_TAC[SUBSET; FORALL_IN_PCROSS] THEN + ONCE_REWRITE_TAC[PASTECART_AS_ORTHOGONAL_SUM] THEN + SUBGOAL_THEN + `(!x:real^M. x IN span s ==> pastecart x (vec 0) IN span(s PCROSS t)) /\ + (!y:real^N. y IN span t ==> pastecart (vec 0) y IN span(s PCROSS t))` + (fun th -> ASM_MESON_TAC[th; SPAN_ADD]) THEN + CONJ_TAC THEN MATCH_MP_TAC SPAN_INDUCT THEN REWRITE_TAC[IN_ELIM_THM] THEN + (CONJ_TAC THENL + [REWRITE_TAC[IN_ELIM_THM] THEN + ASM_SIMP_TAC[SPAN_SUPERSET; PASTECART_IN_PCROSS]; + REWRITE_TAC[subspace; IN_ELIM_THM; PASTECART_VEC; SPAN_0] THEN + CONJ_TAC THEN REPEAT GEN_TAC THENL + [DISCH_THEN(MP_TAC o MATCH_MP SPAN_ADD) THEN + REWRITE_TAC[PASTECART_ADD; VECTOR_ADD_LID]; + DISCH_THEN(MP_TAC o MATCH_MP SPAN_MUL) THEN + SIMP_TAC[GSYM PASTECART_CMUL; VECTOR_MUL_RZERO]]]) + THENL + [X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN + UNDISCH_TAC `~(t:real^N->bool = {})` THEN + REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN + DISCH_THEN(X_CHOOSE_TAC `y:real^N`) THEN + SUBGOAL_THEN + `pastecart x (vec 0) = + pastecart (x:real^M) (y:real^N) - pastecart (vec 0) y` + SUBST1_TAC THENL + [REWRITE_TAC[PASTECART_SUB; PASTECART_INJ] THEN VECTOR_ARITH_TAC; + MATCH_MP_TAC SPAN_SUB THEN + ASM_SIMP_TAC[SPAN_SUPERSET; PASTECART_IN_PCROSS]]; + X_GEN_TAC `y:real^N` THEN DISCH_TAC THEN + UNDISCH_TAC `~(s:real^M->bool = {})` THEN + REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN + DISCH_THEN(X_CHOOSE_TAC `x:real^M`) THEN + SUBGOAL_THEN + `pastecart (vec 0) y = + pastecart (x:real^M) (y:real^N) - pastecart x (vec 0)` + SUBST1_TAC THENL + [REWRITE_TAC[PASTECART_SUB; PASTECART_INJ] THEN VECTOR_ARITH_TAC; + MATCH_MP_TAC SPAN_SUB THEN + ASM_SIMP_TAC[SPAN_SUPERSET; PASTECART_IN_PCROSS]]]);; + +let DIM_PCROSS_STRONG = prove + (`!s:real^M->bool t:real^N->bool. + ~(s = {}) /\ ~(t = {}) /\ (vec 0 IN s \/ vec 0 IN t) + ==> dim(s PCROSS t) = dim s + dim t`, + ONCE_REWRITE_TAC[GSYM DIM_SPAN] THEN + SIMP_TAC[SPAN_PCROSS; DIM_PCROSS; SUBSPACE_SPAN]);; + +let SPAN_SUMS = prove + (`!s t:real^N->bool. + ~(s = {}) /\ ~(t = {}) /\ vec 0 IN (s UNION t) + ==> span {x + y | x IN s /\ y IN t} = + {x + y | x IN span s /\ y IN span t}`, + REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM SPAN_UNION] THEN + MATCH_MP_TAC SUBSET_ANTISYM THEN + CONJ_TAC THEN MATCH_MP_TAC SPAN_SUBSET_SUBSPACE THEN + REWRITE_TAC[SUBSPACE_SPAN; SUBSET; FORALL_IN_GSPEC] THEN + SIMP_TAC[SPAN_ADD; IN_UNION; SPAN_SUPERSET] THEN + X_GEN_TAC `x:real^N` THEN STRIP_TAC THEN + FIRST_X_ASSUM(DISJ_CASES_TAC o GEN_REWRITE_RULE I [IN_UNION]) THENL + [UNDISCH_TAC `~(t:real^N->bool = {})` THEN + REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN + DISCH_THEN(X_CHOOSE_TAC `y:real^N`) THEN + SUBST1_TAC(VECTOR_ARITH `x:real^N = (x + y) - (vec 0 + y)`) THEN + MATCH_MP_TAC SPAN_SUB THEN CONJ_TAC THEN MATCH_MP_TAC SPAN_SUPERSET THEN + ASM SET_TAC[]; + MATCH_MP_TAC SPAN_SUPERSET THEN REWRITE_TAC[IN_ELIM_THM] THEN + ASM_MESON_TAC[VECTOR_ADD_RID]; + MATCH_MP_TAC SPAN_SUPERSET THEN REWRITE_TAC[IN_ELIM_THM] THEN + ASM_MESON_TAC[VECTOR_ADD_LID]; + UNDISCH_TAC `~(s:real^N->bool = {})` THEN + REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN + DISCH_THEN(X_CHOOSE_TAC `y:real^N`) THEN + SUBST1_TAC(VECTOR_ARITH `x:real^N = (y + x) - (y + vec 0)`) THEN + MATCH_MP_TAC SPAN_SUB THEN CONJ_TAC THEN MATCH_MP_TAC SPAN_SUPERSET THEN + ASM SET_TAC[]]);; + +(* ------------------------------------------------------------------------- *) +(* More about rank from the rank/nullspace formula. *) +(* ------------------------------------------------------------------------- *) + +let RANK_NULLSPACE = prove + (`!A:real^M^N. rank A + dim {x | A ** x = vec 0} = dimindex(:M)`, + GEN_TAC THEN REWRITE_TAC[RANK_DIM_IM] THEN + MATCH_MP_TAC DIM_IMAGE_KERNEL THEN + REWRITE_TAC[MATRIX_VECTOR_MUL_LINEAR]);; + +let RANK_SYLVESTER = prove + (`!A:real^N^M B:real^P^N. + rank(A) + rank(B) <= rank(A ** B) + dimindex(:N)`, + REPEAT GEN_TAC THEN MATCH_MP_TAC(ARITH_RULE + `!ia ib iab p:num. + ra + ia = n /\ + rb + ib = p /\ + rab + iab = p /\ + iab <= ia + ib + ==> ra + rb <= rab + n`) THEN + MAP_EVERY EXISTS_TAC + [`dim {x | (A:real^N^M) ** x = vec 0}`; + `dim {x | (B:real^P^N) ** x = vec 0}`; + `dim {x | ((A:real^N^M) ** (B:real^P^N)) ** x = vec 0}`; + `dimindex(:P)`] THEN + REWRITE_TAC[RANK_NULLSPACE] THEN + REWRITE_TAC[GSYM MATRIX_VECTOR_MUL_ASSOC] THEN + ONCE_REWRITE_TAC[ADD_SYM] THEN + MATCH_MP_TAC(REWRITE_RULE[o_DEF] DIM_KERNEL_COMPOSE) THEN + CONJ_TAC THEN GEN_REWRITE_TAC RAND_CONV [GSYM ETA_AX] THEN + REWRITE_TAC[MATRIX_VECTOR_MUL_LINEAR]);; + +let RANK_GRAM = prove + (`!A:real^M^N. rank(transp A ** A) = rank A`, + GEN_TAC THEN MATCH_MP_TAC(ARITH_RULE + `!n n' k. r + n:num = k /\ r' + n' = k /\ n = n' ==> r = r'`) THEN + MAP_EVERY EXISTS_TAC + [`dim {x | (transp A ** (A:real^M^N)) ** x = vec 0}`; + `dim {x | (A:real^M^N) ** x = vec 0}`; + `dimindex(:M)`] THEN + REWRITE_TAC[RANK_NULLSPACE] THEN AP_TERM_TAC THEN + MATCH_MP_TAC SUBSET_ANTISYM THEN + SIMP_TAC[SUBSET; IN_ELIM_THM; GSYM MATRIX_VECTOR_MUL_ASSOC; + MATRIX_VECTOR_MUL_RZERO] THEN + X_GEN_TAC `x:real^M` THEN + DISCH_THEN(MP_TAC o AP_TERM `(dot) (x:real^M)`) THEN + ONCE_REWRITE_TAC[GSYM DOT_LMUL_MATRIX] THEN + REWRITE_TAC[VECTOR_MATRIX_MUL_TRANSP; TRANSP_TRANSP; DOT_RZERO] THEN + REWRITE_TAC[DOT_EQ_0]);; + +let RANK_TRIANGLE = prove + (`!A B:real^M^N. rank(A + B) <= rank(A) + rank(B)`, + REPEAT GEN_TAC THEN REWRITE_TAC[RANK_DIM_IM] THEN + MP_TAC(ISPECL [`IMAGE (\x. (A:real^M^N) ** x) (:real^M)`; + `IMAGE (\x. (B:real^M^N) ** x) (:real^M)`] + DIM_SUMS_INTER) THEN + ASM_SIMP_TAC[SUBSPACE_LINEAR_IMAGE; SUBSPACE_UNIV; + MATRIX_VECTOR_MUL_LINEAR] THEN + DISCH_THEN(SUBST1_TAC o SYM) THEN + MATCH_MP_TAC(ARITH_RULE `x:num <= y ==> x <= y + z`) THEN + MATCH_MP_TAC DIM_SUBSET THEN + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; IN_UNIV; + MATRIX_VECTOR_MUL_ADD_RDISTRIB] THEN + REWRITE_TAC[IN_ELIM_THM; IN_IMAGE; IN_UNIV] THEN MESON_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* Infinity norm. *) +(* ------------------------------------------------------------------------- *) + +let infnorm = define + `infnorm (x:real^N) = sup { abs(x$i) | 1 <= i /\ i <= dimindex(:N) }`;; + +let NUMSEG_DIMINDEX_NONEMPTY = prove + (`?i. i IN 1..dimindex(:N)`, + REWRITE_TAC[MEMBER_NOT_EMPTY; NUMSEG_EMPTY; NOT_LT; DIMINDEX_GE_1]);; + +let INFNORM_SET_IMAGE = prove + (`{abs(x$i) | 1 <= i /\ i <= dimindex(:N)} = + IMAGE (\i. abs(x$i)) (1..dimindex(:N))`, + REWRITE_TAC[numseg] THEN SET_TAC[]);; + +let INFNORM_SET_LEMMA = prove + (`FINITE {abs((x:real^N)$i) | 1 <= i /\ i <= dimindex(:N)} /\ + ~({abs(x$i) | 1 <= i /\ i <= dimindex(:N)} = {})`, + SIMP_TAC[INFNORM_SET_IMAGE; FINITE_NUMSEG; FINITE_IMAGE; IMAGE_EQ_EMPTY] THEN + REWRITE_TAC[NUMSEG_EMPTY; NOT_LT; DIMINDEX_GE_1]);; + +let INFNORM_POS_LE = prove + (`!x. &0 <= infnorm x`, + REWRITE_TAC[infnorm] THEN + SIMP_TAC[REAL_LE_SUP_FINITE; INFNORM_SET_LEMMA] THEN + REWRITE_TAC[INFNORM_SET_IMAGE; NUMSEG_DIMINDEX_NONEMPTY; + EXISTS_IN_IMAGE; REAL_ABS_POS]);; + +let INFNORM_TRIANGLE = prove + (`!x y. infnorm(x + y) <= infnorm x + infnorm y`, + REWRITE_TAC[infnorm] THEN + SIMP_TAC[REAL_SUP_LE_FINITE; INFNORM_SET_LEMMA] THEN + ONCE_REWRITE_TAC[GSYM REAL_LE_SUB_RADD] THEN + SIMP_TAC[REAL_LE_SUP_FINITE; INFNORM_SET_LEMMA] THEN + ONCE_REWRITE_TAC[REAL_ARITH `x - y <= z <=> x - z <= y`] THEN + SIMP_TAC[REAL_LE_SUP_FINITE; INFNORM_SET_LEMMA] THEN + REWRITE_TAC[INFNORM_SET_IMAGE; FORALL_IN_IMAGE; EXISTS_IN_IMAGE] THEN + SIMP_TAC[VECTOR_ADD_COMPONENT; GSYM IN_NUMSEG] THEN + MESON_TAC[NUMSEG_DIMINDEX_NONEMPTY; + REAL_ARITH `abs(x + y) - abs(x) <= abs(y)`]);; + +let INFNORM_EQ_0 = prove + (`!x. infnorm x = &0 <=> x = vec 0`, + REWRITE_TAC[GSYM REAL_LE_ANTISYM; INFNORM_POS_LE] THEN + SIMP_TAC[infnorm; REAL_SUP_LE_FINITE; INFNORM_SET_LEMMA] THEN + SIMP_TAC[FORALL_IN_IMAGE; INFNORM_SET_IMAGE; CART_EQ; VEC_COMPONENT] THEN + REWRITE_TAC[IN_NUMSEG; REAL_ARITH `abs(x) <= &0 <=> x = &0`]);; + +let INFNORM_0 = prove + (`infnorm(vec 0) = &0`, + REWRITE_TAC[INFNORM_EQ_0]);; + +let INFNORM_NEG = prove + (`!x. infnorm(--x) = infnorm x`, + GEN_TAC THEN REWRITE_TAC[infnorm] THEN AP_TERM_TAC THEN + REWRITE_TAC[EXTENSION; IN_ELIM_THM] THEN + MESON_TAC[REAL_ABS_NEG; VECTOR_NEG_COMPONENT]);; + +let INFNORM_SUB = prove + (`!x y. infnorm(x - y) = infnorm(y - x)`, + MESON_TAC[INFNORM_NEG; VECTOR_NEG_SUB]);; + +let REAL_ABS_SUB_INFNORM = prove + (`abs(infnorm x - infnorm y) <= infnorm(x - y)`, + MATCH_MP_TAC(REAL_ARITH + `nx <= n + ny /\ ny <= n + nx ==> abs(nx - ny) <= n`) THEN + MESON_TAC[INFNORM_SUB; VECTOR_SUB_ADD2; INFNORM_TRIANGLE; VECTOR_ADD_SYM]);; + +let REAL_ABS_INFNORM = prove + (`!x. abs(infnorm x) = infnorm x`, + REWRITE_TAC[real_abs; INFNORM_POS_LE]);; + +let COMPONENT_LE_INFNORM = prove + (`!x:real^N i. 1 <= i /\ i <= dimindex (:N) ==> abs(x$i) <= infnorm x`, + REPEAT GEN_TAC THEN REWRITE_TAC[infnorm] THEN + MP_TAC(SPEC `{ abs((x:real^N)$i) | 1 <= i /\ i <= dimindex(:N) }` + SUP_FINITE) THEN + REWRITE_TAC[INFNORM_SET_LEMMA] THEN + SIMP_TAC[INFNORM_SET_IMAGE; FORALL_IN_IMAGE; IN_NUMSEG]);; + +let INFNORM_MUL_LEMMA = prove + (`!a x. infnorm(a % x) <= abs a * infnorm x`, + REPEAT STRIP_TAC THEN GEN_REWRITE_TAC LAND_CONV [infnorm] THEN + SIMP_TAC[REAL_SUP_LE_FINITE; INFNORM_SET_LEMMA] THEN + REWRITE_TAC[FORALL_IN_IMAGE; INFNORM_SET_IMAGE] THEN + SIMP_TAC[REAL_ABS_MUL; VECTOR_MUL_COMPONENT; IN_NUMSEG] THEN + SIMP_TAC[COMPONENT_LE_INFNORM; REAL_LE_LMUL; REAL_ABS_POS]);; + +let INFNORM_MUL = prove + (`!a x:real^N. infnorm(a % x) = abs a * infnorm x`, + REPEAT GEN_TAC THEN ASM_CASES_TAC `a = &0` THEN + ASM_REWRITE_TAC[VECTOR_MUL_LZERO; INFNORM_0; REAL_ABS_0; REAL_MUL_LZERO] THEN + REWRITE_TAC[GSYM REAL_LE_ANTISYM; INFNORM_MUL_LEMMA] THEN + GEN_REWRITE_TAC (LAND_CONV o funpow 2 RAND_CONV) [GSYM VECTOR_MUL_LID] THEN + FIRST_ASSUM(SUBST1_TAC o SYM o MATCH_MP REAL_MUL_LINV) THEN + REWRITE_TAC[GSYM VECTOR_MUL_ASSOC] THEN + MATCH_MP_TAC REAL_LE_TRANS THEN + EXISTS_TAC `abs(a) * abs(inv a) * infnorm(a % x:real^N)` THEN + ASM_SIMP_TAC[INFNORM_MUL_LEMMA; REAL_LE_LMUL; REAL_ABS_POS] THEN + ASM_SIMP_TAC[REAL_MUL_ASSOC; GSYM REAL_ABS_MUL; REAL_MUL_RINV] THEN + REAL_ARITH_TAC);; + +let INFNORM_POS_LT = prove + (`!x. &0 < infnorm x <=> ~(x = vec 0)`, + MESON_TAC[REAL_LT_LE; INFNORM_POS_LE; INFNORM_EQ_0]);; + +(* ------------------------------------------------------------------------- *) +(* Prove that it differs only up to a bound from Euclidean norm. *) +(* ------------------------------------------------------------------------- *) + +let INFNORM_LE_NORM = prove + (`!x. infnorm(x) <= norm(x)`, + SIMP_TAC[infnorm; REAL_SUP_LE_FINITE; INFNORM_SET_LEMMA] THEN + REWRITE_TAC[IN_ELIM_THM] THEN MESON_TAC[COMPONENT_LE_NORM]);; + +let NORM_LE_INFNORM = prove + (`!x:real^N. norm(x) <= sqrt(&(dimindex(:N))) * infnorm(x)`, + GEN_TAC THEN GEN_REWRITE_TAC (RAND_CONV o LAND_CONV o funpow 2 RAND_CONV) + [GSYM CARD_NUMSEG_1] THEN + REWRITE_TAC[vector_norm] THEN MATCH_MP_TAC REAL_LE_LSQRT THEN + SIMP_TAC[DOT_POS_LE; SQRT_POS_LE; REAL_POS; REAL_LE_MUL; INFNORM_POS_LE; + SQRT_POW_2; REAL_POW_MUL] THEN + REWRITE_TAC[dot] THEN MATCH_MP_TAC SUM_BOUND THEN + REWRITE_TAC[FINITE_NUMSEG; IN_NUMSEG] THEN REPEAT STRIP_TAC THEN + REWRITE_TAC[GSYM REAL_POW_2] THEN ONCE_REWRITE_TAC[GSYM REAL_POW2_ABS] THEN + MATCH_MP_TAC REAL_POW_LE2 THEN REWRITE_TAC[REAL_ABS_POS] THEN + MATCH_MP_TAC(REAL_ARITH `x <= y ==> x <= abs(y)`) THEN + SIMP_TAC[infnorm; REAL_LE_SUP_FINITE; INFNORM_SET_LEMMA] THEN + REWRITE_TAC[IN_ELIM_THM] THEN ASM_MESON_TAC[REAL_LE_REFL]);; + +(* ------------------------------------------------------------------------- *) +(* Equality in Cauchy-Schwarz and triangle inequalities. *) +(* ------------------------------------------------------------------------- *) + +let NORM_CAUCHY_SCHWARZ_EQ = prove + (`!x:real^N y. x dot y = norm(x) * norm(y) <=> norm(x) % y = norm(y) % x`, + REPEAT STRIP_TAC THEN + MAP_EVERY ASM_CASES_TAC [`x:real^N = vec 0`; `y:real^N = vec 0`] THEN + ASM_REWRITE_TAC[NORM_0; REAL_MUL_LZERO; REAL_MUL_RZERO; + DOT_LZERO; DOT_RZERO; VECTOR_MUL_LZERO; VECTOR_MUL_RZERO] THEN + MP_TAC(ISPEC `norm(y:real^N) % x - norm(x:real^N) % y` DOT_EQ_0) THEN + REWRITE_TAC[DOT_RSUB; DOT_LSUB; DOT_LMUL; DOT_RMUL; GSYM NORM_POW_2; + REAL_POW_2; VECTOR_SUB_EQ] THEN + REWRITE_TAC[DOT_SYM; REAL_ARITH + `y * (y * x * x - x * d) - x * (y * d - x * y * y) = + &2 * x * y * (x * y - d)`] THEN + ASM_SIMP_TAC[REAL_ENTIRE; NORM_EQ_0; REAL_SUB_0; REAL_OF_NUM_EQ; ARITH] THEN + REWRITE_TAC[EQ_SYM_EQ]);; + +let NORM_CAUCHY_SCHWARZ_ABS_EQ = prove + (`!x:real^N y. abs(x dot y) = norm(x) * norm(y) <=> + norm(x) % y = norm(y) % x \/ norm(x) % y = --norm(y) % x`, + SIMP_TAC[REAL_ARITH `&0 <= a ==> (abs x = a <=> x = a \/ --x = a)`; + REAL_LE_MUL; NORM_POS_LE; GSYM DOT_RNEG] THEN + REPEAT GEN_TAC THEN + GEN_REWRITE_TAC (LAND_CONV o funpow 3 RAND_CONV) [GSYM NORM_NEG] THEN + REWRITE_TAC[NORM_CAUCHY_SCHWARZ_EQ] THEN REWRITE_TAC[NORM_NEG] THEN + BINOP_TAC THEN VECTOR_ARITH_TAC);; + +let NORM_TRIANGLE_EQ = prove + (`!x y:real^N. norm(x + y) = norm(x) + norm(y) <=> norm(x) % y = norm(y) % x`, + REPEAT GEN_TAC THEN REWRITE_TAC[GSYM NORM_CAUCHY_SCHWARZ_EQ] THEN + MATCH_MP_TAC EQ_TRANS THEN + EXISTS_TAC `norm(x + y:real^N) pow 2 = (norm(x) + norm(y)) pow 2` THEN + CONJ_TAC THENL + [REWRITE_TAC[REAL_RING `x pow 2 = y pow 2 <=> x = y \/ x + y = &0`] THEN + MAP_EVERY (MP_TAC o C ISPEC NORM_POS_LE) + [`x + y:real^N`; `x:real^N`; `y:real^N`] THEN + REAL_ARITH_TAC; + REWRITE_TAC[NORM_POW_2; DOT_LADD; DOT_RADD; REAL_ARITH + `(x + y) pow 2 = x pow 2 + y pow 2 + &2 * x * y`] THEN + REWRITE_TAC[DOT_SYM] THEN REAL_ARITH_TAC]);; + +let DIST_TRIANGLE_EQ = prove + (`!x y z. dist(x,z) = dist(x,y) + dist(y,z) <=> + norm (x - y) % (y - z) = norm (y - z) % (x - y)`, + REWRITE_TAC[GSYM NORM_TRIANGLE_EQ] THEN NORM_ARITH_TAC);; + +let NORM_CROSS_MULTIPLY = prove + (`!a b x y:real^N. + a % x = b % y /\ &0 < a /\ &0 < b + ==> norm y % x = norm x % y`, + REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 MP_TAC STRIP_ASSUME_TAC) THEN + ASM_CASES_TAC `y:real^N = vec 0` THEN + ASM_SIMP_TAC[VECTOR_MUL_EQ_0; REAL_LT_IMP_NZ; VECTOR_MUL_RZERO] THEN + DISCH_THEN(MP_TAC o AP_TERM `\x:real^N. inv(a) % x`) THEN + ASM_SIMP_TAC[VECTOR_MUL_ASSOC; REAL_MUL_LINV; REAL_LT_IMP_NZ; VECTOR_MUL_LID; + NORM_MUL; REAL_ABS_MUL; REAL_ABS_INV] THEN + ASM_SIMP_TAC[real_abs; REAL_LT_IMP_LE; REAL_MUL_AC]);; + +(* ------------------------------------------------------------------------- *) +(* Collinearity. *) +(* ------------------------------------------------------------------------- *) + +let collinear = new_definition + `collinear s <=> ?u. !x y. x IN s /\ y IN s ==> ?c. x - y = c % u`;; + +let COLLINEAR_SUBSET = prove + (`!s t. collinear t /\ s SUBSET t ==> collinear s`, + REWRITE_TAC[collinear] THEN SET_TAC[]);; + +let COLLINEAR_EMPTY = prove + (`collinear {}`, + REWRITE_TAC[collinear; NOT_IN_EMPTY]);; + +let COLLINEAR_SING = prove + (`!x. collinear {x}`, + SIMP_TAC[collinear; IN_SING; VECTOR_SUB_REFL] THEN + MESON_TAC[VECTOR_MUL_LZERO]);; + +let COLLINEAR_2 = prove + (`!x y:real^N. collinear {x,y}`, + REPEAT GEN_TAC THEN REWRITE_TAC[collinear; IN_INSERT; NOT_IN_EMPTY] THEN + EXISTS_TAC `x - y:real^N` THEN REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THENL + [EXISTS_TAC `&0`; EXISTS_TAC `&1`; EXISTS_TAC `-- &1`; EXISTS_TAC `&0`] THEN + VECTOR_ARITH_TAC);; + +let COLLINEAR_SMALL = prove + (`!s. FINITE s /\ CARD s <= 2 ==> collinear s`, + REWRITE_TAC[ARITH_RULE `s <= 2 <=> s = 0 \/ s = 1 \/ s = 2`] THEN + REWRITE_TAC[LEFT_OR_DISTRIB; GSYM HAS_SIZE] THEN + CONV_TAC(ONCE_DEPTH_CONV HAS_SIZE_CONV) THEN + REPEAT STRIP_TAC THEN + ASM_REWRITE_TAC[COLLINEAR_EMPTY; COLLINEAR_SING; COLLINEAR_2]);; + +let COLLINEAR_3 = prove + (`!x y z. collinear {x,y,z} <=> collinear {vec 0,x - y,z - y}`, + REPEAT GEN_TAC THEN + REWRITE_TAC[collinear; FORALL_IN_INSERT; IMP_CONJ; RIGHT_FORALL_IMP_THM; + NOT_IN_EMPTY] THEN + AP_TERM_TAC THEN ABS_TAC THEN + MESON_TAC[VECTOR_ARITH `x - y = (x - y) - vec 0`; + VECTOR_ARITH `y - x = vec 0 - (x - y)`; + VECTOR_ARITH `x - z:real^N = (x - y) - (z - y)`]);; + +let COLLINEAR_LEMMA = prove + (`!x y:real^N. collinear {vec 0,x,y} <=> + x = vec 0 \/ y = vec 0 \/ ?c. y = c % x`, + REPEAT GEN_TAC THEN + MAP_EVERY ASM_CASES_TAC [`x:real^N = vec 0`; `y:real^N = vec 0`] THEN + TRY(ASM_REWRITE_TAC[INSERT_AC; COLLINEAR_SING; COLLINEAR_2] THEN NO_TAC) THEN + ASM_REWRITE_TAC[collinear] THEN EQ_TAC THENL + [DISCH_THEN(X_CHOOSE_THEN `u:real^N` + (fun th -> MP_TAC(SPECL [`x:real^N`; `vec 0:real^N`] th) THEN + MP_TAC(SPECL [`y:real^N`; `vec 0:real^N`] th))) THEN + REWRITE_TAC[IN_INSERT; VECTOR_SUB_RZERO] THEN + DISCH_THEN(X_CHOOSE_THEN `e:real` SUBST_ALL_TAC) THEN + DISCH_THEN(X_CHOOSE_THEN `d:real` SUBST_ALL_TAC) THEN + EXISTS_TAC `e / d` THEN REWRITE_TAC[VECTOR_MUL_ASSOC] THEN + RULE_ASSUM_TAC(REWRITE_RULE[VECTOR_MUL_EQ_0; DE_MORGAN_THM]) THEN + ASM_SIMP_TAC[REAL_DIV_RMUL]; + STRIP_TAC THEN EXISTS_TAC `x:real^N` THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[IN_INSERT; NOT_IN_EMPTY] THEN REPEAT STRIP_TAC THEN + ASM_REWRITE_TAC[] THENL + [EXISTS_TAC `&0`; EXISTS_TAC `-- &1`; EXISTS_TAC `--c`; + EXISTS_TAC `&1`; EXISTS_TAC `&0`; EXISTS_TAC `&1 - c`; + EXISTS_TAC `c:real`; EXISTS_TAC `c - &1`; EXISTS_TAC `&0`] THEN + VECTOR_ARITH_TAC]);; + +let COLLINEAR_LEMMA_ALT = prove + (`!x y. collinear {vec 0,x,y} <=> x = vec 0 \/ ?c. y = c % x`, + REWRITE_TAC[COLLINEAR_LEMMA] THEN MESON_TAC[VECTOR_MUL_LZERO]);; + +let NORM_CAUCHY_SCHWARZ_EQUAL = prove + (`!x y:real^N. abs(x dot y) = norm(x) * norm(y) <=> collinear {vec 0,x,y}`, + REPEAT GEN_TAC THEN REWRITE_TAC[NORM_CAUCHY_SCHWARZ_ABS_EQ] THEN + MAP_EVERY ASM_CASES_TAC [`x:real^N = vec 0`; `y:real^N = vec 0`] THEN + TRY(ASM_REWRITE_TAC[INSERT_AC; COLLINEAR_SING; COLLINEAR_2; NORM_0; + VECTOR_MUL_LZERO; VECTOR_MUL_RZERO] THEN NO_TAC) THEN + ASM_REWRITE_TAC[COLLINEAR_LEMMA] THEN EQ_TAC THENL + [STRIP_TAC THENL + [FIRST_X_ASSUM(MP_TAC o AP_TERM + `(%) (inv(norm(x:real^N))):real^N->real^N`); + FIRST_X_ASSUM(MP_TAC o AP_TERM + `(%) (--inv(norm(x:real^N))):real^N->real^N`)] THEN + ASM_REWRITE_TAC[VECTOR_MUL_ASSOC; REAL_MUL_LNEG] THEN + ASM_SIMP_TAC[REAL_MUL_LINV; NORM_EQ_0; VECTOR_MUL_LNEG; VECTOR_MUL_LID; + VECTOR_ARITH `--x = --y <=> x:real^N = y`] THEN + MESON_TAC[]; + STRIP_TAC THEN ASM_REWRITE_TAC[NORM_MUL; VECTOR_MUL_ASSOC] THEN + MATCH_MP_TAC(MESON[] + `t = a \/ t = b ==> t % x = a % x \/ t % x = b % x`) THEN + REWRITE_TAC[GSYM REAL_MUL_LNEG; + REAL_ARITH `x * c = d * x <=> x * (c - d) = &0`] THEN + ASM_REWRITE_TAC[REAL_ENTIRE; NORM_EQ_0] THEN REAL_ARITH_TAC]);; + +let DOT_CAUCHY_SCHWARZ_EQUAL = prove + (`!x y:real^N. + (x dot y) pow 2 = (x dot x) * (y dot y) <=> + collinear {vec 0,x,y}`, + REWRITE_TAC[GSYM NORM_CAUCHY_SCHWARZ_EQUAL] THEN + REPEAT GEN_TAC THEN MATCH_MP_TAC(REAL_ARITH + `&0 <= y /\ (u:real = v <=> x = abs y) ==> (u = v <=> x = y)`) THEN + SIMP_TAC[NORM_POS_LE; REAL_LE_MUL] THEN + REWRITE_TAC[REAL_EQ_SQUARE_ABS] THEN REWRITE_TAC[REAL_POW_MUL; NORM_POW_2]);; + +let COLLINEAR_3_EXPAND = prove + (`!a b c:real^N. collinear{a,b,c} <=> a = c \/ ?u. b = u % a + (&1 - u) % c`, + REPEAT GEN_TAC THEN + ONCE_REWRITE_TAC[SET_RULE `{a,b,c} = {a,c,b}`] THEN + ONCE_REWRITE_TAC[COLLINEAR_3] THEN + REWRITE_TAC[COLLINEAR_LEMMA; VECTOR_SUB_EQ] THEN + ASM_CASES_TAC `a:real^N = c` THEN ASM_REWRITE_TAC[] THEN + ASM_CASES_TAC `b:real^N = c` THEN + ASM_REWRITE_TAC[VECTOR_ARITH `u % c + (&1 - u) % c = c`] THENL + [EXISTS_TAC `&0` THEN VECTOR_ARITH_TAC; + AP_TERM_TAC THEN ABS_TAC THEN VECTOR_ARITH_TAC]);; + +let COLLINEAR_TRIPLES = prove + (`!s a b:real^N. + ~(a = b) + ==> (collinear(a INSERT b INSERT s) <=> + !x. x IN s ==> collinear{a,b,x})`, + REPEAT STRIP_TAC THEN EQ_TAC THENL + [REPEAT STRIP_TAC THEN FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP + (REWRITE_RULE[IMP_CONJ] COLLINEAR_SUBSET)) THEN + ASM SET_TAC[]; + ONCE_REWRITE_TAC[SET_RULE `{a,b,x} = {a,x,b}`] THEN + ASM_REWRITE_TAC[COLLINEAR_3_EXPAND] THEN DISCH_TAC THEN + SUBGOAL_THEN + `!x:real^N. x IN (a INSERT b INSERT s) ==> ?u. x = u % a + (&1 - u) % b` + MP_TAC THENL + [ASM_REWRITE_TAC[FORALL_IN_INSERT] THEN CONJ_TAC THENL + [EXISTS_TAC `&1` THEN VECTOR_ARITH_TAC; + EXISTS_TAC `&0` THEN VECTOR_ARITH_TAC]; + POP_ASSUM_LIST(K ALL_TAC) THEN DISCH_TAC THEN + REWRITE_TAC[collinear] THEN EXISTS_TAC `b - a:real^N` THEN + MAP_EVERY X_GEN_TAC [`x:real^N`; `y:real^N`] THEN STRIP_TAC THEN + FIRST_X_ASSUM(fun th -> MP_TAC(SPEC `x:real^N` th) THEN MP_TAC(SPEC + `y:real^N` th)) THEN + ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN + ASM_REWRITE_TAC[VECTOR_ARITH + `(u % a + (&1 - u) % b) - (v % a + (&1 - v) % b):real^N = + (v - u) % (b - a)`] THEN + MESON_TAC[]]]);; + +let COLLINEAR_4_3 = prove + (`!a b c d:real^N. + ~(a = b) + ==> (collinear {a,b,c,d} <=> collinear{a,b,c} /\ collinear{a,b,d})`, + REPEAT STRIP_TAC THEN + MP_TAC(ISPECL [`{c:real^N,d}`; `a:real^N`; `b:real^N`] + COLLINEAR_TRIPLES) THEN + ASM_REWRITE_TAC[] THEN DISCH_THEN SUBST1_TAC THEN + REWRITE_TAC[FORALL_IN_INSERT; NOT_IN_EMPTY]);; + +let COLLINEAR_3_TRANS = prove + (`!a b c d:real^N. + collinear{a,b,c} /\ collinear{b,c,d} /\ ~(b = c) ==> collinear{a,b,d}`, + REPEAT STRIP_TAC THEN MATCH_MP_TAC COLLINEAR_SUBSET THEN + EXISTS_TAC `{b:real^N,c,a,d}` THEN ASM_SIMP_TAC[COLLINEAR_4_3] THEN + CONJ_TAC THENL [ALL_TAC; SET_TAC[]] THEN + REPEAT(POP_ASSUM MP_TAC) THEN SIMP_TAC[INSERT_AC]);; + +let ORTHOGONAL_TO_ORTHOGONAL_2D = prove + (`!x y z:real^2. + ~(x = vec 0) /\ orthogonal x y /\ orthogonal x z + ==> collinear {vec 0,y,z}`, + REWRITE_TAC[orthogonal; GSYM DOT_CAUCHY_SCHWARZ_EQUAL; GSYM DOT_EQ_0] THEN + REWRITE_TAC[DOT_2] THEN CONV_TAC REAL_RING);; + +let COLLINEAR_3_2D = prove + (`!x y z:real^2. collinear{x,y,z} <=> + (z$1 - x$1) * (y$2 - x$2) = (y$1 - x$1) * (z$2 - x$2)`, + ONCE_REWRITE_TAC[COLLINEAR_3] THEN + REWRITE_TAC[GSYM DOT_CAUCHY_SCHWARZ_EQUAL] THEN + REWRITE_TAC[DOT_2; VECTOR_SUB_COMPONENT] THEN CONV_TAC REAL_RING);; + +let COLLINEAR_3_DOT_MULTIPLES = prove + (`!a b c:real^N. + collinear {a,b,c} <=> + ((b - a) dot (b - a)) % (c - a) = ((c - a) dot (b - a)) % (b - a)`, + REWRITE_TAC[VECTOR_SUB_RZERO] THEN + REPEAT GEN_TAC THEN ASM_CASES_TAC `b:real^N = a` THENL + [ASM_REWRITE_TAC[COLLINEAR_2; INSERT_AC; DOT_RZERO; VECTOR_MUL_LZERO; + VECTOR_SUB_REFL]; + ONCE_REWRITE_TAC[COLLINEAR_3] THEN + POP_ASSUM MP_TAC THEN ONCE_REWRITE_TAC[GSYM VECTOR_SUB_EQ] THEN + REWRITE_TAC[GSYM DOT_CAUCHY_SCHWARZ_EQUAL; GSYM DOT_EQ_0] THEN + REWRITE_TAC[GSYM DOT_EQ_0; DOT_RSUB; DOT_LSUB; DOT_RMUL; DOT_LMUL] THEN + REWRITE_TAC[DOT_SYM] THEN CONV_TAC REAL_RING]);; + +(* ------------------------------------------------------------------------- *) +(* Between-ness. *) +(* ------------------------------------------------------------------------- *) + +let between = new_definition + `between x (a,b) <=> dist(a,b) = dist(a,x) + dist(x,b)`;; + +let BETWEEN_REFL = prove + (`!a b. between a (a,b) /\ between b (a,b) /\ between a (a,a)`, + REWRITE_TAC[between] THEN NORM_ARITH_TAC);; + +let BETWEEN_REFL_EQ = prove + (`!a x. between x (a,a) <=> x = a`, + REWRITE_TAC[between] THEN NORM_ARITH_TAC);; + +let BETWEEN_SYM = prove + (`!a b x. between x (a,b) <=> between x (b,a)`, + REWRITE_TAC[between] THEN NORM_ARITH_TAC);; + +let BETWEEN_ANTISYM = prove + (`!a b c. between a (b,c) /\ between b (a,c) ==> a = b`, + REWRITE_TAC[between; DIST_SYM] THEN NORM_ARITH_TAC);; + +let BETWEEN_TRANS = prove + (`!a b c d. between a (b,c) /\ between d (a,c) ==> between d (b,c)`, + REWRITE_TAC[between; DIST_SYM] THEN NORM_ARITH_TAC);; + +let BETWEEN_TRANS_2 = prove + (`!a b c d. between a (b,c) /\ between d (a,b) ==> between a (c,d)`, + REWRITE_TAC[between; DIST_SYM] THEN NORM_ARITH_TAC);; + +let BETWEEN_NORM = prove + (`!a b x:real^N. + between x (a,b) <=> norm(x - a) % (b - x) = norm(b - x) % (x - a)`, + REPEAT GEN_TAC THEN REWRITE_TAC[between; DIST_TRIANGLE_EQ] THEN + REWRITE_TAC[NORM_SUB] THEN VECTOR_ARITH_TAC);; + +let BETWEEN_DOT = prove + (`!a b x:real^N. + between x (a,b) <=> (x - a) dot (b - x) = norm(x - a) * norm(b - x)`, + REWRITE_TAC[BETWEEN_NORM; NORM_CAUCHY_SCHWARZ_EQ]);; + +let BETWEEN_EXISTS_EXTENSION = prove + (`!a b x:real^N. + between b (a,x) /\ ~(b = a) ==> ?d. &0 <= d /\ x = b + d % (b - a)`, + REPEAT GEN_TAC THEN REWRITE_TAC[BETWEEN_NORM] THEN STRIP_TAC THEN + EXISTS_TAC `norm(x - b:real^N) / norm(b - a)` THEN + SIMP_TAC[REAL_LE_DIV; NORM_POS_LE] THEN FIRST_X_ASSUM + (MP_TAC o AP_TERM `(%) (inv(norm(b - a:real^N))):real^N->real^N`) THEN + ASM_SIMP_TAC[VECTOR_MUL_ASSOC; REAL_MUL_LINV; NORM_EQ_0; VECTOR_SUB_EQ] THEN + VECTOR_ARITH_TAC);; + +let BETWEEN_IMP_COLLINEAR = prove + (`!a b x:real^N. between x (a,b) ==> collinear {a,x,b}`, + REPEAT GEN_TAC THEN MAP_EVERY + (fun t -> ASM_CASES_TAC t THEN + TRY(ASM_REWRITE_TAC[INSERT_AC; COLLINEAR_2] THEN NO_TAC)) + [`x:real^N = a`; `x:real^N = b`; `a:real^N = b`] THEN + ONCE_REWRITE_TAC[COLLINEAR_3; BETWEEN_NORM] THEN + DISCH_TAC THEN REWRITE_TAC[COLLINEAR_LEMMA] THEN + REPEAT DISJ2_TAC THEN EXISTS_TAC `--(norm(b - x:real^N) / norm(x - a))` THEN + MATCH_MP_TAC VECTOR_MUL_LCANCEL_IMP THEN EXISTS_TAC `norm(x - a:real^N)` THEN + ASM_REWRITE_TAC[VECTOR_MUL_ASSOC; REAL_MUL_RNEG] THEN + ASM_SIMP_TAC[REAL_DIV_LMUL; NORM_EQ_0; VECTOR_SUB_EQ] THEN + VECTOR_ARITH_TAC);; + +let COLLINEAR_BETWEEN_CASES = prove + (`!a b c:real^N. + collinear {a,b,c} <=> + between a (b,c) \/ between b (c,a) \/ between c (a,b)`, + REPEAT STRIP_TAC THEN EQ_TAC THENL + [REWRITE_TAC[COLLINEAR_3_EXPAND] THEN + ASM_CASES_TAC `c:real^N = a` THEN ASM_REWRITE_TAC[BETWEEN_REFL] THEN + STRIP_TAC THEN ASM_REWRITE_TAC[between; dist] THEN + REWRITE_TAC[VECTOR_ARITH `(u % a + (&1 - u) % c) - c = --u % (c - a)`; + VECTOR_ARITH `(u % a + (&1 - u) % c) - a = (&1 - u) % (c - a)`; + VECTOR_ARITH `c - (u % a + (&1 - u) % c) = u % (c - a)`; + VECTOR_ARITH `a - (u % a + (&1 - u) % c) = (u - &1) % (c - a)`] THEN + REWRITE_TAC[NORM_MUL] THEN + SUBST1_TAC(NORM_ARITH `norm(a - c:real^N) = norm(c - a)`) THEN + REWRITE_TAC[REAL_ARITH `a * c + c = (a + &1) * c`; GSYM REAL_ADD_RDISTRIB; + REAL_ARITH `c + a * c = (a + &1) * c`] THEN + ASM_REWRITE_TAC[REAL_EQ_MUL_RCANCEL; + REAL_RING `n = x * n <=> n = &0 \/ x = &1`] THEN + ASM_REWRITE_TAC[NORM_EQ_0; VECTOR_SUB_EQ] THEN REAL_ARITH_TAC; + DISCH_THEN(REPEAT_TCL DISJ_CASES_THEN (MP_TAC o MATCH_MP + BETWEEN_IMP_COLLINEAR)) THEN + REWRITE_TAC[INSERT_AC]]);; + +let COLLINEAR_DIST_BETWEEN = prove + (`!a b x. collinear {x,a,b} /\ + dist(x,a) <= dist(a,b) /\ dist(x,b) <= dist(a,b) + ==> between x (a,b)`, + SIMP_TAC[COLLINEAR_BETWEEN_CASES; between; DIST_SYM] THEN NORM_ARITH_TAC);; + +let BETWEEN_COLLINEAR_DIST_EQ = prove + (`!a b x:real^N. + between x (a,b) <=> + collinear {a, x, b} /\ + dist(x,a) <= dist(a,b) /\ dist(x,b) <= dist(a,b)`, + REPEAT GEN_TAC THEN EQ_TAC THENL + [SIMP_TAC[BETWEEN_IMP_COLLINEAR] THEN REWRITE_TAC[between] THEN + NORM_ARITH_TAC; + MESON_TAC[COLLINEAR_DIST_BETWEEN; INSERT_AC]]);; + +let COLLINEAR_1 = prove + (`!s:real^1->bool. collinear s`, + GEN_TAC THEN MATCH_MP_TAC COLLINEAR_SUBSET THEN + EXISTS_TAC `(vec 0:real^1) INSERT (vec 1) INSERT s` THEN + CONJ_TAC THENL [ALL_TAC; SET_TAC[]] THEN + W(MP_TAC o PART_MATCH (lhs o rand) COLLINEAR_TRIPLES o snd) THEN + REWRITE_TAC[VEC_EQ; ARITH_EQ] THEN DISCH_THEN SUBST1_TAC THEN + REWRITE_TAC[COLLINEAR_BETWEEN_CASES] THEN + REWRITE_TAC[between; DIST_REAL; GSYM drop; DROP_VEC; REAL_ABS_NUM] THEN + REAL_ARITH_TAC);; + +(* ------------------------------------------------------------------------- *) +(* Midpoint between two points. *) +(* ------------------------------------------------------------------------- *) + +let midpoint = new_definition + `midpoint(a,b) = inv(&2) % (a + b)`;; + +let MIDPOINT_REFL = prove + (`!x. midpoint(x,x) = x`, + REWRITE_TAC[midpoint] THEN VECTOR_ARITH_TAC);; + +let MIDPOINT_SYM = prove + (`!a b. midpoint(a,b) = midpoint(b,a)`, + REWRITE_TAC[midpoint; VECTOR_ADD_SYM]);; + +let DIST_MIDPOINT = prove + (`!a b. dist(a,midpoint(a,b)) = dist(a,b) / &2 /\ + dist(b,midpoint(a,b)) = dist(a,b) / &2 /\ + dist(midpoint(a,b),a) = dist(a,b) / &2 /\ + dist(midpoint(a,b),b) = dist(a,b) / &2`, + REWRITE_TAC[midpoint] THEN NORM_ARITH_TAC);; + +let MIDPOINT_EQ_ENDPOINT = prove + (`!a b. (midpoint(a,b) = a <=> a = b) /\ + (midpoint(a,b) = b <=> a = b) /\ + (a = midpoint(a,b) <=> a = b) /\ + (b = midpoint(a,b) <=> a = b)`, + REWRITE_TAC[midpoint] THEN NORM_ARITH_TAC);; + +let BETWEEN_MIDPOINT = prove + (`!a b. between (midpoint(a,b)) (a,b) /\ between (midpoint(a,b)) (b,a)`, + REWRITE_TAC[between; midpoint] THEN NORM_ARITH_TAC);; + +let MIDPOINT_LINEAR_IMAGE = prove + (`!f a b. linear f ==> midpoint(f a,f b) = f(midpoint(a,b))`, + SIMP_TAC[midpoint; LINEAR_ADD; LINEAR_CMUL]);; + +let COLLINEAR_MIDPOINT = prove + (`!a b. collinear{a,midpoint(a,b),b}`, + REPEAT GEN_TAC THEN REWRITE_TAC[COLLINEAR_3_EXPAND; midpoint] THEN + DISJ2_TAC THEN EXISTS_TAC `&1 / &2` THEN VECTOR_ARITH_TAC);; + +let MIDPOINT_COLLINEAR = prove + (`!a b c:real^N. + ~(a = c) + ==> (b = midpoint(a,c) <=> collinear{a,b,c} /\ dist(a,b) = dist(b,c))`, + REPEAT STRIP_TAC THEN + MATCH_MP_TAC(TAUT `(a ==> b) /\ (b ==> (a <=> c)) ==> (a <=> b /\ c)`) THEN + SIMP_TAC[COLLINEAR_MIDPOINT] THEN ASM_REWRITE_TAC[COLLINEAR_3_EXPAND] THEN + STRIP_TAC THEN ASM_REWRITE_TAC[midpoint; dist] THEN + REWRITE_TAC + [VECTOR_ARITH `a - (u % a + (&1 - u) % c) = (&1 - u) % (a - c)`; + VECTOR_ARITH `(u % a + (&1 - u) % c) - c = u % (a - c)`; + VECTOR_ARITH `u % a + (&1 - u) % c = inv (&2) % (a + c) <=> + (u - &1 / &2) % (a - c) = vec 0`] THEN + ASM_SIMP_TAC[NORM_MUL; REAL_EQ_MUL_RCANCEL; NORM_EQ_0; VECTOR_SUB_EQ; + VECTOR_MUL_EQ_0] THEN + REAL_ARITH_TAC);; + +let MIDPOINT_BETWEEN = prove + (`!a b c:real^N. + b = midpoint (a,c) <=> between b (a,c) /\ dist (a,b) = dist (b,c)`, + REPEAT GEN_TAC THEN ASM_CASES_TAC `a:real^N = c` THENL + [ASM_SIMP_TAC[BETWEEN_REFL_EQ; MIDPOINT_REFL; DIST_SYM]; ALL_TAC] THEN + EQ_TAC THEN SIMP_TAC[BETWEEN_MIDPOINT; DIST_MIDPOINT] THEN + ASM_MESON_TAC[MIDPOINT_COLLINEAR; BETWEEN_IMP_COLLINEAR]);; + +(* ------------------------------------------------------------------------- *) +(* General "one way" lemma for properties preserved by injective map. *) +(* ------------------------------------------------------------------------- *) + +let WLOG_LINEAR_INJECTIVE_IMAGE_2 = prove + (`!P Q. (!f s. P s /\ linear f ==> Q(IMAGE f s)) /\ + (!g t. Q t /\ linear g ==> P(IMAGE g t)) + ==> !f:real^M->real^N. + linear f /\ (!x y. f x = f y ==> x = y) + ==> !s. Q(IMAGE f s) <=> P s`, + REPEAT STRIP_TAC THEN EQ_TAC THEN ASM_SIMP_TAC[] THEN DISCH_TAC THEN + MP_TAC(ISPEC `f:real^M->real^N` LINEAR_INJECTIVE_LEFT_INVERSE) THEN + ASM_REWRITE_TAC[FUN_EQ_THM; o_THM; I_THM] THEN + DISCH_THEN(X_CHOOSE_THEN `g:real^N->real^M` STRIP_ASSUME_TAC) THEN + FIRST_X_ASSUM(MP_TAC o SPECL + [`g:real^N->real^M`; `IMAGE (f:real^M->real^N) s`]) THEN + ASM_REWRITE_TAC[GSYM IMAGE_o; o_DEF; IMAGE_ID]);; + +let WLOG_LINEAR_INJECTIVE_IMAGE_2_ALT = prove + (`!P Q f s. (!h u. P u /\ linear h ==> Q(IMAGE h u)) /\ + (!g t. Q t /\ linear g ==> P(IMAGE g t)) /\ + linear f /\ (!x y. f x = f y ==> x = y) + ==> (Q(IMAGE f s) <=> P s)`, + REPEAT GEN_TAC THEN STRIP_TAC THEN + MATCH_MP_TAC(REWRITE_RULE[RIGHT_IMP_FORALL_THM; IMP_IMP] + WLOG_LINEAR_INJECTIVE_IMAGE_2) THEN + ASM_REWRITE_TAC[]);; + +let WLOG_LINEAR_INJECTIVE_IMAGE = prove + (`!P. (!f s. P s /\ linear f ==> P(IMAGE f s)) + ==> !f:real^N->real^N. linear f /\ (!x y. f x = f y ==> x = y) + ==> !s. P(IMAGE f s) <=> P s`, + GEN_TAC THEN DISCH_TAC THEN MATCH_MP_TAC WLOG_LINEAR_INJECTIVE_IMAGE_2 THEN + ASM_REWRITE_TAC[]);; + +let WLOG_LINEAR_INJECTIVE_IMAGE_ALT = prove + (`!P f s. (!g t. P t /\ linear g ==> P(IMAGE g t)) /\ + linear f /\ (!x y. f x = f y ==> x = y) + ==> (P(IMAGE f s) <=> P s)`, + REPEAT GEN_TAC THEN STRIP_TAC THEN + MATCH_MP_TAC(REWRITE_RULE[RIGHT_IMP_FORALL_THM; IMP_IMP] + WLOG_LINEAR_INJECTIVE_IMAGE) THEN + ASM_REWRITE_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* Inference rule to apply it conveniently. *) +(* *) +(* |- !f s. P s /\ linear f ==> P(IMAGE f s) [or /\ commuted] *) +(* --------------------------------------------------------------- *) +(* |- !f s. linear f /\ (!x y. f x = f y ==> x = y) *) +(* ==> (Q(IMAGE f s) <=> P s) *) +(* ------------------------------------------------------------------------- *) + +let LINEAR_INVARIANT_RULE th = + let [f;s] = fst(strip_forall(concl th)) in + let (rm,rn) = dest_fun_ty (type_of f) in + let m = last(snd(dest_type rm)) and n = last(snd(dest_type rn)) in + let th' = INST_TYPE [m,n; n,m] th in + let th0 = CONJ th th' in + let th1 = try MATCH_MP WLOG_LINEAR_INJECTIVE_IMAGE_2 th0 + with Failure _ -> + MATCH_MP WLOG_LINEAR_INJECTIVE_IMAGE_2 + (GEN_REWRITE_RULE (BINOP_CONV o ONCE_DEPTH_CONV) [CONJ_SYM] th0) in + GEN_REWRITE_RULE BINDER_CONV [RIGHT_IMP_FORALL_THM] th1;; + +(* ------------------------------------------------------------------------- *) +(* Immediate application. *) +(* ------------------------------------------------------------------------- *) + +let SUBSPACE_LINEAR_IMAGE_EQ = prove + (`!f s. linear f /\ (!x y. f x = f y ==> x = y) + ==> (subspace (IMAGE f s) <=> subspace s)`, + MATCH_ACCEPT_TAC(LINEAR_INVARIANT_RULE SUBSPACE_LINEAR_IMAGE));; + +(* ------------------------------------------------------------------------- *) +(* Storage of useful "invariance under linear map / translation" theorems. *) +(* ------------------------------------------------------------------------- *) + +let invariant_under_linear = ref([]:thm list);; + +let invariant_under_translation = ref([]:thm list);; + +let scaling_theorems = ref([]:thm list);; + +(* ------------------------------------------------------------------------- *) +(* Scaling theorems and derivation from linear invariance. *) +(* ------------------------------------------------------------------------- *) + +let LINEAR_SCALING = prove + (`!c. linear(\x:real^N. c % x)`, + REWRITE_TAC[linear] THEN VECTOR_ARITH_TAC);; + +let INJECTIVE_SCALING = prove + (`!c. (!x y:real^N. c % x = c % y ==> x = y) <=> ~(c = &0)`, + GEN_TAC THEN REWRITE_TAC[VECTOR_MUL_LCANCEL] THEN + ASM_CASES_TAC `c:real = &0` THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN(MP_TAC o SPECL [`vec 0:real^N`; `vec 1:real^N`]) THEN + REWRITE_TAC[VEC_EQ; ARITH]);; + +let SURJECTIVE_SCALING = prove + (`!c. (!y:real^N. ?x. c % x = y) <=> ~(c = &0)`, + ASM_SIMP_TAC[LINEAR_SURJECTIVE_IFF_INJECTIVE; LINEAR_SCALING] THEN + REWRITE_TAC[INJECTIVE_SCALING]);; + +let SCALING_INVARIANT = + let pths = (CONJUNCTS o UNDISCH o prove) + (`&0 < c + ==> linear(\x:real^N. c % x) /\ + (!x y:real^N. c % x = c % y ==> x = y) /\ + (!y:real^N. ?x. c % x = y)`, + SIMP_TAC[REAL_LT_IMP_NZ; LINEAR_SCALING; + INJECTIVE_SCALING; SURJECTIVE_SCALING]) + and sc_tm = `\x:real^N. c % x` + and sa_tm = `&0:real < c` + and c_tm = `c:real` in + fun th -> + let ith = BETA_RULE(ISPEC sc_tm th) in + let avs,bod = strip_forall(concl ith) in + let cjs = conjuncts(lhand bod) in + let cths = map (fun t -> find(fun th -> aconv (concl th) t) pths) cjs in + let oth = MP (SPECL avs ith) (end_itlist CONJ cths) in + GEN c_tm (DISCH sa_tm (GENL avs oth));; + +let scaling_theorems = ref([]:thm list);; + +(* ------------------------------------------------------------------------- *) +(* Augmentation of the lists. The "add_linear_invariants" also updates *) +(* the scaling theorems automatically, so only a few of those will need *) +(* to be added explicitly. *) +(* ------------------------------------------------------------------------- *) + +let add_scaling_theorems thl = + (scaling_theorems := (!scaling_theorems) @ thl);; + +let add_linear_invariants thl = + ignore(mapfilter (fun th -> add_scaling_theorems[SCALING_INVARIANT th]) thl); + (invariant_under_linear := (!invariant_under_linear) @ thl);; + +let add_translation_invariants thl = + (invariant_under_translation := (!invariant_under_translation) @ thl);; + +(* ------------------------------------------------------------------------- *) +(* Start with some basic set equivalences. *) +(* We give them all an injectivity hypothesis even if it's not necessary. *) +(* For just the intersection theorem we add surjectivity (more manageable *) +(* than assuming that the set isn't empty). *) +(* ------------------------------------------------------------------------- *) + +let th_sets = prove + (`!f. (!x y. f x = f y ==> x = y) + ==> (if p then f x else f y) = f(if p then x else y) /\ + (if p then IMAGE f s else IMAGE f t) = + IMAGE f (if p then s else t) /\ + (f x) INSERT (IMAGE f s) = IMAGE f (x INSERT s) /\ + (IMAGE f s) DELETE (f x) = IMAGE f (s DELETE x) /\ + (IMAGE f s) INTER (IMAGE f t) = IMAGE f (s INTER t) /\ + (IMAGE f s) UNION (IMAGE f t) = IMAGE f (s UNION t) /\ + UNIONS(IMAGE (IMAGE f) u) = IMAGE f (UNIONS u) /\ + (IMAGE f s) DIFF (IMAGE f t) = IMAGE f (s DIFF t) /\ + (IMAGE f s (f x) <=> s x) /\ + ((f x) IN (IMAGE f s) <=> x IN s) /\ + ((f o xs) (n:num) = f(xs n)) /\ + ((f o pt) (tt:real^1) = f(pt tt)) /\ + (DISJOINT (IMAGE f s) (IMAGE f t) <=> DISJOINT s t) /\ + ((IMAGE f s) SUBSET (IMAGE f t) <=> s SUBSET t) /\ + ((IMAGE f s) PSUBSET (IMAGE f t) <=> s PSUBSET t) /\ + (IMAGE f s = IMAGE f t <=> s = t) /\ + ((IMAGE f s) HAS_SIZE n <=> s HAS_SIZE n) /\ + (FINITE(IMAGE f s) <=> FINITE s) /\ + (INFINITE(IMAGE f s) <=> INFINITE s)`, + REPEAT GEN_TAC THEN DISCH_TAC THEN REWRITE_TAC[IMAGE_UNIONS] THEN + REWRITE_TAC[o_THM; MESON[IN] `IMAGE f s y <=> y IN IMAGE f s`] THEN + REPLICATE_TAC 2 (CONJ_TAC THENL [MESON_TAC[]; ALL_TAC]) THEN + REWRITE_TAC[INFINITE; TAUT `(~p <=> ~q) <=> (p <=> q)`] THEN + REPLICATE_TAC 11 (CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC]) THEN + REWRITE_TAC[HAS_SIZE] THEN + ASM_MESON_TAC[FINITE_IMAGE_INJ_EQ; CARD_IMAGE_INJ]) in +let f = `f:real^M->real^N` +and imf = `IMAGE (f:real^M->real^N)` +and a = `a:real^N` +and ima = `IMAGE (\x:real^N. a + x)` +and vth = VECTOR_ARITH `!x y. a + x:real^N = a + y ==> x = y` in +let th1 = UNDISCH(ISPEC f th_sets) +and th1' = UNDISCH + (GEN_REWRITE_RULE LAND_CONV [INJECTIVE_IMAGE] (ISPEC imf th_sets)) +and th2 = MATCH_MP th_sets vth +and th2' = MATCH_MP + (BETA_RULE(GEN_REWRITE_RULE LAND_CONV [INJECTIVE_IMAGE] (ISPEC ima th_sets))) + vth in +let fn a th = GENL (a::subtract (frees(concl th)) [a]) th in +add_linear_invariants(map (fn f o DISCH_ALL) (CONJUNCTS th1 @ CONJUNCTS th1')), +add_translation_invariants(map (fn a) (CONJUNCTS th2 @ CONJUNCTS th2'));; + +let th_set = prove + (`!f:A->B s. (!x y. f x = f y ==> x = y) /\ (!y. ?x. f x = y) + ==> INTERS (IMAGE (IMAGE f) s) = IMAGE f (INTERS s)`, + REWRITE_TAC[INTERS_IMAGE] THEN SET_TAC[]) in +let th_vec = prove + (`!a:real^N s. + INTERS (IMAGE (IMAGE (\x. a + x)) s) = IMAGE (\x. a + x) (INTERS s)`, + REPEAT GEN_TAC THEN MATCH_MP_TAC th_set THEN + REWRITE_TAC[VECTOR_ARITH `a + x:real^N = a + y <=> x = y`] THEN + REWRITE_TAC[VECTOR_ARITH `a + x:real^N = y <=> x = y - a`; EXISTS_REFL]) in +add_linear_invariants [th_set],add_translation_invariants[th_vec];; + +(* ------------------------------------------------------------------------- *) +(* Now add arithmetical equivalences. *) +(* ------------------------------------------------------------------------- *) + +let PRESERVES_NORM_PRESERVES_DOT = prove + (`!f:real^M->real^N x y. + linear f /\ (!x. norm(f x) = norm x) + ==> (f x) dot (f y) = x dot y`, + REWRITE_TAC[NORM_EQ] THEN REPEAT STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o SPEC `x + y:real^M`) THEN + FIRST_ASSUM(fun th -> REWRITE_TAC[MATCH_MP LINEAR_ADD th]) THEN + ASM_REWRITE_TAC[DOT_LADD; DOT_RADD] THEN + REWRITE_TAC[DOT_SYM] THEN REAL_ARITH_TAC);; + +let PRESERVES_NORM_INJECTIVE = prove + (`!f:real^M->real^N. + linear f /\ (!x. norm(f x) = norm x) + ==> !x y. f x = f y ==> x = y`, + SIMP_TAC[LINEAR_INJECTIVE_0; GSYM NORM_EQ_0]);; + +let ORTHOGONAL_LINEAR_IMAGE_EQ = prove + (`!f:real^M->real^N x y. + linear f /\ (!x. norm(f x) = norm x) + ==> (orthogonal (f x) (f y) <=> orthogonal x y)`, + SIMP_TAC[orthogonal; PRESERVES_NORM_PRESERVES_DOT]);; + +add_linear_invariants + [GSYM LINEAR_ADD; + GSYM LINEAR_CMUL; + GSYM LINEAR_SUB; + GSYM LINEAR_NEG; + MIDPOINT_LINEAR_IMAGE; + MESON[] `!f:real^M->real^N x. + (!x. norm(f x) = norm x) ==> norm(f x) = norm x`; + PRESERVES_NORM_PRESERVES_DOT; + MESON[dist; LINEAR_SUB] + `!f:real^M->real^N x y. + linear f /\ (!x. norm(f x) = norm x) + ==> dist(f x,f y) = dist(x,y)`; + MESON[] `!f:real^M->real^N x y. + (!x y. f x = f y ==> x = y) ==> (f x = f y <=> x = y)`; + SUBSPACE_LINEAR_IMAGE_EQ; + ORTHOGONAL_LINEAR_IMAGE_EQ; + SPAN_LINEAR_IMAGE; + DEPENDENT_LINEAR_IMAGE_EQ; + INDEPENDENT_LINEAR_IMAGE_EQ; + DIM_INJECTIVE_LINEAR_IMAGE];; + +add_translation_invariants + [VECTOR_ARITH `!a x y. a + x:real^N = a + y <=> x = y`; + NORM_ARITH `!a x y. dist(a + x,a + y) = dist(x,y)`; + VECTOR_ARITH `!a x y. &1 / &2 % ((a + x) + (a + y)) = a + &1 / &2 % (x + y)`; + VECTOR_ARITH `!a x y. inv(&2) % ((a + x) + (a + y)) = a + inv(&2) % (x + y)`; + VECTOR_ARITH `!a x y. (a + x) - (a + y):real^N = x - y`; + (EQT_ELIM o (REWRITE_CONV[midpoint] THENC(EQT_INTRO o NORM_ARITH))) + `!a x y. midpoint(a + x,a + y) = a + midpoint(x,y)`; + (EQT_ELIM o (REWRITE_CONV[between] THENC(EQT_INTRO o NORM_ARITH))) + `!a x y z. between (a + x) (a + y,a + z) <=> between x (y,z)`];; + +let th = prove + (`!a s b c:real^N. (a + b) + c IN IMAGE (\x. a + x) s <=> (b + c) IN s`, + REWRITE_TAC[IN_IMAGE; VECTOR_ARITH + `(a + b) + c:real^N = a + x <=> x = b + c`] THEN + MESON_TAC[]) in +add_translation_invariants [th];; + +(* ------------------------------------------------------------------------- *) +(* A few for lists. *) +(* ------------------------------------------------------------------------- *) + +let MEM_TRANSLATION = prove + (`!a:real^N x l. MEM (a + x) (MAP (\x. a + x) l) <=> MEM x l`, + REWRITE_TAC[MEM_MAP; VECTOR_ARITH `a + x:real^N = a + y <=> x = y`] THEN + MESON_TAC[]);; + +add_translation_invariants [MEM_TRANSLATION];; + +let MEM_LINEAR_IMAGE = prove + (`!f:real^M->real^N x l. + linear f /\ (!x y. f x = f y ==> x = y) + ==> (MEM (f x) (MAP f l) <=> MEM x l)`, + REWRITE_TAC[MEM_MAP] THEN MESON_TAC[]);; + +add_linear_invariants [MEM_LINEAR_IMAGE];; + +let LENGTH_TRANSLATION = prove + (`!a:real^N l. LENGTH(MAP (\x. a + x) l) = LENGTH l`, + REWRITE_TAC[LENGTH_MAP]) in +add_translation_invariants [LENGTH_TRANSLATION];; + +let LENGTH_LINEAR_IMAGE = prove + (`!f:real^M->real^N l. linear f ==> LENGTH(MAP f l) = LENGTH l`, + REWRITE_TAC[LENGTH_MAP]) in +add_linear_invariants [LENGTH_LINEAR_IMAGE];; + +let CONS_TRANSLATION = prove + (`!a:real^N h t. + CONS ((\x. a + x) h) (MAP (\x. a + x) t) = MAP (\x. a + x) (CONS h t)`, + REWRITE_TAC[MAP]) in +add_translation_invariants [CONS_TRANSLATION];; + +let CONS_LINEAR_IMAGE = prove + (`!f:real^M->real^N h t. + linear f ==> CONS (f h) (MAP f t) = MAP f (CONS h t)`, + REWRITE_TAC[MAP]) in +add_linear_invariants [CONS_LINEAR_IMAGE];; + +let APPEND_TRANSLATION = prove + (`!a:real^N l1 l2. + APPEND (MAP (\x. a + x) l1) (MAP (\x. a + x) l2) = + MAP (\x. a + x) (APPEND l1 l2)`, + REWRITE_TAC[MAP_APPEND]) in +add_translation_invariants [APPEND_TRANSLATION];; + +let APPEND_LINEAR_IMAGE = prove + (`!f:real^M->real^N l1 l2. + linear f ==> APPEND (MAP f l1) (MAP f l2) = MAP f (APPEND l1 l2)`, + REWRITE_TAC[MAP_APPEND]) in +add_linear_invariants [APPEND_LINEAR_IMAGE];; + +let REVERSE_TRANSLATION = prove + (`!a:real^N l. REVERSE(MAP (\x. a + x) l) = MAP (\x. a + x) (REVERSE l)`, + REWRITE_TAC[MAP_REVERSE]) in +add_translation_invariants [REVERSE_TRANSLATION];; + +let REVERSE_LINEAR_IMAGE = prove + (`!f:real^M->real^N l. linear f ==> REVERSE(MAP f l) = MAP f (REVERSE l)`, + REWRITE_TAC[MAP_REVERSE]) in +add_linear_invariants [REVERSE_LINEAR_IMAGE];; + +(* ------------------------------------------------------------------------- *) +(* A few scaling theorems that don't come from invariance theorems. Most are *) +(* artificially weak with 0 < c hypotheses, so we don't bind them to names. *) +(* ------------------------------------------------------------------------- *) + +let DOT_SCALING = prove + (`!c. &0 < c ==> !x y. (c % x) dot (c % y) = c pow 2 * (x dot y)`, + REWRITE_TAC[DOT_LMUL; DOT_RMUL] THEN REAL_ARITH_TAC) in +add_scaling_theorems [DOT_SCALING];; + +let DIST_SCALING = prove + (`!c. &0 < c ==> !x y. dist(c % x,c % y) = c * dist(x,y)`, + SIMP_TAC[DIST_MUL; REAL_ARITH `&0 < c ==> abs c = c`]) in +add_scaling_theorems [DIST_SCALING];; + +let ORTHOGONAL_SCALING = prove + (`!c. &0 < c ==> !x y. orthogonal (c % x) (c % y) <=> orthogonal x y`, + REWRITE_TAC[orthogonal; DOT_LMUL; DOT_RMUL] THEN CONV_TAC REAL_FIELD) in +add_scaling_theorems [ORTHOGONAL_SCALING];; + +let NORM_SCALING = prove + (`!c. &0 < c ==> !x. norm(c % x) = c * norm x`, + SIMP_TAC[NORM_MUL; REAL_ARITH `&0 < c ==> abs c = c`]) in +add_scaling_theorems [NORM_SCALING];; + +add_scaling_theorems + [REAL_ARITH `!c. &0 < c ==> !a b. a * c * b = c * a * b`; + REAL_ARITH `!c. &0 < c ==> !a b. c * a + c * b = c * (a + b)`; + REAL_ARITH `!c. &0 < c ==> !a b. c * a - c * b = c * (a - b)`; + REAL_FIELD `!c. &0 < c ==> !a b. c * a = c * b <=> a = b`; + MESON[REAL_LT_LMUL_EQ] `!c. &0 < c ==> !a b. c * a < c * b <=> a < b`; + MESON[REAL_LE_LMUL_EQ] `!c. &0 < c ==> !a b. c * a <= c * b <=> a <= b`; + MESON[REAL_LT_LMUL_EQ; real_gt] + `!c. &0 < c ==> !a b. c * a > c * b <=> a > b`; + MESON[REAL_LE_LMUL_EQ; real_ge] + `!c. &0 < c ==> !a b. c * a >= c * b <=> a >= b`; + MESON[REAL_POW_MUL] + `!c. &0 < c ==> !a n. (c * a) pow n = c pow n * a pow n`; + REAL_ARITH `!c. &0 < c ==> !a b n. a * c pow n * b = c pow n * a * b`; + REAL_ARITH + `!c. &0 < c ==> !a b n. c pow n * a + c pow n * b = c pow n * (a + b)`; + REAL_ARITH + `!c. &0 < c ==> !a b n. c pow n * a - c pow n * b = c pow n * (a - b)`; + MESON[REAL_POW_LT; REAL_EQ_LCANCEL_IMP; REAL_LT_IMP_NZ] + `!c. &0 < c ==> !a b n. c pow n * a = c pow n * b <=> a = b`; + MESON[REAL_LT_LMUL_EQ; REAL_POW_LT] + `!c. &0 < c ==> !a b n. c pow n * a < c pow n * b <=> a < b`; + MESON[REAL_LE_LMUL_EQ; REAL_POW_LT] + `!c. &0 < c ==> !a b n. c pow n * a <= c pow n * b <=> a <= b`; + MESON[REAL_LT_LMUL_EQ; real_gt; REAL_POW_LT] + `!c. &0 < c ==> !a b n. c pow n * a > c pow n * b <=> a > b`; + MESON[REAL_LE_LMUL_EQ; real_ge; REAL_POW_LT] + `!c. &0 < c ==> !a b n. c pow n * a >= c pow n * b <=> a >= b`];; + +(* ------------------------------------------------------------------------- *) +(* Theorem deducing quantifier mappings from surjectivity. *) +(* ------------------------------------------------------------------------- *) + +let QUANTIFY_SURJECTION_THM = prove + (`!f:A->B. + (!y. ?x. f x = y) + ==> ((!P. (!x. P x) <=> (!x. P (f x))) /\ + (!P. (?x. P x) <=> (?x. P (f x))) /\ + (!Q. (!s. Q s) <=> (!s. Q(IMAGE f s))) /\ + (!Q. (?s. Q s) <=> (?s. Q(IMAGE f s)))) /\ + (!P. {x | P x} = IMAGE f {x | P(f x)})`, + GEN_TAC THEN GEN_REWRITE_TAC LAND_CONV [SURJECTIVE_RIGHT_INVERSE] THEN + DISCH_THEN(X_CHOOSE_TAC `g:B->A`) THEN + SUBGOAL_THEN `!s. IMAGE (f:A->B) (IMAGE g s) = s` ASSUME_TAC THENL + [ASM SET_TAC[]; CONJ_TAC THENL [ASM MESON_TAC[]; ASM SET_TAC[]]]);; + +let QUANTIFY_SURJECTION_HIGHER_THM = prove + (`!f:A->B. + (!y. ?x. f x = y) + ==> ((!P. (!x. P x) <=> (!x. P (f x))) /\ + (!P. (?x. P x) <=> (?x. P (f x))) /\ + (!Q. (!s. Q s) <=> (!s. Q(IMAGE f s))) /\ + (!Q. (?s. Q s) <=> (?s. Q(IMAGE f s))) /\ + (!Q. (!s. Q s) <=> (!s. Q(IMAGE (IMAGE f) s))) /\ + (!Q. (?s. Q s) <=> (?s. Q(IMAGE (IMAGE f) s))) /\ + (!P. (!g:real^1->B. P g) <=> (!g. P(f o g))) /\ + (!P. (?g:real^1->B. P g) <=> (?g. P(f o g))) /\ + (!P. (!g:num->B. P g) <=> (!g. P(f o g))) /\ + (!P. (?g:num->B. P g) <=> (?g. P(f o g))) /\ + (!Q. (!l. Q l) <=> (!l. Q(MAP f l))) /\ + (!Q. (?l. Q l) <=> (?l. Q(MAP f l)))) /\ + ((!P. {x | P x} = IMAGE f {x | P(f x)}) /\ + (!Q. {s | Q s} = IMAGE (IMAGE f) {s | Q(IMAGE f s)}) /\ + (!R. {l | R l} = IMAGE (MAP f) {l | R(MAP f l)}))`, + GEN_TAC THEN DISCH_TAC THEN CONV_TAC(ONCE_DEPTH_CONV SYM_CONV) THEN + ASM_REWRITE_TAC[GSYM SURJECTIVE_FORALL_THM; GSYM SURJECTIVE_EXISTS_THM; + GSYM SURJECTIVE_IMAGE_THM; SURJECTIVE_IMAGE; SURJECTIVE_MAP] THEN + REWRITE_TAC[FUN_EQ_THM; o_THM; GSYM SKOLEM_THM] THEN ASM_MESON_TAC[]);; + +(* ------------------------------------------------------------------------- *) +(* Apply such quantifier and set expansions once per level at depth. *) +(* In the PARTIAL version, avoid expanding named variables in list. *) +(* ------------------------------------------------------------------------- *) + +let PARTIAL_EXPAND_QUANTS_CONV avoid th = + let ath,sth = CONJ_PAIR th in + let conv1 = GEN_REWRITE_CONV I [ath] + and conv2 = GEN_REWRITE_CONV I [sth] in + let conv1' tm = + let th = conv1 tm in + if mem (fst(dest_var(fst(dest_abs(rand tm))))) avoid + then failwith "Not going to expand this variable" else th in + let rec conv tm = + ((conv1' THENC BINDER_CONV conv) ORELSEC + (conv2 THENC + RAND_CONV(RAND_CONV(ABS_CONV(BINDER_CONV(LAND_CONV conv))))) ORELSEC + SUB_CONV conv) tm in + conv;; + +let EXPAND_QUANTS_CONV = PARTIAL_EXPAND_QUANTS_CONV [];; diff --git a/Multivariate/wlog.ml b/Multivariate/wlog.ml new file mode 100644 index 0000000..14c6104 --- /dev/null +++ b/Multivariate/wlog.ml @@ -0,0 +1,389 @@ +(* ========================================================================= *) +(* Geometric "without loss of generality" tactics to pick convenient coords. *) +(* ========================================================================= *) + +needs "Multivariate/determinants.ml";; +needs "Multivariate/convex.ml";; + +(* ------------------------------------------------------------------------- *) +(* Flyspeck definition of plane, and its invariance theorems. *) +(* ------------------------------------------------------------------------- *) + +let plane = new_definition + `plane x = (?u v w. ~(collinear {u,v,w}) /\ x = affine hull {u,v,w})`;; + +let PLANE_TRANSLATION_EQ = prove + (`!a:real^N s. plane(IMAGE (\x. a + x) s) <=> plane s`, + REWRITE_TAC[plane] THEN GEOM_TRANSLATE_TAC[]);; + +let PLANE_TRANSLATION = prove + (`!a:real^N s. plane s ==> plane(IMAGE (\x. a + x) s)`, + REWRITE_TAC[PLANE_TRANSLATION_EQ]);; + +add_translation_invariants [PLANE_TRANSLATION_EQ];; + +let PLANE_LINEAR_IMAGE_EQ = prove + (`!f:real^M->real^N p. + linear f /\ (!x y. f x = f y ==> x = y) + ==> (plane(IMAGE f p) <=> plane p)`, + REPEAT STRIP_TAC THEN REWRITE_TAC[plane] THEN + MATCH_MP_TAC EQ_TRANS THEN EXISTS_TAC + `?u. u IN IMAGE f (:real^M) /\ + ?v. v IN IMAGE f (:real^M) /\ + ?w. w IN IMAGE (f:real^M->real^N) (:real^M) /\ + ~collinear {u, v, w} /\ IMAGE f p = affine hull {u, v, w}` THEN + CONJ_TAC THENL + [REWRITE_TAC[RIGHT_AND_EXISTS_THM; IN_IMAGE; IN_UNIV] THEN + REPEAT(AP_TERM_TAC THEN ABS_TAC) THEN + EQ_TAC THEN DISCH_TAC THEN ASM_REWRITE_TAC[] THEN + SUBGOAL_THEN `{u,v,w} SUBSET IMAGE (f:real^M->real^N) p` MP_TAC THENL + [ASM_REWRITE_TAC[HULL_SUBSET]; SET_TAC[]]; + REWRITE_TAC[EXISTS_IN_IMAGE; IN_UNIV] THEN + REWRITE_TAC[SET_RULE `{f a,f b,f c} = IMAGE f {a,b,c}`] THEN + ASM_SIMP_TAC[AFFINE_HULL_LINEAR_IMAGE] THEN + REPEAT(AP_TERM_TAC THEN ABS_TAC) THEN BINOP_TAC THENL + [ASM_MESON_TAC[COLLINEAR_LINEAR_IMAGE_EQ]; ASM SET_TAC[]]]);; + +let PLANE_LINEAR_IMAGE = prove + (`!f:real^M->real^N p. + linear f /\ plane p /\ (!x y. f x = f y ==> x = y) + ==> plane(IMAGE f p)`, + MESON_TAC[PLANE_LINEAR_IMAGE_EQ]);; + +add_linear_invariants [PLANE_LINEAR_IMAGE_EQ];; + +(* ------------------------------------------------------------------------- *) +(* Rotating and translating so a given plane in R^3 becomes {x | x$3 = &0}. *) +(* ------------------------------------------------------------------------- *) + +let ROTATION_PLANE_HORIZONTAL = prove + (`!s. plane s + ==> ?a f. orthogonal_transformation f /\ det(matrix f) = &1 /\ + IMAGE f (IMAGE (\x. a + x) s) = {z:real^3 | z$3 = &0}`, + let lemma = prove + (`span {z:real^3 | z$3 = &0} = {z:real^3 | z$3 = &0}`, + REWRITE_TAC[SPAN_EQ_SELF; subspace; IN_ELIM_THM] THEN + SIMP_TAC[VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT; VEC_COMPONENT; + DIMINDEX_3; ARITH] THEN REAL_ARITH_TAC) in + REPEAT STRIP_TAC THEN + FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [plane]) THEN + REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN + MAP_EVERY X_GEN_TAC [`a:real^3`; `b:real^3`; `c:real^3`] THEN + MAP_EVERY (fun t -> + ASM_CASES_TAC t THENL [ASM_REWRITE_TAC[COLLINEAR_2; INSERT_AC]; + ALL_TAC]) + [`a:real^3 = b`; `a:real^3 = c`; `b:real^3 = c`] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC SUBST1_TAC) THEN + ASM_SIMP_TAC[AFFINE_HULL_INSERT_SPAN; IN_INSERT; NOT_IN_EMPTY] THEN + EXISTS_TAC `--a:real^3` THEN + REWRITE_TAC[SET_RULE `IMAGE (\x:real^3. --a + x) {a + x | x | x IN s} = + IMAGE (\x. --a + a + x) s`] THEN + REWRITE_TAC[VECTOR_ARITH `--a + a + x:real^3 = x`; IMAGE_ID] THEN + REWRITE_TAC[SET_RULE `{x - a:real^x | x = b \/ x = c} = {b - a,c - a}`] THEN + MP_TAC(ISPEC `span{b - a:real^3,c - a}` + ROTATION_LOWDIM_HORIZONTAL) THEN + REWRITE_TAC[DIMINDEX_3] THEN ANTS_TAC THENL + [MATCH_MP_TAC LET_TRANS THEN + EXISTS_TAC `CARD{b - a:real^3,c - a}` THEN + SIMP_TAC[DIM_SPAN; DIM_LE_CARD; FINITE_RULES] THEN + SIMP_TAC[CARD_CLAUSES; FINITE_RULES] THEN ARITH_TAC; + ALL_TAC] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `f:real^3->real^3` THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP ORTHOGONAL_TRANSFORMATION_LINEAR) THEN + ASM_SIMP_TAC[GSYM SPAN_LINEAR_IMAGE] THEN + GEN_REWRITE_TAC RAND_CONV [GSYM lemma] THEN + MATCH_MP_TAC DIM_EQ_SPAN THEN CONJ_TAC THENL + [ASM_MESON_TAC[IMAGE_SUBSET; SPAN_INC; SUBSET_TRANS]; ALL_TAC] THEN + MATCH_MP_TAC LE_TRANS THEN EXISTS_TAC `2` THEN CONJ_TAC THENL + [MP_TAC(ISPECL [`{z:real^3 | z$3 = &0}`; `(:real^3)`] DIM_EQ_SPAN) THEN + REWRITE_TAC[SUBSET_UNIV; DIM_UNIV; DIMINDEX_3; lemma] THEN + MATCH_MP_TAC(TAUT `~r /\ (~p ==> q) ==> (q ==> r) ==> p`) THEN + REWRITE_TAC[ARITH_RULE `~(x <= 2) <=> 3 <= x`] THEN + REWRITE_TAC[EXTENSION; SPAN_UNIV; IN_ELIM_THM] THEN + DISCH_THEN(MP_TAC o SPEC `vector[&0;&0;&1]:real^3`) THEN + REWRITE_TAC[IN_UNIV; VECTOR_3] THEN REAL_ARITH_TAC; + ALL_TAC] THEN + MATCH_MP_TAC LE_TRANS THEN EXISTS_TAC `dim {b - a:real^3,c - a}` THEN + CONJ_TAC THENL + [ALL_TAC; ASM_MESON_TAC[LE_REFL; DIM_INJECTIVE_LINEAR_IMAGE; + ORTHOGONAL_TRANSFORMATION_INJECTIVE]] THEN + MP_TAC(ISPEC `{b - a:real^3,c - a}` INDEPENDENT_BOUND_GENERAL) THEN + SIMP_TAC[CARD_CLAUSES; FINITE_RULES; IN_SING; NOT_IN_EMPTY] THEN + ASM_REWRITE_TAC[VECTOR_ARITH `b - a:real^3 = c - a <=> b = c`; ARITH] THEN + DISCH_THEN MATCH_MP_TAC THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE (RAND_CONV o RAND_CONV) + [SET_RULE `{a,b,c} = {b,a,c}`]) THEN + REWRITE_TAC[] THEN ONCE_REWRITE_TAC[COLLINEAR_3] THEN + REWRITE_TAC[independent; CONTRAPOS_THM; dependent] THEN + REWRITE_TAC[IN_INSERT; NOT_IN_EMPTY; RIGHT_OR_DISTRIB] THEN + REWRITE_TAC[EXISTS_OR_THM; UNWIND_THM2] THEN + ASM_SIMP_TAC[SET_RULE `~(a = b) ==> {a,b} DELETE b = {a}`; + SET_RULE `~(a = b) ==> {a,b} DELETE a = {b}`; + VECTOR_ARITH `b - a:real^3 = c - a <=> b = c`] THEN + REWRITE_TAC[SPAN_BREAKDOWN_EQ; SPAN_EMPTY; IN_SING] THEN + ONCE_REWRITE_TAC[VECTOR_SUB_EQ] THEN MESON_TAC[COLLINEAR_LEMMA; INSERT_AC]);; + +let ROTATION_HORIZONTAL_PLANE = prove + (`!p. plane p + ==> ?a f. orthogonal_transformation f /\ det(matrix f) = &1 /\ + IMAGE (\x. a + x) (IMAGE f {z:real^3 | z$3 = &0}) = p`, + REPEAT STRIP_TAC THEN + FIRST_X_ASSUM(MP_TAC o MATCH_MP ROTATION_PLANE_HORIZONTAL) THEN + DISCH_THEN(X_CHOOSE_THEN `a:real^3` + (X_CHOOSE_THEN `f:real^3->real^3` STRIP_ASSUME_TAC)) THEN + FIRST_ASSUM(X_CHOOSE_THEN `g:real^3->real^3` STRIP_ASSUME_TAC o MATCH_MP + ORTHOGONAL_TRANSFORMATION_INVERSE) THEN + MAP_EVERY EXISTS_TAC [`--a:real^3`; `g:real^3->real^3`] THEN + FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN + ASM_REWRITE_TAC[GSYM IMAGE_o; o_DEF; IMAGE_ID; + VECTOR_ARITH `--a + a + x:real^3 = x`] THEN + MATCH_MP_TAC(REAL_RING `!f. f * g = &1 /\ f = &1 ==> g = &1`) THEN + EXISTS_TAC `det(matrix(f:real^3->real^3))` THEN + REWRITE_TAC[GSYM DET_MUL] THEN + ASM_SIMP_TAC[GSYM MATRIX_COMPOSE; ORTHOGONAL_TRANSFORMATION_LINEAR] THEN + ASM_REWRITE_TAC[o_DEF; MATRIX_ID; DET_I]);; + +(* ------------------------------------------------------------------------- *) +(* Apply plane rotation to a goal. *) +(* ------------------------------------------------------------------------- *) + +let GEOM_HORIZONTAL_PLANE_RULE = + let ifn = MATCH_MP + (TAUT `(p ==> (x <=> x')) /\ (~p ==> (x <=> T)) ==> (x' ==> x)`) + and pth = prove + (`!a f. orthogonal_transformation (f:real^N->real^N) + ==> ((!P. (!x. P x) <=> (!x. P (a + f x))) /\ + (!P. (?x. P x) <=> (?x. P (a + f x))) /\ + (!Q. (!s. Q s) <=> (!s. Q (IMAGE (\x. a + x) (IMAGE f s)))) /\ + (!Q. (?s. Q s) <=> (?s. Q (IMAGE (\x. a + x) (IMAGE f s))))) /\ + (!P. {x | P x} = + IMAGE (\x. a + x) (IMAGE f {x | P(a + f x)}))`, + REPEAT GEN_TAC THEN DISCH_TAC THEN + MP_TAC(ISPEC `(\x. a + x) o (f:real^N->real^N)` + QUANTIFY_SURJECTION_THM) THEN REWRITE_TAC[o_THM; IMAGE_o] THEN + DISCH_THEN MATCH_MP_TAC THEN + ASM_MESON_TAC[ORTHOGONAL_TRANSFORMATION_SURJECTIVE; + VECTOR_ARITH `a + (x - a:real^N) = x`]) + and cth = prove + (`!a f. {} = IMAGE (\x:real^3. a + x) (IMAGE f {})`, + REWRITE_TAC[IMAGE_CLAUSES]) + and oth = prove + (`!f:real^3->real^3. + orthogonal_transformation f /\ det(matrix f) = &1 + ==> linear f /\ + (!x y. f x = f y ==> x = y) /\ + (!y. ?x. f x = y) /\ + (!x. norm(f x) = norm x) /\ + (2 <= dimindex(:3) ==> det(matrix f) = &1)`, + GEN_TAC THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN REPEAT CONJ_TAC THENL + [ASM_SIMP_TAC[ORTHOGONAL_TRANSFORMATION_LINEAR]; + ASM_MESON_TAC[ORTHOGONAL_TRANSFORMATION_INJECTIVE]; + ASM_MESON_TAC[ORTHOGONAL_TRANSFORMATION_SURJECTIVE]; + ASM_MESON_TAC[ORTHOGONAL_TRANSFORMATION]]) + and fth = MESON[] + `(!a f. q a f ==> (p <=> p' a f)) + ==> ((?a f. q a f) ==> (p <=> !a f. q a f ==> p' a f))` in + fun tm -> + let x,bod = dest_forall tm in + let th1 = EXISTS_GENVAR_RULE + (UNDISCH(ISPEC x ROTATION_HORIZONTAL_PLANE)) in + let [a;f],tm1 = strip_exists(concl th1) in + let [th_orth;th_det;th_im] = CONJUNCTS(ASSUME tm1) in + let th2 = PROVE_HYP th_orth (UNDISCH(ISPECL [a;f] pth)) in + let th3 = (EXPAND_QUANTS_CONV(ASSUME(concl th2)) THENC + SUBS_CONV[GSYM th_im; ISPECL [a;f] cth]) bod in + let th4 = PROVE_HYP th2 th3 in + let th5 = TRANSLATION_INVARIANTS a in + let th6 = GEN_REWRITE_RULE (RAND_CONV o REDEPTH_CONV) + [ASSUME(concl th5)] th4 in + let th7 = PROVE_HYP th5 th6 in + let th8s = CONJUNCTS(MATCH_MP oth (CONJ th_orth th_det)) in + let th9 = LINEAR_INVARIANTS f th8s in + let th10 = GEN_REWRITE_RULE (RAND_CONV o REDEPTH_CONV) [th9] th7 in + let th11 = if intersect (frees(concl th10)) [a;f] = [] + then PROVE_HYP th1 (itlist SIMPLE_CHOOSE [a;f] th10) + else MP (MATCH_MP fth (GENL [a;f] (DISCH_ALL th10))) th1 in + let th12 = REWRITE_CONV[ASSUME(mk_neg(hd(hyp th11)))] bod in + let th13 = ifn(CONJ (DISCH_ALL th11) (DISCH_ALL th12)) in + let th14 = MATCH_MP MONO_FORALL (GEN x th13) in + GEN_REWRITE_RULE (TRY_CONV o LAND_CONV) [FORALL_SIMP] th14;; + +let GEOM_HORIZONTAL_PLANE_TAC p = + W(fun (asl,w) -> + let avs,bod = strip_forall w + and avs' = subtract (frees w) (freesl(map (concl o snd) asl)) in + let avs,bod = strip_forall w in + MAP_EVERY X_GEN_TAC avs THEN + MAP_EVERY (fun t -> SPEC_TAC(t,t)) (rev(subtract (avs@avs') [p])) THEN + SPEC_TAC(p,p) THEN + W(MATCH_MP_TAC o GEOM_HORIZONTAL_PLANE_RULE o snd));; + +(* ------------------------------------------------------------------------- *) +(* Injection from real^2 -> real^3 plane with zero last coordinate. *) +(* ------------------------------------------------------------------------- *) + +let pad2d3d = new_definition + `(pad2d3d:real^2->real^3) x = lambda i. if i < 3 then x$i else &0`;; + +let FORALL_PAD2D3D_THM = prove + (`!P. (!y:real^3. y$3 = &0 ==> P y) <=> (!x. P(pad2d3d x))`, + GEN_TAC THEN EQ_TAC THEN REPEAT STRIP_TAC THENL + [FIRST_X_ASSUM MATCH_MP_TAC THEN REWRITE_TAC[pad2d3d] THEN + SIMP_TAC[LAMBDA_BETA; DIMINDEX_3; ARITH; LT_REFL]; + FIRST_X_ASSUM(MP_TAC o SPEC `(lambda i. (y:real^3)$i):real^2`) THEN + MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN + SIMP_TAC[CART_EQ; pad2d3d; DIMINDEX_3; ARITH; LAMBDA_BETA; DIMINDEX_2; + ARITH_RULE `i < 3 <=> i <= 2`] THEN + REWRITE_TAC[ARITH_RULE `i <= 3 <=> i <= 2 \/ i = 3`] THEN + ASM_MESON_TAC[]]);; + +let QUANTIFY_PAD2D3D_THM = prove + (`(!P. (!y:real^3. y$3 = &0 ==> P y) <=> (!x. P(pad2d3d x))) /\ + (!P. (?y:real^3. y$3 = &0 /\ P y) <=> (?x. P(pad2d3d x)))`, + REWRITE_TAC[MESON[] `(?y. P y) <=> ~(!x. ~P x)`] THEN + REWRITE_TAC[GSYM FORALL_PAD2D3D_THM] THEN MESON_TAC[]);; + +let LINEAR_PAD2D3D = prove + (`linear pad2d3d`, + REWRITE_TAC[linear; pad2d3d] THEN + SIMP_TAC[CART_EQ; VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT; + LAMBDA_BETA; DIMINDEX_2; DIMINDEX_3; ARITH; + ARITH_RULE `i < 3 ==> i <= 2`] THEN + REPEAT STRIP_TAC THEN REPEAT(COND_CASES_TAC THEN ASM_REWRITE_TAC[]) THEN + REAL_ARITH_TAC);; + +let INJECTIVE_PAD2D3D = prove + (`!x y. pad2d3d x = pad2d3d y ==> x = y`, + SIMP_TAC[CART_EQ; pad2d3d; LAMBDA_BETA; DIMINDEX_3; DIMINDEX_2] THEN + REWRITE_TAC[ARITH_RULE `i < 3 <=> i <= 2`] THEN + MESON_TAC[ARITH_RULE `i <= 2 ==> i <= 3`]);; + +let NORM_PAD2D3D = prove + (`!x. norm(pad2d3d x) = norm x`, + SIMP_TAC[NORM_EQ; DOT_2; DOT_3; pad2d3d; LAMBDA_BETA; + DIMINDEX_2; DIMINDEX_3; ARITH] THEN + REAL_ARITH_TAC);; + +(* ------------------------------------------------------------------------- *) +(* Apply 3D->2D conversion to a goal. Take care to preserve variable names. *) +(* ------------------------------------------------------------------------- *) + +let PAD2D3D_QUANTIFY_CONV = + let gv = genvar `:real^2` in + let pth = CONV_RULE (BINOP_CONV(BINDER_CONV(RAND_CONV(GEN_ALPHA_CONV gv)))) + QUANTIFY_PAD2D3D_THM in + let conv1 = GEN_REWRITE_CONV I [pth] + and dest_quant tm = try dest_forall tm with Failure _ -> dest_exists tm in + fun tm -> + let th = conv1 tm in + let name = fst(dest_var(fst(dest_quant tm))) in + let ty = snd(dest_var(fst(dest_quant(rand(concl th))))) in + CONV_RULE(RAND_CONV(GEN_ALPHA_CONV(mk_var(name,ty)))) th;; + +let PAD2D3D_TAC = + let pad2d3d_tm = `pad2d3d` + and pths = [LINEAR_PAD2D3D; INJECTIVE_PAD2D3D; NORM_PAD2D3D] + and cth = prove + (`{} = IMAGE pad2d3d {} /\ + vec 0 = pad2d3d(vec 0)`, + REWRITE_TAC[IMAGE_CLAUSES] THEN MESON_TAC[LINEAR_PAD2D3D; LINEAR_0]) in + let lasttac = + GEN_REWRITE_TAC REDEPTH_CONV [LINEAR_INVARIANTS pad2d3d_tm pths] in + fun gl -> (GEN_REWRITE_TAC ONCE_DEPTH_CONV [cth] THEN + CONV_TAC(DEPTH_CONV PAD2D3D_QUANTIFY_CONV) THEN + lasttac) gl;; + +(* ------------------------------------------------------------------------- *) +(* Rotating so a given line from the origin becomes the x-axis. *) +(* ------------------------------------------------------------------------- *) + +let ROTATION_HORIZONTAL_LINE = prove + (`!a:real^N. + ?b f. orthogonal_transformation f /\ det(matrix f) = &1 /\ f b = a /\ + (!k. 1 < k /\ k <= dimindex(:N) ==> b$k = &0)`, + GEN_TAC THEN ASM_CASES_TAC `dimindex(:N) = 1` THENL + [MAP_EVERY EXISTS_TAC [`a:real^N`; `\x:real^N. x`] THEN + ASM_SIMP_TAC[DET_I; MATRIX_ID; ORTHOGONAL_TRANSFORMATION_ID; LTE_ANTISYM]; + EXISTS_TAC `norm(a:real^N) % (basis 1):real^N` THEN + SIMP_TAC[VECTOR_MUL_COMPONENT; LT_IMP_LE; BASIS_COMPONENT] THEN + SIMP_TAC[ARITH_RULE `1 < k ==> ~(k = 1)`; REAL_MUL_RZERO] THEN + MATCH_MP_TAC ROTATION_EXISTS THEN + SIMP_TAC[NORM_MUL; NORM_BASIS; LE_REFL; DIMINDEX_GE_1] THEN + REWRITE_TAC[REAL_ABS_NORM; REAL_MUL_RID] THEN + MATCH_MP_TAC(ARITH_RULE `~(n = 1) /\ 1 <= n ==> 2 <= n`) THEN + ASM_REWRITE_TAC[DIMINDEX_GE_1]]);; + +let GEOM_HORIZONTAL_LINE_RULE = + let pth = prove + (`!f. orthogonal_transformation (f:real^N->real^N) + ==> (vec 0 = f(vec 0) /\ {} = IMAGE f {}) /\ + ((!P. (!x. P x) <=> (!x. P (f x))) /\ + (!P. (?x. P x) <=> (?x. P (f x))) /\ + (!Q. (!s. Q s) <=> (!s. Q (IMAGE f s))) /\ + (!Q. (?s. Q s) <=> (?s. Q (IMAGE f s)))) /\ + (!P. {x | P x} = IMAGE f {x | P(f x)})`, + REPEAT GEN_TAC THEN DISCH_TAC THEN REWRITE_TAC[IMAGE_CLAUSES] THEN + CONJ_TAC THENL + [FIRST_X_ASSUM(MP_TAC o MATCH_MP ORTHOGONAL_TRANSFORMATION_LINEAR) THEN + MESON_TAC[LINEAR_0]; + MATCH_MP_TAC QUANTIFY_SURJECTION_THM THEN + ASM_MESON_TAC[ORTHOGONAL_TRANSFORMATION_SURJECTIVE]]) + and oth = prove + (`!f:real^N->real^N. + orthogonal_transformation f /\ det(matrix f) = &1 + ==> linear f /\ + (!x y. f x = f y ==> x = y) /\ + (!y. ?x. f x = y) /\ + (!x. norm(f x) = norm x) /\ + (2 <= dimindex(:N) ==> det(matrix f) = &1)`, + GEN_TAC THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN REPEAT CONJ_TAC THENL + [ASM_SIMP_TAC[ORTHOGONAL_TRANSFORMATION_LINEAR]; + ASM_MESON_TAC[ORTHOGONAL_TRANSFORMATION_INJECTIVE]; + ASM_MESON_TAC[ORTHOGONAL_TRANSFORMATION_SURJECTIVE]; + ASM_MESON_TAC[ORTHOGONAL_TRANSFORMATION]]) + and sth = prove + (`((!k. 1 < k /\ k <= dimindex(:2) ==> b$k = &0) <=> b$2 = &0) /\ + ((!k. 1 < k /\ k <= dimindex(:3) ==> b$k = &0) <=> b$2 = &0 /\ b$3 = &0)`, + REWRITE_TAC[DIMINDEX_2; DIMINDEX_3; + ARITH_RULE `k <= 3 <=> k = 3 \/ k <= 2`; + ARITH_RULE `k <= 2 <=> k = 2 \/ ~(1 < k)`] THEN + MESON_TAC[ARITH_RULE `1 < 2 /\ 1 < 3`]) in + let sfn = GEN_REWRITE_RULE ONCE_DEPTH_CONV [sth] in + fun tm -> + let x,bod = dest_forall tm in + let th1 = EXISTS_GENVAR_RULE + (sfn(ISPEC x ROTATION_HORIZONTAL_LINE)) in + let [a;f],tm1 = strip_exists(concl th1) in + let th_orth,th2 = CONJ_PAIR(ASSUME tm1) in + let th_det,th2a = CONJ_PAIR th2 in + let th_works,th_zero = CONJ_PAIR th2a in + let thc,thq = CONJ_PAIR(PROVE_HYP th2 (UNDISCH(ISPEC f pth))) in + let th3 = CONV_RULE(RAND_CONV(SUBS_CONV(GSYM th_works::CONJUNCTS thc))) + (EXPAND_QUANTS_CONV(ASSUME(concl thq)) bod) in + let th4 = PROVE_HYP thq th3 in + let thps = CONJUNCTS(MATCH_MP oth (CONJ th_orth th_det)) in + let th5 = LINEAR_INVARIANTS f thps in + let th6 = PROVE_HYP th_orth + (GEN_REWRITE_RULE (RAND_CONV o REDEPTH_CONV) [th5] th4) in + let ntm = mk_forall(a,mk_imp(concl th_zero,rand(concl th6))) in + let th7 = MP(SPEC a (ASSUME ntm)) th_zero in + let th8 = DISCH ntm (EQ_MP (SYM th6) th7) in + if intersect (frees(concl th8)) [a;f] = [] then + let th9 = PROVE_HYP th1 (itlist SIMPLE_CHOOSE [a;f] th8) in + let th10 = DISCH ntm (GEN x (UNDISCH th9)) in + CONV_RULE(LAND_CONV (GEN_ALPHA_CONV x)) th10 + else + let mtm = list_mk_forall([a;f],mk_imp(hd(hyp th8),rand(concl th6))) in + let th9 = EQ_MP (SYM th6) (UNDISCH(SPECL [a;f] (ASSUME mtm))) in + let th10 = itlist SIMPLE_CHOOSE [a;f] (DISCH mtm th9) in + let th11 = GEN x (PROVE_HYP th1 th10) in + MATCH_MP MONO_FORALL th11;; + +let GEOM_HORIZONTAL_LINE_TAC l (asl,w as gl) = + let avs,bod = strip_forall w + and avs' = subtract (frees w) (freesl(map (concl o snd) asl)) in + (MAP_EVERY X_GEN_TAC avs THEN + MAP_EVERY (fun t -> SPEC_TAC(t,t)) (rev(subtract (avs@avs') [l])) THEN + SPEC_TAC(l,l) THEN + W(MATCH_MP_TAC o GEOM_HORIZONTAL_LINE_RULE o snd)) gl;; diff --git a/Multivariate/wlog_examples.ml b/Multivariate/wlog_examples.ml new file mode 100644 index 0000000..2b3deeb --- /dev/null +++ b/Multivariate/wlog_examples.ml @@ -0,0 +1,744 @@ +(* ========================================================================= *) +(* Examples of using the "without loss of generality" tactics. *) +(* ========================================================================= *) + +needs "Multivariate/wlog.ml";; + +(* ------------------------------------------------------------------------- *) +(* Example 1. *) +(* ------------------------------------------------------------------------- *) + +let lemma = prove + (`(?y. y pow 2 = a) <=> &0 <= a`, + MESON_TAC[SQRT_POW_2; REAL_LE_SQUARE; REAL_POW_2]);; + +let TRUONG_1 = prove + (`!u1:real^3 u2 p a b. + ~(u1 = u2) /\ + plane p /\ + {u1,u2} SUBSET p /\ + dist(u1,u2) <= a + b /\ + abs(a - b) < dist(u1,u2) /\ + &0 <= a /\ + &0 <= b + ==> (?d1 d2. + {d1, d2} SUBSET p /\ + &1 / &2 % (d1 + d2) IN affine hull {u1, u2} /\ + dist(d1,u1) = a /\ + dist(d1,u2) = b /\ + dist(d2,u1) = a /\ + dist(d2,u2) = b)`, + (*** First, rotate the plane p to the special case z$3 = &0 ***) + + GEOM_HORIZONTAL_PLANE_TAC `p:real^3->bool` THEN + + (*** Now reshuffle the goal to have explicit restricted quantifiers ***) + + ONCE_REWRITE_TAC[TAUT + `a /\ b /\ c /\ d ==> e <=> c /\ a /\ b /\ d ==> e`] THEN + REWRITE_TAC[INSERT_SUBSET; EMPTY_SUBSET] THEN + REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN + REWRITE_TAC[GSYM CONJ_ASSOC; RIGHT_EXISTS_AND_THM] THEN + REWRITE_TAC[IN_ELIM_THM] THEN + + (*** Now replace quantifiers over real^3 with those over real^2 ***) + + PAD2D3D_TAC THEN + + (*** Tidy the goal a little ***) + + REWRITE_TAC[RIGHT_IMP_FORALL_THM; IMP_IMP; GSYM CONJ_ASSOC] THEN + + (*** Choose u1 as the origin ***) + + GEOM_ORIGIN_TAC `u1:real^2` THEN + + (*** Rotate the point u2 onto the x-axis ***) + + GEOM_HORIZONTAL_LINE_TAC `u2:real^2` THEN + + (*** Only now introduce coordinates ***) + + X_GEN_TAC `u2:real^2` THEN DISCH_TAC THEN + MAP_EVERY X_GEN_TAC [`a:real`; `b:real`] THEN + REWRITE_TAC[dist; VECTOR_SUB_RZERO; VECTOR_SUB_LZERO; NORM_NEG] THEN + SIMP_TAC[GSYM real_gt; NORM_GT_SQUARE; NORM_EQ_SQUARE; NORM_LE_SQUARE] THEN + REWRITE_TAC[real_gt; REAL_ARITH `~(abs x < &0)`] THEN + ASM_SIMP_TAC[DOT_2; REAL_MUL_RZERO; REAL_ADD_RID; CART_EQ; DIMINDEX_2; + FORALL_2; AFFINE_HULL_2; CART_EQ; VECTOR_MUL_COMPONENT; + VECTOR_SUB_COMPONENT; VEC_COMPONENT; ARITH; IN_ELIM_THM; + VECTOR_ADD_COMPONENT; REAL_SUB_RZERO; REAL_ADD_LID; + REAL_POW2_ABS] THEN + DISCH_THEN(CONJUNCTS_THEN2 (ASSUME_TAC o GSYM) STRIP_ASSUME_TAC) THEN + REWRITE_TAC[EXISTS_VECTOR_2] THEN + MATCH_MP_TAC(MESON[] + `(?x y:real. P x y x (--y)) ==> (?x y x' y'. P x y x' y')`) THEN + SIMP_TAC[AFFINE_HULL_2; IN_ELIM_THM; CART_EQ; DIMINDEX_2; FORALL_2; VECTOR_2; + VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT; VEC_COMPONENT; ARITH] THEN + ASM_REWRITE_TAC[REAL_MUL_RZERO; REAL_ADD_LID; REAL_ADD_RINV] THEN + ASM_SIMP_TAC[REAL_FIELD + `~(a = &0) + ==> (u + v = &1 /\ b = v * a <=> u = &1 - b / a /\ v = b / a)`] THEN + REWRITE_TAC[RIGHT_EXISTS_AND_THM; LEFT_EXISTS_AND_THM; EXISTS_REFL] THEN + ABBREV_TAC `u = (u2:real^2)$1` THEN + REWRITE_TAC[REAL_ARITH `x + --y * --y:real = x + y * y`] THEN + REWRITE_TAC[TAUT `a /\ b /\ a /\ b <=> a /\ b`] THEN + + (*** Now finally dive in and solve the algebraic problem ***) + + ASM_SIMP_TAC[REAL_FIELD + `~(u = &0) + ==> (x * x + y * y = a pow 2 /\ (x - u) * (x - u) + y * y = b pow 2 <=> + x = (u pow 2 + a pow 2 - b pow 2) / (&2 * u) /\ + y pow 2 = b pow 2 - (x - u) pow 2)`] THEN + REWRITE_TAC[RIGHT_EXISTS_AND_THM; UNWIND_THM2; lemma] THEN + ASM_SIMP_TAC[REAL_SUB_LE; REAL_FIELD + `(u pow 2 + a - b) / (&2 * u) - u = (a - b - u pow 2) / (&2 * u)`] THEN + REWRITE_TAC[GSYM REAL_LE_SQUARE_ABS] THEN + ASM_SIMP_TAC[REAL_ABS_DIV; REAL_LE_LDIV_EQ; + REAL_ARITH `~(u = &0) ==> &0 < abs(&2 * u)`] THEN + REWRITE_TAC[GSYM REAL_ABS_MUL; REAL_LE_SQUARE_ABS] THEN + + (*** Can just use SOS: this proof was found by SOS_RULE ***) + + MAP_EVERY UNDISCH_TAC + [`u * u <= (a + b) pow 2`; `(a - b) pow 2 < u * u`] THEN + DISCH_THEN(MP_TAC o MATCH_MP REAL_LT_IMP_LE) THEN + ONCE_REWRITE_TAC[GSYM REAL_SUB_LE] THEN + REWRITE_TAC[IMP_IMP] THEN DISCH_THEN(MP_TAC o MATCH_MP REAL_LE_MUL) THEN + REAL_ARITH_TAC);; + +(* ------------------------------------------------------------------------- *) +(* Definition of "opposite" for example 2, and its invariance theorems. *) +(* ------------------------------------------------------------------------- *) + +let opposite = new_definition + `opposite a b p <=> + (&1 / &2 % (a + b)) IN p /\ + (!x y:real^N. {x,y} SUBSET p ==> (x - y) dot (a - b) = &0)`;; + +let OPPOSITE_TRANSLATION_EQ = prove + (`!c a b p. opposite (c + a) (c + b) (IMAGE (\x. c + x) p) <=> + opposite a b p`, + REWRITE_TAC[opposite] THEN GEOM_TRANSLATE_TAC[]);; + +add_translation_invariants [OPPOSITE_TRANSLATION_EQ];; + +let OPPOSITE_LINEAR_IMAGE_EQ = prove + (`!f a b p. linear f /\ (!x. norm(f x) = norm x) + ==> (opposite (f a) (f b) (IMAGE f p) <=> opposite a b p)`, + SIMP_TAC[opposite; INSERT_SUBSET; EMPTY_SUBSET; GSYM orthogonal] THEN + REWRITE_TAC[IMP_CONJ; FORALL_IN_IMAGE; RIGHT_FORALL_IMP_THM] THEN + SIMP_TAC[GSYM LINEAR_ADD; GSYM LINEAR_SUB; ORTHOGONAL_LINEAR_IMAGE_EQ] THEN + SIMP_TAC[GSYM LINEAR_CMUL; IN_IMAGE] THEN + MESON_TAC[PRESERVES_NORM_INJECTIVE]);; + +add_linear_invariants [OPPOSITE_LINEAR_IMAGE_EQ];; + +(* ------------------------------------------------------------------------- *) +(* Example 2. *) +(* ------------------------------------------------------------------------- *) + +let AFFINE_PLANE = prove + (`!p. plane p ==> affine p`, + SIMP_TAC[plane; LEFT_IMP_EXISTS_THM; AFFINE_AFFINE_HULL]);; + +let lemma = prove + (`!a b:real^2. + a$2 <= &0 /\ &0 <= b$2 ==> ?x. x IN convex hull {a,b} /\ x$2 = &0`, + REPEAT GEN_TAC THEN DISCH_TAC THEN + FIRST_ASSUM(DISJ_CASES_TAC o MATCH_MP (REAL_ARITH + `a <= &0 /\ &0 <= b ==> a = &0 /\ b = &0 \/ &0 < b - a`)) + THENL + [EXISTS_TAC `a:real^2` THEN ASM_SIMP_TAC[HULL_INC; IN_INSERT]; + REWRITE_TAC[CONVEX_HULL_2_ALT; EXISTS_IN_GSPEC] THEN + SIMP_TAC[VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT; VECTOR_SUB_COMPONENT; + DIMINDEX_2; ARITH] THEN + EXISTS_TAC `--(a$2) / ((b:real^2)$2 - (a:real^2)$2)` THEN + ASM_SIMP_TAC[REAL_LT_IMP_NZ; REAL_DIV_RMUL; + REAL_LE_LDIV_EQ; REAL_LE_RDIV_EQ] THEN + ASM_REAL_ARITH_TAC]);; + +let TRUONG_OPPOSITE_LEMMA = prove + (`!p a b bb m x y:real^3. + plane p /\ + {a, b, bb, m, x, y} SUBSET p /\ + ~(x = y) /\ m IN affine hull {x,y} /\ midpoint(b,bb) = m + ==> ~(convex hull {a, b} INTER affine hull {x, y} = {}) \/ + ~(convex hull {a, bb} INTER affine hull {x, y} = {})`, + + (*** Make the plane p the xy-plane ***) + + GEOM_HORIZONTAL_PLANE_TAC `p:real^3->bool` THEN + + (*** Rewrite with explicit restricted quantifiers ***) + + REWRITE_TAC[INSERT_SUBSET; EMPTY_SUBSET; IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN + REWRITE_TAC[IN_ELIM_THM] THEN DISCH_THEN(K ALL_TAC) THEN + + (*** Now replace quantifiers over real^3 with those over real^2 ***) + + PAD2D3D_TAC THEN + + (*** Let x be the origin, and y on the x-axis ***) + + GEOM_ORIGIN_TAC `x:real^2` THEN + GEOM_HORIZONTAL_LINE_TAC `y:real^2` THEN + + (*** Make a few simplifications ***) + + GEN_TAC THEN DISCH_TAC THEN REPEAT GEN_TAC THEN + ASM_SIMP_TAC[CART_EQ; DIMINDEX_2; FORALL_2; VEC_COMPONENT] THEN + DISCH_THEN(ASSUME_TAC o GSYM) THEN + SIMP_TAC[midpoint; VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT; + DIMINDEX_2; ARITH] THEN + + (*** Show aff{x,y} is now exactly the x-axis ***) + + SUBGOAL_THEN `affine hull {vec 0,y} = {u:real^2 | u$2 = &0}` SUBST1_TAC THENL + [MATCH_MP_TAC HULL_UNIQUE THEN + REWRITE_TAC[affine; INSERT_SUBSET; EMPTY_SUBSET; IN_ELIM_THM] THEN + ASM_SIMP_TAC[VEC_COMPONENT; DIMINDEX_2; ARITH; VECTOR_ADD_COMPONENT; + VECTOR_MUL_COMPONENT; REAL_MUL_RZERO; REAL_ADD_RID] THEN + X_GEN_TAC `s:real^2->bool` THEN STRIP_TAC THEN + REWRITE_TAC[SUBSET; FORALL_IN_GSPEC] THEN X_GEN_TAC `u:real^2` THEN + DISCH_TAC THEN + SUBGOAL_THEN `u = (&1 - u$1 / (y:real^2)$1) % vec 0 + + (u$1 / (y:real^2)$1) % y` + SUBST1_TAC THENL + [REWRITE_TAC[VECTOR_MUL_RZERO; VECTOR_ADD_LID] THEN + ASM_SIMP_TAC[CART_EQ; VECTOR_MUL_COMPONENT; DIMINDEX_2; ARITH; + FORALL_2; REAL_MUL_RZERO; REAL_DIV_RMUL]; + FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[] THEN + REAL_ARITH_TAC]; + ALL_TAC] THEN + + (*** Simplify a bit more ***) + + SIMP_TAC[IN_ELIM_THM; REAL_ARITH `inv(&2) * (x + y) = &0 <=> y = --x`] THEN + REPEAT STRIP_TAC THEN + + (*** Finally, make a 4-way case split then apply the lemma to each ***) + + REWRITE_TAC[SET_RULE `~(s INTER t = {}) <=> ?x. x IN s /\ x IN t`] THEN + REWRITE_TAC[IN_ELIM_THM] THEN + FIRST_ASSUM(MP_TAC o SPEC `(a:real^2)$2` o MATCH_MP (REAL_ARITH + `b' = --b ==> !a. a <= &0 /\ &0 <= b \/ a <= &0 /\ &0 <= b' \/ + b <= &0 /\ &0 <= a \/ b' <= &0 /\ &0 <= a`)) THEN + MESON_TAC[lemma; SET_RULE `{a,b} = {b,a}`]);; + +let TRUONG_OPPOSITE_THM = prove + (`!a b bb x y:real^3 p. + ~(x = y) /\ + plane p /\ + {a, b, x, y} SUBSET p /\ + opposite b bb (affine hull {x, y}) + ==> ~(convex hull {a, b} INTER affine hull {x, y} = {}) \/ + ~(convex hull {a, bb} INTER affine hull {x, y} = {})`, + REWRITE_TAC[opposite; INSERT_SUBSET; EMPTY_SUBSET] THEN REPEAT STRIP_TAC THEN + MATCH_MP_TAC TRUONG_OPPOSITE_LEMMA THEN + MAP_EVERY EXISTS_TAC [`p:real^3->bool`; `&1 / &2 % (b + bb):real^3`] THEN + ASM_REWRITE_TAC[INSERT_SUBSET; EMPTY_SUBSET; midpoint] THEN + CONJ_TAC THENL [ALL_TAC; VECTOR_ARITH_TAC] THEN + FIRST_ASSUM(ASSUME_TAC o MATCH_MP AFFINE_PLANE) THEN + MATCH_MP_TAC(TAUT `b /\ (b ==> a) ==> a /\ b`) THEN CONJ_TAC THENL + [MATCH_MP_TAC(SET_RULE `!t. x IN t /\ t SUBSET s ==> x IN s`) THEN + EXISTS_TAC `affine hull {x:real^3,y}` THEN ASM_REWRITE_TAC[] THEN + MATCH_MP_TAC HULL_MINIMAL THEN ASM_SIMP_TAC[INSERT_SUBSET; EMPTY_SUBSET]; + DISCH_TAC THEN SUBST1_TAC(VECTOR_ARITH + `bb:real^3 = -- &1 % b + &2 % &1 / &2 % (b + bb)`) THEN + FIRST_X_ASSUM(MATCH_MP_TAC o REWRITE_RULE[affine]) THEN + ASM_REWRITE_TAC[] THEN REAL_ARITH_TAC]);; + +(* ------------------------------------------------------------------------- *) +(* Affsign variants for example 3, and invariance theorems. *) +(* ------------------------------------------------------------------------- *) + +let lin_combo = new_definition + `lin_combo V f = vsum V (\v. f v % (v:real^N))`;; + +let affsign = new_definition + `affsign sgn s t (v:real^A) <=> + (?f. (v = lin_combo (s UNION t) f) /\ + (!w. t w ==> sgn (f w)) /\ + (sum (s UNION t) f = &1))`;; + +let sgn_gt = new_definition `sgn_gt = (\t. (&0 < t))`;; +let sgn_ge = new_definition `sgn_ge = (\t. (&0 <= t))`;; +let sgn_lt = new_definition `sgn_lt = (\t. (t < &0))`;; +let sgn_le = new_definition `sgn_le = (\t. (t <= &0))`;; + +let aff_gt_def = new_definition `aff_gt = affsign sgn_gt`;; +let aff_ge_def = new_definition `aff_ge = affsign sgn_ge`;; +let aff_lt_def = new_definition `aff_lt = affsign sgn_lt`;; +let aff_le_def = new_definition `aff_le = affsign sgn_le`;; + +let AFFSIGN = prove + (`affsign sgn s t = + {y | ?f. y = vsum (s UNION t) (\v. f v % v) /\ + (!w. w IN t ==> sgn(f w)) /\ + sum (s UNION t) f = &1}`, + REWRITE_TAC[FUN_EQ_THM; affsign; lin_combo; IN_ELIM_THM] THEN + REWRITE_TAC[IN]);; + +let AFFSIGN_ALT = prove + (`affsign sgn s t = + {y | ?f. (!w. w IN (s UNION t) ==> w IN t ==> sgn(f w)) /\ + sum (s UNION t) f = &1 /\ + vsum (s UNION t) (\v. f v % v) = y}`, + REWRITE_TAC[SET_RULE `(w IN (s UNION t) ==> w IN t ==> P w) <=> + (w IN t ==> P w)`] THEN + REWRITE_TAC[AFFSIGN; EXTENSION; IN_ELIM_THM] THEN MESON_TAC[]);; + +let IN_AFFSIGN = prove + (`y IN affsign sgn s t <=> + ?u. (!x. x IN t ==> sgn(u x)) /\ + sum (s UNION t) u = &1 /\ + vsum (s UNION t) (\x. u(x) % x) = y`, + REWRITE_TAC[AFFSIGN; IN_ELIM_THM] THEN SET_TAC[]);; + +let AFFSIGN_INJECTIVE_LINEAR_IMAGE = prove + (`!f:real^M->real^N sgn s t v. + linear f /\ (!x y. f x = f y ==> x = y) + ==> (affsign sgn (IMAGE f s) (IMAGE f t) = + IMAGE f (affsign sgn s t))`, + let lemma0 = prove + (`vsum s (\x. u x % x) = vsum {x | x IN s /\ ~(u x = &0)} (\x. u x % x)`, + MATCH_MP_TAC VSUM_SUPERSET THEN SIMP_TAC[SUBSET; IN_ELIM_THM] THEN + REWRITE_TAC[TAUT `p /\ ~(p /\ ~q) <=> p /\ q`] THEN + SIMP_TAC[o_THM; VECTOR_MUL_LZERO]) in + let lemma1 = prove + (`!f:real^M->real^N s. + linear f /\ (!x y. f x = f y ==> x = y) + ==> (sum(IMAGE f s) u = &1 /\ vsum(IMAGE f s) (\x. u x % x) = y <=> + sum s (u o f) = &1 /\ f(vsum s (\x. (u o f) x % x)) = y)`, + REPEAT STRIP_TAC THEN + W(MP_TAC o PART_MATCH (lhs o rand) SUM_IMAGE o funpow 3 lhand o snd) THEN + ANTS_TAC THENL [ASM_MESON_TAC[]; DISCH_THEN SUBST1_TAC] THEN + MATCH_MP_TAC(MESON[] `(p ==> z = x) ==> (p /\ x = y <=> p /\ z = y)`) THEN + DISCH_TAC THEN ONCE_REWRITE_TAC[lemma0] THEN + SUBGOAL_THEN + `{y | y IN IMAGE (f:real^M->real^N) s /\ ~(u y = &0)} = + IMAGE f {x | x IN s /\ ~(u(f x) = &0)}` + SUBST1_TAC THENL [ASM SET_TAC[]; CONV_TAC SYM_CONV] THEN + SUBGOAL_THEN `FINITE {x | x IN s /\ ~(u((f:real^M->real^N) x) = &0)}` + ASSUME_TAC THENL + [FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE + (LAND_CONV o RATOR_CONV o RATOR_CONV) [sum]) THEN + ONCE_REWRITE_TAC[ITERATE_EXPAND_CASES] THEN + REWRITE_TAC[GSYM sum; support; NEUTRAL_REAL_ADD; o_THM] THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[REAL_OF_NUM_EQ; ARITH_EQ]; + W(MP_TAC o PART_MATCH (lhs o rand) VSUM_IMAGE o lhand o snd) THEN + ANTS_TAC THENL [ASM_REWRITE_TAC[] THEN ASM_MESON_TAC[]; ALL_TAC] THEN + DISCH_THEN SUBST1_TAC THEN REWRITE_TAC[o_DEF] THEN + ASM_SIMP_TAC[LINEAR_VSUM; o_DEF; GSYM LINEAR_CMUL]]) in + REPEAT GEN_TAC THEN DISCH_TAC THEN REWRITE_TAC[EXTENSION; IN_AFFSIGN] THEN + REWRITE_TAC[FORALL_IN_IMAGE] THEN REWRITE_TAC[IN_IMAGE; IN_AFFSIGN] THEN + REWRITE_TAC[GSYM IMAGE_UNION] THEN + FIRST_ASSUM(fun th -> REWRITE_TAC[MATCH_MP lemma1 th]) THEN + X_GEN_TAC `y:real^N` THEN EQ_TAC THENL + [DISCH_THEN(X_CHOOSE_THEN `u:real^N->real` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `vsum (s UNION t) (\x. (u o (f:real^M->real^N)) x % x)` THEN + ASM_REWRITE_TAC[] THEN + EXISTS_TAC `(u:real^N->real) o (f:real^M->real^N)` THEN + ASM_REWRITE_TAC[] THEN ASM_REWRITE_TAC[o_THM]; + MP_TAC(ISPEC `f:real^M->real^N` LINEAR_INJECTIVE_LEFT_INVERSE) THEN + ASM_REWRITE_TAC[FUN_EQ_THM; o_THM; I_THM] THEN + DISCH_THEN(X_CHOOSE_THEN `g:real^N->real^M` STRIP_ASSUME_TAC) THEN + DISCH_THEN(X_CHOOSE_THEN `x:real^M` + (CONJUNCTS_THEN2 SUBST1_TAC MP_TAC)) THEN + DISCH_THEN(X_CHOOSE_THEN `u:real^M->real` STRIP_ASSUME_TAC) THEN + EXISTS_TAC `(u:real^M->real) o (g:real^N->real^M)` THEN + ASM_REWRITE_TAC[o_DEF; ETA_AX]]);; + +let AFF_GE_INJECTIVE_LINEAR_IMAGE = prove + (`!f:real^M->real^N s t. + linear f /\ (!x y. f x = f y ==> x = y) + ==> aff_ge (IMAGE f s) (IMAGE f t) = IMAGE f (aff_ge s t)`, + REWRITE_TAC[aff_ge_def; AFFSIGN_INJECTIVE_LINEAR_IMAGE]);; + +let AFF_GT_INJECTIVE_LINEAR_IMAGE = prove + (`!f:real^M->real^N s t. + linear f /\ (!x y. f x = f y ==> x = y) + ==> aff_gt (IMAGE f s) (IMAGE f t) = IMAGE f (aff_gt s t)`, + REWRITE_TAC[aff_gt_def; AFFSIGN_INJECTIVE_LINEAR_IMAGE]);; + +let AFF_LE_INJECTIVE_LINEAR_IMAGE = prove + (`!f:real^M->real^N s t. + linear f /\ (!x y. f x = f y ==> x = y) + ==> aff_le (IMAGE f s) (IMAGE f t) = IMAGE f (aff_le s t)`, + REWRITE_TAC[aff_le_def; AFFSIGN_INJECTIVE_LINEAR_IMAGE]);; + +let AFF_LT_INJECTIVE_LINEAR_IMAGE = prove + (`!f:real^M->real^N s t. + linear f /\ (!x y. f x = f y ==> x = y) + ==> aff_lt (IMAGE f s) (IMAGE f t) = IMAGE f (aff_lt s t)`, + REWRITE_TAC[aff_lt_def; AFFSIGN_INJECTIVE_LINEAR_IMAGE]);; + +add_linear_invariants + [AFFSIGN_INJECTIVE_LINEAR_IMAGE; + AFF_GE_INJECTIVE_LINEAR_IMAGE; + AFF_GT_INJECTIVE_LINEAR_IMAGE; + AFF_LE_INJECTIVE_LINEAR_IMAGE; + AFF_LT_INJECTIVE_LINEAR_IMAGE];; + +let IN_AFFSIGN_TRANSLATION = prove + (`!sgn s t a v:real^N. + affsign sgn s t v + ==> affsign sgn (IMAGE (\x. a + x) s) (IMAGE (\x. a + x) t) (a + v)`, + REPEAT GEN_TAC THEN REWRITE_TAC[affsign; lin_combo] THEN + ONCE_REWRITE_TAC[SET_RULE `(!x. s x ==> p x) <=> (!x. x IN s ==> p x)`] THEN + DISCH_THEN(X_CHOOSE_THEN `f:real^N->real` + (CONJUNCTS_THEN2 SUBST_ALL_TAC STRIP_ASSUME_TAC)) THEN + EXISTS_TAC `\x. (f:real^N->real)(x - a)` THEN + ASM_REWRITE_TAC[GSYM IMAGE_UNION] THEN REPEAT CONJ_TAC THENL + [ALL_TAC; + ASM_REWRITE_TAC[FORALL_IN_IMAGE; ETA_AX; + VECTOR_ARITH `(a + x) - a:real^N = x`]; + W(MP_TAC o PART_MATCH (lhs o rand) SUM_IMAGE o lhs o snd) THEN + SIMP_TAC[VECTOR_ARITH `a + x:real^N = a + y <=> x = y`] THEN + ASM_REWRITE_TAC[o_DEF; VECTOR_ADD_SUB; ETA_AX]] THEN + MATCH_MP_TAC EQ_TRANS THEN EXISTS_TAC + `a + vsum {x | x IN s UNION t /\ ~(f x = &0)} (\v:real^N. f v % v)` THEN + CONJ_TAC THENL + [AP_TERM_TAC THEN MATCH_MP_TAC VSUM_SUPERSET THEN + REWRITE_TAC[VECTOR_MUL_EQ_0; SUBSET; IN_ELIM_THM] THEN MESON_TAC[]; + ALL_TAC] THEN + MATCH_MP_TAC EQ_TRANS THEN + EXISTS_TAC `vsum (IMAGE (\x:real^N. a + x) + {x | x IN s UNION t /\ ~(f x = &0)}) + (\v. f(v - a) % v)` THEN + CONJ_TAC THENL + [ALL_TAC; + CONV_TAC SYM_CONV THEN MATCH_MP_TAC VSUM_SUPERSET THEN + CONJ_TAC THENL [SET_TAC[]; ALL_TAC] THEN + ASM_REWRITE_TAC[IMP_CONJ; FORALL_IN_IMAGE; VECTOR_MUL_EQ_0] THEN + REWRITE_TAC[VECTOR_ADD_SUB] THEN SET_TAC[]] THEN + SUBGOAL_THEN `FINITE {x:real^N | x IN s UNION t /\ ~(f x = &0)}` + ASSUME_TAC THENL + [FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE + (LAND_CONV o RATOR_CONV o RATOR_CONV) [sum]) THEN + ONCE_REWRITE_TAC[ITERATE_EXPAND_CASES] THEN + REWRITE_TAC[GSYM sum; support; NEUTRAL_REAL_ADD] THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[REAL_OF_NUM_EQ; ARITH_EQ]; + ALL_TAC] THEN + W(MP_TAC o PART_MATCH (lhs o rand) VSUM_IMAGE o rhs o snd) THEN + ASM_SIMP_TAC[VECTOR_ARITH `a + x:real^N = a + y <=> x = y`] THEN + DISCH_THEN(K ALL_TAC) THEN REWRITE_TAC[o_DEF; VECTOR_ADD_SUB] THEN + ASM_SIMP_TAC[VECTOR_ADD_LDISTRIB; VSUM_ADD] THEN + AP_THM_TAC THEN AP_TERM_TAC THEN REWRITE_TAC[VSUM_RMUL] THEN + GEN_REWRITE_TAC LAND_CONV [GSYM VECTOR_MUL_LID] THEN + AP_THM_TAC THEN AP_TERM_TAC THEN FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN + MATCH_MP_TAC SUM_SUPERSET THEN SET_TAC[]);; + +let AFFSIGN_TRANSLATION = prove + (`!a:real^N sgn s t. + affsign sgn (IMAGE (\x. a + x) s) (IMAGE (\x. a + x) t) = + IMAGE (\x. a + x) (affsign sgn s t)`, + REPEAT GEN_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL + [REWRITE_TAC[SUBSET; IN] THEN GEN_TAC THEN + DISCH_THEN(MP_TAC o SPEC `--a:real^N` o + MATCH_MP IN_AFFSIGN_TRANSLATION) THEN + REWRITE_TAC[GSYM IMAGE_o; o_DEF; VECTOR_ARITH `--a + a + x:real^N = x`; + IMAGE_ID] THEN + DISCH_TAC THEN REWRITE_TAC[IMAGE; IN_ELIM_THM] THEN + EXISTS_TAC `--a + x:real^N` THEN ASM_REWRITE_TAC[IN] THEN VECTOR_ARITH_TAC; + REWRITE_TAC[SUBSET; FORALL_IN_IMAGE] THEN GEN_TAC THEN REWRITE_TAC[IN] THEN + DISCH_THEN(MP_TAC o SPEC `a:real^N` o MATCH_MP IN_AFFSIGN_TRANSLATION) THEN + REWRITE_TAC[]]);; + +let AFF_GE_TRANSLATION = prove + (`!a:real^N s t. + aff_ge (IMAGE (\x. a + x) s) (IMAGE (\x. a + x) t) = + IMAGE (\x. a + x) (aff_ge s t)`, + REWRITE_TAC[aff_ge_def; AFFSIGN_TRANSLATION]);; + +let AFF_GT_TRANSLATION = prove + (`!a:real^N s t. + aff_gt (IMAGE (\x. a + x) s) (IMAGE (\x. a + x) t) = + IMAGE (\x. a + x) (aff_gt s t)`, + REWRITE_TAC[aff_gt_def; AFFSIGN_TRANSLATION]);; + +let AFF_LE_TRANSLATION = prove + (`!a:real^N s t. + aff_le (IMAGE (\x. a + x) s) (IMAGE (\x. a + x) t) = + IMAGE (\x. a + x) (aff_le s t)`, + REWRITE_TAC[aff_le_def; AFFSIGN_TRANSLATION]);; + +let AFF_LT_TRANSLATION = prove + (`!a:real^N s t. + aff_lt (IMAGE (\x. a + x) s) (IMAGE (\x. a + x) t) = + IMAGE (\x. a + x) (aff_lt s t)`, + REWRITE_TAC[aff_lt_def; AFFSIGN_TRANSLATION]);; + +add_translation_invariants + [AFFSIGN_TRANSLATION; + AFF_GE_TRANSLATION; + AFF_GT_TRANSLATION; + AFF_LE_TRANSLATION; + AFF_LT_TRANSLATION];; + +(* ------------------------------------------------------------------------- *) +(* Example 3. *) +(* ------------------------------------------------------------------------- *) + +let NOT_COPLANAR_NOT_COLLINEAR = prove + (`!v1 v2 v3 w:real^N. ~coplanar {v1, v2, v3, w} ==> ~collinear {v1, v2, v3}`, + REPEAT GEN_TAC THEN + REWRITE_TAC[COLLINEAR_AFFINE_HULL; coplanar; CONTRAPOS_THM] THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `x:real^N` THEN + MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `y:real^N` THEN + REWRITE_TAC[INSERT_SUBSET; EMPTY_SUBSET] THEN STRIP_TAC THEN + EXISTS_TAC `w:real^N` THEN ASM_SIMP_TAC[HULL_INC; IN_INSERT] THEN + REPEAT CONJ_TAC THEN + MATCH_MP_TAC(SET_RULE `!t. t SUBSET s /\ x IN t ==> x IN s`) THEN + EXISTS_TAC `affine hull {x:real^N,y}` THEN + ASM_REWRITE_TAC[] THEN MATCH_MP_TAC HULL_MONO THEN SET_TAC[]);; + +let AFFSIGN = prove + (`affsign sgn s t = + {y | ?f. y = vsum (s UNION t) (\v. f v % v) /\ + (!w. w IN t ==> sgn(f w)) /\ + sum (s UNION t) f = &1}`, + REWRITE_TAC[FUN_EQ_THM; affsign; lin_combo; IN_ELIM_THM] THEN + REWRITE_TAC[IN]);; + +let IN_AFFSIGN = prove + (`y IN affsign sgn s t <=> + ?u. (!x. x IN (s UNION t) ==> x IN t ==> sgn(u x)) /\ + sum (s UNION t) u = &1 /\ + vsum (s UNION t) (\x. u(x) % x) = y`, + REWRITE_TAC[AFFSIGN; IN_ELIM_THM] THEN SET_TAC[]);; + +let LEMMA = prove + (`!v1 v2 v3 w:real^3 p. + plane p /\ {v1, v2, v3} SUBSET p /\ + ~coplanar {v1, v2, v3, w} + ==> (?n n'. norm(n - n') = &1 /\ + (!x. x IN aff_ge {v1, v2, v3} {w} <=> + (?xx h. + xx IN affine hull {v1, v2, v3} /\ + &0 <= h /\ + x - xx = h % (n - n'))) /\ + (!x y. + {x, y} SUBSET affine hull {v1, v2, v3} + ==> (n - n') dot (x - y) = &0))`, + GEOM_HORIZONTAL_PLANE_TAC `p:real^3->bool` THEN + REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN + REWRITE_TAC[INSERT_SUBSET; EMPTY_SUBSET; IN_ELIM_THM] THEN + MAP_EVERY (fun t -> + ASM_CASES_TAC t THENL [ASM_REWRITE_TAC[INSERT_AC; COPLANAR_3]; ALL_TAC]) + [`v1:real^3 = v2`; `v1:real^3 = v3`; `v2:real^3 = v3`; + `v1:real^3 = w`; `v2:real^3 = w`; `v3:real^3 = w`] THEN + STRIP_TAC THEN + ONCE_REWRITE_TAC[SWAP_EXISTS_THM] THEN + EXISTS_TAC `vec 0:real^3` THEN REWRITE_TAC[VECTOR_SUB_RZERO] THEN + SUBGOAL_THEN `~((w:real^3)$3 = &0)` ASSUME_TAC THENL + [DISCH_TAC THEN UNDISCH_TAC `~coplanar{v1:real^3,v2,v3,w}` THEN + REWRITE_TAC[coplanar] THEN + FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [plane]) THEN + REPEAT(MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC) THEN + DISCH_THEN(SUBST1_TAC o SYM o CONJUNCT2) THEN + ASM_REWRITE_TAC[INSERT_SUBSET; EMPTY_SUBSET; IN_ELIM_THM]; + ALL_TAC] THEN + SUBGOAL_THEN `(vec 0:real^3) IN affine hull {v1,v2,v3}` ASSUME_TAC THENL + [MP_TAC(ISPEC `{v1:real^3,v2,v3}` DEPENDENT_BIGGERSET_GENERAL) THEN + ANTS_TAC THENL + [DISCH_THEN(K ALL_TAC) THEN REWRITE_TAC[GT] THEN + MATCH_MP_TAC LET_TRANS THEN EXISTS_TAC `dim {z:real^3 | z$3 = &0}` THEN + CONJ_TAC THENL [MATCH_MP_TAC DIM_SUBSET THEN ASM SET_TAC[]; ALL_TAC] THEN + SIMP_TAC[DIM_SPECIAL_HYPERPLANE; DIMINDEX_3; ARITH] THEN + REWRITE_TAC[GSYM NOT_LE] THEN DISCH_TAC THEN + FIRST_ASSUM(MP_TAC o MATCH_MP NOT_COPLANAR_NOT_COLLINEAR) THEN + REWRITE_TAC[] THEN MATCH_MP_TAC COLLINEAR_SMALL THEN + ASM_REWRITE_TAC[FINITE_INSERT; FINITE_RULES]; + ALL_TAC] THEN + REWRITE_TAC[DEPENDENT_AFFINE_DEPENDENT_CASES] THEN + ASM_MESON_TAC[AFFINE_DEPENDENT_IMP_COLLINEAR_3; + NOT_COPLANAR_NOT_COLLINEAR]; + ALL_TAC] THEN + SUBGOAL_THEN `affine hull {v1,v2,v3} = {z:real^3 | z$3 = &0}` + ASSUME_TAC THENL + [ASM_SIMP_TAC[AFFINE_HULL_EQ_SPAN] THEN + MATCH_MP_TAC(SET_RULE + `!s. t SUBSET u /\ s SUBSET t /\ u SUBSET s ==> t = u`) THEN + EXISTS_TAC `span {x - v1:real^3 | x IN {v2,v3}}` THEN CONJ_TAC THENL + [REWRITE_TAC[SUBSET] THEN MATCH_MP_TAC SPAN_INDUCT THEN + REWRITE_TAC[SET_RULE `(\x. x IN s) = s`] THEN + SIMP_TAC[SUBSPACE_SPECIAL_HYPERPLANE; DIMINDEX_3; ARITH] THEN + ASM_SIMP_TAC[FORALL_IN_INSERT; NOT_IN_EMPTY; IN_ELIM_THM]; + ALL_TAC] THEN + CONJ_TAC THENL + [GEN_REWRITE_TAC RAND_CONV [GSYM SPAN_SPAN] THEN + MATCH_MP_TAC SPAN_MONO THEN + REWRITE_TAC[SUBSET; FORALL_IN_GSPEC; FORALL_IN_INSERT; NOT_IN_EMPTY] THEN + MESON_TAC[SPAN_SUB; SPAN_INC; IN_INSERT; SUBSET]; + ALL_TAC] THEN + MATCH_MP_TAC CARD_GE_DIM_INDEPENDENT THEN REPEAT CONJ_TAC THENL + [REWRITE_TAC[SUBSET; FORALL_IN_GSPEC; IN_ELIM_THM; + FORALL_IN_INSERT; NOT_IN_EMPTY] THEN + ASM_SIMP_TAC[VECTOR_SUB_COMPONENT; DIMINDEX_3; ARITH; REAL_SUB_REFL]; + REWRITE_TAC[independent] THEN + DISCH_THEN(MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] + DEPENDENT_IMP_AFFINE_DEPENDENT)) THEN + ASM_REWRITE_TAC[IN_INSERT; NOT_IN_EMPTY] THEN + ASM_MESON_TAC[AFFINE_DEPENDENT_IMP_COLLINEAR_3; + NOT_COPLANAR_NOT_COLLINEAR]; + SIMP_TAC[DIM_SPECIAL_HYPERPLANE; DIMINDEX_3; ARITH] THEN + ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN + SIMP_TAC[CARD_IMAGE_INJ; FINITE_INSERT; FINITE_RULES; + VECTOR_ARITH `x - a:real^N = y - a <=> x = y`] THEN + ASM_SIMP_TAC[CARD_CLAUSES; FINITE_INSERT; FINITE_RULES; + IN_INSERT; NOT_IN_EMPTY; ARITH]]; + ALL_TAC] THEN + FIRST_ASSUM(DISJ_CASES_TAC o MATCH_MP (REAL_ARITH + `~(x = &0) ==> &0 < x \/ &0 < --x`)) + THENL + [EXISTS_TAC `basis 3:real^3`; EXISTS_TAC `--(basis 3):real^3`] THEN + ASM_SIMP_TAC[NORM_BASIS; DIMINDEX_3; ARITH; IN_ELIM_THM; DOT_BASIS; + NORM_NEG; DOT_LNEG; DIMINDEX_3; ARITH; VECTOR_SUB_COMPONENT; + REAL_SUB_REFL; REAL_NEG_0] THEN + X_GEN_TAC `x:real^3` THEN + REWRITE_TAC[aff_ge_def; IN_AFFSIGN; sgn_ge] THEN + REWRITE_TAC[SET_RULE `{a,b,c} UNION {d} = {a,b,c,d}`] THEN + REWRITE_TAC[SET_RULE `x IN {a} <=> a = x`] THEN + SIMP_TAC[AFFINE_HULL_FINITE_STEP_GEN; REAL_LE_ADD; FINITE_INSERT; + CONJUNCT1 FINITE_RULES; REAL_ARITH `&0 <= x / &2 <=> &0 <= x`; + RIGHT_EXISTS_AND_THM] THEN + ASM_REWRITE_TAC[RIGHT_AND_EXISTS_THM] THEN + REWRITE_TAC[REAL_ARITH `x - y:real = z <=> x = y + z`] THEN + REWRITE_TAC[VECTOR_ARITH `x - y:real^3 = z <=> x = y + z`] THEN + REWRITE_TAC[VECTOR_ADD_RID; REAL_ADD_RID] THEN + REWRITE_TAC[REAL_ARITH `&1 = x + y <=> x + y = &1`] THEN + EQ_TAC THEN REWRITE_TAC[LEFT_IMP_EXISTS_THM] THENL + [MAP_EVERY X_GEN_TAC [`a:real`; `b:real`; `c:real`; `h:real`] THEN + STRIP_TAC THEN + EXISTS_TAC `a % v1 + b % v2 + c % v3 + + h % ((w:real^3)$1 % basis 1 + w$2 % basis 2):real^3` THEN + EXISTS_TAC `h * (w:real^3)$3` THEN + ASM_SIMP_TAC[REAL_LE_MUL; REAL_LT_IMP_LE] THEN + ASM_SIMP_TAC[VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT; BASIS_COMPONENT; + DIMINDEX_3; ARITH; REAL_MUL_RZERO; REAL_ADD_RID] THEN + REWRITE_TAC[GSYM VECTOR_MUL_ASSOC; GSYM VECTOR_ADD_LDISTRIB; + GSYM VECTOR_ADD_ASSOC] THEN + REPLICATE_TAC 4 AP_TERM_TAC THEN + GEN_REWRITE_TAC LAND_CONV [GSYM BASIS_EXPANSION] THEN + REWRITE_TAC[DIMINDEX_3] THEN CONV_TAC(ONCE_DEPTH_CONV NUMSEG_CONV) THEN + SIMP_TAC[VSUM_CLAUSES; FINITE_INSERT; CONJUNCT1 FINITE_RULES] THEN + REWRITE_TAC[IN_INSERT; NOT_IN_EMPTY; ARITH_EQ; VECTOR_ADD_RID]; + + MAP_EVERY X_GEN_TAC [`y:real^3`; `h:real`] THEN STRIP_TAC THEN + UNDISCH_TAC `(vec 0:real^3) IN affine hull {v1,v2,v3}` THEN + SUBGOAL_THEN `(y - h / (w:real^3)$3 % (w$1 % basis 1 + w$2 % basis 2)) + IN affine hull {v1:real^3,v2,v3}` MP_TAC THENL + [ASM_SIMP_TAC[IN_ELIM_THM; VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT; + VECTOR_SUB_COMPONENT; BASIS_COMPONENT; ARITH; DIMINDEX_3] THEN + REAL_ARITH_TAC; + ALL_TAC] THEN + SIMP_TAC[AFFINE_HULL_FINITE; FINITE_INSERT; CONJUNCT1 FINITE_RULES; + AFFINE_HULL_FINITE_STEP; IN_ELIM_THM] THEN + REWRITE_TAC[REAL_ARITH `x - y:real = z <=> x = y + z`] THEN + REWRITE_TAC[VECTOR_ARITH `x - y:real^3 = z <=> x = y + z`] THEN + REWRITE_TAC[VECTOR_ADD_RID; REAL_ADD_RID; LEFT_IMP_EXISTS_THM] THEN + REWRITE_TAC[REAL_ARITH `&1 = x + y <=> x + y = &1`] THEN + MAP_EVERY X_GEN_TAC [`a:real`; `b:real`; `c:real`] THEN STRIP_TAC THEN + MAP_EVERY X_GEN_TAC [`a':real`; `b':real`; `c':real`] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC (ASSUME_TAC o SYM)) THEN + MAP_EVERY EXISTS_TAC + [`a + (&1 - (a + b + c + h / (w:real^3)$3)) * a'`; + `b + (&1 - (a + b + c + h / (w:real^3)$3)) * b'`; + `c + (&1 - (a + b + c + h / (w:real^3)$3)) * c'`; `h / (w:real^3)$3`] THEN + ASM_REWRITE_TAC[REAL_ARITH + `(a + x * a') + (b + x * b') + (c + x * c') + h:real = + (a + b + c + h) + x * (a' + b' + c')`] THEN + ASM_SIMP_TAC[REAL_LE_DIV; REAL_LT_IMP_LE] THEN + CONJ_TAC THENL [REAL_ARITH_TAC; ALL_TAC] THEN + REWRITE_TAC[VECTOR_ARITH + `(a + x * a') % v1 + (b + x * b') % v2 + (c + x * c') % v3 + h:real^N = + (a % v1 + b % v2 + c % v3) + x % (a' % v1 + b' % v2 + c' % v3) + h`] THEN + ASM_REWRITE_TAC[VECTOR_MUL_RZERO; VECTOR_ADD_LID] THEN + REWRITE_TAC[VECTOR_ARITH `(x + a) + y:real^3 = a + z <=> x + y = z`] THEN + GEN_REWRITE_TAC (RAND_CONV o RAND_CONV) [GSYM BASIS_EXPANSION] THEN + REWRITE_TAC[DIMINDEX_3] THEN CONV_TAC(ONCE_DEPTH_CONV NUMSEG_CONV) THEN + SIMP_TAC[VSUM_CLAUSES; FINITE_INSERT; CONJUNCT1 FINITE_RULES] THEN + REWRITE_TAC[IN_INSERT; NOT_IN_EMPTY; ARITH_EQ; VECTOR_ADD_RID] THEN + REWRITE_TAC[VECTOR_ADD_LDISTRIB; GSYM VECTOR_ADD_ASSOC] THEN + ASM_SIMP_TAC[VECTOR_MUL_ASSOC; REAL_DIV_RMUL; REAL_LT_IMP_NZ]; + + MAP_EVERY X_GEN_TAC [`a:real`; `b:real`; `c:real`; `h:real`] THEN + STRIP_TAC THEN + EXISTS_TAC `a % v1 + b % v2 + c % v3 + + h % ((w:real^3)$1 % basis 1 + w$2 % basis 2):real^3` THEN + EXISTS_TAC `h * --((w:real^3)$3)` THEN + ASM_SIMP_TAC[REAL_LE_MUL; REAL_LT_IMP_LE] THEN + REWRITE_TAC[VECTOR_ARITH `(x * --y) % --z:real^N = (x * y) % z`] THEN + ASM_SIMP_TAC[VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT; BASIS_COMPONENT; + DIMINDEX_3; ARITH; REAL_MUL_RZERO; REAL_ADD_RID] THEN + REWRITE_TAC[GSYM VECTOR_MUL_ASSOC; GSYM VECTOR_ADD_LDISTRIB; + GSYM VECTOR_ADD_ASSOC] THEN + REPLICATE_TAC 4 AP_TERM_TAC THEN + GEN_REWRITE_TAC LAND_CONV [GSYM BASIS_EXPANSION] THEN + REWRITE_TAC[DIMINDEX_3] THEN CONV_TAC(ONCE_DEPTH_CONV NUMSEG_CONV) THEN + SIMP_TAC[VSUM_CLAUSES; FINITE_INSERT; CONJUNCT1 FINITE_RULES] THEN + REWRITE_TAC[IN_INSERT; NOT_IN_EMPTY; ARITH_EQ; VECTOR_ADD_RID]; + + MAP_EVERY X_GEN_TAC [`y:real^3`; `h:real`] THEN STRIP_TAC THEN + UNDISCH_TAC `(vec 0:real^3) IN affine hull {v1,v2,v3}` THEN + SUBGOAL_THEN `(y - h / --((w:real^3)$3) % (w$1 % basis 1 + w$2 % basis 2)) + IN affine hull {v1:real^3,v2,v3}` MP_TAC THENL + [ASM_SIMP_TAC[IN_ELIM_THM; VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT; + VECTOR_SUB_COMPONENT; BASIS_COMPONENT; ARITH; DIMINDEX_3] THEN + REAL_ARITH_TAC; + ALL_TAC] THEN + SIMP_TAC[AFFINE_HULL_FINITE; FINITE_INSERT; CONJUNCT1 FINITE_RULES; + AFFINE_HULL_FINITE_STEP; IN_ELIM_THM] THEN + REWRITE_TAC[REAL_ARITH `x - y:real = z <=> x = y + z`] THEN + REWRITE_TAC[VECTOR_ARITH `x - y:real^3 = z <=> x = y + z`] THEN + REWRITE_TAC[VECTOR_ADD_RID; REAL_ADD_RID; LEFT_IMP_EXISTS_THM] THEN + REWRITE_TAC[REAL_ARITH `&1 = x + y <=> x + y = &1`] THEN + MAP_EVERY X_GEN_TAC [`a:real`; `b:real`; `c:real`] THEN STRIP_TAC THEN + MAP_EVERY X_GEN_TAC [`a':real`; `b':real`; `c':real`] THEN + DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC (ASSUME_TAC o SYM)) THEN + MAP_EVERY EXISTS_TAC + [`a + (&1 - (a + b + c + h / --((w:real^3)$3))) * a'`; + `b + (&1 - (a + b + c + h / --((w:real^3)$3))) * b'`; + `c + (&1 - (a + b + c + h / --((w:real^3)$3))) * c'`; + `h / --((w:real^3)$3)`] THEN + ASM_REWRITE_TAC[REAL_ARITH + `(a + x * a') + (b + x * b') + (c + x * c') + h:real = + (a + b + c + h) + x * (a' + b' + c')`] THEN + ASM_SIMP_TAC[REAL_LE_DIV; REAL_LT_IMP_LE] THEN + CONJ_TAC THENL [REAL_ARITH_TAC; ALL_TAC] THEN + REWRITE_TAC[VECTOR_ARITH + `(a + x * a') % v1 + (b + x * b') % v2 + (c + x * c') % v3 + h:real^N = + (a % v1 + b % v2 + c % v3) + x % (a' % v1 + b' % v2 + c' % v3) + h`] THEN + ASM_REWRITE_TAC[VECTOR_MUL_RZERO; VECTOR_ADD_LID] THEN + REWRITE_TAC[VECTOR_ARITH `(x + a) + y:real^3 = a + z <=> x + y = z`] THEN + GEN_REWRITE_TAC (RAND_CONV o RAND_CONV) [GSYM BASIS_EXPANSION] THEN + REWRITE_TAC[DIMINDEX_3] THEN CONV_TAC(ONCE_DEPTH_CONV NUMSEG_CONV) THEN + SIMP_TAC[VSUM_CLAUSES; FINITE_INSERT; CONJUNCT1 FINITE_RULES] THEN + REWRITE_TAC[IN_INSERT; NOT_IN_EMPTY; ARITH_EQ; VECTOR_ADD_RID] THEN + REWRITE_TAC[VECTOR_ADD_LDISTRIB; GSYM VECTOR_ADD_ASSOC] THEN + REWRITE_TAC[real_div; REAL_INV_NEG; REAL_MUL_RNEG] THEN + REWRITE_TAC[VECTOR_MUL_RNEG; VECTOR_MUL_LNEG; GSYM real_div] THEN + ASM_SIMP_TAC[VECTOR_MUL_ASSOC; REAL_DIV_RMUL; REAL_LT_IMP_NZ]]);; + +let THEOREM = prove + (`!v1 v2 v3 w:real^3. + ~coplanar {v1, v2, v3, w} + ==> (?nor. norm nor = &1 /\ + (!x. x IN aff_ge {v1, v2, v3} {w} <=> + (?xx h. + xx IN affine hull {v1, v2, v3} /\ + &0 <= h /\ + x = xx + h % nor)) /\ + (!x y. + {x, y} SUBSET affine hull {v1, v2, v3} + ==> nor dot (x - y) = &0))`, + REPEAT STRIP_TAC THEN + ONCE_REWRITE_TAC[VECTOR_ARITH `x:real^3 = y + h % z <=> x - y = h % z`] THEN + MATCH_MP_TAC(MESON[] `(?a b. P(a - b)) ==> ?a:real^3. P a`) THEN + MATCH_MP_TAC LEMMA THEN ASM_REWRITE_TAC[] THEN + EXISTS_TAC `affine hull {v1:real^3,v2,v3}` THEN + REWRITE_TAC[HULL_SUBSET; plane] THEN + ASM_MESON_TAC[NOT_COPLANAR_NOT_COLLINEAR]);; diff --git a/make.ml b/make.ml new file mode 100644 index 0000000..1a6773d --- /dev/null +++ b/make.ml @@ -0,0 +1,36 @@ +(* ========================================================================= *) +(* Theory of multivariate calculus in Euclidean space. *) +(* ========================================================================= *) + +loadt "Library/card.ml";; (* For countable set theorems. *) +loadt "Library/permutations.ml";; (* For determinants *) +loadt "Library/products.ml";; (* For determinants and integrals *) +loadt "Library/floor.ml";; (* Useful here and there *) +loadt "Multivariate/misc.ml";; (* Background stuff *) + +(* ------------------------------------------------------------------------- *) +(* The main core theory. *) +(* ------------------------------------------------------------------------- *) + +loadt "Multivariate/vectors.ml";; (* Basic vectors, linear algebra *) +loadt "Multivariate/determinants.ml";; (* Determinant and trace *) +loadt "Multivariate/topology.ml";; (* Basic topological notions *) +loadt "Multivariate/convex.ml";; (* Convex sets and functions *) +loadt "Multivariate/paths.ml";; (* Paths, simple connectedness etc. *) +loadt "Multivariate/polytope.ml";; (* Faces, polytopes, polyhedra etc. *) +loadt "Multivariate/dimension.ml";; (* Dimensional theorems *) +loadt "Multivariate/derivatives.ml";; (* Derivatives *) + +(* ------------------------------------------------------------------------- *) +(* Work in progress. *) +(* ------------------------------------------------------------------------- *) + +loadt "Multivariate/clifford.ml";; (* Geometric (Clifford) algebra *) +loadt "Multivariate/integration.ml";; (* Integration *) +loadt "Multivariate/measure.ml";; (* Lebesgue measure *) + +(* ------------------------------------------------------------------------- *) +(* Updated database, for convenience where dynamic updating doesn't work. *) +(* ------------------------------------------------------------------------- *) + +loadt "Multivariate/multivariate_database.ml";;